Tcl Source Code

Changes On Branch core-8-1-branch-old
Login

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

Changes In Branch core-8-1-branch-old Excluding Merge-Ins

This is equivalent to a diff from a027dd039f to 3608acd208

1999-04-15
00:35
Fixed problem with LD_SEARCH_FLAGS on Solaris. It's different for gcc than cc. Closed-Leaf check-in: 3608acd208 user: rjohnson tags: core-8-1-branch-old
1999-04-14
00:33
Fixed comments in code that referred to APIs that no longer exist, were misspelled, or have been upd... check-in: 2d7ffe4998 user: surles tags: core-8-1-branch-old
1998-09-21
23:39
Added contents of Tcl 8.1a2 check-in: 8c56dc8868 user: stanton tags: core-8-1-branch-old
1998-04-29
17:09
added call to TclpFinalize check-in: fd32610091 user: stanton tags: trunk
1998-04-28
18:53
Initial revision check-in: a027dd039f user: stanton tags: trunk
1998-03-26
14:56
Initial revision check-in: f86c34e38d user: rjohnson tags: trunk

Added ChangeLog.























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
1999-04-13    <[email protected]>

	* library/encoding/gb2312.enc:
	* library/encoding/euc-cn.enc:
	* tools/encoding/gb2312.txt:
	* tools/encoding/cp950.txt:
	* tools/encoding/Makefile: 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. [Bug: 632]

1999-04-13    <[email protected]>

	* win/tclWinSock.c: Apply patch to allow write access to a socket
	if FD_WRITE is sent but FD_CONNECT is not.  Some strange problem
	with either Win32 or a socket driver.  [Bug: 1664 1776]

1999-04-09    <[email protected]>

	* unix/tclUnixNotfy.c: Fixed notifier deadlock situation when the
	pipe used to talk back notifier thread is filled with data.  When
	calling the write() function to feed data down that pipe, unlock
	the notifierMutex to allow the notifier to wake up again.  Found
	as a result of the focus.test for Tk hanging. [Bug: 1700]

1999-04-06    <[email protected]>

	* tests/unixNotfy.test: Fixed hang in tests when built with thread
	support. 

	* tests/httpold.test: Fixed broken test that didn't wait long
	enough for events to arrive.

	* tests/unixInit.test: Fixed race condition in test.
	
	* tests/unixInit.test: 
	* tests/fileName.test: Minor test nits.

	* unix/tclUnixInit.c (TclpSetInitialEncodings): Fixed bad initial
	encoding string.

1999-04-06    <[email protected]>

	* generic/tclVar.c: 
	* generic/tclEnv.c: Moved the "array set" C level code into a
	common routine (TclArraySet).  The TclSetupEnv routine now uses
	this API to create an env array w/ no elements.

	* generic/tclEnv.c:
	* generic/tclWinInit.h:
	* generic/tclUnixInit.h:
	* generic/tclInt.h: Made the Env module I18N compliant.  Changed the
	FindVariable routine to TclpFindVariable, that now does a case
	insensitive string comparison on Windows, and not on UNIX. [Bug:
	1299, 1500]

1999-04-05    <[email protected]>

	* tests/io.test: Minor test cleanup.

	* generic/tclEncoding.c (Tcl_CreateEncoding): Minor lint to make
	it easier to compile on Digital-unix. [Bug: 1659]

	* unix/configure.in: 
	* unix/tclUnixPort.h: Applied patch for OS/390 to handle lack of
	sys/param.h. [Bug: 1725]

	* unix/configure.in: Fixed BSD/OS 4.* configuration to support
	shared libraries properly. [Bug: 1730]
	
1999-04-05    <[email protected]>

	* win/tclWinDde.c: decrease timeout value for DDE calls to 30k
	[Bug: 1639]

	* generic/tcl.decls:
	* generic/tcl.h:
	* generic/tclDecls.h:
	* generic/tclInt.decls:
	* generic/tclInt.h:
	* generic/tclIntDecls.h:
	* generic/tclStubInit.c:
	* generic/tclUtil.c: Added more functions to the Tcl stubs table,
	including all Tcl_ functions not already in it (except Cmd
	functions) and Tcl_GetCwd() and Tcl_Chdir() (new functions).
	
	* tests/safe.test:
	* doc/safe.n:
	* generic/tclBasic.c:
	* library/safe.tcl: The encoding command is not safe as-is, so
	create a safe alias to mask out the "encoding system <name>" but
	allow all other uses including "encoding system". Added test cases
	and updated the man page for Safe Tcl.

1999-04-05    <[email protected]>

	* tests/winTime.test: 
	* win/tclWinTime.c: Fixed crash in clock command that occurred
	when manipulating negative time values in timezones east of
	GMT. [Bug: 1142, 1458]
	
	* tests/platform.test: 
	* tests/fileName.test: Fixed broken tests.
	
	* generic/tclFileName.c: Moved global regexps into thread local
	storage.

	* tests/socket.test: Changed so tests don't reuse sockets,
	since Windows is slow to release sockets.

	* win/tclWinConsole.c: 
	* win/tclWinPipe.c: 
	* win/tclWinSerial.c: Fixed race condition where background
	threads were terminated while they still held a lock in the
	notifier. 

1999-04-02    <[email protected]>

	* tests/http.test: Fixed bad test initialization code.

	* generic/tclThreadTest.c (ThreadExitProc): Fixed bug where static
	memory was being returned instead of a dynamically allocated
	result in error cases.

1999-04-02    <[email protected]>

	* doc/dde.n:
	* tools/tcl.wse.in:
	* win/makefile.vc:
	* win/pkgIndex.tcl:
	* win/tclWinDde.c:  Add new DDE package, code removed from Tk now
	separated into its own package.  Changed DDE-based send code into
	"dde eval" command.  Can be loaded into tclsh (not just wish).
	Windows only.

1999-04-02    <[email protected]>

	* tests/expr.test: 
	* tests/for-old.test: 
	* tests/for.test: 
	* tests/foreach.test: 
	* tests/format.test: 
	* tests/httpold.test: 
	* tests/if.test: 
	* tests/init.test: 
	* tests/interp.test: 
	* tests/while.test:  Added some tests for known bugs (marked with
	knownBug constraint), and cleaned up a few bad tests.

	* generic/regc_locale.c: 
	* generic/regcustom.h: 
	* generic/tcl.decls: 
	* generic/tclCmdIL.c: 
	* generic/tclCmdMZ.c: 
	* generic/tclInt.h: 
	* generic/tclRegexp.c: 
	* generic/tclScan.c: 
	* generic/tclTest.c:
	* generic/tclUtf.c: 
	* win/tclWinFCmd.c: 
	* win/tclWinFile.c: Made various Unicode utility functions
	public. The following functions were made public and added to the
	stubs table: 
		Tcl_UtfToUniCharDString, Tcl_UniCharToUtfDString,
		Tcl_UniCharLen, Tcl_UniCharNcmp, Tcl_UniCharIsAlnum,
		Tcl_UniCharIsAlpha, Tcl_UniCharIsDigit, Tcl_UniCharIsLower,
		Tcl_UniCharIsSpace, Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar

1999-04-01    <[email protected]>

	* tests/registry.test: 
	* win/tclWinReg.c: Internationalized the registry code.  It now
	uses Unicode interfaces on NT. [Bug: 1197]

	* tests/parse.test: 
	* generic/tclParse.c: Fixed crash due to multiple frees in parser
	during error cleanup when parsing commands with more tokens than
	will fit in the static area of the parse structure. [Bug: 1681]

	* generic/tclInt.h: Removed duplicate declarations.

	* generic/tclInt.decls: 
	* generic/tcl.decls: Added Tcl_WinUtfToTChar and Tcl_WinTCharToUtf
	to the tclPlat table.

1999-04-01    <[email protected]>

	* generic/tcl.decls:
	* generic/tcl.h:
	* generic/tclBasic.c:
	* generic/tclDecls.h:
	* generic/StubInit.c:
	* tools/genStubs.tcl:
	* unix/Makefile.in:
	* win/makefile.vc: Applied patch from Jan Nijtmans to fix Ultrix
	multiple symbol definition problem.  Now, even Tcl includes a copy
	of the Tcl stub library.  Also fixed TCL_MEM_DEBUG mode (for Tk).

1999-03-31    <[email protected]>

	* win/tclWinConsole.c: WinNT has a bug when reading a single
	character from the console.  Rewrote the code for the console to
	read an entire line at a time using the reader thread.

1999-03-30    <[email protected]>

	* unix/Makefile.in: Removed trailing backslash that broke the
	"depend" target.

	* unix/tclUnixInit.c (TclpSetInitialEncodings): Changed to avoid
	calling setlocale().  We now look directly at env(LANG) and
	env(LC_CTYPE) instead. [Bug: 1636]

	* generic/tclFileName.c: 
	* generic/tclDecls.h: 
	* generic/tcl.decls: Removed CONST from Tcl_JoinPath and
	Tcl_TranslateFileName because it changes the signature of
	Tcl_JoinPath in an incompatible manner.

	* generic/tclInt.h: 
	* generic/tclLoad.c (TclFinalizeLoad): 
	* generic/tclEvent.c (Tcl_Finalize): Defer unloading of loadable
	modules until all exit handlers have been invoked.
	[Bug: 998, 1273, 1573, 1593]

1999-03-29    <[email protected]>

	* generic/tclFileName.c: 
	* generic/tclDecls.h: 
	* generic/tcl.decls: Added CONST to Tcl_JoinPath and
	Tcl_TranslateFileName.

1999-03-29    <[email protected]>

	* tools/genStubs.tcl:
	* unix/configure.in:
	* unix/Makefile.in:
	* win/makefile.vc:
	* generic/tcl.h:
	* generic/tclBasic.c:
	* generic/tclDecls.h:
	* generic/tclIntDecls.h:
	* generic/tclPlatDecls.h:
	* generic/tclIntPlatDecls.h: Removed the stub functions and
	changed the stub macros to just use the name without params. Pass
	&tclStubs into the interp (don't use tclStubsPtr because of
	collisions with the stubs on Solaris).
	
1999-03-27    <[email protected]>

	* win/makefile.bc: Removed makefile for Borland compiler, no
	longer supported.

1999-03-26    <[email protected]>

	* win/tclWinSerial.c:
	* win/tclWinConsole.c:
	* win/tclWinPipe.c: Don't close the Win32 handle for a channel if
	it's a stdio handle (GetStdHandle()) during shutdown of a thread
	to prevent it from destroying the stdio of other threads.

1999-03-26    <[email protected]>

	* unix/configure.in
	--nameble-shared is now the default and build Tcl as a shared
	library; specify --disable-shared to build a static Tcl library
	and shell.

1999-03-25    <[email protected]>

	* tests/interp.test: 
	* generic/tclInterp.c (AliasObjCmd): Changed so aliases are
	invoked at current scope in the target interpreter instead of at
	the global scope.  This was an incompatibility introduced in 8.1
	that is being removed. [Bug: 1153, 1556]
	
	* library/encoding/big5.enc:
	* library/encoding/gb2312.enc:
	* tools/encoding/big5.enc:
	* tools/encoding/gb2312.enc: Added ASCII to big5 and gb2312
	encodings. [Bug: 632]
	
	* generic/tclPkg.c (Tcl_PkgRequireEx): Fixed broken clientData
	initialization in package code.

	* unix/Makefile.in (dist): Added tcl.decls and tclInt.decls to
	source distribution. [Bug: 1571]

	* doc/Thread.3: Updated documentation of Tcl_MutexLock to indicate
	that the recursive locking behavior is undefined.  On Windows, it
	does not block, on Unix it deadlocks. [Bug: 1275]

1999-03-24    <[email protected]>

	* tests/execute.test: 
	* generic/tclExecute.c (TclExecuteByteCode): Fixed expression code
	that incorrectly returned floating point values for integers if
	the internal rep happened to be a double.  Now we check to see if
	the object has a string rep that looks like an integer before
	using the double internal rep. [Bug: 1516]

1999-03-24    <[email protected]>

	* generic/tclAlloc.c:
	* generic/tclEncoding.c:
	* generic/tclProc.c:
	* unix/tclUnixTime.c:
	* win/tclWinSerial.c: Fixed compilation warnings/errors for VC++
	5.0 and 6.0 and HP-UX native compiler without -Aa or -Ae. 
	[Bug: 1323 1518 1324 1583 1585 1586]

	* win/tclWinSock.c: Make sockets thread-safe on Windows. The
	current implementation uses windows to handle events on the
	socket, one for each thread (thread local storage). Previously,
	there was only one window shared between threads, which didn't
	work. [Bug: 1326]

1999-03-23    <[email protected]>

	* tools/tcl.wse: Fixed file association to look in the right place
	for the wish icon. [Bug: 1544]

	* tests/winNotify.test: 
	* tests/ioCmd.test: 
	* tests/event.test: Changed to use new style conditionals.

	* tests/encoding.test: Fixed nonportable test.

	* unix/dltest/configure.in: 
	* unix/dltest/Makefile.in: Added missing DBGX macros. [Bug: 1564]

	* tests/winNotify.test: 
	* mac/tclMacNotify.c: 
	* win/tclWinNotify.c: 
	* unix/tclUnixNotfy.c:
	* generic/tclNotify.c: Added a new Tcl_ServiceModeHook interface
	that is invoked whenever the service mode changes.  This is needed
	to allow the Windows notifier to create a communication window the
	first time Tcl is about to enter an external modal event loop
	instead of at startup time.  This will avoid the various problems
	that people have been seeing where the system hangs when tclsh
	is running outside of the event loop. [Bug: 783]

	* generic/tclInt.h: 
	* generic/tcl.decls: Renamed TclpAlertNotifier back to
	Tcl_AlertNotifier since it is part of the public notifier driver
	API.

1999-03-23    <[email protected]>

	* win/tclWinSerial.c: Fixed problem with fileevent on the serial
	port and nonblocking mode.  Gets no longer hangs, fileevents fire
	whenever there is any character data on the port.
	
	* tests/winConsole.test:
	* win/tclWinConsole.c: Fixed problem with fileevents and gets from
	a console stdin.  Previously, fileevents were firing before an
	entire line was available for reading, which meant that when you
	did a gets or read, it blocked (even in nonblocking mode). Now, it
	should work the same as Unix: fileevents fire when an entire line
	is ready, and gets and read do not block in non-blocking mode.
	Added an interactive test case to check for this.

1999-03-22    <[email protected]>

	* tests/reg.test: 
	* generic/regc_color.c: Applied regexp bug fix from Henry Spencer.

1999-03-19    <[email protected]>

	* generic/tclCmdIL.c: Fixed the initialization of an array so that
 	the Sun 5.0 C compiler wouldn't complain.

	* unix/configure.in: Added support for --enable-64bit.  For now,
 	this is only supported on Solaris 7 64bit (SunOS 5.7) using the Sun 
	compiler (not gcc).
	
1999-03-18    <[email protected]>

	* win/tclWinChan.c (TclpOpenFileChannel, Tcl_MakeFileChannel):
	Changed to only test for console or comm handles when the type is
	FILE_TYPE_CHAR to avoid useless tests on simple files.  Also
	reordered tests so consoles are tested first as this is more
	common.

	* win/makefile.vc: Regularized usage of mkd and rmd and rm.

	* library/encoding/shiftjis.enc: 
	* tools/encoding/shiftjis.txt: Missing/incorrect characters in
	shift-jis table. [Bug: 1008, 1526]

	* generic/tclInt.decls:
	* generic/tcl.decls: Eliminated use of "string" and "list" from
	argument lists to avoid conflicts with C++ STL. [Bug: 1181]

	* win/tclWinFile.c (TclpMatchFiles): Changed to ignore the
	FS_CASE_IS_PRESERVED bit and always return exactly what we get
	from the system.

1999-03-17    <stanton@GASPODE>

	* win/README.binary: 
	* win/README: 
	* unix/configure.in: 
	* generic/tcl.h: 
	* README: Updated version to 8.1b3.

1999-03-14    <stanton@GASPODE>

	* win/tclWinConsole.c: 
	* win/tclWinPipe.c: 
	* win/tclWinSerial.c: Changed so channel drivers wait for the
	reader/writer threads to exit before returning during a close
	operation.  This ensures that the main thread is the last thread
	to exit, so the process return value is set properly.

	* generic/tclIntDecls.h: 
	* generic/tclIntPlatDecls.h: 
	* generic/tclIntPlatStubs.c: 
	* generic/tclIntStubs.c: 
	* generic/tclPlatDecls.h: 
	* generic/tclPlatStubs.c: 
	* generic/tclStubInit.c: 
	* generic/tclStubs.c: Fixed bad eol characters.
	
	* generic/tclInt.decls: Changed "const" to "CONST" in
	declarations for better portability.

	* generic/tcl.decls: Renamed panic and panicVA to Tcl_Panic and
	Tcl_PanicVA in the stub files.

	* generic/tclInterp.c (Tcl_MakeSafe): Remove tcl_platform(user)
	from safe interps.

1999-03-11    <stanton@GASPODE>

	* unix/Makefile.in:
	* unix/configure.in: Include compat files in the stub library in
	addition to the main library.  Compat files are now built for
	dynamic use in all cases.
	
	* generic/tcl.h: Changed magic number so it doesn't match the plus
	patch, at Jan's request.
	
	* unix/tclConfig.sh.in:
	* unix/dltest/Makefile.in:
	* unix/dltest/configure.in:
	* unix/dltest/pkga.c:
	* unix/dltest/pkgb.c:
	* unix/dltest/pkgc.c:
	* unix/dltest/pkgd.c:
	* unix/dltest/pkge.c:
	* unix/dltest/pkgf.c: Changed package tests to build against the
	stubs library.

1999-03-10    <stanton@GASPODE>

	* generic/tcl.h: 
	* generic/tcl.decls: Changed Tcl_ReleaseType from an enum to
	macros so it can be used in .rc files.
	Added Tcl_GetString.

	* mac/tclMacNotify.c:
	* generic/tclNotify.c:
	* generic/tclInt.h: 
	* win/tclWinNotify.c: 
	* generic/tcl.h: Renamed Tcl_AlertNotifier to TclpAlertNotifier.

	* generic/tclInt.decls: Added TclWinAddProcess to make it possible
	for expect to use Tcl_WaitForPid().  This patch is from Gordon
	Chaffee. 

	* mac/tclMacPort.h: 
	* win/tclWinInit.c: 
	* unix/tclUnixPort.h: 
	* generic/tclAsync.c: Added TclpAsyncMark to fix bug in async
	handling on Windows where async events don't wake up the event
	loop.  This patch comes from Gordon Chaffee.

	* generic/tcl.decls: Fixed declarations of reserved slots.
	
1999-03-10    <[email protected]>

	* generic/tclCompile.h: Ensure that the ByteCode struct is binary
	compatible with the version in 8.0.6.

	* generic/tcl.h:
	* generic/tclBasic.c: Add Tcl_GetVersion() function to the public
	C API to allow programs to check the version number of the Tcl
	library at runtime.  Also added an enum to clarify the release
	level (alpha, beta, final).

1999-03-09    <stanton@GASPODE>

	* Integrated changes from Tcl 8.0 including:
		stubs mechanism
		configure patches from Jan Nijtmans
		rename of panic to Tcl_Panic
	
1999-03-08    <[email protected]>

	* win/tclWin32Dll.c: Removed Dll instance from thread-local
	storage.

1999-03-08    <stanton@GASPODE>
	
	* generic/tcl.h: Moved Tcl_Mutex, etc. macros above the inclusion
	of tclDecls.h to avoid macro conflicts.

	* generic/tclInt.h:
	* generic/regc_color.c: 
	* generic/regcomp.c:
	* generic/tclCmdIL.c:
	* generic/tclCmdAH.c:
	* generic/tclIOCmd.c:
	* generic/tclParse.c:
	* generic/tclStringObj.c:
	* unix/tclUnixNotfy.c: Cleaned up various compiler warnings,
	eliminated UCHAR bugs.
	
	* unix/tclUnixNotfy.c:
	* unix/tclUnixThrd.c:
	* generic/tclThreadTest.c:
	* mac/tclMacThrd.c: Changed TclpCondition*() to Tcl_Condition*().
	
	* INTEGRATED PATCHES FROM 8.0.6:

	* generic/tcl.decls:
	* generic/tcl.h:
	* generic/tclBasic.c: 
	* generic/tclDecls.h:
	* generic/tclInt.decls:
	* generic/tclInt.h: 
	* generic/tclIntDecls.h:
	* generic/tclIntPlatDecls.h:
	* generic/tclIntPlatStubs.c:
	* generic/tclIntStubs.c:
	* generic/tclPlatDecls.h:
	* generic/tclPlatStubs.c:
	* generic/tclStubInit.c:
	* generic/tclStubLib.c:
	* generic/tclStubs.c:
	* tools/genStubs.tcl:
	* unix/configure.in:
	* unix/Makefile.in:
	* unix/tclConfig.sh.in:
	* win/makefile.vc:  
	* win/tclWinPort.h: Added Tcl stubs implementation.  There are
	now two new macros USE_TCL_STUBS and USE_TCL_STUB_PROCS that
	enable use of stubs and disable stub macros respectively.  All of
	the public and private function declarations from tcl.h and
	tclInt.h have moved into the *.decls files and the *Stubs.c and
	*Decls.h files are generated using the genStubs.tcl script.

	* unix/Makefile.in:
	* unix/configure.in: 
	* unix/ldAix: Enhanced AIX shared library support.

	* win/tclWinSock.c: Removed a bunch of extraneous PASCAL FAR
	attributes from internal functions.

	* win/tclWinReg.c: Changed registry package to use stubs mechanism
	so it no longer depends on the specific version of Tcl.

	* doc/AddErrInfo.3: 
	* doc/Eval.3: 
	* doc/PkgRequire.3: 
	* doc/SetResult.3: 
	* doc/StringObj.3: 
	* generic/tcl.h:
	* generic/tclBasic.c: 
	* generic/tclPanic.c:
	* generic/tclStringObj.c:
	* generic/tclUtil.c:
	* unix/mkLinks: Added va_list versions of all VARARGS
	functions so they can be invoked from the stub functions.

	* doc/package.n: 
	* doc/PkgRequire.3: 
	* generic/tclPkg.c: Added Tcl_PkgProvideEx, Tcl_RequireEx,
	Tcl_PresentEx, and Tcl_PkgPresent.  Added "package present"
	command.

	* generic/tclFileName.c: 
	* mac/tclMacFile.c: 
	* mac/tclMacShLib.exp: 
	* unix/tclUnixFile.c: 
	* win/tclWinFile.c: Changed so TclGetUserHome is defined on
	all platforms, even though it is currently a noop on mac and
	windows, and renamed it to TclpGetUserHome.

	* generic/tclPanic.c:
	* generic/panic.c: Renamed panic to Tcl_Panic.
	
1999-02-25    <[email protected]>

	* win/makefile.vc: Added tclWinConsole.c and tclWinSerial.c
	
	* win/tclWinConsole.c: New code to properly deal with fileevents
	and nonblocking mode on consoles.
	
	* win/tclWinSerial.c: New code to properly deal with fileevents
	and nonblocking mode on serial ports.

	* win/tclWinPipe.c: 
	* win/tclWinPort.h: Exported functions to allow creation of pipe
	channels from tclWinChan.c

	* win/tclWinChan.c: Check the type of a channel, including for the
	standard (stdin/stdout/stderr), and use the correct channel type
	to create the channel (file, serial, console, or pipe).

1999-02-11    <stanton@GASPODE>

	* README: 
	* generic/tcl.h: 
	* win/README.binary: 
	* win/README: 
	* unix/configure.in: 
	* mac/README: Updated version numbers to 8.1b2.

1999-02-10    <stanton@GASPODE>

	* library/auto.tcl: Fixed auto_mkindex so it handles .tbc files.
	Did some general cleanup to handle bad eval statements that didn't
	use "list".

	* unix/mkLinks:
	* doc/SetVar.3:
	* generic/tcl.h:
	* generic/tclVar.c: Restored Tcl_ObjGetVar2 and Tcl_ObjSetVar2
	from 8.0. Renamed Tcl_Get/SetObjVar2 to Tcl_GetVar2Ex and
	Tcl_SetVar2Ex.

1999-02-10    <stanton@GASPODE>

	INTEGRATED PATCHES FROM 8.0.5b2: 

	* test/winPipe.test: Changed to remove echoArgs.tcl temporary file
	when done.
	
	* tests/cmdAH.test:
	* generic/tclFileName.c (TclGetExtension): Changed behavior so the
	split happens at the last period in the name instead of the first
	period of the last run of periods.  So, "foo..o" is split into
	"foo." and ".o" now. [Bug: 1126]
	
	* win/makefile.vc: Added better support for paths with spaces in
	the name. Added .lib and support .dlls to the install-binaries
	target.  Added generate of a pkgIndex.tcl script to the
	install-libraries target.

	* win/tclAppInit.c: 
	* unix/tclAppInit.c: 
	* mac/tclMacAppInit.c: 
	* generic/tclTest.c: Changed some EXTERN declarations to extern
	since they are not defining exported interfaces.  This avoids
	generating useless declspec() attributes and makes the windows
	makefile simpler.

	* generic/tcl.h: Moved Tcl_AppInit declaration to end and cleared
	out TCL_STORAGE_CLASS so it is not declared with a declspec().

	* tests/interp.test:
	* generic/tclInterp.c (DeleteAlias): Changed to use
	Tcl_DeleteCommandFromToken so we handle renames properly. This
	avoids senseless panic. [Bug: 736]

	* unix/tclUnixChan.c: 
	* win/tclWinSock.c: 
	* doc/socket.n: Applied Gordon Chaffee's patch to handle failures
	during asynchronous socket connection operations.  This adds a new
	"-error" fconfgure option to socket channels. [Bug: 893]

	* generic/tclProc.c:
	* generic/tclNamesp.c:
	* generic/tclInt.h: 
	* generic/tclCmdIL.c: 
	* generic/tclBasic.c: 
	* generic/tclVar.c: Applied patch from Viktor Dukhovni to
	rationalize TCL_LEAVE_ERR_MSG behavior when creating variables.
	
	* generic/tclVar.c: Fixed bug in namespace tail computation.
	Fixed bug where upvar could resurrect a namespace variable whose
	namespace had been deleted.

	* generic/tclCompile.c (TclCompileExprCmd): Eliminated yet another
	bogus optimization in expression compilation.

	* unix/configure.in: Added branch for BSD/OS-4* to shared library
	case statement. [Bug: 975]
	Fixed to correctly handle IRIX 6.5 n32 library support. [Bug: 1117]
	
	* win/winDumpExts.c: Patched to be pickier about stripping
	@'s. [Bug: 920]

	* library/http2.0/http.tcl: Added catch around eof test in
	CopyDone since the user may have already called http::reset.
	[Bug: 1108] 

	* unix/configure.in: Changed Linux and IRIX to set SHLIB_LIBS to
	LIBS so shared libraries are linked with the system
	libraries. [Bug: 1018]

	* generic/tclCompile.c (CompileExprWord): Fixed exception stack
	overflow bug caused by missing statement. [Bug: 928]

	* generic/tclIOCmd.c: 
	* generic/tclBasic.c: Objectified the "open" command. [Bug: 1113] 

	* generic/tclPosixStr.c (Tcl_ErrnoId, Tcl_ErrnoMsg): When using
	egcs, ENOTSUP and EOPNOTSUPP are the same, so now we handle that
	case. [Bug: 1137]

	* library/init.tcl: Various small changes requested by Jan Nijtmans.
	- If the variable $tcl_library contains the empty string, this
	empty string will be put in $auto_path. This is not useful at all,
	it only slows down later package processing.
	- If the variable tcl_pkgPath is not set, the "unset __dir"
	fails. Thich makes init.tcl totally unusable. Better put a "catch"
	around it. 
	- In the function tcl_findLibraries, the "string match" function
	only works correctly if $tcl_patchLevel is in one of the forms
	"?.?a?", "?.?b?" or "?.?.?". Could a "regexp" be used instead,
	then it allows anything to be appended to the patchLevel
	string. And it is more efficient.
	- The tclPkgSetup function assumes that if $type != "load" then
	the type must be "source". This needn't be true. Some users want
	to add their own setup types.
	[RFE: 1138] [Bug: 978]

	* win/tclWinReg.c: 
	* doc/registry.n: Added support for HKEY_PERFORMANCE_DATA and
	HKEY_DYN_DATA keys. [Bug: 1109]

	* win/tclWinInit.c (TclPlatformInit): Added code to ensure
	tcl_pkgPath is set to "" when no registry entry is found. [Bug: 978]

1999-02-01    <stanton@GASPODE>

	* generic/tclBasic.c:
	* generic/tclCmdAH.c:
	* generic/tclCmdIL.c:
	* generic/tclCmdMZ.c:
	* generic/tclExecute.c:
	* generic/tclHistory.c:
	* generic/tclIO.c:
	* generic/tclIOUtil.c:
	* generic/tclInterp.c:
	* generic/tclMain.c:
	* generic/tclNamesp.c:
	* generic/tclParse.c:
	* generic/tclProc.c:
	* generic/tclTest.c:
	* generic/tclTimer.c:
	* generic/tcl.h: Made eval interfaces compatible with 8.0 by
	renaming Tcl_EvalObj to Tcl_EvalObjEx, renaming Tcl_Eval2 to
	Tcl_EvalEx and restoring Tcl_EvalObj and Tcl_GlobalEvalObj
	interfaces so they match Tcl 8.0.

1999-01-28    <stanton@GASPODE>

	* Merged Tcl 8.0.5b1 changes.
	
	* generic/tclUtil.c (Tcl_DStringSetLength): Changed so the buffer
	overallocates in a manner similar to Tcl_DStringAppend.  This
	should improve performance for TclUniCharToUtfDString.

1998-12-11    === Tcl 8.1b1 Release ===
	
1998-12-10    <stanton@GASPODE>

	* Fixed lots of files that used TCL_THREAD instead of TCL_THREADS.
	
	* generic/tclEncoding.c (Tcl_FreeEncoding): Moved most of the code
	into a static FreeEncoding routine that does not grab the
	encodingMutex to avoid deadlocks/races when called from other
	routines that already have the mutex.

1998-12-09    <stanton@GASPODE>

	* library/msgcat1.0/msgcat.tcl: Fixed bad export list, fixed so
	all locale strings are converted to lower case, including file
	names.

	* generic/regcomp.c (makescan): Fixed bug in longest match case
	that caused anchored patterns to fail. [Bug: 897]

1998-12-08    <stanton@GASPODE>

	* library/msgcat1.0/msgcat.tcl: changed mc to invoke mcunknown in
	the calling context, changed locale lookups to be case insensitive

1998-12-07    <stanton@GASPODE>

	* generic/tclAlloc.c (TclpRealloc): Fixed a memory allocation bug
	where big blocks that were reallocated into a different heap
	location were not being placed into the bigBlocks list. [Bug: 933]

	* tests/msgcat.test: Added message catalog test suite.

	* library/msgcat1.0/msgcat.tcl: minor bug fixes, integrated latest
	changes from Mark Harrison.

1998-12-04    <stanton@GASPODE>

	* library/msgcat1.0/msgcat.tcl: Changed code to conform to Tcl
	coding standards.  Changed to use file join for portability.

	* library/msgcat1.0: Added initial implementaion of Tcl message
	catalog package contributed by Mark Harrison.

1998-12-03    <stanton@GASPODE>

	* win/tclWinPipe.c (BuildCommandLine): Fixed bug that kept
	arguments containing spaces from being properly quoted.

	* tests/defs: Changed so auto_path is set to only contain the Tcl
	library directory.  This keeps the tests from accidentally picking
	up stuff in installed packages. 

	* generic/tclUtil.c (Tcl_StringMatch): Changed to match 8.0
	behavior in corner case where there is no closing bracket.

1998-12-02    <stanton@GASPODE>

	* win/tclWinPipe.c (TclpCreateCommandChannel): Changed
	reader/writer threads to have THREAD_PRIORITY_HIGHEST so they will
	have a chance to run whenever there is something to do.

	* generic/tclIO.c (WriteBytes, WriteChars): Fixed so extraneous
	flushes do not happen in line mode.
	(TranslateOutputEOL): Made translation more efficient in line mode
	and fixed a buffer overflow bug in CRLF translation. [Bug: 887]

1998-12-02    <welch@SAGE>

	* Updated patchlevel to 8.1b1

1998-12-02    <stanton@GASPODE>

	* generic/regc_color.c (subcolor): Added check for error case to
	avoid an out of bounds array reference.

	* generic/tclCmdAH.c (Tcl_EncodingObjCmd): Changed to avoid using
	Tcl_DStringResult because it is not binary clean.

	* generic/tclParse.c (Tcl_ParseCommand): Fixed bug in comment
	parsing where a trailing comment looked like an incomplete
	command. 

1998-12-02    <welch@SAGE>

	* Merged changes from 8.0.4, especially the new pkg_mkIndex

1998-12-01    <stanton@GASPODE>

	* generic/tclIO.c (Tcl_ReadChars): Added a call to UpdateInterest
	so we don't block when there is data sitting in the buffers.

	* generic/tclTest.c (TestevalobjvObjCmd): Updated for EvalObjv
	change.

	* tests/parse.test: Updated tests for EvalObjv change.

	* generic/tclParse.c (EvalObjv, Tcl_EvalObjv): Changed
	Tcl_EvalObjv interface to remove string and length arguments,
	preserved original interface as EvalObjv for internal use.

	* generic/tcl.h: Changed Tcl_EvalObjv interface to remove string
	and length arguments.

	* doc/Eval.3: Updated documentation for Tcl_EvalObjv to remove
	string and length arguments.

	* generic/tclCompCmds.c (TclCompileForeachCmd): Fixed code that
	corrupted the exceptDepth value in the compile environment when
	foreach failed to compile inline. [Bug: 884]

	* library/encoding/euc-kr.enc: 
	* library/encoding/ksc5601.enc: 
	* tools/encoding/ksc5601.txt: 
	* unix/tclUnixInit.c: Added support for Korean EUC. 

	* win/tclWinChan.c (TclpGetDefaultStdChannel): added check for a
	failure during Tcl_MakeFileChannel.

1998-11-30    <stanton@GASPODE>

	* unix/tclUnixNotfy.c (Tcl_WaitForEvent): Fixed hang that occurs
	when trying to close a pipe that is currently being waited on by
	the notifier thread. [Bug: 607]

	* unix/tclUnixFCmd.c (GetPermissionsAttribute): Increase size of
	returnString buffer to avoid overflow. [Bug: 584]

	* generic/tclThreadTest.c (TclThreadSend): Fixed memory leak due
	to use of TCL_VOLATILE instead of TCL_DYNAMIC.

	* generic/tclThread.c (TclRememberSyncObject): Fixed memory leak
	caused by failure to reuse condition variables.

	* unix/tclUnixNotfy.c: 	(Tcl_AlertNotifier, Tcl_WaitForEvent,
	NotifierThreadProc, Tcl_InitNotifier): Fixed race condition caused
	by incorrect use of condition variables when sending messages
	between threads.. [Bug: 607]

	* generic/tclTestObj.c (TeststringobjCmd): MAX_STRINGS was off by one
	so the strings array was too small.

	* generic/tclCkalloc.c (Tcl_DbCkfree): Moved mutex lock so
	ValidateMemory is done inside the mutex to avoid a race condition
	when validate_memory is enabled. [Bug: 880]

1998-11-23    <stanton@GASPODE>

	* regexec.c: more performance tuning from Henry Spencer.

1998-11-17    <stanton@GASPODE>

	* tclScan.c: moved "scan" implementation out of tclCmdMZ.c and
	added Unicode support.  This required a complete reimplementation
	of the command to avoid using scanf(), which isn't Unicode aware.
	Two new features were added in the process: %n to return the
	current number of characters consumed, and XPG3-style %n$ argument
	order specifiers similar to those provided by the "format"
	command. [Bug: 833]

	* tclAlloc.c: changed so allocated memory is always 8-byte aligned
	to improve memory performance and to ensure that it will work on
	systems that don't like accessing 4-byte aligned values
	(e.g. Solaris and HP-UX). [Bug: 834]

1998-11-06    <stanton@GASPODE>

	* tclVar.c (TclGetIndexedScalar): Fixed bug 796, var name was
	getting lost before being passed to CallTraces.

1998-10-21    <stanton@GASPODE>

	* added "encoding" command
	
	* Moved internal regexp declarations from tclInt.h to tclRegexp.h

	* integrated regexp updates from Henry Spencer

1998-10-15    <stanton@GASPODE>

	* tclUtf.c: added Unicode character table support

	* tclInt.h: added TclUniCharIsWordChar

	* tclCmdMZ.c (Tcl_StringObjCmd): added "totitle" subcommand,
	changed "wordend" and "wordstart" to properly handle Unicode word
	characters and connector punctuation

1998-10-05    <stanton@GASPODE>

	* auto.tcl, package.tcl: fixed SCCS strings

	* tclIndex: updated index to reflect 8.1 files

	* tclCompile.c (TclCompileScript): changed to avoid modifying the
	input string in place because name lookup operations could have
	arbitrary side effects

	* tclInterp.c: added guard against deleting current interpreter

	* tclMacFile.c, tclUnixFile.c, tclWinFile.c, tclFileName.c: added
	warnings around code that modifies strings in place

	* tclExecute.c: fixed off-by-one copying error, fixed merge bugs

	* tclEvent.c: changed so USE_TCLALLOC is tested for value instead
	of definition

	* tclCompCmds.c: replaced SCCS strings, added warnings around code
	that modifies strings in place

	* interp.test: added test for interp deleting itself

1998-09-30    <stanton@GASPODE>

	* makefile.vc: fixed so TCL_LIBRARY is set before running tcltest

	* tclWin32Dll.c: removed TclpFinalize, cleanup of merges

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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132

133
134
135
136
137
138
139
140
141
142
143
144


145
146
147
148
149
150
151


152
153
154
155
156
157
158
159

160
161


162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182

183


184
185

186
187
188
189
190
191
192
193
194


195
196

197
198
199
200



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230


231
232
233
234
235
236


237


238
239
240
241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

284

285
286
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314


315

316




317
318
319
320
321
322

323
324


325
326
327
328
329
330
331
332
333
334







335
336
337
338
339
340

341

342


343


344
345





346
347
348
349
350
351
352
Tcl



SCCS: @(#) README 1.52 97/11/20 12:43:16




1. Introduction












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








This directory and its descendants contain the sources and documentation
for Tcl, an embeddable scripting language.  The information here
corresponds to release 8.0p2, which is the second patch update for Tcl
8.0. Tcl 8.0 is a major new release that replaces the core of the



interpreter with an on-the-fly bytecode compiler to improve execution
speed.  It also includes several other new features such as namespaces
and binary I/O, plus many bug fixes.  The compiler introduces a few


incompatibilities that may affect existing Tcl scripts; the
incompatibilities are relatively obscure but may require modifications
to some old scripts before they can run with this version. The compiler



introduces many new C-level APIs, but the old APIs are still supported.
See below for more details.  This patch release fixes various bugs in
Tcl 8.0; there are no feature changes relative to Tcl 8.0.





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
















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 library procedures;
and files with extension ".n" describe Tcl commands.  The file "doc/Tcl.n"

gives a quick summary of the Tcl language syntax.  To print any of the man
pages, cd to the "doc" directory and invoke your favorite variant of
troff using the normal -man macros, for example

		ditroff -man Tcl.n

to print Tcl.n.  If Tcl has been installed correctly and your "man"
program supports it, you should be able to access the Tcl manual entries
using the normal "man" mechanisms, such as

		man Tcl

There is also an official home for Tcl and Tk on the Web:
	http://sunscript.sun.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. Compiling and installing Tcl
-------------------------------

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

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 home page for SunScript
        (http://sunscript.sun.com) under "Tech Corner".  Also, check in
        the FTP directory from which you retrieved the base
        distribution.  Some of the binary releases are available freely,
        while others are for sale.

    (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. 
	Patch releases are available in two forms.  A file like
	tcl8.0p2.tar.Z is a complete release for patch level 2 of Tcl
	version 8.0.  If there is a file with a higher patch level than
	this release, just fetch the file with the highest patch level
	and use it.

	Patches are also available in the form of patch files that just
	contain the changes from one patch level to another.  These
	files will have names like tcl8.0p1.patch, tcl8.0p2.patch, etc.  They
	may also have .gz or .Z extensions to indicate compression.  To
	use one of these files, you apply it to an existing release with
	the "patch" program.  Patches must be applied in order:
	tcl8.0p1.patch must be applied to an unpatched Tcl 8.0 release
	to produce a Tcl 8.0p1 release;  tcl8.0p2.patch can then be
	applied to Tcl8.0p1 to produce Tcl 8.0p2, and so on. To apply an
	uncompressed patch file such as tcl8.0p1.patch, invoke a shell
	command like the following from the directory containing this
	file:
	    patch -p < tcl8.0p1.patch
	If the patch file has a .gz extension, invoke a command like the
	following:
	    gunzip -c tcl8.0p1.patch.gz | patch -p
	If the patch file has a .Z extension, it was compressed with
	compress.  To apply it, invoke a command like the following:
	    zcat tcl8.0p1.patch.Z | patch -p
	If you're applying a patch to a release that has already been
	compiled, then before applying the patch you should cd to the
	"unix" subdirectory and type "make distclean" to restore the
	directory to a pristine state.

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

Here are the most significant changes in Tcl 8.0.  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. Bytecode compiler.  The core of the Tcl interpreter has been
    replaced with an on-the-fly compiler that translates Tcl scripts to
    byte codes; a new interpreter then executes the byte codes. In
    earlier versions of Tcl, strings were used as a universal

    representation;  in Tcl 8.0 strings are replaced with Tcl_Obj
    structures ("objects") that can hold both a string value and an

    internal form such as a binary integer or compiled bytecodes.  The
    new objects make it possible to store information in efficient
    internal forms and avoid the constant translations to and from
    strings that occurred with the old interpreter.  We have not yet
    converted all of Tcl to take full advantage of the compiler and
    objects and have not converted any of Tk yet, but even so you
    should see speedups of 2-3x on many programs and you may see
    speedups as much as 10-20x in some cases (such as code that
    manipulates long lists).  Future releases should achieve even
    greater speedups.  The compiler introduces only a few minor changes
    at the level of Tcl scripts, but it introduces many new C APIs for
    managing objects.  See, for example, the manual entries doc/*Obj*.3.



    2. Namespaces.  There is a new namespace mechanism based on the
    namespace implementation by Michael McLennan of Lucent Technologies.
    This includes new "namespace" and "variable" commands.  There are
    many new C APIs associated with namespaces, but they will not be
    exported until Tcl 8.1.  Note: the syntax of the namespace command
    has been changed slightly since the b1 release.  See the changes


    file for details.

    3. Binary I/O.  The new object system in Tcl 8.0 supports binary
    strings (internally, strings are counted in addition to being null
    terminated).  There is a new "binary" command for inserting and
    extracting data to/from binary strings.  Commands such as "puts",
    "gets", and "read" commands now operate correctly on binary data. 
    There is a new variable tcl_platform(byteOrder) to identify the

    native byte order for the current host.



    4. Random numbers.  The "expr" command now contains a random number
    generator, which can be accessed via the "rand()" and "srand()" math
    functions.

    5. Safe-Tcl enhancements.  There is a new "hidden command"
    mechanism, implemented with the Tcl commands "interp hide", "interp
    expose", "interp invokehidden", and "interp hidden" and the C APIs
    Tcl_HideCommand and Tcl_ExposeCommand.  There is now support for
    safe packages and extension loading, including new library
    procedures such as safe::interpCreate (see the manual entry safe.n

    for details).

    6. There is a new package "registry" available under Windows for
    accessing the Windows registry.

    7. There is a new command "file attributes" for getting and setting
    things like permissions and owner.  There is also a new command
    "file nativename" for getting back the platform-specific name for a
    particular file.

    8. There is a new "fcopy" command to copy data between channels. 

    This replaces and improves upon the not-so-secret unsupported old


    command "unsupported0".


    9. There is a new package "http" for doing GET, POST, and HEAD
    requests via the HTTP/1.0 protocol.  See the manual entry http.n
    for details.

    10. There are new library procedures for finding word breaks in
    strings.  See the manual entry library.n for details.

    11. There are new C APIs Tcl_Finalize (for cleaning up before
    unloading the Tcl DLL) and Tcl_Ungets for pushing bytes back into a


    channel's input buffer.


    12. Tcl now supports serial I/O devices on Windows and Unix, with a
    new fconfigure -mode option.  The Windows driver does not yet
    support event-driven I/O.




    13. The lsort command has new options -dictionary and -index.  The
    -index option allows for very rapid sorting based on an element
    of a list.

    14. The event notifier has been completely rewritten (again).  It
    should now allow Tcl to use an external event loop (like Motif's)
    when it is embedded in other applications.  No script-level
    interfaces have changed, but many of the C APIs have.

Tcl 8.0 introduces the following incompatibilities that may affect Tcl
scripts that worked under Tcl 7.6 and earlier releases:

    1. Variable and command names may not include the character sequence
    "::" anymore: this sequence is now used as a namespace separator.

    2. The semantics of some Tcl commands have been changed slightly to
    maximize performance under the compiler.  These incompatibilities
    are documented on the Web so that we can keep the list up-to-date.
    See the URL http://www.sunlabs.com/research/tcl/compiler.html.

    3. 2-digit years are now parsed differently by the "clock" command
    to handle year 2000 issues better (years 00-38 are treated as
    2000-2038 instead of 1900-1938).

    4. The old Macintosh commands "cp", "mkdir", "mv", "rm", and "rmdir"
    are no longer supported; all of these features are now available on
    all platforms via the "file" command.

    5. The variable tcl_precision is now shared between interpreters
    and defaults to 12 digits instead of 6; safe interpreters cannot


    modify tcl_precision.  The new object system in Tcl 8.0 causes
    floating-to-string conversions (and the associated rounding) to
    occur much less often than in Tcl 7.6, which can sometimes cause
    behavioral changes.

    6. The C APIs associated with the notifier have changed substantially.





    7. The procedures Tcl_CreateModalTimeout and Tcl_DeleteModalTimeout
    have been removed.

    8. Tcl_CreateFileHandler and Tcl_DeleteFileHandler now take Unix
    fd's and are only supported on the Unix platform

    9. The C APIs for creating channel drivers have changed as part of
    the new notifier implementation.  The Tcl_File interfaces have been
    removed.  Tcl_GetChannelFile has been replaced with
    Tcl_GetChannelHandle.  Tcl_MakeFileChannel now takes a platform-
    specific file handle.  Tcl_DriverGetOptionProc procedures now take

    an additional interp argument.

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

There is a network news group "comp.lang.tcl" intended for the exchange
of information about Tcl, Tk, and related applications.  Feel free to use
the newsgroup both for general information questions and for bug reports.
We read the newsgroup and will attempt to fix bugs and problems reported
to it.

When using comp.lang.tcl, please be sure that your e-mail return address
is correctly set in your postings.  This allows people to respond directly
to you, rather than the entire newsgroup, for answers that are not of
general interest.  A bad e-mail return address may prevent you from
getting answers to your questions.  You may have to reconfigure your news
reading software to ensure that it is supplying valid e-mail addresses.

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. Mailing lists
----------------

A couple of  Mailing List have been set up to discuss Macintosh or
Windows related Tcl issues.  In order to use these Mailing Lists you
must have access to the internet.  If you have access to the WWW the

home pages for these mailing lists are located at the following URLs:


	http://www.sunlabs.com/research/tcl/lists/mactcl-list.html

		-and-

	http://www.sunlabs.com/research/tcl/lists/wintcl-list.html

The home pages contain information about the lists and an HTML archive
of all the past messages on the list.  To subscribe send a message to:
	

	list[email protected].com
	
In the body of the message (the subject will be ignored) put:
	
	subscribe mactcl Joe Blow
	
Replacing Joe Blow with your real name, of course.  (Use wintcl
instead of mactcl if your interested in the Windows list.)  If you
would just like to receive more information about the list without
subscribing put the line:

	information mactcl
	
in the body instead (or wintcl).

8. Support and bug fixes
------------------------

We're very interested in receiving bug reports and suggestions for
improvements.  We prefer that you send this information to the


comp.lang.tcl newsgroup rather than to any of us at Sun.  We'll see

anything on comp.lang.tcl, and in addition someone else who reads 




comp.lang.tcl may be able to offer a solution.  The normal turn-around
time for bugs is 3-6 weeks.  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 turns into a kitchen sink).  It's
very difficult to make incompatible changes to Tcl at this point, due
to the size of the installed base.


When reporting bugs, please provide 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?








The Tcl community is too large for us to provide much individual
support for users.  If you need help we suggest that you post questions
to comp.lang.tcl.  We read the newsgroup and will attempt to answer
esoteric questions for which no-one else is likely to know the answer.
In addition, Tcl support and training are available commercially from

NeoSoft ([email protected]), Computerized Processes Unlimited

([email protected]), and Data Kinetics ([email protected]).





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

>
>
|
>

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


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




|
>
>
>
>
>
|










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









<
<
|
>
|
>
|
>
>
|
>





|
|







|
|

|
<






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







|


|



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

<
<
<
<
<
<
>
>
|

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

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

|
>
|
>
>
|
|
>
|
|
|

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

>
>
>
|
|
|
|
|
|
|
|

|
|
|
<
<

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

<
>
>

>
>
|
|

|
<

<
<
<
<
<
>
|

|
|

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

|










|
|

|
|
|
>
|
>

|
|
<

<
|
<
|

>
|



|

|








|
|

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

|
>
>
|
|
|
|
|





>
>
>
>
>
>
>


|
|
|
|
>
|
>
|
>
>

>
>
|
|
>
>
>
>
>







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

41
42
43

44
45
46
47
48


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105


106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138





























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

159
160


161





162
163

164
165
166






167
168
169
170


171



172
173
174
175
176



177



178

179
180
181
182


183




184
185
186
187
188
189
190
191
192
193
194
195
196


197


198
199
200
201
202



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218


219




220


221
222



223


224
225
226



227

228
229
230
231
232
233
234
235
236

237





238
239
240
241
242
243
244
245
246


247






248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271

272

273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306





307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
README:  Tcl

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

RCS: @(#) $Id: README,v 1.1.2.10 1999/03/17 21:29:56 stanton 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.1b3, which is the third
beta release for Tcl 8.1.  This release is mostly feature complete but
may have bugs and be missing some minor features.  This release is for
early adopters who are willing to help us find and fix problems.
Please let us know about any problems you uncover.

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
with most of the Perl features, 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
library procedures; and files with extension ".n" describe Tcl
commands.  The file "doc/Tcl.n" gives a quick summary of the Tcl
language syntax.  To print any of the man pages on Unix, cd to the
"doc" directory and invoke your favorite variant of troff using the
normal -man macros, for example

		ditroff -man Tcl.n

to print Tcl.n.  If Tcl has been installed correctly and your "man"
program supports it, you should be able to access the Tcl manual entries
using the normal "man" mechanisms, such as

		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]
	mactcl-request@tclconsortium.org
	
In the body of the message (the subject will be ignored) put:
	
	subscribe mactcl Joe Smith
	
Replacing Joe Smith with your real name, of course.  (Use wintcl
instead of mactcl if your interested in the Windows list.)  If you
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.

The Tcl community is too large for us to provide much individual
support for users.  If you need help we suggest that you post
questions to comp.lang.tcl.  We read the newsgroup and will attempt to
answer esoteric questions for which no-one else is likely to know the
answer.  In addition, Tcl/Tk support and training are available
commercially from Scriptics at:

	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
371
372
373
374
375
376
377



378





379
380
381







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.














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

Changes to changes.

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

SCCS: @(#) changes 1.338 97/11/25 08:30:52

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.1.2.28 1999/04/06 19:06:51 surles 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
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
      create a faster internal representation. In the past, if you had a
      misformed list but the erroneous part was after the point you
      inserted or extracted an element, then you never saw an error.
      In Tcl8.0 an error will be reported. This should only effect
      incorrect programs that took advantage of behavior of the old
      implementation that was not documented in the man pages.
Other changes to Tcl scripts are discussed in the web page at
http://www.sunlabs.com/research/tcl/compiler.html. (BL)
*** POTENTIAL INCOMPATIBILITY ***

10/21/96 (new feature) In earlier versions of Tcl, strings were used as a
universal representation; in Tcl 8.0 strings are replaced with Tcl_Obj
structures ("objects") that can hold both a string value and an internal
form such as a binary integer or compiled bytecodes. The new objects make it
possible to store information in efficient internal forms and avoid the







|







2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
      create a faster internal representation. In the past, if you had a
      misformed list but the erroneous part was after the point you
      inserted or extracted an element, then you never saw an error.
      In Tcl8.0 an error will be reported. This should only effect
      incorrect programs that took advantage of behavior of the old
      implementation that was not documented in the man pages.
Other changes to Tcl scripts are discussed in the web page at
http://www.scriptics.com/doc/compiler.html. (BL)
*** POTENTIAL INCOMPATIBILITY ***

10/21/96 (new feature) In earlier versions of Tcl, strings were used as a
universal representation; in Tcl 8.0 strings are replaced with Tcl_Obj
structures ("objects") that can hold both a string value and an internal
form such as a binary integer or compiled bytecodes. The new objects make it
possible to store information in efficient internal forms and avoid the
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125

7/8/97 (bug fix) Fixed core dump in fcopy that could occur when a command
callback was supplied and an error or eof condition caused no background
activity.  A refcount bug triggered a panic in Tcl_ListObjAppendElement. (BW)

7/8/97 (bug fix) Relaxed the pattern matching on http_get so you do not
need a trailing path component.  You can now get away with just
http_get sunscript.sun.com					(BW)

7/9/97 (bug fix) Creating anonymous interpreters no longer smashes existing
commands with names similar to the generated name. Previously creating an
anonymous interpreter could smash an existing command, now it skips until
it finds a command name that isn't being used. (JL)

7/9/97 (feature change) Removed the policy management mechanism from the







|







3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125

7/8/97 (bug fix) Fixed core dump in fcopy that could occur when a command
callback was supplied and an error or eof condition caused no background
activity.  A refcount bug triggered a panic in Tcl_ListObjAppendElement. (BW)

7/8/97 (bug fix) Relaxed the pattern matching on http_get so you do not
need a trailing path component.  You can now get away with just
http_get www.scriptics.com					(BW)

7/9/97 (bug fix) Creating anonymous interpreters no longer smashes existing
commands with names similar to the generated name. Previously creating an
anonymous interpreter could smash an existing command, now it skips until
it finds a command name that isn't being used. (JL)

7/9/97 (feature change) Removed the policy management mechanism from the
3447
3448
3449
3450
3451
3452
3453
























































































































































































































































































































































































































































































































































































































































































































































































































































































11/20/97 (enhancement) Made the changes required by the new Apple
Universal Headers V.3.0, so that Tcl will compile with CW Pro 2.

11/24/97 (bug fix) Fixed tests in clock test suite that needed the
-gmt flag set.  Thanks to Jan Nijtmans for reporting the problem. (RJ)

----------------- Released 8.0p2, 11/25/97 -----------------------































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
11/20/97 (enhancement) Made the changes required by the new Apple
Universal Headers V.3.0, so that Tcl will compile with CW Pro 2.

11/24/97 (bug fix) Fixed tests in clock test suite that needed the
-gmt flag set.  Thanks to Jan Nijtmans for reporting the problem. (RJ)

----------------- Released 8.0p2, 11/25/97 -----------------------

12/3/97 (bug fix/optimization) Removed uneeded and potentially dangerous
instances of double evaluations if "if" and "expr" statements from
the library files. It is recommended that unless you need a double
evaluation you always use "expr {...}" instead of "expr ..." and
"if {...} ..." instead of "if ... ...". It will also be faster
thanks to the byte compiler. (DL)

---- Shipped as part of the plugin2.0b5 as 8.0p2Plugin1, Dec 8th 97 ----

12/8/97 (bug fix) Need to protect the newly accepted channel in an
accept callback on a socket, otherwise the callback may close it and
cause an error, which would cause the C code to attempt to close the
now deleted channel. Bumping the refcount assures that the channel sticks
around to be really closed in this case. (JL)

12/8/97 (bug fix) Need to protect the channel in a fileevent so that it
is not deleted before the fileevent handler returns. (CS, JL)

12/18/97 (bug fix) In the opt argument parsing package: if the description 
had only flags, the "too many arguments" case was not detected. The default
value was not used for the special "args" ending argument. (DL)

1/15/98 (improvement) Moved common part of initScript in common file.
Moved windows specific initialization to init.tcl so you can initialize
Tcl in windows without having to call Tcl_Init which is now only
searching for init.tcl {back ported from 8.1}. (DL)

---- Shipped as part of the plugin as 8.0p2Plugin2, Jan 15th 98 ----

5/27/98 (bug fix) Windows socket driver did not notice new data arriving
on nonblocking sockets until the event loop was entered. (SS)

5/27/98 (bug fix) Windows socket driver used FIONREAD, which is not
supported correctly by WinSock. (SS)

6/9/98 (bug fix) Generic channel code failed to report readable file
events on buffered data that was left behind by a gets or read that
did not consume all available data. (SS)

6/18/98 (bug fix) Compilation of loop expressions was too aggressive
and incorrectly inlined non-literal expressions. (SS)

6/18/98 (bug fix) "info var" and "info locals" incorrectly reported
the existence of compiler temporary variables. (SS)

6/18/98 (bug fix) Dictionary sorting used signed character
comparisons. (SS)

6/18/98 (bug fix) Compile procs corrupted the exception stack in some
cases. (SS)

6/18/98 (bug fix) Array set had erratic behavior when initializing a
variable from an empty value list. (SS)

6/18/98 (bug fix) The Windows registry package had a bad bounds check
that could lead to a crash. (SS)

6/18/98 (bug fix) The foreach compile proc did not correctly handle
non-local variable references. (SS)

6/25/98 (new features) Added name resolution hooks to support [incr Tcl].
There are new internal Tcl_*Resolver* APIs to add, query and remove the hooks. 
With this changes it should be possible to dynamically load [incr Tcl]
as an extension. (MM)

7/1/97 (bug fix) The commands "info args, body, default, procs" did
not correctly handle imported procedures. (RJ)

7/6/98 (improvement) pkg_mkIndex now implements the "package require"
command.  This makes it possible to create index files for packages
that require another package and then execute code from that package in
their file. Previously, this would throw an error because the required
package had not been loaded.  The -nopkgrequied flag is provided to
revert back to the old functionality. (EMS)

7/6/98 (improvement) back-ported the -direct flag from 8.1 into
pkg_mkIndex.  This results in pkgIndex.tcl files that contain direct
source or load commands instead of tclPkgSetup commands. (EMS)

7/6/98 (improvement) made changes to the AuxData items structures to support
storage of compiled scripts on disk. Also some related minor changes in
the compilation and execution engine. (EMS)

6/4/98 (enhancement) Added new internal routines to support inserting
and deleting from the stat, access, and open-file-channel mechanisms.
TclAccessInsertProc, TclStatInsertProc, & TclOpenFileChannelInsertProc
insert pointers to such routines; TclAccessDeleteProc, TclStatDeleteProc,
& TclOpenFileChannelDeleteProc delete pointers to such routines.  See
the file generic/tclIOUtils.c for more details. (SKS)
 
7/1/98 (enhancement) Added a new internal C variable
tclPreInitScript.  This is a pointer to a string that may hold an
initialization script; If this pointer is non-NULL it is evaluated in
Tcl_Init() prior to the built-in initialization script defined in the
file generic/tclInitScript.h.  (SKS)

7/6/98 (bug fix) Removed dead code in PlatformInitExitHandler so that
the TCL_LIBRARY value can be safely patched in binaries. (BW)

7/24/98 (enhancement) Incorporated a new version of auto_mkindex that
can support the [incr Tcl] class structures.  This version will index
all procedures in a source file, not just those where "proc" starts
at the beginning of the line.  If you want the old behavior, use the
auto_mkindex_old procedure. (MM)

7/24/98 (feature change) Changed the Windows registry key to be
HKEY_LOCAL_MACHINE\Software\Scriptics\Tcl\8.0, and to store the path
in the default value instead of "Root".  Also, this key can be
specified at compile time in case Tcl is being used in a different
context where it needs an alternate library path from the standard Tcl
installation. (SS)

7/24/98 (feature change) Changed the search order for init.tcl.  The
tcl_library variable can now be set before calling Tcl_Init to avoid
doing any searches.  If it isn't set, then Tcl checks
env(TCL_LIBRARY), the static value set at compile time, an install
directory relative to the executable, a source directory relative to
the executable, and a tcl directory relative to the source heirarchy
containing the executable.  See the comment at the top of
generic/tclInitScript.h for more details. (SS)

7/27/98 (config change) Changed the use of the DBGX flag in configure.in
and the makefile to be TCL_DBGX.  Users of tclConfig.sh may need to pass
this through their configure files with AC_SUBST. (BW)

729/98 (bug fix) Changed [info body] to return a copy of the body of a
compiled procedure instead of the body itself, to avoid invalidation
of the internal rep and loss of the byte-codes. (EMS)

8/5/98 (bug fix) The platform init code could walk off the end of a
buffer when reading the PkgPath registry value on Windows. (SS)

8/5/98 (Windows makefile change) Introduced a set of macros to deal with
exporting symbols when compiling DLLS on Windows. See win/README for
details. (EMS)

8/5/98 (addendum) Added a second Windows registry key under
HKEY_LOCAL_MACHINE\Software\Scriptics\Tcl\8.0, named "pkgPath".
This is a multi-string value used to initialize the tcl_pkgPath
variable. This is required if extension DLLs are in architecture specific
subdirectories. (SS)

8/6/98 (new feature) Added tcl_findLibrary to init.tcl for use by
extensions, including Tk.  This searches in a canonical way for
an extensions library directory and initialization file. (BW)

8/10/98 (bug fix) Imported commands used to get lost if the target
of the import was redefined.  Tcl_CreateCommand and Tcl_CreateObjCommand
were updated to restore import links. (Note that if you rename a command,
the import links move to the new name, and if you delete a command then
the import links get lost. These semantics have not changed.) (MC)

-------- Released 8.0.3 to the Tcl Consortium CD-ROM project, 8/10/98 ------

9/3/98 (bug fix) Tcl_Realloc was failing under Windows because the
GlobalReAlloc API was not correctly re-allocating blocks that were
32k+.  The fix was to use newer Win32 APIs (HeapAlloc, HeapFree, and
HeapReAlloc.) (BS)

10/5/98 (bug fix) Fixed bug in pkg_mkIndex that caused some files that do
a "package require" of packages in the Tcl libraries to give a warning like
	warning: "xx.tcl" provides more than one package ({xx 2.0} {yy 0.3})
and generate a broken pkgIndex.tcl file. (EMS)

10/5/98 (bug fix) Pkg_mkIndex was not doing a case-insensitive comparison
of extensions to determine whether to load or source a file. Thus, under
Windows, MYDLLNAME.DLL was sourced, and mydllname.dll loaded. (EMS)

10/5/98 (new feature) Created a new Tcl_Obj type, "procbody". This object's
internal representation holds a pointer to a Proc structure. Extended
TclCreateProc to take both strings and "procbody". (EMS)

10/13/98 (bug fix) The "info complete" command can now handle strings
with NULLs embedded.  Thanks to [email protected] 
for providing this fix. (RJ)

10/13/98 (bug fix) The "lsort -dictionary" command did not properly
handle some numbers starting with 0.  Thanks to Richard Hipp
<[email protected]> for submitting the fix to Scriptics. (RJ)

10/13/98 (bug fix) The function Tcl_SetListObj was creating an invalid
Tcl_Obj if the list had zero elements (despite what the comments said
it would do).  Thanks to Sebastian Wangnick for reporting the
problem. (RJ)

10/20/98 (new feature) Added tcl_platform(debug) element to the
tcl_platform array on Windows platform.  The existence of the debug
element of the tcl_platform array indicates that the particular Tcl
shell has been compiled with debug information.  Using
"info exists tcl_platform(debug)" a Tcl script can direct the
interpreter to load debug versions of DLLs with the load
command. (SKS)

10/20/98 (feature change) The Makefile and configure scripts have been
changed for IRIX to build n32 binaries instead of the old 32 abi
format.  If you have extensions built with the o32 abi's you will need
to update them to n32 for them to work with Tcl.  (RJ)
*** POTENTIAL INCOMPATIBILITY ***

10/23/98 (bug fix) tcl_findLibrary had a stray ] in one of the
pathnames it searched for the initialization script.  tclInitScript.h
was incorrectly adding the parent of tcl_library to tcl_pkgPath.  This
logic was moved into init.tcl, and the initialization of auto_path was
documented.  Thanks to Donald Porter and Tom Silva for related
patches. (BW)

10/29/98 (bug fix) Fixed Tcl_NotifyChannel to use Tcl_Preserve instead
of Tcl_RegisterChannel so that 1) unregistered channels do not get
closed after their first fileevent, and 2) errors that occur during
close in a fileevent script are actually reflected by the close
command. (BW)

10/30/98 (bug fix) Overhaul of pkg_mkIndex to deal with transitive
package requires and packages split among scripts and binary files.
Also fixed ommision of global for errorInfo in tcl_findLibrary. (BW)

11/08/98 (bug fix) Fixed the resource command to always detect
the case where a file is opened a second time with the same
permissions.  IM claims that this will always cause the same
FileRef to be returned, but in MacOS 8.1+, this is no longer the case,
so we have to test for this explicitly. (JI)

11/10/98 (feature change) When compiling with Metrowerk's MSL, use the
exit function from MSL rather than ExitToShell.  This allows MSL to
clean up its temporary files. Thanks to Vince Darley for this
improvement. (JI)

----------------- Released 8.0.4, 11/19/98 -------------------------

11/20/98 (bug fix) Handle possible NULL return in TclGetStdFiles. (RJ)

11/20/98 (bug fix) The dltests would not build on SGI.  They reported
that you could not mix n32 with 032 binaries.  The configure script
has been modified to get the EXTRA_CFLAGS from the tcl configure
script.  [Bug id: 840] (RJ)

12/3/98 (bug fix) Windows NT creates sockets so they are inheritable
by default.  Fixed socket code so it turns off this bit right after
creation so sockets aren't kept open by exec'ed processes. [Bug: 892]
Thanks to Kevin Kenny for this fix.  (SS)

1/11/98 (bug fix)  On HP, "info sharedlibextension" was returning 
empty string on static apps.  It now always returns ".sl".  (RJ)

1/28/99 (configure change) Now support -pipe option on gcc.  (RJ)

2/2/99 (bug fix) Fixed initialization problem on Windows where no
searching for init.tcl would be performed if the registry keys were
missing.  (stanton)

2/2/99 (bug fix) Added support for HKEY_PERFORMANCE_DATA and
HKEY_DYN_DATA keys in the "registry" command. (stanton)

2/2/99 (bug fix) ENOTSUP and EOPNOTSUPP clashed on some Linux
variants. (stanton)

2/2/99 (enhancement) The "open" command has been changed to use the
object interfaces. (stanton)

2/2/99 (bug fix) In some cases Tcl would crash due to an overflow of
the exception stack resulting from a missing byte code in some
expressions. (stanton)

2/2/99 (bug fix) Changed configure so Linux and IRIX shared libraries
are linked with the system libraries. (stanton)

2/2/99 (bug fix) Added support for BSDI 4.x (BSD/OS-4*) to the
configure script. (stanton)

2/2/99 (bug fix) Fixed bug where upvar could resurrect a namespace
variable after the namespace had been deleted. (stanton)

2/2/99 (bug fix) In some cases when creating variables, the
interpreter result was being modified even if the TCL_LEAVE_ERR_MSG
flag was set. (stanton)

2/2/99 (bug fix & new feature) Changed the socket drivers to properly
handle failures during an async socket connection.  Added a new
fconfigure option "-error" to retrieve the failure message.  See the
socket.n manual entry for details. (stanton)

2/2/99 (bug fix) Deleting a renamed interp alias could result in a
panic. (stanton)

2/2/99 (feature change/bug fix) Changed the behavior of "file
extension" so that it splits at the last period.  Now the extension of
a file like "foo..o" is ".o" instead of "..o" as in previous versions. 
*** POTENTIAL INCOMPATIBILITY ***

----------------- Released 8.0.5, 3/9/99 -------------------------

======== Changes for 8.0 go above this line ========
======== Changes for 8.1 go below this line ========

6/18/97 (new feature) Tcl now supports international character sets:
    - All C APIs now accept UTF-8 strings instead of iso8859-1 strings,
      wherever you see "char *", unless explicitly noted otherwise.
    - All Tcl strings represented in UTF-8, which is a convenient
      multi-byte encoding of Unicode.  Variable names, procedure names,
      and all other values in Tcl may include arbitrary Unicode characters.
      For example, the Tcl command "string length" returns how many
      Unicode characters are in the argument string.
    - For Java compatibility, embedded null bytes in C strings are
      represented as \xC080 in UTF-8 strings, but the null byte at the end
      of a UTF-8 string remains \0.  Thus Tcl strings once again do not
      contain null bytes, except for termination bytes.
    - For Java compatibility, "\uXXXX" is used in Tcl to enter a Unicode
      character.  "\u0000" through "\uffff" are acceptable Unicode 
      characters.  
    - "\xXX" is used to enter a small Unicode character (between 0 and 255)
      in Tcl.
    - Tcl automatically translates between UTF-8 and the normal encoding for
      the platform during interactions with the system.
    - 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 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.

9/18/97 (enhancement) Literal objects are now shared by the ByteCode
structures created when compiled different scripts. This saves up to 45%
of the total memory needed for all literals. (BL)

9/24/97 (bug fixes) Fixed Tcl_ParseCommand parsing of backslash-newline
sequences at start of command words. Suppressed Tcl_EvalDirect error logging
if non-TCL_OK result wasn't an error. (BL)

10/17/97 (feature enhancement) "~username" now refers to the users' home
directory on Windows (previously always returned failure). (CCS)

10/20/97 (implementation change) The Tcl parser has been completely rewritten
to make it more modular.  It can now be used to parse a script without actually
executing it.  The APIs for the new parser are not correctly exported, but
they will eventually be exported and augmented with Tcl commands so that
Tcl scripts can parse other Tcl scripts. (JO)

10/21/97 (API change) Added "flags" argument to Tcl_EvalObj, removed
Tcl_GlobalEvalObj procedure.  Added new procedures Tcl_Eval2 and
Tcl_EvalObjv. (JO)
*** POTENTIAL INCOMPATIBILITY ***

10/22/97 (API change) Renamed Tcl_ObjSetVar2 and Tcl_ObjGetVar2 to
Tcl_SetObjVar2 and Tcl_GetObjVar2 (for consistency with other C APIs)
and changed the name arguments to be strings instead of objects.  (JO)
*** POTENTIAL INCOMPATIBILITY ***

10/27/97 (enhancement) Bytecode compiler rewritten to use the new Tcl
parser. (BL)

11/3/97 (New routines) Added Tcl_AppendObjToObj, which appends the
string rep of one Tcl_Obj to another. Added Tcl_GetIndexFromObjStruct,
which is similar to Tcl_GetIndexFromObj, except that you can give an
offset between strings. This allows Tcl_GetIndexFromObjStruct to be
called with a table of records which have strings in them. (SRP)

12/4/97 (enhancement) New Tcl expression parser added. Added new procedure
Tcl_ParseExpr and new token types TCL_TOKEN_SUB_EXPR and
TCL_TOKEN_OPERATOR. Expression compiler is reimplemented to use this
parser. (BL)

12/9/97 (bug fix) Tcl_EvalObj() increments/decrements the refcount of the
script object to prevent the object from deleting itself while in the
middle of being evaluated. (CCS)

12/9/97 (bug fix) Memory leak in Tcl_GetsObjCmd(). (CCS)

12/11/97 (bug fix) Environment array leaked memory when compiled with
Visual C++. (SS)

12/11/97 (bug fix) File events and non-blocking I/O did not work on
pipes under Windows.  Changed to use threads to achieve non-blocking
behavior. (SS)

12/18/97 (bug fixes) Fixed segfault in "namespace import"; importing a
procedure that causes a cycle now returns an error. Modified "info procs",
"info args", "info body", and "info default" to return information about
imported procedures as well as procedures defined in a namespace. (BL)

12/19/97 (enhancement) Added new Tcl_GetString() procedure that can be used
in place of Tcl_GetStringFromObj() if the string representation's length
isn't needed. (BL)

12/18/97 (bug fix) In the opt argument parsing package: if the description 
had only flags, the "too many arguments" case was not detected. The default
value was not used for the special "args" ending argument. (DL)

1/7/98 (clean up) Moved everything not absolutly necessary out of init.tcl
procs now in auto.tcl and package.tcl can be autoloaded if needed. (DL)

1/7/98 (enhancement) tcltest made at install time will search for it's
init.tcl where it is, even when using virtual path compilation. (DL)

1/8/98 (os bug workaround) when needed, using a replacement for memcmp so 
string compare "char with high bit set" "char w/o high bit set" returns
the expected value on all platforms. (DL)

1/8/98 (unix portability/configure) building from .../unix/targetName/ 
subdirectories and simply using "../configure" should now work fine. (DL)

1/14/98 (enhancement) Added new regular expression package that
supports AREs, EREs, and BREs.  The new package includes new escape
characters, meta-syntax, and character classes inside brackets.
Regexps involving backslashes may behave differently.  (MH)
*** POTENTIAL INCOMPATIBILITY ***

1/16/98 (os workaround) Under windows, "file volume" was causing chatter
and/or several seconds of hanging when querying empty floppy drives.
Changed implementation to call an empirically-derived function that doesn't
cause this. (CCS)

1/16/98 (enhancement) Converted regular expressions to a Tcl_Obj type so
their compiled form gets cached automatically.  Reduced NSUBEXP from 100
to 20. (BW)

1/16/98 (documentation) Change unclear documentation and comments for
functions like Tcl_TranslateFileName() and Tcl_ExternalToUtfDString().  Now
it explicitly says they take an uninitialized or free DString.  A DString
that is "empty" or "not holding anything" could have been interpreted as one
currently with a zero length, but with a large dynamically allocated buffer.
(CCS)

----------------- Released 8.1a1, 1/22/98 -----------------------

1/28/98 (new feature) Added a "-direct" optional flag to pkg_mkIndex
to generate direct loading package indexes (such those you need
if you use namespaces and plan on using namespace import just after
package require). pkg_mkIndex still has limitations regarding
package dependencies but errors are now ignored and with -direct, correct
package indexes can be generated even if there are dependencies as long 
as the "package provide" are done early enough in the files. (DL)

1/28/98 (enhancement) Performance tuning of regexp and regsub. (CCS)

1/28/98 (bug fix) regexp and regsub with "-indices" returned the byte-offsets
of the characters in the UTF-8 representation, not the character offsets
themselves. (CCS)

1/28/98 (bug fix) "clock format 0 -format %Z -gmt 1" would return the local
timezone string instead of "GMT" on Solaris and Windows.

1/28/98 (bug fix) Restore tty settings when closing serial device on Unix.
This is good behavior when closing real serial devices, essential when
closing the pseudo-device /dev/tty because the user's terminal settings
would be left useless, in raw mode, when tcl quit. (CCS)

1/28/98 (bug fix) Tcl_OpenCommandChannel() was modifying the contents of the
argv array passed to it, causing problems for any caller that wanted to
continue to use the argv array after calling Tcl_OpenCommandChannel(). (CCS)

2/1/98 (bug fix) More bugs with %Z in format string argument to strftime():
1. Borland always returned empty string.
2. MSVC always returned the timezone string for the current time, not the
   timezone string for the specified time.  
3. With MSVC, "clock format 0 -format %Z -gmt 1" would return "GMT" the first
   time it was called, but would return the current timezone string on all
   subsequent calls. (CCS)

2/1/98 (bug fix) "file stat" was broken on Windows.
1. "file stat" of a root directory (local or network) or a relative path that
   resolved to a root directory (c:. when in pwd was c:/) was returning error.
2. "file stat" on a regular file (S_IFREG), the st_mode was sign extended to
   a negative int if the platform-dependant type "mode_t" was declared as a
   short instead of an unsigned short.
3. "file stat" of a network directory, the st_dev was incorrectly reported
   as the id of the last accessed local drive rather than the id of the
   network drive. (CCS)

2/1/98 (bug fix) "file attributes" of a relative path that resolved to a
root directory was returning error. (CCS)

2/1/98 (bug fix) Change error message when "file attribute" could not
determine the attributes for a file.  Previously it would return different
error messages on Unix vs.  Windows vs. Mac. (CCS)

2/4/98 (bug fixes) Fixed several instances of bugs where the parser/compiler 
would reach outside the range of allocated memory. Improved the array
lookup algorithm in set compilation. (DL)

2/5/98 (change) The TCL_PARSE_PART1 flag for Set/Get(Obj)Var2 C APIs is now
deprecated and ignored. The part1 is always parsed when the part2 argument
is NULL. This is to avoid a pattern of errors for extension writers converting
from string based Tcl_SetVar() to new Tcl_SetObjVar2() and who could easily
forget to provide the flag and thus get code working for normal variables 
but not for array elements. The performance hit is minimal. A side effect
of that change is that is is no longer possible to create scalar variables
that can't be accessed by tcl scripts because of their invalid name 
(ending with parenthesis). Likewise it is also parsed and checked to 
ensure that you don't create array elements of array whose name is a valid 
array element because they would not be accessible from scripts anyway. 
Note: There is still duplicate array elements parsing code. (DL)
*** POTENTIAL INCOMPATIBILITY ***

2/11/98 (bug fix) Sharing objects between interps, such as by "interp
eval" or "send" could cause a crash later when dereferencing an interp
that had been deleted, given code such as:
	set a {set x y}
	interp create foo
	interp eval foo $a
	interp delete foo
	unset a
Interp "foo" was gone, but "a" had a internal rep consisting of bytecodes
containing a dangling pointer to "foo".  Unsetting "a" would attempt to
return resources back to "foo", causing a crash as random memory was
accessed.  The lesson is that that if an object's internal rep depends on
an interp (or any other data structure) it must preserve that data in
some fashion. (CCS)

2/11/98 (enhancement) The "interp" command was returning inconsistent error
messages when the specified slave interp could not be found. (CCS)

2/11/98 (bug fix) Result codes like TCL_BREAK and TCL_CONTINUE were not
propagating through the master/slave interp boundaries, such as "interp
eval" and "interp alias".  TCL_OK, TCL_ERROR, and non-standard codes like
teh integer 57 work.  There is still a question as to whether TCL_RETURN
can/should propagate. (CCS)

2/11/98 (bug fix) TclCompileScript() was derefering memory 1 byte before
start of the string to compile, looking for ']'. (CCS,DL)

2/11/98 (bug fix) Tcl_Eval2() was derefering memory 1 byte before start
of the string to eval, looking for ']'. (CCS,DL)

2/11/98 (bug fix) Compiling "set a(b" was running off end of string. (CCS,DL)

2/11/98 (bug fix) Windows initialization code was dereferencing
uninitialized memory if TCL_LIBRARY environment didn't exist. (CCS)

2/11/98 (bug fix) Windows "registry" command was dereferencing
uninitialized memory when constructing the $errorCode for a failed
registry call. (CCS)

2/11/98 (enhancement) Eliminate the TCL_USE_TIMEZONE_VAR definition from
configure.in, because it was the same information as the already existing
HAVE_TM_ZONE definition.  The lack of HAVE_TM_ZONE is used to work around a
Solaris and Windows bug where "clock format [clock sec] -format %Z -gmt 1" 
produces the local timezone string instead of "GMT". (CCS)

2/11/98 (bug fix) Memleaks and dereferencing of uninitialized memory in
regexp if an error occurred while compiling a regular expression. (CCS).

2/18/98 (new feature) Added mutexes and thread local storage in order
to make Tcl thread safe.  For testing purposes, there is a testthread
command that creates a new thread and an interpreter inside it.  See
thread.test for examples, but this script-level interface is not fixed.
Each thread has its own notifier instance to manage its own events,
and threads can post messages to each other's message queue.
This uses pthreads on UNIX, and native thread support on other platforms.
You enable this by configuring with --enable-threads.  Note that at
this time *Tk* is still not thread safe. Special thanks to
Richard Hipp: his earlier implementation inspired this work. (BW, SS, JI)

2/18/98 (hidden feature change) The way the env() array is shared among
interpreters changed.  Updates to env used to trigger write traces in
other interpreters.  This undocumented feature is no longer implemented.
Instead, variable tracing is used to keep the C-level environ array in sync
with the Tcl-level env array. This required adding TCL_TRACE_ARRAY support
to Tcl_TraceVar2 so that array names works properly. (BW)
*** POTENTIAL INCOMPATIBILITY ***

2/18/98 (enhancement) Conditional compilation for unix systems (e.g.,
IRIX, SCO) that use f_bsize instead of st_blksize to determine disk block
size. (CCS)

2/23/98 (bug fix) Fixed the emulation of polling selects in the threaded
version of the Unix notifier.  The bug was showing up on a multiprocessor
as starvation of the notifier thread. (BW)

----------------- Released 8.1a2, Feb 23 1998 -----------------------

9/22/98 (bug fix) Changed the value of TCL_TRACE_ARRAY so it no longer
conflicts with the deprecated TCL_PARSE_PART1 flag.  This should
improve portability of C code. (stanton)

10/6/98 (bug fix) The compile procedure for "if" incorrectly attempted
to match against the literal string "if", resulting in a stack
overflow when "::if" was compiled.  It also would incorrectly accept
"if" instead of "elsif" in later clauses.  (stanton)

10/15/98 (new feature) Added a "totitle" subcommand to the "string"
command to convert strings to capitalize the first character of a string
and lowercase all of the other characters. (stanton)

10/15/98 (bug fix) Changed regexp and string commands to properly
handle case folding according to the Unicode character
tables. (stanton)

10/21/98 (new feature) Added an "encoding" command to facilitate
translations of strings between different character encodings.  See
the encoding.n manual entry for more details. (stanton)

11/3/98 (bug fix) The regular expression character classification
syntax now includes Unicode characters in the supported
classes. (stanton)

11/6/98 (bug fix) Variable traces were causing crashes when upvar
variables went out of scope. [Bug: 796] (stanton)

11/9/98 (bug fix) "format" now correctly handles multibyte characters
in %s format strings. (stanton)

11/10/98 (new feature) "regexp" now accepts three new switches
("-line", "-lineanchor", and "-linestop") that control how regular
expressions treat line breaks. See the regexp manual entry for more
details. (stanton)

11/17/98 (bug fix) "scan" now correctly handles Unicode
characters. (stanton)

11/17/98 (new feature) "scan" now supports XPG3 position specifiers
and the "%n" conversion character.  See the "scan" manual entry for
more details. (stanton)

11/17/98 (bug fix) The Tcl memory allocator now returns 8-byte aligned
chunks of memory which improves performance on Windows and avoids
crashes on other platforms. [Bug: 834] (stanton)

11/23/98 (bug fix) Applied various regular expression performance bug
fixes supplied by Henry Spencer. (stanton)

11/30/98 (bug fix) Fixed various thread related race conditions. [Bug:
880 & 607] (stanton)

11/30/98 (bug fix) Fixed a number of memory overflow and leak
bugs. [Bug: 584] (stanton)

12/1/98 (new feaure) Added support for Korean encodings. (stanton)

12/1/98 (feature change) Changed the Tcl_EvalObjv interface to remove
the string and length arguments.
*** POTENTIAL INCOMPATIBILITY with previous alpha releases ***

12/2/98 (bug fix) Fixed various bugs related to line feed
translation. [Bug: 887] (stanton)

12/4/98 (new feature) Added a message catalog facility to help with
localizing Tcl scripts.  Thanks to Mark Harrison for contributing the
initial implementation of the "msgcat" package. (stanton)

12/7/98 (bug fix) The memory allocator was failing to update the
block list for large memory blocks that were reallocated into a
different address. [Bug: 933] (stanton)

----------------- Released 8.1b1, Dec 10 1998 -----------------------

12/22/98 (performance improvement) Improved the -command option of the
lsort command to better use the object system for improved
performance (about 5x speed up).  Thanks to Syd Polk for suppling the
patch. [RFE: 726] (rjohnson)

2/10/99 (bug fix) Restored the Tcl_ObjSetVar2/Tcl_ObjGetVar2
interfaces from 8.0 and renamed the Tcl_GetObjVar2/Tcl_SetObjVar2
interfaces to Tcl_GetVar2Ex and Tcl_SetVar2Ex.  This should provide
better compatibility with 8.0. (stanton)
*** POTENTIAL INCOMPATIBILITY with previous alpha/beta releases ***

2/10/99 (bug fix) Made the eval interfaces compatible with 8.0 by
renaming Tcl_EvalObj to Tcl_EvalObjEx, renaming Tcl_Eval2 to
Tcl_EvalEx and restoring Tcl_EvalObj and Tcl_GlobalEvalObj interfaces
so they match Tcl 8.0. (stanton)
*** POTENTIAL INCOMPATIBILITY with previous alpha/beta releases ***

2/25/99 (bug fix/new feature) On Windows, the channel drivers for
consoles and serial ports now completely support file events. (redman)

3/5/99 (bug fix) Integrated patches to fix various configure problems
that affected HP-UX-11, 64-bit IRIX, Linux, and Solaris. (stanton)

3/9/99 (bug fix) Integrated various AIX related patches to improve
support for shared libraries. (stanton)

3/9/99 (new feature) Added tcl_platform(user) to provide a portable
way to get the name of the current user. (welch)

3/9/99 (new feature) Integrated the stub library mechanism contributed
by Jan Nijtmans, Paul Duffin, and Jean-Claude Wippler.  This feature
should make it possible to write extensions that support multiple
versions of Tcl simultaneously.  It also makes it possible to
dynamically load extensions into statically linked interpreters.  This
patch includes the following changes:
      -	Added a Tcl_InitStubs() interface
      -	Added Tcl_PkgProvideEx, Tcl_PkgRequireEx, Tcl_PkgPresentEx,
      	and Tcl_PkgPresent.
      - Added va_list versions of all VARARGS functions so they can be
	invoked from wrapper functions.
See the manual for more information. (stanton)


3/10/99 (feature change) Replaced Tcl_AlertNotifier with
Tcl_ThreadAlert since the Tcl_AlertNotifier function relied on passing
internal data structures. (stanton)
*** POTENTIAL INCOMPATIBILITY with previous alpha/beta releases ***

3/10/99 (new feature) Added a Tcl_GetVersion API to make it easier to
check the Tcl version and patch level from C. (redman)

3/14/99 (feature change) Tried to unify the TclpInitLibrary path
routines to look in similar places from Windows to UNIX.  The new
library search path is: TCL_LIBRARY, TCL_LIBRARY/../tcl8.1, relative
to DLL (Windows Only) relative to installed executable, relative to
develop executable, and relative to compiled-in in location (UNIX
Only.)  This fix included:
    - Defining a TclpFindExecutable
    - Moving Tcl_FindExecutable to a common area in tclEncoding.c
    - Modifying the TclpInitLibraryPath routines.
(surles)

3/14/99 (feature change) Added hooks for TclPro Wrapper to initialize
the location of the encoding files and libraries.  This fix included:
    - Adding the TclSetPerInitScript routine.
    - Modifying the Tcl_Init routines to evaluate the non-NULL
      pre-init script.
    - Adding the Tcl_SetdefaultEncodingDir and Tcl_GetDefaultEncodingDir
      routines.
    - Modifying the TclpInitLibrary routines to append the default
      encoding dir.
(surles)

3/14/99 (feature change) Test suite now uses "test" namespace to
define the test procedure and other auxiliary procedures as well as
global variables.
    - Global array testConfige is now called ::test::testConfig.
    - Global variable VERBOSE is now called ::test::verbose, and
      ::test::verbose no longer works with numerical values.  We've
      switched to a bitwise character string.  You can set
      ::test::verbose by using the -verbose option on the Tcl command
      line.
    - Global variable TESTS is now called ::test::matchingTests, and
      can be set on the Tcl command line via the -match option.
    - There is now a ::test::skipTests variable (works similarly to
      ::test::matchTests) that can be set on the Tcl command line via
      the -match option.
    - The test suite can now be run in any working directory.  When
      you run "make test", the working directory is nolonger switched
      to ../tests.
(hirschl)
*** POTENTIAL INCOMPATIBILITY ***

--------------- Released 8.1b2, March 16, 1999 ----------------------

3/18/99 (bug fix) Fixed missing/incorrect characters in shift-jis table
(stanton)

3/18/99 (feature change) The glob command ignores the
FS_CASE_IS_PRESERVED bit on file systesm and always returns
exactly what it gets from the system. (stanton)
*** POTENTIAL INCOMPATIBILITY ***

3/19/99 (new feature) Added support for --enable-64bit.  For now,
this is only supported on Solaris 7 64bit (SunOS 5.7) using the Sun
compiler. (redman)

3/23/99 (bug fix) Fixed fileevents and gets on Windows consoles and
serial devices so that non-blocking channels do not block on partial
input lines.  (redman)

3/23/99 (bug fix) Added a new Tcl_ServiceModeHook interface.
This is used on Windows to avoid the various problems that people
have been seeing where the system hangs when tclsh is running
outside of the event loop. As part of this, renamed
TclpAlertNotifier back to Tcl_AlertNotifier since it is public.
(stanton)

3/23/99 (feature change) Test suite now uses "tcltest" namespace to
define the test procedure and other auxiliary procedures as well as
global variables.  The previously chosen "test" namespace was thought
to be too generic and likely to create conflits.
(hirschl)
*** POTENTIAL INCOMPATIBILITY ***

3/24/99 (bug fix) Make sockets thread safe on Windows.
(redman)

3/24/99 (bug fix) Fix cases where expr would incorrect return
a floating point value instead of an integer. (stanton)

3/25/99 (bug fix) Added ASCII to big5 and gb2312 encodings.
(stanton)

3/25/99 (feature change) Changed so aliases are invoked at current
scope in the target interpreter instead of at the global scope.  This
was an incompatibility introduced in 8.1 that is being removed.
(stanton)
*** POTENTIAL INCOMPATIBILITY with previous beta releases ***

3/26/99 (feature change) --nameble-shared is now the default and build
Tcl as a shared library; specify --disable-shared to build a static Tcl
library and shell.
*** POTENTIAL INCOMPATIBILITY ***

3/29/99 (bug fix)  Removed the stub functions and changed the stub
macros to just use the name without params. Pass &tclStubs into the
interp (don't use tclStubsPtr because of collisions with the stubs on
Solaris). (redman)

3/30/99 (bug fix) Loadable modules are now unloaded at the last
possible moment during Tcl_Finalize to fix various exit-time crashes.
(welch)

3/30/99 (bug fix) Tcl no longer calls setlocale().  It looks at
env(LANG) and env(LC_TYPE) instead.  (stanton)

4/1/99 (bug fix) Fixed the Ultrix multiple symbol definition problem.
Now, even Tcl includes a copy of the Tcl stub library. (redman)

4/1/99 (bug fix) Internationalized the registry package.

4/1/99 (bug fix) Changed the implemenation of Tcl_ConditionWait and
Tcl_ConditionNotify on Windows.  The new algorithm eliminates a race
condition and was suggested by Jim Davidson. (welch)

4/2/99 (new apis)  Made various Unicode utility functions public.
Tcl_UtfToUniCharDString, Tcl_UniCharToUtfDString, Tcl_UniCharLen,
Tcl_UniCharNcmp, Tcl_UniCharIsAlnum, Tcl_UniCharIsAlpha,
Tcl_UniCharIsDigit, Tcl_UniCharIsLower, Tcl_UniCharIsSpace,
Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar, Tcl_WinUtfToTChar,
Tcl_WinTCharToUtf (stanton)

4/2/99 (feature change) Add new DDE package and removed the Tk
send command from the Windows version.  Changed DDE-based send
code into "dde eval" command.  The DDE package can be loaded
into tclsh, not just wish.  Windows only. (redman)

4/5/99 (bug fix) Changed safe-tcl so that the encoding command
is an alias that masks out the "encoding system" subcommand.
(redman)

4/5/99 (bug fix) Configure patches to improve support for
OS/390 and BSD/OS 4.*. (stanton)

4/5/99 (bug fix) Fixed crash in the clock command that occurred
with negative time values in timezones east of GMT. (stanton)

4/6/99 (bug fix) Moved the "array set" C level code into a common
routine (TclArraySet).  The TclSetupEnv routine now uses this API to
create an env array w/ no elements.  This fixes the bug caused when
every environ varaible is removed, and the Tcl env variable is
synched.  If no environ vars existed, the Tcl env var would never be
created. (surles)

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

Changes to compat/README.

1
2
3
4
5
6
7
8
This directory contains various header and code files that are
used make Tcl compatible with various releases of UNIX and UNIX-like
systems.  Typically, files from this directory are used to compile
Tcl when a system doesn't contain the corresponding files or when
they are known to be incorrect.  When the whole world becomes POSIX-
compliant this directory should be unnecessary.

sccsid = SCCS: @(#) README 1.3 96/02/16 08:56:51







|
1
2
3
4
5
6
7
8
This directory contains various header and code files that are
used make Tcl compatible with various releases of UNIX and UNIX-like
systems.  Typically, files from this directory are used to compile
Tcl when a system doesn't contain the corresponding files or when
they are known to be incorrect.  When the whole world becomes POSIX-
compliant this directory should be unnecessary.

RCS: @(#) $Id: README,v 1.1.2.1 1998/09/24 23:58:16 stanton Exp $

Changes to compat/dirent.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * dirent.h --
 *
 *	This file is a replacement for <dirent.h> in systems that
 *	support the old BSD-style <sys/dir.h> with a "struct direct".
 *
 * Copyright (c) 1991 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) dirent.h 1.4 96/02/15 14:43:50
 */

#ifndef _DIRENT
#define _DIRENT

#include <sys/dir.h>













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * dirent.h --
 *
 *	This file is a replacement for <dirent.h> in systems that
 *	support the old BSD-style <sys/dir.h> with a "struct direct".
 *
 * Copyright (c) 1991 The Regents of the University of California.
 * Copyright (c) 1994 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: dirent.h,v 1.1.2.1 1998/09/24 23:58:16 stanton Exp $
 */

#ifndef _DIRENT
#define _DIRENT

#include <sys/dir.h>

Changes to compat/dirent2.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * dirent.h --
 *
 *	Declarations of a library of directory-reading procedures
 *	in the POSIX style ("struct dirent").
 *
 * Copyright (c) 1991 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) dirent2.h 1.4 96/02/15 14:43:51
 */

#ifndef _DIRENT
#define _DIRENT

#ifndef _TCL
#include <tcl.h>












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * dirent.h --
 *
 *	Declarations of a library of directory-reading procedures
 *	in the POSIX style ("struct dirent").
 *
 * Copyright (c) 1991 The Regents of the University of California.
 * Copyright (c) 1994 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: dirent2.h,v 1.1.2.1 1998/09/24 23:58:16 stanton Exp $
 */

#ifndef _DIRENT
#define _DIRENT

#ifndef _TCL
#include <tcl.h>

Changes to compat/dlfcn.h.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *	Not derived from licensed software.
 *
 *	Permission is granted to freely use, copy, modify, and redistribute
 *	this software, provided that the author is not construed to be liable
 *	for any results of using the software, alterations are clearly marked
 *	as such, and this notice is not modified.
 *
 * SCCS: @(#) dlfcn.h 1.4 96/09/17 09:05:59
 */

/*
 * @(#)dlfcn.h	1.4 revision of 95/04/25  09:36:52
 * This is an unpublished work copyright (c) 1992 HELIOS Software GmbH
 * 30159 Hannover, Germany
 */







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *	Not derived from licensed software.
 *
 *	Permission is granted to freely use, copy, modify, and redistribute
 *	this software, provided that the author is not construed to be liable
 *	for any results of using the software, alterations are clearly marked
 *	as such, and this notice is not modified.
 *
 * RCS: @(#) $Id: dlfcn.h,v 1.1.2.1 1998/09/24 23:58:16 stanton Exp $
 */

/*
 * @(#)dlfcn.h	1.4 revision of 95/04/25  09:36:52
 * This is an unpublished work copyright (c) 1992 HELIOS Software GmbH
 * 30159 Hannover, Germany
 */

Changes to compat/fixstrtod.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * fixstrtod.c --
 *
 *	Source code for the "fixstrtod" procedure.  This procedure is
 *	used in place of strtod under Solaris 2.4, in order to fix
 *	a bug where the "end" pointer gets set incorrectly.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) fixstrtod.c 1.5 96/02/15 12:08:21
 */

#include <stdio.h>

#undef strtod

/*












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * fixstrtod.c --
 *
 *	Source code for the "fixstrtod" procedure.  This procedure is
 *	used in place of strtod under Solaris 2.4, in order to fix
 *	a bug where the "end" pointer gets set incorrectly.
 *
 * Copyright (c) 1995 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: fixstrtod.c,v 1.1.2.1 1998/09/24 23:58:17 stanton Exp $
 */

#include <stdio.h>

#undef strtod

/*

Changes to compat/float.h.

8
9
10
11
12
13
14
15
16
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) float.h 1.3 96/02/15 14:43:52
 */







|

8
9
10
11
12
13
14
15
16
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994 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: float.h,v 1.1.2.1 1998/09/24 23:58:17 stanton Exp $
 */

Changes to compat/gettod.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * gettod.c --
 *
 *	This file provides the gettimeofday function on systems
 *	that only have the System V ftime function.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) gettod.c 1.2 96/02/15 12:08:26
 */

#include "tcl.h"
#include "tclPort.h"
#include <sys/timeb.h>

#undef timezone











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * gettod.c --
 *
 *	This file provides the gettimeofday function on systems
 *	that only have the System V ftime function.
 *
 * Copyright (c) 1995 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: gettod.c,v 1.1.2.1 1998/09/24 23:58:17 stanton Exp $
 */

#include "tcl.h"
#include "tclPort.h"
#include <sys/timeb.h>

#undef timezone

Changes to compat/limits.h.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *
 * Copyright (c) 1991 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) limits.h 1.8 96/07/08 18:00:13
 */

#define LONG_MIN		0x80000000
#define LONG_MAX		0x7fffffff
#define INT_MIN			0x80000000
#define INT_MAX			0x7fffffff
#define SHRT_MIN		0x8000







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *
 * Copyright (c) 1991 The Regents of the University of California.
 * Copyright (c) 1994 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: limits.h,v 1.1.2.1 1998/09/24 23:58:17 stanton Exp $
 */

#define LONG_MIN		0x80000000
#define LONG_MAX		0x7fffffff
#define INT_MIN			0x80000000
#define INT_MAX			0x7fffffff
#define SHRT_MIN		0x8000

Added compat/memcmp.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
/* 
 * memcmp.c --
 *
 *	Source code for the "memcmp" library routine.
 *
 * 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.
 *
 * SCCS: @(#) memcmp.c 1.2 98/01/19 10:48:58
 */

#include "tcl.h"
#include "tclPort.h"

/*
 * Here is the prototype just in case it is not included
 * in tclPort.h.
 */

int		memcmp _ANSI_ARGS_((CONST VOID *s1,
			    CONST VOID *s2, size_t n));

/*
 *----------------------------------------------------------------------
 *
 * memcmp --
 *
 *	Compares two bytes sequences.
 *
 * Results:
 *     compares  its  arguments, looking at the first n
 *     bytes (each interpreted as an unsigned char), and  returns
 *     an integer less than, equal to, or greater than 0, accord-
 *     ing as s1 is less  than,  equal  to,  or
 *     greater than s2 when taken to be unsigned 8 bit numbers.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
memcmp(s1, s2, n)
    CONST VOID *s1;			/* First string. */
    CONST VOID *s2;			/* Second string. */
    size_t      n;                      /* Length to compare. */
{
    unsigned char u1, u2;

    for ( ; n-- ; s1++, s2++) {
	u1 = * (unsigned char *) s1;
	u2 = * (unsigned char *) s2;
	if ( u1 != u2) {
	    return (u1-u2);
	}
    }
    return 0;
}

Changes to compat/opendir.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* 
 * opendir.c --
 *
 *	This file provides dirent-style directory-reading procedures
 *	for V7 Unix systems that don't have such procedures.  The
 *	origin of this code is unclear, but it seems to have come
 *	originally from Larry Wall.
 *
 *
 * SCCS: @(#) opendir.c 1.3 96/02/15 12:08:21
 */

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

#undef DIRSIZ
#define DIRSIZ(dp) \









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* 
 * opendir.c --
 *
 *	This file provides dirent-style directory-reading procedures
 *	for V7 Unix systems that don't have such procedures.  The
 *	origin of this code is unclear, but it seems to have come
 *	originally from Larry Wall.
 *
 *
 * RCS: @(#) $Id: opendir.c,v 1.1.2.1 1998/09/24 23:58:17 stanton Exp $
 */

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

#undef DIRSIZ
#define DIRSIZ(dp) \

Changes to compat/stdlib.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * stdlib.h --
 *
 *	Declares facilities exported by the "stdlib" portion of
 *	the C library.  This file isn't complete in the ANSI-C
 *	sense;  it only declares things that are needed by Tcl.
 *	This file is needed even on many systems with their own
 *	stdlib.h (e.g. SunOS) because not all stdlib.h files
 *	declare all the procedures needed here (such as strtod).
 *
 * Copyright (c) 1991 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) stdlib.h 1.10 96/02/15 14:43:54
 */

#ifndef _STDLIB
#define _STDLIB

#include <tcl.h>












|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * stdlib.h --
 *
 *	Declares facilities exported by the "stdlib" portion of
 *	the C library.  This file isn't complete in the ANSI-C
 *	sense;  it only declares things that are needed by Tcl.
 *	This file is needed even on many systems with their own
 *	stdlib.h (e.g. SunOS) because not all stdlib.h files
 *	declare all the procedures needed here (such as strtod).
 *
 * Copyright (c) 1991 The Regents of the University of California.
 * Copyright (c) 1994-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: stdlib.h,v 1.1.2.2 1998/09/24 23:58:17 stanton Exp $
 */

#ifndef _STDLIB
#define _STDLIB

#include <tcl.h>

Changes to compat/strftime.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * strftime.c --
 *
 *	This file contains a modified version of the BSD 4.4 strftime
 *	function.
 *
 * This file is a modified version of the strftime.c file from the BSD 4.4
 * source.  See the copyright notice below for details on redistribution
 * restrictions.  The "license.terms" file does not apply to this file.
 *
 * SCCS: @(#) strftime.c 1.4 97/08/07 17:17:02
 */

/*
 * Copyright (c) 1989 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * strftime.c --
 *
 *	This file contains a modified version of the BSD 4.4 strftime
 *	function.
 *
 * This file is a modified version of the strftime.c file from the BSD 4.4
 * source.  See the copyright notice below for details on redistribution
 * restrictions.  The "license.terms" file does not apply to this file.
 *
 * RCS: @(#) $Id: strftime.c,v 1.1.2.3 1999/03/10 06:49:09 stanton Exp $
 */

/*
 * Copyright (c) 1989 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)strftime.c	5.11 (Berkeley) 2/24/91";*/
static char *rcsid = "$Id: strftime.c,v 1.1 1998/03/26 14:46:31 rjohnson Exp $";
#endif /* LIBC_SCCS and not lint */

#include <time.h>
#include <string.h>
#include <locale.h>
#include "tclInt.h"
#include "tclPort.h"








|
<
|
|







40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#if defined(LIBC_SCCS)

static char *rcsid = "$Id: strftime.c,v 1.1.2.3 1999/03/10 06:49:09 stanton Exp $";
#endif /* LIBC_SCCS */

#include <time.h>
#include <string.h>
#include <locale.h>
#include "tclInt.h"
#include "tclPort.h"

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
static int		 _add _ANSI_ARGS_((const char* str));
static int		_conv _ANSI_ARGS_((int n, int digits, int pad));
static int		_secs _ANSI_ARGS_((const struct tm *t));
static size_t		_fmt _ANSI_ARGS_((const char *format,
			    const struct tm *t));

size_t
TclStrftime(s, maxsize, format, t)
    char *s;
    size_t maxsize;
    const char *format;
    const struct tm *t;
{
    tzset();








|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
static int		 _add _ANSI_ARGS_((const char* str));
static int		_conv _ANSI_ARGS_((int n, int digits, int pad));
static int		_secs _ANSI_ARGS_((const struct tm *t));
static size_t		_fmt _ANSI_ARGS_((const char *format,
			    const struct tm *t));

size_t
TclpStrftime(s, maxsize, format, t)
    char *s;
    size_t maxsize;
    const char *format;
    const struct tm *t;
{
    tzset();

312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
		    continue;
		case 'Y':
		    if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0'))
			return(0);
		    continue;
#ifndef MAC_TCL
		case 'Z': {
		    char *name = TclpGetTZName();
		    if (name && !_add(name)) {
			return 0;
		    }
		    continue;
		}
#endif
		case '%':







|







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
		    continue;
		case 'Y':
		    if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0'))
			return(0);
		    continue;
#ifndef MAC_TCL
		case 'Z': {
		    char *name = TclpGetTZName(t->tm_isdst);
		    if (name && !_add(name)) {
			return 0;
		    }
		    continue;
		}
#endif
		case '%':

Changes to compat/string.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * string.h --
 *
 *	Declarations of ANSI C library procedures for string handling.
 *
 * Copyright (c) 1991-1993 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) string.h 1.13 96/04/09 22:14:53
 */

#ifndef _STRING
#define _STRING

#include <tcl.h>












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * string.h --
 *
 *	Declarations of ANSI C library procedures for string handling.
 *
 * Copyright (c) 1991-1993 The Regents of the University of California.
 * Copyright (c) 1994-1996 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: string.h,v 1.1.2.2 1998/09/24 23:58:17 stanton Exp $
 */

#ifndef _STRING
#define _STRING

#include <tcl.h>

28
29
30
31
32
33
34



35
36

37
38
39
40
41
42
43
#include <sys/types.h>
#endif

extern char *		memchr _ANSI_ARGS_((CONST VOID *s, int c, size_t n));
extern int		memcmp _ANSI_ARGS_((CONST VOID *s1, CONST VOID *s2,
			    size_t n));
extern char *		memcpy _ANSI_ARGS_((VOID *t, CONST VOID *f, size_t n));



extern char *		memmove _ANSI_ARGS_((VOID *t, CONST VOID *f,
			    size_t n));

extern char *		memset _ANSI_ARGS_((VOID *s, int c, size_t n));

extern int		strcasecmp _ANSI_ARGS_((CONST char *s1,
			    CONST char *s2));
extern char *		strcat _ANSI_ARGS_((char *dst, CONST char *src));
extern char *		strchr _ANSI_ARGS_((CONST char *string, int c));
extern int		strcmp _ANSI_ARGS_((CONST char *s1, CONST char *s2));







>
>
>


>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <sys/types.h>
#endif

extern char *		memchr _ANSI_ARGS_((CONST VOID *s, int c, size_t n));
extern int		memcmp _ANSI_ARGS_((CONST VOID *s1, CONST VOID *s2,
			    size_t n));
extern char *		memcpy _ANSI_ARGS_((VOID *t, CONST VOID *f, size_t n));
#ifdef NO_MEMMOVE
#define memmove(d, s, n) bcopy ((s), (d), (n))
#else
extern char *		memmove _ANSI_ARGS_((VOID *t, CONST VOID *f,
			    size_t n));
#endif
extern char *		memset _ANSI_ARGS_((VOID *s, int c, size_t n));

extern int		strcasecmp _ANSI_ARGS_((CONST char *s1,
			    CONST char *s2));
extern char *		strcat _ANSI_ARGS_((char *dst, CONST char *src));
extern char *		strchr _ANSI_ARGS_((CONST char *string, int c));
extern int		strcmp _ANSI_ARGS_((CONST char *s1, CONST char *s2));

Changes to compat/strncasecmp.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * strncasecmp.c --
 *
 *	Source code for the "strncasecmp" library routine.
 *
 * Copyright (c) 1988-1993 The Regents of the University of California.
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) strncasecmp.c 1.7 96/10/24 15:23:36
 */

#include "tclPort.h"

/*
 * This array is designed for mapping upper and lower case letter
 * together for a case independent comparison.  The mappings are











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * strncasecmp.c --
 *
 *	Source code for the "strncasecmp" library routine.
 *
 * Copyright (c) 1988-1993 The Regents of the University of California.
 * Copyright (c) 1995-1996 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: strncasecmp.c,v 1.1.2.1 1998/09/24 23:58:17 stanton Exp $
 */

#include "tclPort.h"

/*
 * This array is designed for mapping upper and lower case letter
 * together for a case independent comparison.  The mappings are

Changes to compat/strstr.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * strstr.c --
 *
 *	Source code for the "strstr" library routine.
 *
 * Copyright (c) 1988-1993 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) strstr.c 1.4 96/02/15 12:08:22
 */

/*
 *----------------------------------------------------------------------
 *
 * strstr --
 *











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * strstr.c --
 *
 *	Source code for the "strstr" library routine.
 *
 * Copyright (c) 1988-1993 The Regents of the University of California.
 * Copyright (c) 1994 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: strstr.c,v 1.1.2.1 1998/09/24 23:58:18 stanton Exp $
 */

/*
 *----------------------------------------------------------------------
 *
 * strstr --
 *

Changes to compat/strtod.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * strtod.c --
 *
 *	Source code for the "strtod" library procedure.
 *
 * Copyright (c) 1988-1993 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) strtod.c 1.9 96/12/13 15:02:46
 */

#include "tcl.h"
#ifdef NO_STDLIB_H
#   include "../compat/stdlib.h"
#else
#   include <stdlib.h>











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * strtod.c --
 *
 *	Source code for the "strtod" library procedure.
 *
 * Copyright (c) 1988-1993 The Regents of the University of California.
 * Copyright (c) 1994 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: strtod.c,v 1.1.2.1 1998/09/24 23:58:18 stanton Exp $
 */

#include "tcl.h"
#ifdef NO_STDLIB_H
#   include "../compat/stdlib.h"
#else
#   include <stdlib.h>

Changes to compat/strtol.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * strtol.c --
 *
 *	Source code for the "strtol" library procedure.
 *
 * Copyright (c) 1988 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) strtol.c 1.4 96/02/15 12:08:23
 */

#include <ctype.h>


/*
 *----------------------------------------------------------------------











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * strtol.c --
 *
 *	Source code for the "strtol" library procedure.
 *
 * Copyright (c) 1988 The Regents of the University of California.
 * Copyright (c) 1994 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: strtol.c,v 1.1.2.1 1998/09/24 23:58:18 stanton Exp $
 */

#include <ctype.h>


/*
 *----------------------------------------------------------------------

Changes to compat/strtoul.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * strtoul.c --
 *
 *	Source code for the "strtoul" library procedure.
 *
 * Copyright (c) 1988 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) strtoul.c 1.5 96/02/15 12:08:24
 */

#include <ctype.h>

/*
 * The table below is used to convert from ASCII digits to a
 * numerical equivalent.  It maps from '0' through 'z' to integers











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * strtoul.c --
 *
 *	Source code for the "strtoul" library procedure.
 *
 * Copyright (c) 1988 The Regents of the University of California.
 * Copyright (c) 1994 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: strtoul.c,v 1.1.2.1 1998/09/24 23:58:18 stanton Exp $
 */

#include <ctype.h>

/*
 * The table below is used to convert from ASCII digits to a
 * numerical equivalent.  It maps from '0' through 'z' to integers

Changes to compat/tclErrno.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclErrno.h --
 *
 *	This header file contains the various POSIX errno definitions that
 *	are used by Tcl.  This file is derived from the spec POSIX 2.4 and
 *	previous implementations for Berkeley UNIX.
 *
 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
 * Copyright (c) 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclErrno.h 1.1 96/04/29 15:25:31
 */

extern int errno;			/* global error number */

#define	EPERM		1		/* Operation not permitted */
#define	ENOENT		2		/* No such file or directory */
#define	ESRCH		3		/* No such process */













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclErrno.h --
 *
 *	This header file contains the various POSIX errno definitions that
 *	are used by Tcl.  This file is derived from the spec POSIX 2.4 and
 *	previous implementations for Berkeley UNIX.
 *
 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
 * Copyright (c) 1996 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: tclErrno.h,v 1.1.2.1 1998/09/24 23:58:18 stanton Exp $
 */

extern int errno;			/* global error number */

#define	EPERM		1		/* Operation not permitted */
#define	ENOENT		2		/* No such file or directory */
#define	ESRCH		3		/* No such process */

Changes to compat/tmpnam.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (c) 1988 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that this notice is preserved and that due credit is given
 * to the University of California at Berkeley. The name of the University
 * may not be used to endorse or promote products derived from this
 * software without specific written prior permission. This software
 * is provided ``as is'' without express or implied warranty.
 *
 * SCCS: @(#) tmpnam.c 1.3 96/02/15 12:08:25
 */

#include <sys/param.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <stdio.h>












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (c) 1988 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that this notice is preserved and that due credit is given
 * to the University of California at Berkeley. The name of the University
 * may not be used to endorse or promote products derived from this
 * software without specific written prior permission. This software
 * is provided ``as is'' without express or implied warranty.
 *
 * RCS: @(#) $Id: tmpnam.c,v 1.1.2.1 1998/09/24 23:58:18 stanton Exp $
 */

#include <sys/param.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <stdio.h>

Changes to compat/unistd.h.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies.  The University of California
 * makes no representations about the suitability of this
 * software for any purpose.  It is provided "as is" without
 * express or implied warranty.
 *
 * SCCS: @(#) unistd.h 1.7 96/02/15 14:43:57
 */

#ifndef _UNISTD
#define _UNISTD

#include <sys/types.h>
#ifndef _TCL







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies.  The University of California
 * makes no representations about the suitability of this
 * software for any purpose.  It is provided "as is" without
 * express or implied warranty.
 *
 * RCS: @(#) $Id: unistd.h,v 1.1.2.1 1998/09/24 23:58:18 stanton Exp $
 */

#ifndef _UNISTD
#define _UNISTD

#include <sys/types.h>
#ifndef _TCL

Changes to compat/waitpid.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) waitpid.c 1.9 96/02/15 12:08:26
 */

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

/*
 * A linked list of the following structures is used to keep track







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994 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: waitpid.c,v 1.1.2.1 1998/09/24 23:58:18 stanton Exp $
 */

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

/*
 * A linked list of the following structures is used to keep track

Changes to doc/AddErrInfo.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) 1989-1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) AddErrInfo.3 1.28 97/06/12 13:39:53
'\" 
.so man.macros
.TH Tcl_AddErrorInfo 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_AddObjErrorInfo, Tcl_AddErrorInfo, Tcl_SetErrorCode, Tcl_PosixError \- record information about errors
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
\fBTcl_AddObjErrorInfo\fR(\fIinterp, message, length\fR)
.sp
\fBTcl_AddErrorInfo\fR(\fIinterp, message\fR)
.sp
\fBTcl_SetObjErrorCode\fR(\fIinterp, errorObjPtr\fR)
.sp
\fBTcl_SetErrorCode\fR(\fIinterp, element, element, ... \fB(char *) NULL\fR)


.sp
char *
\fBTcl_PosixError\fR(\fIinterp\fR)
.SH ARGUMENTS
.AS Tcl_Interp *message
.AP Tcl_Interp *interp in
Interpreter in which to record information.







|





|











>
>







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
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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: AddErrInfo.3,v 1.1.2.2 1999/03/10 06:49:10 stanton Exp $
'\" 
.so man.macros
.TH Tcl_AddErrorInfo 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_AddObjErrorInfo, Tcl_AddErrorInfo, Tcl_SetErrorCode, Tcl_SetErrorCodeVA, Tcl_PosixError \- record information about errors
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
\fBTcl_AddObjErrorInfo\fR(\fIinterp, message, length\fR)
.sp
\fBTcl_AddErrorInfo\fR(\fIinterp, message\fR)
.sp
\fBTcl_SetObjErrorCode\fR(\fIinterp, errorObjPtr\fR)
.sp
\fBTcl_SetErrorCode\fR(\fIinterp, element, element, ... \fB(char *) NULL\fR)
.sp
\fBTcl_SetErrorCodeVA\fR(\fIinterp, argList\fR)
.sp
char *
\fBTcl_PosixError\fR(\fIinterp\fR)
.SH ARGUMENTS
.AS Tcl_Interp *message
.AP Tcl_Interp *interp in
Interpreter in which to record information.
43
44
45
46
47
48
49



50
51
52
53
54
55
56
setting the \fBerrorInfo\fR variable.
If negative, all bytes up to the first null byte are used.
.AP Tcl_Obj *errorObjPtr in
This variable \fBerrorCode\fR will be set to this value.
.AP char *element in
String to record as one element of \fBerrorCode\fR variable.
Last \fIelement\fR argument must be NULL.



.BE

.SH DESCRIPTION
.PP
These procedures are used to manipulate two Tcl global variables
that hold information about errors.
The variable \fBerrorInfo\fR holds a stack trace of the







>
>
>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
setting the \fBerrorInfo\fR variable.
If negative, all bytes up to the first null byte are used.
.AP Tcl_Obj *errorObjPtr in
This variable \fBerrorCode\fR will be set to this value.
.AP char *element in
String to record as one element of \fBerrorCode\fR variable.
Last \fIelement\fR argument must be NULL.
.AP va_list argList in
An argument list which must have been initialised using
\fBTCL_VARARGS_START\fR, and cleared using \fBva_end\fR.
.BE

.SH DESCRIPTION
.PP
These procedures are used to manipulate two Tcl global variables
that hold information about errors.
The variable \fBerrorInfo\fR holds a stack trace of the
114
115
116
117
118
119
120



121
122
123
124
125
126
127
\fBerrorCode\fR to \fBNONE\fR.
.PP
The procedure \fBTcl_SetErrorCode\fR is also used to set the
\fBerrorCode\fR variable. However, it takes one or more strings to
record instead of an object. Otherwise, it is similar to
\fBTcl_SetObjErrorCode\fR in behavior.
.PP



\fBTcl_PosixError\fR
sets the \fBerrorCode\fR variable after an error in a POSIX kernel call.
It reads the value of the \fBerrno\fR C variable and calls
\fBTcl_SetErrorCode\fR to set \fBerrorCode\fR in the \fBPOSIX\fR format.
The caller must previously have called \fBTcl_SetErrno\fR to set
\fBerrno\fR; this is necessary on some platforms (e.g. Windows) where Tcl
is linked into an application as a shared library, or when the error







>
>
>







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
\fBerrorCode\fR to \fBNONE\fR.
.PP
The procedure \fBTcl_SetErrorCode\fR is also used to set the
\fBerrorCode\fR variable. However, it takes one or more strings to
record instead of an object. Otherwise, it is similar to
\fBTcl_SetObjErrorCode\fR in behavior.
.PP
\fBTcl_SetErrorCodeVA\fR is the same as \fBTcl_SetErrorCode\fR except that
instead of taking a variable number of arguments it takes an argument list.
.PP
\fBTcl_PosixError\fR
sets the \fBerrorCode\fR variable after an error in a POSIX kernel call.
It reads the value of the \fBerrno\fR C variable and calls
\fBTcl_SetErrorCode\fR to set \fBerrorCode\fR in the \fBPOSIX\fR format.
The caller must previously have called \fBTcl_SetErrno\fR to set
\fBerrno\fR; this is necessary on some platforms (e.g. Windows) where Tcl
is linked into an application as a shared library, or when the error

Changes to doc/Alloc.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Alloc.3 1.2 96/06/05 18:00:19
'\" 
.so man.macros
.TH Tcl_Alloc 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Alloc, Tcl_Free, Tcl_Realloc \- allocate or free heap memory
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 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: Alloc.3,v 1.1.2.1 1998/09/24 23:58:19 stanton Exp $
'\" 
.so man.macros
.TH Tcl_Alloc 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Alloc, Tcl_Free, Tcl_Realloc \- allocate or free heap memory
.SH SYNOPSIS

Changes to doc/AllowExc.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) AllowExc.3 1.5 96/03/25 19:55:47
'\" 
.so man.macros
.TH Tcl_AllowExceptions 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_AllowExceptions \- allow all exceptions in next script evaluation
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: AllowExc.3,v 1.1.2.1 1998/09/24 23:58:19 stanton Exp $
'\" 
.so man.macros
.TH Tcl_AllowExceptions 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_AllowExceptions \- allow all exceptions in next script evaluation
.SH SYNOPSIS

Changes to doc/AppInit.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) AppInit.3 1.10 96/08/26 12:59:40
'\" 
.so man.macros
.TH Tcl_AppInit 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_AppInit \- perform application-specific initialization
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: AppInit.3,v 1.1.2.1 1998/09/24 23:58:19 stanton Exp $
'\" 
.so man.macros
.TH Tcl_AppInit 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_AppInit \- perform application-specific initialization
.SH SYNOPSIS

Changes to doc/AssocData.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" 
'\" SCCS: @(#) AssocData.3 1.8 96/03/25 19:56:17
.so man.macros
.TH Tcl_SetAssocData 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetAssocData, Tcl_SetAssocData, Tcl_DeleteAssocData \- manage
associations of string keys and user specified data with Tcl
interpreters.







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1995-1996 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: AssocData.3,v 1.1.2.2 1999/04/09 21:01:29 surles Exp $
.so man.macros
.TH Tcl_SetAssocData 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetAssocData, Tcl_SetAssocData, Tcl_DeleteAssocData \- manage
associations of string keys and user specified data with Tcl
interpreters.
80
81
82
83
84
85
86
87
88
89
specified key in the given interpreter, and if the \fIdelProcPtr\fR field
is non-\fBNULL\fR, the address indicated by it gets the address of the
delete procedure stored with this association. If no association with the
specified key exists in the given interpreter \fBTcl_GetAssocData\fR
returns \fBNULL\fR.
.PP
\fBTcl_DeleteAssocData\fR deletes an association with a specified key in
the given interpreter.  It does not call the deletion procedure.
.SH KEYWORDS
association, data, deletion procedure, interpreter, key







|


80
81
82
83
84
85
86
87
88
89
specified key in the given interpreter, and if the \fIdelProcPtr\fR field
is non-\fBNULL\fR, the address indicated by it gets the address of the
delete procedure stored with this association. If no association with the
specified key exists in the given interpreter \fBTcl_GetAssocData\fR
returns \fBNULL\fR.
.PP
\fBTcl_DeleteAssocData\fR deletes an association with a specified key in
the given interpreter.  Then it calls the deletion procedure.
.SH KEYWORDS
association, data, deletion procedure, interpreter, key

Changes to doc/Async.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Async.3 1.14 96/08/26 12:59:41
'\" 
.so man.macros
.TH Tcl_AsyncCreate 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_AsyncCreate, Tcl_AsyncMark, Tcl_AsyncInvoke, Tcl_AsyncDelete \- handle asynchronous events
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_AsyncHandler
\fBTcl_AsyncCreate\fR(\fIproc, clientData\fR)
.sp







|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: Async.3,v 1.1.2.2 1999/04/14 00:30:35 surles Exp $
'\" 
.so man.macros
.TH Tcl_AsyncCreate 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_AsyncCreate, Tcl_AsyncMark, Tcl_AsyncInvoke, Tcl_AsyncDelete, Tcl_AsyncReady \- handle asynchronous events
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_AsyncHandler
\fBTcl_AsyncCreate\fR(\fIproc, clientData\fR)
.sp

Changes to doc/BackgdErr.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1992-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) BackgdErr.3 1.3 96/03/25 19:56:51
'\" 
.so man.macros
.TH Tcl_BackgroundError 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_BackgroundError \- report Tcl error that occurred in background processing
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1992-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: BackgdErr.3,v 1.1.2.1 1998/09/24 23:58:19 stanton Exp $
'\" 
.so man.macros
.TH Tcl_BackgroundError 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_BackgroundError \- report Tcl error that occurred in background processing
.SH SYNOPSIS

Changes to doc/Backslash.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Backslash.3 1.16 96/03/25 19:57:09
'\" 
.so man.macros
.TH Tcl_Backslash 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Backslash \- parse a backslash sequence
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp







|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: Backslash.3,v 1.1.2.2 1998/09/24 23:58:20 stanton Exp $
'\" 
.so man.macros
.TH Tcl_Backslash 3 "8.1" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Backslash \- parse a backslash sequence
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
26
27
28
29
30
31
32




33
34
35

36
37
38
39
40
41
42




43
44
45
If \fIcountPtr\fR isn't NULL, \fI*countPtr\fR gets filled
in with number of characters in the backslash sequence, including
the backslash character.
.BE

.SH DESCRIPTION
.PP




This is a utility procedure used by several of the Tcl
commands.  It parses a backslash sequence and returns
the single character corresponding to the sequence.

\fBTcl_Backslash\fR modifies \fI*countPtr\fR to contain the number
of characters in the backslash sequence.
.PP
See the Tcl manual entry for information on the valid
backslash sequences.
All of the sequences described in the Tcl
manual entry are supported by \fBTcl_Backslash\fR.





.SH KEYWORDS
backslash, parse







>
>
>
>
|
|
|
>
|
|

|
<
|
|
>
>
>
>



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
If \fIcountPtr\fR isn't NULL, \fI*countPtr\fR gets filled
in with number of characters in the backslash sequence, including
the backslash character.
.BE

.SH DESCRIPTION
.PP
.VS 8.1
The use of \fBTcl_Backslash\fR is deprecated in favor of
\fBTcl_UtfBackslash\fR.
.PP
This is a utility procedure provided for backwards compatibilty with
non-internationalized Tcl extensions.  It parses a backslash sequence and
returns the low byte of the Unicode character corresponding to the sequence. 
.VE
\fBTcl_Backslash\fR modifies \fI*countPtr\fR to contain the number of
characters in the backslash sequence.
.PP
See the Tcl manual entry for information on the valid backslash sequences.

All of the sequences described in the Tcl manual entry are supported by
\fBTcl_Backslash\fR.
.VS 8.1 br
.SH "SEE ALSO"
Tcl(n), Tcl_UtfBackslash(3)
.VE

.SH KEYWORDS
backslash, parse

Changes to doc/BoolObj.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) @(#) BoolObj.3 1.7 97/05/08 19:50:57
'\" 
.so man.macros
.TH Tcl_BooleanObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewBooleanObj, Tcl_SetBooleanObj, Tcl_GetBooleanFromObj \- manipulate Tcl objects as boolean values
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: BoolObj.3,v 1.1.2.1 1998/09/24 23:58:20 stanton Exp $
'\" 
.so man.macros
.TH Tcl_BooleanObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewBooleanObj, Tcl_SetBooleanObj, Tcl_GetBooleanFromObj \- manipulate Tcl objects as boolean values
.SH SYNOPSIS

Added doc/ByteArrObj.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) 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: ByteArrObj.3,v 1.1.2.2 1998/10/21 20:21:31 stanton Exp $
'\" 
.so man.macros
.TH Tcl_ByteArrayObj 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl objects as a arrays of bytes 
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_Obj *
\fBTcl_NewByteArrayObj\fR(\fIbytes, length\fR)
.sp
void 
\fBTcl_SetByteArrayObj\fR(\fIobjPtr, bytes, length\fR)
.sp
unsigned char *
\fBTcl_GetByteArrayFromObj\fR(\fIobjPtr, lengthPtr\fR)
.sp
unsigned char *
\fBTcl_SetByteArrayLength\fR(\fIobjPtr, length\fR)
.SH ARGUMENTS
.AS "unsigned char" *lengthPtr in/out
.AP "unsigned char" *bytes in
The array of bytes used to initialize or set a byte-array object.
.AP int length in
The length of the array of bytes.  It must be >= 0.
.AP Tcl_Obj *objPtr in/out
For \fBTcl_SetByteArrayObj\fR, this points to the object to be converted to
byte-array type.  For \fBTcl_GetByteArrayFromObj\fR and
\fBTcl_SetByteArrayLength\fR, this points to the object from which to get
the byte-array value; if \fIobjPtr\fR does not already point to a byte-array
object, it will be converted to one.
.AP int *lengthPtr out
If non-NULL, filled with the length of the array of bytes in the object.
.BE

.SH DESCRIPTION
.PP
These procedures are used to create, modify, and read Tcl byte-array objects
from C code.  Byte-array objects are typically used to hold the
results of binary IO operations or data structures created with the
\fBbinary\fR command.  In Tcl, an array of bytes is not equivalent to a
string.  Conceptually, a string is an array of Unicode characters, while a
byte-array is an array of 8-bit quantities with no implicit meaning.
Accesser functions are provided to get the string representation of a
byte-array or to convert an arbitrary object to a byte-array.  Obtaining the
string representation of a byte-array object (by calling
\fBTcl_GetStringFromObj\fR) produces a properly formed UTF-8 sequence with a
one-to-one mapping between the bytes in the internal representation and the
UTF-8 characters in the string representation.  
.PP
\fBTcl_NewByteArrayObj\fR and \fBTcl_SetByteArrayObj\fR will
create a new object of byte-array type or modify an existing object to have a
byte-array type.  Both of these procedures set the object's type to be
byte-array and set the object's internal representation to a copy of the
array of bytes given by \fIbytes\fR. \fBTcl_NewByteArrayObj\fR returns a
pointer to a newly allocated object with a reference count of zero.
\fBTcl_SetByteArrayObj\fR invalidates any old string representation and, if
the object is not already a byte-array object, frees any old internal
representation.
.PP
\fBTcl_GetByteArrayFromObj\fR converts a Tcl object to byte-array type and
returns a pointer to the object's new internal representation as an array of
bytes.  The length of this array is stored in \fIlengthPtr\fR if
\fIlengthPtr\fR is non-NULL.  The storage for the array of bytes is owned by
the object and should not be freed.  The contents of the array may be
modified by the caller only if the object is not shared and the caller
invalidates the string representation.  
.PP
\fBTcl_SetByteArrayLength\fR converts the Tcl object to byte-array type
and changes the length of the object's internal representation as an
array of bytes.  If \fIlength\fR is greater than the space currently
allocated for the array, the array is reallocated to the new length; the
newly allocated bytes at the end of the array have arbitrary values.  If
\fIlength\fR is less than the space currently allocated for the array,
the length of array is reduced to the new length.  The return value is a
pointer to the object's new array of bytes.  

.SH "SEE ALSO"
Tcl_GetStringFromObj, Tcl_NewObj, Tcl_IncrRefCount, Tcl_DecrRefCount

.SH KEYWORDS
object, byte array, utf, unicode, internationalization

Changes to doc/CallDel.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) CallDel.3 1.11 96/03/25 19:57:25
'\" 
.so man.macros
.TH Tcl_CallWhenDeleted 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CallWhenDeleted, Tcl_DontCallWhenDeleted \- Arrange for callback when interpreter is deleted
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: CallDel.3,v 1.1.2.1 1998/09/24 23:58:20 stanton Exp $
'\" 
.so man.macros
.TH Tcl_CallWhenDeleted 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CallWhenDeleted, Tcl_DontCallWhenDeleted \- Arrange for callback when interpreter is deleted
.SH SYNOPSIS

Changes to doc/CmdCmplt.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) CmdCmplt.3 1.6 96/03/25 19:57:46
'\" 
.so man.macros
.TH Tcl_CommandComplete 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CommandComplete \- Check for unmatched braces in a Tcl command
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: CmdCmplt.3,v 1.1.2.1 1998/09/24 23:58:20 stanton Exp $
'\" 
.so man.macros
.TH Tcl_CommandComplete 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CommandComplete \- Check for unmatched braces in a Tcl command
.SH SYNOPSIS

Changes to doc/Concat.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Concat.3 1.12 97/06/11 17:54:12
'\" 
.so man.macros
.TH Tcl_Concat 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Concat \- concatenate a collection of strings
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: Concat.3,v 1.1.2.1 1998/09/24 23:58:20 stanton Exp $
'\" 
.so man.macros
.TH Tcl_Concat 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Concat \- concatenate a collection of strings
.SH SYNOPSIS

Changes to doc/CrtChannel.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.
'\"
'\" SCCS: @(#) CrtChannel.3 1.29 97/06/20 13:37:45
.so man.macros
.TH Tcl_CreateChannel 3 8.0 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetDefaultTranslation, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption \- procedures for creating and manipulating channels
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_Channel
\fBTcl_CreateChannel\fR(\fItypePtr, channelName, instanceData, mask\fR)
.sp






|





|







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: CrtChannel.3,v 1.1.2.3 1999/04/13 00:01:57 surles Exp $
.so man.macros
.TH Tcl_CreateChannel 3 8.0 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption \- procedures for creating and manipulating channels
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_Channel
\fBTcl_CreateChannel\fR(\fItypePtr, channelName, instanceData, mask\fR)
.sp
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
\fBTcl_GetChannelName\fR(\fIchannel\fR)
.VS
.sp
int
\fBTcl_GetChannelHandle\fR(\fIchannel, direction, handlePtr\fR)
.VE
.sp
int
\fBTcl_GetChannelFlags\fR(\fIchannel\fR)
.sp
\fBTcl_SetDefaultTranslation\fR(\fIchannel, transMode\fR)
.sp
int
\fBTcl_GetChannelBufferSize\fR(\fIchannel\fR)
.sp
\fBTcl_SetChannelBufferSize\fR(\fIchannel, size\fR)
.sp
.VS
\fBTcl_NotifyChannel\fR(\fIchannel, mask\fR)







<
<
<
<
<







28
29
30
31
32
33
34





35
36
37
38
39
40
41
\fBTcl_GetChannelName\fR(\fIchannel\fR)
.VS
.sp
int
\fBTcl_GetChannelHandle\fR(\fIchannel, direction, handlePtr\fR)
.VE
.sp





int
\fBTcl_GetChannelBufferSize\fR(\fIchannel\fR)
.sp
\fBTcl_SetChannelBufferSize\fR(\fIchannel, size\fR)
.sp
.VS
\fBTcl_NotifyChannel\fR(\fIchannel, mask\fR)
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
for each driver to determine what type of handle is returned.
.VE
.PP
\fBTcl_GetChannelMode\fR returns an OR-ed combination of \fBTCL_READABLE\fR
and \fBTCL_WRITABLE\fR, indicating whether the channel is open for input
and output.
.PP
\fBTcl_SetDefaultTranslation\fR sets the default end of line translation
mode. This mode will be installed as the translation mode for the channel
if an attempt is made to output on the channel while it is still in
\fBTCL_TRANSLATE_AUTO\fR mode. For a description of end of line translation
modes, see the manual entry for \fBfconfigure\fR.
.PP
\fBTcl_GetChannelBufferSize\fR returns the size, in bytes, of buffers
allocated to store input or output in \fIchan\fR. If the value was not set
by a previous call to \fBTcl_SetChannelBufferSize\fR, described below, then
the default value of 4096 is returned.
.PP
\fBTcl_SetChannelBufferSize\fR sets the size, in bytes, of buffers that
will be allocated in subsequent operations on the channel to store input or
output. The \fIsize\fR argument should be between ten and one million,







<
<
<
<
<
<
|







161
162
163
164
165
166
167






168
169
170
171
172
173
174
175
for each driver to determine what type of handle is returned.
.VE
.PP
\fBTcl_GetChannelMode\fR returns an OR-ed combination of \fBTCL_READABLE\fR
and \fBTCL_WRITABLE\fR, indicating whether the channel is open for input
and output.
.PP






 \fBTcl_GetChannelBufferSize\fR returns the size, in bytes, of buffers
allocated to store input or output in \fIchan\fR. If the value was not set
by a previous call to \fBTcl_SetChannelBufferSize\fR, described below, then
the default value of 4096 is returned.
.PP
\fBTcl_SetChannelBufferSize\fR sets the size, in bytes, of buffers that
will be allocated in subsequent operations on the channel to store input or
output. The \fIsize\fR argument should be between ten and one million,
217
218
219
220
221
222
223

224
225
226
227
228
229

230

231
232
233
234
235
236
237
238
239
240
	Tcl_DriverInputProc *\fIinputProc\fR;
	Tcl_DriverOutputProc *\fIoutputProc\fR;
	Tcl_DriverSeekProc *\fIseekProc\fR;
	Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
	Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
	Tcl_DriverWatchProc *\fIwatchProc\fR;
	Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;

} Tcl_ChannelType;
.CE
.VE
.PP
The driver must provide implementations for all functions except
\fIblockModeProc\fR, \fIseekProc\fR, \fIsetOptionProc\fR, and

\fIgetOptionProc\fR, which may be specified as NULL to indicate that the

channel does not support seeking.  Other functions that can not be
implemented for this type of device should return \fBEINVAL\fR when invoked
to indicate that they are not implemented.

.SH TYPENAME
.PP
The \fItypeName\fR field contains a null-terminated string that
identifies the type of the device implemented by this driver, e.g.
\fBfile\fR or \fBsocket\fR.








>





|
>
|
>
|
|
|







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
	Tcl_DriverInputProc *\fIinputProc\fR;
	Tcl_DriverOutputProc *\fIoutputProc\fR;
	Tcl_DriverSeekProc *\fIseekProc\fR;
	Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
	Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
	Tcl_DriverWatchProc *\fIwatchProc\fR;
	Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
	Tcl_DriverClose2Proc *\fIclose2Proc\fR;
} Tcl_ChannelType;
.CE
.VE
.PP
The driver must provide implementations for all functions except
\fIblockModeProc\fR, \fIseekProc\fR, \fIsetOptionProc\fR,
.VS
\fIgetOptionProc\fR, and \fIclose2Proc\fR, which may be specified as
.VE
NULL.  Other functions that can not be implemented for this type of
device should return \fBEINVAL\fR when invoked to indicate that they
are not implemented.

.SH TYPENAME
.PP
The \fItypeName\fR field contains a null-terminated string that
identifies the type of the device implemented by this driver, e.g.
\fBfile\fR or \fBsocket\fR.

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
If the operation is successful, the function can modify the supplied
\fIinstanceData\fR to record that the channel entered blocking or
nonblocking mode and to implement the blocking or nonblocking behavior.
For some device types, the blocking and nonblocking behavior can be
implemented by the underlying operating system; for other device types, the
behavior must be emulated in the channel driver.

.SH CLOSEPROC
.PP
The \fIcloseProc\fR field contains the address of a function called by the
generic layer to clean up driver-related information when the channel is
closed. \fICloseProc\fR must match the following prototype:
.PP
.CS
typedef int Tcl_DriverCloseProc(







|







252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
If the operation is successful, the function can modify the supplied
\fIinstanceData\fR to record that the channel entered blocking or
nonblocking mode and to implement the blocking or nonblocking behavior.
For some device types, the blocking and nonblocking behavior can be
implemented by the underlying operating system; for other device types, the
behavior must be emulated in the channel driver.

.SH CLOSEPROC AND CLOSE2PROC
.PP
The \fIcloseProc\fR field contains the address of a function called by the
generic layer to clean up driver-related information when the channel is
closed. \fICloseProc\fR must match the following prototype:
.PP
.CS
typedef int Tcl_DriverCloseProc(
282
283
284
285
286
287
288





























289
290
291
292
293
294
295
close the input and output devices encapsulated by this channel. All queued
output will have been flushed to the device before this function is called,
and no further driver operations will be invoked on this instance after
calling the \fIcloseProc\fR. If the close operation is successful, the
procedure should return zero; otherwise it should return a nonzero POSIX
error code. In addition, if an error occurs and \fIinterp\fR is not NULL,
the procedure should store an error message in \fIinterp->result\fR.






























.SH INPUTPROC
.PP
The \fIinputProc\fR field contains the address of a function called by the
generic layer to read data from the file or device and store it in an
internal buffer. \fIInputProc\fR must match the following prototype:
.PP







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







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
close the input and output devices encapsulated by this channel. All queued
output will have been flushed to the device before this function is called,
and no further driver operations will be invoked on this instance after
calling the \fIcloseProc\fR. If the close operation is successful, the
procedure should return zero; otherwise it should return a nonzero POSIX
error code. In addition, if an error occurs and \fIinterp\fR is not NULL,
the procedure should store an error message in \fIinterp->result\fR.
.PP
.VS
Alternatively, channels that support closing the read and write sides
independently may set \fIcloseProc\fR to \fBTCL_CLOSE2PROC\fR and set
\fIclose2Proc\fR to the address of a function that matches the
following prototype:
.PP
.CS
typedef int Tcl_DriverClose2Proc(
	ClientData \fIinstanceData\fR,
	Tcl_Interp *\fIinterp\fR,
	int \fIflags\fR);
.CE
.PP
The \fIclose2Proc\fR will be called with \fIflags\fR set to an OR'ed
combination of \fBTCL_CLOSE_READ\fR or \fBTCL_CLOSE_WRITE\fR to
indicate that the driver should close the read and/or write side of
the channel.  The channel driver may be invoked to perform
additional operations on the channel after \fIclose2Proc\fR is
called to close one or both sides of the channel.  If \fIflags\fR is
\fB0\fR (zero), the driver should close the channel in the manner
described above for \fIcloseProc\fR.  No further operations will be
invoked on this instance after \fIclose2Proc\fR is called with all
flags cleared.  In all cases, the \fIclose2Proc\fR function should
return zero if the close operation was successful; otherwise it should
return a nonzero POSIX error code. In addition, if an error occurs and
\fIinterp\fR is not NULL, the procedure should store an error message
in \fIinterp->result\fR.
.VE

.SH INPUTPROC
.PP
The \fIinputProc\fR field contains the address of a function called by the
generic layer to read data from the file or device and store it in an
internal buffer. \fIInputProc\fR must match the following prototype:
.PP
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
	long \fIoffset\fR,
	int \fIseekMode\fR,
	int *\fIerrorCodePtr\fR);
.CE
.PP
The \fIinstanceData\fR argument is the same as the value given to
\fBTcl_CreateChannel\fR when this channel was created.  \fIOffset\fR and
\fIseekMode\fR have the same meaning as for the \fBTcl_SeekChannel\fR
procedure (described in the manual entry for \fBTcl_OpenFileChannel\fR).
.PP
The \fIerrorCodePtr\fR argument points to an integer variable provided by
the generic layer for returning \fBerrno\fR values from the function.  The
function should set this variable to a POSIX error code if an error occurs.
The function should store an \fBEINVAL\fR error code if the channel type
does not implement seeking.







|







399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
	long \fIoffset\fR,
	int \fIseekMode\fR,
	int *\fIerrorCodePtr\fR);
.CE
.PP
The \fIinstanceData\fR argument is the same as the value given to
\fBTcl_CreateChannel\fR when this channel was created.  \fIOffset\fR and
\fIseekMode\fR have the same meaning as for the \fBTcl_Seek\fR
procedure (described in the manual entry for \fBTcl_OpenFileChannel\fR).
.PP
The \fIerrorCodePtr\fR argument points to an integer variable provided by
the generic layer for returning \fBerrno\fR values from the function.  The
function should set this variable to a POSIX error code if an error occurs.
The function should store an \fBEINVAL\fR error code if the channel type
does not implement seeking.

Changes to doc/CrtChnlHdlr.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\" SCCS: @(#) CrtChnlHdlr.3 1.10 96/03/14 10:54:43
.so man.macros
.TH Tcl_CreateChannelHandler 3 7.5 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_CreateChannelHandler, Tcl_DeleteChannelHandler \- call a procedure when a channel becomes readable or writable
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1996 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: CrtChnlHdlr.3,v 1.1.2.1 1998/09/24 23:58:20 stanton Exp $
.so man.macros
.TH Tcl_CreateChannelHandler 3 7.5 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_CreateChannelHandler, Tcl_DeleteChannelHandler \- call a procedure when a channel becomes readable or writable
.SH SYNOPSIS

Changes to doc/CrtCloseHdlr.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\" SCCS: @(#) CrtCloseHdlr.3 1.7 96/04/15 13:08:19
.so man.macros
.TH Tcl_CreateCloseHandler 3 7.5 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_CreateCloseHandler, Tcl_DeleteCloseHandler \- arrange for callbacks when channels are closed
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1994-1996 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: CrtCloseHdlr.3,v 1.1.2.1 1998/09/24 23:58:21 stanton Exp $
.so man.macros
.TH Tcl_CreateCloseHandler 3 7.5 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_CreateCloseHandler, Tcl_DeleteCloseHandler \- arrange for callbacks when channels are closed
.SH SYNOPSIS

Changes to doc/CrtCommand.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) CrtCommand.3 1.29 97/06/04 17:23:53
'\" 
.so man.macros
.TH Tcl_CreateCommand 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateCommand \- implement new commands in C
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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: CrtCommand.3,v 1.1.2.2 1998/10/06 02:59:03 stanton Exp $
'\" 
.so man.macros
.TH Tcl_CreateCommand 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateCommand \- implement new commands in C
.SH SYNOPSIS
90
91
92
93
94
95
96
97





98
99
100
101
102
103
104
Typically, \fIclientData\fR points to an application-specific
data structure that describes what to do when the command procedure
is invoked.  \fIArgc\fR and \fIargv\fR describe the arguments to
the command, \fIargc\fR giving the number of arguments (including
the command name) and \fIargv\fR giving the values of the arguments
as strings.  The \fIargv\fR array will contain \fIargc\fR+1 values;
the first \fIargc\fR values point to the argument strings, and the
last value is NULL.





.PP
\fIProc\fR must return an integer code that is either \fBTCL_OK\fR, \fBTCL_ERROR\fR,
\fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR.  See the Tcl overview man page
for details on what these codes mean.  Most normal commands will only
return \fBTCL_OK\fR or \fBTCL_ERROR\fR.  In addition, \fIproc\fR must set
the interpreter result to point to a string value;
in the case of a \fBTCL_OK\fR return code this gives the result







|
>
>
>
>
>







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
Typically, \fIclientData\fR points to an application-specific
data structure that describes what to do when the command procedure
is invoked.  \fIArgc\fR and \fIargv\fR describe the arguments to
the command, \fIargc\fR giving the number of arguments (including
the command name) and \fIargv\fR giving the values of the arguments
as strings.  The \fIargv\fR array will contain \fIargc\fR+1 values;
the first \fIargc\fR values point to the argument strings, and the
last value is NULL.  
.VS
Note that the argument strings should not be modified as they may
point to constant strings or may be shared with other parts of the
interpreter.
.VE
.PP
\fIProc\fR must return an integer code that is either \fBTCL_OK\fR, \fBTCL_ERROR\fR,
\fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR.  See the Tcl overview man page
for details on what these codes mean.  Most normal commands will only
return \fBTCL_OK\fR or \fBTCL_ERROR\fR.  In addition, \fIproc\fR must set
the interpreter result to point to a string value;
in the case of a \fBTCL_OK\fR return code this gives the result

Changes to doc/CrtFileHdlr.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) CrtFileHdlr.3 1.7 97/04/23 16:11:17
'\" 
.so man.macros
.TH Tcl_CreateFileHandler 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateFileHandler, Tcl_DeleteFileHandler \- associate procedure callbacks with files or devices (Unix only)
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" 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: CrtFileHdlr.3,v 1.1.2.1 1998/09/24 23:58:21 stanton Exp $
'\" 
.so man.macros
.TH Tcl_CreateFileHandler 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateFileHandler, Tcl_DeleteFileHandler \- associate procedure callbacks with files or devices (Unix only)
.SH SYNOPSIS

Changes to doc/CrtInterp.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) CrtInterp.3 1.17 97/10/31 13:05:51
'\" 
.so man.macros
.TH Tcl_CreateInterp 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateInterp, Tcl_DeleteInterp, Tcl_InterpDeleted \- create and delete Tcl command interpreters
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: CrtInterp.3,v 1.1.2.1 1998/09/24 23:58:21 stanton Exp $
'\" 
.so man.macros
.TH Tcl_CreateInterp 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateInterp, Tcl_DeleteInterp, Tcl_InterpDeleted \- create and delete Tcl command interpreters
.SH SYNOPSIS

Changes to doc/CrtMathFnc.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) CrtMathFnc.3 1.9 96/08/26 12:59:43
'\" 
.so man.macros
.TH Tcl_CreateMathFunc 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateMathFunc \- Define a new math function for expressions
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: CrtMathFnc.3,v 1.1.2.1 1998/09/24 23:58:21 stanton Exp $
'\" 
.so man.macros
.TH Tcl_CreateMathFunc 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateMathFunc \- Define a new math function for expressions
.SH SYNOPSIS

Changes to doc/CrtObjCmd.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) @(#) CrtObjCmd.3 1.10 97/07/31 14:10:38
'\" 
.so man.macros
.TH Tcl_CreateObjCommand 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_SetCommandInfo, Tcl_GetCommandName \- implement new commands in C
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: CrtObjCmd.3,v 1.1.2.3 1999/04/13 00:01:57 surles Exp $
'\" 
.so man.macros
.TH Tcl_CreateObjCommand 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_SetCommandInfo, Tcl_GetCommandName \- implement new commands in C
.SH SYNOPSIS
58
59
60
61
62
63
64
65
66


67
68
69
70
71
72
73
.PP
\fBTcl_CreateObjCommand\fR defines a new command in \fIinterp\fR
and associates it with procedure \fIproc\fR
such that whenever \fIname\fR is
invoked as a Tcl command (e.g., via a call to \fBTcl_EvalObj\fR)
the Tcl interpreter will call \fIproc\fR to process the command.
.PP
\fBTcl_CreateObjCommand\fR will delete any command \fIname\fR
already associated with the interpreter.


It returns a token that may be used to refer
to the command in subsequent calls to \fBTcl_GetCommandName\fR.
If \fIname\fR contains any \fB::\fR namespace qualifiers,
then the command is added to the specified namespace;
otherwise the command is added to the global namespace.
If \fBTcl_CreateObjCommand\fR is called for an interpreter that is in
the process of being deleted, then it does not create a new command







|
|
>
>







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
.PP
\fBTcl_CreateObjCommand\fR defines a new command in \fIinterp\fR
and associates it with procedure \fIproc\fR
such that whenever \fIname\fR is
invoked as a Tcl command (e.g., via a call to \fBTcl_EvalObj\fR)
the Tcl interpreter will call \fIproc\fR to process the command.
.PP
\fBTcl_CreateObjCommand\fR deletes any existing command
\fIname\fR already associated with the interpreter
(however see below for an exception where the existing command
is not deleted).
It returns a token that may be used to refer
to the command in subsequent calls to \fBTcl_GetCommandName\fR.
If \fIname\fR contains any \fB::\fR namespace qualifiers,
then the command is added to the specified namespace;
otherwise the command is added to the global namespace.
If \fBTcl_CreateObjCommand\fR is called for an interpreter that is in
the process of being deleted, then it does not create a new command
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
of the \fIobjv\fR array by assigning new pointer values to any element of the
array (for example, \fIobjv\fR[\fB2\fR] = \fBNULL\fR) because this will
cause memory to be lost and the runtime stack to be corrupted.  The
\fBCONST\fR in the declaration of \fIobjv\fR will cause ANSI-compliant
compilers to report any such attempted assignment as an error.  However,
it is acceptable to modify the internal representation of any individual
object argument.  For instance, the user may call
\fBTcl_GetIntFromObject\fR on \fIobjv\fR[\fB2\fR] to obtain the integer
representation of that object; that call may change the type of the object
that \fIobjv\fR[\fB2\fR] points at, but will not change where
\fIobjv\fR[\fB2\fR] points.
.VE
.PP
\fIproc\fR must return an integer code that is either \fBTCL_OK\fR,
\fBTCL_ERROR\fR, \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR.







|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
of the \fIobjv\fR array by assigning new pointer values to any element of the
array (for example, \fIobjv\fR[\fB2\fR] = \fBNULL\fR) because this will
cause memory to be lost and the runtime stack to be corrupted.  The
\fBCONST\fR in the declaration of \fIobjv\fR will cause ANSI-compliant
compilers to report any such attempted assignment as an error.  However,
it is acceptable to modify the internal representation of any individual
object argument.  For instance, the user may call
\fBTcl_GetIntFromObj\fR on \fIobjv\fR[\fB2\fR] to obtain the integer
representation of that object; that call may change the type of the object
that \fIobjv\fR[\fB2\fR] points at, but will not change where
\fIobjv\fR[\fB2\fR] points.
.VE
.PP
\fIproc\fR must return an integer code that is either \fBTCL_OK\fR,
\fBTCL_ERROR\fR, \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR.
124
125
126
127
128
129
130











131
132
133
134
135
136
137
.PP
The contents of the \fIobjv\fR array belong to Tcl and are not
guaranteed to persist once \fIproc\fR returns: \fIproc\fR should
not modify them.
Call \fBTcl_SetObjResult\fR if you want
to return something from the \fIobjv\fR array.
.PP











\fIDeleteProc\fR will be invoked when (if) \fIname\fR is deleted.
This can occur through a call to \fBTcl_DeleteCommand\fR,
\fBTcl_DeleteCommandFromToken\fR, or \fBTcl_DeleteInterp\fR,
or by replacing \fIname\fR in another call to \fBTcl_CreateObjCommand\fR.
\fIDeleteProc\fR is invoked before the command is deleted, and gives the
application an opportunity to release any structures associated
with the command.  \fIDeleteProc\fR should have arguments and







>
>
>
>
>
>
>
>
>
>
>







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
.PP
The contents of the \fIobjv\fR array belong to Tcl and are not
guaranteed to persist once \fIproc\fR returns: \fIproc\fR should
not modify them.
Call \fBTcl_SetObjResult\fR if you want
to return something from the \fIobjv\fR array.
.PP
Ordinarily, \fBTcl_CreateObjCommand\fR deletes any existing command
\fIname\fR already associated with the interpreter.
However, if the existing command was created by a previous call to
\fBTcl_CreateCommand\fR,
\fBTcl_CreateObjCommand\fR does not delete the command
but instead arranges for the Tcl interpreter to call the
\fBTcl_ObjCmdProc\fR \fIproc\fR in the future.
The old string-based \fBTcl_CmdProc\fR associated with the command
is retained and its address can be obtained by subsequent 
\fBTcl_GetCommandInfo\fR calls. This is done for backwards compatibility.
.PP
\fIDeleteProc\fR will be invoked when (if) \fIname\fR is deleted.
This can occur through a call to \fBTcl_DeleteCommand\fR,
\fBTcl_DeleteCommandFromToken\fR, or \fBTcl_DeleteInterp\fR,
or by replacing \fIname\fR in another call to \fBTcl_CreateObjCommand\fR.
\fIDeleteProc\fR is invoked before the command is deleted, and gives the
application an opportunity to release any structures associated
with the command.  \fIDeleteProc\fR should have arguments and

Changes to doc/CrtSlave.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) CrtSlave.3 1.26 97/07/31 18:00:14
'\" 
.so man.macros
.TH Tcl_CreateSlave 3 7.6 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_IsSafe, Tcl_MakeSafe, Tcl_CreateSlave, Tcl_GetSlave, Tcl_GetMaster, Tcl_GetInterpPath, Tcl_CreateAlias, Tcl_CreateAliasObj, Tcl_GetAlias, Tcl_GetAliasObj, Tcl_ExposeCommand, Tcl_HideCommand \- manage multiple Tcl interpreters, aliases and hidden commands.
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 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: CrtSlave.3,v 1.1.2.1 1998/09/24 23:58:22 stanton Exp $
'\" 
.so man.macros
.TH Tcl_CreateSlave 3 7.6 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_IsSafe, Tcl_MakeSafe, Tcl_CreateSlave, Tcl_GetSlave, Tcl_GetMaster, Tcl_GetInterpPath, Tcl_CreateAlias, Tcl_CreateAliasObj, Tcl_GetAlias, Tcl_GetAliasObj, Tcl_ExposeCommand, Tcl_HideCommand \- manage multiple Tcl interpreters, aliases and hidden commands.
.SH SYNOPSIS

Changes to doc/CrtTimerHdlr.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) CrtTimerHdlr.3 1.4 96/09/17 10:54:58
'\" 
.so man.macros
.TH Tcl_CreateTimerHandler 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateTimerHandler, Tcl_DeleteTimerHandler \- call a procedure at a
given time







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: CrtTimerHdlr.3,v 1.1.2.1 1998/09/24 23:58:22 stanton Exp $
'\" 
.so man.macros
.TH Tcl_CreateTimerHandler 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateTimerHandler, Tcl_DeleteTimerHandler \- call a procedure at a
given time

Changes to doc/CrtTrace.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) CrtTrace.3 1.14 96/03/25 20:01:10
'\" 
.so man.macros
.TH Tcl_CreateTrace 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateTrace, Tcl_DeleteTrace \- arrange for command execution to be traced
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: CrtTrace.3,v 1.1.2.1 1998/09/24 23:58:22 stanton Exp $
'\" 
.so man.macros
.TH Tcl_CreateTrace 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_CreateTrace, Tcl_DeleteTrace \- arrange for command execution to be traced
.SH SYNOPSIS

Changes to doc/DString.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) DString.3 1.20 96/08/26 12:59:44
'\" 
.so man.macros
.TH Tcl_DString 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_DStringInit, Tcl_DStringAppend, Tcl_DStringAppendElement, Tcl_DStringStartSublist, Tcl_DStringEndSublist, Tcl_DStringLength, Tcl_DStringValue, Tcl_DStringSetLength, Tcl_DStringFree, Tcl_DStringResult, Tcl_DStringGetResult \- manipulate dynamic strings
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: DString.3,v 1.1.2.1 1998/09/24 23:58:22 stanton Exp $
'\" 
.so man.macros
.TH Tcl_DString 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_DStringInit, Tcl_DStringAppend, Tcl_DStringAppendElement, Tcl_DStringStartSublist, Tcl_DStringEndSublist, Tcl_DStringLength, Tcl_DStringValue, Tcl_DStringSetLength, Tcl_DStringFree, Tcl_DStringResult, Tcl_DStringGetResult \- manipulate dynamic strings
.SH SYNOPSIS

Changes to doc/DetachPids.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) DetachPids.3 1.15 96/08/26 12:59:44
'\" 
.so man.macros
.TH Tcl_DetachPids 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_DetachPids, Tcl_ReapDetachedProcs \- manage child processes in background
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: DetachPids.3,v 1.1.2.1 1998/09/24 23:58:22 stanton Exp $
'\" 
.so man.macros
.TH Tcl_DetachPids 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_DetachPids, Tcl_ReapDetachedProcs \- manage child processes in background
.SH SYNOPSIS

Changes to doc/DoOneEvent.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) DoOneEvent.3 1.6 97/05/09 18:12:05
'\" 
.so man.macros
.TH Tcl_DoOneEvent 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_DoOneEvent \- wait for events and invoke event handlers
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: DoOneEvent.3,v 1.1.2.1 1998/09/24 23:58:22 stanton Exp $
'\" 
.so man.macros
.TH Tcl_DoOneEvent 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_DoOneEvent \- wait for events and invoke event handlers
.SH SYNOPSIS

Changes to doc/DoWhenIdle.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) DoWhenIdle.3 1.6 97/05/09 18:18:33
'\" 
.so man.macros
.TH Tcl_DoWhenIdle 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_DoWhenIdle, Tcl_CancelIdleCall \- invoke a procedure when there are no pending events
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: DoWhenIdle.3,v 1.1.2.1 1998/09/24 23:58:23 stanton Exp $
'\" 
.so man.macros
.TH Tcl_DoWhenIdle 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_DoWhenIdle, Tcl_CancelIdleCall \- invoke a procedure when there are no pending events
.SH SYNOPSIS

Changes to doc/DoubleObj.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) @(#) DoubleObj.3 1.6 97/05/08 19:50:07
'\" 
.so man.macros
.TH Tcl_DoubleObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl objects as floating-point values
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: DoubleObj.3,v 1.1.2.1 1998/09/24 23:58:23 stanton Exp $
'\" 
.so man.macros
.TH Tcl_DoubleObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl objects as floating-point values
.SH SYNOPSIS

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


.SH ARGUMENTS
.AS Tcl_EncodingState *dstWrotePtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting, or NULL if no error reporting is
desired.
.AP "CONST char" *name in
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
source buffer is the first block in a (potentially multi-block) input
stream, telling the conversion routine to reset to an initial state and
perform any initialization that needs to occur before the first byte is
converted.  TCL_ENCODING_END signifies that the source buffer is the last
block in a (potentially multi-block) input stream, telling the conversion
routine to perform any finalization that needs to occur after the last
byte is converted and then to reset to an initial state.
TCL_ENCODING_STOPONERROR signifies that the conversion routine should
return immediately upon reading a source character that doesn't exist in
the target encoding; otherwise a default fallback character will
automatically be substituted.  
.AP Tcl_EncodingState *statePtr in/out
Used when converting a (generally long or indefinite length) byte stream
in a piece by piece fashion.  The conversion routine stores its current
state in \fI*statePtr\fR after \fIsrc\fR (the buffer containing the
current piece) has been converted; that state information must be passed
back when converting the next piece of the stream so the conversion
routine knows what state it was in when it left off at the end of the
last piece.  May be NULL, in which case the value specified for \fIflags\fR 
is ignored and the source buffer is assumed to contain the complete string to
convert.
.AP char *dst out
Buffer in which the converted result will be stored.  No more than
\fIdstLen\fR bytes will be stored in \fIdst\fR.
.AP int dstLen in
The maximum length of the output buffer \fIdst\fR in bytes.
.AP int *srcReadPtr out
Filled with the number of bytes from \fIsrc\fR that were actually
converted.  This may be less than the original source length if there was
a problem converting some source characters.  May be NULL.
.AP int *dstWrotePtr out
Filled with the number of bytes that were actually stored in the output
buffer as a result of the conversion.  May be NULL.
.AP int *dstCharsPtr out
Filled with the number of characters that correspond to the number of bytes
stored in the output buffer.  May be NULL.
.AP Tcl_EncodingType *typePtr in
Structure that defines a new type of encoding.  
.AP char *path in
A path to the location of the encoding file.  
.BE
.SH INTRODUCTION
.PP
These routines convert between Tcl's internal character representation,
UTF-8, and character representations used by various operating systems or
file systems, such as Unicode, ASCII, or Shift-JIS.  When operating on
strings, such as such as obtaining the names of files or displaying
characters using international fonts, the strings must be translated into
one or possibly multiple formats that the various system calls can use.  For
instance, on a Japanese Unix workstation, a user might obtain a filename
represented in the EUC-JP file encoding and then translate the characters to
the jisx0208 font encoding in order to display the filename in a Tk widget.
The purpose of the encoding package is to help bridge the translation gap.
UTF-8 provides an intermediate staging ground for all the various
encodings.  In the example above, text would be translated into UTF-8 from
whatever file encoding the operating system is using.  Then it would be
translated from UTF-8 into whatever font encoding the display routines
require.
.PP
Some basic encodings are compiled into Tcl.  Others can be defined by the
user or dynamically loaded from encoding files in a
platform-independent manner.
.SH DESCRIPTION
.PP
\fBTcl_GetEncoding\fR finds an encoding given its \fIname\fR.  The name may
refer to a builtin Tcl encoding, a user-defined encoding registered by
calling \fBTcl_CreateEncoding\fR, or a dynamically-loadable encoding
file.  The return value is a token that represents the encoding and can be
used in subsequent calls to procedures such as \fBTcl_GetEncodingName\fR,
\fBTcl_FreeEncoding\fR, and \fBTcl_UtfToExternal\fR.  If the name did not
refer to any known or loadable encoding, NULL is returned and an error
message is returned in \fIinterp\fR.
.PP
The encoding package maintains a database of all encodings currently in use.
The first time \fIname\fR is seen, \fBTcl_GetEncoding\fR returns an
encoding with a reference count of 1.  If the same \fIname\fR is requested
further times, then the reference count for that encoding is incremented
without the overhead of allocating a new encoding and all its associated
data structures.  
.PP
When an \fIencoding\fR is no longer needed, \fBTcl_FreeEncoding\fR
should be called to release it.  When an \fIencoding\fR is no longer in use
anywhere (i.e., it has been freed as many times as it has been gotten)
\fBTcl_FreeEncoding\fR will release all storage the encoding was using
and delete it from the database. 
.PP
\fBTcl_ExternalToUtfDString\fR converts a source buffer \fIsrc\fR from the
specified \fIencoding\fR into UTF-8.  The converted bytes are stored in 
\fIdstPtr\fR, which is then NULL terminated.  The caller should eventually
call \fBTcl_DStringFree\fR to free any information stored in \fIdstPtr\fR.
When converting, if any of the characters in the source buffer cannot be
represented in the target encoding, a default fallback character will be
used.  
.PP
\fBTcl_ExternalToUtf\fR converts a source buffer \fIsrc\fR from the specified
\fIencoding\fR into UTF-8.  Up to \fIsrcLen\fR bytes are converted from 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
value is one of the following:
.RS
.IP \fBTCL_OK\fR 29
All bytes of \fIsrc\fR were converted.
.IP \fBTCL_CONVERT_NOSPACE\fR 29
The destination buffer was not large enough for all of the converted data; as
many characters as could fit were converted though.
.IP \fBTCL_CONVERT_MULTIBYTE\fR 29
The last fews bytes in the source buffer were the beginning of a multibyte
sequence, but more bytes were needed to complete this sequence.  A
subsequent call to the conversion routine should pass a buffer containing
the unconverted bytes that remained in \fIsrc\fR plus some further bytes
from the source stream to properly convert the formerly split-up multibyte
sequence.  
.IP \fBTCL_CONVERT_SYNTAX\fR 29
The source buffer contained an invalid character sequence.  This may occur
if the input stream has been damaged or if the input encoding method was
misidentified.
.IP \fBTCL_CONVERT_UNKNOWN\fR 29
The source buffer contained a character that could not be represented in
the target encoding and TCL_ENCODING_STOPONERROR was specified.  
.RE
.LP
\fBTcl_UtfToExternalDString\fR converts a source buffer \fIsrc\fR from UTF-8 
into the specified \fIencoding\fR.  The converted bytes are stored in
\fIdstPtr\fR, which is then terminated with the appropriate encoding-specific
NULL.  The caller should eventually call \fBTcl_DStringFree\fR to free any
information stored in \fIdstPtr\fR.  When converting, if any of the
characters in the source buffer cannot be represented in the target
encoding, a default fallback character will be used.  
.PP
\fBTcl_UtfToExternal\fR converts a source buffer \fIsrc\fR from UTF-8 into
the specified \fIencoding\fR.  Up to \fIsrcLen\fR bytes are converted from
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
any of the other encoding functions.  If \fIname\fR is NULL, the system
encoding is reset to the default system encoding, \fBbinary\fR.  If the
name did not refer to any known or loadable encoding, TCL_ERROR is
returned and an error message is left in \fIinterp\fR.  Otherwise, this
procedure increments the reference count of the new system encoding,
decrements the reference count of the old system encoding, and returns
TCL_OK.
.PP
\fBTcl_GetEncodingNames\fR sets the \fIinterp\fR result to a list
consisting of the names of all the encodings that are currently defined
or can be dynamically loaded, searching the encoding path specified by
\fBTcl_SetDefaultEncodingDir\fR.  This procedure does not ensure that the
dynamically-loadable encoding files contain valid data, but merely that they
exist.
.PP
\fBTcl_CreateEncoding\fR defines a new encoding and registers the C
procedures that are called back to convert between the encoding and
UTF-8.  Encodings created by \fBTcl_CreateEncoding\fR are thereafter
visible in the database used by \fBTcl_GetEncoding\fR.  Just as with the
\fBTcl_GetEncoding\fR procedure, the return value is a token that
represents the encoding and can be used in subsequent calls to other
encoding functions.  \fBTcl_CreateEncoding\fR returns an encoding with a
reference count of 1. If an encoding with the specified \fIname\fR
already exists, then its entry in the database is replaced with the new
encoding; the token for the old encoding will remain valid and continue
to behave as before, but users of the new token will now call the new
encoding procedures.  
.PP
The \fItypePtr\fR argument to \fBTcl_CreateEncoding\fR contains information 
about the name of the encoding and the procedures that will be called to
convert between this encoding and UTF-8.  It is defined as follows:
.PP
.CS
typedef struct Tcl_EncodingType {
	CONST char *\fIencodingName\fR;
	Tcl_EncodingConvertProc *\fItoUtfProc\fR;
	Tcl_EncodingConvertProc *\fIfromUtfProc\fR;
	Tcl_EncodingFreeProc *\fIfreeProc\fR;
	ClientData \fIclientData\fR;
	int \fInullSize\fR;
} Tcl_EncodingType;  
.CE
.PP
The \fIencodingName\fR provides a string name for the encoding, by
which it can be referred in other procedures such as
\fBTcl_GetEncoding\fR.  The \fItoUtfProc\fR refers to a callback
procedure to invoke to convert text from this encoding into UTF-8.
The \fIfromUtfProc\fR refers to a callback procedure to invoke to
convert text from UTF-8 into this encoding.  The \fIfreeProc\fR refers
to a callback procedure to invoke when this encoding is deleted.  The
\fIfreeProc\fR field may be NULL.  The \fIclientData\fR contains an
arbitrary one-word value passed to \fItoUtfProc\fR, \fIfromUtfProc\fR,
and \fIfreeProc\fR whenever they are called.  Typically, this is a
pointer to a data structure containing encoding-specific information
that can be used by the callback procedures.  For instance, two very
similar encodings such as \fBascii\fR and \fBmacRoman\fR may use the
same callback procedure, but use different values of \fIclientData\fR
to control its behavior.  The \fInullSize\fR specifies the number of
zero bytes that signify end-of-string in this encoding.  It must be
\fB1\fR (for single-byte or multi-byte encodings like ASCII or
Shift-JIS) or \fB2\fR (for double-byte encodings like Unicode).
Constant-sized encodings with 3 or more bytes per character (such as
CNS11643) are not accepted.
.PP
The callback procedures \fItoUtfProc\fR and \fIfromUtfProc\fR should match the
type \fBTcl_EncodingConvertProc\fR:
.PP
.CS
typedef int Tcl_EncodingConvertProc(
	ClientData \fIclientData\fR,
	CONST char *\fIsrc\fR, 
	int \fIsrcLen\fR, 
	int \fIflags\fR, 
	Tcl_Encoding *\fIstatePtr\fR,
	char *\fIdst\fR, 
	int \fIdstLen\fR, 
	int *\fIsrcReadPtr\fR,
	int *\fIdstWrotePtr\fR,
	int *\fIdstCharsPtr\fR);
.CE
.PP
The \fItoUtfProc\fR and \fIfromUtfProc\fR procedures are called by the
\fBTcl_ExternalToUtf\fR or \fBTcl_UtfToExternal\fR family of functions to
perform the actual conversion.  The \fIclientData\fR parameter to these
procedures is the same as the \fIclientData\fR field specified to
\fBTcl_CreateEncoding\fR when the encoding was created.  The remaining
arguments to the callback procedures are the same as the arguments,
documented at the top, to \fBTcl_ExternalToUtf\fR or
\fBTcl_UtfToExternal\fR, with the following exceptions.  If the
\fIsrcLen\fR argument to one of those high-level functions is negative,
the value passed to the callback procedure will be the appropriate
encoding-specific string length of \fIsrc\fR.  If any of the \fIsrcReadPtr\fR, 
\fIdstWrotePtr\fR, or \fIdstCharsPtr\fR arguments to one of the high-level
functions is NULL, the corresponding value passed to the callback
procedure will be a non-NULL location.
.PP
The callback procedure \fIfreeProc\fR, if non-NULL, should match the type 
\fBTcl_EncodingFreeProc\fR:
.CS
typedef void Tcl_EncodingFreeProc(
	ClientData \fIclientData\fR);
.CE
.PP
This \fIfreeProc\fR function is called when the encoding is deleted.  The
\fIclientData\fR parameter is the same as the \fIclientData\fR field
specified to \fBTcl_CreateEncoding\fR when the encoding was created.  
.PP

\fBTcl_GetDefaultEncodingDir\fR and \fBTcl_SetDefaultEncodingDir\fR
access and set the directory to use when locating the default encoding
files.  If this value is not NULL, the \fBTclpInitLibraryPath\fR routine
appends the path to the head of the search path, and uses this path as
the first place to look into when trying to locate the encoding file.

.SH ENCODING FILES
Space would prohibit precompiling into Tcl every possible encoding
algorithm, so many encodings are stored on disk as dynamically-loadable
encoding files.  This behavior also allows the user to create additional
encoding files that can be loaded using the same mechanism.  These
encoding files contain information about the tables and/or escape
sequences used to map between an external encoding and Unicode.  The
external encoding may consist of single-byte, multi-byte, or double-byte
characters.  
.PP
Each dynamically-loadable encoding is represented as a text file.  The
initial line of the file, beginning with a ``#'' symbol, is a comment
that provides a human-readable description of the file.  The next line
identifies the type of encoding file.  It can be one of the following
letters:
.IP "[1]   \fBS\fR"
A single-byte encoding, where one character is always one byte long in the
encoding.  An example is \fBiso8859-1\fR, used by many European languages.
.IP "[2]   \fBD\fR"
A double-byte encoding, where one character is always two bytes long in the
encoding.  An example is \fBbig5\fR, used for Chinese text.
.IP "[3]   \fBM\fR"
A multi-byte encoding, where one character may be either one or two bytes long.
Certain bytes are a lead bytes, indicating that another byte must follow
and that together the two bytes represent one character.  Other bytes are not
lead bytes and represent themselves.  An example is \fBshiftjis\fR, used by
many Japanese computers.
.IP "[4]   \fBE\fR"
An escape-sequence encoding, specifying that certain sequences of bytes
do not represent characters, but commands that describe how following bytes
should be interpreted.  
.PP
The rest of the lines in the file depend on the type.  
.PP
Cases [1], [2], and [3] are collectively referred to as table-based encoding
files.  The lines in a table-based encoding file are in the same
format as this example taken from the \fBshiftjis\fR encoding (this is not
the complete file):
.CS
# Encoding file: shiftjis, multi-byte
M
003F 0 40
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D203E007F
0080000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
81
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E
FFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0F005C
301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3DFF5B
FF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D70000
00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6
25A125A025B325B225BD25BC203B301221922190219121933013000000000000
000000000000000000000000000000002208220B2286228722822283222A2229
000000000000000000000000000000002227222800AC21D221D4220022030000
0000000000000000000000000000000000000000222022A52312220222072261
2252226A226B221A223D221D2235222B222C0000000000000000000000000000
212B2030266F266D266A2020202100B6000000000000000025EF000000000000
.CE
.PP
The third line of the file is three numbers.  The first number is the
fallback character (in base 16) to use when converting from UTF-8 to this
encoding.  The second number is a \fB1\fR if this file represents the
encoding for a symbol font, or \fB0\fR otherwise.  The last number (in base
10) is how many pages of data follow.  
.PP
Subsequent lines in the example above are pages that describe how to map
from the encoding into 2-byte Unicode.  The first line in a page identifies
the page number.  Following it are 256 double-byte numbers, arranged as 16
rows of 16 numbers.  Given a character in the encoding, the high byte of
that character is used to select which page, and the low byte of that
character is used as an index to select one of the double-byte numbers in
that page \- the value obtained being the corresponding Unicode character.
By examination of the example above, one can see that the characters 0x7E
and 0x8163 in \fBshiftjis\fR map to 203E and 2026 in Unicode, respectively.
.PP
Following the first page will be all the other pages, each in the same
format as the first: one number identifying the page followed by 256
double-byte Unicode characters.  If a character in the encoding maps to the
Unicode character 0000, it means that the character doesn't actually exist.
If all characters on a page would map to 0000, that page can be omitted.
.PP
Case [4] is the escape-sequence encoding file.  The lines in an this type of
file are in the same format as this example taken from the \fBiso2022-jp\fR
encoding:
.CS
.ta 1.5i
# Encoding file: iso2022-jp, escape-driven
E
init		{}
final		{}
iso8859-1	\\x1b(B
jis0201		\\x1b(J
jis0208		\\x1b$@
jis0208		\\x1b$B
jis0212		\\x1b$(D
gb2312		\\x1b$A
ksc5601		\\x1b$(C
.CE
.PP
In the file, the first column represents an option and the second column
is the associated value.  \fBinit\fR is a string to emit or expect before
the first character is converted, while \fBfinal\fR is a string to emit
or expect after the last character.  All other options are names of
table-based encodings; the associated value is the escape-sequence that
marks that encoding.  Tcl syntax is used for the values; in the above
example, for instance, ``\fB{}\fR'' represents the empty string and
``\fB\\x1b\fR'' represents character 27.
.PP
When \fBTcl_GetEncoding\fR encounters an encoding \fIname\fR that has not
been loaded, it attempts to load an encoding file called \fIname\fB.enc\fR
from the \fBencoding\fR subdirectory of each directory specified in the
library path \fB$tcl_libPath\fR.  If the encoding file exists, but is
malformed, an error message will be left in \fIinterp\fR.
.SH KEYWORDS
utf, encoding, convert



Changes to doc/Eval.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) Eval.3 1.21 97/01/22 14:22:03
'\" 
.so man.macros
.TH Tcl_Eval 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Eval, Tcl_VarEval, Tcl_EvalFile, Tcl_GlobalEval \- execute Tcl commands
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
int
\fBTcl_Eval\fR(\fIinterp, cmd\fR)
.sp
int
\fBTcl_VarEval\fR(\fIinterp, string, string, ... \fB(char *) NULL\fR)
.sp
int
\fBTcl_EvalFile\fR(\fIinterp, fileName\fR)
.sp
int









\fBTcl_GlobalEval\fR(\fIinterp, cmd\fR)









.SH ARGUMENTS
.AS Tcl_Interp **termPtr;
.AP Tcl_Interp *interp in
Interpreter in which to execute the command.
A string result will be stored in \fIinterp->result\fR.

















.AP char *cmd in
Command (or sequence of commands) to execute.  Must be in writable
memory (\fBTcl_Eval\fR makes temporary modifications to the command).

.AP char *string in
String forming part of Tcl command.
.AP char *fileName in
Name of file containing Tcl command string.


.BE

.SH DESCRIPTION
.PP
All four of these procedures execute Tcl commands.

\fBTcl_Eval\fR is the core procedure and is used by all the others.
It executes the commands in the script held by \fIcmd\fR
until either an error occurs or it reaches the end of the script.





.PP
Note that \fBTcl_Eval\fR and \fBTcl_GlobalEval\fR
have been largely replaced by the








object-based procedures \fBTcl_EvalObj\fR and \fBTcl_GlobalEvalObj\fR.
Those object-based procedures evaluate a script held in a Tcl object



instead of a string.

The object argument can retain the bytecode instructions for the script
and so avoid reparsing the script each time it is executed.



\fBTcl_Eval\fR is implemented using \fBTcl_EvalObj\fR
but is slower because it must reparse the script each time


since there is no object to retain the bytecode instructions.







.PP



The return value from \fBTcl_Eval\fR is one of the Tcl return codes






\fBTCL_OK\fR, \fBTCL_ERROR\fR, \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or
\fBTCL_CONTINUE\fR, and \fIinterp->result\fR will point to
a string with additional information (a result value or error message).
If an error occurs during compilation, this return information
describes the error.
Otherwise, this return information corresponds to the last command
executed from \fIcmd\fR.
.PP
\fBTcl_VarEval\fR takes any number of string arguments
of any length, concatenates them into a single string,
then calls \fBTcl_Eval\fR to execute that string as a Tcl command.
It returns the result of the command and also modifies
\fIinterp->result\fR in the usual fashion for Tcl commands.
The last argument to \fBTcl_VarEval\fR must be NULL to indicate the end
of arguments.
.PP
\fBTcl_EvalFile\fR reads the file given by \fIfileName\fR and evaluates

its contents as a Tcl command by calling \fBTcl_Eval\fR.  It returns
a standard Tcl result that reflects the result of evaluating the file.











If the file couldn't be read then a Tcl error is returned to describe







why the file couldn't be read.

.PP
During the processing of a Tcl command it is legal to make nested
calls to evaluate other commands (this is how procedures and
some control structures are implemented).
If a code other than \fBTCL_OK\fR is returned
from a nested \fBTcl_Eval\fR invocation,
then the caller should normally return immediately,
passing that same return code back to its caller,
and so on until the top-level application is reached.
A few commands, like \fBfor\fR, will check for certain
return codes, like \fBTCL_BREAK\fR and \fBTCL_CONTINUE\fR, and process them
specially without returning.
.PP
\fBTcl_Eval\fR keeps track of how many nested \fBTcl_Eval\fR
invocations are in progress for \fIinterp\fR.
If a code of \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR is
about to be returned from the topmost \fBTcl_Eval\fR
invocation for \fIinterp\fR,
it converts the return code to \fBTCL_ERROR\fR
and sets \fIinterp->result\fR
to point to an error message indicating that
the \fBreturn\fR, \fBbreak\fR, or \fBcontinue\fR command was
invoked in an inappropriate place.
This means that top-level applications should never see a return code
from \fBTcl_Eval\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR.

.SH "SEE ALSO"
Tcl_EvalObj, Tcl_GlobalEvalObj

.SH KEYWORDS
command, execute, file, global, object, object result, variable







|


|


|




<
<
|

|





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



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

|
|
<
>
>




|
>
|
|
|
>
>
>
>
>

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

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





|

|

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





|







|


|


<
|



|
|
<
<


|
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
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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: Eval.3,v 1.1.2.5 1999/03/10 06:49:10 stanton Exp $
'\" 
.so man.macros
.TH Tcl_Eval 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_EvalObjEx, Tcl_EvalFile, Tcl_EvalObjv, Tcl_Eval, Tcl_EvalEx, Tcl_GlobalEval, Tcl_GlobalEvalObj, Tcl_VarEval, Tcl_VarEvalVA \- execute Tcl scripts
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp


.VS
int
\fBTcl_EvalObjEx\fR(\fIinterp, objPtr, flags\fR)
.sp
int
\fBTcl_EvalFile\fR(\fIinterp, fileName\fR)
.sp
int
\fBTcl_EvalObjv\fR(\fIinterp, objc, objv, flags\fR)
.sp
int
\fBTcl_Eval\fR(\fIinterp, script\fR)
.sp
int
\fBTcl_EvalEx\fR(\fIinterp, script, numBytes, flags\fR)
.sp
int
\fBTcl_GlobalEval\fR(\fIinterp, script\fR)
.sp
int
\fBTcl_GlobalEvalObj\fR(\fIinterp, objPtr, flags\fR)
.sp
int
\fBTcl_VarEval\fR(\fIinterp, string, string, ... \fB(char *) NULL\fR)
.sp
int
\fBTcl_VarEvalVA\fR(\fIinterp, argList\fR)
.SH ARGUMENTS
.AS Tcl_Interp **termPtr;
.AP Tcl_Interp *interp in
Interpreter in which to execute the script.  The interpreter's result is
modified to hold the result or error message from the script.
.AP Tcl_Obj *objPtr in
A Tcl object containing the script to execute.
.AP int flags in
ORed combination of flag bits that specify additional options.
\fBTCL_EVAL_GLOBAL\fR and \fBTCL_EVAL_DIRECT\fR are currently supported.
.AP char *fileName in
Name of a file containing a Tcl script.
.AP int *objc in
The number of objects in the array pointed to by \fIobjPtr\fR;
this is also the number of words in the command.
.AP Tcl_Obj **objv in
Points to an array of pointers to objects; each object holds the
value of a single word in the command to execute.
.AP int numBytes in
The number of bytes in \fIscript\fR, not including any
null terminating character.  If \-1, then all characters up to the
first null byte are used.
.AP char *script in
Points to first byte of script to execute.  This script must be in
writable memory: temporary modifications are made to it during
parsing.
.AP char *string in
String forming part of a Tcl script.
.AP va_list argList in

An argument list which must have been initialised using
\fBTCL_VARARGS_START\fR, and cleared using \fBva_end\fR.
.BE

.SH DESCRIPTION
.PP
The procedures described here are invoked to execute Tcl scripts in
various forms.
\fBTcl_EvalObjEx\fR is the core procedure and is used by many of the others.
It executes the commands in the script stored in \fIobjPtr\fR
until either an error occurs or the end of the script is reached.
If this is the first time \fIobjPtr\fR has been executed,
its commands are compiled into bytecode instructions
which are then executed.  The
bytecodes are saved in \fIobjPtr\fR so that the compilation step
can be skipped if the object is evaluated again in the future.
.PP
The return value from \fBTcl_EvalObjEx\fR (and all the other procedures

described here) is a Tcl completion code with
one of the values \fBTCL_OK\fR, \fBTCL_ERROR\fR, \fBTCL_RETURN\fR,
\fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR.
In addition, a result value or error message is left in \fIinterp\fR's
result; it can be retrieved using \fBTcl_GetObjResult\fR.
.PP
\fBTcl_EvalFile\fR reads the file given by \fIfileName\fR and evaluates
its contents as a Tcl script.  It returns the same information as
\fBTcl_EvalObjEx\fR.

If the file couldn't be read then a Tcl error is returned to describe
why the file couldn't be read.
.PP
\fBTcl_EvalObjv\fR executes a single pre-parsed command instead of a
script.  The \fIobjc\fR and \fIobjv\fR arguments contain the values
of the words for the Tcl command, one word in each object in

\fIobjv\fR.  \fBTcl_EvalObjv\fR evaluates the command and returns
a completion code and result just like \fBTcl_EvalObjEx\fR.
.PP
\fBTcl_Eval\fR is similar to \fBTcl_EvalObjEx\fR except that
the script to be executed is supplied as a string instead of an
object and no compilation occurs.  The string is parsed and executed
directly (using \fBTcl_EvalObjv\fR) instead of compiling it and
executing the bytecodes.  In situations where it is known that the
script will never be executed again, \fBTcl_Eval\fR may be
faster than \fBTcl_EvalObjEx\fR.  \fBTcl_Eval\fR returns a completion
code and result just like \fBTcl_EvalObjEx\fR.  Note: for backward
compatibility with versions before Tcl 8.0, \fBTcl_Eval\fR
copies the object result in \fIinterp\fR to \fIinterp->result\fR
where it can be accessed directly.  This makes \fBTcl_Eval\fR somewhat
slower than \fBTcl_EvalEx\fR, which doesn't do the copy.
.PP
\fBTcl_EvalEx\fR is an extended version of \fBTcl_Eval\fR that takes
additional arguments \fInumBytes\fR and \fIflags\fR.  For the
efficiency reason given above, \fBTcl_EvalEx\fR is generally preferred
over \fBTcl_Eval\fR.
.PP
\fBTcl_GlobalEval\fR and \fBTcl_GlobalEvalObj\fR are older procedures
that are now deprecated.  They are similar to \fBTcl_EvalEx\fR and
\fBTcl_EvalObjEx\fR except that the script is evaluated in the global
namespace and its variable context consists of global variables only
(it ignores any Tcl procedures that are active).  These functions are
equivalent to using the \fBTCL_EVAL_GLOBAL\fR flag (see below).






.PP
\fBTcl_VarEval\fR takes any number of string arguments
of any length, concatenates them into a single string,
then calls \fBTcl_Eval\fR to execute that string as a Tcl command.
It returns the result of the command and also modifies
\fIinterp->result\fR in the same way as \fBTcl_Eval\fR.
The last argument to \fBTcl_VarEval\fR must be NULL to indicate the end
of arguments.  \fBTcl_VarEval\fR is now deprecated.
.PP
\fBTcl_VarEvalVA\fR is the same as \fBTcl_VarEval\fR except that
instead of taking a variable number of arguments it takes an argument
list. Like \fBTcl_VarEval\fR, \fBTcl_VarEvalVA\fR is deprecated.

.SH "FLAG BITS"
Any ORed combination of the following values may be used for the
\fIflags\fR argument to procedures such as \fBTcl_EvalObjEx\fR:
.TP 23
\fBTCL_EVAL_DIRECT\fR
This flag is only used by \fBTcl_EvalObjEx\fR; it is ignored by
other procedures.  If this flag bit is set, the script is not
compiled to bytecodes; instead it is executed directly
as is done by \fBTcl_EvalEx\fR.  The
\fBTCL_EVAL_DIRECT\fR flag is useful in situations where the
contents of an object are going to change immediately, so the
bytecodes won't be reused in a future execution.  In this case,
it's faster to execute the script directly.
.TP 23
\fBTCL_EVAL_GLOBAL\fR
If this flag is set, the script is processed at global level.  This
means that it is evaluated in the global namespace and its variable
context consists of global variables only (it ignores any Tcl
procedures at are active).

.SH "MISCELLANEOUS DETAILS"
.PP
During the processing of a Tcl command it is legal to make nested
calls to evaluate other commands (this is how procedures and
some control structures are implemented).
If a code other than \fBTCL_OK\fR is returned
from a nested \fBTcl_EvalObjEx\fR invocation,
then the caller should normally return immediately,
passing that same return code back to its caller,
and so on until the top-level application is reached.
A few commands, like \fBfor\fR, will check for certain
return codes, like \fBTCL_BREAK\fR and \fBTCL_CONTINUE\fR, and process them
specially without returning.
.PP
\fBTcl_EvalObjEx\fR keeps track of how many nested \fBTcl_EvalObjEx\fR
invocations are in progress for \fIinterp\fR.
If a code of \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR is
about to be returned from the topmost \fBTcl_EvalObjEx\fR
invocation for \fIinterp\fR,
it converts the return code to \fBTCL_ERROR\fR

and sets \fIinterp\fR's result to an error message indicating that
the \fBreturn\fR, \fBbreak\fR, or \fBcontinue\fR command was
invoked in an inappropriate place.
This means that top-level applications should never see a return code
from \fBTcl_EvalObjEx\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR.
.VE



.SH KEYWORDS
execute, file, global, object, result, script

Deleted doc/EvalObj.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) 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.
'\" 
'\" SCCS: @(#) EvalObj.3 1.4 97/01/22 15:18:44
'\" 
.so man.macros
.TH Tcl_EvalObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_EvalObj, Tcl_GlobalEvalObj \- execute Tcl commands
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
int
\fBTcl_EvalObj\fR(\fIinterp, objPtr\fR)
.sp
int
\fBTcl_GlobalEvalObj\fR(\fIinterp, objPtr\fR)
.SH ARGUMENTS
.AS Tcl_Interp **termPtr;
.AP Tcl_Interp *interp in
Interpreter in which to execute the command.
The command's result will be stored in the interpreter's result object
and can be retrieved using \fBTcl_GetObjResult\fR.
.AP Tcl_Obj *objPtr in
A Tcl object containing a command string
(or sequence of commands in a string) to execute.
.BE

.SH DESCRIPTION
.PP
These two procedures execute Tcl commands.
\fBTcl_EvalObj\fR is the core procedure
and is used by \fBTcl_GlobalEvalObj\fR.
It executes the commands in the script held by \fIobjPtr\fR
until either an error occurs or it reaches the end of the script.
If this is the first time \fIobjPtr\fR has been executed,
its commands are compiled into bytecode instructions
that are then executed if there are no compilation errors.
.PP
The return value from \fBTcl_EvalObj\fR is one of the Tcl return codes
\fBTCL_OK\fR, \fBTCL_ERROR\fR, \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or
\fBTCL_CONTINUE\fR,
and a result object containing additional information
(a result value or error message)
that can be retrieved using \fBTcl_GetObjResult\fR.
If an error occurs during compilation, this return information
describes the error.
Otherwise, this return information corresponds to the last command
executed from \fIobjPtr\fR.
.PP
\fBTcl_GlobalEvalObj\fR is similar to \fBTcl_EvalObj\fR except that it
processes the command at global level.
This means that the variable context for the command consists of
global variables only (it ignores any Tcl procedure that is active).
This produces an effect similar to the Tcl command ``\fBuplevel 0\fR''.
.PP
During the processing of a Tcl command it is legal to make nested
calls to evaluate other commands (this is how procedures and
some control structures are implemented).
If a code other than \fBTCL_OK\fR is returned
from a nested \fBTcl_EvalObj\fR invocation,
then the caller should normally return immediately,
passing that same return code back to its caller,
and so on until the top-level application is reached.
A few commands, like \fBfor\fR, will check for certain
return codes, like \fBTCL_BREAK\fR and \fBTCL_CONTINUE\fR, and process them
specially without returning.
.PP
\fBTcl_EvalObj\fR keeps track of how many nested \fBTcl_EvalObj\fR
invocations are in progress for \fIinterp\fR.
If a code of \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR is
about to be returned from the topmost \fBTcl_EvalObj\fR
invocation for \fIinterp\fR,
it converts the return code to \fBTCL_ERROR\fR
and sets the interpreter's result object
to point to an error message indicating that
the \fBreturn\fR, \fBbreak\fR, or \fBcontinue\fR command was
invoked in an inappropriate place.
This means that top-level applications should never see a return code
from \fBTcl_EvalObj\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR.

.SH "SEE ALSO"
Tcl_GetObjResult, Tcl_SetObjResult

.SH KEYWORDS
command, execute, file, global, object, object result, variable
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































Changes to doc/Exit.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
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Exit.3 1.8 96/12/10 07:37:23
'\" 
.so man.macros
.TH Tcl_Exit 3 7.7 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Exit, Tcl_Finalize, Tcl_CreateExitHandler, Tcl_DeleteExitHandler \- end the application (and invoke exit handlers)
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
\fBTcl_Exit\fR(\fIstatus\fR)
.sp
\fBTcl_Finalize\fR()
.sp
\fBTcl_CreateExitHandler\fR(\fIproc, clientData\fR)
.sp
\fBTcl_DeleteExitHandler\fR(\fIproc, clientData\fR)








.SH ARGUMENTS
.AS Tcl_ExitProc clientData
.AP int status  in
Provides information about why application exited.  Exact meaning may

be platform-specific.  0 usually means a normal exit, any nonzero value
usually means that an error occurred.
.AP Tcl_ExitProc *proc in
Procedure to invoke before exiting application.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE






|


|


|











>
>
>
>
>
>
>
>



|
>







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) 1995-1996 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: Exit.3,v 1.1.2.2 1998/09/24 23:58:23 stanton Exp $
'\" 
.so man.macros
.TH Tcl_Exit 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Exit, Tcl_Finalize, Tcl_FinalizeThread, Tcl_CreateExitHandler, Tcl_DeleteExitHandler, Tcl_CreateThreadExitHandler, Tcl_DeleteThreadExitHandler \- end the application or thread (and invoke exit handlers)
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
\fBTcl_Exit\fR(\fIstatus\fR)
.sp
\fBTcl_Finalize\fR()
.sp
\fBTcl_CreateExitHandler\fR(\fIproc, clientData\fR)
.sp
\fBTcl_DeleteExitHandler\fR(\fIproc, clientData\fR)
.sp
\fBTcl_ExitThread\fR(\fIstatus\fR)
.sp
\fBTcl_FinalizeThread\fR()
.sp
\fBTcl_CreateThreadExitHandler\fR(\fIproc, clientData\fR)
.sp
\fBTcl_DeleteThreadExitHandler\fR(\fIproc, clientData\fR)
.SH ARGUMENTS
.AS Tcl_ExitProc clientData
.AP int status  in
Provides information about why the application or thread exited.
Exact meaning may
be platform-specific.  0 usually means a normal exit, any nonzero value
usually means that an error occurred.
.AP Tcl_ExitProc *proc in
Procedure to invoke before exiting application.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE
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
invoke \fBTcl_Exit\fR instead, so that it can invoke exit handlers.
Note that if other code invokes \fBexit\fR system procedure directly, or
otherwise causes the application to terminate without calling
\fBTcl_Exit\fR, the exit handlers will not be run.
\fBTcl_Exit\fR internally invokes the \fBexit\fR system call, thus it never
returns control to its caller.
.PP
.VS
\fBTcl_Finalize\fR is similar to \fBTcl_Exit\fR except that it does not
exit from the current process.
It is useful for cleaning up when a process is finished using \fBTcl\fR but
wishes to continue executing, and when \fBTcl\fR is used in a dynamically
loaded extension that is about to be unloaded.
On some systems \fBTcl\fR is automatically notified when it is being
unloaded, and it calls \fBTcl_Finalize\fR internally; on these systems it
not necessary for the caller to explicitly call \fBTcl_Finalize\fR.
However, to ensure portability, your code should always invoke
\fBTcl_Finalize\fR when \fBTcl\fR is being unloaded, to ensure that the
code will work on all platforms. \fBTcl_Finalize\fR can be safely called
more than once.








.VE
.PP
\fBTcl_CreateExitHandler\fR arranges for \fIproc\fR to be invoked
by \fBTcl_Finalize\fR and \fBTcl_Exit\fR.


This provides a hook for cleanup operations such as flushing buffers
and freeing global memory.
\fIProc\fR should match the type \fBTcl_ExitProc\fR:
.CS
typedef void Tcl_ExitProc(ClientData \fIclientData\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a
copy of the \fIclientData\fR argument given to
\fBTcl_CreateExitHandler\fR when the callback

was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information about
what to do in \fIproc\fR.
.PP
\fBTcl_DeleteExitHandler\fR may be called to delete a

previously-created exit handler.  It removes the handler
indicated by \fIproc\fR and \fIclientData\fR so that no call
to \fIproc\fR will be made.  If no such handler exists then
\fBTcl_DeleteExitHandler\fR does nothing.
.PP
.VS
.PP
\fBTcl_Finalize\fR and \fBTcl_Exit\fR execute all registered exit handlers,
in reverse order from the order in which they were registered.
This matches the natural order in which extensions are loaded and unloaded;
if extension \fBA\fR loads extension \fBB\fR, it usually
unloads \fBB\fR before it itself is unloaded.
If extension \fBA\fR registers its exit handlers before loading extension
\fBB\fR, this ensures that any exit handlers for \fBB\fR will be executed
before the exit handlers for \fBA\fR.
.VE









.SH KEYWORDS
callback, cleanup, dynamic loading, end application, exit, unloading







<












>
>
>
>
>
>
>
>




>
>








|
>




|
>



|












>
>
>
>
>
>
>
>


|
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
invoke \fBTcl_Exit\fR instead, so that it can invoke exit handlers.
Note that if other code invokes \fBexit\fR system procedure directly, or
otherwise causes the application to terminate without calling
\fBTcl_Exit\fR, the exit handlers will not be run.
\fBTcl_Exit\fR internally invokes the \fBexit\fR system call, thus it never
returns control to its caller.
.PP

\fBTcl_Finalize\fR is similar to \fBTcl_Exit\fR except that it does not
exit from the current process.
It is useful for cleaning up when a process is finished using \fBTcl\fR but
wishes to continue executing, and when \fBTcl\fR is used in a dynamically
loaded extension that is about to be unloaded.
On some systems \fBTcl\fR is automatically notified when it is being
unloaded, and it calls \fBTcl_Finalize\fR internally; on these systems it
not necessary for the caller to explicitly call \fBTcl_Finalize\fR.
However, to ensure portability, your code should always invoke
\fBTcl_Finalize\fR when \fBTcl\fR is being unloaded, to ensure that the
code will work on all platforms. \fBTcl_Finalize\fR can be safely called
more than once.
.PP
.VS
\fBTcl_ExitThread\fR is used to terminate the current thread and invoke
per-thread exit handlers.  This finalization is done by
\fBTcl_FinalizeThread\fR, which you can call if you just want to clean
up per-thread state and invoke the thread exit handlers.
\fBTcl_Finalize\fR calls \fBTcl_FinalizeThread\fR for the current
thread automatically.
.VE
.PP
\fBTcl_CreateExitHandler\fR arranges for \fIproc\fR to be invoked
by \fBTcl_Finalize\fR and \fBTcl_Exit\fR.
\fBTcl_CreateThreadExitHandler\fR arranges for \fIproc\fR to be invoked
by \fBTcl_FinalizeThread\fR and \fBTcl_ExitThread\fR.
This provides a hook for cleanup operations such as flushing buffers
and freeing global memory.
\fIProc\fR should match the type \fBTcl_ExitProc\fR:
.CS
typedef void Tcl_ExitProc(ClientData \fIclientData\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a
copy of the \fIclientData\fR argument given to
\fBTcl_CreateExitHandler\fR or \fBTcl_CreateThreadExitHandler\fR when
the callback
was created.  Typically, \fIclientData\fR points to a data
structure containing application-specific information about
what to do in \fIproc\fR.
.PP
\fBTcl_DeleteExitHandler\fR and \fBTcl_DeleteThreadExitHandler\fR may be
called to delete a
previously-created exit handler.  It removes the handler
indicated by \fIproc\fR and \fIclientData\fR so that no call
to \fIproc\fR will be made.  If no such handler exists then
\fBTcl_DeleteExitHandler\fR or \fBTcl_DeleteThreadExitHandler\fR does nothing.
.PP
.VS
.PP
\fBTcl_Finalize\fR and \fBTcl_Exit\fR execute all registered exit handlers,
in reverse order from the order in which they were registered.
This matches the natural order in which extensions are loaded and unloaded;
if extension \fBA\fR loads extension \fBB\fR, it usually
unloads \fBB\fR before it itself is unloaded.
If extension \fBA\fR registers its exit handlers before loading extension
\fBB\fR, this ensures that any exit handlers for \fBB\fR will be executed
before the exit handlers for \fBA\fR.
.VE
.VS
.PP
\fBTcl_Finalize\fR and \fBTcl_Exit\fR call \fBTcl_FinalizeThread\fR 
and the thread exit handlers \fIafter\fR
the process-wide exit handlers.  This is because thread finalization shuts
down the I/O channel system, so any attempt at I/O by the global exit
handlers will vanish into the bitbucket.
.VE

.SH KEYWORDS
callback, cleanup, dynamic loading, end application, exit, unloading, thread

Changes to doc/ExprLong.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) ExprLong.3 1.26 97/06/26 13:42:47
'\" 
.so man.macros
.TH Tcl_ExprLong 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString \- evaluate an expression
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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: ExprLong.3,v 1.1.2.1 1998/09/24 23:58:23 stanton Exp $
'\" 
.so man.macros
.TH Tcl_ExprLong 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString \- evaluate an expression
.SH SYNOPSIS

Changes to doc/ExprLongObj.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) ExprLongObj.3 1.6 97/06/26 13:41:12
'\" 
.so man.macros
.TH Tcl_ExprLongObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj \- evaluate an expression
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: ExprLongObj.3,v 1.1.2.1 1998/09/24 23:58:23 stanton Exp $
'\" 
.so man.macros
.TH Tcl_ExprLongObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj \- evaluate an expression
.SH SYNOPSIS

Changes to doc/FindExec.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
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) FindExec.3 1.4 96/10/09 08:29:29
'\" 
.so man.macros
.TH Tcl_FindExecutable 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_FindExecutable \- identify the binary file containing the application
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
char *
\fBTcl_FindExecutable\fR(\fIargv0\fR)



.SH ARGUMENTS
.AS char *argv0 in
.AP char *argv0 in
The first command-line argument to the program, which gives the
application's name.
.BE

.SH DESCRIPTION
.PP
This procedure computes the full path name of the executable file
from which the application was invoked and saves it for Tcl's
internal use.
The executable's path name is needed for several purposes in
Tcl.  For example, it is needed on some platforms in the
implementation of the \fBload\fR command.
It is also returned by the \fBinfo nameofexecutable\fR command.
.PP
On UNIX platforms this procedure is typically invoked as the very
first thing in the application's main program;  it must be passed
\fIargv[0]\fR as its argument.  \fBTcl_FindExecutable\fR uses \fIargv0\fR
along with the \fBPATH\fR environment variable to find the
application's executable, if possible.  If it fails to find
the binary, then future calls to \fBinfo nameofexecutable\fR
will return an empty string.








.SH KEYWORDS
binary, executable file






|





|






>
>
>









|
|
|












>
>
>
>
>
>
>



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
'\"
'\" Copyright (c) 1995-1996 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: FindExec.3,v 1.1.2.1 1998/09/24 23:58:23 stanton Exp $
'\" 
.so man.macros
.TH Tcl_FindExecutable 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_FindExecutable, Tcl_GetNameOfExecutable \- identify or return the name of the binary file containing the application
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
char *
\fBTcl_FindExecutable\fR(\fIargv0\fR)
.sp
CONST char *
\fBTcl_GetNameOfExecutable\fR()
.SH ARGUMENTS
.AS char *argv0 in
.AP char *argv0 in
The first command-line argument to the program, which gives the
application's name.
.BE

.SH DESCRIPTION
.PP
The \fBTcl_FindExecutable\fR procedure computes the full path name of
the executable file from which the application was invoked and saves
it for Tcl's internal use.
The executable's path name is needed for several purposes in
Tcl.  For example, it is needed on some platforms in the
implementation of the \fBload\fR command.
It is also returned by the \fBinfo nameofexecutable\fR command.
.PP
On UNIX platforms this procedure is typically invoked as the very
first thing in the application's main program;  it must be passed
\fIargv[0]\fR as its argument.  \fBTcl_FindExecutable\fR uses \fIargv0\fR
along with the \fBPATH\fR environment variable to find the
application's executable, if possible.  If it fails to find
the binary, then future calls to \fBinfo nameofexecutable\fR
will return an empty string.
.PP
\fBTcl_GetNameOfExecutable\fR simply returns a pointer to the
internal full path name of the executable file as computed by
\fBTcl_FindExecutable\fR.  This procedure call is the C API
equivalent to the \fBinfo nameofexecutable\fR command.  NULL
is returned if the internal full path name has not been
computed or unknown.

.SH KEYWORDS
binary, executable file

Added doc/GetCwd.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
'\"
'\" 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: GetCwd.3,v 1.1.2.2 1999/04/06 02:56:07 rjohnson Exp $
'\" 
.so man.macros
.TH Tcl_GetCwd 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetCwd, Tcl_Chdir \- manipulate the current working directory
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
char *
\fBTcl_GetCwd\fR(\fIinterp\fR, \fIbufferPtr\fR)
.sp
int
\fBTcl_Chdir\fR(\fIpath\fR)
.SH ARGUMENTS
.AS Tcl_DString *bufferPtr
.AP Tcl_Interp *interp in
Interpreter in which to report an error, if any.
.AP Tcl_DString *bufferPtr in/out
This dynamic string is used to store the current working directory.
At the time of the call it should be uninitialized or free.  The
caller must eventually call \fBTcl_DStringFree\fR to free up
anything stored here.
.AP char *path in
File path in UTF\-8 format.
.BE

.SH DESCRIPTION
.PP
These procedures may be used to manipulate the current working
directory for the application.  They provide C\-level access to
the same functionality as the Tcl \fBpwd\fR command.
.PP
\fBTcl_GetCwd\fR returns a pointer to a string specifying the current
directory, or NULL if the current directory could not be determined.
If NULL is returned, an error message is left in the interp's result.
Storage for the result string is allocated in bufferPtr; the caller
must call \fBTcl_DStringFree()\fR when the result is no longer needed.
The format of the path is UTF\-8.
.PP
\fBTcl_Chdir\fR changes the applications current working directory to
the value specified in \fIpath\fR.  The format of the passed in string
must be UTF\-8.  The function returns -1 on error or 0 on success.

.SH KEYWORDS
pwd

Changes to doc/GetIndex.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
'\"
'\" 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.
'\" 
'\" SCCS: @(#) @(#) GetIndex.3 1.3 97/07/30 16:21:05
'\" 
.so man.macros
.TH Tcl_GetIndexFromObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetIndexFromObj \- lookup string in table of keywords
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
int
\fBTcl_GetIndexFromObj\fR(\fIinterp, objPtr, tablePtr, msg, flags, indexPtr\fR)







.SH ARGUMENTS
.AS Tcl_Interp **tablePtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting; if NULL, then no message is
provided on errors.
.AP Tcl_Obj *objPtr in/out
The string value of this object is used to search through \fItablePtr\fR.
The internal representation is modified to hold the index of the matching
table entry.
.AP char **tablePtr in
An array of null-terminated strings.  The end of the array is marked
by a NULL string pointer.





.AP char *msg in
Null-terminated string describing what is being looked up, such as
\fBoption\fR.  This string is included in error messages.
.AP int flags in
OR-ed combination of bits providing additional information for
operation.  The only bit that is currently defined is \fBTCL_EXACT\fR.
.AP int *indexPtr out






|


|








|
>
>
>
>
>
>
>












>
>
>
>
>







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
'\"
'\" 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: GetIndex.3,v 1.1.2.2 1998/09/24 23:58:24 stanton Exp $
'\" 
.so man.macros
.TH Tcl_GetIndexFromObj 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetIndexFromObj \- lookup string in table of keywords
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
int
\fBTcl_GetIndexFromObj\fR(\fIinterp, objPtr, tablePtr, msg, flags,
indexPtr\fR)
.VS
.sp
int
\fBTcl_GetIndexFromObjStruct\fR(\fIinterp, objPtr, tablePtr, offset,
msg, flags, indexPtr\fR)
.VE
.SH ARGUMENTS
.AS Tcl_Interp **tablePtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting; if NULL, then no message is
provided on errors.
.AP Tcl_Obj *objPtr in/out
The string value of this object is used to search through \fItablePtr\fR.
The internal representation is modified to hold the index of the matching
table entry.
.AP char **tablePtr in
An array of null-terminated strings.  The end of the array is marked
by a NULL string pointer.
.VS
.AP int offset in
The offset to add to tablePtr to get to the next string in the
list. The end of the array is marked by a NULL string pointer.
.VE
.AP char *msg in
Null-terminated string describing what is being looked up, such as
\fBoption\fR.  This string is included in error messages.
.AP int flags in
OR-ed combination of bits providing additional information for
operation.  The only bit that is currently defined is \fBTCL_EXACT\fR.
.AP int *indexPtr out
64
65
66
67
68
69
70
71











72
73
74
75
76
77
If \fBTcl_GetIndexFromObj\fR completes successfully it modifies the
internal representation of \fIobjPtr\fR to hold the address of
the table and the index of the matching entry.  If \fBTcl_GetIndexFromObj\fR
is invoked again with the same \fIobjPtr\fR and \fItablePtr\fR
arguments (e.g. during a reinvocation of a Tcl command), it returns
the matching index immediately without having to redo the lookup
operation.  Note: \fBTcl_GetIndexFromObj\fR assumes that the entries
in \fItablePtr\fR are static: they must not change between invocations.












.SH "SEE ALSO"
Tcl_WrongNumArgs

.SH KEYWORDS
index, object, table lookup







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






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
If \fBTcl_GetIndexFromObj\fR completes successfully it modifies the
internal representation of \fIobjPtr\fR to hold the address of
the table and the index of the matching entry.  If \fBTcl_GetIndexFromObj\fR
is invoked again with the same \fIobjPtr\fR and \fItablePtr\fR
arguments (e.g. during a reinvocation of a Tcl command), it returns
the matching index immediately without having to redo the lookup
operation.  Note: \fBTcl_GetIndexFromObj\fR assumes that the entries
in \fItablePtr\fR are static: they must not change between
invocations.
.VS
.PP
\fBTcl_GetIndexFromObjStruct\fR works just like
\fBTcl_GetIndexFromObj\fR, except that instead of treating
\fItablePtr\fR as an array of string pointers, it treats it as the
first in a series of string ptrs that are spaced apart by \fIoffset\fR
bytes. This is particularly useful when processing things like
\fBTk_ConfigurationSpec\fR, whose string keys are in the same place in
each of several array elements.
.VE

.SH "SEE ALSO"
Tcl_WrongNumArgs

.SH KEYWORDS
index, object, table lookup

Changes to doc/GetInt.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) GetInt.3 1.12 96/03/25 20:03:44
'\" 
.so man.macros
.TH Tcl_GetInt 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetInt, Tcl_GetDouble, Tcl_GetBoolean \- convert from string to integer, double, or boolean
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: GetInt.3,v 1.1.2.1 1998/09/24 23:58:24 stanton Exp $
'\" 
.so man.macros
.TH Tcl_GetInt 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetInt, Tcl_GetDouble, Tcl_GetBoolean \- convert from string to integer, double, or boolean
.SH SYNOPSIS

Changes to doc/GetOpnFl.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) GetOpnFl.3 1.3 97/04/23 16:14:43
.so man.macros
.TH Tcl_GetOpenFile 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetOpenFile \- Get a standard IO File * handle from a channel. (Unix only)
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: GetOpnFl.3,v 1.1.2.1 1998/09/24 23:58:24 stanton Exp $
.so man.macros
.TH Tcl_GetOpenFile 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetOpenFile \- Get a standard IO File * handle from a channel. (Unix only)
.SH SYNOPSIS
.nf

Changes to doc/GetStdChan.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1996 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.
'\" 
'\" @(#) GetStdChan.3 1.2 96/03/08 13:59:57
'\" 
.so man.macros
.TH Tcl_GetStdChannel 3 7.5 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_GetStdChannel, Tcl_SetStdChannel \- procedures for retrieving and replacing the standard channels






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1996 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: GetStdChan.3,v 1.1.2.1 1998/09/24 23:58:24 stanton Exp $
'\" 
.so man.macros
.TH Tcl_GetStdChannel 3 7.5 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_GetStdChannel, Tcl_SetStdChannel \- procedures for retrieving and replacing the standard channels

Added doc/GetVersion.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
'\"
'\" Copyright (c) 1999 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: GetVersion.3,v 1.1.2.1 1999/04/07 03:21:21 stanton Exp $
'\" 
.so man.macros
.TH Tcl_GetVersion 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetVersion \- get the version of the library at runtime
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
\fBTcl_GetVersion\fR(\fImajor, minor, patchLevel, type\fR)
.SH ARGUMENTS
.AP int *major out
Major version number of the Tcl library.
.AP int *minor out
Minor version number of the Tcl library.
.AP int *patchLevel out
The patch level of the Tcl library (or alpha or beta number).
.AP Tcl_ReleaseType *type out
The type of release, also indicates the type of patch level. Can be
one of \fBTCL_ALPHA_RELEASE\fR, \fBTCL_BETA_RELEASE\fR, or 
\fBTCL_FINAL_RELEASE\fR.
.BE

.SH DESCRIPTION
.PP
\fBTcl_GetVersion\fR should be used to query the version number
of the Tcl library at runtime.  This is useful when using a 
dynamically loaded Tcl library or when writing a stubs-aware
extension.  For instance, if you write an extension that is
linked against the Tcl stubs library, it could be loaded into
a program linked to an older version of Tcl than you expected.
Use \fBTcl_GetVersion\fR to verify that fact, and possibly to
change the behavior of your extension.
.PP
If may pass a NULL for any of the arguments. For instance if 
you do not care about the \fIpatchLevel\fR of the library, pass
a NULL for the \fIpatchLevel\fR argument.

.SH KEYWORDS
version, patchlevel, major, minor, alpha, beta, release

Changes to doc/Hash.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Hash.3 1.15 96/03/25 20:04:01
'\" 
.so man.macros
.TH Tcl_Hash 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_InitHashTable, Tcl_DeleteHashTable, Tcl_CreateHashEntry, Tcl_DeleteHashEntry, Tcl_FindHashEntry, Tcl_GetHashValue, Tcl_SetHashValue, Tcl_GetHashKey, Tcl_FirstHashEntry, Tcl_NextHashEntry, Tcl_HashStats \- procedures to manage hash tables
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: Hash.3,v 1.1.2.1 1998/09/24 23:58:24 stanton Exp $
'\" 
.so man.macros
.TH Tcl_Hash 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_InitHashTable, Tcl_DeleteHashTable, Tcl_CreateHashEntry, Tcl_DeleteHashEntry, Tcl_FindHashEntry, Tcl_GetHashValue, Tcl_SetHashValue, Tcl_GetHashKey, Tcl_FirstHashEntry, Tcl_NextHashEntry, Tcl_HashStats \- procedures to manage hash tables
.SH SYNOPSIS

Changes to doc/IntObj.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) @(#) IntObj.3 1.7 97/05/08 19:49:22
'\" 
.so man.macros
.TH Tcl_IntObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewIntObj, Tcl_NewLongObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj \- manipulate Tcl objects as integers
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: IntObj.3,v 1.1.2.1 1998/09/24 23:58:24 stanton Exp $
'\" 
.so man.macros
.TH Tcl_IntObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewIntObj, Tcl_NewLongObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj \- manipulate Tcl objects as integers
.SH SYNOPSIS

Changes to doc/Interp.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Interp.3 1.16 96/06/06 13:48:02
'\" 
.so man.macros
.TH Tcl_Interp 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Interp \- client-visible fields of interpreter structures
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: Interp.3,v 1.1.2.1 1998/09/24 23:58:24 stanton Exp $
'\" 
.so man.macros
.TH Tcl_Interp 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Interp \- client-visible fields of interpreter structures
.SH SYNOPSIS

Changes to doc/LinkVar.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) LinkVar.3 1.15 96/09/05 17:16:57
'\" 
.so man.macros
.TH Tcl_LinkVar 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_LinkVar, Tcl_UnlinkVar, Tcl_UpdateLinkedVar \- link Tcl variable to C variable
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: LinkVar.3,v 1.1.2.1 1998/09/24 23:58:24 stanton Exp $
'\" 
.so man.macros
.TH Tcl_LinkVar 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_LinkVar, Tcl_UnlinkVar, Tcl_UpdateLinkedVar \- link Tcl variable to C variable
.SH SYNOPSIS

Changes to doc/ListObj.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) @(#) ListObj.3 1.10 97/10/08 11:36:58
'\" 
.so man.macros
.TH Tcl_ListObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl objects as lists
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: ListObj.3,v 1.1.2.1 1998/09/24 23:58:24 stanton Exp $
'\" 
.so man.macros
.TH Tcl_ListObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl objects as lists
.SH SYNOPSIS

Changes to doc/Notifier.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) Notifier.3 1.16 97/05/17 17:03:17
'\" 
.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






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.1.2.1 1998/09/24 23:58:25 stanton 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

Deleted doc/ObjSetVar.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
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
'\"
'\" 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.
'\" 
'\" SCCS: @(#) ObjSetVar.3 1.6 97/05/19 17:35:44
'\" 
.so man.macros
.TH Tcl_ObjSetVar2 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ObjSetVar2, Tcl_ObjGetVar2 \- manipulate Tcl variables
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_Obj *
\fBTcl_ObjSetVar2\fR(\fIinterp, part1Ptr, part2Ptr, newValuePtr, flags\fR)
.sp
Tcl_Obj *
\fBTcl_ObjGetVar2\fR(\fIinterp, part1Ptr, part2Ptr, flags\fR)
.SH ARGUMENTS
.AS Tcl_Interp *newValuePtr
.AP Tcl_Interp *interp in
Interpreter containing variable.
.AP Tcl_Obj *part1Ptr in
Points to a Tcl object containing the variable's name.
The name may include a series of \fB::\fR namespace qualifiers
to specify a variable in a particular namespace.
May refer to a scalar variable or an element of an array variable.
.AP Tcl_Obj *part2Ptr in
If non-NULL, points to an object containing the name of an element
within an array and \fIpart1Ptr\fR must refer to an array variable.
.AP Tcl_Obj *newValuePtr in
Points to a Tcl object containing the new value for the variable.
.AP int flags in
OR-ed combination of bits providing additional information for
operation. See below for valid values.
.BE

.SH DESCRIPTION
.PP
These two procedures may be used to read and modify
Tcl variables from C code.
\fBTcl_ObjSetVar2\fR will create a new variable or modify an existing one.
It sets the specified variable to
the object referenced by \fInewValuePtr\fR
and returns a pointer to the object which is the variable's new value.
The returned object may not be the same one
referenced by \fInewValuePtr\fR;
this might happen because variable traces may modify the variable's value.
The reference count for the variable's old value is decremented
and the reference count for its new value is incremented.
If the new value for the variable
is not the same one referenced by \fInewValuePtr\fR
(perhaps as a result of a variable trace),
then \fInewValuePtr\fR's reference count is left unchanged.
The reference count for the returned object is not incremented
to reflect the returned reference.
If the caller needs to keep a reference to the object,
say in a data structure,
it must increment its reference count using \fBTcl_IncrRefCount\fR.
If an error occurs in setting the variable
(e.g. an array variable is referenced
without giving an index into the array),
then NULL is returned.
.PP
The variable name specified to \fBTcl_ObjSetVar2\fR consists of two parts.
\fIpart1Ptr\fR contains the name of a scalar or array variable.
If \fIpart2Ptr\fR is NULL, the variable must be a scalar.
If \fIpart2Ptr\fR is not NULL,
it contains the name of an element in the array named by \fIpart2Ptr\fR.
As a special case, if the flag TCL_PARSE_PART1 is specified,
\fIpart1Ptr\fR may contain both an array and an element name:
if the name contains an open parenthesis and ends with a
close parenthesis, then the value between the parentheses is
treated as an element name (which can have any string value) and
the characters before the first open
parenthesis are treated as the name of an array variable.
If the flag TCL_PARSE_PART1 is given,
\fIpart2Ptr\fR should be NULL since the array and element names
are taken from \fIpart2Ptr\fR.
.PP
The \fIflags\fR argument may be used to specify any of several
options to the procedures.
It consists of an OR-ed combination of any of the following
bits:
.TP
\fBTCL_GLOBAL_ONLY\fR
Under normal circumstances the procedures look up variables as follows:
If a procedure call is active in \fIinterp\fR,
a variable is looked up at the current level of procedure call.
Otherwise, a variable is looked up first in the current namespace,
then in the global namespace.
However, if this bit is set in \fIflags\fR then the variable
is looked up only in the global namespace
even if there is a procedure call active.
If both \fBTCL_GLOBAL_ONLY\fR and \fBTCL_NAMESPACE_ONLY\fR are given,
\fBTCL_GLOBAL_ONLY\fR is ignored.
.TP
\fBTCL_NAMESPACE_ONLY\fR
Under normal circumstances the procedures look up variables as follows:
If a procedure call is active in \fIinterp\fR,
a variable is looked up at the current level of procedure call.
Otherwise, a variable is looked up first in the current namespace,
then in the global namespace.
However, if this bit is set in \fIflags\fR then the variable
is looked up only in the current namespace
even if there is a procedure call active.
.TP
\fBTCL_LEAVE_ERR_MSG\fR
If an error is returned and this bit is set in \fIflags\fR, then
an error message will be left in the interpreter's result,
where it can be retrieved with \fBTcl_GetObjResult\fR
or \fBTcl_GetStringResult\fR.
If this flag bit isn't set then no error message is left
and the interpreter's result will not be modified.
.TP
\fBTCL_APPEND_VALUE\fR
If this bit is set then \fInewValuePtr\fR is appended to the current
value, instead of replacing it.
If the variable is currently undefined, then this bit is ignored.
.TP
\fBTCL_LIST_ELEMENT\fR
If this bit is set, then \fInewValuePtr\fR is converted to a valid
Tcl list element before setting (or appending to) the variable.
A separator space is appended before the new list element unless
the list element is going to be the first element in a list or
sublist (i.e. the variable's current value is empty, or contains
the single character ``{'', or ends in `` }'').
.TP
\fBTCL_PARSE_PART1\fR
If this bit is set,
then \fBTcl_ObjGetVar2\fR and \fBTcl_ObjSetVar2\fR
will parse \fIpart1Ptr\fR
to obtain both an array name and an element name.
If the name in \fIpart1Ptr\fR contains an open parenthesis
and ends with a close parenthesis,
the name is treated as the name of an element of an array;
otherwise, the name in \fIpart1Ptr\fR
is interpreted as the name of a scalar variable.
When this bit is set,
\fIpart2Ptr\fR is ignored.
.PP
\fBTcl_ObjGetVar2\fR returns the value of the specified variable.
Its arguments are treated the same way as those for \fBTcl_ObjSetVar2\fR.
It returns a pointer to the object which is the variable's value.
The reference count for the returned object is not incremented.
If the caller needs to keep a reference to the object,
say in a data structure,
it must increment the reference count using \fBTcl_IncrRefCount\fR.
If an error occurs in setting the variable
(e.g. an array variable is referenced
without giving an index into the array),
then NULL is returned.

.SH "SEE ALSO"
Tcl_GetObjResult, Tcl_GetStringResult, Tcl_GetVar, Tcl_GetVar2, Tcl_SetVar, Tcl_SetVar2, Tcl_TraceVar, Tcl_UnsetVar, Tcl_UnsetVar2

.SH KEYWORDS
array, interpreter, object, scalar, set, unset, variable
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































Changes to doc/Object.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) @(#) Object.3 1.10 97/07/22 11:40:10
'\" 
.so man.macros
.TH Tcl_Obj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared \- manipulate Tcl objects
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: Object.3,v 1.1.2.4 1999/04/14 00:30:36 surles Exp $
'\" 
.so man.macros
.TH Tcl_Obj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared \- manipulate Tcl objects
.SH SYNOPSIS
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
an up-to-date string can always be obtained,
and any change to the object will be reflected in that string
when the object's string representation is fetched.
Because of this representation invalidation and regeneration,
it is dangerous for extension writers to access
\fBTcl_Obj\fR fields directly.
It is better to access Tcl_Obj information using
procedures like \fBTcl_GetStringFromObj\fR.
.PP
Objects are allocated on the heap
and are referenced using a pointer to their \fBTcl_Obj\fR structure.
Objects are shared as much as possible.
This significantly reduces storage requirements
because some objects such as long lists are very large.
Also, most Tcl values are only read and never modified.







|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
an up-to-date string can always be obtained,
and any change to the object will be reflected in that string
when the object's string representation is fetched.
Because of this representation invalidation and regeneration,
it is dangerous for extension writers to access
\fBTcl_Obj\fR fields directly.
It is better to access Tcl_Obj information using
procedures like \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR.
.PP
Objects are allocated on the heap
and are referenced using a pointer to their \fBTcl_Obj\fR structure.
Objects are shared as much as possible.
This significantly reduces storage requirements
because some objects such as long lists are very large.
Also, most Tcl values are only read and never modified.
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
that may contain binary data with embedded null bytes.
\fIbytes\fR points to the first byte of the string representation.
The \fIlength\fR member gives the number of bytes.
The byte array must always have a null after the last byte,
at offset \fIlength\fR;
this allows string representations that do not contain nulls
to be treated as conventional null-terminated C strings.
C programs use \fBTcl_GetStringFromObj\fR to get
an object's string representation.
If \fIbytes\fR is NULL,
the string representation is invalid.
.PP
An object's type manages its internal representation.
The member \fItypePtr\fR points to the Tcl_ObjType structure
that describes the type.







|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
that may contain binary data with embedded null bytes.
\fIbytes\fR points to the first byte of the string representation.
The \fIlength\fR member gives the number of bytes.
The byte array must always have a null after the last byte,
at offset \fIlength\fR;
this allows string representations that do not contain nulls
to be treated as conventional null-terminated C strings.
C programs use \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR to get
an object's string representation.
If \fIbytes\fR is NULL,
the string representation is invalid.
.PP
An object's type manages its internal representation.
The member \fItypePtr\fR points to the Tcl_ObjType structure
that describes the type.
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
\fBTcl_IncrRefCount\fR and \fBTcl_IsShared\fR instead.
.PP
A key property of Tcl objects is that they hold two representations.
An object typically starts out containing only a string representation:
it is untyped and has a NULL \fItypePtr\fR.
An object containing an empty string or a copy of a specified string
is created using \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR respectively.
An object's string value is gotten with \fBTcl_GetStringFromObj\fR

and changed with \fBTcl_SetStringObj\fR.
If the object is later passed to a procedure like \fBTcl_GetIntFromObj\fR
that requires a specific internal representation,
the procedure will create one and set the object's \fItypePtr\fR.
The internal representation is computed from the string representation.
An object's two representations are duals of each other:
changes made to one are reflected in the other.
For example, \fBTcl_ListObjReplace\fR will modify an object's
internal representation and the next call to \fBTcl_GetStringFromObj\fR
will reflect that change.
.PP
Representations are recomputed lazily for efficiency.
A change to one representation made by a procedure
such as \fBTcl_ListObjReplace\fR is not reflected immediately
in the other representation.
Instead, the other representation is marked invalid
so that it is only regenerated if it is needed later.
Most C programmers never have to be concerned with how this is done
and simply use procedures such as \fBTcl_GetBooleanFromObj\fR or
\fBTcl_ListObjIndex\fR.
Programmers that implement their own object types
must check for invalid representations
and mark representations invalid when necessary.
The procedure \fBTcl_InvalidateStringRep\fR is used
to mark an object's string representation invalid and to
free any storage associated with the old string representation.
.PP
Objects usually remain one type over their life,
but occasionally an object must be converted from one type to another.
For example, a C program might build up a string in an object
with repeated calls to \fBTcl_StringObjAppend\fR,
and then call \fBTcl_ListObjIndex\fR to extract a list element from
the object.
The same object holding the same string value
can have several different internal representations
at different times.
Extension writers can also force an object to be converted from one type
to another using the \fBTcl_ConvertToType\fR procedure.







|
>









|




















|







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
\fBTcl_IncrRefCount\fR and \fBTcl_IsShared\fR instead.
.PP
A key property of Tcl objects is that they hold two representations.
An object typically starts out containing only a string representation:
it is untyped and has a NULL \fItypePtr\fR.
An object containing an empty string or a copy of a specified string
is created using \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR respectively.
An object's string value is gotten with
\fBTcl_GetStringFromObj\fR or \fBTcl_GetString\fR
and changed with \fBTcl_SetStringObj\fR.
If the object is later passed to a procedure like \fBTcl_GetIntFromObj\fR
that requires a specific internal representation,
the procedure will create one and set the object's \fItypePtr\fR.
The internal representation is computed from the string representation.
An object's two representations are duals of each other:
changes made to one are reflected in the other.
For example, \fBTcl_ListObjReplace\fR will modify an object's
internal representation and the next call to \fBTcl_GetStringFromObj\fR
or \fBTcl_GetString\fR will reflect that change.
.PP
Representations are recomputed lazily for efficiency.
A change to one representation made by a procedure
such as \fBTcl_ListObjReplace\fR is not reflected immediately
in the other representation.
Instead, the other representation is marked invalid
so that it is only regenerated if it is needed later.
Most C programmers never have to be concerned with how this is done
and simply use procedures such as \fBTcl_GetBooleanFromObj\fR or
\fBTcl_ListObjIndex\fR.
Programmers that implement their own object types
must check for invalid representations
and mark representations invalid when necessary.
The procedure \fBTcl_InvalidateStringRep\fR is used
to mark an object's string representation invalid and to
free any storage associated with the old string representation.
.PP
Objects usually remain one type over their life,
but occasionally an object must be converted from one type to another.
For example, a C program might build up a string in an object
with repeated calls to \fBTcl_AppendToObj\fR,
and then call \fBTcl_ListObjIndex\fR to extract a list element from
the object.
The same object holding the same string value
can have several different internal representations
at different times.
Extension writers can also force an object to be converted from one type
to another using the \fBTcl_ConvertToType\fR procedure.

Changes to doc/ObjectType.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) ObjectType.3 1.8 97/04/30 15:42:29
'\" 
.so man.macros
.TH Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType  \- manipulate Tcl object types
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: ObjectType.3,v 1.1.2.1 1998/09/24 23:58:25 stanton Exp $
'\" 
.so man.macros
.TH Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType  \- manipulate Tcl object types
.SH SYNOPSIS

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
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
'\"
'\" 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.
'\"
'\" SCCS: @(#) OpenFileChnl.3 1.40 97/09/29 11:22:49
.so man.macros
.TH Tcl_OpenFileChannel 3 8.0 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_Read, Tcl_Gets, Tcl_Write, Tcl_Flush, Tcl_Seek, Tcl_Tell, Tcl_Eof, Tcl_InputBlocked, Tcl_InputBuffered, Tcl_GetChannelOption, Tcl_SetChannelOption \- buffered I/O facilities using channels
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
typedef ... Tcl_Channel;
.sp
Tcl_Channel
\fBTcl_OpenFileChannel\fR(\fIinterp, fileName, mode, permissions\fR)
.sp
Tcl_Channel
\fBTcl_OpenCommandChannel\fR(\fIinterp, argc, argv, flags\fR)
.VS
.sp
Tcl_Channel
\fBTcl_MakeFileChannel\fR(\fIhandle, readOrWrite\fR)
.VE
.sp
Tcl_Channel
\fBTcl_GetChannel\fR(\fIinterp, channelName, modePtr\fR)
.sp
void
\fBTcl_RegisterChannel\fR(\fIinterp, channel\fR)
.sp
int
\fBTcl_UnregisterChannel\fR(\fIinterp, channel\fR)
.sp
int
\fBTcl_Close\fR(\fIinterp, channel\fR)
.sp

int
\fBTcl_Read\fR(\fIchannel, buf, toRead\fR)
.sp
int
\fBTcl_Gets\fR(\fIchannel, lineRead\fR)
.sp
int
\fBTcl_GetsObj\fR(\fIchannel, lineObjPtr\fR)
.sp
int









\fBTcl_Write\fR(\fIchannel, buf, toWrite\fR)

.sp
int
\fBTcl_Flush\fR(\fIchannel\fR)
.sp
int
\fBTcl_Seek\fR(\fIchannel, offset, seekMode\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
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) 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.1.2.2 1998/09/24 23:58:25 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
\fBTcl_OpenFileChannel\fR(\fIinterp, fileName, mode, permissions\fR)
.sp
Tcl_Channel
\fBTcl_OpenCommandChannel\fR(\fIinterp, argc, argv, flags\fR)
.VS 8.0
.sp
Tcl_Channel
\fBTcl_MakeFileChannel\fR(\fIhandle, readOrWrite\fR)
.VE
.sp
Tcl_Channel
\fBTcl_GetChannel\fR(\fIinterp, channelName, modePtr\fR)
.sp
void
\fBTcl_RegisterChannel\fR(\fIinterp, channel\fR)
.sp
int
\fBTcl_UnregisterChannel\fR(\fIinterp, channel\fR)
.sp
int
\fBTcl_Close\fR(\fIinterp, channel\fR)
.sp
.VS 8.1
int
\fBTcl_ReadChars\fR(\fIchannel, readObjPtr, charsToRead, appendFlag\fR)
.sp
int
\fBTcl_Read\fR(\fIchannel, byteBuf, bytesToRead\fR)
.sp
int
\fBTcl_GetsObj\fR(\fIchannel, lineObjPtr\fR)
.sp
int
\fBTcl_Gets\fR(\fIchannel, lineRead\fR)
.sp
int
\fBTcl_WriteObj\fR(\fIchannel, writeObjPtr\fR)
.sp
int
\fBTcl_WriteChars\fR(\fIchannel, charBuf, bytesToWrite\fR)
.sp
int
\fBTcl_Write\fR(\fIchannel, byteBuf, bytesToWrite\fR)
.VE
.sp
int
\fBTcl_Flush\fR(\fIchannel\fR)
.sp
int
\fBTcl_Seek\fR(\fIchannel, offset, seekMode\fR)
.sp
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
.SH ARGUMENTS
.AS Tcl_ChannelType newClientProcPtr in
.AP Tcl_Interp *interp in
Used for error reporting and to look up a channel registered in it.
.AP char *fileName in
The name of a local or network file.
.AP char *mode in
Specifies how the file is to be accessed.  May have any of the
values allowed for the \fImode\fR argument to the Tcl
\fBopen\fR command.
For \fBTcl_OpenCommandChannel\fR, may be NULL.
.AP int permissions in
POSIX-style permission flags such as 0644.
If a new file is created, these permissions will be set on the
created file.
.AP int argc in
The number of elements in \fIargv\fR.
.AP char **argv in
Arguments for constructing a command pipeline.
These values have the same meaning as the non-switch arguments
to the Tcl \fBexec\fR command.
.AP int flags in
Specifies the disposition of the stdio handles in pipeline: OR-ed
combination of \fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, \fBTCL_STDERR\fR,
and \fBTCL_ENFORCE_MODE\fR. If \fBTCL_STDIN\fR is set, stdin for
the first child in the pipe is the pipe channel, otherwise it is the same
as the standard input of the invoking process; likewise for
\fBTCL_STDOUT\fR and \fBTCL_STDERR\fR. If \fBTCL_ENFORCE_MODE\fR is not set,
then the pipe can redirect stdio handles to override the stdio handles for
which \fBTCL_STDIN\fR, \fBTCL_STDOUT\fR and \fBTCL_STDERR\fR have been set.
If it is set, then such redirections cause an error.
.VS
.AP ClientData handle in
Operating system specific handle for I/O to a file. For Unix this is a
file descriptor, for Windows it is a HANDLE.
.AP int readOrWrite in
OR-ed combination of \fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR to indicate
what operations are valid on \fIhandle\fR.


.VE
.AP int *modePtr out
Points at an integer variable that will receive an OR-ed combination of
\fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR denoting whether the channel is
open for reading and writing.
.AP Tcl_Channel channel in
A Tcl channel for input or output.  Must have been the return value
from a procedure such as \fBTcl_OpenFileChannel\fR.

.AP char *buf in
An array of bytes in which to store channel input, or from which
to read channel output.
.AP int len in
The length of the input or output.



.AP int atEnd in

If nonzero, store the input at the end of the input queue, otherwise store
it at the head of the input queue.

.AP int toRead in
The number of bytes to read from the channel.





.AP Tcl_DString *lineRead in
A pointer to a Tcl dynamic string in which to store the line read from the
channel.  Must have been initialized by the caller.  The line read
will be appended to any data already in the dynamic string.
.AP Tcl_Obj *linePtrObj in
A pointer to a Tcl object in which to store the line read from the



channel.  The line read will be appended to the current value of the
object. 
.AP int toWrite in

The number of bytes to read from \fIbuf\fR and output to the channel.

.AP int offset in
How far to move the access point in the channel at which the next input or
output operation will be applied, measured in bytes from the position
given by \fIseekMode\fR.  May be either positive or negative.
.AP int seekMode in
Relative to which point to seek; used with \fIoffset\fR to calculate the new
access point for the channel. Legal values are \fBSEEK_SET\fR,







|
|
<
|

|
|
<



|
<
|


|
|
|
|
|
|
|
|
|






>
>








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

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







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
.SH ARGUMENTS
.AS Tcl_ChannelType newClientProcPtr in
.AP Tcl_Interp *interp in
Used for error reporting and to look up a channel registered in it.
.AP char *fileName in
The name of a local or network file.
.AP char *mode in
Specifies how the file is to be accessed.  May have any of the values
allowed for the \fImode\fR argument to the Tcl \fBopen\fR command.  For

\fBTcl_OpenCommandChannel\fR, may be NULL.
.AP int permissions in
POSIX-style permission flags such as 0644.  If a new file is created, these
permissions will be set on the created file.

.AP int argc in
The number of elements in \fIargv\fR.
.AP char **argv in
Arguments for constructing a command pipeline.  These values have the same

meaning as the non-switch arguments to the Tcl \fBexec\fR command.
.AP int flags in
Specifies the disposition of the stdio handles in pipeline: OR-ed
combination of \fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, \fBTCL_STDERR\fR, and
\fBTCL_ENFORCE_MODE\fR. If \fBTCL_STDIN\fR is set, stdin for the first child
in the pipe is the pipe channel, otherwise it is the same as the standard
input of the invoking process; likewise for \fBTCL_STDOUT\fR and
\fBTCL_STDERR\fR. If \fBTCL_ENFORCE_MODE\fR is not set, then the pipe can
redirect stdio handles to override the stdio handles for which
\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR and \fBTCL_STDERR\fR have been set.  If it
is set, then such redirections cause an error.
.VS 8.0
.AP ClientData handle in
Operating system specific handle for I/O to a file. For Unix this is a
file descriptor, for Windows it is a HANDLE.
.AP int readOrWrite in
OR-ed combination of \fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR to indicate
what operations are valid on \fIhandle\fR.
.AP char *channelName in
The name of the channel. 
.VE
.AP int *modePtr out
Points at an integer variable that will receive an OR-ed combination of
\fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR denoting whether the channel is
open for reading and writing.
.AP Tcl_Channel channel in
A Tcl channel for input or output.  Must have been the return value
from a procedure such as \fBTcl_OpenFileChannel\fR.
.VS 8.1 br
.AP Tcl_Obj *readObjPtr in/out
A pointer to a Tcl Object in which to store the characters read from the
channel.
.AP int charsToRead in

The number of characters to read from the channel.  If the channel's encoding 
is \fBbinary\fR, this is equivalent to the number of bytes to read from the 
channel.
.AP int appendFlag in
If non-zero, data read from the channel will be appended to the object.
Otherwise, the data will replace the existing contents of the object.
.AP char *readBuf out
A buffer in which to store the bytes read from the channel.
.AP int bytesToRead in
The number of bytes to read from the channel.  The buffer \fIreadBuf\fR must
be large enough to hold this many bytes.
.AP Tcl_Obj *lineObjPtr in/out
A pointer to a Tcl object in which to store the line read from the
channel.  The line read will be appended to the current value of the
object. 
.AP Tcl_DString *lineRead in/out
A pointer to a Tcl dynamic string in which to store the line read from the
channel.  Must have been initialized by the caller.  The line read will be
appended to any data already in the dynamic string.
.AP Tcl_Obj *writeObjPtr in
A pointer to a Tcl Object whose contents will be output to the channel.
.AP "CONST char" *charBuf in
A buffer containing the characters to output to the channel.
.AP char *byteBuf in
A buffer containing the bytes to output to the channel.

.AP int bytesToWrite in
The number of bytes to consume from \fIcharBuf\fR or \fIbyteBuf\fR and
output to the channel.
.VE
.AP int offset in
How far to move the access point in the channel at which the next input or
output operation will be applied, measured in bytes from the position
given by \fIseekMode\fR.  May be either positive or negative.
.AP int seekMode in
Relative to which point to seek; used with \fIoffset\fR to calculate the new
access point for the channel. Legal values are \fBSEEK_SET\fR,
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
The Tcl channel mechanism provides a device-independent and
platform-independent mechanism for performing buffered input
and output operations on a variety of file, socket, and device
types.
The channel mechanism is extensible to new channel types, by
providing a low level channel driver for the new type; the channel driver
interface is described in the manual entry for \fBTcl_CreateChannel\fR. The
channel mechanism provides a buffering scheme modelled after
Unix's standard I/O, and it also allows for nonblocking I/O on
channels.
.PP
The procedures described in this manual entry comprise the C APIs of the
generic layer of the channel architecture. For a description of the channel
driver architecture and how to implement channel drivers for new types of
channels, see the manual entry for \fBTcl_CreateChannel\fR.

.SH TCL_OPENFILECHANNEL
.PP
\fBTcl_OpenFileChannel\fR opens a file specified by \fIfileName\fR and
returns a channel handle that can be used to perform input and output on
the file. This API is modelled after the \fBfopen\fR procedure of
the Unix standard I/O library.
The syntax and meaning of all arguments is similar to those
given in the Tcl \fBopen\fR command when opening a file.
If an error occurs while opening the channel, \fBTcl_OpenFileChannel\fR
returns NULL and records a POSIX error code that can be
retrieved with \fBTcl_GetErrno\fR.
In addition, if \fIinterp\fR is non-NULL, \fBTcl_OpenFileChannel\fR
leaves an error message in \fIinterp->result\fR after any error.
.PP
The newly created channel is not registered in the supplied interpreter; to
register it, use \fBTcl_RegisterChannel\fR, described below.
If one of the standard channels, \fBstdin, stdout\fR or \fBstderr\fR was
previously closed, the act of creating the new channel also assigns it as a
replacement for the standard channel.








|












|







|







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
The Tcl channel mechanism provides a device-independent and
platform-independent mechanism for performing buffered input
and output operations on a variety of file, socket, and device
types.
The channel mechanism is extensible to new channel types, by
providing a low level channel driver for the new type; the channel driver
interface is described in the manual entry for \fBTcl_CreateChannel\fR. The
channel mechanism provides a buffering scheme modeled after
Unix's standard I/O, and it also allows for nonblocking I/O on
channels.
.PP
The procedures described in this manual entry comprise the C APIs of the
generic layer of the channel architecture. For a description of the channel
driver architecture and how to implement channel drivers for new types of
channels, see the manual entry for \fBTcl_CreateChannel\fR.

.SH TCL_OPENFILECHANNEL
.PP
\fBTcl_OpenFileChannel\fR opens a file specified by \fIfileName\fR and
returns a channel handle that can be used to perform input and output on
the file. This API is modeled after the \fBfopen\fR procedure of
the Unix standard I/O library.
The syntax and meaning of all arguments is similar to those
given in the Tcl \fBopen\fR command when opening a file.
If an error occurs while opening the channel, \fBTcl_OpenFileChannel\fR
returns NULL and records a POSIX error code that can be
retrieved with \fBTcl_GetErrno\fR.
In addition, if \fIinterp\fR is non-NULL, \fBTcl_OpenFileChannel\fR
leaves an error message in \fIinterp\fR's result after any error.
.PP
The newly created channel is not registered in the supplied interpreter; to
register it, use \fBTcl_RegisterChannel\fR, described below.
If one of the standard channels, \fBstdin, stdout\fR or \fBstderr\fR was
previously closed, the act of creating the new channel also assigns it as a
replacement for the standard channel.

306
307
308
309
310
311
312
313
314

315
316
317
318

319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345
346
347
348
349




















350
351
352
353



354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

376
377
378
379

380
381
382
383
384
385
386
387
388
389
390







391
392
393
394
395
396
397
398
399






















400
401
402
403
404
405
406
POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
If the channel is being closed synchronously and an error occurs during
closing of the channel and \fIinterp\fR is not NULL, an error message is
left in \fIinterp->result\fR.
.PP
Note: it is not safe to call \fBTcl_Close\fR on a channel that has been
registered using \fBTcl_RegisterChannel\fR; see the documentation for
\fBTcl_RegisterChannel\fR, above, for details. If the channel has ever been
given as the \fBchan\fR argument in a call to \fBTcl_RegisterChannel\fR,

you should instead use \fBTcl_UnregisterChannel\fR, which will internally
call \fBTcl_Close\fR when all calls to \fBTcl_RegisterChannel\fR have been
matched by corresponding calls to \fBTcl_UnregisterChannel\fR.


.SH TCL_READ
.PP
\fBTcl_Read\fR consumes up to \fItoRead\fR bytes of data from
\fIchannel\fR and stores it at \fIbuf\fR.
The return value of \fBTcl_Read\fR is the number of characters written
at \fIbuf\fR.
The buffer produced by \fBTcl_Read\fR is not NULL terminated. Its contents
are valid from the zeroth position up to and excluding the position
indicated by the return value.
If an error occurs, the return value is -1 and \fBTcl_Read\fR records
a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
.PP
The return value may be smaller than the value of \fItoRead\fR, indicating
that less data than requested was available, also called a \fIshort
read\fR.
In blocking mode, this can only happen on an end-of-file.
In nonblocking mode, a short read can also occur if there is not
enough input currently available:  \fBTcl_Read\fR returns a short

count rather than waiting for more data.
.PP
If the channel is in blocking mode, a return value of zero indicates an end
of file condition. If the channel is in nonblocking mode, a return value of
zero indicates either that no input is currently available or an end of
file condition. Use \fBTcl_Eof\fR and \fBTcl_InputBlocked\fR
to tell which of these conditions actually occurred.
.PP
\fBTcl_Read\fR translates platform-specific end-of-line representations
into the canonical \fB\en\fR internal representation according to the
current end-of-line recognition mode. End-of-line recognition and the
various platform-specific modes are described in the manual entry for the
Tcl \fBfconfigure\fR command.





















.SH TCL_GETS AND TCL_GETSOBJ
.PP
\fBTcl_Gets\fR reads a line of input from a channel and appends all of



the characters of the line except for the terminating end-of-line character(s)
to the dynamic string given by \fIdsPtr\fR.
The end-of-line character(s) are read and discarded.
.PP
If a line was successfully read, the return value is greater than or
equal to zero, and it indicates the number of characters stored
in the dynamic string.
If an error occurs, \fBTcl_Gets\fR returns -1 and records a POSIX error
code that can be retrieved with \fBTcl_GetErrno\fR.
\fBTcl_Gets\fR also returns -1 if the end of the file is reached;
the \fBTcl_Eof\fR procedure can be used to distinguish an error
from an end-of-file condition.
.PP
If the channel is in nonblocking mode, the return value can also
be -1 if no data was available or the data that was available
did not contain an end-of-line character.
When -1 is returned, the \fBTcl_InputBlocked\fR procedure may be
invoked to determine if the channel is blocked because of input
unavailability.
.PP
\fBTcl_GetsObj\fR is the same as \fBTcl_Gets\fR except the resulting
characters are appended to a Tcl object \fBlineObjPtr\fR rather than a

dynamic string.
.SH TCL_WRITE
.PP
\fBTcl_Write\fR accepts \fItoWrite\fR bytes of data at \fIbuf\fR for output

on \fIchannel\fR. This data may not appear on the output device
immediately. If the data should appear immediately, call \fBTcl_Flush\fR
after the call to \fBTcl_Write\fR, or set the \fB-buffering\fR option on
the channel to \fBnone\fR. If you wish the data to appear as soon as an end
of line is accepted for output, set the \fB\-buffering\fR option on the
channel to \fBline\fR mode.
.PP
The \fItoWrite\fR argument specifies how many bytes of data are provided in
the \fIbuf\fR argument. If it is negative, \fBTcl_Write\fR expects the data
to be NULL terminated and it outputs everything up to the NULL.
.PP







The return value of \fBTcl_Write\fR is a count of how many
characters were accepted for output to the channel. This is either equal to
\fItoWrite\fR or -1 to indicate that an error occurred.
If an error occurs, \fBTcl_Write\fR also records a POSIX error code
that may be retrieved with \fBTcl_GetErrno\fR.
.PP
Newline characters in the output data are translated to platform-specific
end-of-line sequences according to the \fB\-translation\fR option for
the channel.























.SH TCL_FLUSH
.PP
\fBTcl_Flush\fR causes all of the buffered output data for \fIchannel\fR
to be written to its underlying file or device as soon as possible.
If the channel is in blocking mode, the call does not return until
all the buffered data has been sent to the channel or some error occurred.







|
|
>
|
|
|

>
|

|
|
|
<
|
<
|
|
|

|
|
<
|
|
<
>
|

|
|
|
|
|

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

|

|
>
>
>
|
|
|

|
|
<
|
|
|
<
|

|
|
<
|
|
|

|
|
>
|
|

|
>
|
<
<
<
<
<
<
<
|


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


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







330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

350

351
352
353
354
355
356

357
358

359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408

409
410
411
412

413
414
415
416
417
418
419
420
421
422
423
424
425







426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
If the channel is being closed synchronously and an error occurs during
closing of the channel and \fIinterp\fR is not NULL, an error message is
left in \fIinterp->result\fR.
.PP
Note: it is not safe to call \fBTcl_Close\fR on a channel that has been
registered using \fBTcl_RegisterChannel\fR; see the documentation for
\fBTcl_RegisterChannel\fR, above, for details. If the channel has ever
been given as the \fBchan\fR argument in a call to
\fBTcl_RegisterChannel\fR, you should instead use
\fBTcl_UnregisterChannel\fR, which will internally call \fBTcl_Close\fR
when all calls to \fBTcl_RegisterChannel\fR have been matched by
corresponding calls to \fBTcl_UnregisterChannel\fR.

.VS 8.1 br
.SH TCL_READCHARS AND TCL_READ
.PP
\fBTcl_ReadChars\fR consumes bytes from \fIchannel\fR, converting the bytes
to UTF-8 based on the channel's encoding and storing the produced data in 
\fIreadObjPtr\fR's string representation.  The return value of

\fBTcl_ReadChars\fR is the number of characters, up to \fIcharsToRead\fR,

that were stored in \fIobjPtr\fR.  If an error occurs while reading, the
return value is \-1 and \fBTcl_ReadChars\fR records a POSIX error code that
can be retrieved with \fBTcl_GetErrno\fR.
.PP
The return value may be smaller than the value to read, indicating that less
data than requested was available.  This is called a \fIshort read\fR.  In

blocking mode, this can only happen on an end-of-file.  In nonblocking mode,
a short read can also occur if there is not enough input currently

available:  \fBTcl_ReadChars\fR returns a short count rather than waiting
for more data.
.PP
If the channel is in blocking mode, a return value of zero indicates an
end-of-file condition.  If the channel is in nonblocking mode, a return
value of zero indicates either that no input is currently available or an
end-of-file condition.  Use \fBTcl_Eof\fR and \fBTcl_InputBlocked\fR to tell
which of these conditions actually occurred.
.PP
\fBTcl_ReadChars\fR translates the various end-of-line representations into
the canonical \fB\en\fR internal representation according to the current
end-of-line recognition mode.  End-of-line recognition and the various
platform-specific modes are described in the manual entry for the Tcl
\fBfconfigure\fR command.
.PP
As a performance optimization, when reading from a channel with the encoding
\fBbinary\fR, the bytes are not converted to UTF-8 as they are read.
Instead, they are stored in \fIreadObjPtr\fR's internal representation as a
byte-array object.  The string representation of this object will only be
constructed if it is needed (e.g., because of a call to
\fBTcl_GetStringFromObj\fR).  In this way, byte-oriented data can be read
from a channel, manipulated by calling \fBTcl_GetByteArrayFromObj\fR and
related functions, and then written to a channel without the expense of ever
converting to or from UTF-8.
.PP
\fBTcl_Read\fR is similar to \fBTcl_ReadChars\fR, except that it doesn't do
encoding conversions, regardless of the channel's encoding.  It is deprecated
and exists for backwards compatibility with non-internationalized Tcl
extensions.  It consumes bytes from \fIchannel\fR and stores them in
\fIbuf\fR, performing end-of-line translations on the way.  The return value
of \fBTcl_Read\fR is the number of bytes, up to \fItoRead\fR, written in
\fIbuf\fR.  The buffer produced by \fBTcl_Read\fR is not NULL terminated.
Its contents are valid from the zeroth position up to and excluding the
position indicated by the return value.  

.SH TCL_GETSOBJ AND TCL_GETS
.PP
\fBTcl_GetsObj\fR consumes bytes from \fIchannel\fR, converting the bytes to
UTF-8 based on the channel's encoding, until a full line of input has been
seen.  If the channel's encoding is \fBbinary\fR, each byte read from the
channel is treated as an individual Unicode character.  All of the
characters of the line except for the terminating end-of-line character(s)
are appended to \fIlineObjPtr\fR's string representation.  The end-of-line
character(s) are read and discarded.
.PP
If a line was successfully read, the return value is greater than or equal
to zero and indicates the number of bytes stored in \fIlineObjPtr\fR.  If an

error occurs, \fBTcl_GetsObj\fR returns \-1 and records a POSIX error code
that can be retrieved with \fBTcl_GetErrno\fR.  \fBTcl_GetsObj\fR also
returns \-1 if the end of the file is reached; the \fBTcl_Eof\fR procedure

can be used to distinguish an error from an end-of-file condition.
.PP
If the channel is in nonblocking mode, the return value can also be \-1 if
no data was available or the data that was available did not contain an

end-of-line character.  When \-1 is returned, the \fBTcl_InputBlocked\fR
procedure may be invoked to determine if the channel is blocked because
of input unavailability.
.PP
\fBTcl_Gets\fR is the same as \fBTcl_GetsObj\fR except the resulting
characters are appended to the appended to the dynamic string given by
\fIdsPtr\fR rather than a Tcl object.

.SH TCL_WRITECHARS, TCL_WRITEOBJ, AND TCL_WRITE
.PP
\fBTcl_WriteChars\fR accepts \fIbytesToWrite\fR bytes of character data at
\fIcharBuf\fR.  The UTF-8 characters in the buffer are converted to the
channel's encoding and queued for output to \fIchannel\fR.  If







\fIbytesToWrite\fR is negative, \fBTcl_WriteChars\fR expects \fIcharBuf\fR
to be NULL terminated and it outputs everything up to the NULL.
.PP
Data queued for output may not appear on the output device immediately, due
to internal buffering.  If the data should appear immediately, call
\fBTcl_Flush\fR after the call to \fBTcl_WriteChars\fR, or set the 
\fB\-buffering\fR option on the channel to \fBnone\fR.  If you wish the data
to appear as soon as a complete line is accepted for output, set the
\fB\-buffering\fR option on the channel to \fBline\fR mode.
.PP
The return value of \fBTcl_WriteChars\fR is a count of how many bytes were
accepted for output to the channel.  This is either greater than zero to
indicate success or \-1 to indicate that an error occurred.  If an error
occurs, \fBTcl_WriteChars\fR records a POSIX error code that may be
retrieved with \fBTcl_GetErrno\fR.
.PP
Newline characters in the output data are translated to platform-specific
end-of-line sequences according to the \fB\-translation\fR option for the
channel.  This is done even if the channel has no encoding.
.PP
\fBTcl_WriteObj\fR is similar to \fBTcl_WriteChars\fR except it
accepts a Tcl object whose contents will be output to the channel.  The
UTF-8 characters in \fIwriteObjPtr\fR's string representation are converted
to the channel's encoding and queued for output to \fIchannel\fR.  
As a performance optimization, when writing to a channel with the encoding
\fBbinary\fR, UTF-8 characters are not converted as they are written.
Instead, the bytes in \fIwriteObjPtr\fR's internal representation as a
byte-array object are written to the channel.  The byte-array representation
of the object will be constructed if it is needed.  In this way,
byte-oriented data can be read from a channel, manipulated by calling
\fBTcl_GetByteArrayFromObj\fR and related functions, and then written to a
channel without the expense of ever converting to or from UTF-8.
.PP
\fBTcl_Write\fR is similar to \fBTcl_WriteChars\fR except that it doesn't do
encoding conversions, regardless of the channel's encoding.  It is
deprecated and exists for backwards compatibility with non-internationalized
Tcl extensions.  It accepts \fIbytesToWrite\fR bytes of data at
\fIbyteBuf\fR and queues them for output to \fIchannel\fR.  If
\fIbytesToWrite\fR is negative, \fBTcl_Write\fR expects \fIbyteBuf\fR to be
NULL terminated and it outputs everything up to the NULL.
.VE

.SH TCL_FLUSH
.PP
\fBTcl_Flush\fR causes all of the buffered output data for \fIchannel\fR
to be written to its underlying file or device as soon as possible.
If the channel is in blocking mode, the call does not return until
all the buffered data has been sent to the channel or some error occurred.
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
.SH TCL_SEEK
.PP
\fBTcl_Seek\fR moves the access point in \fIchannel\fR where subsequent
data will be read or written. Buffered output is flushed to the channel and
buffered input is discarded, prior to the seek operation.
.PP
\fBTcl_Seek\fR normally returns the new access point.
If an error occurs, \fBTcl_Seek\fR returns -1 and records a POSIX error
code that can be retrieved with \fBTcl_GetErrno\fR.
After an error, the access point may or may not have been moved.

.SH TCL_TELL
.PP
\fBTcl_Tell\fR returns the current access point for a channel. The returned
value is -1 if the channel does not support seeking.

.SH TCL_GETCHANNELOPTION
.PP
\fBTcl_GetChannelOption\fR retrieves, in \fIdsPtr\fR, the value of one of
the options currently in effect for a channel, or a list of all options and
their values.  The \fIchannel\fR argument identifies the channel for which
to query an option or retrieve all options and their values.







|






|







482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
.SH TCL_SEEK
.PP
\fBTcl_Seek\fR moves the access point in \fIchannel\fR where subsequent
data will be read or written. Buffered output is flushed to the channel and
buffered input is discarded, prior to the seek operation.
.PP
\fBTcl_Seek\fR normally returns the new access point.
If an error occurs, \fBTcl_Seek\fR returns \-1 and records a POSIX error
code that can be retrieved with \fBTcl_GetErrno\fR.
After an error, the access point may or may not have been moved.

.SH TCL_TELL
.PP
\fBTcl_Tell\fR returns the current access point for a channel. The returned
value is \-1 if the channel does not support seeking.

.SH TCL_GETCHANNELOPTION
.PP
\fBTcl_GetChannelOption\fR retrieves, in \fIdsPtr\fR, the value of one of
the options currently in effect for a channel, or a list of all options and
their values.  The \fIchannel\fR argument identifies the channel for which
to query an option or retrieve all options and their values.
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

.SH TCL_INPUTBUFFERED
.PP
\fBTcl_InputBuffered\fR returns the number of bytes of input currently
buffered in the internal buffers for a channel. If the channel is not open
for reading, this function always returns zero.

.VS
.SH "PLATFORM ISSUES"
.PP
The handles returned from \fBTcl_GetChannelHandle\fR depend on the
platform and the channel type.  On Unix platforms, the handle is
always a Unix file descriptor as returned from the \fBopen\fR system
call.  On Windows platforms, the handle is a file \fBHANDLE\fR when
the channel was created with \fBTcl_OpenFileChannel\fR,







|







540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

.SH TCL_INPUTBUFFERED
.PP
\fBTcl_InputBuffered\fR returns the number of bytes of input currently
buffered in the internal buffers for a channel. If the channel is not open
for reading, this function always returns zero.

.VS 8.0
.SH "PLATFORM ISSUES"
.PP
The handles returned from \fBTcl_GetChannelHandle\fR depend on the
platform and the channel type.  On Unix platforms, the handle is
always a Unix file descriptor as returned from the \fBopen\fR system
call.  On Windows platforms, the handle is a file \fBHANDLE\fR when
the channel was created with \fBTcl_OpenFileChannel\fR,

Changes to doc/OpenTcp.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1996-7 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\" SCCS: @(#) OpenTcp.3 1.19 97/06/25 14:44:00
.so man.macros
.TH Tcl_OpenTcpClient 3 8.0 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_OpenTcpClient, Tcl_MakeTcpClientChannel, Tcl_OpenTcpServer \- procedures to open channels using TCP sockets
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1996-7 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: OpenTcp.3,v 1.1.2.1 1998/09/24 23:58:25 stanton Exp $
.so man.macros
.TH Tcl_OpenTcpClient 3 8.0 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_OpenTcpClient, Tcl_MakeTcpClientChannel, Tcl_OpenTcpServer \- procedures to open channels using TCP sockets
.SH SYNOPSIS

Added doc/ParseCmd.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
'\"
'\" 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: ParseCmd.3,v 1.1.2.2 1998/10/21 20:21:31 stanton Exp $
'\" 
.so man.macros
.TH Tcl_ParseCommand 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ParseCommand, Tcl_ParseExpr, Tcl_ParseBraces, Tcl_ParseQuotedString, Tcl_ParseVarName, Tcl_FreeParse, Tcl_EvalTokens \- parse Tcl scripts and expressions
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
int
\fBTcl_ParseCommand\fR(\fIinterp, string, numBytes, nested, parsePtr\fR)
.sp
int
\fBTcl_ParseExpr\fR(\fIinterp, string, numBytes, parsePtr\fR)
.sp
int
\fBTcl_ParseBraces\fR(\fIinterp, string, numBytes, parsePtr, append, termPtr\fR)
.sp
int
\fBTcl_ParseQuotedString\fR(\fIinterp, string, numBytes, parsePtr, append, termPtr\fR)
.sp
int
\fBTcl_ParseVarName\fR(\fIinterp, string, numBytes, parsePtr, append\fR)
.sp
\fBTcl_FreeParse\fR(\fIusedParsePtr\fR)
.sp
Tcl_Obj *
\fBTcl_EvalTokens\fR(\fIinterp, tokenPtr, numTokens\fR)
.SH ARGUMENTS
.AS Tcl_Interp *usedParsePtr
.AP Tcl_Interp *interp out
For procedures other than \fBTcl_FreeParse\fR and \fBTcl_EvalTokens\fR,
used only for error reporting;
if NULL, then no error messages are left after errors.
For \fBTcl_EvalTokens\fR, determines the context for evaluating the
script and also is used for error reporting; must not be NULL.
.AP char *string in
Pointer to first character in string to parse.
.AP int numBytes in
Number of bytes in \fIstring\fR, not including any terminating null
character.  If less than 0 then the script consists of all characters
in \fIstring\fR up to the first null character.
.AP int nested in
Non-zero means that the script is part of a command substitution so an
unquoted close bracket should be treated as a command terminator.  If zero,
close brackets have no special meaning. 
.AP int append in
Non-zero means that \fI*parsePtr\fR already contains valid tokens; the new
tokens should be appended to those already present.  Zero means that
\fI*parsePtr\fR is uninitialized; any information in it is ignored.
This argument is normally 0.
.AP Tcl_Parse *parsePtr out
Points to structure to fill in with information about the parsed
command, expression, variable name, etc.
Any previous information in this structure
is ignored, unless \fIappend\fR is non-zero in a call to
\fBTcl_ParseBraces\fR, \fBTcl_ParseQuotedString\fR,
or \fBTcl_ParseVarName\fR.
.AP char **termPtr out
If not NULL, points to a location where
\fBTcl_ParseBraces\fR and \fBTcl_ParseQuotedString\fR
will store a pointer to the character
just after the terminating close-brace or close-quote (respectively)
if the parse was successful.
.AP Tcl_Parse *usedParsePtr in
Points to structure that was filled in by a previous call to
\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseVarName\fR, etc.
.BE

.SH DESCRIPTION
.PP
These procedures parse Tcl commands or portions of Tcl commands such as
expressions or references to variables.
Each procedure takes a pointer to a script (or portion thereof)
and fills in the structure pointed to by \fIparsePtr\fR
with a collection of tokens describing the information that was parsed.
The procedures normally return \fBTCL_OK\fR.
However, if an error occurs then they return \fBTCL_ERROR\fR,
leave an error message in \fIinterp's\fR result
(if \fIinterp\fR is not NULL),
and leave nothing in \fIparsePtr\fR.
.PP
\fBTcl_ParseCommand\fR is a procedure that parses Tcl
scripts.  Given a pointer to a script, it
parses the first command from the script.  If the command was parsed
successfully, \fBTcl_ParseCommand\fR returns \fBTCL_OK\fR and fills in the
structure pointed to by \fIparsePtr\fR with information about the
structure of the command (see below for details).
If an error occurred in parsing the command then
\fBTCL_ERROR\fR is returned, an error message is left in \fIinterp\fR's
result, and no information is left at \fI*parsePtr\fR.
.PP
\fBTcl_ParseExpr\fR parses Tcl expressions.
Given a pointer to a script containing an expression,
\fBTcl_ParseCommand\fR parses the expression.
If the expression was parsed successfully,
\fBTcl_ParseExpr\fR returns \fBTCL_OK\fR and fills in the
structure pointed to by \fIparsePtr\fR with information about the
structure of the expression (see below for details).
If an error occurred in parsing the command then
\fBTCL_ERROR\fR is returned, an error message is left in \fIinterp\fR's
result, and no information is left at \fI*parsePtr\fR.
.PP
\fBTcl_ParseBraces\fR parses a string or command argument
enclosed in braces such as
\fB{hello}\fR or \fB{string \\t with \\t tabs}\fR
from the beginning of its argument \fIstring\fR.
The first character of \fIstring\fR must be \fB{\fR. 
If the braced string was parsed successfully,
\fBTcl_ParseBraces\fR returns \fBTCL_OK\fR,
fills in the structure pointed to by \fIparsePtr\fR
with information about the structure of the string
(see below for details),
and stores a pointer to the character just after the terminating \fB}\fR
in the location given by \fI*termPtr\fR.
If an error occurrs while parsing the string
then \fBTCL_ERROR\fR is returned,
an error message is left in \fIinterp\fR's result,
and no information is left at \fI*parsePtr\fR or \fI*termPtr\fR.
.PP
\fBTcl_ParseQuotedString\fR parses a double-quoted string such as
\fB"sum is [expr $a+$b]"\fR
from the beginning of the argument \fIstring\fR.
The first character of \fIstring\fR must be \fB"\fR. 
If the double-quoted string was parsed successfully,
\fBTcl_ParseQuotedString\fR returns \fBTCL_OK\fR,
fills in the structure pointed to by \fIparsePtr\fR
with information about the structure of the string
(see below for details),
and stores a pointer to the character just after the terminating \fB"\fR
in the location given by \fI*termPtr\fR.
If an error occurrs while parsing the string
then \fBTCL_ERROR\fR is returned,
an error message is left in \fIinterp\fR's result,
and no information is left at \fI*parsePtr\fR or \fI*termPtr\fR.
.PP
\fBTcl_ParseVarName\fR parses a Tcl variable reference such as
\fB$abc\fR or \fB$x([expr $index + 1])\fR from the beginning of its
\fIstring\fR argument.
The first character of \fIstring\fR must be \fB$\fR. 
If a variable name was parsed successfully, \fBTcl_ParseVarName\fR
returns \fBTCL_OK\fR and fills in the structure pointed to by
\fIparsePtr\fR with information about the structure of the variable name
(see below for details).  If an error
occurrs while parsing the command then \fBTCL_ERROR\fR is returned, an
error message is left in \fIinterp\fR's result (if \fIinterp\fR isn't
NULL), and no information is left at \fI*parsePtr\fR.
.PP
The information left at \fI*parsePtr\fR
by \fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR
may include dynamically allocated memory.
If these five parsing procedures return \fBTCL_OK\fR
then the caller must invoke \fBTcl_FreeParse\fR to release
the storage at \fI*parsePtr\fR.
These procedures ignore any existing information in
\fI*parsePtr\fR (unless \fIappend\fR is non-zero),
so if repeated calls are being made to any of them
then \fBTcl_FreeParse\fR must be invoked once after each call.
.PP
\fBTcl_EvalTokens\fR evaluates a sequence of parse tokens from a Tcl_Parse
structure.  The tokens typically consist
of all the tokens in a word or all the tokens that make up the index for
a reference to an array variable.  \fBTcl_EvalTokens\fR performs the
substitutions requested by the tokens, concatenates the
resulting values, and returns the result in a new Tcl_Obj.  The
reference count of the object returned as result has been
incremented, so the caller must
invoke \fBTcl_DecrRefCount\fR when it is finished with the object.
If an error occurs while evaluating the tokens (such as a reference to
a non-existent variable) then the return value is NULL and an error
message is left in \fIinterp\fR's result.

.SH  TCL_PARSE STRUCTURE
.PP
\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR
return parse information in two data structures, Tcl_Parse and Tcl_Token:
.CS
typedef struct Tcl_Parse {
	char *\fIcommentStart\fR;
	int \fIcommentSize\fR;
	char *\fIcommandStart\fR;
	int \fIcommandSize\fR;
	int \fInumWords\fR;
	Tcl_Token *\fItokenPtr\fR;
	int \fInumTokens\fR;
	...
} Tcl_Parse;

typedef struct Tcl_Token {
    int \fItype\fR;
    char *\fIstart\fR;
    int \fIsize\fR;
    int \fInumComponents\fR;
} Tcl_Token;
.CE
.PP
The first five fields of a Tcl_Parse structure
are filled in only by \fBTcl_ParseCommand\fR.
These fields are not used by the other parsing procedures.
.PP
\fBTcl_ParseCommand\fR fills in a Tcl_Parse structure
with information that describes one Tcl command and any comments that
precede the command.
If there are comments,
the \fIcommentStart\fR field points to the \fB#\fR character that begins
the first comment and \fIcommentSize\fR indicates the number of bytes
in all of the comments preceding the command, including the newline
character that terminates the last comment.
If the command is not preceded by any comments, \fIcommentSize\fR is 0.
\fBTcl_ParseCommand\fR also sets the \fIcommandStart\fR field
to point to the first character of the first
word in the command (skipping any comments and leading space) and 
\fIcommandSize\fR gives the total number of bytes in the command,
including the character pointed to by \fIcommandStart\fR up to and
including the newline, close bracket, or semicolon character that
terminates the command.  The \fInumWords\fR field gives the
total number of words in the command.
.PP
All parsing procedures set the remaining fields,
\fItokenPtr\fR and \fInumTokens\fR.
The \fItokenPtr\fR field points to the first in an array of Tcl_Token
structures that describe the components of the entity being parsed.
The \fInumTokens\fR field gives the total number of tokens
present in the array.
Each token contains four fields.
The \fItype\fR field selects one of several token types
that are described below.  The \fIstart\fR field
points to the first character in the token and the \fIsize\fR field
gives the total number of characters in the token.  Some token types,
such as \fBTCL_TOKEN_WORD\fR and \fBTCL_TOKEN_VARIABLE\fR, consist of
several component tokens, which immediately follow the parent token;
the \fInumComponents\fR field describes how many of these there are.
The \fItype\fR field has one of the following values:
.TP 20
\fBTCL_TOKEN_WORD\fR
This token ordinarily describes one word of a command
but it may also describe a quoted or braced string in an expression.
The token describes a component of the script that is
the result of concatenating together a sequence of subcomponents,
each described by a separate subtoken.
The token starts with the first non-blank
character of the component (which may be a double-quote or open brace)
and includes all characters in the component up to but not including the
space, semicolon, close bracket, close quote, or close brace that
terminates the component.  The \fInumComponents\fR field counts the total
number of sub-tokens that make up the word, including sub-tokens
of \fBTCL_TOKEN_VARIABLE\fR and \fBTCL_TOKEN_BS\fR tokens.
.TP
\fBTCL_TOKEN_SIMPLE_WORD\fR
This token has the same meaning as \fBTCL_TOKEN_WORD\fR, except that
the word is guaranteed to consist of a single \fBTCL_TOKEN_TEXT\fR
sub-token.  The \fInumComponents\fR field is always 1.
.TP
\fBTCL_TOKEN_TEXT\fR
The token describes a range of literal text that is part of a word.
The \fInumComponents\fR field is always 0.
.TP
\fBTCL_TOKEN_BS\fR
The token describes a backslash sequence such as \fB\en\fR or \fB\e0xa3\fR.
The \fInumComponents\fR field is always 0.
.TP
\fBTCL_TOKEN_COMMAND\fR
The token describes a command whose result result must be substituted into
the word.  The token includes the square brackets that surround the
command.  The \fInumComponents\fR field is always 0 (the nested command
is not parsed; call \fBTcl_ParseCommand\fR recursively if you want to
see its tokens).
.TP
\fBTCL_TOKEN_VARIABLE\fR
The token describes a variable substitution, including the
\fB$\fR, variable name, and array index (if there is one) up through the
close parenthesis that terminates the index.  This token is followed
by one or more additional tokens that describe the variable name and
array index.  If \fInumComponents\fR  is 1 then the variable is a
scalar and the next token is a \fBTCL_TOKEN_TEXT\fR token that gives the
variable name.  If \fInumComponents\fR is greater than 1 then the
variable is an array: the first sub-token is a \fBTCL_TOKEN_TEXT\fR
token giving the array name and the remaining sub-tokens are
\fBTCL_TOKEN_TEXT\fR, \fBTCL_TOKEN_BS\fR, \fBTCL_TOKEN_COMMAND\fR, and
\fBTCL_TOKEN_VARIABLE\fR tokens that must be concatenated to produce the
array index. The \fInumComponents\fR field includes nested sub-tokens
that are part of \fBTCL_TOKEN_VARIABLE\fR tokens in the array index.
.TP
\fBTCL_TOKEN_SUB_EXPR\fR
The token describes one subexpression of an expression
(or an entire expression).
A subexpression may consist of a value
such as an integer literal, variable substitution,
or parenthesized subexpression;
it may also consist of an operator and its operands.
The token starts with the first non-blank character of the subexpression
up to but not including the space, brace, close-paren, or bracket
that terminates the subexpression.
This token is followed by one or more additional tokens
that describe the subexpression.
If the first sub-token after the \fBTCL_TOKEN_SUB_EXPR\fR token
is a \fBTCL_TOKEN_OPERATOR\fR token,
the subexpression consists of an operator and its token operands.
If the operator has no operands, the subexpression consists of
just the \fBTCL_TOKEN_OPERATOR\fR token.
Each operand is described by a \fBTCL_TOKEN_SUB_EXPR\fR token.
Otherwise, the subexpression is a value described by
one of the token types \fBTCL_TOKEN_WORD\fR, \fBTCL_TOKEN_TEXT\fR,
\fBTCL_TOKEN_BS\fR, \fBTCL_TOKEN_COMMAND\fR, 
\fBTCL_TOKEN_VARIABLE\fR, and \fBTCL_TOKEN_SUB_EXPR\fR.
The \fInumComponents\fR field
counts the total number of sub-tokens that make up the subexpression;
this includes the sub-tokens for any nested \fBTCL_TOKEN_SUB_EXPR\fR tokens.
.TP
\fBTCL_TOKEN_OPERATOR\fR
The token describes one operator of an expression
such as \fB&&\fR or \fBhypot\fR.
An \fBTCL_TOKEN_OPERATOR\fR token is always preceeded by a
\fBTCL_TOKEN_SUB_EXPR\fR token
that describes the operator and its operands;
the \fBTCL_TOKEN_SUB_EXPR\fR token's \fInumComponents\fR field
can be used to determine the number of operands.
A binary operator such as \fB*\fR
is followed by two \fBTCL_TOKEN_SUB_EXPR\fR tokens
that describe its operands.
A unary operator like \fB-\fR
is followed by a single \fBTCL_TOKEN_SUB_EXPR\fR token
for its operand.
If the operator is a math function such as \fBlog10\fR,
the \fBTCL_TOKEN_OPERATOR\fR token will give its name and
the following \fBTCL_TOKEN_SUB_EXPR\fR tokens will describe
its operands;
if there are no operands (as with \fBrand\fR),
no \fBTCL_TOKEN_SUB_EXPR\fR tokens follow.
There is one trinary operator, \fB?\fR,
that appears in if-then-else subexpressions
such as \fIx\fB?\fIy\fB:\fIz\fR;
in this case, the \fB?\fR \fBTCL_TOKEN_OPERATOR\fR token
is followed by three \fBTCL_TOKEN_SUB_EXPR\fR tokens for the operands
\fIx\fR, \fIy\fR, and \fIz\fR.
The \fInumComponents\fR field for a \fBTCL_TOKEN_OPERATOR\fR token
is always 0.
.PP
After \fBTcl_ParseCommand\fR returns, the first token pointed to by
the \fItokenPtr\fR field of the
Tcl_Parse structure always has type \fBTCL_TOKEN_WORD\fR or
\fBTCL_TOKEN_SIMPLE_WORD\fR.  It is followed by the sub-tokens
that must be concatenated to produce the value of that word.
The next token is the \fBTCL_TOKEN_WORD\fR or \fBTCL_TOKEN_SIMPLE_WORD\fR
token for the second word, followed by sub-tokens for that
word, and so on until all \fInumWords\fR have been accounted
for.
.PP
After \fBTcl_ParseExpr\fR returns, the first token pointed to by
the \fItokenPtr\fR field of the
Tcl_Parse structure always has type \fBTCL_TOKEN_SUB_EXPR\fR.
It is followed by the sub-tokens that must be evaluated
to produce the value of the expression.
Only the token information in the Tcl_Parse structure
is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified
by \fBTcl_ParseExpr\fR.
.PP
After \fBTcl_ParseBraces\fR returns,
the array of tokens pointed to by the \fItokenPtr\fR field of the
Tcl_Parse structure will contain a single \fBTCL_TOKEN_TEXT\fR token
if the braced string does not contain any backslash-newlines.
If the string does contain backslash-newlines,
the array of tokens will contain one or more
\fBTCL_TOKEN_TEXT\fR or \fBTCL_TOKEN_BS\fR sub-tokens
that must be concatenated to produce the value of the string.
If the braced string was just \fB{}\fR
(that is, the string was empty),
the single \fBTCL_TOKEN_TEXT\fR token will have a \fIsize\fR field
containing zero;
this ensures that at least one token appears
to describe the braced string.
Only the token information in the Tcl_Parse structure
is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified
by \fBTcl_ParseBraces\fR.
.PP
After \fBTcl_ParseQuotedString\fR returns,
the array of tokens pointed to by the \fItokenPtr\fR field of the
Tcl_Parse structure depends on the contents of the quoted string.
It will consist of one or more \fBTCL_TOKEN_TEXT\fR, \fBTCL_TOKEN_BS\fR,
\fBTCL_TOKEN_COMMAND\fR, and \fBTCL_TOKEN_VARIABLE\fR sub-tokens.
The array always contains at least one token;
for example, if the argument \fIstring\fR is empty,
the array returned consists of a single \fBTCL_TOKEN_TEXT\fR token
with a zero \fIsize\fR field.
Only the token information in the Tcl_Parse structure
is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified.
.PP
After \fBTcl_ParseVarName\fR returns, the first token pointed to by
the \fItokenPtr\fR field of the
Tcl_Parse structure always has type \fBTCL_TOKEN_VARIABLE\fR.  It
is followed by the sub-tokens that make up the variable name as
described above.  The total length of the variable name is
contained in the \fIsize\fR field of the first token.
As in \fBTcl_ParseExpr\fR,
only the token information in the Tcl_Parse structure
is modified by \fBTcl_ParseVarName\fR:
the \fIcommentStart\fR, \fIcommentSize\fR,
\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified.
.PP
All of the character pointers in the
Tcl_Parse and Tcl_Token structures refer
to characters in the \fIstring\fR argument passed to
\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR.
.PP
There are additional fields in the Tcl_Parse structure after the
\fInumTokens\fR field, but these are for the private use of
\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR; they should not be
referenced by code outside of these procedures.

.SH KEYWORDS
backslash substitution, braces, command, expression, parse, token, variable substitution

Changes to doc/PkgRequire.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
'\"
'\" Copyright (c) 1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) PkgRequire.3 1.4 96/02/15 20:03:16
'\" 
.so man.macros
.TH Tcl_PkgRequire 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_PkgRequire, Tcl_PkgProvide \- package version control
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
char *
\fBTcl_PkgRequire\fR(\fIinterp, name, version, exact\fR)
.sp









int
\fBTcl_PkgProvide\fR(\fIinterp, name, version\fR)



.SH ARGUMENTS
.AS Tcl_FreeProc clientData
.AP Tcl_Interp *interp in
Interpreter where package is needed or available.
.AP char *name in
Name of package.
.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 newer versions than \fIversion\fR are also
acceptable as long as they have the same major version number
as \fIversion\fR.






.BE

.SH DESCRIPTION
.PP
These procedures provide C-level interfaces to Tcl's package and
version management facilities.

\fBTcl_PkgRequire\fR is equivalent to the \fBpackage require\fR

command, and \fBTcl_PkgProvide\fR is equivalent to the
\fBpackage provide\fR command.

See the documentation for the Tcl commands for details on what these
procedures do.

If \fBTcl_PkgRequire\fR completes successfully it returns a pointer
to the version string for the version of the package that is provided
in the interpreter (which may be different than \fIversion\fR); if
an error occurs it returns NULL and leaves an error message in
\fIinterp->result\fR.

\fBTcl_PkgProvide\fR returns TCL_OK if it completes successfully;
if an error occurs it returns TCL_ERROR and leaves an error message
in \fIinterp->result\fR.






.SH KEYWORDS
package, provide, require, version






|





|







>
>
>
>
>
>
>
>
>


>
>
>

|













>
>
>
>
>
>






>

>


>


>
|
|
|
|
|
>



>
>
>
>
>


|
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
'\"
'\" Copyright (c) 1996 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: PkgRequire.3,v 1.1.2.2 1999/03/10 06:49:10 stanton Exp $
'\" 
.so man.macros
.TH Tcl_PkgRequire 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_PkgRequire, Tcl_PkgRequireEx, Tcl_PkgPresent, Tcl_PkgPresentEx, Tcl_PkgProvide, Tcl_PkgProvideEx \- package version control
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
char *
\fBTcl_PkgRequire\fR(\fIinterp, name, version, exact\fR)
.sp
char *
\fBTcl_PkgRequireEx\fR(\fIinterp, name, version, exact, clientDataPtr\fR)
.sp
char *
\fBTcl_PkgPresent\fR(\fIinterp, name, version, exact\fR)
.sp
char *
\fBTcl_PkgPresentEx\fR(\fIinterp, name, version, exact, clientDataPtr\fR)
.sp
int
\fBTcl_PkgProvide\fR(\fIinterp, name, version\fR)
.sp
int
\fBTcl_PkgProvideEx\fR(\fIinterp, name, version, clientData\fR)
.SH ARGUMENTS
.AS Tcl_FreeProc clientDataPtr
.AP Tcl_Interp *interp in
Interpreter where package is needed or available.
.AP char *name in
Name of package.
.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 newer versions than \fIversion\fR are also
acceptable as long as they have the same major version number
as \fIversion\fR.
.AP ClientData clientData in
Arbitrary value to be associated with the package.
.AP ClientData *clientDataPtr out
Pointer to place to store the value associated with the matching
package. It is only changed if the pointer is not NULL and the
function completed successfully.
.BE

.SH DESCRIPTION
.PP
These procedures provide C-level interfaces to Tcl's package and
version management facilities.
.PP
\fBTcl_PkgRequire\fR is equivalent to the \fBpackage require\fR
command, \fBTcl_PkgPresent\fR is equivalent to the \fBpackage present\fR
command, and \fBTcl_PkgProvide\fR is equivalent to the
\fBpackage provide\fR command.
.PP
See the documentation for the Tcl commands for details on what these
procedures do.
.PP
If \fBTcl_PkgPresent\fR or \fBTcl_PkgRequire\fR complete successfully
they return a pointer to the version string for the version of the package
that is provided in the interpreter (which may be different than 
\fIversion\fR); if an error occurs they return NULL and leave an error 
message in \fIinterp->result\fR.
.PP
\fBTcl_PkgProvide\fR returns TCL_OK if it completes successfully;
if an error occurs it returns TCL_ERROR and leaves an error message
in \fIinterp->result\fR.
.PP
\fBTcl_PkgProvideEx\fR, \fBTcl_PkgPresentEx\fR and \fBTcl_PkgRequireEx\fR
allow the setting and retrieving of the client data associated with
the package. In all other respects they are equivalent to the matching
functions.

.SH KEYWORDS
package, present, provide, require, version

Changes to doc/Preserve.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Preserve.3 1.13 96/05/28 09:26:12
'\" 
.so man.macros
.TH Tcl_Preserve 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree \- avoid freeing storage while it's being used
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: Preserve.3,v 1.1.2.1 1998/09/24 23:58:25 stanton Exp $
'\" 
.so man.macros
.TH Tcl_Preserve 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree \- avoid freeing storage while it's being used
.SH SYNOPSIS

Changes to doc/PrintDbl.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) PrintDbl.3 1.9 97/08/22 13:30:22
'\" 
.so man.macros
.TH Tcl_PrintDouble 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_PrintDouble \- Convert floating value to string
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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: PrintDbl.3,v 1.1.2.1 1998/09/24 23:58:26 stanton Exp $
'\" 
.so man.macros
.TH Tcl_PrintDouble 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_PrintDouble \- Convert floating value to string
.SH SYNOPSIS

Changes to doc/RecEvalObj.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: SCCS: @(#) RecEvalObj.3 1.1 97/07/29 18:31:21
'\" 
.so man.macros
.TH Tcl_RecordAndEvalObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_RecordAndEvalObj \- save command on history list before evaluating
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: RecEvalObj.3,v 1.1.2.1 1998/09/24 23:58:26 stanton Exp $
'\" 
.so man.macros
.TH Tcl_RecordAndEvalObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_RecordAndEvalObj \- save command on history list before evaluating
.SH SYNOPSIS

Changes to doc/RecordEval.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) RecordEval.3 1.18 97/07/29 18:25:13
'\" 
.so man.macros
.TH Tcl_RecordAndEval 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_RecordAndEval \- save command on history list before evaluating
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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: RecordEval.3,v 1.1.2.1 1998/09/24 23:58:26 stanton Exp $
'\" 
.so man.macros
.TH Tcl_RecordAndEval 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_RecordAndEval \- save command on history list before evaluating
.SH SYNOPSIS

Changes to doc/RegExp.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) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.

'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) RegExp.3 1.9 96/08/26 12:59:48
'\" 
.so man.macros
.TH Tcl_RegExpMatch 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_RegExpMatch, Tcl_RegExpCompile, Tcl_RegExpExec, Tcl_RegExpRange \- Pattern matching with regular expressions
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp



int
\fBTcl_RegExpMatch\fR(\fIinterp\fR, \fIstring\fR, \fIpattern\fR)
.sp
Tcl_RegExp
\fBTcl_RegExpCompile\fR(\fIinterp\fR, \fIpattern\fR)
.sp
int
\fBTcl_RegExpExec\fR(\fIinterp\fR, \fIregexp\fR, \fIstring\fR, \fIstart\fR)
.sp
\fBTcl_RegExpRange\fR(\fIregexp\fR, \fIindex\fR, \fIstartPtr\fR, \fIendPtr\fR)
.SH ARGUMENTS
.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Tcl interpreter to use for error reporting.
.AP char *string in
String to check for a match with a regular expression.
.AP char *pattern in
String in the form of a regular expression pattern.




.AP Tcl_RegExp regexp in
Compiled regular expression.  Must have been returned previously
by \fBTcl_RegExpCompile\fR.
.AP char *start in
If \fIstring\fR is just a portion of some other string, this argument
identifies the beginning of the larger string.
If it isn't the same as \fIstring\fR, then no \fB^\fR matches
will be allowed.
.AP int index in
Specifies which range is desired:  0 means the range of the entire
match, 1 or greater means the range that matched a parenthesized
sub-expression.
.AP char **startPtr out
The address of the first character in the range is stored here, or
NULL if there is no such range.
.AP char **endPtr out
The address of the character just after the last one in the range
is stored here, or NULL if there is no such range.
.BE

.SH DESCRIPTION







.PP
\fBTcl_RegExpMatch\fR determines whether its \fIpattern\fR argument
matches \fIregexp\fR, where \fIregexp\fR is interpreted
as a regular expression using the same rules as for the
\fBregexp\fR Tcl command.
If there is a match then \fBTcl_RegExpMatch\fR returns 1.
If there is no match then \fBTcl_RegExpMatch\fR returns 0.



>




|





|




>
>
>


















>
>
>
>


|


















>
>
>
>
>
>
>







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
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" 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: RegExp.3,v 1.1.2.2 1999/04/05 22:20:26 rjohnson Exp $
'\" 
.so man.macros
.TH Tcl_RegExpMatch 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetRegExpFromObj, Tcl_RegExpMatch, Tcl_RegExpCompile, Tcl_RegExpExec, Tcl_RegExpRange \- Pattern matching with regular expressions
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_RegExp
\fBTcl_GetRegExpFromObj\fR(\fIinterp\fR, \fIpatObj\fR, \fIflags\fR)
.sp
int
\fBTcl_RegExpMatch\fR(\fIinterp\fR, \fIstring\fR, \fIpattern\fR)
.sp
Tcl_RegExp
\fBTcl_RegExpCompile\fR(\fIinterp\fR, \fIpattern\fR)
.sp
int
\fBTcl_RegExpExec\fR(\fIinterp\fR, \fIregexp\fR, \fIstring\fR, \fIstart\fR)
.sp
\fBTcl_RegExpRange\fR(\fIregexp\fR, \fIindex\fR, \fIstartPtr\fR, \fIendPtr\fR)
.SH ARGUMENTS
.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Tcl interpreter to use for error reporting.
.AP char *string in
String to check for a match with a regular expression.
.AP char *pattern in
String in the form of a regular expression pattern.
.AP Tcl_Obj *patObj in
Refers to the object from which to get a compiled regular expression.
.AP int flags in
Various flags to control regular expression compile options.
.AP Tcl_RegExp regexp in
Compiled regular expression.  Must have been returned previously
by \fBTcl_GetRegExpFromObj\fR.
.AP char *start in
If \fIstring\fR is just a portion of some other string, this argument
identifies the beginning of the larger string.
If it isn't the same as \fIstring\fR, then no \fB^\fR matches
will be allowed.
.AP int index in
Specifies which range is desired:  0 means the range of the entire
match, 1 or greater means the range that matched a parenthesized
sub-expression.
.AP char **startPtr out
The address of the first character in the range is stored here, or
NULL if there is no such range.
.AP char **endPtr out
The address of the character just after the last one in the range
is stored here, or NULL if there is no such range.
.BE

.SH DESCRIPTION
.PP
\fBTcl_GetRegExpFromObj\fR attepts to return a compiled regular 
expression from the Tcl obj \fIpatObj\fR.  If the object does not
already contain a compiled regular expression it will attempt to
create one from the string in the Tcl obj and assign it to the
internal representation of the \fIpatObj\fR.  The return value
of this function is of type \fBTcl_RegExp\fR.
.PP
\fBTcl_RegExpMatch\fR determines whether its \fIpattern\fR argument
matches \fIregexp\fR, where \fIregexp\fR is interpreted
as a regular expression using the same rules as for the
\fBregexp\fR Tcl command.
If there is a match then \fBTcl_RegExpMatch\fR returns 1.
If there is no match then \fBTcl_RegExpMatch\fR returns 0.

Added doc/SaveResult.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
'\"
'\" 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: SaveResult.3,v 1.1.2.2 1998/10/21 20:21:31 stanton Exp $
'\" 
.so man.macros
.TH Tcl_SaveResult 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SaveResult, Tcl_RestoreResult, Tcl_DiscardResult \- save and restore an interpreter's result
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
\fBTcl_SaveResult(\fIinterp, statePtr\fB)\fR
.sp
\fBTcl_RestoreResult(\fIinterp, statePtr\fB)\fR
.sp
\fBTcl_DiscardResult(\fIstatePtr\fB)\fR
.SH ARGUMENTS
.AS Tcl_SavedResult statePtr
.AP Tcl_Interp *interp in
Interpreter for which state should be saved.
.AP Tcl_SavedResult *statePtr in
Pointer to location where interpreter result should be saved or restored.
.BE

.SH DESCRIPTION
.PP
These routines allows a C procedure to take a snapshot of the current
interpreter result so that it can be restored after a call
to \fBTcl_Eval\fR or some other routine that modifies the interpreter
result.  These routines are passed a pointer to a structure that is
used to store enough information to restore the interpreter result
state.  This structure can be allocated on the stack of the calling
procedure.  These routines do not save the state of any error
information in the interpreter (e.g. the \fBerrorCode\fR or
\fBerrorInfo\fR variables).
.PP
\fBTcl_SaveResult\fR moves the string and object results
of \fIinterp\fR into the location specified by \fIstatePtr\fR.
\fBTcl_SaveResult\fR clears the result for \fIinterp\fR and
leaves the result in its normal empty initialized state.
.PP
\fBTcl_RestoreResult\fR moves the string and object results from
\fIstatePtr\fR back into \fIinterp\fR.  Any result or error that was
already in the interpreter will be cleared.  The \fIstatePtr\fR is left
in an uninitialized state and cannot be used until another call to
\fBTcl_SaveResult\fR.
.PP
\fBTcl_DiscardResult\fR releases the saved interpreter state
stored at \fBstatePtr\fR.  The state structure is left in an
uninitialized state and cannot be used until another call to
\fBTcl_SaveResult\fR.
.PP
Once \fBTcl_SaveResult\fR is called to save the interpreter
result, either \fBTcl_RestoreResult\fR or
\fBTcl_DiscardResult\fR must be called to properly clean up the
memory associated with the saved state.  

.SH KEYWORDS
result, state, interp

Changes to doc/SetErrno.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) SetErrno.3 1.5 96/02/15 20:01:31
.so man.macros
.TH Tcl_SetErrno 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SetErrno, Tcl_GetErrno \- manipulate errno to store and retrieve error codes
.SH SYNOPSIS
.nf






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1996 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: SetErrno.3,v 1.1.2.1 1998/09/24 23:58:26 stanton Exp $
.so man.macros
.TH Tcl_SetErrno 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SetErrno, Tcl_GetErrno \- manipulate errno to store and retrieve error codes
.SH SYNOPSIS
.nf

Changes to doc/SetRecLmt.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) SetRecLmt.3 1.6 96/03/25 20:06:36
'\" 
.so man.macros
.TH Tcl_SetRecursionLimit 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SetRecursionLimit \- set maximum allowable nesting depth in interpreter
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: SetRecLmt.3,v 1.1.2.2 1999/04/13 00:01:59 surles Exp $
'\" 
.so man.macros
.TH Tcl_SetRecursionLimit 3 7.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SetRecursionLimit \- set maximum allowable nesting depth in interpreter
.SH SYNOPSIS
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
By default the recursion limit is 1000.
.PP
\fBTcl_SetRecursionLimit\fR may be used to change the maximum
allowable nesting depth for an interpreter.
The \fIdepth\fR argument specifies a new limit for \fIinterp\fR,
and \fBTcl_SetRecursionLimit\fR returns the old limit.
To read out the old limit without modifying it, invoke
\fBTcl_SetRecursionDepth\fR with \fIdepth\fR equal to 0.
.PP
The \fBTcl_SetRecursionLimit\fR only sets the size of the Tcl
call stack:  it cannot by itself prevent stack overflows on the
C stack being used by the application.  If your machine has a
limit on the size of the C stack, you may get stack overflows
before reaching the limit set by \fBTcl_SetRecursionLimit\fR.
If this happens, see if there is a mechanism in your system for
increasing the maximum size of the C stack.

.SH KEYWORDS
nesting depth, recursion







|











37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
By default the recursion limit is 1000.
.PP
\fBTcl_SetRecursionLimit\fR may be used to change the maximum
allowable nesting depth for an interpreter.
The \fIdepth\fR argument specifies a new limit for \fIinterp\fR,
and \fBTcl_SetRecursionLimit\fR returns the old limit.
To read out the old limit without modifying it, invoke
\fBTcl_SetRecursionLimit\fR with \fIdepth\fR equal to 0.
.PP
The \fBTcl_SetRecursionLimit\fR only sets the size of the Tcl
call stack:  it cannot by itself prevent stack overflows on the
C stack being used by the application.  If your machine has a
limit on the size of the C stack, you may get stack overflows
before reaching the limit set by \fBTcl_SetRecursionLimit\fR.
If this happens, see if there is a mechanism in your system for
increasing the maximum size of the C stack.

.SH KEYWORDS
nesting depth, recursion

Changes to doc/SetResult.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
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) SetResult.3 1.23 97/06/26 14:05:57
'\" 
.so man.macros
.TH Tcl_SetResult 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SetObjResult, Tcl_GetObjResult, Tcl_SetResult, Tcl_GetStringResult, Tcl_AppendResult, Tcl_AppendElement, Tcl_ResetResult \- manipulate Tcl result
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
\fBTcl_SetObjResult\fR(\fIinterp, objPtr\fR)
.sp
Tcl_Obj *
\fBTcl_GetObjResult\fR(\fIinterp\fR)
.sp
\fBTcl_SetResult\fR(\fIinterp, string, freeProc\fR)
.sp
char *
\fBTcl_GetStringResult\fR(\fIinterp\fR)
.sp
\fBTcl_AppendResult\fR(\fIinterp, string, string, ... , \fB(char *) NULL\fR)


.sp
\fBTcl_AppendElement\fR(\fIinterp, string\fR)
.sp
\fBTcl_ResetResult\fR(\fIinterp\fR)
.sp
\fBTcl_FreeResult\fR(\fIinterp\fR)
.SH ARGUMENTS
.AS Tcl_FreeProc freeProc
.AP Tcl_Interp *interp out
Interpreter whose result is to be modified or read.
.AP Tcl_Obj *objPtr in
Object value to become result for \fIinterp\fR.
.AP char *string in
String value to become result for \fIinterp\fR or to be
appended to the existing result.
.AP Tcl_FreeProc *freeProc in
Address of procedure to call to release storage at
\fIstring\fR, or \fBTCL_STATIC\fR, \fBTCL_DYNAMIC\fR, or
\fBTCL_VOLATILE\fR.



.BE

.SH DESCRIPTION
.PP
The procedures described here are utilities for manipulating the
result value in a Tcl interpreter.
The interpreter result may be either a Tcl object or a string.







|





|















>
>



















>
>
>







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
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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: SetResult.3,v 1.1.2.2 1999/03/10 06:49:10 stanton Exp $
'\" 
.so man.macros
.TH Tcl_SetResult 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SetObjResult, Tcl_GetObjResult, Tcl_SetResult, Tcl_GetStringResult, Tcl_AppendResult, Tcl_AppendResultVA, Tcl_AppendElement, Tcl_ResetResult \- manipulate Tcl result
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
\fBTcl_SetObjResult\fR(\fIinterp, objPtr\fR)
.sp
Tcl_Obj *
\fBTcl_GetObjResult\fR(\fIinterp\fR)
.sp
\fBTcl_SetResult\fR(\fIinterp, string, freeProc\fR)
.sp
char *
\fBTcl_GetStringResult\fR(\fIinterp\fR)
.sp
\fBTcl_AppendResult\fR(\fIinterp, string, string, ... , \fB(char *) NULL\fR)
.sp
\fBTcl_AppendResultVA\fR(\fIinterp, argList\fR)
.sp
\fBTcl_AppendElement\fR(\fIinterp, string\fR)
.sp
\fBTcl_ResetResult\fR(\fIinterp\fR)
.sp
\fBTcl_FreeResult\fR(\fIinterp\fR)
.SH ARGUMENTS
.AS Tcl_FreeProc freeProc
.AP Tcl_Interp *interp out
Interpreter whose result is to be modified or read.
.AP Tcl_Obj *objPtr in
Object value to become result for \fIinterp\fR.
.AP char *string in
String value to become result for \fIinterp\fR or to be
appended to the existing result.
.AP Tcl_FreeProc *freeProc in
Address of procedure to call to release storage at
\fIstring\fR, or \fBTCL_STATIC\fR, \fBTCL_DYNAMIC\fR, or
\fBTCL_VOLATILE\fR.
.AP va_list argList in
An argument list which must have been initialised using
\fBTCL_VARARGS_START\fR, and cleared using \fBva_end\fR.
.BE

.SH DESCRIPTION
.PP
The procedures described here are utilities for manipulating the
result value in a Tcl interpreter.
The interpreter result may be either a Tcl object or a string.
133
134
135
136
137
138
139



140
141
142
143
144
145
146
storage management issues associated with managing \fIinterp\fR's
result, such as allocating a larger result area if necessary.
It also converts the current interpreter result from an object
to a string, if necessary, before appending the argument strings.
Any number of \fIstring\fR arguments may be passed in a single
call; the last argument in the list must be a NULL pointer.
.PP



\fBTcl_AppendElement\fR is similar to \fBTcl_AppendResult\fR in
that it allows results to be built up in pieces.
However, \fBTcl_AppendElement\fR takes only a single \fIstring\fR
argument and it appends that argument to the current result
as a proper Tcl list element.
\fBTcl_AppendElement\fR adds backslashes or braces if necessary
to ensure that \fIinterp\fR's result can be parsed as a list and that







>
>
>







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
storage management issues associated with managing \fIinterp\fR's
result, such as allocating a larger result area if necessary.
It also converts the current interpreter result from an object
to a string, if necessary, before appending the argument strings.
Any number of \fIstring\fR arguments may be passed in a single
call; the last argument in the list must be a NULL pointer.
.PP
\fBTcl_AppendResultVA\fR is the same as \fBTcl_AppendResult\fR except that
instead of taking a variable number of arguments it takes an argument list.
.PP
\fBTcl_AppendElement\fR is similar to \fBTcl_AppendResult\fR in
that it allows results to be built up in pieces.
However, \fBTcl_AppendElement\fR takes only a single \fIstring\fR
argument and it appends that argument to the current result
as a proper Tcl list element.
\fBTcl_AppendElement\fR adds backslashes or braces if necessary
to ensure that \fIinterp\fR's result can be parsed as a list and that

Changes to doc/SetVar.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















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
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) SetVar.3 1.30 97/10/10 16:10:36
'\" 
.so man.macros
.TH Tcl_SetVar 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SetVar, Tcl_SetVar2, Tcl_GetVar, Tcl_GetVar2, Tcl_UnsetVar, Tcl_UnsetVar2 \- manipulate Tcl variables
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR





.sp
char *
\fBTcl_SetVar\fR(\fIinterp, varName, newValue, flags\fR)
.sp
char *
\fBTcl_SetVar2\fR(\fIinterp, name1, name2, newValue, flags\fR)








.sp
char *
\fBTcl_GetVar\fR(\fIinterp, varName, flags\fR)
.sp
char *
\fBTcl_GetVar2\fR(\fIinterp, name1, name2, flags\fR)
.sp



int
\fBTcl_UnsetVar\fR(\fIinterp, varName, flags\fR)
.sp
int
\fBTcl_UnsetVar2\fR(\fIinterp, name1, name2, flags\fR)
.SH ARGUMENTS
.AS Tcl_Interp *newValue
.AP Tcl_Interp *interp in
Interpreter containing variable.
















.AP char *varName in
Name of variable.
May include a series of \fB::\fR namespace qualifiers
to specify a variable in a particular namespace.
May refer to a scalar variable or an element of
an array variable.
If the name references an element of an array, then it
must be in writable memory:  Tcl will make temporary modifications 
to it while looking up the name.
.AP char *newValue in
New value for variable.
.AP int flags in
OR-ed combination of bits providing additional information for
operation. See below for valid values.
.AP char *name1 in
Name of scalar variable, or name of array variable if \fIname2\fR
is non-NULL.
May include a series of \fB::\fR namespace qualifiers
to specify a variable in a particular namespace.

.AP char *name2 in
If non-NULL, gives name of element within array and \fIname1\fR
must refer to an array variable.
.BE

.SH DESCRIPTION
.PP
These procedures may be used to create, modify, read, and delete
Tcl variables from C code.
.PP

Note that \fBTcl_GetVar\fR and \fBTcl_SetVar\fR
have been largely replaced by the
object-based procedures \fBTcl_ObjGetVar2\fR and \fBTcl_ObjSetVar2\fR.
Those object-based procedures read, modify, and create
a variable whose name is held in a Tcl object instead of a string.
They also return a pointer to the object
which is the variable's value instead of returning a string.
Operations on objects can be faster since objects
hold an internal representation that can be manipulated more efficiently.
.PP
\fBTcl_SetVar\fR and \fBTcl_SetVar2\fR
will create a new variable or modify an existing one.
Both of these procedures set the given variable to the value
given by \fInewValue\fR, and they return a pointer to a
copy of the variable's new value, which is stored in Tcl's
variable structure.





Tcl keeps a private copy of the variable's value, so the caller

may change \fInewValue\fR after these procedures return without
affecting the value of the variable.
If an error occurs in setting the variable (e.g. an array
variable is referenced without giving an index into the array),






they return NULL.















.PP















The name of the variable may be specified to


\fBTcl_SetVar\fR and \fBTcl_SetVar2\fR in either of two ways.
If \fBTcl_SetVar\fR is called, the variable name is given as
a single string, \fIvarName\fR.
If \fIvarName\fR contains an open parenthesis and ends with a
close parenthesis, then the value between the parentheses is
treated as an index (which can have any string value) and
the characters before the first open
parenthesis are treated as the name of an array variable.
If \fIvarName\fR doesn't have parentheses as described above, then
the entire string is treated as the name of a scalar variable.



If \fBTcl_SetVar2\fR is called, then the array name and index
have been separated by the caller into two separate strings,
\fIname1\fR and \fIname2\fR respectively;  if \fIname2\fR is







zero it means that a scalar variable is being referenced.

.PP
The \fIflags\fR argument may be used to specify any of several
options to the procedures.
It consists of an OR-ed combination of the following bits.
Note that the flag bit TCL_PARSE_PART1 is only meaningful
for the procedures Tcl_SetVar2 and Tcl_GetVar2.
.TP
\fBTCL_GLOBAL_ONLY\fR
Under normal circumstances the procedures look up variables as follows:
If a procedure call is active in \fIinterp\fR,
a variable is looked up at the current level of procedure call.
Otherwise, a variable is looked up first in the current namespace,
then in the global namespace.
However, if this bit is set in \fIflags\fR then the variable
is looked up only in the global namespace
even if there is a procedure call active.
If both \fBTCL_GLOBAL_ONLY\fR and \fBTCL_NAMESPACE_ONLY\fR are given,
\fBTCL_GLOBAL_ONLY\fR is ignored.
.TP
\fBTCL_NAMESPACE_ONLY\fR
Under normal circumstances the procedures look up variables as follows:
If a procedure call is active in \fIinterp\fR,
a variable is looked up at the current level of procedure call.
Otherwise, a variable is looked up first in the current namespace,
then in the global namespace.
However, if this bit is set in \fIflags\fR then the variable
is looked up only in the current namespace

even if there is a procedure call active.
.TP
\fBTCL_LEAVE_ERR_MSG\fR
If an error is returned and this bit is set in \fIflags\fR, then
an error message will be left in the interpreter's result,
where it can be retrieved with \fBTcl_GetObjResult\fR
or \fBTcl_GetStringResult\fR.
If this flag bit isn't set then no error message is left
and the interpreter's result will not be modified.
.TP
\fBTCL_APPEND_VALUE\fR
If this bit is set then \fInewValue\fR is appended to the current
value, instead of replacing it.
If the variable is currently undefined, then this bit is ignored.

.TP
\fBTCL_LIST_ELEMENT\fR
If this bit is set, then \fInewValue\fR is converted to a valid
Tcl list element before setting (or appending to) the variable.
A separator space is appended before the new list element unless
the list element is going to be the first element in a list or
sublist (i.e. the variable's current value is empty, or contains
the single character ``{'', or ends in `` }'').
.TP
\fBTCL_PARSE_PART1\fR
If this bit is set when calling \fITcl_SetVar2\fR and \fITcl_GetVar2\fR,
\fIname1\fR may contain both an array and an element name:
if the name contains an open parenthesis and ends with a
close parenthesis, then the value between the parentheses is
treated as an element name (which can have any string value) and
the characters before the first open
parenthesis are treated as the name of an array variable.
If the flag TCL_PARSE_PART1 is given,
\fIname2\fR should be NULL since the array and element names
are taken from \fIname1\fR.
.PP
\fBTcl_GetVar\fR and \fBTcl_GetVar2\fR
return the current value of a variable.
The arguments to these procedures are treated in the same way
as the arguments to \fBTcl_SetVar\fR and \fBTcl_SetVar2\fR.
Under normal circumstances, the return value is a pointer
to the variable's value (which is stored in Tcl's variable
structure and will not change before the next call to \fBTcl_SetVar\fR
or \fBTcl_SetVar2\fR).
\fBTcl_GetVar\fR and \fBTcl_GetVar2\fR use the flag bits TCL_GLOBAL_ONLY
and TCL_LEAVE_ERR_MSG, both of
which have
the same meaning as for \fBTcl_SetVar\fR.
In addition, \fBTcl_GetVar2\fR uses the bit TCL_PARSE_PART1,
which has the same meaning as for \fBTcl_SetVar2\fR.
If an error occurs in reading the variable (e.g. the variable
doesn't exist or an array element is specified for a scalar
variable), then NULL is returned.
.PP
\fBTcl_UnsetVar\fR and \fBTcl_UnsetVar2\fR may be used to remove
a variable, so that future calls to \fBTcl_GetVar\fR or \fBTcl_GetVar2\fR
for the variable will return an error.
The arguments to these procedures are treated in the same way
as the arguments to \fBTcl_GetVar\fR and \fBTcl_GetVar2\fR.
If the variable is successfully removed then TCL_OK is returned.
If the variable cannot be removed because it doesn't exist then
TCL_ERROR is returned.
If an array element is specified, the given element is removed
but the array remains.
If an array name is specified without an index, then the entire
array is removed.

.SH "SEE ALSO"
Tcl_GetObjResult, Tcl_GetStringResult, Tcl_ObjGetVar2, Tcl_ObjSetVar2, Tcl_TraceVar

.SH KEYWORDS
array, interpreter, object, scalar, set, unset, variable







|


|


|



>
>
>
>
>






>
>
>
>
>
>
>
>







>
>
>






|


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


|


|
|



|
<
<
|
|
|
<
|

>
|
|
|




|


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

|
|
|

>
>
>
>
>
|
>
|
<

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

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








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




<
<


|

|
|








<
<
<
<
<
|
|
>
|










|
|
|
>








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













<
<


















|


|
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
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" 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: SetVar.3,v 1.1.2.3 1999/02/10 23:31:11 stanton Exp $
'\" 
.so man.macros
.TH Tcl_SetVar 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SetVar2Ex, Tcl_SetVar, Tcl_SetVar2, Tcl_ObjSetVar2, Tcl_GetVar2Ex, Tcl_GetVar, Tcl_GetVar2, Tcl_ObjGetVar2, Tcl_UnsetVar, Tcl_UnsetVar2 \- manipulate Tcl variables
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
.VS 8.1
Tcl_Obj *
\fBTcl_SetVar2Ex\fR(\fIinterp, name1, name2, newValuePtr, flags\fR)
.VE
.sp
char *
\fBTcl_SetVar\fR(\fIinterp, varName, newValue, flags\fR)
.sp
char *
\fBTcl_SetVar2\fR(\fIinterp, name1, name2, newValue, flags\fR)
.sp
Tcl_Obj *
\fBTcl_ObjSetVar2\fR(\fIinterp, part1Ptr, part2Ptr, newValuePtr, flags\fR)
.sp
.VS 8.1
Tcl_Obj *
\fBTcl_GetVar2Ex\fR(\fIinterp, name1, name2, flags\fR)
.VE
.sp
char *
\fBTcl_GetVar\fR(\fIinterp, varName, flags\fR)
.sp
char *
\fBTcl_GetVar2\fR(\fIinterp, name1, name2, flags\fR)
.sp
Tcl_Obj *
\fBTcl_ObjGetVar2\fR(\fIinterp, part1Ptr, part2Ptr, flags\fR)
.sp
int
\fBTcl_UnsetVar\fR(\fIinterp, varName, flags\fR)
.sp
int
\fBTcl_UnsetVar2\fR(\fIinterp, name1, name2, flags\fR)
.SH ARGUMENTS
.AS Tcl_Interp *newValuePtr
.AP Tcl_Interp *interp in
Interpreter containing variable.
.AP char *name1 in
Contains the name of an array variable (if \fIname2\fR is non-NULL)
or (if \fIname2\fR is NULL) either the name of a scalar variable
or a complete name including both variable name and index.
May include \fB::\fR namespace qualifiers
to specify a variable in a particular namespace.
.AP char *name2 in
If non-NULL, gives name of element within array; in this
case \fIname1\fR must refer to an array variable.
.AP Tcl_Obj *newValuePtr in
.VS 8.1
Points to a Tcl object containing the new value for the variable.
.VE
.AP int flags in
OR-ed combination of bits providing additional information. See below
for valid values.
.AP char *varName in
Name of variable.
May include \fB::\fR namespace qualifiers
to specify a variable in a particular namespace.
May refer to a scalar variable or an element of
an array.
If the name references an element of an array, then the name
must be in writable memory:  Tcl will make temporary modifications 
to it while looking up the name.
.AP char *newValue in
New value for variable, specified as a NULL-terminated string.


A copy of this value is stored in the variable.
.AP Tcl_Obj *part1Ptr in
Points to a Tcl object containing the variable's name.

The name may include a series of \fB::\fR namespace qualifiers
to specify a variable in a particular namespace.
May refer to a scalar variable or an element of an array variable.
.AP Tcl_Obj *part2Ptr in
If non-NULL, points to an object containing the name of an element
within an array and \fIpart1Ptr\fR must refer to an array variable.
.BE

.SH DESCRIPTION
.PP
These procedures are used to create, modify, read, and delete
Tcl variables from C code.
.PP
.VS 8.1
\fBTcl_SetVar2Ex\fR, \fBTcl_SetVar\fR, \fBTcl_SetVar2\fR, and

\fBTcl_ObjSetVar2\fR 








will create a new variable or modify an existing one.
These procedures set the given variable to the value
given by \fInewValuePtr\fR or \fInewValue\fR and return a
pointer to the variable's new value, which is stored in Tcl's
variable structure.
\fBTcl_SetVar2Ex\fR and \fBTcl_ObjSetVar2\fR take the new value as a
Tcl_Obj and return
a pointer to a Tcl_Obj.  \fBTcl_SetVar\fR and \fBTcl_SetVar2\fR
take the new value as a string and return a string; they are
usually less efficient than \fBTcl_ObjSetVar2\fR.  Note that the
return value may be different than the \fInewValuePtr\fR or
.VE
\fInewValue\fR argument, due to modifications made by write traces.

If an error occurs in setting the variable (e.g. an array
variable is referenced without giving an index into the array)
NULL is returned and an error message is left in \fIinterp\fR's
result if the \fBTCL_LEAVE_ERR_MSG\fR \fIflag\fR bit is set.
.PP
.VS 8.1
\fBTcl_GetVar2Ex\fR, \fBTcl_GetVar\fR, \fBTcl_GetVar2\fR, and
\fBTcl_ObjGetVar2\fR
return the current value of a variable.
The arguments to these procedures are treated in the same way
as the arguments to the procedures described above.
Under normal circumstances, the return value is a pointer
to the variable's value.  For \fBTcl_GetVar2Ex\fR and
\fBTcl_ObjGetVar2\fR the value is
returned as a pointer to a Tcl_Obj.  For \fBTcl_GetVar\fR and
\fBTcl_GetVar2\fR the value is returned as a string; this is
usually less efficient, so \fBTcl_GetVar2Ex\fR or \fBTcl_ObjGetVar2\fR
are preferred.
.VE
If an error occurs while reading the variable (e.g. the variable
doesn't exist or an array element is specified for a scalar
variable), then NULL is returned and an error message is left
in \fIinterp\fR's result if the \fBTCL_LEAVE_ERR_MSG\fR \fIflag\fR
bit is set.
.PP
\fBTcl_UnsetVar\fR and \fBTcl_UnsetVar2\fR may be used to remove
a variable, so that future attempts to read the variable will return
an error.
The arguments to these procedures are treated in the same way
as the arguments to the procedures above.
If the variable is successfully removed then TCL_OK is returned.
If the variable cannot be removed because it doesn't exist then
TCL_ERROR is returned and an error message is left
in \fIinterp\fR's result if the \fBTCL_LEAVE_ERR_MSG\fR \fIflag\fR
bit is set.
If an array element is specified, the given element is removed
but the array remains.
If an array name is specified without an index, then the entire
array is removed.
.PP
The name of a variable may be specified to these procedures in
four ways:
.IP [1]
If \fBTcl_SetVar\fR, \fBTcl_GetVar\fR, or \fBTcl_UnsetVar\fR
is invoked, the variable name is given as
a single string, \fIvarName\fR.
If \fIvarName\fR contains an open parenthesis and ends with a
close parenthesis, then the value between the parentheses is
treated as an index (which can have any string value) and
the characters before the first open
parenthesis are treated as the name of an array variable.
If \fIvarName\fR doesn't have parentheses as described above, then
the entire string is treated as the name of a scalar variable.
.IP [2]
If the \fIname1\fR and \fIname2\fR arguments are provided and
\fIname2\fR is non-NULL, then an array element is specified and
the array name and index have
already been separated by the caller: \fIname1\fR contains the
name and \fIname2\fR contains the index.
.VS 8.1
An error is generated
if \fIname1\fR  contains an open parenthesis and ends with a
close parenthesis (array element) and \fIname2\fR is non-NULL.
.IP [3]
If \fIname2\fR is NULL, \fIname1\fR is treated just like
\fIvarName\fR in case [1] above (it can be either a scalar or an array
element variable name).
.VE
.PP
The \fIflags\fR argument may be used to specify any of several
options to the procedures.
It consists of an OR-ed combination of the following bits.


.TP
\fBTCL_GLOBAL_ONLY\fR
Under normal circumstances the procedures look up variables as follows.
If a procedure call is active in \fIinterp\fR,
the variable is looked up at the current level of procedure call.
Otherwise, the variable is looked up first in the current namespace,
then in the global namespace.
However, if this bit is set in \fIflags\fR then the variable
is looked up only in the global namespace
even if there is a procedure call active.
If both \fBTCL_GLOBAL_ONLY\fR and \fBTCL_NAMESPACE_ONLY\fR are given,
\fBTCL_GLOBAL_ONLY\fR is ignored.
.TP
\fBTCL_NAMESPACE_ONLY\fR





If this bit is set in \fIflags\fR then the variable
is looked up only in the current namespace; if a procedure is active
its variables are ignored, and the global namespace is also ignored unless
it is the current namespace.
.TP
\fBTCL_LEAVE_ERR_MSG\fR
If an error is returned and this bit is set in \fIflags\fR, then
an error message will be left in the interpreter's result,
where it can be retrieved with \fBTcl_GetObjResult\fR
or \fBTcl_GetStringResult\fR.
If this flag bit isn't set then no error message is left
and the interpreter's result will not be modified.
.TP
\fBTCL_APPEND_VALUE\fR
If this bit is set then \fInewValuePtr\fR or \fInewValue\fR is
appended to the current value instead of replacing it.
If the variable is currently undefined, then the bit is ignored.
This bit is only used by the \fBTcl_Set*\fR procedures.
.TP
\fBTCL_LIST_ELEMENT\fR
If this bit is set, then \fInewValue\fR is converted to a valid
Tcl list element before setting (or appending to) the variable.
A separator space is appended before the new list element unless
the list element is going to be the first element in a list or
sublist (i.e. the variable's current value is empty, or contains
the single character ``{'', or ends in `` }'').












.PP
\fBTcl_GetVar\fR and \fBTcl_GetVar2\fR
return the current value of a variable.
The arguments to these procedures are treated in the same way
as the arguments to \fBTcl_SetVar\fR and \fBTcl_SetVar2\fR.
Under normal circumstances, the return value is a pointer
to the variable's value (which is stored in Tcl's variable
structure and will not change before the next call to \fBTcl_SetVar\fR
or \fBTcl_SetVar2\fR).
\fBTcl_GetVar\fR and \fBTcl_GetVar2\fR use the flag bits TCL_GLOBAL_ONLY
and TCL_LEAVE_ERR_MSG, both of
which have
the same meaning as for \fBTcl_SetVar\fR.


If an error occurs in reading the variable (e.g. the variable
doesn't exist or an array element is specified for a scalar
variable), then NULL is returned.
.PP
\fBTcl_UnsetVar\fR and \fBTcl_UnsetVar2\fR may be used to remove
a variable, so that future calls to \fBTcl_GetVar\fR or \fBTcl_GetVar2\fR
for the variable will return an error.
The arguments to these procedures are treated in the same way
as the arguments to \fBTcl_GetVar\fR and \fBTcl_GetVar2\fR.
If the variable is successfully removed then TCL_OK is returned.
If the variable cannot be removed because it doesn't exist then
TCL_ERROR is returned.
If an array element is specified, the given element is removed
but the array remains.
If an array name is specified without an index, then the entire
array is removed.

.SH "SEE ALSO"
Tcl_GetObjResult, Tcl_GetStringResult, Tcl_TraceVar

.SH KEYWORDS
array, get variable, interpreter, object, scalar, set, unset, variable

Changes to doc/Sleep.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Sleep.3 1.3 96/03/25 20:07:21
'\" 
.so man.macros
.TH Tcl_Sleep 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Sleep \- delay execution for a given number of milliseconds
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: Sleep.3,v 1.1.2.1 1998/09/24 23:58:26 stanton Exp $
'\" 
.so man.macros
.TH Tcl_Sleep 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Sleep \- delay execution for a given number of milliseconds
.SH SYNOPSIS

Changes to doc/SplitList.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) SplitList.3 1.21 97/04/29 14:07:10
'\" 
.so man.macros
.TH Tcl_SplitList 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SplitList, Tcl_Merge, Tcl_ScanElement, Tcl_ConvertElement \- manipulate Tcl lists
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: SplitList.3,v 1.1.2.1 1998/09/24 23:58:27 stanton Exp $
'\" 
.so man.macros
.TH Tcl_SplitList 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SplitList, Tcl_Merge, Tcl_ScanElement, Tcl_ConvertElement \- manipulate Tcl lists
.SH SYNOPSIS

Changes to doc/SplitPath.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) SplitPath.3 1.4 96/08/19 14:59:35
'\" 
.so man.macros
.TH Tcl_SplitPath 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SplitPath, Tcl_JoinPath, Tcl_GetPathType \- manipulate platform-dependent file paths
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1996 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: SplitPath.3,v 1.1.2.1 1998/09/24 23:58:27 stanton Exp $
'\" 
.so man.macros
.TH Tcl_SplitPath 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_SplitPath, Tcl_JoinPath, Tcl_GetPathType \- manipulate platform-dependent file paths
.SH SYNOPSIS

Changes to doc/StaticPkg.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) StaticPkg.3 1.4 96/09/04 11:21:26
'\" 
.so man.macros
.TH Tcl_StaticPackage 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_StaticPackage \- make a statically linked package available via the \fBload\fR command
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 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: StaticPkg.3,v 1.1.2.1 1998/09/24 23:58:27 stanton Exp $
'\" 
.so man.macros
.TH Tcl_StaticPackage 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_StaticPackage \- make a statically linked package available via the \fBload\fR command
.SH SYNOPSIS

Changes to doc/StrMatch.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) StrMatch.3 1.11 96/03/25 20:08:06
'\" 
.so man.macros
.TH Tcl_StringMatch 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_StringMatch \- test whether a string matches a pattern
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: StrMatch.3,v 1.1.2.1 1998/09/24 23:58:27 stanton Exp $
'\" 
.so man.macros
.TH Tcl_StringMatch 3 "" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_StringMatch \- test whether a string matches a pattern
.SH SYNOPSIS

Changes to doc/StringObj.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
'\"
'\" 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.
'\" 
'\" SCCS: @(#) @(#) StringObj.3 1.13 97/06/25 13:40:25
'\" 
.so man.macros
.TH Tcl_StringObj 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewStringObj, Tcl_SetStringObj, Tcl_GetStringFromObj, Tcl_AppendToObj, Tcl_AppendStringsToObj, Tcl_SetObjLength, TclConcatObj \- manipulate Tcl objects as strings
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_Obj *
\fBTcl_NewStringObj\fR(\fIbytes, length\fR)
.sp
\fBTcl_SetStringObj\fR(\fIobjPtr, bytes, length\fR)
.sp
char *
\fBTcl_GetStringFromObj\fR(\fIobjPtr, lengthPtr\fR)
.sp



\fBTcl_AppendToObj\fR(\fIobjPtr, bytes, length\fR)

.sp



\fBTcl_AppendStringsToObj\fR(\fIobjPtr, string, string, ... \fB(char *) NULL\fR)


.sp
\fBTcl_SetObjLength\fR(\fIobjPtr, newLength\fR)
.sp
Tcl_Obj *
\fBTcl_ConcatObj\fR(\fIobjc, objv\fR)
.SH ARGUMENTS
.AS Tcl_Interp *lengthPtr out
.AP char *bytes in
Points to the first byte of an array of bytes
used to set or append to a string object.
This byte array may contain embedded null bytes
unless \fIlength\fR is negative.
.AP int length in
The number of bytes to copy from \fIbytes\fR when
initializing, setting, or appending to a string object.
If negative, all bytes up to the first null are used.
.AP Tcl_Obj *objPtr in/out
Points to an object to manipulate.




.AP int *lengthPtr out
If non-NULL, the location where \fBTcl_GetStringFromObj\fR will store
the the length of an object's string representation.
.AP char *string in
Null-terminated string value to append to \fIobjPtr\fR.



.AP int newLength in
New length for the string value of \fIobjPtr\fR, not including the
final NULL character.
.AP int objc in
The number of elements to concatenate.
.AP Tcl_Obj *objv[] in
The array of objects to concatenate.






|


|


|












>
>
>

>

>
>
>

>
>






|











>
>
>
>





>
>
>







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
'\"
'\" 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: StringObj.3,v 1.1.2.3 1999/03/10 06:49:10 stanton Exp $
'\" 
.so man.macros
.TH Tcl_StringObj 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewStringObj, Tcl_SetStringObj, Tcl_GetStringFromObj, Tcl_GetString, Tcl_AppendToObj, Tcl_AppendStringsToObj, Tcl_AppendStringsToObjVA, Tcl_AppendObjToObj, Tcl_SetObjLength, Tcl_ConcatObj \- manipulate Tcl objects as strings
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_Obj *
\fBTcl_NewStringObj\fR(\fIbytes, length\fR)
.sp
\fBTcl_SetStringObj\fR(\fIobjPtr, bytes, length\fR)
.sp
char *
\fBTcl_GetStringFromObj\fR(\fIobjPtr, lengthPtr\fR)
.sp
char *
\fBTcl_GetString\fR(\fIobjPtr\fR)
.sp
\fBTcl_AppendToObj\fR(\fIobjPtr, bytes, length\fR)
.VS
.sp
\fBTcl_AppendObjToObj\fR(\fIobjPtr, appendObjPtr\fR)
.VE
.sp
\fBTcl_AppendStringsToObj\fR(\fIobjPtr, string, string, ... \fB(char *) NULL\fR)
.sp
\fBTcl_AppendStringsToObjVA\fR(\fIobjPtr, argList\fR)
.sp
\fBTcl_SetObjLength\fR(\fIobjPtr, newLength\fR)
.sp
Tcl_Obj *
\fBTcl_ConcatObj\fR(\fIobjc, objv\fR)
.SH ARGUMENTS
.AS Tcl_Interp *appendObjPtr in/out
.AP char *bytes in
Points to the first byte of an array of bytes
used to set or append to a string object.
This byte array may contain embedded null bytes
unless \fIlength\fR is negative.
.AP int length in
The number of bytes to copy from \fIbytes\fR when
initializing, setting, or appending to a string object.
If negative, all bytes up to the first null are used.
.AP Tcl_Obj *objPtr in/out
Points to an object to manipulate.
.VS
.AP Tcl_Obj *appendObjPtr in
The object to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
.VE
.AP int *lengthPtr out
If non-NULL, the location where \fBTcl_GetStringFromObj\fR will store
the the length of an object's string representation.
.AP char *string in
Null-terminated string value to append to \fIobjPtr\fR.
.AP va_list argList in
An argument list which must have been initialised using
\fBTCL_VARARGS_START\fR, and cleared using \fBva_end\fR.
.AP int newLength in
New length for the string value of \fIobjPtr\fR, not including the
final NULL character.
.AP int objc in
The number of elements to concatenate.
.AP Tcl_Obj *objv[] in
The array of objects to concatenate.
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
the string given by \fIbytes\fR and \fIlength\fR.
\fBTcl_NewStringObj\fR returns a pointer to a newly created object
with reference count zero.
Both procedures set the object to hold a copy of the specified string.
\fBTcl_SetStringObj\fR frees any old string representation
as well as any old internal representation of the object.
.PP
\fBTcl_GetStringFromObj\fR returns an object's string representation.

This is given by the returned byte pointer

and length, which is stored in \fIlengthPtr\fR if it is non-NULL.
If the object's string representation is invalid
(its byte pointer is NULL),
the string representation is regenerated from the
object's internal representation.
The storage referenced by the returned byte pointer
is owned by the object manager and should not be modified by the caller.


.PP
\fBTcl_AppendToObj\fR appends the data given by \fIbytes\fR and
\fIlength\fR to the object specified by \fIobjPtr\fR.  It does this
in a way that handles repeated calls relatively efficiently (it
overallocates the string space to avoid repeated reallocations
and copies of object's string value).





.PP
\fBTcl_AppendStringsToObj\fR is similar to \fBTcl_AppendToObj\fR
except that it can be passed more than one value to append and
each value must be a null-terminated string (i.e. none of the
values may contain internal null characters).  Any number of
\fIstring\fR arguments may be provided, but the last argument
must be a NULL pointer to indicate the end of the list.




.PP
The \fBTcl_SetObjLength\fR procedure changes the length of the
string value of its \fIobjPtr\fR argument.  If the \fInewLength\fR
argument is greater than the space allocated for the object's
string, then the string space is reallocated and the old value
is copied to the new space; the bytes between the old length of
the string and the new length may have arbitrary values.







|
>

>
|






>
>






>
>
>
>
>







>
>
>
>







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
the string given by \fIbytes\fR and \fIlength\fR.
\fBTcl_NewStringObj\fR returns a pointer to a newly created object
with reference count zero.
Both procedures set the object to hold a copy of the specified string.
\fBTcl_SetStringObj\fR frees any old string representation
as well as any old internal representation of the object.
.PP
\fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR
return an object's string representation.
This is given by the returned byte pointer
and (for \fBTcl_GetStringFromObj\fR) length,
which is stored in \fIlengthPtr\fR if it is non-NULL.
If the object's string representation is invalid
(its byte pointer is NULL),
the string representation is regenerated from the
object's internal representation.
The storage referenced by the returned byte pointer
is owned by the object manager and should not be modified by the caller.
The procedure \fBTcl_GetString\fR is used in the common case
where the caller does not need the length of the string representation.
.PP
\fBTcl_AppendToObj\fR appends the data given by \fIbytes\fR and
\fIlength\fR to the object specified by \fIobjPtr\fR.  It does this
in a way that handles repeated calls relatively efficiently (it
overallocates the string space to avoid repeated reallocations
and copies of object's string value).
.VS
.PP
\fBTcl_AppendObjToObj\fR is similar to \fBTcl_AppendToObj\fR, but it
appends the string value of \fIappendObjPtr\fR to \fIobjPtr\fR.
.VE
.PP
\fBTcl_AppendStringsToObj\fR is similar to \fBTcl_AppendToObj\fR
except that it can be passed more than one value to append and
each value must be a null-terminated string (i.e. none of the
values may contain internal null characters).  Any number of
\fIstring\fR arguments may be provided, but the last argument
must be a NULL pointer to indicate the end of the list.
.PP
\fBTcl_AppendStringsToObjVA\fR is the same as \fBTcl_AppendStringsToObj\fR
except that instead of taking a variable number of arguments it takes an
argument list.
.PP
The \fBTcl_SetObjLength\fR procedure changes the length of the
string value of its \fIobjPtr\fR argument.  If the \fInewLength\fR
argument is greater than the space allocated for the object's
string, then the string space is reallocated and the old value
is copied to the new space; the bytes between the old length of
the string and the new length may have arbitrary values.

Changes to doc/Tcl.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Tcl.n 1.128 96/08/26 12:59:50
'
.so man.macros
.TH Tcl n "" Tcl "Tcl Built-In Commands"
.BS
.SH NAME
Tcl \- Summary of Tcl language syntax.
.BE

.SH DESCRIPTION
.PP







|
|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: Tcl.n,v 1.1.2.2 1998/09/24 23:58:27 stanton Exp $
'\"
.so man.macros
.TH Tcl n "8.1" Tcl "Tcl Built-In Commands"
.BS
.SH NAME
Tcl \- Summary of Tcl language syntax.
.BE

.SH DESCRIPTION
.PP
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
character and included in the word.
This allows characters such as double quotes, close brackets,
and dollar signs to be included in words without triggering
special processing.
The following table lists the backslash sequences that are
handled specially, along with the value that replaces each sequence.
.RS
.TP 6
\e\fBa\fR
Audible alert (bell) (0x7).
.TP 6
\e\fBb\fR
Backspace (0x8).
.TP 6
\e\fBf\fR
Form feed (0xc).
.TP 6
\e\fBn\fR
Newline (0xa).
.TP 6
\e\fBr\fR
Carriage-return (0xd).
.TP 6
\e\fBt\fR
Tab (0x9).
.TP 6
\e\fBv\fR
Vertical tab (0xb).
.TP 6
\e\fB<newline>\fIwhiteSpace\fR

A single space character replaces the backslash, newline, and all
spaces and tabs after the newline.
This backslash sequence is unique in that it is replaced in a separate
pre-pass before the command is actually parsed.
This means that it will be replaced even when it occurs between
braces, and the resulting space will be treated as a word separator
if it isn't in braces or quotes.
.TP 6
\e\e
Backslash (``\e'').

.TP 6
\e\fIooo\fR

The digits \fIooo\fR (one, two, or three of them) give the octal value of

the character.
.TP 6
\e\fBx\fIhh\fR

The hexadecimal digits \fIhh\fR give the hexadecimal value of
the character.  Any number of digits may be present.










.LP
Backslash substitution is not performed on words enclosed in braces,
except for backslash-newline as described above.
.RE
.IP [9]
If a hash character (``#'') appears at a point where Tcl is
expecting the first character of the first word of a command,







|


|


|


|


|


|


|


|

>
|
<
|
|
|
|
|
|


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







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
character and included in the word.
This allows characters such as double quotes, close brackets,
and dollar signs to be included in words without triggering
special processing.
The following table lists the backslash sequences that are
handled specially, along with the value that replaces each sequence.
.RS
.TP 7
\e\fBa\fR
Audible alert (bell) (0x7).
.TP 7
\e\fBb\fR
Backspace (0x8).
.TP 7
\e\fBf\fR
Form feed (0xc).
.TP 7
\e\fBn\fR
Newline (0xa).
.TP 7
\e\fBr\fR
Carriage-return (0xd).
.TP 7
\e\fBt\fR
Tab (0x9).
.TP 7
\e\fBv\fR
Vertical tab (0xb).
.TP 7
\e\fB<newline>\fIwhiteSpace\fR
.
A single space character replaces the backslash, newline, and all spaces

and tabs after the newline.  This backslash sequence is unique in that it
is replaced in a separate pre-pass before the command is actually parsed.
This means that it will be replaced even when it occurs between braces,
and the resulting space will be treated as a word separator if it isn't
in braces or quotes.
.TP 7
\e\e
Backslash (``\e'').
.VS 8.1 br
.TP 7
\e\fIooo\fR 
.
The digits \fIooo\fR (one, two, or three of them) give an eight-bit octal 
value for the Unicode character that will be inserted.  The upper bits of the
Unicode character will be 0.
.TP 7
\e\fBx\fIhh\fR 
.
The hexadecimal digits \fIhh\fR give an eight-bit hexadecimal value for the
Unicode character that will be inserted.  Any number of hexadecimal digits
may be present; however, all but the last two are ignored (the result is
always a one-byte quantity).  The upper bits of the Unicode character will
be 0.
.TP 7
\e\fBu\fIhhhh\fR 
.
The hexadecimal digits \fIhhhh\fR (one, two, three, or four of them) give a
sixteen-bit hexadecimal value for the Unicode character that will be
inserted.
.VE
.LP
Backslash substitution is not performed on words enclosed in braces,
except for backslash-newline as described above.
.RE
.IP [9]
If a hash character (``#'') appears at a point where Tcl is
expecting the first character of the first word of a command,

Changes to doc/Tcl_Main.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Tcl_Main.3 1.8 96/03/25 20:08:33
'\" 
.so man.macros
.TH Tcl_Main 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Main \- main program for Tcl-based applications
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: Tcl_Main.3,v 1.1.2.1 1998/09/24 23:58:27 stanton Exp $
'\" 
.so man.macros
.TH Tcl_Main 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Main \- main program for Tcl-based applications
.SH SYNOPSIS

Added 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
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
'\"
'\" 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.1.2.3 1999/03/25 19:43:34 stanton 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
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 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.
.VE
\fBTcl_MutexLock\fR and \fBTcl_MutexUnlock\fR
procedures are defined as empty macros if not compiling with threads enabled.
.PP
A condition variable is used as a signaling mechanism:
a thread can lock a mutex and then wait on a condition variable
with \fBTcl_ConditionWait\fR.  This atomically releases the mutex lock
and blocks the waiting thread until another thread calls
\fBTcl_ConditionNotify\fR.  The caller of \fBTcl_ConditionNotify\fR should
have the associated mutex held by previously calling \fBTcl_MutexLock\fR,
but this is not enforced.  Notifying the
condition variable unblocks all threads waiting on the condition variable,
but they do not proceed until the mutex is released with \fBTcl_MutexUnlock\fR.
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
.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

Added doc/ToUpper.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
'\"
'\" 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: ToUpper.3,v 1.1.2.2 1998/10/21 20:21:31 stanton Exp $
'\" 
.so man.macros
.TH Tcl_UtfToUpper 3 "8.1" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_UniCharToUpper, Tcl_UniCharToLower, Tcl_UniCharToTitle, Tcl_UtfToUpper, Tcl_UtfToLower, Tcl_UtfToTitle \- routines for manipulating the case of Unicode characters and UTF-8 strings.
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_UniChar
\fBTcl_UniCharToUpper\fR(\fIch\fR)
.sp
Tcl_UniChar
\fBTcl_UniCharToLower\fR(\fIch\fR)
.sp
Tcl_UniChar
\fBTcl_UniCharToTitle\fR(\fIch\fR)
.sp
int
\fBTcl_UtfToUpper\fR(\fIstr\fR)
.sp
int
\fBTcl_UtfToLower\fR(\fIstr\fR)
.sp
int
\fBTcl_UtfToTitle\fR(\fIstr\fR)
.SH ARGUMENTS
.AS char *str in/out
.AP int ch in
The Tcl_UniChar to be converted.
.AP char *str in/out
Pointer to UTF-8 string to be converted in place.
.BE

.SH DESCRIPTION
.PP
The first three routines convert the case of individual Unicode characters:
.PP
If \fIch\fR represents a lower-case character,
\fBTcl_UniCharToUpper\fR returns the corresponding upper-case
character.  If no upper-case character is defined, it returns the
character unchanged.
.PP
If \fIch\fR represents an upper-case character,
\fBTcl_UniCharToLower\fR returns the corresponding lower-case
character.  If no lower-case character is defined, it returns the
character unchanged.
.PP
If \fIch\fR represents a lower-case character,
\fBTcl_UniCharToTitle\fR returns the corresponding title-case
character.  If no title-case character is defined, it returns the
corresponding upper-case character.  If no upper-case character is
defined, it returns the character unchanged.  Title-case is defined
for a small number of characters that have a different appearance when
they are at the beginning of a capitalized word.
.PP
The next three routines convert the case of UTF-8 strings in place in
memory:
.PP
\fBTcl_UtfToUpper\fR changes every UTF-8 character in \fIstr\fR to
upper-case.  Because changing the case of a character may change its
size, the byte offset of each character in the resulting string may
differ from its original location.  \fBTcl_UtfToUpper\fR writes a null
byte at the end of the converted string.  \fBTcl_UtfToUpper\fR returns
the new length of the string in bytes.  This new length is guaranteed
to be no longer than the original string length.
.PP
\fBTcl_UtfToLower\fR is the same as \fBTcl_UtfToUpper\fR except it
turns each character in the string into its lower-case equivalent.
.PP
\fBTcl_UtfToTitle\fR is the same as \fBTcl_UtfToUpper\fR except it
turns the first character in the string into its title-case equivalent
and all following characters into their lower-case equivalents.

.SH BUGS
.PP
At this time, the case conversions are only defined for the ISO8859-1
characters.  Unicode characters above 0x00ff are not modified by these
routines.

.SH KEYWORDS
utf, unicode, toupper, tolower, totitle, case

Changes to doc/TraceVar.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) TraceVar.3 1.27 97/10/10 15:05:37
'\" 
.so man.macros
.TH Tcl_TraceVar 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_TraceVar, Tcl_TraceVar2, Tcl_UntraceVar, Tcl_UntraceVar2, Tcl_VarTraceInfo, Tcl_VarTraceInfo2 \- monitor accesses to a variable
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: TraceVar.3,v 1.1.2.2 1998/09/24 23:58:27 stanton Exp $
'\" 
.so man.macros
.TH Tcl_TraceVar 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_TraceVar, Tcl_TraceVar2, Tcl_UntraceVar, Tcl_UntraceVar2, Tcl_VarTraceInfo, Tcl_VarTraceInfo2 \- monitor accesses to a variable
.SH SYNOPSIS
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
an array variable with no index, or to an array variable
with a parenthesized index.
If the name references an element of an array, then it
must be in writable memory:  Tcl will make temporary modifications 
to it while looking up the name.
.AP int flags in
OR-ed combination of the values TCL_TRACE_READS, TCL_TRACE_WRITES, and
TCL_TRACE_UNSETS, TCL_PARSE_PART1, and TCL_GLOBAL_ONLY.  
Not all flags are used by all
procedures.  See below for more information.
.AP Tcl_VarTraceProc *proc in
Procedure to invoke whenever one of the traced operations occurs.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.AP char *name1 in







|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
an array variable with no index, or to an array variable
with a parenthesized index.
If the name references an element of an array, then it
must be in writable memory:  Tcl will make temporary modifications 
to it while looking up the name.
.AP int flags in
OR-ed combination of the values TCL_TRACE_READS, TCL_TRACE_WRITES, and
TCL_TRACE_UNSETS, TCL_TRACE_ARRAY, and TCL_GLOBAL_ONLY.  
Not all flags are used by all
procedures.  See below for more information.
.AP Tcl_VarTraceProc *proc in
Procedure to invoke whenever one of the traced operations occurs.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.AP char *name1 in
92
93
94
95
96
97
98






99
100
101
102
103
104
105
.TP
\fBTCL_TRACE_UNSETS\fR
Invoke \fIproc\fR whenever the variable is unset.
A variable may be unset either explicitly by an \fBunset\fR command,
or implicitly when a procedure returns (its local variables are
automatically unset) or when the interpreter is deleted (all
variables are automatically unset).






.PP
Whenever one of the specified operations occurs on the variable,
\fIproc\fR will be invoked.
It should have arguments and result that match the type
\fBTcl_VarTraceProc\fR:
.CS
typedef char *Tcl_VarTraceProc(







>
>
>
>
>
>







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
.TP
\fBTCL_TRACE_UNSETS\fR
Invoke \fIproc\fR whenever the variable is unset.
A variable may be unset either explicitly by an \fBunset\fR command,
or implicitly when a procedure returns (its local variables are
automatically unset) or when the interpreter is deleted (all
variables are automatically unset).
.TP
\fBTCL_TRACE_ARRAY\fR
Invoke \fIproc\fR whenever the array command is invoked.
This gives the trace procedure a chance to update the array before
array names or array get is called.  Note that this is called
before an array set, but that will trigger write traces.
.PP
Whenever one of the specified operations occurs on the variable,
\fIproc\fR will be invoked.
It should have arguments and result that match the type
\fBTcl_VarTraceProc\fR:
.CS
typedef char *Tcl_VarTraceProc(
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
data structure that describes what to do when \fIproc\fR
is invoked.
\fIName1\fR and \fIname2\fR give the name of the traced variable
in the normal two-part form (see the description of \fBTcl_TraceVar2\fR
below for details).
\fIFlags\fR is an OR-ed combination of bits providing several
pieces of information.
One of the bits TCL_TRACE_READS, TCL_TRACE_WRITES, or TCL_TRACE_UNSETS

will be set in \fIflags\fR to indicate which operation is being performed
on the variable.
The bit TCL_GLOBAL_ONLY will be set whenever the variable being
accessed is a global one not accessible from the current level of
procedure call:  the trace procedure will need to pass this flag
back to variable-related procedures like \fBTcl_GetVar\fR if it
attempts to access the variable.







|
>







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
data structure that describes what to do when \fIproc\fR
is invoked.
\fIName1\fR and \fIname2\fR give the name of the traced variable
in the normal two-part form (see the description of \fBTcl_TraceVar2\fR
below for details).
\fIFlags\fR is an OR-ed combination of bits providing several
pieces of information.
One of the bits TCL_TRACE_READS, TCL_TRACE_WRITES, TCL_TRACE_ARRAY,
or TCL_TRACE_UNSETS
will be set in \fIflags\fR to indicate which operation is being performed
on the variable.
The bit TCL_GLOBAL_ONLY will be set whenever the variable being
accessed is a global one not accessible from the current level of
procedure call:  the trace procedure will need to pass this flag
back to variable-related procedures like \fBTcl_GetVar\fR if it
attempts to access the variable.
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
.PP
The procedures \fBTcl_TraceVar2\fR, \fBTcl_UntraceVar2\fR, and
\fBTcl_VarTraceInfo2\fR are identical to \fBTcl_TraceVar\fR,
\fBTcl_UntraceVar\fR, and \fBTcl_VarTraceInfo\fR, respectively,
except that the name of the variable consists of two parts.
\fIName1\fR gives the name of a scalar variable or array,
and \fIname2\fR gives the name of an element within an array.

If \fIname2\fR is NULL it means that either the variable is
a scalar or the trace is to be set on the entire array rather
than an individual element (see WHOLE-ARRAY TRACES below for
more information).
As a special case, if the flag TCL_PARSE_PART1 is specified,
\fIname1\fR may contain both an array and an element name:
if the name contains an open parenthesis and ends with a
close parenthesis, then the value between the parentheses is
treated as an element name (which can have any string value) and
the characters before the first open
parenthesis are treated as the name of an array variable.
If the flag TCL_PARSE_PART1 is given,
\fIname2\fR should be NULL since the array and element names





are taken from \fIname1\fR.

.SH "ACCESSING VARIABLES DURING TRACES"
.PP
During read and write traces, the
trace procedure can read, write, or unset the traced
variable using \fBTcl_GetVar2\fR, \fBTcl_SetVar2\fR, and
other procedures.
While \fIproc\fR is executing, traces are temporarily disabled
for the variable, so that calls to \fBTcl_GetVar2\fR and
\fBTcl_SetVar2\fR will not cause \fIproc\fR or other trace procedures
to be invoked again.







>
|
<
<
<
<






|
|
>
>
>
>
>
|



|







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
.PP
The procedures \fBTcl_TraceVar2\fR, \fBTcl_UntraceVar2\fR, and
\fBTcl_VarTraceInfo2\fR are identical to \fBTcl_TraceVar\fR,
\fBTcl_UntraceVar\fR, and \fBTcl_VarTraceInfo\fR, respectively,
except that the name of the variable consists of two parts.
\fIName1\fR gives the name of a scalar variable or array,
and \fIname2\fR gives the name of an element within an array.
.VS 8.1
When \fIname2\fR is NULL, 




\fIname1\fR may contain both an array and an element name:
if the name contains an open parenthesis and ends with a
close parenthesis, then the value between the parentheses is
treated as an element name (which can have any string value) and
the characters before the first open
parenthesis are treated as the name of an array variable.
If \fIname2\fR is NULL and \fIname1\fR does not refer
to an array element 
.VE
it means that either the variable is
a scalar or the trace is to be set on the entire array rather
than an individual element (see WHOLE-ARRAY TRACES below for
more information). 


.SH "ACCESSING VARIABLES DURING TRACES"
.PP
During read, write, and array traces, the
trace procedure can read, write, or unset the traced
variable using \fBTcl_GetVar2\fR, \fBTcl_SetVar2\fR, and
other procedures.
While \fIproc\fR is executing, traces are temporarily disabled
for the variable, so that calls to \fBTcl_GetVar2\fR and
\fBTcl_SetVar2\fR will not cause \fIproc\fR or other trace procedures
to be invoked again.
240
241
242
243
244
245
246






247
248
249
250
251
252
253
modified, but before the new value of the variable has been
returned.
It may modify the value of the variable to override the change
and to determine the value actually returned by the traced
access.
If it deletes the variable then the traced access will return
an empty string.






.PP
When unset tracing has been specified, the trace procedure
will be invoked whenever the variable is destroyed.
The traces will be called after the variable has been
completely unset.

.SH "WHOLE-ARRAY TRACES"







>
>
>
>
>
>







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
modified, but before the new value of the variable has been
returned.
It may modify the value of the variable to override the change
and to determine the value actually returned by the traced
access.
If it deletes the variable then the traced access will return
an empty string.
.PP
When array tracing has been specified, the trace procedure
will be invoked at the beginning of the array command implementation,
before any of the operations like get, set, or names have been invoked.
The trace procedure can modify the array elements with \fBTcl_SetVar\fR
and \fBTcl_SetVar2\fR.
.PP
When unset tracing has been specified, the trace procedure
will be invoked whenever the variable is destroyed.
The traces will be called after the variable has been
completely unset.

.SH "WHOLE-ARRAY TRACES"
339
340
341
342
343
344
345



346
347
348
to clean up and free their own internal data structures.

.SH BUGS
.PP
Tcl doesn't do any error checking to prevent trace procedures
from misusing the interpreter during traces with TCL_INTERP_DESTROYED
set.




.SH KEYWORDS
clientData, trace, variable







>
>
>



354
355
356
357
358
359
360
361
362
363
364
365
366
to clean up and free their own internal data structures.

.SH BUGS
.PP
Tcl doesn't do any error checking to prevent trace procedures
from misusing the interpreter during traces with TCL_INTERP_DESTROYED
set.
.PP
Array traces are not yet integrated with the Tcl "info exists" command,
nor is there Tcl-level access to array traces.

.SH KEYWORDS
clientData, trace, variable

Changes to doc/Translate.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
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) Translate.3 1.22 96/08/26 12:59:51
'\" 
.so man.macros
.TH Tcl_TranslateFileName 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_TranslateFileName \- convert file name to native form and replace tilde with home directory
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
char *
\fBTcl_TranslateFileName\fR(\fIinterp\fR, \fIname\fR, \fIbufferPtr\fR)
.SH ARGUMENTS
.AS Tcl_DString *bufferPtr
.AP Tcl_Interp *interp in
Interpreter in which to report an error, if any.
.AP char *name in
File name, which may start with a ``~''.
.AP Tcl_DString *bufferPtr in/out
If needed, this dynamic string is used to store the new file name.
At the time of the call it should be uninitialized or empty.  The
caller must eventually call \fBTcl_DStringFree\fR to free up
anything stored here.
.BE

.SH DESCRIPTION
.PP
This utility procedure translates a file name to a form suitable for


|




|


|

















|







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
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-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: Translate.3,v 1.1.2.2 1998/09/24 23:58:28 stanton Exp $
'\" 
.so man.macros
.TH Tcl_TranslateFileName 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_TranslateFileName \- convert file name to native form and replace tilde with home directory
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
char *
\fBTcl_TranslateFileName\fR(\fIinterp\fR, \fIname\fR, \fIbufferPtr\fR)
.SH ARGUMENTS
.AS Tcl_DString *bufferPtr
.AP Tcl_Interp *interp in
Interpreter in which to report an error, if any.
.AP char *name in
File name, which may start with a ``~''.
.AP Tcl_DString *bufferPtr in/out
If needed, this dynamic string is used to store the new file name.
At the time of the call it should be uninitialized or free.  The
caller must eventually call \fBTcl_DStringFree\fR to free up
anything stored here.
.BE

.SH DESCRIPTION
.PP
This utility procedure translates a file name to a form suitable for

Changes to doc/UpVar.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) UpVar.3 1.6 96/03/25 20:09:19
'\" 
.so man.macros
.TH Tcl_UpVar 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_UpVar, Tcl_UpVar2 \- link one variable to another
.SH SYNOPSIS







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: UpVar.3,v 1.1.2.1 1998/09/24 23:58:28 stanton Exp $
'\" 
.so man.macros
.TH Tcl_UpVar 3 7.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_UpVar, Tcl_UpVar2 \- link one variable to another
.SH SYNOPSIS

Added 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
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
'\"
'\" 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.1.2.2 1998/10/21 20:21:32 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 *
\fBTcl_UtfFindFirst\fR(\fIsrc, ch\fR)
.sp
char *
\fBTcl_UtfFindLast\fR(\fIsrc, ch\fR)
.sp
char *
\fBTcl_UtfNext\fR(\fIsrc\fR)
.sp
char *
\fBTcl_UtfPrev\fR(\fIsrc, start\fR)
.sp
Tcl_UniChar
\fBTcl_UniCharAtIndex\fR(\fIsrc, index\fR)
.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.
.AP char *dst out
Buffer in which the bytes represented by the backslash sequence are stored.
At most TCL_UTF_MAX bytes are stored in the buffer.
.BE

.SH DESCRIPTION
.PP
These routines convert between UTF-8 strings and Tcl_UniChars.  A
Tcl_UniChar is a Unicode character represented as an unsigned, fixed-size
quantity.  A UTF-8 character is a Unicode character represented as
a varying-length sequence of up to TCL_UTF_MAX bytes.  A multibyte UTF-8
sequence consists of a lead byte followed by some number of trail bytes.
.PP
\fBTCL_UTF_MAX\fR is the maximum number of bytes that it takes to
represent one Unicode character in the UTF-8 representation.
.PP
\fBTcl_UniCharToUtf\fR stores the Tcl_UniChar \fIch\fR as a UTF-8 string
in starting at \fIbuf\fR.  The return value is the number of bytes stored
in \fIbuf\fR.
.PP
\fBTcl_UtfToUniChar\fR reads one UTF-8 character starting at \fIsrc\fR
and stores it as a Tcl_UniChar in \fI*chPtr\fR.  The return value is the
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.
.PP
\fBTcl_NumUtfChars\fR corresponds to \fBstrlen\fR for UTF-8 strings.  It
returns the number of Tcl_UniChars that are represented by the UTF-8 string
\fIsrc\fR.  The length of the source string is \fIlen\fR bytes.  If the
length is negative, all bytes up to the first NULL byte are used.
.PP
\fBTcl_UtfFindFirst\fR corresponds to \fBstrchr\fR for UTF-8 strings.  It
returns a pointer to the first occurance of the Tcl_UniChar \fIch\fR
in the NULL-terminated UTF-8 string \fIsrc\fR.  The NULL terminator is
considered part of the UTF-8 string.  
.PP
\fBTcl_UtfFindLast\fR corresponds to \fBstrrchr\fR for UTF-8 strings.  It
returns a pointer to the last occurance of the Tcl_UniChar \fIch\fR
in the NULL terminated UTF-8 string \fIsrc\fR.  The NULL terminator is
considered part of the UTF-8 string.  
.PP
Given \fIsrc\fR, a pointer to some location in a UTF-8 string,
\fBTcl_UtfNext\fR returns a pointer to the next UTF-8 character in the
string.  The caller must not ask for the next character after the last
character in the string.
.PP
Given \fIsrc\fR, a pointer to some location in a UTF-8 string,
\fBTcl_UtfPrev\fR returns a pointer to the previous UTF-8 character in the
string.  This function will not back up to a position before \fIstart\fR,
the start of the UTF-8 string.  If \fIsrc\fR was already at \fIstart\fR, the
return value will be \fIstart\fR.
.PP
\fBTcl_UniCharAtIndex\fR corresponds to a C string array dereference or the
Pascal Ord() function.  It returns the Tcl_UniChar represented at the
specified character (not byte) \fIindex\fR in the UTF-8 string
\fIsrc\fR.  The source string must contain at least \fIindex\fR
characters.
.PP
\fBTcl_UtfAtIndex\fR returns a pointer to the specified character (not
byte) \fIindex\fR in the UTF-8 string \fIsrc\fR.  The source string must
contain at least \fIindex\fR characters.  This is equivalent to calling 
\fBTcl_UtfNext\fR \fIindex\fR times.
.PP
\fBTcl_UtfBackslash\fR is a utility procedure used by several of the Tcl
commands.  It parses a backslash sequence and stores the properly formed
UTF-8 character represented by the backslash sequence in the output
buffer \fIdst\fR.  At most TCL_UTF_MAX bytes are stored in the buffer.
\fBTcl_UtfBackslash\fR modifies \fI*readPtr\fR to contain the number
of bytes in the backslash sequence, including the backslash character.
The return value is the number of bytes stored in the output buffer.
.PP
See the \fBTcl\fR manual entry for information on the valid backslash
sequences.  All of the sequences described in the Tcl manual entry are
supported by \fBTcl_UtfBackslash\fR.

.SH KEYWORDS
utf, unicode, backslash

Changes to doc/WrongNumArgs.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) @(#) WrongNumArgs.3 1.5 97/07/30 16:20:07
'\" 
.so man.macros
.TH Tcl_WrongNumArgs 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_WrongNumArgs \- generate standard error message for wrong number of arguments
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: WrongNumArgs.3,v 1.1.2.1 1998/09/24 23:58:28 stanton Exp $
'\" 
.so man.macros
.TH Tcl_WrongNumArgs 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_WrongNumArgs \- generate standard error message for wrong number of arguments
.SH SYNOPSIS

Changes to doc/after.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) after.n 1.4 96/03/25 20:09:33
'\" 
.so man.macros
.TH after n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
after \- Execute a command after a time delay







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: after.n,v 1.1.2.1 1998/09/24 23:58:28 stanton Exp $
'\" 
.so man.macros
.TH after n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
after \- Execute a command after a time delay

Changes to doc/append.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) append.n 1.6 96/03/25 20:09:44
'\" 
.so man.macros
.TH append n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
append \- Append to variable







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: append.n,v 1.1.2.1 1998/09/24 23:58:28 stanton Exp $
'\" 
.so man.macros
.TH append n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
append \- Append to variable

Changes to doc/array.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) array.n 1.9 97/10/29 14:10:13
'\" 
.so man.macros
.TH array n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
array \- Manipulate array variables







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: array.n,v 1.1.2.1 1998/09/24 23:58:28 stanton Exp $
'\" 
.so man.macros
.TH array n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
array \- Manipulate array variables

Changes to doc/bgerror.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) bgerror.n 1.5 97/08/04 17:49:35
'\" 
.so man.macros
.TH bgerror n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bgerror \- Command invoked to process background errors







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: bgerror.n,v 1.1.2.1 1998/09/24 23:58:28 stanton Exp $
'\" 
.so man.macros
.TH bgerror n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bgerror \- Command invoked to process background errors

Changes to doc/binary.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) binary.n 1.7 97/11/11 19:08:47
'\" 
.so man.macros
.TH binary n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
binary \- Insert and extract fields from binary strings






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: binary.n,v 1.1.2.3 1999/04/09 19:11:26 surles Exp $
'\" 
.so man.macros
.TH binary n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
binary \- Insert and extract fields from binary strings
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
\fIcount\fR is omitted, then one digit will be formatted.  If the
number of digits formatted does not end at a byte boundary, the
remaining bits of the last byte will be zeros.  For example,
.RS
.CS
\fBbinary format h3h* AB def\fR
.CE
will return a string equivalent to \fB\\xba\\xed\\x0f\fR.
.RE
.IP \fBH\fR 5
This form is the same as \fBh\fR except that the digits are stored in
high-to-low order within each byte.  For example,
.RS
.CS
\fBbinary format H3H* ab DEF\fR
.CE
will return a string equivalent to \fB\\xab\\xde\\xf0\fR.
.RE
.IP \fBc\fR 5
Stores one or more 8-bit integer values in the output string.  If no
\fIcount\fR is specified, then \fIarg\fR must consist of an integer
value; otherwise \fIarg\fR must consist of a list containing at least
\fIcount\fR integer elements.  The low-order 8 bits of each integer
are stored as a one-byte value at the cursor position.  If \fIcount\fR
is \fB*\fR, then all of the integers in the list are formatted.  If
the number of elements in the list is fewer than \fIcount\fR, then an
error is generated.  If the number of elements in the list is greater
than \fIcount\fR, then the extra elements are ignored.  For example,
.RS
.CS
\fBbinary format c3cc* {3 -3 128 1} 257 {2 5}\fR
.CE
will return a string equivalent to
\fB\\x03\\xfd\\x80\\x01\\x02\\x05\fR, whereas
.CS
\fBbinary format c {2 5}\fR
.CE
will generate an error.
.RE
.IP \fBs\fR 5
This form is the same as \fBc\fR except that it stores one or more







|








|













|


|







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
\fIcount\fR is omitted, then one digit will be formatted.  If the
number of digits formatted does not end at a byte boundary, the
remaining bits of the last byte will be zeros.  For example,
.RS
.CS
\fBbinary format h3h* AB def\fR
.CE
will return a string equivalent to \fB\\xba\\x00\\xed\\x0f\fR.
.RE
.IP \fBH\fR 5
This form is the same as \fBh\fR except that the digits are stored in
high-to-low order within each byte.  For example,
.RS
.CS
\fBbinary format H3H* ab DEF\fR
.CE
will return a string equivalent to \fB\\xab\\x00\\xde\\xf0\fR.
.RE
.IP \fBc\fR 5
Stores one or more 8-bit integer values in the output string.  If no
\fIcount\fR is specified, then \fIarg\fR must consist of an integer
value; otherwise \fIarg\fR must consist of a list containing at least
\fIcount\fR integer elements.  The low-order 8 bits of each integer
are stored as a one-byte value at the cursor position.  If \fIcount\fR
is \fB*\fR, then all of the integers in the list are formatted.  If
the number of elements in the list is fewer than \fIcount\fR, then an
error is generated.  If the number of elements in the list is greater
than \fIcount\fR, then the extra elements are ignored.  For example,
.RS
.CS
\fBbinary format c3cc* {3 -3 128 1} 260 {2 5}\fR
.CE
will return a string equivalent to
\fB\\x03\\xfd\\x80\\x04\\x02\\x05\fR, whereas
.CS
\fBbinary format c {2 5}\fR
.CE
will generate an error.
.RE
.IP \fBs\fR 5
This form is the same as \fBc\fR except that it stores one or more
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
the cursor position with the least significant byte stored first.  For
example,
.RS
.CS
\fBbinary format i3 {3 -3 65536 1}\fR
.CE
will return a string equivalent to 
\fB\\x03\\x00\\x00\\x00\\xfd\\xff\\xff\\xff\\x00\\x00\\x10\\x00\fR.
.RE
.IP \fBI\fR 5
This form is the same as \fBi\fR except that it stores one or more one
or more 32-bit integers in big-endian byte order in the output string.
For example,
.RS
.CS
\fBbinary format I3 {3 -3 65536 1}\fR
.CE
will return a string equivalent to 
\fB\\x00\\x00\\x00\\x03\\xff\\xff\\xff\\xfd\\x00\\x10\\x00\\x00\fR.
.RE
.IP \fBf\fR 5
This form is the same as \fBc\fR except that it stores one or more one
or more single-precision floating in the machine's native
representation in the output string.  This representation is not
portable across architectures, so it should not be used to communicate
floating point numbers across the network.  The size of a floating







|










|







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
the cursor position with the least significant byte stored first.  For
example,
.RS
.CS
\fBbinary format i3 {3 -3 65536 1}\fR
.CE
will return a string equivalent to 
\fB\\x03\\x00\\x00\\x00\\xfd\\xff\\xff\\xff\\x00\\x00\\x01\\x00\fR
.RE
.IP \fBI\fR 5
This form is the same as \fBi\fR except that it stores one or more one
or more 32-bit integers in big-endian byte order in the output string.
For example,
.RS
.CS
\fBbinary format I3 {3 -3 65536 1}\fR
.CE
will return a string equivalent to 
\fB\\x00\\x00\\x00\\x03\\xff\\xff\\xff\\xfd\\x00\\x01\\x00\\x00\fR
.RE
.IP \fBf\fR 5
This form is the same as \fBc\fR except that it stores one or more one
or more single-precision floating in the machine's native
representation in the output string.  This representation is not
portable across architectures, so it should not be used to communicate
floating point numbers across the network.  The size of a floating
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
stored in \fBvar1\fR and \fBvar2\fR left unmodified.
.RE
.IP \fBA\fR 5
This form is the same as \fBa\fR, except trailing blanks and nulls are stripped from
the scanned value before it is stored in the variable.  For example,
.RS
.CS
\fBbinary scan "abc efghi  \\000" a* var1\fR
.CE
will return \fB1\fR with \fBabc efghi\fR stored in \fBvar1\fR.
.RE
.IP \fBb\fR 5
The data is turned into a string of \fIcount\fR binary digits in
low-to-high order represented as a sequence of ``1'' and ``0''
characters.  The data bytes are scanned in first to last order with
the bits being taken in low-to-high order within each byte.  Any extra
bits in the last byte are ignored.  If \fIcount\fR is \fB*\fR, then
all of the remaining bits in \fBstring\fR will be scanned.  If
\fIcount\fR is omitted, then one bit will be scanned.  For example,
.RS
.CS
\fBbinary scan \\x07\\x87\\x05 b5b* var1 var2\fR
.CE
will return \fB2\fR with \fB11100\fR stored in \fBvar1\fR and
\fB1110000110100000\fR stored in \fBvar2\fR.
.RE
.IP \fBB\fR 5
This form is the same as \fBB\fR, except the bits are taken in
high-to-low order within each byte.  For example,
.RS
.CS
\fBbinary scan \\x70\\x87\\x05 b5b* var1 var2\fR
.CE
will return \fB2\fR with \fB01110\fR stored in \fBvar1\fR and
\fB1000011100000101\fR stored in \fBvar2\fR.
.RE
.IP \fBh\fR 5
The data is turned into a string of \fIcount\fR hexadecimal digits in
low-to-high order represented as a sequence of characters in the set







|



















|



|







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
stored in \fBvar1\fR and \fBvar2\fR left unmodified.
.RE
.IP \fBA\fR 5
This form is the same as \fBa\fR, except trailing blanks and nulls are stripped from
the scanned value before it is stored in the variable.  For example,
.RS
.CS
\fBbinary scan "abc efghi  \\000" A* var1\fR
.CE
will return \fB1\fR with \fBabc efghi\fR stored in \fBvar1\fR.
.RE
.IP \fBb\fR 5
The data is turned into a string of \fIcount\fR binary digits in
low-to-high order represented as a sequence of ``1'' and ``0''
characters.  The data bytes are scanned in first to last order with
the bits being taken in low-to-high order within each byte.  Any extra
bits in the last byte are ignored.  If \fIcount\fR is \fB*\fR, then
all of the remaining bits in \fBstring\fR will be scanned.  If
\fIcount\fR is omitted, then one bit will be scanned.  For example,
.RS
.CS
\fBbinary scan \\x07\\x87\\x05 b5b* var1 var2\fR
.CE
will return \fB2\fR with \fB11100\fR stored in \fBvar1\fR and
\fB1110000110100000\fR stored in \fBvar2\fR.
.RE
.IP \fBB\fR 5
This form is the same as \fBb\fR, except the bits are taken in
high-to-low order within each byte.  For example,
.RS
.CS
\fBbinary scan \\x70\\x87\\x05 B5B* var1 var2\fR
.CE
will return \fB2\fR with \fB01110\fR stored in \fBvar1\fR and
\fB1000011100000101\fR stored in \fBvar2\fR.
.RE
.IP \fBh\fR 5
The data is turned into a string of \fIcount\fR hexadecimal digits in
low-to-high order represented as a sequence of characters in the set
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
\fBbinary scan \\x07\\x86\\x05 h3h* var1 var2\fR
.CE
will return \fB2\fR with \fB706\fR stored in \fBvar1\fR and
\fB50\fR stored in \fBvar2\fR.
.RE
.IP \fBH\fR 5
This form is the same as \fBh\fR, except the digits are taken in
low-to-high order within each byte.  For example,
.RS
.CS
\fBbinary scan \\x07\\x86\\x05 H3H* var1 var2\fR
.CE
will return \fB2\fR with \fB078\fR stored in \fBvar1\fR and
\fB05\fR stored in \fBvar2\fR.
.RE







|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
\fBbinary scan \\x07\\x86\\x05 h3h* var1 var2\fR
.CE
will return \fB2\fR with \fB706\fR stored in \fBvar1\fR and
\fB50\fR stored in \fBvar2\fR.
.RE
.IP \fBH\fR 5
This form is the same as \fBh\fR, except the digits are taken in
high-to-low order within each byte.  For example,
.RS
.CS
\fBbinary scan \\x07\\x86\\x05 H3H* var1 var2\fR
.CE
will return \fB2\fR with \fB078\fR stored in \fBvar1\fR and
\fB05\fR stored in \fBvar2\fR.
.RE

Changes to doc/break.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) break.n 1.7 96/10/09 08:29:26
'\" 
.so man.macros
.TH break n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
break \- Abort looping command







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: break.n,v 1.1.2.1 1998/09/24 23:58:28 stanton Exp $
'\" 
.so man.macros
.TH break n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
break \- Abort looping command

Changes to doc/case.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) case.n 1.8 96/03/25 20:10:49
'\" 
.so man.macros
.TH case n 7.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
case \- Evaluate one of several scripts, depending on a given value







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: case.n,v 1.1.2.1 1998/09/24 23:58:29 stanton Exp $
'\" 
.so man.macros
.TH case n 7.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
case \- Evaluate one of several scripts, depending on a given value

Changes to doc/catch.n.

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
'\"
'\" Copyright (c) 1993-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) catch.n 1.6 96/03/25 20:11:08
'\" 
.so man.macros
.TH catch n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
catch \- Evaluate script and trap exceptional returns
.SH SYNOPSIS
\fBcatch\fI script \fR?\fIvarName\fR?
.BE

.SH DESCRIPTION
.PP
The \fBcatch\fR command may be used to prevent errors from aborting
command interpretation.  \fBCatch\fR calls the Tcl interpreter recursively
to execute \fIscript\fR, and always returns a TCL_OK code, regardless of
any errors that might occur while executing \fIscript\fR.  The return
value from \fBcatch\fR is a decimal string giving the

code returned by the Tcl interpreter after executing \fIscript\fR.
This will be \fB0\fR (TCL_OK) if there were no errors in \fIscript\fR;
otherwise
it will have a non-zero value corresponding to one of the exceptional
return codes (see tcl.h for the definitions of code values).  If the
\fIvarName\fR argument is given, then it gives the name of a variable;


\fBcatch\fR will set the variable to the string returned
from \fIscript\fR (either a result or an error message).
.PP
Note that \fBcatch\fR catches all exceptions, including those
generated by \fBbreak\fR and \fBcontinue\fR as well as errors.































.SH KEYWORDS
catch, error







|


|










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


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



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
'\"
'\" Copyright (c) 1993-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: catch.n,v 1.1.2.3 1999/04/13 00:01:59 surles Exp $
'\" 
.so man.macros
.TH catch n "8.0" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
catch \- Evaluate script and trap exceptional returns
.SH SYNOPSIS
\fBcatch\fI script \fR?\fIvarName\fR?
.BE

.SH DESCRIPTION
.PP
The \fBcatch\fR command may be used to prevent errors from aborting command
interpretation.  \fBCatch\fR calls the Tcl interpreter recursively to
execute \fIscript\fR, and always returns without raising an error,
regardless of any errors that might occur while executing \fIscript\fR.

.PP
If \fIscript\fR raises an error, \fBcatch\fR will return a non-zero integer


value corresponding to one of the exceptional return codes (see tcl.h
for the definitions of code values).  If the \fIvarName\fR argument is
given, then the variable it names is set to the error message from
interpreting \fIscript\fR.
.PP
If \fIscript\fR does not raise an error, \fBcatch\fR will return 0
(TCL_OK) and set the variable to the value returned from \fIscript\fR.
.PP
Note that \fBcatch\fR catches all exceptions, including those
generated by \fBbreak\fR and \fBcontinue\fR as well as errors.  The
only errors that are not caught are syntax errors found when the
script is compiled.  This is because the catch command only catches
errors during runtime.  When the catch statement is compiled, the
script is compiled as well and any syntax errors will generate a Tcl
error. 

.SH EXAMPLES

The \fBcatch\fR command may be used in an \fBif\fR to branch based on
the success of a script.

.DS
.CS
if { [catch {open $someFile w} fid] } {
    puts stderr "Could not open $someFile for writing\\n$fid"
    exit 1
}
.CE
.DE
The \fBcatch\fR command will not catch compiled syntax errors.  The
first time proc \fBfoo\fR is called, the body will be compiled and a
Tcl error will be generated. 

.DS
.CS
proc foo {} {
    catch {expr {1 +- }}
}
.CE
.DE

.SH KEYWORDS
catch, error

Changes to doc/cd.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) cd.n 1.6 96/03/28 08:40:52
'\" 
.so man.macros
.TH cd n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
cd \- Change working directory







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: cd.n,v 1.1.2.1 1998/09/24 23:58:29 stanton Exp $
'\" 
.so man.macros
.TH cd n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
cd \- Change working directory

Changes to doc/clock.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
'\"
'\" This documentation is derived from the time and date facilities of
'\" TclX, by Mark Diekhans and Karl Lehenbauer.
'\" 
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) clock.n 1.18 97/09/10 13:31:23
'\" 
.so man.macros
.TH clock n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
clock \- Obtain and manipulate time










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
'\"
'\" This documentation is derived from the time and date facilities of
'\" TclX, by Mark Diekhans and Karl Lehenbauer.
'\" 
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: clock.n,v 1.1.2.1 1998/09/24 23:58:29 stanton Exp $
'\" 
.so man.macros
.TH clock n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
clock \- Obtain and manipulate time

Changes to doc/close.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) close.n 1.11 97/08/22 18:50:48
'\" 
.so man.macros
.TH close n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
close \- Close an open channel.







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: close.n,v 1.1.2.1 1998/09/24 23:58:29 stanton Exp $
'\" 
.so man.macros
.TH close n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
close \- Close an open channel.

Changes to doc/concat.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) concat.n 1.8 96/08/26 12:59:54
'\" 
.so man.macros
.TH concat n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
concat \- Join lists together







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: concat.n,v 1.1.2.1 1998/09/24 23:58:29 stanton Exp $
'\" 
.so man.macros
.TH concat n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
concat \- Join lists together

Changes to doc/continue.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) continue.n 1.7 96/10/09 08:29:27
'\" 
.so man.macros
.TH continue n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
continue \- Skip to the next iteration of a loop







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: continue.n,v 1.1.2.1 1998/09/24 23:58:29 stanton Exp $
'\" 
.so man.macros
.TH continue n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
continue \- Skip to the next iteration of a loop

Added doc/dde.n.

























































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
'\"
'\" 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: dde.n,v 1.1.2.1 1999/04/02 23:48:32 redman Exp $
'\" 
.so man.macros
.TH dde n 8.1 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
dde \- Execute a Dynamic Data Exchange command
.SH SYNOPSIS
.sp
\fBpackage require dde 1.0\fR
.sp
\fBdde \fIservername \fR?\fItopic\fR?
.sp
\fBdde ?\-async?\fR \fIcommand service topic \fR?\fIdata\fR?
.BE

.SH DESCRIPTION
.PP
This command allows an application to send Dynamic Data Exchange (DDE)
command when running under Microsoft Windows. Dynamic Data Exchange is
a mechanism where applications can exchange raw data. Each DDE
transaction needs a \fIservice name\fR and a \fItopic\fR. Both the
\fIservice name\fR and \fItopic\fR are application defined; Tcl uses
the service name \fBTclEval\fR, while the topic name is the name of the
interpreter given by \fBdde servername\fR. Other applications have their
own \fIservice names\fR and \fItopics\fR. For instance, Microsoft Excel
has the service name \fBExcel\fR.
.PP
The only option to the \fBdde\fR command is:
.TP
\fB\-async\fR
Requests asynchronous invocation.  This is valid only for the
\fBexecute\fR subcommand. Normally, the \fBdde execute\fR subcommand
waits until the command completes, returning appropriate error
messages. When the \fB\-async\fR option is used, the command returns
immediately, and no error information is available.
.SH "DDE COMMANDS"
.PP
The following commands are a subset of the full Dynamic Data Exchange
set of commands.
.TP
\fBdde servername \fR?\fItopic\fR?
\fBdde servername\fR registers the interpreter as a DDE server with
the service name TclEval and the topic name specified byt \fItopic\fR.
If no \fItopic\fR is given, \fBdde servername\fR returns the name
of the current topic or the empty string if it is not registered as a service.
.TP
\fBdde execute \fIservice topic data\fR
\fBdde execute\fR takes the \fIdata\fR and sends it to the server
indicated by \fIservice\fR with the topic indicated by
\fItopic\fR. Typically, \fIservice\fR is the name of an application,
and \fItopic\fR is a file to work on.  The \fIdata\fR field is given
to the remote application. Typically, the application treats the
\fIdata\fR field as a script, and the script is run in the
application. The command returns an error if the script did not
run. If the \fB\-async\fR flag was used, the command
returns immediately with no error.
.TP
\fBdde request \fIservice topic item\fR
\fBdde request\fR is typically used to get the value of something; the
value of a cell in Microsoft Excel or the text of a selection in
Microsoft Word. \fIservice\fR is typically the name of an application,
\fItopic\fR is typically the name of the file, and \fIitem\fR is
application-specific. The command returns the value of \fIitem\fR as
defined in the application.
.TP
\fBdde services \fIservice topic\fR
\fBdde services\fR returns a list of service-topic pairs that
currently exist on the machine. If \fIservice\fR and \fItopic\fR are
both null strings ({}), then all service-topic pairs currently
available on the system are returned. If \fIservice\fR is null and
\fItopic\fR is not, then all services with the specified topic are
returned. If \fIservice\fR is not null and \fItopic\fR is, all topics
for a given service are returned. If both are not null, if that
service-topic pair currently exists, it is returned; otherwise, null
is returned.
.TP
\fBdde eval \fItopic cmd \fR?\fIarg arg ...\fR?
\fBdde eval\fR evaluates a command and its arguments using the
interpreter specified by \fItopic\fR. The DDE service must be the
"TclEval" service.  This command can be used to replace send on Windows.
.SH "DDE AND TCL"
A Tcl interpreter always has a service name of "TclEval". Each
different interp of all running Tcl applications should a unique
name specified by \fBdde servername\fR. Each interp is available as a
DDE topic only if the \fBdde servername\fR command was used to set the
name of the topic for each interp. So a \fBdde services TclEval {}\fR
command will return a list of service-topic pairs, where each of the
currently running interps will be a topic.
.PP
When Tcl processes a \fBdde execute\fR command, the data for the
execute is run as a script in the interp named by the topic of the
\fBdde execute\fR command.
.PP
When Tcl processes a \fBdde request\fR command, it returns the value of
the variable given in the dde command in the context of the interp
named by the dde topic. Tcl reserves the variable "$TCLEVAL$EXECUTE$RESULT"
for internal use, and \fBdde request\fR commands for that variable
will give unpredictable results.
.PP
An external application which wishes to run a script in Tcl should have
that script store its result in a variable, run the \fBdde execute\fR
command, and the run \fBdde request\fR to get the value of the
variable.
.PP
When using DDE, be careful to ensure that the event queue is flushed
using either \fBupdate\fR or \fBvwait\fR.  This happens by default
when using \fBwish\fR unless a blocking command is called (such as \fBexec\fR
without adding the \fB&\fR to place the process in the background).
If for any reason the event queue is not flushed, DDE commands may
hang until the event queue is flushed.  This can create a deadlock
situation.
.SH KEYWORDS
application, dde, name, remote execution
.SH "SEE ALSO"
tk, winfo, send

Added doc/encoding.n.































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
'\"
'\" 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: encoding.n,v 1.1.2.1 1998/10/21 20:39:58 stanton Exp $
'\" 
.so man.macros
.TH encoding n "8.1" Tcl "Tcl Built-In Commands"
.BS
.SH NAME
encoding \- Manipulate encodings
.SH SYNOPSIS
\fBencoding \fIoption\fR ?\fIarg arg ...\fR?
.BE

.SH INTRODUCTION
.PP
Strings in Tcl are encoded using 16-bit Unicode characters.  Different
operating system interfaces or applications may generate strings in
other encodings such as Shift-JIS.  The \fBencoding\fR command helps
to bridge the gap between Unicode and these other formats.

.SH DESCRIPTION
.PP
Performs one of several encoding related operations, depending on
\fIoption\fR.  The legal \fIoption\fRs are:
.TP
\fBencoding convertfrom ?\fIencoding\fR? \fIdata\fR
Convert \fIdata\fR to Unicode from the specified \fIencoding\fR.  The
characters in \fIdata\fR are treated as binary data where the lower
8-bits of each character is taken as a single byte.  The resulting
sequence of bytes is treated as a string in the specified
\fIencoding\fR.  If \fIencoding\fR is not specified, the current
system encoding is used.
.TP
\fBencoding convertto ?\fIencoding\fR? \fIstring\fR
Convert \fIstring\fR from Unicode to the specified \fIencoding\fR.
The result is a sequence of bytes that represents the converted
string.  Each byte is stored in the lower 8-bits of a Unicode
character.  If \fIencoding\fR is not specified, the current
system encoding is used.
.TP
\fBencoding names\fR
Returns a list containing the names of all of the encodings that are
currently available. 
.TP
\fBencoding system\fR ?\fIencoding\fR?
Set the system encoding to \fIencoding\fR. If \fIencoding\fR is
omitted then the command returns the current system encoding.  The
system encoding is used whenever Tcl passes strings to system calls.

.SH EXAMPLE
.PP
It is common practice to write script files using a text editor that
produces output in the euc-jp encoding, which represents the ASCII
characters as singe bytes and Japanese characters as two bytes.  This
makes it easy to embed literal strings that correspond to non-ASCII
characters by simply typing the strings in place in the script.
However, because the \fBsource\fR command always reads files using the
ISO8859-1 encoding, Tcl will treat each byte in the file as a separate
character that maps to the 00 page in Unicode.  The
resulting Tcl strings will not contain the expected Japanese
characters.  Instead, they will contain a sequence of Latin-1
characters that correspond to the bytes of the original string.  The
\fBencoding\fR command can be used to convert this string to the
expected Japanese Unicode characters.  For example,
.CS
	set s [encoding convertfrom euc-jp "\\xA4\\xCF"]
.CE
would return the Unicode string "\\u306F", which is the Hiragana
letter HA.

.SH "SEE ALSO"
Tcl_GetEncoding

.SH KEYWORDS
encoding

Changes to doc/eof.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) eof.n 1.8 96/02/15 20:01:59
'\" 
.so man.macros
.TH eof n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
eof \- Check for end of file condition on channel







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: eof.n,v 1.1.2.1 1998/09/24 23:58:29 stanton Exp $
'\" 
.so man.macros
.TH eof n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
eof \- Check for end of file condition on channel

Changes to doc/error.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) error.n 1.7 96/03/25 20:12:35
'\" 
.so man.macros
.TH error n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
error \- Generate an error







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: error.n,v 1.1.2.1 1998/09/24 23:58:29 stanton Exp $
'\" 
.so man.macros
.TH error n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
error \- Generate an error

Changes to doc/eval.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) eval.n 1.5 96/03/25 20:12:53
'\" 
.so man.macros
.TH eval n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
eval \- Evaluate a Tcl script







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: eval.n,v 1.1.2.1 1998/09/24 23:58:30 stanton Exp $
'\" 
.so man.macros
.TH eval n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
eval \- Evaluate a Tcl script

Changes to doc/exec.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) exec.n 1.17 96/09/18 15:21:17
'\" 
.so man.macros
.TH exec n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
exec \- Invoke subprocess(es)







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: exec.n,v 1.1.2.2 1998/09/24 23:58:30 stanton Exp $
'\" 
.so man.macros
.TH exec n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
exec \- Invoke subprocess(es)
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
Additionally, when calling a 16-bit DOS or Windows 3.X application, all path
names must use the short, cryptic, path format (e.g., using ``applba~1.def''
instead of ``applbakery.default'').
.sp
Two or more forward or backward slashes in a row in a path refer to a
network path.  For example, a simple concatenation of the root directory
\fBc:/\fR with a subdirectory \fB/windows/system\fR will yield
\fBc://windows/system\fR (two slashes together), which refers to the
directory \fB/system\fR on the machine \fBwindows\fR (and the \fBc:/\fR is
ignored), and is not equivalent to \fBc:/windows/system\fR, which describes
a directory on the current computer.

.TP
\fBWindows NT\fR
.
When attempting to execute an application, \fBexec\fR first searches for the
name as it was specified.  Then, in order, \fB.com\fR, \fB.exe\fR, and \fB.bat\fR 
are appended to the end of the specified name and it searches for
the longer name.  If a directory name was not specified as part of the







|
|
|
|
>







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
Additionally, when calling a 16-bit DOS or Windows 3.X application, all path
names must use the short, cryptic, path format (e.g., using ``applba~1.def''
instead of ``applbakery.default'').
.sp
Two or more forward or backward slashes in a row in a path refer to a
network path.  For example, a simple concatenation of the root directory
\fBc:/\fR with a subdirectory \fB/windows/system\fR will yield
\fBc://windows/system\fR (two slashes together), which refers to the mount
point called \fBsystem\fR on the machine called \fBwindows\fR (and the
\fBc:/\fR is ignored), and is not equivalent to \fBc:/windows/system\fR,
which describes a directory on the current computer.  The \fBfile join\fR
command should be used to concatenate path components.
.TP
\fBWindows NT\fR
.
When attempting to execute an application, \fBexec\fR first searches for the
name as it was specified.  Then, in order, \fB.com\fR, \fB.exe\fR, and \fB.bat\fR 
are appended to the end of the specified name and it searches for
the longer name.  If a directory name was not specified as part of the
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
.sp
In order to execute the shell builtin commands like \fBdir\fR and \fBcopy\fR,
the caller must prepend ``\fBcommand.com /c\0\fR'' to the desired command.
.sp
Once a 16-bit DOS application has read standard input from a console and 
then quit, all subsequently run 16-bit DOS applications will see the 
standard input as already closed.  32-bit applications do not have this
problem and will run correctly even after a 16-bit DOS application thinks 
that standard input is closed.  There is no known workaround for this bug
at this time.
.sp
Redirection between the \fBNUL:\fR device and a 16-bit application does not
always work.  When redirecting from \fBNUL:\fR, some applications may hang,
others will get an infinite stream of ``0x01'' bytes, and some will actually
correctly get an immediate end-of-file; the behavior seems to depend upon 
something compiled into the application itself.  When redirecting greater than
4K or so to \fBNUL:\fR, some applications will hang.  The above problems do not
happen with 32-bit applications.  
.sp
All DOS 16-bit applications are run synchronously.  All standard input from
a pipe to a 16-bit DOS application is collected into a temporary file; the
other end of the pipe must be closed before the 16-bit DOS application
begins executing.  All standard output or error from a 16-bit DOS
application to a pipe is collected into temporary files; the application
must terminate before the temporary files are redirected to the next stage
of the pipeline.  This is due to a workaround for a Windows 95 bug in the 
implementation of pipes, and is how the Windows 95 command line interpreter
handles pipes itself.
.sp
Certain applications, such as \fBcommand.com\fR, should not be executed
interactively.  Applications which directly access the console window,
rather than reading from their standard input and writing to their standard
output may fail, hang Tcl, or even hang the system if their own private
console window is not available to them.







|

















|
|







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
.sp
In order to execute the shell builtin commands like \fBdir\fR and \fBcopy\fR,
the caller must prepend ``\fBcommand.com /c\0\fR'' to the desired command.
.sp
Once a 16-bit DOS application has read standard input from a console and 
then quit, all subsequently run 16-bit DOS applications will see the 
standard input as already closed.  32-bit applications do not have this
problem and will run correctly, even after a 16-bit DOS application thinks 
that standard input is closed.  There is no known workaround for this bug
at this time.
.sp
Redirection between the \fBNUL:\fR device and a 16-bit application does not
always work.  When redirecting from \fBNUL:\fR, some applications may hang,
others will get an infinite stream of ``0x01'' bytes, and some will actually
correctly get an immediate end-of-file; the behavior seems to depend upon 
something compiled into the application itself.  When redirecting greater than
4K or so to \fBNUL:\fR, some applications will hang.  The above problems do not
happen with 32-bit applications.  
.sp
All DOS 16-bit applications are run synchronously.  All standard input from
a pipe to a 16-bit DOS application is collected into a temporary file; the
other end of the pipe must be closed before the 16-bit DOS application
begins executing.  All standard output or error from a 16-bit DOS
application to a pipe is collected into temporary files; the application
must terminate before the temporary files are redirected to the next stage
of the pipeline.  This is due to a workaround for a Windows 95 bug in the
implementation of pipes, and is how the standard Windows 95 DOS shell
handles pipes itself.
.sp
Certain applications, such as \fBcommand.com\fR, should not be executed
interactively.  Applications which directly access the console window,
rather than reading from their standard input and writing to their standard
output may fail, hang Tcl, or even hang the system if their own private
console window is not available to them.

Changes to doc/exit.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) exit.n 1.6 96/03/25 20:13:32
'\" 
.so man.macros
.TH exit n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
exit \- End the application







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: exit.n,v 1.1.2.1 1998/09/24 23:58:30 stanton Exp $
'\" 
.so man.macros
.TH exit n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
exit \- End the application

Changes to doc/expr.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) expr.n 1.28 97/09/18 18:21:30
'\" 
.so man.macros
.TH expr n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
expr \- Evaluate an expression







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: expr.n,v 1.1.2.1 1998/09/24 23:58:30 stanton Exp $
'\" 
.so man.macros
.TH expr n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
expr \- Evaluate an expression

Changes to doc/fblocked.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\" 
'\" Copyright (c) 1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\" SCCS: @(#) fblocked.n 1.6 96/02/23 13:46:30
.so man.macros
.TH fblocked n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fblocked \- Test whether the last input operation exhausted all available input
.SH SYNOPSIS






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\" 
'\" Copyright (c) 1996 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: fblocked.n,v 1.1.2.1 1998/09/24 23:58:30 stanton Exp $
.so man.macros
.TH fblocked n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fblocked \- Test whether the last input operation exhausted all available input
.SH SYNOPSIS

Changes to doc/fconfigure.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'\" 
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\" SCCS: @(#) fconfigure.n 1.23 96/04/16 08:20:07
'\"
.so man.macros
.TH fconfigure n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fconfigure \- Set and get options on a channel
.SH SYNOPSIS
.nf
\fBfconfigure \fIchannelId\fR






|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'\" 
'\" Copyright (c) 1995-1996 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: fconfigure.n,v 1.1.2.2 1998/09/24 23:58:30 stanton Exp $
'\"
.so man.macros
.TH fconfigure n 8.1 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fconfigure \- Set and get options on a channel
.SH SYNOPSIS
.nf
\fBfconfigure \fIchannelId\fR
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

\fBread\fR, \fBputs\fR, \fBflush\fR, and \fBclose\fR commands;
see the documentation for those commands for details.
For nonblocking mode to work correctly, the application must be
using the Tcl event loop (e.g. by calling \fBTcl_DoOneEvent\fR or
invoking the \fBvwait\fR command).
.TP
\fB\-buffering\fR \fInewValue\fR

If \fInewValue\fR is \fBfull\fR then the I/O system will buffer output
until its internal buffer is full or until the \fBflush\fR command is
invoked. If \fInewValue\fR is \fBline\fR, then the I/O system will
automatically flush output for the channel whenever a newline character
is output. If \fInewValue\fR is \fBnone\fR, the I/O system will flush
automatically after every output operation.
The default is for \fB\-buffering\fR to be set to \fBfull\fR except for
channels that connect to terminal-like devices; for these channels the
initial setting is \fBline\fR.
.TP
\fB\-buffersize\fR \fInewSize\fR

\fINewvalue\fR must be an integer; its value is used to set the size of
buffers, in bytes, subsequently allocated for this channel to store input
or output. \fINewvalue\fR must be between ten and one million, allowing
buffers of ten to one million bytes in size.

.TP
























\fB\-eofchar\fR \fIchar\fR
.TP
\fB\-eofchar\fR \fB{\fIinChar outChar\fB}\fR

This option supports DOS file systems that use Control-z (\ex1a) as
an end of file marker.
If \fIchar\fR is not an empty string, then this character signals
end of file when it is encountered during input.
For output, the end of file character is output when
the channel is closed.
If \fIchar\fR is the empty string, then there is no special
end of file character marker.
For read-write channels, a two-element list specifies
the end of file marker for input and output, respectively.
As a convenience, when setting the end-of-file character
for a read-write channel
you can specify a single value that will apply to both reading and writing.
When querying the end-of-file character of a read-write channel,
a two-element list will always be returned.
The default value for \fB\-eofchar\fR is the empty string in all
cases except for files under Windows.  In that case the \fB\-eofchar\fR
is Control-z (\ex1a) for reading and the empty string for writing.
.TP
\fB\-translation\fR \fImode\fR
.TP
\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR

In Tcl scripts the end of a line is always represented using a
single newline character (\en).
However, in actual files and devices the end of a line may be
represented differently on different platforms, or even for
different devices on the same platform.  For example, under UNIX
newlines are used in files, whereas carriage-return-linefeed
sequences are normally used in network connections.
On input (i.e., with \fBgets\fP and \fBread\fP)
the Tcl I/O system automatically translates the external end-of-line
representation into newline characters.
Upon output (i.e., with \fBputs\fP),
the I/O system translates newlines to the external
end-of-line representation.
The default translation mode, \fBauto\fP, handles all the common
cases automatically, but the \fB\-translation\fR option provides
explicit control over the end of line translations.
.RS
.PP
The value associated with \fB\-translation\fR is a single item for
read-only and write-only channels.
The value is a two-element list for read-write channels;
the read translation mode is the first element of the list,
and the write translation mode is the second element.
As a convenience, when setting the translation mode for a read-write channel
you can specify a single value that will apply to both reading and writing.
When querying the translation mode of a read-write channel,
a two-element list will always be returned.
The following values are currently supported:
.TP
\fBauto\fR

As the input translation mode, \fBauto\fR treats any of newline (\fBlf\fP),
carriage return (\fBcr\fP), or carriage return followed by a newline (\fBcrlf\fP)
as the end of line representation.  The end of line representation can
even change from line-to-line, and all cases are translated to a newline.
As the output translation mode, \fBauto\fR chooses a platform specific
representation; for sockets on all platforms Tcl
chooses \fBcrlf\fR, for all Unix flavors, it chooses \fBlf\fR, for the
Macintosh platform it chooses \fBcr\fR and for the various flavors of
Windows it chooses \fBcrlf\fR.
The default setting for \fB\-translation\fR is \fBauto\fR for both
input and output.

.TP
\fBbinary\fR

No end-of-line translations are performed.  This is nearly identical to
\fBlf\fP mode, except that in addition \fBbinary\fP mode also sets the
end of file character to the empty string, which disables it.
See the description of
\fB\-eofchar\fP for more information.

.TP
\fBcr\fR

The end of a line in the underlying file or device is represented
by a single carriage return character.
As the input translation mode, \fBcr\fP mode converts carriage returns
to newline characters.
As the output translation mode, \fBcr\fP mode
translates newline characters to carriage returns.
This mode is typically used on Macintosh platforms.
.TP
\fBcrlf\fR

The end of a line in the underlying file or device is represented
by a carriage return character followed by a linefeed character.
As the input translation mode, \fBcrlf\fP mode converts
carriage-return-linefeed sequences
to newline characters.
As the output translation mode, \fBcrlf\fP mode
translates newline characters to
carriage-return-linefeed sequences.
This mode is typically used on Windows platforms and for network
connections.
.TP
\fBlf\fR

The end of a line in the underlying file or device is represented
by a single newline (linefeed) character.
In this mode no translations occur during either input or output.
This mode is typically used on UNIX platforms.
.RE
.PP

.SH "SEE ALSO"
close(n), flush(n), gets(n), puts(n), read(n), socket(n)

.SH KEYWORDS
blocking, buffering, carriage return, end of line, flushing, linemode,
newline, nonblocking, platform, translation








>





|
|
|
|


>




>

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



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



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



|
<
|
|
|
|
|
|
|


>
|
|
|
|
|
|
|

|
|
<
>

|
>


|
|
|
>


>
|
|
|
<
|
<
|


>
|
|
|
<
<
|
|
<
|
|


>
|
|
|
|








|
>
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
\fBread\fR, \fBputs\fR, \fBflush\fR, and \fBclose\fR commands;
see the documentation for those commands for details.
For nonblocking mode to work correctly, the application must be
using the Tcl event loop (e.g. by calling \fBTcl_DoOneEvent\fR or
invoking the \fBvwait\fR command).
.TP
\fB\-buffering\fR \fInewValue\fR
.
If \fInewValue\fR is \fBfull\fR then the I/O system will buffer output
until its internal buffer is full or until the \fBflush\fR command is
invoked. If \fInewValue\fR is \fBline\fR, then the I/O system will
automatically flush output for the channel whenever a newline character
is output. If \fInewValue\fR is \fBnone\fR, the I/O system will flush
automatically after every output operation.  The default is for
\fB\-buffering\fR to be set to \fBfull\fR except for channels that
connect to terminal-like devices; for these channels the initial setting
is \fBline\fR.
.TP
\fB\-buffersize\fR \fInewSize\fR
.
\fINewvalue\fR must be an integer; its value is used to set the size of
buffers, in bytes, subsequently allocated for this channel to store input
or output. \fINewvalue\fR must be between ten and one million, allowing
buffers of ten to one million bytes in size.
.VS 8.1 br
.TP
\fB\-encoding\fR \fIname\fR
.
This option is used to specify the encoding of the channel, so that the data
can be converted to and from Unicode for use in Tcl.  For instance, in
order for Tcl to read characters from a Japanese file in \fBshiftjis\fR
and properly process and display the contents, the encoding would be set
to \fBshiftjis\fR.  Thereafter, when reading from the channel, the bytes in
the Japanese file would be converted to Unicode as they are read.
Writing is also supported \- as Tcl strings are written to the channel they
will automatically be converted to the specified encoding on output.
.RS
.PP
If a file contains pure binary data (for instance, a JPEG image), the
encoding for the channel should be configured to be \fBbinary\fR.  Tcl
will then assign no interpretation to the data in the file and simply read or
write raw bytes.  The Tcl \fBbinary\fR command can be used to manipulate this
byte-oriented data.
.PP
The default encoding for newly opened channels is the same platform- and
locale-dependent system encoding used for interfacing with the operating
system.  
.RE
.VE
.TP
\fB\-eofchar\fR \fIchar\fR
.TP
\fB\-eofchar\fR \fB{\fIinChar outChar\fB}\fR
.
This option supports DOS file systems that use Control-z (\ex1a) as an

end of file marker.  If \fIchar\fR is not an empty string, then this
character signals end-of-file when it is encountered during input.  For
output, the end-of-file character is output when the channel is closed.

If \fIchar\fR is the empty string, then there is no special end of file

character marker.  For read-write channels, a two-element list specifies
the end of file marker for input and output, respectively.  As a
convenience, when setting the end-of-file character for a read-write

channel you can specify a single value that will apply to both reading
and writing.  When querying the end-of-file character of a read-write
channel, a two-element list will always be returned.  The default value
for \fB\-eofchar\fR is the empty string in all cases except for files
under Windows.  In that case the \fB\-eofchar\fR is Control-z (\ex1a) for
reading and the empty string for writing.
.TP
\fB\-translation\fR \fImode\fR
.TP
\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR 
.
In Tcl scripts the end of a line is always represented using a single

newline character (\en).  However, in actual files and devices the end of
a line may be represented differently on different platforms, or even for
different devices on the same platform.  For example, under UNIX newlines
are used in files, whereas carriage-return-linefeed sequences are
normally used in network connections.  On input (i.e., with \fBgets\fP

and \fBread\fP) the Tcl I/O system automatically translates the external
end-of-line representation into newline characters.  Upon output (i.e.,

with \fBputs\fP), the I/O system translates newlines to the external
end-of-line representation.  The default translation mode, \fBauto\fP,

handles all the common cases automatically, but the \fB\-translation\fR
option provides explicit control over the end of line translations.
.RS
.PP
The value associated with \fB\-translation\fR is a single item for
read-only and write-only channels.  The value is a two-element list for

read-write channels; the read translation mode is the first element of
the list, and the write translation mode is the second element.  As a
convenience, when setting the translation mode for a read-write channel
you can specify a single value that will apply to both reading and
writing.  When querying the translation mode of a read-write channel, a
two-element list will always be returned.  The following values are
currently supported:
.TP
\fBauto\fR
.
As the input translation mode, \fBauto\fR treats any of newline
(\fBlf\fP), carriage return (\fBcr\fP), or carriage return followed by a
newline (\fBcrlf\fP) as the end of line representation.  The end of line
representation can even change from line-to-line, and all cases are
translated to a newline.  As the output translation mode, \fBauto\fR
chooses a platform specific representation; for sockets on all platforms
Tcl chooses \fBcrlf\fR, for all Unix flavors, it chooses \fBlf\fR, for the
Macintosh platform it chooses \fBcr\fR and for the various flavors of
Windows it chooses \fBcrlf\fR.  The default setting for
\fB\-translation\fR is \fBauto\fR for both input and output.

.VS 8.1 br
.TP
\fBbinary\fR 
.
No end-of-line translations are performed.  This is nearly identical to
\fBlf\fP mode, except that in addition \fBbinary\fP mode also sets the
end-of-file character to the empty string (which disables it) and sets the
encoding to \fBbinary\fR (which disables encoding filtering).  See the
description of \fB\-eofchar\fR and \fB\-encoding\fR for more information.
.VE
.TP
\fBcr\fR
.
The end of a line in the underlying file or device is represented by a
single carriage return character.  As the input translation mode,
\fBcr\fP mode converts carriage returns to newline characters.  As the

output translation mode, \fBcr\fP mode translates newline characters to

carriage returns.  This mode is typically used on Macintosh platforms.
.TP
\fBcrlf\fR
.
The end of a line in the underlying file or device is represented by a
carriage return character followed by a linefeed character.  As the input
translation mode, \fBcrlf\fP mode converts carriage-return-linefeed


sequences to newline characters.  As the output translation mode,
\fBcrlf\fP mode translates newline characters to carriage-return-linefeed

sequences.  This mode is typically used on Windows platforms and for
network connections.
.TP
\fBlf\fR
.
The end of a line in the underlying file or device is represented by a
single newline (linefeed) character.  In this mode no translations occur
during either input or output.  This mode is typically used on UNIX
platforms.
.RE
.PP

.SH "SEE ALSO"
close(n), flush(n), gets(n), puts(n), read(n), socket(n)

.SH KEYWORDS
blocking, buffering, carriage return, end of line, flushing, linemode,
newline, nonblocking, platform, translation, encoding, filter, byte array,
binary

Changes to doc/fcopy.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) fcopy.n 1.4 97/06/19 11:10:07
'\" 
.so man.macros
.TH fcopy n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fcopy \- Copy data from one channel to another.







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: fcopy.n,v 1.1.2.1 1998/09/24 23:58:30 stanton Exp $
'\" 
.so man.macros
.TH fcopy n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fcopy \- Copy data from one channel to another.

Changes to doc/file.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) file.n 1.23 97/04/30 11:37:10
'\" 
.so man.macros
.TH file n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
file \- Manipulate file names and attributes







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: file.n,v 1.1.2.1 1998/09/24 23:58:30 stanton Exp $
'\" 
.so man.macros
.TH file n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
file \- Manipulate file names and attributes

Changes to doc/fileevent.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) fileevent.n 1.6 96/02/23 13:46:29
'\" 
.so man.macros
.TH fileevent n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fileevent \- Execute a script when a channel becomes readable or writable







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: fileevent.n,v 1.1.2.1 1998/09/24 23:58:31 stanton Exp $
'\" 
.so man.macros
.TH fileevent n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fileevent \- Execute a script when a channel becomes readable or writable

Changes to doc/filename.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) filename.n 1.7 96/04/11 17:03:14
'\" 
.so man.macros
.TH filename n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
filename \- File name conventions supported by Tcl commands






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 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: filename.n,v 1.1.2.1 1998/09/24 23:58:31 stanton Exp $
'\" 
.so man.macros
.TH filename n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
filename \- File name conventions supported by Tcl commands

Changes to doc/flush.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) flush.n 1.10 96/08/26 12:59:57
'\" 
.so man.macros
.TH flush n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
flush \- Flush buffered output for a channel







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: flush.n,v 1.1.2.1 1998/09/24 23:58:31 stanton Exp $
'\" 
.so man.macros
.TH flush n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
flush \- Flush buffered output for a channel

Changes to doc/for.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) for.n 1.6 97/04/08 17:13:49
'\" 
.so man.macros
.TH for n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
for \- ``For'' loop







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: for.n,v 1.1.2.1 1998/09/24 23:58:31 stanton Exp $
'\" 
.so man.macros
.TH for n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
for \- ``For'' loop

Changes to doc/foreach.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) foreach.n 1.6 96/03/25 20:15:14
'\" 
.so man.macros
.TH foreach n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
foreach \- Iterate over all elements in one or more lists







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: foreach.n,v 1.1.2.1 1998/09/24 23:58:31 stanton Exp $
'\" 
.so man.macros
.TH foreach n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
foreach \- Iterate over all elements in one or more lists

Changes to doc/format.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) format.n 1.11 96/08/26 12:59:57
'\" 
.so man.macros
.TH format n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
format \- Format a string in the style of sprintf







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: format.n,v 1.1.2.2 1999/02/10 23:31:11 stanton Exp $
'\" 
.so man.macros
.TH format n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
format \- Format a string in the style of sprintf
150
151
152
153
154
155
156

157
158
159

160
161
162
163
164
165
166
.TP 10
\fBo\fR
Convert integer to unsigned octal string.
.TP 10
\fBx\fR or \fBX\fR
Convert integer to unsigned hexadecimal string, using digits
``0123456789abcdef'' for \fBx\fR and ``0123456789ABCDEF'' for \fBX\fR).

.TP 10
\fBc\fR
Convert integer to the 8-bit character it represents.

.TP 10
\fBs\fR
No conversion; just insert string.
.TP 10
\fBf\fR
Convert floating-point number to signed decimal string of 
the form \fIxx.yyy\fR, where the number of \fIy\fR's is determined by 







>


|
>







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
.TP 10
\fBo\fR
Convert integer to unsigned octal string.
.TP 10
\fBx\fR or \fBX\fR
Convert integer to unsigned hexadecimal string, using digits
``0123456789abcdef'' for \fBx\fR and ``0123456789ABCDEF'' for \fBX\fR).
.VS
.TP 10
\fBc\fR
Convert integer to the Unicode character it represents.
.VE
.TP 10
\fBs\fR
No conversion; just insert string.
.TP 10
\fBf\fR
Convert floating-point number to signed decimal string of 
the form \fIxx.yyy\fR, where the number of \fIy\fR's is determined by 

Changes to doc/gets.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) gets.n 1.13 96/08/26 12:59:58
'\" 
.so man.macros
.TH gets n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
gets \- Read a line from a channel







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: gets.n,v 1.1.2.1 1998/09/24 23:58:31 stanton Exp $
'\" 
.so man.macros
.TH gets n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
gets \- Read a line from a channel

Changes to doc/glob.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) glob.n 1.11 96/08/26 12:59:59
'\" 
.so man.macros
.TH glob n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
glob \- Return names of files that match patterns
.SH SYNOPSIS
\fBglob \fR?\fIswitches\fR? \fIpattern \fR?\fIpattern ...\fR?
.BE







|


|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: glob.n,v 1.1.2.2 1998/09/24 23:58:31 stanton Exp $
'\" 
.so man.macros
.TH glob n 8.1 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
glob \- Return names of files that match patterns
.SH SYNOPSIS
\fBglob \fR?\fIswitches\fR? \fIpattern \fR?\fIpattern ...\fR?
.BE
72
73
74
75
76
77
78
79




80
81





82
83
84
contains a ?, *, or [] construct.

.SH PORTABILITY ISSUES
.PP
Unlike other Tcl commands that will accept both network and native
style names (see the \fBfilename\fR manual entry for details on how
native and network names are specified), the \fBglob\fR command only
accepts native names.  Also, for Windows UNC names, the servername and




sharename components of the path may not contain ?, *, or []
constructs. 






.SH KEYWORDS
exist, file, glob, pattern







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



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
contains a ?, *, or [] construct.

.SH PORTABILITY ISSUES
.PP
Unlike other Tcl commands that will accept both network and native
style names (see the \fBfilename\fR manual entry for details on how
native and network names are specified), the \fBglob\fR command only
accepts native names.  
.VS 8.1
.TP
\fBWindows\fR
.
For Windows UNC names, the servername and sharename components of the path
may not contain ?, *, or [] constructs.  On Windows NT, if \fIpattern\fR is
of the form ``\fB~\fIusername\fB@\fIdomain\fR'' it refers to the home
directory of the user whose account information resides on the specified NT
domain server.  Otherwise, user account information is obtained from
the local computer.  
.VE

.SH KEYWORDS
exist, file, glob, pattern

Changes to doc/global.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) global.n 1.6 97/05/18 15:23:09
'\" 
.so man.macros
.TH global n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
global \- Access global variables







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: global.n,v 1.1.2.1 1998/09/24 23:58:32 stanton Exp $
'\" 
.so man.macros
.TH global n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
global \- Access global variables

Changes to doc/history.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) history.n 1.11 97/08/07 16:44:49
'\" 
.so man.macros
.TH history n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
history \- Manipulate the history list







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: history.n,v 1.1.2.1 1998/09/24 23:58:32 stanton Exp $
'\" 
.so man.macros
.TH history n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
history \- Manipulate the history list

Changes to doc/http.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\" 
'\" SCCS: @(#) http.n 1.11 97/08/07 16:45:02
'\" 
.so man.macros
.TH "Http" n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Http \- Client-side implementation of the HTTP/1.0 protocol.






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: http.n,v 1.1.2.2 1998/12/10 21:21:28 stanton Exp $
'\" 
.so man.macros
.TH "Http" n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Http \- Client-side implementation of the HTTP/1.0 protocol.
246
247
248
249
250
251
252


253
254
255
256
257
258
259
260
.SH "STATE ARRAY"
The \fB::http::geturl\fR procedure returns a \fItoken\fR that can be used to
get to the state of the HTTP transaction in the form of a Tcl array.
Use this construct to create an easy-to-use array variable:
.CS
upvar #0 $token state
.CE


The following elements of the array are supported:
.RS
.TP
\fBbody\fR
The contents of the URL.  This will be empty if the \fB\-channel\fR
option has been specified.  This value is returned by the \fB::http::data\fP command.
.TP
\fBcurrentsize\fR







>
>
|







246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
.SH "STATE ARRAY"
The \fB::http::geturl\fR procedure returns a \fItoken\fR that can be used to
get to the state of the HTTP transaction in the form of a Tcl array.
Use this construct to create an easy-to-use array variable:
.CS
upvar #0 $token state
.CE
Once the data associated with the url is no longer needed, the state
array should be unset to free up storage.  The following elements of
the array are supported:
.RS
.TP
\fBbody\fR
The contents of the URL.  This will be empty if the \fB\-channel\fR
option has been specified.  This value is returned by the \fB::http::data\fP command.
.TP
\fBcurrentsize\fR

Changes to doc/if.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) if.n 1.7 96/08/26 13:00:00
'\" 
.so man.macros
.TH if n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
if \- Execute scripts conditionally







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: if.n,v 1.1.2.1 1998/09/24 23:58:32 stanton Exp $
'\" 
.so man.macros
.TH if n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
if \- Execute scripts conditionally

Changes to doc/incr.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) incr.n 1.5 96/03/25 20:16:58
'\" 
.so man.macros
.TH incr n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
incr \- Increment the value of a variable







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: incr.n,v 1.1.2.1 1998/09/24 23:58:32 stanton Exp $
'\" 
.so man.macros
.TH incr n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
incr \- Increment the value of a variable

Changes to doc/info.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) info.n 1.17 97/05/19 14:48:52
'\" 
.so man.macros
.TH info n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
info \- Return information about the state of the Tcl interpreter








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: info.n,v 1.1.2.1 1998/09/24 23:58:32 stanton Exp $
'\" 
.so man.macros
.TH info n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
info \- Return information about the state of the Tcl interpreter

Changes to doc/interp.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) interp.n 1.37 97/10/31 12:51:11
'\" 
.so man.macros
.TH interp n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
interp \- Create and manipulate Tcl interpreters






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 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: interp.n,v 1.1.2.1 1998/09/24 23:58:32 stanton Exp $
'\" 
.so man.macros
.TH interp n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
interp \- Create and manipulate Tcl interpreters
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
command, by making the current namespace be different from the global one.
Hidden commands are explained in more detail in HIDDEN COMMANDS, below.
.TP
\fBinterp\fR \fBhidden\fR \fIpath\fR
Returns a list of the names of all hidden commands in the interpreter
identified by \fIpath\fR.
.TP
\fBinterp\fR \fBinvokehidden\fR \fIpath\fR ?\fB-global\fR \fIhiddenCmdName\fR ?\fIarg ...\fR?
Invokes the hidden command \fIhiddenCmdName\fR with the arguments supplied
in the interpreter denoted by \fIpath\fR. No substitutions or evaluation
are applied to the arguments.
If the \fB-global\fR flag is present, the hidden command is invoked at the
global level in the target interpreter; otherwise it is invoked at the
current call frame and can access local variables in that and outer call
frames.







|







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
command, by making the current namespace be different from the global one.
Hidden commands are explained in more detail in HIDDEN COMMANDS, below.
.TP
\fBinterp\fR \fBhidden\fR \fIpath\fR
Returns a list of the names of all hidden commands in the interpreter
identified by \fIpath\fR.
.TP
\fBinterp\fR \fBinvokehidden\fR \fIpath\fR ?\fB-global\fR? \fIhiddenCmdName\fR ?\fIarg ...\fR?
Invokes the hidden command \fIhiddenCmdName\fR with the arguments supplied
in the interpreter denoted by \fIpath\fR. No substitutions or evaluation
are applied to the arguments.
If the \fB-global\fR flag is present, the hidden command is invoked at the
global level in the target interpreter; otherwise it is invoked at the
current call frame and can access local variables in that and outer call
frames.

Changes to doc/join.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) join.n 1.5 96/03/25 20:17:46
'\" 
.so man.macros
.TH join n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
join \- Create a string by joining together list elements







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: join.n,v 1.1.2.1 1998/09/24 23:58:32 stanton Exp $
'\" 
.so man.macros
.TH join n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
join \- Create a string by joining together list elements

Changes to doc/lappend.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) lappend.n 1.6 96/03/25 20:18:03
'\" 
.so man.macros
.TH lappend n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lappend \- Append list elements onto a variable







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: lappend.n,v 1.1.2.1 1998/09/24 23:58:33 stanton Exp $
'\" 
.so man.macros
.TH lappend n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lappend \- Append list elements onto a variable

Changes to doc/library.n.

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
'\"
'\" Copyright (c) 1991-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) library.n 1.23 96/11/20 14:07:04
.so man.macros
.TH library n "8.0" Tcl "Tcl Built-In Commands"
.BS
.SH NAME
library \- standard library of Tcl procedures
.SH SYNOPSIS
.nf
\fBauto_execok \fIcmd\fR
\fBauto_load \fIcmd\fR
\fBauto_mkindex \fIdir pattern pattern ...\fR

\fBauto_reset\fR

\fBparray \fIarrayName\fR
.VS
\fBtcl_endOfWord \fIstr start\fR
\fBtcl_startOfNextWord \fIstr start\fR
\fBtcl_startOfPreviousWord \fIstr start\fR
\fBtcl_wordBreakAfter \fIstr start\fR
\fBtcl_wordBreakBefore \fIstr start\fR







|










>

>







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
'\"
'\" Copyright (c) 1991-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: library.n,v 1.1.2.3 1999/04/09 21:01:30 surles Exp $
.so man.macros
.TH library n "8.0" Tcl "Tcl Built-In Commands"
.BS
.SH NAME
library \- standard library of Tcl procedures
.SH SYNOPSIS
.nf
\fBauto_execok \fIcmd\fR
\fBauto_load \fIcmd\fR
\fBauto_mkindex \fIdir pattern pattern ...\fR
\fBauto_mkindex_old \fIdir pattern pattern ...\fR
\fBauto_reset\fR
\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
\fBparray \fIarrayName\fR
.VS
\fBtcl_endOfWord \fIstr start\fR
\fBtcl_startOfNextWord \fIstr start\fR
\fBtcl_startOfPreviousWord \fIstr start\fR
\fBtcl_wordBreakAfter \fIstr start\fR
\fBtcl_wordBreakBefore \fIstr start\fR
54
55
56
57
58
59
60
61



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
the auto-load mechanism defined below.

.SH "COMMAND PROCEDURES"
.PP
The following procedures are provided in the Tcl library:
.TP
\fBauto_execok \fIcmd\fR
Determines whether there is an executable file by the name \fIcmd\fR.



This command examines the directories in the current search path
(given by the PATH environment variable) to see if there is an
executable file named \fIcmd\fR in any of those directories.
If so, it returns 1;  if not it returns 0.  \fBAuto_exec\fR
remembers information about previous searches in an array
named \fBauto_execs\fR;  this avoids the path search in
future calls for the same \fIcmd\fR.  The command \fBauto_reset\fR
may be used to force \fBauto_execok\fR to forget its cached
information.
.TP
\fBauto_load \fIcmd\fR
This command attempts to load the definition for a Tcl command named
\fIcmd\fR.
To do this, it searches an \fIauto-load path\fR, which is a list of
one or more directories.
The auto-load path is given by the global variable \fB$auto_path\fR







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







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
the auto-load mechanism defined below.

.SH "COMMAND PROCEDURES"
.PP
The following procedures are provided in the Tcl library:
.TP
\fBauto_execok \fIcmd\fR
Determines whether there is an executable file or shell builtin
by the name \fIcmd\fR.  If so, it returns a list of arguments to be
passed to \fBexec\fR to execute the executable file or shell builtin
named by \fIcmd\fR.  If not, it returns an empty string.  This command
examines the directories in the current search path (given by the PATH
environment variable) in its search for an executable file named
\fIcmd\fR.  On Windows platforms, the search is expanded with the same
directories and file extensions as used by \fBexec\fR. \fBAuto_exec\fR
remembers information about previous searches in an array named
\fBauto_execs\fR;  this avoids the path search in future calls for the
same \fIcmd\fR.  The command \fBauto_reset\fR may be used to force
\fBauto_execok\fR to forget its cached information.

.TP
\fBauto_load \fIcmd\fR
This command attempts to load the definition for a Tcl command named
\fIcmd\fR.
To do this, it searches an \fIauto-load path\fR, which is a list of
one or more directories.
The auto-load path is given by the global variable \fB$auto_path\fR
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
.CS
\fBauto_mkindex foo *.tcl\fR
.CE
.LP
will read all the \fB.tcl\fR files in subdirectory \fBfoo\fR
and generate a new index file \fBfoo/tclIndex\fR.
.PP
\fBAuto_mkindex\fR parses the Tcl scripts in a relatively








unsophisticated way:  if any line contains the word \fBproc\fR
as its first characters then it is assumed to be a procedure
definition and the next word of the line is taken as the
procedure's name.
Procedure definitions that don't appear in this way (e.g. they
have spaces before the \fBproc\fR) will not be indexed.
.RE
.TP
\fBauto_reset\fR
Destroys all the information cached by \fBauto_execok\fR and
\fBauto_load\fR.
This information will be re-read from disk the next time it is
needed.
\fBAuto_reset\fR also deletes any procedures listed in the auto-load
index, so that fresh copies of them will be loaded the next time
that they're used.




















.TP
\fBparray \fIarrayName\fR
Prints on standard output the names and values of all the elements
in the array \fIarrayName\fR.
\fBArrayName\fR must be an array accessible to the caller of \fBparray\fR.
It may be either local or global.
.TP







|
>
>
>
>
>
>
>
>
















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







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
.CS
\fBauto_mkindex foo *.tcl\fR
.CE
.LP
will read all the \fB.tcl\fR files in subdirectory \fBfoo\fR
and generate a new index file \fBfoo/tclIndex\fR.
.PP
\fBAuto_mkindex\fR parses the Tcl scripts by sourcing them
into a slave interpreter and monitoring the proc and
namespace commands that are executed.
Extensions can use the (undocumented)
auto_mkindex_parser package to register other commands that
can contribute to the auto_load index.
You will have to read through init.tcl to see how this works.
.PP
\fBAuto_mkindex_old\fR parses the Tcl scripts in a relatively
unsophisticated way:  if any line contains the word \fBproc\fR
as its first characters then it is assumed to be a procedure
definition and the next word of the line is taken as the
procedure's name.
Procedure definitions that don't appear in this way (e.g. they
have spaces before the \fBproc\fR) will not be indexed.
.RE
.TP
\fBauto_reset\fR
Destroys all the information cached by \fBauto_execok\fR and
\fBauto_load\fR.
This information will be re-read from disk the next time it is
needed.
\fBAuto_reset\fR also deletes any procedures listed in the auto-load
index, so that fresh copies of them will be loaded the next time
that they're used.
.TP
\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
This is a standard search procedure for use by extensions during
their initialization.  They call this procedure to look for their
script library in several standard directories.
The last component of the name of the library directory is 
normally \fIbasenameversion\fP
(e.g., tk8.0), but it might be "library" when in the build hierarchies.
The \fIinitScript\fR file will be sourced into the interpreter
once it is found.  The directory in which this file is found is
stored into the global variable \fIvarName\fP.
If this variable is already defined (e.g., by C code during
application initialization) then no searching is done.
Otherwise the search looks in these directories:
the directory named by the environment variable \fIenVarName\fP;
relative to the Tcl library directory;
relative to the executable file in the standard installation
bin or bin/\fIarch\fP directory;
relative to the executable file in the current build tree;
relative to the executable file in a parallel build tree.
.TP
\fBparray \fIarrayName\fR
Prints on standard output the names and values of all the elements
in the array \fIarrayName\fR.
\fBArrayName\fR must be an array accessible to the caller of \fBparray\fR.
It may be either local or global.
.TP
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
\fBauto_noload\fR
If set to any value, then \fBunknown\fR will not attempt to auto-load
any commands.
.TP
\fBauto_path\fR
If set, then it must contain a valid Tcl list giving directories to
search during auto-load operations.





.TP
\fBenv(TCL_LIBRARY)\fR
If set, then it specifies the location of the directory containing
library scripts (the value of this variable will be returned by

the command \fBinfo library\fR).  If this variable isn't set then
a default value is used.
.TP
\fBenv(TCLLIBPATH)\fR
If set, then it must contain a valid Tcl list giving directories to
search during auto-load operations.
This variable is only used if \fBauto_path\fR is not defined.

.TP
\fBtcl_nonwordchars\fR
.VS
This variable contains a regular expression that is used by routines
like \fBtcl_endOfWord\fR to identify whether a character is part of a
word or not.  If the pattern matches a character, the character is
considered to be a non-word character.  On Windows platforms, spaces,







>
>
>
>
>



|
>






|
>







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
\fBauto_noload\fR
If set to any value, then \fBunknown\fR will not attempt to auto-load
any commands.
.TP
\fBauto_path\fR
If set, then it must contain a valid Tcl list giving directories to
search during auto-load operations.
This variable is initialized during startup to contain, in order:
the directories listed in the TCLLIBPATH environment variable,
the directory named by the $tcl_library variable,
the parent directory of $tcl_library,
the directories listed in the $tcl_pkgPath variable.
.TP
\fBenv(TCL_LIBRARY)\fR
If set, then it specifies the location of the directory containing
library scripts (the value of this variable will be
assigned to the \fBtcl_library\fR variable and therefore returned by
the command \fBinfo library\fR).  If this variable isn't set then
a default value is used.
.TP
\fBenv(TCLLIBPATH)\fR
If set, then it must contain a valid Tcl list giving directories to
search during auto-load operations.
This variable is only used when
initializing the \fBauto_path\fR variable.
.TP
\fBtcl_nonwordchars\fR
.VS
This variable contains a regular expression that is used by routines
like \fBtcl_endOfWord\fR to identify whether a character is part of a
word or not.  If the pattern matches a character, the character is
considered to be a non-word character.  On Windows platforms, spaces,

Changes to doc/lindex.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) lindex.n 1.8 96/08/26 13:00:02
'\" 
.so man.macros
.TH lindex n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lindex \- Retrieve an element from a list







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: lindex.n,v 1.1.2.1 1998/09/24 23:58:33 stanton Exp $
'\" 
.so man.macros
.TH lindex n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lindex \- Retrieve an element from a list

Changes to doc/linsert.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) linsert.n 1.8 96/08/26 13:00:03
'\" 
.so man.macros
.TH linsert n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
linsert \- Insert elements into a list







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: linsert.n,v 1.1.2.1 1998/09/24 23:58:33 stanton Exp $
'\" 
.so man.macros
.TH linsert n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
linsert \- Insert elements into a list

Changes to doc/list.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) list.n 1.9 96/08/26 13:00:04
'\" 
.so man.macros
.TH list n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
list \- Create a list







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: list.n,v 1.1.2.1 1998/09/24 23:58:33 stanton Exp $
'\" 
.so man.macros
.TH list n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
list \- Create a list

Changes to doc/llength.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) llength.n 1.5 96/03/25 20:19:25
'\" 
.so man.macros
.TH llength n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
llength \- Count the number of elements in a list







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: llength.n,v 1.1.2.1 1998/09/24 23:58:33 stanton Exp $
'\" 
.so man.macros
.TH llength n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
llength \- Count the number of elements in a list

Changes to doc/load.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) load.n 1.9 97/08/22 18:51:18
'\" 
.so man.macros
.TH load n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
load \- Load machine code and initialize new commands.






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 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: load.n,v 1.1.2.1 1998/09/24 23:58:33 stanton Exp $
'\" 
.so man.macros
.TH load n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
load \- Load machine code and initialize new commands.

Changes to doc/lrange.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) lrange.n 1.9 96/08/26 13:00:05
'\" 
.so man.macros
.TH lrange n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lrange \- Return one or more adjacent elements from a list







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: lrange.n,v 1.1.2.1 1998/09/24 23:58:33 stanton Exp $
'\" 
.so man.macros
.TH lrange n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lrange \- Return one or more adjacent elements from a list

Changes to doc/lreplace.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) lreplace.n 1.9 96/08/26 13:00:07
'\" 
.so man.macros
.TH lreplace n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lreplace \- Replace elements in a list with new elements







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: lreplace.n,v 1.1.2.1 1998/09/24 23:58:33 stanton Exp $
'\" 
.so man.macros
.TH lreplace n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lreplace \- Replace elements in a list with new elements

Changes to doc/lsearch.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) lsearch.n 1.7 96/08/26 13:00:05
'\" 
.so man.macros
.TH lsearch n 7.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lsearch \- See if a list contains a particular element







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: lsearch.n,v 1.1.2.1 1998/09/24 23:58:34 stanton Exp $
'\" 
.so man.macros
.TH lsearch n 7.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lsearch \- See if a list contains a particular element

Changes to doc/lsort.n.

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
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.

'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) lsort.n 1.10 97/08/22 18:50:53
'\" 
.so man.macros
.TH lsort n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lsort \- Sort the elements of a list
.SH SYNOPSIS
\fBlsort \fR?\fIoptions\fR? \fIlist\fR
.BE

.SH DESCRIPTION
.PP
This command sorts the elements of \fIlist\fR, returning a new
list in sorted order.  By default ASCII sorting is used with



the result returned in increasing order.
However, any of the
following options may be specified before \fIlist\fR to
control the sorting process (unique abbreviations are accepted):
.TP 20
\fB\-ascii\fR
Use string comparison with ASCII collation order.  This is
the default.
.VS 8.0 br
.TP 20
\fB\-dictionary\fR



>




|














|
>
>
>
|
|
|
|







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
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 1999 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: lsort.n,v 1.1.2.2 1999/01/29 00:20:43 stanton Exp $
'\" 
.so man.macros
.TH lsort n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
lsort \- Sort the elements of a list
.SH SYNOPSIS
\fBlsort \fR?\fIoptions\fR? \fIlist\fR
.BE

.SH DESCRIPTION
.PP
This command sorts the elements of \fIlist\fR, returning a new
list in sorted order.  The implementation of the \fBlsort\fR command
uses the merge\-sort algorithm which is a stable sort that has O(n log
n) performance characteristics.
.PP
By default ASCII sorting is used with the result returned in
increasing order.  However, any of the following options may be
specified before \fIlist\fR to control the sorting process (unique
abbreviations are accepted):
.TP 20
\fB\-ascii\fR
Use string comparison with ASCII collation order.  This is
the default.
.VS 8.0 br
.TP 20
\fB\-dictionary\fR

Changes to doc/man.macros.

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
'\"	option's name as specified in the class command, dbName gives
'\"	the option's name in the option database, and dbClass gives
'\"	the option's class in the option database.
'\"
'\" .UL arg1 arg2
'\"	Print arg1 underlined, then print arg2 normally.
'\"
'\" SCCS: @(#) man.macros 1.9 97/08/22 18:50:59
'\"
'\"	# Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
'\"	# Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}
.ie !"\\$3"" \{\
.ta \\n()Au \\n()Bu

\&\\$1	\\fI\\$2\\fP	(\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP







|












<

>







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
'\"	option's name as specified in the class command, dbName gives
'\"	the option's name in the option database, and dbClass gives
'\"	the option's class in the option database.
'\"
'\" .UL arg1 arg2
'\"	Print arg1 underlined, then print arg2 normally.
'\"
'\" RCS: @(#) $Id: man.macros,v 1.1.2.2 1998/09/24 23:58:34 stanton Exp $
'\"
'\"	# Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
'\"	# Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}

.ta \\n()Au \\n()Bu
.ie !"\\$3"" \{\
\&\\$1	\\fI\\$2\\fP	(\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP

Added doc/msgcat.n.































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
'\"
'\" Copyright (c) 1998 Mark Harrison.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) msgcat.n
'\" 
.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
\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
.sp
\fB::msgcat::mcunknown \fIlocale src-string\fR
.BE

.SH DESCRIPTION
.PP
The \fBmsgcat\fR package provides a set of functions
that can be used to manage multi-lingual user interfaces.
Text strings are defined in a ``message catalog'' which
is independent from the application, and
which can be edited or localized without modifying
the application source code.  New languages
or locales are provided by adding a new file to
the message catalog.
.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
preference.  If the user has specified LANG=en_US_funky,
this procedure would return {en_US_funky en_US en}.
.TP
\fB::msgcat::mcload \fIdirname\fR
Searches the specified directory for files that match
the language specifications returned by \fB::msgcat::mcpreferences\fR.
Each file located is sourced.  The file extension is ``.msg''.
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
system-specific code, each separated by ``_''.  The country and language
codes are specified in standards ISO-639 and ISO-3166.
For example, the locale ``en'' specifies English and
 ``en_US'' specifes  U.S. English.
.PP
The locale defaults to the value in \fBenv(LANG)\fR at the time the
\fBmsgcat\fR package is loaded.  If \fBenv(LANG)\fR is not defined, then the
locale defaults to ``C''.
.PP
When a locale is specified by the user, a ``best match'' search is
performed during string translation.  For example, if a user specifies
en_UK_Funky, the locales ``en_UK_Funky'', ``en_UK'', and ``en'' are
searched in order until a matching translation string is found.  If no
translation string is available, then \fB::msgcat::unknown\fR is
called.

.SH "NAMESPACES AND MESSAGE CATALOGS"
.PP
Strings stored in the message catalog are stored relative
to the namespace from which they were added.  This allows
multiple packages to use the same strings without fear
of collisions with other packages.  It also allows the
source string to be shorter and less prone to typographical
error.
.PP
For example, executing the code
.CS
mcset en hello "hello from ::"
namespace eval foo {mcset en hello "hello from ::foo"}
puts [mc hello]
namespace eval foo {puts [mc hello]}
.CE
will print
.CS
hello from ::
hello from ::foo
.CE

.SH "LOCATION AND FORMAT OF MESSAGE FILES"
.PP
Message files can be located in any directory, subject
to the following conditions:
.IP [1]
All message files for a package are in the same directory.
.IP [2]
The message file name is a locale specifier followed
by ``.msg''.  For example:
.CS
es.msg    -- spanish
en_UK.msg -- UK English
.CE
.IP [3]
The file contains a series of calls to mcset, setting the
necessary translation strings for the language. For example:
.CS
::msgcat::mcset es "Free Beer!" "Cerveza Gracias!"
.CE

.SH "RECOMMENDED MESSAGE SETUP FOR PACKAGES"
.PP
If a package is installed into a subdirectory of the
\fBtcl_pkgPath\fR and loaded via \fBpackage require\fR, the
following procedure is recommended.
.IP [1]
During package installation, create a subdirectory
\fBmsgs\fR under your package directory.
.IP [2]
Copy your *.msg files into that directory.
.IP [3]
 Add the following command to your package
initialization script:
.CS
# load language files, stored in msgs subdirectory
::msgcat::mcload [file join [file dirname [info script]] msgs]
.CE

.SH "POSTITIONAL CODES FOR FORMAT AND SCAN COMMANDS"
.PP
It is possible that a message string used as an argument
to \fBformat\fR might have positionally dependent parameters that
might need to be repositioned.  For example, it might be
syntactically desirable to rearrange the sentence structure
while translating.
.CS
format "We produced %d units in location %s" $num $city
format "In location %s we produced %d units" $city $num
.CE
.PP
This can be handled by using the positional
parameters:
.CS
format "We produced %1\\\\$d units in location %2\\\\$s" $num $city
format "In location %2\\\\$s we produced %1\\\\$d units" $num $city
.CE
.PP
Similarly, positional parameters can be used with \fBscan\fR to
extract values from internationalized strings.

.SH "SEE ALSO"
format(n), scan(n), namespace(n), package(n)

.SH CREDITS
.PP
The message catalog code was developed by Mark Harrison.
.SH KEYWORDS
internationalization, i18n, localization, l10n, message, text, translation

Changes to doc/namespace.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
'\" 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.
'\" 
'\" SCCS: @(#) namespace.n 1.9 97/08/13 17:08:25
'\" 
.so man.macros
.TH namespace n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
namespace \- create and manipulate contexts for commands and variables







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
'\" 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: namespace.n,v 1.1.2.2 1999/04/09 18:42:02 surles Exp $
'\" 
.so man.macros
.TH namespace n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
namespace \- create and manipulate contexts for commands and variables
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
Tcl has always had one such collection,
which we refer to as the \fIglobal namespace\fR.
The global namespace holds all global variables and commands.
The \fBnamespace eval\fR command lets you create new namespaces.
For example,
.CS
\fBnamespace eval Counter {
    namespace export Bump
    variable num 0

    proc Bump {} {
        variable num
        incr num
    }
}\fR
.CE
creates a new namespace containing the variable \fBnum\fR and
the procedure \fBBump\fR.
The commands and variables in this namespace are separate from
other commands and variables in the same program.
If there is a command named \fBBump\fR in the global namespace,
for example, it will be different from the command \fBBump\fR
in the \fBCounter\fR namespace.
.PP
Namespace variables resemble global variables in Tcl.
They exist outside of the procedures in a namespace
but can be accessed in a procedure via the \fBvariable\fR command,
as shown in the example above.
.PP
Namespaces are dynamic.
You can add and delete commands and variables at any time,
so you can build up the contents of a
namespace over time using a series of \fBnamespace eval\fR commands.
For example, the following series of commands has the same effect
as the namespace definition shown above:
.CS
\fBnamespace eval Counter {
    variable num 0
    proc Bump {} {
        variable num
        return [incr num]
    }
}
namespace eval Counter {
    proc test {args} {
        return $args







|


|






|


|
|
















|







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
Tcl has always had one such collection,
which we refer to as the \fIglobal namespace\fR.
The global namespace holds all global variables and commands.
The \fBnamespace eval\fR command lets you create new namespaces.
For example,
.CS
\fBnamespace eval Counter {
    namespace export bump
    variable num 0

    proc bump {} {
        variable num
        incr num
    }
}\fR
.CE
creates a new namespace containing the variable \fBnum\fR and
the procedure \fBbump\fR.
The commands and variables in this namespace are separate from
other commands and variables in the same program.
If there is a command named \fBbump\fR in the global namespace,
for example, it will be different from the command \fBbump\fR
in the \fBCounter\fR namespace.
.PP
Namespace variables resemble global variables in Tcl.
They exist outside of the procedures in a namespace
but can be accessed in a procedure via the \fBvariable\fR command,
as shown in the example above.
.PP
Namespaces are dynamic.
You can add and delete commands and variables at any time,
so you can build up the contents of a
namespace over time using a series of \fBnamespace eval\fR commands.
For example, the following series of commands has the same effect
as the namespace definition shown above:
.CS
\fBnamespace eval Counter {
    variable num 0
    proc bump {} {
        variable num
        return [incr num]
    }
}
namespace eval Counter {
    proc test {args} {
        return $args
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
.PP
If you want to access commands and variables from another namespace,
you must use some extra syntax.
Names must be qualified by the namespace that contains them.
From the global namespace,
we might access the \fBCounter\fR procedures like this:
.CS
\fBCounter::Bump 5
Counter::Reset\fR
.CE
We could access the current count like this:
.CS
\fBputs "count = $Counter::num"\fR
.CE
When one namespace contains another, you may need more than one
qualifier to reach its elements.
If we had a namespace \fBFoo\fR that contained the namespace \fBCounter\fR,
you could invoke its \fBBump\fR procedure
from the global namespace like this:
.CS
\fBFoo::Counter::Bump 3\fR
.CE
.PP
You can also use qualified names when you create and rename commands.
For example, you could add a procedure to the \fBFoo\fR
namespace like this:
.CS
\fBproc Foo::Test {args} {return $args}\fR







|









|


|







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
.PP
If you want to access commands and variables from another namespace,
you must use some extra syntax.
Names must be qualified by the namespace that contains them.
From the global namespace,
we might access the \fBCounter\fR procedures like this:
.CS
\fBCounter::bump 5
Counter::Reset\fR
.CE
We could access the current count like this:
.CS
\fBputs "count = $Counter::num"\fR
.CE
When one namespace contains another, you may need more than one
qualifier to reach its elements.
If we had a namespace \fBFoo\fR that contained the namespace \fBCounter\fR,
you could invoke its \fBbump\fR procedure
from the global namespace like this:
.CS
\fBFoo::Counter::bump 3\fR
.CE
.PP
You can also use qualified names when you create and rename commands.
For example, you could add a procedure to the \fBFoo\fR
namespace like this:
.CS
\fBproc Foo::Test {args} {return $args}\fR
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
.CE
the command is automatically removed from all namespaces that import it.

.SH "EXPORTING COMMANDS"
You can export commands from a namespace like this:
.CS
\fBnamespace eval Counter {
    namespace export Bump Reset
    variable num 0
    variable max 100

    proc Bump {{by 1}} {
        variable num
        incr num $by
        check
        return $num
    }
    proc Reset {} {
        variable num
        set num 0
    }
    proc check {} {
        variable num
        variable max
        if {$num > $max} {
            error "too high!"
        }
    }
}\fR
.CE
The procedures \fBBump\fR and \fBReset\fR are exported,
so they are included when you import from the \fBCounter\fR namespace,
like this:
.CS
\fBnamespace import Counter::*\fR
.CE
However, the \fBcheck\fR procedure is not exported,
so it is ignored by the import operation.
.PP
The \fBnamespace import\fR command only imports commands
that were declared as exported by their namespace.
The \fBnamespace export\fR command specifies what commands
may be imported by other namespaces.
If a \fBnamespace import\fR command specifies a command







|
|
|

|
|
|
|
|

|
|
|

|
|
|
|





|





|







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
.CE
the command is automatically removed from all namespaces that import it.

.SH "EXPORTING COMMANDS"
You can export commands from a namespace like this:
.CS
\fBnamespace eval Counter {
    namespace export bump reset
    variable Num 0
    variable Max 100

    proc bump {{by 1}} {
        variable Num
        incr Num $by
        Check
        return $Num
    }
    proc reset {} {
        variable Num
        set Num 0
    }
    proc Check {} {
        variable Num
        variable Max
        if {$Num > $Max} {
            error "too high!"
        }
    }
}\fR
.CE
The procedures \fBbump\fR and \fBreset\fR are exported,
so they are included when you import from the \fBCounter\fR namespace,
like this:
.CS
\fBnamespace import Counter::*\fR
.CE
However, the \fBCheck\fR procedure is not exported,
so it is ignored by the import operation.
.PP
The \fBnamespace import\fR command only imports commands
that were declared as exported by their namespace.
The \fBnamespace export\fR command specifies what commands
may be imported by other namespaces.
If a \fBnamespace import\fR command specifies a command

Changes to doc/open.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) open.n 1.16 97/01/14 18:00:35
'\" 
.so man.macros
.TH open n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
open \- Open a file-based or command pipeline channel







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: open.n,v 1.1.2.1 1998/09/24 23:58:34 stanton Exp $
'\" 
.so man.macros
.TH open n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
open \- Open a file-based or command pipeline channel

Changes to doc/package.n.

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
'\"
'\" Copyright (c) 1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) package.n 1.5 96/03/18 14:17:31
'\" 
.so man.macros
.TH package n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
package \- Facilities for package loading and version control
.SH SYNOPSIS
.nf
\fBpackage forget \fIpackage\fR
\fBpackage ifneeded \fIpackage version\fR ?\fIscript\fR?
\fBpackage names\fR

\fBpackage provide \fIpackage \fR?\fIversion\fR?
\fBpackage require \fR?\fB\-exact\fR? \fIpackage \fR?\fIversion\fR?
\fBpackage unknown \fR?\fIcommand\fR?
\fBpackage vcompare \fIversion1 version2\fR
\fBpackage versions \fIpackage\fR
\fBpackage vsatisfies \fIversion1 version2\fR
.fi






|












>







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
'\"
'\" Copyright (c) 1996 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: package.n,v 1.1.2.2 1999/03/10 06:49:11 stanton Exp $
'\" 
.so man.macros
.TH package n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
package \- Facilities for package loading and version control
.SH SYNOPSIS
.nf
\fBpackage forget \fIpackage\fR
\fBpackage ifneeded \fIpackage version\fR ?\fIscript\fR?
\fBpackage names\fR
\fBpackage present \fR?\fB\-exact\fR? \fIpackage \fR?\fIversion\fR?
\fBpackage provide \fIpackage \fR?\fIversion\fR?
\fBpackage require \fR?\fB\-exact\fR? \fIpackage \fR?\fIversion\fR?
\fBpackage unknown \fR?\fIcommand\fR?
\fBpackage vcompare \fIversion1 version2\fR
\fBpackage versions \fIpackage\fR
\fBpackage vsatisfies \fIversion1 version2\fR
.fi
70
71
72
73
74
75
76




77
78
79
80
81
82
83
.TP
\fBpackage names\fR
Returns a list of the names of all packages in the
interpreter for which a version has been provided (via
\fBpackage provide\fR) or for which a \fBpackage ifneeded\fR
script is available.
The order of elements in the list is arbitrary.




.TP
\fBpackage provide \fIpackage \fR?\fIversion\fR?
This command is invoked to indicate that version \fIversion\fR
of package \fIpackage\fR is now present in the interpreter.
It is typically invoked once as part of an \fBifneeded\fR script,
and again by the package itself when it is finally loaded.
An error occurs if a different version of \fIpackage\fR has been







>
>
>
>







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
.TP
\fBpackage names\fR
Returns a list of the names of all packages in the
interpreter for which a version has been provided (via
\fBpackage provide\fR) or for which a \fBpackage ifneeded\fR
script is available.
The order of elements in the list is arbitrary.
.TP
\fBpackage present \fR?\fB\-exact\fR? \fIpackage \fR?\fIversion\fR?
This command is equivalent to \fBpackage require\fR except that it
does not try and load the package if it is not already loaded.
.TP
\fBpackage provide \fIpackage \fR?\fIversion\fR?
This command is invoked to indicate that version \fIversion\fR
of package \fIpackage\fR is now present in the interpreter.
It is typically invoked once as part of an \fBifneeded\fR script,
and again by the package itself when it is finally loaded.
An error occurs if a different version of \fIpackage\fR has been

Changes to doc/pid.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) pid.n 1.5 96/03/25 20:20:57
'\" 
.so man.macros
.TH pid n 7.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pid \- Retrieve process id(s)







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: pid.n,v 1.1.2.1 1998/09/24 23:58:34 stanton Exp $
'\" 
.so man.macros
.TH pid n 7.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pid \- Retrieve process id(s)

Changes to doc/pkgMkIndex.n.

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) 1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) pkgMkIndex.n 1.8 97/10/31 12:51:13
'\" 
.so man.macros
.TH pkg_mkIndex n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pkg_mkIndex \- Build an index for automatic loading of packages
.SH SYNOPSIS
.nf

\fBpkg_mkIndex \fIdir\fR \fIpattern \fR?\fIpattern pattern ...\fR?

.fi
.BE

.SH DESCRIPTION
.PP
\fBPkg_mkIndex\fR is a utility procedure that is part of the standard
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
'\"
'\" Copyright (c) 1996 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: pkgMkIndex.n,v 1.1.2.4 1998/12/02 20:08:03 welch Exp $
'\" 
.so man.macros
.TH pkg_mkIndex n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pkg_mkIndex \- Build an index for automatic loading of packages
.SH SYNOPSIS
.nf
.VS 8.0.3
\fBpkg_mkIndex ?\fI-direct\fR? ?\fI-load pkgPat\fR? ?\fI-verbose\fR? \fIdir\fR ?\fIpattern pattern ...\fR?
.VE
.fi
.BE

.SH DESCRIPTION
.PP
\fBPkg_mkIndex\fR is a utility procedure that is part of the standard
Tcl library.
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
the package and version number, and each binary file must contain
a call to \fBTcl_PkgProvide\fR.
.IP [2]
Create the index by invoking \fBpkg_mkIndex\fR.
The \fIdir\fR argument gives the name of a directory and each
\fIpattern\fR argument is a \fBglob\fR-style pattern that selects
script or binary files in \fIdir\fR.




\fBPkg_mkIndex\fR will create a file \fBpkgIndex.tcl\fR in \fIdir\fR
with package information about all the files given by the \fIpattern\fR
arguments.
It does this by loading each file and seeing what packages

and new commands appear (this is why it is essential to have
\fBpackage provide\fR commands or \fBTcl_PkgProvide\fR calls
in the files, as described above).





.VS "" br
.IP [3]
Install the package as a subdirectory of one of the directories given by
the \fBtcl_pkgPath\fR variable.  If \fB$tcl_pkgPath\fR contains more
than one directory, machine-dependent packages (e.g., those that
contain binary shared libraries) should normally be installed
under the first directory and machine-independent packages (e.g.,
those that contain only Tcl scripts) should be installed under the
second directory.
The subdirectory should include
the package's script and/or binary files as well as the \fBpkgIndex.tcl\fR
file.  As long as the package is installed as a subdirectory of a
directory in \fB$tcl_pkgPath\fR it will automatically be found during
\fBpackage require\fR commands.
.RS
.LP
If you install the package anywhere else, then you must ensure that
the directory contaiingn the package is in the \fBauto_path\fR global variable
or an immediate subdirectory of one of the directories in \fBauto_path\fR.
\fBAuto_path\fR contains a list of directories that are searched
by both the auto-loader and the package loader; by default it
includes \fB$tcl_pkgPath\fR.
The package loader also checks all of the subdirectories of the
directories in \fBauto_path\fR.
.VE
You can add a directory to \fBauto_path\fR explicitly in your
application, or you can add the directory to your \fBTCLLIBPATH\fR
environment variable:  if this environment variable is present,
Tcl initializes \fBauto_path\fR from it during application startup.
.RE
.IP [4]
Once the above steps have been taken, all you need to do to use a
package is to invoke \fBpackage require\fR.
For example, if versions 2.1, 2.3, and 3.1 of package \fBTest\fR
have been indexed by \fBpkg_mkIndex\fR, the command
\fBpackage require Test\fR will make version 3.1 available
and the command \fBpackage require \-exact Test 2.1\fR will
make version 2.1 available.
There may be many versions of a package in the various index files
in \fBauto_path\fR, but only one will actually be loaded in a given
interpreter, based on the first call to \fBpackage require\fR.
Different versions of a package may be loaded in different
interpreters.






















.SH "PACKAGES AND THE AUTO-LOADER"
.PP
The package management facilities overlap somewhat with the auto-loader,
in that both arrange for files to be loaded on-demand.
However, package management is a higher-level mechanism that uses
the auto-loader for the last step in the loading process.
It is generally better to index a package with \fBpkg_mkIndex\fR







>
>
>
>



|
>



>
>
>
>
>
|













|
<

|






<




<














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







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
the package and version number, and each binary file must contain
a call to \fBTcl_PkgProvide\fR.
.IP [2]
Create the index by invoking \fBpkg_mkIndex\fR.
The \fIdir\fR argument gives the name of a directory and each
\fIpattern\fR argument is a \fBglob\fR-style pattern that selects
script or binary files in \fIdir\fR.
.VS 8.0.3
The default pattern is \fB*.tcl\fR and \fB*.[info sharedlibextension]\fR.
.VE
.sp 1
\fBPkg_mkIndex\fR will create a file \fBpkgIndex.tcl\fR in \fIdir\fR
with package information about all the files given by the \fIpattern\fR
arguments.
It does this by loading each file into a slave
interpreter and seeing what packages
and new commands appear (this is why it is essential to have
\fBpackage provide\fR commands or \fBTcl_PkgProvide\fR calls
in the files, as described above).
If you have a package split among scripts and binary files, 
or if you have dependencies among files,
you may have to use the \fB-load\fP option
or adjust the order in which \fBpkg_mkIndex\fR processes
the files.  See COMPLEX CASES below.

.IP [3]
Install the package as a subdirectory of one of the directories given by
the \fBtcl_pkgPath\fR variable.  If \fB$tcl_pkgPath\fR contains more
than one directory, machine-dependent packages (e.g., those that
contain binary shared libraries) should normally be installed
under the first directory and machine-independent packages (e.g.,
those that contain only Tcl scripts) should be installed under the
second directory.
The subdirectory should include
the package's script and/or binary files as well as the \fBpkgIndex.tcl\fR
file.  As long as the package is installed as a subdirectory of a
directory in \fB$tcl_pkgPath\fR it will automatically be found during
\fBpackage require\fR commands.
.sp 1

If you install the package anywhere else, then you must ensure that
the directory containing the package is in the \fBauto_path\fR global variable
or an immediate subdirectory of one of the directories in \fBauto_path\fR.
\fBAuto_path\fR contains a list of directories that are searched
by both the auto-loader and the package loader; by default it
includes \fB$tcl_pkgPath\fR.
The package loader also checks all of the subdirectories of the
directories in \fBauto_path\fR.

You can add a directory to \fBauto_path\fR explicitly in your
application, or you can add the directory to your \fBTCLLIBPATH\fR
environment variable:  if this environment variable is present,
Tcl initializes \fBauto_path\fR from it during application startup.

.IP [4]
Once the above steps have been taken, all you need to do to use a
package is to invoke \fBpackage require\fR.
For example, if versions 2.1, 2.3, and 3.1 of package \fBTest\fR
have been indexed by \fBpkg_mkIndex\fR, the command
\fBpackage require Test\fR will make version 3.1 available
and the command \fBpackage require \-exact Test 2.1\fR will
make version 2.1 available.
There may be many versions of a package in the various index files
in \fBauto_path\fR, but only one will actually be loaded in a given
interpreter, based on the first call to \fBpackage require\fR.
Different versions of a package may be loaded in different
interpreters.

.SH OPTIONS
The optional switches are:
.TP 15
\fB\-direct\fR
The generated index
will manage to load the package immediately upon \fBpackage require\fR
instead of delaying loading until actual use of one of the commands.
.TP 15
\fB\-load \fIpkgPat\fR
The index process will pre-load any packages that exist in the
current interpreter and match \fIpkgPat\fP into the slave interpreter used to
generate the index.  The pattern match uses string match rules.
See COMPLEX CASES below.
.TP 15
\fB\-verbose\fR
Generate output during the indexing process.  Output is via
the \fBtclLog\fP procedure, which by default prints to stderr.
.TP 15
\fB\-\-\fR
End of the flags, in case \fIdir\fP begins with a dash.

.SH "PACKAGES AND THE AUTO-LOADER"
.PP
The package management facilities overlap somewhat with the auto-loader,
in that both arrange for files to be loaded on-demand.
However, package management is a higher-level mechanism that uses
the auto-loader for the last step in the loading process.
It is generally better to index a package with \fBpkg_mkIndex\fR
120
121
122
123
124
125
126




127
128
129
130




131
132
133



































































134
135
evaluates all of the \fBpkgIndex.tcl\fR files in the
\fBauto_path\fR.
The \fBpkgIndex.tcl\fR files contain \fBpackage ifneeded\fR
commands for each version of each available package;  these commands
invoke \fBpackage provide\fR commands to announce the
availability of the package, and they setup auto-loader
information to load the files of the package.




A given file of a given version of a given package isn't
actually loaded until the first time one of its commands
is invoked.
Thus, after invoking \fBpackage require\fR you won't see




the package's commands in the interpreter, but you will be able
to invoke the commands and they will be auto-loaded.




































































.SH KEYWORDS
auto-load, index, package, version







>
>
>
>
|


|
>
>
>
>



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


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
evaluates all of the \fBpkgIndex.tcl\fR files in the
\fBauto_path\fR.
The \fBpkgIndex.tcl\fR files contain \fBpackage ifneeded\fR
commands for each version of each available package;  these commands
invoke \fBpackage provide\fR commands to announce the
availability of the package, and they setup auto-loader
information to load the files of the package.
.VS 8.0.3
Unless the \fI-direct\fR flag was provided when the \fBpkgIndex.tcl\fR
was generated,
.VE
a given file of a given version of a given package isn't
actually loaded until the first time one of its commands
is invoked.
Thus, after invoking \fBpackage require\fR you
.VS 8.0.3
may
.VE
not see
the package's commands in the interpreter, but you will be able
to invoke the commands and they will be auto-loaded.

.VS 8.0.3
.SH "DIRECT LOADING"
.PP
Some packages, for instance packages which use namespaces and export
commands or those which require special initialization, might select
that their package files be loaded immediately upon \fBpackage require\fR
instead of delaying the actual loading to the first use of one of the
package's command. This mode is enabled when generating the package
index by specifying the \fI-direct\fR argument.
.VE

.SH "COMPLEX CASES"
Most complex cases of dependencies among scripts
and binary files, and packages being split among scripts and
binary files are handled OK.  However, you may have to adjust
the order in which files are processed by \fBpkg_mkIndex\fR.
These issues are described in detail below.
.PP
If each script or file contains one package, and packages
are only contained in one file, then things are easy.
You simply specify all files to be indexed in any order
with some glob patterns.
.PP
In general, it is OK for scripts to have dependencies on other
packages.
If scripts contain \fBpackage require\fP commands, these are
stubbed out in the interpreter used to process the scripts,
so these do not cause problems.
If scripts call into other packages in global code,
these calls are handled by a stub \fBunknown\fP command.
However, if scripts make variable references to other package's
variables in global code, these will cause errors.  That is
also bad coding style.
.PP
If binary files have dependencies on other packages, things
can become tricky because it is not possible to stub out
C-level API's such as \fBTcl_PkgRequire\fP API
when loading a binary file.
For example, suppose the BLT package requires Tk, and expresses
this with a call to \fBTcl_PkgRequire\fP in its \fBBlt_Init\fP routine.
To support this, you must run \fBpkg_mkIndex\fR in an interpreter that
has Tk loaded.  You can achieve this with the
\fB-load \fIpkgPat\fR option.  If you specify this option,
\fBpkg_mkIndex\fR will load any packages listed by
\fBinfo loaded\fP and that match \fIpkgPat\fP
into the interpreter used to process files.
In most cases this will satisfy the \fBTcl_PkgRequire\fP calls
made by binary files.
.PP
If you are indexing two binary files and one depends on the other,
you should specify the one that has dependencies last.
This way the one without dependencies will get loaded and indexed,
and then the package it provides
will be available when the second file is processed.
You may also need to load the first package into the
temporary interpreter used to create the index by using
the \fB-load\fP flag;
it won't hurt to specify package patterns that are not yet loaded.
.PP
If you have a package that is split across scripts and a binary file,
then you should avoid the \fB-load\fP flag. The problem is that
if you load a package before computing the index it masks any
other files that provide part of the same package.
If you must use \fB-load\fP,
then you must specify the scripts first; otherwise the package loaded from
the binary file may mask the package defined by the scripts.

.SH KEYWORDS
auto-load, index, package, version

Changes to doc/proc.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) proc.n 1.6 97/05/18 15:49:45
'\" 
.so man.macros
.TH proc n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
proc \- Create a Tcl procedure







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: proc.n,v 1.1.2.1 1998/09/24 23:58:34 stanton Exp $
'\" 
.so man.macros
.TH proc n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
proc \- Create a Tcl procedure

Changes to doc/puts.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) puts.n 1.11 96/08/26 13:00:09
'\" 
.so man.macros
.TH puts n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
puts \- Write to a channel







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: puts.n,v 1.1.2.2 1999/04/09 18:42:02 surles Exp $
'\" 
.so man.macros
.TH puts n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
puts \- Write to a channel
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
.PP
Newline characters in the output are translated by \fBputs\fR to
platform-specific end-of-line sequences according to the current
value of the \fB\-translation\fR option for the channel (for example,
on PCs newlines are normally replaced with carriage-return-linefeed
sequences;  on Macintoshes newlines are normally replaced with
carriage-returns).
See the \fBfconfigure\fR manual entry for a discussion of end-of-line
translations.
.PP
Tcl buffers output internally, so characters written with \fBputs\fR
may not appear immediately on the output file or device;  Tcl will
normally delay output until the buffer is full or the channel is
closed.
You can force output to appear immediately with the \fBflush\fR
command.







|
|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
.PP
Newline characters in the output are translated by \fBputs\fR to
platform-specific end-of-line sequences according to the current
value of the \fB\-translation\fR option for the channel (for example,
on PCs newlines are normally replaced with carriage-return-linefeed
sequences;  on Macintoshes newlines are normally replaced with
carriage-returns).
See the \fBfconfigure\fR manual entry for a discussion on ways in
which \fBfconfigure\fR will alter output.
.PP
Tcl buffers output internally, so characters written with \fBputs\fR
may not appear immediately on the output file or device;  Tcl will
normally delay output until the buffer is full or the channel is
closed.
You can force output to appear immediately with the \fBflush\fR
command.

Changes to doc/pwd.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) pwd.n 1.5 96/03/25 20:21:30
'\" 
.so man.macros
.TH pwd n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pwd \- Return the current working directory







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: pwd.n,v 1.1.2.1 1998/09/24 23:58:35 stanton Exp $
'\" 
.so man.macros
.TH pwd n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
pwd \- Return the current working directory

Changes to doc/read.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) read.n 1.15 96/08/26 13:00:09
'\" 
.so man.macros
.TH read n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
read \- Read from a channel







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: read.n,v 1.1.2.2 1999/04/09 18:42:03 surles Exp $
'\" 
.so man.macros
.TH read n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
read \- Read from a channel
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
for more input.
The \fB\-nonewline\fR switch is ignored if the command returns
before reaching the end of the file.
.PP
\fBRead\fR translates end-of-line sequences in the input into
newline characters according to the \fB\-translation\fR option
for the channel.
See the manual entry for \fBfconfigure\fR for details on the
\fB\-translation\fR option.

.SH "SEE ALSO"
eof(n), fblocked(n), fconfigure(n)

.SH KEYWORDS
blocking, channel, end of line, end of file, nonblocking, read, translation







|
|






36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
for more input.
The \fB\-nonewline\fR switch is ignored if the command returns
before reaching the end of the file.
.PP
\fBRead\fR translates end-of-line sequences in the input into
newline characters according to the \fB\-translation\fR option
for the channel.
See the \fBfconfigure\fR manual entry for a discussion on ways in
which \fBfconfigure\fR will alter input.

.SH "SEE ALSO"
eof(n), fblocked(n), fconfigure(n)

.SH KEYWORDS
blocking, channel, end of line, end of file, nonblocking, read, translation

Changes to doc/regexp.n.

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
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) regexp.n 1.12 96/08/26 13:00:10
'\" 
.so man.macros
.TH regexp n "" 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

.SH SYNOPSIS
\fBregexp \fR?\fIswitches\fR? \fIexp string \fR?\fImatchVar\fR? ?\fIsubMatchVar subMatchVar ...\fR?
.BE

.SH DESCRIPTION
.PP
Determines whether the regular expression \fIexp\fR matches part or
all of \fIstring\fR and returns 1 if it does, 0 if it doesn't.
.LP
If additional arguments are specified after \fIstring\fR then they
are treated as the names of variables in which to return
information about which part(s) of \fIstring\fR matched \fIexp\fR.
\fIMatchVar\fR will be set to the range of \fIstring\fR that
matched all of \fIexp\fR.  The first \fIsubMatchVar\fR will contain
the characters in \fIstring\fR that matched the leftmost parenthesized
subexpression within \fIexp\fR, the next \fIsubMatchVar\fR will
contain the characters that matched the next parenthesized
subexpression to the right in \fIexp\fR, and so on.
.LP
If the initial arguments to \fBregexp\fR start with \fB\-\fR then
they are treated as switches.  The following switches are
currently supported:
.TP 10
\fB\-nocase\fR
Causes upper-case characters in \fIstring\fR to be treated as
lower case during the matching process.
.TP 10
\fB\-indices\fR
Changes what is stored in the \fIsubMatchVar\fRs. 
Instead of storing the matching characters from \fBstring\fR,
each variable
will contain a list of two decimal strings giving the indices
in \fIstring\fR of the first and last characters in the matching
range of characters.

.TP 10

































\fB\-\|\-\fR
Marks the end of switches.  The argument following this one will
be treated as \fIexp\fR even if it starts with a \fB\-\fR.
.LP
If there are more \fIsubMatchVar\fR's than parenthesized
subexpressions within \fIexp\fR, or if a particular subexpression
in \fIexp\fR doesn't match the string (e.g. because it was in a
portion of the expression that wasn't matched), then the corresponding
\fIsubMatchVar\fR will be set to ``\fB\-1 \-1\fR'' if \fB\-indices\fR
has been specified or to an empty string otherwise.















.SH "REGULAR EXPRESSIONS"
.PP
Regular expressions are implemented using Henry Spencer's package

(thanks, Henry!),
and much of the description of regular expressions below is copied verbatim
















































from his manual entry.
.PP




A regular expression is zero or more \fIbranches\fR, separated by ``|''.

























































It matches anything that matches one of the branches.









.PP





A branch is zero or more \fIpieces\fR, concatenated.






It matches a match for the first, followed by a match for the second, etc.

.PP




























A piece is an \fIatom\fR possibly followed by ``*'', ``+'', or ``?''.






















An atom followed by ``*'' matches a sequence of 0 or more matches of the atom.





An atom followed by ``+'' matches a sequence of 1 or more matches of the atom.



















An atom followed by ``?'' matches a match of the atom, or the null string.

.PP






























An atom is a regular expression in parentheses (matching a match for the






















regular expression), a \fIrange\fR (see below), ``.''



(matching any single character), ``^'' (matching the null string at the
beginning of the input string), ``$'' (matching the null string at the


end of the input string), a ``\e'' followed by a single character (matching

that character), or a single character with no other significance
(matching that character).



























.PP


























A \fIrange\fR is a sequence of characters enclosed in ``[]''.

















It normally matches any single character from the sequence.
















If the sequence begins with ``^'',


it matches any single character \fInot\fR from the rest of the sequence.


If two characters in the sequence are separated by ``\-'', this is shorthand








for the full list of ASCII characters between them












(e.g. ``[0-9]'' matches any decimal digit).







To include a literal ``]'' in the sequence, make it the first character
(following a possible ``^'').













To include a literal ``\-'', make it the first or last character.
















































































































































































































































.SH "CHOOSING AMONG ALTERNATIVE MATCHES"
.PP
In general there may be more than one way to match a regular expression
to an input string.  For example, consider the command
.CS

\fBregexp  (a*)b*  aabaaabb  x  y\fR
.CE

Considering only the rules given so far, \fBx\fR and \fBy\fR could
end up with the values \fBaabb\fR and \fBaa\fR, \fBaaab\fR and \fBaaa\fR,
\fBab\fR and \fBa\fR, or any of several other combinations.
To resolve this potential ambiguity \fBregexp\fR chooses among




alternatives using the rule ``first then longest''.
In other words, it considers the possible matches in order working
from left to right across the input string and the pattern, and it
attempts to match longer pieces of the input string before shorter
ones.  More specifically, the following rules apply in decreasing

order of priority:
.IP [1]


If a regular expression could match two different parts of an input string




then it will match the one that begins earliest.
.IP [2]
If a regular expression contains \fB|\fR operators then the leftmost













matching sub-expression is chosen.
.IP [3]







In \fB*\fR, \fB+\fR, and \fB?\fR constructs, longer matches are chosen




















in preference to shorter ones.












.IP [4]


In sequences of expression components the components are considered















from left to right.
.LP
In the example from above, \fB(a*)b*\fR matches \fBaab\fR:  the \fB(a*)\fR















portion of the pattern is matched first and it consumes the leading






















\fBaa\fR; then the \fBb*\fR portion of the pattern consumes the



next \fBb\fR.  Or, consider the following example:





.CS














\fBregexp  (ab|a)(b*)c  abc  x  y  z\fR






.CE






After this command \fBx\fR will be \fBabc\fR, \fBy\fR will be
\fBab\fR, and \fBz\fR will be an empty string.



Rule 4 specifies that \fB(ab|a)\fR gets first shot at the input
string and Rule 2 specifies that the \fBab\fR sub-expression


is checked before the \fBa\fR sub-expression.
Thus the \fBb\fR has already been claimed before the \fB(b*)\fR


component is checked and \fB(b*)\fR must match an empty string.








































































.SH KEYWORDS
match, regular expression, string

<
|




|


|




>


















|



|



|


|




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



|







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

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

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

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

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

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

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

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

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


1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783

784
785

786
787
788
789
790
791
792
793
794
795
796



797
798
799
800
801
802
803
804
805
806
807
808

809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885

886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968

969
970
971

972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
'\"

'\" 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.1.2.6 1999/04/09 18:42:03 surles 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

.SH SYNOPSIS
\fBregexp \fR?\fIswitches\fR? \fIexp string \fR?\fImatchVar\fR? ?\fIsubMatchVar subMatchVar ...\fR?
.BE

.SH DESCRIPTION
.PP
Determines whether the regular expression \fIexp\fR matches part or
all of \fIstring\fR and returns 1 if it does, 0 if it doesn't.
.LP
If additional arguments are specified after \fIstring\fR then they
are treated as the names of variables in which to return
information about which part(s) of \fIstring\fR matched \fIexp\fR.
\fIMatchVar\fR will be set to the range of \fIstring\fR that
matched all of \fIexp\fR.  The first \fIsubMatchVar\fR will contain
the characters in \fIstring\fR that matched the leftmost parenthesized
subexpression within \fIexp\fR, the next \fIsubMatchVar\fR will
contain the characters that matched the next parenthesized
subexpression to the right in \fIexp\fR, and so on.
.PP
If the initial arguments to \fBregexp\fR start with \fB\-\fR then
they are treated as switches.  The following switches are
currently supported:
.TP 15
\fB\-nocase\fR
Causes upper-case characters in \fIstring\fR to be treated as
lower case during the matching process.
.TP 15
\fB\-indices\fR
Changes what is stored in the \fIsubMatchVar\fRs. 
Instead of storing the matching characters from \fIstring\fR,
each variable
will contain a list of two decimal strings giving the indices
in \fIstring\fR of the first and last characters in the matching
range of characters.
.VS 8.1
.TP 15
\fB\-expanded\fR
Enables use of the expanded regular expression syntax where
whitespace and comments are ignored.  This is the same as specifying
the \fB(?x)\fR embedded option (see METASYNTAX, below).
.TP 15
\fB\-line\fR
Enables newline-sensitive matching.  By default, newline is a
completely ordinary character with no special meaning.  With this
flag, `[^' bracket expressions and `.' never match newline, `^'
matches an empty string after any newline in addition to its normal
function, and `$' matches an empty string before any newline in
addition to its normal function.  This flag is equivalent to
specifying both \fB\-linestop\fR and \fB\-lineanchor\fR, or the
\fB(?n)\fR embedded option (see METASYNTAX, below).
.TP 15
\fB\-linestop\fR
Changes the behavior of `[^' bracket expressions and `.' so that they
stop at newlines.  This is the same as specifying the \fB(?p)\fR
embedded option (see METASYNTAX, below).
.TP 15
\fB\-lineanchor\fR
Changes the behavior of `^' and `$' (the ``anchors'') so they match the
beginning and end of a line respectively.  This is the same as
specifying the \fB(?w)\fR embedded option (see METASYNTAX, below).
.TP 15
\fB\-about\fR
Instead of attempting to match the regular expression, returns a list
containing information about the regular expression.  The first
element of the list is a subexpression count.  The second element is a
list of property names that describe various attributes of the regular
expression. This switch is primarily intended for debugging purposes.
.VE 8.1
.TP 15
\fB\-\|\-\fR
Marks the end of switches.  The argument following this one will
be treated as \fIexp\fR even if it starts with a \fB\-\fR.
.PP
If there are more \fIsubMatchVar\fR's than parenthesized
subexpressions within \fIexp\fR, or if a particular subexpression
in \fIexp\fR doesn't match the string (e.g. because it was in a
portion of the expression that wasn't matched), then the corresponding
\fIsubMatchVar\fR will be set to ``\fB\-1 \-1\fR'' if \fB\-indices\fR
has been specified or to an empty string otherwise.

.SH "DIFFERENT FLAVORS OF REs"
.VS 8.1
Regular expressions (``RE''s), as defined by POSIX, come in two
flavors: \fIextended\fR REs (``EREs'') and \fIbasic\fR REs (``BREs'').
EREs are roughly those of the traditional \fIegrep\fR, while BREs are
roughly those of the traditional \fIed\fR .  This implementation adds
a third flavor, \fIadvanced\fR REs (``AREs''), basically EREs with
some significant extensions.
.PP
This manual page primarily describes AREs.  BREs mostly exist for
backward compatibility in some old programs; they will be discussed at
the end.  POSIX EREs are almost an exact subset of AREs.  Features of
AREs that are not present in EREs will be indicated.

.SH "REGULAR EXPRESSION SYNTAX"
.PP
Tcl regular expressions are implemented using the package written by
Henry Spencer, based on the 1003.2 spec and some (not quite all) of
the Perl5 extensions (thanks, Henry!).  Much of the description of
regular expressions below is copied verbatim from his manual entry.
.PP
An ARE is one or more \fIbranches\fR,
separated by `\fB|\fR',
matching anything that matches any of the branches.
.PP
A branch is zero or more \fIconstraints\fR or \fIquantified atoms\fR,
concatenated.
It matches a match for the first, followed by a match for the second, etc;
an empty branch matches the empty string.
.PP
A quantified atom is an \fIatom\fR possibly followed
by a single \fIquantifier\fR.
Without a quantifier, it matches a match for the atom.
The quantifiers,
and what a so-quantified atom matches, are:
.RS 2
.TP 6
\fB*\fR
a sequence of 0 or more matches of the atom
.TP
\fB+\fR
a sequence of 1 or more matches of the atom
.TP
\fB?\fR
a sequence of 0 or 1 matches of the atom
.TP
\fB{\fIm\fB}\fR
a sequence of exactly \fIm\fR matches of the atom
.TP
\fB{\fIm\fB,}\fR
a sequence of \fIm\fR or more matches of the atom
.TP
\fB{\fIm\fB,\fIn\fB}\fR
a sequence of \fIm\fR through \fIn\fR (inclusive) matches of the atom;
\fIm\fR may not exceed \fIn\fR
.TP
\fB*?  +?  ??  {\fIm\fB}?  {\fIm\fB,}?  {\fIm\fB,\fIn\fB}?\fR
\fInon-greedy\fR quantifiers,
which match the same possibilities,
but prefer the smallest number rather than the largest number
of matches (see MATCHING)
.RE
.PP
The forms using
\fB{\fR and \fB}\fR
are known as \fIbound\fRs.
The numbers
\fIm\fR and \fIn\fR are unsigned decimal integers
with permissible values from 0 to 255 inclusive.
.PP
An atom is one of:
.RS 2
.TP 6
\fB(\fIre\fB)\fR
(where \fIre\fR is any regular expression)
matches a match for
\fIre\fR, with the match noted for possible reporting
.TP
\fB(?:\fIre\fB)\fR
as previous,
but does no reporting
(a ``non-capturing'' set of parentheses)
.TP
\fB()\fR
matches an empty string,
noted for possible reporting
.TP
\fB(?:)\fR
matches an empty string,
without reporting
.TP
\fB[\fIchars\fB]\fR
a \fIbracket expression\fR,
matching any one of the \fIchars\fR (see BRACKET EXPRESSIONS for more detail)
.TP
 \fB.\fR
matches any single character
.TP
\fB\e\fIk\fR
(where \fIk\fR is a non-alphanumeric character)
matches that character taken as an ordinary character,
e.g. \e\e matches a backslash character
.TP
\fB\e\fIc\fR
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
.PP
A \fIconstraint\fR matches an empty string when specific conditions
are met.
A constraint may not be followed by a quantifier.
The simple constraints are as follows; some more constraints are
described later, under ESCAPES.
.RS 2
.TP 8
\fB^\fR
matches at the beginning of a line
.TP
\fB$\fR
matches at the end of a line
.TP
\fB(?=\fIre\fB)\fR
\fIpositive lookahead\fR (AREs only), matches at any point
where a substring matching \fIre\fR begins
.TP
\fB(?!\fIre\fB)\fR
\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
endpoint, so e.g.
\fBa\-c\-e\fR
is illegal.
Ranges are very collating-sequence-dependent,
and portable programs should avoid relying on them.
.PP
To include a literal
\fB]\fR
or
\fB\-\fR
in the list,
the simplest method is to
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
Within a bracket expression, a collating element (a character,
a multi-character sequence that collates as if it were a single character,
or a collating-sequence name for either)
enclosed in
\fB[.\fR
and
\fB.]\fR
stands for the
sequence of characters of that collating element.
The sequence is a single element of the bracket expression's list.
A bracket expression in a locale which has
multi-character collating elements
can thus match more than one character.
Most insidiously, if
\fB^\fR
is used,
this can happen even if no multi-character collating 
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
and
\fB:]\fR
stands for the list of all characters
(not all collating elements!)
belonging to that
class.
Standard character class names are:
.PP
.RS
.ne 5
.nf
.ta 3c 6c 9c
\fBalnum	digit	punct
alpha	graph	space
blank	lower	upper
cntrl	print	xdigit\fR
.fi
.RE
.PP
These stand for the character classes defined in
\fIctype\fR(3).
A locale may provide others.
A character class may not be used as an endpoint of a range.
.PP
There are two special cases of bracket expressions:
the bracket expressions
\fB[[:<:]]\fR
and
\fB[[:>:]]\fR
are constraints, matching empty strings at
the beginning and end of a word respectively.
'\" note, discussion of escapes below references this definition of word
A word is defined as a sequence of
word characters
which is neither preceded nor followed by
word characters.
A word character is an
\fIalnum\fR
character (as defined by
\fIctype\fR(3))
or an underscore
(\fB_\fR).
These special bracket expressions are deprecated;
users of AREs should use constraint escapes instead (see below).
.SH ESCAPES
Escapes (AREs only), which begin with a
\fB\e\fR
followed by an alphanumeric character,
come in several varieties:
character entry, class shorthands, constraint escapes, and back references.
A
\fB\e\fR
followed by an alphanumeric character but not constituting
a valid escape is illegal in AREs.
In EREs, there are no escapes:
outside a bracket expression,
a
\fB\e\fR
followed by an alphanumeric character merely stands for that
character as an ordinary character,
and inside a bracket expression,
\fB\e\fR
is an ordinary character.
(The latter is the one actual incompatibility between EREs and AREs.)
.PP
Character-entry escapes (AREs only) exist to make it easier to specify
non-printing and otherwise inconvenient characters in REs:
.RS 2
.TP 5
\fB\ea\fR
alert, aka bell, character, as in C
.TP
\fB\eb\fR
backspace, as in C
.TP
\fB\eB\fR
synonym for
\fB\e\fR
to help reduce backslash doubling in some
applications where there are multiple levels of backslash processing
.TP
\fB\ec\fIX\fR
(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
.TP
\fB\er\fR
carriage return, as in C
.TP
\fB\et\fR
horizontal tab, as in C
.TP
\fB\eu\fIwxyz\fR
(where
\fIwxyz\fR
is exactly four hexadecimal digits)
the Unicode character
\fBU+\fIwxyz\fR
in the local byte ordering
.TP
\fB\eU\fIstuvwxyz\fR
(where
\fIstuvwxyz\fR
is exactly eight hexadecimal digits)
reserved for a somewhat-hypothetical Unicode extension to 32 bits
.TP
\fB\ev\fR
vertical tab, as in C
are all available.
.TP
\fB\ex\fIhhh\fR
(where
\fIhhh\fR
is any sequence of hexadecimal digits)
the character whose hexadecimal value is
\fB0x\fIhhh\fR
(a single character no matter how many hexadecimal digits are used).
.TP
\fB\e0\fR
the character whose value is
\fB0\fR
.TP
\fB\e\fIxy\fR
(where
\fIxy\fR
is exactly two octal digits,
and is not a
\fIback reference\fR (see below))
the character whose octal value is
\fB0\fIxy\fR
.TP
\fB\e\fIxyz\fR
(where
\fIxyz\fR
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
.TP
\fB\es\fR
\fB[[:space:]]\fR
.TP
\fB\ew\fR
\fB[[:alnum:]_]\fR
(note underscore)
.TP
\fB\eD\fR
\fB[^[:digit:]]\fR
.TP
\fB\eS\fR
\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
(where
\fIm\fR
is a nonzero digit, and
\fInn\fR
is some more digits,
and the decimal value
\fImnn\fR
is not greater than the number of closing capturing parentheses seen so far)
a \fIback reference\fR, see below
.RE
.PP
A word is defined as in the specification of
\fB[[:<:]]\fR
and
\fB[[:>:]]\fR
above.
Constraint escapes are illegal within bracket expressions.
.PP
A back reference (AREs only) matches the same string matched by the parenthesized
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.
A leading zero always indicates an octal escape.
A single non-zero digit, not followed by another digit,
is always taken as a back reference.
A multi-digit sequence not starting with a zero is taken as a back 
reference if it comes after a suitable subexpression
(i.e. the number is in the legal range for a back reference),
and otherwise is taken as octal.
.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
\fIxyz\fR
is one or more alphabetic characters)
specifies options affecting the rest of the RE.
These supplement, and can override,
any options specified by the application.
The available option letters are:
.RS 2
.TP 3
\fBb\fR
rest of RE is a BRE
.TP 3
\fBc\fR
case-sensitive matching (usual default)
.TP 3
\fBe\fR
rest of RE is an ERE
.TP 3
\fBi\fR
case-insensitive matching (see MATCHING, below)
.TP 3
\fBm\fR
historical synonym for
\fBn\fR
.TP 3
\fBn\fR
newline-sensitive matching (see MATCHING, below)
.TP 3
\fBp\fR
partial newline-sensitive matching (see MATCHING, below)
.TP 3
\fBq\fR
rest of RE is a literal (``quoted'') string, all ordinary characters
.TP 3
\fBs\fR
non-newline-sensitive matching (usual default)
.TP 3
\fBt\fR
tight syntax (usual default; see below)
.TP 3
\fBw\fR
inverse partial newline-sensitive (``weird'') matching (see MATCHING, below)
.TP 3
\fBx\fR
expanded syntax (see below)
.RE
.PP
Embedded options take effect at the
\fB)\fR
terminating the sequence.
They are available only at the start of an ARE,
and may not be used later within it.
.PP
In addition to the usual (\fItight\fR) RE syntax, in which all characters are
significant, there is an \fIexpanded\fR syntax,
available in all flavors of RE
with the \fB-expanded\fR switch, or in AREs with the embedded x option.
In the expanded syntax,
white-space characters are ignored
and all characters between a
\fB#\fR
and the following newline (or the end of the RE) are ignored,
permitting paragraphing and commenting a complex RE.
There are three exceptions to that basic rule:
.RS 2
.PP
a white-space character or `\fB#\fR' preceded by `\fB\e\fR' is retained
.PP
white space or `\fB#\fR' within a bracket expression is retained
.PP
white space and comments are illegal within multi-character symbols
like the ARE `\fB(?:\fR' or the BRE `\fB\e(\fR'
.RE
.PP
Expanded-syntax
white-space characters are blank, tab, newline, etc. (any character
defined as \fIspace\fR by
\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
director)
has specified that the user's input be treated as a literal string
rather than as an RE.
.SH MATCHING
In the event that an RE could match more than one substring of a given
string,
the RE matches the one starting earliest in the string.
If the RE could match more than one substring starting at that point,
its choice is determined by its \fIpreference\fR:
either the longest substring, or the shortest.
.PP
Most atoms, and all constraints, have no preference.
A parenthesized RE has the same preference (possibly none) as the RE.

A quantified atom with quantifier
\fB{\fIm\fB}\fR

or
\fB{\fIm\fB}?\fR
has the same preference (possibly none) as the atom itself.
A quantified atom with other normal quantifiers (including
\fB{\fIm\fB,\fIn\fB}\fR
with
\fIm\fR
equal to
\fIn\fR)
prefers longest match.
A quantified atom with other non-greedy quantifiers (including



\fB{\fIm\fB,\fIn\fB}?\fR
with
\fIm\fR
equal to
\fIn\fR)
prefers shortest match.
A branch has the same preference as the first quantified atom in it
which has a preference.
An RE consisting of two or more branches connected by the
\fB|\fR
operator prefers longest match.
.PP

Subject to the constraints imposed by the rules for matching the whole RE,
subexpressions also match the longest or shortest possible substrings,
based on their preferences,
with subexpressions starting earlier in the RE taking priority over
ones starting later.
Note that outer subexpressions thus take priority over
their component subexpressions.
.PP
Note that the quantifiers
\fB{1,1}\fR
and
\fB{1,1}?\fR
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
\fB(a*)*\fR
is matched against
\fBbc\fR
both the whole RE and the parenthesized
subexpression match an empty string.
.PP
If case-independent matching is specified,
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
explicitly arranges it)
and
\fB^\fR
and
\fB$\fR
will match the empty string after and before a newline
respectively, in addition to matching at beginning and end of string
respectively.
ARE
\fB\eA\fR
and
\fB\eZ\fR
continue to match beginning or end of string \fIonly\fR.
.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
newline-sensitive matching,
but not
\fB.\fR
and bracket expressions.
This isn't very useful but is provided for symmetry.
.SH "LIMITS AND COMPATIBILITY"
No particular limit is imposed on the length of REs.
Programs intended to be highly portable should not employ REs longer
than 256 bytes,
as a POSIX-compliant implementation can refuse to accept such REs.
.PP
The only feature of AREs that is actually incompatible with
POSIX EREs is that
\fB\e\fR
does not lose its special
significance inside bracket expressions.
All other ARE features use syntax which is illegal or has
undefined or unspecified effects in POSIX EREs;
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
have changed since early beta-test versions of this package.
(The new rules are much simpler and cleaner,
but don't work as hard at guessing the user's real intentions.)
.PP
Henry Spencer's original 1986 \fIregexp\fR package,
still in widespread use (e.g., in pre-8.1 releases of Tcl),
implemented an early version of today's EREs.
There are four incompatibilities between \fIregexp\fR's near-EREs
(`RREs' for short) and AREs.
In roughly increasing order of significance:
.PP
.RS
In AREs,
\fB\e\fR
followed by an alphanumeric character is either an
escape or an error,
while in RREs, it was just another way of writing the 
alphanumeric.
This should not be a problem because there was no reason to write
such a sequence in RREs.
.PP
\fB{\fR
followed by a digit in an ARE is the beginning of a bound,
while in RREs,
\fB{\fR
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
\fB[[:<:]]\fR
and
\fB[[:>:]]\fR
respectively;
no other escapes are available.

.VE 8.1
.SH KEYWORDS
match, regular expression, string

Changes to doc/registry.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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.
'\"
'\" SCCS: @(#) registry.n 1.5 97/08/11 19:33:27
'\" 
.so man.macros
.TH registry n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
registry \- Manipulate the Windows registry






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" 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: registry.n,v 1.1.2.3 1999/04/07 23:53:31 surles Exp $
'\" 
.so man.macros
.TH registry n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
registry \- Manipulate the Windows registry
35
36
37
38
39
40
41

42

43

44
45
46
47
48
49
50
\fIrootname\fB\e\fIkeypath\fR
.IP
\fIrootname\fR
.PP
\fIHostname\fR specifies the name of any valid Windows
host that exports its registry.  The \fIrootname\fR component must be
one of \fBHKEY_LOCAL_MACHINE\fR, \fBHKEY_USERS\fR,

\fBHKEY_CLASSES_ROOT\fR, \fBHKEY_CURRENT_USER\fR, or

\fBHKEY_CURRENT_CONFIG\fR.  The \fIkeypath\fR can be one or more

registry key names separated by backslash (\fB\e\fR) characters.
.PP
\fIOption\fR indicates what to do with the registry key name.  Any
unique abbreviation for \fIoption\fR is acceptable.  The valid options
are:
.TP
\fBregistry delete \fIkeyName\fR ?\fIvalueName\fR?







>
|
>
|
>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
\fIrootname\fB\e\fIkeypath\fR
.IP
\fIrootname\fR
.PP
\fIHostname\fR specifies the name of any valid Windows
host that exports its registry.  The \fIrootname\fR component must be
one of \fBHKEY_LOCAL_MACHINE\fR, \fBHKEY_USERS\fR,
.VS
\fBHKEY_CLASSES_ROOT\fR, \fBHKEY_CURRENT_USER\fR,
\fBHKEY_CURRENT_CONFIG\fR, \fBHKEY_PERFORMANCE_DATA\fR, or
\fBHKEY_DYN_DATA\fR.  The \fIkeypath\fR can be one or more
.VE
registry key names separated by backslash (\fB\e\fR) characters.
.PP
\fIOption\fR indicates what to do with the registry key name.  Any
unique abbreviation for \fIoption\fR is acceptable.  The valid options
are:
.TP
\fBregistry delete \fIkeyName\fR ?\fIvalueName\fR?
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
make it easier to manipulate.  The following types are recognized by the
registry command:
.TP 17
\fBbinary\fR
.
The registry value contains arbitrary binary data.  The data is represented
exactly in Tcl, including any embedded nulls.
Tcl 
.TP
\fBnone\fR
.
The registry value contains arbitrary binary data with no defined
type.  The data is represented exactly in Tcl, including any embedded
nulls.
.TP







<







108
109
110
111
112
113
114

115
116
117
118
119
120
121
make it easier to manipulate.  The following types are recognized by the
registry command:
.TP 17
\fBbinary\fR
.
The registry value contains arbitrary binary data.  The data is represented
exactly in Tcl, including any embedded nulls.

.TP
\fBnone\fR
.
The registry value contains arbitrary binary data with no defined
type.  The data is represented exactly in Tcl, including any embedded
nulls.
.TP

Changes to doc/regsub.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) regsub.n 1.9 96/08/26 13:00:11
'\" 
.so man.macros
.TH regsub n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
regsub \- Perform substitutions based on regular expression pattern matching







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: regsub.n,v 1.1.2.1 1998/09/24 23:58:35 stanton Exp $
'\" 
.so man.macros
.TH regsub n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
regsub \- Perform substitutions based on regular expression pattern matching

Changes to doc/rename.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) rename.n 1.6 97/07/30 17:37:26
'\" 
.so man.macros
.TH rename n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
rename \- Rename or delete a command







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: rename.n,v 1.1.2.1 1998/09/24 23:58:35 stanton Exp $
'\" 
.so man.macros
.TH rename n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
rename \- Rename or delete a command

Changes to doc/resource.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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.
'\" SCCS: @(#) resource.n 1.4 97/09/10 15:22:18
'\" 
.so man.macros
.TH resource n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
resource \- Manipulate Macintosh resources





|







1
2
3
4
5
6
7
8
9
10
11
12
13
'\"
'\" 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: resource.n,v 1.1.2.3 1999/01/29 00:20:43 stanton Exp $
'\" 
.so man.macros
.TH resource n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
resource \- Manipulate Macintosh resources
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
of the name of the actual resource.
.TP
\fB\-file\fR \fIresourceRef\fR
If the \fB-file\fR option is specified then the resource will be
deleted from the file pointed to by \fIresourceRef\fR.  Otherwise the
first resource with the given \fIresourceName\fR and or
\fIresourceId\fR which is found on the resource file path will be 
deleted.  To inspect the file path, use the \fIresource files\fB command.
.RE
.TP
\fBresource files ?\fIresourceRef\fR?
If \fIresourceRef\fRis not provided, this command returns a Tcl list
of the resource references for all the currently open resource files.
The list is in the normal Macintosh search order for resources.  If 
\fIresourceRef\fR is specified, the command will
return the path to the file whose resource fork is represented by that
token.
.TP
\fBresource list \fIresourceType\fR ?\fIresourceRef\fR?
List all of the resources ids of type \fIresourceType\fR (see RESOURCE
TYPES below).  If \fIresourceRef\fR is specified then the command will
limit the search to that particular resource file.  Otherwise, all
resource files currently opened by the application will be searched.
A Tcl list of either the resource name's or resource id's of the found
resources will be returned.  See the RESOURCE IDS section below for
more details about what a resource id is.
.TP
\fBresource open \fIfileName\fR ?\fIpermissions\fR?
Open the resource for the file \fIfileName\fR.  Standard file
permissions may also be specified (see the manual entry for \fBopen\fR
for details).  A resource reference (\fIresourceRef\fR) is returned
that can be used by the other resource commands.  An error can occur
if the file doesn't exist or the file does not have a resource fork.
However, if you open the file with write permissions the file and/or
resource fork will be created instead of generating an error.
.TP







|



















|
|







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
of the name of the actual resource.
.TP
\fB\-file\fR \fIresourceRef\fR
If the \fB-file\fR option is specified then the resource will be
deleted from the file pointed to by \fIresourceRef\fR.  Otherwise the
first resource with the given \fIresourceName\fR and or
\fIresourceId\fR which is found on the resource file path will be 
deleted.  To inspect the file path, use the \fIresource files\fR command.
.RE
.TP
\fBresource files ?\fIresourceRef\fR?
If \fIresourceRef\fRis not provided, this command returns a Tcl list
of the resource references for all the currently open resource files.
The list is in the normal Macintosh search order for resources.  If 
\fIresourceRef\fR is specified, the command will
return the path to the file whose resource fork is represented by that
token.
.TP
\fBresource list \fIresourceType\fR ?\fIresourceRef\fR?
List all of the resources ids of type \fIresourceType\fR (see RESOURCE
TYPES below).  If \fIresourceRef\fR is specified then the command will
limit the search to that particular resource file.  Otherwise, all
resource files currently opened by the application will be searched.
A Tcl list of either the resource name's or resource id's of the found
resources will be returned.  See the RESOURCE IDS section below for
more details about what a resource id is.
.TP
\fBresource open \fIfileName\fR ?\fIaccess\fR?
Open the resource for the file \fIfileName\fR.  Standard file access
permissions may also be specified (see the manual entry for \fBopen\fR
for details).  A resource reference (\fIresourceRef\fR) is returned
that can be used by the other resource commands.  An error can occur
if the file doesn't exist or the file does not have a resource fork.
However, if you open the file with write permissions the file and/or
resource fork will be created instead of generating an error.
.TP

Changes to doc/return.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) return.n 1.13 96/08/26 13:00:12
'\" 
.so man.macros
.TH return n 7.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
return \- Return from a procedure







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: return.n,v 1.1.2.1 1998/09/24 23:58:36 stanton Exp $
'\" 
.so man.macros
.TH return n 7.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
return \- Return from a procedure

Changes to doc/safe.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) safe.n 1.11 97/10/31 12:51:13
'\" 
.so man.macros
.TH "Safe Tcl" n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Safe Base \- A mechanism for creating and manipulating safe interpreters.
.SH SYNOPSIS
.PP
\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
.sp
\fB::safe::interpInit\fR \fIslave\fR ?\fIoptions...\fR?
.sp
\fB::safe::interpConfigure\fR \fIslave\fR ?\fIoptions...\fR?
.sp
\fB::safe::interpDelete\fR \fIslave\fR






|






|

<







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

16
17
18
19
20
21
22
'\"
'\" Copyright (c) 1995-1996 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: safe.n,v 1.1.2.3 1999/04/06 00:43:15 redman Exp $
'\" 
.so man.macros
.TH "Safe Tcl" n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Safe\ Base \- A mechanism for creating and manipulating safe interpreters.
.SH SYNOPSIS

\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
.sp
\fB::safe::interpInit\fR \fIslave\fR ?\fIoptions...\fR?
.sp
\fB::safe::interpConfigure\fR \fIslave\fR ?\fIoptions...\fR?
.sp
\fB::safe::interpDelete\fR \fIslave\fR
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
scripts are prevented from corrupting the state of the hosting
application or computer. Untrusted scripts are also prevented from
disclosing information stored on the hosting computer or in the
hosting application to any party.
.PP
The Safe Base allows a master interpreter to create safe, restricted
interpreters that contain a set of predefined aliases for the \fBsource\fR,
\fBload\fR, \fBfile\fR and \fBexit\fR commands and
are able to use the auto-loading and package mechanisms.
.PP
No knowledge of the file system structure is leaked to the
safe interpreter, because it has access only to a virtualized path
containing tokens. When the safe interpreter requests to source a file, it
uses the token in the virtual path as part of the file name to source; the
master interpreter transparently 







|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
scripts are prevented from corrupting the state of the hosting
application or computer. Untrusted scripts are also prevented from
disclosing information stored on the hosting computer or in the
hosting application to any party.
.PP
The Safe Base allows a master interpreter to create safe, restricted
interpreters that contain a set of predefined aliases for the \fBsource\fR,
\fBload\fR, \fBfile\fR, \fBencoding\fR, and \fBexit\fR commands and
are able to use the auto-loading and package mechanisms.
.PP
No knowledge of the file system structure is leaked to the
safe interpreter, because it has access only to a virtualized path
containing tokens. When the safe interpreter requests to source a file, it
uses the token in the virtual path as part of the file name to source; the
master interpreter transparently 
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
\fBfile\fR ?\fIsubCmd args...\fR?
The \fBfile\fR alias provides access to a safe subset of the subcommands of
the \fBfile\fR command; it allows only \fBdirname\fR, \fBjoin\fR,
\fBextension\fR, \fBroot\fR, \fBtail\fR, \fBpathname\fR and \fBsplit\fR
subcommands. For more details on what these subcommands do see the manual
page for the \fBfile\fR command.
.TP






\fBexit\fR
The calling interpreter is deleted and its computation is stopped, but the
Tcl process in which this interpreter exists is not terminated.

.SH SECURITY
The Safe Base does not attempt to completely prevent annoyance and
denial of service attacks. These forms of attack prevent the
application or user from temporarily using the computer to perform
useful work, for example by consuming all available CPU time or
all available screen real estate.
These attacks, while aggravating, are deemed to be of lesser importance
in general than integrity and privacy attacks that the Safe Base
is to prevent.
.PP
The commands available in a safe interpreter, in addition to
the safe set as defined in \fBinterp\fR manual page, are mediated aliases
for \fBsource\fR, \fBload\fR, \fBexit\fR, and a safe subset of \fBfile\fR.
The safe interpreter can also auto-load code and it can request that
packages be loaded.
.PP
Because some of these commands access the local file system, there is a
potential for information leakage about its directory structure.
To prevent this, commands that take file names as arguments in a safe
interpreter use tokens instead of the real directory names.
These tokens are translated to the real directory name while a request to,
e.g., source a file is mediated by the master interpreter.







>
>
>
>
>
>
















|
|
|







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
\fBfile\fR ?\fIsubCmd args...\fR?
The \fBfile\fR alias provides access to a safe subset of the subcommands of
the \fBfile\fR command; it allows only \fBdirname\fR, \fBjoin\fR,
\fBextension\fR, \fBroot\fR, \fBtail\fR, \fBpathname\fR and \fBsplit\fR
subcommands. For more details on what these subcommands do see the manual
page for the \fBfile\fR command.
.TP
\fBencoding\fR ?\fIsubCmd args...\fR?
The \fBenconding\fR alias provides access to a safe subset of the
subcommands of the \fBencoding\fR command;  it disallows setting of
the system encoding, but allows all other subcommands including
\fBsystem\fR to check the current encoding.
.TP
\fBexit\fR
The calling interpreter is deleted and its computation is stopped, but the
Tcl process in which this interpreter exists is not terminated.

.SH SECURITY
The Safe Base does not attempt to completely prevent annoyance and
denial of service attacks. These forms of attack prevent the
application or user from temporarily using the computer to perform
useful work, for example by consuming all available CPU time or
all available screen real estate.
These attacks, while aggravating, are deemed to be of lesser importance
in general than integrity and privacy attacks that the Safe Base
is to prevent.
.PP
The commands available in a safe interpreter, in addition to
the safe set as defined in \fBinterp\fR manual page, are mediated aliases
for \fBsource\fR, \fBload\fR, \fBexit\fR, and safe subsets of
\fBfile\fR and \fBencoding\fR. The safe interpreter can also auto-load
code and it can request that packages be loaded.
.PP
Because some of these commands access the local file system, there is a
potential for information leakage about its directory structure.
To prevent this, commands that take file names as arguments in a safe
interpreter use tokens instead of the real directory names.
These tokens are translated to the real directory name while a request to,
e.g., source a file is mediated by the master interpreter.

Changes to doc/scan.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) scan.n 1.12 96/08/26 13:00:13
'\" 
.so man.macros
.TH scan n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
scan \- Parse string using conversion specifiers in the style of sscanf







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: scan.n,v 1.1.2.2 1998/11/18 04:15:46 stanton Exp $
'\" 
.so man.macros
.TH scan n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
scan \- Parse string using conversion specifiers in the style of sscanf
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
how to parse it, using \fB%\fR conversion specifiers as in \fBsscanf\fR.
Each \fIvarName\fR gives the name of a variable; when a field is
scanned from \fIstring\fR the result is converted back into a string
and assigned to the corresponding variable.

.SH "DETAILS ON SCANNING"
.PP
\fBScan\fR operates by scanning \fIstring\fR and \fIformatString\fR together.
If the next character in \fIformatString\fR is a blank or tab then it
matches any number of white space characters in \fIstring\fR (including
zero).
Otherwise, if it isn't a \fB%\fR character then it 
must match the next character of \fIstring\fR.
When a \fB%\fR is encountered in \fIformatString\fR, it indicates
the start of a conversion specifier.
A conversion specifier contains three fields after the \fB%\fR:
a \fB*\fR, which indicates that the converted value is to be discarded 

instead of assigned to a variable; a number indicating a maximum field

width; and a conversion character.
All of these fields are optional except for the conversion character.

.PP
When \fBscan\fR finds a conversion specifier in \fIformatString\fR, it
first skips any white-space characters in \fIstring\fR.

Then it converts the next input characters according to the 
conversion specifier and stores the result in the variable given
by the next argument to \fBscan\fR.












The following conversion characters are supported:
.TP 10
\fBd\fR
The input field must be a decimal integer.
It is read in and the value is stored in the variable as a decimal string.
.TP 10
\fBo\fR
The input field must be an octal integer. It is read in and the 
value is stored in the variable as a decimal string.
.TP 10
\fBx\fR
The input field must be a hexadecimal integer. It is read in 
and the value is stored in the variable as a decimal string.











.TP 10
\fBc\fR
A single character is read in and its binary value is stored in 
the variable as a decimal string.
Initial white space is not skipped in this case, so the input
field may be a white-space character.
This conversion is different from the ANSI standard in that the







|
|




|

|

>
|
>
|

>

|
|
>



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













>
>
>
>
>
>
>
>
>
>
>







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
how to parse it, using \fB%\fR conversion specifiers as in \fBsscanf\fR.
Each \fIvarName\fR gives the name of a variable; when a field is
scanned from \fIstring\fR the result is converted back into a string
and assigned to the corresponding variable.

.SH "DETAILS ON SCANNING"
.PP
\fBScan\fR operates by scanning \fIstring\fR and \fIformat\fR together.
If the next character in \fIformat\fR is a blank or tab then it
matches any number of white space characters in \fIstring\fR (including
zero).
Otherwise, if it isn't a \fB%\fR character then it 
must match the next character of \fIstring\fR.
When a \fB%\fR is encountered in \fIformat\fR, it indicates
the start of a conversion specifier.
A conversion specifier contains up to four fields after the \fB%\fR:
a \fB*\fR, which indicates that the converted value is to be discarded 
.VS 8.1
instead of assigned to a variable; a XPG3 position specifier; a number
.VE 8.1
indicating a maximum field width; and a conversion character.
All of these fields are optional except for the conversion character.
The fields that are present must appear in the order given above.
.PP
When \fBscan\fR finds a conversion specifier in \fIformat\fR, it
first skips any white-space characters in \fIstring\fR (unless the
specifier is \fB[\fR or \fBc\fR).
Then it converts the next input characters according to the 
conversion specifier and stores the result in the variable given
by the next argument to \fBscan\fR.
.VS 8.1
.PP
If the \fB%\fR is followed by a decimal number and a \fB$\fR, as in
``\fB%2$d\fR'', then the variable to use is not taken from the next
sequential argument.  Instead, it is taken from the argument indicated
by the number, where 1 corresponds to the first \fIvarName\fR.  If
there are any positional specifiers in \fIformat\fR then all of the
specifiers must be positional.  Every \fIvarName\fR on the argument
list must correspond to exactly one conversion specifier or an error
is generated.
.VE 8.1
.PP
The following conversion characters are supported:
.TP 10
\fBd\fR
The input field must be a decimal integer.
It is read in and the value is stored in the variable as a decimal string.
.TP 10
\fBo\fR
The input field must be an octal integer. It is read in and the 
value is stored in the variable as a decimal string.
.TP 10
\fBx\fR
The input field must be a hexadecimal integer. It is read in 
and the value is stored in the variable as a decimal string.
.VS 8.1
.TP 10
\fBu\fR
The input field must be a decimal integer.  The value is stored in the
variable as an unsigned decimal integer string.
.TP 10
\fBi\fR 
The input field must be an integer.  The base (i.e. decimal, octal, or
hexadecimal) is determined in the same fashion as described in
\fBexpr\fR.  The value is stored in the variable as a decimal string.
.VE 8.1
.TP 10
\fBc\fR
A single character is read in and its binary value is stored in 
the variable as a decimal string.
Initial white space is not skipped in this case, so the input
field may be a white-space character.
This conversion is different from the ANSI standard in that the
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
\fB[\fIchars\fB]\fR
The input field consists of any number of characters in 
\fIchars\fR.
The matching string is stored in the variable.
If the first character between the brackets is a \fB]\fR then
it is treated as part of \fIchars\fR rather than the closing
bracket for the set.







.TP 10
\fB[^\fIchars\fB]\fR
The input field consists of any number of characters not in 
\fIchars\fR.
The matching string is stored in the variable.
If the character immediately following the \fB^\fR is a \fB]\fR then it is 
treated as part of the set rather than the closing bracket for 
the set.












.LP
The number of characters read from the input for a conversion is the
largest number that makes sense for that particular conversion (e.g.
as many decimal digits as possible for \fB%d\fR, as 
many octal digits as possible for \fB%o\fR, and so on).
The input field for a given conversion terminates either when a
white-space character is encountered or when the maximum field 
width has been reached, whichever comes first.
If a \fB*\fR is present in the conversion specifier 
then no variable is assigned and the next scan argument is not consumed.

.SH "DIFFERENCES FROM ANSI SSCANF"
.PP
The behavior of the \fBscan\fR command is the same as the behavior of
the ANSI C \fBsscanf\fR procedure except for the following differences:

.IP [1]
\fB%p\fR and \fB%n\fR conversion specifiers are not currently
supported.

.IP [2]
For \fB%c\fR conversions a single character value is
converted to a decimal string, which is then assigned to the
corresponding \fIvarName\fR;
no field width may be specified for this conversion.
.IP [3]
The \fBl\fR, \fBh\fR, and \fBL\fR modifiers are ignored;  integer







>
>
>
>
>
>
>








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















>

|

>







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
\fB[\fIchars\fB]\fR
The input field consists of any number of characters in 
\fIchars\fR.
The matching string is stored in the variable.
If the first character between the brackets is a \fB]\fR then
it is treated as part of \fIchars\fR rather than the closing
bracket for the set.
.VS 8.1
If \fIchars\fR
contains a sequence of the form \fIa\fB\-\fIb\fR then any
character between \fIa\fR and \fIb\fR (inclusive) will match.
If the first or last character between the brackets is a \fB\-\fR, then
it is treated as part of \fIchars\fR rather than indicating a range.
.VE 8.1
.TP 10
\fB[^\fIchars\fB]\fR
The input field consists of any number of characters not in 
\fIchars\fR.
The matching string is stored in the variable.
If the character immediately following the \fB^\fR is a \fB]\fR then it is 
treated as part of the set rather than the closing bracket for 
the set.
.VS 8.1
If \fIchars\fR
contains a sequence of the form \fIa\fB\-\fIb\fR then any
character between \fIa\fR and \fIb\fR (inclusive) will be excluded
from the set.
If the first or last character between the brackets is a \fB\-\fR, then
it is treated as part of \fIchars\fR rather than indicating a range.
.TP 10
\fBn\fR
No input is consumed from the input string.  Instead, the total number
of chacters scanned from the input string so far is stored in the variable.
.VE 8.1
.LP
The number of characters read from the input for a conversion is the
largest number that makes sense for that particular conversion (e.g.
as many decimal digits as possible for \fB%d\fR, as 
many octal digits as possible for \fB%o\fR, and so on).
The input field for a given conversion terminates either when a
white-space character is encountered or when the maximum field 
width has been reached, whichever comes first.
If a \fB*\fR is present in the conversion specifier 
then no variable is assigned and the next scan argument is not consumed.

.SH "DIFFERENCES FROM ANSI SSCANF"
.PP
The behavior of the \fBscan\fR command is the same as the behavior of
the ANSI C \fBsscanf\fR procedure except for the following differences:
.VS 8.1
.IP [1]
\fB%p\fR conversion specifier is not currently
supported.
.VE 8.1
.IP [2]
For \fB%c\fR conversions a single character value is
converted to a decimal string, which is then assigned to the
corresponding \fIvarName\fR;
no field width may be specified for this conversion.
.IP [3]
The \fBl\fR, \fBh\fR, and \fBL\fR modifiers are ignored;  integer

Changes to doc/seek.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) seek.n 1.10 96/08/26 13:00:14
'\" 
.so man.macros
.TH seek n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
seek \- Change the access position for an open channel







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: seek.n,v 1.1.2.1 1998/09/24 23:58:36 stanton Exp $
'\" 
.so man.macros
.TH seek n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
seek \- Change the access position for an open channel

Changes to doc/set.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) set.n 1.6 97/05/18 15:56:26
'\" 
.so man.macros
.TH set n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
set \- Read and write variables







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: set.n,v 1.1.2.1 1998/09/24 23:58:36 stanton Exp $
'\" 
.so man.macros
.TH set n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
set \- Read and write variables

Changes to doc/socket.n.

1
2

3
4
5
6
7
8
9
10
11
12
13
14
15
16
'\"
'\" Copyright (c) 1996 Sun Microsystems, Inc.

'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\" SCCS: @(#) socket.n 1.14 97/10/31 12:51:12
.so man.macros
.TH socket n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
socket \- Open a TCP network connection
.SH SYNOPSIS
.sp
\fBsocket \fR?\fIoptions\fR? \fIhost port\fR


>




|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'\"
'\" Copyright (c) 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: socket.n,v 1.1.2.2 1999/02/10 23:31:12 stanton Exp $
.so man.macros
.TH socket n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
socket \- Open a TCP network connection
.SH SYNOPSIS
.sp
\fBsocket \fR?\fIoptions\fR? \fIhost port\fR
99
100
101
102
103
104
105








106
107
108
109
110
111
112
event loop, for example by invoking the \fBvwait\fR command or
calling the C procedure \fBTcl_DoOneEvent\fR, then no connections
will be accepted.

.SH CONFIGURATION OPTIONS
The \fBfconfigure\fR command can be used to query several readonly
configuration options for socket channels:








.TP
\fB\-sockname\fR
This option returns a list of three elements, the address, the host name
and the port number for the socket. If the host name cannot be computed,
the second element is identical to the address, the first element of the
list.
.TP







>
>
>
>
>
>
>
>







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
event loop, for example by invoking the \fBvwait\fR command or
calling the C procedure \fBTcl_DoOneEvent\fR, then no connections
will be accepted.

.SH CONFIGURATION OPTIONS
The \fBfconfigure\fR command can be used to query several readonly
configuration options for socket channels:
.VS 8.0.5
.TP
\fB\-error\fR
This option gets the current error status of the given socket.  This
is useful when you need to determine if an asynchronous connect
operation succeeded.  If there was an error, the error message is
returned.  If there was no error, an empty string is returned.
.VE 8.0.5
.TP
\fB\-sockname\fR
This option returns a list of three elements, the address, the host name
and the port number for the socket. If the host name cannot be computed,
the second element is identical to the address, the first element of the
list.
.TP

Changes to doc/source.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) source.n 1.8 97/10/31 12:51:10
'\" 
.so man.macros
.TH source n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
source \- Evaluate a file or resource as a Tcl script







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: source.n,v 1.1.2.1 1998/09/24 23:58:36 stanton Exp $
'\" 
.so man.macros
.TH source n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
source \- Evaluate a file or resource as a Tcl script

Changes to doc/split.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) split.n 1.6 96/03/25 20:23:53
'\" 
.so man.macros
.TH split n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
split \- Split a string into a proper Tcl list







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: split.n,v 1.1.2.1 1998/09/24 23:58:36 stanton Exp $
'\" 
.so man.macros
.TH split n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
split \- Split a string into a proper Tcl list

Changes to doc/string.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) string.n 1.9 96/08/26 13:00:14
'\" 
.so man.macros
.TH string n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
string \- Manipulate strings







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: string.n,v 1.1.2.2 1998/10/16 01:24:57 stanton Exp $
'\" 
.so man.macros
.TH string n 7.6 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
string \- Manipulate strings
81
82
83
84
85
86
87

88
89
90
91
92






93
94
95

96
97
98
99
100
101
102
first character of the string.  
An index of \fBend\fR (or any
abbreviation of it) refers to the last character of the string.
If \fIfirst\fR is less than zero then it is treated as if it were zero, and
if \fIlast\fR is greater than or equal to the length of the string then
it is treated as if it were \fBend\fR.  If \fIfirst\fR is greater than
\fIlast\fR then an empty string is returned.

.TP
\fBstring tolower \fIstring\fR
Returns a value equal to \fIstring\fR except that all upper case
letters have been converted to lower case.
.TP






\fBstring toupper \fIstring\fR
Returns a value equal to \fIstring\fR except that all lower case
letters have been converted to upper case.

.TP
\fBstring trim \fIstring\fR ?\fIchars\fR?
Returns a value equal to \fIstring\fR except that any leading
or trailing characters from the set given by \fIchars\fR are
removed.
If \fIchars\fR is not specified then white space is removed
(spaces, tabs, newlines, and carriage returns).







>


|
|

>
>
>
>
>
>
|
|
|
>







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
first character of the string.  
An index of \fBend\fR (or any
abbreviation of it) refers to the last character of the string.
If \fIfirst\fR is less than zero then it is treated as if it were zero, and
if \fIlast\fR is greater than or equal to the length of the string then
it is treated as if it were \fBend\fR.  If \fIfirst\fR is greater than
\fIlast\fR then an empty string is returned.
.VS
.TP
\fBstring tolower \fIstring\fR
Returns a value equal to \fIstring\fR except that all upper (or title)
case letters have been converted to lower case.
.TP
\fBstring totitle \fIstring\fR
Returns a value equal to \fIstring\fR except that the first character
in \fIstring\fR is converted to its Unicode title case variant (or upper
case if there is no title case variant) and the rest of the string is
converted to lower case.
.TP
\fBstring toupper \fIstring\fR 
Returns a value equal to \fIstring\fR except that all lower (or title)
case letters have been converted to upper case.
.VE
.TP
\fBstring trim \fIstring\fR ?\fIchars\fR?
Returns a value equal to \fIstring\fR except that any leading
or trailing characters from the set given by \fIchars\fR are
removed.
If \fIchars\fR is not specified then white space is removed
(spaces, tabs, newlines, and carriage returns).
110
111
112
113
114
115
116

117
118
119
120
121

122
123
124
125
126
127

128

129
130
131
.TP
\fBstring trimright \fIstring\fR ?\fIchars\fR?
Returns a value equal to \fIstring\fR except that any
trailing characters from the set given by \fIchars\fR are
removed.
If \fIchars\fR is not specified then white space is removed
(spaces, tabs, newlines, and carriage returns).

.TP
\fBstring wordend \fIstring index\fR
Returns the index of the character just after the last one in the
word containing character \fIindex\fR of \fIstring\fR.
A word is considered to be any contiguous range of alphanumeric

or underscore characters, or any single character other than these.
.TP
\fBstring wordstart \fIstring index\fR
Returns the index of the first character in the
word containing character \fIindex\fR of \fIstring\fR.
A word is considered to be any contiguous range of alphanumeric

or underscore characters, or any single character other than these.


.SH KEYWORDS
case conversion, compare, index, match, pattern, string, word







>


|
|
|
>
|


|
|
|
>
|
>



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
.TP
\fBstring trimright \fIstring\fR ?\fIchars\fR?
Returns a value equal to \fIstring\fR except that any
trailing characters from the set given by \fIchars\fR are
removed.
If \fIchars\fR is not specified then white space is removed
(spaces, tabs, newlines, and carriage returns).
.VS
.TP
\fBstring wordend \fIstring index\fR
Returns the index of the character just after the last one in the word
containing character \fIindex\fR of \fIstring\fR.  A word is
considered to be any contiguous range of alphanumeric (Unicode letters
or decimal digits) or underscore (Unicode connector punctuation)
characters, or any single character other than these.
.TP
\fBstring wordstart \fIstring index\fR
Returns the index of the first character in the word containing
character \fIindex\fR of \fIstring\fR.  A word is considered to be any
contiguous range of alphanumeric (Unicode letters or decimal digits)
or underscore (Unicode connector punctuation) characters, or any
single character other than these.
.VE

.SH KEYWORDS
case conversion, compare, index, match, pattern, string, word

Changes to doc/subst.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) subst.n 1.9 96/03/25 20:24:17
'\" 
.so man.macros
.TH subst n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
subst \- Perform backslash, command, and variable substitutions







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: subst.n,v 1.1.2.1 1998/09/24 23:58:37 stanton Exp $
'\" 
.so man.macros
.TH subst n 7.4 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
subst \- Perform backslash, command, and variable substitutions

Changes to doc/switch.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) switch.n 1.10 97/10/31 13:05:55
'\" 
.so man.macros
.TH switch n 7.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
switch \- Evaluate one of several scripts, depending on a given value







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: switch.n,v 1.1.2.1 1998/09/24 23:58:37 stanton Exp $
'\" 
.so man.macros
.TH switch n 7.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
switch \- Evaluate one of several scripts, depending on a given value

Changes to doc/tclsh.1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) tclsh.1 1.13 96/08/26 13:00:15
'\" 
.so man.macros
.TH tclsh 1 "" Tcl "Tcl Applications"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tclsh \- Simple shell containing Tcl interpreter







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: tclsh.1,v 1.1.2.1 1998/09/24 23:58:37 stanton Exp $
'\" 
.so man.macros
.TH tclsh 1 "" Tcl "Tcl Applications"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tclsh \- Simple shell containing Tcl interpreter

Changes to doc/tclvars.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) tclvars.n 1.34 97/08/22 18:51:04
'\" 
.so man.macros
.TH tclvars n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tclvars \- Variables used by Tcl







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: tclvars.n,v 1.1.2.3 1999/03/25 22:03:45 redman Exp $
'\" 
.so man.macros
.TH tclvars n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tclvars \- Variables used by Tcl
255
256
257
258
259
260
261
262
263



264
265
266
267


268
269
270
271






272
273
274
275
276
277
278
\fBmachine\fR
The instruction set executed by this machine, such as
\fBintel\fR, \fBPPC\fR, \fB68k\fR, or \fBsun4m\fR.  On UNIX machines, this
is the value returned by \fBuname -m\fR.
.TP
\fBos\fR 
The name of the operating system running on this machine,
such as \fBWin32s\fR, \fBWindows NT\fR, \fBMacOS\fR, or \fBSunOS\fR.
On UNIX machines, this is the value returned by \fBuname -s\fR.



.TP
\fBosVersion\fR
The version number for the operating system running on this machine.
On UNIX machines, this is the value returned by \fBuname -r\fR.


.TP
\fBplatform\fR
Either \fBwindows\fR, \fBmacintosh\fR, or \fBunix\fR.  This identifies the
general operating environment of the machine.






.RE
.TP
\fBtcl_precision\fR
.VS
This variable controls the number of digits to generate
when converting floating-point values to strings.  It defaults
to 12.







|

>
>
>



|
>
>




>
>
>
>
>
>







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
\fBmachine\fR
The instruction set executed by this machine, such as
\fBintel\fR, \fBPPC\fR, \fB68k\fR, or \fBsun4m\fR.  On UNIX machines, this
is the value returned by \fBuname -m\fR.
.TP
\fBos\fR 
The name of the operating system running on this machine,
such as \fBWindows 95\fR, \fBWindows NT\fR, \fBMacOS\fR, or \fBSunOS\fR.
On UNIX machines, this is the value returned by \fBuname -s\fR.
On Windows 95 and Windows 98, the value returned will be \fBWindows
95\fR to provide better backwards compatibility to Windows 95; to
distinguish between the two, check the \fBosVersion\fR.
.TP
\fBosVersion\fR
The version number for the operating system running on this machine.
On UNIX machines, this is the value returned by \fBuname -r\fR.  On
Windows 95, the version will be 4.0; on Windows 98, the version will
be 4.10.
.TP
\fBplatform\fR
Either \fBwindows\fR, \fBmacintosh\fR, or \fBunix\fR.  This identifies the
general operating environment of the machine.
.TP
\fBuser\fR
Either \fBwindows\fR, \fBmacintosh\fR, or \fBunix\fR.  This identifies the
current user based on the login information available on the platform.
This comes from the USER or LOGNAME environment variable on Unix,
and the value from GetUserName on Windows and Macintosh.
.RE
.TP
\fBtcl_precision\fR
.VS
This variable controls the number of digits to generate
when converting floating-point values to strings.  It defaults
to 12.

Changes to doc/tell.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) tell.n 1.9 96/08/26 13:00:17
'\" 
.so man.macros
.TH tell n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tell \- Return current access position for an open channel







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: tell.n,v 1.1.2.1 1998/09/24 23:58:37 stanton Exp $
'\" 
.so man.macros
.TH tell n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tell \- Return current access position for an open channel

Changes to doc/time.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) time.n 1.6 96/03/25 20:25:30
'\" 
.so man.macros
.TH time n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
time \- Time the execution of a script







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: time.n,v 1.1.2.1 1998/09/24 23:58:37 stanton Exp $
'\" 
.so man.macros
.TH time n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
time \- Time the execution of a script

Changes to doc/trace.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) trace.n 1.12 96/08/26 13:00:18
'\" 
.so man.macros
.TH trace n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
trace \- Monitor variable accesses







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: trace.n,v 1.1.2.1 1998/09/24 23:58:37 stanton Exp $
'\" 
.so man.macros
.TH trace n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
trace \- Monitor variable accesses

Changes to doc/unknown.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) unknown.n 1.8 96/10/09 08:29:28
'\" 
.so man.macros
.TH unknown n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
unknown \- Handle attempts to use non-existent commands







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: unknown.n,v 1.1.2.1 1998/09/24 23:58:38 stanton Exp $
'\" 
.so man.macros
.TH unknown n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
unknown \- Handle attempts to use non-existent commands

Changes to doc/unset.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) unset.n 1.5 96/03/25 20:26:21
'\" 
.so man.macros
.TH unset n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
unset \- Delete variables







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: unset.n,v 1.1.2.1 1998/09/24 23:58:38 stanton Exp $
'\" 
.so man.macros
.TH unset n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
unset \- Delete variables

Changes to doc/update.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) update.n 1.3 96/03/25 20:26:34
'\" 
.so man.macros
.TH update n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
update \- Process pending events and idle callbacks







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-1996 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: update.n,v 1.1.2.1 1998/09/24 23:58:38 stanton Exp $
'\" 
.so man.macros
.TH update n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
update \- Process pending events and idle callbacks

Changes to doc/uplevel.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) uplevel.n 1.8 97/08/13 13:41:36
'\" 
.so man.macros
.TH uplevel n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
uplevel \- Execute a script in a different stack frame







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: uplevel.n,v 1.1.2.1 1998/09/24 23:58:38 stanton Exp $
'\" 
.so man.macros
.TH uplevel n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
uplevel \- Execute a script in a different stack frame

Changes to doc/upvar.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) upvar.n 1.16 97/08/13 13:43:34
'\" 
.so man.macros
.TH upvar n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
upvar \- Create link to variable in a different stack frame







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: upvar.n,v 1.1.2.1 1998/09/24 23:58:38 stanton Exp $
'\" 
.so man.macros
.TH upvar n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
upvar \- Create link to variable in a different stack frame

Changes to doc/variable.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
'\" 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.
'\" 
'\" SCCS: @(#) variable.n 1.4 97/08/13 16:57:57
'\" 
.so man.macros
.TH variable n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
variable \- create and initialize a namespace variable







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
'\" 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: variable.n,v 1.1.2.1 1998/09/24 23:58:38 stanton Exp $
'\" 
.so man.macros
.TH variable n 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
variable \- create and initialize a namespace variable

Changes to doc/vwait.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" SCCS: @(#) vwait.n 1.4 97/09/29 11:31:18
'\" 
.so man.macros
.TH vwait n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
vwait \- Process events until a variable is written






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1995-1996 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: vwait.n,v 1.1.2.1 1998/09/24 23:58:38 stanton Exp $
'\" 
.so man.macros
.TH vwait n 7.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
vwait \- Process events until a variable is written

Changes to doc/while.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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.
'\" 
'\" SCCS: @(#) while.n 1.7 97/04/08 17:13:50
'\" 
.so man.macros
.TH while n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
while \- Execute script repeatedly as long as a condition is met







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" 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: while.n,v 1.1.2.1 1998/09/24 23:58:39 stanton Exp $
'\" 
.so man.macros
.TH while n "" Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
while \- Execute script repeatedly as long as a condition is met

Changes to generic/README.

1
2
3
4
5
This directory contains Tcl source files that work on all the platforms
where Tcl runs (e.g. UNIX, PCs, and Macintoshes).  Platform-specific
sources are in the directories ../unix, ../win, and ../mac.

SCCS ID: @(#) README 1.1 95/09/11 14:02:13




|
1
2
3
4
5
This directory contains Tcl source files that work on all the platforms
where Tcl runs (e.g. UNIX, PCs, and Macintoshes).  Platform-specific
sources are in the directories ../unix, ../win, and ../mac.

RCS: @(#) $Id: README,v 1.1.2.1 1998/09/24 23:58:39 stanton Exp $

Changes to generic/panic.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
/* 
 * panic.c --
 *
 *	Source code for the "panic" library procedure for Tcl;
 *	individual applications will probably override this with
 *	an application-specific panic procedure.
 *
 * Copyright (c) 1988-1993 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) panic.c 1.15 96/09/12 14:55:25
 */

#include <stdio.h>
#ifdef NO_STDLIB_H
#   include "../compat/stdlib.h"
#else
#   include <stdlib.h>
#endif

#define panic panicDummy
#include "tcl.h"
#undef panic




EXTERN void		panic _ANSI_ARGS_((char *format, char *arg1,
			    char *arg2, char *arg3, char *arg4, char *arg5,
			    char *arg6, char *arg7, char *arg8));

/*
 * The panicProc variable contains a pointer to an application
 * specific panic procedure.













|













>
>
>







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
/* 
 * panic.c --
 *
 *	Source code for the "panic" library procedure for Tcl;
 *	individual applications will probably override this with
 *	an application-specific panic procedure.
 *
 * Copyright (c) 1988-1993 The Regents of the University of California.
 * Copyright (c) 1994 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: panic.c,v 1.1.2.1 1998/09/24 23:58:39 stanton Exp $
 */

#include <stdio.h>
#ifdef NO_STDLIB_H
#   include "../compat/stdlib.h"
#else
#   include <stdlib.h>
#endif

#define panic panicDummy
#include "tcl.h"
#undef panic

# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT

EXTERN void		panic _ANSI_ARGS_((char *format, char *arg1,
			    char *arg2, char *arg3, char *arg4, char *arg5,
			    char *arg6, char *arg7, char *arg8));

/*
 * The panicProc variable contains a pointer to an application
 * specific panic procedure.

Added generic/regc_color.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
/*
 * colorings of characters
 * This file is #included by regcomp.c.
 *
 * Note that there are some incestuous relationships between this code and
 * NFA arc maintenance, which perhaps ought to be cleaned up sometime.
 */



#define	CISERR()	VISERR(cm->v)
#define	CERR(e)		VERR(cm->v, (e))



/*
 - initcm - set up new colormap
 ^ static VOID initcm(struct vars *, struct colormap *);
 */
static VOID
initcm(v, cm)
struct vars *v;
struct colormap *cm;
{
	int i;
	int j;
	union tree *t;
	union tree *nextt;
	struct colordesc *cd;

	cm->magic = CMMAGIC;
	cm->v = v;

	cm->ncds = NINLINECDS;
	cm->cd = cm->cdspace;
	cm->max = 0;
	cm->free = 0;

	cd = cm->cd;			/* cm->cd[WHITE] */
	cd->sub = NOSUB;
	cd->arcs = NULL;
	cd->flags = 0;
	cd->nchrs = CHR_MAX - CHR_MIN + 1;

	/* upper levels of tree */
	for (t = &cm->tree[0], j = NBYTS-1; j > 0; t = nextt, j--) {
		nextt = t + 1;
		for (i = BYTTAB-1; i >= 0; i--)
			t->tptr[i] = nextt;
	}
	/* bottom level is solid white */
	t = &cm->tree[NBYTS-1];
	for (i = BYTTAB-1; i >= 0; i--)
		t->tcolor[i] = WHITE;
	cd->block = t;
}

/*
 - freecm - free dynamically-allocated things in a colormap
 ^ static VOID freecm(struct colormap *);
 */
static VOID
freecm(cm)
struct colormap *cm;
{
	size_t i;
	union tree *cb;

	cm->magic = 0;
	if (NBYTS > 1)
		cmtreefree(cm, cm->tree, 0);
	for (i = 1; i < cm->max; i++)		/* skip WHITE */
		if (!UNUSEDCOLOR(&cm->cd[i])) {
			cb = cm->cd[i].block;
			if (cb != NULL)
				FREE(cb);
		}
	if (cm->cd != cm->cdspace)
		FREE(cm->cd);
}

/*
 - cmtreefree - free a non-terminal part of a colormap tree
 ^ static VOID cmtreefree(struct colormap *, union tree *, int);
 */
static VOID
cmtreefree(cm, tree, level)
struct colormap *cm;
union tree *tree;
int level;			/* level number (top == 0) of this block */
{
	int i;
	union tree *t;
	union tree *fillt = &cm->tree[level+1];
	union tree *cb;

	assert(level < NBYTS-1);	/* this level has pointers */
	for (i = BYTTAB-1; i >= 0; i--) {
		t = tree->tptr[i];
		assert(t != NULL);
		if (t != fillt) {
			if (level < NBYTS-2) {	/* more pointer blocks below */
				cmtreefree(cm, t, level+1);
				FREE(t);
			} else {		/* color block below */
				cb = cm->cd[t->tcolor[0]].block;
				if (t != cb)	/* not a solid block */
					FREE(t);
			}
		}
	}
}

/*
 - setcolor - set the color of a character in a colormap
 ^ static color setcolor(struct colormap *, pchr, pcolor);
 */
static color			/* previous color */
setcolor(cm, c, co)
struct colormap *cm;
pchr c;
pcolor co;
{
	uchr uc = c;
	int shift;
	int level;
	int b;
	int bottom;
	union tree *t;
	union tree *newt;
	union tree *fillt;
	union tree *lastt;
	union tree *cb;
	color prev;

	assert(cm->magic == CMMAGIC);
	if (CISERR() || co == COLORLESS)
		return COLORLESS;

	t = cm->tree;
	for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
						level++, shift -= BYTBITS) {
		b = (uc >> shift) & BYTMASK;
		lastt = t;
		t = lastt->tptr[b];
		assert(t != NULL);
		fillt = &cm->tree[level+1];
		bottom = (shift <= BYTBITS) ? 1 : 0;
		cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
		if (t == fillt || t == cb) {	/* must allocate a new block */
			newt = (union tree *)MALLOC((bottom) ?
				sizeof(struct colors) : sizeof(struct ptrs));
			if (newt == NULL) {
				CERR(REG_ESPACE);
				return COLORLESS;
			}
			if (bottom)
				memcpy(VS(newt->tcolor), VS(t->tcolor),
							BYTTAB*sizeof(color));
			else
				memcpy(VS(newt->tptr), VS(t->tptr),
						BYTTAB*sizeof(union tree *));
			t = newt;
			lastt->tptr[b] = t;
		}
	}

	b = uc & BYTMASK;
	prev = t->tcolor[b];
	t->tcolor[b] = (color)co;
	return prev;
}

/*
 - maxcolor - report largest color number in use
 ^ static color maxcolor(struct colormap *);
 */
static color
maxcolor(cm)
struct colormap *cm;
{
	if (CISERR())
		return COLORLESS;

	return (color)cm->max;
}

/*
 - newcolor - find a new color (must be subject of setcolor at once)
 * Beware:  may relocate the colordescs.
 ^ static color newcolor(struct colormap *);
 */
static color			/* COLORLESS for error */
newcolor(cm)
struct colormap *cm;
{
	struct colordesc *cd;
	struct colordesc *new;
	size_t n;

	if (CISERR())
		return COLORLESS;

	if (cm->free != 0) {
		assert(cm->free > 0);
		assert((size_t)cm->free < cm->ncds);
		cd = &cm->cd[cm->free];
		assert(UNUSEDCOLOR(cd));
		assert(cd->arcs == NULL);
		cm->free = cd->sub;
	} else if (cm->max < cm->ncds - 1) {
		cm->max++;
		cd = &cm->cd[cm->max];
	} else {
		/* oops, must allocate more */
		n = cm->ncds * 2;
		if (cm->cd == cm->cdspace) {
			new = (struct colordesc *)MALLOC(n *
						sizeof(struct colordesc));
			if (new != NULL)
				memcpy(VS(new), VS(cm->cdspace), cm->ncds *
						sizeof(struct colordesc));
		} else
			new = (struct colordesc *)REALLOC(cm->cd,
						n * sizeof(struct colordesc));
		if (new == NULL) {
			CERR(REG_ESPACE);
			return COLORLESS;
		}
		cm->cd = new;
		cm->ncds = n;
		assert(cm->max < cm->ncds - 1);
		cm->max++;
		cd = &cm->cd[cm->max];
	}

	cd->nchrs = 0;
	cd->sub = NOSUB;
	cd->arcs = NULL;
	cd->flags = 0;
	cd->block = NULL;

	return (color)(cd - cm->cd);
}

/*
 - freecolor - free a color (must have no arcs or subcolor)
 ^ static VOID freecolor(struct colormap *, pcolor);
 */
static VOID
freecolor(cm, co)
struct colormap *cm;
pcolor co;
{
	struct colordesc *cd = &cm->cd[co];
	color pco, nco;			/* for freelist scan */

	assert(co >= 0);
	if (co == WHITE)
		return;

	assert(cd->arcs == NULL);
	assert(cd->sub == NOSUB);
	assert(cd->nchrs == 0);
	cd->flags = FREECOL;
	if (cd->block != NULL) {
		FREE(cd->block);
		cd->block = NULL;	/* just paranoia */
	}

	if ((size_t)co == cm->max) {
		while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max]))
			cm->max--;
		assert(cm->max >= 0);
		while ((size_t)cm->free > cm->max)
			cm->free = cm->cd[cm->free].sub;
		if (cm->free > 0) {
			assert(cm->free < cm->max);
			pco = cm->free;
			nco = cm->cd[pco].sub;
			while (nco > 0)
				if ((size_t)nco > cm->max) {
					/* take this one out of freelist */
					nco = cm->cd[nco].sub;
					cm->cd[pco].sub = nco;
				} else {
					assert(nco < cm->max);
					pco = nco;
					nco = cm->cd[pco].sub;
				}
		}
	} else {
		cd->sub = cm->free;
		cm->free = (color)(cd - cm->cd);
	}
}

/*
 - pseudocolor - allocate a false color, to be managed by other means
 ^ static color pseudocolor(struct colormap *);
 */
static color
pseudocolor(cm)
struct colormap *cm;
{
	color co;

	co = newcolor(cm);
	if (CISERR())
		return COLORLESS;
	cm->cd[co].nchrs = 1;
	cm->cd[co].flags = PSEUDO;
	return co;
}

/*
 - subcolor - allocate a new subcolor (if necessary) to this chr
 ^ static color subcolor(struct colormap *, pchr c);
 */
static color
subcolor(cm, c)
struct colormap *cm;
pchr c;
{
	color co;			/* current color of c */
	color sco;			/* new subcolor */

	co = GETCOLOR(cm, c);
	sco = newsub(cm, co);
	if (sco == COLORLESS) {
		return COLORLESS;
	}
	if (co == sco)		/* already in an open subcolor */
		return co;	/* rest is redundant */
	cm->cd[co].nchrs--;
	cm->cd[sco].nchrs++;
	setcolor(cm, c, sco);
	return sco;
}

/*
 - newsub - allocate a new subcolor (if necessary) for a color
 ^ static color newsub(struct colormap *, pcolor);
 */
static color
newsub(cm, co)
struct colormap *cm;
pcolor co;
{
	color sco;			/* new subcolor */

	sco = cm->cd[co].sub;
	if (sco == NOSUB) {		/* color has no open subcolor */
		if (cm->cd[co].nchrs == 1)	/* optimization */
			return co;
		sco = newcolor(cm);	/* must create subcolor */
		if (sco == COLORLESS)
			return COLORLESS;
		cm->cd[co].sub = sco;
		cm->cd[sco].sub = sco;	/* open subcolor points to self */
	}
	assert(sco != NOSUB);

	return sco;
}

/*
 - subrange - allocate new subcolors to this range of chrs, fill in arcs
 ^ static VOID subrange(struct vars *, pchr, pchr, struct state *,
 ^ 	struct state *);
 */
static VOID
subrange(v, from, to, lp, rp)
struct vars *v;
pchr from;
pchr to;
struct state *lp;
struct state *rp;
{
	uchr uf;
	int i;

	assert(from <= to);

	/* first, align "from" on a tree-block boundary */
	uf = (uchr)from;
	i = (int)( ((uf + BYTTAB-1) & (uchr)~BYTMASK) - uf );
	for (; from <= to && i > 0; i--, from++)
		newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
	if (from > to)			/* didn't reach a boundary */
		return;

	/* deal with whole blocks */
	for (; to - from >= BYTTAB; from += BYTTAB)
		subblock(v, from, lp, rp);

	/* clean up any remaining partial table */
	for (; from <= to; from++)
		newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
}

/*
 - subblock - allocate new subcolors for one tree block of chrs, fill in arcs
 ^ static VOID subblock(struct vars *, pchr, struct state *, struct state *);
 */
static VOID
subblock(v, start, lp, rp)
struct vars *v;
pchr start;			/* first of BYTTAB chrs */
struct state *lp;
struct state *rp;
{
	uchr uc = start;
	struct colormap *cm = v->cm;
	int shift;
	int level;
	int i;
	int b;
	union tree *t;
	union tree *cb;
	union tree *fillt;
	union tree *lastt;
	int previ;
	int ndone;
	color co;
	color sco;

	assert((uc & BYTMASK) == 0);

	/* find its color block, making new pointer blocks as needed */
	t = cm->tree;
	fillt = NULL;
	for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
						level++, shift -= BYTBITS) {
		b = (uc >> shift) & BYTMASK;
		lastt = t;
		t = lastt->tptr[b];
		assert(t != NULL);
		fillt = &cm->tree[level+1];
		if (t == fillt && shift > BYTBITS) {	/* need new ptr block */
			t = (union tree *)MALLOC(sizeof(struct ptrs));
			if (t == NULL) {
				CERR(REG_ESPACE);
				return;
			}
			memcpy(VS(t->tptr), VS(fillt->tptr),
						BYTTAB*sizeof(union tree *));
			lastt->tptr[b] = t;
		}
	}

	/* special cases:  fill block or solid block */
	co = t->tcolor[0];
	cb = cm->cd[co].block;
	if (t == fillt || t == cb) {
		/* either way, we want a subcolor solid block */
		sco = newsub(cm, co);
		t = cm->cd[sco].block;
		if (t == NULL) {	/* must set it up */
			t = (union tree *)MALLOC(sizeof(struct colors));
			if (t == NULL) {
				CERR(REG_ESPACE);
				return;
			}
			for (i = 0; i < BYTTAB; i++)
				t->tcolor[i] = sco;
			cm->cd[sco].block = t;
		}
		/* find loop must have run at least once */
		lastt->tptr[b] = t;
		newarc(v->nfa, PLAIN, sco, lp, rp);
		cm->cd[co].nchrs -= BYTTAB;
		cm->cd[sco].nchrs += BYTTAB;
		return;
	}

	/* general case, a mixed block to be altered */
	i = 0;
	while (i < BYTTAB) {
		co = t->tcolor[i];
		sco = newsub(cm, co);
		newarc(v->nfa, PLAIN, sco, lp, rp);
		previ = i;
		do {
			t->tcolor[i++] = sco;
		} while (i < BYTTAB && t->tcolor[i] == co);
		ndone = i - previ;
		cm->cd[co].nchrs -= ndone;
		cm->cd[sco].nchrs += ndone;
	}
}

/*
 - okcolors - promote subcolors to full colors
 ^ static VOID okcolors(struct nfa *, struct colormap *);
 */
static VOID
okcolors(nfa, cm)
struct nfa *nfa;
struct colormap *cm;
{
	struct colordesc *cd;
	struct colordesc *end = CDEND(cm);
	struct colordesc *scd;
	struct arc *a;
	color co;
	color sco;

	for (cd = cm->cd, co = 0; cd < end; cd++, co++) {
		sco = cd->sub;
		if (UNUSEDCOLOR(cd) || sco == NOSUB) {
			/* has no subcolor, no further action */
		} else if (sco == co) {
			/* is subcolor, let parent deal with it */
		} else if (cd->nchrs == 0) {
			/* parent empty, its arcs change color to subcolor */
			cd->sub = NOSUB;
			scd = &cm->cd[sco];
			assert(scd->nchrs > 0);
			assert(scd->sub == sco);
			scd->sub = NOSUB;
			while ((a = cd->arcs) != NULL) {
				assert(a->co == co);
				/* uncolorchain(cm, a); */
				cd->arcs = a->colorchain;
				a->co = sco;
				/* colorchain(cm, a); */
				a->colorchain = scd->arcs;
				scd->arcs = a;
			}
			freecolor(cm, co);
		} else {
			/* parent's arcs must gain parallel subcolor arcs */
			cd->sub = NOSUB;
			scd = &cm->cd[sco];
			assert(scd->nchrs > 0);
			assert(scd->sub == sco);
			scd->sub = NOSUB;
			for (a = cd->arcs; a != NULL; a = a->colorchain) {
				assert(a->co == co);
				newarc(nfa, a->type, sco, a->from, a->to);
			}
		}
	}
}

/*
 - colorchain - add this arc to the color chain of its color
 ^ static VOID colorchain(struct colormap *, struct arc *);
 */
static VOID
colorchain(cm, a)
struct colormap *cm;
struct arc *a;
{
	struct colordesc *cd = &cm->cd[a->co];

	a->colorchain = cd->arcs;
	cd->arcs = a;
}

/*
 - uncolorchain - delete this arc from the color chain of its color
 ^ static VOID uncolorchain(struct colormap *, struct arc *);
 */
static VOID
uncolorchain(cm, a)
struct colormap *cm;
struct arc *a;
{
	struct colordesc *cd = &cm->cd[a->co];
	struct arc *aa;

	aa = cd->arcs;
	if (aa == a)		/* easy case */
		cd->arcs = a->colorchain;
	else {
		for (; aa != NULL && aa->colorchain != a; aa = aa->colorchain)
			continue;
		assert(aa != NULL);
		aa->colorchain = a->colorchain;
	}
	a->colorchain = NULL;	/* paranoia */
}

/*
 - singleton - is this character in its own color?
 ^ static int singleton(struct colormap *, pchr c);
 */
#if 0
static int			/* predicate */
singleton(cm, c)
struct colormap *cm;
pchr c;
{
	color co;			/* color of c */

	co = GETCOLOR(cm, c);
	if (cm->cd[co].nchrs == 1 && cm->cd[co].sub == NOSUB)
		return 1;
	return 0;
}
#endif
/*
 - rainbow - add arcs of all full colors (but one) between specified states
 ^ static VOID rainbow(struct nfa *, struct colormap *, int, pcolor,
 ^ 	struct state *, struct state *);
 */
static VOID
rainbow(nfa, cm, type, but, from, to)
struct nfa *nfa;
struct colormap *cm;
int type;
pcolor but;			/* COLORLESS if no exceptions */
struct state *from;
struct state *to;
{
	struct colordesc *cd;
	struct colordesc *end = CDEND(cm);
	color co;

	for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
		if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but &&
							!(cd->flags&PSEUDO))
			newarc(nfa, type, co, from, to);
}

/*
 - colorcomplement - add arcs of complementary colors
 * The calling sequence ought to be reconciled with cloneouts().
 ^ static VOID colorcomplement(struct nfa *, struct colormap *, int,
 ^ 	struct state *, struct state *, struct state *);
 */
static VOID
colorcomplement(nfa, cm, type, of, from, to)
struct nfa *nfa;
struct colormap *cm;
int type;
struct state *of;		/* complements of this guy's PLAIN outarcs */
struct state *from;
struct state *to;
{
	struct colordesc *cd;
	struct colordesc *end = CDEND(cm);
	color co;

	assert(of != from);
	for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
		if (!UNUSEDCOLOR(cd) && !(cd->flags&PSEUDO))
			if (findarc(of, PLAIN, co) == NULL)
				newarc(nfa, type, co, from, to);
}



#ifdef REG_DEBUG

/*
 - dumpcolors - debugging output
 ^ static VOID dumpcolors(struct colormap *, FILE *);
 */
static VOID
dumpcolors(cm, f)
struct colormap *cm;
FILE *f;
{
	struct colordesc *cd;
	struct colordesc *end;
	color co;
	chr c;
	char *has;

	fprintf(f, "max %ld\n", (long)cm->max);
	if (NBYTS > 1)
		fillcheck(cm, cm->tree, 0, f);
	end = CDEND(cm);
	for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++)	/* skip 0 */
		if (!UNUSEDCOLOR(cd)) {
			assert(cd->nchrs > 0);
			has = (cd->block != NULL) ? "#" : "";
			if (cd->flags&PSEUDO)
				fprintf(f, "#%2ld%s(ps): ", (long)co, has);
			else
				fprintf(f, "#%2ld%s(%2d): ", (long)co,
							has, cd->nchrs);
			/* it's hard to do this more efficiently */
			for (c = CHR_MIN; c < CHR_MAX; c++)
				if (GETCOLOR(cm, c) == co)
					dumpchr(c, f);
			assert(c == CHR_MAX);
			if (GETCOLOR(cm, c) == co)
				dumpchr(c, f);
			fprintf(f, "\n");
		}
}

/*
 - fillcheck - check proper filling of a tree
 ^ static VOID fillcheck(struct colormap *, union tree *, int, FILE *);
 */
static VOID
fillcheck(cm, tree, level, f)
struct colormap *cm;
union tree *tree;
int level;			/* level number (top == 0) of this block */
FILE *f;
{
	int i;
	union tree *t;
	union tree *fillt = &cm->tree[level+1];

	assert(level < NBYTS-1);	/* this level has pointers */
	for (i = BYTTAB-1; i >= 0; i--) {
		t = tree->tptr[i];
		if (t == NULL)
			fprintf(f, "NULL found in filled tree!\n");
		else if (t == fillt)
			{}
		else if (level < NBYTS-2)	/* more pointer blocks below */
			fillcheck(cm, t, level+1, f);
	}
}

/*
 - dumpchr - print a chr
 * Kind of char-centric but works well enough for debug use.
 ^ static VOID dumpchr(pchr, FILE *);
 */
static VOID
dumpchr(c, f)
pchr c;
FILE *f;
{
	if (c == '\\')
		fprintf(f, "\\\\");
	else if (c > ' ' && c <= '~')
		putc((char)c, f);
	else
		fprintf(f, "\\u%04lx", (long)c);
}

#endif				/* ifdef REG_DEBUG */

Added generic/regc_cvec.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
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
/*
 * Utility functions for handling cvecs
 * This file is #included by regcomp.c.
 */

/*
 - newcvec - allocate a new cvec
 ^ static struct cvec *newcvec(int, int, int);
 */
static struct cvec *
newcvec(nchrs, nranges, nmcces)
int nchrs;			/* to hold this many chrs... */
int nranges;			/* ... and this many ranges... */
int nmcces;			/* ... and this many MCCEs */
{
	size_t n;
	size_t nc;
	struct cvec *cv;

	nc = (size_t)nchrs + (size_t)nmcces*(MAXMCCE+1) + (size_t)nranges*2;
	n = sizeof(struct cvec) + (size_t)(nmcces-1)*sizeof(chr *) +
								nc*sizeof(chr);
	cv = (struct cvec *)MALLOC(n);
	if (cv == NULL)
		return NULL;
	cv->chrspace = nc;
	cv->chrs = (chr *)&cv->mcces[nmcces];	/* chrs just after MCCE ptrs */
	cv->mccespace = nmcces;
	cv->ranges = cv->chrs + nchrs + nmcces*(MAXMCCE+1);
	cv->rangespace = nranges;
	return clearcvec(cv);
}

/*
 - clearcvec - clear a possibly-new cvec
 * Returns pointer as convenience.
 ^ static struct cvec *clearcvec(struct cvec *);
 */
static struct cvec *
clearcvec(cv)
struct cvec *cv;
{
	int i;

	assert(cv != NULL);
	cv->nchrs = 0;
	assert(cv->chrs == (chr *)&cv->mcces[cv->mccespace]);
	cv->nmcces = 0;
	cv->nmccechrs = 0;
	cv->nranges = 0;
	for (i = 0; i < cv->mccespace; i++)
		cv->mcces[i] = NULL;

	return cv;
}

/*
 - addchr - add a chr to a cvec
 ^ static VOID addchr(struct cvec *, pchr);
 */
static VOID
addchr(cv, c)
struct cvec *cv;
pchr c;
{
	assert(cv->nchrs < cv->chrspace - cv->nmccechrs);
	cv->chrs[cv->nchrs++] = (chr)c;
}

/*
 - addrange - add a range to a cvec
 ^ static VOID addrange(struct cvec *, pchr, pchr);
 */
static VOID
addrange(cv, from, to)
struct cvec *cv;
pchr from;
pchr to;
{
	assert(cv->nranges < cv->rangespace);
	cv->ranges[cv->nranges*2] = (chr)from;
	cv->ranges[cv->nranges*2 + 1] = (chr)to;
	cv->nranges++;
}

#ifdef USE_MCCE
/*
 - addmcce - add an MCCE to a cvec
 ^ static VOID addmcce(struct cvec *, chr *, chr *);
 */
static VOID
addmcce(cv, startp, endp)
struct cvec *cv;
chr *startp;			/* beginning of text */
chr *endp;			/* just past end of text */
{
	int n = endp - startp;
	int i;
	chr *s;
	chr *d;

	assert(n > 0);
	assert(cv->nchrs + n < cv->chrspace - cv->nmccechrs);
	assert(cv->nmcces < cv->mccespace);
	d = &cv->chrs[cv->chrspace - cv->nmccechrs - n - 1];
	cv->mcces[cv->nmcces++] = d;
	for (s = startp, i = n; i > 0; s++, i--)
		*d++ = *s;
	*d++ = 0;		/* endmarker */
	assert(d == &cv->chrs[cv->chrspace - cv->nmccechrs]);
	cv->nmccechrs += n + 1;
}
#endif

/*
 - haschr - does a cvec contain this chr?
 ^ static int haschr(struct cvec *, pchr);
 */
static int			/* predicate */
haschr(cv, c)
struct cvec *cv;
pchr c;
{
	int i;
	chr *p;

	for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--)
		if (*p == c)
			return 1;
	for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--)
		if (*p <= c && c <= *(p+1))
			return 1;
	return 0;
}

/*
 - getcvec - get a cvec, remembering it as v->cv
 ^ static struct cvec *getcvec(struct vars *, int, int, int);
 */
static struct cvec *
getcvec(v, nchrs, nranges, nmcces)
struct vars *v;
int nchrs;			/* to hold this many chrs... */
int nranges;			/* ... and this many ranges... */
int nmcces;			/* ... and this many MCCEs */
{
	if (v->cv != NULL && nchrs <= v->cv->chrspace &&
					nranges <= v->cv->rangespace &&
					nmcces <= v->cv->mccespace)
		return clearcvec(v->cv);

	if (v->cv != NULL)
		freecvec(v->cv);
	v->cv = newcvec(nchrs, nranges, nmcces);
	if (v->cv == NULL)
		ERR(REG_ESPACE);

	return v->cv;
}

/*
 - freecvec - free a cvec
 ^ static VOID freecvec(struct cvec *);
 */
static VOID
freecvec(cv)
struct cvec *cv;
{
	FREE(cv);
}

Added generic/regc_lex.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
/*
 * lexical analyzer
 * This file is #included by regcomp.c.
 */

/* scanning macros (know about v) */
#define	ATEOS()		(v->now >= v->stop)
#define	HAVE(n)		(v->stop - v->now >= (n))
#define	NEXT1(c)	(!ATEOS() && *v->now == CHR(c))
#define	NEXT2(a,b)	(HAVE(2) && *v->now == CHR(a) && *(v->now+1) == CHR(b))
#define	NEXT3(a,b,c)	(HAVE(3) && *v->now == CHR(a) && \
						*(v->now+1) == CHR(b) && \
						*(v->now+2) == CHR(c))
#define	SET(c)		(v->nexttype = (c))
#define	SETV(c, n)	(v->nexttype = (c), v->nextvalue = (n))
#define	RET(c)		return (SET(c), 1)
#define	RETV(c, n)	return (SETV(c, n), 1)
#define	FAILW(e)	return (ERR(e), 0)	/* ERR does SET(EOS) */
#define	LASTTYPE(t)	(v->lasttype == (t))

/* lexical contexts */
#define	L_ERE	1	/* mainline ERE/ARE */
#define	L_BRE	2	/* mainline BRE */
#define	L_Q	3	/* REG_QUOTE */
#define	L_EBND	4	/* ERE/ARE bound */
#define	L_BBND	5	/* BRE bound */
#define	L_BRACK	6	/* brackets */
#define	L_CEL	7	/* collating element */
#define	L_ECL	8	/* equivalence class */
#define	L_CCL	9	/* character class */
#define	INTOCON(c)	(v->lexcon = (c))
#define	INCON(con)	(v->lexcon == (con))

/* construct pointer past end of chr array */
#define	ENDOF(array)	((array) + sizeof(array)/sizeof(chr))

/*
 - lexstart - set up lexical stuff, scan leading options
 ^ static VOID lexstart(struct vars *);
 */
static VOID
lexstart(v)
struct vars *v;
{
	prefixes(v);			/* may turn on new type bits etc. */
	NOERR();

	if (v->cflags&REG_QUOTE) {
		assert(!(v->cflags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)));
		INTOCON(L_Q);
	} else if (v->cflags&REG_EXTENDED) {
		assert(!(v->cflags&REG_QUOTE));
		INTOCON(L_ERE);
	} else {
		assert(!(v->cflags&(REG_QUOTE|REG_ADVF)));
		INTOCON(L_BRE);
	}

	v->nexttype = EMPTY;		/* remember we were at the start */
	next(v);			/* set up the first token */
}

/*
 - prefixes - implement various special prefixes
 ^ static VOID prefixes(struct vars *);
 */
static VOID
prefixes(v)
struct vars *v;
{
	/* literal string doesn't get any of this stuff */
	if (v->cflags&REG_QUOTE)
		return;

	/* initial "***" gets special things */	
	if (HAVE(4) && NEXT3('*', '*', '*'))
		switch (*(v->now + 3)) {
		case CHR('?'):		/* "***?" error, msg shows version */
			ERR(REG_BADPAT);
			return;		/* proceed no further */
			break;
		case CHR('='):		/* "***=" shifts to literal string */
			NOTE(REG_UNONPOSIX);
			v->cflags |= REG_QUOTE;
			v->cflags &= ~(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE);
			v->now += 4;
			return;		/* and there can be no more prefixes */
			break;
		case CHR(':'):		/* "***:" shifts to AREs */
			NOTE(REG_UNONPOSIX);
			v->cflags |= REG_ADVANCED;
			v->now += 4;
			break;
		default:		/* otherwise *** is just an error */
			ERR(REG_BADRPT);
			return;
			break;
		}

	/* BREs and EREs don't get embedded options */
	if ((v->cflags&REG_ADVANCED) != REG_ADVANCED)
		return;

	/* embedded options (AREs only) */
	if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2))) {
		NOTE(REG_UNONPOSIX);
		v->now += 2;
		for (; !ATEOS() && iscalpha(*v->now); v->now++)
			switch (*v->now) {
			case CHR('b'):		/* BREs (but why???) */
				v->cflags &= ~(REG_ADVANCED|REG_QUOTE);
				break;
			case CHR('c'):		/* case sensitive */
				v->cflags &= ~REG_ICASE;
				break;
			case CHR('e'):		/* plain EREs */
				v->cflags |= REG_EXTENDED;
				v->cflags &= ~(REG_ADVF|REG_QUOTE);
				break;
			case CHR('i'):		/* case insensitive */
				v->cflags |= REG_ICASE;
				break;
			case CHR('m'):		/* Perloid synonym for n */
			case CHR('n'):		/* \n affects ^ $ . [^ */
				v->cflags |= REG_NEWLINE;
				break;
			case CHR('p'):		/* ~Perl, \n affects . [^ */
				v->cflags |= REG_NLSTOP;
				v->cflags &= ~REG_NLANCH;
				break;
			case CHR('q'):		/* literal string */
				v->cflags |= REG_QUOTE;
				v->cflags &= ~REG_ADVANCED;
				break;
			case CHR('s'):		/* single line, \n ordinary */
				v->cflags &= ~REG_NEWLINE;
				break;
			case CHR('t'):		/* tight syntax */
				v->cflags &= ~REG_EXPANDED;
				break;
			case CHR('w'):		/* weird, \n affects ^ $ only */
				v->cflags &= ~REG_NLSTOP;
				v->cflags |= REG_NLANCH;
				break;
			case CHR('x'):		/* expanded syntax */
				v->cflags |= REG_EXPANDED;
				break;
			default:
				ERR(REG_BADOPT);
				return;
			}
		if (!NEXT1(')')) {
			ERR(REG_BADOPT);
			return;
		}
		v->now++;
		if (v->cflags&REG_QUOTE)
			v->cflags &= ~(REG_EXPANDED|REG_NEWLINE);
	}
}

/*
 - lexnest - "call a subroutine", interpolating string at the lexical level
 * Note, this is not a very general facility.  There are a number of
 * implicit assumptions about what sorts of strings can be subroutines.
 ^ static VOID lexnest(struct vars *, chr *, chr *);
 */
static VOID
lexnest(v, beginp, endp)
struct vars *v;
chr *beginp;				/* start of interpolation */
chr *endp;				/* one past end of interpolation */
{
	assert(v->savenow == NULL);	/* only one level of nesting */
	v->savenow = v->now;
	v->savestop = v->stop;
	v->now = beginp;
	v->stop = endp;
}

/*
 * string constants to interpolate as expansions of things like \d
 */
static chr backd[] = {		/* \d */
	CHR('['), CHR('['), CHR(':'),
	CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
	CHR(':'), CHR(']'), CHR(']')
};
static chr backD[] = {		/* \D */
	CHR('['), CHR('^'), CHR('['), CHR(':'),
	CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
	CHR(':'), CHR(']'), CHR(']')
};
static chr brbackd[] = {	/* \d within brackets */
	CHR('['), CHR(':'),
	CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
	CHR(':'), CHR(']')
};
static chr backs[] = {		/* \s */
	CHR('['), CHR('['), CHR(':'),
	CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
	CHR(':'), CHR(']'), CHR(']')
};
static chr backS[] = {		/* \S */
	CHR('['), CHR('^'), CHR('['), CHR(':'),
	CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
	CHR(':'), CHR(']'), CHR(']')
};
static chr brbacks[] = {	/* \s within brackets */
	CHR('['), CHR(':'),
	CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
	CHR(':'), CHR(']')
};
static chr backw[] = {		/* \w */
	CHR('['), CHR('['), CHR(':'),
	CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
	CHR(':'), CHR(']'), CHR('_'), CHR(']')
};
static chr backW[] = {		/* \W */
	CHR('['), CHR('^'), CHR('['), CHR(':'),
	CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
	CHR(':'), CHR(']'), CHR('_'), CHR(']')
};
static chr brbackw[] = {	/* \w within brackets */
	CHR('['), CHR(':'),
	CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
	CHR(':'), CHR(']'), CHR('_')
};

/*
 - lexword - interpolate a bracket expression for word characters
 * Possibly ought to inquire whether there is a "word" character class.
 ^ static VOID lexword(struct vars *);
 */
static VOID
lexword(v)
struct vars *v;
{
	lexnest(v, backw, ENDOF(backw));
}

/*
 - next - get next token
 ^ static int next(struct vars *);
 */
static int			/* 1 normal, 0 failure */
next(v)
struct vars *v;
{
	chr c;

	/* errors yield an infinite sequence of failures */
	if (ISERR())
		return 0;	/* the error has set nexttype to EOS */

	/* remember flavor of last token */
	v->lasttype = v->nexttype;

	/* if we're nested and we've hit end, return to outer level */
	if (v->savenow != NULL && ATEOS()) {
		v->now = v->savenow;
		v->stop = v->savestop;
		v->savenow = v->savestop = NULL;
	}

	/* skip white space etc. if appropriate (not in literal or []) */
	if (v->cflags&REG_EXPANDED)
		switch (v->lexcon) {
		case L_ERE:
		case L_BRE:
		case L_EBND:
		case L_BBND:
			skip(v);
			break;
		}

	/* handle EOS, depending on context */
	if (ATEOS()) {
		switch (v->lexcon) {
		case L_ERE:
		case L_BRE:
		case L_Q:
			RET(EOS);
			break;
		case L_EBND:
		case L_BBND:
			FAILW(REG_EBRACE);
			break;
		case L_BRACK:
		case L_CEL:
		case L_ECL:
		case L_CCL:
			FAILW(REG_EBRACK);
			break;
		}
		assert(NOTREACHED);
	}

	/* okay, time to actually get a character */
	c = *v->now++;

	/* deal with the easy contexts, punt EREs to code below */
	switch (v->lexcon) {
	case L_BRE:			/* punt BREs to separate function */
		return brenext(v, c);
		break;
	case L_ERE:			/* see below */
		break;
	case L_Q:			/* literal strings are easy */
		RETV(PLAIN, c);
		break;
	case L_BBND:			/* bounds are fairly simple */
	case L_EBND:
		switch (c) {
		case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
		case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
		case CHR('8'): case CHR('9'):
			RETV(DIGIT, (chr)DIGITVAL(c));
			break;
		case CHR(','):
			RET(',');
			break;
		case CHR('}'):		/* ERE bound ends with } */
			if (INCON(L_EBND)) {
				INTOCON(L_ERE);
				if ((v->cflags&REG_ADVF) && NEXT1('?')) {
					v->now++;
					NOTE(REG_UNONPOSIX);
					RETV('}', 0);
				}
				RETV('}', 1);
			} else
				FAILW(REG_BADBR);
			break;
		case CHR('\\'):		/* BRE bound ends with \} */
			if (INCON(L_BBND) && NEXT1('}')) {
				v->now++;
				INTOCON(L_BRE);
				RET('}');
			} else
				FAILW(REG_BADBR);
			break;
		default:
			FAILW(REG_BADBR);
			break;
		}
		assert(NOTREACHED);
		break;
	case L_BRACK:			/* brackets are not too hard */
		switch (c) {
		case CHR(']'):
			if (LASTTYPE('['))
				RETV(PLAIN, c);
			else {
				INTOCON((v->cflags&REG_EXTENDED) ?
							L_ERE : L_BRE);
				RET(']');
			}
			break;
		case CHR('\\'):
			NOTE(REG_UBBS);
			if (!(v->cflags&REG_ADVF))
				RETV(PLAIN, c);
			NOTE(REG_UNONPOSIX);
			if (ATEOS())
				FAILW(REG_EESCAPE);
			(DISCARD)lexescape(v);
			switch (v->nexttype) {	/* not all escapes okay here */
			case PLAIN:
				return 1;
				break;
			case CCLASS:
				switch (v->nextvalue) {
				case 'd':
					lexnest(v, brbackd, ENDOF(brbackd));
					break;
				case 's':
					lexnest(v, brbacks, ENDOF(brbacks));
					break;
				case 'w':
					lexnest(v, brbackw, ENDOF(brbackw));
					break;
				default:
					FAILW(REG_EESCAPE);
					break;
				}
				/* lexnest done, back up and try again */
				v->nexttype = v->lasttype;
				return next(v);
				break;
			}
			/* not one of the acceptable escapes */
			FAILW(REG_EESCAPE);
			break;
		case CHR('-'):
			if (LASTTYPE('[') || NEXT1(']'))
				RETV(PLAIN, c);
			else
				RETV(RANGE, c);
			break;
		case CHR('['):
			if (ATEOS())
				FAILW(REG_EBRACK);
			switch (*v->now++) {
			case CHR('.'):
				INTOCON(L_CEL);
				/* might or might not be locale-specific */
				RET(COLLEL);
				break;
			case CHR('='):
				INTOCON(L_ECL);
				NOTE(REG_ULOCALE);
				RET(ECLASS);
				break;
			case CHR(':'):
				INTOCON(L_CCL);
				NOTE(REG_ULOCALE);
				RET(CCLASS);
				break;
			default:			/* oops */
				v->now--;
				RETV(PLAIN, c);
				break;
			}
			assert(NOTREACHED);
			break;
		default:
			RETV(PLAIN, c);
			break;
		}
		assert(NOTREACHED);
		break;
	case L_CEL:			/* collating elements are easy */
		if (c == CHR('.') && NEXT1(']')) {
			v->now++;
			INTOCON(L_BRACK);
			RETV(END, '.');
		} else
			RETV(PLAIN, c);
		break;
	case L_ECL:			/* ditto equivalence classes */
		if (c == CHR('=') && NEXT1(']')) {
			v->now++;
			INTOCON(L_BRACK);
			RETV(END, '=');
		} else
			RETV(PLAIN, c);
		break;
	case L_CCL:			/* ditto character classes */
		if (c == CHR(':') && NEXT1(']')) {
			v->now++;
			INTOCON(L_BRACK);
			RETV(END, ':');
		} else
			RETV(PLAIN, c);
		break;
	default:
		assert(NOTREACHED);
		break;
	}

	/* that got rid of everything except EREs and AREs */
	assert(INCON(L_ERE));

	/* deal with EREs and AREs, except for backslashes */
	switch (c) {
	case CHR('|'):
		RET('|');
		break;
	case CHR('*'):
		if ((v->cflags&REG_ADVF) && NEXT1('?')) {
			v->now++;
			NOTE(REG_UNONPOSIX);
			RETV('*', 0);
		}
		RETV('*', 1);
		break;
	case CHR('+'):
		if ((v->cflags&REG_ADVF) && NEXT1('?')) {
			v->now++;
			NOTE(REG_UNONPOSIX);
			RETV('+', 0);
		}
		RETV('+', 1);
		break;
	case CHR('?'):
		if ((v->cflags&REG_ADVF) && NEXT1('?')) {
			v->now++;
			NOTE(REG_UNONPOSIX);
			RETV('?', 0);
		}
		RETV('?', 1);
		break;
	case CHR('{'):		/* bounds start or plain character */
		if (v->cflags&REG_EXPANDED)
			skip(v);
		if (ATEOS() || !iscdigit(*v->now)) {
			NOTE(REG_UBRACES);
			NOTE(REG_UUNSPEC);
			RETV(PLAIN, c);
		} else {
			NOTE(REG_UBOUNDS);
			INTOCON(L_EBND);
			RET('{');
		}
		assert(NOTREACHED);
		break;
	case CHR('('):		/* parenthesis, or advanced extension */
		if ((v->cflags&REG_ADVF) && NEXT1('?')) {
			NOTE(REG_UNONPOSIX);
			v->now++;
			switch (*v->now++) {
			case CHR(':'):		/* non-capturing paren */
				RETV('(', 0);
				break;
			case CHR('#'):		/* comment */
				while (!ATEOS() && *v->now != CHR(')'))
					v->now++;
				if (!ATEOS())
					v->now++;
				assert(v->nexttype == v->lasttype);
				return next(v);
				break;
			case CHR('='):		/* positive lookahead */
				NOTE(REG_ULOOKAHEAD);
				RETV(LACON, 1);
				break;
			case CHR('!'):		/* negative lookahead */
				NOTE(REG_ULOOKAHEAD);
				RETV(LACON, 0);
				break;
			default:
				FAILW(REG_BADRPT);
				break;
			}
			assert(NOTREACHED);
		}
		if (v->cflags&REG_NOSUB)
			RETV('(', 0);		/* all parens non-capturing */
		else
			RETV('(', 1);
		break;
	case CHR(')'):
		if (LASTTYPE('(')) {
			NOTE(REG_UUNSPEC);
		}
		RETV(')', c);
		break;
	case CHR('['):		/* easy except for [[:<:]] and [[:>:]] */
		if (HAVE(6) &&	*(v->now+0) == CHR('[') &&
				*(v->now+1) == CHR(':') &&
				(*(v->now+2) == CHR('<') ||
						*(v->now+2) == CHR('>')) &&
				*(v->now+3) == CHR(':') &&
				*(v->now+4) == CHR(']') &&
				*(v->now+5) == CHR(']')) {
			c = *(v->now+2);
			v->now += 6;
			NOTE(REG_UNONPOSIX);
			RET((c == CHR('<')) ? '<' : '>');
		}
		INTOCON(L_BRACK);
		if (NEXT1('^')) {
			v->now++;
			RETV('[', 0);
		}
		RETV('[', 1);
		break;
	case CHR('.'):
		RET('.');
		break;
	case CHR('^'):
		RET('^');
		break;
	case CHR('$'):
		RET('$');
		break;
	case CHR('\\'):		/* mostly punt backslashes to code below */
		if (ATEOS())
			FAILW(REG_EESCAPE);
		break;
	default:		/* ordinary character */
		RETV(PLAIN, c);
		break;
	}

	/* ERE/ARE backslash handling; backslash already eaten */
	assert(!ATEOS());
	if (!(v->cflags&REG_ADVF)) {	/* only AREs have non-trivial escapes */
		if (iscalnum(*v->now)) {
			NOTE(REG_UBSALNUM);
			NOTE(REG_UUNSPEC);
		}
		RETV(PLAIN, *v->now++);
	}
	(DISCARD)lexescape(v);
	if (ISERR())
		FAILW(REG_EESCAPE);
	if (v->nexttype == CCLASS) {	/* fudge at lexical level */
		switch (v->nextvalue) {
		case 'd':	lexnest(v, backd, ENDOF(backd)); break;
		case 'D':	lexnest(v, backD, ENDOF(backD)); break;
		case 's':	lexnest(v, backs, ENDOF(backs)); break;
		case 'S':	lexnest(v, backS, ENDOF(backS)); break;
		case 'w':	lexnest(v, backw, ENDOF(backw)); break;
		case 'W':	lexnest(v, backW, ENDOF(backW)); break;
		default:
			assert(NOTREACHED);
			FAILW(REG_ASSERT);
			break;
		}
		/* lexnest done, back up and try again */
		v->nexttype = v->lasttype;
		return next(v);
	}
	/* otherwise, lexescape has already done the work */
	return !ISERR();
}

/*
 - lexescape - parse an ARE backslash escape (backslash already eaten)
 * Note slightly nonstandard use of the CCLASS type code.
 ^ static int lexescape(struct vars *);
 */
static int			/* not actually used, but convenient for RETV */
lexescape(v)
struct vars *v;
{
	chr c;
	static chr alert[] = {
		CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
	};
	static chr esc[] = {
		CHR('E'), CHR('S'), CHR('C')
	};
	chr *save;

	assert(v->cflags&REG_ADVF);

	assert(!ATEOS());
	c = *v->now++;
	if (!iscalnum(c))
		RETV(PLAIN, c);

	NOTE(REG_UNONPOSIX);
	switch (c) {
	case CHR('a'):
		RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007')));
		break;
	case CHR('A'):
		RETV(SBEGIN, 0);
		break;
	case CHR('b'):
		RETV(PLAIN, CHR('\b'));
		break;
	case CHR('B'):
		RETV(PLAIN, CHR('\\'));
		break;
	case CHR('c'):
		NOTE(REG_UUNPORT);
		if (ATEOS())
			FAILW(REG_EESCAPE);
		RETV(PLAIN, (chr)(*v->now++ & 037));
		break;
	case CHR('d'):
		NOTE(REG_ULOCALE);
		RETV(CCLASS, 'd');
		break;
	case CHR('D'):
		NOTE(REG_ULOCALE);
		RETV(CCLASS, 'D');
		break;
	case CHR('e'):
		NOTE(REG_UUNPORT);
		RETV(PLAIN, chrnamed(v, esc, ENDOF(esc), CHR('\033')));
		break;
	case CHR('f'):
		RETV(PLAIN, CHR('\f'));
		break;
	case CHR('m'):
		RET('<');
		break;
	case CHR('M'):
		RET('>');
		break;
	case CHR('n'):
		RETV(PLAIN, CHR('\n'));
		break;
	case CHR('r'):
		RETV(PLAIN, CHR('\r'));
		break;
	case CHR('s'):
		NOTE(REG_ULOCALE);
		RETV(CCLASS, 's');
		break;
	case CHR('S'):
		NOTE(REG_ULOCALE);
		RETV(CCLASS, 'S');
		break;
	case CHR('t'):
		RETV(PLAIN, CHR('\t'));
		break;
	case CHR('u'):
		c = lexdigits(v, 16, 4, 4);
		if (ISERR())
			FAILW(REG_EESCAPE);
		RETV(PLAIN, c);
		break;
	case CHR('U'):
		c = lexdigits(v, 16, 8, 8);
		if (ISERR())
			FAILW(REG_EESCAPE);
		RETV(PLAIN, c);
		break;
	case CHR('v'):
		RETV(PLAIN, CHR('\v'));
		break;
	case CHR('w'):
		NOTE(REG_ULOCALE);
		RETV(CCLASS, 'w');
		break;
	case CHR('W'):
		NOTE(REG_ULOCALE);
		RETV(CCLASS, 'W');
		break;
	case CHR('x'):
		NOTE(REG_UUNPORT);
		c = lexdigits(v, 16, 1, 255);	/* REs >255 long outside spec */
		if (ISERR())
			FAILW(REG_EESCAPE);
		RETV(PLAIN, c);
		break;
	case CHR('y'):
		NOTE(REG_ULOCALE);
		RETV(WBDRY, 0);
		break;
	case CHR('Y'):
		NOTE(REG_ULOCALE);
		RETV(NWBDRY, 0);
		break;
	case CHR('Z'):
		RETV(SEND, 0);
		break;
	case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
	case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
	case CHR('9'):
		save = v->now;
		v->now--;	/* put first digit back */
		c = lexdigits(v, 10, 1, 255);	/* REs >255 long outside spec */
		if (ISERR())
			FAILW(REG_EESCAPE);
		/* ugly heuristic (first test is "exactly 1 digit?") */
		if (v->now - save == 0 || (int)c <= v->nsubexp) {
			NOTE(REG_UBACKREF);
			RETV(BACKREF, (chr)c);
		}
		/* oops, doesn't look like it's a backref after all... */
		v->now = save;
		/* and fall through into octal number */
	case CHR('0'):
		NOTE(REG_UUNPORT);
		v->now--;	/* put first digit back */
		c = lexdigits(v, 8, 1, 3);
		if (ISERR())
			FAILW(REG_EESCAPE);
		RETV(PLAIN, c);
		break;
	default:
		assert(iscalpha(c));
		FAILW(REG_EESCAPE);	/* unknown alphabetic escape */
		break;
	}
	assert(NOTREACHED);
}

/*
 - lexdigits - slurp up digits and return chr value
 ^ static chr lexdigits(struct vars *, int, int, int);
 */
static chr			/* chr value; errors signalled via ERR */
lexdigits(v, base, minlen, maxlen)
struct vars *v;
int base;
int minlen;
int maxlen;
{
	uchr n;			/* unsigned to avoid overflow misbehavior */
	int len;
	chr c;
	int d;
	CONST uchr ub = (uchr) base;

	n = 0;
	for (len = 0; len < maxlen && !ATEOS(); len++) {
		c = *v->now++;
		switch (c) {
		case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
		case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
		case CHR('8'): case CHR('9'):
			d = DIGITVAL(c);
			break;
		case CHR('a'): case CHR('A'): d = 10; break;
		case CHR('b'): case CHR('B'): d = 11; break;
		case CHR('c'): case CHR('C'): d = 12; break;
		case CHR('d'): case CHR('D'): d = 13; break;
		case CHR('e'): case CHR('E'): d = 14; break;
		case CHR('f'): case CHR('F'): d = 15; break;
		default:
			v->now--;	/* oops, not a digit at all */
			d = -1;
			break;
		}

		if (d >= base) {	/* not a plausible digit */
			v->now--;
			d = -1;
		}
		if (d < 0)
			break;		/* NOTE BREAK OUT */
		n = n*ub + (uchr)d;
	}
	if (len < minlen)
		ERR(REG_EESCAPE);

	return (chr)n;
}

/*
 - brenext - get next BRE token
 * This is much like EREs except for all the stupid backslashes and the
 * context-dependency of some things.
 ^ static int brenext(struct vars *, pchr);
 */
static int			/* 1 normal, 0 failure */
brenext(v, pc)
struct vars *v;
pchr pc;
{
	chr c = (chr)pc;

	switch (c) {
	case CHR('*'):
		if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^'))
			RETV(PLAIN, c);
		RET('*');
		break;
	case CHR('['):
		if (HAVE(6) &&	*(v->now+0) == CHR('[') &&
				*(v->now+1) == CHR(':') &&
				(*(v->now+2) == CHR('<') ||
						*(v->now+2) == CHR('>')) &&
				*(v->now+3) == CHR(':') &&
				*(v->now+4) == CHR(']') &&
				*(v->now+5) == CHR(']')) {
			c = *(v->now+2);
			v->now += 6;
			NOTE(REG_UNONPOSIX);
			RET((c == CHR('<')) ? '<' : '>');
		}
		INTOCON(L_BRACK);
		if (NEXT1('^')) {
			v->now++;
			RETV('[', 0);
		}
		RETV('[', 1);
		break;
	case CHR('.'):
		RET('.');
		break;
	case CHR('^'):
		if (LASTTYPE(EMPTY))
			RET('^');
		if (LASTTYPE('(')) {
			NOTE(REG_UUNSPEC);
			RET('^');
		}
		RETV(PLAIN, c);
		break;
	case CHR('$'):
		if (v->cflags&REG_EXPANDED)
			skip(v);
		if (ATEOS())
			RET('$');
		if (NEXT2('\\', ')')) {
			NOTE(REG_UUNSPEC);
			RET('$');
		}
		RETV(PLAIN, c);
		break;
	case CHR('\\'):
		break;		/* see below */
	default:
		RETV(PLAIN, c);
		break;
	}

	assert(c == CHR('\\'));

	if (ATEOS())
		FAILW(REG_EESCAPE);

	c = *v->now++;
	switch (c) {
	case CHR('{'):
		INTOCON(L_BBND);
		NOTE(REG_UBOUNDS);
		RET('{');
		break;
	case CHR('('):
		RETV('(', 1);
		break;
	case CHR(')'):
		RETV(')', c);
		break;
	case CHR('<'):
		NOTE(REG_UNONPOSIX);
		RET('<');
		break;
	case CHR('>'):
		NOTE(REG_UNONPOSIX);
		RET('>');
		break;
	case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
	case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
	case CHR('9'):
		NOTE(REG_UBACKREF);
		RETV(BACKREF, (chr)DIGITVAL(c));
		break;
	default:
		if (iscalnum(c)) {
			NOTE(REG_UBSALNUM);
			NOTE(REG_UUNSPEC);
		}
		RETV(PLAIN, c);
		break;
	}

	assert(NOTREACHED);
}

/*
 - skip - skip white space and comments in expanded form
 ^ static VOID skip(struct vars *);
 */
static VOID
skip(v)
struct vars *v;
{
	chr *start = v->now;

	assert(v->cflags&REG_EXPANDED);

	for (;;) {
		while (!ATEOS() && iscspace(*v->now))
			v->now++;
		if (ATEOS() || *v->now != CHR('#'))
			break;				/* NOTE BREAK OUT */
		assert(NEXT1('#'));
		while (!ATEOS() && *v->now != CHR('\n'))
			v->now++;
		/* leave the newline to be picked up by the iscspace loop */
	}

	if (v->now != start)
		NOTE(REG_UNONPOSIX);
}

/*
 - newline - return the chr for a newline
 * This helps confine use of CHR to this source file.
 ^ static chr newline(NOPARMS);
 */
static chr
newline()
{
	return CHR('\n');
}

/*
 - chrnamed - return the chr known by a given (chr string) name
 * The code is a bit clumsy, but this routine gets only such specialized
 * use that it hardly matters.
 ^ static chr chrnamed(struct vars *, chr *, chr *, pchr);
 */
static chr
chrnamed(v, startp, endp, lastresort)
struct vars *v;
chr *startp;			/* start of name */
chr *endp;			/* just past end of name */
pchr lastresort;		/* what to return if name lookup fails */
{
	celt c;
	int errsave;
	int e;
	struct cvec *cv;

	errsave = v->err;
	v->err = 0;
	c = element(v, startp, endp);
	e = v->err;
	v->err = errsave;

	if (e != 0)
		return (chr)lastresort;

	cv = range(v, c, c, 0);
	if (cv->nchrs == 0)
		return (chr)lastresort;
	return cv->chrs[0];
}

Added generic/regc_locale.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
/* 
 * regc_locale.c --
 *
 *	This file contains the Unicode locale specific regexp routines.
 *	This file is #included by regcomp.c.
 *
 * 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: regc_locale.c,v 1.1.2.6 1999/04/02 23:44:53 stanton Exp $
 */

/* ASCII character-name table */

static struct cname {
	char *name;
	char code;
} cnames[] = {
	{"NUL",	'\0'},
	{"SOH",	'\001'},
	{"STX",	'\002'},
	{"ETX",	'\003'},
	{"EOT",	'\004'},
	{"ENQ",	'\005'},
	{"ACK",	'\006'},
	{"BEL",	'\007'},
	{"alert",	'\007'},
	{"BS",		'\010'},
	{"backspace",	'\b'},
	{"HT",		'\011'},
	{"tab",		'\t'},
	{"LF",		'\012'},
	{"newline",	'\n'},
	{"VT",		'\013'},
	{"vertical-tab",	'\v'},
	{"FF",		'\014'},
	{"form-feed",	'\f'},
	{"CR",		'\015'},
	{"carriage-return",	'\r'},
	{"SO",	'\016'},
	{"SI",	'\017'},
	{"DLE",	'\020'},
	{"DC1",	'\021'},
	{"DC2",	'\022'},
	{"DC3",	'\023'},
	{"DC4",	'\024'},
	{"NAK",	'\025'},
	{"SYN",	'\026'},
	{"ETB",	'\027'},
	{"CAN",	'\030'},
	{"EM",	'\031'},
	{"SUB",	'\032'},
	{"ESC",	'\033'},
	{"IS4",	'\034'},
	{"FS",	'\034'},
	{"IS3",	'\035'},
	{"GS",	'\035'},
	{"IS2",	'\036'},
	{"RS",	'\036'},
	{"IS1",	'\037'},
	{"US",	'\037'},
	{"space",		' '},
	{"exclamation-mark",	'!'},
	{"quotation-mark",	'"'},
	{"number-sign",		'#'},
	{"dollar-sign",		'$'},
	{"percent-sign",		'%'},
	{"ampersand",		'&'},
	{"apostrophe",		'\''},
	{"left-parenthesis",	'('},
	{"right-parenthesis",	')'},
	{"asterisk",	'*'},
	{"plus-sign",	'+'},
	{"comma",	','},
	{"hyphen",	'-'},
	{"hyphen-minus",	'-'},
	{"period",	'.'},
	{"full-stop",	'.'},
	{"slash",	'/'},
	{"solidus",	'/'},
	{"zero",		'0'},
	{"one",		'1'},
	{"two",		'2'},
	{"three",	'3'},
	{"four",		'4'},
	{"five",		'5'},
	{"six",		'6'},
	{"seven",	'7'},
	{"eight",	'8'},
	{"nine",		'9'},
	{"colon",	':'},
	{"semicolon",	';'},
	{"less-than-sign",	'<'},
	{"equals-sign",		'='},
	{"greater-than-sign",	'>'},
	{"question-mark",	'?'},
	{"commercial-at",	'@'},
	{"left-square-bracket",	'['},
	{"backslash",		'\\'},
	{"reverse-solidus",	'\\'},
	{"right-square-bracket",	']'},
	{"circumflex",		'^'},
	{"circumflex-accent",	'^'},
	{"underscore",		'_'},
	{"low-line",		'_'},
	{"grave-accent",		'`'},
	{"left-brace",		'{'},
	{"left-curly-bracket",	'{'},
	{"vertical-line",	'|'},
	{"right-brace",		'}'},
	{"right-curly-bracket",	'}'},
	{"tilde",		'~'},
	{"DEL",	'\177'},
	{NULL,	0}
};

/* Unicode character-class tables */

typedef struct crange {
    chr start;
    chr end;
} crange;

static crange alphaTable[] = {
    {0X0041, 0X005A}, {0X0061, 0X007A}, {0X00AA, 0X00AA}, {0X00B5, 0X00B5}, 
    {0X00BA, 0X00BA}, {0X00C0, 0X00D6}, {0X00D8, 0X00F6}, {0X00F8, 0X01F5},
    {0X01FA, 0X0217}, {0X0250, 0X02A8}, {0X02B0, 0X02B8}, {0X02BB, 0X02C1},
    {0X02E0, 0X02E4}, {0X037A, 0X037A}, {0x0386, 0x0386}, {0X0388, 0X038A},
    {0X038C, 0X038C}, {0X038E, 0X03A1}, {0X03A3, 0X03CE}, {0X03D0, 0X03D6},
    {0X03DA, 0X03DA}, {0X03DC, 0X03DC}, {0X03DE, 0X03DE}, {0X03E0, 0X03E0}, 
    {0X03E2, 0X03F3}, {0X0401, 0X040C}, {0X040E, 0X044F}, {0X0451, 0X045C},
    {0X045E, 0X0481}, {0X0490, 0X04C4}, {0X04C7, 0X04C8}, {0X04CB, 0X04CC},
    {0X04D0, 0X04EB}, {0X04EE, 0X04F5}, {0X04F8, 0X04F9}, {0x0531, 0x0556},
    {0x0559, 0x0559}, {0x0561, 0x0587}, {0X05D0, 0X05EA}, {0X05F0, 0X05F2},
    {0X0621, 0X063A}, {0x0641, 0x0652}, {0X0670, 0X06B7}, {0X06BA, 0X06BE},
    {0X06C0, 0X06CE}, {0X06D0, 0X06D3}, {0X06D5, 0X06DC}, {0X06E1, 0X06E8},
    {0X06ED, 0X06ED}, {0x0901, 0x0903}, {0x0905, 0x0939}, {0X093D, 0X094C},
    {0x0958, 0x0963}, {0x0981, 0x0983}, {0X0985, 0X098C}, {0X098F, 0X0990},
    {0X0993, 0X09A8}, {0X09AA, 0X09B0}, {0X09B2, 0X09B2}, {0X09B6, 0X09B9},
    {0X09BE, 0X09C4}, {0X09C7, 0X09C8}, {0X09CB, 0X09CC}, {0X09D7, 0X09D7}, 
    {0X09DC, 0X09DD}, {0X09DF, 0X09E3}, {0X09F0, 0X09F1}, {0X0A02, 0X0A02}, 
    {0X0A05, 0X0A0A}, {0X0A0F, 0X0A10}, {0X0A13, 0X0A28}, {0X0A2A, 0X0A30},
    {0X0A32, 0X0A33}, {0X0A35, 0X0A36}, {0X0A38, 0X0A39}, {0X0A3E, 0X0A42},
    {0X0A47, 0X0A48}, {0X0A4B, 0X0A4C}, {0X0A59, 0X0A5C}, {0X0A5E, 0X0A5E}, 
    {0X0A70, 0X0A74}, {0X0A81, 0X0A83}, {0X0A85, 0X0A8B}, {0X0A8D, 0X0A8D}, 
    {0X0A8F, 0X0A91}, {0X0A93, 0X0AA8}, {0X0AAA, 0X0AB0}, {0X0AB2, 0X0AB3},
    {0X0AB5, 0X0AB9}, {0X0ABD, 0X0AC5}, {0X0AC7, 0X0AC9}, {0X0ACB, 0X0ACC},
    {0X0AE0, 0X0AE0}, {0X0B01, 0X0B03}, {0X0B05, 0X0B0C}, {0X0B0F, 0X0B10},
    {0X0B13, 0X0B28}, {0X0B2A, 0X0B30}, {0X0B32, 0X0B33}, {0X0B36, 0X0B39},
    {0X0B3D, 0X0B43}, {0X0B47, 0X0B48}, {0X0B4B, 0X0B4C}, {0X0B56, 0X0B57},
    {0X0B5C, 0X0B5D}, {0X0B5F, 0X0B61}, {0X0B82, 0X0B83}, {0X0B85, 0X0B8A},
    {0X0B8E, 0X0B90}, {0X0B92, 0X0B95}, {0X0B99, 0X0B9A}, {0X0B9C, 0X0B9C}, 
    {0X0B9E, 0X0B9F}, {0X0BA3, 0X0BA4}, {0X0BA8, 0X0BAA}, {0X0BAE, 0X0BB5},
    {0X0BB7, 0X0BB9}, {0X0BBE, 0X0BC2}, {0X0BC6, 0X0BC8}, {0X0BCA, 0X0BCC},
    {0X0BD7, 0X0BD7}, {0X0C01, 0X0C03}, {0X0C05, 0X0C0C}, {0X0C0E, 0X0C10},
    {0X0C12, 0X0C28}, {0X0C2A, 0X0C33}, {0X0C35, 0X0C39}, {0X0C3E, 0X0C44},
    {0X0C46, 0X0C48}, {0X0C4A, 0X0C4C}, {0X0C55, 0X0C56}, {0X0C60, 0X0C61},
    {0X0C82, 0X0C83}, {0X0C85, 0X0C8C}, {0X0C8E, 0X0C90}, {0X0C92, 0X0CA8},
    {0X0CAA, 0X0CB3}, {0X0CB5, 0X0CB9}, {0X0CBE, 0X0CC4}, {0X0CC6, 0X0CC8},
    {0X0CCA, 0X0CCC}, {0X0CD5, 0X0CD6}, {0X0CDE, 0X0CDE}, {0X0CE0, 0X0CE1},
    {0X0D02, 0X0D03}, {0X0D05, 0X0D0C}, {0X0D0E, 0X0D10}, {0X0D12, 0X0D28},
    {0X0D2A, 0X0D39}, {0X0D3E, 0X0D43}, {0X0D46, 0X0D48}, {0X0D4A, 0X0D4C},
    {0X0D57, 0X0D57}, {0X0D60, 0X0D61}, {0X0E01, 0X0E2E}, {0X0E30, 0X0E3A},
    {0X0E40, 0X0E45}, {0X0E47, 0X0E47}, {0X0E4D, 0X0E4D}, {0X0E81, 0X0E82},
    {0X0E84, 0X0E84}, {0X0E87, 0X0E88}, {0X0E8A, 0X0E8A}, {0X0E8D, 0X0E8D}, 
    {0X0E94, 0X0E97}, {0X0E99, 0X0E9F}, {0X0EA1, 0X0EA3}, {0X0EA5, 0X0EA5}, 
    {0X0EA7, 0X0EA7}, {0X0EAA, 0X0EAB}, {0X0EAD, 0X0EAE}, {0X0EB0, 0X0EB9},
    {0X0EBB, 0X0EBD}, {0X0EC0, 0X0EC4}, {0X0ECD, 0X0ECD}, {0X0EDC, 0X0EDD},
    {0X0F40, 0X0F47}, {0X0F49, 0X0F69}, {0X0F71, 0X0F81}, {0X0F90, 0X0F95},
    {0X0F97, 0X0F97}, {0X0F99, 0X0FAD}, {0X0FB1, 0X0FB7}, {0X0FB9, 0X0FB9}, 
    {0X10A0, 0X10C5}, {0X10D0, 0X10F6}, {0x1100, 0x1159}, {0X115F, 0X11A2},
    {0X11A8, 0X11F9}, {0X1E00, 0X1E9B}, {0X1EA0, 0X1EF9}, {0X1F00, 0X1F15},
    {0X1F18, 0X1F1D}, {0X1F20, 0X1F45}, {0X1F48, 0X1F4D}, {0X1F50, 0X1F57},
    {0X1F59, 0X1F59}, {0X1F5B, 0X1F5B}, {0X1F5D, 0X1F5D}, {0X1F5F, 0X1F7D},
    {0X1F80, 0X1FB4}, {0X1FB6, 0X1FBC}, {0X1FBE, 0X1FBE}, {0X1FC2, 0X1FC4},
    {0X1FC6, 0X1FCC}, {0X1FD0, 0X1FD3}, {0X1FD6, 0X1FDB}, {0X1FE0, 0X1FEC},
    {0X1FF2, 0X1FF4}, {0X1FF6, 0X1FFC}, {0X207F, 0X207F}, {0x2102, 0x2102}, 
    {0x2107, 0x2107}, {0X210A, 0X2113}, {0x2115, 0x2115}, {0X2118, 0X211D},
    {0x2124, 0x2124}, {0x2126, 0x2126}, {0x2128, 0x2128}, {0X212A, 0X2131},
    {0x2133, 0x2138}, {0x2160, 0x2182}, {0x3041, 0x3094}, {0X30A1, 0X30FA},
    {0X3105, 0X312C}, {0X3131, 0X318E}, {0XAC00, 0XD7A3}, {0XFB00, 0XFB06},
    {0XFB13, 0XFB17}, {0XFB1F, 0XFB28}, {0XFB2A, 0XFB36}, {0XFB38, 0XFB3C},
    {0XFB3E, 0XFB3E}, {0XFB40, 0XFB41}, {0XFB43, 0XFB44}, {0XFB46, 0XFBB1},
    {0XFBD3, 0XFD3D}, {0XFD50, 0XFD8F}, {0XFD92, 0XFDC7}, {0XFDF0, 0XFDFB},
    {0XFE70, 0XFE72}, {0XFE74, 0XFE74}, {0XFE76, 0XFEFC}, {0XFF21, 0XFF3A},
    {0XFF41, 0XFF5A}, {0XFF66, 0XFF6F}, {0XFF71, 0XFF9D}, {0XFFA0, 0XFFBE},
    {0XFFC2, 0XFFC7}, {0XFFCA, 0XFFCF}, {0XFFD2, 0XFFD7}, {0XFFDA, 0XFFDC}
};

#define NUM_ALPHA (sizeof(alphaTable)/sizeof(crange))

static crange digitTable[] = {
    {0x0030, 0x0039}
};

#define NUM_DIGIT (sizeof(digitTable)/sizeof(crange))

static crange punctTable[] = {
    {0x0021, 0x0023}, {0X0025, 0X002A}, {0X002C, 0X002F}, {0X003A, 0X003B},
    {0X003F, 0X0040}, {0X005B, 0X005D}, {0X005F, 0X005F}, {0X007B, 0X007B},
    {0X007D, 0X007D}, {0X00A1, 0X00A1}, {0X00AB, 0X00AB}, {0X00AD, 0X00AD},
    {0X00BB, 0X00BB}, {0X00BF, 0X00BF}, {0X02BC, 0X02BC}, {0x0374, 0x0375},
    {0X037E, 0X037E}, {0x0387, 0x0387}, {0X055A, 0X055F}, {0x0589, 0x0589},
    {0X05BE, 0X05BE}, {0X05C0, 0X05C0}, {0X05C3, 0X05C3}, {0X05F3, 0X05F4},
    {0X060C, 0X060C}, {0X061B, 0X061B}, {0X061F, 0X061F}, {0X066A, 0X066D},
    {0X06D4, 0X06D4}, {0x0964, 0x0965}, {0x0970, 0x0970}, {0X0E2F, 0X0E2F},
    {0X0E5A, 0X0E5B}, {0X0EAF, 0X0EAF}, {0X0F04, 0X0F12}, {0X0F3A, 0X0F3F},
    {0X0F85, 0X0F85}, {0X10FB, 0X10FB}, {0x2010, 0x2027}, {0x2030, 0x2043},
    {0x2045, 0x2046}, {0X207D, 0X207E}, {0X208D, 0X208E}, {0X2329, 0X232A},
    {0x3001, 0x3003}, {0x3006, 0x3006}, {0x3008, 0x3011}, {0X3014, 0X301F},
    {0x3030, 0x3030}, {0X30FB, 0X30FB}, {0XFD3E, 0XFD3F}, {0XFE30, 0XFE44},
    {0XFE49, 0XFE52}, {0XFE54, 0XFE61}, {0XFE63, 0XFE63}, {0XFE68, 0XFE68},
    {0XFE6A, 0XFE6B}, {0XFF01, 0XFF03}, {0XFF05, 0XFF0A}, {0XFF0C, 0XFF0F},
    {0XFF1A, 0XFF1B}, {0XFF1F, 0XFF20}, {0XFF3B, 0XFF3D}, {0XFF3F, 0XFF3F},
    {0XFF5B, 0XFF5B}, {0XFF5D, 0XFF5D}, {0XFF61, 0XFF65}
};

#define NUM_PUNCT (sizeof(punctTable)/sizeof(crange))

static crange spaceTable[] = {
    {0x0000, 0x0000}, {0x0009, 0x000D}, {0x0020, 0x0020}, {0x00A0, 0x00A0},
    {0x2000, 0x200F}, {0x2028, 0x202E}, {0X206A, 0X206F}, {0x3000, 0x3000},
    {0xFEFF, 0xFEFF}
};  

#define NUM_SPACE (sizeof(spaceTable)/sizeof(crange))

static crange upperRangeTable[] = {
    {0x0041, 0x005a}, {0x00c0, 0x00d6}, {0x00d8, 0x00de}, {0x0189, 0x018b},
    {0x018e, 0x0191}, {0x0388, 0x038a}, {0x0391, 0x03a1}, {0x03a3, 0x03ab},
    {0x03d2, 0x03d4}, {0x0401, 0x040c}, {0x040e, 0x042f}, {0x0531, 0x0556},
    {0x10a0, 0x10c5}, {0x1f08, 0x1f0f}, {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f},
    {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d}, {0x1f68, 0x1f6f}, {0x1f88, 0x1f8f},
    {0x1f98, 0x1f9f}, {0x1fa8, 0x1faf}, {0x1fb8, 0x1fbc}, {0x1fc8, 0x1fcc},
    {0x1fd8, 0x1fdb}, {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffc}, {0x210b, 0x210d},
    {0x2110, 0x2112}, {0x2118, 0x211d}, {0x212a, 0x212d}, {0x2130, 0x2131},
    {0xff21, 0xff3a}
};

#define NUM_UPPER_RANGE (sizeof(upperRangeTable)/sizeof(crange))

static chr upperCharTable[] = {
    0x0100, 0x0102, 0x0104, 0x0106, 0x0108, 0x010a, 0x010c, 0x010e, 0x0110,
    0x0112, 0x0114, 0x0116, 0x0118, 0x011a, 0x011c, 0x011e, 0x0120, 0x0122,
    0x0124, 0x0126, 0x0128, 0x012a, 0x012c, 0x012e, 0x0130, 0x0132, 0x0134,
    0x0136, 0x0139, 0x013b, 0x013d, 0x013f, 0x0141, 0x0143, 0x0145, 0x0147,
    0x014a, 0x014c, 0x014e, 0x0150, 0x0152, 0x0154, 0x0156, 0x0158, 0x015a,
    0x015c, 0x015e, 0x0160, 0x0162, 0x0164, 0x0166, 0x0168, 0x016a, 0x016c,
    0x016e, 0x0170, 0x0172, 0x0174, 0x0176, 0x0178, 0x0179, 0x017b, 0x017d,
    0x0181, 0x0182, 0x0184, 0x0186, 0x0187, 0x0193, 0x0194, 0x0196, 0x0197,
    0x0198, 0x019c, 0x019d, 0x019f, 0x01a0, 0x01a2, 0x01a4, 0x01a6, 0x01a7,
    0x01a9, 0x01ac, 0x01ae, 0x01af, 0x01b1, 0x01b2, 0x01b3, 0x01b5, 0x01b7,
    0x01b8, 0x01bc, 0x01c4, 0x01c7, 0x01ca, 0x01cd, 0x01cf, 0x01d1, 0x01d3,
    0x01d5, 0x01d7, 0x01d9, 0x01db, 0x01de, 0x01e0, 0x01e2, 0x01e4, 0x01e6,
    0x01e8, 0x01ea, 0x01ec, 0x01ee, 0x01f1, 0x01f4, 0x01fa, 0x01fc, 0x01fe,
    0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020a, 0x020c, 0x020e, 0x0210,
    0x0212, 0x0214, 0x0216, 0x0386, 0x038c, 0x038e, 0x038f, 0x03da, 0x03dc,
    0x03de, 0x03e0, 0x03e2, 0x03e4, 0x03e6, 0x03e8, 0x03ea, 0x03ec, 0x03ee,
    0x0460, 0x0462, 0x0464, 0x0466, 0x0468, 0x046a, 0x046c, 0x046e, 0x0470,
    0x0472, 0x0474, 0x0476, 0x0478, 0x047a, 0x047c, 0x047e, 0x0480, 0x0490,
    0x0492, 0x0494, 0x0496, 0x0498, 0x049a, 0x049c, 0x049e, 0x04a0, 0x04a2,
    0x04a4, 0x04a6, 0x04a8, 0x04aa, 0x04ac, 0x04ae, 0x04b0, 0x04b2, 0x04b4,
    0x04b6, 0x04b8, 0x04ba, 0x04bc, 0x04be, 0x04c1, 0x04c3, 0x04c7, 0x04cb,
    0x04d0, 0x04d2, 0x04d4, 0x04d6, 0x04d8, 0x04da, 0x04dc, 0x04de, 0x04e0,
    0x04e2, 0x04e4, 0x04e6, 0x04e8, 0x04ea, 0x04ee, 0x04f0, 0x04f2, 0x04f4,
    0x04f8, 0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08, 0x1e0a, 0x1e0c, 0x1e0e,
    0x1e10, 0x1e12, 0x1e14, 0x1e16, 0x1e18, 0x1e1a, 0x1e1c, 0x1e1e, 0x1e20,
    0x1e22, 0x1e24, 0x1e26, 0x1e28, 0x1e2a, 0x1e2c, 0x1e2e, 0x1e30, 0x1e32,
    0x1e34, 0x1e36, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e, 0x1e40, 0x1e42, 0x1e44,
    0x1e46, 0x1e48, 0x1e4a, 0x1e4c, 0x1e4e, 0x1e50, 0x1e52, 0x1e54, 0x1e56,
    0x1e58, 0x1e5a, 0x1e5c, 0x1e5e, 0x1e60, 0x1e62, 0x1e64, 0x1e66, 0x1e68,
    0x1e6a, 0x1e6c, 0x1e6e, 0x1e70, 0x1e72, 0x1e74, 0x1e76, 0x1e78, 0x1e7a,
    0x1e7c, 0x1e7e, 0x1e80, 0x1e82, 0x1e84, 0x1e86, 0x1e88, 0x1e8a, 0x1e8c,
    0x1e8e, 0x1e90, 0x1e92, 0x1e94, 0x1ea0, 0x1ea2, 0x1ea4, 0x1ea6, 0x1ea8,
    0x1eaa, 0x1eac, 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4, 0x1eb6, 0x1eb8, 0x1eba,
    0x1ebc, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ec8, 0x1eca, 0x1ecc,
    0x1ece, 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, 0x1eda, 0x1edc, 0x1ede,
    0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea, 0x1eec, 0x1eee, 0x1ef0,
    0x1ef2, 0x1ef4, 0x1ef6, 0x1ef8, 0x1f59, 0x1f5b, 0x1f5d, 0x1f5f, 0x1fbe,
    0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x2133
};

#define NUM_UPPER_CHAR (sizeof(upperCharTable)/sizeof(chr))

static crange lowerRangeTable[] = {
    {0x0061, 0x007a}, {0x00df, 0x00f6}, {0x00f8, 0x00ff}, {0x0199, 0x019b},
    {0x0250, 0x02a8}, {0x03ac, 0x03ce}, {0x03ef, 0x03f2}, {0x0430, 0x044f},
    {0x0451, 0x045c}, {0x0561, 0x0587}, {0x10d0, 0x10f6}, {0x1e95, 0x1e9b},
    {0x1f00, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27}, {0x1f30, 0x1f37},
    {0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67}, {0x1f70, 0x1f7d},
    {0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7}, {0x1fb0, 0x1fb4},
    {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7}, {0x1ff2, 0x1ff4}, {0xfb00, 0xfb06},
    {0xfb13, 0xfb17}, {0xff41, 0xff5a}
};

#define NUM_LOWER_RANGE (sizeof(lowerRangeTable)/sizeof(crange))

static chr lowerCharTable[] = {
    0x00aa, 0x00b5, 0x00ba, 0x0101, 0x0103, 0x0105, 0x0107, 0x0109, 0x010b,
    0x010d, 0x010f, 0x0111, 0x0113, 0x0115, 0x0117, 0x0119, 0x011b, 0x011d,
    0x011f, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0x012b, 0x012d, 0x012f,
    0x0131, 0x0133, 0x0135, 0x0138, 0x013a, 0x013c, 0x013e, 0x0140, 0x0142,
    0x0144, 0x0146, 0x0149, 0x014b, 0x014d, 0x014f, 0x0151, 0x0153, 0x0155,
    0x0157, 0x0159, 0x015b, 0x015d, 0x015f, 0x0161, 0x0163, 0x0165, 0x0167,
    0x0169, 0x016b, 0x016d, 0x016f, 0x0171, 0x0173, 0x0175, 0x0177, 0x017a,
    0x017c, 0x017e, 0x017f, 0x0180, 0x0183, 0x0185, 0x0188, 0x018c, 0x018d,
    0x0192, 0x0195, 0x019e, 0x01a1, 0x01a3, 0x01a5, 0x01a8, 0x01ab, 0x01ad,
    0x01b0, 0x01b4, 0x01b6, 0x01b9, 0x01ba, 0x01bd, 0x01c6, 0x01c9, 0x01cc,
    0x01ce, 0x01d0, 0x01d2, 0x01d4, 0x01d6, 0x01d8, 0x01da, 0x01dd, 0x01df,
    0x01e1, 0x01e3, 0x01e5, 0x01e7, 0x01e9, 0x01eb, 0x01ed, 0x01f0, 0x01f3,
    0x01f5, 0x01fb, 0x01fd, 0x01ff, 0x0201, 0x0203, 0x0205, 0x0207, 0x0209,
    0x020b, 0x020d, 0x020f, 0x0211, 0x0213, 0x0215, 0x0217, 0x0390, 0x03d0,
    0x03d1, 0x03d5, 0x03d6, 0x03e3, 0x03e5, 0x03e7, 0x03e9, 0x03eb, 0x03ed,
    0x045e, 0x045f, 0x0461, 0x0463, 0x0465, 0x0467, 0x0469, 0x046b, 0x046d,
    0x046f, 0x0471, 0x0473, 0x0475, 0x0477, 0x0479, 0x047b, 0x047d, 0x047f,
    0x0481, 0x0491, 0x0493, 0x0495, 0x0497, 0x0499, 0x049b, 0x049d, 0x049f,
    0x04a1, 0x04a3, 0x04a5, 0x04a7, 0x04a9, 0x04ab, 0x04ad, 0x04af, 0x04b1,
    0x04b3, 0x04b5, 0x04b7, 0x04b9, 0x04bb, 0x04bd, 0x04bf, 0x04c2, 0x04c4,
    0x04c8, 0x04cc, 0x04d1, 0x04d3, 0x04d5, 0x04d7, 0x04d9, 0x04db, 0x04dd,
    0x04df, 0x04e1, 0x04e3, 0x04e5, 0x04e7, 0x04e9, 0x04eb, 0x04ef, 0x04f1,
    0x04f3, 0x04f5, 0x04f9, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b,
    0x1e0d, 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d,
    0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d, 0x1e2f,
    0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, 0x1e3f, 0x1e41,
    0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e4f, 0x1e51, 0x1e53,
    0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, 0x1e63, 0x1e65,
    0x1e67, 0x1e69, 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77,
    0x1e79, 0x1e7b, 0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89,
    0x1e8b, 0x1e8d, 0x1e8f, 0x1e91, 0x1e93, 0x1ea1, 0x1ea3, 0x1ea5, 0x1ea7,
    0x1ea9, 0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9,
    0x1ebb, 0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb,
    0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb, 0x1edd,
    0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, 0x1eed, 0x1eef,
    0x1ef1, 0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1fb6, 0x1fb7, 0x1fc2, 0x1fc3,
    0x1fc4, 0x1fc6, 0x1fc7, 0x1fd6, 0x1fd7, 0x1ff6, 0x1ff7, 0x207f, 0x210a,
    0x210e, 0x210f, 0x2113, 0x212e, 0x212f, 0x2134
};

#define NUM_LOWER_CHAR (sizeof(lowerCharTable)/sizeof(chr))

/*
 * The graph table includes the set of characters that are neither ISO control
 * characters nor in the space table.
 */

static crange graphTable[] = {
    {0x0021, 0x007e}, {0x00a1, 0x1fff}, {0x2010, 0x2027}, {0x202f, 0x2069},
    {0x2070, 0x2fff}, {0x3001, 0xfefe}, {0xff00, 0xffff}
};

#define NUM_GRAPH (sizeof(graphTable)/sizeof(crange))
#define	CH	NOCELT

/*
 - nmcces - how many distinct MCCEs are there?
 ^ static int nmcces(struct vars *);
 */
static int
nmcces(v)
struct vars *v;
{
	return 0;
}

/*
 - nleaders - how many chrs can be first chrs of MCCEs?
 ^ static int nleaders(struct vars *);
 */
static int
nleaders(v)
struct vars *v;
{
	return 0;
}

/*
 - allmcces - return a cvec with all the MCCEs of the locale
 ^ static struct cvec *allmcces(struct vars *, struct cvec *);
 */
static struct cvec *
allmcces(v, cv)
struct vars *v;
struct cvec *cv;		/* this is supposed to have enough room */
{
	return clearcvec(cv);
}

/*
 - element - map collating-element name to celt
 ^ static celt element(struct vars *, chr *, chr *);
 */
static celt
element(v, startp, endp)
struct vars *v;
chr *startp;			/* points to start of name */
chr *endp;			/* points just past end of name */
{
	struct cname *cn;
	size_t len;
	Tcl_DString ds;
	char *np;

	/* generic:  one-chr names stand for themselves */
	assert(startp < endp);
	len = endp - startp;
	if (len == 1)
		return *startp;

	NOTE(REG_ULOCALE);

	/* search table */
	Tcl_DStringInit(&ds);
	np = Tcl_UniCharToUtfDString(startp, (int)len, &ds);
	for (cn = cnames; cn->name != NULL; cn++)
		if (strlen(cn->name) == len && strncmp(cn->name, np, len) == 0)
			break;		/* NOTE BREAK OUT */
	Tcl_DStringFree(&ds);
	if (cn->name != NULL)
		return CHR(cn->code);

	/* couldn't find it */
	ERR(REG_ECOLLATE);
	return 0;
}

/*
 - range - supply cvec for a range, including legality check
 ^ static struct cvec *range(struct vars *, celt, celt, int);
 */
static struct cvec *
range(v, a, b, cases)
struct vars *v;
celt a;
celt b;				/* might equal a */
int cases;			/* case-independent? */
{
	int nchrs;
	struct cvec *cv;
	celt c, lc, uc, tc;

	if (a != b && !before(a, b)) {
		ERR(REG_ERANGE);
		return NULL;
	}

	if (!cases) {		/* easy version */
		cv = getcvec(v, 0, 1, 0);
		NOERRN();
		addrange(cv, a, b);
		return cv;
	}

	/*
	 * When case-independent, it's hard to decide when cvec ranges are
	 * usable, so for now at least, we won't try.  We allocate enough
	 * space for two case variants plus a little extra for the two
	 * title case variants.
	 */

	nchrs = (b - a + 1)*2 + 4;

	cv = getcvec(v, nchrs, 0, 0);
	NOERRN();

	for (c = a; c <= b; c++) {
		addchr(cv, c);
		lc = Tcl_UniCharToLower((chr)c);
		uc = Tcl_UniCharToUpper((chr)c);
		tc = Tcl_UniCharToTitle((chr)c);
		if (c != lc) {
			addchr(cv, lc);
		}
		if (c != uc) {
			addchr(cv, uc);
		}
		if (c != tc && tc != uc) {
			addchr(cv, tc);
		}
	}

	return cv;
}

/*
 - before - is celt x before celt y, for purposes of range legality?
 ^ static int before(celt, celt);
 */
static int			/* predicate */
before(x, y)
celt x;
celt y;
{
	/* trivial because no MCCEs */
	if (x < y)
		return 1;
	return 0;
}

/*
 - eclass - supply cvec for an equivalence class
 * Must include case counterparts on request.
 ^ static struct cvec *eclass(struct vars *, celt, int);
 */
static struct cvec *
eclass(v, c, cases)
struct vars *v;
celt c;
int cases;			/* all cases? */
{
	struct cvec *cv;

	/* crude fake equivalence class for testing */
	if ((v->cflags&REG_FAKEEC) && c == 'x') {
		cv = getcvec(v, 4, 0, 0);
		addchr(cv, (chr)'x');
		addchr(cv, (chr)'y');
		if (cases) {
			addchr(cv, (chr)'X');
			addchr(cv, (chr)'Y');
		}
		return cv;
	}

	/* otherwise, none */
	if (cases)
		return allcases(v, c);
	cv = getcvec(v, 1, 0, 0);
	assert(cv != NULL);
	addchr(cv, (chr)c);
	return cv;
}

/*
 - cclass - supply cvec for a character class
 * Must include case counterparts on request.
 ^ static struct cvec *cclass(struct vars *, chr *, chr *, int);
 */
static struct cvec *
cclass(v, startp, endp, cases)
struct vars *v;
chr *startp;			/* where the name starts */
chr *endp;			/* just past the end of the name */
int cases;			/* case-independent? */
{
    size_t len;
    struct cvec *cv = NULL;
    Tcl_DString ds;
    char *np, **namePtr;
    int i, index;

    /*
     * The following arrays define the valid character class names.
     */

    static char *classNames[] = {
	"alnum", "alpha", "blank", "cntrl", "digit", "graph", "lower",
	"print", "punct", "space", "upper", "xdigit", NULL
    };

    enum classes {
	CC_ALNUM, CC_ALPHA, CC_BLANK, CC_CNTRL, CC_DIGIT, CC_GRAPH, CC_LOWER,
	CC_PRINT, CC_PUNCT, CC_SPACE, CC_UPPER, CC_XDIGIT
    };
    

    /*
     * Extract the class name
     */

    len = endp - startp;
    Tcl_DStringInit(&ds);
    np = Tcl_UniCharToUtfDString(startp, (int)len, &ds);

    /*
     * Remap lower and upper to alpha if the match is case insensitive.
     */

    if (cases && len == 5 && (strncmp("lower", np, 5) == 0
	    || strncmp("upper", np, 5) == 0)) {
	np = "alpha";
    }

    /*
     * Map the name to the corresponding enumerated value.
     */

    index = -1;
    for (namePtr = classNames, i = 0; *namePtr != NULL; namePtr++, i++) {
	if ((strlen(*namePtr) == len) && (strncmp(*namePtr, np, len) == 0)) {
	    index = i;
	    break;
	}
    }
    Tcl_DStringInit(&ds);
    if (index == -1) {
	ERR(REG_ECTYPE);
	return NULL;
    }
    
    /*
     * Now compute the character class contents.
     */

    switch((enum classes) index) {
	case CC_PRINT:
	case CC_ALNUM:
	    cv = getcvec(v, 0, NUM_DIGIT + NUM_ALPHA, 0);
	    if (cv) {	
		for (i = 0; i < NUM_ALPHA; i++) {
		    addrange(cv, alphaTable[i].start, alphaTable[i].end);
		}
		for (i = 0; i < NUM_DIGIT; i++) {
		    addrange(cv, digitTable[i].start, digitTable[i].end);
		}
	    }
	    break;
	case CC_ALPHA:
	    cv = getcvec(v, 0, NUM_ALPHA, 0);
	    if (cv) {
		for (i = 0; i < NUM_ALPHA; i++) {
		    addrange(cv, alphaTable[i].start, alphaTable[i].end);
		}
	    }
	    break;
	case CC_BLANK:
	    cv = getcvec(v, 2, 0, 0);
	    addchr(cv, '\t');
	    addchr(cv, ' ');
	    break;
	case CC_CNTRL:
	    cv = getcvec(v, 0, 2, 0);
	    addrange(cv, 0x0, 0x1f);
	    addrange(cv, 0x7f, 0x9f);
	    break;
	case CC_DIGIT:
	    cv = getcvec(v, 0, NUM_DIGIT, 0);
	    if (cv) {	
		for (i = 0; i < NUM_DIGIT; i++) {
		    addrange(cv, digitTable[i].start, digitTable[i].end);
		}
	    }
	    break;
	case CC_PUNCT:
	    cv = getcvec(v, 0, NUM_PUNCT, 0);
	    if (cv) {	
		for (i = 0; i < NUM_PUNCT; i++) {
		    addrange(cv, punctTable[i].start, punctTable[i].end);
		}
	    }
	    break;
	case CC_XDIGIT:
	    cv = getcvec(v, 0, NUM_DIGIT+2, 0);
	    if (cv) {	
		for (i = 0; i < NUM_DIGIT; i++) {
		    addrange(cv, digitTable[i].start, digitTable[i].end);
		}
		addrange(cv, 'a', 'f');
		addrange(cv, 'A', 'F');
	    }
	    break;
	case CC_SPACE:
	    cv = getcvec(v, 0, NUM_SPACE, 0);
	    if (cv) {	
		for (i = 0; i < NUM_SPACE; i++) {
		    addrange(cv, spaceTable[i].start, spaceTable[i].end);
		}
	    }
	    break;
	case CC_LOWER:
	    cv  = getcvec(v, NUM_LOWER_CHAR, NUM_LOWER_RANGE, 0);
	    if (cv) {
		for (i = 0; i < NUM_LOWER_RANGE; i++) {
		    addrange(cv, lowerRangeTable[i].start,
			     lowerRangeTable[i].end);
		}
		for (i = 0; i < NUM_LOWER_CHAR; i++) {
		    addchr(cv, lowerCharTable[i]);
		}
	    }
	    break;
	case CC_UPPER:
	    cv  = getcvec(v, NUM_UPPER_CHAR, NUM_UPPER_RANGE, 0);
	    if (cv) {
		for (i = 0; i < NUM_UPPER_RANGE; i++) {
		    addrange(cv, upperRangeTable[i].start,
			     upperRangeTable[i].end);
		}
		for (i = 0; i < NUM_UPPER_CHAR; i++) {
		    addchr(cv, upperCharTable[i]);
		}
	    }
	    break;
	case CC_GRAPH:
	    cv = getcvec(v, 0, NUM_GRAPH, 0);
	    if (cv) {	
		for (i = 0; i < NUM_GRAPH; i++) {
		    addrange(cv, graphTable[i].start, graphTable[i].end);
		}
	    }
	    break;
    }
    if (cv == NULL) {
	ERR(REG_ESPACE);
    }
    return cv;
}

/*
 - allcases - supply cvec for all case counterparts of a chr (including itself)
 * This is a shortcut, preferably an efficient one, for simple characters;
 * messy cases are done via range().
 ^ static struct cvec *allcases(struct vars *, pchr);
 */
static struct cvec *
allcases(v, pc)
struct vars *v;
pchr pc;
{
	struct cvec *cv;
	chr c = (chr)pc;
	chr lc, uc, tc;

	lc = Tcl_UniCharToLower((chr)c);
	uc = Tcl_UniCharToUpper((chr)c);
	tc = Tcl_UniCharToTitle((chr)c);

	if (tc != uc) {
	    cv = getcvec(v, 3, 0, 0);
	    addchr(cv, tc);
	} else {
	    cv = getcvec(v, 2, 0, 0);
	}
	addchr(cv, lc);
	if (lc != uc) {
	    addchr(cv, uc);
	}
	return cv;
}

/*
 - cmp - chr-substring compare
 * Backrefs need this.  It should preferably be efficient.
 * Note that it does not need to report anything except equal/unequal.
 * Note also that the length is exact, and the comparison should not
 * stop at embedded NULs!
 ^ static int cmp(CONST chr *, CONST chr *, size_t);
 */
static int			/* 0 for equal, nonzero for unequal */
cmp(x, y, len)
CONST chr *x;
CONST chr *y;
size_t len;			/* exact length of comparison */
{
	return memcmp(VS(x), VS(y), len*sizeof(chr));
}

/*
 - casecmp - case-independent chr-substring compare
 * REG_ICASE backrefs need this.  It should preferably be efficient.
 * Note that it does not need to report anything except equal/unequal.
 * Note also that the length is exact, and the comparison should not
 * stop at embedded NULs!
 ^ static int casecmp(CONST chr *, CONST chr *, size_t);
 */
static int			/* 0 for equal, nonzero for unequal */
casecmp(x, y, len)
CONST chr *x;
CONST chr *y;
size_t len;			/* exact length of comparison */
{
	size_t i;
	CONST chr *xp;
	CONST chr *yp;

	for (xp = x, yp = y, i = len; i > 0; i--)
		if (Tcl_UniCharToLower(*xp++) != Tcl_UniCharToLower(*yp++))
			return 1;
	return 0;
}

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

#define	NISERR()	VISERR(nfa->v)
#define	NERR(e)		VERR(nfa->v, (e))


/*
 - newnfa - set up an NFA
 ^ static struct nfa *newnfa(struct vars *, struct colormap *, struct nfa *);
 */
static struct nfa *		/* the NFA, or NULL */
newnfa(v, cm, parent)
struct vars *v;
struct colormap *cm;
struct nfa *parent;		/* NULL if primary NFA */
{
	struct nfa *nfa;

	nfa = (struct nfa *)MALLOC(sizeof(struct nfa));
	if (nfa == NULL)
		return NULL;

	nfa->states = NULL;
	nfa->slast = NULL;
	nfa->free = NULL;
	nfa->nstates = 0;
	nfa->cm = cm;
	nfa->v = v;
	nfa->bos[0] = nfa->bos[1] = COLORLESS;
	nfa->eos[0] = nfa->eos[1] = COLORLESS;
	nfa->post = newfstate(nfa, '@');	/* number 0 */
	nfa->pre = newfstate(nfa, '>');		/* number 1 */
	nfa->parent = parent;

	nfa->init = newstate(nfa);		/* may become invalid later */
	nfa->final = newstate(nfa);
	if (ISERR()) {
		freenfa(nfa);
		return NULL;
	}
	rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->pre, nfa->init);
	newarc(nfa, '^', 1, nfa->pre, nfa->init);
	newarc(nfa, '^', 0, nfa->pre, nfa->init);
	rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->final, nfa->post);
	newarc(nfa, '$', 1, nfa->final, nfa->post);
	newarc(nfa, '$', 0, nfa->final, nfa->post);

	if (ISERR()) {
		freenfa(nfa);
		return NULL;
	}
	return nfa;
}

/*
 - freenfa - free an entire NFA
 ^ static VOID freenfa(struct nfa *);
 */
static VOID
freenfa(nfa)
struct nfa *nfa;
{
	struct state *s;

	while ((s = nfa->states) != NULL) {
		s->nins = s->nouts = 0;		/* don't worry about arcs */
		freestate(nfa, s);
	}
	while ((s = nfa->free) != NULL) {
		nfa->free = s->next;
		destroystate(nfa, s);
	}

	nfa->slast = NULL;
	nfa->nstates = -1;
	nfa->pre = NULL;
	nfa->post = NULL;
	FREE(nfa);
}

/*
 - newfstate - allocate an NFA state, with specified flag value
 ^ static struct state *newfstate(struct nfa *, int flag);
 */
static struct state *		/* NULL on error */
newfstate(nfa, flag)
struct nfa *nfa;
int flag;
{
	struct state *s;
	int i;

	if (nfa->free != NULL) {
		s = nfa->free;
		nfa->free = s->next;
	} else {
		s = (struct state *)MALLOC(sizeof(struct state));
		if (s == NULL) {
			NERR(REG_ESPACE);
			return NULL;
		}
		s->oas.next = NULL;
		s->free = &s->oas.a[0];
		for (i = 0; i < ABSIZE; i++) {
			s->oas.a[i].type = 0;
			s->oas.a[i].freechain = &s->oas.a[i+1];
		}
		s->oas.a[ABSIZE-1].freechain = NULL;
	}

	assert(nfa->nstates >= 0);
	s->no = nfa->nstates++;
	s->flag = (char)flag;
	if (nfa->states == NULL)
		nfa->states = s;
	s->nins = 0;
	s->ins = NULL;
	s->nouts = 0;
	s->outs = NULL;
	s->tmp = NULL;
	s->next = NULL;
	if (nfa->slast != NULL) {
		assert(nfa->slast->next == NULL);
		nfa->slast->next = s;
	}
	s->prev = nfa->slast;
	nfa->slast = s;
	return s;
}

/*
 - newstate - allocate an ordinary NFA state
 ^ static struct state *newstate(struct nfa *);
 */
static struct state *		/* NULL on error */
newstate(nfa)
struct nfa *nfa;
{
	return newfstate(nfa, 0);
}

/*
 - dropstate - delete a state's inarcs and outarcs and free it
 ^ static VOID dropstate(struct nfa *, struct state *);
 */
static VOID
dropstate(nfa, s)
struct nfa *nfa;
struct state *s;
{
	struct arc *a;

	while ((a = s->ins) != NULL)
		freearc(nfa, a);
	while ((a = s->outs) != NULL)
		freearc(nfa, a);
	freestate(nfa, s);
}

/*
 - freestate - free a state, which has no in-arcs or out-arcs
 ^ static VOID freestate(struct nfa *, struct state *);
 */
static VOID
freestate(nfa, s)
struct nfa *nfa;
struct state *s;
{
	assert(s != NULL);
	assert(s->nins == 0 && s->nouts == 0);

	s->no = FREESTATE;
	s->flag = 0;
	if (s->next != NULL)
		s->next->prev = s->prev;
	else {
		assert(s == nfa->slast);
		nfa->slast = s->prev;
	}
	if (s->prev != NULL)
		s->prev->next = s->next;
	else {
		assert(s == nfa->states);
		nfa->states = s->next;
	}
	s->prev = NULL;
	s->next = nfa->free;	/* don't delete it, put it on the free list */
	nfa->free = s;
}

/*
 - destroystate - really get rid of an already-freed state
 ^ static VOID destroystate(struct nfa *, struct state *);
 */
static VOID
destroystate(nfa, s)
struct nfa *nfa;
struct state *s;
{
	struct arcbatch *ab;
	struct arcbatch *abnext;

	assert(s->no == FREESTATE);
	for (ab = s->oas.next; ab != NULL; ab = abnext) {
		abnext = ab->next;
		FREE(ab);
	}
	s->ins = NULL;
	s->outs = NULL;
	s->next = NULL;
	FREE(s);
}

/*
 - newarc - set up a new arc within an NFA
 ^ static VOID newarc(struct nfa *, int, pcolor, struct state *, 
 ^	struct state *);
 */
static VOID
newarc(nfa, t, co, from, to)
struct nfa *nfa;
int t;
pcolor co;
struct state *from;
struct state *to;
{
	struct arc *a;

	assert(from != NULL && to != NULL);

	/* check for duplicates */
	for (a = from->outs; a != NULL; a = a->outchain)
		if (a->type == t && a->co == co && a->to == to)
			return;

	a = allocarc(nfa, from);
	if (NISERR())
		return;
	assert(a != NULL);

	a->type = t;
	a->co = (color)co;
	a->to = to;
	a->from = from;

	/*
	 * Put the new arc on the beginning, not the end, of the chains.
	 * Not only is this easier, it has the very useful side effect that 
	 * deleting the most-recently-added arc is the cheapest case rather
	 * than the most expensive one.
	 */
	a->inchain = to->ins;
	to->ins = a;
	a->outchain = from->outs;
	from->outs = a;

	from->nouts++;
	to->nins++;

	if (COLORED(a) && nfa->parent == NULL)
		colorchain(nfa->cm, a);

	return;
}

/*
 - allocarc - allocate a new out-arc within a state
 ^ static struct arc *allocarc(struct nfa *, struct state *);
 */
static struct arc *		/* NULL for failure */
allocarc(nfa, s)
struct nfa *nfa;
struct state *s;
{
	struct arc *a;
	struct arcbatch *new;
	int i;

	/* if none at hand, get more */
	if (s->free == NULL) {
		new = (struct arcbatch *)MALLOC(sizeof(struct arcbatch));
		if (new == NULL) {
			NERR(REG_ESPACE);
			return NULL;
		}
		new->next = s->oas.next;
		s->oas.next = new;

		for (i = 0; i < ABSIZE; i++) {
			new->a[i].type = 0;
			new->a[i].freechain = &new->a[i+1];
		}
		new->a[ABSIZE-1].freechain = NULL;
		s->free = &new->a[0];
	}
	assert(s->free != NULL);

	a = s->free;
	s->free = a->freechain;
	return a;
}

/*
 - freearc - free an arc
 ^ static VOID freearc(struct nfa *, struct arc *);
 */
static VOID
freearc(nfa, victim)
struct nfa *nfa;
struct arc *victim;
{
	struct state *from = victim->from;
	struct state *to = victim->to;
	struct arc *a;

	assert(victim->type != 0);

	/* take it off color chain if necessary */
	if (COLORED(victim) && nfa->parent == NULL)
		uncolorchain(nfa->cm, victim);

	/* take it off source's out-chain */
	assert(from != NULL);
	assert(from->outs != NULL);
	a = from->outs;
	if (a == victim)		/* simple case:  first in chain */
		from->outs = victim->outchain;
	else {
		for (; a != NULL && a->outchain != victim; a = a->outchain)
			continue;
		assert(a != NULL);
		a->outchain = victim->outchain;
	}
	from->nouts--;

	/* take it off target's in-chain */
	assert(to != NULL);
	assert(to->ins != NULL);
	a = to->ins;
	if (a == victim)		/* simple case:  first in chain */
		to->ins = victim->inchain;
	else {
		for (; a != NULL && a->inchain != victim; a = a->inchain)
			continue;
		assert(a != NULL);
		a->inchain = victim->inchain;
	}
	to->nins--;

	/* clean up and place on free list */
	victim->type = 0;
	victim->from = NULL;		/* precautions... */
	victim->to = NULL;
	victim->inchain = NULL;
	victim->outchain = NULL;
	victim->freechain = from->free;
	from->free = victim;
}

/*
 - findarc - find arc, if any, from given source with given type and color
 * If there is more than one such arc, the result is random.
 ^ static struct arc *findarc(struct state *, int, pcolor);
 */
static struct arc *
findarc(s, type, co)
struct state *s;
int type;
pcolor co;
{
	struct arc *a;

	for (a = s->outs; a != NULL; a = a->outchain)
		if (a->type == type && a->co == co)
			return a;
	return NULL;
}

/*
 - cparc - allocate a new arc within an NFA, copying details from old one
 ^ static VOID cparc(struct nfa *, struct arc *, struct state *, 
 ^ 	struct state *);
 */
static VOID
cparc(nfa, oa, from, to)
struct nfa *nfa;
struct arc *oa;
struct state *from;
struct state *to;
{
	newarc(nfa, oa->type, oa->co, from, to);
}

/*
 - moveins - move all in arcs of a state to another state
 * You might think this could be done better by just updating the
 * existing arcs, and you would be right if it weren't for the desire
 * for duplicate suppression, which makes it easier to just make new
 * ones to exploit the suppression built into newarc.
 ^ static VOID moveins(struct nfa *, struct state *, struct state *);
 */
static VOID
moveins(nfa, old, new)
struct nfa *nfa;
struct state *old;
struct state *new;
{
	struct arc *a;

	assert(old != new);

	while ((a = old->ins) != NULL) {
		cparc(nfa, a, a->from, new);
		freearc(nfa, a);
	}
	assert(old->nins == 0);
	assert(old->ins == NULL);
}

/*
 - copyins - copy all in arcs of a state to another state
 ^ static VOID copyins(struct nfa *, struct state *, struct state *);
 */
static VOID
copyins(nfa, old, new)
struct nfa *nfa;
struct state *old;
struct state *new;
{
	struct arc *a;

	assert(old != new);

	for (a = old->ins; a != NULL; a = a->inchain)
		cparc(nfa, a, a->from, new);
}

/*
 - moveouts - move all out arcs of a state to another state
 ^ static VOID moveouts(struct nfa *, struct state *, struct state *);
 */
static VOID
moveouts(nfa, old, new)
struct nfa *nfa;
struct state *old;
struct state *new;
{
	struct arc *a;

	assert(old != new);

	while ((a = old->outs) != NULL) {
		cparc(nfa, a, new, a->to);
		freearc(nfa, a);
	}
}

/*
 - copyouts - copy all out arcs of a state to another state
 ^ static VOID copyouts(struct nfa *, struct state *, struct state *);
 */
static VOID
copyouts(nfa, old, new)
struct nfa *nfa;
struct state *old;
struct state *new;
{
	struct arc *a;

	assert(old != new);

	for (a = old->outs; a != NULL; a = a->outchain)
		cparc(nfa, a, new, a->to);
}

/*
 - cloneouts - copy out arcs of a state to another state pair, modifying type
 ^ static VOID cloneouts(struct nfa *, struct state *, struct state *,
 ^ 	struct state *, int);
 */
static VOID
cloneouts(nfa, old, from, to, type)
struct nfa *nfa;
struct state *old;
struct state *from;
struct state *to;
int type;
{
	struct arc *a;

	assert(old != from);

	for (a = old->outs; a != NULL; a = a->outchain)
		newarc(nfa, type, a->co, from, to);
}

/*
 - delsub - delete a sub-NFA, updating subre pointers if necessary
 * This uses a recursive traversal of the sub-NFA, marking already-seen
 * states using their tmp pointer.
 ^ static VOID delsub(struct nfa *, struct state *, struct state *);
 */
static VOID
delsub(nfa, lp, rp)
struct nfa *nfa;
struct state *lp;	/* the sub-NFA goes from here... */
struct state *rp;	/* ...to here, *not* inclusive */
{
	assert(lp != rp);

	rp->tmp = rp;			/* mark end */

	deltraverse(nfa, lp, lp);
	assert(lp->nouts == 0 && rp->nins == 0);	/* did the job */
	assert(lp->no != FREESTATE && rp->no != FREESTATE);	/* no more */

	rp->tmp = NULL;			/* unmark end */
	lp->tmp = NULL;			/* and begin, marked by deltraverse */
}

/*
 - deltraverse - the recursive heart of delsub
 * This routine's basic job is to destroy all out-arcs of the state.
 ^ static VOID deltraverse(struct nfa *, struct state *, struct state *);
 */
static VOID
deltraverse(nfa, leftend, s)
struct nfa *nfa;
struct state *leftend;
struct state *s;
{
	struct arc *a;
	struct state *to;

	if (s->nouts == 0)
		return;			/* nothing to do */
	if (s->tmp != NULL)
		return;			/* already in progress */

	s->tmp = s;			/* mark as in progress */

	while ((a = s->outs) != NULL) {
		to = a->to;
		deltraverse(nfa, leftend, to);
		assert(to->nouts == 0 || to->tmp != NULL);
		freearc(nfa, a);
		if (to->nins == 0 && to->tmp == NULL) {
			assert(to->nouts == 0);
			freestate(nfa, to);
		}
	}

	assert(s->no != FREESTATE);	/* we're still here */
	assert(s == leftend || s->nins != 0);	/* and still reachable */
	assert(s->nouts == 0);		/* but have no outarcs */

	s->tmp = NULL;			/* we're done here */
}

/*
 - dupnfa - duplicate sub-NFA
 * Another recursive traversal, this time using tmp to point to duplicates
 * as well as mark already-seen states.  (You knew there was a reason why
 * it's a state pointer, didn't you? :-))
 ^ static VOID dupnfa(struct nfa *, struct state *, struct state *, 
 ^ 	struct state *, struct state *);
 */
static VOID
dupnfa(nfa, start, stop, from, to)
struct nfa *nfa;
struct state *start;		/* duplicate of subNFA starting here */
struct state *stop;		/* and stopping here */
struct state *from;		/* stringing duplicate from here */
struct state *to;		/* to here */
{
	if (start == stop) {
		newarc(nfa, EMPTY, 0, from, to);
		return;
	}

	stop->tmp = to;
	duptraverse(nfa, start, from);
	/* done, except for clearing out the tmp pointers */

	stop->tmp = NULL;
	cleartraverse(nfa, start);
}

/*
 - duptraverse - recursive heart of dupnfa
 ^ static VOID duptraverse(struct nfa *, struct state *, struct state *);
 */
static VOID
duptraverse(nfa, s, stmp)
struct nfa *nfa;
struct state *s;
struct state *stmp;		/* s's duplicate, or NULL */
{
	struct arc *a;

	if (s->tmp != NULL)
		return;		/* already done */

	s->tmp = (stmp == NULL) ? newstate(nfa) : stmp;
	if (s->tmp == NULL) {
		assert(NISERR());
		return;
	}

	for (a = s->outs; a != NULL && !NISERR(); a = a->outchain) {
		duptraverse(nfa, a->to, (struct state *)NULL);
		assert(a->to->tmp != NULL);
		cparc(nfa, a, s->tmp, a->to->tmp);
	}
}

/*
 - cleartraverse - recursive cleanup for algorithms that leave tmp ptrs set
 ^ static VOID cleartraverse(struct nfa *, struct state *);
 */
static VOID
cleartraverse(nfa, s)
struct nfa *nfa;
struct state *s;
{
	struct arc *a;

	if (s->tmp == NULL)
		return;
	s->tmp = NULL;

	for (a = s->outs; a != NULL; a = a->outchain)
		cleartraverse(nfa, a->to);
}

/*
 - specialcolors - fill in special colors for an NFA
 ^ static VOID specialcolors(struct nfa *);
 */
static VOID
specialcolors(nfa)
struct nfa *nfa;
{
	/* false colors for BOS, BOL, EOS, EOL */
	if (nfa->parent == NULL) {
		nfa->bos[0] = pseudocolor(nfa->cm);
		nfa->bos[1] = pseudocolor(nfa->cm);
		nfa->eos[0] = pseudocolor(nfa->cm);
		nfa->eos[1] = pseudocolor(nfa->cm);
	} else {
		assert(nfa->parent->bos[0] != COLORLESS);
		nfa->bos[0] = nfa->parent->bos[0];
		assert(nfa->parent->bos[1] != COLORLESS);
		nfa->bos[1] = nfa->parent->bos[1];
		assert(nfa->parent->eos[0] != COLORLESS);
		nfa->eos[0] = nfa->parent->eos[0];
		assert(nfa->parent->eos[1] != COLORLESS);
		nfa->eos[1] = nfa->parent->eos[1];
	}
}

/*
 - optimize - optimize an NFA
 ^ static int optimize(struct nfa *, FILE *);
 */
static int			/* re_info bits */
optimize(nfa, f)
struct nfa *nfa;
FILE *f;			/* for debug output; NULL none */
{
	int verbose = (f != NULL) ? 1 : 0;

	if (verbose)
		fprintf(f, "\ninitial cleanup:\n");
	cleanup(nfa);		/* may simplify situation */
	if (verbose)
		dumpnfa(nfa, f);
	if (verbose)
		fprintf(f, "\nempties:\n");
	fixempties(nfa, f);	/* get rid of EMPTY arcs */
	if (verbose)
		fprintf(f, "\nconstraints:\n");
	pullback(nfa, f);	/* pull back constraints backward */
	pushfwd(nfa, f);	/* push fwd constraints forward */
	if (verbose)
		fprintf(f, "\nfinal cleanup:\n");
	cleanup(nfa);		/* final tidying */
	return analyze(nfa);	/* and analysis */
}

/*
 - pullback - pull back constraints backward to (with luck) eliminate them
 ^ static VOID pullback(struct nfa *, FILE *);
 */
static VOID
pullback(nfa, f)
struct nfa *nfa;
FILE *f;			/* for debug output; NULL none */
{
	struct state *s;
	struct state *nexts;
	struct arc *a;
	struct arc *nexta;
	int progress;

	/* find and pull until there are no more */
	do {
		progress = 0;
		for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
			nexts = s->next;
			for (a = s->outs; a != NULL && !NISERR(); a = nexta) {
				nexta = a->outchain;
				if (a->type == '^' || a->type == BEHIND)
					if (pull(nfa, a))
						progress = 1;
				assert(nexta == NULL || s->no != FREESTATE);
			}
		}
		if (progress && f != NULL)
			dumpnfa(nfa, f);
	} while (progress && !NISERR());
	if (NISERR())
		return;

	for (a = nfa->pre->outs; a != NULL; a = nexta) {
		nexta = a->outchain;
		if (a->type == '^') {
			assert(a->co == 0 || a->co == 1);
			newarc(nfa, PLAIN, nfa->bos[a->co], a->from, a->to);
			freearc(nfa, a);
		}
	}
}

/*
 - pull - pull a back constraint backward past its source state
 * A significant property of this function is that it deletes at most
 * one state -- the constraint's from state -- and only if the constraint
 * was that state's last outarc.
 ^ static int pull(struct nfa *, struct arc *);
 */
static int			/* 0 couldn't, 1 could */
pull(nfa, con)
struct nfa *nfa;
struct arc *con;
{
	struct state *from = con->from;
	struct state *to = con->to;
	struct arc *a;
	struct arc *nexta;
	struct state *s;

	if (from == to) {	/* circular constraint is pointless */
		freearc(nfa, con);
		return 1;
	}
	if (from->flag)		/* can't pull back beyond start */
		return 0;
	if (from->nins == 0) {	/* unreachable */
		freearc(nfa, con);
		return 1;
	}

	/* first, clone from state if necessary to avoid other outarcs */
	if (from->nouts > 1) {
		s = newstate(nfa);
		if (NISERR())
			return 0;
		assert(to != from);		/* con is not an inarc */
		copyins(nfa, from, s);		/* duplicate inarcs */
		cparc(nfa, con, s, to);		/* move constraint arc */
		freearc(nfa, con);
		from = s;
		con = from->outs;
	}
	assert(from->nouts == 1);

	/* propagate the constraint into the from state's inarcs */
	for (a = from->ins; a != NULL; a = nexta) {
		nexta = a->inchain;
		switch (combine(con, a)) {
		case INCOMPATIBLE:	/* destroy the arc */
			freearc(nfa, a);
			break;
		case SATISFIED:		/* no action needed */
			break;
		case COMPATIBLE:	/* swap the two arcs, more or less */
			s = newstate(nfa);
			if (NISERR())
				return 0;
			cparc(nfa, a, s, to);		/* anticipate move */
			cparc(nfa, con, a->from, s);
			if (NISERR())
				return 0;
			freearc(nfa, a);
			break;
		default:
			assert(NOTREACHED);
			break;
		}
	}

	/* remaining inarcs, if any, incorporate the constraint */
	moveins(nfa, from, to);
	dropstate(nfa, from);		/* will free the constraint */
	return 1;
}

/*
 - pushfwd - push forward constraints forward to (with luck) eliminate them
 ^ static VOID pushfwd(struct nfa *, FILE *);
 */
static VOID
pushfwd(nfa, f)
struct nfa *nfa;
FILE *f;			/* for debug output; NULL none */
{
	struct state *s;
	struct state *nexts;
	struct arc *a;
	struct arc *nexta;
	int progress;

	/* find and push until there are no more */
	do {
		progress = 0;
		for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
			nexts = s->next;
			for (a = s->ins; a != NULL && !NISERR(); a = nexta) {
				nexta = a->inchain;
				if (a->type == '$' || a->type == AHEAD)
					if (push(nfa, a))
						progress = 1;
				assert(nexta == NULL || s->no != FREESTATE);
			}
		}
		if (progress && f != NULL)
			dumpnfa(nfa, f);
	} while (progress && !NISERR());
	if (NISERR())
		return;

	for (a = nfa->post->ins; a != NULL; a = nexta) {
		nexta = a->inchain;
		if (a->type == '$') {
			assert(a->co == 0 || a->co == 1);
			newarc(nfa, PLAIN, nfa->eos[a->co], a->from, a->to);
			freearc(nfa, a);
		}
	}
}

/*
 - push - push a forward constraint forward past its destination state
 * A significant property of this function is that it deletes at most
 * one state -- the constraint's to state -- and only if the constraint
 * was that state's last inarc.
 ^ static int push(struct nfa *, struct arc *);
 */
static int			/* 0 couldn't, 1 could */
push(nfa, con)
struct nfa *nfa;
struct arc *con;
{
	struct state *from = con->from;
	struct state *to = con->to;
	struct arc *a;
	struct arc *nexta;
	struct state *s;

	if (to == from) {	/* circular constraint is pointless */
		freearc(nfa, con);
		return 1;
	}
	if (to->flag)		/* can't push forward beyond end */
		return 0;
	if (to->nouts == 0) {	/* dead end */
		freearc(nfa, con);
		return 1;
	}

	/* first, clone to state if necessary to avoid other inarcs */
	if (to->nins > 1) {
		s = newstate(nfa);
		if (NISERR())
			return 0;
		copyouts(nfa, to, s);		/* duplicate outarcs */
		cparc(nfa, con, from, s);	/* move constraint */
		freearc(nfa, con);
		to = s;
		con = to->ins;
	}
	assert(to->nins == 1);

	/* propagate the constraint into the to state's outarcs */
	for (a = to->outs; a != NULL; a = nexta) {
		nexta = a->outchain;
		switch (combine(con, a)) {
		case INCOMPATIBLE:	/* destroy the arc */
			freearc(nfa, a);
			break;
		case SATISFIED:		/* no action needed */
			break;
		case COMPATIBLE:	/* swap the two arcs, more or less */
			s = newstate(nfa);
			if (NISERR())
				return 0;
			cparc(nfa, con, s, a->to);	/* anticipate move */
			cparc(nfa, a, from, s);
			if (NISERR())
				return 0;
			freearc(nfa, a);
			break;
		default:
			assert(NOTREACHED);
			break;
		}
	}

	/* remaining outarcs, if any, incorporate the constraint */
	moveouts(nfa, to, from);
	dropstate(nfa, to);		/* will free the constraint */
	return 1;
}

/*
 - combine - constraint lands on an arc, what happens?
 ^ #def	INCOMPATIBLE	1	// destroys arc
 ^ #def	SATISFIED	2	// constraint satisfied
 ^ #def	COMPATIBLE	3	// compatible but not satisfied yet
 ^ static int combine(struct arc *, struct arc *);
 */
static int
combine(con, a)
struct arc *con;
struct arc *a;
{
#	define	CA(ct,at)	(((ct)<<CHAR_BIT) | (at))

	switch (CA(con->type, a->type)) {
	case CA('^', PLAIN):		/* newlines are handled separately */
	case CA('$', PLAIN):
		return INCOMPATIBLE;
		break;
	case CA(AHEAD, PLAIN):		/* color constraints meet colors */
	case CA(BEHIND, PLAIN):
		if (con->co == a->co)
			return SATISFIED;
		return INCOMPATIBLE;
		break;
	case CA('^', '^'):		/* collision, similar constraints */
	case CA('$', '$'):
	case CA(AHEAD, AHEAD):
	case CA(BEHIND, BEHIND):
		if (con->co == a->co)		/* true duplication */
			return SATISFIED;
		return INCOMPATIBLE;
		break;
	case CA('^', BEHIND):		/* collision, dissimilar constraints */
	case CA(BEHIND, '^'):
	case CA('$', AHEAD):
	case CA(AHEAD, '$'):
		return INCOMPATIBLE;
		break;
	case CA('^', '$'):		/* constraints passing each other */
	case CA('^', AHEAD):
	case CA(BEHIND, '$'):
	case CA(BEHIND, AHEAD):
	case CA('$', '^'):
	case CA('$', BEHIND):
	case CA(AHEAD, '^'):
	case CA(AHEAD, BEHIND):
	case CA('^', LACON):
	case CA(BEHIND, LACON):
	case CA('$', LACON):
	case CA(AHEAD, LACON):
		return COMPATIBLE;
		break;
	}
	assert(NOTREACHED);
	return INCOMPATIBLE;		/* for benefit of blind compilers */
}

/*
 - fixempties - get rid of EMPTY arcs
 ^ static VOID fixempties(struct nfa *, FILE *);
 */
static VOID
fixempties(nfa, f)
struct nfa *nfa;
FILE *f;			/* for debug output; NULL none */
{
	struct state *s;
	struct state *nexts;
	struct arc *a;
	struct arc *nexta;
	int progress;

	/* find and eliminate empties until there are no more */
	do {
		progress = 0;
		for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
			nexts = s->next;
			for (a = s->outs; a != NULL && !NISERR(); a = nexta) {
				nexta = a->outchain;
				if (a->type == EMPTY && unempty(nfa, a))
					progress = 1;
				assert(nexta == NULL || s->no != FREESTATE);
			}
		}
		if (progress && f != NULL)
			dumpnfa(nfa, f);
	} while (progress && !NISERR());
}

/*
 - unempty - optimize out an EMPTY arc, if possible
 * Actually, as it stands this function always succeeds, but the return
 * value is kept with an eye on possible future changes.
 ^ static int unempty(struct nfa *, struct arc *);
 */
static int			/* 0 couldn't, 1 could */
unempty(nfa, a)
struct nfa *nfa;
struct arc *a;
{
	struct state *from = a->from;
	struct state *to = a->to;
	int usefrom;		/* work on from, as opposed to to? */

	assert(a->type == EMPTY);
	assert(from != nfa->pre && to != nfa->post);

	if (from == to) {		/* vacuous loop */
		freearc(nfa, a);
		return 1;
	}

	/* decide which end to work on */
	usefrom = 1;			/* default:  attack from */
	if (from->nouts > to->nins)
		usefrom = 0;
	else if (from->nouts == to->nins) {
		/* decide on secondary issue:  move/copy fewest arcs */
		if (from->nins > to->nouts)
			usefrom = 0;
	}
		
	freearc(nfa, a);
	if (usefrom) {
		if (from->nouts == 0) {
			/* was the state's only outarc */
			moveins(nfa, from, to);
			freestate(nfa, from);
		} else
			copyins(nfa, from, to);
	} else {
		if (to->nins == 0) {
			/* was the state's only inarc */
			moveouts(nfa, to, from);
			freestate(nfa, to);
		} else
			copyouts(nfa, to, from);
	}

	return 1;
}

/*
 - cleanup - clean up NFA after optimizations
 ^ static VOID cleanup(struct nfa *);
 */
static VOID
cleanup(nfa)
struct nfa *nfa;
{
	struct state *s;
	struct state *nexts;
	int n;

	/* clear out unreachable or dead-end states */
	/* use pre to mark reachable, then post to mark can-reach-post */
	markreachable(nfa, nfa->pre, (struct state *)NULL, nfa->pre);
	markcanreach(nfa, nfa->post, nfa->pre, nfa->post);
	for (s = nfa->states; s != NULL; s = nexts) {
		nexts = s->next;
		if (s->tmp != nfa->post && !s->flag)
			dropstate(nfa, s);
	}
	assert(nfa->post->nins == 0 || nfa->post->tmp == nfa->post);
	cleartraverse(nfa, nfa->pre);
	assert(nfa->post->nins == 0 || nfa->post->tmp == NULL);
	/* the nins==0 (final unreachable) case will be caught later */

	/* renumber surviving states */
	n = 0;
	for (s = nfa->states; s != NULL; s = s->next)
		s->no = n++;
	nfa->nstates = n;
}

/*
 - markreachable - recursive marking of reachable states
 ^ static VOID markreachable(struct nfa *, struct state *, struct state *,
 ^ 	struct state *);
 */
static VOID
markreachable(nfa, s, okay, mark)
struct nfa *nfa;
struct state *s;
struct state *okay;		/* consider only states with this mark */
struct state *mark;		/* the value to mark with */
{
	struct arc *a;

	if (s->tmp != okay)
		return;
	s->tmp = mark;

	for (a = s->outs; a != NULL; a = a->outchain)
		markreachable(nfa, a->to, okay, mark);
}

/*
 - markcanreach - recursive marking of states which can reach here
 ^ static VOID markcanreach(struct nfa *, struct state *, struct state *,
 ^ 	struct state *);
 */
static VOID
markcanreach(nfa, s, okay, mark)
struct nfa *nfa;
struct state *s;
struct state *okay;		/* consider only states with this mark */
struct state *mark;		/* the value to mark with */
{
	struct arc *a;

	if (s->tmp != okay)
		return;
	s->tmp = mark;

	for (a = s->ins; a != NULL; a = a->inchain)
		markcanreach(nfa, a->from, okay, mark);
}

/*
 - analyze - ascertain potentially-useful facts about an optimized NFA
 ^ static int analyze(struct nfa *);
 */
static int			/* re_info bits to be ORed in */
analyze(nfa)
struct nfa *nfa;
{
	struct arc *a;
	struct arc *aa;

	if (nfa->pre->outs == NULL)
		return REG_UIMPOSSIBLE;
	for (a = nfa->pre->outs; a != NULL; a = a->outchain)
		for (aa = a->to->outs; aa != NULL; aa = aa->outchain)
			if (aa->to == nfa->post)
				return REG_UEMPTYMATCH;
	return 0;
}

/*
 - compact - compact an NFA
 ^ static VOID compact(struct nfa *, struct cnfa *);
 */
static VOID
compact(nfa, cnfa)
struct nfa *nfa;
struct cnfa *cnfa;
{
	struct state *s;
	struct arc *a;
	size_t nstates;
	size_t narcs;
	struct carc *ca;
	struct carc *first;

	assert (!NISERR());

	nstates = 0;
	narcs = 0;
	for (s = nfa->states; s != NULL; s = s->next) {
		nstates++;
		narcs += 1 + s->nouts + 1;
		/* 1 as a fake for flags, nouts for arcs, 1 as endmarker */
	}

	cnfa->states = (struct carc **)MALLOC(nstates * sizeof(struct carc *));
	cnfa->arcs = (struct carc *)MALLOC(narcs * sizeof(struct carc));
	if (cnfa->states == NULL || cnfa->arcs == NULL) {
		if (cnfa->states != NULL)
			FREE(cnfa->states);
		if (cnfa->arcs != NULL)
			FREE(cnfa->arcs);
		NERR(REG_ESPACE);
		return;
	}
	cnfa->nstates = nstates;
	cnfa->pre = nfa->pre->no;
	cnfa->post = nfa->post->no;
	cnfa->bos[0] = nfa->bos[0];
	cnfa->bos[1] = nfa->bos[1];
	cnfa->eos[0] = nfa->eos[0];
	cnfa->eos[1] = nfa->eos[1];
	cnfa->ncolors = maxcolor(nfa->cm) + 1;
	cnfa->flags = 0;

	ca = cnfa->arcs;
	for (s = nfa->states; s != NULL; s = s->next) {
		assert((size_t)s->no < nstates);
		cnfa->states[s->no] = ca;
		ca->co = 0;		/* clear and skip flags "arc" */
		ca++;
		first = ca;
		for (a = s->outs; a != NULL; a = a->outchain)
			switch (a->type) {
			case PLAIN:
				ca->co = a->co;
				ca->to = a->to->no;
				ca++;
				break;
			case LACON:
				assert(s->no != cnfa->pre);
				ca->co = (color)(cnfa->ncolors + a->co);
				ca->to = a->to->no;
				ca++;
				cnfa->flags |= HASLACONS;
				break;
			default:
				assert(NOTREACHED);
				break;
			}
		carcsort(first, ca-1);
		ca->co = COLORLESS;
		ca->to = 0;
		ca++;
	}
	assert(ca == &cnfa->arcs[narcs]);
	assert(cnfa->nstates != 0);

	/* mark no-progress states */
	for (a = nfa->pre->outs; a != NULL; a = a->outchain)
		cnfa->states[a->to->no]->co = 1;
	cnfa->states[nfa->pre->no]->co = 1;
}

/*
 - carcsort - sort compacted-NFA arcs by color
 * Really dumb algorithm, but if the list is long enough for that to matter,
 * you're in real trouble anyway.
 ^ static VOID carcsort(struct carc *, struct carc *);
 */
static VOID
carcsort(first, last)
struct carc *first;
struct carc *last;
{
	struct carc *p;
	struct carc *q;
	struct carc tmp;

	if (last - first <= 1)
		return;

	for (p = first; p <= last; p++)
		for (q = p; q <= last; q++)
			if (p->co > q->co ||
					(p->co == q->co && p->to > q->to)) {
				assert(p != q);
				tmp = *p;
				*p = *q;
				*q = tmp;
			}
}

/*
 - freecnfa - free a compacted NFA
 ^ static VOID freecnfa(struct cnfa *);
 */
static VOID
freecnfa(cnfa)
struct cnfa *cnfa;
{
	assert(cnfa->nstates != 0);	/* not empty already */
	cnfa->nstates = 0;
	FREE(cnfa->states);
	FREE(cnfa->arcs);
}

/*
 - dumpnfa - dump an NFA in human-readable form
 ^ static VOID dumpnfa(struct nfa *, FILE *);
 */
static VOID
dumpnfa(nfa, f)
struct nfa *nfa;
FILE *f;
{
#ifdef REG_DEBUG
	struct state *s;

	fprintf(f, "pre %d, post %d", nfa->pre->no, nfa->post->no);
	if (nfa->bos[0] != COLORLESS)
		fprintf(f, ", bos [%ld]", (long)nfa->bos[0]);
	if (nfa->bos[1] != COLORLESS)
		fprintf(f, ", bol [%ld]", (long)nfa->bos[1]);
	if (nfa->eos[0] != COLORLESS)
		fprintf(f, ", eos [%ld]", (long)nfa->eos[0]);
	if (nfa->eos[1] != COLORLESS)
		fprintf(f, ", eol [%ld]", (long)nfa->eos[1]);
	fprintf(f, "\n");
	for (s = nfa->states; s != NULL; s = s->next)
		dumpstate(s, f);
	if (nfa->parent == NULL)
		dumpcolors(nfa->cm, f);
	fflush(f);
#endif
}

#ifdef REG_DEBUG		/* subordinates of dumpnfa */

/*
 - dumpstate - dump an NFA state in human-readable form
 ^ static VOID dumpstate(struct state *, FILE *);
 */
static VOID
dumpstate(s, f)
struct state *s;
FILE *f;
{
	struct arc *a;

	fprintf(f, "%d%s%c", s->no, (s->tmp != NULL) ? "T" : "",
					(s->flag) ? s->flag : '.');
	if (s->prev != NULL && s->prev->next != s)
		fprintf(f, "\tstate chain bad\n");
	if (s->nouts == 0)
		fprintf(f, "\tno out arcs\n");
	else
		dumparcs(s, f);
	fflush(f);
	for (a = s->ins; a != NULL; a = a->inchain) {
		if (a->to != s)
			fprintf(f, "\tlink from %d to %d on %d's in-chain\n",
					a->from->no, a->to->no, s->no);
	}
}

/*
 - dumparcs - dump out-arcs in human-readable form
 ^ static VOID dumparcs(struct state *, FILE *);
 */
static VOID
dumparcs(s, f)
struct state *s;
FILE *f;
{
	int pos;

	assert(s->nouts > 0);
	/* printing arcs in reverse order is usually clearer */
	pos = dumprarcs(s->outs, s, f, 1);
	if (pos != 1)
		fprintf(f, "\n");
}

/*
 - dumprarcs - dump remaining outarcs, recursively, in reverse order
 ^ static int dumprarcs(struct arc *, struct state *, FILE *, int);
 */
static int			/* resulting print position */
dumprarcs(a, s, f, pos)
struct arc *a;
struct state *s;
FILE *f;
int pos;			/* initial print position */
{
	if (a->outchain != NULL)
		pos = dumprarcs(a->outchain, s, f, pos);
	dumparc(a, s, f);
	if (pos == 5) {
		fprintf(f, "\n");
		pos = 1;
	} else
		pos++;
	return pos;
}

/*
 - dumparc - dump one outarc in readable form, including prefixing tab
 ^ static VOID dumparc(struct arc *, struct state *, FILE *);
 */
static VOID
dumparc(a, s, f)
struct arc *a;
struct state *s;
FILE *f;
{
	struct arc *aa;
	struct arcbatch *ab;

	fprintf(f, "\t");
	switch (a->type) {
	case PLAIN:
		fprintf(f, "[%ld]", (long)a->co);
		break;
	case AHEAD:
		fprintf(f, ">%ld>", (long)a->co);
		break;
	case BEHIND:
		fprintf(f, "<%ld<", (long)a->co);
		break;
	case LACON:
		fprintf(f, ":%ld:", (long)a->co);
		break;
	case '^':
	case '$':
		fprintf(f, "%c%d", a->type, (int)a->co);
		break;
	case EMPTY:
		break;
	default:
		fprintf(f, "0x%x/0%lo", a->type, (long)a->co);
		break;
	}
	if (a->from != s)
		fprintf(f, "?%d?", a->from->no);
	for (ab = &a->from->oas; ab != NULL; ab = ab->next) {
		for (aa = &ab->a[0]; aa < &ab->a[ABSIZE]; aa++)
			if (aa == a)
				break;		/* NOTE BREAK OUT */
		if (aa < &ab->a[ABSIZE])	/* propagate break */
				break;		/* NOTE BREAK OUT */
	}
	if (ab == NULL)
		fprintf(f, "?!?");	/* not in allocated space */
	fprintf(f, "->");
	if (a->to == NULL) {
		fprintf(f, "NULL");
		return;
	}
	fprintf(f, "%d", a->to->no);
	for (aa = a->to->ins; aa != NULL; aa = aa->inchain)
		if (aa == a)
			break;		/* NOTE BREAK OUT */
	if (aa == NULL)
		fprintf(f, "?!?");	/* missing from in-chain */
}

#endif				/* ifdef REG_DEBUG */

/*
 - dumpcnfa - dump a compacted NFA in human-readable form
 ^ static VOID dumpcnfa(struct cnfa *, FILE *);
 */
static VOID
dumpcnfa(cnfa, f)
struct cnfa *cnfa;
FILE *f;
{
#ifdef REG_DEBUG
	int st;

	fprintf(f, "pre %d, post %d", cnfa->pre, cnfa->post);
	if (cnfa->bos[0] != COLORLESS)
		fprintf(f, ", bos [%ld]", (long)cnfa->bos[0]);
	if (cnfa->bos[1] != COLORLESS)
		fprintf(f, ", bol [%ld]", (long)cnfa->bos[1]);
	if (cnfa->eos[0] != COLORLESS)
		fprintf(f, ", eos [%ld]", (long)cnfa->eos[0]);
	if (cnfa->eos[1] != COLORLESS)
		fprintf(f, ", eol [%ld]", (long)cnfa->eos[1]);
	if (cnfa->flags&HASLACONS)
		fprintf(f, ", haslacons");
	fprintf(f, "\n");
	for (st = 0; st < cnfa->nstates; st++)
		dumpcstate(st, cnfa->states[st], cnfa, f);
	fflush(f);
#endif
}

#ifdef REG_DEBUG		/* subordinates of dumpcnfa */

/*
 - dumpcstate - dump a compacted-NFA state in human-readable form
 ^ static VOID dumpcstate(int, struct carc *, struct cnfa *, FILE *);
 */
static VOID
dumpcstate(st, ca, cnfa, f)
int st;
struct carc *ca;
struct cnfa *cnfa;
FILE *f;
{
	int i;
	int pos;

	fprintf(f, "%d%s", st, (ca[0].co) ? ":" : ".");
	pos = 1;
	for (i = 1; ca[i].co != COLORLESS; i++) {
		if (ca[i].co < cnfa->ncolors)
			fprintf(f, "\t[%ld]->%d", (long)ca[i].co, ca[i].to);
		else
			fprintf(f, "\t:%ld:->%d", (long)ca[i].co-cnfa->ncolors,
								ca[i].to);
		if (pos == 5) {
			fprintf(f, "\n");
			pos = 1;
		} else
			pos++;
	}
	if (i == 1 || pos != 1)
		fprintf(f, "\n");
	fflush(f);
}

#endif				/* ifdef REG_DEBUG */

Added generic/regcomp.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
/*
 * re_*comp and friends - compile REs
 * This file #includes several others (see the bottom).
 */

#include "regguts.h"

/*
 * forward declarations, up here so forward datatypes etc. are defined early
 */
/* =====^!^===== begin forwards =====^!^===== */
/* automatically gathered by fwd; do not hand-edit */
/* === regcomp.c === */
int compile _ANSI_ARGS_((regex_t *, CONST chr *, size_t, int));
static VOID moresubs _ANSI_ARGS_((struct vars *, int));
static int freev _ANSI_ARGS_((struct vars *, int));
static VOID makescan _ANSI_ARGS_((struct vars *, struct nfa *));
static struct subre *parse _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *));
static struct subre *parsebranch _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *, int));
static VOID parseqatom _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *, struct subre *));
static VOID nonword _ANSI_ARGS_((struct vars *, int, struct state *, struct state *));
static VOID word _ANSI_ARGS_((struct vars *, int, struct state *, struct state *));
static int scannum _ANSI_ARGS_((struct vars *));
static VOID repeat _ANSI_ARGS_((struct vars *, struct state *, struct state *, int, int));
static VOID bracket _ANSI_ARGS_((struct vars *, struct state *, struct state *));
static VOID cbracket _ANSI_ARGS_((struct vars *, struct state *, struct state *));
static VOID brackpart _ANSI_ARGS_((struct vars *, struct state *, struct state *));
static chr *scanplain _ANSI_ARGS_((struct vars *));
static VOID leaders _ANSI_ARGS_((struct vars *, struct cvec *));
static VOID onechr _ANSI_ARGS_((struct vars *, pchr, struct state *, struct state *));
static VOID dovec _ANSI_ARGS_((struct vars *, struct cvec *, struct state *, struct state *));
static celt nextleader _ANSI_ARGS_((struct vars *, pchr, pchr));
static VOID wordchrs _ANSI_ARGS_((struct vars *));
static struct subre *subre _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *));
static VOID freesubre _ANSI_ARGS_((struct vars *, struct subre *));
static VOID freesrnode _ANSI_ARGS_((struct vars *, struct subre *));
static VOID optst _ANSI_ARGS_((struct vars *, struct subre *));
static int numst _ANSI_ARGS_((struct subre *, int));
static VOID markst _ANSI_ARGS_((struct subre *));
static VOID cleanst _ANSI_ARGS_((struct vars *));
static int nfatree _ANSI_ARGS_((struct vars *, struct subre *, FILE *));
static int nfanode _ANSI_ARGS_((struct vars *, struct subre *, FILE *));
static int newlacon _ANSI_ARGS_((struct vars *, struct state *, struct state *, int));
static VOID freelacons _ANSI_ARGS_((struct subre *, int));
static VOID rfree _ANSI_ARGS_((regex_t *));
static VOID dump _ANSI_ARGS_((regex_t *, FILE *));
static VOID dumpst _ANSI_ARGS_((struct subre *, FILE *, int));
static VOID stdump _ANSI_ARGS_((struct subre *, FILE *, int, int));
/* === regc_lex.c === */
static VOID lexstart _ANSI_ARGS_((struct vars *));
static VOID prefixes _ANSI_ARGS_((struct vars *));
static VOID lexnest _ANSI_ARGS_((struct vars *, chr *, chr *));
static VOID lexword _ANSI_ARGS_((struct vars *));
static int next _ANSI_ARGS_((struct vars *));
static int lexescape _ANSI_ARGS_((struct vars *));
static chr lexdigits _ANSI_ARGS_((struct vars *, int, int, int));
static int brenext _ANSI_ARGS_((struct vars *, pchr));
static VOID skip _ANSI_ARGS_((struct vars *));
static chr newline _ANSI_ARGS_((NOPARMS));
static chr chrnamed _ANSI_ARGS_((struct vars *, chr *, chr *, pchr));
/* === regc_color.c === */
static VOID initcm _ANSI_ARGS_((struct vars *, struct colormap *));
static VOID freecm _ANSI_ARGS_((struct colormap *));
static VOID cmtreefree _ANSI_ARGS_((struct colormap *, union tree *, int));
static color setcolor _ANSI_ARGS_((struct colormap *, pchr, pcolor));
static color maxcolor _ANSI_ARGS_((struct colormap *));
static color newcolor _ANSI_ARGS_((struct colormap *));
static VOID freecolor _ANSI_ARGS_((struct colormap *, pcolor));
static color pseudocolor _ANSI_ARGS_((struct colormap *));
static color subcolor _ANSI_ARGS_((struct colormap *, pchr c));
static color newsub _ANSI_ARGS_((struct colormap *, pcolor));
static VOID subrange _ANSI_ARGS_((struct vars *, pchr, pchr, struct state *, struct state *));
static VOID subblock _ANSI_ARGS_((struct vars *, pchr, struct state *, struct state *));
static VOID okcolors _ANSI_ARGS_((struct nfa *, struct colormap *));
static VOID colorchain _ANSI_ARGS_((struct colormap *, struct arc *));
static VOID uncolorchain _ANSI_ARGS_((struct colormap *, struct arc *));
#if 0
static int singleton _ANSI_ARGS_((struct colormap *, pchr c));
#endif
static VOID rainbow _ANSI_ARGS_((struct nfa *, struct colormap *, int, pcolor, struct state *, struct state *));
static VOID colorcomplement _ANSI_ARGS_((struct nfa *, struct colormap *, int, struct state *, struct state *, struct state *));
#ifdef REG_DEBUG
static VOID dumpcolors _ANSI_ARGS_((struct colormap *, FILE *));
static VOID fillcheck _ANSI_ARGS_((struct colormap *, union tree *, int, FILE *));
static VOID dumpchr _ANSI_ARGS_((pchr, FILE *));
#endif
/* === regc_nfa.c === */
static struct nfa *newnfa _ANSI_ARGS_((struct vars *, struct colormap *, struct nfa *));
static VOID freenfa _ANSI_ARGS_((struct nfa *));
static struct state *newfstate _ANSI_ARGS_((struct nfa *, int flag));
static struct state *newstate _ANSI_ARGS_((struct nfa *));
static VOID dropstate _ANSI_ARGS_((struct nfa *, struct state *));
static VOID freestate _ANSI_ARGS_((struct nfa *, struct state *));
static VOID destroystate _ANSI_ARGS_((struct nfa *, struct state *));
static VOID newarc _ANSI_ARGS_((struct nfa *, int, pcolor, struct state *, struct state *));
static struct arc *allocarc _ANSI_ARGS_((struct nfa *, struct state *));
static VOID freearc _ANSI_ARGS_((struct nfa *, struct arc *));
static struct arc *findarc _ANSI_ARGS_((struct state *, int, pcolor));
static VOID cparc _ANSI_ARGS_((struct nfa *, struct arc *, struct state *, struct state *));
static VOID moveins _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
static VOID copyins _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
static VOID moveouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
static VOID copyouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
static VOID cloneouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *, int));
static VOID delsub _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
static VOID deltraverse _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
static VOID dupnfa _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *, struct state *));
static VOID duptraverse _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
static VOID cleartraverse _ANSI_ARGS_((struct nfa *, struct state *));
static VOID specialcolors _ANSI_ARGS_((struct nfa *));
static int optimize _ANSI_ARGS_((struct nfa *, FILE *));
static VOID pullback _ANSI_ARGS_((struct nfa *, FILE *));
static int pull _ANSI_ARGS_((struct nfa *, struct arc *));
static VOID pushfwd _ANSI_ARGS_((struct nfa *, FILE *));
static int push _ANSI_ARGS_((struct nfa *, struct arc *));
#define	INCOMPATIBLE	1	/* destroys arc */
#define	SATISFIED	2	/* constraint satisfied */
#define	COMPATIBLE	3	/* compatible but not satisfied yet */
static int combine _ANSI_ARGS_((struct arc *, struct arc *));
static VOID fixempties _ANSI_ARGS_((struct nfa *, FILE *));
static int unempty _ANSI_ARGS_((struct nfa *, struct arc *));
static VOID cleanup _ANSI_ARGS_((struct nfa *));
static VOID markreachable _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *));
static VOID markcanreach _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *));
static int analyze _ANSI_ARGS_((struct nfa *));
static VOID compact _ANSI_ARGS_((struct nfa *, struct cnfa *));
static VOID carcsort _ANSI_ARGS_((struct carc *, struct carc *));
static VOID freecnfa _ANSI_ARGS_((struct cnfa *));
static VOID dumpnfa _ANSI_ARGS_((struct nfa *, FILE *));
#ifdef REG_DEBUG
static VOID dumpstate _ANSI_ARGS_((struct state *, FILE *));
static VOID dumparcs _ANSI_ARGS_((struct state *, FILE *));
static int dumprarcs _ANSI_ARGS_((struct arc *, struct state *, FILE *, int));
static VOID dumparc _ANSI_ARGS_((struct arc *, struct state *, FILE *));
#endif
static VOID dumpcnfa _ANSI_ARGS_((struct cnfa *, FILE *));
#ifdef REG_DEBUG
static VOID dumpcstate _ANSI_ARGS_((int, struct carc *, struct cnfa *, FILE *));
#endif
/* === regc_cvec.c === */
static struct cvec *newcvec _ANSI_ARGS_((int, int, int));
static struct cvec *clearcvec _ANSI_ARGS_((struct cvec *));
static VOID addchr _ANSI_ARGS_((struct cvec *, pchr));
static VOID addrange _ANSI_ARGS_((struct cvec *, pchr, pchr));
#ifdef USE_MCCE
static VOID addmcce _ANSI_ARGS_((struct cvec *, chr *, chr *));
#endif
static int haschr _ANSI_ARGS_((struct cvec *, pchr));
static struct cvec *getcvec _ANSI_ARGS_((struct vars *, int, int, int));
static VOID freecvec _ANSI_ARGS_((struct cvec *));
/* === regc_locale.c === */
static int nmcces _ANSI_ARGS_((struct vars *));
static int nleaders _ANSI_ARGS_((struct vars *));
static struct cvec *allmcces _ANSI_ARGS_((struct vars *, struct cvec *));
static celt element _ANSI_ARGS_((struct vars *, chr *, chr *));
static struct cvec *range _ANSI_ARGS_((struct vars *, celt, celt, int));
static int before _ANSI_ARGS_((celt, celt));
static struct cvec *eclass _ANSI_ARGS_((struct vars *, celt, int));
static struct cvec *cclass _ANSI_ARGS_((struct vars *, chr *, chr *, int));
static struct cvec *allcases _ANSI_ARGS_((struct vars *, pchr));
static int cmp _ANSI_ARGS_((CONST chr *, CONST chr *, size_t));
static int casecmp _ANSI_ARGS_((CONST chr *, CONST chr *, size_t));
/* automatically gathered by fwd; do not hand-edit */
/* =====^!^===== end forwards =====^!^===== */



/* internal variables, bundled for easy passing around */
struct vars {
	regex_t *re;
	chr *now;		/* scan pointer into string */
	chr *stop;		/* end of string */
	chr *savenow;		/* saved now and stop for "subroutine call" */
	chr *savestop;
	int err;		/* error code (0 if none) */
	int cflags;		/* copy of compile flags */
	int lasttype;		/* type of previous token */
	int nexttype;		/* type of next token */
	chr nextvalue;		/* value (if any) of next token */
	int lexcon;		/* lexical context type (see lex.c) */
	int nsubexp;		/* subexpression count */
	struct subre **subs;	/* subRE pointer vector */
	size_t nsubs;		/* length of vector */
	struct subre *sub10[10];	/* initial vector, enough for most */
	struct nfa *nfa;	/* the NFA */
	struct colormap *cm;	/* character color map */
	color nlcolor;		/* color of newline */
	struct state *wordchrs;	/* state in nfa holding word-char outarcs */
	struct subre *tree;	/* subexpression tree */
	struct subre *treechain;	/* all tree nodes allocated */
	struct subre *treefree;		/* any free tree nodes */
	int ntree;		/* number of tree nodes */
	struct cvec *cv;	/* interface cvec */
	struct cvec *cv2;	/* utility cvec */
	struct cvec *mcces;	/* collating-element information */
#		define	ISCELEADER(v,c)	(v->mcces != NULL && haschr(v->mcces, (c)))
	struct state *mccepbegin;	/* in nfa, start of MCCE prototypes */
	struct state *mccepend;	/* in nfa, end of MCCE prototypes */
	struct subre *lacons;	/* lookahead-constraint vector */
	int nlacons;		/* size of lacons */
	int usedshorter;	/* used short-preferring quantifiers */
	int unmatchable;	/* can never match */
};

/* parsing macros; most know that `v' is the struct vars pointer */
#define	NEXT()	(next(v))		/* advance by one token */
#define	SEE(t)	(v->nexttype == (t))	/* is next token this? */
#define	EAT(t)	(SEE(t) && next(v))	/* if next is this, swallow it */
#define	VISERR(vv)	((vv)->err != 0)	/* have we seen an error yet? */
#define	ISERR()	VISERR(v)
#define	VERR(vv,e)	((vv)->nexttype = EOS, ((vv)->err) ? (vv)->err :\
							((vv)->err = (e)))
#define	ERR(e)	VERR(v, e)		/* record an error */
#define	NOERR()	{if (ISERR()) return;}	/* if error seen, return */
#define	NOERRN()	{if (ISERR()) return NULL;}	/* NOERR with retval */
#define	NOERRZ()	{if (ISERR()) return 0;}	/* NOERR with retval */
#define	INSIST(c, e)	((c) ? 0 : ERR(e))	/* if condition false, error */
#define	NOTE(b)	(v->re->re_info |= (b))		/* note visible condition */
#define	EMPTYARC(x, y)	newarc(v->nfa, EMPTY, 0, x, y)

/* token type codes, some also used as NFA arc types */
#define	EMPTY	'n'		/* no token present */
#define	EOS	'e'		/* end of string */
#define	PLAIN	'p'		/* ordinary character */
#define	DIGIT	'd'		/* digit (in bound) */
#define	BACKREF	'b'		/* back reference */
#define	COLLEL	'I'		/* start of [. */
#define	ECLASS	'E'		/* start of [= */
#define	CCLASS	'C'		/* start of [: */
#define	END	'X'		/* end of [. [= [: */
#define	RANGE	'R'		/* - within [] which might be range delim. */
#define	LACON	'L'		/* lookahead constraint subRE */
#define	AHEAD	'a'		/* color-lookahead arc */
#define	BEHIND	'r'		/* color-lookbehind arc */
#define	WBDRY	'w'		/* word boundary constraint */
#define	NWBDRY	'W'		/* non-word-boundary constraint */
#define	SBEGIN	'A'		/* beginning of string (even if not BOL) */
#define	SEND	'Z'		/* end of string (even if not EOL) */
#define	PREFER	'P'		/* length preference */

/* is an arc colored, and hence on a color chain? */
#define	COLORED(a)	((a)->type == PLAIN || (a)->type == AHEAD || \
							(a)->type == BEHIND)



/* static function list */
static struct fns functions = {
	rfree,			/* regfree insides */
};



/*
 - compile - compile regular expression
 ^ int compile(regex_t *, CONST chr *, size_t, int);
 */
int
compile(re, string, len, flags)
regex_t *re;
CONST chr *string;
size_t len;
int flags;
{
	struct vars var;
	struct vars *v = &var;
	struct guts *g;
	int i;
	size_t j;
	FILE *debug = (flags&REG_PROGRESS) ? stdout : (FILE *)NULL;
#	define	CNOERR()	{ if (ISERR()) return freev(v, v->err); }

	/* sanity checks */

	if (re == NULL || string == NULL)
		return REG_INVARG;
	if ((flags&REG_QUOTE) &&
			(flags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)))
		return REG_INVARG;
	if (!(flags&REG_EXTENDED) && (flags&REG_ADVF))
		return REG_INVARG;

	/* initial setup (after which freev() is callable) */
	v->re = re;
	v->now = (chr *)string;
	v->stop = v->now + len;
	v->savenow = v->savestop = NULL;
	v->err = 0;
	v->cflags = flags;
	v->nsubexp = 0;
	v->subs = v->sub10;
	v->nsubs = 10;
	for (j = 0; j < v->nsubs; j++)
		v->subs[j] = NULL;
	v->nfa = NULL;
	v->cm = NULL;
	v->nlcolor = COLORLESS;
	v->wordchrs = NULL;
	v->tree = NULL;
	v->treechain = NULL;
	v->treefree = NULL;
	v->cv = NULL;
	v->cv2 = NULL;
	v->mcces = NULL;
	v->lacons = NULL;
	v->nlacons = 0;
	re->re_magic = REMAGIC;
	re->re_info = 0;		/* bits get set during parse */
	re->re_csize = sizeof(chr);
	re->re_guts = NULL;
	re->re_fns = VS(&functions);

	/* more complex setup, malloced things */
	re->re_guts = VS(MALLOC(sizeof(struct guts)));
	if (re->re_guts == NULL)
		return freev(v, REG_ESPACE);
	g = (struct guts *)re->re_guts;
	g->tree = NULL;
	initcm(v, &g->cmap);
	v->cm = &g->cmap;
	g->lacons = NULL;
	g->nlacons = 0;
	ZAPCNFA(g->search);
	v->nfa = newnfa(v, v->cm, (struct nfa *)NULL);
	CNOERR();
	v->cv = newcvec(100, 20, 10);
	if (v->cv == NULL)
		return freev(v, REG_ESPACE);
	i = nmcces(v);
	if (i > 0) {
		v->mcces = newcvec(nleaders(v), 0, i);
		CNOERR();
		v->mcces = allmcces(v, v->mcces);
		leaders(v, v->mcces);
	}
	CNOERR();

	/* parsing */
	lexstart(v);			/* also handles prefixes */
	if ((v->cflags&REG_NLSTOP) || (v->cflags&REG_NLANCH)) {
		/* assign newline a unique color */
		v->nlcolor = subcolor(v->cm, newline());
		okcolors(v->nfa, v->cm);
	}
	CNOERR();
	v->tree = parse(v, EOS, PLAIN, v->nfa->init, v->nfa->final);
	assert(SEE(EOS));		/* even if error; ISERR() => SEE(EOS) */
	CNOERR();
	assert(v->tree != NULL);

	/* finish setup of nfa and its subre tree */
	specialcolors(v->nfa);
	CNOERR();
	if (debug != NULL) {
		dumpnfa(v->nfa, debug);
		dumpst(v->tree, debug, 1);
	}
	v->usedshorter = 0;
	v->unmatchable = 0;
	optst(v, v->tree);
	v->ntree = numst(v->tree, 1);
	markst(v->tree);
	cleanst(v);
	if (debug != NULL) {
		fprintf(debug, "-->\n");
		dumpst(v->tree, debug, 1);
	}

	/* build compacted NFAs for tree, lacons, fast search */
	re->re_info |= nfatree(v, v->tree, debug);
	if (debug != NULL) {
		fprintf(debug, "---->\n");
		dumpst(v->tree, debug, 1);
	}
	CNOERR();
	if (re->re_info&REG_UIMPOSSIBLE)
		v->unmatchable = 1;
	assert(v->nlacons == 0 || v->lacons != NULL);
	for (i = 1; i < v->nlacons; i++)
		nfanode(v, &v->lacons[i], debug);
	CNOERR();
	(DISCARD)optimize(v->nfa, debug);
	CNOERR();
	makescan(v, v->nfa);
	CNOERR();
	compact(v->nfa, &g->search);
	CNOERR();

	/* looks okay, package it up */
	re->re_nsub = v->nsubexp;
	v->re = NULL;			/* freev no longer frees re */
	g->magic = GUTSMAGIC;
	g->cflags = v->cflags;
	g->info = re->re_info;
	g->nsub = re->re_nsub;
	g->tree = v->tree;
	v->tree = NULL;
	g->ntree = v->ntree;
	g->compare = (v->cflags&REG_ICASE) ? casecmp : cmp;
	g->lacons = v->lacons;
	v->lacons = NULL;
	g->nlacons = v->nlacons;
	g->usedshorter = v->usedshorter;
	g->unmatchable = v->unmatchable;

	if (flags&REG_DUMP)
		dump(re, stdout);

	assert(v->err == 0);
	return freev(v, 0);
}

/*
 - moresubs - enlarge subRE vector
 ^ static VOID moresubs(struct vars *, int);
 */
static VOID
moresubs(v, wanted)
struct vars *v;
int wanted;			/* want enough room for this one */
{
	struct subre **p;
	size_t n;

	assert(wanted > 0 && (size_t)wanted >= v->nsubs);
	n = (size_t)wanted * 3 / 2 + 1;
	if (v->subs == v->sub10) {
		p = (struct subre **)MALLOC(n * sizeof(struct subre *));
		if (p != NULL)
			memcpy(VS(p), VS(v->subs),
					v->nsubs * sizeof(struct subre *));
	} else
		p = (struct subre**)REALLOC(v->subs, n*sizeof(struct subre *));
	if (p == NULL) {
		ERR(REG_ESPACE);
		return;
	}
	v->subs = p;
	for (p = &v->subs[v->nsubs]; v->nsubs < n; p++, v->nsubs++)
		*p = NULL;
	assert(v->nsubs == n);
	assert((size_t)wanted < v->nsubs);
}

/*
 - freev - free vars struct's substructures where necessary
 * Optionally does error-number setting, and always returns error code
 * (if any), to make error-handling code terser.
 ^ static int freev(struct vars *, int);
 */
static int
freev(v, err)
struct vars *v;
int err;
{
	if (v->re != NULL)
		rfree(v->re);
	if (v->subs != v->sub10)
		FREE(v->subs);
	if (v->nfa != NULL)
		freenfa(v->nfa);
	if (v->tree != NULL)
		freesubre(v, v->tree);
	if (v->treechain != NULL)
		cleanst(v);
	if (v->cv != NULL)
		freecvec(v->cv);
	if (v->cv2 != NULL)
		freecvec(v->cv2);
	if (v->mcces != NULL)
		freecvec(v->mcces);
	if (v->lacons != NULL)
		freelacons(v->lacons, v->nlacons);
	ERR(err);			/* nop if err==0 */

	return v->err;
}

/*
 - makescan - turn an NFA into a fast-scan NFA (implicit prepend of .*?)
 * NFA must have been optimize()d already.
 ^ static VOID makescan(struct vars *, struct nfa *);
 */
static VOID
makescan(v, nfa)
struct vars *v;
struct nfa *nfa;
{
	struct arc *a;
	struct arc *b;
	struct state *pre = nfa->pre;
	struct state *s;
  	struct state *s2;
  	struct state *slist;
  
 	/* no loops are needed if it's anchored */
 	for (a = pre->outs; a != NULL; a = a->outchain) {
		assert(a->type == PLAIN);
		if (a->co != nfa->bos[0] && a->co != nfa->bos[1])
			break;
 	}
 	if (a != NULL) {
		/* add implicit .* in front */
		rainbow(nfa, v->cm, PLAIN, COLORLESS, pre, pre);

		/* and ^* and \Z* too -- not always necessary, but harmless */
		newarc(nfa, PLAIN, nfa->bos[0], pre, pre);
		newarc(nfa, PLAIN, nfa->bos[1], pre, pre);
 	}
 
 	/*
  	 * Now here's the subtle part.  Because many REs have no lookback
	 * constraints, often knowing when you were in the pre state tells
	 * you little; it's the next state(s) that are informative.  But
	 * some of them may have other inarcs, i.e. it may be possible to
	 * make actual progress and then return to one of them.  We must
	 * de-optimize such cases, splitting each such state into progress
	 * and no-progress states.
	 */

	/* first, make a list of the states */
	slist = NULL;
	for (a = pre->outs; a != NULL; a = a->outchain) {
		s = a->to;
		for (b = s->ins; b != NULL; b = b->inchain)
			if (b->from != pre)
				break;
		if (b != NULL) {		/* must be split */
			s->tmp = slist;
			slist = s;
		}
	}

	/* do the splits */
	for (s = slist; s != NULL; s = s2) {
		s2 = newstate(nfa);
		copyouts(nfa, s, s2);
		for (a = s->ins; a != NULL; a = b) {
			b = a->inchain;
			if (a->from != pre) {
				cparc(nfa, a, a->from, s2);
				freearc(nfa, a);
			}
		}
		s2 = s->tmp;
		s->tmp = NULL;		/* clean up while we're at it */
	}
}

/*
 - parse - parse an RE
 * This is actually just the top level, which parses a bunch of branches
 * tied together with '|'.  They appear in the tree as the left children
 * of a chain of '|' subres.
 ^ static struct subre *parse(struct vars *, int, int, struct state *,
 ^ 	struct state *);
 */
static struct subre *
parse(v, stopper, type, init, final)
struct vars *v;
int stopper;			/* EOS or ')' */
int type;			/* LACON (lookahead subRE) or PLAIN */
struct state *init;		/* initial state */
struct state *final;		/* final state */
{
	struct state *left;	/* scaffolding for branch */
	struct state *right;
	struct subre *branches;	/* top level */
	struct subre *branch;	/* current branch */
	struct subre *t;	/* temporary */
	int firstbranch;	/* is this the first branch? */

	assert(stopper == ')' || stopper == EOS);

	branches = subre(v, '|', LONGER, init, final);
	NOERRN();
	branch = branches;
	firstbranch = 1;
	do {	/* a branch */
		if (!firstbranch) {
			/* need a place to hang it */
			branch->right = subre(v, '|', LONGER, init, final);
			NOERRN();
			branch = branch->right;
		}
		firstbranch = 0;
		left = newstate(v->nfa);
		right = newstate(v->nfa);
		NOERRN();
		EMPTYARC(init, left);
		EMPTYARC(right, final);
		NOERRN();
		branch->left = parsebranch(v, stopper, type, left, right, 0);
		NOERRN();
		branch->flags |= UP(branch->flags | branch->left->flags);
		if ((branch->flags &~ branches->flags) != 0)	/* new flags */
			for (t = branches; t != branch; t = t->right)
				t->flags |= branch->flags;
	} while (EAT('|'));
	assert(SEE(stopper) || SEE(EOS));

	if (!SEE(stopper)) {
		assert(stopper == ')' && SEE(EOS));
		ERR(REG_EPAREN);
	}

	/* optimize out simple cases */
	if (branch == branches) {	/* only one branch */
		assert(branch->right == NULL);
		t = branch->left;
		branch->left = NULL;
		freesubre(v, branches);
		branches = t;
	} else if (!MESSY(branches->flags)) {	/* no interesting innards */
		freesubre(v, branches->left);
		branches->left = NULL;
		freesubre(v, branches->right);
		branches->right = NULL;
		branches->op = '=';
	}

	return branches;
}

/*
 - parsebranch - parse one branch of an RE
 * This mostly manages concatenation, working closely with parseqatom().
 * Concatenated things are bundled up as much as possible, with separate
 * ',' nodes introduced only when necessary due to substructure.
 ^ static struct subre *parsebranch(struct vars *, int, int, struct state *,
 ^ 	struct state *, int);
 */
static struct subre *
parsebranch(v, stopper, type, left, right, partial)
struct vars *v;
int stopper;			/* EOS or ')' */
int type;			/* LACON (lookahead subRE) or PLAIN */
struct state *left;		/* leftmost state */
struct state *right;		/* rightmost state */
int partial;			/* is this only part of a branch? */
{
	struct state *lp;	/* left end of current construct */
	int seencontent;	/* is there anything in this branch yet? */
	struct subre *t;

	lp = left;
	seencontent = 0;
	t = subre(v, '=', 0, left, right);	/* op '=' is tentative */
	NOERRN();
	while (!SEE('|') && !SEE(stopper) && !SEE(EOS)) {
		if (seencontent) {	/* implicit concat operator */
			lp = newstate(v->nfa);
			NOERRN();
			moveins(v->nfa, right, lp);
		}
		seencontent = 1;

		/* NB, recursion in parseqatom() may swallow rest of branch */
		parseqatom(v, stopper, type, lp, right, t);
	}

	if (!seencontent) {		/* empty branch */
		if (!partial)
			NOTE(REG_UUNSPEC);
		assert(lp == left);
		EMPTYARC(left, right);
	}

	return t;
}

/*
 - parseqatom - parse one quantified atom or constraint of an RE
 * The bookkeeping near the end cooperates very closely with parsebranch();
 * in particular, it contains a recursion that can involve parsing the rest
 * of the branch, making this function's name somewhat inaccurate.
 ^ static VOID parseqatom(struct vars *, int, int, struct state *,
 ^ 	struct state *, struct subre *);
 */
static VOID
parseqatom(v, stopper, type, lp, rp, top)
struct vars *v;
int stopper;			/* EOS or ')' */
int type;			/* LACON (lookahead subRE) or PLAIN */
struct state *lp;		/* left state to hang it on */
struct state *rp;		/* right state to hang it on */
struct subre *top;		/* subtree top */
{
	struct state *s;	/* temporaries for new states */
	struct state *s2;
#	define	ARCV(t, val)	newarc(v->nfa, t, val, lp, rp)
	int m, n;
	struct subre *atom;	/* atom's subtree */
	struct subre *t;
	int cap;		/* capturing parens? */
	int pos;		/* positive lookahead? */
	int subno;		/* capturing-parens or backref number */
	int atomtype;
	int qprefer;		/* quantifier short/long preference */
	int f;
	struct subre **atomp;	/* where the pointer to atom is */

	/* initial bookkeeping */
	atom = NULL;
	assert(lp->nouts == 0);	/* must string new code */
	assert(rp->nins == 0);	/*  between lp and rp */
	subno = 0;		/* just to shut lint up */

	/* an atom or constraint... */
	atomtype = v->nexttype;
	switch (atomtype) {
	/* first, constraints, which end by returning */
	case '^':
		ARCV('^', 1);
		if (v->cflags&REG_NLANCH)
			ARCV(BEHIND, v->nlcolor);
		NEXT();
		return;
		break;
	case '$':
		ARCV('$', 1);
		if (v->cflags&REG_NLANCH)
			ARCV(AHEAD, v->nlcolor);
		NEXT();
		return;
		break;
	case SBEGIN:
		ARCV('^', 1);	/* BOL */
		ARCV('^', 0);	/* or BOS */
		NEXT();
		return;
		break;
	case SEND:
		ARCV('$', 1);	/* EOL */
		ARCV('$', 0);	/* or EOS */
		NEXT();
		return;
		break;
	case '<':
		wordchrs(v);	/* does NEXT() */
		s = newstate(v->nfa);
		NOERR();
		nonword(v, BEHIND, lp, s);
		word(v, AHEAD, s, rp);
		return;
		break;
	case '>':
		wordchrs(v);	/* does NEXT() */
		s = newstate(v->nfa);
		NOERR();
		word(v, BEHIND, lp, s);
		nonword(v, AHEAD, s, rp);
		return;
		break;
	case WBDRY:
		wordchrs(v);	/* does NEXT() */
		s = newstate(v->nfa);
		NOERR();
		nonword(v, BEHIND, lp, s);
		word(v, AHEAD, s, rp);
		s = newstate(v->nfa);
		NOERR();
		word(v, BEHIND, lp, s);
		nonword(v, AHEAD, s, rp);
		return;
		break;
	case NWBDRY:
		wordchrs(v);	/* does NEXT() */
		s = newstate(v->nfa);
		NOERR();
		word(v, BEHIND, lp, s);
		word(v, AHEAD, s, rp);
		s = newstate(v->nfa);
		NOERR();
		nonword(v, BEHIND, lp, s);
		nonword(v, AHEAD, s, rp);
		return;
		break;
	case LACON:	/* lookahead constraint */
		pos = v->nextvalue;
		NEXT();
		s = newstate(v->nfa);
		s2 = newstate(v->nfa);
		NOERR();
		t = parse(v, ')', LACON, s, s2);
		freesubre(v, t);	/* internal structure irrelevant */
		assert(SEE(')') || ISERR());
		NEXT();
		n = newlacon(v, s, s2, pos);
		NOERR();
		ARCV(LACON, n);
		return;
		break;
	/* then errors, to get them out of the way */
	case '*':
	case '+':
	case '?':
	case '{':
		ERR(REG_BADRPT);
		return;
		break;
	default:
		ERR(REG_ASSERT);
		return;
		break;
	/* then plain characters, and minor variants on that theme */
	case ')':		/* unbalanced paren */
		if ((v->cflags&REG_ADVANCED) != REG_EXTENDED) {
			ERR(REG_EPAREN);
			return;
		}
		/* legal in EREs due to specification botch */
		NOTE(REG_UPBOTCH);
		/* fallthrough into case PLAIN */
	case PLAIN:
		onechr(v, v->nextvalue, lp, rp);
		okcolors(v->nfa, v->cm);
		NOERR();
		NEXT();
		break;
	case '[':
		if (v->nextvalue == 1)
			bracket(v, lp, rp);
		else
			cbracket(v, lp, rp);
		assert(SEE(']') || ISERR());
		NEXT();
		break;
	case '.':
		rainbow(v->nfa, v->cm, PLAIN,
				(v->cflags&REG_NLSTOP) ? v->nlcolor : COLORLESS,
				lp, rp);
		NEXT();
		break;
	/* and finally the ugly stuff */
	case '(':	/* value flags as capturing or non */
		cap = (type == LACON) ? 0 : v->nextvalue;
		if (cap) {
			v->nsubexp++;
			subno = v->nsubexp;
			if ((size_t)subno >= v->nsubs)
				moresubs(v, subno);
			assert((size_t)subno < v->nsubs);
		} else
			atomtype = PLAIN;	/* something that's not '(' */
		NEXT();
		/* need new endpoints because tree will contain pointers */
		s = newstate(v->nfa);
		s2 = newstate(v->nfa);
		NOERR();
		EMPTYARC(lp, s);
		EMPTYARC(s2, rp);
		NOERR();
		atom = parse(v, ')', PLAIN, s, s2);
		assert(SEE(')') || ISERR());
		NEXT();
		NOERR();
		if (cap) {
			v->subs[subno] = atom;
			t = subre(v, '(', atom->flags|CAP, lp, rp);
			NOERR();
			t->subno = subno;
			t->left = atom;
			atom = t;
		}
		/* postpone everything else pending possible {0} */
		break;
	case BACKREF:	/* the Feature From The Black Lagoon */
		INSIST(type != LACON, REG_ESUBREG);
		INSIST(v->nextvalue < v->nsubs, REG_ESUBREG);
		INSIST(v->subs[v->nextvalue] != NULL, REG_ESUBREG);
		NOERR();
		assert(v->nextvalue > 0);
		atom = subre(v, 'b', BACKR, lp, rp);
		subno = v->nextvalue;
		atom->subno = subno;
		EMPTYARC(lp, rp);	/* temporarily, so there's something */
		NEXT();
		break;
	}

	/* ...and an atom may be followed by a quantifier */
	switch (v->nexttype) {
	case '*':
		m = 0;
		n = INFINITY;
		qprefer = (v->nextvalue) ? LONGER : SHORTER;
		NEXT();
		break;
	case '+':
		m = 1;
		n = INFINITY;
		qprefer = (v->nextvalue) ? LONGER : SHORTER;
		NEXT();
		break;
	case '?':
		m = 0;
		n = 1;
		qprefer = (v->nextvalue) ? LONGER : SHORTER;
		NEXT();
		break;
	case '{':
		NEXT();
		m = scannum(v);
		if (EAT(',')) {
			if (SEE(DIGIT))
				n = scannum(v);
			else
				n = INFINITY;
			if (m > n) {
				ERR(REG_BADBR);
				return;
			}
			/* {m,n} exercises preference, even if it's {m,m} */
			qprefer = (v->nextvalue) ? LONGER : SHORTER;
		} else {
			n = m;
			/* {m} passes operand's preference through */
			qprefer = 0;
		}
		if (!SEE('}')) {	/* catches errors too */
			ERR(REG_BADBR);
			return;
		}
		NEXT();
		break;
	default:		/* no quantifier */
		m = n = 1;
		qprefer = 0;
		break;
	}

	/* annoying special case:  {0} or {0,0} cancels everything */
	if (m == 0 && n == 0) {
		if (atom != NULL)
			freesubre(v, atom);
		if (atomtype == '(')
			v->subs[subno] = NULL;
		delsub(v->nfa, lp, rp);
		EMPTYARC(lp, rp);
		return;
	}

	/* if not a messy case, avoid hard part */
	assert(!MESSY(top->flags));
	f = top->flags | qprefer | ((atom != NULL) ? atom->flags : 0);
	if (atomtype != '(' && atomtype != BACKREF && !MESSY(UP(f))) {
		if (!(m == 1 && n == 1))
			repeat(v, lp, rp, m, n);
		if (atom != NULL)
			freesubre(v, atom);
		top->flags = f;
		return;
	}

	/*
	 * hard part:  something messy
	 * That is, capturing parens, back reference, short/long clash, or
	 * an atom with substructure containing one of those.
	 */

	/* now we'll need a subre for the contents even if they're boring */
	if (atom == NULL) {
		atom = subre(v, '=', 0, lp, rp);
		NOERR();
	}

	/*
	 * prepare a general-purpose state skeleton
	 *
	 *    ---> [s] ---prefix---> [begin] ---atom---> [end] ----rest---> [rp]
	 *   /                                            /
	 * [lp] ----> [s2] ----bypass---------------------
	 *
	 * where bypass is an empty, and prefix is some repetitions of atom
	 */
	s = newstate(v->nfa);		/* first, new endpoints for the atom */
	s2 = newstate(v->nfa);
	NOERR();
	moveouts(v->nfa, lp, s);
	moveins(v->nfa, rp, s2);
	NOERR();
	atom->begin = s;
	atom->end = s2;
	s = newstate(v->nfa);		/* and spots for prefix and bypass */
	s2 = newstate(v->nfa);
	NOERR();
	EMPTYARC(lp, s);
	EMPTYARC(lp, s2);
	NOERR();

	/* break remaining subRE into x{...} and what follows */
	t = subre(v, '.', COMBINE(qprefer, atom->flags), lp, rp);
	t->left = atom;
	atomp = &t->left;
	/* here we should recurse... but we must postpone that to the end */

	/* split top into prefix and remaining */
	assert(top->op == '=' && top->left == NULL && top->right == NULL);
	top->left = subre(v, '=', top->flags, top->begin, lp);
	top->op = '.';
	top->right = t;

	/* if it's a backref, now is the time to replicate the subNFA */
	if (atomtype == BACKREF) {
		assert(atom->begin->nouts == 1);	/* just the EMPTY */
		delsub(v->nfa, atom->begin, atom->end);
		assert(v->subs[subno] != NULL);
		/* and here's why the recursion got postponed:  it must */
		/* wait until the skeleton is filled in, because it may */
		/* hit a backref that wants to copy the filled-in skeleton */
		dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end,
						atom->begin, atom->end);
		NOERR();
	}

	/* it's quantifier time; first, turn x{0,...} into x{1,...}|empty */
	if (m == 0) {
		EMPTYARC(s2, atom->end);		/* the bypass */
		assert(PREF(qprefer) != 0);
		f = COMBINE(qprefer, atom->flags);
		t = subre(v, '|', f, lp, atom->end);
		NOERR();
		t->left = atom;
		t->right = subre(v, '|', PREF(f), s2, atom->end);
		NOERR();
		t->right->left = subre(v, '=', 0, s2, atom->end);
		NOERR();
		*atomp = t;
		atomp = &t->left;
		m = 1;
	}

	/* deal with the rest of the quantifier */
	if (atomtype == BACKREF) {
		/* special case:  backrefs have internal quantifiers */
		EMPTYARC(s, atom->begin);	/* empty prefix */
		/* just stuff everything into atom */
		repeat(v, atom->begin, atom->end, m, n);
		atom->min = (short)m;
		atom->max = (short)n;
		atom->flags |= COMBINE(qprefer, atom->flags);
	} else if (m == 1 && n == 1) {
		/* no/vacuous quantifier:  done */
		EMPTYARC(s, atom->begin);	/* empty prefix */
	} else {
		/* turn x{m,n} into x{m-1,n-1}x, with capturing */
		/*  parens in only second x */
		dupnfa(v->nfa, atom->begin, atom->end, s, atom->begin);
		assert(m >= 1 && m != INFINITY && n >= 1);
		repeat(v, s, atom->begin, m-1, (n == INFINITY) ? n : n-1);
		f = COMBINE(qprefer, atom->flags);
		t = subre(v, '.', f, s, atom->end);	/* prefix and atom */
		NOERR();
		t->left = subre(v, '=', PREF(f), s, atom->begin);
		NOERR();
		t->right = atom;
		*atomp = t;
	}

	/* and finally, look after that postponed recursion */
	t = top->right;
	if (!(SEE('|') || SEE(stopper) || SEE(EOS)))
		t->right = parsebranch(v, stopper, type, atom->end, rp, 1);
	else {
		EMPTYARC(atom->end, rp);
		t->right = subre(v, '=', 0, atom->end, rp);
	}
	assert(SEE('|') || SEE(stopper) || SEE(EOS));
	t->flags |= COMBINE(t->flags, t->right->flags);
	top->flags |= COMBINE(top->flags, t->flags);
}

/*
 - nonword - generate arcs for non-word-character ahead or behind
 ^ static VOID nonword(struct vars *, int, struct state *, struct state *);
 */
static VOID
nonword(v, dir, lp, rp)
struct vars *v;
int dir;			/* AHEAD or BEHIND */
struct state *lp;
struct state *rp;
{
	int anchor = (dir == AHEAD) ? '$' : '^';

	assert(dir == AHEAD || dir == BEHIND);
	newarc(v->nfa, anchor, 1, lp, rp);
	newarc(v->nfa, anchor, 0, lp, rp);
	colorcomplement(v->nfa, v->cm, dir, v->wordchrs, lp, rp);
	/* (no need for special attention to \n) */
}

/*
 - word - generate arcs for word character ahead or behind
 ^ static VOID word(struct vars *, int, struct state *, struct state *);
 */
static VOID
word(v, dir, lp, rp)
struct vars *v;
int dir;			/* AHEAD or BEHIND */
struct state *lp;
struct state *rp;
{
	assert(dir == AHEAD || dir == BEHIND);
	cloneouts(v->nfa, v->wordchrs, lp, rp, dir);
	/* (no need for special attention to \n) */
}

/*
 - scannum - scan a number
 ^ static int scannum(struct vars *);
 */
static int			/* value, <= DUPMAX */
scannum(v)
struct vars *v;
{
	int n = 0;

	while (SEE(DIGIT) && n < DUPMAX) {
		n = n*10 + v->nextvalue;
		NEXT();
	}
	if (SEE(DIGIT) || n > DUPMAX) {
		ERR(REG_BADBR);
		return 0;
	}
	return n;
}

/*
 - repeat - replicate subNFA for quantifiers
 * The duplication sequences used here are chosen carefully so that any
 * pointers starting out pointing into the subexpression end up pointing into
 * the last occurrence.  (Note that it may not be strung between the same
 * left and right end states, however!)  This used to be important for the
 * subRE tree, although the important bits are now handled by the in-line
 * code in parse(), and when this is called, it doesn't matter any more.
 ^ static VOID repeat(struct vars *, struct state *, struct state *, int, int);
 */
static VOID
repeat(v, lp, rp, m, n)
struct vars *v;
struct state *lp;
struct state *rp;
int m;
int n;
{
#	define	SOME	2
#	define	INF	3
#	define	PAIR(x, y)	((x)*4 + (y))
#	define	REDUCE(x)	( ((x) == INFINITY) ? INF : (((x) > 1) ? SOME : (x)) )
	CONST int rm = REDUCE(m);
	CONST int rn = REDUCE(n);
	struct state *s;
	struct state *s2;

	switch (PAIR(rm, rn)) {
	case PAIR(0, 0):		/* empty string */
		delsub(v->nfa, lp, rp);
		EMPTYARC(lp, rp);
		break;
	case PAIR(0, 1):		/* do as x| */
		EMPTYARC(lp, rp);
		break;
	case PAIR(0, SOME):		/* do as x{1,n}| */
		repeat(v, lp, rp, 1, n);
		NOERR();
		EMPTYARC(lp, rp);
		break;
	case PAIR(0, INF):		/* loop x around */
		s = newstate(v->nfa);
		NOERR();
		moveouts(v->nfa, lp, s);
		moveins(v->nfa, rp, s);
		EMPTYARC(lp, s);
		EMPTYARC(s, rp);
		break;
	case PAIR(1, 1):		/* no action required */
		break;
	case PAIR(1, SOME):		/* do as x{0,n-1}x = (x{1,n-1}|)x */
		s = newstate(v->nfa);
		NOERR();
		moveouts(v->nfa, lp, s);
		dupnfa(v->nfa, s, rp, lp, s);
		NOERR();
		repeat(v, lp, s, 1, n-1);
		NOERR();
		EMPTYARC(lp, s);
		break;
	case PAIR(1, INF):		/* add loopback arc */
		s = newstate(v->nfa);
		s2 = newstate(v->nfa);
		NOERR();
		moveouts(v->nfa, lp, s);
		moveins(v->nfa, rp, s2);
		EMPTYARC(lp, s);
		EMPTYARC(s2, rp);
		EMPTYARC(s2, s);
		break;
	case PAIR(SOME, SOME):		/* do as x{m-1,n-1}x */
		s = newstate(v->nfa);
		NOERR();
		moveouts(v->nfa, lp, s);
		dupnfa(v->nfa, s, rp, lp, s);
		NOERR();
		repeat(v, lp, s, m-1, n-1);
		break;
	case PAIR(SOME, INF):		/* do as x{m-1,}x */
		s = newstate(v->nfa);
		NOERR();
		moveouts(v->nfa, lp, s);
		dupnfa(v->nfa, s, rp, lp, s);
		NOERR();
		repeat(v, lp, s, m-1, n);
		break;
	default:
		ERR(REG_ASSERT);
		break;
	}
}

/*
 - bracket - handle non-complemented bracket expression
 * Also called from cbracket for complemented bracket expressions.
 ^ static VOID bracket(struct vars *, struct state *, struct state *);
 */
static VOID
bracket(v, lp, rp)
struct vars *v;
struct state *lp;
struct state *rp;
{
	assert(SEE('['));
	NEXT();
	while (!SEE(']') && !SEE(EOS))
		brackpart(v, lp, rp);
	assert(SEE(']') || ISERR());
	okcolors(v->nfa, v->cm);
}

/*
 - cbracket - handle complemented bracket expression
 * We do it by calling bracket() with dummy endpoints, and then complementing
 * the result.  The alternative would be to invoke rainbow(), and then delete
 * arcs as the b.e. is seen... but that gets messy.
 ^ static VOID cbracket(struct vars *, struct state *, struct state *);
 */
static VOID
cbracket(v, lp, rp)
struct vars *v;
struct state *lp;
struct state *rp;
{
	struct state *left = newstate(v->nfa);
	struct state *right = newstate(v->nfa);
	struct state *s;
	struct arc *a;			/* arc from lp */
	struct arc *ba;			/* arc from left, from bracket() */
	struct arc *pa;			/* MCCE-prototype arc */
	color co;
	chr *p;
	int i;

	NOERR();
	bracket(v, left, right);
	if (v->cflags&REG_NLSTOP)
		newarc(v->nfa, PLAIN, v->nlcolor, left, right);
	NOERR();

	assert(lp->nouts == 0);		/* all outarcs will be ours */

	/* easy part of complementing */
	colorcomplement(v->nfa, v->cm, PLAIN, left, lp, rp);
	NOERR();
	if (v->mcces == NULL) {		/* no MCCEs -- we're done */
		dropstate(v->nfa, left);
		assert(right->nins == 0);
		freestate(v->nfa, right);
		return;
	}

	/* but complementing gets messy in the presence of MCCEs... */
	NOTE(REG_ULOCALE);
	for (p = v->mcces->chrs, i = v->mcces->nchrs; i > 0; p++, i--) {
		co = GETCOLOR(v->cm, *p);
		a = findarc(lp, PLAIN, co);
		ba = findarc(left, PLAIN, co);
		if (ba == NULL) {
			assert(a != NULL);
			freearc(v->nfa, a);
		} else {
			assert(a == NULL);
		}
		s = newstate(v->nfa);
		NOERR();
		newarc(v->nfa, PLAIN, co, lp, s);
		NOERR();
		pa = findarc(v->mccepbegin, PLAIN, co);
		assert(pa != NULL);
		if (ba == NULL) {	/* easy case, need all of them */
			cloneouts(v->nfa, pa->to, s, rp, PLAIN);
			newarc(v->nfa, '$', 1, s, rp);
			newarc(v->nfa, '$', 0, s, rp);
			colorcomplement(v->nfa, v->cm, AHEAD, pa->to, s, rp);
		} else {		/* must be selective */
			if (findarc(ba->to, '$', 1) == NULL) {
				newarc(v->nfa, '$', 1, s, rp);
				newarc(v->nfa, '$', 0, s, rp);
				colorcomplement(v->nfa, v->cm, AHEAD, pa->to,
									 s, rp);
			}
			for (pa = pa->to->outs; pa != NULL; pa = pa->outchain)
				if (findarc(ba->to, PLAIN, pa->co) == NULL)
					newarc(v->nfa, PLAIN, pa->co, s, rp);
			if (s->nouts == 0)	/* limit of selectivity: none */
				dropstate(v->nfa, s);	/* frees arc too */
		}
		NOERR();
	}

	delsub(v->nfa, left, right);
	assert(left->nouts == 0);
	freestate(v->nfa, left);
	assert(right->nins == 0);
	freestate(v->nfa, right);
}
			
/*
 - brackpart - handle one item (or range) within a bracket expression
 ^ static VOID brackpart(struct vars *, struct state *, struct state *);
 */
static VOID
brackpart(v, lp, rp)
struct vars *v;
struct state *lp;
struct state *rp;
{
	celt startc;
	celt endc;
	struct cvec *cv;
	chr *startp;
	chr *endp;
	chr c[1];

	/* parse something, get rid of special cases, take shortcuts */
	switch (v->nexttype) {
	case RANGE:			/* a-b-c or other botch */
		ERR(REG_ERANGE);
		return;
		break;
	case PLAIN:
		c[0] = v->nextvalue;
		NEXT();
		/* shortcut for ordinary chr (not range, not MCCE leader) */
		if (!SEE(RANGE) && !ISCELEADER(v, c[0])) {
			onechr(v, c[0], lp, rp);
			return;
		}
		startc = element(v, c, c+1);
		NOERR();
		break;
	case COLLEL:
		startp = v->now;
		endp = scanplain(v);
		INSIST(startp < endp, REG_ECOLLATE);
		NOERR();
		startc = element(v, startp, endp);
		NOERR();
		break;
	case ECLASS:
		startp = v->now;
		endp = scanplain(v);
		INSIST(startp < endp, REG_ECOLLATE);
		NOERR();
		startc = element(v, startp, endp);
		NOERR();
		cv = eclass(v, startc, (v->cflags&REG_ICASE));
		NOERR();
		dovec(v, cv, lp, rp);
		return;
		break;
	case CCLASS:
		startp = v->now;
		endp = scanplain(v);
		INSIST(startp < endp, REG_ECTYPE);
		NOERR();
		cv = cclass(v, startp, endp, (v->cflags&REG_ICASE));
		NOERR();
		dovec(v, cv, lp, rp);
		return;
		break;
	default:
		ERR(REG_ASSERT);
		return;
		break;
	}

	if (SEE(RANGE)) {
		NEXT();
		switch (v->nexttype) {
		case PLAIN:
		case RANGE:
			c[0] = v->nextvalue;
			NEXT();
			endc = element(v, c, c+1);
			NOERR();
			break;
		case COLLEL:
			startp = v->now;
			endp = scanplain(v);
			INSIST(startp < endp, REG_ECOLLATE);
			NOERR();
			endc = element(v, startp, endp);
			NOERR();
			break;
		default:
			ERR(REG_ERANGE);
			return;
			break;
		}
	} else
		endc = startc;

	/*
	 * Ranges are unportable.  Actually, standard C does
	 * guarantee that digits are contiguous, but making
	 * that an exception is just too complicated.
	 */
	if (startc != endc)
		NOTE(REG_UUNPORT);
	cv = range(v, startc, endc, (v->cflags&REG_ICASE));
	NOERR();
	dovec(v, cv, lp, rp);
}

/*
 - scanplain - scan PLAIN contents of [. etc.
 * Certain bits of trickery in lex.c know that this code does not try
 * to look past the final bracket of the [. etc.
 ^ static chr *scanplain(struct vars *);
 */
static chr *			/* just after end of sequence */
scanplain(v)
struct vars *v;
{
	chr *endp;

	assert(SEE(COLLEL) || SEE(ECLASS) || SEE(CCLASS));
	NEXT();

	endp = v->now;
	while (SEE(PLAIN)) {
		endp = v->now;
		NEXT();
	}

	assert(SEE(END) || ISERR());
	NEXT();

	return endp;
}

/*
 - leaders - process a cvec of collating elements to also include leaders
 * Also gives all characters involved their own colors, which is almost
 * certainly necessary, and sets up little disconnected subNFA.
 ^ static VOID leaders(struct vars *, struct cvec *);
 */
static VOID
leaders(v, cv)
struct vars *v;
struct cvec *cv;
{
	int mcce;
	chr *p;
	chr leader;
	struct state *s;
	struct arc *a;

	v->mccepbegin = newstate(v->nfa);
	v->mccepend = newstate(v->nfa);
	NOERR();

	for (mcce = 0; mcce < cv->nmcces; mcce++) {
		p = cv->mcces[mcce];
		leader = *p;
		if (!haschr(cv, leader)) {
			addchr(cv, leader);
			s = newstate(v->nfa);
			newarc(v->nfa, PLAIN, subcolor(v->cm, leader),
							v->mccepbegin, s);
			okcolors(v->nfa, v->cm);
		} else {
			a = findarc(v->mccepbegin, PLAIN,
						GETCOLOR(v->cm, leader));
			assert(a != NULL);
			s = a->to;
			assert(s != v->mccepend);
		}
		p++;
		assert(*p != 0 && *(p+1) == 0);	/* only 2-char MCCEs for now */
		newarc(v->nfa, PLAIN, subcolor(v->cm, *p), s, v->mccepend);
		okcolors(v->nfa, v->cm);
	}
}

/*
 - onechr - fill in arcs for a plain character, and possible case complements
 * This is mostly a shortcut for efficient handling of the common case.
 ^ static VOID onechr(struct vars *, pchr, struct state *, struct state *);
 */
static VOID
onechr(v, c, lp, rp)
struct vars *v;
pchr c;
struct state *lp;
struct state *rp;
{
	if (!(v->cflags&REG_ICASE)) {
		newarc(v->nfa, PLAIN, subcolor(v->cm, c), lp, rp);
		return;
	}

	/* rats, need general case anyway... */
	dovec(v, allcases(v, c), lp, rp);
}

/*
 - dovec - fill in arcs for each element of a cvec
 * This one has to handle the messy cases, like MCCEs and MCCE leaders.
 ^ static VOID dovec(struct vars *, struct cvec *, struct state *,
 ^ 	struct state *);
 */
static VOID
dovec(v, cv, lp, rp)
struct vars *v;
struct cvec *cv;
struct state *lp;
struct state *rp;
{
	chr ch, from, to;
	celt ce;
	chr *p;
	int i;
	color co;
	struct cvec *leads;
	struct arc *a;
	struct arc *pa;		/* arc in prototype */
	struct state *s;
	struct state *ps;	/* state in prototype */

	/* need a place to store leaders, if any */
	if (nmcces(v) > 0) {
		assert(v->mcces != NULL);
		if (v->cv2 == NULL || v->cv2->nchrs < v->mcces->nchrs) {
			if (v->cv2 != NULL)
				free(v->cv2);
			v->cv2 = newcvec(v->mcces->nchrs, 0, v->mcces->nmcces);
			NOERR();
			leads = v->cv2;
		} else
			leads = clearcvec(v->cv2);
	} else
		leads = NULL;

	/* first, get the ordinary characters out of the way */
	for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
		ch = *p;
		if (!ISCELEADER(v, ch))
			newarc(v->nfa, PLAIN, subcolor(v->cm, ch), lp, rp);
		else {
			assert(singleton(v->cm, ch));
			assert(leads != NULL);
			if (!haschr(leads, ch))
				addchr(leads, ch);
		}
	}

	/* and the ranges */
	for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
		from = *p;
		to = *(p+1);
		while (from <= to && (ce = nextleader(v, from, to)) != NOCELT) {
			if (from < ce)
				subrange(v, from, ce - 1, lp, rp);
			assert(singleton(v->cm, ce));
			assert(leads != NULL);
			if (!haschr(leads, ce))
				addchr(leads, ce);
			from = ce + 1;
		}
		if (from <= to)
			subrange(v, from, to, lp, rp);
	}

	if ((leads == NULL || leads->nchrs == 0) && cv->nmcces == 0)
		return;

	/* deal with the MCCE leaders */
	NOTE(REG_ULOCALE);
	for (p = leads->chrs, i = leads->nchrs; i > 0; p++, i--) {
		co = GETCOLOR(v->cm, *p);
		a = findarc(lp, PLAIN, co);
		if (a != NULL)
			s = a->to;
		else {
			s = newstate(v->nfa);
			NOERR();
			newarc(v->nfa, PLAIN, co, lp, s);
			NOERR();
		}
		pa = findarc(v->mccepbegin, PLAIN, co);
		assert(pa != NULL);
		ps = pa->to;
		newarc(v->nfa, '$', 1, s, rp);
		newarc(v->nfa, '$', 0, s, rp);
		colorcomplement(v->nfa, v->cm, AHEAD, ps, s, rp);
		NOERR();
	}

	/* and the MCCEs */
	for (i = 0; i < cv->nmcces; i++) {
		p = cv->mcces[i];
		assert(singleton(v->cm, *p));
		ch = *p++;
		co = GETCOLOR(v->cm, ch);
		a = findarc(lp, PLAIN, co);
		if (a != NULL)
			s = a->to;
		else {
			s = newstate(v->nfa);
			NOERR();
			newarc(v->nfa, PLAIN, co, lp, s);
			NOERR();
		}
		assert(*p != 0);	/* at least two chars */
		assert(singleton(v->cm, *p));
		ch = *p++;
		co = GETCOLOR(v->cm, ch);
		assert(*p == 0);	/* and only two, for now */
		newarc(v->nfa, PLAIN, co, s, rp);
		NOERR();
	}
}

/*
 - nextleader - find next MCCE leader within range
 ^ static celt nextleader(struct vars *, pchr, pchr);
 */
static celt			/* NOCELT means none */
nextleader(v, from, to)
struct vars *v;
pchr from;
pchr to;
{
	int i;
	chr *p;
	chr ch;
	celt it = NOCELT;

	if (v->mcces == NULL)
		return it;

	for (i = v->mcces->nchrs, p = v->mcces->chrs; i > 0; i--, p++) {
		ch = *p;
		if (from <= ch && ch <= to)
			if (it == NOCELT || ch < it)
				it = ch;
	}
	return it;
}

/*
 - wordchrs - set up word-chr list for word-boundary stuff, if needed
 * The list is kept as a bunch of arcs between two dummy states; it's
 * disposed of by the unreachable-states sweep in NFA optimization.
 * Does NEXT().  Must not be called from any unusual lexical context.
 * This should be reconciled with the \w etc. handling in lex.c, and
 * should be cleaned up to reduce dependencies on input scanning.
 ^ static VOID wordchrs(struct vars *);
 */
static VOID
wordchrs(v)
struct vars *v;
{
	struct state *left;
	struct state *right;

	if (v->wordchrs != NULL) {
		NEXT();		/* for consistency */
		return;
	}

	left = newstate(v->nfa);
	right = newstate(v->nfa);
	NOERR();
	/* fine point:  implemented with [::], and lexer will set REG_ULOCALE */
	lexword(v);
	NEXT();
	assert(v->savenow != NULL && SEE('['));
	bracket(v, left, right);
	assert((v->savenow != NULL && SEE(']')) || ISERR());
	NEXT();
	NOERR();
	v->wordchrs = left;
}

/*
 - subre - allocate a subre
 ^ static struct subre *subre(struct vars *, int, int, struct state *,
 ^	struct state *);
 */
static struct subre *
subre(v, op, flags, begin, end)
struct vars *v;
int op;
int flags;
struct state *begin;
struct state *end;
{
	struct subre *ret;

	ret = v->treefree;
	if (ret != NULL)
		v->treefree = ret->left;
	else {
		ret = (struct subre *)MALLOC(sizeof(struct subre));
		if (ret == NULL) {
			ERR(REG_ESPACE);
			return NULL;
		}
		ret->chain = v->treechain;
		v->treechain = ret;
	}

	assert(strchr("|.b(=", op) != NULL);

	ret->op = op;
	ret->flags = flags;
	ret->retry = 0;
	ret->subno = 0;
	ret->min = ret->max = 1;
	ret->left = NULL;
	ret->right = NULL;
	ret->begin = begin;
	ret->end = end;
	ZAPCNFA(ret->cnfa);

	return ret;
}

/*
 - freesubre - free a subRE subtree
 ^ static VOID freesubre(struct vars *, struct subre *);
 */
static VOID
freesubre(v, sr)
struct vars *v;			/* might be NULL */
struct subre *sr;
{
	if (sr == NULL)
		return;

	if (sr->left != NULL)
		freesubre(v, sr->left);
	if (sr->right != NULL)
		freesubre(v, sr->right);

	freesrnode(v, sr);
}

/*
 - freesrnode - free one node in a subRE subtree
 ^ static VOID freesrnode(struct vars *, struct subre *);
 */
static VOID
freesrnode(v, sr)
struct vars *v;			/* might be NULL */
struct subre *sr;
{
	if (sr == NULL)
		return;

	if (!NULLCNFA(sr->cnfa))
		freecnfa(&sr->cnfa);
	sr->flags = 0;

	if (v != NULL) {
		sr->left = v->treefree;
		v->treefree = sr;
	} else
		FREE(sr);
}

/*
 - optst - optimize a subRE subtree
 ^ static VOID optst(struct vars *, struct subre *);
 */
static VOID
optst(v, t)
struct vars *v;
struct subre *t;
{
	if (t == NULL)
		return;

	/* preference cleanup and analysis */
	if (t->flags&SHORTER)
		v->usedshorter = 1;

	/* recurse through children */
	if (t->left != NULL)
		optst(v, t->left);
	if (t->right != NULL)
		optst(v, t->right);
}

/*
 - numst - number tree nodes (assigning retry indexes)
 ^ static int numst(struct subre *, int);
 */
static int			/* next number */
numst(t, start)
struct subre *t;
int start;			/* starting point for subtree numbers */
{
	int i;

	assert(t != NULL);

	i = start;
	t->retry = (short)i++;
	if (t->left != NULL)
		i = numst(t->left, i);
	if (t->right != NULL)
		i = numst(t->right, i);
	return i;
}

/*
 - markst - mark tree nodes as INUSE
 ^ static VOID markst(struct subre *);
 */
static VOID
markst(t)
struct subre *t;
{
	assert(t != NULL);

	t->flags |= INUSE;
	if (t->left != NULL)
		markst(t->left);
	if (t->right != NULL)
		markst(t->right);
}

/*
 - cleanst - free any tree nodes not marked INUSE
 ^ static VOID cleanst(struct vars *);
 */
static VOID
cleanst(v)
struct vars *v;
{
	struct subre *t;
	struct subre *next;

	for (t = v->treechain; t != NULL; t = next) {
		next = t->chain;
		if (!(t->flags&INUSE))
			FREE(t);
	}
	v->treechain = NULL;
	v->treefree = NULL;		/* just on general principles */
}

/*
 - nfatree - turn a subRE subtree into a tree of compacted NFAs
 ^ static int nfatree(struct vars *, struct subre *, FILE *);
 */
static int			/* optimize results from top node */
nfatree(v, t, f)
struct vars *v;
struct subre *t;
FILE *f;			/* for debug output */
{
	assert(t != NULL && t->begin != NULL);

	if (t->left != NULL)
		(DISCARD)nfatree(v, t->left, f);
	if (t->right != NULL)
		(DISCARD)nfatree(v, t->right, f);

	return nfanode(v, t, f);
}

/*
 - nfanode - do one NFA for nfatree
 ^ static int nfanode(struct vars *, struct subre *, FILE *);
 */
static int			/* optimize results */
nfanode(v, t, f)
struct vars *v;
struct subre *t;
FILE *f;			/* for debug output */
{
	struct nfa *nfa;
	int ret = 0;

	assert(t->begin != NULL);

	nfa = newnfa(v, v->cm, v->nfa);
	NOERRZ();
	dupnfa(nfa, t->begin, t->end, nfa->init, nfa->final);
	if (!ISERR()) {
		specialcolors(nfa);
		ret = optimize(nfa, f);
	}
	if (!ISERR())
		compact(nfa, &t->cnfa);

	freenfa(nfa);
	return ret;
}

/*
 - newlacon - allocate a lookahead-constraint subRE
 ^ static int newlacon(struct vars *, struct state *, struct state *, int);
 */
static int			/* lacon number */
newlacon(v, begin, end, pos)
struct vars *v;
struct state *begin;
struct state *end;
int pos;
{
	int n;
	struct subre *sub;

	if (v->nlacons == 0) {
		v->lacons = (struct subre *)MALLOC(2 * sizeof(struct subre));
		n = 1;		/* skip 0th */
		v->nlacons = 2;
	} else {
		v->lacons = (struct subre *)REALLOC(v->lacons,
					(v->nlacons+1)*sizeof(struct subre));
		n = v->nlacons++;
	}
	if (v->lacons == NULL) {
		ERR(REG_ESPACE);
		return 0;
	}
	sub = &v->lacons[n];
	sub->begin = begin;
	sub->end = end;
	sub->subno = pos;
	ZAPCNFA(sub->cnfa);
	return n;
}

/*
 - freelacons - free lookahead-constraint subRE vector
 ^ static VOID freelacons(struct subre *, int);
 */
static VOID
freelacons(subs, n)
struct subre *subs;
int n;
{
	struct subre *sub;
	int i;

	assert(n > 0);
	for (sub = subs + 1, i = n - 1; i > 0; sub++, i--)	/* no 0th */
		if (!NULLCNFA(sub->cnfa))
			freecnfa(&sub->cnfa);
	FREE(subs);
}

/*
 - rfree - free a whole RE (insides of regfree)
 ^ static VOID rfree(regex_t *);
 */
static VOID
rfree(re)
regex_t *re;
{
	struct guts *g;

	if (re == NULL || re->re_magic != REMAGIC)
		return;

	re->re_magic = 0;	/* invalidate RE */
	g = (struct guts *)re->re_guts;
	re->re_guts = NULL;
	re->re_fns = NULL;
	g->magic = 0;
	freecm(&g->cmap);
	if (g->tree != NULL)
		freesubre((struct vars *)NULL, g->tree);
	if (g->lacons != NULL)
		freelacons(g->lacons, g->nlacons);
	if (!NULLCNFA(g->search))
		freecnfa(&g->search);
	FREE(g);
}

/*
 - dump - dump an RE in human-readable form
 ^ static VOID dump(regex_t *, FILE *);
 */
static VOID
dump(re, f)
regex_t *re;
FILE *f;
{
#ifdef REG_DEBUG
	struct guts *g;
	int i;

	if (re->re_magic != REMAGIC)
		fprintf(f, "bad magic number (0x%x not 0x%x)\n", re->re_magic,
								REMAGIC);
	if (re->re_guts == NULL) {
		fprintf(f, "NULL guts!!!\n");
		return;
	}
	g = (struct guts *)re->re_guts;
	if (g->magic != GUTSMAGIC)
		fprintf(f, "bad guts magic number (0x%x not 0x%x)\n", g->magic,
								GUTSMAGIC);

	fprintf(f, "nsub %d, info 0%o, csize %d, ntree %d, usedshort %d\n", 
		re->re_nsub, re->re_info, re->re_csize, g->ntree,
		g->usedshorter);

	dumpcolors(&g->cmap, f);
	if (!NULLCNFA(g->search)) {
		printf("search:\n");
		dumpcnfa(&g->search, f);
	}
	for (i = 1; i < g->nlacons; i++) {
		fprintf(f, "la%d (%s):\n", i,
				(g->lacons[i].subno) ? "positive" : "negative");
		dumpcnfa(&g->lacons[i].cnfa, f);
	}
	dumpst(g->tree, f, 0);
#endif
}

/*
 - dumpst - dump a subRE tree
 ^ static VOID dumpst(struct subre *, FILE *, int);
 */
static VOID
dumpst(t, f, nfapresent)
struct subre *t;
FILE *f;
int nfapresent;			/* is the original NFA still around? */
{
	if (t == NULL)
		fprintf(f, "null tree\n");
	else
		stdump(t, f, nfapresent, 0);
	fflush(f);
}

/*
 - stdump - recursive guts of dumpst
 ^ static VOID stdump(struct subre *, FILE *, int, int);
 */
static VOID
stdump(t, f, nfapresent, level)
struct subre *t;
FILE *f;
int nfapresent;			/* is the original NFA still around? */
int level;
{
	int i;
#	define	RTSEP	"  "

	for (i = 0; i < level; i++)
		fprintf(f, RTSEP);
	fprintf(f, "%c (", t->op);
	if (t->flags&LONGER)
		fprintf(f, "L");
	if (t->flags&SHORTER)
		fprintf(f, "S");
	if (t->flags&MIXED)
		fprintf(f, "M");
	if (t->flags&CAP)
		fprintf(f, "c");
	if (t->flags&BACKR)
		fprintf(f, "b");
	if (!(t->flags&INUSE))
		fprintf(f, "!u");
	fprintf(f, ") r%d", t->retry);
	if (t->subno != 0)
		fprintf(f, " #%d", t->subno);
	if (t->min != 1 || t->max != 1) {
		fprintf(f, "{%d,", t->min);
		if (t->max != INFINITY)
			fprintf(f, "%d", t->max);
		fprintf(f, "}");
	}
	if (nfapresent)
		fprintf(f, " %ld-%ld", (long)t->begin->no, (long)t->end->no);
	if (!NULLCNFA(t->cnfa))
		fprintf(f, ":");
	fprintf(f, "\n");
	if (t->left != NULL)
		stdump(t->left, f, nfapresent, level+1);
	if (!NULLCNFA(t->cnfa))
		dumpcnfa(&t->cnfa, f);
	if (t->right != NULL)
		stdump(t->right, f, nfapresent, level+1);
}

#include "regc_lex.c"
#include "regc_color.c"
#include "regc_nfa.c"
#include "regc_cvec.c"
#include "regc_locale.c"

Added generic/regcustom.h.











































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/* headers (which also pick up the standard ones, or equivalents) */
#include "tclInt.h"

/* overrides for regguts.h definitions */
/* function-pointer declarations */
#define	FUNCPTR(name, args)	(*name) _ANSI_ARGS_(args)
#define	MALLOC(n)		ckalloc(n)
#define	FREE(p)			ckfree(VS(p))
#define	REALLOC(p,n)		ckrealloc(VS(p),n)



/*
 * Do not insert extras between the "begin" and "end" lines -- this
 * chunk is automatically extracted to be fitted into regex.h.
 */
/* --- begin --- */
/* ensure certain things don't sneak in from system headers */
#ifdef __REG_WIDE_T
#undef __REG_WIDE_T
#endif
#ifdef __REG_WIDE_COMPILE
#undef __REG_WIDE_COMPILE
#endif
#ifdef __REG_WIDE_EXEC
#undef __REG_WIDE_EXEC
#endif
#ifdef __REG_REGOFF_T
#undef __REG_REGOFF_T
#endif
#ifdef __REG_VOID_T
#undef __REG_VOID_T
#endif
#ifdef __REG_CONST
#undef __REG_CONST
#endif
/* interface types */
#define	__REG_WIDE_T	Tcl_UniChar
#define	__REG_REGOFF_T	long	/* not really right, but good enough... */
#define	__REG_VOID_T	VOID
#define	__REG_CONST	CONST
/* names and declarations */
#define	__REG_WIDE_COMPILE	TclReComp
#define	__REG_WIDE_EXEC		TclReExec
#ifndef __REG_NOFRONT
#define	__REG_NOFRONT		/* don't want regcomp() and regexec() */
#endif
#ifndef __REG_NOCHAR
#define	__REG_NOCHAR		/* or the char versions */
#endif
#define	regfree		TclReFree
#define	regerror	TclReError
/* --- end --- */



/* internal character type and related */
typedef Tcl_UniChar chr;	/* the type itself */
typedef int pchr;		/* what it promotes to */
typedef unsigned uchr;		/* unsigned type that will hold a chr */
typedef int celt;		/* type to hold chr, MCCE number, or NOCELT */
#define	NOCELT	(-1)		/* celt value which is not valid chr or MCCE */
#define	CHR(c)	(UCHAR(c))	/* turn char literal into chr literal */
#define	DIGITVAL(c)	((c)-'0')	/* turn chr digit into its value */
#define	CHRBITS	16		/* bits in a chr; must not use sizeof */
#define	CHR_MIN	0x0000		/* smallest and largest chr; the value */
#define	CHR_MAX	0xffff		/*  CHR_MAX-CHR_MIN+1 should fit in uchr */

/* functions operating on chr */
#define	iscalnum(x)	Tcl_UniCharIsAlnum(x)
#define	iscalpha(x)	Tcl_UniCharIsAlpha(x)
#define	iscdigit(x)	Tcl_UniCharIsDigit(x)
#define	iscspace(x)	Tcl_UniCharIsSpace(x)

/* name the external functions */
#define	compile		TclReComp
#define	exec		TclReExec

/* enable/disable debugging code (by whether REG_DEBUG is defined or not) */
#ifdef notdef
#define	REG_DEBUG	/* */
#endif

/* and pick up the standard header */
#include "regex.h"

Added generic/rege_dfa.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
/*
 * DFA routines
 * This file is #included by regexec.c.
 */

/*
 - longest - longest-preferred matching engine
 ^ static chr *longest(struct vars *, struct dfa *, chr *, chr *);
 */
static chr *			/* endpoint, or NULL */
longest(v, d, start, stop)
struct vars *v;			/* used only for debug and exec flags */
struct dfa *d;
chr *start;			/* where the match should start */
chr *stop;			/* match must end at or before here */
{
	chr *cp;
	chr *realstop = (stop == v->stop) ? stop : stop + 1;
	color co;
	struct sset *css;
	struct sset *ss;
	chr *post;
	int i;
	struct colormap *cm = d->cm;

	/* initialize */
	css = initialize(v, d, start);
	cp = start;

	/* startup */
	FDEBUG(("+++ startup +++\n"));
	if (cp == v->start) {
		co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
		FDEBUG(("color %ld\n", (long)co));
	} else {
		co = GETCOLOR(cm, *(cp - 1));
		FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
	}
	css = miss(v, d, css, co, cp, start);
	if (css == NULL)
		return NULL;
	css->lastseen = cp;

	/* main loop */
	if (v->eflags&REG_FTRACE)
		while (cp < realstop) {
			FDEBUG(("+++ at c%d +++\n", css - d->ssets));
			co = GETCOLOR(cm, *cp);
			FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
			ss = css->outs[co];
			if (ss == NULL) {
				ss = miss(v, d, css, co, cp+1, start);
				if (ss == NULL)
					break;	/* NOTE BREAK OUT */
			}
			cp++;
			ss->lastseen = cp;
			css = ss;
		}
	else
		while (cp < realstop) {
			co = GETCOLOR(cm, *cp);
			ss = css->outs[co];
			if (ss == NULL) {
				ss = miss(v, d, css, co, cp+1, start);
				if (ss == NULL)
					break;	/* NOTE BREAK OUT */
			}
			cp++;
			ss->lastseen = cp;
			css = ss;
		}

	/* shutdown */
	FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
	if (cp == v->stop && stop == v->stop) {
		co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
		FDEBUG(("color %ld\n", (long)co));
		ss = miss(v, d, css, co, cp, start);
		/* special case:  match ended at eol? */
		if (ss != NULL && (ss->flags&POSTSTATE))
			return cp;
		else if (ss != NULL)
			ss->lastseen = cp;	/* to be tidy */
	}

	/* find last match, if any */
	post = d->lastpost;
	for (ss = d->ssets, i = 0; i < d->nssused; ss++, i++)
		if ((ss->flags&POSTSTATE) && post != ss->lastseen &&
					(post == NULL || post < ss->lastseen))
			post = ss->lastseen;
	if (post != NULL)		/* found one */
		return post - 1;

	return NULL;
}

/*
 - shortest - shortest-preferred matching engine
 ^ static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *,
 ^ 	chr **);
 */
static chr *			/* endpoint, or NULL */
shortest(v, d, start, min, max, coldp)
struct vars *v;			/* used only for debug and exec flags */
struct dfa *d;
chr *start;			/* where the match should start */
chr *min;			/* match must end at or after here */
chr *max;			/* match must end at or before here */
chr **coldp;			/* store coldstart pointer here, if nonNULL */
{
	chr *cp;
	chr *realmin = (min == v->stop) ? min : min + 1;
	chr *realmax = (max == v->stop) ? max : max + 1;
	color co;
	struct sset *css;
	struct sset *ss;
	struct colormap *cm = d->cm;
	chr *nopr;
	int i;

	/* initialize */
	css = initialize(v, d, start);
	cp = start;

	/* startup */
	FDEBUG(("--- startup ---\n"));
	if (cp == v->start) {
		co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
		FDEBUG(("color %ld\n", (long)co));
	} else {
		co = GETCOLOR(cm, *(cp - 1));
		FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
	}
	css = miss(v, d, css, co, cp, start);
	if (css == NULL)
		return NULL;
	css->lastseen = cp;
	ss = css;

	/* main loop */
	if (v->eflags&REG_FTRACE)
		while (cp < realmax) {
			FDEBUG(("--- at c%d ---\n", css - d->ssets));
			co = GETCOLOR(cm, *cp);
			FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
			ss = css->outs[co];
			if (ss == NULL) {
				ss = miss(v, d, css, co, cp+1, start);
				if (ss == NULL)
					break;	/* NOTE BREAK OUT */
			}
			cp++;
			ss->lastseen = cp;
			css = ss;
			if ((ss->flags&POSTSTATE) && cp >= realmin)
				break;		/* NOTE BREAK OUT */
		}
	else
		while (cp < realmax) {
			co = GETCOLOR(cm, *cp);
			ss = css->outs[co];
			if (ss == NULL) {
				ss = miss(v, d, css, co, cp+1, start);
				if (ss == NULL)
					break;	/* NOTE BREAK OUT */
			}
			cp++;
			ss->lastseen = cp;
			css = ss;
			if ((ss->flags&POSTSTATE) && cp >= realmin)
				break;		/* NOTE BREAK OUT */
		}

	if (ss == NULL)
		return NULL;
	else if (ss->flags&POSTSTATE) {
		assert(cp >= realmin);
		cp--;
	} else if (cp == v->stop && max == v->stop) {
		co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
		FDEBUG(("color %ld\n", (long)co));
		ss = miss(v, d, css, co, cp, start);
		/* match might have ended at eol */
	}

	if (ss == NULL || !(ss->flags&POSTSTATE))
		return NULL;

	/* find last no-progress state set, if any */
	nopr = d->lastnopr;
	for (ss = d->ssets, i = 0; i < d->nssused; ss++, i++)
		if ((ss->flags&NOPROGRESS) && nopr != ss->lastseen &&
					(nopr == NULL || nopr < ss->lastseen))
			nopr = ss->lastseen;
	assert(nopr != NULL);
	if (coldp != NULL)
		*coldp = (nopr == v->start) ? nopr : nopr-1;
	return cp;
}

/*
 - newdfa - set up a fresh DFA
 ^ static struct dfa *newdfa(struct vars *, struct cnfa *,
 ^ 	struct colormap *, struct smalldfa *);
 */
static struct dfa *
newdfa(v, cnfa, cm, small)
struct vars *v;
struct cnfa *cnfa;
struct colormap *cm;
struct smalldfa *small;		/* preallocated space, may be NULL */
{
	struct dfa *d;
	size_t nss = cnfa->nstates * 2;
	int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
	struct smalldfa *smallwas = small;

	assert(cnfa != NULL && cnfa->nstates != 0);

	if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
		assert(wordsper == 1);
		if (small == NULL) {
			small = (struct smalldfa *)MALLOC(
						sizeof(struct smalldfa));
			if (small == NULL) {
				ERR(REG_ESPACE);
				return NULL;
			}
		}
		d = &small->dfa;
		d->ssets = small->ssets;
		d->statesarea = small->statesarea;
		d->work = &d->statesarea[nss];
		d->outsarea = small->outsarea;
		d->incarea = small->incarea;
		d->cptsmalloced = 0;
		d->mallocarea = (smallwas == NULL) ? (char *)small : NULL;
	} else {
		d = (struct dfa *)MALLOC(sizeof(struct dfa));
		if (d == NULL) {
			ERR(REG_ESPACE);
			return NULL;
		}
		d->ssets = (struct sset *)MALLOC(nss * sizeof(struct sset));
		d->statesarea = (unsigned *)MALLOC((nss+WORK) * wordsper *
							sizeof(unsigned));
		d->work = &d->statesarea[nss * wordsper];
		d->outsarea = (struct sset **)MALLOC(nss * cnfa->ncolors *
							sizeof(struct sset *));
		d->incarea = (struct arcp *)MALLOC(nss * cnfa->ncolors *
							sizeof(struct arcp));
		d->cptsmalloced = 1;
		d->mallocarea = (char *)d;
		if (d->ssets == NULL || d->statesarea == NULL ||
				d->outsarea == NULL || d->incarea == NULL) {
			freedfa(d);
			ERR(REG_ESPACE);
			return NULL;
		}
	}

	d->nssets = (v->eflags&REG_SMALL) ? 7 : nss;
	d->nssused = 0;
	d->nstates = cnfa->nstates;
	d->ncolors = cnfa->ncolors;
	d->wordsper = wordsper;
	d->cnfa = cnfa;
	d->cm = cm;
	d->lastpost = NULL;
	d->lastnopr = NULL;
	d->search = d->ssets;

	/* initialization of sset fields is done as needed */

	return d;
}

/*
 - freedfa - free a DFA
 ^ static VOID freedfa(struct dfa *);
 */
static VOID
freedfa(d)
struct dfa *d;
{
	if (d->cptsmalloced) {
		if (d->ssets != NULL)
			FREE(d->ssets);
		if (d->statesarea != NULL)
			FREE(d->statesarea);
		if (d->outsarea != NULL)
			FREE(d->outsarea);
		if (d->incarea != NULL)
			FREE(d->incarea);
	}

	if (d->mallocarea != NULL)
		FREE(d->mallocarea);
}

/*
 - hash - construct a hash code for a bitvector
 * There are probably better ways, but they're more expensive.
 ^ static unsigned hash(unsigned *, int);
 */
static unsigned
hash(uv, n)
unsigned *uv;
int n;
{
	int i;
	unsigned h;

	h = 0;
	for (i = 0; i < n; i++)
		h ^= uv[i];
	return h;
}

/*
 - initialize - hand-craft a cache entry for startup, otherwise get ready
 ^ static struct sset *initialize(struct vars *, struct dfa *, chr *);
 */
static struct sset *
initialize(v, d, start)
struct vars *v;			/* used only for debug flags */
struct dfa *d;
chr *start;
{
	struct sset *ss;
	int i;

	/* is previous one still there? */
	if (d->nssused > 0 && (d->ssets[0].flags&STARTER))
		ss = &d->ssets[0];
	else {				/* no, must (re)build it */
		ss = getvacant(v, d, start, start);
		for (i = 0; i < d->wordsper; i++)
			ss->states[i] = 0;
		BSET(ss->states, d->cnfa->pre);
		ss->hash = HASH(ss->states, d->wordsper);
		assert(d->cnfa->pre != d->cnfa->post);
		ss->flags = STARTER|LOCKED|NOPROGRESS;
		/* lastseen dealt with below */
	}

	for (i = 0; i < d->nssused; i++)
		d->ssets[i].lastseen = NULL;
	ss->lastseen = start;		/* maybe untrue, but harmless */
	d->lastpost = NULL;
	d->lastnopr = NULL;
	return ss;
}

/*
 - miss - handle a cache miss
 ^ static struct sset *miss(struct vars *, struct dfa *, struct sset *,
 ^ 	pcolor, chr *, chr *);
 */
static struct sset *		/* NULL if goes to empty set */
miss(v, d, css, co, cp, start)
struct vars *v;			/* used only for debug flags */
struct dfa *d;
struct sset *css;
pcolor co;
chr *cp;			/* next chr */
chr *start;			/* where the attempt got started */
{
	struct cnfa *cnfa = d->cnfa;
	int i;
	unsigned h;
	struct carc *ca;
	struct sset *p;
	int ispost;
	int noprogress;
	int gotstate;
	int dolacons;
	int didlacons;

	/* for convenience, we can be called even if it might not be a miss */
	if (css->outs[co] != NULL) {
		FDEBUG(("hit\n"));
		return css->outs[co];
	}
	FDEBUG(("miss\n"));

	/* first, what set of states would we end up in? */
	for (i = 0; i < d->wordsper; i++)
		d->work[i] = 0;
	ispost = 0;
	noprogress = 1;
	gotstate = 0;
	for (i = 0; i < d->nstates; i++)
		if (ISBSET(css->states, i))
			for (ca = cnfa->states[i]+1; ca->co != COLORLESS; ca++)
				if (ca->co == co) {
					BSET(d->work, ca->to);
					gotstate = 1;
					if (ca->to == cnfa->post)
						ispost = 1;
					if (!cnfa->states[ca->to]->co)
						noprogress = 0;
					FDEBUG(("%d -> %d\n", i, ca->to));
				}
	dolacons = (gotstate) ? (cnfa->flags&HASLACONS) : 0;
	didlacons = 0;
	while (dolacons) {		/* transitive closure */
		dolacons = 0;
		for (i = 0; i < d->nstates; i++)
			if (ISBSET(d->work, i))
				for (ca = cnfa->states[i]+1; ca->co != COLORLESS;
									ca++)
					if (ca->co > cnfa->ncolors &&
						!ISBSET(d->work, ca->to) &&
							lacon(v, cnfa, cp,
								ca->co)) {
						BSET(d->work, ca->to);
						dolacons = 1;
						didlacons = 1;
						if (ca->to == cnfa->post)
							ispost = 1;
						if (!cnfa->states[ca->to]->co)
							noprogress = 0;
						FDEBUG(("%d :> %d\n",i,ca->to));
					}
	}
	if (!gotstate)
		return NULL;
	h = HASH(d->work, d->wordsper);

	/* next, is that in the cache? */
	for (p = d->ssets, i = d->nssused; i > 0; p++, i--)
		if (HIT(h, d->work, p, d->wordsper)) {
#ifndef xxx
p->hash == h && 
memcmp(VS(d->work), VS(p->states),
					d->wordsper*sizeof(unsigned)) == 0) {
#endif
			FDEBUG(("cached c%d\n", p - d->ssets));
			break;			/* NOTE BREAK OUT */
		}
	if (i == 0) {		/* nope, need a new cache entry */
		p = getvacant(v, d, cp, start);
		assert(p != css);
		for (i = 0; i < d->wordsper; i++)
			p->states[i] = d->work[i];
		p->hash = h;
		p->flags = (ispost) ? POSTSTATE : 0;
		if (noprogress)
			p->flags |= NOPROGRESS;
		/* lastseen to be dealt with by caller */
	}

	if (!didlacons) {		/* lookahead conds. always cache miss */
		css->outs[co] = p;
		css->inchain[co] = p->ins;
		p->ins.ss = css;
		p->ins.co = (color)co;
	}
	return p;
}

/*
 - lacon - lookahead-constraint checker for miss()
 ^ static int lacon(struct vars *, struct cnfa *, chr *, pcolor);
 */
static int			/* predicate:  constraint satisfied? */
lacon(v, pcnfa, cp, co)
struct vars *v;
struct cnfa *pcnfa;		/* parent cnfa */
chr *cp;
pcolor co;			/* "color" of the lookahead constraint */
{
	int n;
	struct subre *sub;
	struct dfa *d;
	struct smalldfa sd;
	chr *end;

	n = co - pcnfa->ncolors;
	assert(n < v->g->nlacons && v->g->lacons != NULL);
	FDEBUG(("=== testing lacon %d\n", n));
	sub = &v->g->lacons[n];
	d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
	if (d == NULL) {
		ERR(REG_ESPACE);
		return 0;
	}
	end = longest(v, d, cp, v->stop);
	freedfa(d);
	FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
	return (sub->subno) ? (end != NULL) : (end == NULL);
}

/*
 - getvacant - get a vacant state set
 * This routine clears out the inarcs and outarcs, but does not otherwise
 * clear the innards of the state set -- that's up to the caller.
 ^ static struct sset *getvacant(struct vars *, struct dfa *, chr *, chr *);
 */
static struct sset *
getvacant(v, d, cp, start)
struct vars *v;			/* used only for debug flags */
struct dfa *d;
chr *cp;
chr *start;
{
	int i;
	struct sset *ss;
	struct sset *p;
	struct arcp ap;
	struct arcp lastap;
	color co;

	ss = pickss(v, d, cp, start);
	assert(!(ss->flags&LOCKED));

	/* clear out its inarcs, including self-referential ones */
	ap = ss->ins;
	while ((p = ap.ss) != NULL) {
		co = ap.co;
		FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long)co));
		p->outs[co] = NULL;
		ap = p->inchain[co];
		p->inchain[co].ss = NULL;	/* paranoia */
	}
	ss->ins.ss = NULL;

	/* take it off the inarc chains of the ssets reached by its outarcs */
	for (i = 0; i < d->ncolors; i++) {
		p = ss->outs[i];
		assert(p != ss);		/* not self-referential */
		if (p == NULL)
			continue;		/* NOTE CONTINUE */
		FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
		if (p->ins.ss == ss && p->ins.co == i)
			p->ins = ss->inchain[i];
		else {
			assert(p->ins.ss != NULL);
			for (ap = p->ins; ap.ss != NULL &&
						!(ap.ss == ss && ap.co == i);
						ap = ap.ss->inchain[ap.co])
				lastap = ap;
			assert(ap.ss != NULL);
			lastap.ss->inchain[lastap.co] = ss->inchain[i];
		}
		ss->outs[i] = NULL;
		ss->inchain[i].ss = NULL;
	}

	/* if ss was a success state, may need to remember location */
	if ((ss->flags&POSTSTATE) && ss->lastseen != d->lastpost &&
			(d->lastpost == NULL || d->lastpost < ss->lastseen))
		d->lastpost = ss->lastseen;

	/* likewise for a no-progress state */
	if ((ss->flags&NOPROGRESS) && ss->lastseen != d->lastnopr &&
			(d->lastnopr == NULL || d->lastnopr < ss->lastseen))
		d->lastnopr = ss->lastseen;

	return ss;
}

/*
 - pickss - pick the next stateset to be used
 ^ static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
 */
static struct sset *
pickss(v, d, cp, start)
struct vars *v;			/* used only for debug flags */
struct dfa *d;
chr *cp;
chr *start;
{
	int i;
	struct sset *ss;
	struct sset *end;
	chr *ancient;

	/* shortcut for cases where cache isn't full */
	if (d->nssused < d->nssets) {
		i = d->nssused;
		d->nssused++;
		ss = &d->ssets[i];
		FDEBUG(("new c%d\n", i));
		/* set up innards */
		ss->states = &d->statesarea[i * d->wordsper];
		ss->flags = 0;
		ss->ins.ss = NULL;
		ss->ins.co = WHITE;		/* give it some value */
		ss->outs = &d->outsarea[i * d->ncolors];
		ss->inchain = &d->incarea[i * d->ncolors];
		for (i = 0; i < d->ncolors; i++) {
			ss->outs[i] = NULL;
			ss->inchain[i].ss = NULL;
		}
		return ss;
	}

	/* look for oldest, or old enough anyway */
	if (cp - start > d->nssets*2/3)		/* oldest 33% are expendable */
		ancient = cp - d->nssets*2/3;
	else
		ancient = start;
	for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
		if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
							!(ss->flags&LOCKED)) {
			d->search = ss + 1;
			FDEBUG(("replacing c%d\n", ss - d->ssets));
			return ss;
		}
	for (ss = d->ssets, end = d->search; ss < end; ss++)
		if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
							!(ss->flags&LOCKED)) {
			d->search = ss + 1;
			FDEBUG(("replacing c%d\n", ss - d->ssets));
			return ss;
		}

	/* nobody's old enough?!? -- something's really wrong */
	FDEBUG(("can't find victim to replace!\n"));
	assert(NOTREACHED);
	ERR(REG_ASSERT);
	return d->ssets;
}

Added generic/regerror.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
 * regerror - error-code expansion
 */

#include "regguts.h"

/* unknown-error explanation */
static char unk[] = "*** unknown regex error code 0x%x ***";

/* struct to map among codes, code names, and explanations */
static struct rerr {
	int code;
	char *name;
	char *explain;
} rerrs[] = {
	/* the actual table is built from regex.h */
#	include "regerrs.h"
	{ -1,	"",	"oops" },	/* explanation special-cased in code */
};

/*
 - regerror - the interface to error numbers
 */
/* ARGSUSED */
size_t				/* actual space needed (including NUL) */
regerror(errcode, preg, errbuf, errbuf_size)
int errcode;			/* error code, or REG_ATOI or REG_ITOA */
CONST regex_t *preg;		/* associated regex_t (unused at present) */
char *errbuf;			/* result buffer (unless errbuf_size==0) */
size_t errbuf_size;		/* available space in errbuf, can be 0 */
{
	struct rerr *r;
	char *msg;
	char convbuf[sizeof(unk)+50];	/* 50 = plenty for int */
	size_t len;
	int icode;

	switch (errcode) {
	case REG_ATOI:		/* convert name to number */
		for (r = rerrs; r->code >= 0; r++)
			if (strcmp(r->name, errbuf) == 0)
				break;
		sprintf(convbuf, "%d", r->code);	/* -1 for unknown */
		msg = convbuf;
		break;
	case REG_ITOA:		/* convert number to name */
		icode = atoi(errbuf);	/* not our problem if this fails */
		for (r = rerrs; r->code >= 0; r++)
			if (r->code == icode)
				break;
		if (r->code >= 0)
			msg = r->name;
		else {			/* unknown; tell him the number */
			sprintf(convbuf, "REG_%u", (unsigned)icode);
			msg = convbuf;
		}
		break;
	default:		/* a real, normal error code */
		for (r = rerrs; r->code >= 0; r++)
			if (r->code == errcode)
				break;
		if (r->code >= 0)
			msg = r->explain;
		else {			/* unknown; say so */
			sprintf(convbuf, unk, errcode);
			msg = convbuf;
		}
		break;
	}

	len = strlen(msg) + 1;		/* space needed, including NUL */
	if (errbuf_size > 0) {
		if (errbuf_size > len)
			strcpy(errbuf, msg);
		else {			/* truncate to fit */
			strncpy(errbuf, msg, errbuf_size-1);
			errbuf[errbuf_size-1] = '\0';
		}
	}

	return len;
}

Added generic/regerrs.h.





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{ REG_OKAY,	"REG_OKAY",	"no errors detected" },
{ REG_NOMATCH,	"REG_NOMATCH",	"failed to match" },
{ REG_BADPAT,	"REG_BADPAT",	"invalid regexp (reg version 0.2)" },
{ REG_ECOLLATE,	"REG_ECOLLATE",	"invalid collating element" },
{ REG_ECTYPE,	"REG_ECTYPE",	"invalid character class" },
{ REG_EESCAPE,	"REG_EESCAPE",	"invalid escape \\ sequence" },
{ REG_ESUBREG,	"REG_ESUBREG",	"invalid backreference number" },
{ REG_EBRACK,	"REG_EBRACK",	"brackets [] not balanced" },
{ REG_EPAREN,	"REG_EPAREN",	"parentheses () not balanced" },
{ REG_EBRACE,	"REG_EBRACE",	"braces {} not balanced" },
{ REG_BADBR,	"REG_BADBR",	"invalid repetition count(s)" },
{ REG_ERANGE,	"REG_ERANGE",	"invalid character range" },
{ REG_ESPACE,	"REG_ESPACE",	"out of memory" },
{ REG_BADRPT,	"REG_BADRPT",	"quantifier operand invalid" },
{ REG_ASSERT,	"REG_ASSERT",	"\"can't happen\" -- you found a bug" },
{ REG_INVARG,	"REG_INVARG",	"invalid argument to regex function" },
{ REG_MIXED,	"REG_MIXED",	"character widths of regex and string differ" },
{ REG_BADOPT,	"REG_BADOPT",	"invalid embedded option" },

Added generic/regex.h.









































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
#ifndef _REGEX_H_
#define	_REGEX_H_	/* never again */
/*
 * regular expressions
 *
 * Prototypes etc. marked with "^" within comments get gathered up (and
 * possibly edited) by the regfwd program and inserted near the bottom of
 * this file.
 *
 * We offer the option of declaring one wide-character version of the
 * RE functions as well as the char versions.  To do that, define
 * __REG_WIDE_T to the type of wide characters (unfortunately, there
 * is no consensus that wchar_t is suitable) and __REG_WIDE_COMPILE and
 * __REG_WIDE_EXEC to the names to be used for the compile and execute
 * functions (suggestion:  re_Xcomp and re_Xexec, where X is a letter
 * suggestive of the wide type, e.g. re_ucomp and re_uexec for Unicode).
 * For cranky old compilers, it may be necessary to do something like:
 * #define	__REG_WIDE_COMPILE(a,b,c,d)	re_Xcomp(a,b,c,d)
 * #define	__REG_WIDE_EXEC(a,b,c,d,e,f,g)	re_Xexec(a,b,c,d,e,f,g)
 * rather than just #defining the names as parameterless macros.
 *
 * For some specialized purposes, it may be desirable to suppress the
 * declarations of the "front end" functions, regcomp() and regexec(),
 * or of the char versions of the compile and execute functions.  To
 * suppress the front-end functions, define __REG_NOFRONT.  To suppress
 * the char versions, define __REG_NOCHAR.
 *
 * The right place to do those defines (and some others you may want, see
 * below) would be <sys/types.h>.  If you don't have control of that file,
 * the right place to add your own defines to this file is marked below.
 * This is normally done automatically, by the makefile and regmkhdr, based
 * on the contents of regcustom.h.
 */



/*
 * voodoo for C++
 */
#ifdef __cplusplus
extern "C" {
#endif



/*
 * Add your own defines, if needed, here.
 */



/*
 * Location where a chunk of regcustom.h is automatically spliced into
 * this file (working from its prototype, regproto.h).
 */
/* --- begin --- */
/* ensure certain things don't sneak in from system headers */
#ifdef __REG_WIDE_T
#undef __REG_WIDE_T
#endif
#ifdef __REG_WIDE_COMPILE
#undef __REG_WIDE_COMPILE
#endif
#ifdef __REG_WIDE_EXEC
#undef __REG_WIDE_EXEC
#endif
#ifdef __REG_REGOFF_T
#undef __REG_REGOFF_T
#endif
#ifdef __REG_VOID_T
#undef __REG_VOID_T
#endif
#ifdef __REG_CONST
#undef __REG_CONST
#endif
/* interface types */
#define	__REG_WIDE_T	Tcl_UniChar
#define	__REG_REGOFF_T	long	/* not really right, but good enough... */
#define	__REG_VOID_T	VOID
#define	__REG_CONST	CONST
/* names and declarations */
#define	__REG_WIDE_COMPILE	TclReComp
#define	__REG_WIDE_EXEC		TclReExec
#ifndef __REG_NOFRONT
#define	__REG_NOFRONT		/* don't want regcomp() and regexec() */
#endif
#ifndef __REG_NOCHAR
#define	__REG_NOCHAR		/* or the char versions */
#endif
#define	regfree		TclReFree
#define	regerror	TclReError
/* --- end --- */


/*
 * interface types etc.
 */

/*
 * regoff_t has to be large enough to hold either off_t or ssize_t,
 * and must be signed; it's only a guess that long is suitable, so we
 * offer <sys/types.h> an override.
 */
#ifdef __REG_REGOFF_T
typedef __REG_REGOFF_T regoff_t;
#else
typedef long regoff_t;
#endif

/*
 * For benefit of old compilers, we offer <sys/types.h> the option of
 * overriding the `void' type used to declare nonexistent return types.
 */
#ifdef __REG_VOID_T
typedef __REG_VOID_T re_void;
#else
typedef void re_void;
#endif

/*
 * Also for benefit of old compilers, <sys/types.h> can supply a macro
 * which expands to a substitute for `const'.
 */
#ifndef __REG_CONST
#define	__REG_CONST	const
#endif



/*
 * other interface types
 */

/* the biggie, a compiled RE (or rather, a front end to same) */
typedef struct {
	int re_magic;		/* magic number */
	size_t re_nsub;		/* number of subexpressions */
	int re_info;		/* information about RE */
#		define	REG_UBACKREF		000001
#		define	REG_ULOOKAHEAD		000002
#		define	REG_UBOUNDS		000004
#		define	REG_UBRACES		000010
#		define	REG_UBSALNUM		000020
#		define	REG_UPBOTCH		000040
#		define	REG_UBBS		000100
#		define	REG_UNONPOSIX		000200
#		define	REG_UUNSPEC		000400
#		define	REG_UUNPORT		001000
#		define	REG_ULOCALE		002000
#		define	REG_UEMPTYMATCH		004000
#		define	REG_UIMPOSSIBLE		010000
	int re_csize;		/* sizeof(character) */
	char *re_endp;		/* backward compatibility kludge */
	/* the rest is opaque pointers to hidden innards */
	char *re_guts;		/* `char *' is more portable than `void *' */
	char *re_fns;
} regex_t;

/* result reporting (may acquire more fields later) */
typedef struct {
	regoff_t rm_so;		/* start of substring */
	regoff_t rm_eo;		/* end of substring */
} regmatch_t;

/* supplementary control and reporting (placeholder for later work) */
typedef struct {
	int rm_dummy;
} rm_detail_t;



/*
 * compilation
 ^ #ifndef __REG_NOCHAR
 ^ int re_comp(regex_t *, __REG_CONST char *, size_t, int);
 ^ #endif
 ^ #ifndef __REG_NOFRONT
 ^ int regcomp(regex_t *, __REG_CONST char *, int);
 ^ #endif
 ^ #ifdef __REG_WIDE_T
 ^ int __REG_WIDE_COMPILE(regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int);
 ^ #endif
 */
#define	REG_BASIC	000000	/* BREs (convenience) */
#define	REG_EXTENDED	000001	/* EREs */
#define	REG_ADVF	000002	/* advanced features in EREs */
#define	REG_ADVANCED	000003	/* AREs (which are also EREs) */
#define	REG_QUOTE	000004	/* no special characters, none */
#define	REG_NOSPEC	REG_QUOTE	/* historical synonym */
#define	REG_ICASE	000010	/* ignore case */
#define	REG_NOSUB	000020	/* don't care about subexpressions */
#define	REG_EXPANDED	000040	/* expanded format, white space & comments */
#define	REG_NLSTOP	000100	/* \n doesn't match . or [^ ] */
#define	REG_NLANCH	000200	/* ^ matches after \n, $ before */
#define	REG_NEWLINE	000300	/* newlines are line terminators */
#define	REG_PEND	000400	/* ugh -- backward-compatibility hack */
#define	REG_DUMP	004000	/* none of your business :-) */
#define	REG_FAKEEC	010000	/* none of your business :-) */
#define	REG_PROGRESS	020000	/* none of your business :-) */



/*
 * execution
 ^ #ifndef __REG_NOCHAR
 ^ int re_exec(regex_t *, __REG_CONST char *, size_t,
 ^				rm_detail_t *, size_t, regmatch_t [], int);
 ^ #endif
 ^ #ifndef __REG_NOFRONT
 ^ int regexec(regex_t *, __REG_CONST char *, size_t, regmatch_t [], int);
 ^ #endif
 ^ #ifdef __REG_WIDE_T
 ^ int __REG_WIDE_EXEC(regex_t *, __REG_CONST __REG_WIDE_T *, size_t,
 ^				rm_detail_t *, size_t, regmatch_t [], int);
 ^ #endif
 */
#define	REG_NOTBOL	0001	/* BOS is not BOL */
#define	REG_NOTEOL	0002	/* EOS is not EOL */
#define	REG_STARTEND	0004	/* backward compatibility kludge */
#define	REG_FTRACE	0010	/* none of your business */
#define	REG_MTRACE	0020	/* none of your business */
#define	REG_SMALL	0040	/* none of your business */



/*
 * misc generics (may be more functions here eventually)
 ^ re_void regfree(regex_t *);
 */



/*
 * error reporting
 * Be careful if modifying the list of error codes -- the table used by
 * regerror() is generated automatically from this file!
 *
 * Note that there is no wide-char variant of regerror at this time; what
 * kind of character is used for error reports is independent of what kind
 * is used in matching.
 *
 ^ extern size_t regerror(int, __REG_CONST regex_t *, char *, size_t);
 */
#define	REG_OKAY	 0	/* no errors detected */
#define	REG_NOMATCH	 1	/* failed to match */
#define	REG_BADPAT	 2	/* invalid regexp */
#define	REG_ECOLLATE	 3	/* invalid collating element */
#define	REG_ECTYPE	 4	/* invalid character class */
#define	REG_EESCAPE	 5	/* invalid escape \ sequence */
#define	REG_ESUBREG	 6	/* invalid backreference number */
#define	REG_EBRACK	 7	/* brackets [] not balanced */
#define	REG_EPAREN	 8	/* parentheses () not balanced */
#define	REG_EBRACE	 9	/* braces {} not balanced */
#define	REG_BADBR	10	/* invalid repetition count(s) */
#define	REG_ERANGE	11	/* invalid character range */
#define	REG_ESPACE	12	/* out of memory */
#define	REG_BADRPT	13	/* quantifier operand invalid */
#define	REG_ASSERT	15	/* "can't happen" -- you found a bug */
#define	REG_INVARG	16	/* invalid argument to regex function */
#define	REG_MIXED	17	/* character widths of regex and string differ */
#define	REG_BADOPT	18	/* invalid embedded option */
/* two specials for debugging and testing */
#define	REG_ATOI	101	/* convert error-code name to number */
#define	REG_ITOA	102	/* convert error-code number to name */



/*
 * the prototypes, as possibly munched by regfwd
 */
/* =====^!^===== begin forwards =====^!^===== */
/* automatically gathered by fwd; do not hand-edit */
/* === regproto.h === */
#ifndef __REG_NOCHAR
int re_comp _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, int));
#endif
#ifndef __REG_NOFRONT
int regcomp _ANSI_ARGS_((regex_t *, __REG_CONST char *, int));
#endif
#ifdef __REG_WIDE_T
int __REG_WIDE_COMPILE _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int));
#endif
#ifndef __REG_NOCHAR
int re_exec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
#endif
#ifndef __REG_NOFRONT
int regexec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, regmatch_t [], int));
#endif
#ifdef __REG_WIDE_T
int __REG_WIDE_EXEC _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
#endif
re_void regfree _ANSI_ARGS_((regex_t *));
extern size_t regerror _ANSI_ARGS_((int, __REG_CONST regex_t *, char *, size_t));
/* automatically gathered by fwd; do not hand-edit */
/* =====^!^===== end forwards =====^!^===== */



/*
 * more C++ voodoo
 */
#ifdef __cplusplus
}
#endif



#endif

Added generic/regexec.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
/*
 * re_*exec and friends - match REs
 */

#include "regguts.h"



/* internal variables, bundled for easy passing around */
struct vars {
	regex_t *re;
	struct guts *g;
	int eflags;		/* copies of arguments */
	size_t nmatch;
	regmatch_t *pmatch;
	chr *start;		/* start of string */
	chr *stop;		/* just past end of string */
	int err;		/* error code if any (0 none) */
	regoff_t *mem;		/* memory vector for backtracking */
};
#define	VISERR(vv)	((vv)->err != 0)	/* have we seen an error yet? */
#define	ISERR()	VISERR(v)
#define	VERR(vv,e)	(((vv)->err) ? (vv)->err : ((vv)->err = (e)))
#define	ERR(e)	VERR(v, e)		/* record an error */
#define	NOERR()	{if (ISERR()) return;}	/* if error seen, return */
#define	OFF(p)	((p) - v->start)
#define	LOFF(p)	((long)OFF(p))



/* lazy-DFA representation */
struct arcp {			/* "pointer" to an outarc */
	struct sset *ss;
	color co;
};

struct sset {			/* state set */
	unsigned *states;	/* pointer to bitvector */
	unsigned hash;		/* hash of bitvector */
#		define	HASH(bv, nw)	(((nw) == 1) ? *(bv) : hash(bv, nw))
#	define	HIT(h,bv,ss,nw)	((ss)->hash == (h) && ((nw) == 1 || \
		memcmp(VS(bv), VS((ss)->states), (nw)*sizeof(unsigned)) == 0))
	int flags;
#		define	STARTER		01	/* the initial state set */
#		define	POSTSTATE	02	/* includes the goal state */
#		define	LOCKED		04	/* locked in cache */
#		define	NOPROGRESS	010	/* zero-progress state set */
	struct arcp ins;	/* chain of inarcs pointing here */
	chr *lastseen;		/* last entered on arrival here */
	struct sset **outs;	/* outarc vector indexed by color */
	struct arcp *inchain;	/* chain-pointer vector for outarcs */
};

struct dfa {
	int nssets;		/* size of cache */
	int nssused;		/* how many entries occupied yet */
	int nstates;		/* number of states */
	int ncolors;		/* length of outarc and inchain vectors */
	int wordsper;		/* length of state-set bitvectors */
	struct sset *ssets;	/* state-set cache */
	unsigned *statesarea;	/* bitvector storage */
	unsigned *work;		/* pointer to work area within statesarea */
	struct sset **outsarea;	/* outarc-vector storage */
	struct arcp *incarea;	/* inchain storage */
	struct cnfa *cnfa;
	struct colormap *cm;
	chr *lastpost;		/* location of last cache-flushed success */
	chr *lastnopr;		/* location of last cache-flushed NOPROGRESS */
	struct sset *search;	/* replacement-search-pointer memory */
	int cptsmalloced;	/* were the areas individually malloced? */
	char *mallocarea;	/* self, or master malloced area, or NULL */
};

#define	WORK	1		/* number of work bitvectors needed */

/* setup for non-malloc allocation for small cases */
#define	FEWSTATES	20	/* must be less than UBITS */
#define	FEWCOLORS	15
struct smalldfa {
	struct dfa dfa;
	struct sset ssets[FEWSTATES*2];
	unsigned statesarea[FEWSTATES*2 + WORK];
	struct sset *outsarea[FEWSTATES*2 * FEWCOLORS];
	struct arcp incarea[FEWSTATES*2 * FEWCOLORS];
};




/*
 * forward declarations
 */
/* =====^!^===== begin forwards =====^!^===== */
/* automatically gathered by fwd; do not hand-edit */
/* === regexec.c === */
int exec _ANSI_ARGS_((regex_t *, CONST chr *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
static int find _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *));
static int cfind _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *));
static VOID zapsubs _ANSI_ARGS_((regmatch_t *, size_t));
static VOID zapmem _ANSI_ARGS_((struct vars *, struct subre *));
static VOID subset _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
static int dissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
static int condissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
static int altdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
static int cdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
static int ccondissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
static int crevdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
static int cbrdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
static int caltdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
/* === rege_dfa.c === */
static chr *longest _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *));
static chr *shortest _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *, chr *, chr **));
static struct dfa *newdfa _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *, struct smalldfa *));
static VOID freedfa _ANSI_ARGS_((struct dfa *));
static unsigned hash _ANSI_ARGS_((unsigned *, int));
static struct sset *initialize _ANSI_ARGS_((struct vars *, struct dfa *, chr *));
static struct sset *miss _ANSI_ARGS_((struct vars *, struct dfa *, struct sset *, pcolor, chr *, chr *));
static int lacon _ANSI_ARGS_((struct vars *, struct cnfa *, chr *, pcolor));
static struct sset *getvacant _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *));
static struct sset *pickss _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *));
/* automatically gathered by fwd; do not hand-edit */
/* =====^!^===== end forwards =====^!^===== */



/*
 - exec - match regular expression
 ^ int exec(regex_t *, CONST chr *, size_t, rm_detail_t *,
 ^					size_t, regmatch_t [], int);
 */
int
exec(re, string, len, details, nmatch, pmatch, flags)
regex_t *re;
CONST chr *string;
size_t len;
rm_detail_t *details;		/* hook for future elaboration */
size_t nmatch;
regmatch_t pmatch[];
int flags;
{
	struct vars var;
	register struct vars *v = &var;
	int st;
	size_t n;
	int complications;
#	define	LOCALMAT	20
	regmatch_t mat[LOCALMAT];
#	define	LOCALMEM	40
	regoff_t mem[LOCALMEM];

	/* sanity checks */
	if (re == NULL || string == NULL || re->re_magic != REMAGIC)
		return REG_INVARG;
	if (re->re_csize != sizeof(chr))
		return REG_MIXED;

	/* setup */
	v->re = re;
	v->g = (struct guts *)re->re_guts;
	if (v->g->unmatchable)
		return REG_NOMATCH;
	complications = (v->g->info&REG_UBACKREF) ? 1 : 0;
	if (v->g->usedshorter)
		complications = 1;
	v->eflags = flags;
	if (v->g->cflags&REG_NOSUB)
		nmatch = 0;		/* override client */
	v->nmatch = nmatch;
	if (complications && v->nmatch < v->g->nsub + 1) {
		/* need work area bigger than what user gave us */
		if (v->g->nsub + 1 <= LOCALMAT)
			v->pmatch = mat;
		else
			v->pmatch = (regmatch_t *)MALLOC((v->g->nsub + 1) *
							sizeof(regmatch_t));
		if (v->pmatch == NULL)
			return REG_ESPACE;
		v->nmatch = v->g->nsub + 1;
	} else
		v->pmatch = pmatch;
	v->start = (chr *)string;
	v->stop = (chr *)string + len;
	v->err = 0;
	if (complications) {
		assert(v->g->ntree >= 0);
		n = (size_t)v->g->ntree;
		if (n <= LOCALMEM)
			v->mem = mem;
		else
			v->mem = (regoff_t *)MALLOC(n*sizeof(regoff_t));
		if (v->mem == NULL) {
			if (v->pmatch != pmatch && v->pmatch != mat)
				FREE(v->pmatch);
			return REG_ESPACE;
		}
	} else
		v->mem = NULL;

	/* do it */
	assert(v->g->tree != NULL);
	if (complications)
		st = cfind(v, &v->g->tree->cnfa, &v->g->cmap);
	else
		st = find(v, &v->g->tree->cnfa, &v->g->cmap);

	/* copy (portion of) match vector over if necessary */
	if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0) {
		zapsubs(pmatch, nmatch);
		n = (nmatch < v->nmatch) ? nmatch : v->nmatch;
		memcpy(VS(pmatch), VS(v->pmatch), n*sizeof(regmatch_t));
	}

	/* clean up */
	if (v->pmatch != pmatch && v->pmatch != mat)
		FREE(v->pmatch);
	if (v->mem != NULL && v->mem != mem)
		FREE(v->mem);
	return st;
}

/*
 - find - find a match for the main NFA (no-complications case)
 ^ static int find(struct vars *, struct cnfa *, struct colormap *);
 */
static int
find(v, cnfa, cm)
struct vars *v;
struct cnfa *cnfa;
struct colormap *cm;
{
	struct smalldfa da;
	struct dfa *d = newdfa(v, cnfa, cm, &da);
	struct smalldfa sa;
	struct dfa *s = newdfa(v, &v->g->search, cm, &sa);
	chr *begin;
	chr *end;
	chr *open;		/* open and close of range of possible starts */
	chr *close;

	if (d == NULL)
		return v->err;
	if (s == NULL) {
		freedfa(d);
		return v->err;
	}

	close = v->start;
	do {
		MDEBUG(("\nsearch at %ld\n", LOFF(close)));
		close = shortest(v, s, close, close, v->stop, &open);
		if (close == NULL)
			break;				/* NOTE BREAK */
		if (v->nmatch == 0) {
			/* don't need exact location */
			freedfa(d);
			freedfa(s);
			return REG_OKAY;
		}
		MDEBUG(("between %ld and %ld\n", LOFF(open), LOFF(close)));
		for (begin = open; begin <= close; begin++) {
			MDEBUG(("\nfind trying at %ld\n", LOFF(begin)));
			end = longest(v, d, begin, v->stop);
			if (end != NULL) {
				assert(v->nmatch > 0);
 				v->pmatch[0].rm_so = OFF(begin);
 				v->pmatch[0].rm_eo = OFF(end);
				freedfa(d);
				freedfa(s);
				if (v->nmatch > 1) {
					zapsubs(v->pmatch, v->nmatch);
					return dissect(v, v->g->tree, begin,
									end);
				}
				if (ISERR())
					return v->err;
				return REG_OKAY;
			}
		}
	} while (close < v->stop);

	freedfa(d);
	freedfa(s);
	if (ISERR())
		return v->err;
	return REG_NOMATCH;
}

/*
 - cfind - find a match for the main NFA (with complications)
 ^ static int cfind(struct vars *, struct cnfa *, struct colormap *);
 */
static int
cfind(v, cnfa, cm)
struct vars *v;
struct cnfa *cnfa;
struct colormap *cm;
{
	struct smalldfa da;
	struct dfa *d = newdfa(v, cnfa, cm, &da);
	struct smalldfa sa;
	struct dfa *s = newdfa(v, &v->g->search, cm, &sa);
	chr *begin;
	chr *end;
	chr *open;		/* open and close of range of possible starts */
	chr *close;
	chr *estart;
	chr *estop;
	int er;
	int shorter = v->g->tree->flags&SHORTER;

	if (d == NULL)
		return v->err;
	if (s == NULL) {
		freedfa(d);
		return v->err;
	}

	close = v->start;
	do {
		MDEBUG(("\ncsearch at %ld\n", LOFF(close)));
		close = shortest(v, s, close, close, v->stop, &open);
		if (close == NULL)
			break;				/* NOTE BREAK */
		MDEBUG(("cbetween %ld and %ld\n", LOFF(open), LOFF(close)));
		for (begin = open; begin <= close; begin++) {
			MDEBUG(("\ncfind trying at %ld\n", LOFF(begin)));
			estart = begin;
			estop = v->stop;
			for (;;) {
				if (shorter)
					end = shortest(v, d, begin, estart,
							estop, (chr **)NULL);
				else
					end = longest(v, d, begin, estop);
				if (end == NULL)
					break;		/* NOTE BREAK OUT */
				MDEBUG(("tentative end %ld\n", LOFF(end)));
				zapsubs(v->pmatch, v->nmatch);
				zapmem(v, v->g->tree);
				er = cdissect(v, v->g->tree, begin, end);
				switch (er) {
				case REG_OKAY:
					if (v->nmatch > 0) {
						v->pmatch[0].rm_so = OFF(begin);
						v->pmatch[0].rm_eo = OFF(end);
					}
					freedfa(d);
					freedfa(s);
					if (ISERR())
						return v->err;
					return REG_OKAY;
					break;
				case REG_NOMATCH:
					/* go around and try again */
					if ((shorter) ? end == estop :
								end == begin) {
						/* no point in trying again */
						freedfa(s);
						freedfa(d);
						return REG_NOMATCH;
					}
					if (shorter)
						estart = end + 1;
					else
						estop = end - 1;
					break;
				default:
					freedfa(d);
					freedfa(s);
					return er;
					break;
				}
			}
		}
	} while (close < v->stop);

	freedfa(d);
	freedfa(s);
	if (ISERR())
		return v->err;
	return REG_NOMATCH;
}

/*
 - zapsubs - initialize the subexpression matches to "no match"
 ^ static VOID zapsubs(regmatch_t *, size_t);
 */
static VOID
zapsubs(p, n)
regmatch_t *p;
size_t n;
{
	size_t i;

	for (i = n-1; i > 0; i--) {
		p[i].rm_so = -1;
		p[i].rm_eo = -1;
	}
}

/*
 - zapmem - initialize the retry memory of a subtree to zeros
 ^ static VOID zapmem(struct vars *, struct subre *);
 */
static VOID
zapmem(v, t)
struct vars *v;
struct subre *t;
{
	if (t == NULL)
		return;

	assert(v->mem != NULL);
	v->mem[t->retry] = 0;
	if (t->op == '(') {
		assert(t->subno > 0);
		v->pmatch[t->subno].rm_so = -1;
		v->pmatch[t->subno].rm_eo = -1;
	}

	if (t->left != NULL)
		zapmem(v, t->left);
	if (t->right != NULL)
		zapmem(v, t->right);
}

/*
 - subset - set any subexpression relevant to a successful subre
 ^ static VOID subset(struct vars *, struct subre *, chr *, chr *);
 */
static VOID
subset(v, sub, begin, end)
struct vars *v;
struct subre *sub;
chr *begin;
chr *end;
{
	int n = sub->subno;

	assert(n > 0);
	if ((size_t)n >= v->nmatch)
		return;

	MDEBUG(("setting %d\n", n));
	v->pmatch[n].rm_so = OFF(begin);
	v->pmatch[n].rm_eo = OFF(end);
}

/*
 - dissect - determine subexpression matches (uncomplicated case)
 ^ static int dissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
dissect(v, t, begin, end)
struct vars *v;
struct subre *t;
chr *begin;			/* beginning of relevant substring */
chr *end;			/* end of same */
{
	assert(t != NULL);
	MDEBUG(("dissect %ld-%ld\n", LOFF(begin), LOFF(end)));

	switch (t->op) {
	case '=':		/* terminal node */
		assert(t->left == NULL && t->right == NULL);
		return REG_OKAY;	/* no action, parent did the work */
		break;
	case '|':		/* alternation */
		assert(t->left != NULL);
		return altdissect(v, t, begin, end);
		break;
	case 'b':		/* back ref -- shouldn't be calling us! */
		return REG_ASSERT;
		break;
	case '.':		/* concatenation */
		assert(t->left != NULL && t->right != NULL);
		return condissect(v, t, begin, end);
		break;
	case '(':		/* capturing */
		assert(t->left != NULL && t->right == NULL);
		assert(t->subno > 0);
		subset(v, t, begin, end);
		return dissect(v, t->left, begin, end);
		break;
	default:
		return REG_ASSERT;
		break;
	}
}

/*
 - condissect - determine concatenation subexpression matches (uncomplicated)
 ^ static int condissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
condissect(v, t, begin, end)
struct vars *v;
struct subre *t;
chr *begin;			/* beginning of relevant substring */
chr *end;			/* end of same */
{
	struct smalldfa da;
	struct dfa *d;
	struct smalldfa d2a;
	struct dfa *d2;
	chr *mid;
	int i;

	assert(t->op == '.');
	assert(t->left != NULL && t->left->cnfa.nstates > 0);
	assert(t->right != NULL && t->right->cnfa.nstates > 0);

	d = newdfa(v, &t->left->cnfa, &v->g->cmap, &da);
	if (ISERR())
		return v->err;
	d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, &d2a);
	if (ISERR()) {
		freedfa(d);
		return v->err;
	}

	/* pick a tentative midpoint */
	mid = longest(v, d, begin, end);
	if (mid == NULL) {
		freedfa(d);
		freedfa(d2);
		return REG_ASSERT;
	}
	MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));

	/* iterate until satisfaction or failure */
	while (longest(v, d2, mid, end) != end) {
		/* that midpoint didn't work, find a new one */
		if (mid == begin) {
			/* all possibilities exhausted! */
			MDEBUG(("no midpoint!\n"));
			freedfa(d);
			freedfa(d2);
			return REG_ASSERT;
		}
		mid = longest(v, d, begin, mid-1);
		if (mid == NULL) {
			/* failed to find a new one! */
			MDEBUG(("failed midpoint!\n"));
			freedfa(d);
			freedfa(d2);
			return REG_ASSERT;
		}
		MDEBUG(("new midpoint %ld\n", LOFF(mid)));
	}

	/* satisfaction */
	MDEBUG(("successful\n"));
	freedfa(d);
	freedfa(d2);
	i = dissect(v, t->left, begin, mid);
	if (i != REG_OKAY)
		return i;
	return dissect(v, t->right, mid, end);
}

/*
 - altdissect - determine alternative subexpression matches (uncomplicated)
 ^ static int altdissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
altdissect(v, t, begin, end)
struct vars *v;
struct subre *t;
chr *begin;			/* beginning of relevant substring */
chr *end;			/* end of same */
{
	struct smalldfa da;
	struct dfa *d;
	int i;

	assert(t != NULL);
	assert(t->op == '|');

	for (i = 0; t != NULL; t = t->right, i++) {
		MDEBUG(("trying %dth\n", i));
		assert(t->left != NULL && t->left->cnfa.nstates > 0);
		d = newdfa(v, &t->left->cnfa, &v->g->cmap, &da);
		if (ISERR())
			return v->err;
		if (longest(v, d, begin, end) == end) {
			MDEBUG(("success\n"));
			freedfa(d);
			return dissect(v, t->left, begin, end);
		}
		freedfa(d);
	}
	return REG_ASSERT;	/* none of them matched?!? */
}

/*
 - cdissect - determine subexpression matches (with complications)
 * The retry memory stores the offset of the trial midpoint from begin, 
 * plus 1 so that 0 uniquely means "clean slate".
 ^ static int cdissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
cdissect(v, t, begin, end)
struct vars *v;
struct subre *t;
chr *begin;			/* beginning of relevant substring */
chr *end;			/* end of same */
{
	int er;

	assert(t != NULL);
	MDEBUG(("cdissect %ld-%ld\n", LOFF(begin), LOFF(end)));

	switch (t->op) {
	case '=':		/* terminal node */
		assert(t->left == NULL && t->right == NULL);
		return REG_OKAY;	/* no action, parent did the work */
		break;
	case '|':		/* alternation */
		assert(t->left != NULL);
		return caltdissect(v, t, begin, end);
		break;
	case 'b':		/* back ref -- shouldn't be calling us! */
		assert(t->left == NULL && t->right == NULL);
		return cbrdissect(v, t, begin, end);
		break;
	case '.':		/* concatenation */
		assert(t->left != NULL && t->right != NULL);
		return ccondissect(v, t, begin, end);
		break;
	case '(':		/* capturing */
		assert(t->left != NULL && t->right == NULL);
		assert(t->subno > 0);
		er = cdissect(v, t->left, begin, end);
		if (er == REG_OKAY)
			subset(v, t, begin, end);
		return er;
		break;
	default:
		return REG_ASSERT;
		break;
	}
}

/*
 - ccondissect - concatenation subexpression matches (with complications)
 * The retry memory stores the offset of the trial midpoint from begin, 
 * plus 1 so that 0 uniquely means "clean slate".
 ^ static int ccondissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
ccondissect(v, t, begin, end)
struct vars *v;
struct subre *t;
chr *begin;			/* beginning of relevant substring */
chr *end;			/* end of same */
{
	struct smalldfa da;
	struct dfa *d;
	struct smalldfa d2a;
	struct dfa *d2;
	chr *mid;
	int er;

	assert(t->op == '.');
	assert(t->left != NULL && t->left->cnfa.nstates > 0);
	assert(t->right != NULL && t->right->cnfa.nstates > 0);

	if (t->left->flags&SHORTER)		/* reverse scan */
		return crevdissect(v, t, begin, end);

	d = newdfa(v, &t->left->cnfa, &v->g->cmap, &da);
	if (ISERR())
		return v->err;
	d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, &d2a);
	if (ISERR()) {
		freedfa(d);
		return v->err;
	}
	MDEBUG(("cconcat %d\n", t->retry));

	/* pick a tentative midpoint */
	if (v->mem[t->retry] == 0) {
		mid = longest(v, d, begin, end);
		if (mid == NULL) {
			freedfa(d);
			freedfa(d2);
			return REG_NOMATCH;
		}
		MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
		v->mem[t->retry] = (mid - begin) + 1;
	} else {
		mid = begin + (v->mem[t->retry] - 1);
		MDEBUG(("working midpoint %ld\n", LOFF(mid)));
	}

	/* iterate until satisfaction or failure */
	for (;;) {
		/* try this midpoint on for size */
		er = cdissect(v, t->left, begin, mid);
		if (er == REG_OKAY && longest(v, d2, mid, end) == end &&
				(er = cdissect(v, t->right, mid, end)) == 
								REG_OKAY)
			break;			/* NOTE BREAK OUT */
		if (er != REG_OKAY && er != REG_NOMATCH) {
			freedfa(d);
			freedfa(d2);
			return er;
		}

		/* that midpoint didn't work, find a new one */
		if (mid == begin) {
			/* all possibilities exhausted */
			MDEBUG(("%d no midpoint\n", t->retry));
			freedfa(d);
			freedfa(d2);
			return REG_NOMATCH;
		}
		mid = longest(v, d, begin, mid-1);
		if (mid == NULL) {
			/* failed to find a new one */
			MDEBUG(("%d failed midpoint\n", t->retry));
			freedfa(d);
			freedfa(d2);
			return REG_NOMATCH;
		}
		MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid)));
		v->mem[t->retry] = (mid - begin) + 1;
		zapmem(v, t->left);
		zapmem(v, t->right);
	}

	/* satisfaction */
	MDEBUG(("successful\n"));
	freedfa(d);
	freedfa(d2);
	return REG_OKAY;
}

/*
 - crevdissect - determine shortest-first subexpression matches
 * The retry memory stores the offset of the trial midpoint from begin, 
 * plus 1 so that 0 uniquely means "clean slate".
 ^ static int crevdissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
crevdissect(v, t, begin, end)
struct vars *v;
struct subre *t;
chr *begin;			/* beginning of relevant substring */
chr *end;			/* end of same */
{
	struct smalldfa da;
	struct dfa *d;
	struct smalldfa d2a;
	struct dfa *d2;
	chr *mid;
	int er;

	assert(t->op == '.');
	assert(t->left != NULL && t->left->cnfa.nstates > 0);
	assert(t->right != NULL && t->right->cnfa.nstates > 0);
	assert(t->left->flags&SHORTER);

	/* concatenation -- need to split the substring between parts */
	d = newdfa(v, &t->left->cnfa, &v->g->cmap, &da);
	if (ISERR())
		return v->err;
	d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, &d2a);
	if (ISERR()) {
		freedfa(d);
		return v->err;
	}
	MDEBUG(("crev %d\n", t->retry));

	/* pick a tentative midpoint */
	if (v->mem[t->retry] == 0) {
		mid = shortest(v, d, begin, begin, end, (chr **)NULL);
		if (mid == NULL) {
			freedfa(d);
			freedfa(d2);
			return REG_NOMATCH;
		}
		MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
		v->mem[t->retry] = (mid - begin) + 1;
	} else {
		mid = begin + (v->mem[t->retry] - 1);
		MDEBUG(("working midpoint %ld\n", LOFF(mid)));
	}

	/* iterate until satisfaction or failure */
	for (;;) {
		/* try this midpoint on for size */
		er = cdissect(v, t->left, begin, mid);
		if (er == REG_OKAY && longest(v, d2, mid, end) == end &&
				(er = cdissect(v, t->right, mid, end)) == 
								REG_OKAY)
			break;			/* NOTE BREAK OUT */
		if (er != REG_OKAY && er != REG_NOMATCH) {
			freedfa(d);
			freedfa(d2);
			return er;
		}

		/* that midpoint didn't work, find a new one */
		if (mid == end) {
			/* all possibilities exhausted */
			MDEBUG(("%d no midpoint\n", t->retry));
			freedfa(d);
			freedfa(d2);
			return REG_NOMATCH;
		}
		mid = shortest(v, d, begin, mid+1, end, (chr **)NULL);
		if (mid == NULL) {
			/* failed to find a new one */
			MDEBUG(("%d failed midpoint\n", t->retry));
			freedfa(d);
			freedfa(d2);
			return REG_NOMATCH;
		}
		MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid)));
		v->mem[t->retry] = (mid - begin) + 1;
		zapmem(v, t->left);
		zapmem(v, t->right);
	}

	/* satisfaction */
	MDEBUG(("successful\n"));
	freedfa(d);
	freedfa(d2);
	return REG_OKAY;
}

/*
 - cbrdissect - determine backref subexpression matches
 ^ static int cbrdissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
cbrdissect(v, t, begin, end)
struct vars *v;
struct subre *t;
chr *begin;			/* beginning of relevant substring */
chr *end;			/* end of same */
{
	int i;
	int n = t->subno;
	size_t len;
	chr *paren;
	chr *p;
	chr *stop;
	int min = t->min;
	int max = t->max;

	assert(t != NULL);
	assert(t->op == 'b');
	assert(n >= 0);
	assert((size_t)n < v->nmatch);

	MDEBUG(("cbackref n%d %d{%d-%d}\n", t->retry, n, min, max));

	if (v->pmatch[n].rm_so == -1)
		return REG_NOMATCH;
	paren = v->start + v->pmatch[n].rm_so;
	len = v->pmatch[n].rm_eo - v->pmatch[n].rm_so;

	/* no room to maneuver -- retries are pointless */
	if (v->mem[t->retry])
		return REG_NOMATCH;
	v->mem[t->retry] = 1;

	/* special-case zero-length string */
	if (len == 0) {
		if (begin == end)
			return REG_OKAY;
		return REG_NOMATCH;
	}

	/* and too-short string */
	assert(end >= begin);
	if ((size_t)(end - begin) < len)
		return REG_NOMATCH;
	stop = end - len;

	/* count occurrences */
	i = 0;
	for (p = begin; p <= stop && (i < max || max == INFINITY); p += len) {
		if ((*v->g->compare)(paren, p, len) != 0)
				break;
		i++;
	}
	MDEBUG(("cbackref found %d\n", i));

	/* and sort it out */
	if (p != end)			/* didn't consume all of it */
		return REG_NOMATCH;
	if (min <= i && (i <= max || max == INFINITY))
		return REG_OKAY;
	return REG_NOMATCH;		/* out of range */
}

/*
 - caltdissect - determine alternative subexpression matches (w. complications)
 ^ static int caltdissect(struct vars *, struct subre *, chr *, chr *);
 */
static int			/* regexec return code */
caltdissect(v, t, begin, end)
struct vars *v;
struct subre *t;
chr *begin;			/* beginning of relevant substring */
chr *end;			/* end of same */
{
	struct smalldfa da;
	struct dfa *d;
	int er;
#	define	UNTRIED	0	/* not yet tried at all */
#	define	TRYING	1	/* top matched, trying submatches */
#	define	TRIED	2	/* top didn't match or submatches exhausted */

	if (t == NULL)
		return REG_NOMATCH;
	assert(t->op == '|');
	if (v->mem[t->retry] == TRIED)
		return caltdissect(v, t->right, begin, end);

	MDEBUG(("calt n%d\n", t->retry));
	assert(t->left != NULL);

	if (v->mem[t->retry] == UNTRIED) {
		d = newdfa(v, &t->left->cnfa, &v->g->cmap, &da);
		if (ISERR())
			return v->err;
		if (longest(v, d, begin, end) != end) {
			freedfa(d);
			v->mem[t->retry] = TRIED;
			return caltdissect(v, t->right, begin, end);
		}
		freedfa(d);
		MDEBUG(("calt matched\n"));
		v->mem[t->retry] = TRYING;
	}

	er = cdissect(v, t->left, begin, end);
	if (er != REG_NOMATCH)
		return er;

	v->mem[t->retry] = TRIED;
	return caltdissect(v, t->right, begin, end);
}



#include "rege_dfa.c"

Deleted generic/regexp.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
/*
 * TclRegComp and TclRegExec -- TclRegSub is elsewhere
 *
 *	Copyright (c) 1986 by University of Toronto.
 *	Written by Henry Spencer.  Not derived from licensed software.
 *
 *	Permission is granted to anyone to use this software for any
 *	purpose on any computer system, and to redistribute it freely,
 *	subject to the following restrictions:
 *
 *	1. The author is not responsible for the consequences of use of
 *		this software, no matter how awful, even if they arise
 *		from defects in it.
 *
 *	2. The origin of this software must not be misrepresented, either
 *		by explicit claim or by omission.
 *
 *	3. Altered versions must be plainly marked as such, and must not
 *		be misrepresented as being the original software.
 *
 * Beware that some of this code is subtly aware of the way operator
 * precedence is structured in regular expressions.  Serious changes in
 * regular-expression syntax might require a total rethink.
 *
 * *** NOTE: this code has been altered slightly for use in Tcl: ***
 * *** 1. Use ckalloc and ckfree instead of  malloc and free.	 ***
 * *** 2. Add extra argument to regexp to specify the real	 ***
 * ***    start of the string separately from the start of the	 ***
 * ***    current search. This is needed to search for multiple	 ***
 * ***    matches within a string.				 ***
 * *** 3. Names have been changed, e.g. from regcomp to		 ***
 * ***    TclRegComp, to avoid clashes with other 		 ***
 * ***    regexp implementations used by applications. 		 ***
 * *** 4. Added errMsg declaration and TclRegError procedure	 ***
 * *** 5. Various lint-like things, such as casting arguments	 ***
 * ***	  in procedure calls.					 ***
 *
 * *** NOTE: This code has been altered for use in MT-Sturdy Tcl ***
 * *** 1. All use of static variables has been changed to access ***
 * ***    fields of a structure.                                 ***
 * *** 2. This in addition to changes to TclRegError makes the   ***
 * ***    code multi-thread safe.                                ***
 *
 * SCCS: @(#) regexp.c 1.13 97/04/29 17:49:17
 */

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

/*
 * The variable below is set to NULL before invoking regexp functions
 * and checked after those functions.  If an error occurred then TclRegError
 * will set the variable to point to a (static) error message.  This
 * mechanism unfortunately does not support multi-threading, but the
 * procedures TclRegError and TclGetRegError can be modified to use
 * thread-specific storage for the variable and thereby make the code
 * thread-safe.
 */

static char *errMsg = NULL;

/*
 * The "internal use only" fields in regexp.h are present to pass info from
 * compile to execute that permits the execute phase to run lots faster on
 * simple cases.  They are:
 *
 * regstart	char that must begin a match; '\0' if none obvious
 * reganch	is the match anchored (at beginning-of-line only)?
 * regmust	string (pointer into program) that match must include, or NULL
 * regmlen	length of regmust string
 *
 * Regstart and reganch permit very fast decisions on suitable starting points
 * for a match, cutting down the work a lot.  Regmust permits fast rejection
 * of lines that cannot possibly match.  The regmust tests are costly enough
 * that TclRegComp() supplies a regmust only if the r.e. contains something
 * potentially expensive (at present, the only such thing detected is * or +
 * at the start of the r.e., which can involve a lot of backup).  Regmlen is
 * supplied because the test in TclRegExec() needs it and TclRegComp() is
 * computing it anyway.
 */

/*
 * Structure for regexp "program".  This is essentially a linear encoding
 * of a nondeterministic finite-state machine (aka syntax charts or
 * "railroad normal form" in parsing technology).  Each node is an opcode
 * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
 * all nodes except BRANCH implement concatenation; a "next" pointer with
 * a BRANCH on both ends of it is connecting two alternatives.  (Here we
 * have one of the subtle syntax dependencies:  an individual BRANCH (as
 * opposed to a collection of them) is never concatenated with anything
 * because of operator precedence.)  The operand of some types of node is
 * a literal string; for others, it is a node leading into a sub-FSM.  In
 * particular, the operand of a BRANCH node is the first node of the branch.
 * (NB this is *not* a tree structure:  the tail of the branch connects
 * to the thing following the set of BRANCHes.)  The opcodes are:
 */

/* definition	number	opnd?	meaning */
#define	END	0	/* no	End of program. */
#define	BOL	1	/* no	Match "" at beginning of line. */
#define	EOL	2	/* no	Match "" at end of line. */
#define	ANY	3	/* no	Match any one character. */
#define	ANYOF	4	/* str	Match any character in this string. */
#define	ANYBUT	5	/* str	Match any character not in this string. */
#define	BRANCH	6	/* node	Match this alternative, or the next... */
#define	BACK	7	/* no	Match "", "next" ptr points backward. */
#define	EXACTLY	8	/* str	Match this string. */
#define	NOTHING	9	/* no	Match empty string. */
#define	STAR	10	/* node	Match this (simple) thing 0 or more times. */
#define	PLUS	11	/* node	Match this (simple) thing 1 or more times. */
#define	OPEN	20	/* no	Mark this point in input as start of #n. */
			/*	OPEN+1 is number 1, etc. */
#define	CLOSE	(OPEN+NSUBEXP)	/* no	Analogous to OPEN. */

/*
 * Opcode notes:
 *
 * BRANCH	The set of branches constituting a single choice are hooked
 *		together with their "next" pointers, since precedence prevents
 *		anything being concatenated to any individual branch.  The
 *		"next" pointer of the last BRANCH in a choice points to the
 *		thing following the whole choice.  This is also where the
 *		final "next" pointer of each individual branch points; each
 *		branch starts with the operand node of a BRANCH node.
 *
 * BACK		Normal "next" pointers all implicitly point forward; BACK
 *		exists to make loop structures possible.
 *
 * STAR,PLUS	'?', and complex '*' and '+', are implemented as circular
 *		BRANCH structures using BACK.  Simple cases (one character
 *		per match) are implemented with STAR and PLUS for speed
 *		and to minimize recursive plunges.
 *
 * OPEN,CLOSE	...are numbered at compile time.
 */

/*
 * A node is one char of opcode followed by two chars of "next" pointer.
 * "Next" pointers are stored as two 8-bit pieces, high order first.  The
 * value is a positive offset from the opcode of the node containing it.
 * An operand, if any, simply follows the node.  (Note that much of the
 * code generation knows about this implicit relationship.)
 *
 * Using two bytes for the "next" pointer is vast overkill for most things,
 * but allows patterns to get big without disasters.
 */
#define	OP(p)	(*(p))
#define	NEXT(p)	(((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
#define	OPERAND(p)	((p) + 3)

/*
 * See regmagic.h for one further detail of program structure.
 */


/*
 * Utility definitions.
 */
#ifndef CHARBITS
#define	UCHARAT(p)	((int)*(unsigned char *)(p))
#else
#define	UCHARAT(p)	((int)*(p)&CHARBITS)
#endif

#define	FAIL(m)	{ TclRegError(m); return(NULL); }
#define	ISMULT(c)	((c) == '*' || (c) == '+' || (c) == '?')
#define	META	"^$.[()|?+*\\"

/*
 * Flags to be passed up and down.
 */
#define	HASWIDTH	01	/* Known never to match null string. */
#define	SIMPLE		02	/* Simple enough to be STAR/PLUS operand. */
#define	SPSTART		04	/* Starts with * or +. */
#define	WORST		0	/* Worst case. */

/*
 * Global work variables for TclRegComp().
 */
struct regcomp_state  {
    char *regparse;		/* Input-scan pointer. */
    int regnpar;		/* () count. */
    char *regcode;		/* Code-emit pointer; &regdummy = don't. */
    long regsize;		/* Code size. */
};

static char regdummy;

/*
 * The first byte of the regexp internal "program" is actually this magic
 * number; the start node begins in the second byte.
 */
#define	MAGIC	0234


/*
 * Forward declarations for TclRegComp()'s friends.
 */

static char *		reg _ANSI_ARGS_((int paren, int *flagp,
			    struct regcomp_state *rcstate));
static char *		regatom _ANSI_ARGS_((int *flagp,
			    struct regcomp_state *rcstate));
static char *		regbranch _ANSI_ARGS_((int *flagp,
			    struct regcomp_state *rcstate));
static void		regc _ANSI_ARGS_((int b,
			    struct regcomp_state *rcstate));
static void		reginsert _ANSI_ARGS_((int op, char *opnd,
			    struct regcomp_state *rcstate));
static char *		regnext _ANSI_ARGS_((char *p));
static char *		regnode _ANSI_ARGS_((int op,
			    struct regcomp_state *rcstate));
static void 		regoptail _ANSI_ARGS_((char *p, char *val));
static char *		regpiece _ANSI_ARGS_((int *flagp,
			    struct regcomp_state *rcstate));
static void 		regtail _ANSI_ARGS_((char *p, char *val));

#ifdef STRCSPN
static int strcspn _ANSI_ARGS_((char *s1, char *s2));
#endif

/*
 - TclRegComp - compile a regular expression into internal code
 *
 * We can't allocate space until we know how big the compiled form will be,
 * but we can't compile it (and thus know how big it is) until we've got a
 * place to put the code.  So we cheat:  we compile it twice, once with code
 * generation turned off and size counting turned on, and once "for real".
 * This also means that we don't allocate space until we are sure that the
 * thing really will compile successfully, and we never have to move the
 * code and thus invalidate pointers into it.  (Note that it has to be in
 * one piece because free() must be able to free it all.)
 *
 * Beware that the optimization-preparation code in here knows about some
 * of the structure of the compiled regexp.
 */
regexp *
TclRegComp(exp)
char *exp;
{
	register regexp *r;
	register char *scan;
	register char *longest;
	register int len;
	int flags;
	struct regcomp_state state;
	struct regcomp_state *rcstate= &state;

	if (exp == NULL)
		FAIL("NULL argument");

	/* First pass: determine size, legality. */
	rcstate->regparse = exp;
	rcstate->regnpar = 1;
	rcstate->regsize = 0L;
	rcstate->regcode = &regdummy;
	regc(MAGIC, rcstate);
	if (reg(0, &flags, rcstate) == NULL)
		return(NULL);

	/* Small enough for pointer-storage convention? */
	if (rcstate->regsize >= 32767L)		/* Probably could be 65535L. */
		FAIL("regexp too big");

	/* Allocate space. */
	r = (regexp *)ckalloc(sizeof(regexp) + (unsigned)rcstate->regsize);
	if (r == NULL)
		FAIL("out of space");

	/* Second pass: emit code. */
	rcstate->regparse = exp;
	rcstate->regnpar = 1;
	rcstate->regcode = r->program;
	regc(MAGIC, rcstate);
	if (reg(0, &flags, rcstate) == NULL)
		return(NULL);

	/* Dig out information for optimizations. */
	r->regstart = '\0';	/* Worst-case defaults. */
	r->reganch = 0;
	r->regmust = NULL;
	r->regmlen = 0;
	scan = r->program+1;			/* First BRANCH. */
	if (OP(regnext(scan)) == END) {		/* Only one top-level choice. */
		scan = OPERAND(scan);

		/* Starting-point info. */
		if (OP(scan) == EXACTLY)
			r->regstart = *OPERAND(scan);
		else if (OP(scan) == BOL)
			r->reganch++;

		/*
		 * If there's something expensive in the r.e., find the
		 * longest literal string that must appear and make it the
		 * regmust.  Resolve ties in favor of later strings, since
		 * the regstart check works with the beginning of the r.e.
		 * and avoiding duplication strengthens checking.  Not a
		 * strong reason, but sufficient in the absence of others.
		 */
		if (flags&SPSTART) {
			longest = NULL;
			len = 0;
			for (; scan != NULL; scan = regnext(scan))
				if (OP(scan) == EXACTLY && ((int) strlen(OPERAND(scan))) >= len) {
					longest = OPERAND(scan);
					len = strlen(OPERAND(scan));
				}
			r->regmust = longest;
			r->regmlen = len;
		}
	}

	return(r);
}

/*
 - reg - regular expression, i.e. main body or parenthesized thing
 *
 * Caller must absorb opening parenthesis.
 *
 * Combining parenthesis handling with the base level of regular expression
 * is a trifle forced, but the need to tie the tails of the branches to what
 * follows makes it hard to avoid.
 */
static char *
reg(paren, flagp, rcstate)
int paren;			/* Parenthesized? */
int *flagp;
struct regcomp_state *rcstate;
{
	register char *ret;
	register char *br;
	register char *ender;
	register int parno = 0;
	int flags;

	*flagp = HASWIDTH;	/* Tentatively. */

	/* Make an OPEN node, if parenthesized. */
	if (paren) {
		if (rcstate->regnpar >= NSUBEXP)
			FAIL("too many ()");
		parno = rcstate->regnpar;
		rcstate->regnpar++;
		ret = regnode(OPEN+parno,rcstate);
	} else
		ret = NULL;

	/* Pick up the branches, linking them together. */
	br = regbranch(&flags,rcstate);
	if (br == NULL)
		return(NULL);
	if (ret != NULL)
		regtail(ret, br);	/* OPEN -> first. */
	else
		ret = br;
	if (!(flags&HASWIDTH))
		*flagp &= ~HASWIDTH;
	*flagp |= flags&SPSTART;
	while (*rcstate->regparse == '|') {
		rcstate->regparse++;
		br = regbranch(&flags,rcstate);
		if (br == NULL)
			return(NULL);
		regtail(ret, br);	/* BRANCH -> BRANCH. */
		if (!(flags&HASWIDTH))
			*flagp &= ~HASWIDTH;
		*flagp |= flags&SPSTART;
	}

	/* Make a closing node, and hook it on the end. */
	ender = regnode((paren) ? CLOSE+parno : END,rcstate);	
	regtail(ret, ender);

	/* Hook the tails of the branches to the closing node. */
	for (br = ret; br != NULL; br = regnext(br))
		regoptail(br, ender);

	/* Check for proper termination. */
	if (paren && *rcstate->regparse++ != ')') {
		FAIL("unmatched ()");
	} else if (!paren && *rcstate->regparse != '\0') {
		if (*rcstate->regparse == ')') {
			FAIL("unmatched ()");
		} else
			FAIL("junk on end");	/* "Can't happen". */
		/* NOTREACHED */
	}

	return(ret);
}

/*
 - regbranch - one alternative of an | operator
 *
 * Implements the concatenation operator.
 */
static char *
regbranch(flagp, rcstate)
int *flagp;
struct regcomp_state *rcstate;
{
	register char *ret;
	register char *chain;
	register char *latest;
	int flags;

	*flagp = WORST;		/* Tentatively. */

	ret = regnode(BRANCH,rcstate);
	chain = NULL;
	while (*rcstate->regparse != '\0' && *rcstate->regparse != '|' &&
				*rcstate->regparse != ')') {
		latest = regpiece(&flags, rcstate);
		if (latest == NULL)
			return(NULL);
		*flagp |= flags&HASWIDTH;
		if (chain == NULL)	/* First piece. */
			*flagp |= flags&SPSTART;
		else
			regtail(chain, latest);
		chain = latest;
	}
	if (chain == NULL)	/* Loop ran zero times. */
		(void) regnode(NOTHING,rcstate);

	return(ret);
}

/*
 - regpiece - something followed by possible [*+?]
 *
 * Note that the branching code sequences used for ? and the general cases
 * of * and + are somewhat optimized:  they use the same NOTHING node as
 * both the endmarker for their branch list and the body of the last branch.
 * It might seem that this node could be dispensed with entirely, but the
 * endmarker role is not redundant.
 */
static char *
regpiece(flagp, rcstate)
int *flagp;
struct regcomp_state *rcstate;
{
	register char *ret;
	register char op;
	register char *next;
	int flags;

	ret = regatom(&flags,rcstate);
	if (ret == NULL)
		return(NULL);

	op = *rcstate->regparse;
	if (!ISMULT(op)) {
		*flagp = flags;
		return(ret);
	}

	if (!(flags&HASWIDTH) && op != '?')
		FAIL("*+ operand could be empty");
	*flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);

	if (op == '*' && (flags&SIMPLE))
		reginsert(STAR, ret, rcstate);
	else if (op == '*') {
		/* Emit x* as (x&|), where & means "self". */
		reginsert(BRANCH, ret, rcstate);			/* Either x */
		regoptail(ret, regnode(BACK,rcstate));		/* and loop */
		regoptail(ret, ret);			/* back */
		regtail(ret, regnode(BRANCH,rcstate));		/* or */
		regtail(ret, regnode(NOTHING,rcstate));		/* null. */
	} else if (op == '+' && (flags&SIMPLE))
		reginsert(PLUS, ret, rcstate);
	else if (op == '+') {
		/* Emit x+ as x(&|), where & means "self". */
		next = regnode(BRANCH,rcstate);			/* Either */
		regtail(ret, next);
		regtail(regnode(BACK,rcstate), ret);		/* loop back */
		regtail(next, regnode(BRANCH,rcstate));		/* or */
		regtail(ret, regnode(NOTHING,rcstate));		/* null. */
	} else if (op == '?') {
		/* Emit x? as (x|) */
		reginsert(BRANCH, ret, rcstate);			/* Either x */
		regtail(ret, regnode(BRANCH,rcstate));		/* or */
		next = regnode(NOTHING,rcstate);		/* null. */
		regtail(ret, next);
		regoptail(ret, next);
	}
	rcstate->regparse++;
	if (ISMULT(*rcstate->regparse))
		FAIL("nested *?+");

	return(ret);
}

/*
 - regatom - the lowest level
 *
 * Optimization:  gobbles an entire sequence of ordinary characters so that
 * it can turn them into a single node, which is smaller to store and
 * faster to run.  Backslashed characters are exceptions, each becoming a
 * separate node; the code is simpler that way and it's not worth fixing.
 */
static char *
regatom(flagp, rcstate)
int *flagp;
struct regcomp_state *rcstate;
{
	register char *ret;
	int flags;

	*flagp = WORST;		/* Tentatively. */

	switch (*rcstate->regparse++) {
	case '^':
		ret = regnode(BOL,rcstate);
		break;
	case '$':
		ret = regnode(EOL,rcstate);
		break;
	case '.':
		ret = regnode(ANY,rcstate);
		*flagp |= HASWIDTH|SIMPLE;
		break;
	case '[': {
			register int clss;
			register int classend;

			if (*rcstate->regparse == '^') {	/* Complement of range. */
				ret = regnode(ANYBUT,rcstate);
				rcstate->regparse++;
			} else
				ret = regnode(ANYOF,rcstate);
			if (*rcstate->regparse == ']' || *rcstate->regparse == '-')
				regc(*rcstate->regparse++,rcstate);
			while (*rcstate->regparse != '\0' && *rcstate->regparse != ']') {
				if (*rcstate->regparse == '-') {
					rcstate->regparse++;
					if (*rcstate->regparse == ']' || *rcstate->regparse == '\0')
						regc('-',rcstate);
					else {
						clss = UCHARAT(rcstate->regparse-2)+1;
						classend = UCHARAT(rcstate->regparse);
						if (clss > classend+1)
							FAIL("invalid [] range");
						for (; clss <= classend; clss++)
							regc((char)clss,rcstate);
						rcstate->regparse++;
					}
				} else
					regc(*rcstate->regparse++,rcstate);
			}
			regc('\0',rcstate);
			if (*rcstate->regparse != ']')
				FAIL("unmatched []");
			rcstate->regparse++;
			*flagp |= HASWIDTH|SIMPLE;
		}
		break;
	case '(':
		ret = reg(1, &flags, rcstate);
		if (ret == NULL)
			return(NULL);
		*flagp |= flags&(HASWIDTH|SPSTART);
		break;
	case '\0':
	case '|':
	case ')':
		FAIL("internal urp");	/* Supposed to be caught earlier. */
		/* NOTREACHED */
	case '?':
	case '+':
	case '*':
		FAIL("?+* follows nothing");
		/* NOTREACHED */
	case '\\':
		if (*rcstate->regparse == '\0')
			FAIL("trailing \\");
		ret = regnode(EXACTLY,rcstate);
		regc(*rcstate->regparse++,rcstate);
		regc('\0',rcstate);
		*flagp |= HASWIDTH|SIMPLE;
		break;
	default: {
			register int len;
			register char ender;

			rcstate->regparse--;
			len = strcspn(rcstate->regparse, META);
			if (len <= 0)
				FAIL("internal disaster");
			ender = *(rcstate->regparse+len);
			if (len > 1 && ISMULT(ender))
				len--;		/* Back off clear of ?+* operand. */
			*flagp |= HASWIDTH;
			if (len == 1)
				*flagp |= SIMPLE;
			ret = regnode(EXACTLY,rcstate);
			while (len > 0) {
				regc(*rcstate->regparse++,rcstate);
				len--;
			}
			regc('\0',rcstate);
		}
		break;
	}

	return(ret);
}

/*
 - regnode - emit a node
 */
static char *			/* Location. */
regnode(op, rcstate)
int op;
struct regcomp_state *rcstate;
{
	register char *ret;
	register char *ptr;

	ret = rcstate->regcode;
	if (ret == &regdummy) {
		rcstate->regsize += 3;
		return(ret);
	}

	ptr = ret;
	*ptr++ = (char)op;
	*ptr++ = '\0';		/* Null "next" pointer. */
	*ptr++ = '\0';
	rcstate->regcode = ptr;

	return(ret);
}

/*
 - regc - emit (if appropriate) a byte of code
 */
static void
regc(b, rcstate)
int b;
struct regcomp_state *rcstate;
{
	if (rcstate->regcode != &regdummy)
		*rcstate->regcode++ = (char)b;
	else
		rcstate->regsize++;
}

/*
 - reginsert - insert an operator in front of already-emitted operand
 *
 * Means relocating the operand.
 */
static void
reginsert(op, opnd, rcstate)
int op;
char *opnd;
struct regcomp_state *rcstate;
{
	register char *src;
	register char *dst;
	register char *place;

	if (rcstate->regcode == &regdummy) {
		rcstate->regsize += 3;
		return;
	}

	src = rcstate->regcode;
	rcstate->regcode += 3;
	dst = rcstate->regcode;
	while (src > opnd)
		*--dst = *--src;

	place = opnd;		/* Op node, where operand used to be. */
	*place++ = (char)op;
	*place++ = '\0';
	*place = '\0';
}

/*
 - regtail - set the next-pointer at the end of a node chain
 */
static void
regtail(p, val)
char *p;
char *val;
{
	register char *scan;
	register char *temp;
	register int offset;

	if (p == &regdummy)
		return;

	/* Find last node. */
	scan = p;
	for (;;) {
		temp = regnext(scan);
		if (temp == NULL)
			break;
		scan = temp;
	}

	if (OP(scan) == BACK)
		offset = scan - val;
	else
		offset = val - scan;
	*(scan+1) = (char)((offset>>8)&0377);
	*(scan+2) = (char)(offset&0377);
}

/*
 - regoptail - regtail on operand of first argument; nop if operandless
 */
static void
regoptail(p, val)
char *p;
char *val;
{
	/* "Operandless" and "op != BRANCH" are synonymous in practice. */
	if (p == NULL || p == &regdummy || OP(p) != BRANCH)
		return;
	regtail(OPERAND(p), val);
}

/*
 * TclRegExec and friends
 */

/*
 * Global work variables for TclRegExec().
 */
struct regexec_state  {
    char *reginput;		/* String-input pointer. */
    char *regbol;		/* Beginning of input, for ^ check. */
    char **regstartp;	/* Pointer to startp array. */
    char **regendp;		/* Ditto for endp. */
};

/*
 * Forwards.
 */
static int 		regtry _ANSI_ARGS_((regexp *prog, char *string,
			    struct regexec_state *restate));
static int 		regmatch _ANSI_ARGS_((char *prog,
			    struct regexec_state *restate));
static int 		regrepeat _ANSI_ARGS_((char *p,
			    struct regexec_state *restate));

#ifdef DEBUG
int regnarrate = 0;
void regdump _ANSI_ARGS_((regexp *r));
static char *regprop _ANSI_ARGS_((char *op));
#endif

/*
 - TclRegExec - match a regexp against a string
 */
int
TclRegExec(prog, string, start)
register regexp *prog;
register char *string;
char *start;
{
	register char *s;
	struct regexec_state state;
	struct regexec_state *restate= &state;

	/* Be paranoid... */
	if (prog == NULL || string == NULL) {
		TclRegError("NULL parameter");
		return(0);
	}

	/* Check validity of program. */
	if (UCHARAT(prog->program) != MAGIC) {
		TclRegError("corrupted program");
		return(0);
	}

	/* If there is a "must appear" string, look for it. */
	if (prog->regmust != NULL) {
		s = string;
		while ((s = strchr(s, prog->regmust[0])) != NULL) {
			if (strncmp(s, prog->regmust, (size_t) prog->regmlen)
			    == 0)
				break;	/* Found it. */
			s++;
		}
		if (s == NULL)	/* Not present. */
			return(0);
	}

	/* Mark beginning of line for ^ . */
	restate->regbol = start;

	/* Simplest case:  anchored match need be tried only once. */
	if (prog->reganch)
		return(regtry(prog, string, restate));

	/* Messy cases:  unanchored match. */
	s = string;
	if (prog->regstart != '\0')
		/* We know what char it must start with. */
		while ((s = strchr(s, prog->regstart)) != NULL) {
			if (regtry(prog, s, restate))
				return(1);
			s++;
		}
	else
		/* We don't -- general case. */
		do {
			if (regtry(prog, s, restate))
				return(1);
		} while (*s++ != '\0');

	/* Failure. */
	return(0);
}

/*
 - regtry - try match at specific point
 */
static int			/* 0 failure, 1 success */
regtry(prog, string, restate)
regexp *prog;
char *string;
struct regexec_state *restate;
{
	register int i;
	register char **sp;
	register char **ep;

	restate->reginput = string;
	restate->regstartp = prog->startp;
	restate->regendp = prog->endp;

	sp = prog->startp;
	ep = prog->endp;
	for (i = NSUBEXP; i > 0; i--) {
		*sp++ = NULL;
		*ep++ = NULL;
	}
	if (regmatch(prog->program + 1,restate)) {
		prog->startp[0] = string;
		prog->endp[0] = restate->reginput;
		return(1);
	} else
		return(0);
}

/*
 - regmatch - main matching routine
 *
 * Conceptually the strategy is simple:  check to see whether the current
 * node matches, call self recursively to see whether the rest matches,
 * and then act accordingly.  In practice we make some effort to avoid
 * recursion, in particular by going through "ordinary" nodes (that don't
 * need to know whether the rest of the match failed) by a loop instead of
 * by recursion.
 */
static int			/* 0 failure, 1 success */
regmatch(prog, restate)
char *prog;
struct regexec_state *restate;
{
    register char *scan;	/* Current node. */
    char *next;		/* Next node. */

    scan = prog;
#ifdef DEBUG
    if (scan != NULL && regnarrate)
	fprintf(stderr, "%s(\n", regprop(scan));
#endif
    while (scan != NULL) {
#ifdef DEBUG
	if (regnarrate)
	    fprintf(stderr, "%s...\n", regprop(scan));
#endif
	next = regnext(scan);

	switch (OP(scan)) {
	    case BOL:
		if (restate->reginput != restate->regbol) {
		    return 0;
		}
		break;
	    case EOL:
		if (*restate->reginput != '\0') {
		    return 0;
		}
		break;
	    case ANY:
		if (*restate->reginput == '\0') {
		    return 0;
		}
		restate->reginput++;
		break;
	    case EXACTLY: {
		register int len;
		register char *opnd;

		opnd = OPERAND(scan);
		/* Inline the first character, for speed. */
		if (*opnd != *restate->reginput) {
		    return 0 ;
		}
		len = strlen(opnd);
		if (len > 1 && strncmp(opnd, restate->reginput, (size_t) len)
			!= 0) {
		    return 0;
		}
		restate->reginput += len;
		break;
	    }
	    case ANYOF:
		if (*restate->reginput == '\0'
			|| strchr(OPERAND(scan), *restate->reginput) == NULL) {
		    return 0;
		}
		restate->reginput++;
		break;
	    case ANYBUT:
		if (*restate->reginput == '\0'
			|| strchr(OPERAND(scan), *restate->reginput) != NULL) {
		    return 0;
		}
		restate->reginput++;
		break;
	    case NOTHING:
		break;
	    case BACK:
		break;
	    case OPEN+1:
	    case OPEN+2:
	    case OPEN+3:
	    case OPEN+4:
	    case OPEN+5:
	    case OPEN+6:
	    case OPEN+7:
	    case OPEN+8:
	    case OPEN+9: {
		register int no;
		register char *save;

	doOpen:
		no = OP(scan) - OPEN;
		save = restate->reginput;

		if (regmatch(next,restate)) {
		    /*
		     * Don't set startp if some later invocation of the
		     * same parentheses already has.
		     */
		    if (restate->regstartp[no] == NULL) {
			restate->regstartp[no] = save;
		    }
		    return 1;
		} else {
		    return 0;
		}
	    }
	    case CLOSE+1:
	    case CLOSE+2:
	    case CLOSE+3:
	    case CLOSE+4:
	    case CLOSE+5:
	    case CLOSE+6:
	    case CLOSE+7:
	    case CLOSE+8:
	    case CLOSE+9: {
		register int no;
		register char *save;

	doClose:
		no = OP(scan) - CLOSE;
		save = restate->reginput;

		if (regmatch(next,restate)) {
				/*
				 * Don't set endp if some later
				 * invocation of the same parentheses
				 * already has.
				 */
		    if (restate->regendp[no] == NULL)
			restate->regendp[no] = save;
		    return 1;
		} else {
		    return 0;
		}
	    }
	    case BRANCH: {
		register char *save;

		if (OP(next) != BRANCH) { /* No choice. */
		    next = OPERAND(scan); /* Avoid recursion. */
		} else {
		    do {
			save = restate->reginput;
			if (regmatch(OPERAND(scan),restate))
			    return(1);
			restate->reginput = save;
			scan = regnext(scan);
		    } while (scan != NULL && OP(scan) == BRANCH);
		    return 0;
		}
		break;
	    }
	    case STAR:
	    case PLUS: {
		register char nextch;
		register int no;
		register char *save;
		register int min;

		/*
		 * Lookahead to avoid useless match attempts
		 * when we know what character comes next.
		 */
		nextch = '\0';
		if (OP(next) == EXACTLY)
		    nextch = *OPERAND(next);
		min = (OP(scan) == STAR) ? 0 : 1;
		save = restate->reginput;
		no = regrepeat(OPERAND(scan),restate);
		while (no >= min) {
		    /* If it could work, try it. */
		    if (nextch == '\0' || *restate->reginput == nextch)
			if (regmatch(next,restate))
			    return(1);
		    /* Couldn't or didn't -- back up. */
		    no--;
		    restate->reginput = save + no;
		}
		return(0);
	    }
	    case END:
		return(1);	/* Success! */
	    default:
		if (OP(scan) > OPEN && OP(scan) < OPEN+NSUBEXP) {
		    goto doOpen;
		} else if (OP(scan) > CLOSE && OP(scan) < CLOSE+NSUBEXP) {
		    goto doClose;
		}
		TclRegError("memory corruption");
		return 0;
	}

	scan = next;
    }

    /*
     * We get here only if there's trouble -- normally "case END" is
     * the terminating point.
     */
    TclRegError("corrupted pointers");
    return(0);
}

/*
 - regrepeat - repeatedly match something simple, report how many
 */
static int
regrepeat(p, restate)
char *p;
struct regexec_state *restate;
{
	register int count = 0;
	register char *scan;
	register char *opnd;

	scan = restate->reginput;
	opnd = OPERAND(p);
	switch (OP(p)) {
	case ANY:
		count = strlen(scan);
		scan += count;
		break;
	case EXACTLY:
		while (*opnd == *scan) {
			count++;
			scan++;
		}
		break;
	case ANYOF:
		while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
			count++;
			scan++;
		}
		break;
	case ANYBUT:
		while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
			count++;
			scan++;
		}
		break;
	default:		/* Oh dear.  Called inappropriately. */
		TclRegError("internal foulup");
		count = 0;	/* Best compromise. */
		break;
	}
	restate->reginput = scan;

	return(count);
}

/*
 - regnext - dig the "next" pointer out of a node
 */
static char *
regnext(p)
register char *p;
{
	register int offset;

	if (p == &regdummy)
		return(NULL);

	offset = NEXT(p);
	if (offset == 0)
		return(NULL);

	if (OP(p) == BACK)
		return(p-offset);
	else
		return(p+offset);
}

#ifdef DEBUG

static char *regprop();

/*
 - regdump - dump a regexp onto stdout in vaguely comprehensible form
 */
void
regdump(r)
regexp *r;
{
	register char *s;
	register char op = EXACTLY;	/* Arbitrary non-END op. */
	register char *next;


	s = r->program + 1;
	while (op != END) {	/* While that wasn't END last time... */
		op = OP(s);
		printf("%2d%s", s-r->program, regprop(s));	/* Where, what. */
		next = regnext(s);
		if (next == NULL)		/* Next ptr. */
			printf("(0)");
		else 
			printf("(%d)", (s-r->program)+(next-s));
		s += 3;
		if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
			/* Literal string, where present. */
			while (*s != '\0') {
				putchar(*s);
				s++;
			}
			s++;
		}
		putchar('\n');
	}

	/* Header fields of interest. */
	if (r->regstart != '\0')
		printf("start `%c' ", r->regstart);
	if (r->reganch)
		printf("anchored ");
	if (r->regmust != NULL)
		printf("must have \"%s\"", r->regmust);
	printf("\n");
}

/*
 - regprop - printable representation of opcode
 */
static char *
regprop(op)
char *op;
{
	register char *p;
	static char buf[50];

	(void) strcpy(buf, ":");

	switch (OP(op)) {
	case BOL:
		p = "BOL";
		break;
	case EOL:
		p = "EOL";
		break;
	case ANY:
		p = "ANY";
		break;
	case ANYOF:
		p = "ANYOF";
		break;
	case ANYBUT:
		p = "ANYBUT";
		break;
	case BRANCH:
		p = "BRANCH";
		break;
	case EXACTLY:
		p = "EXACTLY";
		break;
	case NOTHING:
		p = "NOTHING";
		break;
	case BACK:
		p = "BACK";
		break;
	case END:
		p = "END";
		break;
	case OPEN+1:
	case OPEN+2:
	case OPEN+3:
	case OPEN+4:
	case OPEN+5:
	case OPEN+6:
	case OPEN+7:
	case OPEN+8:
	case OPEN+9:
		sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
		p = NULL;
		break;
	case CLOSE+1:
	case CLOSE+2:
	case CLOSE+3:
	case CLOSE+4:
	case CLOSE+5:
	case CLOSE+6:
	case CLOSE+7:
	case CLOSE+8:
	case CLOSE+9:
		sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
		p = NULL;
		break;
	case STAR:
		p = "STAR";
		break;
	case PLUS:
		p = "PLUS";
		break;
	default:
		if (OP(op) > OPEN && OP(op) < OPEN+NSUBEXP) {
		    sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
		    p = NULL;
		    break;
		} else if (OP(op) > CLOSE && OP(op) < CLOSE+NSUBEXP) {
		    sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
		    p = NULL;
		} else {
		    TclRegError("corrupted opcode");
		}
		break;
	}
	if (p != NULL)
		(void) strcat(buf, p);
	return(buf);
}
#endif

/*
 * The following is provided for those people who do not have strcspn() in
 * their C libraries.  They should get off their butts and do something
 * about it; at least one public-domain implementation of those (highly
 * useful) string routines has been published on Usenet.
 */
#ifdef STRCSPN
/*
 * strcspn - find length of initial segment of s1 consisting entirely
 * of characters not from s2
 */

static int
strcspn(s1, s2)
char *s1;
char *s2;
{
	register char *scan1;
	register char *scan2;
	register int count;

	count = 0;
	for (scan1 = s1; *scan1 != '\0'; scan1++) {
		for (scan2 = s2; *scan2 != '\0';)	/* ++ moved down. */
			if (*scan1 == *scan2++)
				return(count);
		count++;
	}
	return(count);
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TclRegError --
 *
 *	This procedure is invoked by the regexp code when an error
 *	occurs.  It saves the error message so it can be seen by the
 *	code that called Spencer's code.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The value of "string" is saved in "errMsg".
 *
 *----------------------------------------------------------------------
 */

void
TclRegError(string)
    char *string;			/* Error message. */
{
    errMsg = string;
}

char *
TclGetRegError()
{
    return errMsg;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Added generic/regfree.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
/*
 * regfree - free an RE
 *
 * You might think that this could be incorporated into regcomp.c, and
 * that would be a reasonable idea... except that this is a generic
 * function (with a generic name), applicable to all compiled REs
 * regardless of the size of their characters, whereas the stuff in
 * regcomp.c gets compiled once per character size.
 */

#include "regguts.h"

/*
 - regfree - free an RE (generic function, punts to RE-specific function)
 *
 * Ignoring invocation with NULL is a convenience.
 */
VOID
regfree(re)
regex_t *re;
{
	if (re == NULL)
		return;
	(*((struct fns *)re->re_fns)->free)(re);
}

Added generic/regfronts.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
/*
 * regcomp and regexec - front ends to re_ routines
 *
 * Mostly for implementation of backward-compatibility kludges.  Note
 * that these routines exist ONLY in char versions.
 */

#include "regguts.h"

/*
 - regcomp - compile regular expression
 */
int
regcomp(re, str, flags)
regex_t *re;
CONST char *str;
int flags;
{
	size_t len;
	int f = flags;

	if (f&REG_PEND) {
		len = re->re_endp - str;
		f &= ~REG_PEND;
	} else
		len = strlen(str);

	return re_comp(re, str, len, f);
}

/*
 - regexec - execute regular expression
 */
int
regexec(re, str, nmatch, pmatch, flags)
regex_t *re;
CONST char *str;
size_t nmatch;
regmatch_t pmatch[];
int flags;
{
	CONST char *start;
	size_t len;
	int f = flags;

	if (f&REG_STARTEND) {
		start = str + pmatch[0].rm_so;
		len = pmatch[0].rm_eo - pmatch[0].rm_so;
		f &= ~REG_STARTEND;
	} else {
		start = str;
		len = strlen(str);
	}

	return re_exec(re, start, len, nmatch, pmatch, f);
}

Added generic/regguts.h.









































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
/*
 * Internal interface definitions, etc., for the regex package
 */



/*
 * Environmental customization.  It should not (I hope) be necessary to
 * alter the file you are now reading -- regcustom.h should handle it all,
 * given care here and elsewhere.
 */
#include "regcustom.h"



/*
 * Things that regcustom.h might override.
 */

/* standard header files (NULL is a reasonable indicator for them) */
#ifndef NULL
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#endif

/* assertions */
#ifndef assert
#ifndef REG_DEBUG
#define NDEBUG
#include <assert.h>
#endif
#endif

/* voids */
#ifndef VOID
#define	VOID	void			/* for function return values */
#endif
#ifndef DISCARD
#define	DISCARD	VOID			/* for throwing values away */
#endif
#ifndef PVOID
#define	PVOID	VOID *			/* generic pointer */
#endif
#ifndef VS
#define	VS(x)	((PVOID)(x))		/* cast something to generic ptr */
#endif
#ifndef NOPARMS
#define	NOPARMS	VOID			/* for empty parm lists */
#endif

/* function-pointer declarator */
#ifndef FUNCPTR
#if __STDC__ >= 1
#define	FUNCPTR(name, args)	(*name)args
#else
#define	FUNCPTR(name, args)	(*name)()
#endif
#endif

/* memory allocation */
#ifndef MALLOC
#define	MALLOC(n)	malloc(n)
#endif
#ifndef REALLOC
#define	REALLOC(p, n)	realloc(VS(p), n)
#endif
#ifndef FREE
#define	FREE(p)		free(VS(p))
#endif

/* want size of a char in bits, and max value in bounded quantifiers */
#ifndef CHAR_BIT
#include <limits.h>
#endif
#ifndef _POSIX2_RE_DUP_MAX
#define	_POSIX2_RE_DUP_MAX	255	/* normally from <limits.h> */
#endif



/*
 * misc
 */

#define	NOTREACHED	0
#define	xxx		1

#define	DUPMAX	_POSIX2_RE_DUP_MAX
#define	INFINITY	(DUPMAX+1)

#define	REMAGIC	0xfed7		/* magic number for main struct */



/*
 * debugging facilities
 */
#ifdef REG_DEBUG
/* FDEBUG does finite-state tracing */
#define	FDEBUG(arglist)	{ if (v->eflags&REG_FTRACE) printf arglist; }
/* MDEBUG does higher-level tracing */
#define	MDEBUG(arglist)	{ if (v->eflags&REG_MTRACE) printf arglist; }
#else
#define	FDEBUG(arglist)	{}
#define	MDEBUG(arglist)	{}
#endif



/*
 * bitmap manipulation
 */
#define	UBITS	(CHAR_BIT * sizeof(unsigned))
#define	BSET(uv, sn)	((uv)[(sn)/UBITS] |= (unsigned)1 << ((sn)%UBITS))
#define	ISBSET(uv, sn)	((uv)[(sn)/UBITS] & ((unsigned)1 << ((sn)%UBITS)))



/*
 * We dissect a chr into byts for colormap table indexing.  Here we define
 * a byt, which will be the same as a byte on most machines...  The exact
 * size of a byt is not critical, but about 8 bits is good, and extraction
 * of 8-bit chunks is sometimes especially fast.
 */
#ifndef BYTBITS
#define	BYTBITS	8		/* bits in a byt */
#endif
#define	BYTTAB	(1<<BYTBITS)	/* size of table with one entry per byt value */
#define	BYTMASK	(BYTTAB-1)	/* bit mask for byt */
#define	NBYTS	((CHRBITS+BYTBITS-1)/BYTBITS)
/* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */



/*
 * As soon as possible, we map chrs into equivalence classes -- "colors" --
 * which are of much more manageable number.
 */
typedef short color;		/* colors of characters */
typedef int pcolor;		/* what color promotes to */
#define	COLORLESS	(-1)	/* impossible color */
#define	WHITE		0	/* default color, parent of all others */



/*
 * A colormap is a tree -- more precisely, a DAG -- indexed at each level
 * by a byt of the chr, to map the chr to a color efficiently.  Because
 * lower sections of the tree can be shared, it can exploit the usual
 * sparseness of such a mapping table.  The tree is always NBYTS levels
 * deep (in the past it was shallower during construction but was "filled"
 * to full depth at the end of that); areas that are unaltered as yet point
 * to "fill blocks" which are entirely WHITE in color.
 */

/* the tree itself */
struct colors {
	color ccolor[BYTTAB];
};
struct ptrs {
	union tree *pptr[BYTTAB];
};
union tree {
	struct colors colors;
	struct ptrs ptrs;
};
#define	tcolor	colors.ccolor
#define	tptr	ptrs.pptr

/* internal per-color structure for the color machinery */
struct colordesc {
	uchr nchrs;		/* number of chars of this color */
	color sub;		/* open subcolor (if any); free chain ptr */
#		define	NOSUB	COLORLESS
	struct arc *arcs;	/* color chain */
	int flags;
#		define	FREECOL	01	/* currently free */
#		define	PSEUDO	02	/* pseudocolor, no real chars */
#	define	UNUSEDCOLOR(cd)	((cd)->flags&FREECOL)
	union tree *block;	/* block of solid color, if any */
};

/* the color map itself */
struct colormap {
	int magic;
#		define	CMMAGIC	0x876
	struct vars *v;			/* for compile error reporting */
	size_t ncds;			/* number of colordescs */
	size_t max;			/* highest in use */
	color free;			/* beginning of free chain (if non-0) */
	struct colordesc *cd;
#	define	CDEND(cm)	(&(cm)->cd[(cm)->max + 1])
#		define	NINLINECDS	((size_t)10)
	struct colordesc cdspace[NINLINECDS];
	union tree tree[NBYTS];		/* tree top, plus fill blocks */
};

/* optimization magic to do fast chr->color mapping */
#define	B0(c)	((c) & BYTMASK)
#define	B1(c)	(((c)>>BYTBITS) & BYTMASK)
#define	B2(c)	(((c)>>(2*BYTBITS)) & BYTMASK)
#define	B3(c)	(((c)>>(3*BYTBITS)) & BYTMASK)
#if NBYTS == 1
#define	GETCOLOR(cm, c)	((cm)->tree->tcolor[B0(c)])
#endif
/* beware, for NBYTS>1, GETCOLOR() is unsafe -- 2nd arg used repeatedly */
#if NBYTS == 2
#define	GETCOLOR(cm, c)	((cm)->tree->tptr[B1(c)]->tcolor[B0(c)])
#endif
#if NBYTS == 4
#define	GETCOLOR(cm, c)	((cm)->tree->tptr[B3(c)]->tptr[B2(c)]->tptr[B1(c)]->tcolor[B0(c)])
#endif



/*
 * Interface definitions for locale-interface functions in locale.c.
 * Multi-character collating elements (MCCEs) cause most of the trouble.
 */
struct cvec {
	int nchrs;		/* number of chrs */
	int chrspace;		/* number of chrs possible */
	chr *chrs;		/* pointer to vector of chrs */
	int nranges;		/* number of ranges (chr pairs) */
	int rangespace;		/* number of chrs possible */
	chr *ranges;		/* pointer to vector of chr pairs */
	int nmcces;		/* number of MCCEs */
	int mccespace;		/* number of MCCEs possible */
	int nmccechrs;		/* number of chrs used for MCCEs */
	chr *mcces[1];		/* pointers to 0-terminated MCCEs */
				/* and both batches of chrs are on the end */
};

/* caution:  this value cannot be changed easily */
#define	MAXMCCE	2		/* length of longest MCCE */



/*
 * definitions for NFA internal representation
 *
 * Having a "from" pointer within each arc may seem redundant, but it
 * saves a lot of hassle.
 */
struct state;

struct arc {
	int type;
#		define	ARCFREE	'\0'
	color co;
	struct state *from;	/* where it's from (and contained within) */
	struct state *to;	/* where it's to */
	struct arc *outchain;	/* *from's outs chain or free chain */
#	define	freechain	outchain
	struct arc *inchain;	/* *to's ins chain */
	struct arc *colorchain;	/* color's arc chain */
};

struct arcbatch {		/* for bulk allocation of arcs */
	struct arcbatch *next;
#	define	ABSIZE	10
	struct arc a[ABSIZE];
};

struct state {
	int no;
#		define	FREESTATE	(-1)
	char flag;		/* marks special states */
	int nins;		/* number of inarcs */
	struct arc *ins;	/* chain of inarcs */
	int nouts;		/* number of outarcs */
	struct arc *outs;	/* chain of outarcs */
	struct arc *free;	/* chain of free arcs */
	struct state *tmp;	/* temporary for traversal algorithms */
	struct state *next;	/* chain for traversing all */
	struct state *prev;	/* back chain */
	struct arcbatch oas;	/* first arcbatch, avoid malloc in easy case */
};

struct nfa {
	struct state *pre;	/* pre-initial state */
	struct state *init;	/* initial state */
	struct state *final;	/* final state */
	struct state *post;	/* post-final state */
	int nstates;		/* for numbering states */
	struct state *states;	/* state-chain header */
	struct state *slast;	/* tail of the chain */
	struct state *free;	/* free list */
	struct colormap *cm;	/* the color map */
	color bos[2];		/* colors, if any, assigned to BOS and BOL */
	color eos[2];		/* colors, if any, assigned to EOS and EOL */
	struct vars *v;		/* simplifies compile error reporting */
	struct nfa *parent;	/* parent NFA, if any */
};



/*
 * definitions for compacted NFA
 */
struct carc {
	color co;		/* COLORLESS is list terminator */
	int to;			/* state number */
};

struct cnfa {
	int nstates;		/* number of states */
	int ncolors;		/* number of colors */
	int flags;
#		define	HASLACONS	01	/* uses lookahead constraints */
	int pre;		/* setup state number */
	int post;		/* teardown state number */
	color bos[2];		/* colors, if any, assigned to BOS and BOL */
	color eos[2];		/* colors, if any, assigned to EOS and EOL */
	struct carc **states;	/* vector of pointers to outarc lists */
	struct carc *arcs;	/* the area for the lists */
};
#define	ZAPCNFA(cnfa)	((cnfa).nstates = 0)
#define	NULLCNFA(cnfa)	((cnfa).nstates == 0)



/*
 * subexpression tree
 */
struct subre {
	char op;		/* '|', '.' (concat), 'b' (backref), '(', '=' */
	char flags;
#		define	LONGER	01	/* prefers longer match */
#		define	SHORTER	02	/* prefers shorter match */
#		define	MIXED	04	/* mixed preference below */
#		define	CAP	010	/* capturing parens below */
#		define	BACKR	020	/* back reference below */
#		define	INUSE	0100	/* in use in final tree */
#		define	LOCAL	03	/* bits which may not propagate up */
#		define	LMIX(f)	((f)<<2)	/* LONGER -> MIXED */
#		define	SMIX(f)	((f)<<1)	/* SHORTER -> MIXED */
#		define	UP(f)	(((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
#		define	MESSY(f)	((f)&(MIXED|CAP|BACKR))
#		define	PREF(f)	((f)&LOCAL)
#		define	PREF2(f1, f2)	((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
#		define	COMBINE(f1, f2)	(UP((f1)|(f2)) | PREF2(f1, f2))
	short retry;		/* index into retry memory */
	int subno;		/* subexpression number (for 'b' and '(') */
	short min;		/* min repetitions, for backref only */
	short max;		/* max repetitions, for backref only */
	struct subre *left;	/* left child, if any (also freelist chain) */
	struct subre *right;	/* right child, if any */
	struct state *begin;	/* outarcs from here... */
	struct state *end;	/* ...ending in inarcs here */
	struct cnfa cnfa;	/* compacted NFA, if any */
	struct subre *chain;	/* for bookkeeping and error cleanup */
};



/*
 * table of function pointers for generic manipulation functions
 * A regex_t's re_fns points to one of these.
 */
struct fns {
	VOID FUNCPTR(free, (regex_t *));
};



/*
 * the insides of a regex_t, hidden behind a void *
 */
struct guts {
	int magic;
#		define	GUTSMAGIC	0xfed9
	int cflags;		/* copy of compile flags */
	int info;		/* copy of re_info */
	size_t nsub;		/* copy of re_nsub */
	struct subre *tree;
	struct cnfa search;	/* for fast preliminary search */
	int ntree;
	struct colormap cmap;
	int FUNCPTR(compare, (CONST chr *, CONST chr *, size_t));
	struct subre *lacons;	/* lookahead-constraint vector */
	int nlacons;		/* size of lacons */
	int usedshorter;	/* used non-greedy quantifiers? */
	int unmatchable;	/* cannot match anything? */
};

Added generic/tcl.decls.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































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

library tcl

# Define the tcl interface with several sub interfaces:
#     tclPlat	 - platform specific public
#     tclInt	 - generic private
#     tclPlatInt - platform specific private

interface tcl
hooks {tclPlat tclInt tclIntPlat}

# Declare each of the functions in the public Tcl interface.  Note that
# the an index should never be reused for a different function in order
# to preserve backwards compatibility.

declare 0 generic {
    int Tcl_PkgProvideEx(Tcl_Interp *interp, char *name, char *version, \
	    ClientData clientData)
}
declare 1 generic {
    char * Tcl_PkgRequireEx(Tcl_Interp *interp, char *name, char *version, \
	    int exact, ClientData *clientDataPtr)
}
declare 2 generic {
    void Tcl_Panic(char *format, ...)
}
declare 3 generic {
    char * Tcl_Alloc(unsigned int size)
}
declare 4 generic {
    void Tcl_Free(char *ptr)
}
declare 5 generic {
    char * Tcl_Realloc(char *ptr, unsigned int size)
}
declare 6 generic {
    char * Tcl_DbCkalloc(unsigned int size, char *file, int line)
}
declare 7 generic {
    int Tcl_DbCkfree(char *ptr, char *file, int line)
}
declare 8 generic {
    char * Tcl_DbCkrealloc(char *ptr, unsigned int size, char *file, int line)
}

# Tcl_CreateFileHandler and Tcl_DeleteFileHandler are only available on unix,
# but they are part of the old generic interface, so we include them here for
# compatibility reasons.

declare 9 unix {
    void Tcl_CreateFileHandler(int fd, int mask, Tcl_FileProc *proc, \
	    ClientData clientData)
}
declare 10 unix {
    void Tcl_DeleteFileHandler(int fd)
}

declare 11 generic {
    void Tcl_SetTimer(Tcl_Time *timePtr)
}
declare 12 generic {
    void Tcl_Sleep(int ms)
}
declare 13 generic {
    int Tcl_WaitForEvent(Tcl_Time *timePtr)
}
declare 14 generic {
    int Tcl_AppendAllObjTypes(Tcl_Interp *interp, Tcl_Obj *objPtr)
}
declare 15 generic {
    void Tcl_AppendStringsToObj(Tcl_Obj *objPtr, ...)
}
declare 16 generic {
    void Tcl_AppendToObj(Tcl_Obj *objPtr, char *bytes, int length)
}
declare 17 generic {
    Tcl_Obj * Tcl_ConcatObj(int objc, Tcl_Obj *CONST objv[])
}
declare 18 generic {
    int Tcl_ConvertToType(Tcl_Interp *interp, Tcl_Obj *objPtr, \
	    Tcl_ObjType *typePtr)
}
declare 19 generic {
    void Tcl_DbDecrRefCount(Tcl_Obj *objPtr, char *file, int line)
}
declare 20 generic {
    void Tcl_DbIncrRefCount(Tcl_Obj *objPtr, char *file, int line)
}
declare 21 generic {
    int Tcl_DbIsShared(Tcl_Obj *objPtr, char *file, int line)
}
declare 22 generic {
    Tcl_Obj * Tcl_DbNewBooleanObj(int boolValue, char *file, int line)
}
declare 23 generic {
    Tcl_Obj * Tcl_DbNewByteArrayObj(unsigned char *bytes, int length, \
	    char *file, int line)
}
declare 24 generic {
    Tcl_Obj * Tcl_DbNewDoubleObj(double doubleValue, char *file, int line)
}
declare 25 generic {
    Tcl_Obj * Tcl_DbNewListObj(int objc, Tcl_Obj *CONST objv[], char *file, \
	    int line)
}
declare 26 generic {
    Tcl_Obj * Tcl_DbNewLongObj(long longValue, char *file, int line)
}
declare 27 generic {
    Tcl_Obj * Tcl_DbNewObj(char *file, int line)
}
declare 28 generic {
    Tcl_Obj * Tcl_DbNewStringObj(CONST char *bytes, int length, \
	    char *file, int line)
}
declare 29 generic {
    Tcl_Obj * Tcl_DuplicateObj(Tcl_Obj *objPtr)
}
declare 30 generic {
    void TclFreeObj(Tcl_Obj *objPtr)
}
declare 31 generic {
    int Tcl_GetBoolean(Tcl_Interp *interp, char *str, int *boolPtr)
}
declare 32 generic {
    int Tcl_GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, \
	    int *boolPtr)
}
declare 33 generic {
    unsigned char * Tcl_GetByteArrayFromObj(Tcl_Obj *objPtr, int *lengthPtr)
}
declare 34 generic {
    int Tcl_GetDouble(Tcl_Interp *interp, char *str, double *doublePtr)
}
declare 35 generic {
    int Tcl_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, \
	    double *doublePtr)
}
declare 36 generic {
    int Tcl_GetIndexFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, \
	    char **tablePtr, char *msg, int flags, int *indexPtr)
}
declare 37 generic {
    int Tcl_GetInt(Tcl_Interp *interp, char *str, int *intPtr)
}
declare 38 generic {
    int Tcl_GetIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr)
}
declare 39 generic {
    int Tcl_GetLongFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr)
}
declare 40 generic {
    Tcl_ObjType * Tcl_GetObjType(char *typeName)
}
declare 41 generic {
    char * Tcl_GetStringFromObj(Tcl_Obj *objPtr, int *lengthPtr)
}
declare 42 generic {
    void Tcl_InvalidateStringRep(Tcl_Obj *objPtr)
}
declare 43 generic {
    int Tcl_ListObjAppendList(Tcl_Interp *interp, Tcl_Obj *listPtr, \
	    Tcl_Obj *elemListPtr)
}
declare 44 generic {
    int Tcl_ListObjAppendElement(Tcl_Interp *interp, Tcl_Obj *listPtr, \
	    Tcl_Obj *objPtr)
}
declare 45 generic {
    int Tcl_ListObjGetElements(Tcl_Interp *interp, Tcl_Obj *listPtr, \
	    int *objcPtr, Tcl_Obj ***objvPtr)
}
declare 46 generic {
    int Tcl_ListObjIndex(Tcl_Interp *interp, Tcl_Obj *listPtr, int index, \
	    Tcl_Obj **objPtrPtr)
}
declare 47 generic {
    int Tcl_ListObjLength(Tcl_Interp *interp, Tcl_Obj *listPtr, int *intPtr)
}
declare 48 generic {
    int Tcl_ListObjReplace(Tcl_Interp *interp, Tcl_Obj *listPtr, int first, \
	    int count, int objc, Tcl_Obj *CONST objv[])
}
declare 49 generic {
    Tcl_Obj * Tcl_NewBooleanObj(int boolValue)
}
declare 50 generic {
    Tcl_Obj * Tcl_NewByteArrayObj(unsigned char *bytes, int length)
}
declare 51 generic {
    Tcl_Obj * Tcl_NewDoubleObj(double doubleValue)
}
declare 52 generic {
    Tcl_Obj * Tcl_NewIntObj(int intValue)
}
declare 53 generic {
    Tcl_Obj * Tcl_NewListObj(int objc, Tcl_Obj *CONST objv[])
}
declare 54 generic {
    Tcl_Obj * Tcl_NewLongObj(long longValue)
}
declare 55 generic {
    Tcl_Obj * Tcl_NewObj(void)
}
declare 56 generic {
    Tcl_Obj *Tcl_NewStringObj(CONST char *bytes, int length)
}
declare 57 generic {
    void Tcl_SetBooleanObj(Tcl_Obj *objPtr, int boolValue)
}
declare 58 generic {
    unsigned char * Tcl_SetByteArrayLength(Tcl_Obj *objPtr, int length)
}
declare 59 generic {
    void Tcl_SetByteArrayObj(Tcl_Obj *objPtr, unsigned char *bytes, int length)
}
declare 60 generic {
    void Tcl_SetDoubleObj(Tcl_Obj *objPtr, double doubleValue)
}
declare 61 generic {
    void Tcl_SetIntObj(Tcl_Obj *objPtr, int intValue)
}
declare 62 generic {
    void Tcl_SetListObj(Tcl_Obj *objPtr, int objc, Tcl_Obj *CONST objv[])
}
declare 63 generic {
    void Tcl_SetLongObj(Tcl_Obj *objPtr, long longValue)
}
declare 64 generic {
    void Tcl_SetObjLength(Tcl_Obj *objPtr, int length)
}
declare 65 generic {
    void Tcl_SetStringObj(Tcl_Obj *objPtr, char *bytes, int length)
}
declare 66 generic {
    void Tcl_AddErrorInfo(Tcl_Interp *interp, CONST char *message)
}
declare 67 generic {
    void Tcl_AddObjErrorInfo(Tcl_Interp *interp, CONST char *message, \
	    int length)
}
declare 68 generic {
    void Tcl_AllowExceptions(Tcl_Interp *interp)
}
declare 69 generic {
    void Tcl_AppendElement(Tcl_Interp *interp, CONST char *string)
}
declare 70 generic {
    void Tcl_AppendResult(Tcl_Interp *interp, ...)
}
declare 71 generic {
    Tcl_AsyncHandler Tcl_AsyncCreate(Tcl_AsyncProc *proc, \
	    ClientData clientData)
}
declare 72 generic {
    void Tcl_AsyncDelete(Tcl_AsyncHandler async)
}
declare 73 generic {
    int Tcl_AsyncInvoke(Tcl_Interp *interp, int code)
}
declare 74 generic {
    void Tcl_AsyncMark(Tcl_AsyncHandler async)
}
declare 75 generic {
    int Tcl_AsyncReady(void)
}
declare 76 generic {
    void Tcl_BackgroundError(Tcl_Interp *interp)
}
declare 77 generic {
    char Tcl_Backslash(CONST char *src, int *readPtr)
}
declare 78 generic {
    int Tcl_BadChannelOption(Tcl_Interp *interp, char *optionName, \
	    char *optionList)
}
declare 79 generic {
    void Tcl_CallWhenDeleted(Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, \
	    ClientData clientData)
}
declare 80 generic {
    void Tcl_CancelIdleCall(Tcl_IdleProc *idleProc, ClientData clientData)
}
declare 81 generic {
    int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan)
}
declare 82 generic {
    int Tcl_CommandComplete(char *cmd)
}
declare 83 generic {
    char * Tcl_Concat(int argc, char **argv)
}
declare 84 generic {
    int Tcl_ConvertElement(CONST char *src, char *dst, int flags)
}
declare 85 generic {
    int Tcl_ConvertCountedElement(CONST char *src, int length, char *dst, \
	    int flags)
}
declare 86 generic {
    int Tcl_CreateAlias(Tcl_Interp *slave, char *slaveCmd, \
	    Tcl_Interp *target, char *targetCmd, int argc, char **argv)
}
declare 87 generic {
    int Tcl_CreateAliasObj(Tcl_Interp *slave, char *slaveCmd, \
	    Tcl_Interp *target, char *targetCmd, int objc, \
	    Tcl_Obj *CONST objv[])
}
declare 88 generic {
    Tcl_Channel Tcl_CreateChannel(Tcl_ChannelType *typePtr, char *chanName, \
	    ClientData instanceData, int mask)
}
declare 89 generic {
    void Tcl_CreateChannelHandler(Tcl_Channel chan, int mask, \
	    Tcl_ChannelProc *proc, ClientData clientData)
}
declare 90 generic {
    void Tcl_CreateCloseHandler(Tcl_Channel chan, Tcl_CloseProc *proc, \
	    ClientData clientData)
}
declare 91 generic {
    Tcl_Command Tcl_CreateCommand(Tcl_Interp *interp, char *cmdName, \
	    Tcl_CmdProc *proc, ClientData clientData, \
	    Tcl_CmdDeleteProc *deleteProc)
}
declare 92 generic {
    void Tcl_CreateEventSource(Tcl_EventSetupProc *setupProc, \
	    Tcl_EventCheckProc *checkProc, ClientData clientData)
}
declare 93 generic {
    void Tcl_CreateExitHandler(Tcl_ExitProc *proc, ClientData clientData)
}
declare 94 generic {
    Tcl_Interp * Tcl_CreateInterp(void)
}
declare 95 generic {
    void Tcl_CreateMathFunc(Tcl_Interp *interp, char *name, int numArgs, \
	    Tcl_ValueType *argTypes, Tcl_MathProc *proc, ClientData clientData)
}
declare 96 generic {
    Tcl_Command Tcl_CreateObjCommand(Tcl_Interp *interp, char *cmdName, \
	    Tcl_ObjCmdProc *proc, ClientData clientData, \
	    Tcl_CmdDeleteProc *deleteProc)
}
declare 97 generic {
    Tcl_Interp * Tcl_CreateSlave(Tcl_Interp *interp, char *slaveName, \
	    int isSafe)
}
declare 98 generic {
    Tcl_TimerToken Tcl_CreateTimerHandler(int milliseconds, \
	    Tcl_TimerProc *proc, ClientData clientData)
}
declare 99 generic {
    Tcl_Trace Tcl_CreateTrace(Tcl_Interp *interp, int level, \
	    Tcl_CmdTraceProc *proc, ClientData clientData)
}
declare 100 generic {
    void Tcl_DeleteAssocData(Tcl_Interp *interp, char *name)
}
declare 101 generic {
    void Tcl_DeleteChannelHandler(Tcl_Channel chan, Tcl_ChannelProc *proc, \
	    ClientData clientData)
}
declare 102 generic {
    void Tcl_DeleteCloseHandler(Tcl_Channel chan, Tcl_CloseProc *proc, \
	    ClientData clientData)
}
declare 103 generic {
    int Tcl_DeleteCommand(Tcl_Interp *interp, char *cmdName)
}
declare 104 generic {
    int Tcl_DeleteCommandFromToken(Tcl_Interp *interp, Tcl_Command command)
}
declare 105 generic {
    void Tcl_DeleteEvents(Tcl_EventDeleteProc *proc, ClientData clientData)
}
declare 106 generic {
    void Tcl_DeleteEventSource(Tcl_EventSetupProc *setupProc, \
	    Tcl_EventCheckProc *checkProc, ClientData clientData)
}
declare 107 generic {
    void Tcl_DeleteExitHandler(Tcl_ExitProc *proc, ClientData clientData)
}
declare 108 generic {
    void Tcl_DeleteHashEntry(Tcl_HashEntry *entryPtr)
}
declare 109 generic {
    void Tcl_DeleteHashTable(Tcl_HashTable *tablePtr)
}
declare 110 generic {
    void Tcl_DeleteInterp(Tcl_Interp *interp)
}
declare 111 generic {
    void Tcl_DetachPids(int numPids, Tcl_Pid *pidPtr)
}
declare 112 generic {
    void Tcl_DeleteTimerHandler(Tcl_TimerToken token)
}
declare 113 generic {
    void Tcl_DeleteTrace(Tcl_Interp *interp, Tcl_Trace trace)
}
declare 114 generic {
    void Tcl_DontCallWhenDeleted(Tcl_Interp *interp, \
	    Tcl_InterpDeleteProc *proc, ClientData clientData)
}
declare 115 generic {
    int Tcl_DoOneEvent(int flags)
}
declare 116 generic {
    void Tcl_DoWhenIdle(Tcl_IdleProc *proc, ClientData clientData)
}
declare 117 generic {
    char * Tcl_DStringAppend(Tcl_DString *dsPtr, CONST char *str, int length)
}
declare 118 generic {
    char * Tcl_DStringAppendElement(Tcl_DString *dsPtr, CONST char *string)
}
declare 119 generic {
    void Tcl_DStringEndSublist(Tcl_DString *dsPtr)
}
declare 120 generic {
    void Tcl_DStringFree(Tcl_DString *dsPtr)
}
declare 121 generic {
    void Tcl_DStringGetResult(Tcl_Interp *interp, Tcl_DString *dsPtr)
}
declare 122 generic {
    void Tcl_DStringInit(Tcl_DString *dsPtr)
}
declare 123 generic {
    void Tcl_DStringResult(Tcl_Interp *interp, Tcl_DString *dsPtr)
}
declare 124 generic {
    void Tcl_DStringSetLength(Tcl_DString *dsPtr, int length)
}
declare 125 generic {
    void Tcl_DStringStartSublist(Tcl_DString *dsPtr)
}
declare 126 generic {
    int Tcl_Eof(Tcl_Channel chan)
}
declare 127 generic {
    char * Tcl_ErrnoId(void)
}
declare 128 generic {
    char * Tcl_ErrnoMsg(int err)
}
declare 129 generic {
    int Tcl_Eval(Tcl_Interp *interp, char *string)
}
declare 130 generic {
    int Tcl_EvalFile(Tcl_Interp *interp, char *fileName)
}
declare 131 generic {
    int Tcl_EvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
}
declare 132 generic {
    void Tcl_EventuallyFree(ClientData clientData, Tcl_FreeProc *freeProc)
}
declare 133 generic {
    void Tcl_Exit(int status)
}
declare 134 generic {
    int Tcl_ExposeCommand(Tcl_Interp *interp, char *hiddenCmdToken, \
	    char *cmdName)
}
declare 135 generic {
    int Tcl_ExprBoolean(Tcl_Interp *interp, char *str, int *ptr)
}
declare 136 generic {
    int Tcl_ExprBooleanObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *ptr)
}
declare 137 generic {
    int Tcl_ExprDouble(Tcl_Interp *interp, char *str, double *ptr)
}
declare 138 generic {
    int Tcl_ExprDoubleObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *ptr)
}
declare 139 generic {
    int Tcl_ExprLong(Tcl_Interp *interp, char *str, long *ptr)
}
declare 140 generic {
    int Tcl_ExprLongObj(Tcl_Interp *interp, Tcl_Obj *objPtr, long *ptr)
}
declare 141 generic {
    int Tcl_ExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr, \
	    Tcl_Obj **resultPtrPtr)
}
declare 142 generic {
    int Tcl_ExprString(Tcl_Interp *interp, char *string)
}
declare 143 generic {
    void Tcl_Finalize(void)
}
declare 144 generic {
    void Tcl_FindExecutable(CONST char *argv0)
}
declare 145 generic {
    Tcl_HashEntry * Tcl_FirstHashEntry(Tcl_HashTable *tablePtr, \
	    Tcl_HashSearch *searchPtr)
}
declare 146 generic {
    int Tcl_Flush(Tcl_Channel chan)
}
declare 147 generic {
    void Tcl_FreeResult(Tcl_Interp *interp)
}
declare 148 generic {
    int Tcl_GetAlias(Tcl_Interp *interp, char *slaveCmd, \
	    Tcl_Interp **targetInterpPtr, char **targetCmdPtr, int *argcPtr, \
	    char ***argvPtr)
}
declare 149 generic {
    int Tcl_GetAliasObj(Tcl_Interp *interp, char *slaveCmd, \
	    Tcl_Interp **targetInterpPtr, char **targetCmdPtr, int *objcPtr, \
	    Tcl_Obj ***objv)
}
declare 150 generic {
    ClientData Tcl_GetAssocData(Tcl_Interp *interp, char *name, \
	    Tcl_InterpDeleteProc **procPtr)
}
declare 151 generic {
    Tcl_Channel Tcl_GetChannel(Tcl_Interp *interp, char *chanName, \
	    int *modePtr)
}
declare 152 generic {
    int Tcl_GetChannelBufferSize(Tcl_Channel chan)
}
declare 153 generic {
    int Tcl_GetChannelHandle(Tcl_Channel chan, int direction, \
	    ClientData *handlePtr)
}
declare 154 generic {
    ClientData Tcl_GetChannelInstanceData(Tcl_Channel chan)
}
declare 155 generic {
    int Tcl_GetChannelMode(Tcl_Channel chan)
}
declare 156 generic {
    char * Tcl_GetChannelName(Tcl_Channel chan)
}
declare 157 generic {
    int Tcl_GetChannelOption(Tcl_Interp *interp, Tcl_Channel chan, \
	    char *optionName, Tcl_DString *dsPtr)
}
declare 158 generic {
    Tcl_ChannelType * Tcl_GetChannelType(Tcl_Channel chan)
}
declare 159 generic {
    int Tcl_GetCommandInfo(Tcl_Interp *interp, char *cmdName, \
	    Tcl_CmdInfo *infoPtr)
}
declare 160 generic {
    char * Tcl_GetCommandName(Tcl_Interp *interp, Tcl_Command command)
}
declare 161 generic {
    int Tcl_GetErrno(void)
}
declare 162 generic {
    char * Tcl_GetHostName(void)
}
declare 163 generic {
    int Tcl_GetInterpPath(Tcl_Interp *askInterp, Tcl_Interp *slaveInterp)
}
declare 164 generic {
    Tcl_Interp * Tcl_GetMaster(Tcl_Interp *interp)
}
declare 165 generic {
    CONST char * Tcl_GetNameOfExecutable(void)
}
declare 166 generic {
    Tcl_Obj * Tcl_GetObjResult(Tcl_Interp *interp)
}

# Tcl_GetOpenFile is only available on unix, but it is a part of the old
# generic interface, so we inlcude it here for compatibility reasons.

declare 167 unix {
    int Tcl_GetOpenFile(Tcl_Interp *interp, char *str, int write, \
	    int checkUsage, ClientData *filePtr)
}

declare 168 generic {
    Tcl_PathType Tcl_GetPathType(char *path)
}
declare 169 generic {
    int Tcl_Gets(Tcl_Channel chan, Tcl_DString *dsPtr)
}
declare 170 generic {
    int Tcl_GetsObj(Tcl_Channel chan, Tcl_Obj *objPtr)
}
declare 171 generic {
    int Tcl_GetServiceMode(void)
}
declare 172 generic {
    Tcl_Interp * Tcl_GetSlave(Tcl_Interp *interp, char *slaveName)
}
declare 173 generic {
    Tcl_Channel Tcl_GetStdChannel(int type)
}
declare 174 generic {
    char * Tcl_GetStringResult(Tcl_Interp *interp)
}
declare 175 generic {
    char * Tcl_GetVar(Tcl_Interp *interp, char *varName, int flags)
}
declare 176 generic {
    char * Tcl_GetVar2(Tcl_Interp *interp, char *part1, char *part2, int flags)
}
declare 177 generic {
    int Tcl_GlobalEval(Tcl_Interp *interp, char *command)
}
declare 178 generic {
    int Tcl_GlobalEvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
}
declare 179 generic {
    int Tcl_HideCommand(Tcl_Interp *interp, char *cmdName, \
	    char *hiddenCmdToken)
}
declare 180 generic {
    int Tcl_Init(Tcl_Interp *interp)
}
declare 181 generic {
    void Tcl_InitHashTable(Tcl_HashTable *tablePtr, int keyType)
}
declare 182 generic {
    int Tcl_InputBlocked(Tcl_Channel chan)
}
declare 183 generic {
    int Tcl_InputBuffered(Tcl_Channel chan)
}
declare 184 generic {
    int Tcl_InterpDeleted(Tcl_Interp *interp)
}
declare 185 generic {
    int Tcl_IsSafe(Tcl_Interp *interp)
}
declare 186 generic {
    char * Tcl_JoinPath(int argc, char **argv, Tcl_DString *resultPtr)
}
declare 187 generic {
    int Tcl_LinkVar(Tcl_Interp *interp, char *varName, char *addr, int type)
}

# This slot is reserved for use by the plus patch:
#  declare 188 generic {
#      Tcl_MainLoop
#  }

declare 189 generic {
    Tcl_Channel Tcl_MakeFileChannel(ClientData handle, int mode)
}
declare 190 generic {
    int Tcl_MakeSafe(Tcl_Interp *interp)
}
declare 191 generic {
    Tcl_Channel Tcl_MakeTcpClientChannel(ClientData tcpSocket)
}
declare 192 generic {
    char * Tcl_Merge(int argc, char **argv)
}
declare 193 generic {
    Tcl_HashEntry * Tcl_NextHashEntry(Tcl_HashSearch *searchPtr)
}
declare 194 generic {
    void Tcl_NotifyChannel(Tcl_Channel channel, int mask)
}
declare 195 generic {
    Tcl_Obj * Tcl_ObjGetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, \
	    Tcl_Obj *part2Ptr, int flags)
}
declare 196 generic {
    Tcl_Obj * Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, \
	    Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags)
}
declare 197 generic {
    Tcl_Channel Tcl_OpenCommandChannel(Tcl_Interp *interp, int argc, \
	    char **argv, int flags)
}
declare 198 generic {
    Tcl_Channel Tcl_OpenFileChannel(Tcl_Interp *interp, char *fileName, \
	    char *modeString, int permissions)
}
declare 199 generic {
    Tcl_Channel Tcl_OpenTcpClient(Tcl_Interp *interp, int port, \
	    char *address, char *myaddr, int myport, int async)
}
declare 200 generic {
    Tcl_Channel Tcl_OpenTcpServer(Tcl_Interp *interp, int port, char *host, \
	    Tcl_TcpAcceptProc *acceptProc, ClientData callbackData)
}
declare 201 generic {
    void Tcl_Preserve(ClientData data)
}
declare 202 generic {
    void Tcl_PrintDouble(Tcl_Interp *interp, double value, char *dst)
}
declare 203 generic {
    int Tcl_PutEnv(CONST char *string)
}
declare 204 generic {
    char * Tcl_PosixError(Tcl_Interp *interp)
}
declare 205 generic {
    void Tcl_QueueEvent(Tcl_Event *evPtr, Tcl_QueuePosition position)
}
declare 206 generic {
    int Tcl_Read(Tcl_Channel chan, char *bufPtr, int toRead)
}
declare 207 generic {
    void Tcl_ReapDetachedProcs(void)
}
declare 208 generic {
    int Tcl_RecordAndEval(Tcl_Interp *interp, char *cmd, int flags)
}
declare 209 generic {
    int Tcl_RecordAndEvalObj(Tcl_Interp *interp, Tcl_Obj *cmdPtr, int flags)
}
declare 210 generic {
    void Tcl_RegisterChannel(Tcl_Interp *interp, Tcl_Channel chan)
}
declare 211 generic {
    void Tcl_RegisterObjType(Tcl_ObjType *typePtr)
}
declare 212 generic {
    Tcl_RegExp Tcl_RegExpCompile(Tcl_Interp *interp, char *string)
}
declare 213 generic {
    int Tcl_RegExpExec(Tcl_Interp *interp, Tcl_RegExp regexp, \
	    CONST char *str, CONST char *start)
}
declare 214 generic {
    int Tcl_RegExpMatch(Tcl_Interp *interp, char *str, char *pattern)
}
declare 215 generic {
    void Tcl_RegExpRange(Tcl_RegExp regexp, int index, char **startPtr, \
	    char **endPtr)
}
declare 216 generic {
    void Tcl_Release(ClientData clientData)
}
declare 217 generic {
    void Tcl_ResetResult(Tcl_Interp *interp)
}
declare 218 generic {
    int Tcl_ScanElement(CONST char *str, int *flagPtr)
}
declare 219 generic {
    int Tcl_ScanCountedElement(CONST char *str, int length, int *flagPtr)
}
declare 220 generic {
    int Tcl_Seek(Tcl_Channel chan, int offset, int mode)
}
declare 221 generic {
    int Tcl_ServiceAll(void)
}
declare 222 generic {
    int Tcl_ServiceEvent(int flags)
}
declare 223 generic {
    void Tcl_SetAssocData(Tcl_Interp *interp, char *name, \
	    Tcl_InterpDeleteProc *proc, ClientData clientData)
}
declare 224 generic {
    void Tcl_SetChannelBufferSize(Tcl_Channel chan, int sz)
}
declare 225 generic {
    int Tcl_SetChannelOption(Tcl_Interp *interp, Tcl_Channel chan, \
	    char *optionName, char *newValue)
}
declare 226 generic {
    int Tcl_SetCommandInfo(Tcl_Interp *interp, char *cmdName, \
	    Tcl_CmdInfo *infoPtr)
}
declare 227 generic {
    void Tcl_SetErrno(int err)
}
declare 228 generic {
    void Tcl_SetErrorCode(Tcl_Interp *interp, ...)
}
declare 229 generic {
    void Tcl_SetMaxBlockTime(Tcl_Time *timePtr)
}
declare 230 generic {
    void Tcl_SetPanicProc(Tcl_PanicProc *panicProc)
}
declare 231 generic {
    int Tcl_SetRecursionLimit(Tcl_Interp *interp, int depth)
}
declare 232 generic {
    void Tcl_SetResult(Tcl_Interp *interp, char *str, \
	    Tcl_FreeProc *freeProc)
}
declare 233 generic {
    int Tcl_SetServiceMode(int mode)
}
declare 234 generic {
    void Tcl_SetObjErrorCode(Tcl_Interp *interp, Tcl_Obj *errorObjPtr)
}
declare 235 generic {
    void Tcl_SetObjResult(Tcl_Interp *interp, Tcl_Obj *resultObjPtr)
}
declare 236 generic {
    void Tcl_SetStdChannel(Tcl_Channel channel, int type)
}
declare 237 generic {
    char * Tcl_SetVar(Tcl_Interp *interp, char *varName, char *newValue, \
	    int flags)
}
declare 238 generic {
    char * Tcl_SetVar2(Tcl_Interp *interp, char *part1, char *part2, \
	    char *newValue, int flags)
}
declare 239 generic {
    char * Tcl_SignalId(int sig)
}
declare 240 generic {
    char * Tcl_SignalMsg(int sig)
}
declare 241 generic {
    void Tcl_SourceRCFile(Tcl_Interp *interp)
}
declare 242 generic {
    int Tcl_SplitList(Tcl_Interp *interp, CONST char *listStr, int *argcPtr, \
	    char ***argvPtr)
}
declare 243 generic {
    void Tcl_SplitPath(CONST char *path, int *argcPtr, char ***argvPtr)
}
declare 244 generic {
    void Tcl_StaticPackage(Tcl_Interp *interp, char *pkgName, \
	    Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc)
}
declare 245 generic {
    int Tcl_StringMatch(CONST char *str, CONST char *pattern)
}
declare 246 generic {
    int Tcl_Tell(Tcl_Channel chan)
}
declare 247 generic {
    int Tcl_TraceVar(Tcl_Interp *interp, char *varName, int flags, \
	    Tcl_VarTraceProc *proc, ClientData clientData)
}
declare 248 generic {
    int Tcl_TraceVar2(Tcl_Interp *interp, char *part1, char *part2, \
	    int flags, Tcl_VarTraceProc *proc, ClientData clientData)
}
declare 249 generic {
    char * Tcl_TranslateFileName(Tcl_Interp *interp, char *name, \
	    Tcl_DString *bufferPtr)
}
declare 250 generic {
    int Tcl_Ungets(Tcl_Channel chan, char *str, int len, int atHead)
}
declare 251 generic {
    void Tcl_UnlinkVar(Tcl_Interp *interp, char *varName)
}
declare 252 generic {
    int Tcl_UnregisterChannel(Tcl_Interp *interp, Tcl_Channel chan)
}
declare 253 generic {
    int Tcl_UnsetVar(Tcl_Interp *interp, char *varName, int flags)
}
declare 254 generic {
    int Tcl_UnsetVar2(Tcl_Interp *interp, char *part1, char *part2, int flags)
}
declare 255 generic {
    void Tcl_UntraceVar(Tcl_Interp *interp, char *varName, int flags, \
	    Tcl_VarTraceProc *proc, ClientData clientData)
}
declare 256 generic {
    void Tcl_UntraceVar2(Tcl_Interp *interp, char *part1, char *part2, \
	    int flags, Tcl_VarTraceProc *proc, ClientData clientData)
}
declare 257 generic {
    void Tcl_UpdateLinkedVar(Tcl_Interp *interp, char *varName)
}
declare 258 generic {
    int Tcl_UpVar(Tcl_Interp *interp, char *frameName, char *varName, \
	    char *localName, int flags)
}
declare 259 generic {
    int Tcl_UpVar2(Tcl_Interp *interp, char *frameName, char *part1, \
	    char *part2, char *localName, int flags)
}
declare 260 generic {
    int Tcl_VarEval(Tcl_Interp *interp, ...)
}
declare 261 generic {
    ClientData Tcl_VarTraceInfo(Tcl_Interp *interp, char *varName, \
	    int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData)
}
declare 262 generic {
    ClientData Tcl_VarTraceInfo2(Tcl_Interp *interp, char *part1, \
	    char *part2, int flags, Tcl_VarTraceProc *procPtr, \
	    ClientData prevClientData)
}
declare 263 generic {
    int Tcl_Write(Tcl_Channel chan, char *s, int slen)
}
declare 264 generic {
    void Tcl_WrongNumArgs(Tcl_Interp *interp, int objc, \
	    Tcl_Obj *CONST objv[], char *message)
}
declare 265 generic {
    int Tcl_DumpActiveMemory(char *fileName)
}
declare 266 generic {
    void Tcl_ValidateAllMemory(char *file, int line)
}
declare 267 generic {
    void Tcl_AppendResultVA(Tcl_Interp *interp, va_list argList)
}
declare 268 generic {
    void Tcl_AppendStringsToObjVA(Tcl_Obj *objPtr, va_list argList)
}
declare 269 generic {
    char * Tcl_HashStats(Tcl_HashTable *tablePtr)
}
declare 270 generic {
    char * Tcl_ParseVar(Tcl_Interp *interp, char *str, char **termPtr)
}
declare 271 generic {
    char * Tcl_PkgPresent(Tcl_Interp *interp, char *name, char *version, \
	    int exact)
}
declare 272 generic {
    char * Tcl_PkgPresentEx(Tcl_Interp *interp, char *name, char *version, \
	    int exact, ClientData *clientDataPtr)
}
declare 273 generic {
    int Tcl_PkgProvide(Tcl_Interp *interp, char *name, char *version)
}
declare 274 generic {
    char * Tcl_PkgRequire(Tcl_Interp *interp, char *name, char *version, \
	    int exact)
}
declare 275 generic {
    void Tcl_SetErrorCodeVA(Tcl_Interp *interp, va_list argList)
}
declare 276 generic {
    int  Tcl_VarEvalVA(Tcl_Interp *interp, va_list argList)
}
declare 277 generic {
    Tcl_Pid Tcl_WaitPid(Tcl_Pid pid, int *statPtr, int options)
}
declare 278 generic {
    void Tcl_PanicVA(char *format, va_list argList)
}
declare 279 generic {
    void Tcl_GetVersion(int *major, int *minor, int *patchLevel, int *type)
}
declare 280 generic {
    void Tcl_InitMemory(Tcl_Interp *interp)
}

# Reserved for future use (8.0.x vs. 8.1)
#  declare 281 generic {
#  }
#  declare 282 generic {
#  }
#  declare 283 generic {
#  }
#  declare 284 generic {
#  }
#  declare 285 generic {
#  }


# Added in 8.1:

declare 286 generic {
    void Tcl_AppendObjToObj(Tcl_Obj *objPtr, Tcl_Obj *appendObjPtr)
}
declare 287 generic {
    Tcl_Encoding Tcl_CreateEncoding(Tcl_EncodingType *typePtr)
}
declare 288 generic {
    void Tcl_CreateThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData)
}
declare 289 generic {
    void Tcl_DeleteThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData)
}
declare 290 generic {
    void Tcl_DiscardResult(Tcl_SavedResult *statePtr)
}
declare 291 generic {
    int Tcl_EvalEx(Tcl_Interp *interp, char *script, int numBytes, int flags)
}
declare 292 generic {
    int Tcl_EvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], \
	    int flags)
}
declare 293 generic {
    int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
}
declare 294 generic {
    void Tcl_ExitThread(int status)
}
declare 295 generic {
    int Tcl_ExternalToUtf(Tcl_Interp *interp, Tcl_Encoding encoding, \
	    CONST char *src, int srcLen, int flags, \
	    Tcl_EncodingState *statePtr, char *dst, int dstLen, \
	    int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr)
}
declare 296 generic {
    char * Tcl_ExternalToUtfDString(Tcl_Encoding encoding, CONST char *src, \
	    int srcLen, Tcl_DString *dsPtr)
}
declare 297 generic {
    void Tcl_FinalizeThread(void)
}
declare 298 generic {
    void Tcl_FinalizeNotifier(ClientData clientData)
}
declare 299 generic {
    void Tcl_FreeEncoding(Tcl_Encoding encoding)
}
declare 300 generic {
    Tcl_ThreadId Tcl_GetCurrentThread(void)
}
declare 301 generic {
    Tcl_Encoding Tcl_GetEncoding(Tcl_Interp *interp, CONST char *name)
}
declare 302 generic {
    char * Tcl_GetEncodingName(Tcl_Encoding encoding)
}
declare 303 generic {
    void Tcl_GetEncodingNames(Tcl_Interp *interp)
}
declare 304 generic {
    int Tcl_GetIndexFromObjStruct(Tcl_Interp *interp, Tcl_Obj *objPtr, \
	    char **tablePtr, int offset, char *msg, int flags, int *indexPtr)
}
declare 305 generic {
    VOID * Tcl_GetThreadData(Tcl_ThreadDataKey *keyPtr, int size)
}
declare 306 generic {
    Tcl_Obj * Tcl_GetVar2Ex(Tcl_Interp *interp, char *part1, char *part2, \
	    int flags)
}
declare 307 generic {
    ClientData Tcl_InitNotifier(void)
}
declare 308 generic {
    void Tcl_MutexLock(Tcl_Mutex *mutexPtr)
}
declare 309 generic {
    void Tcl_MutexUnlock(Tcl_Mutex *mutexPtr)
}
declare 310 generic {
    void Tcl_ConditionNotify(Tcl_Condition *condPtr)
}
declare 311 generic {
    void Tcl_ConditionWait(Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr, \
	    Tcl_Time *timePtr)
}
declare 312 generic {
    int Tcl_NumUtfChars(CONST char *src, int len)
}
declare 313 generic {
    int Tcl_ReadChars(Tcl_Channel channel, Tcl_Obj *objPtr, int charsToRead, \
	    int appendFlag)
}
declare 314 generic {
    void Tcl_RestoreResult(Tcl_Interp *interp, Tcl_SavedResult *statePtr)
}
declare 315 generic {
    void Tcl_SaveResult(Tcl_Interp *interp, Tcl_SavedResult *statePtr)
}
declare 316 generic {
    int Tcl_SetSystemEncoding(Tcl_Interp *interp, CONST char *name)
}
declare 317 generic {
    Tcl_Obj * Tcl_SetVar2Ex(Tcl_Interp *interp, char *part1, char *part2, \
	    Tcl_Obj *newValuePtr, int flags)
}
declare 318 generic {
    void Tcl_ThreadAlert(Tcl_ThreadId threadId)
}
declare 319 generic {
    void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId, Tcl_Event* evPtr, \
	    Tcl_QueuePosition position)
}
declare 320 generic {
    Tcl_UniChar Tcl_UniCharAtIndex(CONST char *src, int index)
}
declare 321 generic {
    Tcl_UniChar Tcl_UniCharToLower(int ch)
}
declare 322 generic {
    Tcl_UniChar Tcl_UniCharToTitle(int ch)
}
declare 323 generic {
    Tcl_UniChar Tcl_UniCharToUpper(int ch)
}
declare 324 generic {
    int Tcl_UniCharToUtf(int ch, char *buf)
}
declare 325 generic {
    char * Tcl_UtfAtIndex(CONST char *src, int index)
}
declare 326 generic {
    int Tcl_UtfCharComplete(CONST char *src, int len)
}
declare 327 generic {
    int Tcl_UtfBackslash(CONST char *src, int *readPtr, char *dst)
}
declare 328 generic {
    char * Tcl_UtfFindFirst(CONST char *src, int ch)
}
declare 329 generic {
    char * Tcl_UtfFindLast(CONST char *src, int ch)
}
declare 330 generic {
    char * Tcl_UtfNext(CONST char *src)
}
declare 331 generic {
    char * Tcl_UtfPrev(CONST char *src, CONST char *start)
}
declare 332 generic {
    int Tcl_UtfToExternal(Tcl_Interp *interp, Tcl_Encoding encoding, \
	    CONST char *src, int srcLen, int flags, \
	    Tcl_EncodingState *statePtr, char *dst, int dstLen, \
	    int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr)
}
declare 333 generic {
    char * Tcl_UtfToExternalDString(Tcl_Encoding encoding, CONST char *src, \
	    int srcLen, Tcl_DString *dsPtr)
}
declare 334 generic {
    int Tcl_UtfToLower(char *src)
}
declare 335 generic {
    int Tcl_UtfToTitle(char *src)
}
declare 336 generic {
    int Tcl_UtfToUniChar(CONST char *src, Tcl_UniChar *chPtr)
}
declare 337 generic {
    int Tcl_UtfToUpper(char *src)
}
declare 338 generic {
    int Tcl_WriteChars(Tcl_Channel chan, CONST char *src, int srcLen)
}
declare 339 generic {
    int Tcl_WriteObj(Tcl_Channel chan, Tcl_Obj *objPtr)
}
declare 340 generic {
    char * Tcl_GetString(Tcl_Obj *objPtr)
}
declare 341 generic {
    char * Tcl_GetDefaultEncodingDir(void)
}
declare 342 generic {
    void Tcl_SetDefaultEncodingDir(char *path)
}
declare 343 generic {
    void Tcl_AlertNotifier(ClientData clientData)
}
declare 344 generic {
    void Tcl_ServiceModeHook(int mode)
}
declare 345 generic {
    int Tcl_UniCharIsAlnum(int ch)
}
declare 346 generic {
    int Tcl_UniCharIsAlpha(int ch)
}
declare 347 generic {
    int Tcl_UniCharIsDigit(int ch)
}
declare 348 generic {
    int Tcl_UniCharIsLower(int ch)
}
declare 349 generic {
    int Tcl_UniCharIsSpace(int ch)
}
declare 350 generic {
    int Tcl_UniCharIsUpper(int ch)
}
declare 351 generic {
    int Tcl_UniCharIsWordChar(int ch)
}
declare 352 generic {
    int Tcl_UniCharLen(Tcl_UniChar *str)
}
declare 353 generic {
    int Tcl_UniCharNcmp(const Tcl_UniChar *cs, const Tcl_UniChar *ct, size_t n)
}
declare 354 generic {
    char * Tcl_UniCharToUtfDString(CONST Tcl_UniChar *string, int numChars, \
 	    Tcl_DString *dsPtr)
}
declare 355 generic {
    Tcl_UniChar * Tcl_UtfToUniCharDString(CONST char *string, int length, \
	    Tcl_DString *dsPtr)
}
declare 356 generic {
    Tcl_RegExp	Tcl_GetRegExpFromObj(Tcl_Interp *interp, Tcl_Obj *patObj, int flags)
}

declare 357 generic {
    Tcl_Obj *Tcl_EvalTokens (Tcl_Interp *interp, Tcl_Token *tokenPtr, \
	    int count)
}
declare 358 generic {
    void Tcl_FreeParse (Tcl_Parse *parsePtr)
}
declare 359 generic {
    void Tcl_LogCommandInfo (Tcl_Interp *interp, char *script, \
	    char *command, int length)
}
declare 360 generic {
    int Tcl_ParseBraces (Tcl_Interp *interp, char *string, \
	    int numBytes, Tcl_Parse *parsePtr,int append, char **termPtr)
}
declare 361 generic {
    int Tcl_ParseCommand (Tcl_Interp *interp, char *string, int numBytes, \
	    int nested, Tcl_Parse *parsePtr)
}
declare 362 generic {
    int Tcl_ParseExpr(Tcl_Interp *interp, char *string, int numBytes, \
	    Tcl_Parse *parsePtr)	 
}
declare 363 generic {
    int Tcl_ParseQuotedString(Tcl_Interp *interp, char *string, int numBytes, \
	    Tcl_Parse *parsePtr, int append, char **termPtr)
}
declare 364 generic {
    int Tcl_ParseVarName (Tcl_Interp *interp, char *string, \
	    int numBytes, Tcl_Parse *parsePtr, int append)
}
declare 365 generic {
    char *Tcl_GetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr)
}
declare 366 generic {
   int Tcl_Chdir(CONST char *dirName)
}

##############################################################################

# Define the platform specific public Tcl interface.  These functions are
# only available on the designated platform.

interface tclPlat

######################
# Windows declarations

# Added in Tcl 8.1

declare 0 win {
    TCHAR * Tcl_WinUtfToTChar(CONST char *str, int len, Tcl_DString *dsPtr)
}
declare 1 win {
    char * Tcl_WinTCharToUtf(CONST TCHAR *str, int len, Tcl_DString *dsPtr)
}

##################
# Mac declarations

# This is needed by the shells to handle Macintosh events.
 
declare 0 mac {
    void Tcl_MacSetEventProc(Tcl_MacConvertEventPtr procPtr)
}

# These routines are useful for handling using scripts from resources 
# in the application shell

declare 1 mac {
    char * Tcl_MacConvertTextResource(Handle resource)
}
declare 2 mac {
    int Tcl_MacEvalResource(Tcl_Interp *interp, char *resourceName, \
	    int resourceNumber, char *fileName)
}
declare 3 mac {
    Handle Tcl_MacFindResource(Tcl_Interp *interp, long resourceType, \
	    char *resourceName, int resourceNumber, char *resFileRef, \
	    int * releaseIt)
}

# These routines support the new OSType object type (i.e. the packed 4
# character type and creator codes).

declare 4 mac {
    int Tcl_GetOSTypeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, \
	    OSType *osTypePtr)
}
declare 5 mac {
    void Tcl_SetOSTypeObj(Tcl_Obj *objPtr, OSType osType)
}
declare 6 mac {
    Tcl_Obj * Tcl_NewOSTypeObj(OSType osType)
}

# These are not in MSL 2.1.2, so we need to export them from the
# Tcl shared library.  They are found in the compat directory
# except the panic routine which is found in tclMacPanic.h.
 
declare 7 mac {
    int strncasecmp(CONST char *s1, CONST char *s2, size_t n)
}
declare 8 mac {
    int strcasecmp(CONST char *s1, CONST char *s2)
}

Changes to generic/tcl.h.

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
/*
 * tcl.h --
 *
 *	This header file describes the externally-visible facilities
 *	of the Tcl interpreter.
 *
 * Copyright (c) 1987-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1993-1996 Lucent Technologies.


 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tcl.h 1.326 97/11/20 12:40:43
 */

#ifndef _TCL
#define _TCL









/*
 * When version numbers change here, must also go into the following files
 * and update the version numbers:
 *
 * library/init.tcl
 * unix/configure.in
 * unix/pkginfo
 * win/makefile.bc
 * win/makefile.vc

 *
 * The release level should be  0 for alpha, 1 for beta, and 2 for
 * final/patch.  The release serial value is the number that follows the
 * "a", "b", or "p" in the patch level; for example, if the patch level
 * is 7.6b2, TCL_RELEASE_SERIAL is 2.  It restarts at 1 whenever the
 * release level is changed, except for the final release which is 0
 * (the first patch will start at 1).
 */

#define TCL_MAJOR_VERSION   8
#define TCL_MINOR_VERSION   0
#define TCL_RELEASE_LEVEL   2
#define TCL_RELEASE_SERIAL  2

#define TCL_VERSION	    "8.0"
#define TCL_PATCH_LEVEL	    "8.0p2"

/*
 * The following definitions set up the proper options for Windows
 * compilers.  We use this method because there is no autoconf equivalent.
 */

#ifndef __WIN32__







<

>
>




|





>
>
>
>
>
>
>
>




|

<
|
|
>
|
|
|
<
<
|
|



|
|
|

|
|







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
/*
 * tcl.h --
 *
 *	This header file describes the externally-visible facilities
 *	of the Tcl interpreter.
 *
 * Copyright (c) 1987-1994 The Regents of the University of California.

 * Copyright (c) 1993-1996 Lucent Technologies.
 * Copyright (c) 1994-1998 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: tcl.h,v 1.1.2.23 1999/04/14 00:33:19 surles Exp $
 */

#ifndef _TCL
#define _TCL

/*
 * The following defines are used to indicate the various release levels.
 */

#define TCL_ALPHA_RELEASE	0
#define TCL_BETA_RELEASE	1
#define TCL_FINAL_RELEASE	2

/*
 * When version numbers change here, must also go into the following files
 * and update the version numbers:
 *
 * library/init.tcl	(only if major.minor changes, not patchlevel)
 * unix/configure.in

 * win/makefile.bc	(only if major.minor changes, not patchlevel)
 * win/makefile.vc	(only if major.minor changes, not patchlevel)
 * win/pkgIndex.tcl	(for tclregNN.dll, not patchlevel)
 * README
 * mac/README
 * win/README.binary


 * win/README		(only if major.minor changes, not patchlevel)
 * unix/README		(only if major.minor changes, not patchlevel)
 */

#define TCL_MAJOR_VERSION   8
#define TCL_MINOR_VERSION   1
#define TCL_RELEASE_LEVEL   TCL_BETA_RELEASE
#define TCL_RELEASE_SERIAL  3

#define TCL_VERSION	    "8.1"
#define TCL_PATCH_LEVEL	    "8.1b3"

/*
 * The following definitions set up the proper options for Windows
 * compilers.  We use this method because there is no autoconf equivalent.
 */

#ifndef __WIN32__
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
#   endif
#   ifndef HAS_STDARG
#	define HAS_STDARG 1
#   endif
#   ifndef USE_PROTOTYPE
#	define USE_PROTOTYPE 1
#   endif






#   ifndef USE_TCLALLOC
#	define USE_TCLALLOC 1
#   endif
#   ifndef STRINGIFY
#	define STRINGIFY(x)	    STRINGIFY1(x)
#	define STRINGIFY1(x)	    #x
#   endif
#endif /* __WIN32__ */

/*
 * The following definitions set up the proper options for Macintosh
 * compilers.  We use this method because there is no autoconf equivalent.
 */

#ifdef MAC_TCL
#   ifndef HAS_STDARG
#	define HAS_STDARG 1
#   endif
#   ifndef USE_TCLALLOC
#	define USE_TCLALLOC 1
#   endif
#   ifndef NO_STRERROR
#	define NO_STRERROR 1
#   endif

#endif




















































/* 
 * A special definition used to allow this header file to be included 
 * in resource files so that they can get obtain version information from
 * this file.  Resource compilers don't like all the C stuff, like typedefs
 * and procedure declarations, that occur below.
 */








>
>
>
>
>
>



<
<
<
<

















>


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







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
#   endif
#   ifndef HAS_STDARG
#	define HAS_STDARG 1
#   endif
#   ifndef USE_PROTOTYPE
#	define USE_PROTOTYPE 1
#   endif

/*
 * Under Windows we need to call Tcl_Alloc in all cases to avoid competing
 * C run-time library issues.
 */

#   ifndef USE_TCLALLOC
#	define USE_TCLALLOC 1
#   endif




#endif /* __WIN32__ */

/*
 * The following definitions set up the proper options for Macintosh
 * compilers.  We use this method because there is no autoconf equivalent.
 */

#ifdef MAC_TCL
#   ifndef HAS_STDARG
#	define HAS_STDARG 1
#   endif
#   ifndef USE_TCLALLOC
#	define USE_TCLALLOC 1
#   endif
#   ifndef NO_STRERROR
#	define NO_STRERROR 1
#   endif
#   define INLINE 
#endif

/*
 * Utility macros: STRINGIFY takes an argument and wraps it in "" (double
 * quotation marks), JOIN joins two arguments.
 */

#define VERBATIM(x) x
#ifdef _MSC_VER
# define STRINGIFY(x) STRINGIFY1(x)
# define STRINGIFY1(x) #x
# define JOIN(a,b) JOIN1(a,b)
# define JOIN1(a,b) a##b
#else
# ifdef RESOURCE_INCLUDED
#  define STRINGIFY(x) STRINGIFY1(x)
#  define STRINGIFY1(x) #x
#  define JOIN(a,b) JOIN1(a,b)
#  define JOIN1(a,b) a##b
# else
#  ifdef __STDC__
#   define STRINGIFY(x) #x
#   define JOIN(a,b) a##b
#  else
#   define STRINGIFY(x) "x"
#   define JOIN(a,b) VERBATIM(a)VERBATIM(b)
#  endif
# endif
#endif

/*
 * Special macro to define mutexes, that doesn't do anything
 * if we are not using threads.
 */

#ifdef TCL_THREADS
#define TCL_DECLARE_MUTEX(name) static Tcl_Mutex name;
#else
#define TCL_DECLARE_MUTEX(name)
#endif

/*
 * Macros that eliminate the overhead of the thread synchronization
 * functions when compiling without thread support.
 */

#ifndef TCL_THREADS
#define Tcl_MutexLock(mutexPtr)
#define Tcl_MutexUnlock(mutexPtr)
#define Tcl_ConditionNotify(condPtr)
#define Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
#endif /* TCL_THREADS */

/* 
 * A special definition used to allow this header file to be included 
 * in resource files so that they can get obtain version information from
 * this file.  Resource compilers don't like all the C stuff, like typedefs
 * and procedure declarations, that occur below.
 */

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
 * the arguments in a function definiton: it takes the type and name of
 * the first argument and supplies the appropriate argument declaration
 * string for use in the function definition.  TCL_VARARGS_START
 * initializes the va_list data structure and returns the first argument.
 */

#if defined(__STDC__) || defined(HAS_STDARG)


#   define TCL_VARARGS(type, name) (type name, ...)
#   define TCL_VARARGS_DEF(type, name) (type name, ...)
#   define TCL_VARARGS_START(type, name, list) (va_start(list, name), name)
#else


#   ifdef __cplusplus
#	define TCL_VARARGS(type, name) (type name, ...)
#	define TCL_VARARGS_DEF(type, name) (type va_alist, ...)
#   else
#	define TCL_VARARGS(type, name) ()
#	define TCL_VARARGS_DEF(type, name) (va_alist)
#   endif
#   define TCL_VARARGS_START(type, name, list) \
	(va_start(list), va_arg(list, type))
#endif

















































/*
 * Definitions that allow this header file to be used either with or
 * without ANSI C features like function prototypes.
 */

#undef _ANSI_ARGS_
#undef CONST




#if ((defined(__STDC__) || defined(SABER)) && !defined(NO_PROTOTYPE)) || defined(__cplusplus) || defined(USE_PROTOTYPE)
#   define _USING_PROTOTYPES_ 1
#   define _ANSI_ARGS_(x)	x
#   define CONST const
#else
#   define _ANSI_ARGS_(x)	()
#   define CONST
#endif

#ifdef __cplusplus
#   define EXTERN extern "C"
#else
#   define EXTERN extern
#endif

/*
 * Macro to use instead of "void" for arguments that must have
 * type "void *" in ANSI C;  maps them to type "char *" in
 * non-ANSI systems.
 */







>
>




>
>











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







>
>
>











|

|







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
 * the arguments in a function definiton: it takes the type and name of
 * the first argument and supplies the appropriate argument declaration
 * string for use in the function definition.  TCL_VARARGS_START
 * initializes the va_list data structure and returns the first argument.
 */

#if defined(__STDC__) || defined(HAS_STDARG)
#   include <stdarg.h>

#   define TCL_VARARGS(type, name) (type name, ...)
#   define TCL_VARARGS_DEF(type, name) (type name, ...)
#   define TCL_VARARGS_START(type, name, list) (va_start(list, name), name)
#else
#   include <varargs.h>

#   ifdef __cplusplus
#	define TCL_VARARGS(type, name) (type name, ...)
#	define TCL_VARARGS_DEF(type, name) (type va_alist, ...)
#   else
#	define TCL_VARARGS(type, name) ()
#	define TCL_VARARGS_DEF(type, name) (va_alist)
#   endif
#   define TCL_VARARGS_START(type, name, list) \
	(va_start(list), va_arg(list, type))
#endif

/*
 * Macros used to declare a function to be exported by a DLL.
 * Used by Windows, maps to no-op declarations on non-Windows systems.
 * The default build on windows is for a DLL, which causes the DLLIMPORT
 * and DLLEXPORT macros to be nonempty. To build a static library, the
 * macro STATIC_BUILD should be defined.
 */

#ifdef STATIC_BUILD
# define DLLIMPORT
# define DLLEXPORT
#else
# if defined(__WIN32__) && (defined(_MSC_VER) || (defined(__GNUC__) && defined(__declspec)))
#   define DLLIMPORT __declspec(dllimport)
#   define DLLEXPORT __declspec(dllexport)
# else
#  define DLLIMPORT
#  define DLLEXPORT
# endif
#endif

/*
 * These macros are used to control whether functions are being declared for
 * import or export.  If a function is being declared while it is being built
 * to be included in a shared library, then it should have the DLLEXPORT
 * storage class.  If is being declared for use by a module that is going to
 * link against the shared library, then it should have the DLLIMPORT storage
 * class.  If the symbol is beind declared for a static build or for use from a
 * stub library, then the storage class should be empty.
 *
 * The convention is that a macro called BUILD_xxxx, where xxxx is the
 * name of a library we are building, is set on the compile line for sources
 * that are to be placed in the library.  When this macro is set, the
 * storage class will be set to DLLEXPORT.  At the end of the header file, the
 * storage class will be reset to DLLIMPORt.
 */

#undef TCL_STORAGE_CLASS
#ifdef BUILD_tcl
# define TCL_STORAGE_CLASS DLLEXPORT
#else
# ifdef USE_TCL_STUBS
#  define TCL_STORAGE_CLASS
# else
#  define TCL_STORAGE_CLASS DLLIMPORT
# endif
#endif

/*
 * Definitions that allow this header file to be used either with or
 * without ANSI C features like function prototypes.
 */

#undef _ANSI_ARGS_
#undef CONST
#ifndef INLINE
#   define INLINE
#endif

#if ((defined(__STDC__) || defined(SABER)) && !defined(NO_PROTOTYPE)) || defined(__cplusplus) || defined(USE_PROTOTYPE)
#   define _USING_PROTOTYPES_ 1
#   define _ANSI_ARGS_(x)	x
#   define CONST const
#else
#   define _ANSI_ARGS_(x)	()
#   define CONST
#endif

#ifdef __cplusplus
#   define EXTERN extern "C" TCL_STORAGE_CLASS
#else
#   define EXTERN extern TCL_STORAGE_CLASS
#endif

/*
 * Macro to use instead of "void" for arguments that must have
 * type "void *" in ANSI C;  maps them to type "char *" in
 * non-ANSI systems.
 */
231
232
233
234
235
236
237



238

239
240


241
242
243
244
245
246
247
                                 * the line number within the command where
                                 * the error occurred (1 if first line). */
} Tcl_Interp;

typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler;
typedef struct Tcl_Channel_ *Tcl_Channel;
typedef struct Tcl_Command_ *Tcl_Command;



typedef struct Tcl_Event Tcl_Event;

typedef struct Tcl_Pid_ *Tcl_Pid;
typedef struct Tcl_RegExp_ *Tcl_RegExp;


typedef struct Tcl_TimerToken_ *Tcl_TimerToken;
typedef struct Tcl_Trace_ *Tcl_Trace;
typedef struct Tcl_Var_ *Tcl_Var;

/*
 * When a TCL command returns, the interpreter contains a result from the
 * command. Programmers are strongly encouraged to use one of the







>
>
>

>


>
>







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
                                 * the line number within the command where
                                 * the error occurred (1 if first line). */
} Tcl_Interp;

typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler;
typedef struct Tcl_Channel_ *Tcl_Channel;
typedef struct Tcl_Command_ *Tcl_Command;
typedef struct Tcl_Condition_ *Tcl_Condition;
typedef struct Tcl_EncodingState_ *Tcl_EncodingState;
typedef struct Tcl_Encoding_ *Tcl_Encoding;
typedef struct Tcl_Event Tcl_Event;
typedef struct Tcl_Mutex_ *Tcl_Mutex;
typedef struct Tcl_Pid_ *Tcl_Pid;
typedef struct Tcl_RegExp_ *Tcl_RegExp;
typedef struct Tcl_ThreadDataKey_ *Tcl_ThreadDataKey;
typedef struct Tcl_ThreadId_ *Tcl_ThreadId;
typedef struct Tcl_TimerToken_ *Tcl_TimerToken;
typedef struct Tcl_Trace_ *Tcl_Trace;
typedef struct Tcl_Var_ *Tcl_Var;

/*
 * When a TCL command returns, the interpreter contains a result from the
 * command. Programmers are strongly encouraged to use one of the
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
typedef int (Tcl_CmdProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int argc, char *argv[]));
typedef void (Tcl_CmdTraceProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int level, char *command, Tcl_CmdProc *proc,
	ClientData cmdClientData, int argc, char *argv[]));
typedef void (Tcl_DupInternalRepProc) _ANSI_ARGS_((struct Tcl_Obj *srcPtr, 
        struct Tcl_Obj *dupPtr));





typedef int (Tcl_EventProc) _ANSI_ARGS_((Tcl_Event *evPtr, int flags));
typedef void (Tcl_EventCheckProc) _ANSI_ARGS_((ClientData clientData,
	int flags));
typedef int (Tcl_EventDeleteProc) _ANSI_ARGS_((Tcl_Event *evPtr,
        ClientData clientData));
typedef void (Tcl_EventSetupProc) _ANSI_ARGS_((ClientData clientData,
	int flags));
typedef void (Tcl_ExitProc) _ANSI_ARGS_((ClientData clientData));
typedef void (Tcl_FileProc) _ANSI_ARGS_((ClientData clientData, int mask));
typedef void (Tcl_FileFreeProc) _ANSI_ARGS_((ClientData clientData));
typedef void (Tcl_FreeInternalRepProc) _ANSI_ARGS_((struct Tcl_Obj *objPtr));
typedef void (Tcl_FreeProc) _ANSI_ARGS_((char *blockPtr));
typedef void (Tcl_IdleProc) _ANSI_ARGS_((ClientData clientData));
typedef void (Tcl_InterpDeleteProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp));
typedef int (Tcl_MathProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, Tcl_Value *args, Tcl_Value *resultPtr));
typedef void (Tcl_NamespaceDeleteProc) _ANSI_ARGS_((ClientData clientData));
typedef int (Tcl_ObjCmdProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int objc, struct Tcl_Obj * CONST objv[]));
typedef int (Tcl_PackageInitProc) _ANSI_ARGS_((Tcl_Interp *interp));

typedef void (Tcl_TcpAcceptProc) _ANSI_ARGS_((ClientData callbackData,
        Tcl_Channel chan, char *address, int port));
typedef void (Tcl_TimerProc) _ANSI_ARGS_((ClientData clientData));
typedef int (Tcl_SetFromAnyProc) _ANSI_ARGS_((Tcl_Interp *interp,
	struct Tcl_Obj *objPtr));
typedef void (Tcl_UpdateStringProc) _ANSI_ARGS_((struct Tcl_Obj *objPtr));
typedef char *(Tcl_VarTraceProc) _ANSI_ARGS_((ClientData clientData,







>
>
>
>
>



















|

>







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
typedef int (Tcl_CmdProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int argc, char *argv[]));
typedef void (Tcl_CmdTraceProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int level, char *command, Tcl_CmdProc *proc,
	ClientData cmdClientData, int argc, char *argv[]));
typedef void (Tcl_DupInternalRepProc) _ANSI_ARGS_((struct Tcl_Obj *srcPtr, 
        struct Tcl_Obj *dupPtr));
typedef int (Tcl_EncodingConvertProc)_ANSI_ARGS_((ClientData clientData,
	CONST char *src, int srcLen, int flags, Tcl_EncodingState *statePtr,
	char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr,
	int *dstCharsPtr));
typedef void (Tcl_EncodingFreeProc)_ANSI_ARGS_((ClientData clientData));
typedef int (Tcl_EventProc) _ANSI_ARGS_((Tcl_Event *evPtr, int flags));
typedef void (Tcl_EventCheckProc) _ANSI_ARGS_((ClientData clientData,
	int flags));
typedef int (Tcl_EventDeleteProc) _ANSI_ARGS_((Tcl_Event *evPtr,
        ClientData clientData));
typedef void (Tcl_EventSetupProc) _ANSI_ARGS_((ClientData clientData,
	int flags));
typedef void (Tcl_ExitProc) _ANSI_ARGS_((ClientData clientData));
typedef void (Tcl_FileProc) _ANSI_ARGS_((ClientData clientData, int mask));
typedef void (Tcl_FileFreeProc) _ANSI_ARGS_((ClientData clientData));
typedef void (Tcl_FreeInternalRepProc) _ANSI_ARGS_((struct Tcl_Obj *objPtr));
typedef void (Tcl_FreeProc) _ANSI_ARGS_((char *blockPtr));
typedef void (Tcl_IdleProc) _ANSI_ARGS_((ClientData clientData));
typedef void (Tcl_InterpDeleteProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp));
typedef int (Tcl_MathProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, Tcl_Value *args, Tcl_Value *resultPtr));
typedef void (Tcl_NamespaceDeleteProc) _ANSI_ARGS_((ClientData clientData));
typedef int (Tcl_ObjCmdProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int objc, struct Tcl_Obj *CONST objv[]));
typedef int (Tcl_PackageInitProc) _ANSI_ARGS_((Tcl_Interp *interp));
typedef void (Tcl_PanicProc) _ANSI_ARGS_(TCL_VARARGS(char *, format));
typedef void (Tcl_TcpAcceptProc) _ANSI_ARGS_((ClientData callbackData,
        Tcl_Channel chan, char *address, int port));
typedef void (Tcl_TimerProc) _ANSI_ARGS_((ClientData clientData));
typedef int (Tcl_SetFromAnyProc) _ANSI_ARGS_((Tcl_Interp *interp,
	struct Tcl_Obj *objPtr));
typedef void (Tcl_UpdateStringProc) _ANSI_ARGS_((struct Tcl_Obj *objPtr));
typedef char *(Tcl_VarTraceProc) _ANSI_ARGS_((ClientData clientData,
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
				 * must be followed by a null byte (i.e., at
				 * offset length) but may also contain
				 * embedded null characters. The array's
				 * storage is allocated by ckalloc. NULL
				 * means the string rep is invalid and must
				 * be regenerated from the internal rep.
				 * Clients should use Tcl_GetStringFromObj
				 * to get a pointer to the byte array as a
				 * readonly value. */
    int length;			/* The number of bytes at *bytes, not
				 * including the terminating null. */
    Tcl_ObjType *typePtr;	/* Denotes the object's type. Always
				 * corresponds to the type of the object's
				 * internal rep. NULL indicates the object
				 * has no internal rep (has no type). */
    union {			/* The internal representation: */







|
|







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
				 * must be followed by a null byte (i.e., at
				 * offset length) but may also contain
				 * embedded null characters. The array's
				 * storage is allocated by ckalloc. NULL
				 * means the string rep is invalid and must
				 * be regenerated from the internal rep.
				 * Clients should use Tcl_GetStringFromObj
				 * or Tcl_GetString to get a pointer to the
				 * byte array as a readonly value. */
    int length;			/* The number of bytes at *bytes, not
				 * including the terminating null. */
    Tcl_ObjType *typePtr;	/* Denotes the object's type. Always
				 * corresponds to the type of the object's
				 * internal rep. NULL indicates the object
				 * has no internal rep (has no type). */
    union {			/* The internal representation: */
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
	if (--(objPtr)->refCount <= 0) TclFreeObj(objPtr)
#   define Tcl_IsShared(objPtr) \
	((objPtr)->refCount > 1)
#endif

/*
 * Macros and definitions that help to debug the use of Tcl objects.
 * When TCL_MEM_DEBUG is defined, the Tcl_New* declarations are 
 * overridden to call debugging versions of the object creation procedures.
 */

EXTERN Tcl_Obj *	Tcl_NewBooleanObj _ANSI_ARGS_((int boolValue));
EXTERN Tcl_Obj *	Tcl_NewDoubleObj _ANSI_ARGS_((double doubleValue));
EXTERN Tcl_Obj *	Tcl_NewIntObj _ANSI_ARGS_((int intValue));
EXTERN Tcl_Obj *	Tcl_NewListObj _ANSI_ARGS_((int objc,
			    Tcl_Obj *CONST objv[]));
EXTERN Tcl_Obj *	Tcl_NewLongObj _ANSI_ARGS_((long longValue));
EXTERN Tcl_Obj *	Tcl_NewObj _ANSI_ARGS_((void));
EXTERN Tcl_Obj *	Tcl_NewStringObj _ANSI_ARGS_((char *bytes,
			    int length));

#ifdef TCL_MEM_DEBUG
#  define Tcl_NewBooleanObj(val) \
     Tcl_DbNewBooleanObj(val, __FILE__, __LINE__)


#  define Tcl_NewDoubleObj(val) \
     Tcl_DbNewDoubleObj(val, __FILE__, __LINE__)
#  define Tcl_NewIntObj(val) \
     Tcl_DbNewLongObj(val, __FILE__, __LINE__)
#  define Tcl_NewListObj(objc, objv) \
     Tcl_DbNewListObj(objc, objv, __FILE__, __LINE__)
#  define Tcl_NewLongObj(val) \
     Tcl_DbNewLongObj(val, __FILE__, __LINE__)
#  define Tcl_NewObj() \
     Tcl_DbNewObj(__FILE__, __LINE__)
#  define Tcl_NewStringObj(bytes, len) \
     Tcl_DbNewStringObj(bytes, len, __FILE__, __LINE__)
#endif /* TCL_MEM_DEBUG */


















/*
 * The following definitions support Tcl's namespace facility.
 * Note: the first five fields must match exactly the fields in a
 * Namespace structure (see tcl.h). 
 */








|



<
<
<
<
<
<
<
<
<
<



>
>













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







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
	if (--(objPtr)->refCount <= 0) TclFreeObj(objPtr)
#   define Tcl_IsShared(objPtr) \
	((objPtr)->refCount > 1)
#endif

/*
 * Macros and definitions that help to debug the use of Tcl objects.
 * When TCL_MEM_DEBUG is defined, the Tcl_New declarations are 
 * overridden to call debugging versions of the object creation procedures.
 */











#ifdef TCL_MEM_DEBUG
#  define Tcl_NewBooleanObj(val) \
     Tcl_DbNewBooleanObj(val, __FILE__, __LINE__)
#  define Tcl_NewByteArrayObj(bytes, len) \
     Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__)
#  define Tcl_NewDoubleObj(val) \
     Tcl_DbNewDoubleObj(val, __FILE__, __LINE__)
#  define Tcl_NewIntObj(val) \
     Tcl_DbNewLongObj(val, __FILE__, __LINE__)
#  define Tcl_NewListObj(objc, objv) \
     Tcl_DbNewListObj(objc, objv, __FILE__, __LINE__)
#  define Tcl_NewLongObj(val) \
     Tcl_DbNewLongObj(val, __FILE__, __LINE__)
#  define Tcl_NewObj() \
     Tcl_DbNewObj(__FILE__, __LINE__)
#  define Tcl_NewStringObj(bytes, len) \
     Tcl_DbNewStringObj(bytes, len, __FILE__, __LINE__)
#endif /* TCL_MEM_DEBUG */

/*
 * The following structure contains the state needed by
 * Tcl_SaveResult.  No-one outside of Tcl should access any of these
 * fields.  This structure is typically allocated on the stack.
 */

typedef struct Tcl_SavedResult {
    char *result;
    Tcl_FreeProc *freeProc;
    Tcl_Obj *objResultPtr;
    char *appendResult;
    int appendAvl;
    int appendUsed;
    char resultSpace[TCL_RESULT_SIZE+1];
} Tcl_SavedResult;


/*
 * The following definitions support Tcl's namespace facility.
 * Note: the first five fields must match exactly the fields in a
 * Namespace structure (see tcl.h). 
 */

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
#define Tcl_DStringLength(dsPtr) ((dsPtr)->length)
#define Tcl_DStringValue(dsPtr) ((dsPtr)->string)
#define Tcl_DStringTrunc Tcl_DStringSetLength

/*
 * Definitions for the maximum number of digits of precision that may
 * be specified in the "tcl_precision" variable, and the number of
 * characters of buffer space required by Tcl_PrintDouble.
 */
 
#define TCL_MAX_PREC 17
#define TCL_DOUBLE_SPACE (TCL_MAX_PREC+10)









/*
 * Flag that may be passed to Tcl_ConvertElement to force it not to
 * output braces (careful!  if you change this flag be sure to change
 * the definitions at the front of tclUtil.c).
 */

#define TCL_DONT_USE_BRACES	1

/*
 * Flag that may be passed to Tcl_GetIndexFromObj to force it to disallow
 * abbreviated strings.
 */

#define TCL_EXACT	1

/*
 * Flag values passed to Tcl_RecordAndEval.
 * WARNING: these bit choices must not conflict with the bit choices
 * for evalFlag bits in tclInt.h!!
 */

#define TCL_NO_EVAL		0x10000
#define TCL_EVAL_GLOBAL		0x20000


/*
 * Special freeProc values that may be passed to Tcl_SetResult (see
 * the man page for details):
 */

#define TCL_VOLATILE	((Tcl_FreeProc *) 1)







|





>
>
>
>
>
>
>
>
















|






>







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
#define Tcl_DStringLength(dsPtr) ((dsPtr)->length)
#define Tcl_DStringValue(dsPtr) ((dsPtr)->string)
#define Tcl_DStringTrunc Tcl_DStringSetLength

/*
 * Definitions for the maximum number of digits of precision that may
 * be specified in the "tcl_precision" variable, and the number of
 * bytes of buffer space required by Tcl_PrintDouble.
 */
 
#define TCL_MAX_PREC 17
#define TCL_DOUBLE_SPACE (TCL_MAX_PREC+10)

/*
 * Definition for a number of bytes of buffer space sufficient to hold the
 * string representation of an integer in base 10 (assuming the existence
 * of 64-bit integers).
 */

#define TCL_INTEGER_SPACE	24

/*
 * Flag that may be passed to Tcl_ConvertElement to force it not to
 * output braces (careful!  if you change this flag be sure to change
 * the definitions at the front of tclUtil.c).
 */

#define TCL_DONT_USE_BRACES	1

/*
 * Flag that may be passed to Tcl_GetIndexFromObj to force it to disallow
 * abbreviated strings.
 */

#define TCL_EXACT	1

/*
 * Flag values passed to Tcl_RecordAndEval and/or Tcl_EvalObj.
 * WARNING: these bit choices must not conflict with the bit choices
 * for evalFlag bits in tclInt.h!!
 */

#define TCL_NO_EVAL		0x10000
#define TCL_EVAL_GLOBAL		0x20000
#define TCL_EVAL_DIRECT		0x40000

/*
 * Special freeProc values that may be passed to Tcl_SetResult (see
 * the man page for details):
 */

#define TCL_VOLATILE	((Tcl_FreeProc *) 1)
634
635
636
637
638
639
640










641


642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
#define TCL_LIST_ELEMENT	 8
#define TCL_TRACE_READS		 0x10
#define TCL_TRACE_WRITES	 0x20
#define TCL_TRACE_UNSETS	 0x40
#define TCL_TRACE_DESTROYED	 0x80
#define TCL_INTERP_DESTROYED	 0x100
#define TCL_LEAVE_ERR_MSG	 0x200










#define TCL_PARSE_PART1		 0x400



/*
 * Types for linked variables:
 */

#define TCL_LINK_INT		1
#define TCL_LINK_DOUBLE		2
#define TCL_LINK_BOOLEAN	3
#define TCL_LINK_STRING		4
#define TCL_LINK_READ_ONLY	0x80

/*
 * The following declarations either map ckalloc and ckfree to
 * malloc and free, or they map them to procedures with all sorts
 * of debugging hooks defined in tclCkalloc.c.
 */

EXTERN char *		Tcl_Alloc _ANSI_ARGS_((unsigned int size));
EXTERN void		Tcl_Free _ANSI_ARGS_((char *ptr));
EXTERN char *		Tcl_Realloc _ANSI_ARGS_((char *ptr,
			    unsigned int size));

#ifdef TCL_MEM_DEBUG

#  define Tcl_Alloc(x) Tcl_DbCkalloc(x, __FILE__, __LINE__)
#  define Tcl_Free(x)  Tcl_DbCkfree(x, __FILE__, __LINE__)
#  define Tcl_Realloc(x,y) Tcl_DbCkrealloc((x), (y),__FILE__, __LINE__)
#  define ckalloc(x) Tcl_DbCkalloc(x, __FILE__, __LINE__)
#  define ckfree(x)  Tcl_DbCkfree(x, __FILE__, __LINE__)
#  define ckrealloc(x,y) Tcl_DbCkrealloc((x), (y),__FILE__, __LINE__)

EXTERN int		Tcl_DumpActiveMemory _ANSI_ARGS_((char *fileName));
EXTERN void		Tcl_ValidateAllMemory _ANSI_ARGS_((char *file,
			    int line));

#else

#  if USE_TCLALLOC
#     define ckalloc(x) Tcl_Alloc(x)
#     define ckfree(x) Tcl_Free(x)
#     define ckrealloc(x,y) Tcl_Realloc(x,y)
#  else
#     define ckalloc(x) malloc(x)
#     define ckfree(x)  free(x)
#     define ckrealloc(x,y) realloc(x,y)
#  endif
#  define Tcl_DumpActiveMemory(x)
#  define Tcl_ValidateAllMemory(x,y)

#endif /* TCL_MEM_DEBUG */

/*
 * Forward declaration of Tcl_HashTable.  Needed by some C++ compilers
 * to prevent errors when the forward reference to Tcl_HashTable is
 * encountered in the Tcl_HashEntry structure.
 */

#ifdef __cplusplus







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











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







780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810








































811
812
813
814
815
816
817
#define TCL_LIST_ELEMENT	 8
#define TCL_TRACE_READS		 0x10
#define TCL_TRACE_WRITES	 0x20
#define TCL_TRACE_UNSETS	 0x40
#define TCL_TRACE_DESTROYED	 0x80
#define TCL_INTERP_DESTROYED	 0x100
#define TCL_LEAVE_ERR_MSG	 0x200
#define TCL_TRACE_ARRAY		 0x800

/*
 * The TCL_PARSE_PART1 flag is deprecated and has no effect. 
 * The part1 is now always parsed whenever the part2 is NULL.
 * (This is to avoid a common error when converting code to
 *  use the new object based APIs and forgetting to give the
 *  flag)
 */
#ifndef TCL_NO_DEPRECATED
#define TCL_PARSE_PART1          0x400
#endif


/*
 * Types for linked variables:
 */

#define TCL_LINK_INT		1
#define TCL_LINK_DOUBLE		2
#define TCL_LINK_BOOLEAN	3
#define TCL_LINK_STRING		4
#define TCL_LINK_READ_ONLY	0x80









































/*
 * Forward declaration of Tcl_HashTable.  Needed by some C++ compilers
 * to prevent errors when the forward reference to Tcl_HashTable is
 * encountered in the Tcl_HashEntry structure.
 */

#ifdef __cplusplus
876
877
878
879
880
881
882















883
884
885
886
887
888
889
890


891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908





































909
910
911
912
913
914
915
 */

#define TCL_STDIN		(1<<1)	
#define TCL_STDOUT		(1<<2)
#define TCL_STDERR		(1<<3)
#define TCL_ENFORCE_MODE	(1<<4)
















/*
 * Typedefs for the various operations in a channel type:
 */

typedef int	(Tcl_DriverBlockModeProc) _ANSI_ARGS_((
		    ClientData instanceData, int mode));
typedef int	(Tcl_DriverCloseProc) _ANSI_ARGS_((ClientData instanceData,
		    Tcl_Interp *interp));


typedef int	(Tcl_DriverInputProc) _ANSI_ARGS_((ClientData instanceData,
		    char *buf, int toRead, int *errorCodePtr));
typedef int	(Tcl_DriverOutputProc) _ANSI_ARGS_((ClientData instanceData,
		    char *buf, int toWrite, int *errorCodePtr));
typedef int	(Tcl_DriverSeekProc) _ANSI_ARGS_((ClientData instanceData,
		    long offset, int mode, int *errorCodePtr));
typedef int	(Tcl_DriverSetOptionProc) _ANSI_ARGS_((
		    ClientData instanceData, Tcl_Interp *interp,
	            char *optionName, char *value));
typedef int	(Tcl_DriverGetOptionProc) _ANSI_ARGS_((
		    ClientData instanceData, Tcl_Interp *interp,
		    char *optionName, Tcl_DString *dsPtr));
typedef void	(Tcl_DriverWatchProc) _ANSI_ARGS_((
		    ClientData instanceData, int mask));
typedef int	(Tcl_DriverGetHandleProc) _ANSI_ARGS_((
		    ClientData instanceData, int direction,
		    ClientData *handlePtr));






































/*
 * Enum for different end of line translation and recognition modes.
 */

typedef enum Tcl_EolTranslation {
    TCL_TRANSLATE_AUTO,			/* Eol == \r, \n and \r\n. */
    TCL_TRANSLATE_CR,			/* Eol == \r. */







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








>
>


















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







994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
 */

#define TCL_STDIN		(1<<1)	
#define TCL_STDOUT		(1<<2)
#define TCL_STDERR		(1<<3)
#define TCL_ENFORCE_MODE	(1<<4)

/*
 * Bits passed to Tcl_DriverClose2Proc to indicate which side of a channel
 * should be closed.
 */

#define TCL_CLOSE_READ		(1<<1)
#define TCL_CLOSE_WRITE	(1<<2)

/*
 * Value to use as the closeProc for a channel that supports the
 * close2Proc interface.
 */

#define TCL_CLOSE2PROC	((Tcl_DriverCloseProc *)1)

/*
 * Typedefs for the various operations in a channel type:
 */

typedef int	(Tcl_DriverBlockModeProc) _ANSI_ARGS_((
		    ClientData instanceData, int mode));
typedef int	(Tcl_DriverCloseProc) _ANSI_ARGS_((ClientData instanceData,
		    Tcl_Interp *interp));
typedef int	(Tcl_DriverClose2Proc) _ANSI_ARGS_((ClientData instanceData,
		    Tcl_Interp *interp, int flags));
typedef int	(Tcl_DriverInputProc) _ANSI_ARGS_((ClientData instanceData,
		    char *buf, int toRead, int *errorCodePtr));
typedef int	(Tcl_DriverOutputProc) _ANSI_ARGS_((ClientData instanceData,
		    char *buf, int toWrite, int *errorCodePtr));
typedef int	(Tcl_DriverSeekProc) _ANSI_ARGS_((ClientData instanceData,
		    long offset, int mode, int *errorCodePtr));
typedef int	(Tcl_DriverSetOptionProc) _ANSI_ARGS_((
		    ClientData instanceData, Tcl_Interp *interp,
	            char *optionName, char *value));
typedef int	(Tcl_DriverGetOptionProc) _ANSI_ARGS_((
		    ClientData instanceData, Tcl_Interp *interp,
		    char *optionName, Tcl_DString *dsPtr));
typedef void	(Tcl_DriverWatchProc) _ANSI_ARGS_((
		    ClientData instanceData, int mask));
typedef int	(Tcl_DriverGetHandleProc) _ANSI_ARGS_((
		    ClientData instanceData, int direction,
		    ClientData *handlePtr));

/*
 * The following declarations either map ckalloc and ckfree to
 * malloc and free, or they map them to procedures with all sorts
 * of debugging hooks defined in tclCkalloc.c.
 */

#ifdef TCL_MEM_DEBUG

#   define ckalloc(x) Tcl_DbCkalloc(x, __FILE__, __LINE__)
#   define ckfree(x)  Tcl_DbCkfree(x, __FILE__, __LINE__)
#   define ckrealloc(x,y) Tcl_DbCkrealloc((x), (y),__FILE__, __LINE__)

#else /* !TCL_MEM_DEBUG */

/*
 * If USE_TCLALLOC is true, then we need to call Tcl_Alloc instead of
 * the native malloc/free.  The only time USE_TCLALLOC should not be
 * true is when compiling the Tcl/Tk libraries on Unix systems.  In this
 * case we can safely call the native malloc/free directly as a performance
 * optimization.
 */

#   if USE_TCLALLOC
#	define ckalloc(x) Tcl_Alloc(x)
#	define ckfree(x) Tcl_Free(x)
#	define ckrealloc(x,y) Tcl_Realloc(x,y)
#   else
#	define ckalloc(x) malloc(x)
#	define ckfree(x)  free(x)
#	define ckrealloc(x,y) realloc(x,y)
#   endif
#   define Tcl_InitMemory(x)
#   define Tcl_DumpActiveMemory(x)
#   define Tcl_ValidateAllMemory(x,y)

#endif /* !TCL_MEM_DEBUG */

/*
 * Enum for different end of line translation and recognition modes.
 */

typedef enum Tcl_EolTranslation {
    TCL_TRANSLATE_AUTO,			/* Eol == \r, \n and \r\n. */
    TCL_TRANSLATE_CR,			/* Eol == \r. */
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
typedef struct Tcl_ChannelType {
    char *typeName;			/* The name of the channel type in Tcl
                                         * commands. This storage is owned by
                                         * channel type. */
    Tcl_DriverBlockModeProc *blockModeProc;
    					/* Set blocking mode for the
                                         * raw channel. May be NULL. */
    Tcl_DriverCloseProc *closeProc;	/* Procedure to call to close
                                         * the channel. */


    Tcl_DriverInputProc *inputProc;	/* Procedure to call for input
                                         * on channel. */
    Tcl_DriverOutputProc *outputProc;	/* Procedure to call for output
                                         * on channel. */
    Tcl_DriverSeekProc *seekProc;	/* Procedure to call to seek
                                         * on the channel. May be NULL. */
    Tcl_DriverSetOptionProc *setOptionProc;
    					/* Set an option on a channel. */
    Tcl_DriverGetOptionProc *getOptionProc;
    					/* Get an option from a channel. */
    Tcl_DriverWatchProc *watchProc;	/* Set up the notifier to watch
                                         * for events on this channel. */
    Tcl_DriverGetHandleProc *getHandleProc;
					/* Get an OS handle from the channel
                                         * or NULL if not supported. */




} Tcl_ChannelType;

/*
 * The following flags determine whether the blockModeProc above should
 * set the channel into blocking or nonblocking mode. They are passed
 * as arguments to the blockModeProc procedure in the above structure.
 */







|
|
>
>















>
>
>
>







1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
typedef struct Tcl_ChannelType {
    char *typeName;			/* The name of the channel type in Tcl
                                         * commands. This storage is owned by
                                         * channel type. */
    Tcl_DriverBlockModeProc *blockModeProc;
    					/* Set blocking mode for the
                                         * raw channel. May be NULL. */
    Tcl_DriverCloseProc *closeProc;	/* Procedure to call to close the
                                         * channel, or TCL_CLOSE2PROC if the
                                         * close2Proc should be used
                                         * instead. */
    Tcl_DriverInputProc *inputProc;	/* Procedure to call for input
                                         * on channel. */
    Tcl_DriverOutputProc *outputProc;	/* Procedure to call for output
                                         * on channel. */
    Tcl_DriverSeekProc *seekProc;	/* Procedure to call to seek
                                         * on the channel. May be NULL. */
    Tcl_DriverSetOptionProc *setOptionProc;
    					/* Set an option on a channel. */
    Tcl_DriverGetOptionProc *getOptionProc;
    					/* Get an option from a channel. */
    Tcl_DriverWatchProc *watchProc;	/* Set up the notifier to watch
                                         * for events on this channel. */
    Tcl_DriverGetHandleProc *getHandleProc;
					/* Get an OS handle from the channel
                                         * or NULL if not supported. */
    Tcl_DriverClose2Proc *close2Proc;   /* Procedure to call to close the
					 * channel if the device supports
					 * closing the read & write sides
					 * independently. */
} Tcl_ChannelType;

/*
 * The following flags determine whether the blockModeProc above should
 * set the channel into blocking or nonblocking mode. They are passed
 * as arguments to the blockModeProc procedure in the above structure.
 */
968
969
970
971
972
973
974


























































































































































































































































































975











976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440


1441
1442
1443

1444
1445
1446
1447
1448
1449

1450

1451



1452

1453
1454
1455
1456
1457

1458



1459
1460
1461
1462
1463
1464

1465
1466
1467

1468
1469
1470
1471
1472
1473



1474
1475
1476
1477
1478





1479
1480

1481
1482
1483
1484
1485
1486
1487




1488
typedef enum Tcl_PathType {
    TCL_PATH_ABSOLUTE,
    TCL_PATH_RELATIVE,
    TCL_PATH_VOLUME_RELATIVE
} Tcl_PathType;

/*


























































































































































































































































































 * Exported Tcl procedures:











 */

EXTERN void		Tcl_AddErrorInfo _ANSI_ARGS_((Tcl_Interp *interp,
			    char *message));
EXTERN void		Tcl_AddObjErrorInfo _ANSI_ARGS_((Tcl_Interp *interp,
			    char *message, int length));
EXTERN void		Tcl_AllowExceptions _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		Tcl_AppendAllObjTypes _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Obj *objPtr));
EXTERN void		Tcl_AppendElement _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string));
EXTERN void		Tcl_AppendResult _ANSI_ARGS_(
			    TCL_VARARGS(Tcl_Interp *,interp));
EXTERN void		Tcl_AppendToObj _ANSI_ARGS_((Tcl_Obj *objPtr,
			    char *bytes, int length));
EXTERN void		Tcl_AppendStringsToObj _ANSI_ARGS_(
			    TCL_VARARGS(Tcl_Obj *,interp));
EXTERN int		Tcl_AppInit _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN Tcl_AsyncHandler	Tcl_AsyncCreate _ANSI_ARGS_((Tcl_AsyncProc *proc,
			    ClientData clientData));
EXTERN void		Tcl_AsyncDelete _ANSI_ARGS_((Tcl_AsyncHandler async));
EXTERN int		Tcl_AsyncInvoke _ANSI_ARGS_((Tcl_Interp *interp,
			    int code));
EXTERN void		Tcl_AsyncMark _ANSI_ARGS_((Tcl_AsyncHandler async));
EXTERN int		Tcl_AsyncReady _ANSI_ARGS_((void));
EXTERN void		Tcl_BackgroundError _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN char		Tcl_Backslash _ANSI_ARGS_((CONST char *src,
			    int *readPtr));
EXTERN int		Tcl_BadChannelOption _ANSI_ARGS_((Tcl_Interp *interp,
			    char *optionName, char *optionList));
EXTERN void		Tcl_CallWhenDeleted _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_InterpDeleteProc *proc,
			    ClientData clientData));
EXTERN void		Tcl_CancelIdleCall _ANSI_ARGS_((Tcl_IdleProc *idleProc,
			    ClientData clientData));
#define Tcl_Ckalloc Tcl_Alloc
#define Tcl_Ckfree Tcl_Free
#define Tcl_Ckrealloc Tcl_Realloc
EXTERN int		Tcl_Close _ANSI_ARGS_((Tcl_Interp *interp,
        		    Tcl_Channel chan));
EXTERN int		Tcl_CommandComplete _ANSI_ARGS_((char *cmd));
EXTERN char *		Tcl_Concat _ANSI_ARGS_((int argc, char **argv));
EXTERN Tcl_Obj *	Tcl_ConcatObj _ANSI_ARGS_((int objc,
			    Tcl_Obj *CONST objv[]));
EXTERN int		Tcl_ConvertCountedElement _ANSI_ARGS_((CONST char *src,
			    int length, char *dst, int flags));
EXTERN int		Tcl_ConvertElement _ANSI_ARGS_((CONST char *src,
			    char *dst, int flags));
EXTERN int		Tcl_ConvertToType _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, Tcl_ObjType *typePtr));
EXTERN int		Tcl_CreateAlias _ANSI_ARGS_((Tcl_Interp *slave,
			    char *slaveCmd, Tcl_Interp *target,
        		    char *targetCmd, int argc, char **argv));
EXTERN int		Tcl_CreateAliasObj _ANSI_ARGS_((Tcl_Interp *slave,
			    char *slaveCmd, Tcl_Interp *target,
        		    char *targetCmd, int objc,
		            Tcl_Obj *CONST objv[]));
EXTERN Tcl_Channel	Tcl_CreateChannel _ANSI_ARGS_((
    			    Tcl_ChannelType *typePtr, char *chanName,
                            ClientData instanceData, int mask));
EXTERN void		Tcl_CreateChannelHandler _ANSI_ARGS_((
			    Tcl_Channel chan, int mask,
                            Tcl_ChannelProc *proc, ClientData clientData));
EXTERN void		Tcl_CreateCloseHandler _ANSI_ARGS_((
			    Tcl_Channel chan, Tcl_CloseProc *proc,
                            ClientData clientData));
EXTERN Tcl_Command	Tcl_CreateCommand _ANSI_ARGS_((Tcl_Interp *interp,
			    char *cmdName, Tcl_CmdProc *proc,
			    ClientData clientData,
			    Tcl_CmdDeleteProc *deleteProc));
EXTERN void		Tcl_CreateEventSource _ANSI_ARGS_((
			    Tcl_EventSetupProc *setupProc,
			    Tcl_EventCheckProc *checkProc,
			    ClientData clientData));
EXTERN void		Tcl_CreateExitHandler _ANSI_ARGS_((Tcl_ExitProc *proc,
			    ClientData clientData));
EXTERN void		Tcl_CreateFileHandler _ANSI_ARGS_((
    			    int fd, int mask, Tcl_FileProc *proc,
			    ClientData clientData));
EXTERN Tcl_Interp *	Tcl_CreateInterp _ANSI_ARGS_((void));
EXTERN void		Tcl_CreateMathFunc _ANSI_ARGS_((Tcl_Interp *interp,
			    char *name, int numArgs, Tcl_ValueType *argTypes,
			    Tcl_MathProc *proc, ClientData clientData));
EXTERN Tcl_Command	Tcl_CreateObjCommand _ANSI_ARGS_((
			    Tcl_Interp *interp, char *cmdName,
			    Tcl_ObjCmdProc *proc, ClientData clientData,
			    Tcl_CmdDeleteProc *deleteProc));
EXTERN Tcl_Interp *	Tcl_CreateSlave _ANSI_ARGS_((Tcl_Interp *interp,
		            char *slaveName, int isSafe));
EXTERN Tcl_TimerToken	Tcl_CreateTimerHandler _ANSI_ARGS_((int milliseconds,
			    Tcl_TimerProc *proc, ClientData clientData));
EXTERN Tcl_Trace	Tcl_CreateTrace _ANSI_ARGS_((Tcl_Interp *interp,
			    int level, Tcl_CmdTraceProc *proc,
			    ClientData clientData));
EXTERN char *		Tcl_DbCkalloc _ANSI_ARGS_((unsigned int size,
			    char *file, int line));
EXTERN int		Tcl_DbCkfree _ANSI_ARGS_((char *ptr,
			    char *file, int line));
EXTERN char *		Tcl_DbCkrealloc _ANSI_ARGS_((char *ptr,
			    unsigned int size, char *file, int line));
EXTERN void		Tcl_DbDecrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr,
			    char *file, int line));
EXTERN void		Tcl_DbIncrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr,
			    char *file, int line));
EXTERN int		Tcl_DbIsShared _ANSI_ARGS_((Tcl_Obj *objPtr,
			    char *file, int line));
EXTERN Tcl_Obj *	Tcl_DbNewBooleanObj _ANSI_ARGS_((int boolValue,
                            char *file, int line));
EXTERN Tcl_Obj *	Tcl_DbNewDoubleObj _ANSI_ARGS_((double doubleValue,
                            char *file, int line));
EXTERN Tcl_Obj *	Tcl_DbNewListObj _ANSI_ARGS_((int objc,
			    Tcl_Obj *CONST objv[], char *file, int line));
EXTERN Tcl_Obj *	Tcl_DbNewLongObj _ANSI_ARGS_((long longValue,
                            char *file, int line));
EXTERN Tcl_Obj *	Tcl_DbNewObj _ANSI_ARGS_((char *file, int line));
EXTERN Tcl_Obj *	Tcl_DbNewStringObj _ANSI_ARGS_((char *bytes,
			    int length, char *file, int line));
EXTERN void		Tcl_DeleteAssocData _ANSI_ARGS_((Tcl_Interp *interp,
                            char *name));
EXTERN int		Tcl_DeleteCommand _ANSI_ARGS_((Tcl_Interp *interp,
			    char *cmdName));
EXTERN int		Tcl_DeleteCommandFromToken _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Command command));
EXTERN void		Tcl_DeleteChannelHandler _ANSI_ARGS_((
    			    Tcl_Channel chan, Tcl_ChannelProc *proc,
                            ClientData clientData));
EXTERN void		Tcl_DeleteCloseHandler _ANSI_ARGS_((
			    Tcl_Channel chan, Tcl_CloseProc *proc,
                            ClientData clientData));
EXTERN void		Tcl_DeleteEvents _ANSI_ARGS_((
			    Tcl_EventDeleteProc *proc,
                            ClientData clientData));
EXTERN void		Tcl_DeleteEventSource _ANSI_ARGS_((
			    Tcl_EventSetupProc *setupProc,
			    Tcl_EventCheckProc *checkProc,
			    ClientData clientData));
EXTERN void		Tcl_DeleteExitHandler _ANSI_ARGS_((Tcl_ExitProc *proc,
			    ClientData clientData));
EXTERN void		Tcl_DeleteFileHandler _ANSI_ARGS_((int fd));
EXTERN void		Tcl_DeleteHashEntry _ANSI_ARGS_((
			    Tcl_HashEntry *entryPtr));
EXTERN void		Tcl_DeleteHashTable _ANSI_ARGS_((
			    Tcl_HashTable *tablePtr));
EXTERN void		Tcl_DeleteInterp _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void		Tcl_DeleteTimerHandler _ANSI_ARGS_((
			    Tcl_TimerToken token));
EXTERN void		Tcl_DeleteTrace _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Trace trace));
EXTERN void		Tcl_DetachPids _ANSI_ARGS_((int numPids, Tcl_Pid *pidPtr));
EXTERN void		Tcl_DontCallWhenDeleted _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_InterpDeleteProc *proc,
			    ClientData clientData));
EXTERN int		Tcl_DoOneEvent _ANSI_ARGS_((int flags));
EXTERN void		Tcl_DoWhenIdle _ANSI_ARGS_((Tcl_IdleProc *proc,
			    ClientData clientData));
EXTERN char *		Tcl_DStringAppend _ANSI_ARGS_((Tcl_DString *dsPtr,
			    CONST char *string, int length));
EXTERN char *		Tcl_DStringAppendElement _ANSI_ARGS_((
			    Tcl_DString *dsPtr, CONST char *string));
EXTERN void		Tcl_DStringEndSublist _ANSI_ARGS_((Tcl_DString *dsPtr));
EXTERN void		Tcl_DStringFree _ANSI_ARGS_((Tcl_DString *dsPtr));
EXTERN void		Tcl_DStringGetResult _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_DString *dsPtr));
EXTERN void		Tcl_DStringInit _ANSI_ARGS_((Tcl_DString *dsPtr));
EXTERN void		Tcl_DStringResult _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_DString *dsPtr));
EXTERN void		Tcl_DStringSetLength _ANSI_ARGS_((Tcl_DString *dsPtr,
			    int length));
EXTERN void		Tcl_DStringStartSublist _ANSI_ARGS_((
			    Tcl_DString *dsPtr));
EXTERN Tcl_Obj *	Tcl_DuplicateObj _ANSI_ARGS_((Tcl_Obj *objPtr));
EXTERN int		Tcl_Eof _ANSI_ARGS_((Tcl_Channel chan));
EXTERN char *		Tcl_ErrnoId _ANSI_ARGS_((void));
EXTERN char *		Tcl_ErrnoMsg _ANSI_ARGS_((int err));
EXTERN int		Tcl_Eval _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string));
EXTERN int		Tcl_EvalFile _ANSI_ARGS_((Tcl_Interp *interp,
			    char *fileName));
EXTERN void		Tcl_EventuallyFree _ANSI_ARGS_((ClientData clientData,
			    Tcl_FreeProc *freeProc));
EXTERN int		Tcl_EvalObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
EXTERN void		Tcl_Exit _ANSI_ARGS_((int status));
EXTERN int		Tcl_ExposeCommand _ANSI_ARGS_((Tcl_Interp *interp,
        		    char *hiddenCmdToken, char *cmdName));
EXTERN int		Tcl_ExprBoolean _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, int *ptr));
EXTERN int		Tcl_ExprBooleanObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, int *ptr));
EXTERN int		Tcl_ExprDouble _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, double *ptr));
EXTERN int		Tcl_ExprDoubleObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, double *ptr));
EXTERN int		Tcl_ExprLong _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, long *ptr));
EXTERN int		Tcl_ExprLongObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, long *ptr));
EXTERN int		Tcl_ExprObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, Tcl_Obj **resultPtrPtr));
EXTERN int		Tcl_ExprString _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string));
EXTERN void		Tcl_Finalize _ANSI_ARGS_((void));
EXTERN void		Tcl_FindExecutable _ANSI_ARGS_((char *argv0));
EXTERN Tcl_HashEntry *	Tcl_FirstHashEntry _ANSI_ARGS_((
			    Tcl_HashTable *tablePtr,
			    Tcl_HashSearch *searchPtr));
EXTERN int		Tcl_Flush _ANSI_ARGS_((Tcl_Channel chan));
EXTERN void		TclFreeObj _ANSI_ARGS_((Tcl_Obj *objPtr));
EXTERN void		Tcl_FreeResult _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		Tcl_GetAlias _ANSI_ARGS_((Tcl_Interp *interp,
       			    char *slaveCmd, Tcl_Interp **targetInterpPtr,
                            char **targetCmdPtr, int *argcPtr,
			    char ***argvPtr));
EXTERN int		Tcl_GetAliasObj _ANSI_ARGS_((Tcl_Interp *interp,
       			    char *slaveCmd, Tcl_Interp **targetInterpPtr,
                            char **targetCmdPtr, int *objcPtr,
			    Tcl_Obj ***objv));
EXTERN ClientData	Tcl_GetAssocData _ANSI_ARGS_((Tcl_Interp *interp,
                            char *name, Tcl_InterpDeleteProc **procPtr));
EXTERN int		Tcl_GetBoolean _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, int *boolPtr));
EXTERN int		Tcl_GetBooleanFromObj _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Obj *objPtr,
			    int *boolPtr));
EXTERN Tcl_Channel	Tcl_GetChannel _ANSI_ARGS_((Tcl_Interp *interp,
	        	    char *chanName, int *modePtr));
EXTERN int		Tcl_GetChannelBufferSize _ANSI_ARGS_((
    			    Tcl_Channel chan));
EXTERN int		Tcl_GetChannelHandle _ANSI_ARGS_((Tcl_Channel chan,
	        	    int direction, ClientData *handlePtr));
EXTERN ClientData	Tcl_GetChannelInstanceData _ANSI_ARGS_((
    			    Tcl_Channel chan));
EXTERN int		Tcl_GetChannelMode _ANSI_ARGS_((Tcl_Channel chan));
EXTERN char *		Tcl_GetChannelName _ANSI_ARGS_((Tcl_Channel chan));
EXTERN int		Tcl_GetChannelOption _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Channel chan, char *optionName,
			    Tcl_DString *dsPtr));
EXTERN Tcl_ChannelType * Tcl_GetChannelType _ANSI_ARGS_((Tcl_Channel chan));
EXTERN int		Tcl_GetCommandInfo _ANSI_ARGS_((Tcl_Interp *interp,
			    char *cmdName, Tcl_CmdInfo *infoPtr));
EXTERN char *		Tcl_GetCommandName _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Command command));
EXTERN char *		Tcl_GetCwd _ANSI_ARGS_((char *buf, int len));
EXTERN int		Tcl_GetDouble _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, double *doublePtr));
EXTERN int		Tcl_GetDoubleFromObj _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Obj *objPtr,
			    double *doublePtr));
EXTERN int		Tcl_GetErrno _ANSI_ARGS_((void));
EXTERN int		Tcl_GetErrorLine _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN char *		Tcl_GetHostName _ANSI_ARGS_((void));
EXTERN int		Tcl_GetIndexFromObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, char **tablePtr, char *msg,
			    int flags, int *indexPtr));
EXTERN int		Tcl_GetInt _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, int *intPtr));
EXTERN int		Tcl_GetInterpPath _ANSI_ARGS_((Tcl_Interp *askInterp,
			    Tcl_Interp *slaveInterp));
EXTERN int		Tcl_GetIntFromObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, int *intPtr));
EXTERN int		Tcl_GetLongFromObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, long *longPtr));
EXTERN Tcl_Interp *	Tcl_GetMaster _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN Tcl_Obj *	Tcl_GetObjResult _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN Tcl_ObjType *	Tcl_GetObjType _ANSI_ARGS_((char *typeName));
EXTERN int		Tcl_GetOpenFile _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, int write, int checkUsage,
			    ClientData *filePtr));
EXTERN Tcl_Command	Tcl_GetOriginalCommand _ANSI_ARGS_((
			    Tcl_Command command));
EXTERN Tcl_PathType	Tcl_GetPathType _ANSI_ARGS_((char *path));
EXTERN int		Tcl_Gets _ANSI_ARGS_((Tcl_Channel chan,
        		    Tcl_DString *dsPtr));
EXTERN int		Tcl_GetsObj _ANSI_ARGS_((Tcl_Channel chan,
        		    Tcl_Obj *objPtr));
EXTERN int		Tcl_GetServiceMode _ANSI_ARGS_((void));
EXTERN Tcl_Interp *	Tcl_GetSlave _ANSI_ARGS_((Tcl_Interp *interp,
			    char *slaveName));
EXTERN Tcl_Channel	Tcl_GetStdChannel _ANSI_ARGS_((int type));
EXTERN char *		Tcl_GetStringFromObj _ANSI_ARGS_((Tcl_Obj *objPtr,
			    int *lengthPtr));
EXTERN char *		Tcl_GetStringResult _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN char *		Tcl_GetVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *varName, int flags));
EXTERN char *		Tcl_GetVar2 _ANSI_ARGS_((Tcl_Interp *interp,
			    char *part1, char *part2, int flags));
EXTERN int		Tcl_GlobalEval _ANSI_ARGS_((Tcl_Interp *interp,
			    char *command));
EXTERN int		Tcl_GlobalEvalObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
EXTERN char *		Tcl_HashStats _ANSI_ARGS_((Tcl_HashTable *tablePtr));
EXTERN int		Tcl_HideCommand _ANSI_ARGS_((Tcl_Interp *interp,
		            char *cmdName, char *hiddenCmdToken));
EXTERN int		Tcl_Init _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void		Tcl_InitHashTable _ANSI_ARGS_((Tcl_HashTable *tablePtr,
			    int keyType));
EXTERN void		Tcl_InitMemory _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		Tcl_InputBlocked _ANSI_ARGS_((Tcl_Channel chan));
EXTERN int		Tcl_InputBuffered _ANSI_ARGS_((Tcl_Channel chan));
EXTERN int		Tcl_InterpDeleted _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		Tcl_IsSafe _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void		Tcl_InvalidateStringRep _ANSI_ARGS_((
			    Tcl_Obj *objPtr));
EXTERN char *		Tcl_JoinPath _ANSI_ARGS_((int argc, char **argv,
			    Tcl_DString *resultPtr));
EXTERN int		Tcl_LinkVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *varName, char *addr, int type));
EXTERN int		Tcl_ListObjAppendList _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Obj *listPtr, 
			    Tcl_Obj *elemListPtr));
EXTERN int		Tcl_ListObjAppendElement _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Obj *listPtr,
			    Tcl_Obj *objPtr));
EXTERN int		Tcl_ListObjGetElements _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Obj *listPtr,
			    int *objcPtr, Tcl_Obj ***objvPtr));
EXTERN int		Tcl_ListObjIndex _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *listPtr, int index, 
			    Tcl_Obj **objPtrPtr));
EXTERN int		Tcl_ListObjLength _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *listPtr, int *intPtr));
EXTERN int		Tcl_ListObjReplace _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *listPtr, int first, int count,
			    int objc, Tcl_Obj *CONST objv[]));
EXTERN void		Tcl_Main _ANSI_ARGS_((int argc, char **argv,
			    Tcl_AppInitProc *appInitProc));
EXTERN Tcl_Channel	Tcl_MakeFileChannel _ANSI_ARGS_((ClientData handle,
			    int mode));
EXTERN int		Tcl_MakeSafe _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN Tcl_Channel	Tcl_MakeTcpClientChannel _ANSI_ARGS_((
    			    ClientData tcpSocket));
EXTERN char *		Tcl_Merge _ANSI_ARGS_((int argc, char **argv));
EXTERN Tcl_HashEntry *	Tcl_NextHashEntry _ANSI_ARGS_((
			    Tcl_HashSearch *searchPtr));
EXTERN void		Tcl_NotifyChannel _ANSI_ARGS_((Tcl_Channel channel,
			    int mask));
EXTERN Tcl_Obj *	Tcl_ObjGetVar2 _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr,
			    int flags));
EXTERN Tcl_Obj *	Tcl_ObjSetVar2 _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr,
			    Tcl_Obj *newValuePtr, int flags));
EXTERN Tcl_Channel	Tcl_OpenCommandChannel _ANSI_ARGS_((
    			    Tcl_Interp *interp, int argc, char **argv,
			    int flags));
EXTERN Tcl_Channel	Tcl_OpenFileChannel _ANSI_ARGS_((Tcl_Interp *interp,
        		    char *fileName, char *modeString,
                            int permissions));
EXTERN Tcl_Channel	Tcl_OpenTcpClient _ANSI_ARGS_((Tcl_Interp *interp,
			    int port, char *address, char *myaddr,
		            int myport, int async));
EXTERN Tcl_Channel	Tcl_OpenTcpServer _ANSI_ARGS_((Tcl_Interp *interp,
		            int port, char *host,
        		    Tcl_TcpAcceptProc *acceptProc,
			    ClientData callbackData));
EXTERN char *		Tcl_ParseVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char **termPtr));
EXTERN int		Tcl_PkgProvide _ANSI_ARGS_((Tcl_Interp *interp,
			    char *name, char *version));
EXTERN char *		Tcl_PkgRequire _ANSI_ARGS_((Tcl_Interp *interp,
			    char *name, char *version, int exact));
EXTERN char *		Tcl_PosixError _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void		Tcl_Preserve _ANSI_ARGS_((ClientData data));
EXTERN void		Tcl_PrintDouble _ANSI_ARGS_((Tcl_Interp *interp,
			    double value, char *dst));
EXTERN int		Tcl_PutEnv _ANSI_ARGS_((CONST char *string));
EXTERN void		Tcl_QueueEvent _ANSI_ARGS_((Tcl_Event *evPtr,
			    Tcl_QueuePosition position));
EXTERN int		Tcl_Read _ANSI_ARGS_((Tcl_Channel chan,
	        	    char *bufPtr, int toRead));
EXTERN void		Tcl_ReapDetachedProcs _ANSI_ARGS_((void));
EXTERN int		Tcl_RecordAndEval _ANSI_ARGS_((Tcl_Interp *interp,
			    char *cmd, int flags));
EXTERN int		Tcl_RecordAndEvalObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *cmdPtr, int flags));
EXTERN Tcl_RegExp	Tcl_RegExpCompile _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string));
EXTERN int		Tcl_RegExpExec _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_RegExp regexp, char *string, char *start));
EXTERN int		Tcl_RegExpMatch _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char *pattern));
EXTERN void		Tcl_RegExpRange _ANSI_ARGS_((Tcl_RegExp regexp,
			    int index, char **startPtr, char **endPtr));
EXTERN void		Tcl_RegisterChannel _ANSI_ARGS_((Tcl_Interp *interp,
	        	    Tcl_Channel chan));
EXTERN void		Tcl_RegisterObjType _ANSI_ARGS_((
			    Tcl_ObjType *typePtr));
EXTERN void		Tcl_Release _ANSI_ARGS_((ClientData clientData));
EXTERN void		Tcl_RestartIdleTimer _ANSI_ARGS_((void));
EXTERN void		Tcl_ResetResult _ANSI_ARGS_((Tcl_Interp *interp));
#define Tcl_Return Tcl_SetResult
EXTERN int		Tcl_ScanCountedElement _ANSI_ARGS_((CONST char *string,
			    int length, int *flagPtr));
EXTERN int		Tcl_ScanElement _ANSI_ARGS_((CONST char *string,
			    int *flagPtr));
EXTERN int		Tcl_Seek _ANSI_ARGS_((Tcl_Channel chan,
        		    int offset, int mode));
EXTERN int		Tcl_ServiceAll _ANSI_ARGS_((void));
EXTERN int		Tcl_ServiceEvent _ANSI_ARGS_((int flags));
EXTERN void		Tcl_SetAssocData _ANSI_ARGS_((Tcl_Interp *interp,
                            char *name, Tcl_InterpDeleteProc *proc,
                            ClientData clientData));
EXTERN void		Tcl_SetBooleanObj _ANSI_ARGS_((Tcl_Obj *objPtr, 
			    int boolValue));
EXTERN void		Tcl_SetChannelBufferSize _ANSI_ARGS_((
			    Tcl_Channel chan, int sz));
EXTERN int		Tcl_SetChannelOption _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Channel chan,
	        	    char *optionName, char *newValue));
EXTERN int		Tcl_SetCommandInfo _ANSI_ARGS_((Tcl_Interp *interp,
			    char *cmdName, Tcl_CmdInfo *infoPtr));
EXTERN void		Tcl_SetDoubleObj _ANSI_ARGS_((Tcl_Obj *objPtr, 
			    double doubleValue));
EXTERN void		Tcl_SetErrno _ANSI_ARGS_((int err));
EXTERN void		Tcl_SetErrorCode _ANSI_ARGS_(
    			    TCL_VARARGS(Tcl_Interp *,arg1));
EXTERN void		Tcl_SetIntObj _ANSI_ARGS_((Tcl_Obj *objPtr, 
			    int intValue));
EXTERN void		Tcl_SetListObj _ANSI_ARGS_((Tcl_Obj *objPtr, 
			    int objc, Tcl_Obj *CONST objv[]));
EXTERN void		Tcl_SetLongObj _ANSI_ARGS_((Tcl_Obj *objPtr, 
			    long longValue));
EXTERN void		Tcl_SetMaxBlockTime _ANSI_ARGS_((Tcl_Time *timePtr));
EXTERN void		Tcl_SetObjErrorCode _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *errorObjPtr));
EXTERN void		Tcl_SetObjLength _ANSI_ARGS_((Tcl_Obj *objPtr,
			    int length));
EXTERN void		Tcl_SetObjResult _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *resultObjPtr));
EXTERN void		Tcl_SetPanicProc _ANSI_ARGS_((void (*proc)
			    _ANSI_ARGS_(TCL_VARARGS(char *, format))));
EXTERN int		Tcl_SetRecursionLimit _ANSI_ARGS_((Tcl_Interp *interp,
			    int depth));
EXTERN void		Tcl_SetResult _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, Tcl_FreeProc *freeProc));
EXTERN int		Tcl_SetServiceMode _ANSI_ARGS_((int mode));
EXTERN void		Tcl_SetStdChannel _ANSI_ARGS_((Tcl_Channel channel,
			    int type));
EXTERN void		Tcl_SetStringObj _ANSI_ARGS_((Tcl_Obj *objPtr, 
			    char *bytes, int length));
EXTERN void		Tcl_SetTimer _ANSI_ARGS_((Tcl_Time *timePtr));
EXTERN char *		Tcl_SetVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *varName, char *newValue, int flags));
EXTERN char *		Tcl_SetVar2 _ANSI_ARGS_((Tcl_Interp *interp,
			    char *part1, char *part2, char *newValue,
			    int flags));
EXTERN char *		Tcl_SignalId _ANSI_ARGS_((int sig));
EXTERN char *		Tcl_SignalMsg _ANSI_ARGS_((int sig));
EXTERN void		Tcl_Sleep _ANSI_ARGS_((int ms));
EXTERN void		Tcl_SourceRCFile _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		Tcl_SplitList _ANSI_ARGS_((Tcl_Interp *interp,
			    char *list, int *argcPtr, char ***argvPtr));
EXTERN void		Tcl_SplitPath _ANSI_ARGS_((char *path,
			    int *argcPtr, char ***argvPtr));
EXTERN void		Tcl_StaticPackage _ANSI_ARGS_((Tcl_Interp *interp,
			    char *pkgName, Tcl_PackageInitProc *initProc,
			    Tcl_PackageInitProc *safeInitProc));
EXTERN int		Tcl_StringMatch _ANSI_ARGS_((char *string,
			    char *pattern));
EXTERN int		Tcl_Tell _ANSI_ARGS_((Tcl_Channel chan));
#define Tcl_TildeSubst Tcl_TranslateFileName
EXTERN int		Tcl_TraceVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *varName, int flags, Tcl_VarTraceProc *proc,
			    ClientData clientData));
EXTERN int		Tcl_TraceVar2 _ANSI_ARGS_((Tcl_Interp *interp,


			    char *part1, char *part2, int flags,
			    Tcl_VarTraceProc *proc, ClientData clientData));
EXTERN char *		Tcl_TranslateFileName _ANSI_ARGS_((Tcl_Interp *interp,

			    char *name, Tcl_DString *bufferPtr));
EXTERN int		Tcl_Ungets _ANSI_ARGS_((Tcl_Channel chan, char *str,
			    int len, int atHead));
EXTERN void		Tcl_UnlinkVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *varName));
EXTERN int		Tcl_UnregisterChannel _ANSI_ARGS_((Tcl_Interp *interp,

			    Tcl_Channel chan));

EXTERN int		Tcl_UnsetVar _ANSI_ARGS_((Tcl_Interp *interp,



			    char *varName, int flags));

EXTERN int		Tcl_UnsetVar2 _ANSI_ARGS_((Tcl_Interp *interp,
			    char *part1, char *part2, int flags));
EXTERN void		Tcl_UntraceVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *varName, int flags, Tcl_VarTraceProc *proc,
			    ClientData clientData));

EXTERN void		Tcl_UntraceVar2 _ANSI_ARGS_((Tcl_Interp *interp,



			    char *part1, char *part2, int flags,
			    Tcl_VarTraceProc *proc, ClientData clientData));
EXTERN void		Tcl_UpdateLinkedVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *varName));
EXTERN int		Tcl_UpVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *frameName, char *varName,

			    char *localName, int flags));
EXTERN int		Tcl_UpVar2 _ANSI_ARGS_((Tcl_Interp *interp,
			    char *frameName, char *part1, char *part2,

			    char *localName, int flags));
EXTERN int		Tcl_VarEval _ANSI_ARGS_(
    			    TCL_VARARGS(Tcl_Interp *,interp));
EXTERN ClientData	Tcl_VarTraceInfo _ANSI_ARGS_((Tcl_Interp *interp,
			    char *varName, int flags,
			    Tcl_VarTraceProc *procPtr,



			    ClientData prevClientData));
EXTERN ClientData	Tcl_VarTraceInfo2 _ANSI_ARGS_((Tcl_Interp *interp,
			    char *part1, char *part2, int flags,
			    Tcl_VarTraceProc *procPtr,
			    ClientData prevClientData));





EXTERN int		Tcl_WaitForEvent _ANSI_ARGS_((Tcl_Time *timePtr));
EXTERN Tcl_Pid		Tcl_WaitPid _ANSI_ARGS_((Tcl_Pid pid, int *statPtr, 

			    int options));
EXTERN int		Tcl_Write _ANSI_ARGS_((Tcl_Channel chan,
			    char *s, int slen));
EXTERN void		Tcl_WrongNumArgs _ANSI_ARGS_((Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[], char *message));

#endif /* RESOURCE_INCLUDED */




#endif /* _TCL */







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


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



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

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

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


>
>
>
>

1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448

































1449
1450
1451
































































































































































































































































































































































1452





































































1453
1454
1455
1456

1457
1458
1459


1460
1461
1462


1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474

1475
1476
1477
1478
1479
1480
1481
1482
1483

1484

1485
1486
1487
1488
1489

1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501

1502
1503
1504
1505
1506
1507
1508
1509

1510
1511
1512

1513

1514
1515
1516
1517
1518
1519
1520
typedef enum Tcl_PathType {
    TCL_PATH_ABSOLUTE,
    TCL_PATH_RELATIVE,
    TCL_PATH_VOLUME_RELATIVE
} Tcl_PathType;

/*
 * The following structure represents a user-defined encoding.  It collects
 * together all the functions that are used by the specific encoding.
 */

typedef struct Tcl_EncodingType {
    CONST char *encodingName;	/* The name of the encoding, e.g.  "euc-jp".
				 * This name is the unique key for this
				 * encoding type. */
    Tcl_EncodingConvertProc *toUtfProc;
				/* Procedure to convert from external
				 * encoding into UTF-8. */
    Tcl_EncodingConvertProc *fromUtfProc;
				/* Procedure to convert from UTF-8 into
				 * external encoding. */
    Tcl_EncodingFreeProc *freeProc;
				/* If non-NULL, procedure to call when this
				 * encoding is deleted. */
    ClientData clientData;	/* Arbitrary value associated with encoding
				 * type.  Passed to conversion procedures. */
    int nullSize;		/* Number of zero bytes that signify
				 * end-of-string in this encoding.  This
				 * number is used to determine the source
				 * string length when the srcLen argument is
				 * negative.  Must be 1 or 2. */
} Tcl_EncodingType;    

/*
 * The following definitions are used as values for the conversion control
 * flags argument when converting text from one character set to another:
 *
 * TCL_ENCODING_START:	     	Signifies that the source buffer is the first
 *				block in a (potentially multi-block) input
 *				stream.  Tells the conversion procedure to
 *				reset to an initial state and perform any
 *				initialization that needs to occur before the
 *				first byte is converted.  If the source
 *				buffer contains the entire input stream to be
 *				converted, this flag should be set.
 *
 * TCL_ENCODING_END:		Signifies that the source buffer is the last
 *				block in a (potentially multi-block) input
 *				stream.  Tells the conversion routine to
 *				perform any finalization that needs to occur
 *				after the last byte is converted and then to
 *				reset to an initial state.  If the source
 *				buffer contains the entire input stream to be
 *				converted, this flag should be set.
 *				
 * TCL_ENCODING_STOPONERROR:	If set, then the converter will return
 *				immediately upon encountering an invalid
 *				byte sequence or a source character that has
 *				no mapping in the target encoding.  If clear,
 *				then the converter will skip the problem,
 *				substituting one or more "close" characters
 *				in the destination buffer and then continue
 *				to sonvert the source.
 */

#define TCL_ENCODING_START		0x01
#define TCL_ENCODING_END		0x02
#define TCL_ENCODING_STOPONERROR	0x04

/*
 *----------------------------------------------------------------
 * The following data structures and declarations are for the new
 * Tcl parser.	This stuff should all move to tcl.h eventually.
 *----------------------------------------------------------------
 */

/*
 * For each word of a command, and for each piece of a word such as a
 * variable reference, one of the following structures is created to
 * describe the token.
 */

typedef struct Tcl_Token {
    int type;			/* Type of token, such as TCL_TOKEN_WORD;
				 * see below for valid types. */
    char *start;		/* First character in token. */
    int size;			/* Number of bytes in token. */
    int numComponents;		/* If this token is composed of other
				 * tokens, this field tells how many of
				 * them there are (including components of
				 * components, etc.).  The component tokens
				 * immediately follow this one. */
} Tcl_Token;

/*
 * Type values defined for Tcl_Token structures.  These values are
 * defined as mask bits so that it's easy to check for collections of
 * types.
 *
 * TCL_TOKEN_WORD -		The token describes one word of a command,
 *				from the first non-blank character of
 *				the word (which may be " or {) up to but
 *				not including the space, semicolon, or
 *				bracket that terminates the word. 
 *				NumComponents counts the total number of
 *				sub-tokens that make up the word.  This
 *				includes, for example, sub-tokens of
 *				TCL_TOKEN_VARIABLE tokens.
 * TCL_TOKEN_SIMPLE_WORD -	This token is just like TCL_TOKEN_WORD
 *				except that the word is guaranteed to
 *				consist of a single TCL_TOKEN_TEXT
 *				sub-token.
 * TCL_TOKEN_TEXT -		The token describes a range of literal
 *				text that is part of a word. 
 *				NumComponents is always 0.
 * TCL_TOKEN_BS -		The token describes a backslash sequence
 *				that must be collapsed.	 NumComponents
 *				is always 0.
 * TCL_TOKEN_COMMAND -		The token describes a command whose result
 *				must be substituted into the word.  The
 *				token includes the enclosing brackets. 
 *				NumComponents is always 0.
 * TCL_TOKEN_VARIABLE -		The token describes a variable
 *				substitution, including the dollar sign,
 *				variable name, and array index (if there
 *				is one) up through the right
 *				parentheses.  NumComponents tells how
 *				many additional tokens follow to
 *				represent the variable name.  The first
 *				token will be a TCL_TOKEN_TEXT token
 *				that describes the variable name.  If
 *				the variable is an array reference then
 *				there will be one or more additional
 *				tokens, of type TCL_TOKEN_TEXT,
 *				TCL_TOKEN_BS, TCL_TOKEN_COMMAND, and
 *				TCL_TOKEN_VARIABLE, that describe the
 *				array index; numComponents counts the
 *				total number of nested tokens that make
 *				up the variable reference, including
 *				sub-tokens of TCL_TOKEN_VARIABLE tokens.
 * TCL_TOKEN_SUB_EXPR -		The token describes one subexpression of a
 *				expression, from the first non-blank
 *				character of the subexpression up to but not
 *				including the space, brace, or bracket
 *				that terminates the subexpression. 
 *				NumComponents counts the total number of
 *				following subtokens that make up the
 *				subexpression; this includes all subtokens
 *				for any nested TCL_TOKEN_SUB_EXPR tokens.
 *				For example, a numeric value used as a
 *				primitive operand is described by a
 *				TCL_TOKEN_SUB_EXPR token followed by a
 *				TCL_TOKEN_TEXT token. A binary subexpression
 *				is described by a TCL_TOKEN_SUB_EXPR token
 *				followed by the	TCL_TOKEN_OPERATOR token
 *				for the operator, then TCL_TOKEN_SUB_EXPR
 *				tokens for the left then the right operands.
 * TCL_TOKEN_OPERATOR -		The token describes one expression operator.
 *				An operator might be the name of a math
 *				function such as "abs". A TCL_TOKEN_OPERATOR
 *				token is always preceeded by one
 *				TCL_TOKEN_SUB_EXPR token for the operator's
 *				subexpression, and is followed by zero or
 *				more TCL_TOKEN_SUB_EXPR tokens for the
 *				operator's operands. NumComponents is
 *				always 0.
 */

#define TCL_TOKEN_WORD		1
#define TCL_TOKEN_SIMPLE_WORD	2
#define TCL_TOKEN_TEXT		4
#define TCL_TOKEN_BS		8
#define TCL_TOKEN_COMMAND	16
#define TCL_TOKEN_VARIABLE	32
#define TCL_TOKEN_SUB_EXPR	64
#define TCL_TOKEN_OPERATOR	128

/*
 * A structure of the following type is filled in by Tcl_ParseCommand.
 * It describes a single command parsed from an input string.
 */

#define NUM_STATIC_TOKENS 20

typedef struct Tcl_Parse {
    char *commentStart;		/* Pointer to # that begins the first of
				 * one or more comments preceding the
				 * command. */
    int commentSize;		/* Number of bytes in comments (up through
				 * newline character that terminates the
				 * last comment).  If there were no
				 * comments, this field is 0. */
    char *commandStart;		/* First character in first word of command. */
    int commandSize;		/* Number of bytes in command, including
				 * first character of first word, up
				 * through the terminating newline,
				 * close bracket, or semicolon. */
    int numWords;		/* Total number of words in command.  May
				 * be 0. */
    Tcl_Token *tokenPtr;	/* Pointer to first token representing
				 * the words of the command.  Initially
				 * points to staticTokens, but may change
				 * to point to malloc-ed space if command
				 * exceeds space in staticTokens. */
    int numTokens;		/* Total number of tokens in command. */
    int tokensAvailable;	/* Total number of tokens available at
				 * *tokenPtr. */

    /*
     * The fields below are intended only for the private use of the
     * parser.	They should not be used by procedures that invoke
     * Tcl_ParseCommand.
     */

    char *string;		/* The original command string passed to
				 * Tcl_ParseCommand. */
    char *end;			/* Points to the character just after the
				 * last one in the command string. */
    Tcl_Interp *interp;		/* Interpreter to use for error reporting,
				 * or NULL. */
    char *term;			/* Points to character in string that
				 * terminated most recent token.  Filled in
				 * by ParseTokens.  If an error occurs,
				 * points to beginning of region where the
				 * error occurred (e.g. the open brace if
				 * the close brace is missing). */
    int incomplete;		/* This field is set to 1 by Tcl_ParseCommand
				 * if the command appears to be incomplete.
				 * This information is used by
				 * Tcl_CommandComplete. */
    Tcl_Token staticTokens[NUM_STATIC_TOKENS];
				/* Initial space for tokens for command.
				 * This space should be large enough to
				 * accommodate most commands; dynamic
				 * space is allocated for very large
				 * commands that don't fit here. */
} Tcl_Parse;

/*
 * The following definitions are the error codes returned by the conversion
 * routines:
 *
 * TCL_OK:			All characters were converted.
 *
 * TCL_CONVERT_NOSPACE:		The output buffer would not have been large
 *				enough for all of the converted data; as many
 *				characters as could fit were converted though.
 *
 * TCL_CONVERT_MULTIBYTE:	The last few bytes in the source string were
 *				the beginning of a multibyte sequence, but
 *				more bytes were needed to complete this
 *				sequence.  A subsequent call to the conversion
 *				routine should pass the beginning of this
 *				unconverted sequence plus additional bytes
 *				from the source stream to properly convert
 *				the formerly split-up multibyte sequence.
 *
 * TCL_CONVERT_SYNTAX:		The source stream contained an invalid
 *				character sequence.  This may occur if the
 *				input stream has been damaged or if the input
 *				encoding method was misidentified.  This error
 *				is reported only if TCL_ENCODING_STOPONERROR
 *				was specified.
 * 
 * TCL_CONVERT_UNKNOWN:		The source string contained a character
 *				that could not be represented in the target
 *				encoding.  This error is reported only if
 *				TCL_ENCODING_STOPONERROR was specified.
 */

#define TCL_CONVERT_MULTIBYTE		-1
#define TCL_CONVERT_SYNTAX		-2
#define TCL_CONVERT_UNKNOWN		-3
#define TCL_CONVERT_NOSPACE		-4

/*
 * The maximum number of bytes that are necessary to represent a single
 * Unicode character in UTF-8.
 */

#define TCL_UTF_MAX		3

/*
 * This represents a Unicode character.  
 */

typedef unsigned short Tcl_UniChar;

/*
 * Deprecated Tcl procedures:
 */

#ifndef TCL_NO_DEPRECATED
#define Tcl_EvalObj(interp,objPtr) Tcl_EvalObjEx((interp),(objPtr),0)
#define Tcl_GlobalEvalObj(interp,objPtr) \
	Tcl_EvalObjEx((interp),(objPtr),TCL_EVAL_GLOBAL)
#endif

/*
 * These function have been renamed. The old names are deprecated, but we
 * define these macros for backwards compatibilty.
 */


































#define Tcl_Ckalloc Tcl_Alloc
#define Tcl_Ckfree Tcl_Free
#define Tcl_Ckrealloc Tcl_Realloc
































































































































































































































































































































































#define Tcl_Return Tcl_SetResult





































































#define Tcl_TildeSubst Tcl_TranslateFileName
#define panic Tcl_Panic
#define panicVA Tcl_PanicVA


/*
 * The following constant is used to test for older versions of Tcl
 * in the stubs tables.


 *
 * Jan Nijtman's plus patch uses 0xFCA1BACF, so we need to pick a different
 * value since the stubs tables don't match.


 */

#define TCL_STUB_MAGIC 0xFCA3BACF

/*
 * The following function is required to be defined in all stubs aware
 * extensions.  The function is actually implemented in the stub
 * library, not the main Tcl library, although there is a trivial
 * implementation in the main library in case an extension is statically
 * linked into an application.
 */


EXTERN char *		Tcl_InitStubs _ANSI_ARGS_((Tcl_Interp *interp,
			    char *version, int exact));

#ifndef USE_TCL_STUBS

/*
 * When not using stubs, make it a macro.
 */


#define Tcl_InitStubs(interp, version, exact) \

    Tcl_PkgRequire(interp, "Tcl", version, exact)

#endif



/*
 * Include the public function declarations that are accessible via
 * the stubs table.
 */

#include "tclDecls.h"

/*
 * Public functions that are not accessible via the stubs table.
 */

EXTERN void Tcl_Main _ANSI_ARGS_((int argc, char **argv,

	Tcl_AppInitProc *appInitProc));

/*
 * Convenience declaration of Tcl_AppInit for backwards compatibility.
 * This function is not *implemented* by the tcl library, so the storage
 * class is neither DLLEXPORT nor DLLIMPORT
 */


#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS


EXTERN int		Tcl_AppInit _ANSI_ARGS_((Tcl_Interp *interp));


#endif /* RESOURCE_INCLUDED */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#endif /* _TCL */

Changes to generic/tclAlloc.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
65
/* 
 * tclAlloc.c --
 *
 *	This is a very fast storage allocator.  It allocates blocks of a
 *	small number of different sizes, and keeps free lists of each size.
 *	Blocks that don't exactly fit are passed up to the next larger size.
 *	Blocks over a certain size are directly allocated from the system.
 *
 * Copyright (c) 1983 Regents of the University of California.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.

 *
 * Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclAlloc.c 1.4 97/08/11 18:45:38
 */

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



#ifdef TCL_DEBUG
#   define DEBUG
/* #define MSTATS */
#   define RCHECK
#endif

typedef unsigned long caddr_t;

/*
 * The overhead on a block is at least 4 bytes.  When free, this space
 * contains a pointer to the next free block, and the bottom two bits must
 * be zero.  When in use, the first byte is set to MAGIC, and the second
 * byte is the size index.  The remaining bytes are for alignment.
 * If range checking is enabled then a second word holds the size of the
 * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
 * The order of elements is critical: ov_magic must overlay the low order
 * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
 */

union overhead {
    union overhead *ov_next;	/* when free */

    struct {
	unsigned char	ovu_magic0;	/* magic number */
	unsigned char	ovu_index;	/* bucket # */
	unsigned char	ovu_unused;	/* unused */
	unsigned char	ovu_magic1;	/* other magic number */
#ifdef RCHECK
	unsigned short	ovu_rmagic;	/* range magic number */
	unsigned long	ovu_size;	/* actual block size */

#endif
    } ovu;
#define ov_magic0	ovu.ovu_magic0
#define ov_magic1	ovu.ovu_magic1
#define ov_index	ovu.ovu_index
#define ov_rmagic	ovu.ovu_rmagic
#define ov_size	ovu.ovu_size
};


#define MAGIC		0xef		/* magic # on accounting info */
#define RMAGIC		0x5555		/* magic # on range info */

#ifdef RCHECK










>






|




>
>










|











>








>






|







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
/* 
 * tclAlloc.c --
 *
 *	This is a very fast storage allocator.  It allocates blocks of a
 *	small number of different sizes, and keeps free lists of each size.
 *	Blocks that don't exactly fit are passed up to the next larger size.
 *	Blocks over a certain size are directly allocated from the system.
 *
 * Copyright (c) 1983 Regents of the University of California.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclAlloc.c,v 1.1.2.7 1999/03/25 00:34:15 redman Exp $
 */

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

#if USE_TCLALLOC

#ifdef TCL_DEBUG
#   define DEBUG
/* #define MSTATS */
#   define RCHECK
#endif

typedef unsigned long caddr_t;

/*
 * The overhead on a block is at least 8 bytes.  When free, this space
 * contains a pointer to the next free block, and the bottom two bits must
 * be zero.  When in use, the first byte is set to MAGIC, and the second
 * byte is the size index.  The remaining bytes are for alignment.
 * If range checking is enabled then a second word holds the size of the
 * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
 * The order of elements is critical: ov_magic must overlay the low order
 * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
 */

union overhead {
    union overhead *ov_next;	/* when free */
    unsigned char ov_padding[8]; /* Ensure the structure is 8-byte aligned. */
    struct {
	unsigned char	ovu_magic0;	/* magic number */
	unsigned char	ovu_index;	/* bucket # */
	unsigned char	ovu_unused;	/* unused */
	unsigned char	ovu_magic1;	/* other magic number */
#ifdef RCHECK
	unsigned short	ovu_rmagic;	/* range magic number */
	unsigned long	ovu_size;	/* actual block size */
	unsigned short  ovu_unused2;    /* padding to 8-byte align */
#endif
    } ovu;
#define ov_magic0	ovu.ovu_magic0
#define ov_magic1	ovu.ovu_magic1
#define ov_index	ovu.ovu_index
#define ov_rmagic	ovu.ovu_rmagic
#define ov_size		ovu.ovu_size
};


#define MAGIC		0xef		/* magic # on accounting info */
#define RMAGIC		0x5555		/* magic # on range info */

#ifdef RCHECK
75
76
77
78
79
80
81






























82
83
84
85
86
87
88
 * smallest allocatable block is 8 bytes.  The overhead information
 * precedes the data area returned to the user.
 */

#define NBUCKETS	13
#define MAXMALLOC	(1<<(NBUCKETS+2))
static	union overhead *nextf[NBUCKETS];































#ifdef MSTATS

/*
 * nmalloc[i] is the difference between the number of mallocs and frees
 * for a given block size.
 */







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







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
 * smallest allocatable block is 8 bytes.  The overhead information
 * precedes the data area returned to the user.
 */

#define NBUCKETS	13
#define MAXMALLOC	(1<<(NBUCKETS+2))
static	union overhead *nextf[NBUCKETS];

/* 
 * The following structure is used to keep track of all system memory 
 * currently owned by Tcl.  When finalizing, all this memory will
 * be returned to the system.
 */

struct block {
    struct block *nextPtr;	/* Linked list. */
    struct block *prevPtr;	/* Linked list for big blocks, ensures 8-byte 
				 * alignment for suballocated blocks. */
};

static struct block *blockList;		/* Tracks the suballocated blocks. */
static struct block bigBlocks = {	/* Big blocks aren't suballocated. */
    &bigBlocks, &bigBlocks
};

/*
 * The allocator is protected by a special mutex that must be
 * explicitly initialized.  Futhermore, because Tcl_Alloc may be
 * used before anything else in Tcl, we make this module self-initializing
 * after all with the allocInit variable.
 */

#ifdef TCL_THREADS
static TclpMutex allocMutex;
#endif
static int allocInit = 0;


#ifdef MSTATS

/*
 * nmalloc[i] is the difference between the number of mallocs and frees
 * for a given block size.
 */
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
#endif

/*
 * Prototypes for functions used only in this file.
 */

static void 		MoreCore _ANSI_ARGS_((int bucket));




















































































/*
 *----------------------------------------------------------------------
 *
 * TclpAlloc --
 *
 *	Allocate more memory.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpAlloc(
    unsigned int nbytes)	/* Number of bytes to allocate. */
{
    register union overhead *op;
    register long bucket;
    register unsigned amt;













    /*
     * First the simple case: we simple allocate big blocks directly
     */
    if (nbytes + OVERHEAD >= MAXMALLOC) {
	op = (union overhead *)TclpSysAlloc(nbytes+OVERHEAD, 0);

	if (op == NULL) {

	    return NULL;
	}






	op->ov_magic0 = op->ov_magic1 = MAGIC;
	op->ov_index = 0xff;
#ifdef MSTATS
	nmalloc[NBUCKETS]++;
#endif
#ifdef RCHECK
	/*
	 * Record allocated size of block and
	 * bound space with magic numbers.
	 */
	op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
	op->ov_rmagic = RMAGIC;
	*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif

	return (void *)(op+1);
    }
    /*
     * Convert amount of memory requested into closest block size
     * stored in hash buckets which satisfies request.
     * Account for space used per block for accounting.
     */
#ifndef RCHECK
    amt = 8;	/* size of first bucket */
    bucket = 0;
#else
    amt = 16;	/* size of first bucket */
    bucket = 1;
#endif
    while (nbytes + OVERHEAD > amt) {
	amt <<= 1;
	if (amt == 0) {

	    return (NULL);
	}
	bucket++;
    }
    ASSERT( bucket < NBUCKETS );

    /*
     * If nothing in hash bucket right now,
     * request more memory from the system.
     */
    if ((op = nextf[bucket]) == NULL) {
	MoreCore(bucket);
	if ((op = nextf[bucket]) == NULL) {

	    return (NULL);
	}
    }
    /*
     * Remove from linked list
     */
    nextf[bucket] = op->ov_next;







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


















|
|




>

>
>
>
>
>
>
>
>
>
>
>




|
>
|
>


>
>
>
>
>
>














>

















>













>







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
#endif

/*
 * Prototypes for functions used only in this file.
 */

static void 		MoreCore _ANSI_ARGS_((int bucket));


/*
 *-------------------------------------------------------------------------
 *
 * TclInitAlloc --
 *
 *	Initialize the memory system.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Initialize the mutex used to serialize allocations.
 *
 *-------------------------------------------------------------------------
 */

void
TclInitAlloc()
{
    if (!allocInit) {
	allocInit = 1;
	TclpMutexInit(&allocMutex);
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * TclFinalizeAllocSubsystem --
 *
 *	Release all resources being used by this subsystem, including 
 *	aggressively freeing all memory allocated by TclpAlloc() that 
 *	has not yet been released with TclpFree().
 *	
 *	After this function is called, all memory allocated with 
 *	TclpAlloc() should be considered unusable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	This subsystem is self-initializing, since memory can be 
 *	allocated before Tcl is formally initialized.  After this call,
 *	this subsystem has been reset to its initial state and is 
 *	usable again.
 *
 *-------------------------------------------------------------------------
 */

void
TclFinalizeAllocSubsystem()
{
    int i;
    struct block *blockPtr, *nextPtr;

    TclpMutexLock(&allocMutex);
    for (blockPtr = blockList; blockPtr != NULL; blockPtr = nextPtr) {
	nextPtr = blockPtr->nextPtr;
	TclpSysFree(blockPtr);
    }
    blockList = NULL;

    for (blockPtr = bigBlocks.nextPtr; blockPtr != &bigBlocks; ) {
	nextPtr = blockPtr->nextPtr;
	TclpSysFree(blockPtr);
	blockPtr = nextPtr;
    }
    bigBlocks.nextPtr = &bigBlocks;
    bigBlocks.prevPtr = &bigBlocks;

    for (i = 0; i < NBUCKETS; i++) {
	nextf[i] = NULL;
#ifdef MSTATS
	nmalloc[i] = 0;
#endif
    }
#ifdef MSTATS
    nmalloc[i] = 0;
#endif
    TclpMutexUnlock(&allocMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpAlloc --
 *
 *	Allocate more memory.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpAlloc(nbytes)
    unsigned int nbytes;	/* Number of bytes to allocate. */
{
    register union overhead *op;
    register long bucket;
    register unsigned amt;
    struct block *bigBlockPtr;

    if (!allocInit) {
	/*
	 * We have to make the "self initializing" because Tcl_Alloc
	 * may be used before any other part of Tcl.  E.g., see
	 * main() for tclsh!
	 */

	allocInit = 1;
	TclpMutexInit(&allocMutex);
    }
    TclpMutexLock(&allocMutex);
    /*
     * First the simple case: we simple allocate big blocks directly
     */
    if (nbytes + OVERHEAD >= MAXMALLOC) {
	bigBlockPtr = (struct block *) TclpSysAlloc((unsigned) 
		(sizeof(struct block) + OVERHEAD + nbytes), 0);
	if (bigBlockPtr == NULL) {
	    TclpMutexUnlock(&allocMutex);
	    return NULL;
	}
	bigBlockPtr->nextPtr = bigBlocks.nextPtr;
	bigBlocks.nextPtr = bigBlockPtr;
	bigBlockPtr->prevPtr = &bigBlocks;
	bigBlockPtr->nextPtr->prevPtr = bigBlockPtr;

	op = (union overhead *) (bigBlockPtr + 1);
	op->ov_magic0 = op->ov_magic1 = MAGIC;
	op->ov_index = 0xff;
#ifdef MSTATS
	nmalloc[NBUCKETS]++;
#endif
#ifdef RCHECK
	/*
	 * Record allocated size of block and
	 * bound space with magic numbers.
	 */
	op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
	op->ov_rmagic = RMAGIC;
	*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif
	TclpMutexUnlock(&allocMutex);
	return (void *)(op+1);
    }
    /*
     * Convert amount of memory requested into closest block size
     * stored in hash buckets which satisfies request.
     * Account for space used per block for accounting.
     */
#ifndef RCHECK
    amt = 8;	/* size of first bucket */
    bucket = 0;
#else
    amt = 16;	/* size of first bucket */
    bucket = 1;
#endif
    while (nbytes + OVERHEAD > amt) {
	amt <<= 1;
	if (amt == 0) {
	    TclpMutexUnlock(&allocMutex);
	    return (NULL);
	}
	bucket++;
    }
    ASSERT( bucket < NBUCKETS );

    /*
     * If nothing in hash bucket right now,
     * request more memory from the system.
     */
    if ((op = nextf[bucket]) == NULL) {
	MoreCore(bucket);
	if ((op = nextf[bucket]) == NULL) {
	    TclpMutexUnlock(&allocMutex);
	    return (NULL);
	}
    }
    /*
     * Remove from linked list
     */
    nextf[bucket] = op->ov_next;
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
     * Record allocated size of block and
     * bound space with magic numbers.
     */
    op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
    op->ov_rmagic = RMAGIC;
    *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif

    return ((char *)(op + 1));
}

/*
 *----------------------------------------------------------------------
 *
 * MoreCore --
 *
 *	Allocate more memory to the indicated bucket.


 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Attempts to get more memory from the system.
 *
 *----------------------------------------------------------------------
 */

static void
MoreCore(
    int bucket)		/* What bucket to allocat to. */
{
    register union overhead *op;
    register long sz;		/* size of desired block */
    long amt;			/* amount to allocate */
    int nblks;			/* how many blocks we get */


    /*
     * sbrk_size <= 0 only for big, FLUFFY, requests (about
     * 2^30 bytes on a VAX, I think) or for a negative arg.
     */
    sz = 1 << (bucket + 3);
    ASSERT(sz > 0);

    amt = MAXMALLOC;
    nblks = amt / sz;
    ASSERT(nblks*sz == amt);

    op = (union overhead *)TclpSysAlloc(amt, 1);

    /* no more room! */
    if (op == NULL) {
	return;
    }




    
    /*
     * Add new memory allocated to that on
     * free list for this hash bucket.
     */
    nextf[bucket] = op;
    while (--nblks > 0) {







>









>
>











|
|





>












|
>

|


>
>
>
>







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
     * Record allocated size of block and
     * bound space with magic numbers.
     */
    op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
    op->ov_rmagic = RMAGIC;
    *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif
    TclpMutexUnlock(&allocMutex);
    return ((char *)(op + 1));
}

/*
 *----------------------------------------------------------------------
 *
 * MoreCore --
 *
 *	Allocate more memory to the indicated bucket.
 *
 *	Assumes Mutex is already held.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Attempts to get more memory from the system.
 *
 *----------------------------------------------------------------------
 */

static void
MoreCore(bucket)
    int bucket;		/* What bucket to allocat to. */
{
    register union overhead *op;
    register long sz;		/* size of desired block */
    long amt;			/* amount to allocate */
    int nblks;			/* how many blocks we get */
    struct block *blockPtr;

    /*
     * sbrk_size <= 0 only for big, FLUFFY, requests (about
     * 2^30 bytes on a VAX, I think) or for a negative arg.
     */
    sz = 1 << (bucket + 3);
    ASSERT(sz > 0);

    amt = MAXMALLOC;
    nblks = amt / sz;
    ASSERT(nblks*sz == amt);

    blockPtr = (struct block *) TclpSysAlloc((unsigned) 
	    (sizeof(struct block) + amt), 1);
    /* no more room! */
    if (blockPtr == NULL) {
	return;
    }
    blockPtr->nextPtr = blockList;
    blockList = blockPtr;

    op = (union overhead *) (blockPtr + 1);
    
    /*
     * Add new memory allocated to that on
     * free list for this hash bucket.
     */
    nextf[bucket] = op;
    while (--nblks > 0) {
272
273
274
275
276
277
278
279
280
281
282
283

284
285
286
287
288

289
290
291
292
293

294
295
296
297
298
299
300
301
302
303



304

305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337

338
339
340
341
342
343


344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361




362

363

364
365












366
367
368
369
370
371
372
373
374
375
376

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


390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TclpFree(
    char *cp)		/* Pointer to memory to free. */
{   
    register long size;
    register union overhead *op;


    if (cp == NULL) {
	return;
    }


    op = (union overhead *)((caddr_t)cp - sizeof (union overhead));

    ASSERT(op->ov_magic0 == MAGIC);		/* make sure it was in use */
    ASSERT(op->ov_magic1 == MAGIC);
    if (op->ov_magic0 != MAGIC || op->ov_magic1 != MAGIC) {

	return;
    }

    RANGE_ASSERT(op->ov_rmagic == RMAGIC);
    RANGE_ASSERT(*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
    size = op->ov_index;
    if ( size == 0xff ) {
#ifdef MSTATS
	nmalloc[NBUCKETS]--;
#endif



	TclpSysFree(op);

	return;
    }
    ASSERT(size < NBUCKETS);
    op->ov_next = nextf[size];	/* also clobbers ov_magic */
    nextf[size] = op;
#ifdef MSTATS
    nmalloc[size]--;
#endif

}

/*
 *----------------------------------------------------------------------
 *
 * TclpRealloc --
 *
 *	Reallocate memory.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpRealloc(
    char *cp,			/* Pointer to alloced block. */
    unsigned int nbytes)	/* New size of memory. */
{   
    int i;
    union overhead *op;

    int expensive;
    unsigned long maxsize;

    if (cp == NULL) {
	return (TclpAlloc(nbytes));
    }



    op = (union overhead *)((caddr_t)cp - sizeof (union overhead));

    ASSERT(op->ov_magic0 == MAGIC);		/* make sure it was in use */
    ASSERT(op->ov_magic1 == MAGIC);
    if (op->ov_magic0 != MAGIC || op->ov_magic1 != MAGIC) {

	return NULL;
    }

    RANGE_ASSERT(op->ov_rmagic == RMAGIC);
    RANGE_ASSERT(*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
    i = op->ov_index;

    /*
     * If the block isn't in a bin, just realloc it.
     */

    if (i == 0xff) {




	op = (union overhead *) TclpSysRealloc(op, nbytes+OVERHEAD);

	if (op == NULL) {

	    return NULL;
	}












#ifdef MSTATS
	nmalloc[NBUCKETS]++;
#endif
#ifdef RCHECK
	/*
	 * Record allocated size of block and update magic number bounds.
	 */

	op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
	*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif

	return (char *)(op+1);
    }
    maxsize = 1 << (i+3);
    expensive = 0;
    if ( nbytes + OVERHEAD > maxsize ) {
	expensive = 1;
    } else if ( i > 0 && nbytes + OVERHEAD < (maxsize/2) ) {
	expensive = 1;
    }

    if (expensive) {
	void *newp;
		


	newp = TclpAlloc(nbytes);
	if ( newp == NULL ) {
	    return NULL;
	}
	maxsize -= OVERHEAD;
	if ( maxsize < nbytes )
	    nbytes = maxsize;
	memcpy((VOID *) newp, (VOID *) cp, (size_t) nbytes);
	TclpFree(cp);
	return newp;
    }
    
    /*
     * Ok, we don't have to copy, it fits as-is
     */
#ifdef RCHECK
    op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
    *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif

    return(cp);
}

/*
 *----------------------------------------------------------------------
 *
 * mstats --







|
|



>





>





>










>
>
>
|
>








>



















|
|
|



>






>
>






>












>
>
>
>
|
>
|
>


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











>












|
>
>



















>







422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TclpFree(cp)
    char *cp;		/* Pointer to memory to free. */
{   
    register long size;
    register union overhead *op;
    struct block *bigBlockPtr;

    if (cp == NULL) {
	return;
    }

    TclpMutexLock(&allocMutex);
    op = (union overhead *)((caddr_t)cp - sizeof (union overhead));

    ASSERT(op->ov_magic0 == MAGIC);		/* make sure it was in use */
    ASSERT(op->ov_magic1 == MAGIC);
    if (op->ov_magic0 != MAGIC || op->ov_magic1 != MAGIC) {
	TclpMutexUnlock(&allocMutex);
	return;
    }

    RANGE_ASSERT(op->ov_rmagic == RMAGIC);
    RANGE_ASSERT(*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
    size = op->ov_index;
    if ( size == 0xff ) {
#ifdef MSTATS
	nmalloc[NBUCKETS]--;
#endif
	bigBlockPtr = (struct block *) op - 1;
	bigBlockPtr->prevPtr->nextPtr = bigBlockPtr->nextPtr;
	bigBlockPtr->nextPtr->prevPtr = bigBlockPtr->prevPtr;
	TclpSysFree(bigBlockPtr);
	TclpMutexUnlock(&allocMutex);
	return;
    }
    ASSERT(size < NBUCKETS);
    op->ov_next = nextf[size];	/* also clobbers ov_magic */
    nextf[size] = op;
#ifdef MSTATS
    nmalloc[size]--;
#endif
    TclpMutexUnlock(&allocMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpRealloc --
 *
 *	Reallocate memory.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpRealloc(cp, nbytes)
    char *cp;			/* Pointer to alloced block. */
    unsigned int nbytes;	/* New size of memory. */
{   
    int i;
    union overhead *op;
    struct block *bigBlockPtr;
    int expensive;
    unsigned long maxsize;

    if (cp == NULL) {
	return (TclpAlloc(nbytes));
    }

    TclpMutexLock(&allocMutex);

    op = (union overhead *)((caddr_t)cp - sizeof (union overhead));

    ASSERT(op->ov_magic0 == MAGIC);		/* make sure it was in use */
    ASSERT(op->ov_magic1 == MAGIC);
    if (op->ov_magic0 != MAGIC || op->ov_magic1 != MAGIC) {
	TclpMutexUnlock(&allocMutex);
	return NULL;
    }

    RANGE_ASSERT(op->ov_rmagic == RMAGIC);
    RANGE_ASSERT(*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
    i = op->ov_index;

    /*
     * If the block isn't in a bin, just realloc it.
     */

    if (i == 0xff) {
	struct block *prevPtr, *nextPtr;
	bigBlockPtr = (struct block *) op - 1;
	prevPtr = bigBlockPtr->prevPtr;
	nextPtr = bigBlockPtr->nextPtr;
	bigBlockPtr = (struct block *) TclpSysRealloc(bigBlockPtr, 
		sizeof(struct block) + OVERHEAD + nbytes);
	if (bigBlockPtr == NULL) {
	    TclpMutexUnlock(&allocMutex);
	    return NULL;
	}

	if (prevPtr->nextPtr != bigBlockPtr) {
	    /*
	     * If the block has moved, splice the new block into the list where
	     * the old block used to be. 
	     */

	    prevPtr->nextPtr = bigBlockPtr;
	    nextPtr->prevPtr = bigBlockPtr;
	}

	op = (union overhead *) (bigBlockPtr + 1);
#ifdef MSTATS
	nmalloc[NBUCKETS]++;
#endif
#ifdef RCHECK
	/*
	 * Record allocated size of block and update magic number bounds.
	 */

	op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
	*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif
	TclpMutexUnlock(&allocMutex);
	return (char *)(op+1);
    }
    maxsize = 1 << (i+3);
    expensive = 0;
    if ( nbytes + OVERHEAD > maxsize ) {
	expensive = 1;
    } else if ( i > 0 && nbytes + OVERHEAD < (maxsize/2) ) {
	expensive = 1;
    }

    if (expensive) {
	void *newp;

	TclpMutexUnlock(&allocMutex);

	newp = TclpAlloc(nbytes);
	if ( newp == NULL ) {
	    return NULL;
	}
	maxsize -= OVERHEAD;
	if ( maxsize < nbytes )
	    nbytes = maxsize;
	memcpy((VOID *) newp, (VOID *) cp, (size_t) nbytes);
	TclpFree(cp);
	return newp;
    }
    
    /*
     * Ok, we don't have to copy, it fits as-is
     */
#ifdef RCHECK
    op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
    *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif
    TclpMutexUnlock(&allocMutex);
    return(cp);
}

/*
 *----------------------------------------------------------------------
 *
 * mstats --
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











































































 *	None.
 *
 *----------------------------------------------------------------------
 */

#ifdef MSTATS
void
mstats(
    char *s)	/* Where to write info. */
{
    register int i, j;
    register union overhead *p;
    int totfree = 0,
	totused = 0;


    fprintf(stderr, "Memory allocation statistics %s\nTclpFree:\t", s);
    for (i = 0; i < NBUCKETS; i++) {
	for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
	    fprintf(stderr, " %d", j);
	totfree += j * (1 << (i + 3));
    }
    fprintf(stderr, "\nused:\t");
    for (i = 0; i < NBUCKETS; i++) {
	fprintf(stderr, " %d", nmalloc[i]);
	totused += nmalloc[i] * (1 << (i + 3));
    }
    fprintf(stderr, "\n\tTotal small in use: %d, total free: %d\n",
	    totused, totfree);
    fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %d\n", 
	    MAXMALLOC, nmalloc[NBUCKETS]);

}
#endif


















































































|
|






>















>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
 *	None.
 *
 *----------------------------------------------------------------------
 */

#ifdef MSTATS
void
mstats(s)
    char *s;	/* Where to write info. */
{
    register int i, j;
    register union overhead *p;
    int totfree = 0,
	totused = 0;

    TclpMutexLock(&allocMutex);
    fprintf(stderr, "Memory allocation statistics %s\nTclpFree:\t", s);
    for (i = 0; i < NBUCKETS; i++) {
	for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
	    fprintf(stderr, " %d", j);
	totfree += j * (1 << (i + 3));
    }
    fprintf(stderr, "\nused:\t");
    for (i = 0; i < NBUCKETS; i++) {
	fprintf(stderr, " %d", nmalloc[i]);
	totused += nmalloc[i] * (1 << (i + 3));
    }
    fprintf(stderr, "\n\tTotal small in use: %d, total free: %d\n",
	    totused, totfree);
    fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %d\n", 
	    MAXMALLOC, nmalloc[NBUCKETS]);
    TclpMutexUnlock(&allocMutex);
}
#endif

#else  /* !USE_TCLALLOC */

/*
 *----------------------------------------------------------------------
 *
 * TclpAlloc --
 *
 *	Allocate more memory.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpAlloc(nbytes)
    unsigned int nbytes;	/* Number of bytes to allocate. */
{
    return (char*) malloc(nbytes);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpFree --
 *
 *	Free memory.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TclpFree(cp)
    char *cp;		/* Pointer to memory to free. */
{   
    free(cp);
    return;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpRealloc --
 *
 *	Reallocate memory.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpRealloc(cp, nbytes)
    char *cp;			/* Pointer to alloced block. */
    unsigned int nbytes;	/* New size of memory. */
{   
    return (char*) realloc(cp, nbytes);
}

#endif /* !USE_TCLALLOC */

Changes to generic/tclAsync.c.

8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclAsync.c 1.6 96/02/15 11:46:15
 */

#include "tclInt.h"


/*
 * One of the following structures exists for each asynchronous
 * handler:
 */

typedef struct AsyncHandler {







|



>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994 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: tclAsync.c,v 1.1.2.6 1999/03/11 01:50:27 stanton Exp $
 */

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

/*
 * One of the following structures exists for each asynchronous
 * handler:
 */

typedef struct AsyncHandler {
37
38
39
40
41
42
43


44
45
46
47
48
49
50
/*
 * The variables below maintain a list of all existing handlers.
 */

static AsyncHandler *firstHandler;	/* First handler defined for process,
					 * or NULL if none. */
static AsyncHandler *lastHandler;	/* Last handler or NULL. */



/*
 * The variable below is set to 1 whenever a handler becomes ready and
 * it is cleared to zero whenever Tcl_AsyncInvoke is called.  It can be
 * checked elsewhere in the application by calling Tcl_AsyncReady to see
 * if Tcl_AsyncInvoke should be invoked.
 */







>
>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
 * The variables below maintain a list of all existing handlers.
 */

static AsyncHandler *firstHandler;	/* First handler defined for process,
					 * or NULL if none. */
static AsyncHandler *lastHandler;	/* Last handler or NULL. */

TCL_DECLARE_MUTEX(asyncMutex)           /* Process-wide async handler lock */

/*
 * The variable below is set to 1 whenever a handler becomes ready and
 * it is cleared to zero whenever Tcl_AsyncInvoke is called.  It can be
 * checked elsewhere in the application by calling Tcl_AsyncReady to see
 * if Tcl_AsyncInvoke should be invoked.
 */
87
88
89
90
91
92
93

94
95
96
97
98
99

100
101
102
103
104
105
106
    AsyncHandler *asyncPtr;

    asyncPtr = (AsyncHandler *) ckalloc(sizeof(AsyncHandler));
    asyncPtr->ready = 0;
    asyncPtr->nextPtr = NULL;
    asyncPtr->proc = proc;
    asyncPtr->clientData = clientData;

    if (firstHandler == NULL) {
	firstHandler = asyncPtr;
    } else {
	lastHandler->nextPtr = asyncPtr;
    }
    lastHandler = asyncPtr;

    return (Tcl_AsyncHandler) asyncPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AsyncMark --







>






>







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    AsyncHandler *asyncPtr;

    asyncPtr = (AsyncHandler *) ckalloc(sizeof(AsyncHandler));
    asyncPtr->ready = 0;
    asyncPtr->nextPtr = NULL;
    asyncPtr->proc = proc;
    asyncPtr->clientData = clientData;
    Tcl_MutexLock(&asyncMutex);
    if (firstHandler == NULL) {
	firstHandler = asyncPtr;
    } else {
	lastHandler->nextPtr = asyncPtr;
    }
    lastHandler = asyncPtr;
    Tcl_MutexUnlock(&asyncMutex);
    return (Tcl_AsyncHandler) asyncPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AsyncMark --
119
120
121
122
123
124
125

126
127
128

129

130
131
132
133
134
135
136
 *----------------------------------------------------------------------
 */

void
Tcl_AsyncMark(async)
    Tcl_AsyncHandler async;		/* Token for handler. */
{

    ((AsyncHandler *) async)->ready = 1;
    if (!asyncActive) {
	asyncReady = 1;

    }

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AsyncInvoke --
 *







>



>

>







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
 *----------------------------------------------------------------------
 */

void
Tcl_AsyncMark(async)
    Tcl_AsyncHandler async;		/* Token for handler. */
{
    Tcl_MutexLock(&asyncMutex);
    ((AsyncHandler *) async)->ready = 1;
    if (!asyncActive) {
	asyncReady = 1;
	TclpAsyncMark(async);
    }
    Tcl_MutexUnlock(&asyncMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AsyncInvoke --
 *
155
156
157
158
159
160
161

162
163

164
165
166
167
168
169
170
					 * interpreter.  Otherwise it is
					 * NULL. */
    int code; 				/* If interp is non-NULL, this gives
					 * completion code from command that
					 * just completed. */
{
    AsyncHandler *asyncPtr;


    if (asyncReady == 0) {

	return code;
    }
    asyncReady = 0;
    asyncActive = 1;
    if (interp == NULL) {
	code = 0;
    }







>


>







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
					 * interpreter.  Otherwise it is
					 * NULL. */
    int code; 				/* If interp is non-NULL, this gives
					 * completion code from command that
					 * just completed. */
{
    AsyncHandler *asyncPtr;
    Tcl_MutexLock(&asyncMutex);

    if (asyncReady == 0) {
	Tcl_MutexUnlock(&asyncMutex);
	return code;
    }
    asyncReady = 0;
    asyncActive = 1;
    if (interp == NULL) {
	code = 0;
    }
187
188
189
190
191
192
193

194

195
196

197
198
199
200
201
202
203
		break;
	    }
	}
	if (asyncPtr == NULL) {
	    break;
	}
	asyncPtr->ready = 0;

	code = (*asyncPtr->proc)(asyncPtr->clientData, interp, code);

    }
    asyncActive = 0;

    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AsyncDelete --







>

>


>







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
		break;
	    }
	}
	if (asyncPtr == NULL) {
	    break;
	}
	asyncPtr->ready = 0;
	Tcl_MutexUnlock(&asyncMutex);
	code = (*asyncPtr->proc)(asyncPtr->clientData, interp, code);
	Tcl_MutexLock(&asyncMutex);
    }
    asyncActive = 0;
    Tcl_MutexUnlock(&asyncMutex);
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AsyncDelete --
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
void
Tcl_AsyncDelete(async)
    Tcl_AsyncHandler async;		/* Token for handler to delete. */
{
    AsyncHandler *asyncPtr = (AsyncHandler *) async;
    AsyncHandler *prevPtr;


    if (firstHandler == asyncPtr) {
	firstHandler = asyncPtr->nextPtr;
	if (firstHandler == NULL) {
	    lastHandler = NULL;
	}
    } else {
	prevPtr = firstHandler;
	while (prevPtr->nextPtr != asyncPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = asyncPtr->nextPtr;
	if (lastHandler == asyncPtr) {
	    lastHandler = prevPtr;
	}
    }

    ckfree((char *) asyncPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AsyncReady --







>















>







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
void
Tcl_AsyncDelete(async)
    Tcl_AsyncHandler async;		/* Token for handler to delete. */
{
    AsyncHandler *asyncPtr = (AsyncHandler *) async;
    AsyncHandler *prevPtr;

    Tcl_MutexLock(&asyncMutex);
    if (firstHandler == asyncPtr) {
	firstHandler = asyncPtr->nextPtr;
	if (firstHandler == NULL) {
	    lastHandler = NULL;
	}
    } else {
	prevPtr = firstHandler;
	while (prevPtr->nextPtr != asyncPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = asyncPtr->nextPtr;
	if (lastHandler == asyncPtr) {
	    lastHandler = prevPtr;
	}
    }
    Tcl_MutexUnlock(&asyncMutex);
    ckfree((char *) asyncPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AsyncReady --

Changes to generic/tclBasic.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
/* 
 * tclBasic.c --
 *
 *	Contains the basic facilities for TCL command interpretation,
 *	including interpreter creation and deletion, command creation
 *	and deletion, and command parsing and execution.
 *
 * Copyright (c) 1987-1994 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclBasic.c 1.305 97/08/13 10:34:43
 */

#include "tclInt.h"
#include "tclCompile.h"
#ifndef TCL_GENERIC_ONLY
#   include "tclPort.h"
#endif

/*
 * Static procedures in this file:
 */

static void		DeleteInterpProc _ANSI_ARGS_((Tcl_Interp *interp));


static void		HiddenCmdsDeleteProc _ANSI_ARGS_((
			    ClientData clientData, Tcl_Interp *interp));




/*
 * The following structure defines the commands in the Tcl core.
 */

typedef struct {
    char *name;			/* Name of object-based command. */









>




|













>
>
|
|
>
>
>







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
/* 
 * tclBasic.c --
 *
 *	Contains the basic facilities for TCL command interpretation,
 *	including interpreter creation and deletion, command creation
 *	and deletion, and command parsing and execution.
 *
 * Copyright (c) 1987-1994 The Regents of the University of California.
 * Copyright (c) 1994-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: tclBasic.c,v 1.1.2.16 1999/04/14 00:33:20 surles Exp $
 */

#include "tclInt.h"
#include "tclCompile.h"
#ifndef TCL_GENERIC_ONLY
#   include "tclPort.h"
#endif

/*
 * Static procedures in this file:
 */

static void		DeleteInterpProc _ANSI_ARGS_((Tcl_Interp *interp));
static void		ProcessUnexpectedResult _ANSI_ARGS_((
			    Tcl_Interp *interp, int returnCode));
static void		RecordTracebackInfo _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Obj *objPtr,
			    int numSrcBytes));

extern TclStubs tclStubs;

/*
 * The following structure defines the commands in the Tcl core.
 */

typedef struct {
    char *name;			/* Name of object-based command. */
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

    {"append",		(Tcl_CmdProc *) NULL,	Tcl_AppendObjCmd,
        (CompileProc *) NULL,		1},
    {"array",		(Tcl_CmdProc *) NULL,	Tcl_ArrayObjCmd,
        (CompileProc *) NULL,		1},
    {"binary",		(Tcl_CmdProc *) NULL,	Tcl_BinaryObjCmd,
        (CompileProc *) NULL,		1},
    {"break",		Tcl_BreakCmd,		(Tcl_ObjCmdProc *) NULL,
        TclCompileBreakCmd,		1},
    {"case",		(Tcl_CmdProc *) NULL,	Tcl_CaseObjCmd,
        (CompileProc *) NULL,		1},
    {"catch",		(Tcl_CmdProc *) NULL,	Tcl_CatchObjCmd,	
        TclCompileCatchCmd,		1},
    {"clock",		(Tcl_CmdProc *) NULL,	Tcl_ClockObjCmd,
        (CompileProc *) NULL,		1},
    {"concat",		(Tcl_CmdProc *) NULL,	Tcl_ConcatObjCmd,
        (CompileProc *) NULL,		1},
    {"continue",	Tcl_ContinueCmd,	(Tcl_ObjCmdProc *) NULL,
        TclCompileContinueCmd,		1},


    {"error",		(Tcl_CmdProc *) NULL,	Tcl_ErrorObjCmd,
        (CompileProc *) NULL,		1},
    {"eval",		(Tcl_CmdProc *) NULL,	Tcl_EvalObjCmd,
        (CompileProc *) NULL,		1},
    {"exit",		(Tcl_CmdProc *) NULL,	Tcl_ExitObjCmd,
        (CompileProc *) NULL,		0},
    {"expr",		(Tcl_CmdProc *) NULL,	Tcl_ExprObjCmd,
        TclCompileExprCmd,		1},
    {"fcopy",		(Tcl_CmdProc *) NULL,	Tcl_FcopyObjCmd,
        (CompileProc *) NULL,		1},
    {"fileevent",	Tcl_FileEventCmd,	(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    {"for",		Tcl_ForCmd,		(Tcl_ObjCmdProc *) NULL,
        TclCompileForCmd,		1},
    {"foreach",		(Tcl_CmdProc *) NULL,	Tcl_ForeachObjCmd,
        TclCompileForeachCmd,		1},
    {"format",		(Tcl_CmdProc *) NULL,	Tcl_FormatObjCmd,
        (CompileProc *) NULL,		1},
    {"global",		(Tcl_CmdProc *) NULL,	Tcl_GlobalObjCmd,
        (CompileProc *) NULL,		1},
    {"if",		Tcl_IfCmd,		(Tcl_ObjCmdProc *) NULL,
        TclCompileIfCmd,		1},
    {"incr",		Tcl_IncrCmd,		(Tcl_ObjCmdProc *) NULL,
        TclCompileIncrCmd,		1},
    {"info",		(Tcl_CmdProc *) NULL,	Tcl_InfoObjCmd,
        (CompileProc *) NULL,		1},
    {"interp",		(Tcl_CmdProc *) NULL,	Tcl_InterpObjCmd,
        (CompileProc *) NULL,		1},
    {"join",		(Tcl_CmdProc *) NULL,	Tcl_JoinObjCmd,
        (CompileProc *) NULL,		1},
    {"lappend",		(Tcl_CmdProc *) NULL,	Tcl_LappendObjCmd,
        (CompileProc *) NULL,		1},
    {"lindex",		(Tcl_CmdProc *) NULL,	Tcl_LindexObjCmd,
        (CompileProc *) NULL,		1},
    {"linsert",		(Tcl_CmdProc *) NULL,	Tcl_LinsertObjCmd,
        (CompileProc *) NULL,		1},
    {"list",		(Tcl_CmdProc *) NULL,	Tcl_ListObjCmd,
        (CompileProc *) NULL,		1},
    {"llength",		(Tcl_CmdProc *) NULL,	Tcl_LlengthObjCmd,
        (CompileProc *) NULL,		1},
    {"load",		Tcl_LoadCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0},
    {"lrange",		(Tcl_CmdProc *) NULL,	Tcl_LrangeObjCmd,
        (CompileProc *) NULL,		1},
    {"lreplace",	(Tcl_CmdProc *) NULL,	Tcl_LreplaceObjCmd,
        (CompileProc *) NULL,		1},
    {"lsearch",		(Tcl_CmdProc *) NULL,	Tcl_LsearchObjCmd,
        (CompileProc *) NULL,		1},
    {"lsort",		(Tcl_CmdProc *) NULL,	Tcl_LsortObjCmd,
        (CompileProc *) NULL,		1},
    {"namespace",	(Tcl_CmdProc *) NULL,	Tcl_NamespaceObjCmd,
        (CompileProc *) NULL,		1},
    {"package",		Tcl_PackageCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    {"proc",		(Tcl_CmdProc *) NULL,	Tcl_ProcObjCmd,	
        (CompileProc *) NULL,		1},
    {"regexp",		Tcl_RegexpCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    {"regsub",		Tcl_RegsubCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    {"rename",		(Tcl_CmdProc *) NULL,	Tcl_RenameObjCmd,
        (CompileProc *) NULL,		1},
    {"return",		(Tcl_CmdProc *) NULL,	Tcl_ReturnObjCmd,	
        (CompileProc *) NULL,		1},
    {"scan",		Tcl_ScanCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    {"set",		Tcl_SetCmd,		(Tcl_ObjCmdProc *) NULL,    
        TclCompileSetCmd,		1},
    {"split",		(Tcl_CmdProc *) NULL,	Tcl_SplitObjCmd,
        (CompileProc *) NULL,		1},
    {"string",		(Tcl_CmdProc *) NULL,	Tcl_StringObjCmd,
        (CompileProc *) NULL,		1},
    {"subst",		Tcl_SubstCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    {"switch",		(Tcl_CmdProc *) NULL,	Tcl_SwitchObjCmd,	
        (CompileProc *) NULL,		1},
    {"trace",		Tcl_TraceCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    {"unset",		(Tcl_CmdProc *) NULL,	Tcl_UnsetObjCmd,	
        (CompileProc *) NULL,		1},
    {"uplevel",		(Tcl_CmdProc *) NULL,	Tcl_UplevelObjCmd,	
        (CompileProc *) NULL,		1},
    {"upvar",		(Tcl_CmdProc *) NULL,	Tcl_UpvarObjCmd,	
        (CompileProc *) NULL,		1},
    {"variable",	(Tcl_CmdProc *) NULL,	Tcl_VariableObjCmd,
        (CompileProc *) NULL,		1},
    {"while",		Tcl_WhileCmd,		(Tcl_ObjCmdProc *) NULL,    
        TclCompileWhileCmd,		1},

    /*
     * Commands in the UNIX core:
     */

#ifndef TCL_GENERIC_ONLY
    {"after",		(Tcl_CmdProc *) NULL,	Tcl_AfterObjCmd,
        (CompileProc *) NULL,		1},
    {"cd",		(Tcl_CmdProc *) NULL,	Tcl_CdObjCmd,
        (CompileProc *) NULL,		0},
    {"close",		(Tcl_CmdProc *) NULL,	Tcl_CloseObjCmd,
        (CompileProc *) NULL,		1},
    {"eof",		(Tcl_CmdProc *) NULL,	Tcl_EofObjCmd,
        (CompileProc *) NULL,		1},
    {"fblocked",	(Tcl_CmdProc *) NULL,	Tcl_FblockedObjCmd,
        (CompileProc *) NULL,		1},
    {"fconfigure",	Tcl_FconfigureCmd,	(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0},
    {"file",		(Tcl_CmdProc *) NULL,	Tcl_FileObjCmd,
        (CompileProc *) NULL,		0},
    {"flush",		(Tcl_CmdProc *) NULL,	Tcl_FlushObjCmd,
        (CompileProc *) NULL,		1},
    {"gets",		(Tcl_CmdProc *) NULL,	Tcl_GetsObjCmd,
        (CompileProc *) NULL,		1},
    {"glob",		Tcl_GlobCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0},
    {"open",		Tcl_OpenCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0},
    {"pid",		(Tcl_CmdProc *) NULL,	Tcl_PidObjCmd,
        (CompileProc *) NULL,		1},
    {"puts",		(Tcl_CmdProc *) NULL,	Tcl_PutsObjCmd,
        (CompileProc *) NULL,		1},
    {"pwd",		Tcl_PwdCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0},
    {"read",		(Tcl_CmdProc *) NULL,	Tcl_ReadObjCmd,
        (CompileProc *) NULL,		1},
    {"seek",		Tcl_SeekCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    {"socket",		Tcl_SocketCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0},
    {"tell",		Tcl_TellCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    {"time",		(Tcl_CmdProc *) NULL,	Tcl_TimeObjCmd,
        (CompileProc *) NULL,		1},
    {"update",		Tcl_UpdateCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    {"vwait",		Tcl_VwaitCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		1},
    
#ifdef MAC_TCL
    {"beep",		(Tcl_CmdProc *) NULL,	Tcl_BeepObjCmd,
        (CompileProc *) NULL,		0},
    {"echo",		Tcl_EchoCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0},
    {"ls",		Tcl_LsCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0},
    {"resource",	(Tcl_CmdProc *) NULL,	Tcl_ResourceObjCmd,
        (CompileProc *) NULL,		1},
    {"source",		(Tcl_CmdProc *) NULL,	Tcl_MacSourceObjCmd,
        (CompileProc *) NULL,		0},
#else
    {"exec",		Tcl_ExecCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0},
    {"source",		(Tcl_CmdProc *) NULL,	Tcl_SourceObjCmd,
        (CompileProc *) NULL,		0},
#endif /* MAC_TCL */
    
#endif /* TCL_GENERIC_ONLY */
    {NULL,		(Tcl_CmdProc *) NULL,	(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0}
};


/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateInterp --
 *
 *	Create a new TCL command interpreter.







|









|

>
>










|

|







|

|



<
<












|











|



|

|





|

|





|



|









|

















|







|

|





|



|

|

|



|

|







|






|









>







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

    {"append",		(Tcl_CmdProc *) NULL,	Tcl_AppendObjCmd,
        (CompileProc *) NULL,		1},
    {"array",		(Tcl_CmdProc *) NULL,	Tcl_ArrayObjCmd,
        (CompileProc *) NULL,		1},
    {"binary",		(Tcl_CmdProc *) NULL,	Tcl_BinaryObjCmd,
        (CompileProc *) NULL,		1},
    {"break",		(Tcl_CmdProc *) NULL,	Tcl_BreakObjCmd,
        TclCompileBreakCmd,		1},
    {"case",		(Tcl_CmdProc *) NULL,	Tcl_CaseObjCmd,
        (CompileProc *) NULL,		1},
    {"catch",		(Tcl_CmdProc *) NULL,	Tcl_CatchObjCmd,	
        TclCompileCatchCmd,		1},
    {"clock",		(Tcl_CmdProc *) NULL,	Tcl_ClockObjCmd,
        (CompileProc *) NULL,		1},
    {"concat",		(Tcl_CmdProc *) NULL,	Tcl_ConcatObjCmd,
        (CompileProc *) NULL,		1},
    {"continue",	(Tcl_CmdProc *) NULL,	Tcl_ContinueObjCmd,
        TclCompileContinueCmd,		1},
    {"encoding",	(Tcl_CmdProc *) NULL,	Tcl_EncodingObjCmd,
        (CompileProc *) NULL,		0},
    {"error",		(Tcl_CmdProc *) NULL,	Tcl_ErrorObjCmd,
        (CompileProc *) NULL,		1},
    {"eval",		(Tcl_CmdProc *) NULL,	Tcl_EvalObjCmd,
        (CompileProc *) NULL,		1},
    {"exit",		(Tcl_CmdProc *) NULL,	Tcl_ExitObjCmd,
        (CompileProc *) NULL,		0},
    {"expr",		(Tcl_CmdProc *) NULL,	Tcl_ExprObjCmd,
        TclCompileExprCmd,		1},
    {"fcopy",		(Tcl_CmdProc *) NULL,	Tcl_FcopyObjCmd,
        (CompileProc *) NULL,		1},
    {"fileevent",	(Tcl_CmdProc *) NULL,	Tcl_FileEventObjCmd,
        (CompileProc *) NULL,		1},
    {"for",		(Tcl_CmdProc *) NULL,	Tcl_ForObjCmd,
        TclCompileForCmd,		1},
    {"foreach",		(Tcl_CmdProc *) NULL,	Tcl_ForeachObjCmd,
        TclCompileForeachCmd,		1},
    {"format",		(Tcl_CmdProc *) NULL,	Tcl_FormatObjCmd,
        (CompileProc *) NULL,		1},
    {"global",		(Tcl_CmdProc *) NULL,	Tcl_GlobalObjCmd,
        (CompileProc *) NULL,		1},
    {"if",		(Tcl_CmdProc *) NULL,	Tcl_IfObjCmd,
        TclCompileIfCmd,		1},
    {"incr",		(Tcl_CmdProc *) NULL,	Tcl_IncrObjCmd,
        TclCompileIncrCmd,		1},
    {"info",		(Tcl_CmdProc *) NULL,	Tcl_InfoObjCmd,
        (CompileProc *) NULL,		1},


    {"join",		(Tcl_CmdProc *) NULL,	Tcl_JoinObjCmd,
        (CompileProc *) NULL,		1},
    {"lappend",		(Tcl_CmdProc *) NULL,	Tcl_LappendObjCmd,
        (CompileProc *) NULL,		1},
    {"lindex",		(Tcl_CmdProc *) NULL,	Tcl_LindexObjCmd,
        (CompileProc *) NULL,		1},
    {"linsert",		(Tcl_CmdProc *) NULL,	Tcl_LinsertObjCmd,
        (CompileProc *) NULL,		1},
    {"list",		(Tcl_CmdProc *) NULL,	Tcl_ListObjCmd,
        (CompileProc *) NULL,		1},
    {"llength",		(Tcl_CmdProc *) NULL,	Tcl_LlengthObjCmd,
        (CompileProc *) NULL,		1},
    {"load",		(Tcl_CmdProc *) NULL,	Tcl_LoadObjCmd,
        (CompileProc *) NULL,		0},
    {"lrange",		(Tcl_CmdProc *) NULL,	Tcl_LrangeObjCmd,
        (CompileProc *) NULL,		1},
    {"lreplace",	(Tcl_CmdProc *) NULL,	Tcl_LreplaceObjCmd,
        (CompileProc *) NULL,		1},
    {"lsearch",		(Tcl_CmdProc *) NULL,	Tcl_LsearchObjCmd,
        (CompileProc *) NULL,		1},
    {"lsort",		(Tcl_CmdProc *) NULL,	Tcl_LsortObjCmd,
        (CompileProc *) NULL,		1},
    {"namespace",	(Tcl_CmdProc *) NULL,	Tcl_NamespaceObjCmd,
        (CompileProc *) NULL,		1},
    {"package",		(Tcl_CmdProc *) NULL,	Tcl_PackageObjCmd,
        (CompileProc *) NULL,		1},
    {"proc",		(Tcl_CmdProc *) NULL,	Tcl_ProcObjCmd,	
        (CompileProc *) NULL,		1},
    {"regexp",		(Tcl_CmdProc *) NULL,	Tcl_RegexpObjCmd,
        (CompileProc *) NULL,		1},
    {"regsub",		(Tcl_CmdProc *) NULL,	Tcl_RegsubObjCmd,
        (CompileProc *) NULL,		1},
    {"rename",		(Tcl_CmdProc *) NULL,	Tcl_RenameObjCmd,
        (CompileProc *) NULL,		1},
    {"return",		(Tcl_CmdProc *) NULL,	Tcl_ReturnObjCmd,	
        (CompileProc *) NULL,		1},
    {"scan",		(Tcl_CmdProc *) NULL,	Tcl_ScanObjCmd,
        (CompileProc *) NULL,		1},
    {"set",		(Tcl_CmdProc *) NULL,	Tcl_SetObjCmd,
        TclCompileSetCmd,		1},
    {"split",		(Tcl_CmdProc *) NULL,	Tcl_SplitObjCmd,
        (CompileProc *) NULL,		1},
    {"string",		(Tcl_CmdProc *) NULL,	Tcl_StringObjCmd,
        (CompileProc *) NULL,		1},
    {"subst",		(Tcl_CmdProc *) NULL,	Tcl_SubstObjCmd,
        (CompileProc *) NULL,		1},
    {"switch",		(Tcl_CmdProc *) NULL,	Tcl_SwitchObjCmd,	
        (CompileProc *) NULL,		1},
    {"trace",		(Tcl_CmdProc *) NULL,	Tcl_TraceObjCmd,
        (CompileProc *) NULL,		1},
    {"unset",		(Tcl_CmdProc *) NULL,	Tcl_UnsetObjCmd,	
        (CompileProc *) NULL,		1},
    {"uplevel",		(Tcl_CmdProc *) NULL,	Tcl_UplevelObjCmd,	
        (CompileProc *) NULL,		1},
    {"upvar",		(Tcl_CmdProc *) NULL,	Tcl_UpvarObjCmd,	
        (CompileProc *) NULL,		1},
    {"variable",	(Tcl_CmdProc *) NULL,	Tcl_VariableObjCmd,
        (CompileProc *) NULL,		1},
    {"while",		(Tcl_CmdProc *) NULL,	Tcl_WhileObjCmd,
        TclCompileWhileCmd,		1},

    /*
     * Commands in the UNIX core:
     */

#ifndef TCL_GENERIC_ONLY
    {"after",		(Tcl_CmdProc *) NULL,	Tcl_AfterObjCmd,
        (CompileProc *) NULL,		1},
    {"cd",		(Tcl_CmdProc *) NULL,	Tcl_CdObjCmd,
        (CompileProc *) NULL,		0},
    {"close",		(Tcl_CmdProc *) NULL,	Tcl_CloseObjCmd,
        (CompileProc *) NULL,		1},
    {"eof",		(Tcl_CmdProc *) NULL,	Tcl_EofObjCmd,
        (CompileProc *) NULL,		1},
    {"fblocked",	(Tcl_CmdProc *) NULL,	Tcl_FblockedObjCmd,
        (CompileProc *) NULL,		1},
    {"fconfigure",	(Tcl_CmdProc *) NULL,	Tcl_FconfigureObjCmd,
        (CompileProc *) NULL,		0},
    {"file",		(Tcl_CmdProc *) NULL,	Tcl_FileObjCmd,
        (CompileProc *) NULL,		0},
    {"flush",		(Tcl_CmdProc *) NULL,	Tcl_FlushObjCmd,
        (CompileProc *) NULL,		1},
    {"gets",		(Tcl_CmdProc *) NULL,	Tcl_GetsObjCmd,
        (CompileProc *) NULL,		1},
    {"glob",		(Tcl_CmdProc *) NULL,	Tcl_GlobObjCmd,
        (CompileProc *) NULL,		0},
    {"open",		(Tcl_CmdProc *) NULL,	Tcl_OpenObjCmd,
        (CompileProc *) NULL,		0},
    {"pid",		(Tcl_CmdProc *) NULL,	Tcl_PidObjCmd,
        (CompileProc *) NULL,		1},
    {"puts",		(Tcl_CmdProc *) NULL,	Tcl_PutsObjCmd,
        (CompileProc *) NULL,		1},
    {"pwd",		(Tcl_CmdProc *) NULL,	Tcl_PwdObjCmd,
        (CompileProc *) NULL,		0},
    {"read",		(Tcl_CmdProc *) NULL,	Tcl_ReadObjCmd,
        (CompileProc *) NULL,		1},
    {"seek",		(Tcl_CmdProc *) NULL,	Tcl_SeekObjCmd,
        (CompileProc *) NULL,		1},
    {"socket",		(Tcl_CmdProc *) NULL,	Tcl_SocketObjCmd,
        (CompileProc *) NULL,		0},
    {"tell",		(Tcl_CmdProc *) NULL,	Tcl_TellObjCmd,
        (CompileProc *) NULL,		1},
    {"time",		(Tcl_CmdProc *) NULL,	Tcl_TimeObjCmd,
        (CompileProc *) NULL,		1},
    {"update",		(Tcl_CmdProc *) NULL,	Tcl_UpdateObjCmd,
        (CompileProc *) NULL,		1},
    {"vwait",		(Tcl_CmdProc *) NULL,	Tcl_VwaitObjCmd,
        (CompileProc *) NULL,		1},
    
#ifdef MAC_TCL
    {"beep",		(Tcl_CmdProc *) NULL,	Tcl_BeepObjCmd,
        (CompileProc *) NULL,		0},
    {"echo",		Tcl_EchoCmd,		(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0},
    {"ls",		(Tcl_CmdProc *) NULL, 	Tcl_LsObjCmd,
        (CompileProc *) NULL,		0},
    {"resource",	(Tcl_CmdProc *) NULL,	Tcl_ResourceObjCmd,
        (CompileProc *) NULL,		1},
    {"source",		(Tcl_CmdProc *) NULL,	Tcl_MacSourceObjCmd,
        (CompileProc *) NULL,		0},
#else
    {"exec",		(Tcl_CmdProc *) NULL,	Tcl_ExecObjCmd,
        (CompileProc *) NULL,		0},
    {"source",		(Tcl_CmdProc *) NULL,	Tcl_SourceObjCmd,
        (CompileProc *) NULL,		0},
#endif /* MAC_TCL */
    
#endif /* TCL_GENERIC_ONLY */
    {NULL,		(Tcl_CmdProc *) NULL,	(Tcl_ObjCmdProc *) NULL,
        (CompileProc *) NULL,		0}
};


/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateInterp --
 *
 *	Create a new TCL command interpreter.
251
252
253
254
255
256
257
258

259



260

261
262
263
264



265

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287

288
289



290
291

292
293
294
295
296
297
298
299

300
301
302

303
304
305
306
307
308
309
310
311

312
313

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

336
337
338
339











































340
341
342
343
344
345
346
 *
 *----------------------------------------------------------------------
 */

Tcl_Interp *
Tcl_CreateInterp()
{
    register Interp *iPtr;

    register Command *cmdPtr;



    register CmdInfo *cmdInfoPtr;

    union {
	char c[sizeof(short)];
	short s;
    } order;



    int i;


    /*
     * Panic if someone updated the CallFrame structure without
     * also updating the Tcl_CallFrame structure (or vice versa).
     */  

    if (sizeof(Tcl_CallFrame) != sizeof(CallFrame)) {
	/*NOTREACHED*/
        panic("Tcl_CallFrame and CallFrame are not the same size");
    }

    /*
     * Initialize support for namespaces and create the global namespace
     * (whose name is ""; an alias is "::"). This also initializes the
     * Tcl object type table and other object management code.
     */


    TclInitNamespaces();
    
    iPtr = (Interp *) ckalloc(sizeof(Interp));
    iPtr->result = iPtr->resultSpace;
    iPtr->freeProc = 0;

    iPtr->objResultPtr = Tcl_NewObj(); /* an empty object */
    Tcl_IncrRefCount(iPtr->objResultPtr);



    iPtr->errorLine = 0;
    Tcl_InitHashTable(&iPtr->mathFuncTable, TCL_STRING_KEYS);

    iPtr->numLevels = 0;
    iPtr->maxNestingDepth = 1000;
    iPtr->framePtr = NULL;
    iPtr->varFramePtr = NULL;
    iPtr->activeTracePtr = NULL;
    iPtr->returnCode = TCL_OK;
    iPtr->errorInfo = NULL;
    iPtr->errorCode = NULL;

    iPtr->appendResult = NULL;
    iPtr->appendAvl = 0;
    iPtr->appendUsed = 0;

    for (i = 0; i < NUM_REGEXPS; i++) {
	iPtr->patterns[i] = NULL;
	iPtr->patLengths[i] = -1;
	iPtr->regexps[i] = NULL;
    }
    Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
    iPtr->packageUnknown = NULL;
    iPtr->cmdCount = 0;
    iPtr->termOffset = 0;

    iPtr->compileEpoch = 0;
    iPtr->compiledProcPtr = NULL;

    iPtr->evalFlags = 0;
    iPtr->scriptFile = NULL;
    iPtr->flags = 0;
    iPtr->tracePtr = NULL;
    iPtr->assocData = (Tcl_HashTable *) NULL;
    iPtr->execEnvPtr = NULL;	      /* set after namespaces initialized */
    iPtr->emptyObjPtr = Tcl_NewObj(); /* another empty object */
    Tcl_IncrRefCount(iPtr->emptyObjPtr);
    iPtr->resultSpace[0] = 0;

    iPtr->globalNsPtr = NULL;	/* force creation of global ns below */
    iPtr->globalNsPtr = (Namespace *) Tcl_CreateNamespace(
	    (Tcl_Interp *) iPtr, "", (ClientData) NULL,
	    (Tcl_NamespaceDeleteProc *) NULL);
    if (iPtr->globalNsPtr == NULL) {
        panic("Tcl_CreateInterp: can't create global namespace");
    }

    /*
     * Initialize support for code compilation. Do this after initializing
     * namespaces since TclCreateExecEnv will try to reference a Tcl
     * variable (it links to the Tcl "tcl_traceExec" variable).

     */
    
    iPtr->execEnvPtr = TclCreateExecEnv((Tcl_Interp *) iPtr);












































    /*
     * Create the core commands. Do it here, rather than calling
     * Tcl_CreateCommand, because it's faster (there's no need to check for
     * a pre-existing command by the same name). If a command has a
     * Tcl_CmdProc but no Tcl_ObjCmdProc, set the Tcl_ObjCmdProc to
     * TclInvokeStringCommand. This is an object-based wrapper procedure
     * that extracts strings, calls the string procedure, and creates an







|
>
|
>
>
>
|
>




>
>
>
|
>

















>
|
|
<
|
|
>
|

>
>
>
|

>








>



>









>


>











|
<
|





|
|
|
>

|
|

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







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301

302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
 *
 *----------------------------------------------------------------------
 */

Tcl_Interp *
Tcl_CreateInterp()
{
    Interp *iPtr;
    Tcl_Interp *interp;
    Command *cmdPtr;
    BuiltinFunc *builtinFuncPtr;
    MathFunc *mathFuncPtr;
    Tcl_HashEntry *hPtr;
    CmdInfo *cmdInfoPtr;
    int i;
    union {
	char c[sizeof(short)];
	short s;
    } order;
#ifdef TCL_COMPILE_STATS
    ByteCodeStats *statsPtr;
#endif /* TCL_COMPILE_STATS */

    TclInitSubsystems(NULL);

    /*
     * Panic if someone updated the CallFrame structure without
     * also updating the Tcl_CallFrame structure (or vice versa).
     */  

    if (sizeof(Tcl_CallFrame) != sizeof(CallFrame)) {
	/*NOTREACHED*/
        panic("Tcl_CallFrame and CallFrame are not the same size");
    }

    /*
     * Initialize support for namespaces and create the global namespace
     * (whose name is ""; an alias is "::"). This also initializes the
     * Tcl object type table and other object management code.
     */

    iPtr = (Interp *) ckalloc(sizeof(Interp));
    interp = (Tcl_Interp *) iPtr;


    iPtr->result		= iPtr->resultSpace;
    iPtr->freeProc		= NULL;
    iPtr->errorLine		= 0;
    iPtr->objResultPtr		= Tcl_NewObj();
    Tcl_IncrRefCount(iPtr->objResultPtr);
    iPtr->handle		= TclHandleCreate(iPtr);
    iPtr->globalNsPtr		= NULL;
    iPtr->hiddenCmdTablePtr	= NULL;
    iPtr->interpInfo		= NULL;
    Tcl_InitHashTable(&iPtr->mathFuncTable, TCL_STRING_KEYS);

    iPtr->numLevels = 0;
    iPtr->maxNestingDepth = 1000;
    iPtr->framePtr = NULL;
    iPtr->varFramePtr = NULL;
    iPtr->activeTracePtr = NULL;
    iPtr->returnCode = TCL_OK;
    iPtr->errorInfo = NULL;
    iPtr->errorCode = NULL;

    iPtr->appendResult = NULL;
    iPtr->appendAvl = 0;
    iPtr->appendUsed = 0;

    for (i = 0; i < NUM_REGEXPS; i++) {
	iPtr->patterns[i] = NULL;
	iPtr->patLengths[i] = -1;
	iPtr->regexps[i] = NULL;
    }
    Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
    iPtr->packageUnknown = NULL;
    iPtr->cmdCount = 0;
    iPtr->termOffset = 0;
    TclInitLiteralTable(&(iPtr->literalTable));
    iPtr->compileEpoch = 0;
    iPtr->compiledProcPtr = NULL;
    iPtr->resolverPtr = NULL;
    iPtr->evalFlags = 0;
    iPtr->scriptFile = NULL;
    iPtr->flags = 0;
    iPtr->tracePtr = NULL;
    iPtr->assocData = (Tcl_HashTable *) NULL;
    iPtr->execEnvPtr = NULL;	      /* set after namespaces initialized */
    iPtr->emptyObjPtr = Tcl_NewObj(); /* another empty object */
    Tcl_IncrRefCount(iPtr->emptyObjPtr);
    iPtr->resultSpace[0] = 0;

    iPtr->globalNsPtr = NULL;	/* force creation of global ns below */
    iPtr->globalNsPtr = (Namespace *) Tcl_CreateNamespace(interp, "",

	    (ClientData) NULL, (Tcl_NamespaceDeleteProc *) NULL);
    if (iPtr->globalNsPtr == NULL) {
        panic("Tcl_CreateInterp: can't create global namespace");
    }

    /*
     * Initialize support for code compilation and execution. We call
     * TclCreateExecEnv after initializing namespaces since it tries to
     * reference a Tcl variable (it links to the Tcl "tcl_traceExec"
     * variable).
     */

    iPtr->execEnvPtr = TclCreateExecEnv(interp);

    /*
     * Initialize the compilation and execution statistics kept for this
     * interpreter.
     */

#ifdef TCL_COMPILE_STATS
    statsPtr = &(iPtr->stats);
    statsPtr->numExecutions = 0;
    statsPtr->numCompilations = 0;
    statsPtr->numByteCodesFreed = 0;
    (VOID *) memset(statsPtr->instructionCount, 0,
	    sizeof(statsPtr->instructionCount));

    statsPtr->totalSrcBytes = 0.0;
    statsPtr->totalByteCodeBytes = 0.0;
    statsPtr->currentSrcBytes = 0.0;
    statsPtr->currentByteCodeBytes = 0.0;
    (VOID *) memset(statsPtr->srcCount, 0, sizeof(statsPtr->srcCount));
    (VOID *) memset(statsPtr->byteCodeCount, 0,
	    sizeof(statsPtr->byteCodeCount));
    (VOID *) memset(statsPtr->lifetimeCount, 0,
	    sizeof(statsPtr->lifetimeCount));
    
    statsPtr->currentInstBytes   = 0.0;
    statsPtr->currentLitBytes    = 0.0;
    statsPtr->currentExceptBytes = 0.0;
    statsPtr->currentAuxBytes    = 0.0;
    statsPtr->currentCmdMapBytes = 0.0;
    
    statsPtr->numLiteralsCreated    = 0;
    statsPtr->totalLitStringBytes   = 0.0;
    statsPtr->currentLitStringBytes = 0.0;
    (VOID *) memset(statsPtr->literalCount, 0,
            sizeof(statsPtr->literalCount));
#endif /* TCL_COMPILE_STATS */    

    /*
     * Initialise the stub table pointer.
     */

    iPtr->stubTable = &tclStubs;

    
    /*
     * Create the core commands. Do it here, rather than calling
     * Tcl_CreateCommand, because it's faster (there's no need to check for
     * a pre-existing command by the same name). If a command has a
     * Tcl_CmdProc but no Tcl_ObjCmdProc, set the Tcl_ObjCmdProc to
     * TclInvokeStringCommand. This is an object-based wrapper procedure
     * that extracts strings, calls the string procedure, and creates an
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
	    cmdPtr->deleted = 0;
	    cmdPtr->importRefPtr = NULL;
	    Tcl_SetHashValue(hPtr, cmdPtr);
	}
    }

    /*
     *  Initialize/Create "errorInfo" and "errorCode" global vars
     *  (because some part of the C code assume they exists
     *   and we can get a seg fault otherwise (in multiple 
     *   interps loading of extensions for instance) --dl)
     */
     /*
      *  We can't assume that because we initialize 
      *  the variables here, they won't be unset later.
      *  so we had 2 choices:
      *    + Check every place where a GetVar of those is used 
      *      and the NULL result is not checked (like in tclLoad.c)
      *    + Make SetVar,... NULL friendly
      *  We choosed the second option because :
      *    + It is easy and low cost to check for NULL pointer before


      *      calling strlen()
      *    + It can be helpfull to other people using those API
      *    + Passing a NULL value to those closest 'meaning' is empty string
      *      (specially with the new objects where 0 bytes strings are ok)
      * So the following init is commented out:              -- dl
      */
    /*
      (void)Tcl_SetVar2((Tcl_Interp *)iPtr, "errorInfo", (char *) NULL, "",
         TCL_GLOBAL_ONLY);

      (void)Tcl_SetVar2((Tcl_Interp *)iPtr, "errorCode", (char *) NULL, "NONE",

	    TCL_GLOBAL_ONLY);
     */




#ifndef TCL_GENERIC_ONLY
    TclSetupEnv((Tcl_Interp *) iPtr);

#endif



    /*
     * Do Multiple/Safe Interps Tcl init stuff
     */

    (void) TclInterpInit((Tcl_Interp *)iPtr);

    /*
     * Set up variables such as tcl_version.


     */













    TclPlatformInit((Tcl_Interp *)iPtr);
    Tcl_SetVar((Tcl_Interp *) iPtr, "tcl_patchLevel", TCL_PATCH_LEVEL,
	    TCL_GLOBAL_ONLY);
    Tcl_SetVar((Tcl_Interp *) iPtr, "tcl_version", TCL_VERSION,
	    TCL_GLOBAL_ONLY);

    Tcl_TraceVar2((Tcl_Interp *) iPtr, "tcl_precision", (char *) NULL,
	    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    TclPrecTraceProc, (ClientData) NULL);


    /*
     * Compute the byte order of this machine.
     */

    order.s = 1;
    Tcl_SetVar2((Tcl_Interp *) iPtr, "tcl_platform", "byteOrder",
	    (order.c[0] == 1) ? "littleEndian" : "bigEndian",
	    TCL_GLOBAL_ONLY);












    /*
     * Register Tcl's version number.
     */


    Tcl_PkgProvide((Tcl_Interp *) iPtr, "Tcl", TCL_VERSION);




    
    return (Tcl_Interp *) iPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TclHideUnsafeCommands --
 *







|
<
<
<

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



>
|


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






|
|


>
>
>
>
>
>
>
>
>
>
>




>
|
>
>
>
>
|
|







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
	    cmdPtr->deleted = 0;
	    cmdPtr->importRefPtr = NULL;
	    Tcl_SetHashValue(hPtr, cmdPtr);
	}
    }

    /*
     * Register the builtin math functions.



     */









    i = 0;
    for (builtinFuncPtr = builtinFuncTable;  builtinFuncPtr->name != NULL;
	    builtinFuncPtr++) {






	Tcl_CreateMathFunc((Tcl_Interp *) iPtr, builtinFuncPtr->name,

		builtinFuncPtr->numArgs, builtinFuncPtr->argTypes,
		(Tcl_MathProc *) NULL, (ClientData) 0);
	hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable,
		builtinFuncPtr->name);

	if (hPtr == NULL) {
	    panic("Tcl_CreateInterp: Tcl_CreateMathFunc incorrectly registered '%s'", builtinFuncPtr->name);
	    return NULL;
	}

	mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);
	mathFuncPtr->builtinFuncIndex = i;
	i++;
    }
    iPtr->flags |= EXPR_INITIALIZED;

    /*
     * Do Multiple/Safe Interps Tcl init stuff
     */

    TclInterpInit(interp);

    /*
     * We used to create the "errorInfo" and "errorCode" global vars at this
     * point because so much of the Tcl implementation assumes they already
     * exist. This is not quite enough, however, since they can be unset
     * at any time.
     *
     * There are 2 choices:
     *    + Check every place where a GetVar of those is used 
     *      and the NULL result is not checked (like in tclLoad.c)
     *    + Make SetVar,... NULL friendly
     * We choose the second option because :
     *    + It is easy and low cost to check for NULL pointer before
     *      calling strlen()
     *    + It can be helpfull to other people using those API
     *    + Passing a NULL value to those closest 'meaning' is empty string
     *      (specially with the new objects where 0 bytes strings are ok)
     * So the following init is commented out:              -- dl
     *
     * (void) Tcl_SetVar2((Tcl_Interp *)iPtr, "errorInfo", (char *) NULL,

     *       "", TCL_GLOBAL_ONLY);
     * (void) Tcl_SetVar2((Tcl_Interp *)iPtr, "errorCode", (char *) NULL,
     *       "NONE", TCL_GLOBAL_ONLY);
     */

#ifndef TCL_GENERIC_ONLY
    TclSetupEnv(interp);
#endif

    /*
     * Compute the byte order of this machine.
     */

    order.s = 1;
    Tcl_SetVar2(interp, "tcl_platform", "byteOrder",
	    ((order.c[0] == 1) ? "littleEndian" : "bigEndian"),
	    TCL_GLOBAL_ONLY);

    /*
     * Set up other variables such as tcl_version and tcl_library
     */

    Tcl_SetVar(interp, "tcl_patchLevel", TCL_PATCH_LEVEL, TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp, "tcl_version", TCL_VERSION, TCL_GLOBAL_ONLY);
    Tcl_TraceVar2(interp, "tcl_precision", (char *) NULL,
	    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    TclPrecTraceProc, (ClientData) NULL);
    TclpSetVariables(interp);

    /*
     * Register Tcl's version number.
     */

    Tcl_PkgProvideEx(interp, "Tcl", TCL_VERSION, (ClientData) &tclStubs);
    
#ifdef Tcl_InitStubs
#undef Tcl_InitStubs
#endif
    Tcl_InitStubs(interp, TCL_VERSION, 1);

    return interp;
}

/*
 *----------------------------------------------------------------------
 *
 * TclHideUnsafeCommands --
 *
520
521
522
523
524
525
526



527
528
529
530
531

532
533

534
535
536
537
538
539
540
    Tcl_Interp *interp;		/* Interpreter to watch. */
    Tcl_InterpDeleteProc *proc;	/* Procedure to call when interpreter
				 * is about to be deleted. */
    ClientData clientData;	/* One-word value to pass to proc. */
{
    Interp *iPtr = (Interp *) interp;
    static int assocDataCounter = 0;



    int new;
    char buffer[128];
    AssocData *dPtr = (AssocData *) ckalloc(sizeof(AssocData));
    Tcl_HashEntry *hPtr;


    sprintf(buffer, "Assoc Data Key #%d", assocDataCounter);
    assocDataCounter++;


    if (iPtr->assocData == (Tcl_HashTable *) NULL) {
        iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
        Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
    }
    hPtr = Tcl_CreateHashEntry(iPtr->assocData, buffer, &new);
    dPtr->proc = proc;







>
>
>

|



>


>







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
    Tcl_Interp *interp;		/* Interpreter to watch. */
    Tcl_InterpDeleteProc *proc;	/* Procedure to call when interpreter
				 * is about to be deleted. */
    ClientData clientData;	/* One-word value to pass to proc. */
{
    Interp *iPtr = (Interp *) interp;
    static int assocDataCounter = 0;
#ifdef TCL_THREADS
    static Tcl_Mutex assocMutex;
#endif
    int new;
    char buffer[32 + TCL_INTEGER_SPACE];
    AssocData *dPtr = (AssocData *) ckalloc(sizeof(AssocData));
    Tcl_HashEntry *hPtr;

    Tcl_MutexLock(&assocMutex);
    sprintf(buffer, "Assoc Data Key #%d", assocDataCounter);
    assocDataCounter++;
    Tcl_MutexUnlock(&assocMutex);

    if (iPtr->assocData == (Tcl_HashTable *) NULL) {
        iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
        Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
    }
    hPtr = Tcl_CreateHashEntry(iPtr->assocData, buffer, &new);
    dPtr->proc = proc;
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
    }
    return dPtr->clientData;
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteInterpProc --
 *
 *	Helper procedure to delete an interpreter. This procedure is
 *	called when the last call to Tcl_Preserve on this interpreter
 *	is matched by a call to Tcl_Release. The procedure cleans up
 *	all resources used in the interpreter and calls all currently
 *	registered interpreter deletion callbacks.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Whatever the interpreter deletion callbacks do. Frees resources
 *	used by the interpreter.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteInterpProc(interp)
    Tcl_Interp *interp;			/* Interpreter to delete. */
{
    Interp *iPtr = (Interp *) interp;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Tcl_HashTable *hTablePtr;
    AssocData *dPtr;
    int i;

    /*
     * Punt if there is an error in the Tcl_Release/Tcl_Preserve matchup.
     */
    
    if (iPtr->numLevels > 0) {
        panic("DeleteInterpProc called with active evals");
    }

    /*
     * The interpreter should already be marked deleted; otherwise how
     * did we get here?
     */

    if (!(iPtr->flags & DELETED)) {
        panic("DeleteInterpProc called on interpreter not marked deleted");
    }

    /*
     * Dismantle everything in the global namespace except for the
     * "errorInfo" and "errorCode" variables. These remain until the
     * namespace is actually destroyed, in case any errors occur.
     *   
     * Dismantle the namespace here, before we clear the assocData. If any
     * background errors occur here, they will be deleted below.
     */
    
    TclTeardownNamespace(iPtr->globalNsPtr);

    /*
     * Tear down the math function table.
     */

    for (hPtr = Tcl_FirstHashEntry(&iPtr->mathFuncTable, &search);
	     hPtr != NULL;
             hPtr = Tcl_NextHashEntry(&search)) {
	ckfree((char *) Tcl_GetHashValue(hPtr));
    }
    Tcl_DeleteHashTable(&iPtr->mathFuncTable);

    /*
     * Invoke deletion callbacks; note that a callback can create new
     * callbacks, so we iterate.
     */

    while (iPtr->assocData != (Tcl_HashTable *) NULL) {
        hTablePtr = iPtr->assocData;
        iPtr->assocData = (Tcl_HashTable *) NULL;
        for (hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
                 hPtr != NULL;
                 hPtr = Tcl_FirstHashEntry(hTablePtr, &search)) {
            dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
            Tcl_DeleteHashEntry(hPtr);
            if (dPtr->proc != NULL) {
                (*dPtr->proc)(dPtr->clientData, interp);
            }
            ckfree((char *) dPtr);
        }
        Tcl_DeleteHashTable(hTablePtr);
        ckfree((char *) hTablePtr);
    }

    /*
     * Finish deleting the global namespace.
     */
    
    Tcl_DeleteNamespace((Tcl_Namespace *) iPtr->globalNsPtr);

    /*
     * Free up the result *after* deleting variables, since variable
     * deletion could have transferred ownership of the result string
     * to Tcl.
     */

    Tcl_FreeResult(interp);
    interp->result = NULL;
    Tcl_DecrRefCount(iPtr->objResultPtr);
    iPtr->objResultPtr = NULL;
    if (iPtr->errorInfo != NULL) {
	ckfree(iPtr->errorInfo);
        iPtr->errorInfo = NULL;
    }
    if (iPtr->errorCode != NULL) {
	ckfree(iPtr->errorCode);
        iPtr->errorCode = NULL;
    }
    if (iPtr->appendResult != NULL) {
	ckfree(iPtr->appendResult);
        iPtr->appendResult = NULL;
    }
    for (i = 0; i < NUM_REGEXPS; i++) {
	if (iPtr->patterns[i] == NULL) {
	    break;
	}
	ckfree(iPtr->patterns[i]);
	ckfree((char *) iPtr->regexps[i]);
        iPtr->regexps[i] = NULL;
    }
    TclFreePackageInfo(iPtr);
    while (iPtr->tracePtr != NULL) {
	Trace *nextPtr = iPtr->tracePtr->nextPtr;

	ckfree((char *) iPtr->tracePtr);
	iPtr->tracePtr = nextPtr;
    }
    if (iPtr->execEnvPtr != NULL) {
	TclDeleteExecEnv(iPtr->execEnvPtr);
    }
    Tcl_DecrRefCount(iPtr->emptyObjPtr);
    iPtr->emptyObjPtr = NULL;
    
    ckfree((char *) iPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_InterpDeleted --
 *
 *	Returns nonzero if the interpreter has been deleted with a call
 *	to Tcl_DeleteInterp.
 *
 * Results:
 *	Nonzero if the interpreter is deleted, zero otherwise.







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







816
817
818
819
820
821
822

















































































































































823
824
825
826
827
828
829
    }
    return dPtr->clientData;
}

/*
 *----------------------------------------------------------------------
 *

















































































































































 * Tcl_InterpDeleted --
 *
 *	Returns nonzero if the interpreter has been deleted with a call
 *	to Tcl_DeleteInterp.
 *
 * Results:
 *	Nonzero if the interpreter is deleted, zero otherwise.
942
943
944
945
946
947
948
949
950
951



952
953
954
955
956
957
958

959
960
961
962
963
964
965
966
967
968

969
970
971


972



973
974
975
976

977

978
979
980
981

982
983



984

985
986
987




988


989

990

991
992
993









994





995

996
997
998
999
1000

1001
1002
1003
1004
1005


1006
1007
1008




1009


1010









1011






1012
1013
1014

1015
1016
1017
1018
1019
1020
1021
1022
1023

1024
1025




1026
1027

1028











1029

























1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
    Tcl_EventuallyFree((ClientData) interp,
            (Tcl_FreeProc *) DeleteInterpProc);
}

/*
 *----------------------------------------------------------------------
 *
 * HiddenCmdsDeleteProc --
 *
 *	Called on interpreter deletion to delete all the hidden



 *	commands in an interpreter.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees up memory.

 *
 *----------------------------------------------------------------------
 */

static void
HiddenCmdsDeleteProc(clientData, interp)
    ClientData clientData;		/* The hidden commands hash table. */
    Tcl_Interp *interp;			/* The interpreter being deleted. */
{
    Tcl_HashTable *hiddenCmdTblPtr;

    Tcl_HashEntry *hPtr;
    Tcl_HashSearch hSearch;
    Command *cmdPtr;






    hiddenCmdTblPtr = (Tcl_HashTable *) clientData;
    for (hPtr = Tcl_FirstHashEntry(hiddenCmdTblPtr, &hSearch);
	     hPtr != NULL;
             hPtr = Tcl_FirstHashEntry(hiddenCmdTblPtr, &hSearch)) {



        /*
         * Cannot use Tcl_DeleteCommand because (a) the command is not
         * in the command hash table, and (b) that table has already been
         * deleted above. Hence we emulate what it does, below.

         */
        



        cmdPtr = (Command *) Tcl_GetHashValue(hPtr);


	/*
         * The code here is tricky.  We can't delete the hash table entry




         * before invoking the deletion callback because there are cases


         * where the deletion callback needs to invoke the command (e.g.

         * object systems such as OTcl).  However, this means that the

         * callback could try to delete or rename the command.  The deleted
         * flag allows us to detect these cases and skip nested deletes.
         */















        if (cmdPtr->deleted) {


	    /*
             * Another deletion is already in progress.  Remove the hash
             * table entry now, but don't invoke a callback or free the
             * command structure.

             */

            Tcl_DeleteHashEntry(cmdPtr->hPtr);
            cmdPtr->hPtr = NULL;
            continue;


        }
        cmdPtr->deleted = 1;
        if (cmdPtr->deleteProc != NULL) {




            (*cmdPtr->deleteProc)(cmdPtr->deleteData);


        }
















	/*
	 * Bump the command epoch counter. This will invalidate all cached
         * references that refer to this command.

	 */
	
        cmdPtr->cmdEpoch++;

	/*
         * Don't use hPtr to delete the hash entry here, because it's
         * possible that the deletion callback renamed the command.
         * Instead, use cmdPtr->hptr, and make sure that no-one else
         * has already deleted the hash entry.

         */





        if (cmdPtr->hPtr != NULL) {
            Tcl_DeleteHashEntry(cmdPtr->hPtr);

        }











	

























        /*
	 * Now free the Command structure, unless there is another reference
	 * to it from a CmdName Tcl object in some ByteCode code
	 * sequence. In that case, delay the cleanup until all references
	 * are either discarded (when a ByteCode is freed) or replaced by a
	 * new reference (when a cached CmdName Command reference is found
	 * to be invalid and TclExecuteByteCode looks up the command in the
	 * command hashtable).
	 */
	
	TclCleanupCommand(cmdPtr);
    }
    Tcl_DeleteHashTable(hiddenCmdTblPtr);
    ckfree((char *) hiddenCmdTblPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_HideCommand --
 *
 *	Makes a command hidden so that it cannot be invoked from within
 *	an interpreter, only from within an ancestor.
 *
 * Results:
 *	A standard Tcl result; also leaves a message in interp->result
 *	if an error occurs.
 *
 * Side effects:
 *	Removes a command from the command table and create an entry
 *      into the hidden command table under the specified token name.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
    Tcl_Interp *interp;		/* Interpreter in which to hide command. */
    char *cmdName;		/* Name of command to hide. */
    char *hiddenCmdToken;	/* Token name of the to-be-hidden command. */
{
    Interp *iPtr = (Interp *) interp;
    Tcl_Command cmd;
    Command *cmdPtr;
    Tcl_HashTable *hTblPtr;
    Tcl_HashEntry *hPtr;
    int new;

    if (iPtr->flags & DELETED) {

        /*
         * The interpreter is being deleted. Do not create any new







|

|
>
>
>
|





|
>





|
<
|

<
>

|
|
>
>

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

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

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

|
<
|
<
|
>
|

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



|







|






|











|







892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918

919
920

921
922
923
924
925
926
927
928
929
930
931

932

933
934
935
936

937

938
939
940
941
942
943
944
945
946
947

948
949
950
951
952
953
954
955
956
957
958
959

960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979



980
981
982
983
984

985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014


1015
1016
1017
1018
1019
1020

1021

1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071

1072




1073
1074
1075


1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
    Tcl_EventuallyFree((ClientData) interp,
            (Tcl_FreeProc *) DeleteInterpProc);
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteInterpProc --
 *
 *	Helper procedure to delete an interpreter. This procedure is
 *	called when the last call to Tcl_Preserve on this interpreter
 *	is matched by a call to Tcl_Release. The procedure cleans up
 *	all resources used in the interpreter and calls all currently
 *	registered interpreter deletion callbacks.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Whatever the interpreter deletion callbacks do. Frees resources
 *	used by the interpreter.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteInterpProc(interp)

    Tcl_Interp *interp;			/* Interpreter to delete. */
{

    Interp *iPtr = (Interp *) interp;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Tcl_HashTable *hTablePtr;
    ResolverScheme *resPtr, *nextResPtr;
    int i;

    /*
     * Punt if there is an error in the Tcl_Release/Tcl_Preserve matchup.
     */
    

    if (iPtr->numLevels > 0) {

        panic("DeleteInterpProc called with active evals");
    }

    /*

     * The interpreter should already be marked deleted; otherwise how

     * did we get here?
     */

    if (!(iPtr->flags & DELETED)) {
        panic("DeleteInterpProc called on interpreter not marked deleted");
    }

    TclHandleFree(iPtr->handle);

    /*

     * Dismantle everything in the global namespace except for the
     * "errorInfo" and "errorCode" variables. These remain until the
     * namespace is actually destroyed, in case any errors occur.
     *   
     * Dismantle the namespace here, before we clear the assocData. If any
     * background errors occur here, they will be deleted below.
     */
    
    TclTeardownNamespace(iPtr->globalNsPtr);

    /*
     * Delete all the hidden commands.

     */
     
    hTablePtr = iPtr->hiddenCmdTablePtr;
    if (hTablePtr != NULL) {
	/*
	 * Non-pernicious deletion.  The deletion callbacks will not be
	 * allowed to create any new hidden or non-hidden commands.
	 * Tcl_DeleteCommandFromToken() will remove the entry from the
	 * hiddenCmdTablePtr.
	 */
	 
	hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
	for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	    Tcl_DeleteCommandFromToken(interp,
		    (Tcl_Command) Tcl_GetHashValue(hPtr));
	}
	Tcl_DeleteHashTable(hTablePtr);
	ckfree((char *) hTablePtr);
    }
    /*



     * Tear down the math function table.
     */

    for (hPtr = Tcl_FirstHashEntry(&iPtr->mathFuncTable, &search);
	     hPtr != NULL;

             hPtr = Tcl_NextHashEntry(&search)) {
	ckfree((char *) Tcl_GetHashValue(hPtr));
    }
    Tcl_DeleteHashTable(&iPtr->mathFuncTable);

    /*
     * Invoke deletion callbacks; note that a callback can create new
     * callbacks, so we iterate.
     */

    while (iPtr->assocData != (Tcl_HashTable *) NULL) {
	AssocData *dPtr;
	
        hTablePtr = iPtr->assocData;
        iPtr->assocData = (Tcl_HashTable *) NULL;
        for (hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
                 hPtr != NULL;
                 hPtr = Tcl_FirstHashEntry(hTablePtr, &search)) {
            dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
            Tcl_DeleteHashEntry(hPtr);
            if (dPtr->proc != NULL) {
                (*dPtr->proc)(dPtr->clientData, interp);
            }
            ckfree((char *) dPtr);
        }
        Tcl_DeleteHashTable(hTablePtr);
        ckfree((char *) hTablePtr);
    }

    /*


     * Finish deleting the global namespace.
     */
    
    Tcl_DeleteNamespace((Tcl_Namespace *) iPtr->globalNsPtr);

    /*

     * Free up the result *after* deleting variables, since variable

     * deletion could have transferred ownership of the result string
     * to Tcl.
     */

    Tcl_FreeResult(interp);
    interp->result = NULL;
    Tcl_DecrRefCount(iPtr->objResultPtr);
    iPtr->objResultPtr = NULL;
    if (iPtr->errorInfo != NULL) {
	ckfree(iPtr->errorInfo);
        iPtr->errorInfo = NULL;
    }
    if (iPtr->errorCode != NULL) {
	ckfree(iPtr->errorCode);
        iPtr->errorCode = NULL;
    }
    if (iPtr->appendResult != NULL) {
	ckfree(iPtr->appendResult);
        iPtr->appendResult = NULL;
    }
    for (i = 0; i < NUM_REGEXPS; i++) {
	if (iPtr->patterns[i] == NULL) {
	    break;
	}
	ckfree(iPtr->patterns[i]);
	ckfree((char *) iPtr->regexps[i]);
        iPtr->regexps[i] = NULL;
    }
    TclFreePackageInfo(iPtr);
    while (iPtr->tracePtr != NULL) {
	Trace *nextPtr = iPtr->tracePtr->nextPtr;

	ckfree((char *) iPtr->tracePtr);
	iPtr->tracePtr = nextPtr;
    }
    if (iPtr->execEnvPtr != NULL) {
	TclDeleteExecEnv(iPtr->execEnvPtr);
    }
    Tcl_DecrRefCount(iPtr->emptyObjPtr);
    iPtr->emptyObjPtr = NULL;

    resPtr = iPtr->resolverPtr;
    while (resPtr) {
	nextResPtr = resPtr->nextPtr;
	ckfree(resPtr->name);
	ckfree((char *) resPtr);
        resPtr = nextResPtr;
    }
    
    /*

     * Free up literal objects created for scripts compiled by the




     * interpreter.
     */



    TclDeleteLiteralTable(interp, &(iPtr->literalTable));
    ckfree((char *) iPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_HideCommand --
 *
 *	Makes a command hidden so that it cannot be invoked from within
 *	an interpreter, only from within an ancestor.
 *
 * Results:
 *	A standard Tcl result; also leaves a message in the interp's result
 *	if an error occurs.
 *
 * Side effects:
 *	Removes a command from the command table and create an entry
 *      into the hidden command table under the specified token name.
 *
 *---------------------------------------------------------------------------
 */

int
Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
    Tcl_Interp *interp;		/* Interpreter in which to hide command. */
    char *cmdName;		/* Name of command to hide. */
    char *hiddenCmdToken;	/* Token name of the to-be-hidden command. */
{
    Interp *iPtr = (Interp *) interp;
    Tcl_Command cmd;
    Command *cmdPtr;
    Tcl_HashTable *hiddenCmdTablePtr;
    Tcl_HashEntry *hPtr;
    int new;

    if (iPtr->flags & DELETED) {

        /*
         * The interpreter is being deleted. Do not create any new
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
        return TCL_ERROR;
    }
    
    /*
     * Initialize the hidden command table if necessary.
     */

    hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclHiddenCmds",
            NULL);
    if (hTblPtr == (Tcl_HashTable *) NULL) {
        hTblPtr = (Tcl_HashTable *)
	        ckalloc((unsigned) sizeof(Tcl_HashTable));
        Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS);
        Tcl_SetAssocData(interp, "tclHiddenCmds", HiddenCmdsDeleteProc,
                (ClientData) hTblPtr);
    }

    /*
     * It is an error to move an exposed command to a hidden command with
     * hiddenCmdToken if a hidden command with the name hiddenCmdToken already
     * exists.
     */
    
    hPtr = Tcl_CreateHashEntry(hTblPtr, hiddenCmdToken, &new);
    if (!new) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "hidden command named \"", hiddenCmdToken, "\" already exists",
                (char *) NULL);
        return TCL_ERROR;
    }








|
|
<
|

|
|
<








|







1172
1173
1174
1175
1176
1177
1178
1179
1180

1181
1182
1183
1184

1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
        return TCL_ERROR;
    }
    
    /*
     * Initialize the hidden command table if necessary.
     */

    hiddenCmdTablePtr = iPtr->hiddenCmdTablePtr;
    if (hiddenCmdTablePtr == NULL) {

        hiddenCmdTablePtr = (Tcl_HashTable *)
	        ckalloc((unsigned) sizeof(Tcl_HashTable));
        Tcl_InitHashTable(hiddenCmdTablePtr, TCL_STRING_KEYS);
	iPtr->hiddenCmdTablePtr = hiddenCmdTablePtr;

    }

    /*
     * It is an error to move an exposed command to a hidden command with
     * hiddenCmdToken if a hidden command with the name hiddenCmdToken already
     * exists.
     */
    
    hPtr = Tcl_CreateHashEntry(hiddenCmdTablePtr, hiddenCmdToken, &new);
    if (!new) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "hidden command named \"", hiddenCmdToken, "\" already exists",
                (char *) NULL);
        return TCL_ERROR;
    }

1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
 * Tcl_ExposeCommand --
 *
 *	Makes a previously hidden command callable from inside the
 *	interpreter instead of only by its ancestors.
 *
 * Results:
 *	A standard Tcl result. If an error occurs, a message is left
 *	in interp->result.
 *
 * Side effects:
 *	Moves commands from one hash table to another.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ExposeCommand(interp, hiddenCmdToken, cmdName)
    Tcl_Interp *interp;		/* Interpreter in which to make command
                                 * callable. */
    char *hiddenCmdToken;	/* Name of hidden command. */
    char *cmdName;		/* Name of to-be-exposed command. */
{
    Interp *iPtr = (Interp *) interp;
    Command *cmdPtr;
    Namespace *nsPtr;
    Tcl_HashEntry *hPtr;
    Tcl_HashTable *hTblPtr;
    int new;

    if (iPtr->flags & DELETED) {
        /*
         * The interpreter is being deleted. Do not create any new
         * structures, because it is not safe to modify the interpreter.
         */







|


















|







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
 * Tcl_ExposeCommand --
 *
 *	Makes a previously hidden command callable from inside the
 *	interpreter instead of only by its ancestors.
 *
 * Results:
 *	A standard Tcl result. If an error occurs, a message is left
 *	in the interp's result.
 *
 * Side effects:
 *	Moves commands from one hash table to another.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ExposeCommand(interp, hiddenCmdToken, cmdName)
    Tcl_Interp *interp;		/* Interpreter in which to make command
                                 * callable. */
    char *hiddenCmdToken;	/* Name of hidden command. */
    char *cmdName;		/* Name of to-be-exposed command. */
{
    Interp *iPtr = (Interp *) interp;
    Command *cmdPtr;
    Namespace *nsPtr;
    Tcl_HashEntry *hPtr;
    Tcl_HashTable *hiddenCmdTablePtr;
    int new;

    if (iPtr->flags & DELETED) {
        /*
         * The interpreter is being deleted. Do not create any new
         * structures, because it is not safe to modify the interpreter.
         */
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283



1284

1285
1286
1287
1288
1289
1290
1291
                "can not expose to a namespace ",
		"(use expose to toplevel, then rename)",
                 (char *) NULL);
        return TCL_ERROR;
    }

    /*
     * Find the hash table for the hidden commands; error out if there
     * is none.
     */

    hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclHiddenCmds",
            NULL);
    if (hTblPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "unknown hidden command \"", hiddenCmdToken,
                "\"", (char *) NULL);
        return TCL_ERROR;
    }
        
    /*
     * Get the command from the hidden command table:
     */




    hPtr = Tcl_FindHashEntry(hTblPtr, hiddenCmdToken);

    if (hPtr == (Tcl_HashEntry *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "unknown hidden command \"", hiddenCmdToken,
                "\"", (char *) NULL);
        return TCL_ERROR;
    }
    cmdPtr = (Command *) Tcl_GetHashValue(hPtr);







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



>
>
>
|
>







1292
1293
1294
1295
1296
1297
1298














1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
                "can not expose to a namespace ",
		"(use expose to toplevel, then rename)",
                 (char *) NULL);
        return TCL_ERROR;
    }

    /*














     * Get the command from the hidden command table:
     */

    hPtr = NULL;
    hiddenCmdTablePtr = iPtr->hiddenCmdTablePtr;
    if (hiddenCmdTablePtr != NULL) {
	hPtr = Tcl_FindHashEntry(hiddenCmdTablePtr, hiddenCmdToken);
    }
    if (hPtr == (Tcl_HashEntry *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "unknown hidden command \"", hiddenCmdToken,
                "\"", (char *) NULL);
        return TCL_ERROR;
    }
    cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
1401
1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412

1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444



1445
1446
1447



1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474















1475
1476
1477
1478
1479
1480
1481
    Tcl_CmdProc *proc;		/* Procedure to associate with cmdName. */
    ClientData clientData;	/* Arbitrary value passed to string proc. */
    Tcl_CmdDeleteProc *deleteProc;
				/* If not NULL, gives a procedure to call
				 * when this command is deleted. */
{
    Interp *iPtr = (Interp *) interp;

    Namespace *nsPtr, *dummy1, *dummy2;
    Command *cmdPtr;
    Tcl_HashEntry *hPtr;
    char *tail;
    int new, result;


    if (iPtr->flags & DELETED) {
	/*
	 * The interpreter is being deleted.  Don't create any new
	 * commands; it's not safe to muck with the interpreter anymore.
	 */

	return (Tcl_Command) NULL;
    }

    /*
     * Determine where the command should reside. If its name contains 
     * namespace qualifiers, we put it in the specified namespace; 
     * otherwise, we always put it in the global namespace.
     */

    if (strstr(cmdName, "::") != NULL) {
	result = TclGetNamespaceForQualName(interp, cmdName, 
                (Namespace *) NULL, CREATE_NS_IF_UNKNOWN, &nsPtr, 
                &dummy1, &dummy2, &tail);
	if ((result != TCL_OK) || (nsPtr == NULL) || (tail == NULL)) {
	    return (Tcl_Command) NULL;
	}
    } else {
	nsPtr = iPtr->globalNsPtr;
	tail = cmdName;
    }
    
    hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
    if (!new) {
	/*
	 * Command already exists. Delete the old one.



	 */

	cmdPtr = (Command *) Tcl_GetHashValue(hPtr);



	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
	if (!new) {
	    /*
	     * If the deletion callback recreated the command, just throw
             * away the new command (if we try to delete it again, we
             * could get stuck in an infinite loop).
	     */

	     ckfree((char*) cmdPtr);
	}
    }
    cmdPtr = (Command *) ckalloc(sizeof(Command));
    Tcl_SetHashValue(hPtr, cmdPtr);
    cmdPtr->hPtr = hPtr;
    cmdPtr->nsPtr = nsPtr;
    cmdPtr->refCount = 1;
    cmdPtr->cmdEpoch = 0;
    cmdPtr->compileProc = (CompileProc *) NULL;
    cmdPtr->objProc = TclInvokeStringCommand;
    cmdPtr->objClientData = (ClientData) cmdPtr;
    cmdPtr->proc = proc;
    cmdPtr->clientData = clientData;
    cmdPtr->deleteProc = deleteProc;
    cmdPtr->deleteData = clientData;
    cmdPtr->deleted = 0;
    cmdPtr->importRefPtr = NULL;
















    /*
     * We just created a command, so in its namespace and all of its parent
     * namespaces, it may shadow global commands with the same name. If any
     * shadowed commands are found, invalidate all cached command references
     * in the affected namespaces.
     */







>

|


|
>

















|
<
|
|











>
>
>



>
>
>









|

















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







1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454

1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
    Tcl_CmdProc *proc;		/* Procedure to associate with cmdName. */
    ClientData clientData;	/* Arbitrary value passed to string proc. */
    Tcl_CmdDeleteProc *deleteProc;
				/* If not NULL, gives a procedure to call
				 * when this command is deleted. */
{
    Interp *iPtr = (Interp *) interp;
    ImportRef *oldRefPtr = NULL;
    Namespace *nsPtr, *dummy1, *dummy2;
    Command *cmdPtr, *refCmdPtr;
    Tcl_HashEntry *hPtr;
    char *tail;
    int new;
    ImportedCmdData *dataPtr;

    if (iPtr->flags & DELETED) {
	/*
	 * The interpreter is being deleted.  Don't create any new
	 * commands; it's not safe to muck with the interpreter anymore.
	 */

	return (Tcl_Command) NULL;
    }

    /*
     * Determine where the command should reside. If its name contains 
     * namespace qualifiers, we put it in the specified namespace; 
     * otherwise, we always put it in the global namespace.
     */

    if (strstr(cmdName, "::") != NULL) {
       TclGetNamespaceForQualName(interp, cmdName, (Namespace *) NULL,

           CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
       if ((nsPtr == NULL) || (tail == NULL)) {
	    return (Tcl_Command) NULL;
	}
    } else {
	nsPtr = iPtr->globalNsPtr;
	tail = cmdName;
    }
    
    hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
    if (!new) {
	/*
	 * Command already exists. Delete the old one.
	 * Be careful to preserve any existing import links so we can
	 * restore them down below.  That way, you can redefine a
	 * command and its import status will remain intact.
	 */

	cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
	oldRefPtr = cmdPtr->importRefPtr;
	cmdPtr->importRefPtr = NULL;

	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
	if (!new) {
	    /*
	     * If the deletion callback recreated the command, just throw
             * away the new command (if we try to delete it again, we
             * could get stuck in an infinite loop).
	     */

	     ckfree((char*) Tcl_GetHashValue(hPtr));
	}
    }
    cmdPtr = (Command *) ckalloc(sizeof(Command));
    Tcl_SetHashValue(hPtr, cmdPtr);
    cmdPtr->hPtr = hPtr;
    cmdPtr->nsPtr = nsPtr;
    cmdPtr->refCount = 1;
    cmdPtr->cmdEpoch = 0;
    cmdPtr->compileProc = (CompileProc *) NULL;
    cmdPtr->objProc = TclInvokeStringCommand;
    cmdPtr->objClientData = (ClientData) cmdPtr;
    cmdPtr->proc = proc;
    cmdPtr->clientData = clientData;
    cmdPtr->deleteProc = deleteProc;
    cmdPtr->deleteData = clientData;
    cmdPtr->deleted = 0;
    cmdPtr->importRefPtr = NULL;

    /*
     * Plug in any existing import references found above.  Be sure
     * to update all of these references to point to the new command.
     */

    if (oldRefPtr != NULL) {
	cmdPtr->importRefPtr = oldRefPtr;
	while (oldRefPtr != NULL) {
	    refCmdPtr = oldRefPtr->importedCmdPtr;
	    dataPtr = (ImportedCmdData*)refCmdPtr->objClientData;
	    dataPtr->realCmdPtr = cmdPtr;
	    oldRefPtr = oldRefPtr->nextPtr;
	}
    }

    /*
     * We just created a command, so in its namespace and all of its parent
     * namespaces, it may shadow global commands with the same name. If any
     * shadowed commands are found, invalidate all cached command references
     * in the affected namespaces.
     */
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
 *
 * Tcl_CreateObjCommand --
 *
 *	Define a new object-based command in a command table.
 *
 * Results:
 *	The return value is a token for the command, which can
 *	be used in future calls to Tcl_NameOfCommand.
 *
 * Side effects:
 *	If no command named "cmdName" already exists for interp, one is
 *	created. Otherwise, if a command does exist, then if the
 *	object-based Tcl_ObjCmdProc is TclInvokeStringCommand, we assume
 *	Tcl_CreateCommand was called previously for the same command and
 *	just set its Tcl_ObjCmdProc to the argument "proc"; otherwise, we







|







1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
 *
 * Tcl_CreateObjCommand --
 *
 *	Define a new object-based command in a command table.
 *
 * Results:
 *	The return value is a token for the command, which can
 *	be used in future calls to Tcl_GetCommandName.
 *
 * Side effects:
 *	If no command named "cmdName" already exists for interp, one is
 *	created. Otherwise, if a command does exist, then if the
 *	object-based Tcl_ObjCmdProc is TclInvokeStringCommand, we assume
 *	Tcl_CreateCommand was called previously for the same command and
 *	just set its Tcl_ObjCmdProc to the argument "proc"; otherwise, we
1525
1526
1527
1528
1529
1530
1531

1532
1533
1534
1535
1536

1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
    ClientData clientData;	/* Arbitrary value to pass to object
    				 * procedure. */
    Tcl_CmdDeleteProc *deleteProc;
				/* If not NULL, gives a procedure to call
				 * when this command is deleted. */
{
    Interp *iPtr = (Interp *) interp;

    Namespace *nsPtr, *dummy1, *dummy2;
    Command *cmdPtr;
    Tcl_HashEntry *hPtr;
    char *tail;
    int new, result;


    if (iPtr->flags & DELETED) {
	/*
	 * The interpreter is being deleted.  Don't create any new
	 * commands;  it's not safe to muck with the interpreter anymore.
	 */

	return (Tcl_Command) NULL;
    }

    /*
     * Determine where the command should reside. If its name contains 
     * namespace qualifiers, we put it in the specified namespace; 
     * otherwise, we always put it in the global namespace.
     */

    if (strstr(cmdName, "::") != NULL) {
	result = TclGetNamespaceForQualName(interp, cmdName, 
                (Namespace *) NULL, CREATE_NS_IF_UNKNOWN, &nsPtr, 
                &dummy1, &dummy2, &tail);
	if ((result != TCL_OK) || (nsPtr == NULL) || (tail == NULL)) {
	    return (Tcl_Command) NULL;
	}
    } else {
	nsPtr = iPtr->globalNsPtr;
	tail = cmdName;
    }








>

|


|
>

















|
<
|
|







1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600

1601
1602
1603
1604
1605
1606
1607
1608
1609
    ClientData clientData;	/* Arbitrary value to pass to object
    				 * procedure. */
    Tcl_CmdDeleteProc *deleteProc;
				/* If not NULL, gives a procedure to call
				 * when this command is deleted. */
{
    Interp *iPtr = (Interp *) interp;
    ImportRef *oldRefPtr = NULL;
    Namespace *nsPtr, *dummy1, *dummy2;
    Command *cmdPtr, *refCmdPtr;
    Tcl_HashEntry *hPtr;
    char *tail;
    int new;
    ImportedCmdData *dataPtr;

    if (iPtr->flags & DELETED) {
	/*
	 * The interpreter is being deleted.  Don't create any new
	 * commands;  it's not safe to muck with the interpreter anymore.
	 */

	return (Tcl_Command) NULL;
    }

    /*
     * Determine where the command should reside. If its name contains 
     * namespace qualifiers, we put it in the specified namespace; 
     * otherwise, we always put it in the global namespace.
     */

    if (strstr(cmdName, "::") != NULL) {
       TclGetNamespaceForQualName(interp, cmdName, (Namespace *) NULL,

           CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
       if ((nsPtr == NULL) || (tail == NULL)) {
	    return (Tcl_Command) NULL;
	}
    } else {
	nsPtr = iPtr->globalNsPtr;
	tail = cmdName;
    }

1576
1577
1578
1579
1580
1581
1582










1583
1584
1585
1586
1587
1588
1589
	    cmdPtr->objProc = proc;
	    cmdPtr->objClientData = clientData;
            cmdPtr->deleteProc = deleteProc;
            cmdPtr->deleteData = clientData;
	    return (Tcl_Command) cmdPtr;
	}











	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
	if (!new) {
	    /*
	     * If the deletion callback recreated the command, just throw
	     * away the new command (if we try to delete it again, we
	     * could get stuck in an infinite loop).







>
>
>
>
>
>
>
>
>
>







1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
	    cmdPtr->objProc = proc;
	    cmdPtr->objClientData = clientData;
            cmdPtr->deleteProc = deleteProc;
            cmdPtr->deleteData = clientData;
	    return (Tcl_Command) cmdPtr;
	}

	/*
	 * Otherwise, we delete the old command.  Be careful to preserve
	 * any existing import links so we can restore them down below.
	 * That way, you can redefine a command and its import status
	 * will remain intact.
	 */

	oldRefPtr = cmdPtr->importRefPtr;
	cmdPtr->importRefPtr = NULL;

	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
	if (!new) {
	    /*
	     * If the deletion callback recreated the command, just throw
	     * away the new command (if we try to delete it again, we
	     * could get stuck in an infinite loop).
1603
1604
1605
1606
1607
1608
1609
1610























1611
1612
1613
1614
1615
1616
1617
    cmdPtr->objClientData = clientData;
    cmdPtr->proc = TclInvokeObjectCommand;
    cmdPtr->clientData = (ClientData) cmdPtr;
    cmdPtr->deleteProc = deleteProc;
    cmdPtr->deleteData = clientData;
    cmdPtr->deleted = 0;
    cmdPtr->importRefPtr = NULL;
    























    return (Tcl_Command) cmdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TclInvokeStringCommand --







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







1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
    cmdPtr->objClientData = clientData;
    cmdPtr->proc = TclInvokeObjectCommand;
    cmdPtr->clientData = (ClientData) cmdPtr;
    cmdPtr->deleteProc = deleteProc;
    cmdPtr->deleteData = clientData;
    cmdPtr->deleted = 0;
    cmdPtr->importRefPtr = NULL;

    /*
     * Plug in any existing import references found above.  Be sure
     * to update all of these references to point to the new command.
     */

    if (oldRefPtr != NULL) {
	cmdPtr->importRefPtr = oldRefPtr;
	while (oldRefPtr != NULL) {
	    refCmdPtr = oldRefPtr->importedCmdPtr;
	    dataPtr = (ImportedCmdData*)refCmdPtr->objClientData;
	    dataPtr->realCmdPtr = cmdPtr;
	    oldRefPtr = oldRefPtr->nextPtr;
	}
    }
    
    /*
     * We just created a command, so in its namespace and all of its parent
     * namespaces, it may shadow global commands with the same name. If any
     * shadowed commands are found, invalidate all cached command references
     * in the affected namespaces.
     */
    
    TclResetShadowedCmdRefs(interp, cmdPtr);
    return (Tcl_Command) cmdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TclInvokeStringCommand --
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
    char *(argStorage[NUM_ARGS]);
    char **argv = argStorage;

    /*
     * Create the string argument array "argv". Make sure argv is large
     * enough to hold the objc arguments plus 1 extra for the zero
     * end-of-argv word.
     * THIS FAILS IF ANY ARGUMENT OBJECT CONTAINS AN EMBEDDED NULL.
     */

    if ((objc + 1) > NUM_ARGS) {
	argv = (char **) ckalloc((unsigned)(objc + 1) * sizeof(char *));
    }

    for (i = 0;  i < objc;  i++) {
	argv[i] = Tcl_GetStringFromObj(objv[i], (int *) NULL);
    }
    argv[objc] = 0;

    /*
     * Invoke the command's string-based Tcl_CmdProc.
     */








<







|







1731
1732
1733
1734
1735
1736
1737

1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
    char *(argStorage[NUM_ARGS]);
    char **argv = argStorage;

    /*
     * Create the string argument array "argv". Make sure argv is large
     * enough to hold the objc arguments plus 1 extra for the zero
     * end-of-argv word.

     */

    if ((objc + 1) > NUM_ARGS) {
	argv = (char **) ckalloc((unsigned)(objc + 1) * sizeof(char *));
    }

    for (i = 0;  i < objc;  i++) {
	argv[i] = Tcl_GetString(objv[i]);
    }
    argv[objc] = 0;

    /*
     * Invoke the command's string-based Tcl_CmdProc.
     */

1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
     */

    result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, argc, objv);

    /*
     * Move the interpreter's object result to the string result, 
     * then reset the object result.
     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULL BYTES.
     */

    Tcl_SetResult(interp,
	    TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
	    TCL_VOLATILE);
    
    /*
     * Decrement the ref counts for the argument objects created above,
     * then free the objv array if malloc'ed storage was used.
     */








<


|
<







1831
1832
1833
1834
1835
1836
1837

1838
1839
1840

1841
1842
1843
1844
1845
1846
1847
     */

    result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, argc, objv);

    /*
     * Move the interpreter's object result to the string result, 
     * then reset the object result.

     */

    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),

	    TCL_VOLATILE);
    
    /*
     * Decrement the ref counts for the argument objects created above,
     * then free the objv array if malloc'ed storage was used.
     */

1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
    /*
     * Make sure that the destination command does not already exist.
     * The rename operation is like creating a command, so we should
     * automatically create the containing namespaces just like
     * Tcl_CreateCommand would.
     */

    result = TclGetNamespaceForQualName(interp, newName, (Namespace *) NULL,
            (CREATE_NS_IF_UNKNOWN | TCL_LEAVE_ERR_MSG),
            &newNsPtr, &dummy1, &dummy2, &newTail);
    if (result != TCL_OK) {
        return result;
    }
    if ((newNsPtr == NULL) || (newTail == NULL)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		 "can't rename to \"", newName, "\": bad command name",
    	    	 (char *) NULL);
        return TCL_ERROR;
    }
    if (Tcl_FindHashEntry(&newNsPtr->cmdTable, newTail) != NULL) {







|
<
|
<
<
|







1923
1924
1925
1926
1927
1928
1929
1930

1931


1932
1933
1934
1935
1936
1937
1938
1939
    /*
     * Make sure that the destination command does not already exist.
     * The rename operation is like creating a command, so we should
     * automatically create the containing namespaces just like
     * Tcl_CreateCommand would.
     */

    TclGetNamespaceForQualName(interp, newName, (Namespace *) NULL,

       CREATE_NS_IF_UNKNOWN, &newNsPtr, &dummy1, &dummy2, &newTail);



    if ((newNsPtr == NULL) || (newTail == NULL)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		 "can't rename to \"", newName, "\": bad command name",
    	    	 (char *) NULL);
        return TCL_ERROR;
    }
    if (Tcl_FindHashEntry(&newNsPtr->cmdTable, newTail) != NULL) {
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
	ckfree((char *) cmdPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Eval --
 *
 *	Execute a Tcl command in a string.

 *
 * Results:
 *	The return value is one of the return codes defined in tcl.h
 *	(such as TCL_OK), and interp->result contains a string value
 *	to supplement the return code. The value of interp->result
 *	will persist only until the next call to Tcl_Eval or Tcl_EvalObj:
 *	you must copy it or lose it!
 *
 * Side effects:



 *	The string is compiled to produce a ByteCode object that holds the
 *	command's bytecode instructions. However, this ByteCode object is
 *	lost after executing the command. The command's execution will
 *	almost certainly have side effects. interp->termOffset is set to the
 *	offset of the character in "string" just after the last one
 *	successfully compiled or executed.
 *
 *----------------------------------------------------------------------
 */


int
Tcl_Eval(interp, string)
    Tcl_Interp *interp;		/* Token for command interpreter (returned



				 * by previous call to Tcl_CreateInterp). */





    char *string;		/* Pointer to TCL command to execute. */
{

    register Tcl_Obj *cmdPtr;
    int length = strlen(string);

    int result;

    if (length > 0) {
	/*
	 * Initialize a Tcl object from the command string.
	 */




	TclNewObj(cmdPtr);
	TclInitStringRep(cmdPtr, string, length);
	Tcl_IncrRefCount(cmdPtr);



	/*





	 * Compile and execute the bytecodes.
	 */
    
	result = Tcl_EvalObj(interp, cmdPtr);

	/*
	 * Move the interpreter's object result to the string result, 
	 * then reset the object result.
	 * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
	 */





	Tcl_SetResult(interp,
	        TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
	        TCL_VOLATILE);



	/*
	 * Discard the Tcl object created to hold the command and its code.
	 */
	

	Tcl_DecrRefCount(cmdPtr);	
    } else {
	/*

	 * An empty string. Just reset the interpreter's result.
	 */


	Tcl_ResetResult(interp);
	result = TCL_OK;
    }
    return result;

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_EvalObj --
 *
 *	Execute Tcl commands stored in a Tcl object. These commands are
 *	compiled into bytecodes if necessary.
 *
 * Results:
 *	The return value is one of the return codes defined in tcl.h
 *	(such as TCL_OK), and the interpreter's result contains a value







|

|
>


<
<
<
<
|


>
>
>
|
|
|
<
|
<



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

>
|
<
>
|

<
<
<
<
>
>
>
|
|
<
<

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

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

|
>





|







2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416




2417
2418
2419
2420
2421
2422
2423
2424
2425

2426

2427
2428
2429
2430
2431

2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446

2447
2448
2449




2450
2451
2452
2453
2454


2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469




2470
2471
2472
2473
2474



2475
2476
2477



2478
2479
2480
2481

2482
2483

2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
	ckfree((char *) cmdPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateMathFunc --
 *
 *	Creates a new math function for expressions in a given
 *	interpreter.
 *
 * Results:




 *	None.
 *
 * Side effects:
 *	The function defined by "name" is created or redefined. If the
 *	function already exists then its definition is replaced; this
 *	includes the builtin functions. Redefining a builtin function forces
 *	all existing code to be invalidated since that code may be compiled
 *	using an instruction specific to the replaced function. In addition,
 *	redefioning a non-builtin function will force existing code to be

 *	invalidated if the number of arguments has changed.

 *
 *----------------------------------------------------------------------
 */

void

Tcl_CreateMathFunc(interp, name, numArgs, argTypes, proc, clientData)
    Tcl_Interp *interp;			/* Interpreter in which function is
					 * to be available. */
    char *name;				/* Name of function (e.g. "sin"). */
    int numArgs;			/* Nnumber of arguments required by
					 * function. */
    Tcl_ValueType *argTypes;		/* Array of types acceptable for
					 * each argument. */
    Tcl_MathProc *proc;			/* Procedure that implements the
					 * math function. */
    ClientData clientData;		/* Additional value to pass to the
					 * function. */
{
    Interp *iPtr = (Interp *) interp;
    Tcl_HashEntry *hPtr;

    MathFunc *mathFuncPtr;
    int new, i;





    hPtr = Tcl_CreateHashEntry(&iPtr->mathFuncTable, name, &new);
    if (new) {
	Tcl_SetHashValue(hPtr, ckalloc(sizeof(MathFunc)));
    }
    mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);



    if (!new) {	
	if (mathFuncPtr->builtinFuncIndex >= 0) {
	    /*
	     * We are redefining a builtin math function. Invalidate the
             * interpreter's existing code by incrementing its
             * compileEpoch member. This field is checked in Tcl_EvalObj
             * and ObjInterpProc, and code whose compilation epoch doesn't
             * match is recompiled. Newly compiled code will no longer
             * treat the function as builtin.
	     */

	    iPtr->compileEpoch++;
	} else {
	    /*




	     * A non-builtin function is being redefined. We must invalidate
             * existing code if the number of arguments has changed. This
	     * is because existing code was compiled assuming that number.
	     */




	    if (numArgs != mathFuncPtr->numArgs) {
		iPtr->compileEpoch++;
	    }



	}
    }
    
    mathFuncPtr->builtinFuncIndex = -1;	/* can't be a builtin function */

    if (numArgs > MAX_MATH_ARGS) {
	numArgs = MAX_MATH_ARGS;

    }
    mathFuncPtr->numArgs = numArgs;
    for (i = 0;  i < numArgs;  i++) {
	mathFuncPtr->argTypes[i] = argTypes[i];
    }
    mathFuncPtr->proc = proc;
    mathFuncPtr->clientData = clientData;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_EvalObjEx --
 *
 *	Execute Tcl commands stored in a Tcl object. These commands are
 *	compiled into bytecodes if necessary.
 *
 * Results:
 *	The return value is one of the return codes defined in tcl.h
 *	(such as TCL_OK), and the interpreter's result contains a value
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443





2444
2445
2446
2447
2448
2449
2450
2451
2452






























2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472

2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485

2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499

2500
2501
2502
2503
2504
2505
2506
2507

2508



2509






2510
2511
2512
2513
2514
2515








2516

2517
2518
2519
2520
2521
2522



2523





2524
2525
2526
2527
2528

2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576


2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645





2646
2647
2648
2649
2650
































































































2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
 *	Just as in Tcl_Eval, interp->termOffset is set to the offset of the
 *	last character executed in the objPtr's string.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_EvalObj(interp, objPtr)
    Tcl_Interp *interp;			/* Token for command interpreter
					 * (returned by a previous call to
					 * Tcl_CreateInterp). */
    Tcl_Obj *objPtr;			/* Pointer to object containing
					 * commands to execute. */





{
    register Interp *iPtr = (Interp *) interp;
    int flags;				/* Interp->evalFlags value when the
					 * procedure was called. */
    register ByteCode* codePtr;		/* Tcl Internal type of bytecode. */
    int oldCount = iPtr->cmdCount;	/* Used to tell whether any commands
					 * at all were executed. */
    int numSrcChars;
    register int result;































    /*
     * Reset both the interpreter's string and object results and clear out
     * any error information. This makes sure that we return an empty
     * result if there are no commands in the command string.
     */

    Tcl_ResetResult(interp);

    /*
     * Check depth of nested calls to Tcl_Eval:  if this gets too large,
     * it's probably because of an infinite loop somewhere.
     */

    iPtr->numLevels++;
    if (iPtr->numLevels > iPtr->maxNestingDepth) {
	iPtr->numLevels--;
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
		"too many nested calls to Tcl_EvalObj (infinite loop?)", -1);
	return TCL_ERROR;

    }

    /*
     * On the Mac, we will never reach the default recursion limit before blowing
     * the stack. So we need to do a check here.
     */
    
    if (TclpCheckStackSpace() == 0) {
	/*NOTREACHED*/
    	iPtr->numLevels--;
    	Tcl_AppendToObj(Tcl_GetObjResult(interp),
    		"too many nested calls to Tcl_EvalObj (infinite loop?)", -1);
    	return TCL_ERROR;

    }

    /*
     * If the interpreter has been deleted, return an error.
     */
    
    if (iPtr->flags & DELETED) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "attempt to call eval in deleted interpreter", -1);
	Tcl_SetErrorCode(interp, "CORE", "IDELETE",
	        "attempt to call eval in deleted interpreter", (char *) NULL);
	iPtr->numLevels--;
	return TCL_ERROR;

    }

    /*
     * Get the ByteCode from the object. If it exists, make sure it hasn't
     * been invalidated by, e.g., someone redefining a command with a
     * compile procedure (this might make the compiled code wrong). If
     * necessary, convert the object to be a ByteCode object and compile it.
     * Also, if the code was compiled in/for a different interpreter,

     * we recompile it.



     */







    if (objPtr->typePtr == &tclByteCodeType) {
	codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
	
	if ((codePtr->iPtr != iPtr)
	        || (codePtr->compileEpoch != iPtr->compileEpoch)) {








	    tclByteCodeType.freeIntRepProc(objPtr);

	}
    }
    if (objPtr->typePtr != &tclByteCodeType) {
	/*
	 * First reset any error line number information.
	 */



	





	iPtr->errorLine = 1;   /* no correct line # information yet */
	result = tclByteCodeType.setFromAnyProc(interp, objPtr);
	if (result != TCL_OK) {
	    iPtr->numLevels--;
	    return result;

	}
    }
    codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;

    /*
     * Extract then reset the compilation flags in the interpreter.
     * Resetting the flags must be done after any compilation.
     */

    flags = iPtr->evalFlags;
    iPtr->evalFlags = 0;

    /*
     * Execute the commands. If the code was compiled from an empty string,
     * don't bother executing the code.
     */

    numSrcChars = codePtr->numSrcChars;
    if (numSrcChars > 0) {
	/*
	 * Increment the code's ref count while it is being executed. If
	 * afterwards no references to it remain, free the code.
	 */
	
	codePtr->refCount++;
	result = TclExecuteByteCode(interp, codePtr);
	codePtr->refCount--;
	if (codePtr->refCount <= 0) {
	    TclCleanupByteCode(codePtr);
	}
    } else {
	Tcl_ResetResult(interp);
	result = TCL_OK;
    }

    /*
     * If no commands at all were executed, check for asynchronous
     * handlers so that they at least get one change to execute.
     * This is needed to handle event loops written in Tcl with
     * empty bodies.
     */

    if ((oldCount == iPtr->cmdCount) && (Tcl_AsyncReady())) {
	result = Tcl_AsyncInvoke(interp, result);
    }

    /*
     * Free up any extra resources that were allocated.


     */

    iPtr->numLevels--;
    if (iPtr->numLevels == 0) {
	if (result == TCL_RETURN) {
	    result = TclUpdateReturnInfo(iPtr);
	}
	if ((result != TCL_OK) && (result != TCL_ERROR)
		&& !(flags & TCL_ALLOW_EXCEPTIONS)) {
	    Tcl_ResetResult(interp);
	    if (result == TCL_BREAK) {
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "invoked \"break\" outside of a loop", -1);
	    } else if (result == TCL_CONTINUE) {
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "invoked \"continue\" outside of a loop", -1);
	    } else {
		char buf[50];
		sprintf(buf, "command returned bad code: %d", result);
		Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
	    }
	    result = TCL_ERROR;
	}
    }

    /*
     * If an error occurred, record information about what was being
     * executed when the error occurred.
     */

    if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
	char buf[200];
	char *ellipsis = "";
	char *bytes;
	int length;

	/*
	 * Figure out how much of the command to print in the error
	 * message (up to a certain number of characters, or up to
	 * the first new-line).
	 * THIS FAILS IF THE OBJECT'S STRING REP CONTAINS A NULL.
	 */

	bytes = Tcl_GetStringFromObj(objPtr, &length);
	length = TclMin(numSrcChars, length);
	if (length > 150) {
	    length = 150;
	    ellipsis = " ...";
	}

	if (!(iPtr->flags & ERR_IN_PROGRESS)) {
	    sprintf(buf, "\n    while executing\n\"%.*s%s\"",
		    length, bytes, ellipsis);
	} else {
	    sprintf(buf, "\n    invoked from within\n\"%.*s%s\"",
		    length, bytes, ellipsis);
	}
	Tcl_AddObjErrorInfo(interp, buf, -1);
    }

    /*
     * Set the interpreter's termOffset member to the offset of the
     * character just after the last one executed. We approximate the offset
     * of the last character executed by using the number of characters
     * compiled.
     */

    iPtr->termOffset = numSrcChars;
    iPtr->flags &= ~ERR_ALREADY_LOGGED;





    return result;
}

/*
 *--------------------------------------------------------------
































































































 *
 * Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean --
 *
 *	Procedures to evaluate an expression and return its value in a
 *	particular form.
 *
 * Results:
 *	Each of the procedures below returns a standard Tcl result. If an
 *	error occurs then an error message is left in interp->result.
 *	Otherwise the value of the expression, in the appropriate form, is
 *	stored at *ptr. If the expression had a result that was
 *	incompatible with the desired form then an error is returned.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
Tcl_ExprLong(interp, string, ptr)
    Tcl_Interp *interp;		/* Context in which to evaluate the
				 * expression. */
    char *string;		/* Expression to evaluate. */







|



|

>
>
>
>
>


|




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


















|
|
>



|
|






|
|
>











|
|
|
>








>
|
>
>
>

>
>
>
>
>
>




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



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









|







|
|












<










|




|
>
>


<
|




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










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









|

>
>
>
>
>




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








|
|
|





|







2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657

2658

2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704

2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724

2725
2726
2727
2728
2729
2730
2731











2732
2733
2734
2735
2736
2737
2738
2739
2740
2741




2742






















2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
 *	Just as in Tcl_Eval, interp->termOffset is set to the offset of the
 *	last character executed in the objPtr's string.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_EvalObjEx(interp, objPtr, flags)
    Tcl_Interp *interp;			/* Token for command interpreter
					 * (returned by a previous call to
					 * Tcl_CreateInterp). */
    register Tcl_Obj *objPtr;		/* Pointer to object containing
					 * commands to execute. */
    int flags;				/* Collection of OR-ed bits that
					 * control the evaluation of the
					 * script.  Supported values are
					 * TCL_EVAL_GLOBAL and
					 * TCL_EVAL_DIRECT. */
{
    register Interp *iPtr = (Interp *) interp;
    int evalFlags;			/* Interp->evalFlags value when the
					 * procedure was called. */
    register ByteCode* codePtr;		/* Tcl Internal type of bytecode. */
    int oldCount = iPtr->cmdCount;	/* Used to tell whether any commands
					 * at all were executed. */
    int numSrcBytes;
    int result;
    CallFrame *savedVarFramePtr;	/* Saves old copy of iPtr->varFramePtr
					 * in case TCL_EVAL_GLOBAL was set. */
    Namespace *namespacePtr;

    /*
     * Prevent the object from being deleted as a side effect of evaling it.
     */

    Tcl_IncrRefCount(objPtr);

    if ((iPtr->flags & USE_EVAL_DIRECT) || (flags & TCL_EVAL_DIRECT)) {
	/*
	 * We're not supposed to use the compiler or byte-code interpreter.
	 * Let Tcl_EvalEx evaluate the command directly (and probably
	 * more slowly).
	 */

	char *p;
	int length;

	p = Tcl_GetStringFromObj(objPtr, &length);
	result = Tcl_EvalEx(interp, p, length, flags);
	Tcl_DecrRefCount(objPtr);
	return result;
    }

    savedVarFramePtr = iPtr->varFramePtr;
    if (flags & TCL_EVAL_GLOBAL) {
	iPtr->varFramePtr = NULL;
    }

    /*
     * Reset both the interpreter's string and object results and clear out
     * any error information. This makes sure that we return an empty
     * result if there are no commands in the command string.
     */

    Tcl_ResetResult(interp);

    /*
     * Check depth of nested calls to Tcl_Eval:  if this gets too large,
     * it's probably because of an infinite loop somewhere.
     */

    iPtr->numLevels++;
    if (iPtr->numLevels > iPtr->maxNestingDepth) {
	iPtr->numLevels--;
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
		"too many nested calls to Tcl_EvalObj (infinite loop?)", -1); 
	result = TCL_ERROR;
	goto done;
    }

    /*
     * On the Mac, we will never reach the default recursion limit before
     * blowing the stack. So we need to do a check here.
     */
    
    if (TclpCheckStackSpace() == 0) {
	/*NOTREACHED*/
    	iPtr->numLevels--;
    	Tcl_AppendToObj(Tcl_GetObjResult(interp),
		"too many nested calls to Tcl_EvalObj (infinite loop?)", -1);
	result = TCL_ERROR;
	goto done;
    }

    /*
     * If the interpreter has been deleted, return an error.
     */
    
    if (iPtr->flags & DELETED) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "attempt to call eval in deleted interpreter", -1);
	Tcl_SetErrorCode(interp, "CORE", "IDELETE",
	        "attempt to call eval in deleted interpreter",
		(char *) NULL);
	result = TCL_ERROR;
	goto done;
    }

    /*
     * Get the ByteCode from the object. If it exists, make sure it hasn't
     * been invalidated by, e.g., someone redefining a command with a
     * compile procedure (this might make the compiled code wrong). If
     * necessary, convert the object to be a ByteCode object and compile it.
     * Also, if the code was compiled in/for a different interpreter,
     * or for a different namespace, or for the same namespace but
     * with different name resolution rules, we recompile it.
     *
     * Precompiled objects, however, are immutable and therefore
     * they are not recompiled, even if the epoch has changed.
     */

    if (iPtr->varFramePtr != NULL) {
        namespacePtr = iPtr->varFramePtr->nsPtr;
    } else {
        namespacePtr = iPtr->globalNsPtr;
    }

    if (objPtr->typePtr == &tclByteCodeType) {
	codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
	
	if (((Interp *) *codePtr->interpHandle != iPtr)
	        || (codePtr->compileEpoch != iPtr->compileEpoch)
	        || (codePtr->nsPtr != namespacePtr)
	        || (codePtr->nsEpoch != namespacePtr->resolverEpoch)) {
            if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
                if ((Interp *) *codePtr->interpHandle != iPtr) {
                    panic("Tcl_EvalObj: compiled script jumped interps");
                }
	        codePtr->compileEpoch = iPtr->compileEpoch;
            } else {
                tclByteCodeType.freeIntRepProc(objPtr);
            }
	}
    }
    if (objPtr->typePtr != &tclByteCodeType) {

	iPtr->errorLine = 1; 

	result = tclByteCodeType.setFromAnyProc(interp, objPtr);
	if (result != TCL_OK) {
	    goto done;
	}
    } else {
	codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
	if (((Interp *) *codePtr->interpHandle != iPtr)
	        || (codePtr->compileEpoch != iPtr->compileEpoch)) {
	    (*tclByteCodeType.freeIntRepProc)(objPtr);
	    iPtr->errorLine = 1; 
	    result = (*tclByteCodeType.setFromAnyProc)(interp, objPtr);
	    if (result != TCL_OK) {
		iPtr->numLevels--;
		return result;
	    }
	}
    }
    codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;

    /*
     * Extract then reset the compilation flags in the interpreter.
     * Resetting the flags must be done after any compilation.
     */

    evalFlags = iPtr->evalFlags;
    iPtr->evalFlags = 0;

    /*
     * Execute the commands. If the code was compiled from an empty string,
     * don't bother executing the code.
     */

    numSrcBytes = codePtr->numSrcBytes;
    if ((numSrcBytes > 0) || (codePtr->flags & TCL_BYTECODE_PRECOMPILED)) {
	/*
	 * Increment the code's ref count while it is being executed. If
	 * afterwards no references to it remain, free the code.
	 */
	
	codePtr->refCount++;
	result = TclExecuteByteCode(interp, codePtr);
	codePtr->refCount--;
	if (codePtr->refCount <= 0) {
	    TclCleanupByteCode(codePtr);
	}
    } else {

	result = TCL_OK;
    }

    /*
     * If no commands at all were executed, check for asynchronous
     * handlers so that they at least get one change to execute.
     * This is needed to handle event loops written in Tcl with
     * empty bodies.
     */

    if ((oldCount == iPtr->cmdCount) && Tcl_AsyncReady()) {
	result = Tcl_AsyncInvoke(interp, result);
    }

    /*
     * Update the interpreter's evaluation level count. If we are again at
     * the top level, process any unusual return code returned by the
     * evaluated code.
     */


    if (iPtr->numLevels == 1) {
	if (result == TCL_RETURN) {
	    result = TclUpdateReturnInfo(iPtr);
	}
	if ((result != TCL_OK) && (result != TCL_ERROR)
		&& ((evalFlags & TCL_ALLOW_EXCEPTIONS) == 0)) {
	    ProcessUnexpectedResult(interp, result);











	    result = TCL_ERROR;
	}
    }

    /*
     * If an error occurred, record information about what was being
     * executed when the error occurred.
     */

    if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {




	RecordTracebackInfo(interp, objPtr, numSrcBytes);






















    }

    /*
     * Set the interpreter's termOffset member to the offset of the
     * character just after the last one executed. We approximate the offset
     * of the last character executed by using the number of characters
     * compiled.
     */

    iPtr->termOffset = numSrcBytes;
    iPtr->flags &= ~ERR_ALREADY_LOGGED;

    done:
    TclDecrRefCount(objPtr);
    iPtr->varFramePtr = savedVarFramePtr; 
    iPtr->numLevels--;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * ProcessUnexpectedResult --
 *
 *	Procedure called by Tcl_EvalObj to set the interpreter's result
 *	value to an appropriate error message when the code it evaluates
 *	returns an unexpected result code (not TCL_OK and not TCL_ERROR) to
 *	the topmost evaluation level.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The interpreter result is set to an error message appropriate to
 *	the result code.
 *
 *----------------------------------------------------------------------
 */

static void
ProcessUnexpectedResult(interp, returnCode)
    Tcl_Interp *interp;		/* The interpreter in which the unexpected
				 * result code was returned. */
    int returnCode;		/* The unexpected result code. */
{
    Tcl_ResetResult(interp);
    if (returnCode == TCL_BREAK) {
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "invoked \"break\" outside of a loop", -1);
    } else if (returnCode == TCL_CONTINUE) {
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
		"invoked \"continue\" outside of a loop", -1);
    } else {
        char buf[30 + TCL_INTEGER_SPACE];

	sprintf(buf, "command returned bad code: %d", returnCode);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * RecordTracebackInfo --
 *
 *	Procedure called by Tcl_EvalObj to record information about what was
 *	being executed when the error occurred.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Appends information about the script being evaluated to the
 *	interpreter's "errorInfo" variable.
 *
 *----------------------------------------------------------------------
 */

static void
RecordTracebackInfo(interp, objPtr, numSrcBytes)
    Tcl_Interp *interp;		/* The interpreter in which the error
				 * occurred. */
    Tcl_Obj *objPtr;		/* Points to object containing script whose
				 * evaluation resulted in an error. */
    int numSrcBytes;		/* Number of bytes compiled in script. */
{
    Interp *iPtr = (Interp *) interp;
    char buf[200];
    char *ellipsis, *bytes;
    int length;

    /*
     * Decide how much of the command to print in the error message
     * (up to a certain number of bytes).
     */
    
    bytes = Tcl_GetStringFromObj(objPtr, &length);
    length = TclMin(numSrcBytes, length);
    
    ellipsis = "";
    if (length > 150) {
	length = 150;
	ellipsis = " ...";
    }
    
    if (!(iPtr->flags & ERR_IN_PROGRESS)) {
	sprintf(buf, "\n    while executing\n\"%.*s%s\"",
		length, bytes, ellipsis);
    } else {
	sprintf(buf, "\n    invoked from within\n\"%.*s%s\"",
		length, bytes, ellipsis);
    }
    Tcl_AddObjErrorInfo(interp, buf, -1);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean --
 *
 *	Procedures to evaluate an expression and return its value in a
 *	particular form.
 *
 * Results:
 *	Each of the procedures below returns a standard Tcl result. If an
 *	error occurs then an error message is left in the interp's result.
 *	Otherwise the value of the expression, in the appropriate form,
 *	is stored at *ptr. If the expression had a result that was
 *	incompatible with the desired form then an error is returned.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
Tcl_ExprLong(interp, string, ptr)
    Tcl_Interp *interp;		/* Context in which to evaluate the
				 * expression. */
    char *string;		/* Expression to evaluate. */
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
		result = TCL_ERROR;
	    }
	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
	} else {
	    /*
	     * Move the interpreter's object result to the string result, 
	     * then reset the object result.
	     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
	     */

	    Tcl_SetResult(interp,
	            TclGetStringFromObj(Tcl_GetObjResult(interp),
		            (int *) NULL),
	            TCL_VOLATILE);
	}
	Tcl_DecrRefCount(exprPtr);  /* discard the expression object */	
    } else {
	/*
	 * An empty string. Just set the result integer to 0.
	 */







<


|
<
<







2907
2908
2909
2910
2911
2912
2913

2914
2915
2916


2917
2918
2919
2920
2921
2922
2923
		result = TCL_ERROR;
	    }
	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
	} else {
	    /*
	     * Move the interpreter's object result to the string result, 
	     * then reset the object result.

	     */

	    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),


	            TCL_VOLATILE);
	}
	Tcl_DecrRefCount(exprPtr);  /* discard the expression object */	
    } else {
	/*
	 * An empty string. Just set the result integer to 0.
	 */
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
		result = TCL_ERROR;
	    }
	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
	} else {
	    /*
	     * Move the interpreter's object result to the string result, 
	     * then reset the object result.
	     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
	     */

	    Tcl_SetResult(interp,
	            TclGetStringFromObj(Tcl_GetObjResult(interp),
		            (int *) NULL),
	            TCL_VOLATILE);
	}
	Tcl_DecrRefCount(exprPtr);  /* discard the expression object */
    } else {
	/*
	 * An empty string. Just set the result double to 0.0.
	 */







<


|
<
<







2958
2959
2960
2961
2962
2963
2964

2965
2966
2967


2968
2969
2970
2971
2972
2973
2974
		result = TCL_ERROR;
	    }
	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
	} else {
	    /*
	     * Move the interpreter's object result to the string result, 
	     * then reset the object result.

	     */

	    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),


	            TCL_VOLATILE);
	}
	Tcl_DecrRefCount(exprPtr);  /* discard the expression object */
    } else {
	/*
	 * An empty string. Just set the result double to 0.0.
	 */
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
	    }
	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
	}
	if (result != TCL_OK) {
	    /*
	     * Move the interpreter's object result to the string result, 
	     * then reset the object result.
	     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
	     */

	    Tcl_SetResult(interp,
	            TclGetStringFromObj(Tcl_GetObjResult(interp),
		            (int *) NULL),
	            TCL_VOLATILE);
	}
	Tcl_DecrRefCount(exprPtr); /* discard the expression object */
    } else {
	/*
	 * An empty string. Just set the result boolean to 0 (false).
	 */







<


|
<
<







3008
3009
3010
3011
3012
3013
3014

3015
3016
3017


3018
3019
3020
3021
3022
3023
3024
	    }
	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
	}
	if (result != TCL_OK) {
	    /*
	     * Move the interpreter's object result to the string result, 
	     * then reset the object result.

	     */

	    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),


	            TCL_VOLATILE);
	}
	Tcl_DecrRefCount(exprPtr); /* discard the expression object */
    } else {
	/*
	 * An empty string. Just set the result boolean to 0 (false).
	 */
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
    if (result == TCL_OK) {
	if (resultPtr->typePtr == &tclIntType) {
	    *ptr = (resultPtr->internalRep.longValue != 0);
	} else if (resultPtr->typePtr == &tclDoubleType) {
	    *ptr = (resultPtr->internalRep.doubleValue != 0.0);
	} else {
	    result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
	    if (result != TCL_OK) {
		return result;
	    }
	}
	Tcl_DecrRefCount(resultPtr);  /* discard the result object */
    }
    return result;
}

/*







<
<
<







3118
3119
3120
3121
3122
3123
3124



3125
3126
3127
3128
3129
3130
3131
    if (result == TCL_OK) {
	if (resultPtr->typePtr == &tclIntType) {
	    *ptr = (resultPtr->internalRep.longValue != 0);
	} else if (resultPtr->typePtr == &tclDoubleType) {
	    *ptr = (resultPtr->internalRep.doubleValue != 0.0);
	} else {
	    result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);



	}
	Tcl_DecrRefCount(resultPtr);  /* discard the result object */
    }
    return result;
}

/*
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
     */

    result = TclObjInvoke(interp, argc, objv, flags);

    /*
     * Move the interpreter's object result to the string result, 
     * then reset the object result.
     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
     */
    
    Tcl_SetResult(interp,
	    TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
	    TCL_VOLATILE);

    /*
     * Decrement the ref counts on the objv elements since we are done
     * with them.
     */








<


|
<







3194
3195
3196
3197
3198
3199
3200

3201
3202
3203

3204
3205
3206
3207
3208
3209
3210
     */

    result = TclObjInvoke(interp, argc, objv, flags);

    /*
     * Move the interpreter's object result to the string result, 
     * then reset the object result.

     */
    
    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),

	    TCL_VOLATILE);

    /*
     * Decrement the ref counts on the objv elements since we are done
     * with them.
     */

3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104

3105
3106
3107
3108
3109
3110
3111
 *	Whatever the command does.
 *
 *----------------------------------------------------------------------
 */

int
TclObjInvokeGlobal(interp, objc, objv, flags)
    Tcl_Interp *interp;		/* Interpreter in which command is
				 * to be invoked. */
    int objc;			/* Count of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument value objects; objv[0]
				 * points to the name of the
				 * command to invoke. */
    int flags;			/* Combination of flags controlling
                                 * the call: TCL_INVOKE_HIDDEN and
                                 * TCL_INVOKE_NO_UNKNOWN. */

{
    register Interp *iPtr = (Interp *) interp;
    int result;
    CallFrame *savedVarFramePtr;

    savedVarFramePtr = iPtr->varFramePtr;
    iPtr->varFramePtr = NULL;







|
|

|
<
|
|
|
|
>







3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294

3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
 *	Whatever the command does.
 *
 *----------------------------------------------------------------------
 */

int
TclObjInvokeGlobal(interp, objc, objv, flags)
    Tcl_Interp *interp;		/* Interpreter in which command is to be
				 * invoked. */
    int objc;			/* Count of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects; objv[0] points to the

				 * name of the command to invoke. */
    int flags;			/* Combination of flags controlling the
				 * call: TCL_INVOKE_HIDDEN,
				 * TCL_INVOKE_NO_UNKNOWN, or
				 * TCL_INVOKE_NO_TRACEBACK. */
{
    register Interp *iPtr = (Interp *) interp;
    int result;
    CallFrame *savedVarFramePtr;

    savedVarFramePtr = iPtr->varFramePtr;
    iPtr->varFramePtr = NULL;
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144

3145
3146
3147
3148
3149
3150
3151
 *	Whatever the command does.
 *
 *----------------------------------------------------------------------
 */

int
TclObjInvoke(interp, objc, objv, flags)
    Tcl_Interp *interp;		/* Interpreter in which command is
				 * to be invoked. */
    int objc;			/* Count of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument value objects; objv[0]
				 * points to the name of the
				 * command to invoke. */
    int flags;			/* Combination of flags controlling
                                 * the call: TCL_INVOKE_HIDDEN and
                                 * TCL_INVOKE_NO_UNKNOWN. */

{
    register Interp *iPtr = (Interp *) interp;
    Tcl_HashTable *hTblPtr;	/* Table of hidden commands. */
    char *cmdName;		/* Name of the command from objv[0]. */
    register Tcl_HashEntry *hPtr;
    Tcl_Command cmd;
    Command *cmdPtr;







|
|

|
<
|
|
|
|
>







3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334

3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
 *	Whatever the command does.
 *
 *----------------------------------------------------------------------
 */

int
TclObjInvoke(interp, objc, objv, flags)
    Tcl_Interp *interp;		/* Interpreter in which command is to be
				 * invoked. */
    int objc;			/* Count of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects; objv[0] points to the

				 * name of the command to invoke. */
    int flags;			/* Combination of flags controlling the
				 * call: TCL_INVOKE_HIDDEN,
				 * TCL_INVOKE_NO_UNKNOWN, or
				 * TCL_INVOKE_NO_TRACEBACK. */
{
    register Interp *iPtr = (Interp *) interp;
    Tcl_HashTable *hTblPtr;	/* Table of hidden commands. */
    char *cmdName;		/* Name of the command from objv[0]. */
    register Tcl_HashEntry *hPtr;
    Tcl_Command cmd;
    Command *cmdPtr;
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181



3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203

    if ((objc < 1) || (objv == (Tcl_Obj **) NULL)) {
        Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "illegal argument vector", -1);
        return TCL_ERROR;
    }

    /*
     * THE FOLLOWING CODE FAILS IF THE STRING REP CONTAINS NULLS.
     */
    
    cmdName = Tcl_GetStringFromObj(objv[0], (int *) NULL);
    if (flags & TCL_INVOKE_HIDDEN) {
        /*
         * Find the table of hidden commands; error out if none.
         */

        hTblPtr = (Tcl_HashTable *)
	        Tcl_GetAssocData(interp, "tclHiddenCmds", NULL);
        if (hTblPtr == (Tcl_HashTable *) NULL) {
            badhiddenCmdToken:



	    Tcl_ResetResult(interp);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		     "invalid hidden command name \"", cmdName, "\"",
		     (char *) NULL);
            return TCL_ERROR;
        }
        hPtr = Tcl_FindHashEntry(hTblPtr, cmdName);

        /*
         * We never invoke "unknown" for hidden commands.
         */
        
        if (hPtr == NULL) {
            goto badhiddenCmdToken;
        }
	cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
    } else {
	cmdPtr = NULL;
	cmd = Tcl_FindCommand(interp, cmdName,
	        (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
        if (cmd != (Tcl_Command) NULL) {
	    cmdPtr = (Command *) cmd;







<
<
<
<
|


|

|
|
|
|
<
>
>
>






<
<
<
<
<
<
<
<
<







3356
3357
3358
3359
3360
3361
3362




3363
3364
3365
3366
3367
3368
3369
3370
3371

3372
3373
3374
3375
3376
3377
3378
3379
3380









3381
3382
3383
3384
3385
3386
3387

    if ((objc < 1) || (objv == (Tcl_Obj **) NULL)) {
        Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "illegal argument vector", -1);
        return TCL_ERROR;
    }





    cmdName = Tcl_GetString(objv[0]);
    if (flags & TCL_INVOKE_HIDDEN) {
        /*
         * We never invoke "unknown" for hidden commands.
         */
        
	hPtr = NULL;
        hTblPtr = ((Interp *) interp)->hiddenCmdTablePtr;
        if (hTblPtr != NULL) {

	    hPtr = Tcl_FindHashEntry(hTblPtr, cmdName);
	}
	if (hPtr == NULL) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		     "invalid hidden command name \"", cmdName, "\"",
		     (char *) NULL);
            return TCL_ERROR;
        }









	cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
    } else {
	cmdPtr = NULL;
	cmd = Tcl_FindCommand(interp, cmdName,
	        (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
        if (cmd != (Tcl_Command) NULL) {
	    cmdPtr = (Command *) cmd;
3250
3251
3252
3253
3254
3255
3256
3257


3258
3259
3260
3261
3262
3263
3264
    result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);

    /*
     * If an error occurred, record information about what was being
     * executed when the error occurred.
     */

    if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {


        Tcl_DString ds;
        
        Tcl_DStringInit(&ds);
        if (!(iPtr->flags & ERR_IN_PROGRESS)) {
            Tcl_DStringAppend(&ds, "\n    while invoking\n\"", -1);
        } else {
            Tcl_DStringAppend(&ds, "\n    invoked from within\n\"", -1);







|
>
>







3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
    result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);

    /*
     * If an error occurred, record information about what was being
     * executed when the error occurred.
     */

    if ((result == TCL_ERROR)
	    && ((flags & TCL_INVOKE_NO_TRACEBACK) == 0)
	    && ((iPtr->flags & ERR_ALREADY_LOGGED) == 0)) {
        Tcl_DString ds;
        
        Tcl_DStringInit(&ds);
        if (!(iPtr->flags & ERR_IN_PROGRESS)) {
            Tcl_DStringAppend(&ds, "\n    while invoking\n\"", -1);
        } else {
            Tcl_DStringAppend(&ds, "\n    invoked from within\n\"", -1);
3282
3283
3284
3285
3286
3287
3288

3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
    }

    /*
     * Free any locally allocated storage used to call "unknown".
     */

    if (localObjv != (Tcl_Obj **) NULL) {

        ckfree((char *) localObjv);
    }
    return result;
}

/*
 *--------------------------------------------------------------
 *
 * Tcl_ExprString --
 *
 *	Evaluate an expression in a string and return its value in string
 *	form.
 *
 * Results:
 *	A standard Tcl result. If the result is TCL_OK, then the
 *	interpreter's result is set to the string value of the
 *	expression. If the result is TCL_OK, then interp->result
 *	contains an error message.
 *
 * Side effects:
 *	A Tcl object is allocated to hold a copy of the expression string.
 *	This expression object is passed to Tcl_ExprObj and then
 *	deallocated.
 *
 *--------------------------------------------------------------
 */

int
Tcl_ExprString(interp, string)
    Tcl_Interp *interp;		/* Context in which to evaluate the
				 * expression. */
    char *string;		/* Expression to evaluate. */
{
    register Tcl_Obj *exprPtr;
    Tcl_Obj *resultPtr;
    int length = strlen(string);
    char buf[100];
    int result = TCL_OK;

    if (length > 0) {
	TclNewObj(exprPtr);
	TclInitStringRep(exprPtr, string, length);
	Tcl_IncrRefCount(exprPtr);








>






|







|
|
<
|






|











|







3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491

3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
    }

    /*
     * Free any locally allocated storage used to call "unknown".
     */

    if (localObjv != (Tcl_Obj **) NULL) {
	Tcl_DecrRefCount(localObjv[0]);
        ckfree((char *) localObjv);
    }
    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_ExprString --
 *
 *	Evaluate an expression in a string and return its value in string
 *	form.
 *
 * Results:
 *	A standard Tcl result. If the result is TCL_OK, then the interp's
 *	result is set to the string value of the expression. If the result

 *	is TCL_ERROR, then the interp's result contains an error message.
 *
 * Side effects:
 *	A Tcl object is allocated to hold a copy of the expression string.
 *	This expression object is passed to Tcl_ExprObj and then
 *	deallocated.
 *
 *---------------------------------------------------------------------------
 */

int
Tcl_ExprString(interp, string)
    Tcl_Interp *interp;		/* Context in which to evaluate the
				 * expression. */
    char *string;		/* Expression to evaluate. */
{
    register Tcl_Obj *exprPtr;
    Tcl_Obj *resultPtr;
    int length = strlen(string);
    char buf[TCL_DOUBLE_SPACE];
    int result = TCL_OK;

    if (length > 0) {
	TclNewObj(exprPtr);
	TclInitStringRep(exprPtr, string, length);
	Tcl_IncrRefCount(exprPtr);

3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
	    } else if (resultPtr->typePtr == &tclDoubleType) {
		Tcl_PrintDouble((Tcl_Interp *) NULL,
		        resultPtr->internalRep.doubleValue, buf);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    } else {
		/*
		 * Set interpreter's string result from the result object.
		 * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
		 */
	    
		Tcl_SetResult(interp,
	                TclGetStringFromObj(resultPtr, (int *) NULL),
	                TCL_VOLATILE);
	    }
	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
	} else {
	    /*
	     * Move the interpreter's object result to the string result, 
	     * then reset the object result.
	     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
	     */
	    
	    Tcl_SetResult(interp,
	            TclGetStringFromObj(Tcl_GetObjResult(interp),
			    (int *) NULL),
	            TCL_VOLATILE);
	}
	Tcl_DecrRefCount(exprPtr); /* discard the expression object */
    } else {
	/*
	 * An empty string. Just set the interpreter's result to 0.
	 */







<


|
<
|






<


|
<
<







3528
3529
3530
3531
3532
3533
3534

3535
3536
3537

3538
3539
3540
3541
3542
3543
3544

3545
3546
3547


3548
3549
3550
3551
3552
3553
3554
	    } else if (resultPtr->typePtr == &tclDoubleType) {
		Tcl_PrintDouble((Tcl_Interp *) NULL,
		        resultPtr->internalRep.doubleValue, buf);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    } else {
		/*
		 * Set interpreter's string result from the result object.

		 */
	    
		Tcl_SetResult(interp, TclGetString(resultPtr),

		        TCL_VOLATILE);
	    }
	    Tcl_DecrRefCount(resultPtr);  /* discard the result object */
	} else {
	    /*
	     * Move the interpreter's object result to the string result, 
	     * then reset the object result.

	     */
	    
	    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),


	            TCL_VOLATILE);
	}
	Tcl_DecrRefCount(exprPtr); /* discard the expression object */
    } else {
	/*
	 * An empty string. Just set the interpreter's result to 0.
	 */
3409
3410
3411
3412
3413
3414
3415

3416
3417
3418
3419
3420
3421
3422
3423
3424


























3425
3426
3427
3428
3429
3430
3431
3432
3433




3434
3435
3436
3437
3438
3439






3440
3441

3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453


3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488

3489
3490



3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501



























3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522

3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533


3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
				 * expression to evaluate. */
    Tcl_Obj **resultPtrPtr;	/* Where the Tcl_Obj* that is the expression
				 * result is stored if no errors occur. */
{
    Interp *iPtr = (Interp *) interp;
    CompileEnv compEnv;		/* Compilation environment structure
				 * allocated in frame. */

    register ByteCode *codePtr = NULL;
    				/* Tcl Internal type of bytecode.
				 * Initialized to avoid compiler warning. */
    AuxData *auxDataPtr;
    Interp dummy;
    Tcl_Obj *saveObjPtr;
    char *string;
    int result;
    int i;



























    /*
     * Get the ByteCode from the object. If it exists, make sure it hasn't
     * been invalidated by, e.g., someone redefining a command with a
     * compile procedure (this might make the compiled code wrong). If
     * necessary, convert the object to be a ByteCode object and compile it.
     * Also, if the code was compiled in/for a different interpreter, we
     * recompile it.
     * THIS FAILS IF THE OBJECT'S STRING REP HAS A NULL BYTE.




     */

    if (objPtr->typePtr == &tclByteCodeType) {
	codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
	if ((codePtr->iPtr != iPtr)
	        || (codePtr->compileEpoch != iPtr->compileEpoch)) {






	    tclByteCodeType.freeIntRepProc(objPtr);
	    objPtr->typePtr = (Tcl_ObjType *) NULL;

	}
    }
    if (objPtr->typePtr != &tclByteCodeType) {
	int length;
	string = Tcl_GetStringFromObj(objPtr, &length);
	TclInitCompileEnv(interp, &compEnv, string);
	result = TclCompileExpr(interp, string, string + length,
		/*flags*/ 0, &compEnv);
	if (result == TCL_OK) {
	    /*
	     * If the expression yielded no instructions (e.g., was empty),
	     * push an integer zero object as the expressions's result.


	     */
	    
	    if (compEnv.codeNext == NULL) {
		int objIndex = TclObjIndexForString("0", 0,
			/*allocStrRep*/ 0, /*inHeap*/ 0, &compEnv);
		Tcl_Obj *objPtr = compEnv.objArrayPtr[objIndex];

		Tcl_InvalidateStringRep(objPtr);
		objPtr->internalRep.longValue = 0;
		objPtr->typePtr = &tclIntType;
		
		TclEmitPush(objIndex, &compEnv);
	    }
	    
	    /*
	     * Add done instruction at the end of the instruction sequence.
	     */
	    
	    TclEmitOpcode(INST_DONE, &compEnv);
	    
	    TclInitByteCodeObj(objPtr, &compEnv);
	    codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
	    if (tclTraceCompile == 2) {
		TclPrintByteCodeObj(interp, objPtr);
	    }
	    TclFreeCompileEnv(&compEnv);
	} else {
	    /*
	     * Compilation errors. Decrement the ref counts on any objects
	     * in the object array before freeing the compilation
	     * environment.
	     */
	    
	    for (i = 0;  i < compEnv.objArrayNext;  i++) {
		Tcl_Obj *elemPtr = compEnv.objArrayPtr[i];

		Tcl_DecrRefCount(elemPtr);
	    }




	    auxDataPtr = compEnv.auxDataArrayPtr;
	    for (i = 0;  i < compEnv.auxDataArrayNext;  i++) {
		if (auxDataPtr->freeProc != NULL) {
		    auxDataPtr->freeProc(auxDataPtr->clientData);
		}
		auxDataPtr++;
	    }
	    TclFreeCompileEnv(&compEnv);
	    return result;
	}



























    }

    /*
     * Execute the expression after first saving the interpreter's result.
     */
    
    dummy.objResultPtr = Tcl_NewObj();
    Tcl_IncrRefCount(dummy.objResultPtr);
    if (interp->freeProc == 0) {
	dummy.freeProc = (Tcl_FreeProc *) 0;
	dummy.result = "";
	Tcl_SetResult((Tcl_Interp *) &dummy, interp->result,
	        TCL_VOLATILE);
    } else {
	dummy.freeProc = interp->freeProc;
	dummy.result = interp->result;
	interp->freeProc = (Tcl_FreeProc *) 0;
    }
    
    saveObjPtr = Tcl_GetObjResult(interp);
    Tcl_IncrRefCount(saveObjPtr);

    
    /*
     * Increment the code's ref count while it is being executed. If
     * afterwards no references to it remain, free the code.
     */
    
    codePtr->refCount++;
    result = TclExecuteByteCode(interp, codePtr);
    codePtr->refCount--;
    if (codePtr->refCount <= 0) {
	TclCleanupByteCode(codePtr);


    }
    
    /*
     * If the expression evaluated successfully, store a pointer to its
     * value object in resultPtrPtr then restore the old interpreter result.
     * We increment the object's ref count to reflect the reference that we
     * are returning to the caller. We also decrement the ref count of the
     * interpreter's result object after calling Tcl_SetResult since we
     * next store into that field directly.
     */
    
    if (result == TCL_OK) {
	*resultPtrPtr = iPtr->objResultPtr;
	Tcl_IncrRefCount(iPtr->objResultPtr);
	
	Tcl_SetResult(interp, dummy.result,
	        ((dummy.freeProc == 0) ? TCL_VOLATILE : dummy.freeProc));
	Tcl_DecrRefCount(iPtr->objResultPtr);
	iPtr->objResultPtr = saveObjPtr;
    } else {
	Tcl_DecrRefCount(saveObjPtr);
	Tcl_FreeResult((Tcl_Interp *) &dummy);
    }

    Tcl_DecrRefCount(dummy.objResultPtr);
    dummy.objResultPtr = NULL;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateTrace --







>




|


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








<
>
>
>
>




|

>
>
>
>
>
>
|
|
>



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

|

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

>
>
>
|


|
|






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






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


>
|










>
>















|
<
<
<
<
<
<

<
|
<







3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640

3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662


3663
3664
3665

3666


3667
3668
3669
3670




3671


3672
3673

3674
3675
3676
3677
3678
3679

3680





3681

3682




3683
3684

3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734













3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766






3767

3768

3769
3770
3771
3772
3773
3774
3775
				 * expression to evaluate. */
    Tcl_Obj **resultPtrPtr;	/* Where the Tcl_Obj* that is the expression
				 * result is stored if no errors occur. */
{
    Interp *iPtr = (Interp *) interp;
    CompileEnv compEnv;		/* Compilation environment structure
				 * allocated in frame. */
    LiteralTable *localTablePtr = &(compEnv.localLitTable);
    register ByteCode *codePtr = NULL;
    				/* Tcl Internal type of bytecode.
				 * Initialized to avoid compiler warning. */
    AuxData *auxDataPtr;
    LiteralEntry *entryPtr;
    Tcl_Obj *saveObjPtr;
    char *string;
    int length, i, result;

    /*
     * First handle some common expressions specially.
     */

    string = Tcl_GetStringFromObj(objPtr, &length);
    if (length == 1) {
	if (*string == '0') {
	    *resultPtrPtr = Tcl_NewLongObj(0);
	    Tcl_IncrRefCount(*resultPtrPtr);
	    return TCL_OK;
	} else if (*string == '1') {
	    *resultPtrPtr = Tcl_NewLongObj(1);
	    Tcl_IncrRefCount(*resultPtrPtr);
	    return TCL_OK;
	}
    } else if ((length == 2) && (*string == '!')) {
	if (*(string+1) == '0') {
	    *resultPtrPtr = Tcl_NewLongObj(1);
	    Tcl_IncrRefCount(*resultPtrPtr);
	    return TCL_OK;
	} else if (*(string+1) == '1') {
	    *resultPtrPtr = Tcl_NewLongObj(0);
	    Tcl_IncrRefCount(*resultPtrPtr);
	    return TCL_OK;
	}
    }

    /*
     * Get the ByteCode from the object. If it exists, make sure it hasn't
     * been invalidated by, e.g., someone redefining a command with a
     * compile procedure (this might make the compiled code wrong). If
     * necessary, convert the object to be a ByteCode object and compile it.
     * Also, if the code was compiled in/for a different interpreter, we
     * recompile it.

     *
     * Precompiled expressions, however, are immutable and therefore
     * they are not recompiled, even if the epoch has changed.
     *
     */

    if (objPtr->typePtr == &tclByteCodeType) {
	codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
	if (((Interp *) *codePtr->interpHandle != iPtr)
	        || (codePtr->compileEpoch != iPtr->compileEpoch)) {
            if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
                if ((Interp *) *codePtr->interpHandle != iPtr) {
                    panic("Tcl_ExprObj: compiled expression jumped interps");
                }
	        codePtr->compileEpoch = iPtr->compileEpoch;
            } else {
                (*tclByteCodeType.freeIntRepProc)(objPtr);
                objPtr->typePtr = (Tcl_ObjType *) NULL;
            }
	}
    }
    if (objPtr->typePtr != &tclByteCodeType) {


	TclInitCompileEnv(interp, &compEnv, string, length);
	result = TclCompileExpr(interp, string, length, &compEnv);


	/*


	 * Free the compilation environment's literal table bucket array if
	 * it was dynamically allocated. 
	 */





	if (localTablePtr->buckets != localTablePtr->staticBuckets) {


	    ckfree((char *) localTablePtr->buckets);
	}

    
	if (result != TCL_OK) {
	    /*
	     * Compilation errors. Free storage allocated for compilation.
	     */


#ifdef TCL_COMPILE_DEBUG





	    TclVerifyLocalLiteralTable(&compEnv);

#endif /*TCL_COMPILE_DEBUG*/




	    entryPtr = compEnv.literalArrayPtr;
	    for (i = 0;  i < compEnv.literalArrayNext;  i++) {

		TclReleaseLiteral(interp, entryPtr->objPtr);
		entryPtr++;
	    }
#ifdef TCL_COMPILE_DEBUG
	    TclVerifyGlobalLiteralTable(iPtr);
#endif /*TCL_COMPILE_DEBUG*/
    
	    auxDataPtr = compEnv.auxDataArrayPtr;
	    for (i = 0;  i < compEnv.auxDataArrayNext;  i++) {
		if (auxDataPtr->type->freeProc != NULL) {
		    auxDataPtr->type->freeProc(auxDataPtr->clientData);
		}
		auxDataPtr++;
	    }
	    TclFreeCompileEnv(&compEnv);
	    return result;
	}

	/*
	 * Successful compilation. If the expression yielded no
	 * instructions, push an zero object as the expression's result.
	 */
	    
	if (compEnv.codeNext == compEnv.codeStart) {
	    TclEmitPush(TclRegisterLiteral(&compEnv, "0", 1, /*onHeap*/ 0),
	            &compEnv);
	}
	    
	/*
	 * Add a "done" instruction as the last instruction and change the
	 * object into a ByteCode object. Ownership of the literal objects
	 * and aux data items is given to the ByteCode object.
	 */

	compEnv.numSrcBytes = iPtr->termOffset;
	TclEmitOpcode(INST_DONE, &compEnv);
	TclInitByteCodeObj(objPtr, &compEnv);
	TclFreeCompileEnv(&compEnv);
	codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
#ifdef TCL_COMPILE_DEBUG
	if (tclTraceCompile == 2) {
	    TclPrintByteCodeObj(interp, objPtr);
	}
#endif /* TCL_COMPILE_DEBUG */
    }

    /*
     * Execute the expression after first saving the interpreter's result.
     */
    













    saveObjPtr = Tcl_GetObjResult(interp);
    Tcl_IncrRefCount(saveObjPtr);
    Tcl_ResetResult(interp);

    /*
     * Increment the code's ref count while it is being executed. If
     * afterwards no references to it remain, free the code.
     */
    
    codePtr->refCount++;
    result = TclExecuteByteCode(interp, codePtr);
    codePtr->refCount--;
    if (codePtr->refCount <= 0) {
	TclCleanupByteCode(codePtr);
	objPtr->typePtr = NULL;
	objPtr->internalRep.otherValuePtr = NULL;
    }
    
    /*
     * If the expression evaluated successfully, store a pointer to its
     * value object in resultPtrPtr then restore the old interpreter result.
     * We increment the object's ref count to reflect the reference that we
     * are returning to the caller. We also decrement the ref count of the
     * interpreter's result object after calling Tcl_SetResult since we
     * next store into that field directly.
     */
    
    if (result == TCL_OK) {
	*resultPtrPtr = iPtr->objResultPtr;
	Tcl_IncrRefCount(iPtr->objResultPtr);
	
	Tcl_SetObjResult(interp, saveObjPtr);






    }

    Tcl_DecrRefCount(saveObjPtr);

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateTrace --
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
 *----------------------------------------------------------------------
 */

void
Tcl_AddErrorInfo(interp, message)
    Tcl_Interp *interp;		/* Interpreter to which error information
				 * pertains. */
    char *message;		/* Message to record. */
{
    Tcl_AddObjErrorInfo(interp, message, -1);
}

/*
 *----------------------------------------------------------------------
 *







|







3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
 *----------------------------------------------------------------------
 */

void
Tcl_AddErrorInfo(interp, message)
    Tcl_Interp *interp;		/* Interpreter to which error information
				 * pertains. */
    CONST char *message;	/* Message to record. */
{
    Tcl_AddObjErrorInfo(interp, message, -1);
}

/*
 *----------------------------------------------------------------------
 *
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
 *----------------------------------------------------------------------
 */

void
Tcl_AddObjErrorInfo(interp, message, length)
    Tcl_Interp *interp;		/* Interpreter to which error information
				 * pertains. */
    char *message;		/* Points to the first byte of an array of
				 * bytes of the message. */
    register int length;	/* The number of bytes in the message.
				 * If < 0, then append all bytes up to a
				 * NULL byte. */
{
    register Interp *iPtr = (Interp *) interp;
    Tcl_Obj *namePtr, *messagePtr;
    
    /*
     * If we are just starting to log an error, errorInfo is initialized
     * from the error message in the interpreter's result.
     */

    namePtr = Tcl_NewStringObj("errorInfo", -1);
    Tcl_IncrRefCount(namePtr);
    
    if (!(iPtr->flags & ERR_IN_PROGRESS)) { /* just starting to log error */
	iPtr->flags |= ERR_IN_PROGRESS;

	if (iPtr->result[0] == 0) {
	    (void) Tcl_ObjSetVar2(interp, namePtr, (Tcl_Obj *) NULL,
	            iPtr->objResultPtr, TCL_GLOBAL_ONLY);
	} else {		/* use the string result */
	    Tcl_SetVar2(interp, "errorInfo", (char *) NULL, interp->result,
		    TCL_GLOBAL_ONLY);
	}

	/*
	 * If the errorCode variable wasn't set by the code that generated







|

|




|






<
<
<




|
|







3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968



3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
 *----------------------------------------------------------------------
 */

void
Tcl_AddObjErrorInfo(interp, message, length)
    Tcl_Interp *interp;		/* Interpreter to which error information
				 * pertains. */
    CONST char *message;	/* Points to the first byte of an array of
				 * bytes of the message. */
    int length;			/* The number of bytes in the message.
				 * If < 0, then append all bytes up to a
				 * NULL byte. */
{
    register Interp *iPtr = (Interp *) interp;
    Tcl_Obj *messagePtr;
    
    /*
     * If we are just starting to log an error, errorInfo is initialized
     * from the error message in the interpreter's result.
     */




    if (!(iPtr->flags & ERR_IN_PROGRESS)) { /* just starting to log error */
	iPtr->flags |= ERR_IN_PROGRESS;

	if (iPtr->result[0] == 0) {
	    (void) Tcl_SetVar2Ex(interp, "errorInfo", NULL, iPtr->objResultPtr,
		    TCL_GLOBAL_ONLY);
	} else {		/* use the string result */
	    Tcl_SetVar2(interp, "errorInfo", (char *) NULL, interp->result,
		    TCL_GLOBAL_ONLY);
	}

	/*
	 * If the errorCode variable wasn't set by the code that generated
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797














































3798
3799
3800
3801
3802
3803
3804
    /*
     * Now append "message" to the end of errorInfo.
     */

    if (length != 0) {
	messagePtr = Tcl_NewStringObj(message, length);
	Tcl_IncrRefCount(messagePtr);
	Tcl_ObjSetVar2(interp, namePtr, (Tcl_Obj *) NULL, messagePtr,
		(TCL_GLOBAL_ONLY | TCL_APPEND_VALUE));
	Tcl_DecrRefCount(messagePtr); /* free msg object appended above */
    }

    Tcl_DecrRefCount(namePtr);    /* free the name object */














































}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_VarEval --
 *







|



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







3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
    /*
     * Now append "message" to the end of errorInfo.
     */

    if (length != 0) {
	messagePtr = Tcl_NewStringObj(message, length);
	Tcl_IncrRefCount(messagePtr);
	Tcl_SetVar2Ex(interp, "errorInfo", NULL, messagePtr,
		(TCL_GLOBAL_ONLY | TCL_APPEND_VALUE));
	Tcl_DecrRefCount(messagePtr); /* free msg object appended above */
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_VarEvalVA --
 *
 *	Given a variable number of string arguments, concatenate them
 *	all together and execute the result as a Tcl command.
 *
 * Results:
 *	A standard Tcl return result.  An error message or other result may
 *	be left in the interp's result.
 *
 * Side effects:
 *	Depends on what was done by the command.
 *
 *---------------------------------------------------------------------------
 */

int
Tcl_VarEvalVA (interp, argList)
    Tcl_Interp *interp;		/* Interpreter in which to evaluate command. */
    va_list argList;		/* Variable argument list. */
{
    Tcl_DString buf;
    char *string;
    int result;

    /*
     * Copy the strings one after the other into a single larger
     * string.  Use stack-allocated space for small commands, but if
     * the command gets too large than call ckalloc to create the
     * space.
     */

    Tcl_DStringInit(&buf);
    while (1) {
	string = va_arg(argList, char *);
	if (string == NULL) {
	    break;
	}
	Tcl_DStringAppend(&buf, string, -1);
    }

    result = Tcl_Eval(interp, Tcl_DStringValue(&buf));
    Tcl_DStringFree(&buf);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_VarEval --
 *
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824

3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
 *
 *----------------------------------------------------------------------
 */
	/* VARARGS2 */ /* ARGSUSED */
int
Tcl_VarEval TCL_VARARGS_DEF(Tcl_Interp *,arg1)
{
    va_list argList;
    Tcl_DString buf;
    char *string;
    Tcl_Interp *interp;

    int result;

    /*
     * Copy the strings one after the other into a single larger
     * string.  Use stack-allocated space for small commands, but if
     * the command gets too large than call ckalloc to create the
     * space.
     */

    interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
    Tcl_DStringInit(&buf);
    while (1) {
	string = va_arg(argList, char *);
	if (string == NULL) {
	    break;
	}
	Tcl_DStringAppend(&buf, string, -1);
    }
    va_end(argList);

    result = Tcl_Eval(interp, Tcl_DStringValue(&buf));
    Tcl_DStringFree(&buf);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GlobalEval --
 *
 *	Evaluate a command at global level in an interpreter.
 *
 * Results:
 *	A standard Tcl result is returned, and interp->result is
 *	modified accordingly.
 *
 * Side effects:
 *	The command string is executed in interp, and the execution
 *	is carried out in the variable context of global level (no
 *	procedures active), just as if an "uplevel #0" command were
 *	being executed.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GlobalEval(interp, command)
    Tcl_Interp *interp;		/* Interpreter in which to evaluate command. */
    char *command;		/* Command to evaluate. */
{
    register Interp *iPtr = (Interp *) interp;
    int result;
    CallFrame *savedVarFramePtr;

    savedVarFramePtr = iPtr->varFramePtr;
    iPtr->varFramePtr = NULL;
    result = Tcl_Eval(interp, command);
    iPtr->varFramePtr = savedVarFramePtr;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GlobalEvalObj --
 *
 *	Execute Tcl commands stored in a Tcl object at global level in
 *	an interpreter. These commands are compiled into bytecodes if
 *	necessary.
 *
 * Results:
 *	A standard Tcl result is returned, and the interpreter's result
 *	contains a Tcl object value to supplement the return code.
 *
 * Side effects:
 *	The object is converted, if necessary, to a ByteCode object that
 *	holds the bytecode instructions for the commands. Executing the
 *	commands will almost certainly have side effects that depend on
 *	those commands.
 *
 *	The commands are executed in interp, and the execution
 *	is carried out in the variable context of global level (no
 *	procedures active), just as if an "uplevel #0" command were
 *	being executed.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GlobalEvalObj(interp, objPtr)
    Tcl_Interp *interp;		/* Interpreter in which to evaluate
				 * commands. */
    Tcl_Obj *objPtr;		/* Pointer to object containing commands
				 * to execute. */
{
    register Interp *iPtr = (Interp *) interp;
    int result;
    CallFrame *savedVarFramePtr;

    savedVarFramePtr = iPtr->varFramePtr;
    iPtr->varFramePtr = NULL;
    result = Tcl_EvalObj(interp, objPtr);
    iPtr->varFramePtr = savedVarFramePtr;
    return result;
}

/*
 *----------------------------------------------------------------------
 *







<
<
<

>


<
<
<
<
<
<
<

<
<
|
<
<
<
<
<


<
<




|






|








|














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







4066
4067
4068
4069
4070
4071
4072



4073
4074
4075
4076







4077


4078





4079
4080


4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115













































4116
4117
4118
4119
4120
4121
4122
 *
 *----------------------------------------------------------------------
 */
	/* VARARGS2 */ /* ARGSUSED */
int
Tcl_VarEval TCL_VARARGS_DEF(Tcl_Interp *,arg1)
{



    Tcl_Interp *interp;
    va_list argList;
    int result;








    interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);


    result = Tcl_VarEvalVA(interp, argList);





    va_end(argList);



    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_GlobalEval --
 *
 *	Evaluate a command at global level in an interpreter.
 *
 * Results:
 *	A standard Tcl result is returned, and the interp's result is
 *	modified accordingly.
 *
 * Side effects:
 *	The command string is executed in interp, and the execution
 *	is carried out in the variable context of global level (no
 *	procedures active), just as if an "uplevel #0" command were
 *	being executed.
 *
 ---------------------------------------------------------------------------
 */

int
Tcl_GlobalEval(interp, command)
    Tcl_Interp *interp;		/* Interpreter in which to evaluate command. */
    char *command;		/* Command to evaluate. */
{
    register Interp *iPtr = (Interp *) interp;
    int result;
    CallFrame *savedVarFramePtr;

    savedVarFramePtr = iPtr->varFramePtr;
    iPtr->varFramePtr = NULL;
    result = Tcl_Eval(interp, command);













































    iPtr->varFramePtr = savedVarFramePtr;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
3986
3987
3988
3989
3990
3991
3992







































    Tcl_Interp *interp;		/* Interpreter in which to set flag. */
{
    Interp *iPtr = (Interp *) interp;

    iPtr->evalFlags |= TCL_ALLOW_EXCEPTIONS;
}















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
    Tcl_Interp *interp;		/* Interpreter in which to set flag. */
{
    Interp *iPtr = (Interp *) interp;

    iPtr->evalFlags |= TCL_ALLOW_EXCEPTIONS;
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetVersion
 *
 *	Get the Tcl major, minor, and patchlevel version numbers and
 *      the release type.  A patch is a release type TCL_FINAL_RELEASE
 *      with a patchLevel > 0.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void Tcl_GetVersion(major, minor, patchLevel, type)
    int *major;
    int *minor;
    int *patchLevel;
    int *type;
{
    if (major != NULL) {
        *major = TCL_MAJOR_VERSION;
    }
    if (minor != NULL) {
        *minor = TCL_MINOR_VERSION;
    }
    if (patchLevel != NULL) {
        *patchLevel = TCL_RELEASE_SERIAL;
    }
    if (type != NULL) {
        *type = TCL_RELEASE_LEVEL;
    }
}
 

Changes to generic/tclBinary.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
/* 
 * tclBinary.c --
 *
 *	This file contains the implementation of the "binary" Tcl built-in
 *	command .
 *
 * 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.
 *
 * SCCS: @(#) tclBinary.c 1.26 97/11/05 13:02:05
 */

#include <math.h>
#include "tclInt.h"
#include "tclPort.h"

/*
 * The following constants are used by GetFormatSpec to indicate various
 * special conditions in the parsing of a format specifier.
 */

#define BINARY_ALL -1		/* Use all elements in the argument. */
#define BINARY_NOCOUNT -2	/* No count was specified in format. */

/*
 * Prototypes for local procedures defined in this file:
 */






static int		GetFormatSpec _ANSI_ARGS_((char **formatPtr,
			    char *cmdPtr, int *countPtr));

static int		FormatNumber _ANSI_ARGS_((Tcl_Interp *interp, int type,























































































































































































































































			    Tcl_Obj *src, char **cursorPtr));


static Tcl_Obj *	ScanNumber _ANSI_ARGS_((char *buffer, int type));








































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * Tcl_BinaryObjCmd --
 *
 *	This procedure implements the "binary" Tcl command.




|


>




|


















>
>
>
>
>


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







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

#include <math.h>
#include "tclInt.h"
#include "tclPort.h"

/*
 * The following constants are used by GetFormatSpec to indicate various
 * special conditions in the parsing of a format specifier.
 */

#define BINARY_ALL -1		/* Use all elements in the argument. */
#define BINARY_NOCOUNT -2	/* No count was specified in format. */

/*
 * Prototypes for local procedures defined in this file:
 */

static void		DupByteArrayInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
			    Tcl_Obj *copyPtr));
static int		FormatNumber _ANSI_ARGS_((Tcl_Interp *interp, int type,
			    Tcl_Obj *src, unsigned char **cursorPtr));
static void		FreeByteArrayInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr));
static int		GetFormatSpec _ANSI_ARGS_((char **formatPtr,
			    char *cmdPtr, int *countPtr));
static Tcl_Obj *	ScanNumber _ANSI_ARGS_((unsigned char *buffer, int type));
static int		SetByteArrayFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
static void		UpdateStringOfByteArray _ANSI_ARGS_((Tcl_Obj *listPtr));


/*
 * The following object type represents an array of bytes.  An array of
 * bytes is not equivalent to an internationalized string.  Conceptually, a
 * string is an array of 16-bit quantities organized as a sequence of properly
 * formed UTF-8 characters, while a ByteArray is an array of 8-bit quantities.
 * Accessor functions are provided to convert a ByteArray to a String or a
 * String to a ByteArray.  Two or more consecutive bytes in an array of bytes
 * may look like a single UTF-8 character if the array is casually treated as
 * a string.  But obtaining the String from a ByteArray is guaranteed to
 * produced properly formed UTF-8 sequences so that there is a one-to-one
 * map between bytes and characters.
 *
 * Converting a ByteArray to a String proceeds by casting each byte in the
 * array to a 16-bit quantity, treating that number as a Unicode character,
 * and storing the UTF-8 version of that Unicode character in the String.
 * For ByteArrays consisting entirely of values 1..127, the corresponding
 * String representation is the same as the ByteArray representation.
 *
 * Converting a String to a ByteArray proceeds by getting the Unicode
 * representation of each character in the String, casting it to a
 * byte by truncating the upper 8 bits, and then storing the byte in the
 * ByteArray.  Converting from ByteArray to String and back to ByteArray
 * is not lossy, but converting an arbitrary String to a ByteArray may be.
 */

Tcl_ObjType tclByteArrayType = {
    "bytearray",
    FreeByteArrayInternalRep,
    DupByteArrayInternalRep,
    UpdateStringOfByteArray,
    SetByteArrayFromAny
};

/*
 * The following structure is the internal rep for a ByteArray object.
 * Keeps track of how much memory has been used and how much has been
 * allocated for the byte array to enable growing and shrinking of the
 * ByteArray object with fewer mallocs.  
 */

typedef struct ByteArray {
    int used;			/* The number of bytes used in the byte
				 * array. */
    int allocated;		/* The amount of space actually allocated
				 * minus 1 byte. */
    unsigned char bytes[4];	/* The array of bytes.  The actual size of
				 * this field depends on the 'allocated' field
				 * above. */
} ByteArray;

#define BYTEARRAY_SIZE(len)	\
		((unsigned) (sizeof(ByteArray) - 4 + (len)))
#define GET_BYTEARRAY(objPtr) \
		((ByteArray *) (objPtr)->internalRep.otherValuePtr)
#define SET_BYTEARRAY(objPtr, baPtr) \
		(objPtr)->internalRep.otherValuePtr = (VOID *) (baPtr)


/*
 *---------------------------------------------------------------------------
 *
 * Tcl_NewByteArrayObj --
 *
 *	This procedure is creates a new ByteArray object and initializes
 *	it from the given array of bytes.
 *
 * Results:
 *	The newly create object is returned.  This object will have no
 *	initial string representation.  The returned object has a ref count
 *	of 0.
 *
 * Side effects:
 *	Memory allocated for new object and copy of byte array argument.
 *
 *---------------------------------------------------------------------------
 */

#ifdef TCL_MEM_DEBUG
#undef Tcl_NewByteArrayObj


Tcl_Obj *
Tcl_NewByteArrayObj(bytes, length)
    unsigned char *bytes;	/* The array of bytes used to initialize
				 * the new object. */
    int length;			/* Length of the array of bytes, which must
				 * be >= 0. */
{
    return Tcl_DbNewByteArrayObj(bytes, length, "unknown", 0);
}

#else /* if not TCL_MEM_DEBUG */

Tcl_Obj *
Tcl_NewByteArrayObj(bytes, length)
    unsigned char *bytes;	/* The array of bytes used to initialize
				 * the new object. */
    int length;			/* Length of the array of bytes, which must
				 * be >= 0. */
{
    Tcl_Obj *objPtr;

    TclNewObj(objPtr);
    Tcl_SetByteArrayObj(objPtr, bytes, length);
    return objPtr;
}
#endif /* TCL_MEM_DEBUG */

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_DbNewByteArrayObj --
 *
 *	This procedure is normally called when debugging: i.e., when
 *	TCL_MEM_DEBUG is defined. It is the same as the Tcl_NewByteArrayObj
 *	above except that it calls Tcl_DbCkalloc directly with the file name
 *	and line number from its caller. This simplifies debugging since then
 *	the checkmem command will report the correct file name and line number
 *	when reporting objects that haven't been freed.
 *
 *	When TCL_MEM_DEBUG is not defined, this procedure just returns the
 *	result of calling Tcl_NewByteArrayObj.
 *
 * Results:
 *	The newly create object is returned.  This object will have no
 *	initial string representation.  The returned object has a ref count
 *	of 0.
 *
 * Side effects:
 *	Memory allocated for new object and copy of byte array argument.
 *
 *---------------------------------------------------------------------------
 */

#ifdef TCL_MEM_DEBUG

Tcl_Obj *
Tcl_DbNewByteArrayObj(bytes, length, file, line)
    unsigned char *bytes;	/* The array of bytes used to initialize
				 * the new object. */
    int length;			/* Length of the array of bytes, which must
				 * be >= 0. */
    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
    int line;			/* Line number in the source file; used
				 * for debugging. */
{
    Tcl_Obj *objPtr;

    TclDbNewObj(objPtr, file, line);
    Tcl_SetByteArrayObj(objPtr, bytes, length);
    return objPtr;
}

#else /* if not TCL_MEM_DEBUG */

Tcl_Obj *
Tcl_DbNewByteArrayObj(bytes, length, file, line)
    unsigned char *bytes;	/* The array of bytes used to initialize
				 * the new object. */
    int length;			/* Length of the array of bytes, which must
				 * be >= 0. */
    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
    int line;			/* Line number in the source file; used
				 * for debugging. */
{
    return Tcl_NewByteArrayObj(bytes, length);
}
#endif /* TCL_MEM_DEBUG */

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_SetByteArrayObj --
 *
 *	Modify an object to be a ByteArray object and to have the specified
 *	array of bytes as its value.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object's old string rep and internal rep is freed.
 *	Memory allocated for copy of byte array argument.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetByteArrayObj(objPtr, bytes, length)
    Tcl_Obj *objPtr;		/* Object to initialize as a ByteArray. */
    unsigned char *bytes;	/* The array of bytes to use as the new
				 * value. */
    int length;			/* Length of the array of bytes, which must
				 * be >= 0. */
{
    Tcl_ObjType *typePtr;
    ByteArray *byteArrayPtr;

    if (Tcl_IsShared(objPtr)) {
	panic("Tcl_SetByteArrayObj called with shared object");
    }
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }
    Tcl_InvalidateStringRep(objPtr);

    byteArrayPtr = (ByteArray *) ckalloc(BYTEARRAY_SIZE(length));
    byteArrayPtr->used = length;
    byteArrayPtr->allocated = length;
    memcpy((VOID *) byteArrayPtr->bytes, (VOID *) bytes, (size_t) length);

    objPtr->typePtr = &tclByteArrayType;
    SET_BYTEARRAY(objPtr, byteArrayPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetByteArrayFromObj --
 *
 *	Attempt to get the array of bytes from the Tcl object.  If the
 *	object is not already a ByteArray object, an attempt will be
 *	made to convert it to one.
 *
 * Results:
 *	Pointer to array of bytes representing the ByteArray object.
 *
 * Side effects:
 *	Frees old internal rep.  Allocates memory for new internal rep.
 *
 *----------------------------------------------------------------------
 */

unsigned char *
Tcl_GetByteArrayFromObj(objPtr, lengthPtr)
    Tcl_Obj *objPtr;		/* The ByteArray object. */
    int *lengthPtr;		/* If non-NULL, filled with length of the
				 * array of bytes in the ByteArray object. */
{
    ByteArray *baPtr;
    
    SetByteArrayFromAny(NULL, objPtr);
    baPtr = GET_BYTEARRAY(objPtr);

    if (lengthPtr != NULL) {
	*lengthPtr = baPtr->used;
    }
    return (unsigned char *) baPtr->bytes;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetByteArrayLength --
 *
 *	This procedure changes the length of the byte array for this
 *	object.  Once the caller has set the length of the array, it
 *	is acceptable to directly modify the bytes in the array up until
 *	Tcl_GetStringFromObj() has been called on this object.
 *
 * Results:
 *	The new byte array of the specified length.
 *
 * Side effects:
 *	Allocates enough memory for an array of bytes of the requested
 *	size.  When growing the array, the old array is copied to the
 *	new array; new bytes are undefined.  When shrinking, the
 *	old array is truncated to the specified length.
 *
 *---------------------------------------------------------------------------
 */

unsigned char *
Tcl_SetByteArrayLength(objPtr, length)
    Tcl_Obj *objPtr;		/* The ByteArray object. */
    int length;			/* New length for internal byte array. */
{
    ByteArray *byteArrayPtr, *newByteArrayPtr;
    
    if (Tcl_IsShared(objPtr)) {
	panic("Tcl_SetObjLength called with shared object");
    }
    if (objPtr->typePtr != &tclByteArrayType) {
	SetByteArrayFromAny(NULL, objPtr);
    }

    byteArrayPtr = GET_BYTEARRAY(objPtr);
    if (length > byteArrayPtr->allocated) {
	newByteArrayPtr = (ByteArray *) ckalloc(BYTEARRAY_SIZE(length));
	newByteArrayPtr->used = length;
	newByteArrayPtr->allocated = length;
	memcpy((VOID *) newByteArrayPtr->bytes,
		(VOID *) byteArrayPtr->bytes, (size_t) byteArrayPtr->used);
	ckfree((char *) byteArrayPtr);
	byteArrayPtr = newByteArrayPtr;
	SET_BYTEARRAY(objPtr, byteArrayPtr);
    }
    Tcl_InvalidateStringRep(objPtr);
    byteArrayPtr->used = length;
    return byteArrayPtr->bytes;
}

/*
 *---------------------------------------------------------------------------
 *
 * SetByteArrayFromAny --
 *
 *	Generate the ByteArray internal rep from the string rep.
 *
 * Results:
 *	The return value is always TCL_OK.
 *
 * Side effects:
 *	A ByteArray object is stored as the internal rep of objPtr.
 *
 *---------------------------------------------------------------------------
 */

static int
SetByteArrayFromAny(interp, objPtr)
    Tcl_Interp *interp;		/* Not used. */
    Tcl_Obj *objPtr;		/* The object to convert to type ByteArray. */
{
    Tcl_ObjType *typePtr;
    int length;
    char *src, *srcEnd;
    unsigned char *dst;
    ByteArray *byteArrayPtr;
    Tcl_UniChar ch;
    
    typePtr = objPtr->typePtr;
    if (typePtr != &tclByteArrayType) {
	src = Tcl_GetStringFromObj(objPtr, &length);
	srcEnd = src + length;

	byteArrayPtr = (ByteArray *) ckalloc(BYTEARRAY_SIZE(length));
	for (dst = byteArrayPtr->bytes; src < srcEnd; ) {
	    src += Tcl_UtfToUniChar(src, &ch);
	    *dst++ = (unsigned char) ch;
	}

	byteArrayPtr->used = dst - byteArrayPtr->bytes;
	byteArrayPtr->allocated = length;

	if ((typePtr != NULL) && (typePtr->freeIntRepProc) != NULL) {
	    (*typePtr->freeIntRepProc)(objPtr);
	}
	objPtr->typePtr = &tclByteArrayType;
	SET_BYTEARRAY(objPtr, byteArrayPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeByteArrayInternalRep --
 *
 *	Deallocate the storage associated with a ByteArray data object's
 *	internal representation.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees memory. 
 *
 *----------------------------------------------------------------------
 */

static void
FreeByteArrayInternalRep(objPtr)
    Tcl_Obj *objPtr;		/* Object with internal rep to free. */
{
    ckfree((char *) GET_BYTEARRAY(objPtr));
}

/*
 *---------------------------------------------------------------------------
 *
 * DupByteArrayInternalRep --
 *
 *	Initialize the internal representation of a ByteArray Tcl_Obj
 *	to a copy of the internal representation of an existing ByteArray
 *	object. 
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates memory.
 *
 *---------------------------------------------------------------------------
 */

static void
DupByteArrayInternalRep(srcPtr, copyPtr)
    Tcl_Obj *srcPtr;		/* Object with internal rep to copy. */
    Tcl_Obj *copyPtr;		/* Object with internal rep to set. */
{
    int length;
    ByteArray *srcArrayPtr, *copyArrayPtr;    

    srcArrayPtr = GET_BYTEARRAY(srcPtr);
    length = srcArrayPtr->used;

    copyArrayPtr = (ByteArray *) ckalloc(BYTEARRAY_SIZE(length));
    copyArrayPtr->used = length;
    copyArrayPtr->allocated = length;
    memcpy((VOID *) copyArrayPtr->bytes, (VOID *) srcArrayPtr->bytes,
	    (size_t) length);
    SET_BYTEARRAY(copyPtr, copyArrayPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * UpdateStringOfByteArray --
 *
 *	Update the string representation for a ByteArray data object.
 *	Note: This procedure does not invalidate an existing old string rep
 *	so storage will be lost if this has not already been done. 
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object's string is set to a valid string that results from
 *	the ByteArray-to-string conversion.
 *
 *	The object becomes a string object -- the internal rep is
 *	discarded and the typePtr becomes NULL.
 *
 *---------------------------------------------------------------------------
 */

static void
UpdateStringOfByteArray(objPtr)
    Tcl_Obj *objPtr;		/* ByteArray object whose string rep to
				 * update. */
{
    int i, length, size;
    unsigned char *src;
    char *dst;
    ByteArray *byteArrayPtr;

    byteArrayPtr = GET_BYTEARRAY(objPtr);
    src = byteArrayPtr->bytes;
    length = byteArrayPtr->used;

    /*
     * How much space will string rep need?
     */
     
    size = length;
    for (i = 0; i < length; i++) {
	if ((src[i] == 0) || (src[i] > 127)) {
	    size++;
	}
    }

    dst = (char *) ckalloc((unsigned) (size + 1));
    objPtr->bytes = dst;
    objPtr->length = size;

    if (size == length) {
	memcpy((VOID *) dst, (VOID *) src, (size_t) size);
	dst[size] = '\0';
    } else {
	for (i = 0; i < length; i++) {
	    dst += Tcl_UniCharToUtf(src[i], dst);
	}
	*dst = '\0';
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_BinaryObjCmd --
 *
 *	This procedure implements the "binary" Tcl command.
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
    int value = 0;		/* Current integer value to be packed.
				 * Initialized to avoid compiler warning. */
    char cmd;			/* Current format character. */
    int count;			/* Count associated with current format
				 * character. */
    char *format;		/* Pointer to current position in format
				 * string. */


    char *cursor;		/* Current position within result buffer. */
    char *maxPos;		/* Greatest position within result buffer that
				 * cursor has visited.*/
    char *buffer;		/* Start of data buffer. */
    char *errorString, *errorValue, *str;
    int offset, size, length;
    Tcl_Obj *resultPtr;
    
    static char *subCmds[] = { "format", "scan", (char *) NULL };

    enum { BinaryFormat, BinaryScan } index;



    if (objc < 2) {
    	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], subCmds, "option", 0,
	    (int *) &index) != TCL_OK) {
    	return TCL_ERROR;
    }

    switch (index) {
	case BinaryFormat:
	    if (objc < 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "formatString ?arg arg ...?");
		return TCL_ERROR;
	    }

	    /*
	     * To avoid copying the data, we format the string in two passes.
	     * The first pass computes the size of the output buffer.  The
	     * second pass places the formatted data into the buffer.
	     */

	    format = Tcl_GetStringFromObj(objv[2], NULL);
	    arg = 3;
	    offset = length = 0;

	    while (*format != 0) {

		if (!GetFormatSpec(&format, &cmd, &count)) {
		    break;
		}
		switch (cmd) {
		    case 'a':
		    case 'A':
		    case 'b':
		    case 'B':
		    case 'h':
		    case 'H':
			/*
			 * For string-type specifiers, the count corresponds
			 * to the number of characters in a single argument.
			 */

			if (arg >= objc) {
			    goto badIndex;
			}
			if (count == BINARY_ALL) {
			    (void)Tcl_GetStringFromObj(objv[arg], &count);
			} else if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			arg++;
			if (cmd == 'a' || cmd == 'A') {
			    offset += count;
			} else if (cmd == 'b' || cmd == 'B') {
			    offset += (count + 7) / 8;
			} else {
			    offset += (count + 1) / 2;
			}
			break;

		    case 'c':
			size = 1;
			goto doNumbers;

		    case 's':
		    case 'S':
			size = 2;
			goto doNumbers;

		    case 'i':
		    case 'I':
			size = 4;
			goto doNumbers;

		    case 'f':
			size = sizeof(float);
			goto doNumbers;

		    case 'd':
			size = sizeof(double);

		    doNumbers:
			if (arg >= objc) {
			    goto badIndex;
			}

			/*
			 * For number-type specifiers, the count corresponds
			 * to the number of elements in the list stored in







>
>
|
|

<

|
<
|
|
>
|
>
>






|
|



|
|




>






|

|
>
|
>









|


|






|












|
|


>

|


>

|


>
|


>
|

>
|







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
    int value = 0;		/* Current integer value to be packed.
				 * Initialized to avoid compiler warning. */
    char cmd;			/* Current format character. */
    int count;			/* Count associated with current format
				 * character. */
    char *format;		/* Pointer to current position in format
				 * string. */
    Tcl_Obj *resultPtr;		/* Object holding result buffer. */
    unsigned char *buffer;	/* Start of result buffer. */
    unsigned char *cursor;	/* Current position within result buffer. */
    unsigned char *maxPos;	/* Greatest position within result buffer that
				 * cursor has visited.*/

    char *errorString, *errorValue, *str;
    int offset, size, length, index;

    static char *options[] = { 
	"format",	"scan",		NULL 
    };
    enum options { 
	BINARY_FORMAT,	BINARY_SCAN
    };

    if (objc < 2) {
    	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0,
	    &index) != TCL_OK) {
    	return TCL_ERROR;
    }

    switch ((enum options) index) {
	case BINARY_FORMAT: {
	    if (objc < 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "formatString ?arg arg ...?");
		return TCL_ERROR;
	    }

	    /*
	     * To avoid copying the data, we format the string in two passes.
	     * The first pass computes the size of the output buffer.  The
	     * second pass places the formatted data into the buffer.
	     */

	    format = Tcl_GetString(objv[2]);
	    arg = 3;
	    offset = 0;
	    length = 0;
	    while (*format != '\0') {
		str = format;
		if (!GetFormatSpec(&format, &cmd, &count)) {
		    break;
		}
		switch (cmd) {
		    case 'a':
		    case 'A':
		    case 'b':
		    case 'B':
		    case 'h':
		    case 'H': {
			/*
			 * For string-type specifiers, the count corresponds
			 * to the number of bytes in a single argument.
			 */

			if (arg >= objc) {
			    goto badIndex;
			}
			if (count == BINARY_ALL) {
			    Tcl_GetByteArrayFromObj(objv[arg], &count);
			} else if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			arg++;
			if (cmd == 'a' || cmd == 'A') {
			    offset += count;
			} else if (cmd == 'b' || cmd == 'B') {
			    offset += (count + 7) / 8;
			} else {
			    offset += (count + 1) / 2;
			}
			break;
		    }
		    case 'c': {
			size = 1;
			goto doNumbers;
		    }
		    case 's':
		    case 'S': {
			size = 2;
			goto doNumbers;
		    }
		    case 'i':
		    case 'I': {
			size = 4;
			goto doNumbers;
		    }
		    case 'f': {
			size = sizeof(float);
			goto doNumbers;
		    }
		    case 'd': {
			size = sizeof(double);
			
			doNumbers:
			if (arg >= objc) {
			    goto badIndex;
			}

			/*
			 * For number-type specifiers, the count corresponds
			 * to the number of elements in the list stored in
172
173
174
175
176
177
178

179
180


181
182
183
184
185
186
187

188
189


190
191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
			    if (Tcl_ListObjGetElements(interp, objv[arg++],
				    &listc, &listv) != TCL_OK) {
				return TCL_ERROR;
			    }
			    if (count == BINARY_ALL) {
				count = listc;
			    } else if (count > listc) {

				errorString = "number of elements in list does not match count";
				goto error;


			    }
			}
			offset += count*size;
			break;
			
		    case 'x':
			if (count == BINARY_ALL) {

			    errorString = "cannot use \"*\" in format string with \"x\"";
			    goto error;


			} else if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			offset += count;
			break;

		    case 'X':
			if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			if ((count > offset) || (count == BINARY_ALL)) {
			    count = offset;
			}
			if (offset > length) {
			    length = offset;
			}
			offset -= count;
			break;

		    case '@':
			if (offset > length) {
			    length = offset;
			}
			if (count == BINARY_ALL) {
			    offset = length;
			} else if (count == BINARY_NOCOUNT) {
			    goto badCount;
			} else {
			    offset = count;
			}
			break;
		    default: {
			char buf[2];
			
			Tcl_ResetResult(interp);
			buf[0] = cmd;
			buf[1] = '\0';
			Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
				"bad field specifier \"", buf, "\"", NULL);
			return TCL_ERROR;
		    }
		}
	    }
	    if (offset > length) {
		length = offset;
	    }
	    if (length == 0) {
		return TCL_OK;
	    }

	    /*
	     * Prepare the result object by preallocating the caclulated
	     * number of bytes and filling with nulls.
	     */

	    resultPtr = Tcl_GetObjResult(interp);
	    Tcl_SetObjLength(resultPtr, length);
	    buffer = Tcl_GetStringFromObj(resultPtr, NULL);
	    memset(buffer, 0, (size_t) length);

	    /*
	     * Pack the data into the result object.  Note that we can skip
	     * the error checking during this pass, since we have already
	     * parsed the string once.
	     */

	    arg = 3;
	    format = Tcl_GetStringFromObj(objv[2], NULL);
	    cursor = buffer;
	    maxPos = cursor;
	    while (*format != 0) {
		if (!GetFormatSpec(&format, &cmd, &count)) {
		    break;
		}
		if ((count == 0) && (cmd != '@')) {
		    arg++;
		    continue;
		}
		switch (cmd) {
		    case 'a':
		    case 'A': {
			char pad = (char) (cmd == 'a' ? '\0' : ' ');


			str = Tcl_GetStringFromObj(objv[arg++], &length);

			if (count == BINARY_ALL) {
			    count = length;
			} else if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			if (length >= count) {
			    memcpy((VOID *) cursor, (VOID *) str,
				    (size_t) count);
			} else {
			    memcpy((VOID *) cursor, (VOID *) str,
				    (size_t) length);
			    memset(cursor+length, pad,
			            (size_t) (count - length));
			}
			cursor += count;
			break;
		    }
		    case 'b':
		    case 'B': {
			char *last;
			
			str = Tcl_GetStringFromObj(objv[arg++], &length);
			if (count == BINARY_ALL) {
			    count = length;
			} else if (count == BINARY_NOCOUNT) {
			    count = 1;
			}







>
|
<
>
>




|
|

>
|
<
>
>





>
|











>
|











<
<
|
|
|
<
<
|
<
















|
<
|








|














>

|







|


|

|







|







670
671
672
673
674
675
676
677
678

679
680
681
682
683
684
685
686
687
688
689

690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722


723
724
725


726

727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743

744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
			    if (Tcl_ListObjGetElements(interp, objv[arg++],
				    &listc, &listv) != TCL_OK) {
				return TCL_ERROR;
			    }
			    if (count == BINARY_ALL) {
				count = listc;
			    } else if (count > listc) {
			        Tcl_AppendResult(interp, 
					"number of elements in list does not match count",

					(char *) NULL);
				return TCL_ERROR;
			    }
			}
			offset += count*size;
			break;
		    }
		    case 'x': {
			if (count == BINARY_ALL) {
			    Tcl_AppendResult(interp, 
				    "cannot use \"*\" in format string with \"x\"",

				    (char *) NULL);
			    return TCL_ERROR;
			} else if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			offset += count;
			break;
		    }
		    case 'X': {
			if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			if ((count > offset) || (count == BINARY_ALL)) {
			    count = offset;
			}
			if (offset > length) {
			    length = offset;
			}
			offset -= count;
			break;
		    }
		    case '@': {
			if (offset > length) {
			    length = offset;
			}
			if (count == BINARY_ALL) {
			    offset = length;
			} else if (count == BINARY_NOCOUNT) {
			    goto badCount;
			} else {
			    offset = count;
			}
			break;


		    }
		    default: {
			errorString = str;


			goto badfield;

		    }
		}
	    }
	    if (offset > length) {
		length = offset;
	    }
	    if (length == 0) {
		return TCL_OK;
	    }

	    /*
	     * Prepare the result object by preallocating the caclulated
	     * number of bytes and filling with nulls.
	     */

	    resultPtr = Tcl_GetObjResult(interp);
	    buffer = Tcl_SetByteArrayLength(resultPtr, length);

	    memset((VOID *) buffer, 0, (size_t) length);

	    /*
	     * Pack the data into the result object.  Note that we can skip
	     * the error checking during this pass, since we have already
	     * parsed the string once.
	     */

	    arg = 3;
	    format = Tcl_GetString(objv[2]);
	    cursor = buffer;
	    maxPos = cursor;
	    while (*format != 0) {
		if (!GetFormatSpec(&format, &cmd, &count)) {
		    break;
		}
		if ((count == 0) && (cmd != '@')) {
		    arg++;
		    continue;
		}
		switch (cmd) {
		    case 'a':
		    case 'A': {
			char pad = (char) (cmd == 'a' ? '\0' : ' ');
			unsigned char *bytes;

			bytes = Tcl_GetByteArrayFromObj(objv[arg++], &length);

			if (count == BINARY_ALL) {
			    count = length;
			} else if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			if (length >= count) {
			    memcpy((VOID *) cursor, (VOID *) bytes,
				    (size_t) count);
			} else {
			    memcpy((VOID *) cursor, (VOID *) bytes,
				    (size_t) length);
			    memset((VOID *) (cursor + length), pad,
			            (size_t) (count - length));
			}
			cursor += count;
			break;
		    }
		    case 'b':
		    case 'B': {
			unsigned char *last;
			
			str = Tcl_GetStringFromObj(objv[arg++], &length);
			if (count == BINARY_ALL) {
			    count = length;
			} else if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376








377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393








394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
				if (str[offset] == '1') {
				    value |= 1;
				} else if (str[offset] != '0') {
				    errorValue = str;
				    goto badValue;
				}
				if (((offset + 1) % 8) == 0) {
				    *cursor++ = (char)(value & 0xff);
				    value = 0;
				}
			    }
			} else {
			    for (offset = 0; offset < count; offset++) {
				value >>= 1;
				if (str[offset] == '1') {
				    value |= 128;
				} else if (str[offset] != '0') {
				    errorValue = str;
				    goto badValue;
				}
				if (!((offset + 1) % 8)) {
				    *cursor++ = (char)(value & 0xff);
				    value = 0;
				}
			    }
			}
			if ((offset % 8) != 0) {
			    if (cmd == 'B') {
				value <<= 8 - (offset % 8);
			    } else {
				value >>= 8 - (offset % 8);
			    }
			    *cursor++ = (char)(value & 0xff);
			}
			while (cursor < last) {
			    *cursor++ = '\0';
			}
			break;
		    }
		    case 'h':
		    case 'H': {
			char *last;
			int c;
			
			str = Tcl_GetStringFromObj(objv[arg++], &length);
			if (count == BINARY_ALL) {
			    count = length;
			} else if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			last = cursor + ((count + 1) / 2);
			if (count > length) {
			    count = length;
			}
			value = 0;
			errorString = "hexadecimal";
			if (cmd == 'H') {
			    for (offset = 0; offset < count; offset++) {
				value <<= 4;
				c = tolower(((unsigned char *) str)[offset]);
				if ((c >= 'a') && (c <= 'f')) {
				    value |= ((c - 'a' + 10) & 0xf);
				} else if ((c >= '0') && (c <= '9')) {
				    value |= (c - '0') & 0xf;
				} else {
				    errorValue = str;
				    goto badValue;
				}








				if (offset % 2) {
				    *cursor++ = (char) value;
				    value = 0;
				}
			    }
			} else {
			    for (offset = 0; offset < count; offset++) {
				value >>= 4;
				c = tolower(((unsigned char *) str)[offset]);
				if ((c >= 'a') && (c <= 'f')) {
				    value |= ((c - 'a' + 10) << 4) & 0xf0;
				} else if ((c >= '0') && (c <= '9')) {
				    value |= ((c - '0') << 4) & 0xf0;
				} else {
				    errorValue = str;
				    goto badValue;
				}








				if (offset % 2) {
				    *cursor++ = (char)(value & 0xff);
				    value = 0;
				}
			    }
			}
			if (offset % 2) {
			    if (cmd == 'H') {
				value <<= 4;
			    } else {
				value >>= 4;
			    }
			    *cursor++ = (char) value;
			}

			while (cursor < last) {
			    *cursor++ = '\0';
			}
			break;
		    }







|













|










|








|

















|
<
<
<
<
<



>
>
>
>
>
>
>
>








|
|
<
<
<
<



>
>
>
>
>
>
>
>

|










|







808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867





868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888




889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
				if (str[offset] == '1') {
				    value |= 1;
				} else if (str[offset] != '0') {
				    errorValue = str;
				    goto badValue;
				}
				if (((offset + 1) % 8) == 0) {
				    *cursor++ = (unsigned char) value;
				    value = 0;
				}
			    }
			} else {
			    for (offset = 0; offset < count; offset++) {
				value >>= 1;
				if (str[offset] == '1') {
				    value |= 128;
				} else if (str[offset] != '0') {
				    errorValue = str;
				    goto badValue;
				}
				if (!((offset + 1) % 8)) {
				    *cursor++ = (unsigned char) value;
				    value = 0;
				}
			    }
			}
			if ((offset % 8) != 0) {
			    if (cmd == 'B') {
				value <<= 8 - (offset % 8);
			    } else {
				value >>= 8 - (offset % 8);
			    }
			    *cursor++ = (unsigned char) value;
			}
			while (cursor < last) {
			    *cursor++ = '\0';
			}
			break;
		    }
		    case 'h':
		    case 'H': {
			unsigned char *last;
			int c;
			
			str = Tcl_GetStringFromObj(objv[arg++], &length);
			if (count == BINARY_ALL) {
			    count = length;
			} else if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			last = cursor + ((count + 1) / 2);
			if (count > length) {
			    count = length;
			}
			value = 0;
			errorString = "hexadecimal";
			if (cmd == 'H') {
			    for (offset = 0; offset < count; offset++) {
				value <<= 4;
				if (!isxdigit(UCHAR(str[offset]))) { /* INTL: digit */





				    errorValue = str;
				    goto badValue;
				}
				c = str[offset] - '0';
				if (c > 9) {
				    c += ('0' - 'A') + 10;
				}
				if (c > 16) {
				    c += ('A' - 'a');
				}
				value |= (c & 0xf);
				if (offset % 2) {
				    *cursor++ = (char) value;
				    value = 0;
				}
			    }
			} else {
			    for (offset = 0; offset < count; offset++) {
				value >>= 4;

				if (!isxdigit(UCHAR(str[offset]))) { /* INTL: digit */




				    errorValue = str;
				    goto badValue;
				}
				c = str[offset] - '0';
				if (c > 9) {
				    c += ('0' - 'A') + 10;
				}
				if (c > 16) {
				    c += ('A' - 'a');
				}
				value |= ((c << 4) & 0xf0);
				if (offset % 2) {
				    *cursor++ = (unsigned char)(value & 0xff);
				    value = 0;
				}
			    }
			}
			if (offset % 2) {
			    if (cmd == 'H') {
				value <<= 4;
			    } else {
				value >>= 4;
			    }
			    *cursor++ = (unsigned char) value;
			}

			while (cursor < last) {
			    *cursor++ = '\0';
			}
			break;
		    }
443
444
445
446
447
448
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478
479
480

481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499

500
501
502
503
504
505


506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

539
540
541
542
543
544

545
546

547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597
598
599

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651
652
653

654
655
656
657

658
659
660
661

662
663
664

665


666
667

668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698

699
700
701
702
703

704
705
706
707
708
709
710
711
712
713
714

715
716
717
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
			    if (FormatNumber(interp, cmd, listv[i], &cursor)
				    != TCL_OK) {
				return TCL_ERROR;
			    }
			}
			break;
		    }
		    case 'x':
			if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			memset(cursor, 0, (size_t) count);
			cursor += count;
			break;

		    case 'X':
			if (cursor > maxPos) {
			    maxPos = cursor;
			}
			if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			if ((count == BINARY_ALL)
				|| (count > (cursor - buffer))) {
			    cursor = buffer;
			} else {
			    cursor -= count;
			}
			break;

		    case '@':
			if (cursor > maxPos) {
			    maxPos = cursor;
			}
			if (count == BINARY_ALL) {
			    cursor = maxPos;
			} else {
			    cursor = buffer + count;
			}
			break;

		}
	    }
	    break;
	
	case BinaryScan: {
	    int i;
	    Tcl_Obj *valuePtr, *elementPtr;

	    if (objc < 4) {
		Tcl_WrongNumArgs(interp, 2, objv,
			"value formatString ?varName varName ...?");
		return TCL_ERROR;
	    }
	    buffer = Tcl_GetStringFromObj(objv[2], &length);
	    format = Tcl_GetStringFromObj(objv[3], NULL);
	    cursor = buffer;
	    arg = 4;
	    offset = 0;
	    while (*format != 0) {

		if (!GetFormatSpec(&format, &cmd, &count)) {
		    goto done;
		}
		switch (cmd) {
		    case 'a':
		    case 'A':


			if (arg >= objc) {
			    goto badIndex;
			}
			if (count == BINARY_ALL) {
			    count = length - offset;
			} else {
			    if (count == BINARY_NOCOUNT) {
				count = 1;
			    }
			    if (count > (length - offset)) {
				goto done;
			    }
			}

			str = buffer + offset;
			size = count;

			/*
			 * Trim trailing nulls and spaces, if necessary.
			 */

			if (cmd == 'A') {
			    while (size > 0) {
				if (str[size-1] != '\0' && str[size-1] != ' ') {
				    break;
				}
				size--;
			    }
			}
			valuePtr = Tcl_NewStringObj(str, size);
			resultPtr = Tcl_ObjSetVar2(interp, objv[arg++], NULL,
				valuePtr,
				TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1);

			if (resultPtr == NULL) {
			    Tcl_DecrRefCount(valuePtr);	/* unneeded */
			    return TCL_ERROR;
			}
			offset += count;
			break;

		    case 'b':
		    case 'B': {

			char *dest;

			if (arg >= objc) {
			    goto badIndex;
			}
			if (count == BINARY_ALL) {
			    count = (length - offset)*8;
			} else {
			    if (count == BINARY_NOCOUNT) {
				count = 1;
			    }
			    if (count > (length - offset)*8) {
				goto done;
			    }
			}
			str = buffer + offset;
			valuePtr = Tcl_NewObj();
			Tcl_SetObjLength(valuePtr, count);
			dest = Tcl_GetStringFromObj(valuePtr, NULL);

			if (cmd == 'b') {
			    for (i = 0; i < count; i++) {
				if (i % 8) {
				    value >>= 1;
				} else {
				    value = *str++;
				}
				*dest++ = (char) ((value & 1) ? '1' : '0');
			    }
			} else {
			    for (i = 0; i < count; i++) {
				if (i % 8) {
				    value <<= 1;
				} else {
				    value = *str++;
				}
				*dest++ = (char) ((value & 0x80) ? '1' : '0');
			    }
			}
			
			resultPtr = Tcl_ObjSetVar2(interp, objv[arg++], NULL,
				valuePtr,
				TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1);

			if (resultPtr == NULL) {
			    Tcl_DecrRefCount(valuePtr);	/* unneeded */
			    return TCL_ERROR;
			}
			offset += (count + 7 ) / 8;
			break;
		    }
		    case 'h':
		    case 'H': {
			char *dest;

			int i;
			static char hexdigit[] = "0123456789abcdef";

			if (arg >= objc) {
			    goto badIndex;
			}
			if (count == BINARY_ALL) {
			    count = (length - offset)*2;
			} else {
			    if (count == BINARY_NOCOUNT) {
				count = 1;
			    }
			    if (count > (length - offset)*2) {
				goto done;
			    }
			}
			str = buffer + offset;
			valuePtr = Tcl_NewObj();
			Tcl_SetObjLength(valuePtr, count);
			dest = Tcl_GetStringFromObj(valuePtr, NULL);

			if (cmd == 'h') {
			    for (i = 0; i < count; i++) {
				if (i % 2) {
				    value >>= 4;
				} else {
				    value = *str++;
				}
				*dest++ = hexdigit[value & 0xf];
			    }
			} else {
			    for (i = 0; i < count; i++) {
				if (i % 2) {
				    value <<= 4;
				} else {
				    value = *str++;
				}
				*dest++ = hexdigit[(value >> 4) & 0xf];
			    }
			}
			
			resultPtr = Tcl_ObjSetVar2(interp, objv[arg++], NULL,
				valuePtr,
				TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1);

			if (resultPtr == NULL) {
			    Tcl_DecrRefCount(valuePtr);	/* unneeded */
			    return TCL_ERROR;
			}
			offset += (count + 1) / 2;
			break;
		    }
		    case 'c':
			size = 1;
			goto scanNumber;

		    case 's':
		    case 'S':
			size = 2;
			goto scanNumber;

		    case 'i':
		    case 'I':
			size = 4;
			goto scanNumber;

		    case 'f':
			size = sizeof(float);
			goto scanNumber;

		    case 'd':


			size = sizeof(double);
			/* fall through */

		    scanNumber:
			if (arg >= objc) {
			    goto badIndex;
			}
			if (count == BINARY_NOCOUNT) {
			    if ((length - offset) < size) {
				goto done;
			    }
			    valuePtr = ScanNumber(buffer+offset, cmd);
			    offset += size;
			} else {
			    if (count == BINARY_ALL) {
				count = (length - offset) / size;
			    }
			    if ((length - offset) < (count * size)) {
				goto done;
			    }
			    valuePtr = Tcl_NewObj();
			    str = buffer+offset;
			    for (i = 0; i < count; i++) {
				elementPtr = ScanNumber(str, cmd);
				str += size;
				Tcl_ListObjAppendElement(NULL, valuePtr,
					elementPtr);
			    }
			    offset += count*size;
			}

			resultPtr = Tcl_ObjSetVar2(interp, objv[arg++], NULL,
				valuePtr,
				TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1);

			if (resultPtr == NULL) {
			    Tcl_DecrRefCount(valuePtr);	/* unneeded */
			    return TCL_ERROR;
			}
			break;

		    case 'x':
			if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			if ((count == BINARY_ALL)
				|| (count > (length - offset))) {
			    offset = length;
			} else {
			    offset += count;
			}
			break;

		    case 'X':
			if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			if ((count == BINARY_ALL) || (count > offset)) {
			    offset = 0;
			} else {
			    offset -= count;
			}
			break;

		    case '@':
			if (count == BINARY_NOCOUNT) {
			    goto badCount;
			}
			if ((count == BINARY_ALL) || (count > length)) {
			    offset = length;
			} else {
			    offset = count;
			}
			break;
		    default: {
			char buf[2];
			
			Tcl_ResetResult(interp);
			buf[0] = cmd;
			buf[1] = '\0';
			Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
				"bad field specifier \"", buf, "\"", NULL);
			return TCL_ERROR;
		    }
		}
	    }

	    /*
	     * Set the result to the last position of the cursor.
	     */







|






>
|













>
|









>



|
|








|
|



|
>





|
>
>














|








|





|
|
<
|
>






>


>






|




|



|


|






|








|





|
<
|
>










>
















|


|






|








|





|
<
|
>







|


>

|


>

|


>
|


>
|
>
>


>
|

















|

|
|






|
<
|
>





>
|










>
|









>
|









<
<
|
|
|
<
<
|
<







949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156

1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218

1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259


1260
1261
1262


1263

1264
1265
1266
1267
1268
1269
1270
			    if (FormatNumber(interp, cmd, listv[i], &cursor)
				    != TCL_OK) {
				return TCL_ERROR;
			    }
			}
			break;
		    }
		    case 'x': {
			if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			memset(cursor, 0, (size_t) count);
			cursor += count;
			break;
		    }
		    case 'X': {
			if (cursor > maxPos) {
			    maxPos = cursor;
			}
			if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			if ((count == BINARY_ALL)
				|| (count > (cursor - buffer))) {
			    cursor = buffer;
			} else {
			    cursor -= count;
			}
			break;
		    }
		    case '@': {
			if (cursor > maxPos) {
			    maxPos = cursor;
			}
			if (count == BINARY_ALL) {
			    cursor = maxPos;
			} else {
			    cursor = buffer + count;
			}
			break;
		    }
		}
	    }
	    break;
	}
	case BINARY_SCAN: {
	    int i;
	    Tcl_Obj *valuePtr, *elementPtr;

	    if (objc < 4) {
		Tcl_WrongNumArgs(interp, 2, objv,
			"value formatString ?varName varName ...?");
		return TCL_ERROR;
	    }
	    buffer = Tcl_GetByteArrayFromObj(objv[2], &length);
	    format = Tcl_GetString(objv[3]);
	    cursor = buffer;
	    arg = 4;
	    offset = 0;
	    while (*format != '\0') {
		str = format;
		if (!GetFormatSpec(&format, &cmd, &count)) {
		    goto done;
		}
		switch (cmd) {
		    case 'a':
		    case 'A': {
			unsigned char *src;

			if (arg >= objc) {
			    goto badIndex;
			}
			if (count == BINARY_ALL) {
			    count = length - offset;
			} else {
			    if (count == BINARY_NOCOUNT) {
				count = 1;
			    }
			    if (count > (length - offset)) {
				goto done;
			    }
			}

			src = buffer + offset;
			size = count;

			/*
			 * Trim trailing nulls and spaces, if necessary.
			 */

			if (cmd == 'A') {
			    while (size > 0) {
				if (src[size-1] != '\0' && src[size-1] != ' ') {
				    break;
				}
				size--;
			    }
			}
			valuePtr = Tcl_NewByteArrayObj(src, size);
			resultPtr = Tcl_ObjSetVar2(interp, objv[arg],

				NULL, valuePtr, TCL_LEAVE_ERR_MSG);
			arg++;
			if (resultPtr == NULL) {
			    Tcl_DecrRefCount(valuePtr);	/* unneeded */
			    return TCL_ERROR;
			}
			offset += count;
			break;
		    }
		    case 'b':
		    case 'B': {
			unsigned char *src;
			char *dest;

			if (arg >= objc) {
			    goto badIndex;
			}
			if (count == BINARY_ALL) {
			    count = (length - offset) * 8;
			} else {
			    if (count == BINARY_NOCOUNT) {
				count = 1;
			    }
			    if (count > (length - offset) * 8) {
				goto done;
			    }
			}
			src = buffer + offset;
			valuePtr = Tcl_NewObj();
			Tcl_SetObjLength(valuePtr, count);
			dest = Tcl_GetString(valuePtr);

			if (cmd == 'b') {
			    for (i = 0; i < count; i++) {
				if (i % 8) {
				    value >>= 1;
				} else {
				    value = *src++;
				}
				*dest++ = (char) ((value & 1) ? '1' : '0');
			    }
			} else {
			    for (i = 0; i < count; i++) {
				if (i % 8) {
				    value <<= 1;
				} else {
				    value = *src++;
				}
				*dest++ = (char) ((value & 0x80) ? '1' : '0');
			    }
			}
			
			resultPtr = Tcl_ObjSetVar2(interp, objv[arg],

				NULL, valuePtr, TCL_LEAVE_ERR_MSG);
			arg++;
			if (resultPtr == NULL) {
			    Tcl_DecrRefCount(valuePtr);	/* unneeded */
			    return TCL_ERROR;
			}
			offset += (count + 7 ) / 8;
			break;
		    }
		    case 'h':
		    case 'H': {
			char *dest;
			unsigned char *src;
			int i;
			static char hexdigit[] = "0123456789abcdef";

			if (arg >= objc) {
			    goto badIndex;
			}
			if (count == BINARY_ALL) {
			    count = (length - offset)*2;
			} else {
			    if (count == BINARY_NOCOUNT) {
				count = 1;
			    }
			    if (count > (length - offset)*2) {
				goto done;
			    }
			}
			src = buffer + offset;
			valuePtr = Tcl_NewObj();
			Tcl_SetObjLength(valuePtr, count);
			dest = Tcl_GetString(valuePtr);

			if (cmd == 'h') {
			    for (i = 0; i < count; i++) {
				if (i % 2) {
				    value >>= 4;
				} else {
				    value = *src++;
				}
				*dest++ = hexdigit[value & 0xf];
			    }
			} else {
			    for (i = 0; i < count; i++) {
				if (i % 2) {
				    value <<= 4;
				} else {
				    value = *src++;
				}
				*dest++ = hexdigit[(value >> 4) & 0xf];
			    }
			}
			
			resultPtr = Tcl_ObjSetVar2(interp, objv[arg],

				NULL, valuePtr, TCL_LEAVE_ERR_MSG);
			arg++;
			if (resultPtr == NULL) {
			    Tcl_DecrRefCount(valuePtr);	/* unneeded */
			    return TCL_ERROR;
			}
			offset += (count + 1) / 2;
			break;
		    }
		    case 'c': {
			size = 1;
			goto scanNumber;
		    }
		    case 's':
		    case 'S': {
			size = 2;
			goto scanNumber;
		    }
		    case 'i':
		    case 'I': {
			size = 4;
			goto scanNumber;
		    }
		    case 'f': {
			size = sizeof(float);
			goto scanNumber;
		    }
		    case 'd': {
			unsigned char *src;

			size = sizeof(double);
			/* fall through */
			
			scanNumber:
			if (arg >= objc) {
			    goto badIndex;
			}
			if (count == BINARY_NOCOUNT) {
			    if ((length - offset) < size) {
				goto done;
			    }
			    valuePtr = ScanNumber(buffer+offset, cmd);
			    offset += size;
			} else {
			    if (count == BINARY_ALL) {
				count = (length - offset) / size;
			    }
			    if ((length - offset) < (count * size)) {
				goto done;
			    }
			    valuePtr = Tcl_NewObj();
			    src = buffer+offset;
			    for (i = 0; i < count; i++) {
				elementPtr = ScanNumber(src, cmd);
				src += size;
				Tcl_ListObjAppendElement(NULL, valuePtr,
					elementPtr);
			    }
			    offset += count*size;
			}

			resultPtr = Tcl_ObjSetVar2(interp, objv[arg],

				NULL, valuePtr, TCL_LEAVE_ERR_MSG);
			arg++;
			if (resultPtr == NULL) {
			    Tcl_DecrRefCount(valuePtr);	/* unneeded */
			    return TCL_ERROR;
			}
			break;
		    }
		    case 'x': {
			if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			if ((count == BINARY_ALL)
				|| (count > (length - offset))) {
			    offset = length;
			} else {
			    offset += count;
			}
			break;
		    }
		    case 'X': {
			if (count == BINARY_NOCOUNT) {
			    count = 1;
			}
			if ((count == BINARY_ALL) || (count > offset)) {
			    offset = 0;
			} else {
			    offset -= count;
			}
			break;
		    }
		    case '@': {
			if (count == BINARY_NOCOUNT) {
			    goto badCount;
			}
			if ((count == BINARY_ALL) || (count > length)) {
			    offset = length;
			} else {
			    offset = count;
			}
			break;


		    }
		    default: {
			errorString = str;


			goto badfield;

		    }
		}
	    }

	    /*
	     * Set the result to the last position of the cursor.
	     */
766
767
768
769
770
771
772
773










774
775
776
777
778
779
780
781
782
783
    badCount:
    errorString = "missing count for \"@\" field specifier";
    goto error;

    badIndex:
    errorString = "not enough arguments for all format specifiers";
    goto error;











    error:
    Tcl_ResetResult(interp);
    Tcl_AppendToObj(Tcl_GetObjResult(interp), errorString, -1);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GetFormatSpec --








>
>
>
>
>
>
>
>
>
>

|
<







1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305

1306
1307
1308
1309
1310
1311
1312
    badCount:
    errorString = "missing count for \"@\" field specifier";
    goto error;

    badIndex:
    errorString = "not enough arguments for all format specifiers";
    goto error;

    badfield: {
	Tcl_UniChar ch;
	char buf[TCL_UTF_MAX + 1];

	Tcl_UtfToUniChar(errorString, &ch);
	buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
	Tcl_AppendResult(interp, "bad field specifier \"", buf, "\"", NULL);
	return TCL_ERROR;
    }

    error:
    Tcl_AppendResult(interp, errorString, NULL);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GetFormatSpec --
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
     */

    *cmdPtr = **formatPtr;
    (*formatPtr)++;
    if (**formatPtr == '*') {
	(*formatPtr)++;
	(*countPtr) = BINARY_ALL;
    } else if (isdigit(**formatPtr)) {
	(*countPtr) = strtoul(*formatPtr, formatPtr, 10);
    } else {
	(*countPtr) = BINARY_NOCOUNT;
    }
    return 1;
}








|







1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
     */

    *cmdPtr = **formatPtr;
    (*formatPtr)++;
    if (**formatPtr == '*') {
	(*formatPtr)++;
	(*countPtr) = BINARY_ALL;
    } else if (isdigit(UCHAR(**formatPtr))) { /* INTL: digit */
	(*countPtr) = strtoul(*formatPtr, formatPtr, 10);
    } else {
	(*countPtr) = BINARY_NOCOUNT;
    }
    return 1;
}

856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926

static int
FormatNumber(interp, type, src, cursorPtr)
    Tcl_Interp *interp;		/* Current interpreter, used to report
				 * errors. */
    int type;			/* Type of number to format. */
    Tcl_Obj *src;		/* Number to format. */
    char **cursorPtr;		/* Pointer to index into destination buffer. */
{
    int value;
    double dvalue;
    char cmd = (char)type;

    if (cmd == 'd' || cmd == 'f') {
	/*
	 * For floating point types, we need to copy the data using
	 * memcpy to avoid alignment issues.
	 */

	if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (cmd == 'd') {
	    memcpy((*cursorPtr), &dvalue, sizeof(double));
	    (*cursorPtr) += sizeof(double);
	} else {
	    float fvalue;

	    /*
	     * Because some compilers will generate floating point exceptions
	     * on an overflow cast (e.g. Borland), we restrict the values
	     * to the valid range for float.
	     */

	    if (fabs(dvalue) > (double)FLT_MAX) {
		fvalue = (dvalue >= 0.0) ? FLT_MAX : -FLT_MAX;
	    } else {
		fvalue = (float) dvalue;
	    }
	    memcpy((*cursorPtr), &fvalue, sizeof(float));
	    (*cursorPtr) += sizeof(float);
	}
    } else {
	if (Tcl_GetIntFromObj(interp, src, &value) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (cmd == 'c') {
	    *(*cursorPtr)++ = (char)(value & 0xff);
	} else if (cmd == 's') {
	    *(*cursorPtr)++ = (char)(value & 0xff);
	    *(*cursorPtr)++ = (char)((value >> 8) & 0xff);
	} else if (cmd == 'S') {
	    *(*cursorPtr)++ = (char)((value >> 8) & 0xff);
	    *(*cursorPtr)++ = (char)(value & 0xff);
	} else if (cmd == 'i') {
	    *(*cursorPtr)++ = (char)(value & 0xff);
	    *(*cursorPtr)++ = (char)((value >> 8) & 0xff);
	    *(*cursorPtr)++ = (char)((value >> 16) & 0xff);
	    *(*cursorPtr)++ = (char)((value >> 24) & 0xff);
	} else if (cmd == 'I') {
	    *(*cursorPtr)++ = (char)((value >> 24) & 0xff);
	    *(*cursorPtr)++ = (char)((value >> 16) & 0xff);
	    *(*cursorPtr)++ = (char)((value >> 8) & 0xff);
	    *(*cursorPtr)++ = (char)(value & 0xff);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|



<

|








|
|
|














|
|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395

1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454

static int
FormatNumber(interp, type, src, cursorPtr)
    Tcl_Interp *interp;		/* Current interpreter, used to report
				 * errors. */
    int type;			/* Type of number to format. */
    Tcl_Obj *src;		/* Number to format. */
    unsigned char **cursorPtr;	/* Pointer to index into destination buffer. */
{
    int value;
    double dvalue;


    if ((type == 'd') || (type == 'f')) {
	/*
	 * For floating point types, we need to copy the data using
	 * memcpy to avoid alignment issues.
	 */

	if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (type == 'd') {
	    memcpy((VOID *) *cursorPtr, (VOID *) &dvalue, sizeof(double));
	    *cursorPtr += sizeof(double);
	} else {
	    float fvalue;

	    /*
	     * Because some compilers will generate floating point exceptions
	     * on an overflow cast (e.g. Borland), we restrict the values
	     * to the valid range for float.
	     */

	    if (fabs(dvalue) > (double)FLT_MAX) {
		fvalue = (dvalue >= 0.0) ? FLT_MAX : -FLT_MAX;
	    } else {
		fvalue = (float) dvalue;
	    }
	    memcpy((VOID *) *cursorPtr, (VOID *) &fvalue, sizeof(float));
	    *cursorPtr += sizeof(float);
	}
    } else {
	if (Tcl_GetIntFromObj(interp, src, &value) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (type == 'c') {
	    *(*cursorPtr)++ = (unsigned char) value;
	} else if (type == 's') {
	    *(*cursorPtr)++ = (unsigned char) value;
	    *(*cursorPtr)++ = (unsigned char) (value >> 8);
	} else if (type == 'S') {
	    *(*cursorPtr)++ = (unsigned char) (value >> 8);
	    *(*cursorPtr)++ = (unsigned char) value;
	} else if (type == 'i') {
	    *(*cursorPtr)++ = (unsigned char) value;
	    *(*cursorPtr)++ = (unsigned char) (value >> 8);
	    *(*cursorPtr)++ = (unsigned char) (value >> 16);
	    *(*cursorPtr)++ = (unsigned char) (value >> 24);
	} else if (type == 'I') {
	    *(*cursorPtr)++ = (unsigned char) (value >> 24);
	    *(*cursorPtr)++ = (unsigned char) (value >> 16);
	    *(*cursorPtr)++ = (unsigned char) (value >> 8);
	    *(*cursorPtr)++ = (unsigned char) value;
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959



960


961

962
963
964
965

966
967
968
969

970
971
972
973
974
975
976
977

978
979
980
981
982
983

984
985
986
987
988
989
990
991
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
ScanNumber(buffer, type)
    char *buffer;		/* Buffer to scan number from. */
    int type;			/* Format character from "binary scan" */
{
    int value;

    /*
     * We cannot rely on the compiler to properly sign extend integer values
     * when we cast from smaller values to larger values because we don't know
     * the exact size of the integer types.  So, we have to handle sign
     * extension explicitly by checking the high bit and padding with 1's as
     * needed.
     */

    switch ((char) type) {
	case 'c':



	    value = buffer[0];




	    if (value & 0x80) {
		value |= -0x100;
	    }
	    return Tcl_NewLongObj((long)value);

	case 's':
	    value = (((unsigned char)buffer[0])
		    + ((unsigned char)buffer[1] << 8));
	    goto shortValue;

	case 'S':
	    value = (((unsigned char)buffer[1])
		    + ((unsigned char)buffer[0] << 8));
	    shortValue:
	    if (value & 0x8000) {
		value |= -0x10000;
	    }
	    return Tcl_NewLongObj((long)value);

	case 'i':
	    value =  (((unsigned char)buffer[0])
		    + ((unsigned char)buffer[1] << 8)
		    + ((unsigned char)buffer[2] << 16)
		    + ((unsigned char)buffer[3] << 24));
	    goto intValue;

	case 'I':
	    value = (((unsigned char)buffer[3])
		    + ((unsigned char)buffer[2] << 8)
		    + ((unsigned char)buffer[1] << 16)
		    + ((unsigned char)buffer[0] << 24));
	    intValue:
	    /*
	     * Check to see if the value was sign extended properly on
	     * systems where an int is more than 32-bits.
	     */

	    if ((value & (((unsigned int)1)<<31)) && (value > 0)) {
		value -= (((unsigned int)1)<<31);
		value -= (((unsigned int)1)<<31);
	    }

		
	    return Tcl_NewLongObj((long)value);
	case 'f': {
	    float fvalue;
	    memcpy(&fvalue, buffer, sizeof(float));
	    return Tcl_NewDoubleObj(fvalue);
	}
	case 'd': {
	    double dvalue;
	    memcpy(&dvalue, buffer, sizeof(double));
	    return Tcl_NewDoubleObj(dvalue);
	}
    }
    return NULL;
}







|


|









|
|
>
>
>
|
>
>

>




>
|
<
|

>
|
<
|




|
>
|
|
|
|
|

>
|
|
|
|
|










>
|
<


|




|





1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501

1502
1503
1504
1505

1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536

1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
ScanNumber(buffer, type)
    unsigned char *buffer;	/* Buffer to scan number from. */
    int type;			/* Format character from "binary scan" */
{
    long value;

    /*
     * We cannot rely on the compiler to properly sign extend integer values
     * when we cast from smaller values to larger values because we don't know
     * the exact size of the integer types.  So, we have to handle sign
     * extension explicitly by checking the high bit and padding with 1's as
     * needed.
     */

    switch (type) {
	case 'c': {
	    /*
	     * Characters need special handling.  We want to produce a
	     * signed result, but on some platforms (such as AIX) chars
	     * are unsigned.  To deal with this, check for a value that
	     * should be negative but isn't.
	     */

	    value = buffer[0];
	    if (value & 0x80) {
		value |= -0x100;
	    }
	    return Tcl_NewLongObj((long)value);
	}
	case 's': {

	    value = (long) (buffer[0] + (buffer[1] << 8));
	    goto shortValue;
	}
	case 'S': {

	    value = (long) (buffer[1] + (buffer[0] << 8));
	    shortValue:
	    if (value & 0x8000) {
		value |= -0x10000;
	    }
	    return Tcl_NewLongObj(value);
	}
	case 'i': {
	    value = (long) (buffer[0] 
		    + (buffer[1] << 8)
		    + (buffer[2] << 16)
		    + (buffer[3] << 24));
	    goto intValue;
	}
	case 'I': {
	    value = (long) (buffer[3]
		    + (buffer[2] << 8)
		    + (buffer[1] << 16)
		    + (buffer[0] << 24));
	    intValue:
	    /*
	     * Check to see if the value was sign extended properly on
	     * systems where an int is more than 32-bits.
	     */

	    if ((value & (((unsigned int)1)<<31)) && (value > 0)) {
		value -= (((unsigned int)1)<<31);
		value -= (((unsigned int)1)<<31);
	    }
	    return Tcl_NewLongObj(value);
	}

	case 'f': {
	    float fvalue;
	    memcpy((VOID *) &fvalue, (VOID *) buffer, sizeof(float));
	    return Tcl_NewDoubleObj(fvalue);
	}
	case 'd': {
	    double dvalue;
	    memcpy((VOID *) &dvalue, (VOID *) buffer, sizeof(double));
	    return Tcl_NewDoubleObj(dvalue);
	}
    }
    return NULL;
}

Changes to generic/tclCkalloc.c.

1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 
 * tclCkalloc.c --
 *
 *    Interface to malloc and free that provides support for debugging problems
 *    involving overwritten, double freeing memory and loss of memory.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.

 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * This code contributed by Karl Lehenbauer and Mark Diekhans
 *
 * SCCS: @(#) tclCkalloc.c 1.28 97/04/30 12:09:04
 */

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

#define FALSE	0
#define TRUE	1







|
>






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* 
 * tclCkalloc.c --
 *
 *    Interface to malloc and free that provides support for debugging problems
 *    involving overwritten, double freeing memory and loss of memory.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-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.
 *
 * This code contributed by Karl Lehenbauer and Mark Diekhans
 *
 * RCS: @(#) $Id: tclCkalloc.c,v 1.1.2.4 1999/03/10 06:49:14 stanton Exp $
 */

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

#define FALSE	0
#define TRUE	1
97
98
99
100
101
102
103




















104
105
106
107


108
109
110
111
112



















113
114
115
116
117
118
119
static int  init_malloced_bodies = TRUE;
#ifdef MEM_VALIDATE
    static int  validate_memory = TRUE;
#else
    static int  validate_memory = FALSE;
#endif





















/*
 * Prototypes for procedures defined in this file:
 */



static int		MemoryCmd _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int argc, char **argv));
static void		ValidateMemory _ANSI_ARGS_((
			    struct mem_header *memHeaderP, char *file,
			    int line, int nukeGuards));




















/*
 *----------------------------------------------------------------------
 *
 * TclDumpMemoryInfo --
 *     Display the global memory management statistics.
 *







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




>
>





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







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
static int  init_malloced_bodies = TRUE;
#ifdef MEM_VALIDATE
    static int  validate_memory = TRUE;
#else
    static int  validate_memory = FALSE;
#endif

/*
 * The following variable indicates to TclFinalizeMemorySubsystem() 
 * that it should dump out the state of memory before exiting.  If the
 * value is non-NULL, it gives the name of the file in which to
 * dump memory usage information.
 */

char *tclMemDumpFileName = NULL;

static char dumpFile[100];	/* Records where to dump memory allocation
				 * information. */

/*
 * Mutex to serialize allocations.  This is a low-level mutex that must
 * be explicitly initialized.  This is necessary because the self
 * initializing mutexes use ckalloc...
 */
static TclpMutex ckallocMutex;
static int ckallocInit = 0;

/*
 * Prototypes for procedures defined in this file:
 */

static int		CheckmemCmd _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int argc, char *argv[]));
static int		MemoryCmd _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int argc, char **argv));
static void		ValidateMemory _ANSI_ARGS_((
			    struct mem_header *memHeaderP, char *file,
			    int line, int nukeGuards));

/*
 *----------------------------------------------------------------------
 *
 * TclInitDbCkalloc --
 *     Initialize the locks used by the allocator.
 *	This is only appropriate to call in a single threaded environtment,
 *	such as during TclInitSubsystems.
 *
 *----------------------------------------------------------------------
 */
void
TclInitDbCkalloc() 
{
    if (!ckallocInit) {
	ckallocInit = 1;
	TclpMutexInit(&ckallocMutex);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclDumpMemoryInfo --
 *     Display the global memory management statistics.
 *
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
    for (idx = 0; idx < LOW_GUARD_SIZE; idx++) {
        byte = *(memHeaderP->low_guard + idx);
        if (byte != GUARD_VALUE) {
            guard_failed = TRUE;
            fflush(stdout);
	    byte &= 0xff;
            fprintf(stderr, "low guard byte %d is 0x%x  \t%c\n", idx, byte,
		    (isprint(UCHAR(byte)) ? byte : ' '));
        }
    }
    if (guard_failed) {
        TclDumpMemoryInfo (stderr);
        fprintf(stderr, "low guard failed at %lx, %s %d\n",
                 (long unsigned int) memHeaderP->body, file, line);
        fflush(stderr);  /* In case name pointer is bad. */
        fprintf(stderr, "%ld bytes allocated at (%s %d)\n", memHeaderP->length,
		memHeaderP->file, memHeaderP->line);
        panic ("Memory validation failure");
    }

    hiPtr = (unsigned char *)memHeaderP->body + memHeaderP->length;
    for (idx = 0; idx < HIGH_GUARD_SIZE; idx++) {
        byte = *(hiPtr + idx);
        if (byte != GUARD_VALUE) {
            guard_failed = TRUE;
            fflush (stdout);
	    byte &= 0xff;
            fprintf(stderr, "hi guard byte %d is 0x%x  \t%c\n", idx, byte,
		    (isprint(UCHAR(byte)) ? byte : ' '));
        }
    }

    if (guard_failed) {
        TclDumpMemoryInfo (stderr);
        fprintf(stderr, "high guard failed at %lx, %s %d\n",
                 (long unsigned int) memHeaderP->body, file, line);







|




















|







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
    for (idx = 0; idx < LOW_GUARD_SIZE; idx++) {
        byte = *(memHeaderP->low_guard + idx);
        if (byte != GUARD_VALUE) {
            guard_failed = TRUE;
            fflush(stdout);
	    byte &= 0xff;
            fprintf(stderr, "low guard byte %d is 0x%x  \t%c\n", idx, byte,
		    (isprint(UCHAR(byte)) ? byte : ' ')); /* INTL: bytes */
        }
    }
    if (guard_failed) {
        TclDumpMemoryInfo (stderr);
        fprintf(stderr, "low guard failed at %lx, %s %d\n",
                 (long unsigned int) memHeaderP->body, file, line);
        fflush(stderr);  /* In case name pointer is bad. */
        fprintf(stderr, "%ld bytes allocated at (%s %d)\n", memHeaderP->length,
		memHeaderP->file, memHeaderP->line);
        panic ("Memory validation failure");
    }

    hiPtr = (unsigned char *)memHeaderP->body + memHeaderP->length;
    for (idx = 0; idx < HIGH_GUARD_SIZE; idx++) {
        byte = *(hiPtr + idx);
        if (byte != GUARD_VALUE) {
            guard_failed = TRUE;
            fflush (stdout);
	    byte &= 0xff;
            fprintf(stderr, "hi guard byte %d is 0x%x  \t%c\n", idx, byte,
		    (isprint(UCHAR(byte)) ? byte : ' ')); /* INTL: bytes */
        }
    }

    if (guard_failed) {
        TclDumpMemoryInfo (stderr);
        fprintf(stderr, "high guard failed at %lx, %s %d\n",
                 (long unsigned int) memHeaderP->body, file, line);
218
219
220
221
222
223
224





225
226
227

228
229
230
231
232
233
234
void
Tcl_ValidateAllMemory (file, line)
    char  *file;
    int    line;
{
    struct mem_header *memScanP;






    for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink)
        ValidateMemory(memScanP, file, line, FALSE);


}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DumpActiveMemory --
 *     Displays all allocated memory to stderr.







>
>
>
>
>
|

|
>







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
void
Tcl_ValidateAllMemory (file, line)
    char  *file;
    int    line;
{
    struct mem_header *memScanP;

    if (!ckallocInit) {
	ckallocInit = 1;
	TclpMutexInit(&ckallocMutex);
    }
    TclpMutexLock(&ckallocMutex);
    for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {
        ValidateMemory(memScanP, file, line, FALSE);
    }
    TclpMutexUnlock(&ckallocMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DumpActiveMemory --
 *     Displays all allocated memory to stderr.
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
Tcl_DumpActiveMemory (fileName)
    char *fileName;
{
    FILE              *fileP;
    struct mem_header *memScanP;
    char              *address;




    fileP = fopen(fileName, "w");
    if (fileP == NULL)
        return TCL_ERROR;




    for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {
        address = &memScanP->body [0];
        fprintf(fileP, "%8lx - %8lx  %7ld @ %s %d %s",
		(long unsigned int) address,
                 (long unsigned int) address + memScanP->length - 1,
		 memScanP->length, memScanP->file, memScanP->line,
		 (memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string);
	(void) fputc('\n', fileP);
    }



    fclose (fileP);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DbCkalloc - debugging ckalloc







>
>
>
|
|
|
|
>
>
>









>
>
>
|
>







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
Tcl_DumpActiveMemory (fileName)
    char *fileName;
{
    FILE              *fileP;
    struct mem_header *memScanP;
    char              *address;

    if (fileName == NULL) {
	fileP = stdout;
    } else {
	fileP = fopen(fileName, "w");
	if (fileP == NULL) {
	    return TCL_ERROR;
	}
    }

    TclpMutexLock(&ckallocMutex);
    for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {
        address = &memScanP->body [0];
        fprintf(fileP, "%8lx - %8lx  %7ld @ %s %d %s",
		(long unsigned int) address,
                 (long unsigned int) address + memScanP->length - 1,
		 memScanP->length, memScanP->file, memScanP->line,
		 (memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string);
	(void) fputc('\n', fileP);
    }
    TclpMutexUnlock(&ckallocMutex);

    if (fileP != stderr) {
	fclose (fileP);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DbCkalloc - debugging ckalloc
309
310
311
312
313
314
315





316
317
318
319
320
321
322
323
324

325
326
327
328
329
330
331
    if (init_malloced_bodies) {
        memset ((VOID *) result, GUARD_VALUE,
		size + sizeof(struct mem_header) + HIGH_GUARD_SIZE);
    } else {
	memset ((char *) result->low_guard, GUARD_VALUE, LOW_GUARD_SIZE);
	memset (result->body + size, GUARD_VALUE, HIGH_GUARD_SIZE);
    }





    result->length = size;
    result->tagPtr = curTagPtr;
    if (curTagPtr != NULL) {
	curTagPtr->refCount++;
    }
    result->file = file;
    result->line = line;
    result->flink = allocHead;
    result->blink = NULL;

    if (allocHead != NULL)
        allocHead->blink = result;
    allocHead = result;

    total_mallocs++;
    if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) {
        (void) fflush(stdout);







>
>
>
>
>









>







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
    if (init_malloced_bodies) {
        memset ((VOID *) result, GUARD_VALUE,
		size + sizeof(struct mem_header) + HIGH_GUARD_SIZE);
    } else {
	memset ((char *) result->low_guard, GUARD_VALUE, LOW_GUARD_SIZE);
	memset (result->body + size, GUARD_VALUE, HIGH_GUARD_SIZE);
    }
    if (!ckallocInit) {
	ckallocInit = 1;
	TclpMutexInit(&ckallocMutex);
    }
    TclpMutexLock(&ckallocMutex);
    result->length = size;
    result->tagPtr = curTagPtr;
    if (curTagPtr != NULL) {
	curTagPtr->refCount++;
    }
    result->file = file;
    result->line = line;
    result->flink = allocHead;
    result->blink = NULL;

    if (allocHead != NULL)
        allocHead->blink = result;
    allocHead = result;

    total_mallocs++;
    if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) {
        (void) fflush(stdout);
352
353
354
355
356
357
358


359
360
361
362
363
364
365

    current_malloc_packets++;
    if (current_malloc_packets > maximum_malloc_packets)
        maximum_malloc_packets = current_malloc_packets;
    current_bytes_malloced += size;
    if (current_bytes_malloced > maximum_bytes_malloced)
        maximum_bytes_malloced = current_bytes_malloced;



    return result->body;
}

/*
 *----------------------------------------------------------------------
 *







>
>







416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

    current_malloc_packets++;
    if (current_malloc_packets > maximum_malloc_packets)
        maximum_malloc_packets = current_malloc_packets;
    current_bytes_malloced += size;
    if (current_bytes_malloced > maximum_bytes_malloced)
        maximum_bytes_malloced = current_bytes_malloced;

    TclpMutexUnlock(&ckallocMutex);

    return result->body;
}

/*
 *----------------------------------------------------------------------
 *
399
400
401
402
403
404
405

406
407
408
409
410
411
412
    if (alloc_tracing)
        fprintf(stderr, "ckfree %lx %ld %s %d\n",
		(long unsigned int) memp->body, memp->length, file, line);

    if (validate_memory)
        Tcl_ValidateAllMemory(file, line);


    ValidateMemory(memp, file, line, TRUE);
    if (init_malloced_bodies) {
	memset((VOID *) ptr, GUARD_VALUE, (size_t) memp->length);
    }

    total_frees++;
    current_malloc_packets--;







>







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
    if (alloc_tracing)
        fprintf(stderr, "ckfree %lx %ld %s %d\n",
		(long unsigned int) memp->body, memp->length, file, line);

    if (validate_memory)
        Tcl_ValidateAllMemory(file, line);

    TclpMutexLock(&ckallocMutex);
    ValidateMemory(memp, file, line, TRUE);
    if (init_malloced_bodies) {
	memset((VOID *) ptr, GUARD_VALUE, (size_t) memp->length);
    }

    total_frees++;
    current_malloc_packets--;
425
426
427
428
429
430
431


432
433
434
435
436
437
438
    if (memp->flink != NULL)
        memp->flink->blink = memp->blink;
    if (memp->blink != NULL)
        memp->blink->flink = memp->flink;
    if (allocHead == memp)
        allocHead = memp->flink;
    TclpFree((char *) memp);


    return 0;
}

/*
 *--------------------------------------------------------------------
 *
 * Tcl_DbCkrealloc - debugging ckrealloc







>
>







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
    if (memp->flink != NULL)
        memp->flink->blink = memp->blink;
    if (memp->blink != NULL)
        memp->blink->flink = memp->flink;
    if (allocHead == memp)
        allocHead = memp->flink;
    TclpFree((char *) memp);
    TclpMutexUnlock(&ckallocMutex);

    return 0;
}

/*
 *--------------------------------------------------------------------
 *
 * Tcl_DbCkrealloc - debugging ckrealloc
576
577
578
579
580
581
582
583







584
585
586
587
588
589
590
	}
        if (Tcl_GetInt(interp, argv[2], &break_on_malloc) != TCL_OK) {
	    return TCL_ERROR;
	}
        return TCL_OK;
    }
    if (strcmp(argv[1],"info") == 0) {
        TclDumpMemoryInfo(stdout);







        return TCL_OK;
    }
    if (strcmp(argv[1],"init") == 0) {
        if (argc != 3) {
            goto bad_suboption;
	}
        init_malloced_bodies = (strcmp(argv[2],"on") == 0);







|
>
>
>
>
>
>
>







645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
	}
        if (Tcl_GetInt(interp, argv[2], &break_on_malloc) != TCL_OK) {
	    return TCL_ERROR;
	}
        return TCL_OK;
    }
    if (strcmp(argv[1],"info") == 0) {
	char buffer[400];
	sprintf(buffer, "%-25s %10d\n%-25s %10d\n%-25s %10d\n%-25s %10d\n%-25s %10d\n%-25s %10d\n",
	    "total mallocs", total_mallocs, "total frees", total_frees,
	    "current packets allocated", current_malloc_packets,
	    "current bytes allocated", current_bytes_malloced,
	    "maximum packets allocated", maximum_malloc_packets,
	    "maximum bytes allocated", maximum_bytes_malloced);
	Tcl_SetResult(interp, buffer, TCL_VOLATILE);
        return TCL_OK;
    }
    if (strcmp(argv[1],"init") == 0) {
        if (argc != 3) {
            goto bad_suboption;
	}
        init_malloced_bodies = (strcmp(argv[2],"on") == 0);
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
	    " ", argv[1], " on|off\"", (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *




































 * Tcl_InitMemory --
 *     Initialize the memory command.
 *
 *----------------------------------------------------------------------
 */
void
Tcl_InitMemory(interp)
    Tcl_Interp *interp;
{

    Tcl_CreateCommand (interp, "memory", MemoryCmd, (ClientData) NULL, 


	    (Tcl_CmdDeleteProc *) NULL);
}

#else







/*
 *----------------------------------------------------------------------
 *
 * Tcl_Alloc --
 *     Interface to TclpAlloc when TCL_MEM_DEBUG is disabled.  It does check







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









>

>
>



|
>
>
>
>
>







720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
	    " ", argv[1], " on|off\"", (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * CheckmemCmd --
 *
 *	This is the command procedure for the "checkmem" command, which
 *	causes the application to exit after printing information about
 *	memory usage to the file passed to this command as its first
 *	argument.
 *
 * Results:
 *	Returns a standard Tcl completion code.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
CheckmemCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Interpreter for evaluation. */
    int argc;				/* Number of arguments. */
    char *argv[];			/* String values of arguments. */
{
    if (argc != 2) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" fileName\"", (char *) NULL);
	return TCL_ERROR;
    }
    tclMemDumpFileName = dumpFile;
    strcpy(tclMemDumpFileName, argv[1]);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_InitMemory --
 *     Initialize the memory command.
 *
 *----------------------------------------------------------------------
 */
void
Tcl_InitMemory(interp)
    Tcl_Interp *interp;
{
    TclInitDbCkalloc();
    Tcl_CreateCommand (interp, "memory", MemoryCmd, (ClientData) NULL, 
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "checkmem", CheckmemCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
}


#else	/* TCL_MEM_DEBUG */

#undef Tcl_InitMemory
#undef Tcl_DumpActiveMemory
#undef Tcl_ValidateAllMemory


/*
 *----------------------------------------------------------------------
 *
 * Tcl_Alloc --
 *     Interface to TclpAlloc when TCL_MEM_DEBUG is disabled.  It does check
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814









































815





	/* ARGSUSED */
void
Tcl_InitMemory(interp)
    Tcl_Interp *interp;
{
}

#undef Tcl_DumpActiveMemory
#undef Tcl_ValidateAllMemory

extern int		Tcl_DumpActiveMemory _ANSI_ARGS_((char *fileName));
extern void		Tcl_ValidateAllMemory _ANSI_ARGS_((char *file,
			    int line));

int
Tcl_DumpActiveMemory(fileName)
    char *fileName;
{
    return TCL_OK;
}

void
Tcl_ValidateAllMemory(file, line)
    char  *file;
    int    line;
{
}










































#endif












<
<
<
<
<
<
<














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

>
>
>
>
>
907
908
909
910
911
912
913







914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
	/* ARGSUSED */
void
Tcl_InitMemory(interp)
    Tcl_Interp *interp;
{
}








int
Tcl_DumpActiveMemory(fileName)
    char *fileName;
{
    return TCL_OK;
}

void
Tcl_ValidateAllMemory(file, line)
    char  *file;
    int    line;
{
}

void
TclDumpMemoryInfo(outFile) 
    FILE *outFile;
{
}

#endif	/* TCL_MEM_DEBUG */

/*
 *---------------------------------------------------------------------------
 *
 * TclFinalizeMemorySubsystem --
 *
 *	This procedure is called to finalize all the structures that 
 *	are used by the memory allocator on a per-process basis.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	This subsystem is self-initializing, since memory can be 
 *	allocated before Tcl is formally initialized.  After this call,
 *	this subsystem has been reset to its initial state and is 
 *	usable again.
 *
 *---------------------------------------------------------------------------
 */

void
TclFinalizeMemorySubsystem()
{
#ifdef TCL_MEM_DEBUG
    TclpMutexLock(&ckallocMutex);
    if (tclMemDumpFileName != NULL) {
	Tcl_DumpActiveMemory(tclMemDumpFileName);
    }
    if (curTagPtr != NULL) {
	TclpFree((char *) curTagPtr);
    }
    allocHead = NULL;
    TclpMutexUnlock(&ckallocMutex);
#endif

#if USE_TCLALLOC
    TclFinalizeAllocSubsystem(); 
#endif
}

Changes to generic/tclClock.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
/* 
 * tclClock.c --
 *
 *	Contains the time and date related commands.  This code
 *	is derived from the time and date facilities of TclX,
 *	by Mark Diekhans and Karl Lehenbauer.
 *
 * Copyright 1991-1995 Karl Lehenbauer and Mark Diekhans.
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclClock.c 1.37 97/07/29 10:29:58
 */

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







/*
 * Function prototypes for local procedures in this file:
 */

static int		FormatClock _ANSI_ARGS_((Tcl_Interp *interp,
			    unsigned long clockVal, int useGMT,
			    char *format));













|






>
>
>
>
>
>







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
/* 
 * tclClock.c --
 *
 *	Contains the time and date related commands.  This code
 *	is derived from the time and date facilities of TclX,
 *	by Mark Diekhans and Karl Lehenbauer.
 *
 * Copyright 1991-1995 Karl Lehenbauer and Mark Diekhans.
 * Copyright (c) 1995 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: tclClock.c,v 1.1.2.6 1999/03/10 06:49:14 stanton Exp $
 */

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

/*
 * The date parsing stuff uses lexx and has tons o statics.
 */

TCL_DECLARE_MUTEX(clockMutex)

/*
 * Function prototypes for local procedures in this file:
 */

static int		FormatClock _ANSI_ARGS_((Tcl_Interp *interp,
			    unsigned long clockVal, int useGMT,
			    char *format));
168
169
170
171
172
173
174

175
176

177
178
179
180
181

182
183
184
185
186
187
188
	    if (useGMT) {
		zone = -50000; /* Force GMT */
	    } else {
		zone = TclpGetTimeZone((unsigned long) baseClock);
	    }

	    scanStr = Tcl_GetStringFromObj(objv[2], &dummy);

	    if (TclGetDate(scanStr, (unsigned long) baseClock, zone,
		    (unsigned long *) &clockVal) < 0) {

		Tcl_AppendStringsToObj(resultPtr,
			"unable to convert date-time string \"",
			scanStr, "\"", (char *) NULL);
		return TCL_ERROR;
	    }


	    Tcl_SetLongObj(resultPtr, (long) clockVal);
	    return TCL_OK;
	case 3:			/* seconds */
	    if (objc != 2) {
		Tcl_WrongNumArgs(interp, 2, objv, NULL);
		return TCL_ERROR;







>


>





>







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	    if (useGMT) {
		zone = -50000; /* Force GMT */
	    } else {
		zone = TclpGetTimeZone((unsigned long) baseClock);
	    }

	    scanStr = Tcl_GetStringFromObj(objv[2], &dummy);
	    Tcl_MutexLock(&clockMutex);
	    if (TclGetDate(scanStr, (unsigned long) baseClock, zone,
		    (unsigned long *) &clockVal) < 0) {
		Tcl_MutexUnlock(&clockMutex);
		Tcl_AppendStringsToObj(resultPtr,
			"unable to convert date-time string \"",
			scanStr, "\"", (char *) NULL);
		return TCL_ERROR;
	    }
	    Tcl_MutexUnlock(&clockMutex);

	    Tcl_SetLongObj(resultPtr, (long) clockVal);
	    return TCL_OK;
	case 3:			/* seconds */
	    if (objc != 2) {
		Tcl_WrongNumArgs(interp, 2, objv, NULL);
		return TCL_ERROR;
218
219
220
221
222
223
224


225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241

242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301





302
303
304
305
306
307
    int useGMT;				/* Boolean */
    char *format;			/* Format string */
{
    struct tm *timeDataPtr;
    Tcl_DString buffer;
    int bufSize;
    char *p;


#ifdef TCL_USE_TIMEZONE_VAR
    int savedTimeZone;
    char *savedTZEnv;
#endif
    Tcl_Obj *resultPtr;

    resultPtr = Tcl_GetObjResult(interp);
#ifdef HAVE_TZSET
    /*
     * Some systems forgot to call tzset in localtime, make sure its done.
     */
    static int  calledTzset = 0;


    if (!calledTzset) {
        tzset();
        calledTzset = 1;
    }

#endif

#ifdef TCL_USE_TIMEZONE_VAR
    /*
     * This is a horrible kludge for systems not having the timezone in
     * struct tm.  No matter what was specified, they use the global time
     * zone.  (Thanks Solaris).
     */

    if (useGMT) {
        char *varValue;

        varValue = Tcl_GetVar2(interp, "env", "TZ", TCL_GLOBAL_ONLY);
        if (varValue != NULL) {
	    savedTZEnv = strcpy(ckalloc(strlen(varValue) + 1), varValue);
        } else {
            savedTZEnv = NULL;
	}
        Tcl_SetVar2(interp, "env", "TZ", "GMT", TCL_GLOBAL_ONLY);
        savedTimeZone = timezone;
        timezone = 0;
        tzset();
    }
#endif

    timeDataPtr = TclpGetDate((time_t *) &clockVal, useGMT);
    
    /*
     * Make a guess at the upper limit on the substituted string size
     * based on the number of percents in the string.
     */

    for (bufSize = 1, p = format; *p != '\0'; p++) {
	if (*p == '%') {
	    bufSize += 40;
	} else {
	    bufSize++;
	}
    }
    Tcl_DStringInit(&buffer);
    Tcl_DStringSetLength(&buffer, bufSize);


    if ((TclStrftime(buffer.string, (unsigned int) bufSize, format,
	    timeDataPtr) == 0) && (*format != '\0')) {
	Tcl_AppendStringsToObj(resultPtr, "bad format string \"",
		format, "\"", (char *) NULL);
	return TCL_ERROR;
    }

#ifdef TCL_USE_TIMEZONE_VAR
    if (useGMT) {
        if (savedTZEnv != NULL) {
            Tcl_SetVar2(interp, "env", "TZ", savedTZEnv, TCL_GLOBAL_ONLY);
            ckfree(savedTZEnv);
        } else {
            Tcl_UnsetVar2(interp, "env", "TZ", TCL_GLOBAL_ONLY);
        }
        timezone = savedTimeZone;
        tzset();
    }
#endif






    Tcl_SetStringObj(resultPtr, buffer.string, -1);
    Tcl_DStringFree(&buffer);
    return TCL_OK;
}








>
>
|
|
|

<








>




>


|

|
|
|

>
















|
















>
|
|
<
|
<
|
|
<











>
>
>
>
>






227
228
229
230
231
232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299

300
301

302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
    int useGMT;				/* Boolean */
    char *format;			/* Format string */
{
    struct tm *timeDataPtr;
    Tcl_DString buffer;
    int bufSize;
    char *p;
    Tcl_Obj *resultPtr;
    int result;
#ifndef HAVE_TM_ZONE
    int savedTimeZone = 0;	/* lint. */
    char *savedTZEnv = NULL;	/* lint. */
#endif


    resultPtr = Tcl_GetObjResult(interp);
#ifdef HAVE_TZSET
    /*
     * Some systems forgot to call tzset in localtime, make sure its done.
     */
    static int  calledTzset = 0;

    Tcl_MutexLock(&clockMutex);
    if (!calledTzset) {
        tzset();
        calledTzset = 1;
    }
    Tcl_MutexUnlock(&clockMutex);
#endif

#ifndef HAVE_TM_ZONE
    /*
     * This is a kludge for systems not having the timezone string in
     * struct tm.  No matter what was specified, they use the local
     * timezone string.
     */

    if (useGMT) {
        char *varValue;

        varValue = Tcl_GetVar2(interp, "env", "TZ", TCL_GLOBAL_ONLY);
        if (varValue != NULL) {
	    savedTZEnv = strcpy(ckalloc(strlen(varValue) + 1), varValue);
        } else {
            savedTZEnv = NULL;
	}
        Tcl_SetVar2(interp, "env", "TZ", "GMT", TCL_GLOBAL_ONLY);
        savedTimeZone = timezone;
        timezone = 0;
        tzset();
    }
#endif

    timeDataPtr = TclpGetDate((TclpTime_t) &clockVal, useGMT);
    
    /*
     * Make a guess at the upper limit on the substituted string size
     * based on the number of percents in the string.
     */

    for (bufSize = 1, p = format; *p != '\0'; p++) {
	if (*p == '%') {
	    bufSize += 40;
	} else {
	    bufSize++;
	}
    }
    Tcl_DStringInit(&buffer);
    Tcl_DStringSetLength(&buffer, bufSize);

    Tcl_MutexLock(&clockMutex);
    result = TclpStrftime(buffer.string, (unsigned int) bufSize, format,
	    timeDataPtr);

    Tcl_MutexUnlock(&clockMutex);


#ifndef HAVE_TM_ZONE

    if (useGMT) {
        if (savedTZEnv != NULL) {
            Tcl_SetVar2(interp, "env", "TZ", savedTZEnv, TCL_GLOBAL_ONLY);
            ckfree(savedTZEnv);
        } else {
            Tcl_UnsetVar2(interp, "env", "TZ", TCL_GLOBAL_ONLY);
        }
        timezone = savedTimeZone;
        tzset();
    }
#endif
    if ((result == 0) && (*format != '\0')) {
	Tcl_AppendStringsToObj(resultPtr, "bad format string \"", format, 
		"\"", (char *) NULL);
	return TCL_ERROR;
    }

    Tcl_SetStringObj(resultPtr, buffer.string, -1);
    Tcl_DStringFree(&buffer);
    return TCL_OK;
}

Changes to generic/tclCmdAH.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
65
66
/* 
 * tclCmdAH.c --
 *
 *	This file contains the top-level command routines for most of
 *	the Tcl built-in commands whose names begin with the letters
 *	A to H.
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclCmdAH.c 1.159 97/10/31 13:06:07
 */

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




/*
 * Prototypes for local procedures defined in this file:
 */






static char *		GetTypeFromMode _ANSI_ARGS_((int mode));


static int		StoreStatData _ANSI_ARGS_((Tcl_Interp *interp,
			    char *varName, struct stat *statPtr));



/*
 *----------------------------------------------------------------------
 *
 * Tcl_BreakCmd --
 *
 *	This procedure is invoked to process the "break" Tcl command.
 *	See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "break" or the name
 *	to which "break" was renamed: e.g., "set z break; $z"
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_BreakCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    if (argc != 1) {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], "\"", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_BREAK;
}

/*
 *----------------------------------------------------------------------













|




>
>
>





>
>
>
>
>

>
>


>
>




|



















|


|
|

|
|
<







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
/* 
 * tclCmdAH.c --
 *
 *	This file contains the top-level command routines for most of
 *	the Tcl built-in commands whose names begin with the letters
 *	A to H.
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * 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: tclCmdAH.c,v 1.1.2.12 1999/04/14 00:33:21 surles Exp $
 */

#include "tclInt.h"
#include "tclPort.h"
#include <locale.h>

typedef int (StatProc)_ANSI_ARGS_((CONST char *path, struct stat *buf));

/*
 * Prototypes for local procedures defined in this file:
 */

static int		CheckAccess _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, int mode));
static int		GetStatBuf _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, StatProc *statProc,
			    struct stat *statPtr));
static char *		GetTypeFromMode _ANSI_ARGS_((int mode));
static int		SplitPath _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, int *argcPtr, char ***argvPtr));
static int		StoreStatData _ANSI_ARGS_((Tcl_Interp *interp,
			    char *varName, struct stat *statPtr));
static char **		StringifyObjects _ANSI_ARGS_((int objc,
			    Tcl_Obj *CONST objv[]));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_BreakObjCmd --
 *
 *	This procedure is invoked to process the "break" Tcl command.
 *	See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "break" or the name
 *	to which "break" was renamed: e.g., "set z break; $z"
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_BreakObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);

	return TCL_ERROR;
    }
    return TCL_BREAK;
}

/*
 *----------------------------------------------------------------------
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
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register int i;
    int body, result;
    char *string, *arg;
    int argLen, caseObjc;
    Tcl_Obj *CONST *caseObjv;
    Tcl_Obj *armPtr;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"string ?in? patList body ... ?default body?");
	return TCL_ERROR;
    }

    /*
     * THIS FAILS IF AN OBJECT'S STRING REP HAS A NULL BYTE.
     */
    
    string = Tcl_GetStringFromObj(objv[1], &argLen);
    body = -1;

    arg = Tcl_GetStringFromObj(objv[2], &argLen);
    if (strcmp(arg, "in") == 0) {
	i = 3;
    } else {
	i = 2;
    }
    caseObjc = objc - i;
    caseObjv = objv + i;

    /*
     * If all of the pattern/command pairs are lumped into a single
     * argument, split them out again.
     * THIS FAILS IF THE ARG'S STRING REP CONTAINS A NULL
     */

    if (caseObjc == 1) {
	Tcl_Obj **newObjv;
	
	Tcl_ListObjGetElements(interp, caseObjv[0], &caseObjc, &newObjv);
	caseObjv = newObjv;
    }

    for (i = 0;  i < caseObjc;  i += 2) {
	int patObjc, j;
	char **patObjv;
	char *pat;
	register char *p;

	if (i == (caseObjc-1)) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	            "extra case pattern with no body", -1);
	    return TCL_ERROR;
	}

	/*
	 * Check for special case of single pattern (no list) with
	 * no backslash sequences.
	 */

	pat = Tcl_GetStringFromObj(caseObjv[i], &argLen);
	for (p = pat;  *p != 0;  p++) {	/* FAILS IF NULL BYTE */
	    if (isspace(UCHAR(*p)) || (*p == '\\')) {
		break;
	    }
	}
	if (*p == 0) {
	    if ((*pat == 'd') && (strcmp(pat, "default") == 0)) {
		body = i+1;
	    }
	    if (Tcl_StringMatch(string, pat)) {
		body = i+1;
		goto match;
	    }
	    continue;
	}


	/*
	 * Break up pattern lists, then check each of the patterns
	 * in the list.
	 */

	result = Tcl_SplitList(interp, pat, &patObjc, &patObjv);
	if (result != TCL_OK) {
	    return result;
	}
	for (j = 0; j < patObjc; j++) {
	    if (Tcl_StringMatch(string, patObjv[j])) {
		body = i+1;
		break;
	    }
	}
	ckfree((char *) patObjv);
	if (j < patObjc) {
	    break;
	}
    }

    match:
    if (body != -1) {
	armPtr = caseObjv[body-1];
	result = Tcl_EvalObj(interp, caseObjv[body]);
	if (result == TCL_ERROR) {
	    char msg[100];
	    
	    arg = Tcl_GetStringFromObj(armPtr, &argLen);
	    sprintf(msg, "\n    (\"%.*s\" arm line %d)", argLen, arg,

	            interp->errorLine);
	    Tcl_AddObjErrorInfo(interp, msg, -1);
	}
	return result;
    }

    /*







|









<
<
<
<
|


|











<













|

|











|
|
|



|

|


|

















|











|
|

|

|
|
>







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
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register int i;
    int body, result;
    char *string, *arg;
    int caseObjc;
    Tcl_Obj *CONST *caseObjv;
    Tcl_Obj *armPtr;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"string ?in? patList body ... ?default body?");
	return TCL_ERROR;
    }





    string = Tcl_GetString(objv[1]);
    body = -1;

    arg = Tcl_GetString(objv[2]);
    if (strcmp(arg, "in") == 0) {
	i = 3;
    } else {
	i = 2;
    }
    caseObjc = objc - i;
    caseObjv = objv + i;

    /*
     * If all of the pattern/command pairs are lumped into a single
     * argument, split them out again.

     */

    if (caseObjc == 1) {
	Tcl_Obj **newObjv;
	
	Tcl_ListObjGetElements(interp, caseObjv[0], &caseObjc, &newObjv);
	caseObjv = newObjv;
    }

    for (i = 0;  i < caseObjc;  i += 2) {
	int patObjc, j;
	char **patObjv;
	char *pat;
	unsigned char *p;

	if (i == (caseObjc - 1)) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	            "extra case pattern with no body", -1);
	    return TCL_ERROR;
	}

	/*
	 * Check for special case of single pattern (no list) with
	 * no backslash sequences.
	 */

	pat = Tcl_GetString(caseObjv[i]);
	for (p = (unsigned char *) pat; *p != '\0'; p++) {
	    if (isspace(*p) || (*p == '\\')) {	/* INTL: ISO space, UCHAR */
		break;
	    }
	}
	if (*p == '\0') {
	    if ((*pat == 'd') && (strcmp(pat, "default") == 0)) {
		body = i + 1;
	    }
	    if (Tcl_StringMatch(string, pat)) {
		body = i + 1;
		goto match;
	    }
	    continue;
	}


	/*
	 * Break up pattern lists, then check each of the patterns
	 * in the list.
	 */

	result = Tcl_SplitList(interp, pat, &patObjc, &patObjv);
	if (result != TCL_OK) {
	    return result;
	}
	for (j = 0; j < patObjc; j++) {
	    if (Tcl_StringMatch(string, patObjv[j])) {
		body = i + 1;
		break;
	    }
	}
	ckfree((char *) patObjv);
	if (j < patObjc) {
	    break;
	}
    }

    match:
    if (body != -1) {
	armPtr = caseObjv[body - 1];
	result = Tcl_EvalObjEx(interp, caseObjv[body], 0);
	if (result == TCL_ERROR) {
	    char msg[100 + TCL_INTEGER_SPACE];
	    
	    arg = Tcl_GetString(armPtr);
	    sprintf(msg,
		    "\n    (\"%.50s\" arm line %d)", arg,
	            interp->errorLine);
	    Tcl_AddObjErrorInfo(interp, msg, -1);
	}
	return result;
    }

    /*
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
     * stack rendering objv invalid.
     */
    
    if (objc == 3) {
	varNamePtr = objv[2];
    }
    
    result = Tcl_EvalObj(interp, objv[1]);
    
    if (objc == 3) {
	if (Tcl_ObjSetVar2(interp, varNamePtr, NULL,
		    Tcl_GetObjResult(interp), TCL_PARSE_PART1) == NULL) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),  
	            "couldn't save command result in variable", -1);
	    return TCL_ERROR;
	}
    }








|



|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
     * stack rendering objv invalid.
     */
    
    if (objc == 3) {
	varNamePtr = objv[2];
    }
    
    result = Tcl_EvalObjEx(interp, objv[1], 0);
    
    if (objc == 3) {
	if (Tcl_ObjSetVar2(interp, varNamePtr, NULL,
		Tcl_GetObjResult(interp), 0) == NULL) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),  
	            "couldn't save command result in variable", -1);
	    return TCL_ERROR;
	}
    }

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
Tcl_CdObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    char *dirName;
    int dirLength;
    Tcl_DString buffer;
    int result;

    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "dirName");
	return TCL_ERROR;
    }

    if (objc == 2) {
	dirName = Tcl_GetStringFromObj(objv[1], &dirLength);
    } else {
	dirName = "~";
    }
    dirName = Tcl_TranslateFileName(interp, dirName, &buffer);
    if (dirName == NULL) {
	return TCL_ERROR;
    }
    result = TclChdir(interp, dirName);

    Tcl_DStringFree(&buffer);






    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConcatObjCmd --
 *
 *	This object-based procedure is invoked to process the "concat" Tcl
 *	command. See the user documentation for details on what it does/
 *
 * Results:
 *	A standard Tcl object result.
 *
 * Side effects:
 *	See the user documentation.
 *







<
|



|




|



|
<


|
>
|
>
>
>
>
>
>
|








|







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
Tcl_CdObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    char *dirName;

    Tcl_DString ds;
    int result;

    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "?dirName?");
	return TCL_ERROR;
    }

    if (objc == 2) {
	dirName = Tcl_GetString(objv[1]);
    } else {
	dirName = "~";
    }
    if (Tcl_TranslateFileName(interp, dirName, &ds) == NULL) {

	return TCL_ERROR;
    }

    result = Tcl_Chdir(Tcl_DStringValue(&ds));
    Tcl_DStringFree(&ds);

    if (result != 0) {
	Tcl_AppendResult(interp, "couldn't change working directory to \"",
		dirName, "\": ", Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConcatObjCmd --
 *
 *	This object-based procedure is invoked to process the "concat" Tcl
 *	command. See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl object result.
 *
 * Side effects:
 *	See the user documentation.
 *
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
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ContinueCmd -
 *
 *	This procedure is invoked to process the "continue" Tcl command.
 *	See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "continue" or the name
 *	to which "continue" was renamed: e.g., "set z continue; $z"
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_ContinueCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    if (argc != 1) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		"\"", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_CONTINUE;
}






























































































































/*
 *----------------------------------------------------------------------
 *
 * Tcl_ErrorObjCmd --
 *
 *	This procedure is invoked to process the "error" Tcl command.







|



















|


|
|

|
|
<




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







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ContinueObjCmd -
 *
 *	This procedure is invoked to process the "continue" Tcl command.
 *	See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "continue" or the name
 *	to which "continue" was renamed: e.g., "set z continue; $z"
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_ContinueObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);

	return TCL_ERROR;
    }
    return TCL_CONTINUE;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_EncodingObjCmd --
 *
 *	This command manipulates encodings.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_EncodingObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int index, length;
    Tcl_Encoding encoding;
    char *string;
    Tcl_DString ds;
    Tcl_Obj *resultPtr;

    static char *optionStrings[] = {
	"convertfrom", "convertto", "names", "system",
	NULL
    };
    enum options {
	ENC_CONVERTFROM, ENC_CONVERTTO, ENC_NAMES, ENC_SYSTEM
    };

    if (objc < 2) {
    	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
        return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
	case ENC_CONVERTTO:
	case ENC_CONVERTFROM: {
	    char *name;
	    Tcl_Obj *data;
	    if (objc == 3) {
		name = NULL;
		data = objv[2];
	    } else if (objc == 4) {
		name = Tcl_GetString(objv[2]);
		data = objv[3];
	    } else {
		Tcl_WrongNumArgs(interp, 2, objv, "?encoding? data");
		return TCL_ERROR;
	    }
	    
	    encoding = Tcl_GetEncoding(interp, name);
	    if (!encoding) {
		return TCL_ERROR;
	    }

	    if ((enum options) index == ENC_CONVERTFROM) {
		/*
		 * Treat the string as binary data.
		 */

		string = (char *) Tcl_GetByteArrayFromObj(data, &length);
		Tcl_ExternalToUtfDString(encoding, string, length, &ds);

		/*
		 * Note that we cannot use Tcl_DStringResult here because
		 * it will truncate the string at the first null byte.
		 */

		Tcl_SetStringObj(Tcl_GetObjResult(interp),
			Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
		Tcl_DStringFree(&ds);
	    } else {
		/*
		 * Store the result as binary data.
		 */

		string = Tcl_GetStringFromObj(data, &length);
		Tcl_UtfToExternalDString(encoding, string, length, &ds);
		resultPtr = Tcl_GetObjResult(interp);
		Tcl_SetByteArrayObj(resultPtr, 
			(unsigned char *) Tcl_DStringValue(&ds),
			Tcl_DStringLength(&ds));
		Tcl_DStringFree(&ds);
	    }

	    Tcl_FreeEncoding(encoding);
	    break;
	}
	case ENC_NAMES: {
	    if (objc > 2) {
		Tcl_WrongNumArgs(interp, 2, objv, NULL);
		return TCL_ERROR;
	    }
	    Tcl_GetEncodingNames(interp);
	    break;
	}
	case ENC_SYSTEM: {
	    if (objc > 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "?encoding?");
		return TCL_ERROR;
	    }
	    if (objc == 2) {
	        Tcl_SetResult(interp, Tcl_GetEncodingName(NULL), TCL_STATIC);
	    } else {
	        return Tcl_SetSystemEncoding(interp,
			Tcl_GetStringFromObj(objv[2], NULL));
	    }
	    break;
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ErrorObjCmd --
 *
 *	This procedure is invoked to process the "error" Tcl command.
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
Tcl_ErrorObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Interp *iPtr = (Interp *) interp;
    register Tcl_Obj *namePtr;
    char *info;
    int infoLen;

    if ((objc < 2) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 1, objv, "message ?errorInfo? ?errorCode?");
	return TCL_ERROR;
    }
    
    if (objc >= 3) {		/* process the optional info argument */
	info = Tcl_GetStringFromObj(objv[2], &infoLen);
	if (*info != 0) {
	    Tcl_AddObjErrorInfo(interp, info, infoLen);
	    iPtr->flags |= ERR_ALREADY_LOGGED;
	}
    }
    
    if (objc == 4) {
	namePtr = Tcl_NewStringObj("errorCode", -1);
	Tcl_ObjSetVar2(interp, namePtr, (Tcl_Obj *) NULL, objv[3],
		TCL_GLOBAL_ONLY);
	iPtr->flags |= ERROR_CODE_SET;
	Tcl_DecrRefCount(namePtr); /* we're done with name object */
    }
    
    Tcl_SetObjResult(interp, objv[1]);
    return TCL_ERROR;
}

/*







<

















<
<
|

<







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
Tcl_ErrorObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Interp *iPtr = (Interp *) interp;

    char *info;
    int infoLen;

    if ((objc < 2) || (objc > 4)) {
	Tcl_WrongNumArgs(interp, 1, objv, "message ?errorInfo? ?errorCode?");
	return TCL_ERROR;
    }
    
    if (objc >= 3) {		/* process the optional info argument */
	info = Tcl_GetStringFromObj(objv[2], &infoLen);
	if (*info != 0) {
	    Tcl_AddObjErrorInfo(interp, info, infoLen);
	    iPtr->flags |= ERR_ALREADY_LOGGED;
	}
    }
    
    if (objc == 4) {


	Tcl_SetVar2Ex(interp, "errorCode", NULL, objv[3], TCL_GLOBAL_ONLY);
	iPtr->flags |= ERROR_CODE_SET;

    }
    
    Tcl_SetObjResult(interp, objv[1]);
    return TCL_ERROR;
}

/*
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

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");
	return TCL_ERROR;
    }
    
    if (objc == 2) {
	result = Tcl_EvalObj(interp, objv[1]);
    } else {
	/*
	 * More than one argument: concatenate them together with spaces
	 * between, then evaluate the result.
	 */
    
	objPtr = Tcl_ConcatObj(objc-1, objv+1);

	result = Tcl_EvalObj(interp, objPtr);
	Tcl_DecrRefCount(objPtr);  /* we're done with the object */
    }
    if (result == TCL_ERROR) {
	char msg[60];

	sprintf(msg, "\n    (\"eval\" body line %d)", interp->errorLine);
	Tcl_AddObjErrorInfo(interp, msg, -1);
    }
    return result;
}

/*







|







>
|
|


|
>







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

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");
	return TCL_ERROR;
    }
    
    if (objc == 2) {
	result = Tcl_EvalObjEx(interp, objv[1], 0);
    } else {
	/*
	 * More than one argument: concatenate them together with spaces
	 * between, then evaluate the result.
	 */
    
	objPtr = Tcl_ConcatObj(objc-1, objv+1);
	Tcl_IncrRefCount(objPtr);
	result = Tcl_EvalObjEx(interp, objPtr, 0);
	Tcl_DecrRefCount(objPtr);
    }
    if (result == TCL_ERROR) {
	char msg[32 + TCL_INTEGER_SPACE];

	sprintf(msg, "\n    (\"eval\" body line %d)", interp->errorLine);
	Tcl_AddObjErrorInfo(interp, msg, -1);
    }
    return result;
}

/*
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
	/* ARGSUSED */
int
Tcl_ExprObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register Tcl_Obj *objPtr;
    Tcl_Obj *resultPtr;
    register char *bytes;
    int length, i, result;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");







|







703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
	/* ARGSUSED */
int
Tcl_ExprObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{	 
    register Tcl_Obj *objPtr;
    Tcl_Obj *resultPtr;
    register char *bytes;
    int length, i, result;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
	    Tcl_DecrRefCount(resultPtr);  /* done with the result object */
	}
	return result;
    }

    /*
     * Create a new object holding the concatenated argument strings.
     * THIS FAILS IF AN OBJECT'S STRING REP HAS A NULL BYTE.
     */

    bytes = Tcl_GetStringFromObj(objv[1], &length);
    objPtr = Tcl_NewStringObj(bytes, length);
    Tcl_IncrRefCount(objPtr);
    for (i = 2;  i < objc;  i++) {
	Tcl_AppendToObj(objPtr, " ", 1);







<







725
726
727
728
729
730
731

732
733
734
735
736
737
738
	    Tcl_DecrRefCount(resultPtr);  /* done with the result object */
	}
	return result;
    }

    /*
     * Create a new object holding the concatenated argument strings.

     */

    bytes = Tcl_GetStringFromObj(objv[1], &length);
    objPtr = Tcl_NewStringObj(bytes, length);
    Tcl_IncrRefCount(objPtr);
    for (i = 2;  i < objc;  i++) {
	Tcl_AppendToObj(objPtr, " ", 1);
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668











669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696

697
698

699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717

718
719
720
721
722
723

724
725



726
727
728
729
730
731
732

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

752
753
754
755
756
757
758
759
760



761
762
763

764
765
766
767
768
769

770




771
772


773

774
775
776




777
778
779
780










781
782

783
784
785
786
787



788
789
790
791




792
793
794
795
796




797




798
799



800
801







802
803
804
805



806
807

808
809
810


811
812
813


814
815
816

817
818
819
820
821


822






823
824
825




826



827
828
829

830

831
832









833



834
835
836
837






838





839
840
841

842
843
844


845
846
847
848

849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094


1095
1096
1097
1098







1099




1100



1101








1102








1103
1104






1105





1106
1107
1108
1109

1110
1111


1112
1113
1114



1115



1116
1117
1118
1119
1120


1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133



1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144


1145
1146
1147
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157
1158







1159
1160
1161








1162

1163
1164


1165



1166






1167


1168
1169
1170









1171














1172



























1173

1174
1175
1176

















1177





























































1178

1179












1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
int
Tcl_FileObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    char *fileName, *extension, *errorString;
    int statOp = 0;		/* Init. to avoid compiler warning. */
    int length;
    int mode = 0;			/* Initialized only to prevent
					 * compiler warning message. */
    struct stat statBuf;
    Tcl_DString buffer;
    Tcl_Obj *resultPtr;
    int index, result;

/*
 * This list of constants should match the fileOption string array below.
 */












enum {FILE_ATIME, FILE_ATTRIBUTES, FILE_COPY, FILE_DELETE, FILE_DIRNAME,
	FILE_EXECUTABLE, FILE_EXISTS, FILE_EXTENSION, FILE_ISDIRECTORY,
	FILE_ISFILE, FILE_JOIN, FILE_LSTAT, FILE_MTIME, FILE_MKDIR,
	FILE_NATIVENAME, FILE_OWNED, FILE_PATHTYPE, FILE_READABLE,
	FILE_READLINK, FILE_RENAME, FILE_ROOTNAME, FILE_SIZE, FILE_SPLIT,
	FILE_STAT, FILE_TAIL, FILE_TYPE, FILE_VOLUMES, FILE_WRITABLE};


    static char *fileOptions[] = {"atime", "attributes", "copy", "delete", 
    	    "dirname", "executable", "exists", "extension", "isdirectory", 
    	    "isfile", "join", "lstat", "mtime", "mkdir", "nativename", 
    	    "owned", "pathtype", "readable", "readlink", "rename",
    	    "rootname", "size", "split", "stat", "tail", "type", "volumes", 
    	    "writable", (char *) NULL};

    if (objc < 2) {
    	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
        return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], fileOptions, "option", 0, &index)
	    != TCL_OK) {
    	return TCL_ERROR;
    }
    
    result = TCL_OK;
    /* 
     * First, do the volumes command, since it is the only one that

     * has objc == 2.
     */

	
    if ( index == FILE_VOLUMES) {
        if ( objc != 2 ) {
	    Tcl_WrongNumArgs(interp, 1, objv, "volumes");
	    return TCL_ERROR;
	}
	result = TclpListVolumes(interp);
	return result;
    }
    
    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "name ?arg ...?");
	return TCL_ERROR;
    }

    Tcl_DStringInit(&buffer);
    resultPtr = Tcl_GetObjResult(interp);
    


    /*
     * Handle operations on the file name.
     */
    
    switch (index) {
        case FILE_ATTRIBUTES:

            result = TclFileAttrsCmd(interp, objc - 2, objv + 2);
    	    goto done;



    	case FILE_DIRNAME:	{
    	    int pargc;
	    char **pargv;

	    if (objc != 3) {
	    	errorString = "dirname name";
	    	goto not3Args;

	    }

	    fileName = Tcl_GetStringFromObj(objv[2], &length);

	    /*
	     * If there is only one element, and it starts with a tilde,
	     * perform tilde substitution and resplit the path.
	     */

	    Tcl_SplitPath(fileName, &pargc, &pargv);
	    if ((pargc == 1) && (*fileName == '~')) {
	        ckfree((char*) pargv);
	        fileName = Tcl_TranslateFileName(interp, fileName, &buffer);
	        if (fileName == NULL) {
		    result = TCL_ERROR;
		    goto done;
	        }
	        Tcl_SplitPath(fileName, &pargc, &pargv);
	        Tcl_DStringSetLength(&buffer, 0);

	    }

	    /*
	     * Return all but the last component.  If there is only one
	     * component, return it if the path was non-relative, otherwise
	     * return the current directory.
	     */

	    if (pargc > 1) {



	    	Tcl_JoinPath(pargc-1, pargv, &buffer);
	    	Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&buffer),
	    		buffer.length);

	    } else if ((pargc == 0)
		    || (Tcl_GetPathType(pargv[0]) == TCL_PATH_RELATIVE)) {
		Tcl_SetStringObj(resultPtr, (tclPlatform == TCL_PLATFORM_MAC)
			? ":" : ".", 1);
	    } else {
	    	Tcl_SetStringObj(resultPtr, pargv[0], -1);	    }

	    ckfree((char *)pargv);




	    goto done;
	}


    	case FILE_TAIL: {

	    int pargc;
	    char **pargv;





	    if (objc != 3) {
	    	errorString = "tail name";
	    	goto not3Args;
	    }










	    
	    fileName = Tcl_GetStringFromObj(objv[2], &length);


	    /*
	     * If there is only one element, and it starts with a tilde,
	     * perform tilde substitution and resplit the path.
	     */




	    Tcl_SplitPath(fileName, &pargc, &pargv);
	    if ((pargc == 1) && (*fileName == '~')) {
	    	ckfree((char*) pargv);




	    	fileName = Tcl_TranslateFileName(interp, fileName, &buffer);
	    	if (fileName == NULL) {
		    result = TCL_ERROR;
		    goto done;
	        }




	        Tcl_SplitPath(fileName, &pargc, &pargv);




	        Tcl_DStringSetLength(&buffer, 0);
	    }




	    /*







	     * Return the last component, unless it is the only component,
	     * and it is the root of an absolute path.
	     */




	    if (pargc > 0) {
	    	if ((pargc > 1)

		    	|| (Tcl_GetPathType(pargv[0]) == TCL_PATH_RELATIVE)) {
		    Tcl_SetStringObj(resultPtr, pargv[pargc - 1], -1);
	    	}


	    }
	    ckfree((char *)pargv);
	    goto done;


	}
	case FILE_ROOTNAME: {
	    char *fileName;

	    
	    if (objc != 3) {
	    	errorString = "rootname name";
	    	goto not3Args;
	    }


	    






	    fileName = Tcl_GetStringFromObj(objv[2], &length);
	    extension = TclGetExtension(fileName);
	    if (extension == NULL) {




	    	Tcl_SetObjResult(interp, objv[2]);



	    } else {
	        Tcl_SetStringObj(resultPtr, fileName,
			(int) (length - strlen(extension)));

	    }

	    goto done;
	}









	case FILE_EXTENSION:



	    if (objc != 3) {
	    	errorString = "extension name";
	    	goto not3Args;
	    }






	    extension = TclGetExtension(Tcl_GetStringFromObj(objv[2],&length));






	    if (extension != NULL) {
	    	Tcl_SetStringObj(resultPtr, extension, (int)strlen(extension));

	    }
	    goto done;
	case FILE_PATHTYPE:


	    if (objc != 3) {
	    	errorString = "pathtype name";
	    	goto not3Args;
	    }

	    switch (Tcl_GetPathType(Tcl_GetStringFromObj(objv[2], &length))) {
	    	case TCL_PATH_ABSOLUTE:
	    	    Tcl_SetStringObj(resultPtr, "absolute", -1);
		    break;
	    	case TCL_PATH_RELATIVE:
	    	    Tcl_SetStringObj(resultPtr, "relative", -1);
	    	    break;
	    	case TCL_PATH_VOLUME_RELATIVE:
		    Tcl_SetStringObj(resultPtr, "volumerelative", -1);
		    break;
	    }
	    goto done;
	case FILE_SPLIT: {
	    int pargc, i;
	    char **pargvList;
	    Tcl_Obj *listObjPtr;
		
	    if (objc != 3) {
    	    	errorString = "split name";
	    	goto not3Args;
	    }
		
	    Tcl_SplitPath(Tcl_GetStringFromObj(objv[2], &length), &pargc,
	    	    &pargvList);
	    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
	    for (i = 0; i < pargc; i++) {
	    	Tcl_ListObjAppendElement(interp, listObjPtr,
			Tcl_NewStringObj(pargvList[i], -1));
	    }
	    ckfree((char *) pargvList);
	    Tcl_SetObjResult(interp, listObjPtr);
	    goto done;
	}
	case FILE_JOIN: {
	    char **pargv = (char **) ckalloc((objc - 2) * sizeof(char *));
	    int i;
	    
	    for (i = 2; i < objc; i++) {
	    	pargv[i - 2] = Tcl_GetStringFromObj(objv[i], &length);
	    }
	    Tcl_JoinPath(objc - 2, pargv, &buffer);
	    Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&buffer), 
                    buffer.length);
	    ckfree((char *) pargv);
	    Tcl_DStringFree(&buffer);
	    goto done;
	}
	case FILE_RENAME: {
	    char **pargv = (char **) ckalloc(objc * sizeof(char *));
	    int i;
	    
	    for (i = 0; i < objc; i++) {
	    	pargv[i] = Tcl_GetStringFromObj(objv[i], &length);
	    }
	    result = TclFileRenameCmd(interp, objc, pargv);
	    ckfree((char *) pargv);
	    goto done;
	}
	case FILE_MKDIR: {
	    char **pargv = (char **) ckalloc(objc * sizeof(char *));
	    int i;
	    
	    for (i = 0; i < objc; i++) {
	    	pargv[i] = Tcl_GetStringFromObj(objv[i], &length);
	    }
	    result = TclFileMakeDirsCmd(interp, objc, pargv);
	    ckfree((char *) pargv);
	    goto done;
	}
	case FILE_DELETE: {
	    char **pargv = (char **) ckalloc(objc * sizeof(char *));
	    int i;
	    
	    for (i = 0; i < objc; i++) {
	    	pargv[i] = Tcl_GetStringFromObj(objv[i], &length);
	    }
	    result = TclFileDeleteCmd(interp, objc, pargv);
	    ckfree((char *) pargv);
	    goto done;
	}
	case FILE_COPY: {
	    char **pargv = (char **) ckalloc(objc * sizeof(char *));
	    int i;
	    
	    for (i = 0; i < objc; i++) {
	    	pargv[i] = Tcl_GetStringFromObj(objv[i], &length);
	    }
	    result = TclFileCopyCmd(interp, objc, pargv);
	    ckfree((char *) pargv);
	    goto done;
	}
	case FILE_NATIVENAME:
	    fileName = Tcl_TranslateFileName(interp,
	    	    Tcl_GetStringFromObj(objv[2], &length), &buffer);
	    if (fileName == NULL) {
		result = TCL_ERROR ;
	    } else {
		Tcl_SetStringObj(resultPtr, fileName, -1);
	    }
	    goto done;
    }

    /*
     * Next, handle operations that can be satisfied with the "access"
     * kernel call.
     */

    fileName = Tcl_TranslateFileName(interp,
	    Tcl_GetStringFromObj(objv[2], &length), &buffer);
	
    switch (index) {
    	case FILE_READABLE:
    	    if (objc != 3) {
	    	errorString = "readable name";
	    	goto not3Args;
	    }
	    mode = R_OK;
checkAccess:
	    /*
	     * The result might have been set within Tcl_TranslateFileName
	     * (like no such user "blah" for file exists ~blah)
	     * but we don't want to flag an error in that case.
	     */
	    if (fileName == NULL) {
		Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
	    } else {
		Tcl_SetBooleanObj(resultPtr, (access(fileName, mode) != -1));
	    }
	    goto done;
	  case FILE_WRITABLE:
	    if (objc != 3) {
	    	errorString = "writable name";
	    	goto not3Args;
	    }
	    mode = W_OK;
	    goto checkAccess;
	  case FILE_EXECUTABLE:
	    if (objc != 3) {
	    	errorString = "executable name";
	    	goto not3Args;
	    }
	    mode = X_OK;
	    goto checkAccess;
	  case FILE_EXISTS:
	    if (objc != 3) {
	    	errorString = "exists name";
	    	goto not3Args;
	    }
	    mode = F_OK;
	    goto checkAccess;
    }

	
    /*
     * Lastly, check stuff that requires the file to be stat-ed.
     */

    if (fileName == NULL) {
	result = TCL_ERROR;
	goto done;
    }
    
    switch (index) {
    	case FILE_ATIME:
    	    if (objc != 3) {
	    	errorString = "atime name";
	    	goto not3Args;
	    }
	    
	    if (stat(fileName, &statBuf) == -1) {
	    	goto badStat;
	    }
	    Tcl_SetLongObj(resultPtr, (long) statBuf.st_atime);
	    goto done;
    	case FILE_ISDIRECTORY:
    	    if (objc != 3) {
    	    	errorString = "isdirectory name";
    	    	goto not3Args;
    	    }
    	    statOp = 2;
    	    break;
    	case FILE_ISFILE:
    	    if (objc != 3) {
    	    	errorString = "isfile name";
    	    	goto not3Args;
    	    }
    	    statOp = 1;
    	    break;
    	case FILE_LSTAT:
    	    if (objc != 4) {
    	    	Tcl_WrongNumArgs(interp, 1, objv, "lstat name varName");
    	    	result = TCL_ERROR;
    	    	goto done;
    	    }
    	    
    	    if (lstat(fileName, &statBuf) == -1) {
    	    	Tcl_AppendStringsToObj(resultPtr, "couldn't lstat \"",
    	    		Tcl_GetStringFromObj(objv[2], &length), "\": ",
    	    		Tcl_PosixError(interp), (char *) NULL);
    	    	result = TCL_ERROR;
    	    	goto done;
    	    }
    	    result = StoreStatData(interp, Tcl_GetStringFromObj(objv[3],
    	    	    &length), &statBuf);
    	    goto done;
	case FILE_MTIME:
	    if (objc != 3) {
	    	errorString = "mtime name";
	    	goto not3Args;
	    }
	    if (stat(fileName, &statBuf) == -1) {
	    	goto badStat;
	    }
	    Tcl_SetLongObj(resultPtr, (long) statBuf.st_mtime);
	    goto done;
	case FILE_OWNED:
	    if (objc != 3) {
	    	errorString = "owned name";
	    	goto not3Args;
	    }	        	    
    	    statOp = 0;
    	    break;
	case FILE_READLINK: {
	    char linkValue[MAXPATHLEN + 1];
	    int linkLength;
		
	    if (objc != 3) {
	    	errorString = "readlink name";
	        goto not3Args;
	    }

	    /*
	     * If S_IFLNK isn't defined it means that the machine doesn't
	     * support symbolic links, so the file can't possibly be a
	     * symbolic link.  Generate an EINVAL error, which is what
	     * happens on machines that do support symbolic links when
	     * you invoke readlink on a file that isn't a symbolic link.
	     */

#ifndef S_IFLNK
	    linkLength = -1;
	    errno = EINVAL;
#else
	    linkLength = readlink(fileName, linkValue, sizeof(linkValue) - 1);
#endif /* S_IFLNK */
	    if (linkLength == -1) {


	    	Tcl_AppendStringsToObj(resultPtr, "couldn't readlink \"", 
	    		Tcl_GetStringFromObj(objv[2], &length), "\": ", 
	    		Tcl_PosixError(interp), (char *) NULL);
	    	result = TCL_ERROR;







	    	goto done;




	    }



	    linkValue[linkLength] = 0;








	    Tcl_SetStringObj(resultPtr, linkValue, linkLength);








	    goto done;
	}






	case FILE_SIZE:





	    if (objc != 3) {
	    	errorString = "size name";
	    	goto not3Args;
	    }

	    if (stat(fileName, &statBuf) == -1) {
	    	goto badStat;


	    }
	    Tcl_SetLongObj(resultPtr, (long) statBuf.st_size);
	    goto done;



	case FILE_STAT:



	    if (objc != 4) {
	    	Tcl_WrongNumArgs(interp, 1, objv, "stat name varName");
	    	result = TCL_ERROR;
	    	goto done;
	    }



	    if (stat(fileName, &statBuf) == -1) {
badStat:
		Tcl_AppendStringsToObj(resultPtr, "couldn't stat \"", 
			Tcl_GetStringFromObj(objv[2], &length),
		    	"\": ", Tcl_PosixError(interp), (char *) NULL);
	    	result = TCL_ERROR;
	    	goto done;
	    }
	    result = StoreStatData(interp, Tcl_GetStringFromObj(objv[3],
	    	    &length), &statBuf);
	    goto done;
	case FILE_TYPE:



	    if (objc != 3) {
	    	errorString = "type name";
	    	goto not3Args;
	    }
	    if (lstat(fileName, &statBuf) == -1) {
	    	goto badStat;
	    }
	    errorString = GetTypeFromMode((int) statBuf.st_mode);
	    Tcl_SetStringObj(resultPtr, errorString, -1);
	    goto done;
    }



    if (stat(fileName, &statBuf) == -1) {
    	Tcl_SetBooleanObj(resultPtr, 0);
	goto done;
    }
    switch (statOp) {
	case 0:
	    /*
	     * For Windows and Macintosh, there are no user ids 
	     * associated with a file, so we always return 1.

	     */

#if (defined(__WIN32__) || defined(MAC_TCL))
	    mode = 1;







#else
	    mode = (geteuid() == statBuf.st_uid);
#endif








	    break;

	case 1:
	    mode = S_ISREG(statBuf.st_mode);


	    break;



	case 2:






	    mode = S_ISDIR(statBuf.st_mode);


	    break;
    }
    Tcl_SetBooleanObj(resultPtr, mode);
























done:



























    Tcl_DStringFree(&buffer);

    return result;

not3Args:

















    Tcl_WrongNumArgs(interp, 1, objv, errorString);





























































    result = TCL_ERROR;

    goto done;












}

/*
 *----------------------------------------------------------------------
 *
 * StoreStatData --
 *
 *	This is a utility procedure that breaks out the fields of a
 *	"stat" structure and stores them in textual form into the
 *	elements of an associative array.
 *
 * Results:
 *	Returns a standard Tcl return value.  If an error occurs then
 *	a message is left in interp->result.
 *
 * Side effects:
 *	Elements of the associative array given by "varName" are modified.
 *
 *----------------------------------------------------------------------
 */

static int
StoreStatData(interp, varName, statPtr)
    Tcl_Interp *interp;			/* Interpreter for error reports. */
    char *varName;			/* Name of associative array variable
					 * in which to store stat results. */
    struct stat *statPtr;		/* Pointer to buffer containing
					 * stat data to store in varName. */
{
    char string[30];

    sprintf(string, "%ld", (long) statPtr->st_dev);
    if (Tcl_SetVar2(interp, varName, "dev", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    sprintf(string, "%ld", (long) statPtr->st_ino);
    if (Tcl_SetVar2(interp, varName, "ino", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    sprintf(string, "%ld", (long) statPtr->st_mode);
    if (Tcl_SetVar2(interp, varName, "mode", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    sprintf(string, "%ld", (long) statPtr->st_nlink);
    if (Tcl_SetVar2(interp, varName, "nlink", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    sprintf(string, "%ld", (long) statPtr->st_uid);
    if (Tcl_SetVar2(interp, varName, "uid", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    sprintf(string, "%ld", (long) statPtr->st_gid);
    if (Tcl_SetVar2(interp, varName, "gid", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    sprintf(string, "%lu", (unsigned long) statPtr->st_size);
    if (Tcl_SetVar2(interp, varName, "size", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    sprintf(string, "%ld", (long) statPtr->st_atime);
    if (Tcl_SetVar2(interp, varName, "atime", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    sprintf(string, "%ld", (long) statPtr->st_mtime);
    if (Tcl_SetVar2(interp, varName, "mtime", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    sprintf(string, "%ld", (long) statPtr->st_ctime);
    if (Tcl_SetVar2(interp, varName, "ctime", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    if (Tcl_SetVar2(interp, varName, "type",
	    GetTypeFromMode((int) statPtr->st_mode), TCL_LEAVE_ERR_MSG) 
            == NULL) {
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







<
<
<
<
<
<
<

|





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





<
|
|


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

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

<
<
<
<
|
<
|
|
|
<
>








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

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

<
|

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

<
<
>
>

|
<
>


<
|

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

<
|

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

<
|

>
|










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

<
|

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











|


|

|
>
>
|
|

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

<
|

>
|
|
>
>

<
<
>
>
>
|
>
>
>


|
<

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

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

<
|
>


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













|















|

|




|




|




|




|




|









|




|




|





|
|







781
782
783
784
785
786
787







788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813






814
815
816
817
818

819
820
821
822
823
824


825
826

827
828

829
830

831
832
833
834
835


836
837
838

839
840
841
842
843


844


845
846

847
848
849
850
851
852
853
854
855
856
857
858
859

860
861



862




863

864
865
866

867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902

903
904
905
906
907
908

909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924




925
926
927
928
929

930
931
932
933
934
935
936

937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953

954
955
956
957
958
959
960
961


962
963
964
965
966
967
968
969

970
971
972
973


974
975
976
977

978
979
980

981
982
983
984
985
986
987
988
989
990
991
992

993
994
995
996
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022

1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037

1038
1039
1040

1041
1042
1043
1044

1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058





1059



1060


























1061


1062





1063
1064



1065


1066















1067


1068

















1069

























1070


1071

1072
1073






1074










1075
1076




1077
1078






































































1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150

1151
1152
1153
1154
1155
1156
1157
1158


1159
1160
1161
1162
1163
1164
1165
1166
1167
1168

1169
1170
1171
1172



1173
1174


1175



1176
1177
1178
1179
1180








1181
1182
1183
1184
1185



1186


1187

1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214

1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
int
Tcl_FileObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{







    Tcl_Obj *resultPtr;
    int index;

/*
 * This list of constants should match the fileOption string array below.
 */

    static char *fileOptions[] = {
	"atime",	"attributes",	"copy",		"delete",
	"dirname",	"executable",	"exists",	"extension",
	"isdirectory",	"isfile",	"join",		"lstat",
	"mtime",	"mkdir",	"nativename",	"owned",
	"pathtype",	"readable",	"readlink",	"rename",
	"rootname",	"size",		"split",	"stat",
	"tail",		"type",		"volumes",	"writable",
	(char *) NULL
    };
    enum options {
	FILE_ATIME,	FILE_ATTRIBUTES, FILE_COPY,	FILE_DELETE,
	FILE_DIRNAME,	FILE_EXECUTABLE, FILE_EXISTS,	FILE_EXTENSION,
	FILE_ISDIRECTORY, FILE_ISFILE,	FILE_JOIN,	FILE_LSTAT,
	FILE_MTIME,	FILE_MKDIR,	FILE_NATIVENAME, FILE_OWNED,
	FILE_PATHTYPE,	FILE_READABLE,	FILE_READLINK,	FILE_RENAME,
	FILE_ROOTNAME,	FILE_SIZE,	FILE_SPLIT,	FILE_STAT,
	FILE_TAIL,	FILE_TYPE,	FILE_VOLUMES,	FILE_WRITABLE
    };







    if (objc < 2) {
    	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
        return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], fileOptions, "option", 0,
	    &index) != TCL_OK) {
    	return TCL_ERROR;
    }

    resultPtr = Tcl_GetObjResult(interp);


    switch ((enum options) index) {
    	case FILE_ATIME: {

	    struct stat buf;
	    

	    if (objc != 3) {
		goto only3Args;

	    }
	    if (GetStatBuf(interp, objv[2], TclpStat, &buf) != TCL_OK) {
		return TCL_ERROR;
	    }
	    Tcl_SetLongObj(resultPtr, (long) buf.st_atime);


	    return TCL_OK;
	}
	case FILE_ATTRIBUTES: {

            return TclFileAttrsCmd(interp, objc, objv);
	}
	case FILE_COPY: {
	    int result;
	    char **argv;





	    argv = StringifyObjects(objc, objv);
	    result = TclFileCopyCmd(interp, objc, argv);

	    ckfree((char *) argv);
	    return result;
	}	    
	case FILE_DELETE: {
	    int result;
	    char **argv;

	    argv = StringifyObjects(objc, objv);
	    result = TclFileDeleteCmd(interp, objc, argv);
	    ckfree((char *) argv);
	    return result;
	}
    	case FILE_DIRNAME: {

    	    int argc;
	    char **argv;








	    if (objc != 3) {

		goto only3Args;
	    }
	    if (SplitPath(interp, objv[2], &argc, &argv) != TCL_OK) {

		return TCL_ERROR;
	    }

	    /*
	     * Return all but the last component.  If there is only one
	     * component, return it if the path was non-relative, otherwise
	     * return the current directory.
	     */

	    if (argc > 1) {
		Tcl_DString ds;

		Tcl_DStringInit(&ds);
	    	Tcl_JoinPath(argc - 1, argv, &ds);
	    	Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&ds),
			Tcl_DStringLength(&ds));
		Tcl_DStringFree(&ds);
	    } else if ((argc == 0)
		    || (Tcl_GetPathType(argv[0]) == TCL_PATH_RELATIVE)) {
		Tcl_SetStringObj(resultPtr,
			((tclPlatform == TCL_PLATFORM_MAC) ? ":" : "."), 1);
	    } else {
	    	Tcl_SetStringObj(resultPtr, argv[0], -1);
	    }
	    ckfree((char *) argv);
	    return TCL_OK;
	}
	case FILE_EXECUTABLE: {
	    if (objc != 3) {
		goto only3Args;
	    }
	    return CheckAccess(interp, objv[2], X_OK);
	}
	case FILE_EXISTS: {
	    if (objc != 3) {
		goto only3Args;

	    }
	    return CheckAccess(interp, objv[2], F_OK);
	}
	case FILE_EXTENSION: {
	    char *fileName, *extension;
	    if (objc != 3) {

	    	goto only3Args;
	    }
	    fileName = Tcl_GetString(objv[2]);
	    extension = TclGetExtension(fileName);
	    if (extension != NULL) {
	    	Tcl_SetStringObj(resultPtr, extension, -1);
	    }
	    return TCL_OK;
	}
    	case FILE_ISDIRECTORY: {
	    int value;
	    struct stat buf;

	    if (objc != 3) {
		goto only3Args;
	    }




	    value = 0;
	    if (GetStatBuf(NULL, objv[2], TclpStat, &buf) == TCL_OK) {
		value = S_ISDIR(buf.st_mode);
	    }
	    Tcl_SetBooleanObj(resultPtr, value);

	    return TCL_OK;
	}
    	case FILE_ISFILE: {
	    int value;
	    struct stat buf;
	    
    	    if (objc != 3) {

    	    	goto only3Args;
    	    }
	    value = 0;
	    if (GetStatBuf(NULL, objv[2], TclpStat, &buf) == TCL_OK) {
		value = S_ISREG(buf.st_mode);
	    }
	    Tcl_SetBooleanObj(resultPtr, value);
	    return TCL_OK;
	}
	case FILE_JOIN: {
	    char **argv;
	    Tcl_DString ds;

	    if (objc < 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "name ?name ...?");
		return TCL_ERROR;
	    }

	    argv = StringifyObjects(objc - 2, objv + 2);
	    Tcl_DStringInit(&ds);
	    Tcl_JoinPath(objc - 2, argv, &ds);
	    Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&ds),
		    Tcl_DStringLength(&ds));
	    Tcl_DStringFree(&ds);
	    ckfree((char *) argv);
	    return TCL_OK;


	}
    	case FILE_LSTAT: {
	    char *varName;
	    struct stat buf;

    	    if (objc != 4) {
    	    	Tcl_WrongNumArgs(interp, 2, objv, "name varName");
    	    	return TCL_ERROR;

    	    }
	    if (GetStatBuf(interp, objv[2], TclpLstat, &buf) != TCL_OK) {
		return TCL_ERROR;
	    }


	    varName = Tcl_GetString(objv[3]);
	    return StoreStatData(interp, varName, &buf);
	}
	case FILE_MTIME: {

	    struct stat buf;
	    
	    if (objc != 3) {

		goto only3Args;
	    }
	    if (GetStatBuf(interp, objv[2], TclpStat, &buf) != TCL_OK) {
		return TCL_ERROR;
	    }
	    Tcl_SetLongObj(resultPtr, (long) buf.st_mtime);
	    return TCL_OK;
	}
	case FILE_MKDIR: {
	    char **argv;
	    int result;


	    if (objc < 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "name ?name ...?");
		return TCL_ERROR;
	    }
	    argv = StringifyObjects(objc, objv);
	    result = TclFileMakeDirsCmd(interp, objc, argv);
	    ckfree((char *) argv);
	    return result;
	}
	case FILE_NATIVENAME: {
	    char *fileName;

	    Tcl_DString ds;

	    if (objc != 3) {
		goto only3Args;
	    }
	    fileName = Tcl_GetString(objv[2]);
	    fileName = Tcl_TranslateFileName(interp, fileName, &ds);
	    if (fileName == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetStringObj(resultPtr, fileName, Tcl_DStringLength(&ds));
	    Tcl_DStringFree(&ds);
	    return TCL_OK;
	}
	case FILE_OWNED: {
	    int value;
	    struct stat buf;
	    
	    if (objc != 3) {

		goto only3Args;
	    }
	    value = 0;
	    if (GetStatBuf(NULL, objv[2], TclpStat, &buf) == TCL_OK) {
		/*
		 * For Windows and Macintosh, there are no user ids 
		 * associated with a file, so we always return 1.
		 */

#if (defined(__WIN32__) || defined(MAC_TCL))
		value = 1;
#else
		value = (geteuid() == buf.st_uid);
#endif
	    }	    

	    Tcl_SetBooleanObj(resultPtr, value);
	    return TCL_OK;
	}

	case FILE_PATHTYPE: {
	    char *fileName;

	    if (objc != 3) {

		goto only3Args;
	    }
	    fileName = Tcl_GetString(objv[2]);
	    switch (Tcl_GetPathType(fileName)) {
	    	case TCL_PATH_ABSOLUTE:
	    	    Tcl_SetStringObj(resultPtr, "absolute", -1);
		    break;
	    	case TCL_PATH_RELATIVE:
	    	    Tcl_SetStringObj(resultPtr, "relative", -1);
	    	    break;
	    	case TCL_PATH_VOLUME_RELATIVE:
		    Tcl_SetStringObj(resultPtr, "volumerelative", -1);
		    break;
	    }





	    return TCL_OK;



	}


























    	case FILE_READABLE: {


	    if (objc != 3) {





		goto only3Args;
	    }



	    return CheckAccess(interp, objv[2], R_OK);


	}















	case FILE_READLINK: {


	    char *fileName, *contents;

















	    Tcl_DString name, link;

























		


	    if (objc != 3) {

		goto only3Args;
	    }






	    










	    fileName = Tcl_GetString(objv[2]);
	    fileName = Tcl_TranslateFileName(interp, fileName, &name);




	    if (fileName == NULL) {
		return TCL_ERROR;






































































	    }

	    /*
	     * If S_IFLNK isn't defined it means that the machine doesn't
	     * support symbolic links, so the file can't possibly be a
	     * symbolic link.  Generate an EINVAL error, which is what
	     * happens on machines that do support symbolic links when
	     * you invoke readlink on a file that isn't a symbolic link.
	     */

#ifndef S_IFLNK
	    contents = NULL;
	    errno = EINVAL;
#else
	    contents = TclpReadlink(fileName, &link);
#endif /* S_IFLNK */

	    Tcl_DStringFree(&name);
	    if (contents == NULL) {
	    	Tcl_AppendResult(interp, "could not readlink \"", 
	    		Tcl_GetString(objv[2]), "\": ", 
	    		Tcl_PosixError(interp), (char *) NULL);
	    	return TCL_ERROR;
	    }
	    Tcl_DStringResult(interp, &link);
	    return TCL_OK;
	}
	case FILE_RENAME: {
	    int result;
	    char **argv;

	    argv = StringifyObjects(objc, objv);
	    result = TclFileRenameCmd(interp, objc, argv);
	    ckfree((char *) argv);
	    return result;
	}
	case FILE_ROOTNAME: {
	    int length;
	    char *fileName, *extension;
	    
	    if (objc != 3) {
		goto only3Args;
	    }
	    fileName = Tcl_GetStringFromObj(objv[2], &length);
	    extension = TclGetExtension(fileName);
	    if (extension == NULL) {
	    	Tcl_SetObjResult(interp, objv[2]);
	    } else {
	        Tcl_SetStringObj(resultPtr, fileName,
			(int) (length - strlen(extension)));
	    }
	    return TCL_OK;
	}
	case FILE_SIZE: {
	    struct stat buf;
	    
	    if (objc != 3) {
		goto only3Args;
	    }
	    if (GetStatBuf(interp, objv[2], TclpStat, &buf) != TCL_OK) {
		return TCL_ERROR;
	    }
	    Tcl_SetLongObj(resultPtr, (long) buf.st_size);
	    return TCL_OK;
	}
	case FILE_SPLIT: {
	    int i, argc;
	    char **argv;
	    char *fileName;
	    Tcl_Obj *objPtr;
	    
	    if (objc != 3) {

		goto only3Args;
	    }
	    fileName = Tcl_GetString(objv[2]);
	    Tcl_SplitPath(fileName, &argc, &argv);
	    for (i = 0; i < argc; i++) {
		objPtr = Tcl_NewStringObj(argv[i], -1);
		Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	    }


	    ckfree((char *) argv);
	    return TCL_OK;
	}
	case FILE_STAT: {
	    char *varName;
	    struct stat buf;
	    
	    if (objc != 4) {
	    	Tcl_WrongNumArgs(interp, 1, objv, "stat name varName");
		return TCL_ERROR;

	    }
	    if (GetStatBuf(interp, objv[2], TclpStat, &buf) != TCL_OK) {
		return TCL_ERROR;
	    }



	    varName = Tcl_GetString(objv[3]);
	    return StoreStatData(interp, varName, &buf);


	}



    	case FILE_TAIL: {
	    int argc;
	    char **argv;

	    if (objc != 3) {








		goto only3Args;
	    }
	    if (SplitPath(interp, objv[2], &argc, &argv) != TCL_OK) {
		return TCL_ERROR;
	    }






	    /*

	     * Return the last component, unless it is the only component,
	     * and it is the root of an absolute path.
	     */

	    if (argc > 0) {
	    	if ((argc > 1)
		    	|| (Tcl_GetPathType(argv[0]) == TCL_PATH_RELATIVE)) {
		    Tcl_SetStringObj(resultPtr, argv[argc - 1], -1);
	    	}
	    }
	    ckfree((char *) argv);
	    return TCL_OK;
	}
	case FILE_TYPE: {
	    struct stat buf;

	    if (objc != 3) {
	    	goto only3Args;
	    }
	    if (GetStatBuf(interp, objv[2], TclpLstat, &buf) != TCL_OK) {
		return TCL_ERROR;
	    }
	    Tcl_SetStringObj(resultPtr, 
		    GetTypeFromMode((unsigned short) buf.st_mode), -1);
	    return TCL_OK;
	}
	case FILE_VOLUMES: {

	    if (objc != 2) {
		Tcl_WrongNumArgs(interp, 2, objv, NULL);
		return TCL_ERROR;
	    }
	    return TclpListVolumes(interp);
	}
	case FILE_WRITABLE: {
	    if (objc != 3) {
	    	goto only3Args;
	    }
	    return CheckAccess(interp, objv[2], W_OK);
	}
    }

    only3Args:
    Tcl_WrongNumArgs(interp, 2, objv, "name");
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * SplitPath --
 *
 *	Utility procedure used by Tcl_FileObjCmd() to split a path.
 *	Differs from standard Tcl_SplitPath in its handling of home
 *	directories; Tcl_SplitPath preserves the "~" while this
 *	procedure computes the actual full path name.
 *
 * Results:
 *	The return value is TCL_OK if the path could be split, TCL_ERROR
 *	otherwise.  If TCL_ERROR was returned, an error message is left
 *	in interp.  If TCL_OK was returned, *argvPtr is set to a newly
 *	allocated array of strings that represent the individual
 *	directories in the specified path, and *argcPtr is filled with
 *	the length of that array.
 *
 * Side effects:
 *	Memory allocated.  The caller must eventually free this memory
 *	by calling ckfree() on *argvPtr.
 *
 *---------------------------------------------------------------------------
 */

static int
SplitPath(interp, objPtr, argcPtr, argvPtr)
    Tcl_Interp *interp;		/* Interp for error return.  May be NULL. */
    Tcl_Obj *objPtr;		/* Path to be split. */
    int *argcPtr;		/* Filled with length of following array. */
    char ***argvPtr;		/* Filled with array of strings representing
				 * the elements of the specified path. */
{
    char *fileName;

    fileName = Tcl_GetString(objPtr);

    /*
     * If there is only one element, and it starts with a tilde,
     * perform tilde substitution and resplit the path.
     */

    Tcl_SplitPath(fileName, argcPtr, argvPtr);
    if ((*argcPtr == 1) && (fileName[0] == '~')) {
	Tcl_DString ds;
	
	ckfree((char *) *argvPtr);
	fileName = Tcl_TranslateFileName(interp, fileName, &ds);
	if (fileName == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SplitPath(fileName, argcPtr, argvPtr);
	Tcl_DStringFree(&ds);
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * CheckAccess --
 *
 *	Utility procedure used by Tcl_FileObjCmd() to query file
 *	attributes available through the access() system call.
 *
 * Results:
 *	Always returns TCL_OK.  Sets interp's result to boolean true or
 *	false depending on whether the file has the specified attribute.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
  
static int
CheckAccess(interp, objPtr, mode)
    Tcl_Interp *interp;		/* Interp for status return.  Must not be
				 * NULL. */
    Tcl_Obj *objPtr;		/* Name of file to check. */
    int mode;			/* Attribute to check; passed as argument to
				 * access(). */
{
    int value;
    char *fileName;
    Tcl_DString ds;
    
    fileName = Tcl_GetString(objPtr);
    fileName = Tcl_TranslateFileName(interp, fileName, &ds);
    if (fileName == NULL) {
	value = 0;
    } else {
	value = (TclAccess(fileName, mode) == 0);
        Tcl_DStringFree(&ds);
    }
    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), value);

    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * GetStatBuf --
 *
 *	Utility procedure used by Tcl_FileObjCmd() to query file
 *	attributes available through the stat() or lstat() system call.
 *
 * Results:
 *	The return value is TCL_OK if the specified file exists and can
 *	be stat'ed, TCL_ERROR otherwise.  If TCL_ERROR is returned, an
 *	error message is left in interp's result.  If TCL_OK is returned,
 *	*statPtr is filled with information about the specified file.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
GetStatBuf(interp, objPtr, statProc, statPtr)
    Tcl_Interp *interp;		/* Interp for error return.  May be NULL. */
    Tcl_Obj *objPtr;		/* Path name to examine. */
    StatProc *statProc;		/* Either stat() or lstat() depending on
				 * desired behavior. */
    struct stat *statPtr;	/* Filled with info about file obtained by
				 * calling (*statProc)(). */
{
    char *fileName;
    Tcl_DString ds;
    int status;
    
    fileName = Tcl_GetString(objPtr);
    fileName = Tcl_TranslateFileName(interp, fileName, &ds);
    if (fileName == NULL) {
	return TCL_ERROR;
    }

    status = (*statProc)(Tcl_DStringValue(&ds), statPtr);
    Tcl_DStringFree(&ds);
    
    if (status < 0) {
	if (interp != NULL) {
	    Tcl_AppendResult(interp, "could not read \"",
		    Tcl_GetString(objPtr), "\": ",
		    Tcl_PosixError(interp), (char *) NULL);
	}
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * StoreStatData --
 *
 *	This is a utility procedure that breaks out the fields of a
 *	"stat" structure and stores them in textual form into the
 *	elements of an associative array.
 *
 * Results:
 *	Returns a standard Tcl return value.  If an error occurs then
 *	a message is left in interp's result.
 *
 * Side effects:
 *	Elements of the associative array given by "varName" are modified.
 *
 *----------------------------------------------------------------------
 */

static int
StoreStatData(interp, varName, statPtr)
    Tcl_Interp *interp;			/* Interpreter for error reports. */
    char *varName;			/* Name of associative array variable
					 * in which to store stat results. */
    struct stat *statPtr;		/* Pointer to buffer containing
					 * stat data to store in varName. */
{
    char string[TCL_INTEGER_SPACE];

    TclFormatInt(string, (long) statPtr->st_dev);
    if (Tcl_SetVar2(interp, varName, "dev", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    TclFormatInt(string, (long) statPtr->st_ino);
    if (Tcl_SetVar2(interp, varName, "ino", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    TclFormatInt(string, (unsigned short) statPtr->st_mode);
    if (Tcl_SetVar2(interp, varName, "mode", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    TclFormatInt(string, (long) statPtr->st_nlink);
    if (Tcl_SetVar2(interp, varName, "nlink", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    TclFormatInt(string, (long) statPtr->st_uid);
    if (Tcl_SetVar2(interp, varName, "uid", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    TclFormatInt(string, (long) statPtr->st_gid);
    if (Tcl_SetVar2(interp, varName, "gid", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    sprintf(string, "%lu", (unsigned long) statPtr->st_size);
    if (Tcl_SetVar2(interp, varName, "size", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    TclFormatInt(string, (long) statPtr->st_atime);
    if (Tcl_SetVar2(interp, varName, "atime", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    TclFormatInt(string, (long) statPtr->st_mtime);
    if (Tcl_SetVar2(interp, varName, "mtime", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    TclFormatInt(string, (long) statPtr->st_ctime);
    if (Tcl_SetVar2(interp, varName, "ctime", string, TCL_LEAVE_ERR_MSG)
	    == NULL) {
	return TCL_ERROR;
    }
    if (Tcl_SetVar2(interp, varName, "type",
	    GetTypeFromMode((unsigned short) statPtr->st_mode), 
	    TCL_LEAVE_ERR_MSG) == NULL) {
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368

1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
    }
    return "unknown";
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ForCmd --
 *
 *      This procedure is invoked to process the "for" Tcl command.
 *      See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "for" or the name
 *	to which "for" was renamed: e.g.,
 *	"set z for; $z {set i 0} {$i<100} {incr i} {puts $i}"
 *
 * Results:
 *      A standard Tcl result.
 *
 * Side effects:
 *      See the user documentation.
 *
 *----------------------------------------------------------------------
 */

        /* ARGSUSED */
int
Tcl_ForCmd(dummy, interp, argc, argv)
    ClientData dummy;                   /* Not used. */
    Tcl_Interp *interp;                 /* Current interpreter. */
    int argc;                           /* Number of arguments. */
    char **argv;                        /* Argument strings. */
{
    int result, value;

    if (argc != 5) {
        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                " start test next command\"", (char *) NULL);
        return TCL_ERROR;
    }

    result = Tcl_Eval(interp, argv[1]);
    if (result != TCL_OK) {
        if (result == TCL_ERROR) {
            Tcl_AddErrorInfo(interp, "\n    (\"for\" initial command)");
        }
        return result;
    }
    while (1) {
        result = Tcl_ExprBoolean(interp, argv[2], &value);
        if (result != TCL_OK) {
            return result;
        }
        if (!value) {
            break;
        }
        result = Tcl_Eval(interp, argv[4]);
        if ((result != TCL_OK) && (result != TCL_CONTINUE)) {
            if (result == TCL_ERROR) {
                char msg[60];

                sprintf(msg, "\n    (\"for\" body line %d)",interp->errorLine);
                Tcl_AddErrorInfo(interp, msg);
            }
            break;
        }
        result = Tcl_Eval(interp, argv[3]);
	if (result == TCL_BREAK) {
            break;
        } else if (result != TCL_OK) {
            if (result == TCL_ERROR) {
                Tcl_AddErrorInfo(interp, "\n    (\"for\" loop-end command)");
            }
            return result;







|




















|


|
|



|
<
|



|







|






|


|
>





|







1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549

1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
    }
    return "unknown";
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FoObjCmd --
 *
 *      This procedure is invoked to process the "for" Tcl command.
 *      See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "for" or the name
 *	to which "for" was renamed: e.g.,
 *	"set z for; $z {set i 0} {$i<100} {incr i} {puts $i}"
 *
 * Results:
 *      A standard Tcl result.
 *
 * Side effects:
 *      See the user documentation.
 *
 *----------------------------------------------------------------------
 */

        /* ARGSUSED */
int
Tcl_ForObjCmd(dummy, interp, objc, objv)
    ClientData dummy;                   /* Not used. */
    Tcl_Interp *interp;                 /* Current interpreter. */
    int objc;                           /* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int result, value;

    if (objc != 5) {

        Tcl_WrongNumArgs(interp, 1, objv, "start test next command");
        return TCL_ERROR;
    }

    result = Tcl_EvalObjEx(interp, objv[1], 0);
    if (result != TCL_OK) {
        if (result == TCL_ERROR) {
            Tcl_AddErrorInfo(interp, "\n    (\"for\" initial command)");
        }
        return result;
    }
    while (1) {
        result = Tcl_ExprBooleanObj(interp, objv[2], &value);
        if (result != TCL_OK) {
            return result;
        }
        if (!value) {
            break;
        }
        result = Tcl_EvalObjEx(interp, objv[4], 0);
        if ((result != TCL_OK) && (result != TCL_CONTINUE)) {
            if (result == TCL_ERROR) {
                char msg[32 + TCL_INTEGER_SPACE];

                sprintf(msg, "\n    (\"for\" body line %d)",interp->errorLine);
                Tcl_AddErrorInfo(interp, msg);
            }
            break;
        }
        result = Tcl_EvalObjEx(interp, objv[3], 0);
	if (result == TCL_BREAK) {
            break;
        } else if (result != TCL_OK) {
            if (result == TCL_ERROR) {
                Tcl_AddErrorInfo(interp, "\n    (\"for\" loop-end command)");
            }
            return result;
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
	varvList[i] = (Tcl_Obj **) NULL;
	argcList[i] = 0;
	argvList[i] = (Tcl_Obj **) NULL;
    }

    /*
     * Break up the value lists and variable lists into elements
     * THIS FAILS IF THE OBJECT'S STRING REP HAS A NULL BYTE.
     */

    maxj = 0;
    for (i = 0;  i < numLists;  i++) {
	result = Tcl_ListObjGetElements(interp, argObjv[1+i*2],
	        &varcList[i], &varvList[i]);
	if (result != TCL_OK) {







<







1691
1692
1693
1694
1695
1696
1697

1698
1699
1700
1701
1702
1703
1704
	varvList[i] = (Tcl_Obj **) NULL;
	argcList[i] = 0;
	argvList[i] = (Tcl_Obj **) NULL;
    }

    /*
     * Break up the value lists and variable lists into elements

     */

    maxj = 0;
    for (i = 0;  i < numLists;  i++) {
	result = Tcl_ListObjGetElements(interp, argObjv[1+i*2],
	        &varcList[i], &varvList[i]);
	if (result != TCL_OK) {
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591

1592
1593
1594
1595
1596
1597
1598
		
		if (k < argcList[i]) {
		    valuePtr = argvList[i][k];
		} else {
		    valuePtr = Tcl_NewObj(); /* empty string */
		    isEmptyObj = 1;
		}
		varValuePtr = Tcl_ObjSetVar2(interp, varvList[i][v], NULL,
			valuePtr, TCL_PARSE_PART1);
		if (varValuePtr == NULL) {
		    if (isEmptyObj) {
			Tcl_DecrRefCount(valuePtr);
		    }
		    Tcl_ResetResult(interp);
		    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"couldn't set loop variable: \"",
			Tcl_GetStringFromObj(varvList[i][v], (int *) NULL),
			"\"", (char *) NULL);
		    result = TCL_ERROR;
		    goto done;
		}

	    }
	}

	result = Tcl_EvalObj(interp, bodyPtr);
	if (result != TCL_OK) {
	    if (result == TCL_CONTINUE) {
		result = TCL_OK;
	    } else if (result == TCL_BREAK) {
		result = TCL_OK;
		break;
	    } else if (result == TCL_ERROR) {
		char msg[100];

		sprintf(msg, "\n    (\"foreach\" body line %d)",
			interp->errorLine);
		Tcl_AddObjErrorInfo(interp, msg, -1);
		break;
	    } else {
		break;
	    }







|
|







<
|







|







|
>







1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777

1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
		
		if (k < argcList[i]) {
		    valuePtr = argvList[i][k];
		} else {
		    valuePtr = Tcl_NewObj(); /* empty string */
		    isEmptyObj = 1;
		}
		varValuePtr = Tcl_ObjSetVar2(interp, varvList[i][v],
			NULL, valuePtr, 0);
		if (varValuePtr == NULL) {
		    if (isEmptyObj) {
			Tcl_DecrRefCount(valuePtr);
		    }
		    Tcl_ResetResult(interp);
		    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"couldn't set loop variable: \"",

			Tcl_GetString(varvList[i][v]), "\"", (char *) NULL);
		    result = TCL_ERROR;
		    goto done;
		}

	    }
	}

	result = Tcl_EvalObjEx(interp, bodyPtr, 0);
	if (result != TCL_OK) {
	    if (result == TCL_CONTINUE) {
		result = TCL_OK;
	    } else if (result == TCL_BREAK) {
		result = TCL_OK;
		break;
	    } else if (result == TCL_ERROR) {
                char msg[32 + TCL_INTEGER_SPACE];

		sprintf(msg, "\n    (\"foreach\" body line %d)",
			interp->errorLine);
		Tcl_AddObjErrorInfo(interp, msg, -1);
		break;
	    } else {
		break;
	    }
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668

1669
1670

1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690






1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719

1720
1721
1722
1723
1724
1725
1726
int
Tcl_FormatObjCmd(dummy, interp, objc, objv)
    ClientData dummy;    	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register char *format;	/* Used to read characters from the format
				 * string. */
    int formatLen;              /* The length of the format string */
    char *endPtr;               /* Points to the last char in format array */
    char newFormat[40];		/* A new format specifier is generated here. */
    int width;			/* Field width from field specifier, or 0 if
				 * no width given. */
    int precision;		/* Field precision from field specifier, or 0
				 * if no precision given. */
    int size;			/* Number of bytes needed for result of
				 * conversion, based on type of conversion
				 * ("e", "s", etc.), width, and precision. */
    int intValue;		/* Used to hold value to pass to sprintf, if
				 * it's a one-word integer or char value */
    char *ptrValue = NULL;	/* Used to hold value to pass to sprintf, if
				 * it's a one-word value. */
    double doubleValue;		/* Used to hold value to pass to sprintf if
				 * it's a double value. */
    int whichValue;		/* Indicates which of intValue, ptrValue,
				 * or doubleValue has the value to pass to
				 * sprintf, according to the following
				 * definitions: */
#   define INT_VALUE 0

#   define PTR_VALUE 1
#   define DOUBLE_VALUE 2

#   define MAX_FLOAT_SIZE 320
    
    Tcl_Obj *resultPtr;  	/* Where result is stored finally. */
    char staticBuf[MAX_FLOAT_SIZE + 1];
                                /* A static buffer to copy the format results 
				 * into */
    char *dst = staticBuf;      /* The buffer that sprintf writes into each
				 * time the format processes a specifier */
    int dstSize = MAX_FLOAT_SIZE;
                                /* The size of the dst buffer */
    int noPercent;		/* Special case for speed:  indicates there's
				 * no field specifier, just a string to copy.*/
    int objIndex;		/* Index of argument to substitute next. */
    int gotXpg = 0;		/* Non-zero means that an XPG3 %n$-style
				 * specifier has been seen. */
    int gotSequential = 0;	/* Non-zero means that a regular sequential
				 * (non-XPG3) conversion specifier has been
				 * seen. */
    int useShort;		/* Value to be printed is short (half word). */
    char *end;			/* Used to locate end of numerical fields. */







    /*
     * This procedure is a bit nasty.  The goal is to use sprintf to
     * do most of the dirty work.  There are several problems:
     * 1. this procedure can't trust its arguments.
     * 2. we must be able to provide a large enough result area to hold
     *    whatever's generated.  This is hard to estimate.
     * 2. there's no way to move the arguments from objv to the call
     *    to sprintf in a reasonable way.  This is particularly nasty
     *    because some of the arguments may be two-word values (doubles).
     * So, what happens here is to scan the format string one % group
     * at a time, making many individual calls to sprintf.
     */

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv,
		"formatString ?arg arg ...?");
	return TCL_ERROR;
    }

    format = Tcl_GetStringFromObj(objv[1], &formatLen);
    endPtr = format + formatLen;
    resultPtr = Tcl_NewObj();
    objIndex = 2;

    while (format < endPtr) {
	register char *newPtr = newFormat;

	width = precision = noPercent = useShort = 0;

	whichValue = PTR_VALUE;

	/*
	 * Get rid of any characters before the next field specifier.
	 */
	if (*format != '%') {
	    ptrValue = format;







|


|



















>
|
|
>




















>
>
>
>
>
>







|







|
<



|








>







1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
int
Tcl_FormatObjCmd(dummy, interp, objc, objv)
    ClientData dummy;    	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    char *format;		/* Used to read characters from the format
				 * string. */
    int formatLen;              /* The length of the format string */
    char *endPtr;		/* Points to the last char in format array */
    char newFormat[40];		/* A new format specifier is generated here. */
    int width;			/* Field width from field specifier, or 0 if
				 * no width given. */
    int precision;		/* Field precision from field specifier, or 0
				 * if no precision given. */
    int size;			/* Number of bytes needed for result of
				 * conversion, based on type of conversion
				 * ("e", "s", etc.), width, and precision. */
    int intValue;		/* Used to hold value to pass to sprintf, if
				 * it's a one-word integer or char value */
    char *ptrValue = NULL;	/* Used to hold value to pass to sprintf, if
				 * it's a one-word value. */
    double doubleValue;		/* Used to hold value to pass to sprintf if
				 * it's a double value. */
    int whichValue;		/* Indicates which of intValue, ptrValue,
				 * or doubleValue has the value to pass to
				 * sprintf, according to the following
				 * definitions: */
#   define INT_VALUE 0
#   define CHAR_VALUE 1
#   define PTR_VALUE 2
#   define DOUBLE_VALUE 3
#   define STRING_VALUE 4
#   define MAX_FLOAT_SIZE 320
    
    Tcl_Obj *resultPtr;  	/* Where result is stored finally. */
    char staticBuf[MAX_FLOAT_SIZE + 1];
                                /* A static buffer to copy the format results 
				 * into */
    char *dst = staticBuf;      /* The buffer that sprintf writes into each
				 * time the format processes a specifier */
    int dstSize = MAX_FLOAT_SIZE;
                                /* The size of the dst buffer */
    int noPercent;		/* Special case for speed:  indicates there's
				 * no field specifier, just a string to copy.*/
    int objIndex;		/* Index of argument to substitute next. */
    int gotXpg = 0;		/* Non-zero means that an XPG3 %n$-style
				 * specifier has been seen. */
    int gotSequential = 0;	/* Non-zero means that a regular sequential
				 * (non-XPG3) conversion specifier has been
				 * seen. */
    int useShort;		/* Value to be printed is short (half word). */
    char *end;			/* Used to locate end of numerical fields. */
    int stringLen = 0;		/* Length of string in characters rather
				 * than bytes.  Used for %s substitution. */
    int gotMinus;		/* Non-zero indicates that a minus flag has
				 * been seen in the current field. */
    int gotPrecision;		/* Non-zero indicates that a precision has
				 * been set for the current field. */

    /*
     * This procedure is a bit nasty.  The goal is to use sprintf to
     * do most of the dirty work.  There are several problems:
     * 1. this procedure can't trust its arguments.
     * 2. we must be able to provide a large enough result area to hold
     *    whatever's generated.  This is hard to estimate.
     * 3. there's no way to move the arguments from objv to the call
     *    to sprintf in a reasonable way.  This is particularly nasty
     *    because some of the arguments may be two-word values (doubles).
     * So, what happens here is to scan the format string one % group
     * at a time, making many individual calls to sprintf.
     */

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "formatString ?arg arg ...?");

	return TCL_ERROR;
    }

    format = (char *) Tcl_GetStringFromObj(objv[1], &formatLen);
    endPtr = format + formatLen;
    resultPtr = Tcl_NewObj();
    objIndex = 2;

    while (format < endPtr) {
	register char *newPtr = newFormat;

	width = precision = noPercent = useShort = 0;
	gotMinus = gotPrecision = 0;
	whichValue = PTR_VALUE;

	/*
	 * Get rid of any characters before the next field specifier.
	 */
	if (*format != '%') {
	    ptrValue = format;
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
	 * Parse off a field specifier, compute how many characters
	 * will be needed to store the result, and substitute for
	 * "*" size specifiers.
	 */
	*newPtr = '%';
	newPtr++;
	format++;
	if (isdigit(UCHAR(*format))) {
	    int tmp;

	    /*
	     * Check for an XPG3-style %n$ specification.  Note: there
	     * must not be a mixture of XPG3 specs and non-XPG3 specs
	     * in the same format string.
	     */

	    tmp = strtoul(format, &end, 10);
	    if (*end != '$') {
		goto notXpg;
	    }
	    format = end+1;
	    gotXpg = 1;
	    if (gotSequential) {
		goto mixedXPG;







|








|







1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
	 * Parse off a field specifier, compute how many characters
	 * will be needed to store the result, and substitute for
	 * "*" size specifiers.
	 */
	*newPtr = '%';
	newPtr++;
	format++;
	if (isdigit(UCHAR(*format))) { /* INTL: Tcl source. */
	    int tmp;

	    /*
	     * Check for an XPG3-style %n$ specification.  Note: there
	     * must not be a mixture of XPG3 specs and non-XPG3 specs
	     * in the same format string.
	     */

	    tmp = strtoul(format, &end, 10);	/* INTL: "C" locale. */
	    if (*end != '$') {
		goto notXpg;
	    }
	    format = end+1;
	    gotXpg = 1;
	    if (gotSequential) {
		goto mixedXPG;
1778
1779
1780
1781
1782
1783
1784



1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798






1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823

1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
	if (gotXpg) {
	    goto mixedXPG;
	}

	xpgCheckDone:
	while ((*format == '-') || (*format == '#') || (*format == '0')
		|| (*format == ' ') || (*format == '+')) {



	    *newPtr = *format;
	    newPtr++;
	    format++;
	}
	if (isdigit(UCHAR(*format))) {
	    width = strtoul(format, &end, 10);
	    format = end;
	} else if (*format == '*') {
	    if (objIndex >= objc) {
		goto badIndex;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[objIndex], 
                    &width) != TCL_OK) {
		goto fmtError;






	    }
	    objIndex++;
	    format++;
	}
	if (width > 100000) {
	    /*
	     * Don't allow arbitrarily large widths:  could cause core
	     * dump when we try to allocate a zillion bytes of memory
	     * below.
	     */

	    width = 100000;
	} else if (width < 0) {
	    width = 0;
	}
	if (width != 0) {
	    TclFormatInt(newPtr, width);
	    while (*newPtr != 0) {
		newPtr++;
	    }
	}
	if (*format == '.') {
	    *newPtr = '.';
	    newPtr++;
	    format++;

	}
	if (isdigit(UCHAR(*format))) {
	    precision = strtoul(format, &end, 10);
	    format = end;
	} else if (*format == '*') {
	    if (objIndex >= objc) {
		goto badIndex;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[objIndex], 
                    &precision) != TCL_OK) {
		goto fmtError;
	    }
	    objIndex++;
	    format++;
	}
	if (precision != 0) {
	    TclFormatInt(newPtr, precision);
	    while (*newPtr != 0) {
		newPtr++;
	    }
	}
	if (*format == 'l') {
	    format++;
	} else if (*format == 'h') {







>
>
>




|
|





|
|

>
>
>
>
>
>
















|








>

|
|





|
|





|
|







1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
	if (gotXpg) {
	    goto mixedXPG;
	}

	xpgCheckDone:
	while ((*format == '-') || (*format == '#') || (*format == '0')
		|| (*format == ' ') || (*format == '+')) {
	    if (*format == '-') {
		gotMinus = 1;
	    }
	    *newPtr = *format;
	    newPtr++;
	    format++;
	}
	if (isdigit(UCHAR(*format))) { /* INTL: Tcl source. */
	    width = strtoul(format, &end, 10);	/* INTL: Tcl source. */
	    format = end;
	} else if (*format == '*') {
	    if (objIndex >= objc) {
		goto badIndex;
	    }
	    if (Tcl_GetIntFromObj(interp,	/* INTL: Tcl source. */
		    objv[objIndex], &width) != TCL_OK) {
		goto fmtError;
	    }
	    if (width < 0) {
		width = -width;
		*newPtr = '-';
		gotMinus = 1;
		newPtr++;
	    }
	    objIndex++;
	    format++;
	}
	if (width > 100000) {
	    /*
	     * Don't allow arbitrarily large widths:  could cause core
	     * dump when we try to allocate a zillion bytes of memory
	     * below.
	     */

	    width = 100000;
	} else if (width < 0) {
	    width = 0;
	}
	if (width != 0) {
	    TclFormatInt(newPtr, width);	/* INTL: printf format. */
	    while (*newPtr != 0) {
		newPtr++;
	    }
	}
	if (*format == '.') {
	    *newPtr = '.';
	    newPtr++;
	    format++;
	    gotPrecision = 1;
	}
	if (isdigit(UCHAR(*format))) { /* INTL: Tcl source. */
	    precision = strtoul(format, &end, 10);  /* INTL: "C" locale. */
	    format = end;
	} else if (*format == '*') {
	    if (objIndex >= objc) {
		goto badIndex;
	    }
	    if (Tcl_GetIntFromObj(interp,	/* INTL: Tcl source. */
		    objv[objIndex], &precision) != TCL_OK) {
		goto fmtError;
	    }
	    objIndex++;
	    format++;
	}
	if (gotPrecision) {
	    TclFormatInt(newPtr, precision);	/* INTL: printf format. */
	    while (*newPtr != 0) {
		newPtr++;
	    }
	}
	if (*format == 'l') {
	    format++;
	} else if (*format == 'h') {
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874








1875








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
	    case 'i':
		newPtr[-1] = 'd';
	    case 'd':
	    case 'o':
	    case 'u':
	    case 'x':
	    case 'X':
		if (Tcl_GetIntFromObj(interp, objv[objIndex], 
		        (int *) &intValue) != TCL_OK) {
		    goto fmtError;
		}
		whichValue = INT_VALUE;
		size = 40 + precision;
		break;
	    case 's':








		ptrValue = Tcl_GetStringFromObj(objv[objIndex], &size);








		break;
	    case 'c':
		if (Tcl_GetIntFromObj(interp, objv[objIndex], 
                        (int *) &intValue) != TCL_OK) {
		    goto fmtError;
		}
		whichValue = INT_VALUE;
		size = 1;
		break;
	    case 'e':
	    case 'E':
	    case 'f':
	    case 'g':
	    case 'G':
		if (Tcl_GetDoubleFromObj(interp, objv[objIndex], 
			&doubleValue) != TCL_OK) {
		    goto fmtError;
		}
		whichValue = DOUBLE_VALUE;
		size = MAX_FLOAT_SIZE;
		if (precision > 10) {
		    size += precision;
		}
		break;
	    case 0:
		Tcl_SetResult(interp,
		        "format string ended in middle of field specifier",
			TCL_STATIC);
		goto fmtError;
	    default:
		{
		    char buf[40];
		    sprintf(buf, "bad field specifier \"%c\"", *format);
		    Tcl_SetResult(interp, buf, TCL_VOLATILE);
		    goto fmtError;
		}
	}
	objIndex++;
	format++;

	/*
	 * Make sure that there's enough space to hold the formatted
	 * result, then format it.







|
|






>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>


|
|


|
|






|
|













|
<
|
|
|
|
|







2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143

2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
	    case 'i':
		newPtr[-1] = 'd';
	    case 'd':
	    case 'o':
	    case 'u':
	    case 'x':
	    case 'X':
		if (Tcl_GetIntFromObj(interp,	/* INTL: Tcl source. */
			objv[objIndex], &intValue) != TCL_OK) {
		    goto fmtError;
		}
		whichValue = INT_VALUE;
		size = 40 + precision;
		break;
	    case 's':
		/*
		 * Compute the length of the string in characters and add
		 * any additional space required by the field width.  All of
		 * the extra characters will be spaces, so one byte per
		 * character is adequate.
		 */

		whichValue = STRING_VALUE;
		ptrValue = Tcl_GetStringFromObj(objv[objIndex], &size);
		stringLen = Tcl_NumUtfChars(ptrValue, size);
		if (gotPrecision && (precision < stringLen)) {
		    stringLen = precision;
		}
		size = Tcl_UtfAtIndex(ptrValue, stringLen) - ptrValue;
		if (width > stringLen) {
		    size += (width - stringLen);
		}
		break;
	    case 'c':
		if (Tcl_GetIntFromObj(interp,	/* INTL: Tcl source. */
			objv[objIndex], &intValue) != TCL_OK) {
		    goto fmtError;
		}
		whichValue = CHAR_VALUE;
		size = width + TCL_UTF_MAX;
		break;
	    case 'e':
	    case 'E':
	    case 'f':
	    case 'g':
	    case 'G':
		if (Tcl_GetDoubleFromObj(interp, /* INTL: Tcl source. */
			objv[objIndex], &doubleValue) != TCL_OK) {
		    goto fmtError;
		}
		whichValue = DOUBLE_VALUE;
		size = MAX_FLOAT_SIZE;
		if (precision > 10) {
		    size += precision;
		}
		break;
	    case 0:
		Tcl_SetResult(interp,
		        "format string ended in middle of field specifier",
			TCL_STATIC);
		goto fmtError;
	    default: {

		char buf[40];
		sprintf(buf, "bad field specifier \"%c\"", *format);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
		goto fmtError;
	    }
	}
	objIndex++;
	format++;

	/*
	 * Make sure that there's enough space to hold the formatted
	 * result, then format it.
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
	    if (size > dstSize) {
	        if (dst != staticBuf) {
		    ckfree(dst);
		}
		dst = (char *) ckalloc((unsigned) (size + 1));
		dstSize = size;
	    }

	    if (whichValue == DOUBLE_VALUE) {
	        sprintf(dst, newFormat, doubleValue);


	    } else if (whichValue == INT_VALUE) {
		if (useShort) {
		    sprintf(dst, newFormat, (short) intValue);
		} else {
		    sprintf(dst, newFormat, intValue);
		}
























	    } else {























	        sprintf(dst, newFormat, ptrValue);


	    }
	    Tcl_AppendToObj(resultPtr, dst, -1);
	}
    }

    Tcl_SetObjResult(interp, resultPtr);
    if(dst != staticBuf) {







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







2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
	    if (size > dstSize) {
	        if (dst != staticBuf) {
		    ckfree(dst);
		}
		dst = (char *) ckalloc((unsigned) (size + 1));
		dstSize = size;
	    }
	    switch (whichValue) {
		case DOUBLE_VALUE: {
		    sprintf(dst, newFormat, doubleValue); /* INTL: user locale. */
		    break;
		}
		case INT_VALUE: {
		    if (useShort) {
			sprintf(dst, newFormat, (short) intValue);
		    } else {
			sprintf(dst, newFormat, intValue);
		    }
		    break;
		}
		case CHAR_VALUE: {
		    char *ptr;
		    ptr = dst;
		    if (!gotMinus) {
			for ( ; --width > 0; ptr++) {
			    *ptr = ' ';
			}
		    }
		    ptr += Tcl_UniCharToUtf(intValue, ptr);
		    for ( ; --width > 0; ptr++) {
			*ptr = ' ';
		    }
		    *ptr = '\0';
		    break;
		}
		case STRING_VALUE: {
		    char *ptr;
		    int pad;

		    ptr = dst;
		    if (width > stringLen) {
			pad = width - stringLen;
		    } else {
			pad = 0;
		    }

		    if (!gotMinus) {
			while (pad > 0) {
			    *ptr++ = ' ';
			    pad--;
			}
		    }

		    size = Tcl_UtfAtIndex(ptrValue, stringLen) - ptrValue; 
		    if (size) {
			memcpy(ptr, ptrValue, (size_t) size);
			ptr += size;
		    }
		    while (pad > 0) {
			*ptr++ = ' ';
			pad--;
		    }
		    *ptr = '\0';
		    break;
		}
		default: {
		    sprintf(dst, newFormat, ptrValue);
		    break;
		}
	    }
	    Tcl_AppendToObj(resultPtr, dst, -1);
	}
    }

    Tcl_SetObjResult(interp, resultPtr);
    if(dst != staticBuf) {
1971
1972
1973
1974
1975
1976
1977








































    fmtError:
    if(dst != staticBuf) {
        ckfree(dst);
    }
    Tcl_DecrRefCount(resultPtr);
    return TCL_ERROR;
}















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
    fmtError:
    if(dst != staticBuf) {
        ckfree(dst);
    }
    Tcl_DecrRefCount(resultPtr);
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * StringifyObjects --
 *
 *	Helper function to bridge the gap between an object-based procedure
 *	and an older string-based procedure.
 * 
 *	Given an array of objects, allocate an array that consists of the
 *	string representations of those objects.
 *
 * Results:
 *	The return value is a pointer to the newly allocated array of
 *	strings.  Elements 0 to (objc-1) of the string array point to the
 *	string representation of the corresponding element in the source
 *	object array; element objc of the string array is NULL.
 *
 * Side effects:
 *	Memory allocated.  The caller must eventually free this memory
 *	by calling ckfree() on the return value.
 *
 *---------------------------------------------------------------------------
 */

static char **
StringifyObjects(objc, objv)
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int i;
    char **argv;
    
    argv = (char **) ckalloc((objc + 1) * sizeof(char *));
    for (i = 0; i < objc; i++) {
    	argv[i] = Tcl_GetString(objv[i]);
    }
    argv[i] = NULL;
    return argv;
}

Changes to generic/tclCmdIL.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
/* 
 * tclCmdIL.c --
 *
 *	This file contains the top-level command routines for most of
 *	the Tcl built-in commands whose names begin with the letters
 *	I through L.  It contains only commands in the generic core
 *	(i.e. those that don't depend much upon UNIX facilities).
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * Copyright (c) 1993-1997 Lucent Technologies.
 * 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.
 *
 * SCCS: @(#) tclCmdIL.c 1.173 97/11/18 13:55:01
 */

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

/*
 * The following variable holds the full path name of the binary
 * from which this application was executed, or NULL if it isn't
 * know.  The value of the variable is set by the procedure
 * Tcl_FindExecutable.  The storage space is dynamically allocated.
 */

char *tclExecutableName = NULL;

/*
 * During execution of the "lsort" command, structures of the following
 * type are used to arrange the objects being sorted into a collection
 * of linked lists.
 */












>




|




|
<
<
<
<
<
<
|
<







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
/* 
 * tclCmdIL.c --
 *
 *	This file contains the top-level command routines for most of
 *	the Tcl built-in commands whose names begin with the letters
 *	I through L.  It contains only commands in the generic core
 *	(i.e. those that don't depend much upon UNIX facilities).
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * Copyright (c) 1993-1997 Lucent Technologies.
 * Copyright (c) 1994-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: tclCmdIL.c,v 1.1.2.11 1999/04/02 23:44:54 stanton Exp $
 */

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






#include "tclRegexp.h"


/*
 * During execution of the "lsort" command, structures of the following
 * type are used to arrange the objects being sorted into a collection
 * of linked lists.
 */

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 * information.
 */

typedef struct SortInfo {
    int isIncreasing;		/* Nonzero means sort in increasing order. */
    int sortMode;		/* The sort mode.  One of SORTMODE_*
				 * values defined below */
    Tcl_DString compareCmd;	/* The Tcl comparison command when sortMode
				 * is SORTMODE_COMMAND.  Pre-initialized to
				 * hold base of command.*/
    int index;			/* If the -index option was specified, this
				 * holds the index of the list element
				 * to extract for comparison.  If -index
				 * wasn't specified, this is -1. */
    Tcl_Interp *interp;		/* The interpreter in which the sortis







|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 * information.
 */

typedef struct SortInfo {
    int isIncreasing;		/* Nonzero means sort in increasing order. */
    int sortMode;		/* The sort mode.  One of SORTMODE_*
				 * values defined below */
    Tcl_Obj *compareCmdPtr;     /* The Tcl comparison command when sortMode
				 * is SORTMODE_COMMAND.  Pre-initialized to
				 * hold base of command.*/
    int index;			/* If the -index option was specified, this
				 * holds the index of the list element
				 * to extract for comparison.  If -index
				 * wasn't specified, this is -1. */
    Tcl_Interp *interp;		/* The interpreter in which the sortis
77
78
79
80
81
82
83



84
85
86
87
88
89
90
#define SORTMODE_COMMAND    3
#define SORTMODE_DICTIONARY 4

/*
 * Forward declarations for procedures defined in this file:
 */




static int		DictionaryCompare _ANSI_ARGS_((char *left,
			    char *right));
static int		InfoArgsCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int		InfoBodyCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,







>
>
>







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#define SORTMODE_COMMAND    3
#define SORTMODE_DICTIONARY 4

/*
 * Forward declarations for procedures defined in this file:
 */

static void		AppendLocals _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *listPtr, char *pattern,
			    int includeLinks));
static int		DictionaryCompare _ANSI_ARGS_((char *left,
			    char *right));
static int		InfoArgsCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int		InfoBodyCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198

199
200
201
202
203
204
205
206

207


208
209
210
211







212

213
214
215
216
217
218
219
220
221
222



223
224

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246









247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291



292



293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

308

309
310

311
312
313
314
315
316

317
318
319
320
321
322
323
324
325
326
327
			    SortElement *rightPtr, SortInfo *infoPtr));
static int		SortCompare _ANSI_ARGS_((Tcl_Obj *firstPtr,
			    Tcl_Obj *second, SortInfo *infoPtr));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_IfCmd --
 *
 *	This procedure is invoked to process the "if" Tcl command.
 *	See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "if" or the name
 *	to which "if" was renamed: e.g., "set z if; $z 1 {puts foo}"
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_IfCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{

    int i, result, value;

    i = 1;
    while (1) {
	/*
	 * At this point in the loop, argv and argc refer to an expression
	 * to test, either for the main expression or an expression
	 * following an "elseif".  The arguments after the expression must
	 * be "then" (optional) and a script to execute if the expression is
	 * true.
	 */

	if (i >= argc) {

	    Tcl_AppendResult(interp, "wrong # args: no expression after \"",
		    argv[i-1], "\" argument", (char *) NULL);
	    return TCL_ERROR;
	}

	result = Tcl_ExprBoolean(interp, argv[i], &value);
	if (result != TCL_OK) {
	    return result;
	}
	i++;
	if ((i < argc) && (strcmp(argv[i], "then") == 0)) {
	    i++;
	}

	if (i >= argc) {


	    Tcl_AppendResult(interp, "wrong # args: no script following \"",
		    argv[i-1], "\" argument", (char *) NULL);
	    return TCL_ERROR;
	}







	if (value) {

	    return Tcl_Eval(interp, argv[i]);
	}
	
	/*
	 * The expression evaluated to false.  Skip the command, then
	 * see if there is an "else" or "elseif" clause.
	 */

	i++;
	if (i >= argc) {



	    return TCL_OK;
	}

	if ((argv[i][0] == 'e') && (strcmp(argv[i], "elseif") == 0)) {
	    i++;
	    continue;
	}
	break;
    }

    /*
     * Couldn't find a "then" or "elseif" clause to execute.  Check now
     * for an "else" clause.  We know that there's at least one more
     * argument when we get here.
     */

    if (strcmp(argv[i], "else") == 0) {
	i++;
	if (i >= argc) {
	    Tcl_AppendResult(interp,
		    "wrong # args: no script following \"else\" argument",
		    (char *) NULL);
	    return TCL_ERROR;
	}
    }









    return Tcl_Eval(interp, argv[i]);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_IncrCmd --
 *
 *	This procedure is invoked to process the "incr" Tcl command.
 *	See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "incr" or the name
 *	to which "incr" was renamed: e.g., "set z incr; $z i -1"
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

    /* ARGSUSED */
int
Tcl_IncrCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    int value;
    char *oldString, *result;
    char newString[30];

    if ((argc != 2) && (argc != 3)) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" varName ?increment?\"", (char *) NULL);
	return TCL_ERROR;
    }

    oldString = Tcl_GetVar(interp, argv[1], TCL_LEAVE_ERR_MSG);
    if (oldString == NULL) {
	return TCL_ERROR;



    }



    if (Tcl_GetInt(interp, oldString, &value) != TCL_OK) {
	Tcl_AddErrorInfo(interp,
		"\n    (reading value of variable to increment)");
	return TCL_ERROR;
    }
    if (argc == 2) {
	value += 1;
    } else {
	int increment;

	if (Tcl_GetInt(interp, argv[2], &increment) != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (reading increment)");
	    return TCL_ERROR;
	}

	value += increment;

    }
    TclFormatInt(newString, value);

    result = Tcl_SetVar(interp, argv[1], newString, TCL_LEAVE_ERR_MSG);
    if (result == NULL) {
	return TCL_ERROR;
    }

    /*

     * Copy the result since the variable's value might change.
     */
    
    Tcl_SetResult(interp, result, TCL_VOLATILE);
    return TCL_OK; 
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_InfoObjCmd --







|



















|


|
|

>

|



|






|
>

|


>
|
|
|
|
<
<
<

>
|
>
>

|


>
>
>
>
>
>
>

>
|








|
>
>
>


>
|












|

|






>
>
>
>
>
>
>
>
>
|





|



















|


|
|

|
<
|
|
|
<
|



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




>
|

|
|







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

301
302
303

304
305
306
307



308
309
310
311
312
313
314
315
316

317
318




319




320
321
322
323
324

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
			    SortElement *rightPtr, SortInfo *infoPtr));
static int		SortCompare _ANSI_ARGS_((Tcl_Obj *firstPtr,
			    Tcl_Obj *second, SortInfo *infoPtr));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_IfObjCmd --
 *
 *	This procedure is invoked to process the "if" Tcl command.
 *	See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "if" or the name
 *	to which "if" was renamed: e.g., "set z if; $z 1 {puts foo}"
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_IfObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int thenScriptIndex = 0;	/* then script to be evaled after syntax check */
    int i, result, value;
    char *clause;
    i = 1;
    while (1) {
	/*
	 * At this point in the loop, objv and objc refer to an expression
	 * to test, either for the main expression or an expression
	 * following an "elseif".  The arguments after the expression must
	 * be "then" (optional) and a script to execute if the expression is
	 * true.
	 */

	if (i >= objc) {
	    clause = Tcl_GetString(objv[i-1]);
	    Tcl_AppendResult(interp, "wrong # args: no expression after \"",
		    clause, "\" argument", (char *) NULL);
	    return TCL_ERROR;
	}
	if (!thenScriptIndex) {
	    result = Tcl_ExprBooleanObj(interp, objv[i], &value);
	    if (result != TCL_OK) {
		return result;
	    }



	}
	i++;
	if (i >= objc) {
	    missingScript:
	    clause = Tcl_GetString(objv[i-1]);
	    Tcl_AppendResult(interp, "wrong # args: no script following \"",
		    clause, "\" argument", (char *) NULL);
	    return TCL_ERROR;
	}
	clause = Tcl_GetString(objv[i]);
	if ((i < objc) && (strcmp(clause, "then") == 0)) {
	    i++;
	}
	if (i >= objc) {
	    goto missingScript;
	}
	if (value) {
	    thenScriptIndex = i;
	    value = 0;
	}
	
	/*
	 * The expression evaluated to false.  Skip the command, then
	 * see if there is an "else" or "elseif" clause.
	 */

	i++;
	if (i >= objc) {
	    if (thenScriptIndex) {
		return Tcl_EvalObjEx(interp, objv[thenScriptIndex], 0);
	    }
	    return TCL_OK;
	}
	clause = Tcl_GetString(objv[i]);
	if ((clause[0] == 'e') && (strcmp(clause, "elseif") == 0)) {
	    i++;
	    continue;
	}
	break;
    }

    /*
     * Couldn't find a "then" or "elseif" clause to execute.  Check now
     * for an "else" clause.  We know that there's at least one more
     * argument when we get here.
     */

    if (strcmp(clause, "else") == 0) {
	i++;
	if (i >= objc) {
	    Tcl_AppendResult(interp,
		    "wrong # args: no script following \"else\" argument",
		    (char *) NULL);
	    return TCL_ERROR;
	}
    }
    if (i < objc - 1) {
	Tcl_AppendResult(interp,
		"wrong # args: extra words after \"else\" clause in \"if\" command",
		(char *) NULL);
	return TCL_ERROR;
    }
    if (thenScriptIndex) {
	return Tcl_EvalObjEx(interp, objv[thenScriptIndex], 0);
    }
    return Tcl_EvalObjEx(interp, objv[i], 0);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_IncrObjCmd --
 *
 *	This procedure is invoked to process the "incr" Tcl command.
 *	See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "incr" or the name
 *	to which "incr" was renamed: e.g., "set z incr; $z i -1"
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

    /* ARGSUSED */
int
Tcl_IncrObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    long incrAmount;

    Tcl_Obj *newValuePtr;
    
    if ((objc != 2) && (objc != 3)) {

        Tcl_WrongNumArgs(interp, 1, objv, "varName ?increment?");
	return TCL_ERROR;
    }




    /*
     * Calculate the amount to increment by.
     */
    
    if (objc == 2) {
	incrAmount = 1;
    } else {
	if (Tcl_GetLongFromObj(interp, objv[2], &incrAmount) != TCL_OK) {
	    Tcl_AddErrorInfo(interp, "\n    (reading increment)");

	    return TCL_ERROR;
	}




    }




    
    /*
     * Increment the variable's value.
     */


    newValuePtr = TclIncrVar2(interp, objv[1], (Tcl_Obj *) NULL, incrAmount,
	    TCL_LEAVE_ERR_MSG);
    if (newValuePtr == NULL) {
	return TCL_ERROR;
    }

    /*
     * Set the interpreter's object result to refer to the variable's new
     * value object.
     */

    Tcl_SetObjResult(interp, newValuePtr);
    return TCL_OK; 
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_InfoObjCmd --
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
	     (char *) NULL};
    enum ISubCmdIdx {
	    IArgsIdx, IBodyIdx, ICmdCountIdx, ICommandsIdx,
	    ICompleteIdx, IDefaultIdx, IExistsIdx, IGlobalsIdx,
	    IHostnameIdx, ILevelIdx, ILibraryIdx, ILoadedIdx,
	    ILocalsIdx, INameOfExecutableIdx, IPatchLevelIdx, IProcsIdx,
	    IScriptIdx, ISharedLibExtensionIdx, ITclVersionIdx, IVarsIdx
    } index;
    int result;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
        return TCL_ERROR;
    }
    
    result = Tcl_GetIndexFromObj(interp, objv[1], subCmds, "option", 0,







|
|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
	     (char *) NULL};
    enum ISubCmdIdx {
	    IArgsIdx, IBodyIdx, ICmdCountIdx, ICommandsIdx,
	    ICompleteIdx, IDefaultIdx, IExistsIdx, IGlobalsIdx,
	    IHostnameIdx, ILevelIdx, ILibraryIdx, ILoadedIdx,
	    ILocalsIdx, INameOfExecutableIdx, IPatchLevelIdx, IProcsIdx,
	    IScriptIdx, ISharedLibExtensionIdx, ITclVersionIdx, IVarsIdx
    };
    int index, result;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
        return TCL_ERROR;
    }
    
    result = Tcl_GetIndexFromObj(interp, objv[1], subCmds, "option", 0,
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
    Tcl_Obj *listObjPtr;

    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "procname");
        return TCL_ERROR;
    }

    name = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    procPtr = TclFindProc(iPtr, name);
    if (procPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "\"", name, "\" isn't a procedure", (char *) NULL);
        return TCL_ERROR;
    }

    /*
     * Build a return list containing the arguments.
     */
    
    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;
            localPtr = localPtr->nextPtr) {
        if (localPtr->isArg) {
            Tcl_ListObjAppendElement(interp, listObjPtr,
		    Tcl_NewStringObj(localPtr->name, -1));
        }
    }
    Tcl_SetObjResult(interp, listObjPtr);
    return TCL_OK;
}







|














|







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
    Tcl_Obj *listObjPtr;

    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "procname");
        return TCL_ERROR;
    }

    name = Tcl_GetString(objv[2]);
    procPtr = TclFindProc(iPtr, name);
    if (procPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "\"", name, "\" isn't a procedure", (char *) NULL);
        return TCL_ERROR;
    }

    /*
     * Build a return list containing the arguments.
     */
    
    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;
            localPtr = localPtr->nextPtr) {
        if (TclIsVarArgument(localPtr)) {
            Tcl_ListObjAppendElement(interp, listObjPtr,
		    Tcl_NewStringObj(localPtr->name, -1));
        }
    }
    Tcl_SetObjResult(interp, listObjPtr);
    return TCL_OK;
}
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
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register Interp *iPtr = (Interp *) interp;
    char *name;
    Proc *procPtr;


    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "procname");
        return TCL_ERROR;
    }

    name = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    procPtr = TclFindProc(iPtr, name);
    if (procPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"\"", name, "\" isn't a procedure", (char *) NULL);
        return TCL_ERROR;
    }




















    Tcl_SetObjResult(interp, procPtr->bodyPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InfoCmdCountCmd --







>
|





|






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







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
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register Interp *iPtr = (Interp *) interp;
    char *name;
    Proc *procPtr;
    Tcl_Obj *bodyPtr, *resultPtr;
    
    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "procname");
        return TCL_ERROR;
    }

    name = Tcl_GetString(objv[2]);
    procPtr = TclFindProc(iPtr, name);
    if (procPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"\"", name, "\" isn't a procedure", (char *) NULL);
        return TCL_ERROR;
    }

    /*
     * we need to check if the body from this procedure had been generated
     * from a precompiled body. If that is the case, then the bodyPtr's
     * string representation is bogus, since sources are not available.
     * In order to make sure that later manipulations of the object do not
     * invalidate the internal representation, we make a copy of the string
     * representation and return that one, instead.
     */

    bodyPtr = procPtr->bodyPtr;
    resultPtr = bodyPtr;
    if (bodyPtr->typePtr == &tclByteCodeType) {
        ByteCode *codePtr = (ByteCode *) bodyPtr->internalRep.otherValuePtr;

        if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
            resultPtr = Tcl_NewStringObj(bodyPtr->bytes, bodyPtr->length);
        }
    }
    
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InfoCmdCountCmd --
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
    Tcl_HashSearch search;
    Namespace *nsPtr;
    Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
    Namespace *currNsPtr   = (Namespace *) Tcl_GetCurrentNamespace(interp);
    Tcl_Obj *listPtr, *elemObjPtr;
    int specificNsInPattern = 0;  /* Init. to avoid compiler warning. */
    Tcl_Command cmd;
    int result;

    /*
     * Get the pattern and find the "effective namespace" in which to
     * list commands.
     */

    if (objc == 2) {







<







659
660
661
662
663
664
665

666
667
668
669
670
671
672
    Tcl_HashSearch search;
    Namespace *nsPtr;
    Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
    Namespace *currNsPtr   = (Namespace *) Tcl_GetCurrentNamespace(interp);
    Tcl_Obj *listPtr, *elemObjPtr;
    int specificNsInPattern = 0;  /* Init. to avoid compiler warning. */
    Tcl_Command cmd;


    /*
     * Get the pattern and find the "effective namespace" in which to
     * list commands.
     */

    if (objc == 2) {
644
645
646
647
648
649
650

651
652
653
654
655
656
657
658
659
660
661
662
663
664
	 * error was found while parsing the pattern, return it. Otherwise,
	 * if the namespace wasn't found, just leave nsPtr NULL: we will
	 * return an empty list since no commands there can be found.
	 */

	Namespace *dummy1NsPtr, *dummy2NsPtr;
	

        pattern = Tcl_GetStringFromObj(objv[2], (int *) NULL);
	result = TclGetNamespaceForQualName(interp, pattern,
		(Namespace *) NULL, /*flags*/ TCL_LEAVE_ERR_MSG,
		&nsPtr, &dummy1NsPtr, &dummy2NsPtr, &simplePattern);
	if (result != TCL_OK) {
	    return TCL_ERROR;
	}
	if (nsPtr != NULL) {	/* we successfully found the pattern's ns */
	    specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
	}
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
        return TCL_ERROR;
    }







>
|
|
<
|
<
<
|







680
681
682
683
684
685
686
687
688
689

690


691
692
693
694
695
696
697
698
	 * error was found while parsing the pattern, return it. Otherwise,
	 * if the namespace wasn't found, just leave nsPtr NULL: we will
	 * return an empty list since no commands there can be found.
	 */

	Namespace *dummy1NsPtr, *dummy2NsPtr;
	

	pattern = Tcl_GetString(objv[2]);
	TclGetNamespaceForQualName(interp, pattern, (Namespace *) NULL,

           /*flags*/ 0, &nsPtr, &dummy1NsPtr, &dummy2NsPtr, &simplePattern);



	if (nsPtr != NULL) {	/* we successfully found the pattern's ns */
	    specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
	}
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
        return TCL_ERROR;
    }
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

762
763
764
765
766
767
768
static int
InfoCompleteCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    char *command;

    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "command");
        return TCL_ERROR;
    }

    command = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    if (Tcl_CommandComplete(command)) {
	Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
    } else {
	Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InfoDefaultCmd --







<
<





<
|




>







776
777
778
779
780
781
782


783
784
785
786
787

788
789
790
791
792
793
794
795
796
797
798
799
800
static int
InfoCompleteCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{


    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "command");
        return TCL_ERROR;
    }


    if (TclObjCommandComplete(objv[2])) {
	Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
    } else {
	Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InfoDefaultCmd --
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815

816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
    Tcl_Obj *valueObjPtr;

    if (objc != 5) {
        Tcl_WrongNumArgs(interp, 2, objv, "procname arg varname");
        return TCL_ERROR;
    }

    procName = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    argName = Tcl_GetStringFromObj(objv[3], (int *) NULL);

    procPtr = TclFindProc(iPtr, procName);
    if (procPtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"\"", procName, "\" isn't a procedure", (char *) NULL);
        return TCL_ERROR;
    }

    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;
            localPtr = localPtr->nextPtr) {

        if ((localPtr->isArg) && (strcmp(argName, localPtr->name) == 0)) {
            if (localPtr->defValuePtr != NULL) {
		valueObjPtr = Tcl_ObjSetVar2(interp, objv[4], NULL,
                        localPtr->defValuePtr, 0);
                if (valueObjPtr == NULL) {
                    defStoreError:
		    varName = Tcl_GetStringFromObj(objv[4], (int *) NULL);
		    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
	                    "couldn't store default value in variable \"",
			    varName, "\"", (char *) NULL);
                    return TCL_ERROR;
                }
		Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
            } else {
                Tcl_Obj *nullObjPtr = Tcl_NewObj();
                valueObjPtr = Tcl_ObjSetVar2(interp, objv[4], NULL,
                    nullObjPtr, 0);
                if (valueObjPtr == NULL) {
                    Tcl_DecrRefCount(nullObjPtr); /* free unneeded obj */
                    goto defStoreError;
                }
		Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
            }
            return TCL_OK;







|
|










>
|


|


|









|







829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
    Tcl_Obj *valueObjPtr;

    if (objc != 5) {
        Tcl_WrongNumArgs(interp, 2, objv, "procname arg varname");
        return TCL_ERROR;
    }

    procName = Tcl_GetString(objv[2]);
    argName = Tcl_GetString(objv[3]);

    procPtr = TclFindProc(iPtr, procName);
    if (procPtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"\"", procName, "\" isn't a procedure", (char *) NULL);
        return TCL_ERROR;
    }

    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;
            localPtr = localPtr->nextPtr) {
        if (TclIsVarArgument(localPtr)
		&& (strcmp(argName, localPtr->name) == 0)) {
            if (localPtr->defValuePtr != NULL) {
		valueObjPtr = Tcl_ObjSetVar2(interp, objv[4], NULL,
			localPtr->defValuePtr, 0);
                if (valueObjPtr == NULL) {
                    defStoreError:
		    varName = Tcl_GetString(objv[4]);
		    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
	                    "couldn't store default value in variable \"",
			    varName, "\"", (char *) NULL);
                    return TCL_ERROR;
                }
		Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
            } else {
                Tcl_Obj *nullObjPtr = Tcl_NewObj();
                valueObjPtr = Tcl_ObjSetVar2(interp, objv[4], NULL,
			nullObjPtr, 0);
                if (valueObjPtr == NULL) {
                    Tcl_DecrRefCount(nullObjPtr); /* free unneeded obj */
                    goto defStoreError;
                }
		Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
            }
            return TCL_OK;
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
    Var *varPtr, *arrayPtr;

    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "varName");
        return TCL_ERROR;
    }

    varName = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    varPtr = TclLookupVar(interp, varName, (char *) NULL,
            TCL_PARSE_PART1, "access",
            /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
    if ((varPtr != NULL) && !TclIsVarUndefined(varPtr)) {
        Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
    } else {
        Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
    }
    return TCL_OK;







|

|







910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
    Var *varPtr, *arrayPtr;

    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "varName");
        return TCL_ERROR;
    }

    varName = Tcl_GetString(objv[2]);
    varPtr = TclLookupVar(interp, varName, (char *) NULL,
            0, "access",
            /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
    if ((varPtr != NULL) && !TclIsVarUndefined(varPtr)) {
        Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
    } else {
        Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
    }
    return TCL_OK;
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
    Tcl_HashSearch search;
    Var *varPtr;
    Tcl_Obj *listPtr;

    if (objc == 2) {
        pattern = NULL;
    } else if (objc == 3) {
        pattern = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
        return TCL_ERROR;
    }

    /*
     * Scan through the global :: namespace's variable table and create a







|







960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
    Tcl_HashSearch search;
    Var *varPtr;
    Tcl_Obj *listPtr;

    if (objc == 2) {
        pattern = NULL;
    } else if (objc == 3) {
        pattern = Tcl_GetString(objv[2]);
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
        return TCL_ERROR;
    }

    /*
     * Scan through the global :: namespace's variable table and create a
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
            return TCL_ERROR;
        }
        if (level <= 0) {
            if (iPtr->varFramePtr == NULL) {
                levelError:
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"bad level \"",
			Tcl_GetStringFromObj(objv[2], (int *) NULL),
			"\"", (char *) NULL);
                return TCL_ERROR;
            }
            level += iPtr->varFramePtr->level;
        }
        for (framePtr = iPtr->varFramePtr;  framePtr != NULL;
                framePtr = framePtr->callerVarPtr) {







|







1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
            return TCL_ERROR;
        }
        if (level <= 0) {
            if (iPtr->varFramePtr == NULL) {
                levelError:
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"bad level \"",
			Tcl_GetString(objv[2]),
			"\"", (char *) NULL);
                return TCL_ERROR;
            }
            level += iPtr->varFramePtr->level;
        }
        for (framePtr = iPtr->varFramePtr;  framePtr != NULL;
                framePtr = framePtr->callerVarPtr) {
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
        Tcl_WrongNumArgs(interp, 2, objv, "?interp?");
        return TCL_ERROR;
    }

    if (objc == 2) {		/* get loaded pkgs in all interpreters */
	interpName = NULL;
    } else {			/* get pkgs just in specified interp */
	interpName = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    }
    result = TclGetLoadedPackages(interp, interpName);
    return result;
}

/*
 *----------------------------------------------------------------------







|







1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
        Tcl_WrongNumArgs(interp, 2, objv, "?interp?");
        return TCL_ERROR;
    }

    if (objc == 2) {		/* get loaded pkgs in all interpreters */
	interpName = NULL;
    } else {			/* get pkgs just in specified interp */
	interpName = Tcl_GetString(objv[2]);
    }
    result = TclGetLoadedPackages(interp, interpName);
    return result;
}

/*
 *----------------------------------------------------------------------
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227



1228



































1229
1230


1231



1232
1233
1234
1235
1236
1237
1238
1239


1240
1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
InfoLocalsCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Interp *iPtr = (Interp *) interp;
    Var *varPtr;
    char *varName, *pattern;
    int i, localVarCt;
    Tcl_HashTable *localVarTablePtr;
    register Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;
    Tcl_Obj *listPtr;

    if (objc == 2) {
        pattern = NULL;
    } else if (objc == 3) {
        pattern = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
        return TCL_ERROR;
    }
    
    if (iPtr->varFramePtr == NULL) {
        return TCL_OK;
    }
    localVarTablePtr = iPtr->varFramePtr->varTablePtr;

    /*
     * Return a list containing names of first the compiled locals (i.e. the
     * ones stored in the call frame), then the variables in the local hash
     * table (if one exists).
     */
    
    listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);



    



































    localVarCt = iPtr->varFramePtr->numCompiledLocals;
    for (i = 0, varPtr = iPtr->varFramePtr->compiledLocals;


            i < localVarCt;



	    i++, varPtr++) {
	if (!TclIsVarUndefined(varPtr)) {
	    varName = varPtr->name;
	    if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
		Tcl_ListObjAppendElement(interp, listPtr,
		        Tcl_NewStringObj(varName, -1));
	    }
        }


    }
    
    if (localVarTablePtr != NULL) {
	for (entryPtr = Tcl_FirstHashEntry(localVarTablePtr, &search);
	        entryPtr != NULL;
                entryPtr = Tcl_NextHashEntry(&search)) {
	    varPtr = (Var *) Tcl_GetHashValue(entryPtr);
	    if (!TclIsVarUndefined(varPtr) && !TclIsVarLink(varPtr)) {

		varName = Tcl_GetHashKey(localVarTablePtr, entryPtr);
		if ((pattern == NULL)
		        || Tcl_StringMatch(varName, pattern)) {
		    Tcl_ListObjAppendElement(interp, listPtr,
			    Tcl_NewStringObj(varName, -1));
		}
	    }
	}
    }
    
    Tcl_SetObjResult(interp, listPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InfoNameOfExecutableCmd --
 *







<
|
<
<
<
<





|





|


<








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

|
>
>
|
>
>
>
|
|






>
>







|
>









<
<
<







1225
1226
1227
1228
1229
1230
1231

1232




1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329



1330
1331
1332
1333
1334
1335
1336
InfoLocalsCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Interp *iPtr = (Interp *) interp;

    char *pattern;




    Tcl_Obj *listPtr;

    if (objc == 2) {
        pattern = NULL;
    } else if (objc == 3) {
        pattern = Tcl_GetString(objv[2]);
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
        return TCL_ERROR;
    }
    
    if (iPtr->varFramePtr == NULL || !iPtr->varFramePtr->isProcCallFrame) {
        return TCL_OK;
    }


    /*
     * Return a list containing names of first the compiled locals (i.e. the
     * ones stored in the call frame), then the variables in the local hash
     * table (if one exists).
     */
    
    listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    AppendLocals(interp, listPtr, pattern, 0);
    Tcl_SetObjResult(interp, listPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * AppendLocals --
 *
 *	Append the local variables for the current frame to the
 *	specified list object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
AppendLocals(interp, listPtr, pattern, includeLinks)
    Tcl_Interp *interp;		/* Current interpreter. */
    Tcl_Obj *listPtr;		/* List object to append names to. */
    char *pattern;		/* Pattern to match against. */
    int includeLinks;		/* 1 if upvars should be included, else 0. */
{
    Interp *iPtr = (Interp *) interp;
    CompiledLocal *localPtr;
    Var *varPtr;
    int i, localVarCt;
    char *varName;
    Tcl_HashTable *localVarTablePtr;
    register Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;

    localPtr = iPtr->varFramePtr->procPtr->firstLocalPtr;
    localVarCt = iPtr->varFramePtr->numCompiledLocals;
    varPtr = iPtr->varFramePtr->compiledLocals;
    localVarTablePtr = iPtr->varFramePtr->varTablePtr;

    for (i = 0; i < localVarCt; i++) {
	/*
	 * Skip nameless (temporary) variables and undefined variables
	 */

	if (!TclIsVarTemporary(localPtr) && !TclIsVarUndefined(varPtr)) {
	    varName = varPtr->name;
	    if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
		Tcl_ListObjAppendElement(interp, listPtr,
		        Tcl_NewStringObj(varName, -1));
	    }
        }
	varPtr++;
	localPtr = localPtr->nextPtr;
    }
    
    if (localVarTablePtr != NULL) {
	for (entryPtr = Tcl_FirstHashEntry(localVarTablePtr, &search);
	        entryPtr != NULL;
                entryPtr = Tcl_NextHashEntry(&search)) {
	    varPtr = (Var *) Tcl_GetHashValue(entryPtr);
	    if (!TclIsVarUndefined(varPtr)
		    && (includeLinks || !TclIsVarLink(varPtr))) {
		varName = Tcl_GetHashKey(localVarTablePtr, entryPtr);
		if ((pattern == NULL)
		        || Tcl_StringMatch(varName, pattern)) {
		    Tcl_ListObjAppendElement(interp, listPtr,
			    Tcl_NewStringObj(varName, -1));
		}
	    }
	}
    }



}

/*
 *----------------------------------------------------------------------
 *
 * InfoNameOfExecutableCmd --
 *
1283
1284
1285
1286
1287
1288
1289


1290
1291
1292
1293
1294

1295

1296
1297
1298
1299
1300
1301
1302
1303
static int
InfoNameOfExecutableCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{


    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 2, objv, NULL);
        return TCL_ERROR;
    }
    

    if (tclExecutableName != NULL) {

	Tcl_SetStringObj(Tcl_GetObjResult(interp), tclExecutableName, -1);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







>
>




|
>
|
>
|







1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
static int
InfoNameOfExecutableCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    CONST char *nameOfExecutable;

    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 2, objv, NULL);
        return TCL_ERROR;
    }

    nameOfExecutable = Tcl_GetNameOfExecutable();
    
    if (nameOfExecutable != NULL) {
	Tcl_SetStringObj(Tcl_GetObjResult(interp), (char *)nameOfExecutable, -1);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399









1400

1401
1402
1403
1404
1405
1406
1407
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    char *cmdName, *pattern;
    Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    register Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;
    Command *cmdPtr;
    Tcl_Obj *listPtr;

    if (objc == 2) {
        pattern = NULL;
    } else if (objc == 3) {
        pattern = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
        return TCL_ERROR;
    }

    /*
     * Scan through the current namespace's command table and return a list
     * of all procs that match the pattern.
     */
    
    listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    for (entryPtr = Tcl_FirstHashEntry(&currNsPtr->cmdTable, &search);
            entryPtr != NULL;
            entryPtr = Tcl_NextHashEntry(&search)) {
        cmdName = Tcl_GetHashKey(&currNsPtr->cmdTable, entryPtr);
        cmdPtr = (Command *) Tcl_GetHashValue(entryPtr);









        if (TclIsProc(cmdPtr)) {

            if ((pattern == NULL) || Tcl_StringMatch(cmdName, pattern)) {
                Tcl_ListObjAppendElement(interp, listPtr,
		        Tcl_NewStringObj(cmdName, -1));
            }
        }
    }
    Tcl_SetObjResult(interp, listPtr);







|





|
















>
>
>
>
>
>
>
>
>
|
>







1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    char *cmdName, *pattern;
    Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    register Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;
    Command *cmdPtr, *realCmdPtr;
    Tcl_Obj *listPtr;

    if (objc == 2) {
        pattern = NULL;
    } else if (objc == 3) {
        pattern = Tcl_GetString(objv[2]);
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
        return TCL_ERROR;
    }

    /*
     * Scan through the current namespace's command table and return a list
     * of all procs that match the pattern.
     */
    
    listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    for (entryPtr = Tcl_FirstHashEntry(&currNsPtr->cmdTable, &search);
            entryPtr != NULL;
            entryPtr = Tcl_NextHashEntry(&search)) {
        cmdName = Tcl_GetHashKey(&currNsPtr->cmdTable, entryPtr);
        cmdPtr = (Command *) Tcl_GetHashValue(entryPtr);

	/*
	 * If the command isn't itself a proc, it still might be an
	 * imported command that points to a "real" proc in a different
	 * namespace.
	 */

	realCmdPtr = (Command *) TclGetOriginalCommand(
	        (Tcl_Command) cmdPtr);
        if (TclIsProc(cmdPtr)
	        || ((realCmdPtr != NULL) && TclIsProc(realCmdPtr))) {
            if ((pattern == NULL) || Tcl_StringMatch(cmdName, pattern)) {
                Tcl_ListObjAppendElement(interp, listPtr,
		        Tcl_NewStringObj(cmdName, -1));
            }
        }
    }
    Tcl_SetObjResult(interp, listPtr);
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Interp *iPtr = (Interp *) interp;
    char *varName, *pattern, *simplePattern;
    register Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;
    Var *varPtr, *localVarPtr;
    Namespace *nsPtr;
    Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
    Namespace *currNsPtr   = (Namespace *) Tcl_GetCurrentNamespace(interp);
    Tcl_Obj *listPtr, *elemObjPtr;
    int specificNsInPattern = 0;  /* Init. to avoid compiler warning. */
    int i, result;

    /*
     * Get the pattern and find the "effective namespace" in which to
     * list variables. We only use this effective namespace if there's
     * no active Tcl procedure frame.
     */








|





<







1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657

1658
1659
1660
1661
1662
1663
1664
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Interp *iPtr = (Interp *) interp;
    char *varName, *pattern, *simplePattern;
    register Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;
    Var *varPtr;
    Namespace *nsPtr;
    Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
    Namespace *currNsPtr   = (Namespace *) Tcl_GetCurrentNamespace(interp);
    Tcl_Obj *listPtr, *elemObjPtr;
    int specificNsInPattern = 0;  /* Init. to avoid compiler warning. */


    /*
     * Get the pattern and find the "effective namespace" in which to
     * list variables. We only use this effective namespace if there's
     * no active Tcl procedure frame.
     */

1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
	 * error was found while parsing the pattern, return it. Otherwise,
	 * if the namespace wasn't found, just leave nsPtr NULL: we will
	 * return an empty list since no variables there can be found.
	 */

	Namespace *dummy1NsPtr, *dummy2NsPtr;

        pattern = Tcl_GetStringFromObj(objv[2], (int *) NULL);
	result = TclGetNamespaceForQualName(interp, pattern,
		(Namespace *) NULL, /*flags*/ TCL_LEAVE_ERR_MSG,
		&nsPtr, &dummy1NsPtr, &dummy2NsPtr, &simplePattern);
	if (result != TCL_OK) {
	    return TCL_ERROR;
	}
	if (nsPtr != NULL) {	/* we successfully found the pattern's ns */
	    specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
	}
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
        return TCL_ERROR;
    }







|
|
<
|
<
|
|







1673
1674
1675
1676
1677
1678
1679
1680
1681

1682

1683
1684
1685
1686
1687
1688
1689
1690
1691
	 * error was found while parsing the pattern, return it. Otherwise,
	 * if the namespace wasn't found, just leave nsPtr NULL: we will
	 * return an empty list since no variables there can be found.
	 */

	Namespace *dummy1NsPtr, *dummy2NsPtr;

        pattern = Tcl_GetString(objv[2]);
	TclGetNamespaceForQualName(interp, pattern, (Namespace *) NULL,

		/*flags*/ 0, &nsPtr, &dummy1NsPtr, &dummy2NsPtr,

		&simplePattern);

	if (nsPtr != NULL) {	/* we successfully found the pattern's ns */
	    specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
	}
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
        return TCL_ERROR;
    }
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
			}
		    }
		}
		entryPtr = Tcl_NextHashEntry(&search);
	    }
	}
    } else {
	/*
	 * We're in a local call frame and no specific namespace was
	 * specific. Create a list that starts with the compiled locals
	 * (i.e. the ones stored in the call frame).
	 */

	CallFrame *varFramePtr = iPtr->varFramePtr;
        int localVarCt = varFramePtr->numCompiledLocals;
	Tcl_HashTable *varTablePtr = varFramePtr->varTablePtr;
	
        for (i = 0, localVarPtr = iPtr->varFramePtr->compiledLocals;
                i < localVarCt;
                i++, localVarPtr++) {
            if (!TclIsVarUndefined(localVarPtr)) {
                varName = localVarPtr->name;
                if ((simplePattern == NULL)
		        || Tcl_StringMatch(varName, simplePattern)) {
                    Tcl_ListObjAppendElement(interp, listPtr,
			    Tcl_NewStringObj(varName, -1));
                }
            }
        }

	/*
	 * Now add in the variables in the call frame's variable hash
	 * table (if one exists).
	 */

	if (varTablePtr != NULL) {
	    for (entryPtr = Tcl_FirstHashEntry(varTablePtr, &search);
		    entryPtr != NULL;
		    entryPtr = Tcl_NextHashEntry(&search)) {
		varPtr = (Var *) Tcl_GetHashValue(entryPtr);
		if (!TclIsVarUndefined(varPtr)) {
		    varName = Tcl_GetHashKey(varTablePtr, entryPtr);
		    if ((simplePattern == NULL)
		            || Tcl_StringMatch(varName, simplePattern)) {
			Tcl_ListObjAppendElement(interp, listPtr,
				Tcl_NewStringObj(varName, -1));
		    }
		}
	    }
	}
    }
    
    Tcl_SetObjResult(interp, listPtr);
    return TCL_OK;
}

/*







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







1756
1757
1758
1759
1760
1761
1762

















1763

























1764
1765
1766
1767
1768
1769
1770
			}
		    }
		}
		entryPtr = Tcl_NextHashEntry(&search);
	    }
	}
    } else {

















	AppendLocals(interp, listPtr, simplePattern, 1);

























    }
    
    Tcl_SetObjResult(interp, listPtr);
    return TCL_OK;
}

/*
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
    Tcl_Interp *interp;		/* Current interpreter. */
    register int objc;		/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Obj *listPtr, *resultPtr;
    Tcl_ObjType *typePtr;
    int index, isDuplicate, len, result;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 1, objv, "list index element ?element ...?");
	return TCL_ERROR;
    }

    /*
     * Get the index first since, if a conversion to int is needed, it







|







1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
    Tcl_Interp *interp;		/* Current interpreter. */
    register int objc;		/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Obj *listPtr, *resultPtr;
    Tcl_ObjType *typePtr;
    int index, isDuplicate, len, result;
   
    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 1, objv, "list index element ?element ...?");
	return TCL_ERROR;
    }

    /*
     * Get the index first since, if a conversion to int is needed, it
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
    if (first < 0)  {
    	first = 0;
    }
    if ((first >= listLen) && (listLen > 0)
	    && (strncmp(firstArg, "end", (unsigned) firstArgLen) != 0)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"list doesn't contain element ",
		Tcl_GetStringFromObj(objv[2], (int *) NULL), (int *) NULL);
	result = TCL_ERROR;
	goto errorReturn;
    }
    if (last >= listLen) {
    	last = (listLen - 1);
    }
    if (first <= last) {







|







2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
    if (first < 0)  {
    	first = 0;
    }
    if ((first >= listLen) && (listLen > 0)
	    && (strncmp(firstArg, "end", (unsigned) firstArgLen) != 0)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"list doesn't contain element ",
		Tcl_GetString(objv[2]), (int *) NULL);
	result = TCL_ERROR;
	goto errorReturn;
    }
    if (last >= listLen) {
    	last = (listLen - 1);
    }
    if (first <= last) {
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
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
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
int
Tcl_LsearchObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument values. */
{
#define EXACT	0
#define GLOB	1
#define REGEXP	2
    char *bytes, *patternBytes;
    int i, match, mode, index, result, listLen, length, elemLen;
    Tcl_Obj **elemPtrs;
    static char *switches[] =
	    {"-exact", "-glob", "-regexp", (char *) NULL};





    mode = GLOB;
    if (objc == 4) {
	if (Tcl_GetIndexFromObj(interp, objv[1], switches,
		"search mode", 0, &mode) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "?mode? list pattern");
	return TCL_ERROR;
    }

    /*
     * Make sure the list argument is a list object and get its length and
     * a pointer to its array of element pointers.
     */

    result = Tcl_ListObjGetElements(interp, objv[objc-2], &listLen, &elemPtrs);
    if (result != TCL_OK) {
	return result;
    }


    patternBytes = Tcl_GetStringFromObj(objv[objc-1], &length);
 
    index = -1;
    for (i = 0; i < listLen; i++) {
	match = 0;
	bytes = Tcl_GetStringFromObj(elemPtrs[i], &elemLen);
	switch (mode) {
	    case EXACT:
		if (length == elemLen) {
		    match = (memcmp(bytes, patternBytes,
			    (size_t) length) == 0);
		}
		break;

	    case GLOB:
		/*
		 * WARNING: will not work with data containing NULLs.
		 */
		match = Tcl_StringMatch(bytes, patternBytes);
		break;

	    case REGEXP:
		/*
		 * WARNING: will not work with data containing NULLs.
		 */
		match = Tcl_RegExpMatch(interp, bytes, patternBytes);
		if (match < 0) {
		    return TCL_ERROR;
		}
		break;
	}

	if (match) {
	    index = i;
	    break;
	}
    }

    Tcl_SetIntObj(Tcl_GetObjResult(interp), index);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







<
<
<

|
|
|
|
>
>
>
>

|

|
|












|




>
|
|

|

|
|
|





>
|
<
<
<


>
|
<
<
<
|




|
>
|




<







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
int
Tcl_LsearchObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument values. */
{



    char *bytes, *patternBytes;
    int i, match, mode, index, result, listc, length, elemLen;
    Tcl_Obj *patObj, **listv;
    static char *options[] = {
	"-exact",	"-glob",	"-regexp",	NULL
    };
    enum options {
	LSEARCH_EXACT,	LSEARCH_GLOB,	LSEARCH_REGEXP
    };

    mode = LSEARCH_GLOB;
    if (objc == 4) {
	if (Tcl_GetIndexFromObj(interp, objv[1], options, "search mode", 0,
		&mode) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "?mode? list pattern");
	return TCL_ERROR;
    }

    /*
     * Make sure the list argument is a list object and get its length and
     * a pointer to its array of element pointers.
     */

    result = Tcl_ListObjGetElements(interp, objv[objc - 2], &listc, &listv);
    if (result != TCL_OK) {
	return result;
    }

    patObj = objv[objc - 1];
    patternBytes = Tcl_GetStringFromObj(patObj, &length);

    index = -1;
    for (i = 0; i < listc; i++) {
	match = 0;
	bytes = Tcl_GetStringFromObj(listv[i], &elemLen);
	switch ((enum options) mode) {
	    case LSEARCH_EXACT: {
		if (length == elemLen) {
		    match = (memcmp(bytes, patternBytes,
			    (size_t) length) == 0);
		}
		break;
	    }
	    case LSEARCH_GLOB: {



		match = Tcl_StringMatch(bytes, patternBytes);
		break;
	    }
	    case LSEARCH_REGEXP: {



		match = TclRegExpMatchObj(interp, bytes, patObj);
		if (match < 0) {
		    return TCL_ERROR;
		}
		break;
	    }
	}
	if (match != 0) {
	    index = i;
	    break;
	}
    }

    Tcl_SetIntObj(Tcl_GetObjResult(interp), index);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
int
Tcl_LsortObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument values. */
{
    int i, index, dummy;
    Tcl_Obj *resultPtr;
    int length;
    Tcl_Obj *cmdPtr, **listObjPtrs;
    SortElement *elementArray;
    SortElement *elementPtr;        
    SortInfo sortInfo;                  /* Information about this sort that
                                         * needs to be passed to the 







|







2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
int
Tcl_LsortObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument values. */
{
    int i, index;
    Tcl_Obj *resultPtr;
    int length;
    Tcl_Obj *cmdPtr, **listObjPtrs;
    SortElement *elementArray;
    SortElement *elementPtr;        
    SortInfo sortInfo;                  /* Information about this sort that
                                         * needs to be passed to the 
2466
2467
2468
2469
2470
2471
2472





2473







2474
2475
2476
2477
2478
2479
2480
2481
2482
		break;
	    case 7:			/* -real */
		sortInfo.sortMode = SORTMODE_REAL;
		break;
	}
    }
    if (sortInfo.sortMode == SORTMODE_COMMAND) {





	Tcl_DStringInit(&sortInfo.compareCmd);







	Tcl_DStringAppend(&sortInfo.compareCmd,
		Tcl_GetStringFromObj(cmdPtr, &dummy), -1);
    }

    sortInfo.resultCode = Tcl_ListObjGetElements(interp, objv[objc-1],
	    &length, &listObjPtrs);
    if (sortInfo.resultCode != TCL_OK) {
	goto done;
    }







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







2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
		break;
	    case 7:			/* -real */
		sortInfo.sortMode = SORTMODE_REAL;
		break;
	}
    }
    if (sortInfo.sortMode == SORTMODE_COMMAND) {
	/*
	 * The existing command is a list. We want to flatten it, append
	 * two dummy arguments on the end, and replace these arguments
	 * later.
	 */

        Tcl_Obj *newCommandPtr = Tcl_DuplicateObj(cmdPtr);

	if (Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj()) 
	        != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj());
	sortInfo.compareCmdPtr = newCommandPtr;
	Tcl_IncrRefCount(newCommandPtr);
    }

    sortInfo.resultCode = Tcl_ListObjGetElements(interp, objv[objc-1],
	    &length, &listObjPtrs);
    if (sortInfo.resultCode != TCL_OK) {
	goto done;
    }
2502
2503
2504
2505
2506
2507
2508

2509
2510
2511
2512
2513
2514
2515
2516
	    Tcl_ListObjAppendElement(interp, resultPtr, elementPtr->objPtr);
	}
    }
    ckfree((char*) elementArray);

    done:
    if (sortInfo.sortMode == SORTMODE_COMMAND) {

	Tcl_DStringFree(&sortInfo.compareCmd);
    }
    return sortInfo.resultCode;
}

/*
 *----------------------------------------------------------------------
 *







>
|







2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
	    Tcl_ListObjAppendElement(interp, resultPtr, elementPtr->objPtr);
	}
    }
    ckfree((char*) elementArray);

    done:
    if (sortInfo.sortMode == SORTMODE_COMMAND) {
	Tcl_DecrRefCount(sortInfo.compareCmdPtr);
	sortInfo.compareCmdPtr = NULL;
    }
    return sortInfo.resultCode;
}

/*
 *----------------------------------------------------------------------
 *
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671

static int
SortCompare(objPtr1, objPtr2, infoPtr)
    Tcl_Obj *objPtr1, *objPtr2;		/* Values to be compared. */
    SortInfo *infoPtr;                  /* Information passed from the
                                         * top-level "lsort" command */
{
    int order, dummy, listLen, index;
    Tcl_Obj *objPtr;
    char buffer[30];

    order = 0;
    if (infoPtr->resultCode != TCL_OK) {
	/*
	 * Once an error has occurred, skip any future comparisons
	 * so as to preserve the error message in sortInterp->result.
	 */







|

|







2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721

static int
SortCompare(objPtr1, objPtr2, infoPtr)
    Tcl_Obj *objPtr1, *objPtr2;		/* Values to be compared. */
    SortInfo *infoPtr;                  /* Information passed from the
                                         * top-level "lsort" command */
{
    int order, listLen, index;
    Tcl_Obj *objPtr;
    char buffer[TCL_INTEGER_SPACE];

    order = 0;
    if (infoPtr->resultCode != TCL_OK) {
	/*
	 * Once an error has occurred, skip any future comparisons
	 * so as to preserve the error message in sortInterp->result.
	 */
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
		!= TCL_OK) {
	    infoPtr->resultCode = TCL_ERROR;
	    return order;
	}
	if (objPtr == NULL) {
	    objPtr = objPtr1;
	    missingElement:
	    sprintf(buffer, "%d", infoPtr->index);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(infoPtr->interp),
			"element ", buffer, " missing from sublist \"",
			Tcl_GetStringFromObj(objPtr, (int *) NULL),
			"\"", (char *) NULL);
	    infoPtr->resultCode = TCL_ERROR;
	    return order;
	}
	objPtr1 = objPtr;

	if (Tcl_ListObjLength(infoPtr->interp, objPtr2, &listLen) != TCL_OK) {
	    infoPtr->resultCode = TCL_ERROR;







|


<
|







2744
2745
2746
2747
2748
2749
2750
2751
2752
2753

2754
2755
2756
2757
2758
2759
2760
2761
		!= TCL_OK) {
	    infoPtr->resultCode = TCL_ERROR;
	    return order;
	}
	if (objPtr == NULL) {
	    objPtr = objPtr1;
	    missingElement:
	    TclFormatInt(buffer, infoPtr->index);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(infoPtr->interp),
			"element ", buffer, " missing from sublist \"",

			Tcl_GetString(objPtr), "\"", (char *) NULL);
	    infoPtr->resultCode = TCL_ERROR;
	    return order;
	}
	objPtr1 = objPtr;

	if (Tcl_ListObjLength(infoPtr->interp, objPtr2, &listLen) != TCL_OK) {
	    infoPtr->resultCode = TCL_ERROR;
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
	if (objPtr == NULL) {
	    objPtr = objPtr2;
	    goto missingElement;
	}
	objPtr2 = objPtr;
    }
    if (infoPtr->sortMode == SORTMODE_ASCII) {
	order = strcmp(Tcl_GetStringFromObj(objPtr1, &dummy),
		Tcl_GetStringFromObj(objPtr2, &dummy));
    } else if (infoPtr->sortMode == SORTMODE_DICTIONARY) {
	order = DictionaryCompare(
		Tcl_GetStringFromObj(objPtr1, &dummy),
		Tcl_GetStringFromObj(objPtr2, &dummy));
    } else if (infoPtr->sortMode == SORTMODE_INTEGER) {
	int a, b;

	if ((Tcl_GetIntFromObj(infoPtr->interp, objPtr1, &a) != TCL_OK)
		|| (Tcl_GetIntFromObj(infoPtr->interp, objPtr2, &b)
		!= TCL_OK)) {
	    infoPtr->resultCode = TCL_ERROR;







|
<


|
<







2775
2776
2777
2778
2779
2780
2781
2782

2783
2784
2785

2786
2787
2788
2789
2790
2791
2792
	if (objPtr == NULL) {
	    objPtr = objPtr2;
	    goto missingElement;
	}
	objPtr2 = objPtr;
    }
    if (infoPtr->sortMode == SORTMODE_ASCII) {
	order = strcmp(Tcl_GetString(objPtr1), Tcl_GetString(objPtr2));

    } else if (infoPtr->sortMode == SORTMODE_DICTIONARY) {
	order = DictionaryCompare(
		Tcl_GetString(objPtr1),	Tcl_GetString(objPtr2));

    } else if (infoPtr->sortMode == SORTMODE_INTEGER) {
	int a, b;

	if ((Tcl_GetIntFromObj(infoPtr->interp, objPtr1, &a) != TCL_OK)
		|| (Tcl_GetIntFromObj(infoPtr->interp, objPtr2, &b)
		!= TCL_OK)) {
	    infoPtr->resultCode = TCL_ERROR;
2761
2762
2763
2764
2765
2766
2767

2768
2769



2770

2771
2772
2773
2774
2775
2776
2777
2778

2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
	}
	if (a > b) {
	    order = 1;
	} else if (b > a) {
	    order = -1;
	}
    } else {

	int oldLength;




	/*

	 * Generate and evaluate a command to determine which string comes
	 * first.
	 */

	oldLength = Tcl_DStringLength(&infoPtr->compareCmd);
	Tcl_DStringAppendElement(&infoPtr->compareCmd,
		Tcl_GetStringFromObj(objPtr1, &dummy));
	Tcl_DStringAppendElement(&infoPtr->compareCmd,

		Tcl_GetStringFromObj(objPtr2, &dummy));
	infoPtr->resultCode = Tcl_Eval(infoPtr->interp, 
		Tcl_DStringValue(&infoPtr->compareCmd));
	Tcl_DStringTrunc(&infoPtr->compareCmd, oldLength);
	if (infoPtr->resultCode != TCL_OK) {
	    Tcl_AddErrorInfo(infoPtr->interp,
		    "\n    (-compare command)");
	    return order;
	}

	/*
	 * Parse the result of the command.







>
|

>
>
>
|
>
|
<


|
|
|
|
>
|
|
|
<
|







2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823

2824
2825
2826
2827
2828
2829
2830
2831
2832
2833

2834
2835
2836
2837
2838
2839
2840
2841
	}
	if (a > b) {
	    order = 1;
	} else if (b > a) {
	    order = -1;
	}
    } else {
	Tcl_Obj **objv, *paramObjv[2];
	int objc;

	paramObjv[0] = objPtr1;
	paramObjv[1] = objPtr2;

  	/*
 	 * We made space in the command list for the two things to
	 * compare. Replace them and evaluate the result.

	 */

	Tcl_ListObjLength(infoPtr->interp, infoPtr->compareCmdPtr, &objc);
	Tcl_ListObjReplace(infoPtr->interp, infoPtr->compareCmdPtr, objc - 2,
		2, 2, paramObjv);
   	Tcl_ListObjGetElements(infoPtr->interp, infoPtr->compareCmdPtr,
		&objc, &objv);

	infoPtr->resultCode = Tcl_EvalObjv(infoPtr->interp, objc, objv, 0);
  

  	if (infoPtr->resultCode != TCL_OK) {
	    Tcl_AddErrorInfo(infoPtr->interp,
		    "\n    (-compare command)");
	    return order;
	}

	/*
	 * Parse the result of the command.
2829
2830
2831
2832
2833
2834
2835

2836
2837
2838
2839
2840

2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896















2897

2898
2899
2900
2901
2902
2903
2904
2905

2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
 *----------------------------------------------------------------------
 */

static int
DictionaryCompare(left, right)
    char *left, *right;          /* The strings to compare */
{

    int diff, zeros;
    int secondaryDiff = 0;

    while (1) {
	if (isdigit(UCHAR(*right)) && isdigit(UCHAR(*left))) {

	    /*
	     * There are decimal numbers embedded in the two
	     * strings.  Compare them as numbers, rather than
	     * strings.  If one number has more leading zeros than
	     * the other, the number with more leading zeros sorts
	     * later, but only as a secondary choice.
	     */

	    zeros = 0;
	    while ((*right == '0') && (*(right + 1) != '\0')) {
		right++;
		zeros--;
	    }
	    while ((*left == '0') && (*(left + 1) != '\0')) {
		left++;
		zeros++;
	    }
	    if (secondaryDiff == 0) {
		secondaryDiff = zeros;
	    }

	    /*
	     * The code below compares the numbers in the two
	     * strings without ever converting them to integers.  It
	     * does this by first comparing the lengths of the
	     * numbers and then comparing the digit values.
	     */

	    diff = 0;
	    while (1) {
		if (diff == 0) {
		    diff = *left - *right;
		}
		right++;
		left++;
		if (!isdigit(UCHAR(*right))) {
		    if (isdigit(UCHAR(*left))) {
			return 1;
		    } else {
			/*
			 * The two numbers have the same length. See
			 * if their values are different.
			 */

			if (diff != 0) {
			    return diff;
			}
			break;
		    }
		} else if (!isdigit(UCHAR(*left))) {
		    return -1;
		}
	    }
	    continue;
	}
        diff = *left - *right;















        if (diff) {

            if (isupper(UCHAR(*left)) && islower(UCHAR(*right))) {
                diff = tolower(*left) - *right;
                if (diff) {
		    return diff;
                } else if (secondaryDiff == 0) {
		    secondaryDiff = -1;
                }
            } else if (isupper(UCHAR(*right)) && islower(UCHAR(*left))) {

                diff = *left - tolower(UCHAR(*right));
                if (diff) {
		    return diff;
                } else if (secondaryDiff == 0) {
		    secondaryDiff = 1;
                }
            } else {
                return diff;
            }
        }
        if (*left == 0) {
	    break;
	}
        left++;
        right++;
    }
    if (diff == 0) {
	diff = secondaryDiff;
    }
    return diff;
}







>




|
>









|



|

















|



|
|












|





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

>
|
|
|




|
>
|









<
<
<
<
<






2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985





2986
2987
2988
2989
2990
2991
 *----------------------------------------------------------------------
 */

static int
DictionaryCompare(left, right)
    char *left, *right;          /* The strings to compare */
{
    Tcl_UniChar uniLeft, uniRight;
    int diff, zeros;
    int secondaryDiff = 0;

    while (1) {
	if (isdigit(UCHAR(*right)) /* INTL: digit */
		&& isdigit(UCHAR(*left))) { /* INTL: digit */
	    /*
	     * There are decimal numbers embedded in the two
	     * strings.  Compare them as numbers, rather than
	     * strings.  If one number has more leading zeros than
	     * the other, the number with more leading zeros sorts
	     * later, but only as a secondary choice.
	     */

	    zeros = 0;
	    while ((*right == '0') && (isdigit(UCHAR(right[1])))) {
		right++;
		zeros--;
	    }
	    while ((*left == '0') && (isdigit(UCHAR(left[1])))) {
		left++;
		zeros++;
	    }
	    if (secondaryDiff == 0) {
		secondaryDiff = zeros;
	    }

	    /*
	     * The code below compares the numbers in the two
	     * strings without ever converting them to integers.  It
	     * does this by first comparing the lengths of the
	     * numbers and then comparing the digit values.
	     */

	    diff = 0;
	    while (1) {
		if (diff == 0) {
		    diff = UCHAR(*left) - UCHAR(*right);
		}
		right++;
		left++;
		if (!isdigit(UCHAR(*right))) { /* INTL: digit */
		    if (isdigit(UCHAR(*left))) { /* INTL: digit */
			return 1;
		    } else {
			/*
			 * The two numbers have the same length. See
			 * if their values are different.
			 */

			if (diff != 0) {
			    return diff;
			}
			break;
		    }
		} else if (!isdigit(UCHAR(*left))) { /* INTL: digit */
		    return -1;
		}
	    }
	    continue;
	}

	/*
	 * Convert character to Unicode for comparison purposes.  If either
	 * string is at the terminating null, do a byte-wise comparison and
	 * bail out immediately.
	 */

	if ((*left != '\0') && (*right != '\0')) {
	    left += Tcl_UtfToUniChar(left, &uniLeft);
	    right += Tcl_UtfToUniChar(right, &uniRight);
	} else {
	    diff = UCHAR(*left) - UCHAR(*right);
	    break;
	}

        diff = uniLeft - uniRight;
        if (diff) {
	    if (Tcl_UniCharIsUpper(uniLeft) &&
		    Tcl_UniCharIsLower(uniRight)) {
		diff = Tcl_UniCharToLower(uniLeft) - uniRight;
		if (diff) {
		    return diff;
                } else if (secondaryDiff == 0) {
		    secondaryDiff = -1;
                }
	    } else if (Tcl_UniCharIsUpper(uniRight)
		    && Tcl_UniCharIsLower(uniLeft)) {
                diff = uniLeft - Tcl_UniCharToLower(uniRight);
                if (diff) {
		    return diff;
                } else if (secondaryDiff == 0) {
		    secondaryDiff = 1;
                }
            } else {
                return diff;
            }
        }





    }
    if (diff == 0) {
	diff = secondaryDiff;
    }
    return diff;
}

Changes to generic/tclCmdMZ.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120











121
122



123
124

125

126






127
128
129
130
131
132


133
134
135
136
137
138
139

140
141
142
143
144

145
146
147


148


149

150



151
152
153
154
155



156
157
158

159
160
161
162


163
164
165
166
167
168
169
170
171
172
173



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191


192
193
194
195
196
197























198
199
200
201
202
203
204


205


206

207
208
209
210
211
212
213
214
215
216


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238

239
240
241









242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

300

301
302

303
304
305



306
307

308
309


310
311
312
313
314
315
316
317
318



319
320
321
322
323
324
325
326
327
328

329
330

331
332

333
334
335

336




337

338
339
340
341
342
343
344
345




346




347




348


349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372

373

374
375
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453


454

455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
/* 
 * tclCmdMZ.c --
 *
 *	This file contains the top-level command routines for most of
 *	the Tcl built-in commands whose names begin with the letters
 *	M to Z.  It contains only commands in the generic core (i.e.
 *	those that don't depend much upon UNIX facilities).
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclCmdMZ.c 1.104 97/10/31 13:06:19
 */

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


















/*
 * Structure used to hold information about variable traces:
 */

typedef struct {
    int flags;			/* Operations for which Tcl command is
				 * to be invoked. */
    char *errMsg;		/* Error message returned from Tcl command,
				 * or NULL.  Malloc'ed. */
    int length;			/* Number of non-NULL chars. in command. */
    char command[4];		/* Space for Tcl command to invoke.  Actual
				 * size will be as large as necessary to
				 * hold command.  This field must be the
				 * last in the structure, so that it can
				 * be larger than 4 bytes. */
} TraceVarInfo;

/*
 * Forward declarations for procedures defined in this file:
 */

static char *		TraceVarProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, char *name1, char *name2,
			    int flags));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PwdCmd --
 *
 *	This procedure is invoked to process the "pwd" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_PwdCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    char *dirName;

    if (argc != 1) {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], "\"", (char *) NULL);
	return TCL_ERROR;
    }

    dirName = TclGetCwd(interp);
    if (dirName == NULL) {
	return TCL_ERROR;
    }
    Tcl_SetResult(interp, dirName, TCL_VOLATILE);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegexpCmd --
 *
 *	This procedure is invoked to process the "regexp" Tcl command.
 *	See the user documentation for details on what it does.


 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_RegexpCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    int noCase = 0;
    int indices = 0;
    Tcl_RegExp regExpr;
    char **argPtr, *string, *pattern, *start, *end;
    int match = 0;			/* Initialization needed only to
					 * prevent compiler warning. */
    int i;
    Tcl_DString stringDString, patternDString;












    if (argc < 3) {



	wrongNumArgs:
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],

		" ?switches? exp string ?matchVar? ?subMatchVar ",

		"subMatchVar ...?\"", (char *) NULL);






	return TCL_ERROR;
    }
    argPtr = argv+1;
    argc--;
    while ((argc > 0) && (argPtr[0][0] == '-')) {
	if (strcmp(argPtr[0], "-indices") == 0) {


	    indices = 1;
	} else if (strcmp(argPtr[0], "-nocase") == 0) {
	    noCase = 1;
	} else if (strcmp(argPtr[0], "--") == 0) {
	    argPtr++;
	    argc--;
	    break;

	} else {
	    Tcl_AppendResult(interp, "bad switch \"", argPtr[0],
		    "\": must be -indices, -nocase, or --", (char *) NULL);
	    return TCL_ERROR;
	}

	argPtr++;
	argc--;
    }


    if (argc < 2) {


	goto wrongNumArgs;

    }




    /*
     * Convert the string and pattern to lower case, if desired, and
     * perform the matching operation.
     */




    if (noCase) {
	register char *p;


	Tcl_DStringInit(&patternDString);
	Tcl_DStringAppend(&patternDString, argPtr[0], -1);
	pattern = Tcl_DStringValue(&patternDString);


	for (p = pattern; *p != 0; p++) {
	    if (isupper(UCHAR(*p))) {
		*p = (char)tolower(UCHAR(*p));
	    }
	}
	Tcl_DStringInit(&stringDString);
	Tcl_DStringAppend(&stringDString, argPtr[1], -1);
	string = Tcl_DStringValue(&stringDString);
	for (p = string; *p != 0; p++) {
	    if (isupper(UCHAR(*p))) {
		*p = (char)tolower(UCHAR(*p));



	    }
	}
    } else {
	pattern = argPtr[0];
	string = argPtr[1];
    }
    regExpr = Tcl_RegExpCompile(interp, pattern);
    if (regExpr != NULL) {
	match = Tcl_RegExpExec(interp, regExpr, string, string);
    }
    if (noCase) {
	Tcl_DStringFree(&stringDString);
	Tcl_DStringFree(&patternDString);
    }
    if (regExpr == NULL) {
	return TCL_ERROR;
    }
    if (match < 0) {


	return TCL_ERROR;
    }
    if (!match) {
	Tcl_SetResult(interp, "0", TCL_STATIC);
	return TCL_OK;
    }
























    /*
     * If additional variable names have been specified, return
     * index information in those variables.
     */

    argc -= 2;


    for (i = 0; i < argc; i++) {


	char *result, info[50];


	Tcl_RegExpRange(regExpr, i, &start, &end);
	if (start == NULL) {
	    if (indices) {
		result = Tcl_SetVar(interp, argPtr[i+2], "-1 -1", 0);
	    } else {
		result = Tcl_SetVar(interp, argPtr[i+2], "", 0);
	    }
	} else {
	    if (indices) {


		sprintf(info, "%d %d", (int)(start - string),
			(int)(end - string - 1));
		result = Tcl_SetVar(interp, argPtr[i+2], info, 0);
	    } else {
		char savedChar, *first, *last;

		first = argPtr[1] + (start - string);
		last = argPtr[1] + (end - string);
		if (first == last) { /* don't modify argument */
		    result = Tcl_SetVar(interp, argPtr[i+2], "", 0);
		} else {
		    savedChar = *last;
		    *last = 0;
		    result = Tcl_SetVar(interp, argPtr[i+2], first, 0);
		    *last = savedChar;

		}
	    }
	}
	if (result == NULL) {
	    Tcl_AppendResult(interp, "couldn't set variable \"",
		    argPtr[i+2], "\"", (char *) NULL);
	    return TCL_ERROR;

	}
    }
    Tcl_SetResult(interp, "1", TCL_STATIC);









    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegsubCmd --
 *
 *	This procedure is invoked to process the "regsub" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_RegsubCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    int noCase = 0, all = 0;
    Tcl_RegExp regExpr;
    char *string, *pattern, *p, *firstChar, **argPtr;
    int match, code, numMatches;
    char *start, *end, *subStart, *subEnd;
    register char *src, c;
    Tcl_DString stringDString, patternDString, resultDString;

    if (argc < 5) {
	wrongNumArgs:
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" ?switches? exp string subSpec varName\"", (char *) NULL);
	return TCL_ERROR;

    }
    argPtr = argv+1;
    argc--;
    while (argPtr[0][0] == '-') {
	if (strcmp(argPtr[0], "-nocase") == 0) {
	    noCase = 1;
	} else if (strcmp(argPtr[0], "-all") == 0) {
	    all = 1;
	} else if (strcmp(argPtr[0], "--") == 0) {
	    argPtr++;
	    argc--;
	    break;
	} else {
	    Tcl_AppendResult(interp, "bad switch \"", argPtr[0],
		    "\": must be -all, -nocase, or --", (char *) NULL);
	    return TCL_ERROR;
	}

	argPtr++;

	argc--;
    }

    if (argc != 4) {
	goto wrongNumArgs;
    }




    /*

     * Convert the string and pattern to lower case, if desired.
     */



    if (noCase) {
	Tcl_DStringInit(&patternDString);
	Tcl_DStringAppend(&patternDString, argPtr[0], -1);
	pattern = Tcl_DStringValue(&patternDString);
	for (p = pattern; *p != 0; p++) {
	    if (isupper(UCHAR(*p))) {
		*p = (char)tolower(UCHAR(*p));
	    }



	}
	Tcl_DStringInit(&stringDString);
	Tcl_DStringAppend(&stringDString, argPtr[1], -1);
	string = Tcl_DStringValue(&stringDString);
	for (p = string; *p != 0; p++) {
	    if (isupper(UCHAR(*p))) {
		*p = (char)tolower(UCHAR(*p));
	    }
	}
    } else {

	pattern = argPtr[0];
	string = argPtr[1];

    }
    Tcl_DStringInit(&resultDString);

    regExpr = Tcl_RegExpCompile(interp, pattern);
    if (regExpr == NULL) {
	code = TCL_ERROR;

	goto done;




    }


    /*
     * The following loop is to handle multiple matches within the
     * same source string;  each iteration handles one match and its
     * corresponding substitution.  If "-all" hasn't been specified
     * then the loop body only gets executed once.
     */





    numMatches = 0;




    for (p = string; *p != 0; ) {




	match = Tcl_RegExpExec(interp, regExpr, p, string);


	if (match < 0) {
	    code = TCL_ERROR;
	    goto done;
	}
	if (!match) {
	    break;
	}
	numMatches += 1;

	/*
	 * Copy the portion of the source string before the match to the
	 * result variable.
	 */

	Tcl_RegExpRange(regExpr, 0, &start, &end);
	Tcl_DStringAppend(&resultDString, argPtr[1] + (p - string), start - p);
    
	/*
	 * Append the subSpec argument to the variable, making appropriate
	 * substitutions.  This code is a bit hairy because of the backslash
	 * conventions and because the code saves up ranges of characters in
	 * subSpec to reduce the number of calls to Tcl_SetVar.
	 */
    

	for (src = firstChar = argPtr[2], c = *src; c != 0; src++, c = *src) {

	    int index;
    
	    if (c == '&') {
		index = 0;
	    } else if (c == '\\') {
		c = src[1];
		if ((c >= '0') && (c <= '9')) {
		    index = c - '0';
		} else if ((c == '\\') || (c == '&')) {

		    *src = c;
		    src[1] = 0;
		    Tcl_DStringAppend(&resultDString, firstChar, -1);
		    *src = '\\';
		    src[1] = c;
		    firstChar = src+2;
		    src++;
		    continue;
		} else {
		    continue;
		}
	    } else {
		continue;
	    }
	    if (firstChar != src) {
		c = *src;
		*src = 0;
		Tcl_DStringAppend(&resultDString, firstChar, -1);
		*src = c;
	    }
	    Tcl_RegExpRange(regExpr, index, &subStart, &subEnd);
	    if ((subStart != NULL) && (subEnd != NULL)) {
		char *first, *last, saved;
    
		first = argPtr[1] + (subStart - string);
		last = argPtr[1] + (subEnd - string);
		saved = *last;
		*last = 0;
		Tcl_DStringAppend(&resultDString, first, -1);
		*last = saved;
	    }
	    if (*src == '\\') {
		src++;
	    }
	    firstChar = src+1;
	}
	if (firstChar != src) {
	    Tcl_DStringAppend(&resultDString, firstChar, -1);
	}
	if (end == p) {

	    /*
	     * Always consume at least one character of the input string
	     * in order to prevent infinite loops.
	     */

	    Tcl_DStringAppend(&resultDString, argPtr[1] + (p - string), 1);
	    p = end + 1;
	} else {
	    p = end;
	}

	if (!all) {
	    break;
	}
    }

    /*
     * Copy the portion of the source string after the last match to the
     * result variable.
     */

    if ((*p != 0) || (numMatches == 0)) {
	Tcl_DStringAppend(&resultDString, argPtr[1] + (p - string), -1);
    }
    if (Tcl_SetVar(interp, argPtr[3], Tcl_DStringValue(&resultDString), 0)
	     == NULL) {
	Tcl_AppendResult(interp,
		"couldn't set variable \"", argPtr[3], "\"",
		(char *) NULL);
	code = TCL_ERROR;
    } else {


	char buf[40];

	
	TclFormatInt(buf, numMatches);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	code = TCL_OK;
    }

    done:
    if (noCase) {
	Tcl_DStringFree(&stringDString);
	Tcl_DStringFree(&patternDString);
    }
    Tcl_DStringFree(&resultDString);
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RenameObjCmd --
 *










>




|





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










|


















|















|


|
|

|

|
|
<



|
<


|






|


|
>
>












|


|
|

|
|

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

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



|
>
>
|
|
<
<


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






|
>
>
|
>
>
|
>

|
|

|

|



>
>
|
<
|

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

|
|
>


|
>
>
>
>
>
>
>
>
>
|





|















|


|
|

|

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

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

|
>
|

|
>
|
>
>
>
>
|
>








>
>
>
>

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

|


|


|






|
|







|
>
|
>









>
|
<
|
<
<
|









<
<
|
<

|
|
<
|
<
<
<
<
|
<




|


|

|
<





|
|
<
<

>










|
|

|
|
|
<

|

>
>
|
>

|
<
<



<
|
<
<
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134



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

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164




165
166
167





168
169
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189




190
191
192
193
194
195
196
197



198
199



200


201


202

203
204
205
206


207
208
209
210







211
212
213
214
215
216
217
218


219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

271
272

273
274


275





276
277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

332



333
334
335



336

337








338
339
340
341

342
343
344
345
346
347
348
349
350

351
352

353
354
355
356




357
358
359
360
361
362
363






364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

448


449
450
451
452
453
454
455
456
457
458


459

460
461
462

463




464

465
466
467
468
469
470
471
472
473
474

475
476
477
478
479
480
481


482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499

500
501
502
503
504
505
506
507
508


509
510
511

512


513
514
515
516
517
518
519
520
521
/* 
 * tclCmdMZ.c --
 *
 *	This file contains the top-level command routines for most of
 *	the Tcl built-in commands whose names begin with the letters
 *	M to Z.  It contains only commands in the generic core (i.e.
 *	those that don't depend much upon UNIX facilities).
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * Copyright (c) 1994-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: tclCmdMZ.c,v 1.1.2.12 1999/04/06 04:27:01 rjohnson Exp $
 */

#include "tclInt.h"
#include "tclPort.h"
#include "tclCompile.h"
#include "tclRegexp.h"

/*
 * Flag values used by Tcl_ScanObjCmd.
 */

#define SCAN_NOSKIP	0x1		  /* Don't skip blanks. */
#define SCAN_SUPPRESS	0x2		  /* Suppress assignment. */
#define SCAN_UNSIGNED	0x4		  /* Read an unsigned value. */
#define SCAN_WIDTH	0x8		  /* A width value was supplied. */

#define SCAN_SIGNOK	0x10		  /* A +/- character is allowed. */
#define SCAN_NODIGITS	0x20		  /* No digits have been scanned. */
#define SCAN_NOZERO	0x40		  /* No zero digits have been scanned. */
#define SCAN_XOK	0x80		  /* An 'x' is allowed. */
#define SCAN_PTOK	0x100		  /* Decimal point is allowed. */
#define SCAN_EXPOK	0x200		  /* An exponent is allowed. */

/*
 * Structure used to hold information about variable traces:
 */

typedef struct {
    int flags;			/* Operations for which Tcl command is
				 * to be invoked. */
    char *errMsg;		/* Error message returned from Tcl command,
				 * or NULL.  Malloc'ed. */
    size_t length;		/* Number of non-NULL chars. in command. */
    char command[4];		/* Space for Tcl command to invoke.  Actual
				 * size will be as large as necessary to
				 * hold command.  This field must be the
				 * last in the structure, so that it can
				 * be larger than 4 bytes. */
} TraceVarInfo;

/*
 * Forward declarations for procedures defined in this file:
 */

static char *		TraceVarProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, char *name1, char *name2,
			    int flags));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PwdObjCmd --
 *
 *	This procedure is invoked to process the "pwd" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_PwdObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_DString ds;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);

	return TCL_ERROR;
    }

    if (Tcl_GetCwd(interp, &ds) == NULL) {

	return TCL_ERROR;
    }
    Tcl_DStringResult(interp, &ds);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegexpObjCmd --
 *
 *	This procedure is invoked to process the "regexp" Tcl command.
 *	See the user documentation for details on what it does.  The
 *	REGEXP_TEST stuff is to minimize code differences between this
 *	and the "testregexp" command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_RegexpObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int i, result, indices, stringLength, wLen, match, about;
    int cflags, eflags;
    Tcl_RegExp regExpr;
    char *string;



    Tcl_DString stringBuffer, valueBuffer;
    Tcl_UniChar *wStart;
    static char *options[] = {
	"-indices",	"-nocase",	"-about",	"-expanded",
	"-line",	"-linestop",	"-lineanchor",
	"--",		(char *) NULL
    };
    enum options {
	REGEXP_INDICES, REGEXP_NOCASE,	REGEXP_ABOUT,	REGEXP_EXPANDED,
	REGEXP_LINE,	REGEXP_LINESTOP, REGEXP_LINEANCHOR,
	REGEXP_LAST
    };


    indices = 0;
    about = 0;
    cflags = REG_ADVANCED;
    eflags = 0;
    
    for (i = 1; i < objc; i++) {
	char *name;
	int index;

	name = Tcl_GetString(objv[i]);
	if (name[0] != '-') {
	    break;
	}
	if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", TCL_EXACT,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}




	switch ((enum options) index) {
	    case REGEXP_INDICES: {
		indices = 1;





		break;
	    }
	    case REGEXP_NOCASE: {

		cflags |= REG_ICASE;
		break;
	    }
	    case REGEXP_ABOUT: {
		about = 1;
		break;
	    }
	    case REGEXP_EXPANDED: {
		cflags |= REG_EXPANDED;
		break;
	    }
	    case REGEXP_LINE: {
		cflags |= REG_NEWLINE;
		break;
	    }
	    case REGEXP_LINESTOP: {
		cflags |= REG_NLSTOP;
		break;
	    }




	    case REGEXP_LINEANCHOR: {
		cflags |= REG_NLANCH;
		break;
	    }
	    case REGEXP_LAST: {
		i++;
		goto endOfForLoop;
	    }



	}
    }






    endOfForLoop:


    if (objc - i < 2 - about) {

	Tcl_WrongNumArgs(interp, 1, objv,
		"?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?");
	return TCL_ERROR;
    }


    objc -= i;
    objv += i;

    regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);







    if (regExpr == NULL) {
	return TCL_ERROR;
    }

    if (about) {
	if (TclRegAbout(interp, regExpr) < 0) {
	    return TCL_ERROR;
	}


	return TCL_OK;
    }

    result = TCL_OK;
    string = Tcl_GetStringFromObj(objv[1], &stringLength);

    Tcl_DStringInit(&valueBuffer);
    
    Tcl_DStringInit(&stringBuffer);
    wStart = Tcl_UtfToUniCharDString(string, stringLength, &stringBuffer);
    wLen = Tcl_DStringLength(&stringBuffer) / sizeof(Tcl_UniChar);

    match = TclRegExpExecUniChar(interp, regExpr, wStart, wLen, objc-2, eflags);
    if (match < 0) {
	result = TCL_ERROR;
	goto done;
    }
    if (match == 0) {
	/*
	 * Set the interpreter's object result to an integer object w/ value 0. 
	 */
	
	Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
	goto done;
    }

    /*
     * If additional variable names have been specified, return
     * index information in those variables.
     */

    objc -= 2;
    objv += 2;

    for (i = 0; i < objc; i++) {
	char *varName, *value;
	int start, end;
	
	varName = Tcl_GetString(objv[i]);

	TclRegExpRangeUniChar(regExpr, i, &start, &end);
	if (start < 0) {
	    if (indices) {
		value = Tcl_SetVar(interp, varName, "-1 -1", 0);
	    } else {
		value = Tcl_SetVar(interp, varName, "", 0);
	    }
	} else {
	    if (indices) {
		char info[TCL_INTEGER_SPACE * 2];
		
		sprintf(info, "%d %d", start, end - 1);

		value = Tcl_SetVar(interp, varName, info, 0);
	    } else {

		value = Tcl_UniCharToUtfDString(wStart + start, end - start,
			&valueBuffer);


		value = Tcl_SetVar(interp, varName, value, 0);





		Tcl_DStringSetLength(&valueBuffer, 0);
	    }
	}

	if (value == NULL) {
	    Tcl_AppendResult(interp, "couldn't set variable \"",
		    varName, "\"", (char *) NULL);
	    result = TCL_ERROR;
	    goto done;
	}
    }

    /*
     * Set the interpreter's object result to an integer object w/ value 1. 
     */
	
    Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);

    done:
    Tcl_DStringFree(&stringBuffer);
    Tcl_DStringFree(&valueBuffer);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegsubObjCmd --
 *
 *	This procedure is invoked to process the "regsub" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_RegsubObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int i, result, flags, all, stringLength, numMatches;
    Tcl_RegExp regExpr;
    Tcl_DString resultBuffer, stringBuffer;
    CONST Tcl_UniChar *w, *wStart, *wEnd;
    char *string, *subspec, *varname;
    static char *options[] = {
	"-all",		"-nocase",	"--",		NULL
    };

    enum options {



	REGSUB_ALL,	REGSUB_NOCASE,	REGSUB_LAST
    };




    flags = 0;

    all = 0;









    for (i = 1; i < objc; i++) {
	char *name;
	int index;

	
	name = Tcl_GetString(objv[i]);
	if (name[0] != '-') {
	    break;
	}
	if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", TCL_EXACT,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}

	switch ((enum options) index) {
	    case REGSUB_ALL: {

		all = 1;
		break;
	    }
	    case REGSUB_NOCASE: {




		flags |= REG_ICASE;
		break;
	    }
	    case REGSUB_LAST: {
		i++;
		goto endOfForLoop;
	    }






	}
    }
    endOfForLoop:
    if (objc - i != 4) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?switches? exp string subSpec varName");
	return TCL_ERROR;
    }

    objv += i;
    regExpr = Tcl_GetRegExpFromObj(interp, objv[0], flags | REG_ADVANCED);
    if (regExpr == NULL) {
	return TCL_ERROR;
    }

    result = TCL_OK;
    string = Tcl_GetStringFromObj(objv[1], &stringLength);
    subspec = Tcl_GetString(objv[2]);
    varname = Tcl_GetString(objv[3]);

    Tcl_DStringInit(&resultBuffer);

    /*
     * The following loop is to handle multiple matches within the
     * same source string;  each iteration handles one match and its
     * corresponding substitution.  If "-all" hasn't been specified
     * then the loop body only gets executed once.
     */

    Tcl_DStringInit(&stringBuffer);
    wStart = Tcl_UtfToUniCharDString(string, stringLength, &stringBuffer);
    wEnd = wStart + Tcl_DStringLength(&stringBuffer) / sizeof(Tcl_UniChar);

    numMatches = 0;
    for (w = wStart; w < wEnd; ) {
	int start, end, subStart, subEnd, match;
	char *src, *firstChar;
	char c;

	/*
	 * The flags argument is set if string is part of a larger string,
	 * so that "^" won't match.
	 */

	match = TclRegExpExecUniChar(interp, regExpr, w, wEnd - w, 10,
		((w > wStart) ? REG_NOTBOL : 0));
	if (match < 0) {
	    result = TCL_ERROR;
	    goto done;
	}
	if (match == 0) {
	    break;
	}
	numMatches++;

	/*
	 * Copy the portion of the source string before the match to the
	 * result variable.
	 */

	TclRegExpRangeUniChar(regExpr, 0, &start, &end);
	Tcl_UniCharToUtfDString(w, start, &resultBuffer);
    
	/*
	 * Append the subSpec argument to the variable, making appropriate
	 * substitutions.  This code is a bit hairy because of the backslash
	 * conventions and because the code saves up ranges of characters in
	 * subSpec to reduce the number of calls to Tcl_SetVar.
	 */

	src = subspec;
	firstChar = subspec;
	for (c = *src; c != '\0'; src++, c = *src) {
	    int index;
    
	    if (c == '&') {
		index = 0;
	    } else if (c == '\\') {
		c = src[1];
		if ((c >= '0') && (c <= '9')) {
		    index = c - '0';
		} else if ((c == '\\') || (c == '&')) {
		    Tcl_DStringAppend(&resultBuffer, firstChar,
			    src - firstChar);

		    Tcl_DStringAppend(&resultBuffer, &c, 1);


		    firstChar = src + 2;
		    src++;
		    continue;
		} else {
		    continue;
		}
	    } else {
		continue;
	    }
	    if (firstChar != src) {


		Tcl_DStringAppend(&resultBuffer, firstChar, src - firstChar);

	    }
	    TclRegExpRangeUniChar(regExpr, index, &subStart, &subEnd);
	    if ((subStart >= 0) && (subEnd >= 0)) {

		Tcl_UniCharToUtfDString(w + subStart, subEnd - subStart,




			&resultBuffer);

	    }
	    if (*src == '\\') {
		src++;
	    }
	    firstChar = src + 1;
	}
	if (firstChar != src) {
	    Tcl_DStringAppend(&resultBuffer, firstChar, src - firstChar);
	}
	if (end == 0) {

	    /*
	     * Always consume at least one character of the input string
	     * in order to prevent infinite loops.
	     */

	    Tcl_UniCharToUtfDString(w, 1, &resultBuffer);
	    w++;


	}
	w += end;
	if (!all) {
	    break;
	}
    }

    /*
     * Copy the portion of the source string after the last match to the
     * result variable.
     */

    if ((w < wEnd) || (numMatches == 0)) {
	Tcl_UniCharToUtfDString(w, wEnd - w, &resultBuffer);
    }
    if (Tcl_SetVar(interp, varname, Tcl_DStringValue(&resultBuffer),
	    0) == NULL) {
	Tcl_AppendResult(interp, "couldn't set variable \"", varname, "\"",

		(char *) NULL);
	result = TCL_ERROR;
    } else {
	/*
	 * Set the interpreter's object result to an integer object holding the
	 * number of matches. 
	 */
	
	Tcl_SetIntObj(Tcl_GetObjResult(interp), numMatches);


    }

    done:

    Tcl_DStringFree(&stringBuffer);


    Tcl_DStringFree(&resultBuffer);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RenameObjCmd --
 *
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
    char *oldName, *newName;
    
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "oldName newName");
	return TCL_ERROR;
    }

    oldName = Tcl_GetStringFromObj(objv[1], (int *) NULL);
    newName = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    return TclRenameCommand(interp, oldName, newName);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ReturnObjCmd --







|
|







542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
    char *oldName, *newName;
    
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "oldName newName");
	return TCL_ERROR;
    }

    oldName = Tcl_GetString(objv[1]);
    newName = Tcl_GetString(objv[2]);
    return TclRenameCommand(interp, oldName, newName);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ReturnObjCmd --
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
	iPtr->errorInfo = NULL;
    }
    if (iPtr->errorCode != NULL) {
	ckfree(iPtr->errorCode);
	iPtr->errorCode = NULL;
    }
    code = TCL_OK;

   /*
    * THIS FAILS IF AN OBJECT CONTAINS AN EMBEDDED NULL.
    */
    
    for (objv++, objc--;  objc > 1;  objv += 2, objc -= 2) {
	char *option = Tcl_GetStringFromObj(objv[0], &optionLen);
	char *arg = Tcl_GetStringFromObj(objv[1], &argLen);
    	
	if (strcmp(option, "-code") == 0) {
	    register int c = arg[0];







<
<
<
<







584
585
586
587
588
589
590




591
592
593
594
595
596
597
	iPtr->errorInfo = NULL;
    }
    if (iPtr->errorCode != NULL) {
	ckfree(iPtr->errorCode);
	iPtr->errorCode = NULL;
    }
    code = TCL_OK;




    
    for (objv++, objc--;  objc > 1;  objv += 2, objc -= 2) {
	char *option = Tcl_GetStringFromObj(objv[0], &optionLen);
	char *arg = Tcl_GetStringFromObj(objv[1], &argLen);
    	
	if (strcmp(option, "-code") == 0) {
	    register int c = arg[0];
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
	    } else {
		result = Tcl_GetIntFromObj((Tcl_Interp *) NULL, objv[1],
		        &code);
		if (result != TCL_OK) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			    "bad completion code \"",
			    Tcl_GetStringFromObj(objv[1], (int *) NULL),
			    "\": must be ok, error, return, break, ",
			    "continue, or an integer", (char *) NULL);
		    return result;
		}
	    }
	} else if (strcmp(option, "-errorinfo") == 0) {
	    iPtr->errorInfo =







|







608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
	    } else {
		result = Tcl_GetIntFromObj((Tcl_Interp *) NULL, objv[1],
		        &code);
		if (result != TCL_OK) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			    "bad completion code \"",
			    Tcl_GetString(objv[1]),
			    "\": must be ok, error, return, break, ",
			    "continue, or an integer", (char *) NULL);
		    return result;
		}
	    }
	} else if (strcmp(option, "-errorinfo") == 0) {
	    iPtr->errorInfo =
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
    iPtr->returnCode = code;
    return TCL_RETURN;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ScanCmd --
 *
 *	This procedure is invoked to process the "scan" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_ScanCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
#   define MAX_FIELDS 20
    typedef struct {
	char fmt;			/* Format for field. */
	int size;			/* How many bytes to allow for
					 * field. */
	char *location;			/* Where field will be stored. */
    } Field;
    Field fields[MAX_FIELDS];		/* Info about all the fields in the
					 * format string. */
    register Field *curField;
    int numFields = 0;			/* Number of fields actually
					 * specified. */
    int suppress;			/* Current field is assignment-
					 * suppressed. */
    int totalSize = 0;			/* Number of bytes needed to store
					 * all results combined. */
    char *results;			/* Where scanned output goes.
					 * Malloced; NULL means not allocated
					 * yet. */
    int numScanned;			/* sscanf's result. */
    register char *fmt;
    int i, widthSpecified, length, code;
    char buf[40];

    /*
     * The variables below are used to hold a copy of the format
     * string, so that we can replace format specifiers like "%f"
     * and "%F" with specifiers like "%lf"
     */

#   define STATIC_SIZE 5
    char copyBuf[STATIC_SIZE], *fmtCopy;
    register char *dst;

    if (argc < 3) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" string format ?varName varName ...?\"", (char *) NULL);
	return TCL_ERROR;
    }

    /*
     * This procedure operates in four stages:
     * 1. Scan the format string, collecting information about each field.
     * 2. Allocate an array to hold all of the scanned fields.
     * 3. Call sscanf to do all the dirty work, and have it store the
     *    parsed fields in the array.
     * 4. Pick off the fields from the array and assign them to variables.
     */

    code = TCL_OK;
    results = NULL;
    length = strlen(argv[2]) * 2 + 1;
    if (length < STATIC_SIZE) {
	fmtCopy = copyBuf;
    } else {
	fmtCopy = (char *) ckalloc((unsigned) length);
    }
    dst = fmtCopy;
    for (fmt = argv[2]; *fmt != 0; fmt++) {
	*dst = *fmt;
	dst++;
	if (*fmt != '%') {
	    continue;
	}
	fmt++;
	if (*fmt == '%') {
	    *dst = *fmt;
	    dst++;
	    continue;
	}
	if (*fmt == '*') {
	    suppress = 1;
	    *dst = *fmt;
	    dst++;
	    fmt++;
	} else {
	    suppress = 0;
	}
	widthSpecified = 0;
	while (isdigit(UCHAR(*fmt))) {
	    widthSpecified = 1;
	    *dst = *fmt;
	    dst++;
	    fmt++;
	}
	if ((*fmt == 'l') || (*fmt == 'h') || (*fmt == 'L')) {
	    fmt++;
	}
	*dst = *fmt;
	dst++;
	if (suppress) {
	    continue;
	}
	if (numFields == MAX_FIELDS) {
	    Tcl_SetResult(interp, "too many fields to scan", TCL_STATIC);
	    code = TCL_ERROR;
	    goto done;
	}
	curField = &fields[numFields];
	numFields++;
	switch (*fmt) {
	    case 'd':
	    case 'i':
	    case 'o':
	    case 'x':
		curField->fmt = 'd';
		curField->size = sizeof(int);
		break;

	    case 'u':
		curField->fmt = 'u';
		curField->size = sizeof(int);
		break;

	    case 's':
		curField->fmt = 's';
		curField->size = strlen(argv[1]) + 1;
		break;

	    case 'c':
                if (widthSpecified) {
		    Tcl_SetResult(interp,
		            "field width may not be specified in %c conversion",
			    TCL_STATIC);
		    code = TCL_ERROR;
		    goto done;
                }
		curField->fmt = 'c';
		curField->size = sizeof(int);
		break;

	    case 'e':
	    case 'f':
	    case 'g':
		dst[-1] = 'l';
		dst[0] = 'f';
		dst++;
		curField->fmt = 'f';
		curField->size = sizeof(double);
		break;

	    case '[':
		curField->fmt = 's';
		curField->size = strlen(argv[1]) + 1;
		do {
		    fmt++;
		    if (*fmt == 0) {
			Tcl_SetResult(interp,
			        "unmatched [ in format string", TCL_STATIC);
			code = TCL_ERROR;
			goto done;
		    }
		    *dst = *fmt;
		    dst++;
		} while (*fmt != ']');
		break;

	    default:
		{
		    char buf[50];

		    sprintf(buf, "bad scan conversion character \"%c\"", *fmt);
		    Tcl_SetResult(interp, buf, TCL_VOLATILE);
		    code = TCL_ERROR;
		    goto done;
		}
	}
	curField->size = TCL_ALIGN(curField->size);
	totalSize += curField->size;
    }
    *dst = 0;

    if (numFields != (argc-3)) {
	Tcl_SetResult(interp,
		"different numbers of variable names and field specifiers",
		TCL_STATIC);
	code = TCL_ERROR;
	goto done;
    }

    /*
     * Step 2:
     */

    results = (char *) ckalloc((unsigned) totalSize);
    for (i = 0, totalSize = 0, curField = fields;
	    i < numFields; i++, curField++) {
	curField->location = results + totalSize;
	totalSize += curField->size;
    }

    /*
     * Fill in the remaining fields with NULL;  the only purpose of
     * this is to keep some memory analyzers, like Purify, from
     * complaining.
     */

    for ( ; i < MAX_FIELDS; i++, curField++) {
	curField->location = NULL;
    }

    /*
     * Step 3:
     */

    numScanned = sscanf(argv[1], fmtCopy,
	    fields[0].location, fields[1].location, fields[2].location,
	    fields[3].location, fields[4].location, fields[5].location,
	    fields[6].location, fields[7].location, fields[8].location,
	    fields[9].location, fields[10].location, fields[11].location,
	    fields[12].location, fields[13].location, fields[14].location,
	    fields[15].location, fields[16].location, fields[17].location,
	    fields[18].location, fields[19].location);

    /*
     * Step 4:
     */

    if (numScanned < numFields) {
	numFields = numScanned;
    }
    for (i = 0, curField = fields; i < numFields; i++, curField++) {
	switch (curField->fmt) {
	    char string[TCL_DOUBLE_SPACE];

	    case 'd':
		TclFormatInt(string, *((int *) curField->location));
		if (Tcl_SetVar(interp, argv[i+3], string, 0) == NULL) {
		    storeError:
		    Tcl_AppendResult(interp,
			    "couldn't set variable \"", argv[i+3], "\"",
			    (char *) NULL);
		    code = TCL_ERROR;
		    goto done;
		}
		break;

	    case 'u':
		sprintf(string, "%u", *((int *) curField->location));
		if (Tcl_SetVar(interp, argv[i+3], string, 0) == NULL) {
		    goto storeError;
		}
		break;

	    case 'c':
		TclFormatInt(string, *((char *) curField->location) & 0xff);
		if (Tcl_SetVar(interp, argv[i+3], string, 0) == NULL) {
		    goto storeError;
		}
		break;

	    case 's':
		if (Tcl_SetVar(interp, argv[i+3], curField->location, 0)
			== NULL) {
		    goto storeError;
		}
		break;

	    case 'f':
		Tcl_PrintDouble((Tcl_Interp *) NULL,
			*((double *) curField->location), string);
		if (Tcl_SetVar(interp, argv[i+3], string, 0) == NULL) {
		    goto storeError;
		}
		break;
	}
    }
    TclFormatInt(buf, numScanned);
    Tcl_SetResult(interp, buf, TCL_VOLATILE);
    done:
    if (results != NULL) {
	ckfree(results);
    }
    if (fmtCopy != copyBuf) {
	ckfree(fmtCopy);
    }
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SourceObjCmd --
 *
 *	This procedure is invoked to process the "source" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl object result.







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







646
647
648
649
650
651
652
















































































































































































































































































































653
654
655
656
657
658
659
    iPtr->returnCode = code;
    return TCL_RETURN;
}

/*
 *----------------------------------------------------------------------
 *
















































































































































































































































































































 * Tcl_SourceObjCmd --
 *
 *	This procedure is invoked to process the "source" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl object result.
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
    int result;
    
    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "fileName");
	return TCL_ERROR;
    }

    /*
     * THIS FAILS IF THE OBJECT'S STRING REP CONTAINS A NULL.
     */

    bytes = Tcl_GetStringFromObj(objv[1], (int *) NULL);
    result = Tcl_EvalFile(interp, bytes);
    return result;
}

/*
 *----------------------------------------------------------------------
 *







<
<
<
<
|







676
677
678
679
680
681
682




683
684
685
686
687
688
689
690
    int result;
    
    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "fileName");
	return TCL_ERROR;
    }





    bytes = Tcl_GetString(objv[1]);
    result = Tcl_EvalFile(interp, bytes);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
971
972
973
974
975
976
977
978

979
980
981
982
983
984
985
986
987
988
989
990
991
992
993

994
995

996




997
998
999

1000
1001
1002
1003
1004
1005




1006
1007
1008
1009
1010

1011


1012

1013

1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038


1039
1040
1041
1042
1043
1044
1045
int
Tcl_SplitObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register char *p, *p2;

    char *splitChars, *string, *elementStart;
    int splitCharLen, stringLen, i, j;
    Tcl_Obj *listPtr;

    if (objc == 2) {
	splitChars = " \n\t\r";
	splitCharLen = 4;
    } else if (objc == 3) {
	splitChars = Tcl_GetStringFromObj(objv[2], &splitCharLen);
    } else {
	Tcl_WrongNumArgs(interp, 1, objv, "string ?splitChars?");
	return TCL_ERROR;
    }

    string = Tcl_GetStringFromObj(objv[1], &stringLen);

    listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    

    /*




     * Handle the special case of splitting on every character.
     */


    if (splitCharLen == 0) {
	for (i = 0, p = string;  i < stringLen;  i++, p++) {
	    Tcl_ListObjAppendElement(interp, listPtr,
                    Tcl_NewStringObj(p, 1));
	}
    } else {




	/*
	 * Normal case: split on any of a given set of characters.
	 * Discard instances of the split characters.
	 */


	for (i = 0, p = elementStart = string;  i < stringLen;  i++, p++) {


	    for (j = 0, p2 = splitChars;  j < splitCharLen;  j++, p2++) {

		if (*p2 == *p) {

		    Tcl_ListObjAppendElement(interp, listPtr,
                            Tcl_NewStringObj(elementStart, (p-elementStart)));
		    elementStart = p+1;
		    break;
		}
	    }
	}
	if (p != string) {
	    int remainingChars = stringLen - (elementStart-string);
	    Tcl_ListObjAppendElement(interp, listPtr,
                    Tcl_NewStringObj(elementStart, remainingChars));
	}
    }

    Tcl_SetObjResult(interp, listPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_StringObjCmd --
 *
 *	This procedure is invoked to process the "string" Tcl command.
 *	See the user documentation for details on what it does.


 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *







|
>
|
|
|












>
|

>
|
>
>
>
>
|
|

>
|
|
|
<


>
>
>
>





>
|
>
>
|
>
|
>
|
<
|




|
<
|
<
|
<
<
<









|
>
>







706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745

746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771

772

773



774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
int
Tcl_SplitObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_UniChar ch;
    int len;
    char *splitChars, *string, *end;
    int splitCharLen, stringLen;
    Tcl_Obj *listPtr, *objPtr;

    if (objc == 2) {
	splitChars = " \n\t\r";
	splitCharLen = 4;
    } else if (objc == 3) {
	splitChars = Tcl_GetStringFromObj(objv[2], &splitCharLen);
    } else {
	Tcl_WrongNumArgs(interp, 1, objv, "string ?splitChars?");
	return TCL_ERROR;
    }

    string = Tcl_GetStringFromObj(objv[1], &stringLen);
    end = string + stringLen;
    listPtr = Tcl_GetObjResult(interp);
    
    if (stringLen == 0) {
	/*
	 * Do nothing.
	 */
    } else if (splitCharLen == 0) {
	/*
	 * Handle the special case of splitting on every character.
	 */

	for ( ; string < end; string += len) {
	    len = Tcl_UtfToUniChar(string, &ch);
	    objPtr = Tcl_NewStringObj(string, len);
	    Tcl_ListObjAppendElement(NULL, listPtr, objPtr);

	}
    } else {
	char *element, *p, *splitEnd;
	int splitLen;
	Tcl_UniChar splitChar;
	
	/*
	 * Normal case: split on any of a given set of characters.
	 * Discard instances of the split characters.
	 */

	splitEnd = splitChars + splitCharLen;

	for (element = string; string < end; string += len) {
	    len = Tcl_UtfToUniChar(string, &ch);
	    for (p = splitChars; p < splitEnd; p += splitLen) {
		splitLen = Tcl_UtfToUniChar(p, &splitChar);
		if (ch == splitChar) {
		    objPtr = Tcl_NewStringObj(element, string - element);
		    Tcl_ListObjAppendElement(NULL, listPtr, objPtr);

		    element = string + len;
		    break;
		}
	    }
	}
	objPtr = Tcl_NewStringObj(element, string - element);

	Tcl_ListObjAppendElement(NULL, listPtr, objPtr);

    }



    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_StringObjCmd --
 *
 *	This procedure is invoked to process the "string" Tcl command.
 *	See the user documentation for details on what it does.  Note
 *	that this command only functions correctly on properly formed
 *	Tcl UTF strings.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
    int index, left, right;
    Tcl_Obj *resultPtr;
    char *string1, *string2;
    int length1, length2;
    static char *options[] = {
	"compare",	"first",	"index",	"last",
	"length",	"match",	"range",	"tolower",
	"toupper",	"trim",		"trimleft",	"trimright",
	"wordend",	"wordstart",	NULL
    };
    enum options {
	STR_COMPARE,	STR_FIRST,	STR_INDEX,	STR_LAST,
	STR_LENGTH,	STR_MATCH,	STR_RANGE,	STR_TOLOWER,
	STR_TOUPPER,	STR_TRIM,	STR_TRIMLEFT,	STR_TRIMRIGHT,
	STR_WORDEND,	STR_WORDSTART
    };	  
	    
    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }
    







|
|




|
|







804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
    int index, left, right;
    Tcl_Obj *resultPtr;
    char *string1, *string2;
    int length1, length2;
    static char *options[] = {
	"compare",	"first",	"index",	"last",
	"length",	"match",	"range",	"tolower",
	"toupper",	"totitle",	"trim",		"trimleft",
	"trimright",	"wordend",	"wordstart",	(char *) NULL
    };
    enum options {
	STR_COMPARE,	STR_FIRST,	STR_INDEX,	STR_LAST,
	STR_LENGTH,	STR_MATCH,	STR_RANGE,	STR_TOLOWER,
	STR_TOUPPER,	STR_TOTITLE,	STR_TRIM,	STR_TRIMLEFT,
	STR_TRIMRIGHT,	STR_WORDEND,	STR_WORDSTART
    };	  
	    
    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }
    
1108
1109
1110
1111
1112
1113
1114




1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133









1134
1135
1136
1137
1138
1139



1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150





1151




1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162




1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180









1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198

	    if (objc != 4) {
	        badFirstLastArgs:
	        Tcl_WrongNumArgs(interp, 2, objv, "string1 string2");
		return TCL_ERROR;
	    }





	    match = -1;
	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    string2 = Tcl_GetStringFromObj(objv[3], &length2);
	    if (length1 > 0) {
		end = string2 + length2 - length1 + 1;
		for (p = string2;  p < end;  p++) {
		  /*
		   * Scan forward to find the first character.
		   */
		    
		  p = memchr(p, *string1, (unsigned) (end - p));
		  if (p == NULL) {
		      break;
		  }
		  if (memcmp(string1, p, (unsigned) length1) == 0) {
		      match = p - string2;
		      break;
		  }
		}









	    }
	    Tcl_SetIntObj(resultPtr, match);
	    break;
	}
	case STR_INDEX: {
	    int index;




	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string charIndex");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    if (Tcl_GetIntFromObj(interp, objv[3], &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if ((index >= 0) && (index < length1)) {





	        Tcl_SetStringObj(resultPtr, string1 + index, 1);




	    }
	    break;
	}
	case STR_LAST: {
	    register char *p;
	    int match;

	    if (objc != 4) {
	        goto badFirstLastArgs;
	    }





	    match = -1;
	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    string2 = Tcl_GetStringFromObj(objv[3], &length2);
	    if (length1 > 0) {
		for (p = string2 + length2 - length1;  p >= string2;  p--) {
		    /*
		     * Scan backwards to find the first character.
		     */
		    
		    while ((p != string2) && (*p != *string1)) {
			p--;
		    }
		    if (memcmp(string1, p, (unsigned) length1) == 0) {
			match = p - string2;
			break;
		    }
		}
	    }









	    Tcl_SetIntObj(resultPtr, match);
	    break;
	}
	case STR_LENGTH: {
	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string");
		return TCL_ERROR;
	    }

	    (void) Tcl_GetStringFromObj(objv[2], &length1);
	    Tcl_SetIntObj(resultPtr, length1);
	    break;
	}
	case STR_MATCH: {
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, "pattern string");
		return TCL_ERROR;
	    }







>
>
>
>






|
|
|
|
|
|
|
|
|
|
|
|

>
>
>
>
>
>
>
>
>






>
>
>






<



|
>
>
>
>
>
|
>
>
>
>











>
>
>
>


















>
>
>
>
>
>
>
>
>









|
|







855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908

909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982

	    if (objc != 4) {
	        badFirstLastArgs:
	        Tcl_WrongNumArgs(interp, 2, objv, "string1 string2");
		return TCL_ERROR;
	    }

	    /*
	     * This algorithm fails on improperly formed UTF strings.
	     */

	    match = -1;
	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    string2 = Tcl_GetStringFromObj(objv[3], &length2);
	    if (length1 > 0) {
		end = string2 + length2 - length1 + 1;
		for (p = string2;  p < end;  p++) {
		    /*
		     * Scan forward to find the first character.
		     */

		    p = memchr(p, *string1, (unsigned) (end - p));
		    if (p == NULL) {
			break;
		    }
		    if (memcmp(string1, p, (unsigned) length1) == 0) {
			match = p - string2;
			break;
		    }
		}
	    }

	    /*
	     * Compute the character index of the matching string by counting
	     * the number of characters before the match.
	     */

	    if (match != -1) {
		match = Tcl_NumUtfChars(string2, match);
	    }
	    Tcl_SetIntObj(resultPtr, match);
	    break;
	}
	case STR_INDEX: {
	    int index;
	    Tcl_UniChar ch;
	    char buf[TCL_UTF_MAX];
	    char *start, *end;

	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string charIndex");
		return TCL_ERROR;
	    }


	    if (Tcl_GetIntFromObj(interp, objv[3], &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (index >= 0) {
		start = Tcl_GetStringFromObj(objv[2], &length1);
		end = start + length1;
		for ( ; start < end; index--) {
		    start += Tcl_UtfToUniChar(start, &ch);
		    if (index == 0) {
			Tcl_SetStringObj(resultPtr, buf,
				Tcl_UniCharToUtf(ch, buf));
			break;
		    }
		}
	    }
	    break;
	}
	case STR_LAST: {
	    register char *p;
	    int match;

	    if (objc != 4) {
	        goto badFirstLastArgs;
	    }

	    /*
	     * This algorithm fails on improperly formed UTF strings.
	     */

	    match = -1;
	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    string2 = Tcl_GetStringFromObj(objv[3], &length2);
	    if (length1 > 0) {
		for (p = string2 + length2 - length1;  p >= string2;  p--) {
		    /*
		     * Scan backwards to find the first character.
		     */
		    
		    while ((p != string2) && (*p != *string1)) {
			p--;
		    }
		    if (memcmp(string1, p, (unsigned) length1) == 0) {
			match = p - string2;
			break;
		    }
		}
	    }

	    /*
	     * Compute the character index of the matching string by counting
	     * the number of characters before the match.
	     */

	    if (match != -1) {
		match = Tcl_NumUtfChars(string2, match);
	    }
	    Tcl_SetIntObj(resultPtr, match);
	    break;
	}
	case STR_LENGTH: {
	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    Tcl_SetIntObj(resultPtr, Tcl_NumUtfChars(string1, length1));
	    break;
	}
	case STR_MATCH: {
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, "pattern string");
		return TCL_ERROR;
	    }
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228




1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249

1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307








1308

1309
1310
1311
1312
1313
1314

1315
1316
1317
1318
1319
1320
1321
1322
1323
1324








1325
1326
1327

1328
1329
1330
1331
1332

1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354



1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369


1370
1371

1372
1373
1374
1375
1376
1377
1378


1379
1380
1381
1382
1383
1384



1385
1386
1387
1388
1389
1390
1391
1392
1393
1394

1395
1396
1397
1398
1399

1400
1401

1402
1403
1404

1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443






1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469


1470


1471
1472
1473


1474
1475


1476
1477
1478

1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496


1497
1498
1499
1500
1501

1502
1503
1504
1505
1506
1507
1508

	    if (objc != 5) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string first last");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);

	    if (TclGetIntForIndex(interp, objv[3], length1 - 1,
		    &first) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (TclGetIntForIndex(interp, objv[4], length1 - 1,
		    &last) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (first < 0) {
		first = 0;
	    }
	    if (last >= length1 - 1) {
		last = length1 - 1;
	    }
	    if (last >= first) {




	        Tcl_SetStringObj(resultPtr, string1 + first, last - first + 1);
	    }
	    break;
	}
	case STR_TOLOWER: {
	    register char *p, *end;

	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);

	    /*
	     * Since I know resultPtr is not a shared object, I can reach
	     * in and diddle the bytes in its string rep to convert them in
	     * place to lower case.

	     */

	    Tcl_SetStringObj(resultPtr, string1, length1);

	    string1 = Tcl_GetStringFromObj(resultPtr, &length1);
	    end = string1 + length1;
	    for (p = string1; p < end; p++) {
		if (isupper(UCHAR(*p))) {
		    *p = (char) tolower(UCHAR(*p));
		}
	    }
	    break;
	}
	case STR_TOUPPER: {
	    register char *p, *end;

	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);

	    /*
	     * Since I know resultPtr is not a shared object, I can reach
	     * in and diddle the bytes in its string rep to convert them in
	     * place to upper case.
	     */

	    Tcl_SetStringObj(resultPtr, string1, length1);
	    string1 = Tcl_GetStringFromObj(resultPtr, &length1);
	    end = string1 + length1;
	    for (p = string1; p < end; p++) {
		if (islower(UCHAR(*p))) {
		    *p = (char) toupper(UCHAR(*p));
		}
	    }
	    break;
	}
	case STR_TRIM: {
	    char ch;
	    register char *p, *end;
	    char *check, *checkEnd;


	    left = 1;
	    right = 1;

	    trim:
	    if (objc == 4) {
		string2 = Tcl_GetStringFromObj(objv[3], &length2);
	    } else if (objc == 3) {
		string2 = " \t\n\r";
		length2 = strlen(string2);
	    } else {
	        Tcl_WrongNumArgs(interp, 2, objv, "string ?chars?");
		return TCL_ERROR;
	    }
	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    checkEnd = string2 + length2;

	    if (left) {
		end = string1 + length1;








		for (p = string1; p < end; p++) {

		    ch = *p;
		    for (check = string2; ; check++) {
			if (check >= checkEnd) {
			    p = end;
			    break;
			}

			if (ch == *check) {
			    length1--;
			    string1++;
			    break;
			}
		    }
		}
	    }
	    if (right) {
	        end = string1;








		for (p = string1 + length1; p > end; ) {
		    p--;
		    ch = *p;

		    for (check = string2; ; check++) {
		        if (check >= checkEnd) {
			    p = end;
			    break;
			}

			if (ch == *check) {
			    length1--;
			    break;
			}
		    }
		}
	    }
	    Tcl_SetStringObj(resultPtr, string1, length1);
	    break;
	}
	case STR_TRIMLEFT: {
	    left = 1;
	    right = 0;
	    goto trim;
	}
	case STR_TRIMRIGHT: {
	    left = 0;
	    right = 1;
	    goto trim;
	}
	case STR_WORDEND: {
	    int cur, c;



	    
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string index");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    if (Tcl_GetIntFromObj(interp, objv[3], &index) != TCL_OK) {
	        return TCL_ERROR;
	    }
	    if (index < 0) {
		index = 0;
	    }
	    cur = length1;
	    if (index < length1) {


		for (cur = index; cur < length1; cur++) {
		    c = UCHAR(string1[cur]);

		    if (!isalnum(c) && (c != '_')) {
			break;
		    }
		}
		if (cur == index) {
		    cur = index + 1;
		}


	    }
	    Tcl_SetIntObj(resultPtr, cur);
	    break;
	}
	case STR_WORDSTART: {
	    int cur, c;



	    
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string index");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    if (Tcl_GetIntFromObj(interp, objv[3], &index) != TCL_OK) {
		return TCL_ERROR;
	    }

	    if (index >= length1) {
		index = length1 - 1;
	    }
	    cur = 0;
	    if (index > 0) {

	        for (cur = index; cur >= 0; cur--) {
		    c = UCHAR(string1[cur]);

		    if (!isalnum(c) && (c != '_')) {
			break;
		    }

		}
		if (cur != index) {
		    cur += 1;
		}
	    }
	    Tcl_SetIntObj(resultPtr, cur);
	    break;
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SubstCmd --
 *
 *	This procedure is invoked to process the "subst" Tcl command.
 *	See the user documentation for details on what it does.  This
 *	command is an almost direct copy of an implementation by
 *	Andrew Payne.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_SubstCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{






    Interp *iPtr = (Interp *) interp;
    Tcl_DString result;
    char *p, *old, *value;
    int code, count, doVars, doCmds, doBackslashes, i;
    size_t length;
    char c;

    /*
     * Parse command-line options.
     */

    doVars = doCmds = doBackslashes = 1;
    for (i = 1; i < (argc-1); i++) {
	p = argv[i];
	if (*p != '-') {
	    break;
	}
	length = strlen(p);
	if (length < 4) {
	    badSwitch:
	    Tcl_AppendResult(interp, "bad switch \"", p,
		    "\": must be -nobackslashes, -nocommands, ",
		    "or -novariables", (char *) NULL);
	    return TCL_ERROR;
	}
	if ((p[3] == 'b') && (strncmp(p, "-nobackslashes", length) == 0)) {


	    doBackslashes = 0;


	} else if ((p[3] == 'c') && (strncmp(p, "-nocommands", length) == 0)) {
	    doCmds = 0;
	} else if ((p[3] == 'v') && (strncmp(p, "-novariables", length) == 0)) {


	    doVars = 0;
	} else {


	    goto badSwitch;
	}
    }

    if (i != (argc-1)) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" ?-nobackslashes? ?-nocommands? ?-novariables? string\"",
		(char *) NULL);
	return TCL_ERROR;
    }

    /*
     * Scan through the string one character at a time, performing
     * command, variable, and backslash substitutions.
     */

    Tcl_DStringInit(&result);
    old = p = argv[i];
    while (*p != 0) {
	switch (*p) {
	    case '\\':
		if (doBackslashes) {


		    if (p != old) {
			Tcl_DStringAppend(&result, old, p-old);
		    }
		    c = Tcl_Backslash(p, &count);
		    Tcl_DStringAppend(&result, &c, 1);

		    p += count;
		    old = p;
		} else {
		    p++;
		}
		break;








>















>
>
>
>
|



|
|
|








|
|
|
>



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

|

|


>




|














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




>
|
|
|







>
>
>
>
>
>
>
>

<
|
>
|




>
|
|











|




|


|
>
>
>













|
|
>
>
|
<
>
|




|

>
>





|
>
>
>










>
|
|



>

<
>
|


>















|

















|


|
|

>
>
>
>
>
>



|
<
<






|
|



<
|
|
|
<
<


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









|




>
>



<
|
>







991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041








1042

1043




1044
1045
1046





1047








1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109

1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160

1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197

1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251


1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262

1263
1264
1265


1266
1267

1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307

1308
1309
1310
1311
1312
1313
1314
1315
1316

	    if (objc != 5) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string first last");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    length1 = Tcl_NumUtfChars(string1, length1);
	    if (TclGetIntForIndex(interp, objv[3], length1 - 1,
		    &first) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (TclGetIntForIndex(interp, objv[4], length1 - 1,
		    &last) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (first < 0) {
		first = 0;
	    }
	    if (last >= length1 - 1) {
		last = length1 - 1;
	    }
	    if (last >= first) {
		char *start, *end;

		start = Tcl_UtfAtIndex(string1, first);
		end = Tcl_UtfAtIndex(start, last - first + 1);
	        Tcl_SetStringObj(resultPtr, start, end - start);
	    }
	    break;
	}
	case STR_TOLOWER:
	case STR_TOUPPER:
	case STR_TOTITLE:
	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);

	    /*
	     * Since the result object is not a shared object, it is
	     * safe to copy the string into the result and do the
	     * conversion in place.  The conversion may change the length
	     * of the string, so reset the length after conversion.
	     */

	    Tcl_SetStringObj(resultPtr, string1, length1);
	    if ((enum options) index == STR_TOLOWER) {
		length1 = Tcl_UtfToLower(Tcl_GetStringFromObj(resultPtr, NULL));








	    } else if ((enum options) index == STR_TOUPPER) {

		length1 = Tcl_UtfToUpper(Tcl_GetStringFromObj(resultPtr, NULL));




	    } else {
		length1 = Tcl_UtfToTitle(Tcl_GetStringFromObj(resultPtr, NULL));
	    }





	    Tcl_SetObjLength(resultPtr, length1);








	    break;

	case STR_TRIM: {
	    Tcl_UniChar ch, trim;
	    register char *p, *end;
	    char *check, *checkEnd;
	    int offset;

	    left = 1;
	    right = 1;

	    dotrim:
	    if (objc == 4) {
		string2 = Tcl_GetStringFromObj(objv[3], &length2);
	    } else if (objc == 3) {
		string2 = " \t\n\r";
		length2 = strlen(string2);
	    } else {
	        Tcl_WrongNumArgs(interp, 2, objv, "string ?chars?");
		return TCL_ERROR;
	    }
	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    checkEnd = string2 + length2;

	    if (left) {
		end = string1 + length1;
		/*
		 * The outer loop iterates over the string.  The inner
		 * loop iterates over the trim characters.  The loops
		 * terminate as soon as a non-trim character is discovered
		 * and string1 is left pointing at the first non-trim
		 * character.
		 */

		for (p = string1; p < end; p += offset) {
		    offset = Tcl_UtfToUniChar(p, &ch);
		    
		    for (check = string2; ; ) {
			if (check >= checkEnd) {
			    p = end;
			    break;
			}
			check += Tcl_UtfToUniChar(check, &trim);
			if (ch == trim) {
			    length1 -= offset;
			    string1 += offset;
			    break;
			}
		    }
		}
	    }
	    if (right) {
	        end = string1;

		/*
		 * The outer loop iterates over the string.  The inner
		 * loop iterates over the trim characters.  The loops
		 * terminate as soon as a non-trim character is discovered
		 * and length1 marks the last non-trim character.
		 */

		for (p = string1 + length1; p > end; ) {

		    p = Tcl_UtfPrev(p, string1);
		    offset = Tcl_UtfToUniChar(p, &ch);
		    for (check = string2; ; ) {
		        if (check >= checkEnd) {
			    p = end;
			    break;
			}
			check += Tcl_UtfToUniChar(check, &trim);
			if (ch == trim) {
			    length1 -= offset;
			    break;
			}
		    }
		}
	    }
	    Tcl_SetStringObj(resultPtr, string1, length1);
	    break;
	}
	case STR_TRIMLEFT: {
	    left = 1;
	    right = 0;
	    goto dotrim;
	}
	case STR_TRIMRIGHT: {
	    left = 0;
	    right = 1;
	    goto dotrim;
	}
	case STR_WORDEND: {
	    int cur;
	    Tcl_UniChar ch;
	    char *p, *end;
	    int numChars;
	    
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string index");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    if (Tcl_GetIntFromObj(interp, objv[3], &index) != TCL_OK) {
	        return TCL_ERROR;
	    }
	    if (index < 0) {
		index = 0;
	    }
	    numChars = Tcl_NumUtfChars(string1, length1);
	    if (index < numChars) {
		p = Tcl_UtfAtIndex(string1, index);
		end = string1+length1;
		for (cur = index; p < end; cur++) {

		    p += Tcl_UtfToUniChar(p, &ch);
		    if (!Tcl_UniCharIsWordChar(ch)) {
			break;
		    }
		}
		if (cur == index) {
		    cur++;
		}
	    } else {
		cur = numChars;
	    }
	    Tcl_SetIntObj(resultPtr, cur);
	    break;
	}
	case STR_WORDSTART: {
	    int cur;
	    Tcl_UniChar ch;
	    char *p;
	    int numChars;
	    
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, "string index");
		return TCL_ERROR;
	    }

	    string1 = Tcl_GetStringFromObj(objv[2], &length1);
	    if (Tcl_GetIntFromObj(interp, objv[3], &index) != TCL_OK) {
		return TCL_ERROR;
	    }
	    numChars = Tcl_NumUtfChars(string1, length1);
	    if (index >= numChars) {
		index = numChars - 1;
	    }
	    cur = 0;
	    if (index > 0) {
		p = Tcl_UtfAtIndex(string1, index);
	        for (cur = index; cur >= 0; cur--) {

		    Tcl_UtfToUniChar(p, &ch);
		    if (!Tcl_UniCharIsWordChar(ch)) {
			break;
		    }
		    p = Tcl_UtfPrev(p, string1);
		}
		if (cur != index) {
		    cur += 1;
		}
	    }
	    Tcl_SetIntObj(resultPtr, cur);
	    break;
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SubstObjCmd --
 *
 *	This procedure is invoked to process the "subst" Tcl command.
 *	See the user documentation for details on what it does.  This
 *	command is an almost direct copy of an implementation by
 *	Andrew Payne.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_SubstObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];       	/* Argument objects. */
{
    static char *substOptions[] = {
	"-nobackslashes", "-nocommands", "-novariables", (char *) NULL
    };
    enum substOptions {
	SUBST_NOBACKSLASHES,      SUBST_NOCOMMANDS,       SUBST_NOVARS
    };
    Interp *iPtr = (Interp *) interp;
    Tcl_DString result;
    char *p, *old, *value;
    int optionIndex, code, count, doVars, doCmds, doBackslashes, i;



    /*
     * Parse command-line options.
     */

    doVars = doCmds = doBackslashes = 1;
    for (i = 1; i < (objc-1); i++) {
	p = Tcl_GetString(objv[i]);
	if (*p != '-') {
	    break;
	}

	if (Tcl_GetIndexFromObj(interp, objv[i], substOptions,
		"switch", 0, &optionIndex) != TCL_OK) {



	    return TCL_ERROR;
	}

	switch (optionIndex) {
	    case SUBST_NOBACKSLASHES: {
		doBackslashes = 0;
		break;
	    }
	    case SUBST_NOCOMMANDS: {
		doCmds = 0;
		break;
	    }
	    case SUBST_NOVARS: {
		doVars = 0;
		break;
	    }
	    default: {
		panic("Tcl_SubstObjCmd: bad option index to SubstOptions");
	    }
	}
    }
    if (i != (objc-1)) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?-nobackslashes? ?-nocommands? ?-novariables? string");

	return TCL_ERROR;
    }

    /*
     * Scan through the string one character at a time, performing
     * command, variable, and backslash substitutions.
     */

    Tcl_DStringInit(&result);
    old = p = Tcl_GetString(objv[i]);
    while (*p != 0) {
	switch (*p) {
	    case '\\':
		if (doBackslashes) {
		    char buf[TCL_UTF_MAX];

		    if (p != old) {
			Tcl_DStringAppend(&result, old, p-old);
		    }

		    Tcl_DStringAppend(&result, buf,
			    Tcl_UtfBackslash(p, &count, buf));
		    p += count;
		    old = p;
		} else {
		    p++;
		}
		break;

1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591





1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608

1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622

1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642

1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734

1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
int
Tcl_SwitchObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
#define EXACT	0
#define GLOB	1
#define REGEXP	2
    int switchObjc, index;
    Tcl_Obj *CONST *switchObjv;
    Tcl_Obj *patternObj, *bodyObj;
    char *string, *pattern, *body;
    int splitObjs, length, patternLen, i, code, mode, matched, bodyIdx;
    static char *switches[] =
	    {"-exact", "-glob", "-regexp", "--", (char *) NULL};






    switchObjc = objc-1;
    switchObjv = objv+1;
    mode = EXACT;

    while (switchObjc > 0) {
	string = Tcl_GetStringFromObj(switchObjv[0], &length);
	if (*string != '-') {
	    break;
	}
	if (Tcl_GetIndexFromObj(interp, switchObjv[0], switches,
		"option", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch (index) {
	    case 0:			/* -exact */
		mode = EXACT;

		break;
	    case 1:			/* -glob */
		mode = GLOB;
		break;
	    case 2:			/* -regexp */
		mode = REGEXP;
		break;
	    case 3:			/* -- */
		switchObjc--;
		switchObjv++;
		goto doneWithSwitches;
	}
	switchObjc--;
	switchObjv++;

    }

    doneWithSwitches:
    if (switchObjc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?switches? string pattern body ... ?default body?");
	return TCL_ERROR;
    }
    
    string = Tcl_GetStringFromObj(switchObjv[0], &length);
    switchObjc--;
    switchObjv++;

    /*
     * If all of the pattern/command pairs are lumped into a single
     * argument, split them out again.
     */

    splitObjs = 0;
    if (switchObjc == 1) {

	code = Tcl_ListObjLength(interp, switchObjv[0], &switchObjc);
	if (code != TCL_OK) {
	    return code;
	}
	splitObjs = 1;
    }

    for (i = 0;  i < switchObjc;  i += 2) {
	if (i == (switchObjc-1)) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	            "extra switch pattern with no body", -1);
	    code = TCL_ERROR;
	    goto done;
	}

	/*
	 * See if the pattern matches the string.
	 */

	if (splitObjs) {
	    code = Tcl_ListObjIndex(interp, switchObjv[0], i, &patternObj);
	    if (code != TCL_OK) {
		return code;
	    }
	    pattern = Tcl_GetStringFromObj(patternObj, &patternLen);
	} else {
	    pattern = Tcl_GetStringFromObj(switchObjv[i], &patternLen);
	}

	matched = 0;

	if ((*pattern == 'd') && (i == switchObjc-2)
		&& (strcmp(pattern, "default") == 0)) {
	    matched = 1;
	} else {
	    /*
	     * THIS FAILS IF AN OBJECT'S STRING REP HAS A NULL.
	     */
	    switch (mode) {
		case EXACT:
		    matched = (strcmp(string, pattern) == 0);
		    break;
		case GLOB:
		    matched = Tcl_StringMatch(string, pattern);
		    break;
		case REGEXP:
		    matched = Tcl_RegExpMatch(interp, string, pattern);
		    if (matched < 0) {
			code = TCL_ERROR;
			goto done;
		    }
		    break;
	    }
	}
	if (!matched) {
	    continue;
	}

	/*
	 * We've got a match. Find a body to execute, skipping bodies
	 * that are "-".
	 */

	for (bodyIdx = i+1;  ;  bodyIdx += 2) {
	    if (bodyIdx >= switchObjc) {
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"no body specified for pattern \"", pattern,
			"\"", (char *) NULL);
		code = TCL_ERROR;
		goto done;
	    }
	    
	    if (splitObjs) {
		code = Tcl_ListObjIndex(interp, switchObjv[0], bodyIdx,
		        &bodyObj);
		if (code != TCL_OK) {
		    return code;
		}
	    } else {
		bodyObj = switchObjv[bodyIdx];
	    }
	    /*
	     * THIS FAILS IF AN OBJECT'S STRING REP HAS A NULL.
	     */
	    body = Tcl_GetStringFromObj(bodyObj, &length);
	    if ((length != 1) || (body[0] != '-')) {
		break;
	    }
	}
	code = Tcl_EvalObj(interp, bodyObj);
	if (code == TCL_ERROR) {
	    char msg[100];

	    sprintf(msg, "\n    (\"%.50s\" arm line %d)", pattern,
		    interp->errorLine);
	    Tcl_AddObjErrorInfo(interp, msg, -1);
	}
	goto done;
    }

    /*
     * Nothing matched:  return nothing.
     */

    code = TCL_OK;

    done:
    return code;
#undef EXACT
#undef GLOB
#undef REGEXP
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TimeObjCmd --
 *







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

<
<
|
|
<
|
|


|
|


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

<
<
>


<
|




|
|
|
|






<
|
>
|
|
|

|


|
|



|
<






<
<
<
<
<
|
<
<
<
<

>
|



<
<
<

|


|


|
|

|
<




|








|
|



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



|
|
|
>




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







1383
1384
1385
1386
1387
1388
1389



1390


1391

1392
1393
1394
1395
1396
1397
1398
1399


1400
1401

1402
1403
1404
1405
1406
1407
1408
1409
1410


1411
1412










1413


1414
1415
1416

1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431

1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446

1447
1448
1449
1450
1451
1452





1453




1454
1455
1456
1457
1458
1459



1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470

1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488








1489
1490






1491

1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502


1503



1504



1505



1506
1507
1508
1509
1510
1511
1512
int
Tcl_SwitchObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{



    int i, j, index, mode, matched, result;


    char *string, *pattern;

    static char *options[] = {
	"-exact",	"-glob",	"-regexp",	"--", 
	NULL
    };
    enum options {
	OPT_EXACT,	OPT_GLOB,	OPT_REGEXP,	OPT_LAST
    };



    mode = OPT_EXACT;
    for (i = 1; i < objc; i++) {

	string = Tcl_GetString(objv[i]);
	if (string[0] != '-') {
	    break;
	}
	if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, 
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == OPT_LAST) {


	    i++;
	    break;










	}


	mode = index;
    }


    if (objc - i < 2) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?switches? string pattern body ... ?default body?");
	return TCL_ERROR;
    }

    string = Tcl_GetString(objv[i]);
    objc -= i + 1;
    objv += i + 1;

    /*
     * If all of the pattern/command pairs are lumped into a single
     * argument, split them out again.
     */


    if (objc == 1) {
	Tcl_Obj **listv;

	if (Tcl_ListObjGetElements(interp, objv[0], &objc, &listv) != TCL_OK) {
	    return TCL_ERROR;
	}
	objv = listv;
    }

    for (i = 0; i < objc; i += 2) {
	if (i == objc - 1) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	            "extra switch pattern with no body", -1);
	    return TCL_ERROR;

	}

	/*
	 * See if the pattern matches the string.
	 */






	pattern = Tcl_GetString(objv[i]);




	matched = 0;
	if ((i == objc - 2) 
		&& (*pattern == 'd') 
		&& (strcmp(pattern, "default") == 0)) {
	    matched = 1;
	} else {



	    switch (mode) {
		case OPT_EXACT:
		    matched = (strcmp(string, pattern) == 0);
		    break;
		case OPT_GLOB:
		    matched = Tcl_StringMatch(string, pattern);
		    break;
		case OPT_REGEXP:
		    matched = TclRegExpMatchObj(interp, string, objv[i]);
		    if (matched < 0) {
			return TCL_ERROR;

		    }
		    break;
	    }
	}
	if (matched == 0) {
	    continue;
	}

	/*
	 * We've got a match. Find a body to execute, skipping bodies
	 * that are "-".
	 */

	for (j = i + 1; ; j += 2) {
	    if (j >= objc) {
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"no body specified for pattern \"", pattern,
			"\"", (char *) NULL);








		return TCL_ERROR;
	    }






	    if (strcmp(Tcl_GetString(objv[j]), "-") != 0) {

		break;
	    }
	}
	result = Tcl_EvalObjEx(interp, objv[j], 0);
	if (result == TCL_ERROR) {
	    char msg[100 + TCL_INTEGER_SPACE];

	    sprintf(msg, "\n    (\"%.50s\" arm line %d)", pattern,
		    interp->errorLine);
	    Tcl_AddObjErrorInfo(interp, msg, -1);
	}


	return result;



    }



    return TCL_OK;



}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TimeObjCmd --
 *
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844

1845






1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856





1857
1858
1859
1860
1861
1862
1863
1864
1865
1866

1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976






1977




1978

1979
1980
1981
1982
1983
1984
1985
1986

1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
	return TCL_ERROR;
    }
    
    objPtr = objv[1];
    i = count;
    TclpGetTime(&start);
    while (i-- > 0) {
	result = Tcl_EvalObj(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }
    TclpGetTime(&stop);
    
    totalMicroSec =
	(stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
    sprintf(buf, "%.0f microseconds per iteration",
	((count <= 0) ? 0 : totalMicroSec/count));
    Tcl_ResetResult(interp);
    Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TraceCmd --
 *
 *	This procedure is invoked to process the "trace" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_TraceCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    int c;

    size_t length;







    if (argc < 2) {
	Tcl_AppendResult(interp, "too few args: should be \"",
		argv[0], " option [arg arg ...]\"", (char *) NULL);
	return TCL_ERROR;
    }
    c = argv[1][1];
    length = strlen(argv[1]);
    if ((c == 'a') && (strncmp(argv[1], "variable", length) == 0)
	    && (length >= 2)) {
	char *p;





	int flags, length;
	TraceVarInfo *tvarPtr;

	if (argc != 5) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
		    argv[0], " variable name ops command\"", (char *) NULL);
	    return TCL_ERROR;
	}

	flags = 0;

	for (p = argv[3] ; *p != 0; p++) {
	    if (*p == 'r') {
		flags |= TCL_TRACE_READS;
	    } else if (*p == 'w') {
		flags |= TCL_TRACE_WRITES;
	    } else if (*p == 'u') {
		flags |= TCL_TRACE_UNSETS;
	    } else {
		goto badOps;
	    }
	}
	if (flags == 0) {
	    goto badOps;
	}


	length = strlen(argv[4]);
	tvarPtr = (TraceVarInfo *) ckalloc((unsigned)
		(sizeof(TraceVarInfo) - sizeof(tvarPtr->command) + length + 1));

	tvarPtr->flags = flags;
	tvarPtr->errMsg = NULL;
	tvarPtr->length = length;
	flags |= TCL_TRACE_UNSETS;
	strcpy(tvarPtr->command, argv[4]);

	if (Tcl_TraceVar(interp, argv[2], flags, TraceVarProc,
		(ClientData) tvarPtr) != TCL_OK) {
	    ckfree((char *) tvarPtr);
	    return TCL_ERROR;
	}
    } else if ((c == 'd') && (strncmp(argv[1], "vdelete", length)
	    && (length >= 2)) == 0) {
	char *p;


	int flags, length;
	TraceVarInfo *tvarPtr;
	ClientData clientData;

	if (argc != 5) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
		    argv[0], " vdelete name ops command\"", (char *) NULL);
	    return TCL_ERROR;
	}

	flags = 0;

	for (p = argv[3] ; *p != 0; p++) {
	    if (*p == 'r') {
		flags |= TCL_TRACE_READS;
	    } else if (*p == 'w') {
		flags |= TCL_TRACE_WRITES;
	    } else if (*p == 'u') {
		flags |= TCL_TRACE_UNSETS;
	    } else {
		goto badOps;
	    }
	}
	if (flags == 0) {
	    goto badOps;
	}

	/*
	 * Search through all of our traces on this variable to
	 * see if there's one with the given command.  If so, then
	 * delete the first one that matches.
	 */


	length = strlen(argv[4]);
	clientData = 0;

	while ((clientData = Tcl_VarTraceInfo(interp, argv[2], 0,
		TraceVarProc, clientData)) != 0) {
	    tvarPtr = (TraceVarInfo *) clientData;
	    if ((tvarPtr->length == length) && (tvarPtr->flags == flags)
		    && (strncmp(argv[4], tvarPtr->command,
		    (size_t) length) == 0)) {
		Tcl_UntraceVar(interp, argv[2], flags | TCL_TRACE_UNSETS,
			TraceVarProc, clientData);
		if (tvarPtr->errMsg != NULL) {
		    ckfree(tvarPtr->errMsg);
		}
		ckfree((char *) tvarPtr);
		break;
	    }
	}
    } else if ((c == 'i') && (strncmp(argv[1], "vinfo", length) == 0)
	    && (length >= 2)) {


	ClientData clientData;
	char ops[4], *p;
	char *prefix = "{";


	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
		    argv[0], " vinfo name\"", (char *) NULL);
	    return TCL_ERROR;
	}

	clientData = 0;

	while ((clientData = Tcl_VarTraceInfo(interp, argv[2], 0,
		TraceVarProc, clientData)) != 0) {

	    TraceVarInfo *tvarPtr = (TraceVarInfo *) clientData;


	    p = ops;
	    if (tvarPtr->flags & TCL_TRACE_READS) {
		*p = 'r';
		p++;
	    }
	    if (tvarPtr->flags & TCL_TRACE_WRITES) {
		*p = 'w';
		p++;
	    }
	    if (tvarPtr->flags & TCL_TRACE_UNSETS) {
		*p = 'u';
		p++;
	    }
	    *p = '\0';
	    Tcl_AppendResult(interp, prefix, (char *) NULL);






	    Tcl_AppendElement(interp, ops);




	    Tcl_AppendElement(interp, tvarPtr->command);

	    Tcl_AppendResult(interp, "}", (char *) NULL);
	    prefix = " {";
	}
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1],
		"\": should be variable, vdelete, or vinfo",
		(char *) NULL);
	return TCL_ERROR;

    }
    return TCL_OK;

    badOps:
    Tcl_AppendResult(interp, "bad operations \"", argv[3],
	    "\": should be one or more of rwu", (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *







|


















|















|


|
|

|
>

>
>
>
>
>
>

|
<
|


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

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

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

|
<
|
|
|

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

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

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




|







1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607

1608
1609
1610
1611
1612



1613
1614
1615
1616
1617
1618
1619

1620

1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657


1658
1659
1660
1661
1662
1663
1664
1665

1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712

1713
1714
1715
1716

1717
1718
1719
1720

1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764



1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
	return TCL_ERROR;
    }
    
    objPtr = objv[1];
    i = count;
    TclpGetTime(&start);
    while (i-- > 0) {
	result = Tcl_EvalObjEx(interp, objPtr, 0);
	if (result != TCL_OK) {
	    return result;
	}
    }
    TclpGetTime(&stop);
    
    totalMicroSec =
	(stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
    sprintf(buf, "%.0f microseconds per iteration",
	((count <= 0) ? 0 : totalMicroSec/count));
    Tcl_ResetResult(interp);
    Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TraceObjCmd --
 *
 *	This procedure is invoked to process the "trace" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_TraceObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int optionIndex, commandLength;
    char *name, *rwuOps, *command, *p;
    size_t length;
    static char *traceOptions[] = {
	"variable", "vdelete", "vinfo", (char *) NULL
    };
    enum traceOptions {
	TRACE_VARIABLE,       TRACE_VDELETE,      TRACE_VINFO
    };

    if (objc < 2) {

	Tcl_WrongNumArgs(interp, 1, objv, "option [arg arg ...]");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], traceOptions,



		"option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum traceOptions) optionIndex) {
	    case TRACE_VARIABLE: {
		int flags;
		TraceVarInfo *tvarPtr;

		if (objc != 5) {

		    Tcl_WrongNumArgs(interp, 2, objv, "name ops command");
		    return TCL_ERROR;
		}

		flags = 0;
		rwuOps = Tcl_GetString(objv[3]);
		for (p = rwuOps; *p != 0; p++) {
		    if (*p == 'r') {
			flags |= TCL_TRACE_READS;
		    } else if (*p == 'w') {
			flags |= TCL_TRACE_WRITES;
		    } else if (*p == 'u') {
			flags |= TCL_TRACE_UNSETS;
		    } else {
			goto badOps;
		    }
		}
		if (flags == 0) {
		    goto badOps;
		}

		command = Tcl_GetStringFromObj(objv[4], &commandLength);
		length = (size_t) commandLength;
		tvarPtr = (TraceVarInfo *) ckalloc((unsigned)
			(sizeof(TraceVarInfo) - sizeof(tvarPtr->command)
				+ length + 1));
		tvarPtr->flags = flags;
		tvarPtr->errMsg = NULL;
		tvarPtr->length = length;
		flags |= TCL_TRACE_UNSETS;
		strcpy(tvarPtr->command, command);
		name = Tcl_GetString(objv[2]);
		if (Tcl_TraceVar(interp, name, flags, TraceVarProc,
			(ClientData) tvarPtr) != TCL_OK) {
		    ckfree((char *) tvarPtr);
		    return TCL_ERROR;
		}


		break;
	    }
	    case TRACE_VDELETE: {
		int flags;
		TraceVarInfo *tvarPtr;
		ClientData clientData;

		if (objc != 5) {

		    Tcl_WrongNumArgs(interp, 2, objv, "name ops command");
		    return TCL_ERROR;
		}

		flags = 0;
		rwuOps = Tcl_GetString(objv[3]);
		for (p = rwuOps; *p != 0; p++) {
		    if (*p == 'r') {
			flags |= TCL_TRACE_READS;
		    } else if (*p == 'w') {
			flags |= TCL_TRACE_WRITES;
		    } else if (*p == 'u') {
			flags |= TCL_TRACE_UNSETS;
		    } else {
			goto badOps;
		    }
		}
		if (flags == 0) {
		    goto badOps;
		}

		/*
		 * Search through all of our traces on this variable to
		 * see if there's one with the given command.  If so, then
		 * delete the first one that matches.
		 */
		
		command = Tcl_GetStringFromObj(objv[4], &commandLength);
		length = (size_t) commandLength;
		clientData = 0;
		name = Tcl_GetString(objv[2]);
		while ((clientData = Tcl_VarTraceInfo(interp, name, 0,
			TraceVarProc, clientData)) != 0) {
		    tvarPtr = (TraceVarInfo *) clientData;
		    if ((tvarPtr->length == length) && (tvarPtr->flags == flags)
			    && (strncmp(command, tvarPtr->command,
				    (size_t) length) == 0)) {
			Tcl_UntraceVar(interp, name, flags | TCL_TRACE_UNSETS,
				TraceVarProc, clientData);
			if (tvarPtr->errMsg != NULL) {
			    ckfree(tvarPtr->errMsg);
			}
			ckfree((char *) tvarPtr);
			break;
		    }
		}
		break;

	    }
	    case TRACE_VINFO: {
		ClientData clientData;
		char ops[4];

		Tcl_Obj *resultListPtr, *pairObjPtr, *elemObjPtr;

		if (objc != 3) {
		    Tcl_WrongNumArgs(interp, 2, objv, "name");

		    return TCL_ERROR;
		}
		resultListPtr = Tcl_GetObjResult(interp);
		clientData = 0;
		name = Tcl_GetString(objv[2]);
		while ((clientData = Tcl_VarTraceInfo(interp, name, 0,
			TraceVarProc, clientData)) != 0) {

		    TraceVarInfo *tvarPtr = (TraceVarInfo *) clientData;

		    pairObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
		    p = ops;
		    if (tvarPtr->flags & TCL_TRACE_READS) {
			*p = 'r';
			p++;
		    }
		    if (tvarPtr->flags & TCL_TRACE_WRITES) {
			*p = 'w';
			p++;
		    }
		    if (tvarPtr->flags & TCL_TRACE_UNSETS) {
			*p = 'u';
			p++;
		    }
		    *p = '\0';

		    /*
		     * Build a pair (2-item list) with the ops string as
		     * the first obj element and the tvarPtr->command string
		     * as the second obj element.  Append the pair (as an
		     * element) to the end of the result object list.
		     */

		    elemObjPtr = Tcl_NewStringObj(ops, -1);
		    Tcl_ListObjAppendElement(NULL, pairObjPtr, elemObjPtr);
		    elemObjPtr = Tcl_NewStringObj(tvarPtr->command, -1);
		    Tcl_ListObjAppendElement(NULL, pairObjPtr, elemObjPtr);
		    Tcl_ListObjAppendElement(interp, resultListPtr, pairObjPtr);
		}
		Tcl_SetObjResult(interp, resultListPtr);
		break;
	    }
	default: {
		panic("Tcl_TraceObjCmd: bad option index to TraceOptions");



	    }
    }
    return TCL_OK;

    badOps:
    Tcl_AppendResult(interp, "bad operations \"", rwuOps,
	    "\": should be one or more of rwu", (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085




2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170

2171
2172
2173
2174
2175
2176
2177
    Tcl_Interp *interp;		/* Interpreter containing variable. */
    char *name1;		/* Name of variable or array. */
    char *name2;		/* Name of element within array;  NULL means
				 * scalar variable is being referenced. */
    int flags;			/* OR-ed bits giving operation and other
				 * information. */
{
    Interp *iPtr = (Interp *) interp;
    TraceVarInfo *tvarPtr = (TraceVarInfo *) clientData;
    char *result;
    int code;
    Interp dummy;
    Tcl_DString cmd;
    Tcl_Obj *saveObjPtr, *oldObjResultPtr;

    result = NULL;
    if (tvarPtr->errMsg != NULL) {
	ckfree(tvarPtr->errMsg);
	tvarPtr->errMsg = NULL;
    }
    if ((tvarPtr->flags & flags) && !(flags & TCL_INTERP_DESTROYED)) {

	/*
	 * Generate a command to execute by appending list elements
	 * for the two variable names and the operation.  The five
	 * extra characters are for three space, the opcode character,
	 * and the terminating null.
	 */

	if (name2 == NULL) {
	    name2 = "";
	}
	Tcl_DStringInit(&cmd);
	Tcl_DStringAppend(&cmd, tvarPtr->command, tvarPtr->length);
	Tcl_DStringAppendElement(&cmd, name1);
	Tcl_DStringAppendElement(&cmd, name2);
	if (flags & TCL_TRACE_READS) {
	    Tcl_DStringAppend(&cmd, " r", 2);
	} else if (flags & TCL_TRACE_WRITES) {
	    Tcl_DStringAppend(&cmd, " w", 2);
	} else if (flags & TCL_TRACE_UNSETS) {
	    Tcl_DStringAppend(&cmd, " u", 2);
	}

	/*
	 * Execute the command.  Be careful to save and restore both the
	 * string and object results from the interpreter used for
	 * the command. We discard any object result the command returns.
	 */

	dummy.objResultPtr = Tcl_NewObj();
	Tcl_IncrRefCount(dummy.objResultPtr);
	if (interp->freeProc == 0) {
	    dummy.freeProc = (Tcl_FreeProc *) 0;
	    dummy.result = "";
	    Tcl_SetResult((Tcl_Interp *) &dummy, interp->result,
		    TCL_VOLATILE);
	} else {
	    dummy.freeProc = interp->freeProc;
	    dummy.result = interp->result;
	    interp->freeProc = (Tcl_FreeProc *) 0;
	}
	
	saveObjPtr = Tcl_GetObjResult(interp);
	Tcl_IncrRefCount(saveObjPtr);
	
	code = Tcl_Eval(interp, Tcl_DStringValue(&cmd));
	if (code != TCL_OK) {	     /* copy error msg to result */




	    tvarPtr->errMsg = (char *)
		    ckalloc((unsigned) (strlen(interp->result) + 1));
	    strcpy(tvarPtr->errMsg, interp->result);
	    result = tvarPtr->errMsg;
	    Tcl_ResetResult(interp); /* must clear error state. */
	}

	/*
	 * Restore the interpreter's string result.
	 */
	
	Tcl_SetResult(interp, dummy.result,
		(dummy.freeProc == 0) ? TCL_VOLATILE : dummy.freeProc);

	/*
	 * Restore the interpreter's object result from saveObjPtr.
	 */

	oldObjResultPtr = iPtr->objResultPtr;
	iPtr->objResultPtr = saveObjPtr;  /* was incremented above */
	Tcl_DecrRefCount(oldObjResultPtr);

	Tcl_DecrRefCount(dummy.objResultPtr);
	dummy.objResultPtr = NULL;
	Tcl_DStringFree(&cmd);
    }
    if (flags & TCL_TRACE_DESTROYED) {
	result = NULL;
	if (tvarPtr->errMsg != NULL) {
	    ckfree(tvarPtr->errMsg);
	}
	ckfree((char *) tvarPtr);
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_WhileCmd --
 *
 *      This procedure is invoked to process the "while" Tcl command.
 *      See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "while" or the name
 *	to which "while" was renamed: e.g., "set z while; $z {$i<100} {}"
 *
 * Results:
 *      A standard Tcl result.
 *
 * Side effects:
 *      See the user documentation.
 *
 *----------------------------------------------------------------------
 */

        /* ARGSUSED */
int
Tcl_WhileCmd(dummy, interp, argc, argv)
    ClientData dummy;                   /* Not used. */
    Tcl_Interp *interp;                 /* Current interpreter. */
    int argc;                           /* Number of arguments. */
    char **argv;                        /* Argument strings. */
{
    int result, value;

    if (argc != 3) {
        Tcl_AppendResult(interp, "wrong # args: should be \"",
                argv[0], " test command\"", (char *) NULL);
        return TCL_ERROR;
    }

    while (1) {
        result = Tcl_ExprBoolean(interp, argv[1], &value);
        if (result != TCL_OK) {
            return result;
        }
        if (!value) {
            break;
        }
        result = Tcl_Eval(interp, argv[2]);
        if ((result != TCL_OK) && (result != TCL_CONTINUE)) {
            if (result == TCL_ERROR) {
                char msg[60];

                sprintf(msg, "\n    (\"while\" body line %d)",
                        interp->errorLine);
                Tcl_AddErrorInfo(interp, msg);
            }
            break;
        }
    }







|



<

<



















|











|
<



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


>
>
>
>
|
<
|

<


<
<
<
<
|
<

<
<
<
<
<
<
<
<
<
<















|



















|


|
|



|
|
<




|






|


|
>







1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807

1808

1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840

1841
1842
1843













1844

1845
1846
1847
1848
1849
1850
1851
1852

1853
1854

1855
1856




1857

1858










1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
    Tcl_Interp *interp;		/* Interpreter containing variable. */
    char *name1;		/* Name of variable or array. */
    char *name2;		/* Name of element within array;  NULL means
				 * scalar variable is being referenced. */
    int flags;			/* OR-ed bits giving operation and other
				 * information. */
{
    Tcl_SavedResult state;
    TraceVarInfo *tvarPtr = (TraceVarInfo *) clientData;
    char *result;
    int code;

    Tcl_DString cmd;


    result = NULL;
    if (tvarPtr->errMsg != NULL) {
	ckfree(tvarPtr->errMsg);
	tvarPtr->errMsg = NULL;
    }
    if ((tvarPtr->flags & flags) && !(flags & TCL_INTERP_DESTROYED)) {

	/*
	 * Generate a command to execute by appending list elements
	 * for the two variable names and the operation.  The five
	 * extra characters are for three space, the opcode character,
	 * and the terminating null.
	 */

	if (name2 == NULL) {
	    name2 = "";
	}
	Tcl_DStringInit(&cmd);
	Tcl_DStringAppend(&cmd, tvarPtr->command, (int) tvarPtr->length);
	Tcl_DStringAppendElement(&cmd, name1);
	Tcl_DStringAppendElement(&cmd, name2);
	if (flags & TCL_TRACE_READS) {
	    Tcl_DStringAppend(&cmd, " r", 2);
	} else if (flags & TCL_TRACE_WRITES) {
	    Tcl_DStringAppend(&cmd, " w", 2);
	} else if (flags & TCL_TRACE_UNSETS) {
	    Tcl_DStringAppend(&cmd, " u", 2);
	}

	/*
	 * Execute the command.  Save the interp's result used for

	 * the command. We discard any object result the command returns.
	 */














	Tcl_SaveResult(interp, &state);


	code = Tcl_Eval(interp, Tcl_DStringValue(&cmd));
	if (code != TCL_OK) {	     /* copy error msg to result */
	    char *string;
	    int length;
	    
	    string = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &length);
	    tvarPtr->errMsg = (char *) ckalloc((unsigned) (length + 1));

	    memcpy(tvarPtr->errMsg, string, (size_t) (length + 1));
	    result = tvarPtr->errMsg;

	}





	Tcl_RestoreResult(interp, &state);












	Tcl_DStringFree(&cmd);
    }
    if (flags & TCL_TRACE_DESTROYED) {
	result = NULL;
	if (tvarPtr->errMsg != NULL) {
	    ckfree(tvarPtr->errMsg);
	}
	ckfree((char *) tvarPtr);
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_WhileObjCmd --
 *
 *      This procedure is invoked to process the "while" Tcl command.
 *      See the user documentation for details on what it does.
 *
 *	With the bytecode compiler, this procedure is only called when
 *	a command name is computed at runtime, and is "while" or the name
 *	to which "while" was renamed: e.g., "set z while; $z {$i<100} {}"
 *
 * Results:
 *      A standard Tcl result.
 *
 * Side effects:
 *      See the user documentation.
 *
 *----------------------------------------------------------------------
 */

        /* ARGSUSED */
int
Tcl_WhileObjCmd(dummy, interp, objc, objv)
    ClientData dummy;                   /* Not used. */
    Tcl_Interp *interp;                 /* Current interpreter. */
    int objc;                           /* Number of arguments. */
    Tcl_Obj *CONST objv[];       	/* Argument objects. */
{
    int result, value;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "test command");

        return TCL_ERROR;
    }

    while (1) {
        result = Tcl_ExprBooleanObj(interp, objv[1], &value);
        if (result != TCL_OK) {
            return result;
        }
        if (!value) {
            break;
        }
        result = Tcl_EvalObjEx(interp, objv[2], 0);
        if ((result != TCL_OK) && (result != TCL_CONTINUE)) {
            if (result == TCL_ERROR) {
                char msg[32 + TCL_INTEGER_SPACE];

                sprintf(msg, "\n    (\"while\" body line %d)",
                        interp->errorLine);
                Tcl_AddErrorInfo(interp, msg);
            }
            break;
        }
    }

Added generic/tclCompCmds.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
/* 
 * tclCompCmds.c --
 *
 *	This file contains compilation procedures that compile various
 *	Tcl commands into a sequence of instructions ("bytecodes"). 
 *
 * 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: tclCompCmds.c,v 1.1.2.8 1999/02/10 23:31:14 stanton Exp $
 */

#include "tclInt.h"
#include "tclCompile.h"

/*
 * Prototypes for procedures defined later in this file:
 */

static ClientData	DupForeachInfo _ANSI_ARGS_((ClientData clientData));
static void		FreeForeachInfo _ANSI_ARGS_((
			    ClientData clientData));

/*
 * The structures below define the AuxData types defined in this file.
 */

AuxDataType tclForeachInfoType = {
    "ForeachInfo",				/* name */
    DupForeachInfo,				/* dupProc */
    FreeForeachInfo				/* freeProc */
};

/*
 *----------------------------------------------------------------------
 *
 * TclCompileBreakCmd --
 *
 *	Procedure called to compile the "break" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error during compilation. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "break" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileBreakCmd(interp, parsePtr, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Points to a parse structure for the
				 * command created by Tcl_ParseCommand. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    if (parsePtr->numWords != 1) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"break\"", -1);
	envPtr->maxStackDepth = 0;
	return TCL_ERROR;
    }

    /*
     * Emit a break instruction.
     */

    TclEmitOpcode(INST_BREAK, envPtr);
    envPtr->maxStackDepth = 0;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileCatchCmd --
 *
 *	Procedure called to compile the "catch" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK if
 *	compilation was successful. If an error occurs then the
 *	interpreter's result contains a standard error message and TCL_ERROR
 *	is returned. If the command is too complex for TclCompileCatchCmd,
 *	TCL_OUT_LINE_COMPILE is returned indicating that the catch command
 *	should be compiled "out of line" by emitting code to invoke its
 *	command procedure at runtime.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "catch" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileCatchCmd(interp, parsePtr, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Points to a parse structure for the
				 * command created by Tcl_ParseCommand. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    JumpFixup jumpFixup;
    Tcl_Token *cmdTokenPtr, *nameTokenPtr;
    char *name;
    int localIndex, nameChars, range, maxDepth, startOffset, jumpDist;
    int code;
    char buffer[32 + TCL_INTEGER_SPACE];

    envPtr->maxStackDepth = 0;
    if ((parsePtr->numWords != 2) && (parsePtr->numWords != 3)) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"catch command ?varName?\"", -1);
	return TCL_ERROR;
    }

    /*
     * If a variable was specified and the catch command is at global level
     * (not in a procedure), don't compile it inline: the payoff is
     * too small.
     */

    if ((parsePtr->numWords == 3) && (envPtr->procPtr == NULL)) {
	return TCL_OUT_LINE_COMPILE;
    }

    /*
     * Make sure the variable name, if any, has no substitutions and just
     * refers to a local scaler.
     */

    localIndex = -1;
    cmdTokenPtr = parsePtr->tokenPtr
	    + (parsePtr->tokenPtr->numComponents + 1);
    if (parsePtr->numWords == 3) {
	nameTokenPtr = cmdTokenPtr + (cmdTokenPtr->numComponents + 1);
	if (nameTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
	    name = nameTokenPtr[1].start;
	    nameChars = nameTokenPtr[1].size;
	    if (!TclIsLocalScalar(name, nameChars)) {
		return TCL_OUT_LINE_COMPILE;
	    }
	    localIndex = TclFindCompiledLocal(nameTokenPtr[1].start,
		    nameTokenPtr[1].size, /*create*/ 1, 
		    /*flags*/ VAR_SCALAR, envPtr->procPtr);
	} else {
	   return TCL_OUT_LINE_COMPILE;
	}
    }

    /*
     * We will compile the catch command. Emit a beginCatch instruction at
     * the start of the catch body: the subcommand it controls.
     */

    maxDepth = 0;
    
    envPtr->exceptDepth++;
    envPtr->maxExceptDepth =
	TclMax(envPtr->exceptDepth, envPtr->maxExceptDepth);
    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
    TclEmitInstInt4(INST_BEGIN_CATCH4, range, envPtr);

    startOffset = (envPtr->codeNext - envPtr->codeStart);
    envPtr->exceptArrayPtr[range].codeOffset = startOffset;
    code = TclCompileCmdWord(interp, cmdTokenPtr+1,
	    cmdTokenPtr->numComponents, envPtr);
    if (code != TCL_OK) {
	if (code == TCL_ERROR) {
	    sprintf(buffer, "\n    (\"catch\" body line %d)",
		    interp->errorLine);
            Tcl_AddObjErrorInfo(interp, buffer, -1);
        }
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;
    envPtr->exceptArrayPtr[range].numCodeBytes =
	    (envPtr->codeNext - envPtr->codeStart) - startOffset;
		    
    /*
     * The "no errors" epilogue code: store the body's result into the
     * variable (if any), push "0" (TCL_OK) as the catch's "no error"
     * result, and jump around the "error case" code.
     */

    if (localIndex != -1) {
	if (localIndex <= 255) {
	    TclEmitInstInt1(INST_STORE_SCALAR1, localIndex, envPtr);
	} else {
	    TclEmitInstInt4(INST_STORE_SCALAR4, localIndex, envPtr);
	}
    }
    TclEmitOpcode(INST_POP, envPtr);
    TclEmitPush(TclRegisterLiteral(envPtr, "0", 1, /*onHeap*/ 0),
	    envPtr);
    if (maxDepth == 0) {
	maxDepth = 1;
    }
    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);

    /*
     * The "error case" code: store the body's result into the variable (if
     * any), then push the error result code. The initial PC offset here is
     * the catch's error target.
     */

    envPtr->exceptArrayPtr[range].catchOffset =
	    (envPtr->codeNext - envPtr->codeStart);
    if (localIndex != -1) {
	TclEmitOpcode(INST_PUSH_RESULT, envPtr);
	if (localIndex <= 255) {
	    TclEmitInstInt1(INST_STORE_SCALAR1, localIndex, envPtr);
	} else {
	    TclEmitInstInt4(INST_STORE_SCALAR4, localIndex, envPtr);
	}
	TclEmitOpcode(INST_POP, envPtr);
    }
    TclEmitOpcode(INST_PUSH_RETURN_CODE, envPtr);

    /*
     * Update the target of the jump after the "no errors" code, then emit
     * an endCatch instruction at the end of the catch command.
     */

    jumpDist = (envPtr->codeNext - envPtr->codeStart)
	    - jumpFixup.codeOffset;
    if (TclFixupForwardJump(envPtr, &jumpFixup, jumpDist, 127)) {
	panic("TclCompileCatchCmd: bad jump distance %d\n", jumpDist);
    }
    TclEmitOpcode(INST_END_CATCH, envPtr);

    done:
    envPtr->exceptDepth--;
    envPtr->maxStackDepth = maxDepth;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileContinueCmd --
 *
 *	Procedure called to compile the "continue" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while parsing string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "continue" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileContinueCmd(interp, parsePtr, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Points to a parse structure for the
				 * command created by Tcl_ParseCommand. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    /*
     * There should be no argument after the "continue".
     */

    if (parsePtr->numWords != 1) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"continue\"", -1);
	envPtr->maxStackDepth = 0;
	return TCL_ERROR;
    }

    /*
     * Emit a continue instruction.
     */

    TclEmitOpcode(INST_CONTINUE, envPtr);
    envPtr->maxStackDepth = 0;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileExprCmd --
 *
 *	Procedure called to compile the "expr" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK
 *	unless there was an error while parsing string. If an error occurs
 *	then the interpreter's result contains a standard error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the "expr" command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "expr" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileExprCmd(interp, parsePtr, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Points to a parse structure for the
				 * command created by Tcl_ParseCommand. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Tcl_Token *firstWordPtr;

    envPtr->maxStackDepth = 0;
    if (parsePtr->numWords == 1) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"expr arg ?arg ...?\"", -1);
        return TCL_ERROR;
    }

    firstWordPtr = parsePtr->tokenPtr
	    + (parsePtr->tokenPtr->numComponents + 1);
    return TclCompileExprWords(interp, firstWordPtr, (parsePtr->numWords-1),
	    envPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileForCmd --
 *
 *	Procedure called to compile the "for" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while parsing string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "for" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileForCmd(interp, parsePtr, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Points to a parse structure for the
				 * command created by Tcl_ParseCommand. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Tcl_Token *startTokenPtr, *testTokenPtr, *nextTokenPtr, *bodyTokenPtr;
    JumpFixup jumpFalseFixup;
    int maxDepth, jumpBackDist, jumpBackOffset, testCodeOffset, jumpDist;
    int bodyRange, nextRange, code;
    unsigned char *jumpPc;
    char buffer[32 + TCL_INTEGER_SPACE];

    envPtr->maxStackDepth = 0;
    if (parsePtr->numWords != 5) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"for start test next command\"", -1);
	return TCL_ERROR;
    }

    /*
     * If the test expression requires substitutions, don't compile the for
     * command inline. E.g., the expression might cause the loop to never
     * execute or execute forever, as in "for {} "$x > 5" {incr x} {}".
     */

    startTokenPtr = parsePtr->tokenPtr
	    + (parsePtr->tokenPtr->numComponents + 1);
    testTokenPtr = startTokenPtr + (startTokenPtr->numComponents + 1);
    if (testTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
	return TCL_OUT_LINE_COMPILE;
    }

    /*
     * Create ExceptionRange records for the body and the "next" command.
     * The "next" command's ExceptionRange supports break but not continue
     * (and has a -1 continueOffset).
     */

    envPtr->exceptDepth++;
    envPtr->maxExceptDepth =
	    TclMax(envPtr->exceptDepth, envPtr->maxExceptDepth);
    bodyRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
    nextRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);

    /*
     * Inline compile the initial command.
     */

    maxDepth = 0;
    code = TclCompileCmdWord(interp, startTokenPtr+1,
	    startTokenPtr->numComponents, envPtr);
    if (code != TCL_OK) {
	if (code == TCL_ERROR) {
            Tcl_AddObjErrorInfo(interp,
	            "\n    (\"for\" initial command)", -1);
        }
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;
    TclEmitOpcode(INST_POP, envPtr);
    
    /*
     * Compile the test then emit the conditional jump that exits the for.
     */

    testCodeOffset = (envPtr->codeNext - envPtr->codeStart);
    code = TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
    if (code != TCL_OK) {
	if (code == TCL_ERROR) {
            Tcl_AddObjErrorInfo(interp,
		    "\n    (\"for\" test expression)", -1);
        }
	goto done;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
    TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFalseFixup);

    /*
     * Compile the loop body.
     */

    nextTokenPtr = testTokenPtr + (testTokenPtr->numComponents + 1);
    bodyTokenPtr = nextTokenPtr + (nextTokenPtr->numComponents + 1);
    envPtr->exceptArrayPtr[bodyRange].codeOffset =
	    (envPtr->codeNext - envPtr->codeStart);
    code = TclCompileCmdWord(interp, bodyTokenPtr+1,
	    bodyTokenPtr->numComponents, envPtr);
    if (code != TCL_OK) {
	if (code == TCL_ERROR) {
	    sprintf(buffer, "\n    (\"for\" body line %d)",
		    interp->errorLine);
            Tcl_AddObjErrorInfo(interp, buffer, -1);
        }
	goto done;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
    envPtr->exceptArrayPtr[bodyRange].numCodeBytes =
	    (envPtr->codeNext - envPtr->codeStart)
	    - envPtr->exceptArrayPtr[bodyRange].codeOffset;
    TclEmitOpcode(INST_POP, envPtr);

    /*
     * Compile the "next" subcommand.
     */

    envPtr->exceptArrayPtr[bodyRange].continueOffset =
	    (envPtr->codeNext - envPtr->codeStart);
    envPtr->exceptArrayPtr[nextRange].codeOffset =
	    (envPtr->codeNext - envPtr->codeStart);
    code = TclCompileCmdWord(interp, nextTokenPtr+1,
	    nextTokenPtr->numComponents, envPtr);
    if (code != TCL_OK) {
	if (code == TCL_ERROR) {
	    Tcl_AddObjErrorInfo(interp,
	            "\n    (\"for\" loop-end command)", -1);
	}
	goto done;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
    envPtr->exceptArrayPtr[nextRange].numCodeBytes =
	    (envPtr->codeNext - envPtr->codeStart)
	    - envPtr->exceptArrayPtr[nextRange].codeOffset;
    TclEmitOpcode(INST_POP, envPtr);
	
    /*
     * Jump back to the test at the top of the loop. Generate a 4 byte jump
     * if the distance to the test is > 120 bytes. This is conservative and
     * ensures that we won't have to replace this jump if we later need to
     * replace the ifFalse jump with a 4 byte jump.
     */

    jumpBackOffset = (envPtr->codeNext - envPtr->codeStart);
    jumpBackDist = (jumpBackOffset - testCodeOffset);
    if (jumpBackDist > 120) {
	TclEmitInstInt4(INST_JUMP4, -jumpBackDist, envPtr);
    } else {
	TclEmitInstInt1(INST_JUMP1, -jumpBackDist, envPtr);
    }

    /*
     * Fix the target of the jumpFalse after the test.
     */

    jumpDist = (envPtr->codeNext - envPtr->codeStart)
	    - jumpFalseFixup.codeOffset;
    if (TclFixupForwardJump(envPtr, &jumpFalseFixup, jumpDist, 127)) {
	/*
	 * Update the loop body and "next" command ExceptionRanges since
	 * they moved down.
	 */

	envPtr->exceptArrayPtr[bodyRange].codeOffset += 3;
	envPtr->exceptArrayPtr[bodyRange].continueOffset += 3;
	envPtr->exceptArrayPtr[nextRange].codeOffset += 3;

	/*
	 * Update the jump back to the test at the top of the loop since it
	 * also moved down 3 bytes.
	 */

	jumpBackOffset += 3;
	jumpPc = (envPtr->codeStart + jumpBackOffset);
	jumpBackDist += 3;
	if (jumpBackDist > 120) {
	    TclUpdateInstInt4AtPc(INST_JUMP4, -jumpBackDist, jumpPc);
	} else {
	    TclUpdateInstInt1AtPc(INST_JUMP1, -jumpBackDist, jumpPc);
	}
    }
    
    /*
     * Set the loop's break target.
     */

    envPtr->exceptArrayPtr[bodyRange].breakOffset =
            envPtr->exceptArrayPtr[nextRange].breakOffset =
	    (envPtr->codeNext - envPtr->codeStart);
    
    /*
     * The for command's result is an empty string.
     */

    TclEmitPush(TclRegisterLiteral(envPtr, "", 0, /*onHeap*/ 0), envPtr);
    if (maxDepth == 0) {
	maxDepth = 1;
    }
    code = TCL_OK;

    done:
    envPtr->maxStackDepth = maxDepth;
    envPtr->exceptDepth--;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileForeachCmd --
 *
 *	Procedure called to compile the "foreach" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK if
 *	compilation was successful. If an error occurs then the
 *	interpreter's result contains a standard error message and TCL_ERROR
 *	is returned. If the command is too complex for TclCompileForeachCmd,
 *	TCL_OUT_LINE_COMPILE is returned indicating that the foreach command
 *	should be compiled "out of line" by emitting code to invoke its
 *	command procedure at runtime.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the "while" command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "foreach" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileForeachCmd(interp, parsePtr, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Points to a parse structure for the
				 * command created by Tcl_ParseCommand. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Proc *procPtr = envPtr->procPtr;
    ForeachInfo *infoPtr;	/* Points to the structure describing this
				 * foreach command. Stored in a AuxData
				 * record in the ByteCode. */
    int firstValueTemp;		/* Index of the first temp var in the frame
				 * used to point to a value list. */
    int loopCtTemp;		/* Index of temp var holding the loop's
				 * iteration count. */
    Tcl_Token *tokenPtr, *bodyTokenPtr;
    char *varList;
    unsigned char *jumpPc;
    JumpFixup jumpFalseFixup;
    int jumpDist, jumpBackDist, jumpBackOffset, maxDepth, infoIndex, range;
    int numWords, numLists, numVars, loopIndex, tempVar, i, j, code;
    char savedChar;
    char buffer[32 + TCL_INTEGER_SPACE];

    /*
     * We parse the variable list argument words and create two arrays:
     *    varcList[i] is number of variables in i-th var list
     *    varvList[i] points to array of var names in i-th var list
     */

#define STATIC_VAR_LIST_SIZE 5
    int varcListStaticSpace[STATIC_VAR_LIST_SIZE];
    char **varvListStaticSpace[STATIC_VAR_LIST_SIZE];
    int *varcList = varcListStaticSpace;
    char ***varvList = varvListStaticSpace;

    /*
     * If the foreach command isn't in a procedure, don't compile it inline:
     * the payoff is too small.
     */

    envPtr->maxStackDepth = 0;
    if (procPtr == NULL) {
	return TCL_OUT_LINE_COMPILE;
    }

    maxDepth = 0;
    
    numWords = parsePtr->numWords;
    if ((numWords < 4) || (numWords%2 != 0)) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"foreach varList list ?varList list ...? command\"", -1);
        return TCL_ERROR;
    }

    /*
     * Allocate storage for the varcList and varvList arrays if necessary.
     */

    numLists = (numWords - 2)/2;
    if (numLists > STATIC_VAR_LIST_SIZE) {
        varcList = (int *) ckalloc(numLists * sizeof(int));
        varvList = (char ***) ckalloc(numLists * sizeof(char **));
    }
    for (loopIndex = 0;  loopIndex < numLists;  loopIndex++) {
        varcList[loopIndex] = 0;
        varvList[loopIndex] = (char **) NULL;
    }
    
    /*
     * Set the exception stack depth.
     */ 

    envPtr->exceptDepth++;
    envPtr->maxExceptDepth =
	TclMax(envPtr->exceptDepth, envPtr->maxExceptDepth);

    /*
     * Break up each var list and set the varcList and varvList arrays.
     * Don't compile the foreach inline if any var name needs substitutions
     * or isn't a scalar, or if any var list needs substitutions.
     */

    loopIndex = 0;
    for (i = 0, tokenPtr = parsePtr->tokenPtr;
	    i < numWords-1;
	    i++, tokenPtr += (tokenPtr->numComponents + 1)) {
	if (i%2 == 1) {
	    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
		code = TCL_OUT_LINE_COMPILE;
		goto done;
	    }
	    varList = tokenPtr[1].start;
	    savedChar = varList[tokenPtr[1].size];

	    /*
	     * Note there is a danger that modifying the string could have
	     * undesirable side effects.  In this case, Tcl_SplitList does
	     * not have any dependencies on shared strings so we should be
	     * safe.
	     */

	    varList[tokenPtr[1].size] = '\0';
	    code = Tcl_SplitList(interp, varList,
		    &varcList[loopIndex], &varvList[loopIndex]);
	    varList[tokenPtr[1].size] = savedChar;
	    if (code != TCL_OK) {
		goto done;
	    }

	    numVars = varcList[loopIndex];
	    for (j = 0;  j < numVars;  j++) {
		char *varName = varvList[loopIndex][j];
		if (!TclIsLocalScalar(varName, (int) strlen(varName))) {
		    code = TCL_OUT_LINE_COMPILE;
		    goto done;
		}
	    }
	    loopIndex++;
	}
    }

    /*
     * We will compile the foreach command.
     * Reserve (numLists + 1) temporary variables:
     *    - numLists temps to hold each value list
     *    - 1 temp for the loop counter (index of next element in each list)
     * At this time we don't try to reuse temporaries; if there are two
     * nonoverlapping foreach loops, they don't share any temps.
     */

    firstValueTemp = -1;
    for (loopIndex = 0;  loopIndex < numLists;  loopIndex++) {
	tempVar = TclFindCompiledLocal(NULL, /*nameChars*/ 0,
		/*create*/ 1, /*flags*/ VAR_SCALAR, procPtr);
	if (loopIndex == 0) {
	    firstValueTemp = tempVar;
	}
    }
    loopCtTemp = TclFindCompiledLocal(NULL, /*nameChars*/ 0,
	    /*create*/ 1, /*flags*/ VAR_SCALAR, procPtr);
    
    /*
     * Create and initialize the ForeachInfo and ForeachVarList data
     * structures describing this command. Then create a AuxData record
     * pointing to the ForeachInfo structure.
     */

    infoPtr = (ForeachInfo *) ckalloc((unsigned)
	    (sizeof(ForeachInfo) + (numLists * sizeof(ForeachVarList *))));
    infoPtr->numLists = numLists;
    infoPtr->firstValueTemp = firstValueTemp;
    infoPtr->loopCtTemp = loopCtTemp;
    for (loopIndex = 0;  loopIndex < numLists;  loopIndex++) {
	ForeachVarList *varListPtr;
	numVars = varcList[loopIndex];
	varListPtr = (ForeachVarList *) ckalloc((unsigned)
	        sizeof(ForeachVarList) + (numVars * sizeof(int)));
	varListPtr->numVars = numVars;
	for (j = 0;  j < numVars;  j++) {
	    char *varName = varvList[loopIndex][j];
	    int nameChars = strlen(varName);
	    varListPtr->varIndexes[j] = TclFindCompiledLocal(varName,
		    nameChars, /*create*/ 1, /*flags*/ VAR_SCALAR, procPtr);
	}
	infoPtr->varLists[loopIndex] = varListPtr;
    }
    infoIndex = TclCreateAuxData((ClientData) infoPtr, &tclForeachInfoType, envPtr);

    /*
     * Evaluate then store each value list in the associated temporary.
     */

    range = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
    
    loopIndex = 0;
    for (i = 0, tokenPtr = parsePtr->tokenPtr;
	    i < numWords-1;
	    i++, tokenPtr += (tokenPtr->numComponents + 1)) {
	if ((i%2 == 0) && (i > 0)) {
	    code = TclCompileTokens(interp, tokenPtr+1,
		    tokenPtr->numComponents, envPtr);
	    if (code != TCL_OK) {
		goto done;
	    }
	    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);

	    tempVar = (firstValueTemp + loopIndex);
	    if (tempVar <= 255) {
		TclEmitInstInt1(INST_STORE_SCALAR1, tempVar, envPtr);
	    } else {
		TclEmitInstInt4(INST_STORE_SCALAR4, tempVar, envPtr);
	    }
	    TclEmitOpcode(INST_POP, envPtr);
	    loopIndex++;
	}
    }
    bodyTokenPtr = tokenPtr;

    /*
     * Initialize the temporary var that holds the count of loop iterations.
     */

    TclEmitInstInt4(INST_FOREACH_START4, infoIndex, envPtr);
    
    /*
     * Top of loop code: assign each loop variable and check whether
     * to terminate the loop.
     */

    envPtr->exceptArrayPtr[range].continueOffset =
	    (envPtr->codeNext - envPtr->codeStart);
    TclEmitInstInt4(INST_FOREACH_STEP4, infoIndex, envPtr);
    TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFalseFixup);
    
    /*
     * Inline compile the loop body.
     */

    envPtr->exceptArrayPtr[range].codeOffset =
	    (envPtr->codeNext - envPtr->codeStart);
    code = TclCompileCmdWord(interp, bodyTokenPtr+1,
	    bodyTokenPtr->numComponents, envPtr);
    if (code != TCL_OK) {
	if (code == TCL_ERROR) {
	    sprintf(buffer, "\n    (\"foreach\" body line %d)",
		    interp->errorLine);
            Tcl_AddObjErrorInfo(interp, buffer, -1);
        }
	goto done;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
    envPtr->exceptArrayPtr[range].numCodeBytes =
	    (envPtr->codeNext - envPtr->codeStart)
	    - envPtr->exceptArrayPtr[range].codeOffset;
    TclEmitOpcode(INST_POP, envPtr);
	
    /*
     * Jump back to the test at the top of the loop. Generate a 4 byte jump
     * if the distance to the test is > 120 bytes. This is conservative and
     * ensures that we won't have to replace this jump if we later need to
     * replace the ifFalse jump with a 4 byte jump.
     */

    jumpBackOffset = (envPtr->codeNext - envPtr->codeStart);
    jumpBackDist =
	(jumpBackOffset - envPtr->exceptArrayPtr[range].continueOffset);
    if (jumpBackDist > 120) {
	TclEmitInstInt4(INST_JUMP4, -jumpBackDist, envPtr);
    } else {
	TclEmitInstInt1(INST_JUMP1, -jumpBackDist, envPtr);
    }

    /*
     * Fix the target of the jump after the foreach_step test.
     */

    jumpDist = (envPtr->codeNext - envPtr->codeStart)
	    - jumpFalseFixup.codeOffset;
    if (TclFixupForwardJump(envPtr, &jumpFalseFixup, jumpDist, 127)) {
	/*
	 * Update the loop body's starting PC offset since it moved down.
	 */

	envPtr->exceptArrayPtr[range].codeOffset += 3;

	/*
	 * Update the jump back to the test at the top of the loop since it
	 * also moved down 3 bytes.
	 */

	jumpBackOffset += 3;
	jumpPc = (envPtr->codeStart + jumpBackOffset);
	jumpBackDist += 3;
	if (jumpBackDist > 120) {
	    TclUpdateInstInt4AtPc(INST_JUMP4, -jumpBackDist, jumpPc);
	} else {
	    TclUpdateInstInt1AtPc(INST_JUMP1, -jumpBackDist, jumpPc);
	}
    }

    /*
     * Set the loop's break target.
     */

    envPtr->exceptArrayPtr[range].breakOffset =
	    (envPtr->codeNext - envPtr->codeStart);
    
    /*
     * The foreach command's result is an empty string.
     */

    TclEmitPush(TclRegisterLiteral(envPtr, "", 0, /*onHeap*/ 0), envPtr);
    if (maxDepth == 0) {
	maxDepth = 1;
    }

    done:
    for (loopIndex = 0;  loopIndex < numLists;  loopIndex++) {
        if (varvList[loopIndex] != (char **) NULL) {
            ckfree((char *) varvList[loopIndex]);
        }
    }
    if (varcList != varcListStaticSpace) {
	ckfree((char *) varcList);
        ckfree((char *) varvList);
    }
    envPtr->maxStackDepth = maxDepth;
    envPtr->exceptDepth--;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * DupForeachInfo --
 *
 *	This procedure duplicates a ForeachInfo structure created as
 *	auxiliary data during the compilation of a foreach command.
 *
 * Results:
 *	A pointer to a newly allocated copy of the existing ForeachInfo
 *	structure is returned.
 *
 * Side effects:
 *	Storage for the copied ForeachInfo record is allocated. If the
 *	original ForeachInfo structure pointed to any ForeachVarList
 *	records, these structures are also copied and pointers to them
 *	are stored in the new ForeachInfo record.
 *
 *----------------------------------------------------------------------
 */

static ClientData
DupForeachInfo(clientData)
    ClientData clientData;	/* The foreach command's compilation
				 * auxiliary data to duplicate. */
{
    register ForeachInfo *srcPtr = (ForeachInfo *) clientData;
    ForeachInfo *dupPtr;
    register ForeachVarList *srcListPtr, *dupListPtr;
    int numLists = srcPtr->numLists;
    int numVars, i, j;
    
    dupPtr = (ForeachInfo *) ckalloc((unsigned)
	    (sizeof(ForeachInfo) + (numLists * sizeof(ForeachVarList *))));
    dupPtr->numLists = numLists;
    dupPtr->firstValueTemp = srcPtr->firstValueTemp;
    dupPtr->loopCtTemp = srcPtr->loopCtTemp;
    
    for (i = 0;  i < numLists;  i++) {
	srcListPtr = srcPtr->varLists[i];
	numVars = srcListPtr->numVars;
	dupListPtr = (ForeachVarList *) ckalloc((unsigned)
	        sizeof(ForeachVarList) + numVars*sizeof(int));
	dupListPtr->numVars = numVars;
	for (j = 0;  j < numVars;  j++) {
	    dupListPtr->varIndexes[j] =	srcListPtr->varIndexes[j];
	}
	dupPtr->varLists[i] = dupListPtr;
    }
    return (ClientData) dupPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeForeachInfo --
 *
 *	Procedure to free a ForeachInfo structure created as auxiliary data
 *	during the compilation of a foreach command.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Storage for the ForeachInfo structure pointed to by the ClientData
 *	argument is freed as is any ForeachVarList record pointed to by the
 *	ForeachInfo structure.
 *
 *----------------------------------------------------------------------
 */

static void
FreeForeachInfo(clientData)
    ClientData clientData;	/* The foreach command's compilation
				 * auxiliary data to free. */
{
    register ForeachInfo *infoPtr = (ForeachInfo *) clientData;
    register ForeachVarList *listPtr;
    int numLists = infoPtr->numLists;
    register int i;

    for (i = 0;  i < numLists;  i++) {
	listPtr = infoPtr->varLists[i];
	ckfree((char *) listPtr);
    }
    ckfree((char *) infoPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileIfCmd --
 *
 *	Procedure called to compile the "if" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK if
 *	compilation was successful. If an error occurs then the
 *	interpreter's result contains a standard error message and TCL_ERROR
 *	is returned. If the command is too complex for TclCompileIfCmd,
 *	TCL_OUT_LINE_COMPILE is returned indicating that the if command
 *	should be compiled "out of line" by emitting code to invoke its
 *	command procedure at runtime.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "if" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileIfCmd(interp, parsePtr, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Points to a parse structure for the
				 * command created by Tcl_ParseCommand. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    JumpFixupArray jumpFalseFixupArray;
    				/* Used to fix the ifFalse jump after each
				 * test when its target PC is determined. */
    JumpFixupArray jumpEndFixupArray;
				/* Used to fix the jump after each "then"
				 * body to the end of the "if" when that PC
				 * is determined. */
    Tcl_Token *tokenPtr, *testTokenPtr;
    int jumpDist, jumpFalseDist, jumpIndex;
    int numWords, wordIdx, numBytes, maxDepth, j, code;
    char *word;
    char buffer[100];

    TclInitJumpFixupArray(&jumpFalseFixupArray);
    TclInitJumpFixupArray(&jumpEndFixupArray);
    maxDepth = 0;
    code = TCL_OK;

    /*
     * Each iteration of this loop compiles one "if expr ?then? body"
     * or "elseif expr ?then? body" clause. 
     */

    tokenPtr = parsePtr->tokenPtr;
    wordIdx = 0;
    numWords = parsePtr->numWords;
    while (wordIdx < numWords) {
	/*
	 * Stop looping if the token isn't "if" or "elseif".
	 */

	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
	    break;
	}
	word = tokenPtr[1].start;
	numBytes = tokenPtr[1].size;
	if ((tokenPtr == parsePtr->tokenPtr)
	        || ((numBytes == 6) && (strncmp(word, "elseif", 6) == 0))) {
	    tokenPtr += (tokenPtr->numComponents + 1);
	    wordIdx++;
	} else {
	    break;
	}
	if (wordIdx >= numWords) {
	    sprintf(buffer,
	            "wrong # args: no expression after \"%.30s\" argument",
		    word);
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), buffer, -1);
	    code = TCL_ERROR;
	    goto done;
	}

	/*
	 * Compile the test expression then emit the conditional jump
	 * around the "then" part. If the expression word isn't simple,
	 * we back off and compile the if command out-of-line.
	 */
	
	testTokenPtr = tokenPtr;
	code = TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
	if (code != TCL_OK) {
	    if (code == TCL_ERROR) {
		Tcl_AddObjErrorInfo(interp,
		        "\n    (\"if\" test expression)", -1);
	    }
	    goto done;
	}
	maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
	if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) {
	    TclExpandJumpFixupArray(&jumpFalseFixupArray);
	}
	jumpIndex = jumpFalseFixupArray.next;
	jumpFalseFixupArray.next++;
	TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,
		&(jumpFalseFixupArray.fixup[jumpIndex]));
	
	/*
	 * Skip over the optional "then" before the then clause.
	 */

	tokenPtr = testTokenPtr + (testTokenPtr->numComponents + 1);
	wordIdx++;
	if (wordIdx >= numWords) {
	    sprintf(buffer, "wrong # args: no script following \"%.20s\" argument", testTokenPtr->start);
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), buffer, -1);
	    code = TCL_ERROR;
	    goto done;
	}
	if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
	    word = tokenPtr[1].start;
	    numBytes = tokenPtr[1].size;
	    if ((numBytes == 4) && (strncmp(word, "then", 4) == 0)) {
		tokenPtr += (tokenPtr->numComponents + 1);
		wordIdx++;
		if (wordIdx >= numWords) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "wrong # args: no script following \"then\" argument", -1);
		    code = TCL_ERROR;
		    goto done;
		}
	    }
	}

	/*
	 * Compile the "then" command body.
	 */

	code = TclCompileCmdWord(interp, tokenPtr+1,
		tokenPtr->numComponents, envPtr);
	if (code != TCL_OK) {
	    if (code == TCL_ERROR) {
		sprintf(buffer, "\n    (\"if\" then script line %d)",
		        interp->errorLine);
		Tcl_AddObjErrorInfo(interp, buffer, -1);
	    }
	    goto done;
	}
	maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);

	/*
	 * Jump to the end of the "if" command. Both jumpFalseFixupArray and
	 * jumpEndFixupArray are indexed by "jumpIndex".
	 */

	if (jumpEndFixupArray.next >= jumpEndFixupArray.end) {
	    TclExpandJumpFixupArray(&jumpEndFixupArray);
	}
	jumpEndFixupArray.next++;
	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
		&(jumpEndFixupArray.fixup[jumpIndex]));

 	/*
	 * Fix the target of the jumpFalse after the test. Generate a 4 byte
	 * jump if the distance is > 120 bytes. This is conservative, and
	 * ensures that we won't have to replace this jump if we later also
	 * need to replace the proceeding jump to the end of the "if" with a
	 * 4 byte jump.
	 */

	jumpDist = (envPtr->codeNext - envPtr->codeStart)
	        - jumpFalseFixupArray.fixup[jumpIndex].codeOffset;
	if (TclFixupForwardJump(envPtr,
	        &(jumpFalseFixupArray.fixup[jumpIndex]), jumpDist, 120)) {
	    /*
	     * Adjust the code offset for the proceeding jump to the end
	     * of the "if" command.
	     */

	    jumpEndFixupArray.fixup[jumpIndex].codeOffset += 3;
	}

	tokenPtr += (tokenPtr->numComponents + 1);
	wordIdx++;
    }

    /*
     * Check for the optional else clause.
     */

    if ((wordIdx < numWords)
	    && (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD)) {
	/*
	 * There is an else clause. Skip over the optional "else" word.
	 */
	
	word = tokenPtr[1].start;
	numBytes = tokenPtr[1].size;
	if ((numBytes == 4) && (strncmp(word, "else", 4) == 0)) {
	    tokenPtr += (tokenPtr->numComponents + 1);
	    wordIdx++;
	    if (wordIdx >= numWords) {
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "wrong # args: no script following \"else\" argument", -1);
		code = TCL_ERROR;
		goto done;
	    }
	}

	/*
	 * Compile the else command body.
	 */
	
	code = TclCompileCmdWord(interp, tokenPtr+1,
		tokenPtr->numComponents, envPtr);
	if (code != TCL_OK) {
	    if (code == TCL_ERROR) {
		sprintf(buffer, "\n    (\"if\" else script line %d)",
			interp->errorLine);
		Tcl_AddObjErrorInfo(interp, buffer, -1);
	    }
	    goto done;
	}
	maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);

	/*
	 * Make sure there are no words after the else clause.
	 */
	
	wordIdx++;
	if (wordIdx < numWords) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		    "wrong # args: extra words after \"else\" clause in \"if\" command", -1);
	    code = TCL_ERROR;
	    goto done;
	}
    } else {
	/*
	 * No else clause: the "if" command's result is an empty string.
	 */

	TclEmitPush(TclRegisterLiteral(envPtr, "", 0,/*onHeap*/ 0), envPtr);
	maxDepth = TclMax(1, maxDepth);
    }

    /*
     * Fix the unconditional jumps to the end of the "if" command.
     */
    
    for (j = jumpEndFixupArray.next;  j > 0;  j--) {
	jumpIndex = (j - 1);	/* i.e. process the closest jump first */
	jumpDist = (envPtr->codeNext - envPtr->codeStart)
	        - jumpEndFixupArray.fixup[jumpIndex].codeOffset;
	if (TclFixupForwardJump(envPtr,
	        &(jumpEndFixupArray.fixup[jumpIndex]), jumpDist, 127)) {
	    /*
	     * Adjust the immediately preceeding "ifFalse" jump. We moved
	     * it's target (just after this jump) down three bytes.
	     */

	    unsigned char *ifFalsePc = envPtr->codeStart
	            + jumpFalseFixupArray.fixup[jumpIndex].codeOffset;
	    unsigned char opCode = *ifFalsePc;
	    if (opCode == INST_JUMP_FALSE1) {
		jumpFalseDist = TclGetInt1AtPtr(ifFalsePc + 1);
		jumpFalseDist += 3;
		TclStoreInt1AtPtr(jumpFalseDist, (ifFalsePc + 1));
	    } else if (opCode == INST_JUMP_FALSE4) {
		jumpFalseDist = TclGetInt4AtPtr(ifFalsePc + 1);
		jumpFalseDist += 3;
		TclStoreInt4AtPtr(jumpFalseDist, (ifFalsePc + 1));
	    } else {
		panic("TclCompileIfCmd: unexpected opcode updating ifFalse jump");
	    }
	}
    }
	
    /*
     * Free the jumpFixupArray array if malloc'ed storage was used.
     */

    done:
    TclFreeJumpFixupArray(&jumpFalseFixupArray);
    TclFreeJumpFixupArray(&jumpEndFixupArray);
    envPtr->maxStackDepth = maxDepth;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileIncrCmd --
 *
 *	Procedure called to compile the "incr" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK if
 *	compilation was successful. If an error occurs then the
 *	interpreter's result contains a standard error message and TCL_ERROR
 *	is returned. If the command is too complex for TclCompileIncrCmd,
 *	TCL_OUT_LINE_COMPILE is returned indicating that the incr command
 *	should be compiled "out of line" by emitting code to invoke its
 *	command procedure at runtime.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the "incr" command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "incr" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileIncrCmd(interp, parsePtr, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Points to a parse structure for the
				 * command created by Tcl_ParseCommand. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Tcl_Token *varTokenPtr, *incrTokenPtr;
    Tcl_Parse elemParse;
    int gotElemParse = 0;
    char *name, *elName, *p;
    int nameChars, elNameChars, haveImmValue, immValue, localIndex, i, code;
    int maxDepth = 0;
    char buffer[160];

    envPtr->maxStackDepth = 0;
    if ((parsePtr->numWords != 2) && (parsePtr->numWords != 3)) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"incr varName ?increment?\"", -1);
	return TCL_ERROR;
    }
    
    name = NULL;
    elName = NULL;
    elNameChars = 0;
    localIndex = -1;
    code = TCL_OK;

    varTokenPtr = parsePtr->tokenPtr
	    + (parsePtr->tokenPtr->numComponents + 1);
    if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
	/*
	 * A simple variable name. Divide it up into "name" and "elName"
	 * strings. If it is not a local variable, look it up at runtime.
	 */
	
	name = varTokenPtr[1].start;
	nameChars = varTokenPtr[1].size;
	for (i = 0, p = name;  i < nameChars;  i++, p++) {
	    if (*p == '(') {
		char *openParen = p;
		p = (name + nameChars-1);	
		if (*p == ')') { /* last char is ')' => array reference */
		    nameChars = (openParen - name);
		    elName = openParen+1;
		    elNameChars = (p - elName);
		}
		break;
	    }
	}
	if (envPtr->procPtr != NULL) {
	    localIndex = TclFindCompiledLocal(name, nameChars,
	            /*create*/ 0, /*flags*/ 0, envPtr->procPtr);
	    if (localIndex > 255) {	      /* we'll push the name */
		localIndex = -1;
	    }
	}
	if (localIndex < 0) {
	    TclEmitPush(TclRegisterLiteral(envPtr, name, nameChars,
			/*onHeap*/ 0), envPtr);
	    maxDepth = 1;
	}

	/*
	 * Compile the element script, if any.
	 */
	
	if (elName != NULL) {
	    /*
	     * Temporarily replace the '(' and ')' by '"'s.
	     */
	    
	    *(elName-1) = '"';
	    *(elName+elNameChars) = '"';
	    code = Tcl_ParseCommand(interp, elName-1, elNameChars+2,
                    /*nested*/ 0, &elemParse);
	    *(elName-1) = '(';
	    *(elName+elNameChars) = ')';
	    gotElemParse = 1;
	    if ((code != TCL_OK) || (elemParse.numWords > 1)) {
		sprintf(buffer, "\n    (parsing index for array \"%.*s\")",
			TclMin(nameChars, 100), name);
		Tcl_AddObjErrorInfo(interp, buffer, -1);
		code = TCL_ERROR;
		goto done;
	    } else if (elemParse.numWords == 1) {
		code = TclCompileTokens(interp, elemParse.tokenPtr+1,
                        elemParse.tokenPtr->numComponents, envPtr);
		if (code != TCL_OK) {
		    goto done;
		}
		maxDepth += envPtr->maxStackDepth;
	    } else {
		TclEmitPush(TclRegisterLiteral(envPtr, "", 0,
                        /*alreadyAlloced*/ 0), envPtr);
		maxDepth += 1;
	    }
	}
    } else {
	/*
	 * Not a simple variable name. Look it up at runtime.
	 */
	
	code = TclCompileTokens(interp, varTokenPtr+1,
	        varTokenPtr->numComponents, envPtr);
	if (code != TCL_OK) {
	    goto done;
	}
	maxDepth = envPtr->maxStackDepth;
    }
    
    /*
     * If an increment is given, push it, but see first if it's a small
     * integer.
     */

    haveImmValue = 0;
    immValue = 0;
    if (parsePtr->numWords == 3) {
	incrTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
	if (incrTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
	    char *word = incrTokenPtr[1].start;
	    int numBytes = incrTokenPtr[1].size;
	    char savedChar = word[numBytes];
	    long n;
	
	    /*
	     * Note there is a danger that modifying the string could have
	     * undesirable side effects.  In this case, TclLooksLikeInt and
	     * TclGetLong do not have any dependencies on shared strings so we
	     * should be safe.
	     */

	    word[numBytes] = '\0';
	    if (TclLooksLikeInt(word, numBytes)
		     && (TclGetLong((Tcl_Interp *) NULL, word, &n) == TCL_OK)) {
		if ((-127 <= n) && (n <= 127)) {
		    haveImmValue = 1;
		    immValue = n;
		}
	    }
	    word[numBytes] = savedChar;
	    if (!haveImmValue) {
		TclEmitPush(TclRegisterLiteral(envPtr, word, numBytes,
	               /*onHeap*/ 0), envPtr);
		maxDepth += 1;
	    }
	} else {
	    code = TclCompileTokens(interp, incrTokenPtr+1, 
	            incrTokenPtr->numComponents, envPtr);
	    if (code != TCL_OK) {
		if (code == TCL_ERROR) {
		    Tcl_AddObjErrorInfo(interp,
	                    "\n    (increment expression)", -1);
		}
		goto done;
	    }
	    maxDepth += envPtr->maxStackDepth;
	}
    } else {			/* no incr amount given so use 1 */
	haveImmValue = 1;
	immValue = 1;
    }
    
    /*
     * Emit the instruction to increment the variable.
     */

    if (name != NULL) {
	if (elName == NULL) {
	    if (localIndex >= 0) {
		if (haveImmValue) {
		    TclEmitInstInt1(INST_INCR_SCALAR1_IMM, localIndex,
				    envPtr);
		    TclEmitInt1(immValue, envPtr);
		} else {
		    TclEmitInstInt1(INST_INCR_SCALAR1, localIndex, envPtr);
		}
	    } else {
		if (haveImmValue) {
		    TclEmitInstInt1(INST_INCR_SCALAR_STK_IMM, immValue,
				   envPtr);
		} else {
		    TclEmitOpcode(INST_INCR_SCALAR_STK, envPtr);
		}
	    }
	} else {
	    if (localIndex >= 0) {
		if (haveImmValue) {
		    TclEmitInstInt1(INST_INCR_ARRAY1_IMM, localIndex,
				    envPtr);
		    TclEmitInt1(immValue, envPtr);
		} else {
		    TclEmitInstInt1(INST_INCR_ARRAY1, localIndex, envPtr);
		}
	    } else {
		if (haveImmValue) {
		    TclEmitInstInt1(INST_INCR_ARRAY_STK_IMM, immValue,
				   envPtr);
		} else {
		    TclEmitOpcode(INST_INCR_ARRAY_STK, envPtr);
		}
	    }
	}
    } else {			/* non-simple variable name */
	if (haveImmValue) {
	    TclEmitInstInt1(INST_INCR_STK_IMM, immValue, envPtr);
	} else {
	    TclEmitOpcode(INST_INCR_STK, envPtr);
	}
    }
	
    done:
    if (gotElemParse) {
        Tcl_FreeParse(&elemParse);
    }
    envPtr->maxStackDepth = maxDepth;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileSetCmd --
 *
 *	Procedure called to compile the "set" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is normally TCL_OK
 *	unless there was an error while parsing string. If an error occurs
 *	then the interpreter's result contains a standard error message. If
 *	complation fails because the set command requires a second level of
 *	substitutions, TCL_OUT_LINE_COMPILE is returned indicating that the
 *	set command should be compiled "out of line" by emitting code to
 *	invoke its command procedure (Tcl_SetCmd) at runtime.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the incr command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "set" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileSetCmd(interp, parsePtr, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Points to a parse structure for the
				 * command created by Tcl_ParseCommand. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Tcl_Token *varTokenPtr, *valueTokenPtr;
    Tcl_Parse elemParse;
    int gotElemParse = 0;
    register char *p;
    char *name, *elName;
    int nameChars, elNameChars;
    register int i;
    int isAssignment, simpleVarName, localIndex, numWords;
    int maxDepth = 0;
    int code = TCL_OK;

    envPtr->maxStackDepth = 0;
    numWords = parsePtr->numWords;
    if ((numWords != 2) && (numWords != 3)) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"set varName ?newValue?\"", -1);
        return TCL_ERROR;
    }
    isAssignment = (numWords == 3);

    /*
     * Decide if we can use a frame slot for the var/array name or if we
     * need to emit code to compute and push the name at runtime. We use a
     * frame slot (entry in the array of local vars) if we are compiling a
     * procedure body and if the name is simple text that does not include
     * namespace qualifiers. 
     */

    simpleVarName = 0;
    name = elName = NULL;
    nameChars = elNameChars = 0;
    localIndex = -1;

    varTokenPtr = parsePtr->tokenPtr
	    + (parsePtr->tokenPtr->numComponents + 1);
    if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
	simpleVarName = 1;
	name = varTokenPtr[1].start;
	nameChars = varTokenPtr[1].size;
	/* last char is ')' => potential array reference */
	if ( *(name + nameChars - 1) == ')') {
	    for (i = 0, p = name;  i < nameChars;  i++, p++) {
		if (*p == '(') {
		    elName = p + 1;
		    elNameChars = nameChars - i - 2;
		    nameChars = i ;
		    break;
		}
	    }
	}

	/*
	 * If elName contains any double quotes ("), we can't inline
	 * compile the element script using the replace '()' by '"'
	 * technique below.
	 */

	for (i = 0, p = elName;  i < elNameChars;  i++, p++) {
	    if (*p == '"') {
		simpleVarName = 0;
		break;
	    }
	}
    } else if ((varTokenPtr->numComponents == 4)
	    && (varTokenPtr[1].type == TCL_TOKEN_TEXT)
	    && (varTokenPtr[1].start[varTokenPtr[1].size-1] == '(')
	    && (varTokenPtr[4].type == TCL_TOKEN_TEXT)
	    && (varTokenPtr[4].size == 1)
	    && (varTokenPtr[4].start[0] == ')')) {
	simpleVarName = 1;
	name = varTokenPtr[1].start;
	nameChars = varTokenPtr[1].size - 1;
	elName = varTokenPtr[2].start;
	elNameChars = varTokenPtr[2].size;
    }

    if (simpleVarName) {
	/*
	 * See whether name has any namespace separators (::'s).
	 */

	int hasNsQualifiers = 0;
	for (i = 0, p = name;  i < nameChars;  i++, p++) {
	    if ((*p == ':') && ((i+1) < nameChars) && (*(p+1) == ':')) {
		hasNsQualifiers = 1;
		break;
	    }
	}
	
	/*
	 * Look up the var name's index in the array of local vars in the
	 * proc frame. If retrieving the var's value and it doesn't already
	 * exist, push its name and look it up at runtime.
	 */

	if ((envPtr->procPtr != NULL) && !hasNsQualifiers) {
	    localIndex = TclFindCompiledLocal(name, nameChars,
		    /*create*/ isAssignment,
                    /*flags*/ ((elName==NULL)? VAR_SCALAR : VAR_ARRAY),
		    envPtr->procPtr);
	}
	if (localIndex >= 0) {
	    maxDepth = 0;
	} else {
	    TclEmitPush(TclRegisterLiteral(envPtr, name, nameChars,
		    /*onHeap*/ 0), envPtr);
	    maxDepth = 1;
	}

	/*
	 * Compile the element script, if any.
	 */
	
	if (elName != NULL) {
	    /*
	     * Temporarily replace the '(' and ')' by '"'s.
	     */

	    *(elName-1) = '"';
	    *(elName+elNameChars) = '"';
	    code = Tcl_ParseCommand(interp, elName-1, elNameChars+2,
                    /*nested*/ 0, &elemParse);
	    *(elName-1) = '(';
	    *(elName+elNameChars) = ')';
	    gotElemParse = 1;
	    if ((code != TCL_OK) || (elemParse.numWords > 1)) {
		char buffer[160];
		sprintf(buffer, "\n    (parsing index for array \"%.*s\")",
		        TclMin(nameChars, 100), name);
		Tcl_AddObjErrorInfo(interp, buffer, -1);
		code = TCL_ERROR;
		goto done;
	    } else if (elemParse.numWords == 1) {
		code = TclCompileTokens(interp, elemParse.tokenPtr+1,
                        elemParse.tokenPtr->numComponents, envPtr);
		if (code != TCL_OK) {
		    goto done;
		}
		maxDepth += envPtr->maxStackDepth;
	    } else {
		TclEmitPush(TclRegisterLiteral(envPtr, "", 0,
                        /*alreadyAlloced*/ 0), envPtr);
		maxDepth += 1;
	    }
	}
    } else {
	/*
	 * The var name isn't simple: compile and push it.
	 */

	code = TclCompileTokens(interp, varTokenPtr+1,
		varTokenPtr->numComponents, envPtr);
	if (code != TCL_OK) {
	    goto done;
	}
	maxDepth += envPtr->maxStackDepth;
    }
	
    /*
     * If we are doing an assignment, push the new value.
     */
    
    if (isAssignment) {
	valueTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
	if (valueTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
	    TclEmitPush(TclRegisterLiteral(envPtr, valueTokenPtr[1].start,
		    valueTokenPtr[1].size, /*onHeap*/ 0), envPtr);
	    maxDepth += 1;
	} else {
	    code = TclCompileTokens(interp, valueTokenPtr+1,
	            valueTokenPtr->numComponents, envPtr);
	    if (code != TCL_OK) {
		goto done;
	    }
	    maxDepth += envPtr->maxStackDepth;
	}
    }
	
    /*
     * Emit instructions to set/get the variable.
     */

    if (simpleVarName) {
	if (elName == NULL) {
	    if (localIndex >= 0) {
		if (localIndex <= 255) {
		    TclEmitInstInt1((isAssignment?
		            INST_STORE_SCALAR1 : INST_LOAD_SCALAR1),
			    localIndex, envPtr);
		} else {
		    TclEmitInstInt4((isAssignment?
			    INST_STORE_SCALAR4 : INST_LOAD_SCALAR4),
			    localIndex, envPtr);
		}
	    } else {
		TclEmitOpcode((isAssignment?
		        INST_STORE_SCALAR_STK : INST_LOAD_SCALAR_STK),
			envPtr);
	    }
	} else {
	    if (localIndex >= 0) {
		if (localIndex <= 255) {
		    TclEmitInstInt1((isAssignment?
		            INST_STORE_ARRAY1 : INST_LOAD_ARRAY1),
			    localIndex, envPtr);
		} else {
		    TclEmitInstInt4((isAssignment?
			    INST_STORE_ARRAY4 : INST_LOAD_ARRAY4),
			    localIndex, envPtr);
		}
	    } else {
		TclEmitOpcode((isAssignment?
		        INST_STORE_ARRAY_STK : INST_LOAD_ARRAY_STK),
			envPtr);
	    }
	}
    } else {
	TclEmitOpcode((isAssignment? INST_STORE_STK : INST_LOAD_STK),
	        envPtr);
    }
	
    done:
    if (gotElemParse) {
        Tcl_FreeParse(&elemParse);
    }
    envPtr->maxStackDepth = maxDepth;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileWhileCmd --
 *
 *	Procedure called to compile the "while" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK if
 *	compilation was successful. If an error occurs then the
 *	interpreter's result contains a standard error message and TCL_ERROR
 *	is returned. If compilation failed because the command is too
 *	complex for TclCompileWhileCmd, TCL_OUT_LINE_COMPILE is returned
 *	indicating that the while command should be compiled "out of line"
 *	by emitting code to invoke its command procedure at runtime.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the "while" command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the "while" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileWhileCmd(interp, parsePtr, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Points to a parse structure for the
				 * command created by Tcl_ParseCommand. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Tcl_Token *testTokenPtr, *bodyTokenPtr;
    JumpFixup jumpFalseFixup;
    unsigned char *jumpPc;
    int testCodeOffset, jumpDist, jumpBackDist, jumpBackOffset;
    int range, maxDepth, code;
    char buffer[32 + TCL_INTEGER_SPACE];

    envPtr->maxStackDepth = 0;
    maxDepth = 0;
    if (parsePtr->numWords != 3) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"while test command\"", -1);
	return TCL_ERROR;
    }

    /*
     * If the test expression requires substitutions, don't compile the
     * while command inline. E.g., the expression might cause the loop to
     * never execute or execute forever, as in "while "$x < 5" {}".
     */

    testTokenPtr = parsePtr->tokenPtr
	    + (parsePtr->tokenPtr->numComponents + 1);
    if (testTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
	return TCL_OUT_LINE_COMPILE;
    }

    /*
     * Create a ExceptionRange record for the loop body. This is used to
     * implement break and continue.
     */

    envPtr->exceptDepth++;
    envPtr->maxExceptDepth =
	TclMax(envPtr->exceptDepth, envPtr->maxExceptDepth);
    range = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
    envPtr->exceptArrayPtr[range].continueOffset =
	    (envPtr->codeNext - envPtr->codeStart);

    /*
     * Compile the test expression then emit the conditional jump that
     * terminates the while. We already know it's a simple word.
     */

    testCodeOffset = (envPtr->codeNext - envPtr->codeStart);
    envPtr->exceptArrayPtr[range].continueOffset = testCodeOffset;
    code = TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
    if (code != TCL_OK) {
	if (code == TCL_ERROR) {
            Tcl_AddObjErrorInfo(interp,
		    "\n    (\"while\" test expression)", -1);
        }
	goto error;
    }
    maxDepth = envPtr->maxStackDepth;
    TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFalseFixup);
    
    /*
     * Compile the loop body.
     */

    bodyTokenPtr = testTokenPtr + (testTokenPtr->numComponents + 1);
    envPtr->exceptArrayPtr[range].codeOffset =
	    (envPtr->codeNext - envPtr->codeStart);
    code = TclCompileCmdWord(interp, bodyTokenPtr+1,
	    bodyTokenPtr->numComponents, envPtr);
    if (code != TCL_OK) {
	if (code == TCL_ERROR) {
	    sprintf(buffer, "\n    (\"while\" body line %d)",
		    interp->errorLine);
            Tcl_AddObjErrorInfo(interp, buffer, -1);
        }
	goto error;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
    envPtr->exceptArrayPtr[range].numCodeBytes =
	    (envPtr->codeNext - envPtr->codeStart)
	    - envPtr->exceptArrayPtr[range].codeOffset;
    TclEmitOpcode(INST_POP, envPtr);
	
    /*
     * Jump back to the test at the top of the loop. Generate a 4 byte jump
     * if the distance to the test is > 120 bytes. This is conservative and
     * ensures that we won't have to replace this jump if we later need to
     * replace the ifFalse jump with a 4 byte jump.
     */

    jumpBackOffset = (envPtr->codeNext - envPtr->codeStart);
    jumpBackDist = (jumpBackOffset - testCodeOffset);
    if (jumpBackDist > 120) {
	TclEmitInstInt4(INST_JUMP4, -jumpBackDist, envPtr);
    } else {
	TclEmitInstInt1(INST_JUMP1, -jumpBackDist, envPtr);
    }

    /*
     * Fix the target of the jumpFalse after the test. 
     */

    jumpDist = (envPtr->codeNext - envPtr->codeStart)
	    - jumpFalseFixup.codeOffset;
    if (TclFixupForwardJump(envPtr, &jumpFalseFixup, jumpDist, 127)) {
	/*
	 * Update the loop body's starting PC offset since it moved down.
	 */

	envPtr->exceptArrayPtr[range].codeOffset += 3;

	/*
	 * Update the jump back to the test at the top of the loop since it
	 * also moved down 3 bytes.
	 */

	jumpBackOffset += 3;
	jumpPc = (envPtr->codeStart + jumpBackOffset);
	jumpBackDist += 3;
	if (jumpBackDist > 120) {
	    TclUpdateInstInt4AtPc(INST_JUMP4, -jumpBackDist, jumpPc);
	} else {
	    TclUpdateInstInt1AtPc(INST_JUMP1, -jumpBackDist, jumpPc);
	}
    }

    /*
     * Set the loop's break target.
     */

    envPtr->exceptArrayPtr[range].breakOffset =
	    (envPtr->codeNext - envPtr->codeStart);
    
    /*
     * The while command's result is an empty string.
     */

    TclEmitPush(TclRegisterLiteral(envPtr, "", 0, /*onHeap*/ 0), envPtr);
    if (maxDepth == 0) {
	maxDepth = 1;
    }
    envPtr->maxStackDepth = maxDepth;
    envPtr->exceptDepth--;
    return TCL_OK;

    error:
    envPtr->maxStackDepth = maxDepth;
    envPtr->exceptDepth--;
    return code;
}



Changes to generic/tclCompExpr.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclCompExpr.c --
 *
 *	This file contains the code to compile Tcl expressions.
 *
 * 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.
 *
 * SCCS: @(#) tclCompExpr.c 1.34 97/11/03 14:29:18
 */

#include "tclInt.h"
#include "tclCompile.h"

/*
 * The stuff below is a bit of a hack so that this file can be used in





|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclCompExpr.c --
 *
 *	This file contains the code to compile Tcl expressions.
 *
 * 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: tclCompExpr.c,v 1.1.2.7 1998/12/12 01:36:54 lfb Exp $
 */

#include "tclInt.h"
#include "tclCompile.h"

/*
 * The stuff below is a bit of a hack so that this file can be used in
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125








126
127
128
129
130
131
132


133
134
135
136
137
138
139
140
141
142
143


144





145






146
147




148
149






150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

295
296




297
298
299

300
301
302
303
304
305
306
307
308
309
310
311

312
313

314


315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360































361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541










542
543
544
545
546
547
548
549

550
551
552
553
554
555
556






557

558






559
560
561
562
563
564
565
566
567
568
569
570





571
572
573
574

575
576
577
578
579

580

581
582
583




584





585



586

587
588
589
590
591
592







593
594




595




596

597



598


599

600
601
602


603
604


605
606
607

608
609


610
611
612
613





614
615

616

617
618
619
620
621
622
623

624





625



626
627
628
629
630
631


632


633


634
635
636
637
638
639




640
641
642










643
644
645
646
647
648
649
650


651
652




653
654
655
656
657
















658
659
660
661
662
663
664








665

666






667



668
669
670
671




672
673




674
675


676

677



678
679



680
681
682
683




684
685





686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702


703
704
705
706
707
708
709
710
711
712
713
714
715
716
717



718
719
720
721
722



723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741



742
743
744
745
746
747
748
749
750
751


752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775

776
777
778
779
780

781
782
783
784
785
786
787
788
789
790
791
792
793
794

795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
821
822
823
824

825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870


871
872
873
874
875
876
877
878
879
880
881
882
883
884
885

886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139

1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157

1158
1159
1160
1161
1162
1163
1164
1165
1166
1167

1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534

1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718


1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733


1734
1735
1736
1737
1738
1739



1740

1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831



1832
1833
1834


1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846

1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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

/*
 * Boolean variable that controls whether expression compilation tracing
 * is enabled.
 */

#ifdef TCL_COMPILE_DEBUG
static int traceCompileExpr = 0;
#endif /* TCL_COMPILE_DEBUG */

/*
 * The ExprInfo structure describes the state of compiling an expression.
 * A pointer to an ExprInfo record is passed among the routines in
 * this module.
 */

typedef struct ExprInfo {
    int token;			/* Type of the last token parsed in expr.
				 * See below for definitions. Corresponds
				 * to the characters just before next. */
    int objIndex;		/* If token is a literal value, the index of
				 * an object holding the value in the code's
				 * object table; otherwise is NULL. */
    char *funcName;		/* If the token is FUNC_NAME, points to the
				 * first character of the math function's
				 * name; otherwise is NULL. */
    char *next;			/* Position of the next character to be
				 * scanned in the expression string. */
    char *originalExpr;		/* The entire expression that was originally
				 * passed to Tcl_ExprString et al. */
    char *lastChar;		/* Pointer to terminating null in
				 * originalExpr. */
    int hasOperators;		/* Set 1 if the expr has operators; 0 if
				 * expr is only a primary. If 1 after
				 * compiling an expr, a tryCvtToNumeric
				 * instruction is emitted to convert the
				 * primary to a number if possible. */
    int exprIsJustVarRef;	/* Set 1 if the expr consists of just a
				 * variable reference as in the expression
				 * of "if $b then...". Otherwise 0. If 1 the
				 * expr is compiled out-of-line in order to
				 * implement expr's 2 level substitution
				 * semantics properly. */
    int exprIsComparison;	/* Set 1 if the top-level operator in the
				 * expr is a comparison. Otherwise 0. If 1,
				 * because the operands might be strings,
				 * the expr is compiled out-of-line in order
				 * to implement expr's 2 level substitution
				 * semantics properly. */
} ExprInfo;

/*
 * Definitions of the different tokens that appear in expressions. The order
 * of these must match the corresponding entries in the operatorStrings
 * array below.
 */

#define LITERAL		0
#define FUNC_NAME	(LITERAL + 1)
#define OPEN_BRACKET	(LITERAL + 2)
#define CLOSE_BRACKET	(LITERAL + 3)
#define OPEN_PAREN	(LITERAL + 4)
#define CLOSE_PAREN	(LITERAL + 5)
#define DOLLAR		(LITERAL + 6)
#define QUOTE		(LITERAL + 7)
#define COMMA		(LITERAL + 8)
#define END		(LITERAL + 9)
#define UNKNOWN		(LITERAL + 10)

/*
 * Binary operators:
 */

#define MULT		(UNKNOWN + 1)
#define DIVIDE		(MULT + 1)
#define MOD		(MULT + 2)
#define PLUS		(MULT + 3)
#define MINUS		(MULT + 4)
#define LEFT_SHIFT	(MULT + 5)
#define RIGHT_SHIFT	(MULT + 6)
#define LESS		(MULT + 7)
#define GREATER		(MULT + 8)
#define LEQ		(MULT + 9)
#define GEQ		(MULT + 10)
#define EQUAL		(MULT + 11)
#define NEQ		(MULT + 12)
#define BIT_AND		(MULT + 13)
#define BIT_XOR		(MULT + 14)
#define BIT_OR		(MULT + 15)
#define AND		(MULT + 16)
#define OR		(MULT + 17)
#define QUESTY		(MULT + 18)
#define COLON		(MULT + 19)









/*
 * Unary operators. Unary minus and plus are represented by the (binary)
 * tokens MINUS and PLUS.
 */

#define NOT		(COLON + 1)


#define BIT_NOT		(NOT + 1)

/*
 * Mapping from tokens to strings; used for debugging messages. These
 * entries must match the order and number of the token definitions above.
 */

#ifdef TCL_COMPILE_DEBUG
static char *tokenStrings[] = {
    "LITERAL", "FUNCNAME",
    "[", "]", "(", ")", "$", "\"", ",", "END", "UNKNOWN",


    "*", "/", "%", "+", "-",





    "<<", ">>", "<", ">", "<=", ">=", "==", "!=",






    "&", "^", "|", "&&", "||", "?", ":",
    "!", "~"




};
#endif /* TCL_COMPILE_DEBUG */







/*
 * Declarations for local procedures to this file:
 */

static int		CompileAddExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileBitAndExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileBitOrExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileBitXorExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileCondExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileEqualityExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileLandExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileLorExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileMathFuncCall _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileMultiplyExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompilePrimaryExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileRelationalExpr _ANSI_ARGS_((
    			    Tcl_Interp *interp, ExprInfo *infoPtr,
			    int flags, CompileEnv *envPtr));
static int		CompileShiftExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		CompileUnaryExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, int flags,
			    CompileEnv *envPtr));
static int		GetToken _ANSI_ARGS_((Tcl_Interp *interp,
			    ExprInfo *infoPtr, CompileEnv *envPtr));

/*
 * Macro used to debug the execution of the recursive descent parser used
 * to compile expressions.
 */

#ifdef TCL_COMPILE_DEBUG
#define HERE(production, level) \
    if (traceCompileExpr) { \
	fprintf(stderr, "%*s%s: token=%s, next=\"%.20s\"\n", \
		(level), " ", (production), tokenStrings[infoPtr->token], \
		infoPtr->next); \
    }
#else
#define HERE(production, level)
#endif /* TCL_COMPILE_DEBUG */

/*
 *----------------------------------------------------------------------
 *
 * TclCompileExpr --
 *
 *	This procedure compiles a string containing a Tcl expression into
 *	Tcl bytecodes. This procedure is the top-level interface to the
 *	the expression compilation module, and is used by such public
 *	procedures as Tcl_ExprString, Tcl_ExprStringObj, Tcl_ExprLong,
 *	Tcl_ExprDouble, Tcl_ExprBoolean, and Tcl_ExprBooleanObj.
 *
 *	Note that the topmost recursive-descent parsing routine used by
 *	TclCompileExpr to compile expressions is called "CompileCondExpr"
 *	and not, e.g., "CompileExpr". This is done to avoid an extra
 *	procedure call since such a procedure would only return the result
 *	of calling CompileCondExpr. Other recursive-descent procedures
 *	that need to parse expressions also call CompileCondExpr.
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed; this might
 *	be the offset of the ']' (if flags & TCL_BRACKET_TERM), or the
 *	offset of the '\0' at the end of the string.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 *	envPtr->exprIsJustVarRef is set 1 if the expression consisted of
 *	a single variable reference as in the expression of "if $b then...".
 *	Otherwise it is set 0. This is used to implement Tcl's two level
 *	expression substitution semantics properly.
 *
 *	envPtr->exprIsComparison is set 1 if the top-level operator in the
 *	expr is a comparison. Otherwise it is set 0. If 1, because the
 *	operands might be strings, the expr is compiled out-of-line in order
 *	to implement expr's 2 level substitution semantics properly.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileExpr(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Interp *iPtr = (Interp *) interp;
    ExprInfo info;
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int result;

#ifdef TCL_COMPILE_DEBUG
    if (traceCompileExpr) {
	fprintf(stderr, "expr: string=\"%.30s\"\n", string);
    }
#endif /* TCL_COMPILE_DEBUG */

    /*
     * Register the builtin math functions the first time an expression is
     * compiled.
     */

    if (!(iPtr->flags & EXPR_INITIALIZED)) {
	BuiltinFunc *funcPtr;
	Tcl_HashEntry *hPtr;
	MathFunc *mathFuncPtr;
	int i;


	iPtr->flags |= EXPR_INITIALIZED;




	i = 0;
	for (funcPtr = builtinFuncTable; funcPtr->name != NULL; funcPtr++) {
	    Tcl_CreateMathFunc(interp, funcPtr->name,

		    funcPtr->numArgs, funcPtr->argTypes,
		    (Tcl_MathProc *) NULL, (ClientData) 0);
	    
	    hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, funcPtr->name);
	    if (hPtr == NULL) {
		panic("TclCompileExpr: Tcl_CreateMathFunc incorrectly registered '%s'", funcPtr->name);
		return TCL_ERROR;
	    }
	    mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);
	    mathFuncPtr->builtinFuncIndex = i;
	    i++;
	}

    }


    info.token = UNKNOWN;


    info.objIndex = -1;
    info.funcName = NULL;
    info.next = string;
    info.originalExpr = string;
    info.lastChar = lastChar;
    info.hasOperators = 0;
    info.exprIsJustVarRef = 1;	/* will be set 0 if anything else is seen */
    info.exprIsComparison = 0;	/* set 1 if topmost operator is <,==,etc. */

    /*
     * Get the first token then compile an expression.
     */


    result = GetToken(interp, &info, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    
    result = CompileCondExpr(interp, &info, flags, envPtr);
    if (result != TCL_OK) {

	goto done;
    }
    if (info.token != END) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"syntax error in expression \"", string, "\"", (char *) NULL);
	result = TCL_ERROR;
	goto done;
    }
    if (!info.hasOperators) {
	/*
	 * Attempt to convert the primary's object to an int or double.
	 * This is done in order to support Tcl's policy of interpreting
	 * operands if at all possible as first integers, else
	 * floating-point numbers.
	 */
	
	TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);
    }
    maxDepth = envPtr->maxStackDepth;

    done:
    envPtr->termOffset = (info.next - string);
    envPtr->maxStackDepth = maxDepth;
    envPtr->exprIsJustVarRef = info.exprIsJustVarRef;
    envPtr->exprIsComparison = info.exprIsComparison;
    return result;































}

/*
 *----------------------------------------------------------------------
 *
 * CompileCondExpr --
 *
 *	This procedure compiles a Tcl conditional expression:
 *	condExpr ::= lorExpr ['?' condExpr ':' condExpr]
 *
 *	Note that this is the topmost recursive-descent parsing routine used
 *	by TclCompileExpr to compile expressions. It does not call an
 *	separate, higher-level "CompileExpr" procedure. This avoids an extra
 *	procedure call since such a procedure would only return the result
 *	of calling CompileCondExpr. Other recursive-descent procedures that
 *	need to parse expressions also call CompileCondExpr.
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileCondExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    JumpFixup jumpAroundThenFixup, jumpAroundElseFixup;
				/* Used to update or replace one-byte jumps
				 * around the then and else expressions when
				 * their target PCs are determined. */
    int elseCodeOffset, currCodeOffset, jumpDist, result;
    
    HERE("condExpr", 1);
    result = CompileLorExpr(interp, infoPtr, flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;
    
    if (infoPtr->token == QUESTY) {
	result = GetToken(interp, infoPtr, envPtr); /* skip over the '?' */
	if (result != TCL_OK) {
	    goto done;
	}

	/*
	 * Emit the jump around the "then" clause to the "else" condExpr if
	 * the test was false. We emit a one byte (relative) jump here, and
	 * replace it later with a four byte jump if the jump target is more
	 * than 127 bytes away.
	 */

	TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpAroundThenFixup);

	/*
	 * Compile the "then" expression. Note that if a subexpression
	 * is only a primary, we need to try to convert it to numeric.
	 * This is done in order to support Tcl's policy of interpreting
	 * operands if at all possible as first integers, else
	 * floating-point numbers.
	 */

	infoPtr->hasOperators = 0;
	infoPtr->exprIsJustVarRef = 0;
	infoPtr->exprIsComparison = 0;
	result = CompileCondExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
	if (infoPtr->token != COLON) {
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "syntax error in expression \"", infoPtr->originalExpr,
		    "\"", (char *) NULL);
	    result = TCL_ERROR;
	    goto done;
	}
	if (!infoPtr->hasOperators) {
	    TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);
	}
	result = GetToken(interp, infoPtr, envPtr); /* skip over the ':' */
	if (result != TCL_OK) {
	    goto done;
	}

	/*
	 * Emit an unconditional jump around the "else" condExpr.
	 */

	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
	        &jumpAroundElseFixup);

	/*
	 * Compile the "else" expression.
	 */

	infoPtr->hasOperators = 0;
	elseCodeOffset = TclCurrCodeOffset();
	result = CompileCondExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
	if (!infoPtr->hasOperators) {
	    TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);
	}

	/*
	 * Fix up the second jump: the unconditional jump around the "else"
	 * expression. If the distance is too great (> 127 bytes), replace
	 * it with a four byte instruction and move the instructions after
	 * the jump down.
	 */

	currCodeOffset = TclCurrCodeOffset();
	jumpDist = (currCodeOffset - jumpAroundElseFixup.codeOffset);
	if (TclFixupForwardJump(envPtr, &jumpAroundElseFixup, jumpDist, 127)) {
	    /*
	     * Update the else expression's starting code offset since it
	     * moved down 3 bytes too.
	     */
	    
	    elseCodeOffset += 3;
	}
	
	/*
	 * Now fix up the first branch: the jumpFalse after the test. If the
	 * distance is too great, replace it with a four byte instruction
	 * and update the code offsets for the commands in both the "then"
	 * and "else" expressions.
	 */

	jumpDist = (elseCodeOffset - jumpAroundThenFixup.codeOffset);
	TclFixupForwardJump(envPtr, &jumpAroundThenFixup, jumpDist, 127);

	infoPtr->hasOperators = 1;

	/*
	 * A comparison is not the top-level operator in this expression.
	 */

	infoPtr->exprIsComparison = 0;
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileLorExpr --
 *
 *	This procedure compiles a Tcl logical or expression:
 *	lorExpr ::= landExpr {'||' landExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *










 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileLorExpr(interp, infoPtr, flags, envPtr)

    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{






    int maxDepth;		/* Maximum number of stack elements needed

				 * to execute the expression. */






    JumpFixupArray jumpFixupArray;
				/* Used to fix up the forward "short
				 * circuit" jump after each or-ed
				 * subexpression to just after the last
				 * subexpression. */
    JumpFixup jumpTrueFixup, jumpFixup;
    				/* Used to emit the jumps in the code to
				 * convert the first operand to a 0 or 1. */
    int fixupIndex, jumpDist, currCodeOffset, objIndex, j, result;
    Tcl_Obj *objPtr;
    
    HERE("lorExpr", 2);





    result = CompileLandExpr(interp, infoPtr, flags, envPtr);
    if ((result != TCL_OK) || (infoPtr->token != OR)) {
	return result;		/* envPtr->maxStackDepth is already set */
    }


    infoPtr->hasOperators = 1;
    infoPtr->exprIsJustVarRef = 0;
    maxDepth = envPtr->maxStackDepth;
    TclInitJumpFixupArray(&jumpFixupArray);

    while (infoPtr->token == OR) {

	result = GetToken(interp, infoPtr, envPtr); /* skip over the '||' */
	if (result != TCL_OK) {
	    goto done;




	}









	if (jumpFixupArray.next == 0) {

	    /*
	     * Just the first "lor" operand is on the stack. The following
	     * is slightly ugly: we need to convert that first "lor" operand
	     * to a "0" or "1" to get the correct result if it is nonzero.
	     * Eventually we'll use a new instruction for this.
	     */








	    TclEmitForwardJump(envPtr, TCL_TRUE_JUMP, &jumpTrueFixup);




	    




	    objIndex = TclObjIndexForString("0", 1, /*allocStrRep*/ 0,

					    /*inHeap*/ 0, envPtr);



	    objPtr = envPtr->objArrayPtr[objIndex];




	    Tcl_InvalidateStringRep(objPtr);
	    objPtr->internalRep.longValue = 0;
	    objPtr->typePtr = &tclIntType;


	    
	    TclEmitPush(objIndex, envPtr);


	    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);

	    jumpDist = (TclCurrCodeOffset() - jumpTrueFixup.codeOffset);

	    if (TclFixupForwardJump(envPtr, &jumpTrueFixup, jumpDist, 127)) {
		panic("CompileLorExpr: bad jump distance %d\n", jumpDist);


	    }
	    objIndex = TclObjIndexForString("1", 1, /*allocStrRep*/ 0,
				            /*inHeap*/ 0, envPtr);
	    objPtr = envPtr->objArrayPtr[objIndex];






	    Tcl_InvalidateStringRep(objPtr);

	    objPtr->internalRep.longValue = 1;

	    objPtr->typePtr = &tclIntType;
	    
	    TclEmitPush(objIndex, envPtr);

	    jumpDist = (TclCurrCodeOffset() - jumpFixup.codeOffset);
	    if (TclFixupForwardJump(envPtr, &jumpFixup, jumpDist, 127)) {
		panic("CompileLorExpr: bad jump distance %d\n", jumpDist);

	    }





	}




	/*
	 * Duplicate the value on top of the stack to prevent the jump from
	 * consuming it.
	 */



	TclEmitOpcode(INST_DUP, envPtr);





	/*
	 * Emit the "short circuit" jump around the rest of the lorExp if
	 * the previous expression was true. We emit a one byte (relative)
	 * jump here, and replace it later with a four byte jump if the jump
	 * target is more than 127 bytes away.
	 */





	if (jumpFixupArray.next == jumpFixupArray.end) {
	    TclExpandJumpFixupArray(&jumpFixupArray);










	}
	fixupIndex = jumpFixupArray.next;
	jumpFixupArray.next++;
	TclEmitForwardJump(envPtr, TCL_TRUE_JUMP,
	        &(jumpFixupArray.fixup[fixupIndex]));
	
	/*
	 * Compile the subexpression.


	 */





	result = CompileLandExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);

















	/*
	 * Emit a "logical or" instruction. This does not try to "short-
	 * circuit" the evaluation of both operands of a Tcl "||" operator,
	 * but instead ensures that we either have a "1" or a "0" result.
	 */









	TclEmitOpcode(INST_LOR, envPtr);

    }










    /*
     * Now that we know the target of the forward jumps, update the jumps
     * with the correct distance. Also, if the distance is too great (> 127
     * bytes), replace the jump with a four byte instruction and move the




     * instructions after the jump down.
     */




    
    for (j = jumpFixupArray.next;  j > 0;  j--) {


	fixupIndex = (j - 1);	/* process closest jump first */

	currCodeOffset = TclCurrCodeOffset();



	jumpDist = (currCodeOffset - jumpFixupArray.fixup[fixupIndex].codeOffset);
	TclFixupForwardJump(envPtr, &(jumpFixupArray.fixup[fixupIndex]), jumpDist, 127);



    }

    /*
     * We get here only if one or more ||'s appear as top-level operators.




     */






    done:
    infoPtr->exprIsComparison = 0;
    TclFreeJumpFixupArray(&jumpFixupArray);
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileLandExpr --
 *
 *	This procedure compiles a Tcl logical and expression:
 *	landExpr ::= bitOrExpr {'&&' bitOrExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR


 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileLandExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */



    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */



{
    int maxDepth;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    JumpFixupArray jumpFixupArray;
				/* Used to fix up the forward "short
				 * circuit" jump after each and-ed
				 * subexpression to just after the last
				 * subexpression. */
    JumpFixup jumpTrueFixup, jumpFixup;
    				/* Used to emit the jumps in the code to
				 * convert the first operand to a 0 or 1. */
    int fixupIndex, jumpDist, currCodeOffset, objIndex, j, result;
    Tcl_Obj *objPtr;

    HERE("landExpr", 3);
    result = CompileBitOrExpr(interp, infoPtr, flags, envPtr);
    if ((result != TCL_OK) || (infoPtr->token != AND)) {
	return result;		/* envPtr->maxStackDepth is already set */
    }




    infoPtr->hasOperators = 1;
    infoPtr->exprIsJustVarRef = 0;
    maxDepth = envPtr->maxStackDepth;
    TclInitJumpFixupArray(&jumpFixupArray);
    while (infoPtr->token == AND) {
	result = GetToken(interp, infoPtr, envPtr); /* skip over the '&&' */
	if (result != TCL_OK) {
	    goto done;
	}



	if (jumpFixupArray.next == 0) {
	    /*
	     * Just the first "land" operand is on the stack. The following
	     * is slightly ugly: we need to convert the first "land" operand
	     * to a "0" or "1" to get the correct result if it is
	     * nonzero. Eventually we'll use a new instruction.
	     */

	    TclEmitForwardJump(envPtr, TCL_TRUE_JUMP, &jumpTrueFixup);
	     
	    objIndex = TclObjIndexForString("0", 1, /*allocStrRep*/ 0,
				            /*inHeap*/ 0, envPtr);
	    objPtr = envPtr->objArrayPtr[objIndex];

	    Tcl_InvalidateStringRep(objPtr);
	    objPtr->internalRep.longValue = 0;
	    objPtr->typePtr = &tclIntType;
	    
	    TclEmitPush(objIndex, envPtr);
	    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);

	    jumpDist = (TclCurrCodeOffset() - jumpTrueFixup.codeOffset);
	    if (TclFixupForwardJump(envPtr, &jumpTrueFixup, jumpDist, 127)) {

		panic("CompileLandExpr: bad jump distance %d\n", jumpDist);
	    }
	    objIndex = TclObjIndexForString("1", 1, /*allocStrRep*/ 0,
				            /*inHeap*/ 0, envPtr);
	    objPtr = envPtr->objArrayPtr[objIndex];


	    Tcl_InvalidateStringRep(objPtr);
	    objPtr->internalRep.longValue = 1;
	    objPtr->typePtr = &tclIntType;
	    
	    TclEmitPush(objIndex, envPtr);

	    jumpDist = (TclCurrCodeOffset() - jumpFixup.codeOffset);
	    if (TclFixupForwardJump(envPtr, &jumpFixup, jumpDist, 127)) {
		panic("CompileLandExpr: bad jump distance %d\n", jumpDist);
	    }
	}

	/*

	 * Duplicate the value on top of the stack to prevent the jump from
	 * consuming it.
	 */

	TclEmitOpcode(INST_DUP, envPtr);

	/*
	 * Emit the "short circuit" jump around the rest of the landExp if
	 * the previous expression was false. We emit a one byte (relative)
	 * jump here, and replace it later with a four byte jump if the jump
	 * target is more than 127 bytes away.
	 */

	if (jumpFixupArray.next == jumpFixupArray.end) {
	    TclExpandJumpFixupArray(&jumpFixupArray);
	}
	fixupIndex = jumpFixupArray.next;
	jumpFixupArray.next++;
	TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,

		&(jumpFixupArray.fixup[fixupIndex]));
	
	/*
	 * Compile the subexpression.
	 */

	result = CompileBitOrExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);


	/*
	 * Emit a "logical and" instruction. This does not try to "short-
	 * circuit" the evaluation of both operands of a Tcl "&&" operator,
	 * but instead ensures that we either have a "1" or a "0" result.
	 */

	TclEmitOpcode(INST_LAND, envPtr);
    }

    /*
     * Now that we know the target of the forward jumps, update the jumps
     * with the correct distance. Also, if the distance is too great (> 127
     * bytes), replace the jump with a four byte instruction and move the
     * instructions after the jump down.
     */
    
    for (j = jumpFixupArray.next;  j > 0;  j--) {
	fixupIndex = (j - 1);	/* process closest jump first */
	currCodeOffset = TclCurrCodeOffset();
	jumpDist = (currCodeOffset - jumpFixupArray.fixup[fixupIndex].codeOffset);
	TclFixupForwardJump(envPtr, &(jumpFixupArray.fixup[fixupIndex]),
	        jumpDist, 127);
    }

    /*
     * We get here only if one or more &&'s appear as top-level operators.
     */

    done:
    infoPtr->exprIsComparison = 0;
    TclFreeJumpFixupArray(&jumpFixupArray);
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileBitOrExpr --
 *
 *	This procedure compiles a Tcl bitwise or expression:
 *	bitOrExpr ::= bitXorExpr {'|' bitXorExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR


 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileBitOrExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */

    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int result;

    HERE("bitOrExpr", 4);
    result = CompileBitXorExpr(interp, infoPtr, flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;
    
    while (infoPtr->token == BIT_OR) {
	infoPtr->hasOperators = 1;
	infoPtr->exprIsJustVarRef = 0;
	result = GetToken(interp, infoPtr, envPtr); /* skip over the '|' */
	if (result != TCL_OK) {
	    goto done;
	}

	result = CompileBitXorExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);
	
	TclEmitOpcode(INST_BITOR, envPtr);

	/*
	 * A comparison is not the top-level operator in this expression.
	 */

	infoPtr->exprIsComparison = 0;
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileBitXorExpr --
 *
 *	This procedure compiles a Tcl bitwise exclusive or expression:
 *	bitXorExpr ::= bitAndExpr {'^' bitAndExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileBitXorExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int result;

    HERE("bitXorExpr", 5);
    result = CompileBitAndExpr(interp, infoPtr, flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;
    
    while (infoPtr->token == BIT_XOR) {
	infoPtr->hasOperators = 1;
	infoPtr->exprIsJustVarRef = 0;
	result = GetToken(interp, infoPtr, envPtr); /* skip over the '^' */
	if (result != TCL_OK) {
	    goto done;
	}

	result = CompileBitAndExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);
	
	TclEmitOpcode(INST_BITXOR, envPtr);

	/*
	 * A comparison is not the top-level operator in this expression.
	 */

	infoPtr->exprIsComparison = 0;
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileBitAndExpr --
 *
 *	This procedure compiles a Tcl bitwise and expression:
 *	bitAndExpr ::= equalityExpr {'&' equalityExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileBitAndExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int result;

    HERE("bitAndExpr", 6);
    result = CompileEqualityExpr(interp, infoPtr, flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;
    
    while (infoPtr->token == BIT_AND) {
	infoPtr->hasOperators = 1;
	infoPtr->exprIsJustVarRef = 0;
	result = GetToken(interp, infoPtr, envPtr); /* skip over the '&' */
	if (result != TCL_OK) {
	    goto done;
	}

	result = CompileEqualityExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);
	
	TclEmitOpcode(INST_BITAND, envPtr);

	/*
	 * A comparison is not the top-level operator in this expression.
	 */

	infoPtr->exprIsComparison = 0;
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileEqualityExpr --
 *
 *	This procedure compiles a Tcl equality (inequality) expression:
 *	equalityExpr ::= relationalExpr {('==' | '!=') relationalExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileEqualityExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int op, result;

    HERE("equalityExpr", 7);
    result = CompileRelationalExpr(interp, infoPtr, flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;

    op = infoPtr->token;
    while ((op == EQUAL) || (op == NEQ)) {
	infoPtr->hasOperators = 1;
	infoPtr->exprIsJustVarRef = 0;
	result = GetToken(interp, infoPtr, envPtr); /* skip over == or != */
	if (result != TCL_OK) {
	    goto done;
	}

	result = CompileRelationalExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);

	if (op == EQUAL) {
	    TclEmitOpcode(INST_EQ, envPtr);
	} else {
	    TclEmitOpcode(INST_NEQ, envPtr);
	}
	
	op = infoPtr->token;

	/*
	 * A comparison _is_ the top-level operator in this expression.
	 */
	

	infoPtr->exprIsComparison = 1;
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileRelationalExpr --
 *
 *	This procedure compiles a Tcl relational expression:
 *	relationalExpr ::= shiftExpr {('<' | '>' | '<=' | '>=') shiftExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR

 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------

 */

static int
CompileRelationalExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int op, result;

    HERE("relationalExpr", 8);
    result = CompileShiftExpr(interp, infoPtr, flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;

    op = infoPtr->token;
    while ((op == LESS) || (op == GREATER) || (op == LEQ) || (op == GEQ)) {
	infoPtr->hasOperators = 1;
	infoPtr->exprIsJustVarRef = 0;
	result = GetToken(interp, infoPtr, envPtr); /* skip over the op */
	if (result != TCL_OK) {
	    goto done;
	}

	result = CompileShiftExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);

	switch (op) {
	case LESS:
	    TclEmitOpcode(INST_LT, envPtr);
	    break;
	case GREATER:
	    TclEmitOpcode(INST_GT, envPtr);
	    break;
	case LEQ:
	    TclEmitOpcode(INST_LE, envPtr);
	    break;
	case GEQ:
	    TclEmitOpcode(INST_GE, envPtr);
	    break;
	}

	op = infoPtr->token;

	/*
	 * A comparison _is_ the top-level operator in this expression.
	 */
	
	infoPtr->exprIsComparison = 1;
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileShiftExpr --
 *
 *	This procedure compiles a Tcl shift expression:
 *	shiftExpr ::= addExpr {('<<' | '>>') addExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileShiftExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int op, result;

    HERE("shiftExpr", 9);
    result = CompileAddExpr(interp, infoPtr, flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;

    op = infoPtr->token;
    while ((op == LEFT_SHIFT) || (op == RIGHT_SHIFT)) {
	infoPtr->hasOperators = 1;
	infoPtr->exprIsJustVarRef = 0;
	result = GetToken(interp, infoPtr, envPtr); /* skip over << or >> */
	if (result != TCL_OK) {
	    goto done;
	}

	result = CompileAddExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);

	if (op == LEFT_SHIFT) {
	    TclEmitOpcode(INST_LSHIFT, envPtr);
	} else {
	    TclEmitOpcode(INST_RSHIFT, envPtr);
	}

	op = infoPtr->token;

	/*
	 * A comparison is not the top-level operator in this expression.
	 */

	infoPtr->exprIsComparison = 0;
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileAddExpr --
 *
 *	This procedure compiles a Tcl addition expression:
 *	addExpr ::= multiplyExpr {('+' | '-') multiplyExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileAddExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int op, result;

    HERE("addExpr", 10);
    result = CompileMultiplyExpr(interp, infoPtr, flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;

    op = infoPtr->token;
    while ((op == PLUS) || (op == MINUS)) {
	infoPtr->hasOperators = 1;
	infoPtr->exprIsJustVarRef = 0;
	result = GetToken(interp, infoPtr, envPtr); /* skip over + or - */
	if (result != TCL_OK) {
	    goto done;
	}

	result = CompileMultiplyExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);

	if (op == PLUS) {
	    TclEmitOpcode(INST_ADD, envPtr);
	} else {
	    TclEmitOpcode(INST_SUB, envPtr);
	}

	op = infoPtr->token;

	/*
	 * A comparison is not the top-level operator in this expression.
	 */

	infoPtr->exprIsComparison = 0;
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileMultiplyExpr --
 *
 *	This procedure compiles a Tcl multiply expression:
 *	multiplyExpr ::= unaryExpr {('*' | '/' | '%') unaryExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileMultiplyExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int op, result;

    HERE("multiplyExpr", 11);
    result = CompileUnaryExpr(interp, infoPtr, flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;

    op = infoPtr->token;
    while ((op == MULT) || (op == DIVIDE) || (op == MOD)) {
	infoPtr->hasOperators = 1;
	infoPtr->exprIsJustVarRef = 0;
	result = GetToken(interp, infoPtr, envPtr); /* skip over * or / */
	if (result != TCL_OK) {
	    goto done;
	}

	result = CompileUnaryExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);

	if (op == MULT) {
	    TclEmitOpcode(INST_MULT, envPtr);
	} else if (op == DIVIDE) {
	    TclEmitOpcode(INST_DIV, envPtr);
	} else {
	    TclEmitOpcode(INST_MOD, envPtr);
	}

	op = infoPtr->token;

	/*
	 * A comparison is not the top-level operator in this expression.
	 */

	infoPtr->exprIsComparison = 0;
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileUnaryExpr --
 *
 *	This procedure compiles a Tcl unary expression:
 *	unaryExpr ::= ('+' | '-' | '~' | '!') unaryExpr | primaryExpr
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileUnaryExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int op, result;

    HERE("unaryExpr", 12);
    op = infoPtr->token;
    if ((op == PLUS) || (op == MINUS) || (op == BIT_NOT) || (op == NOT)) {
	infoPtr->hasOperators = 1;
	infoPtr->exprIsJustVarRef = 0;
	result = GetToken(interp, infoPtr, envPtr); /* skip over the op */
	if (result != TCL_OK) {
	    goto done;
	}

	result = CompileUnaryExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = envPtr->maxStackDepth;

	switch (op) {
	case PLUS:
	    TclEmitOpcode(INST_UPLUS, envPtr);
	    break;
	case MINUS:
	    TclEmitOpcode(INST_UMINUS, envPtr);
	    break;
	case BIT_NOT:
	    TclEmitOpcode(INST_BITNOT, envPtr);
	    break;
	case NOT:
	    TclEmitOpcode(INST_LNOT, envPtr);
	    break;
	}

	/*
	 * A comparison is not the top-level operator in this expression.

	 */

	infoPtr->exprIsComparison = 0;
    } else {			/* must be a primaryExpr */
	result = CompilePrimaryExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = envPtr->maxStackDepth;
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompilePrimaryExpr --
 *
 *	This procedure compiles a Tcl primary expression:
 *	primaryExpr ::= literal | varReference | quotedString |
 *			'[' command ']' | mathFuncCall | '(' condExpr ')'
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompilePrimaryExpr(interp, infoPtr, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int theToken;
    char *dollarPtr, *quotePtr, *cmdPtr, *termPtr;
    int result = TCL_OK;

    /*
     * We emit tryCvtToNumeric instructions after most of these primary
     * expressions in order to support Tcl's policy of interpreting operands
     * as first integers if possible, otherwise floating-point numbers if
     * possible.
     */

    HERE("primaryExpr", 13);
    theToken = infoPtr->token;

    if ((theToken != DOLLAR) && (theToken != OPEN_PAREN)) {
	infoPtr->exprIsJustVarRef = 0;
    }
    switch (theToken) {
    case LITERAL:		/* int, double, or string in braces */
	TclEmitPush(infoPtr->objIndex, envPtr);
	maxDepth = 1;
	break;
	
    case DOLLAR:		/* $var variable reference */
	dollarPtr = (infoPtr->next - 1);
	envPtr->pushSimpleWords = 1;
	result = TclCompileDollarVar(interp, dollarPtr,
		infoPtr->lastChar, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = envPtr->maxStackDepth;
	infoPtr->next = (dollarPtr + envPtr->termOffset);
	break;
	
    case QUOTE:			/* quotedString */
	quotePtr = infoPtr->next;
	envPtr->pushSimpleWords = 1;
	result = TclCompileQuotes(interp, quotePtr,
		infoPtr->lastChar, '"', flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = envPtr->maxStackDepth;
	infoPtr->next = (quotePtr + envPtr->termOffset);
	break;
	
    case OPEN_BRACKET:		/* '[' command ']' */
	cmdPtr = infoPtr->next;
	envPtr->pushSimpleWords = 1;
	result = TclCompileString(interp, cmdPtr,
		infoPtr->lastChar, (flags | TCL_BRACKET_TERM), envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	termPtr = (cmdPtr + envPtr->termOffset);
	if (*termPtr == ']') {
	    infoPtr->next = (termPtr + 1); /* advance over the ']'. */
	} else if (termPtr == infoPtr->lastChar) {
	    /*
	     * Missing ] at end of nested command.

	     */
	    
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	            "missing close-bracket", -1);
	    result = TCL_ERROR;
	    goto done;
	} else {
	    panic("CompilePrimaryExpr: unexpected termination char '%c' for nested command\n", *termPtr);
	}
	maxDepth = envPtr->maxStackDepth;
	break;
	
    case FUNC_NAME:
	result = CompileMathFuncCall(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = envPtr->maxStackDepth;
	break;
	
    case OPEN_PAREN:
	result = GetToken(interp, infoPtr, envPtr); /* skip over the '(' */
	if (result != TCL_OK) {
	    goto done;
	}
	infoPtr->exprIsComparison = 0;
	result = CompileCondExpr(interp, infoPtr, flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = envPtr->maxStackDepth;
	if (infoPtr->token != CLOSE_PAREN) {
	    goto syntaxError;
	}
	break;
	
    default:
	goto syntaxError;
    }

    if (theToken != FUNC_NAME) {
	/*
	 * Advance to the next token before returning.
	 */
	
	result = GetToken(interp, infoPtr, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
    }

    done:
    envPtr->maxStackDepth = maxDepth;
    return result;

    syntaxError:
    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
	    "syntax error in expression \"", infoPtr->originalExpr,
	    "\"", (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileMathFuncCall --
 *
 *	This procedure compiles a call on a math function in an expression:
 *	mathFuncCall ::= funcName '(' [condExpr {',' condExpr}] ')'
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR


 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the function.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the math function at
 *	runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileMathFuncCall(interp, infoPtr, flags, envPtr)


    Tcl_Interp *interp;		/* Used for error reporting. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */



{

    Interp *iPtr = (Interp *) interp;
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    MathFunc *mathFuncPtr;	/* Info about math function. */
    int objIndex;		/* The object array index for an object
				 * holding the function name if it is not
				 * builtin. */
    Tcl_HashEntry *hPtr;
    char *p, *funcName;
    char savedChar;
    int result, i;

    /*
     * infoPtr->funcName points to the first character of the math
     * function's name. Look for the end of its name and look up the
     * MathFunc record for the function.
     */

    funcName = p = infoPtr->funcName;
    while (isalnum(UCHAR(*p)) || (*p == '_')) {
	p++;
    }
    infoPtr->next = p;
    
    result = GetToken(interp, infoPtr, envPtr); /* skip over func name */
    if (result != TCL_OK) {
	goto done;
    }
    if (infoPtr->token != OPEN_PAREN) {
	goto syntaxError;
    }
    result = GetToken(interp, infoPtr, envPtr); /* skip over '(' */
    if (result != TCL_OK) {
	goto done;
    }
    
    savedChar = *p;
    *p = 0;
    hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, funcName);
    if (hPtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"unknown math function \"", funcName, "\"", (char *) NULL);
	result = TCL_ERROR;
	*p = savedChar;
	goto done;
    }
    mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);

    /*
     * If not a builtin function, push an object with the function's name.
     */

    if (mathFuncPtr->builtinFuncIndex < 0) {   /* not builtin */
	objIndex = TclObjIndexForString(funcName, -1, /*allocStrRep*/ 1,
				        /*inHeap*/ 0, envPtr);
	TclEmitPush(objIndex, envPtr);
	maxDepth = 1;
    }

    /*
     * Restore the saved character after the function name.
     */

    *p = savedChar;

    /*
     * Compile the arguments for the function, if there are any.
     */

    if (mathFuncPtr->numArgs > 0) {
	for (i = 0;  ;  i++) {
	    infoPtr->exprIsComparison = 0;
	    result = CompileCondExpr(interp, infoPtr, flags, envPtr);
	    if (result != TCL_OK) {
		goto done;
	    }
    
	    /*
	     * Check for a ',' between arguments or a ')' ending the
	     * argument list.
	     */
    
	    if (i == (mathFuncPtr->numArgs-1)) {
		if (infoPtr->token == CLOSE_PAREN) {
		    break;	/* exit the argument parsing loop */
		} else if (infoPtr->token == COMMA) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "too many arguments for math function", -1);
		    result = TCL_ERROR;
		    goto done;



		} else {
		    goto syntaxError;
		}


	    }
	    if (infoPtr->token != COMMA) {
		if (infoPtr->token == CLOSE_PAREN) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "too few arguments for math function", -1);
		    result = TCL_ERROR;
		    goto done;
		} else {
		    goto syntaxError;
		}
	    }

	    result = GetToken(interp, infoPtr, envPtr); /* skip over , */
	    if (result != TCL_OK) {
		goto done;
	    }
	    maxDepth++;
	}
    }

    if (infoPtr->token != CLOSE_PAREN) {
	goto syntaxError;
    }
    result = GetToken(interp, infoPtr, envPtr); /* skip over ')' */
    if (result != TCL_OK) {
	goto done;
    }
    
    /*
     * Compile the call on the math function. Note that the "objc" argument
     * count for non-builtin functions is incremented by 1 to include the
     * the function name itself.
     */

    if (mathFuncPtr->builtinFuncIndex >= 0) { /* a builtin function */
	TclEmitInstUInt1(INST_CALL_BUILTIN_FUNC1,
			mathFuncPtr->builtinFuncIndex, envPtr);
    } else {
	TclEmitInstUInt1(INST_CALL_FUNC1, (mathFuncPtr->numArgs+1), envPtr);
    }

    /*
     * A comparison is not the top-level operator in this expression.
     */

    done:
    infoPtr->exprIsComparison = 0;
    envPtr->maxStackDepth = maxDepth;
    return result;

    syntaxError:
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"syntax error in expression \"", infoPtr->originalExpr,
		"\"", (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GetToken --
 *
 *	Lexical scanner used to compile expressions: parses a single 
 *	operator or other syntactic element from an expression string.
 *
 * Results:
 *	TCL_OK is returned unless an error occurred. In that case a standard
 *	Tcl error is returned, using the interpreter's result to hold an
 *	error message. TCL_ERROR is returned if an integer overflow, or a
 *	floating-point overflow or underflow occurred while reading in a
 *	number. If the lexical analysis is successful, infoPtr->token refers
 *	to the next symbol in the expression string, and infoPtr->next is
 *	advanced past the token. Also, if the token is a integer, double, or
 *	string literal, then infoPtr->objIndex the index of an object
 *	holding the value in the code's object table; otherwise is NULL.
 *
 * Side effects:
 *	Object are added to envPtr to hold the values of scanned literal
 *	integers, doubles, or strings.
 *
 *----------------------------------------------------------------------
 */

static int
GetToken(interp, infoPtr, envPtr)
    Tcl_Interp *interp;			/* Interpreter to use for error
					 * reporting. */
    register ExprInfo *infoPtr;         /* Describes the state of the
					 * compiling the expression,
					 * including the resulting token. */
    CompileEnv *envPtr;			/* Holds objects that store literal
					 * values that are scanned. */
{
    register char *src;		/* Points to current source char. */
    register char c;		/* The current char. */
    register int type;		/* Current char's CHAR_TYPE type. */
    char *termPtr;		/* Points to char terminating a literal. */
    char savedChar;		/* Holds the character termporarily replaced
				 * by a null character during processing of
				 * literal tokens. */
    int objIndex;		/* The object array index for an object
				 * holding a scanned literal. */
    long longValue;		/* Value of a scanned integer literal. */
    double doubleValue;		/* Value of a scanned double literal. */
    Tcl_Obj *objPtr;

    /*
     * First initialize the scanner's "result" fields to default values.
     */
    
    infoPtr->token = UNKNOWN;
    infoPtr->objIndex = -1;
    infoPtr->funcName = NULL;

    /*
     * Scan over leading white space at the start of a token. Note that a
     * backslash-newline is treated as a space.
     */

    src = infoPtr->next;
    c = *src;
    type = CHAR_TYPE(src, infoPtr->lastChar);
    while ((type & (TCL_SPACE | TCL_BACKSLASH)) || (c == '\n')) {
	if (type == TCL_BACKSLASH) {
	    if (src[1] == '\n') {
		src += 2;
	    } else {
		break;	/* no longer white space */
	    }
	} else {
	    src++;
	}
	c = *src;
	type = CHAR_TYPE(src, infoPtr->lastChar);
    }
    if (src == infoPtr->lastChar) {
	infoPtr->token = END;
	infoPtr->next = src;
	return TCL_OK;
    }

    /*
     * Try to parse the token first as an integer or floating-point
     * number. Don't check for a number if the first character is "+" or
     * "-". If we did, we might treat a binary operator as unary by mistake,
     * which would eventually cause a syntax error.
     */

    if ((*src != '+') && (*src != '-')) {
	int startsWithDigit = isdigit(UCHAR(*src));
	
	if (startsWithDigit && TclLooksLikeInt(src)) {
	    errno = 0;
	    longValue = strtoul(src, &termPtr, 0);
	    if (errno == ERANGE) {
		char *s = "integer value too large to represent";
		
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);
		Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s,
			(char *) NULL);
		return TCL_ERROR;
	    }
	    if (termPtr != src) {
		/*
		 * src was the start of a valid integer. Find/create an
		 * object in envPtr's object array to contain the integer.
		 */
	    
		savedChar = *termPtr;
		*termPtr = '\0';
		objIndex = TclObjIndexForString(src, termPtr - src,
		        /*allocStrRep*/ 0, /*inHeap*/ 0, envPtr);
		*termPtr = savedChar;  /* restore the saved char */
		
		objPtr = envPtr->objArrayPtr[objIndex];
		Tcl_InvalidateStringRep(objPtr);
		objPtr->internalRep.longValue = longValue;
		objPtr->typePtr = &tclIntType;
		
		infoPtr->token = LITERAL;
		infoPtr->objIndex = objIndex;
		infoPtr->next = termPtr;
		return TCL_OK;
	    }
	} else if (startsWithDigit || (*src == '.')
	        || (*src == 'n') || (*src == 'N')) {
	    errno = 0;
	    doubleValue = strtod(src, &termPtr);
	    if (termPtr != src) {
		if (errno != 0) {
		    TclExprFloatError(interp, doubleValue);
		    return TCL_ERROR;
		}

		/*
		 * Find/create an object in the object array containing the
		 * double.
		 */
		
		savedChar = *termPtr;
		*termPtr = '\0';
		objIndex = TclObjIndexForString(src, termPtr - src,
			/*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
		*termPtr = savedChar;  /* restore the saved char */
		
		objPtr = envPtr->objArrayPtr[objIndex];
		objPtr->internalRep.doubleValue = doubleValue;
		objPtr->typePtr = &tclDoubleType;
		
		infoPtr->token = LITERAL;
		infoPtr->objIndex = objIndex;
		infoPtr->next = termPtr;
		return TCL_OK;
	    }
	}
    }

    /*
     * Not an integer or double literal. Check next for a string literal
     * in braces.
     */

    if (*src == '{') {
	int level = 0;		 /* The {} nesting level. */
	int hasBackslashNL = 0;  /* Nonzero if '\newline' was found. */
	char *string = src;	 /* Set below to point just after the
				  * starting '{'. */
	char *last;		 /* Points just before terminating '}'. */
	int numChars;		 /* Number of chars in braced string. */
	char savedChar;		 /* Holds the character from string
				  * termporarily replaced by a null char
				  * during braced string processing. */
	int numRead;

	/*
	 * Check first for any backslash-newlines, since we must treat
	 * backslash-newlines specially (they must be replaced by spaces).
	 */

	while (1) {
	    if (src == infoPtr->lastChar) {
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "missing close-brace", -1);
		return TCL_ERROR;
	    } else if (CHAR_TYPE(src, infoPtr->lastChar) == TCL_NORMAL) {
		src++;
		continue;
	    }
	    c = *src++;
	    if (c == '{') {
		level++;
	    } else if (c == '}') {
		--level;
		if (level == 0) {
		    last = (src - 2); /* i.e. just before terminating } */
		    break;
		}
	    } else if (c == '\\') {
		if (*src == '\n') {
		    hasBackslashNL = 1;
		}
		(void) Tcl_Backslash(src-1, &numRead);
		src += numRead - 1;
	    }
	}

	/*
	 * Create a string object for the braced string. This will start at
	 * "string" and ends just after "last" (which points to the final
	 * character before the terminating '}'). If backslash-newlines were
	 * found, we copy characters one at a time into a heap-allocated
	 * buffer and do backslash-newline substitutions.
	 */

	string++;
	numChars = (last - string + 1);
	savedChar = string[numChars];
	string[numChars] = '\0';
	if (hasBackslashNL && (numChars > 0)) {
	    char *buffer = ckalloc((unsigned) numChars + 1);
	    register char *dst = buffer;
	    register char *p = string;
	    while (p <= last) {
		c = *dst++ = *p++;
		if (c == '\\') {
		    if (*p == '\n') {
			dst[-1] = Tcl_Backslash(p-1, &numRead);
			p += numRead - 1;
		    } else {
			(void) Tcl_Backslash(p-1, &numRead);
			while (numRead > 1) {
			    *dst++ = *p++;
			    numRead--;
			}
		    }
		}
	    }
	    *dst = '\0';
	    objIndex = TclObjIndexForString(buffer, dst - buffer,
		    /*allocStrRep*/ 1, /*inHeap*/ 1, envPtr);
	} else {
	    objIndex = TclObjIndexForString(string, numChars,
		    /*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
	}
	string[numChars] = savedChar;   /* restore the saved char */

	infoPtr->token = LITERAL;
	infoPtr->objIndex = objIndex;
	infoPtr->next = src;
	return TCL_OK;
    }

    /*
     * Not an literal value.
     */

    infoPtr->next = src+1;   /* assume a 1 char token and advance over it */
    switch (*src) {
	case '[':
	    infoPtr->token = OPEN_BRACKET;
	    return TCL_OK;

	case ']':
	    infoPtr->token = CLOSE_BRACKET;
	    return TCL_OK;

	case '(':
	    infoPtr->token = OPEN_PAREN;
	    return TCL_OK;

	case ')':
	    infoPtr->token = CLOSE_PAREN;
	    return TCL_OK;

	case '$':
	    infoPtr->token = DOLLAR;
	    return TCL_OK;

	case '"':
	    infoPtr->token = QUOTE;
	    return TCL_OK;

	case ',':
	    infoPtr->token = COMMA;
	    return TCL_OK;

	case '*':
	    infoPtr->token = MULT;
	    return TCL_OK;

	case '/':
	    infoPtr->token = DIVIDE;
	    return TCL_OK;

	case '%':
	    infoPtr->token = MOD;
	    return TCL_OK;

	case '+':
	    infoPtr->token = PLUS;
	    return TCL_OK;

	case '-':
	    infoPtr->token = MINUS;
	    return TCL_OK;

	case '?':
	    infoPtr->token = QUESTY;
	    return TCL_OK;

	case ':':
	    infoPtr->token = COLON;
	    return TCL_OK;

	case '<':
	    switch (src[1]) {
		case '<':
		    infoPtr->next = src+2;
		    infoPtr->token = LEFT_SHIFT;
		    break;
		case '=':
		    infoPtr->next = src+2;
		    infoPtr->token = LEQ;
		    break;
		default:
		    infoPtr->token = LESS;
		    break;
	    }
	    return TCL_OK;

	case '>':
	    switch (src[1]) {
		case '>':
		    infoPtr->next = src+2;
		    infoPtr->token = RIGHT_SHIFT;
		    break;
		case '=':
		    infoPtr->next = src+2;
		    infoPtr->token = GEQ;
		    break;
		default:
		    infoPtr->token = GREATER;
		    break;
	    }
	    return TCL_OK;

	case '=':
	    if (src[1] == '=') {
		infoPtr->next = src+2;
		infoPtr->token = EQUAL;
	    } else {
		infoPtr->token = UNKNOWN;
	    }
	    return TCL_OK;

	case '!':
	    if (src[1] == '=') {
		infoPtr->next = src+2;
		infoPtr->token = NEQ;
	    } else {
		infoPtr->token = NOT;
	    }
	    return TCL_OK;

	case '&':
	    if (src[1] == '&') {
		infoPtr->next = src+2;
		infoPtr->token = AND;
	    } else {
		infoPtr->token = BIT_AND;
	    }
	    return TCL_OK;

	case '^':
	    infoPtr->token = BIT_XOR;
	    return TCL_OK;

	case '|':
	    if (src[1] == '|') {
		infoPtr->next = src+2;
		infoPtr->token = OR;
	    } else {
		infoPtr->token = BIT_OR;
	    }
	    return TCL_OK;

	case '~':
	    infoPtr->token = BIT_NOT;
	    return TCL_OK;

	default:
	    if (isalpha(UCHAR(*src))) {
		infoPtr->token = FUNC_NAME;
		infoPtr->funcName = src;
		while (isalnum(UCHAR(*src)) || (*src == '_')) {
		    src++;
		}
		infoPtr->next = src;
		return TCL_OK;
	    }
	    infoPtr->next = src+1;
	    infoPtr->token = UNKNOWN;
	    return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateMathFunc --
 *
 *	Creates a new math function for expressions in a given
 *	interpreter.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The function defined by "name" is created or redefined. If the
 *	function already exists then its definition is replaced; this
 *	includes the builtin functions. Redefining a builtin function forces
 *	all existing code to be invalidated since that code may be compiled
 *	using an instruction specific to the replaced function. In addition,
 *	redefioning a non-builtin function will force existing code to be
 *	invalidated if the number of arguments has changed.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_CreateMathFunc(interp, name, numArgs, argTypes, proc, clientData)
    Tcl_Interp *interp;			/* Interpreter in which function is
					 * to be available. */
    char *name;				/* Name of function (e.g. "sin"). */
    int numArgs;			/* Nnumber of arguments required by
					 * function. */
    Tcl_ValueType *argTypes;		/* Array of types acceptable for
					 * each argument. */
    Tcl_MathProc *proc;			/* Procedure that implements the
					 * math function. */
    ClientData clientData;		/* Additional value to pass to the
					 * function. */
{
    Interp *iPtr = (Interp *) interp;
    Tcl_HashEntry *hPtr;
    MathFunc *mathFuncPtr;
    int new, i;

    hPtr = Tcl_CreateHashEntry(&iPtr->mathFuncTable, name, &new);
    if (new) {
	Tcl_SetHashValue(hPtr, ckalloc(sizeof(MathFunc)));
    }
    mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);

    if (!new) {	
	if (mathFuncPtr->builtinFuncIndex >= 0) {
	    /*
	     * We are redefining a builtin math function. Invalidate the
             * interpreter's existing code by incrementing its
             * compileEpoch member. This field is checked in Tcl_EvalObj
             * and ObjInterpProc, and code whose compilation epoch doesn't
             * match is recompiled. Newly compiled code will no longer
             * treat the function as builtin.
	     */

	    iPtr->compileEpoch++;
	} else {
	    /*
	     * A non-builtin function is being redefined. We must invalidate
             * existing code if the number of arguments has changed. This
	     * is because existing code was compiled assuming that number.
	     */

	    if (numArgs != mathFuncPtr->numArgs) {
		iPtr->compileEpoch++;
	    }
	}
    }
    
    mathFuncPtr->builtinFuncIndex = -1;	/* can't be a builtin function */
    if (numArgs > MAX_MATH_ARGS) {
	numArgs = MAX_MATH_ARGS;
    }
    mathFuncPtr->numArgs = numArgs;
    for (i = 0;  i < numArgs;  i++) {
	mathFuncPtr->argTypes[i] = argTypes[i];
    }
    mathFuncPtr->proc = proc;
    mathFuncPtr->clientData = clientData;

}







|









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




















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


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

<
|
<
<

|
>
>
|
|
|
|
<
<

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

|
>
>
>
>
>
>





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

<
|
<
<
<


|
<



|
|
|
|
<


|













<
<
<
<
<
<
<





<
<
<
<
<




















|

|
|
|
<
|


<

|
<
|
|
<
<
<
|
<
<

|
|


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

<
|
<

>


>
|
>
>
|
|
|
|
|


|


|


>
|
|


|
|
|
>


<
<
<
|
<
|










|


<



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





|

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







|

>
>
>
>
>
>
>
>
>
>

|





|
>
|


<
<


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

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

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

|
|
|
|

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



<
>
>
>
>

|
>
>
>
>
>

<
<

|





|

|
|



>
>
|












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

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

<
<
|
<
|
|
|
|
|
>
>

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

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

|
|
|
|
|
>

|
|
|
|
|

|
|
<

|
|
<
<

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


<
<

|





|

|
|



>
>
|












|
|
>


<
<

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

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

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

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

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

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

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


|
<
<
<
<
<
<












>
>
|













|
>
>
|


<
<

>
>
>

>

<
<
|
<
<
<

|
<
|


<
<
|


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




|
<








|
|
|
<




|


<
|
<
<
<
|

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






|



|
|

|

|
<
<
<


<

|
<
<
<
<
<
<





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





<
|
<
|
<
<
<




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

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51








52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77


78











79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112


113
114
115
116
117
118
119
120


121

122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157












158
159
160



161
162


163
164
165
166


167
168



169
170



171

172



173
174
175

176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198







199
200
201
202
203





204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231

232
233

234
235



236


237
238
239
240
241
242




243
244

245
246
247
248

249
250
251
252
253
254




255

256

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288



289

290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345























346
















347

































































































348


























349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379


380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401




402
403
404
405
406
407
408
409
410
411


412
413


414

415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437



438

439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477

478
479
480
481
482
483

484

485
486
487
488
489
490
491
492
493
494
495
496
497
498
499


500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525





526
527
528
529
530


531
532
533
534
535
536
537
538
539
540
541




542
543

544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573




574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597



598
599
600
601
602

603
604
605
606
607

608
609
610
611
612
613
614
615
616

617
618
619
620
621
622

623
624
625
626
627
628
629
630
631
632
633
634


635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670


671
672
673
674
675



676


677
678
679
680

681
682




683
684
685
686
687


688

689
690
691
692
693
694
695
696

697

698

699
700
701
702
703









704
705

706
707
708
709
710
711
712
713
714



715








716
717
718
719
720
721
722













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

746
747
748


749
750


751
752
753


754



755
756


757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790


791




792






793






















































794



795



796



797


798







799


800

801
802


803


804




























805


















806
807
808



809
810
811
812

















813


814


















815














































816
817
818
819
820

821






822


823






824
825









826
827
828






















829

830
831
832
833
































834


835












































836













837


838
839


840


841




























842


















843

844








845



846










847


848










849




























































850
851
852
853



854



855


856
857



858









859



860



861












862































863

864
865

















866











867







868














869
870

871

872
873












874











875







876



877












878

879
880








881


882







883















884


885












886
887
888






889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922


923
924
925
926
927
928
929


930



931
932

933
934
935


936
937
938







939











940
941
942
943
944
945

946
947
948
949
950
951
952
953
954
955
956

957
958
959
960
961
962
963

964



965
966
967





968









969
970
971
972
973
974
975
976
977
978
979
980
981
982
983

984
985
986
987
988


989

990
991
992





993




994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010



1011
1012

1013
1014






1015
1016
1017
1018
1019






















1020
























































































































































































1021







1022































1023





1024

































































































































































1025
1026
1027
1028
1029

1030

1031



1032
1033
1034
1035
1036














1037
1038

1039





1040










1041







1042


1043


1044




1045



1046

1047
1048

/*
 * Boolean variable that controls whether expression compilation tracing
 * is enabled.
 */

#ifdef TCL_COMPILE_DEBUG
static int traceExprComp = 0;
#endif /* TCL_COMPILE_DEBUG */

/*
 * The ExprInfo structure describes the state of compiling an expression.
 * A pointer to an ExprInfo record is passed among the routines in
 * this module.
 */

typedef struct ExprInfo {
    Tcl_Interp *interp;		/* Used for error reporting. */
    Tcl_Parse *parsePtr;	/* Structure filled with information about








				 * the parsed expression. */
    char *expr;			/* The expression that was originally passed
				 * to TclCompileExpr. */
    char *lastChar;		/* Points just after last byte of expr. */

    int hasOperators;		/* Set 1 if the expr has operators; 0 if
				 * expr is only a primary. If 1 after
				 * compiling an expr, a tryCvtToNumeric
				 * instruction is emitted to convert the
				 * primary to a number if possible. */
    int exprIsJustVarRef;	/* Set 1 if the expr consists of just a
				 * variable reference as in the expression
				 * of "if $b then...". Otherwise 0. If 1 the
				 * expr is compiled out-of-line in order to
				 * implement expr's 2 level substitution
				 * semantics properly. */
    int exprIsComparison;	/* Set 1 if the top-level operator in the
				 * expr is a comparison. Otherwise 0. If 1,
				 * because the operands might be strings,
				 * the expr is compiled out-of-line in order
				 * to implement expr's 2 level substitution
				 * semantics properly. */
} ExprInfo;

/*
 * Definitions of numeric codes representing each expression operator.
 * The order of these must match the entries in the operatorTable below.


 * Also the codes for the relational operators (OP_LESS, OP_GREATER, 











 * OP_LE, OP_GE, OP_EQ, and OP_NE) must be consecutive and in that order.

 * Note that OP_PLUS and OP_MINUS represent both unary and binary operators.
 */

#define OP_MULT		0
#define OP_DIVIDE	1
#define OP_MOD		2
#define OP_PLUS		3
#define OP_MINUS	4
#define OP_LSHIFT	5
#define OP_RSHIFT	6
#define OP_LESS		7
#define OP_GREATER	8
#define OP_LE		9
#define OP_GE		10
#define OP_EQ		11
#define OP_NEQ		12
#define OP_BITAND	13
#define OP_BITXOR	14
#define OP_BITOR	15
#define OP_LAND		16
#define OP_LOR		17
#define OP_QUESTY	18
#define OP_LNOT		19
#define OP_BITNOT	20

/*
 * Table describing the expression operators. Entries in this table must
 * correspond to the definitions of numeric codes for operators just above.
 */

static int opTableInitialized = 0; /* 0 means not yet initialized. */


TCL_DECLARE_MUTEX(opMutex)



typedef struct OperatorDesc {
    char *name;			/* Name of the operator. */
    int numOperands;		/* Number of operands. 0 if the operator
				 * requires special handling. */
    int instruction;		/* Instruction opcode for the operator.
				 * Ignored if numOperands is 0. */
} OperatorDesc;




OperatorDesc operatorTable[] = {
    {"*",   2,  INST_MULT},

    {"/",   2,  INST_DIV},
    {"%",   2,  INST_MOD},
    {"+",   0}, 
    {"-",   0},
    {"<<",  2,  INST_LSHIFT},
    {">>",  2,  INST_RSHIFT},
    {"<",   2,  INST_LT},
    {">",   2,  INST_GT},
    {"<=",  2,  INST_LE},
    {">=",  2,  INST_GE},
    {"==",  2,  INST_EQ},
    {"!=",  2,  INST_NEQ},
    {"&",   2,  INST_BITAND},
    {"^",   2,  INST_BITXOR},
    {"|",   2,  INST_BITOR},
    {"&&",  0},
    {"||",  0},
    {"?",   0},
    {"!",   1,  INST_LNOT},
    {"~",   1,  INST_BITNOT},
    {NULL}
};

/*
 * Hashtable used to map the names of expression operators to the index
 * of their OperatorDesc description.
 */

static Tcl_HashTable opHashTable;

/*
 * Declarations for local procedures to this file:
 */













static int		CompileCondExpr _ANSI_ARGS_((
			    Tcl_Token *exprTokenPtr, ExprInfo *infoPtr,
			    CompileEnv *envPtr, Tcl_Token **endPtrPtr));



static int		CompileLandOrLorExpr _ANSI_ARGS_((
			    Tcl_Token *exprTokenPtr, int opIndex,


			    ExprInfo *infoPtr, CompileEnv *envPtr,
			    Tcl_Token **endPtrPtr));
static int		CompileMathFuncCall _ANSI_ARGS_((
			    Tcl_Token *exprTokenPtr, char *funcName,


			    ExprInfo *infoPtr, CompileEnv *envPtr,
			    Tcl_Token **endPtrPtr));



static int		CompileSubExpr _ANSI_ARGS_((
			    Tcl_Token *exprTokenPtr, ExprInfo *infoPtr,



			    CompileEnv *envPtr));

static void		LogSyntaxError _ANSI_ARGS_((ExprInfo *infoPtr));




/*
 * Macro used to debug the execution of the expression compiler.

 */

#ifdef TCL_COMPILE_DEBUG
#define TRACE(exprBytes, exprLength, tokenBytes, tokenLength) \
    if (traceExprComp) { \
	fprintf(stderr, "CompileSubExpr: \"%.*s\", token \"%.*s\"\n", \
	        (exprLength), (exprBytes), (tokenLength), (tokenBytes)); \

    }
#else
#define TRACE(exprBytes, exprLength, tokenBytes, tokenLength)
#endif /* TCL_COMPILE_DEBUG */

/*
 *----------------------------------------------------------------------
 *
 * TclCompileExpr --
 *
 *	This procedure compiles a string containing a Tcl expression into
 *	Tcl bytecodes. This procedure is the top-level interface to the
 *	the expression compilation module, and is used by such public
 *	procedures as Tcl_ExprString, Tcl_ExprStringObj, Tcl_ExprLong,
 *	Tcl_ExprDouble, Tcl_ExprBoolean, and Tcl_ExprBooleanObj.
 *







 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *





 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 *	envPtr->exprIsJustVarRef is set 1 if the expression consisted of
 *	a single variable reference as in the expression of "if $b then...".
 *	Otherwise it is set 0. This is used to implement Tcl's two level
 *	expression substitution semantics properly.
 *
 *	envPtr->exprIsComparison is set 1 if the top-level operator in the
 *	expr is a comparison. Otherwise it is set 0. If 1, because the
 *	operands might be strings, the expr is compiled out-of-line in order
 *	to implement expr's 2 level substitution semantics properly.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileExpr(interp, script, numBytes, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *script;		/* The source script to compile. */
    int numBytes;		/* Number of bytes in script. If < 0, the
				 * string consists of all bytes up to the

				 * first null character. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{

    ExprInfo info;
    Tcl_Parse parse;

    Tcl_HashEntry *hPtr;
    int maxDepth, new, i, code;






    /*
     * If this is the first time we've been called, initialize the table
     * of expression operators.
     */

    if (numBytes < 0) {




	numBytes = (script? strlen(script) : 0);
    }

    if (!opTableInitialized) {
	Tcl_MutexLock(&opMutex);
	if (!opTableInitialized) {
	    Tcl_InitHashTable(&opHashTable, TCL_STRING_KEYS);

	    for (i = 0;  operatorTable[i].name != NULL;  i++) {
		hPtr = Tcl_CreateHashEntry(&opHashTable,
			operatorTable[i].name, &new);
		if (new) {
		    Tcl_SetHashValue(hPtr, (ClientData) i);
		}




	    }

	    opTableInitialized = 1;

	}
	Tcl_MutexUnlock(&opMutex);
    }

    /*
     * Initialize the structure containing information abvout this
     * expression compilation.
     */

    info.interp = interp;
    info.parsePtr = &parse;
    info.expr = script;
    info.lastChar = (script + numBytes); 
    info.hasOperators = 0;
    info.exprIsJustVarRef = 1;	/* will be set 0 if anything else is seen */
    info.exprIsComparison = 0;

    /*
     * Parse the expression then compile it.
     */

    maxDepth = 0;
    code = Tcl_ParseExpr(interp, script, numBytes, &parse);
    if (code != TCL_OK) {
	goto done;
    }

    code = CompileSubExpr(parse.tokenPtr, &info, envPtr);
    if (code != TCL_OK) {
	Tcl_FreeParse(&parse);
	goto done;
    }



    maxDepth = envPtr->maxStackDepth;

    
    if (!info.hasOperators) {
	/*
	 * Attempt to convert the primary's object to an int or double.
	 * This is done in order to support Tcl's policy of interpreting
	 * operands if at all possible as first integers, else
	 * floating-point numbers.
	 */
	
	TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);
    }
    Tcl_FreeParse(&parse);

    done:

    envPtr->maxStackDepth = maxDepth;
    envPtr->exprIsJustVarRef = info.exprIsJustVarRef;
    envPtr->exprIsComparison = info.exprIsComparison;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeCompilation --
 *
 *	Clean up the compilation environment so it can later be
 *	properly reinitialized. This procedure is called by
 *	TclFinalizeCompExecEnv() in tclObj.c, which in turn is called
 *	by Tcl_Finalize().
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Cleans up the compilation environment. At the moment, just the
 *	table of expression operators is freed.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeCompilation()
{
    Tcl_MutexLock(&opMutex);
    if (opTableInitialized) {
        Tcl_DeleteHashTable(&opHashTable);
        opTableInitialized = 0;
    }
    Tcl_MutexUnlock(&opMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * CompileSubExpr --
 *























 *	Given a pointer to a TCL_TOKEN_SUB_EXPR token describing a
















 *	subexpression, this procedure emits instructions to evaluate the

































































































 *	subexpression at runtime.


























 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the subexpression.
 *
 *	envPtr->exprIsJustVarRef is set 1 if the subexpression consisted of
 *	a single variable reference as in the expression of "if $b then...".
 *	Otherwise it is set 0. This is used to implement Tcl's two level
 *	expression substitution semantics properly.
 *
 *	envPtr->exprIsComparison is set 1 if the top-level operator in the
 *	subexpression is a comparison. Otherwise it is set 0. If 1, because
 *	the operands might be strings, the expr is compiled out-of-line in
 *	order to implement expr's 2 level substitution semantics properly.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the subexpression.
 *
 *----------------------------------------------------------------------
 */

static int
CompileSubExpr(exprTokenPtr, infoPtr, envPtr)
    Tcl_Token *exprTokenPtr;	/* Points to TCL_TOKEN_SUB_EXPR token
				 * to compile. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */


    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Tcl_Interp *interp = infoPtr->interp;
    Tcl_Token *tokenPtr, *endPtr, *afterSubexprPtr;
    OperatorDesc *opDescPtr;
    Tcl_HashEntry *hPtr;
    char *operator;
    char savedChar;
    int maxDepth, objIndex, opIndex, length, code;
    char buffer[TCL_UTF_MAX];

    if (exprTokenPtr->type != TCL_TOKEN_SUB_EXPR) {
	panic("CompileSubExpr: token type %d not TCL_TOKEN_SUB_EXPR\n",
	        exprTokenPtr->type);
    }
    maxDepth = 0;
    code = TCL_OK;

    /*
     * Switch on the type of the first token after the subexpression token.
     * After processing it, advance tokenPtr to point just after the
     * subexpression's last token.




     */
    
    tokenPtr = exprTokenPtr+1;
    TRACE(exprTokenPtr->start, exprTokenPtr->size,
	    tokenPtr->start, tokenPtr->size);
    switch (tokenPtr->type) {
        case TCL_TOKEN_WORD:
	    code = TclCompileTokens(interp, tokenPtr+1,
	            tokenPtr->numComponents, envPtr);
	    if (code != TCL_OK) {


		goto done;
	    }


	    maxDepth = envPtr->maxStackDepth;

	    tokenPtr += (tokenPtr->numComponents + 1);
	    infoPtr->exprIsJustVarRef = 0;
	    break;
	    
        case TCL_TOKEN_TEXT:
	    if (tokenPtr->size > 0) {
		objIndex = TclRegisterLiteral(envPtr, tokenPtr->start,
	                tokenPtr->size, /*onHeap*/ 0);
	    } else {
		objIndex = TclRegisterLiteral(envPtr, "", 0, /*onHeap*/ 0);
	    }
	    TclEmitPush(objIndex, envPtr);
	    maxDepth = 1;
	    tokenPtr += 1;
	    infoPtr->exprIsJustVarRef = 0;
	    break;
	    
        case TCL_TOKEN_BS:
	    length = Tcl_UtfBackslash(tokenPtr->start, (int *) NULL,
		    buffer);
	    if (length > 0) {
		objIndex = TclRegisterLiteral(envPtr, buffer, length,
	                /*onHeap*/ 0);



	    } else {

		objIndex = TclRegisterLiteral(envPtr, "", 0, /*onHeap*/ 0);
	    }
	    TclEmitPush(objIndex, envPtr);
	    maxDepth = 1;
	    tokenPtr += 1;
	    infoPtr->exprIsJustVarRef = 0;
	    break;
	    
        case TCL_TOKEN_COMMAND:
	    code = TclCompileScript(interp, tokenPtr->start+1,
		    tokenPtr->size-2, /*nested*/ 1, envPtr);
	    if (code != TCL_OK) {
		goto done;
	    }
	    maxDepth = envPtr->maxStackDepth;
	    tokenPtr += 1;
	    infoPtr->exprIsJustVarRef = 0;
	    break;
	    
        case TCL_TOKEN_VARIABLE:
	    code = TclCompileTokens(interp, tokenPtr, 1, envPtr);
	    if (code != TCL_OK) {
		goto done;
	    }
	    maxDepth = envPtr->maxStackDepth;
	    tokenPtr += (tokenPtr->numComponents + 1);
	    break;
	    
        case TCL_TOKEN_SUB_EXPR:
	    infoPtr->exprIsComparison = 0;
	    code = CompileSubExpr(tokenPtr, infoPtr, envPtr);

	    if (code != TCL_OK) {
		goto done;
	    }
	    maxDepth = envPtr->maxStackDepth;
	    tokenPtr += (tokenPtr->numComponents + 1);
	    break;
	    
        case TCL_TOKEN_OPERATOR:

	    /*
	     * Look up the operator. Temporarily overwrite the character
	     * just after the end of the operator with a 0 byte. If the
	     * operator isn't found, treat it as a math function.
	     */


	    /*

	     * TODO: Note that the string is modified in place.  This is unsafe
	     * and will break if any of the routines called while the string is
	     * modified have side effects that depend on the original string
	     * being unmodified (e.g. adding an entry to the literal table).
	     */

	    operator = tokenPtr->start;
	    savedChar = operator[tokenPtr->size];
	    operator[tokenPtr->size] = 0;
	    hPtr = Tcl_FindHashEntry(&opHashTable, operator);
	    if (hPtr == NULL) {
		code = CompileMathFuncCall(exprTokenPtr, operator, infoPtr,
		        envPtr, &endPtr);
		operator[tokenPtr->size] = (char) savedChar;
		if (code != TCL_OK) {


		    goto done;
		}
		maxDepth = envPtr->maxStackDepth;
		tokenPtr = endPtr;
		infoPtr->exprIsJustVarRef = 0;
		infoPtr->exprIsComparison = 0;
		break;
	    }
	    operator[tokenPtr->size] = (char) savedChar;
	    opIndex = (int) Tcl_GetHashValue(hPtr);
	    opDescPtr = &(operatorTable[opIndex]);

	    /*
	     * If the operator is "normal", compile it using information
	     * from the operator table.
	     */

	    if (opDescPtr->numOperands > 0) {
		tokenPtr++;
		code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
		if (code != TCL_OK) {
		    goto done;
		}
		maxDepth = envPtr->maxStackDepth;
		tokenPtr += (tokenPtr->numComponents + 1);






		if (opDescPtr->numOperands == 2) {
		    code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
		    if (code != TCL_OK) {
			goto done;
		    }


		    maxDepth = TclMax((envPtr->maxStackDepth + 1),
		            maxDepth);
		    tokenPtr += (tokenPtr->numComponents + 1);
		}
		TclEmitOpcode(opDescPtr->instruction, envPtr);
		infoPtr->hasOperators = 1;
		infoPtr->exprIsJustVarRef = 0;
		infoPtr->exprIsComparison =
		        ((opIndex >= OP_LESS) && (opIndex <= OP_NEQ));
		break;
	    }




	    
	    /*

	     * The operator requires special treatment, and is either
	     * "+" or "-", or one of "&&", "||" or "?".
	     */
	    
	    switch (opIndex) {
	        case OP_PLUS:
	        case OP_MINUS:
		    tokenPtr++;
		    code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
		    if (code != TCL_OK) {
			goto done;
		    }
		    maxDepth = envPtr->maxStackDepth;
		    tokenPtr += (tokenPtr->numComponents + 1);
		    
		    /*
		     * Check whether the "+" or "-" is unary.
		     */
		    
		    afterSubexprPtr = exprTokenPtr
			    + exprTokenPtr->numComponents+1;
		    if (tokenPtr == afterSubexprPtr) {
			TclEmitOpcode(((opIndex==OP_PLUS)?
			        INST_UPLUS : INST_UMINUS),
			        envPtr);
			break;
		    }
		    
		    /*
		     * The "+" or "-" is binary.




		     */
		    
		    code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
		    if (code != TCL_OK) {
			goto done;
		    }
		    maxDepth = TclMax((envPtr->maxStackDepth + 1),
			    maxDepth);
		    tokenPtr += (tokenPtr->numComponents + 1);
		    TclEmitOpcode(((opIndex==OP_PLUS)? INST_ADD : INST_SUB),
			    envPtr);
		    break;

	        case OP_LAND:
	        case OP_LOR:
		    code = CompileLandOrLorExpr(exprTokenPtr, opIndex,
			    infoPtr, envPtr, &endPtr);
		    if (code != TCL_OK) {
			goto done;
		    }
		    maxDepth = envPtr->maxStackDepth;
		    tokenPtr = endPtr;
		    break;
			



	        case OP_QUESTY:
		    code = CompileCondExpr(exprTokenPtr, infoPtr,
			    envPtr, &endPtr);
		    if (code != TCL_OK) {
			goto done;

		    }
		    maxDepth = envPtr->maxStackDepth;
		    tokenPtr = endPtr;
		    break;
		    

		default:
		    panic("CompileSubExpr: unexpected operator %d requiring special treatment\n",
		        opIndex);
	    } /* end switch on operator requiring special treatment */
	    infoPtr->hasOperators = 1;
	    infoPtr->exprIsJustVarRef = 0;
	    infoPtr->exprIsComparison = 0;
	    break;


        default:
	    panic("CompileSubExpr: unexpected token type %d\n",
	            tokenPtr->type);
    }

    /*

     * Verify that the subexpression token had the required number of
     * subtokens: that we've advanced tokenPtr just beyond the
     * subexpression's last token. For example, a "*" subexpression must
     * contain the tokens for exactly two operands.
     */
    
    if (tokenPtr != (exprTokenPtr + exprTokenPtr->numComponents+1)) {
	LogSyntaxError(infoPtr);
	code = TCL_ERROR;
    }
    
    done:


    envPtr->maxStackDepth = maxDepth;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileLandOrLorExpr --
 *
 *	This procedure compiles a Tcl logical and ("&&") or logical or
 *	("||") subexpression.
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_OK is returned, a pointer to the token just after
 *	the last one in the subexpression is stored at the address in
 *	endPtrPtr. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileLandOrLorExpr(exprTokenPtr, opIndex, infoPtr, envPtr, endPtrPtr)
    Tcl_Token *exprTokenPtr;	 /* Points to TCL_TOKEN_SUB_EXPR token
				  * containing the "&&" or "||" operator. */
    int opIndex;		 /* A code describing the expression
				  * operator: either OP_LAND or OP_LOR. */
    ExprInfo *infoPtr;		 /* Describes the compilation state for the
				  * expression being compiled. */


    CompileEnv *envPtr;		 /* Holds resulting instructions. */
    Tcl_Token **endPtrPtr;	 /* If successful, a pointer to the token
				  * just after the last token in the
				  * subexpression is stored here. */
{



    JumpFixup shortCircuitFixup; /* Used to fix up the short circuit jump


				  * after the first subexpression. */
    JumpFixup lhsTrueFixup, lhsEndFixup;
    				 /* Used to fix up jumps used to convert the
				  * first operand to 0 or 1. */

    Tcl_Token *tokenPtr;
    int dist, maxDepth, code;





    /*
     * Emit code for the first operand.
     */



    maxDepth = 0;

    tokenPtr = exprTokenPtr+2;
    code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
    if (code != TCL_OK) {
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;
    tokenPtr += (tokenPtr->numComponents + 1);


    /*

     * Convert the first operand to the result that Tcl requires:

     * "0" or "1". Eventually we'll use a new instruction for this.
     */
    
    TclEmitForwardJump(envPtr, TCL_TRUE_JUMP, &lhsTrueFixup);
    TclEmitPush(TclRegisterLiteral(envPtr, "0", 1, /*onHeap*/ 0), envPtr);









    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &lhsEndFixup);
    dist = (envPtr->codeNext - envPtr->codeStart) - lhsTrueFixup.codeOffset;

    if (TclFixupForwardJump(envPtr, &lhsTrueFixup, dist, 127)) {
        badDist:
	panic("CompileLandOrLorExpr: bad jump distance %d\n", dist);
    }
    TclEmitPush(TclRegisterLiteral(envPtr, "1", 1, /*onHeap*/ 0), envPtr);
    dist = (envPtr->codeNext - envPtr->codeStart) - lhsEndFixup.codeOffset;
    if (TclFixupForwardJump(envPtr, &lhsEndFixup, dist, 127)) {
	goto badDist;
    }












    /*
     * Emit the "short circuit" jump around the rest of the expression.
     * Duplicate the "0" or "1" on top of the stack first to keep the
     * jump from consuming it.
     */

    TclEmitOpcode(INST_DUP, envPtr);













    TclEmitForwardJump(envPtr,
	    ((opIndex==OP_LAND)? TCL_FALSE_JUMP : TCL_TRUE_JUMP),
	    &shortCircuitFixup);

    /*
     * Emit code for the second operand.
     */

    code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
    if (code != TCL_OK) {
	goto done;
    }
    maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);
    tokenPtr += (tokenPtr->numComponents + 1);

    /*
     * Emit a "logical and" or "logical or" instruction. This does not try
     * to "short- circuit" the evaluation of both operands, but instead
     * ensures that we either have a "1" or a "0" result.
     */

    TclEmitOpcode(((opIndex==OP_LAND)? INST_LAND : INST_LOR), envPtr);


    /*
     * Now that we know the target of the forward jump, update it with the
     * correct distance.


     */



    dist = (envPtr->codeNext - envPtr->codeStart)
	    - shortCircuitFixup.codeOffset;
    TclFixupForwardJump(envPtr, &shortCircuitFixup, dist, 127);


    *endPtrPtr = tokenPtr;




    done:


    envPtr->maxStackDepth = maxDepth;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileCondExpr --
 *
 *	This procedure compiles a Tcl conditional expression:
 *	condExpr ::= lorExpr ['?' condExpr ':' condExpr]
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_OK is returned, a pointer to the token just after
 *	the last one in the subexpression is stored at the address in
 *	endPtrPtr. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the expression at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileCondExpr(exprTokenPtr, infoPtr, envPtr, endPtrPtr)
    Tcl_Token *exprTokenPtr;	/* Points to TCL_TOKEN_SUB_EXPR token
				 * containing the "?" operator. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */


    CompileEnv *envPtr;		/* Holds resulting instructions. */




    Tcl_Token **endPtrPtr;	/* If successful, a pointer to the token






				 * just after the last token in the






















































				 * subexpression is stored here. */



{



    JumpFixup jumpAroundThenFixup, jumpAroundElseFixup;



				/* Used to update or replace one-byte jumps


				 * around the then and else expressions when







				 * their target PCs are determined. */


    Tcl_Token *tokenPtr;

    int elseCodeOffset, dist, maxDepth, code;



    /*


     * Emit code for the test.




























     */



















    maxDepth = 0;
    tokenPtr = exprTokenPtr+2;



    code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
    if (code != TCL_OK) {
	goto done;
    }

















    maxDepth = envPtr->maxStackDepth;


    tokenPtr += (tokenPtr->numComponents + 1);


















    














































    /*
     * Emit the jump to the "else" expression if the test was false.
     */
    
    TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpAroundThenFixup);








    /*


     * Compile the "then" expression. Note that if a subexpression is only






     * a primary, we need to try to convert it to numeric. We do this to
     * support Tcl's policy of interpreting operands if at all possible as









     * first integers, else floating-point numbers.
     */























    infoPtr->hasOperators = 0;

    code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
    if (code != TCL_OK) {
	goto done;
    }
































    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);


    tokenPtr += (tokenPtr->numComponents + 1);












































    if (!infoPtr->hasOperators) {













	TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);


    }



    /*


     * Emit an unconditional jump around the "else" condExpr.




























     */


















    

    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,








	    &jumpAroundElseFixup);














    /*


     * Compile the "else" expression.










     */





























































    elseCodeOffset = (envPtr->codeNext - envPtr->codeStart);
    infoPtr->hasOperators = 0;
    code = CompileSubExpr(tokenPtr, infoPtr, envPtr);



    if (code != TCL_OK) {



	goto done;


    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);



    tokenPtr += (tokenPtr->numComponents + 1);









    if (!infoPtr->hasOperators) {



	TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);



    }












































    /*

     * Fix up the second jump around the "else" expression.
     */





























    dist = (envPtr->codeNext - envPtr->codeStart)







	    - jumpAroundElseFixup.codeOffset;














    if (TclFixupForwardJump(envPtr, &jumpAroundElseFixup, dist, 127)) {
	/*

	 * Update the else expression's starting code offset since it

	 * moved down 3 bytes too.
	 */












	











	elseCodeOffset += 3;







    }



	












    /*

     * Fix up the first jump to the "else" expression if the test was false.
     */








    


    dist = (elseCodeOffset - jumpAroundThenFixup.codeOffset);







    TclFixupForwardJump(envPtr, &jumpAroundThenFixup, dist, 127);















    *endPtrPtr = tokenPtr;















    done:
    envPtr->maxStackDepth = maxDepth;
    return code;






}

/*
 *----------------------------------------------------------------------
 *
 * CompileMathFuncCall --
 *
 *	This procedure compiles a call on a math function in an expression:
 *	mathFuncCall ::= funcName '(' [condExpr {',' condExpr}] ')'
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_OK is returned, a pointer to the token just after
 *	the last one in the subexpression is stored at the address in
 *	endPtrPtr. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the function.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the math function at
 *	runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileMathFuncCall(exprTokenPtr, funcName, infoPtr, envPtr, endPtrPtr)
    Tcl_Token *exprTokenPtr;	/* Points to TCL_TOKEN_SUB_EXPR token
				 * containing the math function call. */
    char *funcName;		/* Name of the math function. */
    ExprInfo *infoPtr;		/* Describes the compilation state for the
				 * expression being compiled. */


    CompileEnv *envPtr;		/* Holds resulting instructions. */
    Tcl_Token **endPtrPtr;	/* If successful, a pointer to the token
				 * just after the last token in the
				 * subexpression is stored here. */
{
    Tcl_Interp *interp = infoPtr->interp;
    Interp *iPtr = (Interp *) interp;


    MathFunc *mathFuncPtr;



    Tcl_HashEntry *hPtr;
    Tcl_Token *tokenPtr, *afterSubexprPtr;

    int maxDepth, code, i;

    /*


     * Look up the MathFunc record for the function.
     */








    code = TCL_OK;











    maxDepth = 0;
    hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, funcName);
    if (hPtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"unknown math function \"", funcName, "\"", (char *) NULL);
	code = TCL_ERROR;

	goto done;
    }
    mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);

    /*
     * If not a builtin function, push an object with the function's name.
     */

    if (mathFuncPtr->builtinFuncIndex < 0) {
	TclEmitPush(TclRegisterLiteral(envPtr, funcName, -1, /*onHeap*/ 0),
	        envPtr);

	maxDepth = 1;
    }

    /*
     * Compile any arguments for the function.
     */


    tokenPtr = exprTokenPtr+2;



    afterSubexprPtr = exprTokenPtr + (exprTokenPtr->numComponents + 1);
    if (mathFuncPtr->numArgs > 0) {
	for (i = 0;  i < mathFuncPtr->numArgs;  i++) {





	    if (tokenPtr == afterSubexprPtr) {









		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "too few arguments for math function", -1);
		code = TCL_ERROR;
		goto done;
	    }
	    infoPtr->exprIsComparison = 0;
	    code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
	    if (code != TCL_OK) {
		goto done;
	    }
	    tokenPtr += (tokenPtr->numComponents + 1);
	    maxDepth++;
	}
	if (tokenPtr != afterSubexprPtr) {

	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		    "too many arguments for math function", -1);
	    code = TCL_ERROR;
	    goto done;


	} 

    } else if (tokenPtr != afterSubexprPtr) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),





		"too many arguments for math function", -1);




	code = TCL_ERROR;
	goto done;
    }
    
    /*
     * Compile the call on the math function. Note that the "objc" argument
     * count for non-builtin functions is incremented by 1 to include the
     * function name itself.
     */

    if (mathFuncPtr->builtinFuncIndex >= 0) { /* a builtin function */
	TclEmitInstInt1(INST_CALL_BUILTIN_FUNC1, 
	        mathFuncPtr->builtinFuncIndex, envPtr);
    } else {
	TclEmitInstInt1(INST_CALL_FUNC1, (mathFuncPtr->numArgs+1), envPtr);
    }
    *endPtrPtr = afterSubexprPtr;




    done:

    envPtr->maxStackDepth = maxDepth;
    return code;






}

/*
 *----------------------------------------------------------------------
 *






















 * LogSyntaxError --
























































































































































































 *







 *	This procedure is invoked after an error occurs when compiling an































 *	expression. It sets the interpreter result to an error message





 *	describing the error.

































































































































































 *
 * Results:
 *	None.
 *
 * Side effects:

 *	Sets the interpreter result to an error message describing the

 *	expression that was being compiled when the error occurred.



 *
 *----------------------------------------------------------------------
 */

static void














LogSyntaxError(infoPtr)
    ExprInfo *infoPtr;		/* Describes the compilation state for the

				 * expression being compiled. */





{










    int numBytes = (infoPtr->lastChar - infoPtr->expr);







    char buffer[100];





    sprintf(buffer, "syntax error in expression \"%.*s\"",




	    ((numBytes > 60)? 60 : numBytes), infoPtr->expr);



    Tcl_AppendStringsToObj(Tcl_GetObjResult(infoPtr->interp),

	    buffer, (char *) NULL);
}

Changes to generic/tclCompile.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
65
66
/* 
 * tclCompile.c --
 *
 *	This file contains procedures that compile Tcl commands or parts
 *	of commands (like quoted strings or nested sub-commands) into a
 *	sequence of instructions ("bytecodes"). 
 *
 * 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.
 *
 * SCCS: @(#) tclCompile.c 1.80 97/09/18 18:23:30
 */

#include "tclInt.h"
#include "tclCompile.h"










/*
 * Variable that controls whether compilation tracing is enabled and, if so,
 * what level of tracing is desired:
 *    0: no compilation tracing
 *    1: summarize compilation of top level cmds and proc bodies
 *    2: display all instructions of each ByteCode compiled
 * This variable is linked to the Tcl variable "tcl_traceCompile".
 */

int tclTraceCompile = 0;
static int traceInitialized = 0;

/*
 * Count of the number of compilations and various other compilation-
 * related statistics.
 */

#ifdef TCL_COMPILE_STATS
long tclNumCompilations = 0;
double tclTotalSourceBytes = 0.0;
double tclTotalCodeBytes = 0.0;

double tclTotalInstBytes = 0.0;
double tclTotalObjBytes = 0.0;
double tclTotalExceptBytes = 0.0;
double tclTotalAuxBytes = 0.0;
double tclTotalCmdMapBytes = 0.0;

double tclCurrentSourceBytes = 0.0;
double tclCurrentCodeBytes = 0.0;

int tclSourceCount[32];
int tclByteCodeCount[32];
#endif /* TCL_COMPILE_STATS */

/*
 * A table describing the Tcl bytecode instructions. The entries in this
 * table must correspond to the list of instructions in tclInt.h. The names
 * "op1" and "op4" refer to an instruction's one or four byte first operand.
 * Similarly, "stktop" and "stknext" refer to the topmost and next to
 * topmost stack elements.
 *
 * Note that the load, store, and incr instructions do not distinguish local
 * from global variables; the bytecode interpreter at runtime uses the
 * existence of a procedure call frame to distinguish these.
 */

InstructionDesc instructionTable[] = {







|




|





>
>
>
>
>
>
>
>
>













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







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
/* 
 * tclCompile.c --
 *
 *	This file contains procedures that compile Tcl commands or parts
 *	of commands (like quoted strings or nested sub-commands) into a
 *	sequence of instructions ("bytecodes"). 
 *
 * Copyright (c) 1996-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: tclCompile.c,v 1.1.2.10 1999/03/24 01:42:47 surles Exp $
 */

#include "tclInt.h"
#include "tclCompile.h"

/*
 * Table of all AuxData types.
 */
 
static Tcl_HashTable auxDataTypeTable;
static int auxDataTypeTableInitialized; /* 0 means not yet initialized. */

TCL_DECLARE_MUTEX(tableMutex)

/*
 * Variable that controls whether compilation tracing is enabled and, if so,
 * what level of tracing is desired:
 *    0: no compilation tracing
 *    1: summarize compilation of top level cmds and proc bodies
 *    2: display all instructions of each ByteCode compiled
 * This variable is linked to the Tcl variable "tcl_traceCompile".
 */

int tclTraceCompile = 0;
static int traceInitialized = 0;

/*























 * A table describing the Tcl bytecode instructions. Entries in this table
 * must correspond to the instruction opcode definitions in tclCompile.h.
 * The names "op1" and "op4" refer to an instruction's one or four byte
 * first operand. Similarly, "stktop" and "stknext" refer to the topmost
 * and next to topmost stack elements.
 *
 * Note that the load, store, and incr instructions do not distinguish local
 * from global variables; the bytecode interpreter at runtime uses the
 * existence of a procedure call frame to distinguish these.
 */

InstructionDesc instructionTable[] = {
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400


401
402
403

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725


726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743







744
745
746
747
748
749

750
751
752
753
754
755
756
757
758
759
760
761
762
763

764
765
766
767
768
769
770
771
772
773
774



775
776
777
778
779
780
781
782
783
784
785

786
787
788
789
790
791

792
793
794
795

796
797
798
799
800


801
802
803
804
805
806

807
808
809
810
811



812



813
814

815
816
817
818
819
820
821
822
823
824

825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
        /* Initialize execution of a foreach loop. Operand is aux data index
	 * of the ForeachInfo structure for the foreach command. */
    {"foreach_step4",     5,   1,   {OPERAND_UINT4}},
        /* "Step" or begin next iteration of foreach loop. Push 0 if to
	 *  terminate loop, else push 1. */

    {"beginCatch4",	  5,   1,   {OPERAND_UINT4}},
        /* Record start of catch with the operand's exception range index.
	 * Push the current stack depth onto a special catch stack. */
    {"endCatch",	  1,   0,   {OPERAND_NONE}},
        /* End of last catch. Pop the bytecode interpreter's catch stack. */
    {"pushResult",	  1,   0,   {OPERAND_NONE}},
        /* Push the interpreter's object result onto the stack. */
    {"pushReturnCode",	  1,   0,   {OPERAND_NONE}},
        /* Push interpreter's return code (e.g. TCL_OK or TCL_ERROR) as
	 * a new object onto the stack. */
    {0}
};

/*
 * The following table assigns a type to each character. Only types
 * meaningful to Tcl parsing are represented here. The table is
 * designed to be referenced with either signed or unsigned characters,
 * so it has 384 entries. The first 128 entries correspond to negative
 * character values, the next 256 correspond to positive character
 * values. The last 128 entries are identical to the first 128. The
 * table is always indexed with a 128-byte offset (the 128th entry
 * corresponds to a 0 character value).
 */

unsigned char tclTypeTable[] = {
    /*
     * Negative character values, from -128 to -1:
     */

    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,

    /*
     * Positive character values, from 0-127:
     */

    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_SPACE,         TCL_COMMAND_END,   TCL_SPACE,
    TCL_SPACE,         TCL_SPACE,         TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_SPACE,         TCL_NORMAL,        TCL_QUOTE,         TCL_NORMAL,
    TCL_DOLLAR,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_COMMAND_END,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_OPEN_BRACKET,
    TCL_BACKSLASH,     TCL_COMMAND_END,   TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_OPEN_BRACE,
    TCL_NORMAL,        TCL_CLOSE_BRACE,   TCL_NORMAL,        TCL_NORMAL,

    /*
     * Large unsigned character values, from 128-255:
     */

    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
    TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,        TCL_NORMAL,
};

/*
 * Prototypes for procedures defined later in this file:
 */

static void		AdvanceToNextWord _ANSI_ARGS_((char *string,
			    CompileEnv *envPtr));
static int		CollectArgInfo _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char *lastChar, int flags,
			    ArgInfo *argInfoPtr));
static int		CompileBraces _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char *lastChar, int flags,
			    CompileEnv *envPtr));
static int		CompileCmdWordInline _ANSI_ARGS_((
    			    Tcl_Interp *interp, char *string,
			    char *lastChar, int flags, CompileEnv *envPtr));
static int		CompileExprWord _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char *lastChar, int flags, 
			    CompileEnv *envPtr));
static int		CompileMultipartWord _ANSI_ARGS_((
    			    Tcl_Interp *interp, char *string,
			    char *lastChar, int flags, CompileEnv *envPtr));
static int		CompileWord _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char *lastChar, int flags, 
			    CompileEnv *envPtr));
static int		CreateExceptionRange _ANSI_ARGS_((
			    ExceptionRangeType type, CompileEnv *envPtr));
static void		DupByteCodeInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
			    Tcl_Obj *copyPtr));
static ClientData	DupForeachInfo _ANSI_ARGS_((ClientData clientData));
static unsigned char *	EncodeCmdLocMap _ANSI_ARGS_((
			    CompileEnv *envPtr, ByteCode *codePtr,
			    unsigned char *startPtr));
static void		EnterCmdExtentData _ANSI_ARGS_((
    			    CompileEnv *envPtr, int cmdNumber,
			    int numSrcChars, int numCodeBytes));
static void		EnterCmdStartData _ANSI_ARGS_((
    			    CompileEnv *envPtr, int cmdNumber,
			    int srcOffset, int codeOffset));
static void		ExpandObjectArray _ANSI_ARGS_((CompileEnv *envPtr));
static void		FreeForeachInfo _ANSI_ARGS_((
			    ClientData clientData));
static void		FreeByteCodeInternalRep _ANSI_ARGS_((
    			    Tcl_Obj *objPtr));
static void		FreeArgInfo _ANSI_ARGS_((ArgInfo *argInfoPtr));
static int		GetCmdLocEncodingSize _ANSI_ARGS_((
			    CompileEnv *envPtr));
static void		InitArgInfo _ANSI_ARGS_((ArgInfo *argInfoPtr));


static int		LookupCompiledLocal _ANSI_ARGS_((
        		    char *name, int nameChars, int createIfNew,
			    int flagsIfCreated, Proc *procPtr));

static int		SetByteCodeFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
static void		UpdateStringOfByteCode _ANSI_ARGS_((Tcl_Obj *objPtr));

/*
 * The structure below defines the bytecode Tcl object type by
 * means of procedures that can be invoked by generic object code.
 */

Tcl_ObjType tclByteCodeType = {
    "bytecode",			/* name */
    FreeByteCodeInternalRep,	/* freeIntRepProc */
    DupByteCodeInternalRep,	/* dupIntRepProc */
    UpdateStringOfByteCode,	/* updateStringProc */
    SetByteCodeFromAny		/* setFromAnyProc */
};

/*
 *----------------------------------------------------------------------
 *
 * TclPrintByteCodeObj --
 *
 *	This procedure prints ("disassembles") the instructions of a
 *	bytecode object to stdout.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TclPrintByteCodeObj(interp, objPtr)
    Tcl_Interp *interp;		/* Used only for Tcl_GetStringFromObj. */
    Tcl_Obj *objPtr;		/* The bytecode object to disassemble. */
{
    ByteCode* codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
    unsigned char *codeStart, *codeLimit, *pc;
    unsigned char *codeDeltaNext, *codeLengthNext;
    unsigned char *srcDeltaNext, *srcLengthNext;
    int codeOffset, codeLen, srcOffset, srcLen;
    int numCmds, numObjs, delta, objBytes, i;

    if (codePtr->refCount <= 0) {
	return;			/* already freed */
    }

    codeStart = codePtr->codeStart;
    codeLimit = (codeStart + codePtr->numCodeBytes);
    numCmds = codePtr->numCommands;
    numObjs = codePtr->numObjects;

    objBytes = (numObjs * sizeof(Tcl_Obj));
    for (i = 0;  i < numObjs;  i++) {
	Tcl_Obj *litObjPtr = codePtr->objArrayPtr[i];
	if (litObjPtr->bytes != NULL) {
	    objBytes += litObjPtr->length;
	}
    }

    /*
     * Print header lines describing the ByteCode.
     */

    fprintf(stdout, "\nByteCode 0x%x, ref ct %u, epoch %u, interp 0x%x(epoch %u)\n",
	    (unsigned int) codePtr, codePtr->refCount,
	    codePtr->compileEpoch, (unsigned int) codePtr->iPtr,
	    codePtr->iPtr->compileEpoch);
    fprintf(stdout, "  Source ");
    TclPrintSource(stdout, codePtr->source,
	    TclMin(codePtr->numSrcChars, 70));
    fprintf(stdout, "\n  Cmds %d, chars %d, inst %d, objs %u, aux %d, stk depth %u, code/src %.2f\n",
	    numCmds, codePtr->numSrcChars, codePtr->numCodeBytes, numObjs,
	    codePtr->numAuxDataItems, codePtr->maxStackDepth,
	    (codePtr->numSrcChars?
	            ((float)codePtr->totalSize)/((float)codePtr->numSrcChars) : 0.0));
    fprintf(stdout, "  Code %d = %d(header)+%d(inst)+%d(objs)+%d(exc)+%d(aux)+%d(cmd map)\n",
	    codePtr->totalSize, sizeof(ByteCode), codePtr->numCodeBytes,
	    objBytes, (codePtr->numExcRanges * sizeof(ExceptionRange)),
	    (codePtr->numAuxDataItems * sizeof(AuxData)),
	    codePtr->numCmdLocBytes);

    /*
     * If the ByteCode is the compiled body of a Tcl procedure, print
     * information about that procedure. Note that we don't know the
     * procedure's name since ByteCode's can be shared among procedures.
     */
    
    if (codePtr->procPtr != NULL) {
	Proc *procPtr = codePtr->procPtr;
	int numCompiledLocals = procPtr->numCompiledLocals;
	fprintf(stdout,
	        "  Proc 0x%x, ref ct %d, args %d, compiled locals %d\n",
		(unsigned int) procPtr, procPtr->refCount, procPtr->numArgs,
		numCompiledLocals);
	if (numCompiledLocals > 0) {
	    CompiledLocal *localPtr = procPtr->firstLocalPtr;
	    for (i = 0;  i < numCompiledLocals;  i++) {
		fprintf(stdout, "      %d: slot %d%s%s%s%s%s",
			i, localPtr->frameIndex,
			((localPtr->flags & VAR_SCALAR)?  ", scalar"  : ""),
			((localPtr->flags & VAR_ARRAY)?  ", array"  : ""),
			((localPtr->flags & VAR_LINK)?  ", link"  : ""),
			(localPtr->isArg?  ", arg"  : ""),
			(localPtr->isTemp? ", temp" : ""));
		if (localPtr->isTemp) {
		    fprintf(stdout,	"\n");
		} else {
		    fprintf(stdout,	", name=\"%s\"\n", localPtr->name);
		}
		localPtr = localPtr->nextPtr;
	    }
	}
    }

    /*
     * Print the ExceptionRange array.
     */

    if (codePtr->numExcRanges > 0) {
	fprintf(stdout, "  Exception ranges %d, depth %d:\n",
	        codePtr->numExcRanges, codePtr->maxExcRangeDepth);
	for (i = 0;  i < codePtr->numExcRanges;  i++) {
	    ExceptionRange *rangePtr = &(codePtr->excRangeArrayPtr[i]);
	    fprintf(stdout, "      %d: level %d, %s, pc %d-%d, ",
		    i, rangePtr->nestingLevel,
		    ((rangePtr->type == LOOP_EXCEPTION_RANGE)? "loop":"catch"),
		    rangePtr->codeOffset,
		    (rangePtr->codeOffset + rangePtr->numCodeBytes - 1));
	    switch (rangePtr->type) {
	    case LOOP_EXCEPTION_RANGE:
		fprintf(stdout,	"continue %d, break %d\n",
		        rangePtr->continueOffset, rangePtr->breakOffset);
		break;
	    case CATCH_EXCEPTION_RANGE:
		fprintf(stdout,	"catch %d\n", rangePtr->catchOffset);
		break;
	    default:
		panic("TclPrintSource: unrecognized ExceptionRange type %d\n",
		        rangePtr->type);
	    }
	}
    }
    
    /*
     * If there were no commands (e.g., an expression or an empty string
     * was compiled), just print all instructions and return.
     */

    if (numCmds == 0) {
	pc = codeStart;
	while (pc < codeLimit) {
	    fprintf(stdout, "    ");
	    pc += TclPrintInstruction(codePtr, pc);
	}
	return;
    }
    
    /*
     * Print table showing the code offset, source offset, and source
     * length for each command. These are encoded as a sequence of bytes.
     */

    fprintf(stdout, "  Commands %d:", numCmds);
    codeDeltaNext = codePtr->codeDeltaStart;
    codeLengthNext = codePtr->codeLengthStart;
    srcDeltaNext  = codePtr->srcDeltaStart;
    srcLengthNext = codePtr->srcLengthStart;
    codeOffset = srcOffset = 0;
    for (i = 0;  i < numCmds;  i++) {
	if ((unsigned int) (*codeDeltaNext) == (unsigned int) 0xFF) {
	    codeDeltaNext++;
	    delta = TclGetInt4AtPtr(codeDeltaNext);
	    codeDeltaNext += 4;
	} else {
	    delta = TclGetInt1AtPtr(codeDeltaNext);
	    codeDeltaNext++;
	}
	codeOffset += delta;

	if ((unsigned int) (*codeLengthNext) == (unsigned int) 0xFF) {
	    codeLengthNext++;
	    codeLen = TclGetInt4AtPtr(codeLengthNext);
	    codeLengthNext += 4;
	} else {
	    codeLen = TclGetInt1AtPtr(codeLengthNext);
	    codeLengthNext++;
	}
	
	if ((unsigned int) (*srcDeltaNext) == (unsigned int) 0xFF) {
	    srcDeltaNext++;
	    delta = TclGetInt4AtPtr(srcDeltaNext);
	    srcDeltaNext += 4;
	} else {
	    delta = TclGetInt1AtPtr(srcDeltaNext);
	    srcDeltaNext++;
	}
	srcOffset += delta;

	if ((unsigned int) (*srcLengthNext) == (unsigned int) 0xFF) {
	    srcLengthNext++;
	    srcLen = TclGetInt4AtPtr(srcLengthNext);
	    srcLengthNext += 4;
	} else {
	    srcLen = TclGetInt1AtPtr(srcLengthNext);
	    srcLengthNext++;
	}
	
	fprintf(stdout,	"%s%4d: pc %d-%d, source %d-%d",
		((i % 2)? "	" : "\n   "),
		(i+1), codeOffset, (codeOffset + codeLen - 1),
		srcOffset, (srcOffset + srcLen - 1));
    }
    if ((numCmds > 0) && ((numCmds % 2) != 0)) {
	fprintf(stdout,	"\n");
    }
    
    /*
     * Print each instruction. If the instruction corresponds to the start
     * of a command, print the command's source. Note that we don't need
     * the code length here.
     */

    codeDeltaNext = codePtr->codeDeltaStart;
    srcDeltaNext  = codePtr->srcDeltaStart;
    srcLengthNext = codePtr->srcLengthStart;
    codeOffset = srcOffset = 0;
    pc = codeStart;
    for (i = 0;  i < numCmds;  i++) {
	if ((unsigned int) (*codeDeltaNext) == (unsigned int) 0xFF) {
	    codeDeltaNext++;
	    delta = TclGetInt4AtPtr(codeDeltaNext);
	    codeDeltaNext += 4;
	} else {
	    delta = TclGetInt1AtPtr(codeDeltaNext);
	    codeDeltaNext++;
	}
	codeOffset += delta;

	if ((unsigned int) (*srcDeltaNext) == (unsigned int) 0xFF) {
	    srcDeltaNext++;
	    delta = TclGetInt4AtPtr(srcDeltaNext);
	    srcDeltaNext += 4;
	} else {
	    delta = TclGetInt1AtPtr(srcDeltaNext);
	    srcDeltaNext++;
	}
	srcOffset += delta;

	if ((unsigned int) (*srcLengthNext) == (unsigned int) 0xFF) {
	    srcLengthNext++;
	    srcLen = TclGetInt4AtPtr(srcLengthNext);
	    srcLengthNext += 4;
	} else {
	    srcLen = TclGetInt1AtPtr(srcLengthNext);
	    srcLengthNext++;
	}

	/*
	 * Print instructions before command i.
	 */
	
	while ((pc-codeStart) < codeOffset) {
	    fprintf(stdout, "    ");
	    pc += TclPrintInstruction(codePtr, pc);
	}

	fprintf(stdout, "  Command %d: ", (i+1));
	TclPrintSource(stdout, (codePtr->source + srcOffset),
	        TclMin(srcLen, 70));
	fprintf(stdout, "\n");
    }
    if (pc < codeLimit) {
	/*
	 * Print instructions after the last command.
	 */

	while (pc < codeLimit) {
	    fprintf(stdout, "    ");
	    pc += TclPrintInstruction(codePtr, pc);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclPrintInstruction --
 *
 *	This procedure prints ("disassembles") one instruction from a
 *	bytecode object to stdout.
 *
 * Results:
 *	Returns the length in bytes of the current instruiction.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclPrintInstruction(codePtr, pc)
    ByteCode* codePtr;		/* Bytecode containing the instruction. */
    unsigned char *pc;		/* Points to first byte of instruction. */
{
    Proc *procPtr = codePtr->procPtr;
    unsigned char opCode = *pc;
    register InstructionDesc *instDesc = &instructionTable[opCode];
    unsigned char *codeStart = codePtr->codeStart;
    unsigned int pcOffset = (pc - codeStart);
    int opnd, elemLen, i, j;
    Tcl_Obj *elemPtr;
    char *string;
    
    fprintf(stdout, "(%u) %s ", pcOffset, instDesc->name);
    for (i = 0;  i < instDesc->numOperands;  i++) {
	switch (instDesc->opTypes[i]) {
	case OPERAND_INT1:


	    opnd = TclGetInt1AtPtr(pc+1+i);
	    if ((i == 0) && ((opCode == INST_JUMP1)
			     || (opCode == INST_JUMP_TRUE1)
		             || (opCode == INST_JUMP_FALSE1))) {
		fprintf(stdout, "%d  	# pc %u", opnd, (pcOffset + opnd));
	    } else {
		fprintf(stdout, "%d", opnd);
	    }
	    break;
	case OPERAND_INT4:
	    opnd = TclGetInt4AtPtr(pc+1+i);
	    if ((i == 0) && ((opCode == INST_JUMP4)
			     || (opCode == INST_JUMP_TRUE4)
		             || (opCode == INST_JUMP_FALSE4))) {
		fprintf(stdout, "%d  	# pc %u", opnd, (pcOffset + opnd));
	    } else {
		fprintf(stdout, "%d", opnd);
	    }







	    break;
	case OPERAND_UINT1:
	    opnd = TclGetUInt1AtPtr(pc+1+i);
	    if ((i == 0) && (opCode == INST_PUSH1)) {
		elemPtr = codePtr->objArrayPtr[opnd];
		string = Tcl_GetStringFromObj(elemPtr, &elemLen);

		fprintf(stdout, "%u  	# ", (unsigned int) opnd);
		TclPrintSource(stdout, string, TclMin(elemLen, 40));
	    } else if ((i == 0) && ((opCode == INST_LOAD_SCALAR1)
				    || (opCode == INST_LOAD_ARRAY1)
				    || (opCode == INST_STORE_SCALAR1)
				    || (opCode == INST_STORE_ARRAY1))) {
		int localCt = procPtr->numCompiledLocals;
		CompiledLocal *localPtr = procPtr->firstLocalPtr;
		if (opnd >= localCt) {
		    panic("TclPrintInstruction: bad local var index %u (%u locals)\n",
			     (unsigned int) opnd, localCt);
		    return instDesc->numBytes;
		}
		for (j = 0;  j < opnd;  j++) {

		    localPtr = localPtr->nextPtr;
		}
		if (localPtr->isTemp) {
		    fprintf(stdout, "%u	# temp var %u",
			    (unsigned int) opnd, (unsigned int) opnd);
		} else {
		    fprintf(stdout, "%u	# var ", (unsigned int) opnd);
		    TclPrintSource(stdout, localPtr->name, 40);
		}
	    } else {
		fprintf(stdout, "%u ", (unsigned int) opnd);



	    }
	    break;
	case OPERAND_UINT4:
	    opnd = TclGetUInt4AtPtr(pc+1+i);
	    if (opCode == INST_PUSH4) {
		elemPtr = codePtr->objArrayPtr[opnd];
		string = Tcl_GetStringFromObj(elemPtr, &elemLen);
		fprintf(stdout, "%u  	# ", opnd);
		TclPrintSource(stdout, string, TclMin(elemLen, 40));
	    } else if ((i == 0) && ((opCode == INST_LOAD_SCALAR4)
				    || (opCode == INST_LOAD_ARRAY4)

				    || (opCode == INST_STORE_SCALAR4)
				    || (opCode == INST_STORE_ARRAY4))) {
		int localCt = procPtr->numCompiledLocals;
		CompiledLocal *localPtr = procPtr->firstLocalPtr;
		if (opnd >= localCt) {
		    panic("TclPrintInstruction: bad local var index %u (%u locals)\n",

			     (unsigned int) opnd, localCt);
		    return instDesc->numBytes;
		}
		for (j = 0;  j < opnd;  j++) {

		    localPtr = localPtr->nextPtr;
		}
		if (localPtr->isTemp) {
		    fprintf(stdout, "%u	# temp var %u",
			    (unsigned int) opnd, (unsigned int) opnd);


		} else {
		    fprintf(stdout, "%u	# var ", (unsigned int) opnd);
		    TclPrintSource(stdout, localPtr->name, 40);
		}
	    } else {
		fprintf(stdout, "%u ", (unsigned int) opnd);

	    }
	    break;
	case OPERAND_NONE:
	default:
	    break;



	}



    }
    fprintf(stdout, "\n");

    return instDesc->numBytes;
}

/*
 *----------------------------------------------------------------------
 *
 * TclPrintSource --
 *
 *	This procedure prints up to a specified number of characters from
 *	the argument string to a specified file. It tries to produce legible

 *	output by adding backslashes as necessary.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Outputs characters to the specified file.
 *
 *----------------------------------------------------------------------
 */

void
TclPrintSource(outFile, string, maxChars)
    FILE *outFile;		/* The file to print the source to. */
    char *string;		/* The string to print. */
    int maxChars;		/* Maximum number of chars to print. */
{
    register char *p;
    register int i = 0;

    if (string == NULL) {
	fprintf(outFile, "\"\"");
	return;
    }

    fprintf(outFile, "\"");
    p = string;
    for (;  (*p != '\0') && (i < maxChars);  p++, i++) {
	switch (*p) {
	    case '"':
		fprintf(outFile, "\\\"");
		continue;
	    case '\f':
		fprintf(outFile, "\\f");
		continue;
	    case '\n':
		fprintf(outFile, "\\n");
		continue;
            case '\r':
		fprintf(outFile, "\\r");
		continue;
	    case '\t':
		fprintf(outFile, "\\t");
		continue;
            case '\v':
		fprintf(outFile, "\\v");
		continue;
	    default:
		fprintf(outFile, "%c", *p);
		continue;
	}
    }
    fprintf(outFile, "\"");
}

/*
 *----------------------------------------------------------------------
 *
 * FreeByteCodeInternalRep --
 *







|












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



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


<





|



<
<
<


<


|
>
>
|
<
|
>


<







|
|
|
|
|



|

|

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

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

<
>
|





|

|
|
>
|





|




|
|
|
|
<

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







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216




























































































































217
218
219






















220
221

222
223
224
225
226
227
228
229
230



231
232

233
234
235
236
237
238

239
240
241
242

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











262











263



264




265







266



267






























268











269







270
271
272

273
























274


275

276








277



278















279

280








281









282








283








284





















285









286








287



288




289









290






291
















292
293











294
295
296
297

298
299
300
301






302
303


304
305


306
307
308
309
310
311
312
313
314
315
316
317
318

319
320
321
322
323
324
325
326
327
328
329




330
331
332
333
334






335


336
337
338
339




340



341
342
343
344
345




346


347

348
349

350


351
352
353

354
355


356
357




358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

393





394






























395
396
397
398
399
400
401
        /* Initialize execution of a foreach loop. Operand is aux data index
	 * of the ForeachInfo structure for the foreach command. */
    {"foreach_step4",     5,   1,   {OPERAND_UINT4}},
        /* "Step" or begin next iteration of foreach loop. Push 0 if to
	 *  terminate loop, else push 1. */

    {"beginCatch4",	  5,   1,   {OPERAND_UINT4}},
        /* Record start of catch with the operand's exception index.
	 * Push the current stack depth onto a special catch stack. */
    {"endCatch",	  1,   0,   {OPERAND_NONE}},
        /* End of last catch. Pop the bytecode interpreter's catch stack. */
    {"pushResult",	  1,   0,   {OPERAND_NONE}},
        /* Push the interpreter's object result onto the stack. */
    {"pushReturnCode",	  1,   0,   {OPERAND_NONE}},
        /* Push interpreter's return code (e.g. TCL_OK or TCL_ERROR) as
	 * a new object onto the stack. */
    {0}
};

/*




























































































































 * Prototypes for procedures defined later in this file:
 */























static void		DupByteCodeInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
			    Tcl_Obj *copyPtr));

static unsigned char *	EncodeCmdLocMap _ANSI_ARGS_((
			    CompileEnv *envPtr, ByteCode *codePtr,
			    unsigned char *startPtr));
static void		EnterCmdExtentData _ANSI_ARGS_((
    			    CompileEnv *envPtr, int cmdNumber,
			    int numSrcBytes, int numCodeBytes));
static void		EnterCmdStartData _ANSI_ARGS_((
    			    CompileEnv *envPtr, int cmdNumber,
			    int srcOffset, int codeOffset));



static void		FreeByteCodeInternalRep _ANSI_ARGS_((
    			    Tcl_Obj *objPtr));

static int		GetCmdLocEncodingSize _ANSI_ARGS_((
			    CompileEnv *envPtr));
static void		LogCompilationInfo _ANSI_ARGS_((Tcl_Interp *interp,
        		    char *script, char *command, int length));
#ifdef TCL_COMPILE_STATS
static void		RecordByteCodeStats _ANSI_ARGS_((

			    ByteCode *codePtr));
#endif /* TCL_COMPILE_STATS */
static int		SetByteCodeFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));


/*
 * The structure below defines the bytecode Tcl object type by
 * means of procedures that can be invoked by generic object code.
 */

Tcl_ObjType tclByteCodeType = {
    "bytecode",				/* name */
    FreeByteCodeInternalRep,		/* freeIntRepProc */
    DupByteCodeInternalRep,		/* dupIntRepProc */
    (Tcl_UpdateStringProc *) NULL,	/* updateStringProc */
    SetByteCodeFromAny			/* setFromAnyProc */
};

/*
 *-----------------------------------------------------------------------
 *
 * SetByteCodeFromAny --
 *











 *	Part of the bytecode Tcl object type implementation. Attempts to











 *	generate an byte code internal form for the Tcl object "objPtr" by



 *	compiling its string representation.




 *







 * Results:



 *	The return value is a standard Tcl object result. If an error occurs






























 *	during compilation, an error message is left in the interpreter's











 *	result unless "interp" is NULL.







 *
 * Side effects:
 *	Frees the old internal representation. If no error occurs, then the

 *	compiled code is stored as "objPtr"s bytecode representation.
























 *	Also, if debugging, initializes the "tcl_traceCompile" Tcl variable


 *	used to trace compilations.

 *








 *----------------------------------------------------------------------



 */

















static int








SetByteCodeFromAny(interp, objPtr)









    Tcl_Interp *interp;		/* The interpreter for which the code is








				 * being compiled.  Must not be NULL. */








    Tcl_Obj *objPtr;		/* The object to make a ByteCode object. */





















{









    Interp *iPtr = (Interp *) interp;








    CompileEnv compEnv;		/* Compilation environment structure



				 * allocated in frame. */




    LiteralTable *localTablePtr = &(compEnv.localLitTable);









    register AuxData *auxDataPtr;






    LiteralEntry *entryPtr;
















    register int i;
    int length, nested, result;











    char *string;

    if (!traceInitialized) {
        if (Tcl_LinkVar(interp, "tcl_traceCompile",

	            (char *) &tclTraceCompile,  TCL_LINK_INT) != TCL_OK) {
            panic("SetByteCodeFromAny: unable to create link for tcl_traceCompile variable");
        }
        traceInitialized = 1;






    }



    if (iPtr->evalFlags & TCL_BRACKET_TERM) {
	nested = 1;


    } else {
	nested = 0;
    }
    string = Tcl_GetStringFromObj(objPtr, &length);
    TclInitCompileEnv(interp, &compEnv, string, length);
    result = TclCompileScript(interp, string, length, nested, &compEnv);
    if (result != TCL_OK) {
	/*
	 * Compilation errors. 
	 */

	entryPtr = compEnv.literalArrayPtr;
	for (i = 0;  i < compEnv.literalArrayNext;  i++) {

	    TclReleaseLiteral(interp, entryPtr->objPtr);
	    entryPtr++;
	}
#ifdef TCL_COMPILE_DEBUG
	TclVerifyGlobalLiteralTable(iPtr);
#endif /*TCL_COMPILE_DEBUG*/

	auxDataPtr = compEnv.auxDataArrayPtr;
	for (i = 0;  i < compEnv.auxDataArrayNext;  i++) {
	    if (auxDataPtr->type->freeProc != NULL) {
		auxDataPtr->type->freeProc(auxDataPtr->clientData);




	    }
	    auxDataPtr++;
	}
	goto done;
    }









    /*
     * Successful compilation. Add a "done" instruction at the end.
     */





    compEnv.numSrcBytes = iPtr->termOffset;



    TclEmitOpcode(INST_DONE, &compEnv);

    /*
     * Change the object into a ByteCode object. Ownership of the literal
     * objects and aux data items is given to the ByteCode object.




     */


    

#ifdef TCL_COMPILE_DEBUG
    TclVerifyLocalLiteralTable(&compEnv);

#endif /*TCL_COMPILE_DEBUG*/    


    TclInitByteCodeObj(objPtr, &compEnv);
#ifdef TCL_COMPILE_DEBUG
    if (tclTraceCompile == 2) {

	TclPrintByteCodeObj(interp, objPtr);
    }


#endif /* TCL_COMPILE_DEBUG */





    /*
     * Free storage allocated during compilation.
     */
    
    done:
    if (localTablePtr->buckets != localTablePtr->staticBuckets) {
	ckfree((char *) localTablePtr->buckets);
    }

    TclFreeCompileEnv(&compEnv);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DupByteCodeInternalRep --
 *
 *	Part of the bytecode Tcl object type implementation. However, it
 *	does not copy the internal representation of a bytecode Tcl_Obj, but
 *	instead leaves the new object untyped (with a NULL type pointer).
 *	Code will be compiled for the new object only if necessary.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DupByteCodeInternalRep(srcPtr, copyPtr)
    Tcl_Obj *srcPtr;		/* Object with internal rep to copy. */
    Tcl_Obj *copyPtr;		/* Object with internal rep to set. */

{





    return;






























}

/*
 *----------------------------------------------------------------------
 *
 * FreeByteCodeInternalRep --
 *
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943

944
945
946

947




948



949
950
























951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150

1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
    objPtr->typePtr = NULL;
    objPtr->internalRep.otherValuePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * CleanupByteCode --
 *
 *	This procedure does all the real work of freeing up a bytecode
 *	object's ByteCode structure. It's called only when the structure's
 *	reference count becomes zero.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees objPtr's bytecode internal representation and sets
 *	its type and objPtr->internalRep.otherValuePtr NULL. Also
 *	decrements the ref counts on each object in its object array,
 *	and frees its auxiliary data items.
 *
 *----------------------------------------------------------------------
 */

void
TclCleanupByteCode(codePtr)
    ByteCode *codePtr;		/* ByteCode to free. */
{
    Tcl_Obj **objArrayPtr = codePtr->objArrayPtr;
    int numObjects = codePtr->numObjects;
    int numAuxDataItems = codePtr->numAuxDataItems;

    register AuxData *auxDataPtr;
    register Tcl_Obj *elemPtr;
    register int i;






#ifdef TCL_COMPILE_STATS    



    tclCurrentSourceBytes -= (double) codePtr->numSrcChars;
    tclCurrentCodeBytes -= (double) codePtr->totalSize;
























#endif /* TCL_COMPILE_STATS */

    /*
     * A single heap object holds the ByteCode structure and its code,
     * object, command location, and auxiliary data arrays. This means we
     * only need to 1) decrement the ref counts on the objects in its
     * object array, 2) call the free procs for the auxiliary data items,
     * and 3) free the ByteCode structure's heap object.
     */

    for (i = 0;  i < numObjects;  i++) {
	elemPtr = objArrayPtr[i];
	TclDecrRefCount(elemPtr);
    }

    auxDataPtr = codePtr->auxDataArrayPtr;
    for (i = 0;  i < numAuxDataItems;  i++) {
	if (auxDataPtr->freeProc != NULL) {
	    auxDataPtr->freeProc(auxDataPtr->clientData);
	}
	auxDataPtr++;
    }
    
    ckfree((char *) codePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * DupByteCodeInternalRep --
 *
 *	Part of the bytecode Tcl object type implementation. However, it
 *	does not copy the internal representation of a bytecode Tcl_Obj, but
 *	instead leaves the new object untyped (with a NULL type pointer).
 *	Code will be compiled for the new object only if necessary.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
DupByteCodeInternalRep(srcPtr, copyPtr)
    Tcl_Obj *srcPtr;		/* Object with internal rep to copy. */
    Tcl_Obj *copyPtr;		/* Object with internal rep to set. */
{
    return;
}


/*
 *-----------------------------------------------------------------------
 *
 * SetByteCodeFromAny --
 *
 *	Part of the bytecode Tcl object type implementation. Attempts to
 *	generate an byte code internal form for the Tcl object "objPtr" by
 *	compiling its string representation.
 *
 * Results:
 *	The return value is a standard Tcl object result. If an error occurs
 *	during compilation, an error message is left in the interpreter's
 *	result unless "interp" is NULL.
 *
 * Side effects:
 *	Frees the old internal representation. If no error occurs, then the
 *	compiled code is stored as "objPtr"s bytecode representation.
 *	Also, if debugging, initializes the "tcl_traceCompile" Tcl variable
 *	used to trace compilations.
 *
 *----------------------------------------------------------------------
 */

static int
SetByteCodeFromAny(interp, objPtr)
    Tcl_Interp *interp;		/* The interpreter for which the code is
				 * compiled. */
    Tcl_Obj *objPtr;		/* The object to convert. */
{
    Interp *iPtr = (Interp *) interp;
    char *string;
    CompileEnv compEnv;		/* Compilation environment structure
				 * allocated in frame. */
    AuxData *auxDataPtr;
    register int i;
    int length, result;

    if (!traceInitialized) {
        if (Tcl_LinkVar(interp, "tcl_traceCompile",
	            (char *) &tclTraceCompile,  TCL_LINK_INT) != TCL_OK) {
            panic("SetByteCodeFromAny: unable to create link for tcl_traceCompile variable");
        }
        traceInitialized = 1;
    }
    
    string = Tcl_GetStringFromObj(objPtr, &length);
    TclInitCompileEnv(interp, &compEnv, string);
    result = TclCompileString(interp, string, string+length,
	    iPtr->evalFlags, &compEnv);
    if (result == TCL_OK) {
	/*
	 * Add a "done" instruction at the end of the instruction sequence.
	 */
    
	TclEmitOpcode(INST_DONE, &compEnv);
	
	/*
	 * Convert the object to a ByteCode object.
	 */

	TclInitByteCodeObj(objPtr, &compEnv);
    } else {
	/*
	 * Compilation errors. Decrement the ref counts on any objects in
	 * the object array and free any aux data items prior to freeing
	 * the compilation environment.
	 */
	
	for (i = 0;  i < compEnv.objArrayNext;  i++) {
	    Tcl_Obj *elemPtr = compEnv.objArrayPtr[i];
	    Tcl_DecrRefCount(elemPtr);
	}

	auxDataPtr = compEnv.auxDataArrayPtr;
	for (i = 0;  i < compEnv.auxDataArrayNext;  i++) {
	    if (auxDataPtr->freeProc != NULL) {
		auxDataPtr->freeProc(auxDataPtr->clientData);
	    }
	    auxDataPtr++;
	}
    }
    TclFreeCompileEnv(&compEnv);

    if (result == TCL_OK) {
	if (tclTraceCompile == 2) {
	    TclPrintByteCodeObj(interp, objPtr);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateStringOfByteCode --
 *
 *	Part of the bytecode Tcl object type implementation. Called to
 *	update the string representation for a byte code object.
 *	Note: This procedure does not free an existing old string rep
 *	so storage will be lost if this has not already been done.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Generates a panic. 
 *
 *----------------------------------------------------------------------
 */

static void
UpdateStringOfByteCode(objPtr)
    register Tcl_Obj *objPtr;	/* ByteCode object with string rep that 
				 * needs updating. */
{
    /*
     * This procedure is never invoked since the internal representation of
     * a bytecode object is never modified.
     */

    panic("UpdateStringOfByteCode should never be called.");
}

/*
 *----------------------------------------------------------------------
 *
 * TclInitCompileEnv --
 *
 *	Initializes a CompileEnv compilation environment structure for the
 *	compilation of a string in an interpreter.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The CompileEnv structure is initialized.
 *
 *----------------------------------------------------------------------
 */

void
TclInitCompileEnv(interp, envPtr, string)
    Tcl_Interp *interp;		 /* The interpreter for which a CompileEnv
				  * structure is initialized. */
    register CompileEnv *envPtr; /* Points to the CompileEnv structure to
				  * initialize. */
    char *string;		 /* The source string to be compiled. */

{
    Interp *iPtr = (Interp *) interp;
    
    envPtr->iPtr = iPtr;
    envPtr->source = string;

    envPtr->procPtr = iPtr->compiledProcPtr;
    envPtr->numCommands = 0;
    envPtr->excRangeDepth = 0;
    envPtr->maxExcRangeDepth = 0;
    envPtr->maxStackDepth = 0;
    Tcl_InitHashTable(&(envPtr->objTable), TCL_STRING_KEYS);
    envPtr->pushSimpleWords = 1;
    envPtr->wordIsSimple = 0;
    envPtr->numSimpleWordChars = 0;
    envPtr->exprIsJustVarRef = 0;
    envPtr->exprIsComparison = 0;
    envPtr->termOffset = 0;

    envPtr->codeStart = envPtr->staticCodeSpace;
    envPtr->codeNext = envPtr->codeStart;
    envPtr->codeEnd = (envPtr->codeStart + COMPILEENV_INIT_CODE_BYTES);
    envPtr->mallocedCodeArray = 0;

    envPtr->objArrayPtr = envPtr->staticObjArraySpace;
    envPtr->objArrayNext = 0;
    envPtr->objArrayEnd = COMPILEENV_INIT_NUM_OBJECTS;
    envPtr->mallocedObjArray = 0;
    
    envPtr->excRangeArrayPtr = envPtr->staticExcRangeArraySpace;
    envPtr->excRangeArrayNext = 0;
    envPtr->excRangeArrayEnd = COMPILEENV_INIT_EXCEPT_RANGES;
    envPtr->mallocedExcRangeArray = 0;
    
    envPtr->cmdMapPtr = envPtr->staticCmdMapSpace;
    envPtr->cmdMapEnd = COMPILEENV_INIT_CMD_MAP_SIZE;
    envPtr->mallocedCmdMap = 0;
    
    envPtr->auxDataArrayPtr = envPtr->staticAuxDataArraySpace;
    envPtr->auxDataArrayNext = 0;







|









|
|
<
|






|

|
|

>

<
|
>

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





|
|
|


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




















|





>





>


|
|

|
<
<
<


<






|
|
|
|

|
|
|
|







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

448
449
450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508







509








510





511

512

513






514





515


516
517
518


519














520


521














522







523








524

525



526







527



528
529
530
531
532
533
534
535
536
537

538







539






























540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578



579
580

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
    objPtr->typePtr = NULL;
    objPtr->internalRep.otherValuePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCleanupByteCode --
 *
 *	This procedure does all the real work of freeing up a bytecode
 *	object's ByteCode structure. It's called only when the structure's
 *	reference count becomes zero.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees objPtr's bytecode internal representation and sets its type
 *	and objPtr->internalRep.otherValuePtr NULL. Also releases its

 *	literals and frees its auxiliary data items.
 *
 *----------------------------------------------------------------------
 */

void
TclCleanupByteCode(codePtr)
    register ByteCode *codePtr;	/* Points to the ByteCode to free. */
{
    Tcl_Interp *interp = (Tcl_Interp *) *codePtr->interpHandle;
    int numLitObjects = codePtr->numLitObjects;
    int numAuxDataItems = codePtr->numAuxDataItems;
    register Tcl_Obj **objArrayPtr;
    register AuxData *auxDataPtr;

    int i;
#ifdef TCL_COMPILE_STATS

    if (interp != NULL) {
	ByteCodeStats *statsPtr;
	Tcl_Time destroyTime;
	int lifetimeSec, lifetimeMicroSec, log2;

	statsPtr = &((Interp *) interp)->stats;

	statsPtr->numByteCodesFreed++;
	statsPtr->currentSrcBytes -= (double) codePtr->numSrcBytes;
	statsPtr->currentByteCodeBytes -= (double) codePtr->structureSize;

	statsPtr->currentInstBytes   -= (double) codePtr->numCodeBytes;
	statsPtr->currentLitBytes    -=
		(double) (codePtr->numLitObjects * sizeof(Tcl_Obj *)); 
	statsPtr->currentExceptBytes -=
		(double) (codePtr->numExceptRanges * sizeof(ExceptionRange));
	statsPtr->currentAuxBytes    -=
		(double) (codePtr->numAuxDataItems * sizeof(AuxData));
	statsPtr->currentCmdMapBytes -= (double) codePtr->numCmdLocBytes;

	TclpGetTime(&destroyTime);
	lifetimeSec = destroyTime.sec - codePtr->createTime.sec;
	if (lifetimeSec > 2000) {	/* avoid overflow */
	    lifetimeSec = 2000;
	}
	lifetimeMicroSec =
	    1000000*lifetimeSec + (destroyTime.usec - codePtr->createTime.usec);
	
	log2 = TclLog2(lifetimeMicroSec);
	if (log2 > 31) {
	    log2 = 31;
	}
	statsPtr->lifetimeCount[log2]++;
    }
#endif /* TCL_COMPILE_STATS */

    /*
     * A single heap object holds the ByteCode structure and its code,
     * object, command location, and auxiliary data arrays. This means we
     * only need to 1) decrement the ref counts of the LiteralEntry's in
     * its literal array, 2) call the free procs for the auxiliary data
     * items, and 3) free the ByteCode structure's heap object.
     */








    if (interp != NULL) {








	/*





	 * If the interp has already been freed, then Tcl will have already 

	 * forcefully released all the literals used by ByteCodes compiled

	 * with respect to that interp.






	 */





	 


	objArrayPtr = codePtr->objArrayPtr;
	for (i = 0;  i < numLitObjects;  i++) {
	    /*


	     * TclReleaseLiteral sets a ByteCode's object array entry NULL to














	     * indicate that it has already freed the literal.


	     */














	    







	    if (*objArrayPtr != NULL) {








		TclReleaseLiteral(interp, *objArrayPtr);

	    }



	    objArrayPtr++;







	}



    }
    
    auxDataPtr = codePtr->auxDataArrayPtr;
    for (i = 0;  i < numAuxDataItems;  i++) {
	if (auxDataPtr->type->freeProc != NULL) {
	    (*auxDataPtr->type->freeProc)(auxDataPtr->clientData);
	}
	auxDataPtr++;
    }


    TclHandleRelease(codePtr->interpHandle);







    ckfree((char *) codePtr);






























}

/*
 *----------------------------------------------------------------------
 *
 * TclInitCompileEnv --
 *
 *	Initializes a CompileEnv compilation environment structure for the
 *	compilation of a string in an interpreter.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The CompileEnv structure is initialized.
 *
 *----------------------------------------------------------------------
 */

void
TclInitCompileEnv(interp, envPtr, string, numBytes)
    Tcl_Interp *interp;		 /* The interpreter for which a CompileEnv
				  * structure is initialized. */
    register CompileEnv *envPtr; /* Points to the CompileEnv structure to
				  * initialize. */
    char *string;		 /* The source string to be compiled. */
    int numBytes;		 /* Number of bytes in source string. */
{
    Interp *iPtr = (Interp *) interp;
    
    envPtr->iPtr = iPtr;
    envPtr->source = string;
    envPtr->numSrcBytes = numBytes;
    envPtr->procPtr = iPtr->compiledProcPtr;
    envPtr->numCommands = 0;
    envPtr->exceptDepth = 0;
    envPtr->maxExceptDepth = 0;
    envPtr->maxStackDepth = 0;
    TclInitLiteralTable(&(envPtr->localLitTable));



    envPtr->exprIsJustVarRef = 0;
    envPtr->exprIsComparison = 0;


    envPtr->codeStart = envPtr->staticCodeSpace;
    envPtr->codeNext = envPtr->codeStart;
    envPtr->codeEnd = (envPtr->codeStart + COMPILEENV_INIT_CODE_BYTES);
    envPtr->mallocedCodeArray = 0;

    envPtr->literalArrayPtr = envPtr->staticLiteralSpace;
    envPtr->literalArrayNext = 0;
    envPtr->literalArrayEnd = COMPILEENV_INIT_NUM_OBJECTS;
    envPtr->mallocedLiteralArray = 0;
    
    envPtr->exceptArrayPtr = envPtr->staticExceptArraySpace;
    envPtr->exceptArrayNext = 0;
    envPtr->exceptArrayEnd = COMPILEENV_INIT_EXCEPT_RANGES;
    envPtr->mallocedExceptArray = 0;
    
    envPtr->cmdMapPtr = envPtr->staticCmdMapSpace;
    envPtr->cmdMapEnd = COMPILEENV_INIT_CMD_MAP_SIZE;
    envPtr->mallocedCmdMap = 0;
    
    envPtr->auxDataArrayPtr = envPtr->staticAuxDataArraySpace;
    envPtr->auxDataArrayNext = 0;
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237










































































































































































































































































































































































































































































































































































































































































































































































































































































1238
1239
1240
1241
1242
1243
1244
 * TclFreeCompileEnv --
 *
 *	Free the storage allocated in a CompileEnv compilation environment
 *	structure.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocated storage in the CompileEnv structure is freed. Note that
 *	ref counts for Tcl objects in its object table are not decremented.
 *	In addition, any storage referenced by any auxiliary data items
 *	in the CompileEnv structure are not freed either. The expectation
 *	is that when compilation is successful, "ownership" (i.e., the
 *	pointers to) these objects and aux data items will just be handed
 *	over to the corresponding ByteCode structure.
 *
 *----------------------------------------------------------------------
 */

void
TclFreeCompileEnv(envPtr)
    register CompileEnv *envPtr; /* Points to the CompileEnv structure. */
{
    Tcl_DeleteHashTable(&(envPtr->objTable));
    if (envPtr->mallocedCodeArray) {
	ckfree((char *) envPtr->codeStart);
    }
    if (envPtr->mallocedObjArray) {
	ckfree((char *) envPtr->objArrayPtr);
    }
    if (envPtr->mallocedExcRangeArray) {
	ckfree((char *) envPtr->excRangeArrayPtr);
    }
    if (envPtr->mallocedCmdMap) {
	ckfree((char *) envPtr->cmdMapPtr);
    }
    if (envPtr->mallocedAuxDataArray) {
	ckfree((char *) envPtr->auxDataArrayPtr);
    }
}











































































































































































































































































































































































































































































































































































































































































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * TclInitByteCodeObj --
 *
 *	Create a ByteCode structure and initialize it from a CompileEnv







|


|
|
<
|
|
|








<



|
|

|
|








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







610
611
612
613
614
615
616
617
618
619
620
621

622
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
 * TclFreeCompileEnv --
 *
 *	Free the storage allocated in a CompileEnv compilation environment
 *	structure.
 *
 * Results:
 *	None.
 * 
 * Side effects:
 *	Allocated storage in the CompileEnv structure is freed. Note that
 *	its local literal table is not deleted and its literal objects are
 *	not released. In addition, storage referenced by its auxiliary data

 *	items is not freed. This is done so that, when compilation is
 *	successful, "ownership" of these objects and aux data items is
 *	handed over to the corresponding ByteCode structure.
 *
 *----------------------------------------------------------------------
 */

void
TclFreeCompileEnv(envPtr)
    register CompileEnv *envPtr; /* Points to the CompileEnv structure. */
{

    if (envPtr->mallocedCodeArray) {
	ckfree((char *) envPtr->codeStart);
    }
    if (envPtr->mallocedLiteralArray) {
	ckfree((char *) envPtr->literalArrayPtr);
    }
    if (envPtr->mallocedExceptArray) {
	ckfree((char *) envPtr->exceptArrayPtr);
    }
    if (envPtr->mallocedCmdMap) {
	ckfree((char *) envPtr->cmdMapPtr);
    }
    if (envPtr->mallocedAuxDataArray) {
	ckfree((char *) envPtr->auxDataArrayPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileScript --
 *
 *	Compile a Tcl script in a string.
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	interp->termOffset is set to the offset of the character in the
 *	script just after the last one successfully processed; this will be
 *	the offset of the ']' if (flags & TCL_BRACKET_TERM).
 *	envPtr->maxStackDepth is set to the maximum number of stack elements
 *	needed to execute the script's commands.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the script at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileScript(interp, script, numBytes, nested, envPtr)
    Tcl_Interp *interp;		/* Used for error and status reporting. */
    char *script;		/* The source script to compile. */
    int numBytes;		/* Number of bytes in script. If < 0, the
				 * script consists of all bytes up to the
				 * first null character. */
    int nested;			/* Non-zero means this is a nested command:
				 * close bracket ']' should be considered a
				 * command terminator. If zero, close
				 * bracket has no special meaning. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Interp *iPtr = (Interp *) interp;
    Tcl_Parse parse;
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute all cmds. */
    int lastTopLevelCmdIndex = -1;
    				/* Index of most recent toplevel command in
 				 * the command location table. Initialized
				 * to avoid compiler warning. */
    int startCodeOffset = -1;	/* Offset of first byte of current command's
                                 * code. Init. to avoid compiler warning. */
    unsigned char *entryCodeNext = envPtr->codeNext;
    char *p, *next;
    Namespace *cmdNsPtr;
    Command *cmdPtr;
    Tcl_Token *tokenPtr;
    int bytesLeft, isFirstCmd, gotParse, wordIdx, currCmdIndex;
    int commandLength, objIndex, code;
    char prev;
    Tcl_DString ds;

    Tcl_DStringInit(&ds);

    if (numBytes < 0) {
	numBytes = strlen(script);
    }
    Tcl_ResetResult(interp);
    isFirstCmd = 1;

    /*
     * Each iteration through the following loop compiles the next
     * command from the script.
     */

    p = script;
    bytesLeft = numBytes;
    gotParse = 0;
    while (bytesLeft > 0) {
	if (Tcl_ParseCommand(interp, p, bytesLeft, nested, &parse) != TCL_OK) {
	    code = TCL_ERROR;
	    goto error;
	}
	gotParse = 1;
	if (parse.numWords > 0) {
	    /*
	     * If not the first command, pop the previous command's result
	     * and, if we're compiling a top level command, update the last
	     * command's code size to account for the pop instruction.
	     */

	    if (!isFirstCmd) {
		TclEmitOpcode(INST_POP, envPtr);
		if (!nested) {
		    envPtr->cmdMapPtr[lastTopLevelCmdIndex].numCodeBytes =
			   (envPtr->codeNext - envPtr->codeStart)
			   - startCodeOffset;
		}
	    }

	    /*
	     * Determine the actual length of the command.
	     */

	    commandLength = parse.commandSize;
	    prev = '\0';
	    if (commandLength > 0) {
		prev = parse.commandStart[commandLength-1];
	    }
	    if (((parse.commandStart+commandLength) != (script+numBytes))
	            || ((prev=='\n') || (nested && (prev==']')))) {
		/*
		 * The command didn't end at the end of the script (i.e.  it
		 * ended at a terminator character such as ";".  Reduce the
		 * length by one so that the trace message doesn't include
		 * the terminator character.
		 */
		
		commandLength -= 1;
	    }

	    /*
             * If tracing, print a line for each top level command compiled.
             */

	    if ((tclTraceCompile >= 1)
		    && !nested && (envPtr->procPtr == NULL)) {
		fprintf(stdout, "  Compiling: ");
		TclPrintSource(stdout, parse.commandStart,
			TclMin(commandLength, 55));
		fprintf(stdout, "\n");
	    }

	    /*
	     * Each iteration of the following loop compiles one word
	     * from the command.
	     */
	    
	    envPtr->numCommands++;
	    currCmdIndex = (envPtr->numCommands - 1);
	    if (!nested) {
		lastTopLevelCmdIndex = currCmdIndex;
	    }
	    startCodeOffset = (envPtr->codeNext - envPtr->codeStart);
	    EnterCmdStartData(envPtr, currCmdIndex,
	            (parse.commandStart - envPtr->source), startCodeOffset);
	    
	    for (wordIdx = 0, tokenPtr = parse.tokenPtr;
		    wordIdx < parse.numWords;
		    wordIdx++, tokenPtr += (tokenPtr->numComponents + 1)) {
		if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
		    /*
		     * If this is the first word and the command has a
		     * compile procedure, let it compile the command.
		     */

		    if (wordIdx == 0) {
			if (envPtr->procPtr != NULL) {
			    cmdNsPtr = envPtr->procPtr->cmdPtr->nsPtr;
			} else {
			    cmdNsPtr = NULL; /* use current NS */
			}

			/*
			 * We copy the string before trying to find the command
			 * by name.  We used to modify the string in place, but
			 * this is not safe because the name resolution
			 * handlers could have side effects that rely on the
			 * unmodified string.
			 */

			Tcl_DStringSetLength(&ds, 0);
			Tcl_DStringAppend(&ds, tokenPtr[1].start,
				tokenPtr[1].size);

			cmdPtr = (Command *) Tcl_FindCommand(interp,
				Tcl_DStringValue(&ds),
			        (Tcl_Namespace *) cmdNsPtr, /*flags*/ 0);

			if ((cmdPtr != NULL)
			        && (cmdPtr->compileProc != NULL)
			        && !(iPtr->flags & DONT_COMPILE_CMDS_INLINE)) {
			    code = (*(cmdPtr->compileProc))(interp, &parse,
			            envPtr);
			    if (code == TCL_OK) {
				maxDepth = TclMax(envPtr->maxStackDepth,
			                maxDepth);
				goto finishCommand;
			    } else if (code == TCL_OUT_LINE_COMPILE) {
				/* do nothing */
			    } else { /* an error */
				goto error;
			    }
			}

			/*
			 * No compile procedure so push the word. If the
			 * command was found, push a CmdName object to
			 * reduce runtime lookups.
			 */

			objIndex = TclRegisterLiteral(envPtr,
				tokenPtr[1].start, tokenPtr[1].size,
				/*onHeap*/ 0);
			if (cmdPtr != NULL) {
			    TclSetCmdNameObj(interp,
			           envPtr->literalArrayPtr[objIndex].objPtr,
				   cmdPtr);
			}
		    } else {
			objIndex = TclRegisterLiteral(envPtr,
				tokenPtr[1].start, tokenPtr[1].size,
				/*onHeap*/ 0);
		    }
		    TclEmitPush(objIndex, envPtr);
		    maxDepth = TclMax((wordIdx + 1), maxDepth);
		} else {
		    /*
		     * The word is not a simple string of characters.
		     */
		    
		    code = TclCompileTokens(interp, tokenPtr+1,
			    tokenPtr->numComponents, envPtr);
		    if (code != TCL_OK) {
			goto error;
		    }
		    maxDepth = TclMax((wordIdx + envPtr->maxStackDepth),
			   maxDepth);
		}
	    }

	    /*
	     * Emit an invoke instruction for the command. We skip this
	     * if a compile procedure was found for the command.
	     */
	    
	    if (wordIdx > 0) {
		if (wordIdx <= 255) {
		    TclEmitInstInt1(INST_INVOKE_STK1, wordIdx, envPtr);
		} else {
		    TclEmitInstInt4(INST_INVOKE_STK4, wordIdx, envPtr);
		}
	    }

	    /*
	     * Update the compilation environment structure and record the
	     * offsets of the source and code for the command.
	     */

	    finishCommand:
	    EnterCmdExtentData(envPtr, currCmdIndex, commandLength,
		    (envPtr->codeNext-envPtr->codeStart) - startCodeOffset);
	    isFirstCmd = 0;
	} /* end if parse.numWords > 0 */

	/*
	 * Advance to the next command in the script.
	 */
	
	next = parse.commandStart + parse.commandSize;
	bytesLeft -= (next - p);
	p = next;
	Tcl_FreeParse(&parse);
	gotParse = 0;
	if (nested && (p[-1] == ']')) {
	    /*
	     * We get here in the special case where TCL_BRACKET_TERM was
	     * set in the interpreter and we reached a close bracket in the
	     * script. Stop compilation.
	     */
	    
	    break;
	}
    }

    /*
     * If the source script yielded no instructions (e.g., if it was empty),
     * push an empty string as the command's result.
     */
    
    if (envPtr->codeNext == entryCodeNext) {
	TclEmitPush(TclRegisterLiteral(envPtr, "", 0, /*alreadyAlloced*/ 0),
	        envPtr);
	maxDepth = 1;
    }
    
    if ((nested != 0) && (p > script) && (p[-1] == ']')) {
	iPtr->termOffset = (p - 1) - script;
    } else {
	iPtr->termOffset = (p - script);
    }
    envPtr->maxStackDepth = maxDepth;
    Tcl_DStringFree(&ds);
    return TCL_OK;
	
    error:
    /*
     * Generate various pieces of error information, such as the line
     * number where the error occurred and information to add to the
     * errorInfo variable. Then free resources that had been allocated
     * to the command.
     */

    commandLength = parse.commandSize;
    prev = '\0';
    if (commandLength > 0) {
	prev = parse.commandStart[commandLength-1];
    }
    if (((parse.commandStart+commandLength) != (script+numBytes))
	    || ((prev == '\n') || (nested && (prev == ']')))) {
	/*
	 * The command where the error occurred didn't end at the end
	 * of the script (i.e. it ended at a terminator character such
	 * as ";".  Reduce the length by one so that the error message
	 * doesn't include the terminator character.
	 */

	commandLength -= 1;
    }
    LogCompilationInfo(interp, script, parse.commandStart, commandLength);
    if (gotParse) {
	Tcl_FreeParse(&parse);
    }
    iPtr->termOffset = (p - script);
    envPtr->maxStackDepth = maxDepth;
    Tcl_DStringFree(&ds);
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileTokens --
 *
 *	Given an array of tokens parsed from a Tcl command (e.g., the tokens
 *	that make up a word) this procedure emits instructions to evaluate
 *	the tokens and concatenate their values to form a single result
 *	value on the interpreter's runtime evaluation stack.
 *
 * Results:
 *	The return value is a standard Tcl result. If an error occurs, an
 *	error message is left in the interpreter's result.
 *	
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to evaluate the tokens.
 *
 * Side effects:
 *	Instructions are added to envPtr to push and evaluate the tokens
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileTokens(interp, tokenPtr, count, envPtr)
    Tcl_Interp *interp;		/* Used for error and status reporting. */
    Tcl_Token *tokenPtr;	/* Pointer to first in an array of tokens
				 * to compile. */
    int count;			/* Number of tokens to consider at tokenPtr.
				 * Must be at least 1. */
    CompileEnv *envPtr;		/* Holds the resulting instructions. */
{
    Tcl_DString textBuffer;	/* Holds concatenated chars from adjacent
				 * TCL_TOKEN_TEXT, TCL_TOKEN_BS tokens. */
    char buffer[TCL_UTF_MAX];
    char *name, *p;
    int numObjsToConcat, nameBytes, hasNsQualifiers, localVar;
    int length, maxDepth, depthForVar, i, code;
    unsigned char *entryCodeNext = envPtr->codeNext;

    Tcl_DStringInit(&textBuffer);
    maxDepth = 0;
    numObjsToConcat = 0;
    for ( ;  count > 0;  count--, tokenPtr++) {
	switch (tokenPtr->type) {
	    case TCL_TOKEN_TEXT:
		Tcl_DStringAppend(&textBuffer, tokenPtr->start,
			tokenPtr->size);
		break;

	    case TCL_TOKEN_BS:
		length = Tcl_UtfBackslash(tokenPtr->start, (int *) NULL,
			buffer);
		Tcl_DStringAppend(&textBuffer, buffer, length);
		break;

	    case TCL_TOKEN_COMMAND:
		/*
		 * Push any accumulated chars appearing before the command.
		 */
		
		if (Tcl_DStringLength(&textBuffer) > 0) {
		    int literal;
		    
		    literal = TclRegisterLiteral(envPtr,
			    Tcl_DStringValue(&textBuffer),
			    Tcl_DStringLength(&textBuffer), /*onHeap*/ 0);
		    TclEmitPush(literal, envPtr);
		    numObjsToConcat++;
		    maxDepth = TclMax(numObjsToConcat, maxDepth);
		    Tcl_DStringFree(&textBuffer);
		}
		
		code = TclCompileScript(interp, tokenPtr->start+1,
			tokenPtr->size-2, /*nested*/ 1,	envPtr);
		if (code != TCL_OK) {
		    goto error;
		}
		maxDepth = TclMax((numObjsToConcat + envPtr->maxStackDepth),
		        maxDepth);
		numObjsToConcat++;
		break;

	    case TCL_TOKEN_VARIABLE:
		/*
		 * Push any accumulated chars appearing before the $<var>.
		 */
		
		if (Tcl_DStringLength(&textBuffer) > 0) {
		    int literal;
		    
		    literal = TclRegisterLiteral(envPtr,
			    Tcl_DStringValue(&textBuffer),
			    Tcl_DStringLength(&textBuffer), /*onHeap*/ 0);
		    TclEmitPush(literal, envPtr);
		    numObjsToConcat++;
		    maxDepth = TclMax(numObjsToConcat, maxDepth);
		    Tcl_DStringFree(&textBuffer);
		}
		
		/*
		 * Check if the name contains any namespace qualifiers.
		 */
		
		name = tokenPtr[1].start;
		nameBytes = tokenPtr[1].size;
		hasNsQualifiers = 0;
		for (i = 0, p = name;  i < nameBytes;  i++, p++) {
		    if ((*p == ':') && (i < (nameBytes-1))
			    && (*(p+1) == ':')) {
			hasNsQualifiers = 1;
			break;
		    }
		}

		/*
		 * Either push the variable's name, or find its index in
		 * the array of local variables in a procedure frame.
		 */

		depthForVar = 0;
		if ((envPtr->procPtr == NULL) || hasNsQualifiers) {
		    localVar = -1;
		    TclEmitPush(TclRegisterLiteral(envPtr, name, nameBytes,
		            /*onHeap*/ 0), envPtr);
		    depthForVar = 1;
		} else {
		    localVar = TclFindCompiledLocal(name, nameBytes, 
			    /*create*/ 0, /*flags*/ 0, envPtr->procPtr);
		    if (localVar < 0) {
			TclEmitPush(TclRegisterLiteral(envPtr, name,
			        nameBytes, /*onHeap*/ 0), envPtr); 
			depthForVar = 1;
		    }
		}

		/*
		 * Emit instructions to load the variable.
		 */
		
		if (tokenPtr->numComponents == 1) {
		    if (localVar < 0) {
			TclEmitOpcode(INST_LOAD_SCALAR_STK, envPtr);
		    } else if (localVar <= 255) {
			TclEmitInstInt1(INST_LOAD_SCALAR1, localVar,
			        envPtr);
		    } else {
			TclEmitInstInt4(INST_LOAD_SCALAR4, localVar,
				envPtr);
		    }
		} else {
		    code = TclCompileTokens(interp, tokenPtr+2,
			    tokenPtr->numComponents-1, envPtr);
		    if (code != TCL_OK) {
			sprintf(buffer,
			        "\n    (parsing index for array \"%.*s\")",
				((nameBytes > 100)? 100 : nameBytes), name);
			Tcl_AddObjErrorInfo(interp, buffer, -1);
			goto error;
		    }
		    depthForVar += envPtr->maxStackDepth;
		    if (localVar < 0) {
			TclEmitOpcode(INST_LOAD_ARRAY_STK, envPtr);
		    } else if (localVar <= 255) {
			TclEmitInstInt1(INST_LOAD_ARRAY1, localVar,
			        envPtr);
		    } else {
			TclEmitInstInt4(INST_LOAD_ARRAY4, localVar,
			        envPtr);
		    }
		}
		maxDepth = TclMax(numObjsToConcat + depthForVar, maxDepth);
		numObjsToConcat++;
		count -= tokenPtr->numComponents;
		tokenPtr += tokenPtr->numComponents;
		break;

	    default:
		panic("Unexpected token type in TclCompileTokens");
	}
    }

    /*
     * Push any accumulated characters appearing at the end.
     */

    if (Tcl_DStringLength(&textBuffer) > 0) {
	int literal;

	literal = TclRegisterLiteral(envPtr, Tcl_DStringValue(&textBuffer),
	        Tcl_DStringLength(&textBuffer), /*onHeap*/ 0);
	TclEmitPush(literal, envPtr);
	numObjsToConcat++;
	maxDepth = TclMax(numObjsToConcat, maxDepth);
    }

    /*
     * If necessary, concatenate the parts of the word.
     */

    while (numObjsToConcat > 255) {
	TclEmitInstInt1(INST_CONCAT1, 255, envPtr);
	numObjsToConcat -= 254;	/* concat pushes 1 obj, the result */
    }
    if (numObjsToConcat > 1) {
	TclEmitInstInt1(INST_CONCAT1, numObjsToConcat, envPtr);
    }

    /*
     * If the tokens yielded no instructions, push an empty string.
     */
    
    if (envPtr->codeNext == entryCodeNext) {
	TclEmitPush(TclRegisterLiteral(envPtr, "", 0, /*alreadyAlloced*/ 0),
	        envPtr);
	maxDepth = 1;
    }
    Tcl_DStringFree(&textBuffer);
    envPtr->maxStackDepth = maxDepth;
    return TCL_OK;

    error:
    Tcl_DStringFree(&textBuffer);
    envPtr->maxStackDepth = maxDepth;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileCmdWord --
 *
 *	Given an array of parse tokens for a word containing one or more Tcl
 *	commands, emit inline instructions to execute them. This procedure
 *	differs from TclCompileTokens in that a simple word such as a loop
 *	body enclosed in braces is not just pushed as a string, but is
 *	itself parsed into tokens and compiled.
 *
 * Results:
 *	The return value is a standard Tcl result. If an error occurs, an
 *	error message is left in the interpreter's result.
 *	
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the tokens.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the tokens at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileCmdWord(interp, tokenPtr, count, envPtr)
    Tcl_Interp *interp;		/* Used for error and status reporting. */
    Tcl_Token *tokenPtr;	/* Pointer to first in an array of tokens
				 * for a command word to compile inline. */
    int count;			/* Number of tokens to consider at tokenPtr.
				 * Must be at least 1. */
    CompileEnv *envPtr;		/* Holds the resulting instructions. */
{
    int code;

    /*
     * Handle the common case: if there is a single text token, compile it
     * into an inline sequence of instructions.
     */
    
    envPtr->maxStackDepth = 0;
    if ((count == 1) && (tokenPtr->type == TCL_TOKEN_TEXT)) {
	code = TclCompileScript(interp, tokenPtr->start, tokenPtr->size,
	        /*nested*/ 0, envPtr);
	return code;
    }

    /*
     * Multiple tokens or the single token involves substitutions. Emit
     * instructions to invoke the eval command procedure at runtime on the
     * result of evaluating the tokens.
     */

    code = TclCompileTokens(interp, tokenPtr, count, envPtr);
    if (code != TCL_OK) {
	return code;
    }
    TclEmitOpcode(INST_EVAL_STK, envPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileExprWords --
 *
 *	Given an array of parse tokens representing one or more words that
 *	contain a Tcl expression, emit inline instructions to execute the
 *	expression. This procedure differs from TclCompileExpr in that it
 *	supports Tcl's two-level substitution semantics for expressions that
 *	appear as command words.
 *
 * Results:
 *	The return value is a standard Tcl result. If an error occurs, an
 *	error message is left in the interpreter's result.
 *	
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the expression.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the expression.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileExprWords(interp, tokenPtr, numWords, envPtr)
    Tcl_Interp *interp;		/* Used for error and status reporting. */
    Tcl_Token *tokenPtr;	/* Points to first in an array of word
				 * tokens tokens for the expression to
				 * compile inline. */
    int numWords;		/* Number of word tokens starting at
				 * tokenPtr. Must be at least 1. Each word
				 * token contains one or more subtokens. */
    CompileEnv *envPtr;		/* Holds the resulting instructions. */
{
    Tcl_Token *wordPtr, *partPtr;
    JumpFixup jumpFixup;
    int maxDepth, doExprInline, range, numBytes, i, j, code;
    char *script;
    char saveChar;
    int saveExprIsJustVarRef = envPtr->exprIsJustVarRef;
    int saveExprIsComparison = envPtr->exprIsComparison;

    envPtr->maxStackDepth = 0;
    maxDepth = 0;
    range = -1;
    code = TCL_OK;

    /*
     * If the expression is a single word that doesn't require
     * substitutions, just compile it's string into inline instructions.
     */

    if ((numWords == 1) && (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD)) {
	/*
	 * Temporarily overwrite the character just after the end of the
	 * string with a 0 byte.
	 */

	script = tokenPtr[1].start;
	numBytes = tokenPtr[1].size;
	saveChar = script[numBytes];
	script[numBytes] = 0;
	code = TclCompileExpr(interp, script, numBytes, envPtr);
	script[numBytes] = saveChar;
	return code;
    }
	
    /*
     * Multiple words or the single word requires substitutions. We may
     * need to call expr's command proc at runtime. This often recompiles
     * the expression each time and is slow. However, there are some
     * circumstances where we can still compile inline code "optimistically"
     * and check for type errors during execution that signal when double
     * substitutions must be done.
     */

    doExprInline = 1;
    wordPtr = tokenPtr;
    for (i = 0;  ((i < numWords) && doExprInline);  i++) {
	if (wordPtr->type == TCL_TOKEN_WORD) {
	    for (j = 0, partPtr = wordPtr+1;  j < wordPtr->numComponents;
		    j++, partPtr++) {
		if ((partPtr->type == TCL_TOKEN_BS)
		        || (partPtr->type == TCL_TOKEN_COMMAND)) {
		    doExprInline = 0;
		    break;
		}
	    }
	}
	wordPtr += (wordPtr->numComponents + 1);
    }

    /*
     * If only variable substitutions appear (no backslash or command
     * substitutions), inline compile the expr inside a "catch" so that if
     * there is any error, we call expr's command proc at runtime.
     */
    
    if (doExprInline) {
	Tcl_DString exprBuffer;
	int startCodeOffset = (envPtr->codeNext - envPtr->codeStart);
	int startExceptNext = envPtr->exceptArrayNext;
	
	envPtr->exceptDepth++;
	envPtr->maxExceptDepth =
	        TclMax(envPtr->exceptDepth, envPtr->maxExceptDepth);
 	range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
	TclEmitInstInt4(INST_BEGIN_CATCH4, range, envPtr);

	Tcl_DStringInit(&exprBuffer);
	wordPtr = tokenPtr;
	for (i = 0;  i < numWords;  i++) {
	    if (i > 0) {
		Tcl_DStringAppend(&exprBuffer, " ", 1);
	    }
	    for (j = 0, partPtr = wordPtr+1;  j < wordPtr->numComponents;
		    j++, partPtr++) {
		switch (partPtr->type) {
		    case TCL_TOKEN_TEXT:
			Tcl_DStringAppend(&exprBuffer, partPtr->start,
		                partPtr->size);
			break;

		    case TCL_TOKEN_VARIABLE:
			Tcl_DStringAppend(&exprBuffer, partPtr->start,
		                partPtr->size);
			j += partPtr->numComponents;
			partPtr += partPtr->numComponents;
			break;

		    default:
			panic("unexpected token type in TclCompileExprWords");
		}
	    }
	    wordPtr += (wordPtr->numComponents + 1);
	}
	envPtr->exceptArrayPtr[range].codeOffset =
	        (envPtr->codeNext - envPtr->codeStart);
	code = TclCompileExpr(interp, Tcl_DStringValue(&exprBuffer),
		Tcl_DStringLength(&exprBuffer), envPtr);
	envPtr->exceptArrayPtr[range].numCodeBytes =
	        (envPtr->codeNext - envPtr->codeStart)
	        - envPtr->exceptArrayPtr[range].codeOffset;
	maxDepth = envPtr->maxStackDepth;
	Tcl_DStringFree(&exprBuffer);
	
	if ((code != TCL_OK) || (envPtr->exprIsJustVarRef)
	        || (envPtr->exprIsComparison)) {
	    /*
	     * Delete the inline code and call the expr command proc at
	     * runtime. There was a compilation error or the inline code
	     * might not have the right 2 level substitution semantics:
	     * e.g., if the expr consisted of a single variable ref or the
	     * top-level operator is a comparison (which might operate on
	     * strings). The code might appear to execute successfully but
	     * produce the wrong result. We depend on execution failing if a
	     * second level of substitutions is required.
	     */
	    
	    envPtr->codeNext = (envPtr->codeStart + startCodeOffset);
	    envPtr->exceptArrayNext = startExceptNext;
	    doExprInline = 0;
	} else {
	    TclEmitOpcode(INST_END_CATCH, envPtr); /* for ok case */
	    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
	    envPtr->exceptArrayPtr[range].catchOffset =
		    (envPtr->codeNext - envPtr->codeStart);
	    TclEmitOpcode(INST_END_CATCH, envPtr); /* for error case */
	}
    }
	    
    /*
     * Emit code to call the expr command proc at runtime. Concatenate the
     * (already substituted once) expr tokens with a space between each.
     */

    wordPtr = tokenPtr;
    for (i = 0;  i < numWords;  i++) {
	code = TclCompileTokens(interp, wordPtr+1, wordPtr->numComponents,
                envPtr);
	if (code != TCL_OK) {
	    break;
	}
	if (i < (numWords - 1)) {
	    TclEmitPush(TclRegisterLiteral(envPtr, " ", 1, /*onHeap*/ 0),
	            envPtr);
	    maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);
	} else {
	    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
	}
	wordPtr += (wordPtr->numComponents + 1);
    }
    if (code == TCL_OK) {
	int concatItems = 2*numWords - 1;
	while (concatItems > 255) {
	    TclEmitInstInt1(INST_CONCAT1, 255, envPtr);
	    concatItems -= 254;
	}
	if (concatItems > 1) {
	    TclEmitInstInt1(INST_CONCAT1, concatItems, envPtr);
	}
	TclEmitOpcode(INST_EXPR_STK, envPtr);
    }
    
    /*
     * If generating inline code, update the target of the jump at the end.
     */
    
    if (doExprInline) {
	int jumpDist = (envPtr->codeNext - envPtr->codeStart)
	        - jumpFixup.codeOffset;
	if (TclFixupForwardJump(envPtr, &jumpFixup, jumpDist, 127)) {
	    /*
	     * Update the inline expression code's catch ExceptionRange
	     * target since it, being after the jump, also moved down.
	     */
	    
	    envPtr->exceptArrayPtr[range].catchOffset += 3;
	}
	envPtr->exceptDepth--;
    }
    
    envPtr->exprIsJustVarRef = saveExprIsJustVarRef;
    envPtr->exprIsComparison = saveExprIsComparison;
    envPtr->maxStackDepth = maxDepth;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TclInitByteCodeObj --
 *
 *	Create a ByteCode structure and initialize it from a CompileEnv
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278

1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329



1330
1331
1332
1333
1334
1335
1336
1337
1338


1339

1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359

1360

1361
1362
1363
1364
1365
1366


1367
1368
1369
1370
1371
1372
1373


1374
1375
1376
1377

1378
1379
1380














1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739


4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376


6377
6378
6379
6380
6381
6382
6383
6384
6385

6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447


6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504

6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593

6594


6595
6596

6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653

6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680



6681



6682
6683
6684
6685
6686
6687

6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718


6719
6720
6721
6722
6723
6724
6725
6726

6727
6728
6729


6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753


6754
6755
6756
6757
6758
6759


6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780


6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805

6806
6807
6808




6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819

6820
6821
6822
6823
6824

6825




6826
6827
6828

6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840


6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
				  * initialized, and whose string rep
				  * contains the source code. */
    register CompileEnv *envPtr; /* Points to the CompileEnv structure from
				  * which to create a ByteCode structure. */
{
    register ByteCode *codePtr;
    size_t codeBytes, objArrayBytes, exceptArrayBytes, cmdLocBytes;
    size_t auxDataArrayBytes;
    register size_t size, objBytes, totalSize;
    register unsigned char *p;
    unsigned char *nextPtr;
    int srcLen = envPtr->termOffset;

    int numObjects, i;
#ifdef TCL_COMPILE_STATS
    int srcLenLog2, sizeLog2;
#endif /*TCL_COMPILE_STATS*/

    codeBytes = (envPtr->codeNext - envPtr->codeStart);
    numObjects = envPtr->objArrayNext;
    objArrayBytes = (envPtr->objArrayNext * sizeof(Tcl_Obj *));
    exceptArrayBytes = (envPtr->excRangeArrayNext * sizeof(ExceptionRange));
    auxDataArrayBytes = (envPtr->auxDataArrayNext * sizeof(AuxData));
    cmdLocBytes = GetCmdLocEncodingSize(envPtr);
    
    size = sizeof(ByteCode);
    size += TCL_ALIGN(codeBytes);       /* align object array */
    size += TCL_ALIGN(objArrayBytes);   /* align exception range array */
    size += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */
    size += auxDataArrayBytes;
    size += cmdLocBytes;

    /*
     * Compute the total number of bytes needed for this bytecode
     * including the storage for the Tcl objects in its object array.
     */

    objBytes = (numObjects * sizeof(Tcl_Obj));
    for (i = 0;  i < numObjects;  i++) {
	Tcl_Obj *litObjPtr = envPtr->objArrayPtr[i];
	if (litObjPtr->bytes != NULL) {
	    objBytes += litObjPtr->length;
	}
    }
    totalSize = (size + objBytes);

#ifdef TCL_COMPILE_STATS
    tclNumCompilations++;
    tclTotalSourceBytes += (double) srcLen;
    tclTotalCodeBytes += (double) totalSize;
    
    tclTotalInstBytes += (double) codeBytes;
    tclTotalObjBytes += (double) objBytes;
    tclTotalExceptBytes += exceptArrayBytes;
    tclTotalAuxBytes += (double) auxDataArrayBytes;
    tclTotalCmdMapBytes += (double) cmdLocBytes;

    tclCurrentSourceBytes += (double) srcLen;
    tclCurrentCodeBytes += (double) totalSize;

    srcLenLog2 = TclLog2(srcLen);
    sizeLog2 = TclLog2((int) totalSize);
    if ((srcLenLog2 > 31) || (sizeLog2 > 31)) {
	panic("TclInitByteCodeObj: bad source or code sizes\n");



    }
    tclSourceCount[srcLenLog2]++;
    tclByteCodeCount[sizeLog2]++;
#endif /* TCL_COMPILE_STATS */    
    
    p = (unsigned char *) ckalloc(size);
    codePtr = (ByteCode *) p;
    codePtr->iPtr = envPtr->iPtr;
    codePtr->compileEpoch = envPtr->iPtr->compileEpoch;


    codePtr->refCount = 1;

    codePtr->source = envPtr->source;
    codePtr->procPtr = envPtr->procPtr;
    codePtr->totalSize = totalSize;
    codePtr->numCommands = envPtr->numCommands;
    codePtr->numSrcChars = srcLen;
    codePtr->numCodeBytes = codeBytes;
    codePtr->numObjects = numObjects;
    codePtr->numExcRanges = envPtr->excRangeArrayNext;
    codePtr->numAuxDataItems = envPtr->auxDataArrayNext;
    codePtr->auxDataArrayPtr = NULL;
    codePtr->numCmdLocBytes = cmdLocBytes;
    codePtr->maxExcRangeDepth = envPtr->maxExcRangeDepth;
    codePtr->maxStackDepth = envPtr->maxStackDepth;
    
    p += sizeof(ByteCode);
    codePtr->codeStart = p;
    memcpy((VOID *) p, (VOID *) envPtr->codeStart, codeBytes);
    
    p += TCL_ALIGN(codeBytes);	      /* align object array */
    codePtr->objArrayPtr = (Tcl_Obj **) p;

    memcpy((VOID *) p, (VOID *) envPtr->objArrayPtr, objArrayBytes);


    p += TCL_ALIGN(objArrayBytes);    /* align exception range array */
    if (exceptArrayBytes > 0) {
	codePtr->excRangeArrayPtr = (ExceptionRange *) p;
	memcpy((VOID *) p, (VOID *) envPtr->excRangeArrayPtr,
	        exceptArrayBytes);


    }
    
    p += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */
    if (auxDataArrayBytes > 0) {
	codePtr->auxDataArrayPtr = (AuxData *) p;
	memcpy((VOID *) p, (VOID *) envPtr->auxDataArrayPtr,
	        auxDataArrayBytes);


    }

    p += auxDataArrayBytes;
    nextPtr = EncodeCmdLocMap(envPtr, codePtr, (unsigned char *) p);

    if (((size_t)(nextPtr - p)) != cmdLocBytes) {	
	panic("TclInitByteCodeObj: encoded cmd location bytes %d != expected size %d\n", (nextPtr - p), cmdLocBytes);
    }














    
    /*
     * Free the old internal rep then convert the object to a
     * bytecode object by making its internal rep point to the just
     * compiled ByteCode.
     */
	    
    if ((objPtr->typePtr != NULL) &&
	    (objPtr->typePtr->freeIntRepProc != NULL)) {
	objPtr->typePtr->freeIntRepProc(objPtr);
    }
    objPtr->internalRep.otherValuePtr = (VOID *) codePtr;
    objPtr->typePtr = &tclByteCodeType;
}

/*
 *----------------------------------------------------------------------
 *
 * GetCmdLocEncodingSize --
 *
 *	Computes the total number of bytes needed to encode the command
 *	location information for some compiled code.
 *
 * Results:
 *	The byte count needed to encode the compiled location information.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
GetCmdLocEncodingSize(envPtr)
     CompileEnv *envPtr;	/* Points to compilation environment
				 * structure containing the CmdLocation
				 * structure to encode. */
{
    register CmdLocation *mapPtr = envPtr->cmdMapPtr;
    int numCmds = envPtr->numCommands;
    int codeDelta, codeLen, srcDelta, srcLen;
    int codeDeltaNext, codeLengthNext, srcDeltaNext, srcLengthNext;
				/* The offsets in their respective byte
				 * sequences where the next encoded offset
				 * or length should go. */
    int prevCodeOffset, prevSrcOffset, i;

    codeDeltaNext = codeLengthNext = srcDeltaNext = srcLengthNext = 0;
    prevCodeOffset = prevSrcOffset = 0;
    for (i = 0;  i < numCmds;  i++) {
	codeDelta = (mapPtr[i].codeOffset - prevCodeOffset);
	if (codeDelta < 0) {
	    panic("GetCmdLocEncodingSize: bad code offset");
	} else if (codeDelta <= 127) {
	    codeDeltaNext++;
	} else {
	    codeDeltaNext += 5;	 /* 1 byte for 0xFF, 4 for positive delta */
	}
	prevCodeOffset = mapPtr[i].codeOffset;

	codeLen = mapPtr[i].numCodeBytes;
	if (codeLen < 0) {
	    panic("GetCmdLocEncodingSize: bad code length");
	} else if (codeLen <= 127) {
	    codeLengthNext++;
	} else {
	    codeLengthNext += 5; /* 1 byte for 0xFF, 4 for length */
	}

	srcDelta = (mapPtr[i].srcOffset - prevSrcOffset);
	if ((-127 <= srcDelta) && (srcDelta <= 127)) {
	    srcDeltaNext++;
	} else {
	    srcDeltaNext += 5;	 /* 1 byte for 0xFF, 4 for delta */
	}
	prevSrcOffset = mapPtr[i].srcOffset;

	srcLen = mapPtr[i].numSrcChars;
	if (srcLen < 0) {
	    panic("GetCmdLocEncodingSize: bad source length");
	} else if (srcLen <= 127) {
	    srcLengthNext++;
	} else {
	    srcLengthNext += 5;	 /* 1 byte for 0xFF, 4 for length */
	}
    }

    return (codeDeltaNext + codeLengthNext + srcDeltaNext + srcLengthNext);
}

/*
 *----------------------------------------------------------------------
 *
 * EncodeCmdLocMap --
 *
 *	Encode the command location information for some compiled code into
 *	a ByteCode structure. The encoded command location map is stored as
 *	three adjacent byte sequences.
 *
 * Results:
 *	Pointer to the first byte after the encoded command location
 *	information.
 *
 * Side effects:
 *	The encoded information is stored into the block of memory headed
 *	by codePtr. Also records pointers to the start of the four byte
 *	sequences in fields in codePtr's ByteCode header structure.
 *
 *----------------------------------------------------------------------
 */

static unsigned char *
EncodeCmdLocMap(envPtr, codePtr, startPtr)
     CompileEnv *envPtr;	/* Points to compilation environment
				 * structure containing the CmdLocation
				 * structure to encode. */
     ByteCode *codePtr;		/* ByteCode in which to encode envPtr's
				 * command location information. */
     unsigned char *startPtr;	/* Points to the first byte in codePtr's
				 * memory block where the location
				 * information is to be stored. */
{
    register CmdLocation *mapPtr = envPtr->cmdMapPtr;
    int numCmds = envPtr->numCommands;
    register unsigned char *p = startPtr;
    int codeDelta, codeLen, srcDelta, srcLen, prevOffset;
    register int i;
    
    /*
     * Encode the code offset for each command as a sequence of deltas.
     */

    codePtr->codeDeltaStart = p;
    prevOffset = 0;
    for (i = 0;  i < numCmds;  i++) {
	codeDelta = (mapPtr[i].codeOffset - prevOffset);
	if (codeDelta < 0) {
	    panic("EncodeCmdLocMap: bad code offset");
	} else if (codeDelta <= 127) {
	    TclStoreInt1AtPtr(codeDelta, p);
	    p++;
	} else {
	    TclStoreInt1AtPtr(0xFF, p);
	    p++;
	    TclStoreInt4AtPtr(codeDelta, p);
	    p += 4;
	}
	prevOffset = mapPtr[i].codeOffset;
    }

    /*
     * Encode the code length for each command.
     */

    codePtr->codeLengthStart = p;
    for (i = 0;  i < numCmds;  i++) {
	codeLen = mapPtr[i].numCodeBytes;
	if (codeLen < 0) {
	    panic("EncodeCmdLocMap: bad code length");
	} else if (codeLen <= 127) {
	    TclStoreInt1AtPtr(codeLen, p);
	    p++;
	} else {
	    TclStoreInt1AtPtr(0xFF, p);
	    p++;
	    TclStoreInt4AtPtr(codeLen, p);
	    p += 4;
	}
    }

    /*
     * Encode the source offset for each command as a sequence of deltas.
     */

    codePtr->srcDeltaStart = p;
    prevOffset = 0;
    for (i = 0;  i < numCmds;  i++) {
	srcDelta = (mapPtr[i].srcOffset - prevOffset);
	if ((-127 <= srcDelta) && (srcDelta <= 127)) {
	    TclStoreInt1AtPtr(srcDelta, p);
	    p++;
	} else {
	    TclStoreInt1AtPtr(0xFF, p);
	    p++;
	    TclStoreInt4AtPtr(srcDelta, p);
	    p += 4;
	}
	prevOffset = mapPtr[i].srcOffset;
    }

    /*
     * Encode the source length for each command.
     */

    codePtr->srcLengthStart = p;
    for (i = 0;  i < numCmds;  i++) {
	srcLen = mapPtr[i].numSrcChars;
	if (srcLen < 0) {
	    panic("EncodeCmdLocMap: bad source length");
	} else if (srcLen <= 127) {
	    TclStoreInt1AtPtr(srcLen, p);
	    p++;
	} else {
	    TclStoreInt1AtPtr(0xFF, p);
	    p++;
	    TclStoreInt4AtPtr(srcLen, p);
	    p += 4;
	}
    }
    
    return p;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileString --
 *
 *	Compile a Tcl script in a null-terminated binary string.
 *
 * Results:
 *	The return value is TCL_OK on a successful compilation and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 *	envPtr->termOffset and interp->termOffset are filled in with the
 *	offset of the character in the string just after the last one
 *	successfully processed; this might be the offset of the ']' (if
 *	flags & TCL_BRACKET_TERM), or the offset of the '\0' at the end of
 *	the string. Also updates envPtr->maxStackDepth with the maximum
 *	number of stack elements needed to execute the string's commands.
 *
 * Side effects:
 *	Adds instructions to envPtr to evaluate the string at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileString(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Interp *iPtr = (Interp *) interp;
    register char *src = string;/* Points to current source char. */
    register char c = *src;	/* The current char. */
    register int type;		/* Current char's CHAR_TYPE type. */
    char termChar = (char)((flags & TCL_BRACKET_TERM)? ']' : '\0');
				/* Return when this character is found
				 * (either ']' or '\0'). Zero means newlines
				 * terminate cmds. */
    int isFirstCmd = 1;		/* 1 if compiling the first cmd. */
    char *cmdSrcStart = NULL;	/* Points to first non-blank char in each
 				 * command. Initialized to avoid compiler
 				 * warning. */
    int cmdIndex;		/* The index of the current command in the
 				 * compilation environment's command
 				 * location table. */
    int lastTopLevelCmdIndex = -1;
    				/* Index of most recent toplevel command in
 				 * the command location table. Initialized
				 * to avoid compiler warning. */
    int cmdCodeOffset = -1;	/* Offset of first byte of current command's
 				 * code. Initialized to avoid compiler
 				 * warning. */
    int cmdWords;		/* Number of words in current command. */
    Tcl_Command cmd;		/* Used to search for commands. */
    Command *cmdPtr;		/* Points to command's Command structure if
				 * first word is simple and command was
				 * found; else NULL. */
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute all cmds. */
    char *termPtr;		/* Points to char that terminated word. */
    char savedChar;		/* Holds the character from string
				 * termporarily replaced by a null character
				 * during processing of words. */
    int objIndex = -1;		/* The object array index for a pushed
 				 * object holding a word or word part
 				 * Initialized to avoid compiler warning. */
    unsigned char *entryCodeNext = envPtr->codeNext;
    				/* Value of envPtr's current instruction
				 * pointer at entry. Used to tell if any
				 * instructions generated. */
    char *ellipsis = "";	/* Used to set errorInfo variable; "..."
				 * indicates that not all of offending
				 * command is included in errorInfo. ""
				 * means that the command is all there. */
    Tcl_Obj *objPtr;
    int numChars;
    int result = TCL_OK;
    int savePushSimpleWords = envPtr->pushSimpleWords;

    /*
     * commands: command {(';' | '\n') command}
     */

    while ((src != lastChar) && (c != termChar)) {
	/*
	 * Skip white space, semicolons, backslash-newlines (treated as
	 * spaces), and comments before command.
	 */

	type = CHAR_TYPE(src, lastChar);
	while ((type & (TCL_SPACE | TCL_BACKSLASH))
	        || (c == '\n') || (c == ';')) {
	    if (type == TCL_BACKSLASH) {
		if (src[1] == '\n') {
		    src += 2;
		} else {
		    break;
		}
	    } else {
		src++;
	    }
	    c = *src;
	    type = CHAR_TYPE(src, lastChar);
	}

	if (c == '#') {
	    while (src != lastChar) {
		if (c == '\\') {
		    int numRead;
		    Tcl_Backslash(src, &numRead);
		    src += numRead;
		} else if (c == '\n') {
		    src++;
		    c = *src;
		    envPtr->termOffset = (src - string);
		    break;
		} else {
		    src++;
		}
		c = *src;
	    }
	    continue;	/* end of comment, restart outer command loop */
	}

	/*
	 * Compile one command: zero or more words terminated by a '\n',
	 * ';', ']' (if command is terminated by close bracket), or
	 * the end of string.
	 *
	 * command: word*
	 */

	type = CHAR_TYPE(src, lastChar);
	if ((type == TCL_COMMAND_END) 
	        && ((c != ']') || (flags & TCL_BRACKET_TERM))) {
	    continue;  /* empty command; restart outer cmd loop */
	}

	/*
	 * If not the first command, discard the previous command's result.
	 */
	
	if (!isFirstCmd) {
	    TclEmitOpcode(INST_POP, envPtr);
	    if (!(flags & TCL_BRACKET_TERM)) {
		/*
		 * We are compiling a top level command. Update the number
		 * of code bytes for the last command to account for the pop
		 * instruction.
		 */
		
	        (envPtr->cmdMapPtr[lastTopLevelCmdIndex]).numCodeBytes =
		    (envPtr->codeNext-envPtr->codeStart) - cmdCodeOffset;
	    }
	}

	/*
	 * Compile the words of the command. Process the first word
	 * specially, since it is the name of a command. If it is a "simple"
	 * string (just a sequence of characters), look it up in the table
	 * of compilation procedures. If a word other than the first is
	 * simple and represents an integer whose formatted representation
	 * is the same as the word, just push an integer object. Also record
	 * starting source and object information for the command.
	 */

	envPtr->numCommands++;
	cmdIndex = (envPtr->numCommands - 1);
	if (!(flags & TCL_BRACKET_TERM)) {
	    lastTopLevelCmdIndex = cmdIndex;
	}
	
	cmdSrcStart = src;
	cmdCodeOffset = (envPtr->codeNext - envPtr->codeStart);
	cmdWords = 0;
	EnterCmdStartData(envPtr, cmdIndex, src-envPtr->source,
		cmdCodeOffset);
	    
	if ((!(flags & TCL_BRACKET_TERM))
	        && (tclTraceCompile >= 1) && (envPtr->procPtr == NULL)) {
	    /*
	     * Display a line summarizing the top level command we are about
	     * to compile.
	     */
	    
	    char *p = cmdSrcStart;
	    int numChars, complete;
	    
	    while ((CHAR_TYPE(p, lastChar) != TCL_COMMAND_END)
		   || ((*p == ']') && !(flags & TCL_BRACKET_TERM))) {
		p++;
	    }
	    numChars = (p - cmdSrcStart);
	    complete = 1;
	    if (numChars > 60) {
		numChars = 60;
		complete = 0;
	    } else if ((numChars >= 2) && (*p == '\n') && (*(p-1) == '{')) {
		complete = 0;
	    }
	    fprintf(stdout, "Compiling: %.*s%s\n",
		    numChars, cmdSrcStart, (complete? "" : " ..."));
	}
	
	while ((type != TCL_COMMAND_END)
	        || ((c == ']') && !(flags & TCL_BRACKET_TERM))) {
	    /*
	     * Skip any leading white space at the start of a word. Note
	     * that a backslash-newline is treated as a space.
	     */

	    while (type & (TCL_SPACE | TCL_BACKSLASH)) {
		if (type == TCL_BACKSLASH) {
		    if (src[1] == '\n') {
			src += 2;
		    } else {
			break;
		    }
		} else {
		    src++;
		}
		c = *src;
		type = CHAR_TYPE(src, lastChar);
	    }
	    if ((type == TCL_COMMAND_END) 
	            && ((c != ']') || (flags & TCL_BRACKET_TERM))) {
		break;		/* no words remain for command. */
	    }

	    /*
	     * Compile one word. We use an inline version of CompileWord to
	     * avoid an extra procedure call.
	     */

	    envPtr->pushSimpleWords = 0;
	    if (type & (TCL_QUOTE | TCL_OPEN_BRACE)) {
		src++;
		if (type == TCL_QUOTE) {
		    result = TclCompileQuotes(interp, src, lastChar,
			    '"', flags, envPtr);
		} else {
		    result = CompileBraces(interp, src, lastChar,
			    flags, envPtr);
		}
		termPtr = (src + envPtr->termOffset);
		if (result != TCL_OK) {
		    src = termPtr;
		    goto done;
		}

		/*
		 * Make sure terminating character of the quoted or braced
		 * string is the end of word.
		 */
		
		c = *termPtr;
		if ((c == '\\') && (*(termPtr+1) == '\n')) {
		    /*
		     * Line is continued on next line; the backslash-
		     * newline turns into space, which terminates the word.
		     */
		} else {
		    type = CHAR_TYPE(termPtr, lastChar);
		    if ((type != TCL_SPACE) && (type != TCL_COMMAND_END)) {
			Tcl_ResetResult(interp);
			if (*(src-1) == '"') {
			    Tcl_AppendToObj(Tcl_GetObjResult(interp),
				    "extra characters after close-quote", -1);
			} else {
			    Tcl_AppendToObj(Tcl_GetObjResult(interp),
				    "extra characters after close-brace", -1);
			}
			result = TCL_ERROR;
		    }
		}
	    } else {
		result = CompileMultipartWord(interp, src, lastChar,
			flags, envPtr);
		termPtr = (src + envPtr->termOffset);
	    }
	    if (result != TCL_OK) {
		ellipsis = "...";
		src = termPtr;
		goto done;
	    }
	    
	    if (envPtr->wordIsSimple) {
		/*
		 * A simple word. Temporarily replace the terminating
		 * character with a null character.
		 */
		
		numChars = envPtr->numSimpleWordChars;
		savedChar = src[numChars];
		src[numChars] = '\0';

		if ((cmdWords == 0)
		        && (!(iPtr->flags & DONT_COMPILE_CMDS_INLINE))) {
		    /*
		     * The first word of a command and inline command
		     * compilation has not been disabled (e.g., by command
		     * traces). Look up the first word in the interpreter's
		     * hashtable of commands. If a compilation procedure is
		     * found, let it compile the command after resetting
		     * error logging information. Note that if we are
		     * compiling a procedure, we must look up the command
		     * in the procedure's namespace and not the current
		     * namespace.
		     */

		    Namespace *cmdNsPtr;

		    if (envPtr->procPtr != NULL) {
			cmdNsPtr = envPtr->procPtr->cmdPtr->nsPtr;
		    } else {
			cmdNsPtr = NULL;
		    }

		    cmdPtr = NULL;
		    cmd = Tcl_FindCommand(interp, src,
			    (Tcl_Namespace *) cmdNsPtr, /*flags*/ 0);
                    if (cmd != (Tcl_Command) NULL) {
                        cmdPtr = (Command *) cmd;
                    }
		    if ((cmdPtr != NULL) && (cmdPtr->compileProc != NULL)) {
			char *firstArg = termPtr;
			src[numChars] = savedChar;
			iPtr->flags &= ~(ERR_ALREADY_LOGGED | ERR_IN_PROGRESS
					 | ERROR_CODE_SET);
			result = (*(cmdPtr->compileProc))(interp,
				firstArg, lastChar, flags, envPtr);
			if (result == TCL_OK) {
			    src = (firstArg + envPtr->termOffset);
			    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
			    goto finishCommand;
			} else if (result == TCL_OUT_LINE_COMPILE) {
			    result = TCL_OK;
			    src[numChars] = '\0';
			} else {
			    src = firstArg;
			    goto done;           /* an error */
			}
		    }

		    /*
		     * No compile procedure was found for the command: push
		     * the word and continue to compile the remaining
		     * words. If a hashtable entry was found for the
		     * command, push a CmdName object instead to avoid
		     * runtime lookups. If necessary, convert the pushed
		     * object to be a CmdName object. If this is the first
		     * CmdName object in this code unit that refers to the
		     * command, increment the reference count in the
		     * Command structure to reflect the new reference from
		     * the CmdName object and, if the command is deleted
		     * later, to keep the Command structure from being freed
		     * until TclExecuteByteCode has a chance to recognize
		     * that the command was deleted.
		     */

		    objIndex = TclObjIndexForString(src, numChars,
			    /*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
		    if (cmdPtr != NULL) {
			objPtr = envPtr->objArrayPtr[objIndex];
			if ((objPtr->typePtr != &tclCmdNameType)
			        && (objPtr->bytes != NULL)) {
			    ResolvedCmdName *resPtr = (ResolvedCmdName *)
                                    ckalloc(sizeof(ResolvedCmdName));
                            Namespace *nsPtr = (Namespace *) 
				    Tcl_GetCurrentNamespace(interp);

                            resPtr->cmdPtr = cmdPtr;
                            resPtr->refNsPtr = nsPtr;
			    resPtr->refNsId = nsPtr->nsId;
                            resPtr->refNsCmdEpoch = nsPtr->cmdRefEpoch;
                            resPtr->cmdEpoch = cmdPtr->cmdEpoch;
                            resPtr->refCount = 1;
			    objPtr->internalRep.twoPtrValue.ptr1 =
				(VOID *) resPtr;
			    objPtr->internalRep.twoPtrValue.ptr2 = NULL;
                            objPtr->typePtr = &tclCmdNameType;
			    cmdPtr->refCount++;
			}
		    }
		} else {
		    /*
		     * See if the word represents an integer whose formatted
		     * representation is the same as the word (e.g., this is
		     * true for 123 and -1 but not for 00005). If so, just
		     * push an integer object.
		     */

		    int isCompilableInt = 0;
		    long n;
		    char buf[40];
		    
		    if (TclLooksLikeInt(src)) {
			int code = TclGetLong(interp, src, &n);
			if (code == TCL_OK) {
			    TclFormatInt(buf, n);
			    if (strcmp(src, buf) == 0) {
				isCompilableInt = 1;
				objIndex = TclObjIndexForString(src,
					numChars, /*allocStrRep*/ 0,
					/*inHeap*/ 0, envPtr);
				objPtr = envPtr->objArrayPtr[objIndex];

				Tcl_InvalidateStringRep(objPtr);
				objPtr->internalRep.longValue = n;
				objPtr->typePtr = &tclIntType;
			    }
			} else {
			    Tcl_ResetResult(interp);
			}
		    }
		    if (!isCompilableInt) {
			objIndex = TclObjIndexForString(src, numChars,
			        /*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
		    }
		}
		src[numChars] = savedChar;
		TclEmitPush(objIndex, envPtr);
		maxDepth = TclMax((cmdWords + 1), maxDepth);
	    } else {		/* not a simple word */
		maxDepth = TclMax((cmdWords + envPtr->maxStackDepth),
			       maxDepth);
	    }
	    src = termPtr;
	    c = *src;
	    type = CHAR_TYPE(src, lastChar);
	    cmdWords++;
	}
	
	/*
	 * Emit an invoke instruction for the command. If a compile command
	 * was found for the command we called it and skipped this.
	 */

	if (cmdWords > 0) {
	    if (cmdWords <= 255) {
	        TclEmitInstUInt1(INST_INVOKE_STK1, cmdWords, envPtr);
            } else {
	        TclEmitInstUInt4(INST_INVOKE_STK4, cmdWords, envPtr);
            }
	}

	/*
	 * Update the compilation environment structure. Record
	 * source/object information for the command.
	 */

        finishCommand:
	EnterCmdExtentData(envPtr, cmdIndex, src-cmdSrcStart,
	        (envPtr->codeNext-envPtr->codeStart) - cmdCodeOffset);
	
	isFirstCmd = 0;
	envPtr->termOffset = (src - string);
	c = *src;
    }

    done:
    if (result == TCL_OK) {
	/*
	 * If the source string yielded no instructions (e.g., if it was
	 * empty), push an empty string object as the command's result.
	 */
    
	if (entryCodeNext == envPtr->codeNext) {
	    int objIndex = TclObjIndexForString("", 0, /*allocStrRep*/ 0,
                                                /*inHeap*/ 0, envPtr);
	    TclEmitPush(objIndex, envPtr);
	    maxDepth = 1;
	}
    } else {
	/*
	 * Add additional error information. First compute the line number
	 * where the error occurred.
	 */

	register char *p;
	int numChars;
	char buf[200];

	iPtr->errorLine = 1;
	for (p = string;  p != cmdSrcStart;  p++) {
	    if (*p == '\n') {
		iPtr->errorLine++;
	    }
	}
	for (  ; isspace(UCHAR(*p)) || (*p == ';');  p++) {
	    if (*p == '\n') {
		iPtr->errorLine++;
	    }
	}

	/*
	 * Figure out how much of the command to print (up to a certain
	 * number of characters, or up to the end of the command).
	 */

	p = cmdSrcStart;
	while ((CHAR_TYPE(p, lastChar) != TCL_COMMAND_END)
		|| ((*p == ']') && !(flags & TCL_BRACKET_TERM))) {
	    p++;
	}
	numChars = (p - cmdSrcStart);
	if (numChars > 150) {
	    numChars = 150;
	    ellipsis = " ...";
	} else if ((numChars >= 2) && (*p == '\n') && (*(p-1) == '{')) {
	    ellipsis = " ...";
	}
	
	sprintf(buf, "\n    while compiling\n\"%.*s%s\"",
		numChars, cmdSrcStart, ellipsis);
	Tcl_AddObjErrorInfo(interp, buf, -1);
    } 
	
    envPtr->termOffset = (src - string);
    iPtr->termOffset = envPtr->termOffset;
    envPtr->maxStackDepth = maxDepth;
    envPtr->pushSimpleWords = savePushSimpleWords;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileWord --
 *
 *	This procedure compiles one word from a command string. It skips
 *	any leading white space.
 *
 *	Ordinarily, callers set envPtr->pushSimpleWords to 1 and this
 *	procedure emits push and other instructions to compute the
 *	word on the Tcl evaluation stack at execution time. If a caller sets
 *	envPtr->pushSimpleWords to 0, CompileWord will _not_ compile
 *	"simple" words: words that are just a sequence of characters without
 *	backslashes. It will leave their compilation up to the caller.
 *
 *	As an important special case, if the word is simple, this procedure
 *	sets envPtr->wordIsSimple to 1 and envPtr->numSimpleWordChars to the
 *	number of characters in the simple word. This allows the caller to
 *	process these words specially.
 *
 * Results:
 *	The return value is a standard Tcl result. If an error occurs, an
 *	error message is left in the interpreter's result.
 *	
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed in the last
 *	word. This is normally the character just after the last one in a
 *	word (perhaps the command terminator), or the vicinity of an error
 *	(if the result is not TCL_OK).
 *
 *	envPtr->wordIsSimple is set 1 if the word is simple: just a
 *	sequence of characters without backslashes. If so, the word's
 *	characters are the envPtr->numSimpleWordChars characters starting 
 *	at string.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to evaluate the word. This is not changed if
 *	the word is simple and envPtr->pushSimpleWords was 0 (false).
 *
 * Side effects:
 *	Instructions are added to envPtr to compute and push the word
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileWord(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Interpreter to use for nested command
				 * evaluations and error messages. */
    char *string;		/* First character of word. */
    char *lastChar;		 /* Pointer to terminating character of
				  * string. */
    int flags;			/* Flags to control compilation (same values
				 * passed to Tcl_EvalObj). */
    CompileEnv *envPtr;		/* Holds the resulting instructions. */
{
    /*
     * Compile one word: approximately
     *
     * word:             quoted_string | braced_string | multipart_word
     * quoted_string:    '"' char* '"'
     * braced_string:    '{' char* '}'
     * multipart_word    (see CompileMultipartWord below)
     */
    
    register char *src = string; /* Points to current source char. */
    register int type = CHAR_TYPE(src, lastChar);
				 /* Current char's CHAR_TYPE type. */
    int maxDepth = 0;		 /* Maximum number of stack elements needed
				  * to compute and push the word. */
    char *termPtr = src;	 /* Points to the character that terminated
				  * the word. */
    int result = TCL_OK;

    /*
     * Skip any leading white space at the start of a word. Note that a
     * backslash-newline is treated as a space.
     */

    while (type & (TCL_SPACE | TCL_BACKSLASH)) {
	if (type == TCL_BACKSLASH) {
	    if (src[1] == '\n') {
		src += 2;
	    } else {
		break;		/* no longer white space */
	    }
	} else {
	    src++;
	}
	type = CHAR_TYPE(src, lastChar);
    }
    if (type == TCL_COMMAND_END) {
	goto done;
    }

    /*
     * Compile the word. Handle quoted and braced string words here in order
     * to avoid an extra procedure call.
     */

    if (type & (TCL_QUOTE | TCL_OPEN_BRACE)) {
	src++;
	if (type == TCL_QUOTE) {
	    result = TclCompileQuotes(interp, src, lastChar, '"', flags,
		    envPtr);
	} else {
	    result = CompileBraces(interp, src, lastChar, flags, envPtr);
	}
	termPtr = (src + envPtr->termOffset);
	if (result != TCL_OK) {
	    goto done;
	}
	
	/*
	 * Make sure terminating character of the quoted or braced string is
	 * the end of word.
	 */
	
	if ((*termPtr == '\\') && (*(termPtr+1) == '\n')) {
	    /*
	     * Line is continued on next line; the backslash-newline turns
	     * into space, which terminates the word.
	     */
	} else {
	    type = CHAR_TYPE(termPtr, lastChar);
	    if (!(type & (TCL_SPACE | TCL_COMMAND_END))) {
		Tcl_ResetResult(interp);
		if (*(src-1) == '"') {
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "extra characters after close-quote", -1);
		} else {
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
			    "extra characters after close-brace", -1);
		}
		result = TCL_ERROR;
		goto done;
	    }
	}
	maxDepth = envPtr->maxStackDepth;
    } else {
	result = CompileMultipartWord(interp, src, lastChar, flags, envPtr);
	termPtr = (src + envPtr->termOffset);
	maxDepth = envPtr->maxStackDepth;
    }

    /*
     * Done processing the word. The values of envPtr->wordIsSimple and
     * envPtr->numSimpleWordChars are left at the values returned by
     * TclCompileQuotes/Braces/MultipartWord.
     */
    
    done:
    envPtr->termOffset = (termPtr - string);
    envPtr->maxStackDepth = maxDepth;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileMultipartWord --
 *
 *	This procedure compiles one multipart word: a word comprised of some
 *	number of nested commands, variable references, or arbitrary
 *	characters. This procedure assumes that quoted string and braced
 *	string words and the end of command have already been handled by its
 *	caller. It also assumes that any leading white space has already
 *	been consumed.
 *
 *	Ordinarily, callers set envPtr->pushSimpleWords to 1 and this
 *	procedure emits push and other instructions to compute the word on
 *	the Tcl evaluation stack at execution time. If a caller sets
 *	envPtr->pushSimpleWords to 0, it will _not_ compile "simple" words:
 *	words that are just a sequence of characters without backslashes.
 *	It will leave their compilation up to the caller. This is done, for
 *	example, to provide special support for the first word of commands,
 *	which are almost always the (simple) name of a command.
 *
 *	As an important special case, if the word is simple, this procedure
 *	sets envPtr->wordIsSimple to 1 and envPtr->numSimpleWordChars to the
 *	number of characters in the simple word. This allows the caller to
 *	process these words specially.
 *
 * Results:
 *	The return value is a standard Tcl result. If an error occurs, an
 *	error message is left in the interpreter's result.
 *	
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed in the last
 *	word. This is normally the character just after the last one in a
 *	word (perhaps the command terminator), or the vicinity of an error
 *	(if the result is not TCL_OK).
 *
 *	envPtr->wordIsSimple is set 1 if the word is simple: just a
 *	sequence of characters without backslashes. If so, the word's
 *	characters are the envPtr->numSimpleWordChars characters starting 
 *	at string.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to evaluate the word. This is not changed if
 *	the word is simple and envPtr->pushSimpleWords was 0 (false).
 *
 * Side effects:
 *	Instructions are added to envPtr to compute and push the word
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileMultipartWord(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Interpreter to use for nested command
				 * evaluations and error messages. */
    char *string;		/* First character of word. */
    char *lastChar;		 /* Pointer to terminating character of
				  * string. */
    int flags;			/* Flags to control compilation (same values
				 * passed to Tcl_EvalObj). */
    CompileEnv *envPtr;		/* Holds the resulting instructions. */
{
    /*
     * Compile one multi_part word:
     *
     * multi_part_word:  word_part+
     * word_part:        nested_cmd | var_reference | char+
     * nested_cmd:       '[' command ']'
     * var_reference:    '$' name | '$' name '(' index_string ')' |
     *                   '$' '{' braced_name '}')
     * name:             (letter | digit | underscore)+
     * braced_name:      (non_close_brace_char)*
     * index_string:     (non_close_paren_char)*
     */
    
    register char *src = string; /* Points to current source char. */
    register char c = *src;	/* The current char. */
    register int type;		/* Current char's CHAR_TYPE type. */
    int bracketNormal = !(flags & TCL_BRACKET_TERM);
    int simpleWord = 0;		/* Set 1 if word is simple. */
    int numParts = 0;		/* Count of word_part objs pushed. */
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to compute and push the word. */
    char *start;		/* Starting position of char+ word_part. */
    int hasBackslash;		/* Nonzero if '\' in char+ word_part. */
    int numChars;		/* Number of chars in char+ word_part. */
    char savedChar;		/* Holds the character from string
				 * termporarily replaced by a null character
				 * during word_part processing. */
    int objIndex;		/* The object array index for a pushed
				 * object holding a word_part. */
    int savePushSimpleWords = envPtr->pushSimpleWords;
    int result = TCL_OK;
    int numRead;

    type = CHAR_TYPE(src, lastChar);
    while (1) {
	/*
	 * Process a word_part: a sequence of chars, a var reference, or
	 * a nested command.
	 */

	if ((type & (TCL_NORMAL | TCL_CLOSE_BRACE | TCL_BACKSLASH |
		     TCL_QUOTE | TCL_OPEN_BRACE)) ||
	    ((c == ']') && bracketNormal)) {
	    /*
	     * A char+ word part. Scan first looking for any backslashes.
	     * Note that a backslash-newline must be treated as a word
	     * separator, as if the backslash-newline had been collapsed
	     * before command parsing began.
	     */
	    
	    start = src;
	    hasBackslash = 0;
	    do {
		if (type == TCL_BACKSLASH) {
		    hasBackslash = 1;
		    Tcl_Backslash(src, &numRead);
		    if (src[1] == '\n') {
			src += numRead;
			type = TCL_SPACE; /* force word end */
			break;
		    }
		    src += numRead;
		} else {
		    src++;
		}
		c = *src;
		type = CHAR_TYPE(src, lastChar);
	    } while (type & (TCL_NORMAL | TCL_BACKSLASH | TCL_QUOTE |
			    TCL_OPEN_BRACE | TCL_CLOSE_BRACE)
			    || ((c == ']') && bracketNormal));

	    if ((numParts == 0) && !hasBackslash
		    && (type & (TCL_SPACE | TCL_COMMAND_END))) {
		/*
		 * The word is "simple": just a sequence of characters
		 * without backslashes terminated by a TCL_SPACE or
		 * TCL_COMMAND_END. Just return if we are not to compile
		 * simple words.
		 */

		simpleWord = 1;
		if (!envPtr->pushSimpleWords) {
		    envPtr->wordIsSimple = 1;
		    envPtr->numSimpleWordChars = (src - string);
		    envPtr->termOffset = envPtr->numSimpleWordChars;
		    envPtr->pushSimpleWords = savePushSimpleWords;
		    return TCL_OK;
		}
	    }

	    /*
	     * Create and push a string object for the char+ word_part,
	     * which starts at "start" and ends at the char just before
	     * src. If backslashes were found, copy the word_part's
	     * characters with substituted backslashes into a heap-allocated
	     * buffer and use it to create the string object. Temporarily
	     * replace the terminating character with a null character.
	     */

	    numChars = (src - start);
	    savedChar = start[numChars];
	    start[numChars] = '\0';
	    if ((numChars > 0) && (hasBackslash)) {
		char *buffer = ckalloc((unsigned) numChars + 1);
		register char *dst = buffer;
		register char *p = start;
		while (p < src) {
		    if (*p == '\\') {	
			*dst = Tcl_Backslash(p, &numRead);
			if (p[1] == '\n') {
			    break;
			}
			p += numRead;
			dst++;
		    } else {
			*dst++ = *p++;
		    }
		}
		*dst = '\0';
		objIndex = TclObjIndexForString(buffer, dst-buffer,
			/*allocStrRep*/ 1, /*inHeap*/ 1, envPtr);
	    } else {
		objIndex = TclObjIndexForString(start, numChars,
			/*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
	    }
	    start[numChars] = savedChar;
	    TclEmitPush(objIndex, envPtr);
	    maxDepth = TclMax((numParts + 1), maxDepth);
	} else if (type == TCL_DOLLAR) {
	    result = TclCompileDollarVar(interp, src, lastChar,
		    flags, envPtr);
	    src += envPtr->termOffset;
	    if (result != TCL_OK) {
		goto done;
	    }
	    maxDepth = TclMax((numParts + envPtr->maxStackDepth), maxDepth);
	    c = *src;
	    type = CHAR_TYPE(src, lastChar);
	} else if (type == TCL_OPEN_BRACKET) {
	    char *termPtr;
	    envPtr->pushSimpleWords = 1;
	    src++;
	    result = TclCompileString(interp, src, lastChar,
				      (flags | TCL_BRACKET_TERM), envPtr);
	    termPtr = (src + envPtr->termOffset);
	    if (*termPtr == ']') {
		termPtr++;
	    } else if (*termPtr == '\0') {
		/*
		 * Missing ] at end of nested command.
		 */
		
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "missing close-bracket", -1);
		result = TCL_ERROR;
	    }
	    src = termPtr;
	    if (result != TCL_OK) {
		goto done;
	    }
	    maxDepth = TclMax((numParts + envPtr->maxStackDepth), maxDepth);
	    c = *src;
	    type = CHAR_TYPE(src, lastChar);
	} else if (type & (TCL_SPACE | TCL_COMMAND_END)) {
	    goto wordEnd;
	}
	numParts++;
    } /* end of infinite loop */

    wordEnd:
    /*
     * End of a non-simple word: TCL_SPACE, TCL_COMMAND_END, or
     * backslash-newline. Concatenate the word_parts if necessary.
     */

    while (numParts > 255) {
	TclEmitInstUInt1(INST_CONCAT1, 255, envPtr);
	numParts -= 254;  /* concat pushes 1 obj, the result */
    }
    if (numParts > 1) {
	TclEmitInstUInt1(INST_CONCAT1, numParts, envPtr);
    }

    done:
    if (simpleWord) {
	envPtr->wordIsSimple = 1;
	envPtr->numSimpleWordChars = (src - string);
    } else {
	envPtr->wordIsSimple = 0;
	envPtr->numSimpleWordChars = 0;
    }
    envPtr->termOffset = (src - string);
    envPtr->maxStackDepth = maxDepth;
    envPtr->pushSimpleWords = savePushSimpleWords;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileQuotes --
 *
 *	This procedure compiles a double-quoted string such as a quoted Tcl
 *	command argument or a quoted value in a Tcl expression. This
 *	procedure is also used to compile array element names within
 *	parentheses (where the termChar will be ')' instead of '"'), or
 *	anything else that needs the substitutions that happen in quotes.
 *
 *	Ordinarily, callers set envPtr->pushSimpleWords to 1 and
 *	TclCompileQuotes always emits push and other instructions to compute
 *	the word on the Tcl evaluation stack at execution time. If a caller
 *	sets envPtr->pushSimpleWords to 0, TclCompileQuotes will not compile
 *	"simple" words: words that are just a sequence of characters without
 *	backslashes. It will leave their compilation up to the caller. This
 *	is done to provide special support for the first word of commands,
 *	which are almost always the (simple) name of a command.
 *
 *	As an important special case, if the word is simple, this procedure
 *	sets envPtr->wordIsSimple to 1 and envPtr->numSimpleWordChars to the
 *	number of characters in the simple word. This allows the caller to
 *	process these words specially.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while parsing the quoted string. If an error
 *	occurs then the interpreter's result contains a standard error
 *	message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed; this is
 *	usually the character just after the matching close-quote.
 *
 *	envPtr->wordIsSimple is set 1 if the word is simple: just a
 *	sequence of characters without backslashes. If so, the word's
 *	characters are the envPtr->numSimpleWordChars characters starting 
 *	at string.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to evaluate the word. This is not changed if
 *	the word is simple and envPtr->pushSimpleWords was 0 (false).
 *
 * Side effects:
 *	Instructions are added to envPtr to push the quoted-string
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileQuotes(interp, string, lastChar, termChar, flags, envPtr)
    Tcl_Interp *interp;		 /* Interpreter to use for nested command
				  * evaluations and error messages. */
    char *string;		 /* Points to the character just after
				  * the opening '"' or '('. */
    char *lastChar;		 /* Pointer to terminating character of
				  * string. */
    int termChar;		 /* Character that terminates the "quoted"
				  * string (usually double-quote, but might
				  * be right-paren or something else). */
    int flags;			 /* Flags to control compilation (same 
				  * values passed to Tcl_Eval). */
    CompileEnv *envPtr;		 /* Holds the resulting instructions. */
{
    register char *src = string; /* Points to current source char. */
    register char c = *src;	 /* The current char. */
    int simpleWord = 0;		 /* Set 1 if a simple quoted string word. */
    char *start;		 /* Start position of char+ string_part. */
    int hasBackslash; 	         /* 1 if '\' found in char+ string_part. */
    int numRead;		 /* Count of chars read by Tcl_Backslash. */
    int numParts = 0;	         /* Count of string_part objs pushed. */
    int maxDepth = 0;		 /* Maximum number of stack elements needed
				  * to compute and push the string. */
    char savedChar;		 /* Holds the character from string
				  * termporarily replaced by a null 
				  * char during string_part processing. */
    int objIndex;		 /* The object array index for a pushed
				  * object holding a string_part. */
    int numChars;		 /* Number of chars in string_part. */
    int savePushSimpleWords = envPtr->pushSimpleWords;
    int result = TCL_OK;
    
    /*
     * quoted_string: '"' string_part* '"'   (or termChar instead of ")
     * string_part:   var_reference | nested_cmd | char+
     */


    while ((src != lastChar) && (c != termChar)) {
	if (c == '$') {
	    result = TclCompileDollarVar(interp, src, lastChar, flags,
		    envPtr);
	    src += envPtr->termOffset;
	    if (result != TCL_OK) {
		goto done;
	    }
	    maxDepth = TclMax((numParts + envPtr->maxStackDepth), maxDepth);
	    c = *src;
        } else if (c == '[') {
	    char *termPtr;
	    envPtr->pushSimpleWords = 1;
	    src++;
	    result = TclCompileString(interp, src, lastChar,
				      (flags | TCL_BRACKET_TERM), envPtr);
	    termPtr = (src + envPtr->termOffset);
	    if (*termPtr == ']') {
		termPtr++;
	    }
	    src = termPtr;
	    if (result != TCL_OK) {
		goto done;
	    }
	    if (termPtr == lastChar) {
		/*
		 * Missing ] at end of nested command.
		 */
		
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "missing close-bracket", -1);
		result = TCL_ERROR;
		goto done;
	    }
	    maxDepth = TclMax((numParts + envPtr->maxStackDepth), maxDepth);
	    c = *src;
        } else {
	    /*
	     * Start of a char+ string_part. Scan first looking for any
	     * backslashes.
	     */

	    start = src;
	    hasBackslash = 0;
	    do {
		if (c == '\\') {
		    hasBackslash = 1;
		    Tcl_Backslash(src, &numRead);
		    src += numRead;
		} else {
		    src++;
		}
		c = *src;
            } while ((src != lastChar) && (c != '$') && (c != '[')
		    && (c != termChar));
	    
	    if ((numParts == 0) && !hasBackslash
		    && ((src == lastChar) && (c == termChar))) {
		/*
		 * The quoted string is "simple": just a sequence of
		 * characters without backslashes terminated by termChar or
		 * a null character. Just return if we are not to compile
		 * simple words.
		 */

		simpleWord = 1;
		if (!envPtr->pushSimpleWords) {
		    if ((src == lastChar) && (termChar != '\0')) {
			char buf[40];
			sprintf(buf, "missing %c", termChar);
			Tcl_ResetResult(interp);
			Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
			result = TCL_ERROR;
		    } else {
			src++;
		    }
		    envPtr->wordIsSimple = 1;
		    envPtr->numSimpleWordChars = (src - string - 1);
		    envPtr->termOffset = (src - string);
		    envPtr->pushSimpleWords = savePushSimpleWords;
		    return result;
		}
	    }

	    /*
	     * Create and push a string object for the char+ string_part
	     * that starts at "start" and ends at the char just before
	     * src. If backslashes were found, copy the string_part's
	     * characters with substituted backslashes into a heap-allocated
	     * buffer and use it to create the string object. Temporarily
	     * replace the terminating character with a null character.
	     */
	    
	    numChars = (src - start);
	    savedChar = start[numChars];
	    start[numChars] = '\0';
	    if ((numChars > 0) && (hasBackslash)) {
		char *buffer = ckalloc((unsigned) numChars + 1);
		register char *dst = buffer;
		register char *p = start;
		while (p < src) {
		    if (*p == '\\') {
			*dst++ = Tcl_Backslash(p, &numRead);
			p += numRead;
		    } else {
			*dst++ = *p++;
		    }
		}
		*dst = '\0';
		objIndex = TclObjIndexForString(buffer, (dst - buffer),
			/*allocStrRep*/ 1, /*inHeap*/ 1, envPtr);
	    } else {
		objIndex = TclObjIndexForString(start, numChars,
			/*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
	    }
	    start[numChars] = savedChar;
	    TclEmitPush(objIndex, envPtr);
	    maxDepth = TclMax((numParts + 1), maxDepth);
        }
	numParts++;
    } 
	    
    /*
     * End of the quoted string: src points at termChar or '\0'. If
     * necessary, concatenate the string_part objects on the stack.
     */

    if ((src == lastChar) && (termChar != '\0')) {
	char buf[40];
	sprintf(buf, "missing %c", termChar);
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
	result = TCL_ERROR;
	goto done;
    } else {
	src++;
    }

    if (numParts == 0) {
	/*
	 * The quoted string was empty. Push an empty string object.
	 */

	int objIndex = TclObjIndexForString("", 0, /*allocStrRep*/ 0,
                                            /*inHeap*/ 0, envPtr);
	TclEmitPush(objIndex, envPtr);
    } else {
	/*
	 * Emit any needed concat instructions.
	 */
	
	while (numParts > 255) {
	    TclEmitInstUInt1(INST_CONCAT1, 255, envPtr);
	    numParts -= 254;  /* concat pushes 1 obj, the result */
	}
	if (numParts > 1) {
	    TclEmitInstUInt1(INST_CONCAT1, numParts, envPtr);
	}
    }

    done:
    if (simpleWord) {
	envPtr->wordIsSimple = 1;
	envPtr->numSimpleWordChars = (src - string - 1);
    } else {
	envPtr->wordIsSimple = 0;
	envPtr->numSimpleWordChars = 0;
    }
    envPtr->termOffset = (src - string);
    envPtr->maxStackDepth = maxDepth;
    envPtr->pushSimpleWords = savePushSimpleWords;
    return result;
}

/*
 *--------------------------------------------------------------
 *
 * CompileBraces --
 *
 *	This procedure compiles characters between matching curly braces.
 *
 *	Ordinarily, callers set envPtr->pushSimpleWords to 1 and
 *	CompileBraces always emits a push instruction to compute the word on
 *	the Tcl evaluation stack at execution time. However, if a caller
 *	sets envPtr->pushSimpleWords to 0, CompileBraces will _not_ compile
 *	"simple" words: words that are just a sequence of characters without
 *	backslash-newlines. It will leave their compilation up to the
 *	caller.
 *
 *	As an important special case, if the word is simple, this procedure
 *	sets envPtr->wordIsSimple to 1 and envPtr->numSimpleWordChars to the
 *	number of characters in the simple word. This allows the caller to
 *	process these words specially.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while parsing string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed. This is
 *	usually the character just after the matching close-brace.
 *
 *	envPtr->wordIsSimple is set 1 if the word is simple: just a
 *	sequence of characters without backslash-newlines. If so, the word's
 *	characters are the envPtr->numSimpleWordChars characters starting 
 *	at string.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to evaluate the word. This is not changed if
 *	the word is simple and envPtr->pushSimpleWords was 0 (false).
 *
 * Side effects:
 *	Instructions are added to envPtr to push the braced string
 *	at runtime.
 *
 *--------------------------------------------------------------
 */

static int
CompileBraces(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		 /* Interpreter to use for nested command
				  * evaluations and error messages. */
    char *string;		 /* Character just after opening bracket. */
    char *lastChar;		 /* Pointer to terminating character of
				  * string. */
    int flags;			 /* Flags to control compilation (same 
				  * values passed to Tcl_Eval). */
    CompileEnv *envPtr;		 /* Holds the resulting instructions. */
{
    register char *src = string; /* Points to current source char. */
    register char c;		 /* The current char. */
    int simpleWord = 0;		 /* Set 1 if a simple braced string word. */
    int level = 1;		 /* {} nesting level. Initially 1 since {
				  * was parsed before we were called. */
    int hasBackslashNewline = 0; /* Nonzero if '\' found. */
    char *last;			 /* Points just before terminating '}'. */
    int numChars;		 /* Number of chars in braced string. */
    char savedChar;		 /* Holds the character from string
				  * termporarily replaced by a null 
				  * char during braced string processing. */
    int objIndex;		 /* The object array index for a pushed
				  * object holding a braced string. */
    int numRead;
    int result = TCL_OK;

    /*
     * Check for any backslash-newlines, since we must treat
     * backslash-newlines specially (they must be replaced by spaces).
     */

    while (1) {
	c = *src;
	if (src == lastChar) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		    "missing close-brace", -1);
	    result = TCL_ERROR;
	    goto done;
	}
	if (CHAR_TYPE(src, lastChar) != TCL_NORMAL) {
	    if (c == '{') {
		level++;
	    } else if (c == '}') {
		--level;
		if (level == 0) {
		    src++;
		    last = (src - 2); /* point just before terminating } */
		    break;
		}
	    } else if (c == '\\') {
		if (*(src+1) == '\n') {
		    hasBackslashNewline = 1;
		}
		(void) Tcl_Backslash(src, &numRead);
		src += numRead - 1;
	    }
	}
	src++;
    }

    if (!hasBackslashNewline) {
	/*
	 * The braced word is "simple": just a sequence of characters
	 * without backslash-newlines. Just return if we are not to compile
	 * simple words.
	 */

	simpleWord = 1;
	if (!envPtr->pushSimpleWords) {
	    envPtr->wordIsSimple = 1;
	    envPtr->numSimpleWordChars = (src - string - 1);
	    envPtr->termOffset = (src - string);
	    return TCL_OK;
	}
    }

    /*
     * Create and push a string object for the braced string. This starts at
     * "string" and ends just after "last" (which points to the final
     * character before the terminating '}'). If backslash-newlines were
     * found, we copy characters one at a time into a heap-allocated buffer
     * and do backslash-newline substitutions.
     */

    numChars = (last - string + 1);
    savedChar = string[numChars];
    string[numChars] = '\0';
    if ((numChars > 0) && (hasBackslashNewline)) {
	char *buffer = ckalloc((unsigned) numChars + 1);
	register char *dst = buffer;
	register char *p = string;
	while (p <= last) {
	    c = *dst++ = *p++;
	    if (c == '\\') {
		if (*p == '\n') {
		    dst[-1] = Tcl_Backslash(p-1, &numRead);
		    p += numRead - 1;
		} else {
		    (void) Tcl_Backslash(p-1, &numRead);
		    while (numRead > 1) {
			*dst++ = *p++;
			numRead--;
		    }
		}
	    }
	}
	*dst = '\0';
	objIndex = TclObjIndexForString(buffer, (dst - buffer),
		/*allocStrRep*/ 1, /*inHeap*/ 1, envPtr);
    } else {
	objIndex = TclObjIndexForString(string, numChars, /*allocStrRep*/ 1,
                                        /*inHeap*/ 0, envPtr);
    }
    string[numChars] = savedChar;
    TclEmitPush(objIndex, envPtr);

    done:
    if (simpleWord) {
	envPtr->wordIsSimple = 1;
	envPtr->numSimpleWordChars = (src - string - 1);
    } else {
	envPtr->wordIsSimple = 0;
	envPtr->numSimpleWordChars = 0;
    }
    envPtr->termOffset = (src - string);
    envPtr->maxStackDepth = 1;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileDollarVar --
 *
 *	Given a string starting with a $ sign, parse a variable name
 *	and compile instructions to push its value. If the variable
 *	reference is just a '$' (i.e. the '$' isn't followed by anything
 *	that could possibly be a variable name), just push a string object
 *	containing '$'.
 *
 * Results:
 *	The return value is a standard Tcl result. If an error occurs
 *	then an error message is left in the interpreter's result.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one in the variable reference.
 *
 *	envPtr->wordIsSimple is set 0 (false) because the word is not
 *	simple: it is not just a sequence of characters without backslashes.
 *	For the same reason, envPtr->numSimpleWordChars is set 0.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the string's commands.
 *
 * Side effects:
 *	Instructions are added to envPtr to look up the variable and
 *	push its value at runtime.
 *
 *----------------------------------------------------------------------
 */
    
int
TclCompileDollarVar(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		 /* Interpreter to use for nested command
				  * evaluations and error messages. */
    char *string;		 /* First char (i.e. $) of var reference. */
    char *lastChar;		 /* Pointer to terminating character of
				  * string. */
    int flags;			 /* Flags to control compilation (same
				  * values passed to Tcl_Eval). */
    CompileEnv *envPtr;		 /* Holds the resulting instructions. */
{
    register char *src = string; /* Points to current source char. */
    register char c;		 /* The current char. */
    char *name;			 /* Start of 1st part of variable name. */
    int nameChars;		 /* Count of chars in name. */
    int nameHasNsSeparators = 0; /* Set 1 if name contains "::"s. */
    char savedChar;		 /* Holds the character from string
				  * termporarily replaced by a null 
				  * char during name processing. */
    int objIndex;		 /* The object array index for a pushed
				  * object holding a name part. */
    int isArrayRef = 0;		 /* 1 if reference to array element. */
    int localIndex = -1;	 /* Frame index of local if found.  */
    int maxDepth = 0;		 /* Maximum number of stack elements needed
				  * to push the variable. */
    int savePushSimpleWords = envPtr->pushSimpleWords;
    int result = TCL_OK;

    /*
     * var_reference: '$' '{' braced_name '}' |
     *                '$' name ['(' index_string ')']
     *
     * There are three cases:
     * 1. The $ sign is followed by an open curly brace. Then the variable
     *    name is everything up to the next close curly brace, and the
     *    variable is a scalar variable.
     * 2. The $ sign is not followed by an open curly brace. Then the
     *    variable name is everything up to the next character that isn't
     *    a letter, digit, underscore, or a "::" namespace separator. If the
     *    following character is an open parenthesis, then the information
     *    between parentheses is the array element name, which can include
     *    any of the substitutions permissible between quotes.
     * 3. The $ sign is followed by something that isn't a letter, digit,
     *    underscore, or a "::" namespace separator: in this case,
     *    there is no variable name, and "$" is pushed.
     */

    src++;			/* advance over the '$'. */

    /*
     * Collect the first part of the variable's name into "name" and
     * determine if it is an array reference and if it contains any
     * namespace separator (::'s).
     */
    
    if (*src == '{') {
        /*
	 * A scalar name in braces.
	 */

	char *p;

	src++;
        name = src;
        c = *src;
	while (c != '}') {
	    if (src == lastChar) {
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
			"missing close-brace for variable name", -1);
		result = TCL_ERROR;
		goto done;
	    }
	    src++;
	    c = *src;
	}
	nameChars = (src - name);
	for (p = name;  p < src;  p++) {
	    if ((*p == ':') && (*(p+1) == ':')) {
		nameHasNsSeparators = 1;
		break;
	    }
	}
	src++;			/* advance over the '}'. */
    } else {
	/*
	 * Scalar name or array reference not in braces.
	 */
	
        name = src;
        c = *src;
        while (isalnum(UCHAR(c)) || (c == '_') || (c == ':')) {
	    if (c == ':') {
                if (*(src+1) == ':') {
		    nameHasNsSeparators = 1;
                    src += 2;
		    while (*src == ':') {
			src++;
		    }
                    c = *src;
                } else {
                    break;	/* : by itself */
                }
            } else {
                src++;
                c = *src;
            }
	}
	if (src == name) {
	    /*
	     * A '$' by itself, not a name reference. Push a "$" string.
	     */

	    objIndex = TclObjIndexForString("$", 1, /*allocStrRep*/ 1,
                                            /*inHeap*/ 0, envPtr);
	    TclEmitPush(objIndex, envPtr);
	    maxDepth = 1;
	    goto done;
	}
	nameChars = (src - name);
	isArrayRef = (c == '(');
    }

    /*
     * Now emit instructions to load the variable. First either push the
     * name of the scalar or array, or determine its index in the array of
     * local variables in a procedure frame. Push the name if we are not
     * compiling a procedure body or if the name has namespace
     * qualifiers ("::"s).
     */
    
    if (!isArrayRef) {		/* scalar reference */
	if ((envPtr->procPtr == NULL) || nameHasNsSeparators) {
	    savedChar = name[nameChars];
	    name[nameChars] = '\0';
	    objIndex = TclObjIndexForString(name, nameChars,
		    /*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
	    name[nameChars] = savedChar;
	    TclEmitPush(objIndex, envPtr);
	    TclEmitOpcode(INST_LOAD_SCALAR_STK, envPtr);
	    maxDepth = 1;
	} else {
	    localIndex = LookupCompiledLocal(name, nameChars,
	            /*createIfNew*/ 0, /*flagsIfCreated*/ 0,
		    envPtr->procPtr);
	    if (localIndex >= 0) {
		if (localIndex <= 255) {
		    TclEmitInstUInt1(INST_LOAD_SCALAR1, localIndex, envPtr);
		} else {
		    TclEmitInstUInt4(INST_LOAD_SCALAR4, localIndex, envPtr);
		}
		maxDepth = 0;
	    } else {
		savedChar = name[nameChars];
		name[nameChars] = '\0';
		objIndex = TclObjIndexForString(name, nameChars,
			/*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
		name[nameChars] = savedChar;
		TclEmitPush(objIndex, envPtr); 
		TclEmitOpcode(INST_LOAD_SCALAR_STK, envPtr);
		maxDepth = 1;
	    }
	}
    } else {			/* array reference */
	if ((envPtr->procPtr == NULL) || nameHasNsSeparators) {
	    savedChar = name[nameChars];
	    name[nameChars] = '\0';
	    objIndex = TclObjIndexForString(name, nameChars,
		    /*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
	    name[nameChars] = savedChar;
	    TclEmitPush(objIndex, envPtr);
	    maxDepth = 1;
	} else {
	    localIndex = LookupCompiledLocal(name, nameChars,
	            /*createIfNew*/ 0, /*flagsIfCreated*/ 0,
		    envPtr->procPtr);
	    if (localIndex < 0) {
		savedChar = name[nameChars];
		name[nameChars] = '\0';
		objIndex = TclObjIndexForString(name, nameChars,
			/*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
		name[nameChars] = savedChar;
		TclEmitPush(objIndex, envPtr);
		maxDepth = 1;
	    }
	}

	/*
	 * Parse and push the array element. Perform substitutions on it,
	 * just as is done for quoted strings.
	 */

	src++;
	envPtr->pushSimpleWords = 1;
	result = TclCompileQuotes(interp, src, lastChar, ')', flags,
		envPtr);
	src += envPtr->termOffset;
	if (result != TCL_OK) {
	    char msg[200];
	    sprintf(msg, "\n    (parsing index for array \"%.*s\")",
		    (nameChars > 100? 100 : nameChars), name);
	    Tcl_AddObjErrorInfo(interp, msg, -1);
	    goto done;
	}
	maxDepth += envPtr->maxStackDepth;

	/*
	 * Now emit the appropriate load instruction for the array element.
	 */

	if (localIndex < 0) {	/* a global or an unknown local */
	    TclEmitOpcode(INST_LOAD_ARRAY_STK, envPtr);
	} else {
	    if (localIndex <= 255) {
		TclEmitInstUInt1(INST_LOAD_ARRAY1, localIndex, envPtr);
	    } else {
		TclEmitInstUInt4(INST_LOAD_ARRAY4, localIndex, envPtr);
	    }
	}
    }

    done:
    envPtr->termOffset = (src - string);
    envPtr->wordIsSimple = 0;
    envPtr->numSimpleWordChars = 0;
    envPtr->maxStackDepth = maxDepth;
    envPtr->pushSimpleWords = savePushSimpleWords;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileBreakCmd --
 *
 *	Procedure called to compile the "break" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while parsing string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the "break" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileBreakCmd(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    register char *src = string;/* Points to current source char. */
    register int type;		/* Current char's CHAR_TYPE type. */
    int result = TCL_OK;
    
    /*
     * There should be no argument after the "break".
     */

    type = CHAR_TYPE(src, lastChar);
    if (type != TCL_COMMAND_END) {
	AdvanceToNextWord(src, envPtr);
	src += envPtr->termOffset;
	type = CHAR_TYPE(src, lastChar);
	if (type != TCL_COMMAND_END) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	            "wrong # args: should be \"break\"", -1);
	    result = TCL_ERROR;
	    goto done;
	}
    }

    /*
     * Emit a break instruction.
     */

    TclEmitOpcode(INST_BREAK, envPtr);

    done:
    envPtr->termOffset = (src - string);
    envPtr->maxStackDepth = 0;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileCatchCmd --
 *
 *	Procedure called to compile the "catch" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK if
 *	compilation was successful. If an error occurs then the
 *	interpreter's result contains a standard error message and TCL_ERROR
 *	is returned. If compilation failed because the command is too
 *	complex for TclCompileCatchCmd, TCL_OUT_LINE_COMPILE is returned
 *	indicating that the catch command should be compiled "out of line"
 *	by emitting code to invoke its command procedure at runtime.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the "catch" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileCatchCmd(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Proc *procPtr = envPtr->procPtr;
    				/* Points to structure describing procedure
				 * containing the catch cmd, else NULL. */
    int maxDepth = 0;           /* Maximum number of stack elements needed
				 * to execute cmd. */
    ArgInfo argInfo;		/* Structure holding information about the
				 * start and end of each argument word. */
    int range = -1;		/* If we compile the catch command, the
				 * index for its catch range record in the
				 * ExceptionRange array. -1 if we are not
				 * compiling the command. */
    char *name;			/* If a var name appears for a scalar local
				 * to a procedure, this points to the name's
				 * 1st char and nameChars is its length. */
    int nameChars;		/* Length of the variable name, if any. */
    int localIndex = -1;        /* Index of the variable in the current
				 * procedure's array of local variables.
				 * Otherwise -1 if not in a procedure or
				 * the variable wasn't found. */
    char savedChar;		/* Holds the character from string
				 * termporarily replaced by a null character
				 * during processing of words. */
    JumpFixup jumpFixup;	/* Used to emit the jump after the "no
				 * errors" epilogue code. */
    int numWords, objIndex, jumpDist, result;
    char *bodyStart, *bodyEnd;
    Tcl_Obj *objPtr;
    int savePushSimpleWords = envPtr->pushSimpleWords;

    /*
     * Scan the words of the command and record the start and finish of
     * each argument word.
     */

    InitArgInfo(&argInfo);
    result = CollectArgInfo(interp, string, lastChar, flags, &argInfo);
    numWords = argInfo.numArgs;	  /* i.e., the # after the command name */
    if (result != TCL_OK) {
	goto done;
    }
    if ((numWords != 1) && (numWords != 2)) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"catch command ?varName?\"", -1);
        result = TCL_ERROR;
	goto done;
    }

    /*
     * If a variable was specified and the catch command is at global level
     * (not in a procedure), don't compile it inline: the payoff is
     * too small.
     */

    if ((numWords == 2) && (procPtr == NULL)) {
	result = TCL_OUT_LINE_COMPILE;
        goto done;
    }

    /*
     * Make sure the variable name, if any, has no substitutions and just
     * refers to a local scaler.
     */

    if (numWords == 2) {
	char *firstChar = argInfo.startArray[1];
	char *lastChar  = argInfo.endArray[1];
	
	if (*firstChar == '{') {
	    if (*lastChar != '}') {
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "extra characters after close-brace", -1);
		result = TCL_ERROR;
		goto done;
	    }
	    firstChar++;
	    lastChar--;
	}

	nameChars = (lastChar - firstChar + 1);
	if (nameChars > 0) {
	    char *p = firstChar;
	    while (p != lastChar) {
		if (CHAR_TYPE(p, lastChar) != TCL_NORMAL) {
		    result = TCL_OUT_LINE_COMPILE;
		    goto done;
		}
		if (*p == '(') {
		    if (*lastChar == ')') { /* we have an array element */
			result = TCL_OUT_LINE_COMPILE;
			goto done; 
		    }
		}
		p++;
	    }
	}

	name = firstChar;
	localIndex = LookupCompiledLocal(name, nameChars,
                    /*createIfNew*/ 1, /*flagsIfCreated*/ VAR_SCALAR,
		    procPtr);
    }

    /*
     *==== At this point we believe we can compile the catch command ====
     */

    /*
     * Create and initialize a ExceptionRange record to hold information
     * about this catch command.
     */
    
    envPtr->excRangeDepth++;
    envPtr->maxExcRangeDepth =
	TclMax(envPtr->excRangeDepth, envPtr->maxExcRangeDepth);
    range = CreateExceptionRange(CATCH_EXCEPTION_RANGE, envPtr);

    /*
     * Emit the instruction to mark the start of the catch command.
     */
    
    TclEmitInstUInt4(INST_BEGIN_CATCH4, range, envPtr);
    
    /*
     * Inline compile the catch's body word: the command it controls. Also
     * register the body's starting PC offset and byte length in the
     * ExceptionRange record.
     */

    envPtr->excRangeArrayPtr[range].codeOffset = TclCurrCodeOffset();

    bodyStart = argInfo.startArray[0];
    bodyEnd   = argInfo.endArray[0];
    savedChar = *(bodyEnd+1);
    *(bodyEnd+1) = '\0';
    result = CompileCmdWordInline(interp, bodyStart, (bodyEnd+1),
	    flags, envPtr);
    *(bodyEnd+1) = savedChar;
    
    if (result != TCL_OK) {
	if (result == TCL_ERROR) {
	    char msg[60];
	    sprintf(msg, "\n    (\"catch\" body line %d)",
		    interp->errorLine);
            Tcl_AddObjErrorInfo(interp, msg, -1);
        }
	goto done;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
    envPtr->excRangeArrayPtr[range].numCodeBytes =
	TclCurrCodeOffset() - envPtr->excRangeArrayPtr[range].codeOffset;

    /*
     * Now emit the "no errors" epilogue code for the catch. First, if a
     * variable was specified, store the body's result into the
     * variable; otherwise, just discard the body's result. Then push
     * a "0" object as the catch command's "no error" TCL_OK result,
     * and jump around the "error case" epilogue code.
     */

    if (localIndex != -1) {
	if (localIndex <= 255) {
	    TclEmitInstUInt1(INST_STORE_SCALAR1, localIndex, envPtr);
	} else {
	    TclEmitInstUInt4(INST_STORE_SCALAR4, localIndex, envPtr);
	}
    }
    TclEmitOpcode(INST_POP, envPtr);

    objIndex = TclObjIndexForString("0", 1, /*allocStrRep*/ 0, /*inHeap*/ 0,
	    envPtr);
    objPtr = envPtr->objArrayPtr[objIndex];
    
    Tcl_InvalidateStringRep(objPtr);
    objPtr->internalRep.longValue = 0;
    objPtr->typePtr = &tclIntType;
    
    TclEmitPush(objIndex, envPtr);
    if (maxDepth == 0) {
	maxDepth = 1;	/* since we just pushed one object */
    }
    
    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);

    /*
     * Now emit the "error case" epilogue code. First, if a variable was
     * specified, emit instructions to push the interpreter's object result
     * and store it into the variable. Then emit an instruction to push the
     * nonzero error result. Note that the initial PC offset here is the
     * catch's error target.
     */

    envPtr->excRangeArrayPtr[range].catchOffset = TclCurrCodeOffset();
    if (localIndex != -1) {
	TclEmitOpcode(INST_PUSH_RESULT, envPtr);
	if (localIndex <= 255) {
	    TclEmitInstUInt1(INST_STORE_SCALAR1, localIndex, envPtr);
	} else {
	    TclEmitInstUInt4(INST_STORE_SCALAR4, localIndex, envPtr);
	}
	TclEmitOpcode(INST_POP, envPtr);
    }
    TclEmitOpcode(INST_PUSH_RETURN_CODE, envPtr);

    /*
     * Now that we know the target of the jump after the "no errors"
     * epilogue, update it with the correct distance. This is less
     * than 127 bytes.
     */

    jumpDist = (TclCurrCodeOffset() - jumpFixup.codeOffset);
    if (TclFixupForwardJump(envPtr, &jumpFixup, jumpDist, 127)) {
	panic("TclCompileCatchCmd: bad jump distance %d\n", jumpDist);
    }

    /*
     * Emit the instruction to mark the end of the catch command.
     */

    TclEmitOpcode(INST_END_CATCH, envPtr);

    done:
    if (numWords == 0) {
	envPtr->termOffset = 0;
    } else {
	envPtr->termOffset = (argInfo.endArray[numWords-1] + 1 - string);
    }
    if (range != -1) {		/* we compiled the catch command */
	envPtr->excRangeDepth--;
    }
    envPtr->pushSimpleWords = savePushSimpleWords;
    envPtr->maxStackDepth = maxDepth;
    FreeArgInfo(&argInfo);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileContinueCmd --
 *
 *	Procedure called to compile the "continue" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while parsing string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the "continue" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileContinueCmd(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    register char *src = string;/* Points to current source char. */
    register int type;		/* Current char's CHAR_TYPE type. */
    int result = TCL_OK;
    
    /*
     * There should be no argument after the "continue".
     */

    type = CHAR_TYPE(src, lastChar);
    if (type != TCL_COMMAND_END) {
	AdvanceToNextWord(src, envPtr);
	src += envPtr->termOffset;
	type = CHAR_TYPE(src, lastChar);
	if (type != TCL_COMMAND_END) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	            "wrong # args: should be \"continue\"", -1);
	    result = TCL_ERROR;
	    goto done;
	}
    }

    /*
     * Emit a continue instruction.
     */

    TclEmitOpcode(INST_CONTINUE, envPtr);

    done:
    envPtr->termOffset = (src - string);
    envPtr->maxStackDepth = 0;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileExprCmd --
 *
 *	Procedure called to compile the "expr" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK
 *	unless there was an error while parsing string. If an error occurs
 *	then the interpreter's result contains a standard error message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the "expr" command.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the "expr" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileExprCmd(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute cmd. */
    ArgInfo argInfo;		/* Structure holding information about the
				 * start and end of each argument word. */
    Tcl_DString buffer;		/* Holds the concatenated expr command
				 * argument words. */
    int firstWord;		/* 1 if processing the first word; 0 if
				 * processing subsequent words. */
    char *first, *last;		/* Points to the first and last significant
				 * chars of the concatenated expression. */
    int inlineCode;		/* 1 if inline "optimistic" code is
				 * emitted for the expression; else 0. */
    int range = -1;		/* If we inline compile the concatenated
				 * expression, the index for its catch range
				 * record in the ExceptionRange array.
				 * Initialized to avoid compile warning. */
    JumpFixup jumpFixup;	/* Used to emit the "success" jump after
				 * the inline concat. expression's code. */
    char savedChar;		/* Holds the character termporarily replaced
				 * by a null character during compilation
				 * of the concatenated expression. */
    int numWords, objIndex, i, result;
    char *wordStart, *wordEnd, *p;
    char c;
    int savePushSimpleWords = envPtr->pushSimpleWords;
    int saveExprIsJustVarRef = envPtr->exprIsJustVarRef;
    int saveExprIsComparison = envPtr->exprIsComparison;

    /*
     * Scan the words of the command and record the start and finish of
     * each argument word.
     */

    InitArgInfo(&argInfo);
    result = CollectArgInfo(interp, string, lastChar, flags, &argInfo);
    numWords = argInfo.numArgs;	  /* i.e., the # after the command name */
    if (result != TCL_OK) {
	goto done;
    }
    if (numWords == 0) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"expr arg ?arg ...?\"", -1);
        result = TCL_ERROR;
	goto done;
    }

    /*
     * If there is a single argument word and it is enclosed in {}s, we may
     * strip them off and safely compile the expr command into an inline
     * sequence of instructions using TclCompileExpr. We know these
     * instructions will have the right Tcl7.x expression semantics.
     *
     * Otherwise, if the word is not enclosed in {}s, or there are multiple
     * words, we may need to call the expr command (Tcl_ExprObjCmd) at
     * runtime. This recompiles the expression each time (typically) and so
     * is slow. However, there are some circumstances where we can still
     * compile inline instructions "optimistically" and check, during their
     * execution, for double substitutions (these appear as nonnumeric
     * operands). We check for any backslash or command substitutions. If
     * none appear, and only variable substitutions are found, we generate
     * inline instructions. If there is a compilation error, we must emit
     * instructions that return the error at runtime, since this is when
     * scripts in Tcl7.x would "see" the error.
     *
     * For now, if there are multiple words, or the single argument word is
     * not in {}s, we concatenate the argument words and strip off any
     * enclosing {}s or ""s. We call the expr command at runtime if
     * either command or backslash substitutions appear (but not if
     * only variable substitutions appear).
     */

    if (numWords == 1) {
	wordStart = argInfo.startArray[0]; /* start of 1st arg word */
	wordEnd   = argInfo.endArray[0];   /* last char of 1st arg word */
	if ((*wordStart == '{') && (*wordEnd == '}')) {
	    /*
	     * Simple case: a single argument word in {}'s. 
	     */

	    *wordEnd = '\0';
	    result = TclCompileExpr(interp, (wordStart + 1), wordEnd,
		    flags, envPtr);
	    *wordEnd = '}';
	    
	    envPtr->termOffset = (wordEnd + 1) - string;
	    envPtr->pushSimpleWords = savePushSimpleWords;
	    FreeArgInfo(&argInfo);
	    return result;
	}
    }
	
    /*
     * There are multiple words or no braces around the single word.
     * Concatenate the expression's argument words while stripping off
     * any enclosing {}s or ""s.
     */
    
    Tcl_DStringInit(&buffer);
    firstWord = 1;
    for (i = 0;  i < numWords;  i++) {
	wordStart = argInfo.startArray[i];
	wordEnd   = argInfo.endArray[i];
	if (((*wordStart == '{') && (*wordEnd == '}'))
	        || ((*wordStart == '"') && (*wordEnd == '"'))) {
	    wordStart++;
	    wordEnd--;
	}
	if (!firstWord) {
	    Tcl_DStringAppend(&buffer, " ", 1);
	}
	firstWord = 0;
	if (wordEnd >= wordStart) {
	    Tcl_DStringAppend(&buffer, wordStart, (wordEnd-wordStart+1));
	}
    }

    /*
     * Scan the concatenated expression's characters looking for any
     * '['s or (for now) '\'s. If any are found, just call the expr cmd
     * at runtime.
     */
    
    inlineCode = 1;
    first = Tcl_DStringValue(&buffer);
    last = first + (Tcl_DStringLength(&buffer) - 1);
    for (p = first;  p <= last;  p++) {
	c = *p;
	if ((c == '[') || (c == '\\')) {
	    inlineCode = 0;
	    break;
	}
    }

    if (inlineCode) {
	/*
	 * Inline compile the concatenated expression inside a "catch"
	 * so that a runtime error will back off to a (slow) call on expr.
	 */
	
	int startCodeOffset = (envPtr->codeNext - envPtr->codeStart);
	int startRangeNext = envPtr->excRangeArrayNext;
	
	/*
	 * Create a ExceptionRange record to hold information about the
	 * "catch" range for the expression's inline code. Also emit the
	 * instruction to mark the start of the range.
	 */
	
	envPtr->excRangeDepth++;
	envPtr->maxExcRangeDepth =
	        TclMax(envPtr->excRangeDepth, envPtr->maxExcRangeDepth);
	range = CreateExceptionRange(CATCH_EXCEPTION_RANGE, envPtr);
	TclEmitInstUInt4(INST_BEGIN_CATCH4, range, envPtr);
	
	/*
	 * Inline compile the concatenated expression.
	 */
	
	envPtr->excRangeArrayPtr[range].codeOffset = TclCurrCodeOffset();
	savedChar = *(last + 1);
	*(last + 1) = '\0';
	result = TclCompileExpr(interp, first, last + 1, flags, envPtr);
	*(last + 1) = savedChar;
	
	maxDepth = envPtr->maxStackDepth;
	envPtr->excRangeArrayPtr[range].numCodeBytes =
	        TclCurrCodeOffset() - envPtr->excRangeArrayPtr[range].codeOffset;
	
	if ((result != TCL_OK) || (envPtr->exprIsJustVarRef)
	        || (envPtr->exprIsComparison)) {
	    /*
	     * We must call the expr command at runtime. Either there was a
	     * compilation error or the inline code might fail to give the
	     * correct 2 level substitution semantics.
	     *
	     * The latter can happen if the expression consisted of just a
	     * single variable reference or if the top-level operator in the
	     * expr is a comparison (which might operate on strings). In the
	     * latter case, the expression's code might execute (apparently)
	     * successfully but produce the wrong result. We depend on its
	     * execution failing if a second level of substitutions is
	     * required. This causes the "catch" code we generate around the
	     * inline code to back off to a call on the expr command at
	     * runtime, and this always gives the right 2 level substitution
	     * semantics.
	     *
	     * We delete the inline code by backing up the code pc and catch
	     * index. Note that if there was a compilation error, we can't
	     * report the error yet since the expression might be valid
	     * after the second round of substitutions.
	     */
	    
	    envPtr->codeNext = (envPtr->codeStart + startCodeOffset);
	    envPtr->excRangeArrayNext = startRangeNext;
	    inlineCode = 0;
	} else {
	    TclEmitOpcode(INST_END_CATCH, envPtr); /* for ok case */
	    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
	    envPtr->excRangeArrayPtr[range].catchOffset = TclCurrCodeOffset();
	    TclEmitOpcode(INST_END_CATCH, envPtr); /* for error case */
	}
    }
	    
    /*
     * Emit code for the (slow) call on the expr command at runtime.
     * Generate code to concatenate the (already substituted once)
     * expression words with a space between each word.
     */
    
    for (i = 0;  i < numWords;  i++) {
	wordStart = argInfo.startArray[i];
	wordEnd   = argInfo.endArray[i];
	savedChar = *(wordEnd + 1);
	*(wordEnd + 1) = '\0';
	envPtr->pushSimpleWords = 1;
	result = CompileWord(interp, wordStart, wordEnd+1, flags, envPtr);
	*(wordEnd + 1) = savedChar;
	if (result != TCL_OK) {
	    break;
	}
	if (i != (numWords - 1)) {
	    objIndex = TclObjIndexForString(" ", 1, /*allocStrRep*/ 1,
					    /*inHeap*/ 0, envPtr);
	    TclEmitPush(objIndex, envPtr);
	    maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);
	} else {
	    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
	}
    }
    if (result == TCL_OK) {
	int concatItems = 2*numWords - 1;
	while (concatItems > 255) {
	    TclEmitInstUInt1(INST_CONCAT1, 255, envPtr);
	    concatItems -= 254;  /* concat pushes 1 obj, the result */
	}
	if (concatItems > 1) {
	    TclEmitInstUInt1(INST_CONCAT1, concatItems, envPtr);
	}
	TclEmitOpcode(INST_EXPR_STK, envPtr);
    }
    
    /*
     * If emitting inline code, update the target of the jump after
     * that inline code.
     */
    
    if (inlineCode) {
	int jumpDist = (TclCurrCodeOffset() - jumpFixup.codeOffset);
	if (TclFixupForwardJump(envPtr, &jumpFixup, jumpDist, 127)) {
	    /*
	     * Update the inline expression code's catch ExceptionRange
	     * target since it, being after the jump, also moved down.
	     */
	    
	    envPtr->excRangeArrayPtr[range].catchOffset += 3;
	}
    }
    Tcl_DStringFree(&buffer);
    
    done:
    if (numWords == 0) {
	envPtr->termOffset = 0;
    } else {
	envPtr->termOffset = (argInfo.endArray[numWords-1] + 1 - string);
    }
    if (range != -1) {		/* we inline compiled the expr */
	envPtr->excRangeDepth--;
    }
    envPtr->pushSimpleWords = savePushSimpleWords;
    envPtr->exprIsJustVarRef = saveExprIsJustVarRef;
    envPtr->exprIsComparison = saveExprIsComparison;
    envPtr->maxStackDepth = maxDepth;
    FreeArgInfo(&argInfo);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileForCmd --
 *
 *	Procedure called to compile the "for" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while parsing string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the "for" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileForCmd(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute cmd. */
    ArgInfo argInfo;		/* Structure holding information about the
				 * start and end of each argument word. */
    int range1, range2;		/* Indexes in the ExceptionRange array of
				 * the loop ranges for this loop: one for
				 * its body and one for its "next" cmd. */
    JumpFixup jumpFalseFixup;	/* Used to update or replace the ifFalse
				 * jump after the "for" test when its target
				 * PC is determined. */
    int jumpBackDist, jumpBackOffset, testCodeOffset, jumpDist, objIndex;
    unsigned char *jumpPc;
    int savePushSimpleWords = envPtr->pushSimpleWords;
    int numWords, result;

    /*
     * Scan the words of the command and record the start and finish of
     * each argument word.
     */

    InitArgInfo(&argInfo);
    result = CollectArgInfo(interp, string, lastChar, flags, &argInfo);
    numWords = argInfo.numArgs;	  /* i.e., the # after the command name */
    if (result != TCL_OK) {
	goto done;
    }
    if (numWords != 4) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"for start test next command\"", -1);
	result = TCL_ERROR;
	goto done;
    }

    /*
     * If the test expression is enclosed in quotes (""s), don't compile
     * the for inline. As a result of Tcl's two level substitution
     * semantics for expressions, the expression might have a constant
     * value that results in the loop never executing, or executing forever.
     * Consider "set x 0; for {} "$x > 5" {incr x} {}": the loop body 
     * should never be executed.
     */

    if (*(argInfo.startArray[1]) == '"') {
	result = TCL_OUT_LINE_COMPILE;
        goto done;
    }

    /*
     * Create a ExceptionRange record for the for loop's body. This is used
     * to implement break and continue commands inside the body.
     * Then create a second ExceptionRange record for the "next" command in 
     * order to implement break (but not continue) inside it. The second,
     * "next" ExceptionRange will always have a -1 continueOffset.
     */

    envPtr->excRangeDepth++;
    envPtr->maxExcRangeDepth =
	TclMax(envPtr->excRangeDepth, envPtr->maxExcRangeDepth);
    range1 = CreateExceptionRange(LOOP_EXCEPTION_RANGE, envPtr);
    range2 = CreateExceptionRange(LOOP_EXCEPTION_RANGE, envPtr);

    /*
     * Compile inline the next word: the initial command.
     */

    result = CompileCmdWordInline(interp, argInfo.startArray[0],
	    (argInfo.endArray[0] + 1), flags, envPtr);
    if (result != TCL_OK) {
	if (result == TCL_ERROR) {
            Tcl_AddObjErrorInfo(interp, "\n    (\"for\" initial command)", -1);
        }
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;

    /*
     * Discard the start command's result.
     */

    TclEmitOpcode(INST_POP, envPtr);

    /*
     * Compile the next word: the test expression.
     */

    testCodeOffset = TclCurrCodeOffset();
    envPtr->pushSimpleWords = 1;    /* process words normally */
    result = CompileExprWord(interp, argInfo.startArray[1],
	    (argInfo.endArray[1] + 1), flags, envPtr);
    if (result != TCL_OK) {
	if (result == TCL_ERROR) {
            Tcl_AddObjErrorInfo(interp, "\n    (\"for\" test expression)", -1);
        }
	goto done;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);

    /*
     * Emit the jump that terminates the for command if the test was
     * false. We emit a one byte (relative) jump here, and replace it later
     * with a four byte jump if the jump target is > 127 bytes away.
     */

    TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFalseFixup);

    /*
     * Compile the loop body word inline. Also register the loop body's
     * starting PC offset and byte length in the its ExceptionRange record.
     */

    envPtr->excRangeArrayPtr[range1].codeOffset = TclCurrCodeOffset();
    result = CompileCmdWordInline(interp, argInfo.startArray[3],
	    (argInfo.endArray[3] + 1), flags, envPtr);
    if (result != TCL_OK) {
	if (result == TCL_ERROR) {
	    char msg[60];
	    sprintf(msg, "\n    (\"for\" body line %d)", interp->errorLine);
            Tcl_AddObjErrorInfo(interp, msg, -1);
        }
	goto done;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
    envPtr->excRangeArrayPtr[range1].numCodeBytes =
	(TclCurrCodeOffset() - envPtr->excRangeArrayPtr[range1].codeOffset);

    /*
     * Discard the loop body's result.
     */

    TclEmitOpcode(INST_POP, envPtr);

    /*
     * Finally, compile the "next" subcommand word inline.
     */

    envPtr->excRangeArrayPtr[range1].continueOffset = TclCurrCodeOffset();
    envPtr->excRangeArrayPtr[range2].codeOffset = TclCurrCodeOffset();
    result = CompileCmdWordInline(interp, argInfo.startArray[2],
	    (argInfo.endArray[2] + 1), flags, envPtr);
    if (result != TCL_OK) {
	if (result == TCL_ERROR) {
	    Tcl_AddObjErrorInfo(interp, "\n    (\"for\" loop-end command)", -1);
	}
	goto done;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
    envPtr->excRangeArrayPtr[range2].numCodeBytes =
	TclCurrCodeOffset() - envPtr->excRangeArrayPtr[range2].codeOffset;

    /*
     * Discard the "next" subcommand's result.
     */

    TclEmitOpcode(INST_POP, envPtr);
	
    /*
     * Emit the unconditional jump back to the test at the top of the for
     * loop. We generate a four byte jump if the distance to the test is
     * greater than 120 bytes. This is conservative, and ensures that we
     * won't have to replace this unconditional jump if we later need to
     * replace the ifFalse jump with a four-byte jump.
     */

    jumpBackOffset = TclCurrCodeOffset();
    jumpBackDist = (jumpBackOffset - testCodeOffset);
    if (jumpBackDist > 120) {
	TclEmitInstInt4(INST_JUMP4, /*offset*/ -jumpBackDist, envPtr);
    } else {
	TclEmitInstInt1(INST_JUMP1, /*offset*/ -jumpBackDist, envPtr);
    }

    /*
     * Now that we know the target of the jumpFalse after the test, update
     * it with the correct distance. If the distance is too great (more
     * than 127 bytes), replace that jump with a four byte instruction and
     * move the instructions after the jump down.
     */

    jumpDist = (TclCurrCodeOffset() - jumpFalseFixup.codeOffset);
    if (TclFixupForwardJump(envPtr, &jumpFalseFixup, jumpDist, 127)) {
	/*
	 * Update the loop body's ExceptionRange record since it moved down:
	 * i.e., increment both its start and continue PC offsets. Also,
	 * update the "next" command's start PC offset in its ExceptionRange
	 * record since it also moved down.
	 */

	envPtr->excRangeArrayPtr[range1].codeOffset += 3;
	envPtr->excRangeArrayPtr[range1].continueOffset += 3;
	envPtr->excRangeArrayPtr[range2].codeOffset += 3;

	/*
	 * Update the distance for the unconditional jump back to the test
	 * at the top of the loop since it moved down 3 bytes too.
	 */

	jumpBackOffset += 3;
	jumpPc = (envPtr->codeStart + jumpBackOffset);
	if (jumpBackDist > 120) {
	    jumpBackDist += 3;
	    TclUpdateInstInt4AtPc(INST_JUMP4, /*offset*/ -jumpBackDist,
				   jumpPc);
	} else {
	    jumpBackDist += 3;
	    TclUpdateInstInt1AtPc(INST_JUMP1, /*offset*/ -jumpBackDist,
				   jumpPc);
	}
    }
    
    /*
     * The current PC offset (after the loop's body and "next" subcommand)
     * is the loop's break target.
     */

    envPtr->excRangeArrayPtr[range1].breakOffset =
	envPtr->excRangeArrayPtr[range2].breakOffset = TclCurrCodeOffset();
    
    /*
     * Push an empty string object as the for command's result.
     */

    objIndex = TclObjIndexForString("", 0, /*allocStrRep*/ 0, /*inHeap*/ 0,
				    envPtr);
    TclEmitPush(objIndex, envPtr);
    if (maxDepth == 0) {
	maxDepth = 1;
    }

    done:
    if (numWords == 0) {
	envPtr->termOffset = 0;
    } else {
	envPtr->termOffset = (argInfo.endArray[numWords-1] + 1 - string);
    }
    envPtr->pushSimpleWords = savePushSimpleWords;
    envPtr->maxStackDepth = maxDepth;
    envPtr->excRangeDepth--;
    FreeArgInfo(&argInfo);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileForeachCmd --
 *
 *	Procedure called to compile the "foreach" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK if
 *	compilation was successful. If an error occurs then the
 *	interpreter's result contains a standard error message and TCL_ERROR
 *	is returned. If complation failed because the command is too complex
 *	for TclCompileForeachCmd, TCL_OUT_LINE_COMPILE is returned
 *	indicating that the foreach command should be compiled "out of line"
 *	by emitting code to invoke its command procedure at runtime.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the "while" command.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the "foreach" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileForeachCmd(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Proc *procPtr = envPtr->procPtr;
    				/* Points to structure describing procedure
				 * containing foreach command, else NULL. */
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute cmd. */
    ArgInfo argInfo;		/* Structure holding information about the
				 * start and end of each argument word. */
    int numLists = 0;		/* Count of variable (and value) lists. */
    int range;			/* Index in the ExceptionRange array of the
				 * ExceptionRange record for this loop. */
    ForeachInfo *infoPtr;	/* Points to the structure describing this
				 * foreach command. Stored in a AuxData
				 * record in the ByteCode. */
    JumpFixup jumpFalseFixup;	/* Used to update or replace the ifFalse
				 * jump after test when its target PC is
				 * determined. */
    char savedChar;		/* Holds the char from string termporarily
				 * replaced by a null character during
				 * processing of argument words. */
    int firstListTmp = -1;	/* If we decide to compile this foreach
				 * command, this is the index or "slot
				 * number" for the first temp var allocated
				 * in the proc frame that holds a pointer to
				 * a value list. Initialized to avoid a
				 * compiler warning. */
    int loopIterNumTmp;		/* If we decide to compile this foreach
				 * command, the index for the temp var that
				 * holds the current iteration count.  */
    char *varListStart, *varListEnd, *valueListStart, *bodyStart, *bodyEnd;
    unsigned char *jumpPc;
    int jumpDist, jumpBackDist, jumpBackOffset;
    int numWords, numVars, infoIndex, tmpIndex, objIndex, i, j, result;
    int savePushSimpleWords = envPtr->pushSimpleWords;

    /*
     * We parse the variable list argument words and create two arrays:
     *    varcList[i] gives the number of variables in the i-th var list
     *    varvList[i] points to an array of the names in the i-th var list
     * These are initially allocated on the stack, and are allocated on
     * the heap if necessary.
     */

#define STATIC_VAR_LIST_SIZE 4
    int varcListStaticSpace[STATIC_VAR_LIST_SIZE];
    char **varvListStaticSpace[STATIC_VAR_LIST_SIZE];

    int *varcList = varcListStaticSpace;
    char ***varvList = varvListStaticSpace;

    /*
     * If the foreach command is at global level (not in a procedure),
     * don't compile it inline: the payoff is too small.
     */

    if (procPtr == NULL) {
	return TCL_OUT_LINE_COMPILE;
    }

    /*
     * Scan the words of the command and record the start and finish of
     * each argument word.
     */

    InitArgInfo(&argInfo);
    result = CollectArgInfo(interp, string, lastChar, flags, &argInfo);
    numWords = argInfo.numArgs;
    if (result != TCL_OK) {
	goto done;
    }
    if ((numWords < 3) || (numWords%2 != 1)) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"foreach varList list ?varList list ...? command\"", -1);
        result = TCL_ERROR;
	goto done;
    }

    /*
     * Initialize the varcList and varvList arrays; allocate heap storage,
     * if necessary, for them. Also make sure the variable names
     * have no substitutions: that they're just "var" or "var(elem)"
     */

    numLists = (numWords - 1)/2;
    if (numLists > STATIC_VAR_LIST_SIZE) {
        varcList = (int *) ckalloc(numLists * sizeof(int));
        varvList = (char ***) ckalloc(numLists * sizeof(char **));
    }
    for (i = 0;  i < numLists;  i++) {
        varcList[i] = 0;
        varvList[i] = (char **) NULL;
    }
    for (i = 0;  i < numLists;  i++) {
	/*
	 * Break each variable list into its component variables. If the
	 * lists is enclosed in {}s or ""s, strip them off first.
	 */

	varListStart = argInfo.startArray[i*2];
	varListEnd   = argInfo.endArray[i*2];
	if ((*varListStart == '{') || (*varListStart == '"')) {
	    if ((*varListEnd != '}') && (*varListEnd != '"')) {
		Tcl_ResetResult(interp);
		if (*varListStart == '"') {
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
			    "extra characters after close-quote", -1);
		} else {
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "extra characters after close-brace", -1);
		}
		result = TCL_ERROR;
		goto done;
	    }
	    varListStart++;
	    varListEnd--;
	}
	    
	/*
	 * NOTE: THIS NEEDS TO BE CONVERTED TO AN OBJECT LIST.
	 */

	savedChar = *(varListEnd+1);
	*(varListEnd+1) = '\0';
	result = Tcl_SplitList(interp, varListStart,
			       &varcList[i], &varvList[i]);
	*(varListEnd+1) = savedChar;
        if (result != TCL_OK) {
            goto done;
        }

	/*
	 * Check that each variable name has no substitutions and that
	 * it is a scalar name.
	 */

	numVars = varcList[i];
	for (j = 0;  j < numVars;  j++) {
	    char *varName = varvList[i][j];
	    char *p = varName;
	    while (*p != '\0') {
		if (CHAR_TYPE(p, p+1) != TCL_NORMAL) {
		    result = TCL_OUT_LINE_COMPILE;
		    goto done;
		}
		if (*p == '(') {
		    char *q = p;
		    do {
			q++;
		    } while (*q != '\0');
		    q--;
		    if (*q == ')') { /* we have an array element */
			result = TCL_OUT_LINE_COMPILE;
			goto done; 
		    }
		}
		p++;
	    }
	}
    }

    /*
     *==== At this point we believe we can compile the foreach command ====
     */

    /*
     * Create and initialize a ExceptionRange record to hold information
     * about this loop. This is used to implement break and continue.
     */
    
    envPtr->excRangeDepth++;
    envPtr->maxExcRangeDepth =
	TclMax(envPtr->excRangeDepth, envPtr->maxExcRangeDepth);
    range = CreateExceptionRange(LOOP_EXCEPTION_RANGE, envPtr);
    
    /*
     * Reserve (numLists + 1) temporary variables:
     *    - numLists temps for each value list
     *    - a temp for the "next value" index into each value list
     * At this time we don't try to reuse temporaries; if there are two
     * nonoverlapping foreach loops, they don't share any temps.
     */

    for (i = 0;  i < numLists;  i++) {
	tmpIndex = LookupCompiledLocal(NULL, /*nameChars*/ 0,
		/*createIfNew*/ 1, /*flagsIfCreated*/ VAR_SCALAR, procPtr);
	if (i == 0) {
	    firstListTmp = tmpIndex;
	}
    }
    loopIterNumTmp = LookupCompiledLocal(NULL, /*nameChars*/ 0,
	    /*createIfNew*/ 1, /*flagsIfCreated*/ VAR_SCALAR, procPtr);
    
    /*
     * Create and initialize the ForeachInfo and ForeachVarList data
     * structures describing this command. Then create a AuxData record
     * pointing to the ForeachInfo structure in the compilation environment.
     */

    infoPtr = (ForeachInfo *) ckalloc((unsigned)
	    (sizeof(ForeachInfo) + (numLists * sizeof(ForeachVarList *))));
    infoPtr->numLists = numLists;
    infoPtr->firstListTmp = firstListTmp;
    infoPtr->loopIterNumTmp = loopIterNumTmp;
    for (i = 0;  i < numLists;  i++) {
	ForeachVarList *varListPtr;
	numVars = varcList[i];
	varListPtr = (ForeachVarList *) ckalloc((unsigned)
	        sizeof(ForeachVarList) + numVars*sizeof(int));
	varListPtr->numVars = numVars;
	for (j = 0;  j < numVars;  j++) {
	    char *varName = varvList[i][j];
	    int nameChars = strlen(varName);
	    varListPtr->varIndexes[j] = LookupCompiledLocal(varName,
		    nameChars, /*createIfNew*/ 1,
                    /*flagsIfCreated*/ VAR_SCALAR, procPtr);
	}
	infoPtr->varLists[i] = varListPtr;
    }
    infoIndex = TclCreateAuxData((ClientData) infoPtr,
            DupForeachInfo, FreeForeachInfo, envPtr);

    /*
     * Emit code to store each value list into the associated temporary.
     */

    for (i = 0;  i < numLists;  i++) {
	valueListStart = argInfo.startArray[2*i + 1];
	envPtr->pushSimpleWords = 1;
	result = CompileWord(interp, valueListStart, lastChar, flags,
		envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);

	tmpIndex = (firstListTmp + i);
	if (tmpIndex <= 255) {
	    TclEmitInstUInt1(INST_STORE_SCALAR1, tmpIndex, envPtr);
	} else {
	    TclEmitInstUInt4(INST_STORE_SCALAR4, tmpIndex, envPtr);
	}
	TclEmitOpcode(INST_POP, envPtr);
    }

    /*
     * Emit the instruction to initialize the foreach loop's index temp var.
     */

    TclEmitInstUInt4(INST_FOREACH_START4, infoIndex, envPtr);
    
    /*
     * Emit the top of loop code that assigns each loop variable and checks
     * whether to terminate the loop.
     */

    envPtr->excRangeArrayPtr[range].continueOffset = TclCurrCodeOffset();
    TclEmitInstUInt4(INST_FOREACH_STEP4, infoIndex, envPtr);

    /*
     * Emit the ifFalse jump that terminates the foreach if all value lists
     * are exhausted. We emit a one byte (relative) jump here, and replace
     * it later with a four byte jump if the jump target is more than
     * 127 bytes away.
     */

    TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFalseFixup);
    
    /*
     * Compile the loop body word inline. Also register the loop body's
     * starting PC offset and byte length in the ExceptionRange record.
     */

    bodyStart = argInfo.startArray[numWords - 1];
    bodyEnd   = argInfo.endArray[numWords - 1];
    savedChar = *(bodyEnd+1);
    *(bodyEnd+1) = '\0';
    envPtr->excRangeArrayPtr[range].codeOffset = TclCurrCodeOffset();
    result = CompileCmdWordInline(interp, bodyStart, bodyEnd+1, flags,
	    envPtr);
    *(bodyEnd+1) = savedChar;
    if (result != TCL_OK) {
	if (result == TCL_ERROR) {
	    char msg[60];
	    sprintf(msg, "\n    (\"foreach\" body line %d)",
		    interp->errorLine);
            Tcl_AddObjErrorInfo(interp, msg, -1);
        }
	goto done;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
    envPtr->excRangeArrayPtr[range].numCodeBytes =
	TclCurrCodeOffset() - envPtr->excRangeArrayPtr[range].codeOffset;

    /*
     * Discard the loop body's result.
     */

    TclEmitOpcode(INST_POP, envPtr);
	
    /*
     * Emit the unconditional jump back to the test at the top of the
     * loop. We generate a four byte jump if the distance to the to of
     * the foreach is greater than 120 bytes. This is conservative and
     * ensures that we won't have to replace this unconditional jump if
     * we later need to replace the ifFalse jump with a four-byte jump.
     */

    jumpBackOffset = TclCurrCodeOffset();
    jumpBackDist =
	(jumpBackOffset - envPtr->excRangeArrayPtr[range].continueOffset);
    if (jumpBackDist > 120) {
	TclEmitInstInt4(INST_JUMP4, /*offset*/ -jumpBackDist, envPtr);
    } else {
	TclEmitInstInt1(INST_JUMP1, /*offset*/ -jumpBackDist, envPtr);
    }

    /*
     * Now that we know the target of the jumpFalse after the foreach_step
     * test, update it with the correct distance. If the distance is too
     * great (more than 127 bytes), replace that jump with a four byte
     * instruction and move the instructions after the jump down.
     */

    jumpDist = (TclCurrCodeOffset() - jumpFalseFixup.codeOffset);
    if (TclFixupForwardJump(envPtr, &jumpFalseFixup, jumpDist, 127)) {
	/*
	 * Update the loop body's starting PC offset since it moved down.
	 */

	envPtr->excRangeArrayPtr[range].codeOffset += 3;

	/*
	 * Update the distance for the unconditional jump back to the test
	 * at the top of the loop since it moved down 3 bytes too.
	 */

	jumpBackOffset += 3;
	jumpPc = (envPtr->codeStart + jumpBackOffset);
	if (jumpBackDist > 120) {
	    jumpBackDist += 3;
	    TclUpdateInstInt4AtPc(INST_JUMP4, /*offset*/ -jumpBackDist,
				   jumpPc);
	} else {
	    jumpBackDist += 3;
	    TclUpdateInstInt1AtPc(INST_JUMP1, /*offset*/ -jumpBackDist,
				   jumpPc);
	}
    }

    /*
     * The current PC offset (after the loop's body) is the loop's
     * break target.
     */

    envPtr->excRangeArrayPtr[range].breakOffset = TclCurrCodeOffset();
    
    /*
     * Push an empty string object as the foreach command's result.
     */

    objIndex = TclObjIndexForString("", 0, /*allocStrRep*/ 0, /*inHeap*/ 0,
				    envPtr);
    TclEmitPush(objIndex, envPtr);
    if (maxDepth == 0) {
	maxDepth = 1;
    }

    done:
    for (i = 0;  i < numLists;  i++) {
        if (varvList[i] != (char **) NULL) {
            ckfree((char *) varvList[i]);
        }
    }
    if (varcList != varcListStaticSpace) {
	ckfree((char *) varcList);
        ckfree((char *) varvList);
    }
    envPtr->termOffset = (argInfo.endArray[numWords-1] + 1 - string);
    envPtr->pushSimpleWords = savePushSimpleWords;
    envPtr->maxStackDepth = maxDepth;
    envPtr->excRangeDepth--;
    FreeArgInfo(&argInfo);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DupForeachInfo --
 *
 *	This procedure duplicates a ForeachInfo structure created as
 *	auxiliary data during the compilation of a foreach command.
 *
 * Results:
 *	A pointer to a newly allocated copy of the existing ForeachInfo
 *	structure is returned.
 *
 * Side effects:
 *	Storage for the copied ForeachInfo record is allocated. If the
 *	original ForeachInfo structure pointed to any ForeachVarList
 *	records, these structures are also copied and pointers to them
 *	are stored in the new ForeachInfo record.
 *
 *----------------------------------------------------------------------
 */

static ClientData
DupForeachInfo(clientData)
    ClientData clientData;	/* The foreach command's compilation
				 * auxiliary data to duplicate. */
{
    register ForeachInfo *srcPtr = (ForeachInfo *) clientData;
    ForeachInfo *dupPtr;
    register ForeachVarList *srcListPtr, *dupListPtr;
    int numLists = srcPtr->numLists;
    int numVars, i, j;
    
    dupPtr = (ForeachInfo *) ckalloc((unsigned)
	    (sizeof(ForeachInfo) + (numLists * sizeof(ForeachVarList *))));
    dupPtr->numLists = numLists;
    dupPtr->firstListTmp = srcPtr->firstListTmp;
    dupPtr->loopIterNumTmp = srcPtr->loopIterNumTmp;
    
    for (i = 0;  i < numLists;  i++) {
	srcListPtr = srcPtr->varLists[i];
	numVars = srcListPtr->numVars;
	dupListPtr = (ForeachVarList *) ckalloc((unsigned)
	        sizeof(ForeachVarList) + numVars*sizeof(int));
	dupListPtr->numVars = numVars;
	for (j = 0;  j < numVars;  j++) {
	    dupListPtr->varIndexes[j] =	srcListPtr->varIndexes[j];
	}
	dupPtr->varLists[i] = dupListPtr;
    }
    return (ClientData) dupPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeForeachInfo --
 *
 *	Procedure to free a ForeachInfo structure created as auxiliary data
 *	during the compilation of a foreach command.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Storage for the ForeachInfo structure pointed to by the ClientData
 *	argument is freed as is any ForeachVarList record pointed to by the
 *	ForeachInfo structure.


 *
 *----------------------------------------------------------------------
 */

static void
FreeForeachInfo(clientData)
    ClientData clientData;	/* The foreach command's compilation
				 * auxiliary data to free. */
{
    register ForeachInfo *infoPtr = (ForeachInfo *) clientData;
    register ForeachVarList *listPtr;
    int numLists = infoPtr->numLists;
    register int i;

    for (i = 0;  i < numLists;  i++) {
	listPtr = infoPtr->varLists[i];
	ckfree((char *) listPtr);
    }
    ckfree((char *) infoPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileIfCmd --
 *
 *	Procedure called to compile the "if" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while parsing string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the "if" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileIfCmd(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    register char *src = string;/* Points to current source char. */
    register int type;		/* Current char's CHAR_TYPE type. */
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute cmd. */
    JumpFixupArray jumpFalseFixupArray;
    				/* Used to fix up the ifFalse jump after
				 * each "if"/"elseif" test when its target
				 * PC is determined. */
    JumpFixupArray jumpEndFixupArray;
				/* Used to fix up the unconditional jump
				 * after each "then" command to the end of
				 * the "if" when that PC is determined. */
    char *testSrcStart;
    int jumpDist, jumpFalseDist, jumpIndex, objIndex, j, result;
    unsigned char *ifFalsePc;
    unsigned char opCode;
    int savePushSimpleWords = envPtr->pushSimpleWords;

    /*
     * Loop compiling "expr then body" clauses after an "if" or "elseif".
     */

    TclInitJumpFixupArray(&jumpFalseFixupArray);
    TclInitJumpFixupArray(&jumpEndFixupArray);
    while (1) {	
	/*
	 * At this point in the loop, we have an expression to test, either
	 * the main expression or an expression following an "elseif".
	 * The arguments after the expression must be "then" (optional) and
	 * a script to execute if the expression is true.
	 */

	AdvanceToNextWord(src, envPtr);
	src += envPtr->termOffset;
	type = CHAR_TYPE(src, lastChar);
	if (type == TCL_COMMAND_END) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		    "wrong # args: no expression after \"if\" argument", -1);
	    result = TCL_ERROR;
	    goto done;
	}

	/*
	 * Compile the "if"/"elseif" test expression.
	 */
	
	testSrcStart = src;
	envPtr->pushSimpleWords = 1;
	result = CompileExprWord(interp, src, lastChar, flags, envPtr);
	if (result != TCL_OK) {
	    if (result == TCL_ERROR) {
		Tcl_AddObjErrorInfo(interp,
		        "\n    (\"if\" test expression)", -1);
	    }
	    goto done;
	}
	maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
	src += envPtr->termOffset;

	/*
	 * Emit the ifFalse jump around the "then" part if the test was
	 * false. We emit a one byte (relative) jump here, and replace it
	 * later with a four byte jump if the jump target is more than 127
	 * bytes away. 
	 */

	if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) {
	    TclExpandJumpFixupArray(&jumpFalseFixupArray);
	}
	jumpIndex = jumpFalseFixupArray.next;
	jumpFalseFixupArray.next++;
	TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,
		&(jumpFalseFixupArray.fixup[jumpIndex]));
	
	/*
	 * Skip over the optional "then" before the then clause.
	 */

	AdvanceToNextWord(src, envPtr);
	src += envPtr->termOffset;
	type = CHAR_TYPE(src, lastChar);
	if (type == TCL_COMMAND_END) {
	    char buf[100];
	    sprintf(buf, "wrong # args: no script following \"%.20s\" argument", testSrcStart);
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
	    result = TCL_ERROR;
	    goto done;
	}
	if ((*src == 't') && (strncmp(src, "then", 4) == 0)) {
	    type = CHAR_TYPE(src+4, lastChar);
	    if ((type == TCL_SPACE) || (type == TCL_COMMAND_END)) {
		src += 4;
		AdvanceToNextWord(src, envPtr); 
		src += envPtr->termOffset;
		type = CHAR_TYPE(src, lastChar);
		if (type == TCL_COMMAND_END) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "wrong # args: no script following \"then\" argument", -1);
		    result = TCL_ERROR;
		    goto done;
		}
	    }
	}

	/*
	 * Compile the "then" command word inline.
	 */

	result = CompileCmdWordInline(interp, src, lastChar, flags, envPtr);
	if (result != TCL_OK) {
	    if (result == TCL_ERROR) {
		char msg[60];
		sprintf(msg, "\n    (\"if\" then script line %d)",
		        interp->errorLine);
		Tcl_AddObjErrorInfo(interp, msg, -1);
	    }
	    goto done;
	}
	maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
	src += envPtr->termOffset;

	/*
	 * Emit an unconditional jump to the end of the "if" command. We
	 * emit a one byte jump here, and replace it later with a four byte
	 * jump if the jump target is more than 127 bytes away. Note that
	 * both the jumpFalseFixupArray and the jumpEndFixupArray are
	 * indexed by the same index, "jumpIndex".
	 */

	if (jumpEndFixupArray.next >= jumpEndFixupArray.end) {
	    TclExpandJumpFixupArray(&jumpEndFixupArray);
	}
	jumpEndFixupArray.next++;
	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
		&(jumpEndFixupArray.fixup[jumpIndex]));

 	/*
	 * Now that we know the target of the jumpFalse after the if test,
         * update it with the correct distance. We generate a four byte
	 * jump if the distance is greater than 120 bytes. This is
	 * conservative, and ensures that we won't have to replace this
	 * jump if we later also need to replace the preceeding
	 * unconditional jump to the end of the "if" with a four-byte jump.
         */

	jumpDist = (TclCurrCodeOffset() - jumpFalseFixupArray.fixup[jumpIndex].codeOffset);
	if (TclFixupForwardJump(envPtr,
	        &(jumpFalseFixupArray.fixup[jumpIndex]), jumpDist, 120)) {
	    /*
	     * Adjust the code offset for the unconditional jump at the end
	     * of the last "then" clause.
	     */

	    jumpEndFixupArray.fixup[jumpIndex].codeOffset += 3;
	}

	/*
	 * Check now for a "elseif" word. If we find one, keep looping.
	 */

	AdvanceToNextWord(src, envPtr);
	src += envPtr->termOffset;
	type = CHAR_TYPE(src, lastChar);
	if ((type != TCL_COMMAND_END)
	        && ((*src == 'e') && (strncmp(src, "elseif", 6) == 0))) {
	    type = CHAR_TYPE(src+6, lastChar);
	    if ((type == TCL_SPACE) || (type == TCL_COMMAND_END)) {
		src += 6;
		AdvanceToNextWord(src, envPtr); 
		src += envPtr->termOffset;
		type = CHAR_TYPE(src, lastChar);
		if (type == TCL_COMMAND_END) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "wrong # args: no expression after \"elseif\" argument", -1);
		    result = TCL_ERROR;
		    goto done;
		}
		continue;	  /* continue the "expr then body" loop */
	    }
	}
	break;
    } /* end of the "expr then body" loop */

    /*
     * No more "elseif expr then body" clauses. Check now for an "else"
     * clause. If there is another word, we are at its start.
     */

    if (type != TCL_COMMAND_END) {
	if ((*src == 'e') && (strncmp(src, "else", 4) == 0)) {
	    type = CHAR_TYPE(src+4, lastChar);
	    if ((type == TCL_SPACE) || (type == TCL_COMMAND_END)) {
		src += 4;
		AdvanceToNextWord(src, envPtr); 
		src += envPtr->termOffset;
		type = CHAR_TYPE(src, lastChar);
		if (type == TCL_COMMAND_END) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "wrong # args: no script following \"else\" argument", -1);
		    result = TCL_ERROR;
		    goto done;
		}
	    }
	}

	/*
	 * Compile the "else" command word inline.
	 */

	result = CompileCmdWordInline(interp, src, lastChar, flags, envPtr);
	if (result != TCL_OK) {
	    if (result == TCL_ERROR) {
		char msg[60];
		sprintf(msg, "\n    (\"if\" else script line %d)",
		        interp->errorLine);
		Tcl_AddObjErrorInfo(interp, msg, -1);
	    }
	    goto done;
	}
	maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
	src += envPtr->termOffset;
    
	/*
	 * Skip over white space until the end of the command.
	 */
	
	type = CHAR_TYPE(src, lastChar);
	if (type != TCL_COMMAND_END) {
	    AdvanceToNextWord(src, envPtr);
	    src += envPtr->termOffset;
	    type = CHAR_TYPE(src, lastChar);
	    if (type != TCL_COMMAND_END) {
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "wrong # args: extra words after \"else\" clause in \"if\" command", -1);
		result = TCL_ERROR;
		goto done;
	    }
	}
    } else {
	/*
	 * The "if" command has no "else" clause: push an empty string
	 * object as its result.
	 */

	objIndex = TclObjIndexForString("", 0, /*allocStrRep*/ 0,
		/*inHeap*/ 0, envPtr);
	TclEmitPush(objIndex, envPtr);
	maxDepth = TclMax(1, maxDepth);
    }

    /*
     * Now that we know the target of the unconditional jumps to the end of
     * the "if" command, update them with the correct distance. If the
     * distance is too great (> 127 bytes), replace the jump with a four
     * byte instruction and move instructions after the jump down.
     */
    
    for (j = jumpEndFixupArray.next;  j > 0;  j--) {
	jumpIndex = (j - 1);	/* i.e. process the closest jump first */
	jumpDist = (TclCurrCodeOffset() - jumpEndFixupArray.fixup[jumpIndex].codeOffset);
	if (TclFixupForwardJump(envPtr,
	        &(jumpEndFixupArray.fixup[jumpIndex]), jumpDist, 127)) {
	    /*
	     * Adjust the jump distance for the "ifFalse" jump that
	     * immediately preceeds this jump. We've moved it's target
	     * (just after this unconditional jump) three bytes down.
	     */

	    ifFalsePc = (envPtr->codeStart + jumpFalseFixupArray.fixup[jumpIndex].codeOffset);
	    opCode = *ifFalsePc;
	    if (opCode == INST_JUMP_FALSE1) {
		jumpFalseDist = TclGetInt1AtPtr(ifFalsePc + 1);
		jumpFalseDist += 3;
		TclStoreInt1AtPtr(jumpFalseDist, (ifFalsePc + 1));
	    } else if (opCode == INST_JUMP_FALSE4) {
		jumpFalseDist = TclGetInt4AtPtr(ifFalsePc + 1);
		jumpFalseDist += 3;
		TclStoreInt4AtPtr(jumpFalseDist, (ifFalsePc + 1));
	    } else {
		panic("TclCompileIfCmd: unexpected opcode updating ifFalse jump");
	    }
	}
    }
	
    /*
     * Free the jumpFixupArray array if malloc'ed storage was used.
     */

    done:
    TclFreeJumpFixupArray(&jumpFalseFixupArray);
    TclFreeJumpFixupArray(&jumpEndFixupArray);
    envPtr->termOffset = (src - string);
    envPtr->maxStackDepth = maxDepth;
    envPtr->pushSimpleWords = savePushSimpleWords;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileIncrCmd --
 *
 *	Procedure called to compile the "incr" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while parsing string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the "incr" command.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the "incr" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileIncrCmd(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Proc *procPtr = envPtr->procPtr;
    				/* Points to structure describing procedure
				 * containing incr command, else NULL. */
    register char *src = string;
    				/* Points to current source char. */
    register int type;		/* Current char's CHAR_TYPE type. */
    int simpleVarName;		/* 1 if name is just sequence of chars with
                                 * an optional element name in parens. */
    char *name = NULL;		/* If simpleVarName, points to first char of
				 * variable name and nameChars is length.
				 * Otherwise NULL. */
    char *elName = NULL;	/* If simpleVarName, points to first char of
				 * element name and elNameChars is length.
				 * Otherwise NULL. */
    int nameChars = 0;		/* Length of the var name. Initialized to
				 * avoid a compiler warning. */
    int elNameChars = 0;	/* Length of array's element name, if any.
				 * Initialized to avoid a compiler
				 * warning. */
    int incrementGiven;		/* 1 if an increment amount was given. */
    int isImmIncrValue = 0;	/* 1 if increment amount is a literal
				 * integer in [-127..127]. */
    int immIncrValue = 0;	/* if isImmIncrValue is 1, the immediate
				 * integer value. */
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute cmd. */
    int localIndex = -1;	/* Index of the variable in the current
				 * procedure's array of local variables.
				 * Otherwise -1 if not in a procedure or
				 * the variable wasn't found. */
    char savedChar;		/* Holds the character from string
				 * termporarily replaced by a null char
				 * during name processing. */
    int objIndex;		/* The object array index for a pushed
				 * object holding a name part. */
    int savePushSimpleWords = envPtr->pushSimpleWords;
    char *p;
    int i, result;

    /*
     * Parse the next word: the variable name. If it is "simple" (requires
     * no substitutions at runtime), divide it up into a simple "name" plus
     * an optional "elName". Otherwise, if not simple, just push the name.
     */

    AdvanceToNextWord(src, envPtr);
    src += envPtr->termOffset;
    type = CHAR_TYPE(src, lastChar);
    if (type == TCL_COMMAND_END) {
	badArgs:
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"incr varName ?increment?\"", -1);
	result = TCL_ERROR;
	goto done;
    }
    
    envPtr->pushSimpleWords = 0;
    result = CompileWord(interp, src, lastChar, flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    simpleVarName = envPtr->wordIsSimple;
    if (simpleVarName) {
	name = src;
	nameChars = envPtr->numSimpleWordChars;
	if (type & (TCL_QUOTE | TCL_OPEN_BRACE)) {
	    name++;
	}
	elName = NULL;
	elNameChars = 0;
	p = name;
	for (i = 0;  i < nameChars;  i++) {
	    if (*p == '(') {
		char *openParen = p;
		p = (src + nameChars-1);	
		if (*p == ')') { /* last char is ')' => array reference */
		    nameChars = (openParen - name);
		    elName = openParen+1;
		    elNameChars = (p - elName);
		}
		break;
	    }
	    p++;
	}
    } else {
        maxDepth = envPtr->maxStackDepth;
    }
    src += envPtr->termOffset;

    /*
     * See if there is a next word. If so, we are incrementing the variable
     * by that value (which must be an integer).
     */

    incrementGiven = 0;
    type = CHAR_TYPE(src, lastChar);
    if (type != TCL_COMMAND_END) {
	AdvanceToNextWord(src, envPtr);
	src += envPtr->termOffset;
	type = CHAR_TYPE(src, lastChar);
	incrementGiven = (type != TCL_COMMAND_END);
    }

    /*
     * Non-simple names have already been pushed. If this is a simple
     * variable, either push its name (if a global or an unknown local
     * variable) or look up the variable's local frame index. If a local is
     * not found, push its name and do the lookup at runtime. If this is an
     * array reference, also push the array element.
     */

    if (simpleVarName) {
	if (procPtr == NULL) {
	    savedChar = name[nameChars];
	    name[nameChars] = '\0';
	    objIndex = TclObjIndexForString(name, nameChars,
		    /*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
	    name[nameChars] = savedChar;
	    TclEmitPush(objIndex, envPtr);
	    maxDepth = 1;
	} else {
	    localIndex = LookupCompiledLocal(name, nameChars,
	            /*createIfNew*/ 0, /*flagsIfCreated*/ 0,
		    envPtr->procPtr);
	    if ((localIndex < 0) || (localIndex > 255)) {
		if (localIndex > 255) {	      /* we'll push the name */
		    localIndex = -1;
		}
		savedChar = name[nameChars];
		name[nameChars] = '\0';
		objIndex = TclObjIndexForString(name, nameChars,
			/*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
		name[nameChars] = savedChar;
		TclEmitPush(objIndex, envPtr);
		maxDepth = 1;
	    } else {
		maxDepth = 0;
	    }
	}
	
	if (elName != NULL) {
	    /*
	     * Parse and push the array element's name. Perform
	     * substitutions on it, just as is done for quoted strings.
	     */

	    savedChar = elName[elNameChars];
	    elName[elNameChars] = '\0';
	    envPtr->pushSimpleWords = 1;
	    result = TclCompileQuotes(interp, elName, elName+elNameChars,
		    0, flags, envPtr);
	    elName[elNameChars] = savedChar;
	    if (result != TCL_OK) {
		char msg[200];
		sprintf(msg, "\n    (parsing index for array \"%.*s\")",
			TclMin(nameChars, 100), name);
		Tcl_AddObjErrorInfo(interp, msg, -1);
		goto done;
	    }
	    maxDepth += envPtr->maxStackDepth;
	}
    }

    /*
     * If an increment was given, push the new value.
     */
    
    if (incrementGiven) {
	type = CHAR_TYPE(src, lastChar);
	envPtr->pushSimpleWords = 0;
	result = CompileWord(interp, src, lastChar, flags, envPtr);
	if (result != TCL_OK) {
	    if (result == TCL_ERROR) {
		Tcl_AddObjErrorInfo(interp,
		        "\n    (increment expression)", -1);
	    }
	    goto done;
	}
	if (type & (TCL_QUOTE | TCL_OPEN_BRACE)) {
	    src++;
	}
	if (envPtr->wordIsSimple) {
	    /*
	     * See if the word represents an integer whose formatted
	     * representation is the same as the word (e.g., this is
	     * true for 123 and -1 but not for 00005). If so, just
	     * push an integer object.
	     */
	    
	    int isCompilableInt = 0;
	    int numChars = envPtr->numSimpleWordChars;
	    char savedChar = src[numChars];
	    char buf[40];
	    Tcl_Obj *objPtr;
	    long n;

	    src[numChars] = '\0';
	    if (TclLooksLikeInt(src)) {
		int code = TclGetLong(interp, src, &n);
		if (code == TCL_OK) {
		    if ((-127 <= n) && (n <= 127)) {
			isCompilableInt = 1;
			isImmIncrValue = 1;
			immIncrValue = n;
		    } else {
			TclFormatInt(buf, n);
			if (strcmp(src, buf) == 0) {
			    isCompilableInt = 1;
			    isImmIncrValue = 0;
			    objIndex = TclObjIndexForString(src, numChars,
                                /*allocStrRep*/ 0, /*inHeap*/ 0, envPtr);
			    objPtr = envPtr->objArrayPtr[objIndex];

			    Tcl_InvalidateStringRep(objPtr);
			    objPtr->internalRep.longValue = n;
			    objPtr->typePtr = &tclIntType;
			    
			    TclEmitPush(objIndex, envPtr);
			    maxDepth += 1;
			}
		    }
		} else {
		    Tcl_ResetResult(interp);
		}
	    }
	    if (!isCompilableInt) {
		objIndex = TclObjIndexForString(src, numChars,
			/*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
		TclEmitPush(objIndex, envPtr);
		maxDepth += 1;
	    }
	    src[numChars] = savedChar;
	} else {
	    maxDepth += envPtr->maxStackDepth;
	}
	if (type & (TCL_QUOTE | TCL_OPEN_BRACE)) {
	    src += (envPtr->termOffset - 1); /* already advanced 1 above */
	} else {
	    src += envPtr->termOffset;
	}
    } else {			/* no incr amount given so use 1 */
	isImmIncrValue = 1;
	immIncrValue = 1;
    }
    
    /*
     * Now emit instructions to increment the variable.
     */

    if (simpleVarName) {
	if (elName == NULL) {  /* scalar */
	    if (localIndex >= 0) {
		if (isImmIncrValue) {
		    TclEmitInstUInt1(INST_INCR_SCALAR1_IMM, localIndex,
				    envPtr);
		    TclEmitInt1(immIncrValue, envPtr);
		} else {
		    TclEmitInstUInt1(INST_INCR_SCALAR1, localIndex, envPtr);
		}
	    } else {
		if (isImmIncrValue) {
		    TclEmitInstInt1(INST_INCR_SCALAR_STK_IMM, immIncrValue,
				   envPtr);
		} else {
		    TclEmitOpcode(INST_INCR_SCALAR_STK, envPtr);
		}
	    }
	} else {		/* array */
	    if (localIndex >= 0) {
		if (isImmIncrValue) {
		    TclEmitInstUInt1(INST_INCR_ARRAY1_IMM, localIndex,
				    envPtr);
		    TclEmitInt1(immIncrValue, envPtr);
		} else {
		    TclEmitInstUInt1(INST_INCR_ARRAY1, localIndex, envPtr);
		}
	    } else {
		if (isImmIncrValue) {
		    TclEmitInstInt1(INST_INCR_ARRAY_STK_IMM, immIncrValue,
				   envPtr);
		} else {
		    TclEmitOpcode(INST_INCR_ARRAY_STK, envPtr);
		}
	    }
	}
    } else {			/* non-simple variable name */
	if (isImmIncrValue) {
	    TclEmitInstInt1(INST_INCR_STK_IMM, immIncrValue, envPtr);
	} else {
	    TclEmitOpcode(INST_INCR_STK, envPtr);
	}
    }
	
    /*
     * Skip over white space until the end of the command.
     */

    type = CHAR_TYPE(src, lastChar);
    if (type != TCL_COMMAND_END) {
	AdvanceToNextWord(src, envPtr);
	src += envPtr->termOffset;
	type = CHAR_TYPE(src, lastChar);
	if (type != TCL_COMMAND_END) {
	    goto badArgs;
	}
    }

    done:
    envPtr->termOffset = (src - string);
    envPtr->maxStackDepth = maxDepth;
    envPtr->pushSimpleWords = savePushSimpleWords;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileSetCmd --
 *
 *	Procedure called to compile the "set" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is normally TCL_OK
 *	unless there was an error while parsing string. If an error occurs
 *	then the interpreter's result contains a standard error message. If
 *	complation fails because the set command requires a second level of
 *	substitutions, TCL_OUT_LINE_COMPILE is returned indicating that the
 *	set command should be compiled "out of line" by emitting code to
 *	invoke its command procedure (Tcl_SetCmd) at runtime.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the incr command.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the "set" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileSetCmd(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Proc *procPtr = envPtr->procPtr;
				/* Points to structure describing procedure
				 * containing the set command, else NULL. */
    ArgInfo argInfo;		/* Structure holding information about the
				 * start and end of each argument word. */
    int simpleVarName;		/* 1 if name is just sequence of chars with
                                 * an optional element name in parens. */
    char *elName = NULL;	/* If simpleVarName, points to first char of
				 * element name and elNameChars is length.
				 * Otherwise NULL. */
    int isAssignment;		/* 1 if assigning value to var, else 0. */
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute cmd. */
    int localIndex = -1;	/* Index of the variable in the current
				 * procedure's array of local variables.
				 * Otherwise -1 if not in a procedure, the
				 * name contains "::"s, or the variable
				 * wasn't found. */
    char savedChar;		/* Holds the character from string
				 * termporarily replaced by a null char
				 * during name processing. */
    int objIndex = -1;		/* The object array index for a pushed
				 * object holding a name part. Initialized
				 * to avoid a compiler warning. */
    char *wordStart, *p;
    int numWords, isCompilableInt, i, result;
    Tcl_Obj *objPtr;
    int savePushSimpleWords = envPtr->pushSimpleWords;

    /*
     * Scan the words of the command and record the start and finish of
     * each argument word.
     */

    InitArgInfo(&argInfo);
    result = CollectArgInfo(interp, string, lastChar, flags, &argInfo);
    numWords = argInfo.numArgs;	  /* i.e., the # after the command name */
    if (result != TCL_OK) {
	goto done;
    }
    if ((numWords < 1) || (numWords > 2)) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"set varName ?newValue?\"", -1);
        result = TCL_ERROR;
	goto done;
    }
    isAssignment = (numWords == 2);

    /*
     * Parse the next word: the variable name. If the name is enclosed in
     * quotes or braces, we return TCL_OUT_LINE_COMPILE and call the set
     * command procedure at runtime since this makes sure that a second
     * round of substitutions is done properly. 
     */

    wordStart = argInfo.startArray[0]; /* start of 1st arg word: varname */
    if ((*wordStart == '{') || (*wordStart == '"')) {
	result = TCL_OUT_LINE_COMPILE;
	goto done;
    }

    /*
     * Check whether the name is "simple": requires no substitutions at
     * runtime.
     */
    
    envPtr->pushSimpleWords = 0;
    result = CompileWord(interp, wordStart, argInfo.endArray[0] + 1,
	    flags, envPtr);
    if (result != TCL_OK) {
	goto done;
    }
    simpleVarName = envPtr->wordIsSimple;
    
    if (!simpleVarName) {
	/*
	 * The name isn't simple. CompileWord already pushed it.
	 */
	
	maxDepth = envPtr->maxStackDepth;
    } else {
	char *name;		/* If simpleVarName, points to first char of
				 * variable name and nameChars is length.
				 * Otherwise NULL. */
	int nameChars;		/* Length of the var name. */
	int nameHasNsSeparators = 0;
				/* Set 1 if name contains "::"s. */
	int elNameChars;	/* Length of array's element name if any. */

	/*
	 * A simple name. First divide it up into "name" plus "elName"
	 * for an array element name, if any.
	 */
	
	name = wordStart;
	nameChars = envPtr->numSimpleWordChars;
	elName = NULL;
	elNameChars = 0;
	
	p = name;
	for (i = 0;  i < nameChars;  i++) {
	    if (*p == '(') {
		char *openParen = p;
		p = (name + nameChars-1);	
		if (*p == ')') { /* last char is ')' => array reference */
		    nameChars = (openParen - name);
		    elName = openParen+1;
		    elNameChars = (p - elName);
		}
		break;
	    }
	    p++;
	}

	/*
	 * Determine if name has any namespace separators (::'s).
	 */

	p = name;
	for (i = 0;  i < nameChars;  i++) {
	    if ((*p == ':') && ((i+1) < nameChars) && (*(p+1) == ':')) {
		nameHasNsSeparators = 1;
		break;
	    }
	    p++;
	}

	/*
	 * Now either push the name or determine its index in the array of
	 * local variables in a procedure frame. Note that if we are
	 * compiling a procedure the variable must be local unless its
	 * name has namespace separators ("::"s). Note also that global
	 * variables are implemented by a local variable that "points" to
	 * the real global. There are two cases:
	 *   1) We are not compiling a procedure body. Push the global
	 *      variable's name and do the lookup at runtime.
	 *   2) We are compiling a procedure and the name has "::"s.
	 *	Push the namespace variable's name and do the lookup at
	 *	runtime.
	 *   3) We are compiling a procedure and the name has no "::"s.
	 *	If the variable has already been allocated an local index,
	 *	just look it up. If the variable is unknown and we are
	 *	doing an assignment, allocate a new index. Otherwise,
	 *	push the name and try to do the lookup at runtime.
	 */

	if ((procPtr == NULL) || nameHasNsSeparators) {
	    savedChar = name[nameChars];
	    name[nameChars] = '\0';
	    objIndex = TclObjIndexForString(name, nameChars,
		    /*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
	    name[nameChars] = savedChar;
	    TclEmitPush(objIndex, envPtr);
	    maxDepth = 1;
	} else {
	    localIndex = LookupCompiledLocal(name, nameChars,
	            /*createIfNew*/ isAssignment,
                    /*flagsIfCreated*/
			((elName == NULL)? VAR_SCALAR : VAR_ARRAY),
		    envPtr->procPtr);
	    if (localIndex >= 0) {
		maxDepth = 0;
	    } else {
		savedChar = name[nameChars];
		name[nameChars] = '\0';
		objIndex = TclObjIndexForString(name, nameChars,
			/*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
		name[nameChars] = savedChar;
		TclEmitPush(objIndex, envPtr);
		maxDepth = 1;
	    }
	}

	/*
	 * If we are dealing with a reference to an array element, push the
	 * array element. Perform substitutions on it, just as is done
	 * for quoted strings.
	 */
	
	if (elName != NULL) {
	    savedChar = elName[elNameChars];
	    elName[elNameChars] = '\0';
	    envPtr->pushSimpleWords = 1;
	    result = TclCompileQuotes(interp, elName, elName+elNameChars,
		    0, flags, envPtr);
	    elName[elNameChars] = savedChar;
	    if (result != TCL_OK) {
		char msg[200];
		sprintf(msg, "\n    (parsing index for array \"%.*s\")",
			TclMin(nameChars, 100), name);
		Tcl_AddObjErrorInfo(interp, msg, -1);
		goto done;
	    }
	    maxDepth += envPtr->maxStackDepth;
	}
    }

    /*
     * If we are doing an assignment, push the new value.
     */
    
    if (isAssignment) {
	wordStart = argInfo.startArray[1]; /* start of 2nd arg word */
	envPtr->pushSimpleWords = 0;       /* we will handle simple words */
	result = CompileWord(interp, wordStart,	argInfo.endArray[1] + 1,
		flags, envPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	if (!envPtr->wordIsSimple) {
	    /*
	     * The value isn't simple. CompileWord already pushed it.
	     */

	    maxDepth += envPtr->maxStackDepth;
	} else {
	    /*
	     * The value is simple. See if the word represents an integer
	     * whose formatted representation is the same as the word (e.g.,
	     * this is true for 123 and -1 but not for 00005). If so, just
	     * push an integer object.
	     */
	    
	    char buf[40];
	    long n;

	    p = wordStart;
	    if ((*wordStart == '"') || (*wordStart == '{')) {
		p++;
	    }
	    savedChar = p[envPtr->numSimpleWordChars];
	    p[envPtr->numSimpleWordChars] = '\0';
	    isCompilableInt = 0;
	    if (TclLooksLikeInt(p)) {
		int code = TclGetLong(interp, p, &n);
		if (code == TCL_OK) {
		    TclFormatInt(buf, n);
		    if (strcmp(p, buf) == 0) {
			isCompilableInt = 1;
			objIndex = TclObjIndexForString(p,
				envPtr->numSimpleWordChars,
                                /*allocStrRep*/ 0, /*inHeap*/ 0, envPtr);
			objPtr = envPtr->objArrayPtr[objIndex];

			Tcl_InvalidateStringRep(objPtr);
			objPtr->internalRep.longValue = n;
			objPtr->typePtr = &tclIntType;
		    }
		} else {
		    Tcl_ResetResult(interp);
		}
	    }
	    if (!isCompilableInt) {
		objIndex = TclObjIndexForString(p,
			envPtr->numSimpleWordChars, /*allocStrRep*/ 1,
			/*inHeap*/ 0, envPtr);
	    }
	    p[envPtr->numSimpleWordChars] = savedChar;
	    TclEmitPush(objIndex, envPtr);
	    maxDepth += 1;
	}
    }
    
    /*
     * Now emit instructions to set/retrieve the variable.
     */

    if (simpleVarName) {
	if (elName == NULL) {  /* scalar */
	    if (localIndex >= 0) {
		if (localIndex <= 255) {
		    TclEmitInstUInt1((isAssignment?
			     INST_STORE_SCALAR1 : INST_LOAD_SCALAR1),
			localIndex, envPtr);
		} else {
		    TclEmitInstUInt4((isAssignment?
			     INST_STORE_SCALAR4 : INST_LOAD_SCALAR4),
			localIndex, envPtr);
		}
	    } else {
		TclEmitOpcode((isAssignment?
			     INST_STORE_SCALAR_STK : INST_LOAD_SCALAR_STK),
			    envPtr);
	    }
	} else {		/* array */
	    if (localIndex >= 0) {
		if (localIndex <= 255) {
		    TclEmitInstUInt1((isAssignment?
			     INST_STORE_ARRAY1 : INST_LOAD_ARRAY1),
			localIndex, envPtr);
		} else {
		    TclEmitInstUInt4((isAssignment?
			     INST_STORE_ARRAY4 : INST_LOAD_ARRAY4),
			localIndex, envPtr);
		}
	    } else {
		TclEmitOpcode((isAssignment?
			     INST_STORE_ARRAY_STK : INST_LOAD_ARRAY_STK),
			    envPtr);
	    }
	}
    } else {			/* non-simple variable name */
	TclEmitOpcode((isAssignment? INST_STORE_STK : INST_LOAD_STK), envPtr);
    }
	
    done:
    if (numWords == 0) {
	envPtr->termOffset = 0;
    } else {
	envPtr->termOffset = (argInfo.endArray[numWords-1] + 1 - string);
    }
    envPtr->pushSimpleWords = savePushSimpleWords;
    envPtr->maxStackDepth = maxDepth;
    FreeArgInfo(&argInfo);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCompileWhileCmd --
 *
 *	Procedure called to compile the "while" command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK if
 *	compilation was successful. If an error occurs then the
 *	interpreter's result contains a standard error message and TCL_ERROR
 *	is returned. If compilation failed because the command is too
 *	complex for TclCompileWhileCmd, TCL_OUT_LINE_COMPILE is returned
 *	indicating that the while command should be compiled "out of line"
 *	by emitting code to invoke its command procedure at runtime.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the "while" command.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the "while" command
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

int
TclCompileWhileCmd(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		 /* Pointer to terminating character of
				  * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    register char *src = string;/* Points to current source char. */
    register int type;		/* Current char's CHAR_TYPE type. */
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute cmd. */
    int range;			/* Index in the ExceptionRange array of the
				 * ExceptionRange record for this loop. */
    JumpFixup jumpFalseFixup;	/* Used to update or replace the ifFalse
				 * jump after test when its target PC is
				 * determined. */
    unsigned char *jumpPc;
    int jumpDist, jumpBackDist, jumpBackOffset, objIndex, result;
    int savePushSimpleWords = envPtr->pushSimpleWords;

    envPtr->excRangeDepth++;
    envPtr->maxExcRangeDepth =
	TclMax(envPtr->excRangeDepth, envPtr->maxExcRangeDepth);

    /*
     * Create and initialize a ExceptionRange record to hold information
     * about this loop. This is used to implement break and continue.
     */

    range = CreateExceptionRange(LOOP_EXCEPTION_RANGE, envPtr);
    envPtr->excRangeArrayPtr[range].continueOffset = TclCurrCodeOffset();

    AdvanceToNextWord(src, envPtr);
    src += envPtr->termOffset;
    type = CHAR_TYPE(src, lastChar);
    if (type == TCL_COMMAND_END) {
	badArgs:
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "wrong # args: should be \"while test command\"", -1);
	result = TCL_ERROR;
	goto done;
    }

    /*
     * If the test expression is enclosed in quotes (""s), don't compile
     * the while inline. As a result of Tcl's two level substitution
     * semantics for expressions, the expression might have a constant
     * value that results in the loop never executing, or executing forever.
     * Consider "set x 0; while "$x < 5" {incr x}": the loop body should
     * never be executed.
     */

    if (*src == '"') {
	result = TCL_OUT_LINE_COMPILE;
        goto done;
    }

    /*
     * Compile the next word: the test expression.
     */

    envPtr->pushSimpleWords = 1;
    result = CompileExprWord(interp, src, lastChar, flags, envPtr);
    if (result != TCL_OK) {
	if (result == TCL_ERROR) {
            Tcl_AddObjErrorInfo(interp, "\n    (\"while\" test expression)", -1);
        }
	goto done;
    }
    maxDepth = envPtr->maxStackDepth;
    src += envPtr->termOffset;

    /*
     * Emit the ifFalse jump that terminates the while if the test was
     * false. We emit a one byte (relative) jump here, and replace it
     * later with a four byte jump if the jump target is more than
     * 127 bytes away.
     */

    TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFalseFixup);
    
    /*
     * Compile the loop body word inline. Also register the loop body's
     * starting PC offset and byte length in the its ExceptionRange record.
     */

    AdvanceToNextWord(src, envPtr);
    src += envPtr->termOffset;
    type = CHAR_TYPE(src, lastChar);
    if (type == TCL_COMMAND_END) {
	goto badArgs;
    }

    envPtr->excRangeArrayPtr[range].codeOffset = TclCurrCodeOffset();
    result = CompileCmdWordInline(interp, src, lastChar,
	    flags, envPtr);
    if (result != TCL_OK) {
	if (result == TCL_ERROR) {
	    char msg[60];
	    sprintf(msg, "\n    (\"while\" body line %d)", interp->errorLine);
            Tcl_AddObjErrorInfo(interp, msg, -1);
        }
	goto done;
    }
    maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
    src += envPtr->termOffset;
    envPtr->excRangeArrayPtr[range].numCodeBytes =
	(TclCurrCodeOffset() - envPtr->excRangeArrayPtr[range].codeOffset);

    /*
     * Discard the loop body's result.
     */

    TclEmitOpcode(INST_POP, envPtr);
	
    /*
     * Emit the unconditional jump back to the test at the top of the
     * loop. We generate a four byte jump if the distance to the while's
     * test is greater than 120 bytes. This is conservative, and ensures
     * that we won't have to replace this unconditional jump if we later
     * need to replace the ifFalse jump with a four-byte jump.
     */

    jumpBackOffset = TclCurrCodeOffset();
    jumpBackDist =
	(jumpBackOffset - envPtr->excRangeArrayPtr[range].continueOffset);
    if (jumpBackDist > 120) {
	TclEmitInstInt4(INST_JUMP4, /*offset*/ -jumpBackDist, envPtr);
    } else {
	TclEmitInstInt1(INST_JUMP1, /*offset*/ -jumpBackDist, envPtr);
    }

    /*
     * Now that we know the target of the jumpFalse after the test, update
     * it with the correct distance. If the distance is too great (more
     * than 127 bytes), replace that jump with a four byte instruction and
     * move the instructions after the jump down. 
     */

    jumpDist = (TclCurrCodeOffset() - jumpFalseFixup.codeOffset);
    if (TclFixupForwardJump(envPtr, &jumpFalseFixup, jumpDist, 127)) {
	/*
	 * Update the loop body's starting PC offset since it moved down.
	 */

	envPtr->excRangeArrayPtr[range].codeOffset += 3;

	/*
	 * Update the distance for the unconditional jump back to the test
	 * at the top of the loop since it moved down 3 bytes too.
	 */

	jumpBackOffset += 3;
	jumpPc = (envPtr->codeStart + jumpBackOffset);
	if (jumpBackDist > 120) {
	    jumpBackDist += 3;
	    TclUpdateInstInt4AtPc(INST_JUMP4, /*offset*/ -jumpBackDist,
				   jumpPc);
	} else {
	    jumpBackDist += 3;
	    TclUpdateInstInt1AtPc(INST_JUMP1, /*offset*/ -jumpBackDist,
				   jumpPc);
	}
    }

    /*
     * The current PC offset (after the loop's body) is the loop's
     * break target.
     */

    envPtr->excRangeArrayPtr[range].breakOffset = TclCurrCodeOffset();
    
    /*
     * Push an empty string object as the while command's result.
     */

    objIndex = TclObjIndexForString("", 0, /*allocStrRep*/ 0, /*inHeap*/ 0,
				    envPtr);
    TclEmitPush(objIndex, envPtr);
    if (maxDepth == 0) {
	maxDepth = 1;
    }

    /*
     * Skip over white space until the end of the command.
     */

    type = CHAR_TYPE(src, lastChar);
    if (type != TCL_COMMAND_END) {
	AdvanceToNextWord(src, envPtr);
	src += envPtr->termOffset;
	type = CHAR_TYPE(src, lastChar);
	if (type != TCL_COMMAND_END) {
	    goto badArgs;
	}
    }

    done:
    envPtr->termOffset = (src - string);
    envPtr->pushSimpleWords = savePushSimpleWords;
    envPtr->maxStackDepth = maxDepth;
    envPtr->excRangeDepth--;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileExprWord --
 *
 *	Procedure that compiles a Tcl expression in a command word.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while compiling string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the "expr" word.
 *
 * Side effects:
 *	Instructions are added to envPtr to evaluate the expression word
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileExprWord(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		 /* Pointer to terminating character of
				  * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    register char *src = string;/* Points to current source char. */
    register int type;          /* Current char's CHAR_TYPE type. */
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute the expression. */
    int nestedCmd = (flags & TCL_BRACKET_TERM);
				/* 1 if script being compiled is a nested
				 * command and is terminated by a ']';
				 * otherwise 0. */
    char *first, *last;		/* Points to the first and last significant
				 * characters of the word. */
    char savedChar;		/* Holds the character termporarily replaced
				 * by a null character during compilation
				 * of the expression. */
    int inlineCode;		/* 1 if inline "optimistic" code is
				 * emitted for the expression; else 0. */
    int range = -1;		/* If we inline compile an un-{}'d
				 * expression, the index for its catch range
				 * record in the ExceptionRange array.
				 * Initialized to avoid compile warning. */
    JumpFixup jumpFixup;	/* Used to emit the "success" jump after
				 * the inline expression code. */
    char *p;
    char c;
    int savePushSimpleWords = envPtr->pushSimpleWords;
    int saveExprIsJustVarRef = envPtr->exprIsJustVarRef;
    int saveExprIsComparison = envPtr->exprIsComparison;
    int numChars, result;

    /*
     * Skip over leading white space.
     */

    AdvanceToNextWord(src, envPtr);
    src += envPtr->termOffset;
    type = CHAR_TYPE(src, lastChar);
    if (type == TCL_COMMAND_END) {
	badArgs:
	Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		    "malformed expression word", -1);
	result = TCL_ERROR;
	goto done;
    }

    /*
     * If the word is enclosed in {}s, we may strip them off and safely
     * compile the expression into an inline sequence of instructions using
     * TclCompileExpr. We know these instructions will have the right Tcl7.x
     * expression semantics.
     *
     * Otherwise, if the word is not enclosed in {}s, we may need to call
     * the expr command (Tcl_ExprObjCmd) at runtime. This recompiles the
     * expression each time (typically) and so is slow. However, there are
     * some circumstances where we can still compile inline instructions
     * "optimistically" and check, during their execution, for double
     * substitutions (these appear as nonnumeric operands). We check for any
     * backslash or command substitutions. If none appear, and only variable
     * substitutions are found, we generate inline instructions.
     *
     * For now, if the expression is not enclosed in {}s, we call the expr
     * command at runtime if either command or backslash substitutions
     * appear (but not if only variable substitutions appear).
     */

    if (*src == '{') {
	/*
	 * Inline compile the expression inside {}s.
	 */
	
	first = src+1;
	src = TclWordEnd(src, lastChar, nestedCmd, NULL);
	if (*src == 0) {
	    goto badArgs;
	}
	if (*src != '}') {
	    goto badArgs;
	}
	last = (src-1);

	numChars = (last - first + 1);
	savedChar = first[numChars];
	first[numChars] = '\0';
	result = TclCompileExpr(interp, first, first+numChars,
		flags, envPtr);
	first[numChars] = savedChar;

	src++;
	maxDepth = envPtr->maxStackDepth;
    } else {
	/*
	 * No braces. If the expression is enclosed in '"'s, call the expr
	 * cmd at runtime. Otherwise, scan the word's characters looking for
	 * any '['s or (for now) '\'s. If any are found, just call expr cmd
	 * at runtime.
	 */

	first = src;
	last = TclWordEnd(first, lastChar, nestedCmd, NULL);
	if (*last == 0) {	/* word doesn't end properly. */
	    src = last;
	    goto badArgs;
	}

	inlineCode = 1;
	if ((*first == '"') && (*last == '"')) {
	    inlineCode = 0;
	} else {
	    for (p = first;  p <= last;  p++) {
		c = *p;
		if ((c == '[') || (c == '\\')) {
		    inlineCode = 0;
		    break;
		}
	    }
	}
	
	if (inlineCode) {
	    /*
	     * Inline compile the expression inside a "catch" so that a
	     * runtime error will back off to make a (slow) call on expr.
	     */

	    int startCodeOffset = (envPtr->codeNext - envPtr->codeStart);
	    int startRangeNext = envPtr->excRangeArrayNext;

	    /*
	     * Create a ExceptionRange record to hold information about
	     * the "catch" range for the expression's inline code. Also
	     * emit the instruction to mark the start of the range.
	     */

	    envPtr->excRangeDepth++;
	    envPtr->maxExcRangeDepth =
		TclMax(envPtr->excRangeDepth, envPtr->maxExcRangeDepth);
	    range = CreateExceptionRange(CATCH_EXCEPTION_RANGE, envPtr);
	    TclEmitInstUInt4(INST_BEGIN_CATCH4, range, envPtr);

	    /*
	     * Inline compile the expression.
	     */

	    envPtr->excRangeArrayPtr[range].codeOffset = TclCurrCodeOffset();
	    numChars = (last - first + 1);
	    savedChar = first[numChars];
	    first[numChars] = '\0';
	    result = TclCompileExpr(interp, first, first + numChars,
		    flags, envPtr);
	    first[numChars] = savedChar;
	    
	    envPtr->excRangeArrayPtr[range].numCodeBytes =
		TclCurrCodeOffset() - envPtr->excRangeArrayPtr[range].codeOffset;

	    if ((result != TCL_OK) || (envPtr->exprIsJustVarRef)
	            || (envPtr->exprIsComparison)) {
		/*
		 * We must call the expr command at runtime. Either there
		 * was a compilation error or the inline code might fail to
		 * give the correct 2 level substitution semantics.
		 *
		 * The latter can happen if the expression consisted of just
		 * a single variable reference or if the top-level operator
		 * in the expr is a comparison (which might operate on
		 * strings). In the latter case, the expression's code might
		 * execute (apparently) successfully but produce the wrong
		 * result. We depend on its execution failing if a second
		 * level of substitutions is required. This causes the
		 * "catch" code we generate around the inline code to back
		 * off to a call on the expr command at runtime, and this
		 * always gives the right 2 level substitution semantics.
		 *
		 * We delete the inline code by backing up the code pc and
		 * catch index. Note that if there was a compilation error,
		 * we can't report the error yet since the expression might
		 * be valid after the second round of substitutions.
		 */
		
		envPtr->codeNext = (envPtr->codeStart + startCodeOffset);
		envPtr->excRangeArrayNext = startRangeNext;
		inlineCode = 0;
	    } else {
		TclEmitOpcode(INST_END_CATCH, envPtr);
		TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
		envPtr->excRangeArrayPtr[range].catchOffset = TclCurrCodeOffset();
	    }
	}
	    
	/*
	 * Arrange to call expr at runtime with the (already substituted
	 * once) expression word on the stack.
	 */

	envPtr->pushSimpleWords = 1;
	result = CompileWord(interp, first, lastChar, flags, envPtr);
	src += envPtr->termOffset;
	maxDepth = envPtr->maxStackDepth;
	if (result == TCL_OK) {
	    TclEmitOpcode(INST_EXPR_STK, envPtr);
	}

	/*
	 * If emitting inline code for this non-{}'d expression, update
	 * the target of the jump after that inline code.
	 */

	if (inlineCode) {
	    int jumpDist = (TclCurrCodeOffset() - jumpFixup.codeOffset);
	    if (TclFixupForwardJump(envPtr, &jumpFixup, jumpDist, 127)) {
		/*
		 * Update the inline expression code's catch ExceptionRange
		 * target since it, being after the jump, also moved down.
		 */

		envPtr->excRangeArrayPtr[range].catchOffset += 3;
	    }
	}
    } /* if expression isn't in {}s */
    
    done:
    envPtr->termOffset = (src - string);
    envPtr->maxStackDepth = maxDepth;
    envPtr->pushSimpleWords = savePushSimpleWords;
    envPtr->exprIsJustVarRef = saveExprIsJustVarRef;
    envPtr->exprIsComparison = saveExprIsComparison;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * CompileCmdWordInline --
 *
 *	Procedure that compiles a Tcl command word inline. If the word is
 *	enclosed in quotes or braces, we call TclCompileString to compile it
 *	after stripping them off. Otherwise, we normally push the word's
 *	value and call eval at runtime, but if the word is just a sequence
 *	of alphanumeric characters, we emit an invoke instruction
 *	directly. This procedure assumes that string points to the start of
 *	the word to compile.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while compiling string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 *	envPtr->termOffset is filled in with the offset of the character in
 *	"string" just after the last one successfully processed.
 *
 *	envPtr->maxStackDepth is updated with the maximum number of stack
 *	elements needed to execute the command.
 *
 * Side effects:
 *	Instructions are added to envPtr to execute the command word
 *	at runtime.
 *
 *----------------------------------------------------------------------
 */

static int
CompileCmdWordInline(interp, string, lastChar, flags, envPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to compile. */
    char *lastChar;		/* Pointer to terminating character of
				 * string. */
    int flags;			/* Flags to control compilation (same as
				 * passed to Tcl_Eval). */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    Interp *iPtr = (Interp *) interp;
    register char *src = string;/* Points to current source char. */
    register int type;          /* Current char's CHAR_TYPE type. */
    int maxDepth = 0;		/* Maximum number of stack elements needed
				 * to execute cmd. */
    char *termPtr;		/* Points to char that terminated braced
				 * string. */
    char savedChar;		/* Holds the character termporarily replaced
				 * by a null character during compilation
				 * of the command. */
    int savePushSimpleWords = envPtr->pushSimpleWords;
    int objIndex;
    int result = TCL_OK;
    register char c;

    type = CHAR_TYPE(src, lastChar);
    if (type & (TCL_QUOTE | TCL_OPEN_BRACE)) {
	src++;
	envPtr->pushSimpleWords = 0;
	if (type == TCL_QUOTE) {
	    result = TclCompileQuotes(interp, src, lastChar,
		    '"', flags, envPtr);
	} else {
	    result = CompileBraces(interp, src, lastChar, flags, envPtr);
	}
	if (result != TCL_OK) {
	    goto done;
	}
	
	/*
	 * Make sure the terminating character is the end of word.


	 */
	
	termPtr = (src + envPtr->termOffset);
	c = *termPtr;
	if ((c == '\\') && (*(termPtr+1) == '\n')) {
	    /*
	     * Line is continued on next line; the backslash-newline turns
	     * into space, which terminates the word.
	     */

	} else {
	    type = CHAR_TYPE(termPtr, lastChar);
	    if ((type != TCL_SPACE) && (type != TCL_COMMAND_END)) {
		Tcl_ResetResult(interp);
		if (*(src-1) == '"') {
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
			    "extra characters after close-quote", -1);
		} else {
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "extra characters after close-brace", -1);
		}
		result = TCL_ERROR;
		goto done;
	    }
	}
	
	if (envPtr->wordIsSimple) {
	    /*
	     * A simple word enclosed in "" or {}s. Call TclCompileString to
	     * compile it inline. Add a null character after the end of the
	     * quoted or braced string: i.e., at the " or }. Turn the
	     * flag bit TCL_BRACKET_TERM off since the recursively
	     * compiled subcommand is now terminated by a null character.
	     */
	    char *closeCharPos = (termPtr - 1);
	    
	    savedChar = *closeCharPos;
	    *closeCharPos = '\0';
	    result = TclCompileString(interp, src, closeCharPos,
		    (flags & ~TCL_BRACKET_TERM), envPtr);
	    *closeCharPos = savedChar;
	    if (result != TCL_OK) {
		goto done;
	    }
	} else {
            /*
	     * The braced string contained a backslash-newline. Call eval
	     * at runtime.
	     */
	    TclEmitOpcode(INST_EVAL_STK, envPtr);
	}
	src = termPtr;
	maxDepth = envPtr->maxStackDepth;
    } else {
	/*
	 * Not a braced or quoted string. We normally push the word's
	 * value and call eval at runtime. However, if the word is just
	 * a sequence of alphanumeric characters, we call its compile
	 * procedure, if any, or otherwise just emit an invoke instruction.
	 */

	char *p = src;
	c = *p;
	while (isalnum(UCHAR(c)) || (c == '_')) {
            p++;
            c = *p;
        }
	type = CHAR_TYPE(p, lastChar);
        if ((p > src) && (type == TCL_COMMAND_END)) {
            /*
	     * Look for a compile procedure and call it. Otherwise emit an
	     * invoke instruction to call the command at runtime.


	     */

	    Tcl_Command cmd;
	    Command *cmdPtr = NULL;
	    int wasCompiled = 0;

	    savedChar = *p;
	    *p = '\0';

	    cmd = Tcl_FindCommand(interp, src, (Tcl_Namespace *) NULL,
		    /*flags*/ 0);
	    if (cmd != (Tcl_Command) NULL) {
                cmdPtr = (Command *) cmd;
            }
	    if (cmdPtr != NULL && cmdPtr->compileProc != NULL) {
		*p = savedChar;
		src = p;
		iPtr->flags &= ~(ERR_ALREADY_LOGGED | ERR_IN_PROGRESS
				 | ERROR_CODE_SET);
		result = (*(cmdPtr->compileProc))(interp, src, lastChar, flags, envPtr);
		if (result != TCL_OK) {
		    goto done;
		}
		wasCompiled = 1;
		src += envPtr->termOffset;
		maxDepth = envPtr->maxStackDepth;
	    }
	    if (!wasCompiled) {
		objIndex = TclObjIndexForString(src, p-src,
			/*allocStrRep*/ 1, /*inHeap*/ 0, envPtr);
		*p = savedChar;
		TclEmitPush(objIndex, envPtr);
		TclEmitInstUInt1(INST_INVOKE_STK1, 1, envPtr);
		src = p;
		maxDepth = 1;
	    }
        } else {
	    /*
	     * Push the word and call eval at runtime.
	     */

	    envPtr->pushSimpleWords = 1;
	    result = CompileWord(interp, src, lastChar, flags, envPtr);
	    if (result != TCL_OK) {
		goto done;
	    }
	    TclEmitOpcode(INST_EVAL_STK, envPtr);
	    src += envPtr->termOffset;
	    maxDepth = envPtr->maxStackDepth;
	}
    }

    done:
    envPtr->termOffset = (src - string);
    envPtr->maxStackDepth = maxDepth;
    envPtr->pushSimpleWords = savePushSimpleWords;
    return result;

}

/*
 *----------------------------------------------------------------------
 *
 * LookupCompiledLocal --
 *
 *	This procedure is called at compile time to look up and optionally
 *	allocate an entry ("slot") for a variable in a procedure's array of
 *	local variables. If the variable's name is NULL, a new temporary
 *	variable is always created. (Such temporary variables can only be
 *	referenced using their slot index.)
 *
 * Results:
 *	If createIfNew is 0 (false) and the name is non-NULL, then if the
 *	variable is found, the index of its entry in the procedure's array
 *	of local variables is returned; otherwise -1 is returned.
 *	If name is NULL, the index of a new temporary variable is returned.
 *	Finally, if createIfNew is 1 and name is non-NULL, the index of a
 *	new entry is returned.
 *
 * Side effects:
 *	Creates and registers a new local variable if createIfNew is 1 and
 *	the variable is unknown, or if the name is NULL.
 *
 *----------------------------------------------------------------------
 */

static int
LookupCompiledLocal(name, nameChars, createIfNew, flagsIfCreated, procPtr)
    register char *name;	/* Points to first character of the name of
				 * a scalar or array variable. If NULL, a
				 * temporary var should be created. */
    int nameChars;		/* The length of the name excluding the
				 * terminating null character. */
    int createIfNew;		/* 1 to allocate a local frame entry for the
				 * variable if it is new. */
    int flagsIfCreated;		/* Flag bits for the compiled local if
				 * created. Only VAR_SCALAR, VAR_ARRAY, and
				 * VAR_LINK make sense. */
    register Proc *procPtr;	/* Points to structure describing procedure
				 * containing the variable reference. */
{
    register CompiledLocal *localPtr;
    int localIndex = -1;
    register int i;

    /*
     * If not creating a temporary, does a local variable of the specified
     * name already exist?
     */

    if (name != NULL) {	
	int localCt = procPtr->numCompiledLocals;
	localPtr = procPtr->firstLocalPtr;
	for (i = 0;  i < localCt;  i++) {
	    if (!localPtr->isTemp) {
		char *localName = localPtr->name;
		if ((name[0] == localName[0])
	                && (nameChars == localPtr->nameLength)
	                && (strncmp(name, localName, (unsigned) nameChars) == 0)) {
		    return i;
		}
	    }
	    localPtr = localPtr->nextPtr;
	}
    }

    /*
     * Create a new variable if appropriate.
     */
    
    if (createIfNew || (name == NULL)) {
	localIndex = procPtr->numCompiledLocals;
	localPtr = (CompiledLocal *) ckalloc((unsigned) 
	        (sizeof(CompiledLocal) - sizeof(localPtr->name)
		+ nameChars+1));
	if (procPtr->firstLocalPtr == NULL) {
	    procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;
	} else {
	    procPtr->lastLocalPtr->nextPtr = localPtr;
	    procPtr->lastLocalPtr = localPtr;
	}
	localPtr->nextPtr = NULL;
	localPtr->nameLength = nameChars;
	localPtr->frameIndex = localIndex;
	localPtr->isArg  = 0;
	localPtr->isTemp = (name == NULL);
	localPtr->flags = flagsIfCreated;

	localPtr->defValuePtr = NULL;


	if (name != NULL) {
	    memcpy((VOID *) localPtr->name, (VOID *) name, (size_t) nameChars);

	}
	localPtr->name[nameChars] = '\0';
	procPtr->numCompiledLocals++;
    }
    return localIndex;
}

/*
 *----------------------------------------------------------------------
 *
 * AdvanceToNextWord --
 *
 *	This procedure is called to skip over any leading white space at the
 *	start of a word. Note that a backslash-newline is treated as a
 *	space.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Updates envPtr->termOffset with the offset of the first
 *	character in "string" that was not white space or a
 *	backslash-newline. This might be the offset of the character that
 *	ends the command: a newline, null, semicolon, or close-bracket.
 *
 *----------------------------------------------------------------------
 */

static void
AdvanceToNextWord(string, envPtr)
    char *string;		/* The source string to compile. */
    CompileEnv *envPtr;		/* Holds resulting instructions. */
{
    register char *src;		/* Points to current source char. */
    register int type;		/* Current char's CHAR_TYPE type. */
    
    src = string;
    type = CHAR_TYPE(src, src+1);
    while (type & (TCL_SPACE | TCL_BACKSLASH)) {
	if (type == TCL_BACKSLASH) {
	    if (src[1] == '\n') {
		src += 2;
	    } else {
		break;		/* exit loop; no longer white space */
	    }
	} else {
	    src++;
	}
	type = CHAR_TYPE(src, src+1);
    }
    envPtr->termOffset = (src - string);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Backslash --

 *
 *	Figure out how to handle a backslash sequence.
 *
 * Results:
 *	The return value is the character that should be substituted
 *	in place of the backslash sequence that starts at src.  If
 *	readPtr isn't NULL then it is filled in with a count of the
 *	number of characters in the backslash sequence.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char
Tcl_Backslash(src, readPtr)
    CONST char *src;		/* Points to the backslash character of
				 * a backslash sequence. */
    int *readPtr;		/* Fill in with number of characters read
				 * from src, unless NULL. */
{
    CONST char *p = src + 1;
    char result;
    int count;

    count = 2;







    switch (*p) {
	/*
         * Note: in the conversions below, use absolute values (e.g.,
         * 0xa) rather than symbolic values (e.g. \n) that get converted
         * by the compiler.  It's possible that compilers on some
         * platforms will do the symbolic conversions differently, which

         * could result in non-portable Tcl scripts.
         */

        case 'a':
            result = 0x7;
            break;
        case 'b':
            result = 0x8;
            break;
        case 'f':
            result = 0xc;
            break;
        case 'n':
            result = 0xa;
            break;
        case 'r':
            result = 0xd;
            break;
        case 't':
            result = 0x9;
            break;
        case 'v':
            result = 0xb;
            break;
        case 'x':
            if (isxdigit(UCHAR(p[1]))) {
                char *end;

                result = (char) strtoul(p+1, &end, 16);
                count = end - src;
            } else {


                count = 2;
                result = 'x';
            }
            break;
        case '\n':
            do {
                p++;
            } while ((*p == ' ') || (*p == '\t'));

            result = ' ';
            count = p - src;
            break;


        case 0:
            result = '\\';
            count = 1;
            break;
	default:
	    if (isdigit(UCHAR(*p))) {
		result = (char)(*p - '0');
		p++;
		if (!isdigit(UCHAR(*p))) {
		    break;
		}
		count = 3;
		result = (char)((result << 3) + (*p - '0'));
		p++;
		if (!isdigit(UCHAR(*p))) {
		    break;
		}
		count = 4;
		result = (char)((result << 3) + (*p - '0'));
		break;
	    }
	    result = *p;
	    count = 2;
	    break;


    }

    if (readPtr != NULL) {
	*readPtr = count;
    }
    return result;


}

/*
 *----------------------------------------------------------------------
 *
 * TclObjIndexForString --
 *
 *	Procedure to find, or if necessary create, an object in a
 *	CompileEnv's object array that has a string representation
 *	matching the argument string.
 *
 * Results:
 *	The index in the CompileEnv's object array of an object with a
 *	string representation matching the argument "string". The object is
 *	created if necessary. If inHeap is 1, then string is heap allocated
 *	and ownership of the string is passed to TclObjIndexForString;
 *	otherwise, the string is owned by the caller and must not be
 *	modified or freed by TclObjIndexForString. Typically, a caller sets
 *	inHeap 1 if string is an already heap-allocated buffer holding the
 *	result of backslash substitutions.
 *


 * Side effects:
 *	A new Tcl object will be created if no existing object matches the
 *	input string. If allocStrRep is 1 then if a new object is created,
 *	its string representation is allocated in the heap, else it is left
 *	NULL. If inHeap is 1, this procedure is given ownership of the
 * 	string: if an object is created and allocStrRep is 1 then its
 *	string representation is set directly from string, otherwise
 *	the string is freed.
 *
 *----------------------------------------------------------------------
 */

int
TclObjIndexForString(string, length, allocStrRep, inHeap, envPtr)
    register char *string;	/* Points to string for which an object is
				 * found or created in CompileEnv's object
				 * array. */
    int length;			/* Length of string. */
    int allocStrRep;		/* If 1 then the object's string rep should
				 * be allocated in the heap. */
    int inHeap;			/* If 1 then string is heap allocated and
				 * its ownership is passed to
				 * TclObjIndexForString. */
    CompileEnv *envPtr;		/* Points to the CompileEnv in whose object
				 * array an object is found or created. */

{
    register Tcl_Obj *objPtr;	/* Points to the object created for
				 * the string, if one was created. */




    int objIndex;		/* Index of matching object. */
    Tcl_HashEntry *hPtr;
    int strLength, new;
    
    /*
     * Look up the string in the code's object hashtable. If found, just
     * return the associated object array index.  Note that if the string
     * has embedded nulls, we don't create a hash table entry.  This
     * should be fixed, but we need to update hash tables, first.
     */


    strLength = strlen(string);
    if (length == -1) {
	length = strLength;
    }
    if (strLength != length) {

	hPtr = NULL;




    } else {
	hPtr = Tcl_CreateHashEntry(&envPtr->objTable, string, &new);
	if (!new) {		/* already in object table and array */

	    objIndex = (int) Tcl_GetHashValue(hPtr);
	    if (inHeap) {
		ckfree(string);
	    }
	    return objIndex;
	}
    }    

    /*
     * Create a new object holding the string, add it to the object array,
     * and register its index in the object hashtable.
     */



    objPtr = Tcl_NewObj();
    if (allocStrRep) {
	if (inHeap) {		/* use input string for obj's string rep */
	    objPtr->bytes = string;
	} else {
	    if (length > 0) {
		objPtr->bytes = ckalloc((unsigned) length + 1);
		memcpy((VOID *) objPtr->bytes, (VOID *) string,
			(size_t) length);
		objPtr->bytes[length] = '\0';
	    }
	}
	objPtr->length = length;
    } else {			/* leave the string rep NULL */
	if (inHeap) {
	    ckfree(string);
	}
    }

    if (envPtr->objArrayNext >= envPtr->objArrayEnd) {
        ExpandObjectArray(envPtr);
    }
    objIndex = envPtr->objArrayNext;
    envPtr->objArrayPtr[objIndex] = objPtr;
    Tcl_IncrRefCount(objPtr);
    envPtr->objArrayNext++;

    if (hPtr) {
	Tcl_SetHashValue(hPtr, objIndex);
    }
    return objIndex;
}

/*
 *----------------------------------------------------------------------
 *
 * TclExpandCodeArray --
 *







|
<


|
>
|
|
|
|


<
|
|



<
<
<
<
<
<
<

|
<


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

<
<
|
<
<
<
<
>
>
>

<
<
<

|

|
|
>
>

>


|

|

|
|

<

|




|



>
|
>



|
|
|
>
>






|
>
>




>



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









|








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





|
|
|
>
>





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

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

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

<
>
>

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

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





|








|
|
|
|
|
|


|





|
|



|
<
|
|
|






|











|


|
|











|
|


|







|
|
|
|
|
>

>
>

|
>

|


|





|

|
|
<





|
|
<
<




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

>
>
>
|

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

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

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

<
<
<
<
<
<
<
<
<







1520
1521
1522
1523
1524
1525
1526
1527

1528
1529
1530
1531
1532
1533
1534
1535
1536
1537

1538
1539
1540
1541
1542







1543
1544

1545
1546







1547
1548




1549


1550
1551
1552
1553


1554




1555
1556
1557
1558



1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576

1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646







































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































1647



























































































































































































































































































































































































































































































































































































































































































































































































































































1648





1649
































































































































































































































































































































































































































1650







1651


















































































































































































































































































































































































































1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666








1667


































1668


































































































































































1669


1670



1671





















































































































































































































1672
























































































































































































































































































































































































1673




1674








































































































































































































































































































































































































1675



1676




















































































































































1677














































1678









1679




























































































































































































1680













1681













1682
1683

1684
1685
1686
1687




1688


1689










1690






1691



1692

1693

1694

1695


1696
1697
1698







1699









1700





1701


1702


1703
1704
1705





















1706
1707

1708
1709
1710





1711
1712
1713




1714










1715





1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825

1826
1827
1828
1829
1830
1831
1832


1833
1834
1835
1836
1837


1838


1839
1840







1841








1842
1843
1844

1845
1846
1847
1848

1849




1850




1851
1852










1853

1854
1855
1856
1857
1858
1859
1860
1861
1862



1863
1864
1865
1866

























1867



1868
1869
1870

1871





1872
1873


1874
1875
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
				  * initialized, and whose string rep
				  * contains the source code. */
    register CompileEnv *envPtr; /* Points to the CompileEnv structure from
				  * which to create a ByteCode structure. */
{
    register ByteCode *codePtr;
    size_t codeBytes, objArrayBytes, exceptArrayBytes, cmdLocBytes;
    size_t auxDataArrayBytes, structureSize;

    register unsigned char *p;
    unsigned char *nextPtr;
    int numLitObjects = envPtr->literalArrayNext;
    Namespace *namespacePtr;
    int i;
    Interp *iPtr;

    iPtr = envPtr->iPtr;

    codeBytes = (envPtr->codeNext - envPtr->codeStart);

    objArrayBytes = (envPtr->literalArrayNext * sizeof(Tcl_Obj *));
    exceptArrayBytes = (envPtr->exceptArrayNext * sizeof(ExceptionRange));
    auxDataArrayBytes = (envPtr->auxDataArrayNext * sizeof(AuxData));
    cmdLocBytes = GetCmdLocEncodingSize(envPtr);
    







    /*
     * Compute the total number of bytes needed for this bytecode.

     */








    structureSize = sizeof(ByteCode);
    structureSize += TCL_ALIGN(codeBytes);        /* align object array */




    structureSize += TCL_ALIGN(objArrayBytes);    /* align exc range arr */


    structureSize += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */
    structureSize += auxDataArrayBytes;
    structureSize += cmdLocBytes;



    if (envPtr->iPtr->varFramePtr != NULL) {




        namespacePtr = envPtr->iPtr->varFramePtr->nsPtr;
    } else {
        namespacePtr = envPtr->iPtr->globalNsPtr;
    }



    
    p = (unsigned char *) ckalloc((size_t) structureSize);
    codePtr = (ByteCode *) p;
    codePtr->interpHandle = TclHandlePreserve(iPtr->handle);
    codePtr->compileEpoch = iPtr->compileEpoch;
    codePtr->nsPtr = namespacePtr;
    codePtr->nsEpoch = namespacePtr->resolverEpoch;
    codePtr->refCount = 1;
    codePtr->flags = 0;
    codePtr->source = envPtr->source;
    codePtr->procPtr = envPtr->procPtr;

    codePtr->numCommands = envPtr->numCommands;
    codePtr->numSrcBytes = envPtr->numSrcBytes;
    codePtr->numCodeBytes = codeBytes;
    codePtr->numLitObjects = numLitObjects;
    codePtr->numExceptRanges = envPtr->exceptArrayNext;
    codePtr->numAuxDataItems = envPtr->auxDataArrayNext;

    codePtr->numCmdLocBytes = cmdLocBytes;
    codePtr->maxExceptDepth = envPtr->maxExceptDepth;
    codePtr->maxStackDepth = envPtr->maxStackDepth;
    
    p += sizeof(ByteCode);
    codePtr->codeStart = p;
    memcpy((VOID *) p, (VOID *) envPtr->codeStart, (size_t) codeBytes);
    
    p += TCL_ALIGN(codeBytes);	      /* align object array */
    codePtr->objArrayPtr = (Tcl_Obj **) p;
    for (i = 0;  i < numLitObjects;  i++) {
	codePtr->objArrayPtr[i] = envPtr->literalArrayPtr[i].objPtr;
    }

    p += TCL_ALIGN(objArrayBytes);    /* align exception range array */
    if (exceptArrayBytes > 0) {
	codePtr->exceptArrayPtr = (ExceptionRange *) p;
	memcpy((VOID *) p, (VOID *) envPtr->exceptArrayPtr,
	        (size_t) exceptArrayBytes);
    } else {
	codePtr->exceptArrayPtr = NULL;
    }
    
    p += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */
    if (auxDataArrayBytes > 0) {
	codePtr->auxDataArrayPtr = (AuxData *) p;
	memcpy((VOID *) p, (VOID *) envPtr->auxDataArrayPtr,
	        (size_t) auxDataArrayBytes);
    } else {
	codePtr->auxDataArrayPtr = NULL;
    }

    p += auxDataArrayBytes;
    nextPtr = EncodeCmdLocMap(envPtr, codePtr, (unsigned char *) p);
#ifdef TCL_COMPILE_DEBUG
    if (((size_t)(nextPtr - p)) != cmdLocBytes) {	
	panic("TclInitByteCodeObj: encoded cmd location bytes %d != expected size %d\n", (nextPtr - p), cmdLocBytes);
    }
#endif
    
    /*
     * Record various compilation-related statistics about the new ByteCode
     * structure. Don't include overhead for statistics-related fields.
     */

#ifdef TCL_COMPILE_STATS
    codePtr->structureSize = structureSize
	    - (sizeof(size_t) + sizeof(Tcl_Time));
    TclpGetTime(&(codePtr->createTime));
    
    RecordByteCodeStats(codePtr);
#endif /* TCL_COMPILE_STATS */
    
    /*
     * Free the old internal rep then convert the object to a
     * bytecode object by making its internal rep point to the just
     * compiled ByteCode.
     */
	    
    if ((objPtr->typePtr != NULL) &&
	    (objPtr->typePtr->freeIntRepProc != NULL)) {
	(*objPtr->typePtr->freeIntRepProc)(objPtr);
    }
    objPtr->internalRep.otherValuePtr = (VOID *) codePtr;
    objPtr->typePtr = &tclByteCodeType;
}

/*
 *----------------------------------------------------------------------
 *







































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































 * LogCompilationInfo --



























































































































































































































































































































































































































































































































































































































































































































































































































































 *





 *	This procedure is invoked after an error occurs during compilation.
































































































































































































































































































































































































































 *	It adds information to the "errorInfo" variable to describe the







 *	command that was being compiled when the error occurred.


















































































































































































































































































































































































































 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information about the command is added to errorInfo and the
 *	line number stored internally in the interpreter is set.  If this
 *	is the first call to this procedure or Tcl_AddObjErrorInfo since
 *	an error occurred, then old information in errorInfo is
 *	deleted.
 *
 *----------------------------------------------------------------------
 */

static void








LogCompilationInfo(interp, script, command, length)


































    Tcl_Interp *interp;		/* Interpreter in which to log the


































































































































































				 * information. */


    char *script;		/* First character in script containing



				 * command (must be <= command). */





















































































































































































































    char *command;		/* First character in command that
























































































































































































































































































































































































				 * generated the error. */




    int length;			/* Number of bytes in command (-1 means








































































































































































































































































































































































































				 * use all bytes up to first null byte). */



{




















































































































































    char buffer[200];














































    register char *p;









    char *ellipsis = "";




























































































































































































    Interp *iPtr = (Interp *) interp;



























    if (iPtr->flags & ERR_ALREADY_LOGGED) {
	/*

	 * Someone else has already logged error information for this
	 * command; we shouldn't add anything more.
	 */





	return;


    }

















    /*



     * Compute the line number where the error occurred.

     */



    iPtr->errorLine = 1;


    for (p = script; p != command; p++) {
	if (*p == '\n') {
	    iPtr->errorLine++;







	}









    }








    /*


     * Create an error message to add to errorInfo, including up to a
     * maximum number of characters of the command.
     */






















    if (length < 0) {

	length = strlen(command);
    }
    if (length > 150) {





	length = 150;
	ellipsis = "...";
    }




    sprintf(buffer, "\n    while compiling\n\"%.*s%s\"",










	    length, command, ellipsis);





    Tcl_AddObjErrorInfo(interp, buffer, -1);
}

/*
 *----------------------------------------------------------------------
 *
 * TclFindCompiledLocal --
 *
 *	This procedure is called at compile time to look up and optionally
 *	allocate an entry ("slot") for a variable in a procedure's array of
 *	local variables. If the variable's name is NULL, a new temporary
 *	variable is always created. (Such temporary variables can only be
 *	referenced using their slot index.)
 *
 * Results:
 *	If create is 0 and the name is non-NULL, then if the variable is
 *	found, the index of its entry in the procedure's array of local
 *	variables is returned; otherwise -1 is returned. If name is NULL,
 *	the index of a new temporary variable is returned. Finally, if
 *	create is 1 and name is non-NULL, the index of a new entry is
 *	returned.
 *
 * Side effects:
 *	Creates and registers a new local variable if create is 1 and
 *	the variable is unknown, or if the name is NULL.
 *
 *----------------------------------------------------------------------
 */

int
TclFindCompiledLocal(name, nameBytes, create, flags, procPtr)
    register char *name;	/* Points to first character of the name of
				 * a scalar or array variable. If NULL, a
				 * temporary var should be created. */
    int nameBytes;		/* Number of bytes in the name. */

    int create;			/* If 1, allocate a local frame entry for
				 * the variable if it is new. */
    int flags;			/* Flag bits for the compiled local if
				 * created. Only VAR_SCALAR, VAR_ARRAY, and
				 * VAR_LINK make sense. */
    register Proc *procPtr;	/* Points to structure describing procedure
				 * containing the variable reference. */
{
    register CompiledLocal *localPtr;
    int localVar = -1;
    register int i;

    /*
     * If not creating a temporary, does a local variable of the specified
     * name already exist?
     */

    if (name != NULL) {	
	int localCt = procPtr->numCompiledLocals;
	localPtr = procPtr->firstLocalPtr;
	for (i = 0;  i < localCt;  i++) {
	    if (!TclIsVarTemporary(localPtr)) {
		char *localName = localPtr->name;
		if ((name[0] == localName[0])
	                && (nameBytes == localPtr->nameLength)
	                && (strncmp(name, localName, (unsigned) nameBytes) == 0)) {
		    return i;
		}
	    }
	    localPtr = localPtr->nextPtr;
	}
    }

    /*
     * Create a new variable if appropriate.
     */
    
    if (create || (name == NULL)) {
	localVar = procPtr->numCompiledLocals;
	localPtr = (CompiledLocal *) ckalloc((unsigned) 
	        (sizeof(CompiledLocal) - sizeof(localPtr->name)
		+ nameBytes+1));
	if (procPtr->firstLocalPtr == NULL) {
	    procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;
	} else {
	    procPtr->lastLocalPtr->nextPtr = localPtr;
	    procPtr->lastLocalPtr = localPtr;
	}
	localPtr->nextPtr = NULL;
	localPtr->nameLength = nameBytes;
	localPtr->frameIndex = localVar;
	localPtr->flags = flags;
	if (name == NULL) {
	    localPtr->flags |= VAR_TEMPORARY;
	}
	localPtr->defValuePtr = NULL;
	localPtr->resolveInfo = NULL;

	if (name != NULL) {
	    memcpy((VOID *) localPtr->name, (VOID *) name,
	            (size_t) nameBytes);
	}
	localPtr->name[nameBytes] = '\0';
	procPtr->numCompiledLocals++;
    }
    return localVar;
}

/*
 *----------------------------------------------------------------------
 *
 * TclInitCompiledLocals --
 *
 *	This routine is invoked in order to initialize the compiled
 *	locals table for a new call frame.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May invoke various name resolvers in order to determine which
 *	variables are being referenced at runtime.


 *
 *----------------------------------------------------------------------
 */

void


TclInitCompiledLocals(interp, framePtr, nsPtr)


    Tcl_Interp *interp;		/* Current interpreter. */
    CallFrame *framePtr;	/* Call frame to initialize. */







    Namespace *nsPtr;		/* Pointer to current namespace. */








{
    register CompiledLocal *localPtr;
    Interp *iPtr = (Interp*) interp;

    Tcl_ResolvedVarInfo *vinfo, *resVarInfo;
    Var *varPtr = framePtr->compiledLocals;
    Var *resolvedVarPtr;
    ResolverScheme *resPtr;

    int result;









    /*
     * Initialize the array of local variables stored in the call frame.










     * Some variables may have special resolution rules.  In that case,

     * we call their "resolver" procs to get our hands on the variable,
     * and we make the compiled local a link to the real variable.
     */

    for (localPtr = framePtr->procPtr->firstLocalPtr;
	 localPtr != NULL;
	 localPtr = localPtr->nextPtr) {

	/*



	 * Check to see if this local is affected by namespace or
	 * interp resolvers.  The resolver to use is cached for the
	 * next invocation of the procedure.
	 */





























	if (!(localPtr->flags & (VAR_ARGUMENT|VAR_TEMPORARY|VAR_RESOLVED))
		&& (nsPtr->compiledVarResProc || iPtr->resolverPtr)) {
	    resPtr = iPtr->resolverPtr;







	    if (nsPtr->compiledVarResProc) {
		result = (*nsPtr->compiledVarResProc)(nsPtr->interp,


			localPtr->name, localPtr->nameLength,
			(Tcl_Namespace *) nsPtr, &vinfo);
	    } else {
		result = TCL_CONTINUE;








	    }







	    while ((result == TCL_CONTINUE) && resPtr) {
		if (resPtr->compiledVarResProc) {

		    result = (*resPtr->compiledVarResProc)(nsPtr->interp,


			    localPtr->name, localPtr->nameLength,
			    (Tcl_Namespace *) nsPtr, &vinfo);
		}
		resPtr = resPtr->nextPtr;


	    }
	    if (result == TCL_OK) {
		localPtr->resolveInfo = vinfo;
		localPtr->flags |= VAR_RESOLVED;
	    }
	}



















	/*
	 * Now invoke the resolvers to determine the exact variables that
	 * should be used.









	 */








        resVarInfo = localPtr->resolveInfo;





        resolvedVarPtr = NULL;



        if (resVarInfo && resVarInfo->fetchProc) {
            resolvedVarPtr = (Var*) (*resVarInfo->fetchProc)(interp,
		    resVarInfo);
        }










        if (resolvedVarPtr) {
	    varPtr->name = localPtr->name; /* will be just '\0' if temp var */
	    varPtr->nsPtr = NULL;
	    varPtr->hPtr = NULL;
	    varPtr->refCount = 0;


	    varPtr->tracePtr = NULL;
	    varPtr->searchPtr = NULL;
	    varPtr->flags = 0;
            TclSetVarLink(varPtr);
            varPtr->value.linkPtr = resolvedVarPtr;
            resolvedVarPtr->refCount++;
        } else {
	    varPtr->value.objPtr = NULL;

	    varPtr->name = localPtr->name; /* will be just '\0' if temp var */
	    varPtr->nsPtr = NULL;

	    varPtr->hPtr = NULL;

	    varPtr->refCount = 0;


	    varPtr->tracePtr = NULL;




	    varPtr->searchPtr = NULL;
	    varPtr->flags = (localPtr->flags | VAR_UNDEFINED);
        }


















	varPtr++;


    }









}

/*
 *----------------------------------------------------------------------
 *
 * TclExpandCodeArray --
 *
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
{
    /*
     * envPtr->codeNext is equal to envPtr->codeEnd. The currently defined
     * code bytes are stored between envPtr->codeStart and
     * (envPtr->codeNext - 1) [inclusive].
     */
    
    size_t currBytes = TclCurrCodeOffset();
    size_t newBytes  = 2*(envPtr->codeEnd  - envPtr->codeStart);
    unsigned char *newPtr = (unsigned char *) ckalloc((unsigned) newBytes);

    /*
     * Copy from old code array to new, free old code array if needed, and
     * mark new code array as malloced.
     */
 
    memcpy((VOID *) newPtr, (VOID *) envPtr->codeStart, currBytes);
    if (envPtr->mallocedCodeArray) {
        ckfree((char *) envPtr->codeStart);
    }
    envPtr->codeStart = newPtr;
    envPtr->codeNext = (newPtr + currBytes);
    envPtr->codeEnd  = (newPtr + newBytes);
    envPtr->mallocedCodeArray = 1;
}

/*
 *----------------------------------------------------------------------
 *
 * ExpandObjectArray --
 *
 *	Procedure that uses malloc to allocate more storage for a
 *	CompileEnv's object array.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object array in *envPtr is reallocated to a new array of
 *	double the size, and if envPtr->mallocedObjArray is non-zero the
 *	old array is freed. Tcl_Obj pointers are copied from the old array
 *	to the new one.
 *
 *----------------------------------------------------------------------
 */

static void
ExpandObjectArray(envPtr)
    CompileEnv *envPtr;		/* Points to the CompileEnv whose object
				 * array must be enlarged. */
{
    /*
     * envPtr->objArrayNext is equal to envPtr->objArrayEnd. The currently
     * allocated Tcl_Obj pointers are stored between elements
     * 0 and (envPtr->objArrayNext - 1) [inclusive] in the object array
     * pointed to by objArrayPtr.
     */

    size_t currBytes = envPtr->objArrayNext * sizeof(Tcl_Obj *);
    int newElems = 2*envPtr->objArrayEnd;
    size_t newBytes = newElems * sizeof(Tcl_Obj *);
    Tcl_Obj **newPtr = (Tcl_Obj **) ckalloc((unsigned) newBytes);

    /*
     * Copy from old object array to new, free old object array if needed,
     * and mark new object array as malloced.
     */
 
    memcpy((VOID *) newPtr, (VOID *) envPtr->objArrayPtr, currBytes);
    if (envPtr->mallocedObjArray) {
	ckfree((char *) envPtr->objArrayPtr);
    }
    envPtr->objArrayPtr = (Tcl_Obj **) newPtr;
    envPtr->objArrayEnd = newElems;
    envPtr->mallocedObjArray = 1;
}

/*
 *----------------------------------------------------------------------
 *
 * EnterCmdStartData --
 *
 *	Registers the starting source and bytecode location of a







|

















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







1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980



















































1981
1982
1983
1984
1985
1986
1987
{
    /*
     * envPtr->codeNext is equal to envPtr->codeEnd. The currently defined
     * code bytes are stored between envPtr->codeStart and
     * (envPtr->codeNext - 1) [inclusive].
     */
    
    size_t currBytes = (envPtr->codeNext - envPtr->codeStart);
    size_t newBytes  = 2*(envPtr->codeEnd  - envPtr->codeStart);
    unsigned char *newPtr = (unsigned char *) ckalloc((unsigned) newBytes);

    /*
     * Copy from old code array to new, free old code array if needed, and
     * mark new code array as malloced.
     */
 
    memcpy((VOID *) newPtr, (VOID *) envPtr->codeStart, currBytes);
    if (envPtr->mallocedCodeArray) {
        ckfree((char *) envPtr->codeStart);
    }
    envPtr->codeStart = newPtr;
    envPtr->codeNext = (newPtr + currBytes);
    envPtr->codeEnd  = (newPtr + newBytes);
    envPtr->mallocedCodeArray = 1;
}




















































/*
 *----------------------------------------------------------------------
 *
 * EnterCmdStartData --
 *
 *	Registers the starting source and bytecode location of a
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
	envPtr->cmdMapPtr = (CmdLocation *) newPtr;
	envPtr->cmdMapEnd = newElems;
	envPtr->mallocedCmdMap = 1;
    }

    if (cmdIndex > 0) {
	if (codeOffset < envPtr->cmdMapPtr[cmdIndex-1].codeOffset) {
	    panic("EnterCmdStartData: cmd map table not sorted by code offset");
	}
    }

    cmdLocPtr = &(envPtr->cmdMapPtr[cmdIndex]);
    cmdLocPtr->codeOffset = codeOffset;
    cmdLocPtr->srcOffset = srcOffset;
    cmdLocPtr->numSrcChars = -1;
    cmdLocPtr->numCodeBytes = -1;
}

/*
 *----------------------------------------------------------------------
 *
 * EnterCmdExtentData --







|






|







2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
	envPtr->cmdMapPtr = (CmdLocation *) newPtr;
	envPtr->cmdMapEnd = newElems;
	envPtr->mallocedCmdMap = 1;
    }

    if (cmdIndex > 0) {
	if (codeOffset < envPtr->cmdMapPtr[cmdIndex-1].codeOffset) {
	    panic("EnterCmdStartData: cmd map not sorted by code offset");
	}
    }

    cmdLocPtr = &(envPtr->cmdMapPtr[cmdIndex]);
    cmdLocPtr->codeOffset = codeOffset;
    cmdLocPtr->srcOffset = srcOffset;
    cmdLocPtr->numSrcBytes = -1;
    cmdLocPtr->numCodeBytes = -1;
}

/*
 *----------------------------------------------------------------------
 *
 * EnterCmdExtentData --
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090

7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
 *	source and bytecode information for the command must already
 *	have been registered.
 *
 *----------------------------------------------------------------------
 */

static void
EnterCmdExtentData(envPtr, cmdIndex, numSrcChars, numCodeBytes)
    CompileEnv *envPtr;		/* Points to the compilation environment
				 * structure in which to enter command
				 * location information. */
    int cmdIndex;		/* Index of the command whose source and
				 * code length data is being set. */
    int numSrcChars;		/* Number of command source chars. */
    int numCodeBytes;		/* Offset of last byte of command code. */
{
    CmdLocation *cmdLocPtr;

    if ((cmdIndex < 0) || (cmdIndex >= envPtr->numCommands)) {
	panic("EnterCmdStartData: bad command index %d\n", cmdIndex);
    }
    
    if (cmdIndex > envPtr->cmdMapEnd) {
	panic("EnterCmdStartData: no start data registered for command with index %d\n", cmdIndex);

    }

    cmdLocPtr = &(envPtr->cmdMapPtr[cmdIndex]);
    cmdLocPtr->numSrcChars = numSrcChars;
    cmdLocPtr->numCodeBytes = numCodeBytes;
}

/*
 *----------------------------------------------------------------------
 *
 * InitArgInfo --
 *
 *	Initializes a ArgInfo structure to hold information about
 *	some number of argument words in a command.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The ArgInfo structure is initialized.
 *
 *----------------------------------------------------------------------
 */

static void
InitArgInfo(argInfoPtr)
    register ArgInfo *argInfoPtr; /* Points to the ArgInfo structure
				   * to initialize. */
{
    argInfoPtr->numArgs = 0;
    argInfoPtr->startArray = argInfoPtr->staticStartSpace;
    argInfoPtr->endArray   = argInfoPtr->staticEndSpace;
    argInfoPtr->allocArgs = ARGINFO_INIT_ENTRIES;
    argInfoPtr->mallocedArrays = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * CollectArgInfo --
 *
 *	Procedure to scan the argument words of a command and record the
 *	start and finish of each argument word in a ArgInfo structure.
 *
 * Results:
 *	The return value is a standard Tcl result, which is TCL_OK unless
 *	there was an error while scanning string. If an error occurs then
 *	the interpreter's result contains a standard error message.
 *
 * Side effects:
 *	If necessary, the argument start and end arrays in *argInfoPtr
 *	are grown and reallocated to a new arrays of double the size, and
 *	if argInfoPtr->mallocedArray is non-zero the old arrays are freed.
 *
 *----------------------------------------------------------------------
 */

static int
CollectArgInfo(interp, string, lastChar, flags, argInfoPtr)
    Tcl_Interp *interp;         /* Used for error reporting. */
    char *string;               /* The source command string to scan. */
    char *lastChar;		 /* Pointer to terminating character of
				  * string. */
    int flags;                  /* Flags to control compilation (same as
                                 * passed to Tcl_Eval). */
    register ArgInfo *argInfoPtr;
				/* Points to the ArgInfo structure in which
				 * to record the arg word information. */
{
    register char *src = string;/* Points to current source char. */
    register int type;		/* Current char's CHAR_TYPE type. */
    int nestedCmd = (flags & TCL_BRACKET_TERM);
                                /* 1 if string being scanned is a nested
				 * command and is terminated by a ']';
				 * otherwise 0. */
    int scanningArgs;           /* 1 if still scanning argument words to
				 * determine their start and end. */
    char *wordStart, *wordEnd;  /* Points to the first and last significant
				 * characters of each word. */
    CompileEnv tempCompEnv;	/* Only used to hold the termOffset field
				 * updated by AdvanceToNextWord. */
    char *prev;

    argInfoPtr->numArgs = 0;
    scanningArgs = 1;
    while (scanningArgs) {
	AdvanceToNextWord(src, &tempCompEnv);
	src += tempCompEnv.termOffset;
	type = CHAR_TYPE(src, lastChar);

	if ((type == TCL_COMMAND_END) && ((*src != ']') || nestedCmd)) {
	    break;		    /* done collecting argument words */
	} else if (*src == '"') {
	    wordStart = src;
	    src = TclWordEnd(src, lastChar, nestedCmd, NULL);
	    if (src == lastChar) {
	        badStringTermination:
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
	                "quoted string doesn't terminate properly", -1);
		return TCL_ERROR;
	    }
	    prev = (src-1);
	    if (*src == '"') {
		wordEnd = src;
		src++;
	    } else if ((*src == ';') && (*prev == '"')) {
		scanningArgs = 0;
		wordEnd = prev;
	    } else {
		goto badStringTermination;
	    }
	} else if (*src == '{') {
	    wordStart = src;
	    src = TclWordEnd(src, lastChar, nestedCmd, NULL);
	    if (src == lastChar) {
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "missing close-brace", -1);
		return TCL_ERROR;
	    }
	    prev = (src-1);
	    if (*src == '}') {
		wordEnd = src;
		src++;
	    } else if ((*src == ';') && (*prev == '}')) {
		scanningArgs = 0;
		wordEnd = prev;
	    } else {
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
	                "argument word in braces doesn't terminate properly", -1);
		return TCL_ERROR;
	    }
	} else {
	    wordStart = src;
	    src = TclWordEnd(src, lastChar, nestedCmd, NULL);
	    prev = (src-1);
	    if (src == lastChar) {
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
		        "missing close-bracket or close-brace", -1);
		return TCL_ERROR;
	    } else if (*src == ';') {
		scanningArgs = 0;
		wordEnd = prev;
	    } else {
		wordEnd = src;
		src++;
		if ((src == lastChar) || (*src == '\n')
	                || ((*src == ']') && nestedCmd)) {
		    scanningArgs = 0;
		}
	    }
	} /* end of test on each kind of word */

	if (argInfoPtr->numArgs == argInfoPtr->allocArgs) {
	    int newArgs = 2*argInfoPtr->numArgs;
	    size_t currBytes = argInfoPtr->numArgs * sizeof(char *);
	    size_t newBytes  = newArgs * sizeof(char *);
	    char **newStartArrayPtr =
		    (char **) ckalloc((unsigned) newBytes);
	    char **newEndArrayPtr =
		    (char **) ckalloc((unsigned) newBytes);
	    
	    /*
	     * Copy from the old arrays to the new, free the old arrays if
	     * needed, and mark the new arrays as malloc'ed.
	     */
	    
	    memcpy((VOID *) newStartArrayPtr,
	            (VOID *) argInfoPtr->startArray, currBytes);
	    memcpy((VOID *) newEndArrayPtr,
		    (VOID *) argInfoPtr->endArray, currBytes);
	    if (argInfoPtr->mallocedArrays) {
		ckfree((char *) argInfoPtr->startArray);
		ckfree((char *) argInfoPtr->endArray);
	    }
	    argInfoPtr->startArray = newStartArrayPtr;
	    argInfoPtr->endArray   = newEndArrayPtr;
	    argInfoPtr->allocArgs = newArgs;
	    argInfoPtr->mallocedArrays = 1;
	}
	argInfoPtr->startArray[argInfoPtr->numArgs] = wordStart;
	argInfoPtr->endArray[argInfoPtr->numArgs]   = wordEnd;
	argInfoPtr->numArgs++;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeArgInfo --
 *
 *	Free any storage allocated in a ArgInfo structure.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocated storage in the ArgInfo structure is freed.
 *
 *----------------------------------------------------------------------
 */

static void
FreeArgInfo(argInfoPtr)
    register ArgInfo *argInfoPtr; /* Points to the ArgInfo structure
				   * to free. */
{
    if (argInfoPtr->mallocedArrays) {
	ckfree((char *) argInfoPtr->startArray);
	ckfree((char *) argInfoPtr->endArray);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * CreateLoopExceptionRange --
 *
 *	Procedure that allocates and initializes a new ExceptionRange
 *	structure of the specified kind in a CompileEnv's ExceptionRange
 *	array.
 *
 * Results:
 *	Returns the index for the newly created ExceptionRange.
 *
 * Side effects:
 *	If there is not enough room in the CompileEnv's ExceptionRange
 *	array, the array in expanded: a new array of double the size is
 *	allocated, if envPtr->mallocedExcRangeArray is non-zero the old
 *	array is freed, and ExceptionRange entries are copied from the old
 *	array to the new one.
 *
 *----------------------------------------------------------------------
 */

static int
CreateExceptionRange(type, envPtr)
    ExceptionRangeType type;	/* The kind of ExceptionRange desired. */
    register CompileEnv *envPtr;/* Points to the CompileEnv for which a new
				 * loop ExceptionRange structure is to be
				 * allocated. */
{
    int index;			/* Index for the newly-allocated
				 * ExceptionRange structure. */
    register ExceptionRange *rangePtr;
    				/* Points to the new ExceptionRange
				 * structure */
    
    index = envPtr->excRangeArrayNext;
    if (index >= envPtr->excRangeArrayEnd) {
        /*
	 * Expand the ExceptionRange array. The currently allocated entries
	 * are stored between elements 0 and (envPtr->excRangeArrayNext - 1)
	 * [inclusive].
	 */
	
	size_t currBytes =
	        envPtr->excRangeArrayNext * sizeof(ExceptionRange);
	int newElems = 2*envPtr->excRangeArrayEnd;
	size_t newBytes = newElems * sizeof(ExceptionRange);
	ExceptionRange *newPtr = (ExceptionRange *)
	        ckalloc((unsigned) newBytes);
	
	/*
	 * Copy from old ExceptionRange array to new, free old
	 * ExceptionRange array if needed, and mark the new ExceptionRange
	 * array as malloced.
	 */
	
	memcpy((VOID *) newPtr, (VOID *) envPtr->excRangeArrayPtr,
	        currBytes);
	if (envPtr->mallocedExcRangeArray) {
	    ckfree((char *) envPtr->excRangeArrayPtr);
	}
	envPtr->excRangeArrayPtr = (ExceptionRange *) newPtr;
	envPtr->excRangeArrayEnd = newElems;
	envPtr->mallocedExcRangeArray = 1;
    }
    envPtr->excRangeArrayNext++;
    
    rangePtr = &(envPtr->excRangeArrayPtr[index]);
    rangePtr->type = type;
    rangePtr->nestingLevel = envPtr->excRangeDepth;
    rangePtr->codeOffset = -1;
    rangePtr->numCodeBytes = -1;
    rangePtr->breakOffset = -1;
    rangePtr->continueOffset = -1;
    rangePtr->catchOffset = -1;
    return index;
}







|





|





|



|
>



|






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

|
<







|






|
|

|
|
<

<
<

|
<

<
|


|




|
|










|

|
|

|
|
|

|

|

|







2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130

2131


2132
2133

2134

2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
 *	source and bytecode information for the command must already
 *	have been registered.
 *
 *----------------------------------------------------------------------
 */

static void
EnterCmdExtentData(envPtr, cmdIndex, numSrcBytes, numCodeBytes)
    CompileEnv *envPtr;		/* Points to the compilation environment
				 * structure in which to enter command
				 * location information. */
    int cmdIndex;		/* Index of the command whose source and
				 * code length data is being set. */
    int numSrcBytes;		/* Number of command source chars. */
    int numCodeBytes;		/* Offset of last byte of command code. */
{
    CmdLocation *cmdLocPtr;

    if ((cmdIndex < 0) || (cmdIndex >= envPtr->numCommands)) {
	panic("EnterCmdExtentData: bad command index %d\n", cmdIndex);
    }
    
    if (cmdIndex > envPtr->cmdMapEnd) {
	panic("EnterCmdExtentData: missing start data for command %d\n",
	        cmdIndex);
    }

    cmdLocPtr = &(envPtr->cmdMapPtr[cmdIndex]);
    cmdLocPtr->numSrcBytes = numSrcBytes;
    cmdLocPtr->numCodeBytes = numCodeBytes;
}

/*
 *----------------------------------------------------------------------
 *













 * TclCreateExceptRange --











 *


























































































































































































 *	Procedure that allocates and initializes a new ExceptionRange
 *	structure of the specified kind in a CompileEnv.

 *
 * Results:
 *	Returns the index for the newly created ExceptionRange.
 *
 * Side effects:
 *	If there is not enough room in the CompileEnv's ExceptionRange
 *	array, the array in expanded: a new array of double the size is
 *	allocated, if envPtr->mallocedExceptArray is non-zero the old
 *	array is freed, and ExceptionRange entries are copied from the old
 *	array to the new one.
 *
 *----------------------------------------------------------------------
 */

int
TclCreateExceptRange(type, envPtr)
    ExceptionRangeType type;	/* The kind of ExceptionRange desired. */
    register CompileEnv *envPtr;/* Points to CompileEnv for which to
				 * create a new ExceptionRange structure. */

{


    register ExceptionRange *rangePtr;
    int index = envPtr->exceptArrayNext;

    

    if (index >= envPtr->exceptArrayEnd) {
        /*
	 * Expand the ExceptionRange array. The currently allocated entries
	 * are stored between elements 0 and (envPtr->exceptArrayNext - 1)
	 * [inclusive].
	 */
	
	size_t currBytes =
	        envPtr->exceptArrayNext * sizeof(ExceptionRange);
	int newElems = 2*envPtr->exceptArrayEnd;
	size_t newBytes = newElems * sizeof(ExceptionRange);
	ExceptionRange *newPtr = (ExceptionRange *)
	        ckalloc((unsigned) newBytes);
	
	/*
	 * Copy from old ExceptionRange array to new, free old
	 * ExceptionRange array if needed, and mark the new ExceptionRange
	 * array as malloced.
	 */
	
	memcpy((VOID *) newPtr, (VOID *) envPtr->exceptArrayPtr,
	        currBytes);
	if (envPtr->mallocedExceptArray) {
	    ckfree((char *) envPtr->exceptArrayPtr);
	}
	envPtr->exceptArrayPtr = (ExceptionRange *) newPtr;
	envPtr->exceptArrayEnd = newElems;
	envPtr->mallocedExceptArray = 1;
    }
    envPtr->exceptArrayNext++;
    
    rangePtr = &(envPtr->exceptArrayPtr[index]);
    rangePtr->type = type;
    rangePtr->nestingLevel = envPtr->exceptDepth;
    rangePtr->codeOffset = -1;
    rangePtr->numCodeBytes = -1;
    rangePtr->breakOffset = -1;
    rangePtr->continueOffset = -1;
    rangePtr->catchOffset = -1;
    return index;
}
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
 *	the old array is freed, and AuxData entries are copied from
 *	the old array to the new one.
 *
 *----------------------------------------------------------------------
 */

int
TclCreateAuxData(clientData, dupProc, freeProc, envPtr)
    ClientData clientData;	/* The compilation auxiliary data to store
				 * in the new aux data record. */
    AuxDataDupProc *dupProc;	/* Procedure to call to duplicate the
				 * compilation aux data when the containing
				 * ByteCode structure is duplicated. */
    AuxDataFreeProc *freeProc;	/* Procedure to call to free the
				 * compilation aux data when the containing
				 * ByteCode structure is freed.  */
    register CompileEnv *envPtr;/* Points to the CompileEnv for which a new
				 * aux data structure is to be allocated. */
{
    int index;			/* Index for the new AuxData structure. */
    register AuxData *auxDataPtr;
    				/* Points to the new AuxData structure */
    







|


<
<
<
|
<
<







2194
2195
2196
2197
2198
2199
2200
2201
2202
2203



2204


2205
2206
2207
2208
2209
2210
2211
 *	the old array is freed, and AuxData entries are copied from
 *	the old array to the new one.
 *
 *----------------------------------------------------------------------
 */

int
TclCreateAuxData(clientData, typePtr, envPtr)
    ClientData clientData;	/* The compilation auxiliary data to store
				 * in the new aux data record. */



    AuxDataType *typePtr;	/* Pointer to the type to attach to this AuxData */


    register CompileEnv *envPtr;/* Points to the CompileEnv for which a new
				 * aux data structure is to be allocated. */
{
    int index;			/* Index for the new AuxData structure. */
    register AuxData *auxDataPtr;
    				/* Points to the new AuxData structure */
    
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
	envPtr->auxDataArrayEnd = newElems;
	envPtr->mallocedAuxDataArray = 1;
    }
    envPtr->auxDataArrayNext++;
    
    auxDataPtr = &(envPtr->auxDataArrayPtr[index]);
    auxDataPtr->clientData = clientData;
    auxDataPtr->dupProc  = dupProc;
    auxDataPtr->freeProc = freeProc;
    return index;
}

/*
 *----------------------------------------------------------------------
 *
 * TclInitJumpFixupArray --







|
<







2236
2237
2238
2239
2240
2241
2242
2243

2244
2245
2246
2247
2248
2249
2250
	envPtr->auxDataArrayEnd = newElems;
	envPtr->mallocedAuxDataArray = 1;
    }
    envPtr->auxDataArrayNext++;
    
    auxDataPtr = &(envPtr->auxDataArrayPtr[index]);
    auxDataPtr->clientData = clientData;
    auxDataPtr->type = typePtr;

    return index;
}

/*
 *----------------------------------------------------------------------
 *
 * TclInitJumpFixupArray --
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
				 * initialize with information about this
				 * forward jump. */
{
    /*
     * Initialize the JumpFixup structure:
     *    - codeOffset is offset of first byte of jump below
     *    - cmdIndex is index of the command after the current one
     *    - excRangeIndex is the index of the first ExceptionRange after
     *      the current one.
     */
    
    jumpFixupPtr->jumpType = jumpType;
    jumpFixupPtr->codeOffset = TclCurrCodeOffset();
    jumpFixupPtr->cmdIndex = envPtr->numCommands;
    jumpFixupPtr->excRangeIndex = envPtr->excRangeArrayNext;
    
    switch (jumpType) {
    case TCL_UNCONDITIONAL_JUMP:
	TclEmitInstInt1(INST_JUMP1, /*offset*/ 0, envPtr);
	break;
    case TCL_TRUE_JUMP:
	TclEmitInstInt1(INST_JUMP_TRUE1, /*offset*/ 0, envPtr);
	break;
    default:
	TclEmitInstInt1(INST_JUMP_FALSE1, /*offset*/ 0, envPtr);
	break;
    }
}

/*
 *----------------------------------------------------------------------
 *







|




|

|



|


|


|







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
				 * initialize with information about this
				 * forward jump. */
{
    /*
     * Initialize the JumpFixup structure:
     *    - codeOffset is offset of first byte of jump below
     *    - cmdIndex is index of the command after the current one
     *    - exceptIndex is the index of the first ExceptionRange after
     *      the current one.
     */
    
    jumpFixupPtr->jumpType = jumpType;
    jumpFixupPtr->codeOffset = (envPtr->codeNext - envPtr->codeStart);
    jumpFixupPtr->cmdIndex = envPtr->numCommands;
    jumpFixupPtr->exceptIndex = envPtr->exceptArrayNext;
    
    switch (jumpType) {
    case TCL_UNCONDITIONAL_JUMP:
	TclEmitInstInt1(INST_JUMP1, 0, envPtr);
	break;
    case TCL_TRUE_JUMP:
	TclEmitInstInt1(INST_JUMP_TRUE1, 0, envPtr);
	break;
    default:
	TclEmitInstInt1(INST_JUMP_FALSE1, 0, envPtr);
	break;
    }
}

/*
 *----------------------------------------------------------------------
 *
7680
7681
7682
7683
7684
7685
7686



7687
7688

7689

7690
7691
7692
7693
7694
7695
7696
	    break;
	}
	return 0;
    }

    /*
     * We must grow the jump then move subsequent instructions down.



     */
    

    TclEnsureCodeSpace(3, envPtr);  /* NB: might change code addresses! */

    jumpPc = (envPtr->codeStart + jumpFixupPtr->codeOffset);
    for (numBytes = envPtr->codeNext-jumpPc-2, p = jumpPc+2+numBytes-1;
	    numBytes > 0;  numBytes--, p--) {
	p[3] = p[0];
    }
    envPtr->codeNext += 3;
    jumpDist += 3;







>
>
>


>
|
>







2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
	    break;
	}
	return 0;
    }

    /*
     * We must grow the jump then move subsequent instructions down.
     * Note that if we expand the space for generated instructions,
     * code addresses might change; be careful about updating any of
     * these addresses held in variables.
     */
    
    if ((envPtr->codeNext + 3) > envPtr->codeEnd) {
        TclExpandCodeArray(envPtr);
    }
    jumpPc = (envPtr->codeStart + jumpFixupPtr->codeOffset);
    for (numBytes = envPtr->codeNext-jumpPc-2, p = jumpPc+2+numBytes-1;
	    numBytes > 0;  numBytes--, p--) {
	p[3] = p[0];
    }
    envPtr->codeNext += 3;
    jumpDist += 3;
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739

7740
7741
7742
7743
7744










































































































































































































































































































































































































































































































































































































































































































































































































































































































































7745










    lastCmd  = (envPtr->numCommands - 1);
    if (firstCmd < lastCmd) {
	for (k = firstCmd;  k <= lastCmd;  k++) {
	    (envPtr->cmdMapPtr[k]).codeOffset += 3;
	}
    }
    
    firstRange = jumpFixupPtr->excRangeIndex;
    lastRange  = (envPtr->excRangeArrayNext - 1);
    for (k = firstRange;  k <= lastRange;  k++) {
	ExceptionRange *rangePtr = &(envPtr->excRangeArrayPtr[k]);
	rangePtr->codeOffset += 3;
	
	switch (rangePtr->type) {
	case LOOP_EXCEPTION_RANGE:
	    rangePtr->breakOffset += 3;
	    if (rangePtr->continueOffset != -1) {
		rangePtr->continueOffset += 3;
	    }
	    break;
	case CATCH_EXCEPTION_RANGE:
	    rangePtr->catchOffset += 3;
	    break;
	default:
	    panic("TclFixupForwardJump: unrecognized ExceptionRange type %d\n", rangePtr->type);

	}
    }
    return 1;			/* the jump was grown */
}





























































































































































































































































































































































































































































































































































































































































































































































































































































































































































|
|

|













|
>




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

>
>
>
>
>
>
>
>
>
>
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
    lastCmd  = (envPtr->numCommands - 1);
    if (firstCmd < lastCmd) {
	for (k = firstCmd;  k <= lastCmd;  k++) {
	    (envPtr->cmdMapPtr[k]).codeOffset += 3;
	}
    }
    
    firstRange = jumpFixupPtr->exceptIndex;
    lastRange  = (envPtr->exceptArrayNext - 1);
    for (k = firstRange;  k <= lastRange;  k++) {
	ExceptionRange *rangePtr = &(envPtr->exceptArrayPtr[k]);
	rangePtr->codeOffset += 3;
	
	switch (rangePtr->type) {
	case LOOP_EXCEPTION_RANGE:
	    rangePtr->breakOffset += 3;
	    if (rangePtr->continueOffset != -1) {
		rangePtr->continueOffset += 3;
	    }
	    break;
	case CATCH_EXCEPTION_RANGE:
	    rangePtr->catchOffset += 3;
	    break;
	default:
	    panic("TclFixupForwardJump: bad ExceptionRange type %d\n",
	            rangePtr->type);
	}
    }
    return 1;			/* the jump was grown */
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetInstructionTable --
 *
 *  Returns a pointer to the table describing Tcl bytecode instructions.
 *  This procedure is defined so that clients can access the pointer from
 *  outside the TCL DLLs.
 *
 * Results:
 *	Returns a pointer to the global instruction table, same as the
 *	expression (&instructionTable[0]).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

InstructionDesc *
TclGetInstructionTable()
{
    return &instructionTable[0];
}

/*
 *--------------------------------------------------------------
 *
 * TclRegisterAuxDataType --
 *
 *	This procedure is called to register a new AuxData type
 *	in the table of all AuxData types supported by Tcl.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The type is registered in the AuxData type table. If there was already
 *	a type with the same name as in typePtr, it is replaced with the
 *	new type.
 *
 *--------------------------------------------------------------
 */

void
TclRegisterAuxDataType(typePtr)
    AuxDataType *typePtr;	/* Information about object type;
                             * storage must be statically
                             * allocated (must live forever). */
{
    register Tcl_HashEntry *hPtr;
    int new;

    Tcl_MutexLock(&tableMutex);
    if (!auxDataTypeTableInitialized) {
        TclInitAuxDataTypeTable();
    }

    /*
     * If there's already a type with the given name, remove it.
     */

    hPtr = Tcl_FindHashEntry(&auxDataTypeTable, typePtr->name);
    if (hPtr != (Tcl_HashEntry *) NULL) {
        Tcl_DeleteHashEntry(hPtr);
    }

    /*
     * Now insert the new object type.
     */

    hPtr = Tcl_CreateHashEntry(&auxDataTypeTable, typePtr->name, &new);
    if (new) {
        Tcl_SetHashValue(hPtr, typePtr);
    }
    Tcl_MutexUnlock(&tableMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetAuxDataType --
 *
 *	This procedure looks up an Auxdata type by name.
 *
 * Results:
 *	If an AuxData type with name matching "typeName" is found, a pointer
 *	to its AuxDataType structure is returned; otherwise, NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

AuxDataType *
TclGetAuxDataType(typeName)
    char *typeName;		/* Name of AuxData type to look up. */
{
    register Tcl_HashEntry *hPtr;
    AuxDataType *typePtr = NULL;

    Tcl_MutexLock(&tableMutex);
    if (!auxDataTypeTableInitialized) {
        TclInitAuxDataTypeTable();
    }

    hPtr = Tcl_FindHashEntry(&auxDataTypeTable, typeName);
    if (hPtr != (Tcl_HashEntry *) NULL) {
        typePtr = (AuxDataType *) Tcl_GetHashValue(hPtr);
    }
    Tcl_MutexUnlock(&tableMutex);

    return typePtr;
}

/*
 *--------------------------------------------------------------
 *
 * TclInitAuxDataTypeTable --
 *
 *	This procedure is invoked to perform once-only initialization of
 *	the AuxData type table. It also registers the AuxData types defined in 
 *	this file.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Initializes the table of defined AuxData types "auxDataTypeTable" with
 *	builtin AuxData types defined in this file.
 *
 *--------------------------------------------------------------
 */

void
TclInitAuxDataTypeTable()
{
    /*
     * The table mutex must already be held before this routine is invoked.
     */

    auxDataTypeTableInitialized = 1;
    Tcl_InitHashTable(&auxDataTypeTable, TCL_STRING_KEYS);

    /*
     * There is only one AuxData type at this time, so register it here.
     */

    TclRegisterAuxDataType(&tclForeachInfoType);
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeAuxDataTypeTable --
 *
 *	This procedure is called by Tcl_Finalize after all exit handlers
 *	have been run to free up storage associated with the table of AuxData
 *	types.  This procedure is called by TclFinalizeExecution() which
 *	is called by Tcl_Finalize().
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Deletes all entries in the hash table of AuxData types.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeAuxDataTypeTable()
{
    Tcl_MutexLock(&tableMutex);
    if (auxDataTypeTableInitialized) {
        Tcl_DeleteHashTable(&auxDataTypeTable);
        auxDataTypeTableInitialized = 0;
    }
    Tcl_MutexUnlock(&tableMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * GetCmdLocEncodingSize --
 *
 *	Computes the total number of bytes needed to encode the command
 *	location information for some compiled code.
 *
 * Results:
 *	The byte count needed to encode the compiled location information.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
GetCmdLocEncodingSize(envPtr)
     CompileEnv *envPtr;	/* Points to compilation environment
				 * structure containing the CmdLocation
				 * structure to encode. */
{
    register CmdLocation *mapPtr = envPtr->cmdMapPtr;
    int numCmds = envPtr->numCommands;
    int codeDelta, codeLen, srcDelta, srcLen;
    int codeDeltaNext, codeLengthNext, srcDeltaNext, srcLengthNext;
				/* The offsets in their respective byte
				 * sequences where the next encoded offset
				 * or length should go. */
    int prevCodeOffset, prevSrcOffset, i;

    codeDeltaNext = codeLengthNext = srcDeltaNext = srcLengthNext = 0;
    prevCodeOffset = prevSrcOffset = 0;
    for (i = 0;  i < numCmds;  i++) {
	codeDelta = (mapPtr[i].codeOffset - prevCodeOffset);
	if (codeDelta < 0) {
	    panic("GetCmdLocEncodingSize: bad code offset");
	} else if (codeDelta <= 127) {
	    codeDeltaNext++;
	} else {
	    codeDeltaNext += 5;	 /* 1 byte for 0xFF, 4 for positive delta */
	}
	prevCodeOffset = mapPtr[i].codeOffset;

	codeLen = mapPtr[i].numCodeBytes;
	if (codeLen < 0) {
	    panic("GetCmdLocEncodingSize: bad code length");
	} else if (codeLen <= 127) {
	    codeLengthNext++;
	} else {
	    codeLengthNext += 5; /* 1 byte for 0xFF, 4 for length */
	}

	srcDelta = (mapPtr[i].srcOffset - prevSrcOffset);
	if ((-127 <= srcDelta) && (srcDelta <= 127)) {
	    srcDeltaNext++;
	} else {
	    srcDeltaNext += 5;	 /* 1 byte for 0xFF, 4 for delta */
	}
	prevSrcOffset = mapPtr[i].srcOffset;

	srcLen = mapPtr[i].numSrcBytes;
	if (srcLen < 0) {
	    panic("GetCmdLocEncodingSize: bad source length");
	} else if (srcLen <= 127) {
	    srcLengthNext++;
	} else {
	    srcLengthNext += 5;	 /* 1 byte for 0xFF, 4 for length */
	}
    }

    return (codeDeltaNext + codeLengthNext + srcDeltaNext + srcLengthNext);
}

/*
 *----------------------------------------------------------------------
 *
 * EncodeCmdLocMap --
 *
 *	Encode the command location information for some compiled code into
 *	a ByteCode structure. The encoded command location map is stored as
 *	three adjacent byte sequences.
 *
 * Results:
 *	Pointer to the first byte after the encoded command location
 *	information.
 *
 * Side effects:
 *	The encoded information is stored into the block of memory headed
 *	by codePtr. Also records pointers to the start of the four byte
 *	sequences in fields in codePtr's ByteCode header structure.
 *
 *----------------------------------------------------------------------
 */

static unsigned char *
EncodeCmdLocMap(envPtr, codePtr, startPtr)
     CompileEnv *envPtr;	/* Points to compilation environment
				 * structure containing the CmdLocation
				 * structure to encode. */
     ByteCode *codePtr;		/* ByteCode in which to encode envPtr's
				 * command location information. */
     unsigned char *startPtr;	/* Points to the first byte in codePtr's
				 * memory block where the location
				 * information is to be stored. */
{
    register CmdLocation *mapPtr = envPtr->cmdMapPtr;
    int numCmds = envPtr->numCommands;
    register unsigned char *p = startPtr;
    int codeDelta, codeLen, srcDelta, srcLen, prevOffset;
    register int i;
    
    /*
     * Encode the code offset for each command as a sequence of deltas.
     */

    codePtr->codeDeltaStart = p;
    prevOffset = 0;
    for (i = 0;  i < numCmds;  i++) {
	codeDelta = (mapPtr[i].codeOffset - prevOffset);
	if (codeDelta < 0) {
	    panic("EncodeCmdLocMap: bad code offset");
	} else if (codeDelta <= 127) {
	    TclStoreInt1AtPtr(codeDelta, p);
	    p++;
	} else {
	    TclStoreInt1AtPtr(0xFF, p);
	    p++;
	    TclStoreInt4AtPtr(codeDelta, p);
	    p += 4;
	}
	prevOffset = mapPtr[i].codeOffset;
    }

    /*
     * Encode the code length for each command.
     */

    codePtr->codeLengthStart = p;
    for (i = 0;  i < numCmds;  i++) {
	codeLen = mapPtr[i].numCodeBytes;
	if (codeLen < 0) {
	    panic("EncodeCmdLocMap: bad code length");
	} else if (codeLen <= 127) {
	    TclStoreInt1AtPtr(codeLen, p);
	    p++;
	} else {
	    TclStoreInt1AtPtr(0xFF, p);
	    p++;
	    TclStoreInt4AtPtr(codeLen, p);
	    p += 4;
	}
    }

    /*
     * Encode the source offset for each command as a sequence of deltas.
     */

    codePtr->srcDeltaStart = p;
    prevOffset = 0;
    for (i = 0;  i < numCmds;  i++) {
	srcDelta = (mapPtr[i].srcOffset - prevOffset);
	if ((-127 <= srcDelta) && (srcDelta <= 127)) {
	    TclStoreInt1AtPtr(srcDelta, p);
	    p++;
	} else {
	    TclStoreInt1AtPtr(0xFF, p);
	    p++;
	    TclStoreInt4AtPtr(srcDelta, p);
	    p += 4;
	}
	prevOffset = mapPtr[i].srcOffset;
    }

    /*
     * Encode the source length for each command.
     */

    codePtr->srcLengthStart = p;
    for (i = 0;  i < numCmds;  i++) {
	srcLen = mapPtr[i].numSrcBytes;
	if (srcLen < 0) {
	    panic("EncodeCmdLocMap: bad source length");
	} else if (srcLen <= 127) {
	    TclStoreInt1AtPtr(srcLen, p);
	    p++;
	} else {
	    TclStoreInt1AtPtr(0xFF, p);
	    p++;
	    TclStoreInt4AtPtr(srcLen, p);
	    p += 4;
	}
    }
    
    return p;
}

#ifdef TCL_COMPILE_DEBUG
/*
 *----------------------------------------------------------------------
 *
 * TclPrintByteCodeObj --
 *
 *	This procedure prints ("disassembles") the instructions of a
 *	bytecode object to stdout.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TclPrintByteCodeObj(interp, objPtr)
    Tcl_Interp *interp;		/* Used only for Tcl_GetStringFromObj. */
    Tcl_Obj *objPtr;		/* The bytecode object to disassemble. */
{
    ByteCode* codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
    unsigned char *codeStart, *codeLimit, *pc;
    unsigned char *codeDeltaNext, *codeLengthNext;
    unsigned char *srcDeltaNext, *srcLengthNext;
    int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i;
    Interp *iPtr = (Interp *) *codePtr->interpHandle;

    if (codePtr->refCount <= 0) {
	return;			/* already freed */
    }

    codeStart = codePtr->codeStart;
    codeLimit = (codeStart + codePtr->numCodeBytes);
    numCmds = codePtr->numCommands;

    /*
     * Print header lines describing the ByteCode.
     */

    fprintf(stdout, "\nByteCode 0x%x, refCt %u, epoch %u, interp 0x%x (epoch %u)\n",
	    (unsigned int) codePtr, codePtr->refCount,
	    codePtr->compileEpoch, (unsigned int) iPtr,
	    iPtr->compileEpoch);
    fprintf(stdout, "  Source ");
    TclPrintSource(stdout, codePtr->source,
	    TclMin(codePtr->numSrcBytes, 55));
    fprintf(stdout, "\n  Cmds %d, src %d, inst %d, litObjs %u, aux %d, stkDepth %u, code/src %.2f\n",
	    numCmds, codePtr->numSrcBytes, codePtr->numCodeBytes,
	    codePtr->numLitObjects, codePtr->numAuxDataItems,
	    codePtr->maxStackDepth,
#ifdef TCL_COMPILE_STATS
	    (codePtr->numSrcBytes?
	            ((float)codePtr->structureSize)/((float)codePtr->numSrcBytes) : 0.0));
#else
	    0.0);
#endif
#ifdef TCL_COMPILE_STATS
    fprintf(stdout,
	    "  Code %d = header %d+inst %d+litObj %d+exc %d+aux %d+cmdMap %d\n",
	    codePtr->structureSize,
	    (sizeof(ByteCode) - (sizeof(size_t) + sizeof(Tcl_Time))),
	    codePtr->numCodeBytes,
	    (codePtr->numLitObjects * sizeof(Tcl_Obj *)),
	    (codePtr->numExceptRanges * sizeof(ExceptionRange)),
	    (codePtr->numAuxDataItems * sizeof(AuxData)),
	    codePtr->numCmdLocBytes);
#endif /* TCL_COMPILE_STATS */
    
    /*
     * If the ByteCode is the compiled body of a Tcl procedure, print
     * information about that procedure. Note that we don't know the
     * procedure's name since ByteCode's can be shared among procedures.
     */
    
    if (codePtr->procPtr != NULL) {
	Proc *procPtr = codePtr->procPtr;
	int numCompiledLocals = procPtr->numCompiledLocals;
	fprintf(stdout,
	        "  Proc 0x%x, refCt %d, args %d, compiled locals %d\n",
		(unsigned int) procPtr, procPtr->refCount, procPtr->numArgs,
		numCompiledLocals);
	if (numCompiledLocals > 0) {
	    CompiledLocal *localPtr = procPtr->firstLocalPtr;
	    for (i = 0;  i < numCompiledLocals;  i++) {
		fprintf(stdout, "      slot %d%s%s%s%s%s%s", i, 
			((localPtr->flags & VAR_SCALAR)?  ", scalar"  : ""),
			((localPtr->flags & VAR_ARRAY)?  ", array"  : ""),
			((localPtr->flags & VAR_LINK)?  ", link"  : ""),
			((localPtr->flags & VAR_ARGUMENT)?  ", arg"  : ""),
			((localPtr->flags & VAR_TEMPORARY)? ", temp" : ""),
			((localPtr->flags & VAR_RESOLVED)? ", resolved" : ""));
		if (TclIsVarTemporary(localPtr)) {
		    fprintf(stdout,	"\n");
		} else {
		    fprintf(stdout,	", \"%s\"\n", localPtr->name);
		}
		localPtr = localPtr->nextPtr;
	    }
	}
    }

    /*
     * Print the ExceptionRange array.
     */

    if (codePtr->numExceptRanges > 0) {
	fprintf(stdout, "  Exception ranges %d, depth %d:\n",
	        codePtr->numExceptRanges, codePtr->maxExceptDepth);
	for (i = 0;  i < codePtr->numExceptRanges;  i++) {
	    ExceptionRange *rangePtr = &(codePtr->exceptArrayPtr[i]);
	    fprintf(stdout, "      %d: level %d, %s, pc %d-%d, ",
		    i, rangePtr->nestingLevel,
		    ((rangePtr->type == LOOP_EXCEPTION_RANGE)
			    ? "loop" : "catch"),
		    rangePtr->codeOffset,
		    (rangePtr->codeOffset + rangePtr->numCodeBytes - 1));
	    switch (rangePtr->type) {
	    case LOOP_EXCEPTION_RANGE:
		fprintf(stdout,	"continue %d, break %d\n",
		        rangePtr->continueOffset, rangePtr->breakOffset);
		break;
	    case CATCH_EXCEPTION_RANGE:
		fprintf(stdout,	"catch %d\n", rangePtr->catchOffset);
		break;
	    default:
		panic("TclPrintByteCodeObj: bad ExceptionRange type %d\n",
		        rangePtr->type);
	    }
	}
    }
    
    /*
     * If there were no commands (e.g., an expression or an empty string
     * was compiled), just print all instructions and return.
     */

    if (numCmds == 0) {
	pc = codeStart;
	while (pc < codeLimit) {
	    fprintf(stdout, "    ");
	    pc += TclPrintInstruction(codePtr, pc);
	}
	return;
    }
    
    /*
     * Print table showing the code offset, source offset, and source
     * length for each command. These are encoded as a sequence of bytes.
     */

    fprintf(stdout, "  Commands %d:", numCmds);
    codeDeltaNext = codePtr->codeDeltaStart;
    codeLengthNext = codePtr->codeLengthStart;
    srcDeltaNext  = codePtr->srcDeltaStart;
    srcLengthNext = codePtr->srcLengthStart;
    codeOffset = srcOffset = 0;
    for (i = 0;  i < numCmds;  i++) {
	if ((unsigned int) (*codeDeltaNext) == (unsigned int) 0xFF) {
	    codeDeltaNext++;
	    delta = TclGetInt4AtPtr(codeDeltaNext);
	    codeDeltaNext += 4;
	} else {
	    delta = TclGetInt1AtPtr(codeDeltaNext);
	    codeDeltaNext++;
	}
	codeOffset += delta;

	if ((unsigned int) (*codeLengthNext) == (unsigned int) 0xFF) {
	    codeLengthNext++;
	    codeLen = TclGetInt4AtPtr(codeLengthNext);
	    codeLengthNext += 4;
	} else {
	    codeLen = TclGetInt1AtPtr(codeLengthNext);
	    codeLengthNext++;
	}
	
	if ((unsigned int) (*srcDeltaNext) == (unsigned int) 0xFF) {
	    srcDeltaNext++;
	    delta = TclGetInt4AtPtr(srcDeltaNext);
	    srcDeltaNext += 4;
	} else {
	    delta = TclGetInt1AtPtr(srcDeltaNext);
	    srcDeltaNext++;
	}
	srcOffset += delta;

	if ((unsigned int) (*srcLengthNext) == (unsigned int) 0xFF) {
	    srcLengthNext++;
	    srcLen = TclGetInt4AtPtr(srcLengthNext);
	    srcLengthNext += 4;
	} else {
	    srcLen = TclGetInt1AtPtr(srcLengthNext);
	    srcLengthNext++;
	}
	
	fprintf(stdout,	"%s%4d: pc %d-%d, src %d-%d",
		((i % 2)? "   	" : "\n   "),
		(i+1), codeOffset, (codeOffset + codeLen - 1),
		srcOffset, (srcOffset + srcLen - 1));
    }
    if (numCmds > 0) {
	fprintf(stdout,	"\n");
    }
    
    /*
     * Print each instruction. If the instruction corresponds to the start
     * of a command, print the command's source. Note that we don't need
     * the code length here.
     */

    codeDeltaNext = codePtr->codeDeltaStart;
    srcDeltaNext  = codePtr->srcDeltaStart;
    srcLengthNext = codePtr->srcLengthStart;
    codeOffset = srcOffset = 0;
    pc = codeStart;
    for (i = 0;  i < numCmds;  i++) {
	if ((unsigned int) (*codeDeltaNext) == (unsigned int) 0xFF) {
	    codeDeltaNext++;
	    delta = TclGetInt4AtPtr(codeDeltaNext);
	    codeDeltaNext += 4;
	} else {
	    delta = TclGetInt1AtPtr(codeDeltaNext);
	    codeDeltaNext++;
	}
	codeOffset += delta;

	if ((unsigned int) (*srcDeltaNext) == (unsigned int) 0xFF) {
	    srcDeltaNext++;
	    delta = TclGetInt4AtPtr(srcDeltaNext);
	    srcDeltaNext += 4;
	} else {
	    delta = TclGetInt1AtPtr(srcDeltaNext);
	    srcDeltaNext++;
	}
	srcOffset += delta;

	if ((unsigned int) (*srcLengthNext) == (unsigned int) 0xFF) {
	    srcLengthNext++;
	    srcLen = TclGetInt4AtPtr(srcLengthNext);
	    srcLengthNext += 4;
	} else {
	    srcLen = TclGetInt1AtPtr(srcLengthNext);
	    srcLengthNext++;
	}

	/*
	 * Print instructions before command i.
	 */
	
	while ((pc-codeStart) < codeOffset) {
	    fprintf(stdout, "    ");
	    pc += TclPrintInstruction(codePtr, pc);
	}

	fprintf(stdout, "  Command %d: ", (i+1));
	TclPrintSource(stdout, (codePtr->source + srcOffset),
	        TclMin(srcLen, 55));
	fprintf(stdout, "\n");
    }
    if (pc < codeLimit) {
	/*
	 * Print instructions after the last command.
	 */

	while (pc < codeLimit) {
	    fprintf(stdout, "    ");
	    pc += TclPrintInstruction(codePtr, pc);
	}
    }
}
#endif /* TCL_COMPILE_DEBUG */

/*
 *----------------------------------------------------------------------
 *
 * TclPrintInstruction --
 *
 *	This procedure prints ("disassembles") one instruction from a
 *	bytecode object to stdout.
 *
 * Results:
 *	Returns the length in bytes of the current instruiction.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclPrintInstruction(codePtr, pc)
    ByteCode* codePtr;		/* Bytecode containing the instruction. */
    unsigned char *pc;		/* Points to first byte of instruction. */
{
    Proc *procPtr = codePtr->procPtr;
    unsigned char opCode = *pc;
    register InstructionDesc *instDesc = &instructionTable[opCode];
    unsigned char *codeStart = codePtr->codeStart;
    unsigned int pcOffset = (pc - codeStart);
    int opnd, i, j;
    
    fprintf(stdout, "(%u) %s ", pcOffset, instDesc->name);
    for (i = 0;  i < instDesc->numOperands;  i++) {
	switch (instDesc->opTypes[i]) {
	case OPERAND_INT1:
	    opnd = TclGetInt1AtPtr(pc+1+i);
	    if ((i == 0) && ((opCode == INST_JUMP1)
			     || (opCode == INST_JUMP_TRUE1)
		             || (opCode == INST_JUMP_FALSE1))) {
		fprintf(stdout, "%d  	# pc %u", opnd, (pcOffset + opnd));
	    } else {
		fprintf(stdout, "%d", opnd);
	    }
	    break;
	case OPERAND_INT4:
	    opnd = TclGetInt4AtPtr(pc+1+i);
	    if ((i == 0) && ((opCode == INST_JUMP4)
			     || (opCode == INST_JUMP_TRUE4)
		             || (opCode == INST_JUMP_FALSE4))) {
		fprintf(stdout, "%d  	# pc %u", opnd, (pcOffset + opnd));
	    } else {
		fprintf(stdout, "%d", opnd);
	    }
	    break;
	case OPERAND_UINT1:
	    opnd = TclGetUInt1AtPtr(pc+1+i);
	    if ((i == 0) && (opCode == INST_PUSH1)) {
		fprintf(stdout, "%u  	# ", (unsigned int) opnd);
		TclPrintObject(stdout, codePtr->objArrayPtr[opnd], 40);
	    } else if ((i == 0) && ((opCode == INST_LOAD_SCALAR1)
				    || (opCode == INST_LOAD_ARRAY1)
				    || (opCode == INST_STORE_SCALAR1)
				    || (opCode == INST_STORE_ARRAY1))) {
		int localCt = procPtr->numCompiledLocals;
		CompiledLocal *localPtr = procPtr->firstLocalPtr;
		if (opnd >= localCt) {
		    panic("TclPrintInstruction: bad local var index %u (%u locals)\n",
			     (unsigned int) opnd, localCt);
		    return instDesc->numBytes;
		}
		for (j = 0;  j < opnd;  j++) {
		    localPtr = localPtr->nextPtr;
		}
		if (TclIsVarTemporary(localPtr)) {
		    fprintf(stdout, "%u	# temp var %u",
			    (unsigned int) opnd, (unsigned int) opnd);
		} else {
		    fprintf(stdout, "%u	# var ", (unsigned int) opnd);
		    TclPrintSource(stdout, localPtr->name, 40);
		}
	    } else {
		fprintf(stdout, "%u ", (unsigned int) opnd);
	    }
	    break;
	case OPERAND_UINT4:
	    opnd = TclGetUInt4AtPtr(pc+1+i);
	    if (opCode == INST_PUSH4) {
		fprintf(stdout, "%u  	# ", opnd);
		TclPrintObject(stdout, codePtr->objArrayPtr[opnd], 40);
	    } else if ((i == 0) && ((opCode == INST_LOAD_SCALAR4)
				    || (opCode == INST_LOAD_ARRAY4)
				    || (opCode == INST_STORE_SCALAR4)
				    || (opCode == INST_STORE_ARRAY4))) {
		int localCt = procPtr->numCompiledLocals;
		CompiledLocal *localPtr = procPtr->firstLocalPtr;
		if (opnd >= localCt) {
		    panic("TclPrintInstruction: bad local var index %u (%u locals)\n",
			     (unsigned int) opnd, localCt);
		    return instDesc->numBytes;
		}
		for (j = 0;  j < opnd;  j++) {
		    localPtr = localPtr->nextPtr;
		}
		if (TclIsVarTemporary(localPtr)) {
		    fprintf(stdout, "%u	# temp var %u",
			    (unsigned int) opnd, (unsigned int) opnd);
		} else {
		    fprintf(stdout, "%u	# var ", (unsigned int) opnd);
		    TclPrintSource(stdout, localPtr->name, 40);
		}
	    } else {
		fprintf(stdout, "%u ", (unsigned int) opnd);
	    }
	    break;
	case OPERAND_NONE:
	default:
	    break;
	}
    }
    fprintf(stdout, "\n");
    return instDesc->numBytes;
}

/*
 *----------------------------------------------------------------------
 *
 * TclPrintObject --
 *
 *	This procedure prints up to a specified number of characters from
 *	the argument Tcl object's string representation to a specified file.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Outputs characters to the specified file.
 *
 *----------------------------------------------------------------------
 */

void
TclPrintObject(outFile, objPtr, maxChars)
    FILE *outFile;		/* The file to print the source to. */
    Tcl_Obj *objPtr;		/* Points to the Tcl object whose string
				 * representation should be printed. */
    int maxChars;		/* Maximum number of chars to print. */
{
    char *bytes;
    int length;
    
    bytes = Tcl_GetStringFromObj(objPtr, &length);
    TclPrintSource(outFile, bytes, TclMin(length, maxChars));
}

/*
 *----------------------------------------------------------------------
 *
 * TclPrintSource --
 *
 *	This procedure prints up to a specified number of characters from
 *	the argument string to a specified file. It tries to produce legible
 *	output by adding backslashes as necessary.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Outputs characters to the specified file.
 *
 *----------------------------------------------------------------------
 */

void
TclPrintSource(outFile, string, maxChars)
    FILE *outFile;		/* The file to print the source to. */
    char *string;		/* The string to print. */
    int maxChars;		/* Maximum number of chars to print. */
{
    register char *p;
    register int i = 0;

    if (string == NULL) {
	fprintf(outFile, "\"\"");
	return;
    }

    fprintf(outFile, "\"");
    p = string;
    for (;  (*p != '\0') && (i < maxChars);  p++, i++) {
	switch (*p) {
	    case '"':
		fprintf(outFile, "\\\"");
		continue;
	    case '\f':
		fprintf(outFile, "\\f");
		continue;
	    case '\n':
		fprintf(outFile, "\\n");
		continue;
            case '\r':
		fprintf(outFile, "\\r");
		continue;
	    case '\t':
		fprintf(outFile, "\\t");
		continue;
            case '\v':
		fprintf(outFile, "\\v");
		continue;
	    default:
		fprintf(outFile, "%c", *p);
		continue;
	}
    }
    fprintf(outFile, "\"");
}

#ifdef TCL_COMPILE_STATS
/*
 *----------------------------------------------------------------------
 *
 * RecordByteCodeStats --
 *
 *	Accumulates various compilation-related statistics for each newly
 *	compiled ByteCode. Called by the TclInitByteCodeObj when Tcl is
 *	compiled with the -DTCL_COMPILE_STATS flag
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Accumulates aggregate code-related statistics in the interpreter's
 *	ByteCodeStats structure. Records statistics specific to a ByteCode
 *	in its ByteCode structure.
 *
 *----------------------------------------------------------------------
 */

void
RecordByteCodeStats(codePtr)
    ByteCode *codePtr;		/* Points to ByteCode structure with info
				 * to add to accumulated statistics. */
{
    Interp *iPtr = (Interp *) *codePtr->interpHandle;
    register ByteCodeStats *statsPtr = &(iPtr->stats);

    statsPtr->numCompilations++;
    statsPtr->totalSrcBytes        += (double) codePtr->numSrcBytes;
    statsPtr->totalByteCodeBytes   += (double) codePtr->structureSize;
    statsPtr->currentSrcBytes      += (double) codePtr->numSrcBytes;
    statsPtr->currentByteCodeBytes += (double) codePtr->structureSize;
    
    statsPtr->srcCount[TclLog2(codePtr->numSrcBytes)]++;
    statsPtr->byteCodeCount[TclLog2(codePtr->structureSize)]++;

    statsPtr->currentInstBytes   += (double) codePtr->numCodeBytes;
    statsPtr->currentLitBytes    +=
	    (double) (codePtr->numLitObjects * sizeof(Tcl_Obj *)); 
    statsPtr->currentExceptBytes +=
	    (double) (codePtr->numExceptRanges * sizeof(ExceptionRange));
    statsPtr->currentAuxBytes    +=
            (double) (codePtr->numAuxDataItems * sizeof(AuxData));
    statsPtr->currentCmdMapBytes += (double) codePtr->numCmdLocBytes;
}
#endif /* TCL_COMPILE_STATS */

Changes to generic/tclCompile.h.

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





18
19
20
21
22
23
24
/*
 * tclCompile.h --
 *
 * 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.
 *
 * SCCS: @(#) tclCompile.h 1.37 97/08/07 19:11:50
 */

#ifndef _TCLCOMPILATION
#define _TCLCOMPILATION 1

#ifndef _TCLINT
#include "tclInt.h"
#endif /* _TCLINT */






/*
 *------------------------------------------------------------------------
 * Variables related to compilation. These are used in tclCompile.c,
 * tclExecute.c, tclBasic.c, and their clients.
 *------------------------------------------------------------------------
 */



|




|








>
>
>
>
>







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
/*
 * tclCompile.h --
 *
 * Copyright (c) 1996-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: tclCompile.h,v 1.1.2.5 1999/03/10 22:51:14 redman Exp $
 */

#ifndef _TCLCOMPILATION
#define _TCLCOMPILATION 1

#ifndef _TCLINT
#include "tclInt.h"
#endif /* _TCLINT */

#ifdef BUILD_tcl
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 *------------------------------------------------------------------------
 * Variables related to compilation. These are used in tclCompile.c,
 * tclExecute.c, tclBasic.c, and their clients.
 *------------------------------------------------------------------------
 */
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
 *    2: trace invocations of all (not compiled away) commands
 *    3: display each instruction executed
 * This variable is linked to the Tcl variable "tcl_traceExec".
 */

extern int 		tclTraceExec;

/*
 * The number of bytecode compilations and various other compilation-related
 * statistics. The tclByteCodeCount and tclSourceCount arrays are used to
 * hold the count of ByteCodes and sources whose sizes fall into various
 * binary decades; e.g., tclByteCodeCount[5] is a count of the ByteCodes
 * with size larger than 2**4 and less than or equal to 2**5.
 */

#ifdef TCL_COMPILE_STATS
extern long		tclNumCompilations;
extern double		tclTotalSourceBytes;
extern double		tclTotalCodeBytes;

extern double		tclTotalInstBytes;
extern double		tclTotalObjBytes;
extern double		tclTotalExceptBytes;
extern double		tclTotalAuxBytes;
extern double		tclTotalCmdMapBytes;

extern double		tclCurrentSourceBytes;
extern double		tclCurrentCodeBytes;

extern int		tclSourceCount[32];
extern int		tclByteCodeCount[32];
#endif /* TCL_COMPILE_STATS */

/*
 *------------------------------------------------------------------------
 * Data structures related to compilation.
 *------------------------------------------------------------------------
 */

/*







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







55
56
57
58
59
60
61


























62
63
64
65
66
67
68
 *    2: trace invocations of all (not compiled away) commands
 *    3: display each instruction executed
 * This variable is linked to the Tcl variable "tcl_traceExec".
 */

extern int 		tclTraceExec;



























/*
 *------------------------------------------------------------------------
 * Data structures related to compilation.
 *------------------------------------------------------------------------
 */

/*
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
 * for the most deeply nested loop, if any, is found and used. These
 * structures are also generated for the "next" subcommands of for loops
 * since a break there terminates the for command. This means a for command
 * actually generates two LoopInfo structures.
 */

typedef enum {
    LOOP_EXCEPTION_RANGE,	/* Code range is part of a loop command.
				 * break and continue "exceptions" cause
				 * jumps to appropriate PC offsets. */
    CATCH_EXCEPTION_RANGE	/* Code range is controlled by a catch
				 * command. Errors in the range cause a
				 * jump to a particular PC offset. */
} ExceptionRangeType;

typedef struct ExceptionRange {
    ExceptionRangeType type;	/* The kind of ExceptionRange. */
    int nestingLevel;		/* Static depth of the exception range.
				 * Used to find the most deeply-nested
				 * range surrounding a PC at runtime. */
    int codeOffset;		/* Offset of the first instruction byte of
				 * the code range. */
    int numCodeBytes;		/* Number of bytes in the code range. */
    int breakOffset;		/* If a LOOP_EXCEPTION_RANGE, the target
				 * PC offset for a break command in the
				 * range. */
    int continueOffset;		/* If a LOOP_EXCEPTION_RANGE and not -1,
				 * the target PC offset for a continue
				 * command in the code range. Otherwise,
				 * ignore this range when processing a
				 * continue command. */
    int catchOffset;		/* If a CATCH_EXCEPTION_RANGE, the target PC
				 * offset for an "exception" in range. */
} ExceptionRange;

/*
 * Structure used to map between instruction pc and source locations. It
 * defines for each compiled Tcl command its code's starting offset and 
 * its source's starting offset and length. Note that the code offset
 * increases monotonically: that is, the table is sorted in code offset
 * order. The source offset is not monotonic.
 */

typedef struct CmdLocation {
    int codeOffset;		/* Offset of first byte of command code. */
    int numCodeBytes;		/* Number of bytes for command's code. */
    int srcOffset;		/* Offset of first char of the command. */
    int numSrcChars;		/* Number of command source chars. */
} CmdLocation;

/*
 * CompileProcs need the ability to record information during compilation
 * that can be used by bytecode instructions during execution. The AuxData
 * structure provides this "auxiliary data" mechanism. An arbitrary number
 * of these structures can be stored in the ByteCode record (during







|
|

|
|
|










|
|
<
|
|
|
<
|

|














|







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
 * for the most deeply nested loop, if any, is found and used. These
 * structures are also generated for the "next" subcommands of for loops
 * since a break there terminates the for command. This means a for command
 * actually generates two LoopInfo structures.
 */

typedef enum {
    LOOP_EXCEPTION_RANGE,	/* Exception's range is part of a loop.
				 * Break and continue "exceptions" cause
				 * jumps to appropriate PC offsets. */
    CATCH_EXCEPTION_RANGE	/* Exception's range is controlled by a
				 * catch command. Errors in the range cause
				 * a jump to a catch PC offset. */
} ExceptionRangeType;

typedef struct ExceptionRange {
    ExceptionRangeType type;	/* The kind of ExceptionRange. */
    int nestingLevel;		/* Static depth of the exception range.
				 * Used to find the most deeply-nested
				 * range surrounding a PC at runtime. */
    int codeOffset;		/* Offset of the first instruction byte of
				 * the code range. */
    int numCodeBytes;		/* Number of bytes in the code range. */
    int breakOffset;		/* If LOOP_EXCEPTION_RANGE, the target PC
				 * offset for a break command in the range. */

    int continueOffset;		/* If LOOP_EXCEPTION_RANGE and not -1, the
				 * target PC offset for a continue command in
				 * the code range. Otherwise, ignore this range

				 * when processing a continue command. */
    int catchOffset;		/* If a CATCH_EXCEPTION_RANGE, the target PC
				 * offset for any "exception" in range. */
} ExceptionRange;

/*
 * Structure used to map between instruction pc and source locations. It
 * defines for each compiled Tcl command its code's starting offset and 
 * its source's starting offset and length. Note that the code offset
 * increases monotonically: that is, the table is sorted in code offset
 * order. The source offset is not monotonic.
 */

typedef struct CmdLocation {
    int codeOffset;		/* Offset of first byte of command code. */
    int numCodeBytes;		/* Number of bytes for command's code. */
    int srcOffset;		/* Offset of first char of the command. */
    int numSrcBytes;		/* Number of command source chars. */
} CmdLocation;

/*
 * CompileProcs need the ability to record information during compilation
 * that can be used by bytecode instructions during execution. The AuxData
 * structure provides this "auxiliary data" mechanism. An arbitrary number
 * of these structures can be stored in the ByteCode record (during
161
162
163
164
165
166
167





















168
169
170
171
172
173
174


175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311






312
313

314
315
316
317
318
319
320
321








322
323
324
325



326
327
328
329
330
331
332
333
334
335
336
337

338

339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362
363
 * objects are duplicated and freed. Pointers to these procedures are kept
 * in the AuxData structure.
 */

typedef ClientData (AuxDataDupProc)  _ANSI_ARGS_((ClientData clientData));
typedef void       (AuxDataFreeProc) _ANSI_ARGS_((ClientData clientData));






















/*
 * The definition of the AuxData structure that holds information created
 * during compilation by CompileProcs and used by instructions during
 * execution.
 */

typedef struct AuxData {


    ClientData clientData;	/* The compilation data itself. */
    AuxDataDupProc *dupProc;	/* Callback procedure to invoke when the
				 * aux data is duplicated (e.g., when the
				 * ByteCode structure containing the aux
				 * data is duplicated). NULL means just
				 * copy the source clientData bits; no
				 * proc need be called. */
    AuxDataFreeProc *freeProc;	/* Callback procedure to invoke when the
				 * aux data is freed. NULL means no
				 * proc need be called. */
} AuxData;

/*
 * Structure defining the compilation environment. After compilation, fields
 * describing bytecode instructions are copied out into the more compact
 * ByteCode structure defined below.
 */

#define COMPILEENV_INIT_CODE_BYTES    250
#define COMPILEENV_INIT_NUM_OBJECTS    40
#define COMPILEENV_INIT_EXCEPT_RANGES   5
#define COMPILEENV_INIT_CMD_MAP_SIZE   40
#define COMPILEENV_INIT_AUX_DATA_SIZE   5

typedef struct CompileEnv {
    Interp *iPtr;		/* Interpreter containing the code being
				 * compiled. Commands and their compile
				 * procs are specific to an interpreter so
				 * the code emitted will depend on the
				 * interpreter. */
    char *source;		/* The source string being compiled by
				 * SetByteCodeFromAny. This pointer is not
				 * owned by the CompileEnv and must not be
				 * freed or changed by it. */

    Proc *procPtr;		/* If a procedure is being compiled, a
				 * pointer to its Proc structure; otherwise
				 * NULL. Used to compile local variables.
				 * Set from information provided by
				 * ObjInterpProc in tclProc.c. */
    int numCommands;		/* Number of commands compiled. */
    int excRangeDepth;		/* Current exception range nesting level;
				 * -1 if not in any range currently. */
    int maxExcRangeDepth;	/* Max nesting level of exception ranges;
				 * -1 if no ranges have been compiled. */
    int maxStackDepth;		/* Maximum number of stack elements needed
				 * to execute the code. Set by compilation
				 * procedures before returning. */

    Tcl_HashTable objTable;	/* Contains all Tcl objects referenced by
				 * the compiled code. Indexed by the string
				 * representations of the objects. Used to
				 * avoid creating duplicate objects. */
    int pushSimpleWords;	/* Set 1 by callers of compilation routines
				 * if they should emit instructions to push
				 * "simple" command words (those that are
				 * just a sequence of characters). If 0, the
				 * callers are responsible for compiling
				 * simple words. */
    int wordIsSimple;		/* Set 1 by compilation procedures before
				 * returning if the previous command word
				 * was just a sequence of characters,
				 * otherwise 0. Used to help determine the
				 * command being compiled. */
    int numSimpleWordChars;	/* If wordIsSimple is 1 then the number of
				 * characters in the simple word, else 0. */
    int exprIsJustVarRef;	/* Set 1 if the expression last compiled by
				 * TclCompileExpr consisted of just a
				 * variable reference as in the expression
				 * of "if $b then...". Otherwise 0. Used
				 * to implement expr's 2 level substitution
				 * semantics properly. */
    int exprIsComparison;	/* Set 1 if the top-level operator in the
				 * expression last compiled is a comparison.
				 * Otherwise 0. If 1, since the operands
				 * might be strings, the expr is compiled
				 * out-of-line to implement expr's 2 level
				 * substitution semantics properly. */
    int termOffset;		/* Offset of character just after the last
				 * one compiled. Set by compilation
				 * procedures before returning. */
    unsigned char *codeStart;	/* Points to the first byte of the code. */
    unsigned char *codeNext;	/* Points to next code array byte to use. */
    unsigned char *codeEnd;	/* Points just after the last allocated
				 * code array byte. */
    int mallocedCodeArray;      /* Set 1 if code array was expanded 
				 * and codeStart points into the heap.*/

    Tcl_Obj **objArrayPtr;	/* Points to start of object array. */
    int objArrayNext;		/* Index of next free object array entry. */
    int objArrayEnd;		/* Index just after last obj array entry. */
    int mallocedObjArray;       /* 1 if object array was expanded and
                                 * objArray points into the heap, else 0. */
    ExceptionRange *excRangeArrayPtr;
    				/* Points to start of the ExceptionRange
				 * array. */
    int excRangeArrayNext;	/* Next free ExceptionRange array index.
				 * excRangeArrayNext is the number of ranges
				 * and (excRangeArrayNext-1) is the index of
				 * the current range's array entry. */
    int excRangeArrayEnd;	/* Index after the last ExceptionRange
				 * array entry. */
    int mallocedExcRangeArray;	/* 1 if ExceptionRange array was expanded
				 * and excRangeArrayPtr points in heap,
				 * else 0. */
    CmdLocation *cmdMapPtr;	/* Points to start of CmdLocation array.
				 * numCommands is the index of the next
				 * entry to use; (numCommands-1) is the
				 * entry index for the last command. */
    int cmdMapEnd;		/* Index after last CmdLocation entry. */
    int mallocedCmdMap;		/* 1 if command map array was expanded and
				 * cmdMapPtr points in the heap, else 0. */
    AuxData *auxDataArrayPtr;   /* Points to auxiliary data array start. */
    int auxDataArrayNext;	/* Next free compile aux data array index.
				 * auxDataArrayNext is the number of aux
				 * data items and (auxDataArrayNext-1) is
				 * index of current aux data array entry. */
    int auxDataArrayEnd;	/* Index after last aux data array entry. */
    int mallocedAuxDataArray;	/* 1 if aux data array was expanded and
				 * auxDataArrayPtr points in heap else 0. */
    unsigned char staticCodeSpace[COMPILEENV_INIT_CODE_BYTES];
                                /* Initial storage for code. */
    Tcl_Obj *staticObjArraySpace[COMPILEENV_INIT_NUM_OBJECTS];
                                /* Initial storage for object array. */
    ExceptionRange staticExcRangeArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];
                                /* Initial ExceptionRange array storage. */
    CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE];
                                /* Initial storage for cmd location map. */
    AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE];
                                /* Initial storage for aux data array. */
} CompileEnv;

/*
 * The structure defining the bytecode instructions resulting from compiling
 * a Tcl script. Note that this structure is variable length: a single heap
 * object is allocated to hold the ByteCode structure immediately followed
 * by the code bytes, the object array, the ExceptionRange array, the
 * CmdLocation map, and the compilation AuxData array.
 */







typedef struct ByteCode {
    Interp *iPtr;		/* Interpreter containing the code being

				 * compiled. Commands and their compile
				 * procs are specific to an interpreter so
				 * the code emitted will depend on the
				 * interpreter. */
    int compileEpoch;		/* Value of iPtr->compileEpoch when this
				 * ByteCode was compiled. Used to invalidate
				 * code when, e.g., commands with compile
				 * procs are redefined. */








    int refCount;		/* Reference count: set 1 when created
				 * plus 1 for each execution of the code
				 * currently active. This structure can be
				 * freed when refCount becomes zero. */



    char *source;		/* The source string from which this
				 * ByteCode was compiled. Note that this
				 * pointer is not owned by the ByteCode and
				 * must not be freed or modified by it. */
    Proc *procPtr;		/* If the ByteCode was compiled from a
				 * procedure body, this is a pointer to its
				 * Proc structure; otherwise NULL. This
				 * pointer is also not owned by the ByteCode
				 * and must not be freed by it. Used for
				 * debugging. */
    size_t totalSize;		/* Total number of bytes required for this
				 * ByteCode structure including the storage

				 * for Tcl objects in its object array. */

    int numCommands;		/* Number of commands compiled. */
    int numSrcChars;		/* Number of source chars compiled. */
    int numCodeBytes;		/* Number of code bytes. */
    int numObjects;		/* Number of Tcl objects in object array. */
    int numExcRanges;		/* Number of ExceptionRange array elems. */
    int numAuxDataItems;	/* Number of AuxData items. */
    int numCmdLocBytes;		/* Number of bytes needed for encoded
				 * command location information. */
    int maxExcRangeDepth;	/* Maximum nesting level of ExceptionRanges;
				 * -1 if no ranges were compiled. */
    int maxStackDepth;		/* Maximum number of stack elements needed
				 * to execute the code. */
    unsigned char *codeStart;	/* Points to the first byte of the code.
				 * This is just after the final ByteCode
				 * member cmdMapPtr. */
    Tcl_Obj **objArrayPtr;	/* Points to the start of the object array.

				 * This is just after the last code byte. */
    ExceptionRange *excRangeArrayPtr;
    				/* Points to the start of the ExceptionRange
				 * array. This is just after the last
				 * object in the object array. */
    AuxData *auxDataArrayPtr;   /* Points to the start of the auxiliary data
				 * array. This is just after the last entry
				 * in the ExceptionRange array. */
    unsigned char *codeDeltaStart;







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







>
>

<
<
<
<
<
<
<
<
<









|














>






|

|




>
|
|
|

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












<
<
<






>
|
|
|
|

|


|
|
|

|

|
|


















|
|
|











|
|


>
>
>
>
>
>

<
>
|
|
|





>
>
>
>
>
>
>
>




>
>
>








|
<
<
|
>
|
>

|

|
|



|






|
>
|
|







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









176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218













219
220
221
222
223
224
225
226
227
228
229
230



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329


330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
 * objects are duplicated and freed. Pointers to these procedures are kept
 * in the AuxData structure.
 */

typedef ClientData (AuxDataDupProc)  _ANSI_ARGS_((ClientData clientData));
typedef void       (AuxDataFreeProc) _ANSI_ARGS_((ClientData clientData));

/*
 * We define a separate AuxDataType struct to hold type-related information
 * for the AuxData structure. This separation makes it possible for clients
 * outside of the TCL core to manipulate (in a limited fashion!) AuxData;
 * for example, it makes it possible to pickle and unpickle AuxData structs.
 */

typedef struct AuxDataType {
    char *name;					/* the name of the type. Types can be
                                 * registered and found by name */
    AuxDataDupProc *dupProc;	/* Callback procedure to invoke when the
                                 * aux data is duplicated (e.g., when the
                                 * ByteCode structure containing the aux
                                 * data is duplicated). NULL means just
                                 * copy the source clientData bits; no
                                 * proc need be called. */
    AuxDataFreeProc *freeProc;	/* Callback procedure to invoke when the
                                 * aux data is freed. NULL means no
                                 * proc need be called. */
} AuxDataType;

/*
 * The definition of the AuxData structure that holds information created
 * during compilation by CompileProcs and used by instructions during
 * execution.
 */

typedef struct AuxData {
    AuxDataType *type;		/* pointer to the AuxData type associated with
                             * this ClientData. */
    ClientData clientData;	/* The compilation data itself. */









} AuxData;

/*
 * Structure defining the compilation environment. After compilation, fields
 * describing bytecode instructions are copied out into the more compact
 * ByteCode structure defined below.
 */

#define COMPILEENV_INIT_CODE_BYTES    250
#define COMPILEENV_INIT_NUM_OBJECTS    60
#define COMPILEENV_INIT_EXCEPT_RANGES   5
#define COMPILEENV_INIT_CMD_MAP_SIZE   40
#define COMPILEENV_INIT_AUX_DATA_SIZE   5

typedef struct CompileEnv {
    Interp *iPtr;		/* Interpreter containing the code being
				 * compiled. Commands and their compile
				 * procs are specific to an interpreter so
				 * the code emitted will depend on the
				 * interpreter. */
    char *source;		/* The source string being compiled by
				 * SetByteCodeFromAny. This pointer is not
				 * owned by the CompileEnv and must not be
				 * freed or changed by it. */
    int numSrcBytes;		/* Number of bytes in source. */
    Proc *procPtr;		/* If a procedure is being compiled, a
				 * pointer to its Proc structure; otherwise
				 * NULL. Used to compile local variables.
				 * Set from information provided by
				 * ObjInterpProc in tclProc.c. */
    int numCommands;		/* Number of commands compiled. */
    int exceptDepth;		/* Current exception range nesting level;
				 * -1 if not in any range currently. */
    int maxExceptDepth;		/* Max nesting level of exception ranges;
				 * -1 if no ranges have been compiled. */
    int maxStackDepth;		/* Maximum number of stack elements needed
				 * to execute the code. Set by compilation
				 * procedures before returning. */
    LiteralTable localLitTable;	/* Contains LiteralEntry's describing
				 * all Tcl objects referenced by this
				 * compiled code. Indexed by the string
				 * representations of the literals. Used to
				 * avoid creating duplicate objects. */













    int exprIsJustVarRef;	/* Set 1 if the expression last compiled by
				 * TclCompileExpr consisted of just a
				 * variable reference as in the expression
				 * of "if $b then...". Otherwise 0. Used
				 * to implement expr's 2 level substitution
				 * semantics properly. */
    int exprIsComparison;	/* Set 1 if the top-level operator in the
				 * expression last compiled is a comparison.
				 * Otherwise 0. If 1, since the operands
				 * might be strings, the expr is compiled
				 * out-of-line to implement expr's 2 level
				 * substitution semantics properly. */



    unsigned char *codeStart;	/* Points to the first byte of the code. */
    unsigned char *codeNext;	/* Points to next code array byte to use. */
    unsigned char *codeEnd;	/* Points just after the last allocated
				 * code array byte. */
    int mallocedCodeArray;      /* Set 1 if code array was expanded 
				 * and codeStart points into the heap.*/
    LiteralEntry *literalArrayPtr;
    				/* Points to start of LiteralEntry array. */
    int literalArrayNext;	/* Index of next free object array entry. */
    int literalArrayEnd;	/* Index just after last obj array entry. */
    int mallocedLiteralArray;   /* 1 if object array was expanded and
                                 * objArray points into the heap, else 0. */
    ExceptionRange *exceptArrayPtr;
    				/* Points to start of the ExceptionRange
				 * array. */
    int exceptArrayNext;	/* Next free ExceptionRange array index.
				 * exceptArrayNext is the number of ranges
				 * and (exceptArrayNext-1) is the index of
				 * the current range's array entry. */
    int exceptArrayEnd;		/* Index after the last ExceptionRange
				 * array entry. */
    int mallocedExceptArray;	/* 1 if ExceptionRange array was expanded
				 * and exceptArrayPtr points in heap,
				 * else 0. */
    CmdLocation *cmdMapPtr;	/* Points to start of CmdLocation array.
				 * numCommands is the index of the next
				 * entry to use; (numCommands-1) is the
				 * entry index for the last command. */
    int cmdMapEnd;		/* Index after last CmdLocation entry. */
    int mallocedCmdMap;		/* 1 if command map array was expanded and
				 * cmdMapPtr points in the heap, else 0. */
    AuxData *auxDataArrayPtr;   /* Points to auxiliary data array start. */
    int auxDataArrayNext;	/* Next free compile aux data array index.
				 * auxDataArrayNext is the number of aux
				 * data items and (auxDataArrayNext-1) is
				 * index of current aux data array entry. */
    int auxDataArrayEnd;	/* Index after last aux data array entry. */
    int mallocedAuxDataArray;	/* 1 if aux data array was expanded and
				 * auxDataArrayPtr points in heap else 0. */
    unsigned char staticCodeSpace[COMPILEENV_INIT_CODE_BYTES];
                                /* Initial storage for code. */
    LiteralEntry staticLiteralSpace[COMPILEENV_INIT_NUM_OBJECTS];
                                /* Initial storage of LiteralEntry array. */
    ExceptionRange staticExceptArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];
                                /* Initial ExceptionRange array storage. */
    CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE];
                                /* Initial storage for cmd location map. */
    AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE];
                                /* Initial storage for aux data array. */
} CompileEnv;

/*
 * The structure defining the bytecode instructions resulting from compiling
 * a Tcl script. Note that this structure is variable length: a single heap
 * object is allocated to hold the ByteCode structure immediately followed
 * by the code bytes, the literal object array, the ExceptionRange array,
 * the CmdLocation map, and the compilation AuxData array.
 */

/*
 * A PRECOMPILED bytecode struct is one that was generated from a compiled
 * image rather than implicitly compiled from source
 */
#define TCL_BYTECODE_PRECOMPILED		0x0001

typedef struct ByteCode {

    TclHandle interpHandle;	/* Handle for interpreter containing the
				 * compiled code.  Commands and their compile
				 * procs are specific to an interpreter so the
				 * code emitted will depend on the
				 * interpreter. */
    int compileEpoch;		/* Value of iPtr->compileEpoch when this
				 * ByteCode was compiled. Used to invalidate
				 * code when, e.g., commands with compile
				 * procs are redefined. */
    Namespace *nsPtr;		/* Namespace context in which this code
				 * was compiled. If the code is executed
				 * if a different namespace, it must be
				 * recompiled. */
    int nsEpoch;		/* Value of nsPtr->resolverEpoch when this
				 * ByteCode was compiled. Used to invalidate
				 * code when new namespace resolution rules
				 * are put into effect. */
    int refCount;		/* Reference count: set 1 when created
				 * plus 1 for each execution of the code
				 * currently active. This structure can be
				 * freed when refCount becomes zero. */
    unsigned int flags;		/* flags describing state for the codebyte.
                                 * this variable holds ORed values from the
                                 * TCL_BYTECODE_ masks defined above */
    char *source;		/* The source string from which this
				 * ByteCode was compiled. Note that this
				 * pointer is not owned by the ByteCode and
				 * must not be freed or modified by it. */
    Proc *procPtr;		/* If the ByteCode was compiled from a
				 * procedure body, this is a pointer to its
				 * Proc structure; otherwise NULL. This
				 * pointer is also not owned by the ByteCode
				 * and must not be freed by it. */


    size_t structureSize;	/* Number of bytes in the ByteCode structure
				 * itself. Does not include heap space for
				 * literal Tcl objects or storage referenced
				 * by AuxData entries. */
    int numCommands;		/* Number of commands compiled. */
    int numSrcBytes;		/* Number of source bytes compiled. */
    int numCodeBytes;		/* Number of code bytes. */
    int numLitObjects;		/* Number of objects in literal array. */
    int numExceptRanges;	/* Number of ExceptionRange array elems. */
    int numAuxDataItems;	/* Number of AuxData items. */
    int numCmdLocBytes;		/* Number of bytes needed for encoded
				 * command location information. */
    int maxExceptDepth;		/* Maximum nesting level of ExceptionRanges;
				 * -1 if no ranges were compiled. */
    int maxStackDepth;		/* Maximum number of stack elements needed
				 * to execute the code. */
    unsigned char *codeStart;	/* Points to the first byte of the code.
				 * This is just after the final ByteCode
				 * member cmdMapPtr. */
    Tcl_Obj **objArrayPtr;	/* Points to the start of the literal
				 * object array. This is just after the
				 * last code byte. */
    ExceptionRange *exceptArrayPtr;
    				/* Points to the start of the ExceptionRange
				 * array. This is just after the last
				 * object in the object array. */
    AuxData *auxDataArrayPtr;   /* Points to the start of the auxiliary data
				 * array. This is just after the last entry
				 * in the ExceptionRange array. */
    unsigned char *codeDeltaStart;
390
391
392
393
394
395
396




397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
				/* Points to the first of a sequence of
				 * bytes that encode the length of each
				 * command's source. The encoding is the
				 * same as for code deltas. Source lengths
				 * are always positive. This sequence is
				 * just after the last byte in the source
				 * delta sequence. */




} ByteCode;

/*
 * Opcodes for the Tcl bytecode instructions. These opcodes must correspond
 * to the entries in the table of instruction descriptions in tclCompile.c.
 * Also, the order and number of the expression opcodes (e.g., INST_LOR)
 * must match the entries in the array operatorStrings in tclExecute.c.

 */

/* Opcodes 0 to 9 */
#define INST_DONE			0
#define INST_PUSH1			(INST_DONE + 1)
#define INST_PUSH4			(INST_DONE + 2)
#define INST_POP			(INST_DONE + 3)
#define INST_DUP			(INST_DONE + 4)
#define INST_CONCAT1			(INST_DONE + 5)
#define INST_INVOKE_STK1		(INST_DONE + 6)
#define INST_INVOKE_STK4		(INST_DONE + 7)
#define INST_EVAL_STK			(INST_DONE + 8)
#define INST_EXPR_STK			(INST_DONE + 9)

/* Opcodes 10 to 23 */
#define INST_LOAD_SCALAR1		(INST_EXPR_STK + 1)
#define INST_LOAD_SCALAR4		(INST_LOAD_SCALAR1 + 1)
#define INST_LOAD_SCALAR_STK		(INST_LOAD_SCALAR1 + 2)
#define INST_LOAD_ARRAY1		(INST_LOAD_SCALAR1 + 3)
#define INST_LOAD_ARRAY4		(INST_LOAD_SCALAR1 + 4)
#define INST_LOAD_ARRAY_STK		(INST_LOAD_SCALAR1 + 5)
#define INST_LOAD_STK			(INST_LOAD_SCALAR1 + 6)
#define INST_STORE_SCALAR1		(INST_LOAD_SCALAR1 + 7)
#define INST_STORE_SCALAR4		(INST_LOAD_SCALAR1 + 8)
#define INST_STORE_SCALAR_STK		(INST_LOAD_SCALAR1 + 9)
#define INST_STORE_ARRAY1		(INST_LOAD_SCALAR1 + 10)
#define INST_STORE_ARRAY4		(INST_LOAD_SCALAR1 + 11)
#define INST_STORE_ARRAY_STK		(INST_LOAD_SCALAR1 + 12)
#define INST_STORE_STK			(INST_LOAD_SCALAR1 + 13)

/* Opcodes 24 to 33 */
#define INST_INCR_SCALAR1		(INST_STORE_STK + 1)
#define INST_INCR_SCALAR_STK		(INST_INCR_SCALAR1 + 1)
#define INST_INCR_ARRAY1		(INST_INCR_SCALAR1 + 2)
#define INST_INCR_ARRAY_STK		(INST_INCR_SCALAR1 + 3)
#define INST_INCR_STK			(INST_INCR_SCALAR1 + 4)
#define INST_INCR_SCALAR1_IMM		(INST_INCR_SCALAR1 + 5)
#define INST_INCR_SCALAR_STK_IMM	(INST_INCR_SCALAR1 + 6)
#define INST_INCR_ARRAY1_IMM		(INST_INCR_SCALAR1 + 7)
#define INST_INCR_ARRAY_STK_IMM		(INST_INCR_SCALAR1 + 8)
#define INST_INCR_STK_IMM		(INST_INCR_SCALAR1 + 9)

/* Opcodes 34 to 39 */
#define INST_JUMP1			(INST_INCR_STK_IMM + 1)
#define INST_JUMP4			(INST_JUMP1 + 1)
#define INST_JUMP_TRUE1			(INST_JUMP1 + 2)
#define INST_JUMP_TRUE4			(INST_JUMP1 + 3)
#define INST_JUMP_FALSE1		(INST_JUMP1 + 4)
#define INST_JUMP_FALSE4	        (INST_JUMP1 + 5)

/* Opcodes 40 to 64 */
#define INST_LOR			(INST_JUMP_FALSE4 + 1)
#define INST_LAND			(INST_LOR + 1)
#define INST_BITOR			(INST_LOR + 2)
#define INST_BITXOR			(INST_LOR + 3)
#define INST_BITAND			(INST_LOR + 4)
#define INST_EQ				(INST_LOR + 5)
#define INST_NEQ			(INST_LOR + 6)
#define INST_LT				(INST_LOR + 7)
#define INST_GT				(INST_LOR + 8)
#define INST_LE				(INST_LOR + 9)
#define INST_GE				(INST_LOR + 10)
#define INST_LSHIFT			(INST_LOR + 11)
#define INST_RSHIFT			(INST_LOR + 12)
#define INST_ADD			(INST_LOR + 13)
#define INST_SUB			(INST_LOR + 14)
#define INST_MULT			(INST_LOR + 15)
#define INST_DIV			(INST_LOR + 16)
#define INST_MOD			(INST_LOR + 17)
#define INST_UPLUS			(INST_LOR + 18)
#define INST_UMINUS			(INST_LOR + 19)
#define INST_BITNOT			(INST_LOR + 20)
#define INST_LNOT			(INST_LOR + 21)
#define INST_CALL_BUILTIN_FUNC1		(INST_LOR + 22)
#define INST_CALL_FUNC1			(INST_LOR + 23)
#define INST_TRY_CVT_TO_NUMERIC		(INST_LOR + 24)

/* Opcodes 65 to 66 */
#define INST_BREAK			(INST_TRY_CVT_TO_NUMERIC + 1)
#define INST_CONTINUE			(INST_BREAK + 1)

/* Opcodes 67 to 68 */
#define INST_FOREACH_START4		(INST_CONTINUE + 1)
#define INST_FOREACH_STEP4		(INST_FOREACH_START4 + 1)

/* Opcodes 69 to 72 */
#define INST_BEGIN_CATCH4		(INST_FOREACH_STEP4 + 1)
#define INST_END_CATCH			(INST_BEGIN_CATCH4 + 1)
#define INST_PUSH_RESULT		(INST_BEGIN_CATCH4 + 2)
#define INST_PUSH_RETURN_CODE		(INST_BEGIN_CATCH4 + 3)

/* The last opcode */
#define LAST_INST_OPCODE        	INST_PUSH_RETURN_CODE

/*
 * Table describing the Tcl bytecode instructions: their name (for
 * displaying code), total number of code bytes required (including
 * operand bytes), and a description of the type of each operand.
 * These operand types include signed and unsigned integers of length
 * one and four bytes. The unsigned integers are used for indexes or







>
>
>
>



|
|
|
|
>




|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|


|
|


|
|
|
|


|







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
				/* Points to the first of a sequence of
				 * bytes that encode the length of each
				 * command's source. The encoding is the
				 * same as for code deltas. Source lengths
				 * are always positive. This sequence is
				 * just after the last byte in the source
				 * delta sequence. */
#ifdef TCL_COMPILE_STATS
    Tcl_Time createTime;	/* Absolute time when the ByteCode was
				 * created. */
#endif /* TCL_COMPILE_STATS */
} ByteCode;

/*
 * Opcodes for the Tcl bytecode instructions. These must correspond to the
 * entries in the table of instruction descriptions, instructionTable, in
 * tclCompile.c. Also, the order and number of the expression opcodes
 * (e.g., INST_LOR) must match the entries in the array operatorStrings in
 * tclExecute.c.
 */

/* Opcodes 0 to 9 */
#define INST_DONE			0
#define INST_PUSH1			1
#define INST_PUSH4			2
#define INST_POP			3
#define INST_DUP			4
#define INST_CONCAT1			5
#define INST_INVOKE_STK1		6
#define INST_INVOKE_STK4		7
#define INST_EVAL_STK			8
#define INST_EXPR_STK			9

/* Opcodes 10 to 23 */
#define INST_LOAD_SCALAR1		10
#define INST_LOAD_SCALAR4		11
#define INST_LOAD_SCALAR_STK		12
#define INST_LOAD_ARRAY1		13
#define INST_LOAD_ARRAY4		14
#define INST_LOAD_ARRAY_STK		15
#define INST_LOAD_STK			16
#define INST_STORE_SCALAR1		17
#define INST_STORE_SCALAR4		18
#define INST_STORE_SCALAR_STK		19
#define INST_STORE_ARRAY1		20
#define INST_STORE_ARRAY4		21
#define INST_STORE_ARRAY_STK		22
#define INST_STORE_STK			23

/* Opcodes 24 to 33 */
#define INST_INCR_SCALAR1		24
#define INST_INCR_SCALAR_STK		25
#define INST_INCR_ARRAY1		26
#define INST_INCR_ARRAY_STK		27
#define INST_INCR_STK			28
#define INST_INCR_SCALAR1_IMM		29
#define INST_INCR_SCALAR_STK_IMM	30
#define INST_INCR_ARRAY1_IMM		31
#define INST_INCR_ARRAY_STK_IMM		32
#define INST_INCR_STK_IMM		33

/* Opcodes 34 to 39 */
#define INST_JUMP1			34
#define INST_JUMP4			35
#define INST_JUMP_TRUE1			36
#define INST_JUMP_TRUE4			37
#define INST_JUMP_FALSE1		38
#define INST_JUMP_FALSE4	        39

/* Opcodes 40 to 64 */
#define INST_LOR			40
#define INST_LAND			41
#define INST_BITOR			42
#define INST_BITXOR			43
#define INST_BITAND			44
#define INST_EQ				45
#define INST_NEQ			46
#define INST_LT				47
#define INST_GT				48
#define INST_LE				49
#define INST_GE				50
#define INST_LSHIFT			51
#define INST_RSHIFT			52
#define INST_ADD			53
#define INST_SUB			54
#define INST_MULT			55
#define INST_DIV			56
#define INST_MOD			57
#define INST_UPLUS			58
#define INST_UMINUS			59
#define INST_BITNOT			60
#define INST_LNOT			61
#define INST_CALL_BUILTIN_FUNC1		62
#define INST_CALL_FUNC1			63
#define INST_TRY_CVT_TO_NUMERIC		64

/* Opcodes 65 to 66 */
#define INST_BREAK			65
#define INST_CONTINUE			66

/* Opcodes 67 to 68 */
#define INST_FOREACH_START4		67
#define INST_FOREACH_STEP4		68

/* Opcodes 69 to 72 */
#define INST_BEGIN_CATCH4		69
#define INST_END_CATCH			70
#define INST_PUSH_RESULT		71
#define INST_PUSH_RETURN_CODE		72

/* The last opcode */
#define LAST_INST_OPCODE        	72

/*
 * Table describing the Tcl bytecode instructions: their name (for
 * displaying code), total number of code bytes required (including
 * operand bytes), and a description of the type of each operand.
 * These operand types include signed and unsigned integers of length
 * one and four bytes. The unsigned integers are used for indexes or
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
#define BUILTIN_FUNC_ABS		19
#define BUILTIN_FUNC_DOUBLE		20
#define BUILTIN_FUNC_INT		21
#define BUILTIN_FUNC_RAND		22
#define BUILTIN_FUNC_ROUND		23
#define BUILTIN_FUNC_SRAND		24

#define LAST_BUILTIN_FUNC        	BUILTIN_FUNC_SRAND

/*
 * Table describing the built-in math functions. Entries in this table are
 * indexed by the values of the INST_CALL_BUILTIN_FUNC instruction's
 * operand byte.
 */








|







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
#define BUILTIN_FUNC_ABS		19
#define BUILTIN_FUNC_DOUBLE		20
#define BUILTIN_FUNC_INT		21
#define BUILTIN_FUNC_RAND		22
#define BUILTIN_FUNC_ROUND		23
#define BUILTIN_FUNC_SRAND		24

#define LAST_BUILTIN_FUNC        	24

/*
 * Table describing the built-in math functions. Entries in this table are
 * indexed by the values of the INST_CALL_BUILTIN_FUNC instruction's
 * operand byte.
 */

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
    CallBuiltinFuncProc *proc;	/* Procedure implementing this function. */
    ClientData clientData;	/* Additional argument to pass to the
				 * function when invoking it. */
} BuiltinFunc;

extern BuiltinFunc builtinFuncTable[];

/*
 * The structure used to hold information about the start and end of each
 * argument word in a command. 
 */

#define ARGINFO_INIT_ENTRIES 5

typedef struct ArgInfo {
    int numArgs;		/* Number of argument words in command. */
    char **startArray;		/* Array of pointers to the first character
				 * of each argument word. */
    char **endArray;		/* Array of pointers to the last character
				 * of each argument word. */
    int allocArgs;		/* Number of array entries currently
				 * allocated. */
    int mallocedArrays;		/* 1 if the arrays were expanded and
				 * wordStartArray/wordEndArray point into
				 * the heap, else 0. */
    char *staticStartSpace[ARGINFO_INIT_ENTRIES];
                                /* Initial storage for word start array. */
    char *staticEndSpace[ARGINFO_INIT_ENTRIES];
                                /* Initial storage for word end array. */
} ArgInfo;

/*
 * Compilation of some Tcl constructs such as if commands and the logical or
 * (||) and logical and (&&) operators in expressions requires the
 * generation of forward jumps. Since the PC target of these jumps isn't
 * known when the jumps are emitted, we record the offset of each jump in an
 * array of JumpFixup structures. There is one array for each sequence of
 * jumps to one target PC. When we learn the target PC, we update the jumps







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







578
579
580
581
582
583
584
























585
586
587
588
589
590
591
    CallBuiltinFuncProc *proc;	/* Procedure implementing this function. */
    ClientData clientData;	/* Additional argument to pass to the
				 * function when invoking it. */
} BuiltinFunc;

extern BuiltinFunc builtinFuncTable[];

























/*
 * Compilation of some Tcl constructs such as if commands and the logical or
 * (||) and logical and (&&) operators in expressions requires the
 * generation of forward jumps. Since the PC target of these jumps isn't
 * known when the jumps are emitted, we record the offset of each jump in an
 * array of JumpFixup structures. There is one array for each sequence of
 * jumps to one target PC. When we learn the target PC, we update the jumps
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
    int codeOffset;		/* Offset of the first byte of the one-byte
				 * forward jump's code. */
    int cmdIndex;		/* Index of the first command after the one
				 * for which the jump was emitted. Used to
				 * update the code offsets for subsequent
				 * commands if the two-byte jump at jumpPc
				 * must be replaced with a five-byte one. */
    int excRangeIndex;		/* Index of the first range entry in the
				 * ExceptionRange array after the current
				 * one. This field is used to adjust the
				 * code offsets in subsequent ExceptionRange
				 * records when a jump is grown from 2 bytes
				 * to 5 bytes. */
} JumpFixup;








|







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
    int codeOffset;		/* Offset of the first byte of the one-byte
				 * forward jump's code. */
    int cmdIndex;		/* Index of the first command after the one
				 * for which the jump was emitted. Used to
				 * update the code offsets for subsequent
				 * commands if the two-byte jump at jumpPc
				 * must be replaced with a five-byte one. */
    int exceptIndex;		/* Index of the first range entry in the
				 * ExceptionRange array after the current
				 * one. This field is used to adjust the
				 * code offsets in subsequent ExceptionRange
				 * records when a jump is grown from 2 bytes
				 * to 5 bytes. */
} JumpFixup;

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
 * during program execution. These structures are stored in CompileEnv and
 * ByteCode structures as auxiliary data.
 */

typedef struct ForeachInfo {
    int numLists;		/* The number of both the variable and value
				 * lists of the foreach command. */
    int firstListTmp;		/* The slot number of the first temporary
				 * variable holding the lists themselves. */
    int loopIterNumTmp;		/* The slot number of the temp var holding
				 * the count of times the loop body has been
				 * executed. This is used to determine which
				 * list element to assign each loop var. */
    ForeachVarList *varLists[1];/* An array of pointers to ForeachVarList
				 * structures describing each var list. The
				 * actual size of this field will be large
				 * enough to numVars indexes. THIS MUST BE
				 * THE LAST FIELD IN THE STRUCTURE! */
} ForeachInfo;



/*
 * Structure containing a cached pointer to a command that is the result
 * of resolving the command's name in some namespace. It is the internal
 * representation for a cmdName object. It contains the pointer along
 * with some information that is used to check the pointer's validity.
 */







|
|
|
|
|
|






>
>







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
 * during program execution. These structures are stored in CompileEnv and
 * ByteCode structures as auxiliary data.
 */

typedef struct ForeachInfo {
    int numLists;		/* The number of both the variable and value
				 * lists of the foreach command. */
    int firstValueTemp;		/* Index of the first temp var in a proc
				 * frame used to point to a value list. */
    int loopCtTemp;		/* Index of temp var in a proc frame
				 * holding the loop's iteration count. Used
				 * to determine next value list element to
				 * assign each loop var. */
    ForeachVarList *varLists[1];/* An array of pointers to ForeachVarList
				 * structures describing each var list. The
				 * actual size of this field will be large
				 * enough to numVars indexes. THIS MUST BE
				 * THE LAST FIELD IN THE STRUCTURE! */
} ForeachInfo;

extern AuxDataType		tclForeachInfoType;

/*
 * Structure containing a cached pointer to a command that is the result
 * of resolving the command's name in some namespace. It is the internal
 * representation for a cmdName object. It contains the pointer along
 * with some information that is used to check the pointer's validity.
 */
732
733
734
735
736
737
738



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

753
754
755


756
757

758
759
760

761
762
763
764
765
766






767
768
769
770
771
772

773
774

775
776

777
778


779


780
781

782
783
784

785
786


787
788













789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822

823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852


853
854
855
856
857
858
859
860
861
862
863
864
865

866

867
868
869
870

871

872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
 *----------------------------------------------------------------
 * Procedures shared among Tcl bytecode compilation and execution
 * modules but not used outside:
 *----------------------------------------------------------------
 */

EXTERN void		TclCleanupByteCode _ANSI_ARGS_((ByteCode *codePtr));



EXTERN int		TclCompileExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char *lastChar, int flags,
			    CompileEnv *envPtr));
EXTERN int		TclCompileQuotes _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char *lastChar, int termChar,
			    int flags, CompileEnv *envPtr));
EXTERN int		TclCompileString _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char *lastChar, int flags,
			    CompileEnv *envPtr));
EXTERN int		TclCompileDollarVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char *lastChar, int flags,
			    CompileEnv *envPtr));
EXTERN int		TclCreateAuxData _ANSI_ARGS_((
			    ClientData clientData, AuxDataDupProc *dupProc,

			    AuxDataFreeProc *freeProc, CompileEnv *envPtr));
EXTERN ExecEnv *	TclCreateExecEnv _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void		TclDeleteExecEnv _ANSI_ARGS_((ExecEnv *eePtr));


EXTERN void		TclEmitForwardJump _ANSI_ARGS_((CompileEnv *envPtr,
			    TclJumpType jumpType, JumpFixup *jumpFixupPtr));

EXTERN ExceptionRange *	TclGetExceptionRangeForPc _ANSI_ARGS_((
			    unsigned char *pc, int catchOnly,
			    ByteCode* codePtr));

EXTERN int		TclExecuteByteCode _ANSI_ARGS_((Tcl_Interp *interp,
			    ByteCode *codePtr));
EXTERN void		TclExpandCodeArray _ANSI_ARGS_((
                            CompileEnv *envPtr));
EXTERN void		TclExpandJumpFixupArray _ANSI_ARGS_((
                            JumpFixupArray *fixupArrayPtr));






EXTERN int		TclFixupForwardJump _ANSI_ARGS_((
			    CompileEnv *envPtr, JumpFixup *jumpFixupPtr,
			    int jumpDist, int distThreshold));
EXTERN void		TclFreeCompileEnv _ANSI_ARGS_((CompileEnv *envPtr));
EXTERN void		TclFreeJumpFixupArray _ANSI_ARGS_((
  			    JumpFixupArray *fixupArrayPtr));

EXTERN void		TclInitByteCodeObj _ANSI_ARGS_((Tcl_Obj *objPtr,
			    CompileEnv *envPtr));

EXTERN void		TclInitCompileEnv _ANSI_ARGS_((Tcl_Interp *interp,
			    CompileEnv *envPtr, char *string));

EXTERN void		TclInitJumpFixupArray _ANSI_ARGS_((
			    JumpFixupArray *fixupArrayPtr));


#ifdef TCL_COMPILE_STATS


EXTERN int		TclLog2 _ANSI_ARGS_((int value));
#endif /*TCL_COMPILE_STATS*/

EXTERN int		TclObjIndexForString _ANSI_ARGS_((char *start,
			    int length, int allocStrRep, int inHeap,
			    CompileEnv *envPtr));

EXTERN int		TclPrintInstruction _ANSI_ARGS_((ByteCode* codePtr,
			    unsigned char *pc));


EXTERN void		TclPrintSource _ANSI_ARGS_((FILE *outFile,
			    char *string, int maxChars));














/*
 *----------------------------------------------------------------
 * Macros used by Tcl bytecode compilation and execution modules
 * inside the Tcl core but not used outside.
 *----------------------------------------------------------------
 */

/*
 * Macros to ensure there is enough room in a CompileEnv's code array.
 * The ANSI C "prototypes" for these macros are:
 *
 * EXTERN void	TclEnsureCodeSpace1 _ANSI_ARGS_((CompileEnv *envPtr));
 * EXTERN void	TclEnsureCodeSpace _ANSI_ARGS_((int nBytes,
 *		    CompileEnv *envPtr));
 */

#define TclEnsureCodeSpace1(envPtr) \
    if ((envPtr)->codeNext == (envPtr)->codeEnd) \
        TclExpandCodeArray(envPtr)

#define TclEnsureCodeSpace(nBytes, envPtr) \
    if (((envPtr)->codeNext + nBytes) > (envPtr)->codeEnd) \
        TclExpandCodeArray(envPtr)

/*
 * Macro to emit an opcode byte into a CompileEnv's code array.
 * The ANSI C "prototype" for this macro is:
 *
 * EXTERN void	TclEmitOpcode _ANSI_ARGS_((unsigned char op,
 *		    CompileEnv *envPtr));
 */

#define TclEmitOpcode(op, envPtr) \

    TclEnsureCodeSpace1(envPtr); \
    *(envPtr)->codeNext++ = (unsigned char) (op)

/*
 * Macros to emit a (signed or unsigned) int operand. The two variants
 * depend on the number of bytes needed for the int. Four byte integers
 * are stored in "big-endian" order with the high order byte stored at
 * the lowest address. The ANSI C "prototypes" for these macros are:
 *
 * EXTERN void	TclEmitInt1 _ANSI_ARGS_((int i, CompileEnv *envPtr));
 * EXTERN void	TclEmitInt4 _ANSI_ARGS_((int i, CompileEnv *envPtr));
 */

#define TclEmitInt1(i, envPtr) \
    TclEnsureCodeSpace(1, (envPtr)); \
    *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))

#define TclEmitInt4(i, envPtr) \
    TclEnsureCodeSpace(4, (envPtr)); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i) >> 24); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i) >> 16); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i) >>  8); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i)      )

/*
 * Macros to emit an instruction with signed or unsigned int operands.


 * The ANSI C "prototypes" for these macros are:
 *
 * EXTERN void	TclEmitInstInt1 _ANSI_ARGS_((unsigned char op, int i, 
 *		    CompileEnv *envPtr));
 * EXTERN void	TclEmitInstInt4 _ANSI_ARGS_((unsigned char op, int i, 
 *		    CompileEnv *envPtr));
 * EXTERN void	TclEmitInstUInt1 _ANSI_ARGS_((unsigned char op,
 *		    unsigned int i, CompileEnv *envPtr));
 * EXTERN void	TclEmitInstUInt4 _ANSI_ARGS_((unsigned char op,
 *		    unsigned int i, CompileEnv *envPtr));
 */

#define TclEmitInstInt1(op, i, envPtr) \

    TclEnsureCodeSpace(2, (envPtr)); \

    *(envPtr)->codeNext++ = (unsigned char) (op); \
    *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))

#define TclEmitInstInt4(op, i, envPtr) \

    TclEnsureCodeSpace(5, (envPtr)); \

    *(envPtr)->codeNext++ = (unsigned char) (op); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i) >> 24); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i) >> 16); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i) >>  8); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i)      )
    
#define TclEmitInstUInt1(op, i, envPtr) \
    TclEmitInstInt1((op), (i), (envPtr))

#define TclEmitInstUInt4(op, i, envPtr) \
    TclEmitInstInt4((op), (i), (envPtr))
    
/*
 * Macro to push a Tcl object onto the Tcl evaluation stack. It emits the
 * object's one or four byte array index into the CompileEnv's code
 * array. These support, respectively, a maximum of 256 (2**8) and 2**32
 * objects in a CompileEnv. The ANSI C "prototype" for this macro is:
 *
 * EXTERN void	TclEmitPush _ANSI_ARGS_((int objIndex, CompileEnv *envPtr));
 */

#define TclEmitPush(objIndex, envPtr) \
    if ((objIndex) <= 255) { \
	TclEmitInstUInt1(INST_PUSH1, (objIndex), (envPtr)); \
    } else { \
	TclEmitInstUInt4(INST_PUSH4, (objIndex), (envPtr)); \
    }

/*
 * Macros to update a (signed or unsigned) integer starting at a pointer.
 * The two variants depend on the number of bytes. The ANSI C "prototypes"
 * for these macros are:
 *







>
>
>

|

|
|
|
|
|

|
|

|
|
>
|


>
>


>



>



|


>
>
>
>
>
>






>


>

|
>


>
>

>
>

|
>
|
<
|
>


>
>


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








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









>
|



|
<
<
|


<



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


|
>
>






<
<
<
<



>
|
>




>
|
>










<
<
<
<
<
<











|

|







711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812

















813
814
815
816
817
818
819
820
821
822
823
824
825
826
827


828
829
830

831
832
833





834

835

836



837
838
839
840
841
842
843
844
845
846
847




848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870






871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
 *----------------------------------------------------------------
 * Procedures shared among Tcl bytecode compilation and execution
 * modules but not used outside:
 *----------------------------------------------------------------
 */

EXTERN void		TclCleanupByteCode _ANSI_ARGS_((ByteCode *codePtr));
EXTERN int		TclCompileCmdWord _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Token *tokenPtr, int count,
			    CompileEnv *envPtr));
EXTERN int		TclCompileExpr _ANSI_ARGS_((Tcl_Interp *interp,
			    char *script, int numBytes,
			    CompileEnv *envPtr));
EXTERN int		TclCompileExprWords _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Token *tokenPtr, int numWords,
			    CompileEnv *envPtr));
EXTERN int		TclCompileScript _ANSI_ARGS_((Tcl_Interp *interp,
			    char *script, int numBytes, int nested,
			    CompileEnv *envPtr));
EXTERN int		TclCompileTokens _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Token *tokenPtr, int count,
			    CompileEnv *envPtr));
EXTERN int		TclCreateAuxData _ANSI_ARGS_((ClientData clientData,
			    AuxDataType *typePtr, CompileEnv *envPtr));
EXTERN int		TclCreateExceptRange _ANSI_ARGS_((
			    ExceptionRangeType type, CompileEnv *envPtr));
EXTERN ExecEnv *	TclCreateExecEnv _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void		TclDeleteExecEnv _ANSI_ARGS_((ExecEnv *eePtr));
EXTERN void		TclDeleteLiteralTable _ANSI_ARGS_((
			    Tcl_Interp *interp, LiteralTable *tablePtr));
EXTERN void		TclEmitForwardJump _ANSI_ARGS_((CompileEnv *envPtr,
			    TclJumpType jumpType, JumpFixup *jumpFixupPtr));
EXTERN AuxDataType *TclGetAuxDataType _ANSI_ARGS_((char *typeName));
EXTERN ExceptionRange *	TclGetExceptionRangeForPc _ANSI_ARGS_((
			    unsigned char *pc, int catchOnly,
			    ByteCode* codePtr));
EXTERN InstructionDesc * TclGetInstructionTable _ANSI_ARGS_(());
EXTERN int		TclExecuteByteCode _ANSI_ARGS_((Tcl_Interp *interp,
			    ByteCode *codePtr));
EXTERN void		TclExpandCodeArray _ANSI_ARGS_((
			    CompileEnv *envPtr));
EXTERN void		TclExpandJumpFixupArray _ANSI_ARGS_((
                            JumpFixupArray *fixupArrayPtr));
EXTERN void		TclFinalizeAuxDataTypeTable _ANSI_ARGS_((void));
EXTERN int		TclFindCompiledLocal _ANSI_ARGS_((char *name, 
        		    int nameChars, int create, int flags,
			    Proc *procPtr));
EXTERN LiteralEntry *	TclLookupLiteralEntry _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Obj *objPtr));
EXTERN int		TclFixupForwardJump _ANSI_ARGS_((
			    CompileEnv *envPtr, JumpFixup *jumpFixupPtr,
			    int jumpDist, int distThreshold));
EXTERN void		TclFreeCompileEnv _ANSI_ARGS_((CompileEnv *envPtr));
EXTERN void		TclFreeJumpFixupArray _ANSI_ARGS_((
  			    JumpFixupArray *fixupArrayPtr));
EXTERN void		TclInitAuxDataTypeTable _ANSI_ARGS_((void));
EXTERN void		TclInitByteCodeObj _ANSI_ARGS_((Tcl_Obj *objPtr,
			    CompileEnv *envPtr));
EXTERN void		TclInitCompilation _ANSI_ARGS_((void));
EXTERN void		TclInitCompileEnv _ANSI_ARGS_((Tcl_Interp *interp,
			    CompileEnv *envPtr, char *string,
			    int numBytes));
EXTERN void		TclInitJumpFixupArray _ANSI_ARGS_((
			    JumpFixupArray *fixupArrayPtr));
EXTERN void		TclInitLiteralTable _ANSI_ARGS_((
			    LiteralTable *tablePtr));
#ifdef TCL_COMPILE_STATS
EXTERN char *		TclLiteralStats _ANSI_ARGS_((
			    LiteralTable *tablePtr));
EXTERN int		TclLog2 _ANSI_ARGS_((int value));
#endif
#ifdef TCL_COMPILE_DEBUG
EXTERN void		TclPrintByteCodeObj _ANSI_ARGS_((Tcl_Interp *interp,

		            Tcl_Obj *objPtr));
#endif
EXTERN int		TclPrintInstruction _ANSI_ARGS_((ByteCode* codePtr,
			    unsigned char *pc));
EXTERN void		TclPrintObject _ANSI_ARGS_((FILE *outFile,
			    Tcl_Obj *objPtr, int maxChars));
EXTERN void		TclPrintSource _ANSI_ARGS_((FILE *outFile,
			    char *string, int maxChars));
EXTERN void		TclRegisterAuxDataType _ANSI_ARGS_((AuxDataType *typePtr));
EXTERN int		TclRegisterLiteral _ANSI_ARGS_((CompileEnv *envPtr,
			    char *bytes, int length, int onHeap));
EXTERN void		TclReleaseLiteral _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
EXTERN void		TclSetCmdNameObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, Command *cmdPtr));
#ifdef TCL_COMPILE_DEBUG
EXTERN void		TclVerifyGlobalLiteralTable _ANSI_ARGS_((
			    Interp *iPtr));
EXTERN void		TclVerifyLocalLiteralTable _ANSI_ARGS_((
			    CompileEnv *envPtr));
#endif

/*
 *----------------------------------------------------------------
 * Macros used by Tcl bytecode compilation and execution modules
 * inside the Tcl core but not used outside.
 *----------------------------------------------------------------
 */


















/*
 * Macro to emit an opcode byte into a CompileEnv's code array.
 * The ANSI C "prototype" for this macro is:
 *
 * EXTERN void	TclEmitOpcode _ANSI_ARGS_((unsigned char op,
 *		    CompileEnv *envPtr));
 */

#define TclEmitOpcode(op, envPtr) \
    if ((envPtr)->codeNext == (envPtr)->codeEnd) \
        TclExpandCodeArray(envPtr); \
    *(envPtr)->codeNext++ = (unsigned char) (op)

/*
 * Macro to emit an integer operand.


 * The ANSI C "prototype" for this macro is:
 *
 * EXTERN void	TclEmitInt1 _ANSI_ARGS_((int i, CompileEnv *envPtr));

 */

#define TclEmitInt1(i, envPtr) \





    if ((envPtr)->codeNext == (envPtr)->codeEnd) \

        TclExpandCodeArray(envPtr); \

    *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))




/*
 * Macros to emit an instruction with signed or unsigned integer operands.
 * Four byte integers are stored in "big-endian" order with the high order
 * byte stored at the lowest address.
 * The ANSI C "prototypes" for these macros are:
 *
 * EXTERN void	TclEmitInstInt1 _ANSI_ARGS_((unsigned char op, int i, 
 *		    CompileEnv *envPtr));
 * EXTERN void	TclEmitInstInt4 _ANSI_ARGS_((unsigned char op, int i, 
 *		    CompileEnv *envPtr));




 */

#define TclEmitInstInt1(op, i, envPtr) \
    if (((envPtr)->codeNext + 2) > (envPtr)->codeEnd) { \
        TclExpandCodeArray(envPtr); \
    } \
    *(envPtr)->codeNext++ = (unsigned char) (op); \
    *(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i))

#define TclEmitInstInt4(op, i, envPtr) \
    if (((envPtr)->codeNext + 5) > (envPtr)->codeEnd) { \
        TclExpandCodeArray(envPtr); \
    } \
    *(envPtr)->codeNext++ = (unsigned char) (op); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i) >> 24); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i) >> 16); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i) >>  8); \
    *(envPtr)->codeNext++ = \
        (unsigned char) ((unsigned int) (i)      )
    






/*
 * Macro to push a Tcl object onto the Tcl evaluation stack. It emits the
 * object's one or four byte array index into the CompileEnv's code
 * array. These support, respectively, a maximum of 256 (2**8) and 2**32
 * objects in a CompileEnv. The ANSI C "prototype" for this macro is:
 *
 * EXTERN void	TclEmitPush _ANSI_ARGS_((int objIndex, CompileEnv *envPtr));
 */

#define TclEmitPush(objIndex, envPtr) \
    if ((objIndex) <= 255) { \
	TclEmitInstInt1(INST_PUSH1, (objIndex), (envPtr)); \
    } else { \
	TclEmitInstInt4(INST_PUSH4, (objIndex), (envPtr)); \
    }

/*
 * Macros to update a (signed or unsigned) integer starting at a pointer.
 * The two variants depend on the number of bytes. The ANSI C "prototypes"
 * for these macros are:
 *
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
 * EXTERN int  TclMin _ANSI_ARGS_((int i, int j));
 * EXTERN int  TclMax _ANSI_ARGS_((int i, int j));
 */

#define TclMin(i, j)   ((((int) i) < ((int) j))? (i) : (j))
#define TclMax(i, j)   ((((int) i) > ((int) j))? (i) : (j))

/*
 * Macro used to compute the offset of the current instruction in the
 * bytecode instruction stream. The ANSI C "prototypes" for this macro is:
 *
 * EXTERN int  TclCurrCodeOffset _ANSI_ARGS_((void));
 */

#define TclCurrCodeOffset()  ((envPtr)->codeNext - (envPtr)->codeStart)

/*
 * Upper bound for legal jump distances. Checked during compilation if
 * debugging.
 */

#define MAX_JUMP_DIST   5000

#endif /* _TCLCOMPILATION */








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

<
<

<
971
972
973
974
975
976
977






978

979




980


981

 * EXTERN int  TclMin _ANSI_ARGS_((int i, int j));
 * EXTERN int  TclMax _ANSI_ARGS_((int i, int j));
 */

#define TclMin(i, j)   ((((int) i) < ((int) j))? (i) : (j))
#define TclMax(i, j)   ((((int) i) > ((int) j))? (i) : (j))







# undef TCL_STORAGE_CLASS

# define TCL_STORAGE_CLASS DLLIMPORT







#endif /* _TCLCOMPILATION */

Changes to generic/tclDate.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclDate.c --
 *
 *	This file is generated from a yacc grammar defined in
 *	the file tclGetDate.y.  It should not be edited directly.
 *
 * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
 * 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.
 *
 * @(#) tclDate.c 1.32 97/02/03 14:54:37
 */

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

#ifdef MAC_TCL
#   define EPOCH           1904












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclDate.c --
 *
 *	This file is generated from a yacc grammar defined in
 *	the file tclGetDate.y.  It should not be edited directly.
 *
 * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
 * 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: tclDate.c,v 1.1.2.3 1999/03/10 06:49:15 stanton Exp $ 
 */

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

#ifdef MAC_TCL
#   define EPOCH           1904
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
    }
    Julian *= SECSPERDAY;
    Julian += TclDateTimezone * 60L;
    if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
        return -1;
    Julian += tod;
    if (DSTmode == DSTon
     || (DSTmode == DSTmaybe && TclpGetDate(&Julian, 0)->tm_isdst))
        Julian -= 60 * 60;
    *TimePtr = Julian;
    return 0;
}


static time_t
DSTcorrect(Start, Future)
    time_t      Start;
    time_t      Future;
{
    time_t      StartDay;
    time_t      FutureDay;

    StartDay = (TclpGetDate(&Start, 0)->tm_hour + 1) % 24;
    FutureDay = (TclpGetDate(&Future, 0)->tm_hour + 1) % 24;
    return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
}


static time_t
RelativeDate(Start, DayOrdinal, DayNumber)
    time_t      Start;
    time_t      DayOrdinal;
    time_t      DayNumber;
{
    struct tm   *tm;
    time_t      now;

    now = Start;
    tm = TclpGetDate(&now, 0);
    now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
    now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
    return DSTcorrect(Start, now);
}


static int







|














|
|














|







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
    }
    Julian *= SECSPERDAY;
    Julian += TclDateTimezone * 60L;
    if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
        return -1;
    Julian += tod;
    if (DSTmode == DSTon
     || (DSTmode == DSTmaybe && TclpGetDate((TclpTime_t)&Julian, 0)->tm_isdst))
        Julian -= 60 * 60;
    *TimePtr = Julian;
    return 0;
}


static time_t
DSTcorrect(Start, Future)
    time_t      Start;
    time_t      Future;
{
    time_t      StartDay;
    time_t      FutureDay;

    StartDay = (TclpGetDate((TclpTime_t)&Start, 0)->tm_hour + 1) % 24;
    FutureDay = (TclpGetDate((TclpTime_t)&Future, 0)->tm_hour + 1) % 24;
    return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
}


static time_t
RelativeDate(Start, DayOrdinal, DayNumber)
    time_t      Start;
    time_t      DayOrdinal;
    time_t      DayNumber;
{
    struct tm   *tm;
    time_t      now;

    now = Start;
    tm = TclpGetDate((TclpTime_t)&now, 0);
    now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
    now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
    return DSTcorrect(Start, now);
}


static int
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
    time_t Julian;
    int result;

    if (RelMonth == 0) {
        *TimePtr = 0;
        return 0;
    }
    tm = TclpGetDate(&Start, 0);
    Month = 12 * (tm->tm_year + TM_YEAR_BASE) + tm->tm_mon + RelMonth;
    Year = Month / 12;
    Month = Month % 12 + 1;
    result = Convert(Month, (time_t) tm->tm_mday, Year,
	    (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
	    MER24, DSTmaybe, &Julian);
    /*







|







491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
    time_t Julian;
    int result;

    if (RelMonth == 0) {
        *TimePtr = 0;
        return 0;
    }
    tm = TclpGetDate((TclpTime_t)&Start, 0);
    Month = 12 * (tm->tm_year + TM_YEAR_BASE) + tm->tm_mon + RelMonth;
    Year = Month / 12;
    Month = Month % 12 + 1;
    result = Convert(Month, (time_t) tm->tm_mday, Year,
	    (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
	    MER24, DSTmaybe, &Julian);
    /*
533
534
535
536
537
538
539
540
541
542
543
544

545
546
547
548
549
550
551
    register TABLE *tp;
    int i;
    int abbrev;

    /*
     * Make it lowercase.
     */
    for (p = buff; *p; p++) {
        if (isupper(UCHAR(*p))) {
            *p = (char) tolower(UCHAR(*p));
	}
    }


    if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
        TclDatelval.Meridian = MERam;
        return tMERIDIAN;
    }
    if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
        TclDatelval.Meridian = MERpm;







<
<
<
|
<
>







533
534
535
536
537
538
539



540

541
542
543
544
545
546
547
548
    register TABLE *tp;
    int i;
    int abbrev;

    /*
     * Make it lowercase.
     */





    Tcl_UtfToLower(buff);

    if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
        TclDatelval.Meridian = MERam;
        return tMERIDIAN;
    }
    if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
        TclDatelval.Meridian = MERpm;
610
611
612
613
614
615
616
617

618
619
620
621
622
623
624
            return tp->type;
        }
    }

    /*
     * Military timezones.
     */
    if (buff[1] == '\0' && isalpha(UCHAR(*buff))) {

        for (tp = MilitaryTable; tp->name; tp++) {
            if (strcmp(buff, tp->name) == 0) {
                TclDatelval.Number = tp->value;
                return tp->type;
            }
	}
    }







|
>







607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
            return tp->type;
        }
    }

    /*
     * Military timezones.
     */
    if (buff[1] == '\0' && !(*buff & 0x80)
	    && isalpha(UCHAR(*buff))) {	/* INTL: ISO only */
        for (tp = MilitaryTable; tp->name; tp++) {
            if (strcmp(buff, tp->name) == 0) {
                TclDatelval.Number = tp->value;
                return tp->type;
            }
	}
    }
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675

676
677
678
679
680
681
682
683
684
685

686
687
688
689
690
691
692
    int                 sign;

    for ( ; ; ) {
        while (isspace((unsigned char) (*TclDateInput))) {
            TclDateInput++;
	}

        if (isdigit(c = *TclDateInput) || c == '-' || c == '+') {
            if (c == '-' || c == '+') {
                sign = c == '-' ? -1 : 1;
                if (!isdigit(*++TclDateInput)) {
                    /*
		     * skip the '-' sign
		     */
                    continue;
		}
            } else {
                sign = 0;
	    }
            for (TclDatelval.Number = 0; isdigit(c = *TclDateInput++); ) {

                TclDatelval.Number = 10 * TclDatelval.Number + c - '0';
	    }
            TclDateInput--;
            if (sign < 0) {
                TclDatelval.Number = -TclDatelval.Number;
	    }
            return sign ? tSNUMBER : tUNUMBER;
        }
        if (isalpha(UCHAR(c))) {
            for (p = buff; isalpha(c = *TclDateInput++) || c == '.'; ) {

                if (p < &buff[sizeof buff - 1]) {
                    *p++ = c;
		}
	    }
            *p = '\0';
            TclDateInput--;
            return LookupWord(buff);







|


|








|
>








|
|
>







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
    int                 sign;

    for ( ; ; ) {
        while (isspace((unsigned char) (*TclDateInput))) {
            TclDateInput++;
	}

        if (isdigit(c = *TclDateInput) || c == '-' || c == '+') { /* INTL: digit */
            if (c == '-' || c == '+') {
                sign = c == '-' ? -1 : 1;
                if (!isdigit(*++TclDateInput)) { /* INTL: digit */
                    /*
		     * skip the '-' sign
		     */
                    continue;
		}
            } else {
                sign = 0;
	    }
            for (TclDatelval.Number = 0;
		    isdigit(c = *TclDateInput++); ) { /* INTL: digit */
                TclDatelval.Number = 10 * TclDatelval.Number + c - '0';
	    }
            TclDateInput--;
            if (sign < 0) {
                TclDatelval.Number = -TclDatelval.Number;
	    }
            return sign ? tSNUMBER : tUNUMBER;
        }
        if (!(c & 0x80) && isalpha(UCHAR(c))) {	/* INTL: ISO only. */
            for (p = buff; isalpha(c = *TclDateInput++) /* INTL: ISO only. */
		     || c == '.'; ) {
                if (p < &buff[sizeof buff - 1]) {
                    *p++ = c;
		}
	    }
            *p = '\0';
            TclDateInput--;
            return LookupWord(buff);
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
    struct tm *tm;
    time_t Start;
    time_t Time;
    time_t tod;
    int thisyear;

    TclDateInput = p;
    tm = TclpGetDate((time_t *) &now, 0);
    thisyear = tm->tm_year + TM_YEAR_BASE;
    TclDateYear = thisyear;
    TclDateMonth = tm->tm_mon + 1;
    TclDateDay = tm->tm_mday;
    TclDateTimezone = zone;
    if (zone == -50000) {
        TclDateDSTmode = DSToff;  /* assume GMT */







|







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
    struct tm *tm;
    time_t Start;
    time_t Time;
    time_t tod;
    int thisyear;

    TclDateInput = p;
    tm = TclpGetDate((TclpTime_t) &now, 0);
    thisyear = tm->tm_year + TM_YEAR_BASE;
    TclDateYear = thisyear;
    TclDateMonth = tm->tm_mon + 1;
    TclDateDay = tm->tm_mday;
    TclDateTimezone = zone;
    if (zone == -50000) {
        TclDateDSTmode = DSToff;  /* assume GMT */

Added generic/tclDecls.h.







































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
/*
 * 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.3.2.16 1999/04/06 03:13:13 redman Exp $
 */

#ifndef _TCLDECLS
#define _TCLDECLS

/*
 * WARNING: 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. */

/*
 * Exported function declarations:
 */

/* 0 */
EXTERN int		Tcl_PkgProvideEx _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, char * version, 
				ClientData clientData));
/* 1 */
EXTERN char *		Tcl_PkgRequireEx _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, char * version, int exact, 
				ClientData * clientDataPtr));
/* 2 */
EXTERN void		Tcl_Panic _ANSI_ARGS_(TCL_VARARGS(char *,format));
/* 3 */
EXTERN char *		Tcl_Alloc _ANSI_ARGS_((unsigned int size));
/* 4 */
EXTERN void		Tcl_Free _ANSI_ARGS_((char * ptr));
/* 5 */
EXTERN char *		Tcl_Realloc _ANSI_ARGS_((char * ptr, 
				unsigned int size));
/* 6 */
EXTERN char *		Tcl_DbCkalloc _ANSI_ARGS_((unsigned int size, 
				char * file, int line));
/* 7 */
EXTERN int		Tcl_DbCkfree _ANSI_ARGS_((char * ptr, char * file, 
				int line));
/* 8 */
EXTERN char *		Tcl_DbCkrealloc _ANSI_ARGS_((char * ptr, 
				unsigned int size, char * file, int line));
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
/* 9 */
EXTERN void		Tcl_CreateFileHandler _ANSI_ARGS_((int fd, int mask, 
				Tcl_FileProc * proc, ClientData clientData));
#endif /* UNIX */
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
/* 10 */
EXTERN void		Tcl_DeleteFileHandler _ANSI_ARGS_((int fd));
#endif /* UNIX */
/* 11 */
EXTERN void		Tcl_SetTimer _ANSI_ARGS_((Tcl_Time * timePtr));
/* 12 */
EXTERN void		Tcl_Sleep _ANSI_ARGS_((int ms));
/* 13 */
EXTERN int		Tcl_WaitForEvent _ANSI_ARGS_((Tcl_Time * timePtr));
/* 14 */
EXTERN int		Tcl_AppendAllObjTypes _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * objPtr));
/* 15 */
EXTERN void		Tcl_AppendStringsToObj _ANSI_ARGS_(TCL_VARARGS(Tcl_Obj *,objPtr));
/* 16 */
EXTERN void		Tcl_AppendToObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				char * bytes, int length));
/* 17 */
EXTERN Tcl_Obj *	Tcl_ConcatObj _ANSI_ARGS_((int objc, 
				Tcl_Obj *CONST objv[]));
/* 18 */
EXTERN int		Tcl_ConvertToType _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr, Tcl_ObjType * typePtr));
/* 19 */
EXTERN void		Tcl_DbDecrRefCount _ANSI_ARGS_((Tcl_Obj * objPtr, 
				char * file, int line));
/* 20 */
EXTERN void		Tcl_DbIncrRefCount _ANSI_ARGS_((Tcl_Obj * objPtr, 
				char * file, int line));
/* 21 */
EXTERN int		Tcl_DbIsShared _ANSI_ARGS_((Tcl_Obj * objPtr, 
				char * file, int line));
/* 22 */
EXTERN Tcl_Obj *	Tcl_DbNewBooleanObj _ANSI_ARGS_((int boolValue, 
				char * file, int line));
/* 23 */
EXTERN Tcl_Obj *	Tcl_DbNewByteArrayObj _ANSI_ARGS_((
				unsigned char * bytes, int length, 
				char * file, int line));
/* 24 */
EXTERN Tcl_Obj *	Tcl_DbNewDoubleObj _ANSI_ARGS_((double doubleValue, 
				char * file, int line));
/* 25 */
EXTERN Tcl_Obj *	Tcl_DbNewListObj _ANSI_ARGS_((int objc, 
				Tcl_Obj *CONST objv[], char * file, int line));
/* 26 */
EXTERN Tcl_Obj *	Tcl_DbNewLongObj _ANSI_ARGS_((long longValue, 
				char * file, int line));
/* 27 */
EXTERN Tcl_Obj *	Tcl_DbNewObj _ANSI_ARGS_((char * file, int line));
/* 28 */
EXTERN Tcl_Obj *	Tcl_DbNewStringObj _ANSI_ARGS_((CONST char * bytes, 
				int length, char * file, int line));
/* 29 */
EXTERN Tcl_Obj *	Tcl_DuplicateObj _ANSI_ARGS_((Tcl_Obj * objPtr));
/* 30 */
EXTERN void		TclFreeObj _ANSI_ARGS_((Tcl_Obj * objPtr));
/* 31 */
EXTERN int		Tcl_GetBoolean _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, int * boolPtr));
/* 32 */
EXTERN int		Tcl_GetBooleanFromObj _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * objPtr, 
				int * boolPtr));
/* 33 */
EXTERN unsigned char *	Tcl_GetByteArrayFromObj _ANSI_ARGS_((
				Tcl_Obj * objPtr, int * lengthPtr));
/* 34 */
EXTERN int		Tcl_GetDouble _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, double * doublePtr));
/* 35 */
EXTERN int		Tcl_GetDoubleFromObj _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * objPtr, 
				double * doublePtr));
/* 36 */
EXTERN int		Tcl_GetIndexFromObj _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr, char ** tablePtr, 
				char * msg, int flags, int * indexPtr));
/* 37 */
EXTERN int		Tcl_GetInt _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, int * intPtr));
/* 38 */
EXTERN int		Tcl_GetIntFromObj _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr, int * intPtr));
/* 39 */
EXTERN int		Tcl_GetLongFromObj _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr, long * longPtr));
/* 40 */
EXTERN Tcl_ObjType *	Tcl_GetObjType _ANSI_ARGS_((char * typeName));
/* 41 */
EXTERN char *		Tcl_GetStringFromObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				int * lengthPtr));
/* 42 */
EXTERN void		Tcl_InvalidateStringRep _ANSI_ARGS_((
				Tcl_Obj * objPtr));
/* 43 */
EXTERN int		Tcl_ListObjAppendList _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * listPtr, 
				Tcl_Obj * elemListPtr));
/* 44 */
EXTERN int		Tcl_ListObjAppendElement _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * listPtr, 
				Tcl_Obj * objPtr));
/* 45 */
EXTERN int		Tcl_ListObjGetElements _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * listPtr, 
				int * objcPtr, Tcl_Obj *** objvPtr));
/* 46 */
EXTERN int		Tcl_ListObjIndex _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * listPtr, int index, 
				Tcl_Obj ** objPtrPtr));
/* 47 */
EXTERN int		Tcl_ListObjLength _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * listPtr, int * intPtr));
/* 48 */
EXTERN int		Tcl_ListObjReplace _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * listPtr, int first, int count, 
				int objc, Tcl_Obj *CONST objv[]));
/* 49 */
EXTERN Tcl_Obj *	Tcl_NewBooleanObj _ANSI_ARGS_((int boolValue));
/* 50 */
EXTERN Tcl_Obj *	Tcl_NewByteArrayObj _ANSI_ARGS_((
				unsigned char * bytes, int length));
/* 51 */
EXTERN Tcl_Obj *	Tcl_NewDoubleObj _ANSI_ARGS_((double doubleValue));
/* 52 */
EXTERN Tcl_Obj *	Tcl_NewIntObj _ANSI_ARGS_((int intValue));
/* 53 */
EXTERN Tcl_Obj *	Tcl_NewListObj _ANSI_ARGS_((int objc, 
				Tcl_Obj *CONST objv[]));
/* 54 */
EXTERN Tcl_Obj *	Tcl_NewLongObj _ANSI_ARGS_((long longValue));
/* 55 */
EXTERN Tcl_Obj *	Tcl_NewObj _ANSI_ARGS_((void));
/* 56 */
EXTERN Tcl_Obj *	Tcl_NewStringObj _ANSI_ARGS_((CONST char * bytes, 
				int length));
/* 57 */
EXTERN void		Tcl_SetBooleanObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				int boolValue));
/* 58 */
EXTERN unsigned char *	Tcl_SetByteArrayLength _ANSI_ARGS_((Tcl_Obj * objPtr, 
				int length));
/* 59 */
EXTERN void		Tcl_SetByteArrayObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				unsigned char * bytes, int length));
/* 60 */
EXTERN void		Tcl_SetDoubleObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				double doubleValue));
/* 61 */
EXTERN void		Tcl_SetIntObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				int intValue));
/* 62 */
EXTERN void		Tcl_SetListObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				int objc, Tcl_Obj *CONST objv[]));
/* 63 */
EXTERN void		Tcl_SetLongObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				long longValue));
/* 64 */
EXTERN void		Tcl_SetObjLength _ANSI_ARGS_((Tcl_Obj * objPtr, 
				int length));
/* 65 */
EXTERN void		Tcl_SetStringObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				char * bytes, int length));
/* 66 */
EXTERN void		Tcl_AddErrorInfo _ANSI_ARGS_((Tcl_Interp * interp, 
				CONST char * message));
/* 67 */
EXTERN void		Tcl_AddObjErrorInfo _ANSI_ARGS_((Tcl_Interp * interp, 
				CONST char * message, int length));
/* 68 */
EXTERN void		Tcl_AllowExceptions _ANSI_ARGS_((Tcl_Interp * interp));
/* 69 */
EXTERN void		Tcl_AppendElement _ANSI_ARGS_((Tcl_Interp * interp, 
				CONST char * string));
/* 70 */
EXTERN void		Tcl_AppendResult _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp));
/* 71 */
EXTERN Tcl_AsyncHandler	 Tcl_AsyncCreate _ANSI_ARGS_((Tcl_AsyncProc * proc, 
				ClientData clientData));
/* 72 */
EXTERN void		Tcl_AsyncDelete _ANSI_ARGS_((Tcl_AsyncHandler async));
/* 73 */
EXTERN int		Tcl_AsyncInvoke _ANSI_ARGS_((Tcl_Interp * interp, 
				int code));
/* 74 */
EXTERN void		Tcl_AsyncMark _ANSI_ARGS_((Tcl_AsyncHandler async));
/* 75 */
EXTERN int		Tcl_AsyncReady _ANSI_ARGS_((void));
/* 76 */
EXTERN void		Tcl_BackgroundError _ANSI_ARGS_((Tcl_Interp * interp));
/* 77 */
EXTERN char		Tcl_Backslash _ANSI_ARGS_((CONST char * src, 
				int * readPtr));
/* 78 */
EXTERN int		Tcl_BadChannelOption _ANSI_ARGS_((
				Tcl_Interp * interp, char * optionName, 
				char * optionList));
/* 79 */
EXTERN void		Tcl_CallWhenDeleted _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_InterpDeleteProc * proc, 
				ClientData clientData));
/* 80 */
EXTERN void		Tcl_CancelIdleCall _ANSI_ARGS_((
				Tcl_IdleProc * idleProc, 
				ClientData clientData));
/* 81 */
EXTERN int		Tcl_Close _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Channel chan));
/* 82 */
EXTERN int		Tcl_CommandComplete _ANSI_ARGS_((char * cmd));
/* 83 */
EXTERN char *		Tcl_Concat _ANSI_ARGS_((int argc, char ** argv));
/* 84 */
EXTERN int		Tcl_ConvertElement _ANSI_ARGS_((CONST char * src, 
				char * dst, int flags));
/* 85 */
EXTERN int		Tcl_ConvertCountedElement _ANSI_ARGS_((
				CONST char * src, int length, char * dst, 
				int flags));
/* 86 */
EXTERN int		Tcl_CreateAlias _ANSI_ARGS_((Tcl_Interp * slave, 
				char * slaveCmd, Tcl_Interp * target, 
				char * targetCmd, int argc, char ** argv));
/* 87 */
EXTERN int		Tcl_CreateAliasObj _ANSI_ARGS_((Tcl_Interp * slave, 
				char * slaveCmd, Tcl_Interp * target, 
				char * targetCmd, int objc, 
				Tcl_Obj *CONST objv[]));
/* 88 */
EXTERN Tcl_Channel	Tcl_CreateChannel _ANSI_ARGS_((
				Tcl_ChannelType * typePtr, char * chanName, 
				ClientData instanceData, int mask));
/* 89 */
EXTERN void		Tcl_CreateChannelHandler _ANSI_ARGS_((
				Tcl_Channel chan, int mask, 
				Tcl_ChannelProc * proc, 
				ClientData clientData));
/* 90 */
EXTERN void		Tcl_CreateCloseHandler _ANSI_ARGS_((Tcl_Channel chan, 
				Tcl_CloseProc * proc, ClientData clientData));
/* 91 */
EXTERN Tcl_Command	Tcl_CreateCommand _ANSI_ARGS_((Tcl_Interp * interp, 
				char * cmdName, Tcl_CmdProc * proc, 
				ClientData clientData, 
				Tcl_CmdDeleteProc * deleteProc));
/* 92 */
EXTERN void		Tcl_CreateEventSource _ANSI_ARGS_((
				Tcl_EventSetupProc * setupProc, 
				Tcl_EventCheckProc * checkProc, 
				ClientData clientData));
/* 93 */
EXTERN void		Tcl_CreateExitHandler _ANSI_ARGS_((
				Tcl_ExitProc * proc, ClientData clientData));
/* 94 */
EXTERN Tcl_Interp *	Tcl_CreateInterp _ANSI_ARGS_((void));
/* 95 */
EXTERN void		Tcl_CreateMathFunc _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, int numArgs, 
				Tcl_ValueType * argTypes, 
				Tcl_MathProc * proc, ClientData clientData));
/* 96 */
EXTERN Tcl_Command	Tcl_CreateObjCommand _ANSI_ARGS_((
				Tcl_Interp * interp, char * cmdName, 
				Tcl_ObjCmdProc * proc, ClientData clientData, 
				Tcl_CmdDeleteProc * deleteProc));
/* 97 */
EXTERN Tcl_Interp *	Tcl_CreateSlave _ANSI_ARGS_((Tcl_Interp * interp, 
				char * slaveName, int isSafe));
/* 98 */
EXTERN Tcl_TimerToken	Tcl_CreateTimerHandler _ANSI_ARGS_((int milliseconds, 
				Tcl_TimerProc * proc, ClientData clientData));
/* 99 */
EXTERN Tcl_Trace	Tcl_CreateTrace _ANSI_ARGS_((Tcl_Interp * interp, 
				int level, Tcl_CmdTraceProc * proc, 
				ClientData clientData));
/* 100 */
EXTERN void		Tcl_DeleteAssocData _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name));
/* 101 */
EXTERN void		Tcl_DeleteChannelHandler _ANSI_ARGS_((
				Tcl_Channel chan, Tcl_ChannelProc * proc, 
				ClientData clientData));
/* 102 */
EXTERN void		Tcl_DeleteCloseHandler _ANSI_ARGS_((Tcl_Channel chan, 
				Tcl_CloseProc * proc, ClientData clientData));
/* 103 */
EXTERN int		Tcl_DeleteCommand _ANSI_ARGS_((Tcl_Interp * interp, 
				char * cmdName));
/* 104 */
EXTERN int		Tcl_DeleteCommandFromToken _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Command command));
/* 105 */
EXTERN void		Tcl_DeleteEvents _ANSI_ARGS_((
				Tcl_EventDeleteProc * proc, 
				ClientData clientData));
/* 106 */
EXTERN void		Tcl_DeleteEventSource _ANSI_ARGS_((
				Tcl_EventSetupProc * setupProc, 
				Tcl_EventCheckProc * checkProc, 
				ClientData clientData));
/* 107 */
EXTERN void		Tcl_DeleteExitHandler _ANSI_ARGS_((
				Tcl_ExitProc * proc, ClientData clientData));
/* 108 */
EXTERN void		Tcl_DeleteHashEntry _ANSI_ARGS_((
				Tcl_HashEntry * entryPtr));
/* 109 */
EXTERN void		Tcl_DeleteHashTable _ANSI_ARGS_((
				Tcl_HashTable * tablePtr));
/* 110 */
EXTERN void		Tcl_DeleteInterp _ANSI_ARGS_((Tcl_Interp * interp));
/* 111 */
EXTERN void		Tcl_DetachPids _ANSI_ARGS_((int numPids, 
				Tcl_Pid * pidPtr));
/* 112 */
EXTERN void		Tcl_DeleteTimerHandler _ANSI_ARGS_((
				Tcl_TimerToken token));
/* 113 */
EXTERN void		Tcl_DeleteTrace _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Trace trace));
/* 114 */
EXTERN void		Tcl_DontCallWhenDeleted _ANSI_ARGS_((
				Tcl_Interp * interp, 
				Tcl_InterpDeleteProc * proc, 
				ClientData clientData));
/* 115 */
EXTERN int		Tcl_DoOneEvent _ANSI_ARGS_((int flags));
/* 116 */
EXTERN void		Tcl_DoWhenIdle _ANSI_ARGS_((Tcl_IdleProc * proc, 
				ClientData clientData));
/* 117 */
EXTERN char *		Tcl_DStringAppend _ANSI_ARGS_((Tcl_DString * dsPtr, 
				CONST char * str, int length));
/* 118 */
EXTERN char *		Tcl_DStringAppendElement _ANSI_ARGS_((
				Tcl_DString * dsPtr, CONST char * string));
/* 119 */
EXTERN void		Tcl_DStringEndSublist _ANSI_ARGS_((
				Tcl_DString * dsPtr));
/* 120 */
EXTERN void		Tcl_DStringFree _ANSI_ARGS_((Tcl_DString * dsPtr));
/* 121 */
EXTERN void		Tcl_DStringGetResult _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_DString * dsPtr));
/* 122 */
EXTERN void		Tcl_DStringInit _ANSI_ARGS_((Tcl_DString * dsPtr));
/* 123 */
EXTERN void		Tcl_DStringResult _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_DString * dsPtr));
/* 124 */
EXTERN void		Tcl_DStringSetLength _ANSI_ARGS_((
				Tcl_DString * dsPtr, int length));
/* 125 */
EXTERN void		Tcl_DStringStartSublist _ANSI_ARGS_((
				Tcl_DString * dsPtr));
/* 126 */
EXTERN int		Tcl_Eof _ANSI_ARGS_((Tcl_Channel chan));
/* 127 */
EXTERN char *		Tcl_ErrnoId _ANSI_ARGS_((void));
/* 128 */
EXTERN char *		Tcl_ErrnoMsg _ANSI_ARGS_((int err));
/* 129 */
EXTERN int		Tcl_Eval _ANSI_ARGS_((Tcl_Interp * interp, 
				char * string));
/* 130 */
EXTERN int		Tcl_EvalFile _ANSI_ARGS_((Tcl_Interp * interp, 
				char * fileName));
/* 131 */
EXTERN int		Tcl_EvalObj _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr));
/* 132 */
EXTERN void		Tcl_EventuallyFree _ANSI_ARGS_((
				ClientData clientData, 
				Tcl_FreeProc * freeProc));
/* 133 */
EXTERN void		Tcl_Exit _ANSI_ARGS_((int status));
/* 134 */
EXTERN int		Tcl_ExposeCommand _ANSI_ARGS_((Tcl_Interp * interp, 
				char * hiddenCmdToken, char * cmdName));
/* 135 */
EXTERN int		Tcl_ExprBoolean _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, int * ptr));
/* 136 */
EXTERN int		Tcl_ExprBooleanObj _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr, int * ptr));
/* 137 */
EXTERN int		Tcl_ExprDouble _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, double * ptr));
/* 138 */
EXTERN int		Tcl_ExprDoubleObj _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr, double * ptr));
/* 139 */
EXTERN int		Tcl_ExprLong _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, long * ptr));
/* 140 */
EXTERN int		Tcl_ExprLongObj _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr, long * ptr));
/* 141 */
EXTERN int		Tcl_ExprObj _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr, Tcl_Obj ** resultPtrPtr));
/* 142 */
EXTERN int		Tcl_ExprString _ANSI_ARGS_((Tcl_Interp * interp, 
				char * string));
/* 143 */
EXTERN void		Tcl_Finalize _ANSI_ARGS_((void));
/* 144 */
EXTERN void		Tcl_FindExecutable _ANSI_ARGS_((CONST char * argv0));
/* 145 */
EXTERN Tcl_HashEntry *	Tcl_FirstHashEntry _ANSI_ARGS_((
				Tcl_HashTable * tablePtr, 
				Tcl_HashSearch * searchPtr));
/* 146 */
EXTERN int		Tcl_Flush _ANSI_ARGS_((Tcl_Channel chan));
/* 147 */
EXTERN void		Tcl_FreeResult _ANSI_ARGS_((Tcl_Interp * interp));
/* 148 */
EXTERN int		Tcl_GetAlias _ANSI_ARGS_((Tcl_Interp * interp, 
				char * slaveCmd, 
				Tcl_Interp ** targetInterpPtr, 
				char ** targetCmdPtr, int * argcPtr, 
				char *** argvPtr));
/* 149 */
EXTERN int		Tcl_GetAliasObj _ANSI_ARGS_((Tcl_Interp * interp, 
				char * slaveCmd, 
				Tcl_Interp ** targetInterpPtr, 
				char ** targetCmdPtr, int * objcPtr, 
				Tcl_Obj *** objv));
/* 150 */
EXTERN ClientData	Tcl_GetAssocData _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, Tcl_InterpDeleteProc ** procPtr));
/* 151 */
EXTERN Tcl_Channel	Tcl_GetChannel _ANSI_ARGS_((Tcl_Interp * interp, 
				char * chanName, int * modePtr));
/* 152 */
EXTERN int		Tcl_GetChannelBufferSize _ANSI_ARGS_((
				Tcl_Channel chan));
/* 153 */
EXTERN int		Tcl_GetChannelHandle _ANSI_ARGS_((Tcl_Channel chan, 
				int direction, ClientData * handlePtr));
/* 154 */
EXTERN ClientData	Tcl_GetChannelInstanceData _ANSI_ARGS_((
				Tcl_Channel chan));
/* 155 */
EXTERN int		Tcl_GetChannelMode _ANSI_ARGS_((Tcl_Channel chan));
/* 156 */
EXTERN char *		Tcl_GetChannelName _ANSI_ARGS_((Tcl_Channel chan));
/* 157 */
EXTERN int		Tcl_GetChannelOption _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Channel chan, 
				char * optionName, Tcl_DString * dsPtr));
/* 158 */
EXTERN Tcl_ChannelType * Tcl_GetChannelType _ANSI_ARGS_((Tcl_Channel chan));
/* 159 */
EXTERN int		Tcl_GetCommandInfo _ANSI_ARGS_((Tcl_Interp * interp, 
				char * cmdName, Tcl_CmdInfo * infoPtr));
/* 160 */
EXTERN char *		Tcl_GetCommandName _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Command command));
/* 161 */
EXTERN int		Tcl_GetErrno _ANSI_ARGS_((void));
/* 162 */
EXTERN char *		Tcl_GetHostName _ANSI_ARGS_((void));
/* 163 */
EXTERN int		Tcl_GetInterpPath _ANSI_ARGS_((
				Tcl_Interp * askInterp, 
				Tcl_Interp * slaveInterp));
/* 164 */
EXTERN Tcl_Interp *	Tcl_GetMaster _ANSI_ARGS_((Tcl_Interp * interp));
/* 165 */
EXTERN CONST char *	Tcl_GetNameOfExecutable _ANSI_ARGS_((void));
/* 166 */
EXTERN Tcl_Obj *	Tcl_GetObjResult _ANSI_ARGS_((Tcl_Interp * interp));
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
/* 167 */
EXTERN int		Tcl_GetOpenFile _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, int write, int checkUsage, 
				ClientData * filePtr));
#endif /* UNIX */
/* 168 */
EXTERN Tcl_PathType	Tcl_GetPathType _ANSI_ARGS_((char * path));
/* 169 */
EXTERN int		Tcl_Gets _ANSI_ARGS_((Tcl_Channel chan, 
				Tcl_DString * dsPtr));
/* 170 */
EXTERN int		Tcl_GetsObj _ANSI_ARGS_((Tcl_Channel chan, 
				Tcl_Obj * objPtr));
/* 171 */
EXTERN int		Tcl_GetServiceMode _ANSI_ARGS_((void));
/* 172 */
EXTERN Tcl_Interp *	Tcl_GetSlave _ANSI_ARGS_((Tcl_Interp * interp, 
				char * slaveName));
/* 173 */
EXTERN Tcl_Channel	Tcl_GetStdChannel _ANSI_ARGS_((int type));
/* 174 */
EXTERN char *		Tcl_GetStringResult _ANSI_ARGS_((Tcl_Interp * interp));
/* 175 */
EXTERN char *		Tcl_GetVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * varName, int flags));
/* 176 */
EXTERN char *		Tcl_GetVar2 _ANSI_ARGS_((Tcl_Interp * interp, 
				char * part1, char * part2, int flags));
/* 177 */
EXTERN int		Tcl_GlobalEval _ANSI_ARGS_((Tcl_Interp * interp, 
				char * command));
/* 178 */
EXTERN int		Tcl_GlobalEvalObj _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr));
/* 179 */
EXTERN int		Tcl_HideCommand _ANSI_ARGS_((Tcl_Interp * interp, 
				char * cmdName, char * hiddenCmdToken));
/* 180 */
EXTERN int		Tcl_Init _ANSI_ARGS_((Tcl_Interp * interp));
/* 181 */
EXTERN void		Tcl_InitHashTable _ANSI_ARGS_((
				Tcl_HashTable * tablePtr, int keyType));
/* 182 */
EXTERN int		Tcl_InputBlocked _ANSI_ARGS_((Tcl_Channel chan));
/* 183 */
EXTERN int		Tcl_InputBuffered _ANSI_ARGS_((Tcl_Channel chan));
/* 184 */
EXTERN int		Tcl_InterpDeleted _ANSI_ARGS_((Tcl_Interp * interp));
/* 185 */
EXTERN int		Tcl_IsSafe _ANSI_ARGS_((Tcl_Interp * interp));
/* 186 */
EXTERN char *		Tcl_JoinPath _ANSI_ARGS_((int argc, char ** argv, 
				Tcl_DString * resultPtr));
/* 187 */
EXTERN int		Tcl_LinkVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * varName, char * addr, int type));
/* Slot 188 is reserved */
/* 189 */
EXTERN Tcl_Channel	Tcl_MakeFileChannel _ANSI_ARGS_((ClientData handle, 
				int mode));
/* 190 */
EXTERN int		Tcl_MakeSafe _ANSI_ARGS_((Tcl_Interp * interp));
/* 191 */
EXTERN Tcl_Channel	Tcl_MakeTcpClientChannel _ANSI_ARGS_((
				ClientData tcpSocket));
/* 192 */
EXTERN char *		Tcl_Merge _ANSI_ARGS_((int argc, char ** argv));
/* 193 */
EXTERN Tcl_HashEntry *	Tcl_NextHashEntry _ANSI_ARGS_((
				Tcl_HashSearch * searchPtr));
/* 194 */
EXTERN void		Tcl_NotifyChannel _ANSI_ARGS_((Tcl_Channel channel, 
				int mask));
/* 195 */
EXTERN Tcl_Obj *	Tcl_ObjGetVar2 _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * part1Ptr, Tcl_Obj * part2Ptr, 
				int flags));
/* 196 */
EXTERN Tcl_Obj *	Tcl_ObjSetVar2 _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * part1Ptr, Tcl_Obj * part2Ptr, 
				Tcl_Obj * newValuePtr, int flags));
/* 197 */
EXTERN Tcl_Channel	Tcl_OpenCommandChannel _ANSI_ARGS_((
				Tcl_Interp * interp, int argc, char ** argv, 
				int flags));
/* 198 */
EXTERN Tcl_Channel	Tcl_OpenFileChannel _ANSI_ARGS_((Tcl_Interp * interp, 
				char * fileName, char * modeString, 
				int permissions));
/* 199 */
EXTERN Tcl_Channel	Tcl_OpenTcpClient _ANSI_ARGS_((Tcl_Interp * interp, 
				int port, char * address, char * myaddr, 
				int myport, int async));
/* 200 */
EXTERN Tcl_Channel	Tcl_OpenTcpServer _ANSI_ARGS_((Tcl_Interp * interp, 
				int port, char * host, 
				Tcl_TcpAcceptProc * acceptProc, 
				ClientData callbackData));
/* 201 */
EXTERN void		Tcl_Preserve _ANSI_ARGS_((ClientData data));
/* 202 */
EXTERN void		Tcl_PrintDouble _ANSI_ARGS_((Tcl_Interp * interp, 
				double value, char * dst));
/* 203 */
EXTERN int		Tcl_PutEnv _ANSI_ARGS_((CONST char * string));
/* 204 */
EXTERN char *		Tcl_PosixError _ANSI_ARGS_((Tcl_Interp * interp));
/* 205 */
EXTERN void		Tcl_QueueEvent _ANSI_ARGS_((Tcl_Event * evPtr, 
				Tcl_QueuePosition position));
/* 206 */
EXTERN int		Tcl_Read _ANSI_ARGS_((Tcl_Channel chan, 
				char * bufPtr, int toRead));
/* 207 */
EXTERN void		Tcl_ReapDetachedProcs _ANSI_ARGS_((void));
/* 208 */
EXTERN int		Tcl_RecordAndEval _ANSI_ARGS_((Tcl_Interp * interp, 
				char * cmd, int flags));
/* 209 */
EXTERN int		Tcl_RecordAndEvalObj _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * cmdPtr, 
				int flags));
/* 210 */
EXTERN void		Tcl_RegisterChannel _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Channel chan));
/* 211 */
EXTERN void		Tcl_RegisterObjType _ANSI_ARGS_((
				Tcl_ObjType * typePtr));
/* 212 */
EXTERN Tcl_RegExp	Tcl_RegExpCompile _ANSI_ARGS_((Tcl_Interp * interp, 
				char * string));
/* 213 */
EXTERN int		Tcl_RegExpExec _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_RegExp regexp, CONST char * str, 
				CONST char * start));
/* 214 */
EXTERN int		Tcl_RegExpMatch _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, char * pattern));
/* 215 */
EXTERN void		Tcl_RegExpRange _ANSI_ARGS_((Tcl_RegExp regexp, 
				int index, char ** startPtr, char ** endPtr));
/* 216 */
EXTERN void		Tcl_Release _ANSI_ARGS_((ClientData clientData));
/* 217 */
EXTERN void		Tcl_ResetResult _ANSI_ARGS_((Tcl_Interp * interp));
/* 218 */
EXTERN int		Tcl_ScanElement _ANSI_ARGS_((CONST char * str, 
				int * flagPtr));
/* 219 */
EXTERN int		Tcl_ScanCountedElement _ANSI_ARGS_((CONST char * str, 
				int length, int * flagPtr));
/* 220 */
EXTERN int		Tcl_Seek _ANSI_ARGS_((Tcl_Channel chan, int offset, 
				int mode));
/* 221 */
EXTERN int		Tcl_ServiceAll _ANSI_ARGS_((void));
/* 222 */
EXTERN int		Tcl_ServiceEvent _ANSI_ARGS_((int flags));
/* 223 */
EXTERN void		Tcl_SetAssocData _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, Tcl_InterpDeleteProc * proc, 
				ClientData clientData));
/* 224 */
EXTERN void		Tcl_SetChannelBufferSize _ANSI_ARGS_((
				Tcl_Channel chan, int sz));
/* 225 */
EXTERN int		Tcl_SetChannelOption _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Channel chan, 
				char * optionName, char * newValue));
/* 226 */
EXTERN int		Tcl_SetCommandInfo _ANSI_ARGS_((Tcl_Interp * interp, 
				char * cmdName, Tcl_CmdInfo * infoPtr));
/* 227 */
EXTERN void		Tcl_SetErrno _ANSI_ARGS_((int err));
/* 228 */
EXTERN void		Tcl_SetErrorCode _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp));
/* 229 */
EXTERN void		Tcl_SetMaxBlockTime _ANSI_ARGS_((Tcl_Time * timePtr));
/* 230 */
EXTERN void		Tcl_SetPanicProc _ANSI_ARGS_((
				Tcl_PanicProc * panicProc));
/* 231 */
EXTERN int		Tcl_SetRecursionLimit _ANSI_ARGS_((
				Tcl_Interp * interp, int depth));
/* 232 */
EXTERN void		Tcl_SetResult _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, Tcl_FreeProc * freeProc));
/* 233 */
EXTERN int		Tcl_SetServiceMode _ANSI_ARGS_((int mode));
/* 234 */
EXTERN void		Tcl_SetObjErrorCode _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * errorObjPtr));
/* 235 */
EXTERN void		Tcl_SetObjResult _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * resultObjPtr));
/* 236 */
EXTERN void		Tcl_SetStdChannel _ANSI_ARGS_((Tcl_Channel channel, 
				int type));
/* 237 */
EXTERN char *		Tcl_SetVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * varName, char * newValue, int flags));
/* 238 */
EXTERN char *		Tcl_SetVar2 _ANSI_ARGS_((Tcl_Interp * interp, 
				char * part1, char * part2, char * newValue, 
				int flags));
/* 239 */
EXTERN char *		Tcl_SignalId _ANSI_ARGS_((int sig));
/* 240 */
EXTERN char *		Tcl_SignalMsg _ANSI_ARGS_((int sig));
/* 241 */
EXTERN void		Tcl_SourceRCFile _ANSI_ARGS_((Tcl_Interp * interp));
/* 242 */
EXTERN int		Tcl_SplitList _ANSI_ARGS_((Tcl_Interp * interp, 
				CONST char * listStr, int * argcPtr, 
				char *** argvPtr));
/* 243 */
EXTERN void		Tcl_SplitPath _ANSI_ARGS_((CONST char * path, 
				int * argcPtr, char *** argvPtr));
/* 244 */
EXTERN void		Tcl_StaticPackage _ANSI_ARGS_((Tcl_Interp * interp, 
				char * pkgName, 
				Tcl_PackageInitProc * initProc, 
				Tcl_PackageInitProc * safeInitProc));
/* 245 */
EXTERN int		Tcl_StringMatch _ANSI_ARGS_((CONST char * str, 
				CONST char * pattern));
/* 246 */
EXTERN int		Tcl_Tell _ANSI_ARGS_((Tcl_Channel chan));
/* 247 */
EXTERN int		Tcl_TraceVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * varName, int flags, 
				Tcl_VarTraceProc * proc, 
				ClientData clientData));
/* 248 */
EXTERN int		Tcl_TraceVar2 _ANSI_ARGS_((Tcl_Interp * interp, 
				char * part1, char * part2, int flags, 
				Tcl_VarTraceProc * proc, 
				ClientData clientData));
/* 249 */
EXTERN char *		Tcl_TranslateFileName _ANSI_ARGS_((
				Tcl_Interp * interp, char * name, 
				Tcl_DString * bufferPtr));
/* 250 */
EXTERN int		Tcl_Ungets _ANSI_ARGS_((Tcl_Channel chan, char * str, 
				int len, int atHead));
/* 251 */
EXTERN void		Tcl_UnlinkVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * varName));
/* 252 */
EXTERN int		Tcl_UnregisterChannel _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Channel chan));
/* 253 */
EXTERN int		Tcl_UnsetVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * varName, int flags));
/* 254 */
EXTERN int		Tcl_UnsetVar2 _ANSI_ARGS_((Tcl_Interp * interp, 
				char * part1, char * part2, int flags));
/* 255 */
EXTERN void		Tcl_UntraceVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * varName, int flags, 
				Tcl_VarTraceProc * proc, 
				ClientData clientData));
/* 256 */
EXTERN void		Tcl_UntraceVar2 _ANSI_ARGS_((Tcl_Interp * interp, 
				char * part1, char * part2, int flags, 
				Tcl_VarTraceProc * proc, 
				ClientData clientData));
/* 257 */
EXTERN void		Tcl_UpdateLinkedVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * varName));
/* 258 */
EXTERN int		Tcl_UpVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * frameName, char * varName, 
				char * localName, int flags));
/* 259 */
EXTERN int		Tcl_UpVar2 _ANSI_ARGS_((Tcl_Interp * interp, 
				char * frameName, char * part1, char * part2, 
				char * localName, int flags));
/* 260 */
EXTERN int		Tcl_VarEval _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp));
/* 261 */
EXTERN ClientData	Tcl_VarTraceInfo _ANSI_ARGS_((Tcl_Interp * interp, 
				char * varName, int flags, 
				Tcl_VarTraceProc * procPtr, 
				ClientData prevClientData));
/* 262 */
EXTERN ClientData	Tcl_VarTraceInfo2 _ANSI_ARGS_((Tcl_Interp * interp, 
				char * part1, char * part2, int flags, 
				Tcl_VarTraceProc * procPtr, 
				ClientData prevClientData));
/* 263 */
EXTERN int		Tcl_Write _ANSI_ARGS_((Tcl_Channel chan, char * s, 
				int slen));
/* 264 */
EXTERN void		Tcl_WrongNumArgs _ANSI_ARGS_((Tcl_Interp * interp, 
				int objc, Tcl_Obj *CONST objv[], 
				char * message));
/* 265 */
EXTERN int		Tcl_DumpActiveMemory _ANSI_ARGS_((char * fileName));
/* 266 */
EXTERN void		Tcl_ValidateAllMemory _ANSI_ARGS_((char * file, 
				int line));
/* 267 */
EXTERN void		Tcl_AppendResultVA _ANSI_ARGS_((Tcl_Interp * interp, 
				va_list argList));
/* 268 */
EXTERN void		Tcl_AppendStringsToObjVA _ANSI_ARGS_((
				Tcl_Obj * objPtr, va_list argList));
/* 269 */
EXTERN char *		Tcl_HashStats _ANSI_ARGS_((Tcl_HashTable * tablePtr));
/* 270 */
EXTERN char *		Tcl_ParseVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, char ** termPtr));
/* 271 */
EXTERN char *		Tcl_PkgPresent _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, char * version, int exact));
/* 272 */
EXTERN char *		Tcl_PkgPresentEx _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, char * version, int exact, 
				ClientData * clientDataPtr));
/* 273 */
EXTERN int		Tcl_PkgProvide _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, char * version));
/* 274 */
EXTERN char *		Tcl_PkgRequire _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, char * version, int exact));
/* 275 */
EXTERN void		Tcl_SetErrorCodeVA _ANSI_ARGS_((Tcl_Interp * interp, 
				va_list argList));
/* 276 */
EXTERN int		Tcl_VarEvalVA _ANSI_ARGS_((Tcl_Interp * interp, 
				va_list argList));
/* 277 */
EXTERN Tcl_Pid		Tcl_WaitPid _ANSI_ARGS_((Tcl_Pid pid, int * statPtr, 
				int options));
/* 278 */
EXTERN void		Tcl_PanicVA _ANSI_ARGS_((char * format, 
				va_list argList));
/* 279 */
EXTERN void		Tcl_GetVersion _ANSI_ARGS_((int * major, int * minor, 
				int * patchLevel, int * type));
/* 280 */
EXTERN void		Tcl_InitMemory _ANSI_ARGS_((Tcl_Interp * interp));
/* Slot 281 is reserved */
/* Slot 282 is reserved */
/* Slot 283 is reserved */
/* Slot 284 is reserved */
/* Slot 285 is reserved */
/* 286 */
EXTERN void		Tcl_AppendObjToObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				Tcl_Obj * appendObjPtr));
/* 287 */
EXTERN Tcl_Encoding	Tcl_CreateEncoding _ANSI_ARGS_((
				Tcl_EncodingType * typePtr));
/* 288 */
EXTERN void		Tcl_CreateThreadExitHandler _ANSI_ARGS_((
				Tcl_ExitProc * proc, ClientData clientData));
/* 289 */
EXTERN void		Tcl_DeleteThreadExitHandler _ANSI_ARGS_((
				Tcl_ExitProc * proc, ClientData clientData));
/* 290 */
EXTERN void		Tcl_DiscardResult _ANSI_ARGS_((
				Tcl_SavedResult * statePtr));
/* 291 */
EXTERN int		Tcl_EvalEx _ANSI_ARGS_((Tcl_Interp * interp, 
				char * script, int numBytes, int flags));
/* 292 */
EXTERN int		Tcl_EvalObjv _ANSI_ARGS_((Tcl_Interp * interp, 
				int objc, Tcl_Obj *CONST objv[], int flags));
/* 293 */
EXTERN int		Tcl_EvalObjEx _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr, int flags));
/* 294 */
EXTERN void		Tcl_ExitThread _ANSI_ARGS_((int status));
/* 295 */
EXTERN int		Tcl_ExternalToUtf _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Encoding encoding, CONST char * src, 
				int srcLen, int flags, 
				Tcl_EncodingState * statePtr, char * dst, 
				int dstLen, int * srcReadPtr, 
				int * dstWrotePtr, int * dstCharsPtr));
/* 296 */
EXTERN char *		Tcl_ExternalToUtfDString _ANSI_ARGS_((
				Tcl_Encoding encoding, CONST char * src, 
				int srcLen, Tcl_DString * dsPtr));
/* 297 */
EXTERN void		Tcl_FinalizeThread _ANSI_ARGS_((void));
/* 298 */
EXTERN void		Tcl_FinalizeNotifier _ANSI_ARGS_((
				ClientData clientData));
/* 299 */
EXTERN void		Tcl_FreeEncoding _ANSI_ARGS_((Tcl_Encoding encoding));
/* 300 */
EXTERN Tcl_ThreadId	Tcl_GetCurrentThread _ANSI_ARGS_((void));
/* 301 */
EXTERN Tcl_Encoding	Tcl_GetEncoding _ANSI_ARGS_((Tcl_Interp * interp, 
				CONST char * name));
/* 302 */
EXTERN char *		Tcl_GetEncodingName _ANSI_ARGS_((
				Tcl_Encoding encoding));
/* 303 */
EXTERN void		Tcl_GetEncodingNames _ANSI_ARGS_((
				Tcl_Interp * interp));
/* 304 */
EXTERN int		Tcl_GetIndexFromObjStruct _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * objPtr, 
				char ** tablePtr, int offset, char * msg, 
				int flags, int * indexPtr));
/* 305 */
EXTERN VOID *		Tcl_GetThreadData _ANSI_ARGS_((
				Tcl_ThreadDataKey * keyPtr, int size));
/* 306 */
EXTERN Tcl_Obj *	Tcl_GetVar2Ex _ANSI_ARGS_((Tcl_Interp * interp, 
				char * part1, char * part2, int flags));
/* 307 */
EXTERN ClientData	Tcl_InitNotifier _ANSI_ARGS_((void));
/* 308 */
EXTERN void		Tcl_MutexLock _ANSI_ARGS_((Tcl_Mutex * mutexPtr));
/* 309 */
EXTERN void		Tcl_MutexUnlock _ANSI_ARGS_((Tcl_Mutex * mutexPtr));
/* 310 */
EXTERN void		Tcl_ConditionNotify _ANSI_ARGS_((
				Tcl_Condition * condPtr));
/* 311 */
EXTERN void		Tcl_ConditionWait _ANSI_ARGS_((
				Tcl_Condition * condPtr, 
				Tcl_Mutex * mutexPtr, Tcl_Time * timePtr));
/* 312 */
EXTERN int		Tcl_NumUtfChars _ANSI_ARGS_((CONST char * src, 
				int len));
/* 313 */
EXTERN int		Tcl_ReadChars _ANSI_ARGS_((Tcl_Channel channel, 
				Tcl_Obj * objPtr, int charsToRead, 
				int appendFlag));
/* 314 */
EXTERN void		Tcl_RestoreResult _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_SavedResult * statePtr));
/* 315 */
EXTERN void		Tcl_SaveResult _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_SavedResult * statePtr));
/* 316 */
EXTERN int		Tcl_SetSystemEncoding _ANSI_ARGS_((
				Tcl_Interp * interp, CONST char * name));
/* 317 */
EXTERN Tcl_Obj *	Tcl_SetVar2Ex _ANSI_ARGS_((Tcl_Interp * interp, 
				char * part1, char * part2, 
				Tcl_Obj * newValuePtr, int flags));
/* 318 */
EXTERN void		Tcl_ThreadAlert _ANSI_ARGS_((Tcl_ThreadId threadId));
/* 319 */
EXTERN void		Tcl_ThreadQueueEvent _ANSI_ARGS_((
				Tcl_ThreadId threadId, Tcl_Event* evPtr, 
				Tcl_QueuePosition position));
/* 320 */
EXTERN Tcl_UniChar	Tcl_UniCharAtIndex _ANSI_ARGS_((CONST char * src, 
				int index));
/* 321 */
EXTERN Tcl_UniChar	Tcl_UniCharToLower _ANSI_ARGS_((int ch));
/* 322 */
EXTERN Tcl_UniChar	Tcl_UniCharToTitle _ANSI_ARGS_((int ch));
/* 323 */
EXTERN Tcl_UniChar	Tcl_UniCharToUpper _ANSI_ARGS_((int ch));
/* 324 */
EXTERN int		Tcl_UniCharToUtf _ANSI_ARGS_((int ch, char * buf));
/* 325 */
EXTERN char *		Tcl_UtfAtIndex _ANSI_ARGS_((CONST char * src, 
				int index));
/* 326 */
EXTERN int		Tcl_UtfCharComplete _ANSI_ARGS_((CONST char * src, 
				int len));
/* 327 */
EXTERN int		Tcl_UtfBackslash _ANSI_ARGS_((CONST char * src, 
				int * readPtr, char * dst));
/* 328 */
EXTERN char *		Tcl_UtfFindFirst _ANSI_ARGS_((CONST char * src, 
				int ch));
/* 329 */
EXTERN char *		Tcl_UtfFindLast _ANSI_ARGS_((CONST char * src, 
				int ch));
/* 330 */
EXTERN char *		Tcl_UtfNext _ANSI_ARGS_((CONST char * src));
/* 331 */
EXTERN char *		Tcl_UtfPrev _ANSI_ARGS_((CONST char * src, 
				CONST char * start));
/* 332 */
EXTERN int		Tcl_UtfToExternal _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Encoding encoding, CONST char * src, 
				int srcLen, int flags, 
				Tcl_EncodingState * statePtr, char * dst, 
				int dstLen, int * srcReadPtr, 
				int * dstWrotePtr, int * dstCharsPtr));
/* 333 */
EXTERN char *		Tcl_UtfToExternalDString _ANSI_ARGS_((
				Tcl_Encoding encoding, CONST char * src, 
				int srcLen, Tcl_DString * dsPtr));
/* 334 */
EXTERN int		Tcl_UtfToLower _ANSI_ARGS_((char * src));
/* 335 */
EXTERN int		Tcl_UtfToTitle _ANSI_ARGS_((char * src));
/* 336 */
EXTERN int		Tcl_UtfToUniChar _ANSI_ARGS_((CONST char * src, 
				Tcl_UniChar * chPtr));
/* 337 */
EXTERN int		Tcl_UtfToUpper _ANSI_ARGS_((char * src));
/* 338 */
EXTERN int		Tcl_WriteChars _ANSI_ARGS_((Tcl_Channel chan, 
				CONST char * src, int srcLen));
/* 339 */
EXTERN int		Tcl_WriteObj _ANSI_ARGS_((Tcl_Channel chan, 
				Tcl_Obj * objPtr));
/* 340 */
EXTERN char *		Tcl_GetString _ANSI_ARGS_((Tcl_Obj * objPtr));
/* 341 */
EXTERN char *		Tcl_GetDefaultEncodingDir _ANSI_ARGS_((void));
/* 342 */
EXTERN void		Tcl_SetDefaultEncodingDir _ANSI_ARGS_((char * path));
/* 343 */
EXTERN void		Tcl_AlertNotifier _ANSI_ARGS_((ClientData clientData));
/* 344 */
EXTERN void		Tcl_ServiceModeHook _ANSI_ARGS_((int mode));
/* 345 */
EXTERN int		Tcl_UniCharIsAlnum _ANSI_ARGS_((int ch));
/* 346 */
EXTERN int		Tcl_UniCharIsAlpha _ANSI_ARGS_((int ch));
/* 347 */
EXTERN int		Tcl_UniCharIsDigit _ANSI_ARGS_((int ch));
/* 348 */
EXTERN int		Tcl_UniCharIsLower _ANSI_ARGS_((int ch));
/* 349 */
EXTERN int		Tcl_UniCharIsSpace _ANSI_ARGS_((int ch));
/* 350 */
EXTERN int		Tcl_UniCharIsUpper _ANSI_ARGS_((int ch));
/* 351 */
EXTERN int		Tcl_UniCharIsWordChar _ANSI_ARGS_((int ch));
/* 352 */
EXTERN int		Tcl_UniCharLen _ANSI_ARGS_((Tcl_UniChar * str));
/* 353 */
EXTERN int		Tcl_UniCharNcmp _ANSI_ARGS_((const Tcl_UniChar * cs, 
				const Tcl_UniChar * ct, size_t n));
/* 354 */
EXTERN char *		Tcl_UniCharToUtfDString _ANSI_ARGS_((
				CONST Tcl_UniChar * string, int numChars, 
				Tcl_DString * dsPtr));
/* 355 */
EXTERN Tcl_UniChar *	Tcl_UtfToUniCharDString _ANSI_ARGS_((
				CONST char * string, int length, 
				Tcl_DString * dsPtr));
/* 356 */
EXTERN Tcl_RegExp	Tcl_GetRegExpFromObj _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * patObj, 
				int flags));
/* 357 */
EXTERN Tcl_Obj *	Tcl_EvalTokens _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Token * tokenPtr, int count));
/* 358 */
EXTERN void		Tcl_FreeParse _ANSI_ARGS_((Tcl_Parse * parsePtr));
/* 359 */
EXTERN void		Tcl_LogCommandInfo _ANSI_ARGS_((Tcl_Interp * interp, 
				char * script, char * command, int length));
/* 360 */
EXTERN int		Tcl_ParseBraces _ANSI_ARGS_((Tcl_Interp * interp, 
				char * string, int numBytes, 
				Tcl_Parse * parsePtr, int append, 
				char ** termPtr));
/* 361 */
EXTERN int		Tcl_ParseCommand _ANSI_ARGS_((Tcl_Interp * interp, 
				char * string, int numBytes, int nested, 
				Tcl_Parse * parsePtr));
/* 362 */
EXTERN int		Tcl_ParseExpr _ANSI_ARGS_((Tcl_Interp * interp, 
				char * string, int numBytes, 
				Tcl_Parse * parsePtr));
/* 363 */
EXTERN int		Tcl_ParseQuotedString _ANSI_ARGS_((
				Tcl_Interp * interp, char * string, 
				int numBytes, Tcl_Parse * parsePtr, 
				int append, char ** termPtr));
/* 364 */
EXTERN int		Tcl_ParseVarName _ANSI_ARGS_((Tcl_Interp * interp, 
				char * string, int numBytes, 
				Tcl_Parse * parsePtr, int append));
/* 365 */
EXTERN char *		Tcl_GetCwd _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_DString * cwdPtr));
/* 366 */
EXTERN int		Tcl_Chdir _ANSI_ARGS_((CONST char * dirName));

typedef struct TclStubHooks {
    struct TclPlatStubs *tclPlatStubs;
    struct TclIntStubs *tclIntStubs;
    struct TclIntPlatStubs *tclIntPlatStubs;
} TclStubHooks;

typedef struct TclStubs {
    int magic;
    struct TclStubHooks *hooks;

    int (*tcl_PkgProvideEx) _ANSI_ARGS_((Tcl_Interp * interp, char * name, char * version, ClientData clientData)); /* 0 */
    char * (*tcl_PkgRequireEx) _ANSI_ARGS_((Tcl_Interp * interp, char * name, char * version, int exact, ClientData * clientDataPtr)); /* 1 */
    void (*tcl_Panic) _ANSI_ARGS_(TCL_VARARGS(char *,format)); /* 2 */
    char * (*tcl_Alloc) _ANSI_ARGS_((unsigned int size)); /* 3 */
    void (*tcl_Free) _ANSI_ARGS_((char * ptr)); /* 4 */
    char * (*tcl_Realloc) _ANSI_ARGS_((char * ptr, unsigned int size)); /* 5 */
    char * (*tcl_DbCkalloc) _ANSI_ARGS_((unsigned int size, char * file, int line)); /* 6 */
    int (*tcl_DbCkfree) _ANSI_ARGS_((char * ptr, char * file, int line)); /* 7 */
    char * (*tcl_DbCkrealloc) _ANSI_ARGS_((char * ptr, unsigned int size, char * file, int line)); /* 8 */
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
    void (*tcl_CreateFileHandler) _ANSI_ARGS_((int fd, int mask, Tcl_FileProc * proc, ClientData clientData)); /* 9 */
#endif /* UNIX */
#ifdef __WIN32__
    void *reserved9;
#endif /* __WIN32__ */
#ifdef MAC_TCL
    void *reserved9;
#endif /* MAC_TCL */
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
    void (*tcl_DeleteFileHandler) _ANSI_ARGS_((int fd)); /* 10 */
#endif /* UNIX */
#ifdef __WIN32__
    void *reserved10;
#endif /* __WIN32__ */
#ifdef MAC_TCL
    void *reserved10;
#endif /* MAC_TCL */
    void (*tcl_SetTimer) _ANSI_ARGS_((Tcl_Time * timePtr)); /* 11 */
    void (*tcl_Sleep) _ANSI_ARGS_((int ms)); /* 12 */
    int (*tcl_WaitForEvent) _ANSI_ARGS_((Tcl_Time * timePtr)); /* 13 */
    int (*tcl_AppendAllObjTypes) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr)); /* 14 */
    void (*tcl_AppendStringsToObj) _ANSI_ARGS_(TCL_VARARGS(Tcl_Obj *,objPtr)); /* 15 */
    void (*tcl_AppendToObj) _ANSI_ARGS_((Tcl_Obj * objPtr, char * bytes, int length)); /* 16 */
    Tcl_Obj * (*tcl_ConcatObj) _ANSI_ARGS_((int objc, Tcl_Obj *CONST objv[])); /* 17 */
    int (*tcl_ConvertToType) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, Tcl_ObjType * typePtr)); /* 18 */
    void (*tcl_DbDecrRefCount) _ANSI_ARGS_((Tcl_Obj * objPtr, char * file, int line)); /* 19 */
    void (*tcl_DbIncrRefCount) _ANSI_ARGS_((Tcl_Obj * objPtr, char * file, int line)); /* 20 */
    int (*tcl_DbIsShared) _ANSI_ARGS_((Tcl_Obj * objPtr, char * file, int line)); /* 21 */
    Tcl_Obj * (*tcl_DbNewBooleanObj) _ANSI_ARGS_((int boolValue, char * file, int line)); /* 22 */
    Tcl_Obj * (*tcl_DbNewByteArrayObj) _ANSI_ARGS_((unsigned char * bytes, int length, char * file, int line)); /* 23 */
    Tcl_Obj * (*tcl_DbNewDoubleObj) _ANSI_ARGS_((double doubleValue, char * file, int line)); /* 24 */
    Tcl_Obj * (*tcl_DbNewListObj) _ANSI_ARGS_((int objc, Tcl_Obj *CONST objv[], char * file, int line)); /* 25 */
    Tcl_Obj * (*tcl_DbNewLongObj) _ANSI_ARGS_((long longValue, char * file, int line)); /* 26 */
    Tcl_Obj * (*tcl_DbNewObj) _ANSI_ARGS_((char * file, int line)); /* 27 */
    Tcl_Obj * (*tcl_DbNewStringObj) _ANSI_ARGS_((CONST char * bytes, int length, char * file, int line)); /* 28 */
    Tcl_Obj * (*tcl_DuplicateObj) _ANSI_ARGS_((Tcl_Obj * objPtr)); /* 29 */
    void (*tclFreeObj) _ANSI_ARGS_((Tcl_Obj * objPtr)); /* 30 */
    int (*tcl_GetBoolean) _ANSI_ARGS_((Tcl_Interp * interp, char * str, int * boolPtr)); /* 31 */
    int (*tcl_GetBooleanFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, int * boolPtr)); /* 32 */
    unsigned char * (*tcl_GetByteArrayFromObj) _ANSI_ARGS_((Tcl_Obj * objPtr, int * lengthPtr)); /* 33 */
    int (*tcl_GetDouble) _ANSI_ARGS_((Tcl_Interp * interp, char * str, double * doublePtr)); /* 34 */
    int (*tcl_GetDoubleFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, double * doublePtr)); /* 35 */
    int (*tcl_GetIndexFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, char ** tablePtr, char * msg, int flags, int * indexPtr)); /* 36 */
    int (*tcl_GetInt) _ANSI_ARGS_((Tcl_Interp * interp, char * str, int * intPtr)); /* 37 */
    int (*tcl_GetIntFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, int * intPtr)); /* 38 */
    int (*tcl_GetLongFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, long * longPtr)); /* 39 */
    Tcl_ObjType * (*tcl_GetObjType) _ANSI_ARGS_((char * typeName)); /* 40 */
    char * (*tcl_GetStringFromObj) _ANSI_ARGS_((Tcl_Obj * objPtr, int * lengthPtr)); /* 41 */
    void (*tcl_InvalidateStringRep) _ANSI_ARGS_((Tcl_Obj * objPtr)); /* 42 */
    int (*tcl_ListObjAppendList) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * listPtr, Tcl_Obj * elemListPtr)); /* 43 */
    int (*tcl_ListObjAppendElement) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * listPtr, Tcl_Obj * objPtr)); /* 44 */
    int (*tcl_ListObjGetElements) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * listPtr, int * objcPtr, Tcl_Obj *** objvPtr)); /* 45 */
    int (*tcl_ListObjIndex) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * listPtr, int index, Tcl_Obj ** objPtrPtr)); /* 46 */
    int (*tcl_ListObjLength) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * listPtr, int * intPtr)); /* 47 */
    int (*tcl_ListObjReplace) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * listPtr, int first, int count, int objc, Tcl_Obj *CONST objv[])); /* 48 */
    Tcl_Obj * (*tcl_NewBooleanObj) _ANSI_ARGS_((int boolValue)); /* 49 */
    Tcl_Obj * (*tcl_NewByteArrayObj) _ANSI_ARGS_((unsigned char * bytes, int length)); /* 50 */
    Tcl_Obj * (*tcl_NewDoubleObj) _ANSI_ARGS_((double doubleValue)); /* 51 */
    Tcl_Obj * (*tcl_NewIntObj) _ANSI_ARGS_((int intValue)); /* 52 */
    Tcl_Obj * (*tcl_NewListObj) _ANSI_ARGS_((int objc, Tcl_Obj *CONST objv[])); /* 53 */
    Tcl_Obj * (*tcl_NewLongObj) _ANSI_ARGS_((long longValue)); /* 54 */
    Tcl_Obj * (*tcl_NewObj) _ANSI_ARGS_((void)); /* 55 */
    Tcl_Obj * (*tcl_NewStringObj) _ANSI_ARGS_((CONST char * bytes, int length)); /* 56 */
    void (*tcl_SetBooleanObj) _ANSI_ARGS_((Tcl_Obj * objPtr, int boolValue)); /* 57 */
    unsigned char * (*tcl_SetByteArrayLength) _ANSI_ARGS_((Tcl_Obj * objPtr, int length)); /* 58 */
    void (*tcl_SetByteArrayObj) _ANSI_ARGS_((Tcl_Obj * objPtr, unsigned char * bytes, int length)); /* 59 */
    void (*tcl_SetDoubleObj) _ANSI_ARGS_((Tcl_Obj * objPtr, double doubleValue)); /* 60 */
    void (*tcl_SetIntObj) _ANSI_ARGS_((Tcl_Obj * objPtr, int intValue)); /* 61 */
    void (*tcl_SetListObj) _ANSI_ARGS_((Tcl_Obj * objPtr, int objc, Tcl_Obj *CONST objv[])); /* 62 */
    void (*tcl_SetLongObj) _ANSI_ARGS_((Tcl_Obj * objPtr, long longValue)); /* 63 */
    void (*tcl_SetObjLength) _ANSI_ARGS_((Tcl_Obj * objPtr, int length)); /* 64 */
    void (*tcl_SetStringObj) _ANSI_ARGS_((Tcl_Obj * objPtr, char * bytes, int length)); /* 65 */
    void (*tcl_AddErrorInfo) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * message)); /* 66 */
    void (*tcl_AddObjErrorInfo) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * message, int length)); /* 67 */
    void (*tcl_AllowExceptions) _ANSI_ARGS_((Tcl_Interp * interp)); /* 68 */
    void (*tcl_AppendElement) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * string)); /* 69 */
    void (*tcl_AppendResult) _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp)); /* 70 */
    Tcl_AsyncHandler (*tcl_AsyncCreate) _ANSI_ARGS_((Tcl_AsyncProc * proc, ClientData clientData)); /* 71 */
    void (*tcl_AsyncDelete) _ANSI_ARGS_((Tcl_AsyncHandler async)); /* 72 */
    int (*tcl_AsyncInvoke) _ANSI_ARGS_((Tcl_Interp * interp, int code)); /* 73 */
    void (*tcl_AsyncMark) _ANSI_ARGS_((Tcl_AsyncHandler async)); /* 74 */
    int (*tcl_AsyncReady) _ANSI_ARGS_((void)); /* 75 */
    void (*tcl_BackgroundError) _ANSI_ARGS_((Tcl_Interp * interp)); /* 76 */
    char (*tcl_Backslash) _ANSI_ARGS_((CONST char * src, int * readPtr)); /* 77 */
    int (*tcl_BadChannelOption) _ANSI_ARGS_((Tcl_Interp * interp, char * optionName, char * optionList)); /* 78 */
    void (*tcl_CallWhenDeleted) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_InterpDeleteProc * proc, ClientData clientData)); /* 79 */
    void (*tcl_CancelIdleCall) _ANSI_ARGS_((Tcl_IdleProc * idleProc, ClientData clientData)); /* 80 */
    int (*tcl_Close) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 81 */
    int (*tcl_CommandComplete) _ANSI_ARGS_((char * cmd)); /* 82 */
    char * (*tcl_Concat) _ANSI_ARGS_((int argc, char ** argv)); /* 83 */
    int (*tcl_ConvertElement) _ANSI_ARGS_((CONST char * src, char * dst, int flags)); /* 84 */
    int (*tcl_ConvertCountedElement) _ANSI_ARGS_((CONST char * src, int length, char * dst, int flags)); /* 85 */
    int (*tcl_CreateAlias) _ANSI_ARGS_((Tcl_Interp * slave, char * slaveCmd, Tcl_Interp * target, char * targetCmd, int argc, char ** argv)); /* 86 */
    int (*tcl_CreateAliasObj) _ANSI_ARGS_((Tcl_Interp * slave, char * slaveCmd, Tcl_Interp * target, char * targetCmd, int objc, Tcl_Obj *CONST objv[])); /* 87 */
    Tcl_Channel (*tcl_CreateChannel) _ANSI_ARGS_((Tcl_ChannelType * typePtr, char * chanName, ClientData instanceData, int mask)); /* 88 */
    void (*tcl_CreateChannelHandler) _ANSI_ARGS_((Tcl_Channel chan, int mask, Tcl_ChannelProc * proc, ClientData clientData)); /* 89 */
    void (*tcl_CreateCloseHandler) _ANSI_ARGS_((Tcl_Channel chan, Tcl_CloseProc * proc, ClientData clientData)); /* 90 */
    Tcl_Command (*tcl_CreateCommand) _ANSI_ARGS_((Tcl_Interp * interp, char * cmdName, Tcl_CmdProc * proc, ClientData clientData, Tcl_CmdDeleteProc * deleteProc)); /* 91 */
    void (*tcl_CreateEventSource) _ANSI_ARGS_((Tcl_EventSetupProc * setupProc, Tcl_EventCheckProc * checkProc, ClientData clientData)); /* 92 */
    void (*tcl_CreateExitHandler) _ANSI_ARGS_((Tcl_ExitProc * proc, ClientData clientData)); /* 93 */
    Tcl_Interp * (*tcl_CreateInterp) _ANSI_ARGS_((void)); /* 94 */
    void (*tcl_CreateMathFunc) _ANSI_ARGS_((Tcl_Interp * interp, char * name, int numArgs, Tcl_ValueType * argTypes, Tcl_MathProc * proc, ClientData clientData)); /* 95 */
    Tcl_Command (*tcl_CreateObjCommand) _ANSI_ARGS_((Tcl_Interp * interp, char * cmdName, Tcl_ObjCmdProc * proc, ClientData clientData, Tcl_CmdDeleteProc * deleteProc)); /* 96 */
    Tcl_Interp * (*tcl_CreateSlave) _ANSI_ARGS_((Tcl_Interp * interp, char * slaveName, int isSafe)); /* 97 */
    Tcl_TimerToken (*tcl_CreateTimerHandler) _ANSI_ARGS_((int milliseconds, Tcl_TimerProc * proc, ClientData clientData)); /* 98 */
    Tcl_Trace (*tcl_CreateTrace) _ANSI_ARGS_((Tcl_Interp * interp, int level, Tcl_CmdTraceProc * proc, ClientData clientData)); /* 99 */
    void (*tcl_DeleteAssocData) _ANSI_ARGS_((Tcl_Interp * interp, char * name)); /* 100 */
    void (*tcl_DeleteChannelHandler) _ANSI_ARGS_((Tcl_Channel chan, Tcl_ChannelProc * proc, ClientData clientData)); /* 101 */
    void (*tcl_DeleteCloseHandler) _ANSI_ARGS_((Tcl_Channel chan, Tcl_CloseProc * proc, ClientData clientData)); /* 102 */
    int (*tcl_DeleteCommand) _ANSI_ARGS_((Tcl_Interp * interp, char * cmdName)); /* 103 */
    int (*tcl_DeleteCommandFromToken) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command command)); /* 104 */
    void (*tcl_DeleteEvents) _ANSI_ARGS_((Tcl_EventDeleteProc * proc, ClientData clientData)); /* 105 */
    void (*tcl_DeleteEventSource) _ANSI_ARGS_((Tcl_EventSetupProc * setupProc, Tcl_EventCheckProc * checkProc, ClientData clientData)); /* 106 */
    void (*tcl_DeleteExitHandler) _ANSI_ARGS_((Tcl_ExitProc * proc, ClientData clientData)); /* 107 */
    void (*tcl_DeleteHashEntry) _ANSI_ARGS_((Tcl_HashEntry * entryPtr)); /* 108 */
    void (*tcl_DeleteHashTable) _ANSI_ARGS_((Tcl_HashTable * tablePtr)); /* 109 */
    void (*tcl_DeleteInterp) _ANSI_ARGS_((Tcl_Interp * interp)); /* 110 */
    void (*tcl_DetachPids) _ANSI_ARGS_((int numPids, Tcl_Pid * pidPtr)); /* 111 */
    void (*tcl_DeleteTimerHandler) _ANSI_ARGS_((Tcl_TimerToken token)); /* 112 */
    void (*tcl_DeleteTrace) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Trace trace)); /* 113 */
    void (*tcl_DontCallWhenDeleted) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_InterpDeleteProc * proc, ClientData clientData)); /* 114 */
    int (*tcl_DoOneEvent) _ANSI_ARGS_((int flags)); /* 115 */
    void (*tcl_DoWhenIdle) _ANSI_ARGS_((Tcl_IdleProc * proc, ClientData clientData)); /* 116 */
    char * (*tcl_DStringAppend) _ANSI_ARGS_((Tcl_DString * dsPtr, CONST char * str, int length)); /* 117 */
    char * (*tcl_DStringAppendElement) _ANSI_ARGS_((Tcl_DString * dsPtr, CONST char * string)); /* 118 */
    void (*tcl_DStringEndSublist) _ANSI_ARGS_((Tcl_DString * dsPtr)); /* 119 */
    void (*tcl_DStringFree) _ANSI_ARGS_((Tcl_DString * dsPtr)); /* 120 */
    void (*tcl_DStringGetResult) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_DString * dsPtr)); /* 121 */
    void (*tcl_DStringInit) _ANSI_ARGS_((Tcl_DString * dsPtr)); /* 122 */
    void (*tcl_DStringResult) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_DString * dsPtr)); /* 123 */
    void (*tcl_DStringSetLength) _ANSI_ARGS_((Tcl_DString * dsPtr, int length)); /* 124 */
    void (*tcl_DStringStartSublist) _ANSI_ARGS_((Tcl_DString * dsPtr)); /* 125 */
    int (*tcl_Eof) _ANSI_ARGS_((Tcl_Channel chan)); /* 126 */
    char * (*tcl_ErrnoId) _ANSI_ARGS_((void)); /* 127 */
    char * (*tcl_ErrnoMsg) _ANSI_ARGS_((int err)); /* 128 */
    int (*tcl_Eval) _ANSI_ARGS_((Tcl_Interp * interp, char * string)); /* 129 */
    int (*tcl_EvalFile) _ANSI_ARGS_((Tcl_Interp * interp, char * fileName)); /* 130 */
    int (*tcl_EvalObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr)); /* 131 */
    void (*tcl_EventuallyFree) _ANSI_ARGS_((ClientData clientData, Tcl_FreeProc * freeProc)); /* 132 */
    void (*tcl_Exit) _ANSI_ARGS_((int status)); /* 133 */
    int (*tcl_ExposeCommand) _ANSI_ARGS_((Tcl_Interp * interp, char * hiddenCmdToken, char * cmdName)); /* 134 */
    int (*tcl_ExprBoolean) _ANSI_ARGS_((Tcl_Interp * interp, char * str, int * ptr)); /* 135 */
    int (*tcl_ExprBooleanObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, int * ptr)); /* 136 */
    int (*tcl_ExprDouble) _ANSI_ARGS_((Tcl_Interp * interp, char * str, double * ptr)); /* 137 */
    int (*tcl_ExprDoubleObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, double * ptr)); /* 138 */
    int (*tcl_ExprLong) _ANSI_ARGS_((Tcl_Interp * interp, char * str, long * ptr)); /* 139 */
    int (*tcl_ExprLongObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, long * ptr)); /* 140 */
    int (*tcl_ExprObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, Tcl_Obj ** resultPtrPtr)); /* 141 */
    int (*tcl_ExprString) _ANSI_ARGS_((Tcl_Interp * interp, char * string)); /* 142 */
    void (*tcl_Finalize) _ANSI_ARGS_((void)); /* 143 */
    void (*tcl_FindExecutable) _ANSI_ARGS_((CONST char * argv0)); /* 144 */
    Tcl_HashEntry * (*tcl_FirstHashEntry) _ANSI_ARGS_((Tcl_HashTable * tablePtr, Tcl_HashSearch * searchPtr)); /* 145 */
    int (*tcl_Flush) _ANSI_ARGS_((Tcl_Channel chan)); /* 146 */
    void (*tcl_FreeResult) _ANSI_ARGS_((Tcl_Interp * interp)); /* 147 */
    int (*tcl_GetAlias) _ANSI_ARGS_((Tcl_Interp * interp, char * slaveCmd, Tcl_Interp ** targetInterpPtr, char ** targetCmdPtr, int * argcPtr, char *** argvPtr)); /* 148 */
    int (*tcl_GetAliasObj) _ANSI_ARGS_((Tcl_Interp * interp, char * slaveCmd, Tcl_Interp ** targetInterpPtr, char ** targetCmdPtr, int * objcPtr, Tcl_Obj *** objv)); /* 149 */
    ClientData (*tcl_GetAssocData) _ANSI_ARGS_((Tcl_Interp * interp, char * name, Tcl_InterpDeleteProc ** procPtr)); /* 150 */
    Tcl_Channel (*tcl_GetChannel) _ANSI_ARGS_((Tcl_Interp * interp, char * chanName, int * modePtr)); /* 151 */
    int (*tcl_GetChannelBufferSize) _ANSI_ARGS_((Tcl_Channel chan)); /* 152 */
    int (*tcl_GetChannelHandle) _ANSI_ARGS_((Tcl_Channel chan, int direction, ClientData * handlePtr)); /* 153 */
    ClientData (*tcl_GetChannelInstanceData) _ANSI_ARGS_((Tcl_Channel chan)); /* 154 */
    int (*tcl_GetChannelMode) _ANSI_ARGS_((Tcl_Channel chan)); /* 155 */
    char * (*tcl_GetChannelName) _ANSI_ARGS_((Tcl_Channel chan)); /* 156 */
    int (*tcl_GetChannelOption) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan, char * optionName, Tcl_DString * dsPtr)); /* 157 */
    Tcl_ChannelType * (*tcl_GetChannelType) _ANSI_ARGS_((Tcl_Channel chan)); /* 158 */
    int (*tcl_GetCommandInfo) _ANSI_ARGS_((Tcl_Interp * interp, char * cmdName, Tcl_CmdInfo * infoPtr)); /* 159 */
    char * (*tcl_GetCommandName) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command command)); /* 160 */
    int (*tcl_GetErrno) _ANSI_ARGS_((void)); /* 161 */
    char * (*tcl_GetHostName) _ANSI_ARGS_((void)); /* 162 */
    int (*tcl_GetInterpPath) _ANSI_ARGS_((Tcl_Interp * askInterp, Tcl_Interp * slaveInterp)); /* 163 */
    Tcl_Interp * (*tcl_GetMaster) _ANSI_ARGS_((Tcl_Interp * interp)); /* 164 */
    CONST char * (*tcl_GetNameOfExecutable) _ANSI_ARGS_((void)); /* 165 */
    Tcl_Obj * (*tcl_GetObjResult) _ANSI_ARGS_((Tcl_Interp * interp)); /* 166 */
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
    int (*tcl_GetOpenFile) _ANSI_ARGS_((Tcl_Interp * interp, char * str, int write, int checkUsage, ClientData * filePtr)); /* 167 */
#endif /* UNIX */
#ifdef __WIN32__
    void *reserved167;
#endif /* __WIN32__ */
#ifdef MAC_TCL
    void *reserved167;
#endif /* MAC_TCL */
    Tcl_PathType (*tcl_GetPathType) _ANSI_ARGS_((char * path)); /* 168 */
    int (*tcl_Gets) _ANSI_ARGS_((Tcl_Channel chan, Tcl_DString * dsPtr)); /* 169 */
    int (*tcl_GetsObj) _ANSI_ARGS_((Tcl_Channel chan, Tcl_Obj * objPtr)); /* 170 */
    int (*tcl_GetServiceMode) _ANSI_ARGS_((void)); /* 171 */
    Tcl_Interp * (*tcl_GetSlave) _ANSI_ARGS_((Tcl_Interp * interp, char * slaveName)); /* 172 */
    Tcl_Channel (*tcl_GetStdChannel) _ANSI_ARGS_((int type)); /* 173 */
    char * (*tcl_GetStringResult) _ANSI_ARGS_((Tcl_Interp * interp)); /* 174 */
    char * (*tcl_GetVar) _ANSI_ARGS_((Tcl_Interp * interp, char * varName, int flags)); /* 175 */
    char * (*tcl_GetVar2) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags)); /* 176 */
    int (*tcl_GlobalEval) _ANSI_ARGS_((Tcl_Interp * interp, char * command)); /* 177 */
    int (*tcl_GlobalEvalObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr)); /* 178 */
    int (*tcl_HideCommand) _ANSI_ARGS_((Tcl_Interp * interp, char * cmdName, char * hiddenCmdToken)); /* 179 */
    int (*tcl_Init) _ANSI_ARGS_((Tcl_Interp * interp)); /* 180 */
    void (*tcl_InitHashTable) _ANSI_ARGS_((Tcl_HashTable * tablePtr, int keyType)); /* 181 */
    int (*tcl_InputBlocked) _ANSI_ARGS_((Tcl_Channel chan)); /* 182 */
    int (*tcl_InputBuffered) _ANSI_ARGS_((Tcl_Channel chan)); /* 183 */
    int (*tcl_InterpDeleted) _ANSI_ARGS_((Tcl_Interp * interp)); /* 184 */
    int (*tcl_IsSafe) _ANSI_ARGS_((Tcl_Interp * interp)); /* 185 */
    char * (*tcl_JoinPath) _ANSI_ARGS_((int argc, char ** argv, Tcl_DString * resultPtr)); /* 186 */
    int (*tcl_LinkVar) _ANSI_ARGS_((Tcl_Interp * interp, char * varName, char * addr, int type)); /* 187 */
    void *reserved188;
    Tcl_Channel (*tcl_MakeFileChannel) _ANSI_ARGS_((ClientData handle, int mode)); /* 189 */
    int (*tcl_MakeSafe) _ANSI_ARGS_((Tcl_Interp * interp)); /* 190 */
    Tcl_Channel (*tcl_MakeTcpClientChannel) _ANSI_ARGS_((ClientData tcpSocket)); /* 191 */
    char * (*tcl_Merge) _ANSI_ARGS_((int argc, char ** argv)); /* 192 */
    Tcl_HashEntry * (*tcl_NextHashEntry) _ANSI_ARGS_((Tcl_HashSearch * searchPtr)); /* 193 */
    void (*tcl_NotifyChannel) _ANSI_ARGS_((Tcl_Channel channel, int mask)); /* 194 */
    Tcl_Obj * (*tcl_ObjGetVar2) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * part1Ptr, Tcl_Obj * part2Ptr, int flags)); /* 195 */
    Tcl_Obj * (*tcl_ObjSetVar2) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * part1Ptr, Tcl_Obj * part2Ptr, Tcl_Obj * newValuePtr, int flags)); /* 196 */
    Tcl_Channel (*tcl_OpenCommandChannel) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv, int flags)); /* 197 */
    Tcl_Channel (*tcl_OpenFileChannel) _ANSI_ARGS_((Tcl_Interp * interp, char * fileName, char * modeString, int permissions)); /* 198 */
    Tcl_Channel (*tcl_OpenTcpClient) _ANSI_ARGS_((Tcl_Interp * interp, int port, char * address, char * myaddr, int myport, int async)); /* 199 */
    Tcl_Channel (*tcl_OpenTcpServer) _ANSI_ARGS_((Tcl_Interp * interp, int port, char * host, Tcl_TcpAcceptProc * acceptProc, ClientData callbackData)); /* 200 */
    void (*tcl_Preserve) _ANSI_ARGS_((ClientData data)); /* 201 */
    void (*tcl_PrintDouble) _ANSI_ARGS_((Tcl_Interp * interp, double value, char * dst)); /* 202 */
    int (*tcl_PutEnv) _ANSI_ARGS_((CONST char * string)); /* 203 */
    char * (*tcl_PosixError) _ANSI_ARGS_((Tcl_Interp * interp)); /* 204 */
    void (*tcl_QueueEvent) _ANSI_ARGS_((Tcl_Event * evPtr, Tcl_QueuePosition position)); /* 205 */
    int (*tcl_Read) _ANSI_ARGS_((Tcl_Channel chan, char * bufPtr, int toRead)); /* 206 */
    void (*tcl_ReapDetachedProcs) _ANSI_ARGS_((void)); /* 207 */
    int (*tcl_RecordAndEval) _ANSI_ARGS_((Tcl_Interp * interp, char * cmd, int flags)); /* 208 */
    int (*tcl_RecordAndEvalObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * cmdPtr, int flags)); /* 209 */
    void (*tcl_RegisterChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 210 */
    void (*tcl_RegisterObjType) _ANSI_ARGS_((Tcl_ObjType * typePtr)); /* 211 */
    Tcl_RegExp (*tcl_RegExpCompile) _ANSI_ARGS_((Tcl_Interp * interp, char * string)); /* 212 */
    int (*tcl_RegExpExec) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_RegExp regexp, CONST char * str, CONST char * start)); /* 213 */
    int (*tcl_RegExpMatch) _ANSI_ARGS_((Tcl_Interp * interp, char * str, char * pattern)); /* 214 */
    void (*tcl_RegExpRange) _ANSI_ARGS_((Tcl_RegExp regexp, int index, char ** startPtr, char ** endPtr)); /* 215 */
    void (*tcl_Release) _ANSI_ARGS_((ClientData clientData)); /* 216 */
    void (*tcl_ResetResult) _ANSI_ARGS_((Tcl_Interp * interp)); /* 217 */
    int (*tcl_ScanElement) _ANSI_ARGS_((CONST char * str, int * flagPtr)); /* 218 */
    int (*tcl_ScanCountedElement) _ANSI_ARGS_((CONST char * str, int length, int * flagPtr)); /* 219 */
    int (*tcl_Seek) _ANSI_ARGS_((Tcl_Channel chan, int offset, int mode)); /* 220 */
    int (*tcl_ServiceAll) _ANSI_ARGS_((void)); /* 221 */
    int (*tcl_ServiceEvent) _ANSI_ARGS_((int flags)); /* 222 */
    void (*tcl_SetAssocData) _ANSI_ARGS_((Tcl_Interp * interp, char * name, Tcl_InterpDeleteProc * proc, ClientData clientData)); /* 223 */
    void (*tcl_SetChannelBufferSize) _ANSI_ARGS_((Tcl_Channel chan, int sz)); /* 224 */
    int (*tcl_SetChannelOption) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan, char * optionName, char * newValue)); /* 225 */
    int (*tcl_SetCommandInfo) _ANSI_ARGS_((Tcl_Interp * interp, char * cmdName, Tcl_CmdInfo * infoPtr)); /* 226 */
    void (*tcl_SetErrno) _ANSI_ARGS_((int err)); /* 227 */
    void (*tcl_SetErrorCode) _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp)); /* 228 */
    void (*tcl_SetMaxBlockTime) _ANSI_ARGS_((Tcl_Time * timePtr)); /* 229 */
    void (*tcl_SetPanicProc) _ANSI_ARGS_((Tcl_PanicProc * panicProc)); /* 230 */
    int (*tcl_SetRecursionLimit) _ANSI_ARGS_((Tcl_Interp * interp, int depth)); /* 231 */
    void (*tcl_SetResult) _ANSI_ARGS_((Tcl_Interp * interp, char * str, Tcl_FreeProc * freeProc)); /* 232 */
    int (*tcl_SetServiceMode) _ANSI_ARGS_((int mode)); /* 233 */
    void (*tcl_SetObjErrorCode) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * errorObjPtr)); /* 234 */
    void (*tcl_SetObjResult) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * resultObjPtr)); /* 235 */
    void (*tcl_SetStdChannel) _ANSI_ARGS_((Tcl_Channel channel, int type)); /* 236 */
    char * (*tcl_SetVar) _ANSI_ARGS_((Tcl_Interp * interp, char * varName, char * newValue, int flags)); /* 237 */
    char * (*tcl_SetVar2) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, char * newValue, int flags)); /* 238 */
    char * (*tcl_SignalId) _ANSI_ARGS_((int sig)); /* 239 */
    char * (*tcl_SignalMsg) _ANSI_ARGS_((int sig)); /* 240 */
    void (*tcl_SourceRCFile) _ANSI_ARGS_((Tcl_Interp * interp)); /* 241 */
    int (*tcl_SplitList) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * listStr, int * argcPtr, char *** argvPtr)); /* 242 */
    void (*tcl_SplitPath) _ANSI_ARGS_((CONST char * path, int * argcPtr, char *** argvPtr)); /* 243 */
    void (*tcl_StaticPackage) _ANSI_ARGS_((Tcl_Interp * interp, char * pkgName, Tcl_PackageInitProc * initProc, Tcl_PackageInitProc * safeInitProc)); /* 244 */
    int (*tcl_StringMatch) _ANSI_ARGS_((CONST char * str, CONST char * pattern)); /* 245 */
    int (*tcl_Tell) _ANSI_ARGS_((Tcl_Channel chan)); /* 246 */
    int (*tcl_TraceVar) _ANSI_ARGS_((Tcl_Interp * interp, char * varName, int flags, Tcl_VarTraceProc * proc, ClientData clientData)); /* 247 */
    int (*tcl_TraceVar2) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags, Tcl_VarTraceProc * proc, ClientData clientData)); /* 248 */
    char * (*tcl_TranslateFileName) _ANSI_ARGS_((Tcl_Interp * interp, char * name, Tcl_DString * bufferPtr)); /* 249 */
    int (*tcl_Ungets) _ANSI_ARGS_((Tcl_Channel chan, char * str, int len, int atHead)); /* 250 */
    void (*tcl_UnlinkVar) _ANSI_ARGS_((Tcl_Interp * interp, char * varName)); /* 251 */
    int (*tcl_UnregisterChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 252 */
    int (*tcl_UnsetVar) _ANSI_ARGS_((Tcl_Interp * interp, char * varName, int flags)); /* 253 */
    int (*tcl_UnsetVar2) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags)); /* 254 */
    void (*tcl_UntraceVar) _ANSI_ARGS_((Tcl_Interp * interp, char * varName, int flags, Tcl_VarTraceProc * proc, ClientData clientData)); /* 255 */
    void (*tcl_UntraceVar2) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags, Tcl_VarTraceProc * proc, ClientData clientData)); /* 256 */
    void (*tcl_UpdateLinkedVar) _ANSI_ARGS_((Tcl_Interp * interp, char * varName)); /* 257 */
    int (*tcl_UpVar) _ANSI_ARGS_((Tcl_Interp * interp, char * frameName, char * varName, char * localName, int flags)); /* 258 */
    int (*tcl_UpVar2) _ANSI_ARGS_((Tcl_Interp * interp, char * frameName, char * part1, char * part2, char * localName, int flags)); /* 259 */
    int (*tcl_VarEval) _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp)); /* 260 */
    ClientData (*tcl_VarTraceInfo) _ANSI_ARGS_((Tcl_Interp * interp, char * varName, int flags, Tcl_VarTraceProc * procPtr, ClientData prevClientData)); /* 261 */
    ClientData (*tcl_VarTraceInfo2) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags, Tcl_VarTraceProc * procPtr, ClientData prevClientData)); /* 262 */
    int (*tcl_Write) _ANSI_ARGS_((Tcl_Channel chan, char * s, int slen)); /* 263 */
    void (*tcl_WrongNumArgs) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[], char * message)); /* 264 */
    int (*tcl_DumpActiveMemory) _ANSI_ARGS_((char * fileName)); /* 265 */
    void (*tcl_ValidateAllMemory) _ANSI_ARGS_((char * file, int line)); /* 266 */
    void (*tcl_AppendResultVA) _ANSI_ARGS_((Tcl_Interp * interp, va_list argList)); /* 267 */
    void (*tcl_AppendStringsToObjVA) _ANSI_ARGS_((Tcl_Obj * objPtr, va_list argList)); /* 268 */
    char * (*tcl_HashStats) _ANSI_ARGS_((Tcl_HashTable * tablePtr)); /* 269 */
    char * (*tcl_ParseVar) _ANSI_ARGS_((Tcl_Interp * interp, char * str, char ** termPtr)); /* 270 */
    char * (*tcl_PkgPresent) _ANSI_ARGS_((Tcl_Interp * interp, char * name, char * version, int exact)); /* 271 */
    char * (*tcl_PkgPresentEx) _ANSI_ARGS_((Tcl_Interp * interp, char * name, char * version, int exact, ClientData * clientDataPtr)); /* 272 */
    int (*tcl_PkgProvide) _ANSI_ARGS_((Tcl_Interp * interp, char * name, char * version)); /* 273 */
    char * (*tcl_PkgRequire) _ANSI_ARGS_((Tcl_Interp * interp, char * name, char * version, int exact)); /* 274 */
    void (*tcl_SetErrorCodeVA) _ANSI_ARGS_((Tcl_Interp * interp, va_list argList)); /* 275 */
    int (*tcl_VarEvalVA) _ANSI_ARGS_((Tcl_Interp * interp, va_list argList)); /* 276 */
    Tcl_Pid (*tcl_WaitPid) _ANSI_ARGS_((Tcl_Pid pid, int * statPtr, int options)); /* 277 */
    void (*tcl_PanicVA) _ANSI_ARGS_((char * format, va_list argList)); /* 278 */
    void (*tcl_GetVersion) _ANSI_ARGS_((int * major, int * minor, int * patchLevel, int * type)); /* 279 */
    void (*tcl_InitMemory) _ANSI_ARGS_((Tcl_Interp * interp)); /* 280 */
    void *reserved281;
    void *reserved282;
    void *reserved283;
    void *reserved284;
    void *reserved285;
    void (*tcl_AppendObjToObj) _ANSI_ARGS_((Tcl_Obj * objPtr, Tcl_Obj * appendObjPtr)); /* 286 */
    Tcl_Encoding (*tcl_CreateEncoding) _ANSI_ARGS_((Tcl_EncodingType * typePtr)); /* 287 */
    void (*tcl_CreateThreadExitHandler) _ANSI_ARGS_((Tcl_ExitProc * proc, ClientData clientData)); /* 288 */
    void (*tcl_DeleteThreadExitHandler) _ANSI_ARGS_((Tcl_ExitProc * proc, ClientData clientData)); /* 289 */
    void (*tcl_DiscardResult) _ANSI_ARGS_((Tcl_SavedResult * statePtr)); /* 290 */
    int (*tcl_EvalEx) _ANSI_ARGS_((Tcl_Interp * interp, char * script, int numBytes, int flags)); /* 291 */
    int (*tcl_EvalObjv) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[], int flags)); /* 292 */
    int (*tcl_EvalObjEx) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, int flags)); /* 293 */
    void (*tcl_ExitThread) _ANSI_ARGS_((int status)); /* 294 */
    int (*tcl_ExternalToUtf) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Encoding encoding, CONST char * src, int srcLen, int flags, Tcl_EncodingState * statePtr, char * dst, int dstLen, int * srcReadPtr, int * dstWrotePtr, int * dstCharsPtr)); /* 295 */
    char * (*tcl_ExternalToUtfDString) _ANSI_ARGS_((Tcl_Encoding encoding, CONST char * src, int srcLen, Tcl_DString * dsPtr)); /* 296 */
    void (*tcl_FinalizeThread) _ANSI_ARGS_((void)); /* 297 */
    void (*tcl_FinalizeNotifier) _ANSI_ARGS_((ClientData clientData)); /* 298 */
    void (*tcl_FreeEncoding) _ANSI_ARGS_((Tcl_Encoding encoding)); /* 299 */
    Tcl_ThreadId (*tcl_GetCurrentThread) _ANSI_ARGS_((void)); /* 300 */
    Tcl_Encoding (*tcl_GetEncoding) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name)); /* 301 */
    char * (*tcl_GetEncodingName) _ANSI_ARGS_((Tcl_Encoding encoding)); /* 302 */
    void (*tcl_GetEncodingNames) _ANSI_ARGS_((Tcl_Interp * interp)); /* 303 */
    int (*tcl_GetIndexFromObjStruct) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, char ** tablePtr, int offset, char * msg, int flags, int * indexPtr)); /* 304 */
    VOID * (*tcl_GetThreadData) _ANSI_ARGS_((Tcl_ThreadDataKey * keyPtr, int size)); /* 305 */
    Tcl_Obj * (*tcl_GetVar2Ex) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags)); /* 306 */
    ClientData (*tcl_InitNotifier) _ANSI_ARGS_((void)); /* 307 */
    void (*tcl_MutexLock) _ANSI_ARGS_((Tcl_Mutex * mutexPtr)); /* 308 */
    void (*tcl_MutexUnlock) _ANSI_ARGS_((Tcl_Mutex * mutexPtr)); /* 309 */
    void (*tcl_ConditionNotify) _ANSI_ARGS_((Tcl_Condition * condPtr)); /* 310 */
    void (*tcl_ConditionWait) _ANSI_ARGS_((Tcl_Condition * condPtr, Tcl_Mutex * mutexPtr, Tcl_Time * timePtr)); /* 311 */
    int (*tcl_NumUtfChars) _ANSI_ARGS_((CONST char * src, int len)); /* 312 */
    int (*tcl_ReadChars) _ANSI_ARGS_((Tcl_Channel channel, Tcl_Obj * objPtr, int charsToRead, int appendFlag)); /* 313 */
    void (*tcl_RestoreResult) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_SavedResult * statePtr)); /* 314 */
    void (*tcl_SaveResult) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_SavedResult * statePtr)); /* 315 */
    int (*tcl_SetSystemEncoding) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name)); /* 316 */
    Tcl_Obj * (*tcl_SetVar2Ex) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, Tcl_Obj * newValuePtr, int flags)); /* 317 */
    void (*tcl_ThreadAlert) _ANSI_ARGS_((Tcl_ThreadId threadId)); /* 318 */
    void (*tcl_ThreadQueueEvent) _ANSI_ARGS_((Tcl_ThreadId threadId, Tcl_Event* evPtr, Tcl_QueuePosition position)); /* 319 */
    Tcl_UniChar (*tcl_UniCharAtIndex) _ANSI_ARGS_((CONST char * src, int index)); /* 320 */
    Tcl_UniChar (*tcl_UniCharToLower) _ANSI_ARGS_((int ch)); /* 321 */
    Tcl_UniChar (*tcl_UniCharToTitle) _ANSI_ARGS_((int ch)); /* 322 */
    Tcl_UniChar (*tcl_UniCharToUpper) _ANSI_ARGS_((int ch)); /* 323 */
    int (*tcl_UniCharToUtf) _ANSI_ARGS_((int ch, char * buf)); /* 324 */
    char * (*tcl_UtfAtIndex) _ANSI_ARGS_((CONST char * src, int index)); /* 325 */
    int (*tcl_UtfCharComplete) _ANSI_ARGS_((CONST char * src, int len)); /* 326 */
    int (*tcl_UtfBackslash) _ANSI_ARGS_((CONST char * src, int * readPtr, char * dst)); /* 327 */
    char * (*tcl_UtfFindFirst) _ANSI_ARGS_((CONST char * src, int ch)); /* 328 */
    char * (*tcl_UtfFindLast) _ANSI_ARGS_((CONST char * src, int ch)); /* 329 */
    char * (*tcl_UtfNext) _ANSI_ARGS_((CONST char * src)); /* 330 */
    char * (*tcl_UtfPrev) _ANSI_ARGS_((CONST char * src, CONST char * start)); /* 331 */
    int (*tcl_UtfToExternal) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Encoding encoding, CONST char * src, int srcLen, int flags, Tcl_EncodingState * statePtr, char * dst, int dstLen, int * srcReadPtr, int * dstWrotePtr, int * dstCharsPtr)); /* 332 */
    char * (*tcl_UtfToExternalDString) _ANSI_ARGS_((Tcl_Encoding encoding, CONST char * src, int srcLen, Tcl_DString * dsPtr)); /* 333 */
    int (*tcl_UtfToLower) _ANSI_ARGS_((char * src)); /* 334 */
    int (*tcl_UtfToTitle) _ANSI_ARGS_((char * src)); /* 335 */
    int (*tcl_UtfToUniChar) _ANSI_ARGS_((CONST char * src, Tcl_UniChar * chPtr)); /* 336 */
    int (*tcl_UtfToUpper) _ANSI_ARGS_((char * src)); /* 337 */
    int (*tcl_WriteChars) _ANSI_ARGS_((Tcl_Channel chan, CONST char * src, int srcLen)); /* 338 */
    int (*tcl_WriteObj) _ANSI_ARGS_((Tcl_Channel chan, Tcl_Obj * objPtr)); /* 339 */
    char * (*tcl_GetString) _ANSI_ARGS_((Tcl_Obj * objPtr)); /* 340 */
    char * (*tcl_GetDefaultEncodingDir) _ANSI_ARGS_((void)); /* 341 */
    void (*tcl_SetDefaultEncodingDir) _ANSI_ARGS_((char * path)); /* 342 */
    void (*tcl_AlertNotifier) _ANSI_ARGS_((ClientData clientData)); /* 343 */
    void (*tcl_ServiceModeHook) _ANSI_ARGS_((int mode)); /* 344 */
    int (*tcl_UniCharIsAlnum) _ANSI_ARGS_((int ch)); /* 345 */
    int (*tcl_UniCharIsAlpha) _ANSI_ARGS_((int ch)); /* 346 */
    int (*tcl_UniCharIsDigit) _ANSI_ARGS_((int ch)); /* 347 */
    int (*tcl_UniCharIsLower) _ANSI_ARGS_((int ch)); /* 348 */
    int (*tcl_UniCharIsSpace) _ANSI_ARGS_((int ch)); /* 349 */
    int (*tcl_UniCharIsUpper) _ANSI_ARGS_((int ch)); /* 350 */
    int (*tcl_UniCharIsWordChar) _ANSI_ARGS_((int ch)); /* 351 */
    int (*tcl_UniCharLen) _ANSI_ARGS_((Tcl_UniChar * str)); /* 352 */
    int (*tcl_UniCharNcmp) _ANSI_ARGS_((const Tcl_UniChar * cs, const Tcl_UniChar * ct, size_t n)); /* 353 */
    char * (*tcl_UniCharToUtfDString) _ANSI_ARGS_((CONST Tcl_UniChar * string, int numChars, Tcl_DString * dsPtr)); /* 354 */
    Tcl_UniChar * (*tcl_UtfToUniCharDString) _ANSI_ARGS_((CONST char * string, int length, Tcl_DString * dsPtr)); /* 355 */
    Tcl_RegExp (*tcl_GetRegExpFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * patObj, int flags)); /* 356 */
    Tcl_Obj * (*tcl_EvalTokens) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Token * tokenPtr, int count)); /* 357 */
    void (*tcl_FreeParse) _ANSI_ARGS_((Tcl_Parse * parsePtr)); /* 358 */
    void (*tcl_LogCommandInfo) _ANSI_ARGS_((Tcl_Interp * interp, char * script, char * command, int length)); /* 359 */
    int (*tcl_ParseBraces) _ANSI_ARGS_((Tcl_Interp * interp, char * string, int numBytes, Tcl_Parse * parsePtr, int append, char ** termPtr)); /* 360 */
    int (*tcl_ParseCommand) _ANSI_ARGS_((Tcl_Interp * interp, char * string, int numBytes, int nested, Tcl_Parse * parsePtr)); /* 361 */
    int (*tcl_ParseExpr) _ANSI_ARGS_((Tcl_Interp * interp, char * string, int numBytes, Tcl_Parse * parsePtr)); /* 362 */
    int (*tcl_ParseQuotedString) _ANSI_ARGS_((Tcl_Interp * interp, char * string, int numBytes, Tcl_Parse * parsePtr, int append, char ** termPtr)); /* 363 */
    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 */
} TclStubs;

extern TclStubs *tclStubsPtr;

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

/*
 * Inline function declarations:
 */

#ifndef Tcl_PkgProvideEx
#define Tcl_PkgProvideEx \
	(tclStubsPtr->tcl_PkgProvideEx) /* 0 */
#endif
#ifndef Tcl_PkgRequireEx
#define Tcl_PkgRequireEx \
	(tclStubsPtr->tcl_PkgRequireEx) /* 1 */
#endif
#ifndef Tcl_Panic
#define Tcl_Panic \
	(tclStubsPtr->tcl_Panic) /* 2 */
#endif
#ifndef Tcl_Alloc
#define Tcl_Alloc \
	(tclStubsPtr->tcl_Alloc) /* 3 */
#endif
#ifndef Tcl_Free
#define Tcl_Free \
	(tclStubsPtr->tcl_Free) /* 4 */
#endif
#ifndef Tcl_Realloc
#define Tcl_Realloc \
	(tclStubsPtr->tcl_Realloc) /* 5 */
#endif
#ifndef Tcl_DbCkalloc
#define Tcl_DbCkalloc \
	(tclStubsPtr->tcl_DbCkalloc) /* 6 */
#endif
#ifndef Tcl_DbCkfree
#define Tcl_DbCkfree \
	(tclStubsPtr->tcl_DbCkfree) /* 7 */
#endif
#ifndef Tcl_DbCkrealloc
#define Tcl_DbCkrealloc \
	(tclStubsPtr->tcl_DbCkrealloc) /* 8 */
#endif
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
#ifndef Tcl_CreateFileHandler
#define Tcl_CreateFileHandler \
	(tclStubsPtr->tcl_CreateFileHandler) /* 9 */
#endif
#endif /* UNIX */
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
#ifndef Tcl_DeleteFileHandler
#define Tcl_DeleteFileHandler \
	(tclStubsPtr->tcl_DeleteFileHandler) /* 10 */
#endif
#endif /* UNIX */
#ifndef Tcl_SetTimer
#define Tcl_SetTimer \
	(tclStubsPtr->tcl_SetTimer) /* 11 */
#endif
#ifndef Tcl_Sleep
#define Tcl_Sleep \
	(tclStubsPtr->tcl_Sleep) /* 12 */
#endif
#ifndef Tcl_WaitForEvent
#define Tcl_WaitForEvent \
	(tclStubsPtr->tcl_WaitForEvent) /* 13 */
#endif
#ifndef Tcl_AppendAllObjTypes
#define Tcl_AppendAllObjTypes \
	(tclStubsPtr->tcl_AppendAllObjTypes) /* 14 */
#endif
#ifndef Tcl_AppendStringsToObj
#define Tcl_AppendStringsToObj \
	(tclStubsPtr->tcl_AppendStringsToObj) /* 15 */
#endif
#ifndef Tcl_AppendToObj
#define Tcl_AppendToObj \
	(tclStubsPtr->tcl_AppendToObj) /* 16 */
#endif
#ifndef Tcl_ConcatObj
#define Tcl_ConcatObj \
	(tclStubsPtr->tcl_ConcatObj) /* 17 */
#endif
#ifndef Tcl_ConvertToType
#define Tcl_ConvertToType \
	(tclStubsPtr->tcl_ConvertToType) /* 18 */
#endif
#ifndef Tcl_DbDecrRefCount
#define Tcl_DbDecrRefCount \
	(tclStubsPtr->tcl_DbDecrRefCount) /* 19 */
#endif
#ifndef Tcl_DbIncrRefCount
#define Tcl_DbIncrRefCount \
	(tclStubsPtr->tcl_DbIncrRefCount) /* 20 */
#endif
#ifndef Tcl_DbIsShared
#define Tcl_DbIsShared \
	(tclStubsPtr->tcl_DbIsShared) /* 21 */
#endif
#ifndef Tcl_DbNewBooleanObj
#define Tcl_DbNewBooleanObj \
	(tclStubsPtr->tcl_DbNewBooleanObj) /* 22 */
#endif
#ifndef Tcl_DbNewByteArrayObj
#define Tcl_DbNewByteArrayObj \
	(tclStubsPtr->tcl_DbNewByteArrayObj) /* 23 */
#endif
#ifndef Tcl_DbNewDoubleObj
#define Tcl_DbNewDoubleObj \
	(tclStubsPtr->tcl_DbNewDoubleObj) /* 24 */
#endif
#ifndef Tcl_DbNewListObj
#define Tcl_DbNewListObj \
	(tclStubsPtr->tcl_DbNewListObj) /* 25 */
#endif
#ifndef Tcl_DbNewLongObj
#define Tcl_DbNewLongObj \
	(tclStubsPtr->tcl_DbNewLongObj) /* 26 */
#endif
#ifndef Tcl_DbNewObj
#define Tcl_DbNewObj \
	(tclStubsPtr->tcl_DbNewObj) /* 27 */
#endif
#ifndef Tcl_DbNewStringObj
#define Tcl_DbNewStringObj \
	(tclStubsPtr->tcl_DbNewStringObj) /* 28 */
#endif
#ifndef Tcl_DuplicateObj
#define Tcl_DuplicateObj \
	(tclStubsPtr->tcl_DuplicateObj) /* 29 */
#endif
#ifndef TclFreeObj
#define TclFreeObj \
	(tclStubsPtr->tclFreeObj) /* 30 */
#endif
#ifndef Tcl_GetBoolean
#define Tcl_GetBoolean \
	(tclStubsPtr->tcl_GetBoolean) /* 31 */
#endif
#ifndef Tcl_GetBooleanFromObj
#define Tcl_GetBooleanFromObj \
	(tclStubsPtr->tcl_GetBooleanFromObj) /* 32 */
#endif
#ifndef Tcl_GetByteArrayFromObj
#define Tcl_GetByteArrayFromObj \
	(tclStubsPtr->tcl_GetByteArrayFromObj) /* 33 */
#endif
#ifndef Tcl_GetDouble
#define Tcl_GetDouble \
	(tclStubsPtr->tcl_GetDouble) /* 34 */
#endif
#ifndef Tcl_GetDoubleFromObj
#define Tcl_GetDoubleFromObj \
	(tclStubsPtr->tcl_GetDoubleFromObj) /* 35 */
#endif
#ifndef Tcl_GetIndexFromObj
#define Tcl_GetIndexFromObj \
	(tclStubsPtr->tcl_GetIndexFromObj) /* 36 */
#endif
#ifndef Tcl_GetInt
#define Tcl_GetInt \
	(tclStubsPtr->tcl_GetInt) /* 37 */
#endif
#ifndef Tcl_GetIntFromObj
#define Tcl_GetIntFromObj \
	(tclStubsPtr->tcl_GetIntFromObj) /* 38 */
#endif
#ifndef Tcl_GetLongFromObj
#define Tcl_GetLongFromObj \
	(tclStubsPtr->tcl_GetLongFromObj) /* 39 */
#endif
#ifndef Tcl_GetObjType
#define Tcl_GetObjType \
	(tclStubsPtr->tcl_GetObjType) /* 40 */
#endif
#ifndef Tcl_GetStringFromObj
#define Tcl_GetStringFromObj \
	(tclStubsPtr->tcl_GetStringFromObj) /* 41 */
#endif
#ifndef Tcl_InvalidateStringRep
#define Tcl_InvalidateStringRep \
	(tclStubsPtr->tcl_InvalidateStringRep) /* 42 */
#endif
#ifndef Tcl_ListObjAppendList
#define Tcl_ListObjAppendList \
	(tclStubsPtr->tcl_ListObjAppendList) /* 43 */
#endif
#ifndef Tcl_ListObjAppendElement
#define Tcl_ListObjAppendElement \
	(tclStubsPtr->tcl_ListObjAppendElement) /* 44 */
#endif
#ifndef Tcl_ListObjGetElements
#define Tcl_ListObjGetElements \
	(tclStubsPtr->tcl_ListObjGetElements) /* 45 */
#endif
#ifndef Tcl_ListObjIndex
#define Tcl_ListObjIndex \
	(tclStubsPtr->tcl_ListObjIndex) /* 46 */
#endif
#ifndef Tcl_ListObjLength
#define Tcl_ListObjLength \
	(tclStubsPtr->tcl_ListObjLength) /* 47 */
#endif
#ifndef Tcl_ListObjReplace
#define Tcl_ListObjReplace \
	(tclStubsPtr->tcl_ListObjReplace) /* 48 */
#endif
#ifndef Tcl_NewBooleanObj
#define Tcl_NewBooleanObj \
	(tclStubsPtr->tcl_NewBooleanObj) /* 49 */
#endif
#ifndef Tcl_NewByteArrayObj
#define Tcl_NewByteArrayObj \
	(tclStubsPtr->tcl_NewByteArrayObj) /* 50 */
#endif
#ifndef Tcl_NewDoubleObj
#define Tcl_NewDoubleObj \
	(tclStubsPtr->tcl_NewDoubleObj) /* 51 */
#endif
#ifndef Tcl_NewIntObj
#define Tcl_NewIntObj \
	(tclStubsPtr->tcl_NewIntObj) /* 52 */
#endif
#ifndef Tcl_NewListObj
#define Tcl_NewListObj \
	(tclStubsPtr->tcl_NewListObj) /* 53 */
#endif
#ifndef Tcl_NewLongObj
#define Tcl_NewLongObj \
	(tclStubsPtr->tcl_NewLongObj) /* 54 */
#endif
#ifndef Tcl_NewObj
#define Tcl_NewObj \
	(tclStubsPtr->tcl_NewObj) /* 55 */
#endif
#ifndef Tcl_NewStringObj
#define Tcl_NewStringObj \
	(tclStubsPtr->tcl_NewStringObj) /* 56 */
#endif
#ifndef Tcl_SetBooleanObj
#define Tcl_SetBooleanObj \
	(tclStubsPtr->tcl_SetBooleanObj) /* 57 */
#endif
#ifndef Tcl_SetByteArrayLength
#define Tcl_SetByteArrayLength \
	(tclStubsPtr->tcl_SetByteArrayLength) /* 58 */
#endif
#ifndef Tcl_SetByteArrayObj
#define Tcl_SetByteArrayObj \
	(tclStubsPtr->tcl_SetByteArrayObj) /* 59 */
#endif
#ifndef Tcl_SetDoubleObj
#define Tcl_SetDoubleObj \
	(tclStubsPtr->tcl_SetDoubleObj) /* 60 */
#endif
#ifndef Tcl_SetIntObj
#define Tcl_SetIntObj \
	(tclStubsPtr->tcl_SetIntObj) /* 61 */
#endif
#ifndef Tcl_SetListObj
#define Tcl_SetListObj \
	(tclStubsPtr->tcl_SetListObj) /* 62 */
#endif
#ifndef Tcl_SetLongObj
#define Tcl_SetLongObj \
	(tclStubsPtr->tcl_SetLongObj) /* 63 */
#endif
#ifndef Tcl_SetObjLength
#define Tcl_SetObjLength \
	(tclStubsPtr->tcl_SetObjLength) /* 64 */
#endif
#ifndef Tcl_SetStringObj
#define Tcl_SetStringObj \
	(tclStubsPtr->tcl_SetStringObj) /* 65 */
#endif
#ifndef Tcl_AddErrorInfo
#define Tcl_AddErrorInfo \
	(tclStubsPtr->tcl_AddErrorInfo) /* 66 */
#endif
#ifndef Tcl_AddObjErrorInfo
#define Tcl_AddObjErrorInfo \
	(tclStubsPtr->tcl_AddObjErrorInfo) /* 67 */
#endif
#ifndef Tcl_AllowExceptions
#define Tcl_AllowExceptions \
	(tclStubsPtr->tcl_AllowExceptions) /* 68 */
#endif
#ifndef Tcl_AppendElement
#define Tcl_AppendElement \
	(tclStubsPtr->tcl_AppendElement) /* 69 */
#endif
#ifndef Tcl_AppendResult
#define Tcl_AppendResult \
	(tclStubsPtr->tcl_AppendResult) /* 70 */
#endif
#ifndef Tcl_AsyncCreate
#define Tcl_AsyncCreate \
	(tclStubsPtr->tcl_AsyncCreate) /* 71 */
#endif
#ifndef Tcl_AsyncDelete
#define Tcl_AsyncDelete \
	(tclStubsPtr->tcl_AsyncDelete) /* 72 */
#endif
#ifndef Tcl_AsyncInvoke
#define Tcl_AsyncInvoke \
	(tclStubsPtr->tcl_AsyncInvoke) /* 73 */
#endif
#ifndef Tcl_AsyncMark
#define Tcl_AsyncMark \
	(tclStubsPtr->tcl_AsyncMark) /* 74 */
#endif
#ifndef Tcl_AsyncReady
#define Tcl_AsyncReady \
	(tclStubsPtr->tcl_AsyncReady) /* 75 */
#endif
#ifndef Tcl_BackgroundError
#define Tcl_BackgroundError \
	(tclStubsPtr->tcl_BackgroundError) /* 76 */
#endif
#ifndef Tcl_Backslash
#define Tcl_Backslash \
	(tclStubsPtr->tcl_Backslash) /* 77 */
#endif
#ifndef Tcl_BadChannelOption
#define Tcl_BadChannelOption \
	(tclStubsPtr->tcl_BadChannelOption) /* 78 */
#endif
#ifndef Tcl_CallWhenDeleted
#define Tcl_CallWhenDeleted \
	(tclStubsPtr->tcl_CallWhenDeleted) /* 79 */
#endif
#ifndef Tcl_CancelIdleCall
#define Tcl_CancelIdleCall \
	(tclStubsPtr->tcl_CancelIdleCall) /* 80 */
#endif
#ifndef Tcl_Close
#define Tcl_Close \
	(tclStubsPtr->tcl_Close) /* 81 */
#endif
#ifndef Tcl_CommandComplete
#define Tcl_CommandComplete \
	(tclStubsPtr->tcl_CommandComplete) /* 82 */
#endif
#ifndef Tcl_Concat
#define Tcl_Concat \
	(tclStubsPtr->tcl_Concat) /* 83 */
#endif
#ifndef Tcl_ConvertElement
#define Tcl_ConvertElement \
	(tclStubsPtr->tcl_ConvertElement) /* 84 */
#endif
#ifndef Tcl_ConvertCountedElement
#define Tcl_ConvertCountedElement \
	(tclStubsPtr->tcl_ConvertCountedElement) /* 85 */
#endif
#ifndef Tcl_CreateAlias
#define Tcl_CreateAlias \
	(tclStubsPtr->tcl_CreateAlias) /* 86 */
#endif
#ifndef Tcl_CreateAliasObj
#define Tcl_CreateAliasObj \
	(tclStubsPtr->tcl_CreateAliasObj) /* 87 */
#endif
#ifndef Tcl_CreateChannel
#define Tcl_CreateChannel \
	(tclStubsPtr->tcl_CreateChannel) /* 88 */
#endif
#ifndef Tcl_CreateChannelHandler
#define Tcl_CreateChannelHandler \
	(tclStubsPtr->tcl_CreateChannelHandler) /* 89 */
#endif
#ifndef Tcl_CreateCloseHandler
#define Tcl_CreateCloseHandler \
	(tclStubsPtr->tcl_CreateCloseHandler) /* 90 */
#endif
#ifndef Tcl_CreateCommand
#define Tcl_CreateCommand \
	(tclStubsPtr->tcl_CreateCommand) /* 91 */
#endif
#ifndef Tcl_CreateEventSource
#define Tcl_CreateEventSource \
	(tclStubsPtr->tcl_CreateEventSource) /* 92 */
#endif
#ifndef Tcl_CreateExitHandler
#define Tcl_CreateExitHandler \
	(tclStubsPtr->tcl_CreateExitHandler) /* 93 */
#endif
#ifndef Tcl_CreateInterp
#define Tcl_CreateInterp \
	(tclStubsPtr->tcl_CreateInterp) /* 94 */
#endif
#ifndef Tcl_CreateMathFunc
#define Tcl_CreateMathFunc \
	(tclStubsPtr->tcl_CreateMathFunc) /* 95 */
#endif
#ifndef Tcl_CreateObjCommand
#define Tcl_CreateObjCommand \
	(tclStubsPtr->tcl_CreateObjCommand) /* 96 */
#endif
#ifndef Tcl_CreateSlave
#define Tcl_CreateSlave \
	(tclStubsPtr->tcl_CreateSlave) /* 97 */
#endif
#ifndef Tcl_CreateTimerHandler
#define Tcl_CreateTimerHandler \
	(tclStubsPtr->tcl_CreateTimerHandler) /* 98 */
#endif
#ifndef Tcl_CreateTrace
#define Tcl_CreateTrace \
	(tclStubsPtr->tcl_CreateTrace) /* 99 */
#endif
#ifndef Tcl_DeleteAssocData
#define Tcl_DeleteAssocData \
	(tclStubsPtr->tcl_DeleteAssocData) /* 100 */
#endif
#ifndef Tcl_DeleteChannelHandler
#define Tcl_DeleteChannelHandler \
	(tclStubsPtr->tcl_DeleteChannelHandler) /* 101 */
#endif
#ifndef Tcl_DeleteCloseHandler
#define Tcl_DeleteCloseHandler \
	(tclStubsPtr->tcl_DeleteCloseHandler) /* 102 */
#endif
#ifndef Tcl_DeleteCommand
#define Tcl_DeleteCommand \
	(tclStubsPtr->tcl_DeleteCommand) /* 103 */
#endif
#ifndef Tcl_DeleteCommandFromToken
#define Tcl_DeleteCommandFromToken \
	(tclStubsPtr->tcl_DeleteCommandFromToken) /* 104 */
#endif
#ifndef Tcl_DeleteEvents
#define Tcl_DeleteEvents \
	(tclStubsPtr->tcl_DeleteEvents) /* 105 */
#endif
#ifndef Tcl_DeleteEventSource
#define Tcl_DeleteEventSource \
	(tclStubsPtr->tcl_DeleteEventSource) /* 106 */
#endif
#ifndef Tcl_DeleteExitHandler
#define Tcl_DeleteExitHandler \
	(tclStubsPtr->tcl_DeleteExitHandler) /* 107 */
#endif
#ifndef Tcl_DeleteHashEntry
#define Tcl_DeleteHashEntry \
	(tclStubsPtr->tcl_DeleteHashEntry) /* 108 */
#endif
#ifndef Tcl_DeleteHashTable
#define Tcl_DeleteHashTable \
	(tclStubsPtr->tcl_DeleteHashTable) /* 109 */
#endif
#ifndef Tcl_DeleteInterp
#define Tcl_DeleteInterp \
	(tclStubsPtr->tcl_DeleteInterp) /* 110 */
#endif
#ifndef Tcl_DetachPids
#define Tcl_DetachPids \
	(tclStubsPtr->tcl_DetachPids) /* 111 */
#endif
#ifndef Tcl_DeleteTimerHandler
#define Tcl_DeleteTimerHandler \
	(tclStubsPtr->tcl_DeleteTimerHandler) /* 112 */
#endif
#ifndef Tcl_DeleteTrace
#define Tcl_DeleteTrace \
	(tclStubsPtr->tcl_DeleteTrace) /* 113 */
#endif
#ifndef Tcl_DontCallWhenDeleted
#define Tcl_DontCallWhenDeleted \
	(tclStubsPtr->tcl_DontCallWhenDeleted) /* 114 */
#endif
#ifndef Tcl_DoOneEvent
#define Tcl_DoOneEvent \
	(tclStubsPtr->tcl_DoOneEvent) /* 115 */
#endif
#ifndef Tcl_DoWhenIdle
#define Tcl_DoWhenIdle \
	(tclStubsPtr->tcl_DoWhenIdle) /* 116 */
#endif
#ifndef Tcl_DStringAppend
#define Tcl_DStringAppend \
	(tclStubsPtr->tcl_DStringAppend) /* 117 */
#endif
#ifndef Tcl_DStringAppendElement
#define Tcl_DStringAppendElement \
	(tclStubsPtr->tcl_DStringAppendElement) /* 118 */
#endif
#ifndef Tcl_DStringEndSublist
#define Tcl_DStringEndSublist \
	(tclStubsPtr->tcl_DStringEndSublist) /* 119 */
#endif
#ifndef Tcl_DStringFree
#define Tcl_DStringFree \
	(tclStubsPtr->tcl_DStringFree) /* 120 */
#endif
#ifndef Tcl_DStringGetResult
#define Tcl_DStringGetResult \
	(tclStubsPtr->tcl_DStringGetResult) /* 121 */
#endif
#ifndef Tcl_DStringInit
#define Tcl_DStringInit \
	(tclStubsPtr->tcl_DStringInit) /* 122 */
#endif
#ifndef Tcl_DStringResult
#define Tcl_DStringResult \
	(tclStubsPtr->tcl_DStringResult) /* 123 */
#endif
#ifndef Tcl_DStringSetLength
#define Tcl_DStringSetLength \
	(tclStubsPtr->tcl_DStringSetLength) /* 124 */
#endif
#ifndef Tcl_DStringStartSublist
#define Tcl_DStringStartSublist \
	(tclStubsPtr->tcl_DStringStartSublist) /* 125 */
#endif
#ifndef Tcl_Eof
#define Tcl_Eof \
	(tclStubsPtr->tcl_Eof) /* 126 */
#endif
#ifndef Tcl_ErrnoId
#define Tcl_ErrnoId \
	(tclStubsPtr->tcl_ErrnoId) /* 127 */
#endif
#ifndef Tcl_ErrnoMsg
#define Tcl_ErrnoMsg \
	(tclStubsPtr->tcl_ErrnoMsg) /* 128 */
#endif
#ifndef Tcl_Eval
#define Tcl_Eval \
	(tclStubsPtr->tcl_Eval) /* 129 */
#endif
#ifndef Tcl_EvalFile
#define Tcl_EvalFile \
	(tclStubsPtr->tcl_EvalFile) /* 130 */
#endif
#ifndef Tcl_EvalObj
#define Tcl_EvalObj \
	(tclStubsPtr->tcl_EvalObj) /* 131 */
#endif
#ifndef Tcl_EventuallyFree
#define Tcl_EventuallyFree \
	(tclStubsPtr->tcl_EventuallyFree) /* 132 */
#endif
#ifndef Tcl_Exit
#define Tcl_Exit \
	(tclStubsPtr->tcl_Exit) /* 133 */
#endif
#ifndef Tcl_ExposeCommand
#define Tcl_ExposeCommand \
	(tclStubsPtr->tcl_ExposeCommand) /* 134 */
#endif
#ifndef Tcl_ExprBoolean
#define Tcl_ExprBoolean \
	(tclStubsPtr->tcl_ExprBoolean) /* 135 */
#endif
#ifndef Tcl_ExprBooleanObj
#define Tcl_ExprBooleanObj \
	(tclStubsPtr->tcl_ExprBooleanObj) /* 136 */
#endif
#ifndef Tcl_ExprDouble
#define Tcl_ExprDouble \
	(tclStubsPtr->tcl_ExprDouble) /* 137 */
#endif
#ifndef Tcl_ExprDoubleObj
#define Tcl_ExprDoubleObj \
	(tclStubsPtr->tcl_ExprDoubleObj) /* 138 */
#endif
#ifndef Tcl_ExprLong
#define Tcl_ExprLong \
	(tclStubsPtr->tcl_ExprLong) /* 139 */
#endif
#ifndef Tcl_ExprLongObj
#define Tcl_ExprLongObj \
	(tclStubsPtr->tcl_ExprLongObj) /* 140 */
#endif
#ifndef Tcl_ExprObj
#define Tcl_ExprObj \
	(tclStubsPtr->tcl_ExprObj) /* 141 */
#endif
#ifndef Tcl_ExprString
#define Tcl_ExprString \
	(tclStubsPtr->tcl_ExprString) /* 142 */
#endif
#ifndef Tcl_Finalize
#define Tcl_Finalize \
	(tclStubsPtr->tcl_Finalize) /* 143 */
#endif
#ifndef Tcl_FindExecutable
#define Tcl_FindExecutable \
	(tclStubsPtr->tcl_FindExecutable) /* 144 */
#endif
#ifndef Tcl_FirstHashEntry
#define Tcl_FirstHashEntry \
	(tclStubsPtr->tcl_FirstHashEntry) /* 145 */
#endif
#ifndef Tcl_Flush
#define Tcl_Flush \
	(tclStubsPtr->tcl_Flush) /* 146 */
#endif
#ifndef Tcl_FreeResult
#define Tcl_FreeResult \
	(tclStubsPtr->tcl_FreeResult) /* 147 */
#endif
#ifndef Tcl_GetAlias
#define Tcl_GetAlias \
	(tclStubsPtr->tcl_GetAlias) /* 148 */
#endif
#ifndef Tcl_GetAliasObj
#define Tcl_GetAliasObj \
	(tclStubsPtr->tcl_GetAliasObj) /* 149 */
#endif
#ifndef Tcl_GetAssocData
#define Tcl_GetAssocData \
	(tclStubsPtr->tcl_GetAssocData) /* 150 */
#endif
#ifndef Tcl_GetChannel
#define Tcl_GetChannel \
	(tclStubsPtr->tcl_GetChannel) /* 151 */
#endif
#ifndef Tcl_GetChannelBufferSize
#define Tcl_GetChannelBufferSize \
	(tclStubsPtr->tcl_GetChannelBufferSize) /* 152 */
#endif
#ifndef Tcl_GetChannelHandle
#define Tcl_GetChannelHandle \
	(tclStubsPtr->tcl_GetChannelHandle) /* 153 */
#endif
#ifndef Tcl_GetChannelInstanceData
#define Tcl_GetChannelInstanceData \
	(tclStubsPtr->tcl_GetChannelInstanceData) /* 154 */
#endif
#ifndef Tcl_GetChannelMode
#define Tcl_GetChannelMode \
	(tclStubsPtr->tcl_GetChannelMode) /* 155 */
#endif
#ifndef Tcl_GetChannelName
#define Tcl_GetChannelName \
	(tclStubsPtr->tcl_GetChannelName) /* 156 */
#endif
#ifndef Tcl_GetChannelOption
#define Tcl_GetChannelOption \
	(tclStubsPtr->tcl_GetChannelOption) /* 157 */
#endif
#ifndef Tcl_GetChannelType
#define Tcl_GetChannelType \
	(tclStubsPtr->tcl_GetChannelType) /* 158 */
#endif
#ifndef Tcl_GetCommandInfo
#define Tcl_GetCommandInfo \
	(tclStubsPtr->tcl_GetCommandInfo) /* 159 */
#endif
#ifndef Tcl_GetCommandName
#define Tcl_GetCommandName \
	(tclStubsPtr->tcl_GetCommandName) /* 160 */
#endif
#ifndef Tcl_GetErrno
#define Tcl_GetErrno \
	(tclStubsPtr->tcl_GetErrno) /* 161 */
#endif
#ifndef Tcl_GetHostName
#define Tcl_GetHostName \
	(tclStubsPtr->tcl_GetHostName) /* 162 */
#endif
#ifndef Tcl_GetInterpPath
#define Tcl_GetInterpPath \
	(tclStubsPtr->tcl_GetInterpPath) /* 163 */
#endif
#ifndef Tcl_GetMaster
#define Tcl_GetMaster \
	(tclStubsPtr->tcl_GetMaster) /* 164 */
#endif
#ifndef Tcl_GetNameOfExecutable
#define Tcl_GetNameOfExecutable \
	(tclStubsPtr->tcl_GetNameOfExecutable) /* 165 */
#endif
#ifndef Tcl_GetObjResult
#define Tcl_GetObjResult \
	(tclStubsPtr->tcl_GetObjResult) /* 166 */
#endif
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
#ifndef Tcl_GetOpenFile
#define Tcl_GetOpenFile \
	(tclStubsPtr->tcl_GetOpenFile) /* 167 */
#endif
#endif /* UNIX */
#ifndef Tcl_GetPathType
#define Tcl_GetPathType \
	(tclStubsPtr->tcl_GetPathType) /* 168 */
#endif
#ifndef Tcl_Gets
#define Tcl_Gets \
	(tclStubsPtr->tcl_Gets) /* 169 */
#endif
#ifndef Tcl_GetsObj
#define Tcl_GetsObj \
	(tclStubsPtr->tcl_GetsObj) /* 170 */
#endif
#ifndef Tcl_GetServiceMode
#define Tcl_GetServiceMode \
	(tclStubsPtr->tcl_GetServiceMode) /* 171 */
#endif
#ifndef Tcl_GetSlave
#define Tcl_GetSlave \
	(tclStubsPtr->tcl_GetSlave) /* 172 */
#endif
#ifndef Tcl_GetStdChannel
#define Tcl_GetStdChannel \
	(tclStubsPtr->tcl_GetStdChannel) /* 173 */
#endif
#ifndef Tcl_GetStringResult
#define Tcl_GetStringResult \
	(tclStubsPtr->tcl_GetStringResult) /* 174 */
#endif
#ifndef Tcl_GetVar
#define Tcl_GetVar \
	(tclStubsPtr->tcl_GetVar) /* 175 */
#endif
#ifndef Tcl_GetVar2
#define Tcl_GetVar2 \
	(tclStubsPtr->tcl_GetVar2) /* 176 */
#endif
#ifndef Tcl_GlobalEval
#define Tcl_GlobalEval \
	(tclStubsPtr->tcl_GlobalEval) /* 177 */
#endif
#ifndef Tcl_GlobalEvalObj
#define Tcl_GlobalEvalObj \
	(tclStubsPtr->tcl_GlobalEvalObj) /* 178 */
#endif
#ifndef Tcl_HideCommand
#define Tcl_HideCommand \
	(tclStubsPtr->tcl_HideCommand) /* 179 */
#endif
#ifndef Tcl_Init
#define Tcl_Init \
	(tclStubsPtr->tcl_Init) /* 180 */
#endif
#ifndef Tcl_InitHashTable
#define Tcl_InitHashTable \
	(tclStubsPtr->tcl_InitHashTable) /* 181 */
#endif
#ifndef Tcl_InputBlocked
#define Tcl_InputBlocked \
	(tclStubsPtr->tcl_InputBlocked) /* 182 */
#endif
#ifndef Tcl_InputBuffered
#define Tcl_InputBuffered \
	(tclStubsPtr->tcl_InputBuffered) /* 183 */
#endif
#ifndef Tcl_InterpDeleted
#define Tcl_InterpDeleted \
	(tclStubsPtr->tcl_InterpDeleted) /* 184 */
#endif
#ifndef Tcl_IsSafe
#define Tcl_IsSafe \
	(tclStubsPtr->tcl_IsSafe) /* 185 */
#endif
#ifndef Tcl_JoinPath
#define Tcl_JoinPath \
	(tclStubsPtr->tcl_JoinPath) /* 186 */
#endif
#ifndef Tcl_LinkVar
#define Tcl_LinkVar \
	(tclStubsPtr->tcl_LinkVar) /* 187 */
#endif
/* Slot 188 is reserved */
#ifndef Tcl_MakeFileChannel
#define Tcl_MakeFileChannel \
	(tclStubsPtr->tcl_MakeFileChannel) /* 189 */
#endif
#ifndef Tcl_MakeSafe
#define Tcl_MakeSafe \
	(tclStubsPtr->tcl_MakeSafe) /* 190 */
#endif
#ifndef Tcl_MakeTcpClientChannel
#define Tcl_MakeTcpClientChannel \
	(tclStubsPtr->tcl_MakeTcpClientChannel) /* 191 */
#endif
#ifndef Tcl_Merge
#define Tcl_Merge \
	(tclStubsPtr->tcl_Merge) /* 192 */
#endif
#ifndef Tcl_NextHashEntry
#define Tcl_NextHashEntry \
	(tclStubsPtr->tcl_NextHashEntry) /* 193 */
#endif
#ifndef Tcl_NotifyChannel
#define Tcl_NotifyChannel \
	(tclStubsPtr->tcl_NotifyChannel) /* 194 */
#endif
#ifndef Tcl_ObjGetVar2
#define Tcl_ObjGetVar2 \
	(tclStubsPtr->tcl_ObjGetVar2) /* 195 */
#endif
#ifndef Tcl_ObjSetVar2
#define Tcl_ObjSetVar2 \
	(tclStubsPtr->tcl_ObjSetVar2) /* 196 */
#endif
#ifndef Tcl_OpenCommandChannel
#define Tcl_OpenCommandChannel \
	(tclStubsPtr->tcl_OpenCommandChannel) /* 197 */
#endif
#ifndef Tcl_OpenFileChannel
#define Tcl_OpenFileChannel \
	(tclStubsPtr->tcl_OpenFileChannel) /* 198 */
#endif
#ifndef Tcl_OpenTcpClient
#define Tcl_OpenTcpClient \
	(tclStubsPtr->tcl_OpenTcpClient) /* 199 */
#endif
#ifndef Tcl_OpenTcpServer
#define Tcl_OpenTcpServer \
	(tclStubsPtr->tcl_OpenTcpServer) /* 200 */
#endif
#ifndef Tcl_Preserve
#define Tcl_Preserve \
	(tclStubsPtr->tcl_Preserve) /* 201 */
#endif
#ifndef Tcl_PrintDouble
#define Tcl_PrintDouble \
	(tclStubsPtr->tcl_PrintDouble) /* 202 */
#endif
#ifndef Tcl_PutEnv
#define Tcl_PutEnv \
	(tclStubsPtr->tcl_PutEnv) /* 203 */
#endif
#ifndef Tcl_PosixError
#define Tcl_PosixError \
	(tclStubsPtr->tcl_PosixError) /* 204 */
#endif
#ifndef Tcl_QueueEvent
#define Tcl_QueueEvent \
	(tclStubsPtr->tcl_QueueEvent) /* 205 */
#endif
#ifndef Tcl_Read
#define Tcl_Read \
	(tclStubsPtr->tcl_Read) /* 206 */
#endif
#ifndef Tcl_ReapDetachedProcs
#define Tcl_ReapDetachedProcs \
	(tclStubsPtr->tcl_ReapDetachedProcs) /* 207 */
#endif
#ifndef Tcl_RecordAndEval
#define Tcl_RecordAndEval \
	(tclStubsPtr->tcl_RecordAndEval) /* 208 */
#endif
#ifndef Tcl_RecordAndEvalObj
#define Tcl_RecordAndEvalObj \
	(tclStubsPtr->tcl_RecordAndEvalObj) /* 209 */
#endif
#ifndef Tcl_RegisterChannel
#define Tcl_RegisterChannel \
	(tclStubsPtr->tcl_RegisterChannel) /* 210 */
#endif
#ifndef Tcl_RegisterObjType
#define Tcl_RegisterObjType \
	(tclStubsPtr->tcl_RegisterObjType) /* 211 */
#endif
#ifndef Tcl_RegExpCompile
#define Tcl_RegExpCompile \
	(tclStubsPtr->tcl_RegExpCompile) /* 212 */
#endif
#ifndef Tcl_RegExpExec
#define Tcl_RegExpExec \
	(tclStubsPtr->tcl_RegExpExec) /* 213 */
#endif
#ifndef Tcl_RegExpMatch
#define Tcl_RegExpMatch \
	(tclStubsPtr->tcl_RegExpMatch) /* 214 */
#endif
#ifndef Tcl_RegExpRange
#define Tcl_RegExpRange \
	(tclStubsPtr->tcl_RegExpRange) /* 215 */
#endif
#ifndef Tcl_Release
#define Tcl_Release \
	(tclStubsPtr->tcl_Release) /* 216 */
#endif
#ifndef Tcl_ResetResult
#define Tcl_ResetResult \
	(tclStubsPtr->tcl_ResetResult) /* 217 */
#endif
#ifndef Tcl_ScanElement
#define Tcl_ScanElement \
	(tclStubsPtr->tcl_ScanElement) /* 218 */
#endif
#ifndef Tcl_ScanCountedElement
#define Tcl_ScanCountedElement \
	(tclStubsPtr->tcl_ScanCountedElement) /* 219 */
#endif
#ifndef Tcl_Seek
#define Tcl_Seek \
	(tclStubsPtr->tcl_Seek) /* 220 */
#endif
#ifndef Tcl_ServiceAll
#define Tcl_ServiceAll \
	(tclStubsPtr->tcl_ServiceAll) /* 221 */
#endif
#ifndef Tcl_ServiceEvent
#define Tcl_ServiceEvent \
	(tclStubsPtr->tcl_ServiceEvent) /* 222 */
#endif
#ifndef Tcl_SetAssocData
#define Tcl_SetAssocData \
	(tclStubsPtr->tcl_SetAssocData) /* 223 */
#endif
#ifndef Tcl_SetChannelBufferSize
#define Tcl_SetChannelBufferSize \
	(tclStubsPtr->tcl_SetChannelBufferSize) /* 224 */
#endif
#ifndef Tcl_SetChannelOption
#define Tcl_SetChannelOption \
	(tclStubsPtr->tcl_SetChannelOption) /* 225 */
#endif
#ifndef Tcl_SetCommandInfo
#define Tcl_SetCommandInfo \
	(tclStubsPtr->tcl_SetCommandInfo) /* 226 */
#endif
#ifndef Tcl_SetErrno
#define Tcl_SetErrno \
	(tclStubsPtr->tcl_SetErrno) /* 227 */
#endif
#ifndef Tcl_SetErrorCode
#define Tcl_SetErrorCode \
	(tclStubsPtr->tcl_SetErrorCode) /* 228 */
#endif
#ifndef Tcl_SetMaxBlockTime
#define Tcl_SetMaxBlockTime \
	(tclStubsPtr->tcl_SetMaxBlockTime) /* 229 */
#endif
#ifndef Tcl_SetPanicProc
#define Tcl_SetPanicProc \
	(tclStubsPtr->tcl_SetPanicProc) /* 230 */
#endif
#ifndef Tcl_SetRecursionLimit
#define Tcl_SetRecursionLimit \
	(tclStubsPtr->tcl_SetRecursionLimit) /* 231 */
#endif
#ifndef Tcl_SetResult
#define Tcl_SetResult \
	(tclStubsPtr->tcl_SetResult) /* 232 */
#endif
#ifndef Tcl_SetServiceMode
#define Tcl_SetServiceMode \
	(tclStubsPtr->tcl_SetServiceMode) /* 233 */
#endif
#ifndef Tcl_SetObjErrorCode
#define Tcl_SetObjErrorCode \
	(tclStubsPtr->tcl_SetObjErrorCode) /* 234 */
#endif
#ifndef Tcl_SetObjResult
#define Tcl_SetObjResult \
	(tclStubsPtr->tcl_SetObjResult) /* 235 */
#endif
#ifndef Tcl_SetStdChannel
#define Tcl_SetStdChannel \
	(tclStubsPtr->tcl_SetStdChannel) /* 236 */
#endif
#ifndef Tcl_SetVar
#define Tcl_SetVar \
	(tclStubsPtr->tcl_SetVar) /* 237 */
#endif
#ifndef Tcl_SetVar2
#define Tcl_SetVar2 \
	(tclStubsPtr->tcl_SetVar2) /* 238 */
#endif
#ifndef Tcl_SignalId
#define Tcl_SignalId \
	(tclStubsPtr->tcl_SignalId) /* 239 */
#endif
#ifndef Tcl_SignalMsg
#define Tcl_SignalMsg \
	(tclStubsPtr->tcl_SignalMsg) /* 240 */
#endif
#ifndef Tcl_SourceRCFile
#define Tcl_SourceRCFile \
	(tclStubsPtr->tcl_SourceRCFile) /* 241 */
#endif
#ifndef Tcl_SplitList
#define Tcl_SplitList \
	(tclStubsPtr->tcl_SplitList) /* 242 */
#endif
#ifndef Tcl_SplitPath
#define Tcl_SplitPath \
	(tclStubsPtr->tcl_SplitPath) /* 243 */
#endif
#ifndef Tcl_StaticPackage
#define Tcl_StaticPackage \
	(tclStubsPtr->tcl_StaticPackage) /* 244 */
#endif
#ifndef Tcl_StringMatch
#define Tcl_StringMatch \
	(tclStubsPtr->tcl_StringMatch) /* 245 */
#endif
#ifndef Tcl_Tell
#define Tcl_Tell \
	(tclStubsPtr->tcl_Tell) /* 246 */
#endif
#ifndef Tcl_TraceVar
#define Tcl_TraceVar \
	(tclStubsPtr->tcl_TraceVar) /* 247 */
#endif
#ifndef Tcl_TraceVar2
#define Tcl_TraceVar2 \
	(tclStubsPtr->tcl_TraceVar2) /* 248 */
#endif
#ifndef Tcl_TranslateFileName
#define Tcl_TranslateFileName \
	(tclStubsPtr->tcl_TranslateFileName) /* 249 */
#endif
#ifndef Tcl_Ungets
#define Tcl_Ungets \
	(tclStubsPtr->tcl_Ungets) /* 250 */
#endif
#ifndef Tcl_UnlinkVar
#define Tcl_UnlinkVar \
	(tclStubsPtr->tcl_UnlinkVar) /* 251 */
#endif
#ifndef Tcl_UnregisterChannel
#define Tcl_UnregisterChannel \
	(tclStubsPtr->tcl_UnregisterChannel) /* 252 */
#endif
#ifndef Tcl_UnsetVar
#define Tcl_UnsetVar \
	(tclStubsPtr->tcl_UnsetVar) /* 253 */
#endif
#ifndef Tcl_UnsetVar2
#define Tcl_UnsetVar2 \
	(tclStubsPtr->tcl_UnsetVar2) /* 254 */
#endif
#ifndef Tcl_UntraceVar
#define Tcl_UntraceVar \
	(tclStubsPtr->tcl_UntraceVar) /* 255 */
#endif
#ifndef Tcl_UntraceVar2
#define Tcl_UntraceVar2 \
	(tclStubsPtr->tcl_UntraceVar2) /* 256 */
#endif
#ifndef Tcl_UpdateLinkedVar
#define Tcl_UpdateLinkedVar \
	(tclStubsPtr->tcl_UpdateLinkedVar) /* 257 */
#endif
#ifndef Tcl_UpVar
#define Tcl_UpVar \
	(tclStubsPtr->tcl_UpVar) /* 258 */
#endif
#ifndef Tcl_UpVar2
#define Tcl_UpVar2 \
	(tclStubsPtr->tcl_UpVar2) /* 259 */
#endif
#ifndef Tcl_VarEval
#define Tcl_VarEval \
	(tclStubsPtr->tcl_VarEval) /* 260 */
#endif
#ifndef Tcl_VarTraceInfo
#define Tcl_VarTraceInfo \
	(tclStubsPtr->tcl_VarTraceInfo) /* 261 */
#endif
#ifndef Tcl_VarTraceInfo2
#define Tcl_VarTraceInfo2 \
	(tclStubsPtr->tcl_VarTraceInfo2) /* 262 */
#endif
#ifndef Tcl_Write
#define Tcl_Write \
	(tclStubsPtr->tcl_Write) /* 263 */
#endif
#ifndef Tcl_WrongNumArgs
#define Tcl_WrongNumArgs \
	(tclStubsPtr->tcl_WrongNumArgs) /* 264 */
#endif
#ifndef Tcl_DumpActiveMemory
#define Tcl_DumpActiveMemory \
	(tclStubsPtr->tcl_DumpActiveMemory) /* 265 */
#endif
#ifndef Tcl_ValidateAllMemory
#define Tcl_ValidateAllMemory \
	(tclStubsPtr->tcl_ValidateAllMemory) /* 266 */
#endif
#ifndef Tcl_AppendResultVA
#define Tcl_AppendResultVA \
	(tclStubsPtr->tcl_AppendResultVA) /* 267 */
#endif
#ifndef Tcl_AppendStringsToObjVA
#define Tcl_AppendStringsToObjVA \
	(tclStubsPtr->tcl_AppendStringsToObjVA) /* 268 */
#endif
#ifndef Tcl_HashStats
#define Tcl_HashStats \
	(tclStubsPtr->tcl_HashStats) /* 269 */
#endif
#ifndef Tcl_ParseVar
#define Tcl_ParseVar \
	(tclStubsPtr->tcl_ParseVar) /* 270 */
#endif
#ifndef Tcl_PkgPresent
#define Tcl_PkgPresent \
	(tclStubsPtr->tcl_PkgPresent) /* 271 */
#endif
#ifndef Tcl_PkgPresentEx
#define Tcl_PkgPresentEx \
	(tclStubsPtr->tcl_PkgPresentEx) /* 272 */
#endif
#ifndef Tcl_PkgProvide
#define Tcl_PkgProvide \
	(tclStubsPtr->tcl_PkgProvide) /* 273 */
#endif
#ifndef Tcl_PkgRequire
#define Tcl_PkgRequire \
	(tclStubsPtr->tcl_PkgRequire) /* 274 */
#endif
#ifndef Tcl_SetErrorCodeVA
#define Tcl_SetErrorCodeVA \
	(tclStubsPtr->tcl_SetErrorCodeVA) /* 275 */
#endif
#ifndef Tcl_VarEvalVA
#define Tcl_VarEvalVA \
	(tclStubsPtr->tcl_VarEvalVA) /* 276 */
#endif
#ifndef Tcl_WaitPid
#define Tcl_WaitPid \
	(tclStubsPtr->tcl_WaitPid) /* 277 */
#endif
#ifndef Tcl_PanicVA
#define Tcl_PanicVA \
	(tclStubsPtr->tcl_PanicVA) /* 278 */
#endif
#ifndef Tcl_GetVersion
#define Tcl_GetVersion \
	(tclStubsPtr->tcl_GetVersion) /* 279 */
#endif
#ifndef Tcl_InitMemory
#define Tcl_InitMemory \
	(tclStubsPtr->tcl_InitMemory) /* 280 */
#endif
/* Slot 281 is reserved */
/* Slot 282 is reserved */
/* Slot 283 is reserved */
/* Slot 284 is reserved */
/* Slot 285 is reserved */
#ifndef Tcl_AppendObjToObj
#define Tcl_AppendObjToObj \
	(tclStubsPtr->tcl_AppendObjToObj) /* 286 */
#endif
#ifndef Tcl_CreateEncoding
#define Tcl_CreateEncoding \
	(tclStubsPtr->tcl_CreateEncoding) /* 287 */
#endif
#ifndef Tcl_CreateThreadExitHandler
#define Tcl_CreateThreadExitHandler \
	(tclStubsPtr->tcl_CreateThreadExitHandler) /* 288 */
#endif
#ifndef Tcl_DeleteThreadExitHandler
#define Tcl_DeleteThreadExitHandler \
	(tclStubsPtr->tcl_DeleteThreadExitHandler) /* 289 */
#endif
#ifndef Tcl_DiscardResult
#define Tcl_DiscardResult \
	(tclStubsPtr->tcl_DiscardResult) /* 290 */
#endif
#ifndef Tcl_EvalEx
#define Tcl_EvalEx \
	(tclStubsPtr->tcl_EvalEx) /* 291 */
#endif
#ifndef Tcl_EvalObjv
#define Tcl_EvalObjv \
	(tclStubsPtr->tcl_EvalObjv) /* 292 */
#endif
#ifndef Tcl_EvalObjEx
#define Tcl_EvalObjEx \
	(tclStubsPtr->tcl_EvalObjEx) /* 293 */
#endif
#ifndef Tcl_ExitThread
#define Tcl_ExitThread \
	(tclStubsPtr->tcl_ExitThread) /* 294 */
#endif
#ifndef Tcl_ExternalToUtf
#define Tcl_ExternalToUtf \
	(tclStubsPtr->tcl_ExternalToUtf) /* 295 */
#endif
#ifndef Tcl_ExternalToUtfDString
#define Tcl_ExternalToUtfDString \
	(tclStubsPtr->tcl_ExternalToUtfDString) /* 296 */
#endif
#ifndef Tcl_FinalizeThread
#define Tcl_FinalizeThread \
	(tclStubsPtr->tcl_FinalizeThread) /* 297 */
#endif
#ifndef Tcl_FinalizeNotifier
#define Tcl_FinalizeNotifier \
	(tclStubsPtr->tcl_FinalizeNotifier) /* 298 */
#endif
#ifndef Tcl_FreeEncoding
#define Tcl_FreeEncoding \
	(tclStubsPtr->tcl_FreeEncoding) /* 299 */
#endif
#ifndef Tcl_GetCurrentThread
#define Tcl_GetCurrentThread \
	(tclStubsPtr->tcl_GetCurrentThread) /* 300 */
#endif
#ifndef Tcl_GetEncoding
#define Tcl_GetEncoding \
	(tclStubsPtr->tcl_GetEncoding) /* 301 */
#endif
#ifndef Tcl_GetEncodingName
#define Tcl_GetEncodingName \
	(tclStubsPtr->tcl_GetEncodingName) /* 302 */
#endif
#ifndef Tcl_GetEncodingNames
#define Tcl_GetEncodingNames \
	(tclStubsPtr->tcl_GetEncodingNames) /* 303 */
#endif
#ifndef Tcl_GetIndexFromObjStruct
#define Tcl_GetIndexFromObjStruct \
	(tclStubsPtr->tcl_GetIndexFromObjStruct) /* 304 */
#endif
#ifndef Tcl_GetThreadData
#define Tcl_GetThreadData \
	(tclStubsPtr->tcl_GetThreadData) /* 305 */
#endif
#ifndef Tcl_GetVar2Ex
#define Tcl_GetVar2Ex \
	(tclStubsPtr->tcl_GetVar2Ex) /* 306 */
#endif
#ifndef Tcl_InitNotifier
#define Tcl_InitNotifier \
	(tclStubsPtr->tcl_InitNotifier) /* 307 */
#endif
#ifndef Tcl_MutexLock
#define Tcl_MutexLock \
	(tclStubsPtr->tcl_MutexLock) /* 308 */
#endif
#ifndef Tcl_MutexUnlock
#define Tcl_MutexUnlock \
	(tclStubsPtr->tcl_MutexUnlock) /* 309 */
#endif
#ifndef Tcl_ConditionNotify
#define Tcl_ConditionNotify \
	(tclStubsPtr->tcl_ConditionNotify) /* 310 */
#endif
#ifndef Tcl_ConditionWait
#define Tcl_ConditionWait \
	(tclStubsPtr->tcl_ConditionWait) /* 311 */
#endif
#ifndef Tcl_NumUtfChars
#define Tcl_NumUtfChars \
	(tclStubsPtr->tcl_NumUtfChars) /* 312 */
#endif
#ifndef Tcl_ReadChars
#define Tcl_ReadChars \
	(tclStubsPtr->tcl_ReadChars) /* 313 */
#endif
#ifndef Tcl_RestoreResult
#define Tcl_RestoreResult \
	(tclStubsPtr->tcl_RestoreResult) /* 314 */
#endif
#ifndef Tcl_SaveResult
#define Tcl_SaveResult \
	(tclStubsPtr->tcl_SaveResult) /* 315 */
#endif
#ifndef Tcl_SetSystemEncoding
#define Tcl_SetSystemEncoding \
	(tclStubsPtr->tcl_SetSystemEncoding) /* 316 */
#endif
#ifndef Tcl_SetVar2Ex
#define Tcl_SetVar2Ex \
	(tclStubsPtr->tcl_SetVar2Ex) /* 317 */
#endif
#ifndef Tcl_ThreadAlert
#define Tcl_ThreadAlert \
	(tclStubsPtr->tcl_ThreadAlert) /* 318 */
#endif
#ifndef Tcl_ThreadQueueEvent
#define Tcl_ThreadQueueEvent \
	(tclStubsPtr->tcl_ThreadQueueEvent) /* 319 */
#endif
#ifndef Tcl_UniCharAtIndex
#define Tcl_UniCharAtIndex \
	(tclStubsPtr->tcl_UniCharAtIndex) /* 320 */
#endif
#ifndef Tcl_UniCharToLower
#define Tcl_UniCharToLower \
	(tclStubsPtr->tcl_UniCharToLower) /* 321 */
#endif
#ifndef Tcl_UniCharToTitle
#define Tcl_UniCharToTitle \
	(tclStubsPtr->tcl_UniCharToTitle) /* 322 */
#endif
#ifndef Tcl_UniCharToUpper
#define Tcl_UniCharToUpper \
	(tclStubsPtr->tcl_UniCharToUpper) /* 323 */
#endif
#ifndef Tcl_UniCharToUtf
#define Tcl_UniCharToUtf \
	(tclStubsPtr->tcl_UniCharToUtf) /* 324 */
#endif
#ifndef Tcl_UtfAtIndex
#define Tcl_UtfAtIndex \
	(tclStubsPtr->tcl_UtfAtIndex) /* 325 */
#endif
#ifndef Tcl_UtfCharComplete
#define Tcl_UtfCharComplete \
	(tclStubsPtr->tcl_UtfCharComplete) /* 326 */
#endif
#ifndef Tcl_UtfBackslash
#define Tcl_UtfBackslash \
	(tclStubsPtr->tcl_UtfBackslash) /* 327 */
#endif
#ifndef Tcl_UtfFindFirst
#define Tcl_UtfFindFirst \
	(tclStubsPtr->tcl_UtfFindFirst) /* 328 */
#endif
#ifndef Tcl_UtfFindLast
#define Tcl_UtfFindLast \
	(tclStubsPtr->tcl_UtfFindLast) /* 329 */
#endif
#ifndef Tcl_UtfNext
#define Tcl_UtfNext \
	(tclStubsPtr->tcl_UtfNext) /* 330 */
#endif
#ifndef Tcl_UtfPrev
#define Tcl_UtfPrev \
	(tclStubsPtr->tcl_UtfPrev) /* 331 */
#endif
#ifndef Tcl_UtfToExternal
#define Tcl_UtfToExternal \
	(tclStubsPtr->tcl_UtfToExternal) /* 332 */
#endif
#ifndef Tcl_UtfToExternalDString
#define Tcl_UtfToExternalDString \
	(tclStubsPtr->tcl_UtfToExternalDString) /* 333 */
#endif
#ifndef Tcl_UtfToLower
#define Tcl_UtfToLower \
	(tclStubsPtr->tcl_UtfToLower) /* 334 */
#endif
#ifndef Tcl_UtfToTitle
#define Tcl_UtfToTitle \
	(tclStubsPtr->tcl_UtfToTitle) /* 335 */
#endif
#ifndef Tcl_UtfToUniChar
#define Tcl_UtfToUniChar \
	(tclStubsPtr->tcl_UtfToUniChar) /* 336 */
#endif
#ifndef Tcl_UtfToUpper
#define Tcl_UtfToUpper \
	(tclStubsPtr->tcl_UtfToUpper) /* 337 */
#endif
#ifndef Tcl_WriteChars
#define Tcl_WriteChars \
	(tclStubsPtr->tcl_WriteChars) /* 338 */
#endif
#ifndef Tcl_WriteObj
#define Tcl_WriteObj \
	(tclStubsPtr->tcl_WriteObj) /* 339 */
#endif
#ifndef Tcl_GetString
#define Tcl_GetString \
	(tclStubsPtr->tcl_GetString) /* 340 */
#endif
#ifndef Tcl_GetDefaultEncodingDir
#define Tcl_GetDefaultEncodingDir \
	(tclStubsPtr->tcl_GetDefaultEncodingDir) /* 341 */
#endif
#ifndef Tcl_SetDefaultEncodingDir
#define Tcl_SetDefaultEncodingDir \
	(tclStubsPtr->tcl_SetDefaultEncodingDir) /* 342 */
#endif
#ifndef Tcl_AlertNotifier
#define Tcl_AlertNotifier \
	(tclStubsPtr->tcl_AlertNotifier) /* 343 */
#endif
#ifndef Tcl_ServiceModeHook
#define Tcl_ServiceModeHook \
	(tclStubsPtr->tcl_ServiceModeHook) /* 344 */
#endif
#ifndef Tcl_UniCharIsAlnum
#define Tcl_UniCharIsAlnum \
	(tclStubsPtr->tcl_UniCharIsAlnum) /* 345 */
#endif
#ifndef Tcl_UniCharIsAlpha
#define Tcl_UniCharIsAlpha \
	(tclStubsPtr->tcl_UniCharIsAlpha) /* 346 */
#endif
#ifndef Tcl_UniCharIsDigit
#define Tcl_UniCharIsDigit \
	(tclStubsPtr->tcl_UniCharIsDigit) /* 347 */
#endif
#ifndef Tcl_UniCharIsLower
#define Tcl_UniCharIsLower \
	(tclStubsPtr->tcl_UniCharIsLower) /* 348 */
#endif
#ifndef Tcl_UniCharIsSpace
#define Tcl_UniCharIsSpace \
	(tclStubsPtr->tcl_UniCharIsSpace) /* 349 */
#endif
#ifndef Tcl_UniCharIsUpper
#define Tcl_UniCharIsUpper \
	(tclStubsPtr->tcl_UniCharIsUpper) /* 350 */
#endif
#ifndef Tcl_UniCharIsWordChar
#define Tcl_UniCharIsWordChar \
	(tclStubsPtr->tcl_UniCharIsWordChar) /* 351 */
#endif
#ifndef Tcl_UniCharLen
#define Tcl_UniCharLen \
	(tclStubsPtr->tcl_UniCharLen) /* 352 */
#endif
#ifndef Tcl_UniCharNcmp
#define Tcl_UniCharNcmp \
	(tclStubsPtr->tcl_UniCharNcmp) /* 353 */
#endif
#ifndef Tcl_UniCharToUtfDString
#define Tcl_UniCharToUtfDString \
	(tclStubsPtr->tcl_UniCharToUtfDString) /* 354 */
#endif
#ifndef Tcl_UtfToUniCharDString
#define Tcl_UtfToUniCharDString \
	(tclStubsPtr->tcl_UtfToUniCharDString) /* 355 */
#endif
#ifndef Tcl_GetRegExpFromObj
#define Tcl_GetRegExpFromObj \
	(tclStubsPtr->tcl_GetRegExpFromObj) /* 356 */
#endif
#ifndef Tcl_EvalTokens
#define Tcl_EvalTokens \
	(tclStubsPtr->tcl_EvalTokens) /* 357 */
#endif
#ifndef Tcl_FreeParse
#define Tcl_FreeParse \
	(tclStubsPtr->tcl_FreeParse) /* 358 */
#endif
#ifndef Tcl_LogCommandInfo
#define Tcl_LogCommandInfo \
	(tclStubsPtr->tcl_LogCommandInfo) /* 359 */
#endif
#ifndef Tcl_ParseBraces
#define Tcl_ParseBraces \
	(tclStubsPtr->tcl_ParseBraces) /* 360 */
#endif
#ifndef Tcl_ParseCommand
#define Tcl_ParseCommand \
	(tclStubsPtr->tcl_ParseCommand) /* 361 */
#endif
#ifndef Tcl_ParseExpr
#define Tcl_ParseExpr \
	(tclStubsPtr->tcl_ParseExpr) /* 362 */
#endif
#ifndef Tcl_ParseQuotedString
#define Tcl_ParseQuotedString \
	(tclStubsPtr->tcl_ParseQuotedString) /* 363 */
#endif
#ifndef Tcl_ParseVarName
#define Tcl_ParseVarName \
	(tclStubsPtr->tcl_ParseVarName) /* 364 */
#endif
#ifndef Tcl_GetCwd
#define Tcl_GetCwd \
	(tclStubsPtr->tcl_GetCwd) /* 365 */
#endif
#ifndef Tcl_Chdir
#define Tcl_Chdir \
	(tclStubsPtr->tcl_Chdir) /* 366 */
#endif

#endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */

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

#endif /* _TCLDECLS */

Added generic/tclEncoding.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
/*
 * tclEncoding.c --
 *
 *	Contains the implementation of the encoding conversion package.
 *
 * Copyright (c) 1996-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: tclEncoding.c,v 1.1.2.12 1999/04/14 00:33:21 surles Exp $
 */

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

typedef size_t (LengthProc)_ANSI_ARGS_((CONST char *src));

/*
 * The following data structure represents an encoding, which describes how
 * to convert between various character sets and UTF-8.
 */

typedef struct Encoding {
    char *name;			/* Name of encoding.  Malloced because (1)
				 * hash table entry that owns this encoding
				 * may be freed prior to this encoding being
				 * freed, (2) string passed in the
				 * Tcl_EncodingType structure may not be
				 * persistent. */
    Tcl_EncodingConvertProc *toUtfProc;
				/* Procedure to convert from external
				 * encoding into UTF-8. */
    Tcl_EncodingConvertProc *fromUtfProc;
				/* Procedure to convert from UTF-8 into
				 * external encoding. */
    Tcl_EncodingFreeProc *freeProc;
				/* If non-NULL, procedure to call when this
				 * encoding is deleted. */
    int nullSize;		/* Number of 0x00 bytes that signify
				 * end-of-string in this encoding.  This
				 * number is used to determine the source
				 * string length when the srcLen argument is
				 * negative.  This number can be 1 or 2. */
    ClientData clientData;	/* Arbitrary value associated with encoding
				 * type.  Passed to conversion procedures. */
    LengthProc *lengthProc;	/* Function to compute length of
				 * null-terminated strings in this encoding.
				 * If nullSize is 1, this is strlen; if
				 * nullSize is 2, this is a function that
				 * returns the number of bytes in a 0x0000
				 * terminated string. */
    int refCount;		/* Number of uses of this structure. */
    Tcl_HashEntry *hPtr;	/* Hash table entry that owns this encoding. */
} Encoding;

/*
 * The following structure is the clientData for a dynamically-loaded,
 * table-driven encoding created by LoadTableEncoding().  It maps between
 * Unicode and a single-byte, double-byte, or multibyte (1 or 2 bytes only)
 * encoding.
 */

typedef struct TableEncodingData {
    int fallback;		/* Character (in this encoding) to
				 * substitute when this encoding cannot
				 * represent a UTF-8 character. */
    char prefixBytes[256];	/* If a byte in the input stream is a lead
				 * byte for a 2-byte sequence, the
				 * corresponding entry in this array is 1,
				 * otherwise it is 0. */
    unsigned short **toUnicode;	/* Two dimensional sparse matrix to map
				 * characters from the encoding to Unicode.
				 * Each element of the toUnicode array points
				 * to an array of 256 shorts.  If there is no
				 * corresponding character in Unicode, the
				 * value in the matrix is 0x0000.  malloc'd. */
    unsigned short **fromUnicode;
				/* Two dimensional sparse matrix to map
				 * characters from Unicode to the encoding.
				 * Each element of the fromUnicode array
				 * points to an array of 256 shorts.  If there
				 * is no corresponding character the encoding,
				 * the value in the matrix is 0x0000.
				 * malloc'd. */
} TableEncodingData;

/*
 * The following structures is the clientData for a dynamically-loaded,
 * escape-driven encoding that is itself comprised of other simpler
 * encodings.  An example is "iso-2022-jp", which uses escape sequences to
 * switch between ascii, jis0208, jis0212, gb2312, and ksc5601.  Note that
 * "escape-driven" does not necessarily mean that the ESCAPE character is
 * the character used for switching character sets.
 */

typedef struct EscapeSubTable {
    unsigned int sequenceLen;	/* Length of following string. */
    char sequence[16];		/* Escape code that marks this encoding. */
    char name[32];		/* Name for encoding. */
    Encoding *encodingPtr;	/* Encoding loaded using above name, or NULL
				 * if this sub-encoding has not been needed
				 * yet. */
} EscapeSubTable;

typedef struct EscapeEncodingData {
    int fallback;		/* Character (in this encoding) to
				 * substitute when this encoding cannot
				 * represent a UTF-8 character. */
    unsigned int initLen;	/* Length of following string. */
    char init[16];		/* String to emit or expect before first char
				 * in conversion. */
    unsigned int finalLen;	/* Length of following string. */
    char final[16];		/* String to emit or expect after last char
				 * in conversion. */
    char prefixBytes[256];	/* If a byte in the input stream is the 
				 * first character of one of the escape 
				 * sequences in the following array, the 
				 * corresponding entry in this array is 1,
				 * otherwise it is 0. */
    int numSubTables;		/* Length of following array. */
    EscapeSubTable subTables[1];/* Information about each EscapeSubTable
				 * used by this encoding type.  The actual 
				 * size will be as large as necessary to 
				 * hold all EscapeSubTables. */
} EscapeEncodingData;

/*
 * Constants used when loading an encoding file to identify the type of the
 * file.
 */

#define ENCODING_SINGLEBYTE	0
#define ENCODING_DOUBLEBYTE	1
#define ENCODING_MULTIBYTE	2
#define ENCODING_ESCAPE		3

/*
 * Initialize the default encoding directory.  If this variable contains
 * a non NULL value, it will be the first path used to locate the
 * system encoding files.
 */

char *tclDefaultEncodingDir = NULL;

/*
 * Hash table that keeps track of all loaded Encodings.  Keys are
 * the string names that represent the encoding, values are (Encoding *).
 */
 
static Tcl_HashTable encodingTable;
TCL_DECLARE_MUTEX(encodingMutex)

/*
 * The following are used to hold the default and current system encodings.  
 * If NULL is passed to one of the conversion routines, the current setting 
 * of the system encoding will be used to perform the conversion.
 */

static Tcl_Encoding defaultEncoding;
static Tcl_Encoding systemEncoding;

/*
 * The following variable is used in the sparse matrix code for a
 * TableEncoding to represent a page in the table that has no entries.
 */

static unsigned short emptyPage[256];

/*
 * Procedures used only in this module.
 */

static int		BinaryProc _ANSI_ARGS_((ClientData clientData,
			    CONST char *src, int srcLen, int flags,
			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
			    int *srcReadPtr, int *dstWrotePtr,
			    int *dstCharsPtr));
static void		EscapeFreeProc _ANSI_ARGS_((ClientData clientData));
static int		EscapeFromUtfProc _ANSI_ARGS_((ClientData clientData,
			    CONST char *src, int srcLen, int flags,
			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
			    int *srcReadPtr, int *dstWrotePtr,
			    int *dstCharsPtr));
static int		EscapeToUtfProc _ANSI_ARGS_((ClientData clientData,
			    CONST char *src, int srcLen, int flags,
			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
			    int *srcReadPtr, int *dstWrotePtr,
			    int *dstCharsPtr));
static void		FreeEncoding _ANSI_ARGS_((Tcl_Encoding encoding));
static Encoding *	GetTableEncoding _ANSI_ARGS_((
			    EscapeEncodingData *dataPtr, int state));
static Tcl_Encoding	LoadEncodingFile _ANSI_ARGS_((Tcl_Interp *interp,
			    CONST char *name));
static Tcl_Encoding	LoadTableEncoding _ANSI_ARGS_((Tcl_Interp *interp,
			    CONST char *name, int type, Tcl_Channel chan));
static Tcl_Encoding	LoadEscapeEncoding _ANSI_ARGS_((CONST char *name, 
			    Tcl_Channel chan));
static Tcl_Channel	OpenEncodingFile _ANSI_ARGS_((CONST char *dir,
			    CONST char *name));
static void		TableFreeProc _ANSI_ARGS_((ClientData clientData));
static int		TableFromUtfProc _ANSI_ARGS_((ClientData clientData,
			    CONST char *src, int srcLen, int flags,
			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
			    int *srcReadPtr, int *dstWrotePtr,
			    int *dstCharsPtr));
static int		TableToUtfProc _ANSI_ARGS_((ClientData clientData,
			    CONST char *src, int srcLen, int flags,
			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
			    int *srcReadPtr, int *dstWrotePtr,
			    int *dstCharsPtr));
static size_t		unilen _ANSI_ARGS_((CONST char *src));
static int		UnicodeToUtfProc _ANSI_ARGS_((ClientData clientData,
			    CONST char *src, int srcLen, int flags,
			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
			    int *srcReadPtr, int *dstWrotePtr,
			    int *dstCharsPtr));
static int		UtfToUnicodeProc _ANSI_ARGS_((ClientData clientData,
			    CONST char *src, int srcLen, int flags,
			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
			    int *srcReadPtr, int *dstWrotePtr,
			    int *dstCharsPtr));
static int		UtfToUtfProc _ANSI_ARGS_((ClientData clientData,
			    CONST char *src, int srcLen, int flags,
			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
			    int *srcReadPtr, int *dstWrotePtr,
			    int *dstCharsPtr));


/*
 *---------------------------------------------------------------------------
 *
 * TclInitEncodingSubsystem --
 *
 *	Initialize all resources used by this subsystem on a per-process
 *	basis.  
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Depends on the memory, object, and IO subsystems.
 *
 *---------------------------------------------------------------------------
 */

void
TclInitEncodingSubsystem()
{
    Tcl_EncodingType type;

    Tcl_MutexLock(&encodingMutex);
    Tcl_InitHashTable(&encodingTable, TCL_STRING_KEYS);
    Tcl_MutexUnlock(&encodingMutex);
    
    /*
     * Create a few initial encodings.  Note that the UTF-8 to UTF-8 
     * translation is not a no-op, because it will turn a stream of
     * improperly formed UTF-8 into a properly formed stream.
     */

    type.encodingName	= "identity";
    type.toUtfProc	= BinaryProc;
    type.fromUtfProc	= BinaryProc;
    type.freeProc	= NULL;
    type.nullSize	= 1;
    type.clientData	= NULL;

    defaultEncoding	= Tcl_CreateEncoding(&type);
    systemEncoding	= Tcl_GetEncoding(NULL, type.encodingName);

    type.encodingName	= "utf-8";
    type.toUtfProc	= UtfToUtfProc;
    type.fromUtfProc    = UtfToUtfProc;
    type.freeProc	= NULL;
    type.nullSize	= 1;
    type.clientData	= NULL;
    Tcl_CreateEncoding(&type);

    type.encodingName   = "unicode";
    type.toUtfProc	= UnicodeToUtfProc;
    type.fromUtfProc    = UtfToUnicodeProc;
    type.freeProc	= NULL;
    type.nullSize	= 2;
    type.clientData	= NULL;
    Tcl_CreateEncoding(&type);
}


/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeEncodingSubsystem --
 *
 *	Release the state associated with the encoding subsystem.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees all of the encodings.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeEncodingSubsystem()
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    Encoding *encodingPtr;

    Tcl_MutexLock(&encodingMutex);
    hPtr = Tcl_FirstHashEntry(&encodingTable, &search);
    while (hPtr != NULL) {
	encodingPtr = (Encoding *) Tcl_GetHashValue(hPtr);
	if (encodingPtr->freeProc != NULL) {
	    (*encodingPtr->freeProc)(encodingPtr->clientData);
	}
	ckfree((char *) encodingPtr->name);
	ckfree((char *) encodingPtr);
	hPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&encodingTable);
    Tcl_MutexUnlock(&encodingMutex);
}

/*
 *-------------------------------------------------------------------------
 *
 * Tcl_GetDefaultEncodingDir --
 *
 *
 * Results:
 *
 * Side effects:
 *
 *-------------------------------------------------------------------------
 */

char *
Tcl_GetDefaultEncodingDir()
{
    return tclDefaultEncodingDir;
}

/*
 *-------------------------------------------------------------------------
 *
 * Tcl_SetDefaultEncodingDir --
 *
 *
 * Results:
 *
 * Side effects:
 *
 *-------------------------------------------------------------------------
 */

void
Tcl_SetDefaultEncodingDir(path)
    char *path;
{
    tclDefaultEncodingDir = (char *)ckalloc((unsigned) strlen(path) + 1);
    strcpy(tclDefaultEncodingDir, path);
}

/*
 *-------------------------------------------------------------------------
 *
 * Tcl_GetEncoding --
 *
 *	Given the name of a encoding, find the corresponding Tcl_Encoding
 *	token.  If the encoding did not already exist, Tcl attempts to
 *	dynamically load an encoding by that name.
 *
 * Results:
 *	Returns a token that represents the encoding.  If the name didn't
 *	refer to any known or loadable encoding, NULL is returned.  If
 *	NULL was returned, an error message is left in interp's result
 *	object, unless interp was NULL.
 *
 * Side effects:
 *	The new encoding type is entered into a table visible to all
 *	interpreters, keyed off the encoding's name.  For each call to
 *	this procedure, there should eventually be a call to
 *	Tcl_FreeEncoding, so that the database can be cleaned up when
 *	encodings aren't needed anymore.
 *
 *-------------------------------------------------------------------------
 */

Tcl_Encoding
Tcl_GetEncoding(interp, name)
    Tcl_Interp *interp;		/* Interp for error reporting, if not NULL. */
    CONST char *name;		/* The name of the desired encoding. */
{
    Tcl_HashEntry *hPtr;
    Encoding *encodingPtr;

    Tcl_MutexLock(&encodingMutex);
    if (name == NULL) {
	encodingPtr = (Encoding *) systemEncoding;
	encodingPtr->refCount++;
	Tcl_MutexUnlock(&encodingMutex);
	return systemEncoding;
    }

    hPtr = Tcl_FindHashEntry(&encodingTable, name);
    if (hPtr != NULL) {
	encodingPtr = (Encoding *) Tcl_GetHashValue(hPtr);
	encodingPtr->refCount++;
	Tcl_MutexUnlock(&encodingMutex);
	return (Tcl_Encoding) encodingPtr;
    }
    Tcl_MutexUnlock(&encodingMutex);
    return LoadEncodingFile(interp, name);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_FreeEncoding --
 *
 *	This procedure is called to release an encoding allocated by
 *	Tcl_CreateEncoding() or Tcl_GetEncoding().
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The reference count associated with the encoding is decremented
 *	and the encoding may be deleted if nothing is using it anymore.
 *
 *---------------------------------------------------------------------------
 */

void
Tcl_FreeEncoding(encoding)
    Tcl_Encoding encoding;
{
    Tcl_MutexLock(&encodingMutex);
    FreeEncoding(encoding);
    Tcl_MutexUnlock(&encodingMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * FreeEncoding --
 *
 *	This procedure is called to release an encoding by procedures
 *	that already have the encodingMutex.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The reference count associated with the encoding is decremented
 *	and the encoding may be deleted if nothing is using it anymore.
 *
 *----------------------------------------------------------------------
 */

static void
FreeEncoding(encoding)
    Tcl_Encoding encoding;
{
    Encoding *encodingPtr;
    
    encodingPtr = (Encoding *) encoding;
    if (encodingPtr == NULL) {
	return;
    }
    encodingPtr->refCount--;
    if (encodingPtr->refCount == 0) {
	if (encodingPtr->freeProc != NULL) {
	    (*encodingPtr->freeProc)(encodingPtr->clientData);
	}
	if (encodingPtr->hPtr != NULL) {
	    Tcl_DeleteHashEntry(encodingPtr->hPtr);
	}
	ckfree((char *) encodingPtr->name);
	ckfree((char *) encodingPtr);
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * Tcl_GetEncodingName --
 *
 *	Given an encoding, return the name that was used to constuct
 *	the encoding.
 *
 * Results:
 *	The name of the encoding.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

char *
Tcl_GetEncodingName(encoding)
    Tcl_Encoding encoding;	/* The encoding whose name to fetch. */
{
    Encoding *encodingPtr;

    if (encoding == NULL) {
	encoding = systemEncoding;
    }
    encodingPtr = (Encoding *) encoding;
    return encodingPtr->name;
}

/*
 *-------------------------------------------------------------------------
 *
 * Tcl_GetEncodingNames --
 *
 *	Get the list of all known encodings, including the ones stored
 *	as files on disk in the encoding path.
 *
 * Results:
 *	Modifies interp's result object to hold a list of all the available
 *	encodings.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

void
Tcl_GetEncodingNames(interp)
    Tcl_Interp *interp;		/* Interp to hold result. */
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    Tcl_Obj *pathPtr, *resultPtr;
    int dummy;

    Tcl_HashTable table;

    Tcl_MutexLock(&encodingMutex);
    Tcl_InitHashTable(&table, TCL_STRING_KEYS);
    hPtr = Tcl_FirstHashEntry(&encodingTable, &search);
    while (hPtr != NULL) {
	Encoding *encodingPtr;
	
	encodingPtr = (Encoding *) Tcl_GetHashValue(hPtr);
	Tcl_CreateHashEntry(&table, encodingPtr->name, &dummy);
	hPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_MutexUnlock(&encodingMutex);

    pathPtr = TclGetLibraryPath();
    if (pathPtr != NULL) {
	int i, objc;
	Tcl_Obj **objv;
	Tcl_DString pwdString;
	char globArgString[10];

	objc = 0;
	Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);

	Tcl_GetCwd(interp, &pwdString);

	for (i = 0; i < objc; i++) {
	    char *string;
	    int j, objc2, length;
	    Tcl_Obj **objv2;

	    string = Tcl_GetStringFromObj(objv[i], NULL);
	    Tcl_ResetResult(interp);

	    /*
	     * TclGlob() changes the contents of globArgString, which causes
	     * a segfault if we pass in a pointer to non-writeable memory.
	     * TclGlob() puts its results directly into interp.
	     */

	    strcpy(globArgString, "*.enc");
	    if ((Tcl_Chdir(string) == 0)
		    && (Tcl_Chdir("encoding") == 0)
		    && (TclGlob(interp, globArgString, 0) == TCL_OK)) {
		objc2 = 0;

		Tcl_ListObjGetElements(NULL, Tcl_GetObjResult(interp), &objc2,
			&objv2);

		for (j = 0; j < objc2; j++) {
		    string = Tcl_GetStringFromObj(objv2[j], &length);
		    length -= 4;
		    if (length > 0) {
			string[length] = '\0';
			Tcl_CreateHashEntry(&table, string, &dummy);
			string[length] = '.';
		    }
		}
	    }
	    Tcl_Chdir(Tcl_DStringValue(&pwdString));
	}
	Tcl_DStringFree(&pwdString);
    }

    /*
     * Clear any values placed in the result by globbing.
     */

    Tcl_ResetResult(interp);
    resultPtr = Tcl_GetObjResult(interp);

    hPtr = Tcl_FirstHashEntry(&table, &search);
    while (hPtr != NULL) {
	Tcl_Obj *strPtr;

	strPtr = Tcl_NewStringObj(Tcl_GetHashKey(&table, hPtr), -1);
	Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	hPtr = Tcl_NextHashEntry(&search);
    }
    Tcl_DeleteHashTable(&table);
}

/*
 *------------------------------------------------------------------------
 *
 * Tcl_SetSystemEncoding --
 *
 *	Sets the default encoding that should be used whenever the user
 *	passes a NULL value in to one of the conversion routines.
 *	If the supplied name is NULL, the system encoding is reset to the
 *	default system encoding.
 *
 * Results:
 *	The return value is TCL_OK if the system encoding was successfully
 *	set to the encoding specified by name, TCL_ERROR otherwise.  If
 *	TCL_ERROR is returned, an error message is left in interp's result
 *	object, unless interp was NULL.
 *
 * Side effects:
 *	The reference count of the new system encoding is incremented.
 *	The reference count of the old system encoding is decremented and 
 *	it may be freed.  
 *
 *------------------------------------------------------------------------
 */

int
Tcl_SetSystemEncoding(interp, name)
    Tcl_Interp *interp;		/* Interp for error reporting, if not NULL. */
    CONST char *name;		/* The name of the desired encoding, or NULL
				 * to reset to default encoding. */
{
    Tcl_Encoding encoding;
    Encoding *encodingPtr;

    if (name == NULL) {
	Tcl_MutexLock(&encodingMutex);
	encoding = defaultEncoding;
	encodingPtr = (Encoding *) encoding;
	encodingPtr->refCount++;
	Tcl_MutexUnlock(&encodingMutex);
    } else {
	encoding = Tcl_GetEncoding(interp, name);
	if (encoding == NULL) {
	    return TCL_ERROR;
	}
    }

    Tcl_MutexLock(&encodingMutex);
    FreeEncoding(systemEncoding);
    systemEncoding = encoding;
    Tcl_MutexUnlock(&encodingMutex);

    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_CreateEncoding --
 *
 *	This procedure is called to define a new encoding and the procedures
 *	that are used to convert between the specified encoding and Unicode.  
 *
 * Results:
 *	Returns a token that represents the encoding.  If an encoding with
 *	the same name already existed, the old encoding token remains
 *	valid and continues to behave as it used to, and will eventually
 *	be garbage collected when the last reference to it goes away.  Any
 *	subsequent calls to Tcl_GetEncoding with the specified name will
 *	retrieve the most recent encoding token.
 *
 * Side effects:
 *	The new encoding type is entered into a table visible to all
 *	interpreters, keyed off the encoding's name.  For each call to
 *	this procedure, there should eventually be a call to
 *	Tcl_FreeEncoding, so that the database can be cleaned up when
 *	encodings aren't needed anymore.
 *
 *---------------------------------------------------------------------------
 */ 

Tcl_Encoding
Tcl_CreateEncoding(typePtr)
    Tcl_EncodingType *typePtr;	/* The encoding type. */
{
    Tcl_HashEntry *hPtr;
    int new;
    Encoding *encodingPtr;
    char *name;

    Tcl_MutexLock(&encodingMutex);
    hPtr = Tcl_CreateHashEntry(&encodingTable, typePtr->encodingName, &new);
    if (new == 0) {
	/*
	 * Remove old encoding from hash table, but don't delete it until
	 * last reference goes away.
	 */
	 
	encodingPtr = (Encoding *) Tcl_GetHashValue(hPtr);
	encodingPtr->hPtr = NULL;
    }

    name = ckalloc((unsigned) strlen(typePtr->encodingName) + 1);
    
    encodingPtr = (Encoding *) ckalloc(sizeof(Encoding));
    encodingPtr->name		= strcpy(name, typePtr->encodingName);
    encodingPtr->toUtfProc	= typePtr->toUtfProc;
    encodingPtr->fromUtfProc	= typePtr->fromUtfProc;
    encodingPtr->freeProc	= typePtr->freeProc;
    encodingPtr->nullSize	= typePtr->nullSize;
    encodingPtr->clientData	= typePtr->clientData;
    if (typePtr->nullSize == 1) {
	encodingPtr->lengthProc = strlen;
    } else {
	encodingPtr->lengthProc = unilen;
    }
    encodingPtr->refCount	= 1;
    encodingPtr->hPtr		= hPtr;
    Tcl_SetHashValue(hPtr, encodingPtr);

    Tcl_MutexUnlock(&encodingMutex);

    return (Tcl_Encoding) encodingPtr;
}

/*
 *-------------------------------------------------------------------------
 *
 * Tcl_ExternalToUtfDString --
 *
 *	Convert a source buffer from the specified encoding into UTF-8.
 *	If any of the bytes in the source buffer are invalid or cannot
 *	be represented in the target encoding, a default fallback
 *	character will be substituted.
 *
 * Results:
 *	The converted bytes are stored in the DString, which is then NULL
 *	terminated.  The return value is a pointer to the value stored 
 *	in the DString.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

char * 
Tcl_ExternalToUtfDString(encoding, src, srcLen, dstPtr)
    Tcl_Encoding encoding;	/* The encoding for the source string, or
				 * NULL for the default system encoding. */
    CONST char *src;		/* Source string in specified encoding. */
    int srcLen;			/* Source string length in bytes, or < 0 for
				 * encoding-specific string length. */
    Tcl_DString *dstPtr;	/* Uninitialized or free DString in which 
				 * the converted string is stored. */
{
    char *dst;
    Tcl_EncodingState state;
    Encoding *encodingPtr;
    int flags, dstLen, result, soFar, srcRead, dstWrote, dstChars;

    Tcl_DStringInit(dstPtr);
    dst = Tcl_DStringValue(dstPtr);
    dstLen = dstPtr->spaceAvl - 1;
    
    if (encoding == NULL) {
	encoding = systemEncoding;
    }
    encodingPtr = (Encoding *) encoding;

    if (src == NULL) {
	srcLen = 0;
    } else if (srcLen < 0) {
	srcLen = (*encodingPtr->lengthProc)(src);
    }
    flags = TCL_ENCODING_START | TCL_ENCODING_END;
    while (1) {
	result = (*encodingPtr->toUtfProc)(encodingPtr->clientData, src,
		srcLen, flags, &state, dst, dstLen, &srcRead, &dstWrote,
		&dstChars);
	soFar = dst + dstWrote - Tcl_DStringValue(dstPtr);
	if (result != TCL_CONVERT_NOSPACE) {
	    Tcl_DStringSetLength(dstPtr, soFar);
	    return Tcl_DStringValue(dstPtr);
	}
	flags &= ~TCL_ENCODING_START;
	src += srcRead;
	srcLen -= srcRead;
	if (Tcl_DStringLength(dstPtr) == 0) {
	    Tcl_DStringSetLength(dstPtr, dstLen);
	}
	Tcl_DStringSetLength(dstPtr, 2 * Tcl_DStringLength(dstPtr) + 1);
	dst = Tcl_DStringValue(dstPtr) + soFar;
	dstLen = Tcl_DStringLength(dstPtr) - soFar - 1;
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * Tcl_ExternalToUtf --
 *
 *	Convert a source buffer from the specified encoding into UTF-8,
 *
 * Results:
 *	The return value is one of TCL_OK, TCL_CONVERT_MULTIBYTE,
 *	TCL_CONVERT_SYNTAX, TCL_CONVERT_UNKNOWN, or TCL_CONVERT_NOSPACE,
 *	as documented in tcl.h.
 *
 * Side effects:
 *	The converted bytes are stored in the output buffer.  
 *
 *-------------------------------------------------------------------------
 */

int
Tcl_ExternalToUtf(interp, encoding, src, srcLen, flags, statePtr, dst,
	dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr)
    Tcl_Interp *interp;		/* Interp for error return, if not NULL. */
    Tcl_Encoding encoding;	/* The encoding for the source string, or
				 * NULL for the default system encoding. */
    CONST char *src;		/* Source string in specified encoding. */
    int srcLen;			/* Source string length in bytes, or < 0 for
				 * encoding-specific string length. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Place for conversion routine to store
				 * state information used during a piecewise
				 * conversion.  Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst;			/* Output buffer in which converted string
				 * is stored. */
    int dstLen;			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr;		/* Filled with the number of bytes from the
				 * source string that were converted.  This
				 * may be less than the original source length
				 * if there was a problem converting some
				 * source characters. */
    int *dstWrotePtr;		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr;		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    Encoding *encodingPtr;
    int result, srcRead, dstWrote, dstChars;
    Tcl_EncodingState state;
    
    if (encoding == NULL) {
	encoding = systemEncoding;
    }
    encodingPtr = (Encoding *) encoding;

    if (src == NULL) {
	srcLen = 0;
    } else if (srcLen < 0) {
	srcLen = (*encodingPtr->lengthProc)(src);
    }
    if (statePtr == NULL) {
	flags |= TCL_ENCODING_START | TCL_ENCODING_END;
	statePtr = &state;
    }
    if (srcReadPtr == NULL) {
	srcReadPtr = &srcRead;
    }
    if (dstWrotePtr == NULL) {
	dstWrotePtr = &dstWrote;
    }
    if (dstCharsPtr == NULL) {
	dstCharsPtr = &dstChars;
    }

    /*
     * If there are any null characters in the middle of the buffer, they will
     * converted to the UTF-8 null character (\xC080).  To get the actual 
     * \0 at the end of the destination buffer, we need to append it manually.
     */

    dstLen--;
    result = (*encodingPtr->toUtfProc)(encodingPtr->clientData, src, srcLen,
	    flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr,
	    dstCharsPtr);
    dst[*dstWrotePtr] = '\0';
    return result;
}

/*
 *-------------------------------------------------------------------------
 *
 * Tcl_UtfToExternalDString --
 *
 *	Convert a source buffer from UTF-8 into the specified encoding.
 *	If any of the bytes in the source buffer are invalid or cannot
 *	be represented in the target encoding, a default fallback
 *	character will be substituted.
 *
 * Results:
 *	The converted bytes are stored in the DString, which is then
 *	NULL terminated in an encoding-specific manner.  The return value 
 *	is a pointer to the value stored in the DString.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

char *
Tcl_UtfToExternalDString(encoding, src, srcLen, dstPtr)
    Tcl_Encoding encoding;	/* The encoding for the converted string,
				 * or NULL for the default system encoding. */
    CONST char *src;		/* Source string in UTF-8. */
    int srcLen;			/* Source string length in bytes, or < 0 for
				 * strlen(). */
    Tcl_DString *dstPtr;	/* Uninitialized or free DString in which 
				 * the converted string is stored. */
{
    char *dst;
    Tcl_EncodingState state;
    Encoding *encodingPtr;
    int flags, dstLen, result, soFar, srcRead, dstWrote, dstChars;
    
    Tcl_DStringInit(dstPtr);
    dst = Tcl_DStringValue(dstPtr);
    dstLen = dstPtr->spaceAvl - 1;

    if (encoding == NULL) {
	encoding = systemEncoding;
    }
    encodingPtr = (Encoding *) encoding;

    if (src == NULL) {
	srcLen = 0;
    } else if (srcLen < 0) {
	srcLen = strlen(src);
    }
    flags = TCL_ENCODING_START | TCL_ENCODING_END;
    while (1) {
	result = (*encodingPtr->fromUtfProc)(encodingPtr->clientData, src,
		srcLen, flags, &state, dst, dstLen, &srcRead, &dstWrote,
		&dstChars);
	soFar = dst + dstWrote - Tcl_DStringValue(dstPtr);
	if (result != TCL_CONVERT_NOSPACE) {
	    if (encodingPtr->nullSize == 2) {
	        Tcl_DStringSetLength(dstPtr, soFar + 1);
	    }
	    Tcl_DStringSetLength(dstPtr, soFar);
	    return Tcl_DStringValue(dstPtr);
	}
	flags &= ~TCL_ENCODING_START;
	src += srcRead;
	srcLen -= srcRead;
	if (Tcl_DStringLength(dstPtr) == 0) {
	    Tcl_DStringSetLength(dstPtr, dstLen);
	}
	Tcl_DStringSetLength(dstPtr, 2 * Tcl_DStringLength(dstPtr) + 1);
	dst = Tcl_DStringValue(dstPtr) + soFar;
	dstLen = Tcl_DStringLength(dstPtr) - soFar - 1;
    }
}

/*
 *-------------------------------------------------------------------------
 *
 * Tcl_UtfToExternal --
 *
 *	Convert a buffer from UTF-8 into the specified encoding.
 *
 * Results:
 *	The return value is one of TCL_OK, TCL_CONVERT_MULTIBYTE,
 *	TCL_CONVERT_SYNTAX, TCL_CONVERT_UNKNOWN, or TCL_CONVERT_NOSPACE,
 *	as documented in tcl.h.
 *
 * Side effects:
 *	The converted bytes are stored in the output buffer.  
 *
 *-------------------------------------------------------------------------
 */

int
Tcl_UtfToExternal(interp, encoding, src, srcLen, flags, statePtr, dst,
	dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr)
    Tcl_Interp *interp;		/* Interp for error return, if not NULL. */
    Tcl_Encoding encoding;	/* The encoding for the converted string,
				 * or NULL for the default system encoding. */
    CONST char *src;		/* Source string in UTF-8. */
    int srcLen;			/* Source string length in bytes, or < 0 for
				 * strlen(). */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Place for conversion routine to store
				 * state information used during a piecewise
				 * conversion.  Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst;			/* Output buffer in which converted string
				 * is stored. */
    int dstLen;			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr;		/* Filled with the number of bytes from the
				 * source string that were converted.  This
				 * may be less than the original source length
				 * if there was a problem converting some
				 * source characters. */
    int *dstWrotePtr;		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr;		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    Encoding *encodingPtr;
    int result, srcRead, dstWrote, dstChars;
    Tcl_EncodingState state;
    
    if (encoding == NULL) {
	encoding = systemEncoding;
    }
    encodingPtr = (Encoding *) encoding;

    if (src == NULL) {
	srcLen = 0;
    } else if (srcLen < 0) {
	srcLen = strlen(src);
    }
    if (statePtr == NULL) {
	flags |= TCL_ENCODING_START | TCL_ENCODING_END;
	statePtr = &state;
    }
    if (srcReadPtr == NULL) {
	srcReadPtr = &srcRead;
    }
    if (dstWrotePtr == NULL) {
	dstWrotePtr = &dstWrote;
    }
    if (dstCharsPtr == NULL) {
	dstCharsPtr = &dstChars;
    }

    dstLen -= encodingPtr->nullSize;
    result = (*encodingPtr->fromUtfProc)(encodingPtr->clientData, src, srcLen,
	    flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr,
	    dstCharsPtr);
    if (encodingPtr->nullSize == 2) {
	dst[*dstWrotePtr + 1] = '\0';
    }
    dst[*dstWrotePtr] = '\0';
    
    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_FindExecutable --
 *
 *	This procedure computes the absolute path name of the current
 *	application, given its argv[0] value.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The variable tclExecutableName gets filled in with the file
 *	name for the application, if we figured it out.  If we couldn't
 *	figure it out, tclExecutableName is set to NULL.
 *
 *---------------------------------------------------------------------------
 */

void
Tcl_FindExecutable(argv0)
    CONST char *argv0;		/* The value of the application's argv[0]
				 * (native). */
{
    CONST char *name;
    Tcl_DString buffer, nameString;

    TclInitSubsystems(argv0);

    if (argv0 == NULL) {
	goto done;
    }
    if (tclExecutableName != NULL) {
	ckfree(tclExecutableName);
	tclExecutableName = NULL;
    }
    if ((name = TclpFindExecutable(argv0)) == NULL) {
	goto done;
    }

    /*
     * The value returned from TclpNameOfExecutable is a UTF string that
     * is possibly dirty depending on when it was initialized.  To assure
     * that the UTF string is a properly encoded native string for this
     * system, convert the UTF string to the default native encoding
     * before the default encoding is initialized.  Then, convert it back
     * to UTF after the system encoding is loaded.
     */
    
    Tcl_UtfToExternalDString(NULL, name, -1, &buffer);
    TclFindEncodings(argv0);

    /*
     * Now it is OK to convert the native string back to UTF and set
     * the value of the tclExecutableName.
     */
    
    Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&buffer), -1, &nameString);
    tclExecutableName = (char *)
	ckalloc((unsigned) (Tcl_DStringLength(&nameString) + 1));
    strcpy(tclExecutableName, Tcl_DStringValue(&nameString));

    Tcl_DStringFree(&buffer);
    Tcl_DStringFree(&nameString);
    return;
	
    done:
    TclFindEncodings(argv0);
}

/*
 *---------------------------------------------------------------------------
 *
 * LoadEncodingFile --
 *
 *	Read a file that describes an encoding and create a new Encoding
 *	from the data.  
 *
 * Results:
 *	The return value is the newly loaded Encoding, or NULL if
 *	the file didn't exist of was in the incorrect format.  If NULL was
 *	returned, an error message is left in interp's result object,
 *	unless interp was NULL.
 *
 * Side effects:
 *	File read from disk.  
 *
 *---------------------------------------------------------------------------
 */

static Tcl_Encoding
LoadEncodingFile(interp, name)
    Tcl_Interp *interp;		/* Interp for error reporting, if not NULL. */
    CONST char *name;		/* The name of the encoding file on disk
				 * and also the name for new encoding. */
{
    int objc, i, ch;
    Tcl_Obj **objv;
    Tcl_Obj *pathPtr;
    Tcl_Channel chan;
    Tcl_Encoding encoding;

    pathPtr = TclGetLibraryPath();
    if (pathPtr == NULL) {
	goto unknown;
    }
    objc = 0;
    Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);

    chan = NULL;
    for (i = 0; i < objc; i++) {
	chan = OpenEncodingFile(Tcl_GetString(objv[i]), name);
	if (chan != NULL) {
	    break;
	}
    }

    if (chan == NULL) {
	goto unknown;
    }

    Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");

    while (1) {
	Tcl_DString ds;

	Tcl_DStringInit(&ds);
	Tcl_Gets(chan, &ds);
	ch = Tcl_DStringValue(&ds)[0];
	Tcl_DStringFree(&ds);
	if (ch != '#') {
	    break;
	}
    }

    encoding = NULL;
    switch (ch) {
	case 'S': {
	    encoding = LoadTableEncoding(interp, name, ENCODING_SINGLEBYTE,
		    chan);
	    break;
	}
	case 'D': {
	    encoding = LoadTableEncoding(interp, name, ENCODING_DOUBLEBYTE,
		    chan);
	    break;
	}
	case 'M': {
	    encoding = LoadTableEncoding(interp, name, ENCODING_MULTIBYTE,
		    chan);
	    break;
	}
	case 'E': {
	    encoding = LoadEscapeEncoding(name, chan);
	    break;
	}
    }
    if ((encoding == NULL) && (interp != NULL)) {
	Tcl_AppendResult(interp, "invalid encoding file \"", name, "\"", NULL);
    }
    Tcl_Close(NULL, chan);
    return encoding;

    unknown:
    if (interp != NULL) {
	Tcl_AppendResult(interp, "unknown encoding \"", name, "\"", NULL);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * OpenEncodingFile --
 *
 *	Look for the file encoding/<name>.enc in the specified
 *	directory.
 *
 * Results:
 *	Returns an open file channel if the file exists.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Channel
OpenEncodingFile(dir, name)
    CONST char *dir;
    CONST char *name;

{
    char *argv[3];
    Tcl_DString pathString;
    char *path;
    Tcl_Channel chan;
    
    argv[0] = (char *) dir;
    argv[1] = "encoding";
    argv[2] = (char *) name;

    Tcl_DStringInit(&pathString);
    Tcl_JoinPath(3, argv, &pathString);
    path = Tcl_DStringAppend(&pathString, ".enc", -1);
    chan = Tcl_OpenFileChannel(NULL, path, "r", 0);
    Tcl_DStringFree(&pathString);

    return chan;
}

/*
 *-------------------------------------------------------------------------
 *
 * LoadTableEncoding --
 *
 *	Helper function for LoadEncodingTable().  Loads a table to that 
 *	converts between Unicode and some other encoding and creates an 
 *	encoding (using a TableEncoding structure) from that information.
 *
 *	File contains binary data, but begins with a marker to indicate 
 *	byte-ordering, so that same binary file can be read on either
 *	endian platforms.
 *
 * Results:
 *	The return value is the new encoding, or NULL if the encoding 
 *	could not be created (because the file contained invalid data).
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static Tcl_Encoding
LoadTableEncoding(interp, name, type, chan)
    Tcl_Interp *interp;		/* Interp for temporary obj while reading. */
    CONST char *name;		/* Name for new encoding. */
    int type;			/* Type of encoding (ENCODING_?????). */
    Tcl_Channel chan;		/* File containing new encoding. */
{
    Tcl_DString lineString;
    Tcl_Obj *objPtr;
    char *line;
    int i, hi, lo, numPages, symbol, fallback;
    unsigned char used[256];
    unsigned int size;
    TableEncodingData *dataPtr;
    unsigned short *pageMemPtr;
    Tcl_EncodingType encType;
    char *hex;
    static char staticHex[] = {
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0,
	10, 11, 12, 13, 14, 15
    };

    hex = staticHex - '0';

    Tcl_DStringInit(&lineString);
    Tcl_Gets(chan, &lineString);
    line = Tcl_DStringValue(&lineString);

    fallback = (int) strtol(line, &line, 16);
    symbol = (int) strtol(line, &line, 10);
    numPages = (int) strtol(line, &line, 10);
    Tcl_DStringFree(&lineString);

    if (numPages < 0) {
	numPages = 0;
    } else if (numPages > 256) {
	numPages = 256;
    }

    memset(used, 0, sizeof(used));

#undef PAGESIZE
#define PAGESIZE    (256 * sizeof(unsigned short))

    dataPtr = (TableEncodingData *) ckalloc(sizeof(TableEncodingData));
    memset(dataPtr, 0, sizeof(TableEncodingData));

    dataPtr->fallback = fallback;

    /*
     * Read the table that maps characters to Unicode.  Performs a single
     * malloc to get the memory for the array and all the pages needed by
     * the array.
     */

    size = 256 * sizeof(unsigned short *) + numPages * PAGESIZE;
    dataPtr->toUnicode = (unsigned short **) ckalloc(size);
    memset(dataPtr->toUnicode, 0, size);
    pageMemPtr = (unsigned short *) (dataPtr->toUnicode + 256);

    if (interp == NULL) {
	objPtr = Tcl_NewObj();
    } else {
	objPtr = Tcl_GetObjResult(interp);
    }
    for (i = 0; i < numPages; i++) {
	int ch;
	char *p;

	Tcl_ReadChars(chan, objPtr, 3 + 16 * (16 * 4 + 1), 0);
	p = Tcl_GetString(objPtr);
	hi = (hex[(int)p[0]] << 4) + hex[(int)p[1]];
	dataPtr->toUnicode[hi] = pageMemPtr;
	p += 2;
	for (lo = 0; lo < 256; lo++) {
	    if ((lo & 0x0f) == 0) {
		p++;
	    }
	    ch = (hex[(int)p[0]] << 12) + (hex[(int)p[1]] << 8)
		+ (hex[(int)p[2]] << 4) + hex[(int)p[3]];
	    if (ch != 0) {
		used[ch >> 8] = 1;
	    }
	    *pageMemPtr = (unsigned short) ch;
	    pageMemPtr++;
	    p += 4;
	}
    }
    if (interp == NULL) {
	Tcl_DecrRefCount(objPtr);
    } else {
	Tcl_ResetResult(interp);
    }
	
    if (type == ENCODING_DOUBLEBYTE) {
	memset(dataPtr->prefixBytes, 1, sizeof(dataPtr->prefixBytes));
    } else {
	for (hi = 1; hi < 256; hi++) {
	    if (dataPtr->toUnicode[hi] != NULL) {
		dataPtr->prefixBytes[hi] = 1;
	    }
	}
    }

    /*
     * Invert toUnicode array to produce the fromUnicode array.  Performs a
     * single malloc to get the memory for the array and all the pages
     * needed by the array.  While reading in the toUnicode array, we
     * remembered what pages that would be needed for the fromUnicode array.
     */

    if (symbol) {
	used[0] = 1;
    }
    numPages = 0;
    for (hi = 0; hi < 256; hi++) {
	if (used[hi]) {
	    numPages++;
	}
    }
    size = 256 * sizeof(unsigned short *) + numPages * PAGESIZE;
    dataPtr->fromUnicode = (unsigned short **) ckalloc(size);
    memset(dataPtr->fromUnicode, 0, size);
    pageMemPtr = (unsigned short *) (dataPtr->fromUnicode + 256);

    for (hi = 0; hi < 256; hi++) {
	if (dataPtr->toUnicode[hi] == NULL) {
	    dataPtr->toUnicode[hi] = emptyPage;
	} else {
	    for (lo = 0; lo < 256; lo++) {
		int ch;

		ch = dataPtr->toUnicode[hi][lo];
		if (ch != 0) {
		    unsigned short *page;
		    
		    page = dataPtr->fromUnicode[ch >> 8];
		    if (page == NULL) {
			page = pageMemPtr;
			pageMemPtr += 256;
			dataPtr->fromUnicode[ch >> 8] = page;
		    }
		    page[ch & 0xff] = (unsigned short) ((hi << 8) + lo);
		}
	    }
	}
    }
    if (type == ENCODING_MULTIBYTE) {
	/*
	 * If multibyte encodings don't have a backslash character, define
	 * one.  Otherwise, on Windows, native file names won't work because
	 * the backslash in the file name will map to the unknown character
	 * (question mark) when converting from UTF-8 to external encoding.
	 */

	if (dataPtr->fromUnicode[0] != NULL) {
	    if (dataPtr->fromUnicode[0]['\\'] == '\0') {
		dataPtr->fromUnicode[0]['\\'] = '\\';
	    }
	}
    }
    if (symbol) {
	unsigned short *page;
	
	/*
	 * Make a special symbol encoding that not only maps the symbol
	 * characters from their Unicode code points down into page 0, but
	 * also ensure that the characters on page 0 map to themselves.
	 * This is so that a symbol font can be used to display a simple
	 * string like "abcd" and have alpha, beta, chi, delta show up,
	 * rather than have "unknown" chars show up because strictly
	 * speaking the symbol font doesn't have glyphs for those low ascii
	 * chars.
	 */

	page = dataPtr->fromUnicode[0];
	if (page == NULL) {
	    page = pageMemPtr;
	    dataPtr->fromUnicode[0] = page;
	}
	for (lo = 0; lo < 256; lo++) {
	    if (dataPtr->toUnicode[0][lo] != 0) {
		page[lo] = (unsigned short) lo;
	    }
	}
    }
    for (hi = 0; hi < 256; hi++) {
	if (dataPtr->fromUnicode[hi] == NULL) {
	    dataPtr->fromUnicode[hi] = emptyPage;
	}
    }
    encType.encodingName    = name;
    encType.toUtfProc	    = TableToUtfProc;
    encType.fromUtfProc	    = TableFromUtfProc;
    encType.freeProc	    = TableFreeProc;
    encType.nullSize	    = (type == ENCODING_DOUBLEBYTE) ? 2 : 1;
    encType.clientData	    = (ClientData) dataPtr;
    return Tcl_CreateEncoding(&encType);

}

/*
 *-------------------------------------------------------------------------
 *
 * LoadEscapeEncoding --
 *
 *	Helper function for LoadEncodingTable().  Loads a state machine
 *	that converts between Unicode and some other encoding.  
 *
 *	File contains text data that describes the escape sequences that
 *	are used to choose an encoding and the associated names for the 
 *	sub-encodings.
 *
 * Results:
 *	The return value is the new encoding, or NULL if the encoding 
 *	could not be created (because the file contained invalid data).
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static Tcl_Encoding
LoadEscapeEncoding(name, chan)
    CONST char *name;		/* Name for new encoding. */
    Tcl_Channel chan;		/* File containing new encoding. */
{
    int i;
    unsigned int size;
    Tcl_DString escapeData;
    char init[16], final[16];
    EscapeEncodingData *dataPtr;
    Tcl_EncodingType type;

    init[0] = '\0';
    final[0] = '\0';
    Tcl_DStringInit(&escapeData);

    while (1) {
	int argc;
	char **argv;
	char *line;
	Tcl_DString lineString;
	
	Tcl_DStringInit(&lineString);
	if (Tcl_Gets(chan, &lineString) < 0) {
	    break;
	}
	line = Tcl_DStringValue(&lineString);
        if (Tcl_SplitList(NULL, line, &argc, &argv) != TCL_OK) {
	    continue;
	}
	if (argc >= 2) {
	    if (strcmp(argv[0], "name") == 0) {
		;
	    } else if (strcmp(argv[0], "init") == 0) {
		strncpy(init, argv[1], sizeof(init));
		init[sizeof(init) - 1] = '\0';
	    } else if (strcmp(argv[0], "final") == 0) {
		strncpy(final, argv[1], sizeof(final));
		final[sizeof(final) - 1] = '\0';
	    } else {
		EscapeSubTable est;

		strncpy(est.sequence, argv[1], sizeof(est.sequence));
		est.sequence[sizeof(est.sequence) - 1] = '\0';
		est.sequenceLen = strlen(est.sequence);

		strncpy(est.name, argv[0], sizeof(est.name));
		est.name[sizeof(est.name) - 1] = '\0';

		est.encodingPtr = NULL;
		Tcl_DStringAppend(&escapeData, (char *) &est, sizeof(est));
	    }
	}
	ckfree((char *) argv);
	Tcl_DStringFree(&lineString);
    }

    size = sizeof(EscapeEncodingData)
	    - sizeof(EscapeSubTable) + Tcl_DStringLength(&escapeData);
    dataPtr = (EscapeEncodingData *) ckalloc(size);
    dataPtr->initLen = strlen(init);
    strcpy(dataPtr->init, init);
    dataPtr->finalLen = strlen(final);
    strcpy(dataPtr->final, final);
    dataPtr->numSubTables = Tcl_DStringLength(&escapeData) / sizeof(EscapeSubTable);
    memcpy((VOID *) dataPtr->subTables, (VOID *) Tcl_DStringValue(&escapeData),
	    (size_t) Tcl_DStringLength(&escapeData));
    Tcl_DStringFree(&escapeData);

    memset(dataPtr->prefixBytes, 0, sizeof(dataPtr->prefixBytes));
    for (i = 0; i < dataPtr->numSubTables; i++) {
	dataPtr->prefixBytes[UCHAR(dataPtr->subTables[i].sequence[0])] = 1;
    }
    if (dataPtr->init[0] != '\0') {
	dataPtr->prefixBytes[UCHAR(dataPtr->init[0])] = 1;
    }
    if (dataPtr->final[0] != '\0') {
	dataPtr->prefixBytes[UCHAR(dataPtr->final[0])] = 1;
    }

    type.encodingName	= name;
    type.toUtfProc	= EscapeToUtfProc;
    type.fromUtfProc    = EscapeFromUtfProc;
    type.freeProc	= EscapeFreeProc;
    type.nullSize	= 1;
    type.clientData	= (ClientData) dataPtr;

    return Tcl_CreateEncoding(&type);
}

/*
 *-------------------------------------------------------------------------
 *
 * BinaryProc --
 *
 *	The default conversion when no other conversion is specified.
 *	No translation is done; source bytes are copied directly to 
 *	destination bytes.
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int
BinaryProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
	srcReadPtr, dstWrotePtr, dstCharsPtr)
    ClientData clientData;	/* Not used. */
    CONST char *src;		/* Source string (unknown encoding). */
    int srcLen;			/* Source string length in bytes. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Place for conversion routine to store
				 * state information used during a piecewise
				 * conversion.  Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst;			/* Output buffer in which converted string
				 * is stored. */
    int dstLen;			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr;		/* Filled with the number of bytes from the
				 * source string that were converted. */
    int *dstWrotePtr;		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr;		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    int result;

    result = TCL_OK;
    dstLen -= TCL_UTF_MAX - 1;
    if (dstLen < 0) {
	dstLen = 0;
    }
    if (srcLen > dstLen) {
	srcLen = dstLen;
	result = TCL_CONVERT_NOSPACE;
    }

    *srcReadPtr = srcLen;
    *dstWrotePtr = srcLen;
    *dstCharsPtr = srcLen;
    for ( ; --srcLen >= 0; ) {
	*dst++ = *src++;
    }
    return result;
}

/*
 *-------------------------------------------------------------------------
 *
 * UtfToUtfProc --
 *
 *	Convert from UTF-8 to UTF-8.  Note that the UTF-8 to UTF-8 
 *	translation is not a no-op, because it will turn a stream of
 *	improperly formed UTF-8 into a properly formed stream.
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int 
UtfToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
	srcReadPtr, dstWrotePtr, dstCharsPtr)
    ClientData clientData;	/* Not used. */
    CONST char *src;		/* Source string in UTF-8. */
    int srcLen;			/* Source string length in bytes. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Place for conversion routine to store
				 * state information used during a piecewise
				 * conversion.  Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst;			/* Output buffer in which converted string
				 * is stored. */
    int dstLen;			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr;		/* Filled with the number of bytes from the
				 * source string that were converted.  This
				 * may be less than the original source length
				 * if there was a problem converting some
				 * source characters. */
    int *dstWrotePtr;		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr;		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    CONST char *srcStart, *srcEnd, *srcClose;
    char *dstStart, *dstEnd;
    int result, numChars;
    Tcl_UniChar ch;

    result = TCL_OK;
    
    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    if ((flags & TCL_ENCODING_END) == 0) {
	srcClose -= TCL_UTF_MAX;
    }

    dstStart = dst;
    dstEnd = dst + dstLen - TCL_UTF_MAX;

    for (numChars = 0; src < srcEnd; numChars++) {
	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */

	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	src += Tcl_UtfToUniChar(src, &ch);
	dst += Tcl_UniCharToUtf(ch, dst);
    }

    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}

/*
 *-------------------------------------------------------------------------
 *
 * UnicodeToUtfProc --
 *
 *	Convert from Unicode to UTF-8.
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int 
UnicodeToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
	srcReadPtr, dstWrotePtr, dstCharsPtr)
    ClientData clientData;	/* Not used. */
    CONST char *src;		/* Source string in Unicode. */
    int srcLen;			/* Source string length in bytes. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Place for conversion routine to store
				 * state information used during a piecewise
				 * conversion.  Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst;			/* Output buffer in which converted string
				 * is stored. */
    int dstLen;			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr;		/* Filled with the number of bytes from the
				 * source string that were converted.  This
				 * may be less than the original source length
				 * if there was a problem converting some
				 * source characters. */
    int *dstWrotePtr;		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr;		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    CONST Tcl_UniChar *wSrc, *wSrcStart, *wSrcEnd;
    char *dstEnd, *dstStart;
    int result, numChars;
    
    result = TCL_OK;
    if ((srcLen % sizeof(Tcl_UniChar)) != 0) {
	result = TCL_CONVERT_MULTIBYTE;
	srcLen /= sizeof(Tcl_UniChar);
	srcLen *= sizeof(Tcl_UniChar);
    }

    wSrc = (Tcl_UniChar *) src;

    wSrcStart = (Tcl_UniChar *) src;
    wSrcEnd = (Tcl_UniChar *) (src + srcLen);

    dstStart = dst;
    dstEnd = dst + dstLen - TCL_UTF_MAX;

    for (numChars = 0; wSrc < wSrcEnd; numChars++) {
	if (dst > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
	}
	dst += Tcl_UniCharToUtf(*wSrc, dst);
	wSrc++;
    }

    *srcReadPtr = (char *) wSrc - (char *) wSrcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}

/*
 *-------------------------------------------------------------------------
 *
 * UtfToUnicodeProc --
 *
 *	Convert from UTF-8 to Unicode.
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int 
UtfToUnicodeProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
	srcReadPtr, dstWrotePtr, dstCharsPtr)
    ClientData clientData;	/* TableEncodingData that specifies encoding. */
    CONST char *src;		/* Source string in UTF-8. */
    int srcLen;			/* Source string length in bytes. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Place for conversion routine to store
				 * state information used during a piecewise
				 * conversion.  Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst;			/* Output buffer in which converted string
				 * is stored. */
    int dstLen;			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr;		/* Filled with the number of bytes from the
				 * source string that were converted.  This
				 * may be less than the original source length
				 * if there was a problem converting some
				 * source characters. */
    int *dstWrotePtr;		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr;		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    CONST char *srcStart, *srcEnd, *srcClose;
    Tcl_UniChar *wDst, *wDstStart, *wDstEnd;
    int result, numChars;
    
    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    if ((flags & TCL_ENCODING_END) == 0) {
	srcClose -= TCL_UTF_MAX;
    }

    wDst = (Tcl_UniChar *) dst;
    wDstStart = (Tcl_UniChar *) dst;
    wDstEnd = (Tcl_UniChar *) (dst + dstLen - sizeof(Tcl_UniChar));

    result = TCL_OK;
    for (numChars = 0; src < srcEnd; numChars++) {
	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */

	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
	if (wDst > wDstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	    break;
        }
	src += Tcl_UtfToUniChar(src, wDst);
	wDst++;
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = (char *) wDst - (char *) wDstStart;
    *dstCharsPtr = numChars;
    return result;
}

/*
 *-------------------------------------------------------------------------
 *
 * TableToUtfProc --
 *
 *	Convert from the encoding specified by the TableEncodingData into
 *	UTF-8.
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int 
TableToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
	srcReadPtr, dstWrotePtr, dstCharsPtr)
    ClientData clientData;	/* TableEncodingData that specifies
				 * encoding. */
    CONST char *src;		/* Source string in specified encoding. */
    int srcLen;			/* Source string length in bytes. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Place for conversion routine to store
				 * state information used during a piecewise
				 * conversion.  Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst;			/* Output buffer in which converted string
				 * is stored. */
    int dstLen;			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr;		/* Filled with the number of bytes from the
				 * source string that were converted.  This
				 * may be less than the original source length
				 * if there was a problem converting some
				 * source characters. */
    int *dstWrotePtr;		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr;		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    CONST char *srcStart, *srcEnd;
    char *dstEnd, *dstStart, *prefixBytes;
    int result, byte, numChars;
    Tcl_UniChar ch;
    unsigned short **toUnicode;
    unsigned short *pageZero;
    TableEncodingData *dataPtr;
    
    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
    dstEnd = dst + dstLen - TCL_UTF_MAX;

    dataPtr = (TableEncodingData *) clientData;
    toUnicode = dataPtr->toUnicode;
    prefixBytes = dataPtr->prefixBytes;
    pageZero = toUnicode[0];

    result = TCL_OK;
    for (numChars = 0; src < srcEnd; numChars++) {
        if (dst > dstEnd) {
            result = TCL_CONVERT_NOSPACE;
            break;
        }
	byte = *((unsigned char *) src);
	if (prefixBytes[byte]) {
	    src++;
	    if (src >= srcEnd) {
		src--;
		result = TCL_CONVERT_MULTIBYTE;
		break;
	    }
	    ch = toUnicode[byte][*((unsigned char *) src)];
	} else {
	    ch = pageZero[byte];
	}
	if ((ch == 0) && (byte != 0)) {
	    if (flags & TCL_ENCODING_STOPONERROR) {
		result = TCL_CONVERT_SYNTAX;
		break;
	    }
	    if (prefixBytes[byte]) {
		src--;
	    }
	    ch = (Tcl_UniChar) byte;
	}
	dst += Tcl_UniCharToUtf(ch, dst);
        src++;
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}

/*
 *-------------------------------------------------------------------------
 *
 * TableFromUtfProc --
 *
 *	Convert from UTF-8 into the encoding specified by the
 *	TableEncodingData.
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int 
TableFromUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
	srcReadPtr, dstWrotePtr, dstCharsPtr)
    ClientData clientData;	/* TableEncodingData that specifies
				 * encoding. */
    CONST char *src;		/* Source string in UTF-8. */
    int srcLen;			/* Source string length in bytes. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Place for conversion routine to store
				 * state information used during a piecewise
				 * conversion.  Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst;			/* Output buffer in which converted string
				 * is stored. */
    int dstLen;			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr;		/* Filled with the number of bytes from the
				 * source string that were converted.  This
				 * may be less than the original source length
				 * if there was a problem converting some
				 * source characters. */
    int *dstWrotePtr;		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr;		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    CONST char *srcStart, *srcEnd, *srcClose;
    char *dstStart, *dstEnd, *prefixBytes;
    Tcl_UniChar ch;
    int result, len, word, numChars;
    TableEncodingData *dataPtr;
    unsigned short **fromUnicode;
    
    result = TCL_OK;    

    dataPtr = (TableEncodingData *) clientData;
    prefixBytes = dataPtr->prefixBytes;
    fromUnicode = dataPtr->fromUnicode;
    
    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    if ((flags & TCL_ENCODING_END) == 0) {
	srcClose -= TCL_UTF_MAX;
    }

    dstStart = dst;
    dstEnd = dst + dstLen - 1;

    for (numChars = 0; src < srcEnd; numChars++) {
	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */

	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
        len = Tcl_UtfToUniChar(src, &ch);
	word = fromUnicode[(ch >> 8)][ch & 0xff];
	if ((word == 0) && (ch != 0)) {
	    if (flags & TCL_ENCODING_STOPONERROR) {
		result = TCL_CONVERT_UNKNOWN;
		break;
	    }
	    word = dataPtr->fallback; 
	}
	if (prefixBytes[(word >> 8)] != 0) {
	    if (dst + 1 > dstEnd) {
		result = TCL_CONVERT_NOSPACE;
		break;
	    }
	    dst[0] = (char) (word >> 8);
	    dst[1] = (char) word;
	    dst += 2;
	} else {
	    if (dst > dstEnd) {
		result = TCL_CONVERT_NOSPACE;
		break;
	    }
	    dst[0] = (char) word;
	    dst++;
	} 
	src += len;
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TableFreeProc --
 *
 *	This procedure is invoked when an encoding is deleted.  It deletes
 *	the memory used by the TableEncodingData.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory freed.
 *
 *---------------------------------------------------------------------------
 */

static void
TableFreeProc(clientData)
    ClientData clientData;	/* TableEncodingData that specifies
				 * encoding. */
{
    TableEncodingData *dataPtr;

    dataPtr = (TableEncodingData *) clientData;
    ckfree((char *) dataPtr->toUnicode);
    ckfree((char *) dataPtr->fromUnicode);
    ckfree((char *) dataPtr);
}

/*
 *-------------------------------------------------------------------------
 *
 * EscapeToUtfProc --
 *
 *	Convert from the encoding specified by the EscapeEncodingData into
 *	UTF-8.
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int 
EscapeToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
	srcReadPtr, dstWrotePtr, dstCharsPtr)
    ClientData clientData;	/* EscapeEncodingData that specifies
				 * encoding. */
    CONST char *src;		/* Source string in specified encoding. */
    int srcLen;			/* Source string length in bytes. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Place for conversion routine to store
				 * state information used during a piecewise
				 * conversion.  Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst;			/* Output buffer in which converted string
				 * is stored. */
    int dstLen;			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr;		/* Filled with the number of bytes from the
				 * source string that were converted.  This
				 * may be less than the original source length
				 * if there was a problem converting some
				 * source characters. */
    int *dstWrotePtr;		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr;		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    EscapeEncodingData *dataPtr;
    char *prefixBytes, *tablePrefixBytes;
    unsigned short **tableToUnicode;
    Encoding *encodingPtr;
    int state, result, numChars;
    CONST char *srcStart, *srcEnd;
    char *dstStart, *dstEnd;

    result = TCL_OK;

    tablePrefixBytes = NULL;	/* lint. */
    tableToUnicode = NULL;	/* lint. */

    dataPtr = (EscapeEncodingData *) clientData;
    prefixBytes = dataPtr->prefixBytes;
    encodingPtr = NULL;

    srcStart = src;
    srcEnd = src + srcLen;

    dstStart = dst;
    dstEnd = dst + dstLen - TCL_UTF_MAX;

    state = (int) *statePtr;
    if (flags & TCL_ENCODING_START) {
	state = 0;
    }

    for (numChars = 0; src < srcEnd; ) {
	int byte, hi, lo, ch;

        if (dst > dstEnd) {
            result = TCL_CONVERT_NOSPACE;
            break;
        }
	byte = *((unsigned char *) src);
	if (prefixBytes[byte]) {
	    unsigned int left, len, longest;
	    int checked, i;
	    EscapeSubTable *subTablePtr;
	    
	    /*
	     * Saw the beginning of an escape sequence. 
	     */
	     
	    left = srcEnd - src;
	    len = dataPtr->initLen;
	    longest = len;
	    checked = 0;
	    if (len <= left) {
		checked++;
		if ((len > 0) && 
			(memcmp(src, dataPtr->init, len) == 0)) {
		    /*
		     * If we see initialization string, skip it, even if we're
		     * not at the beginning of the buffer. 
		     */
		     
		    src += len;
		    continue;
		}
	    }
	    len = dataPtr->finalLen;
	    if (len > longest) {
		longest = len;
	    }
	    if (len <= left) {
		checked++;
		if ((len > 0) && 
			(memcmp(src, dataPtr->final, len) == 0)) {
		    /*
		     * If we see finalization string, skip it, even if we're
		     * not at the end of the buffer. 
		     */
		     
		    src += len;
		    continue;
		}
	    }
	    subTablePtr = dataPtr->subTables;
	    for (i = 0; i < dataPtr->numSubTables; i++) {
		len = subTablePtr->sequenceLen;
		if (len > longest) {
		    longest = len;
		}
		if (len <= left) {
		    checked++;
		    if ((len > 0) && 
			    (memcmp(src, subTablePtr->sequence, len) == 0)) {
			state = i;
			encodingPtr = NULL;
			subTablePtr = NULL;
			src += len;
			break;
		    }
		}
		subTablePtr++;
	    }
	    if (subTablePtr == NULL) {
		/*
		 * A match was found, the escape sequence was consumed, and
		 * the state was updated.
		 */

		continue;
	    }

	    /*
	     * We have a split-up or unrecognized escape sequence.  If we
	     * checked all the sequences, then it's a syntax error,
	     * otherwise we need more bytes to determine a match.
	     */

	    if ((checked == dataPtr->numSubTables + 2)
		    || (flags & TCL_ENCODING_END)) {
		if ((flags & TCL_ENCODING_STOPONERROR) == 0) {
		    /*
		     * Skip the unknown escape sequence.
		     */

		    src += longest;
		    continue;
		}
		result = TCL_CONVERT_SYNTAX;
	    } else {
		result = TCL_CONVERT_MULTIBYTE;
	    }
	    break;
	}

	if (encodingPtr == NULL) {
	    TableEncodingData *tableDataPtr;

	    encodingPtr = GetTableEncoding(dataPtr, state);
	    tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
	    tablePrefixBytes = tableDataPtr->prefixBytes;
	    tableToUnicode = tableDataPtr->toUnicode;
	}
	if (tablePrefixBytes[byte]) {
	    src++;
	    if (src >= srcEnd) {
		src--;
		result = TCL_CONVERT_MULTIBYTE;
		break;
	    }
	    hi = byte;
	    lo = *((unsigned char *) src);
	} else {
	    hi = 0;
	    lo = byte;
	}
	ch = tableToUnicode[hi][lo];
	dst += Tcl_UniCharToUtf(ch, dst);
	src++;
	numChars++;
    }

    *statePtr = (Tcl_EncodingState) state;
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}

/*
 *-------------------------------------------------------------------------
 *
 * EscapeFromUtfProc --
 *
 *	Convert from UTF-8 into the encoding specified by the
 *	EscapeEncodingData.
 *
 * Results:
 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static int 
EscapeFromUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
	srcReadPtr, dstWrotePtr, dstCharsPtr)
    ClientData clientData;	/* EscapeEncodingData that specifies
				 * encoding. */
    CONST char *src;		/* Source string in UTF-8. */
    int srcLen;			/* Source string length in bytes. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Place for conversion routine to store
				 * state information used during a piecewise
				 * conversion.  Contents of statePtr are
				 * initialized and/or reset by conversion
				 * routine under control of flags argument. */
    char *dst;			/* Output buffer in which converted string
				 * is stored. */
    int dstLen;			/* The maximum length of output buffer in
				 * bytes. */
    int *srcReadPtr;		/* Filled with the number of bytes from the
				 * source string that were converted.  This
				 * may be less than the original source length
				 * if there was a problem converting some
				 * source characters. */
    int *dstWrotePtr;		/* Filled with the number of bytes that were
				 * stored in the output buffer as a result of
				 * the conversion. */
    int *dstCharsPtr;		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    EscapeEncodingData *dataPtr;
    Encoding *encodingPtr;
    CONST char *srcStart, *srcEnd, *srcClose;
    char *dstStart, *dstEnd;
    int state, result, numChars;
    TableEncodingData *tableDataPtr;
    char *tablePrefixBytes;
    unsigned short **tableFromUnicode;
    
    result = TCL_OK;    

    dataPtr = (EscapeEncodingData *) clientData;

    srcStart = src;
    srcEnd = src + srcLen;
    srcClose = srcEnd;
    if ((flags & TCL_ENCODING_END) == 0) {
	srcClose -= TCL_UTF_MAX;
    }

    dstStart = dst;
    dstEnd = dst + dstLen - 1;

    if (flags & TCL_ENCODING_START) {
	unsigned int len;
	
	state = 0;
	len = dataPtr->subTables[0].sequenceLen;
	if (dst + dataPtr->initLen + len > dstEnd) {
	    *srcReadPtr = 0;
	    *dstWrotePtr = 0;
	    return TCL_CONVERT_NOSPACE;
	}
	memcpy((VOID *) dst, (VOID *) dataPtr->init,
		(size_t) dataPtr->initLen);
	dst += dataPtr->initLen;
	memcpy((VOID *) dst, (VOID *) dataPtr->subTables[0].sequence,
		(size_t) len);
	dst += len;
    } else {
        state = (int) *statePtr;
    }

    encodingPtr = GetTableEncoding(dataPtr, state);
    tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
    tablePrefixBytes = tableDataPtr->prefixBytes;
    tableFromUnicode = tableDataPtr->fromUnicode;

    for (numChars = 0; src < srcEnd; numChars++) {
	unsigned int len;
	int word;
	Tcl_UniChar ch;
	
	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
	    /*
	     * If there is more string to follow, this will ensure that the
	     * last UTF-8 character in the source buffer hasn't been cut off.
	     */

	    result = TCL_CONVERT_MULTIBYTE;
	    break;
	}
        len = Tcl_UtfToUniChar(src, &ch);
	word = tableFromUnicode[(ch >> 8)][ch & 0xff];

	if ((word == 0) && (ch != 0)) {
	    int oldState;
	    EscapeSubTable *subTablePtr;
	    
	    oldState = state;
	    for (state = 0; state < dataPtr->numSubTables; state++) {
		encodingPtr = GetTableEncoding(dataPtr, state);
		tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
	    	word = tableDataPtr->fromUnicode[(ch >> 8)][ch & 0xff];
		if (word != 0) {
		    break;
		}
	    }

	    if (word == 0) {
		state = oldState;
		if (flags & TCL_ENCODING_STOPONERROR) {
		    result = TCL_CONVERT_UNKNOWN;
		    break;
		}
		encodingPtr = GetTableEncoding(dataPtr, state);
		tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
		word = tableDataPtr->fallback;
	    } 
	    
	    tablePrefixBytes = tableDataPtr->prefixBytes;
	    tableFromUnicode = tableDataPtr->fromUnicode;

	    subTablePtr = &dataPtr->subTables[state];
	    if (dst + subTablePtr->sequenceLen > dstEnd) {
		result = TCL_CONVERT_NOSPACE;
		break;
	    }
	    memcpy((VOID *) dst, (VOID *) subTablePtr->sequence,
		    (size_t) subTablePtr->sequenceLen);
	    dst += subTablePtr->sequenceLen;
	}

	if (tablePrefixBytes[(word >> 8)] != 0) {
	    if (dst + 1 > dstEnd) {
		result = TCL_CONVERT_NOSPACE;
		break;
	    }
	    dst[0] = (char) (word >> 8);
	    dst[1] = (char) word;
	    dst += 2;
	} else {
	    if (dst > dstEnd) {
		result = TCL_CONVERT_NOSPACE;
		break;
	    }
	    dst[0] = (char) word;
	    dst++;
	} 
	src += len;
    }

    if ((result == TCL_OK) && (flags & TCL_ENCODING_END)) {
	if (dst + dataPtr->finalLen > dstEnd) {
	    result = TCL_CONVERT_NOSPACE;
	} else {
	    memcpy((VOID *) dst, (VOID *) dataPtr->final,
		    (size_t) dataPtr->finalLen);
	    dst += dataPtr->finalLen;
	}
    }

    *statePtr = (Tcl_EncodingState) state;
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = numChars;
    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * EscapeFreeProc --
 *
 *	This procedure is invoked when an EscapeEncodingData encoding is 
 *	deleted.  It deletes the memory used by the encoding.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory freed.
 *
 *---------------------------------------------------------------------------
 */

static void
EscapeFreeProc(clientData)
    ClientData clientData;	/* EscapeEncodingData that specifies encoding. */
{
    EscapeEncodingData *dataPtr;
    EscapeSubTable *subTablePtr;
    int i;

    dataPtr = (EscapeEncodingData *) clientData;
    if (dataPtr == NULL) {
	return;
    }
    subTablePtr = dataPtr->subTables;
    for (i = 0; i < dataPtr->numSubTables; i++) {
	FreeEncoding((Tcl_Encoding) subTablePtr->encodingPtr);
	subTablePtr++;
    }
    ckfree((char *) dataPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * GetTableEncoding --
 *
 *	Helper function for the EscapeEncodingData conversions.  Gets the
 *	encoding (of type TextEncodingData) that represents the specified
 *	state.
 *
 * Results:
 *	The return value is the encoding.
 *
 * Side effects:
 *	If the encoding that represents the specified state has not
 *	already been used by this EscapeEncoding, it will be loaded
 *	and cached in the dataPtr.
 *
 *---------------------------------------------------------------------------
 */

static Encoding *
GetTableEncoding(dataPtr, state)
    EscapeEncodingData *dataPtr;/* Contains names of encodings. */
    int state;			/* Index in dataPtr of desired Encoding. */
{
    EscapeSubTable *subTablePtr;
    Encoding *encodingPtr;
    
    subTablePtr = &dataPtr->subTables[state];
    encodingPtr = subTablePtr->encodingPtr;
    if (encodingPtr == NULL) {
	encodingPtr = (Encoding *) Tcl_GetEncoding(NULL, subTablePtr->name);
	if ((encodingPtr == NULL) 
		|| (encodingPtr->toUtfProc != TableToUtfProc)) {
	    panic("EscapeToUtfProc: invalid sub table");
	}
	subTablePtr->encodingPtr = encodingPtr;
    }
    return encodingPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * unilen --
 *
 *	A helper function for the Tcl_ExternalToUtf functions.  This
 *	function is similar to strlen for double-byte characters: it
 *	returns the number of bytes in a 0x0000 terminated string.
 *
 * Results:
 *	As above.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static size_t
unilen(src)
    CONST char *src;
{
    unsigned short *p;

    p = (unsigned short *) src;
    while (*p != 0x0000) {
	p++;
    }
    return (char *) p - src;
}

	

Changes to generic/tclEnv.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
/* 
 * tclEnv.c --
 *
 *	Tcl support for environment variables, including a setenv
 *	procedure.  This file contains the generic portion of the
 *	environment module.  It is primarily responsible for keeping
 *	the "env" arrays in sync with the system environment variables.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclEnv.c 1.54 97/10/27 17:47:52
 */

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

/*
 * The structure below is used to keep track of all of the interpereters
 * for which we're managing the "env" array.  It's needed so that they
 * can all be updated whenever an environment variable is changed
 * anywhere.
 */

typedef struct EnvInterp {
    Tcl_Interp *interp;		/* Interpreter for which we're managing
				 * the env array. */
    struct EnvInterp *nextPtr;	/* Next in list of all such interpreters,
				 * or zero. */
} EnvInterp;

static EnvInterp *firstInterpPtr = NULL;
				/* First in list of all managed interpreters,
				 * or NULL if none. */

static int cacheSize = 0;	/* Number of env strings in environCache. */
static char **environCache = NULL;
				/* Array containing all of the environment
				 * strings that Tcl has allocated. */

#ifndef USE_PUTENV









|




|





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







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
/* 
 * tclEnv.c --
 *
 *	Tcl support for environment variables, including a setenv
 *	procedure.  This file contains the generic portion of the
 *	environment module.  It is primarily responsible for keeping
 *	the "env" arrays in sync with the system environment variables.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-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: tclEnv.c,v 1.1.2.7 1999/04/14 00:33:22 surles Exp $
 */

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







TCL_DECLARE_MUTEX(envMutex)	/* To serialize access to environ */











static int cacheSize = 0;	/* Number of env strings in environCache. */
static char **environCache = NULL;
				/* Array containing all of the environment
				 * strings that Tcl has allocated. */

#ifndef USE_PUTENV
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
/*
 * Declarations for local procedures defined in this file:
 */

static char *		EnvTraceProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, char *name1, char *name2,
			    int flags));
static int		FindVariable _ANSI_ARGS_((CONST char *name,
			    int *lengthPtr));
static void		ReplaceString _ANSI_ARGS_((CONST char *oldStr,
			    char *newStr));
void			TclSetEnv _ANSI_ARGS_((CONST char *name,
			    CONST char *value));
void			TclUnsetEnv _ANSI_ARGS_((CONST char *name));


/*
 *----------------------------------------------------------------------
 *
 * TclSetupEnv --
 *
 *	This procedure is invoked for an interpreter to make environment
 *	variables accessible from that interpreter via the "env"
 *	associative array.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The interpreter is added to a list of interpreters managed
 *	by us, so that its view of envariables can be kept consistent
 *	with the view in other interpreters.  If this is the first
 *	call to Tcl_SetupEnv, then additional initialization happens,
 *	such as copying the environment to dynamically-allocated space
 *	for ease of management.
 *
 *----------------------------------------------------------------------
 */

void
TclSetupEnv(interp)
    Tcl_Interp *interp;		/* Interpreter whose "env" array is to be
				 * managed. */
{
    EnvInterp *eiPtr;
    char *p, *p2;
    Tcl_DString ds;

    int i, sz;

#ifdef MAC_TCL
    if (environ == NULL) {
	environSize = TclMacCreateEnv();
    }
#endif

    /*
     * Next, initialize the DString we are going to use for copying
     * the names of the environment variables.
     */

    Tcl_DStringInit(&ds);
    
    /*


     * Next, add the interpreter to the list of those that we manage.
     */





    eiPtr = (EnvInterp *) ckalloc(sizeof(EnvInterp));
    eiPtr->interp = interp;
    eiPtr->nextPtr = firstInterpPtr;
    firstInterpPtr = eiPtr;

    /*
     * Store the environment variable values into the interpreter's
     * "env" array, and arrange for us to be notified on future
     * writes and unsets to that array.
     */

    (void) Tcl_UnsetVar2(interp, "env", (char *) NULL, TCL_GLOBAL_ONLY);
    for (i = 0; ; i++) {
	p = environ[i];
	if (p == NULL) {
	    break;

	}








	for (p2 = p; *p2 != '='; p2++) {
	    if (*p2 == 0) {
		/*
		 * This condition doesn't seem like it should ever happen,
		 * but it does seem to happen occasionally under some
		 * versions of Solaris; ignore the entry.
		 */

		goto nextEntry;
	    }




	}
        sz = p2 - p;
        Tcl_DStringSetLength(&ds, 0);
        Tcl_DStringAppend(&ds, p, sz);
	(void) Tcl_SetVar2(interp, "env", Tcl_DStringValue(&ds),
                p2+1, TCL_GLOBAL_ONLY);
	nextEntry:
	continue;
    }

    Tcl_TraceVar2(interp, "env", (char *) NULL,
	    TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,

	    EnvTraceProc, (ClientData) NULL);

    /*
     * Finally clean up the DString.
     */

    Tcl_DStringFree(&ds);
}

/*
 *----------------------------------------------------------------------
 *
 * TclSetEnv --
 *
 *	Set an environment variable, replacing an existing value
 *	or creating a new variable if there doesn't exist a variable
 *	by the given name.  This procedure is intended to be a
 *	stand-in for the  UNIX "setenv" procedure so that applications
 *	using that procedure will interface properly to Tcl.  To make
 *	it a stand-in, the Makefile must define "TclSetEnv" to "setenv".
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The environ array gets updated, as do all of the interpreters
 *	that we manage.
 *
 *----------------------------------------------------------------------
 */

void
TclSetEnv(name, value)
    CONST char *name;		/* Name of variable whose value is to be
				 * set. */
    CONST char *value;		/* New value for variable. */
{

    int index, length, nameLength;
    char *p, *oldValue;
    EnvInterp *eiPtr;

#ifdef MAC_TCL
    if (environ == NULL) {
	environSize = TclMacCreateEnv();
    }
#endif

    /*
     * Figure out where the entry is going to go.  If the name doesn't
     * already exist, enlarge the array if necessary to make room.  If
     * the name exists, free its old entry.
     */


    index = FindVariable(name, &length);

    if (index == -1) {
#ifndef USE_PUTENV
	if ((length+2) > environSize) {
	    char **newEnviron;

	    newEnviron = (char **) ckalloc((unsigned)
		    ((length+5) * sizeof(char *)));
	    memcpy((VOID *) newEnviron, (VOID *) environ,
		    length*sizeof(char *));
	    if (environSize != 0) {
		ckfree((char *) environ);
	    }
	    environ = newEnviron;
	    environSize = length+5;
	}
	index = length;
	environ[index+1] = NULL;
#endif
	oldValue = NULL;
	nameLength = strlen(name);
    } else {


	/*
	 * Compare the new value to the existing value.  If they're
	 * the same then quit immediately (e.g. don't rewrite the
	 * value or propagate it to other interpreters).  Otherwise,
	 * when there are N interpreters there will be N! propagations
	 * of the same value among the interpreters.
	 */


	if (strcmp(value, environ[index]+length+1) == 0) {


	    return;
	}


	oldValue = environ[index];
	nameLength = length;
    }
	

    /*
     * Create a new entry.


     */

    p = (char *) ckalloc((unsigned) (nameLength + strlen(value) + 2));
    strcpy(p, name);
    p[nameLength] = '=';
    strcpy(p+nameLength+1, value);





    /*
     * Update the system environment.
     */

#ifdef USE_PUTENV
    putenv(p);

#else






    environ[index] = p;
#endif

    /*


     * Replace the old value with the new value in the cache.
     */




    ReplaceString(oldValue, p);

    /*
     * Update all of the interpreters.
     */

    for (eiPtr= firstInterpPtr; eiPtr != NULL; eiPtr = eiPtr->nextPtr) {
	(void) Tcl_SetVar2(eiPtr->interp, "env", (char *) name,
		(char *) value, TCL_GLOBAL_ONLY);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PutEnv --
 *







<
<





>

















|











<
<
|
>
|

<
<
<
<
<
<

|
|
<
|
<
|
<
>
>
|

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

<
|


|
|

>
>
>
>

<
|
<
<
<
<
<

>

|
>
|
<
<
<
<
<
<


















|
<







|
|

>

|
<
<
<
<
<
<
<



|
|


>
|
>


|



|






|


|




>
>








>
|
>
>


>
>






|
>
>






>
>
|
>
>




<
|
>

>
>
>
>
>
>




>
>
|


>
>
>
|
|
<
<
<

<
<
<
<
|







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
/*
 * Declarations for local procedures defined in this file:
 */

static char *		EnvTraceProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, char *name1, char *name2,
			    int flags));


static void		ReplaceString _ANSI_ARGS_((CONST char *oldStr,
			    char *newStr));
void			TclSetEnv _ANSI_ARGS_((CONST char *name,
			    CONST char *value));
void			TclUnsetEnv _ANSI_ARGS_((CONST char *name));


/*
 *----------------------------------------------------------------------
 *
 * TclSetupEnv --
 *
 *	This procedure is invoked for an interpreter to make environment
 *	variables accessible from that interpreter via the "env"
 *	associative array.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The interpreter is added to a list of interpreters managed
 *	by us, so that its view of envariables can be kept consistent
 *	with the view in other interpreters.  If this is the first
 *	call to TclSetupEnv, then additional initialization happens,
 *	such as copying the environment to dynamically-allocated space
 *	for ease of management.
 *
 *----------------------------------------------------------------------
 */

void
TclSetupEnv(interp)
    Tcl_Interp *interp;		/* Interpreter whose "env" array is to be
				 * managed. */
{


    Tcl_DString envString;
    char *p1, *p2;
    int i;







    /*
     * Synchronize the values in the environ array with the contents
     * of the Tcl "env" variable.  To do this:

     *    1) Remove the trace that fires when the "env" var is unset.

     *    2) Unset the "env" variable.

     *    3) If there are no environ variables, create an empty "env"
     *       array.  Otherwise populate the array with current values.
     *    4) Add a trace that synchronizes the "env" array.
     */
    
    Tcl_UntraceVar2(interp, "env", (char *) NULL,
	    TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS |
	    TCL_TRACE_READS | TCL_TRACE_ARRAY,  EnvTraceProc,
	    (ClientData) NULL);




    






    Tcl_UnsetVar2(interp, "env", (char *) NULL, TCL_GLOBAL_ONLY); 
    

    if (environ[0] == NULL) {

	Tcl_Obj *varNamePtr;
	
	varNamePtr = Tcl_NewStringObj("env", -1);
	Tcl_IncrRefCount(varNamePtr);
	TclArraySet(interp, varNamePtr, NULL);	
	Tcl_DecrRefCount(varNamePtr);
    } else {
	Tcl_MutexLock(&envMutex);
	for (i = 0; environ[i] != NULL; i++) {
	    p1 = Tcl_ExternalToUtfDString(NULL, environ[i], -1, &envString);
	    p2 = strchr(p1, '=');
	    if (p2 == NULL) {
		/*

		 * This condition seem to happen occasionally under some
		 * versions of Solaris; ignore the entry.
		 */
		
		continue;
	    }
	    p2++;
	    p2[-1] = '\0';
	    Tcl_SetVar2(interp, "env", p1, p2, TCL_GLOBAL_ONLY);	
	    Tcl_DStringFree(&envString);
	}

	Tcl_MutexUnlock(&envMutex);





    }

    Tcl_TraceVar2(interp, "env", (char *) NULL,
	    TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS |
	    TCL_TRACE_READS | TCL_TRACE_ARRAY,  EnvTraceProc,
	    (ClientData) NULL);






}

/*
 *----------------------------------------------------------------------
 *
 * TclSetEnv --
 *
 *	Set an environment variable, replacing an existing value
 *	or creating a new variable if there doesn't exist a variable
 *	by the given name.  This procedure is intended to be a
 *	stand-in for the  UNIX "setenv" procedure so that applications
 *	using that procedure will interface properly to Tcl.  To make
 *	it a stand-in, the Makefile must define "TclSetEnv" to "setenv".
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The environ array gets updated.

 *
 *----------------------------------------------------------------------
 */

void
TclSetEnv(name, value)
    CONST char *name;		/* Name of variable whose value is to be
				 * set (UTF-8). */
    CONST char *value;		/* New value for variable (UTF-8). */
{
    Tcl_DString envString;
    int index, length, nameLength;
    char *p, *p2, *oldValue;








    /*
     * Figure out where the entry is going to go.  If the name doesn't
     * already exist, enlarge the array if necessary to make room.  If the
     * name exists, free its old entry.
     */

    Tcl_MutexLock(&envMutex);
    index = TclpFindVariable(name, &length);

    if (index == -1) {
#ifndef USE_PUTENV
	if ((length + 2) > environSize) {
	    char **newEnviron;

	    newEnviron = (char **) ckalloc((unsigned)
		    ((length + 5) * sizeof(char *)));
	    memcpy((VOID *) newEnviron, (VOID *) environ,
		    length*sizeof(char *));
	    if (environSize != 0) {
		ckfree((char *) environ);
	    }
	    environ = newEnviron;
	    environSize = length + 5;
	}
	index = length;
	environ[index + 1] = NULL;
#endif
	oldValue = NULL;
	nameLength = strlen(name);
    } else {
	char *env;

	/*
	 * Compare the new value to the existing value.  If they're
	 * the same then quit immediately (e.g. don't rewrite the
	 * value or propagate it to other interpreters).  Otherwise,
	 * when there are N interpreters there will be N! propagations
	 * of the same value among the interpreters.
	 */

	env = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envString);
	if (strcmp(value, (env + length + 1)) == 0) {
	    Tcl_DStringFree(&envString);
	    Tcl_MutexUnlock(&envMutex);
	    return;
	}
	Tcl_DStringFree(&envString);

	oldValue = environ[index];
	nameLength = length;
    }
	

    /*
     * Create a new entry.  Build a complete UTF string that contains
     * a "name=value" pattern.  Then convert the string to the native
     * encoding, and set the environ array value.
     */

    p = (char *) ckalloc((unsigned) (nameLength + strlen(value) + 2));
    strcpy(p, name);
    p[nameLength] = '=';
    strcpy(p+nameLength+1, value);
    p2 = Tcl_UtfToExternalDString(NULL, p, -1, &envString);
    ckfree(p);
    

#ifdef USE_PUTENV
    /*
     * Update the system environment.
     */


    putenv(p2);
    index = TclpFindVariable(name, &length);
#else
    /*
     * Copy the native string to heap memory.
     */
    
    p = (char *) ckalloc((unsigned) (strlen(p2) + 1));
    strcpy(p, p2);
    environ[index] = p;
#endif

    /*
     * Watch out for versions of putenv that copy the string (e.g. VC++).
     * In this case we need to free the string immediately.  Otherwise
     * update the string in the cache.
     */

    if (environ[index] != p) {
	Tcl_DStringFree(&envString);
    } else {
	ReplaceString(oldValue, p);
    }








    Tcl_MutexUnlock(&envMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PutEnv --
 *
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
 *
 *----------------------------------------------------------------------
 */

int
Tcl_PutEnv(string)
    CONST char *string;		/* Info about environment variable in the
				 * form NAME=value. */
{

    int nameLength;
    char *name, *value;

    if (string == NULL) {
	return 0;
    }

    /*

     * Separate the string into name and value parts, then call
     * TclSetEnv to do all of the real work.
     */


    value = strchr(string, '=');
    if (value == NULL) {
	return 0;
    }
    nameLength = value - string;
    if (nameLength == 0) {
	return 0;
    }
    name = (char *) ckalloc((unsigned) nameLength+1);
    memcpy((VOID *) name, (VOID *) string, (size_t) nameLength);
    name[nameLength] = 0;
    TclSetEnv(name, value+1);
    ckfree(name);
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TclUnsetEnv --







|

>








>
|
|


>
|



|



|
<
|

|







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

int
Tcl_PutEnv(string)
    CONST char *string;		/* Info about environment variable in the
				 * form NAME=value. (native) */
{
    Tcl_DString nameString;   
    int nameLength;
    char *name, *value;

    if (string == NULL) {
	return 0;
    }

    /*
     * First convert the native string to UTF.  Then separate the
     * string into name and value parts, and call TclSetEnv to do
     * all of the real work.
     */

    name = Tcl_ExternalToUtfDString(NULL, string, -1, &nameString);
    value = strchr(name, '=');
    if (value == NULL) {
	return 0;
    }
    nameLength = value - name;
    if (nameLength == 0) {
	return 0;
    }


    value[0] = '\0';
    TclSetEnv(name, value+1);
    Tcl_DStringFree(&nameString);
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TclUnsetEnv --
353
354
355
356
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402




403










404

405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439



440
441
442
443
444
445
446
447
448
449




450
451

452
453


454

455
456
457
458
459
460
461



462
463
464




465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524



525
526
527
528
529
530
531
532
533
534
535


536

537
538




















539
540
541
542
543
544
545
 *	Interpreters are updated, as is environ.
 *
 *----------------------------------------------------------------------
 */

void
TclUnsetEnv(name)
    CONST char *name;			/* Name of variable to remove. */
{
    EnvInterp *eiPtr;
    char *oldValue;
    int length, index;
#ifdef USE_PUTENV

    char *string;
#else
    char **envPtr;
#endif

#ifdef MAC_TCL
    if (environ == NULL) {
	environSize = TclMacCreateEnv();
    }
#endif

    index = FindVariable(name, &length);

    /*
     * First make sure that the environment variable exists to avoid
     * doing needless work and to avoid recursion on the unset.
     */
    
    if (index == -1) {

	return;
    }
    /*
     * Remember the old value so we can free it if Tcl created the string.
     */

    oldValue = environ[index];

    /*
     * Update the system environment.  This must be done before we 
     * update the interpreters or we will recurse.
     */

#ifdef USE_PUTENV
    string = ckalloc(length+2);
    memcpy((VOID *) string, (VOID *) name, (size_t) length);
    string[length] = '=';
    string[length+1] = '\0';




    putenv(string);










    ckfree(string);

#else
    for (envPtr = environ+index+1; ; envPtr++) {
	envPtr[-1] = *envPtr;
	if (*envPtr == NULL) {
	    break;
	}
    }
#endif

    /*
     * Replace the old value in the cache.
     */

    ReplaceString(oldValue, NULL);

    /*
     * Update all of the interpreters.
     */

    for (eiPtr = firstInterpPtr; eiPtr != NULL; eiPtr = eiPtr->nextPtr) {
	(void) Tcl_UnsetVar2(eiPtr->interp, "env", (char *) name,
		TCL_GLOBAL_ONLY);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetEnv --
 *
 *	Retrieve the value of an environment variable.
 *
 * Results:
 *	Returns a pointer to a static string in the environment,
 *	or NULL if the value was not found.



 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclGetEnv(name)
    CONST char *name;		/* Name of variable to find. */




{
    int length, index;


#ifdef MAC_TCL


    if (environ == NULL) {

	environSize = TclMacCreateEnv();
    }
#endif

    index = FindVariable(name, &length);
    if ((index != -1) &&  (*(environ[index]+length) == '=')) {
	return environ[index]+length+1;



    } else {
	return NULL;
    }




}

/*
 *----------------------------------------------------------------------
 *
 * EnvTraceProc --
 *
 *	This procedure is invoked whenever an environment variable
 *	is modified or deleted.  It propagates the change to the
 *	"environ" array and to any other interpreters for whom
 *	we're managing an "env" array.
 *
 * Results:
 *	Always returns NULL to indicate success.
 *
 * Side effects:
 *	Environment variable changes get propagated.  If the whole
 *	"env" array is deleted, then we stop managing things for
 *	this interpreter (usually this happens because the whole
 *	interpreter is being deleted).
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static char *
EnvTraceProc(clientData, interp, name1, name2, flags)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Interpreter whose "env" variable is
				 * being modified. */
    char *name1;		/* Better be "env". */
    char *name2;		/* Name of variable being modified, or
				 * NULL if whole array is being deleted. */
    int flags;			/* Indicates what's happening. */
{
    /*
     * First see if the whole "env" variable is being deleted.  If
     * so, just forget about this interpreter.
     */

    if (name2 == NULL) {
	register EnvInterp *eiPtr, *prevPtr;

	if ((flags & (TCL_TRACE_UNSETS|TCL_TRACE_DESTROYED))
		!= (TCL_TRACE_UNSETS|TCL_TRACE_DESTROYED)) {
	    panic("EnvTraceProc called with confusing arguments");
	}
	eiPtr = firstInterpPtr;
	if (eiPtr->interp == interp) {
	    firstInterpPtr = eiPtr->nextPtr;
	} else {
	    for (prevPtr = eiPtr, eiPtr = eiPtr->nextPtr; ;
		    prevPtr = eiPtr, eiPtr = eiPtr->nextPtr) {
		if (eiPtr == NULL) {
		    panic("EnvTraceProc couldn't find interpreter");
		}
		if (eiPtr->interp == interp) {
		    prevPtr->nextPtr = eiPtr->nextPtr;
		    break;
		}



	    }
	}
	ckfree((char *) eiPtr);
	return NULL;
    }

    /*
     * If a value is being set, call TclSetEnv to do all of the work.
     */

    if (flags & TCL_TRACE_WRITES) {


	TclSetEnv(name2, Tcl_GetVar2(interp, "env", name2, TCL_GLOBAL_ONLY));

    }





















    if (flags & TCL_TRACE_UNSETS) {
	TclUnsetEnv(name2);
    }
    return NULL;
}

/*







|

<



>





<
<
<
<
<
|
|







>


















>
>
>
>

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







<
<
<
<
<
<

|
<
<
<

<
|
<
<



|






|
|
>
>
>








|
|
>
>
>
>


>

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








|
|
<




















|
|



|
<


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








>
>
|
>


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







336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353





354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405






406
407



408

409


410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

443
444
445
446
447
448

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498

499
500


501





502




503

504



505
506
507
508
509

510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
 *	Interpreters are updated, as is environ.
 *
 *----------------------------------------------------------------------
 */

void
TclUnsetEnv(name)
    CONST char *name;		/* Name of variable to remove (UTF-8). */
{

    char *oldValue;
    int length, index;
#ifdef USE_PUTENV
    Tcl_DString envString;
    char *string;
#else
    char **envPtr;
#endif






    Tcl_MutexLock(&envMutex);
    index = TclpFindVariable(name, &length);

    /*
     * First make sure that the environment variable exists to avoid
     * doing needless work and to avoid recursion on the unset.
     */
    
    if (index == -1) {
	Tcl_MutexUnlock(&envMutex);
	return;
    }
    /*
     * Remember the old value so we can free it if Tcl created the string.
     */

    oldValue = environ[index];

    /*
     * Update the system environment.  This must be done before we 
     * update the interpreters or we will recurse.
     */

#ifdef USE_PUTENV
    string = ckalloc(length+2);
    memcpy((VOID *) string, (VOID *) name, (size_t) length);
    string[length] = '=';
    string[length+1] = '\0';
    
    Tcl_UtfToExternalDString(NULL, string, -1, &envString);
    ckfree(string);
    string = Tcl_DStringValue(&envString);
    putenv(string);

    /*
     * Watch out for versions of putenv that copy the string (e.g. VC++).
     * In this case we need to free the string immediately.  Otherwise
     * update the string in the cache.
     */

    if (environ[index] != string) {
	Tcl_DStringFree(&envString);
    } else {
	ReplaceString(oldValue, string);
    }
#else
    for (envPtr = environ+index+1; ; envPtr++) {
	envPtr[-1] = *envPtr;
	if (*envPtr == NULL) {
	    break;
	}
    }






    ReplaceString(oldValue, NULL);
#endif





    Tcl_MutexUnlock(&envMutex);


}

/*
 *---------------------------------------------------------------------------
 *
 * TclGetEnv --
 *
 *	Retrieve the value of an environment variable.
 *
 * Results:
 *	The result is a pointer to a string specifying the value of the
 *	environment variable, or NULL if that environment variable does
 *	not exist.  Storage for the result string is allocated in valuePtr;
 *	the caller must call Tcl_DStringFree() when the result is no
 *	longer needed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclGetEnv(name, valuePtr)
    CONST char *name;		/* Name of environment variable to find
				 * (UTF-8). */
    Tcl_DString *valuePtr;	/* Uninitialized or free DString in which
				 * the value of the environment variable is
				 * stored. */
{
    int length, index;
    char *result;


    Tcl_MutexLock(&envMutex);
    index = TclpFindVariable(name, &length);
    result = NULL;
    if (index != -1) {
	Tcl_DString envStr;
	

	result = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envStr);
	result += length;
	if (*result == '=') {
	    result++;
	    Tcl_DStringInit(valuePtr);
	    Tcl_DStringAppend(valuePtr, result, -1);
	    result = Tcl_DStringValue(valuePtr);
	} else {
	    result = NULL;
	}
	Tcl_DStringFree(&envStr);
    }
    Tcl_MutexUnlock(&envMutex);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * EnvTraceProc --
 *
 *	This procedure is invoked whenever an environment variable
 *	is read, modified or deleted.  It propagates the change to the global
 *	"environ" array.

 *
 * Results:
 *	Always returns NULL to indicate success.
 *
 * Side effects:
 *	Environment variable changes get propagated.  If the whole
 *	"env" array is deleted, then we stop managing things for
 *	this interpreter (usually this happens because the whole
 *	interpreter is being deleted).
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static char *
EnvTraceProc(clientData, interp, name1, name2, flags)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Interpreter whose "env" variable is
				 * being modified. */
    char *name1;		/* Better be "env". */
    char *name2;		/* Name of variable being modified, or NULL
				 * if whole array is being deleted (UTF-8). */
    int flags;			/* Indicates what's happening. */
{
    /*
     * For array traces, let TclSetupEnv do all the work.

     */



    if (flags & TCL_TRACE_ARRAY) {





	TclSetupEnv(interp);




	return NULL;

    }




    /*
     * If name2 is NULL, then return and do nothing.
     */
     

    if (name2 == NULL) {
	return NULL;
    }

    /*
     * If a value is being set, call TclSetEnv to do all of the work.
     */

    if (flags & TCL_TRACE_WRITES) {
	char *value;
	
	value = Tcl_GetVar2(interp, "env", name2, TCL_GLOBAL_ONLY);
	TclSetEnv(name2, value);
    }

    /*
     * If a value is being read, call TclGetEnv to do all of the work.
     */

    if (flags & TCL_TRACE_READS) {
	Tcl_DString valueString;
	char *value;

	value = TclGetEnv(name2, &valueString);
	if (value == NULL) {
	    return "no such variable";
	}
	Tcl_SetVar2(interp, name1, name2, value, 0);
	Tcl_DStringFree(&valueString);
    }

    /*
     * For unset traces, let TclUnsetEnv do all the work.
     */

    if (flags & TCL_TRACE_UNSETS) {
	TclUnsetEnv(name2);
    }
    return NULL;
}

/*
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
    } else {	
        int allocatedSize = (cacheSize + 5) * sizeof(char *);

	/*
	 * We need to grow the cache in order to hold the new string.
	 */

	newCache = (char **) ckalloc((size_t) allocatedSize);
        (VOID *) memset(newCache, (int) 0, (size_t) allocatedSize);
        
	if (environCache) {
	    memcpy((VOID *) newCache, (VOID *) environCache,
		    (size_t) (cacheSize * sizeof(char*)));
	    ckfree((char *) environCache);
	}
	environCache = newCache;
	environCache[cacheSize] = (char *) newStr;
	environCache[cacheSize+1] = NULL;
	cacheSize += 5;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FindVariable --
 *
 *	Locate the entry in environ for a given name.
 *
 * Results:
 *	The return value is the index in environ of an entry with the
 *	name "name", or -1 if there is no such entry.   The integer at
 *	*lengthPtr is filled in with the length of name (if a matching
 *	entry is found) or the length of the environ array (if no matching
 *	entry is found).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
FindVariable(name, lengthPtr)
    CONST char *name;		/* Name of desired environment variable. */
    int *lengthPtr;		/* Used to return length of name (for
				 * successful searches) or number of non-NULL
				 * entries in environ (for unsuccessful
				 * searches). */
{
    int i;
    register CONST char *p1, *p2;

    for (i = 0, p1 = environ[i]; p1 != NULL; i++, p1 = environ[i]) {
	for (p2 = name; *p2 == *p1; p1++, p2++) {
	    /* NULL loop body. */
	}
	if ((*p1 == '=') && (*p2 == '\0')) {
	    *lengthPtr = p2-name;
	    return i;
	}
    }
    *lengthPtr = i;
    return -1;
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeEnvironment --
 *
 *	This function releases any storage allocated by this module







|













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







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
    } else {	
        int allocatedSize = (cacheSize + 5) * sizeof(char *);

	/*
	 * We need to grow the cache in order to hold the new string.
	 */

	newCache = (char **) ckalloc((unsigned) allocatedSize);
        (VOID *) memset(newCache, (int) 0, (size_t) allocatedSize);
        
	if (environCache) {
	    memcpy((VOID *) newCache, (VOID *) environCache,
		    (size_t) (cacheSize * sizeof(char*)));
	    ckfree((char *) environCache);
	}
	environCache = newCache;
	environCache[cacheSize] = (char *) newStr;
	environCache[cacheSize+1] = NULL;
	cacheSize += 5;
    }
}













































/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeEnvironment --
 *
 *	This function releases any storage allocated by this module
697
698
699
700
701
702
703




	environCache = NULL;
	cacheSize    = 0;
#ifndef USE_PUTENV
	environSize  = 0;
#endif
    }
}











>
>
>
>
659
660
661
662
663
664
665
666
667
668
669
	environCache = NULL;
	cacheSize    = 0;
#ifndef USE_PUTENV
	environSize  = 0;
#endif
    }
}

	
    
    

Changes to generic/tclEvent.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
/* 
 * tclEvent.c --
 *
 *	This file implements some general event related interfaces including
 *	background errors, exit handlers, and the "vwait" and "update"
 *	command procedures. 
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclEvent.c 1.153 97/08/11 20:22:31
 */

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

/*
 * The data structure below is used to report background errors.  One
 * such structure is allocated for each error;  it holds information
 * about the interpreter and the error until bgerror can be invoked
 * later as an idle handler.
 */

typedef struct BgError {
    Tcl_Interp *interp;		/* Interpreter in which error occurred.  NULL
				 * means this error report has been cancelled
				 * (a previous report generated a break). */
    char *errorMsg;		/* The error message (interp->result when
				 * the error occurred).  Malloc-ed. */

    char *errorInfo;		/* Value of the errorInfo variable
				 * (malloc-ed). */
    char *errorCode;		/* Value of the errorCode variable
				 * (malloc-ed). */
    struct BgError *nextPtr;	/* Next in list of all pending error
				 * reports for this interpreter, or NULL
				 * for end of list. */








|




|
















|
|
>







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
/* 
 * tclEvent.c --
 *
 *	This file implements some general event related interfaces including
 *	background errors, exit handlers, and the "vwait" and "update"
 *	command procedures. 
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-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: tclEvent.c,v 1.1.2.10 1999/04/03 01:35:19 welch Exp $
 */

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

/*
 * The data structure below is used to report background errors.  One
 * such structure is allocated for each error;  it holds information
 * about the interpreter and the error until bgerror can be invoked
 * later as an idle handler.
 */

typedef struct BgError {
    Tcl_Interp *interp;		/* Interpreter in which error occurred.  NULL
				 * means this error report has been cancelled
				 * (a previous report generated a break). */
    char *errorMsg;		/* Copy of the error message (the interp's
				 * result when the error occurred).
				 * Malloc-ed. */
    char *errorInfo;		/* Value of the errorInfo variable
				 * (malloc-ed). */
    char *errorCode;		/* Value of the errorCode variable
				 * (malloc-ed). */
    struct BgError *nextPtr;	/* Next in list of all pending error
				 * reports for this interpreter, or NULL
				 * for end of list. */
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
typedef struct ExitHandler {
    Tcl_ExitProc *proc;		/* Procedure to call when process exits. */
    ClientData clientData;	/* One word of information to pass to proc. */
    struct ExitHandler *nextPtr;/* Next in list of all exit handlers for
				 * this application, or NULL for end of list. */
} ExitHandler;







static ExitHandler *firstExitPtr = NULL;
				/* First in list of all exit handlers for
				 * application. */

/*
 * The following variable is a "secret" indication to Tcl_Exit that
 * it should dump out the state of memory before exiting.  If the
 * value is non-NULL, it gives the name of the file in which to
 * dump memory usage information.
 */

char *tclMemDumpFileName = NULL;

/*
 * This variable is set to 1 when Tcl_Exit is called, and at the end of
 * its work, it is reset to 0. The variable is checked by TclInExit() to
 * allow different behavior for exit-time processing, e.g. in closing of
 * files and pipes.
 */

static int tclInExit = 0;














/*
 * Prototypes for procedures referenced only in this file:
 */

static void		BgErrorDeleteProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp));







>
>
>
>
>
>



|
<
<
<
<
<
<

<
<

|





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







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
typedef struct ExitHandler {
    Tcl_ExitProc *proc;		/* Procedure to call when process exits. */
    ClientData clientData;	/* One word of information to pass to proc. */
    struct ExitHandler *nextPtr;/* Next in list of all exit handlers for
				 * this application, or NULL for end of list. */
} ExitHandler;

/*
 * There is both per-process and per-thread exit handlers.
 * The first list is controlled by a mutex.  The other is in
 * thread local storage.
 */

static ExitHandler *firstExitPtr = NULL;
				/* First in list of all exit handlers for
				 * application. */
TCL_DECLARE_MUTEX(exitMutex)









/*
 * This variable is set to 1 when Tcl_Finalize is called, and at the end of
 * its work, it is reset to 0. The variable is checked by TclInExit() to
 * allow different behavior for exit-time processing, e.g. in closing of
 * files and pipes.
 */

static int inFinalize = 0;
static int subsystemsInitialized = 0;
static int encodingsInitialized  = 0;

static Tcl_Obj *tclLibraryPath = NULL;

typedef struct ThreadSpecificData {
    ExitHandler *firstExitPtr;  /* First in list of all exit handlers for
				 * this thread. */
    int inExit;			/* True when this thread is exiting. This
				 * is used as a hack to decide to close
				 * the standard channels. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for procedures referenced only in this file:
 */

static void		BgErrorDeleteProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp));
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
Tcl_BackgroundError(interp)
    Tcl_Interp *interp;		/* Interpreter in which an error has
				 * occurred. */
{
    BgError *errPtr;
    char *errResult, *varValue;
    ErrAssocData *assocPtr;


    /*
     * The Tcl_AddErrorInfo call below (with an empty string) ensures that
     * errorInfo gets properly set.  It's needed in cases where the error
     * came from a utility procedure like Tcl_GetVar instead of Tcl_Eval;
     * in these cases errorInfo still won't have been set when this
     * procedure is called.
     */

    Tcl_AddErrorInfo(interp, "");

    errResult = TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL);
	
    errPtr = (BgError *) ckalloc(sizeof(BgError));
    errPtr->interp = interp;
    errPtr->errorMsg = (char *) ckalloc((unsigned) (strlen(errResult) + 1));
    strcpy(errPtr->errorMsg, errResult);
    varValue = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
    if (varValue == NULL) {
	varValue = errPtr->errorMsg;
    }
    errPtr->errorInfo = (char *) ckalloc((unsigned) (strlen(varValue) + 1));
    strcpy(errPtr->errorInfo, varValue);
    varValue = Tcl_GetVar(interp, "errorCode", TCL_GLOBAL_ONLY);







>











|



|
|







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
Tcl_BackgroundError(interp)
    Tcl_Interp *interp;		/* Interpreter in which an error has
				 * occurred. */
{
    BgError *errPtr;
    char *errResult, *varValue;
    ErrAssocData *assocPtr;
    int length;

    /*
     * The Tcl_AddErrorInfo call below (with an empty string) ensures that
     * errorInfo gets properly set.  It's needed in cases where the error
     * came from a utility procedure like Tcl_GetVar instead of Tcl_Eval;
     * in these cases errorInfo still won't have been set when this
     * procedure is called.
     */

    Tcl_AddErrorInfo(interp, "");

    errResult = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &length);
	
    errPtr = (BgError *) ckalloc(sizeof(BgError));
    errPtr->interp = interp;
    errPtr->errorMsg = (char *) ckalloc((unsigned) (length + 1));
    memcpy(errPtr->errorMsg, errResult, (size_t) (length + 1));
    varValue = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
    if (varValue == NULL) {
	varValue = errPtr->errorMsg;
    }
    errPtr->errorInfo = (char *) ckalloc((unsigned) (strlen(varValue) + 1));
    strcpy(errPtr->errorInfo, varValue);
    varValue = Tcl_GetVar(interp, "errorCode", TCL_GLOBAL_ONLY);
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
 */

static void
HandleBgErrors(clientData)
    ClientData clientData;	/* Pointer to ErrAssocData structure. */
{
    Tcl_Interp *interp;
    char *command;
    char *argv[2];
    int code;
    BgError *errPtr;
    ErrAssocData *assocPtr = (ErrAssocData *) clientData;
    Tcl_Channel errChannel;

    Tcl_Preserve((ClientData) assocPtr);







<







215
216
217
218
219
220
221

222
223
224
225
226
227
228
 */

static void
HandleBgErrors(clientData)
    ClientData clientData;	/* Pointer to ErrAssocData structure. */
{
    Tcl_Interp *interp;

    char *argv[2];
    int code;
    BgError *errPtr;
    ErrAssocData *assocPtr = (ErrAssocData *) clientData;
    Tcl_Channel errChannel;

    Tcl_Preserve((ClientData) assocPtr);
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
291
292


293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

	/*
	 * Create and invoke the bgerror command.
	 */

	argv[0] = "bgerror";
	argv[1] = assocPtr->firstBgPtr->errorMsg;
	command = Tcl_Merge(2, argv);
	Tcl_AllowExceptions(interp);
        Tcl_Preserve((ClientData) interp);
	code = Tcl_GlobalEval(interp, command);
	ckfree(command);
	if (code == TCL_ERROR) {

            /*
             * If the interpreter is safe, we look for a hidden command
             * named "bgerror" and call that with the error information.
             * Otherwise, simply ignore the error. The rationale is that
             * this could be an error caused by a malicious applet trying
             * to cause an infinite barrage of error messages. The hidden
             * "bgerror" command can be used by a security policy to
             * interpose on such attacks and e.g. kill the applet after a
             * few attempts.
             */

            if (Tcl_IsSafe(interp)) {
                Tcl_HashTable *hTblPtr;
                Tcl_HashEntry *hPtr;

                hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp,
                        "tclHiddenCmds", NULL);
                if (hTblPtr == (Tcl_HashTable *) NULL) {
                    goto doneWithInterp;
                }
                hPtr = Tcl_FindHashEntry(hTblPtr, "bgerror");
                if (hPtr == (Tcl_HashEntry *) NULL) {
                    goto doneWithInterp;
                }

                /*
                 * OK, the hidden command "bgerror" exists, invoke it.
                 */

                argv[0] = "bgerror";
                argv[1] = ckalloc((unsigned)
                        strlen(assocPtr->firstBgPtr->errorMsg));
                strcpy(argv[1], assocPtr->firstBgPtr->errorMsg);
                (void) TclInvoke(interp, 2, argv, TCL_INVOKE_HIDDEN);
                ckfree(argv[1]);


                goto doneWithInterp;
            } 

            /*
             * We have to get the error output channel at the latest possible
             * time, because the eval (above) might have changed the channel.
             */
            
            errChannel = Tcl_GetStdChannel(TCL_STDERR);
            if (errChannel != (Tcl_Channel) NULL) {


                if (strcmp(interp->result,

           "\"bgerror\" is an invalid command name or ambiguous abbreviation")
                        == 0) {
                    Tcl_Write(errChannel, assocPtr->firstBgPtr->errorInfo, -1);
                    Tcl_Write(errChannel, "\n", -1);
                } else {
                    Tcl_Write(errChannel,
                            "bgerror failed to handle background error.\n",
                            -1);
                    Tcl_Write(errChannel, "    Original error: ", -1);
                    Tcl_Write(errChannel, assocPtr->firstBgPtr->errorMsg,
                            -1);
                    Tcl_Write(errChannel, "\n", -1);
                    Tcl_Write(errChannel, "    Error in bgerror: ", -1);
                    Tcl_Write(errChannel, interp->result, -1);
                    Tcl_Write(errChannel, "\n", -1);
                }
                Tcl_Flush(errChannel);
            }
	} else if (code == TCL_BREAK) {

	    /*
	     * Break means cancel any remaining error reports for this







|


|
<














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











>
>
|
>
|
<
|
|

|


|
|

|
|
|
|







245
246
247
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265
266
267
268
269


270




271




272








273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

	/*
	 * Create and invoke the bgerror command.
	 */

	argv[0] = "bgerror";
	argv[1] = assocPtr->firstBgPtr->errorMsg;
	
	Tcl_AllowExceptions(interp);
        Tcl_Preserve((ClientData) interp);
	code = TclGlobalInvoke(interp, 2, argv, 0);

	if (code == TCL_ERROR) {

            /*
             * If the interpreter is safe, we look for a hidden command
             * named "bgerror" and call that with the error information.
             * Otherwise, simply ignore the error. The rationale is that
             * this could be an error caused by a malicious applet trying
             * to cause an infinite barrage of error messages. The hidden
             * "bgerror" command can be used by a security policy to
             * interpose on such attacks and e.g. kill the applet after a
             * few attempts.
             */

            if (Tcl_IsSafe(interp)) {


		Tcl_SavedResult save;




		




		Tcl_SaveResult(interp, &save);








                TclGlobalInvoke(interp, 2, argv, TCL_INVOKE_HIDDEN);

		Tcl_RestoreResult(interp, &save);

                goto doneWithInterp;
            } 

            /*
             * We have to get the error output channel at the latest possible
             * time, because the eval (above) might have changed the channel.
             */
            
            errChannel = Tcl_GetStdChannel(TCL_STDERR);
            if (errChannel != (Tcl_Channel) NULL) {
		char *string;
		int len;

		string = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &len);
                if (strcmp(string, "\"bgerror\" is an invalid command name or ambiguous abbreviation") == 0) {

                    Tcl_WriteChars(errChannel, assocPtr->firstBgPtr->errorInfo, -1);
                    Tcl_WriteChars(errChannel, "\n", -1);
                } else {
                    Tcl_WriteChars(errChannel,
                            "bgerror failed to handle background error.\n",
                            -1);
                    Tcl_WriteChars(errChannel, "    Original error: ", -1);
                    Tcl_WriteChars(errChannel, assocPtr->firstBgPtr->errorMsg,
                            -1);
                    Tcl_WriteChars(errChannel, "\n", -1);
                    Tcl_WriteChars(errChannel, "    Error in bgerror: ", -1);
                    Tcl_WriteChars(errChannel, string, len);
                    Tcl_WriteChars(errChannel, "\n", -1);
                }
                Tcl_Flush(errChannel);
            }
	} else if (code == TCL_BREAK) {

	    /*
	     * Break means cancel any remaining error reports for this
412
413
414
415
416
417
418

419
420

421
422
423
424
425
426
427
    ClientData clientData;	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr;

    exitPtr = (ExitHandler *) ckalloc(sizeof(ExitHandler));
    exitPtr->proc = proc;
    exitPtr->clientData = clientData;

    exitPtr->nextPtr = firstExitPtr;
    firstExitPtr = exitPtr;

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DeleteExitHandler --
 *







>


>







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
    ClientData clientData;	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr;

    exitPtr = (ExitHandler *) ckalloc(sizeof(ExitHandler));
    exitPtr->proc = proc;
    exitPtr->clientData = clientData;
    Tcl_MutexLock(&exitMutex);
    exitPtr->nextPtr = firstExitPtr;
    firstExitPtr = exitPtr;
    Tcl_MutexUnlock(&exitMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DeleteExitHandler --
 *
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456
457












































































458
459
460
461
462
463
464
void
Tcl_DeleteExitHandler(proc, clientData)
    Tcl_ExitProc *proc;		/* Procedure that was previously registered. */
    ClientData clientData;	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr, *prevPtr;


    for (prevPtr = NULL, exitPtr = firstExitPtr; exitPtr != NULL;
	    prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
	if ((exitPtr->proc == proc)
		&& (exitPtr->clientData == clientData)) {
	    if (prevPtr == NULL) {
		firstExitPtr = exitPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = exitPtr->nextPtr;
	    }












































































	    ckfree((char *) exitPtr);
	    return;
	}
    }
}

/*







>









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







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
void
Tcl_DeleteExitHandler(proc, clientData)
    Tcl_ExitProc *proc;		/* Procedure that was previously registered. */
    ClientData clientData;	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr, *prevPtr;

    Tcl_MutexLock(&exitMutex);
    for (prevPtr = NULL, exitPtr = firstExitPtr; exitPtr != NULL;
	    prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
	if ((exitPtr->proc == proc)
		&& (exitPtr->clientData == clientData)) {
	    if (prevPtr == NULL) {
		firstExitPtr = exitPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = exitPtr->nextPtr;
	    }
	    Tcl_MutexUnlock(&exitMutex);
	    ckfree((char *) exitPtr);
	    return;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateThreadExitHandler --
 *
 *	Arrange for a given procedure to be invoked just before the
 *	current thread exits.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Proc will be invoked with clientData as argument when the
 *	application exits.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_CreateThreadExitHandler(proc, clientData)
    Tcl_ExitProc *proc;		/* Procedure to invoke. */
    ClientData clientData;	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    exitPtr = (ExitHandler *) ckalloc(sizeof(ExitHandler));
    exitPtr->proc = proc;
    exitPtr->clientData = clientData;
    exitPtr->nextPtr = tsdPtr->firstExitPtr;
    tsdPtr->firstExitPtr = exitPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DeleteThreadExitHandler --
 *
 *	This procedure cancels an existing exit handler matching proc
 *	and clientData, if such a handler exits.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If there is an exit handler corresponding to proc and clientData
 *	then it is cancelled;  if no such handler exists then nothing
 *	happens.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DeleteThreadExitHandler(proc, clientData)
    Tcl_ExitProc *proc;		/* Procedure that was previously registered. */
    ClientData clientData;	/* Arbitrary value to pass to proc. */
{
    ExitHandler *exitPtr, *prevPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    for (prevPtr = NULL, exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;
	    prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
	if ((exitPtr->proc == proc)
		&& (exitPtr->clientData == clientData)) {
	    if (prevPtr == NULL) {
		tsdPtr->firstExitPtr = exitPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = exitPtr->nextPtr;
	    }
	    ckfree((char *) exitPtr);
	    return;
	}
    }
}

/*
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

void
Tcl_Exit(status)
    int status;			/* Exit status for application;  typically
				 * 0 for normal return, 1 for error return. */
{
    Tcl_Finalize();


#ifdef TCL_MEM_DEBUG




























    if (tclMemDumpFileName != NULL) {








	Tcl_DumpActiveMemory(tclMemDumpFileName);
















    }














































































#endif

    TclPlatformExit(status);




}




/*


























































































 *----------------------------------------------------------------------
 *
 * Tcl_Finalize --
 *
 *	Runs the exit handlers to allow Tcl to clean up its state prior

 *	to being unloaded. Called by Tcl_Exit and when Tcl was dynamically
 *	loaded and is now being unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Whatever the exit handlers do. Also frees up storage associated
 *	with the Tcl object type table.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_Finalize()
{
    ExitHandler *exitPtr;
    





    /*
     * Invoke exit handler first.
     */


    tclInExit = 1;
    for (exitPtr = firstExitPtr; exitPtr != NULL; exitPtr = firstExitPtr) {
	/*
	 * Be careful to remove the handler from the list before invoking
	 * its callback.  This protects us against double-freeing if the

	 * callback should call Tcl_DeleteExitHandler on itself.
	 */
















































































































	firstExitPtr = exitPtr->nextPtr;
	(*exitPtr->proc)(exitPtr->clientData);
	ckfree((char *) exitPtr);
    }



    /*
     * Now finalize the Tcl execution environment.  Note that this must be done
     * after the exit handlers, because there are order dependencies.

     */
    
    TclFinalizeCompExecEnv();
    TclFinalizeEnvironment();
    firstExitPtr = NULL;
    tclInExit = 0;

}

/*
 *----------------------------------------------------------------------
 *
 * TclInExit --
 *







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

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




|
>
|
|





<
|








|
>
>
>
>
>
|
|
|

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

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

|
<
<
>
|
|
|
<
<
<
>







554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812

813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960


961
962
963
964



965
966
967
968
969
970
971
972

void
Tcl_Exit(status)
    int status;			/* Exit status for application;  typically
				 * 0 for normal return, 1 for error return. */
{
    Tcl_Finalize();
    TclpExit(status);
}

/*
 *-------------------------------------------------------------------------
 * 
 * TclSetLibraryPath --
 *
 *	Set the path that will be used for searching for init.tcl and 
 *	encodings when an interp is being created.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changing the library path will affect what directories are
 *	examined when looking for encodings for all interps from that
 *	point forward.
 *
 *	The refcount of the new library path is incremented and the 
 *	refcount of the old path is decremented.
 *
 *-------------------------------------------------------------------------
 */

void
TclSetLibraryPath(pathPtr)
    Tcl_Obj *pathPtr;		/* A Tcl list object whose elements are
				 * the new library path. */
{
    Tcl_MutexLock(&exitMutex);
    if (pathPtr != NULL) {
	Tcl_IncrRefCount(pathPtr);
    }
    if (tclLibraryPath != NULL) {
	Tcl_DecrRefCount(tclLibraryPath);
    }
    tclLibraryPath = pathPtr;
    Tcl_MutexUnlock(&exitMutex);
}

/*
 *-------------------------------------------------------------------------
 *
 * TclGetLibraryPath --
 *
 *	Return a Tcl list object whose elements are the library path.
 *	The caller should not modify the contents of the returned object.
 *
 * Results:
 *	As above.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

Tcl_Obj *
TclGetLibraryPath()
{
    return tclLibraryPath;
}

/*
 *-------------------------------------------------------------------------
 *
 * TclInitSubsystems --
 *
 *	Initialize various subsytems in Tcl.  This should be called the
 *	first time an interp is created, or before any of the subsystems
 *	are used.  This function ensures an order for the initialization 
 *	of subsystems:
 *
 *	1. that cannot be initialized in lazy order because they are 
 *	mutually dependent.
 *
 *	2. so that they can be finalized in a known order w/o causing
 *	the subsequent re-initialization of a subsystem in the act of
 *	shutting down another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Varied, see the respective initialization routines.
 *
 *-------------------------------------------------------------------------
 */

void
TclInitSubsystems(argv0)
    CONST char *argv0;		/* Name of executable from argv[0] to main()
				 * in native multi-byte encoding. */
{
    ThreadSpecificData *tsdPtr;

    if (inFinalize != 0) {
	panic("TclInitSubsystems called while finalizing");
    }

    /*
     * Grab the thread local storage pointer before doing anything because
     * the initialization routines will be registering exit handlers.
     * We use this pointer to detect if this is the first time this
     * thread has created an interpreter.
     */

    tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
    if (subsystemsInitialized == 0) {
	/* 
	 * Double check inside the mutex.  There are definitly calls
	 * back into this routine from some of the procedures below.
	 */

	TclpInitLock();
	if (subsystemsInitialized == 0) {
	    /*
	     * Have to set this bit here to avoid deadlock with the
	     * routines below us that call into TclInitSubsystems.
	     */

	    subsystemsInitialized = 1;

	    tclExecutableName = NULL;

	    /*
	     * Initialize locks used by the memory allocators before anything
	     * interesting happens so we can use the allocators in the
	     * implementation of self-initializing locks.
	     */
#if USE_TCLALLOC
	    TclInitAlloc();
#endif
#ifdef TCL_MEM_DEBUG
	    TclInitDbCkalloc();
#endif

	    TclpInitPlatform();
    	    TclInitObjSubsystem();
	    TclInitIOSubsystem();
	    TclInitEncodingSubsystem();
    	    TclInitNamespaceSubsystem();
	}
	TclpInitUnlock();
    }

    if (tsdPtr == NULL) {
	/*
	 * First time this thread has created an interpreter.
	 * We fetch the key again just in case no exit handlers were
	 * registered by this point.
	 */

	(void) TCL_TSD_INIT(&dataKey);
	TclInitNotifier();
     }
}

/*
 *-------------------------------------------------------------------------
 *
 * TclFindEncodings --
 *
 *	Find and load the encoding file for this operating system.
 *	Before this is called, Tcl makes assumptions about the
 *	native string representation, but the true encoding is not
 *	assured.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Varied, see the respective initialization routines.
 *
 *-------------------------------------------------------------------------
 */

void
TclFindEncodings(argv0)
    CONST char *argv0;		/* Name of executable from argv[0] to main()
				 * in native multi-byte encoding. */
{
    char *native;
    Tcl_Obj *pathPtr;
    Tcl_DString libPath, buffer;

    if (encodingsInitialized == 0) {
	/* 
	 * Double check inside the mutex.  There may be calls
	 * back into this routine from some of the procedures below.
	 */

	TclpInitLock();
	if (encodingsInitialized == 0) {
	    /*
	     * Have to set this bit here to avoid deadlock with the
	     * routines below us that call into TclInitSubsystems.
	     */

	    encodingsInitialized = 1;

	    native = TclpFindExecutable(argv0);
	    TclpInitLibraryPath(native);

	    /*
	     * The library path was set in the TclpInitLibraryPath routine.
	     * The string set is a dirty UTF string.  To preserve the value
	     * convert the UTF string back to native before setting the new
	     * default encoding.
	     */
	    
	    pathPtr = TclGetLibraryPath();
	    if (pathPtr != NULL) {
		Tcl_UtfToExternalDString(NULL, Tcl_GetString(pathPtr), -1,
			&libPath);
	    }

	    TclpSetInitialEncodings();

	    /*
	     * Now convert the native sting back to native string back to UTF.
	     */
	     
	    if (pathPtr != NULL) {
		Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&libPath), -1,
			&buffer);
		pathPtr = Tcl_NewStringObj(Tcl_DStringValue(&buffer), -1);
		TclSetLibraryPath(pathPtr);

		Tcl_DStringFree(&libPath);
		Tcl_DStringFree(&buffer);
	    }
	}
	TclpInitUnlock();
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Finalize --
 *
 *	Shut down Tcl.  First calls registered exit handlers, then
 *	carefully shuts down various subsystems.
 *	Called by Tcl_Exit or when the Tcl shared library is being 
 *	unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:

 *	Varied, see the respective finalization routines.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_Finalize()
{
    ExitHandler *exitPtr;

    TclpInitLock();
    if (subsystemsInitialized != 0) {
	subsystemsInitialized = 0;
	encodingsInitialized  = 0;

	/*
	 * Invoke exit handlers first.
	 */

	Tcl_MutexLock(&exitMutex);
	inFinalize = 1;
	for (exitPtr = firstExitPtr; exitPtr != NULL; exitPtr = firstExitPtr) {
	    /*
	     * Be careful to remove the handler from the list before
	     * invoking its callback.  This protects us against
	     * double-freeing if the callback should call
	     * Tcl_DeleteExitHandler on itself.
	     */

	    firstExitPtr = exitPtr->nextPtr;
	    Tcl_MutexUnlock(&exitMutex);
	    (*exitPtr->proc)(exitPtr->clientData);
	    ckfree((char *) exitPtr);
	    Tcl_MutexLock(&exitMutex);
	}    
	firstExitPtr = NULL;
	Tcl_MutexUnlock(&exitMutex);

	/*
	 * Clean up after the current thread now, after exit handlers.
	 * In particular, the testexithandler command sets up something
	 * that writes to standard output, which gets closed.
	 * Note that there is no thread-local storage after this call.
	 */
    
	Tcl_FinalizeThread();

	/*
	 * Now finalize the Tcl execution environment.  Note that this
	 * must be done after the exit handlers, because there are
	 * order dependencies.
	 */

	TclFinalizeCompExecEnv();
	TclFinalizeEnvironment();

	TclFinalizeEncodingSubsystem();

	if (tclLibraryPath != NULL) {
	    Tcl_DecrRefCount(tclLibraryPath);
	    tclLibraryPath = NULL;
	}
	if (tclExecutableName != NULL) {
	    ckfree(tclExecutableName);
	    tclExecutableName = NULL;
	}
	if (tclNativeExecutableName != NULL) {
	    ckfree(tclNativeExecutableName);
	    tclNativeExecutableName = NULL;
	}
	if (tclDefaultEncodingDir != NULL) {
	    ckfree(tclDefaultEncodingDir);
	    tclDefaultEncodingDir = NULL;
	}
	
	Tcl_SetPanicProc(NULL);

	/*
	 * Free synchronization objects.  There really should only be one
	 * thread alive at this moment.
	 */

	TclFinalizeSynchronization();

	/*
	 * We defer unloading of packages until very late 
	 * to avoid memory access issues.  Both exit callbacks and
	 * synchronization variables may be stored in packages.
	 */

	TclFinalizeLoad();

	/*
	 * There shouldn't be any malloc'ed memory after this.
	 */

	TclFinalizeMemorySubsystem();
	inFinalize = 0;
    }
    TclpInitUnlock();
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FinalizeThread --
 *
 *	Runs the exit handlers to allow Tcl to clean up its state
 *	about a particular thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Varied, see the respective finalization routines.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_FinalizeThread()
{
    ExitHandler *exitPtr;
    ThreadSpecificData *tsdPtr =
	    (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    if (tsdPtr != NULL) {
	/*
	 * Invoke thread exit handlers first.
	 */

	tsdPtr->inExit = 1;
	for (exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;
		exitPtr = tsdPtr->firstExitPtr) {
	    /*
	     * Be careful to remove the handler from the list before invoking
	     * its callback.  This protects us against double-freeing if the
	     * callback should call Tcl_DeleteThreadExitHandler on itself.
	     */

	    tsdPtr->firstExitPtr = exitPtr->nextPtr;
	    (*exitPtr->proc)(exitPtr->clientData);
	    ckfree((char *) exitPtr);
	}
	TclFinalizeIOSubsystem();
	TclFinalizeNotifier();

	/*


	 * Blow away all thread local storage blocks.
	 */

	TclFinalizeThreadData();



    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclInExit --
 *
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
 *
 *----------------------------------------------------------------------
 */

int
TclInExit()
{

    return tclInExit;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_VwaitCmd --
 *
 *	This procedure is invoked to process the "vwait" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_VwaitCmd(clientData, interp, argc, argv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int argc;			/* Number of arguments. */
    char **argv;		/* Argument strings. */
{
    int done, foundEvent;


    if (argc != 2) {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " name\"", (char *) NULL);
	return TCL_ERROR;
    }

    if (Tcl_TraceVar(interp, argv[1],
	    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    VwaitVarProc, (ClientData) &done) != TCL_OK) {
	return TCL_ERROR;
    };
    done = 0;
    foundEvent = 1;
    while (!done && foundEvent) {
	foundEvent = Tcl_DoOneEvent(TCL_ALL_EVENTS);
    }
    Tcl_UntraceVar(interp, argv[1],
	    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    VwaitVarProc, (ClientData) &done);

    /*
     * Clear out the interpreter's result, since it may have been set
     * by event handlers.
     */

    Tcl_ResetResult(interp);
    if (!foundEvent) {
	Tcl_AppendResult(interp, "can't wait for variable \"", argv[1],
		"\":  would wait forever", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

	/* ARGSUSED */







>
|





|















|


|
|


>

|
|
<


>
|









|










|







980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020

1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
 *
 *----------------------------------------------------------------------
 */

int
TclInExit()
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    return tsdPtr->inExit;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_VwaitObjCmd --
 *
 *	This procedure is invoked to process the "vwait" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_VwaitObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int done, foundEvent;
    char *nameString;

    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "name");

	return TCL_ERROR;
    }
    nameString = Tcl_GetString(objv[1]);
    if (Tcl_TraceVar(interp, nameString,
	    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    VwaitVarProc, (ClientData) &done) != TCL_OK) {
	return TCL_ERROR;
    };
    done = 0;
    foundEvent = 1;
    while (!done && foundEvent) {
	foundEvent = Tcl_DoOneEvent(TCL_ALL_EVENTS);
    }
    Tcl_UntraceVar(interp, nameString,
	    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    VwaitVarProc, (ClientData) &done);

    /*
     * Clear out the interpreter's result, since it may have been set
     * by event handlers.
     */

    Tcl_ResetResult(interp);
    if (!foundEvent) {
	Tcl_AppendResult(interp, "can't wait for variable \"", nameString,
		"\":  would wait forever", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

	/* ARGSUSED */
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668

669


670
671
672
673
674
675
676
677
678


679






680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
    *donePtr = 1;
    return (char *) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UpdateCmd --
 *
 *	This procedure is invoked to process the "update" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_UpdateCmd(clientData, interp, argc, argv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int argc;			/* Number of arguments. */
    char **argv;		/* Argument strings. */
{

    int flags;



    if (argc == 1) {
	flags = TCL_ALL_EVENTS|TCL_DONT_WAIT;
    } else if (argc == 2) {
	if (strncmp(argv[1], "idletasks", strlen(argv[1])) != 0) {
	    Tcl_AppendResult(interp, "bad option \"", argv[1],
		    "\": must be idletasks", (char *) NULL);
	    return TCL_ERROR;
	}


	flags = TCL_WINDOW_EVENTS|TCL_IDLE_EVENTS|TCL_DONT_WAIT;






    } else {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " ?idletasks?\"", (char *) NULL);
	return TCL_ERROR;
    }

    while (Tcl_DoOneEvent(flags) != 0) {
	/* Empty loop body */
    }

    /*
     * Must clear the interpreter's result because event handlers could
     * have executed commands.
     */

    Tcl_ResetResult(interp);
    return TCL_OK;
}







|















|


|
|

>
|
>
>

|

|
|
|
<


>
>
|
>
>
>
>
>
>

<
|


|












1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113

1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
    *donePtr = 1;
    return (char *) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UpdateObjCmd --
 *
 *	This procedure is invoked to process the "update" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_UpdateObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int optionIndex;
    int flags = 0;		/* Initialized to avoid compiler warning. */
    static char *updateOptions[] = {"idletasks", (char *) NULL};
    enum updateOptions {REGEXP_IDLETASKS};

    if (objc == 1) {
	flags = TCL_ALL_EVENTS|TCL_DONT_WAIT;
    } else if (objc == 2) {
	if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions,
		"option", 0, &optionIndex) != TCL_OK) {

	    return TCL_ERROR;
	}
	switch ((enum updateOptions) optionIndex) {
	    case REGEXP_IDLETASKS: {
		flags = TCL_WINDOW_EVENTS|TCL_IDLE_EVENTS|TCL_DONT_WAIT;
		break;
	    }
	    default: {
		panic("Tcl_UpdateObjCmd: bad option index to UpdateOptions");
	    }
	}
    } else {

        Tcl_WrongNumArgs(interp, 1, objv, "?idletasks?");
	return TCL_ERROR;
    }
    
    while (Tcl_DoOneEvent(flags) != 0) {
	/* Empty loop body */
    }

    /*
     * Must clear the interpreter's result because event handlers could
     * have executed commands.
     */

    Tcl_ResetResult(interp);
    return TCL_OK;
}

Changes to generic/tclExecute.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclExecute.c --
 *
 *	This file contains procedures that execute byte-compiled Tcl
 *	commands.
 *
 * 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.
 *
 * SCCS: @(#) tclExecute.c 1.102 97/11/06 11:36:35
 */

#include "tclInt.h"
#include "tclCompile.h"

#ifdef NO_FLOAT_H
#   include "../compat/float.h"











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclExecute.c --
 *
 *	This file contains procedures that execute byte-compiled Tcl
 *	commands.
 *
 * 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: tclExecute.c,v 1.1.2.10 1999/03/25 03:55:31 stanton Exp $
 */

#include "tclInt.h"
#include "tclCompile.h"

#ifdef NO_FLOAT_H
#   include "../compat/float.h"
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

/*
 * Boolean flag indicating whether the Tcl bytecode interpreter has been
 * initialized.
 */

static int execInitialized = 0;


/*
 * Variable that controls whether execution tracing is enabled and, if so,
 * what level of tracing is desired:
 *    0: no execution tracing
 *    1: trace invocations of Tcl procs only
 *    2: trace invocations of all (not compiled away) commands
 *    3: display each instruction executed
 * This variable is linked to the Tcl variable "tcl_traceExec".
 */

int tclTraceExec = 0;


/*
 * The following global variable is use to signal matherr that Tcl
 * is responsible for the arithmetic, so errors can be handled in a
 * fashion appropriate for Tcl.  Zero means no Tcl math is in
 * progress;  non-zero means Tcl is doing math.
 */

int tcl_MathInProgress = 0;





/*
 * The variable below serves no useful purpose except to generate
 * a reference to matherr, so that the Tcl version of matherr is
 * linked in rather than the system version. Without this reference
 * the need for matherr won't be discovered during linking until after
 * libtcl.a has been processed, so Tcl's version won't be used.
 */

#ifdef NEED_MATHERR
extern int matherr();
int (*tclMatherrPtr)() = matherr;
#endif

/*
 * Array of instruction names.
 */

static char *opName[256];

/*
 * Mapping from expression instruction opcodes to strings; used for error
 * messages. Note that these entries must match the order and number of the
 * expression opcodes (e.g., INST_LOR) in tclCompile.h.
 */

static char *operatorStrings[] = {







>













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














<
<
<
<
<
<







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

/*
 * Boolean flag indicating whether the Tcl bytecode interpreter has been
 * initialized.
 */

static int execInitialized = 0;
TCL_DECLARE_MUTEX(execMutex)

/*
 * Variable that controls whether execution tracing is enabled and, if so,
 * what level of tracing is desired:
 *    0: no execution tracing
 *    1: trace invocations of Tcl procs only
 *    2: trace invocations of all (not compiled away) commands
 *    3: display each instruction executed
 * This variable is linked to the Tcl variable "tcl_traceExec".
 */

int tclTraceExec = 0;

typedef struct ThreadSpecificData {
    /*
     * The following global variable is use to signal matherr that Tcl
     * is responsible for the arithmetic, so errors can be handled in a
     * fashion appropriate for Tcl.  Zero means no Tcl math is in
     * progress;  non-zero means Tcl is doing math.
     */
    
    int mathInProgress;

} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * The variable below serves no useful purpose except to generate
 * a reference to matherr, so that the Tcl version of matherr is
 * linked in rather than the system version. Without this reference
 * the need for matherr won't be discovered during linking until after
 * libtcl.a has been processed, so Tcl's version won't be used.
 */

#ifdef NEED_MATHERR
extern int matherr();
int (*tclMatherrPtr)() = matherr;
#endif







/*
 * Mapping from expression instruction opcodes to strings; used for error
 * messages. Note that these entries must match the order and number of the
 * expression opcodes (e.g., INST_LOR) in tclCompile.h.
 */

static char *operatorStrings[] = {
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
 * messages. 
 */

#ifdef TCL_COMPILE_DEBUG
static char *resultStrings[] = {
    "TCL_OK", "TCL_ERROR", "TCL_RETURN", "TCL_BREAK", "TCL_CONTINUE"
};
#endif /* TCL_COMPILE_DEBUG */

/*
 * The following are statistics-related variables that record information
 * about the bytecode compiler and interpreter's operation. This includes
 * an array that records for each instruction how often it is executed.
 */

#ifdef TCL_COMPILE_STATS
static long numExecutions = 0;
static int instructionCount[256];
#endif /* TCL_COMPILE_STATS */

/*
 * Macros for testing floating-point values for certain special cases. Test
 * for not-a-number by comparing a value against itself; test for infinity
 * by comparing against the largest floating-point value.
 */

#define IS_NAN(v) ((v) != (v))
#ifdef DBL_MAX
#   define IS_INF(v) (((v) > DBL_MAX) || ((v) < -DBL_MAX))
#else
#   define IS_INF(v) 0
#endif

/*
 * Macro to adjust the program counter and restart the instruction execution
 * loop after each instruction is executed.
 */

#define ADJUST_PC(instBytes) \

    pc += instBytes;  continue

/*
 * Macros used to cache often-referenced Tcl evaluation stack information
 * in local variables. Note that a DECACHE_STACK_INFO()-CACHE_STACK_INFO()
 * pair must surround any call inside TclExecuteByteCode (and a few other
 * procedures that use this scheme) that could result in a recursive call
 * to TclExecuteByteCode.







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




















>
|







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
 * messages. 
 */

#ifdef TCL_COMPILE_DEBUG
static char *resultStrings[] = {
    "TCL_OK", "TCL_ERROR", "TCL_RETURN", "TCL_BREAK", "TCL_CONTINUE"
};
#endif












/*
 * Macros for testing floating-point values for certain special cases. Test
 * for not-a-number by comparing a value against itself; test for infinity
 * by comparing against the largest floating-point value.
 */

#define IS_NAN(v) ((v) != (v))
#ifdef DBL_MAX
#   define IS_INF(v) (((v) > DBL_MAX) || ((v) < -DBL_MAX))
#else
#   define IS_INF(v) 0
#endif

/*
 * Macro to adjust the program counter and restart the instruction execution
 * loop after each instruction is executed.
 */

#define ADJUST_PC(instBytes) \
    pc += (instBytes); \
    continue

/*
 * Macros used to cache often-referenced Tcl evaluation stack information
 * in local variables. Note that a DECACHE_STACK_INFO()-CACHE_STACK_INFO()
 * pair must surround any call inside TclExecuteByteCode (and a few other
 * procedures that use this scheme) that could result in a recursive call
 * to TclExecuteByteCode.
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
 * increments the object's ref count since it makes the stack have another
 * reference pointing to the object. However, POP_OBJECT does not decrement
 * the ref count. This is because the stack may hold the only reference to
 * the object, so the object would be destroyed if its ref count were
 * decremented before the caller had a chance to, e.g., store it in a
 * variable. It is the caller's responsibility to decrement the ref count
 * when it is finished with an object.
 */

#define STK_ITEM(offset)    (stackPtr[stackTop + (offset)])
#define STK_OBJECT(offset)  (STK_ITEM(offset).o)
#define STK_INT(offset)     (STK_ITEM(offset).i)
#define STK_POINTER(offset) (STK_ITEM(offset).p)

/*
 * WARNING! It is essential that objPtr only appear once in the PUSH_OBJECT
 * macro. The actual parameter might be an expression with side effects,
 * and this ensures that it will be executed only once. 
 */
    
#define PUSH_OBJECT(objPtr) \
    Tcl_IncrRefCount(stackPtr[++stackTop].o = (objPtr))
    
#define POP_OBJECT() \
    (stackPtr[stackTop--].o)

/*
 * Macros used to trace instruction execution. The macros TRACE,
 * TRACE_WITH_OBJ, and O2S are only used inside TclExecuteByteCode.
 * O2S is only used in TRACE* calls to get a string from an object.
 * 
 * NOTE THAT CLIENTS OF O2S ARE LIKELY TO FAIL IF THE OBJECT'S
 * STRING REP CONTAINS NULLS. 
 */

#ifdef TCL_COMPILE_DEBUG
	
#define O2S(objPtr) \
    Tcl_GetStringFromObj((objPtr), &length)
	
#ifdef TCL_COMPILE_STATS
#define TRACE(a) \
    if (traceInstructions) { \
        fprintf(stdout, "%d: %d,%ld (%u) ", iPtr->numLevels, \
	       stackTop, (tclObjsAlloced - tclObjsFreed), \
	       (unsigned int)(pc - codePtr->codeStart)); \

	printf a; \
        fflush(stdout); \
    }
#define TRACE_WITH_OBJ(a, objPtr) \
    if (traceInstructions) { \
        fprintf(stdout, "%d: %d,%ld (%u) ", iPtr->numLevels, \
	       stackTop, (tclObjsAlloced - tclObjsFreed), \
	       (unsigned int)(pc - codePtr->codeStart)); \

	printf a; \
	bytes = Tcl_GetStringFromObj((objPtr), &length); \
        TclPrintSource(stdout, bytes, TclMin(length, 30)); \
        fprintf(stdout, "\n"); \
        fflush(stdout); \
    }
#else  /* not TCL_COMPILE_STATS */
#define TRACE(a) \
    if (traceInstructions) { \
        fprintf(stdout, "%d: %d (%u) ", iPtr->numLevels, stackTop, \
	       (unsigned int)(pc - codePtr->codeStart)); \
	printf a; \
        fflush(stdout); \
    }
#define TRACE_WITH_OBJ(a, objPtr) \
    if (traceInstructions) { \
        fprintf(stdout, "%d: %d (%u) ", iPtr->numLevels, stackTop, \
	       (unsigned int)(pc - codePtr->codeStart)); \
	printf a; \
	bytes = Tcl_GetStringFromObj((objPtr), &length); \
        TclPrintSource(stdout, bytes, TclMin(length, 30)); \
        fprintf(stdout, "\n"); \
        fflush(stdout); \
    }
#endif /* TCL_COMPILE_STATS */

#else  /* not TCL_COMPILE_DEBUG */
	

#define TRACE(a)
#define TRACE_WITH_OBJ(a, objPtr)
#define O2S(objPtr)
	
#endif /* TCL_COMPILE_DEBUG */

/*
 * Declarations for local procedures to this file:
 */

static void		CallTraceProcedure _ANSI_ARGS_((Tcl_Interp *interp,







<
|
<
<
<
<
<
<






|


|





<
<
<



<
<
<
<
<


|
<
|
>

<



|
<
|
>

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

<

<
|
<
|
>



<







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
 * increments the object's ref count since it makes the stack have another
 * reference pointing to the object. However, POP_OBJECT does not decrement
 * the ref count. This is because the stack may hold the only reference to
 * the object, so the object would be destroyed if its ref count were
 * decremented before the caller had a chance to, e.g., store it in a
 * variable. It is the caller's responsibility to decrement the ref count
 * when it is finished with an object.

 *






 * WARNING! It is essential that objPtr only appear once in the PUSH_OBJECT
 * macro. The actual parameter might be an expression with side effects,
 * and this ensures that it will be executed only once. 
 */
    
#define PUSH_OBJECT(objPtr) \
    Tcl_IncrRefCount(stackPtr[++stackTop] = (objPtr))
    
#define POP_OBJECT() \
    (stackPtr[stackTop--])

/*
 * Macros used to trace instruction execution. The macros TRACE,
 * TRACE_WITH_OBJ, and O2S are only used inside TclExecuteByteCode.
 * O2S is only used in TRACE* calls to get a string from an object.



 */

#ifdef TCL_COMPILE_DEBUG





#define TRACE(a) \
    if (traceInstructions) { \
        fprintf(stdout, "%2d: %2d (%u) %s ", iPtr->numLevels, stackTop, \

	       (unsigned int)(pc - codePtr->codeStart), \
	       GetOpcodeName(pc)); \
	printf a; \

    }
#define TRACE_WITH_OBJ(a, objPtr) \
    if (traceInstructions) { \
        fprintf(stdout, "%2d: %2d (%u) %s ", iPtr->numLevels, stackTop, \

	       (unsigned int)(pc - codePtr->codeStart), \
	       GetOpcodeName(pc)); \
	printf a; \


        TclPrintObject(stdout, (objPtr), 30); \

















        fprintf(stdout, "\n"); \

    }

#define O2S(objPtr) \

    Tcl_GetString(objPtr)
#else
#define TRACE(a)
#define TRACE_WITH_OBJ(a, objPtr)
#define O2S(objPtr)

#endif /* TCL_COMPILE_DEBUG */

/*
 * Declarations for local procedures to this file:
 */

static void		CallTraceProcedure _ANSI_ARGS_((Tcl_Interp *interp,
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
static int		ExprSrandFunc _ANSI_ARGS_((Tcl_Interp *interp,
			    ExecEnv *eePtr, ClientData clientData));
static int		ExprUnaryFunc _ANSI_ARGS_((Tcl_Interp *interp,
			    ExecEnv *eePtr, ClientData clientData));
#ifdef TCL_COMPILE_STATS
static int              EvalStatsCmd _ANSI_ARGS_((ClientData clientData,
                            Tcl_Interp *interp, int argc, char **argv));
#endif /* TCL_COMPILE_STATS */
static void		FreeCmdNameInternalRep _ANSI_ARGS_((
    			    Tcl_Obj *objPtr));





static char *		GetSrcInfoForPc _ANSI_ARGS_((unsigned char *pc,
        		    ByteCode* codePtr, int *lengthPtr));
static void		GrowEvaluationStack _ANSI_ARGS_((ExecEnv *eePtr));
static void		IllegalExprOperandType _ANSI_ARGS_((
			    Tcl_Interp *interp, unsigned int opCode,
			    Tcl_Obj *opndPtr));
static void		InitByteCodeExecution _ANSI_ARGS_((
			    Tcl_Interp *interp));

static void		PrintByteCodeInfo _ANSI_ARGS_((ByteCode *codePtr));
static void		RecordTracebackInfo _ANSI_ARGS_((Tcl_Interp *interp,
			    unsigned char *pc, ByteCode *codePtr));
static int		SetCmdNameFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
#ifdef TCL_COMPILE_DEBUG
static char *		StringForResultCode _ANSI_ARGS_((int result));
#endif /* TCL_COMPILE_DEBUG */
static void		UpdateStringOfCmdName _ANSI_ARGS_((Tcl_Obj *objPtr));
#ifdef TCL_COMPILE_DEBUG
static void		ValidatePcAndStackTop _ANSI_ARGS_((
			    ByteCode *codePtr, unsigned char *pc,
			    int stackTop, int stackLowerBound,
			    int stackUpperBound));
#endif /* TCL_COMPILE_DEBUG */

/*
 * Table describing the built-in math functions. Entries in this table are
 * indexed by the values of the INST_CALL_BUILTIN_FUNC instruction's
 * operand byte.
 */








|


>
>
>
>
>




|



>

<
|




<
<
<




|







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
static int		ExprSrandFunc _ANSI_ARGS_((Tcl_Interp *interp,
			    ExecEnv *eePtr, ClientData clientData));
static int		ExprUnaryFunc _ANSI_ARGS_((Tcl_Interp *interp,
			    ExecEnv *eePtr, ClientData clientData));
#ifdef TCL_COMPILE_STATS
static int              EvalStatsCmd _ANSI_ARGS_((ClientData clientData,
                            Tcl_Interp *interp, int argc, char **argv));
#endif
static void		FreeCmdNameInternalRep _ANSI_ARGS_((
    			    Tcl_Obj *objPtr));
#ifdef TCL_COMPILE_DEBUG
static char *		GetOpcodeName _ANSI_ARGS_((unsigned char *pc));
#endif
static ExceptionRange *	GetExceptRangeForPc _ANSI_ARGS_((unsigned char *pc,
			    int catchOnly, ByteCode* codePtr));
static char *		GetSrcInfoForPc _ANSI_ARGS_((unsigned char *pc,
        		    ByteCode* codePtr, int *lengthPtr));
static void		GrowEvaluationStack _ANSI_ARGS_((ExecEnv *eePtr));
static void		IllegalExprOperandType _ANSI_ARGS_((
			    Tcl_Interp *interp, unsigned char *pc,
			    Tcl_Obj *opndPtr));
static void		InitByteCodeExecution _ANSI_ARGS_((
			    Tcl_Interp *interp));
#ifdef TCL_COMPILE_DEBUG
static void		PrintByteCodeInfo _ANSI_ARGS_((ByteCode *codePtr));

#endif
static int		SetCmdNameFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
#ifdef TCL_COMPILE_DEBUG
static char *		StringForResultCode _ANSI_ARGS_((int result));



static void		ValidatePcAndStackTop _ANSI_ARGS_((
			    ByteCode *codePtr, unsigned char *pc,
			    int stackTop, int stackLowerBound,
			    int stackUpperBound));
#endif

/*
 * Table describing the built-in math functions. Entries in this table are
 * indexed by the values of the INST_CALL_BUILTIN_FUNC instruction's
 * operand byte.
 */

352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
 * name") argument in a Tcl command.
 */

Tcl_ObjType tclCmdNameType = {
    "cmdName",				/* name */
    FreeCmdNameInternalRep,		/* freeIntRepProc */
    DupCmdNameInternalRep,		/* dupIntRepProc */
    UpdateStringOfCmdName,		/* updateStringProc */
    SetCmdNameFromAny			/* setFromAnyProc */
};

/*
 *----------------------------------------------------------------------
 *
 * InitByteCodeExecution --







|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
 * name") argument in a Tcl command.
 */

Tcl_ObjType tclCmdNameType = {
    "cmdName",				/* name */
    FreeCmdNameInternalRep,		/* freeIntRepProc */
    DupCmdNameInternalRep,		/* dupIntRepProc */
    (Tcl_UpdateStringProc *) NULL,	/* updateStringProc */
    SetCmdNameFromAny			/* setFromAnyProc */
};

/*
 *----------------------------------------------------------------------
 *
 * InitByteCodeExecution --
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

static void
InitByteCodeExecution(interp)
    Tcl_Interp *interp;		/* Interpreter for which the Tcl variable
				 * "tcl_traceExec" is linked to control
				 * instruction tracing. */
{
    int i;
    
    Tcl_RegisterObjType(&tclCmdNameType);

    (VOID *) memset(opName, 0, sizeof(opName));
    for (i = 0;  instructionTable[i].name != NULL;  i++) {
	opName[i] = instructionTable[i].name;
    }

#ifdef TCL_COMPILE_STATS    
    (VOID *) memset(instructionCount, 0, sizeof(instructionCount));
    (VOID *) memset(tclByteCodeCount, 0, sizeof(tclByteCodeCount));
    (VOID *) memset(tclSourceCount, 0, sizeof(tclSourceCount));

    Tcl_CreateCommand(interp, "evalstats", EvalStatsCmd,
		      (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
#endif /* TCL_COMPILE_STATS */
    
    if (Tcl_LinkVar(interp, "tcl_traceExec", (char *) &tclTraceExec,
		    TCL_LINK_INT) != TCL_OK) {
	panic("InitByteCodeExecution: can't create link for tcl_traceExec variable");
    }





}

/*
 *----------------------------------------------------------------------
 *
 * TclCreateExecEnv --
 *







<
<

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




>
>
>
>
>







338
339
340
341
342
343
344


345















346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

static void
InitByteCodeExecution(interp)
    Tcl_Interp *interp;		/* Interpreter for which the Tcl variable
				 * "tcl_traceExec" is linked to control
				 * instruction tracing. */
{


    Tcl_RegisterObjType(&tclCmdNameType);















    if (Tcl_LinkVar(interp, "tcl_traceExec", (char *) &tclTraceExec,
		    TCL_LINK_INT) != TCL_OK) {
	panic("InitByteCodeExecution: can't create link for tcl_traceExec variable");
    }

#ifdef TCL_COMPILE_STATS    
    Tcl_CreateCommand(interp, "evalstats", EvalStatsCmd,
		      (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
#endif /* TCL_COMPILE_STATS */
}

/*
 *----------------------------------------------------------------------
 *
 * TclCreateExecEnv --
 *
439
440
441
442
443
444
445
446
447
448
449
450

451

452
453
454

455
456
457
458
459
460
461
ExecEnv *
TclCreateExecEnv(interp)
    Tcl_Interp *interp;		/* Interpreter for which the execution
				 * environment is being created. */
{
    ExecEnv *eePtr = (ExecEnv *) ckalloc(sizeof(ExecEnv));

    eePtr->stackPtr = (StackItem *)
	ckalloc((unsigned) (TCL_STACK_INITIAL_SIZE * sizeof(StackItem)));
    eePtr->stackTop = -1;
    eePtr->stackEnd = (TCL_STACK_INITIAL_SIZE - 1);


    if (!execInitialized) {

	InitByteCodeExecution(interp);
	execInitialized = 1;
    }


    return eePtr;
}
#undef TCL_STACK_INITIAL_SIZE

/*
 *----------------------------------------------------------------------







|
|



>

>



>







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
ExecEnv *
TclCreateExecEnv(interp)
    Tcl_Interp *interp;		/* Interpreter for which the execution
				 * environment is being created. */
{
    ExecEnv *eePtr = (ExecEnv *) ckalloc(sizeof(ExecEnv));

    eePtr->stackPtr = (Tcl_Obj **)
	ckalloc((unsigned) (TCL_STACK_INITIAL_SIZE * sizeof(Tcl_Obj *)));
    eePtr->stackTop = -1;
    eePtr->stackEnd = (TCL_STACK_INITIAL_SIZE - 1);

    Tcl_MutexLock(&execMutex);
    if (!execInitialized) {
	TclInitAuxDataTypeTable();
	InitByteCodeExecution(interp);
	execInitialized = 1;
    }
    Tcl_MutexUnlock(&execMutex);

    return eePtr;
}
#undef TCL_STACK_INITIAL_SIZE

/*
 *----------------------------------------------------------------------
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
    ckfree((char *) eePtr->stackPtr);
    ckfree((char *) eePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeExecEnv --
 *
 *	Finalizes the execution environment setup so that it can be
 *	later reinitialized.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	After this call, the next time TclCreateExecEnv will be called
 *	it will call InitByteCodeExecution.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeExecEnv()
{

    execInitialized = 0;


}

/*
 *----------------------------------------------------------------------
 *
 * GrowEvaluationStack --
 *







|















|

>

>
>







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
    ckfree((char *) eePtr->stackPtr);
    ckfree((char *) eePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeExecution --
 *
 *	Finalizes the execution environment setup so that it can be
 *	later reinitialized.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	After this call, the next time TclCreateExecEnv will be called
 *	it will call InitByteCodeExecution.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeExecution()
{
    Tcl_MutexLock(&execMutex);
    execInitialized = 0;
    Tcl_MutexUnlock(&execMutex);
    TclFinalizeAuxDataTypeTable();
}

/*
 *----------------------------------------------------------------------
 *
 * GrowEvaluationStack --
 *
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
    /*
     * The current Tcl stack elements are stored from eePtr->stackPtr[0]
     * to eePtr->stackPtr[eePtr->stackEnd] (inclusive).
     */

    int currElems = (eePtr->stackEnd + 1);
    int newElems  = 2*currElems;
    int currBytes = currElems * sizeof(StackItem);
    int newBytes  = 2*currBytes;
    StackItem *newStackPtr = (StackItem *) ckalloc((unsigned) newBytes);

    /*
     * Copy the existing stack items to the new stack space, free the old
     * storage if appropriate, and mark new space as malloc'ed.
     */
 
    memcpy((VOID *) newStackPtr, (VOID *) eePtr->stackPtr,







|

|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
    /*
     * The current Tcl stack elements are stored from eePtr->stackPtr[0]
     * to eePtr->stackPtr[eePtr->stackEnd] (inclusive).
     */

    int currElems = (eePtr->stackEnd + 1);
    int newElems  = 2*currElems;
    int currBytes = currElems * sizeof(Tcl_Obj *);
    int newBytes  = 2*currBytes;
    Tcl_Obj **newStackPtr = (Tcl_Obj **) ckalloc((unsigned) newBytes);

    /*
     * Copy the existing stack items to the new stack space, free the old
     * storage if appropriate, and mark new space as malloc'ed.
     */
 
    memcpy((VOID *) newStackPtr, (VOID *) eePtr->stackPtr,
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711





712
713
714

715
716
717
718


719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851

852
853
854
855
856
857
858
859
860
861
862
863
864
865

866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
TclExecuteByteCode(interp, codePtr)
    Tcl_Interp *interp;		/* Token for command interpreter. */
    ByteCode *codePtr;		/* The bytecode sequence to interpret. */
{
    Interp *iPtr = (Interp *) interp;
    ExecEnv *eePtr = iPtr->execEnvPtr;
    				/* Points to the execution environment. */
    register StackItem *stackPtr = eePtr->stackPtr;
    				/* Cached evaluation stack base pointer. */
    register int stackTop = eePtr->stackTop;
    				/* Cached top index of evaluation stack. */
    Tcl_Obj **objArrayPtr = codePtr->objArrayPtr;
    				/* Points to the ByteCode's object array. */
    unsigned char *pc = codePtr->codeStart;
				/* The current program counter. */
    unsigned char opCode;	/* The current instruction code. */
    int opnd;			/* Current instruction's operand byte. */
    int pcAdjustment;		/* Hold pc adjustment after instruction. */
    int initStackTop = stackTop;/* Stack top at start of execution. */
    ExceptionRange *rangePtr;	/* Points to closest loop or catch exception
				 * range enclosing the pc. Used by various
				 * instructions and processCatch to
				 * process break, continue, and errors. */
    int result = TCL_OK;	/* Return code returned after execution. */
    int traceInstructions = (tclTraceExec == 3);
    Tcl_Obj *valuePtr, *value2Ptr, *namePtr, *objPtr;
    char *bytes;
    int length;
    long i;
    Tcl_DString command;	/* Used for debugging. If tclTraceExec >= 2
				 * holds a string representing the last
				 * command invoked. */

    /*
     * This procedure uses a stack to hold information about catch commands.
     * This information is the current operand stack top when starting to
     * execute the code for each catch command. It starts out with stack-
     * allocated space but uses dynamically-allocated storage if needed.
     */

#define STATIC_CATCH_STACK_SIZE 5
    int (catchStackStorage[STATIC_CATCH_STACK_SIZE]);
    int *catchStackPtr = catchStackStorage;
    int catchTop = -1;

    /*
     * THIS PROC FAILS IF AN OBJECT'S STRING REP HAS A NULL BYTE.
     */

    if (tclTraceExec >= 2) {
	PrintByteCodeInfo(codePtr);
#ifdef TCL_COMPILE_STATS
	fprintf(stdout, "  Starting stack top=%d, system objects=%ld\n",
		eePtr->stackTop, (tclObjsAlloced - tclObjsFreed));
#else
	fprintf(stdout, "  Starting stack top=%d\n", eePtr->stackTop);
#endif /* TCL_COMPILE_STATS */
	fflush(stdout);
    }


#ifdef TCL_COMPILE_STATS
    numExecutions++;
#endif /* TCL_COMPILE_STATS */

    /*
     * Make sure the catch stack is large enough to hold the maximum number
     * of catch commands that could ever be executing at the same time. This
     * will be no more than the exception range array's depth.
     */

    if (codePtr->maxExcRangeDepth > STATIC_CATCH_STACK_SIZE) {
	catchStackPtr = (int *)
	        ckalloc(codePtr->maxExcRangeDepth * sizeof(int));
    }

    /*
     * Make sure the stack has enough room to execute this ByteCode.
     */

    while ((stackTop + codePtr->maxStackDepth) > eePtr->stackEnd) {
        GrowEvaluationStack(eePtr); 
        stackPtr = eePtr->stackPtr;
    }

    /*
     * Initialize the buffer that holds a string containing the name and
     * arguments for the last invoked command.
     */

    Tcl_DStringInit(&command);

    /*
     * Loop executing instructions until a "done" instruction, a TCL_RETURN,
     * or some error.
     */

    for (;;) {
#ifdef TCL_COMPILE_DEBUG
	ValidatePcAndStackTop(codePtr, pc, stackTop, initStackTop,
		eePtr->stackEnd);
#else /* not TCL_COMPILE_DEBUG */
	if (traceInstructions) {
#ifdef TCL_COMPILE_STATS
	    fprintf(stdout, "%d: %d,%ld ", iPtr->numLevels, stackTop,
		    (tclObjsAlloced - tclObjsFreed));
#else /* TCL_COMPILE_STATS */
	    fprintf(stdout, "%d: %d ", iPtr->numLevels, stackTop);
#endif /* TCL_COMPILE_STATS */
	    TclPrintInstruction(codePtr, pc);
	    fflush(stdout);
	}
#endif /* TCL_COMPILE_DEBUG */
	
	opCode = *pc;
#ifdef TCL_COMPILE_STATS    
	instructionCount[opCode]++;
#endif /* TCL_COMPILE_STATS */

        switch (opCode) {
	case INST_DONE:
	    /*
	     * Pop the topmost object from the stack, set the interpreter's
	     * object result to point to it, and return.
	     */
	    valuePtr = POP_OBJECT();
	    Tcl_SetObjResult(interp, valuePtr);
	    TclDecrRefCount(valuePtr);
	    if (stackTop != initStackTop) {
		fprintf(stderr, "\nTclExecuteByteCode: done instruction at pc %u: stack top %d != entry stack top %d\n",
			(unsigned int)(pc - codePtr->codeStart),
			(unsigned int) stackTop,
			(unsigned int) initStackTop);
		fprintf(stderr, "  Source: ");
		TclPrintSource(stderr, codePtr->source, 150);
		panic("TclExecuteByteCode execution failure: end stack top != start stack top");
	    }
	    TRACE_WITH_OBJ(("done => return code=%d, result is ", result),
		    iPtr->objResultPtr);





	    goto done;
	    
	case INST_PUSH1:

	    valuePtr = objArrayPtr[TclGetUInt1AtPtr(pc+1)];
	    PUSH_OBJECT(valuePtr);
	    TRACE_WITH_OBJ(("push1 %u => ", TclGetUInt1AtPtr(pc+1)),
	            valuePtr);


	    ADJUST_PC(2);
	    
	case INST_PUSH4:
	    valuePtr = objArrayPtr[TclGetUInt4AtPtr(pc+1)];
	    PUSH_OBJECT(valuePtr);
	    TRACE_WITH_OBJ(("push4 %u => ", TclGetUInt4AtPtr(pc+1)),
		    valuePtr);
	    ADJUST_PC(5);
	    
	case INST_POP:
	    valuePtr = POP_OBJECT();
	    TRACE_WITH_OBJ(("pop => discarding "), valuePtr);
	    TclDecrRefCount(valuePtr); /* finished with pop'ed object. */
	    ADJUST_PC(1);

	case INST_DUP:
	    valuePtr = stackPtr[stackTop].o;
	    PUSH_OBJECT(Tcl_DuplicateObj(valuePtr));
	    TRACE_WITH_OBJ(("dup => "), valuePtr);
	    ADJUST_PC(1);

	case INST_CONCAT1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    {
		Tcl_Obj *concatObjPtr;
		int totalLen = 0;

		/*
		 * Concatenate strings (with no separators) from the top
		 * opnd items on the stack starting with the deepest item.
		 * First, determine how many characters are needed.
		 */

		for (i = (stackTop - (opnd-1));  i <= stackTop;  i++) {
		    valuePtr = stackPtr[i].o;
		    bytes = TclGetStringFromObj(valuePtr, &length);
		    if (bytes != NULL) {
			totalLen += length;
		    }
                }

		/*
		 * Initialize the new append string object by appending the
		 * strings of the opnd stack objects. Also pop the objects. 
		 */

		TclNewObj(concatObjPtr);
		if (totalLen > 0) {
		    char *p = (char *) ckalloc((unsigned) (totalLen + 1));
		    concatObjPtr->bytes = p;
		    concatObjPtr->length = totalLen;
		    for (i = (stackTop - (opnd-1));  i <= stackTop;  i++) {
			valuePtr = stackPtr[i].o;
			bytes = TclGetStringFromObj(valuePtr, &length);
			if (bytes != NULL) {
			    memcpy((VOID *) p, (VOID *) bytes,
			            (size_t) length);
			    p += length;
			}
			TclDecrRefCount(valuePtr);
		    }
		    *p = '\0';
		} else {
		    for (i = (stackTop - (opnd-1));  i <= stackTop;  i++) {
			valuePtr = stackPtr[i].o;
			Tcl_DecrRefCount(valuePtr);
		    }
		}
		stackTop -= opnd;
		
		PUSH_OBJECT(concatObjPtr);
		TRACE_WITH_OBJ(("concat %u => ", opnd), concatObjPtr);
		ADJUST_PC(2);
            }
	    
	case INST_INVOKE_STK4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    pcAdjustment = 5;
	    goto doInvocation;

	case INST_INVOKE_STK1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    pcAdjustment = 2;
	    
	    doInvocation:
	    {
		char *cmdName;
		Command *cmdPtr;   /* Points to command's Command struct. */
		int objc = opnd;   /* The number of arguments. */
		Tcl_Obj **objv;	   /* The array of argument objects. */
		Tcl_Obj *objv0Ptr; /* Holds objv[0], the command name. */
		int newPcOffset = 0;
				   /* Instruction offset computed during
				    * break, continue, error processing.
				    * Init. to avoid compiler warning. */
		Tcl_Command cmd;
#ifdef TCL_COMPILE_DEBUG
		int isUnknownCmd = 0;
		char cmdNameBuf[30];
#endif /* TCL_COMPILE_DEBUG */
		
		/*
		 * If the interpreter was deleted, return an error.
		 */
		
		if (iPtr->flags & DELETED) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "attempt to call eval in deleted interpreter", -1);
		    Tcl_SetErrorCode(interp, "CORE", "IDELETE",
			    "attempt to call eval in deleted interpreter",
			    (char *) NULL);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
    
		objv = &(stackPtr[stackTop - (objc-1)].o);
		objv0Ptr = objv[0];
		cmdName = TclGetStringFromObj(objv0Ptr, (int *) NULL);
		
		/*
		 * Find the procedure to execute this command. If there
		 * isn't one, then see if there is a command "unknown". If
		 * so, invoke it, passing it the original command words as
		 * arguments.
		 *
		 * We convert the objv[0] object to be a CmdName object.
		 * This caches a pointer to the Command structure for the
		 * command; this pointer is held in a ResolvedCmdName
		 * structure the object's internal rep. points to.
		 */

		cmd = Tcl_GetCommandFromObj(interp, objv0Ptr);

		cmdPtr = (Command *) cmd;
		
		/*
		 * If the command is still not found, handle it with the
		 * "unknown" proc.
		 */

		if (cmdPtr == NULL) {
		    cmd = Tcl_FindCommand(interp, "unknown",
                            (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
                    if (cmd == (Tcl_Command) NULL) {
			Tcl_ResetResult(interp);
			Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			        "invalid command name \"", cmdName, "\"",

				(char *) NULL);
			TRACE(("%s %u => unknown proc not found: ",
			       opName[opCode], objc));
			result = TCL_ERROR;
			goto checkForCatch;
		    }
		    cmdPtr = (Command *) cmd;
#ifdef TCL_COMPILE_DEBUG
		    isUnknownCmd = 1;
#endif /*TCL_COMPILE_DEBUG*/			
		    stackTop++; /* need room for new inserted objv[0] */
		    for (i = objc;  i >= 0;  i--) {
			objv[i+1] = objv[i];
		    }
		    objc++;
		    objv[0] = Tcl_NewStringObj("unknown", -1);
		    Tcl_IncrRefCount(objv[0]);
		}
		







|



<
<
|

<









|



<
<
<








|




<
<
<
|


<
<
<
<

<


>
|

|
|







|

|











<
<
<
<
<
<
<










|
<
<
<
<
|
<
|
|
|


<

|
|
<
|













<
<


|

>
>
>
>
>



>
|

|
|
>
>



|

|
<




|




|

|















<
|
















|
|










<
|





|














<
<
|
|
|
|
<
<
<
<


|

















<
<
<
<

|
<
<
<
<
<
<
|
<


<
>
|
<
<
<
<
<
<

|
|
|


|
>

|
<



<




|







522
523
524
525
526
527
528
529
530
531
532


533
534

535
536
537
538
539
540
541
542
543
544
545
546
547



548
549
550
551
552
553
554
555
556
557
558
559
560



561
562
563




564

565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592







593
594
595
596
597
598
599
600
601
602
603




604

605
606
607
608
609

610
611
612

613
614
615
616
617
618
619
620
621
622
623
624
625
626


627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678

679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728


729
730
731
732




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




753
754






755

756
757

758
759






760
761
762
763
764
765
766
767
768
769

770
771
772

773
774
775
776
777
778
779
780
781
782
783
784
TclExecuteByteCode(interp, codePtr)
    Tcl_Interp *interp;		/* Token for command interpreter. */
    ByteCode *codePtr;		/* The bytecode sequence to interpret. */
{
    Interp *iPtr = (Interp *) interp;
    ExecEnv *eePtr = iPtr->execEnvPtr;
    				/* Points to the execution environment. */
    register Tcl_Obj **stackPtr = eePtr->stackPtr;
    				/* Cached evaluation stack base pointer. */
    register int stackTop = eePtr->stackTop;
    				/* Cached top index of evaluation stack. */


    register unsigned char *pc = codePtr->codeStart;
				/* The current program counter. */

    int opnd;			/* Current instruction's operand byte. */
    int pcAdjustment;		/* Hold pc adjustment after instruction. */
    int initStackTop = stackTop;/* Stack top at start of execution. */
    ExceptionRange *rangePtr;	/* Points to closest loop or catch exception
				 * range enclosing the pc. Used by various
				 * instructions and processCatch to
				 * process break, continue, and errors. */
    int result = TCL_OK;	/* Return code returned after execution. */
    int traceInstructions = (tclTraceExec == 3);
    Tcl_Obj *valuePtr, *value2Ptr, *objPtr;
    char *bytes;
    int length;
    long i;




    /*
     * This procedure uses a stack to hold information about catch commands.
     * This information is the current operand stack top when starting to
     * execute the code for each catch command. It starts out with stack-
     * allocated space but uses dynamically-allocated storage if needed.
     */

#define STATIC_CATCH_STACK_SIZE 4
    int (catchStackStorage[STATIC_CATCH_STACK_SIZE]);
    int *catchStackPtr = catchStackStorage;
    int catchTop = -1;




#ifdef TCL_COMPILE_DEBUG
    if (tclTraceExec >= 2) {
	PrintByteCodeInfo(codePtr);




	fprintf(stdout, "  Starting stack top=%d\n", eePtr->stackTop);

	fflush(stdout);
    }
#endif
    
#ifdef TCL_COMPILE_STATS
    iPtr->stats.numExecutions++;
#endif

    /*
     * Make sure the catch stack is large enough to hold the maximum number
     * of catch commands that could ever be executing at the same time. This
     * will be no more than the exception range array's depth.
     */

    if (codePtr->maxExceptDepth > STATIC_CATCH_STACK_SIZE) {
	catchStackPtr = (int *)
	        ckalloc(codePtr->maxExceptDepth * sizeof(int));
    }

    /*
     * Make sure the stack has enough room to execute this ByteCode.
     */

    while ((stackTop + codePtr->maxStackDepth) > eePtr->stackEnd) {
        GrowEvaluationStack(eePtr); 
        stackPtr = eePtr->stackPtr;
    }








    /*
     * Loop executing instructions until a "done" instruction, a TCL_RETURN,
     * or some error.
     */

    for (;;) {
#ifdef TCL_COMPILE_DEBUG
	ValidatePcAndStackTop(codePtr, pc, stackTop, initStackTop,
		eePtr->stackEnd);
#else /* not TCL_COMPILE_DEBUG */
        if (traceInstructions) {




            fprintf(stdout, "%2d: %2d ", iPtr->numLevels, stackTop);

            TclPrintInstruction(codePtr, pc);
            fflush(stdout);
        }
#endif /* TCL_COMPILE_DEBUG */
	

#ifdef TCL_COMPILE_STATS    
	iPtr->stats.instructionCount[*pc]++;
#endif

        switch (*pc) {
	case INST_DONE:
	    /*
	     * Pop the topmost object from the stack, set the interpreter's
	     * object result to point to it, and return.
	     */
	    valuePtr = POP_OBJECT();
	    Tcl_SetObjResult(interp, valuePtr);
	    TclDecrRefCount(valuePtr);
	    if (stackTop != initStackTop) {
		fprintf(stderr, "\nTclExecuteByteCode: done instruction at pc %u: stack top %d != entry stack top %d\n",
			(unsigned int)(pc - codePtr->codeStart),
			(unsigned int) stackTop,
			(unsigned int) initStackTop);


		panic("TclExecuteByteCode execution failure: end stack top != start stack top");
	    }
	    TRACE_WITH_OBJ(("=> return code=%d, result=", result),
		    iPtr->objResultPtr);
#ifdef TCL_COMPILE_DEBUG	    
	    if (traceInstructions) {
		fprintf(stdout, "\n");
	    }
#endif
	    goto done;
	    
	case INST_PUSH1:
#ifdef TCL_COMPILE_DEBUG
	    valuePtr = codePtr->objArrayPtr[TclGetUInt1AtPtr(pc+1)];
	    PUSH_OBJECT(valuePtr);
	    TRACE_WITH_OBJ(("%u => ", TclGetInt1AtPtr(pc+1)), valuePtr);
#else
	    PUSH_OBJECT(codePtr->objArrayPtr[TclGetUInt1AtPtr(pc+1)]);
#endif /* TCL_COMPILE_DEBUG */
	    ADJUST_PC(2);
	    
	case INST_PUSH4:
	    valuePtr = codePtr->objArrayPtr[TclGetUInt4AtPtr(pc+1)];
	    PUSH_OBJECT(valuePtr);
	    TRACE_WITH_OBJ(("%u => ", TclGetUInt4AtPtr(pc+1)), valuePtr);

	    ADJUST_PC(5);
	    
	case INST_POP:
	    valuePtr = POP_OBJECT();
	    TRACE_WITH_OBJ(("=> discarding "), valuePtr);
	    TclDecrRefCount(valuePtr); /* finished with pop'ed object. */
	    ADJUST_PC(1);

	case INST_DUP:
	    valuePtr = stackPtr[stackTop];
	    PUSH_OBJECT(Tcl_DuplicateObj(valuePtr));
	    TRACE_WITH_OBJ(("=> "), valuePtr);
	    ADJUST_PC(1);

	case INST_CONCAT1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    {
		Tcl_Obj *concatObjPtr;
		int totalLen = 0;

		/*
		 * Concatenate strings (with no separators) from the top
		 * opnd items on the stack starting with the deepest item.
		 * First, determine how many characters are needed.
		 */

		for (i = (stackTop - (opnd-1));  i <= stackTop;  i++) {

		    bytes = Tcl_GetStringFromObj(stackPtr[i], &length);
		    if (bytes != NULL) {
			totalLen += length;
		    }
                }

		/*
		 * Initialize the new append string object by appending the
		 * strings of the opnd stack objects. Also pop the objects. 
		 */

		TclNewObj(concatObjPtr);
		if (totalLen > 0) {
		    char *p = (char *) ckalloc((unsigned) (totalLen + 1));
		    concatObjPtr->bytes = p;
		    concatObjPtr->length = totalLen;
		    for (i = (stackTop - (opnd-1));  i <= stackTop;  i++) {
			valuePtr = stackPtr[i];
			bytes = Tcl_GetStringFromObj(valuePtr, &length);
			if (bytes != NULL) {
			    memcpy((VOID *) p, (VOID *) bytes,
			            (size_t) length);
			    p += length;
			}
			TclDecrRefCount(valuePtr);
		    }
		    *p = '\0';
		} else {
		    for (i = (stackTop - (opnd-1));  i <= stackTop;  i++) {

			Tcl_DecrRefCount(stackPtr[i]);
		    }
		}
		stackTop -= opnd;
		
		PUSH_OBJECT(concatObjPtr);
		TRACE_WITH_OBJ(("%u => ", opnd), concatObjPtr);
		ADJUST_PC(2);
            }
	    
	case INST_INVOKE_STK4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    pcAdjustment = 5;
	    goto doInvocation;

	case INST_INVOKE_STK1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    pcAdjustment = 2;
	    
	    doInvocation:
	    {


		int objc = opnd; /* The number of arguments. */
		Tcl_Obj **objv;	 /* The array of argument objects. */
		Command *cmdPtr; /* Points to command's Command struct. */
		int newPcOffset; /* New inst offset for break, continue. */




#ifdef TCL_COMPILE_DEBUG
		int isUnknownCmd = 0;
		char cmdNameBuf[21];
#endif /* TCL_COMPILE_DEBUG */
		
		/*
		 * If the interpreter was deleted, return an error.
		 */
		
		if (iPtr->flags & DELETED) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		            "attempt to call eval in deleted interpreter", -1);
		    Tcl_SetErrorCode(interp, "CORE", "IDELETE",
			    "attempt to call eval in deleted interpreter",
			    (char *) NULL);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
    




		/*
		 * Find the procedure to execute this command. If the






		 * command is not found, handle it with the "unknown" proc.

		 */


		objv = &(stackPtr[stackTop - (objc-1)]);
		cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[0]);






		if (cmdPtr == NULL) {
		    cmdPtr = (Command *) Tcl_FindCommand(interp, "unknown",
                            (Tcl_Namespace *) NULL, TCL_GLOBAL_ONLY);
                    if (cmdPtr == NULL) {
			Tcl_ResetResult(interp);
			Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			        "invalid command name \"",
				Tcl_GetString(objv[0]), "\"",
				(char *) NULL);
			TRACE(("%u => unknown proc not found: ", objc));

			result = TCL_ERROR;
			goto checkForCatch;
		    }

#ifdef TCL_COMPILE_DEBUG
		    isUnknownCmd = 1;
#endif /*TCL_COMPILE_DEBUG*/			
		    stackTop++; /* need room for new inserted objv[0] */
		    for (i = objc-1;  i >= 0;  i--) {
			objv[i+1] = objv[i];
		    }
		    objc++;
		    objv[0] = Tcl_NewStringObj("unknown", -1);
		    Tcl_IncrRefCount(objv[0]);
		}
		
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935

936
937
938
939
940
941
942
943
944
945
946
947



948

949
950
951
952
953
954
955
		 * Finally, invoke the command's Tcl_ObjCmdProc. First reset
		 * the interpreter's string and object results to their
		 * default empty values since they could have gotten changed
		 * by earlier invocations.
		 */
		
		Tcl_ResetResult(interp);

		if (tclTraceExec >= 2) {
		    char buffer[50];

		    sprintf(buffer, "%d: (%u) invoking ", iPtr->numLevels,
			    (unsigned int)(pc - codePtr->codeStart));
		    Tcl_DStringAppend(&command, buffer, -1);
		    
#ifdef TCL_COMPILE_DEBUG
		    if (traceInstructions) { /* tclTraceExec == 3 */
			strncpy(cmdNameBuf, cmdName, 20);
			TRACE(("%s %u => call ", opName[opCode],
			       (isUnknownCmd? objc-1 : objc)));
		    } else {
			fprintf(stdout, "%s", buffer);
		    }
#else /* TCL_COMPILE_DEBUG */
		    fprintf(stdout, "%s", buffer);
#endif /*TCL_COMPILE_DEBUG*/


		    for (i = 0;  i < objc;  i++) {
			bytes = TclGetStringFromObj(objv[i], &length);
			TclPrintSource(stdout, bytes, TclMin(length, 15));
			fprintf(stdout, " ");

			sprintf(buffer, "\"%.*s\" ", TclMin(length, 15), bytes);
			Tcl_DStringAppend(&command, buffer, -1);
		    }
		    fprintf(stdout, "\n");
		    fflush(stdout);




		    Tcl_DStringFree(&command);

		}

		iPtr->cmdCount++;
		DECACHE_STACK_INFO();
		result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp,
					    objc, objv);
		if (Tcl_AsyncReady()) {







<

<
<
<
<
<
<

|
|
<
|

|
<
|
<
<
>
|

<
|

<
<
<



|
>
>
>
|
>







810
811
812
813
814
815
816

817






818
819
820

821
822
823

824


825
826
827

828
829



830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
		 * Finally, invoke the command's Tcl_ObjCmdProc. First reset
		 * the interpreter's string and object results to their
		 * default empty values since they could have gotten changed
		 * by earlier invocations.
		 */
		
		Tcl_ResetResult(interp);

		if (tclTraceExec >= 2) {






#ifdef TCL_COMPILE_DEBUG
		    if (traceInstructions) {
			strncpy(cmdNameBuf, Tcl_GetString(objv[0]), 20);

			TRACE(("%u => call ", (isUnknownCmd? objc-1:objc)));
		    } else {
			fprintf(stdout, "%d: (%u) invoking ",

			        iPtr->numLevels,


				(unsigned int)(pc - codePtr->codeStart));
		    }
		    for (i = 0;  i < objc;  i++) {

			TclPrintObject(stdout, objv[i], 15);
			fprintf(stdout, " ");



		    }
		    fprintf(stdout, "\n");
		    fflush(stdout);
#else /* TCL_COMPILE_DEBUG */
		    fprintf(stdout, "%d: (%u) invoking %s\n",
			    iPtr->numLevels,
		            (unsigned int)(pc - codePtr->codeStart),
			    Tcl_GetString(objv[0]));
#endif /*TCL_COMPILE_DEBUG*/
		}

		iPtr->cmdCount++;
		DECACHE_STACK_INFO();
		result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp,
					    objc, objv);
		if (Tcl_AsyncReady()) {
969
970
971
972
973
974
975
976
977
978
979
980
981

982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019

1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074

1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167

1168







1169
1170
1171


1172

1173



1174

1175



1176


1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
		    (void) Tcl_GetObjResult(interp);
		}
		
		/*
		 * Pop the objc top stack elements and decrement their ref
		 * counts. 
		 */
		
		i = (stackTop - (objc-1));
		while (i <= stackTop) {
		    valuePtr = stackPtr[i].o;
		    TclDecrRefCount(valuePtr);
		    i++;

		}
		stackTop -= objc;

		/*
		 * Process the result of the Tcl_ObjCmdProc call.
		 */
		
		switch (result) {
		case TCL_OK:
		    /*
		     * Push the call's object result and continue execution
		     * with the next instruction.
		     */
		    PUSH_OBJECT(Tcl_GetObjResult(interp));
		    TRACE_WITH_OBJ(("%s %u => ...after \"%.20s\", result=",
		            opName[opCode], objc, cmdNameBuf),
			    Tcl_GetObjResult(interp));
		    ADJUST_PC(pcAdjustment);
		    
		case TCL_BREAK:
		case TCL_CONTINUE:
		    /*
		     * The invoked command requested a break or continue.
		     * Find the closest enclosing loop or catch exception
		     * range, if any. If a loop is found, terminate its
		     * execution or skip to its next iteration. If the
		     * closest is a catch exception range, jump to its
		     * catchOffset. If no enclosing range is found, stop
		     * execution and return the TCL_BREAK or TCL_CONTINUE.
		     */
		    rangePtr = TclGetExceptionRangeForPc(pc,
                            /*catchOnly*/ 0, codePtr);
		    if (rangePtr == NULL) {
		        TRACE(("%s %u => ... after \"%.20s\", no encl. loop or catch, returning %s\n",
		                opName[opCode], objc, cmdNameBuf,
			        StringForResultCode(result)));
			goto abnormalReturn; /* no catch exists to check */
		    }

		    switch (rangePtr->type) {
		    case LOOP_EXCEPTION_RANGE:
			if (result == TCL_BREAK) {
			    newPcOffset = rangePtr->breakOffset;
			} else if (rangePtr->continueOffset == -1) {
			    TRACE(("%s %u => ... after \"%.20s\", %s, loop w/o continue, checking for catch\n",
				   opName[opCode], objc, cmdNameBuf,
				   StringForResultCode(result)));
			    goto checkForCatch;
			} else {
			    newPcOffset = rangePtr->continueOffset;
			}
			TRACE(("%s %u => ... after \"%.20s\", %s, range at %d, new pc %d\n",
			       opName[opCode], objc, cmdNameBuf,
			       StringForResultCode(result),
			       rangePtr->codeOffset, newPcOffset));
			break;
		    case CATCH_EXCEPTION_RANGE:
			TRACE(("%s %u => ... after \"%.20s\", %s...\n",
			       opName[opCode], objc, cmdNameBuf,
			       StringForResultCode(result)));
			goto processCatch; /* it will use rangePtr */
		    default:
			panic("TclExecuteByteCode: unrecognized ExceptionRange type %d\n", rangePtr->type);
		    }
		    result = TCL_OK;
		    pc = (codePtr->codeStart + newPcOffset);
		    continue;	/* restart outer instruction loop at pc */
		    
		case TCL_ERROR:
		    /*
		     * The invoked command returned an error. Look for an
		     * enclosing catch exception range, if any.
		     */
		    TRACE_WITH_OBJ(("%s %u => ... after \"%.20s\", TCL_ERROR ",
		            opName[opCode], objc, cmdNameBuf),
			    Tcl_GetObjResult(interp));
		    goto checkForCatch;

		case TCL_RETURN:
		    /*
		     * The invoked command requested that the current
		     * procedure stop execution and return. First check
		     * for an enclosing catch exception range, if any.
		     */
		    TRACE(("%s %u => ... after \"%.20s\", TCL_RETURN\n",
		            opName[opCode], objc, cmdNameBuf));
		    goto checkForCatch;

		default:
		    TRACE_WITH_OBJ(("%s %u => ... after \"%.20s\", OTHER RETURN CODE %d ",
		            opName[opCode], objc, cmdNameBuf, result),
			    Tcl_GetObjResult(interp));
		    goto checkForCatch;
		} /* end of switch on result from invoke instruction */

	    }
	    
	case INST_EVAL_STK:
	    objPtr = POP_OBJECT();
	    DECACHE_STACK_INFO();
	    result = Tcl_EvalObj(interp, objPtr);
	    CACHE_STACK_INFO();
	    if (result == TCL_OK) {
		/*
		 * Normal return; push the eval's object result.
		 */
		
		PUSH_OBJECT(Tcl_GetObjResult(interp));
		TRACE_WITH_OBJ(("evalStk \"%.30s\" => ", O2S(objPtr)),
			Tcl_GetObjResult(interp));
		TclDecrRefCount(objPtr);
		ADJUST_PC(1);
	    } else if ((result == TCL_BREAK) || (result == TCL_CONTINUE)) {
		/*
		 * Find the closest enclosing loop or catch exception range,
		 * if any. If a loop is found, terminate its execution or
		 * skip to its next iteration. If the closest is a catch
		 * exception range, jump to its catchOffset. If no enclosing
		 * range is found, stop execution and return that same
		 * TCL_BREAK or TCL_CONTINUE.
		 */

		int newPcOffset = 0; /* Pc offset computed during break,
				      * continue, error processing. Init.
				      * to avoid compiler warning. */

		rangePtr = TclGetExceptionRangeForPc(pc, /*catchOnly*/ 0,
			codePtr);
		if (rangePtr == NULL) {
		    TRACE(("evalStk \"%.30s\" => no encl. loop or catch, returning %s\n",
			    O2S(objPtr), StringForResultCode(result)));
		    Tcl_DecrRefCount(objPtr);
		    goto abnormalReturn;    /* no catch exists to check */
		}
		switch (rangePtr->type) {
		case LOOP_EXCEPTION_RANGE:
		    if (result == TCL_BREAK) {
			newPcOffset = rangePtr->breakOffset;
		    } else if (rangePtr->continueOffset == -1) {
			TRACE(("evalStk \"%.30s\" => %s, loop w/o continue, checking for catch\n",
			       O2S(objPtr), StringForResultCode(result)));
			Tcl_DecrRefCount(objPtr);
			goto checkForCatch;
		    } else {
			newPcOffset = rangePtr->continueOffset;
		    }
		    result = TCL_OK;
		    TRACE_WITH_OBJ(("evalStk \"%.30s\" => %s, range at %d, new pc %d ",
			    O2S(objPtr), StringForResultCode(result),
			    rangePtr->codeOffset, newPcOffset), valuePtr);
		    break;
		case CATCH_EXCEPTION_RANGE:
		    TRACE_WITH_OBJ(("evalStk \"%.30s\" => %s ",
			    O2S(objPtr), StringForResultCode(result)),
			    valuePtr);
		    Tcl_DecrRefCount(objPtr);
		    goto processCatch;  /* it will use rangePtr */
		default:
		    panic("TclExecuteByteCode: unrecognized ExceptionRange type %d\n", rangePtr->type);
		}
		Tcl_DecrRefCount(objPtr);
		pc = (codePtr->codeStart + newPcOffset);
		continue;	/* restart outer instruction loop at pc */
	    } else { /* eval returned TCL_ERROR, TCL_RETURN, unknown code */
		TRACE_WITH_OBJ(("evalStk \"%.30s\" => ERROR: ", O2S(objPtr)),
		        Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(objPtr);
		goto checkForCatch;
	    }

	case INST_EXPR_STK:
	    objPtr = POP_OBJECT();
	    Tcl_ResetResult(interp);
	    DECACHE_STACK_INFO();
	    result = Tcl_ExprObj(interp, objPtr, &valuePtr);
	    CACHE_STACK_INFO();
	    if (result != TCL_OK) {
		TRACE_WITH_OBJ(("exprStk \"%.30s\" => ERROR: ", 
		        O2S(objPtr)), Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(objPtr);
		goto checkForCatch;
	    }
	    stackPtr[++stackTop].o = valuePtr; /* already has right refct */
	    TRACE_WITH_OBJ(("exprStk \"%.30s\" => ", O2S(objPtr)), valuePtr);
	    TclDecrRefCount(objPtr);
	    ADJUST_PC(1);

	case INST_LOAD_SCALAR4:

	    opnd = TclGetInt4AtPtr(pc+1);







	    pcAdjustment = 5;
	    goto doLoadScalar;



	case INST_LOAD_SCALAR1:

	    opnd = TclGetUInt1AtPtr(pc+1);



	    pcAdjustment = 2;

	    



	    doLoadScalar:


	    DECACHE_STACK_INFO();
	    valuePtr = TclGetIndexedScalar(interp, opnd,
					   /*leaveErrorMsg*/ 1);
	    CACHE_STACK_INFO();
	    if (valuePtr == NULL) {
		TRACE_WITH_OBJ(("%s %u => ERROR: ", opName[opCode], opnd),
			Tcl_GetObjResult(interp));
		result = TCL_ERROR;
		goto checkForCatch;
            }
	    PUSH_OBJECT(valuePtr);
	    TRACE_WITH_OBJ(("%s %u => ", opName[opCode], opnd), valuePtr);
	    ADJUST_PC(pcAdjustment);

	case INST_LOAD_SCALAR_STK:
	    namePtr = POP_OBJECT();
	    DECACHE_STACK_INFO();
	    valuePtr = Tcl_ObjGetVar2(interp, namePtr, (Tcl_Obj *) NULL, 
				      TCL_LEAVE_ERR_MSG);
	    CACHE_STACK_INFO();
	    if (valuePtr == NULL) {
		TRACE_WITH_OBJ(("loadScalarStk \"%.30s\" => ERROR: ",
		        O2S(namePtr)), Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(namePtr);
		result = TCL_ERROR;
		goto checkForCatch;
            }
	    PUSH_OBJECT(valuePtr);
	    TRACE_WITH_OBJ(("loadScalarStk \"%.30s\" => ",
		    O2S(namePtr)), valuePtr);
	    TclDecrRefCount(namePtr);
	    ADJUST_PC(1);

	case INST_LOAD_ARRAY4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    pcAdjustment = 5;
	    goto doLoadArray;

	case INST_LOAD_ARRAY1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    pcAdjustment = 2;
	    
	    doLoadArray:
	    {
		Tcl_Obj *elemPtr = POP_OBJECT();
		
		DECACHE_STACK_INFO();
		valuePtr = TclGetElementOfIndexedArray(interp, opnd,
	                elemPtr, /*leaveErrorMsg*/ 1);
		CACHE_STACK_INFO();
		if (valuePtr == NULL) {
		    TRACE_WITH_OBJ(("%s %u \"%.30s\" => ERROR: ",
			    opName[opCode], opnd, O2S(elemPtr)),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(elemPtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(valuePtr);
		TRACE_WITH_OBJ(("%s %u \"%.30s\" => ",
		        opName[opCode], opnd, O2S(elemPtr)), valuePtr);
		TclDecrRefCount(elemPtr);
	    }
	    ADJUST_PC(pcAdjustment);

	case INST_LOAD_ARRAY_STK:
	    {
		Tcl_Obj *elemPtr = POP_OBJECT();
		
		namePtr = POP_OBJECT();
		DECACHE_STACK_INFO();
		valuePtr = Tcl_ObjGetVar2(interp, namePtr, elemPtr,
		        TCL_LEAVE_ERR_MSG);
		CACHE_STACK_INFO();
		if (valuePtr == NULL) {
		    TRACE_WITH_OBJ(("loadArrayStk \"%.30s(%.30s)\" => ERROR: ",
		            O2S(namePtr), O2S(elemPtr)),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(namePtr);
		    Tcl_DecrRefCount(elemPtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(valuePtr);
		TRACE_WITH_OBJ(("loadArrayStk \"%.30s(%.30s)\" => ",
		        O2S(namePtr), O2S(elemPtr)), valuePtr);
		TclDecrRefCount(namePtr);
		TclDecrRefCount(elemPtr);
	    }
	    ADJUST_PC(1);

	case INST_LOAD_STK:
	    namePtr = POP_OBJECT();
	    DECACHE_STACK_INFO();
	    valuePtr = Tcl_ObjGetVar2(interp, namePtr, NULL,
		    TCL_PARSE_PART1|TCL_LEAVE_ERR_MSG);
	    CACHE_STACK_INFO();
	    if (valuePtr == NULL) {
		TRACE_WITH_OBJ(("loadStk \"%.30s\" => ERROR: ",
		        O2S(namePtr)), Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(namePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(valuePtr);
	    TRACE_WITH_OBJ(("loadStk \"%.30s\" => ", O2S(namePtr)),
		    valuePtr);
	    TclDecrRefCount(namePtr);
	    ADJUST_PC(1);
	    
	case INST_STORE_SCALAR4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    pcAdjustment = 5;
	    goto doStoreScalar;

	case INST_STORE_SCALAR1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    pcAdjustment = 2;
	    
	  doStoreScalar:
	    valuePtr = POP_OBJECT();
	    DECACHE_STACK_INFO();
	    value2Ptr = TclSetIndexedScalar(interp, opnd, valuePtr,
					      /*leaveErrorMsg*/ 1);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("%s %u <- \"%.30s\" => ERROR: ",
			opName[opCode], opnd, O2S(valuePtr)),
			Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(valuePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("%s %u <- \"%.30s\" => ",
		    opName[opCode], opnd, O2S(valuePtr)), value2Ptr);
	    TclDecrRefCount(valuePtr);
	    ADJUST_PC(pcAdjustment);

	case INST_STORE_SCALAR_STK:
	    valuePtr = POP_OBJECT();
	    namePtr = POP_OBJECT();
	    DECACHE_STACK_INFO();
	    value2Ptr = Tcl_ObjSetVar2(interp, namePtr, NULL, valuePtr,
	            TCL_LEAVE_ERR_MSG);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(
			("storeScalarStk \"%.30s\" <- \"%.30s\" => ERROR: ",
		        O2S(namePtr), O2S(valuePtr)),
			Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(namePtr);
		Tcl_DecrRefCount(valuePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(
		    ("storeScalarStk \"%.30s\" <- \"%.30s\" => ",
		    O2S(namePtr),
		    O2S(valuePtr)),
		    value2Ptr);
	    TclDecrRefCount(namePtr);
	    TclDecrRefCount(valuePtr);
	    ADJUST_PC(1);

	case INST_STORE_ARRAY4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    pcAdjustment = 5;
	    goto doStoreArray;







|
<
|
|

<
>

<












|
<
|













|
|

|
|



>





|
|





|
|




|
|



|










|
<
|








|
|



|
|


<
>





|





<

|

















|


|









|







|




|











|












|




|
|



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





|
|




|
|


|

|
<


|
|
|




<
|
|




















|
<
|





|
|








|

|



|
|

|





|
|
|





|

|
<


|
|
|




|
<
|















|


|
<
|





|
|





|

|
|


|
<
|

|





|
<
<
|
<
|







859
860
861
862
863
864
865
866

867
868
869

870
871

872
873
874
875
876
877
878
879
880
881
882
883
884

885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942

943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960

961
962
963
964
965
966
967
968
969
970
971
972

973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100

1101
1102
1103
1104
1105
1106
1107
1108
1109

1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132

1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174

1175
1176
1177
1178
1179
1180
1181
1182
1183
1184

1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204

1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224

1225
1226
1227
1228
1229
1230
1231
1232
1233


1234

1235
1236
1237
1238
1239
1240
1241
1242
		    (void) Tcl_GetObjResult(interp);
		}
		
		/*
		 * Pop the objc top stack elements and decrement their ref
		 * counts. 
		 */


		for (i = 0;  i < objc;  i++) {
		    valuePtr = stackPtr[stackTop];
		    TclDecrRefCount(valuePtr);

		    stackTop--;
		}


		/*
		 * Process the result of the Tcl_ObjCmdProc call.
		 */
		
		switch (result) {
		case TCL_OK:
		    /*
		     * Push the call's object result and continue execution
		     * with the next instruction.
		     */
		    PUSH_OBJECT(Tcl_GetObjResult(interp));
		    TRACE_WITH_OBJ(("%u => ...after \"%.20s\", result=",

		            objc, cmdNameBuf), Tcl_GetObjResult(interp));
		    ADJUST_PC(pcAdjustment);
		    
		case TCL_BREAK:
		case TCL_CONTINUE:
		    /*
		     * The invoked command requested a break or continue.
		     * Find the closest enclosing loop or catch exception
		     * range, if any. If a loop is found, terminate its
		     * execution or skip to its next iteration. If the
		     * closest is a catch exception range, jump to its
		     * catchOffset. If no enclosing range is found, stop
		     * execution and return the TCL_BREAK or TCL_CONTINUE.
		     */
		    rangePtr = GetExceptRangeForPc(pc, /*catchOnly*/ 0,
			    codePtr);
		    if (rangePtr == NULL) {
		        TRACE(("%u => ... after \"%.20s\", no encl. loop or catch, returning %s\n",
		                objc, cmdNameBuf,
			        StringForResultCode(result)));
			goto abnormalReturn; /* no catch exists to check */
		    }
		    newPcOffset = 0;
		    switch (rangePtr->type) {
		    case LOOP_EXCEPTION_RANGE:
			if (result == TCL_BREAK) {
			    newPcOffset = rangePtr->breakOffset;
			} else if (rangePtr->continueOffset == -1) {
			    TRACE(("%u => ... after \"%.20s\", %s, loop w/o continue, checking for catch\n",
				   objc, cmdNameBuf,
				   StringForResultCode(result)));
			    goto checkForCatch;
			} else {
			    newPcOffset = rangePtr->continueOffset;
			}
			TRACE(("%u => ... after \"%.20s\", %s, range at %d, new pc %d\n",
			       objc, cmdNameBuf,
			       StringForResultCode(result),
			       rangePtr->codeOffset, newPcOffset));
			break;
		    case CATCH_EXCEPTION_RANGE:
			TRACE(("%u => ... after \"%.20s\", %s...\n",
			       objc, cmdNameBuf,
			       StringForResultCode(result)));
			goto processCatch; /* it will use rangePtr */
		    default:
			panic("TclExecuteByteCode: bad ExceptionRange type\n");
		    }
		    result = TCL_OK;
		    pc = (codePtr->codeStart + newPcOffset);
		    continue;	/* restart outer instruction loop at pc */
		    
		case TCL_ERROR:
		    /*
		     * The invoked command returned an error. Look for an
		     * enclosing catch exception range, if any.
		     */
		    TRACE_WITH_OBJ(("%u => ... after \"%.20s\", TCL_ERROR ",

		            objc, cmdNameBuf), Tcl_GetObjResult(interp));
		    goto checkForCatch;

		case TCL_RETURN:
		    /*
		     * The invoked command requested that the current
		     * procedure stop execution and return. First check
		     * for an enclosing catch exception range, if any.
		     */
		    TRACE(("%u => ... after \"%.20s\", TCL_RETURN\n",
		            objc, cmdNameBuf));
		    goto checkForCatch;

		default:
		    TRACE_WITH_OBJ(("%u => ... after \"%.20s\", OTHER RETURN CODE %d ",
		            objc, cmdNameBuf, result),
			    Tcl_GetObjResult(interp));
		    goto checkForCatch;

		}
	    }
	    
	case INST_EVAL_STK:
	    objPtr = POP_OBJECT();
	    DECACHE_STACK_INFO();
	    result = Tcl_EvalObjEx(interp, objPtr, 0);
	    CACHE_STACK_INFO();
	    if (result == TCL_OK) {
		/*
		 * Normal return; push the eval's object result.
		 */

		PUSH_OBJECT(Tcl_GetObjResult(interp));
		TRACE_WITH_OBJ(("\"%.30s\" => ", O2S(objPtr)),
			Tcl_GetObjResult(interp));
		TclDecrRefCount(objPtr);
		ADJUST_PC(1);
	    } else if ((result == TCL_BREAK) || (result == TCL_CONTINUE)) {
		/*
		 * Find the closest enclosing loop or catch exception range,
		 * if any. If a loop is found, terminate its execution or
		 * skip to its next iteration. If the closest is a catch
		 * exception range, jump to its catchOffset. If no enclosing
		 * range is found, stop execution and return that same
		 * TCL_BREAK or TCL_CONTINUE.
		 */

		int newPcOffset = 0; /* Pc offset computed during break,
				      * continue, error processing. Init.
				      * to avoid compiler warning. */

		rangePtr = GetExceptRangeForPc(pc, /*catchOnly*/ 0,
			codePtr);
		if (rangePtr == NULL) {
		    TRACE(("\"%.30s\" => no encl. loop or catch, returning %s\n",
			    O2S(objPtr), StringForResultCode(result)));
		    Tcl_DecrRefCount(objPtr);
		    goto abnormalReturn;    /* no catch exists to check */
		}
		switch (rangePtr->type) {
		case LOOP_EXCEPTION_RANGE:
		    if (result == TCL_BREAK) {
			newPcOffset = rangePtr->breakOffset;
		    } else if (rangePtr->continueOffset == -1) {
			TRACE(("\"%.30s\" => %s, loop w/o continue, checking for catch\n",
			       O2S(objPtr), StringForResultCode(result)));
			Tcl_DecrRefCount(objPtr);
			goto checkForCatch;
		    } else {
			newPcOffset = rangePtr->continueOffset;
		    }
		    result = TCL_OK;
		    TRACE_WITH_OBJ(("\"%.30s\" => %s, range at %d, new pc %d ",
			    O2S(objPtr), StringForResultCode(result),
			    rangePtr->codeOffset, newPcOffset), valuePtr);
		    break;
		case CATCH_EXCEPTION_RANGE:
		    TRACE_WITH_OBJ(("\"%.30s\" => %s ",
			    O2S(objPtr), StringForResultCode(result)),
			    valuePtr);
		    Tcl_DecrRefCount(objPtr);
		    goto processCatch;  /* it will use rangePtr */
		default:
		    panic("TclExecuteByteCode: unrecognized ExceptionRange type %d\n", rangePtr->type);
		}
		Tcl_DecrRefCount(objPtr);
		pc = (codePtr->codeStart + newPcOffset);
		continue;	/* restart outer instruction loop at pc */
	    } else { /* eval returned TCL_ERROR, TCL_RETURN, unknown code */
		TRACE_WITH_OBJ(("\"%.30s\" => ERROR: ", O2S(objPtr)),
		        Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(objPtr);
		goto checkForCatch;
	    }

	case INST_EXPR_STK:
	    objPtr = POP_OBJECT();
	    Tcl_ResetResult(interp);
	    DECACHE_STACK_INFO();
	    result = Tcl_ExprObj(interp, objPtr, &valuePtr);
	    CACHE_STACK_INFO();
	    if (result != TCL_OK) {
		TRACE_WITH_OBJ(("\"%.30s\" => ERROR: ", 
		        O2S(objPtr)), Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(objPtr);
		goto checkForCatch;
	    }
	    stackPtr[++stackTop] = valuePtr; /* already has right refct */
	    TRACE_WITH_OBJ(("\"%.30s\" => ", O2S(objPtr)), valuePtr);
	    TclDecrRefCount(objPtr);
	    ADJUST_PC(1);

	case INST_LOAD_SCALAR1:
#ifdef TCL_COMPILE_DEBUG
	    opnd = TclGetInt1AtPtr(pc+1);
	    DECACHE_STACK_INFO();
	    valuePtr = TclGetIndexedScalar(interp, opnd,
		    /*leaveErrorMsg*/ 1);
	    CACHE_STACK_INFO();
	    if (valuePtr == NULL) {
		TRACE_WITH_OBJ(("%u => ERROR: ", opnd),
		        Tcl_GetObjResult(interp));
		result = TCL_ERROR;
		goto checkForCatch;
            }
	    PUSH_OBJECT(valuePtr);
	    TRACE_WITH_OBJ(("%u => ", opnd), valuePtr);
#else /* TCL_COMPILE_DEBUG */
	    DECACHE_STACK_INFO();
	    valuePtr = TclGetIndexedScalar(interp, TclGetInt1AtPtr(pc+1),
	            /*leaveErrorMsg*/ 1);
	    CACHE_STACK_INFO();
	    if (valuePtr == NULL) {
		result = TCL_ERROR;
		goto checkForCatch;
            }
	    PUSH_OBJECT(valuePtr);
#endif /* TCL_COMPILE_DEBUG */
	    ADJUST_PC(2);

	case INST_LOAD_SCALAR4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    DECACHE_STACK_INFO();
	    valuePtr = TclGetIndexedScalar(interp, opnd,
					   /*leaveErrorMsg*/ 1);
	    CACHE_STACK_INFO();
	    if (valuePtr == NULL) {
		TRACE_WITH_OBJ(("%u => ERROR: ", opnd),
		        Tcl_GetObjResult(interp));
		result = TCL_ERROR;
		goto checkForCatch;
            }
	    PUSH_OBJECT(valuePtr);
	    TRACE_WITH_OBJ(("%u => ", opnd), valuePtr);
	    ADJUST_PC(5);

	case INST_LOAD_SCALAR_STK:
	    objPtr = POP_OBJECT(); /* scalar name */
	    DECACHE_STACK_INFO();
	    valuePtr = Tcl_ObjGetVar2(interp, objPtr, NULL, TCL_LEAVE_ERR_MSG);

	    CACHE_STACK_INFO();
	    if (valuePtr == NULL) {
		TRACE_WITH_OBJ(("\"%.30s\" => ERROR: ", O2S(objPtr)),
		        Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(objPtr);
		result = TCL_ERROR;
		goto checkForCatch;
            }
	    PUSH_OBJECT(valuePtr);

	    TRACE_WITH_OBJ(("\"%.30s\" => ", O2S(objPtr)), valuePtr);
	    TclDecrRefCount(objPtr);
	    ADJUST_PC(1);

	case INST_LOAD_ARRAY4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    pcAdjustment = 5;
	    goto doLoadArray;

	case INST_LOAD_ARRAY1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    pcAdjustment = 2;
	    
	    doLoadArray:
	    {
		Tcl_Obj *elemPtr = POP_OBJECT();
		
		DECACHE_STACK_INFO();
		valuePtr = TclGetElementOfIndexedArray(interp, opnd,
	                elemPtr, /*leaveErrorMsg*/ 1);
		CACHE_STACK_INFO();
		if (valuePtr == NULL) {
		    TRACE_WITH_OBJ(("%u \"%.30s\" => ERROR: ",

			    opnd, O2S(elemPtr)), Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(elemPtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(valuePtr);
		TRACE_WITH_OBJ(("%u \"%.30s\" => ",
		        opnd, O2S(elemPtr)),valuePtr);
		TclDecrRefCount(elemPtr);
	    }
	    ADJUST_PC(pcAdjustment);

	case INST_LOAD_ARRAY_STK:
	    {
		Tcl_Obj *elemPtr = POP_OBJECT();
		
		objPtr = POP_OBJECT();	/* array name */
		DECACHE_STACK_INFO();
		valuePtr = Tcl_ObjGetVar2(interp, objPtr, elemPtr,
		        TCL_LEAVE_ERR_MSG);
		CACHE_STACK_INFO();
		if (valuePtr == NULL) {
		    TRACE_WITH_OBJ(("\"%.30s(%.30s)\" => ERROR: ",
		            O2S(objPtr), O2S(elemPtr)),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(objPtr);
		    Tcl_DecrRefCount(elemPtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(valuePtr);
		TRACE_WITH_OBJ(("\"%.30s(%.30s)\" => ",
		        O2S(objPtr), O2S(elemPtr)), valuePtr);
		TclDecrRefCount(objPtr);
		TclDecrRefCount(elemPtr);
	    }
	    ADJUST_PC(1);

	case INST_LOAD_STK:
	    objPtr = POP_OBJECT(); /* variable name */
	    DECACHE_STACK_INFO();
	    valuePtr = Tcl_ObjGetVar2(interp, objPtr, NULL, TCL_LEAVE_ERR_MSG);

	    CACHE_STACK_INFO();
	    if (valuePtr == NULL) {
		TRACE_WITH_OBJ(("\"%.30s\" => ERROR: ",
		        O2S(objPtr)), Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(objPtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(valuePtr);
	    TRACE_WITH_OBJ(("\"%.30s\" => ", O2S(objPtr)), valuePtr);

	    TclDecrRefCount(objPtr);
	    ADJUST_PC(1);
	    
	case INST_STORE_SCALAR4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    pcAdjustment = 5;
	    goto doStoreScalar;

	case INST_STORE_SCALAR1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    pcAdjustment = 2;
	    
	  doStoreScalar:
	    valuePtr = POP_OBJECT();
	    DECACHE_STACK_INFO();
	    value2Ptr = TclSetIndexedScalar(interp, opnd, valuePtr,
	            /*leaveErrorMsg*/ 1);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("%u <- \"%.30s\" => ERROR: ",

			opnd, O2S(valuePtr)), Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(valuePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("%u <- \"%.30s\" => ",
		    opnd, O2S(valuePtr)), value2Ptr);
	    TclDecrRefCount(valuePtr);
	    ADJUST_PC(pcAdjustment);

	case INST_STORE_SCALAR_STK:
	    valuePtr = POP_OBJECT();
	    objPtr = POP_OBJECT(); /* scalar name */
	    DECACHE_STACK_INFO();
	    value2Ptr = Tcl_ObjSetVar2(interp, objPtr, NULL, valuePtr,
		    TCL_LEAVE_ERR_MSG);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("\"%.30s\" <- \"%.30s\" => ERROR: ",

		        O2S(objPtr), O2S(valuePtr)),
			Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(objPtr);
		Tcl_DecrRefCount(valuePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("\"%.30s\" <- \"%.30s\" => ",


		    O2S(objPtr), O2S(valuePtr)), value2Ptr);

	    TclDecrRefCount(objPtr);
	    TclDecrRefCount(valuePtr);
	    ADJUST_PC(1);

	case INST_STORE_ARRAY4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    pcAdjustment = 5;
	    goto doStoreArray;
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676

1677
1678
1679
1680




1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
		valuePtr = POP_OBJECT();
		elemPtr = POP_OBJECT();
		DECACHE_STACK_INFO();
		value2Ptr = TclSetElementOfIndexedArray(interp, opnd,
		        elemPtr, valuePtr, TCL_LEAVE_ERR_MSG);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(
			    ("%s %u \"%.30s\" <- \"%.30s\" => ERROR: ",
			    opName[opCode], opnd, O2S(elemPtr),
			    O2S(valuePtr)), Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(elemPtr);
		    Tcl_DecrRefCount(valuePtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("%s %u \"%.30s\" <- \"%.30s\" => ",
		        opName[opCode], opnd, O2S(elemPtr), O2S(valuePtr)),
		        value2Ptr);
		TclDecrRefCount(elemPtr);
		TclDecrRefCount(valuePtr);
	    }
	    ADJUST_PC(pcAdjustment);

	case INST_STORE_ARRAY_STK:
	    {
		Tcl_Obj *elemPtr;

		valuePtr = POP_OBJECT();
		elemPtr = POP_OBJECT();
		namePtr = POP_OBJECT();
		DECACHE_STACK_INFO();
		value2Ptr = Tcl_ObjSetVar2(interp, namePtr, elemPtr,
		        valuePtr, TCL_LEAVE_ERR_MSG);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(("storeArrayStk \"%.30s(%.30s)\" <- \"%.30s\" => ERROR: ",
		            O2S(namePtr), O2S(elemPtr), O2S(valuePtr)),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(namePtr);
		    Tcl_DecrRefCount(elemPtr);
		    Tcl_DecrRefCount(valuePtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("storeArrayStk \"%.30s(%.30s)\" <- \"%.30s\" => ",
		        O2S(namePtr), O2S(elemPtr), O2S(valuePtr)),
			value2Ptr);
		TclDecrRefCount(namePtr);
		TclDecrRefCount(elemPtr);
		TclDecrRefCount(valuePtr);
	    }
	    ADJUST_PC(1);

	case INST_STORE_STK:
	    valuePtr = POP_OBJECT();
	    namePtr = POP_OBJECT();
	    DECACHE_STACK_INFO();
	    value2Ptr = Tcl_ObjSetVar2(interp, namePtr, NULL, valuePtr,
		    TCL_PARSE_PART1|TCL_LEAVE_ERR_MSG);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("storeStk \"%.30s\" <- \"%.30s\" => ERROR: ",
		        O2S(namePtr), O2S(valuePtr)),
			Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(namePtr);
		Tcl_DecrRefCount(valuePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("storeStk \"%.30s\" <- \"%.30s\" => ",
		    O2S(namePtr), O2S(valuePtr)), value2Ptr);
	    TclDecrRefCount(namePtr);
	    TclDecrRefCount(valuePtr);
	    ADJUST_PC(1);

	case INST_INCR_SCALAR1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    valuePtr = POP_OBJECT(); 
	    if (valuePtr->typePtr != &tclIntType) {
		result = tclIntType.setFromAnyProc(interp, valuePtr);
		if (result != TCL_OK) {
		    TRACE_WITH_OBJ(("incrScalar1 %u (by %s) => ERROR converting increment amount to int: ",
		            opnd, O2S(valuePtr)), Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(valuePtr);
		    goto checkForCatch;
		}
	    }
	    i = valuePtr->internalRep.longValue;
	    DECACHE_STACK_INFO();
	    value2Ptr = TclIncrIndexedScalar(interp, opnd, i);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("incrScalar1 %u (by %ld) => ERROR: ",
		        opnd, i), Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(valuePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("incrScalar1 %u (by %ld) => ", opnd, i),
		    value2Ptr);
	    TclDecrRefCount(valuePtr);
	    ADJUST_PC(2);

	case INST_INCR_SCALAR_STK:
	case INST_INCR_STK:
	    valuePtr = POP_OBJECT();
	    namePtr = POP_OBJECT();
	    if (valuePtr->typePtr != &tclIntType) {
		result = tclIntType.setFromAnyProc(interp, valuePtr);
		if (result != TCL_OK) {
		    TRACE_WITH_OBJ(("%s \"%.30s\" (by %s) => ERROR converting increment amount to int: ",
		            opName[opCode], O2S(namePtr), O2S(valuePtr)),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(namePtr);
		    Tcl_DecrRefCount(valuePtr);
		    goto checkForCatch;
		}
	    }
	    i = valuePtr->internalRep.longValue;
	    DECACHE_STACK_INFO();
	    value2Ptr = TclIncrVar2(interp, namePtr, (Tcl_Obj *) NULL, i,
	        /*part1NotParsed*/ (opCode == INST_INCR_STK));
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("%s \"%.30s\" (by %ld) => ERROR: ",
		        opName[opCode], O2S(namePtr), i),
			Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(namePtr);
		Tcl_DecrRefCount(valuePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("%s \"%.30s\" (by %ld) => ",
	            opName[opCode], O2S(namePtr), i), value2Ptr);
	    Tcl_DecrRefCount(namePtr);
	    Tcl_DecrRefCount(valuePtr);
	    ADJUST_PC(1);

	case INST_INCR_ARRAY1:
	    {
		Tcl_Obj *elemPtr;

		opnd = TclGetUInt1AtPtr(pc+1);
		valuePtr = POP_OBJECT();
		elemPtr = POP_OBJECT();
		if (valuePtr->typePtr != &tclIntType) {
		    result = tclIntType.setFromAnyProc(interp, valuePtr);
		    if (result != TCL_OK) {
			TRACE_WITH_OBJ(("incrArray1 %u \"%.30s\" (by %s) => ERROR converting increment amount to int: ",
		                opnd, O2S(elemPtr), O2S(valuePtr)),
			        Tcl_GetObjResult(interp));
			Tcl_DecrRefCount(elemPtr);
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		}
		i = valuePtr->internalRep.longValue;
		DECACHE_STACK_INFO();
		value2Ptr = TclIncrElementOfIndexedArray(interp, opnd,
		        elemPtr, i);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(("incrArray1 %u \"%.30s\" (by %ld) => ERROR: ",
		            opnd, O2S(elemPtr), i),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(elemPtr);
		    Tcl_DecrRefCount(valuePtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("incrArray1 %u \"%.30s\" (by %ld) => ",
	                opnd, O2S(elemPtr), i), value2Ptr);
		Tcl_DecrRefCount(elemPtr);
		Tcl_DecrRefCount(valuePtr);
	    }
	    ADJUST_PC(2);
	    
	case INST_INCR_ARRAY_STK:
	    {
		Tcl_Obj *elemPtr;

		valuePtr = POP_OBJECT();
		elemPtr = POP_OBJECT();
		namePtr = POP_OBJECT();
		if (valuePtr->typePtr != &tclIntType) {
		    result = tclIntType.setFromAnyProc(interp, valuePtr);
		    if (result != TCL_OK) {
		        TRACE_WITH_OBJ(("incrArrayStk \"%.30s(%.30s)\" (by %s) => ERROR converting increment amount to int: ",
		                O2S(namePtr), O2S(elemPtr), O2S(valuePtr)),
			        Tcl_GetObjResult(interp));
			Tcl_DecrRefCount(namePtr);
			Tcl_DecrRefCount(elemPtr);
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		}
		i = valuePtr->internalRep.longValue;
		DECACHE_STACK_INFO();
		value2Ptr = TclIncrVar2(interp, namePtr, elemPtr, i,
					/*part1NotParsed*/ 0);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(("incrArrayStk \"%.30s(%.30s)\" (by %ld) => ERROR: ",
		            O2S(namePtr), O2S(elemPtr), i),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(namePtr);
		    Tcl_DecrRefCount(elemPtr);
		    Tcl_DecrRefCount(valuePtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("incrArrayStk \"%.30s(%.30s)\" (by %ld) => ",
	                O2S(namePtr), O2S(elemPtr), i), value2Ptr);
		Tcl_DecrRefCount(namePtr);
		Tcl_DecrRefCount(elemPtr);
		Tcl_DecrRefCount(valuePtr);
	    }
	    ADJUST_PC(1);
	    
	case INST_INCR_SCALAR1_IMM:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    i = TclGetInt1AtPtr(pc+2);
	    DECACHE_STACK_INFO();
	    value2Ptr = TclIncrIndexedScalar(interp, opnd, i);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("incrScalar1Imm %u %ld => ERROR: ",
		        opnd, i), Tcl_GetObjResult(interp));
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("incrScalar1Imm %u %ld => ", opnd, i),
		    value2Ptr);
	    ADJUST_PC(3);

	case INST_INCR_SCALAR_STK_IMM:
	case INST_INCR_STK_IMM:
	    namePtr = POP_OBJECT();
	    i = TclGetInt1AtPtr(pc+1);
	    DECACHE_STACK_INFO();
	    value2Ptr = TclIncrVar2(interp, namePtr, (Tcl_Obj *) NULL, i,
		    /*part1NotParsed*/ (opCode == INST_INCR_STK_IMM));
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("%s \"%.30s\" %ld => ERROR: ",
		        opName[opCode], O2S(namePtr), i),
			Tcl_GetObjResult(interp));
		result = TCL_ERROR;
		Tcl_DecrRefCount(namePtr);
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("%s \"%.30s\" %ld => ",
	            opName[opCode], O2S(namePtr), i), value2Ptr);
	    TclDecrRefCount(namePtr);
	    ADJUST_PC(2);

	case INST_INCR_ARRAY1_IMM:
	    {
		Tcl_Obj *elemPtr;

		opnd = TclGetUInt1AtPtr(pc+1);
		i = TclGetInt1AtPtr(pc+2);
		elemPtr = POP_OBJECT();
		DECACHE_STACK_INFO();
		value2Ptr = TclIncrElementOfIndexedArray(interp, opnd,
		        elemPtr, i);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(("incrArray1Imm %u \"%.30s\" (by %ld) => ERROR: ",
		            opnd, O2S(elemPtr), i),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(elemPtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("incrArray1Imm %u \"%.30s\" (by %ld) => ",
	                opnd, O2S(elemPtr), i), value2Ptr);
		Tcl_DecrRefCount(elemPtr);
	    }
	    ADJUST_PC(3);
	    
	case INST_INCR_ARRAY_STK_IMM:
	    {
		Tcl_Obj *elemPtr;

		i = TclGetInt1AtPtr(pc+1);
		elemPtr = POP_OBJECT();
		namePtr = POP_OBJECT();
		DECACHE_STACK_INFO();
		value2Ptr = TclIncrVar2(interp, namePtr, elemPtr, i,
		        /*part1NotParsed*/ 0);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(("incrArrayStkImm \"%.30s(%.30s)\" (by %ld) => ERROR: ",
		            O2S(namePtr), O2S(elemPtr), i),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(namePtr);
		    Tcl_DecrRefCount(elemPtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("incrArrayStkImm \"%.30s(%.30s)\" (by %ld) => ",
	                O2S(namePtr), O2S(elemPtr), i), value2Ptr);
		Tcl_DecrRefCount(namePtr);
		Tcl_DecrRefCount(elemPtr);
	    }
	    ADJUST_PC(2);

	case INST_JUMP1:

	    opnd = TclGetInt1AtPtr(pc+1);
	    TRACE(("jump1 %d => new pc %u\n", opnd,
		   (unsigned int)(pc + opnd - codePtr->codeStart)));
	    ADJUST_PC(opnd);





	case INST_JUMP4:
	    opnd = TclGetInt4AtPtr(pc+1);
	    TRACE(("jump4 %d => new pc %u\n", opnd,
		   (unsigned int)(pc + opnd - codePtr->codeStart)));
	    ADJUST_PC(opnd);

	case INST_JUMP_TRUE4:
	    opnd = TclGetInt4AtPtr(pc+1);
	    pcAdjustment = 5;
	    goto doJumpTrue;







<
|
|
|






|
|
<











|

|
|


|
|

|






|
|

|







|

|
|


|
|

|





|
|
|









|










|
|





|
<






|



|
|

|






|
|


|
<
|
|





|
|
|













|













|








|












|



|
|

|







|
|


|
|

|






|
|
|












|
|




|
<




|


|
|


|
<
|

|



|
|
|














|







|











|

|
|


|
|

|





|
|
|





>

|

|
>
>
>
>



|







1252
1253
1254
1255
1256
1257
1258

1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353

1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378

1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500

1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
		valuePtr = POP_OBJECT();
		elemPtr = POP_OBJECT();
		DECACHE_STACK_INFO();
		value2Ptr = TclSetElementOfIndexedArray(interp, opnd,
		        elemPtr, valuePtr, TCL_LEAVE_ERR_MSG);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {

		    TRACE_WITH_OBJ(("%u \"%.30s\" <- \"%.30s\" => ERROR: ",
			    opnd, O2S(elemPtr), O2S(valuePtr)),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(elemPtr);
		    Tcl_DecrRefCount(valuePtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("%u \"%.30s\" <- \"%.30s\" => ",
		        opnd, O2S(elemPtr), O2S(valuePtr)), value2Ptr);

		TclDecrRefCount(elemPtr);
		TclDecrRefCount(valuePtr);
	    }
	    ADJUST_PC(pcAdjustment);

	case INST_STORE_ARRAY_STK:
	    {
		Tcl_Obj *elemPtr;

		valuePtr = POP_OBJECT();
		elemPtr = POP_OBJECT();
		objPtr = POP_OBJECT();	/* array name */
		DECACHE_STACK_INFO();
		value2Ptr = Tcl_ObjSetVar2(interp, objPtr, elemPtr, valuePtr,
			TCL_LEAVE_ERR_MSG);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <- \"%.30s\" => ERROR: ",
		            O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(objPtr);
		    Tcl_DecrRefCount(elemPtr);
		    Tcl_DecrRefCount(valuePtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("\"%.30s(%.30s)\" <- \"%.30s\" => ",
		        O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
			value2Ptr);
		TclDecrRefCount(objPtr);
		TclDecrRefCount(elemPtr);
		TclDecrRefCount(valuePtr);
	    }
	    ADJUST_PC(1);

	case INST_STORE_STK:
	    valuePtr = POP_OBJECT();
	    objPtr = POP_OBJECT(); /* variable name */
	    DECACHE_STACK_INFO();
	    value2Ptr = Tcl_ObjSetVar2(interp, objPtr, NULL, valuePtr,
		    TCL_LEAVE_ERR_MSG);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("\"%.30s\" <- \"%.30s\" => ERROR: ",
		        O2S(objPtr), O2S(valuePtr)),
			Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(objPtr);
		Tcl_DecrRefCount(valuePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("\"%.30s\" <- \"%.30s\" => ",
		    O2S(objPtr), O2S(valuePtr)), value2Ptr);
	    TclDecrRefCount(objPtr);
	    TclDecrRefCount(valuePtr);
	    ADJUST_PC(1);

	case INST_INCR_SCALAR1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    valuePtr = POP_OBJECT(); 
	    if (valuePtr->typePtr != &tclIntType) {
		result = tclIntType.setFromAnyProc(interp, valuePtr);
		if (result != TCL_OK) {
		    TRACE_WITH_OBJ(("%u (by %s) => ERROR converting increment amount to int: ",
		            opnd, O2S(valuePtr)), Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(valuePtr);
		    goto checkForCatch;
		}
	    }
	    i = valuePtr->internalRep.longValue;
	    DECACHE_STACK_INFO();
	    value2Ptr = TclIncrIndexedScalar(interp, opnd, i);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("%u (by %ld) => ERROR: ", opnd, i),
			Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(valuePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("%u (by %ld) => ", opnd, i), value2Ptr);

	    TclDecrRefCount(valuePtr);
	    ADJUST_PC(2);

	case INST_INCR_SCALAR_STK:
	case INST_INCR_STK:
	    valuePtr = POP_OBJECT();
	    objPtr = POP_OBJECT(); /* scalar name */
	    if (valuePtr->typePtr != &tclIntType) {
		result = tclIntType.setFromAnyProc(interp, valuePtr);
		if (result != TCL_OK) {
		    TRACE_WITH_OBJ(("\"%.30s\" (by %s) => ERROR converting increment amount to int: ",
		            O2S(objPtr), O2S(valuePtr)),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(objPtr);
		    Tcl_DecrRefCount(valuePtr);
		    goto checkForCatch;
		}
	    }
	    i = valuePtr->internalRep.longValue;
	    DECACHE_STACK_INFO();
	    value2Ptr = TclIncrVar2(interp, objPtr, (Tcl_Obj *) NULL, i,
		    TCL_LEAVE_ERR_MSG);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("\"%.30s\" (by %ld) => ERROR: ",

		        O2S(objPtr), i), Tcl_GetObjResult(interp));
		Tcl_DecrRefCount(objPtr);
		Tcl_DecrRefCount(valuePtr);
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("\"%.30s\" (by %ld) => ", O2S(objPtr), i),
		    value2Ptr);
	    Tcl_DecrRefCount(objPtr);
	    Tcl_DecrRefCount(valuePtr);
	    ADJUST_PC(1);

	case INST_INCR_ARRAY1:
	    {
		Tcl_Obj *elemPtr;

		opnd = TclGetUInt1AtPtr(pc+1);
		valuePtr = POP_OBJECT();
		elemPtr = POP_OBJECT();
		if (valuePtr->typePtr != &tclIntType) {
		    result = tclIntType.setFromAnyProc(interp, valuePtr);
		    if (result != TCL_OK) {
			TRACE_WITH_OBJ(("%u \"%.30s\" (by %s) => ERROR converting increment amount to int: ",
		                opnd, O2S(elemPtr), O2S(valuePtr)),
			        Tcl_GetObjResult(interp));
			Tcl_DecrRefCount(elemPtr);
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		}
		i = valuePtr->internalRep.longValue;
		DECACHE_STACK_INFO();
		value2Ptr = TclIncrElementOfIndexedArray(interp, opnd,
		        elemPtr, i);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(("%u \"%.30s\" (by %ld) => ERROR: ",
		            opnd, O2S(elemPtr), i),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(elemPtr);
		    Tcl_DecrRefCount(valuePtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("%u \"%.30s\" (by %ld) => ",
	                opnd, O2S(elemPtr), i), value2Ptr);
		Tcl_DecrRefCount(elemPtr);
		Tcl_DecrRefCount(valuePtr);
	    }
	    ADJUST_PC(2);
	    
	case INST_INCR_ARRAY_STK:
	    {
		Tcl_Obj *elemPtr;

		valuePtr = POP_OBJECT();
		elemPtr = POP_OBJECT();
		objPtr = POP_OBJECT();	/* array name */
		if (valuePtr->typePtr != &tclIntType) {
		    result = tclIntType.setFromAnyProc(interp, valuePtr);
		    if (result != TCL_OK) {
		        TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %s) => ERROR converting increment amount to int: ",
		                O2S(objPtr), O2S(elemPtr), O2S(valuePtr)),
			        Tcl_GetObjResult(interp));
			Tcl_DecrRefCount(objPtr);
			Tcl_DecrRefCount(elemPtr);
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		}
		i = valuePtr->internalRep.longValue;
		DECACHE_STACK_INFO();
		value2Ptr = TclIncrVar2(interp, objPtr, elemPtr, i,
			TCL_LEAVE_ERR_MSG);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %ld) => ERROR: ",
		            O2S(objPtr), O2S(elemPtr), i),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(objPtr);
		    Tcl_DecrRefCount(elemPtr);
		    Tcl_DecrRefCount(valuePtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %ld) => ",
	                O2S(objPtr), O2S(elemPtr), i), value2Ptr);
		Tcl_DecrRefCount(objPtr);
		Tcl_DecrRefCount(elemPtr);
		Tcl_DecrRefCount(valuePtr);
	    }
	    ADJUST_PC(1);
	    
	case INST_INCR_SCALAR1_IMM:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    i = TclGetInt1AtPtr(pc+2);
	    DECACHE_STACK_INFO();
	    value2Ptr = TclIncrIndexedScalar(interp, opnd, i);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("%u %ld => ERROR: ", opnd, i),
			Tcl_GetObjResult(interp));
		result = TCL_ERROR;
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("%u %ld => ", opnd, i), value2Ptr);

	    ADJUST_PC(3);

	case INST_INCR_SCALAR_STK_IMM:
	case INST_INCR_STK_IMM:
	    objPtr = POP_OBJECT(); /* variable name */
	    i = TclGetInt1AtPtr(pc+1);
	    DECACHE_STACK_INFO();
	    value2Ptr = TclIncrVar2(interp, objPtr, (Tcl_Obj *) NULL, i,
		    TCL_LEAVE_ERR_MSG);
	    CACHE_STACK_INFO();
	    if (value2Ptr == NULL) {
		TRACE_WITH_OBJ(("\"%.30s\" %ld => ERROR: ",

		        O2S(objPtr), i), Tcl_GetObjResult(interp));
		result = TCL_ERROR;
		Tcl_DecrRefCount(objPtr);
		goto checkForCatch;
	    }
	    PUSH_OBJECT(value2Ptr);
	    TRACE_WITH_OBJ(("\"%.30s\" %ld => ", O2S(objPtr), i),
		    value2Ptr);
	    TclDecrRefCount(objPtr);
	    ADJUST_PC(2);

	case INST_INCR_ARRAY1_IMM:
	    {
		Tcl_Obj *elemPtr;

		opnd = TclGetUInt1AtPtr(pc+1);
		i = TclGetInt1AtPtr(pc+2);
		elemPtr = POP_OBJECT();
		DECACHE_STACK_INFO();
		value2Ptr = TclIncrElementOfIndexedArray(interp, opnd,
		        elemPtr, i);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(("%u \"%.30s\" (by %ld) => ERROR: ",
		            opnd, O2S(elemPtr), i),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(elemPtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("%u \"%.30s\" (by %ld) => ",
	                opnd, O2S(elemPtr), i), value2Ptr);
		Tcl_DecrRefCount(elemPtr);
	    }
	    ADJUST_PC(3);
	    
	case INST_INCR_ARRAY_STK_IMM:
	    {
		Tcl_Obj *elemPtr;

		i = TclGetInt1AtPtr(pc+1);
		elemPtr = POP_OBJECT();
		objPtr = POP_OBJECT();	/* array name */
		DECACHE_STACK_INFO();
		value2Ptr = TclIncrVar2(interp, objPtr, elemPtr, i,
			TCL_LEAVE_ERR_MSG);
		CACHE_STACK_INFO();
		if (value2Ptr == NULL) {
		    TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %ld) => ERROR: ",
		            O2S(objPtr), O2S(elemPtr), i),
			    Tcl_GetObjResult(interp));
		    Tcl_DecrRefCount(objPtr);
		    Tcl_DecrRefCount(elemPtr);
		    result = TCL_ERROR;
		    goto checkForCatch;
		}
		PUSH_OBJECT(value2Ptr);
		TRACE_WITH_OBJ(("\"%.30s(%.30s)\" (by %ld) => ",
	                O2S(objPtr), O2S(elemPtr), i), value2Ptr);
		Tcl_DecrRefCount(objPtr);
		Tcl_DecrRefCount(elemPtr);
	    }
	    ADJUST_PC(2);

	case INST_JUMP1:
#ifdef TCL_COMPILE_DEBUG
	    opnd = TclGetInt1AtPtr(pc+1);
	    TRACE(("%d => new pc %u\n", opnd,
		   (unsigned int)(pc + opnd - codePtr->codeStart)));
	    pc += opnd;
#else
	    pc += TclGetInt1AtPtr(pc+1);
#endif /* TCL_COMPILE_DEBUG */
	    continue;

	case INST_JUMP4:
	    opnd = TclGetInt4AtPtr(pc+1);
	    TRACE(("%d => new pc %u\n", opnd,
		   (unsigned int)(pc + opnd - codePtr->codeStart)));
	    ADJUST_PC(opnd);

	case INST_JUMP_TRUE4:
	    opnd = TclGetInt4AtPtr(pc+1);
	    pcAdjustment = 5;
	    goto doJumpTrue;
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
		if (valuePtr->typePtr == &tclIntType) {
		    b = (valuePtr->internalRep.longValue != 0);
		} else if (valuePtr->typePtr == &tclDoubleType) {
		    b = (valuePtr->internalRep.doubleValue != 0.0);
		} else {
		    result = Tcl_GetBooleanFromObj(interp, valuePtr, &b);
		    if (result != TCL_OK) {
			TRACE_WITH_OBJ(("%s %d => ERROR: ", opName[opCode],
				opnd), Tcl_GetObjResult(interp));
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		}
		if (b) {
		    TRACE(("%s %d => %.20s true, new pc %u\n",
			    opName[opCode], opnd, O2S(valuePtr),
		            (unsigned int)(pc+opnd - codePtr->codeStart)));
		    TclDecrRefCount(valuePtr);
		    ADJUST_PC(opnd);
		} else {
		    TRACE(("%s %d => %.20s false\n", opName[opCode], opnd,
		            O2S(valuePtr)));
		    TclDecrRefCount(valuePtr);
		    ADJUST_PC(pcAdjustment);
		}
	    }
	    
	case INST_JUMP_FALSE4:
	    opnd = TclGetInt4AtPtr(pc+1);







|
|





|
|




<
|







1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616

1617
1618
1619
1620
1621
1622
1623
1624
		if (valuePtr->typePtr == &tclIntType) {
		    b = (valuePtr->internalRep.longValue != 0);
		} else if (valuePtr->typePtr == &tclDoubleType) {
		    b = (valuePtr->internalRep.doubleValue != 0.0);
		} else {
		    result = Tcl_GetBooleanFromObj(interp, valuePtr, &b);
		    if (result != TCL_OK) {
			TRACE_WITH_OBJ(("%d => ERROR: ", opnd),
				Tcl_GetObjResult(interp));
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		}
		if (b) {
		    TRACE(("%d => %.20s true, new pc %u\n",
			    opnd, O2S(valuePtr),
		            (unsigned int)(pc+opnd - codePtr->codeStart)));
		    TclDecrRefCount(valuePtr);
		    ADJUST_PC(opnd);
		} else {

		    TRACE(("%d => %.20s false\n", opnd, O2S(valuePtr)));
		    TclDecrRefCount(valuePtr);
		    ADJUST_PC(pcAdjustment);
		}
	    }
	    
	case INST_JUMP_FALSE4:
	    opnd = TclGetInt4AtPtr(pc+1);
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
		if (valuePtr->typePtr == &tclIntType) {
		    b = (valuePtr->internalRep.longValue != 0);
		} else if (valuePtr->typePtr == &tclDoubleType) {
		    b = (valuePtr->internalRep.doubleValue != 0.0);
		} else {
		    result = Tcl_GetBooleanFromObj(interp, valuePtr, &b);
		    if (result != TCL_OK) {
			TRACE_WITH_OBJ(("%s %d => ERROR: ", opName[opCode],
				opnd), Tcl_GetObjResult(interp));
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		}
		if (b) {
		    TRACE(("%s %d => %.20s true\n", opName[opCode], opnd,
		            O2S(valuePtr)));
		    TclDecrRefCount(valuePtr);
		    ADJUST_PC(pcAdjustment);
		} else {
		    TRACE(("%s %d => %.20s false, new pc %u\n",
			    opName[opCode], opnd, O2S(valuePtr),
			   (unsigned int)(pc + opnd - codePtr->codeStart)));
		    TclDecrRefCount(valuePtr);
		    ADJUST_PC(opnd);
		}
	    }
	    
	case INST_LOR:







|
|





<
|



|
|







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
		if (valuePtr->typePtr == &tclIntType) {
		    b = (valuePtr->internalRep.longValue != 0);
		} else if (valuePtr->typePtr == &tclDoubleType) {
		    b = (valuePtr->internalRep.doubleValue != 0.0);
		} else {
		    result = Tcl_GetBooleanFromObj(interp, valuePtr, &b);
		    if (result != TCL_OK) {
			TRACE_WITH_OBJ(("%d => ERROR: ", opnd),
				Tcl_GetObjResult(interp));
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		}
		if (b) {

		    TRACE(("%d => %.20s true\n", opnd, O2S(valuePtr)));
		    TclDecrRefCount(valuePtr);
		    ADJUST_PC(pcAdjustment);
		} else {
		    TRACE(("%d => %.20s false, new pc %u\n",
			   opnd, O2S(valuePtr),
			   (unsigned int)(pc + opnd - codePtr->codeStart)));
		    TclDecrRefCount(valuePtr);
		    ADJUST_PC(opnd);
		}
	    }
	    
	case INST_LOR:
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
		t1Ptr = valuePtr->typePtr;
		t2Ptr = value2Ptr->typePtr;
		
		if ((t1Ptr == &tclIntType) || (t1Ptr == &tclBooleanType)) {
		    i1 = (valuePtr->internalRep.longValue != 0);
		} else if (t1Ptr == &tclDoubleType) {
		    i1 = (valuePtr->internalRep.doubleValue != 0.0);
		} else {	/* FAILS IF NULL STRING REP */
		    s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
		    if (TclLooksLikeInt(s)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
			i1 = (i != 0);
		    } else {
			result = Tcl_GetBooleanFromObj((Tcl_Interp *) NULL,
				valuePtr, &i1);
			i1 = (i1 != 0);
		    }
		    if (result != TCL_OK) {
			TRACE(("%s \"%.20s\" => ILLEGAL TYPE %s \n",
			        opName[opCode], O2S(valuePtr),
			        (t1Ptr? t1Ptr->name : "null")));
			IllegalExprOperandType(interp, opCode, valuePtr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		}
		
		if ((t2Ptr == &tclIntType) || (t2Ptr == &tclBooleanType)) {
		    i2 = (value2Ptr->internalRep.longValue != 0);
		} else if (t2Ptr == &tclDoubleType) {
		    i2 = (value2Ptr->internalRep.doubleValue != 0.0);
		} else {	/* FAILS IF NULL STRING REP */
		    s = Tcl_GetStringFromObj(value2Ptr, (int *) NULL);
		    if (TclLooksLikeInt(s)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				value2Ptr, &i);
			i2 = (i != 0);
		    } else {
			result = Tcl_GetBooleanFromObj((Tcl_Interp *) NULL,
				value2Ptr, &i2);
			i2 = (i2 != 0);
		    }
		    if (result != TCL_OK) {
			TRACE(("%s \"%.20s\" => ILLEGAL TYPE %s \n",
			        opName[opCode], O2S(value2Ptr),
			        (t2Ptr? t2Ptr->name : "null")));
			IllegalExprOperandType(interp, opCode, value2Ptr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		}
		
		/*
		 * Reuse the valuePtr object already on stack if possible.
		 */

		if (opCode == INST_LOR) {
		    iResult = (i1 || i2);
		} else {
		    iResult = (i1 && i2);
		}
		if (Tcl_IsShared(valuePtr)) {
		    PUSH_OBJECT(Tcl_NewLongObj(iResult));
		    TRACE(("%s %.20s %.20s => %d\n", opName[opCode],
			   O2S(valuePtr), O2S(value2Ptr), iResult));
		    TclDecrRefCount(valuePtr);
		} else {	/* reuse the valuePtr object */
		    TRACE(("%s %.20s %.20s => %d\n", 
			   opName[opCode], /* NB: stack top is off by 1 */
			   O2S(valuePtr), O2S(value2Ptr), iResult));
		    Tcl_SetLongObj(valuePtr, iResult);
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		}
		TclDecrRefCount(value2Ptr);
	    }
	    ADJUST_PC(1);







|
|
|









|
|

|










|
|
|






<


|
|

|










|






|



|
<







1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719

1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747

1748
1749
1750
1751
1752
1753
1754
		t1Ptr = valuePtr->typePtr;
		t2Ptr = value2Ptr->typePtr;
		
		if ((t1Ptr == &tclIntType) || (t1Ptr == &tclBooleanType)) {
		    i1 = (valuePtr->internalRep.longValue != 0);
		} else if (t1Ptr == &tclDoubleType) {
		    i1 = (valuePtr->internalRep.doubleValue != 0.0);
		} else {
		    s = Tcl_GetStringFromObj(valuePtr, &length);
		    if (TclLooksLikeInt(s, length)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
			i1 = (i != 0);
		    } else {
			result = Tcl_GetBooleanFromObj((Tcl_Interp *) NULL,
				valuePtr, &i1);
			i1 = (i1 != 0);
		    }
		    if (result != TCL_OK) {
			TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n",
			        O2S(valuePtr),
			        (t1Ptr? t1Ptr->name : "null")));
			IllegalExprOperandType(interp, pc, valuePtr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		}
		
		if ((t2Ptr == &tclIntType) || (t2Ptr == &tclBooleanType)) {
		    i2 = (value2Ptr->internalRep.longValue != 0);
		} else if (t2Ptr == &tclDoubleType) {
		    i2 = (value2Ptr->internalRep.doubleValue != 0.0);
		} else {
		    s = Tcl_GetStringFromObj(value2Ptr, &length);
		    if (TclLooksLikeInt(s, length)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				value2Ptr, &i);
			i2 = (i != 0);
		    } else {
			result = Tcl_GetBooleanFromObj((Tcl_Interp *) NULL,
				value2Ptr, &i2);

		    }
		    if (result != TCL_OK) {
			TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n",
			        O2S(value2Ptr),
			        (t2Ptr? t2Ptr->name : "null")));
			IllegalExprOperandType(interp, pc, value2Ptr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		}
		
		/*
		 * Reuse the valuePtr object already on stack if possible.
		 */

		if (*pc == INST_LOR) {
		    iResult = (i1 || i2);
		} else {
		    iResult = (i1 && i2);
		}
		if (Tcl_IsShared(valuePtr)) {
		    PUSH_OBJECT(Tcl_NewLongObj(iResult));
		    TRACE(("%.20s %.20s => %d\n",
			   O2S(valuePtr), O2S(value2Ptr), iResult));
		    TclDecrRefCount(valuePtr);
		} else {	/* reuse the valuePtr object */
		    TRACE(("%.20s %.20s => %d\n", 

			   O2S(valuePtr), O2S(value2Ptr), iResult));
		    Tcl_SetLongObj(valuePtr, iResult);
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		}
		TclDecrRefCount(value2Ptr);
	    }
	    ADJUST_PC(1);
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
		value2Ptr = POP_OBJECT();
		valuePtr  = POP_OBJECT();
		t1Ptr = valuePtr->typePtr;
		t2Ptr = value2Ptr->typePtr;
		
		if ((t1Ptr != &tclIntType) && (t1Ptr != &tclDoubleType)) {
		    s1 = Tcl_GetStringFromObj(valuePtr, &length);
		    if (TclLooksLikeInt(s1)) { /* FAILS IF NULLS */
			(void) Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
		    } else {
			(void) Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				valuePtr, &d1);
		    }
		    t1Ptr = valuePtr->typePtr;
		}
		if ((t2Ptr != &tclIntType) && (t2Ptr != &tclDoubleType)) {
		    s2 = Tcl_GetStringFromObj(value2Ptr, &length);
		    if (TclLooksLikeInt(s2)) { /* FAILS IF NULLS */
			(void) Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				value2Ptr, &i2);
		    } else {
			(void) Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				value2Ptr, &d2);
		    }
		    t2Ptr = value2Ptr->typePtr;
		}

		if (((t1Ptr != &tclIntType) && (t1Ptr != &tclDoubleType))
		        || ((t2Ptr != &tclIntType) && (t2Ptr != &tclDoubleType))) {
		    /*
		     * One operand is not numeric. Compare as strings.
		     * THIS FAILS IF AN OBJECT'S STRING REP CONTAINS NULLS.
		     */
		    int cmpValue;
		    s1 = TclGetStringFromObj(valuePtr, &length);
		    s2 = TclGetStringFromObj(value2Ptr, &length);
		    cmpValue = strcmp(s1, s2);
		    switch (opCode) {
		    case INST_EQ:
			iResult = (cmpValue == 0);
			break;
		    case INST_NEQ:
			iResult = (cmpValue != 0);
			break;
		    case INST_LT:







|










|













<


|
|

|







1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807

1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
		value2Ptr = POP_OBJECT();
		valuePtr  = POP_OBJECT();
		t1Ptr = valuePtr->typePtr;
		t2Ptr = value2Ptr->typePtr;
		
		if ((t1Ptr != &tclIntType) && (t1Ptr != &tclDoubleType)) {
		    s1 = Tcl_GetStringFromObj(valuePtr, &length);
		    if (TclLooksLikeInt(s1, length)) {
			(void) Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
		    } else {
			(void) Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				valuePtr, &d1);
		    }
		    t1Ptr = valuePtr->typePtr;
		}
		if ((t2Ptr != &tclIntType) && (t2Ptr != &tclDoubleType)) {
		    s2 = Tcl_GetStringFromObj(value2Ptr, &length);
		    if (TclLooksLikeInt(s2, length)) {
			(void) Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				value2Ptr, &i2);
		    } else {
			(void) Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				value2Ptr, &d2);
		    }
		    t2Ptr = value2Ptr->typePtr;
		}

		if (((t1Ptr != &tclIntType) && (t1Ptr != &tclDoubleType))
		        || ((t2Ptr != &tclIntType) && (t2Ptr != &tclDoubleType))) {
		    /*
		     * One operand is not numeric. Compare as strings.

		     */
		    int cmpValue;
		    s1 = Tcl_GetString(valuePtr);
		    s2 = Tcl_GetString(value2Ptr);
		    cmpValue = strcmp(s1, s2);
		    switch (*pc) {
		    case INST_EQ:
			iResult = (cmpValue == 0);
			break;
		    case INST_NEQ:
			iResult = (cmpValue != 0);
			break;
		    case INST_LT:
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
			} else {
			    d2 = value2Ptr->internalRep.doubleValue;
			}
		    } else {	/* t1Ptr is int, t2Ptr is double */
			d1 = valuePtr->internalRep.longValue;
			d2 = value2Ptr->internalRep.doubleValue;
		    }
		    switch (opCode) {
		    case INST_EQ:
			iResult = d1 == d2;
			break;
		    case INST_NEQ:
			iResult = d1 != d2;
			break;
		    case INST_LT:







|







1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
			} else {
			    d2 = value2Ptr->internalRep.doubleValue;
			}
		    } else {	/* t1Ptr is int, t2Ptr is double */
			d1 = valuePtr->internalRep.longValue;
			d2 = value2Ptr->internalRep.doubleValue;
		    }
		    switch (*pc) {
		    case INST_EQ:
			iResult = d1 == d2;
			break;
		    case INST_NEQ:
			iResult = d1 != d2;
			break;
		    case INST_LT:
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
		    }
		} else {
		    /*
		     * Compare as ints.
		     */
		    i  = valuePtr->internalRep.longValue;
		    i2 = value2Ptr->internalRep.longValue;
		    switch (opCode) {
		    case INST_EQ:
			iResult = i == i2;
			break;
		    case INST_NEQ:
			iResult = i != i2;
			break;
		    case INST_LT:







|







1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
		    }
		} else {
		    /*
		     * Compare as ints.
		     */
		    i  = valuePtr->internalRep.longValue;
		    i2 = value2Ptr->internalRep.longValue;
		    switch (*pc) {
		    case INST_EQ:
			iResult = i == i2;
			break;
		    case INST_NEQ:
			iResult = i != i2;
			break;
		    case INST_LT:
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026

		/*
		 * Reuse the valuePtr object already on stack if possible.
		 */
		
		if (Tcl_IsShared(valuePtr)) {
		    PUSH_OBJECT(Tcl_NewLongObj(iResult));
		    TRACE(("%s %.20s %.20s => %ld\n", opName[opCode],
		        O2S(valuePtr), O2S(value2Ptr), iResult));
		    TclDecrRefCount(valuePtr);
		} else {	/* reuse the valuePtr object */
		    TRACE(("%s %.20s %.20s => %ld\n",
			opName[opCode], /* NB: stack top is off by 1 */
		        O2S(valuePtr), O2S(value2Ptr), iResult));
		    Tcl_SetLongObj(valuePtr, iResult);
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		}
		TclDecrRefCount(value2Ptr);
	    }
	    ADJUST_PC(1);
	    







|
|


|
<
|







1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907

1908
1909
1910
1911
1912
1913
1914
1915

		/*
		 * Reuse the valuePtr object already on stack if possible.
		 */
		
		if (Tcl_IsShared(valuePtr)) {
		    PUSH_OBJECT(Tcl_NewLongObj(iResult));
		    TRACE(("%.20s %.20s => %ld\n",
			   O2S(valuePtr), O2S(value2Ptr), iResult));
		    TclDecrRefCount(valuePtr);
		} else {	/* reuse the valuePtr object */
		    TRACE(("%.20s %.20s => %ld\n",

			    O2S(valuePtr), O2S(value2Ptr), iResult));
		    Tcl_SetLongObj(valuePtr, iResult);
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		}
		TclDecrRefCount(value2Ptr);
	    }
	    ADJUST_PC(1);
	    
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
		valuePtr  = POP_OBJECT(); 
		if (valuePtr->typePtr == &tclIntType) {
		    i = valuePtr->internalRep.longValue;
		} else {	/* try to convert to int */
		    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
			    valuePtr, &i);
		    if (result != TCL_OK) {
			TRACE(("%s %.20s %.20s => ILLEGAL 1st TYPE %s\n",
			      opName[opCode], O2S(valuePtr), O2S(value2Ptr),
			      (valuePtr->typePtr?
				   valuePtr->typePtr->name : "null")));
			IllegalExprOperandType(interp, opCode, valuePtr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		}
		if (value2Ptr->typePtr == &tclIntType) {
		    i2 = value2Ptr->internalRep.longValue;
		} else {
		    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
			    value2Ptr, &i2);
		    if (result != TCL_OK) {
			TRACE(("%s %.20s %.20s => ILLEGAL 2nd TYPE %s\n",
			      opName[opCode], O2S(valuePtr), O2S(value2Ptr),
			      (value2Ptr->typePtr?
				   value2Ptr->typePtr->name : "null")));
			IllegalExprOperandType(interp, opCode, value2Ptr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		}

		switch (opCode) {
		case INST_MOD:
		    /*
		     * This code is tricky: C doesn't guarantee much about
		     * the quotient or remainder, but Tcl does. The
		     * remainder always has the same sign as the divisor and
		     * a smaller absolute value.
		     */
		    if (i2 == 0) {
			TRACE(("mod %ld %ld => DIVIDE BY ZERO\n", i, i2));
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto divideByZero;
		    }
		    negative = 0;
		    if (i2 < 0) {
			i2 = -i2;







|
|


|











|
|


|






|








|







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
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
		valuePtr  = POP_OBJECT(); 
		if (valuePtr->typePtr == &tclIntType) {
		    i = valuePtr->internalRep.longValue;
		} else {	/* try to convert to int */
		    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
			    valuePtr, &i);
		    if (result != TCL_OK) {
			TRACE(("%.20s %.20s => ILLEGAL 1st TYPE %s\n",
			      O2S(valuePtr), O2S(value2Ptr),
			      (valuePtr->typePtr?
				   valuePtr->typePtr->name : "null")));
			IllegalExprOperandType(interp, pc, valuePtr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		}
		if (value2Ptr->typePtr == &tclIntType) {
		    i2 = value2Ptr->internalRep.longValue;
		} else {
		    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
			    value2Ptr, &i2);
		    if (result != TCL_OK) {
			TRACE(("%.20s %.20s => ILLEGAL 2nd TYPE %s\n",
			      O2S(valuePtr), O2S(value2Ptr),
			      (value2Ptr->typePtr?
				   value2Ptr->typePtr->name : "null")));
			IllegalExprOperandType(interp, pc, value2Ptr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		}

		switch (*pc) {
		case INST_MOD:
		    /*
		     * This code is tricky: C doesn't guarantee much about
		     * the quotient or remainder, but Tcl does. The
		     * remainder always has the same sign as the divisor and
		     * a smaller absolute value.
		     */
		    if (i2 == 0) {
			TRACE(("%ld %ld => DIVIDE BY ZERO\n", i, i2));
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto divideByZero;
		    }
		    negative = 0;
		    if (i2 < 0) {
			i2 = -i2;
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149

		/*
		 * Reuse the valuePtr object already on stack if possible.
		 */
		
		if (Tcl_IsShared(valuePtr)) {
		    PUSH_OBJECT(Tcl_NewLongObj(iResult));
		    TRACE(("%s %ld %ld => %ld\n", opName[opCode], i, i2,
			   iResult));
		    TclDecrRefCount(valuePtr);
		} else {	/* reuse the valuePtr object */
		    TRACE(("%s %ld %ld => %ld\n", opName[opCode], i, i2,
		        iResult)); /* NB: stack top is off by 1 */
		    Tcl_SetLongObj(valuePtr, iResult);
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		}
		TclDecrRefCount(value2Ptr);
	    }
	    ADJUST_PC(1);
	    







|
<


|
<







2019
2020
2021
2022
2023
2024
2025
2026

2027
2028
2029

2030
2031
2032
2033
2034
2035
2036

		/*
		 * Reuse the valuePtr object already on stack if possible.
		 */
		
		if (Tcl_IsShared(valuePtr)) {
		    PUSH_OBJECT(Tcl_NewLongObj(iResult));
		    TRACE(("%ld %ld => %ld\n", i, i2, iResult));

		    TclDecrRefCount(valuePtr);
		} else {	/* reuse the valuePtr object */
		    TRACE(("%ld %ld => %ld\n", i, i2, iResult));

		    Tcl_SetLongObj(valuePtr, iResult);
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		}
		TclDecrRefCount(value2Ptr);
	    }
	    ADJUST_PC(1);
	    
2167
2168
2169
2170
2171
2172
2173
2174







2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200







2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
		value2Ptr = POP_OBJECT();
		valuePtr  = POP_OBJECT();
		t1Ptr = valuePtr->typePtr;
		t2Ptr = value2Ptr->typePtr;
		
		if (t1Ptr == &tclIntType) {
		    i  = valuePtr->internalRep.longValue;
		} else if (t1Ptr == &tclDoubleType) {







		    d1 = valuePtr->internalRep.doubleValue;
		} else {	     /* try to convert; FAILS IF NULLS */
		    char *s = Tcl_GetStringFromObj(valuePtr, &length);
		    if (TclLooksLikeInt(s)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
		    } else {
			result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				valuePtr, &d1);
		    }
		    if (result != TCL_OK) {
			TRACE(("%s %.20s %.20s => ILLEGAL 1st TYPE %s\n",
			       opName[opCode], s, O2S(value2Ptr),
			       (valuePtr->typePtr?
				    valuePtr->typePtr->name : "null")));
			IllegalExprOperandType(interp, opCode, valuePtr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		    t1Ptr = valuePtr->typePtr;
		}
		
		if (t2Ptr == &tclIntType) {
		    i2 = value2Ptr->internalRep.longValue;
		} else if (t2Ptr == &tclDoubleType) {







		    d2 = value2Ptr->internalRep.doubleValue;
		} else {	     /* try to convert; FAILS IF NULLS */
		    char *s = Tcl_GetStringFromObj(value2Ptr, &length);
		    if (TclLooksLikeInt(s)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				value2Ptr, &i2);
		    } else {
			result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				value2Ptr, &d2);
		    }
		    if (result != TCL_OK) {
			TRACE(("%s %.20s %.20s => ILLEGAL 2nd TYPE %s\n",
			       opName[opCode], O2S(valuePtr), s,
			       (value2Ptr->typePtr?
				    value2Ptr->typePtr->name : "null")));
			IllegalExprOperandType(interp, opCode, value2Ptr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		    t2Ptr = value2Ptr->typePtr;
		}

		if ((t1Ptr == &tclDoubleType) || (t2Ptr == &tclDoubleType)) {
		    /*
		     * Do double arithmetic.
		     */
		    doDouble = 1;
		    if (t1Ptr == &tclIntType) {
			d1 = i;       /* promote value 1 to double */
		    } else if (t2Ptr == &tclIntType) {
			d2 = i2;      /* promote value 2 to double */
		    }
		    switch (opCode) {
		    case INST_ADD:
			dResult = d1 + d2;
			break;
		    case INST_SUB:
			dResult = d1 - d2;
			break;
		    case INST_MULT:
			dResult = d1 * d2;
			break;
		    case INST_DIV:
			if (d2 == 0.0) {
			    TRACE(("div %.6g %.6g => DIVIDE BY ZERO\n",
				   d1, d2));
			    Tcl_DecrRefCount(valuePtr);
			    Tcl_DecrRefCount(value2Ptr);
			    goto divideByZero;
			}
			dResult = d1 / d2;
			break;
		    }
		    
		    /*
		     * Check now for IEEE floating-point error.
		     */
		    
		    if (IS_NAN(dResult) || IS_INF(dResult)) {
			TRACE(("%s %.20s %.20s => IEEE FLOATING PT ERROR\n",
			       opName[opCode], O2S(valuePtr), O2S(value2Ptr)));
			TclExprFloatError(interp, dResult);
			result = TCL_ERROR;
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		} else {
		    /*
		     * Do integer arithmetic.
		     */
		    switch (opCode) {
		    case INST_ADD:
			iResult = i + i2;
			break;
		    case INST_SUB:
			iResult = i - i2;
			break;
		    case INST_MULT:
			iResult = i * i2;
			break;
		    case INST_DIV:
			/*
			 * This code is tricky: C doesn't guarantee much
			 * about the quotient or remainder, but Tcl does.
			 * The remainder always has the same sign as the
			 * divisor and a smaller absolute value.
			 */
			if (i2 == 0) {
			    TRACE(("div %ld %ld => DIVIDE BY ZERO\n",
				    i, i2));
			    Tcl_DecrRefCount(valuePtr);
			    Tcl_DecrRefCount(value2Ptr);
			    goto divideByZero;
			}
			if (i2 < 0) {
			    i2 = -i2;
			    i = -i;







|
>
>
>
>
>
>
>

|

|







|
|


|









|
>
>
>
>
>
>
>

|

|







|
|


|

















|











|
<













|
|










|

















|
<







2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147

2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191

2192
2193
2194
2195
2196
2197
2198
		value2Ptr = POP_OBJECT();
		valuePtr  = POP_OBJECT();
		t1Ptr = valuePtr->typePtr;
		t2Ptr = value2Ptr->typePtr;
		
		if (t1Ptr == &tclIntType) {
		    i  = valuePtr->internalRep.longValue;
		} else if ((t1Ptr == &tclDoubleType)
			&& (valuePtr->bytes == NULL)) {
		    /*
		     * We can only use the internal rep directly if there is
		     * no string rep.  Otherwise the string rep might actually
		     * look like an integer, which is preferred.
		     */

		    d1 = valuePtr->internalRep.doubleValue;
		} else {
		    char *s = Tcl_GetStringFromObj(valuePtr, &length);
		    if (TclLooksLikeInt(s, length)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
		    } else {
			result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				valuePtr, &d1);
		    }
		    if (result != TCL_OK) {
			TRACE(("%.20s %.20s => ILLEGAL 1st TYPE %s\n",
			       s, O2S(valuePtr),
			       (valuePtr->typePtr?
				    valuePtr->typePtr->name : "null")));
			IllegalExprOperandType(interp, pc, valuePtr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		    t1Ptr = valuePtr->typePtr;
		}
		
		if (t2Ptr == &tclIntType) {
		    i2 = value2Ptr->internalRep.longValue;
		} else if ((t2Ptr == &tclDoubleType)
			&& (value2Ptr->bytes == NULL)) {
		    /*
		     * We can only use the internal rep directly if there is
		     * no string rep.  Otherwise the string rep might actually
		     * look like an integer, which is preferred.
		     */

		    d2 = value2Ptr->internalRep.doubleValue;
		} else {
		    char *s = Tcl_GetStringFromObj(value2Ptr, &length);
		    if (TclLooksLikeInt(s, length)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				value2Ptr, &i2);
		    } else {
			result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				value2Ptr, &d2);
		    }
		    if (result != TCL_OK) {
			TRACE(("%.20s %.20s => ILLEGAL 2nd TYPE %s\n",
			       O2S(value2Ptr), s,
			       (value2Ptr->typePtr?
				    value2Ptr->typePtr->name : "null")));
			IllegalExprOperandType(interp, pc, value2Ptr);
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		    t2Ptr = value2Ptr->typePtr;
		}

		if ((t1Ptr == &tclDoubleType) || (t2Ptr == &tclDoubleType)) {
		    /*
		     * Do double arithmetic.
		     */
		    doDouble = 1;
		    if (t1Ptr == &tclIntType) {
			d1 = i;       /* promote value 1 to double */
		    } else if (t2Ptr == &tclIntType) {
			d2 = i2;      /* promote value 2 to double */
		    }
		    switch (*pc) {
		    case INST_ADD:
			dResult = d1 + d2;
			break;
		    case INST_SUB:
			dResult = d1 - d2;
			break;
		    case INST_MULT:
			dResult = d1 * d2;
			break;
		    case INST_DIV:
			if (d2 == 0.0) {
			    TRACE(("%.6g %.6g => DIVIDE BY ZERO\n", d1, d2));

			    Tcl_DecrRefCount(valuePtr);
			    Tcl_DecrRefCount(value2Ptr);
			    goto divideByZero;
			}
			dResult = d1 / d2;
			break;
		    }
		    
		    /*
		     * Check now for IEEE floating-point error.
		     */
		    
		    if (IS_NAN(dResult) || IS_INF(dResult)) {
			TRACE(("%.20s %.20s => IEEE FLOATING PT ERROR\n",
			       O2S(valuePtr), O2S(value2Ptr)));
			TclExprFloatError(interp, dResult);
			result = TCL_ERROR;
			Tcl_DecrRefCount(valuePtr);
			Tcl_DecrRefCount(value2Ptr);
			goto checkForCatch;
		    }
		} else {
		    /*
		     * Do integer arithmetic.
		     */
		    switch (*pc) {
		    case INST_ADD:
			iResult = i + i2;
			break;
		    case INST_SUB:
			iResult = i - i2;
			break;
		    case INST_MULT:
			iResult = i * i2;
			break;
		    case INST_DIV:
			/*
			 * This code is tricky: C doesn't guarantee much
			 * about the quotient or remainder, but Tcl does.
			 * The remainder always has the same sign as the
			 * divisor and a smaller absolute value.
			 */
			if (i2 == 0) {
			    TRACE(("%ld %ld => DIVIDE BY ZERO\n", i, i2));

			    Tcl_DecrRefCount(valuePtr);
			    Tcl_DecrRefCount(value2Ptr);
			    goto divideByZero;
			}
			if (i2 < 0) {
			    i2 = -i2;
			    i = -i;
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
		/*
		 * Reuse the valuePtr object already on stack if possible.
		 */
		
		if (Tcl_IsShared(valuePtr)) {
		    if (doDouble) {
			PUSH_OBJECT(Tcl_NewDoubleObj(dResult));
			TRACE(("%s %.6g %.6g => %.6g\n", opName[opCode],
			       d1, d2, dResult));
		    } else {
			PUSH_OBJECT(Tcl_NewLongObj(iResult));
			TRACE(("%s %ld %ld => %ld\n", opName[opCode],
			       i, i2, iResult));
		    } 
		    TclDecrRefCount(valuePtr);
		} else {	    /* reuse the valuePtr object */
		    if (doDouble) { /* NB: stack top is off by 1 */
			TRACE(("%s %.6g %.6g => %.6g\n", opName[opCode],
			       d1, d2, dResult));
			Tcl_SetDoubleObj(valuePtr, dResult);
		    } else {
			TRACE(("%s %ld %ld => %ld\n", opName[opCode],
			       i, i2, iResult));
			Tcl_SetLongObj(valuePtr, iResult);
		    }
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		}
		TclDecrRefCount(value2Ptr);
	    }
	    ADJUST_PC(1);
	    
	case INST_UPLUS:
	    {
	        /*
	         * Operand must be numeric.
	         */

		double d;
		Tcl_ObjType *tPtr;
		
		valuePtr = stackPtr[stackTop].o;
		tPtr = valuePtr->typePtr;
		if ((tPtr != &tclIntType) && (tPtr != &tclDoubleType)) {

		    char *s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
		    if (TclLooksLikeInt(s)) { /* FAILS IF NULLS */
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
		    } else {
			result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				valuePtr, &d);
		    }
		    if (result != TCL_OK) { 
			TRACE(("%s \"%.20s\" => ILLEGAL TYPE %s \n",
			        opName[opCode], s,
			        (tPtr? tPtr->name : "null")));
			IllegalExprOperandType(interp, opCode, valuePtr);
			goto checkForCatch;
		    }

		}

























		TRACE_WITH_OBJ(("uplus %s => ", O2S(valuePtr)), valuePtr);
	    }
	    ADJUST_PC(1);
	    
	case INST_UMINUS:
	case INST_LNOT:
	    {
		/*
		 * The operand must be numeric. If the operand object is
		 * unshared modify it directly, otherwise create a copy to
		 * modify: this is "copy on write". free any old string
		 * representation since it is now invalid.
		 */
		
		double d;
		Tcl_ObjType *tPtr;
		
		valuePtr = POP_OBJECT();
		tPtr = valuePtr->typePtr;
		if ((tPtr != &tclIntType) && (tPtr != &tclDoubleType)) {

		    char *s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
		    if (TclLooksLikeInt(s)) { /* FAILS IF NULLS */
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
		    } else {
			result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				valuePtr, &d);
		    }
		    if (result != TCL_OK) {
			TRACE(("%s \"%.20s\" => ILLEGAL TYPE %s\n",
			        opName[opCode], s,
			       (tPtr? tPtr->name : "null")));
			IllegalExprOperandType(interp, opCode, valuePtr);
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		    tPtr = valuePtr->typePtr;
		}
		
		if (Tcl_IsShared(valuePtr)) {
		    /*
		     * Create a new object.
		     */
		    if (tPtr == &tclIntType) {
			i = valuePtr->internalRep.longValue;
			objPtr = Tcl_NewLongObj(
			        (opCode == INST_UMINUS)? -i : !i);
			TRACE_WITH_OBJ(("%s %ld => ", opName[opCode], i),
		                objPtr); /* NB: stack top is off by 1 */
		    } else {
			d = valuePtr->internalRep.doubleValue;
			if (opCode == INST_UMINUS) {
			    objPtr = Tcl_NewDoubleObj(-d);
			} else {
			    /*
			     * Should be able to use "!d", but apparently
			     * some compilers can't handle it.
			     */
			    objPtr = Tcl_NewLongObj((d==0.0)? 1 : 0);
			}
			TRACE_WITH_OBJ(("%s %.6g => ", opName[opCode], d),
		                objPtr); /* NB: stack top is off by 1 */
		    }
		    PUSH_OBJECT(objPtr);
		    TclDecrRefCount(valuePtr);
		} else {
		    /*
		     * valuePtr is unshared. Modify it directly.
		     */
		    if (tPtr == &tclIntType) {
			i = valuePtr->internalRep.longValue;
			Tcl_SetLongObj(valuePtr,
			        (opCode == INST_UMINUS)? -i : !i);
			TRACE_WITH_OBJ(("%s %ld => ", opName[opCode], i),
		                valuePtr); /* NB: stack top is off by 1 */
		    } else {
			d = valuePtr->internalRep.doubleValue;
			if (opCode == INST_UMINUS) {
			    Tcl_SetDoubleObj(valuePtr, -d);
			} else {
			    /*
			     * Should be able to use "!d", but apparently
			     * some compilers can't handle it.
			     */
			    Tcl_SetLongObj(valuePtr, (d==0.0)? 1 : 0);
			}
			TRACE_WITH_OBJ(("%s %.6g => ", opName[opCode], d),
		                valuePtr); /* NB: stack top is off by 1 */
		    }
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		}
	    }
	    ADJUST_PC(1);
	    
	case INST_BITNOT:







<
|


<
|




<
|


<
|

















|

|
>
|
|







|
<
|
|


>

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


















|
>
|
|







|
<
|
|













|
|
<


|








|
<










|
|
<


|








|
<







2210
2211
2212
2213
2214
2215
2216

2217
2218
2219

2220
2221
2222
2223
2224

2225
2226
2227

2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259

2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321

2322
2323
2324
2325
2326
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
		/*
		 * Reuse the valuePtr object already on stack if possible.
		 */
		
		if (Tcl_IsShared(valuePtr)) {
		    if (doDouble) {
			PUSH_OBJECT(Tcl_NewDoubleObj(dResult));

			TRACE(("%.6g %.6g => %.6g\n", d1, d2, dResult));
		    } else {
			PUSH_OBJECT(Tcl_NewLongObj(iResult));

			TRACE(("%ld %ld => %ld\n", i, i2, iResult));
		    } 
		    TclDecrRefCount(valuePtr);
		} else {	    /* reuse the valuePtr object */
		    if (doDouble) { /* NB: stack top is off by 1 */

			TRACE(("%.6g %.6g => %.6g\n", d1, d2, dResult));
			Tcl_SetDoubleObj(valuePtr, dResult);
		    } else {

			TRACE(("%ld %ld => %ld\n", i, i2, iResult));
			Tcl_SetLongObj(valuePtr, iResult);
		    }
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		}
		TclDecrRefCount(value2Ptr);
	    }
	    ADJUST_PC(1);
	    
	case INST_UPLUS:
	    {
	        /*
	         * Operand must be numeric.
	         */

		double d;
		Tcl_ObjType *tPtr;
		
		valuePtr = stackPtr[stackTop];
		tPtr = valuePtr->typePtr;
		if ((tPtr != &tclIntType) && ((tPtr != &tclDoubleType)
			|| (valuePtr->bytes != NULL))) {
		    char *s = Tcl_GetStringFromObj(valuePtr, &length);
		    if (TclLooksLikeInt(s, length)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
		    } else {
			result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				valuePtr, &d);
		    }
		    if (result != TCL_OK) { 
			TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n",

			        s, (tPtr? tPtr->name : "null")));
			IllegalExprOperandType(interp, pc, valuePtr);
			goto checkForCatch;
		    }
		    tPtr = valuePtr->typePtr;
		}

		/*
		 * Ensure that the operand's string rep is the same as the
		 * formatted version of its internal rep. This makes sure
		 * that "expr +000123" yields "83", not "000123". We
		 * implement this by _discarding_ the string rep since we
		 * know it will be regenerated, if needed later, by
		 * formatting the internal rep's value.
		 */

		if (Tcl_IsShared(valuePtr)) {
		    if (tPtr == &tclIntType) {
			i = valuePtr->internalRep.longValue;
			objPtr = Tcl_NewLongObj(i);
		    } else {
			d = valuePtr->internalRep.doubleValue;
			objPtr = Tcl_NewDoubleObj(d);
		    }
		    Tcl_IncrRefCount(objPtr);
		    Tcl_DecrRefCount(valuePtr);
		    valuePtr = objPtr;
		    stackPtr[stackTop] = valuePtr;
		} else {
		    Tcl_InvalidateStringRep(valuePtr);
		}
		TRACE_WITH_OBJ(("%s => ", O2S(valuePtr)), valuePtr);
	    }
	    ADJUST_PC(1);
	    
	case INST_UMINUS:
	case INST_LNOT:
	    {
		/*
		 * The operand must be numeric. If the operand object is
		 * unshared modify it directly, otherwise create a copy to
		 * modify: this is "copy on write". free any old string
		 * representation since it is now invalid.
		 */
		
		double d;
		Tcl_ObjType *tPtr;
		
		valuePtr = POP_OBJECT();
		tPtr = valuePtr->typePtr;
		if ((tPtr != &tclIntType) && ((tPtr != &tclDoubleType)
			|| (valuePtr->bytes != NULL))) {
		    char *s = Tcl_GetStringFromObj(valuePtr, &length);
		    if (TclLooksLikeInt(s, length)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
		    } else {
			result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				valuePtr, &d);
		    }
		    if (result != TCL_OK) {
			TRACE(("\"%.20s\" => ILLEGAL TYPE %s\n",

			        s, (tPtr? tPtr->name : "null")));
			IllegalExprOperandType(interp, pc, valuePtr);
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		    tPtr = valuePtr->typePtr;
		}
		
		if (Tcl_IsShared(valuePtr)) {
		    /*
		     * Create a new object.
		     */
		    if (tPtr == &tclIntType) {
			i = valuePtr->internalRep.longValue;
			objPtr = Tcl_NewLongObj(
			        (*pc == INST_UMINUS)? -i : !i);
			TRACE_WITH_OBJ(("%ld => ", i), objPtr);

		    } else {
			d = valuePtr->internalRep.doubleValue;
			if (*pc == INST_UMINUS) {
			    objPtr = Tcl_NewDoubleObj(-d);
			} else {
			    /*
			     * Should be able to use "!d", but apparently
			     * some compilers can't handle it.
			     */
			    objPtr = Tcl_NewLongObj((d==0.0)? 1 : 0);
			}
			TRACE_WITH_OBJ(("%.6g => ", d), objPtr);

		    }
		    PUSH_OBJECT(objPtr);
		    TclDecrRefCount(valuePtr);
		} else {
		    /*
		     * valuePtr is unshared. Modify it directly.
		     */
		    if (tPtr == &tclIntType) {
			i = valuePtr->internalRep.longValue;
			Tcl_SetLongObj(valuePtr,
			        (*pc == INST_UMINUS)? -i : !i);
			TRACE_WITH_OBJ(("%ld => ", i), valuePtr);

		    } else {
			d = valuePtr->internalRep.doubleValue;
			if (*pc == INST_UMINUS) {
			    Tcl_SetDoubleObj(valuePtr, -d);
			} else {
			    /*
			     * Should be able to use "!d", but apparently
			     * some compilers can't handle it.
			     */
			    Tcl_SetLongObj(valuePtr, (d==0.0)? 1 : 0);
			}
			TRACE_WITH_OBJ(("%.6g => ", d), valuePtr);

		    }
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		}
	    }
	    ADJUST_PC(1);
	    
	case INST_BITNOT:
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512

2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544

2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577

2578
2579
2580
2581
2582
2583
2584
2585
2586
		
		valuePtr = POP_OBJECT();
		tPtr = valuePtr->typePtr;
		if (tPtr != &tclIntType) {
		    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
			    valuePtr, &i);
		    if (result != TCL_OK) {   /* try to convert to double */
			TRACE(("bitnot \"%.20s\" => ILLEGAL TYPE %s\n",
			       O2S(valuePtr), (tPtr? tPtr->name : "null")));
			IllegalExprOperandType(interp, opCode, valuePtr);
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		}
		
		i = valuePtr->internalRep.longValue;
		if (Tcl_IsShared(valuePtr)) {
		    PUSH_OBJECT(Tcl_NewLongObj(~i));
		    TRACE(("bitnot 0x%lx => (%lu)\n", i, ~i));
		    TclDecrRefCount(valuePtr);
		} else {
		    /*
		     * valuePtr is unshared. Modify it directly.
		     */
		    Tcl_SetLongObj(valuePtr, ~i);
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		    TRACE(("bitnot 0x%lx => (%lu)\n", i, ~i));
		}
	    }
	    ADJUST_PC(1);
	    
	case INST_CALL_BUILTIN_FUNC1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    {
		/*
		 * Call one of the built-in Tcl math functions.
		 */

		BuiltinFunc *mathFuncPtr;


		if ((opnd < 0) || (opnd > LAST_BUILTIN_FUNC)) {
		    TRACE(("UNRECOGNIZED BUILTIN FUNC CODE %d\n", opnd));
		    panic("TclExecuteByteCode: unrecognized builtin function code %d", opnd);
		}
		mathFuncPtr = &(builtinFuncTable[opnd]);
		DECACHE_STACK_INFO();
		tcl_MathInProgress++;
		result = (*mathFuncPtr->proc)(interp, eePtr,
		        mathFuncPtr->clientData);
		tcl_MathInProgress--;
		CACHE_STACK_INFO();
		if (result != TCL_OK) {
		    goto checkForCatch;
		}
		TRACE_WITH_OBJ(("callBuiltinFunc1 %d => ", opnd),
		        stackPtr[stackTop].o);
	    }
	    ADJUST_PC(2);
		    
	case INST_CALL_FUNC1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    {
		/*
		 * Call a non-builtin Tcl math function previously
		 * registered by a call to Tcl_CreateMathFunc.
		 */
		
		int objc = opnd;   /* Number of arguments. The function name
				    * is the 0-th argument. */
		Tcl_Obj **objv;	   /* The array of arguments. The function
				    * name is objv[0]. */

		
		objv = &(stackPtr[stackTop - (objc-1)].o); /* "objv[0]" */
		DECACHE_STACK_INFO();
		tcl_MathInProgress++;
		result = ExprCallMathFunc(interp, eePtr, objc, objv);
		tcl_MathInProgress--;
		CACHE_STACK_INFO();
		if (result != TCL_OK) {
		    goto checkForCatch;
		}
		TRACE_WITH_OBJ(("callFunc1 %d => ", objc),
		        stackPtr[stackTop].o);
		ADJUST_PC(2);
	    }

	case INST_TRY_CVT_TO_NUMERIC:
	    {
		/*
		 * Try to convert the topmost stack object to an int or
		 * double object. This is done in order to support Tcl's
		 * policy of interpreting operands if at all possible as
		 * first integers, else floating-point numbers.
		 */
		
		double d;
		char *s;
		Tcl_ObjType *tPtr;
		int converted, shared;

		valuePtr = stackPtr[stackTop].o;
		tPtr = valuePtr->typePtr;
		converted = 0;
		if ((tPtr != &tclIntType) && (tPtr != &tclDoubleType)) {

		    s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
		    if (TclLooksLikeInt(s)) { /* FAILS IF NULLS */
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
		    } else {
			result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				valuePtr, &d);
		    }
		    if (result == TCL_OK) {







|

|








|







|












>







|


|




<
|















>
|
|

|

|




<
|

















|


|
>
|
|







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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445

2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472

2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
		
		valuePtr = POP_OBJECT();
		tPtr = valuePtr->typePtr;
		if (tPtr != &tclIntType) {
		    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
			    valuePtr, &i);
		    if (result != TCL_OK) {   /* try to convert to double */
			TRACE(("\"%.20s\" => ILLEGAL TYPE %s\n",
			       O2S(valuePtr), (tPtr? tPtr->name : "null")));
			IllegalExprOperandType(interp, pc, valuePtr);
			Tcl_DecrRefCount(valuePtr);
			goto checkForCatch;
		    }
		}
		
		i = valuePtr->internalRep.longValue;
		if (Tcl_IsShared(valuePtr)) {
		    PUSH_OBJECT(Tcl_NewLongObj(~i));
		    TRACE(("0x%lx => (%lu)\n", i, ~i));
		    TclDecrRefCount(valuePtr);
		} else {
		    /*
		     * valuePtr is unshared. Modify it directly.
		     */
		    Tcl_SetLongObj(valuePtr, ~i);
		    ++stackTop; /* valuePtr now on stk top has right r.c. */
		    TRACE(("0x%lx => (%lu)\n", i, ~i));
		}
	    }
	    ADJUST_PC(1);
	    
	case INST_CALL_BUILTIN_FUNC1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    {
		/*
		 * Call one of the built-in Tcl math functions.
		 */

		BuiltinFunc *mathFuncPtr;
		ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

		if ((opnd < 0) || (opnd > LAST_BUILTIN_FUNC)) {
		    TRACE(("UNRECOGNIZED BUILTIN FUNC CODE %d\n", opnd));
		    panic("TclExecuteByteCode: unrecognized builtin function code %d", opnd);
		}
		mathFuncPtr = &(builtinFuncTable[opnd]);
		DECACHE_STACK_INFO();
		tsdPtr->mathInProgress++;
		result = (*mathFuncPtr->proc)(interp, eePtr,
		        mathFuncPtr->clientData);
		tsdPtr->mathInProgress--;
		CACHE_STACK_INFO();
		if (result != TCL_OK) {
		    goto checkForCatch;
		}

		TRACE_WITH_OBJ(("%d => ", opnd), stackPtr[stackTop]);
	    }
	    ADJUST_PC(2);
		    
	case INST_CALL_FUNC1:
	    opnd = TclGetUInt1AtPtr(pc+1);
	    {
		/*
		 * Call a non-builtin Tcl math function previously
		 * registered by a call to Tcl_CreateMathFunc.
		 */
		
		int objc = opnd;   /* Number of arguments. The function name
				    * is the 0-th argument. */
		Tcl_Obj **objv;	   /* The array of arguments. The function
				    * name is objv[0]. */
		ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

		objv = &(stackPtr[stackTop - (objc-1)]); /* "objv[0]" */
		DECACHE_STACK_INFO();
		tsdPtr->mathInProgress++;
		result = ExprCallMathFunc(interp, eePtr, objc, objv);
		tsdPtr->mathInProgress--;
		CACHE_STACK_INFO();
		if (result != TCL_OK) {
		    goto checkForCatch;
		}

		TRACE_WITH_OBJ(("%d => ", objc), stackPtr[stackTop]);
		ADJUST_PC(2);
	    }

	case INST_TRY_CVT_TO_NUMERIC:
	    {
		/*
		 * Try to convert the topmost stack object to an int or
		 * double object. This is done in order to support Tcl's
		 * policy of interpreting operands if at all possible as
		 * first integers, else floating-point numbers.
		 */
		
		double d;
		char *s;
		Tcl_ObjType *tPtr;
		int converted, shared;

		valuePtr = stackPtr[stackTop];
		tPtr = valuePtr->typePtr;
		converted = 0;
		if ((tPtr != &tclIntType) && ((tPtr != &tclDoubleType)
			|| (valuePtr->bytes != NULL))) {
		    s = Tcl_GetStringFromObj(valuePtr, &length);
		    if (TclLooksLikeInt(s, length)) {
			result = Tcl_GetLongFromObj((Tcl_Interp *) NULL,
				valuePtr, &i);
		    } else {
			result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
				valuePtr, &d);
		    }
		    if (result == TCL_OK) {
2611
2612
2613
2614
2615
2616
2617

2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771

2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787

2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
			} else {
			    d = valuePtr->internalRep.doubleValue;
			    objPtr = Tcl_NewDoubleObj(d);
			}
			Tcl_IncrRefCount(objPtr);
			TclDecrRefCount(valuePtr);
			valuePtr = objPtr;

			tPtr = valuePtr->typePtr;
		    } else {
			Tcl_InvalidateStringRep(valuePtr);
		    }
		    stackPtr[stackTop].o = valuePtr;
		
		    if (tPtr == &tclDoubleType) {
			d = valuePtr->internalRep.doubleValue;
			if (IS_NAN(d) || IS_INF(d)) {
			    TRACE(("tryCvtToNumeric \"%.20s\" => IEEE FLOATING PT ERROR\n",
			           O2S(valuePtr)));
			    TclExprFloatError(interp, d);
			    result = TCL_ERROR;
			    goto checkForCatch;
			}
		    }
		    shared = shared;		/* lint, shared not used. */
		    converted = converted;	/* lint, converted not used. */
		    TRACE(("tryCvtToNumeric \"%.20s\" => numeric, %s, %s\n",
			   O2S(valuePtr),
			   (converted? "converted" : "not converted"),
			   (shared? "shared" : "not shared")));
		} else {
		    TRACE(("tryCvtToNumeric \"%.20s\" => not numeric\n",
			   O2S(valuePtr)));
		}
	    }
	    ADJUST_PC(1);

	case INST_BREAK:
	    /*
	     * First reset the interpreter's result. Then find the closest
	     * enclosing loop or catch exception range, if any. If a loop is
	     * found, terminate its execution. If the closest is a catch
	     * exception range, jump to its catchOffset. If no enclosing
	     * range is found, stop execution and return TCL_BREAK.
	     */

	    Tcl_ResetResult(interp);
	    rangePtr = TclGetExceptionRangeForPc(pc, /*catchOnly*/ 0,
		    codePtr);
	    if (rangePtr == NULL) {
		TRACE(("break => no encl. loop or catch, returning TCL_BREAK\n"));
		result = TCL_BREAK;
		goto abnormalReturn; /* no catch exists to check */
	    }
	    switch (rangePtr->type) {
	    case LOOP_EXCEPTION_RANGE:
		result = TCL_OK;
		TRACE(("break => range at %d, new pc %d\n",
		       rangePtr->codeOffset, rangePtr->breakOffset));
		break;
	    case CATCH_EXCEPTION_RANGE:
		result = TCL_BREAK;
		TRACE(("break => ...\n"));
		goto processCatch; /* it will use rangePtr */
	    default:
		panic("TclExecuteByteCode: unrecognized ExceptionRange type %d\n", rangePtr->type);
	    }
	    pc = (codePtr->codeStart + rangePtr->breakOffset);
	    continue;	/* restart outer instruction loop at pc */

	case INST_CONTINUE:
            /*
	     * Find the closest enclosing loop or catch exception range,
	     * if any. If a loop is found, skip to its next iteration.
	     * If the closest is a catch exception range, jump to its
	     * catchOffset. If no enclosing range is found, stop
	     * execution and return TCL_CONTINUE.
	     */

	    Tcl_ResetResult(interp);
	    rangePtr = TclGetExceptionRangeForPc(pc, /*catchOnly*/ 0,
		    codePtr);
	    if (rangePtr == NULL) {
		TRACE(("continue => no encl. loop or catch, returning TCL_CONTINUE\n"));
		result = TCL_CONTINUE;
		goto abnormalReturn;
	    }
	    switch (rangePtr->type) {
	    case LOOP_EXCEPTION_RANGE:
		if (rangePtr->continueOffset == -1) {
		    TRACE(("continue => loop w/o continue, checking for catch\n"));
		    goto checkForCatch;
		} else {
		    result = TCL_OK;
		    TRACE(("continue => range at %d, new pc %d\n",
			   rangePtr->codeOffset, rangePtr->continueOffset));
		}
		break;
	    case CATCH_EXCEPTION_RANGE:
		result = TCL_CONTINUE;
		TRACE(("continue => ...\n"));
		goto processCatch; /* it will use rangePtr */
	    default:
		panic("TclExecuteByteCode: unrecognized ExceptionRange type %d\n", rangePtr->type);
	    }
	    pc = (codePtr->codeStart + rangePtr->continueOffset);
	    continue;	/* restart outer instruction loop at pc */

	case INST_FOREACH_START4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    {
	        /*
		 * Initialize the temporary local var that holds the count
		 * of the number of iterations of the loop body to -1.
		 */

		ForeachInfo *infoPtr = (ForeachInfo *)
		    codePtr->auxDataArrayPtr[opnd].clientData;
		int iterTmpIndex = infoPtr->loopIterNumTmp;
		CallFrame *varFramePtr = iPtr->varFramePtr;
		Var *compiledLocals = varFramePtr->compiledLocals;
		Var *iterVarPtr;
		Tcl_Obj *oldValuePtr;

		iterVarPtr = &(compiledLocals[iterTmpIndex]);
		oldValuePtr = iterVarPtr->value.objPtr;
		if (oldValuePtr == NULL) {
		    iterVarPtr->value.objPtr = Tcl_NewLongObj(-1);
		    Tcl_IncrRefCount(iterVarPtr->value.objPtr);
		    if (oldValuePtr != NULL) {
			Tcl_DecrRefCount(oldValuePtr);
		    }
		} else {
		    Tcl_SetLongObj(oldValuePtr, -1);
		}
		TclSetVarScalar(iterVarPtr);
		TclClearVarUndefined(iterVarPtr);
		TRACE(("foreach_start4 %u => loop iter count temp %d\n", 
		        opnd, iterTmpIndex));
	    }
	    ADJUST_PC(5);
	
	case INST_FOREACH_STEP4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    {
	        /*
		 * "Step" a foreach loop (i.e., begin its next iteration) by
		 * assigning the next value list element to each loop var.
		 */

		ForeachInfo *infoPtr = (ForeachInfo *)
		    codePtr->auxDataArrayPtr[opnd].clientData;
		ForeachVarList *varListPtr;
		int numLists = infoPtr->numLists;
		int iterTmpIndex = infoPtr->loopIterNumTmp;
		CallFrame *varFramePtr = iPtr->varFramePtr;
		Var *compiledLocals = varFramePtr->compiledLocals;
		int iterNum, listTmpIndex, listLen, numVars;
		int varIndex, valIndex, j;
		Tcl_Obj *listPtr, *elemPtr, *oldValuePtr;
		List *listRepPtr;
		Var *iterVarPtr, *listVarPtr;

		int continueLoop = 0;

		/*
		 * Increment the temp holding the loop iteration number.
		 */

		iterVarPtr = &(compiledLocals[iterTmpIndex]);
		oldValuePtr = iterVarPtr->value.objPtr;
		iterNum = (oldValuePtr->internalRep.longValue + 1);
		Tcl_SetLongObj(oldValuePtr, iterNum);
		
		/*
		 * Check whether all value lists are exhausted and we should
		 * stop the loop.
		 */


		listTmpIndex = infoPtr->firstListTmp;
		for (i = 0;  i < numLists;  i++) {
		    varListPtr = infoPtr->varLists[i];
		    numVars = varListPtr->numVars;

		    listVarPtr = &(compiledLocals[listTmpIndex]);
		    listPtr = listVarPtr->value.objPtr;
		    result = Tcl_ListObjLength(interp, listPtr, &listLen);
		    if (result != TCL_OK) {
			TRACE_WITH_OBJ(("foreach_step4 %u => ERROR converting list %ld, \"%s\": ",
			        opnd, i, O2S(listPtr)),
				Tcl_GetObjResult(interp));
			goto checkForCatch;
		    }
		    if (listLen > (iterNum * numVars)) {
			continueLoop = 1;
		    }
		    listTmpIndex++;
		}

		/*
		 * If some var in some var list still has a remaining list
		 * element iterate one more time. Assign to var the next
		 * element from its value list. We already checked above
		 * that each list temp holds a valid list object.
		 */
		
		if (continueLoop) {
		    listTmpIndex = infoPtr->firstListTmp;
		    for (i = 0;  i < numLists;  i++) {
			varListPtr = infoPtr->varLists[i];
			numVars = varListPtr->numVars;

			listVarPtr = &(compiledLocals[listTmpIndex]);
			listPtr = listVarPtr->value.objPtr;
			listRepPtr = (List *)
			        listPtr->internalRep.otherValuePtr;
			listLen = listRepPtr->elemCount;
			
			valIndex = (iterNum * numVars);
			for (j = 0;  j < numVars;  j++) {
			    int setEmptyStr = 0;
			    if (valIndex >= listLen) {
				setEmptyStr = 1;
				elemPtr = Tcl_NewObj();
			    } else {
				elemPtr = listRepPtr->elements[valIndex];
			    }
			    
			    varIndex = varListPtr->varIndexes[j];
			    DECACHE_STACK_INFO();
			    value2Ptr = TclSetIndexedScalar(interp,
			           varIndex, elemPtr, /*leaveErrorMsg*/ 1);
			    CACHE_STACK_INFO();
			    if (value2Ptr == NULL) {
				TRACE_WITH_OBJ(("foreach_step4 %u => ERROR init. index temp %d: ",
				       opnd, varIndex),
				       Tcl_GetObjResult(interp));
				if (setEmptyStr) {
				    Tcl_DecrRefCount(elemPtr); /* unneeded */
				}
				result = TCL_ERROR;
				goto checkForCatch;
			    }
			    valIndex++;
			}
			listTmpIndex++;
		    }
		}
		
		/*
		 * Now push a "1" object if at least one value list had a
		 * remaining element and the loop should continue.
		 * Otherwise push "0".
		 */

		PUSH_OBJECT(Tcl_NewLongObj(continueLoop));
		TRACE(("foreach_step4 %u => %d lists, iter %d, %s loop\n", 
		        opnd, numLists, iterNum,
		        (continueLoop? "continue" : "exit")));
	    }
	    ADJUST_PC(5);

	case INST_BEGIN_CATCH4:
	    /*
	     * Record start of the catch command with exception range index
	     * equal to the operand. Push the current stack depth onto the
	     * special catch stack.
	     */
	    catchStackPtr[++catchTop] = stackTop;
	    TRACE(("beginCatch4 %u => catchTop=%d, stackTop=%d\n",
		    TclGetUInt4AtPtr(pc+1), catchTop, stackTop));
	    ADJUST_PC(5);

	case INST_END_CATCH:
	    catchTop--;
	    result = TCL_OK;
	    TRACE(("endCatch => catchTop=%d\n", catchTop));
	    ADJUST_PC(1);

	case INST_PUSH_RESULT:
	    PUSH_OBJECT(Tcl_GetObjResult(interp));
	    TRACE_WITH_OBJ(("pushResult => "), Tcl_GetObjResult(interp));
	    ADJUST_PC(1);

	case INST_PUSH_RETURN_CODE:
	    PUSH_OBJECT(Tcl_NewLongObj(result));
	    TRACE(("pushReturnCode => %u\n", result));
	    ADJUST_PC(1);

	default:
	    TRACE(("UNRECOGNIZED INSTRUCTION %u\n", opCode));
	    panic("TclExecuteByteCode: unrecognized opCode %u", opCode);
	} /* end of switch on opCode */

	/*
	 * Division by zero in an expression. Control only reaches this
	 * point by "goto divideByZero".
	 */
	







>




<




|






|
|
|
<



|
<














|
<

|






|




|

















|
<

|






|



|





|

















|
<
|
|
|

<
<



<
<
<





|













|


<
<
|
<
<
|


>
|





|
|
|
|






>
|



|




|


















|






|
<







|

|





|


|



|











|
|
<



|












|






|




|




|



<
|







2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540

2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554

2555
2556
2557
2558

2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573

2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605

2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642

2643
2644
2645
2646


2647
2648
2649



2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671


2672


2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729

2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765

2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802

2803
2804
2805
2806
2807
2808
2809
2810
			} else {
			    d = valuePtr->internalRep.doubleValue;
			    objPtr = Tcl_NewDoubleObj(d);
			}
			Tcl_IncrRefCount(objPtr);
			TclDecrRefCount(valuePtr);
			valuePtr = objPtr;
			stackPtr[stackTop] = valuePtr;
			tPtr = valuePtr->typePtr;
		    } else {
			Tcl_InvalidateStringRep(valuePtr);
		    }

		
		    if (tPtr == &tclDoubleType) {
			d = valuePtr->internalRep.doubleValue;
			if (IS_NAN(d) || IS_INF(d)) {
			    TRACE(("\"%.20s\" => IEEE FLOATING PT ERROR\n",
			           O2S(valuePtr)));
			    TclExprFloatError(interp, d);
			    result = TCL_ERROR;
			    goto checkForCatch;
			}
		    }
		    shared = shared;        /* lint, shared not used. */
		    converted = converted;  /* lint, converted not used. */
		    TRACE(("\"%.20s\" => numeric, %s, %s\n", O2S(valuePtr),

			   (converted? "converted" : "not converted"),
			   (shared? "shared" : "not shared")));
		} else {
		    TRACE(("\"%.20s\" => not numeric\n", O2S(valuePtr)));

		}
	    }
	    ADJUST_PC(1);

	case INST_BREAK:
	    /*
	     * First reset the interpreter's result. Then find the closest
	     * enclosing loop or catch exception range, if any. If a loop is
	     * found, terminate its execution. If the closest is a catch
	     * exception range, jump to its catchOffset. If no enclosing
	     * range is found, stop execution and return TCL_BREAK.
	     */

	    Tcl_ResetResult(interp);
	    rangePtr = GetExceptRangeForPc(pc, /*catchOnly*/ 0, codePtr);

	    if (rangePtr == NULL) {
		TRACE(("=> no encl. loop or catch, returning TCL_BREAK\n"));
		result = TCL_BREAK;
		goto abnormalReturn; /* no catch exists to check */
	    }
	    switch (rangePtr->type) {
	    case LOOP_EXCEPTION_RANGE:
		result = TCL_OK;
		TRACE(("=> range at %d, new pc %d\n",
		       rangePtr->codeOffset, rangePtr->breakOffset));
		break;
	    case CATCH_EXCEPTION_RANGE:
		result = TCL_BREAK;
		TRACE(("=> ...\n"));
		goto processCatch; /* it will use rangePtr */
	    default:
		panic("TclExecuteByteCode: unrecognized ExceptionRange type %d\n", rangePtr->type);
	    }
	    pc = (codePtr->codeStart + rangePtr->breakOffset);
	    continue;	/* restart outer instruction loop at pc */

	case INST_CONTINUE:
            /*
	     * Find the closest enclosing loop or catch exception range,
	     * if any. If a loop is found, skip to its next iteration.
	     * If the closest is a catch exception range, jump to its
	     * catchOffset. If no enclosing range is found, stop
	     * execution and return TCL_CONTINUE.
	     */

	    Tcl_ResetResult(interp);
	    rangePtr = GetExceptRangeForPc(pc, /*catchOnly*/ 0, codePtr);

	    if (rangePtr == NULL) {
		TRACE(("=> no encl. loop or catch, returning TCL_CONTINUE\n"));
		result = TCL_CONTINUE;
		goto abnormalReturn;
	    }
	    switch (rangePtr->type) {
	    case LOOP_EXCEPTION_RANGE:
		if (rangePtr->continueOffset == -1) {
		    TRACE(("=> loop w/o continue, checking for catch\n"));
		    goto checkForCatch;
		} else {
		    result = TCL_OK;
		    TRACE(("=> range at %d, new pc %d\n",
			   rangePtr->codeOffset, rangePtr->continueOffset));
		}
		break;
	    case CATCH_EXCEPTION_RANGE:
		result = TCL_CONTINUE;
		TRACE(("=> ...\n"));
		goto processCatch; /* it will use rangePtr */
	    default:
		panic("TclExecuteByteCode: unrecognized ExceptionRange type %d\n", rangePtr->type);
	    }
	    pc = (codePtr->codeStart + rangePtr->continueOffset);
	    continue;	/* restart outer instruction loop at pc */

	case INST_FOREACH_START4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    {
	        /*
		 * Initialize the temporary local var that holds the count
		 * of the number of iterations of the loop body to -1.
		 */

		ForeachInfo *infoPtr = (ForeachInfo *)
		    codePtr->auxDataArrayPtr[opnd].clientData;
		int iterTmpIndex = infoPtr->loopCtTemp;

		Var *compiledLocals = iPtr->varFramePtr->compiledLocals;
		Var *iterVarPtr = &(compiledLocals[iterTmpIndex]);
		Tcl_Obj *oldValuePtr = iterVarPtr->value.objPtr;



		if (oldValuePtr == NULL) {
		    iterVarPtr->value.objPtr = Tcl_NewLongObj(-1);
		    Tcl_IncrRefCount(iterVarPtr->value.objPtr);



		} else {
		    Tcl_SetLongObj(oldValuePtr, -1);
		}
		TclSetVarScalar(iterVarPtr);
		TclClearVarUndefined(iterVarPtr);
		TRACE(("%u => loop iter count temp %d\n", 
		        opnd, iterTmpIndex));
	    }
	    ADJUST_PC(5);
	
	case INST_FOREACH_STEP4:
	    opnd = TclGetUInt4AtPtr(pc+1);
	    {
	        /*
		 * "Step" a foreach loop (i.e., begin its next iteration) by
		 * assigning the next value list element to each loop var.
		 */

		ForeachInfo *infoPtr = (ForeachInfo *)
		        codePtr->auxDataArrayPtr[opnd].clientData;
		ForeachVarList *varListPtr;
		int numLists = infoPtr->numLists;


		Var *compiledLocals = iPtr->varFramePtr->compiledLocals;


		Tcl_Obj *listPtr;
		List *listRepPtr;
		Var *iterVarPtr, *listVarPtr;
		int iterNum, listTmpIndex, listLen, numVars;
		int varIndex, valIndex, continueLoop, j;

		/*
		 * Increment the temp holding the loop iteration number.
		 */

		iterVarPtr = &(compiledLocals[infoPtr->loopCtTemp]);
		valuePtr = iterVarPtr->value.objPtr;
		iterNum = (valuePtr->internalRep.longValue + 1);
		Tcl_SetLongObj(valuePtr, iterNum);
		
		/*
		 * Check whether all value lists are exhausted and we should
		 * stop the loop.
		 */

		continueLoop = 0;
		listTmpIndex = infoPtr->firstValueTemp;
		for (i = 0;  i < numLists;  i++) {
		    varListPtr = infoPtr->varLists[i];
		    numVars = varListPtr->numVars;
		    
		    listVarPtr = &(compiledLocals[listTmpIndex]);
		    listPtr = listVarPtr->value.objPtr;
		    result = Tcl_ListObjLength(interp, listPtr, &listLen);
		    if (result != TCL_OK) {
			TRACE_WITH_OBJ(("%u => ERROR converting list %ld, \"%s\": ",
			        opnd, i, O2S(listPtr)),
				Tcl_GetObjResult(interp));
			goto checkForCatch;
		    }
		    if (listLen > (iterNum * numVars)) {
			continueLoop = 1;
		    }
		    listTmpIndex++;
		}

		/*
		 * If some var in some var list still has a remaining list
		 * element iterate one more time. Assign to var the next
		 * element from its value list. We already checked above
		 * that each list temp holds a valid list object.
		 */
		
		if (continueLoop) {
		    listTmpIndex = infoPtr->firstValueTemp;
		    for (i = 0;  i < numLists;  i++) {
			varListPtr = infoPtr->varLists[i];
			numVars = varListPtr->numVars;

			listVarPtr = &(compiledLocals[listTmpIndex]);
			listPtr = listVarPtr->value.objPtr;
			listRepPtr = (List *) listPtr->internalRep.otherValuePtr;

			listLen = listRepPtr->elemCount;
			
			valIndex = (iterNum * numVars);
			for (j = 0;  j < numVars;  j++) {
			    int setEmptyStr = 0;
			    if (valIndex >= listLen) {
				setEmptyStr = 1;
				valuePtr = Tcl_NewObj();
			    } else {
				valuePtr = listRepPtr->elements[valIndex];
			    }
			    
			    varIndex = varListPtr->varIndexes[j];
			    DECACHE_STACK_INFO();
			    value2Ptr = TclSetIndexedScalar(interp,
			           varIndex, valuePtr, /*leaveErrorMsg*/ 1);
			    CACHE_STACK_INFO();
			    if (value2Ptr == NULL) {
				TRACE_WITH_OBJ(("%u => ERROR init. index temp %d: ",
				       opnd, varIndex),
				       Tcl_GetObjResult(interp));
				if (setEmptyStr) {
				    Tcl_DecrRefCount(valuePtr);
				}
				result = TCL_ERROR;
				goto checkForCatch;
			    }
			    valIndex++;
			}
			listTmpIndex++;
		    }
		}
		
		/*
		 * Push 1 if at least one value list had a remaining element
		 * and the loop should continue. Otherwise push 0.

		 */

		PUSH_OBJECT(Tcl_NewLongObj(continueLoop));
		TRACE(("%u => %d lists, iter %d, %s loop\n", 
		        opnd, numLists, iterNum,
		        (continueLoop? "continue" : "exit")));
	    }
	    ADJUST_PC(5);

	case INST_BEGIN_CATCH4:
	    /*
	     * Record start of the catch command with exception range index
	     * equal to the operand. Push the current stack depth onto the
	     * special catch stack.
	     */
	    catchStackPtr[++catchTop] = stackTop;
	    TRACE(("%u => catchTop=%d, stackTop=%d\n",
		    TclGetUInt4AtPtr(pc+1), catchTop, stackTop));
	    ADJUST_PC(5);

	case INST_END_CATCH:
	    catchTop--;
	    result = TCL_OK;
	    TRACE(("=> catchTop=%d\n", catchTop));
	    ADJUST_PC(1);

	case INST_PUSH_RESULT:
	    PUSH_OBJECT(Tcl_GetObjResult(interp));
	    TRACE_WITH_OBJ(("=> "), Tcl_GetObjResult(interp));
	    ADJUST_PC(1);

	case INST_PUSH_RETURN_CODE:
	    PUSH_OBJECT(Tcl_NewLongObj(result));
	    TRACE(("=> %u\n", result));
	    ADJUST_PC(1);

	default:

	    panic("TclExecuteByteCode: unrecognized opCode %u", *pc);
	} /* end of switch on opCode */

	/*
	 * Division by zero in an expression. Control only reaches this
	 * point by "goto divideByZero".
	 */
	
2918
2919
2920
2921
2922
2923
2924
2925



2926

2927
2928


2929
2930


2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947


2948
2949
2950


2951
2952
2953
2954
2955
2956
2957
	 * executed when the error occurred. Find the closest enclosing
	 * catch range, if any. If no enclosing catch range is found, stop
	 * execution and return the "exception" code.
	 */
	
        checkForCatch:
	if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
	    RecordTracebackInfo(interp, pc, codePtr);



        }

	rangePtr = TclGetExceptionRangeForPc(pc, /*catchOnly*/ 1, codePtr);
	if (rangePtr == NULL) {


	    TRACE(("   ... no enclosing catch, returning %s\n",
		    StringForResultCode(result)));


	    goto abnormalReturn;
	}

	/*
	 * A catch exception range (rangePtr) was found to handle an
	 * "exception". It was found either by checkForCatch just above or
	 * by an instruction during break, continue, or error processing.
	 * Jump to its catchOffset after unwinding the operand stack to
	 * the depth it had when starting to execute the range's catch
	 * command.
	 */

        processCatch:
	while (stackTop > catchStackPtr[catchTop]) {
	    valuePtr = POP_OBJECT();
	    TclDecrRefCount(valuePtr);
	}


	TRACE(("  ... found catch at %d, catchTop=%d, unwound to %d, new pc %u\n",
	        rangePtr->codeOffset, catchTop, catchStackPtr[catchTop],
	        (unsigned int)(rangePtr->catchOffset)));


	pc = (codePtr->codeStart + rangePtr->catchOffset);
	continue;		/* restart the execution loop at pc */
    } /* end of infinite loop dispatching on instructions */

    /*
     * Abnormal return code. Restore the stack to state it had when starting
     * to execute the ByteCode.







|
>
>
>
|
>
|

>
>
|
|
>
>

















>
>
|

|
>
>







2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
	 * executed when the error occurred. Find the closest enclosing
	 * catch range, if any. If no enclosing catch range is found, stop
	 * execution and return the "exception" code.
	 */
	
        checkForCatch:
	if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
	    bytes = GetSrcInfoForPc(pc, codePtr, &length);
	    if (bytes != NULL) {
		Tcl_LogCommandInfo(interp, codePtr->source, bytes, length);
		iPtr->flags |= ERR_ALREADY_LOGGED;
	    }
        }
	rangePtr = GetExceptRangeForPc(pc, /*catchOnly*/ 1, codePtr);
	if (rangePtr == NULL) {
#ifdef TCL_COMPILE_DEBUG
	    if (traceInstructions) {
		fprintf(stdout, "   ... no enclosing catch, returning %s\n",
		        StringForResultCode(result));
	    }
#endif
	    goto abnormalReturn;
	}

	/*
	 * A catch exception range (rangePtr) was found to handle an
	 * "exception". It was found either by checkForCatch just above or
	 * by an instruction during break, continue, or error processing.
	 * Jump to its catchOffset after unwinding the operand stack to
	 * the depth it had when starting to execute the range's catch
	 * command.
	 */

        processCatch:
	while (stackTop > catchStackPtr[catchTop]) {
	    valuePtr = POP_OBJECT();
	    TclDecrRefCount(valuePtr);
	}
#ifdef TCL_COMPILE_DEBUG
	if (traceInstructions) {
	    fprintf(stdout, "  ... found catch at %d, catchTop=%d, unwound to %d, new pc %u\n",
	        rangePtr->codeOffset, catchTop, catchStackPtr[catchTop],
	        (unsigned int)(rangePtr->catchOffset));
	}
#endif	
	pc = (codePtr->codeStart + rangePtr->catchOffset);
	continue;		/* restart the execution loop at pc */
    } /* end of infinite loop dispatching on instructions */

    /*
     * Abnormal return code. Restore the stack to state it had when starting
     * to execute the ByteCode.
2972
2973
2974
2975
2976
2977
2978

2979
2980
2981
2982
2983
2984
2985
	ckfree((char *) catchStackPtr);
    }
    eePtr->stackTop = initStackTop;
    return result;
#undef STATIC_CATCH_STACK_SIZE
}


/*
 *----------------------------------------------------------------------
 *
 * PrintByteCodeInfo --
 *
 *	This procedure prints a summary about a bytecode object to stdout.
 *	It is called by TclExecuteByteCode when starting to execute the







>







2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
	ckfree((char *) catchStackPtr);
    }
    eePtr->stackTop = initStackTop;
    return result;
#undef STATIC_CATCH_STACK_SIZE
}

#ifdef TCL_COMPILE_DEBUG
/*
 *----------------------------------------------------------------------
 *
 * PrintByteCodeInfo --
 *
 *	This procedure prints a summary about a bytecode object to stdout.
 *	It is called by TclExecuteByteCode when starting to execute the
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023

3024
3025

3026
3027
3028



3029


3030

3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041

3042
3043
3044
3045
3046
3047
3048

static void
PrintByteCodeInfo(codePtr)
    register ByteCode *codePtr;	/* The bytecode whose summary is printed
				 * to stdout. */
{
    Proc *procPtr = codePtr->procPtr;
    int numCmds = codePtr->numCommands;
    int numObjs = codePtr->numObjects;
    int objBytes, i;

    objBytes = (numObjs * sizeof(Tcl_Obj));
    for (i = 0;  i < numObjs;  i++) {
	Tcl_Obj *litObjPtr = codePtr->objArrayPtr[i];
	if (litObjPtr->bytes != NULL) {
	    objBytes += litObjPtr->length;
	}
    }
    
    fprintf(stdout, "\nExecuting ByteCode 0x%x, ref ct %u, epoch %u, interp 0x%x(epoch %u)\n",
	    (unsigned int) codePtr, codePtr->refCount,
	    codePtr->compileEpoch, (unsigned int) codePtr->iPtr,
	    codePtr->iPtr->compileEpoch);
    
    fprintf(stdout, "  Source: ");
    TclPrintSource(stdout, codePtr->source, 70);

    fprintf(stdout, "\n  Cmds %d, chars %d, inst %u, objs %u, aux %d, stk depth %u, code/src %.2fn",

            numCmds, codePtr->numSrcChars, codePtr->numCodeBytes, numObjs,
	    codePtr->numAuxDataItems, codePtr->maxStackDepth,

	    (codePtr->numSrcChars?
	            ((float)codePtr->totalSize)/((float)codePtr->numSrcChars) : 0.0));




    fprintf(stdout, "  Code %d = %d(header)+%d(inst)+%d(objs)+%d(exc)+%d(aux)+%d(cmd map)\n",


	    codePtr->totalSize, sizeof(ByteCode), codePtr->numCodeBytes,

	    objBytes, (codePtr->numExcRanges * sizeof(ExceptionRange)),
	    (codePtr->numAuxDataItems * sizeof(AuxData)),
	    codePtr->numCmdLocBytes);

    if (procPtr != NULL) {
	fprintf(stdout,
		"  Proc 0x%x, ref ct %d, args %d, compiled locals %d\n",
		(unsigned int) procPtr, procPtr->refCount,
		procPtr->numArgs, procPtr->numCompiledLocals);
    }
}


/*
 *----------------------------------------------------------------------
 *
 * ValidatePcAndStackTop --
 *
 *	This procedure is called by TclExecuteByteCode when debugging to







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

|
|


|

|
>
|

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


|


|




>







2912
2913
2914
2915
2916
2917
2918



2919





2920


2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963

static void
PrintByteCodeInfo(codePtr)
    register ByteCode *codePtr;	/* The bytecode whose summary is printed
				 * to stdout. */
{
    Proc *procPtr = codePtr->procPtr;



    Interp *iPtr = (Interp *) *codePtr->interpHandle;








    fprintf(stdout, "\nExecuting ByteCode 0x%x, refCt %u, epoch %u, interp 0x%x (epoch %u)\n",
	    (unsigned int) codePtr, codePtr->refCount,
	    codePtr->compileEpoch, (unsigned int) iPtr,
	    iPtr->compileEpoch);
    
    fprintf(stdout, "  Source: ");
    TclPrintSource(stdout, codePtr->source, 60);

    fprintf(stdout, "\n  Cmds %d, src %d, inst %u, litObjs %u, aux %d, stkDepth %u, code/src %.2f\n",
            codePtr->numCommands, codePtr->numSrcBytes,
	    codePtr->numCodeBytes, codePtr->numLitObjects,
	    codePtr->numAuxDataItems, codePtr->maxStackDepth,
#ifdef TCL_COMPILE_STATS
	    (codePtr->numSrcBytes?
	            ((float)codePtr->structureSize)/((float)codePtr->numSrcBytes) : 0.0));
#else
	    0.0);
#endif
#ifdef TCL_COMPILE_STATS
    fprintf(stdout, "  Code %d = header %d+inst %d+litObj %d+exc %d+aux %d+cmdMap %d\n",
	    codePtr->structureSize,
	    (sizeof(ByteCode) - (sizeof(size_t) + sizeof(Tcl_Time))),
	    codePtr->numCodeBytes,
	    (codePtr->numLitObjects * sizeof(Tcl_Obj *)),
	    (codePtr->numExceptRanges * sizeof(ExceptionRange)),
	    (codePtr->numAuxDataItems * sizeof(AuxData)),
	    codePtr->numCmdLocBytes);
#endif /* TCL_COMPILE_STATS */
    if (procPtr != NULL) {
	fprintf(stdout,
		"  Proc 0x%x, refCt %d, args %d, compiled locals %d\n",
		(unsigned int) procPtr, procPtr->refCount,
		procPtr->numArgs, procPtr->numCompiledLocals);
    }
}
#endif /* TCL_COMPILE_DEBUG */

/*
 *----------------------------------------------------------------------
 *
 * ValidatePcAndStackTop --
 *
 *	This procedure is called by TclExecuteByteCode when debugging to
3057
3058
3059
3060
3061
3062
3063
3064

3065
3066
3067
3068
3069
3070
3071
 *	top are invalid.
 *
 *----------------------------------------------------------------------
 */

#ifdef TCL_COMPILE_DEBUG
static void
ValidatePcAndStackTop(codePtr, pc, stackTop, stackLowerBound, stackUpperBound)

    register ByteCode *codePtr; /* The bytecode whose summary is printed
				 * to stdout. */
    unsigned char *pc;		/* Points to first byte of a bytecode
				 * instruction. The program counter. */
    int stackTop;		/* Current stack top. Must be between
				 * stackLowerBound and stackUpperBound
				 * (inclusive). */







|
>







2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
 *	top are invalid.
 *
 *----------------------------------------------------------------------
 */

#ifdef TCL_COMPILE_DEBUG
static void
ValidatePcAndStackTop(codePtr, pc, stackTop, stackLowerBound,
        stackUpperBound)
    register ByteCode *codePtr; /* The bytecode whose summary is printed
				 * to stdout. */
    unsigned char *pc;		/* Points to first byte of a bytecode
				 * instruction. The program counter. */
    int stackTop;		/* Current stack top. Must be between
				 * stackLowerBound and stackUpperBound
				 * (inclusive). */
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140



3141
3142
3143
3144
3145
3146














3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
/*
 *----------------------------------------------------------------------
 *
 * IllegalExprOperandType --
 *
 *	Used by TclExecuteByteCode to add an error message to errorInfo
 *	when an illegal operand type is detected by an expression
 *	instruction. The argument opCode holds the failing instruction's
 *	opcode and opndPtr holds the operand object in error.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	An error message is appended to errorInfo.
 *
 *----------------------------------------------------------------------
 */

static void
IllegalExprOperandType(interp, opCode, opndPtr)
    Tcl_Interp *interp;		/* Interpreter to which error information
				 * pertains. */
    unsigned int opCode;	/* The instruction opcode being executed
				 * when the illegal type was found. */
    Tcl_Obj *opndPtr;		/* Points to the operand holding the value
				 * with the illegal type. */
{



    Tcl_ResetResult(interp);
    if ((opndPtr->bytes == NULL) || (opndPtr->length == 0)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"can't use empty string as operand of \"",
		operatorStrings[opCode - INST_LOR], "\"", (char *) NULL);
    } else {














	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't use ",
		((opndPtr->typePtr == &tclDoubleType) ?
		    "floating-point value" : "non-numeric string"),
		" as operand of \"", operatorStrings[opCode - INST_LOR],
		"\"", (char *) NULL);
    }
}

/*
 *----------------------------------------------------------------------







<
|











|


|




>
>
>






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

<
|







3029
3030
3031
3032
3033
3034
3035

3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079

3080
3081
3082
3083
3084
3085
3086
3087
/*
 *----------------------------------------------------------------------
 *
 * IllegalExprOperandType --
 *
 *	Used by TclExecuteByteCode to add an error message to errorInfo
 *	when an illegal operand type is detected by an expression

 *	instruction. The argument opndPtr holds the operand object in error.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	An error message is appended to errorInfo.
 *
 *----------------------------------------------------------------------
 */

static void
IllegalExprOperandType(interp, pc, opndPtr)
    Tcl_Interp *interp;		/* Interpreter to which error information
				 * pertains. */
    unsigned char *pc;		/* Points to the instruction being executed
				 * when the illegal type was found. */
    Tcl_Obj *opndPtr;		/* Points to the operand holding the value
				 * with the illegal type. */
{
    unsigned char opCode = *pc;
    int isDouble;
    
    Tcl_ResetResult(interp);
    if ((opndPtr->bytes == NULL) || (opndPtr->length == 0)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"can't use empty string as operand of \"",
		operatorStrings[opCode - INST_LOR], "\"", (char *) NULL);
    } else {
	isDouble = 1;
	if (opndPtr->typePtr != &tclDoubleType) {
	    /*
	     * See if the operand can be interpreted as a double in order to
	     * improve the error message.
	     */

	    char *s = Tcl_GetString(opndPtr);
	    double d;

	    if (Tcl_GetDouble((Tcl_Interp *) NULL, s, &d) != TCL_OK) {
		isDouble = 0;
	    }
	}
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't use ",

		(isDouble? "floating-point value" : "non-numeric string"),
		" as operand of \"", operatorStrings[opCode - INST_LOR],
		"\"", (char *) NULL);
    }
}

/*
 *----------------------------------------------------------------------
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
    int length;
    char *p;

    /*
     * Get the string rep from the objv argument objects and place their
     * pointers in argv. First make sure argv is large enough to hold the
     * objc args plus 1 extra word for the zero end-of-argv word.
     * THIS FAILS IF AN OBJECT'S STRING REP CONTAINS NULLS.
     */
    
    argv = (char **) ckalloc((unsigned)(objc + 1) * sizeof(char *));
    for (i = 0;  i < objc;  i++) {
	argv[i] = Tcl_GetStringFromObj(objv[i], &length);
    }
    argv[objc] = 0;







<







3120
3121
3122
3123
3124
3125
3126

3127
3128
3129
3130
3131
3132
3133
    int length;
    char *p;

    /*
     * Get the string rep from the objv argument objects and place their
     * pointers in argv. First make sure argv is large enough to hold the
     * objc args plus 1 extra word for the zero end-of-argv word.

     */
    
    argv = (char **) ckalloc((unsigned)(objc + 1) * sizeof(char *));
    for (i = 0;  i < objc;  i++) {
	argv[i] = Tcl_GetStringFromObj(objv[i], &length);
    }
    argv[objc] = 0;
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
    
    (*tracePtr->proc)(tracePtr->clientData, interp, iPtr->numLevels,
                      p, cmdPtr->proc, cmdPtr->clientData, objc, argv);

    ckfree((char *) argv);
    ckfree((char *) p);
}

/*
 *----------------------------------------------------------------------
 *
 * RecordTracebackInfo --
 *
 *      Procedure called by TclExecuteByteCode to record information
 *      about what was being executed when the error occurred.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      Appends information about the command being executed to the
 *      "errorInfo" variable. Sets the errorLine field in the interpreter
 *      to the line number of that command. Sets the ERR_ALREADY_LOGGED
 *      bit in the interpreter's execution flags.
 *
 *----------------------------------------------------------------------
 */

static void
RecordTracebackInfo(interp, pc, codePtr)
    Tcl_Interp *interp;         /* The interpreter in which the error
                                 * occurred. */
    unsigned char *pc;          /* The program counter value where the error                                 * occurred. This points to a bytecode
                                 * instruction in codePtr's code. */
    ByteCode *codePtr;          /* The bytecode sequence being executed. */
{
    register Interp *iPtr = (Interp *) interp;
    char *cmd, *ellipsis;
    char buf[200];
    register char *p;
    int numChars;
    
    /*
     * Record the command in errorInfo (up to a certain number of
     * characters, or up to the first newline).
     */
    
    iPtr->errorLine = 1;
    cmd = GetSrcInfoForPc(pc, codePtr, &numChars);
    if (cmd != NULL) {
        for (p = codePtr->source;  p != cmd;  p++) {
            if (*p == '\n') {
                iPtr->errorLine++;
            }
        }
        for ( ;  (isspace(UCHAR(*p)) || (*p == ';'));  p++) {
            if (*p == '\n') {
                iPtr->errorLine++;
            }
        }
	
        ellipsis = "";
        if (numChars > 150) {
            numChars = 150;
            ellipsis = "...";
        }
        if (!(iPtr->flags & ERR_IN_PROGRESS)) {
            sprintf(buf, "\n    while executing\n\"%.*s%s\"",
                    numChars, cmd, ellipsis);
        } else {
            sprintf(buf, "\n    invoked from within\n\"%.*s%s\"",
                    numChars, cmd, ellipsis);
        }
        Tcl_AddObjErrorInfo(interp, buf, -1);
        iPtr->flags |= ERR_ALREADY_LOGGED;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetSrcInfoForPc --
 *
 *	Given a program counter value, finds the closest command in the







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







3146
3147
3148
3149
3150
3151
3152






































































3153
3154
3155
3156
3157
3158
3159
    
    (*tracePtr->proc)(tracePtr->clientData, interp, iPtr->numLevels,
                      p, cmdPtr->proc, cmdPtr->clientData, objc, argv);

    ckfree((char *) argv);
    ckfree((char *) p);
}







































































/*
 *----------------------------------------------------------------------
 *
 * GetSrcInfoForPc --
 *
 *	Given a program counter value, finds the closest command in the
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459





3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477






























3478
3479
3480
3481
3482
3483
3484
    }
    return (codePtr->source + bestSrcOffset);
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetExceptionRangeForPc --
 *
 *	Procedure that given a program counter value, returns the closest
 *	enclosing ExceptionRange that matches the kind requested.
 *
 * Results:
 *	In the normal case, catchOnly is 0 (false) and this procedure
 *	returns a pointer to the most closely enclosing ExceptionRange
 *	structure regardless of whether it is a loop or catch exception
 *	range. This is appropriate when processing a TCL_BREAK or
 *	TCL_CONTINUE, which will be "handled" either by a loop exception
 *	range or a closer catch range. If catchOnly is nonzero (true), this
 *	procedure ignores loop exception ranges and returns a pointer to the
 *	closest catch range. If no matching ExceptionRange is found that
 *	encloses pc, a NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

ExceptionRange *
TclGetExceptionRangeForPc(pc, catchOnly, codePtr)
    unsigned char *pc;		/* The program counter value for which to
				 * search for a closest enclosing exception
				 * range. This points to a bytecode
				 * instruction in codePtr's code. */
    int catchOnly;		/* If 0, consider either loop or catch
				 * ExceptionRanges in search. Otherwise
				 * consider only catch ranges (and ignore
				 * any closer loop ranges). */
    ByteCode* codePtr;		/* Points to the ByteCode in which to search
				 * for the enclosing ExceptionRange. */
{
    ExceptionRange *rangeArrayPtr = codePtr->excRangeArrayPtr;
    int numRanges = codePtr->numExcRanges;
    register ExceptionRange *rangePtr;
    int codeOffset = (pc - codePtr->codeStart);
    register int i, level;






    for (level = codePtr->maxExcRangeDepth;  level >= 0;  level--) {
	for (i = 0;  i < numRanges;  i++) {
	    rangePtr = &(rangeArrayPtr[i]);
	    if (rangePtr->nestingLevel == level) {
		int start = rangePtr->codeOffset;
		int end   = (start + rangePtr->numCodeBytes);
		if ((start <= codeOffset) && (codeOffset < end)) {
		    if ((!catchOnly)
			    || (rangePtr->type == CATCH_EXCEPTION_RANGE)) {
			return rangePtr;
		    }
		}
	    }
	}
    }
    return NULL;
}































/*
 *----------------------------------------------------------------------
 *
 * Math Functions --
 *
 *	This page contains the procedures that implement all of the
 *	built-in math functions for expressions.







|

|
|







|










|
|





|





|
|

|


>
>
>
>
>
|





|











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







3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
    }
    return (codePtr->source + bestSrcOffset);
}

/*
 *----------------------------------------------------------------------
 *
 * GetExceptRangeForPc --
 *
 *	Given a program counter value, return the closest enclosing
 *	ExceptionRange.
 *
 * Results:
 *	In the normal case, catchOnly is 0 (false) and this procedure
 *	returns a pointer to the most closely enclosing ExceptionRange
 *	structure regardless of whether it is a loop or catch exception
 *	range. This is appropriate when processing a TCL_BREAK or
 *	TCL_CONTINUE, which will be "handled" either by a loop exception
 *	range or a closer catch range. If catchOnly is nonzero, this
 *	procedure ignores loop exception ranges and returns a pointer to the
 *	closest catch range. If no matching ExceptionRange is found that
 *	encloses pc, a NULL is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static ExceptionRange *
GetExceptRangeForPc(pc, catchOnly, codePtr)
    unsigned char *pc;		/* The program counter value for which to
				 * search for a closest enclosing exception
				 * range. This points to a bytecode
				 * instruction in codePtr's code. */
    int catchOnly;		/* If 0, consider either loop or catch
				 * ExceptionRanges in search. If nonzero
				 * consider only catch ranges (and ignore
				 * any closer loop ranges). */
    ByteCode* codePtr;		/* Points to the ByteCode in which to search
				 * for the enclosing ExceptionRange. */
{
    ExceptionRange *rangeArrayPtr;
    int numRanges = codePtr->numExceptRanges;
    register ExceptionRange *rangePtr;
    int pcOffset = (pc - codePtr->codeStart);
    register int i, level;

    if (numRanges == 0) {
	return NULL;
    }
    rangeArrayPtr = codePtr->exceptArrayPtr;

    for (level = codePtr->maxExceptDepth;  level >= 0;  level--) {
	for (i = 0;  i < numRanges;  i++) {
	    rangePtr = &(rangeArrayPtr[i]);
	    if (rangePtr->nestingLevel == level) {
		int start = rangePtr->codeOffset;
		int end   = (start + rangePtr->numCodeBytes);
		if ((start <= pcOffset) && (pcOffset < end)) {
		    if ((!catchOnly)
			    || (rangePtr->type == CATCH_EXCEPTION_RANGE)) {
			return rangePtr;
		    }
		}
	    }
	}
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * GetOpcodeName --
 *
 *	This procedure is called by the TRACE and TRACE_WITH_OBJ macros
 *	used in TclExecuteByteCode when debugging. It returns the name of
 *	the bytecode instruction at a specified instruction pc.
 *
 * Results:
 *	A character string for the instruction.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#ifdef TCL_COMPILE_DEBUG
static char *
GetOpcodeName(pc)
    unsigned char *pc;		/* Points to the instruction whose name
				 * should be returned. */
{
    unsigned char opCode = *pc;
    
    return instructionTable[opCode].name;
}
#endif /* TCL_COMPILE_DEBUG */

/*
 *----------------------------------------------------------------------
 *
 * Math Functions --
 *
 *	This page contains the procedures that implement all of the
 *	built-in math functions for expressions.
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521

3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Contains the address of a procedure that
				 * takes one double argument and returns a
				 * double result. */
{
    StackItem *stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    register Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    double d, dResult;
    long i;
    int result = TCL_OK;
    
    double (*func) _ANSI_ARGS_((double)) =
	(double (*)_ANSI_ARGS_((double))) clientData;

    /*
     * Set stackPtr and stackTop from eePtr.
     */
    

    CACHE_STACK_INFO();

    /*
     * Pop the function's argument from the evaluation stack. Convert it
     * to a double if necessary.
     */

    valuePtr = POP_OBJECT();
    tPtr = valuePtr->typePtr;
    
    if (tPtr == &tclIntType) {
	d = (double) valuePtr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d = valuePtr->internalRep.doubleValue;
    } else {			/* FAILS IF STRING REP HAS NULLS */
	char *s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
	
	if (TclLooksLikeInt(s)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	    d = (double) valuePtr->internalRep.longValue;
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr, &d);
	}
	if (result != TCL_OK) {
	    Tcl_ResetResult(interp);







|





|







|
>














|
|

|







3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Contains the address of a procedure that
				 * takes one double argument and returns a
				 * double result. */
{
    Tcl_Obj **stackPtr;		/* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    register Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    double d, dResult;
    long i;
    int length, result;
    
    double (*func) _ANSI_ARGS_((double)) =
	(double (*)_ANSI_ARGS_((double))) clientData;

    /*
     * Set stackPtr and stackTop from eePtr.
     */

    result = TCL_OK;
    CACHE_STACK_INFO();

    /*
     * Pop the function's argument from the evaluation stack. Convert it
     * to a double if necessary.
     */

    valuePtr = POP_OBJECT();
    tPtr = valuePtr->typePtr;
    
    if (tPtr == &tclIntType) {
	d = (double) valuePtr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d = valuePtr->internalRep.doubleValue;
    } else {
	char *s = Tcl_GetStringFromObj(valuePtr, &length);
	
	if (TclLooksLikeInt(s, length)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	    d = (double) valuePtr->internalRep.longValue;
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr, &d);
	}
	if (result != TCL_OK) {
	    Tcl_ResetResult(interp);
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602

3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Contains the address of a procedure that
				 * takes two double arguments and
				 * returns a double result. */
{
    StackItem *stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    register Tcl_Obj *valuePtr, *value2Ptr;
    Tcl_ObjType *tPtr;
    double d1, d2, dResult;
    long i;
    char *s;
    int result = TCL_OK;
    
    double (*func) _ANSI_ARGS_((double, double))
	= (double (*)_ANSI_ARGS_((double, double))) clientData;

    /*
     * Set stackPtr and stackTop from eePtr.
     */
    

    CACHE_STACK_INFO();

    /*
     * Pop the function's two arguments from the evaluation stack. Convert
     * them to doubles if necessary.
     */

    value2Ptr = POP_OBJECT();
    valuePtr  = POP_OBJECT();

    tPtr = valuePtr->typePtr;
    if (tPtr == &tclIntType) {
	d1 = (double) valuePtr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d1 = valuePtr->internalRep.doubleValue;
    } else {			/* FAILS IF STRING REP HAS NULLS */
	s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
	if (TclLooksLikeInt(s)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	    d1 = (double) valuePtr->internalRep.longValue;
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr, &d1);
	}
	if (result != TCL_OK) {
            badArg:
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	            "argument to math function didn't have numeric value", -1);
	    goto done;
	}
    }

    tPtr = value2Ptr->typePtr;
    if (tPtr == &tclIntType) {
	d2 = value2Ptr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d2 = value2Ptr->internalRep.doubleValue;
    } else {			/* FAILS IF STRING REP HAS NULLS */
	s = Tcl_GetStringFromObj(value2Ptr, (int *) NULL);
	if (TclLooksLikeInt(s)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, value2Ptr, &i);
	    d2 = (double) value2Ptr->internalRep.longValue;
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, value2Ptr, &d2);
	}
	if (result != TCL_OK) {
	    goto badArg;







|






|







|
>















|
|
|



















|
|
|







3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Contains the address of a procedure that
				 * takes two double arguments and
				 * returns a double result. */
{
    Tcl_Obj **stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    register Tcl_Obj *valuePtr, *value2Ptr;
    Tcl_ObjType *tPtr;
    double d1, d2, dResult;
    long i;
    char *s;
    int length, result;
    
    double (*func) _ANSI_ARGS_((double, double))
	= (double (*)_ANSI_ARGS_((double, double))) clientData;

    /*
     * Set stackPtr and stackTop from eePtr.
     */

    result = TCL_OK;
    CACHE_STACK_INFO();

    /*
     * Pop the function's two arguments from the evaluation stack. Convert
     * them to doubles if necessary.
     */

    value2Ptr = POP_OBJECT();
    valuePtr  = POP_OBJECT();

    tPtr = valuePtr->typePtr;
    if (tPtr == &tclIntType) {
	d1 = (double) valuePtr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d1 = valuePtr->internalRep.doubleValue;
    } else {
	s = Tcl_GetStringFromObj(valuePtr, &length);
	if (TclLooksLikeInt(s, length)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	    d1 = (double) valuePtr->internalRep.longValue;
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr, &d1);
	}
	if (result != TCL_OK) {
            badArg:
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	            "argument to math function didn't have numeric value", -1);
	    goto done;
	}
    }

    tPtr = value2Ptr->typePtr;
    if (tPtr == &tclIntType) {
	d2 = value2Ptr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d2 = value2Ptr->internalRep.doubleValue;
    } else {
	s = Tcl_GetStringFromObj(value2Ptr, &length);
	if (TclLooksLikeInt(s, length)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, value2Ptr, &i);
	    d2 = (double) value2Ptr->internalRep.longValue;
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, value2Ptr, &d2);
	}
	if (result != TCL_OK) {
	    goto badArg;
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697

3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
ExprAbsFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    StackItem *stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    register Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    long i, iResult;
    double d, dResult;
    int result = TCL_OK;

    /*
     * Set stackPtr and stackTop from eePtr.
     */
    

    CACHE_STACK_INFO();

    /*
     * Pop the argument from the evaluation stack.
     */

    valuePtr = POP_OBJECT();
    tPtr = valuePtr->typePtr;
    
    if (tPtr == &tclIntType) {
	i = valuePtr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d = valuePtr->internalRep.doubleValue;
    } else {			/* FAILS IF STRING REP HAS NULLS */
	char *s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
	
	if (TclLooksLikeInt(s)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr, &d);
	}
	if (result != TCL_OK) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),







|





|




|
>













|
|

|







3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
ExprAbsFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    Tcl_Obj **stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    register Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    long i, iResult;
    double d, dResult;
    int length, result;

    /*
     * Set stackPtr and stackTop from eePtr.
     */

    result = TCL_OK;
    CACHE_STACK_INFO();

    /*
     * Pop the argument from the evaluation stack.
     */

    valuePtr = POP_OBJECT();
    tPtr = valuePtr->typePtr;
    
    if (tPtr == &tclIntType) {
	i = valuePtr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d = valuePtr->internalRep.doubleValue;
    } else {
	char *s = Tcl_GetStringFromObj(valuePtr, &length);
	
	if (TclLooksLikeInt(s, length)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr, &d);
	}
	if (result != TCL_OK) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790

3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
ExprDoubleFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    StackItem *stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    register Tcl_Obj *valuePtr;
    double dResult;
    long i;
    int result = TCL_OK;

    /*
     * Set stackPtr and stackTop from eePtr.
     */
    

    CACHE_STACK_INFO();

    /*
     * Pop the argument from the evaluation stack.
     */

    valuePtr = POP_OBJECT();
    if (valuePtr->typePtr == &tclIntType) {
	dResult = (double) valuePtr->internalRep.longValue;
    } else if (valuePtr->typePtr == &tclDoubleType) {
	dResult = valuePtr->internalRep.doubleValue;
    } else {			/* FAILS IF STRING REP HAS NULLS */
	char *s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
	
	if (TclLooksLikeInt(s)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	    dResult = (double) valuePtr->internalRep.longValue;
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr,
		    &dResult);
	}
	if (result != TCL_OK) {







|




|




|
>











|
|

|







3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
ExprDoubleFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    Tcl_Obj **stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    register Tcl_Obj *valuePtr;
    double dResult;
    long i;
    int length, result;

    /*
     * Set stackPtr and stackTop from eePtr.
     */

    result = TCL_OK;
    CACHE_STACK_INFO();

    /*
     * Pop the argument from the evaluation stack.
     */

    valuePtr = POP_OBJECT();
    if (valuePtr->typePtr == &tclIntType) {
	dResult = (double) valuePtr->internalRep.longValue;
    } else if (valuePtr->typePtr == &tclDoubleType) {
	dResult = valuePtr->internalRep.doubleValue;
    } else {
	char *s = Tcl_GetStringFromObj(valuePtr, &length);
	
	if (TclLooksLikeInt(s, length)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	    dResult = (double) valuePtr->internalRep.longValue;
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr,
		    &dResult);
	}
	if (result != TCL_OK) {
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856

3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
ExprIntFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    StackItem *stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    register Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    long i = 0;			/* Initialized to avoid compiler warning. */
    long iResult;
    double d;
    int result = TCL_OK;

    /*
     * Set stackPtr and stackTop from eePtr.
     */
    

    CACHE_STACK_INFO();

    /*
     * Pop the argument from the evaluation stack.
     */

    valuePtr = POP_OBJECT();
    tPtr = valuePtr->typePtr;
    
    if (tPtr == &tclIntType) {
	i = valuePtr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d = valuePtr->internalRep.doubleValue;
    } else {			/* FAILS IF STRING REP HAS NULLS */
	char *s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
	
	if (TclLooksLikeInt(s)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr, &d);
	}
	if (result != TCL_OK) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),







|






|




|
>













|
|

|







3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
ExprIntFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    Tcl_Obj **stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    register Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    long i = 0;			/* Initialized to avoid compiler warning. */
    long iResult;
    double d;
    int length, result;

    /*
     * Set stackPtr and stackTop from eePtr.
     */

    result = TCL_OK;
    CACHE_STACK_INFO();

    /*
     * Pop the argument from the evaluation stack.
     */

    valuePtr = POP_OBJECT();
    tPtr = valuePtr->typePtr;
    
    if (tPtr == &tclIntType) {
	i = valuePtr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d = valuePtr->internalRep.doubleValue;
    } else {
	char *s = Tcl_GetStringFromObj(valuePtr, &length);
	
	if (TclLooksLikeInt(s, length)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr, &d);
	}
	if (result != TCL_OK) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
ExprRandFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    StackItem *stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    Interp *iPtr = (Interp *) interp;
    double dResult;
    int tmp;

    if (!(iPtr->flags & RAND_SEED_INITIALIZED)) {
	iPtr->flags |= RAND_SEED_INITIALIZED;







|







3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
ExprRandFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    Tcl_Obj **stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    Interp *iPtr = (Interp *) interp;
    double dResult;
    int tmp;

    if (!(iPtr->flags & RAND_SEED_INITIALIZED)) {
	iPtr->flags |= RAND_SEED_INITIALIZED;
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037

4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
ExprRoundFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    StackItem *stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    long i = 0;			/* Initialized to avoid compiler warning. */
    long iResult;
    double d, temp;
    int result = TCL_OK;

    /*
     * Set stackPtr and stackTop from eePtr.
     */
    

    CACHE_STACK_INFO();

    /*
     * Pop the argument from the evaluation stack.
     */

    valuePtr = POP_OBJECT();
    tPtr = valuePtr->typePtr;
    
    if (tPtr == &tclIntType) {
	i = valuePtr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d = valuePtr->internalRep.doubleValue;
    } else {			/* FAILS IF STRING REP HAS NULLS */
	char *s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
	
	if (TclLooksLikeInt(s)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr, &d);
	}
	if (result != TCL_OK) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),







|






|




|
>













|
|

|







3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
ExprRoundFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    Tcl_Obj **stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    long i = 0;			/* Initialized to avoid compiler warning. */
    long iResult;
    double d, temp;
    int length, result;

    /*
     * Set stackPtr and stackTop from eePtr.
     */

    result = TCL_OK;
    CACHE_STACK_INFO();

    /*
     * Pop the argument from the evaluation stack.
     */

    valuePtr = POP_OBJECT();
    tPtr = valuePtr->typePtr;
    
    if (tPtr == &tclIntType) {
	i = valuePtr->internalRep.longValue;
    } else if (tPtr == &tclDoubleType) {
	d = valuePtr->internalRep.doubleValue;
    } else {
	char *s = Tcl_GetStringFromObj(valuePtr, &length);
	
	if (TclLooksLikeInt(s, length)) {
	    result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	} else {
	    result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, valuePtr, &d);
	}
	if (result != TCL_OK) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147















4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
ExprSrandFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    StackItem *stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    Interp *iPtr = (Interp *) interp;
    Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    long i = 0;			/* Initialized to avoid compiler warning. */
    int result;

    /*
     * Set stackPtr and stackTop from eePtr.
     */
    
    CACHE_STACK_INFO();

    /*
     * Pop the argument from the evaluation stack.  Use the value
     * to reset the random number seed.
     */

    valuePtr = POP_OBJECT();
    tPtr = valuePtr->typePtr;
    
    if (tPtr == &tclIntType) {
	i = valuePtr->internalRep.longValue;
    } else {			/* FAILS IF STRING REP HAS NULLS */
	result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	if (result != TCL_OK) {















	    Tcl_ResetResult(interp);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't use ",
		    ((tPtr == &tclDoubleType)? "floating-point value" : "non-numeric string"),
		    " as argument to srand", (char *) NULL);
	    Tcl_DecrRefCount(valuePtr);
	    DECACHE_STACK_INFO();
	    return result;
	}
    }
    







|





|

















|


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


|







4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
ExprSrandFunc(interp, eePtr, clientData)
    Tcl_Interp *interp;		/* The interpreter in which to execute the
				 * function. */
    ExecEnv *eePtr;		/* Points to the environment for executing
				 * the function. */
    ClientData clientData;	/* Ignored. */
{
    Tcl_Obj **stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    Interp *iPtr = (Interp *) interp;
    Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    long i = 0;			/* Initialized to avoid compiler warning. */
    int isDouble, result;

    /*
     * Set stackPtr and stackTop from eePtr.
     */
    
    CACHE_STACK_INFO();

    /*
     * Pop the argument from the evaluation stack.  Use the value
     * to reset the random number seed.
     */

    valuePtr = POP_OBJECT();
    tPtr = valuePtr->typePtr;
    
    if (tPtr == &tclIntType) {
	i = valuePtr->internalRep.longValue;
    } else {
	result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	if (result != TCL_OK) {
	    /*
	     * See if the operand can be interpreted as a double in order to
	     * improve the error message.
	     */

	    isDouble = 1;
	    if (valuePtr->typePtr != &tclDoubleType) {
		char *s = Tcl_GetString(valuePtr);
		double d;

		if (Tcl_GetDouble((Tcl_Interp *) NULL, s, &d) != TCL_OK) {
		    isDouble = 0;
		}
	    }

	    Tcl_ResetResult(interp);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't use ",
		    (isDouble? "floating-point value":"non-numeric string"),
		    " as argument to srand", (char *) NULL);
	    Tcl_DecrRefCount(valuePtr);
	    DECACHE_STACK_INFO();
	    return result;
	}
    }
    
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222

4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
				 * the function. */
    int objc;			/* Number of arguments. The function name is
				 * the 0-th argument. */
    Tcl_Obj **objv;		/* The array of arguments. The function name
				 * is objv[0]. */
{
    Interp *iPtr = (Interp *) interp;
    StackItem *stackPtr;        /* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    char *funcName;
    Tcl_HashEntry *hPtr;
    MathFunc *mathFuncPtr;	/* Information about math function. */
    Tcl_Value args[MAX_MATH_ARGS]; /* Arguments for function call. */
    Tcl_Value funcResult;	/* Result of function call as Tcl_Value. */
    register Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    long i;
    double d;
    int j, k, result;

    
    Tcl_ResetResult(interp);
    
    /*
     * Set stackPtr and stackTop from eePtr.
     */
    
    CACHE_STACK_INFO();

    /*
     * Look up the MathFunc record for the function.
     * THIS FAILS IF THE OBJECT'S STRING REP CONTAINS NULLS.
     */

    funcName = Tcl_GetStringFromObj(objv[0], (int *) NULL);
    hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, funcName);
    if (hPtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"unknown math function \"", funcName, "\"", (char *) NULL);
	result = TCL_ERROR;
	goto done;
    }







|










|
>
|

|








<


|







4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150

4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
				 * the function. */
    int objc;			/* Number of arguments. The function name is
				 * the 0-th argument. */
    Tcl_Obj **objv;		/* The array of arguments. The function name
				 * is objv[0]. */
{
    Interp *iPtr = (Interp *) interp;
    Tcl_Obj **stackPtr;		/* Cached evaluation stack base pointer. */
    register int stackTop;	/* Cached top index of evaluation stack. */
    char *funcName;
    Tcl_HashEntry *hPtr;
    MathFunc *mathFuncPtr;	/* Information about math function. */
    Tcl_Value args[MAX_MATH_ARGS]; /* Arguments for function call. */
    Tcl_Value funcResult;	/* Result of function call as Tcl_Value. */
    register Tcl_Obj *valuePtr;
    Tcl_ObjType *tPtr;
    long i;
    double d;
    int j, k, length, result;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    Tcl_ResetResult(interp);

    /*
     * Set stackPtr and stackTop from eePtr.
     */
    
    CACHE_STACK_INFO();

    /*
     * Look up the MathFunc record for the function.

     */

    funcName = Tcl_GetString(objv[0]);
    hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, funcName);
    if (hPtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"unknown math function \"", funcName, "\"", (char *) NULL);
	result = TCL_ERROR;
	goto done;
    }
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
	if (tPtr == &tclIntType) {
	    i = valuePtr->internalRep.longValue;
	} else if (tPtr == &tclDoubleType) {
	    d = valuePtr->internalRep.doubleValue;
	} else {
	    /*
	     * Try to convert to int first then double.
	     * FAILS IF STRING REP HAS NULLS.
	     */
	    
	    char *s = Tcl_GetStringFromObj(valuePtr, (int *) NULL);
	    
	    if (TclLooksLikeInt(s)) {
		result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	    } else {
		result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
			valuePtr, &d);
	    }
	    if (result != TCL_OK) {
		Tcl_AppendToObj(Tcl_GetObjResult(interp),







<


|

|







4179
4180
4181
4182
4183
4184
4185

4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
	if (tPtr == &tclIntType) {
	    i = valuePtr->internalRep.longValue;
	} else if (tPtr == &tclDoubleType) {
	    d = valuePtr->internalRep.doubleValue;
	} else {
	    /*
	     * Try to convert to int first then double.

	     */
	    
	    char *s = Tcl_GetStringFromObj(valuePtr, &length);
	    
	    if (TclLooksLikeInt(s, length)) {
		result = Tcl_GetLongFromObj((Tcl_Interp *) NULL, valuePtr, &i);
	    } else {
		result = Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,
			valuePtr, &d);
	    }
	    if (result != TCL_OK) {
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
	}
    }

    /*
     * Invoke the function and copy its result back into valuePtr.
     */

    tcl_MathInProgress++;
    result = (*mathFuncPtr->proc)(mathFuncPtr->clientData, interp, args,
	    &funcResult);
    tcl_MathInProgress--;
    if (result != TCL_OK) {
	goto done;
    }

    /*
     * Pop the objc top stack elements and decrement their ref counts.
     */
		
    i = (stackTop - (objc-1));
    while (i <= stackTop) {
	valuePtr = stackPtr[i].o;
	Tcl_DecrRefCount(valuePtr);
	i++;
    }
    stackTop -= objc;
    
    /*
     * Push the call's object result.







|


|










|







4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
	}
    }

    /*
     * Invoke the function and copy its result back into valuePtr.
     */

    tsdPtr->mathInProgress++;
    result = (*mathFuncPtr->proc)(mathFuncPtr->clientData, interp, args,
	    &funcResult);
    tsdPtr->mathInProgress--;
    if (result != TCL_OK) {
	goto done;
    }

    /*
     * Pop the objc top stack elements and decrement their ref counts.
     */
		
    i = (stackTop - (objc-1));
    while (i <= stackTop) {
	valuePtr = stackPtr[i];
	Tcl_DecrRefCount(valuePtr);
	i++;
    }
    stackTop -= objc;
    
    /*
     * Push the call's object result.
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
























4411
4412
4413
4414
4415
4416
4417
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);
	    Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", s, (char *) NULL);
	} else {
	    s = "floating-point value too large to represent";
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);
	    Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", s, (char *) NULL);
	}
    } else {			/* FAILS IF STRING REP CONTAINS NULLS */
	char msg[100];
	
	sprintf(msg, "unknown floating-point error, errno = %d", errno);
	Tcl_AppendToObj(Tcl_GetObjResult(interp), msg, -1);
	Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", msg, (char *) NULL);
    }
}

























#ifdef TCL_COMPILE_STATS
/*
 *----------------------------------------------------------------------
 *
 * TclLog2 --
 *







|
|






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







4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);
	    Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", s, (char *) NULL);
	} else {
	    s = "floating-point value too large to represent";
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);
	    Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", s, (char *) NULL);
	}
    } else {
	char msg[64 + TCL_INTEGER_SPACE];
	
	sprintf(msg, "unknown floating-point error, errno = %d", errno);
	Tcl_AppendToObj(Tcl_GetObjResult(interp), msg, -1);
	Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", msg, (char *) NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclMathInProgress --
 *
 *	This procedure is called to find out if Tcl is doing math
 *	in this thread.
 *
 * Results:
 *	0 or 1.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclMathInProgress()
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    return tsdPtr->mathInProgress;
}

#ifdef TCL_COMPILE_STATS
/*
 *----------------------------------------------------------------------
 *
 * TclLog2 --
 *
4463
4464
4465
4466
4467
4468
4469



4470






4471
4472
4473


4474

4475
4476








































4477






















































































































































































































































4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564

4565
4566
4567
4568
4569




4570
4571
4572
4573

4574






4575


4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
static int
EvalStatsCmd(unused, interp, argc, argv)
    ClientData unused;		/* Unused. */
    Tcl_Interp *interp;		/* The current interpreter. */
    int argc;			/* The number of arguments. */
    char **argv;		/* The argument strings. */
{



    register double total = 0.0;






    register int i;
    int maxSizeDecade = 0;
    double totalHeaderBytes = (tclNumCompilations * sizeof(ByteCode));




    for (i = 0;  i < 256;  i++) {
        if (instructionCount[i] != 0) {








































            total += instructionCount[i];






















































































































































































































































        }
    }

    for (i = 31;  i >= 0;  i--) {
        if ((tclSourceCount[i] > 0) && (tclByteCodeCount[i] > 0)) {
            maxSizeDecade = i;
	    break;
        }
    } 

    fprintf(stdout, "\nNumber of compilations		%ld\n",
	    tclNumCompilations);
    fprintf(stdout, "Number of executions		%ld\n",
	    numExecutions);
    fprintf(stdout, "Average executions/compilation	%.0f\n",
	    ((float) numExecutions/tclNumCompilations));
    
    fprintf(stdout, "\nInstructions executed		%.0f\n",
	    total);
    fprintf(stdout, "Average instructions/compile	%.0f\n",
	    total/tclNumCompilations);
    fprintf(stdout, "Average instructions/execution	%.0f\n",
	    total/numExecutions);
    
    fprintf(stdout, "\nTotal source bytes		%.6g\n",
	    tclTotalSourceBytes);
    fprintf(stdout, "Total code bytes		%.6g\n",
	    tclTotalCodeBytes);
    fprintf(stdout, "Average code/compilation	%.0f\n",
	    tclTotalCodeBytes/tclNumCompilations);
    fprintf(stdout, "Average code/source		%.2f\n",
	    tclTotalCodeBytes/tclTotalSourceBytes);
    fprintf(stdout, "Current source bytes		%.6g\n",
	    tclCurrentSourceBytes);
    fprintf(stdout, "Current code bytes		%.6g\n",
	    tclCurrentCodeBytes);
    fprintf(stdout, "Current code/source		%.2f\n",
	    tclCurrentCodeBytes/tclCurrentSourceBytes);
    
    fprintf(stdout, "\nTotal objects allocated		%ld\n",
	    tclObjsAlloced);
    fprintf(stdout, "Total objects freed		%ld\n",
	    tclObjsFreed);
    fprintf(stdout, "Current objects:	 	%ld\n",
	    (tclObjsAlloced - tclObjsFreed));

    fprintf(stdout, "\nBreakdown of code byte requirements:\n");
    fprintf(stdout, "                   Total bytes      Pct of    Avg per\n");
    fprintf(stdout, "                                  all code    compile\n");
    fprintf(stdout, "Total code        %12.6g        100%%   %8.2f\n",
	    tclTotalCodeBytes, tclTotalCodeBytes/tclNumCompilations);
    fprintf(stdout, "Header            %12.6g   %8.2f%%   %8.2f\n",
	    totalHeaderBytes,
	    ((totalHeaderBytes * 100.0) / tclTotalCodeBytes),
	    totalHeaderBytes/tclNumCompilations);
    fprintf(stdout, "Instructions      %12.6g   %8.2f%%   %8.2f\n",
	    tclTotalInstBytes,
	    ((tclTotalInstBytes * 100.0) / tclTotalCodeBytes),
	    tclTotalInstBytes/tclNumCompilations);
    fprintf(stdout, "Objects           %12.6g   %8.2f%%   %8.2f\n",
	    tclTotalObjBytes,
	    ((tclTotalObjBytes * 100.0) / tclTotalCodeBytes),
	    tclTotalObjBytes/tclNumCompilations);
    fprintf(stdout, "Exception table   %12.6g   %8.2f%%   %8.2f\n",
	    tclTotalExceptBytes,
	    ((tclTotalExceptBytes * 100.0) / tclTotalCodeBytes),
	    tclTotalExceptBytes/tclNumCompilations);
    fprintf(stdout, "Auxiliary data    %12.6g   %8.2f%%   %8.2f\n",
	    tclTotalAuxBytes,
	    ((tclTotalAuxBytes * 100.0) / tclTotalCodeBytes),
	    tclTotalAuxBytes/tclNumCompilations);
    fprintf(stdout, "Command map       %12.6g   %8.2f%%   %8.2f\n",
	    tclTotalCmdMapBytes,
	    ((tclTotalCmdMapBytes * 100.0) / tclTotalCodeBytes),
	    tclTotalCmdMapBytes/tclNumCompilations);
    
    fprintf(stdout, "\nSource and ByteCode size distributions:\n");
    fprintf(stdout, "	 binary decade		source	  code\n");
    for (i = 0;  i <= maxSizeDecade;  i++) {
	int decadeLow, decadeHigh;

	if (i == 0) {
	    decadeLow = 0;
	} else {
	    decadeLow = 1 << i;
	}
	decadeHigh = (1 << (i+1)) - 1;

        fprintf(stdout,	"	%6d -%6d		%6d	%6d\n",
		decadeLow, decadeHigh,
		tclSourceCount[i], tclByteCodeCount[i]);
    }





    fprintf(stdout, "\nInstruction counts:\n");
    for (i = 0;  i < 256;  i++) {
        if (instructionCount[i]) {
            fprintf(stdout, "%20s %8d %6.2f%%\n",

		    opName[i], instructionCount[i],






		    (instructionCount[i] * 100.0)/total);


        }
    }

#ifdef TCL_MEM_DEBUG
    fprintf(stdout, "\nHeap Statistics:\n");
    TclDumpMemoryInfo(stdout);
#endif /* TCL_MEM_DEBUG */

    return TCL_OK;
}
#endif /* TCL_COMPILE_STATS */

/*
 *----------------------------------------------------------------------
 *







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

>

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


<

|



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

>
|
|
|


>
>
>
>

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






|
|







4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420

4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715

4716
4717
4718
4719
4720
4721
4722




































































4723







4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
static int
EvalStatsCmd(unused, interp, argc, argv)
    ClientData unused;		/* Unused. */
    Tcl_Interp *interp;		/* The current interpreter. */
    int argc;			/* The number of arguments. */
    char **argv;		/* The argument strings. */
{
    Interp *iPtr = (Interp *) interp;
    LiteralTable *globalTablePtr = &(iPtr->literalTable);
    ByteCodeStats *statsPtr = &(iPtr->stats);
    double totalCodeBytes, currentCodeBytes;
    double totalLiteralBytes, currentLiteralBytes;
    double objBytesIfUnshared, strBytesIfUnshared, sharingBytesSaved;
    double strBytesSharedMultX, strBytesSharedOnce;
    double numInstructions, currentHeaderBytes;
    long numCurrentByteCodes, numByteCodeLits;
    long refCountSum, literalMgmtBytes, sum;
    int numSharedMultX, numSharedOnce;
    int decadeHigh, minSizeDecade, maxSizeDecade, length, i;

    char *litTableStats;
    LiteralEntry *entryPtr;

    numInstructions = 0.0;
    for (i = 0;  i < 256;  i++) {
        if (statsPtr->instructionCount[i] != 0) {
            numInstructions += statsPtr->instructionCount[i];
        }
    }

    totalLiteralBytes = sizeof(LiteralTable)
	    + iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)
	    + (statsPtr->numLiteralsCreated * sizeof(LiteralEntry))
	    + (statsPtr->numLiteralsCreated * sizeof(Tcl_Obj))
	    + statsPtr->totalLitStringBytes;
    totalCodeBytes = statsPtr->totalByteCodeBytes + totalLiteralBytes;

    numCurrentByteCodes =
	    statsPtr->numCompilations - statsPtr->numByteCodesFreed;
    currentHeaderBytes = numCurrentByteCodes
	    * (sizeof(ByteCode) - (sizeof(size_t) + sizeof(Tcl_Time)));
    literalMgmtBytes = sizeof(LiteralTable)
	    + (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *))
	    + (iPtr->literalTable.numEntries * sizeof(LiteralEntry));
    currentLiteralBytes = literalMgmtBytes
	    + iPtr->literalTable.numEntries * sizeof(Tcl_Obj)
	    + statsPtr->currentLitStringBytes;
    currentCodeBytes = statsPtr->currentByteCodeBytes + currentLiteralBytes;
    
    /*
     * Summary statistics, total and current source and ByteCode sizes.
     */

    fprintf(stdout, "\n----------------------------------------------------------------\n");
    fprintf(stdout,
	    "Compilation and execution statistics for interpreter 0x%x\n",
	    (unsigned int) iPtr);

    fprintf(stdout, "\nNumber ByteCodes executed	%ld\n",
	    statsPtr->numExecutions);
    fprintf(stdout, "Number ByteCodes compiled	%ld\n",
	    statsPtr->numCompilations);
    fprintf(stdout, "  Mean executions/compile	%.1f\n",
	    ((float)statsPtr->numExecutions) / ((float)statsPtr->numCompilations));
    
    fprintf(stdout, "\nInstructions executed		%.0f\n",
	    numInstructions);
    fprintf(stdout, "  Mean inst/compile		%.0f\n",
	    numInstructions / statsPtr->numCompilations);
    fprintf(stdout, "  Mean inst/execution		%.0f\n",
	    numInstructions / statsPtr->numExecutions);

    fprintf(stdout, "\nTotal ByteCodes			%ld\n",
	    statsPtr->numCompilations);
    fprintf(stdout, "  Source bytes			%.6g\n",
	    statsPtr->totalSrcBytes);
    fprintf(stdout, "  Code bytes			%.6g\n",
	    totalCodeBytes);
    fprintf(stdout, "    ByteCode bytes		%.6g\n",
	    statsPtr->totalByteCodeBytes);
    fprintf(stdout, "    Literal bytes		%.6g\n",
	    totalLiteralBytes);
    fprintf(stdout, "      table %d + bkts %d + entries %ld + objects %ld + strings %.6g\n",
	    sizeof(LiteralTable),
	    iPtr->literalTable.numBuckets * sizeof(LiteralEntry *),
	    statsPtr->numLiteralsCreated * sizeof(LiteralEntry),
	    statsPtr->numLiteralsCreated * sizeof(Tcl_Obj),
	    statsPtr->totalLitStringBytes);
    fprintf(stdout, "  Mean code/compile		%.1f\n",
	    totalCodeBytes / statsPtr->numCompilations);
    fprintf(stdout, "  Mean code/source		%.1f\n",
	    totalCodeBytes / statsPtr->totalSrcBytes);

    fprintf(stdout, "\nCurrent ByteCodes		%ld\n",
	    numCurrentByteCodes);
    fprintf(stdout, "  Source bytes			%.6g\n",
	    statsPtr->currentSrcBytes);
    fprintf(stdout, "  Code bytes			%.6g\n",
	    currentCodeBytes);
    fprintf(stdout, "    ByteCode bytes		%.6g\n",
	    statsPtr->currentByteCodeBytes);
    fprintf(stdout, "    Literal bytes		%.6g\n",
	    currentLiteralBytes);
    fprintf(stdout, "      table %d + bkts %d + entries %d + objects %d + strings %.6g\n",
	    sizeof(LiteralTable),
	    iPtr->literalTable.numBuckets * sizeof(LiteralEntry *),
	    iPtr->literalTable.numEntries * sizeof(LiteralEntry),
	    iPtr->literalTable.numEntries * sizeof(Tcl_Obj),
	    statsPtr->currentLitStringBytes);
    fprintf(stdout, "  Mean code/source		%.1f\n",
	    currentCodeBytes / statsPtr->currentSrcBytes);
    fprintf(stdout, "  Code + source bytes		%.6g (%0.1f mean code/src)\n",
	    (currentCodeBytes + statsPtr->currentSrcBytes),
	    (currentCodeBytes / statsPtr->currentSrcBytes) + 1.0);

    /*
     * Literal table statistics.
     */

    numByteCodeLits = 0;
    refCountSum = 0;
    numSharedMultX = 0;
    numSharedOnce  = 0;
    objBytesIfUnshared  = 0.0;
    strBytesIfUnshared  = 0.0;
    strBytesSharedMultX = 0.0;
    strBytesSharedOnce  = 0.0;
    for (i = 0;  i < globalTablePtr->numBuckets;  i++) {
	for (entryPtr = globalTablePtr->buckets[i];  entryPtr != NULL;
	        entryPtr = entryPtr->nextPtr) {
	    if (entryPtr->objPtr->typePtr == &tclByteCodeType) {
		numByteCodeLits++;
	    }
	    (void) Tcl_GetStringFromObj(entryPtr->objPtr, &length);
	    refCountSum += entryPtr->refCount;
	    objBytesIfUnshared += (entryPtr->refCount * sizeof(Tcl_Obj));
	    strBytesIfUnshared += (entryPtr->refCount * (length+1));
	    if (entryPtr->refCount > 1) {
		numSharedMultX++;
		strBytesSharedMultX += (length+1);
	    } else {
		numSharedOnce++;
		strBytesSharedOnce += (length+1);
	    }
	}
    }
    sharingBytesSaved = (objBytesIfUnshared + strBytesIfUnshared)
	    - currentLiteralBytes;

    fprintf(stdout, "\nTotal objects (all interps)	%ld\n",
	    tclObjsAlloced);
    fprintf(stdout, "Current objects			%ld\n",
	    (tclObjsAlloced - tclObjsFreed));
    fprintf(stdout, "Total literal objects		%ld\n",
	    statsPtr->numLiteralsCreated);
    
    fprintf(stdout, "\nCurrent literal objects		%d (%0.1f%% of current objects)\n",
	    globalTablePtr->numEntries,
	    (globalTablePtr->numEntries * 100.0) / (tclObjsAlloced-tclObjsFreed));
    fprintf(stdout, "  ByteCode literals	 	%ld (%0.1f%% of current literals)\n",
	    numByteCodeLits,
	    (numByteCodeLits * 100.0) / globalTablePtr->numEntries);
    fprintf(stdout, "  Literals reused > 1x	 	%d\n",
	    numSharedMultX);
    fprintf(stdout, "  Mean reference count	 	%.2f\n",
	    ((double) refCountSum) / globalTablePtr->numEntries);
    fprintf(stdout, "  Mean len, str reused >1x 	%.2f\n",
	    (numSharedMultX? (strBytesSharedMultX/numSharedMultX) : 0.0));
    fprintf(stdout, "  Mean len, str used 1x	 	%.2f\n",
	    (numSharedOnce? (strBytesSharedOnce/numSharedOnce) : 0.0));
    fprintf(stdout, "  Total sharing savings	 	%.6g (%0.1f%% of bytes if no sharing)\n",
	    sharingBytesSaved,
	    (sharingBytesSaved * 100.0) / (objBytesIfUnshared + strBytesIfUnshared));
    fprintf(stdout, "    Bytes with sharing		%.6g\n",
	    currentLiteralBytes);
    fprintf(stdout, "      table %d + bkts %d + entries %d + objects %d + strings %.6g\n",
	    sizeof(LiteralTable),
	    iPtr->literalTable.numBuckets * sizeof(LiteralEntry *),
	    iPtr->literalTable.numEntries * sizeof(LiteralEntry),
	    iPtr->literalTable.numEntries * sizeof(Tcl_Obj),
	    statsPtr->currentLitStringBytes);
    fprintf(stdout, "    Bytes if no sharing		%.6g = objects %.6g + strings %.6g\n",
	    (objBytesIfUnshared + strBytesIfUnshared),
	    objBytesIfUnshared, strBytesIfUnshared);
    fprintf(stdout, "  String sharing savings 	%.6g = unshared %.6g - shared %.6g\n",
	    (strBytesIfUnshared - statsPtr->currentLitStringBytes),
	    strBytesIfUnshared, statsPtr->currentLitStringBytes);
    fprintf(stdout, "  Literal mgmt overhead	 	%ld (%0.1f%% of bytes with sharing)\n",
	    literalMgmtBytes,
	    (literalMgmtBytes * 100.0) / currentLiteralBytes);
    fprintf(stdout, "    table %d + buckets %d + entries %d\n",
	    sizeof(LiteralTable),
	    iPtr->literalTable.numBuckets * sizeof(LiteralEntry *),
	    iPtr->literalTable.numEntries * sizeof(LiteralEntry));

    /*
     * Breakdown of current ByteCode space requirements.
     */
    
    fprintf(stdout, "\nBreakdown of current ByteCode requirements:\n");
    fprintf(stdout, "                         Bytes      Pct of    Avg per\n");
    fprintf(stdout, "                                     total    ByteCode\n");
    fprintf(stdout, "Total             %12.6g     100.00%%   %8.1f\n",
	    statsPtr->currentByteCodeBytes,
	    statsPtr->currentByteCodeBytes / numCurrentByteCodes);
    fprintf(stdout, "Header            %12.6g   %8.1f%%   %8.1f\n",
	    currentHeaderBytes,
	    ((currentHeaderBytes * 100.0) / statsPtr->currentByteCodeBytes),
	    currentHeaderBytes / numCurrentByteCodes);
    fprintf(stdout, "Instructions      %12.6g   %8.1f%%   %8.1f\n",
	    statsPtr->currentInstBytes,
	    ((statsPtr->currentInstBytes * 100.0) / statsPtr->currentByteCodeBytes),
	    statsPtr->currentInstBytes / numCurrentByteCodes);
    fprintf(stdout, "Literal ptr array %12.6g   %8.1f%%   %8.1f\n",
	    statsPtr->currentLitBytes,
	    ((statsPtr->currentLitBytes * 100.0) / statsPtr->currentByteCodeBytes),
	    statsPtr->currentLitBytes / numCurrentByteCodes);
    fprintf(stdout, "Exception table   %12.6g   %8.1f%%   %8.1f\n",
	    statsPtr->currentExceptBytes,
	    ((statsPtr->currentExceptBytes * 100.0) / statsPtr->currentByteCodeBytes),
	    statsPtr->currentExceptBytes / numCurrentByteCodes);
    fprintf(stdout, "Auxiliary data    %12.6g   %8.1f%%   %8.1f\n",
	    statsPtr->currentAuxBytes,
	    ((statsPtr->currentAuxBytes * 100.0) / statsPtr->currentByteCodeBytes),
	    statsPtr->currentAuxBytes / numCurrentByteCodes);
    fprintf(stdout, "Command map       %12.6g   %8.1f%%   %8.1f\n",
	    statsPtr->currentCmdMapBytes,
	    ((statsPtr->currentCmdMapBytes * 100.0) / statsPtr->currentByteCodeBytes),
	    statsPtr->currentCmdMapBytes / numCurrentByteCodes);

    /*
     * Detailed literal statistics.
     */
    
    fprintf(stdout, "\nLiteral string sizes:\n");
    fprintf(stdout, "	 Up to length		Percentage\n");
    maxSizeDecade = 0;
    for (i = 31;  i >= 0;  i--) {
        if (statsPtr->literalCount[i] > 0) {
            maxSizeDecade = i;
	    break;
        }
    }
    sum = 0;
    for (i = 0;  i <= maxSizeDecade;  i++) {
	decadeHigh = (1 << (i+1)) - 1;
	sum += statsPtr->literalCount[i];
        fprintf(stdout,	"	%10d		%8.0f%%\n",
		decadeHigh, (sum * 100.0) / statsPtr->numLiteralsCreated);
    }

    litTableStats = TclLiteralStats(globalTablePtr);
    fprintf(stdout, "\nCurrent literal table statistics:\n%s\n",
            litTableStats);
    ckfree((char *) litTableStats);

    /*
     * Source and ByteCode size distributions.
     */

    fprintf(stdout, "\nSource sizes:\n");
    fprintf(stdout, "	 Up to size		Percentage\n");
    minSizeDecade = maxSizeDecade = 0;
    for (i = 0;  i < 31;  i++) {
        if (statsPtr->srcCount[i] > 0) {
	    minSizeDecade = i;
	    break;
        }
    }
    for (i = 31;  i >= 0;  i--) {
        if (statsPtr->srcCount[i] > 0) {
            maxSizeDecade = i;
	    break;
        }
    }
    sum = 0;
    for (i = minSizeDecade;  i <= maxSizeDecade;  i++) {
	decadeHigh = (1 << (i+1)) - 1;
	sum += statsPtr->srcCount[i];
        fprintf(stdout,	"	%10d		%8.0f%%\n",
		decadeHigh, (sum * 100.0) / statsPtr->numCompilations);
    }

    fprintf(stdout, "\nByteCode sizes:\n");
    fprintf(stdout, "	 Up to size		Percentage\n");
    minSizeDecade = maxSizeDecade = 0;
    for (i = 0;  i < 31;  i++) {
        if (statsPtr->byteCodeCount[i] > 0) {
	    minSizeDecade = i;
	    break;
        }
    }
    for (i = 31;  i >= 0;  i--) {
        if (statsPtr->byteCodeCount[i] > 0) {
            maxSizeDecade = i;
	    break;
        }
    }
    sum = 0;
    for (i = minSizeDecade;  i <= maxSizeDecade;  i++) {
	decadeHigh = (1 << (i+1)) - 1;
	sum += statsPtr->byteCodeCount[i];
        fprintf(stdout,	"	%10d		%8.0f%%\n",
		decadeHigh, (sum * 100.0) / statsPtr->numCompilations);
    }

    fprintf(stdout, "\nByteCode longevity (excludes current ByteCodes):\n");
    fprintf(stdout, "	       Up to ms		Percentage\n");
    minSizeDecade = maxSizeDecade = 0;
    for (i = 0;  i < 31;  i++) {
        if (statsPtr->lifetimeCount[i] > 0) {
	    minSizeDecade = i;
	    break;
        }
    }

    for (i = 31;  i >= 0;  i--) {
        if (statsPtr->lifetimeCount[i] > 0) {
            maxSizeDecade = i;
	    break;
        }
    }
    sum = 0;




































































    for (i = minSizeDecade;  i <= maxSizeDecade;  i++) {







	decadeHigh = (1 << (i+1)) - 1;
	sum += statsPtr->lifetimeCount[i];
        fprintf(stdout,	"	%12.3f		%8.0f%%\n",
		decadeHigh / 1000.0,
		(sum * 100.0) / statsPtr->numByteCodesFreed);
    }

    /*
     * Instruction counts.
     */

    fprintf(stdout, "\nInstruction counts:\n");
    for (i = 0;  i <= LAST_INST_OPCODE;  i++) {
        if (statsPtr->instructionCount[i]) {
            fprintf(stdout, "%20s %8ld %6.1f%%\n",
		    instructionTable[i].name,
		    statsPtr->instructionCount[i],
		    (statsPtr->instructionCount[i]*100.0) / numInstructions);
        }
    }

    fprintf(stdout, "\nInstructions NEVER executed:\n");
    for (i = 0;  i <= LAST_INST_OPCODE;  i++) {
        if (statsPtr->instructionCount[i] == 0) {
            fprintf(stdout, "%20s\n",
		    instructionTable[i].name);
        }
    }

#ifdef TCL_MEM_DEBUG
    fprintf(stdout, "\nHeap Statistics:\n");
    TclDumpMemoryInfo(stdout);
#endif
    fprintf(stdout, "\n----------------------------------------------------------------\n");
    return TCL_OK;
}
#endif /* TCL_COMPILE_STATS */

/*
 *----------------------------------------------------------------------
 *
4672
4673
4674
4675
4676
4677
4678

4679
4680



































4681
4682
4683



4684






















4685
4686
4687
4688
4689
4690
4691
            return (Tcl_Command) NULL;
        }
        resPtr = (ResolvedCmdName *) objPtr->internalRep.otherValuePtr;
        if (resPtr != NULL) {
            cmdPtr = resPtr->cmdPtr;
        }
    }


    if (cmdPtr == NULL) {



































	return (Tcl_Command) NULL;
    }
    return (Tcl_Command) cmdPtr;



}























/*
 *----------------------------------------------------------------------
 *
 * FreeCmdNameInternalRep --
 *
 *	Frees the resources associated with a cmdName object's internal







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

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







4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
            return (Tcl_Command) NULL;
        }
        resPtr = (ResolvedCmdName *) objPtr->internalRep.otherValuePtr;
        if (resPtr != NULL) {
            cmdPtr = resPtr->cmdPtr;
        }
    }
    return (Tcl_Command) cmdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TclSetCmdNameObj --
 *
 *	Modify an object to be an CmdName object that refers to the argument
 *	Command structure.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object's old internal rep is freed. It's string rep is not
 *	changed. The refcount in the Command structure is incremented to
 *	keep it from being freed if the command is later deleted until
 *	TclExecuteByteCode has a chance to recognize that it was deleted.
 *
 *----------------------------------------------------------------------
 */

void
TclSetCmdNameObj(interp, objPtr, cmdPtr)
    Tcl_Interp *interp;		/* Points to interpreter containing command
				 * that should be cached in objPtr. */
    register Tcl_Obj *objPtr;	/* Points to Tcl object to be changed to
				 * a CmdName object. */
    Command *cmdPtr;		/* Points to Command structure that the
				 * CmdName object should refer to. */
{
    Interp *iPtr = (Interp *) interp;
    register ResolvedCmdName *resPtr;
    Tcl_ObjType *oldTypePtr = objPtr->typePtr;
    register Namespace *currNsPtr;

    if (oldTypePtr == &tclCmdNameType) {
	return;
    }
    
    /*
     * Get the current namespace.
     */
    
    if (iPtr->varFramePtr != NULL) {
	currNsPtr = iPtr->varFramePtr->nsPtr;
    } else {
	currNsPtr = iPtr->globalNsPtr;
    }
    
    cmdPtr->refCount++;
    resPtr = (ResolvedCmdName *) ckalloc(sizeof(ResolvedCmdName));
    resPtr->cmdPtr = cmdPtr;
    resPtr->refNsPtr = currNsPtr;
    resPtr->refNsId  = currNsPtr->nsId;
    resPtr->refNsCmdEpoch = currNsPtr->cmdRefEpoch;
    resPtr->cmdEpoch = cmdPtr->cmdEpoch;
    resPtr->refCount = 1;
    
    if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
	oldTypePtr->freeIntRepProc(objPtr);
    }
    objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) resPtr;
    objPtr->internalRep.twoPtrValue.ptr2 = NULL;
    objPtr->typePtr = &tclCmdNameType;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeCmdNameInternalRep --
 *
 *	Frees the resources associated with a cmdName object's internal
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818

    /*
     * Get "objPtr"s string representation. Make it up-to-date if necessary.
     */

    name = objPtr->bytes;
    if (name == NULL) {
	name = Tcl_GetStringFromObj(objPtr, (int *) NULL);
    }

    /*
     * Find the Command structure, if any, that describes the command called
     * "name". Build a ResolvedCmdName that holds a cached pointer to this
     * Command, and bump the reference count in the referenced Command
     * structure. A Command structure will not be deleted as long as it is







|







5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053

    /*
     * Get "objPtr"s string representation. Make it up-to-date if necessary.
     */

    name = objPtr->bytes;
    if (name == NULL) {
	name = Tcl_GetString(objPtr);
    }

    /*
     * Find the Command structure, if any, that describes the command called
     * "name". Build a ResolvedCmdName that holds a cached pointer to this
     * Command, and bump the reference count in the referenced Command
     * structure. A Command structure will not be deleted as long as it is
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
    }
    
    objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) resPtr;
    objPtr->internalRep.twoPtrValue.ptr2 = NULL;
    objPtr->typePtr = &tclCmdNameType;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateStringOfCmdName --
 *
 *	Update the string representation for an cmdName object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Generates a panic. 
 *
 *----------------------------------------------------------------------
 */

static void
UpdateStringOfCmdName(objPtr)
    Tcl_Obj *objPtr;		/* CmdName obj to update string rep. */
{
    /*
     * This procedure is never invoked since the internal representation of
     * a cmdName object is never modified.
     */

    panic("UpdateStringOfCmdName should never be invoked");
}

#ifdef TCL_COMPILE_DEBUG
/*
 *----------------------------------------------------------------------
 *
 * StringForResultCode --
 *







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







5093
5094
5095
5096
5097
5098
5099




























5100
5101
5102
5103
5104
5105
5106
    }
    
    objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) resPtr;
    objPtr->internalRep.twoPtrValue.ptr2 = NULL;
    objPtr->typePtr = &tclCmdNameType;
    return TCL_OK;
}





























#ifdef TCL_COMPILE_DEBUG
/*
 *----------------------------------------------------------------------
 *
 * StringForResultCode --
 *
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
 */

static char *
StringForResultCode(result)
    int result;			/* The Tcl result code for which to
				 * generate a string. */
{
    static char buf[20];
    
    if ((result >= TCL_OK) && (result <= TCL_CONTINUE)) {
	return resultStrings[result];
    }
    TclFormatInt(buf, result);
    return buf;
}
#endif /* TCL_COMPILE_DEBUG */







|








5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
 */

static char *
StringForResultCode(result)
    int result;			/* The Tcl result code for which to
				 * generate a string. */
{
    static char buf[TCL_INTEGER_SPACE];
    
    if ((result >= TCL_OK) && (result <= TCL_CONTINUE)) {
	return resultStrings[result];
    }
    TclFormatInt(buf, result);
    return buf;
}
#endif /* TCL_COMPILE_DEBUG */

Changes to generic/tclFCmd.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * tclFCmd.c
 *
 *      This file implements the generic portion of file manipulation 
 *      subcommands of the "file" command. 
 *
 * 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.
 *
 * SCCS: @(#) tclFCmd.c 1.17 97/05/14 13:23:13
 */

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

/*
 * Declarations for local procedures defined in this file:






|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * tclFCmd.c
 *
 *      This file implements the generic portion of file manipulation 
 *      subcommands of the "file" command. 
 *
 * Copyright (c) 1996-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: tclFCmd.c,v 1.1.2.2 1998/09/24 23:58:49 stanton Exp $
 */

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

/*
 * Declarations for local procedures defined in this file:
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    if (target == NULL) {
	return TCL_ERROR;
    }

    result = TCL_OK;

    /*
     * Call stat() so that if target is a symlink that points to a directory
     * we will put the sources in that directory instead of overwriting the
     * symlink.
     */

    if ((stat(target, &statBuf) != 0) || !S_ISDIR(statBuf.st_mode)) {
	if ((argc - i) > 2) {
	    errno = ENOTDIR;
	    Tcl_PosixError(interp);
	    Tcl_AppendResult(interp, "error ",
		    ((copyFlag) ? "copying" : "renaming"), ": target \"",
		    argv[argc - 1], "\" is not a directory", (char *) NULL);
	    result = TCL_ERROR;







|
|
|


|







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    if (target == NULL) {
	return TCL_ERROR;
    }

    result = TCL_OK;

    /*
     * Call TclpStat() so that if target is a symlink that points to a
     * directory we will put the sources in that directory instead of
     * overwriting the symlink.
     */

    if ((TclpStat(target, &statBuf) != 0) || !S_ISDIR(statBuf.st_mode)) {
	if ((argc - i) > 2) {
	    errno = ENOTDIR;
	    Tcl_PosixError(interp);
	    Tcl_AppendResult(interp, "error ",
		    ((copyFlag) ? "copying" : "renaming"), ": target \"",
		    argv[argc - 1], "\" is not a directory", (char *) NULL);
	    result = TCL_ERROR;
249
250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
266
267
	    errfile = argv[i];
	    break;
	}
	for (j = 0; j < pargc; j++) {
	    char *target = Tcl_JoinPath(j + 1, pargv, &targetBuffer);

	    /*
	     * Call stat() so that if target is a symlink that points to a
	     * directory we will create subdirectories in that directory.

	     */

	    if (stat(target, &statBuf) == 0) {
		if (!S_ISDIR(statBuf.st_mode)) {
		    errno = EEXIST;
		    errfile = target;
		    goto done;
		}
	    } else if ((errno != ENOENT)
		    || (TclpCreateDirectory(target) != TCL_OK)) {







|
|
>


|







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
	    errfile = argv[i];
	    break;
	}
	for (j = 0; j < pargc; j++) {
	    char *target = Tcl_JoinPath(j + 1, pargv, &targetBuffer);

	    /*
	     * Call TclpStat() so that if target is a symlink that points
	     * to a directory we will create subdirectories in that
	     * directory.
	     */

	    if (TclpStat(target, &statBuf) == 0) {
		if (!S_ISDIR(statBuf.st_mode)) {
		    errno = EEXIST;
		    errfile = target;
		    goto done;
		}
	    } else if ((errno != ENOENT)
		    || (TclpCreateDirectory(target) != TCL_OK)) {
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
	    goto done;
	}

	/*
	 * Call lstat() to get info so can delete symbolic link itself.
	 */

	if (lstat(name, &statBuf) != 0) {
	    /*
	     * Trying to delete a file that does not exist is not
	     * considered an error, just a no-op
	     */

	    if (errno != ENOENT) {
		result = TCL_ERROR;







|







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
	    goto done;
	}

	/*
	 * Call lstat() to get info so can delete symbolic link itself.
	 */

	if (TclpLstat(name, &statBuf) != 0) {
	    /*
	     * Trying to delete a file that does not exist is not
	     * considered an error, just a no-op
	     */

	    if (errno != ENOENT) {
		result = TCL_ERROR;
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
    /*
     * We want to copy/rename links and not the files they point to, so we
     * use lstat(). If target is a link, we also want to replace the 
     * link and not the file it points to, so we also use lstat() on the
     * target.
     */

    if (lstat(sourceName, &sourceStatBuf) != 0) {
	errfile = source;
	goto done;
    }
    if (lstat(targetName, &targetStatBuf) != 0) {
	if (errno != ENOENT) {
	    errfile = target;
	    goto done;
	}
    } else {
	if (force == 0) {
	    errno = EEXIST;







|



|







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
    /*
     * We want to copy/rename links and not the files they point to, so we
     * use lstat(). If target is a link, we also want to replace the 
     * link and not the file it points to, so we also use lstat() on the
     * target.
     */

    if (TclpLstat(sourceName, &sourceStatBuf) != 0) {
	errfile = source;
	goto done;
    }
    if (TclpLstat(targetName, &targetStatBuf) != 0) {
	if (errno != ENOENT) {
	    errfile = target;
	    goto done;
	}
    } else {
	if (force == 0) {
	    errno = EEXIST;
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
 *
 *	Helps parse command line options for file commands that take
 *	the "-force" and "--" options.
 *
 * Results:
 *	The return value is how many arguments from argv were consumed
 *	by this function, or -1 if there was an error parsing the
 *	options.  If an error occurred, an error message is left in
 *	interp->result.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
FileForceOption(interp, argc, argv, forcePtr)
    Tcl_Interp *interp;		/* Interp, for error return. */
    int argc;			/* Number of arguments. */
    char **argv;		/* Argument strings.  First command line
    option, if it exists, begins at */
    int *forcePtr;		/* If the "-force" was specified, *forcePtr
				 * is filled with 1, otherwise with 0. */
{
    int force, i;
    
    force = 0;
    for (i = 0; i < argc; i++) {







|
|












|







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
 *
 *	Helps parse command line options for file commands that take
 *	the "-force" and "--" options.
 *
 * Results:
 *	The return value is how many arguments from argv were consumed
 *	by this function, or -1 if there was an error parsing the
 *	options.  If an error occurred, an error message is left in the
 *	interp's result.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
FileForceOption(interp, argc, argv, forcePtr)
    Tcl_Interp *interp;		/* Interp, for error return. */
    int argc;			/* Number of arguments. */
    char **argv;		/* Argument strings.  First command line
				 * option, if it exists, begins at 0. */
    int *forcePtr;		/* If the "-force" was specified, *forcePtr
				 * is filled with 1, otherwise with 0. */
{
    int force, i;
    
    force = 0;
    for (i = 0; i < argc; i++) {
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768

769
770
771



772
773







774














775
776
777
778
779
780
781
782

783

784
785
786
787
788
789
790

791
792
793
794

795
796
797




798
799
800
801
802
803
804






805
806
807

808
809
810

811

812
813
814
815

int
TclFileAttrsCmd(interp, objc, objv)
    Tcl_Interp *interp;		/* The interpreter for error reporting. */
    int objc;			/* Number of command line arguments. */
    Tcl_Obj *CONST objv[];	/* The command line objects. */
{
    Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
    char *fileName;
    int length, index;
    Tcl_Obj *listObjPtr;
    Tcl_Obj *elementObjPtr;
    Tcl_DString buffer;

    if ((objc > 2) && ((objc % 2) == 0)) {
	Tcl_AppendStringsToObj(resultPtr, 
		"wrong # args: must be \"file attributes name ?option? ?value? ?option value? ...\"",
		(char *) NULL);
	return TCL_ERROR;
    }

    fileName = Tcl_GetStringFromObj(objv[0], &length);
    if (Tcl_TranslateFileName(interp, fileName, &buffer) == NULL) {

    	return TCL_ERROR;
    }
    fileName = Tcl_DStringValue(&buffer);



    
    if (objc == 1) {







    	listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);














    	
    	for (index = 0; tclpFileAttrStrings[index] != NULL; index++) {
    	    elementObjPtr = Tcl_NewStringObj(tclpFileAttrStrings[index], -1);
	    Tcl_ListObjAppendElement(interp, listObjPtr, elementObjPtr);
	    if ((*tclpFileAttrProcs[index].getProc)(interp, index, fileName,
	    	    &elementObjPtr) != TCL_OK) {
	    	Tcl_DecrRefCount(listObjPtr);
	    	return TCL_ERROR;

	    }

	    Tcl_ListObjAppendElement(interp, listObjPtr, elementObjPtr);
    	}
    	Tcl_SetObjResult(interp, listObjPtr);
    } else if (objc == 2) {
    	if (Tcl_GetIndexFromObj(interp, objv[1], tclpFileAttrStrings, "option",
    		0, &index) != TCL_OK) {
    	    return TCL_ERROR;

    	}
	if ((*tclpFileAttrProcs[index].getProc)(interp, index, fileName,
		&elementObjPtr) != TCL_OK) {
	    return TCL_ERROR;

	}
	Tcl_SetObjResult(interp, elementObjPtr);
    } else {




        int i;
        
    	for (i = 1; i < objc ; i += 2) {
    	    if (Tcl_GetIndexFromObj(interp, objv[i], tclpFileAttrStrings, "option",
    	    	    0, &index) != TCL_OK) {
    	    	return TCL_ERROR;
    	    }






    	    if ((*tclpFileAttrProcs[index].setProc)(interp, index, fileName,
    	    	    objv[i + 1]) != TCL_OK) {
    	    	return TCL_ERROR;

    	    }
    	}
    }

    

    Tcl_DStringFree(&buffer);
    
    return TCL_OK;
}







<

|
<
<


|
|
|
<



|
|
>


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


|
<
>

|

>
>
>
>
|

|
|
|
|

>
>
>
>
>
>


<
>



>
|
>

<
|

747
748
749
750
751
752
753

754
755


756
757
758
759
760

761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797







798
799
800
801
802


803
804

805
806
807
808

809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831

832
833
834
835
836
837
838
839

840
841

int
TclFileAttrsCmd(interp, objc, objv)
    Tcl_Interp *interp;		/* The interpreter for error reporting. */
    int objc;			/* Number of command line arguments. */
    Tcl_Obj *CONST objv[];	/* The command line objects. */
{

    char *fileName;
    int result;


    Tcl_DString buffer;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv,
		"name ?option? ?value? ?option value ...?");

	return TCL_ERROR;
    }

    fileName = Tcl_GetString(objv[2]);
    fileName = Tcl_TranslateFileName(interp, fileName, &buffer);
    if (fileName == NULL) {
    	return TCL_ERROR;
    }
    
    objc -= 3;
    objv += 3;
    result = TCL_ERROR;

    if (objc == 0) {
	/*
	 * Get all attributes.
	 */

	int index;
	Tcl_Obj *listPtr, *objPtr;
	 
	listPtr = Tcl_NewListObj(0, NULL);
    	for (index = 0; tclpFileAttrStrings[index] != NULL; index++) {
    	    objPtr = Tcl_NewStringObj(tclpFileAttrStrings[index], -1);
	    Tcl_ListObjAppendElement(interp, listPtr, objPtr);

	    if ((*tclpFileAttrProcs[index].getProc)(interp, index, fileName,
	    	    &objPtr) != TCL_OK) {
		Tcl_DecrRefCount(listPtr);
		goto end;
	    }
	    Tcl_ListObjAppendElement(interp, listPtr, objPtr);
    	}
    	Tcl_SetObjResult(interp, listPtr);
    } else if (objc == 1) {
	/*
	 * Get one attribute.







	 */

	int index;
	Tcl_Obj *objPtr;
	 


    	if (Tcl_GetIndexFromObj(interp, objv[0], tclpFileAttrStrings,
		"option", 0, &index) != TCL_OK) {

	    goto end;
    	}
	if ((*tclpFileAttrProcs[index].getProc)(interp, index, fileName,
		&objPtr) != TCL_OK) {

	    goto end;
	}
	Tcl_SetObjResult(interp, objPtr);
    } else {
	/*
	 * Set option/value pairs.
	 */

	int i, index;
        
    	for (i = 0; i < objc ; i += 2) {
    	    if (Tcl_GetIndexFromObj(interp, objv[i], tclpFileAttrStrings,
		    "option", 0, &index) != TCL_OK) {
		goto end;
    	    }
	    if (i + 1 == objc) {
		Tcl_AppendResult(interp, "value for \"",
			Tcl_GetString(objv[i]), "\" missing",
			(char *) NULL);
		goto end;
	    }
    	    if ((*tclpFileAttrProcs[index].setProc)(interp, index, fileName,
    	    	    objv[i + 1]) != TCL_OK) {

		goto end;
    	    }
    	}
    }
    result = TCL_OK;

    end:
    Tcl_DStringFree(&buffer);

    return result;
}

Changes to generic/tclFileName.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
65

66
67
68
69
70
71
72
73




























74
75
76
77
78
79
80
/* 
 * tclFileName.c --
 *
 *	This file contains routines for converting file names betwen
 *	native and network form.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.

 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclFileName.c 1.32 97/08/19 18:44:03
 */

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

/*
 * This variable indicates whether the cleanup procedure has been
 * registered for this file yet.
 */

static int initialized = 0;

/*
 * The following regular expression matches the root portion of a Windows
 * absolute or volume relative path.  It will match both UNC and drive relative
 * paths.
 */

#define WIN_ROOT_PATTERN "^(([a-zA-Z]:)|[/\\][/\\]+([^/\\]+)[/\\]+([^/\\]+)|([/\\]))([/\\])*"

/*
 * The following regular expression matches the root portion of a Macintosh
 * absolute path.  It will match degenerate Unix-style paths, tilde paths,
 * Unix-style paths, and Mac paths.
 */

#define MAC_ROOT_PATTERN "^((/+([.][.]?/+)*([.][.]?)?)|(~[^:/]*)(/[^:]*)?|(~[^:]*)(:.*)?|/+([.][.]?/+)*([^:/]+)(/[^:]*)?|([^:]+):.*)$"

/*
 * The following variables are used to hold precompiled regular expressions
 * for use in filename matching.
 */



static regexp *winRootPatternPtr = NULL;
static regexp *macRootPatternPtr = NULL;




/*
 * The following variable is set in the TclPlatformInit call to one
 * of: TCL_PLATFORM_UNIX, TCL_PLATFORM_MAC, or TCL_PLATFORM_WINDOWS.
 */

TclPlatformType tclPlatform = TCL_PLATFORM_UNIX;

/*
 * Prototypes for local procedures defined in this file:
 */

static char *		DoTildeSubst _ANSI_ARGS_((Tcl_Interp *interp,
			    char *user, Tcl_DString *resultPtr));
static char *		ExtractWinRoot _ANSI_ARGS_((char *path,
			    Tcl_DString *resultPtr, int offset));
static void		FileNameCleanup _ANSI_ARGS_((ClientData clientData));

static int		SkipToChar _ANSI_ARGS_((char **stringPtr,
			    char *match));
static char *		SplitMacPath _ANSI_ARGS_((char *path,
			    Tcl_DString *bufPtr));
static char *		SplitWinPath _ANSI_ARGS_((char *path,
			    Tcl_DString *bufPtr));
static char *		SplitUnixPath _ANSI_ARGS_((char *path,
			    Tcl_DString *bufPtr));





























/*
 *----------------------------------------------------------------------
 *
 * FileNameCleanup --
 *
 *	This procedure is a Tcl_ExitProc used to clean up the static






|
>




|






<
<
<
<
<
<
<






|














>
>
|
|
>
>
>













|
|


>


|

|

|

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







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
/* 
 * tclFileName.c --
 *
 *	This file contains routines for converting file names betwen
 *	native and network form.
 *
 * Copyright (c) 1995-1998 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: tclFileName.c,v 1.1.2.12 1999/04/05 23:14:26 stanton Exp $
 */

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








/*
 * The following regular expression matches the root portion of a Windows
 * absolute or volume relative path.  It will match both UNC and drive relative
 * paths.
 */

#define WIN_ROOT_PATTERN "^(([a-zA-Z]:)|[/\\\\][/\\\\]+([^/\\\\]+)[/\\\\]+([^/\\\\]+)|([/\\\\]))([/\\\\])*"

/*
 * The following regular expression matches the root portion of a Macintosh
 * absolute path.  It will match degenerate Unix-style paths, tilde paths,
 * Unix-style paths, and Mac paths.
 */

#define MAC_ROOT_PATTERN "^((/+([.][.]?/+)*([.][.]?)?)|(~[^:/]*)(/[^:]*)?|(~[^:]*)(:.*)?|/+([.][.]?/+)*([^:/]+)(/[^:]*)?|([^:]+):.*)$"

/*
 * The following variables are used to hold precompiled regular expressions
 * for use in filename matching.
 */

typedef struct ThreadSpecificData {
    int initialized;
    Tcl_Obj *winRootPatternPtr;
    Tcl_Obj *macRootPatternPtr;
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * The following variable is set in the TclPlatformInit call to one
 * of: TCL_PLATFORM_UNIX, TCL_PLATFORM_MAC, or TCL_PLATFORM_WINDOWS.
 */

TclPlatformType tclPlatform = TCL_PLATFORM_UNIX;

/*
 * Prototypes for local procedures defined in this file:
 */

static char *		DoTildeSubst _ANSI_ARGS_((Tcl_Interp *interp,
			    CONST char *user, Tcl_DString *resultPtr));
static CONST char *	ExtractWinRoot _ANSI_ARGS_((CONST char *path,
			    Tcl_DString *resultPtr, int offset));
static void		FileNameCleanup _ANSI_ARGS_((ClientData clientData));
static void		FileNameInit _ANSI_ARGS_((void));
static int		SkipToChar _ANSI_ARGS_((char **stringPtr,
			    char *match));
static char *		SplitMacPath _ANSI_ARGS_((CONST char *path,
			    Tcl_DString *bufPtr));
static char *		SplitWinPath _ANSI_ARGS_((CONST char *path,
			    Tcl_DString *bufPtr));
static char *		SplitUnixPath _ANSI_ARGS_((CONST char *path,
			    Tcl_DString *bufPtr));

/*
 *----------------------------------------------------------------------
 *
 * FileNameInit --
 *
 *	This procedure initializes the patterns used by this module.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Compiles the regular expressions.
 *
 *----------------------------------------------------------------------
 */

static void
FileNameInit()
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	tsdPtr->winRootPatternPtr = Tcl_NewStringObj(WIN_ROOT_PATTERN, -1);
	tsdPtr->macRootPatternPtr = Tcl_NewStringObj(MAC_ROOT_PATTERN, -1);
	Tcl_CreateThreadExitHandler(FileNameCleanup, NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FileNameCleanup --
 *
 *	This procedure is a Tcl_ExitProc used to clean up the static
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
 *----------------------------------------------------------------------
 */

static void
FileNameCleanup(clientData)
    ClientData clientData;	/* Not used. */
{
    if (winRootPatternPtr != NULL) {
	ckfree((char *)winRootPatternPtr);
        winRootPatternPtr = (regexp *) NULL;
    }
    if (macRootPatternPtr != NULL) {
	ckfree((char *)macRootPatternPtr);
        macRootPatternPtr = (regexp *) NULL;
    }
    initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * ExtractWinRoot --
 *







|
|
<
<
<
|
<
<
|







117
118
119
120
121
122
123
124
125



126


127
128
129
130
131
132
133
134
 *----------------------------------------------------------------------
 */

static void
FileNameCleanup(clientData)
    ClientData clientData;	/* Not used. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    Tcl_DecrRefCount(tsdPtr->winRootPatternPtr);



    Tcl_DecrRefCount(tsdPtr->macRootPatternPtr);


    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * ExtractWinRoot --
 *
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
 *
 * Side effects:
 *	Modifies the specified Tcl_DString.
 *
 *----------------------------------------------------------------------
 */

static char *
ExtractWinRoot(path, resultPtr, offset)
    char *path;			/* Path to parse. */
    Tcl_DString *resultPtr;	/* Buffer to hold result. */
    int offset;			/* Offset in buffer where result should be
				 * stored. */
{
    int length;





    /*
     * Initialize the path name parser for Windows path names.
     */

    if (winRootPatternPtr == NULL) {
	winRootPatternPtr = TclRegComp(WIN_ROOT_PATTERN);
	if (!initialized) {
	    Tcl_CreateExitHandler(FileNameCleanup, NULL);
	    initialized = 1;
	}
    }


    /*
     * Match the root portion of a Windows path name.
     */

    if (!TclRegExec(winRootPatternPtr, path, path)) {
	return path;
    }

    Tcl_DStringSetLength(resultPtr, offset);






    if (winRootPatternPtr->startp[2] != NULL) {

	Tcl_DStringAppend(resultPtr, winRootPatternPtr->startp[2], 2);
	if (winRootPatternPtr->startp[6] != NULL) {
	    Tcl_DStringAppend(resultPtr, "/", 1);
	}
    } else if (winRootPatternPtr->startp[4] != NULL) {
	Tcl_DStringAppend(resultPtr, "//", 2);
	length = winRootPatternPtr->endp[3]
	    - winRootPatternPtr->startp[3];
	Tcl_DStringAppend(resultPtr, winRootPatternPtr->startp[3], length);
	Tcl_DStringAppend(resultPtr, "/", 1);
	length = winRootPatternPtr->endp[4]
	    - winRootPatternPtr->startp[4];
	Tcl_DStringAppend(resultPtr, winRootPatternPtr->startp[4], length);
    } else {
	Tcl_DStringAppend(resultPtr, "/", 1);
    }
    return winRootPatternPtr->endp[0];
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetPathType --
 *







|

|





>
>
>
>





<
<
<
|
<
|
<
>





|





>
>
>
>
>
|
>
|
|


|

|
<
|

|
<
|



|







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
 *
 * Side effects:
 *	Modifies the specified Tcl_DString.
 *
 *----------------------------------------------------------------------
 */

static CONST char *
ExtractWinRoot(path, resultPtr, offset)
    CONST char *path;		/* Path to parse. */
    Tcl_DString *resultPtr;	/* Buffer to hold result. */
    int offset;			/* Offset in buffer where result should be
				 * stored. */
{
    int length;
    Tcl_RegExp re;
    char *dummy, *tail, *drive, *hostStart, *hostEnd, *shareStart,
	*shareEnd, *lastSlash;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Initialize the path name parser for Windows path names.
     */




    FileNameInit();



    re = Tcl_GetRegExpFromObj(NULL, tsdPtr->winRootPatternPtr, REG_ADVANCED);

    /*
     * Match the root portion of a Windows path name.
     */

    if (!Tcl_RegExpExec(NULL, re, path, path)) {
	return path;
    }

    Tcl_DStringSetLength(resultPtr, offset);

    Tcl_RegExpRange(re, 0, &dummy, &tail);
    Tcl_RegExpRange(re, 2, &drive, &dummy);
    Tcl_RegExpRange(re, 3, &hostStart, &hostEnd);
    Tcl_RegExpRange(re, 4, &shareStart, &shareEnd);
    Tcl_RegExpRange(re, 6, &lastSlash, &dummy);

    if (drive != NULL) {
	Tcl_DStringAppend(resultPtr, drive, 2);
	if (lastSlash != NULL) {
	    Tcl_DStringAppend(resultPtr, "/", 1);
	}
    } else if (shareStart != NULL) {
	Tcl_DStringAppend(resultPtr, "//", 2);
	length = hostEnd - hostStart;

	Tcl_DStringAppend(resultPtr, hostStart, length);
	Tcl_DStringAppend(resultPtr, "/", 1);
	length = shareEnd - shareStart;

	Tcl_DStringAppend(resultPtr, shareStart, length);
    } else {
	Tcl_DStringAppend(resultPtr, "/", 1);
    }
    return tail;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetPathType --
 *
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
 *----------------------------------------------------------------------
 */

Tcl_PathType
Tcl_GetPathType(path)
    char *path;
{

    Tcl_PathType type = TCL_PATH_ABSOLUTE;


    switch (tclPlatform) {
   	case TCL_PLATFORM_UNIX:
	    /*
	     * Paths that begin with / or ~ are absolute.
	     */

	    if ((path[0] != '/') && (path[0] != '~')) {
		type = TCL_PATH_RELATIVE;
	    }
	    break;

	case TCL_PLATFORM_MAC:
	    if (path[0] == ':') {
		type = TCL_PATH_RELATIVE;
	    } else if (path[0] != '~') {


		/*
		 * Since we have eliminated the easy cases, use the
		 * root pattern to look for the other types.
		 */


		if (!macRootPatternPtr) {
		    macRootPatternPtr = TclRegComp(MAC_ROOT_PATTERN);
		    if (!initialized) {
			Tcl_CreateExitHandler(FileNameCleanup, NULL);
			initialized = 1;
		    }




		}
		if (!TclRegExec(macRootPatternPtr, path, path)
			|| (macRootPatternPtr->startp[2] != NULL)) {
		    type = TCL_PATH_RELATIVE;

		}
	    }
	    break;
	
	case TCL_PLATFORM_WINDOWS:
	    if (path[0] != '~') {


		/*
		 * Since we have eliminated the easy cases, check for
		 * drive relative paths using the regular expression.
		 */


		if (!winRootPatternPtr) {
		    winRootPatternPtr = TclRegComp(WIN_ROOT_PATTERN);
		    if (!initialized) {
			Tcl_CreateExitHandler(FileNameCleanup, NULL);
			initialized = 1;
		    }


		}
		if (TclRegExec(winRootPatternPtr, path, path)) {
		    if (winRootPatternPtr->startp[5]

			    || (winRootPatternPtr->startp[2]
				    && !(winRootPatternPtr->startp[6]))) {
			type = TCL_PATH_VOLUME_RELATIVE;
		    }
		} else {
		    type = TCL_PATH_RELATIVE;
		}
	    }
	    break;







>

>
















>






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






>






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







220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

255


256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

281


282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
 *----------------------------------------------------------------------
 */

Tcl_PathType
Tcl_GetPathType(path)
    char *path;
{
    ThreadSpecificData *tsdPtr;
    Tcl_PathType type = TCL_PATH_ABSOLUTE;
    Tcl_RegExp re;

    switch (tclPlatform) {
   	case TCL_PLATFORM_UNIX:
	    /*
	     * Paths that begin with / or ~ are absolute.
	     */

	    if ((path[0] != '/') && (path[0] != '~')) {
		type = TCL_PATH_RELATIVE;
	    }
	    break;

	case TCL_PLATFORM_MAC:
	    if (path[0] == ':') {
		type = TCL_PATH_RELATIVE;
	    } else if (path[0] != '~') {
		tsdPtr = TCL_TSD_INIT(&dataKey);

		/*
		 * Since we have eliminated the easy cases, use the
		 * root pattern to look for the other types.
		 */

		FileNameInit();
		re = Tcl_GetRegExpFromObj(NULL, tsdPtr->macRootPatternPtr,

			REG_ADVANCED);



		if (!Tcl_RegExpExec(NULL, re, path, path)) {
		    type = TCL_PATH_RELATIVE;
		} else {
		    char *unixRoot, *dummy;

		    Tcl_RegExpRange(re, 2, &unixRoot, &dummy);
		    if (unixRoot) {
			type = TCL_PATH_RELATIVE;
		    }
		}
	    }
	    break;
	
	case TCL_PLATFORM_WINDOWS:
	    if (path[0] != '~') {
		tsdPtr = TCL_TSD_INIT(&dataKey);

		/*
		 * Since we have eliminated the easy cases, check for
		 * drive relative paths using the regular expression.
		 */

		FileNameInit();
		re = Tcl_GetRegExpFromObj(NULL, tsdPtr->winRootPatternPtr,

			REG_ADVANCED);



		if (Tcl_RegExpExec(NULL, re, path, path)) {
		    char *drive, *dummy, *unixRoot, *lastSlash;

		    Tcl_RegExpRange(re, 2, &drive, &dummy);
		    Tcl_RegExpRange(re, 5, &unixRoot, &dummy);
		    Tcl_RegExpRange(re, 6, &lastSlash, &dummy);
		    
		    if (unixRoot || (drive && !lastSlash)) {
			type = TCL_PATH_VOLUME_RELATIVE;
		    }
		} else {
		    type = TCL_PATH_RELATIVE;
		}
	    }
	    break;
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
 *	Allocates memory.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SplitPath(path, argcPtr, argvPtr)
    char *path;			/* Pointer to string containing a path. */
    int *argcPtr;		/* Pointer to location to fill in with
				 * the number of elements in the path. */
    char ***argvPtr;		/* Pointer to place to store pointer to array
				 * of pointers to path elements. */
{
    int i, size;
    char *p;
    Tcl_DString buffer;

    Tcl_DStringInit(&buffer);

    /*
     * Perform platform specific splitting.  These routines will leave the
     * result in the specified buffer.  Individual elements are terminated
     * with a null character.
     */







|








>







323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
 *	Allocates memory.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SplitPath(path, argcPtr, argvPtr)
    CONST char *path;		/* Pointer to string containing a path. */
    int *argcPtr;		/* Pointer to location to fill in with
				 * the number of elements in the path. */
    char ***argvPtr;		/* Pointer to place to store pointer to array
				 * of pointers to path elements. */
{
    int i, size;
    char *p;
    Tcl_DString buffer;

    Tcl_DStringInit(&buffer);

    /*
     * Perform platform specific splitting.  These routines will leave the
     * result in the specified buffer.  Individual elements are terminated
     * with a null character.
     */
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
SplitUnixPath(path, bufPtr)
    char *path;			/* Pointer to string containing a path. */
    Tcl_DString *bufPtr;	/* Pointer to DString to use for the result. */
{
    int length;
    char *p, *elementStart;

    /*
     * Deal with the root directory as a special case.
     */

    if (path[0] == '/') {
	Tcl_DStringAppend(bufPtr, "/", 2);







|



|







417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
SplitUnixPath(path, bufPtr)
    CONST char *path;		/* Pointer to string containing a path. */
    Tcl_DString *bufPtr;	/* Pointer to DString to use for the result. */
{
    int length;
    CONST char *p, *elementStart;

    /*
     * Deal with the root directory as a special case.
     */

    if (path[0] == '/') {
	Tcl_DStringAppend(bufPtr, "/", 2);
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
SplitWinPath(path, bufPtr)
    char *path;			/* Pointer to string containing a path. */
    Tcl_DString *bufPtr;	/* Pointer to DString to use for the result. */
{
    int length;
    char *p, *elementStart;

    p = ExtractWinRoot(path, bufPtr, 0);

    /*
     * Terminate the root portion, if we matched something.
     */








|



|







479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
SplitWinPath(path, bufPtr)
    CONST char *path;		/* Pointer to string containing a path. */
    Tcl_DString *bufPtr;	/* Pointer to DString to use for the result. */
{
    int length;
    CONST char *p, *elementStart;

    p = ExtractWinRoot(path, bufPtr, 0);

    /*
     * Terminate the root portion, if we matched something.
     */

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
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
SplitMacPath(path, bufPtr)
    char *path;			/* Pointer to string containing a path. */
    Tcl_DString *bufPtr;	/* Pointer to DString to use for the result. */
{
    int isMac = 0;		/* 1 if is Mac-style, 0 if Unix-style path. */
    int i, length;
    char *p, *elementStart;



    /*
     * Initialize the path name parser for Macintosh path names.
     */

    if (macRootPatternPtr == NULL) {
	macRootPatternPtr = TclRegComp(MAC_ROOT_PATTERN);
	if (!initialized) {
	    Tcl_CreateExitHandler(FileNameCleanup, NULL);
	    initialized = 1;
	}
    }

    /*
     * Match the root portion of a Mac path name.
     */

    i = 0;			/* Needed only to prevent gcc warnings. */



    if (TclRegExec(macRootPatternPtr, path, path) == 1) {


	/*
	 * Treat degenerate absolute paths like / and /../.. as
	 * Mac relative file names for lack of anything else to do.
	 */


	if (macRootPatternPtr->startp[2] != NULL) {
	    Tcl_DStringAppend(bufPtr, ":", 1);

	    Tcl_DStringAppend(bufPtr, path, macRootPatternPtr->endp[0]
		    - macRootPatternPtr->startp[0] + 1);
	    return Tcl_DStringValue(bufPtr);
	}

	if (macRootPatternPtr->startp[5] != NULL) {

	    /*
	     * Unix-style tilde prefixed paths.
	     */

	    isMac = 0;
	    i = 5;
	} else if (macRootPatternPtr->startp[7] != NULL) {


	    /*
	     * Mac-style tilde prefixed paths.
	     */

	    isMac = 1;
	    i = 7;
	} else if (macRootPatternPtr->startp[10] != NULL) {



	    /*
	     * Normal Unix style paths.
	     */

	    isMac = 0;
	    i = 10;
	} else if (macRootPatternPtr->startp[12] != NULL) {



	    /*
	     * Normal Mac style paths.
	     */

	    isMac = 1;
	    i = 12;
	}



	length = macRootPatternPtr->endp[i]

	    - macRootPatternPtr->startp[i];

	/*
	 * Append the element and terminate it with a : and a null.  Note that
	 * we are forcing the DString to contain an extra null at the end.
	 */

	Tcl_DStringAppend(bufPtr, macRootPatternPtr->startp[i], length);
	Tcl_DStringAppend(bufPtr, ":", 2);
	p = macRootPatternPtr->endp[i];
    } else {
	isMac = (strchr(path, ':') != NULL);
	p = path;
    }
    
    if (isMac) {








|




|
>
>





<
<
<
|
<
<
<






>
>
>
|
>
>





>
|

>
|
<



|
|






|
|
>
|
|
|

|
|
|
>
>

|
|
|

|
|
|
>
>

|
|
|

|
|
|
|
>
>
|
>
|






|

|







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
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
SplitMacPath(path, bufPtr)
    CONST char *path;		/* Pointer to string containing a path. */
    Tcl_DString *bufPtr;	/* Pointer to DString to use for the result. */
{
    int isMac = 0;		/* 1 if is Mac-style, 0 if Unix-style path. */
    int i, length;
    CONST char *p, *elementStart;
    Tcl_RegExp re;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Initialize the path name parser for Macintosh path names.
     */




    FileNameInit();




    /*
     * Match the root portion of a Mac path name.
     */

    i = 0;			/* Needed only to prevent gcc warnings. */

    re = Tcl_GetRegExpFromObj(NULL, tsdPtr->macRootPatternPtr, REG_ADVANCED);

    if (Tcl_RegExpExec(NULL, re, path, path) == 1) {
	char *start, *end;

	/*
	 * Treat degenerate absolute paths like / and /../.. as
	 * Mac relative file names for lack of anything else to do.
	 */

	Tcl_RegExpRange(re, 2, &start, &end);
	if (start) {
	    Tcl_DStringAppend(bufPtr, ":", 1);
	    Tcl_RegExpRange(re, 0, &start, &end);
	    Tcl_DStringAppend(bufPtr, path, end - start + 1);

	    return Tcl_DStringValue(bufPtr);
	}

	Tcl_RegExpRange(re, 5, &start, &end);
	if (start) {
	    /*
	     * Unix-style tilde prefixed paths.
	     */

	    isMac = 0;
	    i = 5;
	} else {
	    Tcl_RegExpRange(re, 7, &start, &end);
	    if (start) {
		/*
		 * Mac-style tilde prefixed paths.
		 */

		isMac = 1;
		i = 7;
	    } else {
		Tcl_RegExpRange(re, 10, &start, &end);
		if (start) {

		    /*
		     * Normal Unix style paths.
		     */

		    isMac = 0;
		    i = 10;
		} else {
		    Tcl_RegExpRange(re, 12, &start, &end);
		    if (start) {

			/*
			 * Normal Mac style paths.
			 */

			isMac = 1;
			i = 12;
		    }
		}
	    }
	}

	Tcl_RegExpRange(re, i, &start, &end);
	length = end - start;

	/*
	 * Append the element and terminate it with a : and a null.  Note that
	 * we are forcing the DString to contain an extra null at the end.
	 */

	Tcl_DStringAppend(bufPtr, start, length);
	Tcl_DStringAppend(bufPtr, ":", 2);
	p = end;
    } else {
	isMac = (strchr(path, ':') != NULL);
	p = path;
    }
    
    if (isMac) {

686
687
688
689
690
691
692
693

694
695
696
697
698
699
700
Tcl_JoinPath(argc, argv, resultPtr)
    int argc;
    char **argv;
    Tcl_DString *resultPtr;	/* Pointer to previously initialized DString. */
{
    int oldLength, length, i, needsSep;
    Tcl_DString buffer;
    char *p, c, *dest;


    Tcl_DStringInit(&buffer);
    oldLength = Tcl_DStringLength(resultPtr);

    switch (tclPlatform) {
   	case TCL_PLATFORM_UNIX:
	    for (i = 0; i < argc; i++) {







|
>







732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
Tcl_JoinPath(argc, argv, resultPtr)
    int argc;
    char **argv;
    Tcl_DString *resultPtr;	/* Pointer to previously initialized DString. */
{
    int oldLength, length, i, needsSep;
    Tcl_DString buffer;
    char c, *dest;
    CONST char *p;

    Tcl_DStringInit(&buffer);
    oldLength = Tcl_DStringLength(resultPtr);

    switch (tclPlatform) {
   	case TCL_PLATFORM_UNIX:
	    for (i = 0; i < argc; i++) {
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897


898
899
900
901
902
903
904
905

906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
			       
    }
    Tcl_DStringFree(&buffer);
    return Tcl_DStringValue(resultPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TranslateFileName --
 *
 *	Converts a file name into a form usable by the native system
 *	interfaces.  If the name starts with a tilde, it will produce
 *	a name where the tilde and following characters have been
 *	replaced by the home directory location for the named user.
 *
 * Results:
 *	The result is a pointer to a static string containing


 *	the new name.  If there was an error in processing the
 *	name, then an error message is left in interp->result
 *	and the return value is NULL.  The result will be stored
 *	in bufferPtr; the caller must call Tcl_DStringFree(bufferPtr)
 *	to free the name if the return value was not NULL.
 *
 * Side effects:
 *	Information may be left in bufferPtr.

 *
 *----------------------------------------------------------------------
 */

char *
Tcl_TranslateFileName(interp, name, bufferPtr)
    Tcl_Interp *interp;		/* Interpreter in which to store error
				 * message (if necessary). */
    char *name;			/* File name, which may begin with "~"
				 * (to indicate current user's home directory)
				 * or "~<user>" (to indicate any user's
				 * home directory). */
    Tcl_DString *bufferPtr;	/* May be used to hold result.  Must not hold
				 * anything at the time of the call, and need
				 * not even be initialized. */
{
    register char *p;

    /*
     * Handle tilde substitutions, if needed.
     */

    if (name[0] == '~') {
	int argc, length;
	char **argv;
	Tcl_DString temp;

	Tcl_SplitPath(name, &argc, &argv);
	
	/*
	 * Strip the trailing ':' off of a Mac path
	 * before passing the user name to DoTildeSubst.
	 */

	if (tclPlatform == TCL_PLATFORM_MAC) {
	    length = strlen(argv[0]);
	    argv[0][length-1] = '\0';
	}
	







|




|
|
|


|
>
>
|
|
|
|
|


<
>








|
|
|
|
|
<
|















|
|







927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953

954
955
956
957
958
959
960
961
962
963
964
965
966
967

968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
			       
    }
    Tcl_DStringFree(&buffer);
    return Tcl_DStringValue(resultPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_TranslateFileName --
 *
 *	Converts a file name into a form usable by the native system
 *	interfaces.  If the name starts with a tilde, it will produce a
 *	name where the tilde and following characters have been replaced
 *	by the home directory location for the named user.
 *
 * Results:
 *	The return value is a pointer to a string containing the name
 *	after tilde substitution.  If there was no tilde substitution,
 *	the return value is a pointer to a copy of the original string.
 *	If there was an error in processing the name, then an error
 *	message is left in the interp's result (if interp was not NULL)
 *	and the return value is NULL.  Space for the return value is
 *	allocated in bufferPtr; the caller must call Tcl_DStringFree()
 *	to free the space if the return value was not NULL.
 *
 * Side effects:

 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_TranslateFileName(interp, name, bufferPtr)
    Tcl_Interp *interp;		/* Interpreter in which to store error
				 * message (if necessary). */
    char *name;			/* File name, which may begin with "~" (to
				 * indicate current user's home directory) or
				 * "~<user>" (to indicate any user's home
				 * directory). */
    Tcl_DString *bufferPtr;	/* Uninitialized or free DString filled

				 * with name after tilde substitution. */
{
    register char *p;

    /*
     * Handle tilde substitutions, if needed.
     */

    if (name[0] == '~') {
	int argc, length;
	char **argv;
	Tcl_DString temp;

	Tcl_SplitPath(name, &argc, &argv);
	
	/*
	 * Strip the trailing ':' off of a Mac path before passing the user
	 * name to DoTildeSubst.
	 */

	if (tclPlatform == TCL_PLATFORM_MAC) {
	    length = strlen(argv[0]);
	    argv[0][length-1] = '\0';
	}
	
1027
1028
1029
1030
1031
1032
1033
1034


1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059

1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079


1080
1081
1082
1083
1084
1085
1086
1087
1088
1089

1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131


1132



1133
1134
1135





1136









1137
1138









1139





1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155




































1156

1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167

1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244

1245
1246


1247


1248
1249
1250
1251
1252
1253
1254


1255
1256

1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
    p = strrchr(name, '.');
    if ((p != NULL) && (lastSep != NULL)
	    && (lastSep > p)) {
	p = NULL;
    }

    /*
     * Back up to the first period in a series of contiguous dots.


     * This is needed so foo..o will be split on the first dot.
     */

    if (p != NULL) {
	while ((p > name) && *(p-1) == '.') {
	    p--;
	}
    }
    return p;
}

/*
 *----------------------------------------------------------------------
 *
 * DoTildeSubst --
 *
 *	Given a string following a tilde, this routine returns the
 *	corresponding home directory.
 *
 * Results:
 *	The result is a pointer to a static string containing the home
 *	directory in native format.  If there was an error in processing
 *	the substitution, then an error message is left in interp->result
 *	and the return value is NULL.  On success, the results are appended
 * 	to resultPtr, and the contents of resultPtr are returned.

 *
 * Side effects:
 *	Information may be left in resultPtr.
 *
 *----------------------------------------------------------------------
 */

static char *
DoTildeSubst(interp, user, resultPtr)
    Tcl_Interp *interp;		/* Interpreter in which to store error
				 * message (if necessary). */
    char *user;			/* Name of user whose home directory should be
				 * substituted, or "" for current user. */
    Tcl_DString *resultPtr;	/* May be used to hold result.  Must not hold
				 * anything at the time of the call, and need
				 * not even be initialized. */
{
    char *dir;

    if (*user == '\0') {


	dir = TclGetEnv("HOME");
	if (dir == NULL) {
	    if (interp) {
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, "couldn't find HOME environment ",
			"variable to expand path", (char *) NULL);
	    }
	    return NULL;
	}
	Tcl_JoinPath(1, &dir, resultPtr);

    } else {
	
	/* lint, TclGetuserHome() always NULL under windows. */
	if (TclGetUserHome(user, resultPtr) == NULL) {	
	    if (interp) {
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, "user \"", user, "\" doesn't exist",
			(char *) NULL);
	    }
	    return NULL;
	}
    }
    return resultPtr->string;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GlobCmd --
 *
 *	This procedure is invoked to process the "glob" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_GlobCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    int i, noComplain, firstArg;
    char c;


    int result = TCL_OK;



    Tcl_DString buffer;
    char *separators, *head, *tail;






    noComplain = 0;









    for (firstArg = 1; (firstArg < argc) && (argv[firstArg][0] == '-');
	    firstArg++) {









	if (strcmp(argv[firstArg], "-nocomplain") == 0) {





	    noComplain = 1;
	} else if (strcmp(argv[firstArg], "--") == 0) {
	    firstArg++;
	    break;
	} else {

	    Tcl_AppendResult(interp, "bad switch \"", argv[firstArg],
		    "\": must be -nocomplain or --", (char *) NULL);
	    return TCL_ERROR;
	}
    }
    if (firstArg >= argc) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" ?switches? name ?name ...?\"", (char *) NULL);
	return TCL_ERROR;
    }





































    Tcl_DStringInit(&buffer);

    separators = NULL;		/* Needed only to prevent gcc warnings. */
    for (i = firstArg; i < argc; i++) {
	switch (tclPlatform) {
	case TCL_PLATFORM_UNIX:
	    separators = "/";
	    break;
	case TCL_PLATFORM_WINDOWS:
	    separators = "/\\:";
	    break;
	case TCL_PLATFORM_MAC:
	    separators = (strchr(argv[i], ':') == NULL) ? "/" : ":";

	    break;
	}

	Tcl_DStringSetLength(&buffer, 0);

	/*
	 * Perform tilde substitution, if needed.
	 */

	if (argv[i][0] == '~') {
	    char *p;

	    /*
	     * Find the first path separator after the tilde.
	     */

	    for (tail = argv[i]; *tail != '\0'; tail++) {
		if (*tail == '\\') {
		    if (strchr(separators, tail[1]) != NULL) {
			break;
		    }
		} else if (strchr(separators, *tail) != NULL) {
		    break;
		}
	    }

	    /*
	     * Determine the home directory for the specified user.  Note that
	     * we don't allow special characters in the user name.
	     */

	    c = *tail;
	    *tail = '\0';
	    p = strpbrk(argv[i]+1, "\\[]*?{}");
	    if (p == NULL) {
		head = DoTildeSubst(interp, argv[i]+1, &buffer);
	    } else {
		if (!noComplain) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendResult(interp, "globbing characters not ",
			    "supported in user names", (char *) NULL);
		}
		head = NULL;
	    }
	    *tail = c;
	    if (head == NULL) {
		if (noComplain) {
		    Tcl_ResetResult(interp);
		    continue;
		} else {
		    result = TCL_ERROR;
		    goto done;
		}
	    }
	    if (head != Tcl_DStringValue(&buffer)) {
		Tcl_DStringAppend(&buffer, head, -1);
	    }
	} else {
	    tail = argv[i];
	}

	result = TclDoGlob(interp, separators, &buffer, tail);
	if (result != TCL_OK) {
	    if (noComplain) {
		/*
		 * We should in fact pass down the nocomplain flag 
		 * or save the interp result or use another mecanism
		 * so the interp result is not mangled on errors in that case.
		 * but that would a bigger change than reasonable for a patch
		 * release.
		 * (see fileName.test 15.2-15.4 for expected behaviour)
		 */
		Tcl_ResetResult(interp);
		result = TCL_OK;
		continue;
	    } else {
		goto done;

	    }
	}


    }



    if ((*interp->result == 0) && !noComplain) {
	char *sep = "";

	Tcl_AppendResult(interp, "no files matched glob pattern",
		(argc == 2) ? " \"" : "s \"", (char *) NULL);
	for (i = firstArg; i < argc; i++) {


	    Tcl_AppendResult(interp, sep, argv[i], (char *) NULL);
	    sep = " ";

	}
	Tcl_AppendResult(interp, "\"", (char *) NULL);
	result = TCL_ERROR;
    }
done:
    Tcl_DStringFree(&buffer);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * SkipToChar --







|
>
>
|


<
<
<
<
<














|
|
|
>











|

|
<
|




>
>
|









>

<
<
|














|















|


|
|

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



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







|
>

|

|

|
|
|

|
|

|
|
|

|
|
|
|
|
|
|
|
|

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



|






|
<

<
>


>
>
|
>
>
|
<
<

|
<
|
>
>
|
<
>

<
<

<
<







1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087





1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119

1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138


1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219




1220
1221

1222
1223
1224



1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322

















1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333

1334

1335
1336
1337
1338
1339
1340
1341
1342
1343


1344
1345

1346
1347
1348
1349

1350
1351


1352


1353
1354
1355
1356
1357
1358
1359
    p = strrchr(name, '.');
    if ((p != NULL) && (lastSep != NULL)
	    && (lastSep > p)) {
	p = NULL;
    }

    /*
     * In earlier versions, we used to back up to the first period in a series
     * so that "foo..o" would be split into "foo" and "..o".  This is a
     * confusing and usually incorrect behavior, so now we split at the last
     * period in the name.
     */






    return p;
}

/*
 *----------------------------------------------------------------------
 *
 * DoTildeSubst --
 *
 *	Given a string following a tilde, this routine returns the
 *	corresponding home directory.
 *
 * Results:
 *	The result is a pointer to a static string containing the home
 *	directory in native format.  If there was an error in processing
 *	the substitution, then an error message is left in the interp's
 *	result and the return value is NULL.  On success, the results
 *	are appended to resultPtr, and the contents of resultPtr are
 *	returned.
 *
 * Side effects:
 *	Information may be left in resultPtr.
 *
 *----------------------------------------------------------------------
 */

static char *
DoTildeSubst(interp, user, resultPtr)
    Tcl_Interp *interp;		/* Interpreter in which to store error
				 * message (if necessary). */
    CONST char *user;		/* Name of user whose home directory should be
				 * substituted, or "" for current user. */
    Tcl_DString *resultPtr;	/* Initialized DString filled with name

				 * after tilde substitution. */
{
    char *dir;

    if (*user == '\0') {
	Tcl_DString dirString;
	
	dir = TclGetEnv("HOME", &dirString);
	if (dir == NULL) {
	    if (interp) {
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, "couldn't find HOME environment ",
			"variable to expand path", (char *) NULL);
	    }
	    return NULL;
	}
	Tcl_JoinPath(1, &dir, resultPtr);
	Tcl_DStringFree(&dirString);
    } else {


	if (TclpGetUserHome(user, resultPtr) == NULL) {	
	    if (interp) {
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, "user \"", user, "\" doesn't exist",
			(char *) NULL);
	    }
	    return NULL;
	}
    }
    return resultPtr->string;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GlobObjCmd --
 *
 *	This procedure is invoked to process the "glob" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_GlobObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int index, i, noComplain, skip, length;
    char *string;
    static char *options[] = {"-nocomplain", "--", NULL};
    enum options {GLOB_NOCOMPLAIN, GLOB_LAST};

    noComplain = 0;
    for (skip = 1; skip < objc; skip++) {
	string = Tcl_GetString(objv[skip]);
	if (string[0] != '-') {
	    break;
	}
	if (Tcl_GetIndexFromObj(interp, objv[skip], options, "switch",
		TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == GLOB_NOCOMPLAIN) {
	    noComplain = 1;
	} else {
	    skip++;
	    break;
	}
    }
    if (skip >= objc) {
        Tcl_WrongNumArgs(interp, 1, objv, "?switches? name ?name ...?");
	return TCL_ERROR;
    }

    for (i = skip; i < objc; i++) {
	string = Tcl_GetString(objv[i]);
	if (TclGlob(interp, string, noComplain) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    if (noComplain == 0) {
	Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &length);
	if (length == 0) {
	    char *sep = "";

	    Tcl_AppendResult(interp, "no files matched glob pattern",
		    (objc == 2) ? " \"" : "s \"", (char *) NULL);
	    for (i = skip; i < objc; i++) {
		string = Tcl_GetString(objv[i]);
		Tcl_AppendResult(interp, sep, string, (char *) NULL);
		sep = " ";




	    }
	    Tcl_AppendResult(interp, "\"", (char *) NULL);

	    return TCL_ERROR;
	}
    }



    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclGlob --
 *
 *	This procedure prepares arguments for the TclDoGlob call.
 *	It sets the separator string based on the platform, performs
 *      tilde substitution, and calls TclDoGlob.
 *
 * Results:
 *	The return value is a standard Tcl result indicating whether
 *	an error occurred in globbing.  After a normal return the
 *	result in interp (set by TclDoGlob) holds all of the file names
 *	given by the dir and rem arguments.  After an error the
 *	result in interp will hold an error message.
 *
 * Side effects:
 *	The currentArgString is written to.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
TclGlob(interp, pattern, noComplain)
    Tcl_Interp *interp;		/* Interpreter for returning error message
				 * or appending list of matching file names. */
    char *pattern;		/* Glob pattern to match. Must not refer
				 * to a static string. */
    int noComplain;		/* Flag to turn off storing error messages
				 * in interp. */
{
    char *separators;
    char *head, *tail;
    char c;
    int result;
    Tcl_DString buffer;

    separators = NULL;		/* lint. */

    switch (tclPlatform) {
	case TCL_PLATFORM_UNIX:
	    separators = "/";
	    break;
	case TCL_PLATFORM_WINDOWS:
	    separators = "/\\:";
	    break;
	case TCL_PLATFORM_MAC:
	    separators = (strchr(pattern, ':') == NULL)
		? "/" : ":";
	    break;
    }

    Tcl_DStringInit(&buffer);

    /*
     * Perform tilde substitution, if needed.
     */

    if (pattern[0] == '~') {
	char *p;

	/*
	 * Find the first path separator after the tilde.
	 */

	for (tail = pattern; *tail != '\0'; tail++) {
	    if (*tail == '\\') {
		if (strchr(separators, tail[1]) != NULL) {
		    break;
		}
	    } else if (strchr(separators, *tail) != NULL) {
		break;
	    }
	}

	/*
	 * Determine the home directory for the specified user.  Note that
	 * we don't allow special characters in the user name.
	 */
	
	c = *tail;
	*tail = '\0';
	p = strpbrk(pattern+1, "\\[]*?{}");
	if (p == NULL) {
	    head = DoTildeSubst(interp, pattern+1, &buffer);
	} else {
	    if (!noComplain) {
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, "globbing characters not ",
			"supported in user names", (char *) NULL);
	    }
	    head = NULL;
	}
	*tail = c;
	if (head == NULL) {

















	    if (noComplain) {
		/*
		 * We should in fact pass down the nocomplain flag 
		 * or save the interp result or use another mechanism
		 * so the interp result is not mangled on errors in that case.
		 * but that would a bigger change than reasonable for a patch
		 * release.
		 * (see fileName.test 15.2-15.4 for expected behaviour)
		 */
		Tcl_ResetResult(interp);
		return TCL_OK;

	    } else {

		return TCL_ERROR;
	    }
	}
	if (head != Tcl_DStringValue(&buffer)) {
	    Tcl_DStringAppend(&buffer, head, -1);
	}
    } else {
	tail = pattern;
    }



    result = TclDoGlob(interp, separators, &buffer, tail);

    Tcl_DStringFree(&buffer);
    if (result != TCL_OK) {
	if (noComplain) {
	    Tcl_ResetResult(interp);

	    return TCL_OK;
	}


    }


    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * SkipToChar --
1342
1343
1344
1345
1346
1347
1348
1349

1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
TclDoGlob(interp, separators, headPtr, tail)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting
				 * (e.g. unmatched brace). */
    char *separators;		/* String containing separator characters
				 * that should be used to identify globbing
				 * boundaries. */
    Tcl_DString *headPtr;	/* Completely expanded prefix. */
    char *tail;			/* The unexpanded remainder of the path. */

{
    int baseLength, quoted, count;
    int result = TCL_OK;
    char *p, *openBrace, *closeBrace, *name, *firstSpecialChar, savedChar;
    char lastChar = 0;
    int length = Tcl_DStringLength(headPtr);

    if (length > 0) {
	lastChar = Tcl_DStringValue(headPtr)[length-1];
    }








|
>



|







1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
TclDoGlob(interp, separators, headPtr, tail)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting
				 * (e.g. unmatched brace). */
    char *separators;		/* String containing separator characters
				 * that should be used to identify globbing
				 * boundaries. */
    Tcl_DString *headPtr;	/* Completely expanded prefix. */
    char *tail;			/* The unexpanded remainder of the path.
				 * Must not be a pointer to a static string. */
{
    int baseLength, quoted, count;
    int result = TCL_OK;
    char *name, *p, *openBrace, *closeBrace, *firstSpecialChar, savedChar;
    char lastChar = 0;
    int length = Tcl_DStringLength(headPtr);

    if (length > 0) {
	lastChar = Tcl_DStringValue(headPtr)[length-1];
    }

1518
1519
1520
1521
1522
1523
1524






1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568

1569
1570

1571
1572
1573
1574
1575
1576
1577
     * this path component.  The variable p is pointing at a quoted or
     * unquoted directory separator or the end of the string.  So we need
     * to check for special globbing characters in the current pattern.
     * We avoid modifying tail if p is pointing at the end of the string.
     */

    if (*p != '\0') {






	 savedChar = *p;
	 *p = '\0';
	 firstSpecialChar = strpbrk(tail, "*[]?\\");
	 *p = savedChar;
    } else {
	firstSpecialChar = strpbrk(tail, "*[]?\\");
    }

    if (firstSpecialChar != NULL) {
	/*
	 * Look for matching files in the current directory.  The
	 * implementation of this function is platform specific, but may
	 * recursively call TclDoGlob.  For each file that matches, it will
	 * add the match onto the interp->result, or call TclDoGlob if there
	 * are more characters to be processed.
	 */

	return TclMatchFiles(interp, separators, headPtr, tail, p);
    }
    Tcl_DStringAppend(headPtr, tail, p-tail);
    if (*p != '\0') {
	return TclDoGlob(interp, separators, headPtr, p);
    }

    /*
     * There are no more wildcards in the pattern and no more unprocessed
     * characters in the tail, so now we can construct the path and verify
     * the existence of the file.
     */

    switch (tclPlatform) {
	case TCL_PLATFORM_MAC:
	    if (strchr(Tcl_DStringValue(headPtr), ':') == NULL) {
		Tcl_DStringAppend(headPtr, ":", 1);
	    }
	    name = Tcl_DStringValue(headPtr);
	    if (access(name, F_OK) == 0) {
		if ((name[1] != '\0') && (strchr(name+1, ':') == NULL)) {
		    Tcl_AppendElement(interp, name+1);
		} else {
		    Tcl_AppendElement(interp, name);
		}
	    }
	    break;

	case TCL_PLATFORM_WINDOWS: {
	    int exists;

	    /*
	     * We need to convert slashes to backslashes before checking
	     * for the existence of the file.  Once we are done, we need
	     * to convert the slashes back.
	     */

	    if (Tcl_DStringLength(headPtr) == 0) {







>
>
>
>
>
>













|



|













|




|

|





>


>







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
     * this path component.  The variable p is pointing at a quoted or
     * unquoted directory separator or the end of the string.  So we need
     * to check for special globbing characters in the current pattern.
     * We avoid modifying tail if p is pointing at the end of the string.
     */

    if (*p != '\0') {

	/*
	 * Note that we are modifying the string in place.  This won't work
	 * if the string is a static.
	 */

	 savedChar = *p;
	 *p = '\0';
	 firstSpecialChar = strpbrk(tail, "*[]?\\");
	 *p = savedChar;
    } else {
	firstSpecialChar = strpbrk(tail, "*[]?\\");
    }

    if (firstSpecialChar != NULL) {
	/*
	 * Look for matching files in the current directory.  The
	 * implementation of this function is platform specific, but may
	 * recursively call TclDoGlob.  For each file that matches, it will
	 * add the match onto the interp's result, or call TclDoGlob if there
	 * are more characters to be processed.
	 */

	return TclpMatchFiles(interp, separators, headPtr, tail, p);
    }
    Tcl_DStringAppend(headPtr, tail, p-tail);
    if (*p != '\0') {
	return TclDoGlob(interp, separators, headPtr, p);
    }

    /*
     * There are no more wildcards in the pattern and no more unprocessed
     * characters in the tail, so now we can construct the path and verify
     * the existence of the file.
     */

    switch (tclPlatform) {
	case TCL_PLATFORM_MAC: {
	    if (strchr(Tcl_DStringValue(headPtr), ':') == NULL) {
		Tcl_DStringAppend(headPtr, ":", 1);
	    }
	    name = Tcl_DStringValue(headPtr);
	    if (TclpAccess(name, F_OK) == 0) {
		if ((name[1] != '\0') && (strchr(name+1, ':') == NULL)) {
		    Tcl_AppendElement(interp, name + 1);
		} else {
		    Tcl_AppendElement(interp, name);
		}
	    }
	    break;
	}
	case TCL_PLATFORM_WINDOWS: {
	    int exists;
	    
	    /*
	     * We need to convert slashes to backslashes before checking
	     * for the existence of the file.  Once we are done, we need
	     * to convert the slashes back.
	     */

	    if (Tcl_DStringLength(headPtr) == 0) {
1585
1586
1587
1588
1589
1590
1591
1592

1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615

1616
1617
1618
1619
		for (p = Tcl_DStringValue(headPtr); *p != '\0'; p++) {
		    if (*p == '/') {
			*p = '\\';
		    }
		}
	    }
	    name = Tcl_DStringValue(headPtr);
	    exists = (access(name, F_OK) == 0);

	    for (p = name; *p != '\0'; p++) {
		if (*p == '\\') {
		    *p = '/';
		}
	    }
	    if (exists) {
		Tcl_AppendElement(interp, name);
	    }
	    break;
	}
	case TCL_PLATFORM_UNIX:
	    if (Tcl_DStringLength(headPtr) == 0) {
		if ((*name == '\\' && name[1] == '/') || (*name == '/')) {
		    Tcl_DStringAppend(headPtr, "/", 1);
		} else {
		    Tcl_DStringAppend(headPtr, ".", 1);
		}
	    }
	    name = Tcl_DStringValue(headPtr);
	    if (access(name, F_OK) == 0) {
		Tcl_AppendElement(interp, name);
	    }
	    break;

    }

    return TCL_OK;
}







|
>










|








|



>




1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
		for (p = Tcl_DStringValue(headPtr); *p != '\0'; p++) {
		    if (*p == '/') {
			*p = '\\';
		    }
		}
	    }
	    name = Tcl_DStringValue(headPtr);
	    exists = (TclpAccess(name, F_OK) == 0);

	    for (p = name; *p != '\0'; p++) {
		if (*p == '\\') {
		    *p = '/';
		}
	    }
	    if (exists) {
		Tcl_AppendElement(interp, name);
	    }
	    break;
	}
	case TCL_PLATFORM_UNIX: {
	    if (Tcl_DStringLength(headPtr) == 0) {
		if ((*name == '\\' && name[1] == '/') || (*name == '/')) {
		    Tcl_DStringAppend(headPtr, "/", 1);
		} else {
		    Tcl_DStringAppend(headPtr, ".", 1);
		}
	    }
	    name = Tcl_DStringValue(headPtr);
	    if (TclpAccess(name, F_OK) == 0) {
		Tcl_AppendElement(interp, name);
	    }
	    break;
	}
    }

    return TCL_OK;
}

Changes to generic/tclGet.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
/* 
 * tclGet.c --
 *
 *	This file contains procedures to convert strings into
 *	other forms, like integers or floating-point numbers or
 *	booleans, doing syntax checking along the way.
 *
 * Copyright (c) 1990-1993 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclGet.c 1.33 97/05/14 16:42:19
 */

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


/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetInt --
 *
 *	Given a string, produce the corresponding integer value.
 *
 * Results:
 *	The return value is normally TCL_OK;  in this case *intPtr
 *	will be set to the integer value equivalent to string.  If
 *	string is improperly formed then TCL_ERROR is returned and
 *	an error message will be left in interp->result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */









|




|

















|







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
/* 
 * tclGet.c --
 *
 *	This file contains procedures to convert strings into
 *	other forms, like integers or floating-point numbers or
 *	booleans, doing syntax checking along the way.
 *
 * Copyright (c) 1990-1993 The Regents of the University of California.
 * 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: tclGet.c,v 1.1.2.2 1998/09/24 23:58:50 stanton Exp $
 */

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


/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetInt --
 *
 *	Given a string, produce the corresponding integer value.
 *
 * Results:
 *	The return value is normally TCL_OK;  in this case *intPtr
 *	will be set to the integer value equivalent to string.  If
 *	string is improperly formed then TCL_ERROR is returned and
 *	an error message will be left in the interp's result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

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: use strtoul instead of strtol for integer conversions
     * to allow full-size unsigned numbers, but don't depend on strtoul
     * to handle sign characters;  it won't in some implementations.
     */

    errno = 0;
    for (p = string; isspace(UCHAR(*p)); p++) {
	/* Empty loop body. */
    }
    if (*p == '-') {
	p++;
	i = -((long)strtoul(p, &end, 0));
    } else if (*p == '+') {
	p++;
	i = strtoul(p, &end, 0);
    } else {
	i = strtoul(p, &end, 0);
    }
    if (end == p) {
	badInteger:
        if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "expected integer but got \"", string,
                    "\"", (char *) NULL);
        }







|




|


|

|







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: use strtoul instead of strtol for integer conversions
     * to allow full-size unsigned numbers, but don't depend on strtoul
     * to handle sign characters;  it won't in some implementations.
     */

    errno = 0;
    for (p = string; isspace(UCHAR(*p)); p++) {	/* INTL: ISO space. */
	/* Empty loop body. */
    }
    if (*p == '-') {
	p++;
	i = -((long)strtoul(p, &end, 0)); /* INTL: Tcl source. */
    } else if (*p == '+') {
	p++;
	i = strtoul(p, &end, 0); /* INTL: Tcl source. */
    } else {
	i = strtoul(p, &end, 0); /* INTL: Tcl source. */
    }
    if (end == p) {
	badInteger:
        if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "expected integer but got \"", string,
                    "\"", (char *) NULL);
        }
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
     */

    if ((errno == ERANGE) || (((long)(int) i) != i)) {
        if (interp != (Tcl_Interp *) NULL) {
	    Tcl_SetResult(interp, "integer value too large to represent",
		    TCL_STATIC);
            Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW",
                    interp->result, (char *) NULL);
        }
	return TCL_ERROR;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
    if (*end != 0) {
	goto badInteger;
    }
    *intPtr = (int) i;
    return TCL_OK;







|



|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
     */

    if ((errno == ERANGE) || (((long)(int) i) != i)) {
        if (interp != (Tcl_Interp *) NULL) {
	    Tcl_SetResult(interp, "integer value too large to represent",
		    TCL_STATIC);
            Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW",
		    Tcl_GetStringResult(interp), (char *) NULL);
        }
	return TCL_ERROR;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) { /* INTL: ISO space. */
	end++;
    }
    if (*end != 0) {
	goto badInteger;
    }
    *intPtr = (int) i;
    return TCL_OK;
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
 *	This routine is a version of Tcl_GetInt but returns a "long"
 *	instead of an "int".
 *
 * Results:
 *	The return value is normally TCL_OK; in this case *longPtr
 *	will be set to the long integer value equivalent to string. If
 *	string is improperly formed then TCL_ERROR is returned and
 *	an error message will be left in interp->result.

 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclGetLong(interp, string, longPtr)
    Tcl_Interp *interp;		/* Interpreter used for error reporting. */

    char *string;		/* String containing a (possibly signed)
				 * long integer in a form acceptable to
				 * strtoul. */
    long *longPtr;		/* Place to store converted long result. */
{
    char *end, *p;
    long i;

    /*
     * Note: don't depend on strtoul to handle sign characters; it won't
     * in some implementations.
     */

    errno = 0;
    for (p = string; isspace(UCHAR(*p)); p++) {
	/* Empty loop body. */
    }
    if (*p == '-') {
	p++;
	i = -(int)strtoul(p, &end, 0);
    } else if (*p == '+') {
	p++;
	i = strtoul(p, &end, 0);
    } else {
	i = strtoul(p, &end, 0);
    }
    if (end == p) {
	badInteger:
        if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "expected integer but got \"", string,
                    "\"", (char *) NULL);
        }
	return TCL_ERROR;
    }
    if (errno == ERANGE) {
        if (interp != (Tcl_Interp *) NULL) {
	    Tcl_SetResult(interp, "integer value too large to represent",
		    TCL_STATIC);
            Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW",
                    interp->result, (char *) NULL);
        }
	return TCL_ERROR;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
    if (*end != 0) {
	goto badInteger;
    }
    *longPtr = i;
    return TCL_OK;







|
>









|
>














|




|


|

|














|



|







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
 *	This routine is a version of Tcl_GetInt but returns a "long"
 *	instead of an "int".
 *
 * Results:
 *	The return value is normally TCL_OK; in this case *longPtr
 *	will be set to the long integer value equivalent to string. If
 *	string is improperly formed then TCL_ERROR is returned and
 *	an error message will be left in the interp's result if interp
 *	is non-NULL. 
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclGetLong(interp, string, longPtr)
    Tcl_Interp *interp;		/* Interpreter used for error reporting
				 * if not NULL. */
    char *string;		/* String containing a (possibly signed)
				 * long integer in a form acceptable to
				 * strtoul. */
    long *longPtr;		/* Place to store converted long result. */
{
    char *end, *p;
    long i;

    /*
     * Note: don't depend on strtoul to handle sign characters; it won't
     * in some implementations.
     */

    errno = 0;
    for (p = string; isspace(UCHAR(*p)); p++) {	/* INTL: ISO space. */
	/* Empty loop body. */
    }
    if (*p == '-') {
	p++;
	i = -(int)strtoul(p, &end, 0); /* INTL: Tcl source. */
    } else if (*p == '+') {
	p++;
	i = strtoul(p, &end, 0); /* INTL: Tcl source. */
    } else {
	i = strtoul(p, &end, 0); /* INTL: Tcl source. */
    }
    if (end == p) {
	badInteger:
        if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "expected integer but got \"", string,
                    "\"", (char *) NULL);
        }
	return TCL_ERROR;
    }
    if (errno == ERANGE) {
        if (interp != (Tcl_Interp *) NULL) {
	    Tcl_SetResult(interp, "integer value too large to represent",
		    TCL_STATIC);
            Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW",
                    Tcl_GetStringResult(interp), (char *) NULL);
        }
	return TCL_ERROR;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) { /* INTL: ISO space. */
	end++;
    }
    if (*end != 0) {
	goto badInteger;
    }
    *longPtr = i;
    return TCL_OK;
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
 *	Given a string, produce the corresponding double-precision
 *	floating-point value.
 *
 * Results:
 *	The return value is normally TCL_OK; in this case *doublePtr
 *	will be set to the double-precision value equivalent to string.
 *	If string is improperly formed then TCL_ERROR is returned and
 *	an error message will be left in interp->result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetDouble(interp, string, doublePtr)
    Tcl_Interp *interp;		/* Interpreter used for error reporting. */
    char *string;		/* String containing a floating-point number
				 * in a form acceptable to strtod. */
    double *doublePtr;		/* Place to store converted result. */
{
    char *end;
    double d;

    errno = 0;
    d = strtod(string, &end);
    if (end == string) {
	badDouble:
        if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp,
                    "expected floating-point number but got \"",
                    string, "\"", (char *) NULL);
        }
	return TCL_ERROR;
    }
    if (errno != 0) {
        if (interp != (Tcl_Interp *) NULL) {
            TclExprFloatError(interp, d); /* sets interp->objResult */

	    /*
	     * Move the interpreter's object result to the string result, 
	     * then reset the object result.
	     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
	     */

	    Tcl_SetResult(interp,
	            TclGetStringFromObj(Tcl_GetObjResult(interp),
			    (int *) NULL),
	            TCL_VOLATILE);
        }
	return TCL_ERROR;
    }
    while ((*end != 0) && isspace(UCHAR(*end))) {
	end++;
    }
    if (*end != 0) {
	goto badDouble;
    }
    *doublePtr = d;
    return TCL_OK;







|


















|











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



|







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
 *	Given a string, produce the corresponding double-precision
 *	floating-point value.
 *
 * Results:
 *	The return value is normally TCL_OK; in this case *doublePtr
 *	will be set to the double-precision value equivalent to string.
 *	If string is improperly formed then TCL_ERROR is returned and
 *	an error message will be left in the interp's result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetDouble(interp, string, doublePtr)
    Tcl_Interp *interp;		/* Interpreter used for error reporting. */
    char *string;		/* String containing a floating-point number
				 * in a form acceptable to strtod. */
    double *doublePtr;		/* Place to store converted result. */
{
    char *end;
    double d;

    errno = 0;
    d = strtod(string, &end); /* INTL: Tcl source. */
    if (end == string) {
	badDouble:
        if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp,
                    "expected floating-point number but got \"",
                    string, "\"", (char *) NULL);
        }
	return TCL_ERROR;
    }
    if (errno != 0) {
        if (interp != (Tcl_Interp *) NULL) {
            TclExprFloatError(interp, d); 











        }
	return TCL_ERROR;
    }
    while ((*end != 0) && isspace(UCHAR(*end))) { /* INTL: ISO space. */
	end++;
    }
    if (*end != 0) {
	goto badDouble;
    }
    *doublePtr = d;
    return TCL_OK;
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
 *	Given a string, return a 0/1 boolean value corresponding
 *	to the string.
 *
 * Results:
 *	The return value is normally TCL_OK;  in this case *boolPtr
 *	will be set to the 0/1 value equivalent to string.  If
 *	string is improperly formed then TCL_ERROR is returned and
 *	an error message will be left in interp->result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */








|







244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
 *	Given a string, return a 0/1 boolean value corresponding
 *	to the string.
 *
 * Results:
 *	The return value is normally TCL_OK;  in this case *boolPtr
 *	will be set to the 0/1 value equivalent to string.  If
 *	string is improperly formed then TCL_ERROR is returned and
 *	an error message will be left in the interp's result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
				 * will be 0 or 1. */
{
    int i;
    char lowerCase[10], c;
    size_t length;

    /*
     * Convert the input string to all lower-case.

     */

    for (i = 0; i < 9; i++) {
	c = string[i];
	if (c == 0) {
	    break;
	}







|
>







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
				 * will be 0 or 1. */
{
    int i;
    char lowerCase[10], c;
    size_t length;

    /*
     * Convert the input string to all lower-case. 
     * INTL: This code will work on UTF strings.
     */

    for (i = 0; i < 9; i++) {
	c = string[i];
	if (c == 0) {
	    break;
	}

Changes to generic/tclGetDate.y.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 
 * tclGetDate.y --
 *
 *	Contains yacc grammar for parsing date and time strings.
 *	The output of this file should be the file tclDate.c which
 *	is used directly in the Tcl sources.
 *
 * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
 * 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.
 *
 * SCCS: @(#) tclGetDate.y 1.34 97/02/03 14:53:54
 */

%{
/* 
 * tclDate.c --
 *
 *	This file is generated from a yacc grammar defined in













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 
 * tclGetDate.y --
 *
 *	Contains yacc grammar for parsing date and time strings.
 *	The output of this file should be the file tclDate.c which
 *	is used directly in the Tcl sources.
 *
 * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
 * 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: tclGetDate.y,v 1.1.2.3 1999/03/10 06:49:16 stanton Exp $
 */

%{
/* 
 * tclDate.c --
 *
 *	This file is generated from a yacc grammar defined in
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
    }
    Julian *= SECSPERDAY;
    Julian += yyTimezone * 60L;
    if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
        return -1;
    Julian += tod;
    if (DSTmode == DSTon
     || (DSTmode == DSTmaybe && TclpGetDate(&Julian, 0)->tm_isdst))
        Julian -= 60 * 60;
    *TimePtr = Julian;
    return 0;
}


static time_t
DSTcorrect(Start, Future)
    time_t      Start;
    time_t      Future;
{
    time_t      StartDay;
    time_t      FutureDay;

    StartDay = (TclpGetDate(&Start, 0)->tm_hour + 1) % 24;
    FutureDay = (TclpGetDate(&Future, 0)->tm_hour + 1) % 24;
    return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
}


static time_t
RelativeDate(Start, DayOrdinal, DayNumber)
    time_t      Start;
    time_t      DayOrdinal;
    time_t      DayNumber;
{
    struct tm   *tm;
    time_t      now;

    now = Start;
    tm = TclpGetDate(&now, 0);
    now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
    now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
    return DSTcorrect(Start, now);
}


static int







|














|
|














|







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
    }
    Julian *= SECSPERDAY;
    Julian += yyTimezone * 60L;
    if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
        return -1;
    Julian += tod;
    if (DSTmode == DSTon
     || (DSTmode == DSTmaybe && TclpGetDate((TclpTime_t)&Julian, 0)->tm_isdst))
        Julian -= 60 * 60;
    *TimePtr = Julian;
    return 0;
}


static time_t
DSTcorrect(Start, Future)
    time_t      Start;
    time_t      Future;
{
    time_t      StartDay;
    time_t      FutureDay;

    StartDay = (TclpGetDate((TclpTime_t)&Start, 0)->tm_hour + 1) % 24;
    FutureDay = (TclpGetDate((TclpTime_t)&Future, 0)->tm_hour + 1) % 24;
    return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
}


static time_t
RelativeDate(Start, DayOrdinal, DayNumber)
    time_t      Start;
    time_t      DayOrdinal;
    time_t      DayNumber;
{
    struct tm   *tm;
    time_t      now;

    now = Start;
    tm = TclpGetDate((TclpTime_t)&now, 0);
    now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
    now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
    return DSTcorrect(Start, now);
}


static int
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
    time_t Julian;
    int result;

    if (RelMonth == 0) {
        *TimePtr = 0;
        return 0;
    }
    tm = TclpGetDate(&Start, 0);
    Month = 12 * (tm->tm_year + TM_YEAR_BASE) + tm->tm_mon + RelMonth;
    Year = Month / 12;
    Month = Month % 12 + 1;
    result = Convert(Month, (time_t) tm->tm_mday, Year,
	    (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
	    MER24, DSTmaybe, &Julian);
    /*







|







646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
    time_t Julian;
    int result;

    if (RelMonth == 0) {
        *TimePtr = 0;
        return 0;
    }
    tm = TclpGetDate((TclpTime_t)&Start, 0);
    Month = 12 * (tm->tm_year + TM_YEAR_BASE) + tm->tm_mon + RelMonth;
    Year = Month / 12;
    Month = Month % 12 + 1;
    result = Convert(Month, (time_t) tm->tm_mday, Year,
	    (time_t) tm->tm_hour, (time_t) tm->tm_min, (time_t) tm->tm_sec,
	    MER24, DSTmaybe, &Julian);
    /*
688
689
690
691
692
693
694
695
696
697
698
699

700
701
702
703
704
705
706
    register TABLE *tp;
    int i;
    int abbrev;

    /*
     * Make it lowercase.
     */
    for (p = buff; *p; p++) {
        if (isupper(UCHAR(*p))) {
            *p = (char) tolower(UCHAR(*p));
	}
    }


    if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
        yylval.Meridian = MERam;
        return tMERIDIAN;
    }
    if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
        yylval.Meridian = MERpm;







<
<
<
|
<
>







688
689
690
691
692
693
694



695

696
697
698
699
700
701
702
703
    register TABLE *tp;
    int i;
    int abbrev;

    /*
     * Make it lowercase.
     */





    Tcl_UtfToLower(buff);

    if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
        yylval.Meridian = MERam;
        return tMERIDIAN;
    }
    if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
        yylval.Meridian = MERpm;
765
766
767
768
769
770
771
772

773
774
775
776
777
778
779
            return tp->type;
        }
    }

    /*
     * Military timezones.
     */
    if (buff[1] == '\0' && isalpha(UCHAR(*buff))) {

        for (tp = MilitaryTable; tp->name; tp++) {
            if (strcmp(buff, tp->name) == 0) {
                yylval.Number = tp->value;
                return tp->type;
            }
	}
    }







|
>







762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
            return tp->type;
        }
    }

    /*
     * Military timezones.
     */
    if (buff[1] == '\0' && !(*buff & 0x80)
	    && isalpha(UCHAR(*buff))) {	/* INTL: ISO only */
        for (tp = MilitaryTable; tp->name; tp++) {
            if (strcmp(buff, tp->name) == 0) {
                yylval.Number = tp->value;
                return tp->type;
            }
	}
    }
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830

831
832
833
834
835
836
837
838
839
840

841
842
843
844
845
846
847
    int                 sign;

    for ( ; ; ) {
        while (isspace((unsigned char) (*yyInput))) {
            yyInput++;
	}

        if (isdigit(c = *yyInput) || c == '-' || c == '+') {
            if (c == '-' || c == '+') {
                sign = c == '-' ? -1 : 1;
                if (!isdigit(*++yyInput)) {
                    /*
		     * skip the '-' sign
		     */
                    continue;
		}
            } else {
                sign = 0;
	    }
            for (yylval.Number = 0; isdigit(c = *yyInput++); ) {

                yylval.Number = 10 * yylval.Number + c - '0';
	    }
            yyInput--;
            if (sign < 0) {
                yylval.Number = -yylval.Number;
	    }
            return sign ? tSNUMBER : tUNUMBER;
        }
        if (isalpha(UCHAR(c))) {
            for (p = buff; isalpha(c = *yyInput++) || c == '.'; ) {

                if (p < &buff[sizeof buff - 1]) {
                    *p++ = c;
		}
	    }
            *p = '\0';
            yyInput--;
            return LookupWord(buff);







|


|








|
>








|
|
>







809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
    int                 sign;

    for ( ; ; ) {
        while (isspace((unsigned char) (*yyInput))) {
            yyInput++;
	}

        if (isdigit(c = *yyInput) || c == '-' || c == '+') { /* INTL: digit */
            if (c == '-' || c == '+') {
                sign = c == '-' ? -1 : 1;
                if (!isdigit(*++yyInput)) { /* INTL: digit */
                    /*
		     * skip the '-' sign
		     */
                    continue;
		}
            } else {
                sign = 0;
	    }
            for (yylval.Number = 0;
		    isdigit(c = *yyInput++); ) { /* INTL: digit */
                yylval.Number = 10 * yylval.Number + c - '0';
	    }
            yyInput--;
            if (sign < 0) {
                yylval.Number = -yylval.Number;
	    }
            return sign ? tSNUMBER : tUNUMBER;
        }
        if (!(c & 0x80) && isalpha(UCHAR(c))) {	/* INTL: ISO only. */
            for (p = buff; isalpha(c = *yyInput++) /* INTL: ISO only. */
		     || c == '.'; ) {
                if (p < &buff[sizeof buff - 1]) {
                    *p++ = c;
		}
	    }
            *p = '\0';
            yyInput--;
            return LookupWord(buff);
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
    struct tm *tm;
    time_t Start;
    time_t Time;
    time_t tod;
    int thisyear;

    yyInput = p;
    tm = TclpGetDate((time_t *) &now, 0);
    thisyear = tm->tm_year + TM_YEAR_BASE;
    yyYear = thisyear;
    yyMonth = tm->tm_mon + 1;
    yyDay = tm->tm_mday;
    yyTimezone = zone;
    if (zone == -50000) {
        yyDSTmode = DSToff;  /* assume GMT */







|







877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
    struct tm *tm;
    time_t Start;
    time_t Time;
    time_t tod;
    int thisyear;

    yyInput = p;
    tm = TclpGetDate((TclpTime_t) &now, 0);
    thisyear = tm->tm_year + TM_YEAR_BASE;
    yyYear = thisyear;
    yyMonth = tm->tm_mon + 1;
    yyDay = tm->tm_mday;
    yyTimezone = zone;
    if (zone == -50000) {
        yyDSTmode = DSToff;  /* assume GMT */

Changes to generic/tclHash.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclHash.c --
 *
 *	Implementation of in-memory hash tables for Tcl and Tcl-based
 *	applications.
 *
 * Copyright (c) 1991-1993 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclHash.c 1.16 96/04/29 10:30:49
 */

#include "tclInt.h"

/*
 * When there are this many entries per bucket, on average, rebuild
 * the hash table to make it larger.












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclHash.c --
 *
 *	Implementation of in-memory hash tables for Tcl and Tcl-based
 *	applications.
 *
 * Copyright (c) 1991-1993 The Regents of the University of California.
 * Copyright (c) 1994 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: tclHash.c,v 1.1.2.2 1998/09/24 23:58:50 stanton Exp $
 */

#include "tclInt.h"

/*
 * When there are this many entries per bucket, on average, rebuild
 * the hash table to make it larger.
79
80
81
82
83
84
85





86
87
88
89
90
91
92
Tcl_InitHashTable(tablePtr, keyType)
    register Tcl_HashTable *tablePtr;	/* Pointer to table record, which
					 * is supplied by the caller. */
    int keyType;			/* Type of keys to use in table:
					 * TCL_STRING_KEYS, TCL_ONE_WORD_KEYS,
					 * or an integer >= 2. */
{





    tablePtr->buckets = tablePtr->staticBuckets;
    tablePtr->staticBuckets[0] = tablePtr->staticBuckets[1] = 0;
    tablePtr->staticBuckets[2] = tablePtr->staticBuckets[3] = 0;
    tablePtr->numBuckets = TCL_SMALL_HASH_TABLE;
    tablePtr->numEntries = 0;
    tablePtr->rebuildSize = TCL_SMALL_HASH_TABLE*REBUILD_MULTIPLIER;
    tablePtr->downShift = 28;







>
>
>
>
>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
Tcl_InitHashTable(tablePtr, keyType)
    register Tcl_HashTable *tablePtr;	/* Pointer to table record, which
					 * is supplied by the caller. */
    int keyType;			/* Type of keys to use in table:
					 * TCL_STRING_KEYS, TCL_ONE_WORD_KEYS,
					 * or an integer >= 2. */
{
#if (TCL_SMALL_HASH_TABLE != 4) 
    panic("Tcl_InitHashTable: TCL_SMALL_HASH_TABLE is %d, not 4\n",
	    TCL_SMALL_HASH_TABLE);
#endif
    
    tablePtr->buckets = tablePtr->staticBuckets;
    tablePtr->staticBuckets[0] = tablePtr->staticBuckets[1] = 0;
    tablePtr->staticBuckets[2] = tablePtr->staticBuckets[3] = 0;
    tablePtr->numBuckets = TCL_SMALL_HASH_TABLE;
    tablePtr->numEntries = 0;
    tablePtr->rebuildSize = TCL_SMALL_HASH_TABLE*REBUILD_MULTIPLIER;
    tablePtr->downShift = 28;

Changes to generic/tclHistory.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * Copyright (c) 1990-1993 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclHistory.c 1.47 97/08/04 16:08:17
 */

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


/*







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * Copyright (c) 1990-1993 The Regents of the University of California.
 * 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: tclHistory.c,v 1.1.2.3 1999/02/01 21:29:51 stanton Exp $
 */

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


/*
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
    int result;

    if (length > 0) {
	/*
	 * Call Tcl_RecordAndEvalObj to do the actual work.
	 */

	TclNewObj(cmdPtr);
	TclInitStringRep(cmdPtr, cmd, length);
	Tcl_IncrRefCount(cmdPtr);

	result = Tcl_RecordAndEvalObj(interp, cmdPtr, flags);

	/*
	 * Move the interpreter's object result to the string result, 
	 * then reset the object result.
	 * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
	 */

	Tcl_SetResult(interp,
	        TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
	        TCL_VOLATILE);

	/*
	 * Discard the Tcl object created to hold the command.
	 */
	
	Tcl_DecrRefCount(cmdPtr);	







<
|

<





<


|
<







53
54
55
56
57
58
59

60
61

62
63
64
65
66

67
68
69

70
71
72
73
74
75
76
    int result;

    if (length > 0) {
	/*
	 * Call Tcl_RecordAndEvalObj to do the actual work.
	 */


	cmdPtr = Tcl_NewStringObj(cmd, length);
	Tcl_IncrRefCount(cmdPtr);

	result = Tcl_RecordAndEvalObj(interp, cmdPtr, flags);

	/*
	 * Move the interpreter's object result to the string result, 
	 * then reset the object result.

	 */

	Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),

	        TCL_VOLATILE);

	/*
	 * Discard the Tcl object created to hold the command.
	 */
	
	Tcl_DecrRefCount(cmdPtr);	
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
Tcl_RecordAndEvalObj(interp, cmdPtr, flags)
    Tcl_Interp *interp;		/* Token for interpreter in which command
				 * will be executed. */
    Tcl_Obj *cmdPtr;		/* Points to object holding the command to
				 * record and execute. */
    int flags;			/* Additional flags. TCL_NO_EVAL means
				 * record only: don't execute the command.
				 * TCL_EVAL_GLOBAL means use
				 * Tcl_GlobalEvalObj instead of
				 * Tcl_EvalObj. */
{
    Interp *iPtr = (Interp *) interp;
    int result;
    Tcl_Obj *list[3];
    register Tcl_Obj *objPtr;

    /*
     * Do recording by eval'ing a tcl history command: history add $cmd.
     */

    list[0] = Tcl_NewStringObj("history", -1);
    list[1] = Tcl_NewStringObj("add", -1);
    list[2] = cmdPtr;
    
    objPtr = Tcl_NewListObj(3, list);
    Tcl_IncrRefCount(objPtr);
    (void) Tcl_GlobalEvalObj(interp, objPtr);
    Tcl_DecrRefCount(objPtr);

    /*
     * Execute the command.
     */

    result = TCL_OK;
    if (!(flags & TCL_NO_EVAL)) {
	iPtr->evalFlags = (flags & ~TCL_EVAL_GLOBAL);
	if (flags & TCL_EVAL_GLOBAL) {
	    result = Tcl_GlobalEvalObj(interp, cmdPtr);
	} else {
	    result = Tcl_EvalObj(interp, cmdPtr);
	}
    }
    return result;
}







|
|
|

<














|








<
<
<
<
|
<



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
Tcl_RecordAndEvalObj(interp, cmdPtr, flags)
    Tcl_Interp *interp;		/* Token for interpreter in which command
				 * will be executed. */
    Tcl_Obj *cmdPtr;		/* Points to object holding the command to
				 * record and execute. */
    int flags;			/* Additional flags. TCL_NO_EVAL means
				 * record only: don't execute the command.
				 * TCL_EVAL_GLOBAL means evaluate the
				 * script in global variable context instead
				 * of the current procedure. */
{

    int result;
    Tcl_Obj *list[3];
    register Tcl_Obj *objPtr;

    /*
     * Do recording by eval'ing a tcl history command: history add $cmd.
     */

    list[0] = Tcl_NewStringObj("history", -1);
    list[1] = Tcl_NewStringObj("add", -1);
    list[2] = cmdPtr;
    
    objPtr = Tcl_NewListObj(3, list);
    Tcl_IncrRefCount(objPtr);
    (void) Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL);
    Tcl_DecrRefCount(objPtr);

    /*
     * Execute the command.
     */

    result = TCL_OK;
    if (!(flags & TCL_NO_EVAL)) {




	result = Tcl_EvalObjEx(interp, cmdPtr, flags & TCL_EVAL_GLOBAL);

    }
    return result;
}

Changes to generic/tclIO.c.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* 
 * tclIO.c --
 *
 *	This file provides the generic portions (those that are the same on
 *	all platforms and for all channel types) of Tcl's IO facilities.
 *

 * 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.
 *
 * SCCS: @(#) tclIO.c 1.272 97/10/22 10:27:53
 */

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

/*
 * Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not
 * compile on systems where neither is defined. We want both defined so
 * that we can test safely for both. In the code we still have to test for
 * both because there may be systems on which both are defined and have
 * different values.






>





|


|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* 
 * tclIO.c --
 *
 *	This file provides the generic portions (those that are the same on
 *	all platforms and for all channel types) of Tcl's IO facilities.
 *
 * Copyright (c) 1998 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: tclIO.c,v 1.1.2.7 1999/04/14 00:33:23 surles Exp $
 */

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

/*
 * Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not
 * compile on systems where neither is defined. We want both defined so
 * that we can test safely for both. In the code we still have to test for
 * both because there may be systems on which both are defined and have
 * different values.
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
 */

typedef struct ChannelBuffer {
    int nextAdded;		/* The next position into which a character
                                 * will be put in the buffer. */
    int nextRemoved;		/* Position of next byte to be removed
                                 * from the buffer. */
    int bufSize;		/* How big is the buffer? */
    struct ChannelBuffer *nextPtr;
    				/* Next buffer in chain. */
    char buf[4];		/* Placeholder for real buffer. The real
                                 * buffer occuppies this space + bufSize-4
                                 * bytes. This must be the last field in
                                 * the structure. */
} ChannelBuffer;

#define CHANNELBUFFER_HEADER_SIZE	(sizeof(ChannelBuffer) - 4)









/*
 * The following defines the *default* buffer size for channels.
 */

#define CHANNELBUFFER_DEFAULT_SIZE	(1024 * 4)

/*







|










>
>
>
>
>
>
>
>







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

typedef struct ChannelBuffer {
    int nextAdded;		/* The next position into which a character
                                 * will be put in the buffer. */
    int nextRemoved;		/* Position of next byte to be removed
                                 * from the buffer. */
    int bufLength;		/* How big is the buffer? */
    struct ChannelBuffer *nextPtr;
    				/* Next buffer in chain. */
    char buf[4];		/* Placeholder for real buffer. The real
                                 * buffer occuppies this space + bufSize-4
                                 * bytes. This must be the last field in
                                 * the structure. */
} ChannelBuffer;

#define CHANNELBUFFER_HEADER_SIZE	(sizeof(ChannelBuffer) - 4)

/*
 * How much extra space to allocate in buffer to hold bytes from previous
 * buffer (when converting to UTF-8) or to hold bytes that will go to
 * next buffer (when converting from UTF-8).
 */
 
#define BUFFER_PADDING	    16
 
/*
 * The following defines the *default* buffer size for channels.
 */

#define CHANNELBUFFER_DEFAULT_SIZE	(1024 * 4)

/*
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
 */

typedef struct EventScriptRecord {
    struct Channel *chanPtr;	/* The channel for which this script is
                                 * registered. This is used only when an
                                 * error occurs during evaluation of the
                                 * script, to delete the handler. */
    char *script;		/* Script to invoke. */
    Tcl_Interp *interp;		/* In what interpreter to invoke script? */
    int mask;			/* Events must overlap current mask for the
                                 * stored script to be invoked. */
    struct EventScriptRecord *nextPtr;
    				/* Next in chain of records. */
} EventScriptRecord;








|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
 */

typedef struct EventScriptRecord {
    struct Channel *chanPtr;	/* The channel for which this script is
                                 * registered. This is used only when an
                                 * error occurs during evaluation of the
                                 * script, to delete the handler. */
    Tcl_Obj *scriptPtr;		/* Script to invoke. */
    Tcl_Interp *interp;		/* In what interpreter to invoke script? */
    int mask;			/* Events must overlap current mask for the
                                 * stored script to be invoked. */
    struct EventScriptRecord *nextPtr;
    				/* Next in chain of records. */
} EventScriptRecord;

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

typedef struct Channel {
    char *channelName;		/* The name of the channel instance in Tcl
                                 * commands. Storage is owned by the generic IO
                                 * code,  is dynamically allocated. */
    int	flags;			/* ORed combination of the flags defined
                                 * below. */



















    Tcl_EolTranslation inputTranslation;
				/* What translation to apply for end of line
                                 * sequences on input? */    
    Tcl_EolTranslation outputTranslation;
    				/* What translation to use for generating
                                 * end of line sequences in output? */
    int inEofChar;		/* If nonzero, use this as a signal of EOF
                                 * on input. */
    int outEofChar;             /* If nonzero, append this to the channel
                                 * when it is closed if it is open for
                                 * writing. */
    int unreportedError;	/* Non-zero if an error report was deferred
                                 * because it happened in the background. The
                                 * value is the POSIX error code. */
    ClientData instanceData;	/* Instance specific data. */


    Tcl_ChannelType *typePtr;	/* Pointer to channel type structure. */
    int refCount;		/* How many interpreters hold references to
                                 * this IO channel? */
    CloseCallback *closeCbPtr;	/* Callbacks registered to be called when the
                                 * channel is closed. */



    ChannelBuffer *curOutPtr;	/* Current output buffer being filled. */
    ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */
    ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */

    ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates
                                 * need to allocate a new buffer for "gets"
                                 * that crosses buffer boundaries. */







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














|
>
>





>
>
>







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

typedef struct Channel {
    char *channelName;		/* The name of the channel instance in Tcl
                                 * commands. Storage is owned by the generic IO
                                 * code,  is dynamically allocated. */
    int	flags;			/* ORed combination of the flags defined
                                 * below. */
    Tcl_Encoding encoding;	/* Encoding to apply when reading or writing
				 * data on this channel.  NULL means no
				 * encoding is applied to data. */
    Tcl_EncodingState inputEncodingState;
				/* Current encoding state, used when converting
				 * input data bytes to UTF-8. */
    int inputEncodingFlags;	/* Encoding flags to pass to conversion
				 * routine when converting input data bytes to
				 * UTF-8.  May be TCL_ENCODING_START before
				 * converting first byte and TCL_ENCODING_END
				 * when EOF is seen. */
    Tcl_EncodingState outputEncodingState;
				/* Current encoding state, used when converting
				 * UTF-8 to output data bytes. */
    int outputEncodingFlags;	/* Encoding flags to pass to conversion
				 * routine when converting UTF-8 to output
				 * data bytes.  May be TCL_ENCODING_START
				 * before converting first byte and
				 * TCL_ENCODING_END when EOF is seen. */
    Tcl_EolTranslation inputTranslation;
				/* What translation to apply for end of line
                                 * sequences on input? */    
    Tcl_EolTranslation outputTranslation;
    				/* What translation to use for generating
                                 * end of line sequences in output? */
    int inEofChar;		/* If nonzero, use this as a signal of EOF
                                 * on input. */
    int outEofChar;             /* If nonzero, append this to the channel
                                 * when it is closed if it is open for
                                 * writing. */
    int unreportedError;	/* Non-zero if an error report was deferred
                                 * because it happened in the background. The
                                 * value is the POSIX error code. */
    ClientData instanceData;	/* Instance-specific data provided by
				 * creator of channel. */

    Tcl_ChannelType *typePtr;	/* Pointer to channel type structure. */
    int refCount;		/* How many interpreters hold references to
                                 * this IO channel? */
    CloseCallback *closeCbPtr;	/* Callbacks registered to be called when the
                                 * channel is closed. */
    char *outputStage;		/* Temporary staging buffer used when
				 * translating EOL before converting from
				 * UTF-8 to external form. */
    ChannelBuffer *curOutPtr;	/* Current output buffer being filled. */
    ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */
    ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */

    ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates
                                 * need to allocate a new buffer for "gets"
                                 * that crosses buffer boundaries. */
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
#define CHANNEL_BLOCKED	(1<<11)	/* EWOULDBLOCK or EAGAIN occurred
					 * on this channel. This bit is
                                         * cleared before every input or
                                         * output operation. */
#define INPUT_SAW_CR		(1<<12)	/* Channel is in CRLF eol input
					 * translation mode and the last
                                         * byte seen was a "\r". */



#define CHANNEL_DEAD		(1<<13)	/* The channel has been closed by
					 * the exit handler (on exit) but
                                         * not deallocated. When any IO
                                         * operation sees this flag on a
                                         * channel, it does not call driver
                                         * level functions to avoid referring
                                         * to deallocated data. */
#define CHANNEL_GETS_BLOCKED	(1<<14)	/* The last input operation was a gets




					 * that failed to get a comlete line.
					 * When set, file events will not be
					 * delivered for buffered data unless
					 * an EOL is present. */

/*
 * For each channel handler registered in a call to Tcl_CreateChannelHandler,
 * there is one record of the following type. All of records for a specific
 * channel are chained together in a singly linked list which is stored in
 * the channel structure.
 */







>
>
>







|
>
>
>
>
|

|
|







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
#define CHANNEL_BLOCKED	(1<<11)	/* EWOULDBLOCK or EAGAIN occurred
					 * on this channel. This bit is
                                         * cleared before every input or
                                         * output operation. */
#define INPUT_SAW_CR		(1<<12)	/* Channel is in CRLF eol input
					 * translation mode and the last
                                         * byte seen was a "\r". */
#define INPUT_NEED_NL		(1<<15)	/* Saw a '\r' at end of last buffer,
					 * and there should be a '\n' at
					 * beginning of next buffer. */
#define CHANNEL_DEAD		(1<<13)	/* The channel has been closed by
					 * the exit handler (on exit) but
                                         * not deallocated. When any IO
                                         * operation sees this flag on a
                                         * channel, it does not call driver
                                         * level functions to avoid referring
                                         * to deallocated data. */
#define CHANNEL_NEED_MORE_DATA	(1<<14)	/* The last input operation failed
					 * because there was not enough data
					 * to complete the operation.  This
					 * flag is set when gets fails to
					 * get a complete line or when read
					 * fails to get a complete character.
					 * When set, file events will not be
					 * delivered for buffered data until
					 * the state of the channel changes. */

/*
 * For each channel handler registered in a call to Tcl_CreateChannelHandler,
 * there is one record of the following type. All of records for a specific
 * channel are chained together in a singly linked list which is stored in
 * the channel structure.
 */
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295



296
































297
298



























299
300
301
302
303
304
305





306
307
308
309

310
311
312
313






314
315
316
317
318
319
320

321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340


341
342
343
344
345

346
347
348
349
350
351
352
353
354
355
356






357




358



















































359

360





































361
362
363
364
365
366
367
368


369
370
371
372
373
374
375




376
377
378
379
380
381
382
383




384

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
    ChannelHandler *nextHandlerPtr;	/* The next handler to be invoked in
                                         * this invocation. */
    struct NextChannelHandler *nestedHandlerPtr;
					/* Next nested invocation of
                                         * ChannelHandlerEventProc. */
} NextChannelHandler;

/*
 * This variable holds the list of nested ChannelHandlerEventProc invocations.
 */

static NextChannelHandler *nestedHandlerPtr = (NextChannelHandler *) NULL;

/*
 * List of all channels currently open.
 */

static Channel *firstChanPtr = (Channel *) NULL;

/*
 * Has a channel exit handler been created yet?
 */

static int channelExitHandlerCreated = 0;

/*
 * The following structure describes the event that is added to the Tcl
 * event queue by the channel handler check procedure.
 */

typedef struct ChannelHandlerEvent {
    Tcl_Event header;		/* Standard header for all events. */
    Channel *chanPtr;		/* The channel that is ready. */
    int readyMask;		/* Events that have occurred. */
} ChannelHandlerEvent;

/*



 * Static variables to hold channels for stdin, stdout and stderr.
































 */




























static Tcl_Channel stdinChannel = NULL;
static int stdinInitialized = 0;
static Tcl_Channel stdoutChannel = NULL;
static int stdoutInitialized = 0;
static Tcl_Channel stderrChannel = NULL;
static int stderrInitialized = 0;






/*
 * Static functions in this file:
 */


static void		ChannelEventScriptInvoker _ANSI_ARGS_((
			    ClientData clientData, int flags));
static void		ChannelTimerProc _ANSI_ARGS_((
			    ClientData clientData));






static void		CheckForStdChannelsBeingClosed _ANSI_ARGS_((
			    Tcl_Channel chan));
static void		CleanupChannelHandlers _ANSI_ARGS_((
			    Tcl_Interp *interp, Channel *chanPtr));
static int		CloseChannel _ANSI_ARGS_((Tcl_Interp *interp,
                            Channel *chanPtr, int errorCode));
static void		CloseChannelsOnExit _ANSI_ARGS_((ClientData data));

static int		CopyAndTranslateBuffer _ANSI_ARGS_((
			    Channel *chanPtr, char *result, int space));
static int		CopyData _ANSI_ARGS_((CopyState *csPtr, int mask));
static void		CopyEventProc _ANSI_ARGS_((ClientData clientData,
			    int mask));
static void		CreateScriptRecord _ANSI_ARGS_((
			    Tcl_Interp *interp, Channel *chanPtr,
                            int mask, char *script));
static void		DeleteChannelTable _ANSI_ARGS_((
			    ClientData clientData, Tcl_Interp *interp));
static void		DeleteScriptRecord _ANSI_ARGS_((Tcl_Interp *interp,
        		    Channel *chanPtr, int mask));
static void		DiscardInputQueued _ANSI_ARGS_((
			    Channel *chanPtr, int discardSavedBuffers));
static void		DiscardOutputQueued _ANSI_ARGS_((
    			    Channel *chanPtr));
static int		DoRead _ANSI_ARGS_((Channel *chanPtr, char *srcPtr,
			    int slen));
static int		DoWrite _ANSI_ARGS_((Channel *chanPtr, char *srcPtr,
			    int slen));


static int		FlushChannel _ANSI_ARGS_((Tcl_Interp *interp,
                            Channel *chanPtr, int calledFromAsyncFlush));
static Tcl_HashTable	*GetChannelTable _ANSI_ARGS_((Tcl_Interp *interp));
static int		GetEOL _ANSI_ARGS_((Channel *chanPtr));
static int		GetInput _ANSI_ARGS_((Channel *chanPtr));

static void		RecycleBuffer _ANSI_ARGS_((Channel *chanPtr,
		            ChannelBuffer *bufPtr, int mustDiscard));
static int		ScanBufferForEOL _ANSI_ARGS_((Channel *chanPtr,
                            ChannelBuffer *bufPtr,
                            Tcl_EolTranslation translation, int eofChar,
		            int *bytesToEOLPtr, int *crSeenPtr));
static int		ScanInputForEOL _ANSI_ARGS_((Channel *chanPtr,
		            int *bytesQueuedPtr));
static int		SetBlockMode _ANSI_ARGS_((Tcl_Interp *interp,
		            Channel *chanPtr, int mode));
static void		StopCopy _ANSI_ARGS_((CopyState *csPtr));






static void		UpdateInterest _ANSI_ARGS_((Channel *chanPtr));




static int		CheckForDeadChannel _ANSI_ARGS_((Tcl_Interp *interp,



















































							Channel *chan));







































/*
 *----------------------------------------------------------------------
 *
 * SetBlockMode --
 *
 *	This function sets the blocking mode for a channel and updates
 *	the state flags.
 *


 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Modifies the blocking mode of the channel and possibly generates
 *	an error.
 *




 *----------------------------------------------------------------------
 */

static int
SetBlockMode(interp, chanPtr, mode)
    Tcl_Interp *interp;		/* Interp for error reporting. */
    Channel *chanPtr;		/* Channel to modify. */
    int mode;			/* One of TCL_MODE_BLOCKING or




				 * TCL_MODE_NONBLOCKING. */

{
    int result = 0;
    if (chanPtr->typePtr->blockModeProc != NULL) {
	result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData,
		mode);
    }
    if (result != 0) {
	Tcl_SetErrno(result);
	if (interp != (Tcl_Interp *) NULL) {
	    Tcl_AppendResult(interp, "error setting blocking mode: ",
		    Tcl_PosixError(interp), (char *) NULL);
	}
	return TCL_ERROR;
    }
    if (mode == TCL_MODE_BLOCKING) {
	chanPtr->flags &= (~(CHANNEL_NONBLOCKING | BG_FLUSH_SCHEDULED));
    } else {
	chanPtr->flags |= CHANNEL_NONBLOCKING;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetStdChannel --
 *
 *	This function is used to change the channels that are used







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













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


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

>
>
>
>
>




>




>
>
>
>
>
>






|
>







|










|
|
>
>


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



>
>
>
>
>
>

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







299
300
301
302
303
304
305

















306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449

450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

563
564

565
566
567
568

569



570
571
572
573
574
575
576
577




578
579
580
581
582
583
584
585

586
587

588





589

590




591

592
593
594
595
596
597
598
599
    ChannelHandler *nextHandlerPtr;	/* The next handler to be invoked in
                                         * this invocation. */
    struct NextChannelHandler *nestedHandlerPtr;
					/* Next nested invocation of
                                         * ChannelHandlerEventProc. */
} NextChannelHandler;



















/*
 * The following structure describes the event that is added to the Tcl
 * event queue by the channel handler check procedure.
 */

typedef struct ChannelHandlerEvent {
    Tcl_Event header;		/* Standard header for all events. */
    Channel *chanPtr;		/* The channel that is ready. */
    int readyMask;		/* Events that have occurred. */
} ChannelHandlerEvent;

/*
 * The following structure is used by Tcl_GetsObj() to encapsulates the
 * state for a "gets" operation.
 */
 
typedef struct GetsState {
    Tcl_Obj *objPtr;		/* The object to which UTF-8 characters
				 * will be appended. */
    char **dstPtr;		/* Pointer into objPtr's string rep where
				 * next character should be stored. */
    Tcl_Encoding encoding;	/* The encoding to use to convert raw bytes
				 * to UTF-8.  */
    ChannelBuffer *bufPtr;	/* The current buffer of raw bytes being
				 * emptied. */
    Tcl_EncodingState state;	/* The encoding state just before the last
				 * external to UTF-8 conversion in
				 * FilterInputBytes(). */
    int rawRead;		/* The number of bytes removed from bufPtr
				 * in the last call to FilterInputBytes(). */
    int bytesWrote;		/* The number of bytes of UTF-8 data
				 * appended to objPtr during the last call to
				 * FilterInputBytes(). */
    int charsWrote;		/* The corresponding number of UTF-8
				 * characters appended to objPtr during the
				 * last call to FilterInputBytes(). */
    int totalChars;		/* The total number of UTF-8 characters
				 * appended to objPtr so far, just before the
				 * last call to FilterInputBytes(). */
} GetsState;

/*
 * All static variables used in this file are collected into a single
 * instance of the following structure.  For multi-threaded implementations,
 * there is one instance of this structure for each thread.
 *
 * Notice that different structures with the same name appear in other
 * files.  The structure defined below is used in this file only.
 */

typedef struct ThreadSpecificData {

    /*
     * This variable holds the list of nested ChannelHandlerEventProc 
     * invocations.
     */
    NextChannelHandler *nestedHandlerPtr;

    /*
     * List of all channels currently open.
     */
    Channel *firstChanPtr;
#ifdef oldcode
    /*
     * Has a channel exit handler been created yet?
     */
    int channelExitHandlerCreated;

    /*
     * Has the channel event source been created and registered with the
     * notifier?
     */
    int channelEventSourceCreated;
#endif
    /*
     * Static variables to hold channels for stdin, stdout and stderr.
     */
    Tcl_Channel stdinChannel;
    int stdinInitialized;
    Tcl_Channel stdoutChannel;
    int stdoutInitialized;
    Tcl_Channel stderrChannel;
    int stderrInitialized;

} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;


/*
 * Static functions in this file:
 */

static ChannelBuffer *	AllocChannelBuffer _ANSI_ARGS_((int length));
static void		ChannelEventScriptInvoker _ANSI_ARGS_((
			    ClientData clientData, int flags));
static void		ChannelTimerProc _ANSI_ARGS_((
			    ClientData clientData));
static int		CheckChannelErrors _ANSI_ARGS_((Channel *chanPtr,
			    int direction));
static int		CheckFlush _ANSI_ARGS_((Channel *chanPtr,
			    ChannelBuffer *bufPtr, int newlineFlag));
static int		CheckForDeadChannel _ANSI_ARGS_((Tcl_Interp *interp,
			    Channel *chan));
static void		CheckForStdChannelsBeingClosed _ANSI_ARGS_((
			    Tcl_Channel chan));
static void		CleanupChannelHandlers _ANSI_ARGS_((
			    Tcl_Interp *interp, Channel *chanPtr));
static int		CloseChannel _ANSI_ARGS_((Tcl_Interp *interp,
                            Channel *chanPtr, int errorCode));
static void		CommonGetsCleanup _ANSI_ARGS_((Channel *chanPtr,
			    Tcl_Encoding encoding));
static int		CopyAndTranslateBuffer _ANSI_ARGS_((
			    Channel *chanPtr, char *result, int space));
static int		CopyData _ANSI_ARGS_((CopyState *csPtr, int mask));
static void		CopyEventProc _ANSI_ARGS_((ClientData clientData,
			    int mask));
static void		CreateScriptRecord _ANSI_ARGS_((
			    Tcl_Interp *interp, Channel *chanPtr,
                            int mask, Tcl_Obj *scriptPtr));
static void		DeleteChannelTable _ANSI_ARGS_((
			    ClientData clientData, Tcl_Interp *interp));
static void		DeleteScriptRecord _ANSI_ARGS_((Tcl_Interp *interp,
        		    Channel *chanPtr, int mask));
static void		DiscardInputQueued _ANSI_ARGS_((
			    Channel *chanPtr, int discardSavedBuffers));
static void		DiscardOutputQueued _ANSI_ARGS_((
    			    Channel *chanPtr));
static int		DoRead _ANSI_ARGS_((Channel *chanPtr, char *srcPtr,
			    int slen));
static int		DoWrite _ANSI_ARGS_((Channel *chanPtr, char *src,
			    int srcLen));
static int		FilterInputBytes _ANSI_ARGS_((Channel *chanPtr,
			    GetsState *statePtr));
static int		FlushChannel _ANSI_ARGS_((Tcl_Interp *interp,
                            Channel *chanPtr, int calledFromAsyncFlush));
static Tcl_HashTable *	GetChannelTable _ANSI_ARGS_((Tcl_Interp *interp));
static int		GetInput _ANSI_ARGS_((Channel *chanPtr));
static void		PeekAhead _ANSI_ARGS_((Channel *chanPtr,
			    char **dstEndPtr, GetsState *gsPtr));
static int		ReadBytes _ANSI_ARGS_((Channel *chanPtr,
			    Tcl_Obj *objPtr, int charsLeft, int *offsetPtr));
static int		ReadChars _ANSI_ARGS_((Channel *chanPtr,

			    Tcl_Obj *objPtr, int charsLeft, int *offsetPtr,
			    int *factorPtr));
static void		RecycleBuffer _ANSI_ARGS_((Channel *chanPtr,
		            ChannelBuffer *bufPtr, int mustDiscard));
static int		SetBlockMode _ANSI_ARGS_((Tcl_Interp *interp,
		            Channel *chanPtr, int mode));
static void		StopCopy _ANSI_ARGS_((CopyState *csPtr));
static int		TranslateInputEOL _ANSI_ARGS_((Channel *chanPtr,
			    char *dst, CONST char *src, int *dstLenPtr,
			    int *srcLenPtr));
static int		TranslateOutputEOL _ANSI_ARGS_((Channel *chanPtr,
			    char *dst, CONST char *src, int *dstLenPtr,
			    int *srcLenPtr));
static void		UpdateInterest _ANSI_ARGS_((Channel *chanPtr));
static int		WriteBytes _ANSI_ARGS_((Channel *chanPtr,
			    CONST char *src, int srcLen));
static int		WriteChars _ANSI_ARGS_((Channel *chanPtr,
			    CONST char *src, int srcLen));


/*
 *---------------------------------------------------------------------------
 *
 * TclInitIOSubsystem --
 *
 *	Initialize all resources used by this subsystem on a per-process
 *	basis.  
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Depends on the memory subsystems.
 *
 *---------------------------------------------------------------------------
 */

void
TclInitIOSubsystem()
{
    /*
     * By fetching thread local storage we take care of
     * allocating it for each thread.
     */
    (void) TCL_TSD_INIT(&dataKey);
}   

/*
 *-------------------------------------------------------------------------
 *
 * TclFinalizeIOSubsystem --
 *
 *	Releases all resources used by this subsystem on a per-process 
 *	basis.  Closes all extant channels that have not already been 
 *	closed because they were not owned by any interp.  
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Depends on encoding and memory subsystems.
 *
 *-------------------------------------------------------------------------
 */

	/* ARGSUSED */
void
TclFinalizeIOSubsystem()
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    Channel *chanPtr;			/* Iterates over open channels. */
    Channel *nextChanPtr;		/* Iterates over open channels. */


    for (chanPtr = tsdPtr->firstChanPtr; chanPtr != (Channel *) NULL;
             chanPtr = nextChanPtr) {
        nextChanPtr = chanPtr->nextChanPtr;

        /*
         * Set the channel back into blocking mode to ensure that we wait
         * for all data to flush out.
         */
        
        (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr,
                "-blocking", "on");

        if ((chanPtr == (Channel *) tsdPtr->stdinChannel) ||
                (chanPtr == (Channel *) tsdPtr->stdoutChannel) ||
                (chanPtr == (Channel *) tsdPtr->stderrChannel)) {

            /*
             * Decrement the refcount which was earlier artificially bumped
             * up to keep the channel from being closed.
             */

            chanPtr->refCount--;
        }

        if (chanPtr->refCount <= 0) {

	    /*
             * Close it only if the refcount indicates that the channel is not
             * referenced from any interpreter. If it is, that interpreter will
             * close the channel when it gets destroyed.
             */

            (void) Tcl_Close((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);

        } else {

            /*
             * The refcount is greater than zero, so flush the channel.
             */


            Tcl_Flush((Tcl_Channel) chanPtr);


            /*
             * Call the device driver to actually close the underlying
             * device for this channel.

             */



            
	    if (chanPtr->typePtr->closeProc != TCL_CLOSE2PROC) {
		(chanPtr->typePtr->closeProc)(chanPtr->instanceData,
			(Tcl_Interp *) NULL);
	    } else {
		(chanPtr->typePtr->close2Proc)(chanPtr->instanceData,
			(Tcl_Interp *) NULL, 0);
	    }





            /*
             * Finally, we clean up the fields in the channel data structure
             * since all of them have been deleted already. We mark the
             * channel with CHANNEL_DEAD to prevent any further IO operations
             * on it.
             */


            chanPtr->instanceData = (ClientData) NULL;
            chanPtr->flags |= CHANNEL_DEAD;

        }





    }

}








/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetStdChannel --
 *
 *	This function is used to change the channels that are used
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
 */

void
Tcl_SetStdChannel(channel, type)
    Tcl_Channel channel;
    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{

    switch (type) {
	case TCL_STDIN:
            stdinInitialized = 1;
	    stdinChannel = channel;
	    break;
	case TCL_STDOUT:
	    stdoutInitialized = 1;
	    stdoutChannel = channel;
	    break;
	case TCL_STDERR:
	    stderrInitialized = 1;
	    stderrChannel = channel;
	    break;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetStdChannel --
 *
 *	Returns the specified standard channel.
 *
 * Results:
 *	Returns the specified standard channel, or NULL.
 *
 * Side effects:
 *	May cause the creation of a standard channel and the underlying
 *	file.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_GetStdChannel(type)
    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{
    Tcl_Channel channel = NULL;


    /*
     * If the channels were not created yet, create them now and
     * store them in the static variables.  Note that we need to set
     * stdinInitialized before calling TclGetDefaultStdChannel in order
     * to avoid recursive loops when TclGetDefaultStdChannel calls
     * Tcl_CreateChannel.
     */

    switch (type) {
	case TCL_STDIN:
	    if (!stdinInitialized) {
		stdinChannel = TclGetDefaultStdChannel(TCL_STDIN);
		stdinInitialized = 1;

                /*
                 * Artificially bump the refcount to ensure that the channel
                 * is only closed on exit.
                 *
                 * NOTE: Must only do this if stdinChannel is not NULL. It
                 * can be NULL in situations where Tcl is unable to connect
                 * to the standard input.
                 */

                if (stdinChannel != (Tcl_Channel) NULL) {
                    (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,
                            stdinChannel);
                }
	    }
	    channel = stdinChannel;
	    break;
	case TCL_STDOUT:
	    if (!stdoutInitialized) {
		stdoutChannel = TclGetDefaultStdChannel(TCL_STDOUT);
		stdoutInitialized = 1;

                /*
                 * Artificially bump the refcount to ensure that the channel
                 * is only closed on exit.
                 *
                 * NOTE: Must only do this if stdoutChannel is not NULL. It
                 * can be NULL in situations where Tcl is unable to connect
                 * to the standard output.
                 */

                if (stdoutChannel != (Tcl_Channel) NULL) {
                    (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,
                            stdoutChannel);
                }
	    }
	    channel = stdoutChannel;
	    break;
	case TCL_STDERR:
	    if (!stderrInitialized) {
		stderrChannel = TclGetDefaultStdChannel(TCL_STDERR);
		stderrInitialized = 1;

                /*
                 * Artificially bump the refcount to ensure that the channel
                 * is only closed on exit.
                 *
                 * NOTE: Must only do this if stderrChannel is not NULL. It
                 * can be NULL in situations where Tcl is unable to connect
                 * to the standard error.
                 */

                if (stderrChannel != (Tcl_Channel) NULL) {
                    (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,
                            stderrChannel);
                }
	    }
	    channel = stderrChannel;
	    break;
    }
    return channel;
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateCloseHandler
 *
 *	Creates a close callback which will be called when the channel is







>


|
|


|
|


|
|




















<





>



|
<
<
<




|
|
|

|








|

|


|


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

|


|


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

|


|




>







609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656
657
658



659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686










687
688
689
690
691
692
693
694
695
696
697










698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
 */

void
Tcl_SetStdChannel(channel, type)
    Tcl_Channel channel;
    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    switch (type) {
	case TCL_STDIN:
	    tsdPtr->stdinInitialized = 1;
	    tsdPtr->stdinChannel = channel;
	    break;
	case TCL_STDOUT:
	    tsdPtr->stdoutInitialized = 1;
	    tsdPtr->stdoutChannel = channel;
	    break;
	case TCL_STDERR:
	    tsdPtr->stderrInitialized = 1;
	    tsdPtr->stderrChannel = channel;
	    break;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetStdChannel --
 *
 *	Returns the specified standard channel.
 *
 * Results:
 *	Returns the specified standard channel, or NULL.
 *
 * Side effects:
 *	May cause the creation of a standard channel and the underlying
 *	file.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_GetStdChannel(type)
    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{
    Tcl_Channel channel = NULL;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * If the channels were not created yet, create them now and
     * store them in the static variables. 



     */

    switch (type) {
	case TCL_STDIN:
	    if (!tsdPtr->stdinInitialized) {
		tsdPtr->stdinChannel = TclpGetDefaultStdChannel(TCL_STDIN);
		tsdPtr->stdinInitialized = 1;

		/*
                 * Artificially bump the refcount to ensure that the channel
                 * is only closed on exit.
                 *
                 * NOTE: Must only do this if stdinChannel is not NULL. It
                 * can be NULL in situations where Tcl is unable to connect
                 * to the standard input.
                 */

                if (tsdPtr->stdinChannel != (Tcl_Channel) NULL) {
                    (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,
                            tsdPtr->stdinChannel);
                }
	    }
	    channel = tsdPtr->stdinChannel;
	    break;
	case TCL_STDOUT:
	    if (!tsdPtr->stdoutInitialized) {
		tsdPtr->stdoutChannel = TclpGetDefaultStdChannel(TCL_STDOUT);
		tsdPtr->stdoutInitialized = 1;










                if (tsdPtr->stdoutChannel != (Tcl_Channel) NULL) {
                    (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,
                            tsdPtr->stdoutChannel);
                }
	    }
	    channel = tsdPtr->stdoutChannel;
	    break;
	case TCL_STDERR:
	    if (!tsdPtr->stderrInitialized) {
		tsdPtr->stderrChannel = TclpGetDefaultStdChannel(TCL_STDERR);
		tsdPtr->stderrInitialized = 1;










                if (tsdPtr->stderrChannel != (Tcl_Channel) NULL) {
                    (void) Tcl_RegisterChannel((Tcl_Interp *) NULL,
                            tsdPtr->stderrChannel);
                }
	    }
	    channel = tsdPtr->stderrChannel;
	    break;
    }
    return channel;
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateCloseHandler
 *
 *	Creates a close callback which will be called when the channel is
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
            ckfree((char *) cbPtr);
            break;
        } else {
            cbPrevPtr = cbPtr;
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * CloseChannelsOnExit --
 *
 *	Closes all the existing channels, on exit. This	routine is called
 *	during exit processing.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Closes all channels.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static void
CloseChannelsOnExit(clientData)
    ClientData clientData;		/* NULL - unused. */
{
    Channel *chanPtr;			/* Iterates over open channels. */
    Channel *nextChanPtr;		/* Iterates over open channels. */


    for (chanPtr = firstChanPtr; chanPtr != (Channel *) NULL;
             chanPtr = nextChanPtr) {
        nextChanPtr = chanPtr->nextChanPtr;

        /*
         * Set the channel back into blocking mode to ensure that we wait
         * for all data to flush out.
         */
        
        (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr,
                "-blocking", "on");

        if ((chanPtr == (Channel *) stdinChannel) ||
                (chanPtr == (Channel *) stdoutChannel) ||
                (chanPtr == (Channel *) stderrChannel)) {

            /*
             * Decrement the refcount which was earlier artificially bumped
             * up to keep the channel from being closed.
             */

            chanPtr->refCount--;
        }

        if (chanPtr->refCount <= 0) {

	    /*
             * Close it only if the refcount indicates that the channel is not
             * referenced from any interpreter. If it is, that interpreter will
             * close the channel when it gets destroyed.
             */

            (void) Tcl_Close((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);

        } else {

            /*
             * The refcount is greater than zero, so flush the channel.
             */

            Tcl_Flush((Tcl_Channel) chanPtr);

            /*
             * Call the device driver to actually close the underlying
             * device for this channel.
             */
            
            (chanPtr->typePtr->closeProc) (chanPtr->instanceData,
                    (Tcl_Interp *) NULL);

            /*
             * Finally, we clean up the fields in the channel data structure
             * since all of them have been deleted already. We mark the
             * channel with CHANNEL_DEAD to prevent any further IO operations
             * on it.
             */

            chanPtr->instanceData = (ClientData) NULL;
            chanPtr->flags |= CHANNEL_DEAD;
        }
    }

    /*
     * Reinitialize all the variables to the initial state:
     */
    
    firstChanPtr = (Channel *) NULL;
    nestedHandlerPtr = (NextChannelHandler *) NULL;
    channelExitHandlerCreated = 0;
    stdinChannel = NULL;
    stdinInitialized = 0;
    stdoutChannel = NULL;
    stdoutInitialized = 0;
    stderrChannel = NULL;
    stderrInitialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * GetChannelTable --
 *
 *	Gets and potentially initializes the channel table for an







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







789
790
791
792
793
794
795







































































































796
797
798
799
800
801
802
            ckfree((char *) cbPtr);
            break;
        } else {
            cbPrevPtr = cbPtr;
        }
    }
}








































































































/*
 *----------------------------------------------------------------------
 *
 * GetChannelTable --
 *
 *	Gets and potentially initializes the channel table for an
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
                } else {
                    prevPtr->nextPtr = nextPtr;
                }

                Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
                        ChannelEventScriptInvoker, (ClientData) sPtr);

		ckfree(sPtr->script);
                ckfree((char *) sPtr);
            } else {
                prevPtr = sPtr;
            }
        }

        /*







|







917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
                } else {
                    prevPtr->nextPtr = nextPtr;
                }

                Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
                        ChannelEventScriptInvoker, (ClientData) sPtr);

		Tcl_DecrRefCount(sPtr->scriptPtr);
                ckfree((char *) sPtr);
            } else {
                prevPtr = sPtr;
            }
        }

        /*
907
908
909
910
911
912
913

914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
















































935
936
937
938
939
940
941
 */

static void
CheckForStdChannelsBeingClosed(chan)
    Tcl_Channel chan;
{
    Channel *chanPtr = (Channel *) chan;

    
    if ((chan == stdinChannel) && (stdinInitialized)) {
        if (chanPtr->refCount < 2) {
            chanPtr->refCount = 0;
            stdinChannel = NULL;
            return;
        }
    } else if ((chan == stdoutChannel) && (stdoutInitialized)) {
        if (chanPtr->refCount < 2) {
            chanPtr->refCount = 0;
            stdoutChannel = NULL;
            return;
        }
    } else if ((chan == stderrChannel) && (stderrInitialized)) {
        if (chanPtr->refCount < 2) {
            chanPtr->refCount = 0;
            stderrChannel = NULL;
            return;
        }
    }
}

















































/*
 *----------------------------------------------------------------------
 *
 * Tcl_UnregisterChannel --
 *
 *	Deletes the hash entry for a channel associated with an interpreter.







>
|
|


|


|


|


|


|




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







970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
 */

static void
CheckForStdChannelsBeingClosed(chan)
    Tcl_Channel chan;
{
    Channel *chanPtr = (Channel *) chan;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if ((chan == tsdPtr->stdinChannel) && (tsdPtr->stdinInitialized)) {
        if (chanPtr->refCount < 2) {
            chanPtr->refCount = 0;
            tsdPtr->stdinChannel = NULL;
            return;
        }
    } else if ((chan == tsdPtr->stdoutChannel) && (tsdPtr->stdoutInitialized)) {
        if (chanPtr->refCount < 2) {
            chanPtr->refCount = 0;
            tsdPtr->stdoutChannel = NULL;
            return;
        }
    } else if ((chan == tsdPtr->stderrChannel) && (tsdPtr->stderrInitialized)) {
        if (chanPtr->refCount < 2) {
            chanPtr->refCount = 0;
            tsdPtr->stderrChannel = NULL;
            return;
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegisterChannel --
 *
 *	Adds an already-open channel to the channel table of an interpreter.
 *	If the interpreter passed as argument is NULL, it only increments
 *	the channel refCount.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May increment the reference count of a channel.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_RegisterChannel(interp, chan)
    Tcl_Interp *interp;		/* Interpreter in which to add the channel. */
    Tcl_Channel chan;		/* The channel to add to this interpreter
                                 * channel table. */
{
    Tcl_HashTable *hTblPtr;	/* Hash table of channels. */
    Tcl_HashEntry *hPtr;	/* Search variable. */
    int new;			/* Is the hash entry new or does it exist? */
    Channel *chanPtr;		/* The actual channel. */

    chanPtr = (Channel *) chan;

    if (chanPtr->channelName == (char *) NULL) {
        panic("Tcl_RegisterChannel: channel without name");
    }
    if (interp != (Tcl_Interp *) NULL) {
        hTblPtr = GetChannelTable(interp);
        hPtr = Tcl_CreateHashEntry(hTblPtr, chanPtr->channelName, &new);
        if (new == 0) {
            if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) {
                return;
            }
            panic("Tcl_RegisterChannel: duplicate channel names");
        }
        Tcl_SetHashValue(hPtr, (ClientData) chanPtr);
    }
    chanPtr->refCount++;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UnregisterChannel --
 *
 *	Deletes the hash entry for a channel associated with an interpreter.
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
            }
        }
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegisterChannel --
 *
 *	Adds an already-open channel to the channel table of an interpreter.
 *	If the interpreter passed as argument is NULL, it only increments
 *	the channel refCount.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May increment the reference count of a channel.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_RegisterChannel(interp, chan)
    Tcl_Interp *interp;		/* Interpreter in which to add the channel. */
    Tcl_Channel chan;		/* The channel to add to this interpreter
                                 * channel table. */
{
    Tcl_HashTable *hTblPtr;	/* Hash table of channels. */
    Tcl_HashEntry *hPtr;	/* Search variable. */
    int new;			/* Is the hash entry new or does it exist? */
    Channel *chanPtr;		/* The actual channel. */

    chanPtr = (Channel *) chan;

    if (chanPtr->channelName == (char *) NULL) {
        panic("Tcl_RegisterChannel: channel without name");
    }
    if (interp != (Tcl_Interp *) NULL) {
        hTblPtr = GetChannelTable(interp);
        hPtr = Tcl_CreateHashEntry(hTblPtr, chanPtr->channelName, &new);
        if (new == 0) {
            if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) {
                return;
            }
            panic("Tcl_RegisterChannel: duplicate channel names");
        }
        Tcl_SetHashValue(hPtr, (ClientData) chanPtr);
    }
    chanPtr->refCount++;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetChannel --
 *
 *	Finds an existing Tcl_Channel structure by name in a given
 *	interpreter. This function is public because it is used by
 *	channel-type-specific functions.
 *
 * Results:
 *	A Tcl_Channel or NULL on failure. If failed, interp->result
 *	contains an error message. It also returns, in modePtr, the
 *	modes in which the channel is opened.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_GetChannel(interp, chanName, modePtr)
    Tcl_Interp *interp;		/* Interpreter in which to find or create
                                 * the channel. */
    char *chanName;		/* The name of the channel. */







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








|
|
|




|







1134
1135
1136
1137
1138
1139
1140
1141
















































1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
            }
        }
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
















































 *
 * Tcl_GetChannel --
 *
 *	Finds an existing Tcl_Channel structure by name in a given
 *	interpreter. This function is public because it is used by
 *	channel-type-specific functions.
 *
 * Results:
 *	A Tcl_Channel or NULL on failure. If failed, interp's result
 *	object contains an error message.  *modePtr is filled with the
 *	modes in which the channel was opened.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

Tcl_Channel
Tcl_GetChannel(interp, chanName, modePtr)
    Tcl_Interp *interp;		/* Interpreter in which to find or create
                                 * the channel. */
    char *chanName;		/* The name of the channel. */
1170
1171
1172
1173
1174
1175
1176


1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188














1189
1190
1191
1192
1193
1194
1195
    Tcl_ChannelType *typePtr;	/* The channel type record. */
    char *chanName;		/* Name of channel to record. */
    ClientData instanceData;	/* Instance specific data. */
    int mask;			/* TCL_READABLE & TCL_WRITABLE to indicate
                                 * if the channel is readable, writable. */
{
    Channel *chanPtr;		/* The channel structure newly created. */



    chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel));
    
    if (chanName != (char *) NULL) {
        chanPtr->channelName = ckalloc((unsigned) (strlen(chanName) + 1));
        strcpy(chanPtr->channelName, chanName);
    } else {
        panic("Tcl_CreateChannel: NULL channel name");
    }

    chanPtr->flags = mask;















    /*
     * Set the channel up initially in AUTO input translation mode to
     * accept "\n", "\r" and "\r\n". Output translation mode is set to
     * a platform specific default value. The eofChar is set to 0 for both
     * input and output, so that Tcl does not look for an in-file EOF
     * indicator (e.g. ^Z) and does not append an EOF indicator to files.
     */







>
>












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







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
    Tcl_ChannelType *typePtr;	/* The channel type record. */
    char *chanName;		/* Name of channel to record. */
    ClientData instanceData;	/* Instance specific data. */
    int mask;			/* TCL_READABLE & TCL_WRITABLE to indicate
                                 * if the channel is readable, writable. */
{
    Channel *chanPtr;		/* The channel structure newly created. */
    CONST char *name;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel));
    
    if (chanName != (char *) NULL) {
        chanPtr->channelName = ckalloc((unsigned) (strlen(chanName) + 1));
        strcpy(chanPtr->channelName, chanName);
    } else {
        panic("Tcl_CreateChannel: NULL channel name");
    }

    chanPtr->flags = mask;

    /*
     * Set the channel to system default encoding.
     */

    chanPtr->encoding = NULL;
    name = Tcl_GetEncodingName(NULL);
    if (strcmp(name, "binary") != 0) {
    	chanPtr->encoding = Tcl_GetEncoding(NULL, name);
    }
    chanPtr->inputEncodingState = NULL;
    chanPtr->inputEncodingFlags = TCL_ENCODING_START;
    chanPtr->outputEncodingState = NULL;
    chanPtr->outputEncodingFlags = TCL_ENCODING_START;

    /*
     * Set the channel up initially in AUTO input translation mode to
     * accept "\n", "\r" and "\r\n". Output translation mode is set to
     * a platform specific default value. The eofChar is set to 0 for both
     * input and output, so that Tcl does not look for an in-file EOF
     * indicator (e.g. ^Z) and does not append an EOF indicator to files.
     */
1212
1213
1214
1215
1216
1217
1218






1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
    chanPtr->inQueueTail = (ChannelBuffer *) NULL;
    chanPtr->chPtr = (ChannelHandler *) NULL;
    chanPtr->interestMask = 0;
    chanPtr->scriptRecordPtr = (EventScriptRecord *) NULL;
    chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE;
    chanPtr->timer = NULL;
    chanPtr->csPtr = NULL;







    /*
     * Link the channel into the list of all channels; create an on-exit
     * handler if there is not one already, to close off all the channels
     * in the list on exit.
     */

    chanPtr->nextChanPtr = firstChanPtr;
    firstChanPtr = chanPtr;

    if (!channelExitHandlerCreated) {
        channelExitHandlerCreated = 1;
        Tcl_CreateExitHandler(CloseChannelsOnExit, (ClientData) NULL);
    }
    
    /*
     * Install this channel in the first empty standard channel slot, if
     * the channel was previously closed explicitly.
     */

    if ((stdinChannel == NULL) && (stdinInitialized == 1)) {
	Tcl_SetStdChannel((Tcl_Channel)chanPtr, TCL_STDIN);
        Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);
    } else if ((stdoutChannel == NULL) && (stdoutInitialized == 1)) {
	Tcl_SetStdChannel((Tcl_Channel)chanPtr, TCL_STDOUT);
        Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);
    } else if ((stderrChannel == NULL) && (stderrInitialized == 1)) {
	Tcl_SetStdChannel((Tcl_Channel)chanPtr, TCL_STDERR);
        Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);
    } 
    return (Tcl_Channel) chanPtr;
}

/*







>
>
>
>
>
>







|
|

<
<
<
<
<





|


|


|







1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314





1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
    chanPtr->inQueueTail = (ChannelBuffer *) NULL;
    chanPtr->chPtr = (ChannelHandler *) NULL;
    chanPtr->interestMask = 0;
    chanPtr->scriptRecordPtr = (EventScriptRecord *) NULL;
    chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE;
    chanPtr->timer = NULL;
    chanPtr->csPtr = NULL;

    chanPtr->outputStage = NULL;
    if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) {
	chanPtr->outputStage = (char *)
		ckalloc((unsigned) (chanPtr->bufSize + 2));
    }

    /*
     * Link the channel into the list of all channels; create an on-exit
     * handler if there is not one already, to close off all the channels
     * in the list on exit.
     */

    chanPtr->nextChanPtr = tsdPtr->firstChanPtr;
    tsdPtr->firstChanPtr = chanPtr;






    /*
     * Install this channel in the first empty standard channel slot, if
     * the channel was previously closed explicitly.
     */

    if ((tsdPtr->stdinChannel == NULL) && (tsdPtr->stdinInitialized == 1)) {
	Tcl_SetStdChannel((Tcl_Channel)chanPtr, TCL_STDIN);
        Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);
    } else if ((tsdPtr->stdoutChannel == NULL) && (tsdPtr->stdoutInitialized == 1)) {
	Tcl_SetStdChannel((Tcl_Channel)chanPtr, TCL_STDOUT);
        Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);
    } else if ((tsdPtr->stderrChannel == NULL) && (tsdPtr->stderrInitialized == 1)) {
	Tcl_SetStdChannel((Tcl_Channel)chanPtr, TCL_STDERR);
        Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);
    } 
    return (Tcl_Channel) chanPtr;
}

/*
1388
1389
1390
1391
1392
1393
1394









































1395
1396
1397
1398
1399
1400
1401
    Tcl_Channel chan;		/* Channel for which to return client data. */
{
    Channel *chanPtr;		/* The actual channel. */

    chanPtr = (Channel *) chan;
    return chanPtr->instanceData;
}










































/*
 *----------------------------------------------------------------------
 *
 * RecycleBuffer --
 *
 *	Helper function to recycle input and output buffers. Ensures







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







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
    Tcl_Channel chan;		/* Channel for which to return client data. */
{
    Channel *chanPtr;		/* The actual channel. */

    chanPtr = (Channel *) chan;
    return chanPtr->instanceData;
}

/*
 *---------------------------------------------------------------------------
 *
 * AllocChannelBuffer --
 *
 *	A channel buffer has BUFFER_PADDING bytes extra at beginning to
 *	hold any bytes of a native-encoding character that got split by
 *	the end of the previous buffer and need to be moved to the
 *	beginning of the next buffer to make a contiguous string so it
 *	can be converted to UTF-8.
 *
 *	A channel buffer has BUFFER_PADDING bytes extra at the end to
 *	hold any bytes of a native-encoding character (generated from a
 *	UTF-8 character) that overflow past the end of the buffer and
 *	need to be moved to the next buffer.
 *
 * Results:
 *	A newly allocated channel buffer.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static ChannelBuffer *
AllocChannelBuffer(length)
    int length;			/* Desired length of channel buffer. */
{
    ChannelBuffer *bufPtr;
    int n;

    n = length + CHANNELBUFFER_HEADER_SIZE + BUFFER_PADDING + BUFFER_PADDING;
    bufPtr = (ChannelBuffer *) ckalloc((unsigned) n);
    bufPtr->nextAdded	= BUFFER_PADDING;
    bufPtr->nextRemoved	= BUFFER_PADDING;
    bufPtr->bufLength	= length + BUFFER_PADDING;
    bufPtr->nextPtr	= (ChannelBuffer *) NULL;
    return bufPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * RecycleBuffer --
 *
 *	Helper function to recycle input and output buffers. Ensures
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
     * If we reached this code we return the buffer to the OS.
     */

    ckfree((char *) bufPtr);
    return;

keepit:
    bufPtr->nextRemoved = 0;
    bufPtr->nextAdded = 0;
    bufPtr->nextPtr = (ChannelBuffer *) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * DiscardOutputQueued --







|
|







1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
     * If we reached this code we return the buffer to the OS.
     */

    ckfree((char *) bufPtr);
    return;

keepit:
    bufPtr->nextRemoved = BUFFER_PADDING;
    bufPtr->nextAdded = BUFFER_PADDING;
    bufPtr->nextPtr = (ChannelBuffer *) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * DiscardOutputQueued --
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574

1575
1576
1577
1578
1579
1580
1581
{
    ChannelBuffer *bufPtr;		/* Iterates over buffered output
                                         * queue. */
    int toWrite;			/* Amount of output data in current
                                         * buffer available to be written. */
    int written;			/* Amount of output data actually
                                         * written in current round. */
    int errorCode;			/* Stores POSIX error codes from
                                         * channel driver operations. */
    errorCode = 0;


    /*
     * Prevent writing on a dead channel -- a channel that has been closed
     * but not yet deallocated. This can occur if the exit handler for the
     * channel deallocation runs before all channels are deregistered in
     * all interpreters.
     */







|

|
>







1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
{
    ChannelBuffer *bufPtr;		/* Iterates over buffered output
                                         * queue. */
    int toWrite;			/* Amount of output data in current
                                         * buffer available to be written. */
    int written;			/* Amount of output data actually
                                         * written in current round. */
    int errorCode = 0;			/* Stores POSIX error codes from
                                         * channel driver operations. */
    int wroteSome = 0;			/* Set to one if any data was
					 * written to the driver. */

    /*
     * Prevent writing on a dead channel -- a channel that has been closed
     * but not yet deallocated. This can occur if the exit handler for the
     * channel deallocation runs before all channels are deregistered in
     * all interpreters.
     */
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
        /*
         * If the queue is empty and there is a ready current buffer, OR if
         * the current buffer is full, then move the current buffer to the
         * queue.
         */
        
        if (((chanPtr->curOutPtr != (ChannelBuffer *) NULL) &&
                (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->bufSize))
                || ((chanPtr->flags & BUFFER_READY) &&
                        (chanPtr->outQueueHead == (ChannelBuffer *) NULL))) {
            chanPtr->flags &= (~(BUFFER_READY));
            chanPtr->curOutPtr->nextPtr = (ChannelBuffer *) NULL;
            if (chanPtr->outQueueHead == (ChannelBuffer *) NULL) {
                chanPtr->outQueueHead = chanPtr->curOutPtr;
            } else {







|







1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
        /*
         * If the queue is empty and there is a ready current buffer, OR if
         * the current buffer is full, then move the current buffer to the
         * queue.
         */
        
        if (((chanPtr->curOutPtr != (ChannelBuffer *) NULL) &&
                (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->bufLength))
                || ((chanPtr->flags & BUFFER_READY) &&
                        (chanPtr->outQueueHead == (ChannelBuffer *) NULL))) {
            chanPtr->flags &= (~(BUFFER_READY));
            chanPtr->curOutPtr->nextPtr = (ChannelBuffer *) NULL;
            if (chanPtr->outQueueHead == (ChannelBuffer *) NULL) {
                chanPtr->outQueueHead = chanPtr->curOutPtr;
            } else {
1631
1632
1633
1634
1635
1636
1637
1638

1639
1640
1641
1642
1643
1644
1645

        /*
         * Produce the output on the channel.
         */
        
        toWrite = bufPtr->nextAdded - bufPtr->nextRemoved;
        written = (chanPtr->typePtr->outputProc) (chanPtr->instanceData,
                bufPtr->buf + bufPtr->nextRemoved, toWrite, &errorCode);

            
	/*
         * If the write failed completely attempt to start the asynchronous
         * flush mechanism and break out of this loop - do not attempt to
         * write any more output at this time.
         */








|
>







1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769

        /*
         * Produce the output on the channel.
         */
        
        toWrite = bufPtr->nextAdded - bufPtr->nextRemoved;
        written = (chanPtr->typePtr->outputProc) (chanPtr->instanceData,
                (char *) bufPtr->buf + bufPtr->nextRemoved, toWrite,
		&errorCode);
            
	/*
         * If the write failed completely attempt to start the asynchronous
         * flush mechanism and break out of this loop - do not attempt to
         * write any more output at this time.
         */

1691
1692
1693
1694
1695
1696
1697


1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716


1717
1718
1719
1720
1721



1722
1723
1724

1725
1726
1727
1728
1729
1730
1731
            /*
             * When we get an error we throw away all the output
             * currently queued.
             */

            DiscardOutputQueued(chanPtr);
            continue;


        }

        bufPtr->nextRemoved += written;

        /*
         * If this buffer is now empty, recycle it.
         */

        if (bufPtr->nextRemoved == bufPtr->nextAdded) {
            chanPtr->outQueueHead = bufPtr->nextPtr;
            if (chanPtr->outQueueHead == (ChannelBuffer *) NULL) {
                chanPtr->outQueueTail = (ChannelBuffer *) NULL;
            }
            RecycleBuffer(chanPtr, bufPtr, 0);
        }
    }	/* Closes "while (1)". */
    
    /*
     * If the queue became empty and we have the asynchronous flushing


     * mechanism active, cancel the asynchronous flushing.
     */

    if ((chanPtr->outQueueHead == (ChannelBuffer *) NULL) &&
            (chanPtr->flags & BG_FLUSH_SCHEDULED)) {



        chanPtr->flags &= (~(BG_FLUSH_SCHEDULED));
	(chanPtr->typePtr->watchProc)(chanPtr->instanceData,
		chanPtr->interestMask);

    }

    /*
     * If the channel is flagged as closed, delete it when the refCount
     * drops to zero, the output queue is empty and there is no output
     * in the current output buffer.
     */







>
>
|















|

|
>
>
|


<
|
>
>
>
|
|
|
>







1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847

1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
            /*
             * When we get an error we throw away all the output
             * currently queued.
             */

            DiscardOutputQueued(chanPtr);
            continue;
        } else {
	    wroteSome = 1;
	}

        bufPtr->nextRemoved += written;

        /*
         * If this buffer is now empty, recycle it.
         */

        if (bufPtr->nextRemoved == bufPtr->nextAdded) {
            chanPtr->outQueueHead = bufPtr->nextPtr;
            if (chanPtr->outQueueHead == (ChannelBuffer *) NULL) {
                chanPtr->outQueueTail = (ChannelBuffer *) NULL;
            }
            RecycleBuffer(chanPtr, bufPtr, 0);
        }
    }	/* Closes "while (1)". */

    /*
     * If we wrote some data while flushing in the background, we are done.
     * We can't finish the background flush until we run out of data and
     * the channel becomes writable again.  This ensures that all of the
     * pending data has been flushed at the system level.
     */


    if (chanPtr->flags & BG_FLUSH_SCHEDULED) {
	if (wroteSome) {
	    return errorCode;
	} else if (chanPtr->outQueueHead == (ChannelBuffer *) NULL) {
	    chanPtr->flags &= (~(BG_FLUSH_SCHEDULED));
	    (chanPtr->typePtr->watchProc)(chanPtr->instanceData,
		    chanPtr->interestMask);
	}
    }

    /*
     * If the channel is flagged as closed, delete it when the refCount
     * drops to zero, the output queue is empty and there is no output
     * in the current output buffer.
     */
1764
1765
1766
1767
1768
1769
1770

1771
1772
1773
1774
1775
1776
1777
1778
    int errorCode;			/* Status of operation so far. */
{
    int result = 0;			/* Of calling driver close
                                         * operation. */
    Channel *prevChanPtr;		/* Preceding channel in list of
                                         * all channels - used to splice a
                                         * channel out of the list on close. */

        
    if (chanPtr == NULL) {
        return result;
    }
    
    /*
     * No more input can be consumed so discard any leftover input.
     */







>
|







1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
    int errorCode;			/* Status of operation so far. */
{
    int result = 0;			/* Of calling driver close
                                         * operation. */
    Channel *prevChanPtr;		/* Preceding channel in list of
                                         * all channels - used to splice a
                                         * channel out of the list on close. */
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (chanPtr == NULL) {
        return result;
    }
    
    /*
     * No more input can be consumed so discard any leftover input.
     */
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845

1846




1847
1848
1849




1850
1851
1852
1853
1854
1855
1856

    chanPtr->flags &= (~(TCL_READABLE|TCL_WRITABLE));
        
    /*
     * Splice this channel out of the list of all channels.
     */

    if (chanPtr == firstChanPtr) {
        firstChanPtr = chanPtr->nextChanPtr;
    } else {
        for (prevChanPtr = firstChanPtr;
                 (prevChanPtr != (Channel *) NULL) &&
                     (prevChanPtr->nextChanPtr != chanPtr);
                 prevChanPtr = prevChanPtr->nextChanPtr) {
            /* Empty loop body. */
        }
        if (prevChanPtr == (Channel *) NULL) {
            panic("FlushChannel: damaged channel list");
        }
        prevChanPtr->nextChanPtr = chanPtr->nextChanPtr;
    }

    /*
     * OK, close the channel itself.
     */
        

    result = (chanPtr->typePtr->closeProc) (chanPtr->instanceData, interp);




    
    if (chanPtr->channelName != (char *) NULL) {
        ckfree(chanPtr->channelName);




    }
    
    /*
     * If we are being called synchronously, report either
     * any latent error on the channel or the current error.
     */
        







|
|

|












|

|
>
|
>
>
>
>



>
>
>
>







1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997

    chanPtr->flags &= (~(TCL_READABLE|TCL_WRITABLE));
        
    /*
     * Splice this channel out of the list of all channels.
     */

    if (chanPtr == tsdPtr->firstChanPtr) {
        tsdPtr->firstChanPtr = chanPtr->nextChanPtr;
    } else {
        for (prevChanPtr = tsdPtr->firstChanPtr;
                 (prevChanPtr != (Channel *) NULL) &&
                     (prevChanPtr->nextChanPtr != chanPtr);
                 prevChanPtr = prevChanPtr->nextChanPtr) {
            /* Empty loop body. */
        }
        if (prevChanPtr == (Channel *) NULL) {
            panic("FlushChannel: damaged channel list");
        }
        prevChanPtr->nextChanPtr = chanPtr->nextChanPtr;
    }

    /*
     * Close and free the channel driver state.
     */
            
    if (chanPtr->typePtr->closeProc != TCL_CLOSE2PROC) {
	result = (chanPtr->typePtr->closeProc)(chanPtr->instanceData, interp);
    } else {
	result = (chanPtr->typePtr->close2Proc)(chanPtr->instanceData, interp,
		0);
    }
    
    if (chanPtr->channelName != (char *) NULL) {
        ckfree(chanPtr->channelName);
    }
    Tcl_FreeEncoding(chanPtr->encoding);
    if (chanPtr->outputStage != NULL) {
	ckfree((char *) chanPtr->outputStage);
    }
    
    /*
     * If we are being called synchronously, report either
     * any latent error on the channel or the current error.
     */
        
1913
1914
1915
1916
1917
1918
1919

1920
1921
1922
1923
1924
1925
1926
{
    ChannelHandler *chPtr, *chNext;	/* Iterate over channel handlers. */
    CloseCallback *cbPtr;		/* Iterate over close callbacks
                                         * for this channel. */
    EventScriptRecord *ePtr, *eNextPtr;	/* Iterate over eventscript records. */
    Channel *chanPtr;			/* The real IO channel. */
    int result;				/* Of calling FlushChannel. */

    NextChannelHandler *nhPtr;

    if (chan == (Tcl_Channel) NULL) {
        return TCL_OK;
    }
    
    /*







>







2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
{
    ChannelHandler *chPtr, *chNext;	/* Iterate over channel handlers. */
    CloseCallback *cbPtr;		/* Iterate over close callbacks
                                         * for this channel. */
    EventScriptRecord *ePtr, *eNextPtr;	/* Iterate over eventscript records. */
    Channel *chanPtr;			/* The real IO channel. */
    int result;				/* Of calling FlushChannel. */
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    NextChannelHandler *nhPtr;

    if (chan == (Tcl_Channel) NULL) {
        return TCL_OK;
    }
    
    /*
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
    }

    /*
     * Remove any references to channel handlers for this channel that
     * may be about to be invoked.
     */

    for (nhPtr = nestedHandlerPtr;
             nhPtr != (NextChannelHandler *) NULL;
             nhPtr = nhPtr->nestedHandlerPtr) {
        if (nhPtr->nextHandlerPtr &&
		(nhPtr->nextHandlerPtr->chanPtr == chanPtr)) {
	    nhPtr->nextHandlerPtr = NULL;
        }
    }







|







2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
    }

    /*
     * Remove any references to channel handlers for this channel that
     * may be about to be invoked.
     */

    for (nhPtr = tsdPtr->nestedHandlerPtr;
             nhPtr != (NextChannelHandler *) NULL;
             nhPtr = nhPtr->nestedHandlerPtr) {
        if (nhPtr->nextHandlerPtr &&
		(nhPtr->nextHandlerPtr->chanPtr == chanPtr)) {
	    nhPtr->nextHandlerPtr = NULL;
        }
    }
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
     * Remove any EventScript records for this channel.
     */

    for (ePtr = chanPtr->scriptRecordPtr;
             ePtr != (EventScriptRecord *) NULL;
             ePtr = eNextPtr) {
        eNextPtr = ePtr->nextPtr;
	ckfree(ePtr->script);
        ckfree((char *) ePtr);
    }
    chanPtr->scriptRecordPtr = (EventScriptRecord *) NULL;
        
    /*
     * Invoke the registered close callbacks and delete their records.
     */







|







2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
     * Remove any EventScript records for this channel.
     */

    for (ePtr = chanPtr->scriptRecordPtr;
             ePtr != (EventScriptRecord *) NULL;
             ePtr = eNextPtr) {
        eNextPtr = ePtr->nextPtr;
	Tcl_DecrRefCount(ePtr->scriptPtr);
        ckfree((char *) ePtr);
    }
    chanPtr->scriptRecordPtr = (EventScriptRecord *) NULL;
        
    /*
     * Invoke the registered close callbacks and delete their records.
     */
2009
2010
2011
2012
2013
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
2057
2058
2059
2060



2061



2062
2063
2064


2065
2066

2067

2068
2069
2070
2071



2072
2073
2074
2075

2076
2077
2078
2079
2080
2081

2082

2083

2084
2085
2086
2087
2088

2089



2090
2091
2092


2093
2094
2095

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





2131





2132


2133

2134

2135


2136




2137
2138



2139


2140
2141





2142



2143


2144



2145



2146

2147
2148
2149


2150
2151






2152

2153

2154

2155
2156
2157
2158

2159


2160
2161
2162
2163




2164


2165
2166

















2167
2168
2169
2170

2171

2172


2173



2174
2175
2176
2177

2178
2179
2180
2181
2182

















2183
2184






2185
2186

2187
2188


2189

2190
2191
2192
2193
2194






2195
2196
2197
2198
2199
2200

2201








2202


2203
2204
2205
2206

2207
2208



2209

2210
2211









2212
2213
2214
2215

2216

2217
2218
2219



2220
2221
2222

2223
2224


2225


2226

2227

























2228

















2229














2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258


2259




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































2260










2261


















































































































































































































































































































































2262
2263
2264
2265
2266
2267
2268
     * Ensure that the last output buffer will be flushed.
     */
    
    if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) &&
           (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) {
        chanPtr->flags |= BUFFER_READY;
    }













    /*
     * The call to FlushChannel will flush any queued output and invoke
     * the close function of the channel driver, or it will set up the
     * channel to be flushed and closed asynchronously.
     */
    
    chanPtr->flags |= CHANNEL_CLOSED;
    result = FlushChannel(interp, chanPtr, 0);
    if (result != 0) {
        return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Write --
 *
 *	Puts a sequence of characters into an output buffer, may queue the















































































































































 *	buffer for output if it gets full, and also remembers whether the
 *	current buffer is ready e.g. if it contains a newline and we are in
 *	line buffering mode.
 *
 * Results:
 *	The number of bytes written or -1 in case of error. If -1,
 *	Tcl_GetErrno will return the error code.
 *
 * Side effects:
 *	May buffer up output and may cause output to be produced on the
 *	channel.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Write(chan, srcPtr, slen)
    Tcl_Channel chan;			/* The channel to buffer output for. */
    char *srcPtr;			/* Output to buffer. */
    int slen;				/* Its length. Negative means
                                         * the output is null terminated
                                         * and we must compute its length. */
{



    Channel *chanPtr = (Channel *) chan;




    /*
     * Check for unreported error.


     */


    if (chanPtr->unreportedError != 0) {

        Tcl_SetErrno(chanPtr->unreportedError);
        chanPtr->unreportedError = 0;
        return -1;
    }



    
    /*
     * If the channel is not open for writing punt.
     */


    if (!(chanPtr->flags & TCL_WRITABLE)) {
        Tcl_SetErrno(EACCES);
        return -1;
    }
    

    /*

     * If the channel is in the middle of a background copy, fail.

     */

    if (chanPtr->csPtr) {
	Tcl_SetErrno(EBUSY);
	return -1;

    }




    /*
     * If length passed is negative, assume that the output is null terminated


     * and compute its length.
     */
    

    if (slen < 0) {
        slen = strlen(srcPtr);
    }





    return DoWrite(chanPtr, srcPtr, slen);
}

/*
 *----------------------------------------------------------------------
 *
 * DoWrite --
 *

 *	Puts a sequence of characters into an output buffer, may queue the
 *	buffer for output if it gets full, and also remembers whether the
 *	current buffer is ready e.g. if it contains a newline and we are in
 *	line buffering mode.
 *
 * Results:
 *	The number of bytes written or -1 in case of error. If -1,
 *	Tcl_GetErrno will return the error code.
 *
 * Side effects:
 *	May buffer up output and may cause output to be produced on the
 *	channel.
 *
 *----------------------------------------------------------------------
 */

static int
DoWrite(chanPtr, srcPtr, slen)
    Channel *chanPtr;			/* The channel to buffer output for. */
    char *srcPtr;			/* Data to write. */
    int slen;				/* Number of bytes to write. */
{
    ChannelBuffer *outBufPtr;		/* Current output buffer. */





    int foundNewline;			/* Did we find a newline in output? */





    char *dPtr, *sPtr;			/* Search variables for newline. */


    int crsent;				/* In CRLF eol translation mode,

                                         * remember the fact that a CR was

                                         * output to the channel without


                                         * its following NL. */




    int i;				/* Loop index for newline search. */
    int destCopied;			/* How many bytes were used in this



                                         * destination buffer to hold the


                                         * output? */
    int totalDestCopied;		/* How many bytes total were





                                         * copied to the channel buffer? */



    int srcCopied;			/* How many bytes were copied from


                                         * the source string? */



    char *destPtr;			/* Where in line to copy to? */





    /*
     * If we are in network (or windows) translation mode, record the fact
     * that we have not yet sent a CR to the channel.


     */







    crsent = 0;

    

    /*

     * Loop filling buffers and flushing them until all output has been
     * consumed.
     */


    srcCopied = 0;


    totalDestCopied = 0;

    while (slen > 0) {
        




        /*


         * Make sure there is a current output buffer to accept output.
         */


















        if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) {
            chanPtr->curOutPtr = (ChannelBuffer *) ckalloc((unsigned)
                    (CHANNELBUFFER_HEADER_SIZE + chanPtr->bufSize));

            chanPtr->curOutPtr->nextAdded = 0;

            chanPtr->curOutPtr->nextRemoved = 0;


            chanPtr->curOutPtr->bufSize = chanPtr->bufSize;



            chanPtr->curOutPtr->nextPtr = (ChannelBuffer *) NULL;
        }

        outBufPtr = chanPtr->curOutPtr;


        destCopied = outBufPtr->bufSize - outBufPtr->nextAdded;
        if (destCopied > slen) {
            destCopied = slen;
        }

















        
        destPtr = outBufPtr->buf + outBufPtr->nextAdded;






        switch (chanPtr->outputTranslation) {
            case TCL_TRANSLATE_LF:

                srcCopied = destCopied;
                memcpy((VOID *) destPtr, (VOID *) srcPtr, (size_t) destCopied);


                break;

            case TCL_TRANSLATE_CR:
                srcCopied = destCopied;
                memcpy((VOID *) destPtr, (VOID *) srcPtr, (size_t) destCopied);
                for (dPtr = destPtr; dPtr < destPtr + destCopied; dPtr++) {
                    if (*dPtr == '\n') {






                        *dPtr = '\r';
                    }
                }
                break;
            case TCL_TRANSLATE_CRLF:
                for (srcCopied = 0, dPtr = destPtr, sPtr = srcPtr;

                     dPtr < destPtr + destCopied;








                     dPtr++, sPtr++, srcCopied++) {


                    if (*sPtr == '\n') {
                        if (crsent) {
                            *dPtr = '\n';
                            crsent = 0;

                        } else {
                            *dPtr = '\r';



                            crsent = 1;

                            sPtr--, srcCopied--;
                        }









                    } else {
                        *dPtr = *sPtr;
                    }
                }

                break;

            case TCL_TRANSLATE_AUTO:
                panic("Tcl_Write: AUTO output translation mode not supported");
            default:



                panic("Tcl_Write: unknown output translation mode");
        }


        /*
         * The current buffer is ready for output if it is full, or if it


         * contains a newline and this channel is line-buffered, or if it


         * contains any output and this channel is unbuffered.

         */











































        outBufPtr->nextAdded += destCopied;














        if (!(chanPtr->flags & BUFFER_READY)) {
            if (outBufPtr->nextAdded == outBufPtr->bufSize) {
                chanPtr->flags |= BUFFER_READY;
            } else if (chanPtr->flags & CHANNEL_LINEBUFFERED) {
                for (sPtr = srcPtr, i = 0, foundNewline = 0;
                         (i < srcCopied) && (!foundNewline);
                         i++, sPtr++) {
                    if (*sPtr == '\n') {
                        foundNewline = 1;
                        break;
                    }
                }
                if (foundNewline) {
                    chanPtr->flags |= BUFFER_READY;
                }
            } else if (chanPtr->flags & CHANNEL_UNBUFFERED) {
                chanPtr->flags |= BUFFER_READY;
            }
        }
        
        totalDestCopied += srcCopied;
        srcPtr += srcCopied;
        slen -= srcCopied;

        if (chanPtr->flags & BUFFER_READY) {
            if (FlushChannel(NULL, chanPtr, 0) != 0) {
                return -1;
            }
        }


    } /* Closes "while" */































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































    return totalDestCopied;


















































































































































































































































































































































}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Flush --
 *







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






|

|
<


<








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















|
|
|
|
|
<
<

>
>
>
|
>
>
>


<
>
>


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

|
<
|
>
|
>
>
>

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





|

>
|
















|
|
|
|

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

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

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







2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178

2179
2180

2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468

2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499


2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525

2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553


2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567

2568
2569



2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588

2589
2590
2591
2592
2593
2594
2595

2596
2597

2598
2599
2600
2601
2602




2603
2604
2605
2606
2607
2608
2609
2610

2611

2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656


2657
2658
2659
2660

2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734




2735




2736
2737
2738
2739
2740
2741





2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
     * Ensure that the last output buffer will be flushed.
     */
    
    if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) &&
           (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) {
        chanPtr->flags |= BUFFER_READY;
    }

    /*
     * If this channel supports it, close the read side, since we don't need it
     * anymore and this will help avoid deadlocks on some channel types.
     */

    if (chanPtr->typePtr->closeProc == TCL_CLOSE2PROC) {
	result = (chanPtr->typePtr->close2Proc)(chanPtr->instanceData, interp,
		TCL_CLOSE_READ);
    } else {
	result = 0;
    }

    /*
     * The call to FlushChannel will flush any queued output and invoke
     * the close function of the channel driver, or it will set up the
     * channel to be flushed and closed asynchronously.
     */

    chanPtr->flags |= CHANNEL_CLOSED;
    if ((FlushChannel(interp, chanPtr, 0) != 0) || (result != 0)) {

        return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Write --
 *
 *	Puts a sequence of bytes into an output buffer, may queue the
 *	buffer for output if it gets full, and also remembers whether the
 *	current buffer is ready e.g. if it contains a newline and we are in
 *	line buffering mode.
 *
 * Results:
 *	The number of bytes written or -1 in case of error. If -1,
 *	Tcl_GetErrno will return the error code.
 *
 * Side effects:
 *	May buffer up output and may cause output to be produced on the
 *	channel.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Write(chan, src, srcLen)
    Tcl_Channel chan;			/* The channel to buffer output for. */
    char *src;				/* Data to queue in output buffer. */
    int srcLen;				/* Length of data in bytes, or < 0 for
					 * strlen(). */
{
    Channel *chanPtr;

    chanPtr = (Channel *) chan;
    if (CheckChannelErrors(chanPtr, TCL_WRITABLE) != 0) {
	return -1;
    }
    if (srcLen < 0) {
        srcLen = strlen(src);
    }
    return DoWrite(chanPtr, src, srcLen);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_WriteChars --
 *
 *	Takes a sequence of UTF-8 characters and converts them for output
 *	using the channel's current encoding, may queue the buffer for
 *	output if it gets full, and also remembers whether the current
 *	buffer is ready e.g. if it contains a newline and we are in
 *	line buffering mode.
 *
 * Results:
 *	The number of bytes written or -1 in case of error. If -1,
 *	Tcl_GetErrno will return the error code.
 *
 * Side effects:
 *	May buffer up output and may cause output to be produced on the
 *	channel.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_WriteChars(chan, src, len)
    Tcl_Channel chan;		/* The channel to buffer output for. */
    CONST char *src;		/* UTF-8 characters to queue in output buffer. */
    int len;			/* Length of string in bytes, or < 0 for 
				 * strlen(). */
{
    Channel *chanPtr;

    chanPtr = (Channel *) chan;
    if (CheckChannelErrors(chanPtr, TCL_WRITABLE) != 0) {
	return -1;
    }
    if (len < 0) {
        len = strlen(src);
    }
    if (chanPtr->encoding == NULL) {
	/*
	 * Inefficient way to convert UTF-8 to byte-array, but the  
	 * code parallels the way it is done for objects.
	 */

	Tcl_Obj *objPtr;
	int result;

	objPtr = Tcl_NewStringObj(src, len);
	src = (char *) Tcl_GetByteArrayFromObj(objPtr, &len);
	result = WriteBytes(chanPtr, src, len);
	Tcl_DecrRefCount(objPtr);
	return result;
    }
    return WriteChars(chanPtr, src, len);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_WriteObj --
 *
 *	Takes the Tcl object and queues its contents for output.  If the 
 *	encoding of the channel is NULL, takes the byte-array representation 
 *	of the object and queues those bytes for output.  Otherwise, takes 
 *	the characters in the UTF-8 (string) representation of the object 
 *	and converts them for output using the channel's current encoding.  
 *	May flush internal buffers to output if one becomes full or is ready 
 *	for some other reason, e.g. if it contains a newline and the channel 
 *	is in line buffering mode.
 *
 * Results:
 *	The number of bytes written or -1 in case of error. If -1, 
 *	Tcl_GetErrno() will return the error code.
 *
 * Side effects:
 *	May buffer up output and may cause output to be produced on the
 *	channel.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_WriteObj(chan, objPtr)
    Tcl_Channel chan;		/* The channel to buffer output for. */
    Tcl_Obj *objPtr;		/* The object to write. */
{
    Channel *chanPtr;
    char *src;
    int srcLen;

    chanPtr = (Channel *) chan;
    if (CheckChannelErrors(chanPtr, TCL_WRITABLE) != 0) {
	return -1;
    }
    if (chanPtr->encoding == NULL) {
	src = (char *) Tcl_GetByteArrayFromObj(objPtr, &srcLen);
	return WriteBytes(chanPtr, src, srcLen);
    } else {
	src = Tcl_GetStringFromObj(objPtr, &srcLen);
	return WriteChars(chanPtr, src, srcLen);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * WriteBytes --
 *
 *	Write a sequence of bytes into an output buffer, may queue the
 *	buffer for output if it gets full, and also remembers whether the
 *	current buffer is ready e.g. if it contains a newline and we are in
 *	line buffering mode.
 *
 * Results:
 *	The number of bytes written or -1 in case of error. If -1,
 *	Tcl_GetErrno will return the error code.
 *
 * Side effects:
 *	May buffer up output and may cause output to be produced on the
 *	channel.
 *
 *----------------------------------------------------------------------
 */

static int
WriteBytes(chanPtr, src, srcLen)
    Channel *chanPtr;		/* The channel to buffer output for. */
    CONST char *src;		/* Bytes to write. */
    int srcLen;			/* Number of bytes to write. */


{
    ChannelBuffer *bufPtr;
    char *dst;
    int dstLen, dstMax, sawLF, savedLF, total, toWrite;
    
    total = 0;
    sawLF = 0;
    savedLF = 0;

    /*

     * Loop over all bytes in src, storing them in output buffer with
     * proper EOL translation.
     */

    while (srcLen + savedLF > 0) {
	bufPtr = chanPtr->curOutPtr;
	if (bufPtr == NULL) {
	    bufPtr = AllocChannelBuffer(chanPtr->bufSize);
	    chanPtr->curOutPtr	= bufPtr;

	}
	dst = bufPtr->buf + bufPtr->nextAdded;
	dstMax = bufPtr->bufLength - bufPtr->nextAdded;
	dstLen = dstMax;


	toWrite = dstLen;

	if (toWrite > srcLen) {
	    toWrite = srcLen;



	}

	if (savedLF) {
	    /*
	     * A '\n' was left over from last call to TranslateOutputEOL()
	     * and we need to store it in this buffer.  If the channel is
	     * line-based, we will need to flush it.
	     */

	    *dst++ = '\n';

	    dstLen--;
	    sawLF++;
	}
	sawLF += TranslateOutputEOL(chanPtr, dst, src, &dstLen, &toWrite);
	dstLen += savedLF;
	savedLF = 0;



	if (dstLen > dstMax) {
	    savedLF = 1;
	    dstLen = dstMax;

	}
	bufPtr->nextAdded += dstLen;
	if (CheckFlush(chanPtr, bufPtr, sawLF) != 0) {
	    return -1;
	}
	total += dstLen;
	src += toWrite;
	srcLen -= toWrite;
	sawLF = 0;
    }
    return total;
}

/*
 *----------------------------------------------------------------------
 *
 * WriteChars --
 *
 *	Convert UTF-8 bytes to the channel's external encoding and
 *	write the produced bytes into an output buffer, may queue the 
 *	buffer for output if it gets full, and also remembers whether the
 *	current buffer is ready e.g. if it contains a newline and we are in
 *	line buffering mode.
 *
 * Results:
 *	The number of bytes written or -1 in case of error. If -1,
 *	Tcl_GetErrno will return the error code.
 *
 * Side effects:
 *	May buffer up output and may cause output to be produced on the
 *	channel.
 *
 *----------------------------------------------------------------------
 */

static int
WriteChars(chanPtr, src, srcLen)
    Channel *chanPtr;		/* The channel to buffer output for. */
    CONST char *src;		/* UTF-8 string to write. */
    int srcLen;			/* Length of UTF-8 string in bytes. */
{
    ChannelBuffer *bufPtr;
    char *dst, *stage;
    int saved, savedLF, sawLF, total, toWrite, flags;
    int dstWrote, dstLen, stageLen, stageMax, stageRead;
    Tcl_Encoding encoding;
    char safe[BUFFER_PADDING];
    
    total = 0;
    sawLF = 0;
    savedLF = 0;
    saved = 0;
    encoding = chanPtr->encoding;

    /*
     * Loop over all UTF-8 characters in src, storing them in staging buffer
     * with proper EOL translation.
     */

    while (srcLen + savedLF > 0) {
	stage = chanPtr->outputStage;
	stageMax = chanPtr->bufSize;
	stageLen = stageMax;

	toWrite = stageLen;
	if (toWrite > srcLen) {
	    toWrite = srcLen;
	}


	if (savedLF) {
	    /*
	     * A '\n' was left over from last call to TranslateOutputEOL()
	     * and we need to store it in the staging buffer.  If the
	     * channel is line-based, we will need to flush the output
	     * buffer (after translating the staging buffer).
	     */
	    
	    *stage++ = '\n';
	    stageLen--;
	    sawLF++;
	}
	sawLF += TranslateOutputEOL(chanPtr, stage, src, &stageLen, &toWrite);

	stage -= savedLF;
	stageLen += savedLF;
	savedLF = 0;

	if (stageLen > stageMax) {
	    savedLF = 1;
	    stageLen = stageMax;
	}
	src += toWrite;
	srcLen -= toWrite;

	flags = chanPtr->outputEncodingFlags;
	if (srcLen == 0) {
	    flags |= TCL_ENCODING_END;
	}

	/*


	 * Loop over all UTF-8 characters in staging buffer, converting them
	 * to external encoding, storing them in output buffer.
	 */

	while (stageLen + saved > 0) {
	    bufPtr = chanPtr->curOutPtr;
	    if (bufPtr == NULL) {
		bufPtr = AllocChannelBuffer(chanPtr->bufSize);
		chanPtr->curOutPtr = bufPtr;
	    }
	    dst = bufPtr->buf + bufPtr->nextAdded;
	    dstLen = bufPtr->bufLength - bufPtr->nextAdded;

	    if (saved != 0) {
		/*
		 * Here's some translated bytes left over from the last
		 * buffer that we need to stick at the beginning of this
		 * buffer.
		 */
		 
		memcpy((VOID *) dst, (VOID *) safe, (size_t) saved);
		bufPtr->nextAdded += saved;
		dst += saved;
		dstLen -= saved;
		saved = 0;
	    }


	    Tcl_UtfToExternal(NULL, encoding, stage, stageLen, flags,
		    &chanPtr->outputEncodingState, dst,
		    dstLen + BUFFER_PADDING, &stageRead, &dstWrote, NULL);
	    if (stageRead + dstWrote == 0) {
		/*
		 * We have an incomplete UTF-8 character at the end of the
		 * staging buffer.  It will get moved to the beginning of the
		 * staging buffer followed by more bytes from src.
		 */

		src -= stageLen;
		srcLen += stageLen;
		stageLen = 0;
		savedLF = 0;
		break;
	    }
	    bufPtr->nextAdded += dstWrote;
	    if (bufPtr->nextAdded > bufPtr->bufLength) {
		/*
		 * When translating from UTF-8 to external encoding, we
		 * allowed the translation to produce a character that
		 * crossed the end of the output buffer, so that we would
		 * get a completely full buffer before flushing it.  The
		 * extra bytes will be moved to the beginning of the next
		 * buffer.
		 */



		saved = bufPtr->nextAdded - bufPtr->bufLength;
		memcpy((VOID *) safe, (VOID *) (dst + dstLen), (size_t) saved);
		bufPtr->nextAdded = bufPtr->bufLength;
	    }
	    if (CheckFlush(chanPtr, bufPtr, sawLF) != 0) {
		return -1;
	    }

	    total += dstWrote;
	    stage += stageRead;
	    stageLen -= stageRead;
	    sawLF = 0;
	}
    }

    return total;
}




/*
 *---------------------------------------------------------------------------
 *
 * TranslateOutputEOL --
 *
 *	Helper function for WriteBytes() and WriteChars().  Converts the
 *	'\n' characters in the source buffer into the appropriate EOL
 *	form specified by the output translation mode.
 *
 *	EOL translation stops either when the source buffer is empty
 *	or the output buffer is full.
 *
 *	When converting to CRLF mode and there is only 1 byte left in
 *	the output buffer, this routine stores the '\r' in the last
 *	byte and then stores the '\n' in the byte just past the end of the 
 *	buffer.  The caller is responsible for passing in a buffer that
 *	is large enough to hold the extra byte.
 *

 * Results:
 *	The return value is 1 if a '\n' was translated from the source
 *	buffer, or 0 otherwise -- this can be used by the caller to
 *	decide to flush a line-based channel even though the channel
 *	buffer is not full.
 *
 *	*dstLenPtr is filled with how many bytes of the output buffer

 *	were used.  As mentioned above, this can be one more that
 *	the output buffer's specified length if a CRLF was stored.

 *
 *	*srcLenPtr is filled with how many bytes of the source buffer
 *	were consumed.  
 *
 * Side effects:




 *	It may be obvious, but bears mentioning that when converting
 *	in CRLF mode (which requires two bytes of storage in the output
 *	buffer), the number of bytes consumed from the source buffer
 *	will be less than the number of bytes stored in the output buffer.
 *
 *---------------------------------------------------------------------------
 */


static int

TranslateOutputEOL(chanPtr, dst, src, dstLenPtr, srcLenPtr)
    Channel *chanPtr;		/* Channel being read, for translation and
				 * buffering modes. */
    char *dst;			/* Output buffer filled with UTF-8 chars by
				 * applying appropriate EOL translation to
				 * source characters. */
    CONST char *src;		/* Source UTF-8 characters. */
    int *dstLenPtr;		/* On entry, the maximum length of output
				 * buffer in bytes.  On exit, the number of
				 * bytes actually used in output buffer. */
    int *srcLenPtr;		/* On entry, the length of source buffer.
				 * On exit, the number of bytes read from
				 * the source buffer. */
{
    char *dstEnd;
    int srcLen, newlineFound;
    
    newlineFound = 0;
    srcLen = *srcLenPtr;

    switch (chanPtr->outputTranslation) {
	case TCL_TRANSLATE_LF: {
	    for (dstEnd = dst + srcLen; dst < dstEnd; ) {
		if (*src == '\n') {
		    newlineFound = 1;
		}
		*dst++ = *src++;
	    }
	    *dstLenPtr = srcLen;
	    break;
	}
	case TCL_TRANSLATE_CR: {
	    for (dstEnd = dst + srcLen; dst < dstEnd;) {
		if (*src == '\n') {
		    *dst++ = '\r';
		    newlineFound = 1;
		    src++;
		} else {
		    *dst++ = *src++;
		}
	    }
	    *dstLenPtr = srcLen;
	    break;
	}
	case TCL_TRANSLATE_CRLF: {


	    /*
	     * Since this causes the number of bytes to grow, we
	     * start off trying to put 'srcLen' bytes into the
	     * output buffer, but allow it to store more bytes, as

	     * long as there's still source bytes and room in the
	     * output buffer.
	     */

	    char *dstStart, *dstMax;
	    CONST char *srcStart;
	    
	    dstStart = dst;
	    dstMax = dst + *dstLenPtr;

	    srcStart = src;
	    
	    if (srcLen < *dstLenPtr) {
		dstEnd = dst + srcLen;
	    } else {
		dstEnd = dst + *dstLenPtr;
	    }
	    while (dst < dstEnd) {
		if (*src == '\n') {
		    if (dstEnd < dstMax) {
			dstEnd++;
		    }
		    *dst++ = '\r';
		    newlineFound = 1;
		}
		*dst++ = *src++;
	    }
	    *srcLenPtr = src - srcStart;
	    *dstLenPtr = dst - dstStart;
	    break;
	}
	default: {
	    break;
	}
    }
    return newlineFound;
}

/*
 *---------------------------------------------------------------------------
 *
 * CheckFlush --
 *
 *	Helper function for WriteBytes() and WriteChars().  If the
 *	channel buffer is ready to be flushed, flush it.
 *
 * Results:
 *	The return value is -1 if there was a problem flushing the
 *	channel buffer, or 0 otherwise.
 *
 * Side effects:
 *	The buffer will be recycled if it is flushed.
 *
 *---------------------------------------------------------------------------
 */

static int
CheckFlush(chanPtr, bufPtr, newlineFlag)
    Channel *chanPtr;		/* Channel being read, for buffering mode. */
    ChannelBuffer *bufPtr;	/* Channel buffer to possibly flush. */
    int newlineFlag;		/* Non-zero if a the channel buffer
				 * contains a newline. */
{
    /*
     * The current buffer is ready for output:
     * 1. if it is full.
     * 2. if it contains a newline and this channel is line-buffered.
     * 3. if it contains any output and this channel is unbuffered.
     */

    if ((chanPtr->flags & BUFFER_READY) == 0) {
	if (bufPtr->nextAdded == bufPtr->bufLength) {
	    chanPtr->flags |= BUFFER_READY;
	} else if (chanPtr->flags & CHANNEL_LINEBUFFERED) {




	    if (newlineFlag != 0) {




		chanPtr->flags |= BUFFER_READY;
	    }
	} else if (chanPtr->flags & CHANNEL_UNBUFFERED) {
	    chanPtr->flags |= BUFFER_READY;
	}
    }





    if (chanPtr->flags & BUFFER_READY) {
	if (FlushChannel(NULL, chanPtr, 0) != 0) {
	    return -1;
	}
    }
    return 0;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_Gets --
 *
 *	Reads a complete line of input from the channel into a Tcl_DString.
 *
 * Results:
 *	Length of line read (in characters) or -1 if error, EOF, or blocked.
 *	If -1, use Tcl_GetErrno() to retrieve the POSIX error code for the
 *	error or condition that occurred.
 *
 * Side effects:
 *	May flush output on the channel.  May cause input to be consumed
 *	from the channel.
 *
 *---------------------------------------------------------------------------
 */

int
Tcl_Gets(chan, lineRead)
    Tcl_Channel chan;		/* Channel from which to read. */
    Tcl_DString *lineRead;	/* The line read will be appended to this
				 * DString as UTF-8 characters.  The caller
				 * must have initialized it and is responsible
				 * for managing the storage. */
{
    Tcl_Obj *objPtr;
    int charsStored, length;
    char *string;

    objPtr = Tcl_NewObj();
    charsStored = Tcl_GetsObj(chan, objPtr);
    if (charsStored > 0) {
	string = Tcl_GetStringFromObj(objPtr, &length);
	Tcl_DStringAppend(lineRead, string, length);
    }
    Tcl_DecrRefCount(objPtr);
    return charsStored;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_GetsObj --
 *
 *	Accumulate input from the input channel until end-of-line or
 *	end-of-file has been seen.  Bytes read from the input channel
 *	are converted to UTF-8 using the encoding specified by the
 *	channel.
 *
 * Results:
 *	Number of characters accumulated in the object or -1 if error,
 *	blocked, or EOF.  If -1, use Tcl_GetErrno() to retrieve the
 *	POSIX error code for the error or condition that occurred.
 *
 * Side effects:
 *	Consumes input from the channel.
 *
 *	On reading EOF, leave channel pointing at EOF char.
 *	On reading EOL, leave channel pointing after EOL, but don't
 *	return EOL in dst buffer.
 *
 *---------------------------------------------------------------------------
 */

int
Tcl_GetsObj(chan, objPtr)
    Tcl_Channel chan;		/* Channel from which to read. */
    Tcl_Obj *objPtr;		/* The line read will be appended to this
				 * object as UTF-8 characters. */
{
    GetsState gs;
    Channel *chanPtr;
    int inEofChar, skip, copiedTotal;
    ChannelBuffer *bufPtr;
    Tcl_Encoding encoding;
    char *dst, *dstEnd, *eol, *eof;
    Tcl_EncodingState oldState;
    int oldLength, oldFlags, oldRemoved;

    chanPtr = (Channel *) chan;
    if (CheckChannelErrors(chanPtr, TCL_READABLE) != 0) {
	copiedTotal = -1;
	goto done;
    }

    bufPtr = chanPtr->inQueueHead;
    encoding = chanPtr->encoding;

    /*
     * Preserved so we can restore the channel's state in case we don't
     * find a newline in the available input.
     */

    Tcl_GetStringFromObj(objPtr, &oldLength);
    oldFlags = chanPtr->inputEncodingFlags;
    oldState = chanPtr->inputEncodingState;
    oldRemoved = BUFFER_PADDING;
    if (bufPtr != NULL) {
	oldRemoved = bufPtr->nextRemoved;
    }

    /*
     * If there is no encoding, use "iso8859-1" -- Tcl_GetsObj() doesn't
     * produce ByteArray objects.  To avoid circularity problems,
     * "iso8859-1" is builtin to Tcl.
     */

    if (encoding == NULL) {
	encoding = Tcl_GetEncoding(NULL, "iso8859-1");
    }

    /*
     * Object used by FilterInputBytes to keep track of how much data has
     * been consumed from the channel buffers.
     */

    gs.objPtr		= objPtr;
    gs.dstPtr		= &dst;
    gs.encoding		= encoding;
    gs.bufPtr		= bufPtr;
    gs.state		= oldState;
    gs.rawRead		= 0;
    gs.bytesWrote	= 0;
    gs.charsWrote	= 0;
    gs.totalChars	= 0;

    dst = objPtr->bytes + oldLength;
    dstEnd = dst;

    skip = 0;
    eof = NULL;
    inEofChar = chanPtr->inEofChar;

    while (1) {
	if (dst >= dstEnd) {
	    if (FilterInputBytes(chanPtr, &gs) != 0) {
		goto restore;
	    }
	    dstEnd = dst + gs.bytesWrote;
	}
	
	/*
	 * Remember if EOF char is seen, then look for EOL anyhow, because
	 * the EOL might be before the EOF char.
	 */

	if (inEofChar != '\0') {
	    for (eol = dst; eol < dstEnd; eol++) {
		if (*eol == inEofChar) {
		    dstEnd = eol;
		    eof = eol;
		    break;
		}
	    }
	}

	/*
	 * On EOL, leave current file position pointing after the EOL, but
	 * don't store the EOL in the output string.
	 */

	eol = dst;
	switch (chanPtr->inputTranslation) {
	    case TCL_TRANSLATE_LF: {
		for (eol = dst; eol < dstEnd; eol++) {
		    if (*eol == '\n') {
			skip = 1;
			goto goteol;
		    }
		}
		break;
	    }
	    case TCL_TRANSLATE_CR: {
		for (eol = dst; eol < dstEnd; eol++) {
		    if (*eol == '\r') {
			skip = 1;
			goto goteol;
		    }
		}
		break;
	    }
	    case TCL_TRANSLATE_CRLF: {
		for (eol = dst; eol < dstEnd; eol++) {
		    if (*eol == '\r') {
			eol++;
			if (eol >= dstEnd) {
			    int offset;
			    
			    offset = eol - objPtr->bytes;
			    dst = dstEnd;
			    if (FilterInputBytes(chanPtr, &gs) != 0) {
				goto restore;
			    }
			    dstEnd = dst + gs.bytesWrote;
			    eol = objPtr->bytes + offset;
			    if (eol >= dstEnd) {
				skip = 0;
				goto goteol;
			    }
			}
			if (*eol == '\n') {
			    eol--;
			    skip = 2;
			    goto goteol;
			}
		    }
		}
		break;
	    }
	    case TCL_TRANSLATE_AUTO: {
		skip = 1;
		if (chanPtr->flags & INPUT_SAW_CR) {
		    chanPtr->flags &= ~INPUT_SAW_CR;
		    if (*eol == '\n') {
			/*
			 * Skip the raw bytes that make up the '\n'.
			 */

			char tmp[1 + TCL_UTF_MAX];
			int rawRead;

			bufPtr = gs.bufPtr;
			Tcl_ExternalToUtf(NULL, gs.encoding,
				bufPtr->buf + bufPtr->nextRemoved,
				gs.rawRead, chanPtr->inputEncodingFlags,
				&gs.state, tmp, 1 + TCL_UTF_MAX, &rawRead,
				NULL, NULL);
			bufPtr->nextRemoved += rawRead;
			gs.rawRead -= rawRead;
			gs.bytesWrote--;
			gs.charsWrote--;
			memmove(dst, dst + 1, (size_t) (dstEnd - dst));
			dstEnd--;
		    }
		}
		for (eol = dst; eol < dstEnd; eol++) {
		    if (*eol == '\r') {
			eol++;
			if (eol == dstEnd) {
			    /*
			     * If buffer ended on \r, peek ahead to see if a
			     * \n is available.
			     */

			    int offset;
			    
			    offset = eol - objPtr->bytes;
			    dst = dstEnd;
			    PeekAhead(chanPtr, &dstEnd, &gs);
			    eol = objPtr->bytes + offset;
			    if (eol >= dstEnd) {
				eol--;
				chanPtr->flags |= INPUT_SAW_CR;
				goto goteol;
			    }
			}
			if (*eol == '\n') {
			    skip++;
			}
			eol--;
			goto goteol;
		    } else if (*eol == '\n') {
			goto goteol;
		    }
		}
	    }
	}
	if (eof != NULL) {
	    /*
	     * EOF character was seen.  On EOF, leave current file position
	     * pointing at the EOF character, but don't store the EOF
	     * character in the output string.
	     */

	    dstEnd = eof;
	    chanPtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
	    chanPtr->inputEncodingFlags |= TCL_ENCODING_END;
	}
	if (chanPtr->flags & CHANNEL_EOF) {
	    skip = 0;
	    eol = dstEnd;
	    if (eol == objPtr->bytes) {
		/*
		 * If we didn't produce any bytes before encountering EOF,
		 * caller needs to see -1.
		 */

		Tcl_SetObjLength(objPtr, 0);
		CommonGetsCleanup(chanPtr, encoding);
		copiedTotal = -1;
		goto done;
	    }
	    goto goteol;
	}
	dst = dstEnd;
    }

    /*
     * Found EOL or EOF, but the output buffer may now contain too many
     * UTF-8 characters.  We need to know how many raw bytes correspond to
     * the number of UTF-8 characters we want, plus how many raw bytes
     * correspond to the character(s) making up EOL (if any), so we can
     * remove the correct number of bytes from the channel buffer.
     */
     
    goteol:
    bufPtr = gs.bufPtr;
    chanPtr->inputEncodingState = gs.state;
    Tcl_ExternalToUtf(NULL, gs.encoding, bufPtr->buf + bufPtr->nextRemoved,
	    gs.rawRead, chanPtr->inputEncodingFlags,
	    &chanPtr->inputEncodingState, dst, eol - dst + skip + TCL_UTF_MAX,
	    &gs.rawRead, NULL, &gs.charsWrote);
    bufPtr->nextRemoved += gs.rawRead;

    /*
     * Recycle all the emptied buffers.
     */

    Tcl_SetObjLength(objPtr, eol - objPtr->bytes);
    CommonGetsCleanup(chanPtr, encoding);
    chanPtr->flags &= ~CHANNEL_BLOCKED;
    copiedTotal = gs.totalChars + gs.charsWrote - skip;
    goto done;

    /*
     * Couldn't get a complete line.  This only happens if we get a error
     * reading from the channel or we are non-blocking and there wasn't
     * an EOL or EOF in the data available.
     */

    restore:
    bufPtr = chanPtr->inQueueHead;
    bufPtr->nextRemoved = oldRemoved;

    for (bufPtr = bufPtr->nextPtr; bufPtr != NULL; bufPtr = bufPtr->nextPtr) {
	bufPtr->nextRemoved = BUFFER_PADDING;
    }
    CommonGetsCleanup(chanPtr, encoding);

    chanPtr->inputEncodingState = oldState;
    chanPtr->inputEncodingFlags = oldFlags;
    Tcl_SetObjLength(objPtr, oldLength);

    /*
     * We didn't get a complete line so we need to indicate to UpdateInterest
     * that the gets blocked.  It will wait for more data instead of firing
     * a timer, avoiding a busy wait.  This is where we are assuming that the
     * next operation is a gets.  No more file events will be delivered on 
     * this channel until new data arrives or some operation is performed
     * on the channel (e.g. gets, read, fconfigure) that changes the blocking
     * state.  Note that this means a file event will not be delivered even
     * though a read would be able to consume the buffered data.
     */

    chanPtr->flags |= CHANNEL_NEED_MORE_DATA;
    copiedTotal = -1;

    done:
    /*
     * Update the notifier state so we don't block while there is still
     * data in the buffers.
     */

    UpdateInterest(chanPtr);
    return copiedTotal;
}

/*
 *---------------------------------------------------------------------------
 *
 * FilterInputBytes --
 *
 *	Helper function for Tcl_GetsObj.  Produces UTF-8 characters from
 *	raw bytes read from the channel.  
 *
 *	Consumes available bytes from channel buffers.  When channel
 *	buffers are exhausted, reads more bytes from channel device into
 *	a new channel buffer.  It is the caller's responsibility to
 *	free the channel buffers that have been exhausted.
 *
 * Results:
 *	The return value is -1 if there was an error reading from the
 *	channel, 0 otherwise.
 *
 * Side effects:
 *	Status object keeps track of how much data from channel buffers
 *	has been consumed and where UTF-8 bytes should be stored.
 *
 *---------------------------------------------------------------------------
 */
 
static int
FilterInputBytes(chanPtr, gsPtr)
    Channel *chanPtr;		/* Channel to read. */
    GetsState *gsPtr;		/* Current state of gets operation. */
{
    ChannelBuffer *bufPtr;
    char *raw, *rawStart, *rawEnd;
    char *dst;
    int offset, toRead, dstNeeded, spaceLeft, result, rawLen, length;
    Tcl_Obj *objPtr;
#define ENCODING_LINESIZE   30	/* Lower bound on how many bytes to convert
				 * at a time.  Since we don't know a priori
				 * how many bytes of storage this many source
				 * bytes will use, we actually need at least
				 * ENCODING_LINESIZE * TCL_MAX_UTF bytes of
				 * room. */

    objPtr = gsPtr->objPtr;

    /*
     * Subtract the number of bytes that were removed from channel buffer
     * during last call.
     */

    bufPtr = gsPtr->bufPtr;
    if (bufPtr != NULL) {
	bufPtr->nextRemoved += gsPtr->rawRead;
	if (bufPtr->nextRemoved >= bufPtr->nextAdded) {
	    bufPtr = bufPtr->nextPtr;
	}
    }
    gsPtr->totalChars += gsPtr->charsWrote;

    if ((bufPtr == NULL) || (bufPtr->nextAdded == BUFFER_PADDING)) {
	/*
	 * All channel buffers were exhausted and the caller still hasn't
	 * seen EOL.  Need to read more bytes from the channel device.
	 * Side effect is to allocate another channel buffer.
	 */
	 
	read:
        if (chanPtr->flags & CHANNEL_BLOCKED) {
            if (chanPtr->flags & CHANNEL_NONBLOCKING) {
		gsPtr->charsWrote = 0;
		gsPtr->rawRead = 0;
		return -1;
	    }
            chanPtr->flags &= ~CHANNEL_BLOCKED;
        }
	if (GetInput(chanPtr) != 0) {
	    gsPtr->charsWrote = 0;
	    gsPtr->rawRead = 0;
	    return -1;
	}
	bufPtr = chanPtr->inQueueTail;
	gsPtr->bufPtr = bufPtr;
    }

    /*
     * Convert some of the bytes from the channel buffer to UTF-8.  Space in
     * objPtr's string rep is used to hold the UTF-8 characters.  Grow the
     * string rep if we need more space.
     */

    rawStart = bufPtr->buf + bufPtr->nextRemoved;
    raw = rawStart;
    rawEnd = bufPtr->buf + bufPtr->nextAdded;
    rawLen = rawEnd - rawStart;

    dst = *gsPtr->dstPtr;
    offset = dst - objPtr->bytes;
    toRead = ENCODING_LINESIZE;
    if (toRead > rawLen) {
	toRead = rawLen;
    }
    dstNeeded = toRead * TCL_UTF_MAX + 1;
    spaceLeft = objPtr->length - offset - TCL_UTF_MAX - 1;
    if (dstNeeded > spaceLeft) {
	length = offset * 2;
	if (offset < dstNeeded) {
	    length = offset + dstNeeded;
	}
	length += TCL_UTF_MAX + 1;
	Tcl_SetObjLength(objPtr, length);
	spaceLeft = length - offset;
	dst = objPtr->bytes + offset;
	*gsPtr->dstPtr = dst;
    }
    gsPtr->state = chanPtr->inputEncodingState;
    result = Tcl_ExternalToUtf(NULL, gsPtr->encoding, raw, rawLen,
	    chanPtr->inputEncodingFlags, &chanPtr->inputEncodingState,
	    dst, spaceLeft, &gsPtr->rawRead, &gsPtr->bytesWrote,
	    &gsPtr->charsWrote); 
    if (result == TCL_CONVERT_MULTIBYTE) {
	/*
	 * The last few bytes in this channel buffer were the start of a
	 * multibyte sequence.  If this buffer was full, then move them to
	 * the next buffer so the bytes will be contiguous.  
	 */

	ChannelBuffer *nextPtr;
	int extra;
	
	nextPtr = bufPtr->nextPtr;
	if (bufPtr->nextAdded < bufPtr->bufLength) {
	    if (gsPtr->rawRead > 0) {
		/*
		 * Some raw bytes were converted to UTF-8.  Fall through,
		 * returning those UTF-8 characters because a EOL might be
		 * present in them.
		 */
	    } else if (chanPtr->flags & CHANNEL_EOF) {
		/*
		 * There was a partial character followed by EOF on the
		 * device.  Fall through, returning that nothing was found.
		 */

		 bufPtr->nextRemoved = bufPtr->nextAdded;
	    } else {
		/*
		 * There are no more cached raw bytes left.  See if we can
		 * get some more.
		 */

		goto read;
	    }
	} else {
	    if (nextPtr == NULL) {
		nextPtr = AllocChannelBuffer(chanPtr->bufSize);
		bufPtr->nextPtr = nextPtr;
		chanPtr->inQueueTail = nextPtr;
	    }
	    extra = rawLen - gsPtr->rawRead;
	    memcpy((VOID *) (nextPtr->buf + BUFFER_PADDING - extra),
		    (VOID *) (raw + gsPtr->rawRead), (size_t) extra);
	    nextPtr->nextRemoved -= extra;
	    bufPtr->nextAdded -= extra;
	}
    }

    gsPtr->bufPtr = bufPtr;
    return 0;
}

/*
 *---------------------------------------------------------------------------
 *
 * PeekAhead --
 *
 *	Helper function used by Tcl_GetsObj().  Called when we've seen a
 *	\r at the end of the UTF-8 string and want to look ahead one
 *	character to see if it is a \n.
 *
 * Results:
 *	*gsPtr->dstPtr is filled with a pointer to the start of the range of
 *	UTF-8 characters that were found by peeking and *dstEndPtr is filled
 *	with a pointer to the bytes just after the end of the range.
 *
 * Side effects:
 *	If no more raw bytes were available in one of the channel buffers,
 *	tries to perform a non-blocking read to get more bytes from the
 *	channel device.
 *
 *---------------------------------------------------------------------------
 */

static void
PeekAhead(chanPtr, dstEndPtr, gsPtr)
    Channel *chanPtr;		/* The channel to read. */
    char **dstEndPtr;		/* Filled with pointer to end of new range
				 * of UTF-8 characters. */
    GetsState *gsPtr;		/* Current state of gets operation. */
{
    ChannelBuffer *bufPtr;
    Tcl_DriverBlockModeProc *blockModeProc;
    int bytesLeft;

    bufPtr = gsPtr->bufPtr;

    /*
     * If there's any more raw input that's still buffered, we'll peek into
     * that.  Otherwise, only get more data from the channel driver if it
     * looks like there might actually be more data.  The assumption is that
     * if the channel buffer is filled right up to the end, then there
     * might be more data to read.
     */

    blockModeProc = NULL;
    if (bufPtr->nextPtr == NULL) {
	bytesLeft = bufPtr->nextAdded - (bufPtr->nextRemoved + gsPtr->rawRead);
	if (bytesLeft == 0) {
	    if (bufPtr->nextAdded < bufPtr->bufLength) {
		/*
		 * Don't peek ahead if last read was short read.
		 */
		 
		goto cleanup;
	    }
	    if ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0) {
		blockModeProc = chanPtr->typePtr->blockModeProc;
		if (blockModeProc == NULL) {
		    /*
		     * Don't peek ahead if cannot set non-blocking mode.
		     */

		    goto cleanup;
		}
		(*blockModeProc)(chanPtr->instanceData, TCL_MODE_NONBLOCKING);
	    }
	}
    }
    if (FilterInputBytes(chanPtr, gsPtr) == 0) {
	*dstEndPtr = *gsPtr->dstPtr + gsPtr->bytesWrote;
    }
    if (blockModeProc != NULL) {
	(*blockModeProc)(chanPtr->instanceData, TCL_MODE_BLOCKING);
    }
    return;

    cleanup:
    bufPtr->nextRemoved += gsPtr->rawRead;
    gsPtr->rawRead = 0;
    gsPtr->totalChars += gsPtr->charsWrote;
    gsPtr->bytesWrote = 0;
    gsPtr->charsWrote = 0;
}

/*
 *---------------------------------------------------------------------------
 *
 * CommonGetsCleanup --
 *
 *	Helper function for Tcl_GetsObj() to restore the channel after
 *	a "gets" operation.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Encoding may be freed.
 *
 *---------------------------------------------------------------------------
 */
 
static void
CommonGetsCleanup(chanPtr, encoding)
    Channel *chanPtr;
    Tcl_Encoding encoding;
{
    ChannelBuffer *bufPtr, *nextPtr;
    
    bufPtr = chanPtr->inQueueHead;
    for ( ; bufPtr != NULL; bufPtr = nextPtr) {
	nextPtr = bufPtr->nextPtr;
	if (bufPtr->nextRemoved < bufPtr->nextAdded) {
	    break;
	}
	RecycleBuffer(chanPtr, bufPtr, 0);
    }
    chanPtr->inQueueHead = bufPtr;
    if (bufPtr == NULL) {
	chanPtr->inQueueTail = NULL;
    } else {
	/*
	 * If any multi-byte characters were split across channel buffer
	 * boundaries, the split-up bytes were moved to the next channel
	 * buffer by FilterInputBytes().  Move the bytes back to their
	 * original buffer because the caller could change the channel's
	 * encoding which could change the interpretation of whether those
	 * bytes really made up multi-byte characters after all.
	 */
	 
	nextPtr = bufPtr->nextPtr;
	for ( ; nextPtr != NULL; nextPtr = bufPtr->nextPtr) {
	    int extra;

	    extra = bufPtr->bufLength - bufPtr->nextAdded;
	    if (extra > 0) {
		memcpy((VOID *) (bufPtr->buf + bufPtr->nextAdded),
			(VOID *) (nextPtr->buf + BUFFER_PADDING - extra),
			(size_t) extra);
		bufPtr->nextAdded += extra;
		nextPtr->nextRemoved = BUFFER_PADDING;
	    }
	    bufPtr = nextPtr;
	}
    }
    if (chanPtr->encoding == NULL) {
	Tcl_FreeEncoding(encoding);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Read --
 *
 *	Reads a given number of bytes from a channel.  EOL and EOF
 *	translation is done on the bytes being read, so the the number
 *	of bytes consumed from the channel may not be equal to the
 *	number of bytes stored in the destination buffer.
 *
 *	No encoding conversions are applied to the bytes being read.
 *
 * Results:
 *	The number of bytes read, or -1 on error. Use Tcl_GetErrno()
 *	to retrieve the error code for the error that occurred.
 *
 * Side effects:
 *	May cause input to be buffered.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Read(chan, dst, bytesToRead)
    Tcl_Channel chan;		/* The channel from which to read. */
    char *dst;			/* Where to store input read. */
    int bytesToRead;		/* Maximum number of bytes to read. */
{
    Channel *chanPtr;		
    
    chanPtr = (Channel *) chan;
    if (CheckChannelErrors(chanPtr, TCL_READABLE) != 0) {
	return -1;
    }

    return DoRead(chanPtr, dst, bytesToRead);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_ReadChars --
 *
 *	Reads from the channel until the requested number of characters
 *	have been seen, EOF is seen, or the channel would block.  EOL
 *	and EOF translation is done.  If reading binary data, the raw
 *	bytes are wrapped in a Tcl byte array object.  Otherwise, the raw
 *	bytes are converted to UTF-8 using the channel's current encoding
 *	and stored in a Tcl string object.
 *
 * Results:
 *	The number of characters read, or -1 on error. Use Tcl_GetErrno()
 *	to retrieve the error code for the error that occurred.
 *
 * Side effects:
 *	May cause input to be buffered.
 *
 *---------------------------------------------------------------------------
 */
 
int
Tcl_ReadChars(chan, objPtr, toRead, appendFlag)
    Tcl_Channel chan;		/* The channel to read. */
    Tcl_Obj *objPtr;		/* Input data is stored in this object. */
    int toRead;			/* Maximum number of characters to store,
				 * or -1 to read all available data (up to EOF
				 * or when channel blocks). */
    int appendFlag;		/* If non-zero, data read from the channel
				 * will be appended to the object.  Otherwise,
				 * the data will replace the existing contents
				 * of the object. */

{
    Channel *chanPtr;
    int offset, factor, copied, copiedNow, result;
    ChannelBuffer *bufPtr;
    Tcl_Encoding encoding;
#define UTF_EXPANSION_FACTOR	1024
    
    chanPtr = (Channel *) chan;
    if (CheckChannelErrors(chanPtr, TCL_READABLE) != 0) {
	copied = -1;
	goto done;
    }

    encoding = chanPtr->encoding;
    factor = UTF_EXPANSION_FACTOR;

    if (appendFlag == 0) {
	if (encoding == NULL) {
	    Tcl_SetByteArrayLength(objPtr, 0);
	} else {
	    Tcl_SetObjLength(objPtr, 0);
	}
	offset = 0;
    } else {
	if (encoding == NULL) {
	    Tcl_GetByteArrayFromObj(objPtr, &offset);
	} else {
	    Tcl_GetStringFromObj(objPtr, &offset);
	}
    }

    for (copied = 0; (unsigned) toRead > 0; ) {
	copiedNow = -1;
	if (chanPtr->inQueueHead != NULL) {
	    if (encoding == NULL) {
		copiedNow = ReadBytes(chanPtr, objPtr, toRead, &offset);
	    } else {
		copiedNow = ReadChars(chanPtr, objPtr, toRead, &offset,
			&factor);
	    }

	    /*
	     * If the current buffer is empty recycle it.
	     */

	    bufPtr = chanPtr->inQueueHead;
	    if (bufPtr->nextRemoved == bufPtr->nextAdded) {
		ChannelBuffer *nextPtr;

		nextPtr = bufPtr->nextPtr;
		RecycleBuffer(chanPtr, bufPtr, 0);
		chanPtr->inQueueHead = nextPtr;
		if (nextPtr == NULL) {
		    chanPtr->inQueueTail = nextPtr;
		}
	    }
	}
	if (copiedNow < 0) {
	    if (chanPtr->flags & CHANNEL_EOF) {
		break;
	    }
	    if (chanPtr->flags & CHANNEL_BLOCKED) {
		if (chanPtr->flags & CHANNEL_NONBLOCKING) {
		    break;
		}
		chanPtr->flags &= ~CHANNEL_BLOCKED;
	    }
	    result = GetInput(chanPtr);
	    if (result != 0) {
		if (result == EAGAIN) {
		    break;
		}
		copied = -1;
		goto done;
	    }
	} else {
	    copied += copiedNow;
	    toRead -= copiedNow;
	}
    }
    chanPtr->flags &= ~CHANNEL_BLOCKED;
    if (encoding == NULL) {
	Tcl_SetByteArrayLength(objPtr, offset);
    } else {
	Tcl_SetObjLength(objPtr, offset);
    }

    done:
    /*
     * Update the notifier state so we don't block while there is still
     * data in the buffers.
     */

    UpdateInterest(chanPtr);
    return copied;
}
/*
 *---------------------------------------------------------------------------
 *
 * ReadBytes --
 *
 *	Reads from the channel until the requested number of bytes have
 *	been seen, EOF is seen, or the channel would block.  Bytes from
 *	the channel are stored in objPtr as a ByteArray object.  EOL
 *	and EOF translation are done.
 *
 *	'bytesToRead' can safely be a very large number because
 *	space is only allocated to hold data read from the channel
 *	as needed.
 *
 * Results:
 *	The return value is the number of bytes appended to the object
 *	and *offsetPtr is filled with the total number of bytes in the
 *	object (greater than the return value if there were already bytes
 *	in the object).
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
ReadBytes(chanPtr, objPtr, bytesToRead, offsetPtr)
    Channel *chanPtr;		/* The channel to read. */
    int bytesToRead;		/* Maximum number of characters to store,
				 * or < 0 to get all available characters.
				 * Characters are obtained from the first
				 * buffer in the queue -- even if this number
				 * is larger than the number of characters
				 * available in the first buffer, only the
				 * characters from the first buffer are
				 * returned. */
    Tcl_Obj *objPtr;		/* Input data is appended to this ByteArray
				 * object.  Its length is how much space
				 * has been allocated to hold data, not how
				 * many bytes of data have been stored in the
				 * object. */
    int *offsetPtr;		/* On input, contains how many bytes of
				 * objPtr have been used to hold data.  On
				 * output, filled with how many bytes are now
				 * being used. */
{
    int toRead, srcLen, srcRead, dstWrote, offset, length;
    ChannelBuffer *bufPtr;
    char *src, *dst;

    offset = *offsetPtr;

    bufPtr = chanPtr->inQueueHead; 
    src = bufPtr->buf + bufPtr->nextRemoved;
    srcLen = bufPtr->nextAdded - bufPtr->nextRemoved;

    toRead = bytesToRead;
    if ((unsigned) toRead > (unsigned) srcLen) {
	toRead = srcLen;
    }

    dst = (char *) Tcl_GetByteArrayFromObj(objPtr, &length);
    if (toRead > length - offset - 1) {
	/*
	 * Double the existing size of the object or make enough room to
	 * hold all the characters we may get from the source buffer,
	 * whichever is larger.
	 */

	length = offset * 2;
	if (offset < toRead) {
	    length = offset + toRead + 1;
	}
	dst = (char *) Tcl_SetByteArrayLength(objPtr, length);
    }
    dst += offset;

    if (chanPtr->flags & INPUT_NEED_NL) {
	chanPtr->flags &= ~INPUT_NEED_NL;
	if ((srcLen == 0) || (*src != '\n')) {
	    *dst = '\r';
	    *offsetPtr += 1;
	    return 1;
	}
	*dst++ = '\n';
	src++;
	srcLen--;
	toRead--;
    }

    srcRead = srcLen;
    dstWrote = toRead;
    if (TranslateInputEOL(chanPtr, dst, src, &dstWrote, &srcRead) != 0) {
	if (dstWrote == 0) {
	    return -1;
	}
    }
    bufPtr->nextRemoved += srcRead;
    *offsetPtr += dstWrote;
    return dstWrote;
}

/*
 *---------------------------------------------------------------------------
 *
 * ReadChars --
 *
 *	Reads from the channel until the requested number of UTF-8
 *	characters have been seen, EOF is seen, or the channel would
 *	block.  Raw bytes from the channel are converted to UTF-8
 *	and stored in objPtr.  EOL and EOF translation is done.
 *
 *	'charsToRead' can safely be a very large number because
 *	space is only allocated to hold data read from the channel
 *	as needed.
 *
 * Results:
 *	The return value is the number of characters appended to
 *	the object, *offsetPtr is filled with the number of bytes that
 *	were appended, and *factorPtr is filled with the expansion
 *	factor used to guess how many bytes of UTF-8 to allocate to
 *	hold N source bytes.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
ReadChars(chanPtr, objPtr, charsToRead, offsetPtr, factorPtr)
    Channel *chanPtr;		/* The channel to read. */
    int charsToRead;		/* Maximum number of characters to store,
				 * or -1 to get all available characters.
				 * Characters are obtained from the first
				 * buffer in the queue -- even if this number
				 * is larger than the number of characters
				 * available in the first buffer, only the
				 * characters from the first buffer are
				 * returned. */
    Tcl_Obj *objPtr;		/* Input data is appended to this object.
				 * objPtr->length is how much space has been
				 * allocated to hold data, not how many bytes
				 * of data have been stored in the object. */
    int *offsetPtr;		/* On input, contains how many bytes of
				 * objPtr have been used to hold data.  On
				 * output, filled with how many bytes are now
				 * being used. */
    int *factorPtr;		/* On input, contains a guess of how many
				 * bytes need to be allocated to hold the
				 * result of converting N source bytes to
				 * UTF-8.  On output, contains another guess
				 * based on the data seen so far. */
{
    int toRead, factor, offset, spaceLeft, length;
    int srcLen, srcRead, dstNeeded, dstRead, dstWrote, numChars;
    ChannelBuffer *bufPtr;
    char *src, *dst;
    Tcl_EncodingState oldState;

    factor = *factorPtr;
    offset = *offsetPtr;

    bufPtr = chanPtr->inQueueHead; 
    src = bufPtr->buf + bufPtr->nextRemoved;
    srcLen = bufPtr->nextAdded - bufPtr->nextRemoved;

    toRead = charsToRead;
    if ((unsigned) toRead > (unsigned) srcLen) {
	toRead = srcLen;
    }

    /*
     * 'factor' is how much we guess that the bytes in the source buffer
     * will expand when converted to UTF-8 chars.  This guess comes from
     * analyzing how many characters were produced by the previous
     * pass.
     */

    dstNeeded = toRead * factor / UTF_EXPANSION_FACTOR;
    spaceLeft = objPtr->length - offset - TCL_UTF_MAX - 1;

    if (dstNeeded > spaceLeft) {
	/*
	 * Double the existing size of the object or make enough room to
	 * hold all the characters we want from the source buffer,
	 * whichever is larger.
	 */

	length = offset * 2;
	if (offset < dstNeeded) {
	    length = offset + dstNeeded;
	}
	spaceLeft = length - offset;
	length += TCL_UTF_MAX + 1;
	Tcl_SetObjLength(objPtr, length);
    }
    if (toRead == srcLen) {
	/*
	 * Want to convert the whole buffer in one pass.  If we have
	 * enough space, convert it using all available space in object
	 * rather than using the factor.
	 */

	dstNeeded = spaceLeft;
    }
    dst = objPtr->bytes + offset;

    oldState = chanPtr->inputEncodingState;
    if (chanPtr->flags & INPUT_NEED_NL) {
	/*
	 * We want a '\n' because the last character we saw was '\r'.
	 */
	 
	chanPtr->flags &= ~INPUT_NEED_NL;
	Tcl_ExternalToUtf(NULL, chanPtr->encoding, src, srcLen,
		chanPtr->inputEncodingFlags, &chanPtr->inputEncodingState,
		dst, TCL_UTF_MAX + 1, &srcRead, &dstWrote, &numChars);
	if ((dstWrote > 0) && (*dst == '\n')) {
	    /*
	     * The next char was a '\n'.  Consume it and produce a '\n'.
	     */
	     
	    bufPtr->nextRemoved += srcRead;
	} else {
	    /*
	     * The next char was not a '\n'.  Produce a '\r'.
	     */

	    *dst = '\r';
	}
	chanPtr->inputEncodingFlags &= ~TCL_ENCODING_START;
	*offsetPtr += 1;
        return 1;
    }

    Tcl_ExternalToUtf(NULL, chanPtr->encoding, src, srcLen,
	    chanPtr->inputEncodingFlags, &chanPtr->inputEncodingState, dst,
	    dstNeeded + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars);
    if (srcRead == 0) {
	/*
	 * Not enough bytes in src buffer to make a complete char.  Copy
	 * the bytes to the next buffer to make a new contiguous string,
	 * then tell the caller to fill the buffer with more bytes.
	 */

	ChannelBuffer *nextPtr;
	
	nextPtr = bufPtr->nextPtr;
	if (nextPtr == NULL) {
	    /*
	     * There isn't enough data in the buffers to complete the next
	     * character, so we need to wait for more data before the next
	     * file event can be delivered.
	     */

	    chanPtr->flags |= CHANNEL_NEED_MORE_DATA;
	    return -1;
	}
	nextPtr->nextRemoved -= srcLen;
	memcpy((VOID *) (nextPtr->buf + nextPtr->nextRemoved), (VOID *) src,
		(size_t) srcLen);
	RecycleBuffer(chanPtr, bufPtr, 0);
	chanPtr->inQueueHead = nextPtr;
	return ReadChars(chanPtr, objPtr, charsToRead, offsetPtr, factorPtr);
    }

    dstRead = dstWrote;
    if (TranslateInputEOL(chanPtr, dst, dst, &dstWrote, &dstRead) != 0) {
	/*
	 * Hit EOF char.  How many bytes of src correspond to where the
	 * EOF was located in dst?
	 */
	 
	if (dstWrote == 0) {
	    return -1;
	}
	chanPtr->inputEncodingState = oldState;
	Tcl_ExternalToUtf(NULL, chanPtr->encoding, src, srcLen,
		chanPtr->inputEncodingFlags, &chanPtr->inputEncodingState,
		dst, dstRead + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars);
	TranslateInputEOL(chanPtr, dst, dst, &dstWrote, &dstRead);
    } 

    /*
     * The number of characters that we got may be less than the number
     * that we started with because "\r\n" sequences may have been
     * turned into just '\n' in dst.
     */

    numChars -= (dstRead - dstWrote);

    if ((unsigned) numChars > (unsigned) toRead) {
	/*
	 * Got too many chars.
	 */

	char *eof;

	eof = Tcl_UtfAtIndex(dst, toRead);
	chanPtr->inputEncodingState = oldState;
	Tcl_ExternalToUtf(NULL, chanPtr->encoding, src, srcLen,
		chanPtr->inputEncodingFlags, &chanPtr->inputEncodingState,
		dst, eof - dst + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars);
	dstRead = dstWrote;
	TranslateInputEOL(chanPtr, dst, dst, &dstWrote, &dstRead);
	numChars -= (dstRead - dstWrote);
    }
    chanPtr->inputEncodingFlags &= ~TCL_ENCODING_START;

    bufPtr->nextRemoved += srcRead;
    if (dstWrote > srcRead + 1) {
	*factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead;
    }
    *offsetPtr += dstWrote;
    return numChars;
}

/*
 *---------------------------------------------------------------------------
 *
 * TranslateInputEOL --
 *
 *	Perform input EOL and EOF translation on the source buffer,
 *	leaving the translated result in the destination buffer.  
 *
 * Results:
 *	The return value is 1 if the EOF character was found when copying
 *	bytes to the destination buffer, 0 otherwise.  
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
TranslateInputEOL(chanPtr, dstStart, srcStart, dstLenPtr, srcLenPtr)
    Channel *chanPtr;		/* Channel being read, for EOL translation
				 * and EOF character. */
    char *dstStart;		/* Output buffer filled with chars by
				 * applying appropriate EOL translation to
				 * source characters. */
    CONST char *srcStart;	/* Source characters. */
    int *dstLenPtr;		/* On entry, the maximum length of output
				 * buffer in bytes; must be <= *srcLenPtr.  On
				 * exit, the number of bytes actually used in
				 * output buffer. */
    int *srcLenPtr;		/* On entry, the length of source buffer.
				 * On exit, the number of bytes read from
				 * the source buffer. */
{
    int dstLen, srcLen, inEofChar;
    CONST char *eof;

    dstLen = *dstLenPtr;

    eof = NULL;
    inEofChar = chanPtr->inEofChar;
    if (inEofChar != '\0') {
	/*
	 * Find EOF in translated buffer then compress out the EOL.  The
	 * source buffer may be much longer than the destination buffer --
	 * we only want to return EOF if the EOF has been copied to the
	 * destination buffer.
	 */

	CONST char *src, *srcMax;

	srcMax = srcStart + *srcLenPtr;
	for (src = srcStart; src < srcMax; src++) {
	    if (*src == inEofChar) {
		eof = src;
		srcLen = src - srcStart;
		if (srcLen < dstLen) {
		    dstLen = srcLen;
		}
		*srcLenPtr = srcLen;
		break;
	    }
	}
    }
    switch (chanPtr->inputTranslation) {
	case TCL_TRANSLATE_LF: {
	    if (dstStart != srcStart) {
		memcpy((VOID *) dstStart, (VOID *) srcStart, (size_t) dstLen);
	    }
	    srcLen = dstLen;
	    break;
	}
	case TCL_TRANSLATE_CR: {
	    char *dst, *dstEnd;
	    
	    if (dstStart != srcStart) {
		memcpy((VOID *) dstStart, (VOID *) srcStart, (size_t) dstLen);
	    }
	    dstEnd = dstStart + dstLen;
	    for (dst = dstStart; dst < dstEnd; dst++) {
		if (*dst == '\r') {
		    *dst = '\n';
		}
	    }
	    srcLen = dstLen;
	    break;
	}
	case TCL_TRANSLATE_CRLF: {
	    char *dst;
	    CONST char *src, *srcEnd, *srcMax;
	    
	    dst = dstStart;
	    src = srcStart;
	    srcEnd = srcStart + dstLen;
	    srcMax = srcStart + *srcLenPtr;

	    for ( ; src < srcEnd; ) {
		if (*src == '\r') {
		    src++;
		    if (src >= srcMax) {
			chanPtr->flags |= INPUT_NEED_NL;
		    } else if (*src == '\n') {
			*dst++ = *src++;
		    } else {
			*dst++ = '\r';
		    }
		} else {
		    *dst++ = *src++;
		}
	    }
	    srcLen = src - srcStart;
	    dstLen = dst - dstStart;
	    break;
	}
	case TCL_TRANSLATE_AUTO: {
	    char *dst;
	    CONST char *src, *srcEnd, *srcMax;

	    dst = dstStart;
	    src = srcStart;
	    srcEnd = srcStart + dstLen;
	    srcMax = srcStart + *srcLenPtr;

	    if ((chanPtr->flags & INPUT_SAW_CR) && (src < srcMax)) {
		if (*src == '\n') {
		    src++;
		}
		chanPtr->flags &= ~INPUT_SAW_CR;
	    }
	    for ( ; src < srcEnd; ) {
		if (*src == '\r') {
		    src++;
		    if (src >= srcMax) {
			chanPtr->flags |= INPUT_SAW_CR;
		    } else if (*src == '\n') {
			if (srcEnd < srcMax) {
			    srcEnd++;
			}
			src++;
		    }
		    *dst++ = '\n';
		} else {
		    *dst++ = *src++;
		}
	    }
	    srcLen = src - srcStart;
	    dstLen = dst - dstStart;
	    break;
	}
	default: {		/* lint. */
	    return 0;
	}
    }
    *dstLenPtr = dstLen;

    if ((eof != NULL) && (srcStart + srcLen >= eof)) {
	/*
	 * EOF character was seen in EOL translated range.  Leave current
	 * file position pointing at the EOF character, but don't store the
	 * EOF character in the output string.
	 */

	chanPtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
	chanPtr->inputEncodingFlags |= TCL_ENCODING_END;
	chanPtr->flags &= ~(INPUT_SAW_CR | INPUT_NEED_NL);
	return 1;
    }

    *srcLenPtr = srcLen;
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Ungets --
 *
 *	Causes the supplied string to be added to the input queue of
 *	the channel, at either the head or tail of the queue.
 *
 * Results:
 *	The number of bytes stored in the channel, or -1 on error.
 *
 * Side effects:
 *	Adds input to the input queue of a channel.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Ungets(chan, str, len, atEnd)
    Tcl_Channel chan;		/* The channel for which to add the input. */
    char *str;			/* The input itself. */
    int len;			/* The length of the input. */
    int atEnd;			/* If non-zero, add at end of queue; otherwise
                                 * add at head of queue. */    
{
    Channel *chanPtr;		/* The real IO channel. */
    ChannelBuffer *bufPtr;	/* Buffer to contain the data. */
    int i, flags;

    chanPtr = (Channel *) chan;
    
    /*
     * CheckChannelErrors clears too many flag bits in this one case.
     */
     
    flags = chanPtr->flags;
    if (CheckChannelErrors(chanPtr, TCL_READABLE) != 0) {
	len = -1;
	goto done;
    }
    chanPtr->flags = flags;

    /*
     * If we have encountered a sticky EOF, just punt without storing.
     * (sticky EOF is set if we have seen the input eofChar, to prevent
     * reading beyond the eofChar). Otherwise, clear the EOF flags, and
     * clear the BLOCKED bit. We want to discover these conditions anew
     * in each operation.
     */

    if (chanPtr->flags & CHANNEL_STICKY_EOF) {
	goto done;
    }
    chanPtr->flags &= (~(CHANNEL_BLOCKED | CHANNEL_EOF));

    bufPtr = AllocChannelBuffer(len);
    for (i = 0; i < len; i++) {
        bufPtr->buf[i] = str[i];
    }
    bufPtr->nextAdded += len;

    if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) {
        bufPtr->nextPtr = (ChannelBuffer *) NULL;
        chanPtr->inQueueHead = bufPtr;
        chanPtr->inQueueTail = bufPtr;
    } else if (atEnd) {
        bufPtr->nextPtr = (ChannelBuffer *) NULL;
        chanPtr->inQueueTail->nextPtr = bufPtr;
        chanPtr->inQueueTail = bufPtr;
    } else {
        bufPtr->nextPtr = chanPtr->inQueueHead;
        chanPtr->inQueueHead = bufPtr;
    }

    done:
    /*
     * Update the notifier state so we don't block while there is still
     * data in the buffers.
     */

    UpdateInterest(chanPtr);
    return len;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Flush --
 *
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
Tcl_Flush(chan)
    Tcl_Channel chan;			/* The Channel to flush. */
{
    int result;				/* Of calling FlushChannel. */
    Channel *chanPtr;			/* The actual channel. */

    chanPtr = (Channel *) chan;

    /*
     * Check for unreported error.
     */

    if (chanPtr->unreportedError != 0) {
        Tcl_SetErrno(chanPtr->unreportedError);
        chanPtr->unreportedError = 0;
        return TCL_ERROR;
    }

    /*
     * If the channel is not open for writing punt.
     */

    if (!(chanPtr->flags & TCL_WRITABLE)) {
        Tcl_SetErrno(EACCES);
        return TCL_ERROR;
    }
    
    /*
     * If the channel is in the middle of a background copy, fail.
     */

    if (chanPtr->csPtr) {
	Tcl_SetErrno(EBUSY);
	return -1;
    }

    /*
     * Force current output buffer to be output also.
     */
    
    if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) &&
            (chanPtr->curOutPtr->nextAdded > 0)) {
        chanPtr->flags |= BUFFER_READY;
    }
    
    result = FlushChannel(NULL, chanPtr, 0);
    if (result != 0) {
        return TCL_ERROR;
    }







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







|
|







4195
4196
4197
4198
4199
4200
4201
4202

























4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
Tcl_Flush(chan)
    Tcl_Channel chan;			/* The Channel to flush. */
{
    int result;				/* Of calling FlushChannel. */
    Channel *chanPtr;			/* The actual channel. */

    chanPtr = (Channel *) chan;
    if (CheckChannelErrors(chanPtr, TCL_WRITABLE) != 0) {

























	return -1;
    }

    /*
     * Force current output buffer to be output also.
     */
    
    if ((chanPtr->curOutPtr != NULL)
	    && (chanPtr->curOutPtr->nextAdded > 0)) {
        chanPtr->flags |= BUFFER_READY;
    }
    
    result = FlushChannel(NULL, chanPtr, 0);
    if (result != 0) {
        return TCL_ERROR;
    }
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
            ckfree((char *) chanPtr->saveInBufPtr);
            chanPtr->saveInBufPtr = (ChannelBuffer *) NULL;
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetInput --
 *
 *	Reads input data from a device or file into an input buffer.
 *
 * Results:
 *	A Posix error code or 0.

 *
 * Side effects:
 *	Reads from the underlying device.
 *
 *----------------------------------------------------------------------
 */

static int
GetInput(chanPtr)
    Channel *chanPtr;			/* Channel to read input from. */
{
    int toRead;				/* How much to read? */
    int result;				/* Of calling driver. */
    int nread;				/* How much was read from channel? */
    ChannelBuffer *bufPtr;		/* New buffer to add to input queue. */

    /*
     * Prevent reading from a dead channel -- a channel that has been closed
     * but not yet deallocated, which can happen if the exit handler for
     * channel cleanup has run but the channel is still registered in some
     * interpreter.
     */
    
    if (CheckForDeadChannel(NULL,chanPtr)) return EINVAL;



    /*
     * See if we can fill an existing buffer. If we can, read only
     * as much as will fit in it. Otherwise allocate a new buffer,
     * add it to the input queue and attempt to fill it to the max.
     */

    if ((chanPtr->inQueueTail != (ChannelBuffer *) NULL) &&
           (chanPtr->inQueueTail->nextAdded < chanPtr->inQueueTail->bufSize)) {
        bufPtr = chanPtr->inQueueTail;

        toRead = bufPtr->bufSize - bufPtr->nextAdded;
    } else {
	if (chanPtr->saveInBufPtr != (ChannelBuffer *) NULL) {
	    bufPtr = chanPtr->saveInBufPtr;
	    chanPtr->saveInBufPtr = (ChannelBuffer *) NULL;
	} else {
	    bufPtr = (ChannelBuffer *) ckalloc(
		((unsigned) CHANNELBUFFER_HEADER_SIZE + chanPtr->bufSize));
	    bufPtr->bufSize = chanPtr->bufSize;
	}
	bufPtr->nextRemoved = 0;
	bufPtr->nextAdded = 0;
        toRead = bufPtr->bufSize;
        if (chanPtr->inQueueTail == (ChannelBuffer *) NULL) {
            chanPtr->inQueueHead = bufPtr;
        } else {
            chanPtr->inQueueTail->nextPtr = bufPtr;
        }
        chanPtr->inQueueTail = bufPtr;
        bufPtr->nextPtr = (ChannelBuffer *) NULL;
    }
      
    /*
     * If EOF is set, we should avoid calling the driver because on some
     * platforms it is impossible to read from a device after EOF.
     */

    if (chanPtr->flags & CHANNEL_EOF) {
	return 0;
    }

    nread = (chanPtr->typePtr->inputProc) (chanPtr->instanceData,
	    bufPtr->buf + bufPtr->nextAdded, toRead, &result);

    if (nread == 0) {
	chanPtr->flags |= CHANNEL_EOF;
    } else if (nread < 0) {
	if ((result == EWOULDBLOCK) || (result == EAGAIN)) {
	    chanPtr->flags |= CHANNEL_BLOCKED;
	    result = EAGAIN;
	    if (chanPtr->flags & CHANNEL_NONBLOCKING) {
		Tcl_SetErrno(result);
	    } else {
		panic("Blocking channel driver did not block on input");
	    }
	} else {
	    Tcl_SetErrno(result);
	}
	return result;
    } else {
	bufPtr->nextAdded += nread;

	/*
	 * If we get a short read, signal up that we may be BLOCKED. We
	 * should avoid calling the driver because on some platforms we
	 * will block in the low level reading code even though the
	 * channel is set into nonblocking mode.
	 */
            
	if (nread < toRead) {
	    chanPtr->flags |= CHANNEL_BLOCKED;
	}
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * CopyAndTranslateBuffer --
 *
 *	Copy at most one buffer of input to the result space, doing
 *	eol translations according to mode in effect currently.
 *
 * Results:
 *	Number of characters (as opposed to bytes) copied. May return
 *	zero if no input is available to be translated.
 *
 * Side effects:
 *	Consumes buffered input. May deallocate one buffer.
 *
 *----------------------------------------------------------------------
 */

static int
CopyAndTranslateBuffer(chanPtr, result, space)
    Channel *chanPtr;		/* The channel from which to read input. */
    char *result;		/* Where to store the copied input. */
    int space;			/* How many bytes are available in result
                                 * to store the copied input? */
{
    int bytesInBuffer;		/* How many bytes are available to be
                                 * copied in the current input buffer? */
    int copied;			/* How many characters were already copied
                                 * into the destination space? */
    ChannelBuffer *bufPtr;	/* The buffer from which to copy bytes. */
    char curByte;		/* The byte we are currently translating. */
    int i;			/* Iterates over the copied input looking
                                 * for the input eofChar. */
    
    /*
     * If there is no input at all, return zero. The invariant is that either
     * there is no buffer in the queue, or if the first buffer is empty, it
     * is also the last buffer (and thus there is no input in the queue).
     * Note also that if the buffer is empty, we leave it in the queue.
     */
    
    if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) {
        return 0;
    }
    bufPtr = chanPtr->inQueueHead;
    bytesInBuffer = bufPtr->nextAdded - bufPtr->nextRemoved;
    if (bytesInBuffer < space) {
        space = bytesInBuffer;
    }
    copied = 0;
    switch (chanPtr->inputTranslation) {
        case TCL_TRANSLATE_LF:

            if (space == 0) {
                return 0;
            }
            
	    /*
             * Copy the current chunk into the result buffer.
             */

            memcpy((VOID *) result,
                    (VOID *)(bufPtr->buf + bufPtr->nextRemoved),
                    (size_t) space);
            bufPtr->nextRemoved += space;
            copied = space;
            break;

        case TCL_TRANSLATE_CR:

            if (space == 0) {
                return 0;
            }

	    /*
             * Copy the current chunk into the result buffer, then
             * replace all \r with \n.
             */

            memcpy((VOID *) result,
                    (VOID *)(bufPtr->buf + bufPtr->nextRemoved),
                    (size_t) space);
            bufPtr->nextRemoved += space;
            for (copied = 0; copied < space; copied++) {
                if (result[copied] == '\r') {
                    result[copied] = '\n';
                }
            }
            break;

        case TCL_TRANSLATE_CRLF:

            /*
             * If there is a held-back "\r" at EOF, produce it now.
             */
            
            if (space == 0) {
                if ((chanPtr->flags & (INPUT_SAW_CR | CHANNEL_EOF)) ==
                        (INPUT_SAW_CR | CHANNEL_EOF)) {
                    result[0] = '\r';
                    chanPtr->flags &= (~(INPUT_SAW_CR));
                    return 1;
                }
                return 0;
            }

            /*
             * Copy the current chunk and replace "\r\n" with "\n"
             * (but not standalone "\r"!).
             */

            for (copied = 0;
                     (copied < space) &&
                         (bufPtr->nextRemoved < bufPtr->nextAdded);
                     copied++) {
                curByte = bufPtr->buf[bufPtr->nextRemoved];
                bufPtr->nextRemoved++;
                if (curByte == '\r') {
                    if (chanPtr->flags & INPUT_SAW_CR) {
                        result[copied] = '\r';
                    } else {
                        chanPtr->flags |= INPUT_SAW_CR;
                        copied--;
                    }
                } else if (curByte == '\n') {
                    chanPtr->flags &= (~(INPUT_SAW_CR));
                    result[copied] = '\n';
                } else {
                    if (chanPtr->flags & INPUT_SAW_CR) {
                        chanPtr->flags &= (~(INPUT_SAW_CR));
                        result[copied] = '\r';
                        bufPtr->nextRemoved--;
                    } else {
                        result[copied] = curByte;
                    }
                }
            }
            break;
                
        case TCL_TRANSLATE_AUTO:
            
            if (space == 0) {
                return 0;
            }

            /*
             * Loop over the current buffer, converting "\r" and "\r\n"
             * to "\n".
             */

            for (copied = 0;
                     (copied < space) &&
                         (bufPtr->nextRemoved < bufPtr->nextAdded); ) {
                curByte = bufPtr->buf[bufPtr->nextRemoved];
                bufPtr->nextRemoved++;
                if (curByte == '\r') {
                    result[copied] = '\n';
		    copied++;
                    if (bufPtr->nextRemoved < bufPtr->nextAdded) {
                        if (bufPtr->buf[bufPtr->nextRemoved] == '\n') {
                            bufPtr->nextRemoved++;
                        }
                        chanPtr->flags &= (~(INPUT_SAW_CR));
                    } else {
                        chanPtr->flags |= INPUT_SAW_CR;
                    }
                } else {
                    if (curByte == '\n') {
                        if (!(chanPtr->flags & INPUT_SAW_CR)) {
                            result[copied] = '\n';
			    copied++;
                        }
                    } else {
                        result[copied] = curByte;
			copied++;
                    }
                    chanPtr->flags &= (~(INPUT_SAW_CR));
                }
            }
            break;

        default:
            panic("unknown eol translation mode");
    }

    /*
     * If an in-stream EOF character is set for this channel,, check that
     * the input we copied so far does not contain the EOF char. If it does,
     * copy only up to and excluding that character.
     */
    
    if (chanPtr->inEofChar != 0) {
        for (i = 0; i < copied; i++) {
            if (result[i] == (char) chanPtr->inEofChar) {
                break;
            }
        }
        if (i < copied) {

            /*
             * Set sticky EOF so that no further input is presented
             * to the caller.
             */
            
            chanPtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);

            /*
             * Reset the start of valid data in the input buffer to the
             * position of the eofChar, so that subsequent reads will
             * encounter it immediately. First we set it to the position
             * of the last byte consumed if all result bytes were the
             * product of one input byte; since it is possible that "\r\n"
             * contracted to "\n" in the result, we have to search back
             * from that position until we find the eofChar, because it
             * is possible that its actual position in the buffer is n
             * bytes further back (n is the number of "\r\n" sequences
             * that were contracted to "\n" in the result).
             */
                  
            bufPtr->nextRemoved -= (copied - i);
            while ((bufPtr->nextRemoved > 0) &&
                    (bufPtr->buf[bufPtr->nextRemoved] !=
                            (char) chanPtr->inEofChar)) {
                bufPtr->nextRemoved--;
            }
            copied = i;
        }
    }

    /*
     * If the current buffer is empty recycle it.
     */

    if (bufPtr->nextRemoved == bufPtr->nextAdded) {
        chanPtr->inQueueHead = bufPtr->nextPtr;
        if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) {
            chanPtr->inQueueTail = (ChannelBuffer *) NULL;
        }
        RecycleBuffer(chanPtr, bufPtr, 0);
    }

    /*
     * Return the number of characters copied into the result buffer.
     * This may be different from the number of bytes consumed, because
     * of EOL translations.
     */

    return copied;
}

/*
 *----------------------------------------------------------------------
 *
 * ScanBufferForEOL --
 *
 *	Scans one buffer for EOL according to the specified EOL
 *	translation mode. If it sees the input eofChar for the channel
 *	it stops also.
 *
 * Results:
 *	TRUE if EOL is found, FALSE otherwise. Also sets output parameter
 *	bytesToEOLPtr to the number of bytes so far to EOL, and crSeenPtr
 *	to whether a "\r" was seen.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ScanBufferForEOL(chanPtr, bufPtr, translation, eofChar, bytesToEOLPtr,
                 crSeenPtr)
    Channel *chanPtr;
    ChannelBuffer *bufPtr;		/* Buffer to scan for EOL. */
    Tcl_EolTranslation translation;	/* Translation mode to use. */
    int eofChar;			/* EOF char to look for. */
    int *bytesToEOLPtr;			/* Running counter. */
    int *crSeenPtr;			/* Has "\r" been seen? */
{
    char *rPtr;				/* Iterates over input string. */
    char *sPtr;				/* Where to stop search? */
    int EOLFound;
    int bytesToEOL;
    
    for (EOLFound = 0, rPtr = bufPtr->buf + bufPtr->nextRemoved,
             sPtr = bufPtr->buf + bufPtr->nextAdded,
             bytesToEOL = *bytesToEOLPtr;
             (!EOLFound) && (rPtr < sPtr);
             rPtr++) {
        switch (translation) {
            case TCL_TRANSLATE_AUTO:
                if ((*rPtr == (char) eofChar) && (eofChar != 0)) {
                    chanPtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
                    EOLFound = 1;
                } else if (*rPtr == '\n') {

		    /*
                     * CopyAndTranslateBuffer wants to know the length
                     * of the result, not the input. The input is one
                     * larger because "\r\n" shrinks to "\n".
                     */

                    if (!(*crSeenPtr)) {
                        bytesToEOL++;
			EOLFound = 1;
                    } else {

			/*
			 * This is a lf at the begining of a buffer
			 * where the previous buffer ended in a cr.
			 * Consume this lf because we've already emitted
			 * the newline for this crlf sequence. ALSO, if
                         * bytesToEOL is 0 (which means that we are at the
                         * first character of the scan), unset the
                         * INPUT_SAW_CR flag in the channel, because we
                         * already handled it; leaving it set would cause
                         * CopyAndTranslateBuffer to potentially consume
                         * another lf if one follows the current byte.
			 */

			bufPtr->nextRemoved++;
                        *crSeenPtr = 0;
                        chanPtr->flags &= (~(INPUT_SAW_CR));
		    }
                } else if (*rPtr == '\r') {
                    bytesToEOL++;
                    EOLFound = 1;
                } else {
                    *crSeenPtr = 0;
                    bytesToEOL++;
                }
                break;
            case TCL_TRANSLATE_LF:
                if ((*rPtr == (char) eofChar) && (eofChar != 0)) {
                    chanPtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
                    EOLFound = 1;
                } else {
                    if (*rPtr == '\n') {
                        EOLFound = 1;
                    }
                    bytesToEOL++;
                }
                break;
            case TCL_TRANSLATE_CR:
                if ((*rPtr == (char) eofChar) && (eofChar != 0)) {
                    chanPtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
                    EOLFound = 1;
                } else {
                    if (*rPtr == '\r') {
                        EOLFound = 1;
                    }
                    bytesToEOL++;
                }
                break;
            case TCL_TRANSLATE_CRLF:
                if ((*rPtr == (char) eofChar) && (eofChar != 0)) {
                    chanPtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
                    EOLFound = 1;
                } else if (*rPtr == '\n') {

                    /*
                     * CopyAndTranslateBuffer wants to know the length
                     * of the result, not the input. The input is one
                     * larger because crlf shrinks to lf.
                     */

                    if (*crSeenPtr) {
                        EOLFound = 1;
                    } else {
                        bytesToEOL++;
                    }
                } else {
                    if (*rPtr == '\r') {
                        *crSeenPtr = 1;
                    } else {
                        *crSeenPtr = 0;
                    }
                    bytesToEOL++;
                }
                break;
            default:
                panic("unknown eol translation mode");
        }
    }

    *bytesToEOLPtr = bytesToEOL;
    return EOLFound;
}

/*
 *----------------------------------------------------------------------
 *
 * ScanInputForEOL --
 *
 *	Scans queued input for chanPtr for an end of line (according to the
 *	current EOL translation mode) and returns the number of bytes
 *	upto and including the end of line, or -1 if none was found.
 *
 * Results:
 *	Count of bytes upto and including the end of line if one is present
 *	or -1 if none was found. Also returns in an output parameter the
 *	number of bytes queued if no end of line was found.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ScanInputForEOL(chanPtr, bytesQueuedPtr)
    Channel *chanPtr;	/* Channel for which to scan queued
                                 * input for end of line. */
    int *bytesQueuedPtr;	/* Where to store the number of bytes
                                 * currently queued if no end of line
                                 * was found. */
{
    ChannelBuffer *bufPtr;	/* Iterates over queued buffers. */
    int bytesToEOL;		/* How many bytes to end of line? */
    int EOLFound;		/* Did we find an end of line? */
    int crSeen;			/* Did we see a "\r" in CRLF mode? */

    *bytesQueuedPtr = 0;
    bytesToEOL = 0;
    EOLFound = 0;
    for (bufPtr = chanPtr->inQueueHead,
             crSeen = (chanPtr->flags & INPUT_SAW_CR) ? 1 : 0;
            (!EOLFound) && (bufPtr != (ChannelBuffer *) NULL);
            bufPtr = bufPtr->nextPtr) {
        EOLFound = ScanBufferForEOL(chanPtr, bufPtr, chanPtr->inputTranslation,
                chanPtr->inEofChar, &bytesToEOL, &crSeen);
    }

    if (EOLFound == 0) {
        *bytesQueuedPtr = bytesToEOL;
        return -1;
    }
    return bytesToEOL;        
}

/*
 *----------------------------------------------------------------------
 *
 * GetEOL --
 *
 *	Accumulate input into the channel input buffer queue until an
 *	end of line has been seen.
 *
 * Results:
 *	Number of bytes buffered (at least 1) or -1 on failure.
 *
 * Side effects:
 *	Consumes input from the channel.
 *
 *----------------------------------------------------------------------
 */

static int
GetEOL(chanPtr)
    Channel *chanPtr;	/* Channel to queue input on. */
{
    int bytesToEOL;		/* How many bytes in buffer up to and
                                 * including the end of line? */
    int bytesQueued;		/* How many bytes are queued currently
                                 * in the input chain of the channel? */

    /*
     * Check for unreported error.
     */

    if (chanPtr->unreportedError != 0) {
        Tcl_SetErrno(chanPtr->unreportedError);
        chanPtr->unreportedError = 0;
        return -1;
    }

    /*
     * Punt if the channel is not opened for reading.
     */

    if (!(chanPtr->flags & TCL_READABLE)) {
        Tcl_SetErrno(EACCES);
        return -1;
    }

    /*
     * If the channel is in the middle of a background copy, fail.
     */

    if (chanPtr->csPtr) {
	Tcl_SetErrno(EBUSY);
	return -1;
    }

    /*
     * If we have not encountered a sticky EOF, clear the EOF bit
     * (sticky EOF is set if we have seen the input eofChar, to prevent
     * reading beyond the eofChar). Also, always clear the BLOCKED bit.
     * We want to discover these conditions anew in each operation.
     */
    
    if (!(chanPtr->flags & CHANNEL_STICKY_EOF)) {
        chanPtr->flags &= (~(CHANNEL_EOF));
    }
    chanPtr->flags &= (~(CHANNEL_BLOCKED | CHANNEL_GETS_BLOCKED));

    while (1) {
        bytesToEOL = ScanInputForEOL(chanPtr, &bytesQueued);
        if (bytesToEOL > 0) {
            chanPtr->flags &= (~(CHANNEL_BLOCKED));
            return bytesToEOL;
        }
        if (chanPtr->flags & CHANNEL_EOF) {
	    /*
	     * Boundary case where cr was at the end of the previous buffer
	     * and this buffer just has a newline.  At EOF our caller wants
	     * to see -1 for the line length.
	     */
            return (bytesQueued == 0) ? -1 : bytesQueued ;
        }
        if (chanPtr->flags & CHANNEL_BLOCKED) {
            if (chanPtr->flags & CHANNEL_NONBLOCKING) {
		goto blocked;
            }
            chanPtr->flags &= (~(CHANNEL_BLOCKED));
        }
	if (GetInput(chanPtr) != 0) {
	    goto blocked;
        }
    }

    blocked:

    /*
     * We didn't get a complete line so we need to indicate to UpdateInterest
     * that the gets blocked.  It will wait for more data instead of firing
     * a timer, avoiding a busy wait.  This is where we are assuming that the
     * next operation is a gets.  No more file events will be delivered on 
     * this channel until new data arrives or some operation is performed
     * on the channel (e.g. gets, read, fconfigure) that changes the blocking
     * state.  Note that this means a file event will not be delivered even
     * though a read would be able to consume the buffered data.
     */

    chanPtr->flags |= CHANNEL_GETS_BLOCKED;
    return -1;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Read --
 *
 *	Reads a given number of characters from a channel.
 *
 * Results:
 *	The number of characters read, or -1 on error. Use Tcl_GetErrno()
 *	to retrieve the error code for the error that occurred.
 *
 * Side effects:
 *	May cause input to be buffered.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Read(chan, bufPtr, toRead)
    Tcl_Channel chan;		/* The channel from which to read. */
    char *bufPtr;		/* Where to store input read. */
    int toRead;			/* Maximum number of characters to read. */
{
    Channel *chanPtr;		/* The real IO channel. */
    
    chanPtr = (Channel *) chan;

    /*
     * Check for unreported error.
     */

    if (chanPtr->unreportedError != 0) {
        Tcl_SetErrno(chanPtr->unreportedError);
        chanPtr->unreportedError = 0;
        return -1;
    }

    /*
     * Punt if the channel is not opened for reading.
     */

    if (!(chanPtr->flags & TCL_READABLE)) {
        Tcl_SetErrno(EACCES);
        return -1;
    }
    
    /*
     * If the channel is in the middle of a background copy, fail.
     */

    if (chanPtr->csPtr) {
	Tcl_SetErrno(EBUSY);
	return -1;
    }

    return DoRead(chanPtr, bufPtr, toRead);
}

/*
 *----------------------------------------------------------------------
 *
 * DoRead --
 *
 *	Reads a given number of characters from a channel.
 *
 * Results:
 *	The number of characters read, or -1 on error. Use Tcl_GetErrno()
 *	to retrieve the error code for the error that occurred.
 *
 * Side effects:
 *	May cause input to be buffered.
 *
 *----------------------------------------------------------------------
 */

static int
DoRead(chanPtr, bufPtr, toRead)
    Channel *chanPtr;		/* The channel from which to read. */
    char *bufPtr;		/* Where to store input read. */
    int toRead;			/* Maximum number of characters to read. */
{
    int copied;			/* How many characters were copied into
                                 * the result string? */
    int copiedNow;		/* How many characters were copied from
                                 * the current input buffer? */
    int result;			/* Of calling GetInput. */
    
    /*
     * If we have not encountered a sticky EOF, clear the EOF bit. Either
     * way clear the BLOCKED bit. We want to discover these anew during
     * each operation.
     */

    if (!(chanPtr->flags & CHANNEL_STICKY_EOF)) {
        chanPtr->flags &= (~(CHANNEL_EOF));
    }
    chanPtr->flags &= (~(CHANNEL_BLOCKED | CHANNEL_GETS_BLOCKED));
    
    for (copied = 0; copied < toRead; copied += copiedNow) {
        copiedNow = CopyAndTranslateBuffer(chanPtr, bufPtr + copied,
                toRead - copied);
        if (copiedNow == 0) {
            if (chanPtr->flags & CHANNEL_EOF) {
                return copied;
            }
            if (chanPtr->flags & CHANNEL_BLOCKED) {
                if (chanPtr->flags & CHANNEL_NONBLOCKING) {
                    return copied;
                }
                chanPtr->flags &= (~(CHANNEL_BLOCKED));
            }
            result = GetInput(chanPtr);
            if (result != 0) {
                if (result == EAGAIN) {
                    return copied;
                }
                return -1;
            }
        }
    }
    chanPtr->flags &= (~(CHANNEL_BLOCKED));
    return copied;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Gets --
 *
 *	Reads a complete line of input from the channel into a
 *	Tcl_DString.
 *
 * Results:
 *	Length of line read or -1 if error, EOF or blocked. If -1, use
 *	Tcl_GetErrno() to retrieve the POSIX error code for the
 *	error or condition that occurred.
 *
 * Side effects:
 *	May flush output on the channel. May cause input to be
 *	consumed from the channel.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Gets(chan, lineRead)
    Tcl_Channel chan;		/* Channel from which to read. */
    Tcl_DString *lineRead;	/* The characters of the line read
                                 * (excluding the terminating newline if
                                 * present) will be appended to this
                                 * DString. The caller must have initialized
                                 * it and is responsible for managing the
                                 * storage. */
{
    Channel *chanPtr;		/* The channel to read from. */
    char *buf;			/* Points into DString where data
                                 * will be stored. */
    int offset;			/* Offset from start of DString at
                                 * which to append the line just read. */
    int copiedTotal;		/* Accumulates total length of input copied. */
    int copiedNow;		/* How many bytes were copied from the
                                 * current input buffer? */
    int lineLen;		/* Length of line read, including the
                                 * translated newline. If this is zero
                                 * and neither EOF nor BLOCKED is set,
                                 * the current line is empty. */
    
    chanPtr = (Channel *) chan;

    lineLen = GetEOL(chanPtr);
    if (lineLen < 0) {
        return -1;
    }
    offset = Tcl_DStringLength(lineRead);
    Tcl_DStringSetLength(lineRead, lineLen + offset);
    buf = Tcl_DStringValue(lineRead) + offset;

    for (copiedTotal = 0; copiedTotal < lineLen; copiedTotal += copiedNow) {
        copiedNow = CopyAndTranslateBuffer(chanPtr, buf + copiedTotal,
                lineLen - copiedTotal);
    }
    if ((copiedTotal > 0) && (buf[copiedTotal - 1] == '\n')) {
        copiedTotal--;
    }
    Tcl_DStringSetLength(lineRead, copiedTotal + offset);
    return copiedTotal;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetsObj --
 *
 *	Reads a complete line of input from the channel into a
 *	string object.
 *
 * Results:
 *	Length of line read or -1 if error, EOF or blocked. If -1, use
 *	Tcl_GetErrno() to retrieve the POSIX error code for the
 *	error or condition that occurred.
 *
 * Side effects:
 *	May flush output on the channel. May cause input to be
 *	consumed from the channel.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetsObj(chan, objPtr)
    Tcl_Channel chan;		/* Channel from which to read. */
    Tcl_Obj *objPtr;		/* The characters of the line read
                                 * (excluding the terminating newline if
                                 * present) will be appended to this
                                 * object. The caller must have initialized
                                 * it and is responsible for managing the
                                 * storage. */
{
    Channel *chanPtr;		/* The channel to read from. */
    char *buf;			/* Points into DString where data
                                 * will be stored. */
    int offset;			/* Offset from start of DString at
                                 * which to append the line just read. */
    int copiedTotal;		/* Accumulates total length of input copied. */
    int copiedNow;		/* How many bytes were copied from the
                                 * current input buffer? */
    int lineLen;		/* Length of line read, including the
                                 * translated newline. If this is zero
                                 * and neither EOF nor BLOCKED is set,
                                 * the current line is empty. */
    
    chanPtr = (Channel *) chan;

    lineLen = GetEOL(chanPtr);
    if (lineLen < 0) {
        return -1;
    }
    (void) Tcl_GetStringFromObj(objPtr, &offset);
    Tcl_SetObjLength(objPtr, lineLen + offset);
    buf = Tcl_GetStringFromObj(objPtr, NULL) + offset;

    for (copiedTotal = 0; copiedTotal < lineLen; copiedTotal += copiedNow) {
        copiedNow = CopyAndTranslateBuffer(chanPtr, buf + copiedTotal,
                lineLen - copiedTotal);
    }
    if ((copiedTotal > 0) && (buf[copiedTotal - 1] == '\n')) {
        copiedTotal--;
    }
    Tcl_SetObjLength(objPtr, copiedTotal + offset);
    return copiedTotal;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Ungets --
 *
 *	Causes the supplied string to be added to the input queue of
 *	the channel, at either the head or tail of the queue.
 *
 * Results:
 *	The number of bytes stored in the channel, or -1 on error.
 *
 * Side effects:
 *	Adds input to the input queue of a channel.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Ungets(chan, str, len, atEnd)
    Tcl_Channel chan;		/* The channel for which to add the input. */
    char *str;			/* The input itself. */
    int len;			/* The length of the input. */
    int atEnd;			/* If non-zero, add at end of queue; otherwise
                                 * add at head of queue. */    
{
    Channel *chanPtr;		/* The real IO channel. */
    ChannelBuffer *bufPtr;	/* Buffer to contain the data. */
    int i;

    chanPtr = (Channel *) chan;

    /*
     * Check for unreported error.
     */

    if (chanPtr->unreportedError != 0) {
        Tcl_SetErrno(chanPtr->unreportedError);
        chanPtr->unreportedError = 0;
        return -1;
    }

    /*
     * Punt if the channel is not opened for reading.
     */

    if (!(chanPtr->flags & TCL_READABLE)) {
        Tcl_SetErrno(EACCES);
        return -1;
    }

    /*
     * If the channel is in the middle of a background copy, fail.
     */

    if (chanPtr->csPtr) {
	Tcl_SetErrno(EBUSY);
	return -1;
    }

    /*
     * If we have encountered a sticky EOF, just punt without storing.
     * (sticky EOF is set if we have seen the input eofChar, to prevent
     * reading beyond the eofChar). Otherwise, clear the EOF flags, and
     * clear the BLOCKED bit. We want to discover these conditions anew
     * in each operation.
     */

    if (chanPtr->flags & CHANNEL_STICKY_EOF) {
        return len;
    }
    chanPtr->flags &= (~(CHANNEL_BLOCKED | CHANNEL_EOF));

    bufPtr = (ChannelBuffer *) ckalloc((unsigned)
            (CHANNELBUFFER_HEADER_SIZE + len));
    for (i = 0; i < len; i++) {
        bufPtr->buf[i] = str[i];
    }
    bufPtr->bufSize = len;
    bufPtr->nextAdded = len;
    bufPtr->nextRemoved = 0;

    if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) {
        bufPtr->nextPtr = (ChannelBuffer *) NULL;
        chanPtr->inQueueHead = bufPtr;
        chanPtr->inQueueTail = bufPtr;
    } else if (atEnd) {
        bufPtr->nextPtr = (ChannelBuffer *) NULL;
        chanPtr->inQueueTail->nextPtr = bufPtr;
        chanPtr->inQueueTail = bufPtr;
    } else {
        bufPtr->nextPtr = chanPtr->inQueueHead;
        chanPtr->inQueueHead = bufPtr;
    }

    return len;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Seek --
 *







|



|


|
>




|




|

|
|
|
|








|
>
>







<
<
|
>
|

<
|
|
<
|
|
<

|
|
|
|





<











|


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












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







4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331

4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346















4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358




























































































































4359












































































































































































4360


4361









4362
4363













































































































































































































































4364


















































































































4365










4366















































































































































































4367
4368
4369



















4370


























4371
4372
4373
4374
4375
4376
4377
            ckfree((char *) chanPtr->saveInBufPtr);
            chanPtr->saveInBufPtr = (ChannelBuffer *) NULL;
        }
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * GetInput --
 *
 *	Reads input data from a device into a channel buffer.  
 *
 * Results:
 *	The return value is the Posix error code if an error occurred while
 *	reading from the file, or 0 otherwise.  
 *
 * Side effects:
 *	Reads from the underlying device.
 *
 *---------------------------------------------------------------------------
 */

static int
GetInput(chanPtr)
    Channel *chanPtr;		/* Channel to read input from. */
{
    int toRead;			/* How much to read? */
    int result;			/* Of calling driver. */
    int nread;			/* How much was read from channel? */
    ChannelBuffer *bufPtr;	/* New buffer to add to input queue. */

    /*
     * Prevent reading from a dead channel -- a channel that has been closed
     * but not yet deallocated, which can happen if the exit handler for
     * channel cleanup has run but the channel is still registered in some
     * interpreter.
     */
    
    if (CheckForDeadChannel(NULL, chanPtr)) {
	return EINVAL;
    }

    /*
     * See if we can fill an existing buffer. If we can, read only
     * as much as will fit in it. Otherwise allocate a new buffer,
     * add it to the input queue and attempt to fill it to the max.
     */



    bufPtr = chanPtr->inQueueTail;
    if ((bufPtr != NULL) && (bufPtr->nextAdded < bufPtr->bufLength)) {
        toRead = bufPtr->bufLength - bufPtr->nextAdded;
    } else {

	bufPtr = chanPtr->saveInBufPtr;
	chanPtr->saveInBufPtr = NULL;

	if (bufPtr == NULL) {
	    bufPtr = AllocChannelBuffer(chanPtr->bufSize);

	}
        bufPtr->nextPtr = (ChannelBuffer *) NULL;

        toRead = chanPtr->bufSize;
        if (chanPtr->inQueueTail == NULL) {
            chanPtr->inQueueHead = bufPtr;
        } else {
            chanPtr->inQueueTail->nextPtr = bufPtr;
        }
        chanPtr->inQueueTail = bufPtr;

    }
      
    /*
     * If EOF is set, we should avoid calling the driver because on some
     * platforms it is impossible to read from a device after EOF.
     */

    if (chanPtr->flags & CHANNEL_EOF) {
	return 0;
    }

    nread = (*chanPtr->typePtr->inputProc)(chanPtr->instanceData,
	    bufPtr->buf + bufPtr->nextAdded, toRead, &result);

    if (nread > 0) {















	bufPtr->nextAdded += nread;

	/*
	 * If we get a short read, signal up that we may be BLOCKED. We
	 * should avoid calling the driver because on some platforms we
	 * will block in the low level reading code even though the
	 * channel is set into nonblocking mode.
	 */
            
	if (nread < toRead) {
	    chanPtr->flags |= CHANNEL_BLOCKED;
	}




























































































































    } else if (nread == 0) {












































































































































































	chanPtr->flags |= CHANNEL_EOF;


	chanPtr->inputEncodingFlags |= TCL_ENCODING_END;









    } else if (nread < 0) {
	if ((result == EWOULDBLOCK) || (result == EAGAIN)) {













































































































































































































































	    chanPtr->flags |= CHANNEL_BLOCKED;


















































































































	    result = EAGAIN;










	}















































































































































































	Tcl_SetErrno(result);
	return result;
    } 



















    return 0;


























}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Seek --
 *
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
    int result;			/* Of device driver operations. */
    int curPos;			/* Position on the device. */
    int wasAsync;		/* Was the channel nonblocking before the
                                 * seek operation? If so, must restore to
                                 * nonblocking mode after the seek. */

    chanPtr = (Channel *) chan;

    /*
     * Check for unreported error.
     */

    if (chanPtr->unreportedError != 0) {
        Tcl_SetErrno(chanPtr->unreportedError);
        chanPtr->unreportedError = 0;
        return -1;
    }

    /*
     * Disallow seek on channels that are open for neither writing nor
     * reading (e.g. socket server channels).
     */

    if (!(chanPtr->flags & (TCL_WRITABLE|TCL_READABLE))) {
        Tcl_SetErrno(EACCES);
        return -1;
    }

    /*
     * If the channel is in the middle of a background copy, fail.
     */

    if (chanPtr->csPtr) {
	Tcl_SetErrno(EBUSY);
	return -1;
    }

    /*
     * Disallow seek on dead channels -- channels that have been closed but
     * not yet been deallocated. Such channels can be found if the exit
     * handler for channel cleanup has run but the channel is still







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







4400
4401
4402
4403
4404
4405
4406
4407


























4408
4409
4410
4411
4412
4413
4414
    int result;			/* Of device driver operations. */
    int curPos;			/* Position on the device. */
    int wasAsync;		/* Was the channel nonblocking before the
                                 * seek operation? If so, must restore to
                                 * nonblocking mode after the seek. */

    chanPtr = (Channel *) chan;
    if (CheckChannelErrors(chanPtr, TCL_WRITABLE | TCL_READABLE) != 0) {


























	return -1;
    }

    /*
     * Disallow seek on dead channels -- channels that have been closed but
     * not yet been deallocated. Such channels can be found if the exit
     * handler for channel cleanup has run but the channel is still
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
    Channel *chanPtr;			/* The actual channel to tell on. */
    ChannelBuffer *bufPtr;
    int inputBuffered, outputBuffered;
    int result;				/* Of calling device driver. */
    int curPos;				/* Position on device. */

    chanPtr = (Channel *) chan;

    /*
     * Check for unreported error.
     */

    if (chanPtr->unreportedError != 0) {
        Tcl_SetErrno(chanPtr->unreportedError);
        chanPtr->unreportedError = 0;
        return -1;
    }

    /*
     * Disallow tell on dead channels -- channels that have been closed but
     * not yet been deallocated. Such channels can be found if the exit
     * handler for channel cleanup has run but the channel is still
     * registered in an interpreter.
     */

    if (CheckForDeadChannel(NULL,chanPtr)) return -1;

    /*
     * Disallow tell on channels that are open for neither
     * writing nor reading (e.g. socket server channels).
     */

    if (!(chanPtr->flags & (TCL_WRITABLE|TCL_READABLE))) {
        Tcl_SetErrno(EACCES);
        return -1;
    }

    /*
     * If the channel is in the middle of a background copy, fail.
     */

    if (chanPtr->csPtr) {
	Tcl_SetErrno(EBUSY);
	return -1;
    }

    /*
     * Disallow tell on channels whose type does not have a seek procedure
     * defined. This means that the channel does not support seeking.
     */







|
<
<
<
<
<
<
<
|









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







4576
4577
4578
4579
4580
4581
4582
4583







4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594

















4595
4596
4597
4598
4599
4600
4601
    Channel *chanPtr;			/* The actual channel to tell on. */
    ChannelBuffer *bufPtr;
    int inputBuffered, outputBuffered;
    int result;				/* Of calling device driver. */
    int curPos;				/* Position on device. */

    chanPtr = (Channel *) chan;
    if (CheckChannelErrors(chanPtr, TCL_WRITABLE | TCL_READABLE) != 0) {







	return -1;
    }

    /*
     * Disallow tell on dead channels -- channels that have been closed but
     * not yet been deallocated. Such channels can be found if the exit
     * handler for channel cleanup has run but the channel is still
     * registered in an interpreter.
     */

    if (CheckForDeadChannel(NULL,chanPtr)) {

















	return -1;
    }

    /*
     * Disallow tell on channels whose type does not have a seek procedure
     * defined. This means that the channel does not support seeking.
     */
3710
3711
3712
3713
3714
3715
3716





































































3717
3718
3719
3720
3721
3722
3723
        return -1;
    }
    if (inputBuffered != 0) {
        return (curPos - inputBuffered);
    }
    return (curPos + outputBuffered);
}






































































/*
 *----------------------------------------------------------------------
 *
 * Tcl_Eof --
 *
 *	Returns 1 if the channel is at EOF, 0 otherwise.







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







4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
        return -1;
    }
    if (inputBuffered != 0) {
        return (curPos - inputBuffered);
    }
    return (curPos + outputBuffered);
}

/*
 *---------------------------------------------------------------------------
 *
 * CheckChannelErrors --
 *
 *	See if the channel is in an ready state and can perform the
 *	desired operation.
 *
 * Results:
 *	The return value is 0 if the channel is OK, otherwise the
 *	return value is -1 and errno is set to indicate the error.
 *
 * Side effects:
 *	May clear the EOF and/or BLOCKED bits if reading from channel.
 *
 *---------------------------------------------------------------------------
 */
 
static int
CheckChannelErrors(chanPtr, direction)
    Channel *chanPtr;	    /* Channel to check. */
    int direction;	    /* Test if channel supports desired operation:
			     * TCL_READABLE, TCL_WRITABLE. */
{
    /*
     * Check for unreported error.
     */

    if (chanPtr->unreportedError != 0) {
        Tcl_SetErrno(chanPtr->unreportedError);
        chanPtr->unreportedError = 0;
        return -1;
    }

    /*
     * Fail if the channel is not opened for desired operation.
     */

    if ((chanPtr->flags & direction) == 0) {
        Tcl_SetErrno(EACCES);
        return -1;
    }

    /*
     * Fail if the channel is in the middle of a background copy.
     */

    if (chanPtr->csPtr != NULL) {
	Tcl_SetErrno(EBUSY);
	return -1;
    }

    if (direction == TCL_READABLE) {
	/*
	 * If we have not encountered a sticky EOF, clear the EOF bit
	 * (sticky EOF is set if we have seen the input eofChar, to prevent
	 * reading beyond the eofChar). Also, always clear the BLOCKED bit.
	 * We want to discover these conditions anew in each operation.
	 */
	
	if ((chanPtr->flags & CHANNEL_STICKY_EOF) == 0) {
	    chanPtr->flags &= ~CHANNEL_EOF;
	}
	chanPtr->flags &= ~(CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA);
    }

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Eof --
 *
 *	Returns 1 if the channel is at EOF, 0 otherwise.
3839
3840
3841
3842
3843
3844
3845









3846
3847
3848
3849
3850
3851
3852
    }
    if (sz > (1024 * 1024)) {
        return;
    }

    chanPtr = (Channel *) chan;
    chanPtr->bufSize = sz;









}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetChannelBufferSize --
 *







>
>
>
>
>
>
>
>
>







4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
    }
    if (sz > (1024 * 1024)) {
        return;
    }

    chanPtr = (Channel *) chan;
    chanPtr->bufSize = sz;

    if (chanPtr->outputStage != NULL) {
	ckfree((char *) chanPtr->outputStage);
	chanPtr->outputStage = NULL;
    }
    if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) {
	chanPtr->outputStage = (char *)
		ckalloc((unsigned) (chanPtr->bufSize + 2));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetChannelBufferSize --
 *
4043
4044
4045
4046
4047
4048
4049
4050
















4051
4052
4053
4054
4055
4056
4057
        TclFormatInt(optionVal, chanPtr->bufSize);
        Tcl_DStringAppendElement(dsPtr, optionVal);
        if (len > 0) {
            return TCL_OK;
        }
    }
    if ((len == 0) ||
            ((len > 1) && (optionName[1] == 'e') &&
















                    (strncmp(optionName, "-eofchar", len) == 0))) {
        if (len == 0) {
            Tcl_DStringAppendElement(dsPtr, "-eofchar");
        }
        if (((flags & (TCL_READABLE|TCL_WRITABLE)) ==
                (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) {
            Tcl_DStringStartSublist(dsPtr);







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







5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
        TclFormatInt(optionVal, chanPtr->bufSize);
        Tcl_DStringAppendElement(dsPtr, optionVal);
        if (len > 0) {
            return TCL_OK;
        }
    }
    if ((len == 0) ||
	    ((len > 2) && (optionName[1] == 'e') &&
		    (strncmp(optionName, "-encoding", len) == 0))) {
	if (len == 0) {
	    Tcl_DStringAppendElement(dsPtr, "-encoding");
	}
	if (chanPtr->encoding == NULL) {
	    Tcl_DStringAppendElement(dsPtr, "binary");
	} else {
	    Tcl_DStringAppendElement(dsPtr,
		    Tcl_GetEncodingName(chanPtr->encoding));
	}
	if (len > 0) {
	    return TCL_OK;
	}
    }
    if ((len == 0) ||
            ((len > 2) && (optionName[1] == 'e') &&
                    (strncmp(optionName, "-eofchar", len) == 0))) {
        if (len == 0) {
            Tcl_DStringAppendElement(dsPtr, "-eofchar");
        }
        if (((flags & (TCL_READABLE|TCL_WRITABLE)) ==
                (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) {
            Tcl_DStringStartSublist(dsPtr);
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
            return TCL_OK;
        }
	return Tcl_BadChannelOption(interp, optionName, NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetChannelOption --
 *
 *	Sets an option on a channel.
 *
 * Results:
 *	A standard Tcl result. Also sets interp->result on error if
 *	interp is not NULL.
 *
 * Side effects:
 *	May modify an option on a device.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_SetChannelOption(interp, chan, optionName, newValue)
    Tcl_Interp *interp;		/* For error reporting - can be NULL. */
    Tcl_Channel chan;		/* Channel on which to set mode. */
    char *optionName;		/* Which option to set? */







|






|
|




|







5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
            return TCL_OK;
        }
	return Tcl_BadChannelOption(interp, optionName, NULL);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_SetChannelOption --
 *
 *	Sets an option on a channel.
 *
 * Results:
 *	A standard Tcl result.  On error, sets interp's result object
 *	if interp is not NULL.
 *
 * Side effects:
 *	May modify an option on a device.
 *
 *---------------------------------------------------------------------------
 */

int
Tcl_SetChannelOption(interp, chan, optionName, newValue)
    Tcl_Interp *interp;		/* For error reporting - can be NULL. */
    Tcl_Channel chan;		/* Channel on which to set mode. */
    char *optionName;		/* Which option to set? */
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
        }
        if (newMode) {
            newMode = TCL_MODE_BLOCKING;
        } else {
            newMode = TCL_MODE_NONBLOCKING;
        }
	return SetBlockMode(interp, chanPtr, newMode);
    }

    if ((len > 7) && (optionName[1] == 'b') &&
            (strncmp(optionName, "-buffering", len) == 0)) {
        len = strlen(newValue);
        if ((newValue[0] == 'f') && (strncmp(newValue, "full", len) == 0)) {
            chanPtr->flags &=
                (~(CHANNEL_UNBUFFERED|CHANNEL_LINEBUFFERED));
        } else if ((newValue[0] == 'l') &&
                (strncmp(newValue, "line", len) == 0)) {







<
<
|







5236
5237
5238
5239
5240
5241
5242


5243
5244
5245
5246
5247
5248
5249
5250
        }
        if (newMode) {
            newMode = TCL_MODE_BLOCKING;
        } else {
            newMode = TCL_MODE_NONBLOCKING;
        }
	return SetBlockMode(interp, chanPtr, newMode);


    } else if ((len > 7) && (optionName[1] == 'b') &&
            (strncmp(optionName, "-buffering", len) == 0)) {
        len = strlen(newValue);
        if ((newValue[0] == 'f') && (strncmp(newValue, "full", len) == 0)) {
            chanPtr->flags &=
                (~(CHANNEL_UNBUFFERED|CHANNEL_LINEBUFFERED));
        } else if ((newValue[0] == 'l') &&
                (strncmp(newValue, "line", len) == 0)) {
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247









4248
4249
4250








4251
4252
4253
4254
4255
4256
4257
4258
            if (interp) {
                Tcl_AppendResult(interp, "bad value for -buffering: ",
                        "must be one of full, line, or none",
                        (char *) NULL);
                return TCL_ERROR;
            }
        }
        return TCL_OK;
    }

    if ((len > 7) && (optionName[1] == 'b') &&
            (strncmp(optionName, "-buffersize", len) == 0)) {
        chanPtr->bufSize = atoi(newValue);
        if ((chanPtr->bufSize < 10) || (chanPtr->bufSize > (1024 * 1024))) {
            chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE;
        }









        return TCL_OK;
    }
    








    if ((len > 1) && (optionName[1] == 'e') &&
            (strncmp(optionName, "-eofchar", len) == 0)) {
        if (Tcl_SplitList(interp, newValue, &argc, &argv) == TCL_ERROR) {
            return TCL_ERROR;
        }
        if (argc == 0) {
            chanPtr->inEofChar = 0;
            chanPtr->outEofChar = 0;







|
<
<
|

|



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







5258
5259
5260
5261
5262
5263
5264
5265


5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
            if (interp) {
                Tcl_AppendResult(interp, "bad value for -buffering: ",
                        "must be one of full, line, or none",
                        (char *) NULL);
                return TCL_ERROR;
            }
        }
	return TCL_OK;


    } else if ((len > 7) && (optionName[1] == 'b') &&
            (strncmp(optionName, "-buffersize", len) == 0)) {
        chanPtr->bufSize = atoi(newValue);	/* INTL: "C", UTF safe. */
        if ((chanPtr->bufSize < 10) || (chanPtr->bufSize > (1024 * 1024))) {
            chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE;
        }
    } else if ((len > 2) && (optionName[1] == 'e') &&
	    (strncmp(optionName, "-encoding", len) == 0)) {
	Tcl_Encoding encoding;

	if ((newValue[0] == '\0') || (strcmp(newValue, "binary") == 0)) {
	    encoding = NULL;
	} else {
	    encoding = Tcl_GetEncoding(interp, newValue);
	    if (encoding == NULL) {
		return TCL_ERROR;
	    }
	}
	Tcl_FreeEncoding(chanPtr->encoding);
	chanPtr->encoding = encoding;
	chanPtr->inputEncodingState = NULL;
	chanPtr->inputEncodingFlags = TCL_ENCODING_START;
	chanPtr->outputEncodingState = NULL;
	chanPtr->outputEncodingFlags = TCL_ENCODING_START;
	chanPtr->flags &= ~CHANNEL_NEED_MORE_DATA;
	UpdateInterest(chanPtr);
    } else if ((len > 2) && (optionName[1] == 'e') &&
            (strncmp(optionName, "-eofchar", len) == 0)) {
        if (Tcl_SplitList(interp, newValue, &argc, &argv) == TCL_ERROR) {
            return TCL_ERROR;
        }
        if (argc == 0) {
            chanPtr->inEofChar = 0;
            chanPtr->outEofChar = 0;
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
            if (chanPtr->flags & TCL_WRITABLE) {
                chanPtr->outEofChar = (int) argv[1][0];
            }
        }
        if (argv != (char **) NULL) {
            ckfree((char *) argv);
        }
        return TCL_OK;
    }

    if ((len > 1) && (optionName[1] == 't') &&
            (strncmp(optionName, "-translation", len) == 0)) {
	char *readMode, *writeMode;

        if (Tcl_SplitList(interp, newValue, &argc, &argv) == TCL_ERROR) {
            return TCL_ERROR;
        }








|
<
<
|







5319
5320
5321
5322
5323
5324
5325
5326


5327
5328
5329
5330
5331
5332
5333
5334
            if (chanPtr->flags & TCL_WRITABLE) {
                chanPtr->outEofChar = (int) argv[1][0];
            }
        }
        if (argv != (char **) NULL) {
            ckfree((char *) argv);
        }
	return TCL_OK;


    } else if ((len > 1) && (optionName[1] == 't') &&
            (strncmp(optionName, "-translation", len) == 0)) {
	char *readMode, *writeMode;

        if (Tcl_SplitList(interp, newValue, &argc, &argv) == TCL_ERROR) {
            return TCL_ERROR;
        }

4311
4312
4313
4314
4315
4316
4317

4318

4319
4320
4321
4322
4323
4324
4325
4326

	if (readMode) {
	    if (*readMode == '\0') {
		newMode = chanPtr->inputTranslation;
	    } else if (strcmp(readMode, "auto") == 0) {
		newMode = TCL_TRANSLATE_AUTO;
	    } else if (strcmp(readMode, "binary") == 0) {

		chanPtr->inEofChar = 0;

		newMode = TCL_TRANSLATE_LF;
	    } else if (strcmp(readMode, "lf") == 0) {
		newMode = TCL_TRANSLATE_LF;
	    } else if (strcmp(readMode, "cr") == 0) {
		newMode = TCL_TRANSLATE_CR;
	    } else if (strcmp(readMode, "crlf") == 0) {
		newMode = TCL_TRANSLATE_CRLF;
	    } else if (strcmp(readMode, "platform") == 0) {







>

>
|







5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367

	if (readMode) {
	    if (*readMode == '\0') {
		newMode = chanPtr->inputTranslation;
	    } else if (strcmp(readMode, "auto") == 0) {
		newMode = TCL_TRANSLATE_AUTO;
	    } else if (strcmp(readMode, "binary") == 0) {
		newMode = TCL_TRANSLATE_LF;
		chanPtr->inEofChar = 0;
		Tcl_FreeEncoding(chanPtr->encoding);		    
		chanPtr->encoding = NULL;
	    } else if (strcmp(readMode, "lf") == 0) {
		newMode = TCL_TRANSLATE_LF;
	    } else if (strcmp(readMode, "cr") == 0) {
		newMode = TCL_TRANSLATE_CR;
	    } else if (strcmp(readMode, "crlf") == 0) {
		newMode = TCL_TRANSLATE_CRLF;
	    } else if (strcmp(readMode, "platform") == 0) {
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
	     * data to see if the new translation mode allows us to
	     * complete the line.
	     */

	    if (newMode != chanPtr->inputTranslation) {
		chanPtr->inputTranslation = (Tcl_EolTranslation) newMode;
		chanPtr->flags &= ~(INPUT_SAW_CR);
		chanPtr->flags &= ~(CHANNEL_GETS_BLOCKED);
		UpdateInterest(chanPtr);
	    }
	}
	if (writeMode) {
	    if (*writeMode == '\0') {
		/* Do nothing. */
	    } else if (strcmp(writeMode, "auto") == 0) {







|







5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
	     * data to see if the new translation mode allows us to
	     * complete the line.
	     */

	    if (newMode != chanPtr->inputTranslation) {
		chanPtr->inputTranslation = (Tcl_EolTranslation) newMode;
		chanPtr->flags &= ~(INPUT_SAW_CR);
		chanPtr->flags &= ~(CHANNEL_NEED_MORE_DATA);
		UpdateInterest(chanPtr);
	    }
	}
	if (writeMode) {
	    if (*writeMode == '\0') {
		/* Do nothing. */
	    } else if (strcmp(writeMode, "auto") == 0) {
4364
4365
4366
4367
4368
4369
4370


4371
4372
4373
4374
4375
4376
4377
		    chanPtr->outputTranslation = TCL_TRANSLATE_CRLF;
		} else {
		    chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION;
		}
	    } else if (strcmp(writeMode, "binary") == 0) {
		chanPtr->outEofChar = 0;
		chanPtr->outputTranslation = TCL_TRANSLATE_LF;


	    } else if (strcmp(writeMode, "lf") == 0) {
		chanPtr->outputTranslation = TCL_TRANSLATE_LF;
	    } else if (strcmp(writeMode, "cr") == 0) {
		chanPtr->outputTranslation = TCL_TRANSLATE_CR;
	    } else if (strcmp(writeMode, "crlf") == 0) {
		chanPtr->outputTranslation = TCL_TRANSLATE_CRLF;
	    } else if (strcmp(writeMode, "platform") == 0) {







>
>







5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
		    chanPtr->outputTranslation = TCL_TRANSLATE_CRLF;
		} else {
		    chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION;
		}
	    } else if (strcmp(writeMode, "binary") == 0) {
		chanPtr->outEofChar = 0;
		chanPtr->outputTranslation = TCL_TRANSLATE_LF;
		Tcl_FreeEncoding(chanPtr->encoding);		    
		chanPtr->encoding = NULL;
	    } else if (strcmp(writeMode, "lf") == 0) {
		chanPtr->outputTranslation = TCL_TRANSLATE_LF;
	    } else if (strcmp(writeMode, "cr") == 0) {
		chanPtr->outputTranslation = TCL_TRANSLATE_CR;
	    } else if (strcmp(writeMode, "crlf") == 0) {
		chanPtr->outputTranslation = TCL_TRANSLATE_CRLF;
	    } else if (strcmp(writeMode, "platform") == 0) {
4385
4386
4387
4388
4389
4390
4391





4392
4393



4394













4395



4396



4397



4398
4399
4400
4401
4402
4403
4404
4405
4406
		}
		ckfree((char *) argv);
		return TCL_ERROR;
	    }
	}
        ckfree((char *) argv);            
        return TCL_OK;





    }




    if (chanPtr->typePtr->setOptionProc != (Tcl_DriverSetOptionProc *) NULL) {













        return (chanPtr->typePtr->setOptionProc) (chanPtr->instanceData,



                interp, optionName, newValue);



    }



    
    return Tcl_BadChannelOption(interp, optionName, (char *) NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * CleanupChannelHandlers --
 *







>
>
>
>
>


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

>
>
>
|
|







5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
		}
		ckfree((char *) argv);
		return TCL_ERROR;
	    }
	}
        ckfree((char *) argv);            
        return TCL_OK;
    } else if (chanPtr->typePtr->setOptionProc != NULL) {
        return (*chanPtr->typePtr->setOptionProc)(chanPtr->instanceData,
                interp, optionName, newValue);
    } else {
	return Tcl_BadChannelOption(interp, optionName, (char *) NULL);
    }

    /*
     * If bufsize changes, need to get rid of old utility buffer.
     */

    if (chanPtr->saveInBufPtr != NULL) {
	RecycleBuffer(chanPtr, chanPtr->saveInBufPtr, 1);
	chanPtr->saveInBufPtr = NULL;
    }
    if (chanPtr->inQueueHead != NULL) {
	if ((chanPtr->inQueueHead->nextPtr == NULL)
		&& (chanPtr->inQueueHead->nextAdded ==
			chanPtr->inQueueHead->nextRemoved)) {
	    RecycleBuffer(chanPtr, chanPtr->inQueueHead, 1);
	    chanPtr->inQueueHead = NULL;
	    chanPtr->inQueueTail = NULL;
	}
    }

    /*
     * If encoding or bufsize changes, need to update output staging buffer.
     */

    if (chanPtr->outputStage != NULL) {
	ckfree((char *) chanPtr->outputStage);
	chanPtr->outputStage = NULL;
    }
    if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) {
	chanPtr->outputStage = (char *) 
		ckalloc((unsigned) (chanPtr->bufSize + 2));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CleanupChannelHandlers --
 *
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
            } else {
                prevPtr->nextPtr = nextPtr;
            }

            Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
                    ChannelEventScriptInvoker, (ClientData) sPtr);

	    ckfree(sPtr->script);
            ckfree((char *) sPtr);
        } else {
            prevPtr = sPtr;
        }
    }
}








|







5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
            } else {
                prevPtr->nextPtr = nextPtr;
            }

            Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
                    ChannelEventScriptInvoker, (ClientData) sPtr);

	    Tcl_DecrRefCount(sPtr->scriptPtr);
            ckfree((char *) sPtr);
        } else {
            prevPtr = sPtr;
        }
    }
}

4478
4479
4480
4481
4482
4483
4484

4485
4486




4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
    Tcl_Channel channel;	/* Channel that detected an event. */
    int mask;			/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which events were detected. */
{
    Channel *chanPtr = (Channel *) channel;
    ChannelHandler *chPtr;

    NextChannelHandler nh;





    Tcl_Preserve((ClientData)chanPtr);

    /*
     * If we are flushing in the background, be sure to call FlushChannel
     * for writable events.  Note that we have to discard the writable
     * event so we don't call any write handlers before the flush is
     * complete.
     */

    if ((chanPtr->flags & BG_FLUSH_SCHEDULED) && (mask & TCL_WRITABLE)) {
	FlushChannel(NULL, chanPtr, 1);
	mask &= ~TCL_WRITABLE;
    }

    /*
     * Add this invocation to the list of recursive invocations of
     * ChannelHandlerEventProc.
     */
    
    nh.nextHandlerPtr = (ChannelHandler *) NULL;
    nh.nestedHandlerPtr = nestedHandlerPtr;
    nestedHandlerPtr = &nh;
    
    for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; ) {

        /*
         * If this channel handler is interested in any of the events that
         * have occurred on the channel, invoke its procedure.
         */







>


>
>
>
>
|



















|
|







5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
    Tcl_Channel channel;	/* Channel that detected an event. */
    int mask;			/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which events were detected. */
{
    Channel *chanPtr = (Channel *) channel;
    ChannelHandler *chPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    NextChannelHandler nh;

    /*
     * Preserve the channel struct in case the script closes it.
     */
     
    Tcl_Preserve((ClientData) channel);

    /*
     * If we are flushing in the background, be sure to call FlushChannel
     * for writable events.  Note that we have to discard the writable
     * event so we don't call any write handlers before the flush is
     * complete.
     */

    if ((chanPtr->flags & BG_FLUSH_SCHEDULED) && (mask & TCL_WRITABLE)) {
	FlushChannel(NULL, chanPtr, 1);
	mask &= ~TCL_WRITABLE;
    }

    /*
     * Add this invocation to the list of recursive invocations of
     * ChannelHandlerEventProc.
     */
    
    nh.nextHandlerPtr = (ChannelHandler *) NULL;
    nh.nestedHandlerPtr = tsdPtr->nestedHandlerPtr;
    tsdPtr->nestedHandlerPtr = &nh;
    
    for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; ) {

        /*
         * If this channel handler is interested in any of the events that
         * have occurred on the channel, invoke its procedure.
         */
4527
4528
4529
4530
4531
4532
4533

4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
     * Update the notifier interest, since it may have changed after
     * invoking event handlers.
     */

    if (chanPtr->typePtr != NULL) {
	UpdateInterest(chanPtr);
    }

    Tcl_Release((ClientData)chanPtr);

    nestedHandlerPtr = nh.nestedHandlerPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateInterest --
 *







>
|

|







5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
     * Update the notifier interest, since it may have changed after
     * invoking event handlers.
     */

    if (chanPtr->typePtr != NULL) {
	UpdateInterest(chanPtr);
    }

    Tcl_Release((ClientData) channel);

    tsdPtr->nestedHandlerPtr = nh.nestedHandlerPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateInterest --
 *
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
     */

    if (chanPtr->flags & BG_FLUSH_SCHEDULED) {
	mask |= TCL_WRITABLE;
    }

    /*
     * If there is data in the input queue, and we aren't blocked waiting for
     * an EOL, then we need to schedule a timer so we don't block in the
     * notifier.  Also, cancel the read interest so we don't get duplicate
     * events.
     */

    if (mask & TCL_READABLE) {
	if (!(chanPtr->flags & CHANNEL_GETS_BLOCKED)
		&& (chanPtr->inQueueHead != (ChannelBuffer *) NULL)
		&& (chanPtr->inQueueHead->nextRemoved <
			chanPtr->inQueueHead->nextAdded)) {
	    mask &= ~TCL_READABLE;
	    if (!chanPtr->timer) {
		chanPtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc,
			(ClientData) chanPtr);







|
|





|







5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
     */

    if (chanPtr->flags & BG_FLUSH_SCHEDULED) {
	mask |= TCL_WRITABLE;
    }

    /*
     * If there is data in the input queue, and we aren't waiting for more
     * data, then we need to schedule a timer so we don't block in the
     * notifier.  Also, cancel the read interest so we don't get duplicate
     * events.
     */

    if (mask & TCL_READABLE) {
	if (!(chanPtr->flags & CHANNEL_NEED_MORE_DATA)
		&& (chanPtr->inQueueHead != (ChannelBuffer *) NULL)
		&& (chanPtr->inQueueHead->nextRemoved <
			chanPtr->inQueueHead->nextAdded)) {
	    mask &= ~TCL_READABLE;
	    if (!chanPtr->timer) {
		chanPtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc,
			(ClientData) chanPtr);
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623

static void
ChannelTimerProc(clientData)
    ClientData clientData;
{
    Channel *chanPtr = (Channel *) clientData;

    if (!(chanPtr->flags & CHANNEL_GETS_BLOCKED)
	    && (chanPtr->interestMask & TCL_READABLE)
	    && (chanPtr->inQueueHead != (ChannelBuffer *) NULL)
	    && (chanPtr->inQueueHead->nextRemoved <
		    chanPtr->inQueueHead->nextAdded)) {
	/*
	 * Restart the timer in case a channel handler reenters the
	 * event loop before UpdateInterest gets called by Tcl_NotifyChannel.







|







5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702

static void
ChannelTimerProc(clientData)
    ClientData clientData;
{
    Channel *chanPtr = (Channel *) clientData;

    if (!(chanPtr->flags & CHANNEL_NEED_MORE_DATA)
	    && (chanPtr->interestMask & TCL_READABLE)
	    && (chanPtr->inQueueHead != (ChannelBuffer *) NULL)
	    && (chanPtr->inQueueHead->nextRemoved <
		    chanPtr->inQueueHead->nextAdded)) {
	/*
	 * Restart the timer in case a channel handler reenters the
	 * event loop before UpdateInterest gets called by Tcl_NotifyChannel.
4745
4746
4747
4748
4749
4750
4751

4752
4753
4754
4755
4756
4757
4758
    Tcl_ChannelProc *proc;	/* The procedure in the callback to delete. */
    ClientData clientData;	/* The client data in the callback
                                 * to delete. */
    
{
    ChannelHandler *chPtr, *prevChPtr;
    Channel *chanPtr;

    NextChannelHandler *nhPtr;

    chanPtr = (Channel *) chan;

    /*
     * Find the entry and the previous one in the list.
     */







>







5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
    Tcl_ChannelProc *proc;	/* The procedure in the callback to delete. */
    ClientData clientData;	/* The client data in the callback
                                 * to delete. */
    
{
    ChannelHandler *chPtr, *prevChPtr;
    Channel *chanPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    NextChannelHandler *nhPtr;

    chanPtr = (Channel *) chan;

    /*
     * Find the entry and the previous one in the list.
     */
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804

4805
4806
4807
4808
4809
4810
4811
    }

    /*
     * If ChannelHandlerEventProc is about to process this handler, tell it to
     * process the next one instead - we are going to delete *this* one.
     */

    for (nhPtr = nestedHandlerPtr;
             nhPtr != (NextChannelHandler *) NULL;
             nhPtr = nhPtr->nestedHandlerPtr) {
        if (nhPtr->nextHandlerPtr == chPtr) {
            nhPtr->nextHandlerPtr = chPtr->nextPtr;
        }
    }

    /*
     * Splice it out of the list of channel handlers.
     */
    
    if (prevChPtr == (ChannelHandler *) NULL) {
        chanPtr->chPtr = chPtr->nextPtr;
    } else {
        prevChPtr->nextPtr = chPtr->nextPtr;
    }
    ckfree((char *) chPtr);

    /*
     * Recompute the interest list for the channel, so that infinite loops
     * will not result if Tcl_DeleteChanelHandler is called inside an event.

     */

    chanPtr->interestMask = 0;
    for (chPtr = chanPtr->chPtr;
             chPtr != (ChannelHandler *) NULL;
             chPtr = chPtr->nextPtr) {
        chanPtr->interestMask |= chPtr->mask;







|




















|
>







5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
    }

    /*
     * If ChannelHandlerEventProc is about to process this handler, tell it to
     * process the next one instead - we are going to delete *this* one.
     */

    for (nhPtr = tsdPtr->nestedHandlerPtr;
             nhPtr != (NextChannelHandler *) NULL;
             nhPtr = nhPtr->nestedHandlerPtr) {
        if (nhPtr->nextHandlerPtr == chPtr) {
            nhPtr->nextHandlerPtr = chPtr->nextPtr;
        }
    }

    /*
     * Splice it out of the list of channel handlers.
     */
    
    if (prevChPtr == (ChannelHandler *) NULL) {
        chanPtr->chPtr = chPtr->nextPtr;
    } else {
        prevChPtr->nextPtr = chPtr->nextPtr;
    }
    ckfree((char *) chPtr);

    /*
     * Recompute the interest list for the channel, so that infinite loops
     * will not result if Tcl_DeleteChannelHandler is called inside an
     * event.
     */

    chanPtr->interestMask = 0;
    for (chPtr = chanPtr->chPtr;
             chPtr != (ChannelHandler *) NULL;
             chPtr = chPtr->nextPtr) {
        chanPtr->interestMask |= chPtr->mask;
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
            } else {
                prevEsPtr->nextPtr = esPtr->nextPtr;
            }

            Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
                    ChannelEventScriptInvoker, (ClientData) esPtr);
            
	    ckfree(esPtr->script);
            ckfree((char *) esPtr);

            break;
        }
    }
}








|







5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
            } else {
                prevEsPtr->nextPtr = esPtr->nextPtr;
            }

            Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
                    ChannelEventScriptInvoker, (ClientData) esPtr);
            
	    Tcl_DecrRefCount(esPtr->scriptPtr);
            ckfree((char *) esPtr);

            break;
        }
    }
}

4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
 * Side effects:
 *	Causes the script to be stored for later execution.
 *
 *----------------------------------------------------------------------
 */

static void
CreateScriptRecord(interp, chanPtr, mask, script)
    Tcl_Interp *interp;			/* Interpreter in which to execute
                                         * the stored script. */
    Channel *chanPtr;			/* Channel for which script is to
                                         * be stored. */
    int mask;				/* Set of events for which script
                                         * will be invoked. */
    char *script;			/* A copy of this script is stored
                                         * in the newly created record. */
{
    EventScriptRecord *esPtr;

    for (esPtr = chanPtr->scriptRecordPtr;
             esPtr != (EventScriptRecord *) NULL;
             esPtr = esPtr->nextPtr) {
        if ((esPtr->interp == interp) && (esPtr->mask == mask)) {
	    ckfree(esPtr->script);
            esPtr->script = (char *) NULL;
            break;
        }
    }
    if (esPtr == (EventScriptRecord *) NULL) {
        esPtr = (EventScriptRecord *) ckalloc((unsigned)
                sizeof(EventScriptRecord));
        Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
                ChannelEventScriptInvoker, (ClientData) esPtr);
        esPtr->nextPtr = chanPtr->scriptRecordPtr;
        chanPtr->scriptRecordPtr = esPtr;
    }
    esPtr->chanPtr = chanPtr;
    esPtr->interp = interp;
    esPtr->mask = mask;
    esPtr->script = ckalloc((unsigned) (strlen(script) + 1));
    strcpy(esPtr->script, script);
}

/*
 *----------------------------------------------------------------------
 *
 * ChannelEventScriptInvoker --
 *







|






|
<







|
|














|
|







5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973

5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
 * Side effects:
 *	Causes the script to be stored for later execution.
 *
 *----------------------------------------------------------------------
 */

static void
CreateScriptRecord(interp, chanPtr, mask, scriptPtr)
    Tcl_Interp *interp;			/* Interpreter in which to execute
                                         * the stored script. */
    Channel *chanPtr;			/* Channel for which script is to
                                         * be stored. */
    int mask;				/* Set of events for which script
                                         * will be invoked. */
    Tcl_Obj *scriptPtr;			/* Pointer to script object. */

{
    EventScriptRecord *esPtr;

    for (esPtr = chanPtr->scriptRecordPtr;
             esPtr != (EventScriptRecord *) NULL;
             esPtr = esPtr->nextPtr) {
        if ((esPtr->interp == interp) && (esPtr->mask == mask)) {
	    Tcl_DecrRefCount(esPtr->scriptPtr);
	    esPtr->scriptPtr = (Tcl_Obj *) NULL;
            break;
        }
    }
    if (esPtr == (EventScriptRecord *) NULL) {
        esPtr = (EventScriptRecord *) ckalloc((unsigned)
                sizeof(EventScriptRecord));
        Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
                ChannelEventScriptInvoker, (ClientData) esPtr);
        esPtr->nextPtr = chanPtr->scriptRecordPtr;
        chanPtr->scriptRecordPtr = esPtr;
    }
    esPtr->chanPtr = chanPtr;
    esPtr->interp = interp;
    esPtr->mask = mask;
    Tcl_IncrRefCount(scriptPtr);
    esPtr->scriptPtr = scriptPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ChannelEventScriptInvoker --
 *
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
ChannelEventScriptInvoker(clientData, mask)
    ClientData clientData;	/* The script+interp record. */
    int mask;			/* Not used. */
{
    Tcl_Interp *interp;		/* Interpreter in which to eval the script. */
    Channel *chanPtr;		/* The channel for which this handler is
                                 * registered. */
    char *script;		/* Script to eval. */
    EventScriptRecord *esPtr;	/* The event script + interpreter to eval it
                                 * in. */
    int result;			/* Result of call to eval script. */

    esPtr = (EventScriptRecord *) clientData;

    chanPtr = esPtr->chanPtr;
    mask = esPtr->mask;
    interp = esPtr->interp;
    script = esPtr->script;

    /*
     * We must preserve the interpreter so we can report errors on it
     * later.  Note that we do not need to preserve the channel because
     * that is done by Tcl_NotifyChannel before calling channel handlers.
     */
    
    Tcl_Preserve((ClientData) interp);
    result = Tcl_GlobalEval(interp, script);

    /*
     * On error, cause a background error and remove the channel handler
     * and the script record.
     *
     * NOTE: Must delete channel handler before causing the background error
     * because the background error may want to reinstall the handler.







<









<
|







|







6020
6021
6022
6023
6024
6025
6026

6027
6028
6029
6030
6031
6032
6033
6034
6035

6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
ChannelEventScriptInvoker(clientData, mask)
    ClientData clientData;	/* The script+interp record. */
    int mask;			/* Not used. */
{
    Tcl_Interp *interp;		/* Interpreter in which to eval the script. */
    Channel *chanPtr;		/* The channel for which this handler is
                                 * registered. */

    EventScriptRecord *esPtr;	/* The event script + interpreter to eval it
                                 * in. */
    int result;			/* Result of call to eval script. */

    esPtr = (EventScriptRecord *) clientData;

    chanPtr = esPtr->chanPtr;
    mask = esPtr->mask;
    interp = esPtr->interp;

    
    /*
     * We must preserve the interpreter so we can report errors on it
     * later.  Note that we do not need to preserve the channel because
     * that is done by Tcl_NotifyChannel before calling channel handlers.
     */
    
    Tcl_Preserve((ClientData) interp);
    result = Tcl_EvalObjEx(interp, esPtr->scriptPtr, TCL_EVAL_GLOBAL);

    /*
     * On error, cause a background error and remove the channel handler
     * and the script record.
     *
     * NOTE: Must delete channel handler before causing the background error
     * because the background error may want to reinstall the handler.
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016

5017
5018
5019
5020
5021
5022
5023

5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040



5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
    }
    Tcl_Release((ClientData) interp);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FileEventCmd --
 *
 *	This procedure implements the "fileevent" Tcl command. See the
 *	user documentation for details on what it does. This command is
 *	based on the Tk command "fileevent" which in turn is based on work
 *	contributed by Mark Diekhans.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	May create a channel handler for the specified channel.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_FileEventCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Interpreter in which the channel
                                         * for which to create the handler
                                         * is found. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    Channel *chanPtr;			/* The channel to create
                                         * the handler for. */
    Tcl_Channel chan;			/* The opaque type for the channel. */

    int c;				/* First char of mode argument. */
    int mask;				/* Mask for events of interest. */
    size_t length;			/* Length of mode argument. */

    /*
     * Parse arguments.
     */


    if ((argc != 3) && (argc != 4)) {
	Tcl_AppendResult(interp, "wrong # args: must be \"", argv[0],
		" channelId event ?script?", (char *) NULL);
	return TCL_ERROR;
    }
    c = argv[2][0];
    length = strlen(argv[2]);
    if ((c == 'r') && (strncmp(argv[2], "readable", length) == 0)) {
        mask = TCL_READABLE;
    } else if ((c == 'w') && (strncmp(argv[2], "writable", length) == 0)) {
        mask = TCL_WRITABLE;
    } else {
	Tcl_AppendResult(interp, "bad event name \"", argv[2],
		"\": must be readable or writable", (char *) NULL);
	return TCL_ERROR;
    }



    chan = Tcl_GetChannel(interp, argv[1], NULL);
    if (chan == (Tcl_Channel) NULL) {
        return TCL_ERROR;
    }
    
    chanPtr = (Channel *) chan;
    if ((chanPtr->flags & mask) == 0) {
        Tcl_AppendResult(interp, "channel is not ",
                (mask == TCL_READABLE) ? "readable" : "writable",
                (char *) NULL);
        return TCL_ERROR;
    }
    
    /*
     * If we are supposed to return the script, do so.
     */

    if (argc == 3) {
	EventScriptRecord *esPtr;
	for (esPtr = chanPtr->scriptRecordPtr;
             esPtr != (EventScriptRecord *) NULL;
             esPtr = esPtr->nextPtr) {
	    if ((esPtr->interp == interp) && (esPtr->mask == mask)) {
		Tcl_SetResult(interp, esPtr->script, TCL_STATIC);
		break;
	    }
	}
        return TCL_OK;
    }

    /*
     * If we are supposed to delete a stored script, do so.
     */

    if (argv[3][0] == 0) {
        DeleteScriptRecord(interp, chanPtr, mask);
        return TCL_OK;
    }

    /*
     * Make the script record that will link between the event and the
     * script to invoke. This also creates a channel event handler which
     * will evaluate the script in the supplied interpreter.
     */

    CreateScriptRecord(interp, chanPtr, mask, argv[3]);
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|

















|




|
|




>
|
|
<
|
<
<
<
>

|
<
|


|
<
<
|
<
<
<
<
<


>
>
>
|

|

<












|





|










|










|







6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097

6098



6099
6100
6101

6102
6103
6104
6105


6106





6107
6108
6109
6110
6111
6112
6113
6114
6115

6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
    }
    Tcl_Release((ClientData) interp);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FileEventObjCmd --
 *
 *	This procedure implements the "fileevent" Tcl command. See the
 *	user documentation for details on what it does. This command is
 *	based on the Tk command "fileevent" which in turn is based on work
 *	contributed by Mark Diekhans.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	May create a channel handler for the specified channel.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_FileEventObjCmd(clientData, interp, objc, objv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Interpreter in which the channel
                                         * for which to create the handler
                                         * is found. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Channel *chanPtr;			/* The channel to create
                                         * the handler for. */
    Tcl_Channel chan;			/* The opaque type for the channel. */
    char *chanName;
    int modeIndex;			/* Index of mode argument. */
    int mask;

    static char *modeOptions[] = {"readable", "writable", NULL};



    static int maskArray[] = {TCL_READABLE, TCL_WRITABLE};

    if ((objc != 3) && (objc != 4)) {

	Tcl_WrongNumArgs(interp, 1, objv, "channelId event ?script?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[2], modeOptions, "event name", 0,


	    &modeIndex) != TCL_OK) {





	return TCL_ERROR;
    }
    mask = maskArray[modeIndex];

    chanName = Tcl_GetString(objv[1]);
    chan = Tcl_GetChannel(interp, chanName, NULL);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }

    chanPtr = (Channel *) chan;
    if ((chanPtr->flags & mask) == 0) {
        Tcl_AppendResult(interp, "channel is not ",
                (mask == TCL_READABLE) ? "readable" : "writable",
                (char *) NULL);
        return TCL_ERROR;
    }
    
    /*
     * If we are supposed to return the script, do so.
     */

    if (objc == 3) {
	EventScriptRecord *esPtr;
	for (esPtr = chanPtr->scriptRecordPtr;
             esPtr != (EventScriptRecord *) NULL;
             esPtr = esPtr->nextPtr) {
	    if ((esPtr->interp == interp) && (esPtr->mask == mask)) {
		Tcl_SetObjResult(interp, esPtr->scriptPtr);
		break;
	    }
	}
        return TCL_OK;
    }

    /*
     * If we are supposed to delete a stored script, do so.
     */

    if (*(Tcl_GetString(objv[3])) == '\0') {
        DeleteScriptRecord(interp, chanPtr, mask);
        return TCL_OK;
    }

    /*
     * Make the script record that will link between the event and the
     * script to invoke. This also creates a channel event handler which
     * will evaluate the script in the supplied interpreter.
     */

    CreateScriptRecord(interp, chanPtr, mask, objv[3]);
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137

5138
5139
5140
5141
5142
5143
5144
5145

5146
5147
5148
5149
5150
5151
5152
    Tcl_HashSearch hSearch;	/* Search variable. */
    Tcl_HashEntry *hPtr;	/* Search variable. */
    Channel *chanPtr;		/* The actual channel. */
    Tcl_Channel chan;		/* The opaque type. */
    size_t len;			/* Length of subcommand string. */
    int IOQueued;		/* How much IO is queued inside channel? */
    ChannelBuffer *bufPtr;	/* For iterating over queued IO. */
    char buf[128];		/* For sprintf. */
    
    if (argc < 2) {
        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                " subcommand ?additional args..?\"", (char *) NULL);
        return TCL_ERROR;
    }
    cmdName = argv[1];
    len = strlen(cmdName);

    chanPtr = (Channel *) NULL;

    if (argc > 2) {
        chan = Tcl_GetChannel(interp, argv[2], NULL);
        if (chan == (Tcl_Channel) NULL) {
            return TCL_ERROR;
        }
        chanPtr = (Channel *) chan;
    }
    

    if ((cmdName[0] == 'i') && (strncmp(cmdName, "info", len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                    " info channelName\"", (char *) NULL);
            return TCL_ERROR;
        }
        Tcl_AppendElement(interp, argv[2]);







|










>







|
>







6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
    Tcl_HashSearch hSearch;	/* Search variable. */
    Tcl_HashEntry *hPtr;	/* Search variable. */
    Channel *chanPtr;		/* The actual channel. */
    Tcl_Channel chan;		/* The opaque type. */
    size_t len;			/* Length of subcommand string. */
    int IOQueued;		/* How much IO is queued inside channel? */
    ChannelBuffer *bufPtr;	/* For iterating over queued IO. */
    char buf[TCL_INTEGER_SPACE];/* For sprintf. */
    
    if (argc < 2) {
        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                " subcommand ?additional args..?\"", (char *) NULL);
        return TCL_ERROR;
    }
    cmdName = argv[1];
    len = strlen(cmdName);

    chanPtr = (Channel *) NULL;

    if (argc > 2) {
        chan = Tcl_GetChannel(interp, argv[2], NULL);
        if (chan == (Tcl_Channel) NULL) {
            return TCL_ERROR;
        }
        chanPtr = (Channel *) chan;
    }


    if ((cmdName[0] == 'i') && (strncmp(cmdName, "info", len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                    " info channelName\"", (char *) NULL);
            return TCL_ERROR;
        }
        Tcl_AppendElement(interp, argv[2]);
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
        }
        
        for (IOQueued = 0, bufPtr = chanPtr->inQueueHead;
                 bufPtr != (ChannelBuffer *) NULL;
                 bufPtr = bufPtr->nextPtr) {
            IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved;
        }
        sprintf(buf, "%d", IOQueued);
        Tcl_AppendResult(interp, buf, (char *) NULL);
        return TCL_OK;
    }
        
    if ((cmdName[0] == 'm') && (strncmp(cmdName, "mode", len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "channel name required",







|







6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
        }
        
        for (IOQueued = 0, bufPtr = chanPtr->inQueueHead;
                 bufPtr != (ChannelBuffer *) NULL;
                 bufPtr = bufPtr->nextPtr) {
            IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved;
        }
        TclFormatInt(buf, IOQueued);
        Tcl_AppendResult(interp, buf, (char *) NULL);
        return TCL_OK;
    }
        
    if ((cmdName[0] == 'm') && (strncmp(cmdName, "mode", len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "channel name required",
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
                chanPtr->curOutPtr->nextRemoved;
        }
        for (bufPtr = chanPtr->outQueueHead;
                 bufPtr != (ChannelBuffer *) NULL;
                 bufPtr = bufPtr->nextPtr) {
            IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved);
        }
        sprintf(buf, "%d", IOQueued);
        Tcl_AppendResult(interp, buf, (char *) NULL);
        return TCL_OK;
    }
        
    if ((cmdName[0] == 'q') &&
            (strncmp(cmdName, "queuedcr", len) == 0)) {
        if (argc != 3) {







|







6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
                chanPtr->curOutPtr->nextRemoved;
        }
        for (bufPtr = chanPtr->outQueueHead;
                 bufPtr != (ChannelBuffer *) NULL;
                 bufPtr = bufPtr->nextPtr) {
            IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved);
        }
        TclFormatInt(buf, IOQueued);
        Tcl_AppendResult(interp, buf, (char *) NULL);
        return TCL_OK;
    }
        
    if ((cmdName[0] == 'q') &&
            (strncmp(cmdName, "queuedcr", len) == 0)) {
        if (argc != 3) {
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
    if ((cmdName[0] == 'r') && (strncmp(cmdName, "refcount", len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "channel name required",
                    (char *) NULL);
            return TCL_ERROR;
        }
        
        sprintf(buf, "%d", chanPtr->refCount);
        Tcl_AppendResult(interp, buf, (char *) NULL);
        return TCL_OK;
    }
    
    if ((cmdName[0] == 't') && (strncmp(cmdName, "type", len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "channel name required",







|







6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
    if ((cmdName[0] == 'r') && (strncmp(cmdName, "refcount", len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "channel name required",
                    (char *) NULL);
            return TCL_ERROR;
        }
        
        TclFormatInt(buf, chanPtr->refCount);
        Tcl_AppendResult(interp, buf, (char *) NULL);
        return TCL_OK;
    }
    
    if ((cmdName[0] == 't') && (strncmp(cmdName, "type", len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "channel name required",
5429
5430
5431
5432
5433
5434
5435

5436
5437
5438
5439
5440
5441
5442
int
TclTestChannelEventCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{

    Channel *chanPtr;
    EventScriptRecord *esPtr, *prevEsPtr, *nextEsPtr;
    char *cmd;
    int index, i, mask, len;

    if ((argc < 3) || (argc > 5)) {
        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],







>







6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
int
TclTestChannelEventCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    Tcl_Obj *resultListPtr;
    Channel *chanPtr;
    EventScriptRecord *esPtr, *prevEsPtr, *nextEsPtr;
    char *cmd;
    int index, i, mask, len;

    if ((argc < 3) || (argc > 5)) {
        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
                sizeof(EventScriptRecord));
        esPtr->nextPtr = chanPtr->scriptRecordPtr;
        chanPtr->scriptRecordPtr = esPtr;
        
        esPtr->chanPtr = chanPtr;
        esPtr->interp = interp;
        esPtr->mask = mask;
        esPtr->script = ckalloc((unsigned) (strlen(argv[4]) + 1));
        strcpy(esPtr->script, argv[4]);

        Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
                ChannelEventScriptInvoker, (ClientData) esPtr);
        
        return TCL_OK;
    }








|
|







6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
                sizeof(EventScriptRecord));
        esPtr->nextPtr = chanPtr->scriptRecordPtr;
        chanPtr->scriptRecordPtr = esPtr;
        
        esPtr->chanPtr = chanPtr;
        esPtr->interp = interp;
        esPtr->mask = mask;
	esPtr->scriptPtr = Tcl_NewStringObj(argv[4], -1);
	Tcl_IncrRefCount(esPtr->scriptPtr);

        Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
                ChannelEventScriptInvoker, (ClientData) esPtr);
        
        return TCL_OK;
    }

5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538

5539
5540
5541
5542
5543

5544
5545
5546

5547
5548
5549
5550
5551

5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
            if (prevEsPtr == (EventScriptRecord *) NULL) {
                panic("TclTestChannelEventCmd: damaged event script list");
            }
            prevEsPtr->nextPtr = esPtr->nextPtr;
        }
        Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
                ChannelEventScriptInvoker, (ClientData) esPtr);
	ckfree(esPtr->script);
        ckfree((char *) esPtr);

        return TCL_OK;
    }

    if ((cmd[0] == 'l') && (strncmp(cmd, "list", (unsigned) len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                    " channelName list\"", (char *) NULL);
            return TCL_ERROR;
        }

        for (esPtr = chanPtr->scriptRecordPtr;
                 esPtr != (EventScriptRecord *) NULL;
                 esPtr = esPtr->nextPtr) {
	    char *event;
	    if (esPtr->mask) {

		event = ((esPtr->mask == TCL_READABLE)
			? "readable" : "writable");
	    } else {

		event = "none";
	    }
            Tcl_AppendElement(interp, event);
            Tcl_AppendElement(interp, esPtr->script);
        }

        return TCL_OK;
    }

    if ((cmd[0] == 'r') && (strncmp(cmd, "removeall", (unsigned) len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                    " channelName removeall\"", (char *) NULL);
            return TCL_ERROR;
        }
        for (esPtr = chanPtr->scriptRecordPtr;
                 esPtr != (EventScriptRecord *) NULL;
                 esPtr = nextEsPtr) {
            nextEsPtr = esPtr->nextPtr;
            Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
                    ChannelEventScriptInvoker, (ClientData) esPtr);
	    ckfree(esPtr->script);
            ckfree((char *) esPtr);
        }
        chanPtr->scriptRecordPtr = (EventScriptRecord *) NULL;
        return TCL_OK;
    }

    if  ((cmd[0] == 's') && (strncmp(cmd, "set", (unsigned) len) == 0)) {







|











>



<

>
|
<
|
>
|

|
<

>















|







6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615

6616
6617
6618

6619
6620
6621
6622
6623

6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
            if (prevEsPtr == (EventScriptRecord *) NULL) {
                panic("TclTestChannelEventCmd: damaged event script list");
            }
            prevEsPtr->nextPtr = esPtr->nextPtr;
        }
        Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
                ChannelEventScriptInvoker, (ClientData) esPtr);
	Tcl_DecrRefCount(esPtr->scriptPtr);
        ckfree((char *) esPtr);

        return TCL_OK;
    }

    if ((cmd[0] == 'l') && (strncmp(cmd, "list", (unsigned) len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                    " channelName list\"", (char *) NULL);
            return TCL_ERROR;
        }
	resultListPtr = Tcl_GetObjResult(interp);
        for (esPtr = chanPtr->scriptRecordPtr;
                 esPtr != (EventScriptRecord *) NULL;
                 esPtr = esPtr->nextPtr) {

	    if (esPtr->mask) {
 	        Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj(
		    (esPtr->mask == TCL_READABLE) ? "readable" : "writable", -1));

 	    } else {
 	        Tcl_ListObjAppendElement(interp, resultListPtr, 
                    Tcl_NewStringObj("none", -1));
	    }
  	    Tcl_ListObjAppendElement(interp, resultListPtr, esPtr->scriptPtr);

        }
	Tcl_SetObjResult(interp, resultListPtr);
        return TCL_OK;
    }

    if ((cmd[0] == 'r') && (strncmp(cmd, "removeall", (unsigned) len) == 0)) {
        if (argc != 3) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                    " channelName removeall\"", (char *) NULL);
            return TCL_ERROR;
        }
        for (esPtr = chanPtr->scriptRecordPtr;
                 esPtr != (EventScriptRecord *) NULL;
                 esPtr = nextEsPtr) {
            nextEsPtr = esPtr->nextPtr;
            Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
                    ChannelEventScriptInvoker, (ClientData) esPtr);
	    Tcl_DecrRefCount(esPtr->scriptPtr);
            ckfree((char *) esPtr);
        }
        chanPtr->scriptRecordPtr = (EventScriptRecord *) NULL;
        return TCL_OK;
    }

    if  ((cmd[0] == 's') && (strncmp(cmd, "set", (unsigned) len) == 0)) {
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
        Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
                ChannelEventScriptInvoker, (ClientData) esPtr);
	return TCL_OK;
    }    
    Tcl_AppendResult(interp, "bad command ", cmd, ", must be one of ",
            "add, delete, list, set, or removeall", (char *) NULL);
    return TCL_ERROR;

}

/*
 *----------------------------------------------------------------------
 *
 * TclCopyChannel --
 *







<







6685
6686
6687
6688
6689
6690
6691

6692
6693
6694
6695
6696
6697
6698
        Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
                ChannelEventScriptInvoker, (ClientData) esPtr);
	return TCL_OK;
    }    
    Tcl_AppendResult(interp, "bad command ", cmd, ", must be one of ",
            "add, delete, list, set, or removeall", (char *) NULL);
    return TCL_ERROR;

}

/*
 *----------------------------------------------------------------------
 *
 * TclCopyChannel --
 *
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926























































































































































































































































































































































































































































































5927
5928
5929
5930
5931
5932
5933
	StopCopy(csPtr);
	Tcl_Preserve((ClientData) interp);

	Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(total));
	if (errObj) {
	    Tcl_ListObjAppendElement(interp, cmdPtr, errObj);
	}
	if (Tcl_GlobalEvalObj(interp, cmdPtr) != TCL_OK) {
	    Tcl_BackgroundError(interp);
	    result = TCL_ERROR;
	}
	Tcl_DecrRefCount(cmdPtr);
	Tcl_Release((ClientData) interp);
    } else {
	StopCopy(csPtr);
	if (errObj) {
	    Tcl_SetObjResult(interp, errObj);
	    result = TCL_ERROR;
	} else {
	    Tcl_ResetResult(interp);
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), total);
	}
    }
    return result;
}
























































































































































































































































































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * CopyEventProc --
 *
 *	This routine is invoked as a channel event handler for







|

















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







6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
	StopCopy(csPtr);
	Tcl_Preserve((ClientData) interp);

	Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(total));
	if (errObj) {
	    Tcl_ListObjAppendElement(interp, cmdPtr, errObj);
	}
	if (Tcl_EvalObjEx(interp, cmdPtr, TCL_EVAL_GLOBAL) != TCL_OK) {
	    Tcl_BackgroundError(interp);
	    result = TCL_ERROR;
	}
	Tcl_DecrRefCount(cmdPtr);
	Tcl_Release((ClientData) interp);
    } else {
	StopCopy(csPtr);
	if (errObj) {
	    Tcl_SetObjResult(interp, errObj);
	    result = TCL_ERROR;
	} else {
	    Tcl_ResetResult(interp);
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), total);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DoRead --
 *
 *	Reads a given number of bytes from a channel.
 *
 * Results:
 *	The number of characters read, or -1 on error. Use Tcl_GetErrno()
 *	to retrieve the error code for the error that occurred.
 *
 * Side effects:
 *	May cause input to be buffered.
 *
 *----------------------------------------------------------------------
 */

static int
DoRead(chanPtr, bufPtr, toRead)
    Channel *chanPtr;		/* The channel from which to read. */
    char *bufPtr;		/* Where to store input read. */
    int toRead;			/* Maximum number of bytes to read. */
{
    int copied;			/* How many characters were copied into
                                 * the result string? */
    int copiedNow;		/* How many characters were copied from
                                 * the current input buffer? */
    int result;			/* Of calling GetInput. */
    
    /*
     * If we have not encountered a sticky EOF, clear the EOF bit. Either
     * way clear the BLOCKED bit. We want to discover these anew during
     * each operation.
     */

    if (!(chanPtr->flags & CHANNEL_STICKY_EOF)) {
        chanPtr->flags &= ~CHANNEL_EOF;
    }
    chanPtr->flags &= ~(CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA);
    
    for (copied = 0; copied < toRead; copied += copiedNow) {
        copiedNow = CopyAndTranslateBuffer(chanPtr, bufPtr + copied,
                toRead - copied);
        if (copiedNow == 0) {
            if (chanPtr->flags & CHANNEL_EOF) {
		goto done;
            }
            if (chanPtr->flags & CHANNEL_BLOCKED) {
                if (chanPtr->flags & CHANNEL_NONBLOCKING) {
		    goto done;
                }
                chanPtr->flags &= (~(CHANNEL_BLOCKED));
            }
            result = GetInput(chanPtr);
            if (result != 0) {
                if (result != EAGAIN) {
                    copied = -1;
                }
		goto done;
            }
        }
    }

    chanPtr->flags &= (~(CHANNEL_BLOCKED));

    done:
    /*
     * Update the notifier state so we don't block while there is still
     * data in the buffers.
     */

    UpdateInterest(chanPtr);
    return copied;
}

/*
 *----------------------------------------------------------------------
 *
 * CopyAndTranslateBuffer --
 *
 *	Copy at most one buffer of input to the result space, doing
 *	eol translations according to mode in effect currently.
 *
 * Results:
 *	Number of bytes stored in the result buffer (as opposed to the
 *	number of bytes read from the channel).  May return
 *	zero if no input is available to be translated.
 *
 * Side effects:
 *	Consumes buffered input. May deallocate one buffer.
 *
 *----------------------------------------------------------------------
 */

static int
CopyAndTranslateBuffer(chanPtr, result, space)
    Channel *chanPtr;		/* The channel from which to read input. */
    char *result;		/* Where to store the copied input. */
    int space;			/* How many bytes are available in result
                                 * to store the copied input? */
{
    int bytesInBuffer;		/* How many bytes are available to be
                                 * copied in the current input buffer? */
    int copied;			/* How many characters were already copied
                                 * into the destination space? */
    ChannelBuffer *bufPtr;	/* The buffer from which to copy bytes. */
    int i;			/* Iterates over the copied input looking
                                 * for the input eofChar. */
    
    /*
     * If there is no input at all, return zero. The invariant is that either
     * there is no buffer in the queue, or if the first buffer is empty, it
     * is also the last buffer (and thus there is no input in the queue).
     * Note also that if the buffer is empty, we leave it in the queue.
     */
    
    if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) {
        return 0;
    }
    bufPtr = chanPtr->inQueueHead;
    bytesInBuffer = bufPtr->nextAdded - bufPtr->nextRemoved;

    copied = 0;
    switch (chanPtr->inputTranslation) {
        case TCL_TRANSLATE_LF: {
            if (bytesInBuffer == 0) {
                return 0;
            }

	    /*
             * Copy the current chunk into the result buffer.
             */

	    if (bytesInBuffer < space) {
		space = bytesInBuffer;
	    }
	    memcpy((VOID *) result,
		    (VOID *) (bufPtr->buf + bufPtr->nextRemoved),
		    (size_t) space);
	    bufPtr->nextRemoved += space;
	    copied = space;
            break;
	}
        case TCL_TRANSLATE_CR: {
	    char *end;
	    
            if (bytesInBuffer == 0) {
                return 0;
            }

	    /*
             * Copy the current chunk into the result buffer, then
             * replace all \r with \n.
             */

	    if (bytesInBuffer < space) {
		space = bytesInBuffer;
	    }
	    memcpy((VOID *) result,
		    (VOID *) (bufPtr->buf + bufPtr->nextRemoved),
		    (size_t) space);
	    bufPtr->nextRemoved += space;
	    copied = space;

	    for (end = result + copied; result < end; result++) {
		if (*result == '\r') {
		    *result = '\n';
		}
            }
            break;
	}
        case TCL_TRANSLATE_CRLF: {
	    char *src, *end, *dst;
	    int curByte;
	    
            /*
             * If there is a held-back "\r" at EOF, produce it now.
             */
            
	    if (bytesInBuffer == 0) {
                if ((chanPtr->flags & (INPUT_SAW_CR | CHANNEL_EOF)) ==
                        (INPUT_SAW_CR | CHANNEL_EOF)) {
                    result[0] = '\r';
                    chanPtr->flags &= ~INPUT_SAW_CR;
                    return 1;
                }
                return 0;
            }

            /*
             * Copy the current chunk and replace "\r\n" with "\n"
             * (but not standalone "\r"!).
             */

	    if (bytesInBuffer < space) {
		space = bytesInBuffer;
	    }
	    memcpy((VOID *) result,
		    (VOID *) (bufPtr->buf + bufPtr->nextRemoved),
		    (size_t) space);
	    bufPtr->nextRemoved += space;
	    copied = space;

	    end = result + copied;
	    dst = result;
	    for (src = result; src < end; src++) {
		curByte = *src;
		if (curByte == '\n') {
                    chanPtr->flags &= ~INPUT_SAW_CR;
		} else if (chanPtr->flags & INPUT_SAW_CR) {
		    chanPtr->flags &= ~INPUT_SAW_CR;
		    *dst = '\r';
		    dst++;
		}
		if (curByte == '\r') {
		    chanPtr->flags |= INPUT_SAW_CR;
		} else {
		    *dst = (char) curByte;
		    dst++;
		}
	    }
	    copied = dst - result;
	    break;
	}
        case TCL_TRANSLATE_AUTO: {
	    char *src, *end, *dst;
	    int curByte;
	
            if (bytesInBuffer == 0) {
                return 0;
            }

            /*
             * Loop over the current buffer, converting "\r" and "\r\n"
             * to "\n".
             */

	    if (bytesInBuffer < space) {
		space = bytesInBuffer;
	    }
	    memcpy((VOID *) result,
		    (VOID *) (bufPtr->buf + bufPtr->nextRemoved),
		    (size_t) space);
	    bufPtr->nextRemoved += space;
	    copied = space;

	    end = result + copied;
	    dst = result;
	    for (src = result; src < end; src++) {
		curByte = *src;
		if (curByte == '\r') {
		    chanPtr->flags |= INPUT_SAW_CR;
		    *dst = '\n';
		    dst++;
		} else {
		    if ((curByte != '\n') || 
			    !(chanPtr->flags & INPUT_SAW_CR)) {
			*dst = (char) curByte;
			dst++;
		    }
		    chanPtr->flags &= ~INPUT_SAW_CR;
		}
	    }
	    copied = dst - result;
            break;
	}
        default: {
            panic("unknown eol translation mode");
	}
    }

    /*
     * If an in-stream EOF character is set for this channel, check that
     * the input we copied so far does not contain the EOF char.  If it does,
     * copy only up to and excluding that character.
     */
    
    if (chanPtr->inEofChar != 0) {
        for (i = 0; i < copied; i++) {
            if (result[i] == (char) chanPtr->inEofChar) {
		/*
		 * Set sticky EOF so that no further input is presented
		 * to the caller.
		 */
		
		chanPtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF);
		chanPtr->inputEncodingFlags |= TCL_ENCODING_END;
		copied = i;
                break;
            }
        }
    }

    /*
     * If the current buffer is empty recycle it.
     */

    if (bufPtr->nextRemoved == bufPtr->nextAdded) {
        chanPtr->inQueueHead = bufPtr->nextPtr;
        if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) {
            chanPtr->inQueueTail = (ChannelBuffer *) NULL;
        }
        RecycleBuffer(chanPtr, bufPtr, 0);
    }

    /*
     * Return the number of characters copied into the result buffer.
     * This may be different from the number of bytes consumed, because
     * of EOL translations.
     */

    return copied;
}

/*
 *----------------------------------------------------------------------
 *
 * DoWrite --
 *
 *	Puts a sequence of characters into an output buffer, may queue the
 *	buffer for output if it gets full, and also remembers whether the
 *	current buffer is ready e.g. if it contains a newline and we are in
 *	line buffering mode.
 *
 * Results:
 *	The number of bytes written or -1 in case of error. If -1,
 *	Tcl_GetErrno will return the error code.
 *
 * Side effects:
 *	May buffer up output and may cause output to be produced on the
 *	channel.
 *
 *----------------------------------------------------------------------
 */

static int
DoWrite(chanPtr, src, srcLen)
    Channel *chanPtr;			/* The channel to buffer output for. */
    char *src;				/* Data to write. */
    int srcLen;				/* Number of bytes to write. */
{
    ChannelBuffer *outBufPtr;		/* Current output buffer. */
    int foundNewline;			/* Did we find a newline in output? */
    char *dPtr;
    char *sPtr;				/* Search variables for newline. */
    int crsent;				/* In CRLF eol translation mode,
                                         * remember the fact that a CR was
                                         * output to the channel without
                                         * its following NL. */
    int i;				/* Loop index for newline search. */
    int destCopied;			/* How many bytes were used in this
                                         * destination buffer to hold the
                                         * output? */
    int totalDestCopied;		/* How many bytes total were
                                         * copied to the channel buffer? */
    int srcCopied;			/* How many bytes were copied from
                                         * the source string? */
    char *destPtr;			/* Where in line to copy to? */

    /*
     * If we are in network (or windows) translation mode, record the fact
     * that we have not yet sent a CR to the channel.
     */

    crsent = 0;
    
    /*
     * Loop filling buffers and flushing them until all output has been
     * consumed.
     */

    srcCopied = 0;
    totalDestCopied = 0;

    while (srcLen > 0) {
        
        /*
         * Make sure there is a current output buffer to accept output.
         */

        if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) {
            chanPtr->curOutPtr = AllocChannelBuffer(chanPtr->bufSize);
        }

        outBufPtr = chanPtr->curOutPtr;

        destCopied = outBufPtr->bufLength - outBufPtr->nextAdded;
        if (destCopied > srcLen) {
            destCopied = srcLen;
        }
        
        destPtr = outBufPtr->buf + outBufPtr->nextAdded;
        switch (chanPtr->outputTranslation) {
            case TCL_TRANSLATE_LF:
                srcCopied = destCopied;
                memcpy((VOID *) destPtr, (VOID *) src, (size_t) destCopied);
                break;
            case TCL_TRANSLATE_CR:
                srcCopied = destCopied;
                memcpy((VOID *) destPtr, (VOID *) src, (size_t) destCopied);
                for (dPtr = destPtr; dPtr < destPtr + destCopied; dPtr++) {
                    if (*dPtr == '\n') {
                        *dPtr = '\r';
                    }
                }
                break;
            case TCL_TRANSLATE_CRLF:
                for (srcCopied = 0, dPtr = destPtr, sPtr = src;
                     dPtr < destPtr + destCopied;
                     dPtr++, sPtr++, srcCopied++) {
                    if (*sPtr == '\n') {
                        if (crsent) {
                            *dPtr = '\n';
                            crsent = 0;
                        } else {
                            *dPtr = '\r';
                            crsent = 1;
                            sPtr--, srcCopied--;
                        }
                    } else {
                        *dPtr = *sPtr;
                    }
                }
                break;
            case TCL_TRANSLATE_AUTO:
                panic("Tcl_Write: AUTO output translation mode not supported");
            default:
                panic("Tcl_Write: unknown output translation mode");
        }

        /*
         * The current buffer is ready for output if it is full, or if it
         * contains a newline and this channel is line-buffered, or if it
         * contains any output and this channel is unbuffered.
         */

        outBufPtr->nextAdded += destCopied;
        if (!(chanPtr->flags & BUFFER_READY)) {
            if (outBufPtr->nextAdded == outBufPtr->bufLength) {
                chanPtr->flags |= BUFFER_READY;
            } else if (chanPtr->flags & CHANNEL_LINEBUFFERED) {
                for (sPtr = src, i = 0, foundNewline = 0;
                         (i < srcCopied) && (!foundNewline);
                         i++, sPtr++) {
                    if (*sPtr == '\n') {
                        foundNewline = 1;
                        break;
                    }
                }
                if (foundNewline) {
                    chanPtr->flags |= BUFFER_READY;
                }
            } else if (chanPtr->flags & CHANNEL_UNBUFFERED) {
                chanPtr->flags |= BUFFER_READY;
            }
        }
        
        totalDestCopied += srcCopied;
        src += srcCopied;
        srcLen -= srcCopied;

        if (chanPtr->flags & BUFFER_READY) {
            if (FlushChannel(NULL, chanPtr, 0) != 0) {
                return -1;
            }
        }
    } /* Closes "while" */

    return totalDestCopied;
}

/*
 *----------------------------------------------------------------------
 *
 * CopyEventProc --
 *
 *	This routine is invoked as a channel event handler for
6007
6008
6009
6010
6011
6012
6013














































	}
        Tcl_DecrRefCount(csPtr->cmdPtr);
    }
    csPtr->readPtr->csPtr = NULL;
    csPtr->writePtr->csPtr = NULL;
    ckfree((char*) csPtr);
}





















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
	}
        Tcl_DecrRefCount(csPtr->cmdPtr);
    }
    csPtr->readPtr->csPtr = NULL;
    csPtr->writePtr->csPtr = NULL;
    ckfree((char*) csPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * SetBlockMode --
 *
 *	This function sets the blocking mode for a channel and updates
 *	the state flags.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Modifies the blocking mode of the channel and possibly generates
 *	an error.
 *
 *----------------------------------------------------------------------
 */

static int
SetBlockMode(interp, chanPtr, mode)
    Tcl_Interp *interp;		/* Interp for error reporting. */
    Channel *chanPtr;		/* Channel to modify. */
    int mode;			/* One of TCL_MODE_BLOCKING or
				 * TCL_MODE_NONBLOCKING. */
{
    int result = 0;
    if (chanPtr->typePtr->blockModeProc != NULL) {
	result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData,
		mode);
    }
    if (result != 0) {
	Tcl_SetErrno(result);
	if (interp != (Tcl_Interp *) NULL) {
	    Tcl_AppendResult(interp, "error setting blocking mode: ",
		    Tcl_PosixError(interp), (char *) NULL);
	}
	return TCL_ERROR;
    }
    if (mode == TCL_MODE_BLOCKING) {
	chanPtr->flags &= (~(CHANNEL_NONBLOCKING | BG_FLUSH_SCHEDULED));
    } else {
	chanPtr->flags |= CHANNEL_NONBLOCKING;
    }
    return TCL_OK;
}

Changes to generic/tclIOCmd.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
/* 
 * tclIOCmd.c --
 *
 *	Contains the definitions of most of the Tcl commands relating to IO.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclIOCmd.c 1.119 97/07/25 20:49:23
 */

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

/*
 * Return at most this number of bytes in one call to Tcl_Read:
 */

#define	TCL_READ_CHUNK_SIZE	4096

/*
 * Callback structure for accept callback in a TCP server.
 */

typedef struct AcceptCallback {
    char *script;			/* Script to invoke. */





|




|


|
|
<
<
<
<
<
<







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






16
17
18
19
20
21
22
/* 
 * tclIOCmd.c --
 *
 *	Contains the definitions of most of the Tcl commands relating to IO.
 *
 * 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: tclIOCmd.c,v 1.1.2.5 1999/03/26 22:39:53 rjohnson Exp $
 */

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







/*
 * Callback structure for accept callback in a TCP server.
 */

typedef struct AcceptCallback {
    char *script;			/* Script to invoke. */
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
    int i;				/* Counter. */
    int newline;			/* Add a newline at end? */
    char *channelId;			/* Name of channel for puts. */
    int result;				/* Result of puts operation. */
    int mode;				/* Mode in which channel is opened. */
    char *arg;
    int length;
    Tcl_Obj *resultPtr;

    i = 1;
    newline = 1;
    if ((objc >= 2) && (strcmp(Tcl_GetStringFromObj(objv[1], NULL),
	    "-nonewline") == 0)) {
	newline = 0;
	i++;
    }
    if ((i < (objc-3)) || (i >= objc)) {
	Tcl_WrongNumArgs(interp, 1, objv, "?-nonewline? ?channelId? string");
	return TCL_ERROR;
    }

    /*
     * The code below provides backwards compatibility with an old
     * form of the command that is no longer recommended or documented.
     */

    resultPtr = Tcl_NewObj();
    if (i == (objc-3)) {
	arg = Tcl_GetStringFromObj(objv[i+2], &length);
	if (strncmp(arg, "nonewline", (size_t) length) != 0) {
	    Tcl_AppendStringsToObj(resultPtr, "bad argument \"", arg,
		    "\": should be \"nonewline\"", (char *) NULL);
            Tcl_SetObjResult(interp, resultPtr);
	    return TCL_ERROR;
	}
	newline = 0;
    }
    if (i == (objc-1)) {
	channelId = "stdout";
    } else {
	channelId = Tcl_GetStringFromObj(objv[i], NULL);
	i++;
    }
    chan = Tcl_GetChannel(interp, channelId, &mode);
    if (chan == (Tcl_Channel) NULL) {
        Tcl_DecrRefCount(resultPtr);
        return TCL_ERROR;
    }
    if ((mode & TCL_WRITABLE) == 0) {
	Tcl_AppendStringsToObj(resultPtr, "channel \"", channelId,
                "\" wasn't opened for writing", (char *) NULL);
        Tcl_SetObjResult(interp, resultPtr);
        return TCL_ERROR;
    }

    arg = Tcl_GetStringFromObj(objv[i], &length);
    result = Tcl_Write(chan, arg, length);
    if (result < 0) {
        goto error;
    }
    if (newline != 0) {
        result = Tcl_Write(chan, "\n", 1);
        if (result < 0) {
            goto error;
        }
    }
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;

error:
    Tcl_AppendStringsToObj(resultPtr, "error writing \"",
	    Tcl_GetChannelName(chan), "\": ", Tcl_PosixError(interp),
	    (char *) NULL);
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FlushObjCmd --







<



|
<













<

|

|

<




|


|




<



|

<



<
|




|




<

>
|
|
<
|
<







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
    int i;				/* Counter. */
    int newline;			/* Add a newline at end? */
    char *channelId;			/* Name of channel for puts. */
    int result;				/* Result of puts operation. */
    int mode;				/* Mode in which channel is opened. */
    char *arg;
    int length;


    i = 1;
    newline = 1;
    if ((objc >= 2) && (strcmp(Tcl_GetString(objv[1]), "-nonewline") == 0)) {

	newline = 0;
	i++;
    }
    if ((i < (objc-3)) || (i >= objc)) {
	Tcl_WrongNumArgs(interp, 1, objv, "?-nonewline? ?channelId? string");
	return TCL_ERROR;
    }

    /*
     * The code below provides backwards compatibility with an old
     * form of the command that is no longer recommended or documented.
     */


    if (i == (objc-3)) {
	arg = Tcl_GetStringFromObj(objv[i + 2], &length);
	if (strncmp(arg, "nonewline", (size_t) length) != 0) {
	    Tcl_AppendResult(interp, "bad argument \"", arg,
		    "\": should be \"nonewline\"", (char *) NULL);

	    return TCL_ERROR;
	}
	newline = 0;
    }
    if (i == (objc - 1)) {
	channelId = "stdout";
    } else {
	channelId = Tcl_GetString(objv[i]);
	i++;
    }
    chan = Tcl_GetChannel(interp, channelId, &mode);
    if (chan == (Tcl_Channel) NULL) {

        return TCL_ERROR;
    }
    if ((mode & TCL_WRITABLE) == 0) {
	Tcl_AppendResult(interp, "channel \"", channelId,
                "\" wasn't opened for writing", (char *) NULL);

        return TCL_ERROR;
    }


    result = Tcl_WriteObj(chan, objv[i]);
    if (result < 0) {
        goto error;
    }
    if (newline != 0) {
        result = Tcl_WriteChars(chan, "\n", 1);
        if (result < 0) {
            goto error;
        }
    }

    return TCL_OK;

    error:
    Tcl_AppendResult(interp, "error writing \"", channelId, "\": ",

	    Tcl_PosixError(interp), (char *) NULL);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FlushObjCmd --
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
Tcl_FlushObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to flush on. */
    char *arg;
    Tcl_Obj *resultPtr;
    int mode;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
	return TCL_ERROR;
    }
    arg = Tcl_GetStringFromObj(objv[1], NULL);
    chan = Tcl_GetChannel(interp, arg, &mode);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    resultPtr = Tcl_GetObjResult(interp);
    if ((mode & TCL_WRITABLE) == 0) {
	Tcl_AppendStringsToObj(resultPtr, "channel \"",
		Tcl_GetStringFromObj(objv[1], NULL), 
                "\" wasn't opened for writing", (char *) NULL);
        return TCL_ERROR;
    }
    
    if (Tcl_Flush(chan) != TCL_OK) {
	Tcl_AppendStringsToObj(resultPtr, "error flushing \"",
		Tcl_GetChannelName(chan), "\": ", Tcl_PosixError(interp),
		(char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|
<






|
|



<

|
<
|




|
<
|







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
Tcl_FlushObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to flush on. */
    char *channelId;

    int mode;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
	return TCL_ERROR;
    }
    channelId = Tcl_GetString(objv[1]);
    chan = Tcl_GetChannel(interp, channelId, &mode);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }

    if ((mode & TCL_WRITABLE) == 0) {
	Tcl_AppendResult(interp, "channel \"", channelId,

		"\" wasn't opened for writing", (char *) NULL);
        return TCL_ERROR;
    }
    
    if (Tcl_Flush(chan) != TCL_OK) {
	Tcl_AppendResult(interp, "error flushing \"", channelId, "\": ",

		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
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
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to read from. */
    int lineLen;			/* Length of line just read. */
    int mode;				/* Mode in which channel is opened. */
    char *arg;
    Tcl_Obj *resultPtr, *objPtr;

    if ((objc != 2) && (objc != 3)) {
	Tcl_WrongNumArgs(interp, 1, objv, "channelId ?varName?");
	return TCL_ERROR;
    }
    arg = Tcl_GetStringFromObj(objv[1], NULL);
    chan = Tcl_GetChannel(interp, arg, &mode);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    resultPtr = Tcl_NewObj();
    if ((mode & TCL_READABLE) == 0) {
	Tcl_AppendStringsToObj(resultPtr, "channel \"", arg,
                "\" wasn't opened for reading", (char *) NULL);
        Tcl_SetObjResult(interp, resultPtr);
        return TCL_ERROR;
    }











    lineLen = Tcl_GetsObj(chan, resultPtr);
    if (lineLen < 0) {
        if (!Tcl_Eof(chan) && !Tcl_InputBlocked(chan)) {
	    Tcl_SetObjLength(resultPtr, 0);



	    Tcl_AppendStringsToObj(resultPtr, "error reading \"",
		    Tcl_GetChannelName(chan), "\": ", Tcl_PosixError(interp),
		    (char *) NULL);
            Tcl_SetObjResult(interp, resultPtr);
            return TCL_ERROR;
        }
        lineLen = -1;
    }
    if (objc == 3) {
	Tcl_ResetResult(interp);
	objPtr = Tcl_ObjSetVar2(interp, objv[2], NULL,
		resultPtr, TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1);
	if (objPtr == NULL) {
            Tcl_DecrRefCount(resultPtr);
            return TCL_ERROR;
        }
        Tcl_ResetResult(interp);
	Tcl_SetIntObj(Tcl_GetObjResult(interp), lineLen);
        return TCL_OK;
    }
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ReadObjCmd --







|
|





|
|



<

|
|
<



>
>
>
>
>
>
>
>
>
>
|


|
>
>
>
|
<
|
<





<
|
|
<
|


<
|


<







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
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to read from. */
    int lineLen;			/* Length of line just read. */
    int mode;				/* Mode in which channel is opened. */
    char *name;
    Tcl_Obj *resultPtr, *linePtr;

    if ((objc != 2) && (objc != 3)) {
	Tcl_WrongNumArgs(interp, 1, objv, "channelId ?varName?");
	return TCL_ERROR;
    }
    name = Tcl_GetString(objv[1]);
    chan = Tcl_GetChannel(interp, name, &mode);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }

    if ((mode & TCL_READABLE) == 0) {
	Tcl_AppendResult(interp, "channel \"", name,
		"\" wasn't opened for reading", (char *) NULL);

        return TCL_ERROR;
    }

    resultPtr = Tcl_GetObjResult(interp);
    linePtr = resultPtr;
    if (objc == 3) {
	/*
	 * Variable gets line, interp get bytecount.
	 */

	linePtr = Tcl_NewObj();
    }

    lineLen = Tcl_GetsObj(chan, linePtr);
    if (lineLen < 0) {
        if (!Tcl_Eof(chan) && !Tcl_InputBlocked(chan)) {
	    if (linePtr != resultPtr) {
		Tcl_DecrRefCount(linePtr);
	    }
	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp, "error reading \"", name, "\": ",

		    Tcl_PosixError(interp), (char *) NULL);

            return TCL_ERROR;
        }
        lineLen = -1;
    }
    if (objc == 3) {

	if (Tcl_ObjSetVar2(interp, objv[2], NULL, linePtr,
		TCL_LEAVE_ERR_MSG) == NULL) {

	    Tcl_DecrRefCount(linePtr);
            return TCL_ERROR;
        }

	Tcl_SetIntObj(resultPtr, lineLen);
        return TCL_OK;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ReadObjCmd --
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359


360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446

447


448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488




489
490
491
492
493
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519

520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
577
578
579
580
581
582
int
Tcl_ReadObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to read from. */
    int newline, i;			/* Discard newline at end? */
    int toRead;				/* How many bytes to read? */
    int toReadNow;			/* How many bytes to attempt to
                                         * read in the current iteration? */
    int charactersRead;			/* How many characters were read? */
    int charactersReadNow;		/* How many characters were read
                                         * in this iteration? */
    int mode;				/* Mode in which channel is opened. */
    int bufSize;			/* Channel buffer size; used to decide
                                         * in what chunk sizes to read from
                                         * the channel. */
    char *arg;
    Tcl_Obj *resultPtr;

    if ((objc != 2) && (objc != 3)) {
argerror:
	Tcl_WrongNumArgs(interp, 1, objv, "channelId ?numBytes?");
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), " or \"",
		Tcl_GetStringFromObj(objv[0], NULL),
		" ?-nonewline? channelId\"", (char *) NULL);
	return TCL_ERROR;
    }

    i = 1;
    newline = 0;
    if (strcmp(Tcl_GetStringFromObj(objv[1], NULL), "-nonewline") == 0) {
	newline = 1;
	i++;
    }

    if (i == objc) {
        goto argerror;
    }

    arg =  Tcl_GetStringFromObj(objv[i], NULL);
    chan = Tcl_GetChannel(interp, arg, &mode);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    if ((mode & TCL_READABLE) == 0) {
	resultPtr = Tcl_GetObjResult(interp);
	Tcl_AppendStringsToObj(resultPtr, "channel \"", arg,
                "\" wasn't opened for reading", (char *) NULL);
        return TCL_ERROR;
    }
    
    i++;	/* Consumed channel name. */

    /*
     * Compute how many bytes to read, and see whether the final
     * newline should be dropped.
     */

    toRead = INT_MAX;
    if (i < objc) {


	arg = Tcl_GetStringFromObj(objv[i], NULL);
	if (isdigit((unsigned char) (arg[0]))) {
	    if (Tcl_GetIntFromObj(interp, objv[i], &toRead) != TCL_OK) {
                return TCL_ERROR;
	    }
	    Tcl_ResetResult(interp);
	} else if (strcmp(arg, "nonewline") == 0) {
	    newline = 1;
	} else {
	    resultPtr = Tcl_GetObjResult(interp);
	    Tcl_AppendStringsToObj(resultPtr, "bad argument \"", arg,
		    "\": should be \"nonewline\"", (char *) NULL);
	    return TCL_ERROR;
        }
    }

    /*
     * Create a new object and use that instead of the interpreter
     * result. We cannot use the interpreter's result object because
     * it may get smashed at any time by recursive calls.
     */
    
    resultPtr = Tcl_NewObj();
    
    bufSize = Tcl_GetChannelBufferSize(chan);

    /*
     * If the caller specified a maximum length to read, then that is
     * a good size to preallocate.
     */
    
    if ((toRead != INT_MAX) && (toRead > bufSize)) {
        Tcl_SetObjLength(resultPtr, toRead);
    }
    
    for (charactersRead = 0; charactersRead < toRead; ) {
        toReadNow = toRead - charactersRead;
        if (toReadNow > bufSize) {
            toReadNow = bufSize;
        }

        /*
         * NOTE: This is a NOOP if we set the size (above) to the
         * number of bytes we expect to read. In the degenerate
         * case, however, it will grow the buffer by the channel
         * buffersize, which is 4K in most cases. This will result
         * in inefficient copying for large files. This will be
         * fixed in a future release.
         */
        
	Tcl_SetObjLength(resultPtr, charactersRead + toReadNow);
        charactersReadNow =
            Tcl_Read(chan, Tcl_GetStringFromObj(resultPtr, NULL)
		    + charactersRead, toReadNow);
        if (charactersReadNow < 0) {
	    Tcl_SetObjLength(resultPtr, 0);
            Tcl_AppendStringsToObj(resultPtr, "error reading \"",
		    Tcl_GetChannelName(chan), "\": ",
		    Tcl_PosixError(interp), (char *) NULL);
            Tcl_SetObjResult(interp, resultPtr);

            return TCL_ERROR;
        }

        /*
         * If we had a short read it means that we have either EOF
         * or BLOCKED on the channel, so break out.
         */
        
        charactersRead += charactersReadNow;

        /*
         * Do not call the driver again if we got a short read
         */
        
        if (charactersReadNow < toReadNow) {
            break;	/* Out of "for" loop. */
        }
    }
    
    /*
     * If requested, remove the last newline in the channel if at EOF.
     */
    
    if ((charactersRead > 0) && (newline) &&
          (Tcl_GetStringFromObj(resultPtr, NULL)[charactersRead-1] == '\n')) {
	charactersRead--;

    }


    Tcl_SetObjLength(resultPtr, charactersRead);

    /*
     * Now set the object into the interpreter result and release our
     * hold on it by decrrefing it.
     */

    Tcl_SetObjResult(interp, resultPtr);
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SeekCmd --
 *
 *	This procedure is invoked to process the Tcl "seek" command. See
 *	the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Moves the position of the access point on the specified channel.
 *	May flush queued output.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_SeekCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    Tcl_Channel chan;			/* The channel to tell on. */
    int offset, mode;			/* Where to seek? */
    int result;				/* Of calling Tcl_Seek. */





    if ((argc != 3) && (argc != 4)) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" channelId offset ?origin?\"", (char *) NULL);
	return TCL_ERROR;
    }

    chan = Tcl_GetChannel(interp, argv[1], NULL);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    if (Tcl_GetInt(interp, argv[2], &offset) != TCL_OK) {
	return TCL_ERROR;
    }
    mode = SEEK_SET;
    if (argc == 4) {
	size_t length;
	int c;

	length = strlen(argv[3]);
	c = argv[3][0];
	if ((c == 's') && (strncmp(argv[3], "start", length) == 0)) {
	    mode = SEEK_SET;
	} else if ((c == 'c') && (strncmp(argv[3], "current", length) == 0)) {
	    mode = SEEK_CUR;
	} else if ((c == 'e') && (strncmp(argv[3], "end", length) == 0)) {
	    mode = SEEK_END;
	} else {
	    Tcl_AppendResult(interp, "bad origin \"", argv[3],
		    "\": should be start, current, or end", (char *) NULL);
	    return TCL_ERROR;
	}

    }

    result = Tcl_Seek(chan, offset, mode);
    if (result == -1) {
        Tcl_AppendResult(interp, "error during seek on \"", 
		Tcl_GetChannelName(chan), "\": ",
                Tcl_PosixError(interp), (char *) NULL);
        return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TellCmd --
 *
 *	This procedure is invoked to process the Tcl "tell" command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_TellCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    Tcl_Channel chan;			/* The channel to tell on. */
    char buf[40];

    if (argc != 2) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" channelId\"", (char *) NULL);
	return TCL_ERROR;
    }
    /*
     * Try to find a channel with the right name and permissions in
     * the IO channel table of this interpreter.
     */
    

    chan = Tcl_GetChannel(interp, argv[1], NULL);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    TclFormatInt(buf, Tcl_Tell(chan));
    Tcl_SetResult(interp, buf, TCL_VOLATILE);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CloseObjCmd --







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



|

<
|



>


|








|
|




<
|



<







|

>
>
|
|



<



<
|





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






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






|
















|


|
|




>
>
>
>

|
<
|


>
|



|



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


>





<
|








|















|


|
|


|

|
<
|







>
|



|
<







284
285
286
287
288
289
290
291
292
293


294


295



296
297
298
299
300
301

302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

344
345
346

347
348
349
350
351
352






353




























354


355
356
357

358


359
















360
361
362
363
364
365
366

367
368
369
370
371
372
373




374


375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
421
422
423
424
425


426

427









428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470

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

485
486
487
488
489
490
491
int
Tcl_ReadObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;		/* The channel to read from. */
    int newline, i;		/* Discard newline at end? */
    int toRead;			/* How many bytes to read? */


    int charactersRead;		/* How many characters were read? */


    int mode;			/* Mode in which channel is opened. */



    char *name;
    Tcl_Obj *resultPtr;

    if ((objc != 2) && (objc != 3)) {
	argerror:
	Tcl_WrongNumArgs(interp, 1, objv, "channelId ?numBytes?");

	Tcl_AppendResult(interp, " or \"", Tcl_GetString(objv[0]),
		" ?-nonewline? channelId\"", (char *) NULL);
	return TCL_ERROR;
    }

    i = 1;
    newline = 0;
    if (strcmp(Tcl_GetString(objv[1]), "-nonewline") == 0) {
	newline = 1;
	i++;
    }

    if (i == objc) {
        goto argerror;
    }

    name = Tcl_GetString(objv[i]);
    chan = Tcl_GetChannel(interp, name, &mode);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    if ((mode & TCL_READABLE) == 0) {

	Tcl_AppendResult(interp, "channel \"", name, 
                "\" wasn't opened for reading", (char *) NULL);
        return TCL_ERROR;
    }

    i++;	/* Consumed channel name. */

    /*
     * Compute how many bytes to read, and see whether the final
     * newline should be dropped.
     */

    toRead = -1;
    if (i < objc) {
	char *arg;
	
	arg = Tcl_GetString(objv[i]);
	if (isdigit(UCHAR(arg[0]))) { /* INTL: digit */
	    if (Tcl_GetIntFromObj(interp, objv[i], &toRead) != TCL_OK) {
                return TCL_ERROR;
	    }

	} else if (strcmp(arg, "nonewline") == 0) {
	    newline = 1;
	} else {

	    Tcl_AppendResult(interp, "bad argument \"", arg,
		    "\": should be \"nonewline\"", (char *) NULL);
	    return TCL_ERROR;
        }
    }







    resultPtr = Tcl_GetObjResult(interp);




























    charactersRead = Tcl_ReadChars(chan, resultPtr, toRead, 0);


    if (charactersRead < 0) {
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "error reading \"", name, "\": ",

		Tcl_PosixError(interp), (char *) NULL);


	return TCL_ERROR;
















    }
    
    /*
     * If requested, remove the last newline in the channel if at EOF.
     */
    
    if ((charactersRead > 0) && (newline != 0)) {

	char *result;
	int length;

	result = Tcl_GetStringFromObj(resultPtr, &length);
	if (result[length - 1] == '\n') {
	    Tcl_SetObjLength(resultPtr, length - 1);
	}




    }


    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SeekObjCmd --
 *
 *	This procedure is invoked to process the Tcl "seek" command. See
 *	the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Moves the position of the access point on the specified channel.
 *	May flush queued output.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_SeekObjCmd(clientData, interp, objc, objv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to tell on. */
    int offset, mode;			/* Where to seek? */
    int result;				/* Of calling Tcl_Seek. */
    char *chanName;
    int optionIndex;
    static char *originOptions[] = {"start", "current", "end", (char *) NULL};
    static int modeArray[] = {SEEK_SET, SEEK_CUR, SEEK_END};

    if ((objc != 3) && (objc != 4)) {

	Tcl_WrongNumArgs(interp, 1, objv, "channelId offset ?origin?");
	return TCL_ERROR;
    }
    chanName = Tcl_GetString(objv[1]);
    chan = Tcl_GetChannel(interp, chanName, NULL);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    if (Tcl_GetIntFromObj(interp, objv[2], &offset) != TCL_OK) {
	return TCL_ERROR;
    }
    mode = SEEK_SET;
    if (objc == 4) {


	if (Tcl_GetIndexFromObj(interp, objv[3], originOptions, "origin", 0,

		&optionIndex) != TCL_OK) {









	    return TCL_ERROR;
	}
	mode = modeArray[optionIndex];
    }

    result = Tcl_Seek(chan, offset, mode);
    if (result == -1) {
        Tcl_AppendResult(interp, "error during seek on \"", 

		chanName, "\": ", Tcl_PosixError(interp), (char *) NULL);
        return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TellObjCmd --
 *
 *	This procedure is invoked to process the Tcl "tell" command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_TellObjCmd(clientData, interp, objc, objv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to tell on. */
    char *chanName;

    if (objc != 2) {

	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
	return TCL_ERROR;
    }
    /*
     * Try to find a channel with the right name and permissions in
     * the IO channel table of this interpreter.
     */
    
    chanName = Tcl_GetString(objv[1]);
    chan = Tcl_GetChannel(interp, chanName, NULL);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    Tcl_SetIntObj(Tcl_GetObjResult(interp), Tcl_Tell(chan));

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CloseObjCmd --
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634




635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
674
675
676
677

678
679
680
681
682
683
684
685
686
687
688
689
690
691
692

693
694
695
696
697
698
699
700


701

702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780

781
782
783

784
785










786
787
788







789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804



805
806





807
808
809
810
811
812
813
814
815
816
817
818
819

820
821
822
823
824
825





















826
827
828
829








830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848

849
850
851
852
853
854
855
856
857
858
859
860
861
862
863

864
865
866
867
868
869
870
871



872
873

874
875


876
877
878
879
880
881
882
883
884
885
886

887
888
889
890


891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995

996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
Tcl_CloseObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to close. */
    int len;				/* Length of error output. */
    char *arg;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
	return TCL_ERROR;
    }

    arg = Tcl_GetStringFromObj(objv[1], NULL);
    chan = Tcl_GetChannel(interp, arg, NULL);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }

    if (Tcl_UnregisterChannel(interp, chan) != TCL_OK) {
        /*
         * If there is an error message and it ends with a newline, remove
         * the newline. This is done for command pipeline channels where the
         * error output from the subprocesses is stored in interp->result.
         *
         * NOTE: This is likely to not have any effect on regular error
         * messages produced by drivers during the closing of a channel,
         * because the Tcl convention is that such error messages do not
         * have a terminating newline.
         */

        len = strlen(interp->result);
        if ((len > 0) && (interp->result[len - 1] == '\n')) {
            interp->result[len - 1] = '\0';
        }




        
        return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FconfigureCmd --
 *
 *	This procedure is invoked to process the Tcl "fconfigure" command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	May modify the behavior of an IO channel.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_FconfigureCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{

    Tcl_Channel chan;			/* The channel to set a mode on. */
    int i;				/* Iterate over arg-value pairs. */
    Tcl_DString ds;			/* DString to hold result of
                                         * calling Tcl_GetChannelOption. */

    if ((argc < 2) || (((argc % 2) == 1) && (argc != 3))) {
        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                " channelId ?optionName? ?value? ?optionName value?...\"",
                (char *) NULL);
        return TCL_ERROR;
    }

    chan = Tcl_GetChannel(interp, argv[1], NULL);
    if (chan == (Tcl_Channel) NULL) {
        return TCL_ERROR;
    }
    if (argc == 2) {
        Tcl_DStringInit(&ds);
        if (Tcl_GetChannelOption(interp, chan, (char *) NULL, &ds) != TCL_OK) {
	    Tcl_DStringFree(&ds);
	    return TCL_ERROR;
        }
        Tcl_DStringResult(interp, &ds);
        return TCL_OK;
    }
    if (argc == 3) {
        Tcl_DStringInit(&ds);

        if (Tcl_GetChannelOption(interp, chan, argv[2], &ds) != TCL_OK) {
            Tcl_DStringFree(&ds);
            return TCL_ERROR;
        }
        Tcl_DStringResult(interp, &ds);
        return TCL_OK;
    }
    for (i = 3; i < argc; i += 2) {


        if (Tcl_SetChannelOption(interp, chan, argv[i-1], argv[i]) != TCL_OK) {

            return TCL_ERROR;
        }
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_EofObjCmd --
 *
 *	This procedure is invoked to process the Tcl "eof" command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Sets interp->result to "0" or "1" depending on whether the
 *	specified channel has an EOF condition.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_EofObjCmd(unused, interp, objc, objv)
    ClientData unused;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to query for EOF. */
    int mode;				/* Mode in which channel is opened. */
    char buf[40];
    char *arg;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
        return TCL_ERROR;
    }

    arg = Tcl_GetStringFromObj(objv[1], NULL);
    chan = Tcl_GetChannel(interp, arg, &mode);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }

    TclFormatInt(buf, Tcl_Eof(chan) ? 1 : 0);
    Tcl_SetResult(interp, buf, TCL_VOLATILE);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ExecCmd --
 *
 *	This procedure is invoked to process the "exec" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_ExecCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
#ifdef MAC_TCL

    Tcl_AppendResult(interp, "exec not implemented under Mac OS",
		(char *)NULL);
    return TCL_ERROR;

#else /* !MAC_TCL */
    int keepNewline, firstWord, background, length, result;










    Tcl_Channel chan;
    Tcl_DString ds;
    int readSoFar, readNow, bufSize;








    /*
     * Check for a leading "-keepnewline" argument.
     */

    keepNewline = 0;
    for (firstWord = 1; (firstWord < argc) && (argv[firstWord][0] == '-');
	  firstWord++) {
	if (strcmp(argv[firstWord], "-keepnewline") == 0) {
	    keepNewline = 1;
	} else if (strcmp(argv[firstWord], "--") == 0) {
	    firstWord++;
	    break;
	} else {
	    Tcl_AppendResult(interp, "bad switch \"", argv[firstWord],
		    "\": must be -keepnewline or --", (char *) NULL);



	    return TCL_ERROR;
	}





    }

    if (argc <= firstWord) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" ?switches? arg ?arg ...?\"", (char *) NULL);
	return TCL_ERROR;
    }

    /*
     * See if the command is to be run in background.
     */

    background = 0;

    if ((argv[argc-1][0] == '&') && (argv[argc-1][1] == 0)) {
	argc--;
	argv[argc] = NULL;
        background = 1;
    }
    





















    chan = Tcl_OpenCommandChannel(interp, argc-firstWord,
            argv+firstWord,
	    (background ? 0 : TCL_STDOUT | TCL_STDERR));









    if (chan == (Tcl_Channel) NULL) {
        return TCL_ERROR;
    }

    if (background) {

        /*
         * Get the list of PIDs from the pipeline into interp->result and
         * detach the PIDs (instead of waiting for them).
         */

        TclGetAndDetachPids(interp, chan);
        
        if (Tcl_Close(interp, chan) != TCL_OK) {
            return TCL_ERROR;
        }
        return TCL_OK;
    }


    if (Tcl_GetChannelHandle(chan, TCL_READABLE, NULL) == TCL_OK) {
#define	EXEC_BUFFER_SIZE 4096

        Tcl_DStringInit(&ds);
        readSoFar = 0; bufSize = 0;
        while (1) {
            bufSize += EXEC_BUFFER_SIZE;
            Tcl_DStringSetLength(&ds, bufSize);
            readNow = Tcl_Read(chan, Tcl_DStringValue(&ds) + readSoFar,
                    EXEC_BUFFER_SIZE);
            if (readNow < 0) {
                Tcl_DStringFree(&ds);
		Tcl_AppendResult(interp,
			"error reading output from command: ",
			Tcl_PosixError(interp), (char *) NULL);

                return TCL_ERROR;
            }
            readSoFar += readNow;
            if (readNow < EXEC_BUFFER_SIZE) {
                break;	/* Out of "while (1)" loop. */
            }
        }
        Tcl_DStringSetLength(&ds, readSoFar);



        Tcl_DStringResult(interp, &ds);
    }


    result = Tcl_Close(interp, chan);



    /*
     * If the last character of interp->result is a newline, then remove
     * the newline character (the newline would just confuse things).
     * Special hack: must replace the old terminating null character
     * as a signal to Tcl_AppendResult et al. that we've mucked with
     * the string.
     */
    
    length = strlen(interp->result);
    if (!keepNewline && (length > 0) &&

        (interp->result[length-1] == '\n')) {
        interp->result[length-1] = '\0';
        interp->result[length] = 'x';
    }



    return result;
#endif /* !MAC_TCL */
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FblockedObjCmd --
 *
 *	This procedure is invoked to process the Tcl "fblocked" command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Sets interp->result to "0" or "1" depending on whether the
 *	a preceding input operation on the channel would have blocked.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_FblockedObjCmd(unused, interp, objc, objv)
    ClientData unused;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to query for blocked. */
    int mode;				/* Mode in which channel was opened. */
    char buf[40];
    char *arg;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
        return TCL_ERROR;
    }

    arg = Tcl_GetStringFromObj(objv[1], NULL);
    chan = Tcl_GetChannel(interp, arg, &mode);
    if (chan == (Tcl_Channel) NULL) {
        return TCL_ERROR;
    }
    if ((mode & TCL_READABLE) == 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"",
		Tcl_GetStringFromObj(objv[1], NULL), 
                "\" wasn't opened for reading", (char *) NULL);
        return TCL_ERROR;
    }
        
    TclFormatInt(buf, Tcl_InputBlocked(chan) ? 1 : 0);
    Tcl_SetResult(interp, buf, TCL_VOLATILE);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_OpenCmd --
 *
 *	This procedure is invoked to process the "open" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_OpenCmd(notUsed, interp, argc, argv)
    ClientData notUsed;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    int pipeline, prot;
    char *modeString;
    Tcl_Channel chan;

    if ((argc < 2) || (argc > 4)) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" fileName ?access? ?permissions?\"", (char *) NULL);
	return TCL_ERROR;
    }
    prot = 0666;
    if (argc == 2) {
	modeString = "r";
    } else {
	modeString = argv[2];
	if (argc == 4) {
	    if (Tcl_GetInt(interp, argv[3], &prot) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
    }

    pipeline = 0;

    if (argv[1][0] == '|') {
	pipeline = 1;
    }

    /*
     * Open the file or create a process pipeline.
     */

    if (!pipeline) {
        chan = Tcl_OpenFileChannel(interp, argv[1], modeString, prot);
    } else {
#ifdef MAC_TCL
	Tcl_AppendResult(interp,
		"command pipelines not supported on Macintosh OS",
		(char *)NULL);
	return TCL_ERROR;
#else
	int mode, seekFlag, cmdArgc;
	char **cmdArgv;

        if (Tcl_SplitList(interp, argv[1]+1, &cmdArgc, &cmdArgv) != TCL_OK) {
            return TCL_ERROR;
        }

        mode = TclGetOpenMode(interp, modeString, &seekFlag);
        if (mode == -1) {
	    chan = NULL;
        } else {







<







|









|







|
|
|
|
>
>
>
>
|









|















|


|
|

>





|
|
|
<


>
|



|








|

>
|






|
>
>
|
>







|










|
|

|










|
|
<







|
|
|



|
<






|















|


|
|


>



>

|
>
>
>
>
>
>
>
>
>
>

|
<
>
>
>
>
>
>
>






<
|
<
|
|
<

<
<
<
>
>
>


>
>
>
>
>
|
|
|
<
|








>
|
|
<


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

>
>
>
>
>
>
>
>

|



<

|
|
|


<

|

|


>

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


>
>


|
|
<
<
<


<
|
>
|
<
|
|
>
>






|










|
|

|










|
|
<







|

|




<
|



|
<






|















|


|
|


|


|
<
|



|


|
|
|






>
|








|







|


|







507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587

588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714

715
716
717
718
719
720
721
722
723
724
725
726
727

728

729
730

731



732
733
734
735
736
737
738
739
740
741
742
743
744

745
746
747
748
749
750
751
752
753
754
755
756

757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781

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

797
798
799
800
801
802

803
804
805
806
807
808
809
810

811









812
813
814
815
816
817



818


819
820
821
822

823
824
825
826
827
828
829
830
831



832
833

834
835
836

837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873

874
875
876
877
878
879
880
881
882
883
884
885
886
887

888
889
890
891
892

893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925

926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
Tcl_CloseObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;			/* The channel to close. */

    char *arg;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
	return TCL_ERROR;
    }

    arg = Tcl_GetString(objv[1]);
    chan = Tcl_GetChannel(interp, arg, NULL);
    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }

    if (Tcl_UnregisterChannel(interp, chan) != TCL_OK) {
        /*
         * If there is an error message and it ends with a newline, remove
         * the newline. This is done for command pipeline channels where the
         * error output from the subprocesses is stored in interp's result.
         *
         * NOTE: This is likely to not have any effect on regular error
         * messages produced by drivers during the closing of a channel,
         * because the Tcl convention is that such error messages do not
         * have a terminating newline.
         */

	Tcl_Obj *resultPtr;
	char *string;
	int len;
	
	resultPtr = Tcl_GetObjResult(interp);
	string = Tcl_GetStringFromObj(resultPtr, &len);
        if ((len > 0) && (string[len - 1] == '\n')) {
	    Tcl_SetObjLength(resultPtr, len - 1);
        }
        return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FconfigureObjCmd --
 *
 *	This procedure is invoked to process the Tcl "fconfigure" command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	May modify the behavior of an IO channel.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_FconfigureObjCmd(clientData, interp, objc, objv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    char *chanName, *optionName, *valueName;
    Tcl_Channel chan;			/* The channel to set a mode on. */
    int i;				/* Iterate over arg-value pairs. */
    Tcl_DString ds;			/* DString to hold result of
                                         * calling Tcl_GetChannelOption. */

    if ((objc < 2) || (((objc % 2) == 1) && (objc != 3))) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"channelId ?optionName? ?value? ?optionName value?...");

        return TCL_ERROR;
    }
    chanName = Tcl_GetString(objv[1]);
    chan = Tcl_GetChannel(interp, chanName, NULL);
    if (chan == (Tcl_Channel) NULL) {
        return TCL_ERROR;
    }
    if (objc == 2) {
        Tcl_DStringInit(&ds);
        if (Tcl_GetChannelOption(interp, chan, (char *) NULL, &ds) != TCL_OK) {
	    Tcl_DStringFree(&ds);
	    return TCL_ERROR;
        }
        Tcl_DStringResult(interp, &ds);
        return TCL_OK;
    }
    if (objc == 3) {
        Tcl_DStringInit(&ds);
	optionName = Tcl_GetString(objv[2]);
        if (Tcl_GetChannelOption(interp, chan, optionName, &ds) != TCL_OK) {
            Tcl_DStringFree(&ds);
            return TCL_ERROR;
        }
        Tcl_DStringResult(interp, &ds);
        return TCL_OK;
    }
    for (i = 3; i < objc; i += 2) {
	optionName = Tcl_GetString(objv[i-1]);
	valueName = Tcl_GetString(objv[i]);
        if (Tcl_SetChannelOption(interp, chan, optionName, valueName)
		!= TCL_OK) {
            return TCL_ERROR;
        }
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_EofObjCmd --
 *
 *	This procedure is invoked to process the Tcl "eof" command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Sets interp's result to boolean true or false depending on whether
 *	the specified channel has an EOF condition.
 *
 *---------------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_EofObjCmd(unused, interp, objc, objv)
    ClientData unused;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;
    int dummy;

    char *arg;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
        return TCL_ERROR;
    }

    arg = Tcl_GetString(objv[1]);
    chan = Tcl_GetChannel(interp, arg, &dummy);
    if (chan == NULL) {
	return TCL_ERROR;
    }

    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), Tcl_Eof(chan));

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ExecObjCmd --
 *
 *	This procedure is invoked to process the "exec" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_ExecObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
#ifdef MAC_TCL

    Tcl_AppendResult(interp, "exec not implemented under Mac OS",
		(char *)NULL);
    return TCL_ERROR;

#else /* !MAC_TCL */

    /*
     * This procedure generates an argv array for the string arguments. It
     * starts out with stack-allocated space but uses dynamically-allocated
     * storage if needed.
     */

#define NUM_ARGS 20
    Tcl_Obj *resultPtr;
    char **argv;
    char *string;
    Tcl_Channel chan;
    char *argStorage[NUM_ARGS];

    int argc, background, i, index, keepNewline, result, skip, length;
    static char *options[] = {
	"-keepnewline",	"--",		NULL
    };
    enum options {
	EXEC_KEEPNEWLINE, EXEC_LAST
    };

    /*
     * Check for a leading "-keepnewline" argument.
     */

    keepNewline = 0;

    for (skip = 1; skip < objc; skip++) {

	string = Tcl_GetString(objv[skip]);
	if (string[0] != '-') {

	    break;



	}
	if (Tcl_GetIndexFromObj(interp, objv[skip], options, "switch",
		TCL_EXACT, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == EXEC_KEEPNEWLINE) {
	    keepNewline = 1;
	} else {
	    skip++;
	    break;
	}
    }
    if (objc <= skip) {

	Tcl_WrongNumArgs(interp, 1, objv, "?switches? arg ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * See if the command is to be run in background.
     */

    background = 0;
    string = Tcl_GetString(objv[objc - 1]);
    if ((string[0] == '&') && (string[1] == '\0')) {
	objc--;

        background = 1;
    }

    /*
     * Create the string argument array "argv". Make sure argv is large
     * enough to hold the argc arguments plus 1 extra for the zero
     * end-of-argv word.
     */

    argv = argStorage;
    argc = objc - skip;
    if ((argc + 1) > sizeof(argv) / sizeof(argv[0])) {
	argv = (char **) ckalloc((unsigned)(argc + 1) * sizeof(char *));
    }

    /*
     * Copy the string conversions of each (post option) object into the
     * argument vector.
     */

    for (i = 0; i < argc; i++) {
	argv[i] = Tcl_GetString(objv[i + skip]);
    }
    argv[argc] = NULL;
    chan = Tcl_OpenCommandChannel(interp, argc, argv,

            (background ? 0 : TCL_STDOUT | TCL_STDERR));

    /*
     * Free the argv array if malloc'ed storage was used.
     */

    if (argv != argStorage) {
	ckfree((char *)argv);
    }

    if (chan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }

    if (background) {

        /*
	 * Store the list of PIDs from the pipeline in interp's result and
	 * detach the PIDs (instead of waiting for them).
	 */

        TclGetAndDetachPids(interp, chan);

        if (Tcl_Close(interp, chan) != TCL_OK) {
	    return TCL_ERROR;
        }
	return TCL_OK;
    }

    resultPtr = Tcl_NewObj();
    if (Tcl_GetChannelHandle(chan, TCL_READABLE, NULL) == TCL_OK) {

	if (Tcl_ReadChars(chan, resultPtr, -1, 0) < 0) {









	    Tcl_ResetResult(interp);
	    Tcl_AppendResult(interp, "error reading output from command: ",
		    Tcl_PosixError(interp), (char *) NULL);
	    Tcl_DecrRefCount(resultPtr);
	    return TCL_ERROR;
	}



    }


    /*
     * If the process produced anything on stderr, it will have been
     * returned in the interpreter result.  It needs to be appended to
     * the result string.

     */

    result = Tcl_Close(interp, chan);
    string = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &length);
    Tcl_AppendToObj(resultPtr, string, length);

    /*
     * If the last character of the result is a newline, then remove
     * the newline character.



     */
    

    if (keepNewline == 0) {
	string = Tcl_GetStringFromObj(resultPtr, &length);
	if ((length > 0) && (string[length - 1] == '\n')) {

	    Tcl_SetObjLength(resultPtr, length - 1);
	}
    }
    Tcl_SetObjResult(interp, resultPtr);

    return result;
#endif /* !MAC_TCL */
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_FblockedObjCmd --
 *
 *	This procedure is invoked to process the Tcl "fblocked" command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Sets interp's result to boolean true or false depending on whether
 *	the preceeding input operation on the channel would have blocked.
 *
 *---------------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_FblockedObjCmd(unused, interp, objc, objv)
    ClientData unused;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel chan;
    int mode;

    char *arg;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
        return TCL_ERROR;
    }

    arg = Tcl_GetString(objv[1]);
    chan = Tcl_GetChannel(interp, arg, &mode);
    if (chan == NULL) {
        return TCL_ERROR;
    }
    if ((mode & TCL_READABLE) == 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"",

		arg, "\" wasn't opened for reading", (char *) NULL);
        return TCL_ERROR;
    }
        
    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), Tcl_InputBlocked(chan));

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_OpenObjCmd --
 *
 *	This procedure is invoked to process the "open" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_OpenObjCmd(notUsed, interp, objc, objv)
    ClientData notUsed;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int pipeline, prot;
    char *modeString, *what;
    Tcl_Channel chan;

    if ((objc < 2) || (objc > 4)) {

	Tcl_WrongNumArgs(interp, 1, objv, "fileName ?access? ?permissions?");
	return TCL_ERROR;
    }
    prot = 0666;
    if (objc == 2) {
	modeString = "r";
    } else {
	modeString = Tcl_GetString(objv[2]);
	if (objc == 4) {
	    if (Tcl_GetIntFromObj(interp, objv[3], &prot) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
    }

    pipeline = 0;
    what = Tcl_GetString(objv[1]);
    if (what[0] == '|') {
	pipeline = 1;
    }

    /*
     * Open the file or create a process pipeline.
     */

    if (!pipeline) {
        chan = Tcl_OpenFileChannel(interp, what, modeString, prot);
    } else {
#ifdef MAC_TCL
	Tcl_AppendResult(interp,
		"command pipelines not supported on Macintosh OS",
		(char *)NULL);
	return TCL_ERROR;
#else
	int mode, seekFlag, cmdObjc;
	char **cmdArgv;

        if (Tcl_SplitList(interp, what+1, &cmdObjc, &cmdArgv) != TCL_OK) {
            return TCL_ERROR;
        }

        mode = TclGetOpenMode(interp, modeString, &seekFlag);
        if (mode == -1) {
	    chan = NULL;
        } else {
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
		case O_RDWR:
		    flags |= (TCL_STDIN | TCL_STDOUT);
		    break;
		default:
		    panic("Tcl_OpenCmd: invalid mode value");
		    break;
	    }
	    chan = Tcl_OpenCommandChannel(interp, cmdArgc, cmdArgv, flags);
	}
        ckfree((char *) cmdArgv);
#endif
    }
    if (chan == (Tcl_Channel) NULL) {
        return TCL_ERROR;
    }







|







979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
		case O_RDWR:
		    flags |= (TCL_STDIN | TCL_STDOUT);
		    break;
		default:
		    panic("Tcl_OpenCmd: invalid mode value");
		    break;
	    }
	    chan = Tcl_OpenCommandChannel(interp, cmdObjc, cmdArgv, flags);
	}
        ckfree((char *) cmdArgv);
#endif
    }
    if (chan == (Tcl_Channel) NULL) {
        return TCL_ERROR;
    }
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240








1241
1242
1243
1244
1245
1246








1247
1248
1249
1250
1251
1252
1253
    char *address;			/* Address of client that was
                                         * accepted. */
    int port;				/* Port of client that was accepted. */
{
    AcceptCallback *acceptCallbackPtr;
    Tcl_Interp *interp;
    char *script;
    char portBuf[10];
    int result;

    acceptCallbackPtr = (AcceptCallback *) callbackData;

    /*
     * Check if the callback is still valid; the interpreter may have gone
     * away, this is signalled by setting the interp field of the callback
     * data to NULL.
     */
    
    if (acceptCallbackPtr->interp != (Tcl_Interp *) NULL) {

        script = acceptCallbackPtr->script;
        interp = acceptCallbackPtr->interp;
        
        Tcl_Preserve((ClientData) script);
        Tcl_Preserve((ClientData) interp);

	TclFormatInt(portBuf, port);
        Tcl_RegisterChannel(interp, chan);








        result = Tcl_VarEval(interp, script, " ", Tcl_GetChannelName(chan),
                " ", address, " ", portBuf, (char *) NULL);
        if (result != TCL_OK) {
            Tcl_BackgroundError(interp);
	    Tcl_UnregisterChannel(interp, chan);
        }








        Tcl_Release((ClientData) interp);
        Tcl_Release((ClientData) script);
    } else {

        /*
         * The interpreter has been deleted, so there is no useful
         * way to utilize the client socket - just close it.







|




















>
>
>
>
>
>
>
>






>
>
>
>
>
>
>
>







1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
    char *address;			/* Address of client that was
                                         * accepted. */
    int port;				/* Port of client that was accepted. */
{
    AcceptCallback *acceptCallbackPtr;
    Tcl_Interp *interp;
    char *script;
    char portBuf[TCL_INTEGER_SPACE];
    int result;

    acceptCallbackPtr = (AcceptCallback *) callbackData;

    /*
     * Check if the callback is still valid; the interpreter may have gone
     * away, this is signalled by setting the interp field of the callback
     * data to NULL.
     */
    
    if (acceptCallbackPtr->interp != (Tcl_Interp *) NULL) {

        script = acceptCallbackPtr->script;
        interp = acceptCallbackPtr->interp;
        
        Tcl_Preserve((ClientData) script);
        Tcl_Preserve((ClientData) interp);

	TclFormatInt(portBuf, port);
        Tcl_RegisterChannel(interp, chan);

        /*
         * Artificially bump the refcount to protect the channel from
         * being deleted while the script is being evaluated.
         */

        Tcl_RegisterChannel((Tcl_Interp *) NULL,  chan);
        
        result = Tcl_VarEval(interp, script, " ", Tcl_GetChannelName(chan),
                " ", address, " ", portBuf, (char *) NULL);
        if (result != TCL_OK) {
            Tcl_BackgroundError(interp);
	    Tcl_UnregisterChannel(interp, chan);
        }

        /*
         * Decrement the artificially bumped refcount. After this it is
         * not safe anymore to use "chan", because it may now be deleted.
         */

        Tcl_UnregisterChannel((Tcl_Interp *) NULL, chan);
        
        Tcl_Release((ClientData) interp);
        Tcl_Release((ClientData) script);
    } else {

        /*
         * The interpreter has been deleted, so there is no useful
         * way to utilize the client socket - just close it.
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321






1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339








1340




































1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
    Tcl_EventuallyFree((ClientData) acceptCallbackPtr->script, TCL_DYNAMIC);
    ckfree((char *) acceptCallbackPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SocketCmd --
 *
 *	This procedure is invoked to process the "socket" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Creates a socket based channel.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_SocketCmd(notUsed, interp, argc, argv)
    ClientData notUsed;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{






    int a, server, port;
    char *arg, *copyScript, *host, *script;
    char *myaddr = NULL;
    int myport = 0;
    int async = 0;
    Tcl_Channel chan;
    AcceptCallback *acceptCallbackPtr;
    
    server = 0;
    script = NULL;

    if (TclHasSockets(interp) != TCL_OK) {
	return TCL_ERROR;
    }

    for (a = 1; a < argc; a++) {
        arg = argv[a];
	if (arg[0] == '-') {








	    if (strcmp(arg, "-server") == 0) {




































                if (async == 1) {
                    Tcl_AppendResult(interp,
                            "cannot set -async option for server sockets",
                            (char *) NULL);
                    return TCL_ERROR;
                }
		server = 1;
		a++;
		if (a >= argc) {
		    Tcl_AppendResult(interp,
			    "no argument given for -server option",
                            (char *) NULL);
		    return TCL_ERROR;
		}
                script = argv[a];
            } else if (strcmp(arg, "-myaddr") == 0) {
		a++;
                if (a >= argc) {
		    Tcl_AppendResult(interp,
			    "no argument given for -myaddr option",
                            (char *) NULL);
		    return TCL_ERROR;
		}
                myaddr = argv[a];
            } else if (strcmp(arg, "-myport") == 0) {
		a++;
                if (a >= argc) {
		    Tcl_AppendResult(interp,
			    "no argument given for -myport option",
                            (char *) NULL);
		    return TCL_ERROR;
		}
		if (TclSockGetPort(interp, argv[a], "tcp", &myport)
                    != TCL_OK) {
		    return TCL_ERROR;
		}
            } else if (strcmp(arg, "-async") == 0) {
                if (server == 1) {
                    Tcl_AppendResult(interp,
                            "cannot set -async option for server sockets",
                            (char *) NULL);
                    return TCL_ERROR;
                }
                async = 1;
	    } else {
		Tcl_AppendResult(interp, "bad option \"", arg,
                        "\", must be -async, -myaddr, -myport, or -server",
                        (char *) NULL);
		return TCL_ERROR;
	    }
	} else {
	    break;
	}
    }
    if (server) {
        host = myaddr;		/* NULL implies INADDR_ANY */
	if (myport != 0) {
	    Tcl_AppendResult(interp, "Option -myport is not valid for servers",
		    NULL);
	    return TCL_ERROR;
	}
    } else if (a < argc) {
	host = argv[a];
	a++;
    } else {
wrongNumArgs:
	Tcl_AppendResult(interp, "wrong # args: should be either:\n",
		argv[0],
                " ?-myaddr addr? ?-myport myport? ?-async? host port\n",
		argv[0],
                " -server command ?-myaddr addr? port",
                (char *) NULL);
        return TCL_ERROR;
    }

    if (a == argc-1) {
	if (TclSockGetPort(interp, argv[a], "tcp", &port) != TCL_OK) {

	    return TCL_ERROR;
	}
    } else {
	goto wrongNumArgs;
    }

    if (server) {







|














|


|
|

>
>
>
>
>
>
|










|



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








|





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









|
|




|

|





|
|
>







1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368

1369





1370




1371










1372



1373









1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
    Tcl_EventuallyFree((ClientData) acceptCallbackPtr->script, TCL_DYNAMIC);
    ckfree((char *) acceptCallbackPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SocketObjCmd --
 *
 *	This procedure is invoked to process the "socket" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Creates a socket based channel.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_SocketObjCmd(notUsed, interp, objc, objv)
    ClientData notUsed;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    static char *socketOptions[] = {
	"-async", "-myaddr", "-myport","-server", (char *) NULL
    };
    enum socketOptions {
	SKT_ASYNC,      SKT_MYADDR,      SKT_MYPORT,      SKT_SERVER  
    };
    int optionIndex, a, server, port;
    char *arg, *copyScript, *host, *script;
    char *myaddr = NULL;
    int myport = 0;
    int async = 0;
    Tcl_Channel chan;
    AcceptCallback *acceptCallbackPtr;
    
    server = 0;
    script = NULL;

    if (TclpHasSockets(interp) != TCL_OK) {
	return TCL_ERROR;
    }

    for (a = 1; a < objc; a++) {
	arg = Tcl_GetString(objv[a]);
	if (arg[0] != '-') {
	    break;
	}
	if (Tcl_GetIndexFromObj(interp, objv[a], socketOptions,
		"option", TCL_EXACT, &optionIndex) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch ((enum socketOptions) optionIndex) {
	    case SKT_ASYNC: {
                if (server == 1) {
                    Tcl_AppendResult(interp,
                            "cannot set -async option for server sockets",
                            (char *) NULL);
                    return TCL_ERROR;
                }
                async = 1;		
		break;
	    }
	    case SKT_MYADDR: {
		a++;
                if (a >= objc) {
		    Tcl_AppendResult(interp,
			    "no argument given for -myaddr option",
                            (char *) NULL);
		    return TCL_ERROR;
		}
                myaddr = Tcl_GetString(objv[a]);
		break;
	    }
	    case SKT_MYPORT: {
		char *myPortName;
		a++;
                if (a >= objc) {
		    Tcl_AppendResult(interp,
			    "no argument given for -myport option",
                            (char *) NULL);
		    return TCL_ERROR;
		}
		myPortName = Tcl_GetString(objv[a]);
		if (TclSockGetPort(interp, myPortName, "tcp", &myport)
			!= TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    }
	    case SKT_SERVER: {
                if (async == 1) {
                    Tcl_AppendResult(interp,
                            "cannot set -async option for server sockets",
                            (char *) NULL);
                    return TCL_ERROR;
                }
		server = 1;
		a++;
		if (a >= objc) {
		    Tcl_AppendResult(interp,
			    "no argument given for -server option",
                            (char *) NULL);
		    return TCL_ERROR;
		}
                script = Tcl_GetString(objv[a]);

		break;





	    }




	    default: {










		panic("Tcl_SocketObjCmd: bad option index to SocketOptions");



	    }









	}
    }
    if (server) {
        host = myaddr;		/* NULL implies INADDR_ANY */
	if (myport != 0) {
	    Tcl_AppendResult(interp, "Option -myport is not valid for servers",
		    NULL);
	    return TCL_ERROR;
	}
    } else if (a < objc) {
	host = Tcl_GetString(objv[a]);
	a++;
    } else {
wrongNumArgs:
	Tcl_AppendResult(interp, "wrong # args: should be either:\n",
		Tcl_GetString(objv[0]),
                " ?-myaddr addr? ?-myport myport? ?-async? host port\n",
		Tcl_GetString(objv[0]),
                " -server command ?-myaddr addr? port",
                (char *) NULL);
        return TCL_ERROR;
    }

    if (a == objc-1) {
	if (TclSockGetPort(interp, Tcl_GetString(objv[a]),
		"tcp", &port) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	goto wrongNumArgs;
    }

    if (server) {
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
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel inChan, outChan;
    char *arg;
    int mode, i;
    int toRead;
    Tcl_Obj *cmdPtr;
    static char* switches[] = { "-size", "-command", NULL };
    enum { FcopySize, FcopyCommand } index;

    if ((objc < 3) || (objc > 7) || (objc == 4) || (objc == 6)) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"input output ?-size size? ?-command callback?");
	return TCL_ERROR;
    }

    /*
     * Parse the channel arguments and verify that they are readable
     * or writable, as appropriate.
     */

    arg = Tcl_GetStringFromObj(objv[1], NULL);
    inChan = Tcl_GetChannel(interp, arg, &mode);
    if (inChan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    if ((mode & TCL_READABLE) == 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"",
		Tcl_GetStringFromObj(objv[1], NULL), 
                "\" wasn't opened for reading", (char *) NULL);
        return TCL_ERROR;
    }
    arg = Tcl_GetStringFromObj(objv[2], NULL);
    outChan = Tcl_GetChannel(interp, arg, &mode);
    if (outChan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    if ((mode & TCL_WRITABLE) == 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"",
		Tcl_GetStringFromObj(objv[1], NULL), 
                "\" wasn't opened for writing", (char *) NULL);
        return TCL_ERROR;
    }

    toRead = -1;
    cmdPtr = NULL;
    for (i = 3; i < objc; i += 2) {







|


|












|






|



|






|







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
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Channel inChan, outChan;
    char *arg;
    int mode, i;
    int toRead, index;
    Tcl_Obj *cmdPtr;
    static char* switches[] = { "-size", "-command", NULL };
    enum { FcopySize, FcopyCommand };

    if ((objc < 3) || (objc > 7) || (objc == 4) || (objc == 6)) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"input output ?-size size? ?-command callback?");
	return TCL_ERROR;
    }

    /*
     * Parse the channel arguments and verify that they are readable
     * or writable, as appropriate.
     */

    arg = Tcl_GetString(objv[1]);
    inChan = Tcl_GetChannel(interp, arg, &mode);
    if (inChan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    if ((mode & TCL_READABLE) == 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"",
		Tcl_GetString(objv[1]), 
                "\" wasn't opened for reading", (char *) NULL);
        return TCL_ERROR;
    }
    arg = Tcl_GetString(objv[2]);
    outChan = Tcl_GetChannel(interp, arg, &mode);
    if (outChan == (Tcl_Channel) NULL) {
	return TCL_ERROR;
    }
    if ((mode & TCL_WRITABLE) == 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"",
		Tcl_GetString(objv[1]), 
                "\" wasn't opened for writing", (char *) NULL);
        return TCL_ERROR;
    }

    toRead = -1;
    cmdPtr = NULL;
    for (i = 3; i < objc; i += 2) {

Changes to generic/tclIOSock.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
/* 
 * tclIOSock.c --
 *
 *	Common routines used by all socket based channel types.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclIOSock.c 1.20 97/04/25 16:36:40
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 *----------------------------------------------------------------------
 *
 * TclSockGetPort --
 *
 *	Maps from a string, which could be a service name, to a port.
 *	Used by socket creation code to get port numbers and resolve
 *	registered service names to port numbers.
 *
 * Results:
 *	A standard Tcl result.  On success, the port number is
 *	returned in portPtr. On failure, an error message is left in
 *	interp->result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclSockGetPort(interp, string, proto, portPtr)
    Tcl_Interp *interp;
    char *string;		/* Integer or service name */
    char *proto;		/* "tcp" or "udp", typically */
    int *portPtr;		/* Return port number */
{
    struct servent *sp;		/* Protocol info for named services */



    if (Tcl_GetInt(interp, string, portPtr) != TCL_OK) {





	sp = getservbyname(string, proto);    

	if (sp != NULL) {
	    *portPtr = ntohs((unsigned short) sp->s_port);
	    Tcl_ResetResult(interp);	/* clear error message */
	    return TCL_OK;
	}
	return TCL_ERROR;
    }
    if (Tcl_GetInt(interp, string, portPtr) != TCL_OK) {
	return TCL_ERROR;
    }
    if (*portPtr > 0xFFFF) {
        Tcl_AppendResult(interp, "couldn't open socket: port number too high",
                (char *) NULL);





|




|






|








|
|
|




|










>
>
>
|
>
>
>
>
>
|
>


<


<







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
/* 
 * tclIOSock.c --
 *
 *	Common routines used by all socket based channel types.
 *
 * 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: tclIOSock.c,v 1.1.2.2 1998/09/24 23:58:53 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 *---------------------------------------------------------------------------
 *
 * TclSockGetPort --
 *
 *	Maps from a string, which could be a service name, to a port.
 *	Used by socket creation code to get port numbers and resolve
 *	registered service names to port numbers.
 *
 * Results:
 *	A standard Tcl result.  On success, the port number is returned
 *	in portPtr. On failure, an error message is left in the interp's
 *	result.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TclSockGetPort(interp, string, proto, portPtr)
    Tcl_Interp *interp;
    char *string;		/* Integer or service name */
    char *proto;		/* "tcp" or "udp", typically */
    int *portPtr;		/* Return port number */
{
    struct servent *sp;		/* Protocol info for named services */
    Tcl_DString ds;
    char *native;

    if (Tcl_GetInt(NULL, string, portPtr) != TCL_OK) {
	/*
	 * Don't bother translating 'proto' to native.
	 */
	 
	native = Tcl_UtfToExternalDString(NULL, string, -1, &ds);
	sp = getservbyname(native, proto);		/* INTL: Native. */
	Tcl_DStringFree(&ds);
	if (sp != NULL) {
	    *portPtr = ntohs((unsigned short) sp->s_port);

	    return TCL_OK;
	}

    }
    if (Tcl_GetInt(interp, string, portPtr) != TCL_OK) {
	return TCL_ERROR;
    }
    if (*portPtr > 0xFFFF) {
        Tcl_AppendResult(interp, "couldn't open socket: port number too high",
                (char *) NULL);

Changes to generic/tclIOUtil.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
/* 
 * tclIOUtil.c --
 *
 *	This file contains a collection of utility procedures that
 *	are shared by the platform specific IO drivers.
 *
 *	Parts of this file are based on code contributed by Karl
 *	Lehenbauer, Mark Diekhans and Peter da Silva.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclIOUtil.c 1.133 97/09/24 16:38:57
 */

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


























/*

































 *----------------------------------------------------------------------
 *
 * TclGetOpenMode --
 *
 * Description:
 *	Computes a POSIX mode mask for opening a file, from a given string,
 *	and also sets a flag to indicate whether the caller should seek to
 *	EOF after opening the file.
 *
 * Results:
 *	On success, returns mode to pass to "open". If an error occurs, the
 *	returns -1 and if interp is not NULL, sets interp->result to an
 *	error message.
 *
 * Side effects:
 *	Sets the integer referenced by seekFlagPtr to 1 to tell the caller
 *	to seek to EOF after opening the file.
 *
 * Special note:
 *	This code is based on a prototype implementation contributed
 *	by Mark Diekhans.
 *
 *----------------------------------------------------------------------
 */

int
TclGetOpenMode(interp, string, seekFlagPtr)
    Tcl_Interp *interp;			/* Interpreter to use for error
					 * reporting - may be NULL. */
    char *string;			/* Mode string, e.g. "r+" or










|




|




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

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










|
|









|







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
/* 
 * tclIOUtil.c --
 *
 *	This file contains a collection of utility procedures that
 *	are shared by the platform specific IO drivers.
 *
 *	Parts of this file are based on code contributed by Karl
 *	Lehenbauer, Mark Diekhans and Peter da Silva.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * 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: tclIOUtil.c,v 1.1.2.9 1999/02/01 21:29:53 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * The following typedef declarations allow for hooking into the chain
 * of functions maintained for 'Tcl_Stat(...)', 'Tcl_Access(...)' &
 * 'Tcl_OpenFileChannel(...)'.  Basically for each hookable function
 * a linked list is defined.
 */

typedef struct StatProc {
    TclStatProc_ *proc;		 /* Function to process a 'stat()' call */
    struct StatProc *nextPtr;    /* The next 'stat()' function to call */
} StatProc;

typedef struct AccessProc {
    TclAccessProc_ *proc;	 /* Function to process a 'access()' call */
    struct AccessProc *nextPtr;  /* The next 'access()' function to call */
} AccessProc;

typedef struct OpenFileChannelProc {
    TclOpenFileChannelProc_ *proc;  /* Function to process a
				     * 'Tcl_OpenFileChannel()' call */
    struct OpenFileChannelProc *nextPtr;
				    /* The next 'Tcl_OpenFileChannel()'
				     * function to call */
} OpenFileChannelProc;

/*
 * For each type of hookable function, a static node is declared to
 * hold the function pointer for the "built-in" routine (e.g.
 * 'TclpStat(...)') and the respective list is initialized as a pointer
 * to that node.
 * 
 * The "delete" functions (e.g. 'TclStatDeleteProc(...)') ensure that
 * these statically declared list entry cannot be inadvertently removed.
 *
 * This method avoids the need to call any sort of "initialization"
 * function.
 *
 * All three lists are protected by a global hookMutex.
 */

static StatProc defaultStatProc = {
    &TclpStat, NULL
};
static StatProc *statProcList = &defaultStatProc;

static AccessProc defaultAccessProc = {
    &TclpAccess, NULL
};
static AccessProc *accessProcList = &defaultAccessProc;

static OpenFileChannelProc defaultOpenFileChannelProc = {
    &TclpOpenFileChannel, NULL
};
static OpenFileChannelProc *openFileChannelProcList =
	&defaultOpenFileChannelProc;

TCL_DECLARE_MUTEX(hookMutex)

/*
 *---------------------------------------------------------------------------
 *
 * TclGetOpenMode --
 *
 * Description:
 *	Computes a POSIX mode mask for opening a file, from a given string,
 *	and also sets a flag to indicate whether the caller should seek to
 *	EOF after opening the file.
 *
 * Results:
 *	On success, returns mode to pass to "open". If an error occurs, the
 *	return value is -1 and if interp is not NULL, sets interp's result
 *	object to an error message.
 *
 * Side effects:
 *	Sets the integer referenced by seekFlagPtr to 1 to tell the caller
 *	to seek to EOF after opening the file.
 *
 * Special note:
 *	This code is based on a prototype implementation contributed
 *	by Mark Diekhans.
 *
 *---------------------------------------------------------------------------
 */

int
TclGetOpenMode(interp, string, seekFlagPtr)
    Tcl_Interp *interp;			/* Interpreter to use for error
					 * reporting - may be NULL. */
    char *string;			/* Mode string, e.g. "r+" or
64
65
66
67
68
69
70







71
72
73
74
75
76
77
78
     * Check for the simpler fopen-like access modes (e.g. "r").  They
     * are distinguished from the POSIX access modes by the presence
     * of a lower-case first letter.
     */

    *seekFlagPtr = 0;
    mode = 0;







    if (islower(UCHAR(string[0]))) {
	switch (string[0]) {
	    case 'r':
		mode = O_RDONLY;
		break;
	    case 'w':
		mode = O_WRONLY|O_CREAT|O_TRUNC;
		break;







>
>
>
>
>
>
>
|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
     * Check for the simpler fopen-like access modes (e.g. "r").  They
     * are distinguished from the POSIX access modes by the presence
     * of a lower-case first letter.
     */

    *seekFlagPtr = 0;
    mode = 0;

    /*
     * Guard against international characters before using byte oriented
     * routines.
     */

    if (!(string[0] & 0x80)
	    && islower(UCHAR(string[0]))) { /* INTL: ISO only. */
	switch (string[0]) {
	    case 'r':
		mode = O_RDONLY;
		break;
	    case 'w':
		mode = O_WRONLY|O_CREAT|O_TRUNC;
		break;
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

int
Tcl_EvalFile(interp, fileName)
    Tcl_Interp *interp;		/* Interpreter in which to process file. */
    char *fileName;		/* Name of file to process.  Tilde-substitution
				 * will be performed on this name. */
{
    int result;
    struct stat statBuf;
    char *cmdBuffer = (char *) NULL;
    char *oldScriptFile;
    Interp *iPtr = (Interp *) interp;
    Tcl_DString buffer;
    char *nativeName;
    Tcl_Channel chan;
    Tcl_Obj *cmdObjPtr;

    Tcl_ResetResult(interp);
    oldScriptFile = iPtr->scriptFile;
    iPtr->scriptFile = fileName;
    Tcl_DStringInit(&buffer);
    nativeName = Tcl_TranslateFileName(interp, fileName, &buffer);
    if (nativeName == NULL) {
	goto error;

    }

    /*
     * If Tcl_TranslateFileName didn't already copy the file name, do it
     * here.  This way we don't depend on fileName staying constant
     * throughout the execution of the script (e.g., what if it happens
     * to point to a Tcl variable that the script could change?).
     */

    if (nativeName != Tcl_DStringValue(&buffer)) {
	Tcl_DStringSetLength(&buffer, 0);
	Tcl_DStringAppend(&buffer, nativeName, -1);
	nativeName = Tcl_DStringValue(&buffer);
    }
    if (stat(nativeName, &statBuf) == -1) {
        Tcl_SetErrno(errno);
	Tcl_AppendResult(interp, "couldn't read file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	goto error;
    }
    chan = Tcl_OpenFileChannel(interp, nativeName, "r", 0644);
    if (chan == (Tcl_Channel) NULL) {
        Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "couldn't read file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	goto error;
    }
    cmdBuffer = (char *) ckalloc((unsigned) statBuf.st_size+1);
    result = Tcl_Read(chan, cmdBuffer, statBuf.st_size);
    if (result < 0) {
        Tcl_Close(interp, chan);
	Tcl_AppendResult(interp, "couldn't read file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	goto error;
    }
    cmdBuffer[result] = 0;
    if (Tcl_Close(interp, chan) != TCL_OK) {
        goto error;
    }

    /*
     * Transfer the buffer memory allocated above to the object system.
     * Tcl_EvalObj will own this new string object if needed,
     * so past the Tcl_EvalObj point, we must not ckfree(cmdBuffer)
     * but rather use the reference counting mechanism.
     * (Nb: and we must not thus not use goto error after this point)
     */
    cmdObjPtr = Tcl_NewObj();
    cmdObjPtr->bytes = cmdBuffer;
    cmdObjPtr->length = result;
    
    Tcl_IncrRefCount(cmdObjPtr);
    result = Tcl_EvalObj(interp, cmdObjPtr);
    Tcl_DecrRefCount(cmdObjPtr);

    if (result == TCL_RETURN) {
	result = TclUpdateReturnInfo(iPtr);
    } else if (result == TCL_ERROR) {
	char msg[200];

	/*
	 * Record information telling where the error occurred.
	 */

	sprintf(msg, "\n    (file \"%.150s\" line %d)", fileName,
		interp->errorLine);
	Tcl_AddErrorInfo(interp, msg);
    }
    iPtr->scriptFile = oldScriptFile;
    Tcl_DStringFree(&buffer);
    return result;

error:
    if (cmdBuffer != (char *) NULL) {
        ckfree(cmdBuffer);
    }
    iPtr->scriptFile = oldScriptFile;
    Tcl_DStringFree(&buffer);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetErrno --
 *







|

<

|
|
|

|

<
<
<
<
|
|
<
>


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



|

|




|

<
<
|



|

<

|


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




|









<
<
<

|
<
|
<
<
|
|







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

int
Tcl_EvalFile(interp, fileName)
    Tcl_Interp *interp;		/* Interpreter in which to process file. */
    char *fileName;		/* Name of file to process.  Tilde-substitution
				 * will be performed on this name. */
{
    int result, length;
    struct stat statBuf;

    char *oldScriptFile;
    Interp *iPtr;
    Tcl_DString nameString;
    char *name, *string;
    Tcl_Channel chan;
    Tcl_Obj *objPtr;





    name = Tcl_TranslateFileName(interp, fileName, &nameString);
    if (name == NULL) {

	return TCL_ERROR;
    }







    result = TCL_ERROR;



    objPtr = Tcl_NewObj();

    if (TclStat(name, &statBuf) == -1) {
        Tcl_SetErrno(errno);
	Tcl_AppendResult(interp, "couldn't read file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	goto end;
    }
    chan = Tcl_OpenFileChannel(interp, name, "r", 0644);
    if (chan == (Tcl_Channel) NULL) {
        Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "couldn't read file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	goto end;
    }


    if (Tcl_ReadChars(chan, objPtr, -1, 0) < 0) {
        Tcl_Close(interp, chan);
	Tcl_AppendResult(interp, "couldn't read file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	goto end;
    }

    if (Tcl_Close(interp, chan) != TCL_OK) {
        goto end;
    }








    iPtr = (Interp *) interp;
    oldScriptFile = iPtr->scriptFile;
    iPtr->scriptFile = fileName;
    string = Tcl_GetStringFromObj(objPtr, &length);

    result = Tcl_EvalEx(interp, string, length, 0);
    iPtr->scriptFile = oldScriptFile;

    if (result == TCL_RETURN) {
	result = TclUpdateReturnInfo(iPtr);
    } else if (result == TCL_ERROR) {
	char msg[200 + TCL_INTEGER_SPACE];

	/*
	 * Record information telling where the error occurred.
	 */

	sprintf(msg, "\n    (file \"%.150s\" line %d)", fileName,
		interp->errorLine);
	Tcl_AddErrorInfo(interp, msg);
    }




    end:

    Tcl_DecrRefCount(objPtr);


    Tcl_DStringFree(&nameString);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetErrno --
 *
386
387
388
389
390
391
392



































































































































































































































































































































































































































































    char *id, *msg;

    msg = Tcl_ErrnoMsg(errno);
    id = Tcl_ErrnoId();
    Tcl_SetErrorCode(interp, "POSIX", id, msg, (char *) NULL);
    return msg;
}










































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
    char *id, *msg;

    msg = Tcl_ErrnoMsg(errno);
    id = Tcl_ErrnoId();
    Tcl_SetErrorCode(interp, "POSIX", id, msg, (char *) NULL);
    return msg;
}

/*
 *----------------------------------------------------------------------
 *
 * TclStat --
 *
 *	This procedure replaces the library version of stat and lsat.
 *	The chain of functions that have been "inserted" into the
 *	'statProcList' will be called in succession until either
 *	a value of zero is returned, or the entire list is visited.
 *
 * Results:
 *      See stat documentation.
 *
 * Side effects:
 *      See stat documentation.
 *
 *----------------------------------------------------------------------
 */

int
TclStat(path, buf)
    CONST char *path;		/* Path of file to stat (in current CP). */
    TclStat_ *buf;		/* Filled with results of stat call. */
{
    StatProc *statProcPtr;
    int retVal = -1;

    /*
     * Call each of the "stat" function in succession.  A non-return
     * value of -1 indicates the particular function has succeeded.
     */

    Tcl_MutexLock(&hookMutex);
    statProcPtr = statProcList;
    while ((retVal == -1) && (statProcPtr != NULL)) {
	retVal = (*statProcPtr->proc)(path, buf);
	statProcPtr = statProcPtr->nextPtr;
    }
    Tcl_MutexUnlock(&hookMutex);

    return (retVal);
}

/*
 *----------------------------------------------------------------------
 *
 * TclAccess --
 *
 *	This procedure replaces the library version of access.
 *	The chain of functions that have been "inserted" into the
 *	'accessProcList' will be called in succession until either
 *	a value of zero is returned, or the entire list is visited.
 *
 * Results:
 *      See access documentation.
 *
 * Side effects:
 *      See access documentation.
 *
 *----------------------------------------------------------------------
 */

int
TclAccess(path, mode)
    CONST char *path;		/* Path of file to access (in current CP). */
    int mode;                   /* Permission setting. */
{
    AccessProc *accessProcPtr;
    int retVal = -1;

    /*
     * Call each of the "access" function in succession.  A non-return
     * value of -1 indicates the particular function has succeeded.
     */

    Tcl_MutexLock(&hookMutex);
    accessProcPtr = accessProcList;
    while ((retVal == -1) && (accessProcPtr != NULL)) {
	retVal = (*accessProcPtr->proc)(path, mode);
	accessProcPtr = accessProcPtr->nextPtr;
    }
    Tcl_MutexUnlock(&hookMutex);

    return (retVal);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_OpenFileChannel --
 *
 *	The chain of functions that have been "inserted" into the
 *	'openFileChannelProcList' will be called in succession until
 *	either a valid file channel is returned, or the entire list is
 *	visited.
 *
 * Results:
 *	The new channel or NULL, if the named file could not be opened.
 *
 * Side effects:
 *	May open the channel and may cause creation of a file on the
 *	file system.
 *
 *----------------------------------------------------------------------
 */
 
Tcl_Channel
Tcl_OpenFileChannel(interp, fileName, modeString, permissions)
    Tcl_Interp *interp;                 /* Interpreter for error reporting;
                                         * can be NULL. */
    char *fileName;                     /* Name of file to open. */
    char *modeString;                   /* A list of POSIX open modes or
                                         * a string such as "rw". */
    int permissions;                    /* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
{
    OpenFileChannelProc *openFileChannelProcPtr;
    Tcl_Channel retVal = NULL;

    /*
     * Call each of the "Tcl_OpenFileChannel" function in succession.
     * A non-NULL return value indicates the particular function has
     * succeeded.
     */

    Tcl_MutexLock(&hookMutex);
    openFileChannelProcPtr = openFileChannelProcList;
    while ((retVal == NULL) && (openFileChannelProcPtr != NULL)) {
	retVal = (*openFileChannelProcPtr->proc)(interp, fileName,
		modeString, permissions);
	openFileChannelProcPtr = openFileChannelProcPtr->nextPtr;
    }
    Tcl_MutexUnlock(&hookMutex);

    return (retVal);
}

/*
 *----------------------------------------------------------------------
 *
 * TclStatInsertProc --
 *
 *	Insert the passed procedure pointer at the head of the list of
 *	functions which are used during a call to 'TclStat(...)'. The
 *	passed function should be have exactly like 'TclStat' when called
 *	during that time (see 'TclStat(...)' for more informatin).
 *	The function will be added even if it already in the list.
 *
 * Results:
 *      Normally TCL_OK; TCL_ERROR if memory for a new node in the list
 *	could not be allocated.
 *
 * Side effects:
 *      Memory allocataed and modifies the link list for 'TclStat'
 *	functions.
 *
 *----------------------------------------------------------------------
 */

int
TclStatInsertProc (proc)
    TclStatProc_ *proc;
{
    int retVal = TCL_ERROR;

    if (proc != NULL) {
	StatProc *newStatProcPtr;

	newStatProcPtr = (StatProc *)Tcl_Alloc(sizeof(StatProc));;

	if (newStatProcPtr != NULL) {
	    newStatProcPtr->proc = proc;
	    Tcl_MutexLock(&hookMutex);
	    newStatProcPtr->nextPtr = statProcList;
	    statProcList = newStatProcPtr;
	    Tcl_MutexUnlock(&hookMutex);

	    retVal = TCL_OK;
	}
    }

    return (retVal);
}

/*
 *----------------------------------------------------------------------
 *
 * TclStatDeleteProc --
 *
 *	Removed the passed function pointer from the list of 'TclStat'
 *	functions.  Ensures that the built-in stat function is not
 *	removvable.
 *
 * Results:
 *      TCL_OK if the procedure pointer was successfully removed,
 *	TCL_ERROR otherwise.
 *
 * Side effects:
 *      Memory is deallocated and the respective list updated.
 *
 *----------------------------------------------------------------------
 */

int
TclStatDeleteProc (proc)
    TclStatProc_ *proc;
{
    int retVal = TCL_ERROR;
    StatProc *tmpStatProcPtr;
    StatProc *prevStatProcPtr = NULL;

    Tcl_MutexLock(&hookMutex);
    tmpStatProcPtr = statProcList;
    /*
     * Traverse the 'statProcList' looking for the particular node
     * whose 'proc' member matches 'proc' and remove that one from
     * the list.  Ensure that the "default" node cannot be removed.
     */

    while ((retVal == TCL_ERROR) && (tmpStatProcPtr != &defaultStatProc)) {
	if (tmpStatProcPtr->proc == proc) {
	    if (prevStatProcPtr == NULL) {
		statProcList = tmpStatProcPtr->nextPtr;
	    } else {
		prevStatProcPtr->nextPtr = tmpStatProcPtr->nextPtr;
	    }

	    Tcl_Free((char *)tmpStatProcPtr);

	    retVal = TCL_OK;
	} else {
	    prevStatProcPtr = tmpStatProcPtr;
	    tmpStatProcPtr = tmpStatProcPtr->nextPtr;
	}
    }

    Tcl_MutexUnlock(&hookMutex);
    return (retVal);
}

/*
 *----------------------------------------------------------------------
 *
 * TclAccessInsertProc --
 *
 *	Insert the passed procedure pointer at the head of the list of
 *	functions which are used during a call to 'TclAccess(...)'. The
 *	passed function should be have exactly like 'TclAccess' when
 *	called during that time (see 'TclAccess(...)' for more informatin).
 *	The function will be added even if it already in the list.
 *
 * Results:
 *      Normally TCL_OK; TCL_ERROR if memory for a new node in the list
 *	could not be allocated.
 *
 * Side effects:
 *      Memory allocataed and modifies the link list for 'TclAccess'
 *	functions.
 *
 *----------------------------------------------------------------------
 */

int
TclAccessInsertProc(proc)
    TclAccessProc_ *proc;
{
    int retVal = TCL_ERROR;

    if (proc != NULL) {
	AccessProc *newAccessProcPtr;

	newAccessProcPtr = (AccessProc *)Tcl_Alloc(sizeof(AccessProc));;

	if (newAccessProcPtr != NULL) {
	    newAccessProcPtr->proc = proc;
	    Tcl_MutexLock(&hookMutex);
	    newAccessProcPtr->nextPtr = accessProcList;
	    accessProcList = newAccessProcPtr;
	    Tcl_MutexUnlock(&hookMutex);

	    retVal = TCL_OK;
	}
    }

    return (retVal);
}

/*
 *----------------------------------------------------------------------
 *
 * TclAccessDeleteProc --
 *
 *	Removed the passed function pointer from the list of 'TclAccess'
 *	functions.  Ensures that the built-in access function is not
 *	removvable.
 *
 * Results:
 *      TCL_OK if the procedure pointer was successfully removed,
 *	TCL_ERROR otherwise.
 *
 * Side effects:
 *      Memory is deallocated and the respective list updated.
 *
 *----------------------------------------------------------------------
 */

int
TclAccessDeleteProc(proc)
    TclAccessProc_ *proc;
{
    int retVal = TCL_ERROR;
    AccessProc *tmpAccessProcPtr;
    AccessProc *prevAccessProcPtr = NULL;

    /*
     * Traverse the 'accessProcList' looking for the particular node
     * whose 'proc' member matches 'proc' and remove that one from
     * the list.  Ensure that the "default" node cannot be removed.
     */

    Tcl_MutexLock(&hookMutex);
    tmpAccessProcPtr = accessProcList;
    while ((retVal == TCL_ERROR) && (tmpAccessProcPtr != &defaultAccessProc)) {
	if (tmpAccessProcPtr->proc == proc) {
	    if (prevAccessProcPtr == NULL) {
		accessProcList = tmpAccessProcPtr->nextPtr;
	    } else {
		prevAccessProcPtr->nextPtr = tmpAccessProcPtr->nextPtr;
	    }

	    Tcl_Free((char *)tmpAccessProcPtr);

	    retVal = TCL_OK;
	} else {
	    prevAccessProcPtr = tmpAccessProcPtr;
	    tmpAccessProcPtr = tmpAccessProcPtr->nextPtr;
	}
    }
    Tcl_MutexUnlock(&hookMutex);

    return (retVal);
}

/*
 *----------------------------------------------------------------------
 *
 * TclOpenFileChannelInsertProc --
 *
 *	Insert the passed procedure pointer at the head of the list of
 *	functions which are used during a call to
 *	'Tcl_OpenFileChannel(...)'. The passed function should be have
 *	exactly like 'Tcl_OpenFileChannel' when called during that time
 *	(see 'Tcl_OpenFileChannel(...)' for more informatin). The
 *	function will be added even if it already in the list.
 *
 * Results:
 *      Normally TCL_OK; TCL_ERROR if memory for a new node in the list
 *	could not be allocated.
 *
 * Side effects:
 *      Memory allocataed and modifies the link list for
 *	'Tcl_OpenFileChannel' functions.
 *
 *----------------------------------------------------------------------
 */

int
TclOpenFileChannelInsertProc(proc)
    TclOpenFileChannelProc_ *proc;
{
    int retVal = TCL_ERROR;

    if (proc != NULL) {
	OpenFileChannelProc *newOpenFileChannelProcPtr;

	newOpenFileChannelProcPtr =
		(OpenFileChannelProc *)Tcl_Alloc(sizeof(OpenFileChannelProc));;

	if (newOpenFileChannelProcPtr != NULL) {
	    newOpenFileChannelProcPtr->proc = proc;
	    Tcl_MutexLock(&hookMutex);
	    newOpenFileChannelProcPtr->nextPtr = openFileChannelProcList;
	    openFileChannelProcList = newOpenFileChannelProcPtr;
	    Tcl_MutexUnlock(&hookMutex);

	    retVal = TCL_OK;
	}
    }

    return (retVal);
}

/*
 *----------------------------------------------------------------------
 *
 * TclOpenFileChannelDeleteProc --
 *
 *	Removed the passed function pointer from the list of
 *	'Tcl_OpenFileChannel' functions.  Ensures that the built-in
 *	open file channel function is not removvable.
 *
 * Results:
 *      TCL_OK if the procedure pointer was successfully removed,
 *	TCL_ERROR otherwise.
 *
 * Side effects:
 *      Memory is deallocated and the respective list updated.
 *
 *----------------------------------------------------------------------
 */

int
TclOpenFileChannelDeleteProc(proc)
    TclOpenFileChannelProc_ *proc;
{
    int retVal = TCL_ERROR;
    OpenFileChannelProc *tmpOpenFileChannelProcPtr = openFileChannelProcList;
    OpenFileChannelProc *prevOpenFileChannelProcPtr = NULL;

    /*
     * Traverse the 'openFileChannelProcList' looking for the particular
     * node whose 'proc' member matches 'proc' and remove that one from
     * the list.  Ensure that the "default" node cannot be removed.
     */

    Tcl_MutexLock(&hookMutex);
    tmpOpenFileChannelProcPtr = openFileChannelProcList;
    while ((retVal == TCL_ERROR) &&
	    (tmpOpenFileChannelProcPtr != &defaultOpenFileChannelProc)) {
	if (tmpOpenFileChannelProcPtr->proc == proc) {
	    if (prevOpenFileChannelProcPtr == NULL) {
		openFileChannelProcList = tmpOpenFileChannelProcPtr->nextPtr;
	    } else {
		prevOpenFileChannelProcPtr->nextPtr =
			tmpOpenFileChannelProcPtr->nextPtr;
	    }

	    Tcl_Free((char *)tmpOpenFileChannelProcPtr);

	    retVal = TCL_OK;
	} else {
	    prevOpenFileChannelProcPtr = tmpOpenFileChannelProcPtr;
	    tmpOpenFileChannelProcPtr = tmpOpenFileChannelProcPtr->nextPtr;
	}
    }
    Tcl_MutexUnlock(&hookMutex);

    return (retVal);
}

Changes to generic/tclIndexObj.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
/* 
 * tclIndexObj.c --
 *
 *	This file implements objects of type "index".  This object type
 *	is used to lookup a keyword in a table of valid values and cache
 *	the index of the matching entry.
 *
 * 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.
 *
 * SCCS: @(#) tclIndexObj.c 1.8 97/07/29 10:16:54
 */

#include "tclInt.h"

/*
 * Prototypes for procedures defined later in this file:
 */

static void		DupIndexInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
			    Tcl_Obj *copyPtr));
static int		SetIndexFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
static void		UpdateStringOfIndex _ANSI_ARGS_((Tcl_Obj *listPtr));

/*
 * The structure below defines the index Tcl object type by means of
 * procedures that can be invoked by generic object code.
 */

Tcl_ObjType tclIndexType = {
    "index",				/* name */
    (Tcl_FreeInternalRepProc *) NULL,	/* freeIntRepProc */
    DupIndexInternalRep,	        /* dupIntRepProc */
    UpdateStringOfIndex,		/* updateStringProc */
    SetIndexFromAny			/* setFromAnyProc */
};








/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetIndexFromObj --
 *
 *	This procedure looks up an object's value in a table of strings
 *	and returns the index of the matching string, if any.
 *
 * Results:

 *	If the value of objPtr is identical to or a unique abbreviation
 *	for one of the entries in objPtr, then the return value is
 *	TCL_OK and the index of the matching entry is stored at
 *	*indexPtr.  If there isn't a proper match, then TCL_ERROR is
 *	returned and an error message is left in interp's result (unless
 *	interp is NULL).  The msg argument is used in the error
 *	message; for example, if msg has the value "option" then the












|








<
<


<









|
|


>
>
>
>
>
>
>










|







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
/* 
 * tclIndexObj.c --
 *
 *	This file implements objects of type "index".  This object type
 *	is used to lookup a keyword in a table of valid values and cache
 *	the index of the matching entry.
 *
 * 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: tclIndexObj.c,v 1.1.2.2 1998/09/24 23:58:53 stanton Exp $
 */

#include "tclInt.h"

/*
 * Prototypes for procedures defined later in this file:
 */



static int		SetIndexFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));


/*
 * The structure below defines the index Tcl object type by means of
 * procedures that can be invoked by generic object code.
 */

Tcl_ObjType tclIndexType = {
    "index",				/* name */
    (Tcl_FreeInternalRepProc *) NULL,	/* freeIntRepProc */
    (Tcl_DupInternalRepProc *) NULL,	/* dupIntRepProc */
    (Tcl_UpdateStringProc *) NULL,	/* updateStringProc */
    SetIndexFromAny			/* setFromAnyProc */
};

/*
 * Boolean flag indicating whether or not the tclIndexType object
 * type has been registered with the Tcl compiler.
 */

static int indexTypeInitialized = 0;

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetIndexFromObj --
 *
 *	This procedure looks up an object's value in a table of strings
 *	and returns the index of the matching string, if any.
 *
 * Results:
 *
 *	If the value of objPtr is identical to or a unique abbreviation
 *	for one of the entries in objPtr, then the return value is
 *	TCL_OK and the index of the matching entry is stored at
 *	*indexPtr.  If there isn't a proper match, then TCL_ERROR is
 *	returned and an error message is left in interp's result (unless
 *	interp is NULL).  The msg argument is used in the error
 *	message; for example, if msg has the value "option" then the
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
    char **tablePtr;		/* Array of strings to compare against the
				 * value of objPtr; last entry must be NULL
				 * and there must not be duplicate entries. */
    char *msg;			/* Identifying word to use in error messages. */
    int flags;			/* 0 or TCL_EXACT */
    int *indexPtr;		/* Place to store resulting integer index. */
{





























































    int index, length, i, numAbbrev;
    char *key, *p1, *p2, **entryPtr;
    Tcl_Obj *resultPtr;

    /*
     * See if there is a valid cached result from a previous lookup.
     */

    if ((objPtr->typePtr == &tclIndexType)
	    && (objPtr->internalRep.twoPtrValue.ptr1 == (VOID *) tablePtr)) {
	*indexPtr = (int) objPtr->internalRep.twoPtrValue.ptr2;
	return TCL_OK;
    }

    /*
     * Lookup the value of the object in the table.  Accept unique
     * abbreviations unless TCL_EXACT is set in flags.
     */











    key = Tcl_GetStringFromObj(objPtr, &length);
    index = -1;
    numAbbrev = 0;
    for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; entryPtr++, i++) {

	for (p1 = key, p2 = *entryPtr; *p1 == *p2; p1++, p2++) {
	    if (*p1 == 0) {
		index = i;
		goto done;
	    }
	}
	if (*p1 == 0) {







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


















>
>
>
>
>
>
>
>
>
>




|
>







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
    char **tablePtr;		/* Array of strings to compare against the
				 * value of objPtr; last entry must be NULL
				 * and there must not be duplicate entries. */
    char *msg;			/* Identifying word to use in error messages. */
    int flags;			/* 0 or TCL_EXACT */
    int *indexPtr;		/* Place to store resulting integer index. */
{

    /*
     * See if there is a valid cached result from a previous lookup
     * (doing the check here saves the overhead of calling
     * Tcl_GetIndexFromObjStruct in the common case where the result
     * is cached).
     */

    if ((objPtr->typePtr == &tclIndexType)
	    && (objPtr->internalRep.twoPtrValue.ptr1 == (VOID *) tablePtr)) {
	*indexPtr = (int) objPtr->internalRep.twoPtrValue.ptr2;
	return TCL_OK;
    }
    return Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, sizeof(char *),
	    msg, flags, indexPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetIndexFromObjStruct --
 *
 *	This procedure looks up an object's value given a starting
 *	string and an offset for the amount of space between strings.
 *	This is useful when the strings are embedded in some other
 *	kind of array.
 *
 * Results:
 *
 *	If the value of objPtr is identical to or a unique abbreviation
 *	for one of the entries in objPtr, then the return value is
 *	TCL_OK and the index of the matching entry is stored at
 *	*indexPtr.  If there isn't a proper match, then TCL_ERROR is
 *	returned and an error message is left in interp's result (unless
 *	interp is NULL).  The msg argument is used in the error
 *	message; for example, if msg has the value "option" then the
 *	error message will say something flag 'bad option "foo": must be
 *	...'
 *
 * Side effects:
 *	The result of the lookup is cached as the internal rep of
 *	objPtr, so that repeated lookups can be done quickly.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, 
	indexPtr)
    Tcl_Interp *interp; 	/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr;		/* Object containing the string to lookup. */
    char **tablePtr;		/* The first string in the table. The second
				 * string will be at this address plus the
				 * offset, the third plus the offset again,
				 * etc. The last entry must be NULL
				 * and there must not be duplicate entries. */
    int offset;			/* The number of bytes between entries */
    char *msg;			/* Identifying word to use in error messages. */
    int flags;			/* 0 or TCL_EXACT */
    int *indexPtr;		/* Place to store resulting integer index. */
{
    int index, length, i, numAbbrev;
    char *key, *p1, *p2, **entryPtr;
    Tcl_Obj *resultPtr;

    /*
     * See if there is a valid cached result from a previous lookup.
     */

    if ((objPtr->typePtr == &tclIndexType)
	    && (objPtr->internalRep.twoPtrValue.ptr1 == (VOID *) tablePtr)) {
	*indexPtr = (int) objPtr->internalRep.twoPtrValue.ptr2;
	return TCL_OK;
    }

    /*
     * Lookup the value of the object in the table.  Accept unique
     * abbreviations unless TCL_EXACT is set in flags.
     */

    if (!indexTypeInitialized) {
	/*
	 * This is the first time we've done a lookup.  Register the
	 * tclIndexType.
	 */

        Tcl_RegisterObjType(&tclIndexType);
        indexTypeInitialized = 1;
    }

    key = Tcl_GetStringFromObj(objPtr, &length);
    index = -1;
    numAbbrev = 0;
    for (entryPtr = tablePtr, i = 0; *entryPtr != NULL; 
	    entryPtr = (char **) ((long) entryPtr + offset), i++) {
	for (p1 = key, p2 = *entryPtr; *p1 == *p2; p1++, p2++) {
	    if (*p1 == 0) {
		index = i;
		goto done;
	    }
	}
	if (*p1 == 0) {
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
    objPtr->internalRep.twoPtrValue.ptr2 = (VOID *) index;
    objPtr->typePtr = &tclIndexType;
    *indexPtr = index;
    return TCL_OK;

    error:
    if (interp != NULL) {

	resultPtr = Tcl_GetObjResult(interp);
	Tcl_AppendStringsToObj(resultPtr,
		(numAbbrev > 1) ? "ambiguous " : "bad ", msg, " \"",
		key, "\": must be ", *tablePtr, (char *) NULL);

	for (entryPtr = tablePtr+1; *entryPtr != NULL; entryPtr++) {

	    if (entryPtr[1] == NULL) {
		Tcl_AppendStringsToObj(resultPtr, ", or ", *entryPtr,

			(char *) NULL);
	    } else {
		Tcl_AppendStringsToObj(resultPtr, ", ", *entryPtr,
			(char *) NULL);
	    }
	}
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * DupIndexInternalRep --
 *
 *	Copy the internal representation of an index Tcl_Obj from one
 *	object to another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	"copyPtr"s internal rep is set to same value as "srcPtr"s
 *	internal rep.
 *
 *----------------------------------------------------------------------
 */

static void
DupIndexInternalRep(srcPtr, copyPtr)
    register Tcl_Obj *srcPtr;	/* Object with internal rep to copy. */
    register Tcl_Obj *copyPtr;	/* Object with internal rep to set. */
{
    copyPtr->internalRep.twoPtrValue.ptr1
	    = srcPtr->internalRep.twoPtrValue.ptr1;
    copyPtr->internalRep.twoPtrValue.ptr2
	    = srcPtr->internalRep.twoPtrValue.ptr2;
    copyPtr->typePtr = &tclIndexType;
}

/*
 *----------------------------------------------------------------------
 *
 * SetIndexFromAny --
 *
 *	This procedure is called to convert a Tcl object to index







>




>
|
>
|
|
>









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







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
    objPtr->internalRep.twoPtrValue.ptr2 = (VOID *) index;
    objPtr->typePtr = &tclIndexType;
    *indexPtr = index;
    return TCL_OK;

    error:
    if (interp != NULL) {
	int count;
	resultPtr = Tcl_GetObjResult(interp);
	Tcl_AppendStringsToObj(resultPtr,
		(numAbbrev > 1) ? "ambiguous " : "bad ", msg, " \"",
		key, "\": must be ", *tablePtr, (char *) NULL);
	for (entryPtr = (char **) ((long) tablePtr + offset), count = 0;
		*entryPtr != NULL;
		entryPtr = (char **) ((long) entryPtr + offset), count++) {
	    if ((*((char **) ((long) entryPtr + offset))) == NULL) {
		Tcl_AppendStringsToObj(resultPtr,
			(count > 0) ? ", or " : " or ", *entryPtr,
			(char *) NULL);
	    } else {
		Tcl_AppendStringsToObj(resultPtr, ", ", *entryPtr,
			(char *) NULL);
	    }
	}
    }
    return TCL_ERROR;
}































/*
 *----------------------------------------------------------------------
 *
 * SetIndexFromAny --
 *
 *	This procedure is called to convert a Tcl object to index
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
    register Tcl_Obj *objPtr;	/* The object to convert. */
{
    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	    "can't convert value to index except via Tcl_GetIndexFromObj API",
	    -1);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateStringOfIndex --
 *
 *	This procedure is called to update the string representation for
 *	an index object.  It should never be called, because we never
 *	invalidate the string representation for an index object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A panic is added
 *
 *----------------------------------------------------------------------
 */

static void
UpdateStringOfIndex(objPtr)
    register Tcl_Obj *objPtr;	/* Int object whose string rep to update. */
{
    panic("UpdateStringOfIndex should never be invoked");
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_WrongNumArgs --
 *
 *	This procedure generates a "wrong # args" error message in an







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







258
259
260
261
262
263
264

























265
266
267
268
269
270
271
    register Tcl_Obj *objPtr;	/* The object to convert. */
{
    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	    "can't convert value to index except via Tcl_GetIndexFromObj API",
	    -1);
    return TCL_ERROR;
}


























/*
 *----------------------------------------------------------------------
 *
 * Tcl_WrongNumArgs --
 *
 *	This procedure generates a "wrong # args" error message in an
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
	
	if (objv[i]->typePtr == &tclIndexType) {
	    tablePtr = ((char **) objv[i]->internalRep.twoPtrValue.ptr1);
	    Tcl_AppendStringsToObj(objPtr,
		    tablePtr[(int) objv[i]->internalRep.twoPtrValue.ptr2],
		    (char *) NULL);
	} else {
	    Tcl_AppendStringsToObj(objPtr,
		    Tcl_GetStringFromObj(objv[i], (int *) NULL),
		    (char *) NULL);
	}
	if (i < (objc - 1)) {
	    Tcl_AppendStringsToObj(objPtr, " ", (char *) NULL);
	}
    }
    if (message) {
      Tcl_AppendStringsToObj(objPtr, " ", message, (char *) NULL);
    }
    Tcl_AppendStringsToObj(objPtr, "\"", (char *) NULL);
}







|
<











314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
329
330
331
332
	
	if (objv[i]->typePtr == &tclIndexType) {
	    tablePtr = ((char **) objv[i]->internalRep.twoPtrValue.ptr1);
	    Tcl_AppendStringsToObj(objPtr,
		    tablePtr[(int) objv[i]->internalRep.twoPtrValue.ptr2],
		    (char *) NULL);
	} else {
	    Tcl_AppendStringsToObj(objPtr, Tcl_GetString(objv[i]),

		    (char *) NULL);
	}
	if (i < (objc - 1)) {
	    Tcl_AppendStringsToObj(objPtr, " ", (char *) NULL);
	}
    }
    if (message) {
      Tcl_AppendStringsToObj(objPtr, " ", message, (char *) NULL);
    }
    Tcl_AppendStringsToObj(objPtr, "\"", (char *) NULL);
}

Added generic/tclInitScript.h.





































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/* 
 * tclInitScript.h --
 *
 *	This file contains Unix & Windows common init script
 *      It is not used on the Mac. (the mac init script is in tclMacInit.c)
 *
 * 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: tclInitScript.h,v 1.1.2.3 1999/03/12 23:29:14 surles Exp $
 */

/*
 * The following string is the startup script executed in new
 * interpreters.  It looks on disk in several different directories
 * for a script "init.tcl" that is compatible with this version
 * of Tcl.  The init.tcl script does all of the real work of
 * initialization.
 */

static char initScript[] = "if {[info proc tclInit]==\"\"} {\n\
  proc tclInit {} {\n\
    global tcl_libPath tcl_library errorInfo\n\
    rename tclInit {}\n\
    set errors {}\n\
    foreach i $tcl_libPath {\n\
	set tcl_library $i\n\
	set tclfile [file join $i init.tcl]\n\
	if {[file exists $tclfile]} {\n\
	    if {[catch {uplevel #0 [list source $tclfile]} msg] != 1} {\n\
		return\n\
	    } else {\n\
		append errors \"$tclfile: $msg\n$errorInfo\n\"\n\
	    }\n\
	}\n\
    }\n\
    set msg \"Can't find a usable init.tcl in the following directories: \n\"\n\
    append msg \"    $tcl_libPath\n\n\"\n\
    append msg \"$errors\n\n\"\n\
    append msg \"This probably means that Tcl wasn't installed properly.\n\"\n\
    error $msg\n\
  }\n\
}\n\
tclInit";


/*
 * A pointer to a string that holds an initialization script that if non-NULL
 * is evaluated in Tcl_Init() prior to the the built-in initialization script
 * above.  This variable can be modified by the procedure below.
 */
 
static char *          tclPreInitScript = NULL;


/*
 *----------------------------------------------------------------------
 *
 * TclSetPreInitScript --
 *
 *	This routine is used to change the value of the internal
 *	variable, tclPreInitScript.
 *
 * Results:
 *	Returns the current value of tclPreInitScript.
 *
 * Side effects:
 *	Changes the way Tcl_Init() routine behaves.
 *
 *----------------------------------------------------------------------
 */

char *
TclSetPreInitScript (string)
    char *string;		/* Pointer to a script. */
{
    char *prevString = tclPreInitScript;
    tclPreInitScript = string;
    return(prevString);
}

Added generic/tclInt.decls.





















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
# tclInt.decls --
#
#	This file contains the declarations for all unsupported
#	functions that are exported by the Tcl library.  This file
#	is used to generate the tclIntDecls.h, tclIntPlatDecls.h,
#	tclIntStub.c, tclPlatStub.c, tclCompileDecls.h and tclCompileStub.c
#	files
#
# 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: tclInt.decls,v 1.3.2.6 1999/04/06 03:13:16 redman Exp $

library tcl

# Define the unsupported generic interfaces.

interface tclInt

# Declare each of the functions in the unsupported internal Tcl
# interface.  These interfaces are allowed to changed between versions.
# Use at your own risk.  Note that the position of functions should not
# be changed between versions to avoid gratuitous incompatibilities.

declare 0 generic {
    int TclAccess(CONST char *path, int mode)
}
declare 1 generic {
    int TclAccessDeleteProc(TclAccessProc_ *proc)
}
declare 2 generic {
    int TclAccessInsertProc(TclAccessProc_ *proc)
}
declare 3 generic {
    void TclAllocateFreeObjects(void)
}
# Replaced by TclpChdir in 8.1:
#  declare 4 generic {   
#      int TclChdir(Tcl_Interp *interp, char *dirName)
#  }
declare 5 generic {
    int TclCleanupChildren(Tcl_Interp *interp, int numPids, Tcl_Pid *pidPtr, \
	    Tcl_Channel errorChan)
}
declare 6 generic {
    void TclCleanupCommand(Command *cmdPtr)
}
declare 7 generic {
    int TclCopyAndCollapse(int count, CONST char *src, char *dst)
}
declare 8 generic {
    int TclCopyChannel(Tcl_Interp *interp, Tcl_Channel inChan, \
	    Tcl_Channel outChan, int toRead, Tcl_Obj *cmdPtr)
}

# TclCreatePipeline unofficially exported for use by BLT.

declare 9 generic {
    int TclCreatePipeline(Tcl_Interp *interp, int argc, char **argv, \
	    Tcl_Pid **pidArrayPtr, TclFile *inPipePtr, TclFile *outPipePtr, \
	    TclFile *errFilePtr)
}
declare 10 generic {
    int TclCreateProc(Tcl_Interp *interp, Namespace *nsPtr, char *procName, \
	    Tcl_Obj *argsPtr, Tcl_Obj *bodyPtr, Proc **procPtrPtr)
}
declare 11 generic {
    void TclDeleteCompiledLocalVars(Interp *iPtr, CallFrame *framePtr)
}
declare 12 generic {
    void TclDeleteVars(Interp *iPtr, Tcl_HashTable *tablePtr)
}
declare 13 generic {
    int TclDoGlob(Tcl_Interp *interp, char *separators, \
	    Tcl_DString *headPtr, char *tail)
}
declare 14 generic {
    void TclDumpMemoryInfo(FILE *outFile)
}
# Removed in 8.1:
#  declare 15 generic {
#      void TclExpandParseValue(ParseValue *pvPtr, int needed)
#  }
declare 16 generic {
    void TclExprFloatError(Tcl_Interp *interp, double value)
}
declare 17 generic {
    int TclFileAttrsCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
}
declare 18 generic {
    int TclFileCopyCmd(Tcl_Interp *interp, int argc, char **argv)
}
declare 19 generic {
    int TclFileDeleteCmd(Tcl_Interp *interp, int argc, char **argv)
}
declare 20 generic {
    int TclFileMakeDirsCmd(Tcl_Interp *interp, int argc, char **argv)
}
declare 21 generic {
    int TclFileRenameCmd(Tcl_Interp *interp, int argc, char **argv)
}
declare 22 generic {
    int TclFindElement(Tcl_Interp *interp, CONST char *listStr, \
	    int listLength, CONST char **elementPtr, CONST char **nextPtr, \
	    int *sizePtr, int *bracePtr)
}
declare 23 generic {
    Proc * TclFindProc(Interp *iPtr, char *procName)
}
declare 24 generic {
    int TclFormatInt(char *buffer, long n)
}
declare 25 generic {
    void TclFreePackageInfo(Interp *iPtr)
}
# Removed in 8.1:
#  declare 26 generic {	
#      char * TclGetCwd(Tcl_Interp *interp)
#  }
declare 27 generic {
    int TclGetDate(char *p, unsigned long now, long zone, \
	    unsigned long *timePtr)
}
declare 28 generic {
    Tcl_Channel TclpGetDefaultStdChannel(int type)
}
declare 29 generic {
    Tcl_Obj * TclGetElementOfIndexedArray(Tcl_Interp *interp, \
	    int localIndex, Tcl_Obj *elemPtr, int leaveErrorMsg)
}
# Replaced by char * TclGetEnv(CONST char *name, Tcl_DString *valuePtr) in 8.1:
#  declare 30 generic {
#      char * TclGetEnv(CONST char *name)
#  }
declare 31 generic {
    char * TclGetExtension(char *name)
}
declare 32 generic {
    int TclGetFrame(Tcl_Interp *interp, char *str, CallFrame **framePtrPtr)
}
declare 33 generic {
    TclCmdProcType TclGetInterpProc(void)
}
declare 34 generic {
    int TclGetIntForIndex(Tcl_Interp *interp, Tcl_Obj *objPtr, \
	    int endValue, int *indexPtr)
}
declare 35 generic {
    Tcl_Obj * TclGetIndexedScalar(Tcl_Interp *interp, int localIndex, \
	    int leaveErrorMsg)
}
declare 36 generic {
    int TclGetLong(Tcl_Interp *interp, char *str, long *longPtr)
}
declare 37 generic {
    int TclGetLoadedPackages(Tcl_Interp *interp, char *targetName)
}
declare 38 generic {
    int TclGetNamespaceForQualName(Tcl_Interp *interp, char *qualName, \
	    Namespace *cxtNsPtr, int flags, Namespace **nsPtrPtr, \
	    Namespace **altNsPtrPtr, Namespace **actualCxtPtrPtr, \
	    char **simpleNamePtr)
}
declare 39 generic {
    TclObjCmdProcType TclGetObjInterpProc(void)
}
declare 40 generic {
    int TclGetOpenMode(Tcl_Interp *interp, char *str, int *seekFlagPtr)
}
declare 41 generic {
    Tcl_Command TclGetOriginalCommand(Tcl_Command command)
}
declare 42 generic {
    char * TclpGetUserHome(CONST char *name, Tcl_DString *bufferPtr)
}
declare 43 generic {
    int TclGlobalInvoke(Tcl_Interp *interp, int argc, char **argv, int flags)
}
declare 44 generic {
    int TclGuessPackageName(char *fileName, Tcl_DString *bufPtr)
}
declare 45 generic {
    int TclHideUnsafeCommands(Tcl_Interp *interp)
}
declare 46 generic {
    int TclInExit(void)
}
declare 47 generic {
    Tcl_Obj * TclIncrElementOfIndexedArray(Tcl_Interp *interp, \
	    int localIndex, Tcl_Obj *elemPtr, long incrAmount)
}
declare 48 generic {
    Tcl_Obj * TclIncrIndexedScalar(Tcl_Interp *interp, int localIndex, \
	    long incrAmount)
}
declare 49 generic {
    Tcl_Obj * TclIncrVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, \
	    Tcl_Obj *part2Ptr, long incrAmount, int part1NotParsed)
}
declare 50 generic {
    void TclInitCompiledLocals(Tcl_Interp *interp, CallFrame *framePtr, \
	    Namespace *nsPtr)
}
declare 51 generic {
    int TclInterpInit(Tcl_Interp *interp)
}
declare 52 generic {
    int TclInvoke(Tcl_Interp *interp, int argc, char **argv, int flags)
}
declare 53 generic {
    int TclInvokeObjectCommand(ClientData clientData, Tcl_Interp *interp, \
	    int argc, char **argv)
}
declare 54 generic {
    int TclInvokeStringCommand(ClientData clientData, Tcl_Interp *interp, \
	    int objc, Tcl_Obj *CONST objv[])
}
declare 55 generic {
    Proc * TclIsProc(Command *cmdPtr)
}
# Replaced with TclpLoadFile in 8.1:
#  declare 56 generic {
#      int TclLoadFile(Tcl_Interp *interp, char *fileName, char *sym1, \
#  	    char *sym2, Tcl_PackageInitProc **proc1Ptr, \
#  	    Tcl_PackageInitProc **proc2Ptr)
#  }
# Signature changed to take a length in 8.1:
#  declare 57 generic {
#      int TclLooksLikeInt(char *p)
#  }
declare 58 generic {
    Var * TclLookupVar(Tcl_Interp *interp, char *part1, char *part2, \
	    int flags, char *msg, int createPart1, int createPart2, \
	    Var **arrayPtrPtr)
}
declare 59 generic {
    int TclpMatchFiles(Tcl_Interp *interp, char *separators, \
	    Tcl_DString *dirPtr, char *pattern, char *tail)
}
declare 60 generic {
    int TclNeedSpace(char *start, char *end)
}
declare 61 generic {
    Tcl_Obj * TclNewProcBodyObj(Proc *procPtr)
}
declare 62 generic {
    int TclObjCommandComplete(Tcl_Obj *cmdPtr)
}
declare 63 generic {
    int TclObjInterpProc(ClientData clientData, Tcl_Interp *interp, \
	    int objc, Tcl_Obj *CONST objv[])
}
declare 64 generic {
    int TclObjInvoke(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], \
	    int flags)
}
declare 65 generic {
    int TclObjInvokeGlobal(Tcl_Interp *interp, int objc, \
	    Tcl_Obj *CONST objv[], int flags)
}
declare 66 generic {
    int TclOpenFileChannelDeleteProc(TclOpenFileChannelProc_ *proc)
}
declare 67 generic {
    int TclOpenFileChannelInsertProc(TclOpenFileChannelProc_ *proc)
}
declare 68 generic {
    int TclpAccess(CONST char *path, int mode)
}
declare 69 generic {
    char * TclpAlloc(unsigned int size)
}
declare 70 generic {
    int TclpCopyFile(CONST char *source, CONST char *dest)
}
declare 71 generic {
    int TclpCopyDirectory(CONST char *source, CONST char *dest, \
	    Tcl_DString *errorPtr)
}
declare 72 generic {
    int TclpCreateDirectory(CONST char *path)
}
declare 73 generic {
    int TclpDeleteFile(CONST char *path)
}
declare 74 generic {
    void TclpFree(char *ptr)
}
declare 75 generic {
    unsigned long TclpGetClicks(void)
}
declare 76 generic {
    unsigned long TclpGetSeconds(void)
}
declare 77 generic {
    void TclpGetTime(Tcl_Time *time)
}
declare 78 generic {
    int TclpGetTimeZone(unsigned long time)
}
declare 79 generic {
    int TclpListVolumes(Tcl_Interp *interp)
}
declare 80 generic {
    Tcl_Channel TclpOpenFileChannel(Tcl_Interp *interp, char *fileName, \
	    char *modeString, int permissions)
}
declare 81 generic {
    char * TclpRealloc(char *ptr, unsigned int size)
}
declare 82 generic {
    int TclpRemoveDirectory(CONST char *path, int recursive, \
	    Tcl_DString *errorPtr)
}
declare 83 generic {
    int TclpRenameFile(CONST char *source, CONST char *dest)
}
# Removed in 8.1:
#  declare 84 generic {
#      int TclParseBraces(Tcl_Interp *interp, char *str, char **termPtr, \
#  	    ParseValue *pvPtr)
#  }
#  declare 85 generic {
#      int TclParseNestedCmd(Tcl_Interp *interp, char *str, int flags, \
#  	    char **termPtr, ParseValue *pvPtr)
#  }
#  declare 86 generic {
#      int TclParseQuotes(Tcl_Interp *interp, char *str, int termChar, \
#  	    int flags, char **termPtr, ParseValue *pvPtr)
#  }
#  declare 87 generic {
#      void TclPlatformInit(Tcl_Interp *interp)
#  }
declare 88 generic {
    char * TclPrecTraceProc(ClientData clientData, Tcl_Interp *interp, \
	    char *name1, char *name2, int flags)
}
declare 89 generic {
    int TclPreventAliasLoop(Tcl_Interp *interp, Tcl_Interp *cmdInterp, \
	    Tcl_Command cmd)
}
# Removed in 8.1 (only available if compiled with TCL_COMPILE_DEBUG):
#  declare 90 generic {
#      void TclPrintByteCodeObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
#  }
declare 91 generic {
    void TclProcCleanupProc(Proc *procPtr)
}
declare 92 generic {
    int TclProcCompileProc(Tcl_Interp *interp, Proc *procPtr, \
	    Tcl_Obj *bodyPtr, Namespace *nsPtr, CONST char *description, \
	    CONST char *procName)
}
declare 93 generic {
    void TclProcDeleteProc(ClientData clientData)
}
declare 94 generic {
    int TclProcInterpProc(ClientData clientData, Tcl_Interp *interp, \
	    int argc, char **argv)
}
declare 95 generic {
    int TclpStat(CONST char *path, struct stat *buf)
}
declare 96 generic {
    int TclRenameCommand(Tcl_Interp *interp, char *oldName, char *newName)
}
declare 97 generic {
    void TclResetShadowedCmdRefs(Tcl_Interp *interp, Command *newCmdPtr)
}
declare 98 generic {
    int TclServiceIdle(void)
}
declare 99 generic {
    Tcl_Obj * TclSetElementOfIndexedArray(Tcl_Interp *interp, \
	    int localIndex, Tcl_Obj *elemPtr, Tcl_Obj *objPtr, int leaveErrorMsg)
}
declare 100 generic {
    Tcl_Obj * TclSetIndexedScalar(Tcl_Interp *interp, int localIndex, \
	    Tcl_Obj *objPtr, int leaveErrorMsg)
}
# TODO: needs to be implemented
#  declare 101 generic {
#      char * TclSetPreInitScript(char *string)
#  }
declare 102 generic {
    void TclSetupEnv(Tcl_Interp *interp)
}
declare 103 generic {
    int TclSockGetPort(Tcl_Interp *interp, char *str, char *proto, \
	    int *portPtr)
}
declare 104 generic {
    int TclSockMinimumBuffers(int sock, int size)
}
declare 105 generic {
    int TclStat(CONST char *path, TclStat_ *buf)
}
declare 106 generic {
    int TclStatDeleteProc(TclStatProc_ *proc)
}
declare 107 generic {
    int TclStatInsertProc(TclStatProc_ *proc)
}
declare 108 generic {
    void TclTeardownNamespace(Namespace *nsPtr)
}
declare 109 generic {
    int TclUpdateReturnInfo(Interp *iPtr)
}
# Removed in 8.1:
#  declare 110 generic {
#      char * TclWordEnd(char *start, char *lastChar, int nested, int *semiPtr)
#  }

# Procedures used in conjunction with Tcl namespaces. They are
# defined here instead of in tcl.decls since they are not stable yet.

declare 111 generic {
    void Tcl_AddInterpResolvers(Tcl_Interp *interp, char *name, \
	    Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, \
	    Tcl_ResolveCompiledVarProc *compiledVarProc)
}
declare 112 generic {
    int Tcl_AppendExportList(Tcl_Interp *interp, Tcl_Namespace *nsPtr, \
	    Tcl_Obj *objPtr)
}
declare 113 generic {
    Tcl_Namespace * Tcl_CreateNamespace(Tcl_Interp *interp, char *name, \
	    ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc)
}
declare 114 generic {
    void Tcl_DeleteNamespace(Tcl_Namespace *nsPtr)
}
declare 115 generic {
    int Tcl_Export(Tcl_Interp *interp, Tcl_Namespace *nsPtr, char *pattern, \
	    int resetListFirst)
}
declare 116 generic {
    Tcl_Command Tcl_FindCommand(Tcl_Interp *interp, char *name, \
	    Tcl_Namespace *contextNsPtr, int flags)
}
declare 117 generic {
    Tcl_Namespace * Tcl_FindNamespace(Tcl_Interp *interp, char *name, \
	    Tcl_Namespace *contextNsPtr, int flags)
}
declare 118 generic {
    int Tcl_GetInterpResolvers(Tcl_Interp *interp, char *name, \
	    Tcl_ResolverInfo *resInfo)
}
declare 119 generic {
    int Tcl_GetNamespaceResolvers(Tcl_Namespace *namespacePtr, \
	    Tcl_ResolverInfo *resInfo)
}
declare 120 generic {
    Tcl_Var Tcl_FindNamespaceVar(Tcl_Interp *interp, char *name, \
	    Tcl_Namespace *contextNsPtr, int flags)
}
declare 121 generic {
    int Tcl_ForgetImport(Tcl_Interp *interp, Tcl_Namespace *nsPtr, \
	    char *pattern)
}
declare 122 generic {
    Tcl_Command Tcl_GetCommandFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
}
declare 123 generic {
    void Tcl_GetCommandFullName(Tcl_Interp *interp, Tcl_Command command, \
	    Tcl_Obj *objPtr)
}
declare 124 generic {
    Tcl_Namespace * Tcl_GetCurrentNamespace(Tcl_Interp *interp)
}
declare 125 generic {
    Tcl_Namespace * Tcl_GetGlobalNamespace(Tcl_Interp *interp)
}
declare 126 generic {
    void Tcl_GetVariableFullName(Tcl_Interp *interp, Tcl_Var variable, \
	    Tcl_Obj *objPtr)
}
declare 127 generic {
    int Tcl_Import(Tcl_Interp *interp, Tcl_Namespace *nsPtr, \
	    char *pattern, int allowOverwrite)
}
declare 128 generic {
    void Tcl_PopCallFrame(Tcl_Interp* interp)
}
declare 129 generic {
    int Tcl_PushCallFrame(Tcl_Interp* interp, Tcl_CallFrame *framePtr, \
	    Tcl_Namespace *nsPtr, int isProcCallFrame)
} 
declare 130 generic {
    int Tcl_RemoveInterpResolvers(Tcl_Interp *interp, char *name)
}
declare 131 generic {
    void Tcl_SetNamespaceResolvers(Tcl_Namespace *namespacePtr, \
	    Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, \
	    Tcl_ResolveCompiledVarProc *compiledVarProc)
}
declare 132 generic {
    int TclpHasSockets(Tcl_Interp *interp)
}
declare 133 generic {
    struct tm *	TclpGetDate(TclpTime_t time, int useGMT)
}
declare 134 generic {
    size_t TclpStrftime(char *s, size_t maxsize, CONST char *format, \
	    CONST struct tm *t)
}
declare 135 generic {
    int TclpCheckStackSpace(void)
}

# Added in 8.1:

declare 137 generic {
   int TclpChdir(CONST char *dirName)
}
declare 138 generic {
    char * TclGetEnv(CONST char *name, Tcl_DString *valuePtr)
}
declare 139 generic {
    int TclpLoadFile(Tcl_Interp *interp, char *fileName, char *sym1, \
	    char *sym2, Tcl_PackageInitProc **proc1Ptr, \
	    Tcl_PackageInitProc **proc2Ptr, ClientData *clientDataPtr)
}
declare 140 generic {
    int TclLooksLikeInt(char *bytes, int length)
}

declare 141 generic {
    char *TclpGetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr)
}
##############################################################################

# Define the platform specific internal Tcl interface. These functions are
# only available on the designated platform.

interface tclIntPlat

########################
# Mac specific internals

declare 0 mac {
    VOID * TclpSysAlloc(long size, int isBin)
}
declare 1 mac {
    void TclpSysFree(VOID *ptr)
}
declare 2 mac {
    VOID * TclpSysRealloc(VOID *cp, unsigned int size)
}
declare 3 mac {
    void TclpExit(int status)
}

# Prototypes for functions found in the tclMacUtil.c compatability library.

declare 4 mac {
    int FSpGetDefaultDir(FSSpecPtr theSpec)
}
declare 5 mac {
    int FSpSetDefaultDir(FSSpecPtr theSpec)
}
declare 6 mac {
    OSErr FSpFindFolder(short vRefNum, OSType folderType, \
	    Boolean createFolder, FSSpec *spec)
}
declare 7 mac {
    void GetGlobalMouse(Point *mouse)
}

# The following routines are utility functions in Tcl.  They are exported
# here because they are needed in Tk.  They are not officially supported,
# however.  The first set are from the MoreFiles package.

declare 8 mac {
    pascal OSErr FSpGetDirectoryID(CONST FSSpec *spec, long *theDirID, \
	    Boolean *isDirectory)
}
declare 9 mac {
    pascal short FSpOpenResFileCompat(CONST FSSpec *spec, \
	    SignedByte permission)
}
declare 10 mac {
    pascal void FSpCreateResFileCompat(CONST FSSpec *spec, OSType creator, \
	    OSType fileType, ScriptCode scriptTag)
}

# Like the MoreFiles routines these fix problems in the standard
# Mac calls.  These routines are from tclMacUtils.h.

declare 11 mac {
    int FSpLocationFromPath(int length, CONST char *path, FSSpecPtr theSpec)
}
declare 12 mac {
    OSErr FSpPathFromLocation(FSSpecPtr theSpec, int *length, \
	    Handle *fullPath)
}

# Prototypes of Mac only internal functions.

declare 13 mac {
    void TclMacExitHandler(void)
}
declare 14 mac {
    void TclMacInitExitToShell(int usePatch)
}
declare 15 mac {
    OSErr TclMacInstallExitToShellPatch(ExitToShellProcPtr newProc)
}
declare 16 mac {
    int TclMacOSErrorToPosixError(int error)
}
declare 17 mac {
    void TclMacRemoveTimer(void *timerToken)
}
declare 18 mac {
    void * TclMacStartTimer(long ms)
}
declare 19 mac {
    int TclMacTimerExpired(void *timerToken)
}
declare 20 mac {
    int TclMacRegisterResourceFork(short fileRef, Tcl_Obj *tokenPtr, \
	    int insert)
}	
declare 21 mac {
    short TclMacUnRegisterResourceFork(char *tokenPtr, Tcl_Obj *resultPtr)
}	
declare 22 mac {
    int TclMacCreateEnv(void)
}
declare 23 mac {
    FILE * TclMacFOpenHack(CONST char *path, CONST char *mode)
}
# Replaced in 8.1 by TclpReadLink:
#  declare 24 mac {
#      int TclMacReadlink(char *path, char *buf, int size)
#  }
declare 25 mac {
    int TclMacChmod(char *path, int mode)
}

############################
# Windows specific internals

declare 0 win {
    void TclWinConvertError(DWORD errCode)
}
declare 1 win {
    void TclWinConvertWSAError(DWORD errCode)
}
declare 2 win {
    struct servent * TclWinGetServByName(CONST char *nm, \
	    CONST char *proto)
}
declare 3 win {
    int TclWinGetSockOpt(SOCKET s, int level, int optname, \
	    char FAR * optval, int FAR *optlen)
}
declare 4 win {
    HINSTANCE TclWinGetTclInstance(void)
}
# Removed in 8.1:
#  declare 5 win {
#      HINSTANCE TclWinLoadLibrary(char *name)
#  }
declare 6 win {
    u_short TclWinNToHS(u_short ns)
}
declare 7 win {
    int TclWinSetSockOpt(SOCKET s, int level, int optname, \
	    CONST char FAR * optval, int optlen)
}
declare 8 win {
    unsigned long TclpGetPid(Tcl_Pid pid)
}
declare 9 win {
    int TclWinGetPlatformId(void)
}
declare 10 win {
    int TclWinSynchSpawn(void *args, int type, void **trans, Tcl_Pid *pidPtr)
}

# Pipe channel functions

declare 11 win {
    void TclGetAndDetachPids(Tcl_Interp *interp, Tcl_Channel chan)
}
declare 12 win {
    int TclpCloseFile(TclFile file)
}
declare 13 win {
    Tcl_Channel TclpCreateCommandChannel(TclFile readFile, \
	    TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr)
}
declare 14 win {
    int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe)
}
declare 15 win {
    int TclpCreateProcess(Tcl_Interp *interp, int argc, char **argv, \
	    TclFile inputFile, TclFile outputFile, TclFile errorFile, \
	    Tcl_Pid *pidPtr)
}
# Signature changed in 8.1:
#  declare 16 win {
#      TclFile TclpCreateTempFile(char *contents, Tcl_DString *namePtr)
#  }
#  declare 17 win {
#      char * TclpGetTZName(void)
#  }
declare 18 win {
    TclFile TclpMakeFile(Tcl_Channel channel, int direction)
}
declare 19 win {
    TclFile TclpOpenFile(CONST char *fname, int mode)
}
declare 20 win {
    void TclWinAddProcess(HANDLE hProcess, DWORD id)
}
declare 21 win {
    void TclpAsyncMark(Tcl_AsyncHandler async)
}

# Added in 8.1:
declare 22 win {
    TclFile TclpCreateTempFile(CONST char *contents)
}
declare 23 win {
    char * TclpGetTZName(int isdst)
}
declare 24 win {
    char * TclWinNoBackslash(char *path)
}

#########################
# Unix specific internals

# Pipe channel functions

declare 0 unix {
    void TclGetAndDetachPids(Tcl_Interp *interp, Tcl_Channel chan)
}
declare 1 unix {
    int TclpCloseFile(TclFile file)
}
declare 2 unix {
    Tcl_Channel TclpCreateCommandChannel(TclFile readFile, \
	    TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr)
}
declare 3 unix {
    int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe)
}
declare 4 unix {
    int TclpCreateProcess(Tcl_Interp *interp, int argc, char **argv, \
	    TclFile inputFile, TclFile outputFile, TclFile errorFile, \
	    Tcl_Pid *pidPtr)
}
# Signature changed in 8.1:
#  declare 5 unix {
#      TclFile TclpCreateTempFile(char *contents, 
#      Tcl_DString *namePtr)
#  }
declare 6 unix {
    TclFile TclpMakeFile(Tcl_Channel channel, int direction)
}
declare 7 unix {
    TclFile TclpOpenFile(CONST char *fname, int mode)
}
declare 8 unix {
    int TclUnixWaitForFile(int fd, int mask, int timeout)
}

# Added in 8.1:

declare 9 unix {
    TclFile TclpCreateTempFile(CONST char *contents)
}

Changes to generic/tclInt.h.

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
/*
 * tclInt.h --
 *
 *	Declarations of things used internally by the Tcl interpreter.
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1993-1997 Lucent Technologies.


 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 *SCCS: @(#) tclInt.h 1.293 97/08/12 17:07:02
 */

#ifndef _TCLINT
#define _TCLINT

/*
 * Common include files needed by most of the Tcl source files are
 * included here, so that system-dependent personalizations for the
 * include files only have to be made in once place.  This results
 * in a few extra includes, but greater modularity.  The order of
 * the three groups of #includes is important.  For example, stdio.h
 * is needed by tcl.h, and the _ANSI_ARGS_ declaration in tcl.h is
 * needed by stdlib.h in some configurations.
 */

#include <stdio.h>

#ifndef _TCL
#include "tcl.h"
#endif
#ifndef _REGEXP
#include "tclRegexp.h"
#endif

#include <ctype.h>
#ifdef NO_LIMITS_H
#   include "../compat/limits.h"
#else
#   include <limits.h>
#endif
#ifdef NO_STDLIB_H
#   include "../compat/stdlib.h"
#else
#   include <stdlib.h>
#endif
#ifdef NO_STRING_H
#include "../compat/string.h"
#else
#include <string.h>
#endif
#if defined(__STDC__) || defined(HAS_STDARG)

#   include <stdarg.h>

#else


#   include <varargs.h>


#endif




















































/*
 *----------------------------------------------------------------
 * Data structures related to namespaces.
 *----------------------------------------------------------------
 */

/*






<

>
>




|










|









<
<
<

















|
>
|
>

>
>
|
>
>


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







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
/*
 * tclInt.h --
 *
 *	Declarations of things used internally by the Tcl interpreter.
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.

 * Copyright (c) 1993-1997 Lucent Technologies.
 * Copyright (c) 1994-1998 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: tclInt.h,v 1.1.2.21 1999/04/14 00:33:23 surles Exp $
 */

#ifndef _TCLINT
#define _TCLINT

/*
 * Common include files needed by most of the Tcl source files are
 * included here, so that system-dependent personalizations for the
 * include files only have to be made in once place.  This results
 * in a few extra includes, but greater modularity.  The order of
 * the three groups of #includes is important.	For example, stdio.h
 * is needed by tcl.h, and the _ANSI_ARGS_ declaration in tcl.h is
 * needed by stdlib.h in some configurations.
 */

#include <stdio.h>

#ifndef _TCL
#include "tcl.h"
#endif




#include <ctype.h>
#ifdef NO_LIMITS_H
#   include "../compat/limits.h"
#else
#   include <limits.h>
#endif
#ifdef NO_STDLIB_H
#   include "../compat/stdlib.h"
#else
#   include <stdlib.h>
#endif
#ifdef NO_STRING_H
#include "../compat/string.h"
#else
#include <string.h>
#endif

#undef TCL_STORAGE_CLASS
#ifdef BUILD_tcl
# define TCL_STORAGE_CLASS DLLEXPORT
#else
# ifdef USE_TCL_STUBS
#  define TCL_STORAGE_CLASS
# else
#  define TCL_STORAGE_CLASS DLLIMPORT
# endif
#endif

/*
 * The following procedures allow namespaces to be customized to
 * support special name resolution rules for commands/variables.
 * 
 */

struct Tcl_ResolvedVarInfo;

typedef Tcl_Var (Tcl_ResolveRuntimeVarProc) _ANSI_ARGS_((
    Tcl_Interp* interp, struct Tcl_ResolvedVarInfo *vinfoPtr));

typedef void (Tcl_ResolveVarDeleteProc) _ANSI_ARGS_((
    struct Tcl_ResolvedVarInfo *vinfoPtr));

/*
 * The following structure encapsulates the routines needed to resolve a
 * variable reference at runtime.  Any variable specific state will typically
 * be appended to this structure.
 */


typedef struct Tcl_ResolvedVarInfo {
    Tcl_ResolveRuntimeVarProc *fetchProc;
    Tcl_ResolveVarDeleteProc *deleteProc;
} Tcl_ResolvedVarInfo;



typedef int (Tcl_ResolveCompiledVarProc) _ANSI_ARGS_((
    Tcl_Interp* interp, char* name, int length,
    Tcl_Namespace *context, Tcl_ResolvedVarInfo **rPtr));

typedef int (Tcl_ResolveVarProc) _ANSI_ARGS_((
    Tcl_Interp* interp, char* name, Tcl_Namespace *context,
    int flags, Tcl_Var *rPtr));

typedef int (Tcl_ResolveCmdProc) _ANSI_ARGS_((Tcl_Interp* interp,
    char* name, Tcl_Namespace *context, int flags,
    Tcl_Command *rPtr));
 
typedef struct Tcl_ResolverInfo {
    Tcl_ResolveCmdProc *cmdResProc;	/* Procedure handling command name
					 * resolution. */
    Tcl_ResolveVarProc *varResProc;	/* Procedure handling variable name
					 * resolution for variables that
					 * can only be handled at runtime. */
    Tcl_ResolveCompiledVarProc *compiledVarResProc;
					/* Procedure handling variable name
					 * resolution at compile time. */
} Tcl_ResolverInfo;

/*
 *----------------------------------------------------------------
 * Data structures related to namespaces.
 *----------------------------------------------------------------
 */

/*
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
    Tcl_NamespaceDeleteProc *deleteProc;
				 /* Procedure invoked when deleting the
				  * namespace to, e.g., free clientData. */
    struct Namespace *parentPtr; /* Points to the namespace that contains
				  * this one. NULL if this is the global
				  * namespace. */
    Tcl_HashTable childTable;	 /* Contains any child namespaces. Indexed
                                  * by strings; values have type
				  * (Namespace *). */
    long nsId;			 /* Unique id for the namespace. */
    Tcl_Interp *interp;		 /* The interpreter containing this
				  * namespace. */
    int flags;			 /* OR-ed combination of the namespace
				  * status flags NS_DYING and NS_DEAD
				  * listed below. */
    int activationCount;	 /* Number of "activations" or active call
				  * frames for this namespace that are on
				  * the Tcl call stack. The namespace won't
				  * be freed until activationCount becomes
				  * zero. */
    int refCount;		 /* Count of references by namespaceName *
				  * objects. The namespace can't be freed
				  * until refCount becomes zero. */
    Tcl_HashTable cmdTable;	 /* Contains all the commands currently
                                  * registered in the namespace. Indexed by
                                  * strings; values have type (Command *).
				  * Commands imported by Tcl_Import have
				  * Command structures that point (via an
				  * ImportedCmdRef structure) to the
				  * Command structure in the source
				  * namespace's command table. */
    Tcl_HashTable varTable;	 /* Contains all the (global) variables
				  * currently in this namespace. Indexed
                                  * by strings; values have type (Var *). */
    char **exportArrayPtr;	 /* Points to an array of string patterns
				  * specifying which commands are exported.
				  * A pattern may include "string match"
				  * style wildcard characters to specify
				  * multiple commands; however, no namespace
				  * qualifiers are allowed. NULL if no
				  * export patterns are registered. */
    int numExportPatterns;	 /* Number of export patterns currently
				  * registered using "namespace export". */
    int maxExportPatterns;	 /* Mumber of export patterns for which
				  * space is currently allocated. */
    int cmdRefEpoch;		 /* Incremented if a newly added command
				  * shadows a command for which this
				  * namespace has already cached a Command *
				  * pointer; this causes all its cached
				  * Command* pointers to be invalidated. */

























} Namespace;

/*
 * Flags used to represent the status of a namespace:
 *
 * NS_DYING -	1 means Tcl_DeleteNamespace has been called to delete the
 *		namespace but there are still active call frames on the Tcl







|
















|
|







|
















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







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
    Tcl_NamespaceDeleteProc *deleteProc;
				 /* Procedure invoked when deleting the
				  * namespace to, e.g., free clientData. */
    struct Namespace *parentPtr; /* Points to the namespace that contains
				  * this one. NULL if this is the global
				  * namespace. */
    Tcl_HashTable childTable;	 /* Contains any child namespaces. Indexed
				  * by strings; values have type
				  * (Namespace *). */
    long nsId;			 /* Unique id for the namespace. */
    Tcl_Interp *interp;		 /* The interpreter containing this
				  * namespace. */
    int flags;			 /* OR-ed combination of the namespace
				  * status flags NS_DYING and NS_DEAD
				  * listed below. */
    int activationCount;	 /* Number of "activations" or active call
				  * frames for this namespace that are on
				  * the Tcl call stack. The namespace won't
				  * be freed until activationCount becomes
				  * zero. */
    int refCount;		 /* Count of references by namespaceName *
				  * objects. The namespace can't be freed
				  * until refCount becomes zero. */
    Tcl_HashTable cmdTable;	 /* Contains all the commands currently
				  * registered in the namespace. Indexed by
				  * strings; values have type (Command *).
				  * Commands imported by Tcl_Import have
				  * Command structures that point (via an
				  * ImportedCmdRef structure) to the
				  * Command structure in the source
				  * namespace's command table. */
    Tcl_HashTable varTable;	 /* Contains all the (global) variables
				  * currently in this namespace. Indexed
				  * by strings; values have type (Var *). */
    char **exportArrayPtr;	 /* Points to an array of string patterns
				  * specifying which commands are exported.
				  * A pattern may include "string match"
				  * style wildcard characters to specify
				  * multiple commands; however, no namespace
				  * qualifiers are allowed. NULL if no
				  * export patterns are registered. */
    int numExportPatterns;	 /* Number of export patterns currently
				  * registered using "namespace export". */
    int maxExportPatterns;	 /* Mumber of export patterns for which
				  * space is currently allocated. */
    int cmdRefEpoch;		 /* Incremented if a newly added command
				  * shadows a command for which this
				  * namespace has already cached a Command *
				  * pointer; this causes all its cached
				  * Command* pointers to be invalidated. */
    int resolverEpoch;		 /* Incremented whenever the name resolution
				  * rules change for this namespace; this
				  * invalidates all byte codes compiled in
				  * the namespace, causing the code to be
				  * recompiled under the new rules. */
    Tcl_ResolveCmdProc *cmdResProc;
				 /* If non-null, this procedure overrides
				  * the usual command resolution mechanism
				  * in Tcl.  This procedure is invoked
				  * within Tcl_FindCommand to resolve all
				  * command references within the namespace. */
    Tcl_ResolveVarProc *varResProc;
				 /* If non-null, this procedure overrides
				  * the usual variable resolution mechanism
				  * in Tcl.  This procedure is invoked
				  * within Tcl_FindNamespaceVar to resolve all
				  * variable references within the namespace
				  * at runtime. */
    Tcl_ResolveCompiledVarProc *compiledVarResProc;
				 /* If non-null, this procedure overrides
				  * the usual variable resolution mechanism
				  * in Tcl.  This procedure is invoked
				  * within LookupCompiledLocal to resolve
				  * variable references within the namespace
				  * at compile time. */
} Namespace;

/*
 * Flags used to represent the status of a namespace:
 *
 * NS_DYING -	1 means Tcl_DeleteNamespace has been called to delete the
 *		namespace but there are still active call frames on the Tcl
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
 *		allows the namespace resolution code to recognize that the
 *		namespace is "deleted". When the last namespaceName object
 *		in any byte code code unit that refers to the namespace has
 *		been freed (i.e., when the namespace's refCount is 0), the
 *		namespace's storage will be freed.
 */

#define NS_DYING  	0x01
#define NS_DEAD  	0x02

/*
 * Flag passed to TclGetNamespaceForQualName to have it create all namespace
 * components of a namespace-qualified name that cannot be found. The new
 * namespaces are created within their specified parent. Note that this
 * flag's value must not conflict with the values of the flags
 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, and FIND_ONLY_NS (defined in







|
|







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
 *		allows the namespace resolution code to recognize that the
 *		namespace is "deleted". When the last namespaceName object
 *		in any byte code code unit that refers to the namespace has
 *		been freed (i.e., when the namespace's refCount is 0), the
 *		namespace's storage will be freed.
 */

#define NS_DYING	0x01
#define NS_DEAD		0x02

/*
 * Flag passed to TclGetNamespaceForQualName to have it create all namespace
 * components of a namespace-qualified name that cannot be found. The new
 * namespaces are created within their specified parent. Note that this
 * flag's value must not conflict with the values of the flags
 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, and FIND_ONLY_NS (defined in
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

typedef struct VarTrace {
    Tcl_VarTraceProc *traceProc;/* Procedure to call when operations given
				 * by flags are performed on variable. */
    ClientData clientData;	/* Argument to pass to proc. */
    int flags;			/* What events the trace procedure is
				 * interested in:  OR-ed combination of
				 * TCL_TRACE_READS, TCL_TRACE_WRITES, and
				 * TCL_TRACE_UNSETS. */
    struct VarTrace *nextPtr;	/* Next in list of traces associated with
				 * a particular variable. */
} VarTrace;

/*
 * When a variable trace is active (i.e. its associated procedure is
 * executing), one of the following structures is linked into a list
 * associated with the variable's interpreter.  The information in
 * the structure is needed in order for Tcl to behave reasonably
 * if traces are deleted while traces are active.
 */

typedef struct ActiveVarTrace {
    struct Var *varPtr;		/* Variable that's being traced. */
    struct ActiveVarTrace *nextPtr;







|
|







|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

typedef struct VarTrace {
    Tcl_VarTraceProc *traceProc;/* Procedure to call when operations given
				 * by flags are performed on variable. */
    ClientData clientData;	/* Argument to pass to proc. */
    int flags;			/* What events the trace procedure is
				 * interested in:  OR-ed combination of
				 * TCL_TRACE_READS, TCL_TRACE_WRITES,
				 * TCL_TRACE_UNSETS and TCL_TRACE_ARRAY. */
    struct VarTrace *nextPtr;	/* Next in list of traces associated with
				 * a particular variable. */
} VarTrace;

/*
 * When a variable trace is active (i.e. its associated procedure is
 * executing), one of the following structures is linked into a list
 * associated with the variable's interpreter.	The information in
 * the structure is needed in order for Tcl to behave reasonably
 * if traces are deleted while traces are active.
 */

typedef struct ActiveVarTrace {
    struct Var *varPtr;		/* Variable that's being traced. */
    struct ActiveVarTrace *nextPtr;
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
				 * multiple concurrent searches for the
				 * same array. */
    struct Var *varPtr;		/* Pointer to array variable that's being
				 * searched. */
    Tcl_HashSearch search;	/* Info kept by the hash module about
				 * progress through the array. */
    Tcl_HashEntry *nextEntry;	/* Non-null means this is the next element
			 	 * to be enumerated (it's leftover from
				 * the Tcl_FirstHashEntry call or from
				 * an "array anymore" command).  NULL
				 * means must call Tcl_NextHashEntry
				 * to get value to return. */
    struct ArraySearch *nextPtr;/* Next in list of all active searches
				 * for this variable, or NULL if this is
				 * the last one. */
} ArraySearch;








|

|







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
				 * multiple concurrent searches for the
				 * same array. */
    struct Var *varPtr;		/* Pointer to array variable that's being
				 * searched. */
    Tcl_HashSearch search;	/* Info kept by the hash module about
				 * progress through the array. */
    Tcl_HashEntry *nextEntry;	/* Non-null means this is the next element
				 * to be enumerated (it's leftover from
				 * the Tcl_FirstHashEntry call or from
				 * an "array anymore" command).	 NULL
				 * means must call Tcl_NextHashEntry
				 * to get value to return. */
    struct ArraySearch *nextPtr;/* Next in list of all active searches
				 * for this variable, or NULL if this is
				 * the last one. */
} ArraySearch;

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
 * VAR_SCALAR -			1 means this is a scalar variable and not
 *				an array or link. The "objPtr" field points
 *				to the variable's value, a Tcl object.
 * VAR_ARRAY -			1 means this is an array variable rather
 *				than a scalar variable or link. The
 *				"tablePtr" field points to the array's
 *				hashtable for its elements.
 * VAR_LINK - 			1 means this Var structure contains a
 *				pointer to another Var structure that
 *				either has the real value or is itself
 *				another VAR_LINK pointer. Variables like
 *				this come about through "upvar" and "global"
 *				commands, or through references to variables
 *				in enclosing namespaces.
 * VAR_UNDEFINED -		1 means that the variable is in the process







|







380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
 * VAR_SCALAR -			1 means this is a scalar variable and not
 *				an array or link. The "objPtr" field points
 *				to the variable's value, a Tcl object.
 * VAR_ARRAY -			1 means this is an array variable rather
 *				than a scalar variable or link. The
 *				"tablePtr" field points to the array's
 *				hashtable for its elements.
 * VAR_LINK -			1 means this Var structure contains a
 *				pointer to another Var structure that
 *				either has the real value or is itself
 *				another VAR_LINK pointer. Variables like
 *				this come about through "upvar" and "global"
 *				commands, or through references to variables
 *				in enclosing namespaces.
 * VAR_UNDEFINED -		1 means that the variable is in the process
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
 *				as a namespace variable. This flag ensures
 *				it persists until its namespace is
 *				destroyed or until the variable is unset;
 *				it will persist even if it has not been
 *				initialized and is marked undefined.
 *				The variable's refCount is incremented to
 *				reflect the "reference" from its namespace.











 */

#define VAR_SCALAR		0x1
#define VAR_ARRAY		0x2
#define VAR_LINK		0x4
#define VAR_UNDEFINED	        0x8
#define VAR_IN_HASHTABLE	0x10
#define VAR_TRACE_ACTIVE	0x20
#define VAR_ARRAY_ELEMENT	0x40
#define VAR_NAMESPACE_VAR	0x80





/*
 * Macros to ensure that various flag bits are set properly for variables.
 * The ANSI C "prototypes" for these macros are:
 *
 * EXTERN void	TclSetVarScalar _ANSI_ARGS_((Var *varPtr));
 * EXTERN void	TclSetVarArray _ANSI_ARGS_((Var *varPtr));
 * EXTERN void	TclSetVarLink _ANSI_ARGS_((Var *varPtr));







>
>
>
>
>
>
>
>
>
>
>





|





>
>
>
>







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
 *				as a namespace variable. This flag ensures
 *				it persists until its namespace is
 *				destroyed or until the variable is unset;
 *				it will persist even if it has not been
 *				initialized and is marked undefined.
 *				The variable's refCount is incremented to
 *				reflect the "reference" from its namespace.
 *
 * The following additional flags are used with the CompiledLocal type
 * defined below:
 *
 * VAR_ARGUMENT -		1 means that this variable holds a procedure
 *				argument. 
 * VAR_TEMPORARY -		1 if the local variable is an anonymous
 *				temporary variable. Temporaries have a NULL
 *				name.
 * VAR_RESOLVED -		1 if name resolution has been done for this
 *				variable.
 */

#define VAR_SCALAR		0x1
#define VAR_ARRAY		0x2
#define VAR_LINK		0x4
#define VAR_UNDEFINED		0x8
#define VAR_IN_HASHTABLE	0x10
#define VAR_TRACE_ACTIVE	0x20
#define VAR_ARRAY_ELEMENT	0x40
#define VAR_NAMESPACE_VAR	0x80

#define VAR_ARGUMENT		0x100
#define VAR_TEMPORARY		0x200
#define VAR_RESOLVED		0x400	

/*
 * Macros to ensure that various flag bits are set properly for variables.
 * The ANSI C "prototypes" for these macros are:
 *
 * EXTERN void	TclSetVarScalar _ANSI_ARGS_((Var *varPtr));
 * EXTERN void	TclSetVarArray _ANSI_ARGS_((Var *varPtr));
 * EXTERN void	TclSetVarLink _ANSI_ARGS_((Var *varPtr));
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
 * The ANSI C "prototypes" for these macros are:
 *
 * EXTERN int	TclIsVarScalar _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarLink _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarArray _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarUndefined _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarArrayElement _ANSI_ARGS_((Var *varPtr));



 */
    
#define TclIsVarScalar(varPtr) \
    ((varPtr)->flags & VAR_SCALAR)

#define TclIsVarLink(varPtr) \
    ((varPtr)->flags & VAR_LINK)

#define TclIsVarArray(varPtr) \
    ((varPtr)->flags & VAR_ARRAY)

#define TclIsVarUndefined(varPtr) \
    ((varPtr)->flags & VAR_UNDEFINED)

#define TclIsVarArrayElement(varPtr) \
    ((varPtr)->flags & VAR_ARRAY_ELEMENT)










/*
 *----------------------------------------------------------------
 * Data structures related to procedures.  These are used primarily
 * in tclProc.c, tclCompile.c, and tclExecute.c.
 *----------------------------------------------------------------
 */








>
>
>

















>
>
>
>
>
>
>
>
>







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
 * The ANSI C "prototypes" for these macros are:
 *
 * EXTERN int	TclIsVarScalar _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarLink _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarArray _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarUndefined _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarArrayElement _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarTemporary _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarArgument _ANSI_ARGS_((Var *varPtr));
 * EXTERN int	TclIsVarResolved _ANSI_ARGS_((Var *varPtr));
 */
    
#define TclIsVarScalar(varPtr) \
    ((varPtr)->flags & VAR_SCALAR)

#define TclIsVarLink(varPtr) \
    ((varPtr)->flags & VAR_LINK)

#define TclIsVarArray(varPtr) \
    ((varPtr)->flags & VAR_ARRAY)

#define TclIsVarUndefined(varPtr) \
    ((varPtr)->flags & VAR_UNDEFINED)

#define TclIsVarArrayElement(varPtr) \
    ((varPtr)->flags & VAR_ARRAY_ELEMENT)

#define TclIsVarTemporary(varPtr) \
    ((varPtr)->flags & VAR_TEMPORARY)
    
#define TclIsVarArgument(varPtr) \
    ((varPtr)->flags & VAR_ARGUMENT)
    
#define TclIsVarResolved(varPtr) \
    ((varPtr)->flags & VAR_RESOLVED)

/*
 *----------------------------------------------------------------
 * Data structures related to procedures.  These are used primarily
 * in tclProc.c, tclCompile.c, and tclExecute.c.
 *----------------------------------------------------------------
 */

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
				 * for this procedure, or NULL if this is
				 * the last local. */
    int nameLength;		/* The number of characters in local
				 * variable's name. Used to speed up
				 * variable lookups. */
    int frameIndex;		/* Index in the array of compiler-assigned
				 * variables in the procedure call frame. */
    int isArg;			/* 1 if the local variable is a formal
				 * argument. */
    int isTemp;			/* 1 if the local variable is an anonymous
				 * temporary variable. Temporaries have
				 * a NULL name. */
    int flags;			/* Flag bits for the local variable. Same as
				 * the flags for the Var structure above,
				 * although only VAR_SCALAR, VAR_ARRAY, and

				 * VAR_LINK make sense. */
    Tcl_Obj *defValuePtr;	/* Pointer to the default value of an
				 * argument, if any. NULL if not an argument
				 * or, if an argument, no default value. */







    char name[4];		/* Name of the local variable starts here.
				 * If the name is NULL, this will just be
				 * '\0'. The actual size of this field will
				 * be large enough to hold the name. MUST
				 * BE THE LAST FIELD IN THE STRUCTURE! */
} CompiledLocal;








<
<
<
<
<


|
>
|



>
>
>
>
>
>
>







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
				 * for this procedure, or NULL if this is
				 * the last local. */
    int nameLength;		/* The number of characters in local
				 * variable's name. Used to speed up
				 * variable lookups. */
    int frameIndex;		/* Index in the array of compiler-assigned
				 * variables in the procedure call frame. */





    int flags;			/* Flag bits for the local variable. Same as
				 * the flags for the Var structure above,
				 * although only VAR_SCALAR, VAR_ARRAY, 
				 * VAR_LINK, VAR_ARGUMENT, VAR_TEMPORARY, and
				 * VAR_RESOLVED make sense. */
    Tcl_Obj *defValuePtr;	/* Pointer to the default value of an
				 * argument, if any. NULL if not an argument
				 * or, if an argument, no default value. */
    Tcl_ResolvedVarInfo *resolveInfo;
				/* Customized variable resolution info
				 * supplied by the Tcl_ResolveCompiledVarProc
				 * associated with a namespace. Each variable
				 * is marked by a unique ClientData tag
				 * during compilation, and that same tag
				 * is used to find the variable at runtime. */
    char name[4];		/* Name of the local variable starts here.
				 * If the name is NULL, this will just be
				 * '\0'. The actual size of this field will
				 * be large enough to hold the name. MUST
				 * BE THE LAST FIELD IN THE STRUCTURE! */
} CompiledLocal;

493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
				   * formal arguments. */
    CompiledLocal *lastLocalPtr;  /* Pointer to the last allocated local
				   * variable or NULL if none. This has
				   * frame index (numCompiledLocals-1). */
} Proc;

/*
 * The structure below defines a command trace.  This is used to allow Tcl
 * clients to find out whenever a command is about to be executed.
 */

typedef struct Trace {
    int level;			/* Only trace commands at nesting level
				 * less than or equal to this. */
    Tcl_CmdTraceProc *proc;	/* Procedure to call to trace command. */







|







603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
				   * formal arguments. */
    CompiledLocal *lastLocalPtr;  /* Pointer to the last allocated local
				   * variable or NULL if none. This has
				   * frame index (numCompiledLocals-1). */
} Proc;

/*
 * The structure below defines a command trace.	 This is used to allow Tcl
 * clients to find out whenever a command is about to be executed.
 */

typedef struct Trace {
    int level;			/* Only trace commands at nesting level
				 * less than or equal to this. */
    Tcl_CmdTraceProc *proc;	/* Procedure to call to trace command. */
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
 * function to call when the interpreter is deleted, and a pointer to
 * a user-defined piece of data.
 */

typedef struct AssocData {
    Tcl_InterpDeleteProc *proc;	/* Proc to call when deleting. */
    ClientData clientData;	/* Value to pass to proc. */
} AssocData;    

/*
 * The structure below defines a call frame. A call frame defines a naming
 * context for a procedure call: its local naming scope (for local
 * variables) and its global naming scope (a namespace, perhaps the global
 * :: namespace). A call frame can also define the naming context for a
 * namespace eval or namespace inscope command: the namespace in which the







|







625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
 * function to call when the interpreter is deleted, and a pointer to
 * a user-defined piece of data.
 */

typedef struct AssocData {
    Tcl_InterpDeleteProc *proc;	/* Proc to call when deleting. */
    ClientData clientData;	/* Value to pass to proc. */
} AssocData;	

/*
 * The structure below defines a call frame. A call frame defines a naming
 * context for a procedure call: its local naming scope (for local
 * variables) and its global naming scope (a namespace, perhaps the global
 * :: namespace). A call frame can also define the naming context for a
 * namespace eval or namespace inscope command: the namespace in which the
579
580
581
582
583
584
585















586
587
588
589
590
591
592
593
				 * recognized by the compiler. The compiler
				 * emits code that refers to these variables
				 * using an index into this array. */
} CallFrame;

/*
 *----------------------------------------------------------------















 * Data structures related to history.   These are used primarily
 * in tclHistory.c
 *----------------------------------------------------------------
 */

/*
 * The structure below defines one history event (a previously-executed
 * command that can be re-executed in whole or in part).







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







689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
				 * recognized by the compiler. The compiler
				 * emits code that refers to these variables
				 * using an index into this array. */
} CallFrame;

/*
 *----------------------------------------------------------------
 * Data structures and procedures related to TclHandles, which
 * are a very lightweight method of preserving enough information
 * to determine if an arbitrary malloc'd block has been deleted.
 *----------------------------------------------------------------
 */

typedef VOID **TclHandle;

TclHandle		TclHandleCreate _ANSI_ARGS_((VOID *ptr));
void			TclHandleFree _ANSI_ARGS_((TclHandle handle));
TclHandle		TclHandlePreserve _ANSI_ARGS_((TclHandle handle));
void			TclHandleRelease _ANSI_ARGS_((TclHandle handle)); 

/*
 *----------------------------------------------------------------
 * Data structures related to history.	 These are used primarily
 * in tclHistory.c
 *----------------------------------------------------------------
 */

/*
 * The structure below defines one history event (a previously-executed
 * command that can be re-executed in whole or in part).
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
    Tcl_MathProc *proc;		/* Procedure that implements this function.
				 * NULL if isBuiltinFunc is 1. */
    ClientData clientData;	/* Additional argument to pass to the
				 * function when invoking it. NULL if
				 * isBuiltinFunc is 1. */
} MathFunc;






















/*
 *----------------------------------------------------------------
 * Data structures related to bytecode compilation and execution.
 * These are used primarily in tclCompile.c, tclExecute.c, and
 * tclBasic.c.
 *----------------------------------------------------------------
 */

/*
 * Forward declaration to prevent an error when the forward reference to
 * CompileEnv is encountered in the procedure type CompileProc declared
 * below.
 */


struct CompileEnv;

/*
 * The type of procedures called by the Tcl bytecode compiler to compile
 * commands. Pointers to these procedures are kept in the Command structure
 * describing each command. When a CompileProc returns, the interpreter's
 * result is set to error information, if any. In addition, the CompileProc







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









|
|
|


>







771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
    Tcl_MathProc *proc;		/* Procedure that implements this function.
				 * NULL if isBuiltinFunc is 1. */
    ClientData clientData;	/* Additional argument to pass to the
				 * function when invoking it. NULL if
				 * isBuiltinFunc is 1. */
} MathFunc;

/*
 * These are a thin layer over TclpThreadKeyDataGet and TclpThreadKeyDataSet
 * when threads are used, or an emulation if there are no threads.  These
 * are really internal and Tcl clients should use Tcl_GetThreadData.
 */

EXTERN VOID *TclThreadDataKeyGet _ANSI_ARGS_((Tcl_ThreadDataKey *keyPtr));
EXTERN void TclThreadDataKeySet _ANSI_ARGS_((Tcl_ThreadDataKey *keyPtr, VOID *data));

/*
 * This is a convenience macro used to initialize a thread local storage ptr.
 */
#define TCL_TSD_INIT(keyPtr)	(ThreadSpecificData *)Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData))


#ifdef MAC_TCL
typedef pascal void *(Tcl_ThreadCreateProc) _ANSI_ARGS_((ClientData clientData));
#else
typedef void (Tcl_ThreadCreateProc) _ANSI_ARGS_((ClientData clientData));
#endif

/*
 *----------------------------------------------------------------
 * Data structures related to bytecode compilation and execution.
 * These are used primarily in tclCompile.c, tclExecute.c, and
 * tclBasic.c.
 *----------------------------------------------------------------
 */

/*
 * Forward declaration to prevent errors when the forward references to
 * Tcl_Parse and CompileEnv are encountered in the procedure type
 * CompileProc declared below.
 */

struct Tcl_Parse;
struct CompileEnv;

/*
 * The type of procedures called by the Tcl bytecode compiler to compile
 * commands. Pointers to these procedures are kept in the Command structure
 * describing each command. When a CompileProc returns, the interpreter's
 * result is set to error information, if any. In addition, the CompileProc
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714























































































715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741















742
743
744
745
746
747
748
 *			CompileProc believes the command is legal but 
 *			should be compiled "out of line" by emitting code
 *			to invoke its command procedure at runtime.
 */

#define TCL_OUT_LINE_COMPILE	(TCL_CONTINUE + 1)

typedef int (CompileProc) _ANSI_ARGS_((Tcl_Interp *interp, char *string,
	char *lastChar, int compileFlags, struct CompileEnv *compEnvPtr));

/*
 * The data structure defining the execution environment for ByteCode's.
 * There is one ExecEnv structure per Tcl interpreter. It holds the
 * evaluation stack that holds command operands and results. The stack grows
 * towards increasing addresses. The "stackTop" member is cached by
 * TclExecuteByteCode in a local variable: it must be set before calling
 * TclExecuteByteCode and will be restored by TclExecuteByteCode before it
 * returns.
 */

typedef union StackItem {
    Tcl_Obj *o;			/* Stack item as a pointer to a Tcl_Obj. */
    int      i;			/* Stack item as an integer. */
    VOID    *p;			/* Stack item as an arbitrary pointer. */
} StackItem;

typedef struct ExecEnv {
    StackItem *stackPtr;	/* Points to the first item in the
				 * evaluation stack on the heap. */
    int stackTop;		/* Index of current top of stack; -1 when
				 * the stack is empty. */
    int stackEnd;		/* Index of last usable item in stack. */
} ExecEnv;
























































































/*
 *----------------------------------------------------------------
 * Data structures related to commands.
 *----------------------------------------------------------------
 */

/*
 * An imported command is created in an namespace when it imports a "real"
 * command from another namespace. An imported command has a Command
 * structure that points (via its ClientData value) to the "real" Command
 * structure in the source namespace's command table. The real command
 * records all the imported commands that refer to it in a list of ImportRef
 * structures so that they can be deleted when the real command is deleted.  */

typedef struct ImportRef {
    struct Command *importedCmdPtr;
    				/* Points to the imported command created in
				 * an importing namespace; this command
				 * redirects its invocations to the "real"
				 * command. */
    struct ImportRef *nextPtr;	/* Next element on the linked list of
				 * imported commands that refer to the
				 * "real" command. The real command deletes
				 * these imported commands on this list when
				 * it is deleted. */
} ImportRef;
















/*
 * A Command structure exists for each command in a namespace. The
 * Tcl_Command opaque type actually refers to these structures.
 */

typedef struct Command {
    Tcl_HashEntry *hPtr;	/* Pointer to the hash table entry that







|
|











<
<
<
<
<
<

|






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
















|










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







828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847






848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
 *			CompileProc believes the command is legal but 
 *			should be compiled "out of line" by emitting code
 *			to invoke its command procedure at runtime.
 */

#define TCL_OUT_LINE_COMPILE	(TCL_CONTINUE + 1)

typedef int (CompileProc) _ANSI_ARGS_((Tcl_Interp *interp,
	struct Tcl_Parse *parsePtr, struct CompileEnv *compEnvPtr));

/*
 * The data structure defining the execution environment for ByteCode's.
 * There is one ExecEnv structure per Tcl interpreter. It holds the
 * evaluation stack that holds command operands and results. The stack grows
 * towards increasing addresses. The "stackTop" member is cached by
 * TclExecuteByteCode in a local variable: it must be set before calling
 * TclExecuteByteCode and will be restored by TclExecuteByteCode before it
 * returns.
 */







typedef struct ExecEnv {
    Tcl_Obj **stackPtr;		/* Points to the first item in the
				 * evaluation stack on the heap. */
    int stackTop;		/* Index of current top of stack; -1 when
				 * the stack is empty. */
    int stackEnd;		/* Index of last usable item in stack. */
} ExecEnv;

/*
 * The definitions for the LiteralTable and LiteralEntry structures. Each
 * interpreter contains a LiteralTable. It is used to reduce the storage
 * needed for all the Tcl objects that hold the literals of scripts compiled
 * by the interpreter. A literal's object is shared by all the ByteCodes
 * that refer to the literal. Each distinct literal has one LiteralEntry
 * entry in the LiteralTable. A literal table is a specialized hash table
 * that is indexed by the literal's string representation, which may contain
 * null characters.
 *
 * Note that we reduce the space needed for literals by sharing literal
 * objects both within a ByteCode (each ByteCode contains a local
 * LiteralTable) and across all an interpreter's ByteCodes (with the
 * interpreter's global LiteralTable).
 */

typedef struct LiteralEntry {
    struct LiteralEntry *nextPtr;	/* Points to next entry in this
					 * hash bucket or NULL if end of
					 * chain. */
    Tcl_Obj *objPtr;			/* Points to Tcl object that
					 * holds the literal's bytes and
					 * length. */
    int refCount;			/* If in an interpreter's global
					 * literal table, the number of
					 * ByteCode structures that share
					 * the literal object; the literal
					 * entry can be freed when refCount
					 * drops to 0. If in a local literal
					 * table, -1. */
} LiteralEntry;

typedef struct LiteralTable {
    LiteralEntry **buckets;		/* Pointer to bucket array. Each
					 * element points to first entry in
					 * bucket's hash chain, or NULL. */
    LiteralEntry *staticBuckets[TCL_SMALL_HASH_TABLE];
					/* Bucket array used for small
					 * tables to avoid mallocs and
					 * frees. */
    int numBuckets;			/* Total number of buckets allocated
					 * at **buckets. */
    int numEntries;			/* Total number of entries present
					 * in table. */
    int rebuildSize;			/* Enlarge table when numEntries
					 * gets to be this large. */
    int mask;				/* Mask value used in hashing
					 * function. */
} LiteralTable;

/*
 * The following structure defines for each Tcl interpreter various
 * statistics-related information about the bytecode compiler and
 * interpreter's operation in that interpreter.
 */

#ifdef TCL_COMPILE_STATS
typedef struct ByteCodeStats {
    long numExecutions;		  /* Number of ByteCodes executed. */
    long numCompilations;	  /* Number of ByteCodes created. */
    long numByteCodesFreed;	  /* Number of ByteCodes destroyed. */
    long instructionCount[256];	  /* Number of times each instruction was
				   * executed. */

    double totalSrcBytes;	  /* Total source bytes ever compiled. */
    double totalByteCodeBytes;	  /* Total bytes for all ByteCodes. */
    double currentSrcBytes;	  /* Src bytes for all current ByteCodes. */
    double currentByteCodeBytes;  /* Code bytes in all current ByteCodes. */

    long srcCount[32];		  /* Source size distribution: # of srcs of
				   * size [2**(n-1)..2**n), n in [0..32). */
    long byteCodeCount[32];	  /* ByteCode size distribution. */
    long lifetimeCount[32];	  /* ByteCode lifetime distribution (ms). */
    
    double currentInstBytes;	  /* Instruction bytes-current ByteCodes. */
    double currentLitBytes;	  /* Current literal bytes. */
    double currentExceptBytes;	  /* Current exception table bytes. */
    double currentAuxBytes;	  /* Current auxiliary information bytes. */
    double currentCmdMapBytes;	  /* Current src<->code map bytes. */
    
    long numLiteralsCreated;	  /* Total literal objects ever compiled. */
    double totalLitStringBytes;	  /* Total string bytes in all literals. */
    double currentLitStringBytes; /* String bytes in current literals. */
    long literalCount[32];	  /* Distribution of literal string sizes. */
} ByteCodeStats;
#endif /* TCL_COMPILE_STATS */

/*
 *----------------------------------------------------------------
 * Data structures related to commands.
 *----------------------------------------------------------------
 */

/*
 * An imported command is created in an namespace when it imports a "real"
 * command from another namespace. An imported command has a Command
 * structure that points (via its ClientData value) to the "real" Command
 * structure in the source namespace's command table. The real command
 * records all the imported commands that refer to it in a list of ImportRef
 * structures so that they can be deleted when the real command is deleted.  */

typedef struct ImportRef {
    struct Command *importedCmdPtr;
				/* Points to the imported command created in
				 * an importing namespace; this command
				 * redirects its invocations to the "real"
				 * command. */
    struct ImportRef *nextPtr;	/* Next element on the linked list of
				 * imported commands that refer to the
				 * "real" command. The real command deletes
				 * these imported commands on this list when
				 * it is deleted. */
} ImportRef;

/*
 * Data structure used as the ClientData of imported commands: commands
 * created in an namespace when it imports a "real" command from another
 * namespace.
 */

typedef struct ImportedCmdData {
    struct Command *realCmdPtr;	/* "Real" command that this imported command
				 * refers to. */
    struct Command *selfPtr;	/* Pointer to this imported command. Needed
				 * only when deleting it in order to remove
				 * it from the real command's linked list of
				 * imported commands that refer to it. */
} ImportedCmdData;

/*
 * A Command structure exists for each command in a namespace. The
 * Tcl_Command opaque type actually refers to these structures.
 */

typedef struct Command {
    Tcl_HashEntry *hPtr;	/* Pointer to the hash table entry that
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
    int refCount;		/* 1 if in command hashtable plus 1 for each
				 * reference from a CmdName Tcl object
				 * representing a command's name in a
				 * ByteCode instruction sequence. This
				 * structure can be freed when refCount
				 * becomes zero. */
    int cmdEpoch;		/* Incremented to invalidate any references
                                 * that point to this command when it is
				 * renamed, deleted, hidden, or exposed. */
    CompileProc *compileProc;   /* Procedure called to compile command. NULL
				 * if no compile proc exists for command. */
    Tcl_ObjCmdProc *objProc;	/* Object-based command procedure. */
    ClientData objClientData;	/* Arbitrary value passed to object proc. */
    Tcl_CmdProc *proc;		/* String-based command procedure. */
    ClientData clientData;	/* Arbitrary value passed to string proc. */
    Tcl_CmdDeleteProc *deleteProc;
				/* Procedure invoked when deleting command







|

|







1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
    int refCount;		/* 1 if in command hashtable plus 1 for each
				 * reference from a CmdName Tcl object
				 * representing a command's name in a
				 * ByteCode instruction sequence. This
				 * structure can be freed when refCount
				 * becomes zero. */
    int cmdEpoch;		/* Incremented to invalidate any references
				 * that point to this command when it is
				 * renamed, deleted, hidden, or exposed. */
    CompileProc *compileProc;	/* Procedure called to compile command. NULL
				 * if no compile proc exists for command. */
    Tcl_ObjCmdProc *objProc;	/* Object-based command procedure. */
    ClientData objClientData;	/* Arbitrary value passed to object proc. */
    Tcl_CmdProc *proc;		/* String-based command procedure. */
    ClientData clientData;	/* Arbitrary value passed to string proc. */
    Tcl_CmdDeleteProc *deleteProc;
				/* Procedure invoked when deleting command
785
786
787
788
789
790
791
































792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832



833



834


835
836







837
838
839
840


841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
				 * imported. These imported commands
				 * redirect invocations back to this
				 * command. The list is used to remove all
				 * those imported commands when deleting
				 * this "real" command. */
} Command;

































/*
 *----------------------------------------------------------------
 * This structure defines an interpreter, which is a collection of
 * commands plus other state information related to interpreting
 * commands, such as variable storage. Primary responsibility for
 * this data structure is in tclBasic.c, but almost every Tcl
 * source file uses something in here.
 *----------------------------------------------------------------
 */

typedef struct Interp {

    /*
     * Note:  the first three fields must match exactly the fields in
     * a Tcl_Interp struct (see tcl.h).  If you change one, be sure to
     * change the other.
     *
     * The interpreter's result is held in both the string and the
     * objResultPtr fields. These fields hold, respectively, the result's
     * string or object value. The interpreter's result is always in the
     * result field if that is non-empty, otherwise it is in objResultPtr.
     * The two fields are kept consistent unless some C code sets
     * interp->result directly. Programs should not access result and
     * objResultPtr directly; instead, they should always get and set the
     * result using procedures such as Tcl_SetObjResult, Tcl_GetObjResult,
     * and Tcl_GetStringResult. See the SetResult man page for details.
     */

    char *result;               /* If the last command returned a string
				 * result, this points to it. Should not be
				 * accessed directly; see comment above. */
    Tcl_FreeProc *freeProc;     /* Zero means a string result is statically
                                 * allocated. TCL_DYNAMIC means string
                                 * result was allocated with ckalloc and
                                 * should be freed with ckfree. Other values
                                 * give address of procedure to invoke to
                                 * free the string result. Tcl_Eval must
                                 * free it before executing next command. */
    int errorLine;		/* When TCL_ERROR is returned, this gives
				 * the line number in the command where the
				 * error occurred (1 means first line). */



    Tcl_Obj *objResultPtr;	/* If the last command returned an object



				 * result, this points to it. Should not be


				 * accessed directly; see comment above. */
    Namespace *globalNsPtr;     /* The interpreter's global namespace. */







    Tcl_HashTable mathFuncTable;/* Contains all the math functions currently
				 * defined for the interpreter.  Indexed by
				 * strings (function names); values have
				 * type (MathFunc *). */



    /*
     * Information related to procedures and variables. See tclProc.c
     * and tclvar.c for usage.
     */

    int numLevels;		/* Keeps track of how many nested calls to
				 * Tcl_Eval are in progress for this
				 * interpreter.  It's used to delay deletion
				 * of the table until all Tcl_Eval
				 * invocations are completed. */
    int maxNestingDepth;	/* If numLevels exceeds this value then Tcl
				 * assumes that infinite recursion has
				 * occurred and it generates an error. */
    CallFrame *framePtr;	/* Points to top-most in stack of all nested
				 * procedure invocations.  NULL means there







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














|













|


|
|
|
|
|
|
|



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

|


>
>








|







1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
				 * imported. These imported commands
				 * redirect invocations back to this
				 * command. The list is used to remove all
				 * those imported commands when deleting
				 * this "real" command. */
} Command;

/*
 *----------------------------------------------------------------
 * Data structures related to name resolution procedures.
 *----------------------------------------------------------------
 */

/*
 * The interpreter keeps a linked list of name resolution schemes.
 * The scheme for a namespace is consulted first, followed by the
 * list of schemes in an interpreter, followed by the default
 * name resolution in Tcl.  Schemes are added/removed from the
 * interpreter's list by calling Tcl_AddInterpResolver and
 * Tcl_RemoveInterpResolver.
 */

typedef struct ResolverScheme {
    char *name;			/* Name identifying this scheme. */
    Tcl_ResolveCmdProc *cmdResProc;
				/* Procedure handling command name
				 * resolution. */
    Tcl_ResolveVarProc *varResProc;
				/* Procedure handling variable name
				 * resolution for variables that
				 * can only be handled at runtime. */
    Tcl_ResolveCompiledVarProc *compiledVarResProc;
				/* Procedure handling variable name
				 * resolution at compile time. */

    struct ResolverScheme *nextPtr;
				/* Pointer to next record in linked list. */
} ResolverScheme;

/*
 *----------------------------------------------------------------
 * This structure defines an interpreter, which is a collection of
 * commands plus other state information related to interpreting
 * commands, such as variable storage. Primary responsibility for
 * this data structure is in tclBasic.c, but almost every Tcl
 * source file uses something in here.
 *----------------------------------------------------------------
 */

typedef struct Interp {

    /*
     * Note:  the first three fields must match exactly the fields in
     * a Tcl_Interp struct (see tcl.h).	 If you change one, be sure to
     * change the other.
     *
     * The interpreter's result is held in both the string and the
     * objResultPtr fields. These fields hold, respectively, the result's
     * string or object value. The interpreter's result is always in the
     * result field if that is non-empty, otherwise it is in objResultPtr.
     * The two fields are kept consistent unless some C code sets
     * interp->result directly. Programs should not access result and
     * objResultPtr directly; instead, they should always get and set the
     * result using procedures such as Tcl_SetObjResult, Tcl_GetObjResult,
     * and Tcl_GetStringResult. See the SetResult man page for details.
     */

    char *result;		/* If the last command returned a string
				 * result, this points to it. Should not be
				 * accessed directly; see comment above. */
    Tcl_FreeProc *freeProc;	/* Zero means a string result is statically
				 * allocated. TCL_DYNAMIC means string
				 * result was allocated with ckalloc and
				 * should be freed with ckfree. Other values
				 * give address of procedure to invoke to
				 * free the string result. Tcl_Eval must
				 * free it before executing next command. */
    int errorLine;		/* When TCL_ERROR is returned, this gives
				 * the line number in the command where the
				 * error occurred (1 means first line). */
    struct TclStubs *stubTable;
				/* Pointer to the exported Tcl stub table.
				 * On previous versions of Tcl this is a
				 * pointer to the objResultPtr or a pointer
				 * to a buckets array in a hash table. We
				 * therefore have to do some careful checking
				 * before we can use this. */

    TclHandle handle;		/* Handle used to keep track of when this
				 * interp is deleted. */

    Namespace *globalNsPtr;	/* The interpreter's global namespace. */
    Tcl_HashTable *hiddenCmdTablePtr;
				/* Hash table used by tclBasic.c to keep
				 * track of hidden commands on a per-interp
				 * basis. */
    ClientData interpInfo;	/* Information used by tclInterp.c to keep
				 * track of master/slave interps on
				 * a per-interp basis. */
    Tcl_HashTable mathFuncTable;/* Contains all the math functions currently
				 * defined for the interpreter.	 Indexed by
				 * strings (function names); values have
				 * type (MathFunc *). */



    /*
     * Information related to procedures and variables. See tclProc.c
     * and tclvar.c for usage.
     */

    int numLevels;		/* Keeps track of how many nested calls to
				 * Tcl_Eval are in progress for this
				 * interpreter.	 It's used to delay deletion
				 * of the table until all Tcl_Eval
				 * invocations are completed. */
    int maxNestingDepth;	/* If numLevels exceeds this value then Tcl
				 * assumes that infinite recursion has
				 * occurred and it generates an error. */
    CallFrame *framePtr;	/* Points to top-most in stack of all nested
				 * procedure invocations.  NULL means there
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888



889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
    char *errorInfo;		/* Value to store in errorInfo if returnCode
				 * is TCL_ERROR.  Malloc'ed, may be NULL */
    char *errorCode;		/* Value to store in errorCode if returnCode
				 * is TCL_ERROR.  Malloc'ed, may be NULL */

    /*
     * Information used by Tcl_AppendResult to keep track of partial
     * results.  See Tcl_AppendResult code for details.
     */

    char *appendResult;		/* Storage space for results generated
				 * by Tcl_AppendResult.  Malloc-ed.  NULL
				 * means not yet allocated. */
    int appendAvl;		/* Total amount of space available at
				 * partialResult. */
    int appendUsed;		/* Number of non-null bytes currently
				 * stored at partialResult. */

    /*
     * A cache of compiled regular expressions.  See Tcl_RegExpCompile
     * in tclUtil.c for details.



     */

#define NUM_REGEXPS 5
    char *patterns[NUM_REGEXPS];/* Strings corresponding to compiled
				 * regular expression patterns.  NULL
				 * means that this slot isn't used.
				 * Malloc-ed. */
    int patLengths[NUM_REGEXPS];/* Number of non-null characters in
				 * corresponding entry in patterns.
				 * -1 means entry isn't used. */
    regexp *regexps[NUM_REGEXPS];
				/* Compiled forms of above strings.  Also
				 * malloc-ed, or NULL if not in use yet. */

    /*
     * Information about packages.  Used only in tclPkg.c.
     */








|



|







|
|
>
>
>




|





|







1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
    char *errorInfo;		/* Value to store in errorInfo if returnCode
				 * is TCL_ERROR.  Malloc'ed, may be NULL */
    char *errorCode;		/* Value to store in errorCode if returnCode
				 * is TCL_ERROR.  Malloc'ed, may be NULL */

    /*
     * Information used by Tcl_AppendResult to keep track of partial
     * results.	 See Tcl_AppendResult code for details.
     */

    char *appendResult;		/* Storage space for results generated
				 * by Tcl_AppendResult.	 Malloc-ed.  NULL
				 * means not yet allocated. */
    int appendAvl;		/* Total amount of space available at
				 * partialResult. */
    int appendUsed;		/* Number of non-null bytes currently
				 * stored at partialResult. */

    /*
     * A cache of compiled regular expressions.	 See Tcl_RegExpCompile
     * in tclUtil.c for details.  THIS CACHE IS OBSOLETE and is only
     * retained for backward compatibility with Tcl_RegExpCompile.
     * New code should use the object interface so the Tcl_Obj caches
     * the compiled expression.
     */

#define NUM_REGEXPS 5
    char *patterns[NUM_REGEXPS];/* Strings corresponding to compiled
				 * regular expression patterns.	 NULL
				 * means that this slot isn't used.
				 * Malloc-ed. */
    int patLengths[NUM_REGEXPS];/* Number of non-null characters in
				 * corresponding entry in patterns.
				 * -1 means entry isn't used. */
    struct TclRegexp *regexps[NUM_REGEXPS];
				/* Compiled forms of above strings.  Also
				 * malloc-ed, or NULL if not in use yet. */

    /*
     * Information about packages.  Used only in tclPkg.c.
     */

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
				 * has been called for this interpreter. */
    int evalFlags;		/* Flags to control next call to Tcl_Eval.
				 * Normally zero, but may be set before
				 * calling Tcl_Eval.  See below for valid
				 * values. */
    int termOffset;		/* Offset of character just after last one
				 * compiled or executed by Tcl_EvalObj. */






    int compileEpoch;		/* Holds the current "compilation epoch"
				 * for this interpreter. This is
				 * incremented to invalidate existing
				 * ByteCodes when, e.g., a command with a
				 * compile procedure is redefined. */
    Proc *compiledProcPtr;	/* If a procedure is being compiled, a
				 * pointer to its Proc structure; otherwise,
				 * this is NULL. Set by ObjInterpProc in
				 * tclProc.c and used by tclCompile.c to
				 * process local variables appropriately. */






    char *scriptFile;		/* NULL means there is no nested source
				 * command active;  otherwise this points to
				 * the name of the file being sourced (it's
				 * not malloc-ed:  it points to an argument
				 * to Tcl_EvalFile. */
    int flags;			/* Various flag bits.  See below. */
    long randSeed;		/* Seed used for rand() function. */
    Trace *tracePtr;		/* List of traces for this interpreter. */
    Tcl_HashTable *assocData;	/* Hash table for associating data with
                                 * this interpreter. Cleaned up when
                                 * this interpreter is deleted. */
    struct ExecEnv *execEnvPtr;	/* Execution environment for Tcl bytecode
                                 * execution. Contains a pointer to the
				 * Tcl evaluation stack. */
    Tcl_Obj *emptyObjPtr;	/* Points to an object holding an empty
				 * string. Returned by Tcl_ObjSetVar2 when
				 * variable traces change a variable in a
				 * gross way. */
    char resultSpace[TCL_RESULT_SIZE+1];
				/* Static space holding small results. */














} Interp;

/*
 * EvalFlag bits for Interp structures:
 *
 * TCL_BRACKET_TERM	1 means that the current script is terminated by
 *			a close bracket rather than the end of the string.
 * TCL_ALLOW_EXCEPTIONS	1 means it's OK for the script to terminate with
 *			a code other than TCL_OK or TCL_ERROR;  0 means
 *			codes other than these should be turned into errors.
 */

#define TCL_BRACKET_TERM	  1
#define TCL_ALLOW_EXCEPTIONS	  4

/*







>
>
>
>
>
>










>
>
>
>
>
>









|
|

|







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








|







1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
				 * has been called for this interpreter. */
    int evalFlags;		/* Flags to control next call to Tcl_Eval.
				 * Normally zero, but may be set before
				 * calling Tcl_Eval.  See below for valid
				 * values. */
    int termOffset;		/* Offset of character just after last one
				 * compiled or executed by Tcl_EvalObj. */
    LiteralTable literalTable;	/* Contains LiteralEntry's describing all
				 * Tcl objects holding literals of scripts
				 * compiled by the interpreter. Indexed by
				 * the string representations of literals.
				 * Used to avoid creating duplicate
				 * objects. */
    int compileEpoch;		/* Holds the current "compilation epoch"
				 * for this interpreter. This is
				 * incremented to invalidate existing
				 * ByteCodes when, e.g., a command with a
				 * compile procedure is redefined. */
    Proc *compiledProcPtr;	/* If a procedure is being compiled, a
				 * pointer to its Proc structure; otherwise,
				 * this is NULL. Set by ObjInterpProc in
				 * tclProc.c and used by tclCompile.c to
				 * process local variables appropriately. */
    ResolverScheme *resolverPtr;
				/* Linked list of name resolution schemes
				 * added to this interpreter.  Schemes
				 * are added/removed by calling
				 * Tcl_AddInterpResolvers and
				 * Tcl_RemoveInterpResolver. */
    char *scriptFile;		/* NULL means there is no nested source
				 * command active;  otherwise this points to
				 * the name of the file being sourced (it's
				 * not malloc-ed:  it points to an argument
				 * to Tcl_EvalFile. */
    int flags;			/* Various flag bits.  See below. */
    long randSeed;		/* Seed used for rand() function. */
    Trace *tracePtr;		/* List of traces for this interpreter. */
    Tcl_HashTable *assocData;	/* Hash table for associating data with
				 * this interpreter. Cleaned up when
				 * this interpreter is deleted. */
    struct ExecEnv *execEnvPtr;	/* Execution environment for Tcl bytecode
				 * execution. Contains a pointer to the
				 * Tcl evaluation stack. */
    Tcl_Obj *emptyObjPtr;	/* Points to an object holding an empty
				 * string. Returned by Tcl_ObjSetVar2 when
				 * variable traces change a variable in a
				 * gross way. */
    char resultSpace[TCL_RESULT_SIZE+1];
				/* Static space holding small results. */
    Tcl_Obj *objResultPtr;	/* If the last command returned an object
				 * result, this points to it. Should not be
				 * accessed directly; see comment above. */
    Tcl_ThreadId threadId;	/* ID of thread that owns the interpreter */

    /*
     * Statistical information about the bytecode compiler and interpreter's
     * operation.
     */

#ifdef TCL_COMPILE_STATS
    ByteCodeStats stats;	/* Holds compilation and execution
				 * statistics for this interpreter. */
#endif /* TCL_COMPILE_STATS */	  
} Interp;

/*
 * EvalFlag bits for Interp structures:
 *
 * TCL_BRACKET_TERM	1 means that the current script is terminated by
 *			a close bracket rather than the end of the string.
 * TCL_ALLOW_EXCEPTIONS	1 means it's OK for the script to terminate with
 *			a code other than TCL_OK or TCL_ERROR;	0 means
 *			codes other than these should be turned into errors.
 */

#define TCL_BRACKET_TERM	  1
#define TCL_ALLOW_EXCEPTIONS	  4

/*
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
 *			invoked since last error occured.
 * ERR_ALREADY_LOGGED:	Non-zero means information has already been logged
 *			in $errorInfo for the current Tcl_Eval instance,
 *			so Tcl_Eval needn't log it (used to implement the
 *			"error message log" command).
 * ERROR_CODE_SET:	Non-zero means that Tcl_SetErrorCode has been
 *			called to record information for the current
 *			error.  Zero means Tcl_Eval must clear the
 *			errorCode variable if an error is returned.
 * EXPR_INITIALIZED:	Non-zero means initialization specific to
 *			expressions has	been carried out.
 * DONT_COMPILE_CMDS_INLINE: Non-zero means that the bytecode compiler
 *			should not compile any commands into an inline
 *			sequence of instructions. This is set 1, for
 *			example, when command traces are requested.
 * RAND_SEED_INITIALIZED: Non-zero means that the randSeed value of the
 *			interp has not be initialized.  This is set 1
 *			when we first use the rand() or srand() functions.
 * SAFE_INTERP:         Non zero means that the current interp is a
 *                      safe interp (ie it has only the safe commands
 *                      installed, less priviledge than a regular interp).




 */

#define DELETED			 1
#define ERR_IN_PROGRESS		 2
#define ERR_ALREADY_LOGGED	 4
#define ERROR_CODE_SET		 8
#define EXPR_INITIALIZED	 0x10
#define DONT_COMPILE_CMDS_INLINE 0x20
#define RAND_SEED_INITIALIZED	 0x40
#define SAFE_INTERP              0x80


/*
 *----------------------------------------------------------------
 * Data structures related to command parsing. These are used in
 * tclParse.c and its clients.
 *----------------------------------------------------------------
 */







|








|

|
|
|
>
>
>
>


|
|
|
|
|
|
|
|
>







1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
 *			invoked since last error occured.
 * ERR_ALREADY_LOGGED:	Non-zero means information has already been logged
 *			in $errorInfo for the current Tcl_Eval instance,
 *			so Tcl_Eval needn't log it (used to implement the
 *			"error message log" command).
 * ERROR_CODE_SET:	Non-zero means that Tcl_SetErrorCode has been
 *			called to record information for the current
 *			error.	Zero means Tcl_Eval must clear the
 *			errorCode variable if an error is returned.
 * EXPR_INITIALIZED:	Non-zero means initialization specific to
 *			expressions has	been carried out.
 * DONT_COMPILE_CMDS_INLINE: Non-zero means that the bytecode compiler
 *			should not compile any commands into an inline
 *			sequence of instructions. This is set 1, for
 *			example, when command traces are requested.
 * RAND_SEED_INITIALIZED: Non-zero means that the randSeed value of the
 *			interp has not be initialized.	This is set 1
 *			when we first use the rand() or srand() functions.
 * SAFE_INTERP:		Non zero means that the current interp is a
 *			safe interp (ie it has only the safe commands
 *			installed, less priviledge than a regular interp).
 * USE_EVAL_DIRECT:	Non-zero means don't use the compiler or byte-code
 *			interpreter; instead, have Tcl_EvalObj call
 *			Tcl_EvalEx. Used primarily for testing the
 *			new parser.
 */

#define DELETED				    1
#define ERR_IN_PROGRESS			    2
#define ERR_ALREADY_LOGGED		    4
#define ERROR_CODE_SET			    8
#define EXPR_INITIALIZED		 0x10
#define DONT_COMPILE_CMDS_INLINE	 0x20
#define RAND_SEED_INITIALIZED		 0x40
#define SAFE_INTERP			 0x80
#define USE_EVAL_DIRECT			0x100

/*
 *----------------------------------------------------------------
 * Data structures related to command parsing. These are used in
 * tclParse.c and its clients.
 *----------------------------------------------------------------
 */
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
    void (*expandProc) _ANSI_ARGS_((struct ParseValue *pvPtr, int needed));
				/* Procedure to call when space runs out;
				 * it will make more space. */
    ClientData clientData;	/* Arbitrary information for use of
				 * expandProc. */
} ParseValue;

/*
 * A table used to classify input characters to assist in parsing
 * Tcl commands.  The table should be indexed with a signed character
 * using the CHAR_TYPE macro.  The character may have a negative
 * value.  The CHAR_TYPE macro takes a pointer to a signed character
 * and a pointer to the last character in the source string.  If the
 * src pointer is pointing at the terminating null of the string,
 * CHAR_TYPE returns TCL_COMMAND_END.
 */

extern unsigned char tclTypeTable[];
#define CHAR_TYPE(src,last) \
	(((src)==(last))?TCL_COMMAND_END:(tclTypeTable+128)[*(src)])

/*
 * Possible values returned by CHAR_TYPE. Note that except for TCL_DOLLAR,
 * these are all one byte values with a single bit set 1. This means these
 * values may be bit-or'ed together (except for TCL_DOLLAR) to quickly test
 * whether a character is one of several different kinds of characters.
 *
 * TCL_NORMAL -		All characters that don't have special significance
 *			to the Tcl language.
 * TCL_SPACE -		Character is space, tab, or return.
 * TCL_COMMAND_END -	Character is newline or semicolon or close-bracket
 *			or terminating null.
 * TCL_QUOTE -		Character is a double-quote.
 * TCL_OPEN_BRACKET -	Character is a "[".
 * TCL_OPEN_BRACE -	Character is a "{".
 * TCL_CLOSE_BRACE -	Character is a "}".
 * TCL_BACKSLASH -	Character is a "\".
 * TCL_DOLLAR - 	Character is a "$".
 */

#define TCL_NORMAL		0x01
#define TCL_SPACE		0x02
#define TCL_COMMAND_END		0x04
#define TCL_QUOTE		0x08
#define TCL_OPEN_BRACKET	0x10
#define TCL_OPEN_BRACE		0x20
#define TCL_CLOSE_BRACE		0x40
#define TCL_BACKSLASH		0x80
#define TCL_DOLLAR		0x00

/*
 * Maximum number of levels of nesting permitted in Tcl commands (used
 * to catch infinite recursion).
 */

#define MAX_NESTING_DEPTH	1000







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







1363
1364
1365
1366
1367
1368
1369










































1370
1371
1372
1373
1374
1375
1376
    void (*expandProc) _ANSI_ARGS_((struct ParseValue *pvPtr, int needed));
				/* Procedure to call when space runs out;
				 * it will make more space. */
    ClientData clientData;	/* Arbitrary information for use of
				 * expandProc. */
} ParseValue;












































/*
 * Maximum number of levels of nesting permitted in Tcl commands (used
 * to catch infinite recursion).
 */

#define MAX_NESTING_DEPTH	1000
1130
1131
1132
1133
1134
1135
1136




1137
1138
1139
1140

1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183

























1184
1185
1186
1187
1188
1189
1190
1191
1192


1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203

1204
1205
1206
1207

1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237



1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286

1287




1288
1289



1290



1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315

1316
1317
1318
1319
1320
1321
1322
1323
1324
1325

1326
1327
1328
1329
1330
1331

1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350







1351
1352


1353
1354
1355
1356
1357
1358
1359
1360


1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376

1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390


1391

1392
1393
1394
1395
1396
1397
1398

1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409

1410
1411
1412
1413



1414
1415

1416
1417
1418




1419


1420


1421




1422
1423

1424
1425

1426
1427
1428
1429
1430
1431

1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455

1456
1457
















1458
1459
1460
1461
1462
1463
1464
1465
1466

1467
1468
1469

1470
1471
1472
1473
1474




1475
1476
1477
1478
1479
1480


1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512


1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
 * TCL_INVOKE_HIDDEN		Invoke a hidden command; if not set,
 *				invokes an exposed command.
 * TCL_INVOKE_NO_UNKNOWN	If set, "unknown" is not invoked if
 *				the command to be invoked is not found.
 *				Only has an effect if invoking an exposed
 *				command, i.e. if TCL_INVOKE_HIDDEN is not
 *				also set.




 */

#define	TCL_INVOKE_HIDDEN	(1<<0)
#define TCL_INVOKE_NO_UNKNOWN	(1<<1)


/*
 * The structure used as the internal representation of Tcl list
 * objects. This is an array of pointers to the element objects. This array
 * is grown (reallocated and copied) as necessary to hold all the list's
 * element pointers. The array might contain more slots than currently used
 * to hold all element pointers. This is done to make append operations
 * faster.
 */

typedef struct List {
    int maxElemCount;		/* Total number of element array slots. */
    int elemCount;		/* Current number of list elements. */
    Tcl_Obj **elements;		/* Array of pointers to element objects. */
} List;


/*
 * The following types are used for getting and storing platform-specific
 * file attributes in tclFCmd.c and the various platform-versions of
 * that file. This is done to have as much common code as possible
 * in the file attributes code. For more information about the callbacks,
 * see TclFileAttrsCmd in tclFCmd.c.
 */

typedef int (TclGetFileAttrProc) _ANSI_ARGS_((Tcl_Interp *interp,
	int objIndex, char *fileName, 
	Tcl_Obj **attrObjPtrPtr));
typedef int (TclSetFileAttrProc) _ANSI_ARGS_((Tcl_Interp *interp,
	int objIndex, char *fileName, 
	Tcl_Obj *attrObjPtr));

typedef struct TclFileAttrProcs {
    TclGetFileAttrProc *getProc; 	/* The procedure for getting attrs. */
    TclSetFileAttrProc *setProc;	/* The procedure for setting attrs. */
} TclFileAttrProcs;

/*
 * Opaque handle used in pipeline routines to encapsulate platform-dependent
 * state. 
 */

typedef struct TclFile_ *TclFile;
    

























/*
 *----------------------------------------------------------------
 * Variables shared among Tcl modules but not used by the outside world.
 *----------------------------------------------------------------
 */

extern Tcl_Time			tclBlockTime;
extern int			tclBlockTimeSet;
extern char *			tclExecutableName;


extern Tcl_ChannelType	 	tclFileChannelType;
extern char *			tclMemDumpFileName;
extern TclPlatformType		tclPlatform;
extern char *			tclpFileAttrStrings[];
extern CONST TclFileAttrProcs   tclpFileAttrProcs[];

/*
 * Variables denoting the Tcl object types defined in the core.
 */

extern Tcl_ObjType	tclBooleanType;

extern Tcl_ObjType	tclByteCodeType;
extern Tcl_ObjType	tclDoubleType;
extern Tcl_ObjType	tclIntType;
extern Tcl_ObjType	tclListType;

extern Tcl_ObjType	tclStringType;

/*
 * The head of the list of free Tcl objects, and the total number of Tcl
 * objects ever allocated and freed.
 */

extern Tcl_Obj *	tclFreeObjList;

#ifdef TCL_COMPILE_STATS
extern long 		tclObjsAlloced;
extern long 		tclObjsFreed;
#endif /* TCL_COMPILE_STATS */

/*
 * Pointer to a heap-allocated string of length zero that the Tcl core uses
 * as the value of an empty string representation for an object. This value
 * is shared by all new objects allocated by Tcl_NewObj.
 */

extern char *		tclEmptyStringRep;

/*
 *----------------------------------------------------------------
 * Procedures shared among Tcl modules but not used by the outside
 * world:
 *----------------------------------------------------------------
 */

EXTERN void		panic _ANSI_ARGS_(TCL_VARARGS(char *,format));



EXTERN void		TclAllocateFreeObjects _ANSI_ARGS_((void));
EXTERN int		TclChdir _ANSI_ARGS_((Tcl_Interp *interp,
			    char *dirName));
EXTERN int		TclCleanupChildren _ANSI_ARGS_((Tcl_Interp *interp,
		            int numPids, Tcl_Pid *pidPtr,
			    Tcl_Channel errorChan));
EXTERN void		TclCleanupCommand _ANSI_ARGS_((Command *cmdPtr));
EXTERN char *		TclConvertToNative _ANSI_ARGS_((Tcl_Interp *interp,
			    char *name, Tcl_DString *bufferPtr));
EXTERN char *		TclConvertToNetwork _ANSI_ARGS_((Tcl_Interp *interp,
			    char *name, Tcl_DString *bufferPtr));
EXTERN int		TclCopyAndCollapse _ANSI_ARGS_((int count,
			    char *src, char *dst));
EXTERN int		TclCopyChannel _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Channel inChan, Tcl_Channel outChan,
			    int toRead, Tcl_Obj *cmdPtr));
/*
 * TclCreatePipeline unofficially exported for use by BLT.
 */
EXTERN int		TclCreatePipeline _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv, Tcl_Pid **pidArrayPtr,
			    TclFile *inPipePtr, TclFile *outPipePtr,
			    TclFile *errFilePtr));
EXTERN int		TclCreateProc _ANSI_ARGS_((Tcl_Interp *interp,
			    Namespace *nsPtr, char *procName,
			    Tcl_Obj *argsPtr, Tcl_Obj *bodyPtr,
			    Proc **procPtrPtr));
EXTERN void		TclDeleteCompiledLocalVars _ANSI_ARGS_((
    			    Interp *iPtr, CallFrame *framePtr));
EXTERN void		TclDeleteVars _ANSI_ARGS_((Interp *iPtr,
			    Tcl_HashTable *tablePtr));
EXTERN int		TclDoGlob _ANSI_ARGS_((Tcl_Interp *interp,
			    char *separators, Tcl_DString *headPtr,
			    char *tail));
EXTERN void		TclDumpMemoryInfo _ANSI_ARGS_((FILE *outFile));
EXTERN void		TclExpandParseValue _ANSI_ARGS_((ParseValue *pvPtr,
			    int needed));
EXTERN void		TclExprFloatError _ANSI_ARGS_((Tcl_Interp *interp,
			    double value));
EXTERN int		TclFileAttrsCmd _ANSI_ARGS_((Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[]));
EXTERN int		TclFileCopyCmd _ANSI_ARGS_((Tcl_Interp *interp, 
			    int argc, char **argv)) ;
EXTERN int 		TclFileDeleteCmd _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv));
EXTERN int		TclFileMakeDirsCmd _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv)) ;
EXTERN int		TclFileRenameCmd _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv)) ;

EXTERN void		TclFinalizeCompExecEnv _ANSI_ARGS_((void));




EXTERN void		TclFinalizeEnvironment _ANSI_ARGS_((void));
EXTERN void		TclFinalizeExecEnv _ANSI_ARGS_((void));



EXTERN int		TclFindElement _ANSI_ARGS_((Tcl_Interp *interp,



			    char *list, int listLength, char **elementPtr,
			    char **nextPtr, int *sizePtr, int *bracePtr));
EXTERN Proc *		TclFindProc _ANSI_ARGS_((Interp *iPtr,
			    char *procName));
EXTERN int		TclFormatInt _ANSI_ARGS_((char *buffer, long n));
EXTERN void		TclFreePackageInfo _ANSI_ARGS_((Interp *iPtr));
EXTERN void		TclGetAndDetachPids _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Channel chan));
EXTERN char *		TclGetCwd _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		TclGetDate _ANSI_ARGS_((char *p,
			    unsigned long now, long zone,
			    unsigned long *timePtr));
EXTERN Tcl_Channel	TclGetDefaultStdChannel _ANSI_ARGS_((int type));
EXTERN Tcl_Obj *	TclGetElementOfIndexedArray _ANSI_ARGS_((
                            Tcl_Interp *interp, int localIndex,
			    Tcl_Obj *elemPtr, int leaveErrorMsg));
EXTERN char *		TclGetEnv _ANSI_ARGS_((CONST char *name));
EXTERN char *		TclGetExtension _ANSI_ARGS_((char *name));
EXTERN int		TclGetFrame _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, CallFrame **framePtrPtr));
EXTERN int		TclGetIdleGeneration _ANSI_ARGS_((void));
EXTERN int		TclGetIntForIndex _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, int endValue, int *indexPtr));
EXTERN Tcl_Obj *	TclGetIndexedScalar _ANSI_ARGS_((Tcl_Interp *interp,
			    int localIndex, int leaveErrorMsg));

EXTERN int		TclGetLong _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, long *longPtr));
EXTERN int		TclGetLoadedPackages _ANSI_ARGS_((
			    Tcl_Interp *interp, char *targetName));
EXTERN int		TclGetNamespaceForQualName _ANSI_ARGS_((
			    Tcl_Interp *interp, char *qualName,
			    Namespace *cxtNsPtr, int flags,
			    Namespace **nsPtrPtr, Namespace **altNsPtrPtr,
			    Namespace **actualCxtPtrPtr,
			    char **simpleNamePtr));

EXTERN int		TclGetOpenMode _ANSI_ARGS_((Tcl_Interp *interp,
        		    char *string, int *seekFlagPtr));
EXTERN Tcl_Command	TclGetOriginalCommand _ANSI_ARGS_((
			    Tcl_Command command));
EXTERN char *		TclGetUserHome _ANSI_ARGS_((char *name,
			    Tcl_DString *bufferPtr));

EXTERN int		TclGlobalInvoke _ANSI_ARGS_((Tcl_Interp *interp,
		            int argc, char **argv, int flags));
EXTERN int		TclGuessPackageName _ANSI_ARGS_((char *fileName,
			    Tcl_DString *bufPtr));
EXTERN int              TclHasPipes _ANSI_ARGS_((void));
EXTERN int		TclHasSockets _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		TclHideUnsafeCommands _ANSI_ARGS_((
    			    Tcl_Interp *interp));
EXTERN int		TclIdlePending _ANSI_ARGS_((void));
EXTERN int		TclInExit _ANSI_ARGS_((void));
EXTERN Tcl_Obj *	TclIncrElementOfIndexedArray _ANSI_ARGS_((
                            Tcl_Interp *interp, int localIndex,
			    Tcl_Obj *elemPtr, long incrAmount));
EXTERN Tcl_Obj *	TclIncrIndexedScalar _ANSI_ARGS_((
                            Tcl_Interp *interp, int localIndex,
			    long incrAmount));
EXTERN Tcl_Obj *	TclIncrVar2 _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr,
			    long incrAmount, int part1NotParsed));







EXTERN void		TclInitNamespaces _ANSI_ARGS_((void));
EXTERN int		TclInterpInit _ANSI_ARGS_((Tcl_Interp *interp));


EXTERN int		TclInvoke _ANSI_ARGS_((Tcl_Interp *interp,
		            int argc, char **argv, int flags));
EXTERN int		TclInvokeObjectCommand _ANSI_ARGS_((
                            ClientData clientData, Tcl_Interp *interp,
                            int argc, char **argv));
EXTERN int		TclInvokeStringCommand _ANSI_ARGS_((
                            ClientData clientData, Tcl_Interp *interp,
                            int objc, Tcl_Obj *CONST objv[]));


EXTERN Proc *		TclIsProc _ANSI_ARGS_((Command *cmdPtr));
EXTERN int		TclLoadFile _ANSI_ARGS_((Tcl_Interp *interp,
			    char *fileName, char *sym1, char *sym2,
			    Tcl_PackageInitProc **proc1Ptr,
			    Tcl_PackageInitProc **proc2Ptr));
EXTERN int		TclLooksLikeInt _ANSI_ARGS_((char *p));
EXTERN Var *		TclLookupVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *part1, char *part2, int flags, char *msg,
			    int createPart1, int createPart2,
			    Var **arrayPtrPtr));
EXTERN int		TclMakeFileTable _ANSI_ARGS_((Tcl_Interp *interp,
                            int noStdio));
EXTERN int		TclMatchFiles _ANSI_ARGS_((Tcl_Interp *interp,
			    char *separators, Tcl_DString *dirPtr,
			    char *pattern, char *tail));
EXTERN int		TclNeedSpace _ANSI_ARGS_((char *start, char *end));

EXTERN int		TclObjCommandComplete _ANSI_ARGS_((Tcl_Obj *cmdPtr));
EXTERN int		TclObjInterpProc _ANSI_ARGS_((ClientData clientData,
		    	    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
EXTERN int		TclObjInvoke _ANSI_ARGS_((Tcl_Interp *interp,
		            int objc, Tcl_Obj *CONST objv[], int flags));
EXTERN int		TclObjInvokeGlobal _ANSI_ARGS_((Tcl_Interp *interp,
		            int objc, Tcl_Obj *CONST objv[], int flags));
EXTERN char *		TclpAlloc _ANSI_ARGS_((unsigned int size));

/*
 * On a Mac, we can exit gracefully if the stack gets too small.
 */



#ifdef MAC_TCL

EXTERN int		TclpCheckStackSpace _ANSI_ARGS_((void));
#else
#define TclpCheckStackSpace() (1)
#endif

EXTERN int		TclpCloseFile _ANSI_ARGS_((TclFile file));
EXTERN int		TclpCopyFile _ANSI_ARGS_((char *source, char *dest));

EXTERN int              TclpCopyDirectory _ANSI_ARGS_((char *source,
			    char *dest, Tcl_DString *errorPtr));
EXTERN Tcl_Channel	TclpCreateCommandChannel _ANSI_ARGS_((
    			    TclFile readFile, TclFile writeFile,
			    TclFile errorFile, int numPids, Tcl_Pid *pidPtr));
EXTERN int              TclpCreateDirectory _ANSI_ARGS_((char *path));
EXTERN int              TclpCreatePipe _ANSI_ARGS_((TclFile *readPipe,
			    TclFile *writePipe));
EXTERN int		TclpCreateProcess _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv, TclFile inputFile, 
			    TclFile outputFile, TclFile errorFile,

			    Tcl_Pid *pidPtr));
EXTERN TclFile		TclpCreateTempFile _ANSI_ARGS_((char *contents, 
			    Tcl_DString *namePtr));
EXTERN int              TclpDeleteFile _ANSI_ARGS_((char *path));



EXTERN void		TclpFree _ANSI_ARGS_((char *ptr));
EXTERN unsigned long	TclpGetClicks _ANSI_ARGS_((void));

EXTERN unsigned long	TclpGetSeconds _ANSI_ARGS_((void));
EXTERN void		TclpGetTime _ANSI_ARGS_((Tcl_Time *time));
EXTERN int		TclpGetTimeZone _ANSI_ARGS_((unsigned long time));




EXTERN char *		TclpGetTZName _ANSI_ARGS_((void));


EXTERN int		TclpListVolumes _ANSI_ARGS_((Tcl_Interp *interp));


EXTERN TclFile		TclpMakeFile _ANSI_ARGS_((Tcl_Channel channel,




			    int direction));
EXTERN TclFile		TclpOpenFile _ANSI_ARGS_((char *fname, int mode));

EXTERN char *		TclpRealloc _ANSI_ARGS_((char *ptr,
			    unsigned int size));

EXTERN int              TclpRemoveDirectory _ANSI_ARGS_((char *path,
			    int recursive, Tcl_DString *errorPtr));
EXTERN int              TclpRenameFile _ANSI_ARGS_((char *source, char *dest));
EXTERN char *		TclpSetEnv _ANSI_ARGS_((CONST char *name,
			    CONST char *value));
#ifndef TclpSysAlloc

EXTERN VOID * 		TclpSysAlloc _ANSI_ARGS_((long size, int isBin));
#endif
#ifndef TclpSysFree
EXTERN void 		TclpSysFree _ANSI_ARGS_((VOID *ptr));
#endif
#ifndef TclpSysRealloc
EXTERN VOID * 		TclpSysRealloc _ANSI_ARGS_((VOID *cp,
			    unsigned int size));
#endif
EXTERN int		TclParseBraces _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char **termPtr, ParseValue *pvPtr));
EXTERN int		TclParseNestedCmd _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, int flags, char **termPtr,
			    ParseValue *pvPtr));
EXTERN int		TclParseQuotes _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, int termChar, int flags,
			    char **termPtr, ParseValue *pvPtr));
EXTERN void		TclPlatformExit _ANSI_ARGS_((int status));
EXTERN void		TclPlatformInit _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN char *		TclPrecTraceProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, char *name1, char *name2,
			    int flags));
EXTERN int		TclPreventAliasLoop _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Interp *cmdInterp, Tcl_Command cmd));

EXTERN void		TclPrintByteCodeObj _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Obj *objPtr));
















EXTERN int		TclRenameCommand _ANSI_ARGS_((Tcl_Interp *interp,
			    char *oldName, char *newName)) ;
EXTERN void		TclResetShadowedCmdRefs _ANSI_ARGS_((
			    Tcl_Interp *interp, Command *newCmdPtr));
EXTERN int		TclServiceIdle _ANSI_ARGS_((void));
EXTERN Tcl_Obj *	TclSetElementOfIndexedArray _ANSI_ARGS_((
                            Tcl_Interp *interp, int localIndex,
			    Tcl_Obj *elemPtr, Tcl_Obj *objPtr,
			    int leaveErrorMsg));

EXTERN Tcl_Obj *	TclSetIndexedScalar _ANSI_ARGS_((Tcl_Interp *interp,
			    int localIndex, Tcl_Obj *objPtr,
			    int leaveErrorMsg));

EXTERN void		TclSetupEnv _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		TclSockGetPort _ANSI_ARGS_((Tcl_Interp *interp,
		            char *string, char *proto, int *portPtr));
EXTERN int		TclSockMinimumBuffers _ANSI_ARGS_((int sock,
        		    int size));




EXTERN void		TclTeardownNamespace _ANSI_ARGS_((Namespace *nsPtr));
EXTERN int		TclTestChannelCmd _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int argc, char **argv));
EXTERN int		TclTestChannelEventCmd _ANSI_ARGS_((
    			    ClientData clientData, Tcl_Interp *interp,
                            int argc, char **argv));


EXTERN int		TclUpdateReturnInfo _ANSI_ARGS_((Interp *iPtr));
EXTERN char *		TclWordEnd _ANSI_ARGS_((char *start, char *lastChar,
			    int nested, int *semiPtr));

/*
 *----------------------------------------------------------------
 * Command procedures in the generic core:
 *----------------------------------------------------------------
 */

EXTERN int	Tcl_AfterObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_AppendObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ArrayObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_BinaryObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_BreakCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_CaseObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_CatchObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_CdObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ClockObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_CloseObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ConcatObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));


EXTERN int	Tcl_ContinueCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_EofObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ErrorObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_EvalObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ExecCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_ExitObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ExprObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FblockedObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FconfigureCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_FcopyObjCmd _ANSI_ARGS_((ClientData dummy,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FileObjCmd _ANSI_ARGS_((ClientData dummy,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FileEventCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_FlushObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ForCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_ForeachObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FormatObjCmd _ANSI_ARGS_((ClientData dummy,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_GetsObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_GlobalObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_GlobCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_HistoryCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_IfCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_IncrCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_InfoObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_InterpObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_JoinObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LappendObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LindexObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LinsertObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LlengthObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ListObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LoadCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_LrangeObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LreplaceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LsearchObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LsortObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_NamespaceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_OpenCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_PackageCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_PidObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ProcObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_PutsObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_PwdCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_ReadObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_RegexpCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_RegsubCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_RenameObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ReturnObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ScanCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_SeekCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_SetCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_SplitObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_SocketCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_SourceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_StringObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_SubstCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_SwitchObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_TellCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_TimeObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_TraceCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_UnsetObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_UpdateCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_UplevelObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_UpvarObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_VariableObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_VwaitCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_WhileCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));

/*
 *----------------------------------------------------------------
 * Command procedures found only in the Mac version of the core:
 *----------------------------------------------------------------
 */

#ifdef MAC_TCL
EXTERN int 	Tcl_EchoCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int 	Tcl_LsCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int 	Tcl_BeepObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int 	Tcl_MacSourceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ResourceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
#endif

/*
 *----------------------------------------------------------------
 * Compilation procedures for commands in the generic core:
 *----------------------------------------------------------------
 */

EXTERN int	TclCompileBreakCmd _ANSI_ARGS_((Tcl_Interp *interp,
		    char *string, char *lastChar, int compileFlags,
		    struct CompileEnv *compileEnvPtr));
EXTERN int	TclCompileCatchCmd _ANSI_ARGS_((Tcl_Interp *interp,
		    char *string, char *lastChar, int compileFlags,
		    struct CompileEnv *compileEnvPtr));
EXTERN int	TclCompileContinueCmd _ANSI_ARGS_((Tcl_Interp *interp,
		    char *string, char *lastChar, int compileFlags,
		    struct CompileEnv *compileEnvPtr));
EXTERN int	TclCompileExprCmd _ANSI_ARGS_((Tcl_Interp *interp,
		    char *string, char *lastChar, int compileFlags,
		    struct CompileEnv *compileEnvPtr));
EXTERN int	TclCompileForCmd _ANSI_ARGS_((Tcl_Interp *interp,
		    char *string, char *lastChar, int compileFlags,
		    struct CompileEnv *compileEnvPtr));
EXTERN int	TclCompileForeachCmd _ANSI_ARGS_((Tcl_Interp *interp,
		    char *string, char *lastChar, int compileFlags,
		    struct CompileEnv *compileEnvPtr));
EXTERN int	TclCompileIfCmd _ANSI_ARGS_((Tcl_Interp *interp,
		    char *string, char *lastChar, int compileFlags,
		    struct CompileEnv *compileEnvPtr));
EXTERN int	TclCompileIncrCmd _ANSI_ARGS_((Tcl_Interp *interp,
		    char *string, char *lastChar, int compileFlags,
		    struct CompileEnv *compileEnvPtr));
EXTERN int	TclCompileSetCmd _ANSI_ARGS_((Tcl_Interp *interp,
		    char *string, char *lastChar, int compileFlags,
		    struct CompileEnv *compileEnvPtr));
EXTERN int	TclCompileWhileCmd _ANSI_ARGS_((Tcl_Interp *interp,
		    char *string, char *lastChar, int compileFlags,
		    struct CompileEnv *compileEnvPtr));

/*
 *----------------------------------------------------------------
 * Macros used by the Tcl core to create and release Tcl objects.
 * TclNewObj(objPtr) creates a new object denoting an empty string.
 * TclDecrRefCount(objPtr) decrements the object's reference count,
 * and frees the object if its reference count is zero.







>
>
>
>




>















>










<
|

<
|


|










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









>
>
|



|






>




>










|
|

















|
>
>
>

|
|

|


<
<
<
<
<
<















|






|
|






|





>

>
>
>
>

|
>
>
>
|
>
>
>
|
<




<
<
<



<

|

<



|




>










>

|


|
<
>

|


<
<

|
<


|


|



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

|

|
|

|
|
>
>

<
<
<
<
<




<
<
|
<
<

>


|


|

|
|
|
<
<
<
|
>
>
|
>

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


>



>
>
>
>
|
>
>

>
>
|
>
>
>
>
|
|
>


>
|

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

<
<
<
<
<
<
<
<
<
|
<




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






|


>



>


|

|
>
>
>
>




|
|
>
>

<
<















|
|












>
>
|
|






|
|






|
|




|
|


|
|








|
|
<
<
|
|
|
|
















|
|










|
|
|
|






|
|


|
|
|
|




|
|
|
|
|
|


|
|




|
|


|
|


|
|


|
|






|
|
|
|








|

|
|
|

|












<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|

<
|







1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455

1456
1457

1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564






1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616

1617
1618
1619
1620



1621
1622
1623

1624
1625
1626

1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651

1652
1653
1654
1655
1656


1657
1658

1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690





1691
1692
1693
1694


1695


1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707



1708
1709
1710
1711
1712
1713





1714
1715
1716
1717
1718
1719

1720
1721
1722
1723


1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760

1761
1762
1763
1764
1765


1766


1767
1768









1769

1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825


1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013

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
 * TCL_INVOKE_HIDDEN		Invoke a hidden command; if not set,
 *				invokes an exposed command.
 * TCL_INVOKE_NO_UNKNOWN	If set, "unknown" is not invoked if
 *				the command to be invoked is not found.
 *				Only has an effect if invoking an exposed
 *				command, i.e. if TCL_INVOKE_HIDDEN is not
 *				also set.
 * TCL_INVOKE_NO_TRACEBACK	Does not record traceback information if
 *				the invoked command returns an error.  Used
 *				if the caller plans on recording its own
 *				traceback information.
 */

#define	TCL_INVOKE_HIDDEN	(1<<0)
#define TCL_INVOKE_NO_UNKNOWN	(1<<1)
#define TCL_INVOKE_NO_TRACEBACK	(1<<2)

/*
 * The structure used as the internal representation of Tcl list
 * objects. This is an array of pointers to the element objects. This array
 * is grown (reallocated and copied) as necessary to hold all the list's
 * element pointers. The array might contain more slots than currently used
 * to hold all element pointers. This is done to make append operations
 * faster.
 */

typedef struct List {
    int maxElemCount;		/* Total number of element array slots. */
    int elemCount;		/* Current number of list elements. */
    Tcl_Obj **elements;		/* Array of pointers to element objects. */
} List;


/*
 * The following types are used for getting and storing platform-specific
 * file attributes in tclFCmd.c and the various platform-versions of
 * that file. This is done to have as much common code as possible
 * in the file attributes code. For more information about the callbacks,
 * see TclFileAttrsCmd in tclFCmd.c.
 */

typedef int (TclGetFileAttrProc) _ANSI_ARGS_((Tcl_Interp *interp,

	int objIndex, CONST char *fileName, Tcl_Obj **attrObjPtrPtr));
typedef int (TclSetFileAttrProc) _ANSI_ARGS_((Tcl_Interp *interp,

	int objIndex, CONST char *fileName, Tcl_Obj *attrObjPtr));

typedef struct TclFileAttrProcs {
    TclGetFileAttrProc *getProc;	/* The procedure for getting attrs. */
    TclSetFileAttrProc *setProc;	/* The procedure for setting attrs. */
} TclFileAttrProcs;

/*
 * Opaque handle used in pipeline routines to encapsulate platform-dependent
 * state. 
 */

typedef struct TclFile_ *TclFile;
    
/*
 *----------------------------------------------------------------
 * Data structures related to hooking 'TclStat(...)' and
 * 'TclAccess(...)'.
 *----------------------------------------------------------------
 */

typedef struct stat TclStat_;
typedef int (TclStatProc_) _ANSI_ARGS_((CONST char *path, TclStat_ *buf));
typedef int (TclAccessProc_) _ANSI_ARGS_((CONST char *path, int mode));
typedef Tcl_Channel (TclOpenFileChannelProc_) _ANSI_ARGS_((Tcl_Interp *interp,
	char *fileName, char *modeString,
	int permissions));

typedef int (*TclCmdProcType) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int argc, char *argv[]));
typedef int (*TclObjCmdProcType) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int objc, struct Tcl_Obj * CONST objv[]));

/*
 * Opaque names for platform specific types.
 */

typedef struct TclpTime_t_ *TclpTime_t;

/*
 *----------------------------------------------------------------
 * Variables shared among Tcl modules but not used by the outside world.
 *----------------------------------------------------------------
 */

extern Tcl_Time			tclBlockTime;
extern int			tclBlockTimeSet;
extern char *			tclExecutableName;
extern char *			tclNativeExecutableName;
extern char *			tclDefaultEncodingDir;
extern Tcl_ChannelType		tclFileChannelType;
extern char *			tclMemDumpFileName;
extern TclPlatformType		tclPlatform;
extern char *			tclpFileAttrStrings[];
extern CONST TclFileAttrProcs	tclpFileAttrProcs[];

/*
 * Variables denoting the Tcl object types defined in the core.
 */

extern Tcl_ObjType	tclBooleanType;
extern Tcl_ObjType	tclByteArrayType;
extern Tcl_ObjType	tclByteCodeType;
extern Tcl_ObjType	tclDoubleType;
extern Tcl_ObjType	tclIntType;
extern Tcl_ObjType	tclListType;
extern Tcl_ObjType	tclProcBodyType;
extern Tcl_ObjType	tclStringType;

/*
 * The head of the list of free Tcl objects, and the total number of Tcl
 * objects ever allocated and freed.
 */

extern Tcl_Obj *	tclFreeObjList;

#ifdef TCL_COMPILE_STATS
extern long		tclObjsAlloced;
extern long		tclObjsFreed;
#endif /* TCL_COMPILE_STATS */

/*
 * Pointer to a heap-allocated string of length zero that the Tcl core uses
 * as the value of an empty string representation for an object. This value
 * is shared by all new objects allocated by Tcl_NewObj.
 */

extern char *		tclEmptyStringRep;

/*
 *----------------------------------------------------------------
 * Procedures shared among Tcl modules but not used by the outside
 * world:
 *----------------------------------------------------------------
 */

EXTERN int		TclAccess _ANSI_ARGS_((CONST char *path,
			    int mode));
EXTERN int		TclAccessDeleteProc _ANSI_ARGS_((TclAccessProc_ *proc));
EXTERN int		TclAccessInsertProc _ANSI_ARGS_((TclAccessProc_ *proc));
EXTERN void		TclAllocateFreeObjects _ANSI_ARGS_((void));
EXTERN int		TclArraySet _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *arrayNameObj, Tcl_Obj *arrayElemObj));
EXTERN int		TclCleanupChildren _ANSI_ARGS_((Tcl_Interp *interp,
			    int numPids, Tcl_Pid *pidPtr,
			    Tcl_Channel errorChan));
EXTERN void		TclCleanupCommand _ANSI_ARGS_((Command *cmdPtr));






EXTERN int		TclCopyChannel _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Channel inChan, Tcl_Channel outChan,
			    int toRead, Tcl_Obj *cmdPtr));
/*
 * TclCreatePipeline unofficially exported for use by BLT.
 */
EXTERN int		TclCreatePipeline _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv, Tcl_Pid **pidArrayPtr,
			    TclFile *inPipePtr, TclFile *outPipePtr,
			    TclFile *errFilePtr));
EXTERN int		TclCreateProc _ANSI_ARGS_((Tcl_Interp *interp,
			    Namespace *nsPtr, char *procName,
			    Tcl_Obj *argsPtr, Tcl_Obj *bodyPtr,
			    Proc **procPtrPtr));
EXTERN void		TclDeleteCompiledLocalVars _ANSI_ARGS_((
			    Interp *iPtr, CallFrame *framePtr));
EXTERN void		TclDeleteVars _ANSI_ARGS_((Interp *iPtr,
			    Tcl_HashTable *tablePtr));
EXTERN int		TclDoGlob _ANSI_ARGS_((Tcl_Interp *interp,
			    char *separators, Tcl_DString *headPtr,
			    char *tail));
EXTERN void		TclDumpMemoryInfo _ANSI_ARGS_((FILE *outFile));
EXTERN void		TclExpandTokenArray _ANSI_ARGS_((
			    Tcl_Parse *parsePtr));
EXTERN void		TclExprFloatError _ANSI_ARGS_((Tcl_Interp *interp,
			    double value));
EXTERN int		TclFileAttrsCmd _ANSI_ARGS_((Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[]));
EXTERN int		TclFileCopyCmd _ANSI_ARGS_((Tcl_Interp *interp, 
			    int argc, char **argv)) ;
EXTERN int		TclFileDeleteCmd _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv));
EXTERN int		TclFileMakeDirsCmd _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv)) ;
EXTERN int		TclFileRenameCmd _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv)) ;
EXTERN void		TclFinalizeAllocSubsystem _ANSI_ARGS_((void));
EXTERN void		TclFinalizeCompExecEnv _ANSI_ARGS_((void));
EXTERN void		TclFinalizeCondition _ANSI_ARGS_((
			    Tcl_Condition *condPtr));
EXTERN void		TclFinalizeCompilation _ANSI_ARGS_((void));
EXTERN void		TclFinalizeEncodingSubsystem _ANSI_ARGS_((void));
EXTERN void		TclFinalizeEnvironment _ANSI_ARGS_((void));
EXTERN void		TclFinalizeExecution _ANSI_ARGS_((void));
EXTERN void		TclFinalizeIOSubsystem _ANSI_ARGS_((void));
EXTERN void		TclFinalizeLoad _ANSI_ARGS_((void));
EXTERN void		TclFinalizeMemorySubsystem _ANSI_ARGS_((void));
EXTERN void		TclFinalizeMutex _ANSI_ARGS_((Tcl_Mutex *mutex));
EXTERN void		TclFinalizeNotifier _ANSI_ARGS_((void));
EXTERN void		TclFinalizeSynchronization _ANSI_ARGS_((void));
EXTERN void		TclFinalizeThreadData _ANSI_ARGS_((void));
EXTERN void		TclFindEncodings _ANSI_ARGS_((CONST char *argv0));

EXTERN Proc *		TclFindProc _ANSI_ARGS_((Interp *iPtr,
			    char *procName));
EXTERN int		TclFormatInt _ANSI_ARGS_((char *buffer, long n));
EXTERN void		TclFreePackageInfo _ANSI_ARGS_((Interp *iPtr));



EXTERN int		TclGetDate _ANSI_ARGS_((char *p,
			    unsigned long now, long zone,
			    unsigned long *timePtr));

EXTERN Tcl_Obj *	TclGetElementOfIndexedArray _ANSI_ARGS_((
			    Tcl_Interp *interp, int localIndex,
			    Tcl_Obj *elemPtr, int leaveErrorMsg));

EXTERN char *		TclGetExtension _ANSI_ARGS_((char *name));
EXTERN int		TclGetFrame _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, CallFrame **framePtrPtr));
EXTERN TclCmdProcType	TclGetInterpProc _ANSI_ARGS_((void));
EXTERN int		TclGetIntForIndex _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, int endValue, int *indexPtr));
EXTERN Tcl_Obj *	TclGetIndexedScalar _ANSI_ARGS_((Tcl_Interp *interp,
			    int localIndex, int leaveErrorMsg));
EXTERN Tcl_Obj *	TclGetLibraryPath _ANSI_ARGS_((void));
EXTERN int		TclGetLong _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, long *longPtr));
EXTERN int		TclGetLoadedPackages _ANSI_ARGS_((
			    Tcl_Interp *interp, char *targetName));
EXTERN int		TclGetNamespaceForQualName _ANSI_ARGS_((
			    Tcl_Interp *interp, char *qualName,
			    Namespace *cxtNsPtr, int flags,
			    Namespace **nsPtrPtr, Namespace **altNsPtrPtr,
			    Namespace **actualCxtPtrPtr,
			    char **simpleNamePtr));
EXTERN TclObjCmdProcType TclGetObjInterpProc _ANSI_ARGS_((void));
EXTERN int		TclGetOpenMode _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, int *seekFlagPtr));
EXTERN Tcl_Command	TclGetOriginalCommand _ANSI_ARGS_((
			    Tcl_Command command));
EXTERN int		TclGlob _ANSI_ARGS_((Tcl_Interp *interp,

			    char *pattern, int noComplain));
EXTERN int		TclGlobalInvoke _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv, int flags));
EXTERN int		TclGuessPackageName _ANSI_ARGS_((char *fileName,
			    Tcl_DString *bufPtr));


EXTERN int		TclHideUnsafeCommands _ANSI_ARGS_((
			    Tcl_Interp *interp));

EXTERN int		TclInExit _ANSI_ARGS_((void));
EXTERN Tcl_Obj *	TclIncrElementOfIndexedArray _ANSI_ARGS_((
			    Tcl_Interp *interp, int localIndex,
			    Tcl_Obj *elemPtr, long incrAmount));
EXTERN Tcl_Obj *	TclIncrIndexedScalar _ANSI_ARGS_((
			    Tcl_Interp *interp, int localIndex,
			    long incrAmount));
EXTERN Tcl_Obj *	TclIncrVar2 _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr,
			    long incrAmount, int flags));
EXTERN void		TclInitAlloc _ANSI_ARGS_((void));
EXTERN void		TclInitCompiledLocals _ANSI_ARGS_((
			    Tcl_Interp *interp, CallFrame *framePtr,
			    Namespace *nsPtr));
EXTERN void		TclInitDbCkalloc _ANSI_ARGS_((void));
EXTERN void		TclInitEncodingSubsystem _ANSI_ARGS_((void));
EXTERN void		TclInitIOSubsystem _ANSI_ARGS_((void));
EXTERN void		TclInitNamespaceSubsystem _ANSI_ARGS_((void));
EXTERN void		TclInitNotifier _ANSI_ARGS_((void));
EXTERN void		TclInitObjSubsystem _ANSI_ARGS_((void));
EXTERN void		TclInitSubsystems _ANSI_ARGS_((CONST char *argv0));
EXTERN int		TclInvoke _ANSI_ARGS_((Tcl_Interp *interp,
			    int argc, char **argv, int flags));
EXTERN int		TclInvokeObjectCommand _ANSI_ARGS_((
			    ClientData clientData, Tcl_Interp *interp,
			    int argc, char **argv));
EXTERN int		TclInvokeStringCommand _ANSI_ARGS_((
			    ClientData clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[]));
EXTERN int		TclIsLocalScalar _ANSI_ARGS_((CONST char *src,
			    int len));
EXTERN Proc *		TclIsProc _ANSI_ARGS_((Command *cmdPtr));





EXTERN Var *		TclLookupVar _ANSI_ARGS_((Tcl_Interp *interp,
			    char *part1, char *part2, int flags, char *msg,
			    int createPart1, int createPart2,
			    Var **arrayPtrPtr));


EXTERN int		TclMathInProgress _ANSI_ARGS_((void));


EXTERN int		TclNeedSpace _ANSI_ARGS_((char *start, char *end));
EXTERN Tcl_Obj *	TclNewProcBodyObj _ANSI_ARGS_((Proc *procPtr));
EXTERN int		TclObjCommandComplete _ANSI_ARGS_((Tcl_Obj *cmdPtr));
EXTERN int		TclObjInterpProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
EXTERN int		TclObjInvoke _ANSI_ARGS_((Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[], int flags));
EXTERN int		TclObjInvokeGlobal _ANSI_ARGS_((Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[], int flags));
EXTERN int		TclOpenFileChannelDeleteProc _ANSI_ARGS_((
			    TclOpenFileChannelProc_ *proc));



EXTERN int		TclOpenFileChannelInsertProc _ANSI_ARGS_((
			    TclOpenFileChannelProc_ *proc));
EXTERN int		TclpAccess _ANSI_ARGS_((CONST char *filename,
			    int mode));
EXTERN char *		TclpAlloc _ANSI_ARGS_((unsigned int size));
EXTERN int		TclpCheckStackSpace _ANSI_ARGS_((void));





EXTERN int		TclpCopyFile _ANSI_ARGS_((CONST char *source,
			    CONST char *dest));
EXTERN int		TclpCopyDirectory _ANSI_ARGS_((CONST char *source,
			    CONST char *dest, Tcl_DString *errorPtr));
EXTERN int		TclpCreateDirectory _ANSI_ARGS_((CONST char *path));
EXTERN int		TclpDeleteFile _ANSI_ARGS_((CONST char *path));

EXTERN void		TclpExit _ANSI_ARGS_((int status));
EXTERN void		TclpFinalizeCondition _ANSI_ARGS_((
			    Tcl_Condition *condPtr));
EXTERN void		TclpFinalizeMutex _ANSI_ARGS_((Tcl_Mutex *mutexPtr));


EXTERN void		TclpFinalizeThreadData _ANSI_ARGS_((
			    Tcl_ThreadDataKey *keyPtr));
EXTERN void		TclpFinalizeThreadDataKey _ANSI_ARGS_((
			    Tcl_ThreadDataKey *keyPtr));
EXTERN char *		TclpFindExecutable _ANSI_ARGS_((
			    CONST char *argv0));
EXTERN int		TclpFindVariable _ANSI_ARGS_((CONST char *name,
			    int *lengthPtr));
EXTERN void		TclpFree _ANSI_ARGS_((char *ptr));
EXTERN unsigned long	TclpGetClicks _ANSI_ARGS_((void));
EXTERN Tcl_Channel	TclpGetDefaultStdChannel _ANSI_ARGS_((int type));
EXTERN unsigned long	TclpGetSeconds _ANSI_ARGS_((void));
EXTERN void		TclpGetTime _ANSI_ARGS_((Tcl_Time *time));
EXTERN int		TclpGetTimeZone _ANSI_ARGS_((unsigned long time));
EXTERN char *		TclpGetUserHome _ANSI_ARGS_((CONST char *name,
			    Tcl_DString *bufferPtr));
EXTERN int		TclpHasSockets _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void		TclpInitLibraryPath _ANSI_ARGS_((CONST char *argv0));
EXTERN void		TclpInitLock _ANSI_ARGS_((void));
EXTERN void		TclpInitPlatform _ANSI_ARGS_((void));
EXTERN void		TclpInitUnlock _ANSI_ARGS_((void));
EXTERN int		TclpListVolumes _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN void		TclpMasterLock _ANSI_ARGS_((void));
EXTERN void		TclpMasterUnlock _ANSI_ARGS_((void));
EXTERN int		TclpMatchFiles _ANSI_ARGS_((Tcl_Interp *interp,
			    char *separators, Tcl_DString *dirPtr,
			    char *pattern, char *tail));
EXTERN Tcl_Channel	TclpOpenFileChannel _ANSI_ARGS_((Tcl_Interp *interp,
			    char *fileName, char *modeString,
			    int permissions));
EXTERN char *		TclpReadlink _ANSI_ARGS_((CONST char *fileName,
			    Tcl_DString *linkPtr));
EXTERN char *		TclpRealloc _ANSI_ARGS_((char *ptr,
			    unsigned int size));
EXTERN void		TclpReleaseFile _ANSI_ARGS_((TclFile file));
EXTERN int		TclpRemoveDirectory _ANSI_ARGS_((CONST char *path,
			    int recursive, Tcl_DString *errorPtr));

EXTERN int		TclpRenameFile _ANSI_ARGS_((CONST char *source,
			    CONST char *dest));
EXTERN void		TclpSetInitialEncodings _ANSI_ARGS_((void));
EXTERN void		TclpSetVariables _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN VOID *		TclpSysAlloc _ANSI_ARGS_((long size, int isBin));


EXTERN void		TclpSysFree _ANSI_ARGS_((VOID *ptr));


EXTERN VOID *		TclpSysRealloc _ANSI_ARGS_((VOID *cp,
			    unsigned int size));









EXTERN void		TclpUnloadFile _ANSI_ARGS_((ClientData clientData));

EXTERN char *		TclPrecTraceProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, char *name1, char *name2,
			    int flags));
EXTERN int		TclPreventAliasLoop _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *cmdInterp, Tcl_Command cmd));
EXTERN void		TclProcCleanupProc _ANSI_ARGS_((Proc *procPtr));
EXTERN int		TclProcCompileProc _ANSI_ARGS_((Tcl_Interp *interp,
			    Proc *procPtr, Tcl_Obj *bodyPtr, Namespace *nsPtr,
			    CONST char *description, CONST char *procName));
EXTERN void		TclProcDeleteProc _ANSI_ARGS_((ClientData clientData));
EXTERN int		TclProcInterpProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int argc, char **argv));
EXTERN int		TclpThreadCreate _ANSI_ARGS_((Tcl_ThreadId *idPtr,
			    Tcl_ThreadCreateProc proc, ClientData clientData));
EXTERN VOID *		TclpThreadDataKeyGet _ANSI_ARGS_((
			    Tcl_ThreadDataKey *keyPtr));
EXTERN void		TclpThreadDataKeyInit _ANSI_ARGS_((
			    Tcl_ThreadDataKey *keyPtr));
EXTERN void		TclpThreadDataKeySet _ANSI_ARGS_((
			    Tcl_ThreadDataKey *keyPtr, VOID *data));
EXTERN void		TclpThreadExit _ANSI_ARGS_((int status));
EXTERN void		TclRememberCondition _ANSI_ARGS_((Tcl_Condition *mutex));
EXTERN void		TclRememberDataKey _ANSI_ARGS_((Tcl_ThreadDataKey *mutex));
EXTERN void		TclRememberMutex _ANSI_ARGS_((Tcl_Mutex *mutex));
EXTERN int		TclRenameCommand _ANSI_ARGS_((Tcl_Interp *interp,
			    char *oldName, char *newName)) ;
EXTERN void		TclResetShadowedCmdRefs _ANSI_ARGS_((
			    Tcl_Interp *interp, Command *newCmdPtr));
EXTERN int		TclServiceIdle _ANSI_ARGS_((void));
EXTERN Tcl_Obj *	TclSetElementOfIndexedArray _ANSI_ARGS_((
			    Tcl_Interp *interp, int localIndex,
			    Tcl_Obj *elemPtr, Tcl_Obj *objPtr,
			    int leaveErrorMsg));
EXTERN void		TclSetLibraryPath _ANSI_ARGS_((Tcl_Obj *pathPtr));
EXTERN Tcl_Obj *	TclSetIndexedScalar _ANSI_ARGS_((Tcl_Interp *interp,
			    int localIndex, Tcl_Obj *objPtr,
			    int leaveErrorMsg));
EXTERN char *		TclSetPreInitScript _ANSI_ARGS_((char *string));
EXTERN void		TclSetupEnv _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		TclSockGetPort _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, char *proto, int *portPtr));
EXTERN int		TclSockMinimumBuffers _ANSI_ARGS_((int sock,
			    int size));
EXTERN int		TclStat _ANSI_ARGS_((CONST char *path,
			    TclStat_ *buf));
EXTERN int		TclStatDeleteProc _ANSI_ARGS_((TclStatProc_ *proc));
EXTERN int		TclStatInsertProc _ANSI_ARGS_((TclStatProc_ *proc));
EXTERN void		TclTeardownNamespace _ANSI_ARGS_((Namespace *nsPtr));
EXTERN int		TclTestChannelCmd _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int argc, char **argv));
EXTERN int		TclTestChannelEventCmd _ANSI_ARGS_((
			    ClientData clientData, Tcl_Interp *interp,
			    int argc, char **argv));
EXTERN void		TclTransferResult _ANSI_ARGS_((Tcl_Interp *sourceInterp,
			    int result, Tcl_Interp *targetInterp));
EXTERN int		TclUpdateReturnInfo _ANSI_ARGS_((Interp *iPtr));



/*
 *----------------------------------------------------------------
 * Command procedures in the generic core:
 *----------------------------------------------------------------
 */

EXTERN int	Tcl_AfterObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_AppendObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ArrayObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_BinaryObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_BreakObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_CaseObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_CatchObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_CdObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ClockObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_CloseObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ConcatObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ContinueObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_EncodingObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_EofObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ErrorObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_EvalObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ExecObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ExitObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ExprObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FblockedObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FconfigureObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FcopyObjCmd _ANSI_ARGS_((ClientData dummy,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FileObjCmd _ANSI_ARGS_((ClientData dummy,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FileEventObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FlushObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ForObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ForeachObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_FormatObjCmd _ANSI_ARGS_((ClientData dummy,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_GetsObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_GlobalObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_GlobObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));


EXTERN int	Tcl_IfObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_IncrObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_InfoObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_InterpObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_JoinObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LappendObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LindexObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LinsertObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LlengthObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ListObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LoadObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LrangeObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LreplaceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LsearchObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_LsortObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_NamespaceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_OpenObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_PackageObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_PidObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ProcObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_PutsObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_PwdObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ReadObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_RegexpObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_RegsubObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_RenameObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ReturnObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ScanObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_SeekObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_SetObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_SplitObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_SocketObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_SourceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_StringObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_SubstObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_SwitchObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_TellObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_TimeObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_TraceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_UnsetObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_UpdateObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_UplevelObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_UpvarObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_VariableObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_VwaitObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_WhileObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));

/*
 *----------------------------------------------------------------
 * Command procedures found only in the Mac version of the core:
 *----------------------------------------------------------------
 */

#ifdef MAC_TCL
EXTERN int	Tcl_EchoCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));
EXTERN int	Tcl_LsObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_BeepObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_MacSourceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	Tcl_ResourceObjCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
#endif

/*
 *----------------------------------------------------------------
 * Compilation procedures for commands in the generic core:
 *----------------------------------------------------------------
 */

EXTERN int	TclCompileBreakCmd _ANSI_ARGS_((Tcl_Interp *interp,

		    Tcl_Parse *parsePtr, struct CompileEnv *envPtr));
EXTERN int	TclCompileCatchCmd _ANSI_ARGS_((Tcl_Interp *interp,

		    Tcl_Parse *parsePtr, struct CompileEnv *envPtr));
EXTERN int	TclCompileContinueCmd _ANSI_ARGS_((Tcl_Interp *interp,

		    Tcl_Parse *parsePtr, struct CompileEnv *envPtr));
EXTERN int	TclCompileExprCmd _ANSI_ARGS_((Tcl_Interp *interp,

		    Tcl_Parse *parsePtr, struct CompileEnv *envPtr));
EXTERN int	TclCompileForCmd _ANSI_ARGS_((Tcl_Interp *interp,

		    Tcl_Parse *parsePtr, struct CompileEnv *envPtr));
EXTERN int	TclCompileForeachCmd _ANSI_ARGS_((Tcl_Interp *interp,

		    Tcl_Parse *parsePtr, struct CompileEnv *envPtr));
EXTERN int	TclCompileIfCmd _ANSI_ARGS_((Tcl_Interp *interp,

		    Tcl_Parse *parsePtr, struct CompileEnv *envPtr));
EXTERN int	TclCompileIncrCmd _ANSI_ARGS_((Tcl_Interp *interp,

		    Tcl_Parse *parsePtr, struct CompileEnv *envPtr));
EXTERN int	TclCompileSetCmd _ANSI_ARGS_((Tcl_Interp *interp,

		    Tcl_Parse *parsePtr, struct CompileEnv *envPtr));
EXTERN int	TclCompileWhileCmd _ANSI_ARGS_((Tcl_Interp *interp,

		    Tcl_Parse *parsePtr, struct CompileEnv *envPtr));

/*
 *----------------------------------------------------------------
 * Macros used by the Tcl core to create and release Tcl objects.
 * TclNewObj(objPtr) creates a new object denoting an empty string.
 * TclDecrRefCount(objPtr) decrements the object's reference count,
 * and frees the object if its reference count is zero.
1725
1726
1727
1728
1729
1730
1731

1732
1733
1734
1735
1736
1737

1738
1739
1740
1741
1742
1743
1744

1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760

1761





1762

1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773


1774
1775
1776
1777
1778
1779
1780
1781
1782
1783

1784
1785
1786

1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871


1872
1873
1874
1875
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
#else
#  define TclIncrObjsAllocated()
#  define TclIncrObjsFreed()
#endif /* TCL_COMPILE_STATS */

#ifdef TCL_MEM_DEBUG
#  define TclNewObj(objPtr) \

    (objPtr) = (Tcl_Obj *) Tcl_DbCkalloc(sizeof(Tcl_Obj), __FILE__, __LINE__); \
    (objPtr)->refCount = 0; \
    (objPtr)->bytes    = tclEmptyStringRep; \
    (objPtr)->length   = 0; \
    (objPtr)->typePtr  = NULL; \
    TclIncrObjsAllocated()

#  define TclDbNewObj(objPtr, file, line) \
    (objPtr) = (Tcl_Obj *) Tcl_DbCkalloc(sizeof(Tcl_Obj), (file), (line)); \
    (objPtr)->refCount = 0; \
    (objPtr)->bytes    = tclEmptyStringRep; \
    (objPtr)->length   = 0; \
    (objPtr)->typePtr  = NULL; \
    TclIncrObjsAllocated()

#  define TclDecrRefCount(objPtr) \
    if (--(objPtr)->refCount <= 0) { \
 	if ((objPtr)->refCount < -1) \
            panic("Reference count for %lx was negative: %s line %d", \
		  (objPtr), __FILE__, __LINE__); \
        if (((objPtr)->bytes != NULL) \
	        && ((objPtr)->bytes != tclEmptyStringRep)) { \
	    ckfree((char *) (objPtr)->bytes); \
        } \
        if (((objPtr)->typePtr != NULL) \
	        && ((objPtr)->typePtr->freeIntRepProc != NULL)) { \
	    (objPtr)->typePtr->freeIntRepProc(objPtr); \
        } \
        ckfree((char *) (objPtr)); \
        TclIncrObjsFreed(); \
    }

#else /* not TCL_MEM_DEBUG */





#  define TclNewObj(objPtr) \

    if (tclFreeObjList == NULL) { \
	TclAllocateFreeObjects(); \
    } \
    (objPtr) = tclFreeObjList; \
    tclFreeObjList = (Tcl_Obj *) \
	tclFreeObjList->internalRep.otherValuePtr; \
    (objPtr)->refCount = 0; \
    (objPtr)->bytes    = tclEmptyStringRep; \
    (objPtr)->length   = 0; \
    (objPtr)->typePtr  = NULL; \
    TclIncrObjsAllocated()


#  define TclDecrRefCount(objPtr) \
    if (--(objPtr)->refCount <= 0) { \
        if (((objPtr)->bytes != NULL) \
	        && ((objPtr)->bytes != tclEmptyStringRep)) { \
	    ckfree((char *) (objPtr)->bytes); \
        } \
        if (((objPtr)->typePtr != NULL) \
	        && ((objPtr)->typePtr->freeIntRepProc != NULL)) { \
	    (objPtr)->typePtr->freeIntRepProc(objPtr); \
        } \

        (objPtr)->internalRep.otherValuePtr = (VOID *) tclFreeObjList; \
        tclFreeObjList = (objPtr); \
        TclIncrObjsFreed(); \

    }
#endif /* TCL_MEM_DEBUG */

/*
 *----------------------------------------------------------------
 * Macro used by the Tcl core to set a Tcl_Obj's string representation
 * to a copy of the "len" bytes starting at "bytePtr". This code
 * works even if the byte array contains NULLs as long as the length
 * is correct. Because "len" is referenced multiple times, it should
 * be as simple an expression as possible. The ANSI C "prototype" for
 * this macro is:
 *
 * EXTERN void	TclInitStringRep _ANSI_ARGS_((Tcl_Obj *objPtr,
 *		    char *bytePtr, int len));
 *----------------------------------------------------------------
 */

#define TclInitStringRep(objPtr, bytePtr, len) \
    if ((len) == 0) { \
        (objPtr)->bytes  = tclEmptyStringRep; \
	(objPtr)->length = 0; \
    } else { \
	(objPtr)->bytes = (char *) ckalloc((unsigned) ((len) + 1)); \
	memcpy((VOID *) (objPtr)->bytes, (VOID *) (bytePtr), \
	        (unsigned) (len)); \
	(objPtr)->bytes[len] = '\0'; \
	(objPtr)->length = (len); \
    }

/*
 *----------------------------------------------------------------
 * Macro used by the Tcl core to get the string representation's
 * byte array pointer and length from a Tcl_Obj. This is an inline
 * version of Tcl_GetStringFromObj(). "lengthPtr" must be the
 * address of an integer variable or NULL; If non-NULL, that variable
 * will be set to the string rep's length. The macro's expression
 * result is the string rep's byte pointer which might be NULL.
 * Note that the bytes referenced by this pointer must not be modified
 * by the caller. The ANSI C "prototype" for this macro is:
 *
 * EXTERN char *  TclGetStringFromObj _ANSI_ARGS_((Tcl_Obj *objPtr,
 *		       int *lengthPtr));
 *----------------------------------------------------------------
 */

#define TclGetStringFromObj(objPtr, lengthPtr) \
    ((objPtr)->bytes? \
        ((lengthPtr)? \
	    ((*(lengthPtr) = (objPtr)->length), (objPtr)->bytes) : \
	    (objPtr)->bytes) : \
        Tcl_GetStringFromObj((objPtr), (lengthPtr)))

/*
 *----------------------------------------------------------------
 * Macro used by the Tcl core to reset an interpreter's Tcl object
 * result to an unshared empty string object with ref count one.
 * This does not clear any error information for the interpreter.
 * The ANSI C "prototype" for this macro is:
 *
 * EXTERN void	TclResetObjResult _ANSI_ARGS_((Tcl_Interp *interp));
 *---------------------------------------------------------------
 */

#define TclResetObjResult(interp) \
    { \
        register Tcl_Obj *objResultPtr = ((Interp *) interp)->objResultPtr; \
        if (Tcl_IsShared(objResultPtr)) { \
	    TclDecrRefCount(objResultPtr); \
	    TclNewObj(objResultPtr); \
	    Tcl_IncrRefCount(objResultPtr); \
	    ((Interp *) interp)->objResultPtr = objResultPtr; \
        } else { \
	    if ((objResultPtr->bytes != NULL) \
		    && (objResultPtr->bytes != tclEmptyStringRep)) { \
	        ckfree((char *) objResultPtr->bytes); \
	    } \
	    objResultPtr->bytes  = tclEmptyStringRep; \
	    objResultPtr->length = 0; \
	    if ((objResultPtr->typePtr != NULL) \
	            && (objResultPtr->typePtr->freeIntRepProc != NULL)) { \
	        objResultPtr->typePtr->freeIntRepProc(objResultPtr); \
	    } \
	    objResultPtr->typePtr = (Tcl_ObjType *) NULL; \
        } \
    }



/*
 *----------------------------------------------------------------
 * Procedures used in conjunction with Tcl namespaces. They are
 * defined here instead of in tcl.h since they are not stable yet.
 *----------------------------------------------------------------
 */


EXTERN int		Tcl_AppendExportList _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Namespace *nsPtr,
			    Tcl_Obj *objPtr));
EXTERN Tcl_Namespace *	Tcl_CreateNamespace _ANSI_ARGS_((Tcl_Interp *interp,
			    char *name, ClientData clientData,
			    Tcl_NamespaceDeleteProc *deleteProc));
EXTERN void		Tcl_DeleteNamespace _ANSI_ARGS_((
			    Tcl_Namespace *nsPtr));
EXTERN int		Tcl_Export _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Namespace *nsPtr, char *pattern,
			    int resetListFirst));
EXTERN Tcl_Command	Tcl_FindCommand _ANSI_ARGS_((Tcl_Interp *interp,
			    char *name, Tcl_Namespace *contextNsPtr,
			    int flags));
EXTERN Tcl_Namespace *	Tcl_FindNamespace _ANSI_ARGS_((Tcl_Interp *interp,
			    char *name, Tcl_Namespace *contextNsPtr,
			    int flags));
EXTERN Tcl_Var		Tcl_FindNamespaceVar _ANSI_ARGS_((
			    Tcl_Interp *interp, char *name,
			    Tcl_Namespace *contextNsPtr, int flags));
EXTERN int		Tcl_ForgetImport _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Namespace *nsPtr, char *pattern));
EXTERN Tcl_Command	Tcl_GetCommandFromObj _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Obj *objPtr));
EXTERN void		Tcl_GetCommandFullName _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Command command,
			    Tcl_Obj *objPtr));
EXTERN Tcl_Namespace *	Tcl_GetCurrentNamespace _ANSI_ARGS_((
			    Tcl_Interp *interp));
EXTERN Tcl_Namespace *	Tcl_GetGlobalNamespace _ANSI_ARGS_((
			    Tcl_Interp *interp));
EXTERN void		Tcl_GetVariableFullName _ANSI_ARGS_((
			    Tcl_Interp *interp, Tcl_Var variable,
			    Tcl_Obj *objPtr));
EXTERN int		Tcl_Import _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Namespace *nsPtr, char *pattern,
			    int allowOverwrite));
EXTERN void		Tcl_PopCallFrame _ANSI_ARGS_((Tcl_Interp* interp));
EXTERN int		Tcl_PushCallFrame _ANSI_ARGS_((Tcl_Interp* interp,
			    Tcl_CallFrame *framePtr, Tcl_Namespace *nsPtr,
			    int isProcCallFrame)); 



#endif /* _TCLINT */








>
|





>







>


|
|

|
|

|
|
|

|
|
|

>

>
>
>
>
>

>










|
>
>


|
|

|
|
|

|
>
|
|
|
>



















|




|







|
<
<
|
|
|
|

|
<


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

<
<
<
<
<
<
>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>



2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165


2166
2167
2168
2169
2170
2171

2172
2173








































2174
2175
2176
2177






2178
2179









































2180
2181
2182
2183
2184
#else
#  define TclIncrObjsAllocated()
#  define TclIncrObjsFreed()
#endif /* TCL_COMPILE_STATS */

#ifdef TCL_MEM_DEBUG
#  define TclNewObj(objPtr) \
    (objPtr) = (Tcl_Obj *) \
	 Tcl_DbCkalloc(sizeof(Tcl_Obj), __FILE__, __LINE__); \
    (objPtr)->refCount = 0; \
    (objPtr)->bytes    = tclEmptyStringRep; \
    (objPtr)->length   = 0; \
    (objPtr)->typePtr  = NULL; \
    TclIncrObjsAllocated()
     
#  define TclDbNewObj(objPtr, file, line) \
    (objPtr) = (Tcl_Obj *) Tcl_DbCkalloc(sizeof(Tcl_Obj), (file), (line)); \
    (objPtr)->refCount = 0; \
    (objPtr)->bytes    = tclEmptyStringRep; \
    (objPtr)->length   = 0; \
    (objPtr)->typePtr  = NULL; \
    TclIncrObjsAllocated()
     
#  define TclDecrRefCount(objPtr) \
    if (--(objPtr)->refCount <= 0) { \
	if ((objPtr)->refCount < -1) \
	    panic("Reference count for %lx was negative: %s line %d", \
		  (objPtr), __FILE__, __LINE__); \
	if (((objPtr)->bytes != NULL) \
		&& ((objPtr)->bytes != tclEmptyStringRep)) { \
	    ckfree((char *) (objPtr)->bytes); \
	} \
	if (((objPtr)->typePtr != NULL) \
		&& ((objPtr)->typePtr->freeIntRepProc != NULL)) { \
	    (objPtr)->typePtr->freeIntRepProc(objPtr); \
	} \
	ckfree((char *) (objPtr)); \
	TclIncrObjsFreed(); \
    }

#else /* not TCL_MEM_DEBUG */

#ifdef TCL_THREADS
extern Tcl_Mutex tclObjMutex;
#endif

#  define TclNewObj(objPtr) \
    Tcl_MutexLock(&tclObjMutex); \
    if (tclFreeObjList == NULL) { \
	TclAllocateFreeObjects(); \
    } \
    (objPtr) = tclFreeObjList; \
    tclFreeObjList = (Tcl_Obj *) \
	tclFreeObjList->internalRep.otherValuePtr; \
    (objPtr)->refCount = 0; \
    (objPtr)->bytes    = tclEmptyStringRep; \
    (objPtr)->length   = 0; \
    (objPtr)->typePtr  = NULL; \
    TclIncrObjsAllocated(); \
    Tcl_MutexUnlock(&tclObjMutex)

#  define TclDecrRefCount(objPtr) \
    if (--(objPtr)->refCount <= 0) { \
	if (((objPtr)->bytes != NULL) \
		&& ((objPtr)->bytes != tclEmptyStringRep)) { \
	    ckfree((char *) (objPtr)->bytes); \
	} \
	if (((objPtr)->typePtr != NULL) \
		&& ((objPtr)->typePtr->freeIntRepProc != NULL)) { \
	    (objPtr)->typePtr->freeIntRepProc(objPtr); \
	} \
	Tcl_MutexLock(&tclObjMutex); \
	(objPtr)->internalRep.otherValuePtr = (VOID *) tclFreeObjList; \
	tclFreeObjList = (objPtr); \
	TclIncrObjsFreed(); \
	Tcl_MutexUnlock(&tclObjMutex); \
    }
#endif /* TCL_MEM_DEBUG */

/*
 *----------------------------------------------------------------
 * Macro used by the Tcl core to set a Tcl_Obj's string representation
 * to a copy of the "len" bytes starting at "bytePtr". This code
 * works even if the byte array contains NULLs as long as the length
 * is correct. Because "len" is referenced multiple times, it should
 * be as simple an expression as possible. The ANSI C "prototype" for
 * this macro is:
 *
 * EXTERN void	TclInitStringRep _ANSI_ARGS_((Tcl_Obj *objPtr,
 *		    char *bytePtr, int len));
 *----------------------------------------------------------------
 */

#define TclInitStringRep(objPtr, bytePtr, len) \
    if ((len) == 0) { \
	(objPtr)->bytes	 = tclEmptyStringRep; \
	(objPtr)->length = 0; \
    } else { \
	(objPtr)->bytes = (char *) ckalloc((unsigned) ((len) + 1)); \
	memcpy((VOID *) (objPtr)->bytes, (VOID *) (bytePtr), \
		(unsigned) (len)); \
	(objPtr)->bytes[len] = '\0'; \
	(objPtr)->length = (len); \
    }

/*
 *----------------------------------------------------------------
 * Macro used by the Tcl core to get the string representation's
 * byte array pointer from a Tcl_Obj. This is an inline version


 * of Tcl_GetString(). The macro's expression result is the string
 * rep's byte pointer which might be NULL. The bytes referenced by 
 * this pointer must not be modified by the caller.
 * The ANSI C "prototype" for this macro is:
 *
 * EXTERN char *  TclGetString _ANSI_ARGS_((Tcl_Obj *objPtr));

 *----------------------------------------------------------------
 */









































#define TclGetString(objPtr) \
    ((objPtr)->bytes? (objPtr)->bytes : Tcl_GetString((objPtr)))







#include "tclIntDecls.h"










































# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT

#endif /* _TCLINT */

Added generic/tclIntDecls.h.





























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
/*
 * 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.3.2.7 1999/04/06 03:13:17 redman Exp $
 */

#ifndef _TCLINTDECLS
#define _TCLINTDECLS

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tclInt.decls script.
 */

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

/*
 * Exported function declarations:
 */

/* 0 */
EXTERN int		TclAccess _ANSI_ARGS_((CONST char * path, int mode));
/* 1 */
EXTERN int		TclAccessDeleteProc _ANSI_ARGS_((
				TclAccessProc_ * proc));
/* 2 */
EXTERN int		TclAccessInsertProc _ANSI_ARGS_((
				TclAccessProc_ * proc));
/* 3 */
EXTERN void		TclAllocateFreeObjects _ANSI_ARGS_((void));
/* Slot 4 is reserved */
/* 5 */
EXTERN int		TclCleanupChildren _ANSI_ARGS_((Tcl_Interp * interp, 
				int numPids, Tcl_Pid * pidPtr, 
				Tcl_Channel errorChan));
/* 6 */
EXTERN void		TclCleanupCommand _ANSI_ARGS_((Command * cmdPtr));
/* 7 */
EXTERN int		TclCopyAndCollapse _ANSI_ARGS_((int count, 
				CONST char * src, char * dst));
/* 8 */
EXTERN int		TclCopyChannel _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Channel inChan, Tcl_Channel outChan, 
				int toRead, Tcl_Obj * cmdPtr));
/* 9 */
EXTERN int		TclCreatePipeline _ANSI_ARGS_((Tcl_Interp * interp, 
				int argc, char ** argv, 
				Tcl_Pid ** pidArrayPtr, TclFile * inPipePtr, 
				TclFile * outPipePtr, TclFile * errFilePtr));
/* 10 */
EXTERN int		TclCreateProc _ANSI_ARGS_((Tcl_Interp * interp, 
				Namespace * nsPtr, char * procName, 
				Tcl_Obj * argsPtr, Tcl_Obj * bodyPtr, 
				Proc ** procPtrPtr));
/* 11 */
EXTERN void		TclDeleteCompiledLocalVars _ANSI_ARGS_((
				Interp * iPtr, CallFrame * framePtr));
/* 12 */
EXTERN void		TclDeleteVars _ANSI_ARGS_((Interp * iPtr, 
				Tcl_HashTable * tablePtr));
/* 13 */
EXTERN int		TclDoGlob _ANSI_ARGS_((Tcl_Interp * interp, 
				char * separators, Tcl_DString * headPtr, 
				char * tail));
/* 14 */
EXTERN void		TclDumpMemoryInfo _ANSI_ARGS_((FILE * outFile));
/* Slot 15 is reserved */
/* 16 */
EXTERN void		TclExprFloatError _ANSI_ARGS_((Tcl_Interp * interp, 
				double value));
/* 17 */
EXTERN int		TclFileAttrsCmd _ANSI_ARGS_((Tcl_Interp * interp, 
				int objc, Tcl_Obj *CONST objv[]));
/* 18 */
EXTERN int		TclFileCopyCmd _ANSI_ARGS_((Tcl_Interp * interp, 
				int argc, char ** argv));
/* 19 */
EXTERN int		TclFileDeleteCmd _ANSI_ARGS_((Tcl_Interp * interp, 
				int argc, char ** argv));
/* 20 */
EXTERN int		TclFileMakeDirsCmd _ANSI_ARGS_((Tcl_Interp * interp, 
				int argc, char ** argv));
/* 21 */
EXTERN int		TclFileRenameCmd _ANSI_ARGS_((Tcl_Interp * interp, 
				int argc, char ** argv));
/* 22 */
EXTERN int		TclFindElement _ANSI_ARGS_((Tcl_Interp * interp, 
				CONST char * listStr, int listLength, 
				CONST char ** elementPtr, 
				CONST char ** nextPtr, int * sizePtr, 
				int * bracePtr));
/* 23 */
EXTERN Proc *		TclFindProc _ANSI_ARGS_((Interp * iPtr, 
				char * procName));
/* 24 */
EXTERN int		TclFormatInt _ANSI_ARGS_((char * buffer, long n));
/* 25 */
EXTERN void		TclFreePackageInfo _ANSI_ARGS_((Interp * iPtr));
/* Slot 26 is reserved */
/* 27 */
EXTERN int		TclGetDate _ANSI_ARGS_((char * p, unsigned long now, 
				long zone, unsigned long * timePtr));
/* 28 */
EXTERN Tcl_Channel	TclpGetDefaultStdChannel _ANSI_ARGS_((int type));
/* 29 */
EXTERN Tcl_Obj *	TclGetElementOfIndexedArray _ANSI_ARGS_((
				Tcl_Interp * interp, int localIndex, 
				Tcl_Obj * elemPtr, int leaveErrorMsg));
/* Slot 30 is reserved */
/* 31 */
EXTERN char *		TclGetExtension _ANSI_ARGS_((char * name));
/* 32 */
EXTERN int		TclGetFrame _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, CallFrame ** framePtrPtr));
/* 33 */
EXTERN TclCmdProcType	TclGetInterpProc _ANSI_ARGS_((void));
/* 34 */
EXTERN int		TclGetIntForIndex _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * objPtr, int endValue, 
				int * indexPtr));
/* 35 */
EXTERN Tcl_Obj *	TclGetIndexedScalar _ANSI_ARGS_((Tcl_Interp * interp, 
				int localIndex, int leaveErrorMsg));
/* 36 */
EXTERN int		TclGetLong _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, long * longPtr));
/* 37 */
EXTERN int		TclGetLoadedPackages _ANSI_ARGS_((
				Tcl_Interp * interp, char * targetName));
/* 38 */
EXTERN int		TclGetNamespaceForQualName _ANSI_ARGS_((
				Tcl_Interp * interp, char * qualName, 
				Namespace * cxtNsPtr, int flags, 
				Namespace ** nsPtrPtr, 
				Namespace ** altNsPtrPtr, 
				Namespace ** actualCxtPtrPtr, 
				char ** simpleNamePtr));
/* 39 */
EXTERN TclObjCmdProcType TclGetObjInterpProc _ANSI_ARGS_((void));
/* 40 */
EXTERN int		TclGetOpenMode _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, int * seekFlagPtr));
/* 41 */
EXTERN Tcl_Command	TclGetOriginalCommand _ANSI_ARGS_((
				Tcl_Command command));
/* 42 */
EXTERN char *		TclpGetUserHome _ANSI_ARGS_((CONST char * name, 
				Tcl_DString * bufferPtr));
/* 43 */
EXTERN int		TclGlobalInvoke _ANSI_ARGS_((Tcl_Interp * interp, 
				int argc, char ** argv, int flags));
/* 44 */
EXTERN int		TclGuessPackageName _ANSI_ARGS_((char * fileName, 
				Tcl_DString * bufPtr));
/* 45 */
EXTERN int		TclHideUnsafeCommands _ANSI_ARGS_((
				Tcl_Interp * interp));
/* 46 */
EXTERN int		TclInExit _ANSI_ARGS_((void));
/* 47 */
EXTERN Tcl_Obj *	TclIncrElementOfIndexedArray _ANSI_ARGS_((
				Tcl_Interp * interp, int localIndex, 
				Tcl_Obj * elemPtr, long incrAmount));
/* 48 */
EXTERN Tcl_Obj *	TclIncrIndexedScalar _ANSI_ARGS_((
				Tcl_Interp * interp, int localIndex, 
				long incrAmount));
/* 49 */
EXTERN Tcl_Obj *	TclIncrVar2 _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj * part1Ptr, Tcl_Obj * part2Ptr, 
				long incrAmount, int part1NotParsed));
/* 50 */
EXTERN void		TclInitCompiledLocals _ANSI_ARGS_((
				Tcl_Interp * interp, CallFrame * framePtr, 
				Namespace * nsPtr));
/* 51 */
EXTERN int		TclInterpInit _ANSI_ARGS_((Tcl_Interp * interp));
/* 52 */
EXTERN int		TclInvoke _ANSI_ARGS_((Tcl_Interp * interp, int argc, 
				char ** argv, int flags));
/* 53 */
EXTERN int		TclInvokeObjectCommand _ANSI_ARGS_((
				ClientData clientData, Tcl_Interp * interp, 
				int argc, char ** argv));
/* 54 */
EXTERN int		TclInvokeStringCommand _ANSI_ARGS_((
				ClientData clientData, Tcl_Interp * interp, 
				int objc, Tcl_Obj *CONST objv[]));
/* 55 */
EXTERN Proc *		TclIsProc _ANSI_ARGS_((Command * cmdPtr));
/* Slot 56 is reserved */
/* Slot 57 is reserved */
/* 58 */
EXTERN Var *		TclLookupVar _ANSI_ARGS_((Tcl_Interp * interp, 
				char * part1, char * part2, int flags, 
				char * msg, int createPart1, int createPart2, 
				Var ** arrayPtrPtr));
/* 59 */
EXTERN int		TclpMatchFiles _ANSI_ARGS_((Tcl_Interp * interp, 
				char * separators, Tcl_DString * dirPtr, 
				char * pattern, char * tail));
/* 60 */
EXTERN int		TclNeedSpace _ANSI_ARGS_((char * start, char * end));
/* 61 */
EXTERN Tcl_Obj *	TclNewProcBodyObj _ANSI_ARGS_((Proc * procPtr));
/* 62 */
EXTERN int		TclObjCommandComplete _ANSI_ARGS_((Tcl_Obj * cmdPtr));
/* 63 */
EXTERN int		TclObjInterpProc _ANSI_ARGS_((ClientData clientData, 
				Tcl_Interp * interp, int objc, 
				Tcl_Obj *CONST objv[]));
/* 64 */
EXTERN int		TclObjInvoke _ANSI_ARGS_((Tcl_Interp * interp, 
				int objc, Tcl_Obj *CONST objv[], int flags));
/* 65 */
EXTERN int		TclObjInvokeGlobal _ANSI_ARGS_((Tcl_Interp * interp, 
				int objc, Tcl_Obj *CONST objv[], int flags));
/* 66 */
EXTERN int		TclOpenFileChannelDeleteProc _ANSI_ARGS_((
				TclOpenFileChannelProc_ * proc));
/* 67 */
EXTERN int		TclOpenFileChannelInsertProc _ANSI_ARGS_((
				TclOpenFileChannelProc_ * proc));
/* 68 */
EXTERN int		TclpAccess _ANSI_ARGS_((CONST char * path, int mode));
/* 69 */
EXTERN char *		TclpAlloc _ANSI_ARGS_((unsigned int size));
/* 70 */
EXTERN int		TclpCopyFile _ANSI_ARGS_((CONST char * source, 
				CONST char * dest));
/* 71 */
EXTERN int		TclpCopyDirectory _ANSI_ARGS_((CONST char * source, 
				CONST char * dest, Tcl_DString * errorPtr));
/* 72 */
EXTERN int		TclpCreateDirectory _ANSI_ARGS_((CONST char * path));
/* 73 */
EXTERN int		TclpDeleteFile _ANSI_ARGS_((CONST char * path));
/* 74 */
EXTERN void		TclpFree _ANSI_ARGS_((char * ptr));
/* 75 */
EXTERN unsigned long	TclpGetClicks _ANSI_ARGS_((void));
/* 76 */
EXTERN unsigned long	TclpGetSeconds _ANSI_ARGS_((void));
/* 77 */
EXTERN void		TclpGetTime _ANSI_ARGS_((Tcl_Time * time));
/* 78 */
EXTERN int		TclpGetTimeZone _ANSI_ARGS_((unsigned long time));
/* 79 */
EXTERN int		TclpListVolumes _ANSI_ARGS_((Tcl_Interp * interp));
/* 80 */
EXTERN Tcl_Channel	TclpOpenFileChannel _ANSI_ARGS_((Tcl_Interp * interp, 
				char * fileName, char * modeString, 
				int permissions));
/* 81 */
EXTERN char *		TclpRealloc _ANSI_ARGS_((char * ptr, 
				unsigned int size));
/* 82 */
EXTERN int		TclpRemoveDirectory _ANSI_ARGS_((CONST char * path, 
				int recursive, Tcl_DString * errorPtr));
/* 83 */
EXTERN int		TclpRenameFile _ANSI_ARGS_((CONST char * source, 
				CONST char * dest));
/* Slot 84 is reserved */
/* Slot 85 is reserved */
/* Slot 86 is reserved */
/* Slot 87 is reserved */
/* 88 */
EXTERN char *		TclPrecTraceProc _ANSI_ARGS_((ClientData clientData, 
				Tcl_Interp * interp, char * name1, 
				char * name2, int flags));
/* 89 */
EXTERN int		TclPreventAliasLoop _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Interp * cmdInterp, Tcl_Command cmd));
/* Slot 90 is reserved */
/* 91 */
EXTERN void		TclProcCleanupProc _ANSI_ARGS_((Proc * procPtr));
/* 92 */
EXTERN int		TclProcCompileProc _ANSI_ARGS_((Tcl_Interp * interp, 
				Proc * procPtr, Tcl_Obj * bodyPtr, 
				Namespace * nsPtr, CONST char * description, 
				CONST char * procName));
/* 93 */
EXTERN void		TclProcDeleteProc _ANSI_ARGS_((ClientData clientData));
/* 94 */
EXTERN int		TclProcInterpProc _ANSI_ARGS_((ClientData clientData, 
				Tcl_Interp * interp, int argc, char ** argv));
/* 95 */
EXTERN int		TclpStat _ANSI_ARGS_((CONST char * path, 
				struct stat * buf));
/* 96 */
EXTERN int		TclRenameCommand _ANSI_ARGS_((Tcl_Interp * interp, 
				char * oldName, char * newName));
/* 97 */
EXTERN void		TclResetShadowedCmdRefs _ANSI_ARGS_((
				Tcl_Interp * interp, Command * newCmdPtr));
/* 98 */
EXTERN int		TclServiceIdle _ANSI_ARGS_((void));
/* 99 */
EXTERN Tcl_Obj *	TclSetElementOfIndexedArray _ANSI_ARGS_((
				Tcl_Interp * interp, int localIndex, 
				Tcl_Obj * elemPtr, Tcl_Obj * objPtr, 
				int leaveErrorMsg));
/* 100 */
EXTERN Tcl_Obj *	TclSetIndexedScalar _ANSI_ARGS_((Tcl_Interp * interp, 
				int localIndex, Tcl_Obj * objPtr, 
				int leaveErrorMsg));
/* Slot 101 is reserved */
/* 102 */
EXTERN void		TclSetupEnv _ANSI_ARGS_((Tcl_Interp * interp));
/* 103 */
EXTERN int		TclSockGetPort _ANSI_ARGS_((Tcl_Interp * interp, 
				char * str, char * proto, int * portPtr));
/* 104 */
EXTERN int		TclSockMinimumBuffers _ANSI_ARGS_((int sock, 
				int size));
/* 105 */
EXTERN int		TclStat _ANSI_ARGS_((CONST char * path, 
				TclStat_ * buf));
/* 106 */
EXTERN int		TclStatDeleteProc _ANSI_ARGS_((TclStatProc_ * proc));
/* 107 */
EXTERN int		TclStatInsertProc _ANSI_ARGS_((TclStatProc_ * proc));
/* 108 */
EXTERN void		TclTeardownNamespace _ANSI_ARGS_((Namespace * nsPtr));
/* 109 */
EXTERN int		TclUpdateReturnInfo _ANSI_ARGS_((Interp * iPtr));
/* Slot 110 is reserved */
/* 111 */
EXTERN void		Tcl_AddInterpResolvers _ANSI_ARGS_((
				Tcl_Interp * interp, char * name, 
				Tcl_ResolveCmdProc * cmdProc, 
				Tcl_ResolveVarProc * varProc, 
				Tcl_ResolveCompiledVarProc * compiledVarProc));
/* 112 */
EXTERN int		Tcl_AppendExportList _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Namespace * nsPtr, 
				Tcl_Obj * objPtr));
/* 113 */
EXTERN Tcl_Namespace *	Tcl_CreateNamespace _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, ClientData clientData, 
				Tcl_NamespaceDeleteProc * deleteProc));
/* 114 */
EXTERN void		Tcl_DeleteNamespace _ANSI_ARGS_((
				Tcl_Namespace * nsPtr));
/* 115 */
EXTERN int		Tcl_Export _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Namespace * nsPtr, char * pattern, 
				int resetListFirst));
/* 116 */
EXTERN Tcl_Command	Tcl_FindCommand _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, Tcl_Namespace * contextNsPtr, 
				int flags));
/* 117 */
EXTERN Tcl_Namespace *	Tcl_FindNamespace _ANSI_ARGS_((Tcl_Interp * interp, 
				char * name, Tcl_Namespace * contextNsPtr, 
				int flags));
/* 118 */
EXTERN int		Tcl_GetInterpResolvers _ANSI_ARGS_((
				Tcl_Interp * interp, char * name, 
				Tcl_ResolverInfo * resInfo));
/* 119 */
EXTERN int		Tcl_GetNamespaceResolvers _ANSI_ARGS_((
				Tcl_Namespace * namespacePtr, 
				Tcl_ResolverInfo * resInfo));
/* 120 */
EXTERN Tcl_Var		Tcl_FindNamespaceVar _ANSI_ARGS_((
				Tcl_Interp * interp, char * name, 
				Tcl_Namespace * contextNsPtr, int flags));
/* 121 */
EXTERN int		Tcl_ForgetImport _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Namespace * nsPtr, char * pattern));
/* 122 */
EXTERN Tcl_Command	Tcl_GetCommandFromObj _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * objPtr));
/* 123 */
EXTERN void		Tcl_GetCommandFullName _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Command command, 
				Tcl_Obj * objPtr));
/* 124 */
EXTERN Tcl_Namespace *	Tcl_GetCurrentNamespace _ANSI_ARGS_((
				Tcl_Interp * interp));
/* 125 */
EXTERN Tcl_Namespace *	Tcl_GetGlobalNamespace _ANSI_ARGS_((
				Tcl_Interp * interp));
/* 126 */
EXTERN void		Tcl_GetVariableFullName _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Var variable, 
				Tcl_Obj * objPtr));
/* 127 */
EXTERN int		Tcl_Import _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Namespace * nsPtr, char * pattern, 
				int allowOverwrite));
/* 128 */
EXTERN void		Tcl_PopCallFrame _ANSI_ARGS_((Tcl_Interp* interp));
/* 129 */
EXTERN int		Tcl_PushCallFrame _ANSI_ARGS_((Tcl_Interp* interp, 
				Tcl_CallFrame * framePtr, 
				Tcl_Namespace * nsPtr, int isProcCallFrame));
/* 130 */
EXTERN int		Tcl_RemoveInterpResolvers _ANSI_ARGS_((
				Tcl_Interp * interp, char * name));
/* 131 */
EXTERN void		Tcl_SetNamespaceResolvers _ANSI_ARGS_((
				Tcl_Namespace * namespacePtr, 
				Tcl_ResolveCmdProc * cmdProc, 
				Tcl_ResolveVarProc * varProc, 
				Tcl_ResolveCompiledVarProc * compiledVarProc));
/* 132 */
EXTERN int		TclpHasSockets _ANSI_ARGS_((Tcl_Interp * interp));
/* 133 */
EXTERN struct tm *	TclpGetDate _ANSI_ARGS_((TclpTime_t time, int useGMT));
/* 134 */
EXTERN size_t		TclpStrftime _ANSI_ARGS_((char * s, size_t maxsize, 
				CONST char * format, CONST struct tm * t));
/* 135 */
EXTERN int		TclpCheckStackSpace _ANSI_ARGS_((void));
/* Slot 136 is reserved */
/* 137 */
EXTERN int		TclpChdir _ANSI_ARGS_((CONST char * dirName));
/* 138 */
EXTERN char *		TclGetEnv _ANSI_ARGS_((CONST char * name, 
				Tcl_DString * valuePtr));
/* 139 */
EXTERN int		TclpLoadFile _ANSI_ARGS_((Tcl_Interp * interp, 
				char * fileName, char * sym1, char * sym2, 
				Tcl_PackageInitProc ** proc1Ptr, 
				Tcl_PackageInitProc ** proc2Ptr, 
				ClientData * clientDataPtr));
/* 140 */
EXTERN int		TclLooksLikeInt _ANSI_ARGS_((char * bytes, 
				int length));
/* 141 */
EXTERN char *		TclpGetCwd _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_DString * cwdPtr));

typedef struct TclIntStubs {
    int magic;
    struct TclIntStubHooks *hooks;

    int (*tclAccess) _ANSI_ARGS_((CONST char * path, int mode)); /* 0 */
    int (*tclAccessDeleteProc) _ANSI_ARGS_((TclAccessProc_ * proc)); /* 1 */
    int (*tclAccessInsertProc) _ANSI_ARGS_((TclAccessProc_ * proc)); /* 2 */
    void (*tclAllocateFreeObjects) _ANSI_ARGS_((void)); /* 3 */
    void *reserved4;
    int (*tclCleanupChildren) _ANSI_ARGS_((Tcl_Interp * interp, int numPids, Tcl_Pid * pidPtr, Tcl_Channel errorChan)); /* 5 */
    void (*tclCleanupCommand) _ANSI_ARGS_((Command * cmdPtr)); /* 6 */
    int (*tclCopyAndCollapse) _ANSI_ARGS_((int count, CONST char * src, char * dst)); /* 7 */
    int (*tclCopyChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel inChan, Tcl_Channel outChan, int toRead, Tcl_Obj * cmdPtr)); /* 8 */
    int (*tclCreatePipeline) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv, Tcl_Pid ** pidArrayPtr, TclFile * inPipePtr, TclFile * outPipePtr, TclFile * errFilePtr)); /* 9 */
    int (*tclCreateProc) _ANSI_ARGS_((Tcl_Interp * interp, Namespace * nsPtr, char * procName, Tcl_Obj * argsPtr, Tcl_Obj * bodyPtr, Proc ** procPtrPtr)); /* 10 */
    void (*tclDeleteCompiledLocalVars) _ANSI_ARGS_((Interp * iPtr, CallFrame * framePtr)); /* 11 */
    void (*tclDeleteVars) _ANSI_ARGS_((Interp * iPtr, Tcl_HashTable * tablePtr)); /* 12 */
    int (*tclDoGlob) _ANSI_ARGS_((Tcl_Interp * interp, char * separators, Tcl_DString * headPtr, char * tail)); /* 13 */
    void (*tclDumpMemoryInfo) _ANSI_ARGS_((FILE * outFile)); /* 14 */
    void *reserved15;
    void (*tclExprFloatError) _ANSI_ARGS_((Tcl_Interp * interp, double value)); /* 16 */
    int (*tclFileAttrsCmd) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 17 */
    int (*tclFileCopyCmd) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv)); /* 18 */
    int (*tclFileDeleteCmd) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv)); /* 19 */
    int (*tclFileMakeDirsCmd) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv)); /* 20 */
    int (*tclFileRenameCmd) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv)); /* 21 */
    int (*tclFindElement) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * listStr, int listLength, CONST char ** elementPtr, CONST char ** nextPtr, int * sizePtr, int * bracePtr)); /* 22 */
    Proc * (*tclFindProc) _ANSI_ARGS_((Interp * iPtr, char * procName)); /* 23 */
    int (*tclFormatInt) _ANSI_ARGS_((char * buffer, long n)); /* 24 */
    void (*tclFreePackageInfo) _ANSI_ARGS_((Interp * iPtr)); /* 25 */
    void *reserved26;
    int (*tclGetDate) _ANSI_ARGS_((char * p, unsigned long now, long zone, unsigned long * timePtr)); /* 27 */
    Tcl_Channel (*tclpGetDefaultStdChannel) _ANSI_ARGS_((int type)); /* 28 */
    Tcl_Obj * (*tclGetElementOfIndexedArray) _ANSI_ARGS_((Tcl_Interp * interp, int localIndex, Tcl_Obj * elemPtr, int leaveErrorMsg)); /* 29 */
    void *reserved30;
    char * (*tclGetExtension) _ANSI_ARGS_((char * name)); /* 31 */
    int (*tclGetFrame) _ANSI_ARGS_((Tcl_Interp * interp, char * str, CallFrame ** framePtrPtr)); /* 32 */
    TclCmdProcType (*tclGetInterpProc) _ANSI_ARGS_((void)); /* 33 */
    int (*tclGetIntForIndex) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, int endValue, int * indexPtr)); /* 34 */
    Tcl_Obj * (*tclGetIndexedScalar) _ANSI_ARGS_((Tcl_Interp * interp, int localIndex, int leaveErrorMsg)); /* 35 */
    int (*tclGetLong) _ANSI_ARGS_((Tcl_Interp * interp, char * str, long * longPtr)); /* 36 */
    int (*tclGetLoadedPackages) _ANSI_ARGS_((Tcl_Interp * interp, char * targetName)); /* 37 */
    int (*tclGetNamespaceForQualName) _ANSI_ARGS_((Tcl_Interp * interp, char * qualName, Namespace * cxtNsPtr, int flags, Namespace ** nsPtrPtr, Namespace ** altNsPtrPtr, Namespace ** actualCxtPtrPtr, char ** simpleNamePtr)); /* 38 */
    TclObjCmdProcType (*tclGetObjInterpProc) _ANSI_ARGS_((void)); /* 39 */
    int (*tclGetOpenMode) _ANSI_ARGS_((Tcl_Interp * interp, char * str, int * seekFlagPtr)); /* 40 */
    Tcl_Command (*tclGetOriginalCommand) _ANSI_ARGS_((Tcl_Command command)); /* 41 */
    char * (*tclpGetUserHome) _ANSI_ARGS_((CONST char * name, Tcl_DString * bufferPtr)); /* 42 */
    int (*tclGlobalInvoke) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv, int flags)); /* 43 */
    int (*tclGuessPackageName) _ANSI_ARGS_((char * fileName, Tcl_DString * bufPtr)); /* 44 */
    int (*tclHideUnsafeCommands) _ANSI_ARGS_((Tcl_Interp * interp)); /* 45 */
    int (*tclInExit) _ANSI_ARGS_((void)); /* 46 */
    Tcl_Obj * (*tclIncrElementOfIndexedArray) _ANSI_ARGS_((Tcl_Interp * interp, int localIndex, Tcl_Obj * elemPtr, long incrAmount)); /* 47 */
    Tcl_Obj * (*tclIncrIndexedScalar) _ANSI_ARGS_((Tcl_Interp * interp, int localIndex, long incrAmount)); /* 48 */
    Tcl_Obj * (*tclIncrVar2) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * part1Ptr, Tcl_Obj * part2Ptr, long incrAmount, int part1NotParsed)); /* 49 */
    void (*tclInitCompiledLocals) _ANSI_ARGS_((Tcl_Interp * interp, CallFrame * framePtr, Namespace * nsPtr)); /* 50 */
    int (*tclInterpInit) _ANSI_ARGS_((Tcl_Interp * interp)); /* 51 */
    int (*tclInvoke) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv, int flags)); /* 52 */
    int (*tclInvokeObjectCommand) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char ** argv)); /* 53 */
    int (*tclInvokeStringCommand) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 54 */
    Proc * (*tclIsProc) _ANSI_ARGS_((Command * cmdPtr)); /* 55 */
    void *reserved56;
    void *reserved57;
    Var * (*tclLookupVar) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags, char * msg, int createPart1, int createPart2, Var ** arrayPtrPtr)); /* 58 */
    int (*tclpMatchFiles) _ANSI_ARGS_((Tcl_Interp * interp, char * separators, Tcl_DString * dirPtr, char * pattern, char * tail)); /* 59 */
    int (*tclNeedSpace) _ANSI_ARGS_((char * start, char * end)); /* 60 */
    Tcl_Obj * (*tclNewProcBodyObj) _ANSI_ARGS_((Proc * procPtr)); /* 61 */
    int (*tclObjCommandComplete) _ANSI_ARGS_((Tcl_Obj * cmdPtr)); /* 62 */
    int (*tclObjInterpProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 63 */
    int (*tclObjInvoke) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[], int flags)); /* 64 */
    int (*tclObjInvokeGlobal) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[], int flags)); /* 65 */
    int (*tclOpenFileChannelDeleteProc) _ANSI_ARGS_((TclOpenFileChannelProc_ * proc)); /* 66 */
    int (*tclOpenFileChannelInsertProc) _ANSI_ARGS_((TclOpenFileChannelProc_ * proc)); /* 67 */
    int (*tclpAccess) _ANSI_ARGS_((CONST char * path, int mode)); /* 68 */
    char * (*tclpAlloc) _ANSI_ARGS_((unsigned int size)); /* 69 */
    int (*tclpCopyFile) _ANSI_ARGS_((CONST char * source, CONST char * dest)); /* 70 */
    int (*tclpCopyDirectory) _ANSI_ARGS_((CONST char * source, CONST char * dest, Tcl_DString * errorPtr)); /* 71 */
    int (*tclpCreateDirectory) _ANSI_ARGS_((CONST char * path)); /* 72 */
    int (*tclpDeleteFile) _ANSI_ARGS_((CONST char * path)); /* 73 */
    void (*tclpFree) _ANSI_ARGS_((char * ptr)); /* 74 */
    unsigned long (*tclpGetClicks) _ANSI_ARGS_((void)); /* 75 */
    unsigned long (*tclpGetSeconds) _ANSI_ARGS_((void)); /* 76 */
    void (*tclpGetTime) _ANSI_ARGS_((Tcl_Time * time)); /* 77 */
    int (*tclpGetTimeZone) _ANSI_ARGS_((unsigned long time)); /* 78 */
    int (*tclpListVolumes) _ANSI_ARGS_((Tcl_Interp * interp)); /* 79 */
    Tcl_Channel (*tclpOpenFileChannel) _ANSI_ARGS_((Tcl_Interp * interp, char * fileName, char * modeString, int permissions)); /* 80 */
    char * (*tclpRealloc) _ANSI_ARGS_((char * ptr, unsigned int size)); /* 81 */
    int (*tclpRemoveDirectory) _ANSI_ARGS_((CONST char * path, int recursive, Tcl_DString * errorPtr)); /* 82 */
    int (*tclpRenameFile) _ANSI_ARGS_((CONST char * source, CONST char * dest)); /* 83 */
    void *reserved84;
    void *reserved85;
    void *reserved86;
    void *reserved87;
    char * (*tclPrecTraceProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, char * name1, char * name2, int flags)); /* 88 */
    int (*tclPreventAliasLoop) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Interp * cmdInterp, Tcl_Command cmd)); /* 89 */
    void *reserved90;
    void (*tclProcCleanupProc) _ANSI_ARGS_((Proc * procPtr)); /* 91 */
    int (*tclProcCompileProc) _ANSI_ARGS_((Tcl_Interp * interp, Proc * procPtr, Tcl_Obj * bodyPtr, Namespace * nsPtr, CONST char * description, CONST char * procName)); /* 92 */
    void (*tclProcDeleteProc) _ANSI_ARGS_((ClientData clientData)); /* 93 */
    int (*tclProcInterpProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char ** argv)); /* 94 */
    int (*tclpStat) _ANSI_ARGS_((CONST char * path, struct stat * buf)); /* 95 */
    int (*tclRenameCommand) _ANSI_ARGS_((Tcl_Interp * interp, char * oldName, char * newName)); /* 96 */
    void (*tclResetShadowedCmdRefs) _ANSI_ARGS_((Tcl_Interp * interp, Command * newCmdPtr)); /* 97 */
    int (*tclServiceIdle) _ANSI_ARGS_((void)); /* 98 */
    Tcl_Obj * (*tclSetElementOfIndexedArray) _ANSI_ARGS_((Tcl_Interp * interp, int localIndex, Tcl_Obj * elemPtr, Tcl_Obj * objPtr, int leaveErrorMsg)); /* 99 */
    Tcl_Obj * (*tclSetIndexedScalar) _ANSI_ARGS_((Tcl_Interp * interp, int localIndex, Tcl_Obj * objPtr, int leaveErrorMsg)); /* 100 */
    void *reserved101;
    void (*tclSetupEnv) _ANSI_ARGS_((Tcl_Interp * interp)); /* 102 */
    int (*tclSockGetPort) _ANSI_ARGS_((Tcl_Interp * interp, char * str, char * proto, int * portPtr)); /* 103 */
    int (*tclSockMinimumBuffers) _ANSI_ARGS_((int sock, int size)); /* 104 */
    int (*tclStat) _ANSI_ARGS_((CONST char * path, TclStat_ * buf)); /* 105 */
    int (*tclStatDeleteProc) _ANSI_ARGS_((TclStatProc_ * proc)); /* 106 */
    int (*tclStatInsertProc) _ANSI_ARGS_((TclStatProc_ * proc)); /* 107 */
    void (*tclTeardownNamespace) _ANSI_ARGS_((Namespace * nsPtr)); /* 108 */
    int (*tclUpdateReturnInfo) _ANSI_ARGS_((Interp * iPtr)); /* 109 */
    void *reserved110;
    void (*tcl_AddInterpResolvers) _ANSI_ARGS_((Tcl_Interp * interp, char * name, Tcl_ResolveCmdProc * cmdProc, Tcl_ResolveVarProc * varProc, Tcl_ResolveCompiledVarProc * compiledVarProc)); /* 111 */
    int (*tcl_AppendExportList) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Namespace * nsPtr, Tcl_Obj * objPtr)); /* 112 */
    Tcl_Namespace * (*tcl_CreateNamespace) _ANSI_ARGS_((Tcl_Interp * interp, char * name, ClientData clientData, Tcl_NamespaceDeleteProc * deleteProc)); /* 113 */
    void (*tcl_DeleteNamespace) _ANSI_ARGS_((Tcl_Namespace * nsPtr)); /* 114 */
    int (*tcl_Export) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Namespace * nsPtr, char * pattern, int resetListFirst)); /* 115 */
    Tcl_Command (*tcl_FindCommand) _ANSI_ARGS_((Tcl_Interp * interp, char * name, Tcl_Namespace * contextNsPtr, int flags)); /* 116 */
    Tcl_Namespace * (*tcl_FindNamespace) _ANSI_ARGS_((Tcl_Interp * interp, char * name, Tcl_Namespace * contextNsPtr, int flags)); /* 117 */
    int (*tcl_GetInterpResolvers) _ANSI_ARGS_((Tcl_Interp * interp, char * name, Tcl_ResolverInfo * resInfo)); /* 118 */
    int (*tcl_GetNamespaceResolvers) _ANSI_ARGS_((Tcl_Namespace * namespacePtr, Tcl_ResolverInfo * resInfo)); /* 119 */
    Tcl_Var (*tcl_FindNamespaceVar) _ANSI_ARGS_((Tcl_Interp * interp, char * name, Tcl_Namespace * contextNsPtr, int flags)); /* 120 */
    int (*tcl_ForgetImport) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Namespace * nsPtr, char * pattern)); /* 121 */
    Tcl_Command (*tcl_GetCommandFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr)); /* 122 */
    void (*tcl_GetCommandFullName) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Command command, Tcl_Obj * objPtr)); /* 123 */
    Tcl_Namespace * (*tcl_GetCurrentNamespace) _ANSI_ARGS_((Tcl_Interp * interp)); /* 124 */
    Tcl_Namespace * (*tcl_GetGlobalNamespace) _ANSI_ARGS_((Tcl_Interp * interp)); /* 125 */
    void (*tcl_GetVariableFullName) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Var variable, Tcl_Obj * objPtr)); /* 126 */
    int (*tcl_Import) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Namespace * nsPtr, char * pattern, int allowOverwrite)); /* 127 */
    void (*tcl_PopCallFrame) _ANSI_ARGS_((Tcl_Interp* interp)); /* 128 */
    int (*tcl_PushCallFrame) _ANSI_ARGS_((Tcl_Interp* interp, Tcl_CallFrame * framePtr, Tcl_Namespace * nsPtr, int isProcCallFrame)); /* 129 */
    int (*tcl_RemoveInterpResolvers) _ANSI_ARGS_((Tcl_Interp * interp, char * name)); /* 130 */
    void (*tcl_SetNamespaceResolvers) _ANSI_ARGS_((Tcl_Namespace * namespacePtr, Tcl_ResolveCmdProc * cmdProc, Tcl_ResolveVarProc * varProc, Tcl_ResolveCompiledVarProc * compiledVarProc)); /* 131 */
    int (*tclpHasSockets) _ANSI_ARGS_((Tcl_Interp * interp)); /* 132 */
    struct tm * (*tclpGetDate) _ANSI_ARGS_((TclpTime_t time, int useGMT)); /* 133 */
    size_t (*tclpStrftime) _ANSI_ARGS_((char * s, size_t maxsize, CONST char * format, CONST struct tm * t)); /* 134 */
    int (*tclpCheckStackSpace) _ANSI_ARGS_((void)); /* 135 */
    void *reserved136;
    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:
 */

#ifndef TclAccess
#define TclAccess \
	(tclIntStubsPtr->tclAccess) /* 0 */
#endif
#ifndef TclAccessDeleteProc
#define TclAccessDeleteProc \
	(tclIntStubsPtr->tclAccessDeleteProc) /* 1 */
#endif
#ifndef TclAccessInsertProc
#define TclAccessInsertProc \
	(tclIntStubsPtr->tclAccessInsertProc) /* 2 */
#endif
#ifndef TclAllocateFreeObjects
#define TclAllocateFreeObjects \
	(tclIntStubsPtr->tclAllocateFreeObjects) /* 3 */
#endif
/* Slot 4 is reserved */
#ifndef TclCleanupChildren
#define TclCleanupChildren \
	(tclIntStubsPtr->tclCleanupChildren) /* 5 */
#endif
#ifndef TclCleanupCommand
#define TclCleanupCommand \
	(tclIntStubsPtr->tclCleanupCommand) /* 6 */
#endif
#ifndef TclCopyAndCollapse
#define TclCopyAndCollapse \
	(tclIntStubsPtr->tclCopyAndCollapse) /* 7 */
#endif
#ifndef TclCopyChannel
#define TclCopyChannel \
	(tclIntStubsPtr->tclCopyChannel) /* 8 */
#endif
#ifndef TclCreatePipeline
#define TclCreatePipeline \
	(tclIntStubsPtr->tclCreatePipeline) /* 9 */
#endif
#ifndef TclCreateProc
#define TclCreateProc \
	(tclIntStubsPtr->tclCreateProc) /* 10 */
#endif
#ifndef TclDeleteCompiledLocalVars
#define TclDeleteCompiledLocalVars \
	(tclIntStubsPtr->tclDeleteCompiledLocalVars) /* 11 */
#endif
#ifndef TclDeleteVars
#define TclDeleteVars \
	(tclIntStubsPtr->tclDeleteVars) /* 12 */
#endif
#ifndef TclDoGlob
#define TclDoGlob \
	(tclIntStubsPtr->tclDoGlob) /* 13 */
#endif
#ifndef TclDumpMemoryInfo
#define TclDumpMemoryInfo \
	(tclIntStubsPtr->tclDumpMemoryInfo) /* 14 */
#endif
/* Slot 15 is reserved */
#ifndef TclExprFloatError
#define TclExprFloatError \
	(tclIntStubsPtr->tclExprFloatError) /* 16 */
#endif
#ifndef TclFileAttrsCmd
#define TclFileAttrsCmd \
	(tclIntStubsPtr->tclFileAttrsCmd) /* 17 */
#endif
#ifndef TclFileCopyCmd
#define TclFileCopyCmd \
	(tclIntStubsPtr->tclFileCopyCmd) /* 18 */
#endif
#ifndef TclFileDeleteCmd
#define TclFileDeleteCmd \
	(tclIntStubsPtr->tclFileDeleteCmd) /* 19 */
#endif
#ifndef TclFileMakeDirsCmd
#define TclFileMakeDirsCmd \
	(tclIntStubsPtr->tclFileMakeDirsCmd) /* 20 */
#endif
#ifndef TclFileRenameCmd
#define TclFileRenameCmd \
	(tclIntStubsPtr->tclFileRenameCmd) /* 21 */
#endif
#ifndef TclFindElement
#define TclFindElement \
	(tclIntStubsPtr->tclFindElement) /* 22 */
#endif
#ifndef TclFindProc
#define TclFindProc \
	(tclIntStubsPtr->tclFindProc) /* 23 */
#endif
#ifndef TclFormatInt
#define TclFormatInt \
	(tclIntStubsPtr->tclFormatInt) /* 24 */
#endif
#ifndef TclFreePackageInfo
#define TclFreePackageInfo \
	(tclIntStubsPtr->tclFreePackageInfo) /* 25 */
#endif
/* Slot 26 is reserved */
#ifndef TclGetDate
#define TclGetDate \
	(tclIntStubsPtr->tclGetDate) /* 27 */
#endif
#ifndef TclpGetDefaultStdChannel
#define TclpGetDefaultStdChannel \
	(tclIntStubsPtr->tclpGetDefaultStdChannel) /* 28 */
#endif
#ifndef TclGetElementOfIndexedArray
#define TclGetElementOfIndexedArray \
	(tclIntStubsPtr->tclGetElementOfIndexedArray) /* 29 */
#endif
/* Slot 30 is reserved */
#ifndef TclGetExtension
#define TclGetExtension \
	(tclIntStubsPtr->tclGetExtension) /* 31 */
#endif
#ifndef TclGetFrame
#define TclGetFrame \
	(tclIntStubsPtr->tclGetFrame) /* 32 */
#endif
#ifndef TclGetInterpProc
#define TclGetInterpProc \
	(tclIntStubsPtr->tclGetInterpProc) /* 33 */
#endif
#ifndef TclGetIntForIndex
#define TclGetIntForIndex \
	(tclIntStubsPtr->tclGetIntForIndex) /* 34 */
#endif
#ifndef TclGetIndexedScalar
#define TclGetIndexedScalar \
	(tclIntStubsPtr->tclGetIndexedScalar) /* 35 */
#endif
#ifndef TclGetLong
#define TclGetLong \
	(tclIntStubsPtr->tclGetLong) /* 36 */
#endif
#ifndef TclGetLoadedPackages
#define TclGetLoadedPackages \
	(tclIntStubsPtr->tclGetLoadedPackages) /* 37 */
#endif
#ifndef TclGetNamespaceForQualName
#define TclGetNamespaceForQualName \
	(tclIntStubsPtr->tclGetNamespaceForQualName) /* 38 */
#endif
#ifndef TclGetObjInterpProc
#define TclGetObjInterpProc \
	(tclIntStubsPtr->tclGetObjInterpProc) /* 39 */
#endif
#ifndef TclGetOpenMode
#define TclGetOpenMode \
	(tclIntStubsPtr->tclGetOpenMode) /* 40 */
#endif
#ifndef TclGetOriginalCommand
#define TclGetOriginalCommand \
	(tclIntStubsPtr->tclGetOriginalCommand) /* 41 */
#endif
#ifndef TclpGetUserHome
#define TclpGetUserHome \
	(tclIntStubsPtr->tclpGetUserHome) /* 42 */
#endif
#ifndef TclGlobalInvoke
#define TclGlobalInvoke \
	(tclIntStubsPtr->tclGlobalInvoke) /* 43 */
#endif
#ifndef TclGuessPackageName
#define TclGuessPackageName \
	(tclIntStubsPtr->tclGuessPackageName) /* 44 */
#endif
#ifndef TclHideUnsafeCommands
#define TclHideUnsafeCommands \
	(tclIntStubsPtr->tclHideUnsafeCommands) /* 45 */
#endif
#ifndef TclInExit
#define TclInExit \
	(tclIntStubsPtr->tclInExit) /* 46 */
#endif
#ifndef TclIncrElementOfIndexedArray
#define TclIncrElementOfIndexedArray \
	(tclIntStubsPtr->tclIncrElementOfIndexedArray) /* 47 */
#endif
#ifndef TclIncrIndexedScalar
#define TclIncrIndexedScalar \
	(tclIntStubsPtr->tclIncrIndexedScalar) /* 48 */
#endif
#ifndef TclIncrVar2
#define TclIncrVar2 \
	(tclIntStubsPtr->tclIncrVar2) /* 49 */
#endif
#ifndef TclInitCompiledLocals
#define TclInitCompiledLocals \
	(tclIntStubsPtr->tclInitCompiledLocals) /* 50 */
#endif
#ifndef TclInterpInit
#define TclInterpInit \
	(tclIntStubsPtr->tclInterpInit) /* 51 */
#endif
#ifndef TclInvoke
#define TclInvoke \
	(tclIntStubsPtr->tclInvoke) /* 52 */
#endif
#ifndef TclInvokeObjectCommand
#define TclInvokeObjectCommand \
	(tclIntStubsPtr->tclInvokeObjectCommand) /* 53 */
#endif
#ifndef TclInvokeStringCommand
#define TclInvokeStringCommand \
	(tclIntStubsPtr->tclInvokeStringCommand) /* 54 */
#endif
#ifndef TclIsProc
#define TclIsProc \
	(tclIntStubsPtr->tclIsProc) /* 55 */
#endif
/* Slot 56 is reserved */
/* Slot 57 is reserved */
#ifndef TclLookupVar
#define TclLookupVar \
	(tclIntStubsPtr->tclLookupVar) /* 58 */
#endif
#ifndef TclpMatchFiles
#define TclpMatchFiles \
	(tclIntStubsPtr->tclpMatchFiles) /* 59 */
#endif
#ifndef TclNeedSpace
#define TclNeedSpace \
	(tclIntStubsPtr->tclNeedSpace) /* 60 */
#endif
#ifndef TclNewProcBodyObj
#define TclNewProcBodyObj \
	(tclIntStubsPtr->tclNewProcBodyObj) /* 61 */
#endif
#ifndef TclObjCommandComplete
#define TclObjCommandComplete \
	(tclIntStubsPtr->tclObjCommandComplete) /* 62 */
#endif
#ifndef TclObjInterpProc
#define TclObjInterpProc \
	(tclIntStubsPtr->tclObjInterpProc) /* 63 */
#endif
#ifndef TclObjInvoke
#define TclObjInvoke \
	(tclIntStubsPtr->tclObjInvoke) /* 64 */
#endif
#ifndef TclObjInvokeGlobal
#define TclObjInvokeGlobal \
	(tclIntStubsPtr->tclObjInvokeGlobal) /* 65 */
#endif
#ifndef TclOpenFileChannelDeleteProc
#define TclOpenFileChannelDeleteProc \
	(tclIntStubsPtr->tclOpenFileChannelDeleteProc) /* 66 */
#endif
#ifndef TclOpenFileChannelInsertProc
#define TclOpenFileChannelInsertProc \
	(tclIntStubsPtr->tclOpenFileChannelInsertProc) /* 67 */
#endif
#ifndef TclpAccess
#define TclpAccess \
	(tclIntStubsPtr->tclpAccess) /* 68 */
#endif
#ifndef TclpAlloc
#define TclpAlloc \
	(tclIntStubsPtr->tclpAlloc) /* 69 */
#endif
#ifndef TclpCopyFile
#define TclpCopyFile \
	(tclIntStubsPtr->tclpCopyFile) /* 70 */
#endif
#ifndef TclpCopyDirectory
#define TclpCopyDirectory \
	(tclIntStubsPtr->tclpCopyDirectory) /* 71 */
#endif
#ifndef TclpCreateDirectory
#define TclpCreateDirectory \
	(tclIntStubsPtr->tclpCreateDirectory) /* 72 */
#endif
#ifndef TclpDeleteFile
#define TclpDeleteFile \
	(tclIntStubsPtr->tclpDeleteFile) /* 73 */
#endif
#ifndef TclpFree
#define TclpFree \
	(tclIntStubsPtr->tclpFree) /* 74 */
#endif
#ifndef TclpGetClicks
#define TclpGetClicks \
	(tclIntStubsPtr->tclpGetClicks) /* 75 */
#endif
#ifndef TclpGetSeconds
#define TclpGetSeconds \
	(tclIntStubsPtr->tclpGetSeconds) /* 76 */
#endif
#ifndef TclpGetTime
#define TclpGetTime \
	(tclIntStubsPtr->tclpGetTime) /* 77 */
#endif
#ifndef TclpGetTimeZone
#define TclpGetTimeZone \
	(tclIntStubsPtr->tclpGetTimeZone) /* 78 */
#endif
#ifndef TclpListVolumes
#define TclpListVolumes \
	(tclIntStubsPtr->tclpListVolumes) /* 79 */
#endif
#ifndef TclpOpenFileChannel
#define TclpOpenFileChannel \
	(tclIntStubsPtr->tclpOpenFileChannel) /* 80 */
#endif
#ifndef TclpRealloc
#define TclpRealloc \
	(tclIntStubsPtr->tclpRealloc) /* 81 */
#endif
#ifndef TclpRemoveDirectory
#define TclpRemoveDirectory \
	(tclIntStubsPtr->tclpRemoveDirectory) /* 82 */
#endif
#ifndef TclpRenameFile
#define TclpRenameFile \
	(tclIntStubsPtr->tclpRenameFile) /* 83 */
#endif
/* Slot 84 is reserved */
/* Slot 85 is reserved */
/* Slot 86 is reserved */
/* Slot 87 is reserved */
#ifndef TclPrecTraceProc
#define TclPrecTraceProc \
	(tclIntStubsPtr->tclPrecTraceProc) /* 88 */
#endif
#ifndef TclPreventAliasLoop
#define TclPreventAliasLoop \
	(tclIntStubsPtr->tclPreventAliasLoop) /* 89 */
#endif
/* Slot 90 is reserved */
#ifndef TclProcCleanupProc
#define TclProcCleanupProc \
	(tclIntStubsPtr->tclProcCleanupProc) /* 91 */
#endif
#ifndef TclProcCompileProc
#define TclProcCompileProc \
	(tclIntStubsPtr->tclProcCompileProc) /* 92 */
#endif
#ifndef TclProcDeleteProc
#define TclProcDeleteProc \
	(tclIntStubsPtr->tclProcDeleteProc) /* 93 */
#endif
#ifndef TclProcInterpProc
#define TclProcInterpProc \
	(tclIntStubsPtr->tclProcInterpProc) /* 94 */
#endif
#ifndef TclpStat
#define TclpStat \
	(tclIntStubsPtr->tclpStat) /* 95 */
#endif
#ifndef TclRenameCommand
#define TclRenameCommand \
	(tclIntStubsPtr->tclRenameCommand) /* 96 */
#endif
#ifndef TclResetShadowedCmdRefs
#define TclResetShadowedCmdRefs \
	(tclIntStubsPtr->tclResetShadowedCmdRefs) /* 97 */
#endif
#ifndef TclServiceIdle
#define TclServiceIdle \
	(tclIntStubsPtr->tclServiceIdle) /* 98 */
#endif
#ifndef TclSetElementOfIndexedArray
#define TclSetElementOfIndexedArray \
	(tclIntStubsPtr->tclSetElementOfIndexedArray) /* 99 */
#endif
#ifndef TclSetIndexedScalar
#define TclSetIndexedScalar \
	(tclIntStubsPtr->tclSetIndexedScalar) /* 100 */
#endif
/* Slot 101 is reserved */
#ifndef TclSetupEnv
#define TclSetupEnv \
	(tclIntStubsPtr->tclSetupEnv) /* 102 */
#endif
#ifndef TclSockGetPort
#define TclSockGetPort \
	(tclIntStubsPtr->tclSockGetPort) /* 103 */
#endif
#ifndef TclSockMinimumBuffers
#define TclSockMinimumBuffers \
	(tclIntStubsPtr->tclSockMinimumBuffers) /* 104 */
#endif
#ifndef TclStat
#define TclStat \
	(tclIntStubsPtr->tclStat) /* 105 */
#endif
#ifndef TclStatDeleteProc
#define TclStatDeleteProc \
	(tclIntStubsPtr->tclStatDeleteProc) /* 106 */
#endif
#ifndef TclStatInsertProc
#define TclStatInsertProc \
	(tclIntStubsPtr->tclStatInsertProc) /* 107 */
#endif
#ifndef TclTeardownNamespace
#define TclTeardownNamespace \
	(tclIntStubsPtr->tclTeardownNamespace) /* 108 */
#endif
#ifndef TclUpdateReturnInfo
#define TclUpdateReturnInfo \
	(tclIntStubsPtr->tclUpdateReturnInfo) /* 109 */
#endif
/* Slot 110 is reserved */
#ifndef Tcl_AddInterpResolvers
#define Tcl_AddInterpResolvers \
	(tclIntStubsPtr->tcl_AddInterpResolvers) /* 111 */
#endif
#ifndef Tcl_AppendExportList
#define Tcl_AppendExportList \
	(tclIntStubsPtr->tcl_AppendExportList) /* 112 */
#endif
#ifndef Tcl_CreateNamespace
#define Tcl_CreateNamespace \
	(tclIntStubsPtr->tcl_CreateNamespace) /* 113 */
#endif
#ifndef Tcl_DeleteNamespace
#define Tcl_DeleteNamespace \
	(tclIntStubsPtr->tcl_DeleteNamespace) /* 114 */
#endif
#ifndef Tcl_Export
#define Tcl_Export \
	(tclIntStubsPtr->tcl_Export) /* 115 */
#endif
#ifndef Tcl_FindCommand
#define Tcl_FindCommand \
	(tclIntStubsPtr->tcl_FindCommand) /* 116 */
#endif
#ifndef Tcl_FindNamespace
#define Tcl_FindNamespace \
	(tclIntStubsPtr->tcl_FindNamespace) /* 117 */
#endif
#ifndef Tcl_GetInterpResolvers
#define Tcl_GetInterpResolvers \
	(tclIntStubsPtr->tcl_GetInterpResolvers) /* 118 */
#endif
#ifndef Tcl_GetNamespaceResolvers
#define Tcl_GetNamespaceResolvers \
	(tclIntStubsPtr->tcl_GetNamespaceResolvers) /* 119 */
#endif
#ifndef Tcl_FindNamespaceVar
#define Tcl_FindNamespaceVar \
	(tclIntStubsPtr->tcl_FindNamespaceVar) /* 120 */
#endif
#ifndef Tcl_ForgetImport
#define Tcl_ForgetImport \
	(tclIntStubsPtr->tcl_ForgetImport) /* 121 */
#endif
#ifndef Tcl_GetCommandFromObj
#define Tcl_GetCommandFromObj \
	(tclIntStubsPtr->tcl_GetCommandFromObj) /* 122 */
#endif
#ifndef Tcl_GetCommandFullName
#define Tcl_GetCommandFullName \
	(tclIntStubsPtr->tcl_GetCommandFullName) /* 123 */
#endif
#ifndef Tcl_GetCurrentNamespace
#define Tcl_GetCurrentNamespace \
	(tclIntStubsPtr->tcl_GetCurrentNamespace) /* 124 */
#endif
#ifndef Tcl_GetGlobalNamespace
#define Tcl_GetGlobalNamespace \
	(tclIntStubsPtr->tcl_GetGlobalNamespace) /* 125 */
#endif
#ifndef Tcl_GetVariableFullName
#define Tcl_GetVariableFullName \
	(tclIntStubsPtr->tcl_GetVariableFullName) /* 126 */
#endif
#ifndef Tcl_Import
#define Tcl_Import \
	(tclIntStubsPtr->tcl_Import) /* 127 */
#endif
#ifndef Tcl_PopCallFrame
#define Tcl_PopCallFrame \
	(tclIntStubsPtr->tcl_PopCallFrame) /* 128 */
#endif
#ifndef Tcl_PushCallFrame
#define Tcl_PushCallFrame \
	(tclIntStubsPtr->tcl_PushCallFrame) /* 129 */
#endif
#ifndef Tcl_RemoveInterpResolvers
#define Tcl_RemoveInterpResolvers \
	(tclIntStubsPtr->tcl_RemoveInterpResolvers) /* 130 */
#endif
#ifndef Tcl_SetNamespaceResolvers
#define Tcl_SetNamespaceResolvers \
	(tclIntStubsPtr->tcl_SetNamespaceResolvers) /* 131 */
#endif
#ifndef TclpHasSockets
#define TclpHasSockets \
	(tclIntStubsPtr->tclpHasSockets) /* 132 */
#endif
#ifndef TclpGetDate
#define TclpGetDate \
	(tclIntStubsPtr->tclpGetDate) /* 133 */
#endif
#ifndef TclpStrftime
#define TclpStrftime \
	(tclIntStubsPtr->tclpStrftime) /* 134 */
#endif
#ifndef TclpCheckStackSpace
#define TclpCheckStackSpace \
	(tclIntStubsPtr->tclpCheckStackSpace) /* 135 */
#endif
/* Slot 136 is reserved */
#ifndef TclpChdir
#define TclpChdir \
	(tclIntStubsPtr->tclpChdir) /* 137 */
#endif
#ifndef TclGetEnv
#define TclGetEnv \
	(tclIntStubsPtr->tclGetEnv) /* 138 */
#endif
#ifndef TclpLoadFile
#define TclpLoadFile \
	(tclIntStubsPtr->tclpLoadFile) /* 139 */
#endif
#ifndef TclLooksLikeInt
#define TclLooksLikeInt \
	(tclIntStubsPtr->tclLooksLikeInt) /* 140 */
#endif
#ifndef TclpGetCwd
#define TclpGetCwd \
	(tclIntStubsPtr->tclpGetCwd) /* 141 */
#endif

#endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */

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

#endif /* _TCLINTDECLS */

Added generic/tclIntPlatDecls.h.















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































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

#ifndef _TCLINTPLATDECLS
#define _TCLINTPLATDECLS

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tclInt.decls script.
 */

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

/*
 * Exported function declarations:
 */

#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
/* 0 */
EXTERN void		TclGetAndDetachPids _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Channel chan));
/* 1 */
EXTERN int		TclpCloseFile _ANSI_ARGS_((TclFile file));
/* 2 */
EXTERN Tcl_Channel	TclpCreateCommandChannel _ANSI_ARGS_((
				TclFile readFile, TclFile writeFile, 
				TclFile errorFile, int numPids, 
				Tcl_Pid * pidPtr));
/* 3 */
EXTERN int		TclpCreatePipe _ANSI_ARGS_((TclFile * readPipe, 
				TclFile * writePipe));
/* 4 */
EXTERN int		TclpCreateProcess _ANSI_ARGS_((Tcl_Interp * interp, 
				int argc, char ** argv, TclFile inputFile, 
				TclFile outputFile, TclFile errorFile, 
				Tcl_Pid * pidPtr));
/* Slot 5 is reserved */
/* 6 */
EXTERN TclFile		TclpMakeFile _ANSI_ARGS_((Tcl_Channel channel, 
				int direction));
/* 7 */
EXTERN TclFile		TclpOpenFile _ANSI_ARGS_((CONST char * fname, 
				int mode));
/* 8 */
EXTERN int		TclUnixWaitForFile _ANSI_ARGS_((int fd, int mask, 
				int timeout));
/* 9 */
EXTERN TclFile		TclpCreateTempFile _ANSI_ARGS_((
				CONST char * contents));
#endif /* UNIX */
#ifdef __WIN32__
/* 0 */
EXTERN void		TclWinConvertError _ANSI_ARGS_((DWORD errCode));
/* 1 */
EXTERN void		TclWinConvertWSAError _ANSI_ARGS_((DWORD errCode));
/* 2 */
EXTERN struct servent *	 TclWinGetServByName _ANSI_ARGS_((CONST char * nm, 
				CONST char * proto));
/* 3 */
EXTERN int		TclWinGetSockOpt _ANSI_ARGS_((SOCKET s, int level, 
				int optname, char FAR * optval, 
				int FAR * optlen));
/* 4 */
EXTERN HINSTANCE	TclWinGetTclInstance _ANSI_ARGS_((void));
/* Slot 5 is reserved */
/* 6 */
EXTERN u_short		TclWinNToHS _ANSI_ARGS_((u_short ns));
/* 7 */
EXTERN int		TclWinSetSockOpt _ANSI_ARGS_((SOCKET s, int level, 
				int optname, CONST char FAR * optval, 
				int optlen));
/* 8 */
EXTERN unsigned long	TclpGetPid _ANSI_ARGS_((Tcl_Pid pid));
/* 9 */
EXTERN int		TclWinGetPlatformId _ANSI_ARGS_((void));
/* 10 */
EXTERN int		TclWinSynchSpawn _ANSI_ARGS_((void * args, int type, 
				void ** trans, Tcl_Pid * pidPtr));
/* 11 */
EXTERN void		TclGetAndDetachPids _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Channel chan));
/* 12 */
EXTERN int		TclpCloseFile _ANSI_ARGS_((TclFile file));
/* 13 */
EXTERN Tcl_Channel	TclpCreateCommandChannel _ANSI_ARGS_((
				TclFile readFile, TclFile writeFile, 
				TclFile errorFile, int numPids, 
				Tcl_Pid * pidPtr));
/* 14 */
EXTERN int		TclpCreatePipe _ANSI_ARGS_((TclFile * readPipe, 
				TclFile * writePipe));
/* 15 */
EXTERN int		TclpCreateProcess _ANSI_ARGS_((Tcl_Interp * interp, 
				int argc, char ** argv, TclFile inputFile, 
				TclFile outputFile, TclFile errorFile, 
				Tcl_Pid * pidPtr));
/* Slot 16 is reserved */
/* Slot 17 is reserved */
/* 18 */
EXTERN TclFile		TclpMakeFile _ANSI_ARGS_((Tcl_Channel channel, 
				int direction));
/* 19 */
EXTERN TclFile		TclpOpenFile _ANSI_ARGS_((CONST char * fname, 
				int mode));
/* 20 */
EXTERN void		TclWinAddProcess _ANSI_ARGS_((HANDLE hProcess, 
				DWORD id));
/* 21 */
EXTERN void		TclpAsyncMark _ANSI_ARGS_((Tcl_AsyncHandler async));
/* 22 */
EXTERN TclFile		TclpCreateTempFile _ANSI_ARGS_((
				CONST char * contents));
/* 23 */
EXTERN char *		TclpGetTZName _ANSI_ARGS_((int isdst));
/* 24 */
EXTERN char *		TclWinNoBackslash _ANSI_ARGS_((char * path));
#endif /* __WIN32__ */
#ifdef MAC_TCL
/* 0 */
EXTERN VOID *		TclpSysAlloc _ANSI_ARGS_((long size, int isBin));
/* 1 */
EXTERN void		TclpSysFree _ANSI_ARGS_((VOID * ptr));
/* 2 */
EXTERN VOID *		TclpSysRealloc _ANSI_ARGS_((VOID * cp, 
				unsigned int size));
/* 3 */
EXTERN void		TclpExit _ANSI_ARGS_((int status));
/* 4 */
EXTERN int		FSpGetDefaultDir _ANSI_ARGS_((FSSpecPtr theSpec));
/* 5 */
EXTERN int		FSpSetDefaultDir _ANSI_ARGS_((FSSpecPtr theSpec));
/* 6 */
EXTERN OSErr		FSpFindFolder _ANSI_ARGS_((short vRefNum, 
				OSType folderType, Boolean createFolder, 
				FSSpec * spec));
/* 7 */
EXTERN void		GetGlobalMouse _ANSI_ARGS_((Point * mouse));
/* 8 */
EXTERN pascal OSErr	FSpGetDirectoryID _ANSI_ARGS_((CONST FSSpec * spec, 
				long * theDirID, Boolean * isDirectory));
/* 9 */
EXTERN pascal short	FSpOpenResFileCompat _ANSI_ARGS_((
				CONST FSSpec * spec, SignedByte permission));
/* 10 */
EXTERN pascal void	FSpCreateResFileCompat _ANSI_ARGS_((
				CONST FSSpec * spec, OSType creator, 
				OSType fileType, ScriptCode scriptTag));
/* 11 */
EXTERN int		FSpLocationFromPath _ANSI_ARGS_((int length, 
				CONST char * path, FSSpecPtr theSpec));
/* 12 */
EXTERN OSErr		FSpPathFromLocation _ANSI_ARGS_((FSSpecPtr theSpec, 
				int * length, Handle * fullPath));
/* 13 */
EXTERN void		TclMacExitHandler _ANSI_ARGS_((void));
/* 14 */
EXTERN void		TclMacInitExitToShell _ANSI_ARGS_((int usePatch));
/* 15 */
EXTERN OSErr		TclMacInstallExitToShellPatch _ANSI_ARGS_((
				ExitToShellProcPtr newProc));
/* 16 */
EXTERN int		TclMacOSErrorToPosixError _ANSI_ARGS_((int error));
/* 17 */
EXTERN void		TclMacRemoveTimer _ANSI_ARGS_((void * timerToken));
/* 18 */
EXTERN void *		TclMacStartTimer _ANSI_ARGS_((long ms));
/* 19 */
EXTERN int		TclMacTimerExpired _ANSI_ARGS_((void * timerToken));
/* 20 */
EXTERN int		TclMacRegisterResourceFork _ANSI_ARGS_((
				short fileRef, Tcl_Obj * tokenPtr, 
				int insert));
/* 21 */
EXTERN short		TclMacUnRegisterResourceFork _ANSI_ARGS_((
				char * tokenPtr, Tcl_Obj * resultPtr));
/* 22 */
EXTERN int		TclMacCreateEnv _ANSI_ARGS_((void));
/* 23 */
EXTERN FILE *		TclMacFOpenHack _ANSI_ARGS_((CONST char * path, 
				CONST char * mode));
/* Slot 24 is reserved */
/* 25 */
EXTERN int		TclMacChmod _ANSI_ARGS_((char * path, int mode));
#endif /* MAC_TCL */

typedef struct TclIntPlatStubs {
    int magic;
    struct TclIntPlatStubHooks *hooks;

#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
    void (*tclGetAndDetachPids) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 0 */
    int (*tclpCloseFile) _ANSI_ARGS_((TclFile file)); /* 1 */
    Tcl_Channel (*tclpCreateCommandChannel) _ANSI_ARGS_((TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid * pidPtr)); /* 2 */
    int (*tclpCreatePipe) _ANSI_ARGS_((TclFile * readPipe, TclFile * writePipe)); /* 3 */
    int (*tclpCreateProcess) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid * pidPtr)); /* 4 */
    void *reserved5;
    TclFile (*tclpMakeFile) _ANSI_ARGS_((Tcl_Channel channel, int direction)); /* 6 */
    TclFile (*tclpOpenFile) _ANSI_ARGS_((CONST char * fname, int mode)); /* 7 */
    int (*tclUnixWaitForFile) _ANSI_ARGS_((int fd, int mask, int timeout)); /* 8 */
    TclFile (*tclpCreateTempFile) _ANSI_ARGS_((CONST char * contents)); /* 9 */
#endif /* UNIX */
#ifdef __WIN32__
    void (*tclWinConvertError) _ANSI_ARGS_((DWORD errCode)); /* 0 */
    void (*tclWinConvertWSAError) _ANSI_ARGS_((DWORD errCode)); /* 1 */
    struct servent * (*tclWinGetServByName) _ANSI_ARGS_((CONST char * nm, CONST char * proto)); /* 2 */
    int (*tclWinGetSockOpt) _ANSI_ARGS_((SOCKET s, int level, int optname, char FAR * optval, int FAR * optlen)); /* 3 */
    HINSTANCE (*tclWinGetTclInstance) _ANSI_ARGS_((void)); /* 4 */
    void *reserved5;
    u_short (*tclWinNToHS) _ANSI_ARGS_((u_short ns)); /* 6 */
    int (*tclWinSetSockOpt) _ANSI_ARGS_((SOCKET s, int level, int optname, CONST char FAR * optval, int optlen)); /* 7 */
    unsigned long (*tclpGetPid) _ANSI_ARGS_((Tcl_Pid pid)); /* 8 */
    int (*tclWinGetPlatformId) _ANSI_ARGS_((void)); /* 9 */
    int (*tclWinSynchSpawn) _ANSI_ARGS_((void * args, int type, void ** trans, Tcl_Pid * pidPtr)); /* 10 */
    void (*tclGetAndDetachPids) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 11 */
    int (*tclpCloseFile) _ANSI_ARGS_((TclFile file)); /* 12 */
    Tcl_Channel (*tclpCreateCommandChannel) _ANSI_ARGS_((TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid * pidPtr)); /* 13 */
    int (*tclpCreatePipe) _ANSI_ARGS_((TclFile * readPipe, TclFile * writePipe)); /* 14 */
    int (*tclpCreateProcess) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid * pidPtr)); /* 15 */
    void *reserved16;
    void *reserved17;
    TclFile (*tclpMakeFile) _ANSI_ARGS_((Tcl_Channel channel, int direction)); /* 18 */
    TclFile (*tclpOpenFile) _ANSI_ARGS_((CONST char * fname, int mode)); /* 19 */
    void (*tclWinAddProcess) _ANSI_ARGS_((HANDLE hProcess, DWORD id)); /* 20 */
    void (*tclpAsyncMark) _ANSI_ARGS_((Tcl_AsyncHandler async)); /* 21 */
    TclFile (*tclpCreateTempFile) _ANSI_ARGS_((CONST char * contents)); /* 22 */
    char * (*tclpGetTZName) _ANSI_ARGS_((int isdst)); /* 23 */
    char * (*tclWinNoBackslash) _ANSI_ARGS_((char * path)); /* 24 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
    VOID * (*tclpSysAlloc) _ANSI_ARGS_((long size, int isBin)); /* 0 */
    void (*tclpSysFree) _ANSI_ARGS_((VOID * ptr)); /* 1 */
    VOID * (*tclpSysRealloc) _ANSI_ARGS_((VOID * cp, unsigned int size)); /* 2 */
    void (*tclpExit) _ANSI_ARGS_((int status)); /* 3 */
    int (*fSpGetDefaultDir) _ANSI_ARGS_((FSSpecPtr theSpec)); /* 4 */
    int (*fSpSetDefaultDir) _ANSI_ARGS_((FSSpecPtr theSpec)); /* 5 */
    OSErr (*fSpFindFolder) _ANSI_ARGS_((short vRefNum, OSType folderType, Boolean createFolder, FSSpec * spec)); /* 6 */
    void (*getGlobalMouse) _ANSI_ARGS_((Point * mouse)); /* 7 */
    pascal OSErr (*fSpGetDirectoryID) _ANSI_ARGS_((CONST FSSpec * spec, long * theDirID, Boolean * isDirectory)); /* 8 */
    pascal short (*fSpOpenResFileCompat) _ANSI_ARGS_((CONST FSSpec * spec, SignedByte permission)); /* 9 */
    pascal void (*fSpCreateResFileCompat) _ANSI_ARGS_((CONST FSSpec * spec, OSType creator, OSType fileType, ScriptCode scriptTag)); /* 10 */
    int (*fSpLocationFromPath) _ANSI_ARGS_((int length, CONST char * path, FSSpecPtr theSpec)); /* 11 */
    OSErr (*fSpPathFromLocation) _ANSI_ARGS_((FSSpecPtr theSpec, int * length, Handle * fullPath)); /* 12 */
    void (*tclMacExitHandler) _ANSI_ARGS_((void)); /* 13 */
    void (*tclMacInitExitToShell) _ANSI_ARGS_((int usePatch)); /* 14 */
    OSErr (*tclMacInstallExitToShellPatch) _ANSI_ARGS_((ExitToShellProcPtr newProc)); /* 15 */
    int (*tclMacOSErrorToPosixError) _ANSI_ARGS_((int error)); /* 16 */
    void (*tclMacRemoveTimer) _ANSI_ARGS_((void * timerToken)); /* 17 */
    void * (*tclMacStartTimer) _ANSI_ARGS_((long ms)); /* 18 */
    int (*tclMacTimerExpired) _ANSI_ARGS_((void * timerToken)); /* 19 */
    int (*tclMacRegisterResourceFork) _ANSI_ARGS_((short fileRef, Tcl_Obj * tokenPtr, int insert)); /* 20 */
    short (*tclMacUnRegisterResourceFork) _ANSI_ARGS_((char * tokenPtr, Tcl_Obj * resultPtr)); /* 21 */
    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:
 */

#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
#ifndef TclGetAndDetachPids
#define TclGetAndDetachPids \
	(tclIntPlatStubsPtr->tclGetAndDetachPids) /* 0 */
#endif
#ifndef TclpCloseFile
#define TclpCloseFile \
	(tclIntPlatStubsPtr->tclpCloseFile) /* 1 */
#endif
#ifndef TclpCreateCommandChannel
#define TclpCreateCommandChannel \
	(tclIntPlatStubsPtr->tclpCreateCommandChannel) /* 2 */
#endif
#ifndef TclpCreatePipe
#define TclpCreatePipe \
	(tclIntPlatStubsPtr->tclpCreatePipe) /* 3 */
#endif
#ifndef TclpCreateProcess
#define TclpCreateProcess \
	(tclIntPlatStubsPtr->tclpCreateProcess) /* 4 */
#endif
/* Slot 5 is reserved */
#ifndef TclpMakeFile
#define TclpMakeFile \
	(tclIntPlatStubsPtr->tclpMakeFile) /* 6 */
#endif
#ifndef TclpOpenFile
#define TclpOpenFile \
	(tclIntPlatStubsPtr->tclpOpenFile) /* 7 */
#endif
#ifndef TclUnixWaitForFile
#define TclUnixWaitForFile \
	(tclIntPlatStubsPtr->tclUnixWaitForFile) /* 8 */
#endif
#ifndef TclpCreateTempFile
#define TclpCreateTempFile \
	(tclIntPlatStubsPtr->tclpCreateTempFile) /* 9 */
#endif
#endif /* UNIX */
#ifdef __WIN32__
#ifndef TclWinConvertError
#define TclWinConvertError \
	(tclIntPlatStubsPtr->tclWinConvertError) /* 0 */
#endif
#ifndef TclWinConvertWSAError
#define TclWinConvertWSAError \
	(tclIntPlatStubsPtr->tclWinConvertWSAError) /* 1 */
#endif
#ifndef TclWinGetServByName
#define TclWinGetServByName \
	(tclIntPlatStubsPtr->tclWinGetServByName) /* 2 */
#endif
#ifndef TclWinGetSockOpt
#define TclWinGetSockOpt \
	(tclIntPlatStubsPtr->tclWinGetSockOpt) /* 3 */
#endif
#ifndef TclWinGetTclInstance
#define TclWinGetTclInstance \
	(tclIntPlatStubsPtr->tclWinGetTclInstance) /* 4 */
#endif
/* Slot 5 is reserved */
#ifndef TclWinNToHS
#define TclWinNToHS \
	(tclIntPlatStubsPtr->tclWinNToHS) /* 6 */
#endif
#ifndef TclWinSetSockOpt
#define TclWinSetSockOpt \
	(tclIntPlatStubsPtr->tclWinSetSockOpt) /* 7 */
#endif
#ifndef TclpGetPid
#define TclpGetPid \
	(tclIntPlatStubsPtr->tclpGetPid) /* 8 */
#endif
#ifndef TclWinGetPlatformId
#define TclWinGetPlatformId \
	(tclIntPlatStubsPtr->tclWinGetPlatformId) /* 9 */
#endif
#ifndef TclWinSynchSpawn
#define TclWinSynchSpawn \
	(tclIntPlatStubsPtr->tclWinSynchSpawn) /* 10 */
#endif
#ifndef TclGetAndDetachPids
#define TclGetAndDetachPids \
	(tclIntPlatStubsPtr->tclGetAndDetachPids) /* 11 */
#endif
#ifndef TclpCloseFile
#define TclpCloseFile \
	(tclIntPlatStubsPtr->tclpCloseFile) /* 12 */
#endif
#ifndef TclpCreateCommandChannel
#define TclpCreateCommandChannel \
	(tclIntPlatStubsPtr->tclpCreateCommandChannel) /* 13 */
#endif
#ifndef TclpCreatePipe
#define TclpCreatePipe \
	(tclIntPlatStubsPtr->tclpCreatePipe) /* 14 */
#endif
#ifndef TclpCreateProcess
#define TclpCreateProcess \
	(tclIntPlatStubsPtr->tclpCreateProcess) /* 15 */
#endif
/* Slot 16 is reserved */
/* Slot 17 is reserved */
#ifndef TclpMakeFile
#define TclpMakeFile \
	(tclIntPlatStubsPtr->tclpMakeFile) /* 18 */
#endif
#ifndef TclpOpenFile
#define TclpOpenFile \
	(tclIntPlatStubsPtr->tclpOpenFile) /* 19 */
#endif
#ifndef TclWinAddProcess
#define TclWinAddProcess \
	(tclIntPlatStubsPtr->tclWinAddProcess) /* 20 */
#endif
#ifndef TclpAsyncMark
#define TclpAsyncMark \
	(tclIntPlatStubsPtr->tclpAsyncMark) /* 21 */
#endif
#ifndef TclpCreateTempFile
#define TclpCreateTempFile \
	(tclIntPlatStubsPtr->tclpCreateTempFile) /* 22 */
#endif
#ifndef TclpGetTZName
#define TclpGetTZName \
	(tclIntPlatStubsPtr->tclpGetTZName) /* 23 */
#endif
#ifndef TclWinNoBackslash
#define TclWinNoBackslash \
	(tclIntPlatStubsPtr->tclWinNoBackslash) /* 24 */
#endif
#endif /* __WIN32__ */
#ifdef MAC_TCL
#ifndef TclpSysAlloc
#define TclpSysAlloc \
	(tclIntPlatStubsPtr->tclpSysAlloc) /* 0 */
#endif
#ifndef TclpSysFree
#define TclpSysFree \
	(tclIntPlatStubsPtr->tclpSysFree) /* 1 */
#endif
#ifndef TclpSysRealloc
#define TclpSysRealloc \
	(tclIntPlatStubsPtr->tclpSysRealloc) /* 2 */
#endif
#ifndef TclpExit
#define TclpExit \
	(tclIntPlatStubsPtr->tclpExit) /* 3 */
#endif
#ifndef FSpGetDefaultDir
#define FSpGetDefaultDir \
	(tclIntPlatStubsPtr->fSpGetDefaultDir) /* 4 */
#endif
#ifndef FSpSetDefaultDir
#define FSpSetDefaultDir \
	(tclIntPlatStubsPtr->fSpSetDefaultDir) /* 5 */
#endif
#ifndef FSpFindFolder
#define FSpFindFolder \
	(tclIntPlatStubsPtr->fSpFindFolder) /* 6 */
#endif
#ifndef GetGlobalMouse
#define GetGlobalMouse \
	(tclIntPlatStubsPtr->getGlobalMouse) /* 7 */
#endif
#ifndef FSpGetDirectoryID
#define FSpGetDirectoryID \
	(tclIntPlatStubsPtr->fSpGetDirectoryID) /* 8 */
#endif
#ifndef FSpOpenResFileCompat
#define FSpOpenResFileCompat \
	(tclIntPlatStubsPtr->fSpOpenResFileCompat) /* 9 */
#endif
#ifndef FSpCreateResFileCompat
#define FSpCreateResFileCompat \
	(tclIntPlatStubsPtr->fSpCreateResFileCompat) /* 10 */
#endif
#ifndef FSpLocationFromPath
#define FSpLocationFromPath \
	(tclIntPlatStubsPtr->fSpLocationFromPath) /* 11 */
#endif
#ifndef FSpPathFromLocation
#define FSpPathFromLocation \
	(tclIntPlatStubsPtr->fSpPathFromLocation) /* 12 */
#endif
#ifndef TclMacExitHandler
#define TclMacExitHandler \
	(tclIntPlatStubsPtr->tclMacExitHandler) /* 13 */
#endif
#ifndef TclMacInitExitToShell
#define TclMacInitExitToShell \
	(tclIntPlatStubsPtr->tclMacInitExitToShell) /* 14 */
#endif
#ifndef TclMacInstallExitToShellPatch
#define TclMacInstallExitToShellPatch \
	(tclIntPlatStubsPtr->tclMacInstallExitToShellPatch) /* 15 */
#endif
#ifndef TclMacOSErrorToPosixError
#define TclMacOSErrorToPosixError \
	(tclIntPlatStubsPtr->tclMacOSErrorToPosixError) /* 16 */
#endif
#ifndef TclMacRemoveTimer
#define TclMacRemoveTimer \
	(tclIntPlatStubsPtr->tclMacRemoveTimer) /* 17 */
#endif
#ifndef TclMacStartTimer
#define TclMacStartTimer \
	(tclIntPlatStubsPtr->tclMacStartTimer) /* 18 */
#endif
#ifndef TclMacTimerExpired
#define TclMacTimerExpired \
	(tclIntPlatStubsPtr->tclMacTimerExpired) /* 19 */
#endif
#ifndef TclMacRegisterResourceFork
#define TclMacRegisterResourceFork \
	(tclIntPlatStubsPtr->tclMacRegisterResourceFork) /* 20 */
#endif
#ifndef TclMacUnRegisterResourceFork
#define TclMacUnRegisterResourceFork \
	(tclIntPlatStubsPtr->tclMacUnRegisterResourceFork) /* 21 */
#endif
#ifndef TclMacCreateEnv
#define TclMacCreateEnv \
	(tclIntPlatStubsPtr->tclMacCreateEnv) /* 22 */
#endif
#ifndef TclMacFOpenHack
#define TclMacFOpenHack \
	(tclIntPlatStubsPtr->tclMacFOpenHack) /* 23 */
#endif
/* Slot 24 is reserved */
#ifndef TclMacChmod
#define TclMacChmod \
	(tclIntPlatStubsPtr->tclMacChmod) /* 25 */
#endif
#endif /* MAC_TCL */

#endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */

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

#endif /* _TCLINTPLATDECLS */

Changes to generic/tclInterp.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
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
/* 
 * tclInterp.c --
 *
 *	This file implements the "interp" command which allows creation
 *	and manipulation of Tcl interpreters from within Tcl scripts.
 *
 * 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.
 *
 * SCCS: @(#) tclInterp.c 1.128 97/11/05 09:35:12
 */

#include <stdio.h>
#include "tclInt.h"
#include "tclPort.h"

/*
 * Counter for how many aliases were created (global)
 */

static int aliasCounter = 0;





































/*
 *
 * struct Slave:
 *
 * Used by the "interp" command to record and find information about slave
 * interpreters. Maps from a command name in the master to information about
 * a slave interpreter, e.g. what aliases are defined in it.
 */

typedef struct {
    Tcl_Interp *masterInterp;	/* Master interpreter for this slave. */
    Tcl_HashEntry *slaveEntry;	/* Hash entry in masters slave table for

                                 * this slave interpreter. Used to find
                                 * this record, and used when deleting the
                                 * slave interpreter to delete it from the
                                 * masters table. */
    Tcl_Interp	*slaveInterp;	/* The slave interpreter. */
    Tcl_Command interpCmd;	/* Interpreter object command. */
    Tcl_HashTable aliasTable;	/* Table which maps from names of commands
                                 * in slave interpreter to struct Alias
                                 * defined below. */
} Slave;

/*
 * struct Alias:
 *
 * Stores information about an alias. Is stored in the slave interpreter
 * and used by the source command to find the target command in the master
 * when the source command is invoked.
 */

typedef struct {
    char	*aliasName;	/* Name of alias command. */
    char	*targetName;	/* Name of target command in master interp. */
    Tcl_Interp	*targetInterp;	/* Master interpreter. */
    int		objc;		/* Count of additional args to pass. */
    Tcl_Obj	**objv;		/* Actual additional args to pass. */
    Tcl_HashEntry *aliasEntry;	/* Entry for the alias hash table in slave.
                                 * This is used by alias deletion to remove
                                 * the alias from the slave interpreter
                                 * alias table. */
    Tcl_HashEntry *targetEntry;	/* Entry for target command in master.
                                 * This is used in the master interpreter to
                                 * map back from the target command to aliases
                                 * redirecting to it. Random access to this
                                 * hash table is never required - we are using
                                 * a hash table only for convenience. */
    Tcl_Command slaveCmd;	/* Source command in slave interpreter. */
} Alias;

/*
 * struct Target:
 *
 * Maps from master interpreter commands back to the source commands in slave
 * interpreters. This is needed because aliases can be created between sibling
 * interpreters and must be deleted when the target interpreter is deleted. In
 * case they would not be deleted the source interpreter would be left with a
 * "dangling pointer". One such record is stored in the Master record of the
 * master interpreter (in the targetTable hashtable, see below) with the
 * master for each alias which directs to a command in the master. These
 * records are used to remove the source command for an from a slave if/when
 * the master is deleted.
 */

typedef struct {
    Tcl_Command	slaveCmd;	/* Command for alias in slave interp. */
    Tcl_Interp *slaveInterp;	/* Slave Interpreter. */
} Target;

/*
 * struct Master:
 *
 * This record is used for two purposes: First, slaveTable (a hashtable)
 * maps from names of commands to slave interpreters. This hashtable is
 * used to store information about slave interpreters of this interpreter,
 * to map over all slaves, etc. The second purpose is to store information
 * about all aliases in slaves (or siblings) which direct to target commands
 * in this interpreter (using the targetTable hashtable).
 * 
 * NB: the flags field in the interp structure, used with SAFE_INTERP
 * mask denotes whether the interpreter is safe or not. Safe
 * interpreters have restricted functionality, can only create safe slave
 * interpreters and can only load safe extensions.
 */

typedef struct {
    Tcl_HashTable slaveTable;	/* Hash table for slave interpreters.
                                 * Maps from command names to Slave records. */
    Tcl_HashTable targetTable;	/* Hash table for Target Records. Contains
                                 * all Target records which denote aliases
                                 * from slaves or sibling interpreters that
                                 * direct to commands in this interpreter. This
                                 * table is used to remove dangling pointers
                                 * from the slave (or sibling) interpreters
                                 * when this interpreter is deleted. */
} Master;













/*
 * Prototypes for local static procedures:
 */











static int		AliasCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *currentInterp, int objc,
		            Tcl_Obj *CONST objv[]));
static void		AliasCmdDeleteProc _ANSI_ARGS_((
			    ClientData clientData));
static int		AliasCreationHelper _ANSI_ARGS_((Tcl_Interp *curInterp,
			    Tcl_Interp *slaveInterp, Tcl_Interp *masterInterp,
			    Master *masterPtr, char *aliasName,
			    char *targetName, int objc,
			    Tcl_Obj *CONST objv[]));
static int		CreateInterpObject _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static Tcl_Interp	*CreateSlave _ANSI_ARGS_((Tcl_Interp *interp,
		            Master *masterPtr, char *slavePath, int safe));
static int		DeleteAlias _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp, char *aliasName));
static int		DescribeAlias _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp, char *aliasName));
static int		DeleteInterpObject _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		DeleteOneInterpObject _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, char *path));
static Tcl_Interp	*GetInterp _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, char *path,
			    Master **masterPtrPtr));
static int		GetTarget _ANSI_ARGS_((Tcl_Interp *interp, char *path,
			    char *aliasName));
static int		InterpAliasHelper _ANSI_ARGS_((Tcl_Interp *interp,
		            Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpAliasesHelper _ANSI_ARGS_((Tcl_Interp *interp,
		            Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpExistsHelper _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpEvalHelper _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpExposeHelper _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpIsSafeHelper _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpHideHelper _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpHiddenHelper _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpInvokeHiddenHelper _ANSI_ARGS_((
    			    Tcl_Interp *interp, Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpMarkTrustedHelper _ANSI_ARGS_((
    			    Tcl_Interp *interp, Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpSlavesHelper _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpShareHelper _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpTargetHelper _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		InterpTransferHelper _ANSI_ARGS_((Tcl_Interp *interp,
			    Master *masterPtr, int objc,
        		    Tcl_Obj *CONST objv[]));
static int		MarkTrusted _ANSI_ARGS_((Tcl_Interp *interp));
static void		MasterRecordDeleteProc _ANSI_ARGS_((
			    ClientData clientData, Tcl_Interp *interp));
static int		SlaveAliasHelper _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Interp *slaveInterp, Slave *slavePtr,
		            int objc, Tcl_Obj *CONST objv[]));
static int		SlaveAliasesHelper _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Interp *slaveInterp, Slave *slavePtr,
		            int objc, Tcl_Obj *CONST objv[]));
static int		SlaveEvalHelper _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Interp *slaveInterp, Slave *slavePtr,
		            int objc, Tcl_Obj *CONST objv[]));
static int		SlaveExposeHelper _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Interp *slaveInterp, Slave *slavePtr,
		            int objc, Tcl_Obj *CONST objv[]));
static int		SlaveHideHelper _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Interp *slaveInterp, Slave *slavePtr,
		            int objc, Tcl_Obj *CONST objv[]));
static int		SlaveHiddenHelper _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Interp *slaveInterp, Slave *slavePtr,
		            int objc, Tcl_Obj *CONST objv[]));
static int		SlaveIsSafeHelper _ANSI_ARGS_((
    			    Tcl_Interp *interp, Tcl_Interp *slaveInterp,
                            Slave *slavePtr, int objc, Tcl_Obj *CONST objv[]));
static int		SlaveInvokeHiddenHelper _ANSI_ARGS_((
    			    Tcl_Interp *interp, Tcl_Interp *slaveInterp,
                            Slave *slavePtr, int objc, Tcl_Obj *CONST objv[]));
static int		SlaveMarkTrustedHelper _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Interp *slaveInterp, Slave *slavePtr,
		            int objc, Tcl_Obj *CONST objv[]));
static int		SlaveObjectCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static void		SlaveObjectDeleteProc _ANSI_ARGS_((
			    ClientData clientData));


































































static void		SlaveRecordDeleteProc _ANSI_ARGS_((



































































































































































































































































































































































































































































































































			    ClientData clientData, Tcl_Interp *interp));






































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * TclPreventAliasLoop --
 *
 *	When defining an alias or renaming a command, prevent an alias











|











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










|

|
>
|


|







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














|




















|











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




>
>
>
>
>
>
>
>
>
>
|


|

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


|

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







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84



























85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163


















164






165
166

167
168


169


170

171



172
173
174
























175
176
177
178
179
180
181
182

183
184
185
186
187













188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
/* 
 * tclInterp.c --
 *
 *	This file implements the "interp" command which allows creation
 *	and manipulation of Tcl interpreters from within Tcl scripts.
 *
 * 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: tclInterp.c,v 1.1.2.11 1999/03/26 02:24:45 stanton Exp $
 */

#include <stdio.h>
#include "tclInt.h"
#include "tclPort.h"

/*
 * Counter for how many aliases were created (global)
 */

static int aliasCounter = 0;
TCL_DECLARE_MUTEX(cntMutex)

/*
 * struct Alias:
 *
 * Stores information about an alias. Is stored in the slave interpreter
 * and used by the source command to find the target command in the master
 * when the source command is invoked.
 */

typedef struct Alias {
    Tcl_Obj *namePtr;		/* Name of alias command in slave interp. */
    Tcl_Interp *targetInterp;	/* Interp in which target command will be
				 * invoked. */
    Tcl_Obj *prefixPtr;		/* Tcl list making up the prefix of the
				 * target command to be invoked in the target
				 * interpreter.  Additional arguments
				 * specified when calling the alias in the
				 * slave interp will be appended to the prefix
				 * before the command is invoked. */
    Tcl_Command slaveCmd;	/* Source command in slave interpreter,
				 * bound to command that invokes the target
				 * command in the target interpreter. */
    Tcl_HashEntry *aliasEntryPtr;
				/* Entry for the alias hash table in slave.
                                 * This is used by alias deletion to remove
                                 * the alias from the slave interpreter
                                 * alias table. */
    Tcl_HashEntry *targetEntryPtr;
				/* Entry for target command in master.
                                 * This is used in the master interpreter to
                                 * map back from the target command to aliases
                                 * redirecting to it. Random access to this
                                 * hash table is never required - we are using
                                 * a hash table only for convenience. */
} Alias;

/*
 *
 * struct Slave:
 *
 * Used by the "interp" command to record and find information about slave
 * interpreters. Maps from a command name in the master to information about
 * a slave interpreter, e.g. what aliases are defined in it.
 */

typedef struct Slave {
    Tcl_Interp *masterInterp;	/* Master interpreter for this slave. */
    Tcl_HashEntry *slaveEntryPtr;
				/* Hash entry in masters slave table for
                                 * this slave interpreter.  Used to find
                                 * this record, and used when deleting the
                                 * slave interpreter to delete it from the
                                 * master's table. */
    Tcl_Interp	*slaveInterp;	/* The slave interpreter. */
    Tcl_Command interpCmd;	/* Interpreter object command. */
    Tcl_HashTable aliasTable;	/* Table which maps from names of commands
                                 * in slave interpreter to struct Alias
                                 * defined below. */
} Slave;




























/*
 * struct Target:
 *
 * Maps from master interpreter commands back to the source commands in slave
 * interpreters. This is needed because aliases can be created between sibling
 * interpreters and must be deleted when the target interpreter is deleted. In
 * case they would not be deleted the source interpreter would be left with a
 * "dangling pointer". One such record is stored in the Master record of the
 * master interpreter (in the targetTable hashtable, see below) with the
 * master for each alias which directs to a command in the master. These
 * records are used to remove the source command for an from a slave if/when
 * the master is deleted.
 */

typedef struct Target {
    Tcl_Command	slaveCmd;	/* Command for alias in slave interp. */
    Tcl_Interp *slaveInterp;	/* Slave Interpreter. */
} Target;

/*
 * struct Master:
 *
 * This record is used for two purposes: First, slaveTable (a hashtable)
 * maps from names of commands to slave interpreters. This hashtable is
 * used to store information about slave interpreters of this interpreter,
 * to map over all slaves, etc. The second purpose is to store information
 * about all aliases in slaves (or siblings) which direct to target commands
 * in this interpreter (using the targetTable hashtable).
 * 
 * NB: the flags field in the interp structure, used with SAFE_INTERP
 * mask denotes whether the interpreter is safe or not. Safe
 * interpreters have restricted functionality, can only create safe slave
 * interpreters and can only load safe extensions.
 */

typedef struct Master {
    Tcl_HashTable slaveTable;	/* Hash table for slave interpreters.
                                 * Maps from command names to Slave records. */
    Tcl_HashTable targetTable;	/* Hash table for Target Records. Contains
                                 * all Target records which denote aliases
                                 * from slaves or sibling interpreters that
                                 * direct to commands in this interpreter. This
                                 * table is used to remove dangling pointers
                                 * from the slave (or sibling) interpreters
                                 * when this interpreter is deleted. */
} Master;

/*
 * The following structure keeps track of all the Master and Slave information
 * on a per-interp basis.
 */

typedef struct InterpInfo {
    Master master;		/* Keeps track of all interps for which this
				 * interp is the Master. */
    Slave slave;		/* Information necessary for this interp to
				 * function as a slave. */
} InterpInfo;

/*
 * Prototypes for local static procedures:
 */

static int		AliasCreate _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp, Tcl_Interp *masterInterp,
			    Tcl_Obj *namePtr, Tcl_Obj *targetPtr, int objc,
			    Tcl_Obj *CONST objv[]));
static int		AliasDelete _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp, Tcl_Obj *namePtr));
static int		AliasDescribe _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp, Tcl_Obj *objPtr));
static int		AliasList _ANSI_ARGS_((Tcl_Interp *interp,
		            Tcl_Interp *slaveInterp));
static int		AliasObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *currentInterp, int objc,
		            Tcl_Obj *CONST objv[]));
static void		AliasObjCmdDeleteProc _ANSI_ARGS_((
			    ClientData clientData));



















static Tcl_Interp *	GetInterp _ANSI_ARGS_((Tcl_Interp *interp,






			    Tcl_Obj *pathPtr));
static Tcl_Interp *	GetInterp2 _ANSI_ARGS_((Tcl_Interp *interp, int objc,

			    Tcl_Obj *CONST objv[]));
static void		InterpInfoDeleteProc _ANSI_ARGS_((


			    ClientData clientData, Tcl_Interp *interp));


static Tcl_Interp *	SlaveCreate _ANSI_ARGS_((Tcl_Interp *interp,

		            Tcl_Obj *pathPtr, int safe));



static int		SlaveEval _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp, int objc,
			    Tcl_Obj *CONST objv[]));
























static int		SlaveExpose _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp, int objc,
			    Tcl_Obj *CONST objv[]));
static int		SlaveHide _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp, int objc,
			    Tcl_Obj *CONST objv[]));
static int		SlaveHidden _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp));

static int		SlaveInvokeHidden _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp, int global, int objc,
			    Tcl_Obj *CONST objv[]));
static int		SlaveMarkTrusted _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Interp *slaveInterp));













static int		SlaveObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static void		SlaveObjCmdDeleteProc _ANSI_ARGS_((
			    ClientData clientData));

/*
 *---------------------------------------------------------------------------
 *
 * TclInterpInit --
 *
 *	Initializes the invoking interpreter for using the master, slave
 *	and safe interp facilities.  This is called from inside
 *	Tcl_CreateInterp().
 *
 * Results:
 *	Always returns TCL_OK for backwards compatibility.
 *
 * Side effects:
 *	Adds the "interp" command to an interpreter and initializes the
 *	interpInfoPtr field of the invoking interpreter.
 *
 *---------------------------------------------------------------------------
 */

int
TclInterpInit(interp)
    Tcl_Interp *interp;			/* Interpreter to initialize. */
{
    InterpInfo *interpInfoPtr;
    Master *masterPtr;
    Slave *slavePtr;	

    interpInfoPtr = (InterpInfo *) ckalloc(sizeof(InterpInfo));
    ((Interp *) interp)->interpInfo = (ClientData) interpInfoPtr;

    masterPtr = &interpInfoPtr->master;
    Tcl_InitHashTable(&masterPtr->slaveTable, TCL_STRING_KEYS);
    Tcl_InitHashTable(&masterPtr->targetTable, TCL_ONE_WORD_KEYS);

    slavePtr = &interpInfoPtr->slave;
    slavePtr->masterInterp	= NULL;
    slavePtr->slaveEntryPtr	= NULL;
    slavePtr->slaveInterp	= interp;
    slavePtr->interpCmd		= NULL;
    Tcl_InitHashTable(&slavePtr->aliasTable, TCL_STRING_KEYS);

    Tcl_CreateObjCommand(interp, "interp", Tcl_InterpObjCmd, NULL, NULL);

    Tcl_CallWhenDeleted(interp, InterpInfoDeleteProc, NULL);
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * InterpInfoDeleteProc --
 *
 *	Invoked when an interpreter is being deleted.  It releases all
 *	storage used by the master/slave/safe interpreter facilities.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Cleans up storage.  Sets the interpInfoPtr field of the interp
 *	to NULL.
 *
 *---------------------------------------------------------------------------
 */

static void
InterpInfoDeleteProc(clientData, interp)
    ClientData clientData;	/* Ignored. */
    Tcl_Interp *interp;		/* Interp being deleted.  All commands for
				 * slave interps should already be deleted. */
{
    InterpInfo *interpInfoPtr;
    Slave *slavePtr;
    Master *masterPtr;
    Tcl_HashSearch hSearch;
    Tcl_HashEntry *hPtr;
    Target *targetPtr;

    interpInfoPtr = (InterpInfo *) ((Interp *) interp)->interpInfo;

    /*
     * There shouldn't be any commands left.
     */

    masterPtr = &interpInfoPtr->master;
    if (masterPtr->slaveTable.numEntries != 0) {
	panic("InterpInfoDeleteProc: still exist commands");
    }
    Tcl_DeleteHashTable(&masterPtr->slaveTable);

    /*
     * Tell any interps that have aliases to this interp that they should
     * delete those aliases.  If the other interp was already dead, it
     * would have removed the target record already. 
     */

    hPtr = Tcl_FirstHashEntry(&masterPtr->targetTable, &hSearch);
    while (hPtr != NULL) {
	targetPtr = (Target *) Tcl_GetHashValue(hPtr);
	Tcl_DeleteCommandFromToken(targetPtr->slaveInterp,
		targetPtr->slaveCmd);
	hPtr = Tcl_NextHashEntry(&hSearch);
    }
    Tcl_DeleteHashTable(&masterPtr->targetTable);

    slavePtr = &interpInfoPtr->slave;
    if (slavePtr->interpCmd != NULL) {
	/*
	 * Tcl_DeleteInterp() was called on this interpreter, rather
	 * "interp delete" or the equivalent deletion of the command in the
	 * master.  First ensure that the cleanup callback doesn't try to
	 * delete the interp again.
	 */

	slavePtr->slaveInterp = NULL;
        Tcl_DeleteCommandFromToken(slavePtr->masterInterp,
		slavePtr->interpCmd);
    }

    /*
     * There shouldn't be any aliases left.
     */

    if (slavePtr->aliasTable.numEntries != 0) {
	panic("InterpInfoDeleteProc: still exist aliases");
    }
    Tcl_DeleteHashTable(&slavePtr->aliasTable);

    ckfree((char *) interpInfoPtr);    
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_InterpObjCmd --
 *
 *	This procedure is invoked to process the "interp" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */
	/* ARGSUSED */
int
Tcl_InterpObjCmd(clientData, interp, objc, objv)
    ClientData clientData;		/* Unused. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int index;
    static char *options[] = {
        "alias",	"aliases",	"create",	"delete", 
	"eval",		"exists",	"expose",	"hide", 
	"hidden",	"issafe",	"invokehidden",	"marktrusted", 
	"slaves",	"share",	"target",	"transfer",
        NULL
    };
    enum option {
	OPT_ALIAS,	OPT_ALIASES,	OPT_CREATE,	OPT_DELETE,
	OPT_EVAL,	OPT_EXISTS,	OPT_EXPOSE,	OPT_HIDE,
	OPT_HIDDEN,	OPT_ISSAFE,	OPT_INVOKEHID,	OPT_MARKTRUSTED,
	OPT_SLAVES,	OPT_SHARE,	OPT_TARGET,	OPT_TRANSFER
    };


    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?");
        return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, 
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum option) index) {
	case OPT_ALIAS: {
	    Tcl_Interp *slaveInterp, *masterInterp;

	    if (objc < 4) {
		aliasArgs:
		Tcl_WrongNumArgs(interp, 2, objv,
			"slavePath slaveCmd ?masterPath masterCmd? ?args ..?");
		return TCL_ERROR;
	    }
	    slaveInterp = GetInterp(interp, objv[2]);
	    if (slaveInterp == (Tcl_Interp *) NULL) {
		return TCL_ERROR;
	    }
	    if (objc == 4) {
		return AliasDescribe(interp, slaveInterp, objv[3]);
	    }
	    if ((objc == 5) && (Tcl_GetString(objv[4])[0] == '\0')) {
		return AliasDelete(interp, slaveInterp, objv[3]);
	    }
	    if (objc > 5) {
		masterInterp = GetInterp(interp, objv[4]);
		if (masterInterp == (Tcl_Interp *) NULL) {
		    return TCL_ERROR;
		}
		if (Tcl_GetString(objv[5])[0] == '\0') {
		    if (objc == 6) {
			return AliasDelete(interp, slaveInterp, objv[3]);
		    }
		} else {
		    return AliasCreate(interp, slaveInterp, masterInterp,
			    objv[3], objv[5], objc - 6, objv + 6);
		}
	    }
	    goto aliasArgs;
	}
	case OPT_ALIASES: {
	    Tcl_Interp *slaveInterp;

	    slaveInterp = GetInterp2(interp, objc, objv);
	    if (slaveInterp == NULL) {
		return TCL_ERROR;
	    }
	    return AliasList(interp, slaveInterp);
	}
	case OPT_CREATE: {
	    int i, last, safe;
	    Tcl_Obj *slavePtr;
	    char buf[16 + TCL_INTEGER_SPACE];
	    static char *options[] = {
		"-safe",	"--",		NULL
	    };
	    enum option {
		OPT_SAFE,	OPT_LAST
	    };

	    safe = Tcl_IsSafe(interp);
	    
	    /*
	     * Weird historical rules: "-safe" is accepted at the end, too.
	     */

	    slavePtr = NULL;
	    last = 0;
	    for (i = 2; i < objc; i++) {
		if ((last == 0) && (Tcl_GetString(objv[i])[0] == '-')) {
		    if (Tcl_GetIndexFromObj(interp, objv[i], options, "option",
			    0, &index) != TCL_OK) {
			return TCL_ERROR;
		    }
		    if (index == OPT_SAFE) {
			safe = 1;
			continue;
		    }
		    i++;
		    last = 1;
		}
		if (slavePtr != NULL) {
		    Tcl_WrongNumArgs(interp, 2, objv, "?-safe? ?--? ?path?");
		    return TCL_ERROR;
		}
		slavePtr = objv[i];
	    }
	    buf[0] = '\0';
	    if (slavePtr == NULL) {
		/*
		 * Create an anonymous interpreter -- we choose its name and
		 * the name of the command. We check that the command name
		 * that we use for the interpreter does not collide with an
		 * existing command in the master interpreter.
		 */
		
		for (i = 0; ; i++) {
		    Tcl_CmdInfo cmdInfo;
		    
		    sprintf(buf, "interp%d", i);
		    if (Tcl_GetCommandInfo(interp, buf, &cmdInfo) == 0) {
			break;
		    }
		}
		slavePtr = Tcl_NewStringObj(buf, -1);
	    }
	    if (SlaveCreate(interp, slavePtr, safe) == NULL) {
		if (buf[0] != '\0') {
		    Tcl_DecrRefCount(slavePtr);
		}
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, slavePtr);
	    return TCL_OK;
	}
	case OPT_DELETE: {
	    int i;
	    InterpInfo *iiPtr;
	    Tcl_Interp *slaveInterp;
	    
	    for (i = 2; i < objc; i++) {
		slaveInterp = GetInterp(interp, objv[i]);
		if (slaveInterp == NULL) {
		    return TCL_ERROR;
		} else if (slaveInterp == interp) {
		    Tcl_ResetResult(interp);
		    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			    "cannot delete the current interpreter",
			    (char *) NULL);
		    return TCL_ERROR;
		}
		iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo;
		Tcl_DeleteCommandFromToken(iiPtr->slave.masterInterp,
			iiPtr->slave.interpCmd);
	    }
	    return TCL_OK;
	}
	case OPT_EVAL: {
	    Tcl_Interp *slaveInterp;

	    if (objc < 4) {
		Tcl_WrongNumArgs(interp, 2, objv, "path arg ?arg ...?");
		return TCL_ERROR;
	    }
	    slaveInterp = GetInterp(interp, objv[2]);
	    if (slaveInterp == NULL) {
		return TCL_ERROR;
	    }
	    return SlaveEval(interp, slaveInterp, objc - 3, objv + 3);
	}
	case OPT_EXISTS: {
	    int exists;
	    Tcl_Interp *slaveInterp;

	    exists = 1;
	    slaveInterp = GetInterp2(interp, objc, objv);
	    if (slaveInterp == NULL) {
		if (objc > 3) {
		    return TCL_ERROR;
		}
		Tcl_ResetResult(interp);
		exists = 0;
	    }
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), exists);
	    return TCL_OK;
	}
	case OPT_EXPOSE: {
	    Tcl_Interp *slaveInterp;

	    if ((objc < 4) || (objc > 5)) {
		Tcl_WrongNumArgs(interp, 2, objv,
			"path hiddenCmdName ?cmdName?");
		return TCL_ERROR;
	    }
	    slaveInterp = GetInterp(interp, objv[2]);
	    if (slaveInterp == NULL) {
		return TCL_ERROR;
	    }
	    return SlaveExpose(interp, slaveInterp, objc - 3, objv + 3);
	}
	case OPT_HIDE: {
	    Tcl_Interp *slaveInterp;		/* A slave. */

	    if ((objc < 4) || (objc > 5)) {
		Tcl_WrongNumArgs(interp, 2, objv,
			"path cmdName ?hiddenCmdName?");
		return TCL_ERROR;
	    }
	    slaveInterp = GetInterp(interp, objv[2]);
	    if (slaveInterp == (Tcl_Interp *) NULL) {
		return TCL_ERROR;
	    }
	    return SlaveHide(interp, slaveInterp, objc - 3, objv + 3);
	}
	case OPT_HIDDEN: {
	    Tcl_Interp *slaveInterp;		/* A slave. */

	    slaveInterp = GetInterp2(interp, objc, objv);
	    if (slaveInterp == NULL) {
		return TCL_ERROR;
	    }
	    return SlaveHidden(interp, slaveInterp);
	}
	case OPT_ISSAFE: {
	    Tcl_Interp *slaveInterp;

	    slaveInterp = GetInterp2(interp, objc, objv);
	    if (slaveInterp == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), Tcl_IsSafe(slaveInterp));
	    return TCL_OK;
	}
	case OPT_INVOKEHID: {
	    int i, index, global;
	    Tcl_Interp *slaveInterp;
	    static char *hiddenOptions[] = {
		"-global",	"--",		NULL
	    };
	    enum hiddenOption {
		OPT_GLOBAL,	OPT_LAST
	    };

	    global = 0;
	    for (i = 3; i < objc; i++) {
		if (Tcl_GetString(objv[i])[0] != '-') {
		    break;
		}
		if (Tcl_GetIndexFromObj(interp, objv[i], hiddenOptions,
			"option", 0, &index) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (index == OPT_GLOBAL) {
		    global = 1;
		} else {
		    i++;
		    break;
		}
	    }
	    if (objc - i < 1) {
		Tcl_WrongNumArgs(interp, 2, objv,
			"path ?-global? ?--? cmd ?arg ..?");
		return TCL_ERROR;
	    }
	    slaveInterp = GetInterp(interp, objv[2]);
	    if (slaveInterp == (Tcl_Interp *) NULL) {
		return TCL_ERROR;
	    }
	    return SlaveInvokeHidden(interp, slaveInterp, global, objc - i,
		    objv + i);
	}
	case OPT_MARKTRUSTED: {
	    Tcl_Interp *slaveInterp;

	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "path");
		return TCL_ERROR;
	    }
	    slaveInterp = GetInterp(interp, objv[2]);
	    if (slaveInterp == NULL) {
		return TCL_ERROR;
	    }
	    return SlaveMarkTrusted(interp, slaveInterp);
	}
	case OPT_SLAVES: {
	    Tcl_Interp *slaveInterp;
	    InterpInfo *iiPtr;
	    Tcl_Obj *resultPtr;
	    Tcl_HashEntry *hPtr;
	    Tcl_HashSearch hashSearch;
	    char *string;
	    
	    slaveInterp = GetInterp2(interp, objc, objv);
	    if (slaveInterp == NULL) {
		return TCL_ERROR;
	    }
	    iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo;
	    resultPtr = Tcl_GetObjResult(interp);
	    hPtr = Tcl_FirstHashEntry(&iiPtr->master.slaveTable, &hashSearch);
	    for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&hashSearch)) {
		string = Tcl_GetHashKey(&iiPtr->master.slaveTable, hPtr);
		Tcl_ListObjAppendElement(NULL, resultPtr,
			Tcl_NewStringObj(string, -1));
	    }
	    return TCL_OK;
	}
	case OPT_SHARE: {
	    Tcl_Interp *slaveInterp;		/* A slave. */
	    Tcl_Interp *masterInterp;		/* Its master. */
	    Tcl_Channel chan;

	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 2, objv, "srcPath channelId destPath");
		return TCL_ERROR;
	    }
	    masterInterp = GetInterp(interp, objv[2]);
	    if (masterInterp == NULL) {
		return TCL_ERROR;
	    }
	    chan = Tcl_GetChannel(masterInterp, Tcl_GetString(objv[3]),
		    NULL);
	    if (chan == NULL) {
		TclTransferResult(masterInterp, TCL_OK, interp);
		return TCL_ERROR;
	    }
	    slaveInterp = GetInterp(interp, objv[4]);
	    if (slaveInterp == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_RegisterChannel(slaveInterp, chan);
	    return TCL_OK;
	}
	case OPT_TARGET: {
	    Tcl_Interp *slaveInterp;
	    InterpInfo *iiPtr;
	    Tcl_HashEntry *hPtr;	
	    Alias *aliasPtr;		
	    char *aliasName;

	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 2, objv, "path alias");
		return TCL_ERROR;
	    }

	    slaveInterp = GetInterp(interp, objv[2]);
	    if (slaveInterp == NULL) {
		return TCL_ERROR;
	    }

	    aliasName = Tcl_GetString(objv[3]);

	    iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo;
	    hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName);
	    if (hPtr == NULL) {
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"alias \"", aliasName, "\" in path \"",
			Tcl_GetString(objv[2]), "\" not found",
			(char *) NULL);
		return TCL_ERROR;
	    }
	    aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
	    if (Tcl_GetInterpPath(interp, aliasPtr->targetInterp) != TCL_OK) {
		Tcl_ResetResult(interp);
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"target interpreter for alias \"", aliasName,
			"\" in path \"", Tcl_GetString(objv[2]),
			"\" is not my descendant", (char *) NULL);
		return TCL_ERROR;
	    }
	    return TCL_OK;
	}
	case OPT_TRANSFER: {
	    Tcl_Interp *slaveInterp;		/* A slave. */
	    Tcl_Interp *masterInterp;		/* Its master. */
	    Tcl_Channel chan;
		    
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 2, objv,
			"srcPath channelId destPath");
		return TCL_ERROR;
	    }
	    masterInterp = GetInterp(interp, objv[2]);
	    if (masterInterp == NULL) {
		return TCL_ERROR;
	    }
	    chan = Tcl_GetChannel(masterInterp, Tcl_GetString(objv[3]), NULL);
	    if (chan == NULL) {
		TclTransferResult(masterInterp, TCL_OK, interp);
		return TCL_ERROR;
	    }
	    slaveInterp = GetInterp(interp, objv[4]);
	    if (slaveInterp == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_RegisterChannel(slaveInterp, chan);
	    if (Tcl_UnregisterChannel(masterInterp, chan) != TCL_OK) {
		TclTransferResult(masterInterp, TCL_OK, interp);
		return TCL_ERROR;
	    }
	    return TCL_OK;
	}
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * GetInterp2 --
 *
 *	Helper function for Tcl_InterpObjCmd() to convert the interp name
 *	potentially specified on the command line to an Tcl_Interp.
 *
 * Results:
 *	The return value is the interp specified on the command line,
 *	or the interp argument itself if no interp was specified on the
 *	command line.  If the interp could not be found or the wrong
 *	number of arguments was specified on the command line, the return
 *	value is NULL and an error message is left in the interp's result.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
static Tcl_Interp *
GetInterp2(interp, objc, objv)
    Tcl_Interp *interp;		/* Default interp if no interp was specified
				 * on the command line. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    if (objc == 2) {
	return interp;
    } else if (objc == 3) {
	return GetInterp(interp, objv[2]);
    } else {
	Tcl_WrongNumArgs(interp, 2, objv, "?path?");
	return NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateAlias --
 *
 *	Creates an alias between two interpreters.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Creates a new alias, manipulates the result field of slaveInterp.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_CreateAlias(slaveInterp, slaveCmd, targetInterp, targetCmd, argc, argv)
    Tcl_Interp *slaveInterp;	/* Interpreter for source command. */
    char *slaveCmd;		/* Command to install in slave. */
    Tcl_Interp *targetInterp;	/* Interpreter for target command. */
    char *targetCmd;		/* Name of target command. */
    int argc;			/* How many additional arguments? */
    char **argv;		/* These are the additional args. */
{
    Tcl_Obj *slaveObjPtr, *targetObjPtr;
    Tcl_Obj **objv;
    int i;
    int result;
    
    objv = (Tcl_Obj **) ckalloc((unsigned) sizeof(Tcl_Obj *) * argc);
    for (i = 0; i < argc; i++) {
        objv[i] = Tcl_NewStringObj(argv[i], -1);
        Tcl_IncrRefCount(objv[i]);
    }
    
    slaveObjPtr = Tcl_NewStringObj(slaveCmd, -1);
    Tcl_IncrRefCount(slaveObjPtr);

    targetObjPtr = Tcl_NewStringObj(targetCmd, -1);
    Tcl_IncrRefCount(targetObjPtr);

    result = AliasCreate(slaveInterp, slaveInterp, targetInterp, slaveObjPtr,
	    targetObjPtr, argc, objv);

    for (i = 0; i < argc; i++) {
	Tcl_DecrRefCount(objv[i]);
    }
    ckfree((char *) objv);
    Tcl_DecrRefCount(targetObjPtr);
    Tcl_DecrRefCount(slaveObjPtr);

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateAliasObj --
 *
 *	Object version: Creates an alias between two interpreters.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Creates a new alias.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_CreateAliasObj(slaveInterp, slaveCmd, targetInterp, targetCmd, objc, objv)
    Tcl_Interp *slaveInterp;	/* Interpreter for source command. */
    char *slaveCmd;		/* Command to install in slave. */
    Tcl_Interp *targetInterp;	/* Interpreter for target command. */
    char *targetCmd;		/* Name of target command. */
    int objc;			/* How many additional arguments? */
    Tcl_Obj *CONST objv[];	/* Argument vector. */
{
    Tcl_Obj *slaveObjPtr, *targetObjPtr;
    int result;

    slaveObjPtr = Tcl_NewStringObj(slaveCmd, -1);
    Tcl_IncrRefCount(slaveObjPtr);

    targetObjPtr = Tcl_NewStringObj(targetCmd, -1);
    Tcl_IncrRefCount(targetObjPtr);

    result = AliasCreate(slaveInterp, slaveInterp, targetInterp, slaveObjPtr,
	    targetObjPtr, objc, objv);

    Tcl_DecrRefCount(slaveObjPtr);
    Tcl_DecrRefCount(targetObjPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetAlias --
 *
 *	Gets information about an alias.
 *
 * Results:
 *	A standard Tcl result. 
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetAlias(interp, aliasName, targetInterpPtr, targetNamePtr, argcPtr,
        argvPtr)
    Tcl_Interp *interp;			/* Interp to start search from. */
    char *aliasName;			/* Name of alias to find. */
    Tcl_Interp **targetInterpPtr;	/* (Return) target interpreter. */
    char **targetNamePtr;		/* (Return) name of target command. */
    int *argcPtr;			/* (Return) count of addnl args. */
    char ***argvPtr;			/* (Return) additional arguments. */
{
    InterpInfo *iiPtr;
    Tcl_HashEntry *hPtr;
    Alias *aliasPtr;
    int i, objc;
    Tcl_Obj **objv;
    
    iiPtr = (InterpInfo *) ((Interp *) interp)->interpInfo;
    hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName);
    if (hPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "alias \"", aliasName, "\" not found", (char *) NULL);
	return TCL_ERROR;
    }
    aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
    Tcl_ListObjGetElements(NULL, aliasPtr->prefixPtr, &objc, &objv);

    if (targetInterpPtr != NULL) {
	*targetInterpPtr = aliasPtr->targetInterp;
    }
    if (targetNamePtr != NULL) {
	*targetNamePtr = Tcl_GetString(objv[0]);
    }
    if (argcPtr != NULL) {
	*argcPtr = objc - 1;
    }
    if (argvPtr != NULL) {
        *argvPtr = (char **) ckalloc((unsigned) sizeof(char *) * (objc - 1));
        for (i = 1; i < objc; i++) {
            *argvPtr[i - 1] = Tcl_GetString(objv[i]);
        }
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ObjGetAlias --
 *
 *	Object version: Gets information about an alias.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetAliasObj(interp, aliasName, targetInterpPtr, targetNamePtr, objcPtr,
        objvPtr)
    Tcl_Interp *interp;			/* Interp to start search from. */
    char *aliasName;			/* Name of alias to find. */
    Tcl_Interp **targetInterpPtr;	/* (Return) target interpreter. */
    char **targetNamePtr;		/* (Return) name of target command. */
    int *objcPtr;			/* (Return) count of addnl args. */
    Tcl_Obj ***objvPtr;			/* (Return) additional args. */
{
    InterpInfo *iiPtr;
    Tcl_HashEntry *hPtr;
    Alias *aliasPtr;	
    int objc;
    Tcl_Obj **objv;

    iiPtr = (InterpInfo *) ((Interp *) interp)->interpInfo;
    hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName);
    if (hPtr == (Tcl_HashEntry *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "alias \"", aliasName, "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
    Tcl_ListObjGetElements(NULL, aliasPtr->prefixPtr, &objc, &objv);

    if (targetInterpPtr != (Tcl_Interp **) NULL) {
        *targetInterpPtr = aliasPtr->targetInterp;
    }
    if (targetNamePtr != (char **) NULL) {
        *targetNamePtr = Tcl_GetString(objv[0]);
    }
    if (objcPtr != (int *) NULL) {
        *objcPtr = objc - 1;
    }
    if (objvPtr != (Tcl_Obj ***) NULL) {
        *objvPtr = objv + 1;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclPreventAliasLoop --
 *
 *	When defining an alias or renaming a command, prevent an alias
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
    Command *aliasCmdPtr;
    
    /*
     * If we are not creating or renaming an alias, then it is
     * always OK to create or rename the command.
     */
    
    if (cmdPtr->objProc != AliasCmd) {
        return TCL_OK;
    }

    /*
     * OK, we are dealing with an alias, so traverse the chain of aliases.
     * If we encounter the alias we are defining (or renaming to) any in
     * the chain then we have a loop.
     */

    aliasPtr = (Alias *) cmdPtr->objClientData;
    nextAliasPtr = aliasPtr;
    while (1) {



        /*
         * If the target of the next alias in the chain is the same as
         * the source alias, we have a loop.
	 */


	aliasCmd = Tcl_FindCommand(nextAliasPtr->targetInterp,
                nextAliasPtr->targetName,

		Tcl_GetGlobalNamespace(nextAliasPtr->targetInterp),
		/*flags*/ 0);
        if (aliasCmd == (Tcl_Command) NULL) {
            return TCL_OK;
        }
	aliasCmdPtr = (Command *) aliasCmd;
        if (aliasCmdPtr == cmdPtr) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"cannot define or rename alias \"", aliasPtr->aliasName,

		"\": would create a loop", (char *) NULL);
            return TCL_ERROR;
        }

        /*
	 * Otherwise, follow the chain one step further. See if the target
         * command is an alias - if so, follow the loop to its target
         * command. Otherwise we do not have a loop.
	 */

        if (aliasCmdPtr->objProc != AliasCmd) {
            return TCL_OK;
        }
        nextAliasPtr = (Alias *) aliasCmdPtr->objClientData;
    }

    /* NOTREACHED */
}

/*
 *----------------------------------------------------------------------
 *




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































 * MarkTrusted --
 *
 *	Mark an interpreter as unsafe (i.e. remove the "safe" mark).
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Removes the "safe" mark from an interpreter.

 *
 *----------------------------------------------------------------------
 */

static int
MarkTrusted(interp)
    Tcl_Interp *interp;		/* Interpreter to be marked unsafe. */


{
    Interp *iPtr = (Interp *) interp;





    iPtr->flags &= ~SAFE_INTERP;
    return TCL_OK;
}































/*
 *----------------------------------------------------------------------
 *
 * Tcl_MakeSafe --
 *
 *	Makes its argument interpreter contain only functionality that is







|












>
>






>

<
>








|
>
|









|











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

|





|
>





|
|
>
>

|
>
>
>
>
|
|


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







1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068

1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
    Command *aliasCmdPtr;
    
    /*
     * If we are not creating or renaming an alias, then it is
     * always OK to create or rename the command.
     */
    
    if (cmdPtr->objProc != AliasObjCmd) {
        return TCL_OK;
    }

    /*
     * OK, we are dealing with an alias, so traverse the chain of aliases.
     * If we encounter the alias we are defining (or renaming to) any in
     * the chain then we have a loop.
     */

    aliasPtr = (Alias *) cmdPtr->objClientData;
    nextAliasPtr = aliasPtr;
    while (1) {
	int objc;
	Tcl_Obj **objv;

        /*
         * If the target of the next alias in the chain is the same as
         * the source alias, we have a loop.
	 */

	Tcl_ListObjGetElements(NULL, nextAliasPtr->prefixPtr, &objc, &objv);
	aliasCmd = Tcl_FindCommand(nextAliasPtr->targetInterp,

                Tcl_GetString(objv[0]),
		Tcl_GetGlobalNamespace(nextAliasPtr->targetInterp),
		/*flags*/ 0);
        if (aliasCmd == (Tcl_Command) NULL) {
            return TCL_OK;
        }
	aliasCmdPtr = (Command *) aliasCmd;
        if (aliasCmdPtr == cmdPtr) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "cannot define or rename alias \"",
		    Tcl_GetString(aliasPtr->namePtr),
		    "\": would create a loop", (char *) NULL);
            return TCL_ERROR;
        }

        /*
	 * Otherwise, follow the chain one step further. See if the target
         * command is an alias - if so, follow the loop to its target
         * command. Otherwise we do not have a loop.
	 */

        if (aliasCmdPtr->objProc != AliasObjCmd) {
            return TCL_OK;
        }
        nextAliasPtr = (Alias *) aliasCmdPtr->objClientData;
    }

    /* NOTREACHED */
}

/*
 *----------------------------------------------------------------------
 *
 * AliasCreate --
 *
 *	Helper function to do the work to actually create an alias.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	An alias command is created and entered into the alias table
 *	for the slave interpreter.
 *
 *----------------------------------------------------------------------
 */

static int
AliasCreate(interp, slaveInterp, masterInterp, namePtr, targetNamePtr,
	objc, objv)
    Tcl_Interp *interp;		/* Interp for error reporting. */
    Tcl_Interp *slaveInterp;	/* Interp where alias cmd will live or from
				 * which alias will be deleted. */
    Tcl_Interp *masterInterp;	/* Interp in which target command will be
				 * invoked. */
    Tcl_Obj *namePtr;		/* Name of alias cmd. */
    Tcl_Obj *targetNamePtr;	/* Name of target cmd. */
    int objc;			/* Additional arguments to store */
    Tcl_Obj *CONST objv[];	/* with alias. */
{
    Alias *aliasPtr;
    Tcl_HashEntry *hPtr;
    int new;
    Target *targetPtr;
    Slave *slavePtr;
    Master *masterPtr;

    aliasPtr = (Alias *) ckalloc((unsigned) sizeof(Alias));
    aliasPtr->namePtr		= namePtr;
    Tcl_IncrRefCount(aliasPtr->namePtr);
    aliasPtr->targetInterp	= masterInterp;
    aliasPtr->prefixPtr		= Tcl_NewListObj(1, &targetNamePtr);
    Tcl_ListObjReplace(NULL, aliasPtr->prefixPtr, 1, 0, objc, objv);
    Tcl_IncrRefCount(aliasPtr->prefixPtr);

    aliasPtr->slaveCmd = Tcl_CreateObjCommand(slaveInterp,
	    Tcl_GetString(namePtr), AliasObjCmd, (ClientData) aliasPtr,
	    AliasObjCmdDeleteProc);

    if (TclPreventAliasLoop(interp, slaveInterp, aliasPtr->slaveCmd) != TCL_OK) {
	/*
	 * Found an alias loop!  The last call to Tcl_CreateObjCommand made
	 * the alias point to itself.  Delete the command and its alias
	 * record.  Be careful to wipe out its client data first, so the
	 * command doesn't try to delete itself.
	 */

	Command *cmdPtr;
	
	Tcl_DecrRefCount(aliasPtr->namePtr);
	Tcl_DecrRefCount(aliasPtr->prefixPtr);
	
        cmdPtr = (Command *) aliasPtr->slaveCmd;
        cmdPtr->clientData = NULL;
        cmdPtr->deleteProc = NULL;
        cmdPtr->deleteData = NULL;
        Tcl_DeleteCommandFromToken(slaveInterp, aliasPtr->slaveCmd);

        ckfree((char *) aliasPtr);

        /*
         * The result was already set by TclPreventAliasLoop.
         */

        return TCL_ERROR;
    }
    
    /*
     * Make an entry in the alias table. If it already exists delete
     * the alias command. Then retry.
     */

    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
    while (1) {
	Alias *oldAliasPtr;
	char *string;
	
	string = Tcl_GetString(namePtr);
	hPtr = Tcl_CreateHashEntry(&slavePtr->aliasTable, string, &new);
	if (new != 0) {
	    break;
	}

	oldAliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
	Tcl_DeleteCommandFromToken(slaveInterp, oldAliasPtr->slaveCmd);
    }

    aliasPtr->aliasEntryPtr = hPtr;
    Tcl_SetHashValue(hPtr, (ClientData) aliasPtr);
    
    /*
     * Create the new command. We must do it after deleting any old command,
     * because the alias may be pointing at a renamed alias, as in:
     *
     * interp alias {} foo {} bar		# Create an alias "foo"
     * rename foo zop				# Now rename the alias
     * interp alias {} foo {} zop		# Now recreate "foo"...
     */

    targetPtr = (Target *) ckalloc((unsigned) sizeof(Target));
    targetPtr->slaveCmd = aliasPtr->slaveCmd;
    targetPtr->slaveInterp = slaveInterp;

    Tcl_MutexLock(&cntMutex);
    masterPtr = &((InterpInfo *) ((Interp *) masterInterp)->interpInfo)->master;
    do {
        hPtr = Tcl_CreateHashEntry(&masterPtr->targetTable,
                (char *) aliasCounter, &new);
	aliasCounter++;
    } while (new == 0);
    Tcl_MutexUnlock(&cntMutex);

    Tcl_SetHashValue(hPtr, (ClientData) targetPtr);
    aliasPtr->targetEntryPtr = hPtr;

    Tcl_SetObjResult(interp, namePtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * AliasDelete --
 *
 *	Deletes the given alias from the slave interpreter given.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Deletes the alias from the slave interpreter.
 *
 *----------------------------------------------------------------------
 */

static int
AliasDelete(interp, slaveInterp, namePtr)
    Tcl_Interp *interp;		/* Interpreter for result & errors. */
    Tcl_Interp *slaveInterp;	/* Interpreter containing alias. */
    Tcl_Obj *namePtr;		/* Name of alias to describe. */
{
    Slave *slavePtr;
    Alias *aliasPtr;
    Tcl_HashEntry *hPtr;

    /*
     * If the alias has been renamed in the slave, the master can still use
     * the original name (with which it was created) to find the alias to
     * delete it.
     */

    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
    hPtr = Tcl_FindHashEntry(&slavePtr->aliasTable, Tcl_GetString(namePtr));
    if (hPtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "alias \"",
		Tcl_GetString(namePtr), "\" not found", NULL);
        return TCL_ERROR;
    }
    aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
    Tcl_DeleteCommandFromToken(slaveInterp, aliasPtr->slaveCmd);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * AliasDescribe --
 *
 *	Sets the interpreter's result object to a Tcl list describing
 *	the given alias in the given interpreter: its target command
 *	and the additional arguments to prepend to any invocation
 *	of the alias.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
AliasDescribe(interp, slaveInterp, namePtr)
    Tcl_Interp *interp;		/* Interpreter for result & errors. */
    Tcl_Interp *slaveInterp;	/* Interpreter containing alias. */
    Tcl_Obj *namePtr;		/* Name of alias to describe. */
{
    Slave *slavePtr;
    Tcl_HashEntry *hPtr;
    Alias *aliasPtr;	

    /*
     * If the alias has been renamed in the slave, the master can still use
     * the original name (with which it was created) to find the alias to
     * describe it.
     */

    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
    hPtr = Tcl_FindHashEntry(&slavePtr->aliasTable, Tcl_GetString(namePtr));
    if (hPtr == NULL) {
        return TCL_OK;
    }
    aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
    Tcl_SetObjResult(interp, aliasPtr->prefixPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * AliasList --
 *
 *	Computes a list of aliases defined in a slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
AliasList(interp, slaveInterp)
    Tcl_Interp *interp;		/* Interp for data return. */
    Tcl_Interp *slaveInterp;	/* Interp whose aliases to compute. */
{
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch hashSearch;
    Tcl_Obj *resultPtr;	
    Alias *aliasPtr;
    Slave *slavePtr;

    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
    resultPtr = Tcl_GetObjResult(interp);

    entryPtr = Tcl_FirstHashEntry(&slavePtr->aliasTable, &hashSearch);
    for ( ; entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&hashSearch)) {
        aliasPtr = (Alias *) Tcl_GetHashValue(entryPtr);
        Tcl_ListObjAppendElement(NULL, resultPtr, aliasPtr->namePtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * AliasObjCmd --
 *
 *	This is the procedure that services invocations of aliases in a
 *	slave interpreter. One such command exists for each alias. When
 *	invoked, this procedure redirects the invocation to the target
 *	command in the master interpreter as designated by the Alias
 *	record associated with this command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Causes forwarding of the invocation; all possible side effects
 *	may occur as a result of invoking the command to which the
 *	invocation is forwarded.
 *
 *----------------------------------------------------------------------
 */

static int
AliasObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Alias record. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument vector. */	
{
    Tcl_Interp *targetInterp;	
    Alias *aliasPtr;		
    int result, prefc, cmdc;
    Tcl_Obj *cmdPtr;
    Tcl_Obj **prefv, **cmdv;
    
    aliasPtr = (Alias *) clientData;
    targetInterp = aliasPtr->targetInterp;

    Tcl_Preserve((ClientData) targetInterp);

    ((Interp *) targetInterp)->numLevels++;

    Tcl_ResetResult(targetInterp);
    Tcl_AllowExceptions(targetInterp);

    /*
     * Append the arguments to the command prefix and invoke the command
     * in the target interp's global namespace.
     */
     
    Tcl_ListObjGetElements(NULL, aliasPtr->prefixPtr, &prefc, &prefv);
    cmdPtr = Tcl_NewListObj(prefc, prefv);
    Tcl_ListObjReplace(NULL, cmdPtr, prefc, 0, objc - 1, objv + 1);
    Tcl_ListObjGetElements(NULL, cmdPtr, &cmdc, &cmdv);
    result = TclObjInvoke(targetInterp, cmdc, cmdv,
	    TCL_INVOKE_NO_TRACEBACK);
    Tcl_DecrRefCount(cmdPtr);

    ((Interp *) targetInterp)->numLevels--;
    
    /*
     * Check if we are at the bottom of the stack for the target interpreter.
     * If so, check for special return codes.
     */
    
    if (((Interp *) targetInterp)->numLevels == 0) {
	if (result == TCL_RETURN) {
	    result = TclUpdateReturnInfo((Interp *) targetInterp);
	}
	if ((result != TCL_OK) && (result != TCL_ERROR)) {
	    Tcl_ResetResult(targetInterp);
	    if (result == TCL_BREAK) {
                Tcl_SetObjResult(targetInterp,
                        Tcl_NewStringObj("invoked \"break\" outside of a loop",
                                -1));
	    } else if (result == TCL_CONTINUE) {
                Tcl_SetObjResult(targetInterp,
                        Tcl_NewStringObj(
                            "invoked \"continue\" outside of a loop",
                            -1));
	    } else {
                char buf[32 + TCL_INTEGER_SPACE];

                sprintf(buf, "command returned bad code: %d", result);
                Tcl_SetObjResult(targetInterp, Tcl_NewStringObj(buf, -1));
	    }
	    result = TCL_ERROR;
	}
    }

    TclTransferResult(targetInterp, result, interp);

    Tcl_Release((ClientData) targetInterp);
    return result;        
}

/*
 *----------------------------------------------------------------------
 *
 * AliasObjCmdDeleteProc --
 *
 *	Is invoked when an alias command is deleted in a slave. Cleans up
 *	all storage associated with this alias.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Deletes the alias record and its entry in the alias table for
 *	the interpreter.
 *
 *----------------------------------------------------------------------
 */

static void
AliasObjCmdDeleteProc(clientData)
    ClientData clientData;	/* The alias record for this alias. */
{
    Alias *aliasPtr;		
    Target *targetPtr;		

    aliasPtr = (Alias *) clientData;
    
    Tcl_DecrRefCount(aliasPtr->namePtr);
    Tcl_DecrRefCount(aliasPtr->prefixPtr);
    Tcl_DeleteHashEntry(aliasPtr->aliasEntryPtr);

    targetPtr = (Target *) Tcl_GetHashValue(aliasPtr->targetEntryPtr);
    ckfree((char *) targetPtr);
    Tcl_DeleteHashEntry(aliasPtr->targetEntryPtr);

    ckfree((char *) aliasPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateSlave --
 *
 *	Creates a slave interpreter. The slavePath argument denotes the
 *	name of the new slave relative to the current interpreter; the
 *	slave is a direct descendant of the one-before-last component of
 *	the path, e.g. it is a descendant of the current interpreter if
 *	the slavePath argument contains only one component. Optionally makes
 *	the slave interpreter safe.
 *
 * Results:
 *	Returns the interpreter structure created, or NULL if an error
 *	occurred.
 *
 * Side effects:
 *	Creates a new interpreter and a new interpreter object command in
 *	the interpreter indicated by the slavePath argument.
 *
 *----------------------------------------------------------------------
 */

Tcl_Interp *
Tcl_CreateSlave(interp, slavePath, isSafe)
    Tcl_Interp *interp;		/* Interpreter to start search at. */
    char *slavePath;		/* Name of slave to create. */
    int isSafe;			/* Should new slave be "safe" ? */
{
    Tcl_Obj *pathPtr;
    Tcl_Interp *slaveInterp;

    pathPtr = Tcl_NewStringObj(slavePath, -1);
    slaveInterp = SlaveCreate(interp, pathPtr, isSafe);
    Tcl_DecrRefCount(pathPtr);

    return slaveInterp;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetSlave --
 *
 *	Finds a slave interpreter by its path name.
 *
 * Results:
 *	Returns a Tcl_Interp * for the named interpreter or NULL if not
 *	found.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Interp *
Tcl_GetSlave(interp, slavePath)
    Tcl_Interp *interp;		/* Interpreter to start search from. */
    char *slavePath;		/* Path of slave to find. */
{
    Tcl_Obj *pathPtr;
    Tcl_Interp *slaveInterp;

    pathPtr = Tcl_NewStringObj(slavePath, -1);
    slaveInterp = GetInterp(interp, pathPtr);
    Tcl_DecrRefCount(pathPtr);

    return slaveInterp;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetMaster --
 *
 *	Finds the master interpreter of a slave interpreter.
 *
 * Results:
 *	Returns a Tcl_Interp * for the master interpreter or NULL if none.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Interp *
Tcl_GetMaster(interp)
    Tcl_Interp *interp;		/* Get the master of this interpreter. */
{
    Slave *slavePtr;		/* Slave record of this interpreter. */

    if (interp == (Tcl_Interp *) NULL) {
        return NULL;
    }
    slavePtr = &((InterpInfo *) ((Interp *) interp)->interpInfo)->slave;
    return slavePtr->masterInterp;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetInterpPath --
 *
 *	Sets the result of the asking interpreter to a proper Tcl list
 *	containing the names of interpreters between the asking and
 *	target interpreters. The target interpreter must be either the
 *	same as the asking interpreter or one of its slaves (including
 *	recursively).
 *
 * Results:
 *	TCL_OK if the target interpreter is the same as, or a descendant
 *	of, the asking interpreter; TCL_ERROR else. This way one can
 *	distinguish between the case where the asking and target interps
 *	are the same (an empty list is the result, and TCL_OK is returned)
 *	and when the target is not a descendant of the asking interpreter
 *	(in which case the Tcl result is an error message and the function
 *	returns TCL_ERROR).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetInterpPath(askingInterp, targetInterp)
    Tcl_Interp *askingInterp;	/* Interpreter to start search from. */
    Tcl_Interp *targetInterp;	/* Interpreter to find. */
{
    InterpInfo *iiPtr;
    
    if (targetInterp == askingInterp) {
        return TCL_OK;
    }
    if (targetInterp == NULL) {
	return TCL_ERROR;
    }
    iiPtr = (InterpInfo *) ((Interp *) targetInterp)->interpInfo;
    if (Tcl_GetInterpPath(askingInterp, iiPtr->slave.masterInterp) != TCL_OK) {
        return TCL_ERROR;
    }
    Tcl_AppendElement(askingInterp,
	    Tcl_GetHashKey(&iiPtr->master.slaveTable,
		    iiPtr->slave.slaveEntryPtr));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetInterp --
 *
 *	Helper function to find a slave interpreter given a pathname.
 *
 * Results:
 *	Returns the slave interpreter known by that name in the calling
 *	interpreter, or NULL if no interpreter known by that name exists. 
 *
 * Side effects:
 *	Assigns to the pointer variable passed in, if not NULL.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Interp *
GetInterp(interp, pathPtr)
    Tcl_Interp *interp;		/* Interp. to start search from. */
    Tcl_Obj *pathPtr;		/* List object containing name of interp. to 
				 * be found. */
{
    Tcl_HashEntry *hPtr;	/* Search element. */
    Slave *slavePtr;		/* Interim slave record. */
    Tcl_Obj **objv;
    int objc, i;	
    Tcl_Interp *searchInterp;	/* Interim storage for interp. to find. */
    InterpInfo *masterInfoPtr;

    if (Tcl_ListObjGetElements(interp, pathPtr, &objc, &objv) != TCL_OK) {
	return NULL;
    }

    searchInterp = interp;
    for (i = 0; i < objc; i++) {
	masterInfoPtr = (InterpInfo *) ((Interp *) searchInterp)->interpInfo;
        hPtr = Tcl_FindHashEntry(&masterInfoPtr->master.slaveTable,
		Tcl_GetString(objv[i]));
        if (hPtr == NULL) {
	    searchInterp = NULL;
	    break;
	}
        slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
        searchInterp = slavePtr->slaveInterp;
        if (searchInterp == NULL) {
	    break;
	}
    }
    if (searchInterp == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"could not find interpreter \"",
                Tcl_GetString(pathPtr), "\"", (char *) NULL);
    }
    return searchInterp;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveCreate --
 *
 *	Helper function to do the actual work of creating a slave interp
 *	and new object command. Also optionally makes the new slave
 *	interpreter "safe".
 *
 * Results:
 *	Returns the new Tcl_Interp * if successful or NULL if not. If failed,
 *	the result of the invoking interpreter contains an error message.
 *
 * Side effects:
 *	Creates a new slave interpreter and a new object command.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Interp *
SlaveCreate(interp, pathPtr, safe)
    Tcl_Interp *interp;		/* Interp. to start search from. */
    Tcl_Obj *pathPtr;		/* Path (name) of slave to create. */
    int safe;			/* Should we make it "safe"? */
{
    Tcl_Interp *masterInterp, *slaveInterp;
    Slave *slavePtr;
    InterpInfo *masterInfoPtr;
    Tcl_HashEntry *hPtr;
    char *path;
    int new, objc;
    Tcl_Obj **objv;

    if (Tcl_ListObjGetElements(interp, pathPtr, &objc, &objv) != TCL_OK) {
	return NULL;
    }
    if (objc < 2) {
	masterInterp = interp;
	path = Tcl_GetString(pathPtr);
    } else {
	Tcl_Obj *objPtr;
	
	objPtr = Tcl_NewListObj(objc - 1, objv);
	masterInterp = GetInterp(interp, objPtr);
	Tcl_DecrRefCount(objPtr);
	if (masterInterp == NULL) {
	    return NULL;
	}
	path = Tcl_GetString(objv[objc - 1]);
    }
    if (safe == 0) {
	safe = Tcl_IsSafe(masterInterp);
    }

    masterInfoPtr = (InterpInfo *) ((Interp *) masterInterp)->interpInfo;
    hPtr = Tcl_CreateHashEntry(&masterInfoPtr->master.slaveTable, path, &new);
    if (new == 0) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter named \"", path,
		"\" already exists, cannot create", (char *) NULL);
        return NULL;
    }

    slaveInterp = Tcl_CreateInterp();
    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
    slavePtr->masterInterp = masterInterp;
    slavePtr->slaveEntryPtr = hPtr;
    slavePtr->slaveInterp = slaveInterp;
    slavePtr->interpCmd = Tcl_CreateObjCommand(masterInterp, path,
            SlaveObjCmd, (ClientData) slaveInterp, SlaveObjCmdDeleteProc);
    Tcl_InitHashTable(&slavePtr->aliasTable, TCL_STRING_KEYS);
    Tcl_SetHashValue(hPtr, (ClientData) slavePtr);
    Tcl_SetVar(slaveInterp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
    
    /*
     * Inherit the recursion limit.
     */
    ((Interp *) slaveInterp)->maxNestingDepth =
	((Interp *) masterInterp)->maxNestingDepth ;

    if (safe) {
        if (Tcl_MakeSafe(slaveInterp) == TCL_ERROR) {
            goto error;
        }
    } else {
        if (Tcl_Init(slaveInterp) == TCL_ERROR) {
            goto error;
        }
    }
    return slaveInterp;

    error:
    TclTransferResult(slaveInterp, TCL_ERROR, interp);
    Tcl_DeleteInterp(slaveInterp);

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveObjCmd --
 *
 *	Command to manipulate an interpreter, e.g. to send commands to it
 *	to be evaluated. One such command exists for each slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See user documentation for details.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Slave interpreter. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Interp *slaveInterp;
    int index;
    static char *options[] = {
        "alias",	"aliases",	"eval",		"expose",
        "hide",		"hidden",	"issafe",	"invokehidden",
        "marktrusted",	NULL
    };
    enum options {
	OPT_ALIAS,	OPT_ALIASES,	OPT_EVAL,	OPT_EXPOSE,
	OPT_HIDE,	OPT_HIDDEN,	OPT_ISSAFE,	OPT_INVOKEHIDDEN,
	OPT_MARKTRUSTED
    };
    
    slaveInterp = (Tcl_Interp *) clientData;
    if (slaveInterp == NULL) {
	panic("SlaveObjCmd: interpreter has been deleted");
    }

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?");
        return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
	case OPT_ALIAS: {
	    if (objc == 3) {
		return AliasDescribe(interp, slaveInterp, objv[2]);
	    }
	    if (Tcl_GetString(objv[3])[0] == '\0') {
		if (objc == 4) {
		    return AliasDelete(interp, slaveInterp, objv[2]);
		}
	    } else {
		return AliasCreate(interp, slaveInterp, interp, objv[2],
			objv[3], objc - 4, objv + 4);
	    }
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "aliasName ?targetName? ?args..?");
            return TCL_ERROR;
	}
	case OPT_ALIASES: {
	    return AliasList(interp, slaveInterp);
	}
	case OPT_EVAL: {
	    if (objc < 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "arg ?arg ...?");
		return TCL_ERROR;
	    }
	    return SlaveEval(interp, slaveInterp, objc - 2, objv + 2);
	}
        case OPT_EXPOSE: {
	    if ((objc < 3) || (objc > 4)) {
		Tcl_WrongNumArgs(interp, 2, objv, "hiddenCmdName ?cmdName?");
		return TCL_ERROR;
	    }
            return SlaveExpose(interp, slaveInterp, objc - 2, objv + 2);
	}
	case OPT_HIDE: {
	    if ((objc < 3) || (objc > 4)) {
		Tcl_WrongNumArgs(interp, 2, objv, "cmdName ?hiddenCmdName?");
		return TCL_ERROR;
	    }
            return SlaveHide(interp, slaveInterp, objc - 2, objv + 2);
	}
        case OPT_HIDDEN: {
	    if (objc != 2) {
		Tcl_WrongNumArgs(interp, 2, objv, NULL);
		return TCL_ERROR;
	    }
            return SlaveHidden(interp, slaveInterp);
	}
        case OPT_ISSAFE: {
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), Tcl_IsSafe(slaveInterp));
	    return TCL_OK;
	}
        case OPT_INVOKEHIDDEN: {
	    int global, i, index;
	    static char *hiddenOptions[] = {
		"-global",	"--",		NULL
	    };
	    enum hiddenOption {
		OPT_GLOBAL,	OPT_LAST
	    };
	    global = 0;
	    for (i = 2; i < objc; i++) {
		if (Tcl_GetString(objv[i])[0] != '-') {
		    break;
		}
		if (Tcl_GetIndexFromObj(interp, objv[i], hiddenOptions,
			"option", 0, &index) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (index == OPT_GLOBAL) {
		    global = 1;
		} else {
		    i++;
		    break;
		}
	    }
	    if (objc - i < 1) {
		Tcl_WrongNumArgs(interp, 2, objv,
			"?-global? ?--? cmd ?arg ..?");
		return TCL_ERROR;
	    }
	    return SlaveInvokeHidden(interp, slaveInterp, global, objc - i,
		    objv + i);
	}
	case OPT_MARKTRUSTED: {
	    if (objc != 2) {
		Tcl_WrongNumArgs(interp, 2, objv, NULL);
		return TCL_ERROR;
	    }
            return SlaveMarkTrusted(interp, slaveInterp);
	}
    }

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveObjCmdDeleteProc --
 *
 *	Invoked when an object command for a slave interpreter is deleted;
 *	cleans up all state associated with the slave interpreter and destroys
 *	the slave interpreter.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Cleans up all state associated with the slave interpreter and
 *	destroys the slave interpreter.
 *
 *----------------------------------------------------------------------
 */

static void
SlaveObjCmdDeleteProc(clientData)
    ClientData clientData;		/* The SlaveRecord for the command. */
{
    Slave *slavePtr;			/* Interim storage for Slave record. */
    Tcl_Interp *slaveInterp;		/* And for a slave interp. */

    slaveInterp = (Tcl_Interp *) clientData;
    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;

    /*
     * Unlink the slave from its master interpreter.
     */

    Tcl_DeleteHashEntry(slavePtr->slaveEntryPtr);

    /*
     * Set to NULL so that when the InterpInfo is cleaned up in the slave
     * it does not try to delete the command causing all sorts of grief.
     * See SlaveRecordDeleteProc().
     */

    slavePtr->interpCmd = NULL;

    if (slavePtr->slaveInterp != NULL) {
	Tcl_DeleteInterp(slavePtr->slaveInterp);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveEval --
 *
 *	Helper function to evaluate a command in a slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Whatever the command does.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveEval(interp, slaveInterp, objc, objv)
    Tcl_Interp *interp;		/* Interp for error return. */
    Tcl_Interp *slaveInterp;	/* The slave interpreter in which command
				 * will be evaluated. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int result;
    Tcl_Obj *objPtr;
    
    Tcl_Preserve((ClientData) slaveInterp);
    Tcl_AllowExceptions(slaveInterp);

    if (objc == 1) {
	result = Tcl_EvalObjEx(slaveInterp, objv[0], 0);
    } else {
	objPtr = Tcl_ConcatObj(objc, objv);
	Tcl_IncrRefCount(objPtr);
	result = Tcl_EvalObjEx(slaveInterp, objPtr, 0);
	Tcl_DecrRefCount(objPtr);
    }
    TclTransferResult(slaveInterp, result, interp);

    Tcl_Release((ClientData) slaveInterp);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveExpose --
 *
 *	Helper function to expose a command in a slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	After this call scripts in the slave will be able to invoke
 *	the newly exposed command.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveExpose(interp, slaveInterp, objc, objv)
    Tcl_Interp *interp;		/* Interp for error return. */
    Tcl_Interp	*slaveInterp;	/* Interp in which command will be exposed. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument strings. */
{
    char *name;
    
    if (Tcl_IsSafe(interp)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"permission denied: safe interpreter cannot expose commands",
		(char *) NULL);
	return TCL_ERROR;
    }

    name = Tcl_GetString(objv[(objc == 1) ? 0 : 1]);
    if (Tcl_ExposeCommand(slaveInterp, Tcl_GetString(objv[0]),
	    name) != TCL_OK) {
	TclTransferResult(slaveInterp, TCL_ERROR, interp);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveHide --
 *
 *	Helper function to hide a command in a slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	After this call scripts in the slave will no longer be able
 *	to invoke the named command.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveHide(interp, slaveInterp, objc, objv)
    Tcl_Interp *interp;		/* Interp for error return. */
    Tcl_Interp	*slaveInterp;	/* Interp in which command will be exposed. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument strings. */
{
    char *name;
    
    if (Tcl_IsSafe(interp)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"permission denied: safe interpreter cannot hide commands",
		(char *) NULL);
	return TCL_ERROR;
    }

    name = Tcl_GetString(objv[(objc == 1) ? 0 : 1]);
    if (Tcl_HideCommand(slaveInterp, Tcl_GetString(objv[0]),
	    name) != TCL_OK) {
	TclTransferResult(slaveInterp, TCL_ERROR, interp);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveHidden --
 *
 *	Helper function to compute list of hidden commands in a slave
 *	interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveHidden(interp, slaveInterp)
    Tcl_Interp *interp;		/* Interp for data return. */
    Tcl_Interp *slaveInterp;	/* Interp whose hidden commands to query. */
{
    Tcl_Obj *listObjPtr;		/* Local object pointer. */
    Tcl_HashTable *hTblPtr;		/* For local searches. */
    Tcl_HashEntry *hPtr;		/* For local searches. */
    Tcl_HashSearch hSearch;		/* For local searches. */
    
    listObjPtr = Tcl_GetObjResult(interp);
    hTblPtr = ((Interp *) slaveInterp)->hiddenCmdTablePtr;
    if (hTblPtr != (Tcl_HashTable *) NULL) {
	for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
	     hPtr != (Tcl_HashEntry *) NULL;
	     hPtr = Tcl_NextHashEntry(&hSearch)) {

	    Tcl_ListObjAppendElement(NULL, listObjPtr,
		    Tcl_NewStringObj(Tcl_GetHashKey(hTblPtr, hPtr), -1));
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveInvokeHidden --
 *
 *	Helper function to invoke a hidden command in a slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Whatever the hidden command does.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveInvokeHidden(interp, slaveInterp, global, objc, objv)
    Tcl_Interp *interp;		/* Interp for error return. */
    Tcl_Interp *slaveInterp;	/* The slave interpreter in which command
				 * will be invoked. */
    int global;			/* Non-zero to invoke in global namespace. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int result;
    
    if (Tcl_IsSafe(interp)) {
	Tcl_SetStringObj(Tcl_GetObjResult(interp),
		"not allowed to invoke hidden commands from safe interpreter",
		-1);
	return TCL_ERROR;
    }

    Tcl_Preserve((ClientData) slaveInterp);
    Tcl_AllowExceptions(slaveInterp);
    
    if (global) {
        result = TclObjInvokeGlobal(slaveInterp, objc, objv,
                TCL_INVOKE_HIDDEN);
    } else {
        result = TclObjInvoke(slaveInterp, objc, objv, TCL_INVOKE_HIDDEN);
    }

    TclTransferResult(slaveInterp, result, interp);

    Tcl_Release((ClientData) slaveInterp);
    return result;        
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveMarkTrusted --
 *
 *	Helper function to mark a slave interpreter as trusted (unsafe).
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	After this call the hard-wired security checks in the core no
 *	longer prevent the slave from performing certain operations.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveMarkTrusted(interp, slaveInterp)
    Tcl_Interp *interp;		/* Interp for error return. */
    Tcl_Interp *slaveInterp;	/* The slave interpreter which will be
				 * marked trusted. */
{
    if (Tcl_IsSafe(interp)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"permission denied: safe interpreter cannot mark trusted",
		(char *) NULL);
	return TCL_ERROR;
    }
    ((Interp *) slaveInterp)->flags &= ~SAFE_INTERP;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_IsSafe --
 *
 *	Determines whether an interpreter is safe
 *
 * Results:
 *	1 if it is safe, 0 if it is not.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_IsSafe(interp)
    Tcl_Interp *interp;		/* Is this interpreter "safe" ? */
{
    Interp *iPtr;

    if (interp == (Tcl_Interp *) NULL) {
        return 0;
    }
    iPtr = (Interp *) interp;

    return ( (iPtr->flags) & SAFE_INTERP ) ? 1 : 0 ;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_MakeSafe --
 *
 *	Makes its argument interpreter contain only functionality that is
392
393
394
395
396
397
398

399
400
401
402
403
404

405
406
407
408
409
410
411
    /* 
     * Remove unsafe parts of tcl_platform
     */

    Tcl_UnsetVar2(interp, "tcl_platform", "os", TCL_GLOBAL_ONLY);
    Tcl_UnsetVar2(interp, "tcl_platform", "osVersion", TCL_GLOBAL_ONLY);
    Tcl_UnsetVar2(interp, "tcl_platform", "machine", TCL_GLOBAL_ONLY);


    /*
     * Unset path informations variables
     * (the only one remaining is [info nameofexecutable])
     */


    Tcl_UnsetVar(interp, "tcl_library", TCL_GLOBAL_ONLY);
    Tcl_UnsetVar(interp, "tcl_pkgPath", TCL_GLOBAL_ONLY);
    
    /*
     * Remove the standard channels from the interpreter; safe interpreters
     * do not ordinarily have access to stdin, stdout and stderr.
     *







>






>







2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
    /* 
     * Remove unsafe parts of tcl_platform
     */

    Tcl_UnsetVar2(interp, "tcl_platform", "os", TCL_GLOBAL_ONLY);
    Tcl_UnsetVar2(interp, "tcl_platform", "osVersion", TCL_GLOBAL_ONLY);
    Tcl_UnsetVar2(interp, "tcl_platform", "machine", TCL_GLOBAL_ONLY);
    Tcl_UnsetVar2(interp, "tcl_platform", "user", TCL_GLOBAL_ONLY);

    /*
     * Unset path informations variables
     * (the only one remaining is [info nameofexecutable])
     */

    Tcl_UnsetVar(interp, "tclDefaultLibrary", TCL_GLOBAL_ONLY);
    Tcl_UnsetVar(interp, "tcl_library", TCL_GLOBAL_ONLY);
    Tcl_UnsetVar(interp, "tcl_pkgPath", TCL_GLOBAL_ONLY);
    
    /*
     * Remove the standard channels from the interpreter; safe interpreters
     * do not ordinarily have access to stdin, stdout and stderr.
     *
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
        Tcl_UnregisterChannel(interp, chan);
    }
    chan = Tcl_GetStdChannel(TCL_STDERR);
    if (chan != (Tcl_Channel) NULL) {
        Tcl_UnregisterChannel(interp, chan);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetInterp --
 *
 *	Helper function to find a slave interpreter given a pathname.
 *
 * Results:
 *	Returns the slave interpreter known by that name in the calling
 *	interpreter, or NULL if no interpreter known by that name exists. 
 *
 * Side effects:
 *	Assigns to the pointer variable passed in, if not NULL.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Interp *
GetInterp(interp, masterPtr, path, masterPtrPtr)
    Tcl_Interp *interp;		/* Interp. to start search from. */
    Master *masterPtr;		/* Its master record. */
    char *path;			/* The path (name) of interp. to be found. */
    Master **masterPtrPtr;	/* (Return) its master record. */
{
    Tcl_HashEntry *hPtr;	/* Search element. */
    Slave *slavePtr;		/* Interim slave record. */
    char **argv;		/* Split-up path (name) for interp to find. */
    int argc, i;		/* Loop indices. */
    Tcl_Interp *searchInterp;	/* Interim storage for interp. to find. */

    if (masterPtrPtr != (Master **) NULL) {
        *masterPtrPtr = masterPtr;
    }
    
    if (Tcl_SplitList(interp, path, &argc, &argv) != TCL_OK) {
        return (Tcl_Interp *) NULL;
    }

    for (searchInterp = interp, i = 0; i < argc; i++) {
        
        hPtr = Tcl_FindHashEntry(&(masterPtr->slaveTable), argv[i]);
        if (hPtr == (Tcl_HashEntry *) NULL) {
            ckfree((char *) argv);
            return (Tcl_Interp *) NULL;
        }
        slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
        searchInterp = slavePtr->slaveInterp;
        if (searchInterp == (Tcl_Interp *) NULL) {
            ckfree((char *) argv);
            return (Tcl_Interp *) NULL;
        }
        masterPtr = (Master *) Tcl_GetAssocData(searchInterp,
                "tclMasterRecord", NULL);
        if (masterPtrPtr != (Master **) NULL) *masterPtrPtr = masterPtr;
        if (masterPtr == (Master *) NULL) {
            ckfree((char *) argv);
            return (Tcl_Interp *) NULL;
        }
    }
    ckfree((char *) argv);
    return searchInterp;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateSlave --
 *
 *	Helper function to do the actual work of creating a slave interp
 *	and new object command. Also optionally makes the new slave
 *	interpreter "safe".
 *
 * Results:
 *	Returns the new Tcl_Interp * if successful or NULL if not. If failed,
 *	the result of the invoking interpreter contains an error message.
 *
 * Side effects:
 *	Creates a new slave interpreter and a new object command.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Interp *
CreateSlave(interp, masterPtr, slavePath, safe)
    Tcl_Interp *interp;			/* Interp. to start search from. */
    Master *masterPtr;			/* Master record. */
    char *slavePath;			/* Path (name) of slave to create. */
    int safe;				/* Should we make it "safe"? */
{
    Tcl_Interp *slaveInterp;		/* Ptr to slave interpreter. */
    Tcl_Interp *masterInterp;		/* Ptr to master interp for slave. */
    Slave *slavePtr;			/* Slave record. */
    Tcl_HashEntry *hPtr;		/* Entry into interp hashtable. */
    int new;				/* Indicates whether new entry. */
    int argc;				/* Count of elements in slavePath. */
    char **argv;			/* Elements in slavePath. */
    char *masterPath;			/* Path to its master. */

    if (Tcl_SplitList(interp, slavePath, &argc, &argv) != TCL_OK) {
        return (Tcl_Interp *) NULL;
    }

    if (argc < 2) {
        masterInterp = interp;
        if (argc == 1) {
            slavePath = argv[0];
        }
    } else {
        masterPath = Tcl_Merge(argc-1, argv);
        masterInterp = GetInterp(interp, masterPtr, masterPath, &masterPtr);
        if (masterInterp == (Tcl_Interp *) NULL) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "interpreter named \"", masterPath,
                    "\" not found", (char *) NULL);
            ckfree((char *) argv);
            ckfree((char *) masterPath);
            return (Tcl_Interp *) NULL;
        }
        ckfree((char *) masterPath);
        slavePath = argv[argc-1];
        if (!safe) {
            safe = Tcl_IsSafe(masterInterp);
        }
    }
    hPtr = Tcl_CreateHashEntry(&(masterPtr->slaveTable), slavePath, &new);
    if (new == 0) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter named \"", slavePath,
                "\" already exists, cannot create", (char *) NULL);
        ckfree((char *) argv);
        return (Tcl_Interp *) NULL;
    }
    slaveInterp = Tcl_CreateInterp();
    if (slaveInterp == (Tcl_Interp *) NULL) {
        panic("CreateSlave: out of memory while creating a new interpreter");
    }
    slavePtr = (Slave *) Tcl_GetAssocData(slaveInterp, "tclSlaveRecord", NULL);
    slavePtr->masterInterp = masterInterp;
    slavePtr->slaveEntry = hPtr;
    slavePtr->slaveInterp = slaveInterp;
    slavePtr->interpCmd = Tcl_CreateObjCommand(masterInterp, slavePath,
            SlaveObjectCmd, (ClientData) slaveInterp, SlaveObjectDeleteProc);
    Tcl_InitHashTable(&(slavePtr->aliasTable), TCL_STRING_KEYS);
    (void) Tcl_SetAssocData(slaveInterp, "tclSlaveRecord",
            SlaveRecordDeleteProc, (ClientData) slavePtr);
    Tcl_SetHashValue(hPtr, (ClientData) slavePtr);
    Tcl_SetVar(slaveInterp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
    
    /*
     * Inherit the recursion limit.
     */
    ((Interp *)slaveInterp)->maxNestingDepth =
	((Interp *)masterInterp)->maxNestingDepth ;

    if (safe) {
        if (Tcl_MakeSafe(slaveInterp) == TCL_ERROR) {
            goto error;
        }
    } else {
        if (Tcl_Init(slaveInterp) == TCL_ERROR) {
            goto error;
        }
    }

    ckfree((char *) argv);
    return slaveInterp;

error:

    Tcl_AddErrorInfo(interp, Tcl_GetVar2(slaveInterp, "errorInfo", (char *)
            NULL, TCL_GLOBAL_ONLY));
    Tcl_SetVar2(interp, "errorCode", (char *) NULL,
            Tcl_GetVar2(slaveInterp, "errorCode", (char *) NULL,
                    TCL_GLOBAL_ONLY),
            TCL_GLOBAL_ONLY);

    Tcl_SetObjResult(interp, Tcl_GetObjResult(slaveInterp));
    Tcl_ResetResult(slaveInterp);

    (void) Tcl_DeleteCommand(masterInterp, slavePath);

    ckfree((char *) argv);
    return (Tcl_Interp *) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateInterpObject -
 *
 *	Helper function to do the actual work of creating a new interpreter
 *	and an object command. 
 *
 * Results:
 *	A Tcl result.
 *
 * Side effects:
 *	See user documentation for details.
 *
 *----------------------------------------------------------------------
 */

static int
CreateInterpObject(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Invoking interpreter. */
    Master *masterPtr;			/* Master record for same. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* with alias. */
{
    int safe;				/* Create a safe interpreter? */
    int moreFlags;			/* Expecting more flag args? */
    char *string;			/* Local pointer to object string. */
    char *slavePath;			/* Name of slave. */
    char localSlaveName[200];		/* Local area for creating names. */
    int i;				/* Loop counter. */
    int len;				/* Length of option argument. */
    static int interpCounter = 0;	/* Unique id for created names. */

    moreFlags = 1;
    slavePath = NULL;
    safe = Tcl_IsSafe(interp);
    
    if ((objc < 2) || (objc > 5)) {
        Tcl_WrongNumArgs(interp, 2, objv, "?-safe? ?--? ?path?");
        return TCL_ERROR;
    }
    for (i = 2; i < objc; i++) {
        string = Tcl_GetStringFromObj(objv[i], &len);
        if ((string[0] == '-') && (moreFlags != 0)) {
            if ((string[1] == 's') &&
                (strncmp(string, "-safe", (size_t) len) == 0) &&
                (len > 1)){
                safe = 1;
            } else if ((strncmp(string, "--", (size_t) len) == 0) &&
                       (len > 1)) {
                moreFlags = 0;
            } else {
                Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                        "bad option \"", string, "\": should be -safe",
                        (char *) NULL);
                return TCL_ERROR;
            }
        } else {
            slavePath = string;
        }
    }
    if (slavePath == (char *) NULL) {

        /*
         * Create an anonymous interpreter -- we choose its name and
         * the name of the command. We check that the command name that
         * we use for the interpreter does not collide with an existing
         * command in the master interpreter.
         */
        
        while (1) {
            Tcl_CmdInfo cmdInfo;
            
            sprintf(localSlaveName, "interp%d", interpCounter);
            interpCounter++;
            if (!(Tcl_GetCommandInfo(interp, localSlaveName, &cmdInfo))) {
                break;
            }
        }
        slavePath = localSlaveName;
    }
    if (CreateSlave(interp, masterPtr, slavePath, safe) != NULL) {
        Tcl_SetObjResult(interp, Tcl_NewStringObj(slavePath, -1));
        return TCL_OK;
    } else {
        /*
         * CreateSlave already set the result if there was an error,
         * so we do not do it here.
         */
        return TCL_ERROR;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteOneInterpObject --
 *
 *	Helper function for DeleteInterpObject. It deals with deleting one
 *	interpreter at a time.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Deletes an interpreter and its interpreter object command.
 *
 *----------------------------------------------------------------------
 */

static int
DeleteOneInterpObject(interp, masterPtr, path)
    Tcl_Interp *interp;			/* Interpreter for reporting errors. */
    Master *masterPtr;			/* Interim storage for master record.*/
    char *path;				/* Path of interpreter to delete. */
{
    Slave *slavePtr;			/* Interim storage for slave record. */
    Tcl_Interp *masterInterp;		/* Master of interp. to delete. */
    Tcl_HashEntry *hPtr;		/* Search element. */
    int localArgc;			/* Local copy of count of elements in
                                         * path (name) of interp. to delete. */
    char **localArgv;			/* Local copy of path. */
    char *slaveName;			/* Last component in path. */
    char *masterPath;			/* One-before-last component in path.*/

    if (Tcl_SplitList(interp, path, &localArgc, &localArgv) != TCL_OK) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "bad interpreter path \"", path, "\"", (char *) NULL);
        return TCL_ERROR;
    }
    if (localArgc < 2) {
        masterInterp = interp;
        if (localArgc == 0) {
            slaveName = "";
        } else {
            slaveName = localArgv[0];
        }
    } else {
        masterPath = Tcl_Merge(localArgc-1, localArgv);
        masterInterp = GetInterp(interp, masterPtr, masterPath, &masterPtr);
        if (masterInterp == (Tcl_Interp *) NULL) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "interpreter named \"", masterPath, "\" not found",
                    (char *) NULL);
            ckfree((char *) localArgv);
            ckfree((char *) masterPath);
            return TCL_ERROR;
        }
        ckfree((char *) masterPath);
        slaveName = localArgv[localArgc-1];
    }
    hPtr = Tcl_FindHashEntry(&(masterPtr->slaveTable), slaveName);
    if (hPtr == (Tcl_HashEntry *) NULL) {
        ckfree((char *) localArgv);
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter named \"", path, "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
    if (Tcl_DeleteCommandFromToken(masterInterp, slavePtr->interpCmd) != 0) {
        ckfree((char *) localArgv);
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter named \"", path, "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    ckfree((char *) localArgv);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteInterpObject --
 *
 *	Helper function to do the work of deleting zero or more
 *	interpreters and their interpreter object commands.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Deletes interpreters and their interpreter object command.
 *
 *----------------------------------------------------------------------
 */

static int
DeleteInterpObject(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Interpreter start search from. */
    Master *masterPtr;			/* Interim storage for master record.*/
    int objc;				/* Number of arguments in vector. */
    Tcl_Obj *CONST objv[];		/* with alias. */
{
    int i;
    int len;
    
    for (i = 2; i < objc; i++) {
        if (DeleteOneInterpObject(interp, masterPtr,
                Tcl_GetStringFromObj(objv[i], &len))
                != TCL_OK) {
            return TCL_ERROR;
        }
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * AliasCreationHelper --
 *
 *	Helper function to do the work to actually create an alias or
 *	delete an alias.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	An alias command is created and entered into the alias table
 *	for the slave interpreter.
 *
 *----------------------------------------------------------------------
 */

static int
AliasCreationHelper(curInterp, slaveInterp, masterInterp, masterPtr,
     aliasName, targetName, objc, objv)
    Tcl_Interp *curInterp;		/* Interp that invoked this proc. */
    Tcl_Interp *slaveInterp;		/* Interp where alias cmd will live
                                         * or from which alias will be
                                         * deleted. */
    Tcl_Interp *masterInterp;		/* Interp where target cmd will be. */
    Master *masterPtr;			/* Master record for target interp. */
    char *aliasName;			/* Name of alias cmd. */
    char *targetName;			/* Name of target cmd. */
    int objc;				/* Additional arguments to store */
    Tcl_Obj *CONST objv[];		/* with alias. */
{
    Alias *aliasPtr;			/* Storage for alias data. */
    Alias *tmpAliasPtr;			/* Temp storage for alias to delete. */
    Tcl_HashEntry *hPtr;		/* Entry into interp hashtable. */
    int i;				/* Loop index. */
    int new;				/* Is it a new hash entry? */
    Target *targetPtr;			/* Maps from target command in master
                                         * to source command in slave. */
    Slave *slavePtr;			/* Maps from source command in slave
                                         * to target command in master. */

    slavePtr = (Slave *) Tcl_GetAssocData(slaveInterp, "tclSlaveRecord", NULL);

    /*
     * Slave record should be always present because it is created when
     * the interpreter is created.
     */
    
    if (slavePtr == (Slave *) NULL) {
        panic("AliasCreationHelper: could not find slave record");
    }

    if ((targetName == (char *) NULL) || (targetName[0] == '\0')) {
        if (objc != 0) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(curInterp),
                    "malformed command: should be",
                    " \"alias ",  aliasName, " {}\"", (char *) NULL);
            return TCL_ERROR;
        }

        return DeleteAlias(curInterp, slaveInterp, aliasName);
    }
    
    aliasPtr = (Alias *) ckalloc((unsigned) sizeof(Alias));
    aliasPtr->aliasName = (char *) ckalloc((unsigned) strlen(aliasName)+1);
    aliasPtr->targetName = (char *) ckalloc((unsigned) strlen(targetName)+1);
    strcpy(aliasPtr->aliasName, aliasName);
    strcpy(aliasPtr->targetName, targetName);
    aliasPtr->targetInterp = masterInterp;

    aliasPtr->objv = NULL;
    aliasPtr->objc = objc;

    if (aliasPtr->objc > 0) {
        aliasPtr->objv =
            (Tcl_Obj **) ckalloc((unsigned) sizeof(Tcl_Obj *) *
                    aliasPtr->objc);
        for (i = 0; i < objc; i++) {
            aliasPtr->objv[i] = objv[i];
            Tcl_IncrRefCount(objv[i]);
        }
    }

    aliasPtr->slaveCmd = Tcl_CreateObjCommand(slaveInterp, aliasName,
            AliasCmd, (ClientData) aliasPtr, AliasCmdDeleteProc);

    if (TclPreventAliasLoop(curInterp, slaveInterp, 
            aliasPtr->slaveCmd) != TCL_OK) {

	/*
         *  Found an alias loop!  The last call to Tcl_CreateObjCommand
         *  made the alias point to itself.  Delete the command and
         *  its alias record.  Be careful to wipe out its client data
         *  first, so the command doesn't try to delete itself.
         */
	
        Command *cmdPtr = (Command*) aliasPtr->slaveCmd;
        cmdPtr->clientData = NULL;
        cmdPtr->deleteProc = NULL;
        cmdPtr->deleteData = NULL;
        Tcl_DeleteCommandFromToken(slaveInterp, aliasPtr->slaveCmd);

        for (i = 0; i < objc; i++) {
            Tcl_DecrRefCount(aliasPtr->objv[i]);
        }
        if (aliasPtr->objv != (Tcl_Obj *CONST *) NULL) {
            ckfree((char *) aliasPtr->objv);
        }
        ckfree(aliasPtr->aliasName);
        ckfree(aliasPtr->targetName);
        ckfree((char *) aliasPtr);

        /*
         * The result was already set by TclPreventAliasLoop.
         */

        return TCL_ERROR;
    }
    
    /*
     * Make an entry in the alias table. If it already exists delete
     * the alias command. Then retry.
     */

    do {
        hPtr = Tcl_CreateHashEntry(&(slavePtr->aliasTable), aliasName, &new);
        if (!new) {
            tmpAliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
            (void) Tcl_DeleteCommandFromToken(slaveInterp,
	            tmpAliasPtr->slaveCmd);

            /*
             * The hash entry should be deleted by the Tcl_DeleteCommand
             * above, in its command deletion callback (most likely this
             * will be AliasCmdDeleteProc, which does the deletion).
             */
        }
    } while (new == 0);
    aliasPtr->aliasEntry = hPtr;
    Tcl_SetHashValue(hPtr, (ClientData) aliasPtr);
    
    /*
     * Create the new command. We must do it after deleting any old command,
     * because the alias may be pointing at a renamed alias, as in:
     *
     * interp alias {} foo {} bar		# Create an alias "foo"
     * rename foo zop				# Now rename the alias
     * interp alias {} foo {} zop		# Now recreate "foo"...
     */

    targetPtr = (Target *) ckalloc((unsigned) sizeof(Target));
    targetPtr->slaveCmd = aliasPtr->slaveCmd;
    targetPtr->slaveInterp = slaveInterp;

    do {
        hPtr = Tcl_CreateHashEntry(&(masterPtr->targetTable),
                (char *) aliasCounter, &new);
	aliasCounter++;
    } while (new == 0);

    Tcl_SetHashValue(hPtr, (ClientData) targetPtr);

    aliasPtr->targetEntry = hPtr;

    /*
     * Make sure we clear out the object result when setting the string
     * result.
     */

    Tcl_SetObjResult(curInterp, Tcl_NewStringObj(aliasPtr->aliasName, -1));
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InterpAliasesHelper --
 *
 *	Computes a list of aliases defined in an interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
InterpAliasesHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Invoking interpreter. */
    Master *masterPtr;			/* Master record for current interp. */
    int objc;				/* How many arguments? */
    Tcl_Obj *CONST objv[];		/* Actual arguments. */
{
    Tcl_Interp *slaveInterp;		/* A slave. */
    Slave *slavePtr;			/* Record for slave interp. */
    Tcl_HashEntry *hPtr;		/* Search variable. */
    Tcl_HashSearch hSearch;		/* Iteration variable. */
    int len;				/* Dummy length variable. */
    Tcl_Obj *listObjPtr, *elemObjPtr;	/* Local object pointers. */
    
    if ((objc != 2) && (objc != 3)) {
        Tcl_WrongNumArgs(interp, 2, objv, "?path?");
        return TCL_ERROR;
    }
    if (objc == 3) {
        slaveInterp = GetInterp(interp, masterPtr,
                Tcl_GetStringFromObj(objv[2], &len), NULL);
        if (slaveInterp == (Tcl_Interp *) NULL) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "interpreter \"", Tcl_GetStringFromObj(objv[2], &len),
                    "\" not found", (char *) NULL);
            return TCL_ERROR;
        }
    } else {
        slaveInterp = interp;
    }
    slavePtr = (Slave *) Tcl_GetAssocData(slaveInterp,
            "tclSlaveRecord", NULL);
    if (slavePtr == (Slave *) NULL) {
        return TCL_OK;
    }

    /*
     * Build a list to return the aliases:
     */
            
    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    for (hPtr = Tcl_FirstHashEntry(&(slavePtr->aliasTable), &hSearch);
         hPtr != NULL;
         hPtr = Tcl_NextHashEntry(&hSearch)) {

        elemObjPtr = Tcl_NewStringObj(
            Tcl_GetHashKey(&(slavePtr->aliasTable), hPtr), -1);
        Tcl_ListObjAppendElement(interp, listObjPtr, elemObjPtr);
    }
    Tcl_SetObjResult(interp, listObjPtr);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InterpAliasHelper -
 *
 *	Handles the different forms of the "interp alias" command:
 *	- interp alias slavePath aliasName
 *		Describes an alias.
 *	- interp alias slavePath aliasName {}
 *		Deletes an alias.
 *	- interp alias slavePath srcCmd masterPath targetCmd args...
 *		Creates an alias.
 *
 * Results:
 *	A Tcl result.
 *
 * Side effects:
 *	See user documentation for details.
 *
 *----------------------------------------------------------------------
 */

static int
InterpAliasHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for current interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Interp *slaveInterp,		/* Interpreters used when */
        *masterInterp;			/* creating an alias btn siblings. */
    Master *masterMasterPtr;		/* Master record for master interp. */
    int len;

    if (objc < 4) {
        Tcl_WrongNumArgs(interp, 2, objv,
                "slavePath slaveCmd masterPath masterCmd ?args ..?");
        return TCL_ERROR;
    }
    slaveInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[2], &len), NULL);
    if (slaveInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "could not find interpreter \"",
                Tcl_GetStringFromObj(objv[2], &len), "\"",
                (char *) NULL);
        return TCL_ERROR;
    }
    if (objc == 4) {
        return DescribeAlias(interp, slaveInterp,
                Tcl_GetStringFromObj(objv[3], &len));
    }
    if (objc == 5 && strcmp(Tcl_GetStringFromObj(objv[4], &len), "") == 0) {
        return DeleteAlias(interp, slaveInterp,
                Tcl_GetStringFromObj(objv[3], &len));
    }
    if (objc < 6) {
        Tcl_WrongNumArgs(interp, 2, objv,
                "slavePath slaveCmd masterPath masterCmd ?args ..?");
        return TCL_ERROR;
    }
    masterInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[4], &len), &masterMasterPtr);
    if (masterInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "could not find interpreter \"",
                Tcl_GetStringFromObj(objv[4], &len), "\"", (char *) NULL);
        return TCL_ERROR;
    }
    return AliasCreationHelper(interp, slaveInterp, masterInterp,
            masterMasterPtr, Tcl_GetStringFromObj(objv[3], &len),
            Tcl_GetStringFromObj(objv[5], &len),
            objc-6, objv+6);
}

/*
 *----------------------------------------------------------------------
 *
 * InterpExistsHelper --
 *
 *	Computes whether a named interpreter exists or not.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
InterpExistsHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for current interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Obj *objPtr;
    int len;

    if (objc > 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "?path?");
        return TCL_ERROR;
    }
    if (objc == 3) {
        if (GetInterp(interp, masterPtr,
                Tcl_GetStringFromObj(objv[2], &len), NULL) ==
                (Tcl_Interp *) NULL) {
            objPtr = Tcl_NewIntObj(0);
        } else {
            objPtr = Tcl_NewIntObj(1);
        }
    } else {
        objPtr = Tcl_NewIntObj(1);
    }
    Tcl_SetObjResult(interp, objPtr);
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InterpEvalHelper --
 *
 *	Helper function to handle all the details of evaluating a
 *	command in another interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Whatever the command itself does.
 *
 *----------------------------------------------------------------------
 */

static int
InterpEvalHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for current interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Interp *slaveInterp;		/* A slave. */
    Interp *iPtr;			/* Internal data type for slave. */
    int len;				/* Dummy length variable. */
    int result;
    Tcl_Obj *namePtr, *objPtr;		/* Local object pointer. */
    char *string;

    if (objc < 4) {
        Tcl_WrongNumArgs(interp, 2, objv, "path arg ?arg ...?");
        return TCL_ERROR;
    }
    slaveInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[2], &len), NULL);
    if (slaveInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter named \"", Tcl_GetStringFromObj(objv[2], &len),
                "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    objPtr = Tcl_ConcatObj(objc-3, objv+3);
    Tcl_IncrRefCount(objPtr);
    
    Tcl_Preserve((ClientData) slaveInterp);
    result = Tcl_EvalObj(slaveInterp, objPtr);

    Tcl_DecrRefCount(objPtr);

    /*
     * Now make the result and any error information accessible. We
     * have to be careful because the slave interpreter and the current
     * interpreter can be the same - do not destroy the result.. This
     * can happen if an interpreter contains an alias which is directed
     * at a target command in the same interpreter.
     */

    if (interp != slaveInterp) {
        if (result == TCL_ERROR) {

            /*
             * An error occurred, so transfer error information from
             * the target interpreter back to our interpreter.
             */

            iPtr = (Interp *) slaveInterp;
            if (!(iPtr->flags & ERR_ALREADY_LOGGED)) {
                Tcl_AddErrorInfo(slaveInterp, "");
            }
            iPtr->flags &= (~(ERR_ALREADY_LOGGED));
            
            Tcl_ResetResult(interp);
            namePtr = Tcl_NewStringObj("errorInfo", -1);
            objPtr = Tcl_ObjGetVar2(slaveInterp, namePtr,
                    (Tcl_Obj *) NULL, TCL_GLOBAL_ONLY);
            string = Tcl_GetStringFromObj(objPtr, &len);
            Tcl_AddObjErrorInfo(interp, string, len);
            Tcl_SetVar2(interp, "errorCode", (char *) NULL,
                    Tcl_GetVar2(slaveInterp, "errorCode", (char *)
                            NULL, TCL_GLOBAL_ONLY),
                    TCL_GLOBAL_ONLY);
            Tcl_DecrRefCount(namePtr);
        }

	/*
         * Move the result object from one interpreter to the
         * other.
         */
                
        Tcl_SetObjResult(interp, Tcl_GetObjResult(slaveInterp));
        Tcl_ResetResult(slaveInterp);

    }
    Tcl_Release((ClientData) slaveInterp);
    return result;        
}

/*
 *----------------------------------------------------------------------
 *
 * InterpExposeHelper --
 *
 *	Helper function to handle the details of exposing a command in
 *	another interpreter.
 *
 * Results:
 *	Standard Tcl result.
 *
 * Side effects:
 *	Exposes a command. From now on the command can be called by scripts
 *	in the interpreter in which it was exposed.
 *
 *----------------------------------------------------------------------
 */

static int
InterpExposeHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for current interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Interp *slaveInterp;		/* A slave. */
    int len;				/* Dummy length variable. */

    if ((objc != 4) && (objc != 5)) {
        Tcl_WrongNumArgs(interp, 2, objv,
                "path hiddenCmdName ?cmdName?");
        return TCL_ERROR;
    }
    if (Tcl_IsSafe(interp)) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "permission denied: safe interpreter cannot expose commands",
                (char *) NULL);
        return TCL_ERROR;
    }
    slaveInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[2], &len), &masterPtr);
    if (slaveInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter \"", Tcl_GetStringFromObj(objv[2], &len),
                "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    if (Tcl_ExposeCommand(slaveInterp,
            Tcl_GetStringFromObj(objv[3], &len),
                (objc == 5 ?
                        Tcl_GetStringFromObj(objv[4], &len) :
                        Tcl_GetStringFromObj(objv[3], &len)))
            == TCL_ERROR) {
        if (interp != slaveInterp) {
            Tcl_SetObjResult(interp, Tcl_GetObjResult(slaveInterp));
            Tcl_ResetResult(slaveInterp);
        }
        return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InterpHideHelper --
 *
 *	Helper function that handles the details of hiding a command in
 *	another interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Hides a command. From now on the command cannot be called by
 *	scripts in that interpreter.
 *
 *----------------------------------------------------------------------
 */

static int
InterpHideHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Interp *slaveInterp;		/* A slave. */
    int len;				/* Dummy length variable. */

    if ((objc != 4) && (objc != 5)) {
        Tcl_WrongNumArgs(interp, 2, objv,
                "path cmdName ?hiddenCmdName?");
        return TCL_ERROR;
    }
    if (Tcl_IsSafe(interp)) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "permission denied: safe interpreter cannot hide commands",
                (char *) NULL);
        return TCL_ERROR;
    }
    slaveInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[2], &len), &masterPtr);
    if (slaveInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter \"", Tcl_GetStringFromObj(objv[2], &len),
                "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    if (Tcl_HideCommand(slaveInterp, Tcl_GetStringFromObj(objv[3], &len),
            (objc == 5 ?
                    Tcl_GetStringFromObj(objv[4], &len) :
                    Tcl_GetStringFromObj(objv[3], &len)))
            == TCL_ERROR) {
        if (interp != slaveInterp) {
            Tcl_SetObjResult(interp, Tcl_GetObjResult(slaveInterp));
            Tcl_ResetResult(slaveInterp);
        }
        return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InterpHiddenHelper --
 *
 *	Computes the list of hidden commands in a named interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
InterpHiddenHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Interp *slaveInterp;		/* A slave. */
    int len;
    Tcl_HashTable *hTblPtr;		/* Hidden command table. */
    Tcl_HashEntry *hPtr;		/* Search variable. */
    Tcl_HashSearch hSearch;		/* Iteration variable. */
    Tcl_Obj *listObjPtr;		/* Local object pointer. */

    if (objc > 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "?path?");
        return TCL_ERROR;
    }
    if (objc == 3) {
        slaveInterp = GetInterp(interp, masterPtr,
                Tcl_GetStringFromObj(objv[2], &len),
                &masterPtr);
        if (slaveInterp == (Tcl_Interp *) NULL) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "interpreter \"", Tcl_GetStringFromObj(objv[2], &len),
                    "\" not found", (char *) NULL);
            return TCL_ERROR;
        }
    } else {
        slaveInterp = interp;
    }
            
    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(slaveInterp,
            "tclHiddenCmds", NULL);
    if (hTblPtr != (Tcl_HashTable *) NULL) {
        for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
             hPtr != (Tcl_HashEntry *) NULL;
             hPtr = Tcl_NextHashEntry(&hSearch)) {

            Tcl_ListObjAppendElement(interp, listObjPtr,
                    Tcl_NewStringObj(Tcl_GetHashKey(hTblPtr, hPtr), -1));
        }
    }
    Tcl_SetObjResult(interp, listObjPtr);
            
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InterpInvokeHiddenHelper --
 *
 *	Helper routine to handle the details of invoking a hidden
 *	command in another interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Whatever the hidden command does.
 *
 *----------------------------------------------------------------------
 */

static int
InterpInvokeHiddenHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int doGlobal = 0;
    int len;
    int result;
    Tcl_Obj *namePtr, *objPtr;
    Tcl_Interp *slaveInterp;
    Interp *iPtr;
    char *string;
            
    if (objc < 4) {
        Tcl_WrongNumArgs(interp, 2, objv,
                "path ?-global? cmd ?arg ..?");
        return TCL_ERROR;
    }
    if (Tcl_IsSafe(interp)) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "not allowed to invoke hidden commands from safe interpreter",
                (char *) NULL);
        return TCL_ERROR;
    }
    if (strcmp(Tcl_GetStringFromObj(objv[3], &len), "-global") == 0) {
        doGlobal = 1;
        if (objc < 5) {
            Tcl_WrongNumArgs(interp, 2, objv,
                    "path ?-global? cmd ?arg ..?");
            return TCL_ERROR;
        }
    }
    slaveInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[2], &len), &masterPtr);
    if (slaveInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter \"", Tcl_GetStringFromObj(objv[2], &len),
                "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    Tcl_Preserve((ClientData) slaveInterp);
    if (doGlobal) {
        result = TclObjInvokeGlobal(slaveInterp, objc-4, objv+4,
                TCL_INVOKE_HIDDEN);
    } else {
        result = TclObjInvoke(slaveInterp, objc-3, objv+3, TCL_INVOKE_HIDDEN);
    }

    /*
     * Now make the result and any error information accessible. We
     * have to be careful because the slave interpreter and the current
     * interpreter can be the same - do not destroy the result.. This
     * can happen if an interpreter contains an alias which is directed
     * at a target command in the same interpreter.
     */

    if (interp != slaveInterp) {
        if (result == TCL_ERROR) {

            /*
             * An error occurred, so transfer error information from
             * the target interpreter back to our interpreter.
             */

            iPtr = (Interp *) slaveInterp;
            if (!(iPtr->flags & ERR_ALREADY_LOGGED)) {
                Tcl_AddErrorInfo(slaveInterp, "");
            }
            iPtr->flags &= (~(ERR_ALREADY_LOGGED));

            Tcl_ResetResult(interp);
            namePtr = Tcl_NewStringObj("errorInfo", -1);
            objPtr = Tcl_ObjGetVar2(slaveInterp, namePtr,
                    (Tcl_Obj *) NULL, TCL_GLOBAL_ONLY);
            Tcl_DecrRefCount(namePtr);
            string = Tcl_GetStringFromObj(objPtr, &len);
            Tcl_AddObjErrorInfo(interp, string, len);
            Tcl_SetVar2(interp, "errorCode", (char *) NULL,
                    Tcl_GetVar2(slaveInterp, "errorCode", (char *)
                            NULL, TCL_GLOBAL_ONLY),
                    TCL_GLOBAL_ONLY);
        }

	/*
         * Move the result object from the slave to the master.
         */
                
        Tcl_SetObjResult(interp, Tcl_GetObjResult(slaveInterp));
        Tcl_ResetResult(slaveInterp);
    }
    Tcl_Release((ClientData) slaveInterp);
    return result;        
}

/*
 *----------------------------------------------------------------------
 *
 * InterpMarkTrustedHelper --
 *
 *	Helper function to handle the details of marking another
 *	interpreter as trusted (unsafe).
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Henceforth the hard-wired checks for safety will not prevent
 *	this interpreter from performing certain operations.
 *
 *----------------------------------------------------------------------
 */

static int
InterpMarkTrustedHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Interp *slaveInterp;		/* A slave. */
    int len;				/* Dummy length variable. */

    if (objc != 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "path");
        return TCL_ERROR;
    }
    if (Tcl_IsSafe(interp)) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "\"", Tcl_GetStringFromObj(objv[0], &len),
                " marktrusted\" can only",
                " be invoked from a trusted interpreter",
                (char *) NULL);
        return TCL_ERROR;
    }

    slaveInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[2], &len), &masterPtr);
    if (slaveInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter \"", Tcl_GetStringFromObj(objv[2], &len),
                "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    return MarkTrusted(slaveInterp);
}

/*
 *----------------------------------------------------------------------
 *
 * InterpIsSafeHelper --
 *
 *	Computes whether a named interpreter is safe.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
InterpIsSafeHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Interp *slaveInterp;		/* A slave. */
    int len;				/* Dummy length variable. */
    Tcl_Obj *objPtr;			/* Local object pointer. */

    if (objc > 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "?path?");
        return TCL_ERROR;
    }
    if (objc == 3) {
        slaveInterp = GetInterp(interp, masterPtr,
                Tcl_GetStringFromObj(objv[2], &len), &masterPtr);
        if (slaveInterp == (Tcl_Interp *) NULL) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "interpreter \"",
                    Tcl_GetStringFromObj(objv[2], &len), "\" not found",
                    (char *) NULL);
            return TCL_ERROR;
        }
	objPtr = Tcl_NewIntObj(Tcl_IsSafe(slaveInterp));
    } else {
	objPtr = Tcl_NewIntObj(Tcl_IsSafe(interp));
    }
    Tcl_SetObjResult(interp, objPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InterpSlavesHelper --
 *
 *	Computes a list of slave interpreters of a named interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
InterpSlavesHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int len;
    Tcl_HashEntry *hPtr;		/* Search variable. */
    Tcl_HashSearch hSearch;		/* Iteration variable. */
    Tcl_Obj *listObjPtr;		/* Local object pointers. */

    if ((objc != 2) && (objc != 3)) {
        Tcl_WrongNumArgs(interp, 2, objv, "?path?");
        return TCL_ERROR;
    }
    if (objc == 3) {
        if (GetInterp(interp, masterPtr,
                Tcl_GetStringFromObj(objv[2], &len), &masterPtr) ==
                (Tcl_Interp *) NULL) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "interpreter \"", Tcl_GetStringFromObj(objv[2], &len),
                    "\" not found", (char *) NULL);
            return TCL_ERROR;
        }
    }

    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    for (hPtr = Tcl_FirstHashEntry(&(masterPtr->slaveTable), &hSearch);
         hPtr != NULL;
         hPtr = Tcl_NextHashEntry(&hSearch)) {

        Tcl_ListObjAppendElement(interp, listObjPtr,
                Tcl_NewStringObj(
                    Tcl_GetHashKey(&(masterPtr->slaveTable), hPtr), -1));
    }
    Tcl_SetObjResult(interp, listObjPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InterpShareHelper --
 *
 *	Helper function to handle the details of sharing a channel between
 *	interpreters.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	After this call the named channel will be shared between the
 *	interpreters named in the arguments.
 *
 *----------------------------------------------------------------------
 */

static int
InterpShareHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Interp *slaveInterp;		/* A slave. */
    Tcl_Interp *masterInterp;		/* Its master. */
    int len;
    Tcl_Channel chan;

    if (objc != 5) {
        Tcl_WrongNumArgs(interp, 2, objv, "srcPath channelId destPath");
        return TCL_ERROR;
    }
    masterInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[2], &len), NULL);
    if (masterInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter \"", Tcl_GetStringFromObj(objv[2], &len),
                "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    slaveInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[4], &len), NULL);
    if (slaveInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter \"", Tcl_GetStringFromObj(objv[4], &len),
                "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    chan = Tcl_GetChannel(masterInterp, Tcl_GetStringFromObj(objv[3], &len),
            NULL);
    if (chan == (Tcl_Channel) NULL) {
        if (interp != masterInterp) {
            Tcl_SetObjResult(interp, Tcl_GetObjResult(masterInterp));
            Tcl_ResetResult(masterInterp);
        }
        return TCL_ERROR;
    }
    Tcl_RegisterChannel(slaveInterp, chan);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * InterpTargetHelper --
 *
 *	Helper function to compute the target of an alias.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
InterpTargetHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int len;
    
    if (objc != 4) {
        Tcl_WrongNumArgs(interp, 2, objv, "path alias");
        return TCL_ERROR;
    }
    return GetTarget(interp,
            Tcl_GetStringFromObj(objv[2], &len),
            Tcl_GetStringFromObj(objv[3], &len));
}

/*
 *----------------------------------------------------------------------
 *
 * InterpTransferHelper --
 *
 *	Helper function to handle the details of transferring ownership
 *	of a channel between interpreters.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	After the call, the named channel will be registered in the target
 *	interpreter and no longer available for use in the source interpreter.
 *
 *----------------------------------------------------------------------
 */

static int
InterpTransferHelper(interp, masterPtr, objc, objv)
    Tcl_Interp *interp;			/* Current interpreter. */
    Master *masterPtr;			/* Master record for interp. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Tcl_Interp *slaveInterp;		/* A slave. */
    Tcl_Interp *masterInterp;		/* Its master. */
    int len;
    Tcl_Channel chan;
            
    if (objc != 5) {
        Tcl_WrongNumArgs(interp, 2, objv,
                "srcPath channelId destPath");
        return TCL_ERROR;
    }
    masterInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[2], &len), NULL);
    if (masterInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter \"", Tcl_GetStringFromObj(objv[2], &len),
                "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    slaveInterp = GetInterp(interp, masterPtr,
            Tcl_GetStringFromObj(objv[4], &len), NULL);
    if (slaveInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter \"", Tcl_GetStringFromObj(objv[4], &len),
                "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    chan = Tcl_GetChannel(masterInterp,
            Tcl_GetStringFromObj(objv[3], &len), NULL);
    if (chan == (Tcl_Channel) NULL) {
        if (interp != masterInterp) {

            /*
             * After fixing objresult, this code will change to:
             * Tcl_SetObjResult(interp, Tcl_GetObjResult(masterInterp));
             */
            
            Tcl_SetObjResult(interp, Tcl_GetObjResult(masterInterp));
            Tcl_ResetResult(masterInterp);
        }
        return TCL_ERROR;
    }
    Tcl_RegisterChannel(slaveInterp, chan);
    if (Tcl_UnregisterChannel(masterInterp, chan) != TCL_OK) {
        if (interp != masterInterp) {
            Tcl_SetObjResult(interp, Tcl_GetObjResult(masterInterp));
            Tcl_ResetResult(masterInterp);
        }
        return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * DescribeAlias --
 *
 *	Sets the interpreter's result object to a Tcl list describing
 *	the given alias in the given interpreter: its target command
 *	and the additional arguments to prepend to any invocation
 *	of the alias.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
DescribeAlias(interp, slaveInterp, aliasName)
    Tcl_Interp *interp;			/* Interpreter for result & errors. */
    Tcl_Interp *slaveInterp;		/* Interpreter defining alias. */
    char *aliasName;			/* Name of alias to describe. */
{
    Slave *slavePtr;			/* Slave interp slave record. */
    Tcl_HashEntry *hPtr;		/* Search variable. */
    Alias *aliasPtr;			/* Structure describing alias. */
    int i;				/* Loop variable. */
    Tcl_Obj *listObjPtr;		/* Local object pointer. */

    slavePtr = (Slave *) Tcl_GetAssocData(slaveInterp, "tclSlaveRecord",
            NULL);

    /*
     * The slave record should always be present because it is created
     * by Tcl_CreateInterp.
     */
    
    if (slavePtr == (Slave *) NULL) {
        panic("DescribeAlias: could not find slave record");
    }
    hPtr = Tcl_FindHashEntry(&(slavePtr->aliasTable), aliasName);
    if (hPtr == (Tcl_HashEntry *) NULL) {
        return TCL_OK;
    }
    aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);

    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    Tcl_ListObjAppendElement(interp, listObjPtr,
            Tcl_NewStringObj(aliasPtr->targetName, -1));
    for (i = 0; i < aliasPtr->objc; i++) {
        Tcl_ListObjAppendElement(interp, listObjPtr, aliasPtr->objv[i]);
    }
    Tcl_SetObjResult(interp, listObjPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteAlias --
 *
 *	Deletes the given alias from the slave interpreter given.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Deletes the alias from the slave interpreter.
 *
 *----------------------------------------------------------------------
 */

static int
DeleteAlias(interp, slaveInterp, aliasName)
    Tcl_Interp *interp;		/* Interpreter for result and errors. */
    Tcl_Interp *slaveInterp;	/* Interpreter defining alias. */
    char *aliasName;		/* Name of alias to delete. */
{
    Slave *slavePtr;		/* Slave record for slave interpreter. */
    Alias *aliasPtr;		/* Points at alias structure to delete. */
    Tcl_HashEntry *hPtr;	/* Search variable. */
    char *tmpPtr, *namePtr;	/* Local pointers to name of command to
                                 * be deleted. */

    slavePtr = (Slave *) Tcl_GetAssocData(slaveInterp, "tclSlaveRecord",
            NULL);
    if (slavePtr == (Slave *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "alias \"", aliasName, "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    
    /*
     * Get the alias from the alias table, then delete the command. The
     * deleteProc on the alias command will take care of removing the entry
     * from the alias table.
     */

    hPtr = Tcl_FindHashEntry(&(slavePtr->aliasTable), aliasName);
    if (hPtr == (Tcl_HashEntry *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "alias \"", aliasName, "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);

    /*
     * Get a copy of the real name of the command -- it might have
     * been renamed, and we want to delete the renamed command, not
     * the current command (if any) by the name of the original alias.
     * We need the local copy because the name may get smashed when the
     * command to delete is exposed, if it was hidden.
     */

    tmpPtr = Tcl_GetCommandName(slaveInterp, aliasPtr->slaveCmd);
    namePtr = (char *) ckalloc((unsigned) strlen(tmpPtr) + 1);
    strcpy(namePtr, tmpPtr);

    /*
     * NOTE: The deleteProc for this command will delete the
     * alias from the hash table. The deleteProc will also
     * delete the target information from the master interpreter
     * target table.
     */

    if (Tcl_DeleteCommand(slaveInterp, namePtr) != 0) {
        if (Tcl_ExposeCommand(slaveInterp, namePtr, namePtr) != TCL_OK) {
            panic("DeleteAlias: did not find alias to be deleted");
        }
        if (Tcl_DeleteCommand(slaveInterp, namePtr) != 0) {
            panic("DeleteAlias: did not find alias to be deleted");
        }
    }
    ckfree(namePtr);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetInterpPath --
 *
 *	Sets the result of the asking interpreter to a proper Tcl list
 *	containing the names of interpreters between the asking and
 *	target interpreters. The target interpreter must be either the
 *	same as the asking interpreter or one of its slaves (including
 *	recursively).
 *
 * Results:
 *	TCL_OK if the target interpreter is the same as, or a descendant
 *	of, the asking interpreter; TCL_ERROR else. This way one can
 *	distinguish between the case where the asking and target interps
 *	are the same (an empty list is the result, and TCL_OK is returned)
 *	and when the target is not a descendant of the asking interpreter
 *	(in which case the Tcl result is an error message and the function
 *	returns TCL_ERROR).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetInterpPath(askingInterp, targetInterp)
    Tcl_Interp *askingInterp;	/* Interpreter to start search from. */
    Tcl_Interp *targetInterp;	/* Interpreter to find. */
{
    Master *masterPtr;		/* Interim storage for Master record. */
    Slave *slavePtr;		/* Interim storage for Slave record. */
    
    if (targetInterp == askingInterp) {
        return TCL_OK;
    }
    if (targetInterp == (Tcl_Interp *) NULL) {
        return TCL_ERROR;
    }
    slavePtr = (Slave *) Tcl_GetAssocData(targetInterp, "tclSlaveRecord",
            NULL);
    if (slavePtr == (Slave *) NULL) {
        return TCL_ERROR;
    }
    if (Tcl_GetInterpPath(askingInterp, slavePtr->masterInterp) == TCL_ERROR) {

        /*
         * The result of askingInterp was set by recursive call.
         */

        return TCL_ERROR;
    }
    masterPtr = (Master *) Tcl_GetAssocData(slavePtr->masterInterp,
            "tclMasterRecord", NULL);
    if (masterPtr == (Master *) NULL) {
        panic("Tcl_GetInterpPath: could not find master record");
    }
    Tcl_AppendElement(askingInterp, Tcl_GetHashKey(&(masterPtr->slaveTable),
            slavePtr->slaveEntry));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetTarget --
 *
 *	Sets the result of the invoking interpreter to a path name for
 *	the target interpreter of an alias in one of the slaves.
 *
 * Results:
 *	TCL_OK if the target interpreter of the alias is a slave of the
 *	invoking interpreter, TCL_ERROR else.
 *
 * Side effects:
 *	Sets the result of the invoking interpreter.
 *
 *----------------------------------------------------------------------
 */

static int
GetTarget(askingInterp, path, aliasName)
    Tcl_Interp *askingInterp;	/* Interpreter to start search from. */
    char *path;			/* The path of the interp to find. */
    char *aliasName;		/* The target of this allias. */
{
    Tcl_Interp *slaveInterp;	/* Interim storage for slave. */
    Slave *slaveSlavePtr;	/* Its Slave record. */
    Master *masterPtr;		/* Interim storage for Master record. */
    Tcl_HashEntry *hPtr;	/* Search element. */
    Alias *aliasPtr;		/* Data describing the alias. */

    Tcl_ResetResult(askingInterp);
    masterPtr = (Master *) Tcl_GetAssocData(askingInterp, "tclMasterRecord",
            NULL);
    if (masterPtr == (Master *) NULL) {
        panic("GetTarget: could not find master record");
    }
    slaveInterp = GetInterp(askingInterp, masterPtr, path, NULL);
    if (slaveInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(askingInterp),
                "could not find interpreter \"", path, "\"", (char *) NULL);
        return TCL_ERROR;
    }
    slaveSlavePtr = (Slave *) Tcl_GetAssocData(slaveInterp, "tclSlaveRecord",
            NULL);
    if (slaveSlavePtr == (Slave *) NULL) {
        panic("GetTarget: could not find slave record");
    }
    hPtr = Tcl_FindHashEntry(&(slaveSlavePtr->aliasTable), aliasName);
    if (hPtr == (Tcl_HashEntry *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(askingInterp),
                "alias \"", aliasName, "\" in path \"", path, "\" not found",
                (char *) NULL);
        return TCL_ERROR;
    }
    aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
    if (aliasPtr == (Alias *) NULL) {
        panic("GetTarget: could not find alias record");
    }
    
    if (Tcl_GetInterpPath(askingInterp, aliasPtr->targetInterp) == TCL_ERROR) {
        Tcl_ResetResult(askingInterp);
        Tcl_AppendStringsToObj(Tcl_GetObjResult(askingInterp),
                "target interpreter for alias \"",
                aliasName, "\" in path \"", path, "\" is not my descendant",
                (char *) NULL);
        return TCL_ERROR;
    }
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_InterpCmd --
 *
 *	This procedure is invoked to process the "interp" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */
	/* ARGSUSED */
int
Tcl_InterpObjCmd(clientData, interp, objc, objv)
    ClientData clientData;		/* Unused. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Master *masterPtr;			/* Master record for current interp. */
    int result;				/* Local result variable. */

    /*
     * These are all the different subcommands for this command:
     */
    
    static char *subCmds[] = {
        "alias", "aliases", "create", "delete", "eval", "exists",
	"expose", "hide", "hidden", "issafe", "invokehidden",
        "marktrusted", "slaves", "share", "target", "transfer",
        (char *) NULL};
    enum ISubCmdIdx {
        IAliasIdx, IAliasesIdx, ICreateIdx, IDeleteIdx, IEvalIdx,
	IExistsIdx, IExposeIdx, IHideIdx, IHiddenIdx, IIsSafeIdx,
	IInvokeHiddenIdx, IMarkTrustedIdx, ISlavesIdx, IShareIdx,
        ITargetIdx, ITransferIdx
    } index;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?");
        return TCL_ERROR;
    }

    masterPtr = (Master *) Tcl_GetAssocData(interp, "tclMasterRecord", NULL);
    if (masterPtr == (Master *) NULL) {
        panic("Tcl_InterpCmd: could not find master record");
    }

    result = Tcl_GetIndexFromObj(interp, objv[1], subCmds, "option",
            0, (int *) &index);
    if (result != TCL_OK) {
        return result;
    }
    
    switch (index) {
        case IAliasIdx:
            return InterpAliasHelper(interp, masterPtr, objc, objv);
        case IAliasesIdx:
            return InterpAliasesHelper(interp, masterPtr, objc, objv);
        case ICreateIdx:
            return CreateInterpObject(interp, masterPtr, objc, objv);
        case IDeleteIdx:
            return DeleteInterpObject(interp, masterPtr, objc, objv);
        case IEvalIdx:
            return InterpEvalHelper(interp, masterPtr, objc, objv);
        case IExistsIdx:
            return InterpExistsHelper(interp, masterPtr, objc, objv);
        case IExposeIdx:
            return InterpExposeHelper(interp, masterPtr, objc, objv);
        case IHideIdx:
            return InterpHideHelper(interp, masterPtr, objc, objv);
        case IHiddenIdx:
            return InterpHiddenHelper(interp, masterPtr, objc, objv);
        case IIsSafeIdx:
            return InterpIsSafeHelper(interp, masterPtr, objc, objv);
        case IInvokeHiddenIdx:
            return InterpInvokeHiddenHelper(interp, masterPtr, objc, objv);
        case IMarkTrustedIdx:
            return InterpMarkTrustedHelper(interp, masterPtr, objc, objv);
        case ISlavesIdx:
            return InterpSlavesHelper(interp, masterPtr, objc, objv);
        case IShareIdx:
            return InterpShareHelper(interp, masterPtr, objc, objv);
        case ITargetIdx:
            return InterpTargetHelper(interp, masterPtr, objc, objv);
        case ITransferIdx:
            return InterpTransferHelper(interp, masterPtr, objc, objv);
    }

    return TCL_ERROR;    
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveAliasHelper --
 *
 *	Helper function to construct or query an alias for a slave
 *	interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Potentially creates a new alias.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveAliasHelper(interp, slaveInterp, slavePtr, objc, objv)
    Tcl_Interp	*interp;		/* Current interpreter. */
    Tcl_Interp	*slaveInterp;		/* The slave interpreter. */
    Slave *slavePtr;			/* Its slave record. */
    int objc;				/* Count of arguments. */
    Tcl_Obj *CONST objv[];		/* Vector of arguments. */
{
    Master *masterPtr;
    int len;

    switch (objc-2) {
        case 0:
            Tcl_WrongNumArgs(interp, 2, objv,
                    "aliasName ?targetName? ?args..?");
            return TCL_ERROR;

        case 1:

            /*
             * Return the name of the command in the current
             * interpreter for which the argument is an alias in the
             * slave interpreter, and the list of saved arguments
             */

            return DescribeAlias(interp, slaveInterp,
                    Tcl_GetStringFromObj(objv[2], &len));

        default:
            masterPtr = (Master *) Tcl_GetAssocData(interp,
                    "tclMasterRecord", NULL);
            if (masterPtr == (Master *) NULL) {
                panic("SlaveObjectCmd: could not find master record");
            }
            return AliasCreationHelper(interp, slaveInterp, interp,
                    masterPtr,
                    Tcl_GetStringFromObj(objv[2], &len),
                    Tcl_GetStringFromObj(objv[3], &len),
                    objc-4, objv+4);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveAliasesHelper --
 *
 *	Computes a list of aliases defined in a slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveAliasesHelper(interp, slaveInterp, slavePtr, objc, objv)
    Tcl_Interp	*interp;		/* Current interpreter. */
    Tcl_Interp	*slaveInterp;		/* The slave interpreter. */
    Slave *slavePtr;			/* Its slave record. */
    int objc;				/* Count of arguments. */
    Tcl_Obj *CONST objv[];		/* Vector of arguments. */
{
    Tcl_HashEntry *hPtr;		/* For local searches. */
    Tcl_HashSearch hSearch;		/* For local searches. */
    Tcl_Obj *listObjPtr;		/* Local object pointer. */
    Alias *aliasPtr;			/* Alias information. */

    /*
     * Return the names of all the aliases created in the
     * slave interpreter.
     */

    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    for (hPtr = Tcl_FirstHashEntry(&(slavePtr->aliasTable),
            &hSearch);
         hPtr != (Tcl_HashEntry *) NULL;
         hPtr = Tcl_NextHashEntry(&hSearch)) {
        aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
        Tcl_ListObjAppendElement(interp, listObjPtr,
                Tcl_NewStringObj(aliasPtr->aliasName, -1));
    }
    Tcl_SetObjResult(interp, listObjPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveEvalHelper --
 *
 *	Helper function to evaluate a command in a slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Whatever the command does.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveEvalHelper(interp, slaveInterp, slavePtr, objc, objv)
    Tcl_Interp	*interp;		/* Current interpreter. */
    Tcl_Interp	*slaveInterp;		/* The slave interpreter. */
    Slave *slavePtr;			/* Its slave record. */
    int objc;				/* Count of arguments. */
    Tcl_Obj *CONST objv[];		/* Vector of arguments. */
{
    Interp *iPtr;			/* Internal data type for slave. */
    Tcl_Obj *objPtr;			/* Local object pointer. */
    Tcl_Obj *namePtr;			/* Local object pointer. */
    int len;
    char *string;
    int result;
    
    if (objc < 3) {
        Tcl_WrongNumArgs(interp, 2, objv, "arg ?arg ...?");
        return TCL_ERROR;
    }

    objPtr = Tcl_ConcatObj(objc-2, objv+2);
    Tcl_IncrRefCount(objPtr);
    
    Tcl_Preserve((ClientData) slaveInterp);
    result = Tcl_EvalObj(slaveInterp, objPtr);

    Tcl_DecrRefCount(objPtr);

    /*
     * Make the result and any error information accessible. We have
     * to be careful because the slave interpreter and the current
     * interpreter can be the same - do not destroy the result.. This
     * can happen if an interpreter contains an alias which is directed
     * at a target command in the same interpreter.
     */

    if (interp != slaveInterp) {
        if (result == TCL_ERROR) {

            /*
             * An error occurred, so transfer error information from the
             * destination interpreter back to our interpreter. 
             */

            iPtr = (Interp *) slaveInterp;
            if (!(iPtr->flags & ERR_ALREADY_LOGGED)) {
                Tcl_AddErrorInfo(slaveInterp, "");
            }
            iPtr->flags &= (~(ERR_ALREADY_LOGGED));

            Tcl_ResetResult(interp);
            namePtr = Tcl_NewStringObj("errorInfo", -1);
            objPtr = Tcl_ObjGetVar2(slaveInterp, namePtr,
                    (Tcl_Obj *) NULL, TCL_GLOBAL_ONLY);
            string = Tcl_GetStringFromObj(objPtr, &len);
            Tcl_AddObjErrorInfo(interp, string, len);
            Tcl_SetVar2(interp, "errorCode", (char *) NULL,
                    Tcl_GetVar2(slaveInterp, "errorCode", (char *)
                            NULL, TCL_GLOBAL_ONLY),
                    TCL_GLOBAL_ONLY);
            Tcl_DecrRefCount(namePtr);
        }

	/*
         * Move the result object from one interpreter to the
         * other.
         */
                
        Tcl_SetObjResult(interp, Tcl_GetObjResult(slaveInterp));
        Tcl_ResetResult(slaveInterp);
    }
    Tcl_Release((ClientData) slaveInterp);
    return result;        
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveExposeHelper --
 *
 *	Helper function to expose a command in a slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	After this call scripts in the slave will be able to invoke
 *	the newly exposed command.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveExposeHelper(interp, slaveInterp, slavePtr, objc, objv)
    Tcl_Interp	*interp;		/* Current interpreter. */
    Tcl_Interp	*slaveInterp;		/* The slave interpreter. */
    Slave *slavePtr;			/* Its slave record. */
    int objc;				/* Count of arguments. */
    Tcl_Obj *CONST objv[];		/* Vector of arguments. */
{
    int len;
    
    if ((objc != 3) && (objc != 4)) {
        Tcl_WrongNumArgs(interp, 2, objv, "hiddenCmdName ?cmdName?");
        return TCL_ERROR;
    }
    if (Tcl_IsSafe(interp)) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "permission denied: safe interpreter cannot expose commands",
                (char *) NULL);
        return TCL_ERROR;
    }
    if (Tcl_ExposeCommand(slaveInterp, Tcl_GetStringFromObj(objv[2], &len),
            (objc == 4 ?
                    Tcl_GetStringFromObj(objv[3], &len) :
                    Tcl_GetStringFromObj(objv[2], &len)))
            == TCL_ERROR) {
        Tcl_SetObjResult(interp, Tcl_GetObjResult(slaveInterp));
        Tcl_ResetResult(slaveInterp);
        return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveHideHelper --
 *
 *	Helper function to hide a command in a slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	After this call scripts in the slave will no longer be able
 *	to invoke the named command.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveHideHelper(interp, slaveInterp, slavePtr, objc, objv)
    Tcl_Interp	*interp;		/* Current interpreter. */
    Tcl_Interp	*slaveInterp;		/* The slave interpreter. */
    Slave *slavePtr;			/* Its slave record. */
    int objc;				/* Count of arguments. */
    Tcl_Obj *CONST objv[];		/* Vector of arguments. */
{
    int len;

    if ((objc != 3) && (objc != 4)) {
        Tcl_WrongNumArgs(interp, 2, objv, "cmdName ?hiddenCmdName?");
        return TCL_ERROR;
    }
    if (Tcl_IsSafe(interp)) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "permission denied: safe interpreter cannot hide commands",
                (char *) NULL);
        return TCL_ERROR;
    }
    if (Tcl_HideCommand(slaveInterp, Tcl_GetStringFromObj(objv[2], &len),
            (objc == 4 ?
                    Tcl_GetStringFromObj(objv[3], &len) :
                    Tcl_GetStringFromObj(objv[2], &len)))
            == TCL_ERROR) {
        Tcl_SetObjResult(interp, Tcl_GetObjResult(slaveInterp));
        Tcl_ResetResult(slaveInterp);
        return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveHiddenHelper --
 *
 *	Helper function to compute list of hidden commands in a slave
 *	interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveHiddenHelper(interp, slaveInterp, slavePtr, objc, objv)
    Tcl_Interp	*interp;		/* Current interpreter. */
    Tcl_Interp	*slaveInterp;		/* The slave interpreter. */
    Slave *slavePtr;			/* Its slave record. */
    int objc;				/* Count of arguments. */
    Tcl_Obj *CONST objv[];		/* Vector of arguments. */
{
    Tcl_Obj *listObjPtr;		/* Local object pointer. */
    Tcl_HashTable *hTblPtr;		/* For local searches. */
    Tcl_HashEntry *hPtr;		/* For local searches. */
    Tcl_HashSearch hSearch;		/* For local searches. */
    
    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 2, objv, NULL);
        return TCL_ERROR;
    }

    listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(slaveInterp,
            "tclHiddenCmds", NULL);
    if (hTblPtr != (Tcl_HashTable *) NULL) {
        for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
             hPtr != (Tcl_HashEntry *) NULL;
             hPtr = Tcl_NextHashEntry(&hSearch)) {
            Tcl_ListObjAppendElement(interp, listObjPtr,
                    Tcl_NewStringObj(Tcl_GetHashKey(hTblPtr, hPtr), -1));
        }
    }
    Tcl_SetObjResult(interp, listObjPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveIsSafeHelper --
 *
 *	Helper function to compute whether a slave interpreter is safe.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveIsSafeHelper(interp, slaveInterp, slavePtr, objc, objv)
    Tcl_Interp	*interp;		/* Current interpreter. */
    Tcl_Interp	*slaveInterp;		/* The slave interpreter. */
    Slave *slavePtr;			/* Its slave record. */
    int objc;				/* Count of arguments. */
    Tcl_Obj *CONST objv[];		/* Vector of arguments. */
{
    Tcl_Obj *resultPtr;			/* Local object pointer. */

    if (objc > 2) {
        Tcl_WrongNumArgs(interp, 2, objv, NULL);
        return TCL_ERROR;
    }
    resultPtr = Tcl_NewIntObj(Tcl_IsSafe(slaveInterp));

    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveInvokeHiddenHelper --
 *
 *	Helper function to invoke a hidden command in a slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Whatever the hidden command does.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveInvokeHiddenHelper(interp, slaveInterp, slavePtr, objc, objv)
    Tcl_Interp	*interp;		/* Current interpreter. */
    Tcl_Interp	*slaveInterp;		/* The slave interpreter. */
    Slave *slavePtr;			/* Its slave record. */
    int objc;				/* Count of arguments. */
    Tcl_Obj *CONST objv[];		/* Vector of arguments. */
{
    Interp *iPtr;
    Master *masterPtr;
    int doGlobal = 0;
    int result;
    int len;
    char *string;
    Tcl_Obj *namePtr, *objPtr;
            
    if (objc < 3) {
        Tcl_WrongNumArgs(interp, 2, objv,
                "?-global? cmd ?arg ..?");
        return TCL_ERROR;
    }
    if (Tcl_IsSafe(interp)) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "not allowed to invoke hidden commands from safe interpreter",
                (char *) NULL);
        return TCL_ERROR;
    }
    if (strcmp(Tcl_GetStringFromObj(objv[2], &len), "-global") == 0) {
        doGlobal = 1;
        if (objc < 4) {
            Tcl_WrongNumArgs(interp, 2, objv,
                    "path ?-global? cmd ?arg ..?");
            return TCL_ERROR;
        }
    }
    masterPtr = (Master *) Tcl_GetAssocData(slaveInterp,
            "tclMasterRecord", NULL);
    if (masterPtr == (Master *) NULL) {
        panic("SlaveObjectCmd: could not find master record");
    }
    Tcl_Preserve((ClientData) slaveInterp);
    if (doGlobal) {
        result = TclObjInvokeGlobal(slaveInterp, objc-3, objv+3,
                TCL_INVOKE_HIDDEN);
    } else {
        result = TclObjInvoke(slaveInterp, objc-2, objv+2,
                TCL_INVOKE_HIDDEN);
    }

    /*
     * Now make the result and any error information accessible. We
     * have to be careful because the slave interpreter and the current
     * interpreter can be the same - do not destroy the result.. This
     * can happen if an interpreter contains an alias which is directed
     * at a target command in the same interpreter.
     */

    if (interp != slaveInterp) {
        if (result == TCL_ERROR) {

            /*
             * An error occurred, so transfer error information from
             * the target interpreter back to our interpreter.
             */

            iPtr = (Interp *) slaveInterp;
            if (!(iPtr->flags & ERR_ALREADY_LOGGED)) {
                Tcl_AddErrorInfo(slaveInterp, "");
            }
            iPtr->flags &= (~(ERR_ALREADY_LOGGED));

            Tcl_ResetResult(interp);
            namePtr = Tcl_NewStringObj("errorInfo", -1);
            objPtr = Tcl_ObjGetVar2(slaveInterp, namePtr,
                    (Tcl_Obj *) NULL, TCL_GLOBAL_ONLY);
            string = Tcl_GetStringFromObj(objPtr, &len);
            Tcl_AddObjErrorInfo(interp, string, len);
            Tcl_SetVar2(interp, "errorCode", (char *) NULL,
                    Tcl_GetVar2(slaveInterp, "errorCode", (char *)
                            NULL, TCL_GLOBAL_ONLY),
                    TCL_GLOBAL_ONLY);
            Tcl_DecrRefCount(namePtr);
        }

	/*
         * Move the result object from the slave to the master.
         */
                
        Tcl_SetObjResult(interp, Tcl_GetObjResult(slaveInterp));
        Tcl_ResetResult(slaveInterp);
    }
    Tcl_Release((ClientData) slaveInterp);
    return result;        
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveMarkTrustedHelper --
 *
 *	Helper function to mark a slave interpreter as trusted (unsafe).
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	After this call the hard-wired security checks in the core no
 *	longer prevent the slave from performing certain operations.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveMarkTrustedHelper(interp, slaveInterp, slavePtr, objc, objv)
    Tcl_Interp	*interp;		/* Current interpreter. */
    Tcl_Interp	*slaveInterp;		/* The slave interpreter. */
    Slave *slavePtr;			/* Its slave record. */
    int objc;				/* Count of arguments. */
    Tcl_Obj *CONST objv[];		/* Vector of arguments. */
{
    int len;
    
    if (objc != 2) {
        Tcl_WrongNumArgs(interp, 2, objv, NULL);
        return TCL_ERROR;
    }
    if (Tcl_IsSafe(interp)) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "\"", Tcl_GetStringFromObj(objv[0], &len), " marktrusted\"",
                " can only be invoked from a trusted interpreter",
                (char *) NULL);
        return TCL_ERROR;
    }
    return MarkTrusted(slaveInterp);
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveObjectCmd --
 *
 *	Command to manipulate an interpreter, e.g. to send commands to it
 *	to be evaluated. One such command exists for each slave interpreter.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See user documentation for details.
 *
 *----------------------------------------------------------------------
 */

static int
SlaveObjectCmd(clientData, interp, objc, objv)
    ClientData clientData;		/* Slave interpreter. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* The argument vector. */
{
    Slave *slavePtr;			/* Slave record. */
    Tcl_Interp *slaveInterp;		/* Slave interpreter. */
    int result;				/* Loop counter, status return. */
    int len;				/* Length of command name. */

    /*
     * These are all the different subcommands for this command:
     */
    
    static char *subCmds[] = {
        "alias", "aliases",
        "eval", "expose",
        "hide", "hidden",
        "issafe", "invokehidden",
        "marktrusted",
        (char *) NULL};
    enum ISubCmdIdx {
        IAliasIdx, IAliasesIdx,
        IEvalIdx, IExposeIdx,
        IHideIdx, IHiddenIdx,
        IIsSafeIdx, IInvokeHiddenIdx,
        IMarkTrustedIdx
    } index;
    
    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?");
        return TCL_ERROR;
    }

    slaveInterp = (Tcl_Interp *) clientData;
    if (slaveInterp == (Tcl_Interp *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "interpreter ", Tcl_GetStringFromObj(objv[0], &len),
                " has been deleted", (char *) NULL);
	return TCL_ERROR;
    }

    slavePtr = (Slave *) Tcl_GetAssocData(slaveInterp,
            "tclSlaveRecord", NULL);
    if (slavePtr == (Slave *) NULL) {
        panic("SlaveObjectCmd: could not find slave record");
    }

    result = Tcl_GetIndexFromObj(interp, objv[1], subCmds, "option",
            0, (int *) &index);
    if (result != TCL_OK) {
        return result;
    }

    switch (index) {
        case IAliasIdx:
            return SlaveAliasHelper(interp, slaveInterp, slavePtr, objc, objv);
        case IAliasesIdx:
            return SlaveAliasesHelper(interp, slaveInterp, slavePtr,
                    objc, objv);
        case IEvalIdx:
            return SlaveEvalHelper(interp, slaveInterp, slavePtr, objc, objv);
        case IExposeIdx:
            return SlaveExposeHelper(interp, slaveInterp, slavePtr,
                    objc, objv);
        case IHideIdx:
            return SlaveHideHelper(interp, slaveInterp, slavePtr,
                    objc, objv);
        case IHiddenIdx:
            return SlaveHiddenHelper(interp, slaveInterp, slavePtr,
                    objc, objv);
        case IIsSafeIdx:
            return SlaveIsSafeHelper(interp, slaveInterp, slavePtr,
                    objc, objv);
        case IInvokeHiddenIdx:
            return SlaveInvokeHiddenHelper(interp, slaveInterp, slavePtr,
                    objc, objv);
        case IMarkTrustedIdx:
            return SlaveMarkTrustedHelper(interp, slaveInterp, slavePtr,
                    objc, objv);
    }

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveObjectDeleteProc --
 *
 *	Invoked when an object command for a slave interpreter is deleted;
 *	cleans up all state associated with the slave interpreter and destroys
 *	the slave interpreter.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Cleans up all state associated with the slave interpreter and
 *	destroys the slave interpreter.
 *
 *----------------------------------------------------------------------
 */

static void
SlaveObjectDeleteProc(clientData)
    ClientData clientData;		/* The SlaveRecord for the command. */
{
    Slave *slavePtr;			/* Interim storage for Slave record. */
    Tcl_Interp *slaveInterp;		/* And for a slave interp. */

    slaveInterp = (Tcl_Interp *) clientData;
    slavePtr = (Slave *) Tcl_GetAssocData(slaveInterp, "tclSlaveRecord",NULL); 
    if (slavePtr == (Slave *) NULL) {
        panic("SlaveObjectDeleteProc: could not find slave record");
    }

    /*
     * Delete the entry in the slave table in the master interpreter now.
     * This is to avoid an infinite loop in the Master hash table cleanup in
     * the master interpreter. This can happen if this slave is being deleted
     * because the master is being deleted and the slave deletion is deferred
     * because it is still active.
     */

    Tcl_DeleteHashEntry(slavePtr->slaveEntry);

    /*
     * Set to NULL so that when the slave record is cleaned up in the slave
     * it does not try to delete the command causing all sorts of grief.
     * See SlaveRecordDeleteProc().
     */

    slavePtr->interpCmd = NULL;

    /*
     * Destroy the interpreter - this will cause all the deleteProcs for
     * all commands (including aliases) to run.
     *
     * NOTE: WE ASSUME THAT THE INTERPRETER HAS NOT BEEN DELETED YET!!
     */

    Tcl_DeleteInterp(slavePtr->slaveInterp);
}

/*
 *----------------------------------------------------------------------
 *
 * AliasCmd --
 *
 *	This is the procedure that services invocations of aliases in a
 *	slave interpreter. One such command exists for each alias. When
 *	invoked, this procedure redirects the invocation to the target
 *	command in the master interpreter as designated by the Alias
 *	record associated with this command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Causes forwarding of the invocation; all possible side effects
 *	may occur as a result of invoking the command to which the
 *	invocation is forwarded.
 *
 *----------------------------------------------------------------------
 */

static int
AliasCmd(clientData, interp, objc, objv)
    ClientData clientData;		/* Alias record. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument vector. */	
{
    Tcl_Interp *targetInterp;		/* Target for alias exec. */
    Interp *iPtr;			/* Internal type of target. */
    Alias *aliasPtr;			/* Describes the alias. */
    Tcl_Command cmd;			/* The target command. */
    Command *cmdPtr;			/* Points to target command. */
    Tcl_Namespace *targetNsPtr;	        /* Target command's namespace. */
    int result;				/* Result of execution. */
    int i, j, addObjc;			/* Loop counters. */
    int localObjc;			/* Local argument count. */
    Tcl_Obj **localObjv;		/* Local argument vector. */
    Tcl_Obj *namePtr, *objPtr;		/* Local object pointers. */
    char *string;			/* Local object string rep. */
    int len;				/* Dummy length arg. */
    
    aliasPtr = (Alias *) clientData;
    targetInterp = aliasPtr->targetInterp;

    /*
     * Look for the target command in the global namespace of the target
     * interpreter.
     */

    cmdPtr = NULL;
    targetNsPtr = Tcl_GetGlobalNamespace(aliasPtr->targetInterp);
    cmd = Tcl_FindCommand(targetInterp, aliasPtr->targetName,
            targetNsPtr, /*flags*/ 0);
    if (cmd != (Tcl_Command) NULL) {
        cmdPtr = (Command *) cmd;
    }

    iPtr = (Interp *) targetInterp;

    /*
     * If the command does not exist, invoke "unknown" in the master.
     */
    
    if (cmdPtr == NULL) {
        addObjc = aliasPtr->objc;
        localObjc = addObjc + objc + 1;
        localObjv = (Tcl_Obj **) ckalloc((unsigned) sizeof(Tcl_Obj *)
                * localObjc);
        
        localObjv[0] = Tcl_NewStringObj("unknown", -1);
        localObjv[1] = Tcl_NewStringObj(aliasPtr->targetName, -1);
        Tcl_IncrRefCount(localObjv[0]);
        Tcl_IncrRefCount(localObjv[1]);
        
        for (i = 0, j = 2; i < addObjc; i++, j++) {
            localObjv[j] = aliasPtr->objv[i];
        }
        for (i = 1; i < objc; i++, j++) {
            localObjv[j] = objv[i];
        }
        Tcl_Preserve((ClientData) targetInterp);
        result = TclObjInvoke(targetInterp, localObjc, localObjv, 0);

        Tcl_DecrRefCount(localObjv[0]);
        Tcl_DecrRefCount(localObjv[1]);
        
        ckfree((char *) localObjv);
        
        if (targetInterp != interp) {
            if (result == TCL_ERROR) {
                
                /*
                 * An error occurred, so transfer error information from
                 * the target interpreter back to our interpreter.
                 */

                if (!(iPtr->flags & ERR_ALREADY_LOGGED)) {
                    Tcl_AddErrorInfo((Tcl_Interp *) iPtr, "");
                }
                iPtr->flags &= (~(ERR_ALREADY_LOGGED));

                Tcl_ResetResult(interp);
                namePtr = Tcl_NewStringObj("errorInfo", -1);
                objPtr = Tcl_ObjGetVar2(targetInterp, namePtr,
                        (Tcl_Obj *) NULL, TCL_GLOBAL_ONLY);
                string = Tcl_GetStringFromObj(objPtr, &len);
                Tcl_AddObjErrorInfo(interp, string, len);
                Tcl_SetVar2(interp, "errorCode", (char *) NULL,
                        Tcl_GetVar2(targetInterp, "errorCode", (char *)
                                NULL, TCL_GLOBAL_ONLY),
                        TCL_GLOBAL_ONLY);
                Tcl_DecrRefCount(namePtr);
            }

            /*
             * Transfer the result from the target interpreter to the
             * calling interpreter.
             */
            
            Tcl_SetObjResult(interp, Tcl_GetObjResult(targetInterp));
            Tcl_ResetResult(targetInterp);
        }

	Tcl_Release((ClientData) targetInterp);
        return result;
    }

    /*
     * Otherwise invoke the regular target command.
     */
    
    if (aliasPtr->objc <= 0) {
        localObjv = (Tcl_Obj **) objv;
        localObjc = objc;
    } else {
        addObjc = aliasPtr->objc;
        localObjc = objc + addObjc;
        localObjv =
            (Tcl_Obj **) ckalloc((unsigned) sizeof(Tcl_Obj *) * localObjc);
        localObjv[0] = objv[0];
        for (i = 0, j = 1; i < addObjc; i++, j++) {
            localObjv[j] = aliasPtr->objv[i];
        }
        for (i = 1; i < objc; i++, j++) {
            localObjv[j] = objv[i];
        }
    }

    iPtr->numLevels++;
    Tcl_Preserve((ClientData) targetInterp);

    /*
     * Reset the interpreter to its clean state; we do not know what state
     * it is in now..
     */
    
    Tcl_ResetResult(targetInterp);
    result = (cmdPtr->objProc)(cmdPtr->objClientData, targetInterp,
            localObjc, localObjv);

    iPtr->numLevels--;
    
    /*
     * Check if we are at the bottom of the stack for the target interpreter.
     * If so, check for special return codes.
     */
    
    if (iPtr->numLevels == 0) {
	if (result == TCL_RETURN) {
	    result = TclUpdateReturnInfo(iPtr);
	}
	if ((result != TCL_OK) && (result != TCL_ERROR)) {
	    Tcl_ResetResult(targetInterp);
	    if (result == TCL_BREAK) {
                Tcl_SetObjResult(targetInterp,
                        Tcl_NewStringObj("invoked \"break\" outside of a loop",
                                -1));
	    } else if (result == TCL_CONTINUE) {
                Tcl_SetObjResult(targetInterp,
                        Tcl_NewStringObj(
                            "invoked \"continue\" outside of a loop",
                            -1));
	    } else {
                char buf[128];

                sprintf(buf, "command returned bad code: %d", result);
                Tcl_SetObjResult(targetInterp, Tcl_NewStringObj(buf, -1));
	    }
	    result = TCL_ERROR;
	}
    }

    /*
     * Clean up any locally allocated argument vector structure.
     */
    
    if (localObjv != objv) {
        ckfree((char *) localObjv);
    }
    
    /*
     * Move the result from the target interpreter to the invoking
     * interpreter if they are different.
     *
     * Note: We cannot use aliasPtr any more because the alias may have
     * been deleted.
     */

    if (interp != targetInterp) {
        if (result == TCL_ERROR) {

            /*
             * An error occurred, so transfer the error information from
             * the target interpreter back to our interpreter.
             */

            if (!(iPtr->flags & ERR_ALREADY_LOGGED)) {
                Tcl_AddErrorInfo(targetInterp, "");
            }
            iPtr->flags &= (~(ERR_ALREADY_LOGGED));
            
            Tcl_ResetResult(interp);
            namePtr = Tcl_NewStringObj("errorInfo", -1);
            objPtr = Tcl_ObjGetVar2(targetInterp, namePtr, (Tcl_Obj *) NULL,
                    TCL_GLOBAL_ONLY);
            string = Tcl_GetStringFromObj(objPtr, &len);
            Tcl_AddObjErrorInfo(interp, string, len);
            Tcl_SetVar2(interp, "errorCode", (char *) NULL,
                    Tcl_GetVar2(targetInterp, "errorCode", (char *) NULL,
                            TCL_GLOBAL_ONLY),
                    TCL_GLOBAL_ONLY);
            Tcl_DecrRefCount(namePtr);
        }

	/*
         * Move the result object from one interpreter to the
         * other.
         */
                
        Tcl_SetObjResult(interp, Tcl_GetObjResult(targetInterp));
        Tcl_ResetResult(targetInterp);
    }
    Tcl_Release((ClientData) targetInterp);
    return result;        
}

/*
 *----------------------------------------------------------------------
 *
 * AliasCmdDeleteProc --
 *
 *	Is invoked when an alias command is deleted in a slave. Cleans up
 *	all storage associated with this alias.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Deletes the alias record and its entry in the alias table for
 *	the interpreter.
 *
 *----------------------------------------------------------------------
 */

static void
AliasCmdDeleteProc(clientData)
    ClientData clientData;		/* The alias record for this alias. */
{
    Alias *aliasPtr;			/* Alias record for alias to delete. */
    Target *targetPtr;			/* Record for target of this alias. */
    int i;				/* Loop counter. */

    aliasPtr = (Alias *) clientData;
    
    targetPtr = (Target *) Tcl_GetHashValue(aliasPtr->targetEntry);
    ckfree((char *) targetPtr);
    Tcl_DeleteHashEntry(aliasPtr->targetEntry);

    ckfree((char *) aliasPtr->targetName);
    ckfree((char *) aliasPtr->aliasName);
    for (i = 0; i < aliasPtr->objc; i++) {
        Tcl_DecrRefCount(aliasPtr->objv[i]);
    }
    if (aliasPtr->objv != (Tcl_Obj **) NULL) {
        ckfree((char *) aliasPtr->objv);
    }

    Tcl_DeleteHashEntry(aliasPtr->aliasEntry);

    ckfree((char *) aliasPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * MasterRecordDeleteProc -
 *
 *	Is invoked when an interpreter (which is using the "interp" facility)
 *	is deleted, and it cleans up the storage associated with the
 *	"tclMasterRecord" assoc-data entry.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Cleans up storage.
 *
 *----------------------------------------------------------------------
 */

static void
MasterRecordDeleteProc(clientData, interp)
    ClientData	clientData;		/* Master record for deleted interp. */
    Tcl_Interp *interp;			/* Interpreter being deleted. */
{
    Target *targetPtr;			/* Loop variable. */
    Tcl_HashEntry *hPtr;		/* Search element. */
    Tcl_HashSearch hSearch;		/* Search record (internal). */
    Slave *slavePtr;			/* Loop variable. */
    Master *masterPtr;			/* Interim storage. */

    masterPtr = (Master *) clientData;
    for (hPtr = Tcl_FirstHashEntry(&(masterPtr->slaveTable), &hSearch);
         hPtr != NULL;
         hPtr = Tcl_NextHashEntry(&hSearch)) {
        slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
        (void) Tcl_DeleteCommandFromToken(interp, slavePtr->interpCmd);
    }
    Tcl_DeleteHashTable(&(masterPtr->slaveTable));

    for (hPtr = Tcl_FirstHashEntry(&(masterPtr->targetTable), &hSearch);
         hPtr != NULL;
         hPtr = Tcl_FirstHashEntry(&(masterPtr->targetTable), &hSearch)) {
        targetPtr = (Target *) Tcl_GetHashValue(hPtr);
        (void) Tcl_DeleteCommandFromToken(targetPtr->slaveInterp,
	        targetPtr->slaveCmd);
    }
    Tcl_DeleteHashTable(&(masterPtr->targetTable));

    ckfree((char *) masterPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * SlaveRecordDeleteProc --
 *
 *	Is invoked when an interpreter (which is using the interp facility)
 *	is deleted, and it cleans up the storage associated with the
 *	tclSlaveRecord assoc-data entry.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Cleans up storage.
 *
 *----------------------------------------------------------------------
 */

static void
SlaveRecordDeleteProc(clientData, interp)
    ClientData	clientData;		/* Slave record for deleted interp. */
    Tcl_Interp *interp;			/* Interpreter being deleted. */
{
    Slave *slavePtr;			/* Interim storage. */
    Alias *aliasPtr;
    Tcl_HashTable *hTblPtr;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch hSearch;
    
    slavePtr = (Slave *) clientData;

    /*
     * In every case that we call SetAssocData on "tclSlaveRecord",
     * slavePtr is not NULL. Otherwise we panic.
     */

    if (slavePtr == NULL) {
	panic("SlaveRecordDeleteProc: NULL slavePtr");
    }

    if (slavePtr->interpCmd != (Tcl_Command) NULL) {
	Command *cmdPtr = (Command *) slavePtr->interpCmd;

	/*
	 * The interpCmd has not been deleted in the master yet,  since
	 * it's callback sets interpCmd to NULL.
	 *
	 * Probably Tcl_DeleteInterp() was called on this interpreter directly,
	 * rather than via "interp delete", or equivalent (deletion of the
	 * command in the master).
	 *
	 * Perform the cleanup done by SlaveObjectDeleteProc() directly,
	 * and turn off the callback now (since we are about to free slavePtr
	 * and this interpreter is going away, while the deletion of commands
	 * in the master may be deferred).
	 */

	Tcl_DeleteHashEntry(slavePtr->slaveEntry);
	cmdPtr->clientData = NULL;
	cmdPtr->deleteProc = NULL;
	cmdPtr->deleteData = NULL;

        Tcl_DeleteCommandFromToken(slavePtr->masterInterp,
	        slavePtr->interpCmd);
    }

    /*
     * If there are any aliases, delete those now. This removes any
     * dependency on the order of deletion between commands and the
     * slave record.
     */

    hTblPtr = (Tcl_HashTable *) &(slavePtr->aliasTable);
    for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
             hPtr != (Tcl_HashEntry *) NULL;
             hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) {
        aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);

        /*
         * The call to Tcl_DeleteCommand will release the storage
         * occupied by the hash entry and the alias record.
         */

        Tcl_DeleteCommandFromToken(interp, aliasPtr->slaveCmd);
    }
        
    /*
     * Finally dispose of the hash table and the slave record.
     */

    Tcl_DeleteHashTable(hTblPtr);
    ckfree((char *) slavePtr);    
}

/*
 *----------------------------------------------------------------------
 *
 * TclInterpInit --
 *
 *	Initializes the invoking interpreter for using the "interp"
 *	facility. This is called from inside Tcl_Init.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Adds the "interp" command to an interpreter and initializes several
 *	records in the associated data of the invoking interpreter.
 *
 *----------------------------------------------------------------------
 */

int
TclInterpInit(interp)
    Tcl_Interp *interp;			/* Interpreter to initialize. */
{
    Master *masterPtr;			/* Its Master record. */
    Slave *slavePtr;			/* And its slave record. */

    masterPtr = (Master *) ckalloc((unsigned) sizeof(Master));

    Tcl_InitHashTable(&(masterPtr->slaveTable), TCL_STRING_KEYS);
    Tcl_InitHashTable(&(masterPtr->targetTable), TCL_ONE_WORD_KEYS);

    (void) Tcl_SetAssocData(interp, "tclMasterRecord", MasterRecordDeleteProc,
            (ClientData) masterPtr);

    slavePtr = (Slave *) ckalloc((unsigned) sizeof(Slave));

    slavePtr->masterInterp = (Tcl_Interp *) NULL;
    slavePtr->slaveEntry = (Tcl_HashEntry *) NULL;
    slavePtr->slaveInterp = interp;
    slavePtr->interpCmd = (Tcl_Command) NULL;
    Tcl_InitHashTable(&(slavePtr->aliasTable), TCL_STRING_KEYS);

    (void) Tcl_SetAssocData(interp, "tclSlaveRecord", SlaveRecordDeleteProc,
            (ClientData) slavePtr);
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_IsSafe --
 *
 *	Determines whether an interpreter is safe
 *
 * Results:
 *	1 if it is safe, 0 if it is not.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_IsSafe(interp)
    Tcl_Interp *interp;		/* Is this interpreter "safe" ? */
{
    Interp *iPtr;

    if (interp == (Tcl_Interp *) NULL) {
        return 0;
    }
    iPtr = (Interp *) interp;

    return ( (iPtr->flags) & SAFE_INTERP ) ? 1 : 0 ;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateSlave --
 *
 *	Creates a slave interpreter. The slavePath argument denotes the
 *	name of the new slave relative to the current interpreter; the
 *	slave is a direct descendant of the one-before-last component of
 *	the path, e.g. it is a descendant of the current interpreter if
 *	the slavePath argument contains only one component. Optionally makes
 *	the slave interpreter safe.
 *
 * Results:
 *	Returns the interpreter structure created, or NULL if an error
 *	occurred.
 *
 * Side effects:
 *	Creates a new interpreter and a new interpreter object command in
 *	the interpreter indicated by the slavePath argument.
 *
 *----------------------------------------------------------------------
 */

Tcl_Interp *
Tcl_CreateSlave(interp, slavePath, isSafe)
    Tcl_Interp *interp;		/* Interpreter to start search at. */
    char *slavePath;		/* Name of slave to create. */
    int isSafe;			/* Should new slave be "safe" ? */
{
    Master *masterPtr;			/* Master record for same. */

    if ((interp == (Tcl_Interp *) NULL) || (slavePath == (char *) NULL)) {
        return NULL;
    }
    masterPtr = (Master *) Tcl_GetAssocData(interp, "tclMasterRecord",
            NULL); 
    if (masterPtr == (Master *) NULL) {
        panic("CreatSlave: could not find master record");
    }
    return CreateSlave(interp, masterPtr, slavePath, isSafe);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetSlave --
 *
 *	Finds a slave interpreter by its path name.
 *
 * Results:
 *	Returns a Tcl_Interp * for the named interpreter or NULL if not
 *	found.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Interp *
Tcl_GetSlave(interp, slavePath)
    Tcl_Interp *interp;		/* Interpreter to start search from. */
    char *slavePath;		/* Path of slave to find. */
{
    Master *masterPtr;		/* Interim storage for Master record. */

    if ((interp == (Tcl_Interp *) NULL) || (slavePath == (char *) NULL)) {
        return NULL;
    }
    masterPtr = (Master *) Tcl_GetAssocData(interp, "tclMasterRecord", NULL);
    if (masterPtr == (Master *) NULL) {
        panic("Tcl_GetSlave: could not find master record");
    }
    return GetInterp(interp, masterPtr, slavePath, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetMaster --
 *
 *	Finds the master interpreter of a slave interpreter.
 *
 * Results:
 *	Returns a Tcl_Interp * for the master interpreter or NULL if none.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Interp *
Tcl_GetMaster(interp)
    Tcl_Interp *interp;		/* Get the master of this interpreter. */
{
    Slave *slavePtr;		/* Slave record of this interpreter. */

    if (interp == (Tcl_Interp *) NULL) {
        return NULL;
    }
    slavePtr = (Slave *) Tcl_GetAssocData(interp, "tclSlaveRecord", NULL);
    if (slavePtr == (Slave *) NULL) {
        return NULL;
    }
    return slavePtr->masterInterp;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateAlias --
 *
 *	Creates an alias between two interpreters.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Creates a new alias, manipulates the result field of slaveInterp.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_CreateAlias(slaveInterp, slaveCmd, targetInterp, targetCmd, argc, argv)
    Tcl_Interp *slaveInterp;		/* Interpreter for source command. */
    char *slaveCmd;			/* Command to install in slave. */
    Tcl_Interp *targetInterp;		/* Interpreter for target command. */
    char *targetCmd;			/* Name of target command. */
    int argc;				/* How many additional arguments? */
    char **argv;			/* These are the additional args. */
{
    Master *masterPtr;			/* Master record for target interp. */
    Tcl_Obj **objv;
    int i;
    int result;
    
    if ((slaveInterp == (Tcl_Interp *) NULL) ||
            (targetInterp == (Tcl_Interp *) NULL) ||
            (slaveCmd == (char *) NULL) ||
            (targetCmd == (char *) NULL)) {
        return TCL_ERROR;
    }
    masterPtr = (Master *) Tcl_GetAssocData(targetInterp, "tclMasterRecord",
            NULL);
    if (masterPtr == (Master *) NULL) {
        panic("Tcl_CreateAlias: could not find master record");
    }
    objv = (Tcl_Obj **) ckalloc((unsigned) sizeof(Tcl_Obj *) * argc);
    for (i = 0; i < argc; i++) {
        objv[i] = Tcl_NewStringObj(argv[i], -1);
        Tcl_IncrRefCount(objv[i]);
    }
    
    result = AliasCreationHelper(slaveInterp, slaveInterp, targetInterp,
            masterPtr, slaveCmd, targetCmd, argc, objv);

    ckfree((char *) objv);

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateAliasObj --
 *
 *	Object version: Creates an alias between two interpreters.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Creates a new alias.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_CreateAliasObj(slaveInterp, slaveCmd, targetInterp, targetCmd, objc, objv)
    Tcl_Interp *slaveInterp;		/* Interpreter for source command. */
    char *slaveCmd;			/* Command to install in slave. */
    Tcl_Interp *targetInterp;		/* Interpreter for target command. */
    char *targetCmd;			/* Name of target command. */
    int objc;				/* How many additional arguments? */
    Tcl_Obj *CONST objv[];		/* Argument vector. */
{
    Master *masterPtr;			/* Master record for target interp. */

    if ((slaveInterp == (Tcl_Interp *) NULL) ||
            (targetInterp == (Tcl_Interp *) NULL) ||
            (slaveCmd == (char *) NULL) ||
            (targetCmd == (char *) NULL)) {
        return TCL_ERROR;
    }
    masterPtr = (Master *) Tcl_GetAssocData(targetInterp, "tclMasterRecord",
            NULL);
    if (masterPtr == (Master *) NULL) {
        panic("Tcl_CreateAlias: could not find master record");
    }
    return AliasCreationHelper(slaveInterp, slaveInterp, targetInterp,
            masterPtr, slaveCmd, targetCmd, objc, objv);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetAlias --
 *
 *	Gets information about an alias.
 *
 * Results:
 *	A standard Tcl result. 
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetAlias(interp, aliasName, targetInterpPtr, targetNamePtr, argcPtr,
        argvPtr)
    Tcl_Interp *interp;			/* Interp to start search from. */
    char *aliasName;			/* Name of alias to find. */
    Tcl_Interp **targetInterpPtr;	/* (Return) target interpreter. */
    char **targetNamePtr;		/* (Return) name of target command. */
    int *argcPtr;			/* (Return) count of addnl args. */
    char ***argvPtr;			/* (Return) additional arguments. */
{
    Slave *slavePtr;			/* Slave record for slave interp. */
    Tcl_HashEntry *hPtr;		/* Search element. */
    Alias *aliasPtr;			/* Storage for alias found. */
    int len;
    int i;

    if ((interp == (Tcl_Interp *) NULL) || (aliasName == (char *) NULL)) {
        return TCL_ERROR;
    }
    slavePtr = (Slave *) Tcl_GetAssocData(interp, "tclSlaveRecord", NULL);
    if (slavePtr == (Slave *) NULL) {
        panic("Tcl_GetAlias: could not find slave record");
    }
    hPtr = Tcl_FindHashEntry(&(slavePtr->aliasTable), aliasName);
    if (hPtr == (Tcl_HashEntry *) NULL) {
        Tcl_AppendResult(interp, "alias \"", aliasName, "\" not found",
                (char *) NULL);
        return TCL_ERROR;
    }
    aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
    if (targetInterpPtr != (Tcl_Interp **) NULL) {
        *targetInterpPtr = aliasPtr->targetInterp;
    }
    if (targetNamePtr != (char **) NULL) {
        *targetNamePtr = aliasPtr->targetName;
    }
    if (argcPtr != (int *) NULL) {
        *argcPtr = aliasPtr->objc;
    }
    if (argvPtr != (char ***) NULL) {
        *argvPtr = (char **) ckalloc((unsigned) sizeof(char *) *
                aliasPtr->objc);
        for (i = 0; i < aliasPtr->objc; i++) {
            *argvPtr[i] = Tcl_GetStringFromObj(aliasPtr->objv[i], &len);
        }
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ObjGetAlias --
 *
 *	Object version: Gets information about an alias.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetAliasObj(interp, aliasName, targetInterpPtr, targetNamePtr, objcPtr,
        objvPtr)
    Tcl_Interp *interp;			/* Interp to start search from. */
    char *aliasName;			/* Name of alias to find. */
    Tcl_Interp **targetInterpPtr;	/* (Return) target interpreter. */
    char **targetNamePtr;		/* (Return) name of target command. */
    int *objcPtr;			/* (Return) count of addnl args. */
    Tcl_Obj ***objvPtr;			/* (Return) additional args. */
{
    Slave *slavePtr;			/* Slave record for slave interp. */
    Tcl_HashEntry *hPtr;		/* Search element. */
    Alias *aliasPtr;			/* Storage for alias found. */

    if ((interp == (Tcl_Interp *) NULL) || (aliasName == (char *) NULL)) {
        return TCL_ERROR;
    }
    slavePtr = (Slave *) Tcl_GetAssocData(interp, "tclSlaveRecord", NULL);
    if (slavePtr == (Slave *) NULL) {
        panic("Tcl_GetAlias: could not find slave record");
    }
    hPtr = Tcl_FindHashEntry(&(slavePtr->aliasTable), aliasName);
    if (hPtr == (Tcl_HashEntry *) NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "alias \"", aliasName, "\" not found", (char *) NULL);
        return TCL_ERROR;
    }
    aliasPtr = (Alias *) Tcl_GetHashValue(hPtr);
    if (targetInterpPtr != (Tcl_Interp **) NULL) {
        *targetInterpPtr = aliasPtr->targetInterp;
    }
    if (targetNamePtr != (char **) NULL) {
        *targetNamePtr = aliasPtr->targetName;
    }
    if (objcPtr != (int *) NULL) {
        *objcPtr = aliasPtr->objc;
    }
    if (objvPtr != (Tcl_Obj ***) NULL) {
        *objvPtr = aliasPtr->objv;
    }
    return TCL_OK;
}







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


2347
2348
2349
2350
2351
2352
2353









































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































2354
2355
        Tcl_UnregisterChannel(interp, chan);
    }
    chan = Tcl_GetStdChannel(TCL_STDERR);
    if (chan != (Tcl_Channel) NULL) {
        Tcl_UnregisterChannel(interp, chan);
    }










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































    return TCL_OK;
}

Changes to generic/tclLink.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* 
 * tclLink.c --
 *
 *	This file implements linked variables (a C variable that is
 *	tied to a Tcl variable).  The idea of linked variables was
 *	first suggested by Andreas Stolcke and this implementation is
 *	based heavily on a prototype implementation provided by
 *	him.
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclLink.c 1.15 97/01/21 21:51:42
 */

#include "tclInt.h"

/*
 * For each linked variable there is a data structure of the following
 * type, which describes the link and is the clientData for the trace










|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* 
 * tclLink.c --
 *
 *	This file implements linked variables (a C variable that is
 *	tied to a Tcl variable).  The idea of linked variables was
 *	first suggested by Andreas Stolcke and this implementation is
 *	based heavily on a prototype implementation provided by
 *	him.
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * 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: tclLink.c,v 1.1.2.2 1998/09/24 23:58:55 stanton Exp $
 */

#include "tclInt.h"

/*
 * For each linked variable there is a data structure of the following
 * type, which describes the link and is the clientData for the trace
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
 * Tcl_LinkVar --
 *
 *	Link a C variable to a Tcl variable so that changes to either
 *	one causes the other to change.
 *
 * Results:
 *	The return value is TCL_OK if everything went well or TCL_ERROR
 *	if an error occurred (interp->result is also set after errors).

 *
 * Side effects:
 *	The value at *addr is linked to the Tcl variable "varName",
 *	using "type" to convert between string values for Tcl and
 *	binary values for *addr.
 *
 *----------------------------------------------------------------------







|
>







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 * Tcl_LinkVar --
 *
 *	Link a C variable to a Tcl variable so that changes to either
 *	one causes the other to change.
 *
 * Results:
 *	The return value is TCL_OK if everything went well or TCL_ERROR
 *	if an error occurred (the interp's result is also set after
 *	errors).
 *
 * Side effects:
 *	The value at *addr is linked to the Tcl variable "varName",
 *	using "type" to convert between string values for Tcl and
 *	binary values for *addr.
 *
 *----------------------------------------------------------------------
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
    char *name1;		/* First part of variable name. */
    char *name2;		/* Second part of variable name. */
    int flags;			/* Miscellaneous additional information. */
{
    Link *linkPtr = (Link *) clientData;
    int changed;
    char buffer[TCL_DOUBLE_SPACE];
    char *value, **pp;
    Tcl_DString savedResult;

    /*
     * If the variable is being unset, then just re-create it (with a
     * trace) unless the whole interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {







|
|







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
    char *name1;		/* First part of variable name. */
    char *name2;		/* Second part of variable name. */
    int flags;			/* Miscellaneous additional information. */
{
    Link *linkPtr = (Link *) clientData;
    int changed;
    char buffer[TCL_DOUBLE_SPACE];
    char *value, **pp, *result;
    Tcl_Obj *objPtr;

    /*
     * If the variable is being unset, then just re-create it (with a
     * trace) unless the whole interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
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
    value = Tcl_GetVar(interp, linkPtr->varName, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	/*
	 * This shouldn't ever happen.
	 */
	return "internal error: linked variable couldn't be read";
    }
    Tcl_DStringInit(&savedResult);
    Tcl_DStringAppend(&savedResult, interp->result, -1);

    Tcl_ResetResult(interp);


    switch (linkPtr->type) {
	case TCL_LINK_INT:
	    if (Tcl_GetInt(interp, value, &linkPtr->lastValue.i) != TCL_OK) {
		Tcl_DStringResult(interp, &savedResult);
		Tcl_SetVar(interp, linkPtr->varName,
			StringValue(linkPtr, buffer), TCL_GLOBAL_ONLY);
		return "variable must have integer value";

	    }
	    *(int *)(linkPtr->addr) = linkPtr->lastValue.i;
	    break;
	case TCL_LINK_DOUBLE:
	    if (Tcl_GetDouble(interp, value, &linkPtr->lastValue.d)
		    != TCL_OK) {
		Tcl_DStringResult(interp, &savedResult);
		Tcl_SetVar(interp, linkPtr->varName,
			StringValue(linkPtr, buffer), TCL_GLOBAL_ONLY);
		return "variable must have real value";

	    }
	    *(double *)(linkPtr->addr) = linkPtr->lastValue.d;
	    break;
	case TCL_LINK_BOOLEAN:
	    if (Tcl_GetBoolean(interp, value, &linkPtr->lastValue.i)
		    != TCL_OK) {
		Tcl_DStringResult(interp, &savedResult);
		Tcl_SetVar(interp, linkPtr->varName,
			StringValue(linkPtr, buffer), TCL_GLOBAL_ONLY);
		return "variable must have boolean value";

	    }
	    *(int *)(linkPtr->addr) = linkPtr->lastValue.i;
	    break;
	case TCL_LINK_STRING:
	    pp = (char **)(linkPtr->addr);
	    if (*pp != NULL) {
		ckfree(*pp);
	    }
	    *pp = (char *) ckalloc((unsigned) (strlen(value) + 1));
	    strcpy(*pp, value);
	    break;
	default:
	    return "internal error: bad linked variable type";
    }

    Tcl_DStringResult(interp, &savedResult);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * StringValue --
 *
 *	Converts the value of a C variable to a string for use in a
 *	Tcl variable to which it is linked.
 *
 * Results:
 *	The return value is a pointer
 to a string that represents
 *	the value of the C variable given by linkPtr.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */







|
|
>

>
>



|


|
>






|


|
>






|


|
>














>
|
|











|
<







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
    value = Tcl_GetVar(interp, linkPtr->varName, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	/*
	 * This shouldn't ever happen.
	 */
	return "internal error: linked variable couldn't be read";
    }

    objPtr = Tcl_GetObjResult(interp);
    Tcl_IncrRefCount(objPtr);
    Tcl_ResetResult(interp);
    result = NULL;

    switch (linkPtr->type) {
	case TCL_LINK_INT:
	    if (Tcl_GetInt(interp, value, &linkPtr->lastValue.i) != TCL_OK) {
		Tcl_SetObjResult(interp, objPtr);
		Tcl_SetVar(interp, linkPtr->varName,
			StringValue(linkPtr, buffer), TCL_GLOBAL_ONLY);
		result = "variable must have integer value";
		goto end;
	    }
	    *(int *)(linkPtr->addr) = linkPtr->lastValue.i;
	    break;
	case TCL_LINK_DOUBLE:
	    if (Tcl_GetDouble(interp, value, &linkPtr->lastValue.d)
		    != TCL_OK) {
		Tcl_SetObjResult(interp, objPtr);
		Tcl_SetVar(interp, linkPtr->varName,
			StringValue(linkPtr, buffer), TCL_GLOBAL_ONLY);
		result = "variable must have real value";
		goto end;
	    }
	    *(double *)(linkPtr->addr) = linkPtr->lastValue.d;
	    break;
	case TCL_LINK_BOOLEAN:
	    if (Tcl_GetBoolean(interp, value, &linkPtr->lastValue.i)
		    != TCL_OK) {
		Tcl_SetObjResult(interp, objPtr);
		Tcl_SetVar(interp, linkPtr->varName,
			StringValue(linkPtr, buffer), TCL_GLOBAL_ONLY);
		result = "variable must have boolean value";
		goto end;
	    }
	    *(int *)(linkPtr->addr) = linkPtr->lastValue.i;
	    break;
	case TCL_LINK_STRING:
	    pp = (char **)(linkPtr->addr);
	    if (*pp != NULL) {
		ckfree(*pp);
	    }
	    *pp = (char *) ckalloc((unsigned) (strlen(value) + 1));
	    strcpy(*pp, value);
	    break;
	default:
	    return "internal error: bad linked variable type";
    }
    end:
    Tcl_DecrRefCount(objPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * StringValue --
 *
 *	Converts the value of a C variable to a string for use in a
 *	Tcl variable to which it is linked.
 *
 * Results:
 *	The return value is a pointer to a string that represents

 *	the value of the C variable given by linkPtr.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Changes to generic/tclListObj.c.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclListObj.c --
 *
 *	This file contains procedures that implement the Tcl list object
 *	type.
 *
 * 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.
 *
 * SCCS: @(#) tclListObj.c 1.47 97/08/12 19:02:02
 */

#include "tclInt.h"

/*
 * Prototypes for procedures defined later in this file:
 */







>




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclListObj.c --
 *
 *	This file contains procedures that implement the Tcl list object
 *	type.
 *
 * Copyright (c) 1995-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: tclListObj.c,v 1.1.2.3 1998/11/11 04:08:22 stanton Exp $
 */

#include "tclInt.h"

/*
 * Prototypes for procedures defined later in this file:
 */
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
    /*
     * Free any old string rep and any internal rep for the old type.
     */

    Tcl_InvalidateStringRep(objPtr);
    if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
	oldTypePtr->freeIntRepProc(objPtr);
	objPtr->typePtr = NULL;
    }

        
    /*
     * Set the object's type to "list" and initialize the internal rep.


     */

    if (objc > 0) {
	elemPtrs = (Tcl_Obj **)
	    ckalloc((unsigned) (objc * sizeof(Tcl_Obj *)));
	for (i = 0;  i < objc;  i++) {
	    elemPtrs[i] = objv[i];
	    Tcl_IncrRefCount(elemPtrs[i]);
	}
	
	listRepPtr = (List *) ckalloc(sizeof(List));
	listRepPtr->maxElemCount = objc;
	listRepPtr->elemCount    = objc;
	listRepPtr->elements     = elemPtrs;
	
	objPtr->internalRep.otherValuePtr = (VOID *) listRepPtr;
	objPtr->typePtr = &tclListType;


    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ListObjGetElements --







<

>



>
>

















>
>







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
    /*
     * Free any old string rep and any internal rep for the old type.
     */

    Tcl_InvalidateStringRep(objPtr);
    if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
	oldTypePtr->freeIntRepProc(objPtr);

    }
    objPtr->typePtr = NULL;
        
    /*
     * Set the object's type to "list" and initialize the internal rep.
     * However, if there are no elements to put in the list, just give
     * the object an empty string rep and a NULL type.
     */

    if (objc > 0) {
	elemPtrs = (Tcl_Obj **)
	    ckalloc((unsigned) (objc * sizeof(Tcl_Obj *)));
	for (i = 0;  i < objc;  i++) {
	    elemPtrs[i] = objv[i];
	    Tcl_IncrRefCount(elemPtrs[i]);
	}
	
	listRepPtr = (List *) ckalloc(sizeof(List));
	listRepPtr->maxElemCount = objc;
	listRepPtr->elemCount    = objc;
	listRepPtr->elements     = elemPtrs;
	
	objPtr->internalRep.otherValuePtr = (VOID *) listRepPtr;
	objPtr->typePtr = &tclListType;
    } else {
	objPtr->bytes = tclEmptyStringRep;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ListObjGetElements --
870
871
872
873
874
875
876
877

878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910

static int
SetListFromAny(interp, objPtr)
    Tcl_Interp *interp;		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr;		/* The object to convert. */
{
    Tcl_ObjType *oldTypePtr = objPtr->typePtr;
    char *string, *elemStart, *nextElem, *s;

    int lenRemain, length, estCount, elemSize, hasBrace, i, j, result;
    char *limit;		/* Points just after string's last byte. */
    register char *p;
    register Tcl_Obj **elemPtrs;
    register Tcl_Obj *elemPtr;
    List *listRepPtr;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    string = TclGetStringFromObj(objPtr, &length);

    /*
     * Parse the string into separate string objects, and create a List
     * structure that points to the element string objects. We use a
     * modified version of Tcl_SplitList's implementation to avoid one
     * malloc and a string copy for each list element. First, estimate the
     * number of elements by counting the number of space characters in the
     * list.
     */

    limit = (string + length);
    estCount = 1;
    for (p = string;  p < limit;  p++) {
	if (isspace(UCHAR(*p))) {
	    estCount++;
	}
    }

    /*
     * Allocate a new List structure with enough room for "estCount"
     * elements. Each element is a pointer to a Tcl_Obj with the appropriate







|
>


|








|













|







875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916

static int
SetListFromAny(interp, objPtr)
    Tcl_Interp *interp;		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr;		/* The object to convert. */
{
    Tcl_ObjType *oldTypePtr = objPtr->typePtr;
    char *string, *s;
    CONST char *elemStart, *nextElem;
    int lenRemain, length, estCount, elemSize, hasBrace, i, j, result;
    char *limit;		/* Points just after string's last byte. */
    register CONST char *p;
    register Tcl_Obj **elemPtrs;
    register Tcl_Obj *elemPtr;
    List *listRepPtr;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    string = Tcl_GetStringFromObj(objPtr, &length);

    /*
     * Parse the string into separate string objects, and create a List
     * structure that points to the element string objects. We use a
     * modified version of Tcl_SplitList's implementation to avoid one
     * malloc and a string copy for each list element. First, estimate the
     * number of elements by counting the number of space characters in the
     * list.
     */

    limit = (string + length);
    estCount = 1;
    for (p = string;  p < limit;  p++) {
	if (isspace(UCHAR(*p))) { /* INTL: ISO space. */
	    estCount++;
	}
    }

    /*
     * Allocate a new List structure with enough room for "estCount"
     * elements. Each element is a pointer to a Tcl_Obj with the appropriate

Added generic/tclLiteral.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
/* 
 * tclLiteral.c --
 *
 *	Implementation of the global and ByteCode-local literal tables
 *	used to manage the Tcl objects created for literal values during
 *	compilation of Tcl scripts. This implementation borrows heavily
 *	from the more general hashtable implementation of Tcl hash tables
 *	that appears in tclHash.c.
 *
 * 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: tclLiteral.c,v 1.1.2.2 1998/10/03 01:56:41 stanton Exp $
 */

#include "tclInt.h"
#include "tclCompile.h"

/*
 * When there are this many entries per bucket, on average, rebuild
 * a literal's hash table to make it larger.
 */

#define REBUILD_MULTIPLIER	3

/*
 * Procedure prototypes for static procedures in this file:
 */

static int		AddLocalLiteralEntry _ANSI_ARGS_((
			    CompileEnv *envPtr, LiteralEntry *globalPtr,
			    int localHash));
static void		ExpandLocalLiteralArray _ANSI_ARGS_((
			    CompileEnv *envPtr));
static unsigned int	HashString _ANSI_ARGS_((CONST char *bytes,
			    int length));
static void		RebuildLiteralTable _ANSI_ARGS_((
			    LiteralTable *tablePtr));

/*
 *----------------------------------------------------------------------
 *
 * TclInitLiteralTable --
 *
 *	This procedure is called to initialize the fields of a literal table
 *	structure for either an interpreter or a compilation's CompileEnv
 *	structure.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The literal table is made ready for use.
 *
 *----------------------------------------------------------------------
 */

void
TclInitLiteralTable(tablePtr)
    register LiteralTable *tablePtr; /* Pointer to table structure, which
				      * is supplied by the caller. */
{
#if (TCL_SMALL_HASH_TABLE != 4) 
    panic("TclInitLiteralTable: TCL_SMALL_HASH_TABLE is %d, not 4\n",
	    TCL_SMALL_HASH_TABLE);
#endif
    
    tablePtr->buckets = tablePtr->staticBuckets;
    tablePtr->staticBuckets[0] = tablePtr->staticBuckets[1] = 0;
    tablePtr->staticBuckets[2] = tablePtr->staticBuckets[3] = 0;
    tablePtr->numBuckets = TCL_SMALL_HASH_TABLE;
    tablePtr->numEntries = 0;
    tablePtr->rebuildSize = TCL_SMALL_HASH_TABLE*REBUILD_MULTIPLIER;
    tablePtr->mask = 3;
}

/*
 *----------------------------------------------------------------------
 *
 * TclDeleteLiteralTable --
 *
 *	This procedure frees up everything associated with a literal table
 *	except for the table's structure itself.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Each literal in the table is released: i.e., its reference count
 *	in the global literal table is decremented and, if it becomes zero,
 *	the literal is freed. In addition, the table's bucket array is
 *	freed.
 *
 *----------------------------------------------------------------------
 */

void
TclDeleteLiteralTable(interp, tablePtr)
    Tcl_Interp *interp;		/* Interpreter containing shared literals
				 * referenced by the table to delete. */
    LiteralTable *tablePtr;	/* Points to the literal table to delete. */
{
    LiteralEntry *entryPtr;
    int i, start;

    /*
     * Release remaining literals in the table. Note that releasing a
     * literal might release other literals, modifying the table, so we
     * restart the search from the bucket chain we last found an entry.
     */

#ifdef TCL_COMPILE_DEBUG
    TclVerifyGlobalLiteralTable((Interp *) interp);
#endif /*TCL_COMPILE_DEBUG*/

    start = 0;
    while (tablePtr->numEntries > 0) {
	for (i = start;  i < tablePtr->numBuckets;  i++) {
	    entryPtr = tablePtr->buckets[i];
	    if (entryPtr != NULL) {
		TclReleaseLiteral(interp, entryPtr->objPtr);
		start = i;
		break;
	    }
	}
    }

    /*
     * Free up the table's bucket array if it was dynamically allocated.
     */

    if (tablePtr->buckets != tablePtr->staticBuckets) {
	ckfree((char *) tablePtr->buckets);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclRegisterLiteral --
 *
 *	Find, or if necessary create, an object in a CompileEnv literal
 *	array that has a string representation matching the argument string.
 *
 * Results:
 *	The index in the CompileEnv's literal array that references a
 *	shared literal matching the string. The object is created if
 *	necessary.
 *
 * Side effects:
 *	To maximize sharing, we look up the string in the interpreter's
 *	global literal table. If not found, we create a new shared literal
 *	in the global table. We then add a reference to the shared
 *	literal in the CompileEnv's literal array. 
 *
 *	If onHeap is 1, this procedure is given ownership of the string: if
 *	an object is created then its string representation is set directly
 *	from string, otherwise the string is freed. Typically, a caller sets
 *	onHeap 1 if "string" is an already heap-allocated buffer holding the
 *	result of backslash substitutions.
 *
 *----------------------------------------------------------------------
 */

int
TclRegisterLiteral(envPtr, bytes, length, onHeap)
    CompileEnv *envPtr;		/* Points to the CompileEnv in whose object
				 * array an object is found or created. */
    register char *bytes;	/* Points to string for which to find or
				 * create an object in CompileEnv's object
				 * array. */
    int length;			/* Number of bytes in the string. If < 0,
				 * the string consists of all bytes up to
				 * the first null character. */
    int onHeap;			/* If 1 then the caller already malloc'd
				 * bytes and ownership is passed to this
				 * procedure. */
{
    Interp *iPtr = envPtr->iPtr;
    LiteralTable *globalTablePtr = &(iPtr->literalTable);
    LiteralTable *localTablePtr = &(envPtr->localLitTable);
    register LiteralEntry *globalPtr, *localPtr;
    register Tcl_Obj *objPtr;
    unsigned int hash;
    int localHash, globalHash, objIndex;
    long n;
    char buf[TCL_INTEGER_SPACE];

    if (length < 0) {
	length = (bytes? strlen(bytes) : 0);
    }
    hash = HashString(bytes, length);

    /*
     * Is the literal already in the CompileEnv's local literal array?
     * If so, just return its index.
     */

    localHash = (hash & localTablePtr->mask);
    for (localPtr = localTablePtr->buckets[localHash];
	    localPtr != NULL;  localPtr = localPtr->nextPtr) {
	objPtr = localPtr->objPtr;
	if ((objPtr->length == length) && ((length == 0)
		|| ((objPtr->bytes[0] == bytes[0])
			&& (memcmp(objPtr->bytes, bytes, (unsigned) length)
				== 0)))) {
	    if (onHeap) {
		ckfree(bytes);
	    }
	    objIndex = (localPtr - envPtr->literalArrayPtr);
#ifdef TCL_COMPILE_DEBUG
	    TclVerifyLocalLiteralTable(envPtr);
#endif /*TCL_COMPILE_DEBUG*/
	    return objIndex;
	}
    }

    /*
     * The literal is new to this CompileEnv. Is it in the interpreter's
     * global literal table?
     */

    globalHash = (hash & globalTablePtr->mask);
    for (globalPtr = globalTablePtr->buckets[globalHash];
	    globalPtr != NULL;  globalPtr = globalPtr->nextPtr) {
	objPtr = globalPtr->objPtr;
	if ((objPtr->length == length) && ((length == 0)
		|| ((objPtr->bytes[0] == bytes[0])
			&& (memcmp(objPtr->bytes, bytes, (unsigned) length)
				== 0)))) {
	    /*
	     * A global literal was found. Add an entry to the CompileEnv's
	     * local literal array.
	     */
	    
	    if (onHeap) {
		ckfree(bytes);
	    }
	    objIndex = AddLocalLiteralEntry(envPtr, globalPtr, localHash);
#ifdef TCL_COMPILE_DEBUG
	    if (globalPtr->refCount < 1) {
		panic("TclRegisterLiteral: global literal \"%.*s\" had bad refCount %d",
		        (length>60? 60 : length), bytes,
		        globalPtr->refCount);
	    }
	    TclVerifyLocalLiteralTable(envPtr);
#endif /*TCL_COMPILE_DEBUG*/ 
	    return objIndex;
	}
    }

    /*
     * The literal is new to the interpreter. Add it to the global literal
     * table then add an entry to the CompileEnv's local literal array.
     * Convert the object to an integer object if possible.
     */

    TclNewObj(objPtr);
    Tcl_IncrRefCount(objPtr);
    if (onHeap) {
	objPtr->bytes = bytes;
	objPtr->length = length;
    } else {
	TclInitStringRep(objPtr, bytes, length);
    }
    if (TclLooksLikeInt(bytes, length)) {
	if (TclGetLong((Tcl_Interp *) NULL, bytes, &n) == TCL_OK) {
	    TclFormatInt(buf, n);
	    if (strcmp(bytes, buf) == 0) {
		objPtr->internalRep.longValue = n;
		objPtr->typePtr = &tclIntType;
	    }
	}
    }
    
#ifdef TCL_COMPILE_DEBUG
    if (TclLookupLiteralEntry((Tcl_Interp *) iPtr, objPtr) != NULL) {
	panic("TclRegisterLiteral: literal \"%.*s\" found globally but shouldn't be",
	        (length>60? 60 : length), bytes);
    }
#endif

    globalPtr = (LiteralEntry *) ckalloc((unsigned) sizeof(LiteralEntry));
    globalPtr->objPtr = objPtr;
    globalPtr->refCount = 0;
    globalPtr->nextPtr = globalTablePtr->buckets[globalHash];
    globalTablePtr->buckets[globalHash] = globalPtr;
    globalTablePtr->numEntries++;

    /*
     * If the global literal table has exceeded a decent size, rebuild it
     * with more buckets.
     */

    if (globalTablePtr->numEntries >= globalTablePtr->rebuildSize) {
	RebuildLiteralTable(globalTablePtr);
    }
    
    objIndex = AddLocalLiteralEntry(envPtr, globalPtr, localHash);

#ifdef TCL_COMPILE_DEBUG
    TclVerifyGlobalLiteralTable(iPtr);
    TclVerifyLocalLiteralTable(envPtr);
    {
	LiteralEntry *entryPtr;
	int found, i;
	found = 0;
	for (i = 0;  i < globalTablePtr->numBuckets;  i++) {
	    for (entryPtr = globalTablePtr->buckets[i];
		    entryPtr != NULL;  entryPtr = entryPtr->nextPtr) {
		if ((entryPtr == globalPtr)
		        && (entryPtr->objPtr == objPtr)) {
		    found = 1;
		}
	    }
	}
	if (!found) {
	    panic("TclRegisterLiteral: literal \"%.*s\" wasn't global",
	            (length>60? 60 : length), bytes);
	}
    }
#endif /*TCL_COMPILE_DEBUG*/
#ifdef TCL_COMPILE_STATS   
    iPtr->stats.numLiteralsCreated++;
    iPtr->stats.totalLitStringBytes   += (double) (length + 1);
    iPtr->stats.currentLitStringBytes += (double) (length + 1);
    iPtr->stats.literalCount[TclLog2(length)]++;
#endif /*TCL_COMPILE_STATS*/
    return objIndex;
}

/*
 *----------------------------------------------------------------------
 *
 * TclLookupLiteralEntry --
 *
 *	Finds the LiteralEntry that corresponds to a literal Tcl object
 *      holding a literal.
 *
 * Results:
 *      Returns the matching LiteralEntry if found, otherwise NULL.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */

LiteralEntry *
TclLookupLiteralEntry(interp, objPtr)
    Tcl_Interp *interp;		/* Interpreter for which objPtr was created
                                 * to hold a literal. */
    register Tcl_Obj *objPtr;	/* Points to a Tcl object holding a
                                 * literal that was previously created by a
                                 * call to TclRegisterLiteral. */
{
    Interp *iPtr = (Interp *) interp;
    LiteralTable *globalTablePtr = &(iPtr->literalTable);
    register LiteralEntry *entryPtr;
    char *bytes;
    int length, globalHash;

    bytes = Tcl_GetStringFromObj(objPtr, &length);
    globalHash = (HashString(bytes, length) & globalTablePtr->mask);
    for (entryPtr = globalTablePtr->buckets[globalHash];
            entryPtr != NULL;  entryPtr = entryPtr->nextPtr) {
        if (entryPtr->objPtr == objPtr) {
            return entryPtr;
        }
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * AddLocalLiteralEntry --
 *
 *	Insert a new literal into a CompileEnv's local literal array.
 *
 * Results:
 *	The index in the CompileEnv's literal array that references the
 *	literal.
 *
 * Side effects:
 *	Increments the ref count of the global LiteralEntry since the
 *	CompileEnv now refers to the literal. Expands the literal array
 *	if necessary. May rebuild the hash bucket array of the CompileEnv's
 *	literal array if it becomes too large.
 *
 *----------------------------------------------------------------------
 */

static int
AddLocalLiteralEntry(envPtr, globalPtr, localHash)
    register CompileEnv *envPtr; /* Points to CompileEnv in whose literal
				  * array the object is to be inserted. */
    LiteralEntry *globalPtr;	 /* Points to the global LiteralEntry for
				  * the literal to add to the CompileEnv. */
    int localHash;		 /* Hash value for the literal's string. */
{
    register LiteralTable *localTablePtr = &(envPtr->localLitTable);
    register LiteralEntry *localPtr;
    int objIndex;
    
    if (envPtr->literalArrayNext >= envPtr->literalArrayEnd) {
	ExpandLocalLiteralArray(envPtr);
    }
    objIndex = envPtr->literalArrayNext;
    envPtr->literalArrayNext++;

    localPtr = &(envPtr->literalArrayPtr[objIndex]);
    localPtr->objPtr = globalPtr->objPtr;
    localPtr->refCount = -1;	/* i.e., unused */
    localPtr->nextPtr = localTablePtr->buckets[localHash];
    localTablePtr->buckets[localHash] = localPtr;
    localTablePtr->numEntries++;

    globalPtr->refCount++;

    /*
     * If the CompileEnv's local literal table has exceeded a decent size,
     * rebuild it with more buckets.
     */

    if (localTablePtr->numEntries >= localTablePtr->rebuildSize) {
	RebuildLiteralTable(localTablePtr);
    }

#ifdef TCL_COMPILE_DEBUG
    TclVerifyLocalLiteralTable(envPtr);
    {
	char *bytes;
	int length, found, i;
	found = 0;
	for (i = 0;  i < localTablePtr->numBuckets;  i++) {
	    for (localPtr = localTablePtr->buckets[i];
		    localPtr != NULL;  localPtr = localPtr->nextPtr) {
		if (localPtr->objPtr == globalPtr->objPtr) {
		    found = 1;
		}
	    }
	}
	if (!found) {
	    bytes = Tcl_GetStringFromObj(globalPtr->objPtr, &length);
	    panic("AddLocalLiteralEntry: literal \"%.*s\" wasn't found locally",
	            (length>60? 60 : length), bytes);
	}
    }
#endif /*TCL_COMPILE_DEBUG*/
    return objIndex;
}

/*
 *----------------------------------------------------------------------
 *
 * ExpandLocalLiteralArray --
 *
 *	Procedure that uses malloc to allocate more storage for a
 *	CompileEnv's local literal array.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The literal array in *envPtr is reallocated to a new array of
 *	double the size, and if envPtr->mallocedLiteralArray is non-zero
 *	the old array is freed. Entries are copied from the old array
 *	to the new one. The local literal table is updated to refer to
 *	the new entries.
 *
 *----------------------------------------------------------------------
 */

static void
ExpandLocalLiteralArray(envPtr)
    register CompileEnv *envPtr; /* Points to the CompileEnv whose object
				  * array must be enlarged. */
{
    /*
     * The current allocated local literal entries are stored between
     * elements 0 and (envPtr->literalArrayNext - 1) [inclusive].
     */

    LiteralTable *localTablePtr = &(envPtr->localLitTable);
    int currElems = envPtr->literalArrayNext;
    size_t currBytes = (currElems * sizeof(LiteralEntry));
    register LiteralEntry *currArrayPtr = envPtr->literalArrayPtr;
    register LiteralEntry *newArrayPtr =
	    (LiteralEntry *) ckalloc((unsigned) (2 * currBytes));
    int i;
    
    /*
     * Copy from the old literal array to the new, then update the local
     * literal table's bucket array.
     */

    memcpy((VOID *) newArrayPtr, (VOID *) currArrayPtr, currBytes);
    for (i = 0;  i < currElems;  i++) {
	if (currArrayPtr[i].nextPtr == NULL) {
	    newArrayPtr[i].nextPtr = NULL;
	} else {
	    newArrayPtr[i].nextPtr = newArrayPtr
		    + (currArrayPtr[i].nextPtr - currArrayPtr);
	}
    }
    for (i = 0;  i < localTablePtr->numBuckets;  i++) {
	if (localTablePtr->buckets[i] != NULL) {
	    localTablePtr->buckets[i] = newArrayPtr
	            + (localTablePtr->buckets[i] - currArrayPtr);
	}
    }

    /*
     * Free the old literal array if needed, and mark the new literal
     * array as malloced.
     */
    
    if (envPtr->mallocedLiteralArray) {
	ckfree((char *) currArrayPtr);
    }
    envPtr->literalArrayPtr = newArrayPtr;
    envPtr->literalArrayEnd = (2 * currElems);
    envPtr->mallocedLiteralArray = 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TclReleaseLiteral --
 *
 *	This procedure releases a reference to one of the shared Tcl objects
 *	that hold literals. It is called to release the literals referenced
 *	by a ByteCode that is being destroyed, and it is also called by
 *	TclDeleteLiteralTable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The reference count for the global LiteralTable entry that 
 *	corresponds to the literal is decremented. If no other reference
 *	to a global literal object remains, it is freed.
 *
 *----------------------------------------------------------------------
 */

void
TclReleaseLiteral(interp, objPtr)
    Tcl_Interp *interp;		/* Interpreter for which objPtr was created
				 * to hold a literal. */
    register Tcl_Obj *objPtr;	/* Points to a literal object that was
				 * previously created by a call to
				 * TclRegisterLiteral. */
{
    Interp *iPtr = (Interp *) interp;
    LiteralTable *globalTablePtr = &(iPtr->literalTable);
    register LiteralEntry *entryPtr, *prevPtr;
    ByteCode* codePtr;
    char *bytes;
    int length, index;

    bytes = Tcl_GetStringFromObj(objPtr, &length);
    index = (HashString(bytes, length) & globalTablePtr->mask);
    for (prevPtr = NULL, entryPtr = globalTablePtr->buckets[index];
	    entryPtr != NULL;
	    prevPtr = entryPtr, entryPtr = entryPtr->nextPtr) {
	if (entryPtr->objPtr == objPtr) {
	    entryPtr->refCount--;

	    /*
	     * We found the matching LiteralEntry. Check if it's only being
	     * kept alive only by a circular reference from a ByteCode
	     * stored as its internal rep.
	     */
	    
	    if ((entryPtr->refCount == 1)
		    && (objPtr->typePtr == &tclByteCodeType)) {
		codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
		if ((codePtr->numLitObjects == 1)
		        && (codePtr->objArrayPtr[0] == objPtr)) {
		    entryPtr->refCount = 0;

		    /*
		     * Set the ByteCode object array entry NULL to signal
		     * to TclCleanupByteCode to not try to release this
		     * about to be freed literal again.
		     */

		    codePtr->objArrayPtr[0] = NULL;
		}
	    }

	    /*
	     * If the literal is no longer being used by any ByteCode,
	     * delete the entry then decrement the ref count of its object.
	     */
		
	    if (entryPtr->refCount == 0) {
		if (prevPtr == NULL) {
		    globalTablePtr->buckets[index] = entryPtr->nextPtr;
		} else {
		    prevPtr->nextPtr = entryPtr->nextPtr;
		}
#ifdef TCL_COMPILE_STATS
		iPtr->stats.currentLitStringBytes -= (double) (length + 1);
#endif /*TCL_COMPILE_STATS*/
		ckfree((char *) entryPtr);
		globalTablePtr->numEntries--;
		TclDecrRefCount(objPtr);
	    }
	    return;
	}
    }
#ifdef TCL_COMPILE_DEBUG
    panic("TclReleaseLiteral: literal \"%.*s\" not found",
	    (length>60? 60 : length), bytes);
#endif /*TCL_COMPILE_DEBUG*/
}

/*
 *----------------------------------------------------------------------
 *
 * HashString --
 *
 *	Compute a one-word summary of a text string, which can be
 *	used to generate a hash index.
 *
 * Results:
 *	The return value is a one-word summary of the information in
 *	string.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static unsigned int
HashString(bytes, length)
    register CONST char *bytes; /* String for which to compute hash
				 * value. */
    int length;			/* Number of bytes in the string. */
{
    register unsigned int result;
    register int i;

    /*
     * I tried a zillion different hash functions and asked many other
     * people for advice.  Many people had their own favorite functions,
     * all different, but no-one had much idea why they were good ones.
     * I chose the one below (multiply by 9 and add new character)
     * because of the following reasons:
     *
     * 1. Multiplying by 10 is perfect for keys that are decimal strings,
     *    and multiplying by 9 is just about as good.
     * 2. Times-9 is (shift-left-3) plus (old).  This means that each
     *    character's bits hang around in the low-order bits of the
     *    hash value for ever, plus they spread fairly rapidly up to
     *    the high-order bits to fill out the hash value.  This seems
     *    works well both for decimal and non-decimal strings.
     */

    result = 0;
    for (i = 0;  i < length;  i++) {
	result += (result<<3) + *bytes++;
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * RebuildLiteralTable --
 *
 *	This procedure is invoked when the ratio of entries to hash buckets
 *	becomes too large in a local or global literal table. It allocates
 *	a larger bucket array and moves the entries into the new buckets.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory gets reallocated and entries get rehashed into new buckets.
 *
 *----------------------------------------------------------------------
 */

static void
RebuildLiteralTable(tablePtr)
    register LiteralTable *tablePtr; /* Local or global table to enlarge. */
{
    LiteralEntry **oldBuckets;
    register LiteralEntry **oldChainPtr, **newChainPtr;
    register LiteralEntry *entryPtr;
    LiteralEntry **bucketPtr;
    char *bytes;
    int oldSize, count, index, length;

    oldSize = tablePtr->numBuckets;
    oldBuckets = tablePtr->buckets;

    /*
     * Allocate and initialize the new bucket array, and set up
     * hashing constants for new array size.
     */

    tablePtr->numBuckets *= 4;
    tablePtr->buckets = (LiteralEntry **) ckalloc((unsigned)
	    (tablePtr->numBuckets * sizeof(LiteralEntry *)));
    for (count = tablePtr->numBuckets, newChainPtr = tablePtr->buckets;
	    count > 0;
	    count--, newChainPtr++) {
	*newChainPtr = NULL;
    }
    tablePtr->rebuildSize *= 4;
    tablePtr->mask = (tablePtr->mask << 2) + 3;

    /*
     * Rehash all of the existing entries into the new bucket array.
     */

    for (oldChainPtr = oldBuckets;
	    oldSize > 0;
	    oldSize--, oldChainPtr++) {
	for (entryPtr = *oldChainPtr;  entryPtr != NULL;
	        entryPtr = *oldChainPtr) {
	    bytes = Tcl_GetStringFromObj(entryPtr->objPtr, &length);
	    index = (HashString(bytes, length) & tablePtr->mask);
	    
	    *oldChainPtr = entryPtr->nextPtr;
	    bucketPtr = &(tablePtr->buckets[index]);
	    entryPtr->nextPtr = *bucketPtr;
	    *bucketPtr = entryPtr;
	}
    }

    /*
     * Free up the old bucket array, if it was dynamically allocated.
     */

    if (oldBuckets != tablePtr->staticBuckets) {
	ckfree((char *) oldBuckets);
    }
}

#ifdef TCL_COMPILE_STATS
/*
 *----------------------------------------------------------------------
 *
 * TclLiteralStats --
 *
 *	Return statistics describing the layout of the hash table
 *	in its hash buckets.
 *
 * Results:
 *	The return value is a malloc-ed string containing information
 *	about tablePtr.  It is the caller's responsibility to free
 *	this string.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclLiteralStats(tablePtr)
    LiteralTable *tablePtr;	/* Table for which to produce stats. */
{
#define NUM_COUNTERS 10
    int count[NUM_COUNTERS], overflow, i, j;
    double average, tmp;
    register LiteralEntry *entryPtr;
    char *result, *p;

    /*
     * Compute a histogram of bucket usage. For each bucket chain i,
     * j is the number of entries in the chain.
     */

    for (i = 0;  i < NUM_COUNTERS;  i++) {
	count[i] = 0;
    }
    overflow = 0;
    average = 0.0;
    for (i = 0;  i < tablePtr->numBuckets;  i++) {
	j = 0;
	for (entryPtr = tablePtr->buckets[i];  entryPtr != NULL;
	        entryPtr = entryPtr->nextPtr) {
	    j++;
	}
	if (j < NUM_COUNTERS) {
	    count[j]++;
	} else {
	    overflow++;
	}
	tmp = j;
	average += (tmp+1.0)*(tmp/tablePtr->numEntries)/2.0;
    }

    /*
     * Print out the histogram and a few other pieces of information.
     */

    result = (char *) ckalloc((unsigned) ((NUM_COUNTERS*60) + 300));
    sprintf(result, "%d entries in table, %d buckets\n",
	    tablePtr->numEntries, tablePtr->numBuckets);
    p = result + strlen(result);
    for (i = 0; i < NUM_COUNTERS; i++) {
	sprintf(p, "number of buckets with %d entries: %d\n",
		i, count[i]);
	p += strlen(p);
    }
    sprintf(p, "number of buckets with %d or more entries: %d\n",
	    NUM_COUNTERS, overflow);
    p += strlen(p);
    sprintf(p, "average search distance for entry: %.1f", average);
    return result;
}
#endif /*TCL_COMPILE_STATS*/

#ifdef TCL_COMPILE_DEBUG
/*
 *----------------------------------------------------------------------
 *
 * TclVerifyLocalLiteralTable --
 *
 *	Check a CompileEnv's local literal table for consistency.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Panics if problems are found.
 *
 *----------------------------------------------------------------------
 */

void
TclVerifyLocalLiteralTable(envPtr)
    CompileEnv *envPtr;		/* Points to CompileEnv whose literal
				 * table is to be validated. */
{
    register LiteralTable *localTablePtr = &(envPtr->localLitTable);
    register LiteralEntry *localPtr;
    char *bytes;
    register int i;
    int length, count;

    count = 0;
    for (i = 0;  i < localTablePtr->numBuckets;  i++) {
	for (localPtr = localTablePtr->buckets[i];
	        localPtr != NULL;  localPtr = localPtr->nextPtr) {
	    count++;
	    if (localPtr->refCount != -1) {
		bytes = Tcl_GetStringFromObj(localPtr->objPtr, &length);
		panic("TclVerifyLocalLiteralTable: local literal \"%.*s\" had bad refCount %d",
		        (length>60? 60 : length), bytes,
		        localPtr->refCount);
	    }
	    if (TclLookupLiteralEntry((Tcl_Interp *) envPtr->iPtr,
		    localPtr->objPtr) == NULL) {
		bytes = Tcl_GetStringFromObj(localPtr->objPtr, &length);
		panic("TclVerifyLocalLiteralTable: local literal \"%.*s\" is not global",
		         (length>60? 60 : length), bytes);
	    }
	    if (localPtr->objPtr->bytes == NULL) {
		panic("TclVerifyLocalLiteralTable: literal has NULL string rep");
	    }
	}
    }
    if (count != localTablePtr->numEntries) {
	panic("TclVerifyLocalLiteralTable: local literal table had %d entries, should be %d",
	      count, localTablePtr->numEntries);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclVerifyGlobalLiteralTable --
 *
 *	Check an interpreter's global literal table literal for consistency.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Panics if problems are found.
 *
 *----------------------------------------------------------------------
 */

void
TclVerifyGlobalLiteralTable(iPtr)
    Interp *iPtr;		/* Points to interpreter whose global
				 * literal table is to be validated. */
{
    register LiteralTable *globalTablePtr = &(iPtr->literalTable);
    register LiteralEntry *globalPtr;
    char *bytes;
    register int i;
    int length, count;

    count = 0;
    for (i = 0;  i < globalTablePtr->numBuckets;  i++) {
	for (globalPtr = globalTablePtr->buckets[i];
	        globalPtr != NULL;  globalPtr = globalPtr->nextPtr) {
	    count++;
	    if (globalPtr->refCount < 1) {
		bytes = Tcl_GetStringFromObj(globalPtr->objPtr, &length);
		panic("TclVerifyGlobalLiteralTable: global literal \"%.*s\" had bad refCount %d",
		        (length>60? 60 : length), bytes,
		        globalPtr->refCount);
	    }
	    if (globalPtr->objPtr->bytes == NULL) {
		panic("TclVerifyGlobalLiteralTable: literal has NULL string rep");
	    }
	}
    }
    if (count != globalTablePtr->numEntries) {
	panic("TclVerifyGlobalLiteralTable: global literal table had %d entries, should be %d",
	      count, globalTablePtr->numEntries);
    }
}
#endif /*TCL_COMPILE_DEBUG*/

Changes to generic/tclLoad.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
/* 
 * tclLoad.c --
 *
 *	This file provides the generic portion (those that are the same
 *	on all platforms) of Tcl's dynamic loading facilities.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclLoad.c 1.17 97/07/24 20:05:04
 */

#include "tclInt.h"

/*
 * The following structure describes a package that has been loaded
 * either dynamically (with the "load" command) or statically (as
 * indicated by a call to Tcl_PackageLoaded).  All such packages
 * are linked together into a single list for the process.  Packages
 * are never unloaded, so these structures are never freed.
 */

typedef struct LoadedPackage {
    char *fileName;		/* Name of the file from which the
				 * package was loaded.  An empty string
				 * means the package is loaded statically.
				 * Malloc-ed. */
    char *packageName;		/* Name of package prefix for the package,
				 * properly capitalized (first letter UC,
				 * others LC), no "_", as in "Net". 
				 * Malloc-ed. */




    Tcl_PackageInitProc *initProc;
				/* Initialization procedure to call to
				 * incorporate this package into a trusted
				 * interpreter. */
    Tcl_PackageInitProc *safeInitProc;
				/* Initialization procedure to call to
				 * incorporate this package into a safe
				 * interpreter (one that will execute
				 * untrusted scripts).   NULL means the
				 * package can't be used in unsafe
				 * interpreters. */
    struct LoadedPackage *nextPtr;
				/* Next in list of all packages loaded into
				 * this application process.  NULL means
				 * end of list. */
} LoadedPackage;







static LoadedPackage *firstPackagePtr = NULL;
				/* First in list of all packages loaded into
				 * this process. */



/*
 * The following structure represents a particular package that has
 * been incorporated into a particular interpreter (by calling its
 * initialization procedure).  There is a list of these structures for
 * each interpreter, with an AssocData value (key "load") for the
 * interpreter that points to the first package (if any).






|




|







|













>
>
>
>

















>
>
>
>
>
>



>
>







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
/* 
 * tclLoad.c --
 *
 *	This file provides the generic portion (those that are the same
 *	on all platforms) of Tcl's dynamic loading facilities.
 *
 * 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: tclLoad.c,v 1.1.2.6 1999/04/14 00:33:24 surles Exp $
 */

#include "tclInt.h"

/*
 * The following structure describes a package that has been loaded
 * either dynamically (with the "load" command) or statically (as
 * indicated by a call to TclGetLoadedPackages).  All such packages
 * are linked together into a single list for the process.  Packages
 * are never unloaded, so these structures are never freed.
 */

typedef struct LoadedPackage {
    char *fileName;		/* Name of the file from which the
				 * package was loaded.  An empty string
				 * means the package is loaded statically.
				 * Malloc-ed. */
    char *packageName;		/* Name of package prefix for the package,
				 * properly capitalized (first letter UC,
				 * others LC), no "_", as in "Net". 
				 * Malloc-ed. */
    ClientData clientData;	/* Token for the loaded file which should be
				 * passed to TclpUnloadFile() when the file
				 * is no longer needed.  If fileName is NULL,
				 * then this field is irrelevant. */
    Tcl_PackageInitProc *initProc;
				/* Initialization procedure to call to
				 * incorporate this package into a trusted
				 * interpreter. */
    Tcl_PackageInitProc *safeInitProc;
				/* Initialization procedure to call to
				 * incorporate this package into a safe
				 * interpreter (one that will execute
				 * untrusted scripts).   NULL means the
				 * package can't be used in unsafe
				 * interpreters. */
    struct LoadedPackage *nextPtr;
				/* Next in list of all packages loaded into
				 * this application process.  NULL means
				 * end of list. */
} LoadedPackage;

/*
 * TCL_THREADS
 * There is a global list of packages that is anchored at firstPackagePtr.
 * Access to this list is governed by a mutex.
 */

static LoadedPackage *firstPackagePtr = NULL;
				/* First in list of all packages loaded into
				 * this process. */

TCL_DECLARE_MUTEX(packageMutex)

/*
 * The following structure represents a particular package that has
 * been incorporated into a particular interpreter (by calling its
 * initialization procedure).  There is a list of these structures for
 * each interpreter, with an AssocData value (key "load") for the
 * interpreter that points to the first package (if any).
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

/*
 * Prototypes for procedures that are private to this file:
 */

static void		LoadCleanupProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp));
static void		LoadExitProc _ANSI_ARGS_((ClientData clientData));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_LoadCmd --
 *
 *	This procedure is invoked to process the "load" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_LoadCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    Tcl_Interp *target;
    LoadedPackage *pkgPtr, *defaultPtr;
    Tcl_DString pkgName, initName, safeInitName, fileName;
    Tcl_PackageInitProc *initProc, *safeInitProc;
    InterpPackage *ipFirstPtr, *ipPtr;
    int code, c, gotPkgName, namesMatch, filesMatch;
    char *p, *fullFileName, *p1, *p2;




    if ((argc < 2) || (argc > 4)) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" fileName ?packageName? ?interp?\"", (char *) NULL);
	return TCL_ERROR;
    }

    fullFileName = Tcl_TranslateFileName(interp, argv[1], &fileName);
    if (fullFileName == NULL) {
	return TCL_ERROR;
    }
    Tcl_DStringInit(&pkgName);
    Tcl_DStringInit(&initName);
    Tcl_DStringInit(&safeInitName);

    if ((argc >= 3) && (argv[2][0] != 0)) {
	gotPkgName = 1;
    } else {



	gotPkgName = 0;
    }

    if ((fullFileName[0] == 0) && !gotPkgName) {
	Tcl_SetResult(interp,
		"must specify either file name or package name",
		TCL_STATIC);
	code = TCL_ERROR;
	goto done;
    }

    /*
     * Figure out which interpreter we're going to load the package into.
     */

    target = interp;
    if (argc == 4) {


	target = Tcl_GetSlave(interp, argv[3]);
	if (target == NULL) {
	    Tcl_AppendResult(interp, "couldn't find slave interpreter named \"",
		    argv[3], "\"", (char *) NULL);
	    return TCL_ERROR;
	}
    }

    /*
     * Scan through the packages that are currently loaded to see if the
     * package we want is already loaded.  We'll use a loaded package if
     * it meets any of the following conditions:
     *  - Its name and file match the once we're looking for.
     *  - Its file matches, and we weren't given a name.
     *  - Its name matches, the file name was specified as empty, and there
     *    is only no statically loaded package with the same name.
     */


    defaultPtr = NULL;
    for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) {
	if (!gotPkgName) {
	    namesMatch = 0;
	} else {








	    namesMatch = 1;
	    for (p1 = argv[2], p2 = pkgPtr->packageName; ; p1++, p2++) {
		if ((isupper(UCHAR(*p1)) ? tolower(UCHAR(*p1)) : *p1)
			!= (isupper(UCHAR(*p2)) ? tolower(UCHAR(*p2)) : *p2)) {

		    namesMatch = 0;
		    break;
		}
		if (*p1 == 0) {
		    break;
		}

	    }
	}
	filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0);
	if (filesMatch && (namesMatch || !gotPkgName)) {
	    break;
	}
	if (namesMatch && (fullFileName[0] == 0)) {
	    defaultPtr = pkgPtr;
	}
	if (filesMatch && !namesMatch && (fullFileName[0] != 0)) {
	    /*
	     * Can't have two different packages loaded from the same
	     * file.
	     */

	    Tcl_AppendResult(interp, "file \"", fullFileName,
		    "\" is already loaded for package \"",
		    pkgPtr->packageName, "\"", (char *) NULL);
	    code = TCL_ERROR;

	    goto done;
	}
    }

    if (pkgPtr == NULL) {
	pkgPtr = defaultPtr;
    }

    /*
     * Scan through the list of packages already loaded in the target
     * interpreter.  If the package we want is already loaded there,







<




|














|
|
|
|
|



|


|
|
>
>
>

|
<
|


>
|






>
|
|
<
>
>
>
|
|
>
|












|
>
>
|

<
<













>



|


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

|















>



>







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

/*
 * Prototypes for procedures that are private to this file:
 */

static void		LoadCleanupProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp));


/*
 *----------------------------------------------------------------------
 *
 * Tcl_LoadObjCmd --
 *
 *	This procedure is invoked to process the "load" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_LoadObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Interp *target;
    LoadedPackage *pkgPtr, *defaultPtr;
    Tcl_DString pkgName, tmp, initName, safeInitName, fileName;
    Tcl_PackageInitProc *initProc, *safeInitProc;
    InterpPackage *ipFirstPtr, *ipPtr;
    int code, namesMatch, filesMatch;
    char *p, *tempString, *fullFileName, *packageName;
    ClientData clientData;
    Tcl_UniChar ch;
    int offset;

    if ((objc < 2) || (objc > 4)) {

        Tcl_WrongNumArgs(interp, 1, objv, "fileName ?packageName? ?interp?");
	return TCL_ERROR;
    }
    tempString = Tcl_GetString(objv[1]);
    fullFileName = Tcl_TranslateFileName(interp, tempString, &fileName);
    if (fullFileName == NULL) {
	return TCL_ERROR;
    }
    Tcl_DStringInit(&pkgName);
    Tcl_DStringInit(&initName);
    Tcl_DStringInit(&safeInitName);
    Tcl_DStringInit(&tmp);

    packageName = NULL;

    if (objc >= 3) {
	packageName = Tcl_GetString(objv[2]);
	if (packageName[0] == '\0') {
	    packageName = NULL;
	}
    }
    if ((fullFileName[0] == 0) && (packageName == NULL)) {
	Tcl_SetResult(interp,
		"must specify either file name or package name",
		TCL_STATIC);
	code = TCL_ERROR;
	goto done;
    }

    /*
     * Figure out which interpreter we're going to load the package into.
     */

    target = interp;
    if (objc == 4) {
	char *slaveIntName;
	slaveIntName = Tcl_GetString(objv[3]);
	target = Tcl_GetSlave(interp, slaveIntName);
	if (target == NULL) {


	    return TCL_ERROR;
	}
    }

    /*
     * Scan through the packages that are currently loaded to see if the
     * package we want is already loaded.  We'll use a loaded package if
     * it meets any of the following conditions:
     *  - Its name and file match the once we're looking for.
     *  - Its file matches, and we weren't given a name.
     *  - Its name matches, the file name was specified as empty, and there
     *    is only no statically loaded package with the same name.
     */
    Tcl_MutexLock(&packageMutex);

    defaultPtr = NULL;
    for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) {
	if (packageName == NULL) {
	    namesMatch = 0;
	} else {
	    Tcl_DStringSetLength(&pkgName, 0);
	    Tcl_DStringAppend(&pkgName, packageName, -1);
	    Tcl_DStringSetLength(&tmp, 0);
	    Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1);
	    Tcl_UtfToLower(Tcl_DStringValue(&pkgName));
	    Tcl_UtfToLower(Tcl_DStringValue(&tmp));
	    if (strcmp(Tcl_DStringValue(&tmp),
		    Tcl_DStringValue(&pkgName)) == 0) {
		namesMatch = 1;



	    } else {
		namesMatch = 0;

	    }


	}
	Tcl_DStringSetLength(&pkgName, 0);


	filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0);
	if (filesMatch && (namesMatch || (packageName == NULL))) {
	    break;
	}
	if (namesMatch && (fullFileName[0] == 0)) {
	    defaultPtr = pkgPtr;
	}
	if (filesMatch && !namesMatch && (fullFileName[0] != 0)) {
	    /*
	     * Can't have two different packages loaded from the same
	     * file.
	     */

	    Tcl_AppendResult(interp, "file \"", fullFileName,
		    "\" is already loaded for package \"",
		    pkgPtr->packageName, "\"", (char *) NULL);
	    code = TCL_ERROR;
	    Tcl_MutexUnlock(&packageMutex);
	    goto done;
	}
    }
    Tcl_MutexUnlock(&packageMutex);
    if (pkgPtr == NULL) {
	pkgPtr = defaultPtr;
    }

    /*
     * Scan through the list of packages already loaded in the target
     * interpreter.  If the package we want is already loaded there,
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237




238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257





258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276

277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

311
312


313
314
315
316
317
318

319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

337
338

339
340

341
342
343
344
345
346
347
    if (pkgPtr == NULL) {
	/*
	 * The desired file isn't currently loaded, so load it.  It's an
	 * error if the desired package is a static one.
	 */

	if (fullFileName[0] == 0) {
	    Tcl_AppendResult(interp, "package \"", argv[2],
		    "\" isn't loaded statically", (char *) NULL);
	    code = TCL_ERROR;
	    goto done;
	}

	/*
	 * Figure out the module name if it wasn't provided explicitly.
	 */

	if (gotPkgName) {
	    Tcl_DStringAppend(&pkgName, argv[2], -1);
	} else {




	    if (!TclGuessPackageName(fullFileName, &pkgName)) {

		int pargc;
		char **pargv, *pkgGuess;

		/*
		 * The platform-specific code couldn't figure out the
		 * module name.  Make a guess by taking the last element
		 * of the file name, stripping off any leading "lib",
		 * and then using all of the alphabetic and underline
		 * characters that follow that.
		 */

		Tcl_SplitPath(fullFileName, &pargc, &pargv);
		pkgGuess = pargv[pargc-1];
		if ((pkgGuess[0] == 'l') && (pkgGuess[1] == 'i')
			&& (pkgGuess[2] == 'b')) {
		    pkgGuess += 3;
		}
		for (p = pkgGuess; isalpha(UCHAR(*p)) || (*p == '_'); p++) {
		    /* Empty loop body. */





		}
		if (p == pkgGuess) {
		    ckfree((char *)pargv);
		    Tcl_AppendResult(interp,
			    "couldn't figure out package name for ",
			    fullFileName, (char *) NULL);
		    code = TCL_ERROR;
		    goto done;
		}
		Tcl_DStringAppend(&pkgName, pkgGuess, (p - pkgGuess));
		ckfree((char *)pargv);
	    }
	}

	/*
	 * Fix the capitalization in the package name so that the first
	 * character is in caps but the others are all lower-case.

	 */
    

	p = Tcl_DStringValue(&pkgName);
	c = UCHAR(*p);
	if (c != 0) {
	    if (islower(c)) {
		*p = (char) toupper(c);
	    }
	    p++;
	    while (1) {
		c = UCHAR(*p);
		if (c == 0) {
		    break;
		}
		if (isupper(c)) {
		    *p = (char) tolower(c);
		}
		p++;
	    }
	}

	/*
	 * Compute the names of the two initialization procedures,
	 * based on the package name.
	 */
    
	Tcl_DStringAppend(&initName, Tcl_DStringValue(&pkgName), -1);
	Tcl_DStringAppend(&initName, "_Init", 5);
	Tcl_DStringAppend(&safeInitName, Tcl_DStringValue(&pkgName), -1);
	Tcl_DStringAppend(&safeInitName, "_SafeInit", 9);
    
	/*
	 * Call platform-specific code to load the package and find the
	 * two initialization procedures.
	 */
    

	code = TclLoadFile(interp, fullFileName, Tcl_DStringValue(&initName),
		Tcl_DStringValue(&safeInitName), &initProc, &safeInitProc);


	if (code != TCL_OK) {
	    goto done;
	}
	if (initProc  == NULL) {
	    Tcl_AppendResult(interp, "couldn't find procedure ",
		    Tcl_DStringValue(&initName), (char *) NULL);

	    code = TCL_ERROR;
	    goto done;
	}

	/*
	 * Create a new record to describe this package.
	 */

	if (firstPackagePtr == NULL) {
	    Tcl_CreateExitHandler(LoadExitProc, (ClientData) NULL);
	}
	pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
	pkgPtr->fileName = (char *) ckalloc((unsigned)
		(strlen(fullFileName) + 1));
	strcpy(pkgPtr->fileName, fullFileName);
	pkgPtr->packageName = (char *) ckalloc((unsigned)
		(Tcl_DStringLength(&pkgName) + 1));
	strcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName));

	pkgPtr->initProc = initProc;
	pkgPtr->safeInitProc = safeInitProc;

	pkgPtr->nextPtr = firstPackagePtr;
	firstPackagePtr = pkgPtr;

    }

    /*
     * Invoke the package's initialization procedure (either the
     * normal one or the safe one, depending on whether or not the
     * interpreter is safe).
     */







|









|
|

>
>
>
>
|
>

















|
|
>
>
>
>
>
















|
>


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










|




|
>
|
|
>
>



|


>








<
<
<

|


|


>
|
|
>
|
|
>







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

















314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
    if (pkgPtr == NULL) {
	/*
	 * The desired file isn't currently loaded, so load it.  It's an
	 * error if the desired package is a static one.
	 */

	if (fullFileName[0] == 0) {
	    Tcl_AppendResult(interp, "package \"", packageName,
		    "\" isn't loaded statically", (char *) NULL);
	    code = TCL_ERROR;
	    goto done;
	}

	/*
	 * Figure out the module name if it wasn't provided explicitly.
	 */

	if (packageName != NULL) {
	    Tcl_DStringAppend(&pkgName, packageName, -1);
	} else {
	    int retc;
	    /*
	     * Threading note - this call used to be protected by a mutex.
	     */
	    retc = TclGuessPackageName(fullFileName, &pkgName);
	    if (!retc) {
		int pargc;
		char **pargv, *pkgGuess;

		/*
		 * The platform-specific code couldn't figure out the
		 * module name.  Make a guess by taking the last element
		 * of the file name, stripping off any leading "lib",
		 * and then using all of the alphabetic and underline
		 * characters that follow that.
		 */

		Tcl_SplitPath(fullFileName, &pargc, &pargv);
		pkgGuess = pargv[pargc-1];
		if ((pkgGuess[0] == 'l') && (pkgGuess[1] == 'i')
			&& (pkgGuess[2] == 'b')) {
		    pkgGuess += 3;
		}
		for (p = pkgGuess; *p != 0; p += offset) {
		    offset = Tcl_UtfToUniChar(p, &ch);
		    if ((ch > 0x100)
			    || !(isalpha(UCHAR(ch)) /* INTL: ISO only */
				    || (UCHAR(ch) == '_'))) {
			break;
		    }
		}
		if (p == pkgGuess) {
		    ckfree((char *)pargv);
		    Tcl_AppendResult(interp,
			    "couldn't figure out package name for ",
			    fullFileName, (char *) NULL);
		    code = TCL_ERROR;
		    goto done;
		}
		Tcl_DStringAppend(&pkgName, pkgGuess, (p - pkgGuess));
		ckfree((char *)pargv);
	    }
	}

	/*
	 * Fix the capitalization in the package name so that the first
	 * character is in caps (or title case) but the others are all
	 * lower-case.
	 */
    
	Tcl_DStringSetLength(&pkgName,
		Tcl_UtfToTitle(Tcl_DStringValue(&pkgName)));


















	/*
	 * Compute the names of the two initialization procedures,
	 * based on the package name.
	 */
    
	Tcl_DStringAppend(&initName, Tcl_DStringValue(&pkgName), -1);
	Tcl_DStringAppend(&initName, "_Init", 5);
	Tcl_DStringAppend(&safeInitName, Tcl_DStringValue(&pkgName), -1);
	Tcl_DStringAppend(&safeInitName, "_SafeInit", 9);

	/*
	 * Call platform-specific code to load the package and find the
	 * two initialization procedures.
	 */

	Tcl_MutexLock(&packageMutex);
	code = TclpLoadFile(interp, fullFileName, Tcl_DStringValue(&initName),
		Tcl_DStringValue(&safeInitName), &initProc, &safeInitProc,
		&clientData);
	Tcl_MutexUnlock(&packageMutex);
	if (code != TCL_OK) {
	    goto done;
	}
	if (initProc == NULL) {
	    Tcl_AppendResult(interp, "couldn't find procedure ",
		    Tcl_DStringValue(&initName), (char *) NULL);
	    TclpUnloadFile(clientData);
	    code = TCL_ERROR;
	    goto done;
	}

	/*
	 * Create a new record to describe this package.
	 */




	pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
	pkgPtr->fileName	= (char *) ckalloc((unsigned)
		(strlen(fullFileName) + 1));
	strcpy(pkgPtr->fileName, fullFileName);
	pkgPtr->packageName	= (char *) ckalloc((unsigned)
		(Tcl_DStringLength(&pkgName) + 1));
	strcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName));
	pkgPtr->clientData	= clientData;
	pkgPtr->initProc	= initProc;
	pkgPtr->safeInitProc	= safeInitProc;
	Tcl_MutexLock(&packageMutex);
	pkgPtr->nextPtr		= firstPackagePtr;
	firstPackagePtr		= pkgPtr;
	Tcl_MutexUnlock(&packageMutex);
    }

    /*
     * Invoke the package's initialization procedure (either the
     * normal one or the safe one, depending on whether or not the
     * interpreter is safe).
     */
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
		    (char *) NULL);
	    code = TCL_ERROR;
	    goto done;
	}
    } else {
	code = (*pkgPtr->initProc)(target);
    }
    if ((code == TCL_ERROR) && (target != interp)) {
	/*
	 * An error occurred, so transfer error information from the
	 * destination interpreter back to our interpreter.  Must clear
	 * interp's result before calling Tcl_AddErrorInfo, since
	 * Tcl_AddErrorInfo will store the interp's result in errorInfo
	 * before appending target's $errorInfo;  we've already got
	 * everything we need in target's $errorInfo.
	 */

	/*
         * It is (abusively) assumed that errorInfo and errorCode vars exists.
         * we changed SetVar2 to accept NULL values to avoid crashes. --dl
	 */
	Tcl_ResetResult(interp);
	Tcl_AddErrorInfo(interp, Tcl_GetVar2(target,
		"errorInfo", (char *) NULL, TCL_GLOBAL_ONLY));
	Tcl_SetVar2(interp, "errorCode", (char *) NULL,
		Tcl_GetVar2(target, "errorCode", (char *) NULL,
		TCL_GLOBAL_ONLY), TCL_GLOBAL_ONLY);
	Tcl_SetResult(interp, target->result, TCL_VOLATILE);
    }

    /*
     * Record the fact that the package has been loaded in the
     * target interpreter.
     */

    if (code == TCL_OK) {
	/*
	 * Refetch ipFirstPtr: loading the package may have introduced
	 * additional static packages at the head of the linked list!
	 */

	ipFirstPtr = (InterpPackage *) Tcl_GetAssocData(target, "tclLoad",
		(Tcl_InterpDeleteProc **) NULL);
	ipPtr = (InterpPackage *) ckalloc(sizeof(InterpPackage));
	ipPtr->pkgPtr = pkgPtr;
	ipPtr->nextPtr = ipFirstPtr;
	Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc,
		(ClientData) ipPtr);


    }

    done:
    Tcl_DStringFree(&pkgName);
    Tcl_DStringFree(&initName);
    Tcl_DStringFree(&safeInitName);
    Tcl_DStringFree(&fileName);

    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_StaticPackage --







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



















>
>







>







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
		    (char *) NULL);
	    code = TCL_ERROR;
	    goto done;
	}
    } else {
	code = (*pkgPtr->initProc)(target);
    }























    /*
     * Record the fact that the package has been loaded in the
     * target interpreter.
     */

    if (code == TCL_OK) {
	/*
	 * Refetch ipFirstPtr: loading the package may have introduced
	 * additional static packages at the head of the linked list!
	 */

	ipFirstPtr = (InterpPackage *) Tcl_GetAssocData(target, "tclLoad",
		(Tcl_InterpDeleteProc **) NULL);
	ipPtr = (InterpPackage *) ckalloc(sizeof(InterpPackage));
	ipPtr->pkgPtr = pkgPtr;
	ipPtr->nextPtr = ipFirstPtr;
	Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc,
		(ClientData) ipPtr);
    } else {
	TclTransferResult(target, code, interp);
    }

    done:
    Tcl_DStringFree(&pkgName);
    Tcl_DStringFree(&initName);
    Tcl_DStringFree(&safeInitName);
    Tcl_DStringFree(&fileName);
    Tcl_DStringFree(&tmp);
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_StaticPackage --
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
    InterpPackage *ipPtr, *ipFirstPtr;

    /*
     * Check to see if someone else has already reported this package as
     * statically loaded.  If this call is redundant then just return.
     */


    for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) {
	if ((pkgPtr->initProc == initProc)
		&& (pkgPtr->safeInitProc == safeInitProc)
		&& (strcmp(pkgPtr->packageName, pkgName) == 0)) {

	    return;
	}
    }

    if (firstPackagePtr == NULL) {
	Tcl_CreateExitHandler(LoadExitProc, (ClientData) NULL);
    }
    pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
    pkgPtr->fileName = (char *) ckalloc((unsigned) 1);
    pkgPtr->fileName[0] = 0;
    pkgPtr->packageName = (char *) ckalloc((unsigned)
	    (strlen(pkgName) + 1));
    strcpy(pkgPtr->packageName, pkgName);

    pkgPtr->initProc = initProc;
    pkgPtr->safeInitProc = safeInitProc;

    pkgPtr->nextPtr = firstPackagePtr;
    firstPackagePtr = pkgPtr;


    if (interp != NULL) {
	ipFirstPtr = (InterpPackage *) Tcl_GetAssocData(interp, "tclLoad",
		(Tcl_InterpDeleteProc **) NULL);
	ipPtr = (InterpPackage *) ckalloc(sizeof(InterpPackage));
	ipPtr->pkgPtr = pkgPtr;
	ipPtr->nextPtr = ipFirstPtr;







>




>




|
<
|

|
|
|


>
|
|
>
|
|
>







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
    InterpPackage *ipPtr, *ipFirstPtr;

    /*
     * Check to see if someone else has already reported this package as
     * statically loaded.  If this call is redundant then just return.
     */

    Tcl_MutexLock(&packageMutex);
    for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) {
	if ((pkgPtr->initProc == initProc)
		&& (pkgPtr->safeInitProc == safeInitProc)
		&& (strcmp(pkgPtr->packageName, pkgName) == 0)) {
	    Tcl_MutexUnlock(&packageMutex);
	    return;
	}
    }

    Tcl_MutexUnlock(&packageMutex);


    pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
    pkgPtr->fileName		= (char *) ckalloc((unsigned) 1);
    pkgPtr->fileName[0]		= 0;
    pkgPtr->packageName		= (char *) ckalloc((unsigned)
	    (strlen(pkgName) + 1));
    strcpy(pkgPtr->packageName, pkgName);
    pkgPtr->clientData		= NULL;
    pkgPtr->initProc		= initProc;
    pkgPtr->safeInitProc	= safeInitProc;
    Tcl_MutexLock(&packageMutex);
    pkgPtr->nextPtr		= firstPackagePtr;
    firstPackagePtr		= pkgPtr;
    Tcl_MutexUnlock(&packageMutex);

    if (interp != NULL) {
	ipFirstPtr = (InterpPackage *) Tcl_GetAssocData(interp, "tclLoad",
		(Tcl_InterpDeleteProc **) NULL);
	ipPtr = (InterpPackage *) ckalloc(sizeof(InterpPackage));
	ipPtr->pkgPtr = pkgPtr;
	ipPtr->nextPtr = ipFirstPtr;
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
 *
 *	This procedure returns information about all of the files
 *	that are loaded (either in a particular intepreter, or
 *	for all interpreters).
 *
 * Results:
 *	The return value is a standard Tcl completion code.  If
 *	successful, a list of lists is placed in interp->result.
 *	Each sublist corresponds to one loaded file;  its first
 *	element is the name of the file (or an empty string for
 *	something that's statically loaded) and the second element
 *	is the name of the package in that file.
 *
 * Side effects:
 *	None.







|







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
 *
 *	This procedure returns information about all of the files
 *	that are loaded (either in a particular intepreter, or
 *	for all interpreters).
 *
 * Results:
 *	The return value is a standard Tcl completion code.  If
 *	successful, a list of lists is placed in the interp's result.
 *	Each sublist corresponds to one loaded file;  its first
 *	element is the name of the file (or an empty string for
 *	something that's statically loaded) and the second element
 *	is the name of the package in that file.
 *
 * Side effects:
 *	None.
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

    if (targetName == NULL) {
	/* 
	 * Return information about all of the available packages.
	 */

	prefix = "{";

	for (pkgPtr = firstPackagePtr; pkgPtr != NULL;
		pkgPtr = pkgPtr->nextPtr) {
	    Tcl_AppendResult(interp, prefix, (char *) NULL);
	    Tcl_AppendElement(interp, pkgPtr->fileName);
	    Tcl_AppendElement(interp, pkgPtr->packageName);
	    Tcl_AppendResult(interp, "}", (char *) NULL);
	    prefix = " {";
	}

	return TCL_OK;
    }

    /*
     * Return information about only the packages that are loaded in
     * a given interpreter.
     */

    target = Tcl_GetSlave(interp, targetName);
    if (target == NULL) {
	Tcl_AppendResult(interp, "couldn't find slave interpreter named \"",
		targetName, "\"", (char *) NULL);
	return TCL_ERROR;
    }
    ipPtr = (InterpPackage *) Tcl_GetAssocData(target, "tclLoad",
	    (Tcl_InterpDeleteProc **) NULL);
    prefix = "{";
    for ( ; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
	pkgPtr = ipPtr->pkgPtr;







>








>










<
<







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

    if (targetName == NULL) {
	/* 
	 * Return information about all of the available packages.
	 */

	prefix = "{";
	Tcl_MutexLock(&packageMutex);
	for (pkgPtr = firstPackagePtr; pkgPtr != NULL;
		pkgPtr = pkgPtr->nextPtr) {
	    Tcl_AppendResult(interp, prefix, (char *) NULL);
	    Tcl_AppendElement(interp, pkgPtr->fileName);
	    Tcl_AppendElement(interp, pkgPtr->packageName);
	    Tcl_AppendResult(interp, "}", (char *) NULL);
	    prefix = " {";
	}
	Tcl_MutexUnlock(&packageMutex);
	return TCL_OK;
    }

    /*
     * Return information about only the packages that are loaded in
     * a given interpreter.
     */

    target = Tcl_GetSlave(interp, targetName);
    if (target == NULL) {


	return TCL_ERROR;
    }
    ipPtr = (InterpPackage *) Tcl_GetAssocData(target, "tclLoad",
	    (Tcl_InterpDeleteProc **) NULL);
    prefix = "{";
    for ( ; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
	pkgPtr = ipPtr->pkgPtr;
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
	ipPtr = nextPtr;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * LoadExitProc --
 *
 *	This procedure is invoked just before the application exits.
 *	It frees all of the LoadedPackage structures.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is freed.
 *
 *----------------------------------------------------------------------
 */

static void
LoadExitProc(clientData)
    ClientData clientData;		/* Not used. */
{
    LoadedPackage *pkgPtr;










    while (firstPackagePtr != NULL) {
	pkgPtr = firstPackagePtr;
	firstPackagePtr = pkgPtr->nextPtr;



	ckfree(pkgPtr->fileName);
	ckfree(pkgPtr->packageName);
	ckfree((char *) pkgPtr);
    }
}







|













|
|
<



>
>
>
>
>
>
>
>
>



>
>
>





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
	ipPtr = nextPtr;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeLoad --
 *
 *	This procedure is invoked just before the application exits.
 *	It frees all of the LoadedPackage structures.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is freed.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeLoad()

{
    LoadedPackage *pkgPtr;

    /*
     * No synchronization here because there should just be
     * one thread alive at this point.  Logically, 
     * packageMutex should be grabbed at this point, but
     * the Mutexes get finalized before the call to this routine.
     * The only subsystem left alive at this point is the
     * memory allocator.
     */

    while (firstPackagePtr != NULL) {
	pkgPtr = firstPackagePtr;
	firstPackagePtr = pkgPtr->nextPtr;
	if (pkgPtr->fileName[0] != '\0') {
	    TclpUnloadFile(pkgPtr->clientData);
	}
	ckfree(pkgPtr->fileName);
	ckfree(pkgPtr->packageName);
	ckfree((char *) pkgPtr);
    }
}

Changes to generic/tclLoadNone.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
/* 
 * tclLoadNone.c --
 *
 *	This procedure provides a version of the TclLoadFile for use
 *	in systems that don't support dynamic loading; it just returns
 *	an error.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclLoadNone.c 1.6 97/05/14 13:23:38
 */

#include "tclInt.h"

/*
 *----------------------------------------------------------------------
 *
 * TclLoadFile --
 *
 *	This procedure is called to carry out dynamic loading of binary
 *	code;  it is intended for use only on systems that don't support
 *	dynamic loading (it returns an error).
 *
 * Results:
 *	The result is TCL_ERROR, and an error message is left in
 *	interp->result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */








|




|















|







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
/* 
 * tclLoadNone.c --
 *
 *	This procedure provides a version of the TclLoadFile for use
 *	in systems that don't support dynamic loading; it just returns
 *	an error.
 *
 * 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: tclLoadNone.c,v 1.1.2.2 1998/09/24 23:58:56 stanton Exp $
 */

#include "tclInt.h"

/*
 *----------------------------------------------------------------------
 *
 * TclLoadFile --
 *
 *	This procedure is called to carry out dynamic loading of binary
 *	code;  it is intended for use only on systems that don't support
 *	dynamic loading (it returns an error).
 *
 * Results:
 *	The result is TCL_ERROR, and an error message is left in
 *	the interp's result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Changes to generic/tclMain.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
/* 
 * tclMain.c --
 *
 *	Main program for Tcl shells and other Tcl-based applications.
 *
 * Copyright (c) 1988-1994 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMain.c 1.54 97/08/07 19:04:43
 */

#include "tcl.h"
#include "tclInt.h"




/*
 * The following code ensures that tclLink.c is linked whenever
 * Tcl is linked.  Without this code there's no reference to the
 * code in that file from anywhere in Tcl, so it may not be
 * linked into the application.
 */







|




|





>
>
>







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
/* 
 * tclMain.c --
 *
 *	Main program for Tcl shells and other Tcl-based applications.
 *
 * Copyright (c) 1988-1994 The Regents of the University of California.
 * 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: tclMain.c,v 1.1.2.4 1999/02/10 23:31:17 stanton Exp $
 */

#include "tcl.h"
#include "tclInt.h"

# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT

/*
 * The following code ensures that tclLink.c is linked whenever
 * Tcl is linked.  Without this code there's no reference to the
 * code in that file from anywhere in Tcl, so it may not be
 * linked into the application.
 */

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
 * declare it without causing conflicts with other definitions elsewher
 * on some systems, so it's better just to leave it out.
 */

extern int		isatty _ANSI_ARGS_((int fd));
extern char *		strcpy _ANSI_ARGS_((char *dst, CONST char *src));

static Tcl_Interp *interp;	/* Interpreter for application. */

#ifdef TCL_MEM_DEBUG
static char dumpFile[100];	/* Records where to dump memory allocation
				 * information. */
static int quitFlag = 0;	/* 1 means "checkmem" command was called,
				 * so the application should quit and dump
				 * memory allocation information. */
#endif

/*
 * Forward references for procedures defined later in this file:
 */

#ifdef TCL_MEM_DEBUG
static int		CheckmemCmd _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int argc, char *argv[]));
#endif

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Main --
 *
 *	Main program for tclsh and most other Tcl-based applications.







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







36
37
38
39
40
41
42


















43
44
45
46
47
48
49
 * declare it without causing conflicts with other definitions elsewher
 * on some systems, so it's better just to leave it out.
 */

extern int		isatty _ANSI_ARGS_((int fd));
extern char *		strcpy _ANSI_ARGS_((char *dst, CONST char *src));




















/*
 *----------------------------------------------------------------------
 *
 * Tcl_Main --
 *
 *	Main program for tclsh and most other Tcl-based applications.
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
    char **argv;		/* Array of argument strings. */
    Tcl_AppInitProc *appInitProc;
				/* Application-specific initialization
				 * procedure to call after most
				 * initialization but before starting to
				 * execute commands. */
{
    Tcl_Obj *prompt1NamePtr = NULL;
    Tcl_Obj *prompt2NamePtr = NULL;
    Tcl_Obj *resultPtr;
    Tcl_Obj *commandPtr = NULL;
    char buffer[1000], *args, *fileName, *bytes;
    int code, gotPartial, tty, length;
    int exitCode = 0;
    Tcl_Channel inChannel, outChannel, errChannel;



    Tcl_FindExecutable(argv[0]);
    interp = Tcl_CreateInterp();
#ifdef TCL_MEM_DEBUG
    Tcl_InitMemory(interp);
    Tcl_CreateCommand(interp, "checkmem", CheckmemCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
#endif

    /*
     * Make command-line arguments available in the Tcl variables "argc"
     * and "argv".  If the first argument doesn't start with a "-" then
     * strip it off and use it as the name of a script file to process.
     */

    fileName = NULL;
    if ((argc > 1) && (argv[1][0] != '-')) {
	fileName = argv[1];
	argc--;
	argv++;
    }
    args = Tcl_Merge(argc-1, argv+1);

    Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY);

    ckfree(args);







    TclFormatInt(buffer, argc-1);
    Tcl_SetVar(interp, "argc", buffer, TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp, "argv0", (fileName != NULL) ? fileName : argv[0],
	    TCL_GLOBAL_ONLY);

    /*
     * Set the "tcl_interactive" variable.
     */

    tty = isatty(0);
    Tcl_SetVar(interp, "tcl_interactive",
	    ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY);
    
    /*
     * Invoke application-specific initialization.
     */

    if ((*appInitProc)(interp) != TCL_OK) {
	errChannel = Tcl_GetStdChannel(TCL_STDERR);
	if (errChannel) {
	    Tcl_Write(errChannel,
		    "application-specific initialization failed: ", -1);
	    Tcl_Write(errChannel, interp->result, -1);
	    Tcl_Write(errChannel, "\n", 1);
	}
    }

    /*
     * If a script file was specified then just source that file
     * and quit.
     */

    if (fileName != NULL) {
	code = Tcl_EvalFile(interp, fileName);
	if (code != TCL_OK) {
	    errChannel = Tcl_GetStdChannel(TCL_STDERR);
	    if (errChannel) {
		/*
		 * The following statement guarantees that the errorInfo
		 * variable is set properly.
		 */

		Tcl_AddErrorInfo(interp, "");
		Tcl_Write(errChannel,
			Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY), -1);
		Tcl_Write(errChannel, "\n", 1);
	    }
	    exitCode = 1;
	}
	goto done;
    }


    /*
     * We're running interactively.  Source a user-specific startup
     * file if the application specified one and if the file exists.
     */

    Tcl_SourceRCFile(interp);

    /*
     * Process commands from stdin until there's an end-of-file.  Note
     * that we need to fetch the standard channels again after every
     * eval, since they may have been changed.
     */

    commandPtr = Tcl_NewObj();
    Tcl_IncrRefCount(commandPtr);
    prompt1NamePtr = Tcl_NewStringObj("tcl_prompt1", -1);
    Tcl_IncrRefCount(prompt1NamePtr);
    prompt2NamePtr = Tcl_NewStringObj("tcl_prompt2", -1);
    Tcl_IncrRefCount(prompt2NamePtr);
    
    inChannel = Tcl_GetStdChannel(TCL_STDIN);
    outChannel = Tcl_GetStdChannel(TCL_STDOUT);
    gotPartial = 0;
    while (1) {
	if (tty) {
	    Tcl_Obj *promptCmdPtr;

	    promptCmdPtr = Tcl_ObjGetVar2(interp,
		    (gotPartial? prompt2NamePtr : prompt1NamePtr),
		    (Tcl_Obj *) NULL, TCL_GLOBAL_ONLY);
	    if (promptCmdPtr == NULL) {
                defaultPrompt:
		if (!gotPartial && outChannel) {
		    Tcl_Write(outChannel, "% ", 2);
		}
	    } else {
		code = Tcl_EvalObj(interp, promptCmdPtr);
		inChannel = Tcl_GetStdChannel(TCL_STDIN);
		outChannel = Tcl_GetStdChannel(TCL_STDOUT);
		errChannel = Tcl_GetStdChannel(TCL_STDERR);
		if (code != TCL_OK) {
		    if (errChannel) {
			resultPtr = Tcl_GetObjResult(interp);
			bytes = Tcl_GetStringFromObj(resultPtr, &length);
			Tcl_Write(errChannel, bytes, length);
			Tcl_Write(errChannel, "\n", 1);
		    }
		    Tcl_AddErrorInfo(interp,
			    "\n    (script that generates prompt)");
		    goto defaultPrompt;
		}
	    }
	    if (outChannel) {







<
<


|



>
>





<
<















>
|
>

>
>
>
>
>
>
>


|
<
















|

|
|



















|
|
|





>
















<
<
<
<
|







|
|
|



|


|





|
<
<
|







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
    char **argv;		/* Array of argument strings. */
    Tcl_AppInitProc *appInitProc;
				/* Application-specific initialization
				 * procedure to call after most
				 * initialization but before starting to
				 * execute commands. */
{


    Tcl_Obj *resultPtr;
    Tcl_Obj *commandPtr = NULL;
    char buffer[1000], *args, *fileName;
    int code, gotPartial, tty, length;
    int exitCode = 0;
    Tcl_Channel inChannel, outChannel, errChannel;
    Tcl_Interp *interp;
    Tcl_DString argString;

    Tcl_FindExecutable(argv[0]);
    interp = Tcl_CreateInterp();
#ifdef TCL_MEM_DEBUG
    Tcl_InitMemory(interp);


#endif

    /*
     * Make command-line arguments available in the Tcl variables "argc"
     * and "argv".  If the first argument doesn't start with a "-" then
     * strip it off and use it as the name of a script file to process.
     */

    fileName = NULL;
    if ((argc > 1) && (argv[1][0] != '-')) {
	fileName = argv[1];
	argc--;
	argv++;
    }
    args = Tcl_Merge(argc-1, argv+1);
    Tcl_ExternalToUtfDString(NULL, args, -1, &argString);
    Tcl_SetVar(interp, "argv", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY);
    Tcl_DStringFree(&argString);
    ckfree(args);

    if (fileName == NULL) {
	Tcl_ExternalToUtfDString(NULL, argv[0], -1, &argString);
    } else {
	fileName = Tcl_ExternalToUtfDString(NULL, fileName, -1, &argString);
    }

    TclFormatInt(buffer, argc-1);
    Tcl_SetVar(interp, "argc", buffer, TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp, "argv0", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY);


    /*
     * Set the "tcl_interactive" variable.
     */

    tty = isatty(0);
    Tcl_SetVar(interp, "tcl_interactive",
	    ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY);
    
    /*
     * Invoke application-specific initialization.
     */

    if ((*appInitProc)(interp) != TCL_OK) {
	errChannel = Tcl_GetStdChannel(TCL_STDERR);
	if (errChannel) {
	    Tcl_WriteChars(errChannel,
		    "application-specific initialization failed: ", -1);
	    Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
	    Tcl_WriteChars(errChannel, "\n", 1);
	}
    }

    /*
     * If a script file was specified then just source that file
     * and quit.
     */

    if (fileName != NULL) {
	code = Tcl_EvalFile(interp, fileName);
	if (code != TCL_OK) {
	    errChannel = Tcl_GetStdChannel(TCL_STDERR);
	    if (errChannel) {
		/*
		 * The following statement guarantees that the errorInfo
		 * variable is set properly.
		 */

		Tcl_AddErrorInfo(interp, "");
		Tcl_WriteObj(errChannel, Tcl_GetVar2Ex(interp, "errorInfo",
			NULL, TCL_GLOBAL_ONLY));
		Tcl_WriteChars(errChannel, "\n", 1);
	    }
	    exitCode = 1;
	}
	goto done;
    }
    Tcl_DStringFree(&argString);

    /*
     * We're running interactively.  Source a user-specific startup
     * file if the application specified one and if the file exists.
     */

    Tcl_SourceRCFile(interp);

    /*
     * Process commands from stdin until there's an end-of-file.  Note
     * that we need to fetch the standard channels again after every
     * eval, since they may have been changed.
     */

    commandPtr = Tcl_NewObj();
    Tcl_IncrRefCount(commandPtr);





    inChannel = Tcl_GetStdChannel(TCL_STDIN);
    outChannel = Tcl_GetStdChannel(TCL_STDOUT);
    gotPartial = 0;
    while (1) {
	if (tty) {
	    Tcl_Obj *promptCmdPtr;

	    promptCmdPtr = Tcl_GetVar2Ex(interp,
		    (gotPartial ? "tcl_prompt2" : "tcl_prompt1"),
		    NULL, TCL_GLOBAL_ONLY);
	    if (promptCmdPtr == NULL) {
                defaultPrompt:
		if (!gotPartial && outChannel) {
		    Tcl_WriteChars(outChannel, "% ", 2);
		}
	    } else {
		code = Tcl_EvalObjEx(interp, promptCmdPtr, 0);
		inChannel = Tcl_GetStdChannel(TCL_STDIN);
		outChannel = Tcl_GetStdChannel(TCL_STDOUT);
		errChannel = Tcl_GetStdChannel(TCL_STDERR);
		if (code != TCL_OK) {
		    if (errChannel) {
			Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));


			Tcl_WriteChars(errChannel, "\n", 1);
		    }
		    Tcl_AddErrorInfo(interp,
			    "\n    (script that generates prompt)");
		    goto defaultPrompt;
		}
	    }
	    if (outChannel) {
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
	code = Tcl_RecordAndEvalObj(interp, commandPtr, 0);
	inChannel = Tcl_GetStdChannel(TCL_STDIN);
	outChannel = Tcl_GetStdChannel(TCL_STDOUT);
	errChannel = Tcl_GetStdChannel(TCL_STDERR);
	Tcl_SetObjLength(commandPtr, 0);
	if (code != TCL_OK) {
	    if (errChannel) {
		resultPtr = Tcl_GetObjResult(interp);
		bytes = Tcl_GetStringFromObj(resultPtr, &length);
		Tcl_Write(errChannel, bytes, length);
		Tcl_Write(errChannel, "\n", 1);
	    }
	} else if (tty) {
	    resultPtr = Tcl_GetObjResult(interp);
	    bytes = Tcl_GetStringFromObj(resultPtr, &length);
	    if ((length > 0) && outChannel) {
		Tcl_Write(outChannel, bytes, length);
		Tcl_Write(outChannel, "\n", 1);
	    }
	}
#ifdef TCL_MEM_DEBUG
	if (quitFlag) {
	    Tcl_DecrRefCount(commandPtr);
	    Tcl_DecrRefCount(prompt1NamePtr);
	    Tcl_DecrRefCount(prompt2NamePtr);
	    Tcl_DeleteInterp(interp);
	    Tcl_Exit(0);
	}
#endif
    }

    /*
     * Rather than calling exit, invoke the "exit" command so that
     * users can replace "exit" with some other command to do additional
     * cleanup on exit.  The Tcl_Eval call should never return.
     */

    done:
    if (commandPtr != NULL) {
	Tcl_DecrRefCount(commandPtr);
    }
    if (prompt1NamePtr != NULL) {
	Tcl_DecrRefCount(prompt1NamePtr);
    }
    if (prompt2NamePtr != NULL) {
	Tcl_DecrRefCount(prompt2NamePtr);
    }
    sprintf(buffer, "exit %d", exitCode);
    Tcl_Eval(interp, buffer);
}

/*
 *----------------------------------------------------------------------
 *
 * CheckmemCmd --
 *
 *	This is the command procedure for the "checkmem" command, which
 *	causes the application to exit after printing information about
 *	memory usage to the file passed to this command as its first
 *	argument.
 *
 * Results:
 *	Returns a standard Tcl completion code.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
#ifdef TCL_MEM_DEBUG

	/* ARGSUSED */
static int
CheckmemCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Interpreter for evaluation. */
    int argc;				/* Number of arguments. */
    char *argv[];			/* String values of arguments. */
{
    extern char *tclMemDumpFileName;
    if (argc != 2) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" fileName\"", (char *) NULL);
	return TCL_ERROR;
    }
    strcpy(dumpFile, argv[1]);
    tclMemDumpFileName = dumpFile;
    quitFlag = 1;
    return TCL_OK;
}
#endif







|
<
<
|



|

|
|



|

<
<
















<
<
<
<
<
<



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









































	code = Tcl_RecordAndEvalObj(interp, commandPtr, 0);
	inChannel = Tcl_GetStdChannel(TCL_STDIN);
	outChannel = Tcl_GetStdChannel(TCL_STDOUT);
	errChannel = Tcl_GetStdChannel(TCL_STDERR);
	Tcl_SetObjLength(commandPtr, 0);
	if (code != TCL_OK) {
	    if (errChannel) {
		Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));


		Tcl_WriteChars(errChannel, "\n", 1);
	    }
	} else if (tty) {
	    resultPtr = Tcl_GetObjResult(interp);
	    Tcl_GetStringFromObj(resultPtr, &length);
	    if ((length > 0) && outChannel) {
		Tcl_WriteObj(outChannel, resultPtr);
		Tcl_WriteChars(outChannel, "\n", 1);
	    }
	}
#ifdef TCL_MEM_DEBUG
	if (tclMemDumpFileName != NULL) {
	    Tcl_DecrRefCount(commandPtr);


	    Tcl_DeleteInterp(interp);
	    Tcl_Exit(0);
	}
#endif
    }

    /*
     * Rather than calling exit, invoke the "exit" command so that
     * users can replace "exit" with some other command to do additional
     * cleanup on exit.  The Tcl_Eval call should never return.
     */

    done:
    if (commandPtr != NULL) {
	Tcl_DecrRefCount(commandPtr);
    }






    sprintf(buffer, "exit %d", exitCode);
    Tcl_Eval(interp, buffer);
}









































Changes to generic/tclMath.h.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *	are passed around and used, they will crash hard on the 68K.
 *
 * 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.
 *
 * SCCS: @(#) tclMath.h 1.2 97/07/23 17:39:14
 */

#ifndef _TCLMATH
#define _TCLMATH

#if defined(MAC_TCL)
#   include "tclMacMath.h"







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *	are passed around and used, they will crash hard on the 68K.
 *
 * 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: tclMath.h,v 1.1.2.1 1998/09/24 23:58:57 stanton Exp $
 */

#ifndef _TCLMATH
#define _TCLMATH

#if defined(MAC_TCL)
#   include "tclMacMath.h"

Changes to generic/tclNamesp.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
/*
 * tclNamesp.c --
 *
 *      Contains support for namespaces, which provide a separate context of
 *      commands and global variables. The global :: namespace is the
 *      traditional Tcl "global" scope. Other namespaces are created as
 *      children of the global namespace. These other namespaces contain
 *      special-purpose commands and variables for packages.
 *
 * Copyright (c) 1993-1997 Lucent Technologies.
 * Copyright (c) 1997 Sun Microsystems, Inc.

 *
 * Originally implemented by
 *   Michael J. McLennan
 *   Bell Labs Innovations for Lucent Technologies
 *   [email protected]
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclNamesp.c 1.29 97/08/04 09:32:38
 */

#include "tclInt.h"

/*
 * Flag passed to TclGetNamespaceForQualName to indicate that it should
 * search for a namespace rather than a command or variable inside a
 * namespace. Note that this flag's value must not conflict with the values
 * of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, or CREATE_NS_IF_UNKNOWN.
 */

#define FIND_ONLY_NS	0x1000








/*
 * Count of the number of namespaces created. This value is used as a
 * unique id for each namespace.
 */

static long numNsCreated = 0; 

/*
 * Data structure used as the ClientData of imported commands: commands
 * created in an namespace when it imports a "real" command from another
 * namespace.
 */

typedef struct ImportedCmdData {
    Command *realCmdPtr;	/* "Real" command that this imported command
                                 * refers to. */
    Command *selfPtr;		/* Pointer to this imported command. Needed
				 * only when deleting it in order to remove
				 * it from the real command's linked list of
				 * imported commands that refer to it. */
} ImportedCmdData;

/*
 * This structure contains a cached pointer to a namespace that is the
 * result of resolving the namespace's name in some other namespace. It is
 * the internal representation for a nsName object. It contains the
 * pointer along with some information that is used to check the cached
 * pointer's validity.











>









|













>
>
>
>
>
>
>






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







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
/*
 * tclNamesp.c --
 *
 *      Contains support for namespaces, which provide a separate context of
 *      commands and global variables. The global :: namespace is the
 *      traditional Tcl "global" scope. Other namespaces are created as
 *      children of the global namespace. These other namespaces contain
 *      special-purpose commands and variables for packages.
 *
 * Copyright (c) 1993-1997 Lucent Technologies.
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * Originally implemented by
 *   Michael J. McLennan
 *   Bell Labs Innovations for Lucent Technologies
 *   [email protected]
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclNamesp.c,v 1.1.2.8 1999/03/26 22:39:53 rjohnson Exp $
 */

#include "tclInt.h"

/*
 * Flag passed to TclGetNamespaceForQualName to indicate that it should
 * search for a namespace rather than a command or variable inside a
 * namespace. Note that this flag's value must not conflict with the values
 * of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, or CREATE_NS_IF_UNKNOWN.
 */

#define FIND_ONLY_NS	0x1000

/*
 * Initial size of stack allocated space for tail list - used when resetting
 * shadowed command references in the functin: TclResetShadowedCmdRefs.
 */

#define NUM_TRAIL_ELEMS 5

/*
 * Count of the number of namespaces created. This value is used as a
 * unique id for each namespace.
 */

static long numNsCreated = 0; 
TCL_DECLARE_MUTEX(nsMutex)















/*
 * This structure contains a cached pointer to a namespace that is the
 * result of resolving the namespace's name in some other namespace. It is
 * the internal representation for a nsName object. It contains the
 * pointer along with some information that is used to check the cached
 * pointer's validity.
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
Tcl_ObjType tclNsNameType = {
    "nsName",			/* the type's name */
    FreeNsNameInternalRep,	/* freeIntRepProc */
    DupNsNameInternalRep,	/* dupIntRepProc */
    UpdateStringOfNsName,	/* updateStringProc */
    SetNsNameFromAny		/* setFromAnyProc */
};

/*
 * Boolean flag indicating whether or not the namespName object
 * type has been registered with the Tcl compiler.
 */

static int nsInitialized = 0;

/*
 *----------------------------------------------------------------------
 *
 * TclInitNamespaces --
 *
 *	Called when any interpreter is created to make sure that
 *	things are properly set up for namespaces.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	On the first call, the namespName object type is registered
 *	with the Tcl compiler.
 *
 *----------------------------------------------------------------------
 */

void
TclInitNamespaces()
{
    if (!nsInitialized) {
        Tcl_RegisterObjType(&tclNsNameType);
        nsInitialized = 1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetCurrentNamespace --
 *







<
<
<
<
<
<
<




|

|
|





<
|





|

<
|
<
<







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
Tcl_ObjType tclNsNameType = {
    "nsName",			/* the type's name */
    FreeNsNameInternalRep,	/* freeIntRepProc */
    DupNsNameInternalRep,	/* dupIntRepProc */
    UpdateStringOfNsName,	/* updateStringProc */
    SetNsNameFromAny		/* setFromAnyProc */
};








/*
 *----------------------------------------------------------------------
 *
 * TclInitNamespaceSubsystem --
 *
 *	This procedure is called to initialize all the structures that 
 *	are used by namespaces on a per-process basis.
 *
 * Results:
 *	None.
 *
 * Side effects:

 *	The namespace object type is registered with the Tcl compiler.
 *
 *----------------------------------------------------------------------
 */

void
TclInitNamespaceSubsystem()
{

    Tcl_RegisterObjType(&tclNsNameType);


}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetCurrentNamespace --
 *
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
    register Namespace *nsPtr;

    if (namespacePtr == NULL) {
	nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    } else {
        nsPtr = (Namespace *) namespacePtr;
        if (nsPtr->flags & NS_DEAD) {
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "namespace \"",
		    nsPtr->fullName, "\" not found in context \"",
		    Tcl_GetCurrentNamespace(interp)->fullName, "\"",
		    (char *) NULL);
            return TCL_ERROR;
        }
    }

    nsPtr->activationCount++;
    framePtr->nsPtr = nsPtr;
    framePtr->isProcCallFrame = isProcCallFrame;
    framePtr->objc = 0;







|
|
<
<
<







284
285
286
287
288
289
290
291
292



293
294
295
296
297
298
299
    register Namespace *nsPtr;

    if (namespacePtr == NULL) {
	nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    } else {
        nsPtr = (Namespace *) namespacePtr;
        if (nsPtr->flags & NS_DEAD) {
	    panic("Trying to push call frame for dead namespace");
	    /*NOTREACHED*/



        }
    }

    nsPtr->activationCount++;
    framePtr->nsPtr = nsPtr;
    framePtr->isProcCallFrame = isProcCallFrame;
    framePtr->objc = 0;
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
    Interp *iPtr = (Interp *) interp;
    register Namespace *nsPtr, *ancestorPtr;
    Namespace *parentPtr, *dummy1Ptr, *dummy2Ptr;
    Namespace *globalNsPtr = iPtr->globalNsPtr;
    char *simpleName;
    Tcl_HashEntry *entryPtr;
    Tcl_DString buffer1, buffer2;
    int newEntry, result;

    /*
     * If there is no active namespace, the interpreter is being
     * initialized. 
     */

    if ((globalNsPtr == NULL) && (iPtr->varFramePtr == NULL)) {







|







441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
    Interp *iPtr = (Interp *) interp;
    register Namespace *nsPtr, *ancestorPtr;
    Namespace *parentPtr, *dummy1Ptr, *dummy2Ptr;
    Namespace *globalNsPtr = iPtr->globalNsPtr;
    char *simpleName;
    Tcl_HashEntry *entryPtr;
    Tcl_DString buffer1, buffer2;
    int newEntry;

    /*
     * If there is no active namespace, the interpreter is being
     * initialized. 
     */

    if ((globalNsPtr == NULL) && (iPtr->varFramePtr == NULL)) {
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
		"can't create namespace \"\": only global namespace can have empty name", (char *) NULL);
	return NULL;
    } else {
	/*
	 * Find the parent for the new namespace.
	 */

	result = TclGetNamespaceForQualName(interp, name,
		(Namespace *) NULL,
		/*flags*/ (CREATE_NS_IF_UNKNOWN | TCL_LEAVE_ERR_MSG),
		&parentPtr, &dummy1Ptr, &dummy2Ptr, &simpleName);
        if (result != TCL_OK) {
            return NULL;
        }

	/*
	 * If the unqualified name at the end is empty, there were trailing
	 * "::"s after the namespace's name which we ignore. The new
	 * namespace was already (recursively) created and is pointed to
	 * by parentPtr.
	 */







|
<


<
<
<







465
466
467
468
469
470
471
472

473
474



475
476
477
478
479
480
481
		"can't create namespace \"\": only global namespace can have empty name", (char *) NULL);
	return NULL;
    } else {
	/*
	 * Find the parent for the new namespace.
	 */

	TclGetNamespaceForQualName(interp, name, (Namespace *) NULL,

		/*flags*/ (CREATE_NS_IF_UNKNOWN | TCL_LEAVE_ERR_MSG),
		&parentPtr, &dummy1Ptr, &dummy2Ptr, &simpleName);




	/*
	 * If the unqualified name at the end is empty, there were trailing
	 * "::"s after the namespace's name which we ignore. The new
	 * namespace was already (recursively) created and is pointed to
	 * by parentPtr.
	 */
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
    }

    /*
     * Create the new namespace and root it in its parent. Increment the
     * count of namespaces created.
     */

    numNsCreated++;

    nsPtr = (Namespace *) ckalloc(sizeof(Namespace));
    nsPtr->name            = (char *) ckalloc((unsigned) (strlen(simpleName)+1));
    strcpy(nsPtr->name, simpleName);
    nsPtr->fullName        = NULL;   /* set below */
    nsPtr->clientData      = clientData;
    nsPtr->deleteProc      = deleteProc;
    nsPtr->parentPtr       = parentPtr;
    Tcl_InitHashTable(&nsPtr->childTable, TCL_STRING_KEYS);


    nsPtr->nsId            = numNsCreated;

    nsPtr->interp          = interp;
    nsPtr->flags           = 0;
    nsPtr->activationCount = 0;
    nsPtr->refCount        = 0;
    Tcl_InitHashTable(&nsPtr->cmdTable, TCL_STRING_KEYS);
    Tcl_InitHashTable(&nsPtr->varTable, TCL_STRING_KEYS);
    nsPtr->exportArrayPtr  = NULL;
    nsPtr->numExportPatterns = 0;
    nsPtr->maxExportPatterns = 0;
    nsPtr->cmdRefEpoch     = 0;





    if (parentPtr != NULL) {
        entryPtr = Tcl_CreateHashEntry(&parentPtr->childTable, simpleName,
	        &newEntry);
        Tcl_SetHashValue(entryPtr, (ClientData) nsPtr);
    }








<









>
>

>









|
>
>
>
>







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
    }

    /*
     * Create the new namespace and root it in its parent. Increment the
     * count of namespaces created.
     */



    nsPtr = (Namespace *) ckalloc(sizeof(Namespace));
    nsPtr->name            = (char *) ckalloc((unsigned) (strlen(simpleName)+1));
    strcpy(nsPtr->name, simpleName);
    nsPtr->fullName        = NULL;   /* set below */
    nsPtr->clientData      = clientData;
    nsPtr->deleteProc      = deleteProc;
    nsPtr->parentPtr       = parentPtr;
    Tcl_InitHashTable(&nsPtr->childTable, TCL_STRING_KEYS);
    Tcl_MutexLock(&nsMutex);
    numNsCreated++;
    nsPtr->nsId            = numNsCreated;
    Tcl_MutexUnlock(&nsMutex);
    nsPtr->interp          = interp;
    nsPtr->flags           = 0;
    nsPtr->activationCount = 0;
    nsPtr->refCount        = 0;
    Tcl_InitHashTable(&nsPtr->cmdTable, TCL_STRING_KEYS);
    Tcl_InitHashTable(&nsPtr->varTable, TCL_STRING_KEYS);
    nsPtr->exportArrayPtr  = NULL;
    nsPtr->numExportPatterns = 0;
    nsPtr->maxExportPatterns = 0;
    nsPtr->cmdRefEpoch       = 0;
    nsPtr->resolverEpoch     = 0;
    nsPtr->cmdResProc        = NULL;
    nsPtr->varResProc        = NULL;
    nsPtr->compiledVarResProc = NULL;

    if (parentPtr != NULL) {
        entryPtr = Tcl_CreateHashEntry(&parentPtr->childTable, simpleName,
	        &newEntry);
        Tcl_SetHashValue(entryPtr, (ClientData) nsPtr);
    }

880
881
882
883
884
885
886

887
888
889
890
891
892
893
     */

    ckfree(nsPtr->name);
    ckfree(nsPtr->fullName);

    ckfree((char *) nsPtr);
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_Export --
 *
 *	Makes all the commands matching a pattern available to later be







>







862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
     */

    ckfree(nsPtr->name);
    ckfree(nsPtr->fullName);

    ckfree((char *) nsPtr);
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_Export --
 *
 *	Makes all the commands matching a pattern available to later be
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
				  * If 0, return an error if an imported
				  * cmd conflicts with an existing one. */
{
#define INIT_EXPORT_PATTERNS 5    
    Namespace *nsPtr, *exportNsPtr, *dummyPtr;
    Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    char *simplePattern, *patternCpy;
    int neededElems, len, i, result;

    /*
     * If the specified namespace is NULL, use the current namespace.
     */

    if (namespacePtr == NULL) {
        nsPtr = (Namespace *) currNsPtr;







|







907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
				  * If 0, return an error if an imported
				  * cmd conflicts with an existing one. */
{
#define INIT_EXPORT_PATTERNS 5    
    Namespace *nsPtr, *exportNsPtr, *dummyPtr;
    Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    char *simplePattern, *patternCpy;
    int neededElems, len, i;

    /*
     * If the specified namespace is NULL, use the current namespace.
     */

    if (namespacePtr == NULL) {
        nsPtr = (Namespace *) currNsPtr;
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
	}
    }

    /*
     * Check that the pattern doesn't have namespace qualifiers.
     */

    result = TclGetNamespaceForQualName(interp, pattern, nsPtr,
	    /*flags*/ TCL_LEAVE_ERR_MSG, &exportNsPtr, &dummyPtr,
	    &dummyPtr, &simplePattern);
    if (result != TCL_OK) {
	return result;
    }
    if ((exportNsPtr != nsPtr) || (strcmp(pattern, simplePattern) != 0)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
	        "invalid export pattern \"", pattern,
		"\": pattern can't specify a namespace",
		(char *) NULL);
	return TCL_ERROR;
    }







|


<
<
|







940
941
942
943
944
945
946
947
948
949


950
951
952
953
954
955
956
957
	}
    }

    /*
     * Check that the pattern doesn't have namespace qualifiers.
     */

    TclGetNamespaceForQualName(interp, pattern, nsPtr,
	    /*flags*/ TCL_LEAVE_ERR_MSG, &exportNsPtr, &dummyPtr,
	    &dummyPtr, &simplePattern);



    if ((exportNsPtr != nsPtr) || (strcmp(pattern, simplePattern) != 0)) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
	        "invalid export pattern \"", pattern,
		"\": pattern can't specify a namespace",
		(char *) NULL);
	return TCL_ERROR;
    }
1076
1077
1078
1079
1080
1081
1082




1083
1084
1085
1086
1087
1088
1089
 * Tcl_Import --
 *
 *	Imports all of the commands matching a pattern into the namespace
 *	specified by contextNsPtr (or the current namespace if contextNsPtr
 *	is NULL). This is done by creating a new command (the "imported
 *	command") that points to the real command in its original namespace.
 *




 * Results:
 *	Returns TCL_OK if successful, or TCL_ERROR (along with an error
 *	message in the interpreter's result) if something goes wrong.
 *
 * Side effects:
 *	Creates new commands in the importing namespace. These indirect
 *	calls back to the real command and are deleted if the real commands







>
>
>
>







1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
 * Tcl_Import --
 *
 *	Imports all of the commands matching a pattern into the namespace
 *	specified by contextNsPtr (or the current namespace if contextNsPtr
 *	is NULL). This is done by creating a new command (the "imported
 *	command") that points to the real command in its original namespace.
 *
 *      If matching commands are on the autoload path but haven't been
 *	loaded yet, this command forces them to be loaded, then creates
 *	the links to them.
 *
 * Results:
 *	Returns TCL_OK if successful, or TCL_ERROR (along with an error
 *	message in the interpreter's result) if something goes wrong.
 *
 * Side effects:
 *	Creates new commands in the importing namespace. These indirect
 *	calls back to the real command and are deleted if the real commands
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
































1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
{
    Interp *iPtr = (Interp *) interp;
    Namespace *nsPtr, *importNsPtr, *dummyPtr;
    Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    char *simplePattern, *cmdName;
    register Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Command *cmdPtr;
    ImportRef *refPtr;
    Tcl_Command importedCmd;
    ImportedCmdData *dataPtr;
    int wasExported, i, result;

    /*
     * If the specified namespace is NULL, use the current namespace.
     */

    if (namespacePtr == NULL) {
        nsPtr = (Namespace *) currNsPtr;
    } else {
        nsPtr = (Namespace *) namespacePtr;
    }

































    /*
     * From the pattern, find the namespace from which we are importing
     * and get the simple pattern (no namespace qualifiers or ::'s) at
     * the end.
     */

    if (strlen(pattern) == 0) {
	Tcl_SetStringObj(Tcl_GetObjResult(interp),
	        "empty import pattern", -1);
        return TCL_ERROR;
    }
    result = TclGetNamespaceForQualName(interp, pattern, nsPtr,
	    /*flags*/ TCL_LEAVE_ERR_MSG, &importNsPtr, &dummyPtr,
	    &dummyPtr, &simplePattern);
    if (result != TCL_OK) {
        return TCL_ERROR;
    }
    if (importNsPtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"unknown namespace in import pattern \"",
		pattern, "\"", (char *) NULL);
        return TCL_ERROR;
    }
    if (importNsPtr == nsPtr) {







|

|












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












|


<
<
|







1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162


1163
1164
1165
1166
1167
1168
1169
1170
{
    Interp *iPtr = (Interp *) interp;
    Namespace *nsPtr, *importNsPtr, *dummyPtr;
    Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    char *simplePattern, *cmdName;
    register Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Command *cmdPtr, *realCmdPtr;
    ImportRef *refPtr;
    Tcl_Command autoCmd, importedCmd;
    ImportedCmdData *dataPtr;
    int wasExported, i, result;

    /*
     * If the specified namespace is NULL, use the current namespace.
     */

    if (namespacePtr == NULL) {
        nsPtr = (Namespace *) currNsPtr;
    } else {
        nsPtr = (Namespace *) namespacePtr;
    }
 
    /*
     * First, invoke the "auto_import" command with the pattern
     * being imported.  This command is part of the Tcl library.
     * It looks for imported commands in autoloaded libraries and
     * loads them in.  That way, they will be found when we try
     * to create links below.
     */
    
    autoCmd = Tcl_FindCommand(interp, "auto_import",
 	    (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
 
    if (autoCmd != NULL) {
	Tcl_Obj *objv[2];
 
	objv[0] = Tcl_NewStringObj("auto_import", -1);
	Tcl_IncrRefCount(objv[0]);
	objv[1] = Tcl_NewStringObj(pattern, -1);
	Tcl_IncrRefCount(objv[1]);
 
	cmdPtr = (Command *) autoCmd;
	result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp,
		2, objv);
 
	Tcl_DecrRefCount(objv[0]);
	Tcl_DecrRefCount(objv[1]);
 
	if (result != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_ResetResult(interp);
    }

    /*
     * From the pattern, find the namespace from which we are importing
     * and get the simple pattern (no namespace qualifiers or ::'s) at
     * the end.
     */

    if (strlen(pattern) == 0) {
	Tcl_SetStringObj(Tcl_GetObjResult(interp),
	        "empty import pattern", -1);
        return TCL_ERROR;
    }
    TclGetNamespaceForQualName(interp, pattern, nsPtr,
	    /*flags*/ TCL_LEAVE_ERR_MSG, &importNsPtr, &dummyPtr,
	    &dummyPtr, &simplePattern);



    if (importNsPtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"unknown namespace in import pattern \"",
		pattern, "\"", (char *) NULL);
        return TCL_ERROR;
    }
    if (importNsPtr == nsPtr) {
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220







1221















1222
1223
1224
1225
1226
1227
1228
		 * To create the new command in the current namespace, 
		 * generate a fully qualified name for it.
		 */

		Tcl_DString ds;

		Tcl_DStringInit(&ds);
		Tcl_DStringAppend(&ds, currNsPtr->fullName, -1);
		if (currNsPtr != iPtr->globalNsPtr) {
		    Tcl_DStringAppend(&ds, "::", 2);
		}
		Tcl_DStringAppend(&ds, cmdName, -1);
		







		cmdPtr = (Command *) Tcl_GetHashValue(hPtr);















		dataPtr = (ImportedCmdData *)
		        ckalloc(sizeof(ImportedCmdData));
                importedCmd = Tcl_CreateObjCommand(interp, 
                        Tcl_DStringValue(&ds), InvokeImportedCmd,
                        (ClientData) dataPtr, DeleteImportedCmd);
		dataPtr->realCmdPtr = cmdPtr;
		dataPtr->selfPtr = (Command *) importedCmd;







|
|



|
>
>
>
>
>
>
>

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







1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
		 * To create the new command in the current namespace, 
		 * generate a fully qualified name for it.
		 */

		Tcl_DString ds;

		Tcl_DStringInit(&ds);
		Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
		if (nsPtr != iPtr->globalNsPtr) {
		    Tcl_DStringAppend(&ds, "::", 2);
		}
		Tcl_DStringAppend(&ds, cmdName, -1);

		/*
		 * Check whether creating the new imported command in the
		 * current namespace would create a cycle of imported->real
		 * command references that also would destroy an existing
		 * "real" command already in the current namespace.
		 */

		cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
		if (cmdPtr->deleteProc == DeleteImportedCmd) {
		    realCmdPtr = (Command *) TclGetOriginalCommand(
			    (Tcl_Command) cmdPtr);
		    if ((realCmdPtr != NULL)
			    && (realCmdPtr->nsPtr == currNsPtr)
			    && (Tcl_FindHashEntry(&currNsPtr->cmdTable,
			            cmdName) != NULL)) {
			Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			        "import pattern \"", pattern,
				"\" would create a loop containing command \"",
				Tcl_DStringValue(&ds), "\"", (char *) NULL);
			return TCL_ERROR;
		    }
		}

		dataPtr = (ImportedCmdData *)
		        ckalloc(sizeof(ImportedCmdData));
                importedCmd = Tcl_CreateObjCommand(interp, 
                        Tcl_DStringValue(&ds), InvokeImportedCmd,
                        (ClientData) dataPtr, DeleteImportedCmd);
		dataPtr->realCmdPtr = cmdPtr;
		dataPtr->selfPtr = (Command *) importedCmd;
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
				  * imported. */
{
    Namespace *nsPtr, *importNsPtr, *dummyPtr, *actualCtxPtr;
    char *simplePattern, *cmdName;
    register Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Command *cmdPtr;
    int result;

    /*
     * If the specified namespace is NULL, use the current namespace.
     */

    if (namespacePtr == NULL) {
        nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    } else {
        nsPtr = (Namespace *) namespacePtr;
    }

    /*
     * From the pattern, find the namespace from which we are importing
     * and get the simple pattern (no namespace qualifiers or ::'s) at
     * the end.
     */

    result = TclGetNamespaceForQualName(interp, pattern, nsPtr,
	    /*flags*/ TCL_LEAVE_ERR_MSG, &importNsPtr, &dummyPtr,
	    &actualCtxPtr, &simplePattern);
    if (result != TCL_OK) {
        return result;
    }
    if (importNsPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"unknown namespace in namespace forget pattern \"",
		pattern, "\"", (char *) NULL);
        return TCL_ERROR;
    }








<

















|


<
<
|







1321
1322
1323
1324
1325
1326
1327

1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347


1348
1349
1350
1351
1352
1353
1354
1355
				  * imported. */
{
    Namespace *nsPtr, *importNsPtr, *dummyPtr, *actualCtxPtr;
    char *simplePattern, *cmdName;
    register Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Command *cmdPtr;


    /*
     * If the specified namespace is NULL, use the current namespace.
     */

    if (namespacePtr == NULL) {
        nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    } else {
        nsPtr = (Namespace *) namespacePtr;
    }

    /*
     * From the pattern, find the namespace from which we are importing
     * and get the simple pattern (no namespace qualifiers or ::'s) at
     * the end.
     */

    TclGetNamespaceForQualName(interp, pattern, nsPtr,
	    /*flags*/ TCL_LEAVE_ERR_MSG, &importNsPtr, &dummyPtr,
	    &actualCtxPtr, &simplePattern);



    if (importNsPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"unknown namespace in namespace forget pattern \"",
		pattern, "\"", (char *) NULL);
        return TCL_ERROR;
    }

1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545



1546
1547
1548

1549
1550
1551
1552
1553
1554
1555
 *	in the current namespace. A pointer to the namespace is stored in
 *	*nsPtrPtr and NULL is stored in *simpleNamePtr. Otherwise, if
 *	FIND_ONLY_NS is not specified, only the leading components are
 *	treated as namespace names, and a pointer to the simple name of the
 *	final component is stored in *simpleNamePtr.
 *
 * Results:
 *	Ordinarily this procedure returns TCL_OK. It sets *nsPtrPtr and
 *	*altNsPtrPtr to point to the two possible namespaces which represent
 *	the last (containing) namespace in the qualified name. If the
 *	procedure sets either *nsPtrPtr or *altNsPtrPtr to NULL, then the
 *	search along that path failed. The procedure also stores a pointer
 *	to the simple name of the final component in *simpleNamePtr. If the
 *	qualified name is "::" or was treated as a namespace reference
 *	(FIND_ONLY_NS), the procedure stores a pointer to the
 *	namespace in *nsPtrPtr, NULL in *altNsPtrPtr, and sets
 *	*simpleNamePtr to point to an empty string.
 *
 *	If there is an error, this procedure returns TCL_ERROR. If "flags"
 *	contains TCL_LEAVE_ERR_MSG, an error message is returned in the
 *	interpreter's result object. Otherwise, the interpreter's result
 *	object is left unchanged.
 *
 *	*actualCxtPtrPtr is set to the actual context namespace. It is
 *	set to the input context namespace pointer in cxtNsPtr. If cxtNsPtr
 *	is NULL, it is set to the current namespace context.
 *



 * Side effects:
 *	If flags contains TCL_LEAVE_ERR_MSG and an error is encountered,
 *	the interpreter's result object will contain an error message.

 *
 *----------------------------------------------------------------------
 */

int
TclGetNamespaceForQualName(interp, qualName, cxtNsPtr, flags,
	nsPtrPtr, altNsPtrPtr, actualCxtPtrPtr, simpleNamePtr)







<
|
|
|
|
|
|
|
|











>
>
>

|
<
>







1553
1554
1555
1556
1557
1558
1559

1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583

1584
1585
1586
1587
1588
1589
1590
1591
 *	in the current namespace. A pointer to the namespace is stored in
 *	*nsPtrPtr and NULL is stored in *simpleNamePtr. Otherwise, if
 *	FIND_ONLY_NS is not specified, only the leading components are
 *	treated as namespace names, and a pointer to the simple name of the
 *	final component is stored in *simpleNamePtr.
 *
 * Results:

 *	It sets *nsPtrPtr and *altNsPtrPtr to point to the two possible
 *	namespaces which represent the last (containing) namespace in the
 *	qualified name. If the procedure sets either *nsPtrPtr or *altNsPtrPtr
 *	to NULL, then the search along that path failed.  The procedure also
 *	stores a pointer to the simple name of the final component in
 *	*simpleNamePtr. If the qualified name is "::" or was treated as a
 *	namespace reference (FIND_ONLY_NS), the procedure stores a pointer
 *	to the namespace in *nsPtrPtr, NULL in *altNsPtrPtr, and sets
 *	*simpleNamePtr to point to an empty string.
 *
 *	If there is an error, this procedure returns TCL_ERROR. If "flags"
 *	contains TCL_LEAVE_ERR_MSG, an error message is returned in the
 *	interpreter's result object. Otherwise, the interpreter's result
 *	object is left unchanged.
 *
 *	*actualCxtPtrPtr is set to the actual context namespace. It is
 *	set to the input context namespace pointer in cxtNsPtr. If cxtNsPtr
 *	is NULL, it is set to the current namespace context.
 *
 *	For backwards compatibility with the TclPro byte code loader,
 *	this function always returns TCL_OK.
 *
 * Side effects:
 *	If "flags" contains CREATE_NS_IF_UNKNOWN, new namespaces may be

 *	created.
 *
 *----------------------------------------------------------------------
 */

int
TclGetNamespaceForQualName(interp, qualName, cxtNsPtr, flags,
	nsPtrPtr, altNsPtrPtr, actualCxtPtrPtr, simpleNamePtr)
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
    Namespace *nsPtr = cxtNsPtr;
    Namespace *altNsPtr;
    Namespace *globalNsPtr = iPtr->globalNsPtr;
    register char *start, *end;
    char *nsName;
    Tcl_HashEntry *entryPtr;
    Tcl_DString buffer;
    int len, result;

    /*
     * Determine the context namespace nsPtr in which to start the primary
     * search. If TCL_NAMESPACE_ONLY or FIND_ONLY_NS was specified, search
     * from the current namespace. If the qualName name starts with a "::"
     * or TCL_GLOBAL_ONLY was specified, search from the global
     * namespace. Otherwise, use the given namespace given in cxtNsPtr, or







|







1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
    Namespace *nsPtr = cxtNsPtr;
    Namespace *altNsPtr;
    Namespace *globalNsPtr = iPtr->globalNsPtr;
    register char *start, *end;
    char *nsName;
    Tcl_HashEntry *entryPtr;
    Tcl_DString buffer;
    int len;

    /*
     * Determine the context namespace nsPtr in which to start the primary
     * search. If TCL_NAMESPACE_ONLY or FIND_ONLY_NS was specified, search
     * from the current namespace. If the qualName name starts with a "::"
     * or TCL_GLOBAL_ONLY was specified, search from the global
     * namespace. Otherwise, use the given namespace given in cxtNsPtr, or
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736

1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
        if (nsPtr != NULL) {
            entryPtr = Tcl_FindHashEntry(&nsPtr->childTable, nsName);
            if (entryPtr != NULL) {
                nsPtr = (Namespace *) Tcl_GetHashValue(entryPtr);
            } else if (flags & CREATE_NS_IF_UNKNOWN) {
		Tcl_CallFrame frame;
		
		result = Tcl_PushCallFrame(interp, &frame,
		        (Tcl_Namespace *) nsPtr, /*isProcCallFrame*/ 0);
                if (result != TCL_OK) {
                    Tcl_DStringFree(&buffer);
                    return result;
                }
                nsPtr = (Namespace *) Tcl_CreateNamespace(interp, nsName,
		        (ClientData) NULL, (Tcl_NamespaceDeleteProc *) NULL);
                Tcl_PopCallFrame(interp);

                if (nsPtr == NULL) {
                    Tcl_DStringFree(&buffer);
                    return TCL_ERROR;
                }
            } else {		/* namespace not found and wasn't created */
                nsPtr = NULL;
            }
        }

        /*







|

<
<
<
|



>

<
|







1757
1758
1759
1760
1761
1762
1763
1764
1765



1766
1767
1768
1769
1770
1771

1772
1773
1774
1775
1776
1777
1778
1779
        if (nsPtr != NULL) {
            entryPtr = Tcl_FindHashEntry(&nsPtr->childTable, nsName);
            if (entryPtr != NULL) {
                nsPtr = (Namespace *) Tcl_GetHashValue(entryPtr);
            } else if (flags & CREATE_NS_IF_UNKNOWN) {
		Tcl_CallFrame frame;
		
		(void) Tcl_PushCallFrame(interp, &frame,
		        (Tcl_Namespace *) nsPtr, /*isProcCallFrame*/ 0);




                nsPtr = (Namespace *) Tcl_CreateNamespace(interp, nsName,
		        (ClientData) NULL, (Tcl_NamespaceDeleteProc *) NULL);
                Tcl_PopCallFrame(interp);

                if (nsPtr == NULL) {

                    panic("Could not create namespace '%s'", nsName);
                }
            } else {		/* namespace not found and wasn't created */
                nsPtr = NULL;
            }
        }

        /*
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
     * namespaces can not have empty names except for the global namespace.
     */

    if ((flags & FIND_ONLY_NS) && (*qualName == '\0')
	    && (nsPtr != globalNsPtr)) {
	nsPtr = NULL;
    }
    
    *nsPtrPtr    = nsPtr;
    *altNsPtrPtr = altNsPtr;
    Tcl_DStringFree(&buffer);
    return TCL_OK;
}

/*







|







1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
     * namespaces can not have empty names except for the global namespace.
     */

    if ((flags & FIND_ONLY_NS) && (*qualName == '\0')
	    && (nsPtr != globalNsPtr)) {
	nsPtr = NULL;
    }

    *nsPtrPtr    = nsPtr;
    *altNsPtrPtr = altNsPtr;
    Tcl_DStringFree(&buffer);
    return TCL_OK;
}

/*
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
				  * in the current namespace. */
    register int flags;		 /* Flags controlling namespace lookup: an
				  * OR'd combination of TCL_GLOBAL_ONLY and
				  * TCL_LEAVE_ERR_MSG flags. */
{
    Namespace *nsPtr, *dummy1Ptr, *dummy2Ptr;
    char *dummy;
    int result;

    /*
     * Find the namespace(s) that contain the specified namespace name.
     * Add the FIND_ONLY_NS flag to resolve the name all the way down
     * to its last component, a namespace.
     */

    result = TclGetNamespaceForQualName(interp, name,
	    (Namespace *) contextNsPtr, /*flags*/ (flags | FIND_ONLY_NS),
	    &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy);
    if (result != TCL_OK) {
        return NULL;
    }
    if (nsPtr != NULL) {
       return (Tcl_Namespace *) nsPtr;
    } else if (flags & TCL_LEAVE_ERR_MSG) {
	Tcl_ResetResult(interp);
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "unknown namespace \"", name, "\"", (char *) NULL);
    }







<







|
<
|
<
<
|







1868
1869
1870
1871
1872
1873
1874

1875
1876
1877
1878
1879
1880
1881
1882

1883


1884
1885
1886
1887
1888
1889
1890
1891
				  * in the current namespace. */
    register int flags;		 /* Flags controlling namespace lookup: an
				  * OR'd combination of TCL_GLOBAL_ONLY and
				  * TCL_LEAVE_ERR_MSG flags. */
{
    Namespace *nsPtr, *dummy1Ptr, *dummy2Ptr;
    char *dummy;


    /*
     * Find the namespace(s) that contain the specified namespace name.
     * Add the FIND_ONLY_NS flag to resolve the name all the way down
     * to its last component, a namespace.
     */

    TclGetNamespaceForQualName(interp, name, (Namespace *) contextNsPtr,

	    (flags | FIND_ONLY_NS), &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy);


    
    if (nsPtr != NULL) {
       return (Tcl_Namespace *) nsPtr;
    } else if (flags & TCL_LEAVE_ERR_MSG) {
	Tcl_ResetResult(interp);
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "unknown namespace \"", name, "\"", (char *) NULL);
    }
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
				  * (look up only in contextNsPtr, or the
				  * current namespace if contextNsPtr is
				  * NULL), and TCL_LEAVE_ERR_MSG. If both
				  * TCL_GLOBAL_ONLY and TCL_NAMESPACE_ONLY
				  * are given, TCL_GLOBAL_ONLY is
				  * ignored. */
{



    Namespace *nsPtr[2], *cxtNsPtr;
    char *simpleName;
    register Tcl_HashEntry *entryPtr;
    register Command *cmdPtr;
    register int search;
    int result;


    /*

     * Find the namespace(s) that contain the command.



     */









    result = TclGetNamespaceForQualName(interp, name,





	    (Namespace *) contextNsPtr, flags, &nsPtr[0], &nsPtr[1],



	    &cxtNsPtr, &simpleName);











    if (result != TCL_OK) {
        return (Tcl_Command) NULL;
    }









    /*
     * Look for the command in the command table of its namespace.
     * Be sure to check both possible search paths: from the specified
     * namespace context and from the global namespace.
     */








>
>
>






>


>
|
>
>
>

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







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
1971
1972
1973
1974
1975
1976
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
				  * (look up only in contextNsPtr, or the
				  * current namespace if contextNsPtr is
				  * NULL), and TCL_LEAVE_ERR_MSG. If both
				  * TCL_GLOBAL_ONLY and TCL_NAMESPACE_ONLY
				  * are given, TCL_GLOBAL_ONLY is
				  * ignored. */
{
    Interp *iPtr = (Interp*)interp;

    ResolverScheme *resPtr;
    Namespace *nsPtr[2], *cxtNsPtr;
    char *simpleName;
    register Tcl_HashEntry *entryPtr;
    register Command *cmdPtr;
    register int search;
    int result;
    Tcl_Command cmd;

    /*
     * If this namespace has a command resolver, then give it first
     * crack at the command resolution.  If the interpreter has any
     * command resolvers, consult them next.  The command resolver
     * procedures may return a Tcl_Command value, they may signal
     * to continue onward, or they may signal an error.
     */
    if ((flags & TCL_GLOBAL_ONLY) != 0) {
        cxtNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
    }
    else if (contextNsPtr != NULL) {
        cxtNsPtr = (Namespace *) contextNsPtr;
    }
    else {
        cxtNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    }

    if (cxtNsPtr->cmdResProc != NULL || iPtr->resolverPtr != NULL) {
        resPtr = iPtr->resolverPtr;

        if (cxtNsPtr->cmdResProc) {
            result = (*cxtNsPtr->cmdResProc)(interp, name,
                (Tcl_Namespace *) cxtNsPtr, flags, &cmd);
        } else {
            result = TCL_CONTINUE;
        }

        while (result == TCL_CONTINUE && resPtr) {
            if (resPtr->cmdResProc) {
                result = (*resPtr->cmdResProc)(interp, name,
                    (Tcl_Namespace *) cxtNsPtr, flags, &cmd);
            }
            resPtr = resPtr->nextPtr;
        }

        if (result == TCL_OK) {
            return cmd;
        }
        else if (result != TCL_CONTINUE) {
            return (Tcl_Command) NULL;
        }
    }

    /*
     * Find the namespace(s) that contain the command.
     */

    TclGetNamespaceForQualName(interp, name, (Namespace *) contextNsPtr,
	    flags, &nsPtr[0], &nsPtr[1], &cxtNsPtr, &simpleName);

    /*
     * Look for the command in the command table of its namespace.
     * Be sure to check both possible search paths: from the specified
     * namespace context and from the global namespace.
     */

1942
1943
1944
1945
1946
1947
1948

1949
1950
1951
1952
1953
1954
1955
    if (cmdPtr != NULL) {
        return (Tcl_Command) cmdPtr;
    } else if (flags & TCL_LEAVE_ERR_MSG) {
	Tcl_ResetResult(interp);
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "unknown command \"", name, "\"", (char *) NULL);
    }

    return (Tcl_Command) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FindNamespaceVar --







>







2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
    if (cmdPtr != NULL) {
        return (Tcl_Command) cmdPtr;
    } else if (flags & TCL_LEAVE_ERR_MSG) {
	Tcl_ResetResult(interp);
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                "unknown command \"", name, "\"", (char *) NULL);
    }

    return (Tcl_Command) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FindNamespaceVar --
1989
1990
1991
1992
1993
1994
1995


1996
1997
1998
1999
2000
2001

2002
2003

2004


2005


2006






2007





2008



2009











2010
2011
2012








2013
2014
2015
2016
2017
2018
2019
				  * (look up only in contextNsPtr, or the
				  * current namespace if contextNsPtr is
				  * NULL), and TCL_LEAVE_ERR_MSG. If both
				  * TCL_GLOBAL_ONLY and TCL_NAMESPACE_ONLY
				  * are given, TCL_GLOBAL_ONLY is
				  * ignored. */
{


    Namespace *nsPtr[2], *cxtNsPtr;
    char *simpleName;
    Tcl_HashEntry *entryPtr;
    Var *varPtr;
    register int search;
    int result;


    /*

     * Find the namespace(s) that contain the variable.


     */









    result = TclGetNamespaceForQualName(interp, name,





	    (Namespace *) contextNsPtr, flags, &nsPtr[0], &nsPtr[1],



	    &cxtNsPtr, &simpleName);











    if (result != TCL_OK) {
        return (Tcl_Var) NULL;
    }









    /*
     * Look for the variable in the variable table of its namespace.
     * Be sure to check both possible search paths: from the specified
     * namespace context and from the global namespace.
     */








>
>






>


>
|
>
>

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







2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
				  * (look up only in contextNsPtr, or the
				  * current namespace if contextNsPtr is
				  * NULL), and TCL_LEAVE_ERR_MSG. If both
				  * TCL_GLOBAL_ONLY and TCL_NAMESPACE_ONLY
				  * are given, TCL_GLOBAL_ONLY is
				  * ignored. */
{
    Interp *iPtr = (Interp*)interp;
    ResolverScheme *resPtr;
    Namespace *nsPtr[2], *cxtNsPtr;
    char *simpleName;
    Tcl_HashEntry *entryPtr;
    Var *varPtr;
    register int search;
    int result;
    Tcl_Var var;

    /*
     * If this namespace has a variable resolver, then give it first
     * crack at the variable resolution.  It may return a Tcl_Var
     * value, it may signal to continue onward, or it may signal
     * an error.
     */
    if ((flags & TCL_GLOBAL_ONLY) != 0) {
        cxtNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
    }
    else if (contextNsPtr != NULL) {
        cxtNsPtr = (Namespace *) contextNsPtr;
    }
    else {
        cxtNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    }

    if (cxtNsPtr->varResProc != NULL || iPtr->resolverPtr != NULL) {
        resPtr = iPtr->resolverPtr;

        if (cxtNsPtr->varResProc) {
            result = (*cxtNsPtr->varResProc)(interp, name,
                (Tcl_Namespace *) cxtNsPtr, flags, &var);
        } else {
            result = TCL_CONTINUE;
        }

        while (result == TCL_CONTINUE && resPtr) {
            if (resPtr->varResProc) {
                result = (*resPtr->varResProc)(interp, name,
                    (Tcl_Namespace *) cxtNsPtr, flags, &var);
            }
            resPtr = resPtr->nextPtr;
        }

        if (result == TCL_OK) {
            return var;
        }
        else if (result != TCL_CONTINUE) {
            return (Tcl_Var) NULL;
        }
    }

    /*
     * Find the namespace(s) that contain the variable.
     */

    TclGetNamespaceForQualName(interp, name, (Namespace *) contextNsPtr,
	    flags, &nsPtr[0], &nsPtr[1], &cxtNsPtr, &simpleName);

    /*
     * Look for the variable in the variable table of its namespace.
     * Be sure to check both possible search paths: from the specified
     * namespace context and from the global namespace.
     */

2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097

    /*
     * This procedure generates an array used to hold the trail list. This
     * starts out with stack-allocated space but uses dynamically-allocated
     * storage if needed.
     */

#define NUM_TRAIL_ELEMS 5
    Namespace *(trailStorage[NUM_TRAIL_ELEMS]);
    Namespace **trailPtr = trailStorage;
    int trailFront = -1;
    int trailSize = NUM_TRAIL_ELEMS;

    /*
     * Start at the namespace containing the new command, and work up







<







2197
2198
2199
2200
2201
2202
2203

2204
2205
2206
2207
2208
2209
2210

    /*
     * This procedure generates an array used to hold the trail list. This
     * starts out with stack-allocated space but uses dynamically-allocated
     * storage if needed.
     */


    Namespace *(trailStorage[NUM_TRAIL_ELEMS]);
    Namespace **trailPtr = trailStorage;
    int trailFront = -1;
    int trailSize = NUM_TRAIL_ELEMS;

    /*
     * Start at the namespace containing the new command, and work up
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
    /*
     * Free any allocated storage.
     */
    
    if (trailPtr != trailStorage) {
	ckfree((char *) trailPtr);
    }
#undef NUM_TRAIL_ELEMS
}

/*
 *----------------------------------------------------------------------
 *
 * GetNamespaceFromObj --
 *







<







2290
2291
2292
2293
2294
2295
2296

2297
2298
2299
2300
2301
2302
2303
    /*
     * Free any allocated storage.
     */
    
    if (trailPtr != trailStorage) {
	ckfree((char *) trailPtr);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * GetNamespaceFromObj --
 *
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
	    "inscope", "origin", "parent", "qualifiers",
	    "tail", "which", (char *) NULL};
    enum NSSubCmdIdx {
	    NSChildrenIdx, NSCodeIdx, NSCurrentIdx, NSDeleteIdx,
	    NSEvalIdx, NSExportIdx, NSForgetIdx, NSImportIdx,
	    NSInscopeIdx, NSOriginIdx, NSParentIdx, NSQualifiersIdx,
	    NSTailIdx, NSWhichIdx
    } index;
    int result;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?arg ...?");
        return TCL_ERROR;
    }

    /*







|
|







2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
	    "inscope", "origin", "parent", "qualifiers",
	    "tail", "which", (char *) NULL};
    enum NSSubCmdIdx {
	    NSChildrenIdx, NSCodeIdx, NSCurrentIdx, NSDeleteIdx,
	    NSEvalIdx, NSExportIdx, NSForgetIdx, NSImportIdx,
	    NSInscopeIdx, NSOriginIdx, NSParentIdx, NSQualifiersIdx,
	    NSTailIdx, NSWhichIdx
    };
    int index, result;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?arg ...?");
        return TCL_ERROR;
    }

    /*
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
	nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    } else if ((objc == 3) || (objc == 4)) {
        if (GetNamespaceFromObj(interp, objv[2], &namespacePtr) != TCL_OK) {
            return TCL_ERROR;
        }
        if (namespacePtr == NULL) {
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "unknown namespace \"",
		    Tcl_GetStringFromObj(objv[2], (int *) NULL),
		    "\" in namespace children command", (char *) NULL);
            return TCL_ERROR;
        }
        nsPtr = (Namespace *) namespacePtr;
    } else {
	Tcl_WrongNumArgs(interp, 2, objv, "?name? ?pattern?");
        return TCL_ERROR;
    }

    /*
     * Get the glob-style pattern, if any, used to narrow the search.
     */

    Tcl_DStringInit(&buffer);
    if (objc == 4) {
        char *name = Tcl_GetStringFromObj(objv[3], (int *) NULL);
	
        if ((*name == ':') && (*(name+1) == ':')) {
            pattern = name;
        } else {
            Tcl_DStringAppend(&buffer, nsPtr->fullName, -1);
            if (nsPtr != globalNsPtr) {
                Tcl_DStringAppend(&buffer, "::", 2);







|
<















|







2548
2549
2550
2551
2552
2553
2554
2555

2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
	nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
    } else if ((objc == 3) || (objc == 4)) {
        if (GetNamespaceFromObj(interp, objv[2], &namespacePtr) != TCL_OK) {
            return TCL_ERROR;
        }
        if (namespacePtr == NULL) {
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "unknown namespace \"", Tcl_GetString(objv[2]),

		    "\" in namespace children command", (char *) NULL);
            return TCL_ERROR;
        }
        nsPtr = (Namespace *) namespacePtr;
    } else {
	Tcl_WrongNumArgs(interp, 2, objv, "?name? ?pattern?");
        return TCL_ERROR;
    }

    /*
     * Get the glob-style pattern, if any, used to narrow the search.
     */

    Tcl_DStringInit(&buffer);
    if (objc == 4) {
        char *name = Tcl_GetString(objv[3]);
	
        if ((*name == ':') && (*(name+1) == ':')) {
            pattern = name;
        } else {
            Tcl_DStringAppend(&buffer, nsPtr->fullName, -1);
            if (nsPtr != globalNsPtr) {
                Tcl_DStringAppend(&buffer, "::", 2);
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
    /*
     * Destroying one namespace may cause another to be destroyed. Break
     * this into two passes: first check to make sure that all namespaces on
     * the command line are valid, and report any errors.
     */

    for (i = 2;  i < objc;  i++) {
        name = Tcl_GetStringFromObj(objv[i], (int *) NULL);
	namespacePtr = Tcl_FindNamespace(interp, name,
		(Tcl_Namespace *) NULL, /*flags*/ 0);
        if (namespacePtr == NULL) {
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "unknown namespace \"",
		    Tcl_GetStringFromObj(objv[i], (int *) NULL),
		    "\" in namespace delete command", (char *) NULL);
            return TCL_ERROR;
        }
    }

    /*
     * Okay, now delete each namespace.
     */

    for (i = 2;  i < objc;  i++) {
        name = Tcl_GetStringFromObj(objv[i], (int *) NULL);
	namespacePtr = Tcl_FindNamespace(interp, name,
	    (Tcl_Namespace *) NULL, TCL_LEAVE_ERR_MSG);
	if (namespacePtr == NULL) {
            return TCL_ERROR;
        }
        Tcl_DeleteNamespace(namespacePtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|




|
<










|

|
|
|

<







2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810

2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826

2827
2828
2829
2830
2831
2832
2833
    /*
     * Destroying one namespace may cause another to be destroyed. Break
     * this into two passes: first check to make sure that all namespaces on
     * the command line are valid, and report any errors.
     */

    for (i = 2;  i < objc;  i++) {
        name = Tcl_GetString(objv[i]);
	namespacePtr = Tcl_FindNamespace(interp, name,
		(Tcl_Namespace *) NULL, /*flags*/ 0);
        if (namespacePtr == NULL) {
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "unknown namespace \"", Tcl_GetString(objv[i]),

		    "\" in namespace delete command", (char *) NULL);
            return TCL_ERROR;
        }
    }

    /*
     * Okay, now delete each namespace.
     */

    for (i = 2;  i < objc;  i++) {
        name = Tcl_GetString(objv[i]);
	namespacePtr = Tcl_FindNamespace(interp, name,
	    (Tcl_Namespace *) NULL, /* flags */ 0);
	if (namespacePtr) {
            Tcl_DeleteNamespace(namespacePtr);
        }

    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805




2806

2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
    result = Tcl_PushCallFrame(interp, &frame, namespacePtr,
	    /*isProcCallFrame*/ 0);
    if (result != TCL_OK) {
        return TCL_ERROR;
    }

    if (objc == 4) {
        result = Tcl_EvalObj(interp, objv[3]);
    } else {
        objPtr = Tcl_ConcatObj(objc-3, objv+3);
        result = Tcl_EvalObj(interp, objPtr);




        Tcl_DecrRefCount(objPtr);  /* we're done with the object */

    }
    if (result == TCL_ERROR) {
        char msg[256];
	
        sprintf(msg, "\n    (in namespace eval \"%.200s\" script line %d)",
            namespacePtr->fullName, interp->errorLine);
        Tcl_AddObjErrorInfo(interp, msg, -1);
    }

    /*







|


|
>
>
>
>
|
>


|







2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
    result = Tcl_PushCallFrame(interp, &frame, namespacePtr,
	    /*isProcCallFrame*/ 0);
    if (result != TCL_OK) {
        return TCL_ERROR;
    }

    if (objc == 4) {
        result = Tcl_EvalObjEx(interp, objv[3], 0);
    } else {
        objPtr = Tcl_ConcatObj(objc-3, objv+3);

	/* 
	 * Tcl_EvalObj will delete the object when it decrements its
	 * refcount after eval'ing it.
	 */

        result = Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_DIRECT);
    }
    if (result == TCL_ERROR) {
        char msg[256 + TCL_INTEGER_SPACE];
	
        sprintf(msg, "\n    (in namespace eval \"%.200s\" script line %d)",
            namespacePtr->fullName, interp->errorLine);
        Tcl_AddObjErrorInfo(interp, msg, -1);
    }

    /*
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891

    /*
     * Process the optional "-clear" argument.
     */

    firstArg = 2;
    if (firstArg < objc) {
	string = Tcl_GetStringFromObj(objv[firstArg], (int *) NULL);
	if (strcmp(string, "-clear") == 0) {
	    resetListFirst = 1;
	    firstArg++;
	}
    }

    /*







|







2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005

    /*
     * Process the optional "-clear" argument.
     */

    firstArg = 2;
    if (firstArg < objc) {
	string = Tcl_GetString(objv[firstArg]);
	if (strcmp(string, "-clear") == 0) {
	    resetListFirst = 1;
	    firstArg++;
	}
    }

    /*
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
    }

    /*
     * Add each pattern to the namespace's export pattern list.
     */
    
    for (i = firstArg;  i < objc;  i++) {
	pattern = Tcl_GetStringFromObj(objv[i], (int *) NULL);
	result = Tcl_Export(interp, (Tcl_Namespace *) currNsPtr, pattern,
		((i == firstArg)? resetListFirst : 0));
        if (result != TCL_OK) {
            return result;
        }
    }
    return TCL_OK;







|







3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
    }

    /*
     * Add each pattern to the namespace's export pattern list.
     */
    
    for (i = firstArg;  i < objc;  i++) {
	pattern = Tcl_GetString(objv[i]);
	result = Tcl_Export(interp, (Tcl_Namespace *) currNsPtr, pattern,
		((i == firstArg)? resetListFirst : 0));
        if (result != TCL_OK) {
            return result;
        }
    }
    return TCL_OK;
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern pattern...?");
        return TCL_ERROR;
    }

    for (i = 2;  i < objc;  i++) {
        pattern = Tcl_GetStringFromObj(objv[i], (int *) NULL);
	result = Tcl_ForgetImport(interp, (Tcl_Namespace *) NULL, pattern);
        if (result != TCL_OK) {
            return result;
        }
    }
    return TCL_OK;
}







|







3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 2, objv, "?pattern pattern...?");
        return TCL_ERROR;
    }

    for (i = 2;  i < objc;  i++) {
        pattern = Tcl_GetString(objv[i]);
	result = Tcl_ForgetImport(interp, (Tcl_Namespace *) NULL, pattern);
        if (result != TCL_OK) {
            return result;
        }
    }
    return TCL_OK;
}
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062

    /*
     * Skip over the optional "-force" as the first argument.
     */

    firstArg = 2;
    if (firstArg < objc) {
	string = Tcl_GetStringFromObj(objv[firstArg], (int *) NULL);
	if ((*string == '-') && (strcmp(string, "-force") == 0)) {
	    allowOverwrite = 1;
	    firstArg++;
	}
    }

    /*
     * Handle the imports for each of the patterns.
     */

    for (i = firstArg;  i < objc;  i++) {
        pattern = Tcl_GetStringFromObj(objv[i], (int *) NULL);
	result = Tcl_Import(interp, (Tcl_Namespace *) NULL, pattern,
	        allowOverwrite);
        if (result != TCL_OK) {
            return result;
        }
    }
    return TCL_OK;







|











|







3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176

    /*
     * Skip over the optional "-force" as the first argument.
     */

    firstArg = 2;
    if (firstArg < objc) {
	string = Tcl_GetString(objv[firstArg]);
	if ((*string == '-') && (strcmp(string, "-force") == 0)) {
	    allowOverwrite = 1;
	    firstArg++;
	}
    }

    /*
     * Handle the imports for each of the patterns.
     */

    for (i = firstArg;  i < objc;  i++) {
        pattern = Tcl_GetString(objv[i]);
	result = Tcl_Import(interp, (Tcl_Namespace *) NULL, pattern,
	        allowOverwrite);
        if (result != TCL_OK) {
            return result;
        }
    }
    return TCL_OK;
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137

    result = GetNamespaceFromObj(interp, objv[2], &namespacePtr);
    if (result != TCL_OK) {
        return result;
    }
    if (namespacePtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
	        "unknown namespace \"",
		Tcl_GetStringFromObj(objv[2], (int *) NULL),
		"\" in inscope namespace command", (char *) NULL);
        return TCL_ERROR;
    }

    /*
     * Make the specified namespace the current namespace.
     */







|
<







3236
3237
3238
3239
3240
3241
3242
3243

3244
3245
3246
3247
3248
3249
3250

    result = GetNamespaceFromObj(interp, objv[2], &namespacePtr);
    if (result != TCL_OK) {
        return result;
    }
    if (namespacePtr == NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
	        "unknown namespace \"", Tcl_GetString(objv[2]),

		"\" in inscope namespace command", (char *) NULL);
        return TCL_ERROR;
    }

    /*
     * Make the specified namespace the current namespace.
     */
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
     * Execute the command. If there is just one argument, just treat it as
     * a script and evaluate it. Otherwise, create a list from the arguments
     * after the first one, then concatenate the first argument and the list
     * of extra arguments to form the command to evaluate.
     */

    if (objc == 4) {
        result = Tcl_EvalObj(interp, objv[3]);
    } else {
	Tcl_Obj *concatObjv[2];
	register Tcl_Obj *listPtr, *cmdObjPtr;
	
        listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
        for (i = 4;  i < objc;  i++) {
	    result = Tcl_ListObjAppendElement(interp, listPtr, objv[i]);
            if (result != TCL_OK) {
                Tcl_DecrRefCount(listPtr); /* free unneeded obj */
                return result;
            }
        }

	concatObjv[0] = objv[3];
	concatObjv[1] = listPtr;
	cmdObjPtr = Tcl_ConcatObj(2, concatObjv);
        result = Tcl_EvalObj(interp, cmdObjPtr);
	
	Tcl_DecrRefCount(cmdObjPtr);  /* we're done with the cmd object */
	Tcl_DecrRefCount(listPtr);    /* we're done with the list object */
    }
    if (result == TCL_ERROR) {
        char msg[256];
	
        sprintf(msg,
	    "\n    (in namespace inscope \"%.200s\" script line %d)",
            namespacePtr->fullName, interp->errorLine);
        Tcl_AddObjErrorInfo(interp, msg, -1);
    }








|
















|
<
<



|







3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283


3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
     * Execute the command. If there is just one argument, just treat it as
     * a script and evaluate it. Otherwise, create a list from the arguments
     * after the first one, then concatenate the first argument and the list
     * of extra arguments to form the command to evaluate.
     */

    if (objc == 4) {
        result = Tcl_EvalObjEx(interp, objv[3], 0);
    } else {
	Tcl_Obj *concatObjv[2];
	register Tcl_Obj *listPtr, *cmdObjPtr;
	
        listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
        for (i = 4;  i < objc;  i++) {
	    result = Tcl_ListObjAppendElement(interp, listPtr, objv[i]);
            if (result != TCL_OK) {
                Tcl_DecrRefCount(listPtr); /* free unneeded obj */
                return result;
            }
        }

	concatObjv[0] = objv[3];
	concatObjv[1] = listPtr;
	cmdObjPtr = Tcl_ConcatObj(2, concatObjv);
        result = Tcl_EvalObjEx(interp, cmdObjPtr, TCL_EVAL_DIRECT);


	Tcl_DecrRefCount(listPtr);    /* we're done with the list object */
    }
    if (result == TCL_ERROR) {
        char msg[256 + TCL_INTEGER_SPACE];
	
        sprintf(msg,
	    "\n    (in namespace inscope \"%.200s\" script line %d)",
            namespacePtr->fullName, interp->errorLine);
        Tcl_AddObjErrorInfo(interp, msg, -1);
    }

3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
        Tcl_WrongNumArgs(interp, 2, objv, "name");
        return TCL_ERROR;
    }

    command = Tcl_GetCommandFromObj(interp, objv[2]);
    if (command == (Tcl_Command) NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"invalid command name \"",
		Tcl_GetStringFromObj(objv[2], (int *) NULL),
		"\"", (char *) NULL);
	return TCL_ERROR;
    }
    origCommand = TclGetOriginalCommand(command);
    if (origCommand == (Tcl_Command) NULL) {
	/*
	 * The specified command isn't an imported command. Return the







|
<







3342
3343
3344
3345
3346
3347
3348
3349

3350
3351
3352
3353
3354
3355
3356
        Tcl_WrongNumArgs(interp, 2, objv, "name");
        return TCL_ERROR;
    }

    command = Tcl_GetCommandFromObj(interp, objv[2]);
    if (command == (Tcl_Command) NULL) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"invalid command name \"", Tcl_GetString(objv[2]),

		"\"", (char *) NULL);
	return TCL_ERROR;
    }
    origCommand = TclGetOriginalCommand(command);
    if (origCommand == (Tcl_Command) NULL) {
	/*
	 * The specified command isn't an imported command. Return the
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
    } else if (objc == 3) {
	result = GetNamespaceFromObj(interp, objv[2], &nsPtr);
        if (result != TCL_OK) {
            return result;
        }
        if (nsPtr == NULL) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "unknown namespace \"",
		    Tcl_GetStringFromObj(objv[2], (int *) NULL),
		    "\" in namespace parent command", (char *) NULL);
            return TCL_ERROR;
        }
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?name?");
        return TCL_ERROR;
    }







|
<







3401
3402
3403
3404
3405
3406
3407
3408

3409
3410
3411
3412
3413
3414
3415
    } else if (objc == 3) {
	result = GetNamespaceFromObj(interp, objv[2], &nsPtr);
        if (result != TCL_OK) {
            return result;
        }
        if (nsPtr == NULL) {
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "unknown namespace \"", Tcl_GetString(objv[2]),

		    "\" in namespace parent command", (char *) NULL);
            return TCL_ERROR;
        }
    } else {
        Tcl_WrongNumArgs(interp, 2, objv, "?name?");
        return TCL_ERROR;
    }
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
    }

    /*
     * Find the end of the string, then work backward and find
     * the start of the last "::" qualifier.
     */

    name = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    for (p = name;  *p != '\0';  p++) {
	/* empty body */
    }
    while (--p >= name) {
        if ((*p == ':') && (p > name) && (*(p-1) == ':')) {
	    p -= 2;		/* back up over the :: */
	    while ((p >= name) && (*p == ':')) {







|







3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
    }

    /*
     * Find the end of the string, then work backward and find
     * the start of the last "::" qualifier.
     */

    name = Tcl_GetString(objv[2]);
    for (p = name;  *p != '\0';  p++) {
	/* empty body */
    }
    while (--p >= name) {
        if ((*p == ':') && (p > name) && (*(p-1) == ':')) {
	    p -= 2;		/* back up over the :: */
	    while ((p >= name) && (*p == ':')) {
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
    }

    /*
     * Find the end of the string, then work backward and find the
     * last "::" qualifier.
     */

    name = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    for (p = name;  *p != '\0';  p++) {
	/* empty body */
    }
    while (--p > name) {
        if ((*p == ':') && (*(p-1) == ':')) {
            p++;		/* just after the last "::" */
            break;







|







3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
    }

    /*
     * Find the end of the string, then work backward and find the
     * last "::" qualifier.
     */

    name = Tcl_GetString(objv[2]);
    for (p = name;  *p != '\0';  p++) {
	/* empty body */
    }
    while (--p > name) {
        if ((*p == ':') && (*(p-1) == ':')) {
            p++;		/* just after the last "::" */
            break;
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502

    /*
     * Look for a flag controlling the lookup.
     */

    argIndex = 2;
    lookup = 0;			/* assume command lookup by default */
    arg = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    if (*arg == '-') {
	if (strncmp(arg, "-command", 8) == 0) {
	    lookup = 0;
	} else if (strncmp(arg, "-variable", 9) == 0) {
	    lookup = 1;
	} else {
	    goto badArgs;







|







3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611

    /*
     * Look for a flag controlling the lookup.
     */

    argIndex = 2;
    lookup = 0;			/* assume command lookup by default */
    arg = Tcl_GetString(objv[2]);
    if (*arg == '-') {
	if (strncmp(arg, "-command", 8) == 0) {
	    lookup = 0;
	} else if (strncmp(arg, "-variable", 9) == 0) {
	    lookup = 1;
	} else {
	    goto badArgs;
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
        if (cmd == (Tcl_Command) NULL) {	
            return TCL_OK;	/* cmd not found, just return (no error) */
        }
	Tcl_GetCommandFullName(interp, cmd, Tcl_GetObjResult(interp));
        break;

    case 1:			/* -variable */
        arg = Tcl_GetStringFromObj(objv[argIndex], (int *) NULL);
	variable = Tcl_FindNamespaceVar(interp, arg, (Tcl_Namespace *) NULL,
		/*flags*/ 0);
        if (variable != (Tcl_Var) NULL) {
            Tcl_GetVariableFullName(interp, variable, Tcl_GetObjResult(interp));
        }
        break;
    }







|







3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
        if (cmd == (Tcl_Command) NULL) {	
            return TCL_OK;	/* cmd not found, just return (no error) */
        }
	Tcl_GetCommandFullName(interp, cmd, Tcl_GetObjResult(interp));
        break;

    case 1:			/* -variable */
        arg = Tcl_GetString(objv[argIndex]);
	variable = Tcl_FindNamespaceVar(interp, arg, (Tcl_Namespace *) NULL,
		/*flags*/ 0);
        if (variable != (Tcl_Var) NULL) {
            Tcl_GetVariableFullName(interp, variable, Tcl_GetObjResult(interp));
        }
        break;
    }
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
				 * reporting if not NULL. */
    register Tcl_Obj *objPtr;	/* The object to convert. */
{
    register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
    char *name, *dummy;
    Namespace *nsPtr, *dummy1Ptr, *dummy2Ptr;
    register ResolvedNsName *resNamePtr;
    int flags, result;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    name = objPtr->bytes;
    if (name == NULL) {
	name = Tcl_GetStringFromObj(objPtr, (int *) NULL);
    }

    /*
     * Look for the namespace "name" in the current namespace. If there is
     * an error parsing the (possibly qualified) name, return an error.
     * If the namespace isn't found, we convert the object to an nsName
     * object with a NULL ResolvedNsName* internal rep.
     */

    flags = ((interp != NULL)? TCL_LEAVE_ERR_MSG : 0) | FIND_ONLY_NS;
    result = TclGetNamespaceForQualName(interp, name, (Namespace *) NULL,
            flags, &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy);
    if (result != TCL_OK) {
        return result;
    }

    /*
     * If we found a namespace, then create a new ResolvedNsName structure
     * that holds a reference to it.
     */

    if (nsPtr != NULL) {







<







|









<
|
|
<
<
<







3754
3755
3756
3757
3758
3759
3760

3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777

3778
3779



3780
3781
3782
3783
3784
3785
3786
				 * reporting if not NULL. */
    register Tcl_Obj *objPtr;	/* The object to convert. */
{
    register Tcl_ObjType *oldTypePtr = objPtr->typePtr;
    char *name, *dummy;
    Namespace *nsPtr, *dummy1Ptr, *dummy2Ptr;
    register ResolvedNsName *resNamePtr;


    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    name = objPtr->bytes;
    if (name == NULL) {
	name = Tcl_GetString(objPtr);
    }

    /*
     * Look for the namespace "name" in the current namespace. If there is
     * an error parsing the (possibly qualified) name, return an error.
     * If the namespace isn't found, we convert the object to an nsName
     * object with a NULL ResolvedNsName* internal rep.
     */


    TclGetNamespaceForQualName(interp, name, (Namespace *) NULL,
            FIND_ONLY_NS, &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy);




    /*
     * If we found a namespace, then create a new ResolvedNsName structure
     * that holds a reference to it.
     */

    if (nsPtr != NULL) {

Changes to generic/tclNotify.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
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
/* 
 * tclNotify.c --
 *
 *	This file implements the generic portion of the Tcl notifier.
 *	The notifier is lowest-level part of the event system.  It
 *	manages an event queue that holds Tcl_Event structures.  The
 *	platform specific portion of the notifier is defined in the
 *	tcl*Notify.c files in each platform directory.
 *
 * 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.
 *
 * SCCS: @(#) tclNotify.c 1.16 97/09/15 15:12:52
 */

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

/*
 * The following static indicates whether this module has been initialized.
 */

static int initialized = 0;

/*
 * For each event source (created with Tcl_CreateEventSource) there
 * is a structure of the following type:
 */

typedef struct EventSource {
    Tcl_EventSetupProc *setupProc;
    Tcl_EventCheckProc *checkProc;
    ClientData clientData;
    struct EventSource *nextPtr;
} EventSource;

/*
 * The following structure keeps track of the state of the notifier.
 * The first three elements keep track of the event queue.  In addition to
 * the first (next to be serviced) and last events in the queue, we keep
 * track of a "marker" event.  This provides a simple priority mechanism
 * whereby events can be inserted at the front of the queue but behind all
 * other high-priority events already in the queue (this is used for things
 * like a sequence of Enter and Leave events generated during a grab in
 * Tk).


 */

static struct {
    Tcl_Event *firstEventPtr;	/* First pending event, or NULL if none. */
    Tcl_Event *lastEventPtr;	/* Last pending event, or NULL if none. */
    Tcl_Event *markerEventPtr;	/* Last high-priority event in queue, or
				 * NULL if none. */


    int serviceMode;		/* One of TCL_SERVICE_NONE or
				 * TCL_SERVICE_ALL. */
    int blockTimeSet;		/* 0 means there is no maximum block
				 * time:  block forever. */
    Tcl_Time blockTime;		/* If blockTimeSet is 1, gives the
				 * maximum elapsed time for the next block. */
    int inTraversal;		/* 1 if Tcl_SetMaxBlockTime is being
				 * called during an event source traversal. */
    EventSource *firstEventSourcePtr;
				/* Pointer to first event source in
				 * global list of event sources. */


} notifier;








/*
 * Declarations for functions used in this file.



 */

static void	InitNotifier _ANSI_ARGS_((void));

static void	NotifierExitHandler _ANSI_ARGS_((ClientData clientData));







/*
 *----------------------------------------------------------------------
 *
 * InitNotifier --
 *
 *	This routine is called to initialize the notifier module.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates an exit handler and initializes static data.
 *
 *----------------------------------------------------------------------
 */

static void
InitNotifier()
{

    initialized = 1;

    memset(&notifier, 0, sizeof(notifier));



    notifier.serviceMode = TCL_SERVICE_NONE;
    Tcl_CreateExitHandler(NotifierExitHandler, NULL);

}

/*
 *----------------------------------------------------------------------
 *
 * NotifierExitHandler --
 *
 *	This routine is called during Tcl finalization.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Clears the notifier intialization flag.

 *
 *----------------------------------------------------------------------
 */

static void
NotifierExitHandler(clientData)



    ClientData clientData;  /* Not used. */

{









    initialized = 0;

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateEventSource --
 *
 *	This procedure is invoked to create a new source of events.
 *	The source is identified by a procedure that gets invoked
 *	during Tcl_DoOneEvent to check for events on that source
 *	and queue them.
 *
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	SetupProc and checkProc will be invoked each time that Tcl_DoOneEvent
 *	runs out of things to do.  SetupProc will be invoked before
 *	Tcl_DoOneEvent calls select or whatever else it uses to wait
 *	for events.  SetupProc typically calls functions like Tcl_WatchFile
 *	or Tcl_SetMaxBlockTime to indicate what to wait for.
 *
 *	CheckProc is called after select or whatever operation was actually
 *	used to wait.  It figures out whether anything interesting actually
 *	happened (e.g. by calling Tcl_FileReady), and then calls
 *	Tcl_QueueEvent to queue any events that are ready.
 *
 *	Each of these procedures is passed two arguments, e.g.
 *		(*checkProc)(ClientData clientData, int flags));
 *	ClientData is the same as the clientData argument here, and flags
 *	is a combination of things like TCL_FILE_EVENTS that indicates
 *	what events are of interest:  setupProc and checkProc use flags










>




|





<
<
<
<
<
<













|
|
|
|
|
|
|
|
>
>


|




>
>










|
>
>
|
>
>
>
>
>

>
>

<
>
>
>


|
>
|
>
>
>

>
>




|

|
>





|




|
|

>
|
>
|
>
>
>
|
|
>





|

|
>


|


|
>




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




















|
|



|







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
/* 
 * tclNotify.c --
 *
 *	This file implements the generic portion of the Tcl notifier.
 *	The notifier is lowest-level part of the event system.  It
 *	manages an event queue that holds Tcl_Event structures.  The
 *	platform specific portion of the notifier is defined in the
 *	tcl*Notify.c files in each platform directory.
 *
 * Copyright (c) 1995-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: tclNotify.c,v 1.1.2.9 1999/04/14 00:33:25 surles Exp $
 */

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







/*
 * For each event source (created with Tcl_CreateEventSource) there
 * is a structure of the following type:
 */

typedef struct EventSource {
    Tcl_EventSetupProc *setupProc;
    Tcl_EventCheckProc *checkProc;
    ClientData clientData;
    struct EventSource *nextPtr;
} EventSource;

/*
 * The following structure keeps track of the state of the notifier on a
 * per-thread basis. The first three elements keep track of the event queue.
 * In addition to the first (next to be serviced) and last events in the queue,
 * we keep track of a "marker" event.  This provides a simple priority
 * mechanism whereby events can be inserted at the front of the queue but
 * behind all other high-priority events already in the queue (this is used for
 * things like a sequence of Enter and Leave events generated during a grab in
 * Tk).  These elements are protected by the queueMutex so that any thread
 * can queue an event on any notifier.  Note that all of the values in this
 * structure will be initialized to 0.
 */

typedef struct ThreadSpecificData {
    Tcl_Event *firstEventPtr;	/* First pending event, or NULL if none. */
    Tcl_Event *lastEventPtr;	/* Last pending event, or NULL if none. */
    Tcl_Event *markerEventPtr;	/* Last high-priority event in queue, or
				 * NULL if none. */
    Tcl_Mutex queueMutex;	/* Mutex to protect access to the previous
				 * three fields. */
    int serviceMode;		/* One of TCL_SERVICE_NONE or
				 * TCL_SERVICE_ALL. */
    int blockTimeSet;		/* 0 means there is no maximum block
				 * time:  block forever. */
    Tcl_Time blockTime;		/* If blockTimeSet is 1, gives the
				 * maximum elapsed time for the next block. */
    int inTraversal;		/* 1 if Tcl_SetMaxBlockTime is being
				 * called during an event source traversal. */
    EventSource *firstEventSourcePtr;
				/* Pointer to first event source in
				 * list of event sources for this thread. */
    Tcl_ThreadId threadId;	/* Thread that owns this notifier instance. */
    ClientData clientData;	/* Opaque handle for platform specific
				 * notifier. */
    struct ThreadSpecificData *nextPtr;
				/* Next notifier in global list of notifiers.
				 * Access is controlled by the listLock global
				 * mutex. */
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*

 * Global list of notifiers.  Access to this list is controlled by the
 * listLock mutex.  If this becomes a performance bottleneck, this could
 * be replaced with a hashtable.
 */

static ThreadSpecificData *firstNotifierPtr;
TCL_DECLARE_MUTEX(listLock)

/*
 * Declarations for routines used only in this file.
 */

static void		QueueEvent _ANSI_ARGS_((ThreadSpecificData *tsdPtr,
			    Tcl_Event* evPtr, Tcl_QueuePosition position));

/*
 *----------------------------------------------------------------------
 *
 * TclInitNotifier --
 *
 *	Initialize the thread local data structures for the notifier
 *	subsystem.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Adds the current thread to the global list of notifiers.
 *
 *----------------------------------------------------------------------
 */

void
TclInitNotifier()
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    Tcl_MutexLock(&listLock);

    tsdPtr->threadId = Tcl_GetCurrentThread();
    tsdPtr->clientData = Tcl_InitNotifier();
    tsdPtr->nextPtr = firstNotifierPtr;
    firstNotifierPtr = tsdPtr;

    Tcl_MutexUnlock(&listLock);
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeNotifier --
 *
 *	Finalize the thread local data structures for the notifier
 *	subsystem.
 *
 * Results:
 *	None.	
 *
 * Side effects:
 *	Removes the notifier associated with the current thread from
 *	the global notifier list.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeNotifier()
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    ThreadSpecificData **prevPtrPtr;

    Tcl_MutexLock(&listLock);

    Tcl_FinalizeNotifier(tsdPtr->clientData);
    TclFinalizeMutex(&(tsdPtr->queueMutex));
    for (prevPtrPtr = &firstNotifierPtr; *prevPtrPtr != NULL;
	 prevPtrPtr = &((*prevPtrPtr)->nextPtr)) {
	if (*prevPtrPtr == tsdPtr) {
	    *prevPtrPtr = tsdPtr->nextPtr;
	    break;
	}
    }

    Tcl_MutexUnlock(&listLock);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateEventSource --
 *
 *	This procedure is invoked to create a new source of events.
 *	The source is identified by a procedure that gets invoked
 *	during Tcl_DoOneEvent to check for events on that source
 *	and queue them.
 *
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	SetupProc and checkProc will be invoked each time that Tcl_DoOneEvent
 *	runs out of things to do.  SetupProc will be invoked before
 *	Tcl_DoOneEvent calls select or whatever else it uses to wait
 *	for events.  SetupProc typically calls functions like
 *	Tcl_SetMaxBlockTime to indicate what to wait for.
 *
 *	CheckProc is called after select or whatever operation was actually
 *	used to wait.  It figures out whether anything interesting actually
 *	happened (e.g. by calling Tcl_AsyncReady), and then calls
 *	Tcl_QueueEvent to queue any events that are ready.
 *
 *	Each of these procedures is passed two arguments, e.g.
 *		(*checkProc)(ClientData clientData, int flags));
 *	ClientData is the same as the clientData argument here, and flags
 *	is a combination of things like TCL_FILE_EVENTS that indicates
 *	what events are of interest:  setupProc and checkProc use flags
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
    Tcl_EventSetupProc *setupProc;	/* Procedure to invoke to figure out
					 * what to wait for. */
    Tcl_EventCheckProc *checkProc;	/* Procedure to call after waiting
					 * to see what happened. */
    ClientData clientData;		/* One-word argument to pass to
					 * setupProc and checkProc. */
{

    EventSource *sourcePtr;

    if (!initialized) {
	InitNotifier();
    }

    sourcePtr = (EventSource *) ckalloc(sizeof(EventSource));
    sourcePtr->setupProc = setupProc;
    sourcePtr->checkProc = checkProc;
    sourcePtr->clientData = clientData;
    sourcePtr->nextPtr = notifier.firstEventSourcePtr;
    notifier.firstEventSourcePtr = sourcePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DeleteEventSource --
 *







>
|

<
<
<
<
<



|
|







201
202
203
204
205
206
207
208
209
210





211
212
213
214
215
216
217
218
219
220
221
222
    Tcl_EventSetupProc *setupProc;	/* Procedure to invoke to figure out
					 * what to wait for. */
    Tcl_EventCheckProc *checkProc;	/* Procedure to call after waiting
					 * to see what happened. */
    ClientData clientData;		/* One-word argument to pass to
					 * setupProc and checkProc. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    EventSource *sourcePtr = (EventSource *) ckalloc(sizeof(EventSource));






    sourcePtr->setupProc = setupProc;
    sourcePtr->checkProc = checkProc;
    sourcePtr->clientData = clientData;
    sourcePtr->nextPtr = tsdPtr->firstEventSourcePtr;
    tsdPtr->firstEventSourcePtr = sourcePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DeleteEventSource --
 *
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
    Tcl_EventSetupProc *setupProc;	/* Procedure to invoke to figure out
					 * what to wait for. */
    Tcl_EventCheckProc *checkProc;	/* Procedure to call after waiting
					 * to see what happened. */
    ClientData clientData;		/* One-word argument to pass to
					 * setupProc and checkProc. */
{

    EventSource *sourcePtr, *prevPtr;

    for (sourcePtr = notifier.firstEventSourcePtr, prevPtr = NULL;
	    sourcePtr != NULL;
	    prevPtr = sourcePtr, sourcePtr = sourcePtr->nextPtr) {
	if ((sourcePtr->setupProc != setupProc)
		|| (sourcePtr->checkProc != checkProc)
		|| (sourcePtr->clientData != clientData)) {
	    continue;
	}
	if (prevPtr == NULL) {
	    notifier.firstEventSourcePtr = sourcePtr->nextPtr;
	} else {
	    prevPtr->nextPtr = sourcePtr->nextPtr;
	}
	ckfree((char *) sourcePtr);
	return;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_QueueEvent --
 *
 *	Insert an event into the Tk event queue at one of three
 *	positions: the head, the tail, or before a floating marker.
 *	Events inserted before the marker will be processed in
 *	first-in-first-out order, but before any events inserted at
 *	the tail of the queue.  Events inserted at the head of the
 *	queue will be processed in last-in-first-out order.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *







>


|








|













|
<
<
<
|
<







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
    Tcl_EventSetupProc *setupProc;	/* Procedure to invoke to figure out
					 * what to wait for. */
    Tcl_EventCheckProc *checkProc;	/* Procedure to call after waiting
					 * to see what happened. */
    ClientData clientData;		/* One-word argument to pass to
					 * setupProc and checkProc. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    EventSource *sourcePtr, *prevPtr;

    for (sourcePtr = tsdPtr->firstEventSourcePtr, prevPtr = NULL;
	    sourcePtr != NULL;
	    prevPtr = sourcePtr, sourcePtr = sourcePtr->nextPtr) {
	if ((sourcePtr->setupProc != setupProc)
		|| (sourcePtr->checkProc != checkProc)
		|| (sourcePtr->clientData != clientData)) {
	    continue;
	}
	if (prevPtr == NULL) {
	    tsdPtr->firstEventSourcePtr = sourcePtr->nextPtr;
	} else {
	    prevPtr->nextPtr = sourcePtr->nextPtr;
	}
	ckfree((char *) sourcePtr);
	return;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_QueueEvent --
 *
 *	Queue an event on the event queue associated with the



 *	current thread.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
256
257
258
259
260
261
262



263















264













265



266



















































267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346



347
348
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
				 * with malloc (ckalloc), and it becomes
				 * the property of the event queue.  It
				 * will be freed after the event has been
				 * handled. */
    Tcl_QueuePosition position;	/* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,
				 * TCL_QUEUE_MARK. */
{



    if (!initialized) {















	InitNotifier();













    }























































    if (position == TCL_QUEUE_TAIL) {
	/*
	 * Append the event on the end of the queue.
	 */

	evPtr->nextPtr = NULL;
	if (notifier.firstEventPtr == NULL) {
	    notifier.firstEventPtr = evPtr;
	} else {
	    notifier.lastEventPtr->nextPtr = evPtr;
	}
	notifier.lastEventPtr = evPtr;
    } else if (position == TCL_QUEUE_HEAD) {
	/*
	 * Push the event on the head of the queue.
	 */

	evPtr->nextPtr = notifier.firstEventPtr;
	if (notifier.firstEventPtr == NULL) {
	    notifier.lastEventPtr = evPtr;
	}	    
	notifier.firstEventPtr = evPtr;
    } else if (position == TCL_QUEUE_MARK) {
	/*
	 * Insert the event after the current marker event and advance
	 * the marker to the new event.
	 */

	if (notifier.markerEventPtr == NULL) {
	    evPtr->nextPtr = notifier.firstEventPtr;
	    notifier.firstEventPtr = evPtr;
	} else {
	    evPtr->nextPtr = notifier.markerEventPtr->nextPtr;
	    notifier.markerEventPtr->nextPtr = evPtr;
	}
	notifier.markerEventPtr = evPtr;
	if (evPtr->nextPtr == NULL) {
	    notifier.lastEventPtr = evPtr;
	}
    }

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DeleteEvents --
 *
 *	Calls a procedure for each event in the queue and deletes those
 *	for which the procedure returns 1. Events for which the
 *	procedure returns 0 are left in the queue.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Potentially removes one or more events from the event queue.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DeleteEvents(proc, clientData)
    Tcl_EventDeleteProc *proc;		/* The procedure to call. */
    ClientData clientData;    		/* type-specific data. */
{
    Tcl_Event *evPtr, *prevPtr, *hold;

    if (!initialized) {
	InitNotifier();
    }

    for (prevPtr = (Tcl_Event *) NULL, evPtr = notifier.firstEventPtr;
             evPtr != (Tcl_Event *) NULL;
             ) {
        if ((*proc) (evPtr, clientData) == 1) {
            if (notifier.firstEventPtr == evPtr) {
                notifier.firstEventPtr = evPtr->nextPtr;
                if (evPtr->nextPtr == (Tcl_Event *) NULL) {
                    notifier.lastEventPtr = (Tcl_Event *) NULL;
                }



            } else {
                prevPtr->nextPtr = evPtr->nextPtr;
            }
            hold = evPtr;
            evPtr = evPtr->nextPtr;
            ckfree((char *) hold);
        } else {
            prevPtr = evPtr;
            evPtr = evPtr->nextPtr;
        }
    }

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ServiceEvent --
 *
 *	Process one event from the event queue, or invoke an
 *	asynchronous event handler.

 *
 * Results:
 *	The return value is 1 if the procedure actually found an event
 *	to process.  If no processing occurred, then 0 is returned.
 *
 * Side effects:
 *	Invokes all of the event handlers for the highest priority







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

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






|
|

|

|





|
|
|

|






|
|
|

|
|

|

|


>









|
>
















|
<
<
|
|
|



|
|

|

>
>
>











>








|
>







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452


453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
				 * with malloc (ckalloc), and it becomes
				 * the property of the event queue.  It
				 * will be freed after the event has been
				 * handled. */
    Tcl_QueuePosition position;	/* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,
				 * TCL_QUEUE_MARK. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    QueueEvent(tsdPtr, evPtr, position);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ThreadQueueEvent --
 *
 *	Queue an event on the specified thread's event queue.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ThreadQueueEvent(threadId, evPtr, position)
    Tcl_ThreadId threadId;	/* Identifier for thread to use. */
    Tcl_Event* evPtr;		/* Event to add to queue.  The storage
				 * space must have been allocated the caller
				 * with malloc (ckalloc), and it becomes
				 * the property of the event queue.  It
				 * will be freed after the event has been
				 * handled. */
    Tcl_QueuePosition position;	/* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,
				 * TCL_QUEUE_MARK. */
{
    ThreadSpecificData *tsdPtr;

    /*
     * Find the notifier associated with the specified thread.
     */

    Tcl_MutexLock(&listLock);
    for (tsdPtr = firstNotifierPtr; tsdPtr && tsdPtr->threadId != threadId;
	     tsdPtr = tsdPtr->nextPtr) {
	/* Empty loop body. */
    }

    /*
     * Queue the event if there was a notifier associated with the thread.
     */

    if (tsdPtr) {
	QueueEvent(tsdPtr, evPtr, position);
    }
    Tcl_MutexUnlock(&listLock);
}

/*
 *----------------------------------------------------------------------
 *
 * QueueEvent --
 *
 *	Insert an event into the specified thread's event queue at one
 *	of three positions: the head, the tail, or before a floating
 *	marker. Events inserted before the marker will be processed in
 *	first-in-first-out order, but before any events inserted at
 *	the tail of the queue.  Events inserted at the head of the
 *	queue will be processed in last-in-first-out order.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
QueueEvent(tsdPtr, evPtr, position)
    ThreadSpecificData *tsdPtr;	/* Handle to thread local data that indicates
				 * which event queue to use. */
    Tcl_Event* evPtr;		/* Event to add to queue.  The storage
				 * space must have been allocated the caller
				 * with malloc (ckalloc), and it becomes
				 * the property of the event queue.  It
				 * will be freed after the event has been
				 * handled. */
    Tcl_QueuePosition position;	/* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,
				 * TCL_QUEUE_MARK. */
{
    Tcl_MutexLock(&(tsdPtr->queueMutex));
    if (position == TCL_QUEUE_TAIL) {
	/*
	 * Append the event on the end of the queue.
	 */

	evPtr->nextPtr = NULL;
	if (tsdPtr->firstEventPtr == NULL) {
	    tsdPtr->firstEventPtr = evPtr;
	} else {
	    tsdPtr->lastEventPtr->nextPtr = evPtr;
	}
	tsdPtr->lastEventPtr = evPtr;
    } else if (position == TCL_QUEUE_HEAD) {
	/*
	 * Push the event on the head of the queue.
	 */

	evPtr->nextPtr = tsdPtr->firstEventPtr;
	if (tsdPtr->firstEventPtr == NULL) {
	    tsdPtr->lastEventPtr = evPtr;
	}	    
	tsdPtr->firstEventPtr = evPtr;
    } else if (position == TCL_QUEUE_MARK) {
	/*
	 * Insert the event after the current marker event and advance
	 * the marker to the new event.
	 */

	if (tsdPtr->markerEventPtr == NULL) {
	    evPtr->nextPtr = tsdPtr->firstEventPtr;
	    tsdPtr->firstEventPtr = evPtr;
	} else {
	    evPtr->nextPtr = tsdPtr->markerEventPtr->nextPtr;
	    tsdPtr->markerEventPtr->nextPtr = evPtr;
	}
	tsdPtr->markerEventPtr = evPtr;
	if (evPtr->nextPtr == NULL) {
	    tsdPtr->lastEventPtr = evPtr;
	}
    }
    Tcl_MutexUnlock(&(tsdPtr->queueMutex));
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DeleteEvents --
 *
 *	Calls a procedure for each event in the queue and deletes those
 *	for which the procedure returns 1. Events for which the
 *	procedure returns 0 are left in the queue.  Operates on the
 *	queue associated with the current thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Potentially removes one or more events from the event queue.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DeleteEvents(proc, clientData)
    Tcl_EventDeleteProc *proc;		/* The procedure to call. */
    ClientData clientData;    		/* type-specific data. */
{
    Tcl_Event *evPtr, *prevPtr, *hold;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);



    Tcl_MutexLock(&(tsdPtr->queueMutex));
    for (prevPtr = (Tcl_Event *) NULL, evPtr = tsdPtr->firstEventPtr;
             evPtr != (Tcl_Event *) NULL;
             ) {
        if ((*proc) (evPtr, clientData) == 1) {
            if (tsdPtr->firstEventPtr == evPtr) {
                tsdPtr->firstEventPtr = evPtr->nextPtr;
                if (evPtr->nextPtr == (Tcl_Event *) NULL) {
                    tsdPtr->lastEventPtr = prevPtr;
                }
		if (tsdPtr->markerEventPtr == evPtr) {
		    tsdPtr->markerEventPtr = prevPtr;
		}
            } else {
                prevPtr->nextPtr = evPtr->nextPtr;
            }
            hold = evPtr;
            evPtr = evPtr->nextPtr;
            ckfree((char *) hold);
        } else {
            prevPtr = evPtr;
            evPtr = evPtr->nextPtr;
        }
    }
    Tcl_MutexUnlock(&(tsdPtr->queueMutex));
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ServiceEvent --
 *
 *	Process one event from the event queue, or invoke an
 *	asynchronous event handler.  Operates on event queue for
 *	current thread.
 *
 * Results:
 *	The return value is 1 if the procedure actually found an event
 *	to process.  If no processing occurred, then 0 is returned.
 *
 * Side effects:
 *	Invokes all of the event handlers for the highest priority
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
				 * TCL_FILE_EVENTS, TCL_TIMER_EVENTS, or other
				 * flags defined elsewhere.  Events not
				 * matching this will be skipped for processing
				 * later. */
{
    Tcl_Event *evPtr, *prevPtr;
    Tcl_EventProc *proc;

    if (!initialized) {
	InitNotifier();
    }

    /*
     * Asynchronous event handlers are considered to be the highest
     * priority events, and so must be invoked before we process events
     * on the event queue.
     */
    







|
|
<
<







506
507
508
509
510
511
512
513
514


515
516
517
518
519
520
521
				 * TCL_FILE_EVENTS, TCL_TIMER_EVENTS, or other
				 * flags defined elsewhere.  Events not
				 * matching this will be skipped for processing
				 * later. */
{
    Tcl_Event *evPtr, *prevPtr;
    Tcl_EventProc *proc;
    int result;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);



    /*
     * Asynchronous event handlers are considered to be the highest
     * priority events, and so must be invoked before we process events
     * on the event queue.
     */
    
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438



439









440







441
442
443
444
445
446
447
448
449
450

451
452
453

454
455
456
457
458
459
460


461


462


463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
    }

    /*
     * Loop through all the events in the queue until we find one
     * that can actually be handled.
     */


    for (evPtr = notifier.firstEventPtr; evPtr != NULL;
	 evPtr = evPtr->nextPtr) {
	/*
	 * Call the handler for the event.  If it actually handles the
	 * event then free the storage for the event.  There are two
	 * tricky things here, but stemming from the fact that the event
	 * code may be re-entered while servicing the event:
	 *
	 * 1. Set the "proc" field to NULL.  This is a signal to ourselves
	 *    that we shouldn't reexecute the handler if the event loop
	 *    is re-entered.
	 * 2. When freeing the event, must search the queue again from the
	 *    front to find it.  This is because the event queue could
	 *    change almost arbitrarily while handling the event, so we
	 *    can't depend on pointers found now still being valid when
	 *    the handler returns.
	 */

	proc = evPtr->proc;



	evPtr->proc = NULL;









	if ((proc != NULL) && (*proc)(evPtr, flags)) {







	    if (notifier.firstEventPtr == evPtr) {
		notifier.firstEventPtr = evPtr->nextPtr;
		if (evPtr->nextPtr == NULL) {
		    notifier.lastEventPtr = NULL;
		}
		if (notifier.markerEventPtr == evPtr) {
		    notifier.markerEventPtr = NULL;
		}
	    } else {
		for (prevPtr = notifier.firstEventPtr;

		     prevPtr->nextPtr != evPtr; prevPtr = prevPtr->nextPtr) {
		    /* Empty loop body. */
		}

		prevPtr->nextPtr = evPtr->nextPtr;
		if (evPtr->nextPtr == NULL) {
		    notifier.lastEventPtr = prevPtr;
		}
		if (notifier.markerEventPtr == evPtr) {
		    notifier.markerEventPtr = prevPtr;
		}


	    }


	    ckfree((char *) evPtr);


	    return 1;
	} else {
	    /*
	     * The event wasn't actually handled, so we have to restore
	     * the proc field to allow the event to be attempted again.
	     */

	    evPtr->proc = proc;
	}

	/*
	 * The handler for this event asked to defer it.  Just go on to
	 * the next event.
	 */

	continue;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetServiceMode --







>
|




|













>
>
>

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

|

|
|


|
>
|


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









|
<
<
<
<
|
<
<







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
    }

    /*
     * Loop through all the events in the queue until we find one
     * that can actually be handled.
     */

    Tcl_MutexLock(&(tsdPtr->queueMutex));
    for (evPtr = tsdPtr->firstEventPtr; evPtr != NULL;
	 evPtr = evPtr->nextPtr) {
	/*
	 * Call the handler for the event.  If it actually handles the
	 * event then free the storage for the event.  There are two
	 * tricky things here, both stemming from the fact that the event
	 * code may be re-entered while servicing the event:
	 *
	 * 1. Set the "proc" field to NULL.  This is a signal to ourselves
	 *    that we shouldn't reexecute the handler if the event loop
	 *    is re-entered.
	 * 2. When freeing the event, must search the queue again from the
	 *    front to find it.  This is because the event queue could
	 *    change almost arbitrarily while handling the event, so we
	 *    can't depend on pointers found now still being valid when
	 *    the handler returns.
	 */

	proc = evPtr->proc;
	if (proc == NULL) {
	    continue;
	}
	evPtr->proc = NULL;

	/*
	 * Release the lock before calling the event procedure.  This
	 * allows other threads to post events if we enter a recursive
	 * event loop in this thread.  Note that we are making the assumption
	 * that if the proc returns 0, the event is still in the list.
	 */

	Tcl_MutexUnlock(&(tsdPtr->queueMutex));
	result = (*proc)(evPtr, flags);
	Tcl_MutexLock(&(tsdPtr->queueMutex));

	if (result) {
	    /*
	     * The event was processed, so remove it from the queue.
	     */

	    if (tsdPtr->firstEventPtr == evPtr) {
		tsdPtr->firstEventPtr = evPtr->nextPtr;
		if (evPtr->nextPtr == NULL) {
		    tsdPtr->lastEventPtr = NULL;
		}
		if (tsdPtr->markerEventPtr == evPtr) {
		    tsdPtr->markerEventPtr = NULL;
		}
	    } else {
		for (prevPtr = tsdPtr->firstEventPtr;
		     prevPtr && prevPtr->nextPtr != evPtr;
		     prevPtr = prevPtr->nextPtr) {
		    /* Empty loop body. */
		}
		if (prevPtr) {
		    prevPtr->nextPtr = evPtr->nextPtr;
		    if (evPtr->nextPtr == NULL) {
			tsdPtr->lastEventPtr = prevPtr;
		    }
		    if (tsdPtr->markerEventPtr == evPtr) {
			tsdPtr->markerEventPtr = prevPtr;
		    }
		} else {
		    evPtr = NULL;
		}
	    }
	    if (evPtr) {
		ckfree((char *) evPtr);
	    }
	    Tcl_MutexUnlock(&(tsdPtr->queueMutex));
	    return 1;
	} else {
	    /*
	     * The event wasn't actually handled, so we have to restore
	     * the proc field to allow the event to be attempted again.
	     */

	    evPtr->proc = proc;
	}
    }




    Tcl_MutexUnlock(&(tsdPtr->queueMutex));


    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetServiceMode --
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
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetServiceMode()
{
    if (!initialized) {
	InitNotifier();
    }

    return notifier.serviceMode;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetServiceMode --
 *
 *	This routine sets the current service mode of the notifier.
 *
 * Results:
 *	Returns the previous service mode.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_SetServiceMode(mode)
    int mode;			/* New service mode: TCL_SERVICE_ALL or
				 * TCL_SERVICE_NONE */
{
    int oldMode;

    if (!initialized) {
	InitNotifier();
    }

    oldMode = notifier.serviceMode;
    notifier.serviceMode = mode;
    return oldMode;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetMaxBlockTime --
 *
 *	This procedure is invoked by event sources to tell the notifier
 *	how long it may block the next time it blocks.  The timePtr
 *	argument gives a maximum time;  the actual time may be less if
 *	some other event source requested a smaller time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May reduce the length of the next sleep in the notifier.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetMaxBlockTime(timePtr)
    Tcl_Time *timePtr;		/* Specifies a maximum elapsed time for
				 * the next blocking operation in the
				 * event notifier. */
{
    if (!initialized) {
	InitNotifier();
    }

    if (!notifier.blockTimeSet || (timePtr->sec < notifier.blockTime.sec)
	    || ((timePtr->sec == notifier.blockTime.sec)
	    && (timePtr->usec < notifier.blockTime.usec))) {
	notifier.blockTime = *timePtr;
	notifier.blockTimeSet = 1;
    }

    /*
     * If we are called outside an event source traversal, set the
     * timeout immediately.
     */

    if (!notifier.inTraversal) {
	if (notifier.blockTimeSet) {
	    Tcl_SetTimer(&notifier.blockTime);
	} else {
	    Tcl_SetTimer(NULL);
	}
    }
}

/*







|
<
|
|
<







|





|










|
<
<
|
|
|
|

















|








|

|
<
|
<
|
|
|
|
|







|
|
|







637
638
639
640
641
642
643
644

645
646

647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671


672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704

705

706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetServiceMode()
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);


    return tsdPtr->serviceMode;

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetServiceMode --
 *
 *	This routine sets the current service mode of the tsdPtr->
 *
 * Results:
 *	Returns the previous service mode.
 *
 * Side effects:
 *	Invokes the notifier service mode hook procedure.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_SetServiceMode(mode)
    int mode;			/* New service mode: TCL_SERVICE_ALL or
				 * TCL_SERVICE_NONE */
{
    int oldMode;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);



    oldMode = tsdPtr->serviceMode;
    tsdPtr->serviceMode = mode;
    Tcl_ServiceModeHook(mode);
    return oldMode;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetMaxBlockTime --
 *
 *	This procedure is invoked by event sources to tell the notifier
 *	how long it may block the next time it blocks.  The timePtr
 *	argument gives a maximum time;  the actual time may be less if
 *	some other event source requested a smaller time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May reduce the length of the next sleep in the tsdPtr->
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetMaxBlockTime(timePtr)
    Tcl_Time *timePtr;		/* Specifies a maximum elapsed time for
				 * the next blocking operation in the
				 * event tsdPtr-> */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);



    if (!tsdPtr->blockTimeSet || (timePtr->sec < tsdPtr->blockTime.sec)
	    || ((timePtr->sec == tsdPtr->blockTime.sec)
	    && (timePtr->usec < tsdPtr->blockTime.usec))) {
	tsdPtr->blockTime = *timePtr;
	tsdPtr->blockTimeSet = 1;
    }

    /*
     * If we are called outside an event source traversal, set the
     * timeout immediately.
     */

    if (!tsdPtr->inTraversal) {
	if (tsdPtr->blockTimeSet) {
	    Tcl_SetTimer(&tsdPtr->blockTime);
	} else {
	    Tcl_SetTimer(NULL);
	}
    }
}

/*
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
				 * TCL_WINDOW_EVENTS, TCL_FILE_EVENTS,
				 * TCL_TIMER_EVENTS, TCL_IDLE_EVENTS, or
				 * others defined by event sources. */
{
    int result = 0, oldMode;
    EventSource *sourcePtr;
    Tcl_Time *timePtr;

    if (!initialized) {
	InitNotifier();
    }

    /*
     * The first thing we do is to service any asynchronous event
     * handlers.
     */
    
    if (Tcl_AsyncReady()) {







|
<
<
<







754
755
756
757
758
759
760
761



762
763
764
765
766
767
768
				 * TCL_WINDOW_EVENTS, TCL_FILE_EVENTS,
				 * TCL_TIMER_EVENTS, TCL_IDLE_EVENTS, or
				 * others defined by event sources. */
{
    int result = 0, oldMode;
    EventSource *sourcePtr;
    Tcl_Time *timePtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);




    /*
     * The first thing we do is to service any asynchronous event
     * handlers.
     */
    
    if (Tcl_AsyncReady()) {
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
    }

    /*
     * Set the service mode to none so notifier event routines won't
     * try to service events recursively.
     */

    oldMode = notifier.serviceMode;
    notifier.serviceMode = TCL_SERVICE_NONE;

    /*
     * The core of this procedure is an infinite loop, even though
     * we only service one event.  The reason for this is that we
     * may be processing events that don't do anything inside of Tcl.
     */








|
|







779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
    }

    /*
     * Set the service mode to none so notifier event routines won't
     * try to service events recursively.
     */

    oldMode = tsdPtr->serviceMode;
    tsdPtr->serviceMode = TCL_SERVICE_NONE;

    /*
     * The core of this procedure is an infinite loop, even though
     * we only service one event.  The reason for this is that we
     * may be processing events that don't do anything inside of Tcl.
     */

683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739

	/*
	 * If TCL_DONT_WAIT is set, be sure to poll rather than
	 * blocking, otherwise reset the block time to infinity.
	 */

	if (flags & TCL_DONT_WAIT) {
	    notifier.blockTime.sec = 0;
	    notifier.blockTime.usec = 0;
	    notifier.blockTimeSet = 1;
	} else {
	    notifier.blockTimeSet = 0;
	}

	/*
	 * Set up all the event sources for new events.  This will
	 * cause the block time to be updated if necessary.
	 */

	notifier.inTraversal = 1;
	for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
	     sourcePtr = sourcePtr->nextPtr) {
	    if (sourcePtr->setupProc) {
		(sourcePtr->setupProc)(sourcePtr->clientData, flags);
	    }
	}
	notifier.inTraversal = 0;

	if ((flags & TCL_DONT_WAIT) || notifier.blockTimeSet) {
	    timePtr = &notifier.blockTime;
	} else {
	    timePtr = NULL;
	}

	/*
	 * Wait for a new event or a timeout.  If Tcl_WaitForEvent
	 * returns -1, we should abort Tcl_DoOneEvent.
	 */

	result = Tcl_WaitForEvent(timePtr);
	if (result < 0) {
	    result = 0;
	    break;
	}

	/*
	 * Check all the event sources for new events.
	 */

	for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
	     sourcePtr = sourcePtr->nextPtr) {
	    if (sourcePtr->checkProc) {
		(sourcePtr->checkProc)(sourcePtr->clientData, flags);
	    }
	}

	/*







|
|
|

|







|
|





|

|
|



















|







816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872

	/*
	 * If TCL_DONT_WAIT is set, be sure to poll rather than
	 * blocking, otherwise reset the block time to infinity.
	 */

	if (flags & TCL_DONT_WAIT) {
	    tsdPtr->blockTime.sec = 0;
	    tsdPtr->blockTime.usec = 0;
	    tsdPtr->blockTimeSet = 1;
	} else {
	    tsdPtr->blockTimeSet = 0;
	}

	/*
	 * Set up all the event sources for new events.  This will
	 * cause the block time to be updated if necessary.
	 */

	tsdPtr->inTraversal = 1;
	for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL;
	     sourcePtr = sourcePtr->nextPtr) {
	    if (sourcePtr->setupProc) {
		(sourcePtr->setupProc)(sourcePtr->clientData, flags);
	    }
	}
	tsdPtr->inTraversal = 0;

	if ((flags & TCL_DONT_WAIT) || tsdPtr->blockTimeSet) {
	    timePtr = &tsdPtr->blockTime;
	} else {
	    timePtr = NULL;
	}

	/*
	 * Wait for a new event or a timeout.  If Tcl_WaitForEvent
	 * returns -1, we should abort Tcl_DoOneEvent.
	 */

	result = Tcl_WaitForEvent(timePtr);
	if (result < 0) {
	    result = 0;
	    break;
	}

	/*
	 * Check all the event sources for new events.
	 */

	for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL;
	     sourcePtr = sourcePtr->nextPtr) {
	    if (sourcePtr->checkProc) {
		(sourcePtr->checkProc)(sourcePtr->clientData, flags);
	    }
	}

	/*
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792

	if (result) {
	    break;
	}

    }

    notifier.serviceMode = oldMode;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ServiceAll --







|







911
912
913
914
915
916
917
918
919
920
921
922
923
924
925

	if (result) {
	    break;
	}

    }

    tsdPtr->serviceMode = oldMode;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ServiceAll --
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876








































 */

int
Tcl_ServiceAll()
{
    int result = 0;
    EventSource *sourcePtr;

    if (!initialized) {
	InitNotifier();
    }

    if (notifier.serviceMode == TCL_SERVICE_NONE) {
	return result;
    }

    /*
     * We need to turn off event servicing like we to in Tcl_DoOneEvent,
     * to avoid recursive calls.
     */
    
    notifier.serviceMode = TCL_SERVICE_NONE;

    /*
     * Check async handlers first.
     */

    if (Tcl_AsyncReady()) {
	(void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0);
    }

    /*
     * Make a single pass through all event sources, queued events,
     * and idle handlers.  Note that we wait to update the notifier
     * timer until the end so we can avoid multiple changes.
     */

    notifier.inTraversal = 1;
    notifier.blockTimeSet = 0;

    for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
	 sourcePtr = sourcePtr->nextPtr) {
	if (sourcePtr->setupProc) {
	    (sourcePtr->setupProc)(sourcePtr->clientData, TCL_ALL_EVENTS);
	}
    }
    for (sourcePtr = notifier.firstEventSourcePtr; sourcePtr != NULL;
	 sourcePtr = sourcePtr->nextPtr) {
	if (sourcePtr->checkProc) {
	    (sourcePtr->checkProc)(sourcePtr->clientData, TCL_ALL_EVENTS);
	}
    }

    while (Tcl_ServiceEvent(0)) {
	result = 1;
    }
    if (TclServiceIdle()) {
	result = 1;
    }

    if (!notifier.blockTimeSet) {
	Tcl_SetTimer(NULL);
    } else {
	Tcl_SetTimer(&notifier.blockTime);
    }
    notifier.inTraversal = 0;
    notifier.serviceMode = TCL_SERVICE_ALL;
    return result;
}















































|
<
<
|
<
|








|















|
|

|





|













|


|

|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
941
942
943
944
945
946
947
948


949

950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
 */

int
Tcl_ServiceAll()
{
    int result = 0;
    EventSource *sourcePtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);




    if (tsdPtr->serviceMode == TCL_SERVICE_NONE) {
	return result;
    }

    /*
     * We need to turn off event servicing like we to in Tcl_DoOneEvent,
     * to avoid recursive calls.
     */
    
    tsdPtr->serviceMode = TCL_SERVICE_NONE;

    /*
     * Check async handlers first.
     */

    if (Tcl_AsyncReady()) {
	(void) Tcl_AsyncInvoke((Tcl_Interp *) NULL, 0);
    }

    /*
     * Make a single pass through all event sources, queued events,
     * and idle handlers.  Note that we wait to update the notifier
     * timer until the end so we can avoid multiple changes.
     */

    tsdPtr->inTraversal = 1;
    tsdPtr->blockTimeSet = 0;

    for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL;
	 sourcePtr = sourcePtr->nextPtr) {
	if (sourcePtr->setupProc) {
	    (sourcePtr->setupProc)(sourcePtr->clientData, TCL_ALL_EVENTS);
	}
    }
    for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL;
	 sourcePtr = sourcePtr->nextPtr) {
	if (sourcePtr->checkProc) {
	    (sourcePtr->checkProc)(sourcePtr->clientData, TCL_ALL_EVENTS);
	}
    }

    while (Tcl_ServiceEvent(0)) {
	result = 1;
    }
    if (TclServiceIdle()) {
	result = 1;
    }

    if (!tsdPtr->blockTimeSet) {
	Tcl_SetTimer(NULL);
    } else {
	Tcl_SetTimer(&tsdPtr->blockTime);
    }
    tsdPtr->inTraversal = 0;
    tsdPtr->serviceMode = TCL_SERVICE_ALL;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ThreadAlert --
 *
 *	This function wakes up the notifier associated with the
 *	specified thread (if there is one).  
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ThreadAlert(threadId)
    Tcl_ThreadId threadId;	/* Identifier for thread to use. */
{
    ThreadSpecificData *tsdPtr;

    /*
     * Find the notifier associated with the specified thread.
     * Note that we need to hold the listLock while calling
     * Tcl_AlertNotifier to avoid a race condition where
     * the specified thread might destroy its notifier.
     */

    Tcl_MutexLock(&listLock);
    for (tsdPtr = firstNotifierPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
	if (tsdPtr->threadId == threadId) {
	    Tcl_AlertNotifier(tsdPtr->clientData);
	    break;
	}
    }
    Tcl_MutexUnlock(&listLock);
}

Changes to generic/tclObj.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
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
/* 
 * tclObj.c --
 *
 *	This file contains Tcl object-related procedures that are used by
 * 	many Tcl commands.
 *
 * 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.
 *
 * SCCS: @(#) tclObj.c 1.47 97/10/30 13:39:00
 */

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

/*
 * Table of all object types.
 */

static Tcl_HashTable typeTable;
static int typeTableInitialized = 0;    /* 0 means not yet initialized. */


/*
 * Head of the list of free Tcl_Objs we maintain.
 */

Tcl_Obj *tclFreeObjList = NULL;










/*
 * Pointer to a heap-allocated string of length zero that the Tcl core uses
 * as the value of an empty string representation for an object. This value
 * is shared by all new objects allocated by Tcl_NewObj.
 */


char *tclEmptyStringRep = NULL;

/*
 * Count of the number of Tcl objects every allocated (by Tcl_NewObj) and
 * freed (by TclFreeObj).
 */

#ifdef TCL_COMPILE_STATS
long tclObjsAlloced = 0;
long tclObjsFreed = 0;
#endif /* TCL_COMPILE_STATS */

/*
 * Prototypes for procedures defined later in this file:
 */

static void		DupBooleanInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
			    Tcl_Obj *copyPtr));
static void		DupDoubleInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
			    Tcl_Obj *copyPtr));
static void		DupIntInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
			    Tcl_Obj *copyPtr));
static void		FinalizeTypeTable _ANSI_ARGS_((void));
static void		FinalizeFreeObjList _ANSI_ARGS_((void));
static void		InitTypeTable _ANSI_ARGS_((void));
static int		SetBooleanFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
static int		SetDoubleFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
static int		SetIntFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
static void		UpdateStringOfBoolean _ANSI_ARGS_((Tcl_Obj *objPtr));
static void		UpdateStringOfDouble _ANSI_ARGS_((Tcl_Obj *objPtr));
static void		UpdateStringOfInt _ANSI_ARGS_((Tcl_Obj *objPtr));

/*
 * The structures below defines the Tcl object types defined in this file by
 * means of procedures that can be invoked by generic object code. See also
 * tclStringObj.c, tclListObj.c, tclByteCode.c for other type manager
 * implementations.
 */

Tcl_ObjType tclBooleanType = {
    "boolean",				/* name */
    (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
    DupBooleanInternalRep,		/* dupIntRepProc */
    UpdateStringOfBoolean,		/* updateStringProc */
    SetBooleanFromAny			/* setFromAnyProc */
};

Tcl_ObjType tclDoubleType = {
    "double",				/* name */
    (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
    DupDoubleInternalRep,		/* dupIntRepProc */
    UpdateStringOfDouble,		/* updateStringProc */
    SetDoubleFromAny			/* setFromAnyProc */
};

Tcl_ObjType tclIntType = {
    "int",				/* name */
    (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
    DupIntInternalRep,		        /* dupIntRepProc */
    UpdateStringOfInt,			/* updateStringProc */
    SetIntFromAny			/* setFromAnyProc */
};

/*
 *--------------------------------------------------------------
 *
 * InitTypeTable --
 *
 *	This procedure is invoked to perform once-only initialization of
 *	the type table. It also registers the object types defined in 
 *	this file.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Initializes the table of defined object types "typeTable" with
 *	builtin object types defined in this file. It also initializes the
 *	value of tclEmptyStringRep, which points to the heap-allocated
 *	string of length zero used as the string representation for
 *	newly-created objects.
 *
 *--------------------------------------------------------------
 */

static void
InitTypeTable()
{

    typeTableInitialized = 1;

    Tcl_InitHashTable(&typeTable, TCL_STRING_KEYS);


    Tcl_RegisterObjType(&tclBooleanType);

    Tcl_RegisterObjType(&tclDoubleType);
    Tcl_RegisterObjType(&tclIntType);
    Tcl_RegisterObjType(&tclStringType);
    Tcl_RegisterObjType(&tclListType);
    Tcl_RegisterObjType(&tclByteCodeType);

    tclEmptyStringRep = (char *) ckalloc((unsigned) 1);
    tclEmptyStringRep[0] = '\0';
}

/*
 *----------------------------------------------------------------------
 *
 * FinalizeTypeTable --
 *
 *	This procedure is called by Tcl_Finalize after all exit handlers
 *	have been run to free up storage associated with the table of Tcl
 *	object types.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Deletes all entries in the hash table of object types, "typeTable".
 *	Then sets "typeTableInitialized" to 0 so that the Tcl type system
 *	will be properly reinitialized if Tcl is restarted. Also deallocates
 *	the storage for tclEmptyStringRep.
 *
 *----------------------------------------------------------------------
 */

static void
FinalizeTypeTable()
{
    if (typeTableInitialized) {
        Tcl_DeleteHashTable(&typeTable);
	ckfree(tclEmptyStringRep);
        typeTableInitialized = 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FinalizeFreeObjList --
 *
 *	Resets the free object list so it can later be reinitialized.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resets the value of tclFreeObjList.
 *
 *----------------------------------------------------------------------
 */

static void
FinalizeFreeObjList()
{
    tclFreeObjList = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeCompExecEnv --
 *

 *	Clean up the compiler execution environment so it can later be
 *	properly reinitialized.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Cleans up the execution environment
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeCompExecEnv()
{



    FinalizeTypeTable();



    FinalizeFreeObjList();



    TclFinalizeExecEnv();
}

/*
 *--------------------------------------------------------------
 *
 * Tcl_RegisterObjType --
 *











|











>


|




>
>
>
>
>
>
>
>
>






>
|


|
|











<
<
<
<
<
<
<
<
<




















|







|







|





|

|










|
<
<
<

|


|
|

>

<

>
>

>





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







>
|
|





|







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







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
/* 
 * tclObj.c --
 *
 *	This file contains Tcl object-related procedures that are used by
 * 	many Tcl commands.
 *
 * 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: tclObj.c,v 1.1.2.8 1999/04/14 00:33:25 surles Exp $
 */

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

/*
 * Table of all object types.
 */

static Tcl_HashTable typeTable;
static int typeTableInitialized = 0;    /* 0 means not yet initialized. */
TCL_DECLARE_MUTEX(tableMutex)

/*
 * Head of the list of free Tcl_Obj structs we maintain.
 */

Tcl_Obj *tclFreeObjList = NULL;

/*
 * The object allocator is single threaded.  This mutex is referenced
 * by the TclNewObj macro, however, so must be visible.
 */

#ifdef TCL_THREADS
Tcl_Mutex tclObjMutex;
#endif

/*
 * Pointer to a heap-allocated string of length zero that the Tcl core uses
 * as the value of an empty string representation for an object. This value
 * is shared by all new objects allocated by Tcl_NewObj.
 */

static char emptyString;
char *tclEmptyStringRep = &emptyString;

/*
 * The number of Tcl objects ever allocated (by Tcl_NewObj) and freed
 * (by TclFreeObj).
 */

#ifdef TCL_COMPILE_STATS
long tclObjsAlloced = 0;
long tclObjsFreed = 0;
#endif /* TCL_COMPILE_STATS */

/*
 * Prototypes for procedures defined later in this file:
 */










static int		SetBooleanFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
static int		SetDoubleFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
static int		SetIntFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
static void		UpdateStringOfBoolean _ANSI_ARGS_((Tcl_Obj *objPtr));
static void		UpdateStringOfDouble _ANSI_ARGS_((Tcl_Obj *objPtr));
static void		UpdateStringOfInt _ANSI_ARGS_((Tcl_Obj *objPtr));

/*
 * The structures below defines the Tcl object types defined in this file by
 * means of procedures that can be invoked by generic object code. See also
 * tclStringObj.c, tclListObj.c, tclByteCode.c for other type manager
 * implementations.
 */

Tcl_ObjType tclBooleanType = {
    "boolean",				/* name */
    (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
    (Tcl_DupInternalRepProc *) NULL,	/* dupIntRepProc */
    UpdateStringOfBoolean,		/* updateStringProc */
    SetBooleanFromAny			/* setFromAnyProc */
};

Tcl_ObjType tclDoubleType = {
    "double",				/* name */
    (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
    (Tcl_DupInternalRepProc *) NULL,	/* dupIntRepProc */
    UpdateStringOfDouble,		/* updateStringProc */
    SetDoubleFromAny			/* setFromAnyProc */
};

Tcl_ObjType tclIntType = {
    "int",				/* name */
    (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */
    (Tcl_DupInternalRepProc *) NULL,	/* dupIntRepProc */
    UpdateStringOfInt,			/* updateStringProc */
    SetIntFromAny			/* setFromAnyProc */
};

/*
 *-------------------------------------------------------------------------
 *
 * TclInitObjectSubsystem --
 *
 *	This procedure is invoked to perform once-only initialization of
 *	the type table. It also registers the object types defined in 
 *	this file.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Initializes the table of defined object types "typeTable" with
 *	builtin object types defined in this file.  



 *
 *-------------------------------------------------------------------------
 */

void
TclInitObjSubsystem()
{
    Tcl_MutexLock(&tableMutex);
    typeTableInitialized = 1;

    Tcl_InitHashTable(&typeTable, TCL_STRING_KEYS);
    Tcl_MutexUnlock(&tableMutex);

    Tcl_RegisterObjType(&tclBooleanType);
    Tcl_RegisterObjType(&tclByteArrayType);
    Tcl_RegisterObjType(&tclDoubleType);
    Tcl_RegisterObjType(&tclIntType);
    Tcl_RegisterObjType(&tclStringType);
    Tcl_RegisterObjType(&tclListType);
    Tcl_RegisterObjType(&tclByteCodeType);
    Tcl_RegisterObjType(&tclProcBodyType);



#ifdef TCL_COMPILE_STATS




















    Tcl_MutexLock(&tclObjMutex);





    tclObjsAlloced = 0;
    tclObjsFreed = 0;


    Tcl_MutexUnlock(&tclObjMutex);















#endif




}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeCompExecEnv --
 *
 *	This procedure is called by Tcl_Finalize to clean up the Tcl
 *	compilation and execution environment so it can later be properly
 *	reinitialized.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Cleans up the compilation and execution environment
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeCompExecEnv()
{
    Tcl_MutexLock(&tableMutex);
    if (typeTableInitialized) {
        Tcl_DeleteHashTable(&typeTable);
        typeTableInitialized = 0;
    }
    Tcl_MutexUnlock(&tableMutex);
    Tcl_MutexLock(&tclObjMutex);
    tclFreeObjList = NULL;
    Tcl_MutexUnlock(&tclObjMutex);

    TclFinalizeCompilation();
    TclFinalizeExecution();
}

/*
 *--------------------------------------------------------------
 *
 * Tcl_RegisterObjType --
 *
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
    Tcl_ObjType *typePtr;	/* Information about object type;
				 * storage must be statically
				 * allocated (must live forever). */
{
    register Tcl_HashEntry *hPtr;
    int new;

    if (!typeTableInitialized) {
	InitTypeTable();
    }

    /*
     * If there's already an object type with the given name, remove it.
     */

    hPtr = Tcl_FindHashEntry(&typeTable, typePtr->name);
    if (hPtr != (Tcl_HashEntry *) NULL) {
        Tcl_DeleteHashEntry(hPtr);
    }

    /*
     * Now insert the new object type.
     */

    hPtr = Tcl_CreateHashEntry(&typeTable, typePtr->name, &new);
    if (new) {
	Tcl_SetHashValue(hPtr, typePtr);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppendAllObjTypes --
 *
 *	This procedure appends onto the argument object the name of each
 *	object type as a list element. This includes the builtin object
 *	types (e.g. int, list) as well as those added using
 *	Tcl_CreateObjType. These names can be used, for example, with
 *	Tcl_GetObjType to get pointers to the corresponding Tcl_ObjType
 *	structures.
 *
 * Results:
 *	The return value is normally TCL_OK; in this case the object
 *	referenced by objPtr has each type name appended to it. If an
 *	error occurs, TCL_ERROR is returned and the interpreter's result







<
<
<
<



|













>










|







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
    Tcl_ObjType *typePtr;	/* Information about object type;
				 * storage must be statically
				 * allocated (must live forever). */
{
    register Tcl_HashEntry *hPtr;
    int new;





    /*
     * If there's already an object type with the given name, remove it.
     */
    Tcl_MutexLock(&tableMutex);
    hPtr = Tcl_FindHashEntry(&typeTable, typePtr->name);
    if (hPtr != (Tcl_HashEntry *) NULL) {
        Tcl_DeleteHashEntry(hPtr);
    }

    /*
     * Now insert the new object type.
     */

    hPtr = Tcl_CreateHashEntry(&typeTable, typePtr->name, &new);
    if (new) {
	Tcl_SetHashValue(hPtr, typePtr);
    }
    Tcl_MutexUnlock(&tableMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppendAllObjTypes --
 *
 *	This procedure appends onto the argument object the name of each
 *	object type as a list element. This includes the builtin object
 *	types (e.g. int, list) as well as those added using
 *	Tcl_NewObj. These names can be used, for example, with
 *	Tcl_GetObjType to get pointers to the corresponding Tcl_ObjType
 *	structures.
 *
 * Results:
 *	The return value is normally TCL_OK; in this case the object
 *	referenced by objPtr has each type name appended to it. If an
 *	error occurs, TCL_ERROR is returned and the interpreter's result
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
				 * as a list element. */
{
    register Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Tcl_ObjType *typePtr;
    int result;
 
    if (!typeTableInitialized) {
	InitTypeTable();
    }

    /*
     * This code assumes that types names do not contain embedded NULLs.
     */


    for (hPtr = Tcl_FirstHashEntry(&typeTable, &search);
	    hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
        typePtr = (Tcl_ObjType *) Tcl_GetHashValue(hPtr);
	result = Tcl_ListObjAppendElement(interp, objPtr,
	        Tcl_NewStringObj(typePtr->name, -1));
	if (result == TCL_ERROR) {

	    return result;
	}
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetObjType --







<
<
<
<




>






>



>







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
				 * as a list element. */
{
    register Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Tcl_ObjType *typePtr;
    int result;
 




    /*
     * This code assumes that types names do not contain embedded NULLs.
     */

    Tcl_MutexLock(&tableMutex);
    for (hPtr = Tcl_FirstHashEntry(&typeTable, &search);
	    hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
        typePtr = (Tcl_ObjType *) Tcl_GetHashValue(hPtr);
	result = Tcl_ListObjAppendElement(interp, objPtr,
	        Tcl_NewStringObj(typePtr->name, -1));
	if (result == TCL_ERROR) {
	    Tcl_MutexUnlock(&tableMutex);
	    return result;
	}
    }
    Tcl_MutexUnlock(&tableMutex);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetObjType --
346
347
348
349
350
351
352
353
354
355
356
357
358
359

360
361

362
363
364
365
366
367
368
Tcl_ObjType *
Tcl_GetObjType(typeName)
    char *typeName;		/* Name of Tcl object type to look up. */
{
    register Tcl_HashEntry *hPtr;
    Tcl_ObjType *typePtr;

    if (!typeTableInitialized) {
	InitTypeTable();
    }

    hPtr = Tcl_FindHashEntry(&typeTable, typeName);
    if (hPtr != (Tcl_HashEntry *) NULL) {
        typePtr = (Tcl_ObjType *) Tcl_GetHashValue(hPtr);

	return typePtr;
    }

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConvertToType --







<
<
<
|



>


>







306
307
308
309
310
311
312



313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
Tcl_ObjType *
Tcl_GetObjType(typeName)
    char *typeName;		/* Name of Tcl object type to look up. */
{
    register Tcl_HashEntry *hPtr;
    Tcl_ObjType *typePtr;




    Tcl_MutexLock(&tableMutex);
    hPtr = Tcl_FindHashEntry(&typeTable, typeName);
    if (hPtr != (Tcl_HashEntry *) NULL) {
        typePtr = (Tcl_ObjType *) Tcl_GetHashValue(hPtr);
	Tcl_MutexUnlock(&tableMutex);
	return typePtr;
    }
    Tcl_MutexUnlock(&tableMutex);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConvertToType --
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

Tcl_Obj *
Tcl_NewObj()
{
    register Tcl_Obj *objPtr;

    /*
     * Allocate the object using the list of free Tcl_Objs we maintain.

     */


    if (tclFreeObjList == NULL) {
	TclAllocateFreeObjects();
    }
    objPtr = tclFreeObjList;
    tclFreeObjList = (Tcl_Obj *) tclFreeObjList->internalRep.otherValuePtr;
    
    objPtr->refCount = 0;
    objPtr->bytes    = tclEmptyStringRep;
    objPtr->length   = 0;
    objPtr->typePtr  = NULL;
#ifdef TCL_COMPILE_STATS
    tclObjsAlloced++;
#endif /* TCL_COMPILE_STATS */

    return objPtr;
}
#endif /* TCL_MEM_DEBUG */

/*
 *----------------------------------------------------------------------
 *







|
>


>













>







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

Tcl_Obj *
Tcl_NewObj()
{
    register Tcl_Obj *objPtr;

    /*
     * Allocate the object using the list of free Tcl_Obj structs
     * we maintain.
     */

    Tcl_MutexLock(&tclObjMutex);
    if (tclFreeObjList == NULL) {
	TclAllocateFreeObjects();
    }
    objPtr = tclFreeObjList;
    tclFreeObjList = (Tcl_Obj *) tclFreeObjList->internalRep.otherValuePtr;
    
    objPtr->refCount = 0;
    objPtr->bytes    = tclEmptyStringRep;
    objPtr->length   = 0;
    objPtr->typePtr  = NULL;
#ifdef TCL_COMPILE_STATS
    tclObjsAlloced++;
#endif /* TCL_COMPILE_STATS */
    Tcl_MutexUnlock(&tclObjMutex);
    return objPtr;
}
#endif /* TCL_MEM_DEBUG */

/*
 *----------------------------------------------------------------------
 *
500
501
502
503
504
505
506
507

508
509
510
511
512
513
514
515

516

517
518
519
520
521
522
523
    register int line;		/* Line number in the source file; used
				 * for debugging. */
{
    register Tcl_Obj *objPtr;

    /*
     * If debugging Tcl's memory usage, allocate the object using ckalloc.
     * Otherwise, allocate it using the list of free Tcl_Objs we maintain.

     */

    objPtr = (Tcl_Obj *) Tcl_DbCkalloc(sizeof(Tcl_Obj), file, line);
    objPtr->refCount = 0;
    objPtr->bytes    = tclEmptyStringRep;
    objPtr->length   = 0;
    objPtr->typePtr  = NULL;
#ifdef TCL_COMPILE_STATS

    tclObjsAlloced++;

#endif /* TCL_COMPILE_STATS */
    return objPtr;
}

#else /* if not TCL_MEM_DEBUG */

Tcl_Obj *







|
>








>

>







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
    register int line;		/* Line number in the source file; used
				 * for debugging. */
{
    register Tcl_Obj *objPtr;

    /*
     * If debugging Tcl's memory usage, allocate the object using ckalloc.
     * Otherwise, allocate it using the list of free Tcl_Obj structs we
     * maintain.
     */

    objPtr = (Tcl_Obj *) Tcl_DbCkalloc(sizeof(Tcl_Obj), file, line);
    objPtr->refCount = 0;
    objPtr->bytes    = tclEmptyStringRep;
    objPtr->length   = 0;
    objPtr->typePtr  = NULL;
#ifdef TCL_COMPILE_STATS
    Tcl_MutexLock(&tclObjMutex);
    tclObjsAlloced++;
    Tcl_MutexUnlock(&tclObjMutex);
#endif /* TCL_COMPILE_STATS */
    return objPtr;
}

#else /* if not TCL_MEM_DEBUG */

Tcl_Obj *
534
535
536
537
538
539
540


541
542
543
544
545
546
547
/*
 *----------------------------------------------------------------------
 *
 * TclAllocateFreeObjects --
 *
 *	Procedure to allocate a number of free Tcl_Objs. This is done using
 *	a single ckalloc to reduce the overhead for Tcl_Obj allocation.


 *
 * Results:
 *	None.
 *
 * Side effects:
 *	tclFreeObjList, the head of the list of free Tcl_Objs, is set to the
 *	first of a number of free Tcl_Obj's linked together by their







>
>







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
/*
 *----------------------------------------------------------------------
 *
 * TclAllocateFreeObjects --
 *
 *	Procedure to allocate a number of free Tcl_Objs. This is done using
 *	a single ckalloc to reduce the overhead for Tcl_Obj allocation.
 *
 *	Assumes mutex is held.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	tclFreeObjList, the head of the list of free Tcl_Objs, is set to the
 *	first of a number of free Tcl_Obj's linked together by their
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
    
#ifdef TCL_MEM_DEBUG
    if ((objPtr)->refCount < -1) {
	panic("Reference count for %lx was negative", objPtr);
    }
#endif /* TCL_MEM_DEBUG */

    Tcl_InvalidateStringRep(objPtr);
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }


    /*
     * If debugging Tcl's memory usage, deallocate the object using ckfree.
     * Otherwise, deallocate it by adding it onto the list of free
     * Tcl_Objs we maintain.
     */
    

#ifdef TCL_MEM_DEBUG
    ckfree((char *) objPtr);
#else
    objPtr->internalRep.otherValuePtr = (VOID *) tclFreeObjList;
    tclFreeObjList = objPtr;
#endif /* TCL_MEM_DEBUG */

#ifdef TCL_COMPILE_STATS    
    tclObjsFreed++;
#endif /* TCL_COMPILE_STATS */    

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DuplicateObj --
 *







<



>




|

|
>







|

|
>







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
    
#ifdef TCL_MEM_DEBUG
    if ((objPtr)->refCount < -1) {
	panic("Reference count for %lx was negative", objPtr);
    }
#endif /* TCL_MEM_DEBUG */


    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }
    Tcl_InvalidateStringRep(objPtr);

    /*
     * If debugging Tcl's memory usage, deallocate the object using ckfree.
     * Otherwise, deallocate it by adding it onto the list of free
     * Tcl_Obj structs we maintain.
     */

    Tcl_MutexLock(&tclObjMutex);
#ifdef TCL_MEM_DEBUG
    ckfree((char *) objPtr);
#else
    objPtr->internalRep.otherValuePtr = (VOID *) tclFreeObjList;
    tclFreeObjList = objPtr;
#endif /* TCL_MEM_DEBUG */

#ifdef TCL_COMPILE_STATS
    tclObjsFreed++;
#endif /* TCL_COMPILE_STATS */
    Tcl_MutexUnlock(&tclObjMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DuplicateObj --
 *
686
687
688
689
690
691
692
693




694

695
696






































697
698
699
700
701
702
703
		   (unsigned) len);
	}
	dupPtr->bytes[len] = '\0';
	dupPtr->length = len;
    }
    
    if (typePtr != NULL) {
	typePtr->dupIntRepProc(objPtr, dupPtr);




    }

    return dupPtr;
}







































/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetStringFromObj --
 *
 *	Returns the string representation's byte array pointer and length







|
>
>
>
>
|
>


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







655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
		   (unsigned) len);
	}
	dupPtr->bytes[len] = '\0';
	dupPtr->length = len;
    }
    
    if (typePtr != NULL) {
	if (typePtr->dupIntRepProc == NULL) {
	    dupPtr->internalRep = objPtr->internalRep;
	    dupPtr->typePtr = typePtr;
	} else {
	    (*typePtr->dupIntRepProc)(objPtr, dupPtr);
	}
    }
    return dupPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetString --
 *
 *	Returns the string representation byte array pointer for an object.
 *
 * Results:
 *	Returns a pointer to the string representation of objPtr. The byte
 *	array referenced by the returned pointer must not be modified by the
 *	caller. Furthermore, the caller must copy the bytes if they need to
 *	retain them since the object's string rep can change as a result of
 *	other operations.
 *
 * Side effects:
 *	May call the object's updateStringProc to update the string
 *	representation from the internal representation.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_GetString(objPtr)
    register Tcl_Obj *objPtr;	/* Object whose string rep byte pointer
				 * should be returned. */
{
    if (objPtr->bytes != NULL) {
	return objPtr->bytes;
    }

    if (objPtr->typePtr->updateStringProc == NULL) {
	panic("UpdateStringProc should not be invoked for type %s",
		objPtr->typePtr->name);
    }
    (*objPtr->typePtr->updateStringProc)(objPtr);
    return objPtr->bytes;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetStringFromObj --
 *
 *	Returns the string representation's byte array pointer and length
729
730
731
732
733
734
735


736


737
738
739
740
741
742
743
    if (objPtr->bytes != NULL) {
	if (lengthPtr != NULL) {
	    *lengthPtr = objPtr->length;
	}
	return objPtr->bytes;
    }



    objPtr->typePtr->updateStringProc(objPtr);


    if (lengthPtr != NULL) {
	*lengthPtr = objPtr->length;
    }
    return objPtr->bytes;
}

/*







>
>
|
>
>







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
    if (objPtr->bytes != NULL) {
	if (lengthPtr != NULL) {
	    *lengthPtr = objPtr->length;
	}
	return objPtr->bytes;
    }

    if (objPtr->typePtr->updateStringProc == NULL) {
	panic("UpdateStringProc should not be invoked for type %s",
		objPtr->typePtr->name);
    }
    (*objPtr->typePtr->updateStringProc)(objPtr);
    if (lengthPtr != NULL) {
	*lengthPtr = objPtr->length;
    }
    return objPtr->bytes;
}

/*
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DupBooleanInternalRep --
 *
 *	Initialize the internal representation of a boolean Tcl_Obj to a
 *	copy of the internal representation of an existing boolean object. 
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	"copyPtr"s internal rep is set to the boolean (an integer)
 *	corresponding to "srcPtr"s internal rep.
 *
 *----------------------------------------------------------------------
 */

static void
DupBooleanInternalRep(srcPtr, copyPtr)
    register Tcl_Obj *srcPtr;	/* Object with internal rep to copy. */
    register Tcl_Obj *copyPtr;	/* Object with internal rep to set. */
{
    copyPtr->internalRep.longValue = srcPtr->internalRep.longValue;
    copyPtr->typePtr = &tclBooleanType;
}

/*
 *----------------------------------------------------------------------
 *
 * SetBooleanFromAny --
 *
 *	Attempt to generate a boolean internal form for the Tcl object
 *	"objPtr".
 *
 * Results:
 *	The return value is a standard Tcl result. If an error occurs during







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







970
971
972
973
974
975
976



























977
978
979
980
981
982
983
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *



























 * SetBooleanFromAny --
 *
 *	Attempt to generate a boolean internal form for the Tcl object
 *	"objPtr".
 *
 * Results:
 *	The return value is a standard Tcl result. If an error occurs during
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029








1030
1031
1032
1033
1034
1035
1036
1037
1038
    register int i;
    double dbl;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    string = TclGetStringFromObj(objPtr, &length);

    /*
     * Copy the string converting its characters to lower case.
     */

    for (i = 0;  (i < 9) && (i < length);  i++) {
	c = string[i];








	if (isupper(UCHAR(c))) {
	    c = (char) tolower(UCHAR(c));
	}
	lowerCase[i] = c;
    }
    lowerCase[i] = 0;

    /*
     * Parse the string as a boolean. We use an implementation here that







|







>
>
>
>
>
>
>
>
|
|







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
    register int i;
    double dbl;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    string = Tcl_GetStringFromObj(objPtr, &length);

    /*
     * Copy the string converting its characters to lower case.
     */

    for (i = 0;  (i < 9) && (i < length);  i++) {
	c = string[i];
	/*
	 * Weed out international characters so we can safely operate
	 * on single bytes.
	 */

	if (c & 0x80) {
	    goto badBoolean;
	}
	if (isupper(UCHAR(c))) { /* INTL: ISO only. */
	    c = (char) UCHAR(tolower(UCHAR(c))); /* INTL: ISO only. */
	}
	lowerCase[i] = c;
    }
    lowerCase[i] = 0;

    /*
     * Parse the string as a boolean. We use an implementation here that
1075
1076
1077
1078
1079
1080
1081
1082

1083
1084
1085
1086
1087
1088
1089
	    goto badBoolean;
	}

	/*
	 * Make sure the string has no garbage after the end of the double.
	 */
	
	while ((end < (string+length)) && isspace(UCHAR(*end))) {

	    end++;
	}
	if (end != (string+length)) {
	    goto badBoolean;
	}
	newBool = (dbl != 0.0);
    }







|
>







1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
	    goto badBoolean;
	}

	/*
	 * Make sure the string has no garbage after the end of the double.
	 */
	
	while ((end < (string+length))
		&& isspace(UCHAR(*end))) { /* INTL: ISO only */
	    end++;
	}
	if (end != (string+length)) {
	    goto badBoolean;
	}
	newBool = (dbl != 0.0);
    }
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DupDoubleInternalRep --
 *
 *	Initialize the internal representation of a double Tcl_Obj to a
 *	copy of the internal representation of an existing double object. 
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	"copyPtr"s internal rep is set to the double precision floating 
 *	point number corresponding to "srcPtr"s internal rep.
 *
 *----------------------------------------------------------------------
 */

static void
DupDoubleInternalRep(srcPtr, copyPtr)
    register Tcl_Obj *srcPtr;	/* Object with internal rep to copy. */
    register Tcl_Obj *copyPtr;	/* Object with internal rep to set. */
{
    copyPtr->internalRep.doubleValue = srcPtr->internalRep.doubleValue;
    copyPtr->typePtr = &tclDoubleType;
}

/*
 *----------------------------------------------------------------------
 *
 * SetDoubleFromAny --
 *
 *	Attempt to generate an double-precision floating point internal form
 *	for the Tcl object "objPtr".
 *
 * Results:
 *	The return value is a standard Tcl object result. If an error occurs







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







1333
1334
1335
1336
1337
1338
1339



























1340
1341
1342
1343
1344
1345
1346
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *



























 * SetDoubleFromAny --
 *
 *	Attempt to generate an double-precision floating point internal form
 *	for the Tcl object "objPtr".
 *
 * Results:
 *	The return value is a standard Tcl object result. If an error occurs
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
    double newDouble;
    int length;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    string = TclGetStringFromObj(objPtr, &length);

    /*
     * Now parse "objPtr"s string as an double. Numbers can't have embedded
     * NULLs. We use an implementation here that doesn't report errors in
     * interp if interp is NULL.
     */








|







1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
    double newDouble;
    int length;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    string = Tcl_GetStringFromObj(objPtr, &length);

    /*
     * Now parse "objPtr"s string as an double. Numbers can't have embedded
     * NULLs. We use an implementation here that doesn't report errors in
     * interp if interp is NULL.
     */

1430
1431
1432
1433
1434
1435
1436
1437

1438
1439
1440
1441
1442
1443
1444
	return TCL_ERROR;
    }

    /*
     * Make sure that the string has no garbage after the end of the double.
     */
    
    while ((end < (string+length)) && isspace(UCHAR(*end))) {

	end++;
    }
    if (end != (string+length)) {
	goto badDouble;
    }
    
    /*







|
>







1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
	return TCL_ERROR;
    }

    /*
     * Make sure that the string has no garbage after the end of the double.
     */
    
    while ((end < (string+length))
	    && isspace(UCHAR(*end))) { /* INTL: ISO space. */
	end++;
    }
    if (end != (string+length)) {
	goto badDouble;
    }
    
    /*
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
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * DupIntInternalRep --
 *
 *	Initialize the internal representation of an int Tcl_Obj to a
 *	copy of the internal representation of an existing int object. 
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	"copyPtr"s internal rep is set to the integer corresponding to
 *	"srcPtr"s internal rep.
 *
 *----------------------------------------------------------------------
 */

static void
DupIntInternalRep(srcPtr, copyPtr)
    register Tcl_Obj *srcPtr;	/* Object with internal rep to copy. */
    register Tcl_Obj *copyPtr;	/* Object with internal rep to set. */
{
    copyPtr->internalRep.longValue = srcPtr->internalRep.longValue;
    copyPtr->typePtr = &tclIntType;
}

/*
 *----------------------------------------------------------------------
 *
 * SetIntFromAny --
 *
 *	Attempt to generate an integer internal form for the Tcl object
 *	"objPtr".
 *
 * Results:
 *	The return value is a standard object Tcl result. If an error occurs







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







1614
1615
1616
1617
1618
1619
1620



























1621
1622
1623
1624
1625
1626
1627
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *



























 * SetIntFromAny --
 *
 *	Attempt to generate an integer internal form for the Tcl object
 *	"objPtr".
 *
 * Results:
 *	The return value is a standard object Tcl result. If an error occurs
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
    register char *p;
    long newLong;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    string = TclGetStringFromObj(objPtr, &length);

    /*
     * Now parse "objPtr"s string as an int. We use an implementation here
     * that doesn't report errors in interp if interp is NULL. Note: use
     * strtoul instead of strtol for integer conversions to allow full-size
     * unsigned numbers, but don't depend on strtoul to handle sign
     * characters; it won't in some implementations.
     */

    errno = 0;
    for (p = string;  isspace(UCHAR(*p));  p++) {
	/* Empty loop body. */
    }
    if (*p == '-') {
	p++;
	newLong = -((long)strtoul(p, &end, 0));
    } else if (*p == '+') {
	p++;







|










|







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
    register char *p;
    long newLong;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    string = Tcl_GetStringFromObj(objPtr, &length);

    /*
     * Now parse "objPtr"s string as an int. We use an implementation here
     * that doesn't report errors in interp if interp is NULL. Note: use
     * strtoul instead of strtol for integer conversions to allow full-size
     * unsigned numbers, but don't depend on strtoul to handle sign
     * characters; it won't in some implementations.
     */

    errno = 0;
    for (p = string;  isspace(UCHAR(*p));  p++) { /* INTL: ISO space. */
	/* Empty loop body. */
    }
    if (*p == '-') {
	p++;
	newLong = -((long)strtoul(p, &end, 0));
    } else if (*p == '+') {
	p++;
1753
1754
1755
1756
1757
1758
1759
1760

1761
1762
1763
1764
1765
1766
1767
	return TCL_ERROR;
    }

    /*
     * Make sure that the string has no garbage after the end of the int.
     */
    
    while ((end < (string+length)) && isspace(UCHAR(*end))) {

	end++;
    }
    if (end != (string+length)) {
	goto badInteger;
    }

    /*







|
>







1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
	return TCL_ERROR;
    }

    /*
     * Make sure that the string has no garbage after the end of the int.
     */
    
    while ((end < (string+length))
	    && isspace(UCHAR(*end))) { /* INTL: ISO space. */
	end++;
    }
    if (end != (string+length)) {
	goto badInteger;
    }

    /*
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
 *----------------------------------------------------------------------
 */

static void
UpdateStringOfInt(objPtr)
    register Tcl_Obj *objPtr;	/* Int object whose string rep to update. */
{
    char buffer[TCL_DOUBLE_SPACE];
    register int len;
    
    len = TclFormatInt(buffer, objPtr->internalRep.longValue);
    
    objPtr->bytes = ckalloc((unsigned) len + 1);
    strcpy(objPtr->bytes, buffer);
    objPtr->length = len;







|







1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
 *----------------------------------------------------------------------
 */

static void
UpdateStringOfInt(objPtr)
    register Tcl_Obj *objPtr;	/* Int object whose string rep to update. */
{
    char buffer[TCL_INTEGER_SPACE];
    register int len;
    
    len = TclFormatInt(buffer, objPtr->internalRep.longValue);
    
    objPtr->bytes = ckalloc((unsigned) len + 1);
    strcpy(objPtr->bytes, buffer);
    objPtr->length = len;
2039
2040
2041
2042
2043
2044
2045
2046

2047
2048
2049
2050
2051
2052
2053
 *	The object's ref count is incremented.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DbIncrRefCount(objPtr, file, line)
    register Tcl_Obj *objPtr;	/* The object we are adding a reference to. */

    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
    int line;			/* Line number in the source file; used
				 * for debugging. */
{
#ifdef TCL_MEM_DEBUG
    if (objPtr->refCount == 0x61616161) {







|
>







1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
 *	The object's ref count is incremented.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DbIncrRefCount(objPtr, file, line)
    register Tcl_Obj *objPtr;	/* The object we are registering a
				 * reference to. */
    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
    int line;			/* Line number in the source file; used
				 * for debugging. */
{
#ifdef TCL_MEM_DEBUG
    if (objPtr->refCount == 0x61616161) {
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085

2086
2087
2088
2089
2090
2091
2092
/*
 *----------------------------------------------------------------------
 *
 * Tcl_DbDecrRefCount --
 *
 *	This procedure is normally called when debugging: i.e., when
 *	TCL_MEM_DEBUG is defined. This checks to see whether or not
 *	the memory has been freed before incrementing the ref count.
 *
 *	When TCL_MEM_DEBUG is not defined, this procedure just increments
 *	the reference count of the object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object's ref count is incremented.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DbDecrRefCount(objPtr, file, line)
    register Tcl_Obj *objPtr;	/* The object we are adding a reference to. */

    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
    int line;			/* Line number in the source file; used
				 * for debugging. */
{
#ifdef TCL_MEM_DEBUG
    if (objPtr->refCount == 0x61616161) {







|

|













|
>







2009
2010
2011
2012
2013
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
/*
 *----------------------------------------------------------------------
 *
 * Tcl_DbDecrRefCount --
 *
 *	This procedure is normally called when debugging: i.e., when
 *	TCL_MEM_DEBUG is defined. This checks to see whether or not
 *	the memory has been freed before decrementing the ref count.
 *
 *	When TCL_MEM_DEBUG is not defined, this procedure just decrements
 *	the reference count of the object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object's ref count is incremented.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DbDecrRefCount(objPtr, file, line)
    register Tcl_Obj *objPtr;	/* The object we are releasing a reference
				 * to. */
    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
    int line;			/* Line number in the source file; used
				 * for debugging. */
{
#ifdef TCL_MEM_DEBUG
    if (objPtr->refCount == 0x61616161) {
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
2130
2131
2132
2133
2134

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DbIsShared --
 *
 *	This procedure is normally called when debugging: i.e., when
 *	TCL_MEM_DEBUG is defined. This checks to see whether or not
 *	the memory has been freed before incrementing the ref count.
 *
 *	When TCL_MEM_DEBUG is not defined, this procedure just decrements
 *	the reference count of the object and throws it away if the count
 *	is 0 or less.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object's ref count is incremented.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_DbIsShared(objPtr, file, line)
    register Tcl_Obj *objPtr;	/* The object we are adding a reference to. */
    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
    int line;			/* Line number in the source file; used
				 * for debugging. */
{
#ifdef TCL_MEM_DEBUG
    if (objPtr->refCount == 0x61616161) {







|
|

|
|
<





|






|







2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061

2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DbIsShared --
 *
 *	This procedure is normally called when debugging: i.e., when
 *	TCL_MEM_DEBUG is defined. It tests whether the object has a ref
 *	count greater than one.
 *
 *	When TCL_MEM_DEBUG is not defined, this procedure just tests
 *	if the object has a ref count greater than one.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_DbIsShared(objPtr, file, line)
    register Tcl_Obj *objPtr;	/* The object to test for being shared. */
    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
    int line;			/* Line number in the source file; used
				 * for debugging. */
{
#ifdef TCL_MEM_DEBUG
    if (objPtr->refCount == 0x61616161) {

Added generic/tclPanic.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
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
/* 
 * tclPanic.c --
 *
 *	Source code for the "Tcl_Panic" library procedure for Tcl;
 *	individual applications will probably override this with
 *	an application-specific panic procedure.
 *
 * Copyright (c) 1988-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: tclPanic.c,v 1.2.6.1 1999/03/10 06:49:20 stanton Exp $
 */

#include "tclInt.h"

/*
 * The panicProc variable contains a pointer to an application
 * specific panic procedure.
 */

void (*panicProc) _ANSI_ARGS_(TCL_VARARGS(char *,format)) = NULL;

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetPanicProc --
 *
 *	Replace the default panic behavior with the specified functiion.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets the panicProc variable.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetPanicProc(proc)
    void (*proc) _ANSI_ARGS_(TCL_VARARGS(char *,format));
{
    panicProc = proc;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PanicVA --
 *
 *	Print an error message and kill the process.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The process dies, entering the debugger if possible.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_PanicVA (format, argList)
    char *format;		/* Format string, suitable for passing to
				 * fprintf. */
    va_list argList;		/* Variable argument list. */
{
    char *arg1, *arg2, *arg3, *arg4;	/* Additional arguments (variable in
					 * number) to pass to fprintf. */
    char *arg5, *arg6, *arg7, *arg8;

    arg1 = va_arg(argList, char *);
    arg2 = va_arg(argList, char *);
    arg3 = va_arg(argList, char *);
    arg4 = va_arg(argList, char *);
    arg5 = va_arg(argList, char *);
    arg6 = va_arg(argList, char *);
    arg7 = va_arg(argList, char *);
    arg8 = va_arg(argList, char *);
    
    if (panicProc != NULL) {
	(void) (*panicProc)(format, arg1, arg2, arg3, arg4,
		arg5, arg6, arg7, arg8);
    } else {
	(void) fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5, arg6,
		arg7, arg8);
	(void) fprintf(stderr, "\n");
	(void) fflush(stderr);
	abort();
    }
}

/*
 *----------------------------------------------------------------------
 *
 * panic --
 *
 *	Print an error message and kill the process.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The process dies, entering the debugger if possible.
 *
 *----------------------------------------------------------------------
 */

	/* VARARGS ARGSUSED */
void
panic TCL_VARARGS_DEF(char *,arg1)
{
    va_list argList;
    char *format;

    format = TCL_VARARGS_START(char *,arg1,argList);
    Tcl_PanicVA(format, argList);
    va_end (argList);
}

Changes to generic/tclParse.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
65
66
67
68
69
70

71
72
73
74
75

76




77





78



















79



80
81
82
83

84
85
86
87
88


89
90









91
92
93
94
95
96
97
98



99
100
101
102
103
104


105
106
































107




108

109
110


111
112




113
114
115
116
117
118
119
120
121

122
123








124
125
126

127

128
129



130
131
132
133




134










135






136




137



138






139
140







141
142
143



144



145

146
147

148
149
150
151





152






153



154



155
156



157
158







159
160




161
162
163
164
165
166



167
168
169

170
171
172
173
174
175
176
177




178




179
180
181


















182
183
184



185
186
187










188
189
190


191







192













193
194








195
196

197

198
199
200
201
202


203
204
205

206

207
208



209



210
211





212








213
214




215




216







217




218






219





220


221
222
223
224
225















































226














227
228
229
230
231
232

233
234
235



236
237
238
239
240
241
242
243
244
245


























246
247


248
249
250





251
252
253
254
255
256
257
258
259
260







261








262
263
264
265







266


267
268




















269
270
271
272
273
274

275





276




277


278
279
280







281




282
283
284

285
286
287
288




289
290

291



292







293

294
295
296




297
298

299








300





301


302


303





304



305

































































306
307
308

309

310
311
312
313
314
315
316
317



318
319
320
321
322
323
324













325
326
327

328
329
330














331
332
333
334
335
336

















337







338
339
340
341
342
343
344
345


346
347
348
349
350
351
352
353




354
355
356
357
358
359













360





361


362



363






364




365

















366


















367



368



369














370


371
372





373



374




375













































376
377


378
379

380
381
382














383


384

385



386





















387







388













389





390






















391





392

393




394



395
396




397




















398





399























































































































400




401











402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418
419








420
421




422



423





424



425

















426




427
428







429

430
431

432



433






















434






435


436



437



438
439
440











441
442


443












444















445



446


447
448
449
450

451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712


713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758


759



760







761


762




763






















764
765
766
767
768
769
770
771
772
773
774

775
776

777
778






779






















780





781

782



783





784




785










786





787











































788
789
790

791




792
793
794
795
796
797
798


799




800

801
802
803
804
805
806
807
808
809
810
811
812

813
814

815

816
817
818
819
820
821
822



823
824
825




826






827

828







829






















830
831
832
833
834
835
836
837
838
839
840
841





842

843
844
845

846


847


848



849
850









851
852
853









854
855




856




857







858
859
860





861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885


886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
/* 
 * tclParse.c --
 *
 *	This file contains a collection of procedures that are used
 *	to parse Tcl commands or parts of commands (like quoted
 *	strings or nested sub-commands).



 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclParse.c 1.56 97/07/29 18:40:03
 */

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

/*













 * Function prototypes for procedures local to this file:










 */









static char *	QuoteEnd _ANSI_ARGS_((char *string, char *lastChar,

		    int term));
static char *	ScriptEnd _ANSI_ARGS_((char *p, char *lastChar,



		    int nested));
static char *	VarNameEnd _ANSI_ARGS_((char *string,  char *lastChar));

































/*
 *--------------------------------------------------------------

 *
 * TclParseQuotes --
 *
 *	This procedure parses a double-quoted string such as a
 *	quoted Tcl command argument or a quoted value in a Tcl
 *	expression.  This procedure is also used to parse array
 *	element names within parentheses, or anything else that
 *	needs all the substitutions that happen in quotes.
 *
 * Results:
 *	The return value is a standard Tcl result, which is
 *	TCL_OK unless there was an error while parsing the
















 *	quoted string.  If an error occurs then interp->result
 *	contains a standard error message.  *TermPtr is filled
 *	in with the address of the character just after the
 *	last one successfully processed;  this is usually the
 *	character just after the matching close-quote.  The
 *	fully-substituted contents of the quotes are stored in










 *	standard fashion in *pvPtr, null-terminated with

 *	pvPtr->next pointing to the terminating null character.
 *
 * Side effects:
 *	The buffer space in pvPtr may be enlarged by calling its
 *	expandProc.
 *
 *--------------------------------------------------------------
 */


































int
TclParseQuotes(interp, string, termChar, flags, termPtr, pvPtr)
    Tcl_Interp *interp;		/* Interpreter to use for nested command
				 * evaluations and error messages. */
    char *string;		/* Character just after opening double-
				 * quote. */
    int termChar;		/* Character that terminates "quoted" string
				 * (usually double-quote, but sometimes
				 * right-paren or something else). */
    int flags;			/* Flags to pass to nested Tcl_Eval calls. */
    char **termPtr;		/* Store address of terminating character

				 * here. */
    ParseValue *pvPtr;		/* Information about where to place
				 * fully-substituted result of parse. */
{
    register char *src, *dst, c;

    char *lastChar = string + strlen(string);










    src = string;



















    dst = pvPtr->next;




    while (1) {
	if (dst == pvPtr->end) {
	    /*

	     * Target buffer space is about to run out.  Make more space.
	     */

	    pvPtr->next = dst;
	    (*pvPtr->expandProc)(pvPtr, 1);


	    dst = pvPtr->next;
	}










	c = *src;
	src++;
	if (c == termChar) {
	    *dst = '\0';
	    pvPtr->next = dst;
	    *termPtr = src;
	    return TCL_OK;



	} else if (CHAR_TYPE(src-1, lastChar) == TCL_NORMAL) {
	    copy:
	    *dst = c;
	    dst++;
	    continue;
	} else if (c == '$') {


	    int length;
	    char *value;





































	    value = Tcl_ParseVar(interp, src-1, termPtr);

	    if (value == NULL) {
		return TCL_ERROR;


	    }
	    src = *termPtr;




	    length = strlen(value);
	    if ((pvPtr->end - dst) <= length) {
		pvPtr->next = dst;
		(*pvPtr->expandProc)(pvPtr, length);
		dst = pvPtr->next;
	    }
	    strcpy(dst, value);
	    dst += length;
	    continue;

	} else if (c == '[') {
	    int result;









	    pvPtr->next = dst;
	    result = TclParseNestedCmd(interp, src, flags, termPtr, pvPtr);

	    if (result != TCL_OK) {

		return result;
	    }



	    src = *termPtr;
	    dst = pvPtr->next;
	    continue;
	} else if (c == '\\') {




	    int numRead;

















	    src--;




	    *dst = Tcl_Backslash(src, &numRead);



	    dst++;






	    src += numRead;
	    continue;







	} else if (c == '\0') {
	    char buf[30];
	    



	    Tcl_ResetResult(interp);



	    sprintf(buf, "missing %c", termChar);

	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    *termPtr = string-1;

	    return TCL_ERROR;
	} else {
	    goto copy;
	}





    }






}







/*
 *--------------------------------------------------------------



 *
 * TclParseNestedCmd --







 *
 *	This procedure parses a nested Tcl command between




 *	brackets, returning the result of the command.
 *
 * Results:
 *	The return value is a standard Tcl result, which is
 *	TCL_OK unless there was an error while executing the
 *	nested command.  If an error occurs then interp->result



 *	contains a standard error message.  *TermPtr is filled
 *	in with the address of the character just after the
 *	last one processed;  this is usually the character just

 *	after the matching close-bracket, or the null character
 *	at the end of the string if the close-bracket was missing
 *	(a missing close bracket is an error).  The result returned
 *	by the command is stored in standard fashion in *pvPtr,
 *	null-terminated, with pvPtr->next pointing to the null
 *	character.
 *
 * Side effects:




 *	The storage space at *pvPtr may be expanded.




 *
 *--------------------------------------------------------------
 */



















int
TclParseNestedCmd(interp, string, flags, termPtr, pvPtr)



    Tcl_Interp *interp;		/* Interpreter to use for nested command
				 * evaluations and error messages. */
    char *string;		/* Character just after opening bracket. */










    int flags;			/* Flags to pass to nested Tcl_Eval. */
    char **termPtr;		/* Store address of terminating character
				 * here. */


    register ParseValue *pvPtr;	/* Information about where to place







				 * result of command. */













{
    int result, length, shortfall;








    Interp *iPtr = (Interp *) interp;


    iPtr->evalFlags = flags | TCL_BRACKET_TERM;

    result = Tcl_Eval(interp, string);
    *termPtr = (string + iPtr->termOffset);
    if (result != TCL_OK) {
	/*
	 * The increment below results in slightly cleaner message in


	 * the errorInfo variable (the close-bracket will appear).
	 */


	if (**termPtr == ']') {

	    *termPtr += 1;
	}



	return result;



    }
    (*termPtr) += 1;





    length = strlen(iPtr->result);








    shortfall = length + 1 - (pvPtr->end - pvPtr->next);
    if (shortfall > 0) {




	(*pvPtr->expandProc)(pvPtr, shortfall);




    }







    strcpy(pvPtr->next, iPtr->result);




    pvPtr->next += length;






    





    Tcl_FreeResult(interp);


    iPtr->result = iPtr->resultSpace;
    iPtr->resultSpace[0] = '\0';
    return TCL_OK;
}
















































/*














 *--------------------------------------------------------------
 *
 * TclParseBraces --
 *
 *	This procedure scans the information between matching
 *	curly braces.

 *
 * Results:
 *	The return value is a standard Tcl result, which is



 *	TCL_OK unless there was an error while parsing string.
 *	If an error occurs then interp->result contains a
 *	standard error message.  *TermPtr is filled
 *	in with the address of the character just after the
 *	last one successfully processed;  this is usually the
 *	character just after the matching close-brace.  The
 *	information between curly braces is stored in standard
 *	fashion in *pvPtr, null-terminated with pvPtr->next
 *	pointing to the terminating null character.
 *


























 * Side effects:
 *	The storage space at *pvPtr may be expanded.


 *
 *--------------------------------------------------------------
 */






int
TclParseBraces(interp, string, termPtr, pvPtr)
    Tcl_Interp *interp;		/* Interpreter to use for nested command
				 * evaluations and error messages. */
    char *string;		/* Character just after opening bracket. */
    char **termPtr;		/* Store address of terminating character
				 * here. */
    register ParseValue *pvPtr;	/* Information about where to place
				 * result of command. */







{








    int level;
    register char *src, *dst, *end;
    register char c;
    char *lastChar = string + strlen(string);










    src = string;
    dst = pvPtr->next;




















    end = pvPtr->end;
    level = 1;

    /*
     * Copy the characters one at a time to the result area, stopping
     * when the matching close-brace is found.

     */










    while (1) {


	c = *src;
	src++;
	if (dst == end) {







	    pvPtr->next = dst;




	    (*pvPtr->expandProc)(pvPtr, 20);
	    dst = pvPtr->next;
	    end = pvPtr->end;

	}
	*dst = c;
	dst++;
	if (CHAR_TYPE(src-1, lastChar) == TCL_NORMAL) {




	    continue;
	} else if (c == '{') {

	    level++;



	} else if (c == '}') {







	    level--;

	    if (level == 0) {
		dst--;			/* Don't copy the last close brace. */
		break;




	    }
	} else if (c == '\\') {

	    int count;














	    /*


	     * Must always squish out backslash-newlines, even when in


	     * braces.  This is needed so that this sequence can appear





	     * anywhere in a command, such as the middle of an expression.



	     */


































































	    if (*src == '\n') {
		dst[-1] = Tcl_Backslash(src-1, &count);

		src += count - 1;

	    } else {
		(void) Tcl_Backslash(src-1, &count);
		while (count > 1) {
                    if (dst == end) {
                        pvPtr->next = dst;
                        (*pvPtr->expandProc)(pvPtr, 20);
                        dst = pvPtr->next;
                        end = pvPtr->end;



                    }
		    *dst = *src;
		    dst++;
		    src++;
		    count--;
		}
	    }













	} else if (c == '\0') {
	    Tcl_SetResult(interp, "missing close-brace", TCL_STATIC);
	    *termPtr = string-1;

	    return TCL_ERROR;
	}
    }















    *dst = '\0';
    pvPtr->next = dst;
    *termPtr = src;
    return TCL_OK;
}

























/*
 *--------------------------------------------------------------
 *
 * TclExpandParseValue --
 *
 *	This procedure is commonly used as the value of the
 *	expandProc in a ParseValue.  It uses malloc to allocate
 *	more space for the result of a parse.


 *
 * Results:
 *	The buffer space in *pvPtr is reallocated to something
 *	larger, and if pvPtr->clientData is non-zero the old
 *	buffer is freed.  Information is copied from the old
 *	buffer to the new one.
 *
 * Side effects:




 *	None.
 *
 *--------------------------------------------------------------
 */

void













TclExpandParseValue(pvPtr, needed)





    register ParseValue *pvPtr;		/* Information about buffer that


					 * must be expanded.  If the clientData



					 * in the structure is non-zero, it






					 * means that the current buffer is




					 * dynamically allocated. */

















    int needed;				/* Minimum amount of additional space


















					 * to allocate. */



{



    int newSpace;














    char *new;



    /*





     * Either double the size of the buffer or add enough new space



     * to meet the demand, whichever produces a larger new buffer.




     */














































    newSpace = (pvPtr->end - pvPtr->buffer) + 1;


    if (newSpace < needed) {
	newSpace += needed;

    } else {
	newSpace += newSpace;
    }














    new = (char *) ckalloc((unsigned) newSpace);




    /*



     * Copy from old buffer to new, free old buffer if needed, and





















     * mark new buffer as malloc-ed.







     */



















    memcpy((VOID *) new, (VOID *) pvPtr->buffer,






















	    (size_t) (pvPtr->next - pvPtr->buffer));





    pvPtr->next = new + (pvPtr->next - pvPtr->buffer);

    if (pvPtr->clientData != 0) {




	ckfree(pvPtr->buffer);



    }
    pvPtr->buffer = new;




    pvPtr->end = new + newSpace - 1;




















    pvPtr->clientData = (ClientData) 1;





}




























































































































/*











 *----------------------------------------------------------------------
 *
 * TclWordEnd --
 *
 *	Given a pointer into a Tcl command, find the end of the next

 *	word of the command.
 *
 * Results:
 *	The return value is a pointer to the last character that's part
 *	of the word pointed to by "start".  If the word doesn't end
 *	properly within the string then the return value is the address
 *	of the null character at the end of the string.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */









char *




TclWordEnd(start, lastChar, nested, semiPtr)



    char *start;		/* Beginning of a word of a Tcl command. */





    char *lastChar;		/* Terminating character in string. */



    int nested;			/* Zero means this is a top-level command.

















				 * One means this is a nested command (close




				 * bracket is a word terminator). */
    int *semiPtr;		/* Set to 1 if word ends with a command-







				 * terminating semi-colon, zero otherwise.

				 * If NULL then ignored. */
{

    register char *p;



    int count;





























    if (semiPtr != NULL) {


	*semiPtr = 0;



    }




    /*
     * Skip leading white space (backslash-newline must be treated like











     * white-space, except that it better not be the last thing in the
     * command).


     */




























    for (p = start; ; p++) {



	if (isspace(UCHAR(*p))) {


	    continue;
	}
	if ((p[0] == '\\') && (p[1] == '\n')) {
	    if (p+2 == lastChar) {

		return p+2;
	    }
	    continue;
	}
	break;
    }

    /*
     * Handle words beginning with a double-quote or a brace.
     */

    if (*p == '"') {
	p = QuoteEnd(p+1, lastChar, '"');
	if (p == lastChar) {
	    return p;
	}
	p++;
    } else if (*p == '{') {
	int braces = 1;
	while (braces != 0) {
	    p++;
	    while (*p == '\\') {
		(void) Tcl_Backslash(p, &count);
		p += count;
	    }
	    if (*p == '}') {
		braces--;
	    } else if (*p == '{') {
		braces++;
	    } else if (p == lastChar) {
		return p;
	    }
	}
	p++;
    }

    /*
     * Handle words that don't start with a brace or double-quote.
     * This code is also invoked if the word starts with a brace or
     * double-quote and there is garbage after the closing brace or
     * quote.  This is an error as far as Tcl_Eval is concerned, but
     * for here the garbage is treated as part of the word.
     */

    while (1) {
	if (*p == '[') {
	    p = ScriptEnd(p+1, lastChar, 1);
	    if (p == lastChar) {
		return p;
	    }
	    p++;
	} else if (*p == '\\') {
	    if (p[1] == '\n') {
		/*
		 * Backslash-newline:  it maps to a space character
		 * that is a word separator, so the word ends just before
		 * the backslash.
		 */

		return p-1;
	    }
	    (void) Tcl_Backslash(p, &count);
	    p += count;
	} else if (*p == '$') {
	    p = VarNameEnd(p, lastChar);
	    if (p == lastChar) {
		return p;
	    }
	    p++;
	} else if (*p == ';') {
	    /*
	     * Include the semi-colon in the word that is returned.
	     */

	    if (semiPtr != NULL) {
		*semiPtr = 1;
	    }
	    return p;
	} else if (isspace(UCHAR(*p))) {
	    return p-1;
	} else if ((*p == ']') && nested) {
	    return p-1;
	} else if (p == lastChar) {
	    if (nested) {
		/*
		 * Nested commands can't end because of the end of the
		 * string.
		 */
		return p;
	    }
	    return p-1;
	} else {
	    p++;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * QuoteEnd --
 *
 *	Given a pointer to a string that obeys the parsing conventions
 *	for quoted things in Tcl, find the end of that quoted thing.
 *	The actual thing may be a quoted argument or a parenthesized
 *	index name.
 *
 * Results:
 *	The return value is a pointer to the last character that is
 *	part of the quoted string (i.e the character that's equal to
 *	term).  If the quoted string doesn't terminate properly then
 *	the return value is a pointer to the null character at the
 *	end of the string.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


static char *
QuoteEnd(string, lastChar, term)
    char *string;		/* Pointer to character just after opening
				 * "quote". */
    char *lastChar;		/* Terminating character in string. */
    int term;			/* This character will terminate the
				 * quoted string (e.g. '"' or ')'). */
{
    register char *p = string;
    int count;

    while (*p != term) {
	if (*p == '\\') {
	    (void) Tcl_Backslash(p, &count);
	    p += count;
	} else if (*p == '[') {
	    for (p++; *p != ']'; p++) {
		p = TclWordEnd(p, lastChar, 1, (int *) NULL);
		if (*p == 0) {
		    return p;
		}
	    }
	    p++;
	} else if (*p == '$') {
	    p = VarNameEnd(p, lastChar);
	    if (*p == 0) {
		return p;
	    }
	    p++;
	} else if (p == lastChar) {
	    return p;
	} else {
	    p++;
	}
    }
    return p-1;
}

/*
 *----------------------------------------------------------------------
 *
 * VarNameEnd --
 *
 *	Given a pointer to a variable reference using $-notation, find
 *	the end of the variable name spec.
 *
 * Results:
 *	The return value is a pointer to the last character that
 *	is part of the variable name.  If the variable name doesn't
 *	terminate properly then the return value is a pointer to the
 *	null character at the end of the string.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
VarNameEnd(string, lastChar)
    char *string;		/* Pointer to dollar-sign character. */
    char *lastChar;		/* Terminating character in string. */
{
    register char *p = string+1;

    if (*p == '{') {
	for (p++; (*p != '}') && (p != lastChar); p++) {
	    /* Empty loop body. */
	}
	return p;
    }
    while (isalnum(UCHAR(*p)) || (*p == '_')) {
	p++;
    }
    if ((*p == '(') && (p != string+1)) {
	return QuoteEnd(p+1, lastChar, ')');
    }
    return p-1;
}


/*
 *----------------------------------------------------------------------
 *
 * ScriptEnd --
 *
 *	Given a pointer to the beginning of a Tcl script, find the end of
 *	the script.
 *
 * Results:
 *	The return value is a pointer to the last character that's part
 *	of the script pointed to by "p".  If the command doesn't end
 *	properly within the string then the return value is the address
 *	of the null character at the end of the string.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
ScriptEnd(p, lastChar, nested)
    char *p;			/* Script to check. */
    char *lastChar;		/* Terminating character in string. */
    int nested;			/* Zero means this is a top-level command.
				 * One means this is a nested command (the
				 * last character of the script must be
				 * an unquoted ]). */
{
    int commentOK = 1;
    int length;

    while (1) {
	while (isspace(UCHAR(*p))) {
	    if (*p == '\n') {
		commentOK = 1;
	    }
	    p++;
	}
	if ((*p == '#') && commentOK) {
	    do {
		if (*p == '\\') {
		    /*
		     * If the script ends with backslash-newline, then
		     * this command isn't complete.
		     */

		    if ((p[1] == '\n') && (p+2 == lastChar)) {
			return p+2;
		    }
		    Tcl_Backslash(p, &length);
		    p += length;
		} else {
		    p++;
		}
	    } while ((p != lastChar) && (*p != '\n'));
	    continue;
	}
	p = TclWordEnd(p, lastChar, nested, &commentOK);
	if (p == lastChar) {
	    return p;


	}
	p++;
	if (nested) {
	    if (*p == ']') {
		return p;
	    }
	} else {
	    if (p == lastChar) {
		return p-1;
	    }
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ParseVar --
 *
 *	Given a string starting with a $ sign, parse off a variable
 *	name and return its value.
 *
 * Results:
 *	The return value is the contents of the variable given by
 *	the leading characters of string.  If termPtr isn't NULL,
 *	*termPtr gets filled in with the address of the character
 *	just after the last one in the variable specifier.  If the
 *	variable doesn't exist, then the return value is NULL and
 *	an error message will be left in interp->result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_ParseVar(interp, string, termPtr)
    Tcl_Interp *interp;			/* Context for looking up variable. */
    register char *string;		/* String containing variable name.
					 * First character must be "$". */
    char **termPtr;			/* If non-NULL, points to word to fill
					 * in with character just after last
					 * one in the variable specifier. */

{


    char *name1, *name1End, c, *result;



    register char *name2;







#define NUM_CHARS 200


    char copyStorage[NUM_CHARS];




    ParseValue pv;























    /*
     * There are three cases:
     * 1. The $ sign is followed by an open curly brace.  Then the variable
     *    name is everything up to the next close curly brace, and the
     *    variable is a scalar variable.
     * 2. The $ sign is not followed by an open curly brace.  Then the
     *    variable name is everything up to the next character that isn't
     *    a letter, digit, or underscore, or a "::" namespace separator.
     *    If the following character is an open parenthesis, then the
     *    information between parentheses is the array element name, which

     *    can include any of the substitutions permissible between quotes.
     * 3. The $ sign is followed by something that isn't a letter, digit,

     *    underscore, or a "::" namespace separator: in this case,
     *    there is no variable name, and "$" is returned.






     */




























    name2 = NULL;

    string++;



    if (*string == '{') {





	string++;




	name1 = string;










	while (*string != '}') {





	    if (*string == 0) {











































		Tcl_SetResult(interp, "missing close-brace for variable name",
			TCL_STATIC);
		if (termPtr != 0) {

		    *termPtr = string;




		}
		return NULL;
	    }
	    string++;
	}
	name1End = string;
	string++;


    } else {




	name1 = string;

	while (isalnum(UCHAR(*string)) || (*string == '_')
	        || (*string == ':')) {
	    if (*string == ':') {
		if (*(string+1) == ':') {
                    string += 2;  /* skip over the initial :: */
		    while (*string == ':') {
			string++; /* skip over a subsequent : */
		    }
		} else {
		    break;	  /* : by itself */
                }
	    } else {

		string++;
	    }

	}

	if (string == name1) {
	    if (termPtr != 0) {
		*termPtr = string;
	    }
	    return "$";
	}
	name1End = string;



	if (*string == '(') {
	    char *end;





	    /*






	     * Perform substitutions on the array element name, just as

	     * is done for quotes.







	     */























	    pv.buffer = pv.next = copyStorage;
	    pv.end = copyStorage + NUM_CHARS - 1;
	    pv.expandProc = TclExpandParseValue;
	    pv.clientData = (ClientData) NULL;
	    if (TclParseQuotes(interp, string+1, ')', 0, &end, &pv)
		    != TCL_OK) {
		char msg[200];
		int length;

		length = string-name1;
		if (length > 100) {





		    length = 100;

		}
		sprintf(msg, "\n    (parsing index for array \"%.*s\")",
			length, name1);

		Tcl_AddErrorInfo(interp, msg);


		result = NULL;


		name2 = pv.buffer;



		if (termPtr != 0) {
		    *termPtr = end;









		}
		goto done;
	    }









	    Tcl_ResetResult(interp);
	    string = end;




	    name2 = pv.buffer;




	}







    }
    if (termPtr != 0) {
	*termPtr = string;





    }

    c = *name1End;
    *name1End = 0;
    result = Tcl_GetVar2(interp, name1, name2, TCL_LEAVE_ERR_MSG);
    *name1End = c;

    done:
    if ((name2 != NULL) && (pv.buffer != copyStorage)) {
	ckfree(pv.buffer);
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CommandComplete --
 *
 *	Given a partial or complete Tcl command, this procedure
 *	determines whether the command is complete in the sense
 *	of having matched braces and quotes and brackets.
 *
 * Results:
 *	1 is returned if the command is complete, 0 otherwise.


 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_CommandComplete(cmd)
    char *cmd;			/* Command to check. */
{
    char *p;

    if (*cmd == 0) {
	return 1;
    }
    p = ScriptEnd(cmd, cmd+strlen(cmd), 0);
    return (*p != 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TclObjCommandComplete --
 *



|
|
|
>
>
>

|
|




|






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


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

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

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

<
|

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

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

>
|
>
|

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

|

|
<
>


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

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

<
>
>

|

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

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

|

|

|
<
<
>
>


<
<
<
|


>
>
>
>
|

|



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


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

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


|

<
>
|


<
<
<
|


|



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

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

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

>
>
>


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

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

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


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
















|

















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

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

|







|
|



|
>
>








|
<
<
|
|
<
|
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

100
101

102









103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138



139


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





174





175
176


177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237

238



239
240
241
242
243
244




245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296
297
298
299


300

301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423
424
425
426

427
428
429
430
431
432
433



434
435
436
437
438

439
440




441
442
443
444
445
446
447
448
449
450
451
452
453


454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491

492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533

534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680

681
682
683

684
685
686
687

688






689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
724
725
726
727
728

729
730

731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751



752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784

785
786


787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821

822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845


846
847
848
849
850

851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955






956
957
958
959
960



961


962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980

981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996

997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030


1031
1032
1033
1034



1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211

1212
1213
1214

1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505

1506
1507
1508
1509



1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628

1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640

1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690



1691


1692

1693












1694






1695
1696



1697


1698














1699













1700
1701
1702








1703







1704

1705


1706





1707




1708











1709
1710
1711







1712
1713
1714








1715
1716
1717
1718
1719
1720










1721
1722

1723


















1724






1725














1726



1727




1728






1729




1730











1731



1732










1733

1734
1735


1736






1737

1738
1739
1740



1741







1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822



1823
1824
1825
1826

1827
1828
1829

1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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

1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074

2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085

2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140


2141
2142

2143



2144
2145
2146
2147
2148
2149
2150
/* 
 * tclParse.c --
 *
 *	This file contains procedures that parse Tcl scripts.  They
 *	do so in a general-purpose fashion that can be used for many
 *	different purposes, including compilation, direct execution,
 *	code analysis, etc.  This file also includes a few additional
 *	procedures such as Tcl_EvalObjv, Tcl_Eval, and Tcl_EvalEx, which
 *	allow scripts to be evaluated directly, without compiling.
 *
 * 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.1.2.12 1999/04/14 00:33:26 surles Exp $
 */

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

/*
 * The following table provides parsing information about each possible
 * 8-bit character.  The table is designed to be referenced with either
 * signed or unsigned characters, so it has 384 entries.  The first 128
 * entries correspond to negative character values, the next 256 correspond
 * to positive character values.  The last 128 entries are identical to the
 * first 128.  The table is always indexed with a 128-byte offset (the 128th
 * entry corresponds to a character value of 0).
 *
 * The macro CHAR_TYPE is used to index into the table and return
 * information about its character argument.  The following return
 * values are defined.
 *
 * TYPE_NORMAL -	All characters that don't have special significance
 *			to the Tcl parser.
 * TYPE_SPACE -		The character is a whitespace character other
 *			than newline.
 * TYPE_COMMAND_END -	Character is newline or semicolon.
 * TYPE_SUBS -		Character begins a substitution or has other
 *			special meaning in ParseTokens: backslash, dollar
 *			sign, open bracket, or null.
 * TYPE_QUOTE -		Character is a double quote.
 * TYPE_CLOSE_PAREN -	Character is a right parenthesis.
 * TYPE_CLOSE_BRACK -	Character is a right square bracket.
 * TYPE_BRACE -		Character is a curly brace (either left or right).
 */

#define TYPE_NORMAL		0
#define TYPE_SPACE		0x1
#define TYPE_COMMAND_END	0x2
#define TYPE_SUBS		0x4
#define TYPE_QUOTE		0x8
#define TYPE_CLOSE_PAREN	0x10
#define TYPE_CLOSE_BRACK	0x20
#define TYPE_BRACE		0x40

#define CHAR_TYPE(c) (typeTable+128)[(int)(c)]

char typeTable[] = {
    /*
     * Negative character values, from -128 to -1:
     */


    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,

    /*

     * Positive character values, from 0-127:
     */











    TYPE_SUBS,        TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_SPACE,       TYPE_COMMAND_END, TYPE_SPACE,
    TYPE_SPACE,       TYPE_SPACE,       TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_SPACE,       TYPE_NORMAL,      TYPE_QUOTE,       TYPE_NORMAL,
    TYPE_SUBS,        TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_CLOSE_PAREN, TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_COMMAND_END,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_SUBS,
    TYPE_SUBS,        TYPE_CLOSE_BRACK, TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_BRACE,
    TYPE_NORMAL,      TYPE_BRACE,       TYPE_NORMAL,      TYPE_NORMAL,

    /*
     * Large unsigned character values, from 128-255:
     */






    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
};






/*





 * Prototypes for local procedures defined in this file:
 */



static int		CommandComplete _ANSI_ARGS_((char *script,
			    int length));
static int		ParseTokens _ANSI_ARGS_((char *src, int mask,
			    Tcl_Parse *parsePtr));
static int		EvalObjv _ANSI_ARGS_((Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[], char *command, int length,
			    int flags));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ParseCommand --
 *
 *	Given a string, this procedure parses the first Tcl command
 *	in the string and returns information about the structure of
 *	the command.
 *
 * Results:
 *	The return value is TCL_OK if the command was parsed
 *	successfully and TCL_ERROR otherwise.  If an error occurs
 *	and interp isn't NULL then an error message is left in
 *	its result.  On a successful return, parsePtr is filled in
 *	with information about the command that was parsed.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the command, then additional space is
 *	malloc-ed.  If the procedure returns TCL_OK then the caller must
 *	eventually invoke Tcl_FreeParse to release any additional space
 *	that was allocated.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ParseCommand(interp, string, numBytes, nested, parsePtr)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting;
				 * if NULL, then no error message is
				 * provided. */
    char *string;		/* First character of string containing
				 * one or more Tcl commands.  The string
				 * must be in writable memory and must
				 * have one additional byte of space at

				 * string[length] where we can
				 * temporarily store a 0 sentinel
				 * character. */
    int numBytes;		/* Total number of bytes in string.  If < 0,
				 * the script consists of all bytes up to 
				 * the first null character. */

    int nested;			/* Non-zero means this is a nested command:
				 * close bracket should be considered
				 * a command terminator. If zero, then close
				 * bracket has no special meaning. */
    register Tcl_Parse *parsePtr;
    				/* Structure to fill in with information
				 * about the parsed command; any previous
				 * information in the structure is
				 * ignored. */
{
    register char *src;		/* Points to current character

				 * in the command. */



    int type;			/* Result returned by CHAR_TYPE(*src). */
    Tcl_Token *tokenPtr;	/* Pointer to token being filled in. */
    int wordIndex;		/* Index of word token for current word. */
    char utfBytes[TCL_UTF_MAX];	/* Holds result of backslash substitution. */
    int terminators;		/* CHAR_TYPE bits that indicate the end
				 * of a command. */




    char *termPtr;		/* Set by Tcl_ParseBraces/QuotedString to
				 * point to char after terminating one. */
    int length, savedChar;


    if (numBytes < 0) {
	numBytes = (string? strlen(string) : 0);
    }
    parsePtr->commentStart = NULL;
    parsePtr->commentSize = 0;
    parsePtr->commandStart = NULL;
    parsePtr->commandSize = 0;
    parsePtr->numWords = 0;
    parsePtr->tokenPtr = parsePtr->staticTokens;
    parsePtr->numTokens = 0;
    parsePtr->tokensAvailable = NUM_STATIC_TOKENS;
    parsePtr->string = string;
    parsePtr->end = string + numBytes;
    parsePtr->interp = interp;
    parsePtr->incomplete = 0;
    if (nested != 0) {
	terminators = TYPE_COMMAND_END | TYPE_CLOSE_BRACK;
    } else {
	terminators = TYPE_COMMAND_END;
    }

    /*
     * Temporarily overwrite the character just after the end of the
     * string with a 0 byte.  This acts as a sentinel and reduces the
     * number of places where we have to check for the end of the
     * input string.  The original value of the byte is restored at
     * the end of the parse.
     */

    savedChar = string[numBytes];
    string[numBytes] = 0;

    /*
     * Parse any leading space and comments before the first word of the
     * command.
     */

    src = string;
    while (1) {

	while ((CHAR_TYPE(*src) == TYPE_SPACE) || (*src == '\n')) {
	    src++;
	}
	if ((*src == '\\') && (src[1] == '\n')) {
	    /*
	     * Skip backslash-newline sequence: it should be treated
	     * just like white space.
	     */

	    if ((src + 2) == parsePtr->end) {
		parsePtr->incomplete = 1;


	    }

	    src += 2;
	    continue;
	}
	if (*src != '#') {
	    break;
	}
	if (parsePtr->commentStart == NULL) {
	    parsePtr->commentStart = src;
	}
	while (1) {
	    if (src == parsePtr->end) {
		if (nested) {
		    parsePtr->incomplete = nested;
		}
		parsePtr->commentSize = src - parsePtr->commentStart;

		break;
	    } else if (*src == '\\') {
		if ((src[1] == '\n') && ((src + 2) == parsePtr->end)) {
		    parsePtr->incomplete = 1;
		}
		Tcl_UtfBackslash(src, &length, utfBytes);
		src += length;
	    } else if (*src == '\n') {
		src++;
		parsePtr->commentSize = src - parsePtr->commentStart;
		break;
	    } else {
		src++;
	    }
	}
    }

    /*
     * The following loop parses the words of the command, one word
     * in each iteration through the loop.
     */

    parsePtr->commandStart = src;
    while (1) {
	/*
	 * Create the token for the word.
	 */

	if (parsePtr->numTokens == parsePtr->tokensAvailable) {
	    TclExpandTokenArray(parsePtr);
	}
	wordIndex = parsePtr->numTokens;
	tokenPtr = &parsePtr->tokenPtr[wordIndex];
	tokenPtr->type = TCL_TOKEN_WORD;

	/*
	 * Skip white space before the word. Also skip a backslash-newline
	 * sequence: it should be treated just like white space.
	 */

	while (1) {
	    type = CHAR_TYPE(*src);
	    if (type == TYPE_SPACE) {
		src++;
		continue;
	    } else if ((*src == '\\') && (src[1] == '\n')) {
		if ((src + 2) == parsePtr->end) {
		    parsePtr->incomplete = 1;
		}
		Tcl_UtfBackslash(src, &length, utfBytes);
		src += length;
		continue;
	    }
	    break;
	}
	if ((type & terminators) != 0) {
	    src++;
	    break;
	}
	if (src == parsePtr->end) {
	    break;
	}
	tokenPtr->start = src;
	parsePtr->numTokens++;
	parsePtr->numWords++;

	/*
	 * At this point the word can have one of three forms: something
	 * enclosed in quotes, something enclosed in braces, or an
	 * unquoted word (anything else).
	 */

	if (*src == '"') {
	    if (Tcl_ParseQuotedString(interp, src, (parsePtr->end - src),
	            parsePtr, 1, &termPtr) != TCL_OK) {

		goto error;
	    }
	    src = termPtr;
	} else if (*src == '{') {
	    if (Tcl_ParseBraces(interp, src, (parsePtr->end - src),
	            parsePtr, 1, &termPtr) != TCL_OK) {
		goto error;
	    }
	    src = termPtr;
	} else {
	    /*
	     * This is an unquoted word.  Call ParseTokens and let it do
	     * all of the work.
	     */

	    if (ParseTokens(src, TYPE_SPACE|terminators, 
		    parsePtr) != TCL_OK) {
		goto error;
	    }
	    src = parsePtr->term;
	}

	/*

	 * Finish filling in the token for the word and check for the
	 * special case of a word consisting of a single range of
	 * literal text.
	 */

	tokenPtr = &parsePtr->tokenPtr[wordIndex];
	tokenPtr->size = src - tokenPtr->start;
	tokenPtr->numComponents = parsePtr->numTokens - (wordIndex + 1);
	if ((tokenPtr->numComponents == 1)
		&& (tokenPtr[1].type == TCL_TOKEN_TEXT)) {
	    tokenPtr->type = TCL_TOKEN_SIMPLE_WORD;
	}


	/*
	 * Do two additional checks: (a) make sure we're really at the
	 * end of a word (there might have been garbage left after a
	 * quoted or braced word), and (b) check for the end of the
	 * command.
	 */




	type = CHAR_TYPE(*src);
	if (type == TYPE_SPACE) {
	    src++;
	    continue;
	} else {

	    /*
	     * Backslash-newline (and any following white space) must be




	     * treated as if it were a space character.
	     */

	    if ((*src == '\\') && (src[1] == '\n')) {
		if ((src + 2) == parsePtr->end) {
		    parsePtr->incomplete = 1;
		}
		Tcl_UtfBackslash(src, &length, utfBytes);
		src += length;
		continue;
	    }
	}



	if ((type & terminators) != 0) {
	    src++;
	    break;
	}
	if (src == parsePtr->end) {
	    break;
	}
	if (interp != NULL) {
	    if (src[-1] == '"') { 
		Tcl_SetResult(interp, "extra characters after close-quote",
			TCL_STATIC);
	    } else {
		Tcl_SetResult(interp, "extra characters after close-brace",
			TCL_STATIC);
	    }
	}
	parsePtr->term = src;
	goto error;
    }


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

/*
 *----------------------------------------------------------------------
 *
 * ParseTokens --
 *
 *	This procedure forms the heart of the Tcl parser.  It parses one
 *	or more tokens from a string, up to a termination point
 *	specified by the caller.  This procedure is used to parse
 *	unquoted command words (those not in quotes or braces), words in
 *	quotes, and array indices for variables.
 *
 * Results:
 *	Tokens are added to parsePtr and parsePtr->term is filled in
 *	with the address of the character that terminated the parse (the
 *	first one whose CHAR_TYPE matched mask or the character at
 *	parsePtr->end).  The return value is TCL_OK if the parse
 *	completed successfully and TCL_ERROR otherwise.  If a parse
 *	error occurs and parsePtr->interp isn't NULL, then an error
 *	message is left in the interpreter's result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ParseTokens(src, mask, parsePtr)
    register char *src;		/* First character to parse. */
    int mask;			/* Specifies when to stop parsing.  The
				 * parse stops at the first unquoted
				 * character whose CHAR_TYPE contains
				 * any of the bits in mask. */
    Tcl_Parse *parsePtr;	/* Information about parse in progress.
				 * Updated with additional tokens and
				 * termination information. */
{
    int type, originalTokens, varToken;
    char utfBytes[TCL_UTF_MAX];
    Tcl_Token *tokenPtr;
    Tcl_Parse nested;


    /*
     * Each iteration through the following loop adds one token of
     * type TCL_TOKEN_TEXT, TCL_TOKEN_BS, TCL_TOKEN_COMMAND, or
     * TCL_TOKEN_VARIABLE to parsePtr.  For TCL_TOKEN_VARIABLE tokens,
     * additional tokens are added for the parsed variable name.
     */

    originalTokens = parsePtr->numTokens;
    while (1) {
	if (parsePtr->numTokens == parsePtr->tokensAvailable) {
	    TclExpandTokenArray(parsePtr);
	}
	tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
	tokenPtr->start = src;
	tokenPtr->numComponents = 0;

	type = CHAR_TYPE(*src);
	if (type & mask) {
	    break;
	}

	if ((type & TYPE_SUBS) == 0) {
	    /*
	     * This is a simple range of characters.  Scan to find the end
	     * of the range.
	     */

	    while (1) {
		src++;
		if (CHAR_TYPE(*src) & (mask | TYPE_SUBS)) {
		    break;
		}
	    }
	    tokenPtr->type = TCL_TOKEN_TEXT;
	    tokenPtr->size = src - tokenPtr->start;
	    parsePtr->numTokens++;
	} else if (*src == '$') {
	    /*
	     * This is a variable reference.  Call Tcl_ParseVarName to do
	     * all the dirty work of parsing the name.
	     */

	    varToken = parsePtr->numTokens;
	    if (Tcl_ParseVarName(parsePtr->interp, src, parsePtr->end - src,
		    parsePtr, 1) != TCL_OK) {
		return TCL_ERROR;
	    }
	    src += parsePtr->tokenPtr[varToken].size;
	} else if (*src == '[') {
	    /*
	     * Command substitution.  Call Tcl_ParseCommand recursively
	     * (and repeatedly) to parse the nested command(s), then
	     * throw away the parse information.
	     */

	    src++;
	    while (1) {
		if (Tcl_ParseCommand(parsePtr->interp, src,
			parsePtr->end - src, 1, &nested) != TCL_OK) {
		    parsePtr->term = nested.term;
		    parsePtr->incomplete = nested.incomplete;
		    return TCL_ERROR;
		}
		src = nested.commandStart + nested.commandSize;
		if (nested.tokenPtr != nested.staticTokens) {
		    ckfree((char *) nested.tokenPtr);
		}
		if ((src[-1] == ']') && !nested.incomplete) {
		    break;
		}
		if (src == parsePtr->end) {
		    if (parsePtr->interp != NULL) {
			Tcl_SetResult(parsePtr->interp,
			    "missing close-bracket", TCL_STATIC);
		    }
		    parsePtr->term = tokenPtr->start;
		    parsePtr->incomplete = 1;
		    return TCL_ERROR;
		}
	    }
	    tokenPtr->type = TCL_TOKEN_COMMAND;
	    tokenPtr->size = src - tokenPtr->start;
	    parsePtr->numTokens++;
	} else if (*src == '\\') {
	    /*
	     * Backslash substitution.
	     */

	    if (src[1] == '\n') {
		if ((src + 2) == parsePtr->end) {
		    parsePtr->incomplete = 1;
		}

		/*
		 * Note: backslash-newline is special in that it is
		 * treated the same as a space character would be.  This
		 * means that it could terminate the token.
		 */

		if (mask & TYPE_SPACE) {
		    break;
		}
	    }
	    tokenPtr->type = TCL_TOKEN_BS;
	    Tcl_UtfBackslash(src, &tokenPtr->size, utfBytes);
	    parsePtr->numTokens++;
	    src += tokenPtr->size;
	} else if (*src == 0) {
	    /*
	     * We encountered a null character.  If it is the null
	     * character at the end of the string, then return.
	     * Otherwise generate a text token for the single
	     * character.
	     */

	    if (src == parsePtr->end) {
		break;
	    }
	    tokenPtr->type = TCL_TOKEN_TEXT;
	    tokenPtr->size = 1;
	    parsePtr->numTokens++;
	    src++;
	} else {
	    panic("ParseTokens encountered unknown character");
	}
    }
    if (parsePtr->numTokens == originalTokens) {
	/*
	 * There was nothing in this range of text.  Add an empty token
	 * for the empty range, so that there is always at least one
	 * token added.
	 */

	tokenPtr->type = TCL_TOKEN_TEXT;
	tokenPtr->size = 0;
	parsePtr->numTokens++;
    }
    parsePtr->term = src;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FreeParse --
 *
 *	This procedure is invoked to free any dynamic storage that may

 *	have been allocated by a previous call to Tcl_ParseCommand.
 *
 * Results:

 *	None.
 *
 * Side effects:
 *	If there is any dynamically allocated memory in *parsePtr,

 *	it is freed.






 *
 *----------------------------------------------------------------------
 */

void
Tcl_FreeParse(parsePtr)
    Tcl_Parse *parsePtr;	/* Structure that was filled in by a
				 * previous call to Tcl_ParseCommand. */
{
    if (parsePtr->tokenPtr != parsePtr->staticTokens) {
	ckfree((char *) parsePtr->tokenPtr);
	parsePtr->tokenPtr = parsePtr->staticTokens;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclExpandTokenArray --
 *
 *	This procedure is invoked when the current space for tokens in
 *	a Tcl_Parse structure fills up; it allocates memory to grow the
 *	token array
 *
 * Results:
 *	None.
 *
 * Side effects:

 *	Memory is allocated for a new larger token array; the memory
 *	for the old array is freed, if it had been dynamically allocated.
 *
 *----------------------------------------------------------------------
 */

void
TclExpandTokenArray(parsePtr)
    Tcl_Parse *parsePtr;	/* Parse structure whose token space
				 * has overflowed. */
{
    int newCount;

    Tcl_Token *newPtr;


    newCount = parsePtr->tokensAvailable*2;
    newPtr = (Tcl_Token *) ckalloc((unsigned) (newCount * sizeof(Tcl_Token)));
    memcpy((VOID *) newPtr, (VOID *) parsePtr->tokenPtr,
	    (size_t) (parsePtr->tokensAvailable * sizeof(Tcl_Token)));
    if (parsePtr->tokenPtr != parsePtr->staticTokens) {
	ckfree((char *) parsePtr->tokenPtr);
	parsePtr->tokenPtr = parsePtr->staticTokens;
    }
    parsePtr->tokenPtr = newPtr;
    parsePtr->tokensAvailable = newCount;
}

/*
 *----------------------------------------------------------------------
 *
 * EvalObjv --
 *
 *	This procedure evaluates a Tcl command that has already been
 *	parsed into words, with one Tcl_Obj holding each word.
 *
 * Results:



 *	The return value is a standard Tcl completion code such as
 *	TCL_OK or TCL_ERROR.  A result or error message is left in
 *	interp's result.  If an error occurs, this procedure does
 *	NOT add any information to the errorInfo variable.
 *
 * Side effects:
 *	Depends on the command.
 *
 *----------------------------------------------------------------------
 */

static int
EvalObjv(interp, objc, objv, command, length, flags)
    Tcl_Interp *interp;		/* Interpreter in which to evaluate the
				 * command.  Also used for error
				 * reporting. */
    int objc;			/* Number of words in command. */
    Tcl_Obj *CONST objv[];	/* An array of pointers to objects that are
				 * the words that make up the command. */
    char *command;		/* Points to the beginning of the string
				 * representation of the command; this
				 * is used for traces.  If the string
				 * representation of the command is
				 * unknown, an empty string should be
				 * supplied. */
    int length;			/* Number of bytes in command; if -1, all
				 * characters up to the first null byte are
				 * used. */
    int flags;			/* Collection of OR-ed bits that control
				 * the evaluation of the script.  Only
				 * TCL_EVAL_GLOBAL is currently
				 * supported. */


{
    Command *cmdPtr;


    Interp *iPtr = (Interp *) interp;
    Tcl_Obj **newObjv;
    int i, code;
    Trace *tracePtr, *nextPtr;
    char **argv, *commandCopy;
    CallFrame *savedVarFramePtr;	/* Saves old copy of iPtr->varFramePtr
					 * in case TCL_EVAL_GLOBAL was set. */

    Tcl_ResetResult(interp);
    if (objc == 0) {
	return TCL_OK;
    }

    /*
     * If the interpreter was deleted, return an error.
     */
    
    if (iPtr->flags & DELETED) {
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
		"attempt to call eval in deleted interpreter", -1);
	Tcl_SetErrorCode(interp, "CORE", "IDELETE",
		"attempt to call eval in deleted interpreter",
		(char *) NULL);
	return TCL_ERROR;
    }

    /*
     * Check depth of nested calls to Tcl_Eval:  if this gets too large,
     * it's probably because of an infinite loop somewhere.
     */

    if (iPtr->numLevels >= iPtr->maxNestingDepth) {
	iPtr->result =  "too many nested calls to Tcl_Eval (infinite loop?)";
	return TCL_ERROR;
    }

    iPtr->numLevels++;

    /*
     * On the Mac, we will never reach the default recursion limit before
     * blowing the stack. So we need to do a check here.
     */
    
    if (TclpCheckStackSpace() == 0) {
	/*NOTREACHED*/
	iPtr->numLevels--;
	iPtr->result =  "too many nested calls to Tcl_Eval (infinite loop?)";
	return TCL_ERROR;
    }
    
    /*
     * Find the procedure to execute this command. If there isn't one,
     * then see if there is a command "unknown".  If so, create a new
     * word array with "unknown" as the first word and the original
     * command words as arguments.  Then call ourselves recursively
     * to execute it.
     */
    
    cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[0]);
    if (cmdPtr == NULL) {


	newObjv = (Tcl_Obj **) ckalloc((unsigned)
		((objc + 1) * sizeof (Tcl_Obj *)));
	for (i = objc-1; i >= 0; i--) {
	    newObjv[i+1] = objv[i];
	}

	newObjv[0] = Tcl_NewStringObj("unknown", -1);
	Tcl_IncrRefCount(newObjv[0]);
	cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, newObjv[0]);
	if (cmdPtr == NULL) {
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "invalid command name \"", Tcl_GetString(objv[0]), "\"",
		    (char *) NULL);
	    code = TCL_ERROR;
	} else {
	    code = EvalObjv(interp, objc+1, newObjv, command, length, 0);
	}
	Tcl_DecrRefCount(newObjv[0]);
	ckfree((char *) newObjv);
	goto done;
    }
    
    /*
     * Call trace procedures if needed.
     */

    argv = NULL;
    commandCopy = command;

    for (tracePtr = iPtr->tracePtr; tracePtr != NULL; tracePtr = nextPtr) {
	nextPtr = tracePtr->nextPtr;
	if (iPtr->numLevels > tracePtr->level) {
	    continue;
	}

	/*
	 * This is a bit messy because we have to emulate the old trace
	 * interface, which uses strings for everything.
	 */

	if (argv == NULL) {
	    argv = (char **) ckalloc((unsigned) (objc + 1) * sizeof(char *));
	    for (i = 0; i < objc; i++) {
		argv[i] = Tcl_GetString(objv[i]);
	    }
	    argv[objc] = 0;

	    if (length < 0) {
		length = strlen(command);
	    } else if ((size_t)length < strlen(command)) {
		commandCopy = (char *) ckalloc((unsigned) (length + 1));
		strncpy(commandCopy, command, (size_t) length);
		commandCopy[length] = 0;
	    }
	}
	(*tracePtr->proc)(tracePtr->clientData, interp, iPtr->numLevels,
			  commandCopy, cmdPtr->proc, cmdPtr->clientData,
			  objc, argv);
    }
    if (argv != NULL) {
	ckfree((char *) argv);
    }
    if (commandCopy != command) {
	ckfree((char *) commandCopy);
    }
    
    /*
     * Finally, invoke the command's Tcl_ObjCmdProc.
     */
    
    iPtr->cmdCount++;
    savedVarFramePtr = iPtr->varFramePtr;
    if (flags & TCL_EVAL_GLOBAL) {
	iPtr->varFramePtr = NULL;
    }
    code = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);
    iPtr->varFramePtr = savedVarFramePtr;
    if (Tcl_AsyncReady()) {
	code = Tcl_AsyncInvoke(interp, code);
    }

    /*
     * If the interpreter has a non-empty string result, the result
     * object is either empty or stale because some procedure set
     * interp->result directly. If so, move the string result to the
     * result object, then reset the string result.
     */
    
    if (*(iPtr->result) != 0) {
	(void) Tcl_GetObjResult(interp);
    }

    done:
    iPtr->numLevels--;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_EvalObjv --
 *
 *	This procedure evaluates a Tcl command that has already been
 *	parsed into words, with one Tcl_Obj holding each word.
 *
 * Results:
 *	The return value is a standard Tcl completion code such as
 *	TCL_OK or TCL_ERROR.  A result or error message is left in
 *	interp's result.
 *
 * Side effects:






 *	Depends on the command.
 *
 *----------------------------------------------------------------------
 */




int


Tcl_EvalObjv(interp, objc, objv, flags)
    Tcl_Interp *interp;		/* Interpreter in which to evaluate the
				 * command.  Also used for error
				 * reporting. */
    int objc;			/* Number of words in command. */
    Tcl_Obj *CONST objv[];	/* An array of pointers to objects that are
				 * the words that make up the command. */
    int flags;			/* Collection of OR-ed bits that control
				 * the evaluation of the script.  Only
				 * TCL_EVAL_GLOBAL is currently
				 * supported. */
{
    Interp *iPtr = (Interp *)interp;
    Trace *tracePtr;
    Tcl_DString cmdBuf;
    char *cmdString = "";
    int cmdLen = 0;
    int code = TCL_OK;


    for (tracePtr = iPtr->tracePtr; tracePtr; tracePtr = tracePtr->nextPtr) {
	/*
	 * EvalObjv will increment numLevels so use "<" rather than "<="
	 */
	if (iPtr->numLevels < tracePtr->level) {
	    int i;
	    /*
	     * The command will be needed for an execution trace or stack trace
	     * generate a command string.
	     */
	cmdtraced:
	    Tcl_DStringInit(&cmdBuf);
	    for (i = 0; i < objc; i++) {
		Tcl_DStringAppendElement(&cmdBuf, Tcl_GetString(objv[i]));
	    }
	    cmdString = Tcl_DStringValue(&cmdBuf);

	    cmdLen = Tcl_DStringLength(&cmdBuf);
	    break;
	}
    }

    /*
     * Execute the command if we have not done so already
     */
    switch (code) {
	case TCL_OK:
	    code = EvalObjv(interp, objc, objv, cmdString, cmdLen, flags);
	    if (code == TCL_ERROR && cmdLen == 0)
		goto cmdtraced;
	    break;
	case TCL_ERROR:
	    Tcl_LogCommandInfo(interp, cmdString, cmdString, cmdLen);
	    break;
	default:
	    /*NOTREACHED*/
	    break;
    }

    if (cmdLen != 0) {
	Tcl_DStringFree(&cmdBuf);
    }
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_LogCommandInfo --
 *
 *	This procedure is invoked after an error occurs in an interpreter.


 *	It adds information to the "errorInfo" variable to describe the
 *	command that was being executed when the error occurred.
 *
 * Results:



 *	None.
 *
 * Side effects:
 *	Information about the command is added to errorInfo and the
 *	line number stored internally in the interpreter is set.  If this
 *	is the first call to this procedure or Tcl_AddObjErrorInfo since
 *	an error occurred, then old information in errorInfo is
 *	deleted.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_LogCommandInfo(interp, script, command, length)
    Tcl_Interp *interp;		/* Interpreter in which to log information. */
    char *script;		/* First character in script containing
				 * command (must be <= command). */
    char *command;		/* First character in command that
				 * generated the error. */
    int length;			/* Number of bytes in command (-1 means
				 * use all bytes up to first null byte). */
{
    char buffer[200];
    register char *p;
    char *ellipsis = "";
    Interp *iPtr = (Interp *) interp;

    if (iPtr->flags & ERR_ALREADY_LOGGED) {
	/*
	 * Someone else has already logged error information for this
	 * command; we shouldn't add anything more.
	 */

	return;
    }

    /*
     * Compute the line number where the error occurred.
     */

    iPtr->errorLine = 1;
    for (p = script; p != command; p++) {
	if (*p == '\n') {
	    iPtr->errorLine++;
	}
    }

    /*
     * Create an error message to add to errorInfo, including up to a
     * maximum number of characters of the command.
     */

    if (length < 0) {
	length = strlen(command);
    }
    if (length > 150) {
	length = 150;
	ellipsis = "...";
    }
    if (!(iPtr->flags & ERR_IN_PROGRESS)) {
	sprintf(buffer, "\n    while executing\n\"%.*s%s\"",
		length, command, ellipsis);
    } else {
	sprintf(buffer, "\n    invoked from within\n\"%.*s%s\"",
		length, command, ellipsis);
    }
    Tcl_AddObjErrorInfo(interp, buffer, -1);
    iPtr->flags &= ~ERR_ALREADY_LOGGED;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_EvalTokens --
 *
 *	Given an array of tokens parsed from a Tcl command (e.g., the
 *	tokens that make up a word or the index for an array variable)
 *	this procedure evaluates the tokens and concatenates their
 *	values to form a single result value.
 *
 * Results:
 *	The return value is a pointer to a newly allocated Tcl_Obj
 *	containing the value of the array of tokens.  The reference
 *	count of the returned object has been incremented.  If an error
 *	occurs in evaluating the tokens then a NULL value is returned
 *	and an error message is left in interp's result.
 *
 * Side effects:
 *	A new object is allocated to hold the result.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tcl_EvalTokens(interp, tokenPtr, count)
    Tcl_Interp *interp;		/* Interpreter in which to lookup
				 * variables, execute nested commands,
				 * and report errors. */
    Tcl_Token *tokenPtr;	/* Pointer to first in an array of tokens
				 * to evaluate and concatenate. */
    int count;			/* Number of tokens to consider at tokenPtr.
				 * Must be at least 1. */
{
    Tcl_Obj *resultPtr, *indexPtr, *valuePtr, *newPtr;
    char buffer[TCL_UTF_MAX];
#ifdef TCL_MEM_DEBUG
#   define  MAX_VAR_CHARS 5
#else
#   define  MAX_VAR_CHARS 30
#endif
    char nameBuffer[MAX_VAR_CHARS+1];
    char *varName, *index;
    char *p = NULL;		/* Initialized to avoid compiler warning. */
    int length, code;

    /*
     * The only tricky thing about this procedure is that it attempts to
     * avoid object creation and string copying whenever possible.  For
     * example, if the value is just a nested command, then use the
     * command's result object directly.
     */

    resultPtr = NULL;
    for ( ; count > 0; count--, tokenPtr++) {
	valuePtr = NULL;

	/*
	 * The switch statement below computes the next value to be
	 * concat to the result, as either a range of text or an
	 * object.
	 */

	switch (tokenPtr->type) {
	    case TCL_TOKEN_TEXT:
		p = tokenPtr->start;
		length = tokenPtr->size;
		break;

	    case TCL_TOKEN_BS:
		length = Tcl_UtfBackslash(tokenPtr->start, (int *) NULL,
			buffer);
		p = buffer;
		break;

	    case TCL_TOKEN_COMMAND:
		code = Tcl_EvalEx(interp, tokenPtr->start+1, tokenPtr->size-2,
			0);
		if (code != TCL_OK) {
		    goto error;
		}
		valuePtr = Tcl_GetObjResult(interp);
		break;

	    case TCL_TOKEN_VARIABLE:
		if (tokenPtr->numComponents == 1) {
		    indexPtr = NULL;
		} else {
		    indexPtr = Tcl_EvalTokens(interp, tokenPtr+2,
			    tokenPtr->numComponents - 1);
		    if (indexPtr == NULL) {
			goto error;
		    }
		}

		/*
		 * We have to make a copy of the variable name in order
		 * to have a null-terminated string.  We can't make a
		 * temporary modification to the script to null-terminate
		 * the name, because a trace callback might potentially
		 * reuse the script and be affected by the null character.
		 */

		if (tokenPtr[1].size <= MAX_VAR_CHARS) {
		    varName = nameBuffer;
		} else {
		    varName = ckalloc((unsigned) (tokenPtr[1].size + 1));
		}

		strncpy(varName, tokenPtr[1].start, (size_t) tokenPtr[1].size);
		varName[tokenPtr[1].size] = 0;
		if (indexPtr != NULL) {

		    index = TclGetString(indexPtr);
		} else {
		    index = NULL;
		}
		valuePtr = Tcl_GetVar2Ex(interp, varName, index,
			TCL_LEAVE_ERR_MSG);
		if (varName != nameBuffer) {
		    ckfree(varName);
		}
		if (indexPtr != NULL) {
		    Tcl_DecrRefCount(indexPtr);
		}
		if (valuePtr == NULL) {
		    goto error;
		}
		count -= tokenPtr->numComponents;
		tokenPtr += tokenPtr->numComponents;
		break;

	    default:
		panic("unexpected token type in Tcl_EvalTokens");
	}

	/*
	 * If valuePtr isn't NULL, the next piece of text comes from that
	 * object; otherwise, take length bytes starting at p.
	 */

	if (resultPtr == NULL) {
	    if (valuePtr != NULL) {
		resultPtr = valuePtr;
	    } else {
		resultPtr = Tcl_NewStringObj(p, length);
	    }
	    Tcl_IncrRefCount(resultPtr);
	} else {
	    if (Tcl_IsShared(resultPtr)) {
		newPtr = Tcl_DuplicateObj(resultPtr);
		Tcl_DecrRefCount(resultPtr);
		resultPtr = newPtr;
		Tcl_IncrRefCount(resultPtr);
	    }
	    if (valuePtr != NULL) {
		p = Tcl_GetStringFromObj(valuePtr, &length);
	    }
	    Tcl_AppendToObj(resultPtr, p, length);
	}
    }
    return resultPtr;

    error:
    if (resultPtr != NULL) {
	Tcl_DecrRefCount(resultPtr);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_EvalEx --
 *
 *	This procedure evaluates a Tcl script without using the compiler
 *	or byte-code interpreter.  It just parses the script, creates
 *	values for each word of each command, then calls EvalObjv
 *	to execute each command.
 *
 * Results:
 *	The return value is a standard Tcl completion code such as
 *	TCL_OK or TCL_ERROR.  A result or error message is left in
 *	interp's result.
 *
 * Side effects:
 *	Depends on the script.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_EvalEx(interp, script, numBytes, flags)
    Tcl_Interp *interp;		/* Interpreter in which to evaluate the
				 * script.  Also used for error reporting. */
    char *script;		/* First character of script to evaluate. */
    int numBytes;		/* Number of bytes in script.  If < 0, the
				 * script consists of all bytes up to the
				 * first null character. */
    int flags;			/* Collection of OR-ed bits that control
				 * the evaluation of the script.  Only
				 * TCL_EVAL_GLOBAL is currently
				 * supported. */
{
    Interp *iPtr = (Interp *) interp;
    char *p, *next;
    Tcl_Parse parse;
#define NUM_STATIC_OBJS 20
    Tcl_Obj *staticObjArray[NUM_STATIC_OBJS], **objv;
    Tcl_Token *tokenPtr;
    int i, code, commandLength, bytesLeft, nested;
    CallFrame *savedVarFramePtr;	/* Saves old copy of iPtr->varFramePtr
					 * in case TCL_EVAL_GLOBAL was set. */

    /*
     * The variables below keep track of how much state has been
     * allocated while evaluating the script, so that it can be freed
     * properly if an error occurs.
     */

    int gotParse = 0, objectsUsed = 0;

    if (numBytes < 0) {
	numBytes = strlen(script);
    }
    Tcl_ResetResult(interp);

    savedVarFramePtr = iPtr->varFramePtr;
    if (flags & TCL_EVAL_GLOBAL) {
	iPtr->varFramePtr = NULL;
    }

    /*
     * Each iteration through the following loop parses the next
     * command from the script and then executes it.
     */

    objv = staticObjArray;
    p = script;
    bytesLeft = numBytes;
    if (iPtr->evalFlags & TCL_BRACKET_TERM) {
	nested = 1;
    } else {
	nested = 0;
    }
    iPtr->evalFlags = 0;
    do {
	if (Tcl_ParseCommand(interp, p, bytesLeft, nested, &parse)
	        != TCL_OK) {
	    code = TCL_ERROR;
	    goto error;
	}
	gotParse = 1; 
	if (parse.numWords > 0) {
	    /*
	     * Generate an array of objects for the words of the command.
	     */
    
	    if (parse.numWords <= NUM_STATIC_OBJS) {
		objv = staticObjArray;
	    } else {
		objv = (Tcl_Obj **) ckalloc((unsigned)
		    (parse.numWords * sizeof (Tcl_Obj *)));
	    }
	    for (objectsUsed = 0, tokenPtr = parse.tokenPtr;
		    objectsUsed < parse.numWords;
		    objectsUsed++, tokenPtr += (tokenPtr->numComponents + 1)) {
		objv[objectsUsed] = Tcl_EvalTokens(interp, tokenPtr+1,
			tokenPtr->numComponents);
		if (objv[objectsUsed] == NULL) {
		    code = TCL_ERROR;
		    goto error;
		}
	    }
    
	    /*
	     * Execute the command and free the objects for its words.
	     */
    
	    code = EvalObjv(interp, objectsUsed, objv, p, bytesLeft, 0);
	    if (code != TCL_OK) {
		goto error;
	    }
	    for (i = 0; i < objectsUsed; i++) {
		Tcl_DecrRefCount(objv[i]);
	    }
	    objectsUsed = 0;
	    if (objv != staticObjArray) {
		ckfree((char *) objv);
		objv = staticObjArray;
	    }
	}

	/*
	 * Advance to the next command in the script.
	 */

	next = parse.commandStart + parse.commandSize;
	bytesLeft -= next - p;
	p = next;
	Tcl_FreeParse(&parse);
	gotParse = 0;
	if ((nested != 0) && (p > script) && (p[-1] == ']')) {
	    /*
	     * We get here in the special case where the TCL_BRACKET_TERM
	     * flag was set in the interpreter and we reached a close
	     * bracket in the script.  Return immediately.
	     */

	    iPtr->termOffset = (p - 1) - script;
	    iPtr->varFramePtr = savedVarFramePtr;
	    return TCL_OK;
	}
    } while (bytesLeft > 0);
    iPtr->termOffset = p - script;
    iPtr->varFramePtr = savedVarFramePtr;
    return TCL_OK;

    error:
    /*
     * Generate various pieces of error information, such as the line
     * number where the error occurred and information to add to the
     * errorInfo variable.  Then free resources that had been allocated
     * to the command.
     */

    if ((code == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) { 
	commandLength = parse.commandSize;
	if ((parse.commandStart + commandLength) != (script + numBytes)) {
	    /*
	     * The command where the error occurred didn't end at the end
	     * of the script (i.e. it ended at a terminator character such
	     * as ";".  Reduce the length by one so that the error message
	     * doesn't include the terminator character.
	     */
	    
	    commandLength -= 1;
	}
	Tcl_LogCommandInfo(interp, script, parse.commandStart, commandLength);
    }
    
    for (i = 0; i < objectsUsed; i++) {
	Tcl_DecrRefCount(objv[i]);
    }
    if (gotParse) {
	Tcl_FreeParse(&parse);
    }
    if (objv != staticObjArray) {
	ckfree((char *) objv);
    }
    iPtr->varFramePtr = savedVarFramePtr;
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Eval --
 *
 *	Execute a Tcl command in a string.  This procedure executes the
 *	script directly, rather than compiling it to bytecodes.  Before
 *	the arrival of the bytecode compiler in Tcl 8.0 Tcl_Eval was
 *	the main procedure used for executing Tcl commands, but nowadays
 *	it isn't used much.
 *
 * Results:
 *	The return value is one of the return codes defined in tcl.h
 *	(such as TCL_OK), and interp's result contains a value
 *	to supplement the return code. The value of the result
 *	will persist only until the next call to Tcl_Eval or Tcl_EvalObj:
 *	you must copy it or lose it!
 *
 * Side effects:
 *	Can be almost arbitrary, depending on the commands in the script.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Eval(interp, string)
    Tcl_Interp *interp;		/* Token for command interpreter (returned
				 * by previous call to Tcl_CreateInterp). */
    char *string;		/* Pointer to TCL command to execute. */
{
    int code;

    code = Tcl_EvalEx(interp, string, -1, 0);

    /*
     * For backwards compatibility with old C code that predates the
     * object system in Tcl 8.0, we have to mirror the object result
     * back into the string result (some callers may expect it there).
     */

    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
	    TCL_VOLATILE);
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_EvalObj, Tcl_GlobalEvalObj --
 *

 *	These functions are deprecated but we keep them around for backwards
 *	compatibility reasons.
 *
 * Results:



 *	See the functions they call.
 *
 * Side effects:
 *	See the functions they call.
 *
 *----------------------------------------------------------------------
 */

#undef Tcl_EvalObj
int
Tcl_EvalObj(interp, objPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
{
    return Tcl_EvalObjEx(interp, objPtr, 0);
}

#undef Tcl_GlobalEvalObj
int
Tcl_GlobalEvalObj(interp, objPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
{
    return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ParseVarName --
 *
 *	Given a string starting with a $ sign, parse off a variable
 *	name and return information about the parse.
 *
 * Results:
 *	The return value is TCL_OK if the command was parsed
 *	successfully and TCL_ERROR otherwise.  If an error occurs and
 *	interp isn't NULL then an error message is left in its result. 
 *	On a successful return, tokenPtr and numTokens fields of
 *	parsePtr are filled in with information about the variable name
 *	that was parsed.  The "size" field of the first new token gives
 *	the total number of bytes in the variable name.  Other fields in
 *	parsePtr are undefined.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the command, then additional space is
 *	malloc-ed.  If the procedure returns TCL_OK then the caller must
 *	eventually invoke Tcl_FreeParse to release any additional space
 *	that was allocated.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ParseVarName(interp, string, numBytes, parsePtr, append)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting;
				 * if NULL, then no error message is
				 * provided. */
    char *string;		/* String containing variable name.  First
				 * character must be "$". */
    int numBytes;		/* Total number of bytes in string.  If < 0,
				 * the string consists of all bytes up to the
				 * first null character. */
    Tcl_Parse *parsePtr;	/* Structure to fill in with information
				 * about the variable name. */
    int append;			/* Non-zero means append tokens to existing
				 * information in parsePtr; zero means ignore
				 * existing tokens in parsePtr and reinitialize
				 * it. */
{
    Tcl_Token *tokenPtr;
    char *end, *src;
    unsigned char c;
    int varIndex, offset;
    Tcl_UniChar ch;

    if (numBytes >= 0) {
	end = string + numBytes;
    } else {
	end = string + strlen(string);
    }

    if (!append) {
	parsePtr->numWords = 0;
	parsePtr->tokenPtr = parsePtr->staticTokens;
	parsePtr->numTokens = 0;
	parsePtr->tokensAvailable = NUM_STATIC_TOKENS;
	parsePtr->string = string;
	parsePtr->end = end;
	parsePtr->interp = interp;
	parsePtr->incomplete = 0;
    }

    /*
     * Generate one token for the variable, an additional token for the
     * name, plus any number of additional tokens for the index, if
     * there is one.
     */

    src = string;
    if ((parsePtr->numTokens + 2) > parsePtr->tokensAvailable) {
	TclExpandTokenArray(parsePtr);
    }
    tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
    tokenPtr->type = TCL_TOKEN_VARIABLE;
    tokenPtr->start = src;
    varIndex = parsePtr->numTokens;
    parsePtr->numTokens++;
    tokenPtr++;
    src++;
    if (src >= end) {
	goto justADollarSign;
    }
    tokenPtr->type = TCL_TOKEN_TEXT;
    tokenPtr->start = src;
    tokenPtr->numComponents = 0;

    /*

     * The name of the variable can have three forms:
     * 1. The $ sign is followed by an open curly brace.  Then 
     *    the variable name is everything up to the next close
     *    curly brace, and the variable is a scalar variable.
     * 2. The $ sign is not followed by an open curly brace.  Then
     *    the variable name is everything up to the next
     *    character that isn't a letter, digit, or underscore.
     *    :: sequences are also considered part of the variable
     *    name, in order to support namespaces. If the following
     *    character is an open parenthesis, then the information
     *    between parentheses is the array element name.
     * 3. The $ sign is followed by something that isn't a letter,

     *    digit, or underscore:  in this case, there is no variable
     *    name and the token is just "$".
     */

    if (*src == '{') {
	src++;
	tokenPtr->type = TCL_TOKEN_TEXT;
	tokenPtr->start = src;
	tokenPtr->numComponents = 0;
	while (1) {
	    if (src == end) {
		if (interp != NULL) {
		    Tcl_SetResult(interp,
			"missing close-brace for variable name",
			TCL_STATIC);
		}
		parsePtr->term = tokenPtr->start-1;
		parsePtr->incomplete = 1;
		goto error;
	    }
	    if (*src == '}') {
		break;
	    }
	    src++;
	}
	tokenPtr->size = src - tokenPtr->start;
	tokenPtr[-1].size = src - tokenPtr[-1].start;
	parsePtr->numTokens++;
	src++;
    } else {
	tokenPtr->type = TCL_TOKEN_TEXT;
	tokenPtr->start = src;
	tokenPtr->numComponents = 0;
	while (src != end) {
	    offset = Tcl_UtfToUniChar(src, &ch);
	    c = UCHAR(ch);
	    if (isalnum(c) || (c == '_')) { /* INTL: ISO only, UCHAR. */
		src += offset;
		continue;
	    }
	    if ((c == ':') && (((src+1) != end) && (src[1] == ':'))) {
		src += 2;
		while ((src != end) && (*src == ':')) {
		    src += 1;
		}
		continue;
	    }
	    break;
	}
	tokenPtr->size = src - tokenPtr->start;



	if (tokenPtr->size == 0) {


	    goto justADollarSign;

	}












	parsePtr->numTokens++;






	if ((src != end) && (*src == '(')) {
	    /*



	     * This is a reference to an array element.  Call


	     * ParseTokens recursively to parse the element name,














	     * since it could contain any number of substitutions.













	     */

	    if (ParseTokens(src+1, TYPE_CLOSE_PAREN, parsePtr)








		    != TCL_OK) {







		goto error;

	    }


	    if ((parsePtr->term == end) || (*parsePtr->term != ')')) { 





		if (parsePtr->interp != NULL) {




		    Tcl_SetResult(parsePtr->interp, "missing )",











			    TCL_STATIC);
		}
		parsePtr->term = src;







		parsePtr->incomplete = 1;
		goto error;
	    }








	    src = parsePtr->term + 1;
	}
    }
    tokenPtr = &parsePtr->tokenPtr[varIndex];
    tokenPtr->size = src - tokenPtr->start;
    tokenPtr->numComponents = parsePtr->numTokens - (varIndex + 1);










    return TCL_OK;


    /*


















     * The dollar sign isn't followed by a variable name.






     * replace the TCL_TOKEN_VARIABLE token with a














     * TCL_TOKEN_TEXT token for the dollar sign.



     */











    justADollarSign:




    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 --
 *
 *	Given a string starting with a $ sign, parse off a variable
 *	name and return its value.
 *
 * Results:
 *	The return value is the contents of the variable given by
 *	the leading characters of string.  If termPtr isn't NULL,
 *	*termPtr gets filled in with the address of the character
 *	just after the last one in the variable specifier.  If the
 *	variable doesn't exist, then the return value is NULL and
 *	an error message will be left in interp's result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_ParseVar(interp, string, termPtr)
    Tcl_Interp *interp;			/* Context for looking up variable. */
    register char *string;		/* String containing variable name.
					 * First character must be "$". */
    char **termPtr;			/* If non-NULL, points to word to fill
					 * in with character just after last
					 * one in the variable specifier. */

{
    Tcl_Parse parse;
    register Tcl_Obj *objPtr;

    if (Tcl_ParseVarName(interp, string, -1, &parse, 0) != TCL_OK) {
	return NULL;
    }

    if (termPtr != NULL) {
	*termPtr = string + parse.tokenPtr->size;
    }
    if (parse.numTokens == 1) {
	/*
	 * There isn't a variable name after all: the $ is just a $.
	 */

	return "$";
    }

    objPtr = Tcl_EvalTokens(interp, parse.tokenPtr, parse.numTokens);
    if (objPtr == NULL) {
	return NULL;
    }

    /*
     * At this point we should have an object containing the value of
     * a variable.  Just return the string from that object.
     */

#ifdef TCL_COMPILE_DEBUG
    if (objPtr->refCount < 2) {
	panic("Tcl_ParseVar got temporary object from Tcl_EvalTokens");
    }
#endif /*TCL_COMPILE_DEBUG*/    
    TclDecrRefCount(objPtr);
    return TclGetString(objPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ParseBraces --
 *
 *	Given a string in braces such as a Tcl command argument or a string
 *	value in a Tcl expression, this procedure parses the string and
 *	returns information about the parse.
 *
 * Results:



 *	The return value is TCL_OK if the string was parsed successfully and
 *	TCL_ERROR otherwise. If an error occurs and interp isn't NULL then
 *	an error message is left in its result. On a successful return,
 *	tokenPtr and numTokens fields of parsePtr are filled in with

 *	information about the string that was parsed. Other fields in
 *	parsePtr are undefined. termPtr is set to point to the character
 *	just after the last one in the braced string.

 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the command, then additional space is
 *	malloc-ed. If the procedure returns TCL_OK then the caller must
 *	eventually invoke Tcl_FreeParse to release any additional space
 *	that was allocated.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ParseBraces(interp, string, numBytes, parsePtr, append, termPtr)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting;
				 * if NULL, then no error message is
				 * provided. */
    char *string;		/* String containing the string in braces.
				 * The first character must be '{'. */
    int numBytes;		/* Total number of bytes in string. If < 0,
				 * the string consists of all bytes up to
				 * the first null character. */
    register Tcl_Parse *parsePtr;
    				/* Structure to fill in with information
				 * about the string. */
    int append;			/* Non-zero means append tokens to existing
				 * information in parsePtr; zero means
				 * ignore existing tokens in parsePtr and
				 * reinitialize it. */
    char **termPtr;		/* If non-NULL, points to word in which to
				 * store a pointer to the character just
				 * after the terminating '}' if the parse
				 * was successful. */

{
    char utfBytes[TCL_UTF_MAX];	/* For result of backslash substitution. */
    Tcl_Token *tokenPtr;
    register char *src, *end;
    int startIndex, level, length;

    if ((numBytes >= 0) || (string == NULL)) {
	end = string + numBytes;
    } else {
	end = string + strlen(string);
    }
    
    if (!append) {
	parsePtr->numWords = 0;
	parsePtr->tokenPtr = parsePtr->staticTokens;
	parsePtr->numTokens = 0;
	parsePtr->tokensAvailable = NUM_STATIC_TOKENS;
	parsePtr->string = string;
	parsePtr->end = end;
	parsePtr->interp = interp;
    }

    src = string+1;
    startIndex = parsePtr->numTokens;

    if (parsePtr->numTokens == parsePtr->tokensAvailable) {
	TclExpandTokenArray(parsePtr);
    }
    tokenPtr = &parsePtr->tokenPtr[startIndex];
    tokenPtr->type = TCL_TOKEN_TEXT;
    tokenPtr->start = src;
    tokenPtr->numComponents = 0;
    level = 1;
    while (1) {
	while (CHAR_TYPE(*src) == TYPE_NORMAL) {
	    src++;
	}
	if (*src == '}') {
	    level--;
	    if (level == 0) {
		break;
	    }
	    src++;
	} else if (*src == '{') {
	    level++;
	    src++;
	} else if (*src == '\\') {
	    Tcl_UtfBackslash(src, &length, utfBytes);
	    if (src[1] == '\n') {
		/*
		 * A backslash-newline sequence must be collapsed, even
		 * inside braces, so we have to split the word into
		 * multiple tokens so that the backslash-newline can be
		 * represented explicitly.
		 */
		
		if ((src + 2) == end) {
		    parsePtr->incomplete = 1;
		}
		tokenPtr->size = (src - tokenPtr->start);
		if (tokenPtr->size != 0) {
		    parsePtr->numTokens++;
		}
		if ((parsePtr->numTokens+1) >= parsePtr->tokensAvailable) {
		    TclExpandTokenArray(parsePtr);
		}
		tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
		tokenPtr->type = TCL_TOKEN_BS;
		tokenPtr->start = src;
		tokenPtr->size = length;
		tokenPtr->numComponents = 0;
		parsePtr->numTokens++;
		
		src += length;
		tokenPtr++;
		tokenPtr->type = TCL_TOKEN_TEXT;
		tokenPtr->start = src;
		tokenPtr->numComponents = 0;
	    } else {
		src += length;
	    }
	} else if (src == end) {
	    if (interp != NULL) {
		Tcl_SetResult(interp, "missing close-brace", TCL_STATIC);


	    }
	    parsePtr->term = string;
	    parsePtr->incomplete = 1;
	    goto error;
	} else {
	    src++;
	}

    }




    /*
     * Decide if we need to finish emitting a partially-finished token.
     * There are 3 cases:
     *     {abc \newline xyz} or {xyz}	- finish emitting "xyz" token
     *     {abc \newline}		- don't emit token after \newline
     *     {}				- finish emitting zero-sized token
     * The last case ensures that there is a token (even if empty) that
     * describes the braced string.
     */
    

    if ((src != tokenPtr->start)


	    || (parsePtr->numTokens == startIndex)) {
	tokenPtr->size = (src - tokenPtr->start);

	parsePtr->numTokens++;

    }

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

 *
 *	Given a double-quoted string such as a quoted Tcl command argument
 *	or a quoted value in a Tcl expression, this procedure parses the
 *	string and returns information about the parse.
 *
 * Results:
 *	The return value is TCL_OK if the string was parsed successfully and
 *	TCL_ERROR otherwise. If an error occurs and interp isn't NULL then
 *	an error message is left in its result. On a successful return,
 *	tokenPtr and numTokens fields of parsePtr are filled in with
 *	information about the string that was parsed. Other fields in
 *	parsePtr are undefined. termPtr is set to point to the character
 *	just after the quoted string's terminating close-quote.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the command, then additional space is
 *	malloc-ed. If the procedure returns TCL_OK then the caller must
 *	eventually invoke Tcl_FreeParse to release any additional space
 *	that was allocated.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ParseQuotedString(interp, string, numBytes, parsePtr, append, termPtr)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting;
				 * if NULL, then no error message is
				 * provided. */
    char *string;		/* String containing the quoted string. 
				 * The first character must be '"'. */
    int numBytes;		/* Total number of bytes in string. If < 0,
				 * the string consists of all bytes up to
				 * the first null character. */
    register Tcl_Parse *parsePtr;
    				/* Structure to fill in with information
				 * about the string. */
    int append;			/* Non-zero means append tokens to existing
				 * information in parsePtr; zero means
				 * ignore existing tokens in parsePtr and
				 * reinitialize it. */
    char **termPtr;		/* If non-NULL, points to word in which to
				 * store a pointer to the character just
				 * after the quoted string's terminating
				 * close-quote if the parse succeeds. */
{

    char *end;
    
    if ((numBytes >= 0) || (string == NULL)) {
	end = string + numBytes;
    } else {

	end = string + strlen(string);
    }
    
    if (!append) {
	parsePtr->numWords = 0;
	parsePtr->tokenPtr = parsePtr->staticTokens;
	parsePtr->numTokens = 0;
	parsePtr->tokensAvailable = NUM_STATIC_TOKENS;
	parsePtr->string = string;
	parsePtr->end = end;
	parsePtr->interp = interp;
    }
    

    if (ParseTokens(string+1, TYPE_QUOTE, parsePtr) != TCL_OK) {
	goto error;
    }
    if (*parsePtr->term != '"') {
	if (interp != NULL) {
	    Tcl_SetResult(parsePtr->interp, "missing \"", TCL_STATIC);
	}
	parsePtr->term = string;
	parsePtr->incomplete = 1;
	goto error;
    }
    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 --
 *
 *	This procedure is shared by TclCommandComplete and
 *	Tcl_ObjCommandcoComplete; it does all the real work of seeing
 *	whether a script is complete
 *
 * Results:

 *	1 is returned if the script is complete, 0 if there are open
 *	delimiters such as " or (. 1 is also returned if there is a
 *	parse error in the script other than unmatched delimiters.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

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 --
 *
 *	Given a partial or complete Tcl script, this procedure
 *	determines whether the script is complete in the sense
 *	of having matched braces and quotes and brackets.
 *
 * Results:
 *	1 is returned if the script is complete, 0 otherwise.
 *	1 is also returned if there is a parse error in the script
 *	other than unmatched delimiters.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_CommandComplete(script)


    char *script;			/* Script to check. */
{

    return CommandComplete(script, (int) strlen(script));



}

/*
 *----------------------------------------------------------------------
 *
 * TclObjCommandComplete --
 *
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932


933


































934
935










936
937
938
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclObjCommandComplete(cmdPtr)
    Tcl_Obj *cmdPtr;			/* Points to object holding command
					 * to check. */
{
    char *cmd, *p;
    int length;

    cmd = Tcl_GetStringFromObj(cmdPtr, &length);


    if (length == 0) {


































	return 1;
    }










    p = ScriptEnd(cmd, cmd+length, /*nested*/ 0);
    return (*p != 0);
}







|
|


|


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

2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclObjCommandComplete(objPtr)
    Tcl_Obj *objPtr;			/* Points to object holding script
					 * to check. */
{
    char *script;
    int length;

    script = Tcl_GetStringFromObj(objPtr, &length);
    return CommandComplete(script, length);
}

/*
 *----------------------------------------------------------------------
 *
 * TclIsLocalScalar --
 *
 *	Check to see if a given string is a legal scalar variable
 *	name with no namespace qualifiers or substitutions.
 *
 * Results:
 *	Returns 1 if the variable is a local scalar.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclIsLocalScalar(src, len)
    CONST char *src;
    int len;
{
    CONST char *p;
    CONST char *lastChar = src + (len - 1);

    for (p = src; p <= lastChar; p++) {
	if ((CHAR_TYPE(*p) != TYPE_NORMAL) &&
		(CHAR_TYPE(*p) != TYPE_COMMAND_END)) {
	    /*
	     * TCL_COMMAND_END is returned for the last character
	     * of the string.  By this point we know it isn't
	     * an array or namespace reference.
	     */

	    return 0;
	}
	if  (*p == '(') {
	    if (*lastChar == ')') { /* we have an array element */
		return 0;
	    }
	} else if (*p == ':') {
	    if ((p != lastChar) && *(p+1) == ':') { /* qualified name */
		return 0;
	    }
	}
    }
	
    return 1;
}

Added generic/tclParseExpr.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
/* 
 * tclParseExpr.c --
 *
 *	This file contains procedures that parse Tcl expressions. They
 *	do so in a general-purpose fashion that can be used for many
 *	different purposes, including compilation, direct execution,
 *	code analysis, etc.
 *
 * 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: tclParseExpr.c,v 1.1.2.3 1998/11/11 04:54:18 stanton Exp $
 */

#include "tclInt.h"
#include "tclCompile.h"

/*
 * The stuff below is a bit of a hack so that this file can be used in
 * environments that include no UNIX, i.e. no errno: just arrange to use
 * the errno from tclExecute.c here.
 */

#ifndef TCL_GENERIC_ONLY
#include "tclPort.h"
#else
#define NO_ERRNO_H
#endif

#ifdef NO_ERRNO_H
extern int errno;			/* Use errno from tclExecute.c. */
#define ERANGE 34
#endif

/*
 * Boolean variable that controls whether expression parse tracing
 * is enabled.
 */

#ifdef TCL_COMPILE_DEBUG
static int traceParseExpr = 0;
#endif /* TCL_COMPILE_DEBUG */

/*
 * The ParseInfo structure holds state while parsing an expression.
 * A pointer to an ParseInfo record is passed among the routines in
 * this module.
 */

typedef struct ParseInfo {
    Tcl_Parse *parsePtr;	/* Points to structure to fill in with
				 * information about the expression. */
    int lexeme;			/* Type of last lexeme scanned in expr.
				 * See below for definitions. Corresponds to
				 * size characters beginning at start. */
    char *start;		/* First character in lexeme. */
    int size;			/* Number of bytes in lexeme. */
    char *next;			/* Position of the next character to be
				 * scanned in the expression string. */
    char *prevEnd;		/* Points to the character just after the
				 * last one in the previous lexeme. Used to
				 * compute size of subexpression tokens. */
    char *originalExpr;		/* Points to the start of the expression
				 * originally passed to Tcl_ParseExpr. */
    char *lastChar;		/* Points just after last byte of expr. */
} ParseInfo;

/*
 * Definitions of the different lexemes that appear in expressions. The
 * order of these must match the corresponding entries in the
 * operatorStrings array below.
 */

#define LITERAL		0
#define FUNC_NAME	1
#define OPEN_BRACKET	2
#define OPEN_BRACE	3
#define OPEN_PAREN	4
#define CLOSE_PAREN	5
#define DOLLAR		6
#define QUOTE		7
#define COMMA		8
#define END		9
#define UNKNOWN		10

/*
 * Binary operators:
 */

#define MULT		11
#define DIVIDE		12
#define MOD		13
#define PLUS		14
#define MINUS		15
#define LEFT_SHIFT	16
#define RIGHT_SHIFT	17
#define LESS		18
#define GREATER		19
#define LEQ		20
#define GEQ		21
#define EQUAL		22
#define NEQ		23
#define BIT_AND		24
#define BIT_XOR		25
#define BIT_OR		26
#define AND		27
#define OR		28
#define QUESTY		29
#define COLON		30

/*
 * Unary operators. Unary minus and plus are represented by the (binary)
 * lexemes MINUS and PLUS.
 */

#define NOT		31
#define BIT_NOT		32

/*
 * Mapping from lexemes to strings; used for debugging messages. These
 * entries must match the order and number of the lexeme definitions above.
 */

#ifdef TCL_COMPILE_DEBUG
static char *lexemeStrings[] = {
    "LITERAL", "FUNCNAME",
    "[", "{", "(", ")", "$", "\"", ",", "END", "UNKNOWN",
    "*", "/", "%", "+", "-",
    "<<", ">>", "<", ">", "<=", ">=", "==", "!=",
    "&", "^", "|", "&&", "||", "?", ":",
    "!", "~"
};
#endif /* TCL_COMPILE_DEBUG */

/*
 * Declarations for local procedures to this file:
 */

static int		GetLexeme _ANSI_ARGS_((ParseInfo *infoPtr));
static void		LogSyntaxError _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseAddExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseBitAndExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseBitOrExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseBitXorExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseCondExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseEqualityExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseLandExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseLorExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseMultiplyExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParsePrimaryExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseRelationalExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseShiftExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static int		ParseUnaryExpr _ANSI_ARGS_((ParseInfo *infoPtr));
static void		PrependSubExprTokens _ANSI_ARGS_((char *op,
			    int opBytes, char *src, int srcBytes,
			    int firstIndex, ParseInfo *infoPtr));

/*
 * Macro used to debug the execution of the recursive descent parser used
 * to parse expressions.
 */

#ifdef TCL_COMPILE_DEBUG
#define HERE(production, level) \
    if (traceParseExpr) { \
	fprintf(stderr, "%*s%s: lexeme=%s, next=\"%.20s\"\n", \
		(level), " ", (production), \
		lexemeStrings[infoPtr->lexeme], infoPtr->next); \
    }
#else
#define HERE(production, level)
#endif /* TCL_COMPILE_DEBUG */

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ParseExpr --
 *
 *	Given a string, this procedure parses the first Tcl expression
 *	in the string and returns information about the structure of
 *	the expression. This procedure is the top-level interface to the
 *	the expression parsing module.
 *
 * Results:
 *	The return value is TCL_OK if the command was parsed successfully
 *	and TCL_ERROR otherwise. If an error occurs and interp isn't NULL
 *	then an error message is left in its result. On a successful return,
 *	parsePtr is filled in with information about the expression that 
 *	was parsed.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the expression, then additional space is
 *	malloc-ed. If the procedure returns TCL_OK then the caller must
 *	eventually invoke Tcl_FreeParse to release any additional space
 *	that was allocated.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ParseExpr(interp, string, numBytes, parsePtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* The source string to parse. */
    int numBytes;		/* Number of bytes in string. If < 0, the
				 * string consists of all bytes up to the
				 * first null character. */
    Tcl_Parse *parsePtr;	/* Structure to fill with information about
				 * the parsed expression; any previous
				 * information in the structure is
				 * ignored. */
{
    ParseInfo info;
    int code;
    char savedChar;

    if (numBytes < 0) {
	numBytes = (string? strlen(string) : 0);
    }
#ifdef TCL_COMPILE_DEBUG
    if (traceParseExpr) {
	fprintf(stderr, "Tcl_ParseExpr: string=\"%.*s\"\n",
	        numBytes, string);
    }
#endif /* TCL_COMPILE_DEBUG */
    
    parsePtr->commentStart = NULL;
    parsePtr->commentSize = 0;
    parsePtr->commandStart = NULL;
    parsePtr->commandSize = 0;
    parsePtr->numWords = 0;
    parsePtr->tokenPtr = parsePtr->staticTokens;
    parsePtr->numTokens = 0;
    parsePtr->tokensAvailable = NUM_STATIC_TOKENS;
    parsePtr->string = string;
    parsePtr->end = (string + numBytes);
    parsePtr->interp = interp;
    parsePtr->term = string;
    parsePtr->incomplete = 0;

    /*
     * Temporarily overwrite the character just after the end of the
     * string with a 0 byte.  This acts as a sentinel and reduces the
     * number of places where we have to check for the end of the
     * input string.  The original value of the byte is restored at
     * the end of the parse.
     */

    savedChar = string[numBytes];
    string[numBytes] = 0;

    /*
     * Initialize the ParseInfo structure that holds state while parsing
     * the expression.
     */

    info.parsePtr = parsePtr;
    info.lexeme = UNKNOWN;
    info.start = NULL;
    info.size = 0;
    info.next = string;
    info.prevEnd = string;
    info.originalExpr = string;
    info.lastChar = (string + numBytes); /* just after last char of expr */

    /*
     * Get the first lexeme then parse the expression.
     */

    code = GetLexeme(&info);
    if (code != TCL_OK) {
	goto error;
    }
    code = ParseCondExpr(&info);
    if (code != TCL_OK) {
	goto error;
    }
    if (info.lexeme != END) {
	LogSyntaxError(&info);
	goto error;
    }
    string[numBytes] = (char) savedChar;
    return TCL_OK;
    
    error:
    string[numBytes] = (char) savedChar;
    if (parsePtr->tokenPtr != parsePtr->staticTokens) {
	ckfree((char *) parsePtr->tokenPtr);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseCondExpr --
 *
 *	This procedure parses a Tcl conditional expression:
 *	condExpr ::= lorExpr ['?' condExpr ':' condExpr]
 *
 *	Note that this is the topmost recursive-descent parsing routine used
 *	by TclParseExpr to parse expressions. This avoids an extra procedure
 *	call since such a procedure would only return the result of calling
 *	ParseCondExpr. Other recursive-descent procedures that need to parse
 *	complete expressions also call ParseCondExpr.
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseCondExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    Tcl_Token *tokenPtr, *firstTokenPtr, *condTokenPtr;
    int firstIndex, numToMove, code;
    char *srcStart;
    
    HERE("condExpr", 1);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseLorExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }
    
    if (infoPtr->lexeme == QUESTY) {
	/*
	 * Emit two tokens: one TCL_TOKEN_SUB_EXPR token for the entire
	 * conditional expression, and a TCL_TOKEN_OPERATOR token for 
	 * the "?" operator. Note that these two tokens must be inserted
	 * before the LOR operand tokens generated above.
	 */

	if ((parsePtr->numTokens + 1) >= parsePtr->tokensAvailable) {
	    TclExpandTokenArray(parsePtr);
	}
	firstTokenPtr = &parsePtr->tokenPtr[firstIndex];
	tokenPtr = (firstTokenPtr + 2);
	numToMove = (parsePtr->numTokens - firstIndex);
	memmove((VOID *) tokenPtr, (VOID *) firstTokenPtr,
	        (size_t) (numToMove * sizeof(Tcl_Token)));
	parsePtr->numTokens += 2;
	
	tokenPtr = firstTokenPtr;
	tokenPtr->type = TCL_TOKEN_SUB_EXPR;
	tokenPtr->start = srcStart;
	
	tokenPtr++;
	tokenPtr->type = TCL_TOKEN_OPERATOR;
	tokenPtr->start = infoPtr->start;
	tokenPtr->size = 1;
	tokenPtr->numComponents = 0;
    
	/*
	 * Skip over the '?'.
	 */
	
	code = GetLexeme(infoPtr); 
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Parse the "then" expression.
	 */

	code = ParseCondExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}
	if (infoPtr->lexeme != COLON) {
	    LogSyntaxError(infoPtr);
	    return TCL_ERROR;
	}
	code = GetLexeme(infoPtr); /* skip over the ':' */
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Parse the "else" expression.
	 */

	code = ParseCondExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Now set the size-related fields in the '?' subexpression token.
	 */

	condTokenPtr = &parsePtr->tokenPtr[firstIndex];
	condTokenPtr->size = (infoPtr->prevEnd - srcStart);
	condTokenPtr->numComponents = parsePtr->numTokens - (firstIndex+1);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseLorExpr --
 *
 *	This procedure parses a Tcl logical or expression:
 *	lorExpr ::= landExpr {'||' landExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseLorExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, code;
    char *srcStart, *operator;
    
    HERE("lorExpr", 2);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseLandExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }

    while (infoPtr->lexeme == OR) {
	operator = infoPtr->start;
	code = GetLexeme(infoPtr); /* skip over the '||' */
	if (code != TCL_OK) {
	    return code;
	}
	code = ParseLandExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Generate tokens for the LOR subexpression and the '||' operator.
	 */

	PrependSubExprTokens(operator, 2, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseLandExpr --
 *
 *	This procedure parses a Tcl logical and expression:
 *	landExpr ::= bitOrExpr {'&&' bitOrExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseLandExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, code;
    char *srcStart, *operator;

    HERE("landExpr", 3);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseBitOrExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }

    while (infoPtr->lexeme == AND) {
	operator = infoPtr->start;
	code = GetLexeme(infoPtr); /* skip over the '&&' */
	if (code != TCL_OK) {
	    return code;
	}
	code = ParseBitOrExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Generate tokens for the LAND subexpression and the '&&' operator.
	 */

	PrependSubExprTokens(operator, 2, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseBitOrExpr --
 *
 *	This procedure parses a Tcl bitwise or expression:
 *	bitOrExpr ::= bitXorExpr {'|' bitXorExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseBitOrExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, code;
    char *srcStart, *operator;

    HERE("bitOrExpr", 4);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseBitXorExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }
    
    while (infoPtr->lexeme == BIT_OR) {
	operator = infoPtr->start;
	code = GetLexeme(infoPtr); /* skip over the '|' */
	if (code != TCL_OK) {
	    return code;
	}

	code = ParseBitXorExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}
	
	/*
	 * Generate tokens for the BITOR subexpression and the '|' operator.
	 */

	PrependSubExprTokens(operator, 1, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseBitXorExpr --
 *
 *	This procedure parses a Tcl bitwise exclusive or expression:
 *	bitXorExpr ::= bitAndExpr {'^' bitAndExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseBitXorExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, code;
    char *srcStart, *operator;

    HERE("bitXorExpr", 5);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseBitAndExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }
    
    while (infoPtr->lexeme == BIT_XOR) {
	operator = infoPtr->start;
	code = GetLexeme(infoPtr); /* skip over the '^' */
	if (code != TCL_OK) {
	    return code;
	}

	code = ParseBitAndExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}
	
	/*
	 * Generate tokens for the XOR subexpression and the '^' operator.
	 */

	PrependSubExprTokens(operator, 1, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseBitAndExpr --
 *
 *	This procedure parses a Tcl bitwise and expression:
 *	bitAndExpr ::= equalityExpr {'&' equalityExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseBitAndExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, code;
    char *srcStart, *operator;

    HERE("bitAndExpr", 6);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseEqualityExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }
    
    while (infoPtr->lexeme == BIT_AND) {
	operator = infoPtr->start;
	code = GetLexeme(infoPtr); /* skip over the '&' */
	if (code != TCL_OK) {
	    return code;
	}
	code = ParseEqualityExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}
	
	/*
	 * Generate tokens for the BITAND subexpression and '&' operator.
	 */

	PrependSubExprTokens(operator, 1, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseEqualityExpr --
 *
 *	This procedure parses a Tcl equality (inequality) expression:
 *	equalityExpr ::= relationalExpr {('==' | '!=') relationalExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseEqualityExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, lexeme, code;
    char *srcStart, *operator;

    HERE("equalityExpr", 7);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseRelationalExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }

    lexeme = infoPtr->lexeme;
    while ((lexeme == EQUAL) || (lexeme == NEQ)) {
	operator = infoPtr->start;
	code = GetLexeme(infoPtr); /* skip over == or != */
	if (code != TCL_OK) {
	    return code;
	}
	code = ParseRelationalExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Generate tokens for the subexpression and '==' or '!=' operator.
	 */

	PrependSubExprTokens(operator, 2, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
	lexeme = infoPtr->lexeme;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseRelationalExpr --
 *
 *	This procedure parses a Tcl relational expression:
 *	relationalExpr ::= shiftExpr {('<' | '>' | '<=' | '>=') shiftExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseRelationalExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, lexeme, operatorSize, code;
    char *srcStart, *operator;

    HERE("relationalExpr", 8);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseShiftExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }

    lexeme = infoPtr->lexeme;
    while ((lexeme == LESS) || (lexeme == GREATER) || (lexeme == LEQ)
            || (lexeme == GEQ)) {
	operator = infoPtr->start;
	if ((lexeme == LEQ) || (lexeme == GEQ)) {
	    operatorSize = 2;
	} else {
	    operatorSize = 1;
	}
	code = GetLexeme(infoPtr); /* skip over the operator */
	if (code != TCL_OK) {
	    return code;
	}
	code = ParseShiftExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Generate tokens for the subexpression and the operator.
	 */

	PrependSubExprTokens(operator, operatorSize, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
	lexeme = infoPtr->lexeme;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseShiftExpr --
 *
 *	This procedure parses a Tcl shift expression:
 *	shiftExpr ::= addExpr {('<<' | '>>') addExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseShiftExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, lexeme, code;
    char *srcStart, *operator;

    HERE("shiftExpr", 9);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseAddExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }

    lexeme = infoPtr->lexeme;
    while ((lexeme == LEFT_SHIFT) || (lexeme == RIGHT_SHIFT)) {
	operator = infoPtr->start;
	code = GetLexeme(infoPtr); /* skip over << or >> */
	if (code != TCL_OK) {
	    return code;
	}
	code = ParseAddExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Generate tokens for the subexpression and '<<' or '>>' operator.
	 */

	PrependSubExprTokens(operator, 2, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
	lexeme = infoPtr->lexeme;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseAddExpr --
 *
 *	This procedure parses a Tcl addition expression:
 *	addExpr ::= multiplyExpr {('+' | '-') multiplyExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseAddExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, lexeme, code;
    char *srcStart, *operator;

    HERE("addExpr", 10);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseMultiplyExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }

    lexeme = infoPtr->lexeme;
    while ((lexeme == PLUS) || (lexeme == MINUS)) {
	operator = infoPtr->start;
	code = GetLexeme(infoPtr); /* skip over + or - */
	if (code != TCL_OK) {
	    return code;
	}
	code = ParseMultiplyExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Generate tokens for the subexpression and '+' or '-' operator.
	 */

	PrependSubExprTokens(operator, 1, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
	lexeme = infoPtr->lexeme;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseMultiplyExpr --
 *
 *	This procedure parses a Tcl multiply expression:
 *	multiplyExpr ::= unaryExpr {('*' | '/' | '%') unaryExpr}
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseMultiplyExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, lexeme, code;
    char *srcStart, *operator;

    HERE("multiplyExpr", 11);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    code = ParseUnaryExpr(infoPtr);
    if (code != TCL_OK) {
	return code;
    }

    lexeme = infoPtr->lexeme;
    while ((lexeme == MULT) || (lexeme == DIVIDE) || (lexeme == MOD)) {
	operator = infoPtr->start;
	code = GetLexeme(infoPtr); /* skip over * or / or % */
	if (code != TCL_OK) {
	    return code;
	}
	code = ParseUnaryExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Generate tokens for the subexpression and * or / or % operator.
	 */

	PrependSubExprTokens(operator, 1, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
	lexeme = infoPtr->lexeme;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseUnaryExpr --
 *
 *	This procedure parses a Tcl unary expression:
 *	unaryExpr ::= ('+' | '-' | '~' | '!') unaryExpr | primaryExpr
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParseUnaryExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    int firstIndex, lexeme, code;
    char *srcStart, *operator;

    HERE("unaryExpr", 12);
    srcStart = infoPtr->start;
    firstIndex = parsePtr->numTokens;
    
    lexeme = infoPtr->lexeme;
    if ((lexeme == PLUS) || (lexeme == MINUS) || (lexeme == BIT_NOT)
            || (lexeme == NOT)) {
	operator = infoPtr->start;
	code = GetLexeme(infoPtr); /* skip over the unary operator */
	if (code != TCL_OK) {
	    return code;
	}
	code = ParseUnaryExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}

	/*
	 * Generate tokens for the subexpression and the operator.
	 */

	PrependSubExprTokens(operator, 1, srcStart,
	        (infoPtr->prevEnd - srcStart), firstIndex, infoPtr);
    } else {			/* must be a primaryExpr */
	code = ParsePrimaryExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParsePrimaryExpr --
 *
 *	This procedure parses a Tcl primary expression:
 *	primaryExpr ::= literal | varReference | quotedString |
 *			'[' command ']' | mathFuncCall | '(' condExpr ')'
 *
 * Results:
 *	The return value is TCL_OK on a successful parse and TCL_ERROR
 *	on failure. If TCL_ERROR is returned, then the interpreter's result
 *	contains an error message.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static int
ParsePrimaryExpr(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    Tcl_Interp *interp = parsePtr->interp;
    Tcl_Token *tokenPtr, *exprTokenPtr;
    Tcl_Parse nested;
    char *dollarPtr, *stringStart, *termPtr, *src;
    int lexeme, exprIndex, firstIndex, numToMove, code;

    /*
     * We simply recurse on parenthesized subexpressions.
     */

    HERE("primaryExpr", 13);
    lexeme = infoPtr->lexeme;
    if (lexeme == OPEN_PAREN) {
	code = GetLexeme(infoPtr); /* skip over the '(' */
	if (code != TCL_OK) {
	    return code;
	}
	code = ParseCondExpr(infoPtr);
	if (code != TCL_OK) {
	    return code;
	}
	if (infoPtr->lexeme != CLOSE_PAREN) {
	    goto syntaxError;
	}
	code = GetLexeme(infoPtr); /* skip over the ')' */
	if (code != TCL_OK) {
	    return code;
	}
	return TCL_OK;
    }

    /*
     * Start a TCL_TOKEN_SUB_EXPR token for the primary.
     */

    if (parsePtr->numTokens == parsePtr->tokensAvailable) {
	TclExpandTokenArray(parsePtr);
    }
    exprIndex = parsePtr->numTokens;
    exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
    exprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
    exprTokenPtr->start = infoPtr->start;
    parsePtr->numTokens++;

    /*
     * Process the primary then finish setting the fields of the
     * TCL_TOKEN_SUB_EXPR token. Note that we can't use the pointer now
     * stored in "exprTokenPtr" in the code below since the token array
     * might be reallocated.
     */

    firstIndex = parsePtr->numTokens;
    switch (lexeme) {
    case LITERAL:
	/*
	 * Int or double number.
	 */
	
	if (parsePtr->numTokens == parsePtr->tokensAvailable) {
	    TclExpandTokenArray(parsePtr);
	}
	tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
	tokenPtr->type = TCL_TOKEN_TEXT;
	tokenPtr->start = infoPtr->start;
	tokenPtr->size = infoPtr->size;
	tokenPtr->numComponents = 0;
	parsePtr->numTokens++;

	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
	exprTokenPtr->size = infoPtr->size;
	exprTokenPtr->numComponents = 1;
	break;
	
    case DOLLAR:
	/*
	 * $var variable reference.
	 */
	
	dollarPtr = (infoPtr->next - 1);
	code = Tcl_ParseVarName(interp, dollarPtr,
	        (infoPtr->lastChar - dollarPtr), parsePtr, 1);
	if (code != TCL_OK) {
	    return code;
	}
	infoPtr->next = dollarPtr + parsePtr->tokenPtr[firstIndex].size;

	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
	exprTokenPtr->size = parsePtr->tokenPtr[firstIndex].size;
	exprTokenPtr->numComponents =
	        (parsePtr->tokenPtr[firstIndex].numComponents + 1);
	break;
	
    case QUOTE:
	/*
	 * '"' string '"'
	 */
	
	stringStart = infoPtr->next;
	code = Tcl_ParseQuotedString(interp, infoPtr->start,
	        (infoPtr->lastChar - stringStart), parsePtr, 1, &termPtr);
	if (code != TCL_OK) {
	    return code;
	}
	infoPtr->next = termPtr;

	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
	exprTokenPtr->size = (termPtr - exprTokenPtr->start);
	exprTokenPtr->numComponents = parsePtr->numTokens - firstIndex;

	/*
	 * If parsing the quoted string resulted in more than one token,
	 * insert a TCL_TOKEN_WORD token before them. This indicates that
	 * the quoted string represents a concatenation of multiple tokens.
	 */

	if (exprTokenPtr->numComponents > 1) {
	    if (parsePtr->numTokens >= parsePtr->tokensAvailable) {
		TclExpandTokenArray(parsePtr);
	    }
	    tokenPtr = &parsePtr->tokenPtr[firstIndex];
	    numToMove = (parsePtr->numTokens - firstIndex);
	    memmove((VOID *) (tokenPtr + 1), (VOID *) tokenPtr,
	            (size_t) (numToMove * sizeof(Tcl_Token)));
	    parsePtr->numTokens++;

	    exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
	    exprTokenPtr->numComponents++;

	    tokenPtr->type = TCL_TOKEN_WORD;
	    tokenPtr->start = exprTokenPtr->start;
	    tokenPtr->size = exprTokenPtr->size;
	    tokenPtr->numComponents = (exprTokenPtr->numComponents - 1);
	}
	break;
	
    case OPEN_BRACKET:
	/*
	 * '[' command {command} ']'
	 */

	if (parsePtr->numTokens == parsePtr->tokensAvailable) {
	    TclExpandTokenArray(parsePtr);
	}
	tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
	tokenPtr->type = TCL_TOKEN_COMMAND;
	tokenPtr->start = infoPtr->start;
	tokenPtr->numComponents = 0;
	parsePtr->numTokens++;

	/*
	 * Call Tcl_ParseCommand repeatedly to parse the nested command(s)
	 * to find their end, then throw away that parse information.
	 */
	
	src = infoPtr->next;
	while (1) {
	    if (Tcl_ParseCommand(interp, src, (parsePtr->end - src), 1,
		    &nested) != TCL_OK) {
		parsePtr->term = nested.term;
		parsePtr->incomplete = nested.incomplete;
		return TCL_ERROR;
	    }
	    src = (nested.commandStart + nested.commandSize);
	    if (nested.tokenPtr != nested.staticTokens) {
		ckfree((char *) nested.tokenPtr);
	    }
	    if ((src[-1] == ']') && !nested.incomplete) {
		break;
	    }
	    if (src == parsePtr->end) {
		if (parsePtr->interp != NULL) {
		    Tcl_SetResult(interp, "missing close-bracket",
			    TCL_STATIC);
		}
		parsePtr->term = tokenPtr->start;
		parsePtr->incomplete = 1;
		return TCL_ERROR;
	    }
	}
	tokenPtr->size = (src - tokenPtr->start);
	infoPtr->next = src;

	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
	exprTokenPtr->size = (src - tokenPtr->start);
	exprTokenPtr->numComponents = 1;
	break;

    case OPEN_BRACE:
	/*
	 * '{' string '}'
	 */

	code = Tcl_ParseBraces(interp, infoPtr->start,
	        (infoPtr->lastChar - infoPtr->start), parsePtr, 1,
		&termPtr);
	if (code != TCL_OK) {
	    return code;
	}
	infoPtr->next = termPtr;

	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
	exprTokenPtr->size = (termPtr - infoPtr->start);
	exprTokenPtr->numComponents = parsePtr->numTokens - firstIndex;

	/*
	 * If parsing the braced string resulted in more than one token,
	 * insert a TCL_TOKEN_WORD token before them. This indicates that
	 * the braced string represents a concatenation of multiple tokens.
	 */

	if (exprTokenPtr->numComponents > 1) {
	    if (parsePtr->numTokens >= parsePtr->tokensAvailable) {
		TclExpandTokenArray(parsePtr);
	    }
	    tokenPtr = &parsePtr->tokenPtr[firstIndex];
	    numToMove = (parsePtr->numTokens - firstIndex);
	    memmove((VOID *) (tokenPtr + 1), (VOID *) tokenPtr,
	            (size_t) (numToMove * sizeof(Tcl_Token)));
	    parsePtr->numTokens++;

	    exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
	    exprTokenPtr->numComponents++;
	    
	    tokenPtr->type = TCL_TOKEN_WORD;
	    tokenPtr->start = exprTokenPtr->start;
	    tokenPtr->size = exprTokenPtr->size;
	    tokenPtr->numComponents = exprTokenPtr->numComponents-1;
	}
	break;
	
    case FUNC_NAME:
	/*
	 * math_func '(' expr {',' expr} ')'
	 */
	
	if (parsePtr->numTokens == parsePtr->tokensAvailable) {
	    TclExpandTokenArray(parsePtr);
	}
	tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
	tokenPtr->type = TCL_TOKEN_OPERATOR;
	tokenPtr->start = infoPtr->start;
	tokenPtr->size = infoPtr->size;
	tokenPtr->numComponents = 0;
	parsePtr->numTokens++;
	
	code = GetLexeme(infoPtr); /* skip over function name */
	if (code != TCL_OK) {
	    return code;
	}
	if (infoPtr->lexeme != OPEN_PAREN) {
	    goto syntaxError;
	}
	code = GetLexeme(infoPtr); /* skip over '(' */
	if (code != TCL_OK) {
	    return code;
	}

	while (infoPtr->lexeme != CLOSE_PAREN) {
	    code = ParseCondExpr(infoPtr);
	    if (code != TCL_OK) {
		return code;
	    }
	    
	    if (infoPtr->lexeme == COMMA) {
		code = GetLexeme(infoPtr); /* skip over , */
		if (code != TCL_OK) {
		    return code;
		}
	    } else if (infoPtr->lexeme != CLOSE_PAREN) {
		goto syntaxError;
	    }
	}

	exprTokenPtr = &parsePtr->tokenPtr[exprIndex];
	exprTokenPtr->size = (infoPtr->next - exprTokenPtr->start);
	exprTokenPtr->numComponents = parsePtr->numTokens - firstIndex;
	break;
	
    default:
	goto syntaxError;
    }

    /*
     * Advance to the next lexeme before returning.
     */
    
    code = GetLexeme(infoPtr);
    if (code != TCL_OK) {
	return code;
    }
    parsePtr->term = infoPtr->next;
    return TCL_OK;

    syntaxError:
    LogSyntaxError(infoPtr);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GetLexeme --
 *
 *	Lexical scanner for Tcl expressions: scans a single operator or
 *	other syntactic element from an expression string.
 *
 * Results:
 *	TCL_OK is returned unless an error occurred. In that case a standard
 *	Tcl error code is returned and, if infoPtr->parsePtr->interp is
 *	non-NULL, the interpreter's result is set to hold an error
 *	message. TCL_ERROR is returned if an integer overflow, or a
 *	floating-point overflow or underflow occurred while reading in a
 *	number. If the lexical analysis is successful, infoPtr->lexeme
 *	refers to the next symbol in the expression string, and
 *	infoPtr->next is advanced past the lexeme. Also, if the lexeme is a
 *	LITERAL or FUNC_NAME, then infoPtr->start is set to the first
 *	character of the lexeme; otherwise it is set NULL.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold all the
 *	information about the subexpression, then additional space is
 *	malloc-ed..
 *
 *----------------------------------------------------------------------
 */

static int
GetLexeme(infoPtr)
    ParseInfo *infoPtr;		/* Holds state needed to parse the expr,
				 * including the resulting lexeme. */
{
    register char *src;		/* Points to current source char. */
    char *termPtr;		/* Points to char terminating a literal. */
    double doubleValue;		/* Value of a scanned double literal. */
    char c;
    int startsWithDigit, offset;
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    Tcl_Interp *interp = parsePtr->interp;
    Tcl_UniChar ch;

    /*
     * Record where the previous lexeme ended. Since we always read one
     * lexeme ahead during parsing, this helps us know the source length of
     * subexpression tokens.
     */

    infoPtr->prevEnd = infoPtr->next;

    /*
     * Scan over leading white space at the start of a lexeme. Note that a
     * backslash-newline is treated as a space.
     */

    src = infoPtr->next;
    c = *src;
    while (isspace(UCHAR(c)) || (c == '\\')) { /* INTL: ISO space */
	if (c == '\\') {
	    if (src[1] == '\n') {
		src += 2;
	    } else {
		break;	/* no longer white space */
	    }
	} else {
	    src++;
	}
	c = *src;
    }
    parsePtr->term = src;
    if (src >= infoPtr->lastChar) {
	infoPtr->lexeme = END;
	infoPtr->next = src;
	return TCL_OK;
    }

    /*
     * Try to parse the lexeme first as an integer or floating-point
     * number. Don't check for a number if the first character c is
     * "+" or "-". If we did, we might treat a binary operator as unary
     * by mistake, which would eventually cause a syntax error.
     */

    if ((c != '+') && (c != '-')) {
	startsWithDigit = isdigit(UCHAR(c)); /* INTL: digit */
	if (startsWithDigit && TclLooksLikeInt(src, -1)) {
	    errno = 0;
	    (void) strtoul(src, &termPtr, 0);
	    if (errno == ERANGE) {
		if (interp != NULL) {
		    char *s = "integer value too large to represent";
		    Tcl_ResetResult(interp);
		    Tcl_AppendToObj(Tcl_GetObjResult(interp), s, -1);
		    Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s,
			    (char *) NULL);
		}
		return TCL_ERROR;
	    }
 	    if (termPtr != src) {
                /*
                 * src was the start of a valid integer.
                 */

                infoPtr->lexeme = LITERAL;
		infoPtr->start = src;
		infoPtr->size = (termPtr - src);
                infoPtr->next = termPtr;
		parsePtr->term = termPtr;
                return TCL_OK;
	    }
	} else if (startsWithDigit || (c == '.')
	        || (c == 'n') || (c == 'N')) {
	    errno = 0;
	    doubleValue = strtod(src, &termPtr);
	    if (termPtr != src) {
		if (errno != 0) {
		    if (interp != NULL) {
			TclExprFloatError(interp, doubleValue);
		    }
		    return TCL_ERROR;
		}
		
		/*
                 * src was the start of a valid double.
                 */
		
		infoPtr->lexeme = LITERAL;
		infoPtr->start = src;
		infoPtr->size = (termPtr - src);
		infoPtr->next = termPtr;
		parsePtr->term = termPtr;
		return TCL_OK;
	    }
	}
    }

    /*
     * Not an integer or double literal. Initialize the lexeme's fields
     * assuming the common case of a single character lexeme.
     */

    infoPtr->start = src;
    infoPtr->size = 1;
    infoPtr->next = src+1;
    parsePtr->term = infoPtr->next;
    
    switch (*src) {
	case '[':
	    infoPtr->lexeme = OPEN_BRACKET;
	    return TCL_OK;

        case '{':
	    infoPtr->lexeme = OPEN_BRACE;
	    return TCL_OK;

	case '(':
	    infoPtr->lexeme = OPEN_PAREN;
	    return TCL_OK;

	case ')':
	    infoPtr->lexeme = CLOSE_PAREN;
	    return TCL_OK;

	case '$':
	    infoPtr->lexeme = DOLLAR;
	    return TCL_OK;

	case '"':
	    infoPtr->lexeme = QUOTE;
	    return TCL_OK;

	case ',':
	    infoPtr->lexeme = COMMA;
	    return TCL_OK;

	case '*':
	    infoPtr->lexeme = MULT;
	    return TCL_OK;

	case '/':
	    infoPtr->lexeme = DIVIDE;
	    return TCL_OK;

	case '%':
	    infoPtr->lexeme = MOD;
	    return TCL_OK;

	case '+':
	    infoPtr->lexeme = PLUS;
	    return TCL_OK;

	case '-':
	    infoPtr->lexeme = MINUS;
	    return TCL_OK;

	case '?':
	    infoPtr->lexeme = QUESTY;
	    return TCL_OK;

	case ':':
	    infoPtr->lexeme = COLON;
	    return TCL_OK;

	case '<':
	    switch (src[1]) {
		case '<':
		    infoPtr->lexeme = LEFT_SHIFT;
		    infoPtr->size = 2;
		    infoPtr->next = src+2;
		    break;
		case '=':
		    infoPtr->lexeme = LEQ;
		    infoPtr->size = 2;
		    infoPtr->next = src+2;
		    break;
		default:
		    infoPtr->lexeme = LESS;
		    break;
	    }
	    parsePtr->term = infoPtr->next;
	    return TCL_OK;

	case '>':
	    switch (src[1]) {
		case '>':
		    infoPtr->lexeme = RIGHT_SHIFT;
		    infoPtr->size = 2;
		    infoPtr->next = src+2;
		    break;
		case '=':
		    infoPtr->lexeme = GEQ;
		    infoPtr->size = 2;
		    infoPtr->next = src+2;
		    break;
		default:
		    infoPtr->lexeme = GREATER;
		    break;
	    }
	    parsePtr->term = infoPtr->next;
	    return TCL_OK;

	case '=':
	    if (src[1] == '=') {
		infoPtr->lexeme = EQUAL;
		infoPtr->size = 2;
		infoPtr->next = src+2;
	    } else {
		infoPtr->lexeme = UNKNOWN;
	    }
	    parsePtr->term = infoPtr->next;
	    return TCL_OK;

	case '!':
	    if (src[1] == '=') {
		infoPtr->lexeme = NEQ;
		infoPtr->size = 2;
		infoPtr->next = src+2;
	    } else {
		infoPtr->lexeme = NOT;
	    }
	    parsePtr->term = infoPtr->next;
	    return TCL_OK;

	case '&':
	    if (src[1] == '&') {
		infoPtr->lexeme = AND;
		infoPtr->size = 2;
		infoPtr->next = src+2;
	    } else {
		infoPtr->lexeme = BIT_AND;
	    }
	    parsePtr->term = infoPtr->next;
	    return TCL_OK;

	case '^':
	    infoPtr->lexeme = BIT_XOR;
	    return TCL_OK;

	case '|':
	    if (src[1] == '|') {
		infoPtr->lexeme = OR;
		infoPtr->size = 2;
		infoPtr->next = src+2;
	    } else {
		infoPtr->lexeme = BIT_OR;
	    }
	    parsePtr->term = infoPtr->next;
	    return TCL_OK;

	case '~':
	    infoPtr->lexeme = BIT_NOT;
	    return TCL_OK;

	default:
	    offset = Tcl_UtfToUniChar(src, &ch);
	    c = UCHAR(ch);
	    if (isalpha(UCHAR(c))) {	/* INTL: ISO only. */
		infoPtr->lexeme = FUNC_NAME;
		while (isalnum(UCHAR(c)) || (c == '_')) { /* INTL: ISO only. */
		    src += offset;
		    offset = Tcl_UtfToUniChar(src, &ch);
		    c = UCHAR(ch);
		}
		infoPtr->size = (src - infoPtr->start);
		infoPtr->next = src;
		parsePtr->term = infoPtr->next;
		return TCL_OK;
	    }
	    infoPtr->lexeme = UNKNOWN;
	    return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PrependSubExprTokens --
 *
 *	This procedure is called after the operands of an subexpression have
 *	been parsed. It generates two tokens: a TCL_TOKEN_SUB_EXPR token for
 *	the subexpression, and a TCL_TOKEN_OPERATOR token for its operator.
 *	These two tokens are inserted before the operand tokens.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If there is insufficient space in parsePtr to hold the new tokens,
 *	additional space is malloc-ed.
 *
 *----------------------------------------------------------------------
 */

static void
PrependSubExprTokens(op, opBytes, src, srcBytes, firstIndex, infoPtr)
    char *op;			/* Points to first byte of the operator
				 * in the source script. */
    int opBytes;		/* Number of bytes in the operator. */
    char *src;			/* Points to first byte of the subexpression
				 * in the source script. */
    int srcBytes;		/* Number of bytes in subexpression's
				 * source. */
    int firstIndex;		/* Index of first token already emitted for
				 * operator's first (or only) operand. */
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    Tcl_Parse *parsePtr = infoPtr->parsePtr;
    Tcl_Token *tokenPtr, *firstTokenPtr;
    int numToMove;

    if ((parsePtr->numTokens + 1) >= parsePtr->tokensAvailable) {
	TclExpandTokenArray(parsePtr);
    }
    firstTokenPtr = &parsePtr->tokenPtr[firstIndex];
    tokenPtr = (firstTokenPtr + 2);
    numToMove = (parsePtr->numTokens - firstIndex);
    memmove((VOID *) tokenPtr, (VOID *) firstTokenPtr,
            (size_t) (numToMove * sizeof(Tcl_Token)));
    parsePtr->numTokens += 2;
    
    tokenPtr = firstTokenPtr;
    tokenPtr->type = TCL_TOKEN_SUB_EXPR;
    tokenPtr->start = src;
    tokenPtr->size = srcBytes;
    tokenPtr->numComponents = parsePtr->numTokens - (firstIndex + 1);
    
    tokenPtr++;
    tokenPtr->type = TCL_TOKEN_OPERATOR;
    tokenPtr->start = op;
    tokenPtr->size = opBytes;
    tokenPtr->numComponents = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * LogSyntaxError --
 *
 *	This procedure is invoked after an error occurs when parsing an
 *	expression. It sets the interpreter result to an error message
 *	describing the error.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets the interpreter result to an error message describing the
 *	expression that was being parsed when the error occurred.
 *
 *----------------------------------------------------------------------
 */

static void
LogSyntaxError(infoPtr)
    ParseInfo *infoPtr;		/* Holds the parse state for the
				 * expression being parsed. */
{
    int numBytes = (infoPtr->lastChar - infoPtr->originalExpr);
    char buffer[100];

    sprintf(buffer, "syntax error in expression \"%.*s\"",
	    ((numBytes > 60)? 60 : numBytes), infoPtr->originalExpr);
    Tcl_AppendStringsToObj(Tcl_GetObjResult(infoPtr->parsePtr->interp),
	    buffer, (char *) NULL);
}

Changes to generic/tclPipe.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclPipe.c --
 *
 *	This file contains the generic portion of the command channel
 *	driver as well as various utility routines used in managing
 *	subprocesses.
 *
 * 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.
 *
 * SCCS: @(#) tclPipe.c 1.8 97/06/20 13:26:45
 */

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

/*
 * A linked list of the following structures is used to keep track












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclPipe.c --
 *
 *	This file contains the generic portion of the command channel
 *	driver as well as various utility routines used in managing
 *	subprocesses.
 *
 * 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: tclPipe.c,v 1.1.2.5 1998/12/12 01:37:02 lfb Exp $
 */

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

/*
 * A linked list of the following structures is used to keep track
28
29
30
31
32
33
34

35
36
37
38
39
40
41
    Tcl_Pid pid;			/* Id of process that's been detached
					 * but isn't known to have exited. */
    struct Detached *nextPtr;		/* Next in list of all detached
					 * processes. */
} Detached;

static Detached *detList = NULL;	/* List of all detached proceses. */


/*
 * Declarations for local procedures defined in this file:
 */

static TclFile	FileForRedirect _ANSI_ARGS_((Tcl_Interp *interp,
	            char *spec, int atOk, char *arg, char *nextArg, 







>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    Tcl_Pid pid;			/* Id of process that's been detached
					 * but isn't known to have exited. */
    struct Detached *nextPtr;		/* Next in list of all detached
					 * processes. */
} Detached;

static Detached *detList = NULL;	/* List of all detached proceses. */
TCL_DECLARE_MUTEX(pipeMutex)		/* Guard access to detList. */

/*
 * Declarations for local procedures defined in this file:
 */

static TclFile	FileForRedirect _ANSI_ARGS_((Tcl_Interp *interp,
	            char *spec, int atOk, char *arg, char *nextArg, 
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 *	This procedure does much of the work of parsing redirection
 *	operators.  It handles "@" if specified and allowed, and a file
 *	name, and opens the file if necessary.
 *
 * Results:
 *	The return value is the descriptor number for the file.  If an
 *	error occurs then NULL is returned and an error message is left
 *	in interp->result.  Several arguments are side-effected; see
 *	the argument list below for details.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */







|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
 *	This procedure does much of the work of parsing redirection
 *	operators.  It handles "@" if specified and allowed, and a file
 *	name, and opens the file if necessary.
 *
 * Results:
 *	The return value is the descriptor number for the file.  If an
 *	error occurs then NULL is returned and an error message is left
 *	in the interp's result.  Several arguments are side-effected; see
 *	the argument list below for details.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
179
180
181
182
183
184
185

186
187
188
189
190
191


192
193
194
195
196
197
198
    int numPids;		/* Number of pids to detach:  gives size
				 * of array pointed to by pidPtr. */
    Tcl_Pid *pidPtr;		/* Array of pids to detach. */
{
    register Detached *detPtr;
    int i;


    for (i = 0; i < numPids; i++) {
	detPtr = (Detached *) ckalloc(sizeof(Detached));
	detPtr->pid = pidPtr[i];
	detPtr->nextPtr = detList;
	detList = detPtr;
    }


}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ReapDetachedProcs --
 *







>






>
>







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
    int numPids;		/* Number of pids to detach:  gives size
				 * of array pointed to by pidPtr. */
    Tcl_Pid *pidPtr;		/* Array of pids to detach. */
{
    register Detached *detPtr;
    int i;

    Tcl_MutexLock(&pipeMutex);
    for (i = 0; i < numPids; i++) {
	detPtr = (Detached *) ckalloc(sizeof(Detached));
	detPtr->pid = pidPtr[i];
	detPtr->nextPtr = detList;
	detList = detPtr;
    }
    Tcl_MutexUnlock(&pipeMutex);

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ReapDetachedProcs --
 *
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
Tcl_ReapDetachedProcs()
{
    register Detached *detPtr;
    Detached *nextPtr, *prevPtr;
    int status;
    Tcl_Pid pid;


    for (detPtr = detList, prevPtr = NULL; detPtr != NULL; ) {
	pid = Tcl_WaitPid(detPtr->pid, &status, WNOHANG);
	if ((pid == 0) || ((pid == (Tcl_Pid) -1) && (errno != ECHILD))) {
	    prevPtr = detPtr;
	    detPtr = detPtr->nextPtr;
	    continue;
	}
	nextPtr = detPtr->nextPtr;
	if (prevPtr == NULL) {
	    detList = detPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = detPtr->nextPtr;
	}
	ckfree((char *) detPtr);
	detPtr = nextPtr;
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TclCleanupChildren --
 *
 *	This is a utility procedure used to wait for child processes
 *	to exit, record information about abnormal exits, and then
 *	collect any stderr output generated by them.
 *
 * Results:
 *	The return value is a standard Tcl result.  If anything at
 *	weird happened with the child processes, TCL_ERROR is returned
 *	and a message is left in interp->result.
 *
 * Side effects:
 *	If the last character of interp->result is a newline, then it
 *	is removed unless keepNewline is non-zero.  File errorId gets
 *	closed, and pidPtr is freed back to the storage allocator.
 *
 *----------------------------------------------------------------------
 */

int







>
















>














|


|







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
Tcl_ReapDetachedProcs()
{
    register Detached *detPtr;
    Detached *nextPtr, *prevPtr;
    int status;
    Tcl_Pid pid;

    Tcl_MutexLock(&pipeMutex);
    for (detPtr = detList, prevPtr = NULL; detPtr != NULL; ) {
	pid = Tcl_WaitPid(detPtr->pid, &status, WNOHANG);
	if ((pid == 0) || ((pid == (Tcl_Pid) -1) && (errno != ECHILD))) {
	    prevPtr = detPtr;
	    detPtr = detPtr->nextPtr;
	    continue;
	}
	nextPtr = detPtr->nextPtr;
	if (prevPtr == NULL) {
	    detList = detPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = detPtr->nextPtr;
	}
	ckfree((char *) detPtr);
	detPtr = nextPtr;
    }
    Tcl_MutexUnlock(&pipeMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * TclCleanupChildren --
 *
 *	This is a utility procedure used to wait for child processes
 *	to exit, record information about abnormal exits, and then
 *	collect any stderr output generated by them.
 *
 * Results:
 *	The return value is a standard Tcl result.  If anything at
 *	weird happened with the child processes, TCL_ERROR is returned
 *	and a message is left in the interp's result.
 *
 * Side effects:
 *	If the last character of the interp's result is a newline, then it
 *	is removed unless keepNewline is non-zero.  File errorId gets
 *	closed, and pidPtr is freed back to the storage allocator.
 *
 *----------------------------------------------------------------------
 */

int
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
	 * Create error messages for unusual process exits.  An
	 * extra newline gets appended to each error message, but
	 * it gets removed below (in the same fashion that an
	 * extra newline in the command's output is removed).
	 */

	if (!WIFEXITED(waitStatus) || (WEXITSTATUS(waitStatus) != 0)) {
	    char msg1[20], msg2[20];

	    result = TCL_ERROR;
	    sprintf(msg1, "%ld", TclpGetPid(pid));
	    if (WIFEXITED(waitStatus)) {
                if (interp != (Tcl_Interp *) NULL) {
                    sprintf(msg2, "%d", WEXITSTATUS(waitStatus));
                    Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2,
                            (char *) NULL);
                }
		abnormalExit = 1;
	    } else if (WIFSIGNALED(waitStatus)) {
                if (interp != (Tcl_Interp *) NULL) {
                    char *p;







|


|


|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
	 * Create error messages for unusual process exits.  An
	 * extra newline gets appended to each error message, but
	 * it gets removed below (in the same fashion that an
	 * extra newline in the command's output is removed).
	 */

	if (!WIFEXITED(waitStatus) || (WEXITSTATUS(waitStatus) != 0)) {
	    char msg1[TCL_INTEGER_SPACE], msg2[TCL_INTEGER_SPACE];

	    result = TCL_ERROR;
	    TclFormatInt(msg1, (long) TclpGetPid(pid));
	    if (WIFEXITED(waitStatus)) {
                if (interp != (Tcl_Interp *) NULL) {
		    TclFormatInt(msg2, WEXITSTATUS(waitStatus));
                    Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2,
                            (char *) NULL);
                }
		abnormalExit = 1;
	    } else if (WIFSIGNALED(waitStatus)) {
                if (interp != (Tcl_Interp *) NULL) {
                    char *p;
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
    anyErrorInfo = 0;
    if (errorChan != NULL) {

	/*
	 * Make sure we start at the beginning of the file.
	 */

	Tcl_Seek(errorChan, 0L, SEEK_SET);

        if (interp != (Tcl_Interp *) NULL) {
            while (1) {
#define BUFFER_SIZE 1000
                char buffer[BUFFER_SIZE+1];
                int count;

    


                count = Tcl_Read(errorChan, buffer, BUFFER_SIZE);
                if (count == 0) {
                    break;
                }
                result = TCL_ERROR;
                if (count < 0) {
                    Tcl_AppendResult(interp,
                            "error reading stderr output file: ",
                            Tcl_PosixError(interp), (char *) NULL);
                    break;	/* out of the "while (1)" loop. */
                }
                buffer[count] = 0;
                Tcl_AppendResult(interp, buffer, (char *) NULL);
                anyErrorInfo = 1;


            }

        }
        
	Tcl_Close((Tcl_Interp *) NULL, errorChan);
    }

    /*
     * If a child exited abnormally but didn't output any error information
     * at all, generate an error message here.
     */

    if (abnormalExit && !anyErrorInfo && (interp != (Tcl_Interp *) NULL)) {
	Tcl_AppendResult(interp, "child process exited abnormally",
		(char *) NULL);
    }
    
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCreatePipeline --







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







|



<







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
    anyErrorInfo = 0;
    if (errorChan != NULL) {

	/*
	 * Make sure we start at the beginning of the file.
	 */



        if (interp != NULL) {



	    int count;
	    Tcl_Obj *objPtr;
	    
	    Tcl_Seek(errorChan, 0L, SEEK_SET);
	    objPtr = Tcl_NewObj();
	    count = Tcl_ReadChars(errorChan, objPtr, -1, 0);
	    if (count < 0) {


		result = TCL_ERROR;
		Tcl_DecrRefCount(objPtr);
		Tcl_ResetResult(interp);
		Tcl_AppendResult(interp, "error reading stderr output file: ",
			Tcl_PosixError(interp), NULL);


	    } else if (count > 0) {

		anyErrorInfo = 1;
		Tcl_SetObjResult(interp, objPtr);
		result = TCL_ERROR;
	    } else {
		Tcl_DecrRefCount(objPtr);
	    }
	}
	Tcl_Close(NULL, errorChan);
    }

    /*
     * If a child exited abnormally but didn't output any error information
     * at all, generate an error message here.
     */

    if ((abnormalExit != 0) && (anyErrorInfo == 0) && (interp != NULL)) {
	Tcl_AppendResult(interp, "child process exited abnormally",
		(char *) NULL);
    }

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCreatePipeline --
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
    if (inputFile == NULL) {
	if (inputLiteral != NULL) {
	    /*
	     * The input for the first process is immediate data coming from
	     * Tcl.  Create a temporary file for it and put the data into the
	     * file.
	     */
	    inputFile = TclpCreateTempFile(inputLiteral, NULL);
	    if (inputFile == NULL) {
		Tcl_AppendResult(interp,
			"couldn't create input file for command: ",
			Tcl_PosixError(interp), (char *) NULL);
		goto error;
	    }
	    inputClose = 1;







|







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
    if (inputFile == NULL) {
	if (inputLiteral != NULL) {
	    /*
	     * The input for the first process is immediate data coming from
	     * Tcl.  Create a temporary file for it and put the data into the
	     * file.
	     */
	    inputFile = TclpCreateTempFile(inputLiteral);
	    if (inputFile == NULL) {
		Tcl_AppendResult(interp,
			"couldn't create input file for command: ",
			Tcl_PosixError(interp), (char *) NULL);
		goto error;
	    }
	    inputClose = 1;
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
	     * requested.  Use a temporary file which is opened, then deleted.
	     * Could potentially just use pipe, but if it filled up it could
	     * cause the pipeline to deadlock:  we'd be waiting for processes
	     * to complete before reading stderr, and processes couldn't 
	     * complete because stderr was backed up.
	     */

	    errorFile = TclpCreateTempFile(NULL, NULL);
	    if (errorFile == NULL) {
		Tcl_AppendResult(interp,
			"couldn't create error file for command: ",
			Tcl_PosixError(interp), (char *) NULL);
		goto error;
	    }
	    *errFilePtr = errorFile;







|







762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
	     * requested.  Use a temporary file which is opened, then deleted.
	     * Could potentially just use pipe, but if it filled up it could
	     * cause the pipeline to deadlock:  we'd be waiting for processes
	     * to complete before reading stderr, and processes couldn't 
	     * complete because stderr was backed up.
	     */

	    errorFile = TclpCreateTempFile(NULL);
	    if (errorFile == NULL) {
		Tcl_AppendResult(interp,
			"couldn't create error file for command: ",
			Tcl_PosixError(interp), (char *) NULL);
		goto error;
	    }
	    *errFilePtr = errorFile;
795
796
797
798
799
800
801
802
803

804
805
806
807
808
809
810
811
812
813
814
815
816
817

    Tcl_ReapDetachedProcs();
    pidPtr = (Tcl_Pid *) ckalloc((unsigned) (cmdCount * sizeof(Tcl_Pid)));

    curInFile = inputFile;

    for (i = 0; i < argc; i = lastArg + 1) { 
	int joinThisError;
	Tcl_Pid pid;


	/*
	 * Convert the program name into native form. 
	 */

	argv[i] = Tcl_TranslateFileName(interp, argv[i], &execBuffer);
	if (argv[i] == NULL) {
	    goto error;
	}

	/*
	 * Find the end of the current segment of the pipeline.
	 */








|

>





|
<







796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811

812
813
814
815
816
817
818

    Tcl_ReapDetachedProcs();
    pidPtr = (Tcl_Pid *) ckalloc((unsigned) (cmdCount * sizeof(Tcl_Pid)));

    curInFile = inputFile;

    for (i = 0; i < argc; i = lastArg + 1) { 
	int result, joinThisError;
	Tcl_Pid pid;
	char *oldName;

	/*
	 * Convert the program name into native form. 
	 */

	if (Tcl_TranslateFileName(interp, argv[i], &execBuffer) == NULL) {

	    goto error;
	}

	/*
	 * Find the end of the current segment of the pipeline.
	 */

847
848
849
850
851
852
853







854
855


856
857
858
859
860
861
862

	if (joinThisError != 0) {
	    curErrFile = curOutFile;
	} else {
	    curErrFile = errorFile;
	}








	if (TclpCreateProcess(interp, lastArg - i, argv + i,
		curInFile, curOutFile, curErrFile, &pid) != TCL_OK) {


	    goto error;
	}
	Tcl_DStringFree(&execBuffer);

	pidPtr[numPids] = pid;
	numPids++;








>
>
>
>
>
>
>
|
|
>
>







848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872

	if (joinThisError != 0) {
	    curErrFile = curOutFile;
	} else {
	    curErrFile = errorFile;
	}

	/*
	 * Restore argv[i], since a caller wouldn't expect the contents of
	 * argv to be modified.
	 */
	 
	oldName = argv[i];
	argv[i] = Tcl_DStringValue(&execBuffer);
	result = TclpCreateProcess(interp, lastArg - i, argv + i,
		curInFile, curOutFile, curErrFile, &pid);
	argv[i] = oldName;
	if (result != TCL_OK) {
	    goto error;
	}
	Tcl_DStringFree(&execBuffer);

	pidPtr[numPids] = pid;
	numPids++;

Changes to generic/tclPkg.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclPkg.c --
 *
 *	This file implements package and version control for Tcl via
 *	the "package" command and a few C APIs.
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclPkg.c 1.9 97/05/14 13:23:51
 */

#include "tclInt.h"

/*
 * Each invocation of the "package ifneeded" command creates a structure
 * of the following type, which is used to load the package into the











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclPkg.c --
 *
 *	This file implements package and version control for Tcl via
 *	the "package" command and a few C APIs.
 *
 * Copyright (c) 1996 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: tclPkg.c,v 1.1.2.4 1999/03/25 23:28:54 stanton Exp $
 */

#include "tclInt.h"

/*
 * Each invocation of the "package ifneeded" command creates a structure
 * of the following type, which is used to load the package into the
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
typedef struct Package {
    char *version;		/* Version that has been supplied in this
				 * interpreter via "package provide"
				 * (malloc'ed).  NULL means the package doesn't
				 * exist in this interpreter yet. */
    PkgAvail *availPtr;		/* First in list of all available versions
				 * of this package. */

} Package;

/*
 * Prototypes for procedures defined in this file:
 */

static int		CheckVersion _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string));
static int		ComparePkgVersions _ANSI_ARGS_((char *v1, char *v2,
			    int *satPtr));
static Package *	FindPackage _ANSI_ARGS_((Tcl_Interp *interp,
			    char *name));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PkgProvide --
 *
 *	This procedure is invoked to declare that a particular version
 *	of a particular package is now present in an interpreter.  There
 *	must not be any other version of this package already
 *	provided in the interpreter.
 *
 * Results:
 *	Normally returns TCL_OK;  if there is already another version
 *	of the package loaded then TCL_ERROR is returned and an error
 *	message is left in interp->result.
 *
 * Side effects:
 *	The interpreter remembers that this package is available,
 *	so that no other version of the package may be provided for
 *	the interpreter.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_PkgProvide(interp, name, version)
    Tcl_Interp *interp;		/* Interpreter in which package is now
				 * available. */
    char *name;			/* Name of package. */
    char *version;		/* Version string for package. */
{












    Package *pkgPtr;

    pkgPtr = FindPackage(interp, name);
    if (pkgPtr->version == NULL) {
	pkgPtr->version = ckalloc((unsigned) (strlen(version) + 1));
	strcpy(pkgPtr->version, version);

	return TCL_OK;
    }
    if (ComparePkgVersions(pkgPtr->version, version, (int *) NULL) == 0) {



	return TCL_OK;
    }
    Tcl_AppendResult(interp, "conflicting versions provided for package \"",
	    name, "\": ", pkgPtr->version, ", then ", version, (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PkgRequire --
 *
 *	This procedure is called by code that depends on a particular
 *	version of a particular package.  If the package is not already
 *	provided in the interpreter, this procedure invokes a Tcl script
 *	to provide it.  If the package is already provided, this
 *	procedure makes sure that the caller's needs don't conflict with
 *	the version that is present.
 *
 * Results:
 *	If successful, returns the version string for the currently
 *	provided version of the package, which may be different from
 *	the "version" argument.  If the caller's requirements
 *	cannot be met (e.g. the version requested conflicts with
 *	a currently provided version, or the required version cannot
 *	be found, or the script to provide the required version
 *	generates an error), NULL is returned and an error
 *	message is left in interp->result.
 *
 * Side effects:
 *	The script from some previous "package ifneeded" command may
 *	be invoked to provide the package.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_PkgRequire(interp, name, version, exact)
    Tcl_Interp *interp;		/* Interpreter in which package is now
				 * available. */
    char *name;			/* Name of desired package. */
    char *version;		/* Version string for desired version;
				 * NULL means use the latest version
				 * available. */
    int exact;			/* Non-zero means that only the particular
				 * version given is acceptable. Zero means
				 * use the latest compatible version. */
{



















    Package *pkgPtr;
    PkgAvail *availPtr, *bestPtr;
    char *script;
    int code, satisfies, result, pass;
    Tcl_DString command;

















    /*
     * It can take up to three passes to find the package:  one pass to
     * run the "package unknown" script, one to run the "package ifneeded"
     * script for a specific version, and a final pass to lookup the
     * package loaded by the "package ifneeded" script.
     */







>
















|









|
















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






>



>
>
>










|
















|




















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





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







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
typedef struct Package {
    char *version;		/* Version that has been supplied in this
				 * interpreter via "package provide"
				 * (malloc'ed).  NULL means the package doesn't
				 * exist in this interpreter yet. */
    PkgAvail *availPtr;		/* First in list of all available versions
				 * of this package. */
    ClientData clientData;	/* Client data. */
} Package;

/*
 * Prototypes for procedures defined in this file:
 */

static int		CheckVersion _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string));
static int		ComparePkgVersions _ANSI_ARGS_((char *v1, char *v2,
			    int *satPtr));
static Package *	FindPackage _ANSI_ARGS_((Tcl_Interp *interp,
			    char *name));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PkgProvide / Tcl_PkgProvideEx --
 *
 *	This procedure is invoked to declare that a particular version
 *	of a particular package is now present in an interpreter.  There
 *	must not be any other version of this package already
 *	provided in the interpreter.
 *
 * Results:
 *	Normally returns TCL_OK;  if there is already another version
 *	of the package loaded then TCL_ERROR is returned and an error
 *	message is left in the interp's result.
 *
 * Side effects:
 *	The interpreter remembers that this package is available,
 *	so that no other version of the package may be provided for
 *	the interpreter.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_PkgProvide(interp, name, version)
    Tcl_Interp *interp;		/* Interpreter in which package is now
				 * available. */
    char *name;			/* Name of package. */
    char *version;		/* Version string for package. */
{
    return Tcl_PkgProvideEx(interp, name, version, (ClientData) NULL);
}

int
Tcl_PkgProvideEx(interp, name, version, clientData)
    Tcl_Interp *interp;		/* Interpreter in which package is now
				 * available. */
    char *name;			/* Name of package. */
    char *version;		/* Version string for package. */
    ClientData clientData;      /* clientdata for this package (normally
                                 * used for C callback function table) */
{
    Package *pkgPtr;

    pkgPtr = FindPackage(interp, name);
    if (pkgPtr->version == NULL) {
	pkgPtr->version = ckalloc((unsigned) (strlen(version) + 1));
	strcpy(pkgPtr->version, version);
	pkgPtr->clientData = clientData;
	return TCL_OK;
    }
    if (ComparePkgVersions(pkgPtr->version, version, (int *) NULL) == 0) {
	if (clientData != NULL) {
	    pkgPtr->clientData = clientData;
	}
	return TCL_OK;
    }
    Tcl_AppendResult(interp, "conflicting versions provided for package \"",
	    name, "\": ", pkgPtr->version, ", then ", version, (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PkgRequire / Tcl_PkgRequireEx --
 *
 *	This procedure is called by code that depends on a particular
 *	version of a particular package.  If the package is not already
 *	provided in the interpreter, this procedure invokes a Tcl script
 *	to provide it.  If the package is already provided, this
 *	procedure makes sure that the caller's needs don't conflict with
 *	the version that is present.
 *
 * Results:
 *	If successful, returns the version string for the currently
 *	provided version of the package, which may be different from
 *	the "version" argument.  If the caller's requirements
 *	cannot be met (e.g. the version requested conflicts with
 *	a currently provided version, or the required version cannot
 *	be found, or the script to provide the required version
 *	generates an error), NULL is returned and an error
 *	message is left in the interp's result.
 *
 * Side effects:
 *	The script from some previous "package ifneeded" command may
 *	be invoked to provide the package.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_PkgRequire(interp, name, version, exact)
    Tcl_Interp *interp;		/* Interpreter in which package is now
				 * available. */
    char *name;			/* Name of desired package. */
    char *version;		/* Version string for desired version;
				 * NULL means use the latest version
				 * available. */
    int exact;			/* Non-zero means that only the particular
				 * version given is acceptable. Zero means
				 * use the latest compatible version. */
{
    return Tcl_PkgRequireEx(interp, name, version, exact, (ClientData *) NULL);
}

char *
Tcl_PkgRequireEx(interp, name, version, exact, clientDataPtr)
    Tcl_Interp *interp;		/* Interpreter in which package is now
				 * available. */
    char *name;			/* Name of desired package. */
    char *version;		/* Version string for desired version;
				 * NULL means use the latest version
				 * available. */
    int exact;			/* Non-zero means that only the particular
				 * version given is acceptable. Zero means
				 * use the latest compatible version. */
    ClientData *clientDataPtr;	/* Used to return the client data for this
				 * package. If it is NULL then the client
				 * data is not returned. This is unchanged
				 * if this call fails for any reason. */
{
    Package *pkgPtr;
    PkgAvail *availPtr, *bestPtr;
    char *script;
    int code, satisfies, result, pass;
    Tcl_DString command;

    /*
     * If an attempt is being made to load this into a standalong executable
     * on a platform where backlinking is not supported then this must be
     * a shared version of Tcl (Otherwise the load would have failed).
     * Detect this situation by checking that this library has been correctly
     * initialised. If it has not been then return immediately as nothing will
     * work.
     */
    
    if (!tclEmptyStringRep) {
        Tcl_AppendResult(interp, "Cannot load package \"", name, 
                "\" in standalone executable: This package is not ",
                "compiled with stub support", NULL);
        return NULL;
    }

    /*
     * It can take up to three passes to find the package:  one pass to
     * run the "package unknown" script, one to run the "package ifneeded"
     * script for a specific version, and a final pass to lookup the
     * package loaded by the "package ifneeded" script.
     */
249
250
251
252
253
254
255
256
257
258
259
260



261
262
263
264



265
266
267
268
269
270
271
272
273
274
275




















































































































276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297









298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316






317

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335



336
337
338
339
340
341

342
343
344

345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383



384
385
386
387
388
389
390
391
392
393
394
395
396











397








398











399




400
401
402

403
404
405
406
407
408
409
410
411
412

413
414
415
416
417


418
419
420
421
422
423

424
425
426
427
428
429
430
431
432
433
434
435
436
437


438



439
440
441
442



443
444
445
446
447
448
449
450
451

452
453
454
455
456
457
458
459


460


461
462
463
464
465



466
467
468
469
470


471
472
473
474

475
476
477
478



479
480
481
482
483

484
485
486
487
488
489
490
491
492
493


494
495
496
497
498


499
500
501
502
503
504
505
506

507
508
509
510
511

512
513
514
515
516
517
518
	if (version != NULL) {
	    Tcl_AppendResult(interp, " ", version, (char *) NULL);
	}
	return NULL;
    }

    /*
     * At this point we now that the package is present.  Make sure that the
     * provided version meets the current requirement.
     */

    if (version == NULL) {



	return pkgPtr->version;
    }
    result = ComparePkgVersions(pkgPtr->version, version, &satisfies);
    if ((satisfies && !exact) || (result == 0)) {



	return pkgPtr->version;
    }
    Tcl_AppendResult(interp, "version conflict for package \"",
	    name, "\": have ", pkgPtr->version, ", need ", version,
	    (char *) NULL);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *




















































































































 * Tcl_PackageCmd --
 *
 *	This procedure is invoked to process the "package" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_PackageCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{









    Interp *iPtr = (Interp *) interp;
    size_t length;
    int c, exact, i, satisfies;
    PkgAvail *availPtr, *prevPtr;
    Package *pkgPtr;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Tcl_HashTable *tablePtr;
    char *version;
    char buf[30];

    if (argc < 2) {
	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		" option ?arg arg ...?\"", (char *) NULL);
	return TCL_ERROR;
    }
    c = argv[1][0];
    length = strlen(argv[1]);
    if ((c == 'f') && (strncmp(argv[1], "forget", length) == 0)) {






	for (i = 2; i < argc; i++) {

	    hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv[i]);
	    if (hPtr == NULL) {
		return TCL_OK;
	    }
	    pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
	    Tcl_DeleteHashEntry(hPtr);
	    if (pkgPtr->version != NULL) {
		ckfree(pkgPtr->version);
	    }
	    while (pkgPtr->availPtr != NULL) {
		availPtr = pkgPtr->availPtr;
		pkgPtr->availPtr = availPtr->nextPtr;
		ckfree(availPtr->version);
		Tcl_EventuallyFree((ClientData)availPtr->script, TCL_DYNAMIC);
		ckfree((char *) availPtr);
	    }
	    ckfree((char *) pkgPtr);
	}



    } else if ((c == 'i') && (strncmp(argv[1], "ifneeded", length) == 0)) {
	if ((argc != 4) && (argc != 5)) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		    " ifneeded package version ?script?\"", (char *) NULL);
	    return TCL_ERROR;
	}

	if (CheckVersion(interp, argv[3]) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (argc == 4) {
	    hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv[2]);
	    if (hPtr == NULL) {
		return TCL_OK;
	    }
	    pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
	} else {
	    pkgPtr = FindPackage(interp, argv[2]);
	}

	for (availPtr = pkgPtr->availPtr, prevPtr = NULL; availPtr != NULL;
		prevPtr = availPtr, availPtr = availPtr->nextPtr) {
	    if (ComparePkgVersions(availPtr->version, argv[3], (int *) NULL)
		    == 0) {
		if (argc == 4) {
		    Tcl_SetResult(interp, availPtr->script, TCL_VOLATILE);
		    return TCL_OK;
		}
		Tcl_EventuallyFree((ClientData)availPtr->script, TCL_DYNAMIC);
		break;
	    }
	}
	if (argc == 4) {
	    return TCL_OK;
	}
	if (availPtr == NULL) {
	    availPtr = (PkgAvail *) ckalloc(sizeof(PkgAvail));
	    availPtr->version = ckalloc((unsigned) (strlen(argv[3]) + 1));
	    strcpy(availPtr->version, argv[3]);
	    if (prevPtr == NULL) {
		availPtr->nextPtr = pkgPtr->availPtr;
		pkgPtr->availPtr = availPtr;
	    } else {
		availPtr->nextPtr = prevPtr->nextPtr;
		prevPtr->nextPtr = availPtr;
	    }
	}

	availPtr->script = ckalloc((unsigned) (strlen(argv[4]) + 1));
	strcpy(availPtr->script, argv[4]);
    } else if ((c == 'n') && (strncmp(argv[1], "names", length) == 0)) {



	if (argc != 2) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		    " names\"", (char *) NULL);
	    return TCL_ERROR;
	}
	tablePtr = &iPtr->packageTable;
	for (hPtr = Tcl_FirstHashEntry(tablePtr, &search); hPtr != NULL;
		hPtr = Tcl_NextHashEntry(&search)) {
	    pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
	    if ((pkgPtr->version != NULL) || (pkgPtr->availPtr != NULL)) {
		Tcl_AppendElement(interp, Tcl_GetHashKey(tablePtr, hPtr));
	    }
	}











    } else if ((c == 'p') && (strncmp(argv[1], "provide", length) == 0)) {








	if ((argc != 3) && (argc != 4)) {











	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],




		    " provide package ?version?\"", (char *) NULL);
	    return TCL_ERROR;
	}

	if (argc == 3) {
	    hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv[2]);
	    if (hPtr != NULL) {
		pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
		if (pkgPtr->version != NULL) {
		    Tcl_SetResult(interp, pkgPtr->version, TCL_VOLATILE);
		}
	    }
	    return TCL_OK;
	}

	if (CheckVersion(interp, argv[3]) != TCL_OK) {
	    return TCL_ERROR;
	}
	return Tcl_PkgProvide(interp, argv[2], argv[3]);
    } else if ((c == 'r') && (strncmp(argv[1], "require", length) == 0)) {


	if (argc < 3) {
	    requireSyntax:
	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		    " require ?-exact? package ?version?\"", (char *) NULL);
	    return TCL_ERROR;
	}

	if ((argv[2][0] == '-') && (strcmp(argv[2], "-exact") == 0)) {
	    exact = 1;
	} else {
	    exact = 0;
	}
	version = NULL;
	if (argc == (4+exact)) {
	    version = argv[3+exact];
	    if (CheckVersion(interp, version) != TCL_OK) {
		return TCL_ERROR;
	    }
	} else if ((argc != 3) || exact) {
	    goto requireSyntax;
	}


	version = Tcl_PkgRequire(interp, argv[2+exact], version, exact);



	if (version == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetResult(interp, version, TCL_VOLATILE);



    } else if ((c == 'u') && (strncmp(argv[1], "unknown", length) == 0)) {
	if (argc == 2) {
	    if (iPtr->packageUnknown != NULL) {
		Tcl_SetResult(interp, iPtr->packageUnknown, TCL_VOLATILE);
	    }
	} else if (argc == 3) {
	    if (iPtr->packageUnknown != NULL) {
		ckfree(iPtr->packageUnknown);
	    }

	    if (argv[2][0] == 0) {
		iPtr->packageUnknown = NULL;
	    } else {
		iPtr->packageUnknown = (char *) ckalloc((unsigned)
			(strlen(argv[2]) + 1));
		strcpy(iPtr->packageUnknown, argv[2]);
	    }
	} else {


	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],


		    " unknown ?command?\"", (char *) NULL);
	    return TCL_ERROR;
	}
    } else if ((c == 'v') && (strncmp(argv[1], "vcompare", length) == 0)
	    && (length >= 2)) {



	if (argc != 4) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		    " vcompare version1 version2\"", (char *) NULL);
	    return TCL_ERROR;
	}


	if ((CheckVersion(interp, argv[2]) != TCL_OK)
		|| (CheckVersion(interp, argv[3]) != TCL_OK)) {
	    return TCL_ERROR;
	}

	TclFormatInt(buf, ComparePkgVersions(argv[2], argv[3], (int *) NULL));
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else if ((c == 'v') && (strncmp(argv[1], "versions", length) == 0)
	    && (length >= 2)) {



	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		    " versions package\"", (char *) NULL);
	    return TCL_ERROR;
	}

	hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv[2]);
	if (hPtr != NULL) {
	    pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
	    for (availPtr = pkgPtr->availPtr; availPtr != NULL;
		    availPtr = availPtr->nextPtr) {
		Tcl_AppendElement(interp, availPtr->version);
	    }
	}
    } else if ((c == 'v') && (strncmp(argv[1], "vsatisfies", length) == 0)
	    && (length >= 2)) {


	if (argc != 4) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		    " vsatisfies version1 version2\"", (char *) NULL);
	    return TCL_ERROR;
	}


	if ((CheckVersion(interp, argv[2]) != TCL_OK)
		|| (CheckVersion(interp, argv[3]) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComparePkgVersions(argv[2], argv[3], &satisfies);
	TclFormatInt(buf, satisfies);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else {

	Tcl_AppendResult(interp, "bad option \"", argv[1],
		"\": should be forget, ifneeded, names, ",
		"provide, require, unknown, vcompare, ",
		"versions, or vsatisfies", (char *) NULL);
	return TCL_ERROR;

    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







|




>
>
>




>
>
>











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















|


|
|

>
>
>
>
>
>
>
>
>

<
|





|
<

|
<
|


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







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481

482
483
484
485
486
487
488

489
490

491
492
493
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574

575
576
577
578
579

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

646
647
648
649

650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692





693
694
695
696
697
698
699
700
701


702
703
704
705

706
707
708
709
710
711
712
713
714
715
716



717
718
719
720
721

722
723
724
725
726
727
728
729
730
731
732
733

734
735
736

737
738
739
740
741
742
743
744
745
746
747

748
749
750


751

752
753
754
755
756
757
758
759
	if (version != NULL) {
	    Tcl_AppendResult(interp, " ", version, (char *) NULL);
	}
	return NULL;
    }

    /*
     * At this point we know that the package is present.  Make sure that the
     * provided version meets the current requirement.
     */

    if (version == NULL) {
        if (clientDataPtr) {
	    *clientDataPtr = pkgPtr->clientData;
	}
	return pkgPtr->version;
    }
    result = ComparePkgVersions(pkgPtr->version, version, &satisfies);
    if ((satisfies && !exact) || (result == 0)) {
	if (clientDataPtr) {
	    *clientDataPtr = pkgPtr->clientData;
	}
	return pkgPtr->version;
    }
    Tcl_AppendResult(interp, "version conflict for package \"",
	    name, "\": have ", pkgPtr->version, ", need ", version,
	    (char *) NULL);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PkgPresent / Tcl_PkgPresentEx --
 *
 *	Checks to see whether the specified package is present. If it
 *	is not then no additional action is taken.
 *
 * Results:
 *	If successful, returns the version string for the currently
 *	provided version of the package, which may be different from
 *	the "version" argument.  If the caller's requirements
 *	cannot be met (e.g. the version requested conflicts with
 *	a currently provided version), NULL is returned and an error
 *	message is left in interp->result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_PkgPresent(interp, name, version, exact)
    Tcl_Interp *interp;		/* Interpreter in which package is now
				 * available. */
    char *name;			/* Name of desired package. */
    char *version;		/* Version string for desired version;
				 * NULL means use the latest version
				 * available. */
    int exact;			/* Non-zero means that only the particular
				 * version given is acceptable. Zero means
				 * use the latest compatible version. */
{
    return Tcl_PkgPresentEx(interp, name, version, exact, (ClientData *) NULL);
}

char *
Tcl_PkgPresentEx(interp, name, version, exact, clientDataPtr)
    Tcl_Interp *interp;		/* Interpreter in which package is now
				 * available. */
    char *name;			/* Name of desired package. */
    char *version;		/* Version string for desired version;
				 * NULL means use the latest version
				 * available. */
    int exact;			/* Non-zero means that only the particular
				 * version given is acceptable. Zero means
				 * use the latest compatible version. */
    ClientData *clientDataPtr;	/* Used to return the client data for this
				 * package. If it is NULL then the client
				 * data is not returned. This is unchanged
				 * if this call fails for any reason. */
{
    Interp *iPtr = (Interp *) interp;
    Tcl_HashEntry *hPtr;
    Package *pkgPtr;
    int satisfies, result;

    /*
     * If an attempt is being made to load this into a standalone executable
     * on a platform where backlinking is not supported then this must be
     * a shared version of Tcl (Otherwise the load would have failed).
     * Detect this situation by checking that this library has been correctly
     * initialised. If it has not been then return immediately as nothing will
     * work.
     */
    
    if (!tclEmptyStringRep) {
        Tcl_AppendResult(interp, "Cannot load package \"", name, 
                "\" in standalone executable: This package is not ",
                "compiled with stub support", NULL);
        return NULL;
    }

    hPtr = Tcl_FindHashEntry(&iPtr->packageTable, name);
    if (hPtr) {
	pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
	if (pkgPtr->version != NULL) {
	    
	    /*
	     * At this point we know that the package is present.  Make sure
	     * that the provided version meets the current requirement.
	     */

	    if (version == NULL) {
		if (clientDataPtr) {
		    *clientDataPtr = pkgPtr->clientData;
		}
		
		return pkgPtr->version;
	    }
	    result = ComparePkgVersions(pkgPtr->version, version, &satisfies);
	    if ((satisfies && !exact) || (result == 0)) {
		if (clientDataPtr) {
		    *clientDataPtr = pkgPtr->clientData;
		}
    
		return pkgPtr->version;
	    }
	    Tcl_AppendResult(interp, "version conflict for package \"",
			     name, "\": have ", pkgPtr->version,
			     ", need ", version, (char *) NULL);
	    return NULL;
	}
    }

    if (version != NULL) {
	Tcl_AppendResult(interp, "package ", name, " ", version,
			 " is not present", (char *) NULL);
    } else {
	Tcl_AppendResult(interp, "package ", name, " is not present",
			 (char *) NULL);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PackageObjCmd --
 *
 *	This procedure is invoked to process the "package" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_PackageObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    static char *pkgOptions[] = {
	"forget", "ifneeded", "names", "present", "provide", "require",
	"unknown", "vcompare", "versions", "vsatisfies", (char *) NULL
    };
    enum pkgOptions {
	PKG_FORGET, PKG_IFNEEDED, PKG_NAMES, PKG_PRESENT,
	PKG_PROVIDE, PKG_REQUIRE, PKG_UNKNOWN, PKG_VCOMPARE,
	PKG_VERSIONS, PKG_VSATISFIES
    };
    Interp *iPtr = (Interp *) interp;

    int optionIndex, exact, i, satisfies;
    PkgAvail *availPtr, *prevPtr;
    Package *pkgPtr;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    Tcl_HashTable *tablePtr;
    char *version, *argv2, *argv3, *argv4;


    if (objc < 2) {

        Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }


    if (Tcl_GetIndexFromObj(interp, objv[1], pkgOptions, "option", 0,
	    &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum pkgOptions) optionIndex) {
	case PKG_FORGET: {
	    char *keyString;
	    for (i = 2; i < objc; i++) {
		keyString = Tcl_GetString(objv[i]);
		hPtr = Tcl_FindHashEntry(&iPtr->packageTable, keyString);
		if (hPtr == NULL) {
		    return TCL_OK;
		}
		pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
		Tcl_DeleteHashEntry(hPtr);
		if (pkgPtr->version != NULL) {
		    ckfree(pkgPtr->version);
		}
		while (pkgPtr->availPtr != NULL) {
		    availPtr = pkgPtr->availPtr;
		    pkgPtr->availPtr = availPtr->nextPtr;
		    ckfree(availPtr->version);
		    Tcl_EventuallyFree((ClientData)availPtr->script, TCL_DYNAMIC);
		    ckfree((char *) availPtr);
		}
		ckfree((char *) pkgPtr);
	    }
	    break;
	}
	case PKG_IFNEEDED: {
	    int length;
	    if ((objc != 4) && (objc != 5)) {

		Tcl_WrongNumArgs(interp, 2, objv, "package version ?script?");
		return TCL_ERROR;
	    }
	    argv3 = Tcl_GetString(objv[3]);
	    if (CheckVersion(interp, argv3) != TCL_OK) {
		return TCL_ERROR;
	    }
	    argv2 = Tcl_GetString(objv[2]);
	    if (objc == 4) {
		hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2);
		if (hPtr == NULL) {
		    return TCL_OK;
		}
		pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
	    } else {
		pkgPtr = FindPackage(interp, argv2);
	    }
	    argv3 = Tcl_GetStringFromObj(objv[3], &length);
	    for (availPtr = pkgPtr->availPtr, prevPtr = NULL; availPtr != NULL;
		 prevPtr = availPtr, availPtr = availPtr->nextPtr) {
		if (ComparePkgVersions(availPtr->version, argv3, (int *) NULL)
			== 0) {
		    if (objc == 4) {
			Tcl_SetResult(interp, availPtr->script, TCL_VOLATILE);
			return TCL_OK;
		    }
		    Tcl_EventuallyFree((ClientData)availPtr->script, TCL_DYNAMIC);
		    break;
		}
	    }
	    if (objc == 4) {
		return TCL_OK;
	    }
	    if (availPtr == NULL) {
		availPtr = (PkgAvail *) ckalloc(sizeof(PkgAvail));
		availPtr->version = ckalloc((unsigned) (length + 1));
		strcpy(availPtr->version, argv3);
		if (prevPtr == NULL) {
		    availPtr->nextPtr = pkgPtr->availPtr;
		    pkgPtr->availPtr = availPtr;
		} else {
		    availPtr->nextPtr = prevPtr->nextPtr;
		    prevPtr->nextPtr = availPtr;
		}
	    }
	    argv4 = Tcl_GetStringFromObj(objv[4], &length);
	    availPtr->script = ckalloc((unsigned) (length + 1));
	    strcpy(availPtr->script, argv4);

	    break;
	}
	case PKG_NAMES: {
	    if (objc != 2) {
		Tcl_WrongNumArgs(interp, 2, objv, NULL);

		return TCL_ERROR;
	    }
	    tablePtr = &iPtr->packageTable;
	    for (hPtr = Tcl_FirstHashEntry(tablePtr, &search); hPtr != NULL;
		 hPtr = Tcl_NextHashEntry(&search)) {
		pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
		if ((pkgPtr->version != NULL) || (pkgPtr->availPtr != NULL)) {
		    Tcl_AppendElement(interp, Tcl_GetHashKey(tablePtr, hPtr));
		}
	    }
	    break;
	}
	case PKG_PRESENT: {
	    if (objc < 3) {
		presentSyntax:
		Tcl_WrongNumArgs(interp, 2, objv, "?-exact? package ?version?");
		return TCL_ERROR;
	    }
	    argv2 = Tcl_GetString(objv[2]);
	    if ((argv2[0] == '-') && (strcmp(argv2, "-exact") == 0)) {
		exact = 1;
	    } else {
		exact = 0;
	    }
	    version = NULL;
	    if (objc == (4 + exact)) {
		version =  Tcl_GetString(objv[3 + exact]);
		if (CheckVersion(interp, version) != TCL_OK) {
		    return TCL_ERROR;
		}
	    } else if ((objc != 3) || exact) {
		goto presentSyntax;
	    }
	    if (exact) {
		argv3 =  Tcl_GetString(objv[3]);
		version = Tcl_PkgPresent(interp, argv3, version, exact);
	    } else {
		version = Tcl_PkgPresent(interp, argv2, version, exact);
	    }
	    if (version == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetResult(interp, version, TCL_VOLATILE);
	    break;
	}
	case PKG_PROVIDE: {
	    if ((objc != 3) && (objc != 4)) {
		Tcl_WrongNumArgs(interp, 2, objv, "package ?version?");
		return TCL_ERROR;
	    }
	    argv2 = Tcl_GetString(objv[2]);
	    if (objc == 3) {
		hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2);
		if (hPtr != NULL) {
		    pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
		    if (pkgPtr->version != NULL) {
			Tcl_SetResult(interp, pkgPtr->version, TCL_VOLATILE);
		    }
		}
		return TCL_OK;
	    }
	    argv3 = Tcl_GetString(objv[3]);
	    if (CheckVersion(interp, argv3) != TCL_OK) {
		return TCL_ERROR;
	    }
	    return Tcl_PkgProvide(interp, argv2, argv3);

	}
	case PKG_REQUIRE: {
	    if (objc < 3) {
		requireSyntax:

		Tcl_WrongNumArgs(interp, 2, objv, "?-exact? package ?version?");
		return TCL_ERROR;
	    }
	    argv2 = Tcl_GetString(objv[2]);
	    if ((argv2[0] == '-') && (strcmp(argv2, "-exact") == 0)) {
		exact = 1;
	    } else {
		exact = 0;
	    }
	    version = NULL;
	    if (objc == (4 + exact)) {
		version =  Tcl_GetString(objv[3 + exact]);
		if (CheckVersion(interp, version) != TCL_OK) {
		    return TCL_ERROR;
		}
	    } else if ((objc != 3) || exact) {
		goto requireSyntax;
	    }
	    if (exact) {
		argv3 =  Tcl_GetString(objv[3]);
		version = Tcl_PkgRequire(interp, argv3, version, exact);
	    } else {
		version = Tcl_PkgRequire(interp, argv2, version, exact);
	    }
	    if (version == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetResult(interp, version, TCL_VOLATILE);
	    break;
	}
	case PKG_UNKNOWN: {
	    int length;
	    if (objc == 2) {
		if (iPtr->packageUnknown != NULL) {
		    Tcl_SetResult(interp, iPtr->packageUnknown, TCL_VOLATILE);
		}
	    } else if (objc == 3) {
		if (iPtr->packageUnknown != NULL) {
		    ckfree(iPtr->packageUnknown);
		}
		argv2 = Tcl_GetStringFromObj(objv[2], &length);
		if (argv2[0] == 0) {
		    iPtr->packageUnknown = NULL;





		} else {
		    iPtr->packageUnknown = (char *) ckalloc((unsigned)
			    (length + 1));
		    strcpy(iPtr->packageUnknown, argv2);
		}
	    } else {
		Tcl_WrongNumArgs(interp, 2, objv, "?command?");
		return TCL_ERROR;
	    }


	    break;
	}
	case PKG_VCOMPARE: {
	    if (objc != 4) {

		Tcl_WrongNumArgs(interp, 2, objv, "version1 version2");
		return TCL_ERROR;
	    }
	    argv3 = Tcl_GetString(objv[3]);
	    argv2 = Tcl_GetString(objv[2]);
	    if ((CheckVersion(interp, argv2) != TCL_OK)
		    || (CheckVersion(interp, argv3) != TCL_OK)) {
		return TCL_ERROR;
	    }
	    Tcl_SetIntObj(Tcl_GetObjResult(interp),
		    ComparePkgVersions(argv2, argv3, (int *) NULL));



	    break;
	}
	case PKG_VERSIONS: {
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "package");

		return TCL_ERROR;
	    }
	    argv2 = Tcl_GetString(objv[2]);
	    hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2);
	    if (hPtr != NULL) {
		pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
		for (availPtr = pkgPtr->availPtr; availPtr != NULL;
		     availPtr = availPtr->nextPtr) {
		    Tcl_AppendElement(interp, availPtr->version);
		}
	    }
	    break;

	}
	case PKG_VSATISFIES: {
	    if (objc != 4) {

		Tcl_WrongNumArgs(interp, 2, objv, "version1 version2");
		return TCL_ERROR;
	    }
	    argv3 = Tcl_GetString(objv[3]);
	    argv2 = Tcl_GetString(objv[2]);
	    if ((CheckVersion(interp, argv2) != TCL_OK)
		    || (CheckVersion(interp, argv3) != TCL_OK)) {
		return TCL_ERROR;
	    }
	    ComparePkgVersions(argv2, argv3, &satisfies);
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), satisfies);

	    break;
	}
	default: {


	    panic("Tcl_PackageObjCmd: bad option index to pkgOptions");

	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
543
544
545
546
547
548
549

550
551
552
553
554
555
556
    Package *pkgPtr;

    hPtr = Tcl_CreateHashEntry(&iPtr->packageTable, name, &new);
    if (new) {
	pkgPtr = (Package *) ckalloc(sizeof(Package));
	pkgPtr->version = NULL;
	pkgPtr->availPtr = NULL;

	Tcl_SetHashValue(hPtr, pkgPtr);
    } else {
	pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
    }
    return pkgPtr;
}








>







784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
    Package *pkgPtr;

    hPtr = Tcl_CreateHashEntry(&iPtr->packageTable, name, &new);
    if (new) {
	pkgPtr = (Package *) ckalloc(sizeof(Package));
	pkgPtr->version = NULL;
	pkgPtr->availPtr = NULL;
	pkgPtr->clientData = NULL;
	Tcl_SetHashValue(hPtr, pkgPtr);
    } else {
	pkgPtr = (Package *) Tcl_GetHashValue(hPtr);
    }
    return pkgPtr;
}

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
 *
 *	This procedure checks to see whether a version number has
 *	valid syntax.
 *
 * Results:
 *	If string is a properly formed version number the TCL_OK
 *	is returned.  Otherwise TCL_ERROR is returned and an error
 *	message is left in interp->result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
CheckVersion(interp, string)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* Supposedly a version number, which is
				 * groups of decimal digits separated
				 * by dots. */
{
    char *p = string;

    if (!isdigit(UCHAR(*p))) {
	goto error;
    }
    for (p++; *p != 0; p++) {
	if (!isdigit(UCHAR(*p)) && (*p != '.')) {
	    goto error;
	}
    }
    if (p[-1] != '.') {
	return TCL_OK;
    }








|
















|



|







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
 *
 *	This procedure checks to see whether a version number has
 *	valid syntax.
 *
 * Results:
 *	If string is a properly formed version number the TCL_OK
 *	is returned.  Otherwise TCL_ERROR is returned and an error
 *	message is left in the interp's result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
CheckVersion(interp, string)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* Supposedly a version number, which is
				 * groups of decimal digits separated
				 * by dots. */
{
    char *p = string;

    if (!isdigit(UCHAR(*p))) {	/* INTL: digit */
	goto error;
    }
    for (p++; *p != 0; p++) {
	if (!isdigit(UCHAR(*p)) && (*p != '.')) { /* INTL: digit */
	    goto error;
	}
    }
    if (p[-1] != '.') {
	return TCL_OK;
    }

Added generic/tclPlatDecls.h.





































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * tclPlatDecls.h --
 *
 *	Declarations of platform specific Tcl APIs.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * All rights reserved.
 *
 * RCS: @(#) $Id: tclPlatDecls.h,v 1.3.2.5 1999/04/01 21:58:18 stanton Exp $
 */

#ifndef _TCLPLATDECLS
#define _TCLPLATDECLS

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

/*
 * Exported function declarations:
 */

#ifdef __WIN32__
/* 0 */
EXTERN TCHAR *		Tcl_WinUtfToTChar _ANSI_ARGS_((CONST char * str, 
				int len, Tcl_DString * dsPtr));
/* 1 */
EXTERN char *		Tcl_WinTCharToUtf _ANSI_ARGS_((CONST TCHAR * str, 
				int len, Tcl_DString * dsPtr));
#endif /* __WIN32__ */
#ifdef MAC_TCL
/* 0 */
EXTERN void		Tcl_MacSetEventProc _ANSI_ARGS_((
				Tcl_MacConvertEventPtr procPtr));
/* 1 */
EXTERN char *		Tcl_MacConvertTextResource _ANSI_ARGS_((
				Handle resource));
/* 2 */
EXTERN int		Tcl_MacEvalResource _ANSI_ARGS_((Tcl_Interp * interp, 
				char * resourceName, int resourceNumber, 
				char * fileName));
/* 3 */
EXTERN Handle		Tcl_MacFindResource _ANSI_ARGS_((Tcl_Interp * interp, 
				long resourceType, char * resourceName, 
				int resourceNumber, char * resFileRef, 
				int * releaseIt));
/* 4 */
EXTERN int		Tcl_GetOSTypeFromObj _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj * objPtr, 
				OSType * osTypePtr));
/* 5 */
EXTERN void		Tcl_SetOSTypeObj _ANSI_ARGS_((Tcl_Obj * objPtr, 
				OSType osType));
/* 6 */
EXTERN Tcl_Obj *	Tcl_NewOSTypeObj _ANSI_ARGS_((OSType osType));
/* 7 */
EXTERN int		strncasecmp _ANSI_ARGS_((CONST char * s1, 
				CONST char * s2, size_t n));
/* 8 */
EXTERN int		strcasecmp _ANSI_ARGS_((CONST char * s1, 
				CONST char * s2));
#endif /* MAC_TCL */

typedef struct TclPlatStubs {
    int magic;
    struct TclPlatStubHooks *hooks;

#ifdef __WIN32__
    TCHAR * (*tcl_WinUtfToTChar) _ANSI_ARGS_((CONST char * str, int len, Tcl_DString * dsPtr)); /* 0 */
    char * (*tcl_WinTCharToUtf) _ANSI_ARGS_((CONST TCHAR * str, int len, Tcl_DString * dsPtr)); /* 1 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
    void (*tcl_MacSetEventProc) _ANSI_ARGS_((Tcl_MacConvertEventPtr procPtr)); /* 0 */
    char * (*tcl_MacConvertTextResource) _ANSI_ARGS_((Handle resource)); /* 1 */
    int (*tcl_MacEvalResource) _ANSI_ARGS_((Tcl_Interp * interp, char * resourceName, int resourceNumber, char * fileName)); /* 2 */
    Handle (*tcl_MacFindResource) _ANSI_ARGS_((Tcl_Interp * interp, long resourceType, char * resourceName, int resourceNumber, char * resFileRef, int * releaseIt)); /* 3 */
    int (*tcl_GetOSTypeFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, OSType * osTypePtr)); /* 4 */
    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:
 */

#ifdef __WIN32__
#ifndef Tcl_WinUtfToTChar
#define Tcl_WinUtfToTChar \
	(tclPlatStubsPtr->tcl_WinUtfToTChar) /* 0 */
#endif
#ifndef Tcl_WinTCharToUtf
#define Tcl_WinTCharToUtf \
	(tclPlatStubsPtr->tcl_WinTCharToUtf) /* 1 */
#endif
#endif /* __WIN32__ */
#ifdef MAC_TCL
#ifndef Tcl_MacSetEventProc
#define Tcl_MacSetEventProc \
	(tclPlatStubsPtr->tcl_MacSetEventProc) /* 0 */
#endif
#ifndef Tcl_MacConvertTextResource
#define Tcl_MacConvertTextResource \
	(tclPlatStubsPtr->tcl_MacConvertTextResource) /* 1 */
#endif
#ifndef Tcl_MacEvalResource
#define Tcl_MacEvalResource \
	(tclPlatStubsPtr->tcl_MacEvalResource) /* 2 */
#endif
#ifndef Tcl_MacFindResource
#define Tcl_MacFindResource \
	(tclPlatStubsPtr->tcl_MacFindResource) /* 3 */
#endif
#ifndef Tcl_GetOSTypeFromObj
#define Tcl_GetOSTypeFromObj \
	(tclPlatStubsPtr->tcl_GetOSTypeFromObj) /* 4 */
#endif
#ifndef Tcl_SetOSTypeObj
#define Tcl_SetOSTypeObj \
	(tclPlatStubsPtr->tcl_SetOSTypeObj) /* 5 */
#endif
#ifndef Tcl_NewOSTypeObj
#define Tcl_NewOSTypeObj \
	(tclPlatStubsPtr->tcl_NewOSTypeObj) /* 6 */
#endif
#ifndef strncasecmp
#define strncasecmp \
	(tclPlatStubsPtr->strncasecmp) /* 7 */
#endif
#ifndef strcasecmp
#define strcasecmp \
	(tclPlatStubsPtr->strcasecmp) /* 8 */
#endif
#endif /* MAC_TCL */

#endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */

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

#endif /* _TCLPLATDECLS */


Changes to generic/tclPort.h.

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
/*
 * tclPort.h --
 *
 *	This header file handles porting issues that occur because
 *	of differences between systems.  It reads in platform specific
 *	portability files.
 *
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclPort.h 1.15 96/02/07 17:24:21
 */

#ifndef _TCLPORT
#define _TCLPORT

#if defined(__WIN32__) || defined(_WIN32)
#   include "../win/tclWinPort.h"
#else
#   if defined(MAC_TCL)
#	include "tclMacPort.h"
#    else
#	include "../unix/tclUnixPort.h"
#    endif












|





|







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
/*
 * tclPort.h --
 *
 *	This header file handles porting issues that occur because
 *	of differences between systems.  It reads in platform specific
 *	portability files.
 *
 * Copyright (c) 1994-1995 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: tclPort.h,v 1.1.2.2 1998/09/24 23:59:01 stanton Exp $
 */

#ifndef _TCLPORT
#define _TCLPORT

#if defined(__WIN32__)
#   include "../win/tclWinPort.h"
#else
#   if defined(MAC_TCL)
#	include "tclMacPort.h"
#    else
#	include "../unix/tclUnixPort.h"
#    endif

Changes to generic/tclPosixStr.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 
 * tclPosixStr.c --
 *
 *	This file contains procedures that generate strings
 *	corresponding to various POSIX-related codes, such
 *	as errno and signals.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclPosixStr.c 1.33 97/10/08 12:40:12
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 *----------------------------------------------------------------------













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 
 * tclPosixStr.c --
 *
 *	This file contains procedures that generate strings
 *	corresponding to various POSIX-related codes, such
 *	as errno and signals.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1996 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: tclPosixStr.c,v 1.1.2.2 1998/09/24 23:59:01 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 *----------------------------------------------------------------------
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
#endif
#ifdef ENOTUNIQ
	case ENOTUNIQ: return "ENOTUNIQ";
#endif
#ifdef ENXIO
	case ENXIO: return "ENXIO";
#endif
#ifdef EOPNOTSUPP
	case EOPNOTSUPP: return "EOPNOTSUPP";
#endif
#ifdef EPERM
	case EPERM: return "EPERM";
#endif
#if defined(EPFNOSUPPORT) && (!defined(ENOLCK) || (ENOLCK != EPFNOSUPPORT))
	case EPFNOSUPPORT: return "EPFNOSUPPORT";







|







332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
#endif
#ifdef ENOTUNIQ
	case ENOTUNIQ: return "ENOTUNIQ";
#endif
#ifdef ENXIO
	case ENXIO: return "ENXIO";
#endif
#if defined(EOPNOTSUPP) &&  (!defined(ENOTSUP) || (ENOTSUP != EOPNOTSUPP))
	case EOPNOTSUPP: return "EOPNOTSUPP";
#endif
#ifdef EPERM
	case EPERM: return "EPERM";
#endif
#if defined(EPFNOSUPPORT) && (!defined(ENOLCK) || (ENOLCK != EPFNOSUPPORT))
	case EPFNOSUPPORT: return "EPFNOSUPPORT";
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
#endif
#ifdef ENOTUNIQ
	case ENOTUNIQ: return "name not unique on network";
#endif
#ifdef ENXIO
	case ENXIO: return "no such device or address";
#endif
#ifdef EOPNOTSUPP
	case EOPNOTSUPP: return "operation not supported on socket";
#endif
#ifdef EPERM
	case EPERM: return "not owner";
#endif
#if defined(EPFNOSUPPORT) && (!defined(ENOLCK) || (ENOLCK != EPFNOSUPPORT))
	case EPFNOSUPPORT: return "protocol family not supported";







|







779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
#endif
#ifdef ENOTUNIQ
	case ENOTUNIQ: return "name not unique on network";
#endif
#ifdef ENXIO
	case ENXIO: return "no such device or address";
#endif
#if defined(EOPNOTSUPP) &&  (!defined(ENOTSUP) || (ENOTSUP != EOPNOTSUPP))
	case EOPNOTSUPP: return "operation not supported on socket";
#endif
#ifdef EPERM
	case EPERM: return "not owner";
#endif
#if defined(EPFNOSUPPORT) && (!defined(ENOLCK) || (ENOLCK != EPFNOSUPPORT))
	case EPFNOSUPPORT: return "protocol family not supported";

Changes to generic/tclPreserve.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 
 * tclPreserve.c --
 *
 *	This file contains a collection of procedures that are used
 *	to make sure that widget records and other data structures
 *	aren't reallocated when there are nested procedures that
 *	depend on their existence.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclPreserve.c 1.18 96/08/05 13:15:08
 */

#include "tclInt.h"

/*
 * The following data structure is used to keep track of all the
 * Tcl_Preserve calls that are still in effect.  It grows as needed









|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 
 * tclPreserve.c --
 *
 *	This file contains a collection of procedures that are used
 *	to make sure that widget records and other data structures
 *	aren't reallocated when there are nested procedures that
 *	depend on their existence.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-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: tclPreserve.c,v 1.1.2.5 1998/12/12 01:37:02 lfb Exp $
 */

#include "tclInt.h"

/*
 * The following data structure is used to keep track of all the
 * Tcl_Preserve calls that are still in effect.  It grows as needed
36
37
38
39
40
41
42

























43
44
45
46
47
48
49

static Reference *refArray;	/* First in array of references. */
static int spaceAvl = 0;	/* Total number of structures available
				 * at *firstRefPtr. */
static int inUse = 0;		/* Count of structures currently in use
				 * in refArray. */
#define INITIAL_SIZE 2


























/*
 * Static routines in this file:
 */

static void	PreserveExitProc _ANSI_ARGS_((ClientData clientData));








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







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

static Reference *refArray;	/* First in array of references. */
static int spaceAvl = 0;	/* Total number of structures available
				 * at *firstRefPtr. */
static int inUse = 0;		/* Count of structures currently in use
				 * in refArray. */
#define INITIAL_SIZE 2
TCL_DECLARE_MUTEX(preserveMutex)/* To protect the above statics */

/*
 * The following data structure is used to keep track of whether an
 * arbitrary block of memory has been deleted.  This is used by the
 * TclHandle code to avoid the more time-expensive algorithm of
 * Tcl_Preserve().  This mechanism is mainly used when we have lots of
 * references to a few big, expensive objects that we don't want to live
 * any longer than necessary.
 */

typedef struct HandleStruct {
    VOID *ptr;			/* Pointer to the memory block being
				 * tracked.  This field will become NULL when
				 * the memory block is deleted.  This field
				 * must be the first in the structure. */
#ifdef TCL_MEM_DEBUG
    VOID *ptr2;			/* Backup copy of the abpve pointer used to
				 * ensure that the contents of the handle are
				 * not changed by anyone else. */
#endif
    int refCount;		/* Number of TclHandlePreserve() calls in
				 * effect on this handle. */
} HandleStruct;


/*
 * Static routines in this file:
 */

static void	PreserveExitProc _ANSI_ARGS_((ClientData clientData));

65
66
67
68
69
70
71

72
73
74
75
76
77

78
79
80
81
82
83
84
 */

	/* ARGSUSED */
static void
PreserveExitProc(clientData)
    ClientData clientData;		/* NULL -Unused. */
{

    if (spaceAvl != 0) {
        ckfree((char *) refArray);
        refArray = (Reference *) NULL;
        inUse = 0;
        spaceAvl = 0;
    }

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Preserve --
 *







>






>







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
 */

	/* ARGSUSED */
static void
PreserveExitProc(clientData)
    ClientData clientData;		/* NULL -Unused. */
{
    Tcl_MutexLock(&preserveMutex);
    if (spaceAvl != 0) {
        ckfree((char *) refArray);
        refArray = (Reference *) NULL;
        inUse = 0;
        spaceAvl = 0;
    }
    Tcl_MutexUnlock(&preserveMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Preserve --
 *
104
105
106
107
108
109
110

111
112
113

114
115
116
117
118
119
120
    int i;

    /*
     * See if there is already a reference for this pointer.  If so,
     * just increment its reference count.
     */


    for (i = 0, refPtr = refArray; i < inUse; i++, refPtr++) {
	if (refPtr->clientData == clientData) {
	    refPtr->refCount++;

	    return;
	}
    }

    /*
     * Make a reference array if it doesn't already exist, or make it
     * bigger if it is full.







>



>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    int i;

    /*
     * See if there is already a reference for this pointer.  If so,
     * just increment its reference count.
     */

    Tcl_MutexLock(&preserveMutex);
    for (i = 0, refPtr = refArray; i < inUse; i++, refPtr++) {
	if (refPtr->clientData == clientData) {
	    refPtr->refCount++;
	    Tcl_MutexUnlock(&preserveMutex);
	    return;
	}
    }

    /*
     * Make a reference array if it doesn't already exist, or make it
     * bigger if it is full.
146
147
148
149
150
151
152

153
154
155
156
157
158
159

    refPtr = &refArray[inUse];
    refPtr->clientData = clientData;
    refPtr->refCount = 1;
    refPtr->mustFree = 0;
    refPtr->freeProc = TCL_STATIC;
    inUse += 1;

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Release --
 *







>







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

    refPtr = &refArray[inUse];
    refPtr->clientData = clientData;
    refPtr->refCount = 1;
    refPtr->mustFree = 0;
    refPtr->freeProc = TCL_STATIC;
    inUse += 1;
    Tcl_MutexUnlock(&preserveMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Release --
 *
177
178
179
180
181
182
183

184
185
186
187
188
189
190
    ClientData clientData;	/* Pointer to malloc'ed block of memory. */
{
    Reference *refPtr;
    int mustFree;
    Tcl_FreeProc *freeProc;
    int i;


    for (i = 0, refPtr = refArray; i < inUse; i++, refPtr++) {
	if (refPtr->clientData != clientData) {
	    continue;
	}
	refPtr->refCount--;
	if (refPtr->refCount == 0) {








>







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
    ClientData clientData;	/* Pointer to malloc'ed block of memory. */
{
    Reference *refPtr;
    int mustFree;
    Tcl_FreeProc *freeProc;
    int i;

    Tcl_MutexLock(&preserveMutex);
    for (i = 0, refPtr = refArray; i < inUse; i++, refPtr++) {
	if (refPtr->clientData != clientData) {
	    continue;
	}
	refPtr->refCount--;
	if (refPtr->refCount == 0) {

202
203
204
205
206
207
208

209

210
211
212

213
214

215
216
217
218
219
220
221
		refArray[i] = refArray[inUse];
	    }
	    if (mustFree) {
		if ((freeProc == TCL_DYNAMIC) ||
                        (freeProc == (Tcl_FreeProc *) free)) {
		    ckfree((char *) clientData);
		} else {

		    (*freeProc)((char *) clientData);

		}
	    }
	}

	return;
    }


    /*
     * Reference not found.  This is a bug in the caller.
     */

    panic("Tcl_Release couldn't find reference for 0x%x", clientData);
}







>

>



>


>







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
		refArray[i] = refArray[inUse];
	    }
	    if (mustFree) {
		if ((freeProc == TCL_DYNAMIC) ||
                        (freeProc == (Tcl_FreeProc *) free)) {
		    ckfree((char *) clientData);
		} else {
		    Tcl_MutexUnlock(&preserveMutex);
		    (*freeProc)((char *) clientData);
		    return;
		}
	    }
	}
	Tcl_MutexUnlock(&preserveMutex);
	return;
    }
    Tcl_MutexUnlock(&preserveMutex);

    /*
     * Reference not found.  This is a bug in the caller.
     */

    panic("Tcl_Release couldn't find reference for 0x%x", clientData);
}
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















































































































































































    int i;

    /*
     * See if there is a reference for this pointer.  If so, set its
     * "mustFree" flag (the flag had better not be set already!).
     */


    for (i = 0, refPtr = refArray; i < inUse; i++, refPtr++) {
	if (refPtr->clientData != clientData) {
	    continue;
	}
	if (refPtr->mustFree) {
	    panic("Tcl_EventuallyFree called twice for 0x%x\n", clientData);
        }
        refPtr->mustFree = 1;
	refPtr->freeProc = freeProc;

        return;
    }


    /*
     * No reference for this block.  Free it now.
     */

    if ((freeProc == TCL_DYNAMIC)
	    || (freeProc == (Tcl_FreeProc *) free)) {
	ckfree((char *) clientData);
    } else {
	(*freeProc)((char *)clientData);
    }
}






















































































































































































>









>


>












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
    int i;

    /*
     * See if there is a reference for this pointer.  If so, set its
     * "mustFree" flag (the flag had better not be set already!).
     */

    Tcl_MutexLock(&preserveMutex);
    for (i = 0, refPtr = refArray; i < inUse; i++, refPtr++) {
	if (refPtr->clientData != clientData) {
	    continue;
	}
	if (refPtr->mustFree) {
	    panic("Tcl_EventuallyFree called twice for 0x%x\n", clientData);
        }
        refPtr->mustFree = 1;
	refPtr->freeProc = freeProc;
	Tcl_MutexUnlock(&preserveMutex);
        return;
    }
    Tcl_MutexUnlock(&preserveMutex);

    /*
     * No reference for this block.  Free it now.
     */

    if ((freeProc == TCL_DYNAMIC)
	    || (freeProc == (Tcl_FreeProc *) free)) {
	ckfree((char *) clientData);
    } else {
	(*freeProc)((char *)clientData);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * TclHandleCreate --
 *
 *	Allocate a handle that contains enough information to determine
 *	if an arbitrary malloc'd block has been deleted.  This is 
 *	used to avoid the more time-expensive algorithm of Tcl_Preserve().
 *
 * Results:
 *	The return value is a TclHandle that refers to the given malloc'd
 *	block.  Doubly dereferencing the returned handle will give
 *	back the pointer to the block, or will give NULL if the block has
 *	been deleted.
 *
 * Side effects:
 *	The caller must keep track of this handle (generally by storing
 *	it in a field in the malloc'd block) and call TclHandleFree()
 *	on this handle when the block is deleted.  Everything else that
 *	wishes to keep track of whether the malloc'd block has been deleted
 *	should use calls to TclHandlePreserve() and TclHandleRelease()
 *	on the associated handle.
 *
 *---------------------------------------------------------------------------
 */

TclHandle
TclHandleCreate(ptr)
    VOID *ptr;			/* Pointer to an arbitrary block of memory
				 * to be tracked for deletion.  Must not be
				 * NULL. */
{
    HandleStruct *handlePtr;

    handlePtr = (HandleStruct *) ckalloc(sizeof(HandleStruct));
    handlePtr->ptr = ptr;
#ifdef TCL_MEM_DEBUG
    handlePtr->ptr2 = ptr;
#endif
    handlePtr->refCount = 0;
    return (TclHandle) handlePtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclHandleFree --
 *
 *	Called when the arbitrary malloc'd block associated with the
 *	handle is being deleted.  Modifies the handle so that doubly
 *	dereferencing it will give NULL.  This informs any user of the
 *	handle that the block of memory formerly referenced by the
 *	handle has been freed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If nothing is referring to the handle, the handle will be reclaimed.
 *
 *---------------------------------------------------------------------------
 */

void
TclHandleFree(handle)
    TclHandle handle;		/* Previously created handle associated
				 * with a malloc'd block that is being
				 * deleted.  The handle is modified so that
				 * doubly dereferencing it will give NULL. */
{
    HandleStruct *handlePtr;

    handlePtr = (HandleStruct *) handle;
#ifdef TCL_MEM_DEBUG
    if (handlePtr->refCount == 0x61616161) {
	panic("using previously disposed TclHandle %x", handlePtr);
    }
    if (handlePtr->ptr2 != handlePtr->ptr) {
	panic("someone has changed the block referenced by the handle %x\nfrom %x to %x",
		handlePtr, handlePtr->ptr2, handlePtr->ptr);
    }
#endif
    handlePtr->ptr = NULL;
    if (handlePtr->refCount == 0) {
	ckfree((char *) handlePtr);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * TclHandlePreserve --
 *
 *	Declare an interest in the arbitrary malloc'd block associated
 *	with the handle.  
 *
 * Results:
 *	The return value is the handle argument, with its ref count
 *	incremented.
 *
 * Side effects:
 *	For each call to TclHandlePreserve(), there should be a matching
 *	call to TclHandleRelease() when the caller is no longer interested
 *	in the malloc'd block associated with the handle.
 *
 *---------------------------------------------------------------------------
 */

TclHandle
TclHandlePreserve(handle)
    TclHandle handle;		/* Declare an interest in the block of
				 * memory referenced by this handle. */
{
    HandleStruct *handlePtr;

    handlePtr = (HandleStruct *) handle;
#ifdef TCL_MEM_DEBUG
    if (handlePtr->refCount == 0x61616161) {
	panic("using previously disposed TclHandle %x", handlePtr);
    }
    if ((handlePtr->ptr != NULL)
	    && (handlePtr->ptr != handlePtr->ptr2)) {
	panic("someone has changed the block referenced by the handle %x\nfrom %x to %x",
		handlePtr, handlePtr->ptr2, handlePtr->ptr);
    }
#endif
    handlePtr->refCount++;

    return handle;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclHandleRelease --
 *
 *	This procedure is called to release an interest in the malloc'd
 *	block associated with the handle.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The ref count of the handle is decremented.  If the malloc'd block
 *	has been freed and if no one is using the handle any more, the
 *	handle will be reclaimed.
 *
 *---------------------------------------------------------------------------
 */
 
void
TclHandleRelease(handle)
    TclHandle handle;		/* Unregister interest in the block of
				 * memory referenced by this handle. */
{
    HandleStruct *handlePtr;

    handlePtr = (HandleStruct *) handle;
#ifdef TCL_MEM_DEBUG
    if (handlePtr->refCount == 0x61616161) {
	panic("using previously disposed TclHandle %x", handlePtr);
    }
    if ((handlePtr->ptr != NULL)
	    && (handlePtr->ptr != handlePtr->ptr2)) {
	panic("someone has changed the block referenced by the handle %x\nfrom %x to %x",
		handlePtr, handlePtr->ptr2, handlePtr->ptr);
    }
#endif
    handlePtr->refCount--;
    if ((handlePtr->refCount == 0) && (handlePtr->ptr == NULL)) {
	ckfree((char *) handlePtr);
    }
}
    

Changes to generic/tclProc.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
/* 
 * tclProc.c --
 *
 *	This file contains routines that implement Tcl procedures,
 *	including the "proc" and "uplevel" commands.
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclProc.c 1.116 97/10/29 18:33:24
 */

#include "tclInt.h"
#include "tclCompile.h"

/*
 * Forward references to procedures defined later in this file:
 */

static void	CleanupProc _ANSI_ARGS_((Proc *procPtr));
static  int	InterpProc _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));




static  void	ProcDeleteProc _ANSI_ARGS_((ClientData clientData));












/*
 *----------------------------------------------------------------------
 *
 * Tcl_ProcObjCmd --
 *
 *	This object-based procedure is invoked to process the "proc" Tcl 







|




|






|


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







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
/* 
 * tclProc.c --
 *
 *	This file contains routines that implement Tcl procedures,
 *	including the "proc" and "uplevel" commands.
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * Copyright (c) 1994-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: tclProc.c,v 1.1.2.8 1999/03/25 00:34:16 redman Exp $
 */

#include "tclInt.h"
#include "tclCompile.h"

/*
 * Prototypes for static functions in this file
 */

static void	ProcBodyDup _ANSI_ARGS_((Tcl_Obj *srcPtr, Tcl_Obj *dupPtr));
static void	ProcBodyFree _ANSI_ARGS_((Tcl_Obj *objPtr));
static int	ProcBodySetFromAny _ANSI_ARGS_((Tcl_Interp *interp,
		Tcl_Obj *objPtr));
static void	ProcBodyUpdateString _ANSI_ARGS_((Tcl_Obj *objPtr));
static  int	ProcessProcResultCode _ANSI_ARGS_((Tcl_Interp *interp,
		    char *procName, int nameLen, int returnCode));

/*
 * The ProcBodyObjType type
 */

Tcl_ObjType tclProcBodyType = {
    "procbody",			/* name for this type */
    ProcBodyFree,		/* FreeInternalRep procedure */
    ProcBodyDup,		/* DupInternalRep procedure */
    ProcBodyUpdateString,	/* UpdateString procedure */
    ProcBodySetFromAny		/* SetFromAny procedure */
};

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ProcObjCmd --
 *
 *	This object-based procedure is invoked to process the "proc" Tcl 
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
Tcl_ProcObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register Interp *iPtr = (Interp *) interp;
    register Proc *procPtr;
    char *fullName, *procName, *args, *bytes, *p;
    char **argArray = NULL;
    Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
    Tcl_Obj *defPtr, *bodyPtr;
    Tcl_Command cmd;
    Tcl_DString ds;
    int numArgs, length, result, i;
    register CompiledLocal *localPtr;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 1, objv, "name args body");
	return TCL_ERROR;
    }

    /*
     * Determine the namespace where the procedure should reside. Unless
     * the command name includes namespace qualifiers, this will be the
     * current namespace.
     */
    
    fullName = Tcl_GetStringFromObj(objv[1], (int *) NULL);
    result = TclGetNamespaceForQualName(interp, fullName,
	    (Namespace *) NULL, TCL_LEAVE_ERR_MSG,
            &nsPtr, &altNsPtr, &cxtNsPtr, &procName);
    if (result != TCL_OK) {
        return result;
    }
    if (nsPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"can't create procedure \"", fullName,
		"\": unknown namespace", (char *) NULL);
        return TCL_ERROR;
    }
    if (procName == NULL) {







|
|
<

<


<
<












|
|
<
|
<
<
|







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
Tcl_ProcObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register Interp *iPtr = (Interp *) interp;
    Proc *procPtr;
    char *fullName, *procName;

    Namespace *nsPtr, *altNsPtr, *cxtNsPtr;

    Tcl_Command cmd;
    Tcl_DString ds;



    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 1, objv, "name args body");
	return TCL_ERROR;
    }

    /*
     * Determine the namespace where the procedure should reside. Unless
     * the command name includes namespace qualifiers, this will be the
     * current namespace.
     */
    
    fullName = TclGetString(objv[1]);
    TclGetNamespaceForQualName(interp, fullName, (Namespace *) NULL,

	    0, &nsPtr, &altNsPtr, &cxtNsPtr, &procName);



    if (nsPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"can't create procedure \"", fullName,
		"\": unknown namespace", (char *) NULL);
        return TCL_ERROR;
    }
    if (procName == NULL) {
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275


























































































































































































































































































276
277
278
279



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

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
		"can't create procedure \"", procName,
		"\" in non-global namespace with name starting with \":\"",
	        (char *) NULL);
        return TCL_ERROR;
    }

    /*
     * If the procedure's body object is shared because its string value is
     * identical to, e.g., the body of another procedure, we must create a
     * private copy for this procedure to use. Such sharing of procedure
     * bodies is rare but can cause problems. A procedure body is compiled
     * in a context that includes the number of compiler-allocated "slots"
     * for local variables. Each formal parameter is given a local variable
     * slot (the "procPtr->numCompiledLocals = numArgs" assignment
     * below). This means that the same code can not be shared by two
     * procedures that have a different number of arguments, even if their
     * bodies are identical. Note that we don't use Tcl_DuplicateObj since
     * we would not want any bytecode internal representation.
     */

    bodyPtr = objv[3];
    if (Tcl_IsShared(bodyPtr)) {
	bytes = Tcl_GetStringFromObj(bodyPtr, &length);
	bodyPtr = Tcl_NewStringObj(bytes, length);
    }

    /*
     * Create and initialize a Proc structure for the procedure. Note that
     * we initialize its cmdPtr field below after we've created the command
     * for the procedure. We increment the ref count of the procedure's
     * body object since there will be a reference to it in the Proc
     * structure.
     */
    
    Tcl_IncrRefCount(bodyPtr);

    procPtr = (Proc *) ckalloc(sizeof(Proc));
    procPtr->iPtr = iPtr;
    procPtr->refCount = 1;
    procPtr->bodyPtr = bodyPtr;
    procPtr->numArgs  = 0;	/* actual argument count is set below. */
    procPtr->numCompiledLocals = 0;
    procPtr->firstLocalPtr = NULL;
    procPtr->lastLocalPtr = NULL;
    
    /*
     * Break up the argument list into argument specifiers, then process
     * each argument specifier.
     * THIS FAILS IF THE ARG LIST OBJECT'S STRING REP CONTAINS NULLS.
     */

    args = Tcl_GetStringFromObj(objv[2], &length);
    result = Tcl_SplitList(interp, args, &numArgs, &argArray);
    if (result != TCL_OK) {
	goto procError;
    }
    
    procPtr->numArgs = numArgs;
    procPtr->numCompiledLocals = numArgs;
    for (i = 0;  i < numArgs;  i++) {
	int fieldCount, nameLength, valueLength;
	char **fieldValues;

	/*
	 * Now divide the specifier up into name and default.
	 */

	result = Tcl_SplitList(interp, argArray[i], &fieldCount,
		&fieldValues);
	if (result != TCL_OK) {
	    goto procError;
	}
	if (fieldCount > 2) {
	    ckfree((char *) fieldValues);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "too many fields in argument specifier \"",
		    argArray[i], "\"", (char *) NULL);
	    goto procError;
	}
	if ((fieldCount == 0) || (*fieldValues[0] == 0)) {
	    ckfree((char *) fieldValues);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "procedure \"", fullName,
		    "\" has argument with no name", (char *) NULL);
	    goto procError;
	}
	
	nameLength = strlen(fieldValues[0]);
	if (fieldCount == 2) {
	    valueLength = strlen(fieldValues[1]);
	} else {
	    valueLength = 0;
	}

	/*
	 * Check that the formal parameter name is a scalar.
	 */

	p = fieldValues[0];
	while (*p != '\0') {
	    if (*p == '(') {
		char *q = p;
		do {
		    q++;
		} while (*q != '\0');
		q--;
		if (*q == ')') { /* we have an array element */
		    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		            "procedure \"", fullName,
		            "\" has formal parameter \"", fieldValues[0],
			    "\" that is an array element",
			    (char *) NULL);
		    ckfree((char *) fieldValues);
		    goto procError;
		}
	    }
	    p++;
	}

	/*
	 * Allocate an entry in the runtime procedure frame's array of local
	 * variables for the argument. 
	 */

	localPtr = (CompiledLocal *) ckalloc((unsigned) 
	        (sizeof(CompiledLocal) - sizeof(localPtr->name)
		+ nameLength+1));
	if (procPtr->firstLocalPtr == NULL) {
	    procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;
	} else {
	    procPtr->lastLocalPtr->nextPtr = localPtr;
	    procPtr->lastLocalPtr = localPtr;
	}
	localPtr->nextPtr = NULL;
	localPtr->nameLength = nameLength;
	localPtr->frameIndex = i;
	localPtr->isArg  = 1;
	localPtr->isTemp = 0;
	localPtr->flags = VAR_SCALAR;
	if (fieldCount == 2) {
	    localPtr->defValuePtr =
		    Tcl_NewStringObj(fieldValues[1], valueLength);
	    Tcl_IncrRefCount(localPtr->defValuePtr);
	} else {
	    localPtr->defValuePtr = NULL;
	}
	strcpy(localPtr->name, fieldValues[0]);
	
	ckfree((char *) fieldValues);
    }

    /*
     * Now create a command for the procedure. This will initially be in
     * the current namespace unless the procedure's name included namespace
     * qualifiers. To create the new command in the right namespace, we
     * generate a fully qualified name for it.
     */

    Tcl_DStringInit(&ds);
    if (nsPtr != iPtr->globalNsPtr) {
	Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
	Tcl_DStringAppend(&ds, "::", 2);
    }
    Tcl_DStringAppend(&ds, procName, -1);
    
    Tcl_CreateCommand(interp, Tcl_DStringValue(&ds), InterpProc,
	    (ClientData) procPtr, ProcDeleteProc);
    cmd = Tcl_CreateObjCommand(interp, Tcl_DStringValue(&ds),
	    TclObjInterpProc, (ClientData) procPtr, ProcDeleteProc);

    /*
     * Now initialize the new procedure's cmdPtr field. This will be used
     * later when the procedure is called to determine what namespace the
     * procedure will run in. This will be different than the current
     * namespace if the proc was renamed into a different namespace.
     */
    
    procPtr->cmdPtr = (Command *) cmd;
	


























































































































































































































































































    ckfree((char *) argArray);
    return TCL_OK;

    procError:



    Tcl_DecrRefCount(bodyPtr);
    while (procPtr->firstLocalPtr != NULL) {
	localPtr = procPtr->firstLocalPtr;
	procPtr->firstLocalPtr = localPtr->nextPtr;
	
	defPtr = localPtr->defValuePtr;
	if (defPtr != NULL) {
	    Tcl_DecrRefCount(defPtr);
	}
	
	ckfree((char *) localPtr);
    }
    ckfree((char *) procPtr);

    if (argArray != NULL) {
	ckfree((char *) argArray);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetFrame --
 *
 *	Given a description of a procedure frame, such as the first
 *	argument to an "uplevel" or "upvar" command, locate the
 *	call frame for the appropriate level of procedure.
 *
 * Results:
 *	The return value is -1 if an error occurred in finding the
 *	frame (in this case an error message is left in interp->result).
 *	1 is returned if string was either a number or a number preceded
 *	by "#" and it specified a valid frame.  0 is returned if string
 *	isn't one of the two things above (in this case, the lookup
 *	acts as if string were "1").  The variable pointed to by
 *	framePtrPtr is filled in with the address of the desired frame
 *	(unless an error occurs, in which case it isn't modified).
 *







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

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
















|
|

|









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



|
>
>
>
|
|
|
|

|
|
|
|

|
|
|
>
















|
|







105
106
107
108
109
110
111












112












113
114



















115


116




























































































117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
		"can't create procedure \"", procName,
		"\" in non-global namespace with name starting with \":\"",
	        (char *) NULL);
        return TCL_ERROR;
    }

    /*












     *  Create the data structure to represent the procedure.












     */
    if (TclCreateProc(interp, nsPtr, procName, objv[2], objv[3],



















        &procPtr) != TCL_OK) {


        return TCL_ERROR;




























































































    }

    /*
     * Now create a command for the procedure. This will initially be in
     * the current namespace unless the procedure's name included namespace
     * qualifiers. To create the new command in the right namespace, we
     * generate a fully qualified name for it.
     */

    Tcl_DStringInit(&ds);
    if (nsPtr != iPtr->globalNsPtr) {
	Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
	Tcl_DStringAppend(&ds, "::", 2);
    }
    Tcl_DStringAppend(&ds, procName, -1);
    
    Tcl_CreateCommand(interp, Tcl_DStringValue(&ds), TclProcInterpProc,
	    (ClientData) procPtr, TclProcDeleteProc);
    cmd = Tcl_CreateObjCommand(interp, Tcl_DStringValue(&ds),
	    TclObjInterpProc, (ClientData) procPtr, TclProcDeleteProc);

    /*
     * Now initialize the new procedure's cmdPtr field. This will be used
     * later when the procedure is called to determine what namespace the
     * procedure will run in. This will be different than the current
     * namespace if the proc was renamed into a different namespace.
     */
    
    procPtr->cmdPtr = (Command *) cmd;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclCreateProc --
 *
 *	Creates the data associated with a Tcl procedure definition.
 *	This procedure knows how to handle two types of body objects:
 *	strings and procbody. Strings are the traditional (and common) value
 *	for bodies, procbody are values created by extensions that have
 *	loaded a previously compiled script.
 *
 * Results:
 *	Returns TCL_OK on success, along with a pointer to a Tcl
 *	procedure definition in procPtrPtr.  This definition should
 *	be freed by calling TclCleanupProc() when it is no longer
 *	needed.  Returns TCL_ERROR if anything goes wrong.
 *
 * Side effects:
 *	If anything goes wrong, this procedure returns an error
 *	message in the interpreter.
 *
 *----------------------------------------------------------------------
 */
int
TclCreateProc(interp, nsPtr, procName, argsPtr, bodyPtr, procPtrPtr)
    Tcl_Interp *interp;         /* interpreter containing proc */
    Namespace *nsPtr;           /* namespace containing this proc */
    char *procName;             /* unqualified name of this proc */
    Tcl_Obj *argsPtr;           /* description of arguments */
    Tcl_Obj *bodyPtr;           /* command body */
    Proc **procPtrPtr;          /* returns:  pointer to proc data */
{
    Interp *iPtr = (Interp*)interp;
    char **argArray = NULL;

    register Proc *procPtr;
    int i, length, result, numArgs;
    char *args, *bytes, *p;
    register CompiledLocal *localPtr = NULL;
    Tcl_Obj *defPtr;
    int precompiled = 0;
    
    if (bodyPtr->typePtr == &tclProcBodyType) {
        /*
         * Because the body is a TclProProcBody, the actual body is already
         * compiled, and it is not shared with anyone else, so it's OK not to
         * unshare it (as a matter of fact, it is bad to unshare it, because
         * there may be no source code).
         *
         * We don't create and initialize a Proc structure for the procedure;
         * rather, we use what is in the body object. Note that
         * we initialize its cmdPtr field below after we've created the command
         * for the procedure. We increment the ref count of the Proc struct
         * since the command (soon to be created) will be holding a reference
         * to it.
         */
    
        procPtr = (Proc *) bodyPtr->internalRep.otherValuePtr;
        procPtr->iPtr = iPtr;
        procPtr->refCount++;
        precompiled = 1;
    } else {
        /*
         * If the procedure's body object is shared because its string value is
         * identical to, e.g., the body of another procedure, we must create a
         * private copy for this procedure to use. Such sharing of procedure
         * bodies is rare but can cause problems. A procedure body is compiled
         * in a context that includes the number of compiler-allocated "slots"
         * for local variables. Each formal parameter is given a local variable
         * slot (the "procPtr->numCompiledLocals = numArgs" assignment
         * below). This means that the same code can not be shared by two
         * procedures that have a different number of arguments, even if their
         * bodies are identical. Note that we don't use Tcl_DuplicateObj since
         * we would not want any bytecode internal representation.
         */

        if (Tcl_IsShared(bodyPtr)) {
            bytes = Tcl_GetStringFromObj(bodyPtr, &length);
            bodyPtr = Tcl_NewStringObj(bytes, length);
        }

        /*
         * Create and initialize a Proc structure for the procedure. Note that
         * we initialize its cmdPtr field below after we've created the command
         * for the procedure. We increment the ref count of the procedure's
         * body object since there will be a reference to it in the Proc
         * structure.
         */
    
        Tcl_IncrRefCount(bodyPtr);

        procPtr = (Proc *) ckalloc(sizeof(Proc));
        procPtr->iPtr = iPtr;
        procPtr->refCount = 1;
        procPtr->bodyPtr = bodyPtr;
        procPtr->numArgs  = 0;	/* actual argument count is set below. */
        procPtr->numCompiledLocals = 0;
        procPtr->firstLocalPtr = NULL;
        procPtr->lastLocalPtr = NULL;
    }
    
    /*
     * Break up the argument list into argument specifiers, then process
     * each argument specifier.
     * If the body is precompiled, processing is limited to checking that
     * the the parsed argument is consistent with the one stored in the
     * Proc.
     * THIS FAILS IF THE ARG LIST OBJECT'S STRING REP CONTAINS NULLS.
     */

    args = Tcl_GetStringFromObj(argsPtr, &length);
    result = Tcl_SplitList(interp, args, &numArgs, &argArray);
    if (result != TCL_OK) {
        goto procError;
    }

    if (precompiled) {
        if (numArgs > procPtr->numArgs) {
            char buf[128];
            sprintf(buf, "\": arg list contains %d entries, precompiled header expects %d",
                    numArgs, procPtr->numArgs);
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "procedure \"", procName,
                    buf, (char *) NULL);
            goto procError;
        }
        localPtr = procPtr->firstLocalPtr;
    } else {
        procPtr->numArgs = numArgs;
        procPtr->numCompiledLocals = numArgs;
    }
    for (i = 0;  i < numArgs;  i++) {
        int fieldCount, nameLength, valueLength;
        char **fieldValues;

        /*
         * Now divide the specifier up into name and default.
         */

        result = Tcl_SplitList(interp, argArray[i], &fieldCount,
                &fieldValues);
        if (result != TCL_OK) {
            goto procError;
        }
        if (fieldCount > 2) {
            ckfree((char *) fieldValues);
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "too many fields in argument specifier \"",
                    argArray[i], "\"", (char *) NULL);
            goto procError;
        }
        if ((fieldCount == 0) || (*fieldValues[0] == 0)) {
            ckfree((char *) fieldValues);
            Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                    "procedure \"", procName,
                    "\" has argument with no name", (char *) NULL);
            goto procError;
        }
	
        nameLength = strlen(fieldValues[0]);
        if (fieldCount == 2) {
            valueLength = strlen(fieldValues[1]);
        } else {
            valueLength = 0;
        }

        /*
         * Check that the formal parameter name is a scalar.
         */

        p = fieldValues[0];
        while (*p != '\0') {
            if (*p == '(') {
                char *q = p;
                do {
		    q++;
		} while (*q != '\0');
		q--;
		if (*q == ')') { /* we have an array element */
		    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		            "procedure \"", procName,
		            "\" has formal parameter \"", fieldValues[0],
			    "\" that is an array element",
			    (char *) NULL);
		    ckfree((char *) fieldValues);
		    goto procError;
		}
	    }
	    p++;
	}

        if (precompiled) {
            /*
             * compare the parsed argument with the stored one
             */

            if ((localPtr->nameLength != nameLength)
                    || (strcmp(localPtr->name, fieldValues[0]))
                    || (localPtr->frameIndex != i)
                    || (localPtr->flags != (VAR_SCALAR | VAR_ARGUMENT))
                    || ((localPtr->defValuePtr == NULL)
                            && (fieldCount == 2))
                    || ((localPtr->defValuePtr != NULL)
                            && (fieldCount != 2))) {
                char buf[128];
                sprintf(buf, "\": formal parameter %d is inconsistent with precompiled body",
                        i);
                Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                        "procedure \"", procName,
                        buf, (char *) NULL);
                ckfree((char *) fieldValues);
                goto procError;
            }

            /*
             * compare the default value if any
             */

            if (localPtr->defValuePtr != NULL) {
                int tmpLength;
                char *tmpPtr = Tcl_GetStringFromObj(localPtr->defValuePtr,
                        &tmpLength);
                if ((valueLength != tmpLength)
                        || (strncmp(fieldValues[1], tmpPtr,
                                (size_t) tmpLength))) {
                    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
                            "procedure \"", procName,
                            "\": formal parameter \"",
                            fieldValues[0],
                            "\" has default value inconsistent with precompiled body",
                            (char *) NULL);
                    ckfree((char *) fieldValues);
                    goto procError;
                }
            }

            localPtr = localPtr->nextPtr;
        } else {
            /*
             * Allocate an entry in the runtime procedure frame's array of
             * local variables for the argument. 
             */

            localPtr = (CompiledLocal *) ckalloc((unsigned) 
                    (sizeof(CompiledLocal) - sizeof(localPtr->name)
                            + nameLength+1));
            if (procPtr->firstLocalPtr == NULL) {
                procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;
            } else {
                procPtr->lastLocalPtr->nextPtr = localPtr;
                procPtr->lastLocalPtr = localPtr;
            }
            localPtr->nextPtr = NULL;
            localPtr->nameLength = nameLength;
            localPtr->frameIndex = i;
            localPtr->flags = VAR_SCALAR | VAR_ARGUMENT;
            localPtr->resolveInfo = NULL;
	
            if (fieldCount == 2) {
                localPtr->defValuePtr =
		    Tcl_NewStringObj(fieldValues[1], valueLength);
                Tcl_IncrRefCount(localPtr->defValuePtr);
            } else {
                localPtr->defValuePtr = NULL;
            }
            strcpy(localPtr->name, fieldValues[0]);
	}

        ckfree((char *) fieldValues);
    }

    /*
     * Now initialize the new procedure's cmdPtr field. This will be used
     * later when the procedure is called to determine what namespace the
     * procedure will run in. This will be different than the current
     * namespace if the proc was renamed into a different namespace.
     */
    
    *procPtrPtr = procPtr;
    ckfree((char *) argArray);
    return TCL_OK;

procError:
    if (precompiled) {
        procPtr->refCount--;
    } else {
        Tcl_DecrRefCount(bodyPtr);
        while (procPtr->firstLocalPtr != NULL) {
            localPtr = procPtr->firstLocalPtr;
            procPtr->firstLocalPtr = localPtr->nextPtr;
	
            defPtr = localPtr->defValuePtr;
            if (defPtr != NULL) {
                Tcl_DecrRefCount(defPtr);
            }
	
            ckfree((char *) localPtr);
        }
        ckfree((char *) procPtr);
    }
    if (argArray != NULL) {
	ckfree((char *) argArray);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetFrame --
 *
 *	Given a description of a procedure frame, such as the first
 *	argument to an "uplevel" or "upvar" command, locate the
 *	call frame for the appropriate level of procedure.
 *
 * Results:
 *	The return value is -1 if an error occurred in finding the frame
 *	(in this case an error message is left in the interp's result).
 *	1 is returned if string was either a number or a number preceded
 *	by "#" and it specified a valid frame.  0 is returned if string
 *	isn't one of the two things above (in this case, the lookup
 *	acts as if string were "1").  The variable pointed to by
 *	framePtrPtr is filled in with the address of the desired frame
 *	(unless an error occurs, in which case it isn't modified).
 *
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
	}
	if (level < 0) {
	    levelError:
	    Tcl_AppendResult(interp, "bad level \"", string, "\"",
		    (char *) NULL);
	    return -1;
	}
    } else if (isdigit(UCHAR(*string))) {
	if (Tcl_GetInt(interp, string, &level) != TCL_OK) {
	    return -1;
	}
	level = curLevel - level;
    } else {
	level = curLevel - 1;
	result = 0;







|







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
	}
	if (level < 0) {
	    levelError:
	    Tcl_AppendResult(interp, "bad level \"", string, "\"",
		    (char *) NULL);
	    return -1;
	}
    } else if (isdigit(UCHAR(*string))) { /* INTL: digit */
	if (Tcl_GetInt(interp, string, &level) != TCL_OK) {
	    return -1;
	}
	level = curLevel - level;
    } else {
	level = curLevel - 1;
	result = 0;
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
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register Interp *iPtr = (Interp *) interp;
    char *optLevel;
    int length, result;
    CallFrame *savedVarFramePtr, *framePtr;

    if (objc < 2) {
	uplevelSyntax:
	Tcl_WrongNumArgs(interp, 1, objv, "?level? command ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * Find the level to use for executing the command.
     * THIS FAILS IF THE OBJECT RESULT'S STRING REP CONTAINS A NULL.
     */

    optLevel = Tcl_GetStringFromObj(objv[1], &length);
    result = TclGetFrame(interp, optLevel, &framePtr);
    if (result == -1) {
	return TCL_ERROR;
    }
    objc -= (result+1);
    if (objc == 0) {
	goto uplevelSyntax;







|










<


|







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
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    register Interp *iPtr = (Interp *) interp;
    char *optLevel;
    int result;
    CallFrame *savedVarFramePtr, *framePtr;

    if (objc < 2) {
	uplevelSyntax:
	Tcl_WrongNumArgs(interp, 1, objv, "?level? command ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * Find the level to use for executing the command.

     */

    optLevel = TclGetString(objv[1]);
    result = TclGetFrame(interp, optLevel, &framePtr);
    if (result == -1) {
	return TCL_ERROR;
    }
    objc -= (result+1);
    if (objc == 0) {
	goto uplevelSyntax;
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
    iPtr->varFramePtr = framePtr;

    /*
     * Execute the residual arguments as a command.
     */

    if (objc == 1) {
	result = Tcl_EvalObj(interp, objv[0]);
    } else {


	Tcl_Obj *cmdObjPtr = Tcl_ConcatObj(objc, objv);
	result = Tcl_EvalObj(interp, cmdObjPtr);
	Tcl_DecrRefCount(cmdObjPtr); /* done with object */
    }
    if (result == TCL_ERROR) {
	char msg[60];
	sprintf(msg, "\n    (\"uplevel\" body line %d)", interp->errorLine);
	Tcl_AddObjErrorInfo(interp, msg, -1);
    }

    /*
     * Restore the variable frame, and return.
     */

    iPtr->varFramePtr = savedVarFramePtr;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclFindProc --
 *
 *	Given the name of a procedure, return a pointer to the
 *	record describing the procedure.


 *
 * Results:
 *	NULL is returned if the name doesn't correspond to any
 *	procedure.  Otherwise the return value is a pointer to
 *	the procedure's record.



 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Proc *
TclFindProc(iPtr, procName)
    Interp *iPtr;		/* Interpreter in which to look. */
    char *procName;		/* Name of desired procedure. */
{
    Tcl_Command cmd;

    Command *cmdPtr;

    cmd = Tcl_FindCommand((Tcl_Interp *) iPtr, procName,
            (Tcl_Namespace *) NULL, /*flags*/ 0);
    if (cmd == (Tcl_Command) NULL) {
        return NULL;
    }
    cmdPtr = (Command *) cmd;





    if (cmdPtr->proc != InterpProc) {
	return NULL;
    }
    return (Proc *) cmdPtr->clientData;
}

/*
 *----------------------------------------------------------------------
 *
 * TclIsProc --
 *
 *	Tells whether a command is a Tcl procedure or not.
 *
 * Results:
 *	If the given command is actuall a Tcl procedure, the
 *	return value is the address of the record describing
 *	the procedure.  Otherwise the return value is 0.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Proc *
TclIsProc(cmdPtr)
    Command *cmdPtr;		/* Command to test. */
{






    if (cmdPtr->proc == InterpProc) {
	return (Proc *) cmdPtr->clientData;
    }
    return (Proc *) 0;
}

/*
 *----------------------------------------------------------------------
 *
 * InterpProc --
 *
 *	When a Tcl procedure gets invoked with an argc/argv array of
 *	strings, this routine gets invoked to interpret the procedure.
 *
 * Results:
 *	A standard Tcl result value, usually TCL_OK.
 *
 * Side effects:
 *	Depends on the commands in the procedure.
 *
 *----------------------------------------------------------------------
 */

static int
InterpProc(clientData, interp, argc, argv)
    ClientData clientData;	/* Record describing procedure to be
				 * interpreted. */
    Tcl_Interp *interp;		/* Interpreter in which procedure was
				 * invoked. */
    int argc;			/* Count of number of arguments to this
				 * procedure. */
    register char **argv;	/* Argument values. */







|

>
>
|
|
<


|


















|
>
>



|
|
>
>
>













>

|






>
>
>
>
>
|













|













>
>
>
>
>
>
|








|













|
|







596
597
598
599
600
601
602
603
604
605
606
607
608

609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
    iPtr->varFramePtr = framePtr;

    /*
     * Execute the residual arguments as a command.
     */

    if (objc == 1) {
	result = Tcl_EvalObjEx(interp, objv[0], 0);
    } else {
	Tcl_Obj *objPtr;

	objPtr = Tcl_ConcatObj(objc, objv);
	result = Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_DIRECT);

    }
    if (result == TCL_ERROR) {
	char msg[32 + TCL_INTEGER_SPACE];
	sprintf(msg, "\n    (\"uplevel\" body line %d)", interp->errorLine);
	Tcl_AddObjErrorInfo(interp, msg, -1);
    }

    /*
     * Restore the variable frame, and return.
     */

    iPtr->varFramePtr = savedVarFramePtr;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclFindProc --
 *
 *	Given the name of a procedure, return a pointer to the
 *	record describing the procedure. The procedure will be
 *	looked up using the usual rules: first in the current
 *	namespace and then in the global namespace.
 *
 * Results:
 *	NULL is returned if the name doesn't correspond to any
 *	procedure. Otherwise, the return value is a pointer to
 *	the procedure's record. If the name is found but refers
 *	to an imported command that points to a "real" procedure
 *	defined in another namespace, a pointer to that "real"
 *	procedure's structure is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Proc *
TclFindProc(iPtr, procName)
    Interp *iPtr;		/* Interpreter in which to look. */
    char *procName;		/* Name of desired procedure. */
{
    Tcl_Command cmd;
    Tcl_Command origCmd;
    Command *cmdPtr;
    
    cmd = Tcl_FindCommand((Tcl_Interp *) iPtr, procName,
            (Tcl_Namespace *) NULL, /*flags*/ 0);
    if (cmd == (Tcl_Command) NULL) {
        return NULL;
    }
    cmdPtr = (Command *) cmd;

    origCmd = TclGetOriginalCommand(cmd);
    if (origCmd != NULL) {
	cmdPtr = (Command *) origCmd;
    }
    if (cmdPtr->proc != TclProcInterpProc) {
	return NULL;
    }
    return (Proc *) cmdPtr->clientData;
}

/*
 *----------------------------------------------------------------------
 *
 * TclIsProc --
 *
 *	Tells whether a command is a Tcl procedure or not.
 *
 * Results:
 *	If the given command is actually a Tcl procedure, the
 *	return value is the address of the record describing
 *	the procedure.  Otherwise the return value is 0.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Proc *
TclIsProc(cmdPtr)
    Command *cmdPtr;		/* Command to test. */
{
    Tcl_Command origCmd;

    origCmd = TclGetOriginalCommand((Tcl_Command) cmdPtr);
    if (origCmd != NULL) {
	cmdPtr = (Command *) origCmd;
    }
    if (cmdPtr->proc == TclProcInterpProc) {
	return (Proc *) cmdPtr->clientData;
    }
    return (Proc *) 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TclProcInterpProc --
 *
 *	When a Tcl procedure gets invoked with an argc/argv array of
 *	strings, this routine gets invoked to interpret the procedure.
 *
 * Results:
 *	A standard Tcl result value, usually TCL_OK.
 *
 * Side effects:
 *	Depends on the commands in the procedure.
 *
 *----------------------------------------------------------------------
 */

int
TclProcInterpProc(clientData, interp, argc, argv)
    ClientData clientData;	/* Record describing procedure to be
				 * interpreted. */
    Tcl_Interp *interp;		/* Interpreter in which procedure was
				 * invoked. */
    int argc;			/* Count of number of arguments to this
				 * procedure. */
    register char **argv;	/* Argument values. */
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
     */

    result = TclObjInterpProc(clientData, interp, argc, objv);

    /*
     * Move the interpreter's object result to the string result, 
     * then reset the object result.
     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
     */
    
    Tcl_SetResult(interp,
	    TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
	    TCL_VOLATILE);

    /*
     * Decrement the ref counts on the objv elements since we are done
     * with them.
     */








<


|
<







768
769
770
771
772
773
774

775
776
777

778
779
780
781
782
783
784
     */

    result = TclObjInterpProc(clientData, interp, argc, objv);

    /*
     * Move the interpreter's object result to the string result, 
     * then reset the object result.

     */
    
    Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),

	    TCL_VOLATILE);

    /*
     * Decrement the ref counts on the objv elements since we are done
     * with them.
     */

641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
 *	Depends on the commands in the procedure.
 *
 *----------------------------------------------------------------------
 */

int
TclObjInterpProc(clientData, interp, objc, objv)
    ClientData clientData;	/* Record describing procedure to be
				 * interpreted. */
    Tcl_Interp *interp;		/* Interpreter in which procedure was
				 * invoked. */
    int objc;			/* Count of number of arguments to this
				 * procedure. */
    Tcl_Obj *CONST objv[];	/* Argument value objects. */
{
    Interp *iPtr = (Interp *) interp;
    Proc *procPtr = (Proc *) clientData;
    Tcl_Obj *bodyPtr = procPtr->bodyPtr;
    CallFrame frame;
    register CallFrame *framePtr = &frame;
    register Var *varPtr;
    register CompiledLocal *localPtr;
    Proc *saveProcPtr;
    char *procName, *bytes;
    int nameLen, localCt, numArgs, argCt, length, i, result;

    /*
     * This procedure generates an array "compiledLocals" that holds the
     * storage for local variables. It starts out with stack-allocated space
     * but uses dynamically-allocated storage if needed.
     */

#define NUM_LOCALS 20
    Var localStorage[NUM_LOCALS];
    Var *compiledLocals = localStorage;

    /*
     * Get the procedure's name.
     * THIS FAILS IF THE PROC NAME'S STRING REP HAS A NULL.
     */
    
    procName = Tcl_GetStringFromObj(objv[0], &nameLen);

    /*
     * If necessary, compile the procedure's body. The compiler will
     * allocate frame slots for the procedure's non-argument local
     * variables. If the ByteCode already exists, make sure it hasn't been
     * invalidated by someone redefining a core command (this might make the
     * compiled code wrong). Also, if the code was compiled in/for a
     * different interpreter, we recompile it. Note that compiling the body
     * might increase procPtr->numCompiledLocals if new local variables are
     * found while compiling.
     */

    if (bodyPtr->typePtr == &tclByteCodeType) {
	ByteCode *codePtr = (ByteCode *) bodyPtr->internalRep.otherValuePtr;
	
	if ((codePtr->iPtr != iPtr)
	        || (codePtr->compileEpoch != iPtr->compileEpoch)) {
	    tclByteCodeType.freeIntRepProc(bodyPtr);
	    bodyPtr->typePtr = (Tcl_ObjType *) NULL;
	}
    }
    if (bodyPtr->typePtr != &tclByteCodeType) {
	char buf[100];
	int numChars;
	char *ellipsis;
	
	if (tclTraceCompile >= 1) {
	    /*
	     * Display a line summarizing the top level command we
	     * are about to compile.
	     */

	    numChars = nameLen;
	    ellipsis = "";
	    if (numChars > 50) {
		numChars = 50;
		ellipsis = "...";
	    }
	    fprintf(stdout, "Compiling body of proc \"%.*s%s\"\n",
		    numChars, procName, ellipsis);
	}
	
	saveProcPtr = iPtr->compiledProcPtr;
	iPtr->compiledProcPtr = procPtr;
	result = tclByteCodeType.setFromAnyProc(interp, bodyPtr);
	iPtr->compiledProcPtr = saveProcPtr;
	
	if (result != TCL_OK) {
	    if (result == TCL_ERROR) {
		numChars = nameLen;
		ellipsis = "";
		if (numChars > 50) {
		    numChars = 50;
		    ellipsis = "...";
		}
		sprintf(buf, "\n    (compiling body of proc \"%.*s%s\", line %d)",
			numChars, procName, ellipsis, interp->errorLine);
		Tcl_AddObjErrorInfo(interp, buf, -1);
	    }
	    return result;
	}
    }

    /*
     * Create the "compiledLocals" array. Make sure it is large enough to
     * hold all the procedure's compiled local variables, including its
     * formal parameters.
     */







|
|
|
|
|
|
|


|
|




<
|
|













<







<
<
<
|
|
|


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







813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834

835
836
837
838
839
840
841
842
843
844
845
846
847
848
849

850
851
852
853
854
855
856



857
858
859
860
861


862
























863
864






865











866

867
868
869
870
871
872
873
 *	Depends on the commands in the procedure.
 *
 *----------------------------------------------------------------------
 */

int
TclObjInterpProc(clientData, interp, objc, objv)
    ClientData clientData; 	 /* Record describing procedure to be
				  * interpreted. */
    register Tcl_Interp *interp; /* Interpreter in which procedure was
				  * invoked. */
    int objc;			 /* Count of number of arguments to this
				  * procedure. */
    Tcl_Obj *CONST objv[];	 /* Argument value objects. */
{
    Interp *iPtr = (Interp *) interp;
    register Proc *procPtr = (Proc *) clientData;
    Namespace *nsPtr = procPtr->cmdPtr->nsPtr;
    CallFrame frame;
    register CallFrame *framePtr = &frame;
    register Var *varPtr;
    register CompiledLocal *localPtr;

    char *procName;
    int nameLen, localCt, numArgs, argCt, i, result;

    /*
     * This procedure generates an array "compiledLocals" that holds the
     * storage for local variables. It starts out with stack-allocated space
     * but uses dynamically-allocated storage if needed.
     */

#define NUM_LOCALS 20
    Var localStorage[NUM_LOCALS];
    Var *compiledLocals = localStorage;

    /*
     * Get the procedure's name.

     */
    
    procName = Tcl_GetStringFromObj(objv[0], &nameLen);

    /*
     * If necessary, compile the procedure's body. The compiler will
     * allocate frame slots for the procedure's non-argument local



     * variables.  Note that compiling the body might increase
     * procPtr->numCompiledLocals if new local variables are found
     * while compiling.
     */



    result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr, nsPtr,
























	    "body of proc", procName);
    






    if (result != TCL_OK) {











        return result;

    }

    /*
     * Create the "compiledLocals" array. Make sure it is large enough to
     * hold all the procedure's compiled local variables, including its
     * formal parameters.
     */
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773





774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
     * This call frame will execute in the proc's namespace, which might
     * be different than the current namespace. The proc's namespace is
     * that of its command, which can change if the command is renamed
     * from one namespace to another.
     */

    result = Tcl_PushCallFrame(interp, (Tcl_CallFrame *) framePtr,
            (Tcl_Namespace *) procPtr->cmdPtr->nsPtr,
	     /*isProcCallFrame*/ 1);
    if (result != TCL_OK) {
        return result;
    }

    framePtr->objc = objc;
    framePtr->objv = objv;  /* ref counts for args are incremented below */





    framePtr->procPtr = procPtr;
    framePtr->numCompiledLocals = localCt;
    framePtr->compiledLocals = compiledLocals;

    /*
     * Initialize the array of local variables stored in the call frame.
     */

    varPtr = framePtr->compiledLocals;
    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;
	    localPtr = localPtr->nextPtr) {
	varPtr->value.objPtr = NULL;
	varPtr->name = localPtr->name; /* will be just '\0' if temp var */
	varPtr->nsPtr = NULL;
	varPtr->hPtr = NULL;
	varPtr->refCount = 0;
	varPtr->tracePtr = NULL;
	varPtr->searchPtr = NULL;
	varPtr->flags = (localPtr->flags | VAR_UNDEFINED);
	varPtr++;
    }

    /*
     * Match and assign the call's actual parameters to the procedure's
     * formal arguments. The formal arguments are described by the first
     * numArgs entries in both the Proc structure's local variable list and
     * the call frame's local variable array.
     */

    numArgs = procPtr->numArgs;
    varPtr = framePtr->compiledLocals;
    localPtr = procPtr->firstLocalPtr;
    argCt = objc;
    for (i = 1, argCt -= 1;  i <= numArgs;  i++, argCt--) {
	if (!localPtr->isArg) {
	    panic("TclObjInterpProc: local variable %s is not argument but should be",
		  localPtr->name);
	    return TCL_ERROR;
	}
	if (localPtr->isTemp) {
	    panic("TclObjInterpProc: local variable %d is temporary but should be an argument", i);
	    return TCL_ERROR;
	}

	/*
	 * Handle the special case of the last formal being "args".  When
	 * it occurs, assign it a list consisting of all the remaining







|
|






>
>
>
>
>




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













|




|







882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905



906













907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
     * This call frame will execute in the proc's namespace, which might
     * be different than the current namespace. The proc's namespace is
     * that of its command, which can change if the command is renamed
     * from one namespace to another.
     */

    result = Tcl_PushCallFrame(interp, (Tcl_CallFrame *) framePtr,
            (Tcl_Namespace *) nsPtr, /*isProcCallFrame*/ 1);

    if (result != TCL_OK) {
        return result;
    }

    framePtr->objc = objc;
    framePtr->objv = objv;  /* ref counts for args are incremented below */

    /*
     * Initialize and resolve compiled variable references.
     */

    framePtr->procPtr = procPtr;
    framePtr->numCompiledLocals = localCt;
    framePtr->compiledLocals = compiledLocals;




    TclInitCompiledLocals(interp, framePtr, nsPtr);














    /*
     * Match and assign the call's actual parameters to the procedure's
     * formal arguments. The formal arguments are described by the first
     * numArgs entries in both the Proc structure's local variable list and
     * the call frame's local variable array.
     */

    numArgs = procPtr->numArgs;
    varPtr = framePtr->compiledLocals;
    localPtr = procPtr->firstLocalPtr;
    argCt = objc;
    for (i = 1, argCt -= 1;  i <= numArgs;  i++, argCt--) {
	if (!TclIsVarArgument(localPtr)) {
	    panic("TclObjInterpProc: local variable %s is not argument but should be",
		  localPtr->name);
	    return TCL_ERROR;
	}
	if (TclIsVarTemporary(localPtr)) {
	    panic("TclObjInterpProc: local variable %d is temporary but should be an argument", i);
	    return TCL_ERROR;
	}

	/*
	 * Handle the special case of the last formal being "args".  When
	 * it occurs, assign it a list consisting of all the remaining
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868

869
870
871
872
873
874
875



876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911

912
913

914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929















































































































































































































930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983

984
985
986
987
988
989









990
991
992
993
994
995
996
	    varPtr->flags &= ~VAR_UNDEFINED;
	    Tcl_IncrRefCount(objPtr);  /* since the local variable now has
					* another reference to object. */
	} else {
	    Tcl_ResetResult(interp);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "no value given for parameter \"", localPtr->name,
		    "\" to \"", Tcl_GetStringFromObj(objv[0], (int *) NULL),
		    "\"", (char *) NULL);
	    result = TCL_ERROR;
	    goto procDone;
	}
	varPtr++;
	localPtr = localPtr->nextPtr;
    }
    if (argCt > 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"called \"", Tcl_GetStringFromObj(objv[0], (int *) NULL),
		"\" with too many arguments", (char *) NULL);
	result = TCL_ERROR;
	goto procDone;
    }

    /*
     * Invoke the commands in the procedure's body.
     */

    if (tclTraceExec >= 1) {

	fprintf(stdout, "Calling proc ");
	for (i = 0;  i < objc;  i++) {
	    bytes = Tcl_GetStringFromObj(objv[i], &length);
	    TclPrintSource(stdout, bytes, TclMin(length, 15));
	    fprintf(stdout, " ");
	}
	fprintf(stdout, "\n");



	fflush(stdout);
    }

    iPtr->returnCode = TCL_OK;
    procPtr->refCount++;
    result = Tcl_EvalObj(interp, procPtr->bodyPtr);
    procPtr->refCount--;
    if (procPtr->refCount <= 0) {
	CleanupProc(procPtr);
    }

    if (result != TCL_OK) {
	if (result == TCL_RETURN) {
	    result = TclUpdateReturnInfo(iPtr);
	} else if (result == TCL_ERROR) {
	    char msg[100];
	    sprintf(msg, "\n    (procedure \"%.50s\" line %d)",
		    procName, iPtr->errorLine);
	    Tcl_AddObjErrorInfo(interp, msg, -1);
	} else if (result == TCL_BREAK) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
	            "invoked \"break\" outside of a loop", -1);
	    result = TCL_ERROR;
	} else if (result == TCL_CONTINUE) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		    "invoked \"continue\" outside of a loop", -1);
	    result = TCL_ERROR;
	}
    }
    
    procDone:

    /*
     * Pop and free the call frame for this procedure invocation.

     */
    

    Tcl_PopCallFrame(interp);
    
    /*
     * Free the compiledLocals array if malloc'ed storage was used.
     */

    if (compiledLocals != localStorage) {
	ckfree((char *) compiledLocals);
    }
    return result;
#undef NUM_LOCALS
}

/*
 *----------------------------------------------------------------------
 *















































































































































































































 * ProcDeleteProc --
 *
 *	This procedure is invoked just before a command procedure is
 *	removed from an interpreter.  Its job is to release all the
 *	resources allocated to the procedure.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory gets freed, unless the procedure is actively being
 *	executed.  In this case the cleanup is delayed until the
 *	last call to the current procedure completes.
 *
 *----------------------------------------------------------------------
 */

static void
ProcDeleteProc(clientData)
    ClientData clientData;		/* Procedure to be deleted. */
{
    Proc *procPtr = (Proc *) clientData;

    procPtr->refCount--;
    if (procPtr->refCount <= 0) {
	CleanupProc(procPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * CleanupProc --
 *
 *	This procedure does all the real work of freeing up a Proc
 *	structure.  It's called only when the structure's reference
 *	count becomes zero.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory gets freed.
 *
 *----------------------------------------------------------------------
 */

static void
CleanupProc(procPtr)
    register Proc *procPtr;		/* Procedure to be deleted. */
{
    register CompiledLocal *localPtr;
    Tcl_Obj *bodyPtr = procPtr->bodyPtr;
    Tcl_Obj *defPtr;


    if (bodyPtr != NULL) {
	Tcl_DecrRefCount(bodyPtr);
    }
    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;  ) {
	CompiledLocal *nextPtr = localPtr->nextPtr;










	if (localPtr->defValuePtr != NULL) {
	    defPtr = localPtr->defValuePtr;
	    Tcl_DecrRefCount(defPtr);
	}
	ckfree((char *) localPtr);
	localPtr = nextPtr;







|
<








|










>


<
|



>
>
>





|


|



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

|
>


>

<
<
<
<
<










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
















|
|






|






|














|
|





>






>
>
>
>
>
>
>
>
>







953
954
955
956
957
958
959
960

961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982

983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001





1002











1003
1004



1005
1006
1007
1008
1009
1010
1011





1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
	    varPtr->flags &= ~VAR_UNDEFINED;
	    Tcl_IncrRefCount(objPtr);  /* since the local variable now has
					* another reference to object. */
	} else {
	    Tcl_ResetResult(interp);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "no value given for parameter \"", localPtr->name,
		    "\" to \"", Tcl_GetString(objv[0]), "\"", (char *) NULL);

	    result = TCL_ERROR;
	    goto procDone;
	}
	varPtr++;
	localPtr = localPtr->nextPtr;
    }
    if (argCt > 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"called \"", Tcl_GetString(objv[0]),
		"\" with too many arguments", (char *) NULL);
	result = TCL_ERROR;
	goto procDone;
    }

    /*
     * Invoke the commands in the procedure's body.
     */

    if (tclTraceExec >= 1) {
#ifdef TCL_COMPILE_DEBUG
	fprintf(stdout, "Calling proc ");
	for (i = 0;  i < objc;  i++) {

	    TclPrintObject(stdout, objv[i], 15);
	    fprintf(stdout, " ");
	}
	fprintf(stdout, "\n");
#else /* TCL_COMPILE_DEBUG */
	fprintf(stdout, "Calling proc %.*s\n", nameLen, procName);
#endif /*TCL_COMPILE_DEBUG*/
	fflush(stdout);
    }

    iPtr->returnCode = TCL_OK;
    procPtr->refCount++;
    result = Tcl_EvalObjEx(interp, procPtr->bodyPtr, 0);
    procPtr->refCount--;
    if (procPtr->refCount <= 0) {
	TclProcCleanupProc(procPtr);
    }

    if (result != TCL_OK) {





	result = ProcessProcResultCode(interp, procName, nameLen, result);











    }
    



    /*
     * Pop and free the call frame for this procedure invocation, then
     * free the compiledLocals array if malloc'ed storage was used.
     */
    
    procDone:
    Tcl_PopCallFrame(interp);





    if (compiledLocals != localStorage) {
	ckfree((char *) compiledLocals);
    }
    return result;
#undef NUM_LOCALS
}

/*
 *----------------------------------------------------------------------
 *
 * TclProcCompileProc --
 *
 *	Called just before a procedure is executed to compile the
 *	body to byte codes.  If the type of the body is not
 *	"byte code" or if the compile conditions have changed
 *	(namespace context, epoch counters, etc.) then the body
 *	is recompiled.  Otherwise, this procedure does nothing.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May change the internal representation of the body object
 *	to compiled code.
 *
 *----------------------------------------------------------------------
 */
 
int
TclProcCompileProc(interp, procPtr, bodyPtr, nsPtr, description, procName)
    Tcl_Interp *interp;		/* Interpreter containing procedure. */
    Proc *procPtr;		/* Data associated with procedure. */
    Tcl_Obj *bodyPtr;		/* Body of proc. (Usually procPtr->bodyPtr,
 				 * but could be any code fragment compiled
 				 * in the context of this procedure.) */
    Namespace *nsPtr;		/* Namespace containing procedure. */
    CONST char *description;	/* string describing this body of code. */
    CONST char *procName;	/* Name of this procedure. */
{
    Interp *iPtr = (Interp*)interp;
    int result;
    Tcl_CallFrame frame;
    Proc *saveProcPtr;
    ByteCode *codePtr = (ByteCode *) bodyPtr->internalRep.otherValuePtr;
 
    /*
     * If necessary, compile the procedure's body. The compiler will
     * allocate frame slots for the procedure's non-argument local
     * variables. If the ByteCode already exists, make sure it hasn't been
     * invalidated by someone redefining a core command (this might make the
     * compiled code wrong). Also, if the code was compiled in/for a
     * different interpreter, we recompile it. Note that compiling the body
     * might increase procPtr->numCompiledLocals if new local variables are
     * found while compiling.
     *
     * Precompiled procedure bodies, however, are immutable and therefore
     * they are not recompiled, even if things have changed.
     */
 
    if (bodyPtr->typePtr == &tclByteCodeType) {
 	if (((Interp *) *codePtr->interpHandle != iPtr)
 	        || (codePtr->compileEpoch != iPtr->compileEpoch)
 	        || (codePtr->nsPtr != nsPtr)) {
            if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
                if ((Interp *) *codePtr->interpHandle != iPtr) {
                    Tcl_AppendResult(interp,
                            "a precompiled script jumped interps", NULL);
                    return TCL_ERROR;
                }
	        codePtr->compileEpoch = iPtr->compileEpoch;
                codePtr->nsPtr = nsPtr;
            } else {
                (*tclByteCodeType.freeIntRepProc)(bodyPtr);
                bodyPtr->typePtr = (Tcl_ObjType *) NULL;
            }
 	}
    }
    if (bodyPtr->typePtr != &tclByteCodeType) {
 	char buf[100];
 	int numChars;
 	char *ellipsis;
 	
 	if (tclTraceCompile >= 1) {
 	    /*
 	     * Display a line summarizing the top level command we
 	     * are about to compile.
 	     */
 
 	    numChars = strlen(procName);
 	    ellipsis = "";
 	    if (numChars > 50) {
 		numChars = 50;
 		ellipsis = "...";
 	    }
 	    fprintf(stdout, "Compiling %s \"%.*s%s\"\n",
 		    description, numChars, procName, ellipsis);
 	}
 	
 	/*
 	 * Plug the current procPtr into the interpreter and coerce
 	 * the code body to byte codes.  The interpreter needs to
 	 * know which proc it's compiling so that it can access its
 	 * list of compiled locals.
 	 *
 	 * TRICKY NOTE:  Be careful to push a call frame with the
 	 *   proper namespace context, so that the byte codes are
 	 *   compiled in the appropriate class context.
 	 */
 
 	saveProcPtr = iPtr->compiledProcPtr;
 	iPtr->compiledProcPtr = procPtr;
 
 	result = Tcl_PushCallFrame(interp, &frame,
		(Tcl_Namespace*)nsPtr, /* isProcCallFrame */ 0);
 
 	if (result == TCL_OK) {
	    result = tclByteCodeType.setFromAnyProc(interp, bodyPtr);
	    Tcl_PopCallFrame(interp);
	}
 
 	iPtr->compiledProcPtr = saveProcPtr;
 	
 	if (result != TCL_OK) {
 	    if (result == TCL_ERROR) {
 		numChars = strlen(procName);
 		ellipsis = "";
 		if (numChars > 50) {
 		    numChars = 50;
 		    ellipsis = "...";
 		}
 		sprintf(buf, "\n    (compiling %s \"%.*s%s\", line %d)",
 			description, numChars, procName, ellipsis,
 			interp->errorLine);
 		Tcl_AddObjErrorInfo(interp, buf, -1);
 	    }
 	    return result;
 	}
    } else if (codePtr->nsEpoch != nsPtr->resolverEpoch) {
	register CompiledLocal *localPtr;
 	
	/*
	 * The resolver epoch has changed, but we only need to invalidate
	 * the resolver cache.
	 */

	for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;
	    localPtr = localPtr->nextPtr) {
	    localPtr->flags &= ~(VAR_RESOLVED);
	    if (localPtr->resolveInfo) {
		if (localPtr->resolveInfo->deleteProc) {
		    localPtr->resolveInfo->deleteProc(localPtr->resolveInfo);
		} else {
		    ckfree((char*)localPtr->resolveInfo);
		}
		localPtr->resolveInfo = NULL;
	    }
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ProcessProcResultCode --
 *
 *	Procedure called by TclObjInterpProc to process a return code other
 *	than TCL_OK returned by a Tcl procedure.
 *
 * Results:
 *	Depending on the argument return code, the result returned is
 *	another return code and the interpreter's result is set to a value
 *	to supplement that return code.
 *
 * Side effects:
 *	If the result returned is TCL_ERROR, traceback information about
 *	the procedure just executed is appended to the interpreter's
 *	"errorInfo" variable.
 *
 *----------------------------------------------------------------------
 */

static int
ProcessProcResultCode(interp, procName, nameLen, returnCode)
    Tcl_Interp *interp;		/* The interpreter in which the procedure
				 * was called and returned returnCode. */
    char *procName;		/* Name of the procedure. Used for error
				 * messages and trace information. */
    int nameLen;		/* Number of bytes in procedure's name. */
    int returnCode;		/* The unexpected result code. */
{
    Interp *iPtr = (Interp *) interp;
    char msg[100 + TCL_INTEGER_SPACE];
    
    if (returnCode == TCL_RETURN) {
	returnCode = TclUpdateReturnInfo(iPtr);
    } else if (returnCode == TCL_ERROR) {
	sprintf(msg, "\n    (procedure \"%.*s\" line %d)",
		nameLen, procName, iPtr->errorLine);
	Tcl_AddObjErrorInfo(interp, msg, -1);
    } else if (returnCode == TCL_BREAK) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
		"invoked \"break\" outside of a loop", -1);
	returnCode = TCL_ERROR;
    } else if (returnCode == TCL_CONTINUE) {
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp),
	        "invoked \"continue\" outside of a loop", -1);
	returnCode = TCL_ERROR;
    }
    return returnCode;
}

/*
 *----------------------------------------------------------------------
 *
 * TclProcDeleteProc --
 *
 *	This procedure is invoked just before a command procedure is
 *	removed from an interpreter.  Its job is to release all the
 *	resources allocated to the procedure.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory gets freed, unless the procedure is actively being
 *	executed.  In this case the cleanup is delayed until the
 *	last call to the current procedure completes.
 *
 *----------------------------------------------------------------------
 */

void
TclProcDeleteProc(clientData)
    ClientData clientData;		/* Procedure to be deleted. */
{
    Proc *procPtr = (Proc *) clientData;

    procPtr->refCount--;
    if (procPtr->refCount <= 0) {
	TclProcCleanupProc(procPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclProcCleanupProc --
 *
 *	This procedure does all the real work of freeing up a Proc
 *	structure.  It's called only when the structure's reference
 *	count becomes zero.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory gets freed.
 *
 *----------------------------------------------------------------------
 */

void
TclProcCleanupProc(procPtr)
    register Proc *procPtr;		/* Procedure to be deleted. */
{
    register CompiledLocal *localPtr;
    Tcl_Obj *bodyPtr = procPtr->bodyPtr;
    Tcl_Obj *defPtr;
    Tcl_ResolvedVarInfo *resVarInfo;

    if (bodyPtr != NULL) {
	Tcl_DecrRefCount(bodyPtr);
    }
    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;  ) {
	CompiledLocal *nextPtr = localPtr->nextPtr;

        resVarInfo = localPtr->resolveInfo;
	if (resVarInfo) {
	    if (resVarInfo->deleteProc) {
		(*resVarInfo->deleteProc)(resVarInfo);
	    } else {
		ckfree((char *) resVarInfo);
	    }
        }

	if (localPtr->defValuePtr != NULL) {
	    defPtr = localPtr->defValuePtr;
	    Tcl_DecrRefCount(defPtr);
	}
	ckfree((char *) localPtr);
	localPtr = nextPtr;
1036
1037
1038
1039
1040
1041
1042














































































































































































































	    Tcl_SetVar2((Tcl_Interp *) iPtr, "errorInfo", (char *) NULL,
		    iPtr->errorInfo, TCL_GLOBAL_ONLY);
	    iPtr->flags |= ERR_IN_PROGRESS;
	}
    }
    return code;
}





















































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
	    Tcl_SetVar2((Tcl_Interp *) iPtr, "errorInfo", (char *) NULL,
		    iPtr->errorInfo, TCL_GLOBAL_ONLY);
	    iPtr->flags |= ERR_IN_PROGRESS;
	}
    }
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetInterpProc --
 *
 *  Returns a pointer to the TclProcInterpProc procedure; this is different
 *  from the value obtained from the TclProcInterpProc reference on systems
 *  like Windows where import and export versions of a procedure exported
 *  by a DLL exist.
 *
 * Results:
 *  Returns the internal address of the TclProcInterpProc procedure.
 *
 * Side effects:
 *  None.
 *
 *----------------------------------------------------------------------
 */

TclCmdProcType
TclGetInterpProc()
{
    return (TclCmdProcType) TclProcInterpProc;
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetObjInterpProc --
 *
 *  Returns a pointer to the TclObjInterpProc procedure; this is different
 *  from the value obtained from the TclObjInterpProc reference on systems
 *  like Windows where import and export versions of a procedure exported
 *  by a DLL exist.
 *
 * Results:
 *  Returns the internal address of the TclObjInterpProc procedure.
 *
 * Side effects:
 *  None.
 *
 *----------------------------------------------------------------------
 */

TclObjCmdProcType
TclGetObjInterpProc()
{
    return (TclObjCmdProcType) TclObjInterpProc;
}

/*
 *----------------------------------------------------------------------
 *
 * TclNewProcBodyObj --
 *
 *  Creates a new object, of type "procbody", whose internal
 *  representation is the given Proc struct.
 *  The newly created object's reference count is 0.
 *
 * Results:
 *  Returns a pointer to a newly allocated Tcl_Obj, 0 on error.
 *
 * Side effects:
 *  The reference count in the ByteCode attached to the Proc is bumped up
 *  by one, since the internal rep stores a pointer to it.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TclNewProcBodyObj(procPtr)
    Proc *procPtr;	/* the Proc struct to store as the internal
                         * representation. */
{
    Tcl_Obj *objPtr;

    if (!procPtr) {
        return (Tcl_Obj *) NULL;
    }
    
    objPtr = Tcl_NewStringObj("", 0);

    if (objPtr) {
        objPtr->typePtr = &tclProcBodyType;
        objPtr->internalRep.otherValuePtr = (VOID *) procPtr;

        procPtr->refCount++;
    }

    return objPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ProcBodyDup --
 *
 *  Tcl_ObjType's Dup function for the proc body object.
 *  Bumps the reference count on the Proc stored in the internal
 *  representation.
 *
 * Results:
 *  None.
 *
 * Side effects:
 *  Sets up the object in dupPtr to be a duplicate of the one in srcPtr.
 *
 *----------------------------------------------------------------------
 */

static void ProcBodyDup(srcPtr, dupPtr)
    Tcl_Obj *srcPtr;		/* object to copy */
    Tcl_Obj *dupPtr;		/* target object for the duplication */
{
    Proc *procPtr = (Proc *) srcPtr->internalRep.otherValuePtr;
    
    dupPtr->typePtr = &tclProcBodyType;
    dupPtr->internalRep.otherValuePtr = (VOID *) procPtr;
    procPtr->refCount++;
}

/*
 *----------------------------------------------------------------------
 *
 * ProcBodyFree --
 *
 *  Tcl_ObjType's Free function for the proc body object.
 *  The reference count on its Proc struct is decreased by 1; if the count
 *  reaches 0, the proc is freed.
 *
 * Results:
 *  None.
 *
 * Side effects:
 *  If the reference count on the Proc struct reaches 0, the struct is freed.
 *
 *----------------------------------------------------------------------
 */

static void
ProcBodyFree(objPtr)
    Tcl_Obj *objPtr;		/* the object to clean up */
{
    Proc *procPtr = (Proc *) objPtr->internalRep.otherValuePtr;
    procPtr->refCount--;
    if (procPtr->refCount <= 0) {
        TclProcCleanupProc(procPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ProcBodySetFromAny --
 *
 *  Tcl_ObjType's SetFromAny function for the proc body object.
 *  Calls panic.
 *
 * Results:
 *  Theoretically returns a TCL result code.
 *
 * Side effects:
 *  Calls panic, since we can't set the value of the object from a string
 *  representation (or any other internal ones).
 *
 *----------------------------------------------------------------------
 */

static int
ProcBodySetFromAny(interp, objPtr)
    Tcl_Interp *interp;			/* current interpreter */
    Tcl_Obj *objPtr;			/* object pointer */
{
    panic("called ProcBodySetFromAny");

    /*
     * this to keep compilers happy.
     */
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ProcBodyUpdateString --
 *
 *  Tcl_ObjType's UpdateString function for the proc body object.
 *  Calls panic.
 *
 * Results:
 *  None.
 *
 * Side effects:
 *  Calls panic, since we this type has no string representation.
 *
 *----------------------------------------------------------------------
 */

static void
ProcBodyUpdateString(objPtr)
    Tcl_Obj *objPtr;		/* the object to update */
{
    panic("called ProcBodyUpdateString");
}

Added generic/tclRegexp.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
/* 
 * tclRegexp.c --
 *
 *	This file contains the public interfaces to the Tcl regular
 *	expression mechanism.
 *
 * Copyright (c) 1998 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: tclRegexp.c,v 1.1.2.9 1999/04/14 00:33:26 surles Exp $
 */

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

/*
 *----------------------------------------------------------------------
 * The routines in this file use Henry Spencer's regular expression
 * package contained in the following additional source files:
 *
 *	regc_color.c	regc_cvec.c	regc_lex.c
 *	regc_nfa.c	regcomp.c	regcustom.h
 *	rege_dfa.c	regerror.c	regerrs.h
 *	regex.h		regexec.c	regfree.c
 *	regfronts.c	regguts.h
 *
 * Copyright (c) 1998 Henry Spencer.  All rights reserved.
 * 
 * Development of this software was funded, in part, by Cray Research Inc.,
 * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
 * Corporation, none of whom are responsible for the results.  The author
 * thanks all of them. 
 * 
 * Redistribution and use in source and binary forms -- with or without
 * modification -- are permitted for any purpose, provided that
 * redistributions in source form retain this entire copyright notice and
 * indicate the origin and nature of any modifications.
 * 
 * I'd appreciate being given credit for this package in the documentation
 * of software which uses it, but that is not a requirement.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * *** NOTE: this code has been altered slightly for use in Tcl: ***
 * *** 1. Names have been changed, e.g. from re_comp to		 ***
 * ***    TclRegComp, to avoid clashes with other 		 ***
 * ***    regexp implementations used by applications. 		 ***
 */

/*
 * Declarations for functions used only in this file.
 */

static void		DupRegexpInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
			    Tcl_Obj *copyPtr));
static void		FreeRegexpInternalRep _ANSI_ARGS_((Tcl_Obj *regexpPtr));
static int		SetRegexpFromAny _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr));
static TclRegexp *	CompileRegexp _ANSI_ARGS_((Tcl_Interp *interp,
			    char *pattern, int length, int flags));

/*
 * The regular expression Tcl object type.  This serves as a cache
 * of the compiled form of the regular expression.
 */

Tcl_ObjType tclRegexpType = {
    "regexp",				/* name */
    FreeRegexpInternalRep,		/* freeIntRepProc */
    DupRegexpInternalRep,		/* dupIntRepProc */
    NULL,				/* updateStringProc */
    SetRegexpFromAny			/* setFromAnyProc */
};


/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegExpCompile --
 *
 *	Compile a regular expression into a form suitable for fast
 *	matching.  This procedure is DEPRECATED in favor of the
 *	object version of the command.
 *
 * Results:
 *	The return value is a pointer to the compiled form of string,
 *	suitable for passing to Tcl_RegExpExec.  This compiled form
 *	is only valid up until the next call to this procedure, so
 *	don't keep these around for a long time!  If an error occurred
 *	while compiling the pattern, then NULL is returned and an error
 *	message is left in the interp's result.
 *
 * Side effects:
 *	Updates the cache of compiled regexps.
 *
 *----------------------------------------------------------------------
 */

Tcl_RegExp
Tcl_RegExpCompile(interp, string)
    Tcl_Interp *interp;			/* For use in error reporting. */
    char *string;			/* String for which to produce
					 * compiled regular expression. */
{
    Interp *iPtr = (Interp *) interp;
    int i, length;
    TclRegexp *result;

    length = strlen(string);
    for (i = 0; i < NUM_REGEXPS; i++) {
	if ((length == iPtr->patLengths[i])
		&& (strcmp(string, iPtr->patterns[i]) == 0)) {
	    /*
	     * Move the matched pattern to the first slot in the
	     * cache and shift the other patterns down one position.
	     */

	    if (i != 0) {
		int j;
		char *cachedString;

		cachedString = iPtr->patterns[i];
		result = iPtr->regexps[i];
		for (j = i-1; j >= 0; j--) {
		    iPtr->patterns[j+1] = iPtr->patterns[j];
		    iPtr->patLengths[j+1] = iPtr->patLengths[j];
		    iPtr->regexps[j+1] = iPtr->regexps[j];
		}
		iPtr->patterns[0] = cachedString;
		iPtr->patLengths[0] = length;
		iPtr->regexps[0] = result;
	    }
	    return (Tcl_RegExp) iPtr->regexps[0];
	}
    }

    /*
     * No match in the cache.  Compile the string and add it to the
     * cache.
     */

    result = CompileRegexp(interp, string, length, REG_ADVANCED);
    if (!result) {
	return NULL;
    }

    /*
     * We successfully compiled the expression, so add it to the cache.
     */

    if (iPtr->patterns[NUM_REGEXPS-1] != NULL) {
	ckfree(iPtr->patterns[NUM_REGEXPS-1]);
	TclReFree(&(iPtr->regexps[NUM_REGEXPS-1]->re));
	ckfree((char *) iPtr->regexps[NUM_REGEXPS-1]);
    }
    for (i = NUM_REGEXPS - 2; i >= 0; i--) {
	iPtr->patterns[i+1] = iPtr->patterns[i];
	iPtr->patLengths[i+1] = iPtr->patLengths[i];
	iPtr->regexps[i+1] = iPtr->regexps[i];
    }
    iPtr->patterns[0] = (char *) ckalloc((unsigned) (length+1));
    strcpy(iPtr->patterns[0], string);
    iPtr->patLengths[0] = length;
    iPtr->regexps[0] = result;
    return (Tcl_RegExp) result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegExpExec --
 *
 *	Execute the regular expression matcher using a compiled form
 *	of a regular expression and save information about any match
 *	that is found.
 *
 * Results:
 *	If an error occurs during the matching operation then -1
 *	is returned and the interp's result contains an error message.
 *	Otherwise the return value is 1 if a matching range is
 *	found and 0 if there is no matching range.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_RegExpExec(interp, re, string, start)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting. */
    Tcl_RegExp re;		/* Compiled regular expression;  must have
				 * been returned by previous call to
				 * Tcl_GetRegExpFromObj. */
    CONST char *string;		/* String against which to match re. */
    CONST char *start;		/* If string is part of a larger string,
				 * this identifies beginning of larger
				 * string, so that "^" won't match. */
{
    int result, numChars;
    Tcl_DString stringBuffer;
    Tcl_UniChar *uniString;

    TclRegexp *regexpPtr = (TclRegexp *) re;

    /*
     * Remember the UTF-8 string so Tcl_RegExpRange() can convert the
     * matches from character to byte offsets.
     */

    regexpPtr->string = string;

    Tcl_DStringInit(&stringBuffer);
    uniString = Tcl_UtfToUniCharDString(string, -1, &stringBuffer);
    numChars = Tcl_DStringLength(&stringBuffer) / sizeof(Tcl_UniChar);

    /*
     * Perform the regexp match.
     */

    result = TclRegExpExecUniChar(interp, re, uniString, numChars, -1,
	    ((string > start) ? REG_NOTBOL : 0));

    Tcl_DStringFree(&stringBuffer);

    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_RegExpRange --
 *
 *	Returns pointers describing the range of a regular expression match,
 *	or one of the subranges within the match.
 *
 * Results:
 *	The variables at *startPtr and *endPtr are modified to hold the
 *	addresses of the endpoints of the range given by index.  If the
 *	specified range doesn't exist then NULLs are returned.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
Tcl_RegExpRange(re, index, startPtr, endPtr)
    Tcl_RegExp re;		/* Compiled regular expression that has
				 * been passed to Tcl_RegExpExec. */
    int index;			/* 0 means give the range of the entire
				 * match, > 0 means give the range of
				 * a matching subrange. */
    char **startPtr;		/* Store address of first character in
				 * (sub-) range here. */
    char **endPtr;		/* Store address of character just after last
				 * in (sub-) range here. */
{
    TclRegexp *regexpPtr = (TclRegexp *) re;

    if ((size_t) index > regexpPtr->re.re_nsub) {
	*startPtr = *endPtr = NULL;
    } else if (regexpPtr->matches[index].rm_so < 0) {
	*startPtr = *endPtr = NULL;
    } else {
	*startPtr = Tcl_UtfAtIndex(regexpPtr->string,
		regexpPtr->matches[index].rm_so);
	*endPtr = Tcl_UtfAtIndex(regexpPtr->string,
		regexpPtr->matches[index].rm_eo);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * TclRegExpExecUniChar --
 *
 *	Execute the regular expression matcher using a compiled form of a
 *	regular expression and save information about any match that is
 *	found.
 *
 * Results:
 *	If an error occurs during the matching operation then -1 is
 *	returned and an error message is left in interp's result.
 *	Otherwise the return value is 1 if a matching range was found or
 *	0 if there was no matching range.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclRegExpExecUniChar(interp, re, wString, numChars, nmatches, flags)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting. */
    Tcl_RegExp re;		/* Compiled regular expression; returned by
				 * a previous call to Tcl_GetRegExpFromObj */
    CONST Tcl_UniChar *wString;	/* String against which to match re. */
    int numChars;		/* Length of Tcl_UniChar string (must
				 * be >= 0). */
    int nmatches;		/* How many subexpression matches (counting
				 * the whole match as subexpression 0) are
				 * of interest.  -1 means "don't know". */
    int flags;			/* Regular expression flags. */
{
    int status;
    TclRegexp *regexpPtr = (TclRegexp *) re;
    size_t nm = regexpPtr->re.re_nsub + 1;

    if (nmatches >= 0 && (size_t) nmatches < nm)
	nm = (size_t) nmatches;

    status = TclReExec(&regexpPtr->re, wString, (size_t) numChars,
	    (rm_detail_t *)NULL, nm, regexpPtr->matches, flags);

    /*
     * Check for errors.
     */

    if (status != REG_OKAY) {
	if (status == REG_NOMATCH) {
	    return 0;
	}
	if (interp != NULL) {
	    TclRegError(interp, "error while matching regular expression: ",
		    status);
	}
	return -1;
    }
    return 1;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclRegExpRangeUniChar --
 *
 *	Returns pointers describing the range of a regular expression match,
 *	or one of the subranges within the match.
 *
 * Results:
 *	The variables at *startPtr and *endPtr are modified to hold the
 *	addresses of the endpoints of the range given by index.  If the
 *	specified range doesn't exist then NULLs are returned.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TclRegExpRangeUniChar(re, index, startPtr, endPtr)
    Tcl_RegExp re;		/* Compiled regular expression that has
				 * been passed to Tcl_RegExpExec. */
    int index;			/* 0 means give the range of the entire
				 * match, > 0 means give the range of
				 * a matching subrange. */
    int *startPtr;		/* Store address of first character in
				 * (sub-) range here. */
    int *endPtr;		/* Store address of character just after last
				 * in (sub-) range here. */
{
    TclRegexp *regexpPtr = (TclRegexp *) re;

    if ((size_t) index > regexpPtr->re.re_nsub) {
	*startPtr = -1;
	*endPtr = -1;
    } else {
	*startPtr = regexpPtr->matches[index].rm_so;
	*endPtr = regexpPtr->matches[index].rm_eo;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegExpMatch --
 *
 *	See if a string matches a regular expression.
 *
 * Results:
 *	If an error occurs during the matching operation then -1
 *	is returned and the interp's result contains an error message.
 *	Otherwise the return value is 1 if "string" matches "pattern"
 *	and 0 otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_RegExpMatch(interp, string, pattern)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* String. */
    char *pattern;		/* Regular expression to match against
				 * string. */
{
    Tcl_RegExp re;

    re = Tcl_RegExpCompile(interp, pattern);
    if (re == NULL) {
	return -1;
    }
    return Tcl_RegExpExec(interp, re, string, string);
}

/*
 *----------------------------------------------------------------------
 *
 * TclRegExpMatchObj --
 *
 *	See if a string matches a regular expression pattern object.
 *
 * Results:
 *	If an error occurs during the matching operation then -1
 *	is returned and the interp's result contains an error message.
 *	Otherwise the return value is 1 if "string" matches "pattern"
 *	and 0 otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclRegExpMatchObj(interp, string, patObj)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* String. */
    Tcl_Obj *patObj;		/* Regular expression to match against
				 * string. */
{
    Tcl_RegExp re;

    re = Tcl_GetRegExpFromObj(interp, patObj, REG_ADVANCED);
    if (re == NULL) {
	return -1;
    }
    return Tcl_RegExpExec(interp, re, string, string);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetRegExpFromObj --
 *
 *	Compile a regular expression into a form suitable for fast
 *	matching.  This procedure caches the result in a Tcl_Obj.
 *
 * Results:
 *	The return value is a pointer to the compiled form of string,
 *	suitable for passing to Tcl_RegExpExec.  If an error occurred
 *	while compiling the pattern, then NULL is returned and an error
 *	message is left in the interp's result.
 *
 * Side effects:
 *	Updates the native rep of the Tcl_Obj.
 *
 *----------------------------------------------------------------------
 */

Tcl_RegExp
Tcl_GetRegExpFromObj(interp, objPtr, flags)
    Tcl_Interp *interp;		/* For use in error reporting. */
    Tcl_Obj *objPtr;		/* Object whose string rep contains regular
				 * expression pattern.  Internal rep will be
				 * changed to compiled form of this regular
				 * expression. */
    int flags;			/* Regular expression compilation flags. */
{
    int length;
    Tcl_ObjType *typePtr;
    TclRegexp *regexpPtr;
    char *pattern;

    typePtr = objPtr->typePtr;
    regexpPtr = (TclRegexp *) objPtr->internalRep.otherValuePtr;

    if ((typePtr != &tclRegexpType) || (regexpPtr->flags != flags)) {
	pattern = Tcl_GetStringFromObj(objPtr, &length);
	regexpPtr = CompileRegexp(interp, pattern, length, flags);
	if (regexpPtr == NULL) {
	    return NULL;
	}

	/*
	 * Free the old representation and set our type.
	 */

	if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	    (*typePtr->freeIntRepProc)(objPtr);
	}
	objPtr->internalRep.otherValuePtr = (VOID *) regexpPtr;
	objPtr->typePtr = &tclRegexpType;
    }
    return (Tcl_RegExp) regexpPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TclRegAbout --
 *
 *	Return information about a compiled regular expression.
 *
 * Results:
 *	The return value is -1 for failure, 0 for success, although at
 *	the moment there's nothing that could fail.  On success, a list
 *	is left in the interp's result:  first element is the subexpression
 *	count, second is a list of re_info bit names.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclRegAbout(interp, re)
    Tcl_Interp *interp;		/* For use in variable assignment. */
    Tcl_RegExp re;		/* The compiled regular expression. */
{
    TclRegexp *regexpPtr = (TclRegexp *)re;
    char buf[TCL_INTEGER_SPACE];
    static struct infoname {
	int bit;
	char *text;
    } infonames[] = {
	{REG_UBACKREF,		"REG_UBACKREF"},
	{REG_ULOOKAHEAD,	"REG_ULOOKAHEAD"},
	{REG_UBOUNDS,		"REG_UBOUNDS"},
	{REG_UBRACES,		"REG_UBRACES"},
	{REG_UBSALNUM,		"REG_UBSALNUM"},
	{REG_UPBOTCH,		"REG_UPBOTCH"},
	{REG_UBBS,		"REG_UBBS"},
	{REG_UNONPOSIX,		"REG_UNONPOSIX"},
	{REG_UUNSPEC,		"REG_UUNSPEC"},
	{REG_UUNPORT,		"REG_UUNPORT"},
	{REG_ULOCALE,		"REG_ULOCALE"},
	{REG_UEMPTYMATCH,	"REG_UEMPTYMATCH"},
	{REG_UIMPOSSIBLE,	"REG_UIMPOSSIBLE"},
	 {0,			""}
    };
    struct infoname *inf;
    int n;

    Tcl_ResetResult(interp);

    sprintf(buf, "%u", (unsigned)(regexpPtr->re.re_nsub));
    Tcl_AppendElement(interp, buf);

    /*
     * Must count bits before generating list, because we must know
     * whether {} are needed before we start appending names.
     */
    n = 0;
    for (inf = infonames; inf->bit != 0; inf++) {
	if (regexpPtr->re.re_info&inf->bit) {
	    n++;
	}
    }
    if (n != 1) {
	Tcl_AppendResult(interp, " {", NULL);
    }
    for (inf = infonames; inf->bit != 0; inf++) {
	if (regexpPtr->re.re_info&inf->bit) {
	    Tcl_AppendElement(interp, inf->text);
	}
    }
    if (n != 1) {
	Tcl_AppendResult(interp, "}", NULL);
    }

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TclRegError --
 *
 *	Generate an error message based on the regexp status code.
 *
 * Results:
 *	Places an error in the interpreter.
 *
 * Side effects:
 *	Sets errorCode as well.
 *
 *----------------------------------------------------------------------
 */

void
TclRegError(interp, msg, status)
    Tcl_Interp *interp;		/* Interpreter for error reporting. */
    char *msg;			/* Message to prepend to error. */
    int status;			/* Status code to report. */
{
    char buf[100];		/* ample in practice */
    char cbuf[100];		/* lots in practice */
    size_t n;
    char *p;

    Tcl_ResetResult(interp);
    n = TclReError(status, (regex_t *)NULL, buf, sizeof(buf));
    p = (n > sizeof(buf)) ? "..." : "";
    Tcl_AppendResult(interp, msg, buf, p, NULL);

    sprintf(cbuf, "%d", status);
    (VOID) TclReError(REG_ITOA, (regex_t *)NULL, cbuf, sizeof(cbuf));
    Tcl_SetErrorCode(interp, "REGEXP", cbuf, buf, NULL);
}


/*
 *----------------------------------------------------------------------
 *
 * FreeRegexpInternalRep --
 *
 *	Deallocate the storage associated with a regexp object's internal
 *	representation.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the compiled regular expression.
 *
 *----------------------------------------------------------------------
 */

static void
FreeRegexpInternalRep(objPtr)
    Tcl_Obj *objPtr;		/* Regexp object with internal rep to free. */
{
    TclRegexp *regexpRepPtr = (TclRegexp *) objPtr->internalRep.otherValuePtr;

    TclReFree(&regexpRepPtr->re);
    if (regexpRepPtr->matches) {
	ckfree((char *) regexpRepPtr->matches);
    }
    ckfree((char *) regexpRepPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * DupRegexpInternalRep --
 *
 *	It is way too hairy to copy a regular expression, so we punt
 *	and revert the object back to a vanilla string. 
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Changes the type back to string.
 *
 *----------------------------------------------------------------------
 */

static void
DupRegexpInternalRep(srcPtr, copyPtr)
    Tcl_Obj *srcPtr;		/* Object with internal rep to copy. */
    Tcl_Obj *copyPtr;		/* Object with internal rep to set. */
{
    copyPtr->internalRep.longValue = (long)copyPtr->length;
    copyPtr->typePtr = &tclStringType;
}

/*
 *----------------------------------------------------------------------
 *
 * SetRegexpFromAny --
 *
 *	Attempt to generate a compiled regular expression for the Tcl object
 *	"objPtr".
 *
 * Results:
 *	The return value is TCL_OK or TCL_ERROR. If an error occurs during
 *	conversion, an error message is left in the interpreter's result
 *	unless "interp" is NULL.
 *
 * Side effects:
 *	If no error occurs, a regular expression is stored as "objPtr"s internal
 *	representation.
 *
 *----------------------------------------------------------------------
 */

static int
SetRegexpFromAny(interp, objPtr)
    Tcl_Interp *interp;		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr;		/* The object to convert. */
{
    if (Tcl_GetRegExpFromObj(interp, objPtr, REG_ADVANCED) == NULL) {
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * CompileRegexp --
 *
 *	Attempt to compile the given regexp pattern
 *
 * Results:
 *	The return value is a pointer to a newly allocated TclRegexp
 *	that represents the compiled pattern, or NULL if the pattern
 *	could not be compiled.  If NULL is returned, an error message is
 *	left in the interp's result.
 *
 * Side effects:
 *	Memory allocated.
 *
 *----------------------------------------------------------------------
 */

static TclRegexp *
CompileRegexp(interp, string, length, flags)
    Tcl_Interp *interp;		/* Used for error reporting if not NULL. */
    char *string;		/* The regexp to compile (UTF-8). */
    int length;			/* The length of the string in bytes. */
    int flags;			/* Compilation flags. */
{
    TclRegexp *regexpPtr;
    Tcl_UniChar *uniString;
    int numChars;
    Tcl_DString stringBuf;
    int status;

    regexpPtr = (TclRegexp *) ckalloc(sizeof(TclRegexp));

    /*
     * Get the up-to-date string representation and map to unicode.
     */

    Tcl_DStringInit(&stringBuf);
    uniString = Tcl_UtfToUniCharDString(string, length, &stringBuf);
    numChars = Tcl_DStringLength(&stringBuf) / sizeof(Tcl_UniChar);

    /*
     * Compile the string and check for errors.
     */

    regexpPtr->flags = flags;
    status = TclReComp(&regexpPtr->re, uniString, (size_t) numChars, flags);
    Tcl_DStringFree(&stringBuf);

    if (status != REG_OKAY) {
	/*
	 * Clean up and report errors in the interpreter, if possible.
	 */
	ckfree((char *)regexpPtr);
	if (interp) {
	    TclRegError(interp,
		    "couldn't compile regular expression pattern: ",
		    status);
	}
	return NULL;
    }

    /*
     * Allocate enough space for all of the subexpressions, plus one
     * extra for the entire pattern.
     */

    regexpPtr->matches = (regmatch_t *) ckalloc(
	    sizeof(regmatch_t) * (regexpPtr->re.re_nsub + 1));

    return regexpPtr;
}

Changes to generic/tclRegexp.h.

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
/*
 * Definitions etc. for regexp(3) routines.
 *
 * Caveat:  this is V8 regexp(3) [actually, a reimplementation thereof],





 * not the System V one.


 *






















 * SCCS: @(#) tclRegexp.h 1.6 96/04/02 18:43:57
 */

#ifndef _REGEXP
#define _REGEXP 1

#ifndef _TCL
#include "tcl.h"




#endif

/*
 * NSUBEXP must be at least 10, and no greater than 117 or the parser
 * will not work properly.

 */

#define NSUBEXP  20

typedef struct regexp {

	char *startp[NSUBEXP];
	char *endp[NSUBEXP];
	char regstart;		/* Internal use only. */
	char reganch;		/* Internal use only. */
	char *regmust;		/* Internal use only. */
	int regmlen;		/* Internal use only. */


	char program[1];	/* Unwarranted chumminess with compiler. */

} regexp;




EXTERN regexp *TclRegComp _ANSI_ARGS_((char *exp));








EXTERN int TclRegExec _ANSI_ARGS_((regexp *prog, char *string, char *start));


EXTERN void TclRegSub _ANSI_ARGS_((regexp *prog, char *source, char *dest));



EXTERN void TclRegError _ANSI_ARGS_((char *msg));
EXTERN char *TclGetRegError _ANSI_ARGS_((void));


#endif /* REGEXP */
|
|

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


|
|

<
|
>
>
>
>



|
|
>


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

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

|
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
/* 
 * tclRegexp.h --
 *
 * 	This file contains definitions used internally by Henry
 *	Spencer's regular expression code.
 *
 * Copyright (c) 1998 Henry Spencer.  All rights reserved.
 * 
 * Development of this software was funded, in part, by Cray Research Inc.,
 * UUNET Communications Services Inc., Sun Microsystems Inc., and
 * Scriptics Corporation, none of whom are responsible for the results.
 * The author thanks all of them.
 * 
 * Redistribution and use in source and binary forms -- with or without
 * modification -- are permitted for any purpose, provided that
 * redistributions in source form retain this entire copyright notice and
 * indicate the origin and nature of any modifications. 
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * Copyright (c) 1998 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: tclRegexp.h,v 1.1.2.5 1999/04/05 22:20:31 rjohnson Exp $
 */

#ifndef _TCLREGEXP
#define _TCLREGEXP


#include "regex.h"

#ifdef BUILD_tcl
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * The TclRegexp structure encapsulates a compiled regex_t,
 * the flags that were used to compile it, and an array of pointers
 * that are used to indicate subexpressions after a call to Tcl_RegExpExec.
 */



typedef struct TclRegexp {
    int flags;			/* Regexp compile flags. */
    regex_t re;			/* Compiled re, includes number of
				 * subexpressions. */
    CONST char *string;		/* Last string matched with this regexp
				 * (UTF-8), so Tcl_RegExpRange() can convert
				 * the matches from character indices to UTF-8
				 * byte offsets. */
    regmatch_t *matches;	/* Array of indices into the Tcl_UniChar
				 * representation of the last string matched
				 * with this regexp to indicate the location
				 * of subexpressions. */
} TclRegexp;

/*
 * Functions exported for use within the rest of Tcl.
 */

EXTERN int		TclRegAbout _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_RegExp re));
EXTERN VOID		TclRegXflags _ANSI_ARGS_((char *string, int length,
			    int *cflagsPtr, int *eflagsPtr));
EXTERN int		TclRegExpExecUniChar _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_RegExp re, CONST Tcl_UniChar *uniString,
			    int numChars, int nmatches, int flags));
EXTERN int		TclRegExpMatchObj _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, Tcl_Obj *patObj));
EXTERN void		TclRegExpRangeUniChar _ANSI_ARGS_((Tcl_RegExp re,
			    int index, int *startPtr, int *endPtr));

/*
 * Functions exported from the regexp package for the test package to use.
 */

EXTERN void		TclRegError _ANSI_ARGS_((Tcl_Interp *interp, char *msg,
			    int status));

#endif /* _TCLREGEXP */

Added generic/tclResolve.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
/*
 * tclResolve.c --
 *
 *      Contains hooks for customized command/variable name resolution
 *      schemes.  These hooks allow extensions like [incr Tcl] to add
 *      their own name resolution rules to the Tcl language.  Rules can
 *      be applied to a particular namespace, to the interpreter as a
 *      whole, or both.
 *
 * Copyright (c) 1998 Lucent Technologies, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclResolve.c,v 1.1.2.2 1998/11/11 04:08:22 stanton Exp $
 */

#include "tclInt.h"

/*
 * Declarations for procedures local to this file:
 */

static void		BumpCmdRefEpochs _ANSI_ARGS_((Namespace *nsPtr));


/*
 *----------------------------------------------------------------------
 *
 * Tcl_AddInterpResolvers --
 *
 *	Adds a set of command/variable resolution procedures to an
 *	interpreter.  These procedures are consulted when commands
 *	are resolved in Tcl_FindCommand, and when variables are
 *	resolved in TclLookupVar and LookupCompiledLocal.  Each
 *	namespace may also have its own set of resolution procedures
 *	which take precedence over those for the interpreter.
 *
 *	When a name is resolved, it is handled as follows.  First,
 *	the name is passed to the resolution procedures for the
 *	namespace.  If not resolved, the name is passed to each of
 *	the resolution procedures added to the interpreter.  Finally,
 *	if still not resolved, the name is handled using the default
 *	Tcl rules for name resolution.
 *
 * Results:
 *	Returns pointers to the current name resolution procedures
 *	in the cmdProcPtr, varProcPtr and compiledVarProcPtr
 *	arguments.
 *
 * Side effects:
 *	If a compiledVarProc is specified, this procedure bumps the
 *	compileEpoch for the interpreter, forcing all code to be
 *	recompiled.  If a cmdProc is specified, this procedure bumps
 *	the cmdRefEpoch in all namespaces, forcing commands to be
 *	resolved again using the new rules.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AddInterpResolvers(interp, name, cmdProc, varProc, compiledVarProc)

    Tcl_Interp *interp;			/* Interpreter whose name resolution
					 * rules are being modified. */
    char *name;				/* Name of this resolution scheme. */
    Tcl_ResolveCmdProc *cmdProc;	/* New procedure for command
					 * resolution */
    Tcl_ResolveVarProc *varProc;	/* Procedure for variable resolution
					 * at runtime */
    Tcl_ResolveCompiledVarProc *compiledVarProc;
					/* Procedure for variable resolution
					 * at compile time. */
{
    Interp *iPtr = (Interp*)interp;
    ResolverScheme *resPtr;

    /*
     *  Since we're adding a new name resolution scheme, we must force
     *  all code to be recompiled to use the new scheme.  If there
     *  are new compiled variable resolution rules, bump the compiler
     *  epoch to invalidate compiled code.  If there are new command
     *  resolution rules, bump the cmdRefEpoch in all namespaces.
     */
    if (compiledVarProc) {
        iPtr->compileEpoch++;
    }
    if (cmdProc) {
        BumpCmdRefEpochs(iPtr->globalNsPtr);
    }

    /*
     *  Look for an existing scheme with the given name.  If found,
     *  then replace its rules.
     */
    for (resPtr = iPtr->resolverPtr; resPtr != NULL; resPtr = resPtr->nextPtr) {
        if (*name == *resPtr->name && strcmp(name, resPtr->name) == 0) {
            resPtr->cmdResProc = cmdProc;
            resPtr->varResProc = varProc;
            resPtr->compiledVarResProc = compiledVarProc;
            return;
        }
    }

    /*
     *  Otherwise, this is a new scheme.  Add it to the FRONT
     *  of the linked list, so that it overrides existing schemes.
     */
    resPtr = (ResolverScheme *) ckalloc(sizeof(ResolverScheme));
    resPtr->name = (char*)ckalloc((unsigned)(strlen(name)+1));
    strcpy(resPtr->name, name);
    resPtr->cmdResProc = cmdProc;
    resPtr->varResProc = varProc;
    resPtr->compiledVarResProc = compiledVarProc;
    resPtr->nextPtr = iPtr->resolverPtr;
    iPtr->resolverPtr = resPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetInterpResolvers --
 *
 *	Looks for a set of command/variable resolution procedures with
 *	the given name in an interpreter.  These procedures are
 *	registered by calling Tcl_AddInterpResolvers.
 *
 * Results:
 *	If the name is recognized, this procedure returns non-zero,
 *	along with pointers to the name resolution procedures in
 *	the Tcl_ResolverInfo structure.  If the name is not recognized,
 *	this procedure returns zero.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetInterpResolvers(interp, name, resInfoPtr)

    Tcl_Interp *interp;			/* Interpreter whose name resolution
					 * rules are being queried. */
    char *name;                         /* Look for a scheme with this name. */
    Tcl_ResolverInfo *resInfoPtr;	/* Returns pointers to the procedures,
					 * if found */
{
    Interp *iPtr = (Interp*)interp;
    ResolverScheme *resPtr;

    /*
     *  Look for an existing scheme with the given name.  If found,
     *  then return pointers to its procedures.
     */
    for (resPtr = iPtr->resolverPtr; resPtr != NULL; resPtr = resPtr->nextPtr) {
        if (*name == *resPtr->name && strcmp(name, resPtr->name) == 0) {
	    resInfoPtr->cmdResProc = resPtr->cmdResProc;
	    resInfoPtr->varResProc = resPtr->varResProc;
	    resInfoPtr->compiledVarResProc = resPtr->compiledVarResProc;
            return 1;
        }
    }

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RemoveInterpResolvers --
 *
 *	Removes a set of command/variable resolution procedures
 *	previously added by Tcl_AddInterpResolvers.  The next time
 *	a command/variable name is resolved, these procedures
 *	won't be consulted.
 *
 * Results:
 *	Returns non-zero if the name was recognized and the
 *	resolution scheme was deleted.  Returns zero otherwise.
 *
 * Side effects:
 *	If a scheme with a compiledVarProc was deleted, this procedure
 *	bumps the compileEpoch for the interpreter, forcing all code
 *	to be recompiled.  If a scheme with a cmdProc was deleted,
 *	this procedure bumps the cmdRefEpoch in all namespaces,
 *	forcing commands to be resolved again using the new rules.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_RemoveInterpResolvers(interp, name)

    Tcl_Interp *interp;			/* Interpreter whose name resolution
					 * rules are being modified. */
    char *name;                         /* Name of the scheme to be removed. */
{
    Interp *iPtr = (Interp*)interp;
    ResolverScheme **prevPtrPtr, *resPtr;

    /*
     *  Look for an existing scheme with the given name.
     */
    prevPtrPtr = &iPtr->resolverPtr;
    for (resPtr = iPtr->resolverPtr; resPtr != NULL; resPtr = resPtr->nextPtr) {
        if (*name == *resPtr->name && strcmp(name, resPtr->name) == 0) {
            break;
        }
        prevPtrPtr = &resPtr->nextPtr;
    }

    /*
     *  If we found the scheme, delete it.
     */
    if (resPtr) {
        /*
         *  If we're deleting a scheme with compiled variable resolution
         *  rules, bump the compiler epoch to invalidate compiled code.
         *  If we're deleting a scheme with command resolution rules,
         *  bump the cmdRefEpoch in all namespaces.
         */
        if (resPtr->compiledVarResProc) {
            iPtr->compileEpoch++;
        }
        if (resPtr->cmdResProc) {
            BumpCmdRefEpochs(iPtr->globalNsPtr);
        }

        *prevPtrPtr = resPtr->nextPtr;
        ckfree(resPtr->name);
        ckfree((char *) resPtr);

        return 1;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * BumpCmdRefEpochs --
 *
 *	This procedure is used to bump the cmdRefEpoch counters in
 *	the specified namespace and all of its child namespaces.
 *	It is used whenever name resolution schemes are added/removed
 *	from an interpreter, to invalidate all command references.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Bumps the cmdRefEpoch in the specified namespace and its
 *	children, recursively.
 *
 *----------------------------------------------------------------------
 */

static void
BumpCmdRefEpochs(nsPtr)
    Namespace *nsPtr;			/* Namespace being modified. */
{
    Tcl_HashEntry *entry;
    Tcl_HashSearch search;
    Namespace *childNsPtr;

    nsPtr->cmdRefEpoch++;

    for (entry = Tcl_FirstHashEntry(&nsPtr->childTable, &search);
	    entry != NULL;
	    entry = Tcl_NextHashEntry(&search)) {

        childNsPtr = (Namespace *) Tcl_GetHashValue(entry);
        BumpCmdRefEpochs(childNsPtr);
    }
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetNamespaceResolvers --
 *
 *	Sets the command/variable resolution procedures for a namespace,
 *	thereby changing the way that command/variable names are
 *	interpreted.  This allows extension writers to support different
 *	name resolution schemes, such as those for object-oriented
 *	packages.
 *
 *	Command resolution is handled by a procedure of the following
 *	type:
 *
 *	  typedef int (Tcl_ResolveCmdProc) _ANSI_ARGS_((
 *		Tcl_Interp* interp, char* name, Tcl_Namespace *context,
 *              int flags, Tcl_Command *rPtr));
 *          
 *	Whenever a command is executed or Tcl_FindCommand is invoked
 *	within the namespace, this procedure is called to resolve the
 *	command name.  If this procedure is able to resolve the name,
 *	it should return the status code TCL_OK, along with the
 *	corresponding Tcl_Command in the rPtr argument.  Otherwise,
 *	the procedure can return TCL_CONTINUE, and the command will
 *	be treated under the usual name resolution rules.  Or, it can
 *	return TCL_ERROR, and the command will be considered invalid.
 *
 *	Variable resolution is handled by two procedures.  The first
 *	is called whenever a variable needs to be resolved at compile
 *	time:
 *
 *        typedef int (Tcl_ResolveCompiledVarProc) _ANSI_ARGS_((
 *	        Tcl_Interp* interp, char* name, Tcl_Namespace *context,
 *	        Tcl_ResolvedVarInfo *rPtr));
 *
 *      If this procedure is able to resolve the name, it should return
 *      the status code TCL_OK, along with variable resolution info in
 *      the rPtr argument; this info will be used to set up compiled
 *	locals in the call frame at runtime.  The procedure may also
 *	return TCL_CONTINUE, and the variable will be treated under
 *	the usual name resolution rules.  Or, it can return TCL_ERROR,
 *	and the variable will be considered invalid.
 *
 *	Another procedure is used whenever a variable needs to be
 *	resolved at runtime but it is not recognized as a compiled local.
 *	(For example, the variable may be requested via
 *	Tcl_FindNamespaceVar.) This procedure has the following type:
 *
 *	  typedef int (Tcl_ResolveVarProc) _ANSI_ARGS_((
 *	        Tcl_Interp* interp, char* name, Tcl_Namespace *context,
 *	        int flags, Tcl_Var *rPtr));
 *
 *	This procedure is quite similar to the compile-time version.
 *	It returns the same status codes, but if variable resolution
 *	succeeds, this procedure returns a Tcl_Var directly via the
 *	rPtr argument.
 *
 * Results:
 *	Nothing.
 *
 * Side effects:
 *	Bumps the command epoch counter for the namespace, invalidating
 *	all command references in that namespace.  Also bumps the
 *	resolver epoch counter for the namespace, forcing all code
 *	in the namespace to be recompiled.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetNamespaceResolvers(namespacePtr, cmdProc, varProc, compiledVarProc)
    Tcl_Namespace *namespacePtr;	/* Namespace whose resolution rules
					 * are being modified. */
    Tcl_ResolveCmdProc *cmdProc;	/* Procedure for command resolution */
    Tcl_ResolveVarProc *varProc;	/* Procedure for variable resolution
					 * at runtime */
    Tcl_ResolveCompiledVarProc *compiledVarProc;
					/* Procedure for variable resolution
					 * at compile time. */
{
    Namespace *nsPtr = (Namespace*)namespacePtr;

    /*
     *  Plug in the new command resolver, and bump the epoch counters
     *  so that all code will have to be recompiled and all commands
     *  will have to be resolved again using the new policy.
     */
    nsPtr->cmdResProc = cmdProc;
    nsPtr->varResProc = varProc;
    nsPtr->compiledVarResProc = compiledVarProc;

    nsPtr->cmdRefEpoch++;
    nsPtr->resolverEpoch++;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetNamespaceResolvers --
 *
 *	Returns the current command/variable resolution procedures
 *	for a namespace.  By default, these procedures are NULL.
 *	New procedures can be installed by calling
 *	Tcl_SetNamespaceResolvers, to provide new name resolution
 *	rules.
 *
 * Results:
 *	Returns non-zero if any name resolution procedures have been
 *	assigned to this namespace; also returns pointers to the
 *	procedures in the Tcl_ResolverInfo structure.  Returns zero
 *	otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_GetNamespaceResolvers(namespacePtr, resInfoPtr)

    Tcl_Namespace *namespacePtr;	/* Namespace whose resolution rules
					 * are being modified. */
    Tcl_ResolverInfo *resInfoPtr;	/* Returns: pointers for all
					 * name resolution procedures
					 * assigned to this namespace. */
{
    Namespace *nsPtr = (Namespace*)namespacePtr;

    resInfoPtr->cmdResProc = nsPtr->cmdResProc;
    resInfoPtr->varResProc = nsPtr->varResProc;
    resInfoPtr->compiledVarResProc = nsPtr->compiledVarResProc;

    if (nsPtr->cmdResProc != NULL ||
        nsPtr->varResProc != NULL ||
        nsPtr->compiledVarResProc != NULL) {
	return 1;
    }
    return 0;
}

Added generic/tclResult.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
/* 
 * tclResult.c --
 *
 *	This file contains code to manage the interpreter result.
 *
 * 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: tclResult.c,v 1.1.2.4 1999/03/10 06:49:21 stanton Exp $
 */

#include "tclInt.h"

/*
 * Function prototypes for local procedures in this file:
 */

static void             ResetObjResult _ANSI_ARGS_((Interp *iPtr));
static void		SetupAppendBuffer _ANSI_ARGS_((Interp *iPtr,
			    int newSpace));


/*
 *----------------------------------------------------------------------
 *
 * Tcl_SaveResult --
 *
 *      Takes a snapshot of the current result state of the interpreter.
 *      The snapshot can be restored at any point by
 *      Tcl_RestoreResult. Note that this routine does not 
 *	preserve the errorCode, errorInfo, or flags fields so it
 *	should not be used if an error is in progress.
 *
 *      Once a snapshot is saved, it must be restored by calling
 *      Tcl_RestoreResult, or discarded by calling
 *      Tcl_DiscardResult.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resets the interpreter result.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SaveResult(interp, statePtr)
    Tcl_Interp *interp;		/* Interpreter to save. */
    Tcl_SavedResult *statePtr;	/* Pointer to state structure. */
{
    Interp *iPtr = (Interp *) interp;

    /*
     * Move the result object into the save state.  Note that we don't need
     * to change its refcount because we're moving it, not adding a new
     * reference.  Put an empty object into the interpreter.
     */

    statePtr->objResultPtr = iPtr->objResultPtr;
    iPtr->objResultPtr = Tcl_NewObj(); 
    Tcl_IncrRefCount(iPtr->objResultPtr); 

    /*
     * Save the string result. 
     */

    statePtr->freeProc = iPtr->freeProc;
    if (iPtr->result == iPtr->resultSpace) {
	/*
	 * Copy the static string data out of the interp buffer.
	 */

	statePtr->result = statePtr->resultSpace;
	strcpy(statePtr->result, iPtr->result);
	statePtr->appendResult = NULL;
    } else if (iPtr->result == iPtr->appendResult) {
	/*
	 * Move the append buffer out of the interp.
	 */

	statePtr->appendResult = iPtr->appendResult;
	statePtr->appendAvl = iPtr->appendAvl;
	statePtr->appendUsed = iPtr->appendUsed;
	statePtr->result = statePtr->appendResult;
	iPtr->appendResult = NULL;
	iPtr->appendAvl = 0;
	iPtr->appendUsed = 0;
    } else {
	/*
	 * Move the dynamic or static string out of the interpreter.
	 */

	statePtr->result = iPtr->result;
	statePtr->appendResult = NULL;
    }

    iPtr->result = iPtr->resultSpace;
    iPtr->resultSpace[0] = 0;
    iPtr->freeProc = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RestoreResult --
 *
 *      Restores the state of the interpreter to a snapshot taken
 *      by Tcl_SaveResult.  After this call, the token for
 *      the interpreter state is no longer valid.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      Restores the interpreter result.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_RestoreResult(interp, statePtr)
    Tcl_Interp* interp;		/* Interpreter being restored. */
    Tcl_SavedResult *statePtr;	/* State returned by Tcl_SaveResult. */
{
    Interp *iPtr = (Interp *) interp;

    Tcl_ResetResult(interp);

    /*
     * Restore the string result.
     */

    iPtr->freeProc = statePtr->freeProc;
    if (statePtr->result == statePtr->resultSpace) {
	/*
	 * Copy the static string data into the interp buffer.
	 */

	iPtr->result = iPtr->resultSpace;
	strcpy(iPtr->result, statePtr->result);
    } else if (statePtr->result == statePtr->appendResult) {
	/*
	 * Move the append buffer back into the interp.
	 */

	if (iPtr->appendResult != NULL) {
	    ckfree((char *)iPtr->appendResult);
	}

	iPtr->appendResult = statePtr->appendResult;
	iPtr->appendAvl = statePtr->appendAvl;
	iPtr->appendUsed = statePtr->appendUsed;
	iPtr->result = iPtr->appendResult;
    } else {
	/*
	 * Move the dynamic or static string back into the interpreter.
	 */

	iPtr->result = statePtr->result;
    }

    /*
     * Restore the object result.
     */

    Tcl_DecrRefCount(iPtr->objResultPtr);
    iPtr->objResultPtr = statePtr->objResultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DiscardResult --
 *
 *      Frees the memory associated with an interpreter snapshot
 *      taken by Tcl_SaveResult.  If the snapshot is not
 *      restored, this procedure must be called to discard it,
 *      or the memory will be lost.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DiscardResult(statePtr)
    Tcl_SavedResult *statePtr;	/* State returned by Tcl_SaveResult. */
{
    TclDecrRefCount(statePtr->objResultPtr);

    if (statePtr->result == statePtr->appendResult) {
	ckfree(statePtr->appendResult);
    } else if (statePtr->freeProc) {
	if ((statePtr->freeProc == TCL_DYNAMIC)
	        || (statePtr->freeProc == (Tcl_FreeProc *) free)) {
	    ckfree(statePtr->result);
	} else {
	    (*statePtr->freeProc)(statePtr->result);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetResult --
 *
 *	Arrange for "string" to be the Tcl return value.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	interp->result is left pointing either to "string" (if "copy" is 0)
 *	or to a copy of string. Also, the object result is reset.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetResult(interp, string, freeProc)
    Tcl_Interp *interp;		/* Interpreter with which to associate the
				 * return value. */
    register char *string;	/* Value to be returned.  If NULL, the
				 * result is set to an empty string. */
    Tcl_FreeProc *freeProc;	/* Gives information about the string:
				 * TCL_STATIC, TCL_VOLATILE, or the address
				 * of a Tcl_FreeProc such as free. */
{
    Interp *iPtr = (Interp *) interp;
    int length;
    register Tcl_FreeProc *oldFreeProc = iPtr->freeProc;
    char *oldResult = iPtr->result;

    if (string == NULL) {
	iPtr->resultSpace[0] = 0;
	iPtr->result = iPtr->resultSpace;
	iPtr->freeProc = 0;
    } else if (freeProc == TCL_VOLATILE) {
	length = strlen(string);
	if (length > TCL_RESULT_SIZE) {
	    iPtr->result = (char *) ckalloc((unsigned) length+1);
	    iPtr->freeProc = TCL_DYNAMIC;
	} else {
	    iPtr->result = iPtr->resultSpace;
	    iPtr->freeProc = 0;
	}
	strcpy(iPtr->result, string);
    } else {
	iPtr->result = string;
	iPtr->freeProc = freeProc;
    }

    /*
     * If the old result was dynamically-allocated, free it up.  Do it
     * here, rather than at the beginning, in case the new result value
     * was part of the old result value.
     */

    if (oldFreeProc != 0) {
	if ((oldFreeProc == TCL_DYNAMIC)
		|| (oldFreeProc == (Tcl_FreeProc *) free)) {
	    ckfree(oldResult);
	} else {
	    (*oldFreeProc)(oldResult);
	}
    }

    /*
     * Reset the object result since we just set the string result.
     */

    ResetObjResult(iPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetStringResult --
 *
 *	Returns an interpreter's result value as a string.
 *
 * Results:
 *	The interpreter's result as a string.
 *
 * Side effects:
 *	If the string result is empty, the object result is moved to the
 *	string result, then the object result is reset.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_GetStringResult(interp)
     register Tcl_Interp *interp; /* Interpreter whose result to return. */
{
    /*
     * If the string result is empty, move the object result to the
     * string result, then reset the object result.
     */
    
    if (*(interp->result) == 0) {
	Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
	        TCL_VOLATILE);
    }
    return interp->result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetObjResult --
 *
 *	Arrange for objPtr to be an interpreter's result value.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	interp->objResultPtr is left pointing to the object referenced
 *	by objPtr. The object's reference count is incremented since
 *	there is now a new reference to it. The reference count for any
 *	old objResultPtr value is decremented. Also, the string result
 *	is reset.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetObjResult(interp, objPtr)
    Tcl_Interp *interp;		/* Interpreter with which to associate the
				 * return object value. */
    register Tcl_Obj *objPtr;	/* Tcl object to be returned. If NULL, the
				 * obj result is made an empty string
				 * object. */
{
    register Interp *iPtr = (Interp *) interp;
    register Tcl_Obj *oldObjResult = iPtr->objResultPtr;

    iPtr->objResultPtr = objPtr;
    Tcl_IncrRefCount(objPtr);	/* since interp result is a reference */

    /*
     * We wait until the end to release the old object result, in case
     * we are setting the result to itself.
     */
    
    TclDecrRefCount(oldObjResult);

    /*
     * Reset the string result since we just set the result object.
     */

    if (iPtr->freeProc != NULL) {
	if ((iPtr->freeProc == TCL_DYNAMIC)
	        || (iPtr->freeProc == (Tcl_FreeProc *) free)) {
	    ckfree(iPtr->result);
	} else {
	    (*iPtr->freeProc)(iPtr->result);
	}
	iPtr->freeProc = 0;
    }
    iPtr->result = iPtr->resultSpace;
    iPtr->resultSpace[0] = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetObjResult --
 *
 *	Returns an interpreter's result value as a Tcl object. The object's
 *	reference count is not modified; the caller must do that if it
 *	needs to hold on to a long-term reference to it.
 *
 * Results:
 *	The interpreter's result as an object.
 *
 * Side effects:
 *	If the interpreter has a non-empty string result, the result object
 *	is either empty or stale because some procedure set interp->result
 *	directly. If so, the string result is moved to the result object
 *	then the string result is reset.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tcl_GetObjResult(interp)
    Tcl_Interp *interp;		/* Interpreter whose result to return. */
{
    register Interp *iPtr = (Interp *) interp;
    Tcl_Obj *objResultPtr;
    int length;

    /*
     * If the string result is non-empty, move the string result to the
     * object result, then reset the string result.
     */
    
    if (*(iPtr->result) != 0) {
	ResetObjResult(iPtr);
	
	objResultPtr = iPtr->objResultPtr;
	length = strlen(iPtr->result);
	TclInitStringRep(objResultPtr, iPtr->result, length);
	
	if (iPtr->freeProc != NULL) {
	    if ((iPtr->freeProc == TCL_DYNAMIC)
	            || (iPtr->freeProc == (Tcl_FreeProc *) free)) {
		ckfree(iPtr->result);
	    } else {
		(*iPtr->freeProc)(iPtr->result);
	    }
	    iPtr->freeProc = 0;
	}
	iPtr->result = iPtr->resultSpace;
	iPtr->resultSpace[0] = 0;
    }
    return iPtr->objResultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppendResultVA --
 *
 *	Append a variable number of strings onto the interpreter's string
 *	result.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The result of the interpreter given by the first argument is
 *	extended by the strings in the va_list (up to a terminating NULL
 *	argument).
 *
 *	If the string result is empty, the object result is moved to the
 *	string result, then the object result is reset.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AppendResultVA (interp, argList)
    Tcl_Interp *interp;		/* Interpreter with which to associate the
				 * return value. */
    va_list argList;		/* Variable argument list. */
{
    Interp *iPtr = (Interp *) interp;
    va_list tmpArgList;
    char *string;
    int newSpace;

    /*
     * If the string result is empty, move the object result to the
     * string result, then reset the object result.
     */

    if (*(iPtr->result) == 0) {
	Tcl_SetResult((Tcl_Interp *) iPtr,
	        TclGetString(Tcl_GetObjResult((Tcl_Interp *) iPtr)),
	        TCL_VOLATILE);
    }
    
    /*
     * Scan through all the arguments to see how much space is needed.
     */

    tmpArgList = argList;
    newSpace = 0;
    while (1) {
	string = va_arg(tmpArgList, char *);
	if (string == NULL) {
	    break;
	}
	newSpace += strlen(string);
    }

    /*
     * If the append buffer isn't already setup and large enough to hold
     * the new data, set it up.
     */

    if ((iPtr->result != iPtr->appendResult)
	    || (iPtr->appendResult[iPtr->appendUsed] != 0)
	    || ((newSpace + iPtr->appendUsed) >= iPtr->appendAvl)) {
       SetupAppendBuffer(iPtr, newSpace);
    }

    /*
     * Now go through all the argument strings again, copying them into the
     * buffer.
     */

    while (1) {
	string = va_arg(argList, char *);
	if (string == NULL) {
	    break;
	}
	strcpy(iPtr->appendResult + iPtr->appendUsed, string);
	iPtr->appendUsed += strlen(string);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppendResult --
 *
 *	Append a variable number of strings onto the interpreter's string
 *	result.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The result of the interpreter given by the first argument is
 *	extended by the strings given by the second and following arguments
 *	(up to a terminating NULL argument).
 *
 *	If the string result is empty, the object result is moved to the
 *	string result, then the object result is reset.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AppendResult TCL_VARARGS_DEF(Tcl_Interp *,arg1)
{
    Tcl_Interp *interp;
    va_list argList;

    interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
    Tcl_AppendResultVA(interp, argList);
    va_end(argList);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppendElement --
 *
 *	Convert a string to a valid Tcl list element and append it to the
 *	result (which is ostensibly a list).
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The result in the interpreter given by the first argument is
 *	extended with a list element converted from string. A separator
 *	space is added before the converted list element unless the current
 *	result is empty, contains the single character "{", or ends in " {".
 *
 *	If the string result is empty, the object result is moved to the
 *	string result, then the object result is reset.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AppendElement(interp, string)
    Tcl_Interp *interp;		/* Interpreter whose result is to be
				 * extended. */
    CONST char *string;		/* String to convert to list element and
				 * add to result. */
{
    Interp *iPtr = (Interp *) interp;
    char *dst;
    int size;
    int flags;

    /*
     * If the string result is empty, move the object result to the
     * string result, then reset the object result.
     */

    if (*(iPtr->result) == 0) {
	Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
	        TCL_VOLATILE);
    }

    /*
     * See how much space is needed, and grow the append buffer if
     * needed to accommodate the list element.
     */

    size = Tcl_ScanElement(string, &flags) + 1;
    if ((iPtr->result != iPtr->appendResult)
	    || (iPtr->appendResult[iPtr->appendUsed] != 0)
	    || ((size + iPtr->appendUsed) >= iPtr->appendAvl)) {
       SetupAppendBuffer(iPtr, size+iPtr->appendUsed);
    }

    /*
     * Convert the string into a list element and copy it to the
     * buffer that's forming, with a space separator if needed.
     */

    dst = iPtr->appendResult + iPtr->appendUsed;
    if (TclNeedSpace(iPtr->appendResult, dst)) {
	iPtr->appendUsed++;
	*dst = ' ';
	dst++;
    }
    iPtr->appendUsed += Tcl_ConvertElement(string, dst, flags);
}

/*
 *----------------------------------------------------------------------
 *
 * SetupAppendBuffer --
 *
 *	This procedure makes sure that there is an append buffer properly
 *	initialized, if necessary, from the interpreter's result, and
 *	that it has at least enough room to accommodate newSpace new
 *	bytes of information.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
SetupAppendBuffer(iPtr, newSpace)
    Interp *iPtr;		/* Interpreter whose result is being set up. */
    int newSpace;		/* Make sure that at least this many bytes
				 * of new information may be added. */
{
    int totalSpace;

    /*
     * Make the append buffer larger, if that's necessary, then copy the
     * result into the append buffer and make the append buffer the official
     * Tcl result.
     */

    if (iPtr->result != iPtr->appendResult) {
	/*
	 * If an oversized buffer was used recently, then free it up
	 * so we go back to a smaller buffer.  This avoids tying up
	 * memory forever after a large operation.
	 */

	if (iPtr->appendAvl > 500) {
	    ckfree(iPtr->appendResult);
	    iPtr->appendResult = NULL;
	    iPtr->appendAvl = 0;
	}
	iPtr->appendUsed = strlen(iPtr->result);
    } else if (iPtr->result[iPtr->appendUsed] != 0) {
	/*
	 * Most likely someone has modified a result created by
	 * Tcl_AppendResult et al. so that it has a different size.
	 * Just recompute the size.
	 */

	iPtr->appendUsed = strlen(iPtr->result);
    }
    
    totalSpace = newSpace + iPtr->appendUsed;
    if (totalSpace >= iPtr->appendAvl) {
	char *new;

	if (totalSpace < 100) {
	    totalSpace = 200;
	} else {
	    totalSpace *= 2;
	}
	new = (char *) ckalloc((unsigned) totalSpace);
	strcpy(new, iPtr->result);
	if (iPtr->appendResult != NULL) {
	    ckfree(iPtr->appendResult);
	}
	iPtr->appendResult = new;
	iPtr->appendAvl = totalSpace;
    } else if (iPtr->result != iPtr->appendResult) {
	strcpy(iPtr->appendResult, iPtr->result);
    }
    
    Tcl_FreeResult((Tcl_Interp *) iPtr);
    iPtr->result = iPtr->appendResult;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FreeResult --
 *
 *	This procedure frees up the memory associated with an interpreter's
 *	string result. It also resets the interpreter's result object.
 *	Tcl_FreeResult is most commonly used when a procedure is about to
 *	replace one result value with another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the memory associated with interp's string result and sets
 *	interp->freeProc to zero, but does not change interp->result or
 *	clear error state. Resets interp's result object to an unshared
 *	empty object.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_FreeResult(interp)
    register Tcl_Interp *interp; /* Interpreter for which to free result. */
{
    register Interp *iPtr = (Interp *) interp;
    
    if (iPtr->freeProc != NULL) {
	if ((iPtr->freeProc == TCL_DYNAMIC)
	        || (iPtr->freeProc == (Tcl_FreeProc *) free)) {
	    ckfree(iPtr->result);
	} else {
	    (*iPtr->freeProc)(iPtr->result);
	}
	iPtr->freeProc = 0;
    }
    
    ResetObjResult(iPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ResetResult --
 *
 *	This procedure resets both the interpreter's string and object
 *	results.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	It resets the result object to an unshared empty object. It
 *	then restores the interpreter's string result area to its default
 *	initialized state, freeing up any memory that may have been
 *	allocated. It also clears any error information for the interpreter.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ResetResult(interp)
    register Tcl_Interp *interp; /* Interpreter for which to clear result. */
{
    register Interp *iPtr = (Interp *) interp;

    ResetObjResult(iPtr);
    if (iPtr->freeProc != NULL) {
	if ((iPtr->freeProc == TCL_DYNAMIC)
	        || (iPtr->freeProc == (Tcl_FreeProc *) free)) {
	    ckfree(iPtr->result);
	} else {
	    (*iPtr->freeProc)(iPtr->result);
	}
	iPtr->freeProc = 0;
    }
    iPtr->result = iPtr->resultSpace;
    iPtr->resultSpace[0] = 0;
    iPtr->flags &= ~(ERR_ALREADY_LOGGED | ERR_IN_PROGRESS | ERROR_CODE_SET);
}

/*
 *----------------------------------------------------------------------
 *
 * ResetObjResult --
 *
 *	Procedure used to reset an interpreter's Tcl result object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resets the interpreter's result object to an unshared empty string
 *	object with ref count one. It does not clear any error information
 *	in the interpreter.
 *
 *----------------------------------------------------------------------
 */

static void
ResetObjResult(iPtr)
    register Interp *iPtr;	/* Points to the interpreter whose result
				 * object should be reset. */
{
    register Tcl_Obj *objResultPtr = iPtr->objResultPtr;

    if (Tcl_IsShared(objResultPtr)) {
	TclDecrRefCount(objResultPtr);
	TclNewObj(objResultPtr);
	Tcl_IncrRefCount(objResultPtr);
	iPtr->objResultPtr = objResultPtr;
    } else {
	if ((objResultPtr->bytes != NULL)
	        && (objResultPtr->bytes != tclEmptyStringRep)) {
	    ckfree((char *) objResultPtr->bytes);
	}
	objResultPtr->bytes  = tclEmptyStringRep;
	objResultPtr->length = 0;
	if ((objResultPtr->typePtr != NULL)
	        && (objResultPtr->typePtr->freeIntRepProc != NULL)) {
	    objResultPtr->typePtr->freeIntRepProc(objResultPtr);
	}
	objResultPtr->typePtr = (Tcl_ObjType *) NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetErrorCodeVA --
 *
 *	This procedure is called to record machine-readable information
 *	about an error that is about to be returned.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The errorCode global variable is modified to hold all of the
 *	arguments to this procedure, in a list form with each argument
 *	becoming one element of the list.  A flag is set internally
 *	to remember that errorCode has been set, so the variable doesn't
 *	get set automatically when the error is returned.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetErrorCodeVA (interp, argList)
    Tcl_Interp *interp;		/* Interpreter in which to access the errorCode
				 * variable. */
    va_list argList;		/* Variable argument list. */
{
    char *string;
    int flags;
    Interp *iPtr = (Interp *) interp;

    /*
     * Scan through the arguments one at a time, appending them to
     * $errorCode as list elements.
     */

    flags = TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT;
    while (1) {
	string = va_arg(argList, char *);
	if (string == NULL) {
	    break;
	}
	(void) Tcl_SetVar2((Tcl_Interp *) iPtr, "errorCode",
		(char *) NULL, string, flags);
	flags |= TCL_APPEND_VALUE;
    }
    iPtr->flags |= ERROR_CODE_SET;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetErrorCode --
 *
 *	This procedure is called to record machine-readable information
 *	about an error that is about to be returned.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The errorCode global variable is modified to hold all of the
 *	arguments to this procedure, in a list form with each argument
 *	becoming one element of the list.  A flag is set internally
 *	to remember that errorCode has been set, so the variable doesn't
 *	get set automatically when the error is returned.
 *
 *----------------------------------------------------------------------
 */
	/* VARARGS2 */
void
Tcl_SetErrorCode TCL_VARARGS_DEF(Tcl_Interp *,arg1)
{
    Tcl_Interp *interp;
    va_list argList;

    /*
     * Scan through the arguments one at a time, appending them to
     * $errorCode as list elements.
     */

    interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
    Tcl_SetErrorCodeVA(interp, argList);
    va_end(argList);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetObjErrorCode --
 *
 *	This procedure is called to record machine-readable information
 *	about an error that is about to be returned. The caller should
 *	build a list object up and pass it to this routine.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The errorCode global variable is modified to be the new value.
 *	A flag is set internally to remember that errorCode has been
 *	set, so the variable doesn't get set automatically when the
 *	error is returned.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetObjErrorCode(interp, errorObjPtr)
    Tcl_Interp *interp;
    Tcl_Obj *errorObjPtr;
{
    Interp *iPtr;
    
    iPtr = (Interp *) interp;
    Tcl_SetVar2Ex(interp, "errorCode", NULL, errorObjPtr, TCL_GLOBAL_ONLY);
    iPtr->flags |= ERROR_CODE_SET;
}

/*
 *-------------------------------------------------------------------------
 *
 * TclTransferResult --
 *
 *	Copy the result (and error information) from one interp to 
 *	another.  Used when one interp has caused another interp to 
 *	evaluate a script and then wants to transfer the results back
 *	to itself.
 *
 *	This routine copies the string reps of the result and error 
 *	information.  It does not simply increment the refcounts of the
 *	result and error information objects themselves.
 *	It is not legal to exchange objects between interps, because an
 *	object may be kept alive by one interp, but have an internal rep 
 *	that is only valid while some other interp is alive.  
 *
 * Results:
 *	The target interp's result is set to a copy of the source interp's
 *	result.  The source's error information "$errorInfo" may be
 *	appended to the target's error information and the source's error
 *	code "$errorCode" may be stored in the target's error code.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */
	
void
TclTransferResult(sourceInterp, result, targetInterp)
    Tcl_Interp *sourceInterp;	/* Interp whose result and error information
				 * should be moved to the target interp.  
				 * After moving result, this interp's result 
				 * is reset. */
    int result;			/* TCL_OK if just the result should be copied, 
				 * TCL_ERROR if both the result and error 
				 * information should be copied. */
    Tcl_Interp *targetInterp;	/* Interp where result and error information 
				 * should be stored.  If source and target
				 * are the same, nothing is done. */
{
    Interp *iPtr;
    Tcl_Obj *objPtr;

    if (sourceInterp == targetInterp) {
	return;
    }

    if (result == TCL_ERROR) {
	/*
	 * An error occurred, so transfer error information from the source
	 * interpreter to the target interpreter.  Setting the flags tells
	 * the target interp that it has inherited a partial traceback
	 * chain, not just a simple error message.
	 */

	iPtr = (Interp *) sourceInterp;
        if ((iPtr->flags & ERR_ALREADY_LOGGED) == 0) {
            Tcl_AddErrorInfo(sourceInterp, "");
        }
        iPtr->flags &= ~(ERR_ALREADY_LOGGED);
        
        Tcl_ResetResult(targetInterp);
        
	objPtr = Tcl_GetVar2Ex(sourceInterp, "errorInfo", NULL,
		TCL_GLOBAL_ONLY);
	Tcl_SetVar2Ex(targetInterp, "errorInfo", NULL, objPtr,
		TCL_GLOBAL_ONLY);

	objPtr = Tcl_GetVar2Ex(sourceInterp, "errorCode", NULL,
		TCL_GLOBAL_ONLY);
	Tcl_SetVar2Ex(targetInterp, "errorCode", NULL, objPtr,
		TCL_GLOBAL_ONLY);

	((Interp *) targetInterp)->flags |= (ERR_IN_PROGRESS | ERROR_CODE_SET);
    }

    ((Interp *) targetInterp)->returnCode = ((Interp *) sourceInterp)->returnCode;
    Tcl_SetObjResult(targetInterp, Tcl_GetObjResult(sourceInterp));
    Tcl_ResetResult(sourceInterp);
}

Added generic/tclScan.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
/* 
 * tclScan.c --
 *
 *	This file contains the implementation of the "scan" command.
 *
 * 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: tclScan.c,v 1.1.2.4 1999/04/02 23:44:57 stanton Exp $
 */

#include "tclInt.h"

/*
 * Flag values used by Tcl_ScanObjCmd.
 */

#define SCAN_NOSKIP	0x1		  /* Don't skip blanks. */
#define SCAN_SUPPRESS	0x2		  /* Suppress assignment. */
#define SCAN_UNSIGNED	0x4		  /* Read an unsigned value. */
#define SCAN_WIDTH	0x8		  /* A width value was supplied. */

#define SCAN_SIGNOK	0x10		  /* A +/- character is allowed. */
#define SCAN_NODIGITS	0x20		  /* No digits have been scanned. */
#define SCAN_NOZERO	0x40		  /* No zero digits have been scanned. */
#define SCAN_XOK	0x80		  /* An 'x' is allowed. */
#define SCAN_PTOK	0x100		  /* Decimal point is allowed. */
#define SCAN_EXPOK	0x200		  /* An exponent is allowed. */


/*
 * The following structure contains the information associated with
 * a character set.
 */

typedef struct CharSet {
    int exclude;		/* 1 if this is an exclusion set. */
    int nchars;
    Tcl_UniChar *chars;
    int nranges;
    struct Range {
	Tcl_UniChar start;
	Tcl_UniChar end;
    } *ranges;
} CharSet;

/*
 * Declarations for functions used only in this file.
 */

static char *	BuildCharSet _ANSI_ARGS_((CharSet *cset, char *format));
static int	CharInSet _ANSI_ARGS_((CharSet *cset, int ch));
static void	ReleaseCharSet _ANSI_ARGS_((CharSet *cset));
static int	ValidateFormat _ANSI_ARGS_((Tcl_Interp *interp, char *format,
		    int numVars));

/*
 *----------------------------------------------------------------------
 *
 * BuildCharSet --
 *
 *	This function examines a character set format specification
 *	and builds a CharSet containing the individual characters and
 *	character ranges specified.
 *
 * Results:
 *	Returns the next format position.
 *
 * Side effects:
 *	Initializes the charset.
 *
 *----------------------------------------------------------------------
 */

static char *
BuildCharSet(cset, format)
    CharSet *cset;
    char *format;		/* Points to first char of set. */
{
    Tcl_UniChar ch, start;
    int offset, nranges;
    char *end;

    memset(cset, 0, sizeof(CharSet));
    
    offset = Tcl_UtfToUniChar(format, &ch);
    if (ch == '^') {
	cset->exclude = 1;
	format += offset;
	offset = Tcl_UtfToUniChar(format, &ch);
    }
    end = format + offset;

    /*
     * Find the close bracket so we can overallocate the set.
     */

    if (ch == ']') {
	end += Tcl_UtfToUniChar(end, &ch);
    }
    nranges = 0;
    while (ch != ']') {
	if (ch == '-') {
	    nranges++;
	}
	end += Tcl_UtfToUniChar(end, &ch);
    }

    cset->chars = (Tcl_UniChar *) ckalloc(sizeof(Tcl_UniChar)
	    * (end - format - 1));
    if (nranges > 0) {
	cset->ranges = (struct Range *) ckalloc(sizeof(struct Range)*nranges);
    } else {
	cset->ranges = NULL;
    }

    /*
     * Now build the character set.
     */

    cset->nchars = cset->nranges = 0;
    format += Tcl_UtfToUniChar(format, &ch);
    start = ch;
    if (ch == ']' || ch == '-') {
	cset->chars[cset->nchars++] = ch;
	format += Tcl_UtfToUniChar(format, &ch);
    }
    while (ch != ']') {
	if (*format == '-') {
	    /*
	     * This may be the first character of a range, so don't add
	     * it yet.
	     */

	    start = ch;
	} else if (ch == '-') {
	    /*
	     * Check to see if this is the last character in the set, in which
	     * case it is not a range and we should add the previous character
	     * as well as the dash.
	     */

	    if (*format == ']') {
		cset->chars[cset->nchars++] = start;
		cset->chars[cset->nchars++] = ch;
	    } else {
		format += Tcl_UtfToUniChar(format, &ch);

		/*
		 * Check to see if the range is in reverse order.
		 */

		if (start < ch) {
		    cset->ranges[cset->nranges].start = start;
		    cset->ranges[cset->nranges].end = ch;
		} else {
		    cset->ranges[cset->nranges].start = ch;
		    cset->ranges[cset->nranges].end = start;
		}		    
		cset->nranges++;
	    }
	} else {
	    cset->chars[cset->nchars++] = ch;
	}
	format += Tcl_UtfToUniChar(format, &ch);
    }
    return format;
}

/*
 *----------------------------------------------------------------------
 *
 * CharInSet --
 *
 *	Check to see if a character matches the given set.
 *
 * Results:
 *	Returns non-zero if the character matches the given set.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
CharInSet(cset, c)
    CharSet *cset;
    int c;			/* Character to test, passed as int because
				 * of non-ANSI prototypes. */
{
    Tcl_UniChar ch = (Tcl_UniChar) c;
    int i, match = 0;
    for (i = 0; i < cset->nchars; i++) {
	if (cset->chars[i] == ch) {
	    match = 1;
	    break;
	}
    }
    if (!match) {
	for (i = 0; i < cset->nranges; i++) {
	    if ((cset->ranges[i].start <= ch)
		    && (ch <= cset->ranges[i].end)) {
		match = 1;
		break;
	    }
	}
    }
    return (cset->exclude ? !match : match);    
}

/*
 *----------------------------------------------------------------------
 *
 * ReleaseCharSet --
 *
 *	Free the storage associated with a character set.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
ReleaseCharSet(cset)
    CharSet *cset;
{
    ckfree((char *)cset->chars);
    if (cset->ranges) {
	ckfree((char *)cset->ranges);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ValidateFormat --
 *
 *	Parse the format string and verify that it is properly formed
 *	and that there are exactly enough variables on the command line.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	May place an error in the interpreter result.
 *
 *----------------------------------------------------------------------
 */

static int
ValidateFormat(interp, format, numVars)
    Tcl_Interp *interp;		/* Current interpreter. */
    char *format;		/* The format string. */
    int numVars;		/* The number of variables passed to the
				 * scan command. */
{
    int gotXpg, gotSequential, value, i, flags;
    char *end;
    Tcl_UniChar ch;
    int *nassign = (int*)ckalloc(sizeof(int) * numVars);
    int objIndex;

    /*
     * Initialize an array that records the number of times a variable
     * is assigned to by the format string.  We use this to detect if
     * a variable is multiply assigned or left unassigned.
     */

    for (i = 0; i < numVars; i++) {
	nassign[i] = 0;
    }

    objIndex = gotXpg = gotSequential = 0;

    while (*format != '\0') {
	format += Tcl_UtfToUniChar(format, &ch);

	flags = 0;

	if (ch != '%') {
	    continue;
	}
	format += Tcl_UtfToUniChar(format, &ch);
	if (ch == '%') {
	    continue;
	}
	if (ch == '*') {
	    flags |= SCAN_SUPPRESS;
	    format += Tcl_UtfToUniChar(format, &ch);
	    goto xpgCheckDone;
	}

	if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */
	    /*
	     * Check for an XPG3-style %n$ specification.  Note: there
	     * must not be a mixture of XPG3 specs and non-XPG3 specs
	     * in the same format string.
	     */

	    value = strtoul(format-1, &end, 10); /* INTL: "C" locale. */
	    if (*end != '$') {
		goto notXpg;
	    }
	    format = end+1;
	    format += Tcl_UtfToUniChar(format, &ch);
	    gotXpg = 1;
	    if (gotSequential) {
		goto mixedXPG;
	    }
	    objIndex = value - 1;
	    if ((objIndex < 0) || (objIndex >= numVars)) {
		goto badIndex;
	    }
	    goto xpgCheckDone;
	}

	notXpg:
	gotSequential = 1;
	if (gotXpg) {
	    mixedXPG:
	    Tcl_SetResult(interp,
		    "cannot mix \"%\" and \"%n$\" conversion specifiers",
		    TCL_STATIC);
	    goto error;
	}

	xpgCheckDone:
	/*
	 * Parse any width specifier.
	 */

	if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */
	    value = strtoul(format-1, &format, 10); /* INTL: "C" locale. */
	    flags |= SCAN_WIDTH;
	    format += Tcl_UtfToUniChar(format, &ch);
	}

	/*
	 * Ignore size specifier.
	 */

 	if ((ch == 'l') || (ch == 'L') || (ch == 'h')) {
	    format += Tcl_UtfToUniChar(format, &ch);
	}

	if (!(flags & SCAN_SUPPRESS) && objIndex >= numVars) {
	    goto badIndex;
	}

	/*
	 * Handle the various field types.
	 */

	switch (ch) {
	    case 'n':
	    case 'd':
	    case 'i':
	    case 'o':
	    case 'x':
	    case 'u':
	    case 'f':
	    case 'e':
	    case 'g':
	    case 's':
		break;
	    case 'c':
                if (flags & SCAN_WIDTH) {
		    Tcl_SetResult(interp, "field width may not be specified in %c conversion", TCL_STATIC);
		    goto error;
                }
		break;
	    case '[':
		if (*format == '\0') {
		    goto badSet;
		}
		format += Tcl_UtfToUniChar(format, &ch);
		if (ch == '^') {
		    if (*format == '\0') {
			goto badSet;
		    }
		    format += Tcl_UtfToUniChar(format, &ch);
		}
		if (ch == ']') {
		    if (*format == '\0') {
			goto badSet;
		    }
		    format += Tcl_UtfToUniChar(format, &ch);
		}
		while (ch != ']') {
		    if (*format == '\0') {
			goto badSet;
		    }
		    format += Tcl_UtfToUniChar(format, &ch);
		}
		break;
	    badSet:
		Tcl_SetResult(interp, "unmatched [ in format string",
			TCL_STATIC);
		goto error;
	    default:
	    {
		char buf[TCL_UTF_MAX+1];

		buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"bad scan conversion character \"", buf, "\"", NULL);
		goto error;
	    }
	}
	if (!(flags & SCAN_SUPPRESS)) {
	    nassign[objIndex]++;
	    objIndex++;
	}
    }

    /*
     * Verify that all of the variable were assigned exactly once.
     */

    for (i = 0; i < numVars; i++) {
	if (nassign[i] > 1) {
	    Tcl_SetResult(interp, "variable is assigned by multiple \"%n$\" conversion specifiers", TCL_STATIC);
	    goto error;
	} else if (nassign[i] == 0) {
	    Tcl_SetResult(interp, "variable is not assigend by any conversion specifiers", TCL_STATIC);
	    goto error;
	}
    }

    ckfree((char *)nassign);
    return TCL_OK;

    badIndex:
    if (gotXpg) {
	Tcl_SetResult(interp, "\"%n$\" argument index out of range",
		TCL_STATIC);
    } else {
	Tcl_SetResult(interp, 
		"different numbers of variable names and field specifiers",
		TCL_STATIC);
    }

    error:
    ckfree((char *)nassign);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ScanObjCmd --
 *
 *	This procedure is invoked to process the "scan" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_ScanObjCmd(dummy, interp, objc, objv)
    ClientData dummy;    	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    char *format;
    int numVars, nconversions;
    int objIndex, offset, i, value, result, code;
    char *string, *end, *baseString;
    char op = 0;
    int base = 0;
    int underflow = 0;
    size_t width;
    long (*fn)() = NULL;
    Tcl_UniChar ch, sch;
    Tcl_Obj **objs, *objPtr;
    int flags;
    char buf[513];			  /* Temporary buffer to hold scanned
					   * number strings before they are
					   * passed to strtoul. */

    if (objc < 3) {
        Tcl_WrongNumArgs(interp, 1, objv,
		"string format ?varName varName ...?");
	return TCL_ERROR;
    }

    format = Tcl_GetStringFromObj(objv[2], NULL);
    numVars = objc-3;

    /*
     * Check for errors in the format string.
     */
    
    if (ValidateFormat(interp, format, numVars) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * Allocate space for the result objects.
     */
    
    objs = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj*) * numVars);
    for (i = 0; i < numVars; i++) {
	objs[i] = NULL;
    }

    string = Tcl_GetStringFromObj(objv[1], NULL);
    baseString = string;

    /*
     * Iterate over the format string filling in the result objects until
     * we reach the end of input, the end of the format string, or there
     * is a mismatch.
     */

    objIndex = 0;
    nconversions = 0;
    while (*format != '\0') {
	format += Tcl_UtfToUniChar(format, &ch);

	flags = 0;

	/*
	 * If we see whitespace in the format, skip whitespace in the string.
	 */

	if (Tcl_UniCharIsSpace(ch)) {
	    offset = Tcl_UtfToUniChar(string, &sch);
	    while (Tcl_UniCharIsSpace(sch)) {
		if (*string == '\0') {
		    goto done;
		}
		string += offset;
		offset = Tcl_UtfToUniChar(string, &sch);
	    }
	    continue;
	}
	    
	if (ch != '%') {
	    literal:
	    if (*string == '\0') {
		underflow = 1;
		goto done;
	    }
	    string += Tcl_UtfToUniChar(string, &sch);
	    if (ch != sch) {
		goto done;
	    }
	    continue;
	}

	format += Tcl_UtfToUniChar(format, &ch);
	if (ch == '%') {
	    goto literal;
	}

	/*
	 * Check for assignment suppression ('*') or an XPG3-style
	 * assignment ('%n$').
	 */

	if (ch == '*') {
	    flags |= SCAN_SUPPRESS;
	    format += Tcl_UtfToUniChar(format, &ch);
	} else if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */
	    value = strtoul(format-1, &end, 10); /* INTL: "C" locale. */
	    if (*end == '$') {
		format = end+1;
		format += Tcl_UtfToUniChar(format, &ch);
		objIndex = value - 1;
	    }
	}

	/*
	 * Parse any width specifier.
	 */

	if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */
	    width = strtoul(format-1, &format, 10); /* INTL: "C" locale. */
	    format += Tcl_UtfToUniChar(format, &ch);
	} else {
	    width = 0;
	}

	/*
	 * Ignore size specifier.
	 */

 	if ((ch == 'l') || (ch == 'L') || (ch == 'h')) {
	    format += Tcl_UtfToUniChar(format, &ch);
	}

	/*
	 * Handle the various field types.
	 */

	switch (ch) {
	    case 'n':
		if (!(flags & SCAN_SUPPRESS)) {
		    objPtr = Tcl_NewIntObj(string - baseString);
		    Tcl_IncrRefCount(objPtr);
		    objs[objIndex++] = objPtr;
		}
		nconversions++;
		continue;

	    case 'd':
		op = 'i';
		base = 10;
		fn = (long (*)())strtol;
		break;
	    case 'i':
		op = 'i';
		base = 0;
		fn = (long (*)())strtol;
		break;
	    case 'o':
		op = 'i';
		base = 8;
		fn = (long (*)())strtol;
		break;
	    case 'x':
		op = 'i';
		base = 16;
		fn = (long (*)())strtol;
		break;
	    case 'u':
		op = 'i';
		base = 10;
		flags |= SCAN_UNSIGNED;
		fn = (long (*)())strtoul;
		break;

	    case 'f':
	    case 'e':
	    case 'g':
		op = 'f';
		break;

	    case 's':
		op = 's';
		break;

	    case 'c':
		op = 'c';
		flags |= SCAN_NOSKIP;
		break;
	    case '[':
		op = '[';
		flags |= SCAN_NOSKIP;
		break;
	}

	/*
	 * At this point, we will need additional characters from the
	 * string to proceed.
	 */

	if (*string == '\0') {
	    underflow = 1;
	    goto done;
	}
	
	/*
	 * Skip any leading whitespace at the beginning of a field unless
	 * the format suppresses this behavior.
	 */

	if (!(flags & SCAN_NOSKIP)) {
	    while (*string != '\0') {
		offset = Tcl_UtfToUniChar(string, &sch);
		if (!Tcl_UniCharIsSpace(sch)) {
		    break;
		}
		string += offset;
	    }
	    if (*string == '\0') {
		underflow = 1;
		goto done;
	    }
	}

	/*
	 * Perform the requested scanning operation.
	 */
	
	switch (op) {
	    case 's':
		/*
		 * Scan a string up to width characters or whitespace.
		 */

		if (width == 0) {
		    width = (size_t) ~0;
		}
		end = string;
		while (*end != '\0') {
		    offset = Tcl_UtfToUniChar(end, &sch);
		    if (Tcl_UniCharIsSpace(sch)) {
			break;
		    }
		    end += offset;
		    if (--width == 0) {
			break;
		    }
		}
		if (!(flags & SCAN_SUPPRESS)) {
		    objPtr = Tcl_NewStringObj(string, end-string);
		    Tcl_IncrRefCount(objPtr);
		    objs[objIndex++] = objPtr;
		}
		string = end;
		break;

	    case '[': {
		CharSet cset;

		if (width == 0) {
		    width = (size_t) ~0;
		}
		end = string;

		format = BuildCharSet(&cset, format);
		while (*end != '\0') {
		    offset = Tcl_UtfToUniChar(end, &sch);
		    if (!CharInSet(&cset, (int)sch)) {
			break;
		    }
		    end += offset;
		    if (--width == 0) {
			break;
		    }
		}
		ReleaseCharSet(&cset);

		if (!(flags & SCAN_SUPPRESS)) {
		    objPtr = Tcl_NewStringObj(string, end-string);
		    Tcl_IncrRefCount(objPtr);
		    objs[objIndex++] = objPtr;
		}
		string = end;
		
		break;
	    }
	    case 'c':
		/*
		 * Scan a single Unicode character.
		 */

		string += Tcl_UtfToUniChar(string, &sch);
		if (!(flags & SCAN_SUPPRESS)) {
		    objPtr = Tcl_NewIntObj((int)sch);
		    Tcl_IncrRefCount(objPtr);
		    objs[objIndex++] = objPtr;
		}
		break;

	    case 'i':
		/*
		 * Scan an unsigned or signed integer.
		 */

		if ((width == 0) || (width > sizeof(buf) - 1)) {
		    width = sizeof(buf) - 1;
		}
		flags |= SCAN_SIGNOK | SCAN_NODIGITS | SCAN_NOZERO;
		for (end = buf; width > 0; width--) {
		    switch (*string) {
			/*
			 * The 0 digit has special meaning at the beginning of
			 * a number.  If we are unsure of the base, it
			 * indicates that we are in base 8 or base 16 (if it is
			 * followed by an 'x').
			 */
			case '0':
			    if (base == 0) {
				base = 8;
				flags |= SCAN_XOK;
			    }
			    if (flags & SCAN_NOZERO) {
				flags &= ~(SCAN_SIGNOK | SCAN_NODIGITS
					| SCAN_NOZERO);
			    } else {
				flags &= ~(SCAN_SIGNOK | SCAN_XOK
					| SCAN_NODIGITS);
			    }
			    goto addToInt;

			case '1': case '2': case '3': case '4':
			case '5': case '6': case '7':
			    if (base == 0) {
				base = 10;
			    }
			    flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
			    goto addToInt;

			case '8': case '9':
			    if (base == 0) {
				base = 10;
			    }
			    if (base <= 8) {
				break;
			    }
			    flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
			    goto addToInt;

			case 'A': case 'B': case 'C':
			case 'D': case 'E': case 'F': 
			case 'a': case 'b': case 'c':
			case 'd': case 'e': case 'f':
			    if (base <= 10) {
				break;
			    }
			    flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
			    goto addToInt;

			case '+': case '-':
			    if (flags & SCAN_SIGNOK) {
				flags &= ~SCAN_SIGNOK;
				goto addToInt;
			    }
			    break;

			case 'x': case 'X':
			    if ((flags & SCAN_XOK) && (end == buf+1)) {
				base = 16;
				flags &= ~SCAN_XOK;
				goto addToInt;
			    }
			    break;
		    }

		    /*
		     * We got an illegal character so we are done accumulating.
		     */

		    break;

		    addToInt:
		    /*
		     * Add the character to the temporary buffer.
		     */

		    *end++ = *string++;
		    if (*string == '\0') {
			break;
		    }
		}

		/*
		 * Check to see if we need to back up because we only got a
		 * sign or a trailing x after a 0.
		 */

		if (flags & SCAN_NODIGITS) {
		    if (*string == '\0') {
			underflow = 1;
		    }
		    goto done;
		} else if (end[-1] == 'x' || end[-1] == 'X') {
		    end--;
		    string--;
		}


		/*
		 * Scan the value from the temporary buffer.  If we are
		 * returning a large unsigned value, we have to convert it back
		 * to a string since Tcl only supports signed values.
		 */

		if (!(flags & SCAN_SUPPRESS)) {
		    *end = '\0';
		    value = (int) (*fn)(buf, NULL, base);
		    if ((flags & SCAN_UNSIGNED) && (value < 0)) {
			sprintf(buf, "%u", value); /* INTL: ISO digit */
			objPtr = Tcl_NewStringObj(buf, -1);
		    } else {
			objPtr = Tcl_NewIntObj(value);
		    }
		    Tcl_IncrRefCount(objPtr);
		    objs[objIndex++] = objPtr;
		}

		break;

	    case 'f':
		/*
		 * Scan a floating point number
		 */

		if ((width == 0) || (width > sizeof(buf) - 1)) {
		    width = sizeof(buf) - 1;
		}
		flags |= SCAN_SIGNOK | SCAN_NODIGITS | SCAN_PTOK | SCAN_EXPOK;
		for (end = buf; width > 0; width--) {
		    switch (*string) {
			case '0': case '1': case '2': case '3':
			case '4': case '5': case '6': case '7':
			case '8': case '9':
			    flags &= ~(SCAN_SIGNOK | SCAN_NODIGITS);
			    goto addToFloat;
			case '+': case '-':
			    if (flags & SCAN_SIGNOK) {
				flags &= ~SCAN_SIGNOK;
				goto addToFloat;
			    }
			    break;
			case '.':
			    if (flags & SCAN_PTOK) {
				flags &= ~(SCAN_SIGNOK | SCAN_PTOK);
				goto addToFloat;
			    }
			    break;
			case 'e': case 'E':
			    /*
			     * An exponent is not allowed until there has
			     * been at least one digit.
			     */

			    if ((flags & (SCAN_NODIGITS | SCAN_EXPOK))
				    == SCAN_EXPOK) {
				flags = (flags & ~(SCAN_EXPOK|SCAN_PTOK))
				    | SCAN_SIGNOK | SCAN_NODIGITS;
				goto addToFloat;
			    }
			    break;
		    }

		    /*
		     * We got an illegal character so we are done accumulating.
		     */

		    break;

		    addToFloat:
		    /*
		     * Add the character to the temporary buffer.
		     */

		    *end++ = *string++;
		    if (*string == '\0') {
			break;
		    }
		}

		/*
		 * Check to see if we need to back up because we saw a
		 * trailing 'e' or sign.
		 */

		if (flags & SCAN_NODIGITS) {
		    if (flags & SCAN_EXPOK) {
			/*
			 * There were no digits at all so scanning has
			 * failed and we are done.
			 */
			if (*string == '\0') {
			    underflow = 1;
			}
			goto done;
		    }

		    /*
		     * We got a bad exponent ('e' and maybe a sign).
		     */

		    end--;
		    string--;
		    if (*end != 'e' && *end != 'E') {
			end--;
			string--;
		    }
		}

		/*
		 * Scan the value from the temporary buffer.
		 */

		if (!(flags & SCAN_SUPPRESS)) {
		    double dvalue;
		    *end = '\0';
		    dvalue = strtod(buf, NULL);
		    objPtr = Tcl_NewDoubleObj(dvalue);
		    Tcl_IncrRefCount(objPtr);
		    objs[objIndex++] = objPtr;
		}
		break;
	}
	nconversions++;
    }

    done:
    result = 0;
    code = TCL_OK;

    for (i = 0; i < numVars; i++) {
	if (objs[i] != NULL) {
	    result++;
	    if (Tcl_ObjSetVar2(interp, objv[i+3], NULL, objs[i], 0) == NULL) {
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"couldn't set variable \"",
			Tcl_GetString(objv[i+3]), "\"", (char *) NULL);
		code = TCL_ERROR;
	    }
	    Tcl_DecrRefCount(objs[i]);
	}
    }
    ckfree((char*) objs);
    if (code == TCL_OK) {
	if (underflow && (nconversions == 0)) {
	    result = -1;
	}
	Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
    }
    return code;
}

Changes to generic/tclStringObj.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *	representation are called "expandable string objects".
 *
 * 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.
 *
 * SCCS: @(#) tclStringObj.c 1.31 97/10/30 13:56:35
 */

#include "tclInt.h"

/*
 * Prototypes for procedures defined later in this file:
 */







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *	representation are called "expandable string objects".
 *
 * 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: tclStringObj.c,v 1.1.2.3 1999/03/10 06:49:21 stanton Exp $
 */

#include "tclInt.h"

/*
 * Prototypes for procedures defined later in this file:
 */
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
 */

#ifdef TCL_MEM_DEBUG
#undef Tcl_NewStringObj

Tcl_Obj *
Tcl_NewStringObj(bytes, length)
    register char *bytes;	/* Points to the first of the length bytes
				 * used to initialize the new object. */
    register int length;	/* The number of bytes to copy from "bytes"
				 * when initializing the new object. If 
				 * negative, use bytes up to the first
				 * NULL byte. */
{
    return Tcl_DbNewStringObj(bytes, length, "unknown", 0);
}

#else /* if not TCL_MEM_DEBUG */

Tcl_Obj *
Tcl_NewStringObj(bytes, length)
    register char *bytes;	/* Points to the first of the length bytes
				 * used to initialize the new object. */
    register int length;	/* The number of bytes to copy from "bytes"
				 * when initializing the new object. If 
				 * negative, use bytes up to the first
				 * NULL byte. */
{
    register Tcl_Obj *objPtr;

    if (length < 0) {







|

|











|

|







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

#ifdef TCL_MEM_DEBUG
#undef Tcl_NewStringObj

Tcl_Obj *
Tcl_NewStringObj(bytes, length)
    CONST char *bytes;		/* Points to the first of the length bytes
				 * used to initialize the new object. */
    int length;			/* The number of bytes to copy from "bytes"
				 * when initializing the new object. If 
				 * negative, use bytes up to the first
				 * NULL byte. */
{
    return Tcl_DbNewStringObj(bytes, length, "unknown", 0);
}

#else /* if not TCL_MEM_DEBUG */

Tcl_Obj *
Tcl_NewStringObj(bytes, length)
    CONST char *bytes;		/* Points to the first of the length bytes
				 * used to initialize the new object. */
    int length;			/* The number of bytes to copy from "bytes"
				 * when initializing the new object. If 
				 * negative, use bytes up to the first
				 * NULL byte. */
{
    register Tcl_Obj *objPtr;

    if (length < 0) {
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
 *----------------------------------------------------------------------
 */

#ifdef TCL_MEM_DEBUG

Tcl_Obj *
Tcl_DbNewStringObj(bytes, length, file, line)
    register char *bytes;	/* Points to the first of the length bytes
				 * used to initialize the new object. */
    register int length;	/* The number of bytes to copy from "bytes"
				 * when initializing the new object. If 
				 * negative, use bytes up to the first
				 * NULL byte. */
    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
    int line;			/* Line number in the source file; used
				 * for debugging. */







|

|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
 *----------------------------------------------------------------------
 */

#ifdef TCL_MEM_DEBUG

Tcl_Obj *
Tcl_DbNewStringObj(bytes, length, file, line)
    CONST char *bytes;		/* Points to the first of the length bytes
				 * used to initialize the new object. */
    int length;			/* The number of bytes to copy from "bytes"
				 * when initializing the new object. If 
				 * negative, use bytes up to the first
				 * NULL byte. */
    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
    int line;			/* Line number in the source file; used
				 * for debugging. */
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    return objPtr;
}

#else /* if not TCL_MEM_DEBUG */

Tcl_Obj *
Tcl_DbNewStringObj(bytes, length, file, line)
    register char *bytes;	/* Points to the first of the length bytes
				 * used to initialize the new object. */
    register int length;	/* The number of bytes to copy from "bytes"
				 * when initializing the new object. If 
				 * negative, use bytes up to the first
				 * NULL byte. */
    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */







|







161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    return objPtr;
}

#else /* if not TCL_MEM_DEBUG */

Tcl_Obj *
Tcl_DbNewStringObj(bytes, length, file, line)
    CONST char *bytes;		/* Points to the first of the length bytes
				 * used to initialize the new object. */
    register int length;	/* The number of bytes to copy from "bytes"
				 * when initializing the new object. If 
				 * negative, use bytes up to the first
				 * NULL byte. */
    char *file;			/* The name of the source file calling this
				 * procedure; used for debugging. */
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

    if (Tcl_IsShared(objPtr)) {
	panic("Tcl_SetStringObj called with shared object");
    }

    Tcl_InvalidateStringRep(objPtr);
    if (length < 0) {
	length = strlen(bytes);
    }
    TclInitStringRep(objPtr, bytes, length);
        
    /*
     * Set the type to NULL and free any internal rep for the old type.
     */








|







220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

    if (Tcl_IsShared(objPtr)) {
	panic("Tcl_SetStringObj called with shared object");
    }

    Tcl_InvalidateStringRep(objPtr);
    if (length < 0) {
	length = (bytes? strlen(bytes) : 0);
    }
    TclInitStringRep(objPtr, bytes, length);
        
    /*
     * Set the type to NULL and free any internal rep for the old type.
     */

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
    if (Tcl_IsShared(objPtr)) {
	panic("Tcl_AppendToObj called with shared object");
    }
    if (objPtr->typePtr != &tclStringType) {
	ConvertToStringType(objPtr);
    }
    if (length < 0) {
	length = strlen(bytes);
    }
    if (length == 0) {
	return;
    }
    oldLength = objPtr->length;
    newLength = length + oldLength;
    if ((long)newLength > objPtr->internalRep.longValue) {







|







331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
    if (Tcl_IsShared(objPtr)) {
	panic("Tcl_AppendToObj called with shared object");
    }
    if (objPtr->typePtr != &tclStringType) {
	ConvertToStringType(objPtr);
    }
    if (length < 0) {
	length = (bytes? strlen(bytes) : 0);
    }
    if (length == 0) {
	return;
    }
    oldLength = objPtr->length;
    newLength = length + oldLength;
    if ((long)newLength > objPtr->internalRep.longValue) {
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
	objPtr->bytes[objPtr->length] = 0;
    }
}

/*
 *----------------------------------------------------------------------
 *





























 * Tcl_AppendStringsToObj --
 *
 *	This procedure appends one or more null-terminated strings
 *	to an object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The contents of all the string arguments are appended to the
 *	string representation of objPtr.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AppendStringsToObj TCL_VARARGS_DEF(Tcl_Obj *,arg1)


{
    va_list argList;
    register Tcl_Obj *objPtr;
    int newLength, oldLength;
    register char *string, *dst;

    objPtr = (Tcl_Obj *) TCL_VARARGS_START(Tcl_Obj *,arg1,argList);
    if (Tcl_IsShared(objPtr)) {
	panic("Tcl_AppendStringsToObj called with shared object");
    }
    if (objPtr->typePtr != &tclStringType) {
	ConvertToStringType(objPtr);
    }

    /*
     * Figure out how much space is needed for all the strings, and
     * expand the string representation if it isn't big enough. If no
     * bytes would be appended, just return.
     */


    newLength = oldLength = objPtr->length;
    while (1) {
	string = va_arg(argList, char *);
	if (string == NULL) {
	    break;
	}
	newLength += strlen(string);
    }
    if (newLength == oldLength) {
	return;







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















|
>
>

|
<



<













>


|







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417
418

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
	objPtr->bytes[objPtr->length] = 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppendObjToObj --
 *
 *	This procedure appends the string rep of one object to another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The string rep of appendObjPtr is appended to the string 
 *	representation of objPtr.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AppendObjToObj(objPtr, appendObjPtr)
    Tcl_Obj *objPtr;		/* Points to the object to append to. */
    Tcl_Obj *appendObjPtr;	/* Object to append. */
{
    int length;
    char *stringRep;

    stringRep = Tcl_GetStringFromObj(appendObjPtr, &length);
    Tcl_AppendToObj(objPtr, stringRep, length);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppendStringsToObjVA --
 *
 *	This procedure appends one or more null-terminated strings
 *	to an object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The contents of all the string arguments are appended to the
 *	string representation of objPtr.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AppendStringsToObjVA (objPtr, argList)
    Tcl_Obj *objPtr;		/* Points to the object to append to. */
    va_list argList;		/* Variable argument list. */
{
    va_list tmpArgList;

    int newLength, oldLength;
    register char *string, *dst;


    if (Tcl_IsShared(objPtr)) {
	panic("Tcl_AppendStringsToObj called with shared object");
    }
    if (objPtr->typePtr != &tclStringType) {
	ConvertToStringType(objPtr);
    }

    /*
     * Figure out how much space is needed for all the strings, and
     * expand the string representation if it isn't big enough. If no
     * bytes would be appended, just return.
     */

    tmpArgList = argList;
    newLength = oldLength = objPtr->length;
    while (1) {
	string = va_arg(tmpArgList, char *);
	if (string == NULL) {
	    break;
	}
	newLength += strlen(string);
    }
    if (newLength == oldLength) {
	return;
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
    }

    /*
     * Make a second pass through the arguments, appending all the
     * strings to the object.
     */

    TCL_VARARGS_START(Tcl_Obj *,arg1,argList);
    dst = objPtr->bytes + oldLength;
    while (1) {
	string = va_arg(argList, char *);
	if (string == NULL) {
	    break;
	}
	while (*string != 0) {







<







456
457
458
459
460
461
462

463
464
465
466
467
468
469
    }

    /*
     * Make a second pass through the arguments, appending all the
     * strings to the object.
     */


    dst = objPtr->bytes + oldLength;
    while (1) {
	string = va_arg(argList, char *);
	if (string == NULL) {
	    break;
	}
	while (*string != 0) {
451
452
453
454
455
456
457




























458
459
460
461
462
463
464
     * NULL; just leave everything alone.
     */

    if (dst != NULL) {
	*dst = 0;
    }
    objPtr->length = newLength;




























    va_end(argList);
}

/*
 *----------------------------------------------------------------------
 *
 * ConvertToStringType --







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







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
     * NULL; just leave everything alone.
     */

    if (dst != NULL) {
	*dst = 0;
    }
    objPtr->length = newLength;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppendStringsToObj --
 *
 *	This procedure appends one or more null-terminated strings
 *	to an object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The contents of all the string arguments are appended to the
 *	string representation of objPtr.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AppendStringsToObj TCL_VARARGS_DEF(Tcl_Obj *,arg1)
{
    register Tcl_Obj *objPtr;
    va_list argList;

    objPtr = TCL_VARARGS_START(Tcl_Obj *,arg1,argList);
    Tcl_AppendStringsToObjVA(objPtr, argList);
    va_end(argList);
}

/*
 *----------------------------------------------------------------------
 *
 * ConvertToStringType --

Added generic/tclStubInit.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
/* 
 * 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.3.2.12 1999/04/06 03:13:19 redman Exp $
 */

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

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

#undef Tcl_Alloc
#undef Tcl_Free
#undef Tcl_Realloc
#undef Tcl_NewBooleanObj
#undef Tcl_NewByteArrayObj
#undef Tcl_NewDoubleObj
#undef Tcl_NewIntObj
#undef Tcl_NewListObj
#undef Tcl_NewLongObj
#undef Tcl_NewObj
#undef Tcl_NewStringObj
#undef Tcl_DumpActiveMemory
#undef Tcl_ValidateAllMemory

/*
 * 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 */
    Tcl_Alloc, /* 3 */
    Tcl_Free, /* 4 */
    Tcl_Realloc, /* 5 */
    Tcl_DbCkalloc, /* 6 */
    Tcl_DbCkfree, /* 7 */
    Tcl_DbCkrealloc, /* 8 */
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
    Tcl_CreateFileHandler, /* 9 */
#endif /* UNIX */
#ifdef __WIN32__
    NULL, /* 9 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
    NULL, /* 9 */
#endif /* MAC_TCL */
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
    Tcl_DeleteFileHandler, /* 10 */
#endif /* UNIX */
#ifdef __WIN32__
    NULL, /* 10 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
    NULL, /* 10 */
#endif /* MAC_TCL */
    Tcl_SetTimer, /* 11 */
    Tcl_Sleep, /* 12 */
    Tcl_WaitForEvent, /* 13 */
    Tcl_AppendAllObjTypes, /* 14 */
    Tcl_AppendStringsToObj, /* 15 */
    Tcl_AppendToObj, /* 16 */
    Tcl_ConcatObj, /* 17 */
    Tcl_ConvertToType, /* 18 */
    Tcl_DbDecrRefCount, /* 19 */
    Tcl_DbIncrRefCount, /* 20 */
    Tcl_DbIsShared, /* 21 */
    Tcl_DbNewBooleanObj, /* 22 */
    Tcl_DbNewByteArrayObj, /* 23 */
    Tcl_DbNewDoubleObj, /* 24 */
    Tcl_DbNewListObj, /* 25 */
    Tcl_DbNewLongObj, /* 26 */
    Tcl_DbNewObj, /* 27 */
    Tcl_DbNewStringObj, /* 28 */
    Tcl_DuplicateObj, /* 29 */
    TclFreeObj, /* 30 */
    Tcl_GetBoolean, /* 31 */
    Tcl_GetBooleanFromObj, /* 32 */
    Tcl_GetByteArrayFromObj, /* 33 */
    Tcl_GetDouble, /* 34 */
    Tcl_GetDoubleFromObj, /* 35 */
    Tcl_GetIndexFromObj, /* 36 */
    Tcl_GetInt, /* 37 */
    Tcl_GetIntFromObj, /* 38 */
    Tcl_GetLongFromObj, /* 39 */
    Tcl_GetObjType, /* 40 */
    Tcl_GetStringFromObj, /* 41 */
    Tcl_InvalidateStringRep, /* 42 */
    Tcl_ListObjAppendList, /* 43 */
    Tcl_ListObjAppendElement, /* 44 */
    Tcl_ListObjGetElements, /* 45 */
    Tcl_ListObjIndex, /* 46 */
    Tcl_ListObjLength, /* 47 */
    Tcl_ListObjReplace, /* 48 */
    Tcl_NewBooleanObj, /* 49 */
    Tcl_NewByteArrayObj, /* 50 */
    Tcl_NewDoubleObj, /* 51 */
    Tcl_NewIntObj, /* 52 */
    Tcl_NewListObj, /* 53 */
    Tcl_NewLongObj, /* 54 */
    Tcl_NewObj, /* 55 */
    Tcl_NewStringObj, /* 56 */
    Tcl_SetBooleanObj, /* 57 */
    Tcl_SetByteArrayLength, /* 58 */
    Tcl_SetByteArrayObj, /* 59 */
    Tcl_SetDoubleObj, /* 60 */
    Tcl_SetIntObj, /* 61 */
    Tcl_SetListObj, /* 62 */
    Tcl_SetLongObj, /* 63 */
    Tcl_SetObjLength, /* 64 */
    Tcl_SetStringObj, /* 65 */
    Tcl_AddErrorInfo, /* 66 */
    Tcl_AddObjErrorInfo, /* 67 */
    Tcl_AllowExceptions, /* 68 */
    Tcl_AppendElement, /* 69 */
    Tcl_AppendResult, /* 70 */
    Tcl_AsyncCreate, /* 71 */
    Tcl_AsyncDelete, /* 72 */
    Tcl_AsyncInvoke, /* 73 */
    Tcl_AsyncMark, /* 74 */
    Tcl_AsyncReady, /* 75 */
    Tcl_BackgroundError, /* 76 */
    Tcl_Backslash, /* 77 */
    Tcl_BadChannelOption, /* 78 */
    Tcl_CallWhenDeleted, /* 79 */
    Tcl_CancelIdleCall, /* 80 */
    Tcl_Close, /* 81 */
    Tcl_CommandComplete, /* 82 */
    Tcl_Concat, /* 83 */
    Tcl_ConvertElement, /* 84 */
    Tcl_ConvertCountedElement, /* 85 */
    Tcl_CreateAlias, /* 86 */
    Tcl_CreateAliasObj, /* 87 */
    Tcl_CreateChannel, /* 88 */
    Tcl_CreateChannelHandler, /* 89 */
    Tcl_CreateCloseHandler, /* 90 */
    Tcl_CreateCommand, /* 91 */
    Tcl_CreateEventSource, /* 92 */
    Tcl_CreateExitHandler, /* 93 */
    Tcl_CreateInterp, /* 94 */
    Tcl_CreateMathFunc, /* 95 */
    Tcl_CreateObjCommand, /* 96 */
    Tcl_CreateSlave, /* 97 */
    Tcl_CreateTimerHandler, /* 98 */
    Tcl_CreateTrace, /* 99 */
    Tcl_DeleteAssocData, /* 100 */
    Tcl_DeleteChannelHandler, /* 101 */
    Tcl_DeleteCloseHandler, /* 102 */
    Tcl_DeleteCommand, /* 103 */
    Tcl_DeleteCommandFromToken, /* 104 */
    Tcl_DeleteEvents, /* 105 */
    Tcl_DeleteEventSource, /* 106 */
    Tcl_DeleteExitHandler, /* 107 */
    Tcl_DeleteHashEntry, /* 108 */
    Tcl_DeleteHashTable, /* 109 */
    Tcl_DeleteInterp, /* 110 */
    Tcl_DetachPids, /* 111 */
    Tcl_DeleteTimerHandler, /* 112 */
    Tcl_DeleteTrace, /* 113 */
    Tcl_DontCallWhenDeleted, /* 114 */
    Tcl_DoOneEvent, /* 115 */
    Tcl_DoWhenIdle, /* 116 */
    Tcl_DStringAppend, /* 117 */
    Tcl_DStringAppendElement, /* 118 */
    Tcl_DStringEndSublist, /* 119 */
    Tcl_DStringFree, /* 120 */
    Tcl_DStringGetResult, /* 121 */
    Tcl_DStringInit, /* 122 */
    Tcl_DStringResult, /* 123 */
    Tcl_DStringSetLength, /* 124 */
    Tcl_DStringStartSublist, /* 125 */
    Tcl_Eof, /* 126 */
    Tcl_ErrnoId, /* 127 */
    Tcl_ErrnoMsg, /* 128 */
    Tcl_Eval, /* 129 */
    Tcl_EvalFile, /* 130 */
    Tcl_EvalObj, /* 131 */
    Tcl_EventuallyFree, /* 132 */
    Tcl_Exit, /* 133 */
    Tcl_ExposeCommand, /* 134 */
    Tcl_ExprBoolean, /* 135 */
    Tcl_ExprBooleanObj, /* 136 */
    Tcl_ExprDouble, /* 137 */
    Tcl_ExprDoubleObj, /* 138 */
    Tcl_ExprLong, /* 139 */
    Tcl_ExprLongObj, /* 140 */
    Tcl_ExprObj, /* 141 */
    Tcl_ExprString, /* 142 */
    Tcl_Finalize, /* 143 */
    Tcl_FindExecutable, /* 144 */
    Tcl_FirstHashEntry, /* 145 */
    Tcl_Flush, /* 146 */
    Tcl_FreeResult, /* 147 */
    Tcl_GetAlias, /* 148 */
    Tcl_GetAliasObj, /* 149 */
    Tcl_GetAssocData, /* 150 */
    Tcl_GetChannel, /* 151 */
    Tcl_GetChannelBufferSize, /* 152 */
    Tcl_GetChannelHandle, /* 153 */
    Tcl_GetChannelInstanceData, /* 154 */
    Tcl_GetChannelMode, /* 155 */
    Tcl_GetChannelName, /* 156 */
    Tcl_GetChannelOption, /* 157 */
    Tcl_GetChannelType, /* 158 */
    Tcl_GetCommandInfo, /* 159 */
    Tcl_GetCommandName, /* 160 */
    Tcl_GetErrno, /* 161 */
    Tcl_GetHostName, /* 162 */
    Tcl_GetInterpPath, /* 163 */
    Tcl_GetMaster, /* 164 */
    Tcl_GetNameOfExecutable, /* 165 */
    Tcl_GetObjResult, /* 166 */
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
    Tcl_GetOpenFile, /* 167 */
#endif /* UNIX */
#ifdef __WIN32__
    NULL, /* 167 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
    NULL, /* 167 */
#endif /* MAC_TCL */
    Tcl_GetPathType, /* 168 */
    Tcl_Gets, /* 169 */
    Tcl_GetsObj, /* 170 */
    Tcl_GetServiceMode, /* 171 */
    Tcl_GetSlave, /* 172 */
    Tcl_GetStdChannel, /* 173 */
    Tcl_GetStringResult, /* 174 */
    Tcl_GetVar, /* 175 */
    Tcl_GetVar2, /* 176 */
    Tcl_GlobalEval, /* 177 */
    Tcl_GlobalEvalObj, /* 178 */
    Tcl_HideCommand, /* 179 */
    Tcl_Init, /* 180 */
    Tcl_InitHashTable, /* 181 */
    Tcl_InputBlocked, /* 182 */
    Tcl_InputBuffered, /* 183 */
    Tcl_InterpDeleted, /* 184 */
    Tcl_IsSafe, /* 185 */
    Tcl_JoinPath, /* 186 */
    Tcl_LinkVar, /* 187 */
    NULL, /* 188 */
    Tcl_MakeFileChannel, /* 189 */
    Tcl_MakeSafe, /* 190 */
    Tcl_MakeTcpClientChannel, /* 191 */
    Tcl_Merge, /* 192 */
    Tcl_NextHashEntry, /* 193 */
    Tcl_NotifyChannel, /* 194 */
    Tcl_ObjGetVar2, /* 195 */
    Tcl_ObjSetVar2, /* 196 */
    Tcl_OpenCommandChannel, /* 197 */
    Tcl_OpenFileChannel, /* 198 */
    Tcl_OpenTcpClient, /* 199 */
    Tcl_OpenTcpServer, /* 200 */
    Tcl_Preserve, /* 201 */
    Tcl_PrintDouble, /* 202 */
    Tcl_PutEnv, /* 203 */
    Tcl_PosixError, /* 204 */
    Tcl_QueueEvent, /* 205 */
    Tcl_Read, /* 206 */
    Tcl_ReapDetachedProcs, /* 207 */
    Tcl_RecordAndEval, /* 208 */
    Tcl_RecordAndEvalObj, /* 209 */
    Tcl_RegisterChannel, /* 210 */
    Tcl_RegisterObjType, /* 211 */
    Tcl_RegExpCompile, /* 212 */
    Tcl_RegExpExec, /* 213 */
    Tcl_RegExpMatch, /* 214 */
    Tcl_RegExpRange, /* 215 */
    Tcl_Release, /* 216 */
    Tcl_ResetResult, /* 217 */
    Tcl_ScanElement, /* 218 */
    Tcl_ScanCountedElement, /* 219 */
    Tcl_Seek, /* 220 */
    Tcl_ServiceAll, /* 221 */
    Tcl_ServiceEvent, /* 222 */
    Tcl_SetAssocData, /* 223 */
    Tcl_SetChannelBufferSize, /* 224 */
    Tcl_SetChannelOption, /* 225 */
    Tcl_SetCommandInfo, /* 226 */
    Tcl_SetErrno, /* 227 */
    Tcl_SetErrorCode, /* 228 */
    Tcl_SetMaxBlockTime, /* 229 */
    Tcl_SetPanicProc, /* 230 */
    Tcl_SetRecursionLimit, /* 231 */
    Tcl_SetResult, /* 232 */
    Tcl_SetServiceMode, /* 233 */
    Tcl_SetObjErrorCode, /* 234 */
    Tcl_SetObjResult, /* 235 */
    Tcl_SetStdChannel, /* 236 */
    Tcl_SetVar, /* 237 */
    Tcl_SetVar2, /* 238 */
    Tcl_SignalId, /* 239 */
    Tcl_SignalMsg, /* 240 */
    Tcl_SourceRCFile, /* 241 */
    Tcl_SplitList, /* 242 */
    Tcl_SplitPath, /* 243 */
    Tcl_StaticPackage, /* 244 */
    Tcl_StringMatch, /* 245 */
    Tcl_Tell, /* 246 */
    Tcl_TraceVar, /* 247 */
    Tcl_TraceVar2, /* 248 */
    Tcl_TranslateFileName, /* 249 */
    Tcl_Ungets, /* 250 */
    Tcl_UnlinkVar, /* 251 */
    Tcl_UnregisterChannel, /* 252 */
    Tcl_UnsetVar, /* 253 */
    Tcl_UnsetVar2, /* 254 */
    Tcl_UntraceVar, /* 255 */
    Tcl_UntraceVar2, /* 256 */
    Tcl_UpdateLinkedVar, /* 257 */
    Tcl_UpVar, /* 258 */
    Tcl_UpVar2, /* 259 */
    Tcl_VarEval, /* 260 */
    Tcl_VarTraceInfo, /* 261 */
    Tcl_VarTraceInfo2, /* 262 */
    Tcl_Write, /* 263 */
    Tcl_WrongNumArgs, /* 264 */
    Tcl_DumpActiveMemory, /* 265 */
    Tcl_ValidateAllMemory, /* 266 */
    Tcl_AppendResultVA, /* 267 */
    Tcl_AppendStringsToObjVA, /* 268 */
    Tcl_HashStats, /* 269 */
    Tcl_ParseVar, /* 270 */
    Tcl_PkgPresent, /* 271 */
    Tcl_PkgPresentEx, /* 272 */
    Tcl_PkgProvide, /* 273 */
    Tcl_PkgRequire, /* 274 */
    Tcl_SetErrorCodeVA, /* 275 */
    Tcl_VarEvalVA, /* 276 */
    Tcl_WaitPid, /* 277 */
    Tcl_PanicVA, /* 278 */
    Tcl_GetVersion, /* 279 */
    Tcl_InitMemory, /* 280 */
    NULL, /* 281 */
    NULL, /* 282 */
    NULL, /* 283 */
    NULL, /* 284 */
    NULL, /* 285 */
    Tcl_AppendObjToObj, /* 286 */
    Tcl_CreateEncoding, /* 287 */
    Tcl_CreateThreadExitHandler, /* 288 */
    Tcl_DeleteThreadExitHandler, /* 289 */
    Tcl_DiscardResult, /* 290 */
    Tcl_EvalEx, /* 291 */
    Tcl_EvalObjv, /* 292 */
    Tcl_EvalObjEx, /* 293 */
    Tcl_ExitThread, /* 294 */
    Tcl_ExternalToUtf, /* 295 */
    Tcl_ExternalToUtfDString, /* 296 */
    Tcl_FinalizeThread, /* 297 */
    Tcl_FinalizeNotifier, /* 298 */
    Tcl_FreeEncoding, /* 299 */
    Tcl_GetCurrentThread, /* 300 */
    Tcl_GetEncoding, /* 301 */
    Tcl_GetEncodingName, /* 302 */
    Tcl_GetEncodingNames, /* 303 */
    Tcl_GetIndexFromObjStruct, /* 304 */
    Tcl_GetThreadData, /* 305 */
    Tcl_GetVar2Ex, /* 306 */
    Tcl_InitNotifier, /* 307 */
    Tcl_MutexLock, /* 308 */
    Tcl_MutexUnlock, /* 309 */
    Tcl_ConditionNotify, /* 310 */
    Tcl_ConditionWait, /* 311 */
    Tcl_NumUtfChars, /* 312 */
    Tcl_ReadChars, /* 313 */
    Tcl_RestoreResult, /* 314 */
    Tcl_SaveResult, /* 315 */
    Tcl_SetSystemEncoding, /* 316 */
    Tcl_SetVar2Ex, /* 317 */
    Tcl_ThreadAlert, /* 318 */
    Tcl_ThreadQueueEvent, /* 319 */
    Tcl_UniCharAtIndex, /* 320 */
    Tcl_UniCharToLower, /* 321 */
    Tcl_UniCharToTitle, /* 322 */
    Tcl_UniCharToUpper, /* 323 */
    Tcl_UniCharToUtf, /* 324 */
    Tcl_UtfAtIndex, /* 325 */
    Tcl_UtfCharComplete, /* 326 */
    Tcl_UtfBackslash, /* 327 */
    Tcl_UtfFindFirst, /* 328 */
    Tcl_UtfFindLast, /* 329 */
    Tcl_UtfNext, /* 330 */
    Tcl_UtfPrev, /* 331 */
    Tcl_UtfToExternal, /* 332 */
    Tcl_UtfToExternalDString, /* 333 */
    Tcl_UtfToLower, /* 334 */
    Tcl_UtfToTitle, /* 335 */
    Tcl_UtfToUniChar, /* 336 */
    Tcl_UtfToUpper, /* 337 */
    Tcl_WriteChars, /* 338 */
    Tcl_WriteObj, /* 339 */
    Tcl_GetString, /* 340 */
    Tcl_GetDefaultEncodingDir, /* 341 */
    Tcl_SetDefaultEncodingDir, /* 342 */
    Tcl_AlertNotifier, /* 343 */
    Tcl_ServiceModeHook, /* 344 */
    Tcl_UniCharIsAlnum, /* 345 */
    Tcl_UniCharIsAlpha, /* 346 */
    Tcl_UniCharIsDigit, /* 347 */
    Tcl_UniCharIsLower, /* 348 */
    Tcl_UniCharIsSpace, /* 349 */
    Tcl_UniCharIsUpper, /* 350 */
    Tcl_UniCharIsWordChar, /* 351 */
    Tcl_UniCharLen, /* 352 */
    Tcl_UniCharNcmp, /* 353 */
    Tcl_UniCharToUtfDString, /* 354 */
    Tcl_UtfToUniCharDString, /* 355 */
    Tcl_GetRegExpFromObj, /* 356 */
    Tcl_EvalTokens, /* 357 */
    Tcl_FreeParse, /* 358 */
    Tcl_LogCommandInfo, /* 359 */
    Tcl_ParseBraces, /* 360 */
    Tcl_ParseCommand, /* 361 */
    Tcl_ParseExpr, /* 362 */
    Tcl_ParseQuotedString, /* 363 */
    Tcl_ParseVarName, /* 364 */
    Tcl_GetCwd, /* 365 */
    Tcl_Chdir, /* 366 */
};

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 */
    NULL, /* 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. */

Added generic/tclStubLib.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
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
/* 
 * tclStubLib.c --
 *
 *	Stub object that will be statically linked into extensions that wish
 *	to access Tcl.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * Copyright (c) 1998 Paul Duffin.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclStubLib.c,v 1.3.2.2 1999/03/14 03:14:29 stanton Exp $
 */

/*
 * We need to ensure that we use the stub macros so that this file contains
 * no references to any of the stub functions.  This will make it possible
 * to build an extension that references Tcl_InitStubs but doesn't end up
 * including the rest of the stub functions.
 */

#ifndef USE_TCL_STUBS
#define USE_TCL_STUBS
#endif
#undef USE_TCL_STUB_PROCS

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

/*
 * Ensure that Tcl_InitStubs is built as an exported symbol.  The other stub
 * functions should be built as non-exported symbols.
 */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT

TclStubs *tclStubsPtr;
TclPlatStubs *tclPlatStubsPtr;
TclIntStubs *tclIntStubsPtr;
TclIntPlatStubs *tclIntPlatStubsPtr;

static TclStubs *	HasStubSupport _ANSI_ARGS_((Tcl_Interp *interp));

static TclStubs *
HasStubSupport (interp)
    Tcl_Interp *interp;
{
    Interp *iPtr = (Interp *) interp;

    if (iPtr->stubTable && (iPtr->stubTable->magic == TCL_STUB_MAGIC)) {
	return iPtr->stubTable;
    }
    interp->result = "This interpreter does not support stubs-enabled extensions.";
    interp->freeProc = TCL_STATIC;

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_InitStubs --
 *
 *	Tries to initialise the stub table pointers and ensures that
 *	the correct version of Tcl is loaded.
 *
 * Results:
 *	The actual version of Tcl that satisfies the request, or
 *	NULL to indicate that an error occurred.
 *
 * Side effects:
 *	Sets the stub table pointers.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_InitStubs (interp, version, exact)
    Tcl_Interp *interp;
    char *version;
    int exact;
{
    char *actualVersion;
    TclStubs *tmp;
    
    if (!tclStubsPtr) {
	tclStubsPtr = HasStubSupport(interp);
	if (!tclStubsPtr) {
            return NULL;
        }
    }

    actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, exact,
	    (ClientData *) &tmp);
    if (actualVersion == NULL) {
	tclStubsPtr = NULL;
	return NULL;
    }

    if (tclStubsPtr->hooks) {
	tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs;
	tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs;
	tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs;
    } else {
	tclPlatStubsPtr = NULL;
	tclIntStubsPtr = NULL;
	tclIntPlatStubsPtr = NULL;
    }
    
    return actualVersion;
}

Added generic/tclStubs.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
/* 
 * tclStubs.c --
 *
 *	This file contains the wrapper functions for 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: tclStubs.c,v 1.3.2.10 1999/03/30 03:45:34 stanton Exp $
 */

#include "tcl.h"

/*
 * Undefine function macros that will interfere with the defintions below.
 */

#undef Tcl_Alloc
#undef Tcl_Free
#undef Tcl_Realloc
#undef Tcl_NewBooleanObj
#undef Tcl_NewByteArrayObj
#undef Tcl_NewDoubleObj
#undef Tcl_NewIntObj
#undef Tcl_NewListObj
#undef Tcl_NewLongObj
#undef Tcl_NewObj
#undef Tcl_NewStringObj
#undef Tcl_InitMemory
#undef Tcl_DumpActiveMemory
#undef Tcl_ValidateAllMemory
#undef Tcl_EvalObj
#undef Tcl_GlobalEvalObj
#undef Tcl_MutexLock
#undef Tcl_MutexUnlock
#undef Tcl_ConditionNotify
#undef Tcl_ConditionWait

/*
 * WARNING: 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. */

/*
 * Exported stub functions:
 */

/* Slot 0 */
int
Tcl_PkgProvideEx(interp, name, version, clientData)
    Tcl_Interp * interp;
    char * name;
    char * version;
    ClientData clientData;
{
    return (tclStubsPtr->tcl_PkgProvideEx)(interp, name, version, clientData);
}

/* Slot 1 */
char *
Tcl_PkgRequireEx(interp, name, version, exact, clientDataPtr)
    Tcl_Interp * interp;
    char * name;
    char * version;
    int exact;
    ClientData * clientDataPtr;
{
    return (tclStubsPtr->tcl_PkgRequireEx)(interp, name, version, exact, clientDataPtr);
}

/* Slot 2 */
void
Tcl_Panic TCL_VARARGS_DEF(char *,format)
{
    char * var;
    va_list argList;

    var = (char *) TCL_VARARGS_START(char *,format,argList);

    (tclStubsPtr->tcl_PanicVA)(var, argList);
    va_end(argList);
}

/* Slot 3 */
char *
Tcl_Alloc(size)
    unsigned int size;
{
    return (tclStubsPtr->tcl_Alloc)(size);
}

/* Slot 4 */
void
Tcl_Free(ptr)
    char * ptr;
{
    (tclStubsPtr->tcl_Free)(ptr);
}

/* Slot 5 */
char *
Tcl_Realloc(ptr, size)
    char * ptr;
    unsigned int size;
{
    return (tclStubsPtr->tcl_Realloc)(ptr, size);
}

/* Slot 6 */
char *
Tcl_DbCkalloc(size, file, line)
    unsigned int size;
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbCkalloc)(size, file, line);
}

/* Slot 7 */
int
Tcl_DbCkfree(ptr, file, line)
    char * ptr;
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbCkfree)(ptr, file, line);
}

/* Slot 8 */
char *
Tcl_DbCkrealloc(ptr, size, file, line)
    char * ptr;
    unsigned int size;
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbCkrealloc)(ptr, size, file, line);
}

#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
/* Slot 9 */
void
Tcl_CreateFileHandler(fd, mask, proc, clientData)
    int fd;
    int mask;
    Tcl_FileProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_CreateFileHandler)(fd, mask, proc, clientData);
}

#endif /* UNIX */
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
/* Slot 10 */
void
Tcl_DeleteFileHandler(fd)
    int fd;
{
    (tclStubsPtr->tcl_DeleteFileHandler)(fd);
}

#endif /* UNIX */
/* Slot 11 */
void
Tcl_SetTimer(timePtr)
    Tcl_Time * timePtr;
{
    (tclStubsPtr->tcl_SetTimer)(timePtr);
}

/* Slot 12 */
void
Tcl_Sleep(ms)
    int ms;
{
    (tclStubsPtr->tcl_Sleep)(ms);
}

/* Slot 13 */
int
Tcl_WaitForEvent(timePtr)
    Tcl_Time * timePtr;
{
    return (tclStubsPtr->tcl_WaitForEvent)(timePtr);
}

/* Slot 14 */
int
Tcl_AppendAllObjTypes(interp, objPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
{
    return (tclStubsPtr->tcl_AppendAllObjTypes)(interp, objPtr);
}

/* Slot 15 */
void
Tcl_AppendStringsToObj TCL_VARARGS_DEF(Tcl_Obj *,objPtr)
{
    Tcl_Obj * var;
    va_list argList;

    var = (Tcl_Obj *) TCL_VARARGS_START(Tcl_Obj *,objPtr,argList);

    (tclStubsPtr->tcl_AppendStringsToObjVA)(var, argList);
    va_end(argList);
}

/* Slot 16 */
void
Tcl_AppendToObj(objPtr, bytes, length)
    Tcl_Obj * objPtr;
    char * bytes;
    int length;
{
    (tclStubsPtr->tcl_AppendToObj)(objPtr, bytes, length);
}

/* Slot 17 */
Tcl_Obj *
Tcl_ConcatObj(objc, objv)
    int objc;
    Tcl_Obj *CONST objv[];
{
    return (tclStubsPtr->tcl_ConcatObj)(objc, objv);
}

/* Slot 18 */
int
Tcl_ConvertToType(interp, objPtr, typePtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    Tcl_ObjType * typePtr;
{
    return (tclStubsPtr->tcl_ConvertToType)(interp, objPtr, typePtr);
}

/* Slot 19 */
void
Tcl_DbDecrRefCount(objPtr, file, line)
    Tcl_Obj * objPtr;
    char * file;
    int line;
{
    (tclStubsPtr->tcl_DbDecrRefCount)(objPtr, file, line);
}

/* Slot 20 */
void
Tcl_DbIncrRefCount(objPtr, file, line)
    Tcl_Obj * objPtr;
    char * file;
    int line;
{
    (tclStubsPtr->tcl_DbIncrRefCount)(objPtr, file, line);
}

/* Slot 21 */
int
Tcl_DbIsShared(objPtr, file, line)
    Tcl_Obj * objPtr;
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbIsShared)(objPtr, file, line);
}

/* Slot 22 */
Tcl_Obj *
Tcl_DbNewBooleanObj(boolValue, file, line)
    int boolValue;
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbNewBooleanObj)(boolValue, file, line);
}

/* Slot 23 */
Tcl_Obj *
Tcl_DbNewByteArrayObj(bytes, length, file, line)
    unsigned char * bytes;
    int length;
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbNewByteArrayObj)(bytes, length, file, line);
}

/* Slot 24 */
Tcl_Obj *
Tcl_DbNewDoubleObj(doubleValue, file, line)
    double doubleValue;
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbNewDoubleObj)(doubleValue, file, line);
}

/* Slot 25 */
Tcl_Obj *
Tcl_DbNewListObj(objc, objv, file, line)
    int objc;
    Tcl_Obj *CONST objv[];
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbNewListObj)(objc, objv, file, line);
}

/* Slot 26 */
Tcl_Obj *
Tcl_DbNewLongObj(longValue, file, line)
    long longValue;
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbNewLongObj)(longValue, file, line);
}

/* Slot 27 */
Tcl_Obj *
Tcl_DbNewObj(file, line)
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbNewObj)(file, line);
}

/* Slot 28 */
Tcl_Obj *
Tcl_DbNewStringObj(bytes, length, file, line)
    CONST char * bytes;
    int length;
    char * file;
    int line;
{
    return (tclStubsPtr->tcl_DbNewStringObj)(bytes, length, file, line);
}

/* Slot 29 */
Tcl_Obj *
Tcl_DuplicateObj(objPtr)
    Tcl_Obj * objPtr;
{
    return (tclStubsPtr->tcl_DuplicateObj)(objPtr);
}

/* Slot 30 */
void
TclFreeObj(objPtr)
    Tcl_Obj * objPtr;
{
    (tclStubsPtr->tclFreeObj)(objPtr);
}

/* Slot 31 */
int
Tcl_GetBoolean(interp, str, boolPtr)
    Tcl_Interp * interp;
    char * str;
    int * boolPtr;
{
    return (tclStubsPtr->tcl_GetBoolean)(interp, str, boolPtr);
}

/* Slot 32 */
int
Tcl_GetBooleanFromObj(interp, objPtr, boolPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    int * boolPtr;
{
    return (tclStubsPtr->tcl_GetBooleanFromObj)(interp, objPtr, boolPtr);
}

/* Slot 33 */
unsigned char *
Tcl_GetByteArrayFromObj(objPtr, lengthPtr)
    Tcl_Obj * objPtr;
    int * lengthPtr;
{
    return (tclStubsPtr->tcl_GetByteArrayFromObj)(objPtr, lengthPtr);
}

/* Slot 34 */
int
Tcl_GetDouble(interp, str, doublePtr)
    Tcl_Interp * interp;
    char * str;
    double * doublePtr;
{
    return (tclStubsPtr->tcl_GetDouble)(interp, str, doublePtr);
}

/* Slot 35 */
int
Tcl_GetDoubleFromObj(interp, objPtr, doublePtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    double * doublePtr;
{
    return (tclStubsPtr->tcl_GetDoubleFromObj)(interp, objPtr, doublePtr);
}

/* Slot 36 */
int
Tcl_GetIndexFromObj(interp, objPtr, tablePtr, msg, flags, indexPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    char ** tablePtr;
    char * msg;
    int flags;
    int * indexPtr;
{
    return (tclStubsPtr->tcl_GetIndexFromObj)(interp, objPtr, tablePtr, msg, flags, indexPtr);
}

/* Slot 37 */
int
Tcl_GetInt(interp, str, intPtr)
    Tcl_Interp * interp;
    char * str;
    int * intPtr;
{
    return (tclStubsPtr->tcl_GetInt)(interp, str, intPtr);
}

/* Slot 38 */
int
Tcl_GetIntFromObj(interp, objPtr, intPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    int * intPtr;
{
    return (tclStubsPtr->tcl_GetIntFromObj)(interp, objPtr, intPtr);
}

/* Slot 39 */
int
Tcl_GetLongFromObj(interp, objPtr, longPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    long * longPtr;
{
    return (tclStubsPtr->tcl_GetLongFromObj)(interp, objPtr, longPtr);
}

/* Slot 40 */
Tcl_ObjType *
Tcl_GetObjType(typeName)
    char * typeName;
{
    return (tclStubsPtr->tcl_GetObjType)(typeName);
}

/* Slot 41 */
char *
Tcl_GetStringFromObj(objPtr, lengthPtr)
    Tcl_Obj * objPtr;
    int * lengthPtr;
{
    return (tclStubsPtr->tcl_GetStringFromObj)(objPtr, lengthPtr);
}

/* Slot 42 */
void
Tcl_InvalidateStringRep(objPtr)
    Tcl_Obj * objPtr;
{
    (tclStubsPtr->tcl_InvalidateStringRep)(objPtr);
}

/* Slot 43 */
int
Tcl_ListObjAppendList(interp, listPtr, elemListPtr)
    Tcl_Interp * interp;
    Tcl_Obj * listPtr;
    Tcl_Obj * elemListPtr;
{
    return (tclStubsPtr->tcl_ListObjAppendList)(interp, listPtr, elemListPtr);
}

/* Slot 44 */
int
Tcl_ListObjAppendElement(interp, listPtr, objPtr)
    Tcl_Interp * interp;
    Tcl_Obj * listPtr;
    Tcl_Obj * objPtr;
{
    return (tclStubsPtr->tcl_ListObjAppendElement)(interp, listPtr, objPtr);
}

/* Slot 45 */
int
Tcl_ListObjGetElements(interp, listPtr, objcPtr, objvPtr)
    Tcl_Interp * interp;
    Tcl_Obj * listPtr;
    int * objcPtr;
    Tcl_Obj *** objvPtr;
{
    return (tclStubsPtr->tcl_ListObjGetElements)(interp, listPtr, objcPtr, objvPtr);
}

/* Slot 46 */
int
Tcl_ListObjIndex(interp, listPtr, index, objPtrPtr)
    Tcl_Interp * interp;
    Tcl_Obj * listPtr;
    int index;
    Tcl_Obj ** objPtrPtr;
{
    return (tclStubsPtr->tcl_ListObjIndex)(interp, listPtr, index, objPtrPtr);
}

/* Slot 47 */
int
Tcl_ListObjLength(interp, listPtr, intPtr)
    Tcl_Interp * interp;
    Tcl_Obj * listPtr;
    int * intPtr;
{
    return (tclStubsPtr->tcl_ListObjLength)(interp, listPtr, intPtr);
}

/* Slot 48 */
int
Tcl_ListObjReplace(interp, listPtr, first, count, objc, objv)
    Tcl_Interp * interp;
    Tcl_Obj * listPtr;
    int first;
    int count;
    int objc;
    Tcl_Obj *CONST objv[];
{
    return (tclStubsPtr->tcl_ListObjReplace)(interp, listPtr, first, count, objc, objv);
}

/* Slot 49 */
Tcl_Obj *
Tcl_NewBooleanObj(boolValue)
    int boolValue;
{
    return (tclStubsPtr->tcl_NewBooleanObj)(boolValue);
}

/* Slot 50 */
Tcl_Obj *
Tcl_NewByteArrayObj(bytes, length)
    unsigned char * bytes;
    int length;
{
    return (tclStubsPtr->tcl_NewByteArrayObj)(bytes, length);
}

/* Slot 51 */
Tcl_Obj *
Tcl_NewDoubleObj(doubleValue)
    double doubleValue;
{
    return (tclStubsPtr->tcl_NewDoubleObj)(doubleValue);
}

/* Slot 52 */
Tcl_Obj *
Tcl_NewIntObj(intValue)
    int intValue;
{
    return (tclStubsPtr->tcl_NewIntObj)(intValue);
}

/* Slot 53 */
Tcl_Obj *
Tcl_NewListObj(objc, objv)
    int objc;
    Tcl_Obj *CONST objv[];
{
    return (tclStubsPtr->tcl_NewListObj)(objc, objv);
}

/* Slot 54 */
Tcl_Obj *
Tcl_NewLongObj(longValue)
    long longValue;
{
    return (tclStubsPtr->tcl_NewLongObj)(longValue);
}

/* Slot 55 */
Tcl_Obj *
Tcl_NewObj()
{
    return (tclStubsPtr->tcl_NewObj)();
}

/* Slot 56 */
Tcl_Obj *
Tcl_NewStringObj(bytes, length)
    CONST char * bytes;
    int length;
{
    return (tclStubsPtr->tcl_NewStringObj)(bytes, length);
}

/* Slot 57 */
void
Tcl_SetBooleanObj(objPtr, boolValue)
    Tcl_Obj * objPtr;
    int boolValue;
{
    (tclStubsPtr->tcl_SetBooleanObj)(objPtr, boolValue);
}

/* Slot 58 */
unsigned char *
Tcl_SetByteArrayLength(objPtr, length)
    Tcl_Obj * objPtr;
    int length;
{
    return (tclStubsPtr->tcl_SetByteArrayLength)(objPtr, length);
}

/* Slot 59 */
void
Tcl_SetByteArrayObj(objPtr, bytes, length)
    Tcl_Obj * objPtr;
    unsigned char * bytes;
    int length;
{
    (tclStubsPtr->tcl_SetByteArrayObj)(objPtr, bytes, length);
}

/* Slot 60 */
void
Tcl_SetDoubleObj(objPtr, doubleValue)
    Tcl_Obj * objPtr;
    double doubleValue;
{
    (tclStubsPtr->tcl_SetDoubleObj)(objPtr, doubleValue);
}

/* Slot 61 */
void
Tcl_SetIntObj(objPtr, intValue)
    Tcl_Obj * objPtr;
    int intValue;
{
    (tclStubsPtr->tcl_SetIntObj)(objPtr, intValue);
}

/* Slot 62 */
void
Tcl_SetListObj(objPtr, objc, objv)
    Tcl_Obj * objPtr;
    int objc;
    Tcl_Obj *CONST objv[];
{
    (tclStubsPtr->tcl_SetListObj)(objPtr, objc, objv);
}

/* Slot 63 */
void
Tcl_SetLongObj(objPtr, longValue)
    Tcl_Obj * objPtr;
    long longValue;
{
    (tclStubsPtr->tcl_SetLongObj)(objPtr, longValue);
}

/* Slot 64 */
void
Tcl_SetObjLength(objPtr, length)
    Tcl_Obj * objPtr;
    int length;
{
    (tclStubsPtr->tcl_SetObjLength)(objPtr, length);
}

/* Slot 65 */
void
Tcl_SetStringObj(objPtr, bytes, length)
    Tcl_Obj * objPtr;
    char * bytes;
    int length;
{
    (tclStubsPtr->tcl_SetStringObj)(objPtr, bytes, length);
}

/* Slot 66 */
void
Tcl_AddErrorInfo(interp, message)
    Tcl_Interp * interp;
    CONST char * message;
{
    (tclStubsPtr->tcl_AddErrorInfo)(interp, message);
}

/* Slot 67 */
void
Tcl_AddObjErrorInfo(interp, message, length)
    Tcl_Interp * interp;
    CONST char * message;
    int length;
{
    (tclStubsPtr->tcl_AddObjErrorInfo)(interp, message, length);
}

/* Slot 68 */
void
Tcl_AllowExceptions(interp)
    Tcl_Interp * interp;
{
    (tclStubsPtr->tcl_AllowExceptions)(interp);
}

/* Slot 69 */
void
Tcl_AppendElement(interp, string)
    Tcl_Interp * interp;
    CONST char * string;
{
    (tclStubsPtr->tcl_AppendElement)(interp, string);
}

/* Slot 70 */
void
Tcl_AppendResult TCL_VARARGS_DEF(Tcl_Interp *,interp)
{
    Tcl_Interp * var;
    va_list argList;

    var = (Tcl_Interp *) TCL_VARARGS_START(Tcl_Interp *,interp,argList);

    (tclStubsPtr->tcl_AppendResultVA)(var, argList);
    va_end(argList);
}

/* Slot 71 */
Tcl_AsyncHandler
Tcl_AsyncCreate(proc, clientData)
    Tcl_AsyncProc * proc;
    ClientData clientData;
{
    return (tclStubsPtr->tcl_AsyncCreate)(proc, clientData);
}

/* Slot 72 */
void
Tcl_AsyncDelete(async)
    Tcl_AsyncHandler async;
{
    (tclStubsPtr->tcl_AsyncDelete)(async);
}

/* Slot 73 */
int
Tcl_AsyncInvoke(interp, code)
    Tcl_Interp * interp;
    int code;
{
    return (tclStubsPtr->tcl_AsyncInvoke)(interp, code);
}

/* Slot 74 */
void
Tcl_AsyncMark(async)
    Tcl_AsyncHandler async;
{
    (tclStubsPtr->tcl_AsyncMark)(async);
}

/* Slot 75 */
int
Tcl_AsyncReady()
{
    return (tclStubsPtr->tcl_AsyncReady)();
}

/* Slot 76 */
void
Tcl_BackgroundError(interp)
    Tcl_Interp * interp;
{
    (tclStubsPtr->tcl_BackgroundError)(interp);
}

/* Slot 77 */
char
Tcl_Backslash(src, readPtr)
    CONST char * src;
    int * readPtr;
{
    return (tclStubsPtr->tcl_Backslash)(src, readPtr);
}

/* Slot 78 */
int
Tcl_BadChannelOption(interp, optionName, optionList)
    Tcl_Interp * interp;
    char * optionName;
    char * optionList;
{
    return (tclStubsPtr->tcl_BadChannelOption)(interp, optionName, optionList);
}

/* Slot 79 */
void
Tcl_CallWhenDeleted(interp, proc, clientData)
    Tcl_Interp * interp;
    Tcl_InterpDeleteProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_CallWhenDeleted)(interp, proc, clientData);
}

/* Slot 80 */
void
Tcl_CancelIdleCall(idleProc, clientData)
    Tcl_IdleProc * idleProc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_CancelIdleCall)(idleProc, clientData);
}

/* Slot 81 */
int
Tcl_Close(interp, chan)
    Tcl_Interp * interp;
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_Close)(interp, chan);
}

/* Slot 82 */
int
Tcl_CommandComplete(cmd)
    char * cmd;
{
    return (tclStubsPtr->tcl_CommandComplete)(cmd);
}

/* Slot 83 */
char *
Tcl_Concat(argc, argv)
    int argc;
    char ** argv;
{
    return (tclStubsPtr->tcl_Concat)(argc, argv);
}

/* Slot 84 */
int
Tcl_ConvertElement(src, dst, flags)
    CONST char * src;
    char * dst;
    int flags;
{
    return (tclStubsPtr->tcl_ConvertElement)(src, dst, flags);
}

/* Slot 85 */
int
Tcl_ConvertCountedElement(src, length, dst, flags)
    CONST char * src;
    int length;
    char * dst;
    int flags;
{
    return (tclStubsPtr->tcl_ConvertCountedElement)(src, length, dst, flags);
}

/* Slot 86 */
int
Tcl_CreateAlias(slave, slaveCmd, target, targetCmd, argc, argv)
    Tcl_Interp * slave;
    char * slaveCmd;
    Tcl_Interp * target;
    char * targetCmd;
    int argc;
    char ** argv;
{
    return (tclStubsPtr->tcl_CreateAlias)(slave, slaveCmd, target, targetCmd, argc, argv);
}

/* Slot 87 */
int
Tcl_CreateAliasObj(slave, slaveCmd, target, targetCmd, objc, objv)
    Tcl_Interp * slave;
    char * slaveCmd;
    Tcl_Interp * target;
    char * targetCmd;
    int objc;
    Tcl_Obj *CONST objv[];
{
    return (tclStubsPtr->tcl_CreateAliasObj)(slave, slaveCmd, target, targetCmd, objc, objv);
}

/* Slot 88 */
Tcl_Channel
Tcl_CreateChannel(typePtr, chanName, instanceData, mask)
    Tcl_ChannelType * typePtr;
    char * chanName;
    ClientData instanceData;
    int mask;
{
    return (tclStubsPtr->tcl_CreateChannel)(typePtr, chanName, instanceData, mask);
}

/* Slot 89 */
void
Tcl_CreateChannelHandler(chan, mask, proc, clientData)
    Tcl_Channel chan;
    int mask;
    Tcl_ChannelProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_CreateChannelHandler)(chan, mask, proc, clientData);
}

/* Slot 90 */
void
Tcl_CreateCloseHandler(chan, proc, clientData)
    Tcl_Channel chan;
    Tcl_CloseProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_CreateCloseHandler)(chan, proc, clientData);
}

/* Slot 91 */
Tcl_Command
Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc)
    Tcl_Interp * interp;
    char * cmdName;
    Tcl_CmdProc * proc;
    ClientData clientData;
    Tcl_CmdDeleteProc * deleteProc;
{
    return (tclStubsPtr->tcl_CreateCommand)(interp, cmdName, proc, clientData, deleteProc);
}

/* Slot 92 */
void
Tcl_CreateEventSource(setupProc, checkProc, clientData)
    Tcl_EventSetupProc * setupProc;
    Tcl_EventCheckProc * checkProc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_CreateEventSource)(setupProc, checkProc, clientData);
}

/* Slot 93 */
void
Tcl_CreateExitHandler(proc, clientData)
    Tcl_ExitProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_CreateExitHandler)(proc, clientData);
}

/* Slot 94 */
Tcl_Interp *
Tcl_CreateInterp()
{
    return (tclStubsPtr->tcl_CreateInterp)();
}

/* Slot 95 */
void
Tcl_CreateMathFunc(interp, name, numArgs, argTypes, proc, clientData)
    Tcl_Interp * interp;
    char * name;
    int numArgs;
    Tcl_ValueType * argTypes;
    Tcl_MathProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_CreateMathFunc)(interp, name, numArgs, argTypes, proc, clientData);
}

/* Slot 96 */
Tcl_Command
Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc)
    Tcl_Interp * interp;
    char * cmdName;
    Tcl_ObjCmdProc * proc;
    ClientData clientData;
    Tcl_CmdDeleteProc * deleteProc;
{
    return (tclStubsPtr->tcl_CreateObjCommand)(interp, cmdName, proc, clientData, deleteProc);
}

/* Slot 97 */
Tcl_Interp *
Tcl_CreateSlave(interp, slaveName, isSafe)
    Tcl_Interp * interp;
    char * slaveName;
    int isSafe;
{
    return (tclStubsPtr->tcl_CreateSlave)(interp, slaveName, isSafe);
}

/* Slot 98 */
Tcl_TimerToken
Tcl_CreateTimerHandler(milliseconds, proc, clientData)
    int milliseconds;
    Tcl_TimerProc * proc;
    ClientData clientData;
{
    return (tclStubsPtr->tcl_CreateTimerHandler)(milliseconds, proc, clientData);
}

/* Slot 99 */
Tcl_Trace
Tcl_CreateTrace(interp, level, proc, clientData)
    Tcl_Interp * interp;
    int level;
    Tcl_CmdTraceProc * proc;
    ClientData clientData;
{
    return (tclStubsPtr->tcl_CreateTrace)(interp, level, proc, clientData);
}

/* Slot 100 */
void
Tcl_DeleteAssocData(interp, name)
    Tcl_Interp * interp;
    char * name;
{
    (tclStubsPtr->tcl_DeleteAssocData)(interp, name);
}

/* Slot 101 */
void
Tcl_DeleteChannelHandler(chan, proc, clientData)
    Tcl_Channel chan;
    Tcl_ChannelProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_DeleteChannelHandler)(chan, proc, clientData);
}

/* Slot 102 */
void
Tcl_DeleteCloseHandler(chan, proc, clientData)
    Tcl_Channel chan;
    Tcl_CloseProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_DeleteCloseHandler)(chan, proc, clientData);
}

/* Slot 103 */
int
Tcl_DeleteCommand(interp, cmdName)
    Tcl_Interp * interp;
    char * cmdName;
{
    return (tclStubsPtr->tcl_DeleteCommand)(interp, cmdName);
}

/* Slot 104 */
int
Tcl_DeleteCommandFromToken(interp, command)
    Tcl_Interp * interp;
    Tcl_Command command;
{
    return (tclStubsPtr->tcl_DeleteCommandFromToken)(interp, command);
}

/* Slot 105 */
void
Tcl_DeleteEvents(proc, clientData)
    Tcl_EventDeleteProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_DeleteEvents)(proc, clientData);
}

/* Slot 106 */
void
Tcl_DeleteEventSource(setupProc, checkProc, clientData)
    Tcl_EventSetupProc * setupProc;
    Tcl_EventCheckProc * checkProc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_DeleteEventSource)(setupProc, checkProc, clientData);
}

/* Slot 107 */
void
Tcl_DeleteExitHandler(proc, clientData)
    Tcl_ExitProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_DeleteExitHandler)(proc, clientData);
}

/* Slot 108 */
void
Tcl_DeleteHashEntry(entryPtr)
    Tcl_HashEntry * entryPtr;
{
    (tclStubsPtr->tcl_DeleteHashEntry)(entryPtr);
}

/* Slot 109 */
void
Tcl_DeleteHashTable(tablePtr)
    Tcl_HashTable * tablePtr;
{
    (tclStubsPtr->tcl_DeleteHashTable)(tablePtr);
}

/* Slot 110 */
void
Tcl_DeleteInterp(interp)
    Tcl_Interp * interp;
{
    (tclStubsPtr->tcl_DeleteInterp)(interp);
}

/* Slot 111 */
void
Tcl_DetachPids(numPids, pidPtr)
    int numPids;
    Tcl_Pid * pidPtr;
{
    (tclStubsPtr->tcl_DetachPids)(numPids, pidPtr);
}

/* Slot 112 */
void
Tcl_DeleteTimerHandler(token)
    Tcl_TimerToken token;
{
    (tclStubsPtr->tcl_DeleteTimerHandler)(token);
}

/* Slot 113 */
void
Tcl_DeleteTrace(interp, trace)
    Tcl_Interp * interp;
    Tcl_Trace trace;
{
    (tclStubsPtr->tcl_DeleteTrace)(interp, trace);
}

/* Slot 114 */
void
Tcl_DontCallWhenDeleted(interp, proc, clientData)
    Tcl_Interp * interp;
    Tcl_InterpDeleteProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_DontCallWhenDeleted)(interp, proc, clientData);
}

/* Slot 115 */
int
Tcl_DoOneEvent(flags)
    int flags;
{
    return (tclStubsPtr->tcl_DoOneEvent)(flags);
}

/* Slot 116 */
void
Tcl_DoWhenIdle(proc, clientData)
    Tcl_IdleProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_DoWhenIdle)(proc, clientData);
}

/* Slot 117 */
char *
Tcl_DStringAppend(dsPtr, str, length)
    Tcl_DString * dsPtr;
    CONST char * str;
    int length;
{
    return (tclStubsPtr->tcl_DStringAppend)(dsPtr, str, length);
}

/* Slot 118 */
char *
Tcl_DStringAppendElement(dsPtr, string)
    Tcl_DString * dsPtr;
    CONST char * string;
{
    return (tclStubsPtr->tcl_DStringAppendElement)(dsPtr, string);
}

/* Slot 119 */
void
Tcl_DStringEndSublist(dsPtr)
    Tcl_DString * dsPtr;
{
    (tclStubsPtr->tcl_DStringEndSublist)(dsPtr);
}

/* Slot 120 */
void
Tcl_DStringFree(dsPtr)
    Tcl_DString * dsPtr;
{
    (tclStubsPtr->tcl_DStringFree)(dsPtr);
}

/* Slot 121 */
void
Tcl_DStringGetResult(interp, dsPtr)
    Tcl_Interp * interp;
    Tcl_DString * dsPtr;
{
    (tclStubsPtr->tcl_DStringGetResult)(interp, dsPtr);
}

/* Slot 122 */
void
Tcl_DStringInit(dsPtr)
    Tcl_DString * dsPtr;
{
    (tclStubsPtr->tcl_DStringInit)(dsPtr);
}

/* Slot 123 */
void
Tcl_DStringResult(interp, dsPtr)
    Tcl_Interp * interp;
    Tcl_DString * dsPtr;
{
    (tclStubsPtr->tcl_DStringResult)(interp, dsPtr);
}

/* Slot 124 */
void
Tcl_DStringSetLength(dsPtr, length)
    Tcl_DString * dsPtr;
    int length;
{
    (tclStubsPtr->tcl_DStringSetLength)(dsPtr, length);
}

/* Slot 125 */
void
Tcl_DStringStartSublist(dsPtr)
    Tcl_DString * dsPtr;
{
    (tclStubsPtr->tcl_DStringStartSublist)(dsPtr);
}

/* Slot 126 */
int
Tcl_Eof(chan)
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_Eof)(chan);
}

/* Slot 127 */
char *
Tcl_ErrnoId()
{
    return (tclStubsPtr->tcl_ErrnoId)();
}

/* Slot 128 */
char *
Tcl_ErrnoMsg(err)
    int err;
{
    return (tclStubsPtr->tcl_ErrnoMsg)(err);
}

/* Slot 129 */
int
Tcl_Eval(interp, string)
    Tcl_Interp * interp;
    char * string;
{
    return (tclStubsPtr->tcl_Eval)(interp, string);
}

/* Slot 130 */
int
Tcl_EvalFile(interp, fileName)
    Tcl_Interp * interp;
    char * fileName;
{
    return (tclStubsPtr->tcl_EvalFile)(interp, fileName);
}

/* Slot 131 */
int
Tcl_EvalObj(interp, objPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
{
    return (tclStubsPtr->tcl_EvalObj)(interp, objPtr);
}

/* Slot 132 */
void
Tcl_EventuallyFree(clientData, freeProc)
    ClientData clientData;
    Tcl_FreeProc * freeProc;
{
    (tclStubsPtr->tcl_EventuallyFree)(clientData, freeProc);
}

/* Slot 133 */
void
Tcl_Exit(status)
    int status;
{
    (tclStubsPtr->tcl_Exit)(status);
}

/* Slot 134 */
int
Tcl_ExposeCommand(interp, hiddenCmdToken, cmdName)
    Tcl_Interp * interp;
    char * hiddenCmdToken;
    char * cmdName;
{
    return (tclStubsPtr->tcl_ExposeCommand)(interp, hiddenCmdToken, cmdName);
}

/* Slot 135 */
int
Tcl_ExprBoolean(interp, str, ptr)
    Tcl_Interp * interp;
    char * str;
    int * ptr;
{
    return (tclStubsPtr->tcl_ExprBoolean)(interp, str, ptr);
}

/* Slot 136 */
int
Tcl_ExprBooleanObj(interp, objPtr, ptr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    int * ptr;
{
    return (tclStubsPtr->tcl_ExprBooleanObj)(interp, objPtr, ptr);
}

/* Slot 137 */
int
Tcl_ExprDouble(interp, str, ptr)
    Tcl_Interp * interp;
    char * str;
    double * ptr;
{
    return (tclStubsPtr->tcl_ExprDouble)(interp, str, ptr);
}

/* Slot 138 */
int
Tcl_ExprDoubleObj(interp, objPtr, ptr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    double * ptr;
{
    return (tclStubsPtr->tcl_ExprDoubleObj)(interp, objPtr, ptr);
}

/* Slot 139 */
int
Tcl_ExprLong(interp, str, ptr)
    Tcl_Interp * interp;
    char * str;
    long * ptr;
{
    return (tclStubsPtr->tcl_ExprLong)(interp, str, ptr);
}

/* Slot 140 */
int
Tcl_ExprLongObj(interp, objPtr, ptr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    long * ptr;
{
    return (tclStubsPtr->tcl_ExprLongObj)(interp, objPtr, ptr);
}

/* Slot 141 */
int
Tcl_ExprObj(interp, objPtr, resultPtrPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    Tcl_Obj ** resultPtrPtr;
{
    return (tclStubsPtr->tcl_ExprObj)(interp, objPtr, resultPtrPtr);
}

/* Slot 142 */
int
Tcl_ExprString(interp, string)
    Tcl_Interp * interp;
    char * string;
{
    return (tclStubsPtr->tcl_ExprString)(interp, string);
}

/* Slot 143 */
void
Tcl_Finalize()
{
    (tclStubsPtr->tcl_Finalize)();
}

/* Slot 144 */
void
Tcl_FindExecutable(argv0)
    CONST char * argv0;
{
    (tclStubsPtr->tcl_FindExecutable)(argv0);
}

/* Slot 145 */
Tcl_HashEntry *
Tcl_FirstHashEntry(tablePtr, searchPtr)
    Tcl_HashTable * tablePtr;
    Tcl_HashSearch * searchPtr;
{
    return (tclStubsPtr->tcl_FirstHashEntry)(tablePtr, searchPtr);
}

/* Slot 146 */
int
Tcl_Flush(chan)
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_Flush)(chan);
}

/* Slot 147 */
void
Tcl_FreeResult(interp)
    Tcl_Interp * interp;
{
    (tclStubsPtr->tcl_FreeResult)(interp);
}

/* Slot 148 */
int
Tcl_GetAlias(interp, slaveCmd, targetInterpPtr, targetCmdPtr, argcPtr, argvPtr)
    Tcl_Interp * interp;
    char * slaveCmd;
    Tcl_Interp ** targetInterpPtr;
    char ** targetCmdPtr;
    int * argcPtr;
    char *** argvPtr;
{
    return (tclStubsPtr->tcl_GetAlias)(interp, slaveCmd, targetInterpPtr, targetCmdPtr, argcPtr, argvPtr);
}

/* Slot 149 */
int
Tcl_GetAliasObj(interp, slaveCmd, targetInterpPtr, targetCmdPtr, objcPtr, objv)
    Tcl_Interp * interp;
    char * slaveCmd;
    Tcl_Interp ** targetInterpPtr;
    char ** targetCmdPtr;
    int * objcPtr;
    Tcl_Obj *** objv;
{
    return (tclStubsPtr->tcl_GetAliasObj)(interp, slaveCmd, targetInterpPtr, targetCmdPtr, objcPtr, objv);
}

/* Slot 150 */
ClientData
Tcl_GetAssocData(interp, name, procPtr)
    Tcl_Interp * interp;
    char * name;
    Tcl_InterpDeleteProc ** procPtr;
{
    return (tclStubsPtr->tcl_GetAssocData)(interp, name, procPtr);
}

/* Slot 151 */
Tcl_Channel
Tcl_GetChannel(interp, chanName, modePtr)
    Tcl_Interp * interp;
    char * chanName;
    int * modePtr;
{
    return (tclStubsPtr->tcl_GetChannel)(interp, chanName, modePtr);
}

/* Slot 152 */
int
Tcl_GetChannelBufferSize(chan)
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_GetChannelBufferSize)(chan);
}

/* Slot 153 */
int
Tcl_GetChannelHandle(chan, direction, handlePtr)
    Tcl_Channel chan;
    int direction;
    ClientData * handlePtr;
{
    return (tclStubsPtr->tcl_GetChannelHandle)(chan, direction, handlePtr);
}

/* Slot 154 */
ClientData
Tcl_GetChannelInstanceData(chan)
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_GetChannelInstanceData)(chan);
}

/* Slot 155 */
int
Tcl_GetChannelMode(chan)
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_GetChannelMode)(chan);
}

/* Slot 156 */
char *
Tcl_GetChannelName(chan)
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_GetChannelName)(chan);
}

/* Slot 157 */
int
Tcl_GetChannelOption(interp, chan, optionName, dsPtr)
    Tcl_Interp * interp;
    Tcl_Channel chan;
    char * optionName;
    Tcl_DString * dsPtr;
{
    return (tclStubsPtr->tcl_GetChannelOption)(interp, chan, optionName, dsPtr);
}

/* Slot 158 */
Tcl_ChannelType *
Tcl_GetChannelType(chan)
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_GetChannelType)(chan);
}

/* Slot 159 */
int
Tcl_GetCommandInfo(interp, cmdName, infoPtr)
    Tcl_Interp * interp;
    char * cmdName;
    Tcl_CmdInfo * infoPtr;
{
    return (tclStubsPtr->tcl_GetCommandInfo)(interp, cmdName, infoPtr);
}

/* Slot 160 */
char *
Tcl_GetCommandName(interp, command)
    Tcl_Interp * interp;
    Tcl_Command command;
{
    return (tclStubsPtr->tcl_GetCommandName)(interp, command);
}

/* Slot 161 */
int
Tcl_GetErrno()
{
    return (tclStubsPtr->tcl_GetErrno)();
}

/* Slot 162 */
char *
Tcl_GetHostName()
{
    return (tclStubsPtr->tcl_GetHostName)();
}

/* Slot 163 */
int
Tcl_GetInterpPath(askInterp, slaveInterp)
    Tcl_Interp * askInterp;
    Tcl_Interp * slaveInterp;
{
    return (tclStubsPtr->tcl_GetInterpPath)(askInterp, slaveInterp);
}

/* Slot 164 */
Tcl_Interp *
Tcl_GetMaster(interp)
    Tcl_Interp * interp;
{
    return (tclStubsPtr->tcl_GetMaster)(interp);
}

/* Slot 165 */
CONST char *
Tcl_GetNameOfExecutable()
{
    return (tclStubsPtr->tcl_GetNameOfExecutable)();
}

/* Slot 166 */
Tcl_Obj *
Tcl_GetObjResult(interp)
    Tcl_Interp * interp;
{
    return (tclStubsPtr->tcl_GetObjResult)(interp);
}

#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
/* Slot 167 */
int
Tcl_GetOpenFile(interp, str, write, checkUsage, filePtr)
    Tcl_Interp * interp;
    char * str;
    int write;
    int checkUsage;
    ClientData * filePtr;
{
    return (tclStubsPtr->tcl_GetOpenFile)(interp, str, write, checkUsage, filePtr);
}

#endif /* UNIX */
/* Slot 168 */
Tcl_PathType
Tcl_GetPathType(path)
    char * path;
{
    return (tclStubsPtr->tcl_GetPathType)(path);
}

/* Slot 169 */
int
Tcl_Gets(chan, dsPtr)
    Tcl_Channel chan;
    Tcl_DString * dsPtr;
{
    return (tclStubsPtr->tcl_Gets)(chan, dsPtr);
}

/* Slot 170 */
int
Tcl_GetsObj(chan, objPtr)
    Tcl_Channel chan;
    Tcl_Obj * objPtr;
{
    return (tclStubsPtr->tcl_GetsObj)(chan, objPtr);
}

/* Slot 171 */
int
Tcl_GetServiceMode()
{
    return (tclStubsPtr->tcl_GetServiceMode)();
}

/* Slot 172 */
Tcl_Interp *
Tcl_GetSlave(interp, slaveName)
    Tcl_Interp * interp;
    char * slaveName;
{
    return (tclStubsPtr->tcl_GetSlave)(interp, slaveName);
}

/* Slot 173 */
Tcl_Channel
Tcl_GetStdChannel(type)
    int type;
{
    return (tclStubsPtr->tcl_GetStdChannel)(type);
}

/* Slot 174 */
char *
Tcl_GetStringResult(interp)
    Tcl_Interp * interp;
{
    return (tclStubsPtr->tcl_GetStringResult)(interp);
}

/* Slot 175 */
char *
Tcl_GetVar(interp, varName, flags)
    Tcl_Interp * interp;
    char * varName;
    int flags;
{
    return (tclStubsPtr->tcl_GetVar)(interp, varName, flags);
}

/* Slot 176 */
char *
Tcl_GetVar2(interp, part1, part2, flags)
    Tcl_Interp * interp;
    char * part1;
    char * part2;
    int flags;
{
    return (tclStubsPtr->tcl_GetVar2)(interp, part1, part2, flags);
}

/* Slot 177 */
int
Tcl_GlobalEval(interp, command)
    Tcl_Interp * interp;
    char * command;
{
    return (tclStubsPtr->tcl_GlobalEval)(interp, command);
}

/* Slot 178 */
int
Tcl_GlobalEvalObj(interp, objPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
{
    return (tclStubsPtr->tcl_GlobalEvalObj)(interp, objPtr);
}

/* Slot 179 */
int
Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
    Tcl_Interp * interp;
    char * cmdName;
    char * hiddenCmdToken;
{
    return (tclStubsPtr->tcl_HideCommand)(interp, cmdName, hiddenCmdToken);
}

/* Slot 180 */
int
Tcl_Init(interp)
    Tcl_Interp * interp;
{
    return (tclStubsPtr->tcl_Init)(interp);
}

/* Slot 181 */
void
Tcl_InitHashTable(tablePtr, keyType)
    Tcl_HashTable * tablePtr;
    int keyType;
{
    (tclStubsPtr->tcl_InitHashTable)(tablePtr, keyType);
}

/* Slot 182 */
int
Tcl_InputBlocked(chan)
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_InputBlocked)(chan);
}

/* Slot 183 */
int
Tcl_InputBuffered(chan)
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_InputBuffered)(chan);
}

/* Slot 184 */
int
Tcl_InterpDeleted(interp)
    Tcl_Interp * interp;
{
    return (tclStubsPtr->tcl_InterpDeleted)(interp);
}

/* Slot 185 */
int
Tcl_IsSafe(interp)
    Tcl_Interp * interp;
{
    return (tclStubsPtr->tcl_IsSafe)(interp);
}

/* Slot 186 */
char *
Tcl_JoinPath(argc, argv, resultPtr)
    int argc;
    CONST char ** argv;
    Tcl_DString * resultPtr;
{
    return (tclStubsPtr->tcl_JoinPath)(argc, argv, resultPtr);
}

/* Slot 187 */
int
Tcl_LinkVar(interp, varName, addr, type)
    Tcl_Interp * interp;
    char * varName;
    char * addr;
    int type;
{
    return (tclStubsPtr->tcl_LinkVar)(interp, varName, addr, type);
}

/* Slot 188 is reserved */
/* Slot 189 */
Tcl_Channel
Tcl_MakeFileChannel(handle, mode)
    ClientData handle;
    int mode;
{
    return (tclStubsPtr->tcl_MakeFileChannel)(handle, mode);
}

/* Slot 190 */
int
Tcl_MakeSafe(interp)
    Tcl_Interp * interp;
{
    return (tclStubsPtr->tcl_MakeSafe)(interp);
}

/* Slot 191 */
Tcl_Channel
Tcl_MakeTcpClientChannel(tcpSocket)
    ClientData tcpSocket;
{
    return (tclStubsPtr->tcl_MakeTcpClientChannel)(tcpSocket);
}

/* Slot 192 */
char *
Tcl_Merge(argc, argv)
    int argc;
    char ** argv;
{
    return (tclStubsPtr->tcl_Merge)(argc, argv);
}

/* Slot 193 */
Tcl_HashEntry *
Tcl_NextHashEntry(searchPtr)
    Tcl_HashSearch * searchPtr;
{
    return (tclStubsPtr->tcl_NextHashEntry)(searchPtr);
}

/* Slot 194 */
void
Tcl_NotifyChannel(channel, mask)
    Tcl_Channel channel;
    int mask;
{
    (tclStubsPtr->tcl_NotifyChannel)(channel, mask);
}

/* Slot 195 */
Tcl_Obj *
Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags)
    Tcl_Interp * interp;
    Tcl_Obj * part1Ptr;
    Tcl_Obj * part2Ptr;
    int flags;
{
    return (tclStubsPtr->tcl_ObjGetVar2)(interp, part1Ptr, part2Ptr, flags);
}

/* Slot 196 */
Tcl_Obj *
Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, newValuePtr, flags)
    Tcl_Interp * interp;
    Tcl_Obj * part1Ptr;
    Tcl_Obj * part2Ptr;
    Tcl_Obj * newValuePtr;
    int flags;
{
    return (tclStubsPtr->tcl_ObjSetVar2)(interp, part1Ptr, part2Ptr, newValuePtr, flags);
}

/* Slot 197 */
Tcl_Channel
Tcl_OpenCommandChannel(interp, argc, argv, flags)
    Tcl_Interp * interp;
    int argc;
    char ** argv;
    int flags;
{
    return (tclStubsPtr->tcl_OpenCommandChannel)(interp, argc, argv, flags);
}

/* Slot 198 */
Tcl_Channel
Tcl_OpenFileChannel(interp, fileName, modeString, permissions)
    Tcl_Interp * interp;
    char * fileName;
    char * modeString;
    int permissions;
{
    return (tclStubsPtr->tcl_OpenFileChannel)(interp, fileName, modeString, permissions);
}

/* Slot 199 */
Tcl_Channel
Tcl_OpenTcpClient(interp, port, address, myaddr, myport, async)
    Tcl_Interp * interp;
    int port;
    char * address;
    char * myaddr;
    int myport;
    int async;
{
    return (tclStubsPtr->tcl_OpenTcpClient)(interp, port, address, myaddr, myport, async);
}

/* Slot 200 */
Tcl_Channel
Tcl_OpenTcpServer(interp, port, host, acceptProc, callbackData)
    Tcl_Interp * interp;
    int port;
    char * host;
    Tcl_TcpAcceptProc * acceptProc;
    ClientData callbackData;
{
    return (tclStubsPtr->tcl_OpenTcpServer)(interp, port, host, acceptProc, callbackData);
}

/* Slot 201 */
void
Tcl_Preserve(data)
    ClientData data;
{
    (tclStubsPtr->tcl_Preserve)(data);
}

/* Slot 202 */
void
Tcl_PrintDouble(interp, value, dst)
    Tcl_Interp * interp;
    double value;
    char * dst;
{
    (tclStubsPtr->tcl_PrintDouble)(interp, value, dst);
}

/* Slot 203 */
int
Tcl_PutEnv(string)
    CONST char * string;
{
    return (tclStubsPtr->tcl_PutEnv)(string);
}

/* Slot 204 */
char *
Tcl_PosixError(interp)
    Tcl_Interp * interp;
{
    return (tclStubsPtr->tcl_PosixError)(interp);
}

/* Slot 205 */
void
Tcl_QueueEvent(evPtr, position)
    Tcl_Event * evPtr;
    Tcl_QueuePosition position;
{
    (tclStubsPtr->tcl_QueueEvent)(evPtr, position);
}

/* Slot 206 */
int
Tcl_Read(chan, bufPtr, toRead)
    Tcl_Channel chan;
    char * bufPtr;
    int toRead;
{
    return (tclStubsPtr->tcl_Read)(chan, bufPtr, toRead);
}

/* Slot 207 */
void
Tcl_ReapDetachedProcs()
{
    (tclStubsPtr->tcl_ReapDetachedProcs)();
}

/* Slot 208 */
int
Tcl_RecordAndEval(interp, cmd, flags)
    Tcl_Interp * interp;
    char * cmd;
    int flags;
{
    return (tclStubsPtr->tcl_RecordAndEval)(interp, cmd, flags);
}

/* Slot 209 */
int
Tcl_RecordAndEvalObj(interp, cmdPtr, flags)
    Tcl_Interp * interp;
    Tcl_Obj * cmdPtr;
    int flags;
{
    return (tclStubsPtr->tcl_RecordAndEvalObj)(interp, cmdPtr, flags);
}

/* Slot 210 */
void
Tcl_RegisterChannel(interp, chan)
    Tcl_Interp * interp;
    Tcl_Channel chan;
{
    (tclStubsPtr->tcl_RegisterChannel)(interp, chan);
}

/* Slot 211 */
void
Tcl_RegisterObjType(typePtr)
    Tcl_ObjType * typePtr;
{
    (tclStubsPtr->tcl_RegisterObjType)(typePtr);
}

/* Slot 212 */
Tcl_RegExp
Tcl_RegExpCompile(interp, string)
    Tcl_Interp * interp;
    char * string;
{
    return (tclStubsPtr->tcl_RegExpCompile)(interp, string);
}

/* Slot 213 */
int
Tcl_RegExpExec(interp, regexp, str, start)
    Tcl_Interp * interp;
    Tcl_RegExp regexp;
    CONST char * str;
    CONST char * start;
{
    return (tclStubsPtr->tcl_RegExpExec)(interp, regexp, str, start);
}

/* Slot 214 */
int
Tcl_RegExpMatch(interp, str, pattern)
    Tcl_Interp * interp;
    char * str;
    char * pattern;
{
    return (tclStubsPtr->tcl_RegExpMatch)(interp, str, pattern);
}

/* Slot 215 */
void
Tcl_RegExpRange(regexp, index, startPtr, endPtr)
    Tcl_RegExp regexp;
    int index;
    char ** startPtr;
    char ** endPtr;
{
    (tclStubsPtr->tcl_RegExpRange)(regexp, index, startPtr, endPtr);
}

/* Slot 216 */
void
Tcl_Release(clientData)
    ClientData clientData;
{
    (tclStubsPtr->tcl_Release)(clientData);
}

/* Slot 217 */
void
Tcl_ResetResult(interp)
    Tcl_Interp * interp;
{
    (tclStubsPtr->tcl_ResetResult)(interp);
}

/* Slot 218 */
int
Tcl_ScanElement(str, flagPtr)
    CONST char * str;
    int * flagPtr;
{
    return (tclStubsPtr->tcl_ScanElement)(str, flagPtr);
}

/* Slot 219 */
int
Tcl_ScanCountedElement(str, length, flagPtr)
    CONST char * str;
    int length;
    int * flagPtr;
{
    return (tclStubsPtr->tcl_ScanCountedElement)(str, length, flagPtr);
}

/* Slot 220 */
int
Tcl_Seek(chan, offset, mode)
    Tcl_Channel chan;
    int offset;
    int mode;
{
    return (tclStubsPtr->tcl_Seek)(chan, offset, mode);
}

/* Slot 221 */
int
Tcl_ServiceAll()
{
    return (tclStubsPtr->tcl_ServiceAll)();
}

/* Slot 222 */
int
Tcl_ServiceEvent(flags)
    int flags;
{
    return (tclStubsPtr->tcl_ServiceEvent)(flags);
}

/* Slot 223 */
void
Tcl_SetAssocData(interp, name, proc, clientData)
    Tcl_Interp * interp;
    char * name;
    Tcl_InterpDeleteProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_SetAssocData)(interp, name, proc, clientData);
}

/* Slot 224 */
void
Tcl_SetChannelBufferSize(chan, sz)
    Tcl_Channel chan;
    int sz;
{
    (tclStubsPtr->tcl_SetChannelBufferSize)(chan, sz);
}

/* Slot 225 */
int
Tcl_SetChannelOption(interp, chan, optionName, newValue)
    Tcl_Interp * interp;
    Tcl_Channel chan;
    char * optionName;
    char * newValue;
{
    return (tclStubsPtr->tcl_SetChannelOption)(interp, chan, optionName, newValue);
}

/* Slot 226 */
int
Tcl_SetCommandInfo(interp, cmdName, infoPtr)
    Tcl_Interp * interp;
    char * cmdName;
    Tcl_CmdInfo * infoPtr;
{
    return (tclStubsPtr->tcl_SetCommandInfo)(interp, cmdName, infoPtr);
}

/* Slot 227 */
void
Tcl_SetErrno(err)
    int err;
{
    (tclStubsPtr->tcl_SetErrno)(err);
}

/* Slot 228 */
void
Tcl_SetErrorCode TCL_VARARGS_DEF(Tcl_Interp *,interp)
{
    Tcl_Interp * var;
    va_list argList;

    var = (Tcl_Interp *) TCL_VARARGS_START(Tcl_Interp *,interp,argList);

    (tclStubsPtr->tcl_SetErrorCodeVA)(var, argList);
    va_end(argList);
}

/* Slot 229 */
void
Tcl_SetMaxBlockTime(timePtr)
    Tcl_Time * timePtr;
{
    (tclStubsPtr->tcl_SetMaxBlockTime)(timePtr);
}

/* Slot 230 */
void
Tcl_SetPanicProc(panicProc)
    Tcl_PanicProc * panicProc;
{
    (tclStubsPtr->tcl_SetPanicProc)(panicProc);
}

/* Slot 231 */
int
Tcl_SetRecursionLimit(interp, depth)
    Tcl_Interp * interp;
    int depth;
{
    return (tclStubsPtr->tcl_SetRecursionLimit)(interp, depth);
}

/* Slot 232 */
void
Tcl_SetResult(interp, str, freeProc)
    Tcl_Interp * interp;
    char * str;
    Tcl_FreeProc * freeProc;
{
    (tclStubsPtr->tcl_SetResult)(interp, str, freeProc);
}

/* Slot 233 */
int
Tcl_SetServiceMode(mode)
    int mode;
{
    return (tclStubsPtr->tcl_SetServiceMode)(mode);
}

/* Slot 234 */
void
Tcl_SetObjErrorCode(interp, errorObjPtr)
    Tcl_Interp * interp;
    Tcl_Obj * errorObjPtr;
{
    (tclStubsPtr->tcl_SetObjErrorCode)(interp, errorObjPtr);
}

/* Slot 235 */
void
Tcl_SetObjResult(interp, resultObjPtr)
    Tcl_Interp * interp;
    Tcl_Obj * resultObjPtr;
{
    (tclStubsPtr->tcl_SetObjResult)(interp, resultObjPtr);
}

/* Slot 236 */
void
Tcl_SetStdChannel(channel, type)
    Tcl_Channel channel;
    int type;
{
    (tclStubsPtr->tcl_SetStdChannel)(channel, type);
}

/* Slot 237 */
char *
Tcl_SetVar(interp, varName, newValue, flags)
    Tcl_Interp * interp;
    char * varName;
    char * newValue;
    int flags;
{
    return (tclStubsPtr->tcl_SetVar)(interp, varName, newValue, flags);
}

/* Slot 238 */
char *
Tcl_SetVar2(interp, part1, part2, newValue, flags)
    Tcl_Interp * interp;
    char * part1;
    char * part2;
    char * newValue;
    int flags;
{
    return (tclStubsPtr->tcl_SetVar2)(interp, part1, part2, newValue, flags);
}

/* Slot 239 */
char *
Tcl_SignalId(sig)
    int sig;
{
    return (tclStubsPtr->tcl_SignalId)(sig);
}

/* Slot 240 */
char *
Tcl_SignalMsg(sig)
    int sig;
{
    return (tclStubsPtr->tcl_SignalMsg)(sig);
}

/* Slot 241 */
void
Tcl_SourceRCFile(interp)
    Tcl_Interp * interp;
{
    (tclStubsPtr->tcl_SourceRCFile)(interp);
}

/* Slot 242 */
int
Tcl_SplitList(interp, listStr, argcPtr, argvPtr)
    Tcl_Interp * interp;
    CONST char * listStr;
    int * argcPtr;
    char *** argvPtr;
{
    return (tclStubsPtr->tcl_SplitList)(interp, listStr, argcPtr, argvPtr);
}

/* Slot 243 */
void
Tcl_SplitPath(path, argcPtr, argvPtr)
    CONST char * path;
    int * argcPtr;
    char *** argvPtr;
{
    (tclStubsPtr->tcl_SplitPath)(path, argcPtr, argvPtr);
}

/* Slot 244 */
void
Tcl_StaticPackage(interp, pkgName, initProc, safeInitProc)
    Tcl_Interp * interp;
    char * pkgName;
    Tcl_PackageInitProc * initProc;
    Tcl_PackageInitProc * safeInitProc;
{
    (tclStubsPtr->tcl_StaticPackage)(interp, pkgName, initProc, safeInitProc);
}

/* Slot 245 */
int
Tcl_StringMatch(str, pattern)
    CONST char * str;
    CONST char * pattern;
{
    return (tclStubsPtr->tcl_StringMatch)(str, pattern);
}

/* Slot 246 */
int
Tcl_Tell(chan)
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_Tell)(chan);
}

/* Slot 247 */
int
Tcl_TraceVar(interp, varName, flags, proc, clientData)
    Tcl_Interp * interp;
    char * varName;
    int flags;
    Tcl_VarTraceProc * proc;
    ClientData clientData;
{
    return (tclStubsPtr->tcl_TraceVar)(interp, varName, flags, proc, clientData);
}

/* Slot 248 */
int
Tcl_TraceVar2(interp, part1, part2, flags, proc, clientData)
    Tcl_Interp * interp;
    char * part1;
    char * part2;
    int flags;
    Tcl_VarTraceProc * proc;
    ClientData clientData;
{
    return (tclStubsPtr->tcl_TraceVar2)(interp, part1, part2, flags, proc, clientData);
}

/* Slot 249 */
char *
Tcl_TranslateFileName(interp, name, bufferPtr)
    Tcl_Interp * interp;
    CONST char * name;
    Tcl_DString * bufferPtr;
{
    return (tclStubsPtr->tcl_TranslateFileName)(interp, name, bufferPtr);
}

/* Slot 250 */
int
Tcl_Ungets(chan, str, len, atHead)
    Tcl_Channel chan;
    char * str;
    int len;
    int atHead;
{
    return (tclStubsPtr->tcl_Ungets)(chan, str, len, atHead);
}

/* Slot 251 */
void
Tcl_UnlinkVar(interp, varName)
    Tcl_Interp * interp;
    char * varName;
{
    (tclStubsPtr->tcl_UnlinkVar)(interp, varName);
}

/* Slot 252 */
int
Tcl_UnregisterChannel(interp, chan)
    Tcl_Interp * interp;
    Tcl_Channel chan;
{
    return (tclStubsPtr->tcl_UnregisterChannel)(interp, chan);
}

/* Slot 253 */
int
Tcl_UnsetVar(interp, varName, flags)
    Tcl_Interp * interp;
    char * varName;
    int flags;
{
    return (tclStubsPtr->tcl_UnsetVar)(interp, varName, flags);
}

/* Slot 254 */
int
Tcl_UnsetVar2(interp, part1, part2, flags)
    Tcl_Interp * interp;
    char * part1;
    char * part2;
    int flags;
{
    return (tclStubsPtr->tcl_UnsetVar2)(interp, part1, part2, flags);
}

/* Slot 255 */
void
Tcl_UntraceVar(interp, varName, flags, proc, clientData)
    Tcl_Interp * interp;
    char * varName;
    int flags;
    Tcl_VarTraceProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_UntraceVar)(interp, varName, flags, proc, clientData);
}

/* Slot 256 */
void
Tcl_UntraceVar2(interp, part1, part2, flags, proc, clientData)
    Tcl_Interp * interp;
    char * part1;
    char * part2;
    int flags;
    Tcl_VarTraceProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_UntraceVar2)(interp, part1, part2, flags, proc, clientData);
}

/* Slot 257 */
void
Tcl_UpdateLinkedVar(interp, varName)
    Tcl_Interp * interp;
    char * varName;
{
    (tclStubsPtr->tcl_UpdateLinkedVar)(interp, varName);
}

/* Slot 258 */
int
Tcl_UpVar(interp, frameName, varName, localName, flags)
    Tcl_Interp * interp;
    char * frameName;
    char * varName;
    char * localName;
    int flags;
{
    return (tclStubsPtr->tcl_UpVar)(interp, frameName, varName, localName, flags);
}

/* Slot 259 */
int
Tcl_UpVar2(interp, frameName, part1, part2, localName, flags)
    Tcl_Interp * interp;
    char * frameName;
    char * part1;
    char * part2;
    char * localName;
    int flags;
{
    return (tclStubsPtr->tcl_UpVar2)(interp, frameName, part1, part2, localName, flags);
}

/* Slot 260 */
int
Tcl_VarEval TCL_VARARGS_DEF(Tcl_Interp *,interp)
{
    Tcl_Interp * var;
    va_list argList;
    int resultValue;

    var = (Tcl_Interp *) TCL_VARARGS_START(Tcl_Interp *,interp,argList);

    resultValue = (tclStubsPtr->tcl_VarEvalVA)(var, argList);
    va_end(argList);
return resultValue;
}

/* Slot 261 */
ClientData
Tcl_VarTraceInfo(interp, varName, flags, procPtr, prevClientData)
    Tcl_Interp * interp;
    char * varName;
    int flags;
    Tcl_VarTraceProc * procPtr;
    ClientData prevClientData;
{
    return (tclStubsPtr->tcl_VarTraceInfo)(interp, varName, flags, procPtr, prevClientData);
}

/* Slot 262 */
ClientData
Tcl_VarTraceInfo2(interp, part1, part2, flags, procPtr, prevClientData)
    Tcl_Interp * interp;
    char * part1;
    char * part2;
    int flags;
    Tcl_VarTraceProc * procPtr;
    ClientData prevClientData;
{
    return (tclStubsPtr->tcl_VarTraceInfo2)(interp, part1, part2, flags, procPtr, prevClientData);
}

/* Slot 263 */
int
Tcl_Write(chan, s, slen)
    Tcl_Channel chan;
    char * s;
    int slen;
{
    return (tclStubsPtr->tcl_Write)(chan, s, slen);
}

/* Slot 264 */
void
Tcl_WrongNumArgs(interp, objc, objv, message)
    Tcl_Interp * interp;
    int objc;
    Tcl_Obj *CONST objv[];
    char * message;
{
    (tclStubsPtr->tcl_WrongNumArgs)(interp, objc, objv, message);
}

/* Slot 265 */
int
Tcl_DumpActiveMemory(fileName)
    char * fileName;
{
    return (tclStubsPtr->tcl_DumpActiveMemory)(fileName);
}

/* Slot 266 */
void
Tcl_ValidateAllMemory(file, line)
    char * file;
    int line;
{
    (tclStubsPtr->tcl_ValidateAllMemory)(file, line);
}

/* Slot 267 */
void
Tcl_AppendResultVA(interp, argList)
    Tcl_Interp * interp;
    va_list argList;
{
    (tclStubsPtr->tcl_AppendResultVA)(interp, argList);
}

/* Slot 268 */
void
Tcl_AppendStringsToObjVA(objPtr, argList)
    Tcl_Obj * objPtr;
    va_list argList;
{
    (tclStubsPtr->tcl_AppendStringsToObjVA)(objPtr, argList);
}

/* Slot 269 */
char *
Tcl_HashStats(tablePtr)
    Tcl_HashTable * tablePtr;
{
    return (tclStubsPtr->tcl_HashStats)(tablePtr);
}

/* Slot 270 */
char *
Tcl_ParseVar(interp, str, termPtr)
    Tcl_Interp * interp;
    char * str;
    char ** termPtr;
{
    return (tclStubsPtr->tcl_ParseVar)(interp, str, termPtr);
}

/* Slot 271 */
char *
Tcl_PkgPresent(interp, name, version, exact)
    Tcl_Interp * interp;
    char * name;
    char * version;
    int exact;
{
    return (tclStubsPtr->tcl_PkgPresent)(interp, name, version, exact);
}

/* Slot 272 */
char *
Tcl_PkgPresentEx(interp, name, version, exact, clientDataPtr)
    Tcl_Interp * interp;
    char * name;
    char * version;
    int exact;
    ClientData * clientDataPtr;
{
    return (tclStubsPtr->tcl_PkgPresentEx)(interp, name, version, exact, clientDataPtr);
}

/* Slot 273 */
int
Tcl_PkgProvide(interp, name, version)
    Tcl_Interp * interp;
    char * name;
    char * version;
{
    return (tclStubsPtr->tcl_PkgProvide)(interp, name, version);
}

/* Slot 274 */
char *
Tcl_PkgRequire(interp, name, version, exact)
    Tcl_Interp * interp;
    char * name;
    char * version;
    int exact;
{
    return (tclStubsPtr->tcl_PkgRequire)(interp, name, version, exact);
}

/* Slot 275 */
void
Tcl_SetErrorCodeVA(interp, argList)
    Tcl_Interp * interp;
    va_list argList;
{
    (tclStubsPtr->tcl_SetErrorCodeVA)(interp, argList);
}

/* Slot 276 */
int
Tcl_VarEvalVA(interp, argList)
    Tcl_Interp * interp;
    va_list argList;
{
    return (tclStubsPtr->tcl_VarEvalVA)(interp, argList);
}

/* Slot 277 */
Tcl_Pid
Tcl_WaitPid(pid, statPtr, options)
    Tcl_Pid pid;
    int * statPtr;
    int options;
{
    return (tclStubsPtr->tcl_WaitPid)(pid, statPtr, options);
}

/* Slot 278 */
void
Tcl_PanicVA(format, argList)
    char * format;
    va_list argList;
{
    (tclStubsPtr->tcl_PanicVA)(format, argList);
}

/* Slot 279 */
void
Tcl_GetVersion(major, minor, patchLevel, type)
    int * major;
    int * minor;
    int * patchLevel;
    int * type;
{
    (tclStubsPtr->tcl_GetVersion)(major, minor, patchLevel, type);
}

/* Slot 280 is reserved */
/* Slot 281 is reserved */
/* Slot 282 is reserved */
/* Slot 283 is reserved */
/* Slot 284 is reserved */
/* Slot 285 is reserved */
/* Slot 286 */
void
Tcl_AppendObjToObj(objPtr, appendObjPtr)
    Tcl_Obj * objPtr;
    Tcl_Obj * appendObjPtr;
{
    (tclStubsPtr->tcl_AppendObjToObj)(objPtr, appendObjPtr);
}

/* Slot 287 */
Tcl_Encoding
Tcl_CreateEncoding(typePtr)
    Tcl_EncodingType * typePtr;
{
    return (tclStubsPtr->tcl_CreateEncoding)(typePtr);
}

/* Slot 288 */
void
Tcl_CreateThreadExitHandler(proc, clientData)
    Tcl_ExitProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_CreateThreadExitHandler)(proc, clientData);
}

/* Slot 289 */
void
Tcl_DeleteThreadExitHandler(proc, clientData)
    Tcl_ExitProc * proc;
    ClientData clientData;
{
    (tclStubsPtr->tcl_DeleteThreadExitHandler)(proc, clientData);
}

/* Slot 290 */
void
Tcl_DiscardResult(statePtr)
    Tcl_SavedResult * statePtr;
{
    (tclStubsPtr->tcl_DiscardResult)(statePtr);
}

/* Slot 291 */
int
Tcl_EvalEx(interp, script, numBytes, flags)
    Tcl_Interp * interp;
    char * script;
    int numBytes;
    int flags;
{
    return (tclStubsPtr->tcl_EvalEx)(interp, script, numBytes, flags);
}

/* Slot 292 */
int
Tcl_EvalObjv(interp, objc, objv, flags)
    Tcl_Interp * interp;
    int objc;
    Tcl_Obj *CONST objv[];
    int flags;
{
    return (tclStubsPtr->tcl_EvalObjv)(interp, objc, objv, flags);
}

/* Slot 293 */
int
Tcl_EvalObjEx(interp, objPtr, flags)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    int flags;
{
    return (tclStubsPtr->tcl_EvalObjEx)(interp, objPtr, flags);
}

/* Slot 294 */
void
Tcl_ExitThread(status)
    int status;
{
    (tclStubsPtr->tcl_ExitThread)(status);
}

/* Slot 295 */
int
Tcl_ExternalToUtf(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr)
    Tcl_Interp * interp;
    Tcl_Encoding encoding;
    CONST char * src;
    int srcLen;
    int flags;
    Tcl_EncodingState * statePtr;
    char * dst;
    int dstLen;
    int * srcReadPtr;
    int * dstWrotePtr;
    int * dstCharsPtr;
{
    return (tclStubsPtr->tcl_ExternalToUtf)(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr);
}

/* Slot 296 */
char *
Tcl_ExternalToUtfDString(encoding, src, srcLen, dsPtr)
    Tcl_Encoding encoding;
    CONST char * src;
    int srcLen;
    Tcl_DString * dsPtr;
{
    return (tclStubsPtr->tcl_ExternalToUtfDString)(encoding, src, srcLen, dsPtr);
}

/* Slot 297 */
void
Tcl_FinalizeThread()
{
    (tclStubsPtr->tcl_FinalizeThread)();
}

/* Slot 298 */
void
Tcl_FinalizeNotifier(clientData)
    ClientData clientData;
{
    (tclStubsPtr->tcl_FinalizeNotifier)(clientData);
}

/* Slot 299 */
void
Tcl_FreeEncoding(encoding)
    Tcl_Encoding encoding;
{
    (tclStubsPtr->tcl_FreeEncoding)(encoding);
}

/* Slot 300 */
Tcl_ThreadId
Tcl_GetCurrentThread()
{
    return (tclStubsPtr->tcl_GetCurrentThread)();
}

/* Slot 301 */
Tcl_Encoding
Tcl_GetEncoding(interp, name)
    Tcl_Interp * interp;
    CONST char * name;
{
    return (tclStubsPtr->tcl_GetEncoding)(interp, name);
}

/* Slot 302 */
char *
Tcl_GetEncodingName(encoding)
    Tcl_Encoding encoding;
{
    return (tclStubsPtr->tcl_GetEncodingName)(encoding);
}

/* Slot 303 */
void
Tcl_GetEncodingNames(interp)
    Tcl_Interp * interp;
{
    (tclStubsPtr->tcl_GetEncodingNames)(interp);
}

/* Slot 304 */
int
Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr)
    Tcl_Interp * interp;
    Tcl_Obj * objPtr;
    char ** tablePtr;
    int offset;
    char * msg;
    int flags;
    int * indexPtr;
{
    return (tclStubsPtr->tcl_GetIndexFromObjStruct)(interp, objPtr, tablePtr, offset, msg, flags, indexPtr);
}

/* Slot 305 */
VOID *
Tcl_GetThreadData(keyPtr, size)
    Tcl_ThreadDataKey * keyPtr;
    int size;
{
    return (tclStubsPtr->tcl_GetThreadData)(keyPtr, size);
}

/* Slot 306 */
Tcl_Obj *
Tcl_GetVar2Ex(interp, part1, part2, flags)
    Tcl_Interp * interp;
    char * part1;
    char * part2;
    int flags;
{
    return (tclStubsPtr->tcl_GetVar2Ex)(interp, part1, part2, flags);
}

/* Slot 307 */
ClientData
Tcl_InitNotifier()
{
    return (tclStubsPtr->tcl_InitNotifier)();
}

/* Slot 308 */
void
Tcl_MutexLock(mutexPtr)
    Tcl_Mutex * mutexPtr;
{
    (tclStubsPtr->tcl_MutexLock)(mutexPtr);
}

/* Slot 309 */
void
Tcl_MutexUnlock(mutexPtr)
    Tcl_Mutex * mutexPtr;
{
    (tclStubsPtr->tcl_MutexUnlock)(mutexPtr);
}

/* Slot 310 */
void
Tcl_ConditionNotify(condPtr)
    Tcl_Condition * condPtr;
{
    (tclStubsPtr->tcl_ConditionNotify)(condPtr);
}

/* Slot 311 */
void
Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
    Tcl_Condition * condPtr;
    Tcl_Mutex * mutexPtr;
    Tcl_Time * timePtr;
{
    (tclStubsPtr->tcl_ConditionWait)(condPtr, mutexPtr, timePtr);
}

/* Slot 312 */
int
Tcl_NumUtfChars(src, len)
    CONST char * src;
    int len;
{
    return (tclStubsPtr->tcl_NumUtfChars)(src, len);
}

/* Slot 313 */
int
Tcl_ReadChars(channel, objPtr, charsToRead, appendFlag)
    Tcl_Channel channel;
    Tcl_Obj * objPtr;
    int charsToRead;
    int appendFlag;
{
    return (tclStubsPtr->tcl_ReadChars)(channel, objPtr, charsToRead, appendFlag);
}

/* Slot 314 */
void
Tcl_RestoreResult(interp, statePtr)
    Tcl_Interp * interp;
    Tcl_SavedResult * statePtr;
{
    (tclStubsPtr->tcl_RestoreResult)(interp, statePtr);
}

/* Slot 315 */
void
Tcl_SaveResult(interp, statePtr)
    Tcl_Interp * interp;
    Tcl_SavedResult * statePtr;
{
    (tclStubsPtr->tcl_SaveResult)(interp, statePtr);
}

/* Slot 316 */
int
Tcl_SetSystemEncoding(interp, name)
    Tcl_Interp * interp;
    CONST char * name;
{
    return (tclStubsPtr->tcl_SetSystemEncoding)(interp, name);
}

/* Slot 317 */
Tcl_Obj *
Tcl_SetVar2Ex(interp, part1, part2, newValuePtr, flags)
    Tcl_Interp * interp;
    char * part1;
    char * part2;
    Tcl_Obj * newValuePtr;
    int flags;
{
    return (tclStubsPtr->tcl_SetVar2Ex)(interp, part1, part2, newValuePtr, flags);
}

/* Slot 318 */
void
Tcl_ThreadAlert(threadId)
    Tcl_ThreadId threadId;
{
    (tclStubsPtr->tcl_ThreadAlert)(threadId);
}

/* Slot 319 */
void
Tcl_ThreadQueueEvent(threadId, evPtr, position)
    Tcl_ThreadId threadId;
    Tcl_Event* evPtr;
    Tcl_QueuePosition position;
{
    (tclStubsPtr->tcl_ThreadQueueEvent)(threadId, evPtr, position);
}

/* Slot 320 */
Tcl_UniChar
Tcl_UniCharAtIndex(src, index)
    CONST char * src;
    int index;
{
    return (tclStubsPtr->tcl_UniCharAtIndex)(src, index);
}

/* Slot 321 */
Tcl_UniChar
Tcl_UniCharToLower(ch)
    int ch;
{
    return (tclStubsPtr->tcl_UniCharToLower)(ch);
}

/* Slot 322 */
Tcl_UniChar
Tcl_UniCharToTitle(ch)
    int ch;
{
    return (tclStubsPtr->tcl_UniCharToTitle)(ch);
}

/* Slot 323 */
Tcl_UniChar
Tcl_UniCharToUpper(ch)
    int ch;
{
    return (tclStubsPtr->tcl_UniCharToUpper)(ch);
}

/* Slot 324 */
int
Tcl_UniCharToUtf(ch, buf)
    int ch;
    char * buf;
{
    return (tclStubsPtr->tcl_UniCharToUtf)(ch, buf);
}

/* Slot 325 */
char *
Tcl_UtfAtIndex(src, index)
    CONST char * src;
    int index;
{
    return (tclStubsPtr->tcl_UtfAtIndex)(src, index);
}

/* Slot 326 */
int
Tcl_UtfCharComplete(src, len)
    CONST char * src;
    int len;
{
    return (tclStubsPtr->tcl_UtfCharComplete)(src, len);
}

/* Slot 327 */
int
Tcl_UtfBackslash(src, readPtr, dst)
    CONST char * src;
    int * readPtr;
    char * dst;
{
    return (tclStubsPtr->tcl_UtfBackslash)(src, readPtr, dst);
}

/* Slot 328 */
char *
Tcl_UtfFindFirst(src, ch)
    CONST char * src;
    int ch;
{
    return (tclStubsPtr->tcl_UtfFindFirst)(src, ch);
}

/* Slot 329 */
char *
Tcl_UtfFindLast(src, ch)
    CONST char * src;
    int ch;
{
    return (tclStubsPtr->tcl_UtfFindLast)(src, ch);
}

/* Slot 330 */
char *
Tcl_UtfNext(src)
    CONST char * src;
{
    return (tclStubsPtr->tcl_UtfNext)(src);
}

/* Slot 331 */
char *
Tcl_UtfPrev(src, start)
    CONST char * src;
    CONST char * start;
{
    return (tclStubsPtr->tcl_UtfPrev)(src, start);
}

/* Slot 332 */
int
Tcl_UtfToExternal(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr)
    Tcl_Interp * interp;
    Tcl_Encoding encoding;
    CONST char * src;
    int srcLen;
    int flags;
    Tcl_EncodingState * statePtr;
    char * dst;
    int dstLen;
    int * srcReadPtr;
    int * dstWrotePtr;
    int * dstCharsPtr;
{
    return (tclStubsPtr->tcl_UtfToExternal)(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr);
}

/* Slot 333 */
char *
Tcl_UtfToExternalDString(encoding, src, srcLen, dsPtr)
    Tcl_Encoding encoding;
    CONST char * src;
    int srcLen;
    Tcl_DString * dsPtr;
{
    return (tclStubsPtr->tcl_UtfToExternalDString)(encoding, src, srcLen, dsPtr);
}

/* Slot 334 */
int
Tcl_UtfToLower(src)
    char * src;
{
    return (tclStubsPtr->tcl_UtfToLower)(src);
}

/* Slot 335 */
int
Tcl_UtfToTitle(src)
    char * src;
{
    return (tclStubsPtr->tcl_UtfToTitle)(src);
}

/* Slot 336 */
int
Tcl_UtfToUniChar(src, chPtr)
    CONST char * src;
    Tcl_UniChar * chPtr;
{
    return (tclStubsPtr->tcl_UtfToUniChar)(src, chPtr);
}

/* Slot 337 */
int
Tcl_UtfToUpper(src)
    char * src;
{
    return (tclStubsPtr->tcl_UtfToUpper)(src);
}

/* Slot 338 */
int
Tcl_WriteChars(chan, src, srcLen)
    Tcl_Channel chan;
    CONST char * src;
    int srcLen;
{
    return (tclStubsPtr->tcl_WriteChars)(chan, src, srcLen);
}

/* Slot 339 */
int
Tcl_WriteObj(chan, objPtr)
    Tcl_Channel chan;
    Tcl_Obj * objPtr;
{
    return (tclStubsPtr->tcl_WriteObj)(chan, objPtr);
}

/* Slot 340 */
char *
Tcl_GetString(objPtr)
    Tcl_Obj * objPtr;
{
    return (tclStubsPtr->tcl_GetString)(objPtr);
}

/* Slot 341 */
char *
Tcl_GetDefaultEncodingDir()
{
    return (tclStubsPtr->tcl_GetDefaultEncodingDir)();
}

/* Slot 342 */
void
Tcl_SetDefaultEncodingDir(path)
    char * path;
{
    (tclStubsPtr->tcl_SetDefaultEncodingDir)(path);
}

/* Slot 343 */
void
Tcl_AlertNotifier(clientData)
    ClientData clientData;
{
    (tclStubsPtr->tcl_AlertNotifier)(clientData);
}

/* Slot 344 */
void
Tcl_ServiceModeHook(mode)
    int mode;
{
    (tclStubsPtr->tcl_ServiceModeHook)(mode);
}


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

Changes to generic/tclTest.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
/* 
 * tclTest.c --
 *
 *	This file contains C command procedures for a bunch of additional
 *	Tcl commands that are used for testing out Tcl's C interfaces.
 *	These commands are not normally included in Tcl applications;
 *	they're only used for testing.
 *
 * Copyright (c) 1993-1994 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclTest.c 1.119 97/10/31 15:57:28
 */

#define TCL_TEST

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



/*
 * Declare external functions used in Windows tests.
 */

#if defined(__WIN32__)
extern TclPlatformType *	TclWinGetPlatform _ANSI_ARGS_((void));

#endif

/*
 * Dynamic string shared by TestdcallCmd and DelCallbackProc;  used
 * to collect the results of the various deletion callbacks.
 */











>




|






>
>






|
>







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
/* 
 * tclTest.c --
 *
 *	This file contains C command procedures for a bunch of additional
 *	Tcl commands that are used for testing out Tcl's C interfaces.
 *	These commands are not normally included in Tcl applications;
 *	they're only used for testing.
 *
 * Copyright (c) 1993-1994 The Regents of the University of California.
 * Copyright (c) 1994-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: tclTest.c,v 1.1.2.16 1999/04/14 00:33:27 surles Exp $
 */

#define TCL_TEST

#include "tclInt.h"
#include "tclPort.h"
#include "tclRegexp.h"
#include <locale.h>

/*
 * Declare external functions used in Windows tests.
 */

#if defined(__WIN32__)
extern TclPlatformType *TclWinGetPlatform(void);
EXTERN void		TclWinSetInterfaces(int);
#endif

/*
 * Dynamic string shared by TestdcallCmd and DelCallbackProc;  used
 * to collect the results of the various deletion callbacks.
 */

72
73
74
75
76
77
78


















79
80
81
82
83
84
85

typedef struct DelCmd {
    Tcl_Interp *interp;		/* Interpreter in which command exists. */
    char *deleteCmd;		/* Script to execute when command is
				 * deleted.  Malloc'ed. */
} DelCmd;



















/*
 * Forward declarations for procedures defined later in this file:
 */

int			Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
static int		AsyncHandlerProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int code));







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







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

typedef struct DelCmd {
    Tcl_Interp *interp;		/* Interpreter in which command exists. */
    char *deleteCmd;		/* Script to execute when command is
				 * deleted.  Malloc'ed. */
} DelCmd;

/*
 * The following is used to keep track of an encoding that invokes a Tcl
 * command. 
 */

typedef struct TclEncoding {
    Tcl_Interp *interp;
    char *toUtfCmd;
    char *fromUtfCmd;
} TclEncoding;

/*
 * The counter below is used to determine if the TestsaveresultFree
 * routine was called for a result.
 */

static int freeCount;

/*
 * Forward declarations for procedures defined later in this file:
 */

int			Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
static int		AsyncHandlerProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int code));
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
			    ClientData clientData, Tcl_Interp *interp,
			    int argc, char **argv));
static void		DelCallbackProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp));
static int		DelCmdProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int argc, char **argv));
static void		DelDeleteProc _ANSI_ARGS_((ClientData clientData));











static void		ExitProcEven _ANSI_ARGS_((ClientData clientData));
static void		ExitProcOdd _ANSI_ARGS_((ClientData clientData));
static int              GetTimesCmd _ANSI_ARGS_((ClientData clientData,
                            Tcl_Interp *interp, int argc, char **argv));
static int              NoopCmd _ANSI_ARGS_((ClientData clientData,
                            Tcl_Interp *interp, int argc, char **argv));
static int              NoopObjCmd _ANSI_ARGS_((ClientData clientData,
                            Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));



static void		SpecialFree _ANSI_ARGS_((char *blockPtr));
static int		StaticInitProc _ANSI_ARGS_((Tcl_Interp *interp));








static int		TestasyncCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestcmdinfoCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestcmdtokenCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestcmdtraceCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestchmodCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestcreatecommandCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestdcallCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestdelCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestdelassocdataCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestdstringCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));









static int		TestexithandlerCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestexprlongCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));



static int		TestexprstringCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestfileCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestfeventCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestgetassocdataCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestgetplatformCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestgetvarfullnameCmd _ANSI_ARGS_((
			    ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[]));
static int		TestinterpdeleteCmd _ANSI_ARGS_((ClientData dummy,
		            Tcl_Interp *interp, int argc, char **argv));
static int		TestlinkCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));



static int		TestMathFunc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, Tcl_Value *args,
			    Tcl_Value *resultPtr));
static int		TestMathFunc2 _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, Tcl_Value *args,
			    Tcl_Value *resultPtr));






static int		TestPanicCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));


















static int		TestsetassocdataCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestsetnoerrCmd _ANSI_ARGS_((ClientData dummy,
		            Tcl_Interp *interp, int argc, char **argv));
static int		TestsetobjerrorcodeCmd _ANSI_ARGS_((
			    ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[]));


static int		TestsetplatformCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestsetrecursionlimitCmd _ANSI_ARGS_((
                            ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[]));
static int		TeststaticpkgCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));








static int		TesttranslatefilenameCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestupvarCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestwordendObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));

/*
 * External (platform specific) initialization routine:


 */

EXTERN int		TclplatformtestInit _ANSI_ARGS_((
			    Tcl_Interp *interp));

/*
 *----------------------------------------------------------------------
 *
 * Tcltest_Init --
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in interp->result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */








>
>
>
>
>
>
>
>
>
>
>







|
>
>
>


>
>
>
>
>
>
>
>




















>
>
>
>
>
>
>
>
>




>
>
>

















>
>
>






>
>
>
>
>
>
|

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


|
|



>
>







>
>
>
>
>
>
>
>




<
<
<


|
>
>


|
|












|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
			    ClientData clientData, Tcl_Interp *interp,
			    int argc, char **argv));
static void		DelCallbackProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp));
static int		DelCmdProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, int argc, char **argv));
static void		DelDeleteProc _ANSI_ARGS_((ClientData clientData));
static void		EncodingFreeProc _ANSI_ARGS_((ClientData clientData));
static int		EncodingToUtfProc _ANSI_ARGS_((ClientData clientData,
			    CONST char *src, int srcLen, int flags,
			    Tcl_EncodingState *statePtr, char *dst,
			    int dstLen, int *srcReadPtr, int *dstWrotePtr,
			    int *dstCharsPtr));
static int		EncodingFromUtfProc _ANSI_ARGS_((ClientData clientData,
			    CONST char *src, int srcLen, int flags,
			    Tcl_EncodingState *statePtr, char *dst,
			    int dstLen, int *srcReadPtr, int *dstWrotePtr,
			    int *dstCharsPtr));
static void		ExitProcEven _ANSI_ARGS_((ClientData clientData));
static void		ExitProcOdd _ANSI_ARGS_((ClientData clientData));
static int              GetTimesCmd _ANSI_ARGS_((ClientData clientData,
                            Tcl_Interp *interp, int argc, char **argv));
static int              NoopCmd _ANSI_ARGS_((ClientData clientData,
                            Tcl_Interp *interp, int argc, char **argv));
static int              NoopObjCmd _ANSI_ARGS_((ClientData clientData,
                            Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static void		PrintParse _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Parse *parsePtr));
static void		SpecialFree _ANSI_ARGS_((char *blockPtr));
static int		StaticInitProc _ANSI_ARGS_((Tcl_Interp *interp));
static int		TestaccessprocCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestAccessProc1 _ANSI_ARGS_((CONST char *path,
			   int mode));
static int		TestAccessProc2 _ANSI_ARGS_((CONST char *path,
			   int mode));
static int		TestAccessProc3 _ANSI_ARGS_((CONST char *path,
			   int mode));
static int		TestasyncCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestcmdinfoCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestcmdtokenCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestcmdtraceCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestchmodCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestcreatecommandCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestdcallCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestdelCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestdelassocdataCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestdstringCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestencodingObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc, 
			    Tcl_Obj *CONST objv[]));
static int		TestevalexObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc, 
			    Tcl_Obj *CONST objv[]));
static int		TestevalobjvObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc, 
			    Tcl_Obj *CONST objv[]));
static int		TestexithandlerCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestexprlongCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestexprparserObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int		TestexprstringCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestfileCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestfeventCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestgetassocdataCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestgetplatformCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestgetvarfullnameCmd _ANSI_ARGS_((
			    ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[]));
static int		TestinterpdeleteCmd _ANSI_ARGS_((ClientData dummy,
		            Tcl_Interp *interp, int argc, char **argv));
static int		TestlinkCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestlocaleCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int		TestMathFunc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, Tcl_Value *args,
			    Tcl_Value *resultPtr));
static int		TestMathFunc2 _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp, Tcl_Value *args,
			    Tcl_Value *resultPtr));
static Tcl_Channel	TestOpenFileChannelProc1 _ANSI_ARGS_((Tcl_Interp *interp,
			    char *filename, char *modeString, int permissions));
static Tcl_Channel	TestOpenFileChannelProc2 _ANSI_ARGS_((Tcl_Interp *interp,
			    char *filename, char *modeString, int permissions));
static Tcl_Channel	TestOpenFileChannelProc3 _ANSI_ARGS_((Tcl_Interp *interp,
			    char *filename, char *modeString, int permissions));
static int		TestpanicCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestparserObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int		TestparsevarObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int		TestparsevarnameObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int		TestregexpObjCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static void		TestregexpXflags _ANSI_ARGS_((char *string,
			    int length, int *cflagsPtr, int *eflagsPtr));
static int		TestsaveresultCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static void		TestsaveresultFree _ANSI_ARGS_((char *blockPtr));
static int		TestsetassocdataCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestsetCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestsetobjerrorcodeCmd _ANSI_ARGS_((
			    ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[]));
static int		TestopenfilechannelprocCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestsetplatformCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestsetrecursionlimitCmd _ANSI_ARGS_((
                            ClientData dummy, Tcl_Interp *interp,
			    int objc, Tcl_Obj *CONST objv[]));
static int		TeststaticpkgCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestStatProc1 _ANSI_ARGS_((CONST char *path,
			    TclStat_ *buf));
static int		TestStatProc2 _ANSI_ARGS_((CONST char *path,
			    TclStat_ *buf));
static int		TestStatProc3 _ANSI_ARGS_((CONST char *path,
			    TclStat_ *buf));
static int		TeststatprocCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TesttranslatefilenameCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestupvarCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));




/*
 * External (platform specific) initialization routine, these declarations
 * explicitly don't use EXTERN since this code does not get compiled
 * into the library:
 */

extern int		TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
extern int		TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp));

/*
 *----------------------------------------------------------------------
 *
 * Tcltest_Init --
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in the interp's result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */

228
229
230
231
232
233
234


235
236
237


238
239
240
241
242
243
244
        return TCL_ERROR;
    }

    /*
     * Create additional commands and math functions for testing Tcl.
     */



    Tcl_CreateCommand(interp, "noop", NoopCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, (ClientData) 0,


	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testasync", TestasyncCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testchannel", TclTestChannelCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testchannelevent", TclTestChannelEventCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);







>
>



>
>







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
        return TCL_ERROR;
    }

    /*
     * Create additional commands and math functions for testing Tcl.
     */

    Tcl_CreateCommand(interp, "gettimes", GetTimesCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "noop", NoopCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testaccessproc", TestaccessprocCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testasync", TestasyncCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testchannel", TclTestChannelCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testchannelevent", TclTestChannelEventCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
257
258
259
260
261
262
263






264
265
266
267


268
269


270
271
272
273
274
275
276
277
278
279
280
281
282

















283
284
285
286


287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313


314
315
316
317






318
319
320
321
322
323
324
    Tcl_CreateCommand(interp, "testdel", TestdelCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testdelassocdata", TestdelassocdataCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_DStringInit(&dstring);
    Tcl_CreateCommand(interp, "testdstring", TestdstringCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);






    Tcl_CreateCommand(interp, "testexithandler", TestexithandlerCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testexprlong", TestexprlongCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);


    Tcl_CreateCommand(interp, "testexprstring", TestexprstringCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);


    Tcl_CreateCommand(interp, "testfile", TestfileCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testgetassocdata", TestgetassocdataCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testgetplatform", TestgetplatformCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testgetvarfullname",
	    TestgetvarfullnameCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testinterpdelete", TestinterpdeleteCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testlink", TestlinkCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);

















    Tcl_CreateCommand(interp, "testsetassocdata", TestsetassocdataCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testsetnoerr", TestsetnoerrCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);


    Tcl_CreateObjCommand(interp, "testsetobjerrorcode", 
	    TestsetobjerrorcodeCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testsetplatform", TestsetplatformCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testsetrecursionlimit",
	    TestsetrecursionlimitCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "teststaticpkg", TeststaticpkgCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testtranslatefilename",
            TesttranslatefilenameCmd, (ClientData) 0,
            (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testwordend", TestwordendObjCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testfevent", TestfeventCmd, (ClientData) 0,
            (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testpanic", TestPanicCmd, (ClientData) 0,
            (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "gettimes", GetTimesCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateMathFunc(interp, "T1", 0, (Tcl_ValueType *) NULL, TestMathFunc,
	    (ClientData) 123);
    Tcl_CreateMathFunc(interp, "T2", 0, (Tcl_ValueType *) NULL, TestMathFunc,
	    (ClientData) 345);


    t3ArgTypes[0] = TCL_EITHER;
    t3ArgTypes[1] = TCL_EITHER;
    Tcl_CreateMathFunc(interp, "T3", 2, t3ArgTypes, TestMathFunc2,
	    (ClientData) 0);







    /*
     * And finally add any platform specific test commands.
     */
    
    return TclplatformtestInit(interp);
}







>
>
>
>
>
>




>
>


>
>













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


|

>
>















<
<
<
<
<
<
<
<




>
>




>
>
>
>
>
>







353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426








427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
    Tcl_CreateCommand(interp, "testdel", TestdelCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testdelassocdata", TestdelassocdataCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_DStringInit(&dstring);
    Tcl_CreateCommand(interp, "testdstring", TestdstringCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testencoding", TestencodingObjCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testevalex", TestevalexObjCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testevalobjv", TestevalobjvObjCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testexithandler", TestexithandlerCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testexprlong", TestexprlongCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testexprparser", TestexprparserObjCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testexprstring", TestexprstringCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testfevent", TestfeventCmd, (ClientData) 0,
            (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testfile", TestfileCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testgetassocdata", TestgetassocdataCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testgetplatform", TestgetplatformCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testgetvarfullname",
	    TestgetvarfullnameCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testinterpdelete", TestinterpdeleteCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testlink", TestlinkCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testlocale", TestlocaleCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testopenfilechannelproc",
    	    TestopenfilechannelprocCmd, (ClientData) 0, 
    	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testpanic", TestpanicCmd, (ClientData) 0,
            (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testparser", TestparserObjCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testparsevar", TestparsevarObjCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testparsevarname", TestparsevarnameObjCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testregexp", TestregexpObjCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testsaveresult", TestsaveresultCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testsetassocdata", TestsetassocdataCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testsetnoerr", TestsetCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testseterr", TestsetCmd,
            (ClientData) TCL_LEAVE_ERR_MSG, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testsetobjerrorcode", 
	    TestsetobjerrorcodeCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testsetplatform", TestsetplatformCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateObjCommand(interp, "testsetrecursionlimit",
	    TestsetrecursionlimitCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "teststaticpkg", TeststaticpkgCmd,
	    (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testtranslatefilename",
            TesttranslatefilenameCmd, (ClientData) 0,
            (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);








    Tcl_CreateMathFunc(interp, "T1", 0, (Tcl_ValueType *) NULL, TestMathFunc,
	    (ClientData) 123);
    Tcl_CreateMathFunc(interp, "T2", 0, (Tcl_ValueType *) NULL, TestMathFunc,
	    (ClientData) 345);
    Tcl_CreateCommand(interp, "teststatproc", TeststatprocCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    t3ArgTypes[0] = TCL_EITHER;
    t3ArgTypes[1] = TCL_EITHER;
    Tcl_CreateMathFunc(interp, "T3", 2, t3ArgTypes, TestMathFunc2,
	    (ClientData) 0);

#ifdef TCL_THREADS
    if (TclThread_Init(interp) != TCL_OK) {
	return TCL_ERROR;
    }
#endif

    /*
     * And finally add any platform specific test commands.
     */
    
    return TclplatformtestInit(interp);
}
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
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    TestAsyncHandler *asyncPtr, *prevPtr;
    int id, code;
    static int nextId = 1;
    char buf[30];

    if (argc < 2) {
	wrongNumArgs:
	Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
	return TCL_ERROR;
    }
    if (strcmp(argv[1], "create") == 0) {
	if (argc != 3) {
	    goto wrongNumArgs;
	}
	asyncPtr = (TestAsyncHandler *) ckalloc(sizeof(TestAsyncHandler));
	asyncPtr->id = nextId;
	nextId++;
	asyncPtr->handler = Tcl_AsyncCreate(AsyncHandlerProc,
		(ClientData) asyncPtr);
	asyncPtr->command = (char *) ckalloc((unsigned) (strlen(argv[2]) + 1));
	strcpy(asyncPtr->command, argv[2]);
	asyncPtr->nextPtr = firstHandler;
	firstHandler = asyncPtr;
	sprintf(buf, "%d", asyncPtr->id);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else if (strcmp(argv[1], "delete") == 0) {
	if (argc == 2) {
	    while (firstHandler != NULL) {
		asyncPtr = firstHandler;
		firstHandler = asyncPtr->nextPtr;
		Tcl_AsyncDelete(asyncPtr->handler);







|



















|







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
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    TestAsyncHandler *asyncPtr, *prevPtr;
    int id, code;
    static int nextId = 1;
    char buf[TCL_INTEGER_SPACE];

    if (argc < 2) {
	wrongNumArgs:
	Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
	return TCL_ERROR;
    }
    if (strcmp(argv[1], "create") == 0) {
	if (argc != 3) {
	    goto wrongNumArgs;
	}
	asyncPtr = (TestAsyncHandler *) ckalloc(sizeof(TestAsyncHandler));
	asyncPtr->id = nextId;
	nextId++;
	asyncPtr->handler = Tcl_AsyncCreate(AsyncHandlerProc,
		(ClientData) asyncPtr);
	asyncPtr->command = (char *) ckalloc((unsigned) (strlen(argv[2]) + 1));
	strcpy(asyncPtr->command, argv[2]);
	asyncPtr->nextPtr = firstHandler;
	firstHandler = asyncPtr;
	TclFormatInt(buf, asyncPtr->id);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else if (strcmp(argv[1], "delete") == 0) {
	if (argc == 2) {
	    while (firstHandler != NULL) {
		asyncPtr = firstHandler;
		firstHandler = asyncPtr->nextPtr;
		Tcl_AsyncDelete(asyncPtr->handler);
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
    ClientData clientData;	/* Pointer to TestAsyncHandler structure. */
    Tcl_Interp *interp;		/* Interpreter in which command was
				 * executed, or NULL. */
    int code;			/* Current return code from command. */
{
    TestAsyncHandler *asyncPtr = (TestAsyncHandler *) clientData;
    char *listArgv[4];
    char string[20], *cmd;

    sprintf(string, "%d", code);
    listArgv[0] = asyncPtr->command;
    listArgv[1] = interp->result;
    listArgv[2] = string;
    listArgv[3] = NULL;
    cmd = Tcl_Merge(3, listArgv);
    code = Tcl_Eval(interp, cmd);
    ckfree(cmd);
    return code;
}







|

|

|







561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
    ClientData clientData;	/* Pointer to TestAsyncHandler structure. */
    Tcl_Interp *interp;		/* Interpreter in which command was
				 * executed, or NULL. */
    int code;			/* Current return code from command. */
{
    TestAsyncHandler *asyncPtr = (TestAsyncHandler *) clientData;
    char *listArgv[4];
    char string[TCL_INTEGER_SPACE], *cmd;

    TclFormatInt(string, code);
    listArgv[0] = asyncPtr->command;
    listArgv[1] = Tcl_GetStringResult(interp);
    listArgv[2] = string;
    listArgv[3] = NULL;
    cmd = Tcl_Merge(3, listArgv);
    code = Tcl_Eval(interp, cmd);
    ckfree(cmd);
    return code;
}
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
	}

	objPtr = Tcl_NewObj();
	Tcl_GetCommandFullName(interp, (Tcl_Command) l, objPtr);
	
	Tcl_AppendElement(interp,
	        Tcl_GetCommandName(interp, (Tcl_Command) l));
	Tcl_AppendElement(interp,
		Tcl_GetStringFromObj(objPtr, (int *) NULL));
	Tcl_DecrRefCount(objPtr);
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1],
		"\": must be create or name", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;







|
<







763
764
765
766
767
768
769
770

771
772
773
774
775
776
777
	}

	objPtr = Tcl_NewObj();
	Tcl_GetCommandFullName(interp, (Tcl_Command) l, objPtr);
	
	Tcl_AppendElement(interp,
	        Tcl_GetCommandName(interp, (Tcl_Command) l));
	Tcl_AppendElement(interp, Tcl_GetString(objPtr));

	Tcl_DecrRefCount(objPtr);
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1],
		"\": must be create or name", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
	 * called. Note that this trace procedure removes itself as a
	 * further check of the robustness of the trace proc calling code in
	 * TclExecuteByteCode.
	 */
	
	cmdTrace = Tcl_CreateTrace(interp, 50000,
	        (Tcl_CmdTraceProc *) CmdTraceDeleteProc, (ClientData) NULL);
	result = Tcl_Eval(interp, argv[2]);
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1],
		"\": must be tracetest or deletetest", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}







|







829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
	 * called. Note that this trace procedure removes itself as a
	 * further check of the robustness of the trace proc calling code in
	 * TclExecuteByteCode.
	 */
	
	cmdTrace = Tcl_CreateTrace(interp, 50000,
	        (Tcl_CmdTraceProc *) CmdTraceDeleteProc, (ClientData) NULL);
	Tcl_Eval(interp, argv[2]);
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1],
		"\": must be tracetest or deletetest", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
static void
DelCallbackProc(clientData, interp)
    ClientData clientData;		/* Numerical value to append to
					 * delString. */
    Tcl_Interp *interp;			/* Interpreter being deleted. */
{
    int id = (int) clientData;
    char buffer[10];

    sprintf(buffer, "%d", id);
    Tcl_DStringAppendElement(&delString, buffer);
    if (interp != delInterp) {
	Tcl_DStringAppendElement(&delString, "bogus interpreter argument!");
    }
}

/*







|

|







1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
static void
DelCallbackProc(clientData, interp)
    ClientData clientData;		/* Numerical value to append to
					 * delString. */
    Tcl_Interp *interp;			/* Interpreter being deleted. */
{
    int id = (int) clientData;
    char buffer[TCL_INTEGER_SPACE];

    TclFormatInt(buffer, id);
    Tcl_DStringAppendElement(&delString, buffer);
    if (interp != delInterp) {
	Tcl_DStringAppendElement(&delString, "bogus interpreter argument!");
    }
}

/*
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
	    Tcl_AppendResult(interp, "bad gresult option \"", argv[2],
		    "\": must be staticsmall, staticlarge, free, or special",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	Tcl_DStringGetResult(interp, &dstring);
    } else if (strcmp(argv[1], "length") == 0) {
	char buf[30];
	
	if (argc != 2) {
	    goto wrongNumArgs;
	}
	sprintf(buf, "%d", Tcl_DStringLength(&dstring));
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else if (strcmp(argv[1], "result") == 0) {
	if (argc != 2) {
	    goto wrongNumArgs;
	}
	Tcl_DStringResult(interp, &dstring);
    } else if (strcmp(argv[1], "trunc") == 0) {







|




|







1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
	    Tcl_AppendResult(interp, "bad gresult option \"", argv[2],
		    "\": must be staticsmall, staticlarge, free, or special",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	Tcl_DStringGetResult(interp, &dstring);
    } else if (strcmp(argv[1], "length") == 0) {
	char buf[TCL_INTEGER_SPACE];
	
	if (argc != 2) {
	    goto wrongNumArgs;
	}
	TclFormatInt(buf, Tcl_DStringLength(&dstring));
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else if (strcmp(argv[1], "result") == 0) {
	if (argc != 2) {
	    goto wrongNumArgs;
	}
	Tcl_DStringResult(interp, &dstring);
    } else if (strcmp(argv[1], "trunc") == 0) {
1165
1166
1167
1168
1169
1170
1171























































































































































































































































































1172
1173
1174
1175
1176
1177
1178
 */

static void SpecialFree(blockPtr)
    char *blockPtr;			/* Block to free. */
{
    ckfree(blockPtr - 4);
}
























































































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * TestexithandlerCmd --
 *
 *	This procedure implements the "testexithandler" command. It is







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







1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
 */

static void SpecialFree(blockPtr)
    char *blockPtr;			/* Block to free. */
{
    ckfree(blockPtr - 4);
}

/*
 *----------------------------------------------------------------------
 *
 * TestencodingCmd --
 *
 *	This procedure implements the "testencoding" command.  It is used
 *	to test the encoding package.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Load encodings.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
TestencodingObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Tcl_Encoding encoding;
    int index, length;
    char *string;
    TclEncoding *encodingPtr;
    static char *optionStrings[] = {
	"create",	"delete",	"path",
	NULL
    };
    enum options {
	ENC_CREATE,	ENC_DELETE,	ENC_PATH
    };
    
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
	case ENC_CREATE: {
	    Tcl_EncodingType type;

	    if (objc != 5) {
		return TCL_ERROR;
	    }
	    encodingPtr = (TclEncoding *) ckalloc(sizeof(TclEncoding));
	    encodingPtr->interp = interp;

	    string = Tcl_GetStringFromObj(objv[3], &length);
	    encodingPtr->toUtfCmd = (char *) ckalloc((unsigned) (length + 1));
	    memcpy(encodingPtr->toUtfCmd, string, (unsigned) length + 1);

	    string = Tcl_GetStringFromObj(objv[4], &length);
	    encodingPtr->fromUtfCmd = (char *) ckalloc((unsigned) (length + 1));
	    memcpy(encodingPtr->fromUtfCmd, string, (unsigned) (length + 1));

	    string = Tcl_GetStringFromObj(objv[2], &length);

	    type.encodingName = string;
	    type.toUtfProc = EncodingToUtfProc;
	    type.fromUtfProc = EncodingFromUtfProc;
	    type.freeProc = EncodingFreeProc;
	    type.clientData = (ClientData) encodingPtr;
	    type.nullSize = 1;

	    Tcl_CreateEncoding(&type);
	    break;
	}
	case ENC_DELETE: {
	    if (objc != 3) {
		return TCL_ERROR;
	    }
	    encoding = Tcl_GetEncoding(NULL, Tcl_GetString(objv[2]));
	    Tcl_FreeEncoding(encoding);
	    Tcl_FreeEncoding(encoding);
	    break;
	}
	case ENC_PATH: {
	    if (objc == 2) {
		Tcl_SetObjResult(interp, TclGetLibraryPath());
	    } else {
		TclSetLibraryPath(objv[2]);
	    }
	    break;
	}
    }
    return TCL_OK;
}
static int 
EncodingToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
	srcReadPtr, dstWrotePtr, dstCharsPtr)
    ClientData clientData;	/* TclEncoding structure. */
    CONST char *src;		/* Source string in specified encoding. */
    int srcLen;			/* Source string length in bytes. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Current state. */
    char *dst;			/* Output buffer. */
    int dstLen;			/* The maximum length of output buffer. */
    int *srcReadPtr;		/* Filled with number of bytes read. */
    int *dstWrotePtr;		/* Filled with number of bytes stored. */
    int *dstCharsPtr;		/* Filled with number of chars stored. */
{
    int len;
    TclEncoding *encodingPtr;

    encodingPtr = (TclEncoding *) clientData;
    Tcl_GlobalEval(encodingPtr->interp, encodingPtr->toUtfCmd);

    len = strlen(Tcl_GetStringResult(encodingPtr->interp));
    if (len > dstLen) {
	len = dstLen;
    }
    memcpy(dst, Tcl_GetStringResult(encodingPtr->interp), (unsigned) len);
    Tcl_ResetResult(encodingPtr->interp);

    *srcReadPtr = srcLen;
    *dstWrotePtr = len;
    *dstCharsPtr = len;
    return TCL_OK;
}
static int 
EncodingFromUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
	srcReadPtr, dstWrotePtr, dstCharsPtr)
    ClientData clientData;	/* TclEncoding structure. */
    CONST char *src;		/* Source string in specified encoding. */
    int srcLen;			/* Source string length in bytes. */
    int flags;			/* Conversion control flags. */
    Tcl_EncodingState *statePtr;/* Current state. */
    char *dst;			/* Output buffer. */
    int dstLen;			/* The maximum length of output buffer. */
    int *srcReadPtr;		/* Filled with number of bytes read. */
    int *dstWrotePtr;		/* Filled with number of bytes stored. */
    int *dstCharsPtr;		/* Filled with number of chars stored. */
{
    int len;
    TclEncoding *encodingPtr;

    encodingPtr = (TclEncoding *) clientData;
    Tcl_GlobalEval(encodingPtr->interp, encodingPtr->fromUtfCmd);

    len = strlen(Tcl_GetStringResult(encodingPtr->interp));
    if (len > dstLen) {
	len = dstLen;
    }
    memcpy(dst, Tcl_GetStringResult(encodingPtr->interp), (unsigned) len);
    Tcl_ResetResult(encodingPtr->interp);

    *srcReadPtr = srcLen;
    *dstWrotePtr = len;
    *dstCharsPtr = len;
    return TCL_OK;
}
static void
EncodingFreeProc(clientData)
    ClientData clientData;	/* ClientData associated with type. */
{
    TclEncoding *encodingPtr;

    encodingPtr = (TclEncoding *) clientData;
    ckfree((char *) encodingPtr->toUtfCmd);
    ckfree((char *) encodingPtr->fromUtfCmd);
    ckfree((char *) encodingPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TestevalexObjCmd --
 *
 *	This procedure implements the "testevalex" command.  It is
 *	used to test Tcl_EvalEx.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestevalexObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    Interp *iPtr = (Interp *) interp;
    int code, oldFlags, length, flags;
    char *string;

    if (objc == 1) {
	/*
	 * The command was invoked with no arguments, so just toggle
	 * the flag that determines whether we use Tcl_EvalEx.
	 */

	if (iPtr->flags & USE_EVAL_DIRECT) {
	    iPtr->flags &= ~USE_EVAL_DIRECT;
	    Tcl_SetResult(interp, "disabling direct evaluation", TCL_STATIC);
	} else {
	    iPtr->flags |= USE_EVAL_DIRECT;
	    Tcl_SetResult(interp, "enabling direct evaluation", TCL_STATIC);
	}
	return TCL_OK;
    }

    flags = 0;
    if (objc == 3) {
	string = Tcl_GetStringFromObj(objv[2], &length);
	if (strcmp(string, "global") != 0) {
	    Tcl_AppendResult(interp, "bad value \"", string,
		    "\": must be global", (char *) NULL);
	    return TCL_ERROR;
	}
	flags = TCL_EVAL_GLOBAL;
    } else if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "script ?global?");
        return TCL_ERROR;
    }
    Tcl_SetResult(interp, "xxx", TCL_STATIC);

    /*
     * Note, we have to set the USE_EVAL_DIRECT flag in the interpreter
     * in addition to calling Tcl_EvalEx.  This is needed so that even nested
     * commands are evaluated directly.
     */

    oldFlags = iPtr->flags;
    iPtr->flags |= USE_EVAL_DIRECT;
    string = Tcl_GetStringFromObj(objv[1], &length);
    code = Tcl_EvalEx(interp, string, length, flags); 
    iPtr->flags = (iPtr->flags & ~USE_EVAL_DIRECT)
	    | (oldFlags & USE_EVAL_DIRECT);
    return code;
}

/*
 *----------------------------------------------------------------------
 *
 * TestevalobjvObjCmd --
 *
 *	This procedure implements the "testevalobjv" command.  It is
 *	used to test Tcl_EvalObjv.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestevalobjvObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int evalGlobal;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "global word ?word ...?");
        return TCL_ERROR;
    }
    if (Tcl_GetIntFromObj(interp, objv[1], &evalGlobal) != TCL_OK) {
	return TCL_ERROR;
    }
    return Tcl_EvalObjv(interp, objc-2, objv+2,
	    (evalGlobal) ? TCL_EVAL_GLOBAL : 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TestexithandlerCmd --
 *
 *	This procedure implements the "testexithandler" command. It is
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
    return TCL_OK;
}

static void
ExitProcOdd(clientData)
    ClientData clientData;		/* Integer value to print. */
{
    char buf[100];

    sprintf(buf, "odd %d\n", (int) clientData);
    write(1, buf, strlen(buf));
}

static void
ExitProcEven(clientData)
    ClientData clientData;		/* Integer value to print. */
{
    char buf[100];

    sprintf(buf, "even %d\n", (int) clientData);
    write(1, buf, strlen(buf));
}

/*
 *----------------------------------------------------------------------







|









|







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
    return TCL_OK;
}

static void
ExitProcOdd(clientData)
    ClientData clientData;		/* Integer value to print. */
{
    char buf[16 + TCL_INTEGER_SPACE];

    sprintf(buf, "odd %d\n", (int) clientData);
    write(1, buf, strlen(buf));
}

static void
ExitProcEven(clientData)
    ClientData clientData;		/* Integer value to print. */
{
    char buf[16 + TCL_INTEGER_SPACE];

    sprintf(buf, "even %d\n", (int) clientData);
    write(1, buf, strlen(buf));
}

/*
 *----------------------------------------------------------------------
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
TestexprlongCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    long exprResult;
    char buf[30];
    int result;
    
    Tcl_SetResult(interp, "This is a result", TCL_STATIC);
    result = Tcl_ExprLong(interp, "4+1", &exprResult);
    if (result != TCL_OK) {
        return result;
    }







|







1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
TestexprlongCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    long exprResult;
    char buf[4 + TCL_INTEGER_SPACE];
    int result;
    
    Tcl_SetResult(interp, "This is a result", TCL_STATIC);
    result = Tcl_ExprLong(interp, "4+1", &exprResult);
    if (result != TCL_OK) {
        return result;
    }
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
    if (argv[1][0] == '\0') {
        Tcl_AppendResult(interp, "cannot delete current interpreter",
                (char *) NULL);
        return TCL_ERROR;
    }
    slaveToDelete = Tcl_GetSlave(interp, argv[1]);
    if (slaveToDelete == (Tcl_Interp *) NULL) {
        Tcl_AppendResult(interp, "could not find interpreter \"",
                argv[1], "\"", (char *) NULL);
        return TCL_ERROR;
    }
    Tcl_DeleteInterp(slaveToDelete);
    return TCL_OK;
}

/*







<
<







1827
1828
1829
1830
1831
1832
1833


1834
1835
1836
1837
1838
1839
1840
    if (argv[1][0] == '\0') {
        Tcl_AppendResult(interp, "cannot delete current interpreter",
                (char *) NULL);
        return TCL_ERROR;
    }
    slaveToDelete = Tcl_GetSlave(interp, argv[1]);
    if (slaveToDelete == (Tcl_Interp *) NULL) {


        return TCL_ERROR;
    }
    Tcl_DeleteInterp(slaveToDelete);
    return TCL_OK;
}

/*
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
    } else if (strcmp(argv[1], "delete") == 0) {
	Tcl_UnlinkVar(interp, "int");
	Tcl_UnlinkVar(interp, "real");
	Tcl_UnlinkVar(interp, "bool");
	Tcl_UnlinkVar(interp, "string");
	created = 0;
    } else if (strcmp(argv[1], "get") == 0) {
	sprintf(buffer, "%d", intVar);
	Tcl_AppendElement(interp, buffer);
	Tcl_PrintDouble((Tcl_Interp *) NULL, realVar, buffer);
	Tcl_AppendElement(interp, buffer);
	sprintf(buffer, "%d", boolVar);
	Tcl_AppendElement(interp, buffer);
	Tcl_AppendElement(interp, (stringVar == NULL) ? "-" : stringVar);
    } else if (strcmp(argv[1], "set") == 0) {
	if (argc != 6) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " ", argv[1],
		"intValue realValue boolValue stringValue\"", (char *) NULL);







|



|







1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
    } else if (strcmp(argv[1], "delete") == 0) {
	Tcl_UnlinkVar(interp, "int");
	Tcl_UnlinkVar(interp, "real");
	Tcl_UnlinkVar(interp, "bool");
	Tcl_UnlinkVar(interp, "string");
	created = 0;
    } else if (strcmp(argv[1], "get") == 0) {
	TclFormatInt(buffer, intVar);
	Tcl_AppendElement(interp, buffer);
	Tcl_PrintDouble((Tcl_Interp *) NULL, realVar, buffer);
	Tcl_AppendElement(interp, buffer);
	TclFormatInt(buffer, boolVar);
	Tcl_AppendElement(interp, buffer);
	Tcl_AppendElement(interp, (stringVar == NULL) ? "-" : stringVar);
    } else if (strcmp(argv[1], "set") == 0) {
	if (argc != 6) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " ", argv[1],
		"intValue realValue boolValue stringValue\"", (char *) NULL);
1607
1608
1609
1610
1611
1612
1613






























































1614
1615
1616
1617
1618
1619
1620
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *






























































 * TestMathFunc --
 *
 *	This is a user-defined math procedure to test out math procedures
 *	with no arguments.
 *
 * Results:
 *	A normal Tcl completion code.







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







2008
2009
2010
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestlocaleCmd --
 *
 *	This procedure implements the "testlocale" command.  It is used
 *	to test the effects of setting different locales in Tcl.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Modifies the current C locale.
 *
 *----------------------------------------------------------------------
 */

static int
TestlocaleCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* The argument objects. */
{
    int index;
    char *locale;

    static char *optionStrings[] = {
    	"ctype", "numeric", "time", "collate", "monetary", 
	"all",	NULL
    };
    static int lcTypes[] = {
	LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY,
	LC_ALL
    };

    /*
     * LC_CTYPE, etc. correspond to the indices for the strings.
     */

    if (objc < 2 || objc > 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "category ?locale?");
	return TCL_ERROR;
    }
    
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc == 3) {
	locale = Tcl_GetString(objv[2]);
    } else {
	locale = NULL;
    }
    locale = setlocale(lcTypes[index], locale);
    if (locale) {
	Tcl_SetStringObj(Tcl_GetObjResult(interp), locale, -1);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestMathFunc --
 *
 *	This is a user-defined math procedure to test out math procedures
 *	with no arguments.
 *
 * Results:
 *	A normal Tcl completion code.
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672

	/* ARGSUSED */
static int
TestMathFunc2(clientData, interp, args, resultPtr)
    ClientData clientData;		/* Integer value to return. */
    Tcl_Interp *interp;			/* Used to report errors. */
    Tcl_Value *args;			/* Points to an array of two
					 * Tcl_Values for the two
					 * arguments. */
    Tcl_Value *resultPtr;		/* Where to store the result. */
{
    int result = TCL_OK;
    
    /*
     * Return the maximum of the two arguments with the correct type.
     */







|
|







2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135

	/* ARGSUSED */
static int
TestMathFunc2(clientData, interp, args, resultPtr)
    ClientData clientData;		/* Integer value to return. */
    Tcl_Interp *interp;			/* Used to report errors. */
    Tcl_Value *args;			/* Points to an array of two
					 * Tcl_Value structs for the 
					 * two arguments. */
    Tcl_Value *resultPtr;		/* Where to store the result. */
{
    int result = TCL_OK;
    
    /*
     * Return the maximum of the two arguments with the correct type.
     */
1733
1734
1735
1736
1737
1738
1739



































































































































































































































































































































































































































































































































































































































1740
1741
1742
1743
1744
1745
1746
static void
CleanupTestSetassocdataTests(clientData, interp)
    ClientData clientData;		/* Data to be released. */
    Tcl_Interp *interp;			/* Interpreter being deleted. */
{
    ckfree((char *) clientData);
}




































































































































































































































































































































































































































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * TestsetassocdataCmd --
 *
 *	This procedure implements the "testsetassocdata" command. It is used







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







2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
static void
CleanupTestSetassocdataTests(clientData, interp)
    ClientData clientData;		/* Data to be released. */
    Tcl_Interp *interp;			/* Interpreter being deleted. */
{
    ckfree((char *) clientData);
}

/*
 *----------------------------------------------------------------------
 *
 * TestparserObjCmd --
 *
 *	This procedure implements the "testparser" command.  It is
 *	used for testing the new Tcl script parser in Tcl 8.1.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestparserObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* The argument objects. */
{
    char *script;
    int length, dummy;
    Tcl_Parse parse;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "script length");
	return TCL_ERROR;
    }
    script = Tcl_GetStringFromObj(objv[1], &dummy);
    if (Tcl_GetIntFromObj(interp, objv[2], &length)) {
	return TCL_ERROR;
    }
    if (length == 0) {
	length = dummy;
    }
    if (Tcl_ParseCommand(interp, script, length, 0, &parse) != TCL_OK) {
	Tcl_AddErrorInfo(interp, "\n    (remainder of script: \"");
	Tcl_AddErrorInfo(interp, parse.term);
	Tcl_AddErrorInfo(interp, "\")");
	return TCL_ERROR;
    }

    /*
     * The parse completed successfully.  Just print out the contents
     * of the parse structure into the interpreter's result.
     */

    PrintParse(interp, &parse);
    Tcl_FreeParse(&parse);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestexprparserObjCmd --
 *
 *	This procedure implements the "testexprparser" command.  It is
 *	used for testing the new Tcl expression parser in Tcl 8.1.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestexprparserObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* The argument objects. */
{
    char *script;
    int length, dummy;
    Tcl_Parse parse;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "expr length");
	return TCL_ERROR;
    }
    script = Tcl_GetStringFromObj(objv[1], &dummy);
    if (Tcl_GetIntFromObj(interp, objv[2], &length)) {
	return TCL_ERROR;
    }
    if (length == 0) {
	length = dummy;
    }
    if (Tcl_ParseExpr(interp, script, length, &parse) != TCL_OK) {
	Tcl_AddErrorInfo(interp, "\n    (remainder of expr: \"");
	Tcl_AddErrorInfo(interp, parse.term);
	Tcl_AddErrorInfo(interp, "\")");
	return TCL_ERROR;
    }

    /*
     * The parse completed successfully.  Just print out the contents
     * of the parse structure into the interpreter's result.
     */

    PrintParse(interp, &parse);
    Tcl_FreeParse(&parse);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * PrintParse --
 *
 *	This procedure prints out the contents of a Tcl_Parse structure
 *	in the result of an interpreter.
 *
 * Results:
 *	Interp's result is set to a prettily formatted version of the
 *	contents of parsePtr.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
PrintParse(interp, parsePtr)
    Tcl_Interp *interp;		/* Interpreter whose result is to be set to
				 * the contents of a parse structure. */
    Tcl_Parse *parsePtr;	/* Parse structure to print out. */
{
    Tcl_Obj *objPtr;
    char *typeString;
    Tcl_Token *tokenPtr;
    int i;

    objPtr = Tcl_GetObjResult(interp);
    if (parsePtr->commentSize > 0) {
	Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
		Tcl_NewStringObj(parsePtr->commentStart,
			parsePtr->commentSize));
    } else {
	Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
		Tcl_NewStringObj("-", 1));
    }
    Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
	    Tcl_NewStringObj(parsePtr->commandStart, parsePtr->commandSize));
    Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
	    Tcl_NewIntObj(parsePtr->numWords));
    for (i = 0; i < parsePtr->numTokens; i++) {
	tokenPtr = &parsePtr->tokenPtr[i];
	switch (tokenPtr->type) {
	    case TCL_TOKEN_WORD:
		typeString = "word";
		break;
	    case TCL_TOKEN_SIMPLE_WORD:
		typeString = "simple";
		break;
	    case TCL_TOKEN_TEXT:
		typeString = "text";
		break;
	    case TCL_TOKEN_BS:
		typeString = "backslash";
		break;
	    case TCL_TOKEN_COMMAND:
		typeString = "command";
		break;
	    case TCL_TOKEN_VARIABLE:
		typeString = "variable";
		break;
	    case TCL_TOKEN_SUB_EXPR:
		typeString = "subexpr";
		break;
	    case TCL_TOKEN_OPERATOR:
		typeString = "operator";
		break;
	    default:
		typeString = "??";
		break;
	}
	Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
		Tcl_NewStringObj(typeString, -1));
	Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
		Tcl_NewStringObj(tokenPtr->start, tokenPtr->size));
	Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
		Tcl_NewIntObj(tokenPtr->numComponents));
    }
    Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
	    Tcl_NewStringObj(parsePtr->commandStart + parsePtr->commandSize,
	    -1));
}

/*
 *----------------------------------------------------------------------
 *
 * TestparsevarObjCmd --
 *
 *	This procedure implements the "testparsevar" command.  It is
 *	used for testing Tcl_ParseVar.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestparsevarObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* The argument objects. */
{
    char *name, *value, *termPtr;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "varName");
	return TCL_ERROR;
    }
    name = Tcl_GetString(objv[1]);
    value = Tcl_ParseVar(interp, name, &termPtr);
    if (value == NULL) {
	return TCL_ERROR;
    }

    Tcl_AppendElement(interp, value);
    Tcl_AppendElement(interp, termPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestparsevarnameObjCmd --
 *
 *	This procedure implements the "testparsevarname" command.  It is
 *	used for testing the new Tcl script parser in Tcl 8.1.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestparsevarnameObjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* The argument objects. */
{
    char *script;
    int append, length, dummy;
    Tcl_Parse parse;

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 1, objv, "script length append");
	return TCL_ERROR;
    }
    script = Tcl_GetStringFromObj(objv[1], &dummy);
    if (Tcl_GetIntFromObj(interp, objv[2], &length)) {
	return TCL_ERROR;
    }
    if (length == 0) {
	length = dummy;
    }
    if (Tcl_GetIntFromObj(interp, objv[3], &append)) {
	return TCL_ERROR;
    }
    if (Tcl_ParseVarName(interp, script, length, &parse, append) != TCL_OK) {
	Tcl_AddErrorInfo(interp, "\n    (remainder of script: \"");
	Tcl_AddErrorInfo(interp, parse.term);
	Tcl_AddErrorInfo(interp, "\")");
	return TCL_ERROR;
    }

    /*
     * The parse completed successfully.  Just print out the contents
     * of the parse structure into the interpreter's result.
     */

    parse.commentSize = 0;
    parse.commandStart = script + parse.tokenPtr->size;
    parse.commandSize = 0;
    PrintParse(interp, &parse);
    Tcl_FreeParse(&parse);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestregexpObjCmd --
 *
 *	This procedure implements the "testregexp" command. It is
 *	used to give a direct interface for regexp flags.  It's identical
 *	to Tcl_RegexpObjCmd except for the REGEXP_TEST define, which
 *	enables the -xflags option.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
TestregexpObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    int i, result, indices, stringLength, wLen, match, about;
    int hasxflags, cflags, eflags;
    Tcl_RegExp regExpr;
    char *string;
    Tcl_DString stringBuffer, valueBuffer;
    Tcl_UniChar *wStart;
#   define	REGEXP_TEST	/* yes */
    static char *options[] = {
	"-indices",	"-nocase",	"-about",	"-expanded",
	"-line",	"-linestop",	"-lineanchor",
#ifdef REGEXP_TEST
	"-xflags",
#endif
	"--",		(char *) NULL
    };
    enum options {
	REGEXP_INDICES, REGEXP_NOCASE,	REGEXP_ABOUT,	REGEXP_EXPANDED,
	REGEXP_MULTI,	REGEXP_NOCROSS,	REGEXP_NEWL,
#ifdef REGEXP_TEST
	REGEXP_XFLAGS,
#endif
	REGEXP_LAST
    };
#ifndef REGEXP_TEST
#   define REGEXP_XFLAGS	-1	/* impossible value */
#   define TestregexpXflags(a,b,c,d)	/* do nothing */
#endif

    indices = 0;
    about = 0;
    cflags = REG_ADVANCED;
    eflags = 0;
    hasxflags = 0;
    
    for (i = 1; i < objc; i++) {
	char *name;
	int index;

	name = Tcl_GetString(objv[i]);
	if (name[0] != '-') {
	    break;
	}
	if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", TCL_EXACT,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
	switch ((enum options) index) {
	    case REGEXP_INDICES: {
		indices = 1;
		break;
	    }
	    case REGEXP_NOCASE: {
		cflags |= REG_ICASE;
		break;
	    }
	    case REGEXP_ABOUT: {
		about = 1;
		break;
	    }
	    case REGEXP_EXPANDED: {
		cflags |= REG_EXPANDED;
		break;
	    }
	    case REGEXP_MULTI: {
		cflags |= REG_NEWLINE;
		break;
	    }
	    case REGEXP_NOCROSS: {
		cflags |= REG_NLSTOP;
		break;
	    }
	    case REGEXP_NEWL: {
		cflags |= REG_NLANCH;
		break;
	    }
	    case REGEXP_XFLAGS: {
		hasxflags = 1;
		break;
	    }
	    case REGEXP_LAST: {
		i++;
		goto endOfForLoop;
	    }
	}
    }

    endOfForLoop:
    if (objc - i < hasxflags + 2 - about) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?");
	return TCL_ERROR;
    }
    objc -= i;
    objv += i;

    if (hasxflags) {
	string = Tcl_GetStringFromObj(objv[0], &stringLength);
	TestregexpXflags(string, stringLength, &cflags, &eflags);
	objc--;
	objv++;
    }

    regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
    if (regExpr == NULL) {
	return TCL_ERROR;
    }

    if (about) {
	if (TclRegAbout(interp, regExpr) < 0) {
	    return TCL_ERROR;
	}
	return TCL_OK;
    }

    result = TCL_OK;
    string = Tcl_GetStringFromObj(objv[1], &stringLength);

    Tcl_DStringInit(&valueBuffer);
    
    Tcl_DStringInit(&stringBuffer);
    wStart = Tcl_UtfToUniCharDString(string, stringLength, &stringBuffer);
    wLen = Tcl_DStringLength(&stringBuffer) / sizeof(Tcl_UniChar);

    match = TclRegExpExecUniChar(interp, regExpr, wStart, wLen, objc-2, eflags);
    if (match < 0) {
	result = TCL_ERROR;
	goto done;
    }
    if (match == 0) {
	/*
	 * Set the interpreter's object result to an integer object w/ value 0. 
	 */
	
	Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
	goto done;
    }

    /*
     * If additional variable names have been specified, return
     * index information in those variables.
     */

    objc -= 2;
    objv += 2;

    for (i = 0; i < objc; i++) {
	char *varName, *value;
	int start, end;
	
	varName = Tcl_GetString(objv[i]);

	TclRegExpRangeUniChar(regExpr, i, &start, &end);
	if (start < 0) {
	    if (indices) {
		value = Tcl_SetVar(interp, varName, "-1 -1", 0);
	    } else {
		value = Tcl_SetVar(interp, varName, "", 0);
	    }
	} else {
	    if (indices) {
		char info[TCL_INTEGER_SPACE * 2];
		
		sprintf(info, "%d %d", start, end - 1);
		value = Tcl_SetVar(interp, varName, info, 0);
	    } else {
		value = Tcl_UniCharToUtfDString(wStart + start, end - start,
			&valueBuffer);
		value = Tcl_SetVar(interp, varName, value, 0);
		Tcl_DStringSetLength(&valueBuffer, 0);
	    }
	}
	if (value == NULL) {
	    Tcl_AppendResult(interp, "couldn't set variable \"",
		    varName, "\"", (char *) NULL);
	    result = TCL_ERROR;
	    goto done;
	}
    }

    /*
     * Set the interpreter's object result to an integer object w/ value 1. 
     */
	
    Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);

    done:
    Tcl_DStringFree(&stringBuffer);
    Tcl_DStringFree(&valueBuffer);
    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TestregexpXflags --
 *
 *	Parse a string of extended regexp flag letters, for testing.
 *
 * Results:
 *	No return value (you're on your own for errors here).
 *
 * Side effects:
 *	Modifies *cflagsPtr, a regcomp flags word, and *eflagsPtr, a
 *	regexec flags word, as appropriate.
 *
 *----------------------------------------------------------------------
 */

static void
TestregexpXflags(string, length, cflagsPtr, eflagsPtr)
    char *string;		/* The string of flags. */
    int length;			/* The length of the string in bytes. */
    int *cflagsPtr;		/* compile flags word */
    int *eflagsPtr;		/* exec flags word */
{
    int i;
    int cflags;
    int eflags;

    cflags = *cflagsPtr;
    eflags = *eflagsPtr;
    for (i = 0; i < length; i++) {
	switch (string[i]) {
	    case 'a': {
		cflags |= REG_ADVF;
		break;
	    }
	    case 'b': {
		cflags &= ~REG_ADVANCED;
		break;
	    }
	    case 'e': {
		cflags &= ~REG_ADVANCED;
		cflags |= REG_EXTENDED;
		break;
	    }
	    case 'q': {
		cflags &= ~REG_ADVANCED;
		cflags |= REG_QUOTE;
		break;
	    }
	    case 'o': {			/* o for opaque */
		cflags |= REG_NOSUB;
		break;
	    }
	    case '+': {
		cflags |= REG_FAKEEC;
		break;
	    }
	    case ',': {
		cflags |= REG_PROGRESS;
		break;
	    }
	    case '.': {
		cflags |= REG_DUMP;
		break;
	    }
	    case ':': {
		eflags |= REG_MTRACE;
		break;
	    }
	    case ';': {
		eflags |= REG_FTRACE;
		break;
	    }
	    case '^': {
		eflags |= REG_NOTBOL;
		break;
	    }
	    case '$': {
		eflags |= REG_NOTEOL;
		break;
	    }
	    case '%': {
		eflags |= REG_SMALL;
		break;
	    }
	}
    }

    *cflagsPtr = cflags;
    *eflagsPtr = eflags;
}

/*
 *----------------------------------------------------------------------
 *
 * TestsetassocdataCmd --
 *
 *	This procedure implements the "testsetassocdata" command. It is used
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
		flags);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TestwordendCmd --
 *
 *	This procedure implements the "testwordend" command.  It is used
 *	to test TclWordEnd.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
TestwordendObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* The argument objects. */
{
    Tcl_Obj *objPtr;
    char *string, *end;
    int length;

    if (objc != 2) {
    	Tcl_WrongNumArgs(interp, 1, objv, "string");
	return TCL_ERROR;
    }
    objPtr = Tcl_GetObjResult(interp);
    string = Tcl_GetStringFromObj(objv[1], &length);
    end = TclWordEnd(string, string+length, 0, NULL);
    Tcl_AppendToObj(objPtr, end, length - (end - string));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestsetobjerrorcodeCmd --
 *
 *	This procedure implements the "testsetobjerrorcodeCmd".
 *	This tests up to five elements passed to the
 *	Tcl_SetObjErrorCode command.
 *
 * Results:







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







3105
3106
3107
3108
3109
3110
3111








































3112
3113
3114
3115
3116
3117
3118
		flags);
    }
}

/*
 *----------------------------------------------------------------------
 *








































 * TestsetobjerrorcodeCmd --
 *
 *	This procedure implements the "testsetobjerrorcodeCmd".
 *	This tests up to five elements passed to the
 *	Tcl_SetObjErrorCode command.
 *
 * Results:
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		    " cmd script", (char *) NULL);
	    return TCL_ERROR;
	}
        if (interp2 != (Tcl_Interp *) NULL) {
            code = Tcl_GlobalEval(interp2, argv[2]);
            interp->result = interp2->result;
            return code;
        } else {
            Tcl_AppendResult(interp,
                    "called \"testfevent code\" before \"testfevent create\"",
                    (char *) NULL);
            return TCL_ERROR;
        }







|







3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
		    " cmd script", (char *) NULL);
	    return TCL_ERROR;
	}
        if (interp2 != (Tcl_Interp *) NULL) {
            code = Tcl_GlobalEval(interp2, argv[2]);
	    Tcl_SetObjResult(interp, Tcl_GetObjResult(interp2));
            return code;
        } else {
            Tcl_AppendResult(interp,
                    "called \"testfevent code\" before \"testfevent create\"",
                    (char *) NULL);
            return TCL_ERROR;
        }
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestPanicCmd --
 *
 *	Calls the panic routine.
 *
 * Results:
 *      Always returns TCL_OK. 
 *
 * Side effects:
 *	May exit application.
 *
 *----------------------------------------------------------------------
 */

static int
TestPanicCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    char *argString;
    







|













|







3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestpanicCmd --
 *
 *	Calls the panic routine.
 *
 * Results:
 *      Always returns TCL_OK. 
 *
 * Side effects:
 *	May exit application.
 *
 *----------------------------------------------------------------------
 */

static int
TestpanicCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    char *argString;
    
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
    int result;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "name scope");
        return TCL_ERROR;
    }
    
    name = Tcl_GetStringFromObj(objv[1], (int *) NULL);

    arg = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    if (strcmp(arg, "global") == 0) {
	flags = TCL_GLOBAL_ONLY;
    } else if (strcmp(arg, "namespace") == 0) {
	flags = TCL_NAMESPACE_ONLY;
    }

    /*







|

|







3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
    int result;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "name scope");
        return TCL_ERROR;
    }
    
    name = Tcl_GetString(objv[1]);

    arg = Tcl_GetString(objv[2]);
    if (strcmp(arg, "global") == 0) {
	flags = TCL_GLOBAL_ONLY;
    } else if (strcmp(arg, "namespace") == 0) {
	flags = TCL_NAMESPACE_ONLY;
    }

    /*
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
    Interp *iPtr = (Interp *) interp;
    int i, n;
    double timePer;
    Tcl_Time start, stop;
    Tcl_Obj *objPtr;
    Tcl_Obj **objv;
    char *s;
    char newString[30];

    /* alloc & free 100000 times */
    fprintf(stderr, "alloc & free 100000 6 word items\n");
    TclpGetTime(&start);
    for (i = 0;  i < 100000;  i++) {
	objPtr = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj));
	ckfree((char *) objPtr);







|







3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
    Interp *iPtr = (Interp *) interp;
    int i, n;
    double timePer;
    Tcl_Time start, stop;
    Tcl_Obj *objPtr;
    Tcl_Obj **objv;
    char *s;
    char newString[TCL_INTEGER_SPACE];

    /* alloc & free 100000 times */
    fprintf(stderr, "alloc & free 100000 6 word items\n");
    TclpGetTime(&start);
    for (i = 0;  i < 100000;  i++) {
	objPtr = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj));
	ckfree((char *) objPtr);
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
	Tcl_DecrRefCount(objPtr);
    }
    TclpGetTime(&stop);
    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
    fprintf(stderr, "   %.3f usec per Tcl_DecrRefCount\n", timePer/5000);
    ckfree((char *) objv);

    /* TclGetStringFromObj 100000 times */
    fprintf(stderr, "TclGetStringFromObj of \"12345\" 100000 times\n");
    objPtr = Tcl_NewStringObj("12345", -1);
    TclpGetTime(&start);
    for (i = 0;  i < 100000;  i++) {
	(void) TclGetStringFromObj(objPtr, &n);
    }
    TclpGetTime(&stop);
    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
    fprintf(stderr, "   %.3f usec per TclGetStringFromObj of \"12345\"\n",
	    timePer/100000);

    /* Tcl_GetIntFromObj 100000 times */







|




|







3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
	Tcl_DecrRefCount(objPtr);
    }
    TclpGetTime(&stop);
    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
    fprintf(stderr, "   %.3f usec per Tcl_DecrRefCount\n", timePer/5000);
    ckfree((char *) objv);

    /* TclGetString 100000 times */
    fprintf(stderr, "TclGetStringFromObj of \"12345\" 100000 times\n");
    objPtr = Tcl_NewStringObj("12345", -1);
    TclpGetTime(&start);
    for (i = 0;  i < 100000;  i++) {
	(void) TclGetString(objPtr);
    }
    TclpGetTime(&stop);
    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
    fprintf(stderr, "   %.3f usec per TclGetStringFromObj of \"12345\"\n",
	    timePer/100000);

    /* Tcl_GetIntFromObj 100000 times */
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672




















































2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684


































































































































2685

















































































































































































































2686
2687
2688
2689
2690


2691
2692
2693



2694













2695
2696
2697
2698







2699




2700




2701




2702

2703
2704











2705
2706





2707

2708
2709



2710











2711
2712

2713
2714














2715
2716
2717
2718
2719
2720
2721
{
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestsetnoerrCmd --
 *
 *	Implements the "testsetnoerr" cmd that is used when testing
 *	the Tcl_Set/GetVar C Api without TCL_LEAVE_ERR_MSG flag




















































 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int


































































































































TestsetnoerrCmd(dummy, interp, argc, argv)

















































































































































































































    ClientData dummy;			/* Not used. */
    register Tcl_Interp *interp;	/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{


    char *value;
    if (argc == 2) {
	Tcl_SetResult(interp, "before get", TCL_STATIC);



	value = Tcl_GetVar2(interp, argv[1], (char *) NULL, TCL_PARSE_PART1);













	if (value == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetResult(interp, value, TCL_VOLATILE);







	return TCL_OK;




    } else if (argc == 3) {




	char *m1 = "before set";




	char *message=Tcl_Alloc(strlen(m1)+1);

	
	strcpy(message,m1);












	Tcl_SetResult(interp, message, TCL_DYNAMIC);







	value = Tcl_SetVar2(interp, argv[1], (char *) NULL, argv[2],
		            TCL_PARSE_PART1);



	if (value == NULL) {











	    return TCL_ERROR;
	}

	Tcl_SetResult(interp, value, TCL_VOLATILE);
	return TCL_OK;














    } else {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " varName ?newValue?\"", (char *) NULL);
	return TCL_ERROR;
    }
}








|

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












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





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

<
<
|


<
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179

4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223


4224
4225
4226

{
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestsetCmd --
 *
 *	Implements the "testset{err,noerr}" cmds that are used when testing
 *	Tcl_Set/GetVar C Api with/without TCL_LEAVE_ERR_MSG flag
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *     Variables may be set.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
TestsetCmd(data, interp, argc, argv)
    ClientData data;			/* Additional flags for Get/SetVar2. */
    register Tcl_Interp *interp;	/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    int flags = (int) data;
    char *value;

    if (argc == 2) {
        Tcl_SetResult(interp, "before get", TCL_STATIC);
	value = Tcl_GetVar2(interp, argv[1], (char *) NULL, flags);
        if (value == NULL) {
            return TCL_ERROR;
        }
	Tcl_AppendElement(interp, value);
        return TCL_OK;
    } else if (argc == 3) {
	Tcl_SetResult(interp, "before set", TCL_STATIC);
        value = Tcl_SetVar2(interp, argv[1], (char *) NULL, argv[2], flags);
        if (value == NULL) {
            return TCL_ERROR;
        }
	Tcl_AppendElement(interp, value);
	return TCL_OK;
    } else {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " varName ?newValue?\"", (char *) NULL);
	return TCL_ERROR;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TestsaveresultCmd --
 *
 *	Implements the "testsaveresult" cmd that is used when testing
 *	the Tcl_SaveResult, Tcl_RestoreResult, and
 *	Tcl_DiscardResult interfaces.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
TestsaveresultCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    register Tcl_Interp *interp;	/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* The argument objects. */
{
    int discard, result, index;
    Tcl_SavedResult state;
    Tcl_Obj *objPtr;
    static char *optionStrings[] = {
	"append", "dynamic", "free", "object", "small", NULL
    };
    enum options {
	RESULT_APPEND, RESULT_DYNAMIC, RESULT_FREE, RESULT_OBJECT, RESULT_SMALL
    };

    /*
     * Parse arguments
     */

    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 1, objv, "type script discard");
        return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &discard) != TCL_OK) {
	return TCL_ERROR;
    }

    objPtr = NULL;		/* Lint. */
    switch ((enum options) index) {
	case RESULT_SMALL:
	    Tcl_SetResult(interp, "small result", TCL_VOLATILE);
	    break;
	case RESULT_APPEND:
	    Tcl_AppendResult(interp, "append result", NULL);
	    break;
	case RESULT_FREE: {
	    char *buf = ckalloc(200);
	    strcpy(buf, "free result");
	    Tcl_SetResult(interp, buf, TCL_DYNAMIC);
	    break;
	}
	case RESULT_DYNAMIC:
	    Tcl_SetResult(interp, "dynamic result", TestsaveresultFree);
	    break;
	case RESULT_OBJECT:
	    objPtr = Tcl_NewStringObj("object result", -1);
	    Tcl_SetObjResult(interp, objPtr);
	    break;
    }

    freeCount = 0;
    Tcl_SaveResult(interp, &state);

    if (((enum options) index) == RESULT_OBJECT) {
	result = Tcl_EvalObjEx(interp, objv[2], 0);
    } else {
	result = Tcl_Eval(interp, Tcl_GetString(objv[2]));
    }

    if (discard) {
	Tcl_DiscardResult(&state);
    } else {
	Tcl_RestoreResult(interp, &state);
	result = TCL_OK;
    }

    switch ((enum options) index) {
	case RESULT_DYNAMIC: {
	    int present = interp->freeProc == TestsaveresultFree;
	    int called = freeCount;
	    Tcl_AppendElement(interp, called ? "called" : "notCalled");
	    Tcl_AppendElement(interp, present ? "present" : "missing");
	    break;
	}
	case RESULT_OBJECT:
	    Tcl_AppendElement(interp, Tcl_GetObjResult(interp) == objPtr
		    ? "same" : "different");
	    break;
	default:
	    break;
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TestsaveresultFree --
 *
 *	Special purpose freeProc used by TestsaveresultCmd.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Increments the freeCount.
 *
 *----------------------------------------------------------------------
 */

static void
TestsaveresultFree(blockPtr)
    char *blockPtr;
{
    freeCount++;
}

/*
 *----------------------------------------------------------------------
 *
 * TeststatprocCmd  --
 *
 *	Implements the "testTclStatProc" cmd that is used to test the
 *	'TclStatInsertProc' & 'TclStatDeleteProc' C Apis.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TeststatprocCmd (dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    register Tcl_Interp *interp;	/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    TclStatProc_ *proc;
    int retVal;

    if (argc != 3) {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " option arg\"", (char *) NULL);
	return TCL_ERROR;
    }

    if (strcmp(argv[2], "TclpStat") == 0) {
	proc = TclpStat;
    } else if (strcmp(argv[2], "TestStatProc1") == 0) {
	proc = TestStatProc1;
    } else if (strcmp(argv[2], "TestStatProc2") == 0) {
	proc = TestStatProc2;
    } else if (strcmp(argv[2], "TestStatProc3") == 0) {
	proc = TestStatProc3;
    } else {
	Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
		"must be TclpStat, ",
		"TestStatProc1, TestStatProc2, or TestStatProc3",
		(char *) NULL);
	return TCL_ERROR;
    }

    if (strcmp(argv[1], "insert") == 0) {
	if (proc == TclpStat) {
	    Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
		   "must be ",
		   "TestStatProc1, TestStatProc2, or TestStatProc3",
		   (char *) NULL);
	    return TCL_ERROR;
	}
	retVal = TclStatInsertProc(proc);
    } else if (strcmp(argv[1], "delete") == 0) {
	retVal = TclStatDeleteProc(proc);
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1], "\": ",
		"must be insert or delete", (char *) NULL);
	return TCL_ERROR;
    }

    if (retVal == TCL_ERROR) {
	Tcl_AppendResult(interp, "\"", argv[2], "\": ",
		"could not be ", argv[1], "ed", (char *) NULL);
    }

    return retVal;
}

/* Be careful in the compares in these tests, since the Macintosh puts a  
 * leading : in the beginning of non-absolute paths before passing them 
 * into the file command procedures.
 */
 
static int
TestStatProc1(path, buf)
    CONST char *path;
    TclStat_ *buf;
{
    buf->st_size = 1234;
    return ((strstr(path, "testStat1%.fil") == NULL) ? -1 : 0);
}


static int
TestStatProc2(path, buf)
    CONST char *path;
    TclStat_ *buf;
{
    buf->st_size = 2345;
    return ((strstr(path, "testStat2%.fil") == NULL) ? -1 : 0);
}


static int
TestStatProc3(path, buf)
    CONST char *path;
    TclStat_ *buf;
{
    buf->st_size = 3456;
    return ((strstr(path, "testStat3%.fil") == NULL) ? -1 : 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TestaccessprocCmd  --
 *
 *	Implements the "testTclAccessProc" cmd that is used to test the
 *	'TclAccessInsertProc' & 'TclAccessDeleteProc' C Apis.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestaccessprocCmd (dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    register Tcl_Interp *interp;	/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    TclAccessProc_ *proc;
    int retVal;

    if (argc != 3) {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " option arg\"", (char *) NULL);
	return TCL_ERROR;
    }

    if (strcmp(argv[2], "TclpAccess") == 0) {
	proc = TclpAccess;
    } else if (strcmp(argv[2], "TestAccessProc1") == 0) {
	proc = TestAccessProc1;
    } else if (strcmp(argv[2], "TestAccessProc2") == 0) {
	proc = TestAccessProc2;
    } else if (strcmp(argv[2], "TestAccessProc3") == 0) {
	proc = TestAccessProc3;
    } else {
	Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
		"must be TclpAccess, ",
		"TestAccessProc1, TestAccessProc2, or TestAccessProc3",
		(char *) NULL);
	return TCL_ERROR;
    }

    if (strcmp(argv[1], "insert") == 0) {
	if (proc == TclpAccess) {
	    Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
		   "must be ",
		   "TestAccessProc1, TestAccessProc2, or TestAccessProc3",
		   (char *) NULL);
	    return TCL_ERROR;
	}
	retVal = TclAccessInsertProc(proc);
    } else if (strcmp(argv[1], "delete") == 0) {
	retVal = TclAccessDeleteProc(proc);
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1], "\": ",
		"must be insert or delete", (char *) NULL);
	return TCL_ERROR;
    }

    if (retVal == TCL_ERROR) {
	Tcl_AppendResult(interp, "\"", argv[2], "\": ",
		"could not be ", argv[1], "ed", (char *) NULL);
    }

    return retVal;
}


static int
TestAccessProc1(path, mode)
    CONST char *path;
    int mode;
{
    return ((strstr(path, "testAccess1%.fil") == NULL) ? -1 : 0);
}


static int
TestAccessProc2(path, mode)
    CONST char *path;
    int mode;
{
    return ((strstr(path, "testAccess2%.fil") == NULL) ? -1 : 0);
}


static int
TestAccessProc3(path, mode)
    CONST char *path;
    int mode;
{
    return ((strstr(path, "testAccess3%.fil") == NULL) ? -1 : 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TestopenfilechannelprocCmd  --
 *
 *	Implements the "testTclOpenFileChannelProc" cmd that is used to test the
 *	'TclOpenFileChannelInsertProc' & 'TclOpenFileChannelDeleteProc' C Apis.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestopenfilechannelprocCmd (dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    register Tcl_Interp *interp;	/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    TclOpenFileChannelProc_ *proc;
    int retVal;

    if (argc != 3) {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " option arg\"", (char *) NULL);
	return TCL_ERROR;
    }

    if (strcmp(argv[2], "TclpOpenFileChannel") == 0) {
	proc = TclpOpenFileChannel;
    } else if (strcmp(argv[2], "TestOpenFileChannelProc1") == 0) {
	proc = TestOpenFileChannelProc1;
    } else if (strcmp(argv[2], "TestOpenFileChannelProc2") == 0) {
	proc = TestOpenFileChannelProc2;
    } else if (strcmp(argv[2], "TestOpenFileChannelProc3") == 0) {
	proc = TestOpenFileChannelProc3;
    } else {
	Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
		"must be TclpOpenFileChannel, ",
		"TestOpenFileChannelProc1, TestOpenFileChannelProc2, or ",
		"TestOpenFileChannelProc3",
		(char *) NULL);
	return TCL_ERROR;
    }

    if (strcmp(argv[1], "insert") == 0) {
	if (proc == TclpOpenFileChannel) {
	    Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
		   "must be ",
		   "TestOpenFileChannelProc1, TestOpenFileChannelProc2, or ",
		   "TestOpenFileChannelProc3",
		   (char *) NULL);
	    return TCL_ERROR;
	}
	retVal = TclOpenFileChannelInsertProc(proc);
    } else if (strcmp(argv[1], "delete") == 0) {
	retVal = TclOpenFileChannelDeleteProc(proc);
    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1], "\": ",
		"must be insert or delete", (char *) NULL);
	return TCL_ERROR;
    }

    if (retVal == TCL_ERROR) {
	Tcl_AppendResult(interp, "\"", argv[2], "\": ",
		"could not be ", argv[1], "ed", (char *) NULL);
    }

    return retVal;
}


static Tcl_Channel
TestOpenFileChannelProc1(interp, fileName, modeString, permissions)
    Tcl_Interp *interp;                 /* Interpreter for error reporting;
                                         * can be NULL. */
    char *fileName;                     /* Name of file to open. */
    char *modeString;                   /* A list of POSIX open modes or
                                         * a string such as "rw". */
    int permissions;                    /* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
{

    if (!strcmp("testOpenFileChannel1%.fil", fileName)) {
	return (TclpOpenFileChannel(interp, "__testOpenFileChannel1%__.fil",
		modeString, permissions));
    } else {
	return (NULL);
    }
}


static Tcl_Channel
TestOpenFileChannelProc2(interp, fileName, modeString, permissions)
    Tcl_Interp *interp;                 /* Interpreter for error reporting;
                                         * can be NULL. */
    char *fileName;                     /* Name of file to open. */
    char *modeString;                   /* A list of POSIX open modes or
                                         * a string such as "rw". */
    int permissions;                    /* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
{
    if (!strcmp("testOpenFileChannel2%.fil", fileName)) {
	return (TclpOpenFileChannel(interp, "__testOpenFileChannel2%__.fil",
		modeString, permissions));
    } else {
	return (NULL);
    }
}


static Tcl_Channel
TestOpenFileChannelProc3(interp, fileName, modeString, permissions)
    Tcl_Interp *interp;                 /* Interpreter for error reporting;
                                         * can be NULL. */
    char *fileName;                     /* Name of file to open. */
    char *modeString;                   /* A list of POSIX open modes or
                                         * a string such as "rw". */
    int permissions;                    /* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
{
    if (!strcmp("testOpenFileChannel3%.fil", fileName)) {
	return (TclpOpenFileChannel(interp, "__testOpenFileChannel3%__.fil",
		modeString, permissions));
    } else {


	return (NULL);
    }
}

Changes to generic/tclTestObj.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 
 * tclTestObj.c --
 *
 *	This file contains C command procedures for the additional Tcl
 *	commands that are used for testing implementations of the Tcl object
 *	types. These commands are not normally included in Tcl
 *	applications; they're only used for testing.
 *
 * Copyright (c) 1995, 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclTestObj.c 1.27 97/05/19 17:37:31
 */

#include "tclInt.h"

/*
 * An array of Tcl_Obj pointers used in the commands that operate on or get
 * the values of Tcl object-valued variables. varPtr[i] is the i-th








|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 
 * tclTestObj.c --
 *
 *	This file contains C command procedures for the additional Tcl
 *	commands that are used for testing implementations of the Tcl object
 *	types. These commands are not normally included in Tcl
 *	applications; they're only used for testing.
 *
 * Copyright (c) 1995-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: tclTestObj.c,v 1.1.2.3 1998/12/01 05:01:01 stanton Exp $
 */

#include "tclInt.h"

/*
 * An array of Tcl_Obj pointers used in the commands that operate on or get
 * the values of Tcl object-valued variables. varPtr[i] is the i-th
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 * TclObjTest_Init --
 *
 *	This procedure creates additional commands that are used to test the
 *	Tcl object support.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in interp->result if an error occurs.
 *
 * Side effects:
 *	Creates and registers several new testing commands.
 *
 *----------------------------------------------------------------------
 */








|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 * TclObjTest_Init --
 *
 *	This procedure creates additional commands that are used to test the
 *	Tcl object support.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in the interp's result if an error occurs.
 *
 * Side effects:
 *	Creates and registers several new testing commands.
 *
 *----------------------------------------------------------------------
 */

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
static int
TestbooleanobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int varIndex, boolValue, length;
    char *index, *subCmd;

    if (objc < 3) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * THIS FAILS IF AN OBJECT'S STRING REP HAS A NULL BYTE.
     */

    index = Tcl_GetStringFromObj(objv[2], &length);
    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    subCmd = Tcl_GetStringFromObj(objv[1], &length);
    if (strcmp(subCmd, "set") == 0) {
	if (objc != 4) {
	    goto wrongNumArgs;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[3], &boolValue) != TCL_OK) {
	    return TCL_ERROR;
	}







|








<
<
<
<
|




|







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
static int
TestbooleanobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int varIndex, boolValue;
    char *index, *subCmd;

    if (objc < 3) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }





    index = Tcl_GetString(objv[2]);
    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    subCmd = Tcl_GetString(objv[1]);
    if (strcmp(subCmd, "set") == 0) {
	if (objc != 4) {
	    goto wrongNumArgs;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[3], &boolValue) != TCL_OK) {
	    return TCL_ERROR;
	}
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
	    Tcl_SetBooleanObj(varPtr[varIndex], !boolValue);
	} else {
	    SetVarToObj(varIndex, Tcl_NewBooleanObj(!boolValue));
	}
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"bad option \"", Tcl_GetStringFromObj(objv[1], (int *) NULL),
		"\": must be set, get, or not", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
	    Tcl_SetBooleanObj(varPtr[varIndex], !boolValue);
	} else {
	    SetVarToObj(varIndex, Tcl_NewBooleanObj(!boolValue));
	}
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"bad option \"", Tcl_GetString(objv[1]),
		"\": must be set, get, or not", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
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
static int
TestconvertobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int length;
    char *subCmd;
    char buf[20];

    if (objc < 3) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * THIS FAILS IF AN OBJECT'S STRING REP HAS A NULL BYTE.
     */

    subCmd = Tcl_GetStringFromObj(objv[1], &length);
    if (strcmp(subCmd, "double") == 0) {
	double d;

	if (objc != 3) {
	    goto wrongNumArgs;
	}
	if (Tcl_GetDoubleFromObj(interp, objv[2], &d) != TCL_OK) {
	    return TCL_ERROR;
	}
	sprintf(buf, "%f", d);
        Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
    } else {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"bad option \"", Tcl_GetStringFromObj(objv[1], (int *) NULL),
		"\": must be double", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







<









<
<
<
<
|













|







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
static int
TestconvertobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{

    char *subCmd;
    char buf[20];

    if (objc < 3) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }





    subCmd = Tcl_GetString(objv[1]);
    if (strcmp(subCmd, "double") == 0) {
	double d;

	if (objc != 3) {
	    goto wrongNumArgs;
	}
	if (Tcl_GetDoubleFromObj(interp, objv[2], &d) != TCL_OK) {
	    return TCL_ERROR;
	}
	sprintf(buf, "%f", d);
        Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
    } else {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"bad option \"", Tcl_GetString(objv[1]),
		"\": must be double", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
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
static int
TestdoubleobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int varIndex, length;
    double doubleValue;
    char *index, *subCmd, *string;
	
    if (objc < 3) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * THIS FAILS IF AN OBJECT'S STRING REP HAS A NULL BYTE.
     */

    index = Tcl_GetStringFromObj(objv[2], &length);
    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    subCmd = Tcl_GetStringFromObj(objv[1], &length);
    if (strcmp(subCmd, "set") == 0) {
	if (objc != 4) {
	    goto wrongNumArgs;
	}
	string = Tcl_GetStringFromObj(objv[3], &length);
	if (Tcl_GetDouble(interp, string, &doubleValue) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
	 * If the object currently bound to the variable with index varIndex
	 * has ref count 1 (i.e. the object is unshared) we can modify that







|









<
<
<
<
|




|




|







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
static int
TestdoubleobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int varIndex;
    double doubleValue;
    char *index, *subCmd, *string;
	
    if (objc < 3) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }





    index = Tcl_GetString(objv[2]);
    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    subCmd = Tcl_GetString(objv[1]);
    if (strcmp(subCmd, "set") == 0) {
	if (objc != 4) {
	    goto wrongNumArgs;
	}
	string = Tcl_GetString(objv[3]);
	if (Tcl_GetDouble(interp, string, &doubleValue) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
	 * If the object currently bound to the variable with index varIndex
	 * has ref count 1 (i.e. the object is unshared) we can modify that
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
	    Tcl_SetDoubleObj(varPtr[varIndex], (doubleValue / 10.0));
	} else {
	    SetVarToObj(varIndex, Tcl_NewDoubleObj( (doubleValue / 10.0) ));
	}
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"bad option \"", Tcl_GetStringFromObj(objv[1], (int *) NULL),
		"\": must be set, get, mult10, or div10", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
	    Tcl_SetDoubleObj(varPtr[varIndex], (doubleValue / 10.0));
	} else {
	    SetVarToObj(varIndex, Tcl_NewDoubleObj( (doubleValue / 10.0) ));
	}
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"bad option \"", Tcl_GetString(objv[1]),
		"\": must be set, get, mult10, or div10", (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
static int
TestindexobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int allowAbbrev, index, index2, setError, i, dummy, result;
    char **argv;
    static char *tablePtr[] = {"a", "b", "check", (char *) NULL};

    if ((objc == 3) && (strcmp(Tcl_GetStringFromObj(objv[1], &dummy),
	    "check") == 0)) {
	/*
	 * This code checks to be sure that the results of
	 * Tcl_GetIndexFromObj are properly cached in the object and
	 * returned on subsequent lookups.
	 */








|



|







390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
static int
TestindexobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int allowAbbrev, index, index2, setError, i, result;
    char **argv;
    static char *tablePtr[] = {"a", "b", "check", (char *) NULL};

    if ((objc == 3) && (strcmp(Tcl_GetString(objv[1]),
	    "check") == 0)) {
	/*
	 * This code checks to be sure that the results of
	 * Tcl_GetIndexFromObj are properly cached in the object and
	 * returned on subsequent lookups.
	 */

440
441
442
443
444
445
446

447
448
449
450
451













452
453
454
455
456
457
458
459
460

    if (Tcl_GetBooleanFromObj(interp, objv[1], &setError) != TCL_OK) {
	return TCL_ERROR;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[2], &allowAbbrev) != TCL_OK) {
	return TCL_ERROR;
    }

    argv = (char **) ckalloc((unsigned) ((objc-3) * sizeof(char *)));
    for (i = 4; i < objc; i++) {
	argv[i-4] = Tcl_GetStringFromObj(objv[i], &dummy);
    }
    argv[objc-4] = NULL;













    result = Tcl_GetIndexFromObj(setError ? interp : NULL, objv[3],
	    argv, "token", allowAbbrev ? 0 : TCL_EXACT, &index);
    ckfree((char *) argv);
    if (result == TCL_OK) {
	Tcl_SetIntObj(Tcl_GetObjResult(interp), index);
    }
    return result;
}








>


|


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







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

    if (Tcl_GetBooleanFromObj(interp, objv[1], &setError) != TCL_OK) {
	return TCL_ERROR;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[2], &allowAbbrev) != TCL_OK) {
	return TCL_ERROR;
    }

    argv = (char **) ckalloc((unsigned) ((objc-3) * sizeof(char *)));
    for (i = 4; i < objc; i++) {
	argv[i-4] = Tcl_GetString(objv[i]);
    }
    argv[objc-4] = NULL;
    
    /*
     * Tcl_GetIndexFromObj assumes that the table is statically-allocated
     * so that its address is different for each index object. If we
     * accidently allocate a table at the same address as that cached in
     * the index object, clear out the object's cached state.
     */

    if ((objv[3]->typePtr == Tcl_GetObjType("index"))
	    && (objv[3]->internalRep.twoPtrValue.ptr1 == (VOID *) argv)) {
	objv[3]->typePtr = NULL;
    }

    result = Tcl_GetIndexFromObj((setError? interp : NULL), objv[3],
	    argv, "token", (allowAbbrev? 0 : TCL_EXACT), &index);
    ckfree((char *) argv);
    if (result == TCL_OK) {
	Tcl_SetIntObj(Tcl_GetObjResult(interp), index);
    }
    return result;
}

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
static int
TestintobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int intValue, varIndex, length, i;
    long longValue;
    char *index, *subCmd, *string;
	
    if (objc < 3) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * THIS FAILS IF AN OBJECT'S STRING REP HAS A NULL BYTE.
     */

    index = Tcl_GetStringFromObj(objv[2], &length);
    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    subCmd = Tcl_GetStringFromObj(objv[1], &length);
    if (strcmp(subCmd, "set") == 0) {
	if (objc != 4) {
	    goto wrongNumArgs;
	}
	string = Tcl_GetStringFromObj(objv[3], &length);
	if (Tcl_GetInt(interp, string, &i) != TCL_OK) {
	    return TCL_ERROR;
	}
	intValue = i;

	/*
	 * If the object currently bound to the variable with index varIndex







|









<
<
<
<
|




|




|







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
static int
TestintobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int intValue, varIndex, i;
    long longValue;
    char *index, *subCmd, *string;
	
    if (objc < 3) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }





    index = Tcl_GetString(objv[2]);
    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    subCmd = Tcl_GetString(objv[1]);
    if (strcmp(subCmd, "set") == 0) {
	if (objc != 4) {
	    goto wrongNumArgs;
	}
	string = Tcl_GetString(objv[3]);
	if (Tcl_GetInt(interp, string, &i) != TCL_OK) {
	    return TCL_ERROR;
	}
	intValue = i;

	/*
	 * If the object currently bound to the variable with index varIndex
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
	    SetVarToObj(varIndex, Tcl_NewIntObj(intValue));
	}
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else if (strcmp(subCmd, "set2") == 0) { /* doesn't set result */
	if (objc != 4) {
	    goto wrongNumArgs;
	}
	string = Tcl_GetStringFromObj(objv[3], &length);
	if (Tcl_GetInt(interp, string, &i) != TCL_OK) {
	    return TCL_ERROR;
	}
	intValue = i;
	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
	    Tcl_SetIntObj(varPtr[varIndex], intValue);
	} else {
	    SetVarToObj(varIndex, Tcl_NewIntObj(intValue));
	}
    } else if (strcmp(subCmd, "setlong") == 0) {
	if (objc != 4) {
	    goto wrongNumArgs;
	}
	string = Tcl_GetStringFromObj(objv[3], &length);
	if (Tcl_GetInt(interp, string, &i) != TCL_OK) {
	    return TCL_ERROR;
	}
	intValue = i;
	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
	    Tcl_SetLongObj(varPtr[varIndex], intValue);
	} else {







|













|







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
	    SetVarToObj(varIndex, Tcl_NewIntObj(intValue));
	}
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else if (strcmp(subCmd, "set2") == 0) { /* doesn't set result */
	if (objc != 4) {
	    goto wrongNumArgs;
	}
	string = Tcl_GetString(objv[3]);
	if (Tcl_GetInt(interp, string, &i) != TCL_OK) {
	    return TCL_ERROR;
	}
	intValue = i;
	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
	    Tcl_SetIntObj(varPtr[varIndex], intValue);
	} else {
	    SetVarToObj(varIndex, Tcl_NewIntObj(intValue));
	}
    } else if (strcmp(subCmd, "setlong") == 0) {
	if (objc != 4) {
	    goto wrongNumArgs;
	}
	string = Tcl_GetString(objv[3]);
	if (Tcl_GetInt(interp, string, &i) != TCL_OK) {
	    return TCL_ERROR;
	}
	intValue = i;
	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
	    Tcl_SetLongObj(varPtr[varIndex], intValue);
	} else {
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
	if (objc != 3) {
	    goto wrongNumArgs;
	}
	if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, varPtr[varIndex]);









    } else if (strcmp(subCmd, "inttoobigtest") == 0) {
	/*
	 * If long ints have more bits than ints on this platform, verify
	 * that Tcl_GetIntFromObj returns an error if the long int held
	 * in an integer object's internal representation is too large
	 * to fit in an int.
	 */
	
	long maxLong = LONG_MAX;
	
	if (objc != 3) {
	    goto wrongNumArgs;
	}
	if (INT_MAX == LONG_MAX) { /* int is same size as long int */
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", -1);
	} else {
	    if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
		Tcl_SetLongObj(varPtr[varIndex], maxLong);
	    } else {
		SetVarToObj(varIndex, Tcl_NewLongObj(maxLong));
	    }
	    if (Tcl_GetIntFromObj(interp, varPtr[varIndex], &i) != TCL_OK) {
		Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", -1);
		return TCL_OK;
	    }
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), "0", -1);
	}

    } else if (strcmp(subCmd, "mult10") == 0) {
	if (objc != 3) {
	    goto wrongNumArgs;
	}
	if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}







>
>
>
>
>
>
>
>
>








<
<



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







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
	if (objc != 3) {
	    goto wrongNumArgs;
	}
	if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else if (strcmp(subCmd, "get2") == 0) {
	if (objc != 3) {
	    goto wrongNumArgs;
	}
	if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
	string = Tcl_GetString(varPtr[varIndex]);
	Tcl_AppendToObj(Tcl_GetObjResult(interp), string, -1);
    } else if (strcmp(subCmd, "inttoobigtest") == 0) {
	/*
	 * If long ints have more bits than ints on this platform, verify
	 * that Tcl_GetIntFromObj returns an error if the long int held
	 * in an integer object's internal representation is too large
	 * to fit in an int.
	 */
	


	if (objc != 3) {
	    goto wrongNumArgs;
	}
#if (INT_MAX == LONG_MAX)   /* int is same size as long int */
	Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", -1);
#else 
	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
	    Tcl_SetLongObj(varPtr[varIndex], LONG_MAX);
	} else {
	    SetVarToObj(varIndex, Tcl_NewLongObj(LONG_MAX));
	}
	if (Tcl_GetIntFromObj(interp, varPtr[varIndex], &i) != TCL_OK) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", -1);
	    return TCL_OK;
	}
	Tcl_AppendToObj(Tcl_GetObjResult(interp), "0", -1);

#endif
    } else if (strcmp(subCmd, "mult10") == 0) {
	if (objc != 3) {
	    goto wrongNumArgs;
	}
	if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
646
647
648
649
650
651
652
653
654

655
656
657
658
659
660
661
	    Tcl_SetIntObj(varPtr[varIndex], (intValue / 10));
	} else {
	    SetVarToObj(varIndex, Tcl_NewIntObj( (intValue / 10) ));
	}
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"bad option \"", Tcl_GetStringFromObj(objv[1], (int *) NULL),
		"\": must be set, get, mult10, or div10", (char *) NULL);

	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|
|
>







650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
	    Tcl_SetIntObj(varPtr[varIndex], (intValue / 10));
	} else {
	    SetVarToObj(varIndex, Tcl_NewIntObj( (intValue / 10) ));
	}
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"bad option \"", Tcl_GetString(objv[1]),
		"\": must be set, get, get2, mult10, or div10",
		(char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778


779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int varIndex, destIndex, i;
    char *index, *subCmd, *string;
    Tcl_ObjType *targetType;
    char buf[20];
    int length;
	
    if (objc < 2) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * THIS FAILS IF AN OBJECT'S STRING REP HAS A NULL BYTE.
     */

    subCmd = Tcl_GetStringFromObj(objv[1], &length);
    if (strcmp(subCmd, "assign") == 0) {
        if (objc != 4) {
            goto wrongNumArgs;
        }
        index = Tcl_GetStringFromObj(objv[2], &length);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
	string = Tcl_GetStringFromObj(objv[3], &length);
        if (GetVariableIndex(interp, string, &destIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        SetVarToObj(destIndex, varPtr[varIndex]);
	Tcl_SetObjResult(interp, varPtr[destIndex]);
     } else if (strcmp(subCmd, "convert") == 0) {
        char *typeName;
        if (objc != 4) {
            goto wrongNumArgs;
        }
        index = Tcl_GetStringFromObj(objv[2], &length);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
        typeName = Tcl_GetStringFromObj(objv[3], &length);
        if ((targetType = Tcl_GetObjType(typeName)) == NULL) {
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "no type ", typeName, " found", (char *) NULL);
            return TCL_ERROR;
        }
        if (Tcl_ConvertToType(interp, varPtr[varIndex], targetType)
            != TCL_OK) {
            return TCL_ERROR;
        }
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else if (strcmp(subCmd, "duplicate") == 0) {
        if (objc != 4) {
            goto wrongNumArgs;
        }
        index = Tcl_GetStringFromObj(objv[2], &length);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
	string = Tcl_GetStringFromObj(objv[3], &length);
        if (GetVariableIndex(interp, string, &destIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        SetVarToObj(destIndex, Tcl_DuplicateObj(varPtr[varIndex]));
	Tcl_SetObjResult(interp, varPtr[destIndex]);
    } else if (strcmp(subCmd, "freeallvars") == 0) {
        if (objc != 2) {
            goto wrongNumArgs;
        }
        for (i = 0;  i < NUMBER_OF_OBJECT_VARS;  i++) {
            if (varPtr[i] != NULL) {
                Tcl_DecrRefCount(varPtr[i]);
                varPtr[i] = NULL;
            }
        }
    } else if (strcmp(subCmd, "newobj") == 0) {
        if (objc != 3) {
            goto wrongNumArgs;
        }
        index = Tcl_GetStringFromObj(objv[2], &length);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        SetVarToObj(varIndex, Tcl_NewObj());
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else if (strcmp(subCmd, "refcount") == 0) {


        if (objc != 3) {
            goto wrongNumArgs;
        }
        index = Tcl_GetStringFromObj(objv[2], &length);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
        sprintf(buf, "%d", varPtr[varIndex]->refCount);
        Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
    } else if (strcmp(subCmd, "type") == 0) {
        if (objc != 3) {
            goto wrongNumArgs;
        }
        index = Tcl_GetStringFromObj(objv[2], &length);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
        if (varPtr[varIndex]->typePtr == NULL) { /* a string! */







<
<







<
<
<
<
|




|






|










|






|














|






|



















|






>
>



|






|
|




|







685
686
687
688
689
690
691


692
693
694
695
696
697
698




699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int varIndex, destIndex, i;
    char *index, *subCmd, *string;
    Tcl_ObjType *targetType;


	
    if (objc < 2) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }





    subCmd = Tcl_GetString(objv[1]);
    if (strcmp(subCmd, "assign") == 0) {
        if (objc != 4) {
            goto wrongNumArgs;
        }
        index = Tcl_GetString(objv[2]);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[3]);
        if (GetVariableIndex(interp, string, &destIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        SetVarToObj(destIndex, varPtr[varIndex]);
	Tcl_SetObjResult(interp, varPtr[destIndex]);
     } else if (strcmp(subCmd, "convert") == 0) {
        char *typeName;
        if (objc != 4) {
            goto wrongNumArgs;
        }
        index = Tcl_GetString(objv[2]);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
        typeName = Tcl_GetString(objv[3]);
        if ((targetType = Tcl_GetObjType(typeName)) == NULL) {
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "no type ", typeName, " found", (char *) NULL);
            return TCL_ERROR;
        }
        if (Tcl_ConvertToType(interp, varPtr[varIndex], targetType)
            != TCL_OK) {
            return TCL_ERROR;
        }
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else if (strcmp(subCmd, "duplicate") == 0) {
        if (objc != 4) {
            goto wrongNumArgs;
        }
        index = Tcl_GetString(objv[2]);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[3]);
        if (GetVariableIndex(interp, string, &destIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        SetVarToObj(destIndex, Tcl_DuplicateObj(varPtr[varIndex]));
	Tcl_SetObjResult(interp, varPtr[destIndex]);
    } else if (strcmp(subCmd, "freeallvars") == 0) {
        if (objc != 2) {
            goto wrongNumArgs;
        }
        for (i = 0;  i < NUMBER_OF_OBJECT_VARS;  i++) {
            if (varPtr[i] != NULL) {
                Tcl_DecrRefCount(varPtr[i]);
                varPtr[i] = NULL;
            }
        }
    } else if (strcmp(subCmd, "newobj") == 0) {
        if (objc != 3) {
            goto wrongNumArgs;
        }
        index = Tcl_GetString(objv[2]);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        SetVarToObj(varIndex, Tcl_NewObj());
	Tcl_SetObjResult(interp, varPtr[varIndex]);
    } else if (strcmp(subCmd, "refcount") == 0) {
	char buf[TCL_INTEGER_SPACE];

        if (objc != 3) {
            goto wrongNumArgs;
        }
        index = Tcl_GetString(objv[2]);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
	TclFormatInt(buf, varPtr[varIndex]->refCount);
        Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else if (strcmp(subCmd, "type") == 0) {
        if (objc != 3) {
            goto wrongNumArgs;
        }
        index = Tcl_GetString(objv[2]);
        if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        if (CheckIfVarUnset(interp, varIndex)) {
	    return TCL_ERROR;
	}
        if (varPtr[varIndex]->typePtr == NULL) { /* a string! */
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
        }
	if (Tcl_AppendAllObjTypes(interp, Tcl_GetObjResult(interp)) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"bad option \"",
		Tcl_GetStringFromObj(objv[1], (int *) NULL),
		"\": must be assign, convert, duplicate, freeallvars, ",
		"newobj, objcount, refcount, type, or types",
		(char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}







|







812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
        }
	if (Tcl_AppendAllObjTypes(interp, Tcl_GetObjResult(interp)) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"bad option \"",
		Tcl_GetString(objv[1]),
		"\": must be assign, convert, duplicate, freeallvars, ",
		"newobj, objcount, refcount, type, or types",
		(char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
TeststringobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int varIndex, option, i, length;
#define MAX_STRINGS 10
    char *index, *string, *strings[MAX_STRINGS+1];
    static char *options[] = {
	"append", "appendstrings", "get", "length", "length2",
	"set", "set2", "setlength", (char *) NULL
    };

    if (objc < 3) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    index = Tcl_GetStringFromObj(objv[2], (int *) NULL);
    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &option)
	    != TCL_OK) {
	return TCL_ERROR;







|


|









|







847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
TeststringobjCmd(clientData, interp, objc, objv)
    ClientData clientData;	/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    int varIndex, option, i, length;
#define MAX_STRINGS 11
    char *index, *string, *strings[MAX_STRINGS+1];
    static char *options[] = {
	"append", "appendstrings", "get", "get2", "length", "length2",
	"set", "set2", "setlength", (char *) NULL
    };

    if (objc < 3) {
	wrongNumArgs:
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    index = Tcl_GetString(objv[2]);
    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &option)
	    != TCL_OK) {
	return TCL_ERROR;
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917

918

919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934










935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
	     * If the object bound to variable "varIndex" is shared, we must
	     * "copy on write" and append to a copy of the object. 
	     */
	    
	    if (Tcl_IsShared(varPtr[varIndex])) {
		SetVarToObj(varIndex, Tcl_DuplicateObj(varPtr[varIndex]));
	    }
	    string = Tcl_GetStringFromObj(objv[3], (int *) NULL);
	    Tcl_AppendToObj(varPtr[varIndex], string, length);
	    Tcl_SetObjResult(interp, varPtr[varIndex]);
	    break;
	case 1:				/* appendstrings */
	    if (objc > (MAX_STRINGS+3)) {
		goto wrongNumArgs;
	    }
	    if (varPtr[varIndex] == NULL) {
		SetVarToObj(varIndex, Tcl_NewObj());
	    }

	    /*
	     * If the object bound to variable "varIndex" is shared, we must
	     * "copy on write" and append to a copy of the object. 
	     */

	    if (Tcl_IsShared(varPtr[varIndex])) {
		SetVarToObj(varIndex, Tcl_DuplicateObj(varPtr[varIndex]));
	    }
	    for (i = 3;  i < objc;  i++) {
		strings[i-3] = Tcl_GetStringFromObj(objv[i], (int *) NULL);
	    }

	    strings[objc-3] = NULL;

	    Tcl_AppendStringsToObj(varPtr[varIndex], strings[0], strings[1],
		    strings[2], strings[3], strings[4], strings[5],
		    strings[6], strings[7], strings[8], strings[9],
		    strings[10], strings[11]);
	    Tcl_SetObjResult(interp, varPtr[varIndex]);
	    break;
	case 2:				/* get */
	    if (objc != 3) {
		goto wrongNumArgs;
	    }
	    if (CheckIfVarUnset(interp, varIndex)) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, varPtr[varIndex]);
	    break;
	case 3:				/* length */










	    if (objc != 3) {
		goto wrongNumArgs;
	    }
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), (varPtr[varIndex] != NULL)
		    ? varPtr[varIndex]->length : -1);
	    break;
	case 4:				/* length2 */
	    if (objc != 3) {
		goto wrongNumArgs;
	    }
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), (varPtr[varIndex] != NULL)
		    ? (int) varPtr[varIndex]->internalRep.longValue : -1);
	    break;
	case 5:				/* set */
	    if (objc != 4) {
		goto wrongNumArgs;
	    }

	    /*
	     * If the object currently bound to the variable with index
	     * varIndex has ref count 1 (i.e. the object is unshared) we







|




















|

>
|
>















|
>
>
>
>
>
>
>
>
>
>






|






|







889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
	     * If the object bound to variable "varIndex" is shared, we must
	     * "copy on write" and append to a copy of the object. 
	     */
	    
	    if (Tcl_IsShared(varPtr[varIndex])) {
		SetVarToObj(varIndex, Tcl_DuplicateObj(varPtr[varIndex]));
	    }
	    string = Tcl_GetString(objv[3]);
	    Tcl_AppendToObj(varPtr[varIndex], string, length);
	    Tcl_SetObjResult(interp, varPtr[varIndex]);
	    break;
	case 1:				/* appendstrings */
	    if (objc > (MAX_STRINGS+3)) {
		goto wrongNumArgs;
	    }
	    if (varPtr[varIndex] == NULL) {
		SetVarToObj(varIndex, Tcl_NewObj());
	    }

	    /*
	     * If the object bound to variable "varIndex" is shared, we must
	     * "copy on write" and append to a copy of the object. 
	     */

	    if (Tcl_IsShared(varPtr[varIndex])) {
		SetVarToObj(varIndex, Tcl_DuplicateObj(varPtr[varIndex]));
	    }
	    for (i = 3;  i < objc;  i++) {
		strings[i-3] = Tcl_GetString(objv[i]);
	    }
	    for ( ; i < 12 + 3; i++) {
		strings[i - 3] = NULL;
	    }
	    Tcl_AppendStringsToObj(varPtr[varIndex], strings[0], strings[1],
		    strings[2], strings[3], strings[4], strings[5],
		    strings[6], strings[7], strings[8], strings[9],
		    strings[10], strings[11]);
	    Tcl_SetObjResult(interp, varPtr[varIndex]);
	    break;
	case 2:				/* get */
	    if (objc != 3) {
		goto wrongNumArgs;
	    }
	    if (CheckIfVarUnset(interp, varIndex)) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, varPtr[varIndex]);
	    break;
	case 3:				/* get2 */
	    if (objc != 3) {
		goto wrongNumArgs;
	    }
	    if (CheckIfVarUnset(interp, varIndex)) {
		return TCL_ERROR;
	    }
	    string = Tcl_GetString(varPtr[varIndex]);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp), string, -1);
	    break;
	case 4:				/* length */
	    if (objc != 3) {
		goto wrongNumArgs;
	    }
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), (varPtr[varIndex] != NULL)
		    ? varPtr[varIndex]->length : -1);
	    break;
	case 5:				/* length2 */
	    if (objc != 3) {
		goto wrongNumArgs;
	    }
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), (varPtr[varIndex] != NULL)
		    ? (int) varPtr[varIndex]->internalRep.longValue : -1);
	    break;
	case 6:				/* set */
	    if (objc != 4) {
		goto wrongNumArgs;
	    }

	    /*
	     * If the object currently bound to the variable with index
	     * varIndex has ref count 1 (i.e. the object is unshared) we
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
		    && !Tcl_IsShared(varPtr[varIndex])) {
		Tcl_SetStringObj(varPtr[varIndex], string, length);
	    } else {
		SetVarToObj(varIndex, Tcl_NewStringObj(string, length));
	    }
	    Tcl_SetObjResult(interp, varPtr[varIndex]);
	    break;
	case 6:				/* set2 */
	    if (objc != 4) {
		goto wrongNumArgs;
	    }
	    SetVarToObj(varIndex, objv[3]);
	    break;
	case 7:				/* setlength */
	    if (objc != 4) {
		goto wrongNumArgs;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[3], &length) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (varPtr[varIndex] != NULL) {







|





|







977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
		    && !Tcl_IsShared(varPtr[varIndex])) {
		Tcl_SetStringObj(varPtr[varIndex], string, length);
	    } else {
		SetVarToObj(varIndex, Tcl_NewStringObj(string, length));
	    }
	    Tcl_SetObjResult(interp, varPtr[varIndex]);
	    break;
	case 7:				/* set2 */
	    if (objc != 4) {
		goto wrongNumArgs;
	    }
	    SetVarToObj(varIndex, objv[3]);
	    break;
	case 8:				/* setlength */
	    if (objc != 4) {
		goto wrongNumArgs;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[3], &length) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (varPtr[varIndex] != NULL) {
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097

static int
CheckIfVarUnset(interp, varIndex)
    Tcl_Interp *interp;		/* Interpreter for error reporting. */
    int varIndex;		/* Index of the test variable to check. */
{
    if (varPtr[varIndex] == NULL) {
	char buf[100];
	
	sprintf(buf, "variable %d is unset (NULL)", varIndex);
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
	return 1;
    }
    return 0;
}







|








1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110

static int
CheckIfVarUnset(interp, varIndex)
    Tcl_Interp *interp;		/* Interpreter for error reporting. */
    int varIndex;		/* Index of the test variable to check. */
{
    if (varPtr[varIndex] == NULL) {
	char buf[32 + TCL_INTEGER_SPACE];
	
	sprintf(buf, "variable %d is unset (NULL)", varIndex);
	Tcl_ResetResult(interp);
	Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
	return 1;
    }
    return 0;
}

Added generic/tclTestProcBodyObj.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
/* 
 * tclTestProcBodyObj.c --
 *
 *	Implements the "procbodytest" package, which contains commands
 *	to test creation of Tcl procedures whose body argument is a
 *	Tcl_Obj of type "procbody" rather than a string.
 *
 * 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: tclTestProcBodyObj.c,v 1.1.2.2 1998/11/11 04:08:24 stanton Exp $
 */

#include "tclInt.h"

/*
 * name and version of this package
 */

static char packageName[] = "procbodytest";
static char packageVersion[] = "1.0";

/*
 * Name of the commands exported by this package
 */

static char procCommand[] = "proc";

/*
 * this struct describes an entry in the table of command names and command
 * procs
 */

typedef struct CmdTable
{
    char *cmdName;		/* command name */
    Tcl_ObjCmdProc *proc;	/* command proc */
    int exportIt;		/* if 1, export the command */
} CmdTable;

/*
 * Declarations for functions defined in this file.
 */

static int	ProcBodyTestProcObjCmd _ANSI_ARGS_((ClientData dummy,
			Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
static int	ProcBodyTestInitInternal _ANSI_ARGS_((Tcl_Interp *interp,
			int isSafe));
static int	RegisterCommand _ANSI_ARGS_((Tcl_Interp* interp,
			char *namespace, CONST CmdTable *cmdTablePtr));
int             Procbodytest_Init _ANSI_ARGS_((Tcl_Interp * interp));
int             Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp * interp));

/*
 * List of commands to create when the package is loaded; must go after the
 * declarations of the enable command procedure.
 */

static CONST CmdTable commands[] =
{
    { procCommand,	ProcBodyTestProcObjCmd,	1 },

    { 0, 0, 0 }
};

static CONST CmdTable safeCommands[] =
{
    { procCommand,	ProcBodyTestProcObjCmd,	1 },

    { 0, 0, 0 }
};

/*
 *----------------------------------------------------------------------
 *
 * Procbodytest_Init --
 *
 *  This procedure initializes the "procbodytest" package.
 *
 * Results:
 *  A standard Tcl result.
 *
 * Side effects:
 *  None.
 *
 *----------------------------------------------------------------------
 */

int
Procbodytest_Init(interp)
    Tcl_Interp *interp;		/* the Tcl interpreter for which the package
                                 * is initialized */
{
    return ProcBodyTestInitInternal(interp, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * Procbodytest_SafeInit --
 *
 *  This procedure initializes the "procbodytest" package.
 *
 * Results:
 *  A standard Tcl result.
 *
 * Side effects:
 *  None.
 *
 *----------------------------------------------------------------------
 */

int
Procbodytest_SafeInit(interp)
    Tcl_Interp *interp;		/* the Tcl interpreter for which the package
                                 * is initialized */
{
    return ProcBodyTestInitInternal(interp, 1);
}

/*
 *----------------------------------------------------------------------
 *
 * RegisterCommand --
 *
 *  This procedure registers a command in the context of the given namespace.
 *
 * Results:
 *  A standard Tcl result.
 *
 * Side effects:
 *  None.
 *
 *----------------------------------------------------------------------
 */

static int RegisterCommand(interp, namespace, cmdTablePtr)
    Tcl_Interp* interp;			/* the Tcl interpreter for which the
                                         * operation is performed */
    char *namespace;			/* the namespace in which the command
                                         * is registered */
    CONST CmdTable *cmdTablePtr;	/* the command to register */
{
    char buf[128];

    if (cmdTablePtr->exportIt) {
        sprintf(buf, "namespace eval %s { namespace export %s }",
                namespace, cmdTablePtr->cmdName);
        if (Tcl_Eval(interp, buf) != TCL_OK)
            return TCL_ERROR;
    }
    
    sprintf(buf, "%s::%s", namespace, cmdTablePtr->cmdName);
    Tcl_CreateObjCommand(interp, buf, cmdTablePtr->proc, 0, 0);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ProcBodyTestInitInternal --
 *
 *  This procedure initializes the Loader package.
 *  The isSafe flag is 1 if the interpreter is safe, 0 otherwise.
 *
 * Results:
 *  A standard Tcl result.
 *
 * Side effects:
 *  None.
 *
 *----------------------------------------------------------------------
 */

static int
ProcBodyTestInitInternal(interp, isSafe)
    Tcl_Interp *interp;		/* the Tcl interpreter for which the package
                                 * is initialized */
    int isSafe;			/* 1 if this is a safe interpreter */
{
    CONST CmdTable *cmdTablePtr;

    cmdTablePtr = (isSafe) ? &safeCommands[0] : &commands[0];
    for ( ; cmdTablePtr->cmdName ; cmdTablePtr++) {
        if (RegisterCommand(interp, packageName, cmdTablePtr) != TCL_OK) {
            return TCL_ERROR;
        }
    }
    
    return Tcl_PkgProvide(interp, packageName, packageVersion);
}

/*
 *----------------------------------------------------------------------
 *
 * ProcBodyTestProcObjCmd --
 *
 *  Implements the "procbodytest::proc" command. Here is the command
 *  description:
 *	procbodytest::proc newName argList bodyName
 *  Looks up a procedure called $bodyName and, if the procedure exists,
 *  constructs a Tcl_Obj of type "procbody" and calls Tcl_ProcObjCmd.
 *  Arguments:
 *    newName		the name of the procedure to be created
 *    argList		the argument list for the procedure
 *    bodyName		the name of an existing procedure from which the
 *			body is to be copied.
 *  This command can be used to trigger the branches in Tcl_ProcObjCmd that
 *  construct a proc from a "procbody", for example:
 *	proc a {x} {return $x}
 *	a 123
 *	procbodytest::proc b {x} a
 *  Note the call to "a 123", which is necessary so that the Proc pointer
 *  for "a" is filled in by the internal compiler; this is a hack.
 *
 * Results:
 *  Returns a standard Tcl code.
 *
 * Side effects:
 *  A new procedure is created.
 *  Leaves an error message in the interp's result on error.
 *
 *----------------------------------------------------------------------
 */

static int
ProcBodyTestProcObjCmd (dummy, interp, objc, objv)
    ClientData dummy;		/* context; not used */
    Tcl_Interp *interp;		/* the current interpreter */
    int objc;			/* argument count */
    Tcl_Obj *CONST objv[];	/* arguments */
{
    char *fullName;
    Tcl_Command procCmd;
    Command *cmdPtr;
    Proc *procPtr = (Proc *) NULL;
    Tcl_Obj *bodyObjPtr;
    Tcl_Obj *myobjv[5];
    int result;
    
    if (objc != 4) {
	Tcl_WrongNumArgs(interp, 1, objv, "newName argsList bodyName");
	return TCL_ERROR;
    }

    /*
     * Find the Command pointer to this procedure
     */
    
    fullName = Tcl_GetStringFromObj(objv[3], (int *) NULL);
    procCmd = Tcl_FindCommand(interp, fullName, (Tcl_Namespace *) NULL,
            TCL_LEAVE_ERR_MSG);
    if (procCmd == NULL) {
        return TCL_ERROR;
    }

    cmdPtr = (Command *) procCmd;

    /*
     * check that this is a procedure and not a builtin command:
     * If a procedure, cmdPtr->objProc is either 0 or TclObjInterpProc,
     * and cmdPtr->proc is either 0 or TclProcInterpProc.
     * Also, the compile proc should be 0, but we don't check for that.
     */

    if (((cmdPtr->objProc != NULL)
            && (cmdPtr->objProc != TclGetObjInterpProc()))
            || ((cmdPtr->proc != NULL)
                    && (cmdPtr->proc != TclGetInterpProc()))) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"command \"", fullName,
		"\" is not a Tcl procedure", (char *) NULL);
        return TCL_ERROR;
    }

    /*
     * it is a Tcl procedure: the client data is the Proc structure
     */
    
    if (cmdPtr->objProc != NULL) {
        procPtr = (Proc *) cmdPtr->objClientData;
    } else if (cmdPtr->proc != NULL) {
        procPtr = (Proc *) cmdPtr->clientData;
    }

    if (procPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"procedure \"", fullName,
		"\" does not have a Proc struct!", (char *) NULL);
        return TCL_ERROR;
    }
        
    /*
     * create a new object, initialize our argument vector, call into Tcl
     */

    bodyObjPtr = TclNewProcBodyObj(procPtr);
    if (bodyObjPtr == NULL) {
        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"failed to create a procbody object for procedure \"",
                fullName, "\"", (char *) NULL);
        return TCL_ERROR;
    }
    Tcl_IncrRefCount(bodyObjPtr);

    myobjv[0] = objv[0];
    myobjv[1] = objv[1];
    myobjv[2] = objv[2];
    myobjv[3] = bodyObjPtr;
    myobjv[4] = (Tcl_Obj *) NULL;

    result = Tcl_ProcObjCmd((ClientData) NULL, interp, objc, myobjv);
    Tcl_DecrRefCount(bodyObjPtr);

    return result;
}

Added generic/tclThread.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
/* 
 * tclThread.c --
 *
 *	This file implements   Platform independent thread operations.
 *	Most of the real work is done in the platform dependent files.
 *
 * Copyright (c) 1998 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: tclThread.c,v 1.1.2.8 1999/04/14 00:33:27 surles Exp $
 */

#include "tclInt.h"

/*
 * There are three classes of synchronization objects:
 * mutexes, thread data keys, and condition variables.
 * The following are used to record the memory used for these
 * objects so they can be finalized.
 *
 * These statics are guarded by the mutex in the caller of
 * TclRememberThreadData, e.g., TclpThreadDataKeyInit
 */

typedef struct {
    int num;		/* Number of objects remembered */
    int max;		/* Max size of the array */
    char **list;	/* List of pointers */
} SyncObjRecord;

static SyncObjRecord keyRecord;
static SyncObjRecord mutexRecord;
static SyncObjRecord condRecord;

/*
 * Prototypes of functions used only in this file
 */
 
static void		RememberSyncObject _ANSI_ARGS_((char *objPtr,
			    SyncObjRecord *recPtr));
static void		ForgetSyncObject _ANSI_ARGS_((char *objPtr,
			    SyncObjRecord *recPtr));


/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetThreadData --
 *
 *	This procedure allocates and initializes a chunk of thread
 *	local storage.
 *
 * Results:
 *	A thread-specific pointer to the data structure.
 *
 * Side effects:
 *	Will allocate memory the first time this thread calls for
 *	this chunk of storage.
 *
 *----------------------------------------------------------------------
 */

VOID *
Tcl_GetThreadData(keyPtr, size)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk */
    int size;			/* Size of storage block */
{
    VOID *result;
#ifdef TCL_THREADS

    /*
     * See if this is the first thread to init this key.
     */

    if (*keyPtr == NULL) {
	TclpThreadDataKeyInit(keyPtr);
    }

    /*
     * Initialize the key for this thread.
     */

    result = TclpThreadDataKeyGet(keyPtr);
    if (result == NULL) {
	result  = (VOID *)ckalloc((size_t)size);
	memset(result, 0, (size_t)size);
	TclpThreadDataKeySet(keyPtr, result);
    }
#else
    if (*keyPtr == NULL) {
	result = (VOID *)ckalloc((size_t)size);
	memset((char *)result, 0, (size_t)size);
	*keyPtr = (Tcl_ThreadDataKey)result;
	TclRememberDataKey(keyPtr);
    }
    result = *(VOID **)keyPtr;
#endif
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclThreadDataKeyGet --
 *
 *	This procedure returns a pointer to a block of thread local storage.
 *
 * Results:
 *	A thread-specific pointer to the data structure, or NULL
 *	if the memory has not been assigned to this key for this thread.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

VOID *
TclThreadDataKeyGet(keyPtr)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (pthread_key_t **) */
{
#ifdef TCL_THREADS
    return (VOID *)TclpThreadDataKeyGet(keyPtr);
#else
    char *result = *(char **)keyPtr;
    return (VOID *)result;
#endif /* TCL_THREADS */
}


/*
 *----------------------------------------------------------------------
 *
 * TclThreadDataKeySet --
 *
 *	This procedure sets a thread local storage pointer.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The assigned value will be returned by TclpThreadDataKeyGet.
 *
 *----------------------------------------------------------------------
 */

void
TclThreadDataKeySet(keyPtr, data)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (pthread_key_t **) */
    VOID *data;			/* Thread local storage */
{
#ifdef TCL_THREADS
    if (*keyPtr == NULL) {
	TclpThreadDataKeyInit(keyPtr);
    }
    TclpThreadDataKeySet(keyPtr, data);
#else
    *keyPtr = (Tcl_ThreadDataKey)data;
#endif /* TCL_THREADS */
}



/*
 *----------------------------------------------------------------------
 *
 * RememberSyncObject
 *
 *      Keep a list of (mutexes/condition variable/data key)
 *	used during finalization.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Add to the appropriate list.
 *
 *----------------------------------------------------------------------
 */

static void
RememberSyncObject(objPtr, recPtr)
    char *objPtr;		/* Pointer to sync object */
    SyncObjRecord *recPtr;	/* Record of sync objects */
{
    char **newList;
    int i, j;

    /*
     * Save the pointer to the allocated object so it can be finalized.
     * Grow the list of pointers if necessary, copying only non-NULL
     * pointers to the new list.
     */

    if (recPtr->num >= recPtr->max) {
	recPtr->max += 8;
	newList = (char **)ckalloc(recPtr->max * sizeof(char *));
	for (i=0,j=0 ; i<recPtr->num ; i++) {
            if (recPtr->list[i] != NULL) {
		newList[j++] = recPtr->list[i];
            }
	}
	if (recPtr->list != NULL) {
	    ckfree((char *)recPtr->list);
	}
	recPtr->list = newList;
	recPtr->num = j;
    }
    recPtr->list[recPtr->num] = objPtr;
    recPtr->num++;
}

/*
 *----------------------------------------------------------------------
 *
 * ForgetSyncObject
 *
 *      Remove a single object from the list.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Remove from the appropriate list.
 *
 *----------------------------------------------------------------------
 */

static void
ForgetSyncObject(objPtr, recPtr)
    char *objPtr;		/* Pointer to sync object */
    SyncObjRecord *recPtr;	/* Record of sync objects */
{
    int i;

    for (i=0 ; i<recPtr->num ; i++) {
	if (objPtr == recPtr->list[i]) {
	    recPtr->list[i] = NULL;
	    return;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclRememberMutex
 *
 *      Keep a list of mutexes used during finalization.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Add to the mutex list.
 *
 *----------------------------------------------------------------------
 */

void
TclRememberMutex(mutexPtr)
    Tcl_Mutex *mutexPtr;
{
    RememberSyncObject((char *)mutexPtr, &mutexRecord);
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeMutex
 *
 *      Finalize a single mutex and remove it from the
 *	list of remembered objects.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Remove the mutex from the list.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeMutex(mutexPtr)
    Tcl_Mutex *mutexPtr;
{
#ifdef TCL_THREADS
    TclpFinalizeMutex(mutexPtr);
#endif
    ForgetSyncObject((char *)mutexPtr, &mutexRecord);
}

/*
 *----------------------------------------------------------------------
 *
 * TclRememberDataKey
 *
 *      Keep a list of thread data keys used during finalization.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Add to the key list.
 *
 *----------------------------------------------------------------------
 */

void
TclRememberDataKey(keyPtr)
    Tcl_ThreadDataKey *keyPtr;
{
    RememberSyncObject((char *)keyPtr, &keyRecord);
}

/*
 *----------------------------------------------------------------------
 *
 * TclRememberCondition
 *
 *      Keep a list of condition variables used during finalization.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Add to the condition variable list.
 *
 *----------------------------------------------------------------------
 */

void
TclRememberCondition(condPtr)
    Tcl_Condition *condPtr;
{
    RememberSyncObject((char *)condPtr, &condRecord);
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeCondition
 *
 *      Finalize a single condition variable and remove it from the
 *	list of remembered objects.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Remove the condition variable from the list.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeCondition(condPtr)
    Tcl_Condition *condPtr;
{
#ifdef TCL_THREADS
    TclpFinalizeCondition(condPtr);
#endif
    ForgetSyncObject((char *)condPtr, &condRecord);
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeThreadData --
 *
 *	This procedure cleans up the thread-local storage.  This is
 *	called once for each thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees up all thread local storage.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeThreadData()
{
    int i;
    Tcl_ThreadDataKey *keyPtr;

    TclpMasterLock();
    for (i=0 ; i<keyRecord.num ; i++) {
	keyPtr = (Tcl_ThreadDataKey *) keyRecord.list[i];
#ifdef TCL_THREADS
	TclpFinalizeThreadData(keyPtr);
#else
	if (*keyPtr != NULL) {
	    ckfree((char *)*keyPtr);
	    *keyPtr = NULL;
	}
#endif
    }
    TclpMasterUnlock();
}

/*
 *----------------------------------------------------------------------
 *
 * TclFinalizeSyncronization --
 *
 *      This procedure cleans up all synchronization objects:
 *      mutexes, condition variables, and thread-local storage.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees up the memory.
 *
 *----------------------------------------------------------------------
 */

void
TclFinalizeSynchronization()
{
#ifdef TCL_THREADS
    Tcl_ThreadDataKey *keyPtr;
    Tcl_Mutex *mutexPtr;
    Tcl_Condition *condPtr;
    int i;

    TclpMasterLock();
    for (i=0 ; i<keyRecord.num ; i++) {
	keyPtr = (Tcl_ThreadDataKey *)keyRecord.list[i];
	TclpFinalizeThreadDataKey(keyPtr);
    }
    if (keyRecord.list != NULL) {
	ckfree((char *)keyRecord.list);
	keyRecord.list = NULL;
    }
    keyRecord.max = 0;
    keyRecord.num = 0;

    for (i=0 ; i<mutexRecord.num ; i++) {
	mutexPtr = (Tcl_Mutex *)mutexRecord.list[i];
	if (mutexPtr != NULL) {
	    TclpFinalizeMutex(mutexPtr);
	}
    }
    if (mutexRecord.list != NULL) {
	ckfree((char *)mutexRecord.list);
	mutexRecord.list = NULL;
    }
    mutexRecord.max = 0;
    mutexRecord.num = 0;

    for (i=0 ; i<condRecord.num ; i++) {
	condPtr = (Tcl_Condition *)condRecord.list[i];
	if (condPtr != NULL) {
	    TclpFinalizeCondition(condPtr);
	}
    }
    if (condRecord.list != NULL) {
	ckfree((char *)condRecord.list);
	condRecord.list = NULL;
    }
    condRecord.max = 0;
    condRecord.num = 0;

    TclpMasterUnlock();
#else
    if (keyRecord.list != NULL) {
	ckfree((char *)keyRecord.list);
	keyRecord.list = NULL;
    }
    keyRecord.max = 0;
    keyRecord.num = 0;
#endif
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_ExitThread --
 *
 *	This procedure is called to terminate the current thread.
 *	This should be used by extensions that create threads with
 *	additional interpreters in them.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	All thread exit handlers are invoked, then the thread dies.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ExitThread(status)
    int status;
{
    Tcl_FinalizeThread();
#ifdef TCL_THREADS
    TclpThreadExit(status);
#endif
}

#ifndef TCL_THREADS

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConditionWait, et al. --
 *
 *	These noop procedures are provided so the stub table does
 *	not have to be conditionalized for threads.  The real
 *	implementations of these functions live in the platform
 *	specific files.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#undef Tcl_ConditionWait
void
Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
    Tcl_Condition *condPtr;	/* Really (pthread_cond_t **) */
    Tcl_Mutex *mutexPtr;	/* Really (pthread_mutex_t **) */
    Tcl_Time *timePtr;		/* Timeout on waiting period */
{
}

#undef Tcl_ConditionNotify
void
Tcl_ConditionNotify(condPtr)
    Tcl_Condition *condPtr;
{
}

#undef Tcl_MutexLock
void
Tcl_MutexLock(mutexPtr)
    Tcl_Mutex *mutexPtr;
{
}

#undef Tcl_MutexUnlock
void
Tcl_MutexUnlock(mutexPtr)
    Tcl_Mutex *mutexPtr;
{
}
#endif

Added generic/tclThreadTest.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
/* 
 * tclThreadTest.c --
 *
 *	This file implements the testthread command.  Eventually this
 *	should be tclThreadCmd.c
 *	Some of this code is based on work done by Richard Hipp on behalf of
 *	Conservation Through Innovation, Limited, with their permission.
 *
 * Copyright (c) 1998 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: tclThreadTest.c,v 1.1.2.9 1999/04/14 00:33:28 surles Exp $
 */

#include "tclInt.h"

#ifdef TCL_THREADS
/*
 * Each thread has an single instance of the following structure.  There
 * is one instance of this structure per thread even if that thread contains
 * multiple interpreters.  The interpreter identified by this structure is
 * the main interpreter for the thread.  
 *
 * The main interpreter is the one that will process any messages 
 * received by a thread.  Any thread can send messages but only the
 * main interpreter can receive them.
 */

typedef struct ThreadSpecificData {
    Tcl_ThreadId  threadId;          /* Tcl ID for this thread */
    Tcl_Interp *interp;              /* Main interpreter for this thread */
    int flags;                       /* See the TP_ defines below... */
    struct ThreadSpecificData *nextPtr;	/* List for "thread names" */
    struct ThreadSpecificData *prevPtr;	/* List for "thread names" */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * This list is used to list all threads that have interpreters.
 * This is protected by threadMutex.
 */

static struct ThreadSpecificData *threadList;

/*
 * The following bit-values are legal for the "flags" field of the
 * ThreadSpecificData structure.
 */
#define TP_Dying               0x001 /* This thread is being cancelled */

/*
 * An instance of the following structure contains all information that is
 * passed into a new thread when the thread is created using either the
 * "thread create" Tcl command or the TclCreateThread() C function.
 */

typedef struct ThreadCtrl {
    char *script;    /* The TCL command this thread should execute */
    int flags;        /* Initial value of the "flags" field in the 
                       * ThreadSpecificData structure for the new thread.
                       * Might contain TP_Detached or TP_TclThread. */
    Tcl_Condition condWait;
    /* This condition variable is used to synchronize
     * the parent and child threads.  The child won't run
     * until it acquires threadMutex, and the parent function
     * won't complete until signaled on this condition
     * variable. */
} ThreadCtrl;

/*
 * This is the event used to send scripts to other threads.
 */

typedef struct ThreadEvent {
    Tcl_Event event;		/* Must be first */
    char *script;		/* The script to execute. */
    struct ThreadEventResult *resultPtr;
				/* To communicate the result.  This is
				 * NULL if we don't care about it. */
} ThreadEvent;

typedef struct ThreadEventResult {
    Tcl_Condition done;		/* Signaled when the script completes */
    int code;			/* Return value of Tcl_Eval */
    char *result;		/* Result from the script */
    char *errorInfo;		/* Copy of errorInfo variable */
    char *errorCode;		/* Copy of errorCode variable */
    Tcl_ThreadId srcThreadId;	/* Id of sending thread, in case it dies */
    Tcl_ThreadId dstThreadId;	/* Id of target thread, in case it dies */
    struct ThreadEvent *eventPtr;	/* Back pointer */
    struct ThreadEventResult *nextPtr;	/* List for cleanup */
    struct ThreadEventResult *prevPtr;

} ThreadEventResult;

static ThreadEventResult *resultList;

/*
 * This is for simple error handling when a thread script exits badly.
 */

static Tcl_ThreadId errorThreadId;
static char *errorProcString;

/* 
 * Access to the list of threads and to the thread send results is
 * guarded by this mutex. 
 */

TCL_DECLARE_MUTEX(threadMutex)

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT

EXTERN int	TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int	Tcl_ThreadObjCmd _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
EXTERN int	TclCreateThread _ANSI_ARGS_((Tcl_Interp *interp,
	CONST char *script));
EXTERN int	TclThreadList _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int	TclThreadSend _ANSI_ARGS_((Tcl_Interp *interp, Tcl_ThreadId id,
	char *script, int wait));

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#ifdef MAC_TCL
static pascal void *NewThread _ANSI_ARGS_((ClientData clientData));
#else
static void     NewThread _ANSI_ARGS_((ClientData clientData));
#endif
static void	ListRemove _ANSI_ARGS_((ThreadSpecificData *tsdPtr));
static void	ListUpdateInner _ANSI_ARGS_((ThreadSpecificData *tsdPtr));
static int	ThreadEventProc _ANSI_ARGS_((Tcl_Event *evPtr, int mask));
static void	ThreadErrorProc _ANSI_ARGS_((Tcl_Interp *interp));
static void	ThreadExitProc _ANSI_ARGS_((ClientData clientData));


/*
 *----------------------------------------------------------------------
 *
 * TclThread_Init --
 *
 *	Initialize the test thread command.
 *
 * Results:
 *      TCL_OK if the package was properly initialized.
 *
 * Side effects:
 *	Add the "testthread" command to the interp.
 *
 *----------------------------------------------------------------------
 */

int
TclThread_Init(interp)
    Tcl_Interp *interp; /* The current Tcl interpreter */
{
    
    Tcl_CreateObjCommand(interp,"testthread", Tcl_ThreadObjCmd, 
	    (ClientData)NULL ,NULL);
    if (Tcl_PkgProvide(interp, "Thread", "1.0" ) != TCL_OK) {
	return TCL_ERROR;
    }
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_ThreadObjCmd --
 *
 *	This procedure is invoked to process the "testthread" Tcl command.
 *	See the user documentation for details on what it does.
 *
 *	thread create
 *	thread send id ?-async? script
 *	thread exit
 *	thread info id
 *	thread names
 *	thread wait
 *	thread errorproc proc
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_ThreadObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    int option;
    static char *threadOptions[] = {"create", "exit", "id", "names",
				    "send", "wait", "errorproc", (char *) NULL};
    enum options {THREAD_CREATE, THREAD_EXIT, THREAD_ID, THREAD_NAMES,
		  THREAD_SEND, THREAD_WAIT, THREAD_ERRORPROC};

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], threadOptions,
	    "option", 0, &option) != TCL_OK) {
	return TCL_ERROR;
    }

    /* 
     * Make sure the initial thread is on the list before doing anything.
     */

    if (tsdPtr->interp == NULL) {
	Tcl_MutexLock(&threadMutex);
	tsdPtr->interp = interp;
	ListUpdateInner(tsdPtr);
	Tcl_CreateThreadExitHandler(ThreadExitProc, NULL);
	Tcl_MutexUnlock(&threadMutex);
    }

    switch ((enum options)option) {
	case THREAD_CREATE: {
	    char *script;
	    if (objc == 2) {
		script = "testthread wait";	/* Just enter the event loop */
	    } else if (objc == 3) {
		script = Tcl_GetString(objv[2]);
	    } else {
		Tcl_WrongNumArgs(interp, 2, objv, "?script?");
		return TCL_ERROR;
	    }
	    return TclCreateThread(interp, script);
	}
	case THREAD_EXIT: {
	    if (objc > 2) {
		Tcl_WrongNumArgs(interp, 1, objv, NULL);
		return TCL_ERROR;
	    }
	    ListRemove(NULL);
	    Tcl_ExitThread(0);
	    return TCL_OK;
	}
	case THREAD_ID:
	    if (objc == 2) {
		Tcl_Obj *idObj = Tcl_NewIntObj((int)Tcl_GetCurrentThread());
		Tcl_SetObjResult(interp, idObj);
		return TCL_OK;
	    } else {
		Tcl_WrongNumArgs(interp, 2, objv, NULL);
		return TCL_ERROR;
	    }
	case THREAD_NAMES: {
	    if (objc > 2) {
		Tcl_WrongNumArgs(interp, 2, objv, NULL);
		return TCL_ERROR;
	    }
	    return TclThreadList(interp);
	}
	case THREAD_SEND: {
	    int id;
	    char *script;
	    int wait, arg;

	    if ((objc != 4) && (objc != 5)) {
		Tcl_WrongNumArgs(interp, 1, objv, "send ?-async? id script");
		return TCL_ERROR;
	    }
	    if (objc == 5) {
		if (strcmp("-async", Tcl_GetString(objv[2])) != 0) {
		    Tcl_WrongNumArgs(interp, 1, objv, "send ?-async? id script");
		    return TCL_ERROR;
		}
		wait = 0;
		arg = 3;
	    } else {
		wait = 1;
		arg = 2;
	    }
	    if (Tcl_GetIntFromObj(interp, objv[arg], &id) != TCL_OK) {
		return TCL_ERROR;
	    }
	    arg++;
	    script = Tcl_GetString(objv[arg]);
	    return TclThreadSend(interp, (Tcl_ThreadId) id, script, wait);
	}
	case THREAD_WAIT: {
	    while (1) {
		(void) Tcl_DoOneEvent(TCL_ALL_EVENTS);
	    }
	}
	case THREAD_ERRORPROC: {
	    /*
	     * Arrange for this proc to handle thread death errors.
	     */

	    char *proc;
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 1, objv, "errorproc proc");
		return TCL_ERROR;
	    }
	    Tcl_MutexLock(&threadMutex);
	    errorThreadId = Tcl_GetCurrentThread();
	    if (errorProcString) {
		ckfree(errorProcString);
	    }
	    proc = Tcl_GetString(objv[2]);
	    errorProcString = ckalloc(strlen(proc)+1);
	    strcpy(errorProcString, proc);
	    Tcl_MutexUnlock(&threadMutex);
	    return TCL_OK;
	}
    }
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * TclCreateThread --
 *
 *	This procedure is invoked to create a thread containing an interp to
 *	run a script.  This returns after the thread has started executing.
 *
 * Results:
 *	A standard Tcl result, which is the thread ID.
 *
 * Side effects:
 *	Create a thread.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
TclCreateThread(interp, script)
    Tcl_Interp *interp;			/* Current interpreter. */
    CONST char *script;			/* Script to execute */
{
    ThreadCtrl ctrl;
    Tcl_ThreadId id;

    ctrl.script = (char*)ckalloc( strlen(script) + 1 );
    strcpy(ctrl.script, script);
    ctrl.condWait = NULL;
    ctrl.flags = 0;

    Tcl_MutexLock(&threadMutex);
    if (TclpThreadCreate(&id, NewThread, (ClientData) &ctrl) != TCL_OK) {
	Tcl_MutexUnlock(&threadMutex);
        Tcl_AppendResult(interp,"can't create a new thread",0);
	ckfree((void*)ctrl.script);
	return TCL_ERROR;
    }

    /*
     * Wait for the thread to start because it is using something on our stack!
     */

    Tcl_ConditionWait(&ctrl.condWait, &threadMutex, NULL);
    Tcl_MutexUnlock(&threadMutex);
    TclFinalizeCondition(&ctrl.condWait);
    Tcl_SetObjResult(interp, Tcl_NewIntObj((int)id));
    return TCL_OK;
}

/*
 *------------------------------------------------------------------------
 *
 * NewThread --
 *
 *    This routine is the "main()" for a new thread whose task is to
 *    execute a single TCL script.  The argument to this function is
 *    a pointer to a structure that contains the text of the TCL script
 *    to be executed.
 *
 *    Space to hold the script field of the ThreadControl structure passed 
 *    in as the only argument was obtained from malloc() and must be freed 
 *    by this function before it exits.  Space to hold the ThreadControl
 *    structure itself is released by the calling function, and the
 *    two condition variables in the ThreadControl structure are destroyed
 *    by the calling function.  The calling function will destroy the
 *    ThreadControl structure and the condition variable as soon as
 *    ctrlPtr->condWait is signaled, so this routine must make copies of
 *    any data it might need after that point.
 *
 * Results:
 *    none
 *
 * Side effects:
 *    A TCL script is executed in a new thread.
 *
 *------------------------------------------------------------------------
 */
#ifdef MAC_TCL
static pascal void *
#else
static void
#endif
NewThread(clientData)
    ClientData clientData;
{
    ThreadCtrl *ctrlPtr = (ThreadCtrl*)clientData;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    ThreadCtrl ctrl;
    int result;

    ctrl = *ctrlPtr;

    /*
     * Initialize the interpreter.  This should be more general.
     */

    tsdPtr->interp = Tcl_CreateInterp();
    result = Tcl_Init(tsdPtr->interp);
    result = TclThread_Init(tsdPtr->interp);

    /*
     * Update the list of threads.
     */

    Tcl_MutexLock(&threadMutex);
    ListUpdateInner(tsdPtr);
    Tcl_CreateThreadExitHandler(ThreadExitProc, NULL);

    /*
     * Notify the parent we are alive.
     */

    Tcl_ConditionNotify(&ctrlPtr->condWait);
    Tcl_MutexUnlock(&threadMutex);

    /*
     * Run the script.
     */

    Tcl_Preserve((ClientData) tsdPtr->interp);
    result = Tcl_Eval(tsdPtr->interp, ctrl.script);
    if (result != TCL_OK) {
	ThreadErrorProc(tsdPtr->interp);
    }

    /*
     * Clean up.
     */

    ListRemove(tsdPtr);
    ckfree((char*)ctrl.script);
    Tcl_Release((ClientData) tsdPtr->interp);
    Tcl_DeleteInterp(tsdPtr->interp);
    Tcl_ExitThread(result);
#ifdef MAC_TCL
    return NULL;
#endif
}

/*
 *------------------------------------------------------------------------
 *
 * ThreadErrorProc --
 *
 *    Send a message to the thread willing to hear about errors.
 *
 * Results:
 *    none
 *
 * Side effects:
 *    Send an event.
 *
 *------------------------------------------------------------------------
 */
static void
ThreadErrorProc(interp)
    Tcl_Interp *interp;		/* Interp that failed */
{
    Tcl_Channel errChannel;
    char *errorInfo, *script;
    char *argv[3];
    char buf[10];
    sprintf(buf, "%ld", (long) Tcl_GetCurrentThread());

    errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
    if (errorProcString == NULL) {
	errChannel = Tcl_GetStdChannel(TCL_STDERR);
	Tcl_WriteChars(errChannel, "Error from thread ", -1);
	Tcl_WriteChars(errChannel, buf, -1);
	Tcl_WriteChars(errChannel, "\n", 1);
	Tcl_WriteChars(errChannel, errorInfo, -1);
	Tcl_WriteChars(errChannel, "\n", 1);
    } else {
	argv[0] = errorProcString;
	argv[1] = buf;
	argv[2] = errorInfo;
	script = Tcl_Merge(3, argv);
	TclThreadSend(interp, errorThreadId, script, 0);
	ckfree(script);
    }
}


/*
 *------------------------------------------------------------------------
 *
 * ListUpdateInner --
 *
 *    Add the thread local storage to the list.  This assumes
 *	the caller has obtained the mutex.
 *
 * Results:
 *    none
 *
 * Side effects:
 *    Add the thread local storage to its list.
 *
 *------------------------------------------------------------------------
 */
static void
ListUpdateInner(tsdPtr)
    ThreadSpecificData *tsdPtr;
{
    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
    }
    tsdPtr->threadId = Tcl_GetCurrentThread();
    tsdPtr->nextPtr = threadList;
    if (threadList) {
	threadList->prevPtr = tsdPtr;
    }
    tsdPtr->prevPtr = NULL;
    threadList = tsdPtr;
}

/*
 *------------------------------------------------------------------------
 *
 * ListRemove --
 *
 *    Remove the thread local storage from its list.  This grabs the
 *	mutex to protect the list.
 *
 * Results:
 *    none
 *
 * Side effects:
 *    Remove the thread local storage from its list.
 *
 *------------------------------------------------------------------------
 */
static void
ListRemove(tsdPtr)
    ThreadSpecificData *tsdPtr;
{
    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
    }
    Tcl_MutexLock(&threadMutex);
    if (tsdPtr->prevPtr) {
	tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
    } else {
	threadList = tsdPtr->nextPtr;
    }
    if (tsdPtr->nextPtr) {
	tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
    }
    tsdPtr->nextPtr = tsdPtr->prevPtr = 0;
    Tcl_MutexUnlock(&threadMutex);
}


/*
 *------------------------------------------------------------------------
 *
 * TclThreadList --
 *
 *    Return a list of threads running Tcl interpreters.
 *
 * Results:
 *    A standard Tcl result.
 *
 * Side effects:
 *    None.
 *
 *------------------------------------------------------------------------
 */
int
TclThreadList(interp)
    Tcl_Interp *interp;
{
    ThreadSpecificData *tsdPtr;
    Tcl_Obj *listPtr;

    listPtr = Tcl_NewListObj(0, NULL);
    Tcl_MutexLock(&threadMutex);
    for (tsdPtr = threadList ; tsdPtr ; tsdPtr = tsdPtr->nextPtr) {
	Tcl_ListObjAppendElement(interp, listPtr,
		Tcl_NewIntObj((int)tsdPtr->threadId));
    }
    Tcl_MutexUnlock(&threadMutex);
    Tcl_SetObjResult(interp, listPtr);
    return TCL_OK;
}


/*
 *------------------------------------------------------------------------
 *
 * TclThreadSend --
 *
 *    Send a script to another thread.
 *
 * Results:
 *    A standard Tcl result.
 *
 * Side effects:
 *    None.
 *
 *------------------------------------------------------------------------
 */
int
TclThreadSend(interp, id, script, wait)
    Tcl_Interp *interp;		/* The current interpreter. */
    Tcl_ThreadId id;		/* Thread Id of other interpreter. */
    char *script;		/* The script to evaluate. */
    int wait;			/* If 1, we block for the result. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    ThreadEvent *threadEventPtr;
    ThreadEventResult *resultPtr;
    int found, code;
    Tcl_ThreadId threadId = (Tcl_ThreadId) id;

    /* 
     * Verify the thread exists.
     */

    Tcl_MutexLock(&threadMutex);
    found = 0;
    for (tsdPtr = threadList ; tsdPtr ; tsdPtr = tsdPtr->nextPtr) {
	if (tsdPtr->threadId == threadId) {
	    found = 1;
	    break;
	}
    }
    if (!found) {
	Tcl_MutexUnlock(&threadMutex);
	Tcl_AppendResult(interp, "invalid thread id", NULL);
	return TCL_ERROR;
    }

    /*
     * Short circut sends to ourself.  Ought to do something with -async,
     * like run in an idle handler.
     */

    if (threadId == Tcl_GetCurrentThread()) {
        Tcl_MutexUnlock(&threadMutex);
	return Tcl_GlobalEval(interp, script);
    }

    /* 
     * Create the event for its event queue.
     */

    threadEventPtr = (ThreadEvent *) ckalloc(sizeof(ThreadEvent));
    threadEventPtr->script = ckalloc(strlen(script) + 1);
    strcpy(threadEventPtr->script, script);
    if (!wait) {
	threadEventPtr->resultPtr = NULL;
    } else {
	resultPtr = (ThreadEventResult *) ckalloc(sizeof(ThreadEventResult));
	threadEventPtr->resultPtr = resultPtr;

	/*
	 * Initialize the result fields.
	 */

	resultPtr->done = NULL;
	resultPtr->code = 0;
	resultPtr->result = NULL;
	resultPtr->errorInfo = NULL;
	resultPtr->errorCode = NULL;

	/* 
	 * Maintain the cleanup list.
	 */

	resultPtr->srcThreadId = Tcl_GetCurrentThread();
	resultPtr->dstThreadId = threadId;
	resultPtr->eventPtr = threadEventPtr;
	resultPtr->nextPtr = resultList;
	if (resultList) {
	    resultList->prevPtr = resultPtr;
	}
	resultPtr->prevPtr = NULL;
	resultList = resultPtr;
    }

    /*
     * Queue the event and poke the other thread's notifier.
     */

    threadEventPtr->event.proc = ThreadEventProc;
    Tcl_ThreadQueueEvent(threadId, (Tcl_Event *)threadEventPtr, 
	    TCL_QUEUE_TAIL);
    Tcl_MutexUnlock(&threadMutex);
    Tcl_ThreadAlert(threadId);

    if (!wait) {
	return TCL_OK;
    }

    /* 
     * Block on the results and then get them.
     */

    Tcl_ResetResult(interp);
    Tcl_MutexLock(&threadMutex);
    while (resultPtr->result == NULL) {
        Tcl_ConditionWait(&resultPtr->done, &threadMutex, NULL);
    }

    /*
     * Unlink result from the result list.
     */

    if (resultPtr->prevPtr) {
	resultPtr->prevPtr->nextPtr = resultPtr->nextPtr;
    } else {
	resultList = resultPtr->nextPtr;
    }
    if (resultPtr->nextPtr) {
	resultPtr->nextPtr->prevPtr = resultPtr->prevPtr;
    }
    resultPtr->eventPtr = NULL;
    resultPtr->nextPtr = NULL;
    resultPtr->prevPtr = NULL;

    Tcl_MutexUnlock(&threadMutex);

    if (resultPtr->code != TCL_OK) {
	if (resultPtr->errorCode) {
	    Tcl_SetErrorCode(interp, resultPtr->errorCode, NULL);
	    ckfree(resultPtr->errorCode);
	}
	if (resultPtr->errorInfo) {
	    Tcl_AddErrorInfo(interp, resultPtr->errorInfo);
	    ckfree(resultPtr->errorInfo);
	}
    }
    Tcl_SetResult(interp, resultPtr->result, TCL_DYNAMIC);
    TclFinalizeCondition(&resultPtr->done);
    code = resultPtr->code;

    ckfree((char *) resultPtr);

    return code;
}


/*
 *------------------------------------------------------------------------
 *
 * ThreadEventProc --
 *
 *    Handle the event in the target thread.
 *
 * Results:
 *    Returns 1 to indicate that the event was processed.
 *
 * Side effects:
 *    Fills out the ThreadEventResult struct.
 *
 *------------------------------------------------------------------------
 */
int
ThreadEventProc(evPtr, mask)
    Tcl_Event *evPtr;		/* Really ThreadEvent */
    int mask;
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    ThreadEvent *threadEventPtr = (ThreadEvent *)evPtr;
    ThreadEventResult *resultPtr = threadEventPtr->resultPtr;
    Tcl_Interp *interp = tsdPtr->interp;
    int code;
    char *result, *errorCode, *errorInfo;

    if (interp == NULL) {
	code = TCL_ERROR;
	result = "no target interp!";
	errorCode = "THREAD";
	errorInfo = "";
    } else {
	Tcl_Preserve((ClientData) interp);
	Tcl_ResetResult(interp);
	code = Tcl_GlobalEval(interp, threadEventPtr->script);
	result = Tcl_GetStringResult(interp);
	if (code != TCL_OK) {
	    errorCode = Tcl_GetVar(interp, "errorCode", TCL_GLOBAL_ONLY);
	    errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
	} else {
	    errorCode = errorInfo = NULL;
	}
    }
    ckfree(threadEventPtr->script);
    if (resultPtr) {
	Tcl_MutexLock(&threadMutex);
	resultPtr->code = code;
	resultPtr->result = ckalloc(strlen(result) + 1);
	strcpy(resultPtr->result, result);
	if (errorCode != NULL) {
	    resultPtr->errorCode = ckalloc(strlen(errorCode) + 1);
	    strcpy(resultPtr->errorCode, errorCode);
	}
	if (errorInfo != NULL) {
	    resultPtr->errorInfo = ckalloc(strlen(errorInfo) + 1);
	    strcpy(resultPtr->errorInfo, errorInfo);
	}
	Tcl_ConditionNotify(&resultPtr->done);
	Tcl_MutexUnlock(&threadMutex);
    }
    if (interp != NULL) {
	Tcl_Release((ClientData) interp);
    }
    return 1;
}

/*
 *------------------------------------------------------------------------
 *
 * ThreadExitProc --
 *
 *    This is called when the thread exits.  
 *
 * Results:
 *    None.
 *
 * Side effects:
 *	It unblocks anyone that is waiting on a send to this thread.
 *	It cleans up any events in the event queue for this thread.
 *
 *------------------------------------------------------------------------
 */
     /* ARGSUSED */
void
ThreadExitProc(dummy)
    ClientData dummy;
{
    ThreadEventResult *resultPtr, *nextPtr;
    Tcl_ThreadId self = Tcl_GetCurrentThread();

    Tcl_MutexLock(&threadMutex);
    for (resultPtr = resultList ; resultPtr ; resultPtr = nextPtr) {
	nextPtr = resultPtr->nextPtr;
	if (resultPtr->srcThreadId == self) {
	    /*
	     * We are going away.  By freeing up the result we signal
	     * to the other thread we don't care about the result.
	     */
	    if (resultPtr->prevPtr) {
		resultPtr->prevPtr->nextPtr = resultPtr->nextPtr;
	    } else {
		resultList = resultPtr->nextPtr;
	    }
	    if (resultPtr->nextPtr) {
		resultPtr->nextPtr->prevPtr = resultPtr->prevPtr;
	    }
	    resultPtr->nextPtr = resultPtr->prevPtr = 0;
	    resultPtr->eventPtr->resultPtr = NULL;
	    ckfree((char *)resultPtr);
	} else if (resultPtr->dstThreadId == self) {
	    /*
	     * Dang.  The target is going away.  Unblock the caller.
	     * The result string must be dynamically allocated because
	     * the main thread is going to call free on it.
	     */

	    char *msg = "target thread died";
	    resultPtr->result = ckalloc(strlen(msg)+1);
	    strcpy(resultPtr->result, msg);
	    resultPtr->code = TCL_ERROR;
	    Tcl_ConditionNotify(&resultPtr->done);
	}
    }
    Tcl_MutexUnlock(&threadMutex);
}

#endif /* TCL_THREADS */

Changes to generic/tclTimer.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
65
/* 
 * tclTimer.c --
 *
 *	This file provides timer event management facilities for Tcl,
 *	including the "after" command.
 *
 * 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.
 *
 * SCCS: @(#) tclTimer.c 1.9 97/07/29 16:21:53
 */

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

/*
 * This flag indicates whether this module has been initialized.
 */

static int initialized = 0;

/*
 * For each timer callback that's pending there is one record of the following
 * type.  The normal handlers (created by Tcl_CreateTimerHandler) are chained
 * together in a list sorted by time (earliest event first).
 */

typedef struct TimerHandler {
    Tcl_Time time;			/* When timer is to fire. */
    Tcl_TimerProc *proc;		/* Procedure to call. */
    ClientData clientData;		/* Argument to pass to proc. */
    Tcl_TimerToken token;		/* Identifies handler so it can be
					 * deleted. */
    struct TimerHandler *nextPtr;	/* Next event in queue, or NULL for
					 * end of queue. */
} TimerHandler;

static TimerHandler *firstTimerHandlerPtr = NULL;
					/* First event in queue. */
static int lastTimerId;			/* Timer identifier of most recently
					 * created timer. */
static int timerPending;		/* 1 if a timer event is in the queue. */

/*
 * The data structure below is used by the "after" command to remember
 * the command to be executed later.  All of the pending "after" commands
 * for an interpreter are linked together in a list.
 */

typedef struct AfterInfo {
    struct AfterAssocData *assocPtr;
				/* Pointer to the "tclAfter" assocData for
				 * the interp in which command will be
				 * executed. */
    char *command;		/* Command to execute.  Malloc'ed, so must
				 * be freed when structure is deallocated. */
    int id;			/* Integer identifier for command;  used to
				 * cancel it. */
    Tcl_TimerToken token;	/* Used to cancel the "after" command.  NULL
				 * means that the command is run as an
				 * idle handler rather than as a timer
				 * handler.  NULL means this is an "after
				 * idle" handler rather than a











|





<
<
<
<
<
<
















<
<
<
<
<
<











|
<







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
/* 
 * tclTimer.c --
 *
 *	This file provides timer event management facilities for Tcl,
 *	including the "after" command.
 *
 * 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: tclTimer.c,v 1.1.2.3 1999/02/01 21:29:56 stanton Exp $
 */

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







/*
 * For each timer callback that's pending there is one record of the following
 * type.  The normal handlers (created by Tcl_CreateTimerHandler) are chained
 * together in a list sorted by time (earliest event first).
 */

typedef struct TimerHandler {
    Tcl_Time time;			/* When timer is to fire. */
    Tcl_TimerProc *proc;		/* Procedure to call. */
    ClientData clientData;		/* Argument to pass to proc. */
    Tcl_TimerToken token;		/* Identifies handler so it can be
					 * deleted. */
    struct TimerHandler *nextPtr;	/* Next event in queue, or NULL for
					 * end of queue. */
} TimerHandler;







/*
 * The data structure below is used by the "after" command to remember
 * the command to be executed later.  All of the pending "after" commands
 * for an interpreter are linked together in a list.
 */

typedef struct AfterInfo {
    struct AfterAssocData *assocPtr;
				/* Pointer to the "tclAfter" assocData for
				 * the interp in which command will be
				 * executed. */
    Tcl_Obj *commandPtr;	/* Command to execute. */

    int id;			/* Integer identifier for command;  used to
				 * cancel it. */
    Tcl_TimerToken token;	/* Used to cancel the "after" command.  NULL
				 * means that the command is run as an
				 * idle handler rather than as a timer
				 * handler.  NULL means this is an "after
				 * idle" handler rather than a
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
    Tcl_IdleProc (*proc);	/* Procedure to call. */
    ClientData clientData;	/* Value to pass to proc. */
    int generation;		/* Used to distinguish older handlers from
				 * recently-created ones. */
    struct IdleHandler *nextPtr;/* Next in list of active handlers. */
} IdleHandler;












static IdleHandler *idleList;





				/* First in list of all idle handlers. */
static IdleHandler *lastIdlePtr;
				/* Last in list (or NULL for empty list). */
static int idleGeneration;	/* Used to fill in the "generation" fields
				 * of IdleHandler structures.  Increments
				 * each time Tcl_DoOneEvent starts calling
				 * idle handlers, so that all old handlers
				 * can be called without calling any of the
				 * new ones created by old ones. */





/*
 * Prototypes for procedures referenced only in this file:
 */

static void		AfterCleanupProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp));
static void		AfterProc _ANSI_ARGS_((ClientData clientData));
static void		FreeAfterPtr _ANSI_ARGS_((AfterInfo *afterPtr));
static AfterInfo *	GetAfterEvent _ANSI_ARGS_((AfterAssocData *assocPtr,
			    char *string));
static void		InitTimer _ANSI_ARGS_((void));
static void		TimerExitProc _ANSI_ARGS_((ClientData clientData));
static int		TimerHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
			    int flags));
static void		TimerCheckProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static void		TimerSetupProc _ANSI_ARGS_((ClientData clientData,
			    int flags));

/*
 *----------------------------------------------------------------------
 *
 * InitTimer --
 *
 *	This function initializes the timer module.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Registers the idle and timer event sources.
 *
 *----------------------------------------------------------------------
 */

static void
InitTimer()
{
    initialized = 1;
    lastTimerId = 0;
    timerPending = 0;
    idleGeneration = 0;
    firstTimerHandlerPtr = NULL;
    lastIdlePtr = NULL;
    idleList = NULL;




    Tcl_CreateEventSource(TimerSetupProc, TimerCheckProc, NULL);
    Tcl_CreateExitHandler(TimerExitProc, NULL);


}

/*
 *----------------------------------------------------------------------
 *
 * TimerExitProc --
 *







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





>
>
>
>










|
|
















|







|


<
<
<
<
<
|
<
>

>
>
|
|
>
>







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
    Tcl_IdleProc (*proc);	/* Procedure to call. */
    ClientData clientData;	/* Value to pass to proc. */
    int generation;		/* Used to distinguish older handlers from
				 * recently-created ones. */
    struct IdleHandler *nextPtr;/* Next in list of active handlers. */
} IdleHandler;

/*
 * The timer and idle queues are per-thread because they are associated
 * with the notifier, which is also per-thread.
 *
 * All static variables used in this file are collected into a single
 * instance of the following structure.  For multi-threaded implementations,
 * there is one instance of this structure for each thread.
 *
 * Notice that different structures with the same name appear in other
 * files.  The structure defined below is used in this file only.
 */

typedef struct ThreadSpecificData {
    TimerHandler *firstTimerHandlerPtr;	/* First event in queue. */
    int lastTimerId;		/* Timer identifier of most recently
				 * created timer. */
    int timerPending;		/* 1 if a timer event is in the queue. */
    IdleHandler *idleList;	/* First in list of all idle handlers. */

    IdleHandler *lastIdlePtr;	/* Last in list (or NULL for empty list). */
    int idleGeneration;		/* Used to fill in the "generation" fields
				 * of IdleHandler structures.  Increments
				 * each time Tcl_DoOneEvent starts calling
				 * idle handlers, so that all old handlers
				 * can be called without calling any of the
				 * new ones created by old ones. */
    int afterId;		/* For unique identifiers of after events. */
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for procedures referenced only in this file:
 */

static void		AfterCleanupProc _ANSI_ARGS_((ClientData clientData,
			    Tcl_Interp *interp));
static void		AfterProc _ANSI_ARGS_((ClientData clientData));
static void		FreeAfterPtr _ANSI_ARGS_((AfterInfo *afterPtr));
static AfterInfo *	GetAfterEvent _ANSI_ARGS_((AfterAssocData *assocPtr,
			    Tcl_Obj *commandPtr));
static ThreadSpecificData *InitTimer _ANSI_ARGS_((void));
static void		TimerExitProc _ANSI_ARGS_((ClientData clientData));
static int		TimerHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
			    int flags));
static void		TimerCheckProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static void		TimerSetupProc _ANSI_ARGS_((ClientData clientData,
			    int flags));

/*
 *----------------------------------------------------------------------
 *
 * InitTimer --
 *
 *	This function initializes the timer module.
 *
 * Results:
 *	A pointer to the thread specific data.
 *
 * Side effects:
 *	Registers the idle and timer event sources.
 *
 *----------------------------------------------------------------------
 */

static ThreadSpecificData *
InitTimer()
{





    ThreadSpecificData *tsdPtr = 

	(ThreadSpecificData *) TclThreadDataKeyGet(&dataKey);

    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
	Tcl_CreateEventSource(TimerSetupProc, TimerCheckProc, NULL);
	Tcl_CreateThreadExitHandler(TimerExitProc, NULL);
    }
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TimerExitProc --
 *
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
 */

static void
TimerExitProc(clientData)
    ClientData clientData;	/* Not used. */
{
    Tcl_DeleteEventSource(TimerSetupProc, TimerCheckProc, NULL);
    initialized = 0;
}

/*
 *--------------------------------------------------------------
 *
 * Tcl_CreateTimerHandler --
 *







<







180
181
182
183
184
185
186

187
188
189
190
191
192
193
 */

static void
TimerExitProc(clientData)
    ClientData clientData;	/* Not used. */
{
    Tcl_DeleteEventSource(TimerSetupProc, TimerCheckProc, NULL);

}

/*
 *--------------------------------------------------------------
 *
 * Tcl_CreateTimerHandler --
 *
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
    int milliseconds;		/* How many milliseconds to wait
				 * before invoking proc. */
    Tcl_TimerProc *proc;	/* Procedure to invoke. */
    ClientData clientData;	/* Arbitrary data to pass to proc. */
{
    register TimerHandler *timerHandlerPtr, *tPtr2, *prevPtr;
    Tcl_Time time;


    if (!initialized) {
	InitTimer();
    }

    timerHandlerPtr = (TimerHandler *) ckalloc(sizeof(TimerHandler));

    /*
     * Compute when the event should fire.
     */

    TclpGetTime(&time);
    timerHandlerPtr->time.sec = time.sec + milliseconds/1000;
    timerHandlerPtr->time.usec = time.usec + (milliseconds%1000)*1000;
    if (timerHandlerPtr->time.usec >= 1000000) {
	timerHandlerPtr->time.usec -= 1000000;
	timerHandlerPtr->time.sec += 1;
    }
    
    /*
     * Fill in other fields for the event.
     */

    timerHandlerPtr->proc = proc;
    timerHandlerPtr->clientData = clientData;
    lastTimerId++;
    timerHandlerPtr->token = (Tcl_TimerToken) lastTimerId;

    /*
     * Add the event to the queue in the correct position
     * (ordered by event firing time).
     */

    for (tPtr2 = firstTimerHandlerPtr, prevPtr = NULL; tPtr2 != NULL;
	    prevPtr = tPtr2, tPtr2 = tPtr2->nextPtr) {
	if ((tPtr2->time.sec > timerHandlerPtr->time.sec)
		|| ((tPtr2->time.sec == timerHandlerPtr->time.sec)
		&& (tPtr2->time.usec > timerHandlerPtr->time.usec))) {
	    break;
	}
    }
    timerHandlerPtr->nextPtr = tPtr2;
    if (prevPtr == NULL) {
	firstTimerHandlerPtr = timerHandlerPtr;
    } else {
	prevPtr->nextPtr = timerHandlerPtr;
    }

    TimerSetupProc(NULL, TCL_ALL_EVENTS);

    return timerHandlerPtr->token;
}

/*
 *--------------------------------------------------------------
 *
 * Tcl_DeleteTimerHandler --







>

<
|
<














|






|
|






|









|





>







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
    int milliseconds;		/* How many milliseconds to wait
				 * before invoking proc. */
    Tcl_TimerProc *proc;	/* Procedure to invoke. */
    ClientData clientData;	/* Arbitrary data to pass to proc. */
{
    register TimerHandler *timerHandlerPtr, *tPtr2, *prevPtr;
    Tcl_Time time;
    ThreadSpecificData *tsdPtr;


    tsdPtr = InitTimer();


    timerHandlerPtr = (TimerHandler *) ckalloc(sizeof(TimerHandler));

    /*
     * Compute when the event should fire.
     */

    TclpGetTime(&time);
    timerHandlerPtr->time.sec = time.sec + milliseconds/1000;
    timerHandlerPtr->time.usec = time.usec + (milliseconds%1000)*1000;
    if (timerHandlerPtr->time.usec >= 1000000) {
	timerHandlerPtr->time.usec -= 1000000;
	timerHandlerPtr->time.sec += 1;
    }

    /*
     * Fill in other fields for the event.
     */

    timerHandlerPtr->proc = proc;
    timerHandlerPtr->clientData = clientData;
    tsdPtr->lastTimerId++;
    timerHandlerPtr->token = (Tcl_TimerToken) tsdPtr->lastTimerId;

    /*
     * Add the event to the queue in the correct position
     * (ordered by event firing time).
     */

    for (tPtr2 = tsdPtr->firstTimerHandlerPtr, prevPtr = NULL; tPtr2 != NULL;
	    prevPtr = tPtr2, tPtr2 = tPtr2->nextPtr) {
	if ((tPtr2->time.sec > timerHandlerPtr->time.sec)
		|| ((tPtr2->time.sec == timerHandlerPtr->time.sec)
		&& (tPtr2->time.usec > timerHandlerPtr->time.usec))) {
	    break;
	}
    }
    timerHandlerPtr->nextPtr = tPtr2;
    if (prevPtr == NULL) {
	tsdPtr->firstTimerHandlerPtr = timerHandlerPtr;
    } else {
	prevPtr->nextPtr = timerHandlerPtr;
    }

    TimerSetupProc(NULL, TCL_ALL_EVENTS);

    return timerHandlerPtr->token;
}

/*
 *--------------------------------------------------------------
 *
 * Tcl_DeleteTimerHandler --
283
284
285
286
287
288
289

290

291
292
293
294
295
296
297
298
299
300
301
302
303
304
305

void
Tcl_DeleteTimerHandler(token)
    Tcl_TimerToken token;	/* Result previously returned by
				 * Tcl_DeleteTimerHandler. */
{
    register TimerHandler *timerHandlerPtr, *prevPtr;



    for (timerHandlerPtr = firstTimerHandlerPtr, prevPtr = NULL;
	    timerHandlerPtr != NULL; prevPtr = timerHandlerPtr,
	    timerHandlerPtr = timerHandlerPtr->nextPtr) {
	if (timerHandlerPtr->token != token) {
	    continue;
	}
	if (prevPtr == NULL) {
	    firstTimerHandlerPtr = timerHandlerPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = timerHandlerPtr->nextPtr;
	}
	ckfree((char *) timerHandlerPtr);
	return;
    }
}







>

>
|






|







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

void
Tcl_DeleteTimerHandler(token)
    Tcl_TimerToken token;	/* Result previously returned by
				 * Tcl_DeleteTimerHandler. */
{
    register TimerHandler *timerHandlerPtr, *prevPtr;
    ThreadSpecificData *tsdPtr;

    tsdPtr = InitTimer();
    for (timerHandlerPtr = tsdPtr->firstTimerHandlerPtr, prevPtr = NULL;
	    timerHandlerPtr != NULL; prevPtr = timerHandlerPtr,
	    timerHandlerPtr = timerHandlerPtr->nextPtr) {
	if (timerHandlerPtr->token != token) {
	    continue;
	}
	if (prevPtr == NULL) {
	    tsdPtr->firstTimerHandlerPtr = timerHandlerPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = timerHandlerPtr->nextPtr;
	}
	ckfree((char *) timerHandlerPtr);
	return;
    }
}
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

static void
TimerSetupProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    Tcl_Time blockTime;


    if (((flags & TCL_IDLE_EVENTS) && idleList)
	    || ((flags & TCL_TIMER_EVENTS) && timerPending)) {
	/*
	 * There is an idle handler or a pending timer event, so just poll.
	 */

	blockTime.sec = 0;
	blockTime.usec = 0;

    } else if ((flags & TCL_TIMER_EVENTS) && firstTimerHandlerPtr) {
	/*
	 * Compute the timeout for the next timer on the list.
	 */

	TclpGetTime(&blockTime);
	blockTime.sec = firstTimerHandlerPtr->time.sec - blockTime.sec;
	blockTime.usec = firstTimerHandlerPtr->time.usec - blockTime.usec;

	if (blockTime.usec < 0) {
	    blockTime.sec -= 1;
	    blockTime.usec += 1000000;
	}
	if (blockTime.sec < 0) {
	    blockTime.sec = 0;
	    blockTime.usec = 0;







>

|
|







|





|
|
>







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

static void
TimerSetupProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    Tcl_Time blockTime;
    ThreadSpecificData *tsdPtr = InitTimer();

    if (((flags & TCL_IDLE_EVENTS) && tsdPtr->idleList)
	    || ((flags & TCL_TIMER_EVENTS) && tsdPtr->timerPending)) {
	/*
	 * There is an idle handler or a pending timer event, so just poll.
	 */

	blockTime.sec = 0;
	blockTime.usec = 0;

    } else if ((flags & TCL_TIMER_EVENTS) && tsdPtr->firstTimerHandlerPtr) {
	/*
	 * Compute the timeout for the next timer on the list.
	 */

	TclpGetTime(&blockTime);
	blockTime.sec = tsdPtr->firstTimerHandlerPtr->time.sec - blockTime.sec;
	blockTime.usec = tsdPtr->firstTimerHandlerPtr->time.usec -
		blockTime.usec;
	if (blockTime.usec < 0) {
	    blockTime.sec -= 1;
	    blockTime.usec += 1000000;
	}
	if (blockTime.sec < 0) {
	    blockTime.sec = 0;
	    blockTime.usec = 0;
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
static void
TimerCheckProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    Tcl_Event *timerEvPtr;
    Tcl_Time blockTime;


    if ((flags & TCL_TIMER_EVENTS) && firstTimerHandlerPtr) {
	/*
	 * Compute the timeout for the next timer on the list.
	 */

	TclpGetTime(&blockTime);
	blockTime.sec = firstTimerHandlerPtr->time.sec - blockTime.sec;
	blockTime.usec = firstTimerHandlerPtr->time.usec - blockTime.usec;

	if (blockTime.usec < 0) {
	    blockTime.sec -= 1;
	    blockTime.usec += 1000000;
	}
	if (blockTime.sec < 0) {
	    blockTime.sec = 0;
	    blockTime.usec = 0;
	}

	/*
	 * If the first timer has expired, stick an event on the queue.
	 */

	if (blockTime.sec == 0 && blockTime.usec == 0 && !timerPending) {

	    timerPending = 1;
	    timerEvPtr = (Tcl_Event *) ckalloc(sizeof(Tcl_Event));
	    timerEvPtr->proc = TimerHandlerEventProc;
	    Tcl_QueueEvent(timerEvPtr, TCL_QUEUE_TAIL);
	}
    }
}








>

|





|
|
>













|
>
|







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
static void
TimerCheckProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    Tcl_Event *timerEvPtr;
    Tcl_Time blockTime;
    ThreadSpecificData *tsdPtr = InitTimer();

    if ((flags & TCL_TIMER_EVENTS) && tsdPtr->firstTimerHandlerPtr) {
	/*
	 * Compute the timeout for the next timer on the list.
	 */

	TclpGetTime(&blockTime);
	blockTime.sec = tsdPtr->firstTimerHandlerPtr->time.sec - blockTime.sec;
	blockTime.usec = tsdPtr->firstTimerHandlerPtr->time.usec -
		blockTime.usec;
	if (blockTime.usec < 0) {
	    blockTime.sec -= 1;
	    blockTime.usec += 1000000;
	}
	if (blockTime.sec < 0) {
	    blockTime.sec = 0;
	    blockTime.usec = 0;
	}

	/*
	 * If the first timer has expired, stick an event on the queue.
	 */

	if (blockTime.sec == 0 && blockTime.usec == 0 &&
		!tsdPtr->timerPending) {
	    tsdPtr->timerPending = 1;
	    timerEvPtr = (Tcl_Event *) ckalloc(sizeof(Tcl_Event));
	    timerEvPtr->proc = TimerHandlerEventProc;
	    Tcl_QueueEvent(timerEvPtr, TCL_QUEUE_TAIL);
	}
    }
}

444
445
446
447
448
449
450

451
452
453
454
455
456
457
    Tcl_Event *evPtr;		/* Event to service. */
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    TimerHandler *timerHandlerPtr, **nextPtrPtr;
    Tcl_Time time;
    int currentTimerId;


    /*
     * Do nothing if timers aren't enabled.  This leaves the event on the
     * queue, so we will get to it as soon as ServiceEvents() is called
     * with timers enabled.
     */








>







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
    Tcl_Event *evPtr;		/* Event to service. */
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    TimerHandler *timerHandlerPtr, **nextPtrPtr;
    Tcl_Time time;
    int currentTimerId;
    ThreadSpecificData *tsdPtr = InitTimer();

    /*
     * Do nothing if timers aren't enabled.  This leaves the event on the
     * queue, so we will get to it as soon as ServiceEvents() is called
     * with timers enabled.
     */

482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
     *	  a course granularity clock.  Since timers are placed
     *	  on the queue in time order with the most recently created
     *    handler appearing after earlier ones with the same expiration
     *	  time, we don't have to worry about newer generation timers
     *	  appearing before later ones.
     */

    timerPending = 0;
    currentTimerId = lastTimerId;
    TclpGetTime(&time);
    while (1) {
	nextPtrPtr = &firstTimerHandlerPtr;
	timerHandlerPtr = firstTimerHandlerPtr;
	if (timerHandlerPtr == NULL) {
	    break;
	}
	    
	if ((timerHandlerPtr->time.sec > time.sec)
		|| ((timerHandlerPtr->time.sec == time.sec)
			&& (timerHandlerPtr->time.usec > time.usec))) {







|
|


|
|







494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
     *	  a course granularity clock.  Since timers are placed
     *	  on the queue in time order with the most recently created
     *    handler appearing after earlier ones with the same expiration
     *	  time, we don't have to worry about newer generation timers
     *	  appearing before later ones.
     */

    tsdPtr->timerPending = 0;
    currentTimerId = tsdPtr->lastTimerId;
    TclpGetTime(&time);
    while (1) {
	nextPtrPtr = &tsdPtr->firstTimerHandlerPtr;
	timerHandlerPtr = tsdPtr->firstTimerHandlerPtr;
	if (timerHandlerPtr == NULL) {
	    break;
	}
	    
	if ((timerHandlerPtr->time.sec > time.sec)
		|| ((timerHandlerPtr->time.sec == time.sec)
			&& (timerHandlerPtr->time.usec > time.usec))) {
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
void
Tcl_DoWhenIdle(proc, clientData)
    Tcl_IdleProc *proc;		/* Procedure to invoke. */
    ClientData clientData;	/* Arbitrary value to pass to proc. */
{
    register IdleHandler *idlePtr;
    Tcl_Time blockTime;

    if (!initialized) {
	InitTimer();
    }

    idlePtr = (IdleHandler *) ckalloc(sizeof(IdleHandler));
    idlePtr->proc = proc;
    idlePtr->clientData = clientData;
    idlePtr->generation = idleGeneration;
    idlePtr->nextPtr = NULL;
    if (lastIdlePtr == NULL) {
	idleList = idlePtr;
    } else {
	lastIdlePtr->nextPtr = idlePtr;
    }
    lastIdlePtr = idlePtr;

    blockTime.sec = 0;
    blockTime.usec = 0;
    Tcl_SetMaxBlockTime(&blockTime);
}

/*







<
<
|
<




|

|
|

|

|







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
void
Tcl_DoWhenIdle(proc, clientData)
    Tcl_IdleProc *proc;		/* Procedure to invoke. */
    ClientData clientData;	/* Arbitrary value to pass to proc. */
{
    register IdleHandler *idlePtr;
    Tcl_Time blockTime;


    ThreadSpecificData *tsdPtr = InitTimer();


    idlePtr = (IdleHandler *) ckalloc(sizeof(IdleHandler));
    idlePtr->proc = proc;
    idlePtr->clientData = clientData;
    idlePtr->generation = tsdPtr->idleGeneration;
    idlePtr->nextPtr = NULL;
    if (tsdPtr->lastIdlePtr == NULL) {
	tsdPtr->idleList = idlePtr;
    } else {
	tsdPtr->lastIdlePtr->nextPtr = idlePtr;
    }
    tsdPtr->lastIdlePtr = idlePtr;

    blockTime.sec = 0;
    blockTime.usec = 0;
    Tcl_SetMaxBlockTime(&blockTime);
}

/*
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
void
Tcl_CancelIdleCall(proc, clientData)
    Tcl_IdleProc *proc;		/* Procedure that was previously registered. */
    ClientData clientData;	/* Arbitrary value to pass to proc. */
{
    register IdleHandler *idlePtr, *prevPtr;
    IdleHandler *nextPtr;


    for (prevPtr = NULL, idlePtr = idleList; idlePtr != NULL;
	    prevPtr = idlePtr, idlePtr = idlePtr->nextPtr) {
	while ((idlePtr->proc == proc)
		&& (idlePtr->clientData == clientData)) {
	    nextPtr = idlePtr->nextPtr;
	    ckfree((char *) idlePtr);
	    idlePtr = nextPtr;
	    if (prevPtr == NULL) {
		idleList = idlePtr;
	    } else {
		prevPtr->nextPtr = idlePtr;
	    }
	    if (idlePtr == NULL) {
		lastIdlePtr = prevPtr;
		return;
	    }
	}
    }
}

/*







>

|







|




|







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
void
Tcl_CancelIdleCall(proc, clientData)
    Tcl_IdleProc *proc;		/* Procedure that was previously registered. */
    ClientData clientData;	/* Arbitrary value to pass to proc. */
{
    register IdleHandler *idlePtr, *prevPtr;
    IdleHandler *nextPtr;
    ThreadSpecificData *tsdPtr = InitTimer();

    for (prevPtr = NULL, idlePtr = tsdPtr->idleList; idlePtr != NULL;
	    prevPtr = idlePtr, idlePtr = idlePtr->nextPtr) {
	while ((idlePtr->proc == proc)
		&& (idlePtr->clientData == clientData)) {
	    nextPtr = idlePtr->nextPtr;
	    ckfree((char *) idlePtr);
	    idlePtr = nextPtr;
	    if (prevPtr == NULL) {
		tsdPtr->idleList = idlePtr;
	    } else {
		prevPtr->nextPtr = idlePtr;
	    }
	    if (idlePtr == NULL) {
		tsdPtr->lastIdlePtr = prevPtr;
		return;
	    }
	}
    }
}

/*
639
640
641
642
643
644
645

646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691

int
TclServiceIdle()
{
    IdleHandler *idlePtr;
    int oldGeneration;
    Tcl_Time blockTime;


    if (idleList == NULL) {
	return 0;
    }

    oldGeneration = idleGeneration;
    idleGeneration++;

    /*
     * The code below is trickier than it may look, for the following
     * reasons:
     *
     * 1. New handlers can get added to the list while the current
     *    one is being processed.  If new ones get added, we don't
     *    want to process them during this pass through the list (want
     *    to check for other work to do first).  This is implemented
     *    using the generation number in the handler:  new handlers
     *    will have a different generation than any of the ones currently
     *    on the list.
     * 2. The handler can call Tcl_DoOneEvent, so we have to remove
     *    the handler from the list before calling it. Otherwise an
     *    infinite loop could result.
     * 3. Tcl_CancelIdleCall can be called to remove an element from
     *    the list while a handler is executing, so the list could
     *    change structure during the call.
     */

    for (idlePtr = idleList;
	    ((idlePtr != NULL)
		    && ((oldGeneration - idlePtr->generation) >= 0));
	    idlePtr = idleList) {
	idleList = idlePtr->nextPtr;
	if (idleList == NULL) {
	    lastIdlePtr = NULL;
	}
	(*idlePtr->proc)(idlePtr->clientData);
	ckfree((char *) idlePtr);
    }
    if (idleList) {
	blockTime.sec = 0;
	blockTime.usec = 0;
	Tcl_SetMaxBlockTime(&blockTime);
    }
    return 1;
}








>

|



|
|




















|


|
|
|
|




|







649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702

int
TclServiceIdle()
{
    IdleHandler *idlePtr;
    int oldGeneration;
    Tcl_Time blockTime;
    ThreadSpecificData *tsdPtr = InitTimer();

    if (tsdPtr->idleList == NULL) {
	return 0;
    }

    oldGeneration = tsdPtr->idleGeneration;
    tsdPtr->idleGeneration++;

    /*
     * The code below is trickier than it may look, for the following
     * reasons:
     *
     * 1. New handlers can get added to the list while the current
     *    one is being processed.  If new ones get added, we don't
     *    want to process them during this pass through the list (want
     *    to check for other work to do first).  This is implemented
     *    using the generation number in the handler:  new handlers
     *    will have a different generation than any of the ones currently
     *    on the list.
     * 2. The handler can call Tcl_DoOneEvent, so we have to remove
     *    the handler from the list before calling it. Otherwise an
     *    infinite loop could result.
     * 3. Tcl_CancelIdleCall can be called to remove an element from
     *    the list while a handler is executing, so the list could
     *    change structure during the call.
     */

    for (idlePtr = tsdPtr->idleList;
	    ((idlePtr != NULL)
		    && ((oldGeneration - idlePtr->generation) >= 0));
	    idlePtr = tsdPtr->idleList) {
	tsdPtr->idleList = idlePtr->nextPtr;
	if (tsdPtr->idleList == NULL) {
	    tsdPtr->lastIdlePtr = NULL;
	}
	(*idlePtr->proc)(idlePtr->clientData);
	ckfree((char *) idlePtr);
    }
    if (tsdPtr->idleList) {
	blockTime.sec = 0;
	blockTime.usec = 0;
	Tcl_SetMaxBlockTime(&blockTime);
    }
    return 1;
}

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
    ClientData clientData;	/* Points to the "tclAfter" assocData for
				 * this interpreter, or NULL if the assocData
				 * hasn't been created yet.*/
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    /*
     * The variable below is used to generate unique identifiers for
     * after commands.  This id can wrap around, which can potentially
     * cause problems.  However, there are not likely to be problems
     * in practice, because after commands can only be requested to
     * about a month in the future, and wrap-around is unlikely to
     * occur in less than about 1-10 years.  Thus it's unlikely that
     * any old ids will still be around when wrap-around occurs.
     */

    static int nextId = 1;
    int ms;
    AfterInfo *afterPtr;
    AfterAssocData *assocPtr = (AfterAssocData *) clientData;
    Tcl_CmdInfo cmdInfo;
    int length;
    char *arg;
    int index, result;
    static char *subCmds[] = {
        "cancel", "idle", "info",
        (char *) NULL};

    
    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }

    /*
     * Create the "after" information associated for this interpreter,







<
<
<
<
<
<
<
<
<
<
<





|
|
|
|
|
>
|







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
    ClientData clientData;	/* Points to the "tclAfter" assocData for
				 * this interpreter, or NULL if the assocData
				 * hasn't been created yet.*/
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{











    int ms;
    AfterInfo *afterPtr;
    AfterAssocData *assocPtr = (AfterAssocData *) clientData;
    Tcl_CmdInfo cmdInfo;
    int length;
    char *argString;
    int index;
    char buf[16 + TCL_INTEGER_SPACE];
    static char *afterSubCmds[] = {"cancel", "idle", "info", (char *) NULL};
    enum afterSubCmds {AFTER_CANCEL, AFTER_IDLE, AFTER_INFO};
    ThreadSpecificData *tsdPtr = InitTimer();

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
	return TCL_ERROR;
    }

    /*
     * Create the "after" information associated for this interpreter,
765
766
767
768
769
770
771
772




773
774
775
776
777

778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797










798
799
800
801
802
803
804

805
806
807
808
809
810

811
812
813
814
815
816
817
818
819
820
821
822

823
824

825
826
827
828
829
830
831
832
833
834
835

836
837
838




839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875

876
877
878
879
880
881
882

883
884
885
886
887

888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907

908
909
910

911




912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938


939
940
941
942
943
944
945

946
947
948
949
950
951
952
953
954
955
956
957
958
	Tcl_SetCommandInfo(interp, Tcl_GetStringFromObj(objv[0], &length),
		&cmdInfo);
    }

    /*
     * First lets see if the command was passed a number as the first argument.
     */
    




    arg = Tcl_GetStringFromObj(objv[1], &length);
    if (isdigit(UCHAR(arg[0]))) {
	if (Tcl_GetIntFromObj(interp, objv[1], &ms) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (ms < 0) {
	    ms = 0;
	}
	if (objc == 2) {
	    Tcl_Sleep(ms);
	    return TCL_OK;
	}
	afterPtr = (AfterInfo *) ckalloc((unsigned) (sizeof(AfterInfo)));
	afterPtr->assocPtr = assocPtr;
	if (objc == 3) {
	    arg = Tcl_GetStringFromObj(objv[2], &length);
	    afterPtr->command = (char *) ckalloc((unsigned) (length + 1));
	    strcpy(afterPtr->command, arg);
	} else {
	    Tcl_Obj *objPtr = Tcl_ConcatObj(objc-2, objv+2);
	    arg = Tcl_GetStringFromObj(objPtr, &length);
	    afterPtr->command = (char *) ckalloc((unsigned) (length + 1));
	    strcpy(afterPtr->command, arg);
	    Tcl_DecrRefCount(objPtr);
	}










	afterPtr->id = nextId;
	nextId += 1;
	afterPtr->token = Tcl_CreateTimerHandler(ms, AfterProc,
		(ClientData) afterPtr);
	afterPtr->nextPtr = assocPtr->firstAfterPtr;
	assocPtr->firstAfterPtr = afterPtr;
	sprintf(interp->result, "after#%d", afterPtr->id);

	return TCL_OK;
    }

    /*
     * If it's not a number it must be a subcommand.
     */

    result = Tcl_GetIndexFromObj(NULL, objv[1], subCmds, "option",
            0, (int *) &index);
    if (result != TCL_OK) {
	Tcl_AppendResult(interp, "bad argument \"", arg,
		"\": must be cancel, idle, info, or a number",
		(char *) NULL);
	return TCL_ERROR;
    }

    switch (index) {
        case 0:		/* cancel */
	    {

		char *arg;
		Tcl_Obj *objPtr = NULL;


		if (objc < 3) {
		    Tcl_WrongNumArgs(interp, 2, objv, "id|command");
		    return TCL_ERROR;
		}
		if (objc == 3) {
		    arg = Tcl_GetStringFromObj(objv[2], &length);
		} else {
		    objPtr = Tcl_ConcatObj(objc-2, objv+2);;
		    arg = Tcl_GetStringFromObj(objPtr, &length);
		}

		for (afterPtr = assocPtr->firstAfterPtr; afterPtr != NULL;
		     afterPtr = afterPtr->nextPtr) {
		    if (strcmp(afterPtr->command, arg) == 0) {




			break;
		    }
		}
		if (afterPtr == NULL) {
		    afterPtr = GetAfterEvent(assocPtr, arg);
		}
		if (objPtr != NULL) {
		    Tcl_DecrRefCount(objPtr);
		}
		if (afterPtr != NULL) {
		    if (afterPtr->token != NULL) {
			Tcl_DeleteTimerHandler(afterPtr->token);
		    } else {
			Tcl_CancelIdleCall(AfterProc, (ClientData) afterPtr);
		    }
		    FreeAfterPtr(afterPtr);
		}
		break;
	    }
	case 1:		/* idle */
	    if (objc < 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "script script ...");
		return TCL_ERROR;
	    }
	    afterPtr = (AfterInfo *) ckalloc((unsigned) (sizeof(AfterInfo)));
	    afterPtr->assocPtr = assocPtr;
	    if (objc == 3) {
		arg = Tcl_GetStringFromObj(objv[2], &length);
		afterPtr->command = (char *) ckalloc((unsigned) length + 1);
		strcpy(afterPtr->command, arg);
	    } else {
		Tcl_Obj *objPtr = Tcl_ConcatObj(objc-2, objv+2);;
		arg = Tcl_GetStringFromObj(objPtr, &length);
		afterPtr->command = (char *) ckalloc((unsigned) (length + 1));
		strcpy(afterPtr->command, arg);
		Tcl_DecrRefCount(objPtr);
	    }

	    afterPtr->id = nextId;
	    nextId += 1;
	    afterPtr->token = NULL;
	    afterPtr->nextPtr = assocPtr->firstAfterPtr;
	    assocPtr->firstAfterPtr = afterPtr;
	    Tcl_DoWhenIdle(AfterProc, (ClientData) afterPtr);
	    sprintf(interp->result, "after#%d", afterPtr->id);

	    break;
	case 2:		/* info */
	    if (objc == 2) {
		char buffer[30];
	    

		for (afterPtr = assocPtr->firstAfterPtr; afterPtr != NULL;
		     afterPtr = afterPtr->nextPtr) {
		    if (assocPtr->interp == interp) {
			sprintf(buffer, "after#%d", afterPtr->id);
			Tcl_AppendElement(interp, buffer);
		    }
		}
		return TCL_OK;
	    }
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "?id?");
		return TCL_ERROR;
	    }
	    arg = Tcl_GetStringFromObj(objv[2], &length);
	    afterPtr = GetAfterEvent(assocPtr, arg);
	    if (afterPtr == NULL) {
		Tcl_AppendResult(interp, "event \"", arg,
			"\" doesn't exist", (char *) NULL);
		return TCL_ERROR;
	    }

	    Tcl_AppendElement(interp, afterPtr->command);
	    Tcl_AppendElement(interp,
		    (afterPtr->token == NULL) ? "idle" : "timer");

	    break;




    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetAfterEvent --
 *
 *	This procedure parses an "after" id such as "after#4" and
 *	returns a pointer to the AfterInfo structure.
 *
 * Results:
 *	The return value is either a pointer to an AfterInfo structure,
 *	if one is found that corresponds to "string" and is for interp,
 *	or NULL if no corresponding after event can be found.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static AfterInfo *
GetAfterEvent(assocPtr, string)
    AfterAssocData *assocPtr;	/* Points to "after"-related information for
				 * this interpreter. */


    char *string;		/* Textual identifier for after event, such
				 * as "after#6". */
{
    AfterInfo *afterPtr;
    int id;
    char *end;


    if (strncmp(string, "after#", 6) != 0) {
	return NULL;
    }
    string += 6;
    id = strtoul(string, &end, 10);
    if ((end == string) || (*end != 0)) {
	return NULL;
    }
    for (afterPtr = assocPtr->firstAfterPtr; afterPtr != NULL;
	    afterPtr = afterPtr->nextPtr) {
	if (afterPtr->id == id) {
	    return afterPtr;
	}







|
>
>
>
>
|
|



>










<
<
|

|
<
<
<
<

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




|
>






>
|
<
|
|




|
<
|
<
>
|
<
>

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







<
|
<

|
<
<
<
<

>
|
|




|
>

|
|
<
|
>



|
|








<
|

|



>
|
|
|
>

>
>
>
>














|









|


>
>
|

<




>
|


|
|
|







766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793


794
795
796




797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823

824
825
826
827
828
829
830

831

832
833

834
835
836
837
838
839
840
841
842
843

844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879

880

881
882




883
884
885
886
887
888
889
890
891
892
893
894
895

896
897
898
899
900
901
902
903
904
905
906
907
908
909
910

911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957

958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
	Tcl_SetCommandInfo(interp, Tcl_GetStringFromObj(objv[0], &length),
		&cmdInfo);
    }

    /*
     * First lets see if the command was passed a number as the first argument.
     */

    if (objv[1]->typePtr == &tclIntType) {
	ms = (int) objv[1]->internalRep.longValue;
	goto processInteger;
    }
    argString = Tcl_GetStringFromObj(objv[1], &length);
    if (isdigit(UCHAR(argString[0]))) {	/* INTL: digit */
	if (Tcl_GetIntFromObj(interp, objv[1], &ms) != TCL_OK) {
	    return TCL_ERROR;
	}
processInteger:
	if (ms < 0) {
	    ms = 0;
	}
	if (objc == 2) {
	    Tcl_Sleep(ms);
	    return TCL_OK;
	}
	afterPtr = (AfterInfo *) ckalloc((unsigned) (sizeof(AfterInfo)));
	afterPtr->assocPtr = assocPtr;
	if (objc == 3) {


	    afterPtr->commandPtr = objv[2];
	} else {
 	    afterPtr->commandPtr = Tcl_ConcatObj(objc-2, objv+2);




	}
	Tcl_IncrRefCount(afterPtr->commandPtr);
	/*
	 * The variable below is used to generate unique identifiers for
	 * after commands.  This id can wrap around, which can potentially
	 * cause problems.  However, there are not likely to be problems
	 * in practice, because after commands can only be requested to
	 * about a month in the future, and wrap-around is unlikely to
	 * occur in less than about 1-10 years.  Thus it's unlikely that
	 * any old ids will still be around when wrap-around occurs.
	 */
	afterPtr->id = tsdPtr->afterId;
	tsdPtr->afterId += 1;
	afterPtr->token = Tcl_CreateTimerHandler(ms, AfterProc,
		(ClientData) afterPtr);
	afterPtr->nextPtr = assocPtr->firstAfterPtr;
	assocPtr->firstAfterPtr = afterPtr;
	sprintf(buf, "after#%d", afterPtr->id);
	Tcl_AppendResult(interp, buf, (char *) NULL);
	return TCL_OK;
    }

    /*
     * If it's not a number it must be a subcommand.
     */

    if (Tcl_GetIndexFromObj(NULL, objv[1], afterSubCmds, "argument",

            0, &index) != TCL_OK) {
	Tcl_AppendResult(interp, "bad argument \"", argString,
		"\": must be cancel, idle, info, or a number",
		(char *) NULL);
	return TCL_ERROR;
    }
    switch ((enum afterSubCmds) index) {

        case AFTER_CANCEL: {

	    Tcl_Obj *commandPtr;
	    char *command, *tempCommand;

	    int tempLength;

	    if (objc < 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "id|command");
		return TCL_ERROR;
	    }
	    if (objc == 3) {
		commandPtr = objv[2];
	    } else {
		commandPtr = Tcl_ConcatObj(objc-2, objv+2);;

	    }
	    command = Tcl_GetStringFromObj(commandPtr, &length);
	    for (afterPtr = assocPtr->firstAfterPtr;  afterPtr != NULL;
		    afterPtr = afterPtr->nextPtr) {
		tempCommand = Tcl_GetStringFromObj(afterPtr->commandPtr,
			&tempLength);
		if ((length == tempLength)
		        && (memcmp((void*) command, (void*) tempCommand,
			        (unsigned) length) == 0)) {
		    break;
		}
	    }
	    if (afterPtr == NULL) {
		afterPtr = GetAfterEvent(assocPtr, commandPtr);
	    }
	    if (objc != 3) {
		Tcl_DecrRefCount(commandPtr);
	    }
	    if (afterPtr != NULL) {
		if (afterPtr->token != NULL) {
		    Tcl_DeleteTimerHandler(afterPtr->token);
		} else {
		    Tcl_CancelIdleCall(AfterProc, (ClientData) afterPtr);
		}
		FreeAfterPtr(afterPtr);
	    }
	    break;
	}
	case AFTER_IDLE:
	    if (objc < 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "script script ...");
		return TCL_ERROR;
	    }
	    afterPtr = (AfterInfo *) ckalloc((unsigned) (sizeof(AfterInfo)));
	    afterPtr->assocPtr = assocPtr;
	    if (objc == 3) {

 		afterPtr->commandPtr = objv[2];

	    } else {
		afterPtr->commandPtr = Tcl_ConcatObj(objc-2, objv+2);




	    }
	    Tcl_IncrRefCount(afterPtr->commandPtr);
	    afterPtr->id = tsdPtr->afterId;
	    tsdPtr->afterId += 1;
	    afterPtr->token = NULL;
	    afterPtr->nextPtr = assocPtr->firstAfterPtr;
	    assocPtr->firstAfterPtr = afterPtr;
	    Tcl_DoWhenIdle(AfterProc, (ClientData) afterPtr);
	    sprintf(buf, "after#%d", afterPtr->id);
	    Tcl_AppendResult(interp, buf, (char *) NULL);
	    break;
	case AFTER_INFO: {
	    Tcl_Obj *resultListPtr;


	    if (objc == 2) {
		for (afterPtr = assocPtr->firstAfterPtr; afterPtr != NULL;
		     afterPtr = afterPtr->nextPtr) {
		    if (assocPtr->interp == interp) {
			sprintf(buf, "after#%d", afterPtr->id);
			Tcl_AppendElement(interp, buf);
		    }
		}
		return TCL_OK;
	    }
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 2, objv, "?id?");
		return TCL_ERROR;
	    }

	    afterPtr = GetAfterEvent(assocPtr, objv[2]);
	    if (afterPtr == NULL) {
		Tcl_AppendResult(interp, "event \"", Tcl_GetString(objv[2]),
			"\" doesn't exist", (char *) NULL);
		return TCL_ERROR;
	    }
	    resultListPtr = Tcl_GetObjResult(interp);
 	    Tcl_ListObjAppendElement(interp, resultListPtr, afterPtr->commandPtr);
 	    Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj(
 		(afterPtr->token == NULL) ? "idle" : "timer", -1));
	    Tcl_SetObjResult(interp, resultListPtr);
	    break;
	}
	default: {
	    panic("Tcl_AfterObjCmd: bad subcommand index to afterSubCmds");
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetAfterEvent --
 *
 *	This procedure parses an "after" id such as "after#4" and
 *	returns a pointer to the AfterInfo structure.
 *
 * Results:
 *	The return value is either a pointer to an AfterInfo structure,
 *	if one is found that corresponds to "cmdString" and is for interp,
 *	or NULL if no corresponding after event can be found.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static AfterInfo *
GetAfterEvent(assocPtr, commandPtr)
    AfterAssocData *assocPtr;	/* Points to "after"-related information for
				 * this interpreter. */
    Tcl_Obj *commandPtr;
{
    char *cmdString;		/* Textual identifier for after event, such
				 * as "after#6". */

    AfterInfo *afterPtr;
    int id;
    char *end;

    cmdString = Tcl_GetString(commandPtr);
    if (strncmp(cmdString, "after#", 6) != 0) {
	return NULL;
    }
    cmdString += 6;
    id = strtoul(cmdString, &end, 10);
    if ((end == cmdString) || (*end != 0)) {
	return NULL;
    }
    for (afterPtr = assocPtr->firstAfterPtr; afterPtr != NULL;
	    afterPtr = afterPtr->nextPtr) {
	if (afterPtr->id == id) {
	    return afterPtr;
	}
985
986
987
988
989
990
991


992
993
994
995
996
997
998
    ClientData clientData;	/* Describes command to execute. */
{
    AfterInfo *afterPtr = (AfterInfo *) clientData;
    AfterAssocData *assocPtr = afterPtr->assocPtr;
    AfterInfo *prevPtr;
    int result;
    Tcl_Interp *interp;



    /*
     * First remove the callback from our list of callbacks;  otherwise
     * someone could delete the callback while it's being executed, which
     * could cause a core dump.
     */








>
>







1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
    ClientData clientData;	/* Describes command to execute. */
{
    AfterInfo *afterPtr = (AfterInfo *) clientData;
    AfterAssocData *assocPtr = afterPtr->assocPtr;
    AfterInfo *prevPtr;
    int result;
    Tcl_Interp *interp;
    char *script;
    int numBytes;

    /*
     * First remove the callback from our list of callbacks;  otherwise
     * someone could delete the callback while it's being executed, which
     * could cause a core dump.
     */

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

    /*
     * Execute the callback.
     */

    interp = assocPtr->interp;
    Tcl_Preserve((ClientData) interp);
    result = Tcl_GlobalEval(interp, afterPtr->command);

    if (result != TCL_OK) {
	Tcl_AddErrorInfo(interp, "\n    (\"after\" script)");
	Tcl_BackgroundError(interp);
    }
    Tcl_Release((ClientData) interp);
    
    /*
     * Free the memory for the callback.
     */

    ckfree(afterPtr->command);
    ckfree((char *) afterPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * FreeAfterPtr --







|
>










|







1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053

    /*
     * Execute the callback.
     */

    interp = assocPtr->interp;
    Tcl_Preserve((ClientData) interp);
    script = Tcl_GetStringFromObj(afterPtr->commandPtr, &numBytes);
    result = Tcl_EvalEx(interp, script, numBytes, TCL_EVAL_GLOBAL);
    if (result != TCL_OK) {
	Tcl_AddErrorInfo(interp, "\n    (\"after\" script)");
	Tcl_BackgroundError(interp);
    }
    Tcl_Release((ClientData) interp);
    
    /*
     * Free the memory for the callback.
     */

    Tcl_DecrRefCount(afterPtr->commandPtr);
    ckfree((char *) afterPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * FreeAfterPtr --
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
    } else {
	for (prevPtr = assocPtr->firstAfterPtr; prevPtr->nextPtr != afterPtr;
		prevPtr = prevPtr->nextPtr) {
	    /* Empty loop body. */
	}
	prevPtr->nextPtr = afterPtr->nextPtr;
    }
    ckfree(afterPtr->command);
    ckfree((char *) afterPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * AfterCleanupProc --







|







1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
    } else {
	for (prevPtr = assocPtr->firstAfterPtr; prevPtr->nextPtr != afterPtr;
		prevPtr = prevPtr->nextPtr) {
	    /* Empty loop body. */
	}
	prevPtr->nextPtr = afterPtr->nextPtr;
    }
    Tcl_DecrRefCount(afterPtr->commandPtr);
    ckfree((char *) afterPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * AfterCleanupProc --
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
	afterPtr = assocPtr->firstAfterPtr;
	assocPtr->firstAfterPtr = afterPtr->nextPtr;
	if (afterPtr->token != NULL) {
	    Tcl_DeleteTimerHandler(afterPtr->token);
	} else {
	    Tcl_CancelIdleCall(AfterProc, (ClientData) afterPtr);
	}
	ckfree(afterPtr->command);
	ckfree((char *) afterPtr);
    }
    ckfree((char *) assocPtr);
}







|




1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
	afterPtr = assocPtr->firstAfterPtr;
	assocPtr->firstAfterPtr = afterPtr->nextPtr;
	if (afterPtr->token != NULL) {
	    Tcl_DeleteTimerHandler(afterPtr->token);
	} else {
	    Tcl_CancelIdleCall(AfterProc, (ClientData) afterPtr);
	}
	Tcl_DecrRefCount(afterPtr->commandPtr);
	ckfree((char *) afterPtr);
    }
    ckfree((char *) assocPtr);
}

Added generic/tclUniData.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
/*
 * tclUtfData.c --
 *
 *	Declarations of Unicode character information tables.  This file is
 *	automatically generated by the tools/uniParse.tcl script.  Do not
 *	modify this file by hand.
 *
 * Copyright (c) 1998 by Scriptics Corporation.
 * All rights reserved.
 *
 * RCS: @(#) $Id: tclUniData.c,v 1.1.2.2 1998/11/11 04:54:21 stanton Exp $
 */

/*
 * A 16-bit Unicode character is split into two parts in order to index
 * into the following tables.  The lower OFFSET_BITS comprise an offset
 * into a page of characters.  The upper bits comprise the page number.
 */

#define OFFSET_BITS 6

/*
 * The pageMap is indexed by page number and returns an alternate page number
 * that identifies a unique page of characters.  Many Unicode characters map
 * to the same alternate page number.
 */

static char pageMap[] = {
    0, 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, 28, 28, 28, 28, 28, 28, 28, 29, 
    30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 
    28, 28, 47, 48, 49, 50, 51, 52, 53, 28, 28, 28, 54, 55, 56, 57, 58, 
    59, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 60, 60, 
    61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 75, 
    76, 77, 78, 28, 28, 79, 80, 81, 82, 83, 83, 84, 85, 86, 85, 28, 28, 
    87, 88, 89, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 90, 91, 92, 93, 94, 56, 95, 28, 96, 97, 98, 99, 83, 100, 83, 
    101, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 102, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 
    28, 28, 28, 28, 28, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
    56, 56, 56, 56, 56, 56, 56, 56, 56, 103, 28, 104, 104, 104, 104, 104, 
    104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 
    104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 
    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
    105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 
    105, 56, 56, 56, 56, 106, 28, 28, 28, 107, 108, 109, 110, 56, 56, 56, 
    56, 111, 112, 113, 114, 115, 116, 56, 117, 118, 119, 120, 121
};

/*
 * The groupMap is indexed by combining the alternate page number with
 * the page offset and returns a group number that identifies a unique
 * set of character attributes.
 */

static char groupMap[] = {
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, 3, 3, 3, 5, 6, 3, 7, 3, 8, 
    3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 7, 7, 7, 3, 3, 10, 10, 10, 
    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 
    10, 10, 10, 10, 10, 10, 5, 3, 6, 11, 12, 11, 13, 13, 13, 13, 13, 13, 
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
    13, 13, 13, 5, 7, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 4, 4, 
    4, 14, 14, 11, 14, 15, 16, 7, 8, 14, 11, 14, 7, 17, 17, 11, 15, 14, 
    3, 11, 17, 15, 18, 17, 17, 17, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 
    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 7, 10, 10, 
    10, 10, 10, 10, 10, 15, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 7, 13, 13, 13, 13, 
    13, 13, 13, 19, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 22, 23, 20, 21, 20, 21, 20, 21, 15, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 15, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 24, 20, 21, 20, 21, 20, 21, 25, 15, 26, 20, 21, 
    20, 21, 27, 20, 21, 28, 28, 20, 21, 15, 29, 30, 31, 20, 21, 28, 32, 
    15, 33, 34, 20, 21, 15, 15, 33, 35, 15, 36, 20, 21, 20, 21, 20, 21, 
    37, 20, 21, 38, 39, 15, 20, 21, 38, 20, 21, 40, 40, 20, 21, 20, 21, 
    41, 20, 21, 15, 39, 20, 21, 39, 39, 39, 39, 39, 39, 42, 43, 44, 42, 
    43, 44, 42, 43, 44, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 45, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 15, 42, 43, 44, 20, 21, 0, 0, 0, 0, 20, 21, 
    20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 15, 15, 15, 46, 47, 15, 48, 48, 15, 49, 15, 50, 15, 15, 15, 15, 
    48, 15, 15, 51, 15, 15, 15, 15, 52, 53, 15, 15, 15, 15, 15, 53, 15, 
    15, 54, 15, 15, 55, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
    15, 56, 15, 15, 15, 15, 56, 15, 57, 57, 15, 15, 15, 15, 15, 15, 58, 
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
    15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 59, 59, 59, 59, 59, 59, 59, 
    59, 59, 11, 11, 59, 59, 59, 59, 59, 59, 59, 11, 11, 11, 11, 11, 11, 
    11, 11, 11, 11, 11, 11, 11, 11, 59, 59, 11, 11, 11, 11, 11, 11, 11, 
    11, 11, 11, 11, 11, 11, 0, 59, 59, 59, 59, 59, 11, 11, 11, 11, 11, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 
    60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 
    60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 
    60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 
    60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 
    60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 3, 3, 0, 0, 0, 0, 59, 0, 0, 0, 3, 0, 0, 0, 0, 0, 11, 11, 61, 
    3, 62, 62, 62, 0, 63, 0, 64, 64, 15, 10, 10, 10, 10, 10, 10, 10, 10, 
    10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 
    10, 10, 65, 66, 66, 66, 15, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
    13, 13, 13, 13, 13, 13, 13, 67, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
    68, 69, 69, 0, 70, 71, 37, 37, 37, 72, 73, 0, 0, 0, 37, 0, 37, 0, 37, 
    0, 37, 0, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 74, 
    75, 45, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 
    76, 76, 76, 76, 76, 76, 76, 76, 0, 76, 76, 10, 10, 10, 10, 10, 10, 
    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 
    10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
    13, 13, 13, 13, 13, 13, 13, 0, 75, 75, 75, 75, 75, 75, 75, 75, 75, 
    75, 75, 75, 0, 75, 75, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 14, 60, 60, 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 39, 20, 
    21, 20, 21, 0, 0, 20, 21, 0, 0, 20, 21, 0, 0, 0, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 0, 0, 20, 21, 20, 21, 20, 21, 20, 21, 0, 0, 
    20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 77, 77, 77, 77, 77, 77, 77, 
    77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 
    77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 0, 0, 59, 3, 3, 
    3, 3, 3, 3, 0, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 
    78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 
    78, 78, 78, 78, 78, 78, 78, 78, 15, 0, 3, 0, 0, 0, 0, 0, 0, 0, 60, 
    60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0, 
    60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 
    60, 60, 60, 60, 60, 60, 0, 60, 60, 60, 3, 60, 3, 60, 60, 3, 60, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    0, 0, 0, 0, 0, 39, 39, 39, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 3, 0, 0, 0, 3, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 
    0, 0, 0, 0, 59, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 60, 60, 60, 
    60, 60, 60, 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 
    9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 0, 0, 60, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 0, 39, 39, 
    39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 0, 39, 39, 39, 39, 3, 39, 60, 60, 60, 60, 60, 60, 60, 79, 79, 
    60, 60, 60, 60, 60, 60, 59, 59, 60, 60, 14, 60, 60, 60, 60, 0, 0, 9, 
    9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 80, 0, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 0, 60, 39, 
    80, 80, 80, 60, 60, 60, 60, 60, 60, 60, 60, 80, 80, 80, 80, 60, 0, 
    0, 14, 60, 60, 60, 60, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 60, 60, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 80, 80, 0, 39, 39, 39, 39, 39, 39, 
    39, 39, 0, 0, 39, 39, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 39, 39, 39, 39, 
    39, 39, 39, 0, 39, 0, 0, 0, 39, 39, 39, 39, 0, 0, 60, 0, 80, 80, 80, 
    60, 60, 60, 60, 0, 0, 80, 80, 0, 0, 80, 80, 60, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 80, 0, 0, 0, 0, 39, 39, 0, 39, 39, 39, 60, 60, 0, 0, 9, 9, 9, 
    9, 9, 9, 9, 9, 9, 9, 39, 39, 4, 4, 17, 17, 17, 17, 17, 17, 14, 0, 0, 
    0, 0, 0, 0, 0, 60, 0, 0, 39, 39, 39, 39, 39, 39, 0, 0, 0, 0, 39, 39, 
    0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 0, 39, 39, 0, 
    39, 39, 0, 39, 39, 0, 0, 60, 0, 80, 80, 80, 60, 60, 0, 0, 0, 0, 60, 
    60, 0, 0, 60, 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 
    39, 0, 39, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 60, 60, 
    39, 39, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 80, 0, 39, 
    39, 39, 39, 39, 39, 39, 0, 39, 0, 39, 39, 39, 0, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    0, 39, 39, 39, 39, 39, 39, 39, 0, 39, 39, 0, 39, 39, 39, 39, 39, 0, 
    0, 60, 39, 80, 80, 80, 60, 60, 60, 60, 60, 0, 60, 60, 80, 0, 80, 80, 
    60, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 
    0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 60, 80, 80, 0, 39, 39, 39, 39, 39, 39, 39, 39, 
    0, 0, 39, 39, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 
    39, 0, 39, 39, 0, 0, 39, 39, 39, 39, 0, 0, 60, 39, 80, 60, 80, 60, 
    60, 60, 0, 0, 0, 80, 80, 0, 0, 80, 80, 60, 0, 0, 0, 0, 0, 0, 0, 0, 
    60, 80, 0, 0, 0, 0, 39, 39, 0, 39, 39, 39, 0, 0, 0, 0, 9, 9, 9, 9, 
    9, 9, 9, 9, 9, 9, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 60, 80, 0, 39, 39, 39, 39, 39, 39, 0, 0, 0, 39, 39, 39, 0, 39, 
    39, 39, 39, 0, 0, 0, 39, 39, 0, 39, 0, 39, 39, 0, 0, 0, 39, 39, 0, 
    0, 0, 39, 39, 39, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 0, 39, 39, 
    39, 0, 0, 0, 0, 80, 80, 60, 80, 80, 0, 0, 0, 80, 80, 80, 0, 80, 80, 
    80, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 17, 17, 17, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 0, 39, 39, 39, 39, 39, 39, 39, 
    39, 0, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 0, 0, 0, 0, 60, 60, 60, 
    80, 80, 80, 80, 0, 60, 60, 60, 0, 60, 60, 60, 60, 0, 0, 0, 0, 0, 0, 
    0, 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 39, 0, 0, 0, 0, 9, 9, 9, 
    9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 80, 80, 0, 39, 39, 39, 39, 39, 39, 39, 39, 0, 39, 39, 39, 0, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    0, 39, 39, 39, 39, 39, 0, 0, 0, 0, 80, 60, 80, 80, 80, 80, 80, 0, 60, 
    80, 80, 0, 80, 80, 60, 60, 0, 0, 0, 0, 0, 0, 0, 80, 80, 0, 0, 0, 0, 
    0, 0, 0, 39, 0, 39, 39, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 0, 39, 39, 
    39, 39, 39, 39, 39, 39, 0, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 
    0, 0, 0, 80, 80, 80, 60, 60, 60, 0, 0, 80, 80, 80, 0, 80, 80, 80, 60, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 39, 39, 0, 0, 
    0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 3, 
    39, 60, 39, 39, 60, 60, 60, 60, 60, 60, 60, 0, 0, 0, 0, 4, 39, 39, 
    39, 39, 39, 39, 59, 60, 60, 60, 60, 60, 60, 60, 60, 14, 9, 9, 9, 9, 
    9, 9, 9, 9, 9, 9, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 
    39, 0, 39, 0, 0, 39, 39, 0, 39, 0, 0, 39, 0, 0, 0, 0, 0, 0, 39, 39, 
    39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 0, 39, 39, 39, 0, 39, 0, 39, 
    0, 0, 39, 39, 0, 39, 39, 3, 39, 60, 39, 39, 60, 60, 60, 60, 60, 60, 
    0, 60, 60, 39, 0, 0, 39, 39, 39, 39, 39, 0, 59, 0, 60, 60, 60, 60, 
    60, 60, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 39, 39, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 14, 60, 60, 14, 14, 14, 14, 14, 14, 
    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
    14, 60, 14, 60, 14, 60, 5, 6, 5, 6, 5, 6, 39, 39, 39, 39, 39, 39, 39, 
    39, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 0, 0, 0, 0, 0, 0, 0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 
    60, 60, 60, 80, 60, 60, 60, 60, 60, 3, 60, 60, 14, 14, 14, 14, 0, 0, 
    0, 0, 60, 60, 60, 60, 60, 60, 0, 60, 0, 60, 60, 60, 60, 60, 60, 60, 
    60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0, 0, 0, 60, 
    60, 60, 60, 60, 60, 60, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 
    77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 
    77, 77, 77, 77, 77, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
    15, 0, 0, 0, 0, 3, 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 0, 0, 0, 0, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 0, 0, 0, 0, 0, 0, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 15, 15, 15, 15, 15, 81, 0, 0, 0, 0, 20, 21, 
    20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 
    20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 21, 20, 
    21, 20, 21, 0, 0, 0, 0, 0, 0, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 
    83, 83, 83, 83, 83, 83, 82, 82, 82, 82, 82, 82, 0, 0, 83, 83, 83, 83, 
    83, 83, 0, 0, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 
    83, 83, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 
    83, 82, 82, 82, 82, 82, 82, 0, 0, 83, 83, 83, 83, 83, 83, 0, 0, 15, 
    82, 15, 82, 15, 82, 15, 82, 0, 83, 0, 83, 0, 83, 0, 83, 82, 82, 82, 
    82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 85, 85, 
    85, 85, 86, 86, 87, 87, 88, 88, 89, 89, 0, 0, 82, 82, 82, 82, 82, 82, 
    82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 82, 82, 82, 82, 82, 82, 82, 
    82, 83, 83, 83, 83, 83, 83, 83, 83, 82, 82, 82, 82, 82, 82, 82, 82, 
    83, 83, 83, 83, 83, 83, 83, 83, 82, 82, 15, 90, 15, 0, 15, 15, 83, 
    83, 91, 91, 92, 11, 37, 11, 11, 11, 15, 90, 15, 0, 15, 15, 93, 93, 
    93, 93, 92, 11, 11, 11, 82, 82, 15, 15, 0, 0, 15, 15, 83, 83, 94, 94, 
    0, 11, 11, 11, 82, 82, 15, 15, 15, 95, 15, 15, 83, 83, 96, 96, 97, 
    11, 11, 11, 0, 0, 15, 90, 15, 0, 15, 15, 98, 98, 99, 99, 92, 11, 11, 
    0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 100, 100, 100, 100, 8, 8, 8, 
    8, 8, 8, 3, 3, 16, 18, 5, 16, 16, 18, 5, 16, 3, 3, 3, 3, 3, 3, 3, 3, 
    101, 102, 100, 100, 100, 100, 100, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 16, 
    18, 3, 3, 3, 3, 12, 12, 3, 3, 3, 7, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 100, 100, 100, 100, 100, 100, 17, 0, 0, 0, 17, 17, 17, 17, 
    17, 17, 7, 7, 7, 5, 6, 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
    7, 7, 7, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 79, 79, 79, 
    79, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 37, 14, 14, 14, 14, 37, 14, 14, 
    15, 37, 37, 37, 15, 15, 37, 37, 37, 15, 14, 37, 14, 14, 37, 37, 37, 
    37, 37, 37, 14, 14, 14, 14, 14, 14, 37, 14, 37, 14, 37, 14, 37, 37, 
    37, 37, 15, 15, 37, 37, 14, 37, 15, 39, 39, 39, 39, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 103, 103, 103, 103, 
    103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 104, 104, 
    104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 
    105, 105, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 7, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 14, 14, 14, 14, 14, 14, 7, 
    7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 7, 7, 14, 14, 14, 14, 14, 14, 14, 5, 6, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
    17, 17, 17, 17, 17, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 106, 106, 106, 
    106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 
    106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 
    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
    107, 107, 107, 107, 107, 107, 107, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    0, 14, 14, 14, 14, 0, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 0, 14, 0, 14, 14, 14, 14, 0, 0, 0, 14, 
    0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
    17, 17, 17, 17, 17, 17, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 2, 3, 3, 
    3, 14, 59, 3, 105, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 14, 14, 5, 6, 5, 6, 
    5, 6, 5, 6, 8, 5, 6, 6, 14, 105, 105, 105, 105, 105, 105, 105, 105, 
    105, 60, 60, 60, 60, 60, 60, 8, 59, 59, 59, 59, 59, 14, 14, 0, 0, 0, 
    0, 0, 0, 0, 14, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 0, 0, 0, 0, 60, 60, 59, 59, 59, 59, 0, 0, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 3, 59, 59, 59, 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 
    0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 14, 
    14, 17, 17, 17, 17, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 
    0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 0, 0, 0, 14, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 
    0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 108, 108, 108, 108, 
    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
    108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 
    109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 
    109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 
    109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 
    109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 60, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 7, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 0, 39, 0, 39, 39, 0, 39, 
    39, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 0, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 60, 60, 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 8, 
    12, 12, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 0, 0, 0, 0, 
    3, 3, 3, 3, 12, 12, 12, 3, 3, 3, 0, 3, 3, 3, 3, 8, 5, 6, 5, 6, 5, 6, 
    3, 3, 3, 7, 8, 7, 7, 7, 0, 3, 4, 3, 3, 0, 0, 0, 0, 39, 39, 39, 0, 39, 
    0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 0, 0, 100, 0, 3, 3, 3, 4, 3, 3, 3, 5, 6, 3, 7, 3, 8, 
    3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 7, 7, 7, 3, 3, 10, 10, 10, 
    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 
    10, 10, 10, 10, 10, 10, 5, 3, 6, 11, 12, 11, 13, 13, 13, 13, 13, 13, 
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
    13, 13, 13, 5, 7, 6, 7, 0, 0, 3, 5, 6, 3, 3, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 59, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 59, 
    59, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 0, 0, 
    39, 39, 39, 39, 39, 39, 0, 0, 39, 39, 39, 39, 39, 39, 0, 0, 39, 39, 
    39, 39, 39, 39, 0, 0, 39, 39, 39, 0, 0, 0, 4, 4, 7, 11, 14, 4, 4, 0, 
    7, 7, 7, 7, 7, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 
    0, 0
};

/*
 * Each group represents a unique set of character attributes.  The attributes
 * are encoded into a 32-bit value as follows:
 *
 * Bits 0-4	Character category: see the constants listed below.
 *
 * Bits 5-7	Case delta type: 000 = identity
 *				 010 = add delta for lower
 *				 011 = add delta for lower, add 1 for title
 *				 100 = sutract delta for title/upper
 *				 101 = sub delta for upper, sub 1 for title
 *				 110 = sub delta for upper, add delta for lower
 *
 * Bits 8-21	Reserved for future use.
 *
 * Bits 22-31	Case delta: delta for case conversions.  This should be the
 *			    highest field so we can easily sign extend.
 */

static int groups[] = {
    0, 15, 12, 25, 27, 21, 22, 26, 20, 9, 134217793, 28, 19, 134217858, 
    29, 2, 23, 11, 24, -507510654, 4194369, 4194434, -834666431, 973078658, 
    -507510719, 1258291330, 880803905, 864026689, 859832385, 331350081, 
    847249473, 851443777, 868220993, 884998209, 876609601, 893386817, 
    897581121, 1, 914358337, 5, 910164033, 918552641, 8388705, 4194499, 
    8388770, 331350146, 880803970, 864026754, 859832450, 847249538, 
    851443842, 868221058, 876609666, 884998274, 893386882, 897581186, 
    914358402, 910164098, 918552706, 4, 6, 159383617, 155189313, 268435521, 
    264241217, 159383682, 155189378, 130023554, 268435586, 264241282, 
    260046978, 239075458, 197132418, 226492546, 360710274, 335544450, 
    335544385, 201326657, 201326722, 7, 8, 247464066, -33554302, -33554367, 
    -310378366, -360710014, -419430270, -536870782, -469761918, -528482174, 
    -37748606, -310378431, -37748671, -360710079, -419430335, -29359998, 
    -469761983, -29360063, -536870847, -528482239, 16, 13, 14, 67108938, 
    67109002, 10, 109051997, 109052061, 18, 17
};

/*
 * The following constants are used to determine the category of a
 * Unicode character.
 */

#define UNICODE_CATEGORY_MASK 0X1F

enum {
    UNASSIGNED,
    UPPERCASE_LETTER,
    LOWERCASE_LETTER,
    TITLECASE_LETTER,
    MODIFIER_LETTER,
    OTHER_LETTER,
    NON_SPACING_MARK,
    ENCLOSING_MARK,
    COMBINING_SPACING_MARK,
    DECIMAL_DIGIT_NUMBER,
    LETTER_NUMBER,
    OTHER_NUMBER,
    SPACE_SEPARATOR,
    LINE_SEPARATOR,
    PARAGRAPH_SEPARATOR,
    CONTROL,
    FORMAT,
    PRIVATE_USE,
    SURROGATE,
    CONNECTOR_PUNCTUATION,
    DASH_PUNCTUATION,
    OPEN_PUNCTUATION,
    CLOSE_PUNCTUATION,
    INITIAL_QUOTE_PUNCTUATION,
    FINAL_QUOTE_PUNCTUATION,
    OTHER_PUNCTUATION,
    MATH_SYMBOL,
    CURRENCY_SYMBOL,
    MODIFIER_SYMBOL,
    OTHER_SYMBOL
};

/*
 * The following macros extract the fields of the character info.  The
 * GetDelta() macro is complicated because we can't rely on the C compiler
 * to do sign extension on right shifts.
 */

#define GetCaseType(info) (((info) & 0xE0) >> 5)
#define GetCategory(info) ((info) & 0x1F)
#define GetDelta(infO) (((info) > 0) ? ((info) >> 22) : (~(~((info)) >> 22)))

/*
 * This macro extracts the information about a character from the
 * Unicode character tables.
 */

#define GetUniCharInfo(ch) (groups[(int)groupMap[(int)((pageMap[(((int)(ch)) & 0xffff) >> OFFSET_BITS] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1)))]])

Added generic/tclUtf.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
/*
 * tclUtf.c --
 *
 *	Routines for manipulating UTF-8 strings.
 *
 * 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: tclUtf.c,v 1.1.2.6 1999/04/02 23:44:58 stanton Exp $
 */

#include "tclInt.h"

/*
 * Include the static character classification tables and macros.
 */

#include "tclUniData.c"

/*
 * The following macros are used for fast character category tests.  The
 * x_BITS values are shifted right by the category value to determine whether
 * the given category is included in the set.
 */ 

#define ALPHA_BITS ((1 << UPPERCASE_LETTER) | (1 << LOWERCASE_LETTER) \
    | (1 << TITLECASE_LETTER) | (1 << MODIFIER_LETTER) | (1 << OTHER_LETTER))

#define DIGIT_BITS (1 << DECIMAL_DIGIT_NUMBER)

#define SPACE_BITS ((1 << SPACE_SEPARATOR) | (1 << LINE_SEPARATOR) \
    | (1 << PARAGRAPH_SEPARATOR))

#define CONNECTOR_BITS (1 << CONNECTOR_PUNCTUATION)

/*
 * Unicode characters less than this value are represented by themselves 
 * in UTF-8 strings. 
 */

#define UNICODE_SELF	0x80

/*
 * The following structures are used when mapping between Unicode (UCS-2)
 * and UTF-8.
 */
 
CONST unsigned char totalBytes[256] = {
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
#if TCL_UTF_MAX > 3
    4,4,4,4,4,4,4,4,
#else
    1,1,1,1,1,1,1,1,
#endif
#if TCL_UTF_MAX > 4
    5,5,5,5,
#else
    1,1,1,1,
#endif
#if TCL_UTF_MAX > 5
    6,6,6,6
#else
    1,1,1,1
#endif
};


/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UniCharToUtf --
 *
 *	Store the given Tcl_UniChar as a sequence of UTF-8 bytes in the
 *	provided buffer.  Equivalent to Plan 9 runetochar().
 *
 * Results:
 *	The return values is the number of bytes in the buffer that
 *	were consumed.  
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
INLINE int
Tcl_UniCharToUtf(ch, str)
    int ch;			/* The Tcl_UniChar to be stored in the
				 * buffer. */
    char *str;			/* Buffer in which the UTF-8 representation
				 * of the Tcl_UniChar is stored.  Buffer must
				 * be large enough to hold the UTF-8 character
				 * (at most TCL_UTF_MAX bytes). */
{
    if ((ch > 0) && (ch < UNICODE_SELF)) {
	str[0] = (char) ch;
	return 1;
    }
    if (ch <= 0x7FF) {
	str[1] = (char) ((ch | 0x80) & 0xBF);
	str[0] = (char) ((ch >> 6) | 0xC0);
	return 2;
    }
    if (ch <= 0xFFFF) {
	three:
	str[2] = (char) ((ch | 0x80) & 0xBF);
	str[1] = (char) (((ch >> 6) | 0x80) & 0xBF);
	str[0] = (char) ((ch >> 12) | 0xE0);
	return 3;
    }

#if TCL_UTF_MAX > 3
    if (ch <= 0x1FFFFF) {
	str[3] = (char) ((ch | 0x80) & 0xBF);
	str[2] = (char) (((ch >> 6) | 0x80) & 0xBF);
	str[1] = (char) (((ch >> 12) | 0x80) & 0xBF);
	str[0] = (char) ((ch >> 18) | 0xF0);
	return 4;
    }
    if (ch <= 0x3FFFFFF) {
	str[4] = (char) ((ch | 0x80) & 0xBF);
	str[3] = (char) (((ch >> 6) | 0x80) & 0xBF);
	str[2] = (char) (((ch >> 12) | 0x80) & 0xBF);
	str[1] = (char) (((ch >> 18) | 0x80) & 0xBF);
	str[0] = (char) ((ch >> 24) | 0xF8);
	return 5;
    }
    if (ch <= 0x7FFFFFFF) {
	str[5] = (char) ((ch | 0x80) & 0xBF);
	str[4] = (char) (((ch >> 6) | 0x80) & 0xBF);
	str[3] = (char) (((ch >> 12) | 0x80) & 0xBF);
	str[2] = (char) (((ch >> 18) | 0x80) & 0xBF);
	str[1] = (char) (((ch >> 24) | 0x80) & 0xBF);
	str[0] = (char) ((ch >> 30) | 0xFC);
	return 6;
    }
#endif

    ch = 0xFFFD;
    goto three;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UniCharToUtfDString --
 *
 *	Convert the given Unicode string to UTF-8.
 *
 * Results:
 *	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 dsPtr.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
char *
Tcl_UniCharToUtfDString(wString, numChars, dsPtr)
    CONST Tcl_UniChar *wString;	/* Unicode string to convert to UTF-8. */
    int numChars;		/* Length of Unicode string in Tcl_UniChars
				 * (must be >= 0). */
    Tcl_DString *dsPtr;		/* UTF-8 representation of string is
				 * appended to this previously initialized
				 * DString. */
{
    CONST Tcl_UniChar *w, *wEnd;
    char *p, *string;
    int oldLength;

    /*
     * UTF-8 string length in bytes will be <= Unicode string length *
     * TCL_UTF_MAX.
     */

    oldLength = Tcl_DStringLength(dsPtr);
    Tcl_DStringSetLength(dsPtr, (oldLength + numChars + 1) * TCL_UTF_MAX);
    string = Tcl_DStringValue(dsPtr) + oldLength;

    p = string;
    wEnd = wString + numChars;
    for (w = wString; w < wEnd; ) {
	p += Tcl_UniCharToUtf(*w, p);
	w++;
    }
    Tcl_DStringSetLength(dsPtr, oldLength + (p - string));

    return string;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UtfToUniChar --
 *
 *	Extract the Tcl_UniChar represented by the UTF-8 string.  Bad
 *	UTF-8 sequences are converted to valid Tcl_UniChars and processing
 *	continues.  Equivalent to Plan 9 chartorune().
 *
 *	The caller must ensure that the source buffer is long enough that
 *	this routine does not run off the end and dereference non-existent
 *	memory looking for trail bytes.  If the source buffer is known to
 *	be '\0' terminated, this cannot happen.  Otherwise, the caller
 *	should call Tcl_UtfCharComplete() before calling this routine to
 *	ensure that enough bytes remain in the string.
 *
 * Results:
 *	*chPtr is filled with the Tcl_UniChar, and the return value is the
 *	number of bytes from the UTF-8 string that were consumed.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
int
Tcl_UtfToUniChar(str, chPtr)
    register CONST char *str;	 /* The UTF-8 string. */
    register Tcl_UniChar *chPtr; /* Filled with the Tcl_UniChar represented
				  * by the UTF-8 string. */
{
    register int byte;
    
    /*
     * Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones.
     */

    byte = *((unsigned char *) str);
    if (byte < 0xC0) {
	/*
	 * Handles properly formed UTF-8 characters between 0x01 and 0x7F.
	 * Also treats \0 and naked trail bytes 0x80 to 0xBF as valid
	 * characters representing themselves.
	 */
	 
	*chPtr = (Tcl_UniChar) byte;
	return 1;
    } else if (byte < 0xE0) {
	if ((str[1] & 0xC0) == 0x80) {
	    /*
	     * Two-byte-character lead-byte followed by a trail-byte.
	     */
	     
	    *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (str[1] & 0x3F));
	    return 2;
	}
	/*
	 * A two-byte-character lead-byte not followed by trail-byte
	 * represents itself.
	 */
	 
	*chPtr = (Tcl_UniChar) byte;
	return 1;
    } else if (byte < 0xF0) {
	if (((str[1] & 0xC0) == 0x80) && ((str[2] & 0xC0) == 0x80)) {
	    /*
	     * Three-byte-character lead byte followed by two trail bytes.
	     */

	    *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) 
		    | ((str[1] & 0x3F) << 6) | (str[2] & 0x3F));
	    return 3;
	}
	/*
	 * A three-byte-character lead-byte not followed by two trail-bytes
	 * represents itself.
	 */

	*chPtr = (Tcl_UniChar) byte;
	return 1;
    }
#if TCL_UTF_MAX > 3
    else {
	int ch, total, trail;

	total = totalBytes[byte];
	trail = total - 1;
	if (trail > 0) {
	    ch = byte & (0x3F >> trail);
	    do {
		str++;
		if ((*str & 0xC0) != 0x80) {
		    *chPtr = byte;
		    return 1;
		}
		ch <<= 6;
		ch |= (*str & 0x3F);
		trail--;
	    } while (trail > 0);
	    *chPtr = ch;
	    return total;
	}
    }
#endif

    *chPtr = (Tcl_UniChar) byte;
    return 1;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UtfToUniCharDString --
 *
 *	Convert the UTF-8 string to Unicode.
 *
 * Results:
 *	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 dsPtr.  The Unicode string is terminated with a Unicode
 *	NULL character.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

Tcl_UniChar *
Tcl_UtfToUniCharDString(string, length, dsPtr)
    CONST char *string;		/* UTF-8 string to convert to Unicode. */
    int length;			/* Length of UTF-8 string in bytes, or -1
				 * for strlen(). */
    Tcl_DString *dsPtr;		/* Unicode representation of string is
				 * appended to this previously initialized
				 * DString. */
{
    Tcl_UniChar *w, *wString;
    CONST char *p, *end;
    int oldLength;

    if (length < 0) {
	length = strlen(string);
    }

    /*
     * Unicode string length in Tcl_UniChars will be <= UTF-8 string length
     * in bytes.
     */

    oldLength = Tcl_DStringLength(dsPtr);
    Tcl_DStringSetLength(dsPtr,
	    (int) ((oldLength + length + 1) * sizeof(Tcl_UniChar)));
    wString = (Tcl_UniChar *) (Tcl_DStringValue(dsPtr) + oldLength);

    w = wString;
    end = string + length;
    for (p = string; p < end; ) {
	p += Tcl_UtfToUniChar(p, w);
	w++;
    }
    *w = '\0';
    Tcl_DStringSetLength(dsPtr,
	    (oldLength + ((char *) w - (char *) wString)));

    return wString;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UtfCharComplete --
 *
 *	Determine if the UTF-8 string of the given length is long enough
 *	to be decoded by Tcl_UtfToUniChar().  This does not ensure that the
 *	UTF-8 string is properly formed.  Equivalent to Plan 9 fullrune().
 *
 * Results:
 *	The return value is 0 if the string is not long enough, non-zero
 *	otherwise.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
Tcl_UtfCharComplete(str, len)
    CONST char *str;		/* String to check if first few bytes
				 * contain a complete UTF-8 character. */
    int len;			/* Length of above string in bytes. */
{
    int ch;

    ch = *((unsigned char *) str);
    return len >= totalBytes[ch];
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_NumUtfChars --
 *
 *	Returns the number of characters (not bytes) in the UTF-8 string,
 *	not including the terminating NULL byte.  This is equivalent to
 *	Plan 9 utflen() and utfnlen().
 *
 * Results:
 *	As above.  
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
int 
Tcl_NumUtfChars(str, len)
    register CONST char *str;	/* The UTF-8 string to measure. */
    int len;			/* The length of the string in bytes, or -1
				 * for strlen(string). */
{
    Tcl_UniChar ch;
    register Tcl_UniChar *chPtr = &ch;
    register int n;
    int i;

    /*
     * The separate implementations are faster.
     */
     
    i = 0;
    if (len < 0) {
	while (1) {
	    str += Tcl_UtfToUniChar(str, chPtr);
	    if (ch == '\0') {
		break;
	    }
	    i++;
	}
    } else {
	while (len > 0) {
	    n = Tcl_UtfToUniChar(str, chPtr);
	    len -= n;
	    str += n;
	    i++;
	}
    }
    return i;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UtfFindFirst --
 *
 *	Returns a pointer to the first occurance of the given Tcl_UniChar
 *	in the NULL-terminated UTF-8 string.  The NULL terminator is
 *	considered part of the UTF-8 string.  Equivalent to Plan 9
 *	utfrune().
 *
 * Results:
 *	As above.  If the Tcl_UniChar does not exist in the given string,
 *	the return value is NULL.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
char *
Tcl_UtfFindFirst(string, ch)
    CONST char *string;		/* The UTF-8 string to be searched. */
    int ch;			/* The Tcl_UniChar to search for. */
{
    int len;
    Tcl_UniChar find;
    
    while (1) {
	len = Tcl_UtfToUniChar(string, &find);
	if (find == ch) {
	    return (char *) string;
	}
	if (*string == '\0') {
	    return NULL;
	}
	string += len;
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UtfFindLast --
 *
 *	Returns a pointer to the last occurance of the given Tcl_UniChar
 *	in the NULL-terminated UTF-8 string.  The NULL terminator is
 *	considered part of the UTF-8 string.  Equivalent to Plan 9
 *	utfrrune().
 *
 * Results:
 *	As above.  If the Tcl_UniChar does not exist in the given string,
 *	the return value is NULL.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

char *
Tcl_UtfFindLast(string, ch)
    CONST char *string;		/* The UTF-8 string to be searched. */
    int ch;			/* The Tcl_UniChar to search for. */
{
    int len;
    Tcl_UniChar find;
    CONST char *last;
	
    last = NULL;
    while (1) {
	len = Tcl_UtfToUniChar(string, &find);
	if (find == ch) {
	    last = string;
	}
	if (*string == '\0') {
	    break;
	}
	string += len;
    }
    return (char *) last;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UtfNext --
 *
 *	Given a pointer to some current location in a UTF-8 string,
 *	move forward one character.  The caller must ensure that they
 *	are not asking for the next character after the last character
 *	in the string.
 *
 * Results:
 *	The return value is the pointer to the next character in
 *	the UTF-8 string.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
char *
Tcl_UtfNext(str) 
    CONST char *str;		    /* The current location in the string. */
{
    Tcl_UniChar ch;

    return (char *) str + Tcl_UtfToUniChar(str, &ch);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UtfPrev --
 *
 *	Given a pointer to some current location in a UTF-8 string,
 *	move backwards one character.
 *
 * Results:
 *	The return value is a pointer to the previous character in the
 *	UTF-8 string.  If the current location was already at the
 *	beginning of the string, the return value will also be a
 *	pointer to the beginning of the string.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

char *
Tcl_UtfPrev(str, start)
    CONST char *str;		    /* The current location in the string. */
    CONST char *start;		    /* Pointer to the beginning of the
				     * string, to avoid going backwards too
				     * far. */
{
    CONST char *look;
    int i, byte;
    
    str--;
    look = str;
    for (i = 0; i < TCL_UTF_MAX; i++) {
	if (look < start) {
	    if (str < start) {
		str = start;
	    }
	    break;
	}
	byte = *((unsigned char *) look);
	if (byte < 0x80) {
	    break;
	} 
	if (byte >= 0xC0) {
	    if (totalBytes[byte] != i + 1) {
		break;
	    }
	    return (char *) look;
	}
	look--;
    }
    return (char *) str;
}
	
/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UniCharAtIndex --
 *
 *	Returns the Unicode character represented at the specified
 *	character (not byte) position in the UTF-8 string.
 *
 * Results:
 *	As above.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
Tcl_UniChar
Tcl_UniCharAtIndex(src, index)
    register CONST char *src;	/* The UTF-8 string to dereference. */
    register int index;		/* The position of the desired character. */
{
    Tcl_UniChar ch;

    while (index >= 0) {
	index--;
	src += Tcl_UtfToUniChar(src, &ch);
    }
    return ch;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UtfAtIndex --
 *
 *	Returns a pointer to the specified character (not byte) position
 *	in the UTF-8 string.
 *
 * Results:
 *	As above.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

char *
Tcl_UtfAtIndex(src, index)
    register CONST char *src;	/* The UTF-8 string. */
    register int index;		/* The position of the desired character. */
{
    Tcl_UniChar ch;
    
    while (index > 0) {
	index--;
	src += Tcl_UtfToUniChar(src, &ch);
    }
    return (char *) src;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UtfBackslash --
 *
 *	Figure out how to handle a backslash sequence.
 *
 * Results:
 *	Stores the bytes represented by the backslash sequence in dst and
 *	returns the number of bytes written to dst.  At most TCL_UTF_MAX
 *	bytes are written to dst; dst must have been large enough to accept
 *	those bytes.  If readPtr isn't NULL then it is filled in with a
 *	count of the number of bytes in the backslash sequence.  
 *
 * Side effects:
 *	The maximum number of bytes it takes to represent a Unicode
 *	character in UTF-8 is guaranteed to be less than the number of
 *	bytes used to express the backslash sequence that represents
 *	that Unicode character.  If the target buffer into which the
 *	caller is going to store the bytes that represent the Unicode
 *	character is at least as large as the source buffer from which
 *	the backslashed sequence was extracted, no buffer overruns should
 *	occur.
 *
 *---------------------------------------------------------------------------
 */

int
Tcl_UtfBackslash(src, readPtr, dst)
    CONST char *src;		/* Points to the backslash character of
				 * a backslash sequence. */
    int *readPtr;		/* Fill in with number of characters read
				 * from src, unless NULL. */
    char *dst;			/* Filled with the bytes represented by the
				 * backslash sequence. */
{
    register CONST char *p = src+1;
    int result, count, n;
    char buf[TCL_UTF_MAX];

    if (dst == NULL) {
	dst = buf;
    }

    count = 2;
    switch (*p) {
	/*
         * Note: in the conversions below, use absolute values (e.g.,
         * 0xa) rather than symbolic values (e.g. \n) that get converted
         * by the compiler.  It's possible that compilers on some
         * platforms will do the symbolic conversions differently, which
         * could result in non-portable Tcl scripts.
         */

        case 'a':
            result = 0x7;
            break;
        case 'b':
            result = 0x8;
            break;
        case 'f':
            result = 0xc;
            break;
        case 'n':
            result = 0xa;
            break;
        case 'r':
            result = 0xd;
            break;
        case 't':
            result = 0x9;
            break;
        case 'v':
            result = 0xb;
            break;
        case 'x':
            if (isxdigit(UCHAR(p[1]))) { /* INTL: digit */
                char *end;

                result = (unsigned char) strtoul(p+1, &end, 16);
                count = end - src;
            } else {
                count = 2;
                result = 'x';
            }
            break;
	case 'u':
	    result = 0;
	    for (count = 0; count < 4; count++) {
		p++;
		if (!isxdigit(UCHAR(*p))) { /* INTL: digit */
		    break;
		}
		n = *p - '0';
		if (n > 9) {
		    n = n + '0' + 10 - 'A';
		}
		if (n > 16) {
		    n = n + 'A' - 'a';
		}
		result = (result << 4) + n;
	    }
	    if (count == 0) {
		result = 'u';
	    }
	    count += 2;
	    break;
		    
        case '\n':
            do {
                p++;
            } while ((*p == ' ') || (*p == '\t'));
            result = ' ';
            count = p - src;
            break;
        case 0:
            result = '\\';
            count = 1;
            break;
	default:
	    if (isdigit(UCHAR(*p))) { /* INTL: digit */
		result = (unsigned char)(*p - '0');
		p++;
		if (!isdigit(UCHAR(*p))) { /* INTL: digit */
		    break;
		}
		count = 3;
		result = (unsigned char)((result << 3) + (*p - '0'));
		p++;
		if (!isdigit(UCHAR(*p))) { /* INTL: digit */
		    break;
		}
		count = 4;
		result = (unsigned char)((result << 3) + (*p - '0'));
		break;
	    }
	    result = *p;
	    count = 2;
	    break;
    }

    if (readPtr != NULL) {
	*readPtr = count;
    }
    return Tcl_UniCharToUtf(result, dst);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UtfToUpper --
 *
 *	Convert lowercase characters to uppercase characters in a UTF
 *	string in place.  The conversion may shrink the UTF string.
 *
 * Results:
 *	Returns the number of bytes in the resulting string
 *	excluding the trailing null.
 *
 * Side effects:
 *	Writes a terminating null after the last converted character.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UtfToUpper(str)
    char *str;			/* String to convert in place. */
{
    Tcl_UniChar ch;
    char *src, *dst;
    
    /*
     * Iterate over the string until we hit the terminating null.
     */

    src = dst = str;
    while (*src) {
	src += Tcl_UtfToUniChar(src, &ch);
	dst += Tcl_UniCharToUtf(Tcl_UniCharToUpper(ch), dst);
    }
    *dst = '\0';
    return (dst - str);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UtfToLower --
 *
 *	Convert uppercase characters to lowercase characters in a UTF
 *	string in place.  The conversion may shrink the UTF string.
 *
 * Results:
 *	Returns the number of bytes in the resulting string
 *	excluding the trailing null.
 *
 * Side effects:
 *	Writes a terminating null after the last converted character.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UtfToLower(str)
    char *str;			/* String to convert in place. */
{
    Tcl_UniChar ch;
    char *src, *dst;
    
    /*
     * Iterate over the string until we hit the terminating null.
     */

    src = dst = str;
    while (*src) {
	src += Tcl_UtfToUniChar(src, &ch);
	dst += Tcl_UniCharToUtf(Tcl_UniCharToLower(ch), dst);
    }
    *dst = '\0';
    return (dst - str);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UtfToTitle --
 *
 *	Changes the first character of a UTF string to title case or
 *	uppercase and the rest of the string to lowercase.  The
 *	conversion happens in place and may shrink the UTF string.
 *
 * Results:
 *	Returns the number of bytes in the resulting string
 *	excluding the trailing null.
 *
 * Side effects:
 *	Writes a terminating null after the last converted character.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UtfToTitle(str)
    char *str;			/* String to convert in place. */
{
    Tcl_UniChar ch;
    char *src, *dst;
    
    /*
     * Capitalize the first character and then lowercase the rest of the
     * characters until we get to a null.
     */

    src = dst = str;

    if (*src) {
	src += Tcl_UtfToUniChar(src, &ch);
	dst += Tcl_UniCharToUtf(Tcl_UniCharToTitle(ch), dst);
    }
    while (*src) {
	src += Tcl_UtfToUniChar(src, &ch);
	dst += Tcl_UniCharToUtf(Tcl_UniCharToLower(ch), dst);
    }
    *dst = '\0';
    return (dst - str);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharToUpper --
 *
 *	Compute the uppercase equivalent of the given Unicode character.
 *
 * Results:
 *	Returns the uppercase Unicode character.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_UniChar
Tcl_UniCharToUpper(ch)
    int ch;			/* Unicode character to convert. */
{
    int info = GetUniCharInfo(ch);

    if (GetCaseType(info) & 0x04) {
	return (Tcl_UniChar) (ch - GetDelta(info));
    } else {
	return ch;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharToLower --
 *
 *	Compute the lowercase equivalent of the given Unicode character.
 *
 * Results:
 *	Returns the lowercase Unicode character.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_UniChar
Tcl_UniCharToLower(ch)
    int ch;			/* Unicode character to convert. */
{
    int info = GetUniCharInfo(ch);

    if (GetCaseType(info) & 0x02) {
	return (Tcl_UniChar) (ch + GetDelta(info));
    } else {
	return ch;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharToTitle --
 *
 *	Compute the titlecase equivalent of the given Unicode character.
 *
 * Results:
 *	Returns the titlecase Unicode character.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_UniChar
Tcl_UniCharToTitle(ch)
    int ch;			/* Unicode character to convert. */
{
    int info = GetUniCharInfo(ch);
    int mode = GetCaseType(info);

    if (mode & 0x1) {
	/*
	 * Subtract or add one depending on the original case.
	 */

	return (Tcl_UniChar) (ch + ((mode & 0x4) ? -1 : 1));
    } else if (mode == 0x4) {
	return (Tcl_UniChar) (ch - GetDelta(info));
    } else {
	return ch;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharLen --
 *
 *	Find the length of a UniChar string.  The str input must be null
 *	terminated.
 *
 * Results:
 *	Returns the length of str in UniChars (not bytes).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UniCharLen(str)
    Tcl_UniChar *str;		/* Unicode string to find length of. */
{
    int len = 0;
    
    while (*str != '\0') {
	len++;
	str++;
    }
    return len;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharNcmp --
 *
 *	Compare at most n unichars of string cs to string ct.  Both cs
 *	and ct are assumed to be at least n unichars long.
 *
 * Results:
 *	Return <0 if cs < ct, 0 if cs == ct, or >0 if cs > ct.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UniCharNcmp(cs, ct, n)
    CONST Tcl_UniChar *cs;		/* Unicode string to compare to ct. */
    CONST Tcl_UniChar *ct;		/* Unicode string cs is compared to. */
    size_t n;				/* Number of unichars to compare. */
{
    for ( ; n != 0; n--, cs++, ct++) {
	if (*cs != *ct) {
	    return *cs - *ct;
	}
	if (*cs == '\0') {
	    break;
	}
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharIsAlnum --
 *
 *	Test if a character is an alphanumeric Unicode character.
 *
 * Results:
 *	Returns 1 if character is alphanumeric.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UniCharIsAlnum(ch)
    int ch;			/* Unicode character to test. */
{
    register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);

    return (((ALPHA_BITS | DIGIT_BITS) >> category) & 1);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharIsAlpha --
 *
 *	Test if a character is an alphabetic Unicode character.
 *
 * Results:
 *	Returns 1 if character is alphabetic.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UniCharIsAlpha(ch)
    int ch;			/* Unicode character to test. */
{
    register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);
    return ((ALPHA_BITS >> category) & 1);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharIsDigit --
 *
 *	Test if a character is a numeric Unicode character.
 *
 * Results:
 *	Returns non-zero if character is a digit.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UniCharIsDigit(ch)
    int ch;			/* Unicode character to test. */
{
    return ((GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK)
	    == DECIMAL_DIGIT_NUMBER);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharIsLower --
 *
 *	Test if a character is a lowercase Unicode character.
 *
 * Results:
 *	Returns non-zero if character is lowercase.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UniCharIsLower(ch)
    int ch;			/* Unicode character to test. */
{
    return ((GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK) == LOWERCASE_LETTER);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharIsSpace --
 *
 *	Test if a character is a whitespace Unicode character.
 *
 * Results:
 *	Returns non-zero if character is a space.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UniCharIsSpace(ch)
    int ch;			/* Unicode character to test. */
{
    register int category;

    /*
     * If the character is within the first 127 characters, just use the
     * standard C function, otherwise consult the Unicode table.
     */

    if (ch < 0x80) {
	return isspace(UCHAR(ch)); /* INTL: ISO space */
    } else {
	category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);
	return ((SPACE_BITS >> category) & 1);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharIsUpper --
 *
 *	Test if a character is a uppercase Unicode character.
 *
 * Results:
 *	Returns non-zero if character is uppercase.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UniCharIsUpper(ch)
    int ch;			/* Unicode character to test. */
{
    return ((GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK) == UPPERCASE_LETTER);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UniCharIsWordChar --
 *
 *	Test if a character is alphanumeric or a connector punctuation
 *	mark.
 *
 * Results:
 *	Returns 1 if character is a word character.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UniCharIsWordChar(ch)
    int ch;			/* Unicode character to test. */
{
    register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK);

    return (((ALPHA_BITS | DIGIT_BITS | CONNECTOR_BITS) >> category) & 1);
}

Changes to generic/tclUtil.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
/* 
 * tclUtil.c --
 *
 *	This file contains utility procedures that are used by many Tcl
 *	commands.
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclUtil.c 1.161 97/08/12 17:07:18
 */

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











/*
 * The following values are used in the flags returned by Tcl_ScanElement
 * and used by Tcl_ConvertElement.  The value TCL_DONT_USE_BRACES is also
 * defined in tcl.h;  make sure its value doesn't overlap with any of the
 * values below.
 *
 * TCL_DONT_USE_BRACES -	1 means the string mustn't be enclosed 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
/* 
 * tclUtil.c --
 *
 *	This file contains utility procedures that are used by many Tcl
 *	commands.
 *
 * Copyright (c) 1987-1993 The Regents of the University of California.
 * Copyright (c) 1994-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: tclUtil.c,v 1.1.2.10 1999/04/06 04:27:02 rjohnson Exp $
 */

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

/*
 * The following variable holds the full path name of the binary
 * from which this application was executed, or NULL if it isn't
 * know.  The value of the variable is set by the procedure
 * Tcl_FindExecutable.  The storage space is dynamically allocated.
 */

char *tclExecutableName = NULL;
char *tclNativeExecutableName = NULL;

/*
 * The following values are used in the flags returned by Tcl_ScanElement
 * and used by Tcl_ConvertElement.  The value TCL_DONT_USE_BRACES is also
 * defined in tcl.h;  make sure its value doesn't overlap with any of the
 * values below.
 *
 * TCL_DONT_USE_BRACES -	1 means the string mustn't be enclosed in
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
#define BRACES_UNMATCHED	4

/*
 * The following values determine the precision used when converting
 * floating-point values to strings.  This information is linked to all
 * of the tcl_precision variables in all interpreters via the procedure
 * TclPrecTraceProc.
 *
 * NOTE: these variables are not thread-safe.
 */

static char precisionString[10] = "12";
				/* The string value of all the tcl_precision
				 * variables. */
static char precisionFormat[10] = "%.12g";
				/* The format string actually used in calls
				 * to sprintf. */


/*
 * Function prototypes for local procedures in this file:
 */

static void		SetupAppendBuffer _ANSI_ARGS_((Interp *iPtr,
			    int newSpace));

/*
 *----------------------------------------------------------------------
 *
 * TclFindElement --
 *
 *	Given a pointer into a Tcl list, locate the first (or next)
 *	element in the list.
 *
 * Results:
 *	The return value is normally TCL_OK, which means that the
 *	element was successfully located.  If TCL_ERROR is returned
 *	it means that list didn't have proper list structure;
 *	interp->result contains a more detailed error message.
 *
 *	If TCL_OK is returned, then *elementPtr will be set to point to the
 *	first element of list, and *nextPtr will be set to point to the
 *	character just after any white space following the last character
 *	that's part of the element. If this is the last argument in the
 *	list, then *nextPtr will point just after the last character in the
 *	list (i.e., at the character at list+listLength). If sizePtr is







<
<








|

<
<
<
<
<
<













|







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
#define BRACES_UNMATCHED	4

/*
 * The following values determine the precision used when converting
 * floating-point values to strings.  This information is linked to all
 * of the tcl_precision variables in all interpreters via the procedure
 * TclPrecTraceProc.


 */

static char precisionString[10] = "12";
				/* The string value of all the tcl_precision
				 * variables. */
static char precisionFormat[10] = "%.12g";
				/* The format string actually used in calls
				 * to sprintf. */
TCL_DECLARE_MUTEX(precisionMutex)








/*
 *----------------------------------------------------------------------
 *
 * TclFindElement --
 *
 *	Given a pointer into a Tcl list, locate the first (or next)
 *	element in the list.
 *
 * Results:
 *	The return value is normally TCL_OK, which means that the
 *	element was successfully located.  If TCL_ERROR is returned
 *	it means that list didn't have proper list structure;
 *	the interp's result contains a more detailed error message.
 *
 *	If TCL_OK is returned, then *elementPtr will be set to point to the
 *	first element of list, and *nextPtr will be set to point to the
 *	character just after any white space following the last character
 *	that's part of the element. If this is the last argument in the
 *	list, then *nextPtr will point just after the last character in the
 *	list (i.e., at the character at list+listLength). If sizePtr is
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

int
TclFindElement(interp, list, listLength, elementPtr, nextPtr, sizePtr,
	       bracePtr)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting. 
				 * If NULL, then no error message is left
				 * after errors. */
    char *list;			/* Points to the first byte of a string
				 * containing a Tcl list with zero or more
				 * elements (possibly in braces). */
    int listLength;		/* Number of bytes in the list's string. */
    char **elementPtr;		/* Where to put address of first significant
				 * character in first element of list. */
    char **nextPtr;		/* Fill in with location of character just
				 * after all white space following end of
				 * argument (next arg or end of list). */
    int *sizePtr;		/* If non-zero, fill in with size of
				 * element. */
    int *bracePtr;		/* If non-zero, fill in with non-zero/zero
				 * to indicate that arg was/wasn't
				 * in braces. */
{
    char *p = list;
    char *elemStart;		/* Points to first byte of first element. */
    char *limit;		/* Points just after list's last byte. */
    int openBraces = 0;		/* Brace nesting level during parse. */
    int inQuotes = 0;
    int size = 0;		/* Init. avoids compiler warning. */
    int numChars;
    char *p2;
    
    /*
     * Skim off leading white space and check for an opening brace or
     * quote. We treat embedded NULLs in the list as bytes belonging to
     * a list element. Note: use of "isascii" below and elsewhere in this
     * procedure is a temporary hack (7/27/90) because Mx uses characters
     * with the high-order bit set for some things. This should probably
     * be changed back eventually, or all of Tcl should call isascii.
     */

    limit = (list + listLength);
    while ((p < limit) && (isspace(UCHAR(*p)))) {
	p++;
    }
    if (p == limit) {		/* no element found */
	elemStart = limit;
	goto done;
    }








|



|

|








|
|
|


|

|




|
<
<
<



|







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

int
TclFindElement(interp, list, listLength, elementPtr, nextPtr, sizePtr,
	       bracePtr)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting. 
				 * If NULL, then no error message is left
				 * after errors. */
    CONST char *list;		/* Points to the first byte of a string
				 * containing a Tcl list with zero or more
				 * elements (possibly in braces). */
    int listLength;		/* Number of bytes in the list's string. */
    CONST char **elementPtr;	/* Where to put address of first significant
				 * character in first element of list. */
    CONST char **nextPtr;	/* Fill in with location of character just
				 * after all white space following end of
				 * argument (next arg or end of list). */
    int *sizePtr;		/* If non-zero, fill in with size of
				 * element. */
    int *bracePtr;		/* If non-zero, fill in with non-zero/zero
				 * to indicate that arg was/wasn't
				 * in braces. */
{
    CONST char *p = list;
    CONST char *elemStart;	/* Points to first byte of first element. */
    CONST char *limit;		/* Points just after list's last byte. */
    int openBraces = 0;		/* Brace nesting level during parse. */
    int inQuotes = 0;
    int size = 0;		/* lint. */
    int numChars;
    CONST char *p2;
    
    /*
     * Skim off leading white space and check for an opening brace or
     * quote. We treat embedded NULLs in the list as bytes belonging to
     * a list element.



     */

    limit = (list + listLength);
    while ((p < limit) && (isspace(UCHAR(*p)))) { /* INTL: ISO space. */
	p++;
    }
    if (p == limit) {		/* no element found */
	elemStart = limit;
	goto done;
    }

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

	    case '}':
		if (openBraces > 1) {
		    openBraces--;
		} else if (openBraces == 1) {
		    size = (p - elemStart);
		    p++;
		    if ((p >= limit) || isspace(UCHAR(*p))) {

			goto done;
		    }

		    /*
		     * Garbage after the closing brace; return an error.
		     */
		    
		    if (interp != NULL) {
			char buf[100];
			
			p2 = p;
			while ((p2 < limit) && (!isspace(UCHAR(*p2)))

			        && (p2 < p+20)) {
			    p2++;
			}
			sprintf(buf,
				"list element in braces followed by \"%.*s\" instead of space",
				(int) (p2-p), p);
			Tcl_SetResult(interp, buf, TCL_VOLATILE);
		    }
		    return TCL_ERROR;
		}
		break;

	    /*
	     * Backslash:  skip over everything up to the end of the
	     * backslash sequence.
	     */

	    case '\\': {
		(void) Tcl_Backslash(p, &numChars);
		p += (numChars - 1);
		break;
	    }

	    /*
	     * Space: ignore if element is in braces or quotes; otherwise
	     * terminate element.







|
>











|
>


















|







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

	    case '}':
		if (openBraces > 1) {
		    openBraces--;
		} else if (openBraces == 1) {
		    size = (p - elemStart);
		    p++;
		    if ((p >= limit)
			    || isspace(UCHAR(*p))) { /* INTL: ISO space. */
			goto done;
		    }

		    /*
		     * Garbage after the closing brace; return an error.
		     */
		    
		    if (interp != NULL) {
			char buf[100];
			
			p2 = p;
			while ((p2 < limit)
				&& (!isspace(UCHAR(*p2))) /* INTL: ISO space. */
			        && (p2 < p+20)) {
			    p2++;
			}
			sprintf(buf,
				"list element in braces followed by \"%.*s\" instead of space",
				(int) (p2-p), p);
			Tcl_SetResult(interp, buf, TCL_VOLATILE);
		    }
		    return TCL_ERROR;
		}
		break;

	    /*
	     * Backslash:  skip over everything up to the end of the
	     * backslash sequence.
	     */

	    case '\\': {
		Tcl_UtfBackslash(p, &numChars, NULL);
		p += (numChars - 1);
		break;
	    }

	    /*
	     * Space: ignore if element is in braces or quotes; otherwise
	     * terminate element.
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
	     * Double-quote: if element is in quotes then terminate it.
	     */

	    case '"':
		if (inQuotes) {
		    size = (p - elemStart);
		    p++;
		    if ((p >= limit) || isspace(UCHAR(*p))) {

			goto done;
		    }

		    /*
		     * Garbage after the closing quote; return an error.
		     */
		    
		    if (interp != NULL) {
			char buf[100];
			
			p2 = p;
			while ((p2 < limit) && (!isspace(UCHAR(*p2)))

				 && (p2 < p+20)) {
			    p2++;
			}
			sprintf(buf,
				"list element in quotes followed by \"%.*s\" %s",
				(int) (p2-p), p, "instead of space");
			Tcl_SetResult(interp, buf, TCL_VOLATILE);







|
>











|
>







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
	     * Double-quote: if element is in quotes then terminate it.
	     */

	    case '"':
		if (inQuotes) {
		    size = (p - elemStart);
		    p++;
		    if ((p >= limit)
			    || isspace(UCHAR(*p))) { /* INTL: ISO space */
			goto done;
		    }

		    /*
		     * Garbage after the closing quote; return an error.
		     */
		    
		    if (interp != NULL) {
			char buf[100];
			
			p2 = p;
			while ((p2 < limit)
				&& (!isspace(UCHAR(*p2))) /* INTL: ISO space */
				 && (p2 < p+20)) {
			    p2++;
			}
			sprintf(buf,
				"list element in quotes followed by \"%.*s\" %s",
				(int) (p2-p), p, "instead of space");
			Tcl_SetResult(interp, buf, TCL_VOLATILE);
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
	    }
	    return TCL_ERROR;
	}
	size = (p - elemStart);
    }

    done:
    while ((p < limit) && (isspace(UCHAR(*p)))) {
	p++;
    }
    *elementPtr = elemStart;
    *nextPtr = p;
    if (sizePtr != 0) {
	*sizePtr = size;
    }







|







295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
	    }
	    return TCL_ERROR;
	}
	size = (p - elemStart);
    }

    done:
    while ((p < limit) && (isspace(UCHAR(*p)))) { /* INTL: ISO space. */
	p++;
    }
    *elementPtr = elemStart;
    *nextPtr = p;
    if (sizePtr != 0) {
	*sizePtr = size;
    }
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
 *
 *----------------------------------------------------------------------
 */

int
TclCopyAndCollapse(count, src, dst)
    int count;			/* Number of characters to copy from src. */
    char *src;			/* Copy from here... */
    char *dst;			/* ... to here. */
{
    char c;
    int numRead;
    int newCount = 0;


    for (c = *src;  count > 0;  src++, c = *src, count--) {
	if (c == '\\') {
	    *dst = Tcl_Backslash(src, &numRead);
	    dst++;

	    src += numRead-1;
	    count -= numRead-1;
	    newCount++;
	} else {
	    *dst = c;
	    dst++;
	    newCount++;
	}
    }
    *dst = 0;







|


|


>



|
|
>


<







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

int
TclCopyAndCollapse(count, src, dst)
    int count;			/* Number of characters to copy from src. */
    CONST char *src;		/* Copy from here... */
    char *dst;			/* ... to here. */
{
    register char c;
    int numRead;
    int newCount = 0;
    int backslashCount;

    for (c = *src;  count > 0;  src++, c = *src, count--) {
	if (c == '\\') {
	    backslashCount = Tcl_UtfBackslash(src, &numRead, dst);
	    dst += backslashCount;
	    newCount += backslashCount;
	    src += numRead-1;
	    count -= numRead-1;

	} else {
	    *dst = c;
	    dst++;
	    newCount++;
	}
    }
    *dst = 0;
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
 *
 *	Splits a list up into its constituent fields.
 *
 * Results
 *	The return value is normally TCL_OK, which means that
 *	the list was successfully split up.  If TCL_ERROR is
 *	returned, it means that "list" didn't have proper list
 *	structure;  interp->result will contain a more detailed
 *	error message.
 *
 *	*argvPtr will be filled in with the address of an array
 *	whose elements point to the elements of list, in order.
 *	*argcPtr will get filled in with the number of valid elements
 *	in the array.  A single block of memory is dynamically allocated
 *	to hold both the argv array and a copy of the list (with







|







365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
 *
 *	Splits a list up into its constituent fields.
 *
 * Results
 *	The return value is normally TCL_OK, which means that
 *	the list was successfully split up.  If TCL_ERROR is
 *	returned, it means that "list" didn't have proper list
 *	structure;  the interp's result will contain a more detailed
 *	error message.
 *
 *	*argvPtr will be filled in with the address of an array
 *	whose elements point to the elements of list, in order.
 *	*argcPtr will get filled in with the number of valid elements
 *	in the array.  A single block of memory is dynamically allocated
 *	to hold both the argv array and a copy of the list (with
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
 *----------------------------------------------------------------------
 */

int
Tcl_SplitList(interp, list, argcPtr, argvPtr)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting. 
				 * If NULL, no error message is left. */
    char *list;			/* Pointer to string with list structure. */
    int *argcPtr;		/* Pointer to location to fill in with
				 * the number of elements in the list. */
    char ***argvPtr;		/* Pointer to place to store pointer to
				 * array of pointers to list elements. */
{
    char **argv;

    char *p;
    int length, size, i, result, elSize, brace;
    char *element;

    /*
     * Figure out how much space to allocate.  There must be enough
     * space for both the array of pointers and also for a copy of
     * the list.  To estimate the number of pointers needed, count
     * the number of space characters in the list.
     */

    for (size = 1, p = list; *p != 0; p++) {
	if (isspace(UCHAR(*p))) {
	    size++;
	}
    }
    size++;			/* Leave space for final NULL pointer. */
    argv = (char **) ckalloc((unsigned)
	    ((size * sizeof(char *)) + (p - list) + 1));
    length = strlen(list);
    for (i = 0, p = ((char *) argv) + size*sizeof(char *);
	    *list != 0;  i++) {
	char *prevList = list;
	
	result = TclFindElement(interp, list, length, &element,
				&list, &elSize, &brace);
	length -= (list - prevList);
	if (result != TCL_OK) {
	    ckfree((char *) argv);
	    return result;







|






>


|








|
|





|



|







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

int
Tcl_SplitList(interp, list, argcPtr, argvPtr)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting. 
				 * If NULL, no error message is left. */
    CONST char *list;		/* Pointer to string with list structure. */
    int *argcPtr;		/* Pointer to location to fill in with
				 * the number of elements in the list. */
    char ***argvPtr;		/* Pointer to place to store pointer to
				 * array of pointers to list elements. */
{
    char **argv;
    CONST char *l;
    char *p;
    int length, size, i, result, elSize, brace;
    CONST char *element;

    /*
     * Figure out how much space to allocate.  There must be enough
     * space for both the array of pointers and also for a copy of
     * the list.  To estimate the number of pointers needed, count
     * the number of space characters in the list.
     */

    for (size = 1, l = list; *l != 0; l++) {
	if (isspace(UCHAR(*l))) { /* INTL: ISO space. */
	    size++;
	}
    }
    size++;			/* Leave space for final NULL pointer. */
    argv = (char **) ckalloc((unsigned)
	    ((size * sizeof(char *)) + (l - list) + 1));
    length = strlen(list);
    for (i = 0, p = ((char *) argv) + size*sizeof(char *);
	    *list != 0;  i++) {
	CONST char *prevList = list;
	
	result = TclFindElement(interp, list, length, &element,
				&list, &elSize, &brace);
	length -= (list - prevList);
	if (result != TCL_OK) {
	    ckfree((char *) argv);
	    return result;
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ScanElement(string, flagPtr)
    CONST char *string;		/* String to convert to Tcl list element. */
    int *flagPtr;		/* Where to store information to guide
				 * Tcl_ConvertCountedElement. */
{
    return Tcl_ScanCountedElement(string, -1, flagPtr);
}

/*
 *----------------------------------------------------------------------
 *







|
|
|







481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ScanElement(string, flagPtr)
    register CONST char *string; /* String to convert to list element. */
    register int *flagPtr;	 /* Where to store information to guide
				  * Tcl_ConvertCountedElement. */
{
    return Tcl_ScanCountedElement(string, -1, flagPtr);
}

/*
 *----------------------------------------------------------------------
 *
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
Tcl_ScanCountedElement(string, length, flagPtr)
    CONST char *string;		/* String to convert to Tcl list element. */
    int length;			/* Number of bytes in string, or -1. */
    int *flagPtr;		/* Where to store information to guide
				 * Tcl_ConvertElement. */
{
    int flags, nestingLevel;
    CONST char *p, *lastChar;

    /*
     * This procedure and Tcl_ConvertElement together do two things:
     *
     * 1. They produce a proper list, one that will yield back the
     * argument strings when evaluated or when disassembled with
     * Tcl_SplitList.  This is the most important thing.







|







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
Tcl_ScanCountedElement(string, length, flagPtr)
    CONST char *string;		/* String to convert to Tcl list element. */
    int length;			/* Number of bytes in string, or -1. */
    int *flagPtr;		/* Where to store information to guide
				 * Tcl_ConvertElement. */
{
    int flags, nestingLevel;
    register CONST char *p, *lastChar;

    /*
     * This procedure and Tcl_ConvertElement together do two things:
     *
     * 1. They produce a proper list, one that will yield back the
     * argument strings when evaluated or when disassembled with
     * Tcl_SplitList.  This is the most important thing.
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
		break;
	    case '\\':
		if ((p+1 == lastChar) || (p[1] == '\n')) {
		    flags = TCL_DONT_USE_BRACES | BRACES_UNMATCHED;
		} else {
		    int size;

		    (void) Tcl_Backslash(p, &size);
		    p += size-1;
		    flags |= USE_BRACES;
		}
		break;
	}
    }
    if (nestingLevel != 0) {







|







605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
		break;
	    case '\\':
		if ((p+1 == lastChar) || (p[1] == '\n')) {
		    flags = TCL_DONT_USE_BRACES | BRACES_UNMATCHED;
		} else {
		    int size;

		    Tcl_UtfBackslash(p, &size, NULL);
		    p += size-1;
		    flags |= USE_BRACES;
		}
		break;
	}
    }
    if (nestingLevel != 0) {
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ConvertElement(src, dst, flags)
    CONST char *src;		/* Source information for list element. */
    char *dst;			/* Place to put list-ified element. */
    int flags;			/* Flags produced by Tcl_ScanElement. */
{
    return Tcl_ConvertCountedElement(src, -1, dst, flags);
}

/*
 *----------------------------------------------------------------------
 *







|
|
|







649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ConvertElement(src, dst, flags)
    register CONST char *src;	/* Source information for list element. */
    register char *dst;		/* Place to put list-ified element. */
    register int flags;		/* Flags produced by Tcl_ScanElement. */
{
    return Tcl_ConvertCountedElement(src, -1, dst, flags);
}

/*
 *----------------------------------------------------------------------
 *
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ConvertCountedElement(src, length, dst, flags)
    CONST char *src;		/* Source information for list element. */
    int length;			/* Number of bytes in src, or -1. */
    char *dst;			/* Place to put list-ified element. */
    int flags;			/* Flags produced by Tcl_ScanElement. */
{
    char *p = dst;
    CONST char *lastChar;

    /*
     * See the comment block at the beginning of the Tcl_ScanElement
     * code for details of how this works.
     */

    if (src && length == -1) {







|




|
|







681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_ConvertCountedElement(src, length, dst, flags)
    register CONST char *src;	/* Source information for list element. */
    int length;			/* Number of bytes in src, or -1. */
    char *dst;			/* Place to put list-ified element. */
    int flags;			/* Flags produced by Tcl_ScanElement. */
{
    register char *p = dst;
    register CONST char *lastChar;

    /*
     * See the comment block at the beginning of the Tcl_ScanElement
     * code for details of how this works.
     */

    if (src && length == -1) {
863
864
865
866
867
868
869


































870
871
872
873
874
875
876
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *


































 * Tcl_Concat --
 *
 *	Concatenate a set of strings into a single large string.
 *
 * Results:
 *	The return value is dynamically-allocated string containing
 *	a concatenation of all the strings in argv, with spaces between







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







868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Backslash --
 *
 *	Figure out how to handle a backslash sequence.
 *
 * Results:
 *	The return value is the character that should be substituted
 *	in place of the backslash sequence that starts at src.  If
 *	readPtr isn't NULL then it is filled in with a count of the
 *	number of characters in the backslash sequence.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char
Tcl_Backslash(src, readPtr)
    CONST char *src;		/* Points to the backslash character of
				 * a backslash sequence. */
    int *readPtr;		/* Fill in with number of characters read
				 * from src, unless NULL. */
{
    char buf[TCL_UTF_MAX];
    Tcl_UniChar ch;

    Tcl_UtfBackslash(src, readPtr, buf);
    Tcl_UtfToUniChar(buf, &ch);
    return (char) ch;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Concat --
 *
 *	Concatenate a set of strings into a single large string.
 *
 * Results:
 *	The return value is dynamically-allocated string containing
 *	a concatenation of all the strings in argv, with spaces between
907
908
909
910
911
912
913
914
915
916
917

918
919
920
921
922
923
924
925
926
927
	/*
	 * Clip white space off the front and back of the string
	 * to generate a neater result, and ignore any empty
	 * elements.
	 */

	element = argv[i];
	while (isspace(UCHAR(*element))) {
	    element++;
	}
	for (length = strlen(element);

		(length > 0) && (isspace(UCHAR(element[length-1])))
		&& ((length < 2) || (element[length-2] != '\\'));
		length--) {
	    /* Null loop body. */
	}
	if (length == 0) {
	    continue;
	}
	memcpy((VOID *) p, (VOID *) element, (size_t) length);
	p += length;







|



>
|

|







946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
	/*
	 * Clip white space off the front and back of the string
	 * to generate a neater result, and ignore any empty
	 * elements.
	 */

	element = argv[i];
	while (isspace(UCHAR(*element))) { /* INTL: ISO space. */
	    element++;
	}
	for (length = strlen(element);
		(length > 0)
		&& (isspace(UCHAR(element[length-1]))) /* INTL: ISO space. */
		&& ((length < 2) || (element[length-2] != '\\'));
	        length--) {
	    /* Null loop body. */
	}
	if (length == 0) {
	    continue;
	}
	memcpy((VOID *) p, (VOID *) element, (size_t) length);
	p += length;
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
    char *element;
    char *concatStr;
    Tcl_Obj *objPtr;

    allocSize = 0;
    for (i = 0;  i < objc;  i++) {
	objPtr = objv[i];
	element = TclGetStringFromObj(objPtr, &length);
	if ((element != NULL) && (length > 0)) {
	    allocSize += (length + 1);
	}
    }
    if (allocSize == 0) {
	allocSize = 1;		/* enough for the NULL byte at end */
    }







|







1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
    char *element;
    char *concatStr;
    Tcl_Obj *objPtr;

    allocSize = 0;
    for (i = 0;  i < objc;  i++) {
	objPtr = objv[i];
	element = Tcl_GetStringFromObj(objPtr, &length);
	if ((element != NULL) && (length > 0)) {
	    allocSize += (length + 1);
	}
    }
    if (allocSize == 0) {
	allocSize = 1;		/* enough for the NULL byte at end */
    }
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
    finalSize = 0;
    if (objc == 0) {
	*concatStr = '\0';
    } else {
	p = concatStr;
        for (i = 0;  i < objc;  i++) {
	    objPtr = objv[i];
	    element = TclGetStringFromObj(objPtr, &elemLength);
	    while ((elemLength > 0) && (isspace(UCHAR(*element)))) {

	         element++;
		 elemLength--;
	    }

	    /*
	     * Trim trailing white space.  But, be careful not to trim
	     * a space character if it is preceded by a backslash: in
	     * this case it could be significant.
	     */

	    while ((elemLength > 0)
		    && isspace(UCHAR(element[elemLength-1]))
		    && ((elemLength < 2) || (element[elemLength-2] != '\\'))) {
		elemLength--;
	    }
	    if (elemLength == 0) {
	         continue;	/* nothing left of this element */
	    }
	    memcpy((VOID *) p, (VOID *) element, (size_t) elemLength);







|
|
>











|







1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
    finalSize = 0;
    if (objc == 0) {
	*concatStr = '\0';
    } else {
	p = concatStr;
        for (i = 0;  i < objc;  i++) {
	    objPtr = objv[i];
	    element = Tcl_GetStringFromObj(objPtr, &elemLength);
	    while ((elemLength > 0)
		    && (isspace(UCHAR(*element)))) { /* INTL: ISO space. */
	         element++;
		 elemLength--;
	    }

	    /*
	     * Trim trailing white space.  But, be careful not to trim
	     * a space character if it is preceded by a backslash: in
	     * this case it could be significant.
	     */

	    while ((elemLength > 0)
		    && isspace(UCHAR(element[elemLength-1])) /* INTL: ISO space. */
		    && ((elemLength < 2) || (element[elemLength-2] != '\\'))) {
		elemLength--;
	    }
	    if (elemLength == 0) {
	         continue;	/* nothing left of this element */
	    }
	    memcpy((VOID *) p, (VOID *) element, (size_t) elemLength);
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065

1066
1067
1068




1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111

1112



1113
1114
1115
1116
1117
1118
1119
1120


1121


1122
1123
1124
1125

1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136





1137
1138
1139

1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151


1152
1153
1154
1155
1156
1157
1158
1159
1160

1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_StringMatch(string, pattern)
    char *string;		/* String. */
    char *pattern;		/* Pattern, which may contain special
				 * characters. */
{

    char c2;

    while (1) {




	/* See if we're at the end of both the pattern and the string.
	 * If so, we succeeded.  If we're at the end of the pattern
	 * but not at the end of the string, we failed.
	 */
	
	if (*pattern == 0) {
	    if (*string == 0) {
		return 1;
	    } else {
		return 0;
	    }
	}
	if ((*string == 0) && (*pattern != '*')) {
	    return 0;
	}

	/* Check for a "*" as the next pattern character.  It matches
	 * any substring.  We handle this by calling ourselves
	 * recursively for each postfix of string, until either we
	 * match or we reach the end of the string.
	 */
	
	if (*pattern == '*') {
	    pattern += 1;
	    if (*pattern == 0) {
		return 1;
	    }
	    while (1) {
		if (Tcl_StringMatch(string, pattern)) {
		    return 1;
		}
		if (*string == 0) {
		    return 0;
		}
		string += 1;
	    }
	}
    
	/* Check for a "?" as the next pattern character.  It matches
	 * any single character.
	 */

	if (*pattern == '?') {

	    goto thisCharOK;



	}

	/* Check for a "[" as the next pattern character.  It is followed
	 * by a list of characters that are acceptable, or by a range
	 * (two characters separated by "-").
	 */
	
	if (*pattern == '[') {


	    pattern += 1;


	    while (1) {
		if ((*pattern == ']') || (*pattern == 0)) {
		    return 0;
		}

		if (*pattern == *string) {
		    break;
		}
		if (pattern[1] == '-') {
		    c2 = pattern[2];
		    if (c2 == 0) {
			return 0;
		    }
		    if ((*pattern <= *string) && (c2 >= *string)) {
			break;
		    }





		    if ((*pattern >= *string) && (c2 <= *string)) {
			break;
		    }

		    pattern += 2;
		}
		pattern += 1;
	    }
	    while (*pattern != ']') {
		if (*pattern == 0) {
		    pattern--;
		    break;
		}
		pattern += 1;
	    }
	    goto thisCharOK;


	}
    
	/* If the next pattern character is '/', just strip off the '/'
	 * so we do exact matching on the character that follows.
	 */
	
	if (*pattern == '\\') {
	    pattern += 1;
	    if (*pattern == 0) {

		return 0;
	    }
	}

	/* There's no special character.  Just make sure that the next
	 * characters of each string match.
	 */
	
	if (*pattern != *string) {
	    return 0;
	}

	thisCharOK: pattern += 1;
	string += 1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetResult --
 *
 *	Arrange for "string" to be the Tcl return value.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	interp->result is left pointing either to "string" (if "copy" is 0)
 *	or to a copy of string. Also, the object result is reset.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetResult(interp, string, freeProc)
    Tcl_Interp *interp;		/* Interpreter with which to associate the
				 * return value. */
    char *string;		/* Value to be returned.  If NULL, the
				 * result is set to an empty string. */
    Tcl_FreeProc *freeProc;	/* Gives information about the string:
				 * TCL_STATIC, TCL_VOLATILE, or the address
				 * of a Tcl_FreeProc such as free. */
{
    Interp *iPtr = (Interp *) interp;
    int length;
    Tcl_FreeProc *oldFreeProc = iPtr->freeProc;
    char *oldResult = iPtr->result;

    if (string == NULL) {
	iPtr->resultSpace[0] = 0;
	iPtr->result = iPtr->resultSpace;
	iPtr->freeProc = 0;
    } else if (freeProc == TCL_VOLATILE) {
	length = strlen(string);
	if (length > TCL_RESULT_SIZE) {
	    iPtr->result = (char *) ckalloc((unsigned) length+1);
	    iPtr->freeProc = TCL_DYNAMIC;
	} else {
	    iPtr->result = iPtr->resultSpace;
	    iPtr->freeProc = 0;
	}
	strcpy(iPtr->result, string);
    } else {
	iPtr->result = string;
	iPtr->freeProc = freeProc;
    }

    /*
     * If the old result was dynamically-allocated, free it up.  Do it
     * here, rather than at the beginning, in case the new result value
     * was part of the old result value.
     */

    if (oldFreeProc != 0) {
	if ((oldFreeProc == TCL_DYNAMIC)
		|| (oldFreeProc == (Tcl_FreeProc *) free)) {
	    ckfree(oldResult);
	} else {
	    (*oldFreeProc)(oldResult);
	}
    }

    /*
     * Reset the object result since we just set the string result.
     */

    TclResetObjResult(iPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetStringResult --
 *
 *	Returns an interpreter's result value as a string.
 *
 * Results:
 *	The interpreter's result as a string.
 *
 * Side effects:
 *	If the string result is empty, the object result is moved to the
 *	string result, then the object result is reset.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_GetStringResult(interp)
     Tcl_Interp *interp;	/* Interpreter whose result to return. */
{
    /*
     * If the string result is empty, move the object result to the
     * string result, then reset the object result.
     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
     */
    
    if (*(interp->result) == 0) {
	Tcl_SetResult(interp,
	        TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
	        TCL_VOLATILE);
    }
    return interp->result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetObjResult --
 *
 *	Arrange for objPtr to be an interpreter's result value.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	interp->objResultPtr is left pointing to the object referenced
 *	by objPtr. The object's reference count is incremented since
 *	there is now a new reference to it. The reference count for any
 *	old objResultPtr value is decremented. Also, the string result
 *	is reset.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetObjResult(interp, objPtr)
    Tcl_Interp *interp;		/* Interpreter with which to associate the
				 * return object value. */
    Tcl_Obj *objPtr;		/* Tcl object to be returned. If NULL, the
				 * obj result is made an empty string
				 * object. */
{
    Interp *iPtr = (Interp *) interp;
    Tcl_Obj *oldObjResult = iPtr->objResultPtr;

    iPtr->objResultPtr = objPtr;
    Tcl_IncrRefCount(objPtr);	/* since interp result is a reference */

    /*
     * We wait until the end to release the old object result, in case
     * we are setting the result to itself.
     */
    
    TclDecrRefCount(oldObjResult);

    /*
     * Reset the string result since we just set the result object.
     */

    if (iPtr->freeProc != NULL) {
	if ((iPtr->freeProc == TCL_DYNAMIC)
	        || (iPtr->freeProc == (Tcl_FreeProc *) free)) {
	    ckfree(iPtr->result);
	} else {
	    (*iPtr->freeProc)(iPtr->result);
	}
	iPtr->freeProc = 0;
    }
    iPtr->result = iPtr->resultSpace;
    iPtr->resultSpace[0] = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetObjResult --
 *
 *	Returns an interpreter's result value as a Tcl object. The object's
 *	reference count is not modified; the caller must do that if it
 *	needs to hold on to a long-term reference to it.
 *
 * Results:
 *	The interpreter's result as an object.
 *
 * Side effects:
 *	If the interpreter has a non-empty string result, the result object
 *	is either empty or stale because some procedure set interp->result
 *	directly. If so, the string result is moved to the result object
 *	then the string result is reset.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tcl_GetObjResult(interp)
    Tcl_Interp *interp;		/* Interpreter whose result to return. */
{
    Interp *iPtr = (Interp *) interp;
    Tcl_Obj *objResultPtr;
    int length;

    /*
     * If the string result is non-empty, move the string result to the
     * object result, then reset the string result.
     */
    
    if (*(iPtr->result) != 0) {
	TclResetObjResult(iPtr);
	
	objResultPtr = iPtr->objResultPtr;
	length = strlen(iPtr->result);
	TclInitStringRep(objResultPtr, iPtr->result, length);
	
	if (iPtr->freeProc != NULL) {
	    if ((iPtr->freeProc == TCL_DYNAMIC)
	            || (iPtr->freeProc == (Tcl_FreeProc *) free)) {
		ckfree(iPtr->result);
	    } else {
		(*iPtr->freeProc)(iPtr->result);
	    }
	    iPtr->freeProc = 0;
	}
	iPtr->result = iPtr->resultSpace;
	iPtr->resultSpace[0] = 0;
    }
    return iPtr->objResultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppendResult --
 *
 *	Append a variable number of strings onto the interpreter's string
 *	result.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The result of the interpreter given by the first argument is
 *	extended by the strings given by the second and following arguments
 *	(up to a terminating NULL argument).
 *
 *	If the string result is empty, the object result is moved to the
 *	string result, then the object result is reset.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AppendResult TCL_VARARGS_DEF(Tcl_Interp *,arg1)
{
    va_list argList;
    Interp *iPtr;
    char *string;
    int newSpace;

    /*
     * If the string result is empty, move the object result to the
     * string result, then reset the object result.
     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
     */

    iPtr = (Interp *) TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
    if (*(iPtr->result) == 0) {
	Tcl_SetResult((Tcl_Interp *) iPtr,
	        TclGetStringFromObj(Tcl_GetObjResult((Tcl_Interp *) iPtr),
		        (int *) NULL),
	        TCL_VOLATILE);
    }
    
    /*
     * Scan through all the arguments to see how much space is needed.
     */

    newSpace = 0;
    while (1) {
	string = va_arg(argList, char *);
	if (string == NULL) {
	    break;
	}
	newSpace += strlen(string);
    }
    va_end(argList);

    /*
     * If the append buffer isn't already setup and large enough to hold
     * the new data, set it up.
     */

    if ((iPtr->result != iPtr->appendResult)
	    || (iPtr->appendResult[iPtr->appendUsed] != 0)
	    || ((newSpace + iPtr->appendUsed) >= iPtr->appendAvl)) {
       SetupAppendBuffer(iPtr, newSpace);
    }

    /*
     * Now go through all the argument strings again, copying them into the
     * buffer.
     */

    TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
    while (1) {
	string = va_arg(argList, char *);
	if (string == NULL) {
	    break;
	}
	strcpy(iPtr->appendResult + iPtr->appendUsed, string);
	iPtr->appendUsed += strlen(string);
    }
    va_end(argList);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppendElement --
 *
 *	Convert a string to a valid Tcl list element and append it to the
 *	result (which is ostensibly a list).
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The result in the interpreter given by the first argument is
 *	extended with a list element converted from string. A separator
 *	space is added before the converted list element unless the current
 *	result is empty, contains the single character "{", or ends in " {".
 *
 *	If the string result is empty, the object result is moved to the
 *	string result, then the object result is reset.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AppendElement(interp, string)
    Tcl_Interp *interp;		/* Interpreter whose result is to be
				 * extended. */
    char *string;		/* String to convert to list element and
				 * add to result. */
{
    Interp *iPtr = (Interp *) interp;
    char *dst;
    int size;
    int flags;

    /*
     * If the string result is empty, move the object result to the
     * string result, then reset the object result.
     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
     */

    if (*(iPtr->result) == 0) {
	Tcl_SetResult(interp,
	        TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
	        TCL_VOLATILE);
    }

    /*
     * See how much space is needed, and grow the append buffer if
     * needed to accommodate the list element.
     */

    size = Tcl_ScanElement(string, &flags) + 1;
    if ((iPtr->result != iPtr->appendResult)
	    || (iPtr->appendResult[iPtr->appendUsed] != 0)
	    || ((size + iPtr->appendUsed) >= iPtr->appendAvl)) {
       SetupAppendBuffer(iPtr, size+iPtr->appendUsed);
    }

    /*
     * Convert the string into a list element and copy it to the
     * buffer that's forming, with a space separator if needed.
     */

    dst = iPtr->appendResult + iPtr->appendUsed;
    if (TclNeedSpace(iPtr->appendResult, dst)) {
	iPtr->appendUsed++;
	*dst = ' ';
	dst++;
    }
    iPtr->appendUsed += Tcl_ConvertElement(string, dst, flags);
}

/*
 *----------------------------------------------------------------------
 *
 * SetupAppendBuffer --
 *
 *	This procedure makes sure that there is an append buffer properly
 *	initialized, if necessary, from the interpreter's result, and
 *	that it has at least enough room to accommodate newSpace new
 *	bytes of information.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
SetupAppendBuffer(iPtr, newSpace)
    Interp *iPtr;		/* Interpreter whose result is being set up. */
    int newSpace;		/* Make sure that at least this many bytes
				 * of new information may be added. */
{
    int totalSpace;

    /*
     * Make the append buffer larger, if that's necessary, then copy the
     * result into the append buffer and make the append buffer the official
     * Tcl result.
     */

    if (iPtr->result != iPtr->appendResult) {
	/*
	 * If an oversized buffer was used recently, then free it up
	 * so we go back to a smaller buffer.  This avoids tying up
	 * memory forever after a large operation.
	 */

	if (iPtr->appendAvl > 500) {
	    ckfree(iPtr->appendResult);
	    iPtr->appendResult = NULL;
	    iPtr->appendAvl = 0;
	}
	iPtr->appendUsed = strlen(iPtr->result);
    } else if (iPtr->result[iPtr->appendUsed] != 0) {
	/*
	 * Most likely someone has modified a result created by
	 * Tcl_AppendResult et al. so that it has a different size.
	 * Just recompute the size.
	 */

	iPtr->appendUsed = strlen(iPtr->result);
    }
    
    totalSpace = newSpace + iPtr->appendUsed;
    if (totalSpace >= iPtr->appendAvl) {
	char *new;

	if (totalSpace < 100) {
	    totalSpace = 200;
	} else {
	    totalSpace *= 2;
	}
	new = (char *) ckalloc((unsigned) totalSpace);
	strcpy(new, iPtr->result);
	if (iPtr->appendResult != NULL) {
	    ckfree(iPtr->appendResult);
	}
	iPtr->appendResult = new;
	iPtr->appendAvl = totalSpace;
    } else if (iPtr->result != iPtr->appendResult) {
	strcpy(iPtr->appendResult, iPtr->result);
    }
    
    Tcl_FreeResult((Tcl_Interp *) iPtr);
    iPtr->result = iPtr->appendResult;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FreeResult --
 *
 *	This procedure frees up the memory associated with an interpreter's
 *	string result. It also resets the interpreter's result object.
 *	Tcl_FreeResult is most commonly used when a procedure is about to
 *	replace one result value with another.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the memory associated with interp's string result and sets
 *	interp->freeProc to zero, but does not change interp->result or
 *	clear error state. Resets interp's result object to an unshared
 *	empty object.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_FreeResult(interp)
    Tcl_Interp *interp;		/* Interpreter for which to free result. */
{
    Interp *iPtr = (Interp *) interp;
    
    if (iPtr->freeProc != NULL) {
	if ((iPtr->freeProc == TCL_DYNAMIC)
	        || (iPtr->freeProc == (Tcl_FreeProc *) free)) {
	    ckfree(iPtr->result);
	} else {
	    (*iPtr->freeProc)(iPtr->result);
	}
	iPtr->freeProc = 0;
    }
    
    TclResetObjResult(iPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ResetResult --
 *
 *	This procedure resets both the interpreter's string and object
 *	results.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	It resets the result object to an unshared empty object. It
 *	then restores the interpreter's string result area to its default
 *	initialized state, freeing up any memory that may have been
 *	allocated. It also clears any error information for the interpreter.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ResetResult(interp)
    Tcl_Interp *interp;		/* Interpreter for which to clear result. */
{
    Interp *iPtr = (Interp *) interp;

    TclResetObjResult(iPtr);
    
    Tcl_FreeResult(interp);
    iPtr->result = iPtr->resultSpace;
    iPtr->resultSpace[0] = 0;
    
    iPtr->flags &= ~(ERR_ALREADY_LOGGED | ERR_IN_PROGRESS | ERROR_CODE_SET);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetErrorCode --
 *
 *	This procedure is called to record machine-readable information
 *	about an error that is about to be returned.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The errorCode global variable is modified to hold all of the
 *	arguments to this procedure, in a list form with each argument
 *	becoming one element of the list.  A flag is set internally
 *	to remember that errorCode has been set, so the variable doesn't
 *	get set automatically when the error is returned.
 *
 *----------------------------------------------------------------------
 */
	/* VARARGS2 */
void
Tcl_SetErrorCode TCL_VARARGS_DEF(Tcl_Interp *,arg1)
{
    va_list argList;
    char *string;
    int flags;
    Interp *iPtr;

    /*
     * Scan through the arguments one at a time, appending them to
     * $errorCode as list elements.
     */

    iPtr = (Interp *) TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
    flags = TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT;
    while (1) {
	string = va_arg(argList, char *);
	if (string == NULL) {
	    break;
	}
	(void) Tcl_SetVar2((Tcl_Interp *) iPtr, "errorCode",
		(char *) NULL, string, flags);
	flags |= TCL_APPEND_VALUE;
    }
    va_end(argList);
    iPtr->flags |= ERROR_CODE_SET;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetObjErrorCode --
 *
 *	This procedure is called to record machine-readable information
 *	about an error that is about to be returned. The caller should
 *	build a list object up and pass it to this routine.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The errorCode global variable is modified to be the new value.
 *	A flag is set internally to remember that errorCode has been
 *	set, so the variable doesn't get set automatically when the
 *	error is returned.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetObjErrorCode(interp, errorObjPtr)
    Tcl_Interp *interp;
    Tcl_Obj *errorObjPtr;
{
    Tcl_Obj *namePtr;
    Interp *iPtr;
    
    namePtr = Tcl_NewStringObj("errorCode", -1);
    iPtr = (Interp *) interp;
    Tcl_ObjSetVar2(interp, namePtr, (Tcl_Obj *) NULL, errorObjPtr,
	    TCL_GLOBAL_ONLY);
    iPtr->flags |= ERROR_CODE_SET;
    Tcl_DecrRefCount(namePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegExpCompile --
 *
 *	Compile a regular expression into a form suitable for fast
 *	matching.  This procedure retains a small cache of pre-compiled
 *	regular expressions in the interpreter, in order to avoid
 *	compilation costs as much as possible.
 *
 * Results:
 *	The return value is a pointer to the compiled form of string,
 *	suitable for passing to Tcl_RegExpExec.  This compiled form
 *	is only valid up until the next call to this procedure, so
 *	don't keep these around for a long time!  If an error occurred
 *	while compiling the pattern, then NULL is returned and an error
 *	message is left in interp->result.
 *
 * Side effects:
 *	The cache of compiled regexp's in interp will be modified to
 *	hold information for string, if such information isn't already
 *	present in the cache.
 *
 *----------------------------------------------------------------------
 */

Tcl_RegExp
Tcl_RegExpCompile(interp, string)
    Tcl_Interp *interp;			/* For use in error reporting. */
    char *string;			/* String for which to produce
					 * compiled regular expression. */
{
    Interp *iPtr = (Interp *) interp;
    int i, length;
    regexp *result;

    length = strlen(string);
    for (i = 0; i < NUM_REGEXPS; i++) {
	if ((length == iPtr->patLengths[i])
		&& (strcmp(string, iPtr->patterns[i]) == 0)) {
	    /*
	     * Move the matched pattern to the first slot in the
	     * cache and shift the other patterns down one position.
	     */

	    if (i != 0) {
		int j;
		char *cachedString;

		cachedString = iPtr->patterns[i];
		result = iPtr->regexps[i];
		for (j = i-1; j >= 0; j--) {
		    iPtr->patterns[j+1] = iPtr->patterns[j];
		    iPtr->patLengths[j+1] = iPtr->patLengths[j];
		    iPtr->regexps[j+1] = iPtr->regexps[j];
		}
		iPtr->patterns[0] = cachedString;
		iPtr->patLengths[0] = length;
		iPtr->regexps[0] = result;
	    }
	    return (Tcl_RegExp) iPtr->regexps[0];
	}
    }

    /*
     * No match in the cache.  Compile the string and add it to the
     * cache.
     */

    TclRegError((char *) NULL);
    result = TclRegComp(string);
    if (TclGetRegError() != NULL) {
	Tcl_AppendResult(interp,
	    "couldn't compile regular expression pattern: ",
	    TclGetRegError(), (char *) NULL);
	return NULL;
    }
    if (iPtr->patterns[NUM_REGEXPS-1] != NULL) {
	ckfree(iPtr->patterns[NUM_REGEXPS-1]);
	ckfree((char *) iPtr->regexps[NUM_REGEXPS-1]);
    }
    for (i = NUM_REGEXPS - 2; i >= 0; i--) {
	iPtr->patterns[i+1] = iPtr->patterns[i];
	iPtr->patLengths[i+1] = iPtr->patLengths[i];
	iPtr->regexps[i+1] = iPtr->regexps[i];
    }
    iPtr->patterns[0] = (char *) ckalloc((unsigned) (length+1));
    strcpy(iPtr->patterns[0], string);
    iPtr->patLengths[0] = length;
    iPtr->regexps[0] = result;
    return (Tcl_RegExp) result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegExpExec --
 *
 *	Execute the regular expression matcher using a compiled form
 *	of a regular expression and save information about any match
 *	that is found.
 *
 * Results:
 *	If an error occurs during the matching operation then -1
 *	is returned and interp->result contains an error message.
 *	Otherwise the return value is 1 if a matching range is
 *	found and 0 if there is no matching range.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_RegExpExec(interp, re, string, start)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting. */
    Tcl_RegExp re;		/* Compiled regular expression;  must have
				 * been returned by previous call to
				 * Tcl_RegExpCompile. */
    char *string;		/* String against which to match re. */
    char *start;		/* If string is part of a larger string,
				 * this identifies beginning of larger
				 * string, so that "^" won't match. */
{
    int match;

    regexp *regexpPtr = (regexp *) re;
    TclRegError((char *) NULL);
    match = TclRegExec(regexpPtr, string, start);
    if (TclGetRegError() != NULL) {
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "error while matching regular expression: ",
		TclGetRegError(), (char *) NULL);
	return -1;
    }
    return match;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegExpRange --
 *
 *	Returns pointers describing the range of a regular expression match,
 *	or one of the subranges within the match.
 *
 * Results:
 *	The variables at *startPtr and *endPtr are modified to hold the
 *	addresses of the endpoints of the range given by index.  If the
 *	specified range doesn't exist then NULLs are returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_RegExpRange(re, index, startPtr, endPtr)
    Tcl_RegExp re;		/* Compiled regular expression that has
				 * been passed to Tcl_RegExpExec. */
    int index;			/* 0 means give the range of the entire
				 * match, > 0 means give the range of
				 * a matching subrange.  Must be no greater
				 * than NSUBEXP. */
    char **startPtr;		/* Store address of first character in
				 * (sub-) range here. */
    char **endPtr;		/* Store address of character just after last
				 * in (sub-) range here. */
{
    regexp *regexpPtr = (regexp *) re;

    if (index >= NSUBEXP) {
	*startPtr = *endPtr = NULL;
    } else {
	*startPtr = regexpPtr->startp[index];
	*endPtr = regexpPtr->endp[index];
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_RegExpMatch --
 *
 *	See if a string matches a regular expression.
 *
 * Results:
 *	If an error occurs during the matching operation then -1
 *	is returned and interp->result contains an error message.
 *	Otherwise the return value is 1 if "string" matches "pattern"
 *	and 0 otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_RegExpMatch(interp, string, pattern)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *string;		/* String. */
    char *pattern;		/* Regular expression to match against
				 * string. */
{
    Tcl_RegExp re;

    re = Tcl_RegExpCompile(interp, pattern);
    if (re == NULL) {
	return -1;
    }
    return Tcl_RegExpExec(interp, re, string, string);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DStringInit --
 *







|
|


>
|
|

>
>
>
>
|
|
|


|
|





|









|
|
|






|


|


|




|
>
|
>
>
>







|
>
>
|
>
>

|


>
|
<
<
|
|
<


|
<
<
>
>
>
>
>
|


>
|

<


|
|


|

<
>
>


|



|
|
|
>





|


|


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







1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181


1182
1183

1184
1185
1186


1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197

1198
1199
1200
1201
1202
1203
1204
1205

1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228

1229
































































































































































































































































































































































































































































































































































































































































































































































































































































1230


1231





1232
1233
1234
1235
1236
1237
1238
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_StringMatch(string, pattern)
    CONST char *string;		/* String. */
    CONST char *pattern;	/* Pattern, which may contain special
				 * characters. */
{
    int p, s;
    CONST char *pstart = pattern;
    
    while (1) {
	p = *pattern;
	s = *string;
	
	/*
	 * See if we're at the end of both the pattern and the string.  If
	 * so, we succeeded.  If we're at the end of the pattern but not at
	 * the end of the string, we failed.
	 */
	
	if (p == '\0') {
	    if (s == '\0') {
		return 1;
	    } else {
		return 0;
	    }
	}
	if ((s == '\0') && (p != '*')) {
	    return 0;
	}

	/* Check for a "*" as the next pattern character.  It matches
	 * any substring.  We handle this by calling ourselves
	 * recursively for each postfix of string, until either we
	 * match or we reach the end of the string.
	 */
	
	if (p == '*') {
	    pattern++;
	    if (*pattern == '\0') {
		return 1;
	    }
	    while (1) {
		if (Tcl_StringMatch(string, pattern)) {
		    return 1;
		}
		if (*string == '\0') {
		    return 0;
		}
		string++;
	    }
	}

	/* Check for a "?" as the next pattern character.  It matches
	 * any single character.
	 */

	if (p == '?') {
	    Tcl_UniChar ch;
	    
	    pattern++;
	    string += Tcl_UtfToUniChar(string, &ch);
	    continue;
	}

	/* Check for a "[" as the next pattern character.  It is followed
	 * by a list of characters that are acceptable, or by a range
	 * (two characters separated by "-").
	 */
	
	if (p == '[') {
	    Tcl_UniChar ch, startChar, endChar;

	    pattern++;
	    string += Tcl_UtfToUniChar(string, &ch);

	    while (1) {
		if ((*pattern == ']') || (*pattern == '\0')) {
		    return 0;
		}
		pattern += Tcl_UtfToUniChar(pattern, &startChar);
		if (*pattern == '-') {


		    pattern++;
		    if (*pattern == '\0') {

			return 0;
		    }
		    pattern += Tcl_UtfToUniChar(pattern, &endChar);


		    if (((startChar <= ch) && (ch <= endChar))
			    || ((endChar <= ch) && (ch <= startChar))) {
			/*
			 * Matches ranges of form [a-z] or [z-a].
			 */

			break;
		    }
		} else if (startChar == ch) {
		    break;
		}

	    }
	    while (*pattern != ']') {
		if (*pattern == '\0') {
		    pattern = Tcl_UtfPrev(pattern, pstart);
		    break;
		}
		pattern++;
	    }

	    pattern++;
	    continue;
	}
    
	/* If the next pattern character is '\', just strip off the '\'
	 * so we do exact matching on the character that follows.
	 */
	
	if (p == '\\') {
	    pattern++;
	    p = *pattern;
	    if (p == '\0') {
		return 0;
	    }
	}

	/* There's no special character.  Just make sure that the next
	 * bytes of each string match.
	 */
	
	if (s != p) {
	    return 0;
	}

	pattern++;
































































































































































































































































































































































































































































































































































































































































































































































































































































	string++;


    }





}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DStringInit --
 *
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
void
Tcl_DStringInit(dsPtr)
    Tcl_DString *dsPtr;		/* Pointer to structure for dynamic string. */
{
    dsPtr->string = dsPtr->staticSpace;
    dsPtr->length = 0;
    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
    dsPtr->staticSpace[0] = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DStringAppend --
 *







|







1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
void
Tcl_DStringInit(dsPtr)
    Tcl_DString *dsPtr;		/* Pointer to structure for dynamic string. */
{
    dsPtr->string = dsPtr->staticSpace;
    dsPtr->length = 0;
    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
    dsPtr->staticSpace[0] = '\0';
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DStringAppend --
 *
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088



2089
2090
2091
2092


2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
    CONST char *string;		/* String to append.  If length is -1 then
				 * this must be null-terminated. */
    int length;			/* Number of characters from string to
				 * append.  If < 0, then append all of string,
				 * up to null at end. */
{
    int newSize;
    char *newString, *dst;
    CONST char *end;

    if (length < 0) {
	length = strlen(string);
    }
    newSize = length + dsPtr->length;

    /*
     * Allocate a larger buffer for the string if the current one isn't
     * large enough. Allocate extra space in the new buffer so that there
     * will be room to grow before we have to allocate again.
     */

    if (newSize >= dsPtr->spaceAvl) {
	dsPtr->spaceAvl = newSize*2;



	newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
	memcpy((VOID *) newString, (VOID *) dsPtr->string,
		(size_t) dsPtr->length);
	if (dsPtr->string != dsPtr->staticSpace) {


	    ckfree(dsPtr->string);
	}
	dsPtr->string = newString;
    }

    /*
     * Copy the new string into the buffer at the end of the old
     * one.
     */








|














|
>
>
>
|
|
|
|
>
>
|

<







1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316

1317
1318
1319
1320
1321
1322
1323
    CONST char *string;		/* String to append.  If length is -1 then
				 * this must be null-terminated. */
    int length;			/* Number of characters from string to
				 * append.  If < 0, then append all of string,
				 * up to null at end. */
{
    int newSize;
    char *dst;
    CONST char *end;

    if (length < 0) {
	length = strlen(string);
    }
    newSize = length + dsPtr->length;

    /*
     * Allocate a larger buffer for the string if the current one isn't
     * large enough. Allocate extra space in the new buffer so that there
     * will be room to grow before we have to allocate again.
     */

    if (newSize >= dsPtr->spaceAvl) {
	dsPtr->spaceAvl = newSize * 2;
	if (dsPtr->string == dsPtr->staticSpace) {
	    char *newString;

	    newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
	    memcpy((VOID *) newString, (VOID *) dsPtr->string,
		    (size_t) dsPtr->length);
	    dsPtr->string = newString;
	} else {
	    dsPtr->string = (char *) ckrealloc((VOID *) dsPtr->string,
		    (size_t) dsPtr->spaceAvl);
	}

    }

    /*
     * Copy the new string into the buffer at the end of the old
     * one.
     */

2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151



2152
2153
2154
2155


2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
char *
Tcl_DStringAppendElement(dsPtr, string)
    Tcl_DString *dsPtr;		/* Structure describing dynamic string. */
    CONST char *string;		/* String to append.  Must be
				 * null-terminated. */
{
    int newSize, flags;
    char *dst, *newString;

    newSize = Tcl_ScanElement(string, &flags) + dsPtr->length + 1;

    /*
     * Allocate a larger buffer for the string if the current one isn't
     * large enough.  Allocate extra space in the new buffer so that there
     * will be room to grow before we have to allocate again.
     * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
     * to a larger buffer, since there may be embedded NULLs in the
     * string in some cases.
     */

    if (newSize >= dsPtr->spaceAvl) {
	dsPtr->spaceAvl = newSize*2;



	newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
	memcpy((VOID *) newString, (VOID *) dsPtr->string,
		(size_t) dsPtr->length);
	if (dsPtr->string != dsPtr->staticSpace) {


	    ckfree(dsPtr->string);
	}
	dsPtr->string = newString;
    }

    /*
     * Convert the new string to a list element and copy it into the
     * buffer at the end, with a space, if needed.
     */








|













|
>
>
>
|
|
|
|
>
>
|

<







1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
char *
Tcl_DStringAppendElement(dsPtr, string)
    Tcl_DString *dsPtr;		/* Structure describing dynamic string. */
    CONST char *string;		/* String to append.  Must be
				 * null-terminated. */
{
    int newSize, flags;
    char *dst;

    newSize = Tcl_ScanElement(string, &flags) + dsPtr->length + 1;

    /*
     * Allocate a larger buffer for the string if the current one isn't
     * large enough.  Allocate extra space in the new buffer so that there
     * will be room to grow before we have to allocate again.
     * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
     * to a larger buffer, since there may be embedded NULLs in the
     * string in some cases.
     */

    if (newSize >= dsPtr->spaceAvl) {
	dsPtr->spaceAvl = newSize * 2;
	if (dsPtr->string == dsPtr->staticSpace) {
	    char *newString;

	    newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
	    memcpy((VOID *) newString, (VOID *) dsPtr->string,
		    (size_t) dsPtr->length);
	    dsPtr->string = newString;
	} else {
	    dsPtr->string = (char *) ckrealloc((VOID *) dsPtr->string,
		    (size_t) dsPtr->spaceAvl);
	}

    }

    /*
     * Convert the new string to a list element and copy it into the
     * buffer at the end, with a space, if needed.
     */

2194
2195
2196
2197
2198
2199
2200


2201
2202
2203
2204






2205




2206


2207

2208
2209
2210
2211
2212
2213
2214
2215

2216
2217
2218


2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
 */

void
Tcl_DStringSetLength(dsPtr, length)
    Tcl_DString *dsPtr;		/* Structure describing dynamic string. */
    int length;			/* New length for dynamic string. */
{


    if (length < 0) {
	length = 0;
    }
    if (length >= dsPtr->spaceAvl) {






	char *newString;







	dsPtr->spaceAvl = length+1;

	newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);

	/*
	 * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
	 * to a larger buffer, since there may be embedded NULLs in the
	 * string in some cases.
	 */


	memcpy((VOID *) newString, (VOID *) dsPtr->string,
		(size_t) dsPtr->length);
	if (dsPtr->string != dsPtr->staticSpace) {


	    ckfree(dsPtr->string);
	}
	dsPtr->string = newString;
    }
    dsPtr->length = length;
    dsPtr->string[length] = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DStringFree --
 *
 *	Frees up any memory allocated for the dynamic string and
 *	reinitializes the string to an empty state.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The previous contents of the dynamic string are lost, and
 *	the new value is an empty string.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DStringFree(dsPtr)
    Tcl_DString *dsPtr;		/* Structure describing dynamic string. */
{
    if (dsPtr->string != dsPtr->staticSpace) {
	ckfree(dsPtr->string);
    }
    dsPtr->string = dsPtr->staticSpace;
    dsPtr->length = 0;
    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
    dsPtr->staticSpace[0] = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DStringResult --
 *







>
>




>
>
>
>
>
>
|
>
>
>
>

>
>
|
>
|
|
<
|
<
|
<

>
|
|
|
>
>
|

<




















|
<











|







1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449

1450

1451

1452
1453
1454
1455
1456
1457
1458
1459
1460

1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481

1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
 */

void
Tcl_DStringSetLength(dsPtr, length)
    Tcl_DString *dsPtr;		/* Structure describing dynamic string. */
    int length;			/* New length for dynamic string. */
{
    int newsize;

    if (length < 0) {
	length = 0;
    }
    if (length >= dsPtr->spaceAvl) {
	/*
	 * There are two interesting cases here.  In the first case, the user
	 * may be trying to allocate a large buffer of a specific size.  It
	 * would be wasteful to overallocate that buffer, so we just allocate
	 * enough for the requested size plus the trailing null byte.  In the
	 * second case, we are growing the buffer incrementally, so we need
	 * behavior similar to Tcl_DStringAppend.  The requested length will
	 * usually be a small delta above the current spaceAvl, so we'll end up
	 * doubling the old size.  This won't grow the buffer quite as quickly,
	 * but it should be close enough.
	 */

	newsize = dsPtr->spaceAvl * 2;
	if (length < newsize) {
	    dsPtr->spaceAvl = newsize;
	} else {
	    dsPtr->spaceAvl = length + 1;
	}

	if (dsPtr->string == dsPtr->staticSpace) {

	    char *newString;


	    newString = (char *) ckalloc((unsigned) dsPtr->spaceAvl);
	    memcpy((VOID *) newString, (VOID *) dsPtr->string,
		    (size_t) dsPtr->length);
	    dsPtr->string = newString;
	} else {
	    dsPtr->string = (char *) ckrealloc((VOID *) dsPtr->string,
		    (size_t) dsPtr->spaceAvl);
	}

    }
    dsPtr->length = length;
    dsPtr->string[length] = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DStringFree --
 *
 *	Frees up any memory allocated for the dynamic string and
 *	reinitializes the string to an empty state.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The previous contents of the dynamic string are lost, and
 *	the new value is an empty string.
 *
 *---------------------------------------------------------------------- */


void
Tcl_DStringFree(dsPtr)
    Tcl_DString *dsPtr;		/* Structure describing dynamic string. */
{
    if (dsPtr->string != dsPtr->staticSpace) {
	ckfree(dsPtr->string);
    }
    dsPtr->string = dsPtr->staticSpace;
    dsPtr->length = 0;
    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
    dsPtr->staticSpace[0] = '\0';
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DStringResult --
 *
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
    } else {
	Tcl_SetResult(interp, dsPtr->string, TCL_VOLATILE);
    }
    
    dsPtr->string = dsPtr->staticSpace;
    dsPtr->length = 0;
    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
    dsPtr->staticSpace[0] = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DStringGetResult --
 *







|







1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
    } else {
	Tcl_SetResult(interp, dsPtr->string, TCL_VOLATILE);
    }
    
    dsPtr->string = dsPtr->staticSpace;
    dsPtr->length = 0;
    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
    dsPtr->staticSpace[0] = '\0';
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DStringGetResult --
 *
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
    if (dsPtr->string != dsPtr->staticSpace) {
	ckfree(dsPtr->string);
    }

    /*
     * If the string result is empty, move the object result to the
     * string result, then reset the object result.
     * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
     */

    if (*(iPtr->result) == 0) {
	Tcl_SetResult(interp,
	        TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
	        TCL_VOLATILE);
    }

    dsPtr->length = strlen(iPtr->result);
    if (iPtr->freeProc != NULL) {
	if ((iPtr->freeProc == TCL_DYNAMIC)
		|| (iPtr->freeProc == (Tcl_FreeProc *) free)) {







<



|
<







1568
1569
1570
1571
1572
1573
1574

1575
1576
1577
1578

1579
1580
1581
1582
1583
1584
1585
    if (dsPtr->string != dsPtr->staticSpace) {
	ckfree(dsPtr->string);
    }

    /*
     * If the string result is empty, move the object result to the
     * string result, then reset the object result.

     */

    if (*(iPtr->result) == 0) {
	Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),

	        TCL_VOLATILE);
    }

    dsPtr->length = strlen(iPtr->result);
    if (iPtr->freeProc != NULL) {
	if ((iPtr->freeProc == TCL_DYNAMIC)
		|| (iPtr->freeProc == (Tcl_FreeProc *) free)) {
2452
2453
2454
2455
2456
2457
2458
2459

2460

2461

2462
2463
2464
2465
2466
2467
2468
2469


2470
2471
2472
2473
2474
2475
2476
2477
					 * variable used to be used to control
					 * printing.  It's ignored now. */
    double value;			/* Value to print as string. */
    char *dst;				/* Where to store converted value;
					 * must have at least TCL_DOUBLE_SPACE
					 * characters. */
{
    char *p;



    sprintf(dst, precisionFormat, value);


    /*
     * If the ASCII result looks like an integer, add ".0" so that it
     * doesn't look like an integer anymore.  This prevents floating-point
     * values from being converted to integers unintentionally.
     */

    for (p = dst; *p != 0; p++) {


	if ((*p == '.') || (isalpha(UCHAR(*p)))) {
	    return;
	}
    }
    p[0] = '.';
    p[1] = '0';
    p[2] = 0;
}







|
>

>

>







|
>
>
|







1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
					 * variable used to be used to control
					 * printing.  It's ignored now. */
    double value;			/* Value to print as string. */
    char *dst;				/* Where to store converted value;
					 * must have at least TCL_DOUBLE_SPACE
					 * characters. */
{
    char *p, c;
    Tcl_UniChar ch;

    Tcl_MutexLock(&precisionMutex);
    sprintf(dst, precisionFormat, value);
    Tcl_MutexUnlock(&precisionMutex);

    /*
     * If the ASCII result looks like an integer, add ".0" so that it
     * doesn't look like an integer anymore.  This prevents floating-point
     * values from being converted to integers unintentionally.
     */

    for (p = dst; *p != 0; ) {
	p += Tcl_UtfToUniChar(p, &ch);
	c = UCHAR(ch);
	if ((c == '.') || isalpha(UCHAR(c))) {	/* INTL: ISO only. */
	    return;
	}
    }
    p[0] = '.';
    p[1] = '0';
    p[2] = 0;
}
2524
2525
2526
2527
2528
2529
2530


2531
2532
2533

2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546

2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557

2558
2559
2560
2561

2562
2563
2564
2565
2566
2567
2568
    /*
     * When the variable is read, reset its value from our shared
     * value.  This is needed in case the variable was modified in
     * some other interpreter so that this interpreter's value is
     * out of date.
     */



    if (flags & TCL_TRACE_READS) {
	Tcl_SetVar2(interp, name1, name2, precisionString,
		flags & TCL_GLOBAL_ONLY);

	return (char *) NULL;
    }

    /*
     * The variable is being written.  Check the new value and disallow
     * it if it isn't reasonable or if this is a safe interpreter (we
     * don't want safe interpreters messing up the precision of other
     * interpreters).
     */

    if (Tcl_IsSafe(interp)) {
	Tcl_SetVar2(interp, name1, name2, precisionString,
		flags & TCL_GLOBAL_ONLY);

	return "can't modify precision from a safe interpreter";
    }
    value = Tcl_GetVar2(interp, name1, name2, flags & TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    prec = strtoul(value, &end, 10);
    if ((prec <= 0) || (prec > TCL_MAX_PREC) || (prec > 100) ||
	    (end == value) || (*end != 0)) {
	Tcl_SetVar2(interp, name1, name2, precisionString,
		flags & TCL_GLOBAL_ONLY);

	return "improper value for precision";
    }
    TclFormatInt(precisionString, prec);
    sprintf(precisionFormat, "%%.%dg", prec);

    return (char *) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TclNeedSpace --







>
>



>













>











>




>







1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
    /*
     * When the variable is read, reset its value from our shared
     * value.  This is needed in case the variable was modified in
     * some other interpreter so that this interpreter's value is
     * out of date.
     */

    Tcl_MutexLock(&precisionMutex);

    if (flags & TCL_TRACE_READS) {
	Tcl_SetVar2(interp, name1, name2, precisionString,
		flags & TCL_GLOBAL_ONLY);
	Tcl_MutexUnlock(&precisionMutex);
	return (char *) NULL;
    }

    /*
     * The variable is being written.  Check the new value and disallow
     * it if it isn't reasonable or if this is a safe interpreter (we
     * don't want safe interpreters messing up the precision of other
     * interpreters).
     */

    if (Tcl_IsSafe(interp)) {
	Tcl_SetVar2(interp, name1, name2, precisionString,
		flags & TCL_GLOBAL_ONLY);
	Tcl_MutexUnlock(&precisionMutex);
	return "can't modify precision from a safe interpreter";
    }
    value = Tcl_GetVar2(interp, name1, name2, flags & TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    prec = strtoul(value, &end, 10);
    if ((prec <= 0) || (prec > TCL_MAX_PREC) || (prec > 100) ||
	    (end == value) || (*end != 0)) {
	Tcl_SetVar2(interp, name1, name2, precisionString,
		flags & TCL_GLOBAL_ONLY);
	Tcl_MutexUnlock(&precisionMutex);
	return "improper value for precision";
    }
    TclFormatInt(precisionString, prec);
    sprintf(precisionFormat, "%%.%dg", prec);
    Tcl_MutexUnlock(&precisionMutex);
    return (char *) NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TclNeedSpace --
2597
2598
2599
2600
2601
2602
2603

2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
     */

    if (end == start) {
	return 0;
    }
    end--;
    if (*end != '{') {

	if (isspace(UCHAR(*end)) && ((end == start) || (end[-1] != '\\'))) {
	    return 0;
	}
	return 1;
    }
    do {
	if (end == start) {
	    return 0;
	}
	end--;
    } while (*end == '{');
    if (isspace(UCHAR(*end))) {
	return 0;
    }
    return 1;
}

/*
 *----------------------------------------------------------------------







>
|










|







1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
     */

    if (end == start) {
	return 0;
    }
    end--;
    if (*end != '{') {
	if (isspace(UCHAR(*end)) /* INTL: ISO space. */
		&& ((end == start) || (end[-1] != '\\'))) {
	    return 0;
	}
	return 1;
    }
    do {
	if (end == start) {
	    return 0;
	}
	end--;
    } while (*end == '{');
    if (isspace(UCHAR(*end))) {	/* INTL: ISO space. */
	return 0;
    }
    return 1;
}

/*
 *----------------------------------------------------------------------
2649
2650
2651
2652
2653
2654
2655
2656










2657
2658
2659
2660
2661
2662
2663
{
    long intVal;
    int i;
    int numFormatted, j;
    char *digits = "0123456789";

    /*
     * Check first whether "n" is the maximum negative value. This is










     * -2^(m-1) for an m-bit word, and has no positive equivalent;
     * negating it produces the same value.
     */

    if (n == -n) {
	sprintf(buffer, "%ld", n);
	return strlen(buffer);







|
>
>
>
>
>
>
>
>
>
>







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
{
    long intVal;
    int i;
    int numFormatted, j;
    char *digits = "0123456789";

    /*
     * Check first whether "n" is zero.
     */

    if (n == 0) {
	buffer[0] = '0';
	buffer[1] = 0;
	return 1;
    }

    /*
     * Check whether "n" is the maximum negative value. This is
     * -2^(m-1) for an m-bit word, and has no positive equivalent;
     * negating it produces the same value.
     */

    if (n == -n) {
	sprintf(buffer, "%ld", n);
	return strlen(buffer);
2711
2712
2713
2714
2715
2716
2717
2718







2719




2720

2721
2722
2723




2724
2725
2726
2727
2728
2729
2730
2731
2732



2733
2734
2735
2736
2737
2738
2739
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclLooksLikeInt(p)







    char *p;			/* Pointer to string. */




{

    while (isspace(UCHAR(*p))) {
	p++;
    }




    if ((*p == '+') || (*p == '-')) {
	p++;
    }
    if (!isdigit(UCHAR(*p))) {
	return 0;
    }
    p++;
    while (isdigit(UCHAR(*p))) {
	p++;



    }
    if ((*p != '.') && (*p != 'e') && (*p != 'E')) {
	return 1;
    }
    return 0;
}








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


>
>
>
>



|



|

>
>
>







1969
1970
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
2014
2015
2016
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclLooksLikeInt(bytes, length)
    register char *bytes;	/* Points to first byte of the string. */
    int length;			/* Number of bytes in the string. If < 0
				 * bytes up to the first null byte are
				 * considered (if they may appear in an 
				 * integer). */
{
    register char *p, *end;

    if (length < 0) {
	length = (bytes? strlen(bytes) : 0);
    }
    end = (bytes + length);

    p = bytes;
    while ((p < end) && isspace(UCHAR(*p))) { /* INTL: ISO space. */
	p++;
    }
    if (p == end) {
	return 0;
    }
    
    if ((*p == '+') || (*p == '-')) {
	p++;
    }
    if ((p == end) || !isdigit(UCHAR(*p))) { /* INTL: digit */
	return 0;
    }
    p++;
    while ((p < end) && isdigit(UCHAR(*p))) { /* INTL: digit */
	p++;
    }
    if (p == end) {
	return 1;
    }
    if ((*p != '.') && (*p != 'e') && (*p != 'E')) {
	return 1;
    }
    return 0;
}

2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
















































































 *	integer object.
 *
 *----------------------------------------------------------------------
 */

int
TclGetIntForIndex(interp, objPtr, endValue, indexPtr)
     Tcl_Interp *interp;	/* Interpreter to use for error reporting. 
				 * If NULL, then no error message is left
				 * after errors. */
     Tcl_Obj *objPtr;		/* Points to an object containing either
				 * "end" or an integer. */
     int endValue;		/* The value to be stored at "indexPtr" if
				 * "objPtr" holds "end". */
     int *indexPtr;		/* Location filled in with an integer
				 * representing an index. */
{
    Interp *iPtr = (Interp *) interp;
    char *bytes;
    int index, length, result;

    /*
     * THIS FAILS IF THE INDEX OBJECT'S STRING REP CONTAINS NULLS.
     */
    
    if (objPtr->typePtr == &tclIntType) {
	*indexPtr = (int)objPtr->internalRep.longValue;
	return TCL_OK;
    }
    
    bytes = TclGetStringFromObj(objPtr, &length);
    if ((*bytes == 'e')
	    && (strncmp(bytes, "end", (unsigned) length) == 0)) {
	index = endValue;
    } else {
	result = Tcl_GetIntFromObj((Tcl_Interp *) NULL, objPtr, &index);
	if (result != TCL_OK) {
	    if (iPtr != NULL) {
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"bad index \"", bytes,
			"\": must be integer or \"end\"", (char *) NULL);
	    }
	    return result;
	}
    }
    *indexPtr = index;
    return TCL_OK;
}























































































|


|

|

|






<
<
<
<





|

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057




2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
 *	integer object.
 *
 *----------------------------------------------------------------------
 */

int
TclGetIntForIndex(interp, objPtr, endValue, indexPtr)
    Tcl_Interp *interp;		/* Interpreter to use for error reporting. 
				 * If NULL, then no error message is left
				 * after errors. */
    Tcl_Obj *objPtr;		/* Points to an object containing either
				 * "end" or an integer. */
    int endValue;		/* The value to be stored at "indexPtr" if
				 * "objPtr" holds "end". */
    int *indexPtr;		/* Location filled in with an integer
				 * representing an index. */
{
    Interp *iPtr = (Interp *) interp;
    char *bytes;
    int index, length, result;





    if (objPtr->typePtr == &tclIntType) {
	*indexPtr = (int)objPtr->internalRep.longValue;
	return TCL_OK;
    }
    
    bytes = Tcl_GetStringFromObj(objPtr, &length);
    if ((*bytes == 'e')
	    && (strncmp(bytes, "end", (unsigned) length) == 0)) {
	index = endValue;
    } else {
	result = Tcl_GetIntFromObj((Tcl_Interp *) NULL, objPtr, &index);
	if (result != TCL_OK) {
	    if (iPtr != NULL) {
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
			"bad index \"", bytes,
			"\": must be integer or \"end\"", (char *) NULL);
	    }
	    return result;
	}
    }
    *indexPtr = index;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetNameOfExecutable --
 *
 *	This procedure simply returns a pointer to the internal full
 *	path name of the executable file as computed by
 *	Tcl_FindExecutable.  This procedure call is the C API
 *	equivalent to the "info nameofexecutable" command.
 *
 * Results:
 *	A pointer to the internal string or NULL if the internal full
 *	path name has not been computed or unknown.
 *
 * Side effects:
 *	The object referenced by "objPtr" might be converted to an
 *	integer object.
 *
 *----------------------------------------------------------------------
 */

CONST char *
Tcl_GetNameOfExecutable()
{
    return (tclExecutableName);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetCwd --
 *
 *	This function replaces the library version of getcwd().
 *
 * Results:
 *	The result is a pointer to a string specifying the current
 *	directory, or NULL if the current directory could not be
 *	determined.  If NULL is returned, an error message is left in the
 *	interp's result.  Storage for the result string is allocated in
 *	bufferPtr; the caller must call Tcl_DStringFree() when the result
 *	is no longer needed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_GetCwd(interp, cwdPtr)
    Tcl_Interp *interp;
    Tcl_DString *cwdPtr;
{
    return TclpGetCwd(interp, cwdPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Chdir --
 *
 *	This function replaces the library version of chdir().
 *
 * Results:
 *	See chdir() documentation.
 *
 * Side effects:
 *	See chdir() documentation.  
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Chdir(dirName)
    CONST char *dirName;
{
    return TclpChdir(dirName);
}

Changes to generic/tclVar.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
/* 
 * tclVar.c --
 *
 *	This file contains routines that implement Tcl variables
 *	(both scalars and arrays).
 *
 *	The implementation of arrays is modelled after an initial
 *	implementation by Mark Diekhans and Karl Lehenbauer.
 *
 * Copyright (c) 1987-1994 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclVar.c 1.130 97/10/29 18:26:16
 */

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

/*
 * The strings below are used to indicate what went wrong when a
 * variable access is denied.
 */

static char *noSuchVar =	"no such variable";
static char *isArray =		"variable is array";
static char *needArray =	"variable isn't array";
static char *noSuchElement =	"no such element in array";
static char *danglingUpvar =	"upvar refers to element in deleted array";

static char *badNamespace =	"parent namespace doesn't exist";
static char *missingName =	"missing variable name";

/*
 * Forward references to procedures defined later in this file:
 */












>




|














|
>







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
/* 
 * tclVar.c --
 *
 *	This file contains routines that implement Tcl variables
 *	(both scalars and arrays).
 *
 *	The implementation of arrays is modelled after an initial
 *	implementation by Mark Diekhans and Karl Lehenbauer.
 *
 * Copyright (c) 1987-1994 The Regents of the University of California.
 * Copyright (c) 1994-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: tclVar.c,v 1.1.2.5 1999/04/06 19:06:54 surles Exp $
 */

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

/*
 * The strings below are used to indicate what went wrong when a
 * variable access is denied.
 */

static char *noSuchVar =	"no such variable";
static char *isArray =		"variable is array";
static char *needArray =	"variable isn't array";
static char *noSuchElement =	"no such element in array";
static char *danglingElement =  "upvar refers to element in deleted array";
static char *danglingVar =     "upvar refers to variable in deleted namespace";
static char *badNamespace =	"parent namespace doesn't exist";
static char *missingName =	"missing variable name";

/*
 * Forward references to procedures defined later in this file:
 */

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
 *	if the variable is a scalar). If the variable can't be found and
 *	either createPart1 or createPart2 are 1, a new as-yet-undefined
 *	(VAR_UNDEFINED) variable structure is created, entered into a hash
 *	table, and returned.
 *
 *	If the variable isn't found and creation wasn't specified, or some
 *	other error occurs, NULL is returned and an error message is left in
 *	interp->result if TCL_LEAVE_ERR_MSG is set in flags. (The result
 *	isn't put in interp->objResultPtr because this procedure is used
 *	by so many string-based routines.)
 *
 *	Note: it's possible for the variable returned to be VAR_UNDEFINED
 *	even if createPart1 or createPart2 are 1 (these only cause the hash
 *	table entry or array to be created). For example, the variable might
 *	be a global that has been unset but is still referenced by a
 *	procedure, or a variable that has been unset but it only being kept
 *	in existence (if VAR_UNDEFINED) by a trace.
 *
 * Side effects:
 *	New hashtable entries may be created if createPart1 or createPart2
 *	are 1.
 *
 *----------------------------------------------------------------------
 */

Var *
TclLookupVar(interp, part1, part2, flags, msg, createPart1, createPart2,
        arrayPtrPtr)
    Tcl_Interp *interp;		/* Interpreter to use for lookup. */
    char *part1;		/* If part2 isn't NULL, this is the name of
				 * an array. Otherwise, if the
				 * TCL_PARSE_PART1 flag bit is set this
				 * is a full variable name that could
				 * include a parenthesized array elemnt. If
				 * TCL_PARSE_PART1 isn't present, then
				 * this is the name of a scalar variable. */
    char *part2;		/* Name of element within array, or NULL. */
    int flags;			/* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
				 * TCL_LEAVE_ERR_MSG, and
				 * TCL_PARSE_PART1 bits matter. */
    char *msg;			/* Verb to use in error messages, e.g.
				 * "read" or "set". Only needed if
				 * TCL_LEAVE_ERR_MSG is set in flags. */
    int createPart1;		/* If 1, create hash table entry for part 1
				 * of name, if it doesn't already exist. If
				 * 0, return error if it doesn't exist. */
    int createPart2;		/* If 1, create hash table entry for part 2







|
<
<



















|
|
<

|
<
<


|
<







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
 *	if the variable is a scalar). If the variable can't be found and
 *	either createPart1 or createPart2 are 1, a new as-yet-undefined
 *	(VAR_UNDEFINED) variable structure is created, entered into a hash
 *	table, and returned.
 *
 *	If the variable isn't found and creation wasn't specified, or some
 *	other error occurs, NULL is returned and an error message is left in
 *	the interp's result if TCL_LEAVE_ERR_MSG is set in flags. 


 *
 *	Note: it's possible for the variable returned to be VAR_UNDEFINED
 *	even if createPart1 or createPart2 are 1 (these only cause the hash
 *	table entry or array to be created). For example, the variable might
 *	be a global that has been unset but is still referenced by a
 *	procedure, or a variable that has been unset but it only being kept
 *	in existence (if VAR_UNDEFINED) by a trace.
 *
 * Side effects:
 *	New hashtable entries may be created if createPart1 or createPart2
 *	are 1.
 *
 *----------------------------------------------------------------------
 */

Var *
TclLookupVar(interp, part1, part2, flags, msg, createPart1, createPart2,
        arrayPtrPtr)
    Tcl_Interp *interp;		/* Interpreter to use for lookup. */
    register char *part1;	/* If part2 isn't NULL, this is the name of
				 * an array. Otherwise, this

				 * is a full variable name that could
				 * include a parenthesized array element. */


    char *part2;		/* Name of element within array, or NULL. */
    int flags;			/* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
				 * and TCL_LEAVE_ERR_MSG bits matter. */

    char *msg;			/* Verb to use in error messages, e.g.
				 * "read" or "set". Only needed if
				 * TCL_LEAVE_ERR_MSG is set in flags. */
    int createPart1;		/* If 1, create hash table entry for part 1
				 * of name, if it doesn't already exist. If
				 * 0, return error if it doesn't exist. */
    int createPart2;		/* If 1, create hash table entry for part 2
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
				 * same as part2, or may be openParen+1. */
    char *openParen, *closeParen;
                                /* If this procedure parses a name into
				 * array and index, these point to the
				 * parens around the index.  Otherwise they
				 * are NULL. These are needed to restore
				 * the parens after parsing the name. */
    Namespace *varNsPtr, *dummy1Ptr, *dummy2Ptr;

    Tcl_HashEntry *hPtr;
    register char *p;
    int new, i, result;

    varPtr = NULL;
    *arrayPtrPtr = NULL;
    openParen = closeParen = NULL;
    varNsPtr = NULL;		/* set non-NULL if a nonlocal variable */

    /*
     * If the name hasn't been parsed into array name and index yet,

     * do it now.




     */

    elName = part2;
    if (flags & TCL_PARSE_PART1) {
	for (p = part1; ; p++) {
	    if (*p == 0) {
		elName = NULL;
		break;
	    }
	    if (*p == '(') {
		openParen = p;
		do {
		    p++;
		} while (*p != '\0');
		p--;
		if (*p == ')') {







		    closeParen = p;
		    *openParen = 0;
		    elName = openParen+1;
		} else {
		    openParen = NULL;
		    elName = NULL;
		}
		break;
	    }
	}
    }







































    /*
     * Look up part1. Look it up as either a namespace variable or as a
     * local variable in a procedure call frame (varFramePtr).
     * Interpret part1 as a namespace variable if:
     *    1) so requested by a TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY flag,
     *    2) there is no active frame (we're at the global :: scope),
     *    3) the active frame was pushed to define the namespace context
     *       for a "namespace eval" or "namespace inscope" command,
     *    4) the name has namespace qualifiers ("::"s).
     * Otherwise, if part1 is a local variable, search first in the
     * frame's array of compiler-allocated local variables, then in its
     * hashtable for runtime-created local variables.
     *
     * If createPart1 and the variable isn't found, create the variable and,
     * if necessary, create varFramePtr's local var hashtable.
     */

    if (((flags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY)) != 0)
	        || (varFramePtr == NULL)
	        || !varFramePtr->isProcCallFrame
	        || (strstr(part1, "::") != NULL)) {
	char *tail;
	




	var = Tcl_FindNamespaceVar(interp, part1, (Tcl_Namespace *) NULL,
	        flags);
	if (var != (Tcl_Var) NULL) {
            varPtr = (Var *) var;
        }
	if (varPtr == NULL) {
	    if (flags & TCL_LEAVE_ERR_MSG) {
		Tcl_ResetResult(interp);
	    }
	    if (createPart1) {   /* var wasn't found so create it  */
		result = TclGetNamespaceForQualName(interp, part1,
		        (Namespace *) NULL, flags, &varNsPtr, &dummy1Ptr,
			&dummy2Ptr, &tail);
		if (result != TCL_OK) {
		    if (flags & TCL_LEAVE_ERR_MSG) {
			/*
			 * Move the interpreter's object result to the
			 * string result, then reset the object result.
			 * FAILS IF OBJECT RESULT'S STRING REP HAS NULLS.
			 */
			
			Tcl_SetResult(interp,
	                        TclGetStringFromObj(Tcl_GetObjResult(interp),
				    (int *) NULL),
	                        TCL_VOLATILE);
		    }
		    goto done;
		}
		if (varNsPtr == NULL) {
		    if (flags & TCL_LEAVE_ERR_MSG) {
			VarErrMsg(interp, part1, part2, msg, badNamespace);
		    }
		    goto done;
		}
		if (tail == NULL) {







|
>










|
>
|
>
>
>
>



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


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



















|
|
|


>
>
>
>

|




<
<
<

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







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
				 * same as part2, or may be openParen+1. */
    char *openParen, *closeParen;
                                /* If this procedure parses a name into
				 * array and index, these point to the
				 * parens around the index.  Otherwise they
				 * are NULL. These are needed to restore
				 * the parens after parsing the name. */
    Namespace *varNsPtr, *cxtNsPtr, *dummy1Ptr, *dummy2Ptr;
    ResolverScheme *resPtr;
    Tcl_HashEntry *hPtr;
    register char *p;
    int new, i, result;

    varPtr = NULL;
    *arrayPtrPtr = NULL;
    openParen = closeParen = NULL;
    varNsPtr = NULL;		/* set non-NULL if a nonlocal variable */

    /*
     * Parse part1 into array name and index.
     * Always check if part1 is an array element name and allow it only if
     * part2 is not given.   
     * (if one does not care about creating array elements that can't be used
     *  from tcl, and prefer slightly better performance, one can put
     *  the following in an   if (part2 == NULL) { ... } block and remove
     *  the part2's test and error reporting  or move that code in array set)
     */

    elName = part2;

    for (p = part1; *p ; p++) {




	if (*p == '(') {
	    openParen = p;
	    do {
		p++;
	    } while (*p != '\0');
	    p--;
	    if (*p == ')') {
		if (part2 != NULL) {
		    openParen = NULL;
		    if (flags & TCL_LEAVE_ERR_MSG) {
			VarErrMsg(interp, part1, part2, msg, needArray);
		    }
		    goto done;
		}
		closeParen = p;
		*openParen = 0;
		elName = openParen+1;
	    } else {
		openParen = NULL;

	    }
	    break;

	}
    }

    /*
     * If this namespace has a variable resolver, then give it first
     * crack at the variable resolution.  It may return a Tcl_Var
     * value, it may signal to continue onward, or it may signal
     * an error.
     */
    if ((flags & TCL_GLOBAL_ONLY) != 0 || iPtr->varFramePtr == NULL) {
        cxtNsPtr = iPtr->globalNsPtr;
    } else {
        cxtNsPtr = iPtr->varFramePtr->nsPtr;
    }

    if (cxtNsPtr->varResProc != NULL || iPtr->resolverPtr != NULL) {
        resPtr = iPtr->resolverPtr;

        if (cxtNsPtr->varResProc) {
            result = (*cxtNsPtr->varResProc)(interp, part1,
		    (Tcl_Namespace *) cxtNsPtr, flags, &var);
        } else {
            result = TCL_CONTINUE;
        }

        while (result == TCL_CONTINUE && resPtr) {
            if (resPtr->varResProc) {
                result = (*resPtr->varResProc)(interp, part1,
			(Tcl_Namespace *) cxtNsPtr, flags, &var);
            }
            resPtr = resPtr->nextPtr;
        }

        if (result == TCL_OK) {
            varPtr = (Var *) var;
            goto lookupVarPart2;
        } else if (result != TCL_CONTINUE) {
            return (Var *) NULL;
        }
    }

    /*
     * Look up part1. Look it up as either a namespace variable or as a
     * local variable in a procedure call frame (varFramePtr).
     * Interpret part1 as a namespace variable if:
     *    1) so requested by a TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY flag,
     *    2) there is no active frame (we're at the global :: scope),
     *    3) the active frame was pushed to define the namespace context
     *       for a "namespace eval" or "namespace inscope" command,
     *    4) the name has namespace qualifiers ("::"s).
     * Otherwise, if part1 is a local variable, search first in the
     * frame's array of compiler-allocated local variables, then in its
     * hashtable for runtime-created local variables.
     *
     * If createPart1 and the variable isn't found, create the variable and,
     * if necessary, create varFramePtr's local var hashtable.
     */

    if (((flags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY)) != 0)
	    || (varFramePtr == NULL)
	    || !varFramePtr->isProcCallFrame
	    || (strstr(part1, "::") != NULL)) {
	char *tail;
	
	/*
	 * Don't pass TCL_LEAVE_ERR_MSG, we may yet create the variable,
	 * or otherwise generate our own error!
	 */
	var = Tcl_FindNamespaceVar(interp, part1, (Tcl_Namespace *) NULL,
		flags & ~TCL_LEAVE_ERR_MSG);
	if (var != (Tcl_Var) NULL) {
            varPtr = (Var *) var;
        }
	if (varPtr == NULL) {



	    if (createPart1) {   /* var wasn't found so create it  */
		TclGetNamespaceForQualName(interp, part1, (Namespace *) NULL,
			flags, &varNsPtr, &dummy1Ptr, &dummy2Ptr, &tail);
















		if (varNsPtr == NULL) {
		    if (flags & TCL_LEAVE_ERR_MSG) {
			VarErrMsg(interp, part1, part2, msg, badNamespace);
		    }
		    goto done;
		}
		if (tail == NULL) {
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
	Proc *procPtr = varFramePtr->procPtr;
	int localCt = procPtr->numCompiledLocals;
	CompiledLocal *localPtr = procPtr->firstLocalPtr;
	Var *localVarPtr = varFramePtr->compiledLocals;
	int part1Len = strlen(part1);
	
	for (i = 0;  i < localCt;  i++) {
	    if (!localPtr->isTemp) {
		char *localName = localVarPtr->name;
		if ((part1[0] == localName[0])
		        && (part1Len == localPtr->nameLength)
		        && (strcmp(part1, localName) == 0)) {
		    varPtr = localVarPtr;
		    break;
		}
	    }
	    localVarPtr++;
	    localPtr = localPtr->nextPtr;
	}
	if (varPtr == NULL) {	/* look in the frame's var hash table */
	    tablePtr = varFramePtr->varTablePtr;
	    if (createPart1) {
		if (tablePtr == NULL) {
		    tablePtr = (Tcl_HashTable *)
			    ckalloc(sizeof(Tcl_HashTable));
		    Tcl_InitHashTable(tablePtr, TCL_STRING_KEYS);
		    varFramePtr->varTablePtr = tablePtr;
		}
		hPtr = Tcl_CreateHashEntry(tablePtr, part1, &new);
		if (new) {
		    varPtr = NewVar();
		    Tcl_SetHashValue(hPtr, varPtr);







|
|















|







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
	Proc *procPtr = varFramePtr->procPtr;
	int localCt = procPtr->numCompiledLocals;
	CompiledLocal *localPtr = procPtr->firstLocalPtr;
	Var *localVarPtr = varFramePtr->compiledLocals;
	int part1Len = strlen(part1);
	
	for (i = 0;  i < localCt;  i++) {
	    if (!TclIsVarTemporary(localPtr)) {
		register char *localName = localVarPtr->name;
		if ((part1[0] == localName[0])
		        && (part1Len == localPtr->nameLength)
		        && (strcmp(part1, localName) == 0)) {
		    varPtr = localVarPtr;
		    break;
		}
	    }
	    localVarPtr++;
	    localPtr = localPtr->nextPtr;
	}
	if (varPtr == NULL) {	/* look in the frame's var hash table */
	    tablePtr = varFramePtr->varTablePtr;
	    if (createPart1) {
		if (tablePtr == NULL) {
		    tablePtr = (Tcl_HashTable *)
			ckalloc(sizeof(Tcl_HashTable));
		    Tcl_InitHashTable(tablePtr, TCL_STRING_KEYS);
		    varFramePtr->varTablePtr = tablePtr;
		}
		hPtr = Tcl_CreateHashEntry(tablePtr, part1, &new);
		if (new) {
		    varPtr = NewVar();
		    Tcl_SetHashValue(hPtr, varPtr);
306
307
308
309
310
311
312


313
314
315
316
317
318
319
		    }
		    goto done;
		}
		varPtr = (Var *) Tcl_GetHashValue(hPtr);
	    }
	}
    }


    if (openParen != NULL) {
	*openParen = '(';
	openParen = NULL;
    }

    /*
     * If varPtr is a link variable, we have a reference to some variable







>
>







332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
		    }
		    goto done;
		}
		varPtr = (Var *) Tcl_GetHashValue(hPtr);
	    }
	}
    }

    lookupVarPart2:
    if (openParen != NULL) {
	*openParen = '(';
	openParen = NULL;
    }

    /*
     * If varPtr is a link variable, we have a reference to some variable
342
343
344
345
346
347
348













349
350
351
352
353
354
355
356
357
358
359
	if (!createPart1) {
	    if (flags & TCL_LEAVE_ERR_MSG) {
		VarErrMsg(interp, part1, part2, msg, noSuchVar);
	    }
	    varPtr = NULL;
	    goto done;
	}













	TclSetVarArray(varPtr);
	TclClearVarUndefined(varPtr);
	varPtr->value.tablePtr =
	        (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
	Tcl_InitHashTable(varPtr->value.tablePtr, TCL_STRING_KEYS);
    } else if (!TclIsVarArray(varPtr)) {
	if (flags & TCL_LEAVE_ERR_MSG) {
	    VarErrMsg(interp, part1, part2, msg, needArray);
	}
	varPtr = NULL;
	goto done;







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



|







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
	if (!createPart1) {
	    if (flags & TCL_LEAVE_ERR_MSG) {
		VarErrMsg(interp, part1, part2, msg, noSuchVar);
	    }
	    varPtr = NULL;
	    goto done;
	}

	/*
	 * Make sure we are not resurrecting a namespace variable from a
	 * deleted namespace!
	 */
	if ((varPtr->flags & VAR_IN_HASHTABLE) && (varPtr->hPtr == NULL)) {
	    if (flags & TCL_LEAVE_ERR_MSG) {
		VarErrMsg(interp, part1, part2, msg, danglingVar);
	    }
	    varPtr = NULL;
	    goto done;
	}

	TclSetVarArray(varPtr);
	TclClearVarUndefined(varPtr);
	varPtr->value.tablePtr =
	    (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
	Tcl_InitHashTable(varPtr->value.tablePtr, TCL_STRING_KEYS);
    } else if (!TclIsVarArray(varPtr)) {
	if (flags & TCL_LEAVE_ERR_MSG) {
	    VarErrMsg(interp, part1, part2, msg, needArray);
	}
	varPtr = NULL;
	goto done;
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
 *
 *	Return the value of a Tcl variable as a string.
 *
 * Results:
 *	The return value points to the current value of varName as a string.
 *	If the variable is not defined or can't be read because of a clash
 *	in array usage then a NULL pointer is returned and an error message
 *	is left in interp->result if the TCL_LEAVE_ERR_MSG flag is set.
 *	Note: the return value is only valid up until the next change to the
 *	variable; if you depend on the value lasting longer than that, then
 *	make yourself a private copy.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_GetVar(interp, varName, flags)
    Tcl_Interp *interp;		/* Command interpreter in which varName is
				 * to be looked up. */
    char *varName;		/* Name of a variable in interp. */
    int flags;			/* OR-ed combination of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY or TCL_LEAVE_ERR_MSG
				 * bits. */
{
    return Tcl_GetVar2(interp, varName, (char *) NULL,
		       (flags | TCL_PARSE_PART1));
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetVar2 --
 *
 *	Return the value of a Tcl variable as a string, given a two-part
 *	name consisting of array name and element within array.
 *
 * Results:
 *	The return value points to the current value of the variable given
 *	by part1 and part2 as a string. If the specified variable doesn't
 *	exist, or if there is a clash in array usage, then NULL is returned
 *	and a message will be left in interp->result if the
 *	TCL_LEAVE_ERR_MSG flag is set. Note: the return value is only valid
 *	up until the next change to the variable; if you depend on the value
 *	lasting longer than that, then make yourself a private copy.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_GetVar2(interp, part1, part2, flags)
    Tcl_Interp *interp;		/* Command interpreter in which variable is
				 * to be looked up. */
    char *part1;		/* Name of an array (if part2 is non-NULL)
				 * or the name of a variable. */
    char *part2;		/* If non-NULL, gives the name of an element
				 * in the array part1. */
    int flags;			/* OR-ed combination of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, TCL_LEAVE_ERR_MSG,
                                 * and TCL_PARSE_PART1 bits. */
{
    register Tcl_Obj *part1Ptr;
    register Tcl_Obj *part2Ptr = NULL;
    Tcl_Obj *objPtr;
    int length;

    length = strlen(part1);
    TclNewObj(part1Ptr);
    TclInitStringRep(part1Ptr, part1, length);
    Tcl_IncrRefCount(part1Ptr);

    if (part2 != NULL) {
        length = strlen(part2);
        TclNewObj(part2Ptr);
        TclInitStringRep(part2Ptr, part2, length);
	Tcl_IncrRefCount(part2Ptr);
    }
    
    objPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags);
    
    TclDecrRefCount(part1Ptr);	    /* done with the part1 name object */
    if (part2Ptr != NULL) {
	TclDecrRefCount(part2Ptr);  /* and the part2 name object */
    }
    
    if (objPtr == NULL) {
	/*
	 * Move the interpreter's object result to the string result, 
	 * then reset the object result.
	 * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
	 */

	Tcl_SetResult(interp,
	        TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
	        TCL_VOLATILE);
	return NULL;
    }

    /*
     * THIS FAILS IF Tcl_ObjGetVar2's RESULT'S STRING REP HAS A NULL BYTE.
     */
    
    return TclGetStringFromObj(objPtr, (int *) NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ObjGetVar2 --
 *
 *	Return the value of a Tcl variable as a Tcl object, given a
 *	two-part name consisting of array name and element within array.







|



















|
<














|



















|
|

<
<

<

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

<
<
<
<
<
<
<
<
<


<
<
<
<
<
|

<







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
 *
 *	Return the value of a Tcl variable as a string.
 *
 * Results:
 *	The return value points to the current value of varName as a string.
 *	If the variable is not defined or can't be read because of a clash
 *	in array usage then a NULL pointer is returned and an error message
 *	is left in the interp's result if the TCL_LEAVE_ERR_MSG flag is set.
 *	Note: the return value is only valid up until the next change to the
 *	variable; if you depend on the value lasting longer than that, then
 *	make yourself a private copy.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_GetVar(interp, varName, flags)
    Tcl_Interp *interp;		/* Command interpreter in which varName is
				 * to be looked up. */
    char *varName;		/* Name of a variable in interp. */
    int flags;			/* OR-ed combination of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY or TCL_LEAVE_ERR_MSG
				 * bits. */
{
    return Tcl_GetVar2(interp, varName, (char *) NULL, flags);

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetVar2 --
 *
 *	Return the value of a Tcl variable as a string, given a two-part
 *	name consisting of array name and element within array.
 *
 * Results:
 *	The return value points to the current value of the variable given
 *	by part1 and part2 as a string. If the specified variable doesn't
 *	exist, or if there is a clash in array usage, then NULL is returned
 *	and a message will be left in the interp's result if the
 *	TCL_LEAVE_ERR_MSG flag is set. Note: the return value is only valid
 *	up until the next change to the variable; if you depend on the value
 *	lasting longer than that, then make yourself a private copy.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
Tcl_GetVar2(interp, part1, part2, flags)
    Tcl_Interp *interp;		/* Command interpreter in which variable is
				 * to be looked up. */
    char *part1;		/* Name of an array (if part2 is non-NULL)
				 * or the name of a variable. */
    char *part2;		/* If non-NULL, gives the name of an element
				 * in the array part1. */
    int flags;			/* OR-ed combination of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY and TCL_LEAVE_ERR_MSG
                                 * bits. */
{


    Tcl_Obj *objPtr;






    objPtr = Tcl_GetVar2Ex(interp, part1, part2, flags);














    if (objPtr == NULL) {









	return NULL;
    }





    return TclGetString(objPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ObjGetVar2 --
 *
 *	Return the value of a Tcl variable as a Tcl object, given a
 *	two-part name consisting of array name and element within array.
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
    register Tcl_Obj *part2Ptr;	/* If non-null, points to an object holding
				 * the name of an element in the array
				 * part1Ptr. */
    int flags;			/* OR-ed combination of TCL_GLOBAL_ONLY,
				 * TCL_LEAVE_ERR_MSG, and
				 * TCL_PARSE_PART1 bits. */
{
    Interp *iPtr = (Interp *) interp;
    register Var *varPtr;
    Var *arrayPtr;
    char *part1, *msg;





    char *part2 = NULL;





    /*
     * THIS FAILS IF A NAME OBJECT'S STRING REP HAS A NULL BYTE.




















     */

    part1 = TclGetStringFromObj(part1Ptr, (int *) NULL);
    if (part2Ptr != NULL) {


	part2 = TclGetStringFromObj(part2Ptr, (int *) NULL);










    }
    varPtr = TclLookupVar(interp, part1, part2, flags, "read",
            /*createPart1*/ 0, /*createPart2*/ 1, &arrayPtr);
    if (varPtr == NULL) {
	return NULL;
    }

    /*
     * Invoke any traces that have been set for the variable.
     */

    if ((varPtr->tracePtr != NULL)
	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
	msg = CallTraces(iPtr, arrayPtr, varPtr, part1, part2,
		(flags & (TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|TCL_PARSE_PART1)) | TCL_TRACE_READS);
	if (msg != NULL) {
	    if (flags & TCL_LEAVE_ERR_MSG) {
		VarErrMsg(interp, part1, part2, "read", msg);
	    }
	    goto errorReturn;
	}
    }







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

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













|







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
    register Tcl_Obj *part2Ptr;	/* If non-null, points to an object holding
				 * the name of an element in the array
				 * part1Ptr. */
    int flags;			/* OR-ed combination of TCL_GLOBAL_ONLY,
				 * TCL_LEAVE_ERR_MSG, and
				 * TCL_PARSE_PART1 bits. */
{



    char *part1, *part2;

    part1 = Tcl_GetString(part1Ptr);
    if (part2Ptr != NULL) {
	part2 = Tcl_GetString(part2Ptr);
    } else {
	part2 = NULL;
    }
    
    return Tcl_GetVar2Ex(interp, part1, part2, flags);
}

/*

 *----------------------------------------------------------------------
 *
 * Tcl_GetVar2Ex --
 *
 *	Return the value of a Tcl variable as a Tcl object, given a
 *	two-part name consisting of array name and element within array.
 *
 * Results:
 *	The return value points to the current object value of the variable
 *	given by part1Ptr and part2Ptr. If the specified variable doesn't
 *	exist, or if there is a clash in array usage, then NULL is returned
 *	and a message will be left in the interpreter's result if the
 *	TCL_LEAVE_ERR_MSG flag is set.
 *
 * Side effects:
 *	The ref count for the returned object is _not_ incremented to
 *	reflect the returned reference; if you want to keep a reference to
 *	the object you must increment its ref count yourself.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tcl_GetVar2Ex(interp, part1, part2, flags)
    Tcl_Interp *interp;		/* Command interpreter in which variable is
				 * to be looked up. */
    char *part1;		/* Name of an array (if part2 is non-NULL)
				 * or the name of a variable. */
    char *part2;		/* If non-NULL, gives the name of an element
				 * in the array part1. */
    int flags;			/* OR-ed combination of TCL_GLOBAL_ONLY,
				 * and TCL_LEAVE_ERR_MSG bits. */
{
    Interp *iPtr = (Interp *) interp;
    register Var *varPtr;
    Var *arrayPtr;
    char *msg;

    varPtr = TclLookupVar(interp, part1, part2, flags, "read",
            /*createPart1*/ 0, /*createPart2*/ 1, &arrayPtr);
    if (varPtr == NULL) {
	return NULL;
    }

    /*
     * Invoke any traces that have been set for the variable.
     */

    if ((varPtr->tracePtr != NULL)
	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
	msg = CallTraces(iPtr, arrayPtr, varPtr, part1, part2,
		(flags & (TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY)) | TCL_TRACE_READS);
	if (msg != NULL) {
	    if (flags & TCL_LEAVE_ERR_MSG) {
		VarErrMsg(interp, part1, part2, "read", msg);
	    }
	    goto errorReturn;
	}
    }
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
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TclGetIndexedScalar(interp, localIndex, leaveErrorMsg)
    Tcl_Interp *interp;		/* Command interpreter in which variable is
				 * to be looked up. */
    int localIndex;		/* Index of variable in procedure's array
				 * of local variables. */
    int leaveErrorMsg;		/* 1 if to leave an error message in
				 * interpreter's result on an error.
				 * Otherwise no error message is left. */
{
    Interp *iPtr = (Interp *) interp;
    CallFrame *varFramePtr = iPtr->varFramePtr;
				/* Points to the procedure call frame whose
				 * variables are currently in use. Same as
				 * the current procedure's frame, if any,
				 * unless an "uplevel" is executing. */
    Var *compiledLocals = varFramePtr->compiledLocals;
    Var *varPtr;		/* Points to the variable's in-frame Var
				 * structure. */
    char *varName;		/* Name of the local variable. */
    char *msg;

#ifdef TCL_COMPILE_DEBUG
    Proc *procPtr = varFramePtr->procPtr;
    int localCt = procPtr->numCompiledLocals;

    if (compiledLocals == NULL) {
	fprintf(stderr, "\nTclGetIndexedScalar: can't get local %i in frame 0x%x, no compiled locals\n",
		    localIndex, (unsigned int) varFramePtr);
	panic("TclGetIndexedScalar: no compiled locals in frame 0x%x",
	      (unsigned int) varFramePtr);
    }
    if ((localIndex < 0) || (localIndex >= localCt)) {
	fprintf(stderr, "\nTclGetIndexedScalar: can't get local %i in frame 0x%x with %i locals\n",
		    localIndex, (unsigned int) varFramePtr, localCt);
	panic("TclGetIndexedScalar: bad local index %i in frame 0x%x",
	      localIndex, (unsigned int) varFramePtr);
    }
#endif /* TCL_COMPILE_DEBUG */
    
    varPtr = &(compiledLocals[localIndex]);
    varName = varPtr->name;

    /*







|












|





<
|



|

|



|

|







683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708

709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TclGetIndexedScalar(interp, localIndex, leaveErrorMsg)
    Tcl_Interp *interp;		/* Command interpreter in which variable is
				 * to be looked up. */
    register int localIndex;	/* Index of variable in procedure's array
				 * of local variables. */
    int leaveErrorMsg;		/* 1 if to leave an error message in
				 * interpreter's result on an error.
				 * Otherwise no error message is left. */
{
    Interp *iPtr = (Interp *) interp;
    CallFrame *varFramePtr = iPtr->varFramePtr;
				/* Points to the procedure call frame whose
				 * variables are currently in use. Same as
				 * the current procedure's frame, if any,
				 * unless an "uplevel" is executing. */
    Var *compiledLocals = varFramePtr->compiledLocals;
    register Var *varPtr;	/* Points to the variable's in-frame Var
				 * structure. */
    char *varName;		/* Name of the local variable. */
    char *msg;

#ifdef TCL_COMPILE_DEBUG

    int localCt = varFramePtr->procPtr->numCompiledLocals;

    if (compiledLocals == NULL) {
	fprintf(stderr, "\nTclGetIndexedScalar: can't get local %i in frame 0x%x, no compiled locals\n",
		localIndex, (unsigned int) varFramePtr);
	panic("TclGetIndexedScalar: no compiled locals in frame 0x%x",
		(unsigned int) varFramePtr);
    }
    if ((localIndex < 0) || (localIndex >= localCt)) {
	fprintf(stderr, "\nTclGetIndexedScalar: can't get local %i in frame 0x%x with %i locals\n",
		localIndex, (unsigned int) varFramePtr, localCt);
	panic("TclGetIndexedScalar: bad local index %i in frame 0x%x",
		localIndex, (unsigned int) varFramePtr);
    }
#endif /* TCL_COMPILE_DEBUG */
    
    varPtr = &(compiledLocals[localIndex]);
    varName = varPtr->name;

    /*
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712

    /*
     * Invoke any traces that have been set for the variable.
     */

    if (varPtr->tracePtr != NULL) {
	msg = CallTraces(iPtr, /*arrayPtr*/ NULL, varPtr, varName, NULL,
	        TCL_TRACE_READS);
	if (msg != NULL) {
	    if (leaveErrorMsg) {
		VarErrMsg(interp, varName, NULL, "read", msg);
	    }
	    return NULL;
	}
    }







|







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

    /*
     * Invoke any traces that have been set for the variable.
     */

    if (varPtr->tracePtr != NULL) {
	msg = CallTraces(iPtr, /*arrayPtr*/ NULL, varPtr, varName, NULL,
		TCL_TRACE_READS);
	if (msg != NULL) {
	    if (leaveErrorMsg) {
		VarErrMsg(interp, varName, NULL, "read", msg);
	    }
	    return NULL;
	}
    }
720
721
722
723
724
725
726

727
728
729
730
731
732
733
	if (leaveErrorMsg) {
	    if (TclIsVarArray(varPtr)) {
		msg = isArray;
	    } else {
		msg = noSuchVar;
	    }
	    VarErrMsg(interp, varName, NULL, "read", msg);

	}
	return NULL;
    }
    return varPtr->value.objPtr;
}

/*







>







760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
	if (leaveErrorMsg) {
	    if (TclIsVarArray(varPtr)) {
		msg = isArray;
	    } else {
		msg = noSuchVar;
	    }
	    VarErrMsg(interp, varName, NULL, "read", msg);

	}
	return NULL;
    }
    return varPtr->value.objPtr;
}

/*
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

#ifdef TCL_COMPILE_DEBUG
    Proc *procPtr = varFramePtr->procPtr;
    int localCt = procPtr->numCompiledLocals;

    if (compiledLocals == NULL) {
	fprintf(stderr, "\nTclGetElementOfIndexedArray: can't get element of local %i in frame 0x%x, no compiled locals\n",
		    localIndex, (unsigned int) varFramePtr);
	panic("TclGetIndexedScalar: no compiled locals in frame 0x%x",
	      (unsigned int) varFramePtr);
    }
    if ((localIndex < 0) || (localIndex >= localCt)) {
	fprintf(stderr, "\nTclGetIndexedScalar: can't get element of local %i in frame 0x%x with %i locals\n",
		    localIndex, (unsigned int) varFramePtr, localCt);
	panic("TclGetElementOfIndexedArray: bad local index %i in frame 0x%x",
	      localIndex, (unsigned int) varFramePtr);
    }
#endif /* TCL_COMPILE_DEBUG */

    /*
     * THIS FAILS IF THE ELEMENT NAME OBJECT'S STRING REP HAS A NULL BYTE.
     */
    
    elem = Tcl_GetStringFromObj(elemPtr, (int *) NULL);
    arrayPtr = &(compiledLocals[localIndex]);
    arrayName = arrayPtr->name;

    /*
     * If arrayPtr is a link variable, we have a reference to some variable
     * that was created through an "upvar" or "global" command, or we have a
     * reference to a variable in an enclosing namespace. Traverse through







|

|



|

|



<
<
<
|
<







827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845



846

847
848
849
850
851
852
853

#ifdef TCL_COMPILE_DEBUG
    Proc *procPtr = varFramePtr->procPtr;
    int localCt = procPtr->numCompiledLocals;

    if (compiledLocals == NULL) {
	fprintf(stderr, "\nTclGetElementOfIndexedArray: can't get element of local %i in frame 0x%x, no compiled locals\n",
		localIndex, (unsigned int) varFramePtr);
	panic("TclGetIndexedScalar: no compiled locals in frame 0x%x",
		(unsigned int) varFramePtr);
    }
    if ((localIndex < 0) || (localIndex >= localCt)) {
	fprintf(stderr, "\nTclGetIndexedScalar: can't get element of local %i in frame 0x%x with %i locals\n",
		localIndex, (unsigned int) varFramePtr, localCt);
	panic("TclGetElementOfIndexedArray: bad local index %i in frame 0x%x",
		localIndex, (unsigned int) varFramePtr);
    }
#endif /* TCL_COMPILE_DEBUG */




    elem = TclGetString(elemPtr);

    arrayPtr = &(compiledLocals[localIndex]);
    arrayName = arrayPtr->name;

    /*
     * If arrayPtr is a link variable, we have a reference to some variable
     * that was created through an "upvar" or "global" command, or we have a
     * reference to a variable in an enclosing namespace. Traverse through
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932

933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetCmd --
 *
 *	This procedure is invoked to process the "set" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result value.
 *
 * Side effects:
 *	A variable's value may be changed.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_SetCmd(dummy, interp, argc, argv)
    ClientData dummy;			/* Not used. */
    register Tcl_Interp *interp;	/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    if (argc == 2) {
	char *value;

	value = Tcl_GetVar2(interp, argv[1], (char *) NULL,

		TCL_LEAVE_ERR_MSG|TCL_PARSE_PART1);
	if (value == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetResult(interp, value, TCL_VOLATILE);
	return TCL_OK;
    } else if (argc == 3) {
	char *result;

	result = Tcl_SetVar2(interp, argv[1], (char *) NULL, argv[2],
		TCL_LEAVE_ERR_MSG|TCL_PARSE_PART1);
	if (result == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetResult(interp, result, TCL_VOLATILE);
	return TCL_OK;
    } else {
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " varName ?newValue?\"", (char *) NULL);
	return TCL_ERROR;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetVar --
 *
 *	Change the value of a variable.
 *
 * Results:
 *	Returns a pointer to the malloc'ed string which is the character
 *	representation of the variable's new value. The caller must not
 *	modify this string. If the write operation was disallowed then NULL
 *	is returned; if the TCL_LEAVE_ERR_MSG flag is set, then an
 *	explanatory message will be left in interp->result. Note that the
 *	returned string may not be the same as newValue; this is because
 *	variable traces may modify the variable's value.
 *
 * Side effects:
 *	If varName is defined as a local or global variable in interp,
 *	its value is changed to newValue. If varName isn't currently
 *	defined, then a new global variable by that name is created.







|















|


|
|

<
|

<
>
|
|


|

|
<

|
|
|


|


<
|
















|







937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965

966
967

968
969
970
971
972
973
974
975

976
977
978
979
980
981
982
983
984

985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetObjCmd --
 *
 *	This procedure is invoked to process the "set" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result value.
 *
 * Side effects:
 *	A variable's value may be changed.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_SetObjCmd(dummy, interp, objc, objv)
    ClientData dummy;			/* Not used. */
    register Tcl_Interp *interp;	/* Current interpreter. */
    int objc;				/* Number of arguments. */
    Tcl_Obj *CONST objv[];		/* Argument objects. */
{

    Tcl_Obj *varValueObj;


    if (objc == 2) {
	varValueObj = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG);
	if (varValueObj == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, varValueObj);
	return TCL_OK;
    } else if (objc == 3) {


	varValueObj = Tcl_ObjSetVar2(interp, objv[1], NULL, objv[2],
		TCL_LEAVE_ERR_MSG);
	if (varValueObj == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, varValueObj);
	return TCL_OK;
    } else {

	Tcl_WrongNumArgs(interp, 1, objv, "varName ?newValue?");
	return TCL_ERROR;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetVar --
 *
 *	Change the value of a variable.
 *
 * Results:
 *	Returns a pointer to the malloc'ed string which is the character
 *	representation of the variable's new value. The caller must not
 *	modify this string. If the write operation was disallowed then NULL
 *	is returned; if the TCL_LEAVE_ERR_MSG flag is set, then an
 *	explanatory message will be left in the interp's result. Note that the
 *	returned string may not be the same as newValue; this is because
 *	variable traces may modify the variable's value.
 *
 * Side effects:
 *	If varName is defined as a local or global variable in interp,
 *	its value is changed to newValue. If varName isn't currently
 *	defined, then a new global variable by that name is created.
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
    char *varName;		/* Name of a variable in interp. */
    char *newValue;		/* New value for varName. */
    int flags;			/* Various flags that tell how to set value:
				 * any of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, TCL_APPEND_VALUE,
				 * TCL_LIST_ELEMENT, TCL_LEAVE_ERR_MSG. */
{
    return Tcl_SetVar2(interp, varName, (char *) NULL, newValue,
		       (flags | TCL_PARSE_PART1));
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetVar2 --
 *
 *      Given a two-part variable name, which may refer either to a
 *      scalar variable or an element of an array, change the value
 *      of the variable.  If the named scalar or array or element
 *      doesn't exist then create one.
 *
 * Results:
 *	Returns a pointer to the malloc'ed string which is the character
 *	representation of the variable's new value. The caller must not
 *	modify this string. If the write operation was disallowed because an
 *	array was expected but not found (or vice versa), then NULL is
 *	returned; if the TCL_LEAVE_ERR_MSG flag is set, then an explanatory
 *	message will be left in interp->result. Note that the returned
 *	string may not be the same as newValue; this is because variable
 *	traces may modify the variable's value.
 *
 * Side effects:
 *      The value of the given variable is set. If either the array
 *      or the entry didn't exist then a new one is created.
 *







|
<


















|







1018
1019
1020
1021
1022
1023
1024
1025

1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
    char *varName;		/* Name of a variable in interp. */
    char *newValue;		/* New value for varName. */
    int flags;			/* Various flags that tell how to set value:
				 * any of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, TCL_APPEND_VALUE,
				 * TCL_LIST_ELEMENT, TCL_LEAVE_ERR_MSG. */
{
    return Tcl_SetVar2(interp, varName, (char *) NULL, newValue, flags);

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetVar2 --
 *
 *      Given a two-part variable name, which may refer either to a
 *      scalar variable or an element of an array, change the value
 *      of the variable.  If the named scalar or array or element
 *      doesn't exist then create one.
 *
 * Results:
 *	Returns a pointer to the malloc'ed string which is the character
 *	representation of the variable's new value. The caller must not
 *	modify this string. If the write operation was disallowed because an
 *	array was expected but not found (or vice versa), then NULL is
 *	returned; if the TCL_LEAVE_ERR_MSG flag is set, then an explanatory
 *	message will be left in the interp's result. Note that the returned
 *	string may not be the same as newValue; this is because variable
 *	traces may modify the variable's value.
 *
 * Side effects:
 *      The value of the given variable is set. If either the array
 *      or the entry didn't exist then a new one is created.
 *
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098






















































1099
1100
1101
1102
1103
1104
1105
                                 * an array. */
    char *part2;                /* Name of an element within an array, or
				 * NULL. */
    char *newValue;             /* New value for variable. */
    int flags;                  /* Various flags that tell how to set value:
				 * any of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, TCL_APPEND_VALUE,
				 * TCL_LIST_ELEMENT, TCL_LEAVE_ERR_MSG, or 
				 * TCL_PARSE_PART1. */
{
    register Tcl_Obj *valuePtr;
    register Tcl_Obj *part1Ptr;
    register Tcl_Obj *part2Ptr = NULL;
    Tcl_Obj *varValuePtr;
    int length;

    /*
     * Create an object holding the variable's new value and use
     * Tcl_ObjSetVar2 to actually set the variable.
     */

    length = newValue ? strlen(newValue) : 0;
    TclNewObj(valuePtr);
    TclInitStringRep(valuePtr, newValue, length);
    Tcl_IncrRefCount(valuePtr);

    length = strlen(part1) ;
    TclNewObj(part1Ptr);
    TclInitStringRep(part1Ptr, part1, length);
    Tcl_IncrRefCount(part1Ptr);

    if (part2 != NULL) {
        length = strlen(part2);
        TclNewObj(part2Ptr);
        TclInitStringRep(part2Ptr, part2, length);
	Tcl_IncrRefCount(part2Ptr);
    }
    
    varValuePtr = Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, valuePtr,
	    flags);
    
    TclDecrRefCount(part1Ptr);      /* done with the part1 name object */
    if (part2Ptr != NULL) {
	TclDecrRefCount(part2Ptr);  /* and the part2 name object */
    }
    Tcl_DecrRefCount(valuePtr); /* done with the object */
    
    if (varValuePtr == NULL) {
	/*
	 * Move the interpreter's object result to the string result, 
	 * then reset the object result.
	 * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
	 */

	Tcl_SetResult(interp,
	        TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
	        TCL_VOLATILE);
	return NULL;
    }

    /*
     * THIS FAILS IF Tcl_ObjSetVar2's RESULT'S STRING REP HAS A NULL BYTE.
     */

    return TclGetStringFromObj(varValuePtr, (int *) NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ObjSetVar2 --






















































 *
 *	Given a two-part variable name, which may refer either to a scalar
 *	variable or an element of an array, change the value of the variable
 *	to a new Tcl object value. If the named scalar or array or element
 *	doesn't exist then create one.
 *
 * Results:







|
<


<
<

<



|


<
|
<


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



<
<
<
<
<
<
<
<
<


<
<
<
<
<
|






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







1061
1062
1063
1064
1065
1066
1067
1068

1069
1070


1071

1072
1073
1074
1075
1076
1077

1078

1079
1080




1081














1082
1083
1084









1085
1086





1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
                                 * an array. */
    char *part2;                /* Name of an element within an array, or
				 * NULL. */
    char *newValue;             /* New value for variable. */
    int flags;                  /* Various flags that tell how to set value:
				 * any of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, TCL_APPEND_VALUE,
				 * TCL_LIST_ELEMENT, or TCL_LEAVE_ERR_MSG */

{
    register Tcl_Obj *valuePtr;


    Tcl_Obj *varValuePtr;


    /*
     * Create an object holding the variable's new value and use
     * Tcl_SetVar2Ex to actually set the variable.
     */


    valuePtr = Tcl_NewStringObj(newValue, -1);

    Tcl_IncrRefCount(valuePtr);





    varValuePtr = Tcl_SetVar2Ex(interp, part1, part2, valuePtr, flags);














    Tcl_DecrRefCount(valuePtr); /* done with the object */
    
    if (varValuePtr == NULL) {









	return NULL;
    }





    return TclGetString(varValuePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ObjSetVar2 --
 *
 *	This function is the same as Tcl_SetVar2Ex below, except the
 *	variable names are passed in Tcl object instead of strings.
 *
 * Results:
 *	Returns a pointer to the Tcl_Obj holding the new value of the
 *	variable. If the write operation was disallowed because an array was
 *	expected but not found (or vice versa), then NULL is returned; if
 *	the TCL_LEAVE_ERR_MSG flag is set, then an explanatory message will
 *	be left in the interpreter's result. Note that the returned object
 *	may not be the same one referenced by newValuePtr; this is because
 *	variable traces may modify the variable's value.
 *
 * Side effects:
 *	The value of the given variable is set. If either the array or the
 *	entry didn't exist then a new variable is created.

 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, newValuePtr, flags)
    Tcl_Interp *interp;		/* Command interpreter in which variable is
				 * to be found. */
    register Tcl_Obj *part1Ptr;	/* Points to an object holding the name of
				 * an array (if part2 is non-NULL) or the
				 * name of a variable. */
    register Tcl_Obj *part2Ptr;	/* If non-null, points to an object holding
				 * the name of an element in the array
				 * part1Ptr. */
    Tcl_Obj *newValuePtr;	/* New value for variable. */
    int flags;			/* Various flags that tell how to set value:
				 * any of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, TCL_APPEND_VALUE,
				 * TCL_LIST_ELEMENT, TCL_LEAVE_ERR_MSG, or
				 * TCL_PARSE_PART1. */
{
    char *part1, *part2;

    part1 = Tcl_GetString(part1Ptr);
    if (part2Ptr != NULL) {
	part2 = Tcl_GetString(part2Ptr);
    } else {
	part2 = NULL;
    }
    
    return Tcl_SetVar2Ex(interp, part1, part2, newValuePtr, flags);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetVar2Ex --
 *
 *	Given a two-part variable name, which may refer either to a scalar
 *	variable or an element of an array, change the value of the variable
 *	to a new Tcl object value. If the named scalar or array or element
 *	doesn't exist then create one.
 *
 * Results:
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183

1184



1185
1186
1187
1188
1189
1190
1191
 *	The value of the given variable is set. If either the array or the
 *	entry didn't exist then a new variable is created.
 *
 *	The reference count is decremented for any old value of the variable
 *	and incremented for its new value. If the new value for the variable
 *	is not the same one referenced by newValuePtr (perhaps as a result
 *	of a variable trace), then newValuePtr's ref count is left unchanged
 *	by Tcl_ObjSetVar2. newValuePtr's ref count is also left unchanged if
 *	we are appending it as a string value: that is, if "flags" includes
 *	TCL_APPEND_VALUE but not TCL_LIST_ELEMENT.
 *
 *	The reference count for the returned object is _not_ incremented: if
 *	you want to keep a reference to the object you must increment its
 *	ref count yourself.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, newValuePtr, flags)
    Tcl_Interp *interp;		/* Command interpreter in which variable is
				 * to be found. */
    register Tcl_Obj *part1Ptr;	/* Points to an object holding the name of
				 * an array (if part2 is non-NULL) or the
				 * name of a variable. */
    register Tcl_Obj *part2Ptr;	/* If non-null, points to an object holding
				 * the name of an element in the array
				 * part1Ptr. */
    Tcl_Obj *newValuePtr;	/* New value for variable. */
    int flags;			/* Various flags that tell how to set value:
				 * any of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, TCL_APPEND_VALUE,
				 * TCL_LIST_ELEMENT, TCL_LEAVE_ERR_MSG, or
				 * TCL_PARSE_PART1. */
{
    Interp *iPtr = (Interp *) interp;
    register Var *varPtr;
    Var *arrayPtr;
    Tcl_Obj *oldValuePtr;
    Tcl_Obj *resultPtr = NULL;
    char *part1, *bytes;
    char *part2 = NULL;
    int length, result;

    /*
     * THIS FAILS IF A NAME OBJECT'S STRING REP HAS A NULL BYTE.
     */

    part1 = TclGetStringFromObj(part1Ptr, (int *) NULL);
    if (part2Ptr != NULL) {
	part2 = TclGetStringFromObj(part2Ptr, (int *) NULL);
    }
    
    varPtr = TclLookupVar(interp, part1, part2, flags, "set",
	    /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
    if (varPtr == NULL) {
	return NULL;
    }

    /*
     * If the variable is in a hashtable and its hPtr field is NULL, then we
     * have an upvar to an array element where the array was deleted,
     * leaving the element dangling at the end of the upvar. Generate an
     * error (allowing the variable to be reset would screw up our storage
     * allocation and is meaningless anyway).
     */

    if ((varPtr->flags & VAR_IN_HASHTABLE) && (varPtr->hPtr == NULL)) {
	if (flags & TCL_LEAVE_ERR_MSG) {

	    VarErrMsg(interp, part1, part2, "set", danglingUpvar);



	}
	return NULL;
    }

    /*
     * It's an error to try to set an array variable itself.
     */







|











|


<
|
|
<
|
|




|
<






|
<


<
<
<
<
<
<
<
<
<








|
|
|
|




>
|
>
>
>







1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185

1186
1187

1188
1189
1190
1191
1192
1193
1194

1195
1196
1197
1198
1199
1200
1201

1202
1203









1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
 *	The value of the given variable is set. If either the array or the
 *	entry didn't exist then a new variable is created.
 *
 *	The reference count is decremented for any old value of the variable
 *	and incremented for its new value. If the new value for the variable
 *	is not the same one referenced by newValuePtr (perhaps as a result
 *	of a variable trace), then newValuePtr's ref count is left unchanged
 *	by Tcl_SetVar2Ex. newValuePtr's ref count is also left unchanged if
 *	we are appending it as a string value: that is, if "flags" includes
 *	TCL_APPEND_VALUE but not TCL_LIST_ELEMENT.
 *
 *	The reference count for the returned object is _not_ incremented: if
 *	you want to keep a reference to the object you must increment its
 *	ref count yourself.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tcl_SetVar2Ex(interp, part1, part2, newValuePtr, flags)
    Tcl_Interp *interp;		/* Command interpreter in which variable is
				 * to be found. */

    char *part1;		/* Name of an array (if part2 is non-NULL)
				 * or the name of a variable. */

    char *part2;		/* If non-NULL, gives the name of an element
				 * in the array part1. */
    Tcl_Obj *newValuePtr;	/* New value for variable. */
    int flags;			/* Various flags that tell how to set value:
				 * any of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, TCL_APPEND_VALUE,
				 * TCL_LIST_ELEMENT or TCL_LEAVE_ERR_MSG. */

{
    Interp *iPtr = (Interp *) interp;
    register Var *varPtr;
    Var *arrayPtr;
    Tcl_Obj *oldValuePtr;
    Tcl_Obj *resultPtr = NULL;
    char *bytes;

    int length, result;










    varPtr = TclLookupVar(interp, part1, part2, flags, "set",
	    /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
    if (varPtr == NULL) {
	return NULL;
    }

    /*
     * If the variable is in a hashtable and its hPtr field is NULL, then we
     * may have an upvar to an array element where the array was deleted
     * or an upvar to a namespace variable whose namespace was deleted.
     * Generate an error (allowing the variable to be reset would screw up
     * our storage allocation and is meaningless anyway).
     */

    if ((varPtr->flags & VAR_IN_HASHTABLE) && (varPtr->hPtr == NULL)) {
	if (flags & TCL_LEAVE_ERR_MSG) {
	    if (TclIsVarArrayElement(varPtr)) {
		VarErrMsg(interp, part1, part2, "set", danglingElement);
	    } else {
		VarErrMsg(interp, part1, part2, "set", danglingVar);
	    }
	}
	return NULL;
    }

    /*
     * It's an error to try to set an array variable itself.
     */
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
	    if (oldValuePtr != NULL) {
		Tcl_DecrRefCount(oldValuePtr); /* discard old value */
	    }
	    bytes = Tcl_GetStringFromObj(newValuePtr, &length);
	    neededBytes = Tcl_ScanElement(bytes, &listFlags);
	    oldValuePtr = Tcl_NewObj();
	    oldValuePtr->bytes = (char *)
		    ckalloc((unsigned) (neededBytes + 1));
	    oldValuePtr->length = Tcl_ConvertElement(bytes,
		    oldValuePtr->bytes, listFlags);
	    varPtr->value.objPtr = oldValuePtr;
	    Tcl_IncrRefCount(varPtr->value.objPtr);
	} else if (newValuePtr != oldValuePtr) {
	    varPtr->value.objPtr = newValuePtr;
	    Tcl_IncrRefCount(newValuePtr);      /* var is another ref */







|







1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
	    if (oldValuePtr != NULL) {
		Tcl_DecrRefCount(oldValuePtr); /* discard old value */
	    }
	    bytes = Tcl_GetStringFromObj(newValuePtr, &length);
	    neededBytes = Tcl_ScanElement(bytes, &listFlags);
	    oldValuePtr = Tcl_NewObj();
	    oldValuePtr->bytes = (char *)
		ckalloc((unsigned) (neededBytes + 1));
	    oldValuePtr->length = Tcl_ConvertElement(bytes,
		    oldValuePtr->bytes, listFlags);
	    varPtr->value.objPtr = oldValuePtr;
	    Tcl_IncrRefCount(varPtr->value.objPtr);
	} else if (newValuePtr != oldValuePtr) {
	    varPtr->value.objPtr = newValuePtr;
	    Tcl_IncrRefCount(newValuePtr);      /* var is another ref */
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
    /*
     * Invoke any write traces for the variable.
     */

    if ((varPtr->tracePtr != NULL)
	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
	char *msg = CallTraces(iPtr, arrayPtr, varPtr, part1, part2,
	        (flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_PARSE_PART1)) | TCL_TRACE_WRITES);
	if (msg != NULL) {
	    if (flags & TCL_LEAVE_ERR_MSG) {
		VarErrMsg(interp, part1, part2, "set", msg);
	    }
	    goto cleanup;
	}
    }







|







1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
    /*
     * Invoke any write traces for the variable.
     */

    if ((varPtr->tracePtr != NULL)
	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
	char *msg = CallTraces(iPtr, arrayPtr, varPtr, part1, part2,
	        (flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY)) | TCL_TRACE_WRITES);
	if (msg != NULL) {
	    if (flags & TCL_LEAVE_ERR_MSG) {
		VarErrMsg(interp, part1, part2, "set", msg);
	    }
	    goto cleanup;
	}
    }
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436

1437



1438
1439
1440
1441
1442
1443
1444

#ifdef TCL_COMPILE_DEBUG
    Proc *procPtr = varFramePtr->procPtr;
    int localCt = procPtr->numCompiledLocals;

    if (compiledLocals == NULL) {
	fprintf(stderr, "\nTclSetIndexedScalar: can't set local %i in frame 0x%x, no compiled locals\n",
		    localIndex, (unsigned int) varFramePtr);
	panic("TclSetIndexedScalar: no compiled locals in frame 0x%x",
	      (unsigned int) varFramePtr);
    }
    if ((localIndex < 0) || (localIndex >= localCt)) {
	fprintf(stderr, "\nTclSetIndexedScalar: can't set local %i in frame 0x%x with %i locals\n",
		    localIndex, (unsigned int) varFramePtr, localCt);
	panic("TclSetIndexedScalar: bad local index %i in frame 0x%x",
	      localIndex, (unsigned int) varFramePtr);
    }
#endif /* TCL_COMPILE_DEBUG */
    
    varPtr = &(compiledLocals[localIndex]);
    varName = varPtr->name;

    /*
     * If varPtr is a link variable, we have a reference to some variable
     * that was created through an "upvar" or "global" command, or we have a
     * reference to a variable in an enclosing namespace. Traverse through
     * any links until we find the referenced variable.
     */
	
    while (TclIsVarLink(varPtr)) {
	varPtr = varPtr->value.linkPtr;
    }

    /*
     * If the variable is in a hashtable and its hPtr field is NULL, then we
     * have an upvar to an array element where the array was deleted,
     * leaving the element dangling at the end of the upvar. Generate an
     * error (allowing the variable to be reset would screw up our storage
     * allocation and is meaningless anyway).
     */

    if ((varPtr->flags & VAR_IN_HASHTABLE) && (varPtr->hPtr == NULL)) {
	if (leaveErrorMsg) {

	    VarErrMsg(interp, varName, NULL, "set", danglingUpvar);



	}
	return NULL;
    }

    /*
     * It's an error to try to set an array variable itself.
     */







|

|



|

|



















|
|
|
|




>
|
>
>
>







1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488

#ifdef TCL_COMPILE_DEBUG
    Proc *procPtr = varFramePtr->procPtr;
    int localCt = procPtr->numCompiledLocals;

    if (compiledLocals == NULL) {
	fprintf(stderr, "\nTclSetIndexedScalar: can't set local %i in frame 0x%x, no compiled locals\n",
		localIndex, (unsigned int) varFramePtr);
	panic("TclSetIndexedScalar: no compiled locals in frame 0x%x",
		(unsigned int) varFramePtr);
    }
    if ((localIndex < 0) || (localIndex >= localCt)) {
	fprintf(stderr, "\nTclSetIndexedScalar: can't set local %i in frame 0x%x with %i locals\n",
		localIndex, (unsigned int) varFramePtr, localCt);
	panic("TclSetIndexedScalar: bad local index %i in frame 0x%x",
		localIndex, (unsigned int) varFramePtr);
    }
#endif /* TCL_COMPILE_DEBUG */
    
    varPtr = &(compiledLocals[localIndex]);
    varName = varPtr->name;

    /*
     * If varPtr is a link variable, we have a reference to some variable
     * that was created through an "upvar" or "global" command, or we have a
     * reference to a variable in an enclosing namespace. Traverse through
     * any links until we find the referenced variable.
     */
	
    while (TclIsVarLink(varPtr)) {
	varPtr = varPtr->value.linkPtr;
    }

    /*
     * If the variable is in a hashtable and its hPtr field is NULL, then we
     * may have an upvar to an array element where the array was deleted
     * or an upvar to a namespace variable whose namespace was deleted.
     * Generate an error (allowing the variable to be reset would screw up
     * our storage allocation and is meaningless anyway).
     */

    if ((varPtr->flags & VAR_IN_HASHTABLE) && (varPtr->hPtr == NULL)) {
	if (leaveErrorMsg) {
	    if (TclIsVarArrayElement(varPtr)) {
		VarErrMsg(interp, varName, NULL, "set", danglingElement);
	    } else {
		VarErrMsg(interp, varName, NULL, "set", danglingVar);
	    }
	}
	return NULL;
    }

    /*
     * It's an error to try to set an array variable itself.
     */
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611



















1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
    
#ifdef TCL_COMPILE_DEBUG
    Proc *procPtr = varFramePtr->procPtr;
    int localCt = procPtr->numCompiledLocals;

    if (compiledLocals == NULL) {
	fprintf(stderr, "\nTclSetElementOfIndexedArray: can't set element of local %i in frame 0x%x, no compiled locals\n",
		    localIndex, (unsigned int) varFramePtr);
	panic("TclSetIndexedScalar: no compiled locals in frame 0x%x",
	      (unsigned int) varFramePtr);
    }
    if ((localIndex < 0) || (localIndex >= localCt)) {
	fprintf(stderr, "\nTclSetIndexedScalar: can't set elememt of local %i in frame 0x%x with %i locals\n",
		    localIndex, (unsigned int) varFramePtr, localCt);
	panic("TclSetElementOfIndexedArray: bad local index %i in frame 0x%x",
	      localIndex, (unsigned int) varFramePtr);
    }
#endif /* TCL_COMPILE_DEBUG */

    /*
     * THIS FAILS IF THE ELEMENT NAME OBJECT'S STRING REP HAS A NULL BYTE.
     */
    
    elem = Tcl_GetStringFromObj(elemPtr, (int *) NULL);
    arrayPtr = &(compiledLocals[localIndex]);
    arrayName = arrayPtr->name;

    /*
     * If arrayPtr is a link variable, we have a reference to some variable
     * that was created through an "upvar" or "global" command, or we have a
     * reference to a variable in an enclosing namespace. Traverse through
     * any links until we find the referenced variable.
     */
	
    while (TclIsVarLink(arrayPtr)) {
	arrayPtr = arrayPtr->value.linkPtr;
    }




















    /*
     * Make sure we're dealing with an array.
     */

    if (TclIsVarUndefined(arrayPtr) && !TclIsVarArrayElement(arrayPtr)) {
	TclSetVarArray(arrayPtr);
	arrayPtr->value.tablePtr =
	        (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
	Tcl_InitHashTable(arrayPtr->value.tablePtr, TCL_STRING_KEYS);
	TclClearVarUndefined(arrayPtr);
    } else if (!TclIsVarArray(arrayPtr)) {
	if (leaveErrorMsg) {
	    VarErrMsg(interp, arrayName, elem, "set", needArray);
	}
	goto errorReturn;







|

|



|

|



<
<
<
|
<













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








|







1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637



1638

1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
    
#ifdef TCL_COMPILE_DEBUG
    Proc *procPtr = varFramePtr->procPtr;
    int localCt = procPtr->numCompiledLocals;

    if (compiledLocals == NULL) {
	fprintf(stderr, "\nTclSetElementOfIndexedArray: can't set element of local %i in frame 0x%x, no compiled locals\n",
		localIndex, (unsigned int) varFramePtr);
	panic("TclSetIndexedScalar: no compiled locals in frame 0x%x",
		(unsigned int) varFramePtr);
    }
    if ((localIndex < 0) || (localIndex >= localCt)) {
	fprintf(stderr, "\nTclSetIndexedScalar: can't set elememt of local %i in frame 0x%x with %i locals\n",
		localIndex, (unsigned int) varFramePtr, localCt);
	panic("TclSetElementOfIndexedArray: bad local index %i in frame 0x%x",
		localIndex, (unsigned int) varFramePtr);
    }
#endif /* TCL_COMPILE_DEBUG */




    elem = TclGetString(elemPtr);

    arrayPtr = &(compiledLocals[localIndex]);
    arrayName = arrayPtr->name;

    /*
     * If arrayPtr is a link variable, we have a reference to some variable
     * that was created through an "upvar" or "global" command, or we have a
     * reference to a variable in an enclosing namespace. Traverse through
     * any links until we find the referenced variable.
     */
	
    while (TclIsVarLink(arrayPtr)) {
	arrayPtr = arrayPtr->value.linkPtr;
    }

    /*
     * If the variable is in a hashtable and its hPtr field is NULL, then we
     * may have an upvar to an array element where the array was deleted
     * or an upvar to a namespace variable whose namespace was deleted.
     * Generate an error (allowing the variable to be reset would screw up
     * our storage allocation and is meaningless anyway).
     */

    if ((arrayPtr->flags & VAR_IN_HASHTABLE) && (arrayPtr->hPtr == NULL)) {
	if (leaveErrorMsg) {
	    if (TclIsVarArrayElement(arrayPtr)) {
		VarErrMsg(interp, arrayName, elem, "set", danglingElement);
	    } else {
		VarErrMsg(interp, arrayName, elem, "set", danglingVar);
	    }
	}
	goto errorReturn;
    }

    /*
     * Make sure we're dealing with an array.
     */

    if (TclIsVarUndefined(arrayPtr) && !TclIsVarArrayElement(arrayPtr)) {
	TclSetVarArray(arrayPtr);
	arrayPtr->value.tablePtr =
	    (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
	Tcl_InitHashTable(arrayPtr->value.tablePtr, TCL_STRING_KEYS);
	TclClearVarUndefined(arrayPtr);
    } else if (!TclIsVarArray(arrayPtr)) {
	if (leaveErrorMsg) {
	    VarErrMsg(interp, arrayName, elem, "set", needArray);
	}
	goto errorReturn;
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
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
 *	incremented to reflect the returned reference; if you want to keep a
 *	reference to the object you must increment its ref count yourself.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TclIncrVar2(interp, part1Ptr, part2Ptr, incrAmount, part1NotParsed)
    Tcl_Interp *interp;		/* Command interpreter in which variable is
				 * to be found. */
    Tcl_Obj *part1Ptr;		/* Points to an object holding the name of
				 * an array (if part2 is non-NULL) or the
				 * name of a variable. */
    Tcl_Obj *part2Ptr;		/* If non-null, points to an object holding
				 * the name of an element in the array
				 * part1Ptr. */
    long incrAmount;		/* Amount to be added to variable. */
    int part1NotParsed;		/* 1 if part1 hasn't yet been parsed into
				 * an array name and index (if any). */


{
    register Tcl_Obj *varValuePtr;
    Tcl_Obj *resultPtr;
    int createdNewObj;		/* Set 1 if var's value object is shared
				 * so we must increment a copy (i.e. copy
				 * on write). */
    long i;
    int flags, result;

    flags = TCL_LEAVE_ERR_MSG;
    if (part1NotParsed) {
	flags |= TCL_PARSE_PART1;
    }
    
    varValuePtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags);
    if (varValuePtr == NULL) {
	Tcl_AddObjErrorInfo(interp,
		"\n    (reading value of variable to increment)", -1);
	return NULL;
    }








|









|
|
>
>







|

<
<
<
<
<







1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824





1825
1826
1827
1828
1829
1830
1831
 *	incremented to reflect the returned reference; if you want to keep a
 *	reference to the object you must increment its ref count yourself.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TclIncrVar2(interp, part1Ptr, part2Ptr, incrAmount, flags)
    Tcl_Interp *interp;		/* Command interpreter in which variable is
				 * to be found. */
    Tcl_Obj *part1Ptr;		/* Points to an object holding the name of
				 * an array (if part2 is non-NULL) or the
				 * name of a variable. */
    Tcl_Obj *part2Ptr;		/* If non-null, points to an object holding
				 * the name of an element in the array
				 * part1Ptr. */
    long incrAmount;		/* Amount to be added to variable. */
    int flags;                  /* Various flags that tell how to incr value:
				 * any of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, TCL_APPEND_VALUE,
				 * TCL_LIST_ELEMENT, TCL_LEAVE_ERR_MSG. */
{
    register Tcl_Obj *varValuePtr;
    Tcl_Obj *resultPtr;
    int createdNewObj;		/* Set 1 if var's value object is shared
				 * so we must increment a copy (i.e. copy
				 * on write). */
    long i;
    int result;






    varValuePtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags);
    if (varValuePtr == NULL) {
	Tcl_AddObjErrorInfo(interp,
		"\n    (reading value of variable to increment)", -1);
	return NULL;
    }

1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
    }
    Tcl_SetLongObj(varValuePtr, (i + incrAmount));

    /*
     * Store the variable's new value and run any write traces.
     */
    
    resultPtr = Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, varValuePtr,
	    flags);
    if (resultPtr == NULL) {
	return NULL;
    }
    return resultPtr;
}

/*







|
<







1850
1851
1852
1853
1854
1855
1856
1857

1858
1859
1860
1861
1862
1863
1864
    }
    Tcl_SetLongObj(varValuePtr, (i + incrAmount));

    /*
     * Store the variable's new value and run any write traces.
     */
    
    resultPtr = Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, varValuePtr, flags);

    if (resultPtr == NULL) {
	return NULL;
    }
    return resultPtr;
}

/*
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
    int createdNewObj;		/* Set 1 if var's value object is shared
				 * so we must increment a copy (i.e. copy
				 * on write). */
    long i;
    int result;

    varValuePtr = TclGetIndexedScalar(interp, localIndex,
                                      /*leaveErrorMsg*/ 1);
    if (varValuePtr == NULL) {
	Tcl_AddObjErrorInfo(interp,
		"\n    (reading value of variable to increment)", -1);
	return NULL;
    }

    /*







|







1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
    int createdNewObj;		/* Set 1 if var's value object is shared
				 * so we must increment a copy (i.e. copy
				 * on write). */
    long i;
    int result;

    varValuePtr = TclGetIndexedScalar(interp, localIndex,
	    /*leaveErrorMsg*/ 1);
    if (varValuePtr == NULL) {
	Tcl_AddObjErrorInfo(interp,
		"\n    (reading value of variable to increment)", -1);
	return NULL;
    }

    /*
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
    Tcl_SetLongObj(varValuePtr, (i + incrAmount));

    /*
     * Store the variable's new value and run any write traces.
     */
    
    resultPtr = TclSetIndexedScalar(interp, localIndex, varValuePtr,
				    /*leaveErrorMsg*/ 1);
    if (resultPtr == NULL) {
	return NULL;
    }
    return resultPtr;
}

/*







|







1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
    Tcl_SetLongObj(varValuePtr, (i + incrAmount));

    /*
     * Store the variable's new value and run any write traces.
     */
    
    resultPtr = TclSetIndexedScalar(interp, localIndex, varValuePtr,
	    /*leaveErrorMsg*/ 1);
    if (resultPtr == NULL) {
	return NULL;
    }
    return resultPtr;
}

/*
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
    int createdNewObj;		/* Set 1 if var's value object is shared
				 * so we must increment a copy (i.e. copy
				 * on write). */
    long i;
    int result;

    varValuePtr = TclGetElementOfIndexedArray(interp, localIndex, elemPtr,
				              /*leaveErrorMsg*/ 1);
    if (varValuePtr == NULL) {
	Tcl_AddObjErrorInfo(interp,
		"\n    (reading value of variable to increment)", -1);
	return NULL;
    }

    /*







|







1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
    int createdNewObj;		/* Set 1 if var's value object is shared
				 * so we must increment a copy (i.e. copy
				 * on write). */
    long i;
    int result;

    varValuePtr = TclGetElementOfIndexedArray(interp, localIndex, elemPtr,
	    /*leaveErrorMsg*/ 1);
    if (varValuePtr == NULL) {
	Tcl_AddObjErrorInfo(interp,
		"\n    (reading value of variable to increment)", -1);
	return NULL;
    }

    /*
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
    Tcl_SetLongObj(varValuePtr, (i + incrAmount));
    
    /*
     * Store the variable's new value and run any write traces.
     */
    
    resultPtr = TclSetElementOfIndexedArray(interp, localIndex, elemPtr,
					    varValuePtr,
                                            /*leaveErrorMsg*/ 1);
    if (resultPtr == NULL) {
	return NULL;
    }
    return resultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UnsetVar --
 *
 *	Delete a variable, so that it may not be accessed anymore.
 *
 * Results:
 *	Returns TCL_OK if the variable was successfully deleted, TCL_ERROR
 *	if the variable can't be unset.  In the event of an error,
 *	if the TCL_LEAVE_ERR_MSG flag is set then an error message
 *	is left in interp->result.
 *
 * Side effects:
 *	If varName is defined as a local or global variable in interp,
 *	it is deleted.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UnsetVar(interp, varName, flags)
    Tcl_Interp *interp;		/* Command interpreter in which varName is
				 * to be looked up. */
    char *varName;		/* Name of a variable in interp.  May be
				 * either a scalar name or an array name
				 * or an element in an array. */
    int flags;			/* OR-ed combination of any of
				 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY or
				 * TCL_LEAVE_ERR_MSG. */
{
    return Tcl_UnsetVar2(interp, varName, (char *) NULL,
	    (flags | TCL_PARSE_PART1));
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UnsetVar2 --
 *
 *	Delete a variable, given a 2-part name.
 *
 * Results:
 *	Returns TCL_OK if the variable was successfully deleted, TCL_ERROR
 *	if the variable can't be unset.  In the event of an error,
 *	if the TCL_LEAVE_ERR_MSG flag is set then an error message
 *	is left in interp->result.
 *
 * Side effects:
 *	If part1 and part2 indicate a local or global variable in interp,
 *	it is deleted.  If part1 is an array name and part2 is NULL, then
 *	the whole array is deleted.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UnsetVar2(interp, part1, part2, flags)
    Tcl_Interp *interp;		/* Command interpreter in which varName is
				 * to be looked up. */
    char *part1;		/* Name of variable or array. */
    char *part2;		/* Name of element within array or NULL. */
    int flags;			/* OR-ed combination of any of
				 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
				 * TCL_LEAVE_ERR_MSG, or
				 * TCL_PARSE_PART1. */
{
    Var dummyVar;
    Var *varPtr, *dummyVarPtr;
    Interp *iPtr = (Interp *) interp;
    Var *arrayPtr;
    ActiveVarTrace *activePtr;
    Tcl_Obj *objPtr;







|
|

















|



















|
<













|

















|
<







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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066

2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098

2099
2100
2101
2102
2103
2104
2105
    Tcl_SetLongObj(varValuePtr, (i + incrAmount));
    
    /*
     * Store the variable's new value and run any write traces.
     */
    
    resultPtr = TclSetElementOfIndexedArray(interp, localIndex, elemPtr,
	    varValuePtr,
	    /*leaveErrorMsg*/ 1);
    if (resultPtr == NULL) {
	return NULL;
    }
    return resultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UnsetVar --
 *
 *	Delete a variable, so that it may not be accessed anymore.
 *
 * Results:
 *	Returns TCL_OK if the variable was successfully deleted, TCL_ERROR
 *	if the variable can't be unset.  In the event of an error,
 *	if the TCL_LEAVE_ERR_MSG flag is set then an error message
 *	is left in the interp's result.
 *
 * Side effects:
 *	If varName is defined as a local or global variable in interp,
 *	it is deleted.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UnsetVar(interp, varName, flags)
    Tcl_Interp *interp;		/* Command interpreter in which varName is
				 * to be looked up. */
    char *varName;		/* Name of a variable in interp.  May be
				 * either a scalar name or an array name
				 * or an element in an array. */
    int flags;			/* OR-ed combination of any of
				 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY or
				 * TCL_LEAVE_ERR_MSG. */
{
    return Tcl_UnsetVar2(interp, varName, (char *) NULL, flags);

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UnsetVar2 --
 *
 *	Delete a variable, given a 2-part name.
 *
 * Results:
 *	Returns TCL_OK if the variable was successfully deleted, TCL_ERROR
 *	if the variable can't be unset.  In the event of an error,
 *	if the TCL_LEAVE_ERR_MSG flag is set then an error message
 *	is left in the interp's result.
 *
 * Side effects:
 *	If part1 and part2 indicate a local or global variable in interp,
 *	it is deleted.  If part1 is an array name and part2 is NULL, then
 *	the whole array is deleted.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_UnsetVar2(interp, part1, part2, flags)
    Tcl_Interp *interp;		/* Command interpreter in which varName is
				 * to be looked up. */
    char *part1;		/* Name of variable or array. */
    char *part2;		/* Name of element within array or NULL. */
    int flags;			/* OR-ed combination of any of
				 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
				 * TCL_LEAVE_ERR_MSG. */

{
    Var dummyVar;
    Var *varPtr, *dummyVarPtr;
    Interp *iPtr = (Interp *) interp;
    Var *arrayPtr;
    ActiveVarTrace *activePtr;
    Tcl_Obj *objPtr;
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
     */

    if ((dummyVar.tracePtr != NULL)
	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
	varPtr->refCount++;
	dummyVar.flags &= ~VAR_TRACE_ACTIVE;
	(void) CallTraces(iPtr, arrayPtr, &dummyVar, part1, part2,
		(flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_PARSE_PART1)) | TCL_TRACE_UNSETS);
	while (dummyVar.tracePtr != NULL) {
	    VarTrace *tracePtr = dummyVar.tracePtr;
	    dummyVar.tracePtr = tracePtr->nextPtr;
	    ckfree((char *) tracePtr);
	}
	for (activePtr = iPtr->activeTracePtr;  activePtr != NULL;
		activePtr = activePtr->nextPtr) {
	    if (activePtr->varPtr == varPtr) {
		activePtr->nextTracePtr = NULL;
	    }
	}
	varPtr->refCount--;
    }

    /*
     * If the variable is an array, delete all of its elements. This must be
     * done after calling the traces on the array, above (that's the way
     * traces are defined). If it is a scalar, "discard" its object
     * (decrement the ref count of its object, if any).
     */

    dummyVarPtr = &dummyVar;
    if (TclIsVarArray(dummyVarPtr) && !TclIsVarUndefined(dummyVarPtr)) {
	DeleteArray(iPtr, part1, dummyVarPtr,
	    (flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY)) | TCL_TRACE_UNSETS);
    }
    if (TclIsVarScalar(dummyVarPtr)
	    && (dummyVarPtr->value.objPtr != NULL)) {
	objPtr = dummyVarPtr->value.objPtr;
	TclDecrRefCount(objPtr);
	dummyVarPtr->value.objPtr = NULL;
    }

    /*
     * If the variable was a namespace variable, decrement its reference
     * count. We are in the process of destroying its namespace so that
     * namespace will no longer "refer" to the variable.
     */
    
    if (varPtr->flags & VAR_NAMESPACE_VAR) {
	varPtr->flags &= ~VAR_NAMESPACE_VAR;
	varPtr->refCount--;
    }








|






|

















|









|
<
<







2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189


2190
2191
2192
2193
2194
2195
2196
     */

    if ((dummyVar.tracePtr != NULL)
	    || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
	varPtr->refCount++;
	dummyVar.flags &= ~VAR_TRACE_ACTIVE;
	(void) CallTraces(iPtr, arrayPtr, &dummyVar, part1, part2,
		(flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY)) | TCL_TRACE_UNSETS);
	while (dummyVar.tracePtr != NULL) {
	    VarTrace *tracePtr = dummyVar.tracePtr;
	    dummyVar.tracePtr = tracePtr->nextPtr;
	    ckfree((char *) tracePtr);
	}
	for (activePtr = iPtr->activeTracePtr;  activePtr != NULL;
	     activePtr = activePtr->nextPtr) {
	    if (activePtr->varPtr == varPtr) {
		activePtr->nextTracePtr = NULL;
	    }
	}
	varPtr->refCount--;
    }

    /*
     * If the variable is an array, delete all of its elements. This must be
     * done after calling the traces on the array, above (that's the way
     * traces are defined). If it is a scalar, "discard" its object
     * (decrement the ref count of its object, if any).
     */

    dummyVarPtr = &dummyVar;
    if (TclIsVarArray(dummyVarPtr) && !TclIsVarUndefined(dummyVarPtr)) {
	DeleteArray(iPtr, part1, dummyVarPtr,
		(flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY)) | TCL_TRACE_UNSETS);
    }
    if (TclIsVarScalar(dummyVarPtr)
	    && (dummyVarPtr->value.objPtr != NULL)) {
	objPtr = dummyVarPtr->value.objPtr;
	TclDecrRefCount(objPtr);
	dummyVarPtr->value.objPtr = NULL;
    }

    /*
     * If the variable was a namespace variable, decrement its reference count.


     */
    
    if (varPtr->flags & VAR_NAMESPACE_VAR) {
	varPtr->flags &= ~VAR_NAMESPACE_VAR;
	varPtr->refCount--;
    }

2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
				 * of TCL_TRACE_READS, TCL_TRACE_WRITES,
				 * TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY, and
				 * TCL_NAMESPACE_ONLY. */
    Tcl_VarTraceProc *proc;	/* Procedure to call when specified ops are
				 * invoked upon varName. */
    ClientData clientData;	/* Arbitrary argument to pass to proc. */
{
    return Tcl_TraceVar2(interp, varName, (char *) NULL,
	    (flags | TCL_PARSE_PART1), proc, clientData);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TraceVar2 --
 *







|
|







2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
				 * of TCL_TRACE_READS, TCL_TRACE_WRITES,
				 * TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY, and
				 * TCL_NAMESPACE_ONLY. */
    Tcl_VarTraceProc *proc;	/* Procedure to call when specified ops are
				 * invoked upon varName. */
    ClientData clientData;	/* Arbitrary argument to pass to proc. */
{
    return Tcl_TraceVar2(interp, varName, (char *) NULL, 
	    flags, proc, clientData);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_TraceVar2 --
 *
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
    char *part1;		/* Name of scalar variable or array. */
    char *part2;		/* Name of element within array;  NULL means
				 * trace applies to scalar variable or array
				 * as-a-whole. */
    int flags;			/* OR-ed collection of bits, including any
				 * of TCL_TRACE_READS, TCL_TRACE_WRITES,
				 * TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY and
				 * TCL_PARSE_PART1. */
    Tcl_VarTraceProc *proc;	/* Procedure to call when specified ops are
				 * invoked upon varName. */
    ClientData clientData;	/* Arbitrary argument to pass to proc. */
{
    Var *varPtr, *arrayPtr;
    register VarTrace *tracePtr;








|
<







2282
2283
2284
2285
2286
2287
2288
2289

2290
2291
2292
2293
2294
2295
2296
    char *part1;		/* Name of scalar variable or array. */
    char *part2;		/* Name of element within array;  NULL means
				 * trace applies to scalar variable or array
				 * as-a-whole. */
    int flags;			/* OR-ed collection of bits, including any
				 * of TCL_TRACE_READS, TCL_TRACE_WRITES,
				 * TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY,
				 * and TCL_NAMESPACE_ONLY. */

    Tcl_VarTraceProc *proc;	/* Procedure to call when specified ops are
				 * invoked upon varName. */
    ClientData clientData;	/* Arbitrary argument to pass to proc. */
{
    Var *varPtr, *arrayPtr;
    register VarTrace *tracePtr;

2254
2255
2256
2257
2258
2259
2260
2261

2262
2263
2264
2265
2266
2267
2268
     * Set up trace information.
     */

    tracePtr = (VarTrace *) ckalloc(sizeof(VarTrace));
    tracePtr->traceProc = proc;
    tracePtr->clientData = clientData;
    tracePtr->flags = 
	    flags & (TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS);

    tracePtr->nextPtr = varPtr->tracePtr;
    varPtr->tracePtr = tracePtr;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|
>







2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
     * Set up trace information.
     */

    tracePtr = (VarTrace *) ckalloc(sizeof(VarTrace));
    tracePtr->traceProc = proc;
    tracePtr->clientData = clientData;
    tracePtr->flags = 
	flags & (TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS | 
		TCL_TRACE_ARRAY);
    tracePtr->nextPtr = varPtr->tracePtr;
    varPtr->tracePtr = tracePtr;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
				 * current trace, including any of
				 * TCL_TRACE_READS, TCL_TRACE_WRITES,
				 * TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY
				 * and TCL_NAMESPACE_ONLY. */
    Tcl_VarTraceProc *proc;	/* Procedure assocated with trace. */
    ClientData clientData;	/* Arbitrary argument to pass to proc. */
{
    Tcl_UntraceVar2(interp, varName, (char *) NULL,
		    (flags | TCL_PARSE_PART1), proc, clientData);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UntraceVar2 --
 *







|
<







2342
2343
2344
2345
2346
2347
2348
2349

2350
2351
2352
2353
2354
2355
2356
				 * current trace, including any of
				 * TCL_TRACE_READS, TCL_TRACE_WRITES,
				 * TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY
				 * and TCL_NAMESPACE_ONLY. */
    Tcl_VarTraceProc *proc;	/* Procedure assocated with trace. */
    ClientData clientData;	/* Arbitrary argument to pass to proc. */
{
    Tcl_UntraceVar2(interp, varName, (char *) NULL, flags, proc, clientData);

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UntraceVar2 --
 *
2324
2325
2326
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
    char *part2;		/* Name of element within array;  NULL means
				 * trace applies to scalar variable or array
				 * as-a-whole. */
    int flags;			/* OR-ed collection of bits describing
				 * current trace, including any of
				 * TCL_TRACE_READS, TCL_TRACE_WRITES,
				 * TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY and
				 * TCL_PARSE_PART1. */
    Tcl_VarTraceProc *proc;	/* Procedure assocated with trace. */
    ClientData clientData;	/* Arbitrary argument to pass to proc. */
{
    register VarTrace *tracePtr;
    VarTrace *prevPtr;
    Var *varPtr, *arrayPtr;
    Interp *iPtr = (Interp *) interp;
    ActiveVarTrace *activePtr;

    varPtr = TclLookupVar(interp, part1, part2,
	    flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_PARSE_PART1),
	    /*msg*/ (char *) NULL,
	    /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
    if (varPtr == NULL) {
	return;
    }

    flags &= (TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS);

    for (tracePtr = varPtr->tracePtr, prevPtr = NULL;  ;
	    prevPtr = tracePtr, tracePtr = tracePtr->nextPtr) {
	if (tracePtr == NULL) {
	    return;
	}
	if ((tracePtr->traceProc == proc) && (tracePtr->flags == flags)
		&& (tracePtr->clientData == clientData)) {
	    break;
	}
    }

    /*
     * The code below makes it possible to delete traces while traces
     * are active: it makes sure that the deleted trace won't be
     * processed by CallTraces.
     */

    for (activePtr = iPtr->activeTracePtr;  activePtr != NULL;
	    activePtr = activePtr->nextPtr) {
	if (activePtr->nextTracePtr == tracePtr) {
	    activePtr->nextTracePtr = tracePtr->nextPtr;
	}
    }
    if (prevPtr == NULL) {
	varPtr->tracePtr = tracePtr->nextPtr;
    } else {







|
<










|






|
>

|
















|







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
    char *part2;		/* Name of element within array;  NULL means
				 * trace applies to scalar variable or array
				 * as-a-whole. */
    int flags;			/* OR-ed collection of bits describing
				 * current trace, including any of
				 * TCL_TRACE_READS, TCL_TRACE_WRITES,
				 * TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY,
				 * and TCL_NAMESPACE_ONLY. */

    Tcl_VarTraceProc *proc;	/* Procedure assocated with trace. */
    ClientData clientData;	/* Arbitrary argument to pass to proc. */
{
    register VarTrace *tracePtr;
    VarTrace *prevPtr;
    Var *varPtr, *arrayPtr;
    Interp *iPtr = (Interp *) interp;
    ActiveVarTrace *activePtr;

    varPtr = TclLookupVar(interp, part1, part2,
	    flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY),
	    /*msg*/ (char *) NULL,
	    /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
    if (varPtr == NULL) {
	return;
    }

    flags &= (TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS |
	    TCL_TRACE_ARRAY);
    for (tracePtr = varPtr->tracePtr, prevPtr = NULL;  ;
	 prevPtr = tracePtr, tracePtr = tracePtr->nextPtr) {
	if (tracePtr == NULL) {
	    return;
	}
	if ((tracePtr->traceProc == proc) && (tracePtr->flags == flags)
		&& (tracePtr->clientData == clientData)) {
	    break;
	}
    }

    /*
     * The code below makes it possible to delete traces while traces
     * are active: it makes sure that the deleted trace won't be
     * processed by CallTraces.
     */

    for (activePtr = iPtr->activeTracePtr;  activePtr != NULL;
	 activePtr = activePtr->nextPtr) {
	if (activePtr->nextTracePtr == tracePtr) {
	    activePtr->nextTracePtr = tracePtr->nextPtr;
	}
    }
    if (prevPtr == NULL) {
	varPtr->tracePtr = tracePtr->nextPtr;
    } else {
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
    ClientData prevClientData;	/* If non-NULL, gives last value returned
				 * by this procedure, so this call will
				 * return the next trace after that one.
				 * If NULL, this call will return the
				 * first trace. */
{
    return Tcl_VarTraceInfo2(interp, varName, (char *) NULL,
	    (flags | TCL_PARSE_PART1), proc, prevClientData);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_VarTraceInfo2 --
 *







|







2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
    ClientData prevClientData;	/* If non-NULL, gives last value returned
				 * by this procedure, so this call will
				 * return the next trace after that one.
				 * If NULL, this call will return the
				 * first trace. */
{
    return Tcl_VarTraceInfo2(interp, varName, (char *) NULL,
	    flags, proc, prevClientData);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_VarTraceInfo2 --
 *
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
Tcl_VarTraceInfo2(interp, part1, part2, flags, proc, prevClientData)
    Tcl_Interp *interp;		/* Interpreter containing variable. */
    char *part1;		/* Name of variable or array. */
    char *part2;		/* Name of element within array;  NULL means
				 * trace applies to scalar variable or array
				 * as-a-whole. */
    int flags;			/* OR-ed combination of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, and
				 * TCL_PARSE_PART1. */
    Tcl_VarTraceProc *proc;	/* Procedure assocated with trace. */
    ClientData prevClientData;	/* If non-NULL, gives last value returned
				 * by this procedure, so this call will
				 * return the next trace after that one.
				 * If NULL, this call will return the
				 * first trace. */
{
    register VarTrace *tracePtr;
    Var *varPtr, *arrayPtr;

    varPtr = TclLookupVar(interp, part1, part2,
	    flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_PARSE_PART1),
	    /*msg*/ (char *) NULL,
	    /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
    if (varPtr == NULL) {
	return NULL;
    }

    /*







|
<











|







2503
2504
2505
2506
2507
2508
2509
2510

2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
Tcl_VarTraceInfo2(interp, part1, part2, flags, proc, prevClientData)
    Tcl_Interp *interp;		/* Interpreter containing variable. */
    char *part1;		/* Name of variable or array. */
    char *part2;		/* Name of element within array;  NULL means
				 * trace applies to scalar variable or array
				 * as-a-whole. */
    int flags;			/* OR-ed combination of TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY. */

    Tcl_VarTraceProc *proc;	/* Procedure assocated with trace. */
    ClientData prevClientData;	/* If non-NULL, gives last value returned
				 * by this procedure, so this call will
				 * return the next trace after that one.
				 * If NULL, this call will return the
				 * first trace. */
{
    register VarTrace *tracePtr;
    Var *varPtr, *arrayPtr;

    varPtr = TclLookupVar(interp, part1, part2,
	    flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY),
	    /*msg*/ (char *) NULL,
	    /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
    if (varPtr == NULL) {
	return NULL;
    }

    /*
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "varName ?varName ...?");
	return TCL_ERROR;
    }
    
    for (i = 1;  i < objc;  i++) {
	/*
	 * THIS FAILS IF A NAME OBJECT'S STRING REP HAS A NULL BYTE.
	 */

	name = Tcl_GetStringFromObj(objv[i], (int *) NULL);
	if (Tcl_UnsetVar2(interp, name, (char *) NULL,
	        (TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1)) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    return TCL_OK;
}

/*







<
<
<
|
<

|







2578
2579
2580
2581
2582
2583
2584



2585

2586
2587
2588
2589
2590
2591
2592
2593
2594

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "varName ?varName ...?");
	return TCL_ERROR;
    }
    
    for (i = 1;  i < objc;  i++) {



	name = TclGetString(objv[i]);

	if (Tcl_UnsetVar2(interp, name, (char *) NULL,
		TCL_LEAVE_ERR_MSG) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    return TCL_OK;
}

/*
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
				         * warning. */
    int i;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "varName ?value value ...?");
	return TCL_ERROR;
    }

    if (objc == 2) {
	varValuePtr = Tcl_ObjGetVar2(interp, objv[1], (Tcl_Obj *) NULL,
	        (TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1));
	if (varValuePtr == NULL) {
	    return TCL_ERROR;
	}
    } else {
	for (i = 2;  i < objc;  i++) {
	    varValuePtr = Tcl_ObjSetVar2(interp, objv[1], (Tcl_Obj *) NULL,
		objv[i],
		(TCL_APPEND_VALUE | TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1));
	    if (varValuePtr == NULL) {
		return TCL_ERROR;
	    }
	}
    }
    
    Tcl_SetObjResult(interp, varValuePtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







<

|
<






<
|





<







2621
2622
2623
2624
2625
2626
2627

2628
2629

2630
2631
2632
2633
2634
2635

2636
2637
2638
2639
2640
2641

2642
2643
2644
2645
2646
2647
2648
				         * warning. */
    int i;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "varName ?value value ...?");
	return TCL_ERROR;
    }

    if (objc == 2) {
	varValuePtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG);

	if (varValuePtr == NULL) {
	    return TCL_ERROR;
	}
    } else {
	for (i = 2;  i < objc;  i++) {
	    varValuePtr = Tcl_ObjSetVar2(interp, objv[1], (Tcl_Obj *) NULL,

		    objv[i], (TCL_APPEND_VALUE | TCL_LEAVE_ERR_MSG));
	    if (varValuePtr == NULL) {
		return TCL_ERROR;
	    }
	}
    }

    Tcl_SetObjResult(interp, varValuePtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
    register Tcl_Obj **elemPtrs;
    int numElems, numRequired, createdNewObj, createVar, i, j;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "varName ?value value ...?");
	return TCL_ERROR;
    }
    
    if (objc == 2) {
	newValuePtr = Tcl_ObjGetVar2(interp, objv[1], (Tcl_Obj *) NULL,
	    (TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1));
	if (newValuePtr == NULL) {
	    /*
	     * The variable doesn't exist yet. Just create it with an empty
	     * initial value.
	     */
	    
	    Tcl_Obj *nullObjPtr = Tcl_NewObj();
	    newValuePtr = Tcl_ObjSetVar2(interp, objv[1], NULL,
		    nullObjPtr, (TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1));
	    if (newValuePtr == NULL) {
		Tcl_DecrRefCount(nullObjPtr); /* free unneeded object */
		return TCL_ERROR;
	    }
	}
    } else {
	/*
	 * We have arguments to append. We used to call Tcl_ObjSetVar2 to
	 * append each argument one at a time to ensure that traces were run
	 * for each append step. We now append the arguments all at once
	 * because it's faster. Note that a read trace and a write trace for
	 * the variable will now each only be called once. Also, if the
	 * variable's old value is unshared we modify it directly, otherwise
	 * we create a new copy to modify: this is "copy on write".
	 */

	createdNewObj = 0;
	createVar = 1;
	varValuePtr = Tcl_ObjGetVar2(interp, objv[1], (Tcl_Obj *) NULL,
	        TCL_PARSE_PART1);
	if (varValuePtr == NULL) {
	    /*
	     * We couldn't read the old value: either the var doesn't yet
	     * exist or it's an array element. If it's new, we will try to
	     * create it with Tcl_ObjSetVar2 below.
	     */
	    
	    char *name, *p;
	    int nameBytes, i;

	    name = TclGetStringFromObj(objv[1], &nameBytes);
	    for (i = 0, p = name;  i < nameBytes;  i++, p++) {
		if (*p == '(') {
		    p = (name + nameBytes-1);	
		    if (*p == ')') { /* last char is ')' => array ref */
			createVar = 0;
		    }
		    break;
		}
	    }
	    varValuePtr = Tcl_NewObj();







<


|








|







|










|
<







|


|
|

|







2673
2674
2675
2676
2677
2678
2679

2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710

2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
    register Tcl_Obj **elemPtrs;
    int numElems, numRequired, createdNewObj, createVar, i, j;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "varName ?value value ...?");
	return TCL_ERROR;
    }

    if (objc == 2) {
	newValuePtr = Tcl_ObjGetVar2(interp, objv[1], (Tcl_Obj *) NULL,
		(TCL_LEAVE_ERR_MSG));
	if (newValuePtr == NULL) {
	    /*
	     * The variable doesn't exist yet. Just create it with an empty
	     * initial value.
	     */
	    
	    Tcl_Obj *nullObjPtr = Tcl_NewObj();
	    newValuePtr = Tcl_ObjSetVar2(interp, objv[1], NULL,
		    nullObjPtr, TCL_LEAVE_ERR_MSG);
	    if (newValuePtr == NULL) {
		Tcl_DecrRefCount(nullObjPtr); /* free unneeded object */
		return TCL_ERROR;
	    }
	}
    } else {
	/*
	 * We have arguments to append. We used to call Tcl_SetVar2 to
	 * append each argument one at a time to ensure that traces were run
	 * for each append step. We now append the arguments all at once
	 * because it's faster. Note that a read trace and a write trace for
	 * the variable will now each only be called once. Also, if the
	 * variable's old value is unshared we modify it directly, otherwise
	 * we create a new copy to modify: this is "copy on write".
	 */

	createdNewObj = 0;
	createVar = 1;
	varValuePtr = Tcl_ObjGetVar2(interp, objv[1], NULL, 0);

	if (varValuePtr == NULL) {
	    /*
	     * We couldn't read the old value: either the var doesn't yet
	     * exist or it's an array element. If it's new, we will try to
	     * create it with Tcl_ObjSetVar2 below.
	     */
	    
	    char *p, *varName;
	    int nameBytes, i;

	    varName = Tcl_GetStringFromObj(objv[1], &nameBytes);
	    for (i = 0, p = varName;  i < nameBytes;  i++, p++) {
		if (*p == '(') {
		    p = (varName + nameBytes-1);	
		    if (*p == ')') { /* last char is ')' => array ref */
			createVar = 0;
		    }
		    break;
		}
	    }
	    varValuePtr = Tcl_NewObj();
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
	 * allocate a new, larger array and copy the pointers to it.
	 */
	
	numRequired = numElems + (objc-2);
	if (numRequired > listRepPtr->maxElemCount) {
	    int newMax = (2 * numRequired);
	    Tcl_Obj **newElemPtrs = (Tcl_Obj **)
		    ckalloc((unsigned) (newMax * sizeof(Tcl_Obj *)));
	    
	    memcpy((VOID *) newElemPtrs, (VOID *) elemPtrs,
		    (size_t) (numElems * sizeof(Tcl_Obj *)));
	    listRepPtr->maxElemCount = newMax;
	    listRepPtr->elements = newElemPtrs;
	    ckfree((char *) elemPtrs);
	    elemPtrs = newElemPtrs;







|







2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
	 * allocate a new, larger array and copy the pointers to it.
	 */
	
	numRequired = numElems + (objc-2);
	if (numRequired > listRepPtr->maxElemCount) {
	    int newMax = (2 * numRequired);
	    Tcl_Obj **newElemPtrs = (Tcl_Obj **)
		ckalloc((unsigned) (newMax * sizeof(Tcl_Obj *)));
	    
	    memcpy((VOID *) newElemPtrs, (VOID *) elemPtrs,
		    (size_t) (numElems * sizeof(Tcl_Obj *)));
	    listRepPtr->maxElemCount = newMax;
	    listRepPtr->elements = newElemPtrs;
	    ckfree((char *) elemPtrs);
	    elemPtrs = newElemPtrs;
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766

	/*
	 * Now store the list object back into the variable. If there is an
	 * error setting the new value, decrement its ref count if it
	 * was new and we didn't create the variable.
	 */
	
	newValuePtr = Tcl_ObjSetVar2(interp, objv[1], (Tcl_Obj *) NULL,
		varValuePtr, (TCL_LEAVE_ERR_MSG | TCL_PARSE_PART1));
	if (newValuePtr == NULL) {
	    if (createdNewObj && !createVar) {
		Tcl_DecrRefCount(varValuePtr); /* free unneeded obj */
	    }
	    return TCL_ERROR;
	}
    }







|
|







2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805

	/*
	 * Now store the list object back into the variable. If there is an
	 * error setting the new value, decrement its ref count if it
	 * was new and we didn't create the variable.
	 */
	
	newValuePtr = Tcl_ObjSetVar2(interp, objv[1], NULL, varValuePtr,
		TCL_LEAVE_ERR_MSG);
	if (newValuePtr == NULL) {
	    if (createdNewObj && !createVar) {
		Tcl_DecrRefCount(varValuePtr); /* free unneeded obj */
	    }
	    return TCL_ERROR;
	}
    }
2795
2796
2797
2798
2799
2800
2801








2802
2803
2804


2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837















2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
int
Tcl_ArrayObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{








    static char *arrayOptions[] = {"anymore", "donesearch", "exists",
	    "get", "names", "nextelement", "set", "size", "startsearch", 
            (char *) NULL};


    Var *varPtr, *arrayPtr;
    Tcl_HashEntry *hPtr;
    Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
    int notArray;
    char *varName;
    int index, result;


    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arrayName ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], arrayOptions, "option", 0, &index)
	    != TCL_OK) {
    	return TCL_ERROR;
    }

    /*
     * Locate the array variable (and it better be an array).
     * THIS FAILS IF A NAME OBJECT'S STRING REP HAS A NULL BYTE.
     */
    
    varName = TclGetStringFromObj(objv[2], (int *) NULL);
    varPtr = TclLookupVar(interp, varName, (char *) NULL, /*flags*/ 0,
            /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);

    notArray = 0;
    if ((varPtr == NULL) || !TclIsVarArray(varPtr)
	    || TclIsVarUndefined(varPtr)) {
	notArray = 1;
    }
    















    switch (index) {
        case 0: {        /* anymore */
	    ArraySearch *searchPtr;
	    char *searchId;
	    
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, 
                        "arrayName searchId");
		return TCL_ERROR;
	    }
	    if (notArray) {
	        goto error;
	    }
	    searchId = Tcl_GetStringFromObj(objv[3], (int *) NULL);
	    searchPtr = ParseSearchId(interp, varPtr, varName, searchId);
	    if (searchPtr == NULL) {
	        return TCL_ERROR;
	    }
	    while (1) {
	        Var *varPtr2;








>
>
>
>
>
>
>
>

|
|
>
>




|








|
|





<


|








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

|











|







2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873

2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
int
Tcl_ArrayObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    /*
     * The list of constants below should match the arrayOptions string array
     * below.
     */

    enum {ARRAY_ANYMORE, ARRAY_DONESEARCH,  ARRAY_EXISTS, ARRAY_GET,
	  ARRAY_NAMES, ARRAY_NEXTELEMENT, ARRAY_SET, ARRAY_SIZE,
	  ARRAY_STARTSEARCH}; 
    static char *arrayOptions[] = {"anymore", "donesearch", "exists",
				   "get", "names", "nextelement", "set",
				   "size", "startsearch", (char *) NULL};

    Interp *iPtr = (Interp *) interp;
    Var *varPtr, *arrayPtr;
    Tcl_HashEntry *hPtr;
    Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
    int notArray;
    char *varName, *msg;
    int index, result;


    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arrayName ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], arrayOptions, "option",
	    0, &index) != TCL_OK) {
    	return TCL_ERROR;
    }

    /*
     * Locate the array variable (and it better be an array).

     */
    
    varName = TclGetString(objv[2]);
    varPtr = TclLookupVar(interp, varName, (char *) NULL, /*flags*/ 0,
            /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);

    notArray = 0;
    if ((varPtr == NULL) || !TclIsVarArray(varPtr)
	    || TclIsVarUndefined(varPtr)) {
	notArray = 1;
    }

    /*
     * Special array trace used to keep the env array in sync for
     * array names, array get, etc.
     */

    if (varPtr != NULL && varPtr->tracePtr != NULL) {
	msg = CallTraces(iPtr, arrayPtr, varPtr, varName, NULL,
		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
		TCL_TRACE_ARRAY));
	if (msg != NULL) {
	    VarErrMsg(interp, varName, NULL, "trace array", msg);
	    return TCL_ERROR;
	}
    }

    switch (index) {
        case ARRAY_ANYMORE: {
	    ArraySearch *searchPtr;
	    char *searchId;
	    
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, 
                        "arrayName searchId");
		return TCL_ERROR;
	    }
	    if (notArray) {
	        goto error;
	    }
	    searchId = Tcl_GetString(objv[3]);
	    searchPtr = ParseSearchId(interp, varPtr, varName, searchId);
	    if (searchPtr == NULL) {
	        return TCL_ERROR;
	    }
	    while (1) {
	        Var *varPtr2;

2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
		    Tcl_SetIntObj(resultPtr, 0);
		    return TCL_OK;
		}
	    }
	    Tcl_SetIntObj(resultPtr, 1);
	    break;
	}
        case 1: {        /* donesearch */
	    ArraySearch *searchPtr, *prevPtr;
	    char *searchId;

	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, 
                        "arrayName searchId");
		return TCL_ERROR;
	    }
	    if (notArray) {
	        goto error;
	    }
	    searchId = Tcl_GetStringFromObj(objv[3], (int *) NULL);
	    searchPtr = ParseSearchId(interp, varPtr, varName, searchId);
	    if (searchPtr == NULL) {
	        return TCL_ERROR;
	    }
	    if (varPtr->searchPtr == searchPtr) {
	        varPtr->searchPtr = searchPtr->nextPtr;
	    } else {
	        for (prevPtr = varPtr->searchPtr;  ;
		        prevPtr = prevPtr->nextPtr) {
		    if (prevPtr->nextPtr == searchPtr) {
		        prevPtr->nextPtr = searchPtr->nextPtr;
			break;
		    }
		}
	    }
	    ckfree((char *) searchPtr);
	    break;
	}
        case 2: {        /* exists */
	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName");
	        return TCL_ERROR;
	    }
	    Tcl_SetIntObj(resultPtr, !notArray);
	    break;
	}
        case 3: {        /*get*/
	    Tcl_HashSearch search;
	    Var *varPtr2;
	    char *pattern = NULL;
	    char *name;
	    Tcl_Obj *namePtr, *valuePtr;
	    
	    if ((objc != 3) && (objc != 4)) {
	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName ?pattern?");
		return TCL_ERROR;
	    }
	    if (notArray) {
	        return TCL_OK;
	    }
	    if (objc == 4) {
	        pattern = Tcl_GetStringFromObj(objv[3], (int *) NULL);
	    }
	    for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr, &search);
		    hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
	        varPtr2 = (Var *) Tcl_GetHashValue(hPtr);
		if (TclIsVarUndefined(varPtr2)) {
		    continue;
		}
		name = Tcl_GetHashKey(varPtr->value.tablePtr, hPtr);
		if ((objc == 4) && !Tcl_StringMatch(name, pattern)) {
		    continue;	/* element name doesn't match pattern */







|











|








|









|







|














|


|







2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
		    Tcl_SetIntObj(resultPtr, 0);
		    return TCL_OK;
		}
	    }
	    Tcl_SetIntObj(resultPtr, 1);
	    break;
	}
        case ARRAY_DONESEARCH: {
	    ArraySearch *searchPtr, *prevPtr;
	    char *searchId;

	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, 
                        "arrayName searchId");
		return TCL_ERROR;
	    }
	    if (notArray) {
	        goto error;
	    }
	    searchId = Tcl_GetString(objv[3]);
	    searchPtr = ParseSearchId(interp, varPtr, varName, searchId);
	    if (searchPtr == NULL) {
	        return TCL_ERROR;
	    }
	    if (varPtr->searchPtr == searchPtr) {
	        varPtr->searchPtr = searchPtr->nextPtr;
	    } else {
	        for (prevPtr = varPtr->searchPtr;  ;
		     prevPtr = prevPtr->nextPtr) {
		    if (prevPtr->nextPtr == searchPtr) {
		        prevPtr->nextPtr = searchPtr->nextPtr;
			break;
		    }
		}
	    }
	    ckfree((char *) searchPtr);
	    break;
	}
        case ARRAY_EXISTS: {
	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName");
	        return TCL_ERROR;
	    }
	    Tcl_SetIntObj(resultPtr, !notArray);
	    break;
	}
        case ARRAY_GET: {
	    Tcl_HashSearch search;
	    Var *varPtr2;
	    char *pattern = NULL;
	    char *name;
	    Tcl_Obj *namePtr, *valuePtr;
	    
	    if ((objc != 3) && (objc != 4)) {
	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName ?pattern?");
		return TCL_ERROR;
	    }
	    if (notArray) {
	        return TCL_OK;
	    }
	    if (objc == 4) {
	        pattern = TclGetString(objv[3]);
	    }
	    for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr, &search);
		 hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
	        varPtr2 = (Var *) Tcl_GetHashValue(hPtr);
		if (TclIsVarUndefined(varPtr2)) {
		    continue;
		}
		name = Tcl_GetHashKey(varPtr->value.tablePtr, hPtr);
		if ((objc == 4) && !Tcl_StringMatch(name, pattern)) {
		    continue;	/* element name doesn't match pattern */
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
		if (result != TCL_OK) {
		    Tcl_DecrRefCount(namePtr); /* free unneeded name obj */
		    return result;
		}
	    }
	    break;
	}
        case 4: {        /* names */
	    Tcl_HashSearch search;
	    Var *varPtr2;
	    char *pattern = NULL;
	    char *name;
	    Tcl_Obj *namePtr;
	    
	    if ((objc != 3) && (objc != 4)) {
  	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName ?pattern?");
		return TCL_ERROR;
	    }
	    if (notArray) {
	        return TCL_OK;
	    }
	    if (objc == 4) {
	        pattern = Tcl_GetStringFromObj(objv[3], (int *) NULL);
	    }
	    for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr, &search);
		    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	        varPtr2 = (Var *) Tcl_GetHashValue(hPtr);
		if (TclIsVarUndefined(varPtr2)) {
		    continue;
		}
		name = Tcl_GetHashKey(varPtr->value.tablePtr, hPtr);
		if ((objc == 4) && !Tcl_StringMatch(name, pattern)) {
 		    continue;	/* element name doesn't match pattern */
		}
		
		namePtr = Tcl_NewStringObj(name, -1);
		result = Tcl_ListObjAppendElement(interp, resultPtr, namePtr);
		if (result != TCL_OK) {
		    Tcl_DecrRefCount(namePtr); /* free unneeded name object */
		    return result;
		}
	    }
	    break;
	}
        case 5: {        /*nextelement*/
	    ArraySearch *searchPtr;
	    char *searchId;
	    Tcl_HashEntry *hPtr;
	    
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, 
                        "arrayName searchId");
		return TCL_ERROR;
	    }
	    if (notArray) {
  	        goto error;
	    }
	    searchId = Tcl_GetStringFromObj(objv[3], (int *) NULL);
	    searchPtr = ParseSearchId(interp, varPtr, varName, searchId);
	    if (searchPtr == NULL) {
	        return TCL_ERROR;
	    }
	    while (1) {
	        Var *varPtr2;








|














|


|












|





|












|







3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
		if (result != TCL_OK) {
		    Tcl_DecrRefCount(namePtr); /* free unneeded name obj */
		    return result;
		}
	    }
	    break;
	}
        case ARRAY_NAMES: {
	    Tcl_HashSearch search;
	    Var *varPtr2;
	    char *pattern = NULL;
	    char *name;
	    Tcl_Obj *namePtr;
	    
	    if ((objc != 3) && (objc != 4)) {
  	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName ?pattern?");
		return TCL_ERROR;
	    }
	    if (notArray) {
	        return TCL_OK;
	    }
	    if (objc == 4) {
	        pattern = Tcl_GetString(objv[3]);
	    }
	    for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr, &search);
		 hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
	        varPtr2 = (Var *) Tcl_GetHashValue(hPtr);
		if (TclIsVarUndefined(varPtr2)) {
		    continue;
		}
		name = Tcl_GetHashKey(varPtr->value.tablePtr, hPtr);
		if ((objc == 4) && !Tcl_StringMatch(name, pattern)) {
 		    continue;	/* element name doesn't match pattern */
		}
		
		namePtr = Tcl_NewStringObj(name, -1);
		result = Tcl_ListObjAppendElement(interp, resultPtr, namePtr);
		if (result != TCL_OK) {
		    Tcl_DecrRefCount(namePtr); /* free unneeded name obj */
		    return result;
		}
	    }
	    break;
	}
        case ARRAY_NEXTELEMENT: {
	    ArraySearch *searchPtr;
	    char *searchId;
	    Tcl_HashEntry *hPtr;
	    
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, 
                        "arrayName searchId");
		return TCL_ERROR;
	    }
	    if (notArray) {
  	        goto error;
	    }
	    searchId = Tcl_GetString(objv[3]);
	    searchPtr = ParseSearchId(interp, varPtr, varName, searchId);
	    if (searchPtr == NULL) {
	        return TCL_ERROR;
	    }
	    while (1) {
	        Var *varPtr2;

3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
































































































3156
3157
3158
3159
3160
3161
3162
		    break;
		}
	    }
	    Tcl_SetStringObj(resultPtr,
	            Tcl_GetHashKey(varPtr->value.tablePtr, hPtr), -1);
	    break;
	}
        case 6: {        /*set*/
	    Tcl_Obj **elemPtrs;
	    int listLen, i, result;
	    
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName list");
		return TCL_ERROR;
	    }
	    result = Tcl_ListObjGetElements(interp, objv[3], &listLen, 
                    &elemPtrs);
	    if (result != TCL_OK) {
	        return result;
	    }
	    if (listLen & 1) {
	        Tcl_ResetResult(interp);
		Tcl_AppendToObj(Tcl_GetObjResult(interp),
                        "list must have an even number of elements", -1);
		return TCL_ERROR;
	    }
	    if (listLen > 0) {
		for (i = 0;  i < listLen;  i += 2) {
		    if (Tcl_ObjSetVar2(interp, objv[2], elemPtrs[i],
			    elemPtrs[i+1], TCL_LEAVE_ERR_MSG) == NULL) {
			result = TCL_ERROR;
			break;
		    }
		}
	    } else if (varPtr == NULL) {
		/*
		 * The list is empty and the array variable doesn't
		 * exist yet: create the variable with an empty array
		 * as the value.
		 */

		Tcl_Obj *namePtr, *valuePtr;

		namePtr = Tcl_NewStringObj("tempElem", -1);
		valuePtr = Tcl_NewObj();
		if (Tcl_ObjSetVar2(interp, objv[2], namePtr, valuePtr,
			/* flags*/ 0) == NULL) {
		    Tcl_DecrRefCount(namePtr);
		    Tcl_DecrRefCount(valuePtr);
		    return TCL_ERROR;
		}
		result = Tcl_UnsetVar2(interp, varName, "tempElem",
                        TCL_LEAVE_ERR_MSG);
		if (result != TCL_OK) {
		    Tcl_DecrRefCount(namePtr);
		    Tcl_DecrRefCount(valuePtr);
		    return result;
		}
	    }
	    return result;
	}
        case 7: {        /*size*/
	    Tcl_HashSearch search;
	    Var *varPtr2;
	    int size;

	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName");
		return TCL_ERROR;
	    }
	    size = 0;
	    if (!notArray) {
	        for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr, 
                        &search);
		        hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
		    varPtr2 = (Var *) Tcl_GetHashValue(hPtr);
		    if (TclIsVarUndefined(varPtr2)) {
		        continue;
		    }
		    size++;
		}
	    }
	    Tcl_SetIntObj(resultPtr, size);
	    break;
	}
        case 8: {         /*startsearch*/
	    ArraySearch *searchPtr;

	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName");
		return TCL_ERROR;
	    }
	    if (notArray) {
	        goto error;
	    }
	    searchPtr = (ArraySearch *) ckalloc(sizeof(ArraySearch));
	    if (varPtr->searchPtr == NULL) {
	        searchPtr->id = 1;
		Tcl_AppendStringsToObj(resultPtr, "s-1-", varName,
		        (char *) NULL);
	    } else {
	        char string[20];

		searchPtr->id = varPtr->searchPtr->id + 1;
		TclFormatInt(string, searchPtr->id);
		Tcl_AppendStringsToObj(resultPtr, "s-", string, "-", varName,
		    (char *) NULL);
	    }
	    searchPtr->varPtr = varPtr;
	    searchPtr->nextEntry = Tcl_FirstHashEntry(varPtr->value.tablePtr,
		    &searchPtr->search);
	    searchPtr->nextPtr = varPtr->searchPtr;
	    varPtr->searchPtr = searchPtr;
	    break;
	}
    }
    return TCL_OK;

    error:
    Tcl_AppendStringsToObj(resultPtr, "\"", varName, "\" isn't an array",
	    (char *) NULL);
    return TCL_ERROR;
}

































































































/*
 *----------------------------------------------------------------------
 *
 * MakeUpvar --
 *
 *	This procedure does all of the work of the "global" and "upvar"







<
<
<
|




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












|










|















|




|
















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







3096
3097
3098
3099
3100
3101
3102



3103
3104
3105
3106
3107













3108



3109







3110





















3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
		    break;
		}
	    }
	    Tcl_SetStringObj(resultPtr,
	            Tcl_GetHashKey(varPtr->value.tablePtr, hPtr), -1);
	    break;
	}



        case ARRAY_SET: {
	    if (objc != 4) {
	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName list");
		return TCL_ERROR;
	    }













	    return(TclArraySet(interp, objv[2], objv[3]));



	}







        case ARRAY_SIZE: {





















	    Tcl_HashSearch search;
	    Var *varPtr2;
	    int size;

	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName");
		return TCL_ERROR;
	    }
	    size = 0;
	    if (!notArray) {
	        for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr, 
                        &search);
		     hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
		    varPtr2 = (Var *) Tcl_GetHashValue(hPtr);
		    if (TclIsVarUndefined(varPtr2)) {
		        continue;
		    }
		    size++;
		}
	    }
	    Tcl_SetIntObj(resultPtr, size);
	    break;
	}
        case ARRAY_STARTSEARCH: {
	    ArraySearch *searchPtr;

	    if (objc != 3) {
	        Tcl_WrongNumArgs(interp, 2, objv, "arrayName");
		return TCL_ERROR;
	    }
	    if (notArray) {
	        goto error;
	    }
	    searchPtr = (ArraySearch *) ckalloc(sizeof(ArraySearch));
	    if (varPtr->searchPtr == NULL) {
	        searchPtr->id = 1;
		Tcl_AppendStringsToObj(resultPtr, "s-1-", varName,
		        (char *) NULL);
	    } else {
	        char string[TCL_INTEGER_SPACE];

		searchPtr->id = varPtr->searchPtr->id + 1;
		TclFormatInt(string, searchPtr->id);
		Tcl_AppendStringsToObj(resultPtr, "s-", string, "-", varName,
			(char *) NULL);
	    }
	    searchPtr->varPtr = varPtr;
	    searchPtr->nextEntry = Tcl_FirstHashEntry(varPtr->value.tablePtr,
		    &searchPtr->search);
	    searchPtr->nextPtr = varPtr->searchPtr;
	    varPtr->searchPtr = searchPtr;
	    break;
	}
    }
    return TCL_OK;

    error:
    Tcl_AppendStringsToObj(resultPtr, "\"", varName, "\" isn't an array",
	    (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TclArraySet --
 *
 *	Set the elements of an array.  If there are no elements to
 *	set, create an empty array.  This routine is used by the
 *	Tcl_ArrayObjCmd and by the TclSetupEnv routine.
 *
 * Results:
 *	A standard Tcl result object.
 *
 * Side effects:
 *	A variable will be created if one does not already exist.
 *
 *----------------------------------------------------------------------
 */

int
TclArraySet(interp, arrayNameObj, arrayElemObj)
    Tcl_Interp *interp;		/* Current interpreter. */
    Tcl_Obj *arrayNameObj;	/* The array name. */
    Tcl_Obj *arrayElemObj;	/* The array elements list.  If this is
				 * NULL, create an empty array. */
{
    Var *varPtr, *arrayPtr;
    Tcl_Obj **elemPtrs;
    int result, elemLen, i;
    char *varName;
    
    varName = TclGetString(arrayNameObj);
    varPtr = TclLookupVar(interp, varName, (char *) NULL, /*flags*/ 0,
            /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);

    if (arrayElemObj != NULL) {
	result = Tcl_ListObjGetElements(interp, arrayElemObj,
		&elemLen, &elemPtrs);
	if (result != TCL_OK) {
	    return result;
	}
	if (elemLen & 1) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
		    "list must have an even number of elements", -1);
	    return TCL_ERROR;
	}
	if (elemLen > 0) {
	    for (i = 0;  i < elemLen;  i += 2) {
		if (Tcl_ObjSetVar2(interp, arrayNameObj, elemPtrs[i],
			elemPtrs[i+1], TCL_LEAVE_ERR_MSG) == NULL) {
		    result = TCL_ERROR;
		    break;
		}
	    }
	    return result;
	}
    }
    
    /*
     * The list is empty make sure we have an array, or create
     * one if necessary.
     */
    
    if (varPtr != NULL) {
	if (!TclIsVarUndefined(varPtr) && TclIsVarArray(varPtr)) {
	    /*
	     * Already an array, done.
	     */
	    
	    return TCL_OK;
	}
	if (TclIsVarArrayElement(varPtr) ||
		!TclIsVarUndefined(varPtr)) {
	    /*
	     * Either an array element, or a scalar: lose!
	     */
	    
	    VarErrMsg(interp, varName, (char *)NULL, "array set", needArray);
	    return TCL_ERROR;
	}
    } else {
	/*
	 * Create variable for new array.
	 */
	
	varPtr = TclLookupVar(interp, varName, (char *) NULL, 0, 0,
	        /*createPart1*/ 1, /*createPart2*/ 0, &arrayPtr);
    }
    TclSetVarArray(varPtr);
    TclClearVarUndefined(varPtr);
    varPtr->value.tablePtr =
	(Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
    Tcl_InitHashTable(varPtr->value.tablePtr, TCL_STRING_KEYS);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * MakeUpvar --
 *
 *	This procedure does all of the work of the "global" and "upvar"
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
    Tcl_HashEntry *hPtr;
    Var *otherPtr, *varPtr, *arrayPtr;
    CallFrame *varFramePtr;
    CallFrame *savedFramePtr = NULL;  /* Init. to avoid compiler warning. */
    Tcl_HashTable *tablePtr;
    Namespace *nsPtr, *altNsPtr, *dummyNsPtr;
    char *tail;
    int new, result;

    /*
     * Find "other" in "framePtr". If not looking up other in just the
     * current namespace, temporarily replace the current var frame
     * pointer in the interpreter in order to use TclLookupVar.
     */








|







3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
    Tcl_HashEntry *hPtr;
    Var *otherPtr, *varPtr, *arrayPtr;
    CallFrame *varFramePtr;
    CallFrame *savedFramePtr = NULL;  /* Init. to avoid compiler warning. */
    Tcl_HashTable *tablePtr;
    Namespace *nsPtr, *altNsPtr, *dummyNsPtr;
    char *tail;
    int new;

    /*
     * Find "other" in "framePtr". If not looking up other in just the
     * current namespace, temporarily replace the current var frame
     * pointer in the interpreter in order to use TclLookupVar.
     */

3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
     * frame's array of compiler-allocated local variables, then in its
     * hashtable for runtime-created local variables. Create that
     * procedure's local variable hashtable if necessary.
     */

    varFramePtr = iPtr->varFramePtr;
    if ((myFlags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY))
	        || (varFramePtr == NULL)
	        || !varFramePtr->isProcCallFrame
	        || (strstr(myName, "::") != NULL)) {
	result = TclGetNamespaceForQualName((Tcl_Interp *) iPtr, myName,
                (Namespace *) NULL, (myFlags | TCL_LEAVE_ERR_MSG),
                &nsPtr, &altNsPtr, &dummyNsPtr, &tail);
        if (result != TCL_OK) {
	    return result;
        }
        if (nsPtr == NULL) {
            nsPtr = altNsPtr;
        }
        if (nsPtr == NULL) {
	    Tcl_AppendResult((Tcl_Interp *) iPtr, "bad variable name \"",
                myName, "\": unknown namespace", (char *) NULL);
            return TCL_ERROR;
        }
	
	/*
	 * Check that we are not trying to create a namespace var linked to
	 * a local variable in a procedure. If we allowed this, the local
	 * variable in the shorter-lived procedure frame could go away
	 * leaving the namespace var's reference invalid.
	 */

	if (otherPtr->nsPtr == NULL) {
	    Tcl_AppendResult((Tcl_Interp *) iPtr, "bad variable name \"",
                    myName, "\": upvar won't create namespace variable that refers to procedure variable",
		    (char *) NULL);
            return TCL_ERROR;
        }
	
	hPtr = Tcl_CreateHashEntry(&nsPtr->varTable, tail, &new);







|
|
|
|
<
|
<
<
|





|










|







3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352

3353


3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
     * frame's array of compiler-allocated local variables, then in its
     * hashtable for runtime-created local variables. Create that
     * procedure's local variable hashtable if necessary.
     */

    varFramePtr = iPtr->varFramePtr;
    if ((myFlags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY))
	    || (varFramePtr == NULL)
	    || !varFramePtr->isProcCallFrame
	    || (strstr(myName, "::") != NULL)) {
	TclGetNamespaceForQualName((Tcl_Interp *) iPtr, myName,

		(Namespace *) NULL, myFlags, &nsPtr, &altNsPtr, &dummyNsPtr, &tail);



        if (nsPtr == NULL) {
            nsPtr = altNsPtr;
        }
        if (nsPtr == NULL) {
	    Tcl_AppendResult((Tcl_Interp *) iPtr, "bad variable name \"",
		    myName, "\": unknown namespace", (char *) NULL);
            return TCL_ERROR;
        }
	
	/*
	 * Check that we are not trying to create a namespace var linked to
	 * a local variable in a procedure. If we allowed this, the local
	 * variable in the shorter-lived procedure frame could go away
	 * leaving the namespace var's reference invalid.
	 */

	if ((otherP2 ? arrayPtr->nsPtr : otherPtr->nsPtr) == NULL) {
	    Tcl_AppendResult((Tcl_Interp *) iPtr, "bad variable name \"",
                    myName, "\": upvar won't create namespace variable that refers to procedure variable",
		    (char *) NULL);
            return TCL_ERROR;
        }
	
	hPtr = Tcl_CreateHashEntry(&nsPtr->varTable, tail, &new);
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
	CompiledLocal *localPtr = procPtr->firstLocalPtr;
	Var *localVarPtr = varFramePtr->compiledLocals;
	int nameLen = strlen(myName);
	int i;

	varPtr = NULL;
	for (i = 0;  i < localCt;  i++) {
	    if (!localPtr->isTemp) {
		char *localName = localVarPtr->name;
		if ((myName[0] == localName[0])
		        && (nameLen == localPtr->nameLength)
		        && (strcmp(myName, localName) == 0)) {
		    varPtr = localVarPtr;
		    new = 0;
		    break;







|







3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
	CompiledLocal *localPtr = procPtr->firstLocalPtr;
	Var *localVarPtr = varFramePtr->compiledLocals;
	int nameLen = strlen(myName);
	int i;

	varPtr = NULL;
	for (i = 0;  i < localCt;  i++) {
	    if (!TclIsVarTemporary(localPtr)) {
		char *localName = localVarPtr->name;
		if ((myName[0] == localName[0])
		        && (nameLen == localPtr->nameLength)
		        && (strcmp(myName, localName) == 0)) {
		    varPtr = localVarPtr;
		    new = 0;
		    break;
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
	    }
	    linkPtr->refCount--;
	    if (TclIsVarUndefined(linkPtr)) {
		CleanupVar(linkPtr, (Var *) NULL);
	    }
	} else if (!TclIsVarUndefined(varPtr)) {
	    Tcl_AppendResult((Tcl_Interp *) iPtr, "variable \"", myName,
		"\" already exists", (char *) NULL);
	    return TCL_ERROR;
	} else if (varPtr->tracePtr != NULL) {
	    Tcl_AppendResult((Tcl_Interp *) iPtr, "variable \"", myName,
		"\" has traces: can't use for upvar", (char *) NULL);
	    return TCL_ERROR;
	}
    }
    TclSetVarLink(varPtr);
    TclClearVarUndefined(varPtr);
    varPtr->value.linkPtr = otherPtr;
    otherPtr->refCount++;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UpVar --
 *
 *	This procedure links one variable to another, just like
 *	the "upvar" command.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs then
 *	an error message is left in interp->result.
 *
 * Side effects:
 *	The variable in frameName whose name is given by varName becomes
 *	accessible under the name localName, so that references to
 *	localName are redirected to the other variable like a symbolic
 *	link.
 *







|



|




















|







3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
	    }
	    linkPtr->refCount--;
	    if (TclIsVarUndefined(linkPtr)) {
		CleanupVar(linkPtr, (Var *) NULL);
	    }
	} else if (!TclIsVarUndefined(varPtr)) {
	    Tcl_AppendResult((Tcl_Interp *) iPtr, "variable \"", myName,
		    "\" already exists", (char *) NULL);
	    return TCL_ERROR;
	} else if (varPtr->tracePtr != NULL) {
	    Tcl_AppendResult((Tcl_Interp *) iPtr, "variable \"", myName,
		    "\" has traces: can't use for upvar", (char *) NULL);
	    return TCL_ERROR;
	}
    }
    TclSetVarLink(varPtr);
    TclClearVarUndefined(varPtr);
    varPtr->value.linkPtr = otherPtr;
    otherPtr->refCount++;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UpVar --
 *
 *	This procedure links one variable to another, just like
 *	the "upvar" command.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs then
 *	an error message is left in the interp's result.
 *
 * Side effects:
 *	The variable in frameName whose name is given by varName becomes
 *	accessible under the name localName, so that references to
 *	localName are redirected to the other variable like a symbolic
 *	link.
 *
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
 * Tcl_UpVar2 --
 *
 *	This procedure links one variable to another, just like
 *	the "upvar" command.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs then
 *	an error message is left in interp->result.
 *
 * Side effects:
 *	The variable in frameName whose name is given by part1 and
 *	part2 becomes accessible under the name localName, so that
 *	references to localName are redirected to the other variable
 *	like a symbolic link.
 *







|







3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
 * Tcl_UpVar2 --
 *
 *	This procedure links one variable to another, just like
 *	the "upvar" command.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs then
 *	an error message is left in the interp's result.
 *
 * Side effects:
 *	The variable in frameName whose name is given by part1 and
 *	part2 becomes accessible under the name localName, so that
 *	references to localName are redirected to the other variable
 *	like a symbolic link.
 *
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
    for (i = 1;  i < objc;  i++) {
	/*
	 * Make a local variable linked to its counterpart in the global ::
	 * namespace.
	 */
	
	objPtr = objv[i];
	varName = Tcl_GetStringFromObj(objPtr, (int *) NULL);

	/*
	 * The variable name might have a scope qualifier, but the name for
         * the local "link" variable must be the simple name at the tail.
	 */

	for (tail = varName;  *tail != '\0';  tail++) {







|







3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
    for (i = 1;  i < objc;  i++) {
	/*
	 * Make a local variable linked to its counterpart in the global ::
	 * namespace.
	 */
	
	objPtr = objv[i];
	varName = TclGetString(objPtr);

	/*
	 * The variable name might have a scope qualifier, but the name for
         * the local "link" variable must be the simple name at the tail.
	 */

	for (tail = varName;  *tail != '\0';  tail++) {
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
Tcl_VariableObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Interp *iPtr = (Interp *) interp;
    char *varName, *tail;
    Var *varPtr, *arrayPtr;
    Tcl_Obj *varValuePtr;
    int i, result;

    for (i = 1;  i < objc;  i = i+2) {
	/*
	 * Look up each variable in the current namespace context, creating
	 * it if necessary.
	 */
	
	varName = Tcl_GetStringFromObj(objv[i], (int *) NULL);
	varPtr = TclLookupVar(interp, varName, (char *) NULL,
                (TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "define",
                /*createPart1*/ 1, /*createPart2*/ 0, &arrayPtr);
	if (varPtr == NULL) {
	    return TCL_ERROR;
	}








|










|







3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
Tcl_VariableObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST objv[];	/* Argument objects. */
{
    Interp *iPtr = (Interp *) interp;
    char *varName, *tail, *cp;
    Var *varPtr, *arrayPtr;
    Tcl_Obj *varValuePtr;
    int i, result;

    for (i = 1;  i < objc;  i = i+2) {
	/*
	 * Look up each variable in the current namespace context, creating
	 * it if necessary.
	 */
	
	varName = TclGetString(objv[i]);
	varPtr = TclLookupVar(interp, varName, (char *) NULL,
                (TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "define",
                /*createPart1*/ 1, /*createPart2*/ 0, &arrayPtr);
	if (varPtr == NULL) {
	    return TCL_ERROR;
	}

3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710



3711
3712
3713
3714



3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
	 * Otherwise, if the variable is new, leave it undefined.
	 * (If the variable already exists and no value was specified,
	 * leave its value unchanged; just create the local link if
	 * we're in a Tcl procedure).
	 */

	if (i+1 < objc) {	/* a value was specified */
	    varValuePtr = Tcl_ObjSetVar2(interp, objv[i], (Tcl_Obj *) NULL,
		    objv[i+1], (TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG));
	    if (varValuePtr == NULL) {
		return TCL_ERROR;
	    }
	}

	/*
	 * If we are executing inside a Tcl procedure, create a local
	 * variable linked to the new namespace variable "varName".
	 */

	if ((iPtr->varFramePtr != NULL)
	        && iPtr->varFramePtr->isProcCallFrame) {
	    /*
	     * varName might have a scope qualifier, but the name for the
	     * local "link" variable must be the simple name at the tail.



	     */

	    for (tail = varName;  *tail != '\0';  tail++) {
		/* empty body */



	    }
	    while ((tail > varName)
		    && ((*tail != ':') || (*(tail-1) != ':'))) {
		tail--;
	    }
	    if (*tail == ':') {
		tail++;
	    }
	    
	    /*
	     * Create a local link "tail" to the variable "varName" in the
	     * current namespace.
	     */
	    







|
|















>
>
>


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







3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825

3826
3827
3828
3829



3830


3831
3832
3833
3834
3835
3836
3837
	 * Otherwise, if the variable is new, leave it undefined.
	 * (If the variable already exists and no value was specified,
	 * leave its value unchanged; just create the local link if
	 * we're in a Tcl procedure).
	 */

	if (i+1 < objc) {	/* a value was specified */
	    varValuePtr = Tcl_ObjSetVar2(interp, objv[i], NULL, objv[i+1],
		    (TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG));
	    if (varValuePtr == NULL) {
		return TCL_ERROR;
	    }
	}

	/*
	 * If we are executing inside a Tcl procedure, create a local
	 * variable linked to the new namespace variable "varName".
	 */

	if ((iPtr->varFramePtr != NULL)
	        && iPtr->varFramePtr->isProcCallFrame) {
	    /*
	     * varName might have a scope qualifier, but the name for the
	     * local "link" variable must be the simple name at the tail.
	     *
	     * Locate tail in one pass: drop any prefix after two *or more*
	     * consecutive ":" characters).
	     */

	    for (tail = cp = varName;  *cp != '\0'; ) {

		if (*cp++ == ':') {
		    while (*cp++ == ':') {
			tail = cp;
		    }



		}


	    }
	    
	    /*
	     * Create a local link "tail" to the variable "varName" in the
	     * current namespace.
	     */
	    
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
	Tcl_WrongNumArgs(interp, 1, objv,
		"?level? otherVar localVar ?otherVar localVar ...?");
	return TCL_ERROR;
    }

    /*
     * Find the call frame containing each of the "other variables" to be
     * linked to. FAILS IF objv[1]'s STRING REP CONTAINS NULLS.
     */

    frameSpec = Tcl_GetStringFromObj(objv[1], (int *) NULL);
    result = TclGetFrame(interp, frameSpec, &framePtr);
    if (result == -1) {
	return TCL_ERROR;
    }
    objc -= result+1;
    if ((objc & 1) != 0) {
	goto upvarSyntax;
    }
    objv += result+1;

    /*
     * Iterate over each (other variable, local variable) pair.
     * Divide the other variable name into two parts, then call
     * MakeUpvar to do all the work of linking it to the local variable.
     */

    for ( ;  objc > 0;  objc -= 2, objv += 2) {
	myVarName = Tcl_GetStringFromObj(objv[1], (int *) NULL);
	otherVarName = Tcl_GetStringFromObj(objv[0], (int *) NULL);
	for (p = otherVarName;  *p != 0;  p++) {
	    if (*p == '(') {
		char *openParen = p;

		do {
		    p++;
		} while (*p != '\0');







|


|

















|
|







3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
	Tcl_WrongNumArgs(interp, 1, objv,
		"?level? otherVar localVar ?otherVar localVar ...?");
	return TCL_ERROR;
    }

    /*
     * Find the call frame containing each of the "other variables" to be
     * linked to. 
     */

    frameSpec = TclGetString(objv[1]);
    result = TclGetFrame(interp, frameSpec, &framePtr);
    if (result == -1) {
	return TCL_ERROR;
    }
    objc -= result+1;
    if ((objc & 1) != 0) {
	goto upvarSyntax;
    }
    objv += result+1;

    /*
     * Iterate over each (other variable, local variable) pair.
     * Divide the other variable name into two parts, then call
     * MakeUpvar to do all the work of linking it to the local variable.
     */

    for ( ;  objc > 0;  objc -= 2, objv += 2) {
	myVarName = TclGetString(objv[1]);
	otherVarName = TclGetString(objv[0]);
	for (p = otherVarName;  *p != 0;  p++) {
	    if (*p == '(') {
		char *openParen = p;

		do {
		    p++;
		} while (*p != '\0');
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
    Var *varPtr;		/* Variable whose traces are to be
				 * invoked. */
    char *part1, *part2;	/* Variable's two-part name. */
    int flags;			/* Flags passed to trace procedures:
				 * indicates what's happening to variable,
				 * plus other stuff like TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, and
				 * TCL_INTERP_DESTROYED. May also contain
				 * TCL_PARSE_PART1, which should not be
				 * passed through to callbacks. */
{
    register VarTrace *tracePtr;
    ActiveVarTrace active;
    char *result, *openParen, *p;
    Tcl_DString nameCopy;
    int copiedName;








|
<
<







3977
3978
3979
3980
3981
3982
3983
3984


3985
3986
3987
3988
3989
3990
3991
    Var *varPtr;		/* Variable whose traces are to be
				 * invoked. */
    char *part1, *part2;	/* Variable's two-part name. */
    int flags;			/* Flags passed to trace procedures:
				 * indicates what's happening to variable,
				 * plus other stuff like TCL_GLOBAL_ONLY,
				 * TCL_NAMESPACE_ONLY, and
				 * TCL_INTERP_DESTROYED. */


{
    register VarTrace *tracePtr;
    ActiveVarTrace active;
    char *result, *openParen, *p;
    Tcl_DString nameCopy;
    int copiedName;

3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
     * make a copy of the original name so that NULLs can be
     * inserted into it to separate the names (can't modify the name
     * string in place, because the string might get used by the
     * callbacks we invoke).
     */

    copiedName = 0;
    if (flags & TCL_PARSE_PART1) {
	for (p = part1; ; p++) {
	    if (*p == 0) {
		break;
	    }
	    if (*p == '(') {
		openParen = p;
		do {
		    p++;
		} while (*p != '\0');
		p--;
		if (*p == ')') {
		    Tcl_DStringInit(&nameCopy);
		    Tcl_DStringAppend(&nameCopy, part1, (p-part1));
		    part2 = Tcl_DStringValue(&nameCopy)
			    + (openParen + 1 - part1);
		    part2[-1] = 0;
		    part1 = Tcl_DStringValue(&nameCopy);
		    copiedName = 1;
		}
		break;
	    }
	}
    }
    flags &= ~TCL_PARSE_PART1;

    /*
     * Invoke traces on the array containing the variable, if relevant.
     */

    result = NULL;
    active.nextPtr = iPtr->activeTracePtr;
    iPtr->activeTracePtr = &active;
    if (arrayPtr != NULL) {
	arrayPtr->refCount++;
	active.varPtr = arrayPtr;
	for (tracePtr = arrayPtr->tracePtr;  tracePtr != NULL;
		tracePtr = active.nextTracePtr) {
	    active.nextTracePtr = tracePtr->nextPtr;
	    if (!(tracePtr->flags & flags)) {
		continue;
	    }
	    result = (*tracePtr->traceProc)(tracePtr->clientData,
		    (Tcl_Interp *) iPtr, part1, part2, flags);
	    if (result != NULL) {







|
|
<
<
<










|








<












|







4006
4007
4008
4009
4010
4011
4012
4013
4014



4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033

4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
     * make a copy of the original name so that NULLs can be
     * inserted into it to separate the names (can't modify the name
     * string in place, because the string might get used by the
     * callbacks we invoke).
     */

    copiedName = 0;
    if (part2 == NULL) {
	for (p = part1; *p ; p++) {



	    if (*p == '(') {
		openParen = p;
		do {
		    p++;
		} while (*p != '\0');
		p--;
		if (*p == ')') {
		    Tcl_DStringInit(&nameCopy);
		    Tcl_DStringAppend(&nameCopy, part1, (p-part1));
		    part2 = Tcl_DStringValue(&nameCopy)
			+ (openParen + 1 - part1);
		    part2[-1] = 0;
		    part1 = Tcl_DStringValue(&nameCopy);
		    copiedName = 1;
		}
		break;
	    }
	}
    }


    /*
     * Invoke traces on the array containing the variable, if relevant.
     */

    result = NULL;
    active.nextPtr = iPtr->activeTracePtr;
    iPtr->activeTracePtr = &active;
    if (arrayPtr != NULL) {
	arrayPtr->refCount++;
	active.varPtr = arrayPtr;
	for (tracePtr = arrayPtr->tracePtr;  tracePtr != NULL;
	     tracePtr = active.nextTracePtr) {
	    active.nextTracePtr = tracePtr->nextPtr;
	    if (!(tracePtr->flags & flags)) {
		continue;
	    }
	    result = (*tracePtr->traceProc)(tracePtr->clientData,
		    (Tcl_Interp *) iPtr, part1, part2, flags);
	    if (result != NULL) {
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
     */

    if (flags & TCL_TRACE_UNSETS) {
	flags |= TCL_TRACE_DESTROYED;
    }
    active.varPtr = varPtr;
    for (tracePtr = varPtr->tracePtr; tracePtr != NULL;
	    tracePtr = active.nextTracePtr) {
	active.nextTracePtr = tracePtr->nextPtr;
	if (!(tracePtr->flags & flags)) {
	    continue;
	}
	result = (*tracePtr->traceProc)(tracePtr->clientData,
		(Tcl_Interp *) iPtr, part1, part2, flags);
	if (result != NULL) {







|







4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
     */

    if (flags & TCL_TRACE_UNSETS) {
	flags |= TCL_TRACE_DESTROYED;
    }
    active.varPtr = varPtr;
    for (tracePtr = varPtr->tracePtr; tracePtr != NULL;
	 tracePtr = active.nextTracePtr) {
	active.nextTracePtr = tracePtr->nextPtr;
	if (!(tracePtr->flags & flags)) {
	    continue;
	}
	result = (*tracePtr->traceProc)(tracePtr->clientData,
		(Tcl_Interp *) iPtr, part1, part2, flags);
	if (result != NULL) {
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
 *
 *	This procedure translates from a string to a pointer to an
 *	active array search (if there is one that matches the string).
 *
 * Results:
 *	The return value is a pointer to the array search indicated
 *	by string, or NULL if there isn't one.  If NULL is returned,
 *	interp->result contains an error message.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */








|







4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
 *
 *	This procedure translates from a string to a pointer to an
 *	active array search (if there is one that matches the string).
 *
 * Results:
 *	The return value is a pointer to the array search indicated
 *	by string, or NULL if there isn't one.  If NULL is returned,
 *	the interp's result contains an error message.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108

    /*
     * Search through the list of active searches on the interpreter
     * to see if the desired one exists.
     */

    for (searchPtr = varPtr->searchPtr; searchPtr != NULL;
	    searchPtr = searchPtr->nextPtr) {
	if (searchPtr->id == id) {
	    return searchPtr;
	}
    }
    Tcl_AppendResult(interp, "couldn't find search \"", string, "\"",
	    (char *) NULL);
    return NULL;







|







4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211

    /*
     * Search through the list of active searches on the interpreter
     * to see if the desired one exists.
     */

    for (searchPtr = varPtr->searchPtr; searchPtr != NULL;
	 searchPtr = searchPtr->nextPtr) {
	if (searchPtr->id == id) {
	    return searchPtr;
	}
    }
    Tcl_AppendResult(interp, "couldn't find search \"", string, "\"",
	    (char *) NULL);
    return NULL;
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
    if (tablePtr == &iPtr->globalNsPtr->varTable) {
	flags |= (TCL_INTERP_DESTROYED | TCL_GLOBAL_ONLY);
    } else if (tablePtr == &currNsPtr->varTable) {
	flags |= TCL_NAMESPACE_ONLY;
    }

    for (hPtr = Tcl_FirstHashEntry(tablePtr, &search);  hPtr != NULL;
	    hPtr = Tcl_NextHashEntry(&search)) {
	varPtr = (Var *) Tcl_GetHashValue(hPtr);

	/*
	 * For global/upvar variables referenced in procedures, decrement
	 * the reference count on the variable referred to, and free
	 * the referenced variable if it's no longer needed. Don't delete
	 * the hash entry for the other variable if it's in the same table







|







4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
    if (tablePtr == &iPtr->globalNsPtr->varTable) {
	flags |= (TCL_INTERP_DESTROYED | TCL_GLOBAL_ONLY);
    } else if (tablePtr == &currNsPtr->varTable) {
	flags |= TCL_NAMESPACE_ONLY;
    }

    for (hPtr = Tcl_FirstHashEntry(tablePtr, &search);  hPtr != NULL;
	 hPtr = Tcl_NextHashEntry(&search)) {
	varPtr = (Var *) Tcl_GetHashValue(hPtr);

	/*
	 * For global/upvar variables referenced in procedures, decrement
	 * the reference count on the variable referred to, and free
	 * the referenced variable if it's no longer needed. Don't delete
	 * the hash entry for the other variable if it's in the same table
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251

4252
4253
4254
4255
4256
4257
4258
	 */

	if (varPtr->tracePtr != NULL) {
	    objPtr = Tcl_NewObj();
	    Tcl_IncrRefCount(objPtr); /* until done with traces */
	    Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, objPtr);
	    (void) CallTraces(iPtr, (Var *) NULL, varPtr,
		    Tcl_GetStringFromObj(objPtr, (int *) NULL),
		    (char *) NULL, flags);
	    Tcl_DecrRefCount(objPtr); /* free no longer needed obj */

	    while (varPtr->tracePtr != NULL) {
		VarTrace *tracePtr = varPtr->tracePtr;
		varPtr->tracePtr = tracePtr->nextPtr;
		ckfree((char *) tracePtr);
	    }
	    for (activePtr = iPtr->activeTracePtr; activePtr != NULL;
		    activePtr = activePtr->nextPtr) {
		if (activePtr->varPtr == varPtr) {
		    activePtr->nextTracePtr = NULL;
		}
	    }
	}
	    
	if (TclIsVarArray(varPtr)) {
	    DeleteArray(iPtr, Tcl_GetHashKey(tablePtr, hPtr), varPtr,
	            flags);

	}
	if (TclIsVarScalar(varPtr) && (varPtr->value.objPtr != NULL)) {
	    objPtr = varPtr->value.objPtr;
	    TclDecrRefCount(objPtr);
	    varPtr->value.objPtr = NULL;
	}
	varPtr->hPtr = NULL;







<
|








|









>







4328
4329
4330
4331
4332
4333
4334

4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
	 */

	if (varPtr->tracePtr != NULL) {
	    objPtr = Tcl_NewObj();
	    Tcl_IncrRefCount(objPtr); /* until done with traces */
	    Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, objPtr);
	    (void) CallTraces(iPtr, (Var *) NULL, varPtr,

		    Tcl_GetString(objPtr), (char *) NULL, flags);
	    Tcl_DecrRefCount(objPtr); /* free no longer needed obj */

	    while (varPtr->tracePtr != NULL) {
		VarTrace *tracePtr = varPtr->tracePtr;
		varPtr->tracePtr = tracePtr->nextPtr;
		ckfree((char *) tracePtr);
	    }
	    for (activePtr = iPtr->activeTracePtr; activePtr != NULL;
		 activePtr = activePtr->nextPtr) {
		if (activePtr->varPtr == varPtr) {
		    activePtr->nextTracePtr = NULL;
		}
	    }
	}
	    
	if (TclIsVarArray(varPtr)) {
	    DeleteArray(iPtr, Tcl_GetHashKey(tablePtr, hPtr), varPtr,
	            flags);
	    varPtr->value.tablePtr = NULL;
	}
	if (TclIsVarScalar(varPtr) && (varPtr->value.objPtr != NULL)) {
	    objPtr = varPtr->value.objPtr;
	    TclDecrRefCount(objPtr);
	    varPtr->value.objPtr = NULL;
	}
	varPtr->hPtr = NULL;
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
		    varPtr->name, (char *) NULL, flags);
	    while (varPtr->tracePtr != NULL) {
		VarTrace *tracePtr = varPtr->tracePtr;
		varPtr->tracePtr = tracePtr->nextPtr;
		ckfree((char *) tracePtr);
	    }
	    for (activePtr = iPtr->activeTracePtr; activePtr != NULL;
		    activePtr = activePtr->nextPtr) {
		if (activePtr->varPtr == varPtr) {
		    activePtr->nextTracePtr = NULL;
		}
	    }
	}

        /*







|







4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
		    varPtr->name, (char *) NULL, flags);
	    while (varPtr->tracePtr != NULL) {
		VarTrace *tracePtr = varPtr->tracePtr;
		varPtr->tracePtr = tracePtr->nextPtr;
		ckfree((char *) tracePtr);
	    }
	    for (activePtr = iPtr->activeTracePtr; activePtr != NULL;
		 activePtr = activePtr->nextPtr) {
		if (activePtr->varPtr == varPtr) {
		    activePtr->nextTracePtr = NULL;
		}
	    }
	}

        /*
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
    register Tcl_HashEntry *hPtr;
    register Var *elPtr;
    ActiveVarTrace *activePtr;
    Tcl_Obj *objPtr;

    DeleteSearches(varPtr);
    for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr, &search);
	    hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
	elPtr = (Var *) Tcl_GetHashValue(hPtr);
	if (TclIsVarScalar(elPtr) && (elPtr->value.objPtr != NULL)) {
	    objPtr = elPtr->value.objPtr;
	    TclDecrRefCount(objPtr);
	    elPtr->value.objPtr = NULL;
	}
	elPtr->hPtr = NULL;
	if (elPtr->tracePtr != NULL) {
	    elPtr->flags &= ~VAR_TRACE_ACTIVE;
	    (void) CallTraces(iPtr, (Var *) NULL, elPtr, arrayName,
		    Tcl_GetHashKey(varPtr->value.tablePtr, hPtr), flags);
	    while (elPtr->tracePtr != NULL) {
		VarTrace *tracePtr = elPtr->tracePtr;
		elPtr->tracePtr = tracePtr->nextPtr;
		ckfree((char *) tracePtr);
	    }
	    for (activePtr = iPtr->activeTracePtr; activePtr != NULL;
		    activePtr = activePtr->nextPtr) {
		if (activePtr->varPtr == elPtr) {
		    activePtr->nextTracePtr = NULL;
		}
	    }
	}
	TclSetVarUndefined(elPtr);
	TclSetVarScalar(elPtr);







|

















|







4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
    register Tcl_HashEntry *hPtr;
    register Var *elPtr;
    ActiveVarTrace *activePtr;
    Tcl_Obj *objPtr;

    DeleteSearches(varPtr);
    for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr, &search);
	 hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
	elPtr = (Var *) Tcl_GetHashValue(hPtr);
	if (TclIsVarScalar(elPtr) && (elPtr->value.objPtr != NULL)) {
	    objPtr = elPtr->value.objPtr;
	    TclDecrRefCount(objPtr);
	    elPtr->value.objPtr = NULL;
	}
	elPtr->hPtr = NULL;
	if (elPtr->tracePtr != NULL) {
	    elPtr->flags &= ~VAR_TRACE_ACTIVE;
	    (void) CallTraces(iPtr, (Var *) NULL, elPtr, arrayName,
		    Tcl_GetHashKey(varPtr->value.tablePtr, hPtr), flags);
	    while (elPtr->tracePtr != NULL) {
		VarTrace *tracePtr = elPtr->tracePtr;
		elPtr->tracePtr = tracePtr->nextPtr;
		ckfree((char *) tracePtr);
	    }
	    for (activePtr = iPtr->activeTracePtr; activePtr != NULL;
		 activePtr = activePtr->nextPtr) {
		if (activePtr->varPtr == elPtr) {
		    activePtr->nextTracePtr = NULL;
		}
	    }
	}
	TclSetVarUndefined(elPtr);
	TclSetVarScalar(elPtr);
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
 *      Generate a reasonable error message describing why a variable
 *      operation failed.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      Interp->result is reset to hold a message identifying the
 *      variable given by part1 and part2 and describing why the
 *      variable operation failed.
 *
 *----------------------------------------------------------------------
 */

static void
VarErrMsg(interp, part1, part2, operation, reason)
    Tcl_Interp *interp;         /* Interpreter in which to record message. */
    char *part1, *part2;        /* Variable's two-part name. */
    char *operation;            /* String describing operation that failed,
                                 * e.g. "read", "set", or "unset". */
    char *reason;               /* String describing why operation failed. */
{
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, "can't ", operation, " \"", part1,
		     (char *) NULL);
    if (part2 != NULL) {
        Tcl_AppendResult(interp, "(", part2, ")", (char *) NULL);
    }
    Tcl_AppendResult(interp, "\": ", reason, (char *) NULL);
}







|
















|





4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
 *      Generate a reasonable error message describing why a variable
 *      operation failed.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      The interp's result is set to hold a message identifying the
 *      variable given by part1 and part2 and describing why the
 *      variable operation failed.
 *
 *----------------------------------------------------------------------
 */

static void
VarErrMsg(interp, part1, part2, operation, reason)
    Tcl_Interp *interp;         /* Interpreter in which to record message. */
    char *part1, *part2;        /* Variable's two-part name. */
    char *operation;            /* String describing operation that failed,
                                 * e.g. "read", "set", or "unset". */
    char *reason;               /* String describing why operation failed. */
{
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, "can't ", operation, " \"", part1,
	    (char *) NULL);
    if (part2 != NULL) {
        Tcl_AppendResult(interp, "(", part2, ")", (char *) NULL);
    }
    Tcl_AppendResult(interp, "\": ", reason, (char *) NULL);
}

Added library/auto.tcl.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































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

# auto_reset --
#
# Destroy all cached information for auto-loading and auto-execution,
# so that the information gets recomputed the next time it's needed.
# Also delete any procedures that are listed in the auto-load index
# except those defined in this file.
#
# Arguments: 
# None.

proc auto_reset {} {
    global auto_execs auto_index auto_oldpath
    foreach p [info procs] {
	if {[info exists auto_index($p)] && ![string match auto_* $p]
		&& ([lsearch -exact {unknown pkg_mkIndex tclPkgSetup
			tcl_findLibrary pkg_compareExtension
			tclMacPkgSearch tclPkgUnknown} $p] < 0)} {
	    rename $p {}
	}
    }
    catch {unset auto_execs}
    catch {unset auto_index}
    catch {unset auto_oldpath}
}

# tcl_findLibrary --
#
#	This is a utility for extensions that searches for a library directory
#	using a canonical searching algorithm. A side effect is to source
#	the initialization script and set a global library variable.
#
# Arguments:
# 	basename	Prefix of the directory name, (e.g., "tk")
#	version		Version number of the package, (e.g., "8.0")
#	patch		Patchlevel of the package, (e.g., "8.0.3")
#	initScript	Initialization script to source (e.g., tk.tcl)
#	enVarName	environment variable to honor (e.g., TK_LIBRARY)
#	varName		Global variable to set when done (e.g., tk_library)

proc tcl_findLibrary {basename version patch initScript enVarName varName} {
    upvar #0 $varName the_library
    global env errorInfo

    set dirs {}
    set errors {}

    # The C application may have hardwired a path, which we honor
    
    if {[info exist the_library] && [string compare $the_library {}]} {
	lappend dirs $the_library
    } else {

	# Do the canonical search

	# 1. From an environment variable, if it exists

        if {[info exists env($enVarName)]} {
            lappend dirs $env($enVarName)
        }

	# 2. Relative to the Tcl library

        lappend dirs [file join [file dirname [info library]] \
		$basename$version]

	# 3. Various locations relative to the executable
	# ../lib/foo1.0		(From bin directory in install hierarchy)
	# ../../lib/foo1.0	(From bin/arch directory in install hierarchy)
	# ../library		(From unix directory in build hierarchy)
	# ../../library		(From unix/arch directory in build hierarchy)
	# ../../foo1.0b1/library (From unix directory in parallel build hierarchy)
	# ../../../foo1.0b1/library (From unix/arch directory in parallel build hierarchy)

        set parentDir [file dirname [file dirname [info nameofexecutable]]]
        set grandParentDir [file dirname $parentDir]
        lappend dirs [file join $parentDir lib $basename$version]
        lappend dirs [file join $grandParentDir lib $basename$version]
        lappend dirs [file join $parentDir library]
        lappend dirs [file join $grandParentDir library]
        if {![regexp {.*[ab][0-9]*} $patch ver]} {
            set ver $version
        }
        lappend dirs [file join $grandParentDir $basename$ver library]
        lappend dirs [file join [file dirname $grandParentDir] $basename$ver library]
    }
    foreach i $dirs {
        set the_library $i
        set file [file join $i $initScript]

	# source everything when in a safe interpreter because
	# we have a source command, but no file exists command

        if {[interp issafe] || [file exists $file]} {
            if {![catch {uplevel #0 [list source $file]} msg]} {
                return
            } else {
                append errors "$file: $msg\n$errorInfo\n"
            }
        }
    }
    set msg "Can't find a usable $initScript in the following directories: \n"
    append msg "    $dirs\n\n"
    append msg "$errors\n\n"
    append msg "This probably means that $basename wasn't installed properly.\n"
    error $msg
}


# ----------------------------------------------------------------------
# auto_mkindex
# ----------------------------------------------------------------------
# The following procedures are used to generate the tclIndex file
# from Tcl source files.  They use a special safe interpreter to
# parse Tcl source files, writing out index entries as "proc"
# commands are encountered.  This implementation won't work in a
# safe interpreter, since a safe interpreter can't create the
# special parser and mess with its commands.  

if {[interp issafe]} {
    return	;# Stop sourcing the file here
}

# auto_mkindex --
# Regenerate a tclIndex file from Tcl source files.  Takes as argument
# the name of the directory in which the tclIndex file is to be placed,
# followed by any number of glob patterns to use in that directory to
# locate all of the relevant files.
#
# Arguments: 
# dir -		Name of the directory in which to create an index.
# args -	Any number of additional arguments giving the
#		names of files within dir.  If no additional
#		are given auto_mkindex will look for *.tcl.

proc auto_mkindex {dir args} {
    global errorCode errorInfo

    if {[interp issafe]} {
        error "can't generate index within safe interpreter"
    }

    set oldDir [pwd]
    cd $dir
    set dir [pwd]

    append index "# Tcl autoload index file, version 2.0\n"
    append index "# This file is generated by the \"auto_mkindex\" command\n"
    append index "# and sourced to set up indexing information for one or\n"
    append index "# more commands.  Typically each line is a command that\n"
    append index "# sets an element in the auto_index array, where the\n"
    append index "# element name is the name of a command and the value is\n"
    append index "# a script that loads the command.\n\n"
    if {$args == ""} {
	set args *.tcl
    }

    auto_mkindex_parser::init
    foreach file [eval glob $args] {
        if {[catch {auto_mkindex_parser::mkindex $file} msg] == 0} {
            append index $msg
        } else {
            set code $errorCode
            set info $errorInfo
            cd $oldDir
            error $msg $info $code
        }
    }
    auto_mkindex_parser::cleanup

    set fid [open "tclIndex" w]
    puts $fid $index nonewline
    close $fid
    cd $oldDir
}

# Original version of auto_mkindex that just searches the source
# code for "proc" at the beginning of the line.

proc auto_mkindex_old {dir args} {
    global errorCode errorInfo
    set oldDir [pwd]
    cd $dir
    set dir [pwd]
    append index "# Tcl autoload index file, version 2.0\n"
    append index "# This file is generated by the \"auto_mkindex\" command\n"
    append index "# and sourced to set up indexing information for one or\n"
    append index "# more commands.  Typically each line is a command that\n"
    append index "# sets an element in the auto_index array, where the\n"
    append index "# element name is the name of a command and the value is\n"
    append index "# a script that loads the command.\n\n"
    if {$args == ""} {
	set args *.tcl
    }
    foreach file [eval glob $args] {
	set f ""
	set error [catch {
	    set f [open $file]
	    while {[gets $f line] >= 0} {
		if {[regexp {^proc[ 	]+([^ 	]*)} $line match procName]} {
		    set procName [lindex [auto_qualify $procName "::"] 0]
		    append index "set [list auto_index($procName)]"
		    append index " \[list source \[file join \$dir [list $file]\]\]\n"
		}
	    }
	    close $f
	} msg]
	if {$error} {
	    set code $errorCode
	    set info $errorInfo
	    catch {close $f}
	    cd $oldDir
	    error $msg $info $code
	}
    }
    set f ""
    set error [catch {
	set f [open tclIndex w]
	puts $f $index nonewline
	close $f
	cd $oldDir
    } msg]
    if {$error} {
	set code $errorCode
	set info $errorInfo
	catch {close $f}
	cd $oldDir
	error $msg $info $code
    }
}

# Create a safe interpreter that can be used to parse Tcl source files
# generate a tclIndex file for autoloading.  This interp contains
# commands for things that need index entries.  Each time a command
# is executed, it writes an entry out to the index file.

namespace eval auto_mkindex_parser {
    variable parser ""          ;# parser used to build index
    variable index ""           ;# maintains index as it is built
    variable scriptFile ""      ;# name of file being processed
    variable contextStack ""    ;# stack of namespace scopes
    variable imports ""         ;# keeps track of all imported cmds
    variable initCommands ""    ;# list of commands that create aliases

    proc init {} {
	variable parser
	variable initCommands

	if {![interp issafe]} {
	    set parser [interp create -safe]
	    $parser hide info
	    $parser hide rename
	    $parser hide proc
	    $parser hide namespace
	    $parser hide eval
	    $parser hide puts
	    $parser invokehidden namespace delete ::
	    $parser invokehidden proc unknown {args} {}

	    # We'll need access to the "namespace" command within the
	    # interp.  Put it back, but move it out of the way.

	    $parser expose namespace
	    $parser invokehidden rename namespace _%@namespace
	    $parser expose eval
	    $parser invokehidden rename eval _%@eval

	    # Install all the registered psuedo-command implementations

	    foreach cmd $initCommands {
		eval $cmd
	    }
	}
    }
    proc cleanup {} {
	variable parser
	interp delete $parser
	unset parser
    }
}

# auto_mkindex_parser::mkindex --
#
# Used by the "auto_mkindex" command to create a "tclIndex" file for
# the given Tcl source file.  Executes the commands in the file, and
# handles things like the "proc" command by adding an entry for the
# index file.  Returns a string that represents the index file.
#
# Arguments: 
#	file	Name of Tcl source file to be indexed.

proc auto_mkindex_parser::mkindex {file} {
    variable parser
    variable index
    variable scriptFile
    variable contextStack
    variable imports

    set scriptFile $file

    set fid [open $file]
    set contents [read $fid]
    close $fid

    # There is one problem with sourcing files into the safe
    # interpreter:  references like "$x" will fail since code is not
    # really being executed and variables do not really exist.
    # Be careful to escape all naked "$" before evaluating.

    regsub -all {([^\$])\$([^\$])} $contents {\1\\$\2} contents

    set index ""
    set contextStack ""
    set imports ""

    $parser eval $contents

    foreach name $imports {
        catch {$parser eval [list _%@namespace forget $name]}
    }
    return $index
}

# auto_mkindex_parser::hook command
#
# Registers a Tcl command to evaluate when initializing the
# slave interpreter used by the mkindex parser.
# The command is evaluated in the master interpreter, and can
# use the variable auto_mkindex_parser::parser to get to the slave

proc auto_mkindex_parser::hook {cmd} {
    variable initCommands

    lappend initCommands $cmd
}

# auto_mkindex_parser::slavehook command
#
# Registers a Tcl command to evaluate when initializing the
# slave interpreter used by the mkindex parser.
# The command is evaluated in the slave interpreter.

proc auto_mkindex_parser::slavehook {cmd} {
    variable initCommands

    # The $parser variable is defined to be the name of the
    # slave interpreter when this command is used later.

    lappend initCommands "\$parser eval [list $cmd]"
}

# auto_mkindex_parser::command --
#
# Registers a new command with the "auto_mkindex_parser" interpreter
# that parses Tcl files.  These commands are fake versions of things
# like the "proc" command.  When you execute them, they simply write
# out an entry to a "tclIndex" file for auto-loading.
#
# This procedure allows extensions to register their own commands
# with the auto_mkindex facility.  For example, a package like
# [incr Tcl] might register a "class" command so that class definitions
# could be added to a "tclIndex" file for auto-loading.
#
# Arguments:
#	name 	Name of command recognized in Tcl files.
#	arglist	Argument list for command.
#	body 	Implementation of command to handle indexing.

proc auto_mkindex_parser::command {name arglist body} {
    hook [list auto_mkindex_parser::commandInit $name $arglist $body]
}

# auto_mkindex_parser::commandInit --
#
# This does the actual work set up by auto_mkindex_parser::command
# This is called when the interpreter used by the parser is created.
#
# Arguments:
#	name 	Name of command recognized in Tcl files.
#	arglist	Argument list for command.
#	body 	Implementation of command to handle indexing.

proc auto_mkindex_parser::commandInit {name arglist body} {
    variable parser

    set ns [namespace qualifiers $name]
    set tail [namespace tail $name]
    if {$ns == ""} {
        set fakeName "[namespace current]::_%@fake_$tail"
    } else {
        set fakeName "_%@fake_$name"
        regsub -all {::} $fakeName "_" fakeName
        set fakeName "[namespace current]::$fakeName"
    }
    proc $fakeName $arglist $body

    # YUK!  Tcl won't let us alias fully qualified command names,
    # so we can't handle names like "::itcl::class".  Instead,
    # we have to build procs with the fully qualified names, and
    # have the procs point to the aliases.

    if {[regexp {::} $name]} {
        set exportCmd [list _%@namespace export [namespace tail $name]]
        $parser eval [list _%@namespace eval $ns $exportCmd]
 
	# The following proc definition does not work if you
	# want to tolerate space or something else diabolical
	# in the procedure name, (i.e., space in $alias)
	# The following does not work:
	#   "_%@eval {$alias} \$args"
	# because $alias gets concat'ed to $args.
	# The following does not work because $cmd is somehow undefined
	#   "set cmd {$alias} \; _%@eval {\$cmd} \$args"
	# A gold star to someone that can make test
	# autoMkindex-3.3 work properly

        set alias [namespace tail $fakeName]
        $parser invokehidden proc $name {args} "_%@eval {$alias} \$args"
        $parser alias $alias $fakeName
    } else {
        $parser alias $name $fakeName
    }
    return
}

# auto_mkindex_parser::fullname --
# Used by commands like "proc" within the auto_mkindex parser.
# Returns the qualified namespace name for the "name" argument.
# If the "name" does not start with "::", elements are added from
# the current namespace stack to produce a qualified name.  Then,
# the name is examined to see whether or not it should really be
# qualified.  If the name has more than the leading "::", it is
# returned as a fully qualified name.  Otherwise, it is returned
# as a simple name.  That way, the Tcl autoloader will recognize
# it properly.
#
# Arguments:
# name -		Name that is being added to index.

proc auto_mkindex_parser::fullname {name} {
    variable contextStack

    if {![string match ::* $name]} {
        foreach ns $contextStack {
            set name "${ns}::$name"
            if {[string match ::* $name]} {
                break
            }
        }
    }

    if {[namespace qualifiers $name] == ""} {
        return [namespace tail $name]
    } elseif {![string match ::* $name]} {
        return "::$name"
    }
    return $name
}

# Register all of the procedures for the auto_mkindex parser that
# will build the "tclIndex" file.

# AUTO MKINDEX:  proc name arglist body
# Adds an entry to the auto index list for the given procedure name.

auto_mkindex_parser::command proc {name args} {
    variable index
    variable scriptFile
    append index [list set auto_index([fullname $name])] \
	    " \[list source \[file join \$dir [list $scriptFile]\]\]\n"
}

# Conditionally add support for Tcl byte code files.  There are some
# tricky details here.  First, we need to get the tbcload library
# initialized in the current interpreter.  We cannot load tbcload into the
# slave until we have done so because it needs access to the tcl_patchLevel
# variable.  Second, because the package index file may defer loading the
# library until we invoke a command, we need to explicitly invoke auto_load
# to force it to be loaded.  This should be a noop if the package has
# already been loaded

auto_mkindex_parser::hook {
    if {![catch {package require tbcload}]} {
	if {[info commands tbcload::bcproc] == ""} {
	    auto_load tbcload::bcproc
	}
	load {} tbcload $auto_mkindex_parser::parser

	# AUTO MKINDEX:  tbcload::bcproc name arglist body
	# Adds an entry to the auto index list for the given pre-compiled
	# procedure name.  

	auto_mkindex_parser::commandInit tbcload::bcproc {name args} {
	    variable index
	    variable scriptFile
	    append index [list set auto_index([fullname $name])] \
		    " \[list source \[file join \$dir [list $scriptFile]\]\]\n"
	}
    }
}

# AUTO MKINDEX:  namespace eval name command ?arg arg...?
# Adds the namespace name onto the context stack and evaluates the
# associated body of commands.
#
# AUTO MKINDEX:  namespace import ?-force? pattern ?pattern...?
# Performs the "import" action in the parser interpreter.  This is
# important for any commands contained in a namespace that affect
# the index.  For example, a script may say "itcl::class ...",
# or it may import "itcl::*" and then say "class ...".  This
# procedure does the import operation, but keeps track of imported
# patterns so we can remove the imports later.

auto_mkindex_parser::command namespace {op args} {
    switch -- $op {
        eval {
            variable parser
            variable contextStack

            set name [lindex $args 0]
            set args [lrange $args 1 end]

            set contextStack [linsert $contextStack 0 $name]
	    $parser eval [list _%@namespace eval $name] $args
            set contextStack [lrange $contextStack 1 end]
        }
        import {
            variable parser
            variable imports
            foreach pattern $args {
                if {$pattern != "-force"} {
                    lappend imports $pattern
                }
            }
            catch {$parser eval "_%@namespace import $args"}
        }
    }
}

return

Added library/encoding/ascii.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: ascii, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/big5.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
# Encoding file: big5, multi-byte
M
003F 0 89
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3000FF0C30013002FF0E2022FF1BFF1AFF1FFF01FE3020262025FE50FF64FE52
00B7FE54FE55FE56FE57FF5C2013FE312014FE33FFFDFE34FE4FFF08FF09FE35
FE36FF5BFF5DFE37FE3830143015FE39FE3A30103011FE3BFE3C300A300BFE3D
FE3E30083009FE3FFE40300C300DFE41FE42300E300FFE43FE44FE59FE5A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FE5BFE5CFE5DFE5E20182019201C201D301D301E20352032FF03FF06FF0A
203B00A7300325CB25CF25B325B225CE2606260525C725C625A125A025BD25BC
32A32105203EFFFDFF3FFFFDFE49FE4AFE4DFE4EFE4BFE4CFE5FFE60FE61FF0B
FF0D00D700F700B1221AFF1CFF1EFF1D226622672260221E22522261FE62FE63
FE64FE65FE66223C2229222A22A52220221F22BF33D233D1222B222E22352234
26402642264126092191219321902192219621972199219822252223FFFD0000
A2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FFFDFF0FFF3CFF0400A5301200A200A3FF05FF2021032109FE69FE6AFE6B33D5
339C339D339E33CE33A1338E338F33C400B05159515B515E515D5161516355E7
74E97CCE25812582258325842585258625872588258F258E258D258C258B258A
2589253C2534252C2524251C2594250025022595250C251025142518256D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000256E2570256F2550255E256A256125E225E325E525E4257125722573FF10
FF11FF12FF13FF14FF15FF16FF17FF18FF192160216121622163216421652166
216721682169302130223023302430253026302730283029FFFD5344FFFDFF21
FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2FFF30FF31
FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF41FF42FF43FF44FF45FF46FF47
FF48FF49FF4AFF4BFF4CFF4DFF4EFF4FFF50FF51FF52FF53FF54FF55FF560000
A3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF57FF58FF59FF5A039103920393039403950396039703980399039A039B039C
039D039E039F03A003A103A303A403A503A603A703A803A903B103B203B303B4
03B503B603B703B803B903BA03BB03BC03BD03BE03BF03C003C103C303C403C5
03C603C703C803C931053106310731083109310A310B310C310D310E310F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00003110311131123113311431153116311731183119311A311B311C311D311E
311F312031213122312331243125312631273128312902D902C902CA02C702CB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E004E594E014E034E434E5D4E864E8C4EBA513F5165516B51E052005201529B
53155341535C53C84E094E0B4E084E0A4E2B4E3851E14E454E484E5F4E5E4E8E
4EA15140520352FA534353C953E3571F58EB5915592759735B505B515B535BF8
5C0F5C225C385C715DDD5DE55DF15DF25DF35DFE5E725EFE5F0B5F13624D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E114E104E0D4E2D4E304E394E4B5C394E884E914E954E924E944EA24EC1
4EC04EC34EC64EC74ECD4ECA4ECB4EC4514351415167516D516E516C519751F6
52065207520852FB52FE52FF53165339534853475345535E538453CB53CA53CD
58EC5929592B592A592D5B545C115C245C3A5C6F5DF45E7B5EFF5F145F155FC3
62086236624B624E652F6587659765A465B965E566F0670867286B206B626B79
6BCB6BD46BDB6C0F6C34706B722A7236723B72477259725B72AC738B4E190000
A5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E164E154E144E184E3B4E4D4E4F4E4E4EE54ED84ED44ED54ED64ED74EE34EE4
4ED94EDE514551445189518A51AC51F951FA51F8520A52A0529F530553065317
531D4EDF534A534953615360536F536E53BB53EF53E453F353EC53EE53E953E8
53FC53F853F553EB53E653EA53F253F153F053E553ED53FB56DB56DA59160000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000592E5931597459765B555B835C3C5DE85DE75DE65E025E035E735E7C5F01
5F185F175FC5620A625362546252625165A565E6672E672C672A672B672D6B63
6BCD6C116C106C386C416C406C3E72AF7384738974DC74E67518751F75287529
7530753175327533758B767D76AE76BF76EE77DB77E277F3793A79BE7A747ACB
4E1E4E1F4E524E534E694E994EA44EA64EA54EFF4F094F194F0A4F154F0D4F10
4F114F0F4EF24EF64EFB4EF04EF34EFD4F014F0B514951475146514851680000
A6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5171518D51B0521752115212520E521652A3530853215320537053715409540F
540C540A54105401540B54045411540D54085403540E5406541256E056DE56DD
573357305728572D572C572F57295919591A59375938598459785983597D5979
598259815B575B585B875B885B855B895BFA5C165C795DDE5E065E765E740000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F0F5F1B5FD95FD6620E620C620D62106263625B6258653665E965E865EC
65ED66F266F36709673D6734673167356B216B646B7B6C166C5D6C576C596C5F
6C606C506C556C616C5B6C4D6C4E7070725F725D767E7AF97C737CF87F367F8A
7FBD80018003800C80128033807F8089808B808C81E381EA81F381FC820C821B
821F826E8272827E866B8840884C8863897F96214E324EA84F4D4F4F4F474F57
4F5E4F344F5B4F554F304F504F514F3D4F3A4F384F434F544F3C4F464F630000
A7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4F5C4F604F2F4F4E4F364F594F5D4F484F5A514C514B514D517551B651B75225
52245229522A522852AB52A952AA52AC532353735375541D542D541E543E5426
544E542754465443543354485442541B5429544A5439543B5438542E54355436
5420543C54405431542B541F542C56EA56F056E456EB574A57515740574D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005747574E573E5750574F573B58EF593E599D599259A8599E59A359995996
598D59A45993598A59A55B5D5B5C5B5A5B5B5B8C5B8B5B8F5C2C5C405C415C3F
5C3E5C905C915C945C8C5DEB5E0C5E8F5E875E8A5EF75F045F1F5F645F625F77
5F795FD85FCC5FD75FCD5FF15FEB5FF85FEA6212621162846297629662806276
6289626D628A627C627E627962736292626F6298626E62956293629162866539
653B653865F166F4675F674E674F67506751675C6756675E6749674667600000
A8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
675367576B656BCF6C426C5E6C996C816C886C896C856C9B6C6A6C7A6C906C70
6C8C6C686C966C926C7D6C836C726C7E6C746C866C766C8D6C946C986C827076
707C707D707872627261726072C472C27396752C752B75377538768276EF77E3
79C179C079BF7A767CFB7F5580968093809D8098809B809A80B2826F82920000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000828B828D898B89D28A008C378C468C558C9D8D648D708DB38EAB8ECA8F9B
8FB08FC28FC68FC58FC45DE1909190A290AA90A690A3914991C691CC9632962E
9631962A962C4E264E564E734E8B4E9B4E9E4EAB4EAC4F6F4F9D4F8D4F734F7F
4F6C4F9B4F8B4F864F834F704F754F884F694F7B4F964F7E4F8F4F914F7A5154
51525155516951775176517851BD51FD523B52385237523A5230522E52365241
52BE52BB5352535453535351536653775378537953D653D453D7547354750000
A9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5496547854955480547B5477548454925486547C549054715476548C549A5462
5468548B547D548E56FA57835777576A5769576157665764577C591C59495947
59485944595459BE59BB59D459B959AE59D159C659D059CD59CB59D359CA59AF
59B359D259C55B5F5B645B635B975B9A5B985B9C5B995B9B5C1A5C485C450000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005C465CB75CA15CB85CA95CAB5CB15CB35E185E1A5E165E155E1B5E115E78
5E9A5E975E9C5E955E965EF65F265F275F295F805F815F7F5F7C5FDD5FE05FFD
5FF55FFF600F6014602F60356016602A6015602160276029602B601B62166215
623F623E6240627F62C962CC62C462BF62C262B962D262DB62AB62D362D462CB
62C862A862BD62BC62D062D962C762CD62B562DA62B162D862D662D762C662AC
62CE653E65A765BC65FA66146613660C66066602660E6600660F6615660A0000
AA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6607670D670B676D678B67956771679C677367776787679D6797676F6770677F
6789677E67906775679A6793677C676A67726B236B666B676B7F6C136C1B6CE3
6CE86CF36CB16CCC6CE56CB36CBD6CBE6CBC6CE26CAB6CD56CD36CB86CC46CB9
6CC16CAE6CD76CC56CF16CBF6CBB6CE16CDB6CCA6CAC6CEF6CDC6CD66CE00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007095708E7092708A7099722C722D723872487267726972C072CE72D972D7
72D073A973A8739F73AB73A5753D759D7599759A768476C276F276F477E577FD
793E7940794179C979C87A7A7A797AFA7CFE7F547F8C7F8B800580BA80A580A2
80B180A180AB80A980B480AA80AF81E581FE820D82B3829D829982AD82BD829F
82B982B182AC82A582AF82B882A382B082BE82B7864E8671521D88688ECB8FCE
8FD48FD190B590B890B190B691C791D195779580961C9640963F963B96440000
AB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
964296B996E89752975E4E9F4EAD4EAE4FE14FB54FAF4FBF4FE04FD14FCF4FDD
4FC34FB64FD84FDF4FCA4FD74FAE4FD04FC44FC24FDA4FCE4FDE4FB751575192
519151A0524E5243524A524D524C524B524752C752C952C352C1530D5357537B
539A53DB54AC54C054A854CE54C954B854A654B354C754C254BD54AA54C10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054C454C854AF54AB54B154BB54A954A754BF56FF5782578B57A057A357A2
57CE57AE579359555951594F594E595059DC59D859FF59E359E85A0359E559EA
59DA59E65A0159FB5B695BA35BA65BA45BA25BA55C015C4E5C4F5C4D5C4B5CD9
5CD25DF75E1D5E255E1F5E7D5EA05EA65EFA5F085F2D5F655F885F855F8A5F8B
5F875F8C5F896012601D60206025600E6028604D60706068606260466043606C
606B606A6064624162DC6316630962FC62ED630162EE62FD630762F162F70000
AC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
62EF62EC62FE62F463116302653F654565AB65BD65E26625662D66206627662F
661F66286631662466F767FF67D367F167D467D067EC67B667AF67F567E967EF
67C467D167B467DA67E567B867CF67DE67F367B067D967E267DD67D26B6A6B83
6B866BB56BD26BD76C1F6CC96D0B6D326D2A6D416D256D0C6D316D1E6D170000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D3B6D3D6D3E6D366D1B6CF56D396D276D386D296D2E6D356D0E6D2B70AB
70BA70B370AC70AF70AD70B870AE70A472307272726F727472E972E072E173B7
73CA73BB73B273CD73C073B3751A752D754F754C754E754B75AB75A475A575A2
75A3767876867687768876C876C676C376C5770176F976F87709770B76FE76FC
770777DC78027814780C780D794679497948794779B979BA79D179D279CB7A7F
7A817AFF7AFD7C7D7D027D057D007D097D077D047D067F387F8E7FBF80040000
AD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8010800D8011803680D680E580DA80C380C480CC80E180DB80CE80DE80E480DD
81F4822282E78303830582E382DB82E6830482E58302830982D282D782F18301
82DC82D482D182DE82D382DF82EF830686508679867B867A884D886B898189D4
8A088A028A038C9E8CA08D748D738DB48ECD8ECC8FF08FE68FE28FEA8FE50000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008FED8FEB8FE48FE890CA90CE90C190C3914B914A91CD95829650964B964C
964D9762976997CB97ED97F3980198A898DB98DF999699994E584EB3500C500D
50234FEF502650254FF8502950165006503C501F501A501250114FFA50005014
50284FF15021500B501950184FF34FEE502D502A4FFE502B5009517C51A451A5
51A251CD51CC51C651CB5256525C5254525B525D532A537F539F539D53DF54E8
55105501553754FC54E554F2550654FA551454E954ED54E1550954EE54EA0000
AE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54E65527550754FD550F5703570457C257D457CB57C35809590F59575958595A
5A115A185A1C5A1F5A1B5A1359EC5A205A235A295A255A0C5A095B6B5C585BB0
5BB35BB65BB45BAE5BB55BB95BB85C045C515C555C505CED5CFD5CFB5CEA5CE8
5CF05CF65D015CF45DEE5E2D5E2B5EAB5EAD5EA75F315F925F915F9060590000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006063606560506055606D6069606F6084609F609A608D6094608C60856096
624762F3630862FF634E633E632F635563426346634F6349633A6350633D632A
632B6328634D634C65486549659965C165C566426649664F66436652664C6645
664166F867146715671768216838684868466853683968426854682968B36817
684C6851683D67F468506840683C6843682A68456813681868416B8A6B896BB7
6C236C276C286C266C246CF06D6A6D956D886D876D666D786D776D596D930000
AF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6D6C6D896D6E6D5A6D746D696D8C6D8A6D796D856D656D9470CA70D870E470D9
70C870CF7239727972FC72F972FD72F872F7738673ED740973EE73E073EA73DE
7554755D755C755A755975BE75C575C775B275B375BD75BC75B975C275B8768B
76B076CA76CD76CE7729771F7720772877E9783078277838781D783478370000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007825782D7820781F7832795579507960795F7956795E795D7957795A79E4
79E379E779DF79E679E979D87A847A887AD97B067B117C897D217D177D0B7D0A
7D207D227D147D107D157D1A7D1C7D0D7D197D1B7F3A7F5F7F947FC57FC18006
8018801580198017803D803F80F1810280F0810580ED80F4810680F880F38108
80FD810A80FC80EF81ED81EC82008210822A822B8228822C82BB832B83528354
834A83388350834983358334834F833283398336831783408331832883430000
B0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8654868A86AA869386A486A9868C86A3869C8870887788818882887D88798A18
8A108A0E8A0C8A158A0A8A178A138A168A0F8A118C488C7A8C798CA18CA28D77
8EAC8ED28ED48ECF8FB1900190068FF790008FFA8FF490038FFD90058FF89095
90E190DD90E29152914D914C91D891DD91D791DC91D995839662966396610000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000965B965D96649658965E96BB98E299AC9AA89AD89B259B329B3C4E7E507A
507D505C50475043504C505A504950655076504E5055507550745077504F500F
506F506D515C519551F0526A526F52D252D952D852D55310530F5319533F5340
533E53C366FC5546556A55665544555E55615543554A55315556554F5555552F
55645538552E555C552C55635533554155575708570B570957DF5805580A5806
57E057E457FA5802583557F757F9592059625A365A415A495A665A6A5A400000
B1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5A3C5A625A5A5A465A4A5B705BC75BC55BC45BC25BBF5BC65C095C085C075C60
5C5C5C5D5D075D065D0E5D1B5D165D225D115D295D145D195D245D275D175DE2
5E385E365E335E375EB75EB85EB65EB55EBE5F355F375F575F6C5F695F6B5F97
5F995F9E5F985FA15FA05F9C607F60A3608960A060A860CB60B460E660BD0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000060C560BB60B560DC60BC60D860D560C660DF60B860DA60C7621A621B6248
63A063A76372639663A263A563776367639863AA637163A963896383639B636B
63A863846388639963A163AC6392638F6380637B63696368637A655D65566551
65596557555F654F655865556554659C659B65AC65CF65CB65CC65CE665D665A
666466686666665E66F952D7671B688168AF68A2689368B5687F687668B168A7
689768B0688368C468AD688668856894689D68A8689F68A168826B326BBA0000
B2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6BEB6BEC6C2B6D8E6DBC6DF36DD96DB26DE16DCC6DE46DFB6DFA6E056DC76DCB
6DAF6DD16DAE6DDE6DF96DB86DF76DF56DC56DD26E1A6DB56DDA6DEB6DD86DEA
6DF16DEE6DE86DC66DC46DAA6DEC6DBF6DE670F97109710A70FD70EF723D727D
7281731C731B73167313731973877405740A7403740673FE740D74E074F60000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000074F7751C75227565756675627570758F75D475D575B575CA75CD768E76D4
76D276DB7737773E773C77367738773A786B7843784E79657968796D79FB7A92
7A957B207B287B1B7B2C7B267B197B1E7B2E7C927C977C957D467D437D717D2E
7D397D3C7D407D307D337D447D2F7D427D327D317F3D7F9E7F9A7FCC7FCE7FD2
801C804A8046812F81168123812B81298130812482028235823782368239838E
839E8398837883A2839683BD83AB8392838A8393838983A08377837B837C0000
B3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
838683A786555F6A86C786C086B686C486B586C686CB86B186AF86C98853889E
888888AB88928896888D888B8993898F8A2A8A1D8A238A258A318A2D8A1F8A1B
8A228C498C5A8CA98CAC8CAB8CA88CAA8CA78D678D668DBE8DBA8EDB8EDF9019
900D901A90179023901F901D90109015901E9020900F90229016901B90140000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000090E890ED90FD915791CE91F591E691E391E791ED91E99589966A96759673
96789670967496769677966C96C096EA96E97AE07ADF980298039B5A9CE59E75
9E7F9EA59EBB50A2508D508550995091508050965098509A670051F152725274
5275526952DE52DD52DB535A53A5557B558055A7557C558A559D55985582559C
55AA55945587558B558355B355AE559F553E55B2559A55BB55AC55B1557E5589
55AB5599570D582F582A58345824583058315821581D582058F958FA59600000
B4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5A775A9A5A7F5A925A9B5AA75B735B715BD25BCC5BD35BD05C0A5C0B5C315D4C
5D505D345D475DFD5E455E3D5E405E435E7E5ECA5EC15EC25EC45F3C5F6D5FA9
5FAA5FA860D160E160B260B660E0611C612360FA611560F060FB60F4616860F1
610E60F6610961006112621F624963A3638C63CF63C063E963C963C663CD0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000063D263E363D063E163D663ED63EE637663F463EA63DB645263DA63F9655E
6566656265636591659065AF666E667066746676666F6691667A667E667766FE
66FF671F671D68FA68D568E068D868D7690568DF68F568EE68E768F968D268F2
68E368CB68CD690D6912690E68C968DA696E68FB6B3E6B3A6B3D6B986B966BBC
6BEF6C2E6C2F6C2C6E2F6E386E546E216E326E676E4A6E206E256E236E1B6E5B
6E586E246E566E6E6E2D6E266E6F6E346E4D6E3A6E2C6E436E1D6E3E6ECB0000
B5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6E896E196E4E6E636E446E726E696E5F7119711A7126713071217136716E711C
724C728472807336732573347329743A742A743374227425743574367434742F
741B7426742875257526756B756A75E275DB75E375D975D875DE75E0767B767C
7696769376B476DC774F77ED785D786C786F7A0D7A087A0B7A057A007A980000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A977A967AE57AE37B497B567B467B507B527B547B4D7B4B7B4F7B517C9F
7CA57D5E7D507D687D557D2B7D6E7D727D617D667D627D707D7355847FD47FD5
800B8052808581558154814B8151814E81398146813E814C815381748212821C
83E9840383F8840D83E083C5840B83C183EF83F183F48457840A83F0840C83CC
83FD83F283CA8438840E840483DC840783D483DF865B86DF86D986ED86D486DB
86E486D086DE885788C188C288B1898389968A3B8A608A558A5E8A3C8A410000
B6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8A548A5B8A508A468A348A3A8A368A568C618C828CAF8CBC8CB38CBD8CC18CBB
8CC08CB48CB78CB68CBF8CB88D8A8D858D818DCE8DDD8DCB8DDA8DD18DCC8DDB
8DC68EFB8EF88EFC8F9C902E90359031903890329036910290F5910990FE9163
916591CF9214921592239209921E920D9210920792119594958F958B95910000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000095939592958E968A968E968B967D96859686968D9672968496C196C596C4
96C696C796EF96F297CC98059806980898E798EA98EF98E998F298ED99AE99AD
9EC39ECD9ED14E8250AD50B550B250B350C550BE50AC50B750BB50AF50C7527F
5277527D52DF52E652E452E252E3532F55DF55E855D355E655CE55DC55C755D1
55E355E455EF55DA55E155C555C655E555C957125713585E585158585857585A
5854586B584C586D584A58625852584B59675AC15AC95ACC5ABE5ABD5ABC0000
B7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5AB35AC25AB25D695D6F5E4C5E795EC95EC85F125F595FAC5FAE611A610F6148
611F60F3611B60F961016108614E614C6144614D613E61346127610D61066137
622162226413643E641E642A642D643D642C640F641C6414640D643664166417
6406656C659F65B06697668966876688669666846698668D67036994696D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000695A697769606954697569306982694A6968696B695E695369796986695D
6963695B6B476B726BC06BBF6BD36BFD6EA26EAF6ED36EB66EC26E906E9D6EC7
6EC56EA56E986EBC6EBA6EAB6ED16E966E9C6EC46ED46EAA6EA76EB4714E7159
7169716471497167715C716C7166714C7165715E714671687156723A72527337
7345733F733E746F745A7455745F745E7441743F7459745B745C757675787600
75F0760175F275F175FA75FF75F475F376DE76DF775B776B7766775E77630000
B8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7779776A776C775C77657768776277EE788E78B078977898788C7889787C7891
7893787F797A797F7981842C79BD7A1C7A1A7A207A147A1F7A1E7A9F7AA07B77
7BC07B607B6E7B677CB17CB37CB57D937D797D917D817D8F7D5B7F6E7F697F6A
7F727FA97FA87FA480568058808680848171817081788165816E8173816B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008179817A81668205824784828477843D843184758466846B8449846C845B
843C8435846184638469846D8446865E865C865F86F9871387088707870086FE
86FB870287038706870A885988DF88D488D988DC88D888DD88E188CA88D588D2
899C89E38A6B8A728A738A668A698A708A878A7C8A638AA08A718A858A6D8A62
8A6E8A6C8A798A7B8A3E8A688C628C8A8C898CCA8CC78CC88CC48CB28CC38CC2
8CC58DE18DDF8DE88DEF8DF38DFA8DEA8DE48DE68EB28F038F098EFE8F0A0000
B9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8F9F8FB2904B904A905390429054903C905590509047904F904E904D9051903E
904191129117916C916A916991C9923792579238923D9240923E925B924B9264
925192349249924D92459239923F925A959896989694969596CD96CB96C996CA
96F796FB96F996F6975697749776981098119813980A9812980C98FC98F40000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000098FD98FE99B399B199B49AE19CE99E829F0E9F139F2050E750EE50E550D6
50ED50DA50D550CF50D150F150CE50E9516251F352835282533153AD55FE5600
561B561755FD561456065609560D560E55F75616561F5608561055F657185716
5875587E58835893588A58795885587D58FD592559225924596A59695AE15AE6
5AE95AD75AD65AD85AE35B755BDE5BE75BE15BE55BE65BE85BE25BE45BDF5C0D
5C625D845D875E5B5E635E555E575E545ED35ED65F0A5F465F705FB961470000
BA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
613F614B617761626163615F615A61586175622A64876458645464A46478645F
647A645164676434646D647B657265A165D765D666A266A8669D699C69A86995
69C169AE69D369CB699B69B769BB69AB69B469D069CD69AD69CC69A669C369A3
6B496B4C6C336F336F146EFE6F136EF46F296F3E6F206F2C6F0F6F026F220000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006EFF6EEF6F066F316F386F326F236F156F2B6F2F6F886F2A6EEC6F016EF2
6ECC6EF771947199717D718A71847192723E729272967344735074647463746A
7470746D750475917627760D760B7609761376E176E37784777D777F776178C1
789F78A778B378A978A3798E798F798D7A2E7A317AAA7AA97AED7AEF7BA17B95
7B8B7B757B977B9D7B947B8F7BB87B877B847CB97CBD7CBE7DBB7DB07D9C7DBD
7DBE7DA07DCA7DB47DB27DB17DBA7DA27DBF7DB57DB87DAD7DD27DC77DAC0000
BB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7F707FE07FE17FDF805E805A808781508180818F8188818A817F818281E781FA
82078214821E824B84C984BF84C684C48499849E84B2849C84CB84B884C084D3
849084BC84D184CA873F871C873B872287258734871887558737872988F38902
88F488F988F888FD88E8891A88EF8AA68A8C8A9E8AA38A8D8AA18A938AA40000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008AAA8AA58AA88A988A918A9A8AA78C6A8C8D8C8C8CD38CD18CD28D6B8D99
8D958DFC8F148F128F158F138FA390609058905C90639059905E9062905D905B
91199118911E917591789177917492789280928592989296927B9293929C92A8
927C929195A195A895A995A395A595A49699969C969B96CC96D29700977C9785
97F69817981898AF98B199039905990C990999C19AAF9AB09AE69B419B429CF4
9CF69CF39EBC9F3B9F4A5104510050FB50F550F9510251085109510551DC0000
BC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
528752885289528D528A52F053B2562E563B56395632563F563456295653564E
565756745636562F56305880589F589E58B3589C58AE58A958A6596D5B095AFB
5B0B5AF55B0C5B085BEE5BEC5BE95BEB5C645C655D9D5D945E625E5F5E615EE2
5EDA5EDF5EDD5EE35EE05F485F715FB75FB561766167616E615D615561820000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000617C6170616B617E61A7619061AB618E61AC619A61A4619461AE622E6469
646F6479649E64B26488649064B064A56493649564A9649264AE64AD64AB649A
64AC649964A264B365756577657866AE66AB66B466B16A236A1F69E86A016A1E
6A1969FD6A216A136A0A69F36A026A0569ED6A116B506B4E6BA46BC56BC66F3F
6F7C6F846F516F666F546F866F6D6F5B6F786F6E6F8E6F7A6F706F646F976F58
6ED56F6F6F606F5F719F71AC71B171A87256729B734E73577469748B74830000
BD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
747E7480757F76207629761F7624762676217622769A76BA76E4778E7787778C
7791778B78CB78C578BA78CA78BE78D578BC78D07A3F7A3C7A407A3D7A377A3B
7AAF7AAE7BAD7BB17BC47BB47BC67BC77BC17BA07BCC7CCA7DE07DF47DEF7DFB
7DD87DEC7DDD7DE87DE37DDA7DDE7DE97D9E7DD97DF27DF97F757F777FAF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007FE98026819B819C819D81A0819A81988517853D851A84EE852C852D8513
851185238521851484EC852584FF850687828774877687608766877887688759
8757874C8753885B885D89108907891289138915890A8ABC8AD28AC78AC48A95
8ACB8AF88AB28AC98AC28ABF8AB08AD68ACD8AB68AB98ADB8C4C8C4E8C6C8CE0
8CDE8CE68CE48CEC8CED8CE28CE38CDC8CEA8CE18D6D8D9F8DA38E2B8E108E1D
8E228E0F8E298E1F8E218E1E8EBA8F1D8F1B8F1F8F298F268F2A8F1C8F1E0000
BE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8F259069906E9068906D90779130912D9127913191879189918B918392C592BB
92B792EA92AC92E492C192B392BC92D292C792F092B295AD95B1970497069707
97099760978D978B978F9821982B981C98B3990A99139912991899DD99D099DF
99DB99D199D599D299D99AB79AEE9AEF9B279B459B449B779B6F9D069D090000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009D039EA99EBE9ECE58A89F5251125118511451105115518051AA51DD5291
529352F35659566B5679566956645678566A566856655671566F566C56625676
58C158BE58C758C5596E5B1D5B345B785BF05C0E5F4A61B2619161A9618A61CD
61B661BE61CA61C8623064C564C164CB64BB64BC64DA64C464C764C264CD64BF
64D264D464BE657466C666C966B966C466C766B86A3D6A386A3A6A596A6B6A58
6A396A446A626A616A4B6A476A356A5F6A486B596B776C056FC26FB16FA10000
BF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6FC36FA46FC16FA76FB36FC06FB96FB66FA66FA06FB471BE71C971D071D271C8
71D571B971CE71D971DC71C371C47368749C74A37498749F749E74E2750C750D
76347638763A76E776E577A0779E779F77A578E878DA78EC78E779A67A4D7A4E
7A467A4C7A4B7ABA7BD97C117BC97BE47BDB7BE17BE97BE67CD57CD67E0A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007E117E087E1B7E237E1E7E1D7E097E107F797FB27FF07FF17FEE802881B3
81A981A881FB820882588259854A855985488568856985438549856D856A855E
8783879F879E87A2878D8861892A89328925892B892189AA89A68AE68AFA8AEB
8AF18B008ADC8AE78AEE8AFE8B018B028AF78AED8AF38AF68AFC8C6B8C6D8C93
8CF48E448E318E348E428E398E358F3B8F2F8F388F338FA88FA6907590749078
9072907C907A913491929320933692F89333932F932292FC932B9304931A0000
C0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9310932693219315932E931995BB96A796A896AA96D5970E97119716970D9713
970F975B975C9766979898309838983B9837982D9839982499109928991E991B
9921991A99ED99E299F19AB89ABC9AFB9AED9B289B919D159D239D269D289D12
9D1B9ED89ED49F8D9F9C512A511F5121513252F5568E56805690568556870000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000568F58D558D358D158CE5B305B2A5B245B7A5C375C685DBC5DBA5DBD5DB8
5E6B5F4C5FBD61C961C261C761E661CB6232623464CE64CA64D864E064F064E6
64EC64F164E264ED6582658366D966D66A806A946A846AA26A9C6ADB6AA36A7E
6A976A906AA06B5C6BAE6BDA6C086FD86FF16FDF6FE06FDB6FE46FEB6FEF6F80
6FEC6FE16FE96FD56FEE6FF071E771DF71EE71E671E571ED71EC71F471E07235
72467370737274A974B074A674A876467642764C76EA77B377AA77B077AC0000
C1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
77A777AD77EF78F778FA78F478EF790179A779AA7A577ABF7C077C0D7BFE7BF7
7C0C7BE07CE07CDC7CDE7CE27CDF7CD97CDD7E2E7E3E7E467E377E327E437E2B
7E3D7E317E457E417E347E397E487E357E3F7E2F7F447FF37FFC807180728070
806F807381C681C381BA81C281C081BF81BD81C981BE81E88209827185AA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008584857E859C8591859485AF859B858785A8858A866787C087D187B387D2
87C687AB87BB87BA87C887CB893B893689448938893D89AC8B0E8B178B198B1B
8B0A8B208B1D8B048B108C418C3F8C738CFA8CFD8CFC8CF88CFB8DA88E498E4B
8E488E4A8F448F3E8F428F458F3F907F907D9084908190829080913991A3919E
919C934D938293289375934A9365934B9318937E936C935B9370935A935495CA
95CB95CC95C895C696B196B896D6971C971E97A097D3984698B699359A010000
C2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
99FF9BAE9BAB9BAA9BAD9D3B9D3F9E8B9ECF9EDE9EDC9EDD9EDB9F3E9F4B53E2
569556AE58D958D85B385F5D61E3623364F464F264FE650664FA64FB64F765B7
66DC67266AB36AAC6AC36ABB6AB86AC26AAE6AAF6B5F6B786BAF7009700B6FFE
70066FFA7011700F71FB71FC71FE71F87377737574A774BF7515765676580000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000765277BD77BF77BB77BC790E79AE7A617A627A607AC47AC57C2B7C277C2A
7C1E7C237C217CE77E547E557E5E7E5A7E617E527E597F487FF97FFB80778076
81CD81CF820A85CF85A985CD85D085C985B085BA85B985A687EF87EC87F287E0
898689B289F48B288B398B2C8B2B8C508D058E598E638E668E648E5F8E558EC0
8F498F4D90879083908891AB91AC91D09394938A939693A293B393AE93AC93B0
9398939A939795D495D695D095D596E296DC96D996DB96DE972497A397A60000
C3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
97AD97F9984D984F984C984E985398BA993E993F993D992E99A59A0E9AC19B03
9B069B4F9B4E9B4D9BCA9BC99BFD9BC89BC09D519D5D9D609EE09F159F2C5133
56A558DE58DF58E25BF59F905EEC61F261F761F661F56500650F66E066DD6AE5
6ADD6ADA6AD3701B701F7028701A701D701570187206720D725872A273780000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000737A74BD74CA74E375877586765F766177C7791979B17A6B7A697C3E7C3F
7C387C3D7C377C407E6B7E6D7E797E697E6A7F857E737FB67FB97FB881D885E9
85DD85EA85D585E485E585F787FB8805880D87F987FE8960895F8956895E8B41
8B5C8B588B498B5A8B4E8B4F8B468B598D088D0A8E7C8E728E878E768E6C8E7A
8E748F548F4E8FAD908A908B91B191AE93E193D193DF93C393C893DC93DD93D6
93E293CD93D893E493D793E895DC96B496E3972A9727976197DC97FB985E0000
C4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9858985B98BC994599499A169A199B0D9BE89BE79BD69BDB9D899D619D729D6A
9D6C9E929E979E939EB452F856A856B756B656B456BC58E45B405B435B7D5BF6
5DC961F861FA65186514651966E667276AEC703E703070327210737B74CF7662
76657926792A792C792B7AC77AF67C4C7C437C4D7CEF7CF08FAE7E7D7E7C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007E827F4C800081DA826685FB85F9861185FA8606860B8607860A88148815
896489BA89F88B708B6C8B668B6F8B5F8B6B8D0F8D0D8E898E818E858E8291B4
91CB9418940393FD95E1973098C49952995199A89A2B9A309A379A359C139C0D
9E799EB59EE89F2F9F5F9F639F615137513856C156C056C259145C6C5DCD61FC
61FE651D651C659566E96AFB6B046AFA6BB2704C721B72A774D674D4766977D3
7C507E8F7E8C7FBC8617862D861A882388228821881F896A896C89BD8B740000
C5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8B778B7D8D138E8A8E8D8E8B8F5F8FAF91BA942E94339435943A94389432942B
95E297389739973297FF9867986599579A459A439A409A3E9ACF9B549B519C2D
9C259DAF9DB49DC29DB89E9D9EEF9F199F5C9F669F67513C513B56C856CA56C9
5B7F5DD45DD25F4E61FF65246B0A6B6170517058738074E4758A766E766C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000079B37C607C5F807E807D81DF8972896F89FC8B808D168D178E918E938F61
9148944494519452973D973E97C397C1986B99559A559A4D9AD29B1A9C499C31
9C3E9C3B9DD39DD79F349F6C9F6A9F9456CC5DD662006523652B652A66EC6B10
74DA7ACA7C647C637C657E937E967E9481E28638863F88318B8A9090908F9463
946094649768986F995C9A5A9A5B9A579AD39AD49AD19C549C579C569DE59E9F
9EF456D158E9652C705E7671767277D77F507F888836883988628B938B920000
C6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8B9682778D1B91C0946A97429748974497C698709A5F9B229B589C5F9DF99DFA
9E7C9E7D9F079F779F725EF36B1670637C6C7C6E883B89C08EA191C194729470
9871995E9AD69B239ECC706477DA8B9A947797C99A629A657E9C8B9C8EAA91C5
947D947E947C9C779C789EF78C54947F9E1A72289A6A9B319E1B9E1E7C720000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030FE309D309E3005304130423043304430453046304730483049304A304B
304C304D304E304F3050305130523053305430553056305730583059305A305B
305C305D305E305F3060306130623063306430653066306730683069306A306B
306C306D306E306F3070307130723073307430753076307730783079307A307B
307C307D307E307F3080308130823083308430853086308730883089308A308B
308C308D308E308F309030913092309330A130A230A330A430A530A630A70000
C7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
30A830A930AA30AB30AC30AD30AE30AF30B030B130B230B330B430B530B630B7
30B830B930BA30BB30BC30BD30BE30BF30C030C130C230C330C430C530C630C7
30C830C930CA30CB30CC30CD30CE30CF30D030D130D230D330D430D530D630D7
30D830D930DA30DB30DC30DD30DE30DF30E030E130E230E330E430E530E60000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030E730E830E930EA30EB30EC30ED30EE30EF30F030F130F230F330F430F5
30F60414041504010416041704180419041A041B041C04230424042504260427
04280429042A042B042C042D042E042F04300431043204330434043504510436
043704380439043A043B043C043D043E043F0440044104420443044404450446
044704480449044A044B044C044D044E044F2460246124622463246424652466
246724682469247424752476247724782479247A247B247C247D000000000000
C9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E424E5C51F5531A53824E074E0C4E474E8D56D7FA0C5C6E5F734E0F51874E0E
4E2E4E934EC24EC94EC8519852FC536C53B957205903592C5C105DFF65E16BB3
6BCC6C14723F4E314E3C4EE84EDC4EE94EE14EDD4EDA520C531C534C57225723
5917592F5B815B845C125C3B5C745C735E045E805E825FC9620962506C150000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006C366C436C3F6C3B72AE72B0738A79B8808A961E4F0E4F184F2C4EF54F14
4EF14F004EF74F084F1D4F024F054F224F134F044EF44F1251B1521352095210
52A65322531F534D538A540756E156DF572E572A5734593C5980597C5985597B
597E5977597F5B565C155C255C7C5C7A5C7B5C7E5DDF5E755E845F025F1A5F74
5FD55FD45FCF625C625E626462616266626262596260625A626565EF65EE673E
67396738673B673A673F673C67336C186C466C526C5C6C4F6C4A6C546C4B0000
CA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6C4C7071725E72B472B5738E752A767F7A757F518278827C8280827D827F864D
897E909990979098909B909496229624962096234F564F3B4F624F494F534F64
4F3E4F674F524F5F4F414F584F2D4F334F3F4F61518F51B9521C521E522152AD
52AE530953635372538E538F54305437542A545454455419541C542554180000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000543D544F544154285424544756EE56E756E557415745574C5749574B5752
5906594059A6599859A05997598E59A25990598F59A759A15B8E5B925C285C2A
5C8D5C8F5C885C8B5C895C925C8A5C865C935C955DE05E0A5E0E5E8B5E895E8C
5E885E8D5F055F1D5F785F765FD25FD15FD05FED5FE85FEE5FF35FE15FE45FE3
5FFA5FEF5FF75FFB60005FF4623A6283628C628E628F629462876271627B627A
6270628162886277627D62726274653765F065F465F365F265F5674567470000
CB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
67596755674C6748675D674D675A674B6BD06C196C1A6C786C676C6B6C846C8B
6C8F6C716C6F6C696C9A6C6D6C876C956C9C6C666C736C656C7B6C8E7074707A
726372BF72BD72C372C672C172BA72C573957397739373947392753A75397594
75957681793D80348095809980908092809C8290828F8285828E829182930000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000828A828382848C788FC98FBF909F90A190A5909E90A790A096309628962F
962D4E334F984F7C4F854F7D4F804F874F764F744F894F844F774F4C4F974F6A
4F9A4F794F814F784F904F9C4F944F9E4F924F824F954F6B4F6E519E51BC51BE
5235523252335246523152BC530A530B533C539253945487547F548154915482
5488546B547A547E5465546C54745466548D546F546154605498546354675464
56F756F9576F5772576D576B57715770577657805775577B5773577457620000
CC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5768577D590C594559B559BA59CF59CE59B259CC59C159B659BC59C359D659B1
59BD59C059C859B459C75B625B655B935B955C445C475CAE5CA45CA05CB55CAF
5CA85CAC5C9F5CA35CAD5CA25CAA5CA75C9D5CA55CB65CB05CA65E175E145E19
5F285F225F235F245F545F825F7E5F7D5FDE5FE5602D602660196032600B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006034600A60176033601A601E602C6022600D6010602E60136011600C6009
601C6214623D62AD62B462D162BE62AA62B662CA62AE62B362AF62BB62A962B0
62B8653D65A865BB660965FC66046612660865FB6603660B660D660565FD6611
661066F6670A6785676C678E67926776677B6798678667846774678D678C677A
679F679167996783677D67816778677967946B256B806B7E6BDE6C1D6C936CEC
6CEB6CEE6CD96CB66CD46CAD6CE76CB76CD06CC26CBA6CC36CC66CED6CF20000
CD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6CD26CDD6CB46C8A6C9D6C806CDE6CC06D306CCD6CC76CB06CF96CCF6CE96CD1
709470987085709370867084709170967082709A7083726A72D672CB72D872C9
72DC72D272D472DA72CC72D173A473A173AD73A673A273A073AC739D74DD74E8
753F7540753E758C759876AF76F376F176F076F577F877FC77F977FB77FA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077F77942793F79C57A787A7B7AFB7C757CFD8035808F80AE80A380B880B5
80AD822082A082C082AB829A8298829B82B582A782AE82BC829E82BA82B482A8
82A182A982C282A482C382B682A28670866F866D866E8C568FD28FCB8FD38FCD
8FD68FD58FD790B290B490AF90B390B09639963D963C963A96434FCD4FC54FD3
4FB24FC94FCB4FC14FD44FDC4FD94FBB4FB34FDB4FC74FD64FBA4FC04FB94FEC
5244524952C052C2533D537C539753965399539854BA54A154AD54A554CF0000
CE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54C3830D54B754AE54D654B654C554C654A0547054BC54A254BE547254DE54B0
57B5579E579F57A4578C5797579D579B57945798578F579957A5579A579558F4
590D595359E159DE59EE5A0059F159DD59FA59FD59FC59F659E459F259F759DB
59E959F359F559E059FE59F459ED5BA85C4C5CD05CD85CCC5CD75CCB5CDB0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005CDE5CDA5CC95CC75CCA5CD65CD35CD45CCF5CC85CC65CCE5CDF5CF85DF9
5E215E225E235E205E245EB05EA45EA25E9B5EA35EA55F075F2E5F565F866037
603960546072605E6045605360476049605B604C60406042605F602460446058
6066606E6242624362CF630D630B62F5630E630362EB62F9630F630C62F862F6
63006313631462FA631562FB62F06541654365AA65BF6636662166326635661C
662666226633662B663A661D66346639662E670F671067C167F267C867BA0000
CF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
67DC67BB67F867D867C067B767C567EB67E467DF67B567CD67B367F767F667EE
67E367C267B967CE67E767F067B267FC67C667ED67CC67AE67E667DB67FA67C9
67CA67C367EA67CB6B286B826B846BB66BD66BD86BE06C206C216D286D346D2D
6D1F6D3C6D3F6D126D0A6CDA6D336D046D196D3A6D1A6D116D006D1D6D420000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D016D186D376D036D0F6D406D076D206D2C6D086D226D096D1070B7709F
70BE70B170B070A170B470B570A972417249724A726C72707273726E72CA72E4
72E872EB72DF72EA72E672E3738573CC73C273C873C573B973B673B573B473EB
73BF73C773BE73C373C673B873CB74EC74EE752E7547754875A775AA767976C4
7708770377047705770A76F776FB76FA77E777E878067811781278057810780F
780E780978037813794A794C794B7945794479D579CD79CF79D679CE7A800000
D0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7A7E7AD17B007B017C7A7C787C797C7F7C807C817D037D087D017F587F917F8D
7FBE8007800E800F8014803780D880C780E080D180C880C280D080C580E380D9
80DC80CA80D580C980CF80D780E680CD81FF8221829482D982FE82F9830782E8
830082D5833A82EB82D682F482EC82E182F282F5830C82FB82F682F082EA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000082E482E082FA82F382ED86778674867C86738841884E8867886A886989D3
8A048A078D728FE38FE18FEE8FE090F190BD90BF90D590C590BE90C790CB90C8
91D491D39654964F96519653964A964E501E50055007501350225030501B4FF5
4FF450335037502C4FF64FF75017501C502050275035502F5031500E515A5194
519351CA51C451C551C851CE5261525A5252525E525F5255526252CD530E539E
552654E25517551254E754F354E4551A54FF5504550854EB5511550554F10000
D1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
550A54FB54F754F854E0550E5503550B5701570257CC583257D557D257BA57C6
57BD57BC57B857B657BF57C757D057B957C1590E594A5A195A165A2D5A2E5A15
5A0F5A175A0A5A1E5A335B6C5BA75BAD5BAC5C035C565C545CEC5CFF5CEE5CF1
5CF75D005CF95E295E285EA85EAE5EAA5EAC5F335F305F67605D605A60670000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000604160A26088608060926081609D60836095609B60976087609C608E6219
624662F263106356632C634463456336634363E46339634B634A633C63296341
6334635863546359632D63476333635A63516338635763406348654A654665C6
65C365C465C2664A665F6647665167126713681F681A684968326833683B684B
684F68166831681C6835682B682D682F684E68446834681D6812681468266828
682E684D683A682568206B2C6B2F6B2D6B316B346B6D80826B886BE66BE40000
D2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6BE86BE36BE26BE76C256D7A6D636D646D766D0D6D616D926D586D626D6D6D6F
6D916D8D6DEF6D7F6D866D5E6D676D606D976D706D7C6D5F6D826D986D2F6D68
6D8B6D7E6D806D846D166D836D7B6D7D6D756D9070DC70D370D170DD70CB7F39
70E270D770D270DE70E070D470CD70C570C670C770DA70CE70E1724272780000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000072777276730072FA72F472FE72F672F372FB730173D373D973E573D673BC
73E773E373E973DC73D273DB73D473DD73DA73D773D873E874DE74DF74F474F5
7521755B755F75B075C175BB75C475C075BF75B675BA768A76C9771D771B7710
771377127723771177157719771A772277277823782C78227835782F7828782E
782B782178297833782A78317954795B794F795C79537952795179EB79EC79E0
79EE79ED79EA79DC79DE79DD7A867A897A857A8B7A8C7A8A7A877AD87B100000
D3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7B047B137B057B0F7B087B0A7B0E7B097B127C847C917C8A7C8C7C887C8D7C85
7D1E7D1D7D117D0E7D187D167D137D1F7D127D0F7D0C7F5C7F617F5E7F607F5D
7F5B7F967F927FC37FC27FC08016803E803980FA80F280F980F5810180FB8100
8201822F82258333832D83448319835183258356833F83418326831C83220000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008342834E831B832A8308833C834D8316832483208337832F832983478345
834C8353831E832C834B832783488653865286A286A88696868D8691869E8687
86978686868B869A868586A5869986A186A786958698868E869D869086948843
8844886D88758876887288808871887F886F8883887E8874887C8A128C478C57
8C7B8CA48CA38D768D788DB58DB78DB68ED18ED38FFE8FF590028FFF8FFB9004
8FFC8FF690D690E090D990DA90E390DF90E590D890DB90D790DC90E491500000
D4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
914E914F91D591E291DA965C965F96BC98E39ADF9B2F4E7F5070506A5061505E
50605053504B505D50725048504D5041505B504A506250155045505F5069506B
5063506450465040506E50735057505151D0526B526D526C526E52D652D3532D
539C55755576553C554D55505534552A55515562553655355530555255450000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000550C55325565554E55395548552D553B5540554B570A570757FB581457E2
57F657DC57F4580057ED57FD580857F8580B57F357CF580757EE57E357F257E5
57EC57E1580E57FC581057E75801580C57F157E957F0580D5804595C5A605A58
5A555A675A5E5A385A355A6D5A505A5F5A655A6C5A535A645A575A435A5D5A52
5A445A5B5A485A8E5A3E5A4D5A395A4C5A705A695A475A515A565A425A5C5B72
5B6E5BC15BC05C595D1E5D0B5D1D5D1A5D205D0C5D285D0D5D265D255D0F0000
D5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5D305D125D235D1F5D2E5E3E5E345EB15EB45EB95EB25EB35F365F385F9B5F96
5F9F608A6090608660BE60B060BA60D360D460CF60E460D960DD60C860B160DB
60B760CA60BF60C360CD60C063326365638A6382637D63BD639E63AD639D6397
63AB638E636F63876390636E63AF6375639C636D63AE637C63A4633B639F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006378638563816391638D6370655365CD66656661665B6659665C66626718
687968876890689C686D686E68AE68AB6956686F68A368AC68A96875687468B2
688F68776892687C686B687268AA68806871687E689B6896688B68A0688968A4
6878687B6891688C688A687D6B366B336B376B386B916B8F6B8D6B8E6B8C6C2A
6DC06DAB6DB46DB36E746DAC6DE96DE26DB76DF66DD46E006DC86DE06DDF6DD6
6DBE6DE56DDC6DDD6DDB6DF46DCA6DBD6DED6DF06DBA6DD56DC26DCF6DC90000
D6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6DD06DF26DD36DFD6DD76DCD6DE36DBB70FA710D70F7711770F4710C70F07104
70F3711070FC70FF71067113710070F870F6710B7102710E727E727B727C727F
731D7317730773117318730A730872FF730F731E738873F673F873F574047401
73FD7407740073FA73FC73FF740C740B73F474087564756375CE75D275CF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075CB75CC75D175D0768F768976D37739772F772D7731773277347733773D
7725773B7735784878527849784D784A784C782678457850796479677969796A
7963796B796179BB79FA79F879F679F77A8F7A947A907B357B477B347B257B30
7B227B247B337B187B2A7B1D7B317B2B7B2D7B2F7B327B387B1A7B237C947C98
7C967CA37D357D3D7D387D367D3A7D457D2C7D297D417D477D3E7D3F7D4A7D3B
7D287F637F957F9C7F9D7F9B7FCA7FCB7FCD7FD07FD17FC77FCF7FC9801F0000
D7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
801E801B804780438048811881258119811B812D811F812C811E812181158127
811D8122821182388233823A823482328274839083A383A8838D837A837383A4
8374838F8381839583998375839483A9837D8383838C839D839B83AA838B837E
83A583AF8388839783B0837F83A6838783AE8376839A8659865686BF86B70000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000086C286C186C586BA86B086C886B986B386B886CC86B486BB86BC86C386BD
86BE88528889889588A888A288AA889A889188A1889F889888A78899889B8897
88A488AC888C8893888E898289D689D989D58A308A278A2C8A1E8C398C3B8C5C
8C5D8C7D8CA58D7D8D7B8D798DBC8DC28DB98DBF8DC18ED88EDE8EDD8EDC8ED7
8EE08EE19024900B9011901C900C902190EF90EA90F090F490F290F390D490EB
90EC90E991569158915A9153915591EC91F491F191F391F891E491F991EA0000
D8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
91EB91F791E891EE957A95869588967C966D966B9671966F96BF976A980498E5
9997509B50955094509E508B50A35083508C508E509D5068509C509250825087
515F51D45312531153A453A7559155A855A555AD5577564555A255935588558F
55B5558155A3559255A4557D558C55A6557F559555A1558E570C582958370000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005819581E58275823582857F558485825581C581B5833583F5836582E5839
5838582D582C583B59615AAF5A945A9F5A7A5AA25A9E5A785AA65A7C5AA55AAC
5A955AAE5A375A845A8A5A975A835A8B5AA95A7B5A7D5A8C5A9C5A8F5A935A9D
5BEA5BCD5BCB5BD45BD15BCA5BCE5C0C5C305D375D435D6B5D415D4B5D3F5D35
5D515D4E5D555D335D3A5D525D3D5D315D595D425D395D495D385D3C5D325D36
5D405D455E445E415F585FA65FA55FAB60C960B960CC60E260CE60C461140000
D9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
60F2610A6116610560F5611360F860FC60FE60C161036118611D611060FF6104
610B624A639463B163B063CE63E563E863EF63C3649D63F363CA63E063F663D5
63F263F5646163DF63BE63DD63DC63C463D863D363C263C763CC63CB63C863F0
63D763D965326567656A6564655C65686565658C659D659E65AE65D065D20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000667C666C667B668066716679666A66726701690C68D3690468DC692A68EC
68EA68F1690F68D668F768EB68E468F66913691068F368E1690768CC69086970
68B4691168EF68C6691468F868D068FD68FC68E8690B690A691768CE68C868DD
68DE68E668F468D1690668D468E96915692568C76B396B3B6B3F6B3C6B946B97
6B996B956BBD6BF06BF26BF36C306DFC6E466E476E1F6E496E886E3C6E3D6E45
6E626E2B6E3F6E416E5D6E736E1C6E336E4B6E406E516E3B6E036E2E6E5E0000
DA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6E686E5C6E616E316E286E606E716E6B6E396E226E306E536E656E276E786E64
6E776E556E796E526E666E356E366E5A7120711E712F70FB712E713171237125
71227132711F7128713A711B724B725A7288728972867285728B7312730B7330
73227331733373277332732D732673237335730C742E742C7430742B74160000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000741A7421742D743174247423741D74297420743274FB752F756F756C75E7
75DA75E175E675DD75DF75E475D77695769276DA774677477744774D7745774A
774E774B774C77DE77EC786078647865785C786D7871786A786E787078697868
785E786279747973797279707A027A0A7A037A0C7A047A997AE67AE47B4A7B3B
7B447B487B4C7B4E7B407B587B457CA27C9E7CA87CA17D587D6F7D637D537D56
7D677D6A7D4F7D6D7D5C7D6B7D527D547D697D517D5F7D4E7F3E7F3F7F650000
DB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7F667FA27FA07FA17FD78051804F805080FE80D48143814A8152814F8147813D
814D813A81E681EE81F781F881F98204823C823D823F8275833B83CF83F98423
83C083E8841283E783E483FC83F6841083C683C883EB83E383BF840183DD83E5
83D883FF83E183CB83CE83D683F583C98409840F83DE8411840683C283F30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000083D583FA83C783D183EA841383C383EC83EE83C483FB83D783E2841B83DB
83FE86D886E286E686D386E386DA86EA86DD86EB86DC86EC86E986D786E886D1
88488856885588BA88D788B988B888C088BE88B688BC88B788BD88B2890188C9
89958998899789DD89DA89DB8A4E8A4D8A398A598A408A578A588A448A458A52
8A488A518A4A8A4C8A4F8C5F8C818C808CBA8CBE8CB08CB98CB58D848D808D89
8DD88DD38DCD8DC78DD68DDC8DCF8DD58DD98DC88DD78DC58EEF8EF78EFA0000
DC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8EF98EE68EEE8EE58EF58EE78EE88EF68EEB8EF18EEC8EF48EE9902D9034902F
9106912C910490FF90FC910890F990FB9101910091079105910391619164915F
916291609201920A92259203921A9226920F920C9200921291FF91FD92069204
92279202921C92249219921792059216957B958D958C95909687967E96880000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000096899683968096C296C896C396F196F0976C9770976E980798A998EB9CE6
9EF94E834E844EB650BD50BF50C650AE50C450CA50B450C850C250B050C150BA
50B150CB50C950B650B851D7527A5278527B527C55C355DB55CC55D055CB55CA
55DD55C055D455C455E955BF55D2558D55CF55D555E255D655C855F255CD55D9
55C25714585358685864584F584D5849586F5855584E585D58595865585B583D
5863587158FC5AC75AC45ACB5ABA5AB85AB15AB55AB05ABF5AC85ABB5AC60000
DD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5AB75AC05ACA5AB45AB65ACD5AB95A905BD65BD85BD95C1F5C335D715D635D4A
5D655D725D6C5D5E5D685D675D625DF05E4F5E4E5E4A5E4D5E4B5EC55ECC5EC6
5ECB5EC75F405FAF5FAD60F76149614A612B614561366132612E6146612F614F
612961406220916862236225622463C563F163EB641064126409642064240000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000064336443641F641564186439643764226423640C64266430642864416435
642F640A641A644064256427640B63E7641B642E6421640E656F659265D36686
668C66956690668B668A66996694667867206966695F6938694E69626971693F
6945696A6939694269576959697A694869496935696C6933693D696568F06978
693469696940696F69446976695869416974694C693B694B6937695C694F6951
69326952692F697B693C6B466B456B436B426B486B416B9BFA0D6BFB6BFC0000
DE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6BF96BF76BF86E9B6ED66EC86E8F6EC06E9F6E936E946EA06EB16EB96EC66ED2
6EBD6EC16E9E6EC96EB76EB06ECD6EA66ECF6EB26EBE6EC36EDC6ED86E996E92
6E8E6E8D6EA46EA16EBF6EB36ED06ECA6E976EAE6EA371477154715271637160
7141715D716271727178716A7161714271587143714B7170715F715071530000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007144714D715A724F728D728C72917290728E733C7342733B733A7340734A
73497444744A744B7452745174577440744F7450744E74427446744D745474E1
74FF74FE74FD751D75797577698375EF760F760375F775FE75FC75F975F87610
75FB75F675ED75F575FD769976B576DD7755775F776077527756775A77697767
77547759776D77E07887789A7894788F788478957885788678A1788378797899
78807896787B797C7982797D79797A117A187A197A127A177A157A227A130000
DF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7A1B7A107AA37AA27A9E7AEB7B667B647B6D7B747B697B727B657B737B717B70
7B617B787B767B637CB27CB47CAF7D887D867D807D8D7D7F7D857D7A7D8E7D7B
7D837D7C7D8C7D947D847D7D7D927F6D7F6B7F677F687F6C7FA67FA57FA77FDB
7FDC8021816481608177815C8169815B816281726721815E81768167816F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000081448161821D8249824482408242824584F1843F845684768479848F848D
846584518440848684678430844D847D845A845984748473845D8507845E8437
843A8434847A8443847884328445842983D9844B842F8442842D845F84708439
844E844C8452846F84C5848E843B8447843684338468847E8444842B84608454
846E8450870B870486F7870C86FA86D686F5874D86F8870E8709870186F6870D
870588D688CB88CD88CE88DE88DB88DA88CC88D08985899B89DF89E589E40000
E0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
89E189E089E289DC89E68A768A868A7F8A618A3F8A778A828A848A758A838A81
8A748A7A8C3C8C4B8C4A8C658C648C668C868C848C858CCC8D688D698D918D8C
8D8E8D8F8D8D8D938D948D908D928DF08DE08DEC8DF18DEE8DD08DE98DE38DE2
8DE78DF28DEB8DF48F068EFF8F018F008F058F078F088F028F0B9052903F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000090449049903D9110910D910F911191169114910B910E916E916F92489252
9230923A926692339265925E9283922E924A9246926D926C924F92609267926F
92369261927092319254926392509272924E9253924C92569232959F959C959E
959B969296939691969796CE96FA96FD96F896F59773977797789772980F980D
980E98AC98F698F999AF99B299B099B59AAD9AAB9B5B9CEA9CED9CE79E809EFD
50E650D450D750E850F350DB50EA50DD50E450D350EC50F050EF50E350E00000
E1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
51D85280528152E952EB533053AC56275615560C561255FC560F561C56015613
560255FA561D560455FF55F95889587C5890589858865881587F5874588B587A
58875891588E587658825888587B5894588F58FE596B5ADC5AEE5AE55AD55AEA
5ADA5AED5AEB5AF35AE25AE05ADB5AEC5ADE5ADD5AD95AE85ADF5B775BE00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005BE35C635D825D805D7D5D865D7A5D815D775D8A5D895D885D7E5D7C5D8D
5D795D7F5E585E595E535ED85ED15ED75ECE5EDC5ED55ED95ED25ED45F445F43
5F6F5FB6612C61286141615E61716173615261536172616C618061746154617A
615B6165613B616A6161615662296227622B642B644D645B645D647464766472
6473647D6475646664A6644E6482645E645C644B645364606450647F643F646C
646B645964656477657365A066A166A0669F67056704672269B169B669C90000
E2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
69A069CE699669B069AC69BC69916999698E69A7698D69A969BE69AF69BF69C4
69BD69A469D469B969CA699A69CF69B3699369AA69A1699E69D96997699069C2
69B569A569C66B4A6B4D6B4B6B9E6B9F6BA06BC36BC46BFE6ECE6EF56EF16F03
6F256EF86F376EFB6F2E6F096F4E6F196F1A6F276F186F3B6F126EED6F0A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006F366F736EF96EEE6F2D6F406F306F3C6F356EEB6F076F0E6F436F056EFD
6EF66F396F1C6EFC6F3A6F1F6F0D6F1E6F086F21718771907189718071857182
718F717B718671817197724472537297729572937343734D7351734C74627473
7471747574727467746E750075027503757D759076167608760C76157611760A
761476B87781777C77857782776E7780776F777E778378B278AA78B478AD78A8
787E78AB789E78A578A078AC78A278A47998798A798B79967995799479930000
E3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
79977988799279907A2B7A4A7A307A2F7A287A267AA87AAB7AAC7AEE7B887B9C
7B8A7B917B907B967B8D7B8C7B9B7B8E7B857B9852847B997BA47B827CBB7CBF
7CBC7CBA7DA77DB77DC27DA37DAA7DC17DC07DC57D9D7DCE7DC47DC67DCB7DCC
7DAF7DB97D967DBC7D9F7DA67DAE7DA97DA17DC97F737FE27FE37FE57FDE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008024805D805C8189818681838187818D818C818B8215849784A484A1849F
84BA84CE84C284AC84AE84AB84B984B484C184CD84AA849A84B184D0849D84A7
84BB84A2849484C784CC849B84A984AF84A884D6849884B684CF84A084D784D4
84D284DB84B084918661873387238728876B8740872E871E87218719871B8743
872C8741873E874687208732872A872D873C8712873A87318735874287268727
87388724871A8730871188F788E788F188F288FA88FE88EE88FC88F688FB0000
E4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
88F088EC88EB899D89A1899F899E89E989EB89E88AAB8A998A8B8A928A8F8A96
8C3D8C688C698CD58CCF8CD78D968E098E028DFF8E0D8DFD8E0A8E038E078E06
8E058DFE8E008E048F108F118F0E8F0D9123911C91209122911F911D911A9124
9121911B917A91729179917392A592A49276929B927A92A0929492AA928D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000092A6929A92AB92799297927F92A392EE928E9282929592A2927D928892A1
928A9286928C929992A7927E928792A9929D928B922D969E96A196FF9758977D
977A977E978397809782977B97849781977F97CE97CD981698AD98AE99029900
9907999D999C99C399B999BB99BA99C299BD99C79AB19AE39AE79B3E9B3F9B60
9B619B5F9CF19CF29CF59EA750FF5103513050F85106510750F650FE510B510C
50FD510A528B528C52F152EF56485642564C56355641564A5649564656580000
E5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
565A56405633563D562C563E5638562A563A571A58AB589D58B158A058A358AF
58AC58A558A158FF5AFF5AF45AFD5AF75AF65B035AF85B025AF95B015B075B05
5B0F5C675D995D975D9F5D925DA25D935D955DA05D9C5DA15D9A5D9E5E695E5D
5E605E5C7DF35EDB5EDE5EE15F495FB2618B6183617961B161B061A261890000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000619B619361AF61AD619F619261AA61A1618D616661B3622D646E64706496
64A064856497649C648F648B648A648C64A3649F646864B164986576657A6579
657B65B265B366B566B066A966B266B766AA66AF6A006A066A1769E569F86A15
69F169E46A2069FF69EC69E26A1B6A1D69FE6A2769F269EE6A1469F769E76A40
6A0869E669FB6A0D69FC69EB6A096A046A186A256A0F69F66A266A0769F46A16
6B516BA56BA36BA26BA66C016C006BFF6C026F416F266F7E6F876FC66F920000
E6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6F8D6F896F8C6F626F4F6F856F5A6F966F766F6C6F826F556F726F526F506F57
6F946F936F5D6F006F616F6B6F7D6F676F906F536F8B6F696F7F6F956F636F77
6F6A6F7B71B271AF719B71B071A0719A71A971B5719D71A5719E71A471A171AA
719C71A771B37298729A73587352735E735F7360735D735B7361735A73590000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000736274877489748A74867481747D74857488747C747975087507757E7625
761E7619761D761C7623761A7628761B769C769D769E769B778D778F77897788
78CD78BB78CF78CC78D178CE78D478C878C378C478C9799A79A179A0799C79A2
799B6B767A397AB27AB47AB37BB77BCB7BBE7BAC7BCE7BAF7BB97BCA7BB57CC5
7CC87CCC7CCB7DF77DDB7DEA7DE77DD77DE17E037DFA7DE67DF67DF17DF07DEE
7DDF7F767FAC7FB07FAD7FED7FEB7FEA7FEC7FE67FE88064806781A3819F0000
E7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
819E819581A2819981978216824F825382528250824E82518524853B850F8500
8529850E8509850D851F850A8527851C84FB852B84FA8508850C84F4852A84F2
851584F784EB84F384FC851284EA84E9851684FE8528851D852E850284FD851E
84F68531852684E784E884F084EF84F9851885208530850B8519852F86620000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000875687638764877787E1877387588754875B87528761875A8751875E876D
876A8750874E875F875D876F876C877A876E875C8765874F877B877587628767
8769885A8905890C8914890B891789188919890689168911890E890989A289A4
89A389ED89F089EC8ACF8AC68AB88AD38AD18AD48AD58ABB8AD78ABE8AC08AC5
8AD88AC38ABA8ABD8AD98C3E8C4D8C8F8CE58CDF8CD98CE88CDA8CDD8CE78DA0
8D9C8DA18D9B8E208E238E258E248E2E8E158E1B8E168E118E198E268E270000
E8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8E148E128E188E138E1C8E178E1A8F2C8F248F188F1A8F208F238F168F179073
9070906F9067906B912F912B9129912A91329126912E91859186918A91819182
9184918092D092C392C492C092D992B692CF92F192DF92D892E992D792DD92CC
92EF92C292E892CA92C892CE92E692CD92D592C992E092DE92E792D192D30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000092B592E192C692B4957C95AC95AB95AE95B096A496A296D3970597089702
975A978A978E978897D097CF981E981D9826982998289820981B982798B29908
98FA9911991499169917991599DC99CD99CF99D399D499CE99C999D699D899CB
99D799CC9AB39AEC9AEB9AF39AF29AF19B469B439B679B749B719B669B769B75
9B709B689B649B6C9CFC9CFA9CFD9CFF9CF79D079D009CF99CFB9D089D059D04
9E839ED39F0F9F10511C51135117511A511151DE533453E156705660566E0000
E9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
567356665663566D5672565E5677571C571B58C858BD58C958BF58BA58C258BC
58C65B175B195B1B5B215B145B135B105B165B285B1A5B205B1E5BEF5DAC5DB1
5DA95DA75DB55DB05DAE5DAA5DA85DB25DAD5DAF5DB45E675E685E665E6F5EE9
5EE75EE65EE85EE55F4B5FBC619D61A8619661C561B461C661C161CC61BA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000061BF61B8618C64D764D664D064CF64C964BD648964C364DB64F364D96533
657F657C65A266C866BE66C066CA66CB66CF66BD66BB66BA66CC67236A346A66
6A496A676A326A686A3E6A5D6A6D6A766A5B6A516A286A5A6A3B6A3F6A416A6A
6A646A506A4F6A546A6F6A696A606A3C6A5E6A566A556A4D6A4E6A466B556B54
6B566BA76BAA6BAB6BC86BC76C046C036C066FAD6FCB6FA36FC76FBC6FCE6FC8
6F5E6FC46FBD6F9E6FCA6FA870046FA56FAE6FBA6FAC6FAA6FCF6FBF6FB80000
EA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6FA26FC96FAB6FCD6FAF6FB26FB071C571C271BF71B871D671C071C171CB71D4
71CA71C771CF71BD71D871BC71C671DA71DB729D729E736973667367736C7365
736B736A747F749A74A074947492749574A1750B7580762F762D7631763D7633
763C76357632763076BB76E6779A779D77A1779C779B77A277A3779577990000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000779778DD78E978E578EA78DE78E378DB78E178E278ED78DF78E079A47A44
7A487A477AB67AB87AB57AB17AB77BDE7BE37BE77BDD7BD57BE57BDA7BE87BF9
7BD47BEA7BE27BDC7BEB7BD87BDF7CD27CD47CD77CD07CD17E127E217E177E0C
7E1F7E207E137E0E7E1C7E157E1A7E227E0B7E0F7E167E0D7E147E257E247F43
7F7B7F7C7F7A7FB17FEF802A8029806C81B181A681AE81B981B581AB81B081AC
81B481B281B781A781F282558256825785568545856B854D8553856185580000
EB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
854085468564854185628544855185478563853E855B8571854E856E85758555
85678560858C8566855D85548565856C866386658664879B878F879787938792
87888781879687988779878787A3878587908791879D87848794879C879A8789
891E89268930892D892E89278931892289298923892F892C891F89F18AE00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008AE28AF28AF48AF58ADD8B148AE48ADF8AF08AC88ADE8AE18AE88AFF8AEF
8AFB8C918C928C908CF58CEE8CF18CF08CF38D6C8D6E8DA58DA78E338E3E8E38
8E408E458E368E3C8E3D8E418E308E3F8EBD8F368F2E8F358F328F398F378F34
90769079907B908690FA913391359136919391909191918D918F9327931E9308
931F9306930F937A9338933C931B9323931293019346932D930E930D92CB931D
92FA9325931392F992F793349302932492FF932993399335932A9314930C0000
EC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
930B92FE9309930092FB931695BC95CD95BE95B995BA95B695BF95B595BD96A9
96D4970B9712971097999797979497F097F89835982F98329924991F99279929
999E99EE99EC99E599E499F099E399EA99E999E79AB99ABF9AB49ABB9AF69AFA
9AF99AF79B339B809B859B879B7C9B7E9B7B9B829B939B929B909B7A9B950000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009B7D9B889D259D179D209D1E9D149D299D1D9D189D229D109D199D1F9E88
9E869E879EAE9EAD9ED59ED69EFA9F129F3D51265125512251245120512952F4
5693568C568D568656845683567E5682567F568158D658D458CF58D25B2D5B25
5B325B235B2C5B275B265B2F5B2E5B7B5BF15BF25DB75E6C5E6A5FBE5FBB61C3
61B561BC61E761E061E561E461E861DE64EF64E964E364EB64E464E865816580
65B665DA66D26A8D6A966A816AA56A896A9F6A9B6AA16A9E6A876A936A8E0000
ED
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A956A836AA86AA46A916A7F6AA66A9A6A856A8C6A926B5B6BAD6C096FCC6FA9
6FF46FD46FE36FDC6FED6FE76FE66FDE6FF26FDD6FE26FE871E171F171E871F2
71E471F071E27373736E736F749774B274AB749074AA74AD74B174A574AF7510
75117512750F7584764376487649764776A476E977B577AB77B277B777B60000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077B477B177A877F078F378FD790278FB78FC78F2790578F978FE790479AB
79A87A5C7A5B7A567A587A547A5A7ABE7AC07AC17C057C0F7BF27C007BFF7BFB
7C0E7BF47C0B7BF37C027C097C037C017BF87BFD7C067BF07BF17C107C0A7CE8
7E2D7E3C7E427E3398487E387E2A7E497E407E477E297E4C7E307E3B7E367E44
7E3A7F457F7F7F7E7F7D7FF47FF2802C81BB81C481CC81CA81C581C781BC81E9
825B825A825C85838580858F85A7859585A0858B85A3857B85A4859A859E0000
EE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8577857C858985A1857A85788557858E85968586858D8599859D858185A28582
858885858579857685988590859F866887BE87AA87AD87C587B087AC87B987B5
87BC87AE87C987C387C287CC87B787AF87C487CA87B487B687BF87B887BD87DE
87B289358933893C893E894189528937894289AD89AF89AE89F289F38B1E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008B188B168B118B058B0B8B228B0F8B128B158B078B0D8B088B068B1C8B13
8B1A8C4F8C708C728C718C6F8C958C948CF98D6F8E4E8E4D8E538E508E4C8E47
8F438F409085907E9138919A91A2919B9199919F91A1919D91A093A1938393AF
936493569347937C9358935C93769349935093519360936D938F934C936A9379
935793559352934F93719377937B9361935E936393679380934E935995C795C0
95C995C395C595B796AE96B096AC9720971F9718971D9719979A97A1979C0000
EF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
979E979D97D597D497F198419844984A9849984598439925992B992C992A9933
9932992F992D99319930999899A399A19A0299FA99F499F799F999F899F699FB
99FD99FE99FC9A039ABE9AFE9AFD9B019AFC9B489B9A9BA89B9E9B9B9BA69BA1
9BA59BA49B869BA29BA09BAF9D339D419D679D369D2E9D2F9D319D389D300000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009D459D429D439D3E9D379D409D3D7FF59D2D9E8A9E899E8D9EB09EC89EDA
9EFB9EFF9F249F239F229F549FA05131512D512E5698569C5697569A569D5699
59705B3C5C695C6A5DC05E6D5E6E61D861DF61ED61EE61F161EA61F061EB61D6
61E964FF650464FD64F86501650364FC659465DB66DA66DB66D86AC56AB96ABD
6AE16AC66ABA6AB66AB76AC76AB46AAD6B5E6BC96C0B7007700C700D70017005
7014700E6FFF70006FFB70266FFC6FF7700A720171FF71F9720371FD73760000
F0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
74B874C074B574C174BE74B674BB74C275147513765C76647659765076537657
765A76A676BD76EC77C277BA78FF790C79137914790979107912791179AD79AC
7A5F7C1C7C297C197C207C1F7C2D7C1D7C267C287C227C257C307E5C7E507E56
7E637E587E627E5F7E517E607E577E537FB57FB37FF77FF8807581D181D20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000081D0825F825E85B485C685C085C385C285B385B585BD85C785C485BF85CB
85CE85C885C585B185B685D2862485B885B785BE866987E787E687E287DB87EB
87EA87E587DF87F387E487D487DC87D387ED87D887E387A487D787D9880187F4
87E887DD8953894B894F894C89468950895189498B2A8B278B238B338B308B35
8B478B2F8B3C8B3E8B318B258B378B268B368B2E8B248B3B8B3D8B3A8C428C75
8C998C988C978CFE8D048D028D008E5C8E628E608E578E568E5E8E658E670000
F1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8E5B8E5A8E618E5D8E698E548F468F478F488F4B9128913A913B913E91A891A5
91A791AF91AA93B5938C939293B7939B939D938993A7938E93AA939E93A69395
93889399939F938D93B1939193B293A493A893B493A393A595D295D395D196B3
96D796DA5DC296DF96D896DD97239722972597AC97AE97A897AB97A497AA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000097A297A597D797D997D697D897FA98509851985298B89941993C993A9A0F
9A0B9A099A0D9A049A119A0A9A059A079A069AC09ADC9B089B049B059B299B35
9B4A9B4C9B4B9BC79BC69BC39BBF9BC19BB59BB89BD39BB69BC49BB99BBD9D5C
9D539D4F9D4A9D5B9D4B9D599D569D4C9D579D529D549D5F9D589D5A9E8E9E8C
9EDF9F019F009F169F259F2B9F2A9F299F289F4C9F5551345135529652F753B4
56AB56AD56A656A756AA56AC58DA58DD58DB59125B3D5B3E5B3F5DC35E700000
F2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5FBF61FB65076510650D6509650C650E658465DE65DD66DE6AE76AE06ACC6AD1
6AD96ACB6ADF6ADC6AD06AEB6ACF6ACD6ADE6B606BB06C0C7019702770207016
702B702170227023702970177024701C702A720C720A72077202720572A572A6
72A472A372A174CB74C574B774C37516766077C977CA77C477F1791D791B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007921791C7917791E79B07A677A687C337C3C7C397C2C7C3B7CEC7CEA7E76
7E757E787E707E777E6F7E7A7E727E747E687F4B7F4A7F837F867FB77FFD7FFE
807881D781D582648261826385EB85F185ED85D985E185E885DA85D785EC85F2
85F885D885DF85E385DC85D185F085E685EF85DE85E2880087FA880387F687F7
8809880C880B880687FC880887FF880A88028962895A895B89578961895C8958
895D8959898889B789B689F68B508B488B4A8B408B538B568B548B4B8B550000
F3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8B518B428B528B578C438C778C768C9A8D068D078D098DAC8DAA8DAD8DAB8E6D
8E788E738E6A8E6F8E7B8EC28F528F518F4F8F508F538FB49140913F91B091AD
93DE93C793CF93C293DA93D093F993EC93CC93D993A993E693CA93D493EE93E3
93D593C493CE93C093D293E7957D95DA95DB96E19729972B972C972897260000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000097B397B797B697DD97DE97DF985C9859985D985798BF98BD98BB98BE9948
9947994399A699A79A1A9A159A259A1D9A249A1B9A229A209A279A239A1E9A1C
9A149AC29B0B9B0A9B0E9B0C9B379BEA9BEB9BE09BDE9BE49BE69BE29BF09BD4
9BD79BEC9BDC9BD99BE59BD59BE19BDA9D779D819D8A9D849D889D719D809D78
9D869D8B9D8C9D7D9D6B9D749D759D709D699D859D739D7B9D829D6F9D799D7F
9D879D689E949E919EC09EFC9F2D9F409F419F4D9F569F579F58533756B20000
F4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
56B556B358E35B455DC65DC75EEE5EEF5FC05FC161F9651765166515651365DF
66E866E366E46AF36AF06AEA6AE86AF96AF16AEE6AEF703C7035702F70377034
703170427038703F703A70397040703B703370417213721472A8737D737C74BA
76AB76AA76BE76ED77CC77CE77CF77CD77F27925792379277928792479290000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000079B27A6E7A6C7A6D7AF77C497C487C4A7C477C457CEE7E7B7E7E7E817E80
7FBA7FFF807981DB81D9820B82688269862285FF860185FE861B860085F68604
86098605860C85FD8819881088118817881388168963896689B989F78B608B6A
8B5D8B688B638B658B678B6D8DAE8E868E888E848F598F568F578F558F588F5A
908D9143914191B791B591B291B3940B941393FB9420940F941493FE94159410
94289419940D93F5940093F79407940E9416941293FA940993F8940A93FF0000
F5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
93FC940C93F69411940695DE95E095DF972E972F97B997BB97FD97FE98609862
9863985F98C198C29950994E9959994C994B99539A329A349A319A2C9A2A9A36
9A299A2E9A389A2D9AC79ACA9AC69B109B129B119C0B9C089BF79C059C129BF8
9C409C079C0E9C069C179C149C099D9F9D999DA49D9D9D929D989D909D9B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009DA09D949D9C9DAA9D979DA19D9A9DA29DA89D9E9DA39DBF9DA99D969DA6
9DA79E999E9B9E9A9EE59EE49EE79EE69F309F2E9F5B9F609F5E9F5D9F599F91
513A51395298529756C356BD56BE5B485B475DCB5DCF5EF161FD651B6B026AFC
6B036AF86B0070437044704A7048704970457046721D721A7219737E7517766A
77D0792D7931792F7C547C537CF27E8A7E877E887E8B7E867E8D7F4D7FBB8030
81DD8618862A8626861F8623861C86198627862E862186208629861E86250000
F6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8829881D881B88208824881C882B884A896D8969896E896B89FA8B798B788B45
8B7A8B7B8D108D148DAF8E8E8E8C8F5E8F5B8F5D91469144914591B9943F943B
94369429943D943C94309439942A9437942C9440943195E595E495E39735973A
97BF97E1986498C998C698C0995899569A399A3D9A469A449A429A419A3A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009A3F9ACD9B159B179B189B169B3A9B529C2B9C1D9C1C9C2C9C239C289C29
9C249C219DB79DB69DBC9DC19DC79DCA9DCF9DBE9DC59DC39DBB9DB59DCE9DB9
9DBA9DAC9DC89DB19DAD9DCC9DB39DCD9DB29E7A9E9C9EEB9EEE9EED9F1B9F18
9F1A9F319F4E9F659F649F924EB956C656C556CB59715B4B5B4C5DD55DD15EF2
65216520652665226B0B6B086B096C0D7055705670577052721E721F72A9737F
74D874D574D974D7766D76AD793579B47A707A717C577C5C7C597C5B7C5A0000
F7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7CF47CF17E917F4F7F8781DE826B863486358633862C86328636882C88288826
882A8825897189BF89BE89FB8B7E8B848B828B868B858B7F8D158E958E948E9A
8E928E908E968E978F608F629147944C9450944A944B944F9447944594489449
9446973F97E3986A986998CB9954995B9A4E9A539A549A4C9A4F9A489A4A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009A499A529A509AD09B199B2B9B3B9B569B559C469C489C3F9C449C399C33
9C419C3C9C379C349C329C3D9C369DDB9DD29DDE9DDA9DCB9DD09DDC9DD19DDF
9DE99DD99DD89DD69DF59DD59DDD9EB69EF09F359F339F329F429F6B9F959FA2
513D529958E858E759725B4D5DD8882F5F4F62016203620465296525659666EB
6B116B126B0F6BCA705B705A7222738273817383767077D47C677C667E95826C
863A86408639863C8631863B863E88308832882E883389768974897389FE0000
F8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8B8C8B8E8B8B8B888C458D198E988F648F6391BC94629455945D9457945E97C4
97C598009A569A599B1E9B1F9B209C529C589C509C4A9C4D9C4B9C559C599C4C
9C4E9DFB9DF79DEF9DE39DEB9DF89DE49DF69DE19DEE9DE69DF29DF09DE29DEC
9DF49DF39DE89DED9EC29ED09EF29EF39F069F1C9F389F379F369F439F4F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009F719F709F6E9F6F56D356CD5B4E5C6D652D66ED66EE6B13705F7061705D
7060722374DB74E577D5793879B779B67C6A7E977F89826D8643883888378835
884B8B948B958E9E8E9F8EA08E9D91BE91BD91C2946B9468946996E597469743
974797C797E59A5E9AD59B599C639C679C669C629C5E9C609E029DFE9E079E03
9E069E059E009E019E099DFF9DFD9E049EA09F1E9F469F749F759F7656D4652E
65B86B186B196B176B1A7062722672AA77D877D979397C697C6B7CF67E9A0000
F9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7E987E9B7E9981E081E18646864786488979897A897C897B89FF8B988B998EA5
8EA48EA3946E946D946F9471947397499872995F9C689C6E9C6D9E0B9E0D9E10
9E0F9E129E119EA19EF59F099F479F789F7B9F7A9F79571E70667C6F883C8DB2
8EA691C394749478947694759A609C749C739C719C759E149E139EF69F0A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009FA4706870657CF7866A883E883D883F8B9E8C9C8EA98EC9974B98739874
98CC996199AB9A649A669A679B249E159E179F4862076B1E7227864C8EA89482
948094819A699A689B2E9E197229864B8B9F94839C799EB776759A6B9C7A9E1D
7069706A9EA49F7E9F499F980000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/cp1250.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1250, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0083201E2026202020210088203001602039015A0164017D0179
009020182019201C201D202220132014009821220161203A015B0165017E017A
00A002C702D8014100A4010400A600A700A800A9015E00AB000000AD00AE017B
00B000B102DB014200B400B500B600B700B80105015F00BB013D02DD013E017C
015400C100C2010200C40139010600C7010C00C9011800CB011A00CD00CE010E
01100143014700D300D4015000D600D70158016E00DA017000DC00DD016200DF
015500E100E2010300E4013A010700E7010D00E9011900EB011B00ED00EE010F
01110144014800F300F4015100F600F70159016F00FA017100FC00FD016302D9

Added library/encoding/cp1251.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1251, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
04020403201A0453201E2026202020210088203004092039040A040C040B040F
045220182019201C201D202220132014009821220459203A045A045C045B045F
00A0040E045E040800A4049000A600A7040100A9040400AB00AC00AD00AE0407
00B000B104060456049100B500B600B704512116045400BB0458040504550457
0410041104120413041404150416041704180419041A041B041C041D041E041F
0420042104220423042404250426042704280429042A042B042C042D042E042F
0430043104320433043404350436043704380439043A043B043C043D043E043F
0440044104420443044404450446044704480449044A044B044C044D044E044F

Added library/encoding/cp1252.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1252, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0192201E20262020202102C62030016020390152008D008E008F
009020182019201C201D20222013201402DC21220161203A0153009D009E0178
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
00D000D100D200D300D400D500D600D700D800D900DA00DB00DC00DD00DE00DF
00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
00F000F100F200F300F400F500F600F700F800F900FA00FB00FC00FD00FE00FF

Added library/encoding/cp1253.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1253, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0192201E20262020202100882030008A2039008C008D008E008F
009020182019201C201D20222013201400982122009A203A009C009D009E009F
00A00385038600A300A400A500A600A700A800A9000000AB00AC00AD00AE2015
00B000B100B200B3038400B500B600B703880389038A00BB038C00BD038E038F
0390039103920393039403950396039703980399039A039B039C039D039E039F
03A003A1000003A303A403A503A603A703A803A903AA03AB03AC03AD03AE03AF
03B003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C203C303C403C503C603C703C803C903CA03CB03CC03CD03CE0000

Added library/encoding/cp1254.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1254, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0192201E20262020202102C62030016020390152008D008E008F
009020182019201C201D20222013201402DC21220161203A0153009D009E0178
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
011E00D100D200D300D400D500D600D700D800D900DA00DB00DC0130015E00DF
00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
011F00F100F200F300F400F500F600F700F800F900FA00FB00FC0131015F00FF

Added library/encoding/cp1255.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1255, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0192201E20262020202102C62030008A2039008C008D008E008F
009020182019201C201D20222013201402DC2122009A203A009C009D009E009F
00A0000000A200A320AA00A500A600A700A800A9000000AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B7000000B9000000BB00BC00BD00BE0000
05B005B105B205B305B405B505B605B705B805B905BA05BB05BC05BD05BE05BF
05C005C105C205C305F005F105F2000000000000000000000000000000000000
05D005D105D205D305D405D505D605D705D805D905DA05DB05DC05DD05DE05DF
05E005E105E205E305E405E505E605E705E805E905EA00000000200E200F0000

Added library/encoding/cp1256.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1256, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080067E201A0192201E20262020202102C62030008A2039015206860698008F
06AF20182019201C201D20222013201400982122009A203A0153200C200D009F
00A0060C00A200A300A400A500A600A700A800A9000000AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B9061B00BB00BC00BD00BE061F
0000062106220623062406250626062706280629062A062B062C062D062E062F
063006310632063306340635063600D7063706380639063A0640064106420643
00E0064400E2064506460647064800E700E800E900EA00EB0649064A00EE00EF
064B064C064D064E00F4064F065000F7065100F9065200FB00FC200E200F0000

Added library/encoding/cp1257.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1257, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0083201E20262020202100882030008A2039008C00A802C700B8
009020182019201C201D20222013201400982122009A203A009C00AF02DB009F
00A0000000A200A300A4000000A600A700D800A9015600AB00AC00AD00AE00C6
00B000B100B200B300B400B500B600B700F800B9015700BB00BC00BD00BE00E6
0104012E0100010600C400C501180112010C00C90179011601220136012A013B
01600143014500D3014C00D500D600D701720141015A016A00DC017B017D00DF
0105012F0101010700E400E501190113010D00E9017A011701230137012B013C
01610144014600F3014D00F500F600F701730142015B016B00FC017C017E02D9

Added library/encoding/cp1258.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1258, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0192201E20262020202102C62030008A20390152008D008E008F
009020182019201C201D20222013201402DC2122009A203A0153009D009E0178
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C2010200C400C500C600C700C800C900CA00CB034000CD00CE00CF
011000D1030900D300D401A000D600D700D800D900DA00DB00DC01AF030300DF
00E000E100E2010300E400E500E600E700E800E900EA00EB034100ED00EE00EF
011100F1032300F300F401A100F600F700F800F900FA00FB00FC01B020AB00FF

Added library/encoding/cp437.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp437, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
00C900E600C600F400F600F200FB00F900FF00D600DC00A200A300A520A70192
00E100ED00F300FA00F100D100AA00BA00BF231000AC00BD00BC00A100AB00BB
259125922593250225242561256225562555256325512557255D255C255B2510
25142534252C251C2500253C255E255F255A25542569256625602550256C2567
2568256425652559255825522553256B256A2518250C25882584258C25902580
03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0

Added library/encoding/cp737.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp737, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
039103920393039403950396039703980399039A039B039C039D039E039F03A0
03A103A303A403A503A603A703A803A903B103B203B303B403B503B603B703B8
03B903BA03BB03BC03BD03BE03BF03C003C103C303C203C403C503C603C703C8
259125922593250225242561256225562555256325512557255D255C255B2510
25142534252C251C2500253C255E255F255A25542569256625602550256C2567
2568256425652559255825522553256B256A2518250C25882584258C25902580
03C903AC03AD03AE03CA03AF03CC03CD03CB03CE038603880389038A038C038E
038F00B12265226403AA03AB00F7224800B0221900B7221A207F00B225A000A0

Added library/encoding/cp775.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp775, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
010600FC00E9010100E4012300E501070142011301560157012B017900C400C5
00C900E600C6014D00F6012200A2015A015B00D600DC00F800A300D800D700A4
0100012A00F3017B017C017A201D00A600A900AE00AC00BD00BC014100AB00BB
259125922593250225240104010C01180116256325512557255D012E01602510
25142534252C251C2500253C0172016A255A25542569256625602550256C017D
0105010D01190117012F01610173016B017E2518250C25882584258C25902580
00D300DF014C014300F500D500B5014401360137013B013C0146011201452019
00AD00B1201C00BE00B600A700F7201E00B0221900B700B900B300B225A000A0

Added library/encoding/cp850.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp850, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
00C900E600C600F400F600F200FB00F900FF00D600DC00F800A300D800D70192
00E100ED00F300FA00F100D100AA00BA00BF00AE00AC00BD00BC00A100AB00BB
2591259225932502252400C100C200C000A9256325512557255D00A200A52510
25142534252C251C2500253C00E300C3255A25542569256625602550256C00A4
00F000D000CA00CB00C8013100CD00CE00CF2518250C2588258400A600CC2580
00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4
00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0

Added library/encoding/cp852.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp852, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C700FC00E900E200E4016F010700E7014200EB0150015100EE017900C40106
00C90139013A00F400F6013D013E015A015B00D600DC01640165014100D7010D
00E100ED00F300FA01040105017D017E0118011900AC017A010C015F00AB00BB
2591259225932502252400C100C2011A015E256325512557255D017B017C2510
25142534252C251C2500253C01020103255A25542569256625602550256C00A4
01110110010E00CB010F014700CD00CE011B2518250C258825840162016E2580
00D300DF00D401430144014801600161015400DA0155017000FD00DD016300B4
00AD02DD02DB02C702D800A700F700B800B000A802D901710158015925A000A0

Added library/encoding/cp855.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp855, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0452040204530403045104010454040404550405045604060457040704580408
04590409045A040A045B040B045C040C045E040E045F040F044E042E044A042A
0430041004310411044604260434041404350415044404240433041300AB00BB
259125922593250225240445042504380418256325512557255D043904192510
25142534252C251C2500253C043A041A255A25542569256625602550256C00A4
043B041B043C041C043D041D043E041E043F2518250C25882584041F044F2580
042F044004200441042104420422044304230436041604320412044C042C2116
00AD044B042B0437041704480428044D042D044904290447042700A725A000A0

Added library/encoding/cp857.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp857, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE013100C400C5
00C900E600C600F400F600F200FB00F9013000D600DC00F800A300D8015E015F
00E100ED00F300FA00F100D1011E011F00BF00AE00AC00BD00BC00A100AB00BB
2591259225932502252400C100C200C000A9256325512557255D00A200A52510
25142534252C251C2500253C00E300C3255A25542569256625602550256C00A4
00BA00AA00CA00CB00C8000000CD00CE00CF2518250C2588258400A600CC2580
00D300DF00D400D200F500D500B5000000D700DA00DB00D900EC00FF00AF00B4
00AD00B1000000BE00B600A700F700B800B000A800B700B900B300B225A000A0

Added library/encoding/cp860.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp860, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C700FC00E900E200E300E000C100E700EA00CA00E800CD00D400EC00C300C2
00C900C000C800F400F500F200DA00F900CC00D500DC00A200A300D920A700D3
00E100ED00F300FA00F100D100AA00BA00BF00D200AC00BD00BC00A100AB00BB
259125922593250225242561256225562555256325512557255D255C255B2510
25142534252C251C2500253C255E255F255A25542569256625602550256C2567
2568256425652559255825522553256B256A2518250C25882584258C25902580
03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0

Added library/encoding/cp861.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp861, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C700FC00E900E200E400E000E500E700EA00EB00E800D000F000DE00C400C5
00C900E600C600F400F600FE00FB00DD00FD00D600DC00F800A300D820A70192
00E100ED00F300FA00C100CD00D300DA00BF231000AC00BD00BC00A100AB00BB
259125922593250225242561256225562555256325512557255D255C255B2510
25142534252C251C2500253C255E255F255A25542569256625602550256C2567
2568256425652559255825522553256B256A2518250C25882584258C25902580
03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0

Added library/encoding/cp862.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp862, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
05D005D105D205D305D405D505D605D705D805D905DA05DB05DC05DD05DE05DF
05E005E105E205E305E405E505E605E705E805E905EA00A200A300A520A70192
00E100ED00F300FA00F100D100AA00BA00BF231000AC00BD00BC00A100AB00BB
259125922593250225242561256225562555256325512557255D255C255B2510
25142534252C251C2500253C255E255F255A25542569256625602550256C2567
2568256425652559255825522553256B256A2518250C25882584258C25902580
03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0

Added library/encoding/cp863.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp863, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C700FC00E900E200C200E000B600E700EA00EB00E800EF00EE201700C000A7
00C900C800CA00F400CB00CF00FB00F900A400D400DC00A200A300D900DB0192
00A600B400F300FA00A800B800B300AF00CE231000AC00BD00BC00BE00AB00BB
259125922593250225242561256225562555256325512557255D255C255B2510
25142534252C251C2500253C255E255F255A25542569256625602550256C2567
2568256425652559255825522553256B256A2518250C25882584258C25902580
03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0

Added library/encoding/cp864.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp864, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
00200021002200230024066A0026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00B000B72219221A259225002502253C2524252C251C25342510250C25142518
03B2221E03C600B100BD00BC224800AB00BBFEF7FEF8009B009CFEFBFEFC009F
00A000ADFE8200A300A4FE8400000000FE8EFE8FFE95FE99060CFE9DFEA1FEA5
0660066106620663066406650666066706680669FED1061BFEB1FEB5FEB9061F
00A2FE80FE81FE83FE85FECAFE8BFE8DFE91FE93FE97FE9BFE9FFEA3FEA7FEA9
FEABFEADFEAFFEB3FEB7FEBBFEBFFEC1FEC5FECBFECF00A600AC00F700D7FEC9
0640FED3FED7FEDBFEDFFEE3FEE7FEEBFEEDFEEFFEF3FEBDFECCFECEFECDFEE1
FE7D0651FEE5FEE9FEECFEF0FEF2FED0FED5FEF5FEF6FEDDFED9FEF125A00000

Added library/encoding/cp865.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp865, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
00C900E600C600F400F600F200FB00F900FF00D600DC00F800A300D820A70192
00E100ED00F300FA00F100D100AA00BA00BF231000AC00BD00BC00A100AB00A4
259125922593250225242561256225562555256325512557255D255C255B2510
25142534252C251C2500253C255E255F255A25542569256625602550256C2567
2568256425652559255825522553256B256A2518250C25882584258C25902580
03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0

Added library/encoding/cp866.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp866, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0410041104120413041404150416041704180419041A041B041C041D041E041F
0420042104220423042404250426042704280429042A042B042C042D042E042F
0430043104320433043404350436043704380439043A043B043C043D043E043F
259125922593250225242561256225562555256325512557255D255C255B2510
25142534252C251C2500253C255E255F255A25542569256625602550256C2567
2568256425652559255825522553256B256A2518250C25882584258C25902580
0440044104420443044404450446044704480449044A044B044C044D044E044F
040104510404045404070457040E045E00B0221900B7221A211600A425A000A0

Added library/encoding/cp869.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp869, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850386008700B700AC00A620182019038820150389
038A03AA038C00930094038E03AB00A9038F00B200B303AC00A303AD03AE03AF
03CA039003CC03CD039103920393039403950396039700BD0398039900AB00BB
25912592259325022524039A039B039C039D256325512557255D039E039F2510
25142534252C251C2500253C03A003A1255A25542569256625602550256C03A3
03A403A503A603A703A803A903B103B203B32518250C2588258403B403B52580
03B603B703B803B903BA03BB03BC03BD03BE03BF03C003C103C303C203C40384
00AD00B103C503C603C700A703C8038500B000A803C903CB03B003CE25A000A0

Added library/encoding/cp874.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp874, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008420260086008700880089008A008B008C008D008E008F
009020182019201C201D20222013201400980099009A009B009C009D009E009F
00A00E010E020E030E040E050E060E070E080E090E0A0E0B0E0C0E0D0E0E0E0F
0E100E110E120E130E140E150E160E170E180E190E1A0E1B0E1C0E1D0E1E0E1F
0E200E210E220E230E240E250E260E270E280E290E2A0E2B0E2C0E2D0E2E0E2F
0E300E310E320E330E340E350E360E370E380E390E3A00000000000000000E3F
0E400E410E420E430E440E450E460E470E480E490E4A0E4B0E4C0E4D0E4E0E4F
0E500E510E520E530E540E550E560E570E580E590E5A0E5B0000000000000000

Added library/encoding/cp932.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
# Encoding file: cp932, multi-byte
M
003F 0 46
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080000000000000000000850086000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
81
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E
FFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0FFF3C
FF5E2225FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3DFF5B
FF5D30083009300A300B300C300D300E300F30103011FF0BFF0D00B100D70000
00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
FF04FFE0FFE1FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6
25A125A025B325B225BD25BC203B301221922190219121933013000000000000
000000000000000000000000000000002208220B2286228722822283222A2229
0000000000000000000000000000000022272228FFE221D221D4220022030000
0000000000000000000000000000000000000000222022A52312220222072261
2252226A226B221A223D221D2235222B222C0000000000000000000000000000
212B2030266F266D266A2020202100B6000000000000000025EF000000000000
82
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000FF10
FF11FF12FF13FF14FF15FF16FF17FF18FF190000000000000000000000000000
FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2FFF30
FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3A000000000000000000000000
0000FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5A00000000000000003041
30423043304430453046304730483049304A304B304C304D304E304F30503051
30523053305430553056305730583059305A305B305C305D305E305F30603061
30623063306430653066306730683069306A306B306C306D306E306F30703071
30723073307430753076307730783079307A307B307C307D307E307F30803081
30823083308430853086308730883089308A308B308C308D308E308F30903091
3092309300000000000000000000000000000000000000000000000000000000
83
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
30A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF30B0
30B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF30C0
30C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF30D0
30D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF0000
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000391
03920393039403950396039703980399039A039B039C039D039E039F03A003A1
03A303A403A503A603A703A803A90000000000000000000000000000000003B1
03B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF03C003C1
03C303C403C503C603C703C803C9000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
84
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
04100411041204130414041504010416041704180419041A041B041C041D041E
041F0420042104220423042404250426042704280429042A042B042C042D042E
042F000000000000000000000000000000000000000000000000000000000000
04300431043204330434043504510436043704380439043A043B043C043D0000
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000002500
2502250C251025182514251C252C25242534253C25012503250F2513251B2517
25232533252B253B254B2520252F25282537253F251D25302525253825420000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
87
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
2460246124622463246424652466246724682469246A246B246C246D246E246F
2470247124722473216021612162216321642165216621672168216900003349
33143322334D331833273303333633513357330D33263323332B334A333B339C
339D339E338E338F33C433A100000000000000000000000000000000337B0000
301D301F211633CD212132A432A532A632A732A8323132323239337E337D337C
22522261222B222E2211221A22A52220221F22BF22352229222A000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
88
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000004E9C
55165A03963F54C0611B632859F690228475831C7A5060AA63E16E2565ED8466
82A69BF56893572765A162715B9B59D0867B98F47D627DBE9B8E62167C9F88B7
5B895EB563096697684895C7978D674F4EE54F0A4F4D4F9D504956F2593759D4
5A015C0960DF610F61706613690570BA754F757079FB7DAD7DEF80C3840E8863
8B029055907A533B4E954EA557DF80B290C178EF4E0058F16EA290387A328328
828B9C2F5141537054BD54E156E059FB5F1598F26DEB80E4852D000000000000
89
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9662967096A097FB540B53F35B8770CF7FBD8FC296E8536F9D5C7ABA4E117893
81FC6E26561855046B1D851A9C3B59E553A96D6674DC958F56424E91904B96F2
834F990C53E155B65B305F71662066F368046C386CF36D29745B76C87A4E9834
82F1885B8A6092ED6DB275AB76CA99C560A68B018D8A95B2698E53AD51860000
5712583059445BB45EF6602863A963F46CBF6F14708E7114715971D5733F7E01
827682D185979060925B9D1B586965BC6C5A752551F9592E59655F805FDC62BC
65FA6A2A6B276BB4738B7FC189569D2C9D0E9EC45CA16C96837B51045C4B61B6
81C6687672614E594FFA537860696E297A4F97F34E0B53164EEE4F554F3D4FA1
4F7352A053EF5609590F5AC15BB65BE179D16687679C67B66B4C6CB3706B73C2
798D79BE7A3C7B8782B182DB8304837783EF83D387668AB256298CA88FE6904E
971E868A4FC45CE862117259753B81E582BD86FE8CC096C5991399D54ECB4F1A
89E356DE584A58CA5EFB5FEB602A6094606261D0621262D06539000000000000
8A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9B41666668B06D777070754C76867D7582A587F9958B968E8C9D51F152BE5916
54B35BB35D16616869826DAF788D84CB88578A7293A79AB86D6C99A886D957A3
67FF86CE920E5283568754045ED362E164B9683C68386BBB737278BA7A6B899A
89D28D6B8F0390ED95A3969497695B665CB3697D984D984E639B7B206A2B0000
6A7F68B69C0D6F5F5272559D607062EC6D3B6E076ED1845B89108F444E149C39
53F6691B6A3A9784682A515C7AC384B291DC938C565B9D286822830584317CA5
520882C574E64E7E4F8351A05BD2520A52D852E75DFB559A582A59E65B8C5B98
5BDB5E725E7960A3611F616361BE63DB656267D1685368FA6B3E6B536C576F22
6F976F4574B0751876E3770B7AFF7BA17C217DE97F367FF0809D8266839E89B3
8ACC8CAB908494519593959195A2966597D3992882184E38542B5CB85DCC73A9
764C773C5CA97FEB8D0B96C19811985498584F014F0E5371559C566857FA5947
5B095BC45C905E0C5E7E5FCC63EE673A65D765E2671F68CB68C4000000000000
8B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A5F5E306BC56C176C7D757F79485B637A007D005FBD898F8A188CB48D778ECC
8F1D98E29A0E9B3C4E80507D510059935B9C622F628064EC6B3A72A075917947
7FA987FB8ABC8B7063AC83CA97A05409540355AB68546A588A70782767759ECD
53745BA2811A865090064E184E454EC74F1153CA54385BAE5F13602565510000
673D6C426C726CE3707874037A767AAE7B087D1A7CFE7D6665E7725B53BB5C45
5DE862D262E063196E20865A8A318DDD92F86F0179A69B5A4EA84EAB4EAC4F9B
4FA050D151477AF6517151F653545321537F53EB55AC58835CE15F375F4A602F
6050606D631F65596A4B6CC172C272ED77EF80F881058208854E90F793E197FF
99579A5A4EF051DD5C2D6681696D5C4066F26975738968507C8150C552E45747
5DFE932665A46B236B3D7434798179BD7B4B7DCA82B983CC887F895F8B398FD1
91D1541F92804E5D503653E5533A72D7739677E982E68EAF99C699C899D25177
611A865E55B07A7A50765BD3904796854E326ADB91E75C515C48000000000000
8C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
63987A9F6C9397748F617AAA718A96887C8268177E706851936C52F2541B85AB
8A137FA48ECD90E15366888879414FC250BE521151445553572D73EA578B5951
5F625F8460756176616761A963B2643A656C666F68426E1375667A3D7CFB7D4C
7D997E4B7F6B830E834A86CD8A088A638B668EFD981A9D8F82B88FCE9BE80000
5287621F64836FC09699684150916B206C7A6F547A747D5088408A2367084EF6
503950265065517C5238526355A7570F58055ACC5EFA61B261F862F36372691C
6A29727D72AC732E7814786F7D79770C80A9898B8B198CE28ED290639375967A
98559A139E785143539F53B35E7B5F266E1B6E90738473FE7D4382378A008AFA
96504E4E500B53E4547C56FA59D15B645DF15EAB5F276238654567AF6E5672D0
7CCA88B480A180E183F0864E8A878DE8923796C798679F134E944E924F0D5348
5449543E5A2F5F8C5FA1609F68A76A8E745A78818A9E8AA48B7791904E5E9BC9
4EA44F7C4FAF501950165149516C529F52B952FE539A53E35411000000000000
8D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
540E5589575157A2597D5B545B5D5B8F5DE55DE75DF75E785E835E9A5EB75F18
6052614C629762D863A7653B6602664366F4676D6821689769CB6C5F6D2A6D69
6E2F6E9D75327687786C7A3F7CE07D057D187D5E7DB18015800380AF80B18154
818F822A8352884C88618B1B8CA28CFC90CA91759271783F92FC95A4964D0000
980599999AD89D3B525B52AB53F7540858D562F76FE08C6A8F5F9EB9514B523B
544A56FD7A4091779D609ED273446F09817075115FFD60DA9AA872DB8FBC6B64
98034ECA56F0576458BE5A5A606861C7660F6606683968B16DF775D57D3A826E
9B424E9B4F5053C955065D6F5DE65DEE67FB6C99747378028A50939688DF5750
5EA7632B50B550AC518D670054C9585E59BB5BB05F69624D63A1683D6B736E08
707D91C7728078157826796D658E7D3083DC88C18F09969B5264572867507F6A
8CA151B45742962A583A698A80B454B25D0E57FC78959DFA4F5C524A548B643E
6628671467F57A847B567D22932F685C9BAD7B395319518A5237000000000000
8E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5BDF62F664AE64E6672D6BBA85A996D176909BD6634C93069BAB76BF66524E09
509853C25C7160E864926563685F71E673CA75237B977E8286958B838CDB9178
991065AC66AB6B8B4ED54ED44F3A4F7F523A53F853F255E356DB58EB59CB59C9
59FF5B505C4D5E025E2B5FD7601D6307652F5B5C65AF65BD65E8679D6B620000
6B7B6C0F7345794979C17CF87D197D2B80A2810281F389968A5E8A698A668A8C
8AEE8CC78CDC96CC98FC6B6F4E8B4F3C4F8D51505B575BFA6148630166426B21
6ECB6CBB723E74BD75D478C1793A800C803381EA84948F9E6C509E7F5F0F8B58
9D2B7AFA8EF85B8D96EB4E0353F157F759315AC95BA460896E7F6F0675BE8CEA
5B9F85007BE0507267F4829D5C61854A7E1E820E51995C0463688D66659C716E
793E7D1780058B1D8ECA906E86C790AA501F52FA5C3A6753707C7235914C91C8
932B82E55BC25F3160F94E3B53D65B88624B67316B8A72E973E07A2E816B8DA3
91529996511253D7546A5BFF63886A397DAC970056DA53CE5468000000000000
8F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5B975C315DDE4FEE610162FE6D3279C079CB7D427E4D7FD281ED821F84908846
89728B908E748F2F9031914B916C96C6919C4EC04F4F514553415F93620E67D4
6C416E0B73637E2691CD928353D459195BBF6DD1795D7E2E7C9B587E719F51FA
88538FF04FCA5CFB662577AC7AE3821C99FF51C65FAA65EC696F6B896DF30000
6E966F6476FE7D145DE190759187980651E6521D6240669166D96E1A5EB67DD2
7F7266F885AF85F78AF852A953D959735E8F5F90605592E4966450B7511F52DD
5320534753EC54E8554655315617596859BE5A3C5BB55C065C0F5C115C1A5E84
5E8A5EE05F70627F628462DB638C63776607660C662D6676677E68A26A1F6A35
6CBC6D886E096E58713C7126716775C77701785D7901796579F07AE07B117CA7
7D39809683D6848B8549885D88F38A1F8A3C8A548A738C618CDE91A49266937E
9418969C97984E0A4E084E1E4E575197527057CE583458CC5B225E3860C564FE
676167566D4472B675737A6384B88B7291B89320563157F498FE000000000000
90
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
62ED690D6B9671ED7E548077827289E698DF87558FB15C3B4F384FE14FB55507
5A205BDD5BE95FC3614E632F65B0664B68EE699B6D786DF1753375B9771F795E
79E67D3381E382AF85AA89AA8A3A8EAB8F9B903291DD97074EBA4EC152035875
58EC5C0B751A5C3D814E8A0A8FC59663976D7B258ACF9808916256F353A80000
9017543957825E2563A86C34708A77617C8B7FE088709042915493109318968F
745E9AC45D075D69657067A28DA896DB636E6749691983C5981796C088FE6F84
647A5BF84E16702C755D662F51C4523652E259D35F8160276210653F6574661F
667468F268166B636E057272751F76DB7CBE805658F088FD897F8AA08A938ACB
901D91929752975965897A0E810696BB5E2D60DC621A65A56614679077F37A4D
7C4D7E3E810A8CAC8D648DE18E5F78A9520762D963A5644262988A2D7A837BC0
8AAC96EA7D76820C87494ED95148534353605BA35C025C165DDD6226624764B0
681368346CC96D456D1767D36F5C714E717D65CB7A7F7BAD7DDA000000000000
91
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7E4A7FA8817A821B823985A68A6E8CCE8DF59078907792AD929195839BAE524D
55846F387136516879857E5581B37CCE564C58515CA863AA66FE66FD695A72D9
758F758E790E795679DF7C977D207D4486078A34963B90619F2050E7527553CC
53E2500955AA58EE594F723D5B8B5C64531D60E360F3635C6383633F63BB0000
64CD65E966F95DE369CD69FD6F1571E54E8975E976F87A937CDF7DCF7D9C8061
83498358846C84BC85FB88C58D709001906D9397971C9A1250CF5897618E81D3
85358D0890204FC3507452475373606F6349675F6E2C8DB3901F4FD75C5E8CCA
65CF7D9A53528896517663C35B585B6B5C0A640D6751905C4ED6591A592A6C70
8A51553E581559A560F0625367C182356955964099C49A284F5358065BFE8010
5CB15E2F5F856020614B623466FF6CF06EDE80CE817F82D4888B8CB89000902E
968A9EDB9BDB4EE353F059277B2C918D984C9DF96EDD7027535355445B856258
629E62D36CA26FEF74228A1794386FC18AFE833851E786F853EA000000000000
92
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
53E94F4690548FB0596A81315DFD7AEA8FBF68DA8C3772F89C486A3D8AB04E39
53585606576662C563A265E66B4E6DE16E5B70AD77ED7AEF7BAA7DBB803D80C6
86CB8A95935B56E358C75F3E65AD66966A806BB575378AC7502477E557305F1B
6065667A6C6075F47A1A7F6E81F48718904599B37BC9755C7AF97B5184C40000
901079E97A9283365AE177404E2D4EF25B995FE062BD663C67F16CE8866B8877
8A3B914E92F399D06A177026732A82E784578CAF4E01514651CB558B5BF55E16
5E335E815F145F355F6B5FB461F2631166A2671D6F6E7252753A773A80748139
817887768ABF8ADC8D858DF3929A957798029CE552C5635776F467156C8873CD
8CC393AE96736D25589C690E69CC8FFD939A75DB901A585A680263B469FB4F43
6F2C67D88FBB85267DB49354693F6F70576A58F75B2C7D2C722A540A91E39DB4
4EAD4F4E505C507552438C9E544858245B9A5E1D5E955EAD5EF75F1F608C62B5
633A63D068AF6C407887798E7A0B7DE082478A028AE68E449013000000000000
93
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
90B8912D91D89F0E6CE5645864E265756EF476847B1B906993D16EBA54F25FB9
64A48F4D8FED92445178586B59295C555E976DFB7E8F751C8CBC8EE2985B70B9
4F1D6BBF6FB1753096FB514E54105835585759AC5C605F926597675C6E21767B
83DF8CED901490FD934D7825783A52AA5EA6571F597460125012515A51AC0000
51CD520055105854585859575B955CF65D8B60BC6295642D6771684368BC68DF
76D76DD86E6F6D9B706F71C85F5375D879777B497B547B527CD67D7152308463
856985E48A0E8B048C468E0F9003900F94199676982D9A3095D850CD52D5540C
58025C0E61A7649E6D1E77B37AE580F48404905392855CE09D07533F5F975FB3
6D9C7279776379BF7BE46BD272EC8AAD68036A6151F87A8169345C4A9CF682EB
5BC59149701E56785C6F60C765666C8C8C5A90419813545166C7920D594890A3
51854E4D51EA85998B0E7058637A934B696299B47E047577535769608EDF96E3
6C5D4E8C5C3C5F108FE953028CD1808986795EFF65E54E735165000000000000
94
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59825C3F97EE4EFB598A5FCD8A8D6FE179B079625BE78471732B71B15E745FF5
637B649A71C37C984E435EFC4E4B57DC56A260A96FC37D0D80FD813381BF8FB2
899786A45DF4628A64AD898767776CE26D3E743678345A467F7582AD99AC4FF3
5EC362DD63926557676F76C3724C80CC80BA8F29914D500D57F95A9268850000
6973716472FD8CB758F28CE0966A9019877F79E477E784294F2F5265535A62CD
67CF6CCA767D7B947C95823685848FEB66DD6F2072067E1B83AB99C19EA651FD
7BB178727BB880877B486AE85E61808C75517560516B92626E8C767A91979AEA
4F107F70629C7B4F95A59CE9567A585986E496BC4F345224534A53CD53DB5E06
642C6591677F6C3E6C4E724872AF73ED75547E41822C85E98CA97BC491C67169
981298EF633D6669756A76E478D0854386EE532A5351542659835E875F7C60B2
6249627962AB65906BD46CCC75B276AE789179D87DCB7F7780A588AB8AB98CBB
907F975E98DB6A0B7C3850995C3E5FAE67876BD8743577097F8E000000000000
95
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9F3B67CA7A175339758B9AED5F66819D83F180985F3C5FC575627B46903C6867
59EB5A9B7D10767E8B2C4FF55F6A6A196C376F0274E2796888688A558C795EDF
63CF75C579D282D7932892F2849C86ED9C2D54C15F6C658C6D5C70158CA78CD3
983B654F74F64E0D4ED857E0592B5A665BCC51A85E035E9C6016627665770000
65A7666E6D6E72367B268150819A82998B5C8CA08CE68D74961C96444FAE64AB
6B66821E8461856A90E85C01695398A8847A85574F0F526F5FA95E45670D798F
8179890789866DF55F1762556CB84ECF72699B925206543B567458B361A4626E
711A596E7C897CDE7D1B96F06587805E4E194F75517558405E635E735F0A67C4
4E26853D9589965B7C73980150FB58C1765678A7522577A585117B86504F5909
72477BC77DE88FBA8FD4904D4FBF52C95A295F0197AD4FDD821792EA57036355
6B69752B88DC8F147A4252DF58936155620A66AE6BCD7C3F83E950234FF85305
5446583159495B9D5CF05CEF5D295E9662B16367653E65B9670B000000000000
96
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6CD56CE170F978327E2B80DE82B3840C84EC870289128A2A8C4A90A692D298FD
9CF39D6C4E4F4EA1508D5256574A59A85E3D5FD85FD9623F66B4671B67D068D2
51927D2180AA81A88B008C8C8CBF927E96325420982C531750D5535C58A864B2
6734726777667A4691E652C36CA16B8658005E4C5954672C7FFB51E176C60000
646978E89B549EBB57CB59B96627679A6BCE54E969D95E55819C67959BAA67FE
9C52685D4EA64FE353C862B9672B6CAB8FC44FAD7E6D9EBF4E0761626E806F2B
85135473672A9B455DF37B955CAC5BC6871C6E4A84D17A14810859997C8D6C11
772052D959227121725F77DB97279D61690B5A7F5A1851A5540D547D660E76DF
8FF792989CF459EA725D6EC5514D68C97DBF7DEC97629EBA64786A2183025984
5B5F6BDB731B76F27DB280178499513267289ED976EE676252FF99055C24623B
7C7E8CB0554F60B67D0B958053014E5F51B6591C723A803691CE5F2577E25384
5F797D0485AC8A338E8D975667F385AE9453610961086CB97652000000000000
97
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8AED8F38552F4F51512A52C753CB5BA55E7D60A0618263D6670967DA6E676D8C
733673377531795088D58A98904A909190F596C4878D59154E884F594E0E8A89
8F3F981050AD5E7C59965BB95EB863DA63FA64C166DC694A69D86D0B6EB67194
75287AAF7F8A8000844984C989818B218E0A9065967D990A617E62916B320000
6C836D747FCC7FFC6DC07F8587BA88F8676583B1983C96F76D1B7D61843D916A
4E7153755D506B046FEB85CD862D89A75229540F5C65674E68A87406748375E2
88CF88E191CC96E296785F8B73877ACB844E63A0756552896D416E9C74097559
786B7C9296867ADC9F8D4FB6616E65C5865C4E864EAE50DA4E2151CC5BEE6599
68816DBC731F764277AD7A1C7CE7826F8AD2907C91CF96759818529B7DD1502B
539867976DCB71D0743381E88F2A96A39C579E9F746058416D997D2F985E4EE4
4F364F8B51B752B15DBA601C73B2793C82D3923496B796F6970A9E979F6266A6
6B74521752A370C888C25EC9604B61906F2371497C3E7DF4806F000000000000
98
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
84EE9023932C54429B6F6AD370898CC28DEF973252B45A415ECA5F046717697C
69946D6A6F0F726272FC7BED8001807E874B90CE516D9E937984808B93328AD6
502D548C8A716B6A8CC4810760D167A09DF24E994E989C108A6B85C185686900
6E7E789781550000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000005F0C
4E104E154E2A4E314E364E3C4E3F4E424E564E584E824E858C6B4E8A82125F0D
4E8E4E9E4E9F4EA04EA24EB04EB34EB64ECE4ECD4EC44EC64EC24ED74EDE4EED
4EDF4EF74F094F5A4F304F5B4F5D4F574F474F764F884F8F4F984F7B4F694F70
4F914F6F4F864F9651184FD44FDF4FCE4FD84FDB4FD14FDA4FD04FE44FE5501A
50285014502A502550054F1C4FF650215029502C4FFE4FEF5011500650435047
6703505550505048505A5056506C50785080509A508550B450B2000000000000
99
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
50C950CA50B350C250D650DE50E550ED50E350EE50F950F55109510151025116
51155114511A5121513A5137513C513B513F51405152514C515451627AF85169
516A516E5180518256D8518C5189518F519151935195519651A451A651A251A9
51AA51AB51B351B151B251B051B551BD51C551C951DB51E0865551E951ED0000
51F051F551FE5204520B5214520E5227522A522E52335239524F5244524B524C
525E5254526A527452695273527F527D528D529452925271528852918FA88FA7
52AC52AD52BC52B552C152CD52D752DE52E352E698ED52E052F352F552F852F9
530653087538530D5310530F5315531A5323532F533153335338534053465345
4E175349534D51D6535E5369536E5918537B53775382539653A053A653A553AE
53B053B653C37C1296D953DF66FC71EE53EE53E853ED53FA5401543D5440542C
542D543C542E54365429541D544E548F5475548E545F5471547754705492547B
5480547654845490548654C754A254B854A554AC54C454C854A8000000000000
9A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54AB54C254A454BE54BC54D854E554E6550F551454FD54EE54ED54FA54E25539
55405563554C552E555C55455556555755385533555D5599558054AF558A559F
557B557E5598559E55AE557C558355A9558755A855DA55C555DF55C455DC55E4
55D4561455F7561655FE55FD561B55F9564E565071DF56345636563256380000
566B5664562F566C566A56865680568A56A05694568F56A556AE56B656B456C2
56BC56C156C356C056C856CE56D156D356D756EE56F9570056FF570457095708
570B570D57135718571655C7571C572657375738574E573B5740574F576957C0
57885761577F5789579357A057B357A457AA57B057C357C657D457D257D3580A
57D657E3580B5819581D587258215862584B58706BC05852583D5879588558B9
589F58AB58BA58DE58BB58B858AE58C558D358D158D758D958D858E558DC58E4
58DF58EF58FA58F958FB58FC58FD5902590A5910591B68A65925592C592D5932
5938593E7AD259555950594E595A5958596259605967596C5969000000000000
9B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59785981599D4F5E4FAB59A359B259C659E859DC598D59D959DA5A255A1F5A11
5A1C5A095A1A5A405A6C5A495A355A365A625A6A5A9A5ABC5ABE5ACB5AC25ABD
5AE35AD75AE65AE95AD65AFA5AFB5B0C5B0B5B165B325AD05B2A5B365B3E5B43
5B455B405B515B555B5A5B5B5B655B695B705B735B755B7865885B7A5B800000
5B835BA65BB85BC35BC75BC95BD45BD05BE45BE65BE25BDE5BE55BEB5BF05BF6
5BF35C055C075C085C0D5C135C205C225C285C385C395C415C465C4E5C535C50
5C4F5B715C6C5C6E4E625C765C795C8C5C915C94599B5CAB5CBB5CB65CBC5CB7
5CC55CBE5CC75CD95CE95CFD5CFA5CED5D8C5CEA5D0B5D155D175D5C5D1F5D1B
5D115D145D225D1A5D195D185D4C5D525D4E5D4B5D6C5D735D765D875D845D82
5DA25D9D5DAC5DAE5DBD5D905DB75DBC5DC95DCD5DD35DD25DD65DDB5DEB5DF2
5DF55E0B5E1A5E195E115E1B5E365E375E445E435E405E4E5E575E545E5F5E62
5E645E475E755E765E7A9EBC5E7F5EA05EC15EC25EC85ED05ECF000000000000
9C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5ED65EE35EDD5EDA5EDB5EE25EE15EE85EE95EEC5EF15EF35EF05EF45EF85EFE
5F035F095F5D5F5C5F0B5F115F165F295F2D5F385F415F485F4C5F4E5F2F5F51
5F565F575F595F615F6D5F735F775F835F825F7F5F8A5F885F915F875F9E5F99
5F985FA05FA85FAD5FBC5FD65FFB5FE45FF85FF15FDD60B35FFF602160600000
601960106029600E6031601B6015602B6026600F603A605A6041606A6077605F
604A6046604D6063604360646042606C606B60596081608D60E76083609A6084
609B60966097609260A7608B60E160B860E060D360B45FF060BD60C660B560D8
614D6115610660F660F7610060F460FA6103612160FB60F1610D610E6147613E
61286127614A613F613C612C6134613D614261446173617761586159615A616B
6174616F61656171615F615D6153617561996196618761AC6194619A618A6191
61AB61AE61CC61CA61C961F761C861C361C661BA61CB7F7961CD61E661E361F6
61FA61F461FF61FD61FC61FE620062086209620D620C6214621B000000000000
9D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
621E6221622A622E6230623262336241624E625E6263625B62606268627C6282
6289627E62926293629662D46283629462D762D162BB62CF62FF62C664D462C8
62DC62CC62CA62C262C7629B62C9630C62EE62F163276302630862EF62F56350
633E634D641C634F6396638E638063AB637663A3638F6389639F63B5636B0000
636963BE63E963C063C663E363C963D263F663C4641664346406641364266436
651D64176428640F6467646F6476644E652A6495649364A564A9648864BC64DA
64D264C564C764BB64D864C264F164E7820964E064E162AC64E364EF652C64F6
64F464F264FA650064FD6518651C650565246523652B65346535653765366538
754B654865566555654D6558655E655D65726578658265838B8A659B659F65AB
65B765C365C665C165C465CC65D265DB65D965E065E165F16772660A660365FB
6773663566366634661C664F664466496641665E665D666466676668665F6662
667066836688668E668966846698669D66C166B966C966BE66BC000000000000
9E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
66C466B866D666DA66E0663F66E666E966F066F566F7670F6716671E67266727
9738672E673F67366741673867376746675E67606759676367646789677067A9
677C676A678C678B67A667A1678567B767EF67B467EC67B367E967B867E467DE
67DD67E267EE67B967CE67C667E76A9C681E684668296840684D6832684E0000
68B3682B685968636877687F689F688F68AD6894689D689B68836AAE68B96874
68B568A068BA690F688D687E690168CA690868D86922692668E1690C68CD68D4
68E768D569366912690468D768E3692568F968E068EF6928692A691A69236921
68C669796977695C6978696B6954697E696E69396974693D695969306961695E
695D6981696A69B269AE69D069BF69C169D369BE69CE5BE869CA69DD69BB69C3
69A76A2E699169A0699C699569B469DE69E86A026A1B69FF6B0A69F969F269E7
6A0569B16A1E69ED6A1469EB6A0A6A126AC16A236A136A446A0C6A726A366A78
6A476A626A596A666A486A386A226A906A8D6AA06A846AA26AA3000000000000
9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A9786176ABB6AC36AC26AB86AB36AAC6ADE6AD16ADF6AAA6ADA6AEA6AFB6B05
86166AFA6B126B169B316B1F6B386B3776DC6B3998EE6B476B436B496B506B59
6B546B5B6B5F6B616B786B796B7F6B806B846B836B8D6B986B956B9E6BA46BAA
6BAB6BAF6BB26BB16BB36BB76BBC6BC66BCB6BD36BDF6BEC6BEB6BF36BEF0000
9EBE6C086C136C146C1B6C246C236C5E6C556C626C6A6C826C8D6C9A6C816C9B
6C7E6C686C736C926C906CC46CF16CD36CBD6CD76CC56CDD6CAE6CB16CBE6CBA
6CDB6CEF6CD96CEA6D1F884D6D366D2B6D3D6D386D196D356D336D126D0C6D63
6D936D646D5A6D796D596D8E6D956FE46D856DF96E156E0A6DB56DC76DE66DB8
6DC66DEC6DDE6DCC6DE86DD26DC56DFA6DD96DE46DD56DEA6DEE6E2D6E6E6E2E
6E196E726E5F6E3E6E236E6B6E2B6E766E4D6E1F6E436E3A6E4E6E246EFF6E1D
6E386E826EAA6E986EC96EB76ED36EBD6EAF6EC46EB26ED46ED56E8F6EA56EC2
6E9F6F416F11704C6EEC6EF86EFE6F3F6EF26F316EEF6F326ECC000000000000
E0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6F3E6F136EF76F866F7A6F786F816F806F6F6F5B6FF36F6D6F826F7C6F586F8E
6F916FC26F666FB36FA36FA16FA46FB96FC66FAA6FDF6FD56FEC6FD46FD86FF1
6FEE6FDB7009700B6FFA70117001700F6FFE701B701A6F74701D7018701F7030
703E7032705170637099709270AF70F170AC70B870B370AE70DF70CB70DD0000
70D9710970FD711C711971657155718871667162714C7156716C718F71FB7184
719571A871AC71D771B971BE71D271C971D471CE71E071EC71E771F571FC71F9
71FF720D7210721B7228722D722C72307232723B723C723F72407246724B7258
7274727E7282728172877292729672A272A772B972B272C372C672C472CE72D2
72E272E072E172F972F7500F7317730A731C7316731D7334732F73297325733E
734E734F9ED87357736A7368737073787375737B737A73C873B373CE73BB73C0
73E573EE73DE74A27405746F742573F87432743A7455743F745F74597441745C
746974707463746A7476747E748B749E74A774CA74CF74D473F1000000000000
E1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
74E074E374E774E974EE74F274F074F174F874F7750475037505750C750E750D
75157513751E7526752C753C7544754D754A7549755B7546755A756975647567
756B756D75787576758675877574758A758975827594759A759D75A575A375C2
75B375C375B575BD75B875BC75B175CD75CA75D275D975E375DE75FE75FF0000
75FC760175F075FA75F275F3760B760D7609761F762776207621762276247634
7630763B764776487646765C76587661766276687669766A7667766C76707672
76767678767C768076837688768B768E769676937699769A76B076B476B876B9
76BA76C276CD76D676D276DE76E176E576E776EA862F76FB7708770777047729
7724771E77257726771B773777387747775A7768776B775B7765777F777E7779
778E778B779177A0779E77B077B677B977BF77BC77BD77BB77C777CD77D777DA
77DC77E377EE77FC780C781279267820792A7845788E78747886787C789A788C
78A378B578AA78AF78D178C678CB78D478BE78BC78C578CA78EC000000000000
E2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
78E778DA78FD78F47907791279117919792C792B794079607957795F795A7955
7953797A797F798A799D79A79F4B79AA79AE79B379B979BA79C979D579E779EC
79E179E37A087A0D7A187A197A207A1F79807A317A3B7A3E7A377A437A577A49
7A617A627A699F9D7A707A797A7D7A887A977A957A987A967AA97AC87AB00000
7AB67AC57AC47ABF90837AC77ACA7ACD7ACF7AD57AD37AD97ADA7ADD7AE17AE2
7AE67AED7AF07B027B0F7B0A7B067B337B187B197B1E7B357B287B367B507B7A
7B047B4D7B0B7B4C7B457B757B657B747B677B707B717B6C7B6E7B9D7B987B9F
7B8D7B9C7B9A7B8B7B927B8F7B5D7B997BCB7BC17BCC7BCF7BB47BC67BDD7BE9
7C117C147BE67BE57C607C007C077C137BF37BF77C177C0D7BF67C237C277C2A
7C1F7C377C2B7C3D7C4C7C437C547C4F7C407C507C587C5F7C647C567C657C6C
7C757C837C907CA47CAD7CA27CAB7CA17CA87CB37CB27CB17CAE7CB97CBD7CC0
7CC57CC27CD87CD27CDC7CE29B3B7CEF7CF27CF47CF67CFA7D06000000000000
E3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7D027D1C7D157D0A7D457D4B7D2E7D327D3F7D357D467D737D567D4E7D727D68
7D6E7D4F7D637D937D897D5B7D8F7D7D7D9B7DBA7DAE7DA37DB57DC77DBD7DAB
7E3D7DA27DAF7DDC7DB87D9F7DB07DD87DDD7DE47DDE7DFB7DF27DE17E057E0A
7E237E217E127E317E1F7E097E0B7E227E467E667E3B7E357E397E437E370000
7E327E3A7E677E5D7E567E5E7E597E5A7E797E6A7E697E7C7E7B7E837DD57E7D
8FAE7E7F7E887E897E8C7E927E907E937E947E967E8E7E9B7E9C7F387F3A7F45
7F4C7F4D7F4E7F507F517F557F547F587F5F7F607F687F697F677F787F827F86
7F837F887F877F8C7F947F9E7F9D7F9A7FA37FAF7FB27FB97FAE7FB67FB88B71
7FC57FC67FCA7FD57FD47FE17FE67FE97FF37FF998DC80068004800B80128018
8019801C80218028803F803B804A804680528058805A805F8062806880738072
807080768079807D807F808480868085809B8093809A80AD519080AC80DB80E5
80D980DD80C480DA80D6810980EF80F1811B81298123812F814B000000000000
E4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
968B8146813E8153815180FC8171816E81658166817481838188818A81808182
81A0819581A481A3815F819381A981B081B581BE81B881BD81C081C281BA81C9
81CD81D181D981D881C881DA81DF81E081E781FA81FB81FE8201820282058207
820A820D821082168229822B82388233824082598258825D825A825F82640000
82628268826A826B822E827182778278827E828D829282AB829F82BB82AC82E1
82E382DF82D282F482F382FA8393830382FB82F982DE830682DC830982D98335
83348316833283318340833983508345832F832B831783188385839A83AA839F
83A283968323838E8387838A837C83B58373837583A0838983A883F4841383EB
83CE83FD840383D8840B83C183F7840783E083F2840D8422842083BD84388506
83FB846D842A843C855A84848477846B84AD846E848284698446842C846F8479
843584CA846284B984BF849F84D984CD84BB84DA84D084C184C684D684A18521
84FF84F485178518852C851F8515851484FC8540856385588548000000000000
E5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
85418602854B8555858085A485888591858A85A8856D8594859B85EA8587859C
8577857E859085C985BA85CF85B985D085D585DD85E585DC85F9860A8613860B
85FE85FA86068622861A8630863F864D4E558654865F86678671869386A386A9
86AA868B868C86B686AF86C486C686B086C9882386AB86D486DE86E986EC0000
86DF86DB86EF8712870687088700870386FB87118709870D86F9870A8734873F
8737873B87258729871A8760875F8778874C874E877487578768876E87598753
8763876A880587A2879F878287AF87CB87BD87C087D096D687AB87C487B387C7
87C687BB87EF87F287E0880F880D87FE87F687F7880E87D28811881688158822
88218831883688398827883B8844884288528859885E8862886B8881887E889E
8875887D88B5887288828897889288AE889988A2888D88A488B088BF88B188C3
88C488D488D888D988DD88F9890288FC88F488E888F28904890C890A89138943
891E8925892A892B89418944893B89368938894C891D8960895E000000000000
E6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
89668964896D896A896F89748977897E89838988898A8993899889A189A989A6
89AC89AF89B289BA89BD89BF89C089DA89DC89DD89E789F489F88A038A168A10
8A0C8A1B8A1D8A258A368A418A5B8A528A468A488A7C8A6D8A6C8A628A858A82
8A848AA88AA18A918AA58AA68A9A8AA38AC48ACD8AC28ADA8AEB8AF38AE70000
8AE48AF18B148AE08AE28AF78ADE8ADB8B0C8B078B1A8AE18B168B108B178B20
8B3397AB8B268B2B8B3E8B288B418B4C8B4F8B4E8B498B568B5B8B5A8B6B8B5F
8B6C8B6F8B748B7D8B808B8C8B8E8B928B938B968B998B9A8C3A8C418C3F8C48
8C4C8C4E8C508C558C628C6C8C788C7A8C828C898C858C8A8C8D8C8E8C948C7C
8C98621D8CAD8CAA8CBD8CB28CB38CAE8CB68CC88CC18CE48CE38CDA8CFD8CFA
8CFB8D048D058D0A8D078D0F8D0D8D109F4E8D138CCD8D148D168D678D6D8D71
8D738D818D998DC28DBE8DBA8DCF8DDA8DD68DCC8DDB8DCB8DEA8DEB8DDF8DE3
8DFC8E088E098DFF8E1D8E1E8E108E1F8E428E358E308E348E4A000000000000
E7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8E478E498E4C8E508E488E598E648E608E2A8E638E558E768E728E7C8E818E87
8E858E848E8B8E8A8E938E918E948E998EAA8EA18EAC8EB08EC68EB18EBE8EC5
8EC88ECB8EDB8EE38EFC8EFB8EEB8EFE8F0A8F058F158F128F198F138F1C8F1F
8F1B8F0C8F268F338F3B8F398F458F428F3E8F4C8F498F468F4E8F578F5C0000
8F628F638F648F9C8F9F8FA38FAD8FAF8FB78FDA8FE58FE28FEA8FEF90878FF4
90058FF98FFA901190159021900D901E9016900B90279036903590398FF8904F
905090519052900E9049903E90569058905E9068906F907696A890729082907D
90819080908A9089908F90A890AF90B190B590E290E4624890DB910291129119
91329130914A9156915891639165916991739172918B9189918291A291AB91AF
91AA91B591B491BA91C091C191C991CB91D091D691DF91E191DB91FC91F591F6
921E91FF9214922C92159211925E925792459249926492489295923F924B9250
929C92969293929B925A92CF92B992B792E9930F92FA9344932E000000000000
E8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
93199322931A9323933A9335933B935C9360937C936E935693B093AC93AD9394
93B993D693D793E893E593D893C393DD93D093C893E4941A9414941394039407
94109436942B94359421943A944194529444945B94609462945E946A92299470
94759477947D945A947C947E9481947F95829587958A95949596959895990000
95A095A895A795AD95BC95BB95B995BE95CA6FF695C395CD95CC95D595D495D6
95DC95E195E595E296219628962E962F9642964C964F964B9677965C965E965D
965F96669672966C968D96989695969796AA96A796B196B296B096B496B696B8
96B996CE96CB96C996CD894D96DC970D96D596F99704970697089713970E9711
970F971697199724972A97309739973D973E97449746974897429749975C9760
97649766976852D2976B977197799785977C9781977A9786978B978F9790979C
97A897A697A397B397B497C397C697C897CB97DC97ED9F4F97F27ADF97F697F5
980F980C9838982498219837983D9846984F984B986B986F9870000000000000
E9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
98719874987398AA98AF98B198B698C498C398C698E998EB9903990999129914
99189921991D991E99249920992C992E993D993E9942994999459950994B9951
9952994C99559997999899A599AD99AE99BC99DF99DB99DD99D899D199ED99EE
99F199F299FB99F89A019A0F9A0599E29A199A2B9A379A459A429A409A430000
9A3E9A559A4D9A5B9A579A5F9A629A659A649A699A6B9A6A9AAD9AB09ABC9AC0
9ACF9AD19AD39AD49ADE9ADF9AE29AE39AE69AEF9AEB9AEE9AF49AF19AF79AFB
9B069B189B1A9B1F9B229B239B259B279B289B299B2A9B2E9B2F9B329B449B43
9B4F9B4D9B4E9B519B589B749B939B839B919B969B979B9F9BA09BA89BB49BC0
9BCA9BB99BC69BCF9BD19BD29BE39BE29BE49BD49BE19C3A9BF29BF19BF09C15
9C149C099C139C0C9C069C089C129C0A9C049C2E9C1B9C259C249C219C309C47
9C329C469C3E9C5A9C609C679C769C789CE79CEC9CF09D099D089CEB9D039D06
9D2A9D269DAF9D239D1F9D449D159D129D419D3F9D3E9D469D48000000000000
EA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9D5D9D5E9D649D519D509D599D729D899D879DAB9D6F9D7A9D9A9DA49DA99DB2
9DC49DC19DBB9DB89DBA9DC69DCF9DC29DD99DD39DF89DE69DED9DEF9DFD9E1A
9E1B9E1E9E759E799E7D9E819E889E8B9E8C9E929E959E919E9D9EA59EA99EB8
9EAA9EAD97619ECC9ECE9ECF9ED09ED49EDC9EDE9EDD9EE09EE59EE89EEF0000
9EF49EF69EF79EF99EFB9EFC9EFD9F079F0876B79F159F219F2C9F3E9F4A9F52
9F549F639F5F9F609F619F669F679F6C9F6A9F779F729F769F959F9C9FA0582F
69C79059746451DC719900000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
ED
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7E8A891C9348928884DC4FC970BB663168C892F966FB5F454E284EE14EFC4F00
4F034F394F564F924F8A4F9A4F944FCD504050224FFF501E5046507050425094
50F450D8514A5164519D51BE51EC5215529C52A652C052DB5300530753245372
539353B253DDFA0E549C548A54A954FF55865759576557AC57C857C7FA0F0000
FA10589E58B2590B5953595B595D596359A459BA5B565BC0752F5BD85BEC5C1E
5CA65CBA5CF55D275D53FA115D425D6D5DB85DB95DD05F215F345F675FB75FDE
605D6085608A60DE60D5612060F26111613761306198621362A663F56460649D
64CE654E66006615663B6609662E661E6624666566576659FA126673669966A0
66B266BF66FA670EF929676667BB685267C06801684468CFFA136968FA146998
69E26A306A6B6A466A736A7E6AE26AE46BD66C3F6C5C6C866C6F6CDA6D046D87
6D6F6D966DAC6DCF6DF86DF26DFC6E396E5C6E276E3C6EBF6F886FB56FF57005
70077028708570AB710F7104715C71467147FA1571C171FE72B1000000000000
EE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
72BE7324FA16737773BD73C973D673E373D2740773F57426742A7429742E7462
7489749F7501756F7682769C769E769B76A6FA17774652AF7821784E7864787A
7930FA18FA19FA1A7994FA1B799B7AD17AE7FA1C7AEB7B9EFA1D7D487D5C7DB7
7DA07DD67E527F477FA1FA1E83018362837F83C783F6844884B4855385590000
856BFA1F85B0FA20FA21880788F58A128A378A798AA78ABE8ADFFA228AF68B53
8B7F8CF08CF48D128D76FA238ECFFA24FA25906790DEFA269115912791DA91D7
91DE91ED91EE91E491E592069210920A923A9240923C924E9259925192399267
92A79277927892E792D792D992D0FA2792D592E092D39325932192FBFA28931E
92FF931D93029370935793A493C693DE93F89431944594489592F9DCFA29969D
96AF9733973B9743974D974F9751975598579865FA2AFA2B9927FA2C999E9A4E
9AD99ADC9B759B729B8F9BB19BBB9C009D709D6BFA2D9E199ED1000000002170
217121722173217421752176217721782179FFE2FFE4FF07FF02000000000000
FA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
2170217121722173217421752176217721782179216021612162216321642165
2166216721682169FFE2FFE4FF07FF0232312116212122357E8A891C93489288
84DC4FC970BB663168C892F966FB5F454E284EE14EFC4F004F034F394F564F92
4F8A4F9A4F944FCD504050224FFF501E504650705042509450F450D8514A0000
5164519D51BE51EC5215529C52A652C052DB5300530753245372539353B253DD
FA0E549C548A54A954FF55865759576557AC57C857C7FA0FFA10589E58B2590B
5953595B595D596359A459BA5B565BC0752F5BD85BEC5C1E5CA65CBA5CF55D27
5D53FA115D425D6D5DB85DB95DD05F215F345F675FB75FDE605D6085608A60DE
60D5612060F26111613761306198621362A663F56460649D64CE654E66006615
663B6609662E661E6624666566576659FA126673669966A066B266BF66FA670E
F929676667BB685267C06801684468CFFA136968FA14699869E26A306A6B6A46
6A736A7E6AE26AE46BD66C3F6C5C6C866C6F6CDA6D046D876D6F000000000000
FB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6D966DAC6DCF6DF86DF26DFC6E396E5C6E276E3C6EBF6F886FB56FF570057007
7028708570AB710F7104715C71467147FA1571C171FE72B172BE7324FA167377
73BD73C973D673E373D2740773F57426742A7429742E74627489749F7501756F
7682769C769E769B76A6FA17774652AF7821784E7864787A7930FA18FA190000
FA1A7994FA1B799B7AD17AE7FA1C7AEB7B9EFA1D7D487D5C7DB77DA07DD67E52
7F477FA1FA1E83018362837F83C783F6844884B485538559856BFA1F85B0FA20
FA21880788F58A128A378A798AA78ABE8ADFFA228AF68B538B7F8CF08CF48D12
8D76FA238ECFFA24FA25906790DEFA269115912791DA91D791DE91ED91EE91E4
91E592069210920A923A9240923C924E925992519239926792A79277927892E7
92D792D992D0FA2792D592E092D39325932192FBFA28931E92FF931D93029370
935793A493C693DE93F89431944594489592F9DCFA29969D96AF9733973B9743
974D974F9751975598579865FA2AFA2B9927FA2C999E9A4E9AD9000000000000
FC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9ADC9B759B729B8F9BB19BBB9C009D709D6BFA2D9E199ED10000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/cp936.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
# Encoding file: cp936, multi-byte
M
003F 0 127
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
81
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E024E044E054E064E0F4E124E174E1F4E204E214E234E264E294E2E4E2F4E31
4E334E354E374E3C4E404E414E424E444E464E4A4E514E554E574E5A4E5B4E62
4E634E644E654E674E684E6A4E6B4E6C4E6D4E6E4E6F4E724E744E754E764E77
4E784E794E7A4E7B4E7C4E7D4E7F4E804E814E824E834E844E854E874E8A0000
4E904E964E974E994E9C4E9D4E9E4EA34EAA4EAF4EB04EB14EB44EB64EB74EB8
4EB94EBC4EBD4EBE4EC84ECC4ECF4ED04ED24EDA4EDB4EDC4EE04EE24EE64EE7
4EE94EED4EEE4EEF4EF14EF44EF84EF94EFA4EFC4EFE4F004F024F034F044F05
4F064F074F084F0B4F0C4F124F134F144F154F164F1C4F1D4F214F234F284F29
4F2C4F2D4F2E4F314F334F354F374F394F3B4F3E4F3F4F404F414F424F444F45
4F474F484F494F4A4F4B4F4C4F524F544F564F614F624F664F684F6A4F6B4F6D
4F6E4F714F724F754F774F784F794F7A4F7D4F804F814F824F854F864F874F8A
4F8C4F8E4F904F924F934F954F964F984F994F9A4F9C4F9E4F9F4FA14FA20000
82
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4FA44FAB4FAD4FB04FB14FB24FB34FB44FB64FB74FB84FB94FBA4FBB4FBC4FBD
4FBE4FC04FC14FC24FC64FC74FC84FC94FCB4FCC4FCD4FD24FD34FD44FD54FD6
4FD94FDB4FE04FE24FE44FE54FE74FEB4FEC4FF04FF24FF44FF54FF64FF74FF9
4FFB4FFC4FFD4FFF5000500150025003500450055006500750085009500A0000
500B500E501050115013501550165017501B501D501E50205022502350245027
502B502F5030503150325033503450355036503750385039503B503D503F5040
504150425044504550465049504A504B504D5050505150525053505450565057
50585059505B505D505E505F506050615062506350645066506750685069506A
506B506D506E506F50705071507250735074507550785079507A507C507D5081
508250835084508650875089508A508B508C508E508F50905091509250935094
50955096509750985099509A509B509C509D509E509F50A050A150A250A450A6
50AA50AB50AD50AE50AF50B050B150B350B450B550B650B750B850B950BC0000
83
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
50BD50BE50BF50C050C150C250C350C450C550C650C750C850C950CA50CB50CC
50CD50CE50D050D150D250D350D450D550D750D850D950DB50DC50DD50DE50DF
50E050E150E250E350E450E550E850E950EA50EB50EF50F050F150F250F450F6
50F750F850F950FA50FC50FD50FE50FF51005101510251035104510551080000
5109510A510C510D510E510F511051115113511451155116511751185119511A
511B511C511D511E511F512051225123512451255126512751285129512A512B
512C512D512E512F5130513151325133513451355136513751385139513A513B
513C513D513E51425147514A514C514E514F515051525153515751585159515B
515D515E515F5160516151635164516651675169516A516F5172517A517E517F
5183518451865187518A518B518E518F51905191519351945198519A519D519E
519F51A151A351A651A751A851A951AA51AD51AE51B451B851B951BA51BE51BF
51C151C251C351C551C851CA51CD51CE51D051D251D351D451D551D651D70000
84
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
51D851D951DA51DC51DE51DF51E251E351E551E651E751E851E951EA51EC51EE
51F151F251F451F751FE520452055209520B520C520F5210521352145215521C
521E521F522152225223522552265227522A522C522F5231523252345235523C
523E524452455246524752485249524B524E524F525252535255525752580000
5259525A525B525D525F526052625263526452665268526B526C526D526E5270
52715273527452755276527752785279527A527B527C527E5280528352845285
528652875289528A528B528C528D528E528F5291529252945295529652975298
5299529A529C52A452A552A652A752AE52AF52B052B452B552B652B752B852B9
52BA52BB52BC52BD52C052C152C252C452C552C652C852CA52CC52CD52CE52CF
52D152D352D452D552D752D952DA52DB52DC52DD52DE52E052E152E252E352E5
52E652E752E852E952EA52EB52EC52ED52EE52EF52F152F252F352F452F552F6
52F752F852FB52FC52FD530153025303530453075309530A530B530C530E0000
85
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
53115312531353145318531B531C531E531F532253245325532753285329532B
532C532D532F533053315332533353345335533653375338533C533D53405342
53445346534B534C534D5350535453585359535B535D53655368536A536C536D
537253765379537B537C537D537E53805381538353875388538A538E538F0000
53905391539253935394539653975399539B539C539E53A053A153A453A753AA
53AB53AC53AD53AF53B053B153B253B353B453B553B753B853B953BA53BC53BD
53BE53C053C353C453C553C653C753CE53CF53D053D253D353D553DA53DC53DD
53DE53E153E253E753F453FA53FE53FF5400540254055407540B541454185419
541A541C542254245425542A5430543354365437543A543D543F544154425444
544554475449544C544D544E544F5451545A545D545E545F5460546154635465
54675469546A546B546C546D546E546F547054745479547A547E547F54815483
5485548754885489548A548D5491549354975498549C549E549F54A054A10000
86
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54A254A554AE54B054B254B554B654B754B954BA54BC54BE54C354C554CA54CB
54D654D854DB54E054E154E254E354E454EB54EC54EF54F054F154F454F554F6
54F754F854F954FB54FE550055025503550455055508550A550B550C550D550E
5512551355155516551755185519551A551C551D551E551F5521552555260000
55285529552B552D553255345535553655385539553A553B553D554055425545
55475548554B554C554D554E554F5551555255535554555755585559555A555B
555D555E555F55605562556355685569556B556F557055715572557355745579
557A557D557F55855586558C558D558E559055925593559555965597559A559B
559E55A055A155A255A355A455A555A655A855A955AA55AB55AC55AD55AE55AF
55B055B255B455B655B855BA55BC55BF55C055C155C255C355C655C755C855CA
55CB55CE55CF55D055D555D755D855D955DA55DB55DE55E055E255E755E955ED
55EE55F055F155F455F655F855F955FA55FB55FC55FF56025603560456050000
87
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
56065607560A560B560D561056115612561356145615561656175619561A561C
561D5620562156225625562656285629562A562B562E562F5630563356355637
5638563A563C563D563E5640564156425643564456455646564756485649564A
564B564F565056515652565356555656565A565B565D565E565F566056610000
5663566556665667566D566E566F56705672567356745675567756785679567A
567D567E567F56805681568256835684568756885689568A568B568C568D5690
56915692569456955696569756985699569A569B569C569D569E569F56A056A1
56A256A456A556A656A756A856A956AA56AB56AC56AD56AE56B056B156B256B3
56B456B556B656B856B956BA56BB56BD56BE56BF56C056C156C256C356C456C5
56C656C756C856C956CB56CC56CD56CE56CF56D056D156D256D356D556D656D8
56D956DC56E356E556E656E756E856E956EA56EC56EE56EF56F256F356F656F7
56F856FB56FC57005701570257055707570B570C570D570E570F571057110000
88
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
57125713571457155716571757185719571A571B571D571E5720572157225724
572557265727572B5731573257345735573657375738573C573D573F57415743
57445745574657485749574B5752575357545755575657585759576257635765
5767576C576E5770577157725774577557785779577A577D577E577F57800000
5781578757885789578A578D578E578F57905791579457955796579757985799
579A579C579D579E579F57A557A857AA57AC57AF57B057B157B357B557B657B7
57B957BA57BB57BC57BD57BE57BF57C057C157C457C557C657C757C857C957CA
57CC57CD57D057D157D357D657D757DB57DC57DE57E157E257E357E557E657E7
57E857E957EA57EB57EC57EE57F057F157F257F357F557F657F757FB57FC57FE
57FF580158035804580558085809580A580C580E580F58105812581358145816
58175818581A581B581C581D581F5822582358255826582758285829582B582C
582D582E582F58315832583358345836583758385839583A583B583C583D0000
89
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
583E583F584058415842584358455846584758485849584A584B584E584F5850
585258535855585658575859585A585B585C585D585F58605861586258635864
5866586758685869586A586D586E586F58705871587258735874587558765877
58785879587A587B587C587D587F58825884588658875888588A588B588C0000
588D588E588F5890589158945895589658975898589B589C589D58A058A158A2
58A358A458A558A658A758AA58AB58AC58AD58AE58AF58B058B158B258B358B4
58B558B658B758B858B958BA58BB58BD58BE58BF58C058C258C358C458C658C7
58C858C958CA58CB58CC58CD58CE58CF58D058D258D358D458D658D758D858D9
58DA58DB58DC58DD58DE58DF58E058E158E258E358E558E658E758E858E958EA
58ED58EF58F158F258F458F558F758F858FA58FB58FC58FD58FE58FF59005901
59035905590659085909590A590B590C590E591059115912591359175918591B
591D591E592059215922592359265928592C59305932593359355936593B0000
8A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
593D593E593F5940594359455946594A594C594D5950595259535959595B595C
595D595E595F5961596359645966596759685969596A596B596C596D596E596F
59705971597259755977597A597B597C597E597F598059855989598B598C598E
598F59905991599459955998599A599B599C599D599F59A059A159A259A60000
59A759AC59AD59B059B159B359B459B559B659B759B859BA59BC59BD59BF59C0
59C159C259C359C459C559C759C859C959CC59CD59CE59CF59D559D659D959DB
59DE59DF59E059E159E259E459E659E759E959EA59EB59ED59EE59EF59F059F1
59F259F359F459F559F659F759F859FA59FC59FD59FE5A005A025A0A5A0B5A0D
5A0E5A0F5A105A125A145A155A165A175A195A1A5A1B5A1D5A1E5A215A225A24
5A265A275A285A2A5A2B5A2C5A2D5A2E5A2F5A305A335A355A375A385A395A3A
5A3B5A3D5A3E5A3F5A415A425A435A445A455A475A485A4B5A4C5A4D5A4E5A4F
5A505A515A525A535A545A565A575A585A595A5B5A5C5A5D5A5E5A5F5A600000
8B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5A615A635A645A655A665A685A695A6B5A6C5A6D5A6E5A6F5A705A715A725A73
5A785A795A7B5A7C5A7D5A7E5A805A815A825A835A845A855A865A875A885A89
5A8A5A8B5A8C5A8D5A8E5A8F5A905A915A935A945A955A965A975A985A995A9C
5A9D5A9E5A9F5AA05AA15AA25AA35AA45AA55AA65AA75AA85AA95AAB5AAC0000
5AAD5AAE5AAF5AB05AB15AB45AB65AB75AB95ABA5ABB5ABC5ABD5ABF5AC05AC3
5AC45AC55AC65AC75AC85ACA5ACB5ACD5ACE5ACF5AD05AD15AD35AD55AD75AD9
5ADA5ADB5ADD5ADE5ADF5AE25AE45AE55AE75AE85AEA5AEC5AED5AEE5AEF5AF0
5AF25AF35AF45AF55AF65AF75AF85AF95AFA5AFB5AFC5AFD5AFE5AFF5B005B01
5B025B035B045B055B065B075B085B0A5B0B5B0C5B0D5B0E5B0F5B105B115B12
5B135B145B155B185B195B1A5B1B5B1C5B1D5B1E5B1F5B205B215B225B235B24
5B255B265B275B285B295B2A5B2B5B2C5B2D5B2E5B2F5B305B315B335B355B36
5B385B395B3A5B3B5B3C5B3D5B3E5B3F5B415B425B435B445B455B465B470000
8C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5B485B495B4A5B4B5B4C5B4D5B4E5B4F5B525B565B5E5B605B615B675B685B6B
5B6D5B6E5B6F5B725B745B765B775B785B795B7B5B7C5B7E5B7F5B825B865B8A
5B8D5B8E5B905B915B925B945B965B9F5BA75BA85BA95BAC5BAD5BAE5BAF5BB1
5BB25BB75BBA5BBB5BBC5BC05BC15BC35BC85BC95BCA5BCB5BCD5BCE5BCF0000
5BD15BD45BD55BD65BD75BD85BD95BDA5BDB5BDC5BE05BE25BE35BE65BE75BE9
5BEA5BEB5BEC5BED5BEF5BF15BF25BF35BF45BF55BF65BF75BFD5BFE5C005C02
5C035C055C075C085C0B5C0C5C0D5C0E5C105C125C135C175C195C1B5C1E5C1F
5C205C215C235C265C285C295C2A5C2B5C2D5C2E5C2F5C305C325C335C355C36
5C375C435C445C465C475C4C5C4D5C525C535C545C565C575C585C5A5C5B5C5C
5C5D5C5F5C625C645C675C685C695C6A5C6B5C6C5C6D5C705C725C735C745C75
5C765C775C785C7B5C7C5C7D5C7E5C805C835C845C855C865C875C895C8A5C8B
5C8E5C8F5C925C935C955C9D5C9E5C9F5CA05CA15CA45CA55CA65CA75CA80000
8D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5CAA5CAE5CAF5CB05CB25CB45CB65CB95CBA5CBB5CBC5CBE5CC05CC25CC35CC5
5CC65CC75CC85CC95CCA5CCC5CCD5CCE5CCF5CD05CD15CD35CD45CD55CD65CD7
5CD85CDA5CDB5CDC5CDD5CDE5CDF5CE05CE25CE35CE75CE95CEB5CEC5CEE5CEF
5CF15CF25CF35CF45CF55CF65CF75CF85CF95CFA5CFC5CFD5CFE5CFF5D000000
5D015D045D055D085D095D0A5D0B5D0C5D0D5D0F5D105D115D125D135D155D17
5D185D195D1A5D1C5D1D5D1F5D205D215D225D235D255D285D2A5D2B5D2C5D2F
5D305D315D325D335D355D365D375D385D395D3A5D3B5D3C5D3F5D405D415D42
5D435D445D455D465D485D495D4D5D4E5D4F5D505D515D525D535D545D555D56
5D575D595D5A5D5C5D5E5D5F5D605D615D625D635D645D655D665D675D685D6A
5D6D5D6E5D705D715D725D735D755D765D775D785D795D7A5D7B5D7C5D7D5D7E
5D7F5D805D815D835D845D855D865D875D885D895D8A5D8B5D8C5D8D5D8E5D8F
5D905D915D925D935D945D955D965D975D985D9A5D9B5D9C5D9E5D9F5DA00000
8E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5DA15DA25DA35DA45DA55DA65DA75DA85DA95DAA5DAB5DAC5DAD5DAE5DAF5DB0
5DB15DB25DB35DB45DB55DB65DB85DB95DBA5DBB5DBC5DBD5DBE5DBF5DC05DC1
5DC25DC35DC45DC65DC75DC85DC95DCA5DCB5DCC5DCE5DCF5DD05DD15DD25DD3
5DD45DD55DD65DD75DD85DD95DDA5DDC5DDF5DE05DE35DE45DEA5DEC5DED0000
5DF05DF55DF65DF85DF95DFA5DFB5DFC5DFF5E005E045E075E095E0A5E0B5E0D
5E0E5E125E135E175E1E5E1F5E205E215E225E235E245E255E285E295E2A5E2B
5E2C5E2F5E305E325E335E345E355E365E395E3A5E3E5E3F5E405E415E435E46
5E475E485E495E4A5E4B5E4D5E4E5E4F5E505E515E525E535E565E575E585E59
5E5A5E5C5E5D5E5F5E605E635E645E655E665E675E685E695E6A5E6B5E6C5E6D
5E6E5E6F5E705E715E755E775E795E7E5E815E825E835E855E885E895E8C5E8D
5E8E5E925E985E9B5E9D5EA15EA25EA35EA45EA85EA95EAA5EAB5EAC5EAE5EAF
5EB05EB15EB25EB45EBA5EBB5EBC5EBD5EBF5EC05EC15EC25EC35EC45EC50000
8F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5EC65EC75EC85ECB5ECC5ECD5ECE5ECF5ED05ED45ED55ED75ED85ED95EDA5EDC
5EDD5EDE5EDF5EE05EE15EE25EE35EE45EE55EE65EE75EE95EEB5EEC5EED5EEE
5EEF5EF05EF15EF25EF35EF55EF85EF95EFB5EFC5EFD5F055F065F075F095F0C
5F0D5F0E5F105F125F145F165F195F1A5F1C5F1D5F1E5F215F225F235F240000
5F285F2B5F2C5F2E5F305F325F335F345F355F365F375F385F3B5F3D5F3E5F3F
5F415F425F435F445F455F465F475F485F495F4A5F4B5F4C5F4D5F4E5F4F5F51
5F545F595F5A5F5B5F5C5F5E5F5F5F605F635F655F675F685F6B5F6E5F6F5F72
5F745F755F765F785F7A5F7D5F7E5F7F5F835F865F8D5F8E5F8F5F915F935F94
5F965F9A5F9B5F9D5F9E5F9F5FA05FA25FA35FA45FA55FA65FA75FA95FAB5FAC
5FAF5FB05FB15FB25FB35FB45FB65FB85FB95FBA5FBB5FBE5FBF5FC05FC15FC2
5FC75FC85FCA5FCB5FCE5FD35FD45FD55FDA5FDB5FDC5FDE5FDF5FE25FE35FE5
5FE65FE85FE95FEC5FEF5FF05FF25FF35FF45FF65FF75FF95FFA5FFC60070000
90
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
60086009600B600C60106011601360176018601A601E601F602260236024602C
602D602E603060316032603360346036603760386039603A603D603E60406044
60456046604760486049604A604C604E604F605160536054605660576058605B
605C605E605F6060606160656066606E60716072607460756077607E60800000
608160826085608660876088608A608B608E608F609060916093609560976098
6099609C609E60A160A260A460A560A760A960AA60AE60B060B360B560B660B7
60B960BA60BD60BE60BF60C060C160C260C360C460C760C860C960CC60CD60CE
60CF60D060D260D360D460D660D760D960DB60DE60E160E260E360E460E560EA
60F160F260F560F760F860FB60FC60FD60FE60FF61026103610461056107610A
610B610C611061116112611361146116611761186119611B611C611D611E6121
6122612561286129612A612C612D612E612F6130613161326133613461356136
613761386139613A613B613C613D613E61406141614261436144614561460000
91
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
61476149614B614D614F61506152615361546156615761586159615A615B615C
615E615F6160616161636164616561666169616A616B616C616D616E616F6171
617261736174617661786179617A617B617C617D617E617F6180618161826183
618461856186618761886189618A618C618D618F619061916192619361950000
6196619761986199619A619B619C619E619F61A061A161A261A361A461A561A6
61AA61AB61AD61AE61AF61B061B161B261B361B461B561B661B861B961BA61BB
61BC61BD61BF61C061C161C361C461C561C661C761C961CC61CD61CE61CF61D0
61D361D561D661D761D861D961DA61DB61DC61DD61DE61DF61E061E161E261E3
61E461E561E761E861E961EA61EB61EC61ED61EE61EF61F061F161F261F361F4
61F661F761F861F961FA61FB61FC61FD61FE6200620162026203620462056207
6209621362146219621C621D621E622062236226622762286229622B622D622F
6230623162326235623662386239623A623B623C6242624462456246624A0000
92
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
624F62506255625662576259625A625C625D625E625F62606261626262646265
6268627162726274627562776278627A627B627D628162826283628562866287
6288628B628C628D628E628F629062946299629C629D629E62A362A662A762A9
62AA62AD62AE62AF62B062B262B362B462B662B762B862BA62BE62C062C10000
62C362CB62CF62D162D562DD62DE62E062E162E462EA62EB62F062F262F562F8
62F962FA62FB63006303630463056306630A630B630C630D630F631063126313
63146315631763186319631C632663276329632C632D632E6330633163336334
6335633663376338633B633C633E633F63406341634463476348634A63516352
635363546356635763586359635A635B635C635D63606364636563666368636A
636B636C636F6370637263736374637563786379637C637D637E637F63816383
638463856386638B638D639163936394639563976399639A639B639C639D639E
639F63A163A463A663AB63AF63B163B263B563B663B963BB63BD63BF63C00000
93
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
63C163C263C363C563C763C863CA63CB63CC63D163D363D463D563D763D863D9
63DA63DB63DC63DD63DF63E263E463E563E663E763E863EB63EC63EE63EF63F0
63F163F363F563F763F963FA63FB63FC63FE640364046406640764086409640A
640D640E6411641264156416641764186419641A641D641F6422642364240000
6425642764286429642B642E642F643064316432643364356436643764386439
643B643C643E6440644264436449644B644C644D644E644F6450645164536455
645664576459645A645B645C645D645F64606461646264636464646564666468
646A646B646C646E646F64706471647264736474647564766477647B647C647D
647E647F648064816483648664886489648A648B648C648D648E648F64906493
649464976498649A649B649C649D649F64A064A164A264A364A564A664A764A8
64AA64AB64AF64B164B264B364B464B664B964BB64BD64BE64BF64C164C364C4
64C664C764C864C964CA64CB64CC64CF64D164D364D464D564D664D964DA0000
94
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
64DB64DC64DD64DF64E064E164E364E564E764E864E964EA64EB64EC64ED64EE
64EF64F064F164F264F364F464F564F664F764F864F964FA64FB64FC64FD64FE
64FF65016502650365046505650665076508650A650B650C650D650E650F6510
6511651365146515651665176519651A651B651C651D651E651F652065210000
6522652365246526652765286529652A652C652D65306531653265336537653A
653C653D6540654165426543654465466547654A654B654D654E655065526553
655465576558655A655C655F6560656165646565656765686569656A656D656E
656F657165736575657665786579657A657B657C657D657E657F658065816582
658365846585658665886589658A658D658E658F65926594659565966598659A
659D659E65A065A265A365A665A865AA65AC65AE65B165B265B365B465B565B6
65B765B865BA65BB65BE65BF65C065C265C765C865C965CA65CD65D065D165D3
65D465D565D865D965DA65DB65DC65DD65DE65DF65E165E365E465EA65EB0000
95
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
65F265F365F465F565F865F965FB65FC65FD65FE65FF66016604660566076608
6609660B660D661066116612661666176618661A661B661C661E662166226623
662466266629662A662B662C662E663066326633663766386639663A663B663D
663F66406642664466456646664766486649664A664D664E6650665166580000
6659665B665C665D665E666066626663666566676669666A666B666C666D6671
66726673667566786679667B667C667D667F6680668166836685668666886689
668A668B668D668E668F6690669266936694669566986699669A669B669C669E
669F66A066A166A266A366A466A566A666A966AA66AB66AC66AD66AF66B066B1
66B266B366B566B666B766B866BA66BB66BC66BD66BF66C066C166C266C366C4
66C566C666C766C866C966CA66CB66CC66CD66CE66CF66D066D166D266D366D4
66D566D666D766D866DA66DE66DF66E066E166E266E366E466E566E766E866EA
66EB66EC66ED66EE66EF66F166F566F666F866FA66FB66FD6701670267030000
96
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6704670567066707670C670E670F671167126713671667186719671A671C671E
67206721672267236724672567276729672E6730673267336736673767386739
673B673C673E673F6741674467456747674A674B674D67526754675567576758
6759675A675B675D67626763676467666767676B676C676E6771677467760000
67786779677A677B677D678067826783678567866788678A678C678D678E678F
679167926793679467966799679B679F67A067A167A467A667A967AC67AE67B1
67B267B467B967BA67BB67BC67BD67BE67BF67C067C267C567C667C767C867C9
67CA67CB67CC67CD67CE67D567D667D767DB67DF67E167E367E467E667E767E8
67EA67EB67ED67EE67F267F567F667F767F867F967FA67FB67FC67FE68016802
680368046806680D681068126814681568186819681A681B681C681E681F6820
6822682368246825682668276828682B682C682D682E682F6830683168346835
6836683A683B683F6847684B684D684F68526856685768586859685A685B0000
97
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
685C685D685E685F686A686C686D686E686F6870687168726873687568786879
687A687B687C687D687E687F688068826884688768886889688A688B688C688D
688E68906891689268946895689668986899689A689B689C689D689E689F68A0
68A168A368A468A568A968AA68AB68AC68AE68B168B268B468B668B768B80000
68B968BA68BB68BC68BD68BE68BF68C168C368C468C568C668C768C868CA68CC
68CE68CF68D068D168D368D468D668D768D968DB68DC68DD68DE68DF68E168E2
68E468E568E668E768E868E968EA68EB68EC68ED68EF68F268F368F468F668F7
68F868FB68FD68FE68FF69006902690369046906690769086909690A690C690F
69116913691469156916691769186919691A691B691C691D691E692169226923
69256926692769286929692A692B692C692E692F693169326933693569366937
6938693A693B693C693E694069416943694469456946694769486949694A694B
694C694D694E694F69506951695269536955695669586959695B695C695F0000
98
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6961696269646965696769686969696A696C696D696F69706972697369746975
6976697A697B697D697E697F698169836985698A698B698C698E698F69906991
69926993699669976999699A699D699E699F69A069A169A269A369A469A569A6
69A969AA69AC69AE69AF69B069B269B369B569B669B869B969BA69BC69BD0000
69BE69BF69C069C269C369C469C569C669C769C869C969CB69CD69CF69D169D2
69D369D569D669D769D869D969DA69DC69DD69DE69E169E269E369E469E569E6
69E769E869E969EA69EB69EC69EE69EF69F069F169F369F469F569F669F769F8
69F969FA69FB69FC69FE6A006A016A026A036A046A056A066A076A086A096A0B
6A0C6A0D6A0E6A0F6A106A116A126A136A146A156A166A196A1A6A1B6A1C6A1D
6A1E6A206A226A236A246A256A266A276A296A2B6A2C6A2D6A2E6A306A326A33
6A346A366A376A386A396A3A6A3B6A3C6A3F6A406A416A426A436A456A466A48
6A496A4A6A4B6A4C6A4D6A4E6A4F6A516A526A536A546A556A566A576A5A0000
99
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A5C6A5D6A5E6A5F6A606A626A636A646A666A676A686A696A6A6A6B6A6C6A6D
6A6E6A6F6A706A726A736A746A756A766A776A786A7A6A7B6A7D6A7E6A7F6A81
6A826A836A856A866A876A886A896A8A6A8B6A8C6A8D6A8F6A926A936A946A95
6A966A986A996A9A6A9B6A9C6A9D6A9E6A9F6AA16AA26AA36AA46AA56AA60000
6AA76AA86AAA6AAD6AAE6AAF6AB06AB16AB26AB36AB46AB56AB66AB76AB86AB9
6ABA6ABB6ABC6ABD6ABE6ABF6AC06AC16AC26AC36AC46AC56AC66AC76AC86AC9
6ACA6ACB6ACC6ACD6ACE6ACF6AD06AD16AD26AD36AD46AD56AD66AD76AD86AD9
6ADA6ADB6ADC6ADD6ADE6ADF6AE06AE16AE26AE36AE46AE56AE66AE76AE86AE9
6AEA6AEB6AEC6AED6AEE6AEF6AF06AF16AF26AF36AF46AF56AF66AF76AF86AF9
6AFA6AFB6AFC6AFD6AFE6AFF6B006B016B026B036B046B056B066B076B086B09
6B0A6B0B6B0C6B0D6B0E6B0F6B106B116B126B136B146B156B166B176B186B19
6B1A6B1B6B1C6B1D6B1E6B1F6B256B266B286B296B2A6B2B6B2C6B2D6B2E0000
9A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6B2F6B306B316B336B346B356B366B386B3B6B3C6B3D6B3F6B406B416B426B44
6B456B486B4A6B4B6B4D6B4E6B4F6B506B516B526B536B546B556B566B576B58
6B5A6B5B6B5C6B5D6B5E6B5F6B606B616B686B696B6B6B6C6B6D6B6E6B6F6B70
6B716B726B736B746B756B766B776B786B7A6B7D6B7E6B7F6B806B856B880000
6B8C6B8E6B8F6B906B916B946B956B976B986B996B9C6B9D6B9E6B9F6BA06BA2
6BA36BA46BA56BA66BA76BA86BA96BAB6BAC6BAD6BAE6BAF6BB06BB16BB26BB6
6BB86BB96BBA6BBB6BBC6BBD6BBE6BC06BC36BC46BC66BC76BC86BC96BCA6BCC
6BCE6BD06BD16BD86BDA6BDC6BDD6BDE6BDF6BE06BE26BE36BE46BE56BE66BE7
6BE86BE96BEC6BED6BEE6BF06BF16BF26BF46BF66BF76BF86BFA6BFB6BFC6BFE
6BFF6C006C016C026C036C046C086C096C0A6C0B6C0C6C0E6C126C176C1C6C1D
6C1E6C206C236C256C2B6C2C6C2D6C316C336C366C376C396C3A6C3B6C3C6C3E
6C3F6C436C446C456C486C4B6C4C6C4D6C4E6C4F6C516C526C536C566C580000
9B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6C596C5A6C626C636C656C666C676C6B6C6C6C6D6C6E6C6F6C716C736C756C77
6C786C7A6C7B6C7C6C7F6C806C846C876C8A6C8B6C8D6C8E6C916C926C956C96
6C976C986C9A6C9C6C9D6C9E6CA06CA26CA86CAC6CAF6CB06CB46CB56CB66CB7
6CBA6CC06CC16CC26CC36CC66CC76CC86CCB6CCD6CCE6CCF6CD16CD26CD80000
6CD96CDA6CDC6CDD6CDF6CE46CE66CE76CE96CEC6CED6CF26CF46CF96CFF6D00
6D026D036D056D066D086D096D0A6D0D6D0F6D106D116D136D146D156D166D18
6D1C6D1D6D1F6D206D216D226D236D246D266D286D296D2C6D2D6D2F6D306D34
6D366D376D386D3A6D3F6D406D426D446D496D4C6D506D556D566D576D586D5B
6D5D6D5F6D616D626D646D656D676D686D6B6D6C6D6D6D706D716D726D736D75
6D766D796D7A6D7B6D7D6D7E6D7F6D806D816D836D846D866D876D8A6D8B6D8D
6D8F6D906D926D966D976D986D996D9A6D9C6DA26DA56DAC6DAD6DB06DB16DB3
6DB46DB66DB76DB96DBA6DBB6DBC6DBD6DBE6DC16DC26DC36DC86DC96DCA0000
9C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6DCD6DCE6DCF6DD06DD26DD36DD46DD56DD76DDA6DDB6DDC6DDF6DE26DE36DE5
6DE76DE86DE96DEA6DED6DEF6DF06DF26DF46DF56DF66DF86DFA6DFD6DFE6DFF
6E006E016E026E036E046E066E076E086E096E0B6E0F6E126E136E156E186E19
6E1B6E1C6E1E6E1F6E226E266E276E286E2A6E2C6E2E6E306E316E336E350000
6E366E376E396E3B6E3C6E3D6E3E6E3F6E406E416E426E456E466E476E486E49
6E4A6E4B6E4C6E4F6E506E516E526E556E576E596E5A6E5C6E5D6E5E6E606E61
6E626E636E646E656E666E676E686E696E6A6E6C6E6D6E6F6E706E716E726E73
6E746E756E766E776E786E796E7A6E7B6E7C6E7D6E806E816E826E846E876E88
6E8A6E8B6E8C6E8D6E8E6E916E926E936E946E956E966E976E996E9A6E9B6E9D
6E9E6EA06EA16EA36EA46EA66EA86EA96EAB6EAC6EAD6EAE6EB06EB36EB56EB8
6EB96EBC6EBE6EBF6EC06EC36EC46EC56EC66EC86EC96ECA6ECC6ECD6ECE6ED0
6ED26ED66ED86ED96EDB6EDC6EDD6EE36EE76EEA6EEB6EEC6EED6EEE6EEF0000
9D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6EF06EF16EF26EF36EF56EF66EF76EF86EFA6EFB6EFC6EFD6EFE6EFF6F006F01
6F036F046F056F076F086F0A6F0B6F0C6F0D6F0E6F106F116F126F166F176F18
6F196F1A6F1B6F1C6F1D6F1E6F1F6F216F226F236F256F266F276F286F2C6F2E
6F306F326F346F356F376F386F396F3A6F3B6F3C6F3D6F3F6F406F416F420000
6F436F446F456F486F496F4A6F4C6F4E6F4F6F506F516F526F536F546F556F56
6F576F596F5A6F5B6F5D6F5F6F606F616F636F646F656F676F686F696F6A6F6B
6F6C6F6F6F706F716F736F756F766F776F796F7B6F7D6F7E6F7F6F806F816F82
6F836F856F866F876F8A6F8B6F8F6F906F916F926F936F946F956F966F976F98
6F996F9A6F9B6F9D6F9E6F9F6FA06FA26FA36FA46FA56FA66FA86FA96FAA6FAB
6FAC6FAD6FAE6FAF6FB06FB16FB26FB46FB56FB76FB86FBA6FBB6FBC6FBD6FBE
6FBF6FC16FC36FC46FC56FC66FC76FC86FCA6FCB6FCC6FCD6FCE6FCF6FD06FD3
6FD46FD56FD66FD76FD86FD96FDA6FDB6FDC6FDD6FDF6FE26FE36FE46FE50000
9E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6FE66FE76FE86FE96FEA6FEB6FEC6FED6FF06FF16FF26FF36FF46FF56FF66FF7
6FF86FF96FFA6FFB6FFC6FFD6FFE6FFF70007001700270037004700570067007
70087009700A700B700C700D700E700F70107012701370147015701670177018
7019701C701D701E701F702070217022702470257026702770287029702A0000
702B702C702D702E702F70307031703270337034703670377038703A703B703C
703D703E703F7040704170427043704470457046704770487049704A704B704D
704E7050705170527053705470557056705770587059705A705B705C705D705F
7060706170627063706470657066706770687069706A706E7071707270737074
70777079707A707B707D7081708270837084708670877088708B708C708D708F
70907091709370977098709A709B709E709F70A070A170A270A370A470A570A6
70A770A870A970AA70B070B270B470B570B670BA70BE70BF70C470C570C670C7
70C970CB70CC70CD70CE70CF70D070D170D270D370D470D570D670D770DA0000
9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
70DC70DD70DE70E070E170E270E370E570EA70EE70F070F170F270F370F470F5
70F670F870FA70FB70FC70FE70FF710071017102710371047105710671077108
710B710C710D710E710F7111711271147117711B711C711D711E711F71207121
7122712371247125712771287129712A712B712C712D712E7132713371340000
7135713771387139713A713B713C713D713E713F714071417142714371447146
714771487149714B714D714F7150715171527153715471557156715771587159
715A715B715D715F716071617162716371657169716A716B716C716D716F7170
717171747175717671777179717B717C717E717F718071817182718371857186
718771887189718B718C718D718E7190719171927193719571967197719A719B
719C719D719E71A171A271A371A471A571A671A771A971AA71AB71AD71AE71AF
71B071B171B271B471B671B771B871BA71BB71BC71BD71BE71BF71C071C171C2
71C471C571C671C771C871C971CA71CB71CC71CD71CF71D071D171D271D30000
A0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
71D671D771D871D971DA71DB71DC71DD71DE71DF71E171E271E371E471E671E8
71E971EA71EB71EC71ED71EF71F071F171F271F371F471F571F671F771F871FA
71FB71FC71FD71FE71FF720072017202720372047205720772087209720A720B
720C720D720E720F7210721172127213721472157216721772187219721A0000
721B721C721E721F722072217222722372247225722672277229722B722D722E
722F723272337234723A723C723E72407241724272437244724572467249724A
724B724E724F7250725172537254725572577258725A725C725E726072637264
72657268726A726B726C726D7270727172737274727672777278727B727C727D
7282728372857286728772887289728C728E7290729172937294729572967297
72987299729A729B729C729D729E72A072A172A272A372A472A572A672A772A8
72A972AA72AB72AE72B172B272B372B572BA72BB72BC72BD72BE72BF72C072C5
72C672C772C972CA72CB72CC72CF72D172D372D472D572D672D872DA72DB0000
A1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030003001300200B702C902C700A8300330052014FF5E2016202620182019
201C201D3014301530083009300A300B300C300D300E300F3016301730103011
00B100D700F72236222722282211220F222A222922082237221A22A522252220
23122299222B222E2261224C2248223D221D2260226E226F22642265221E2235
22342642264000B0203220332103FF0400A4FFE0FFE1203000A7211626062605
25CB25CF25CE25C725C625A125A025B325B2203B219221902191219330130000
A2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000217021712172217321742175217621772178217900000000000000000000
000024882489248A248B248C248D248E248F2490249124922493249424952496
249724982499249A249B247424752476247724782479247A247B247C247D247E
247F248024812482248324842485248624872460246124622463246424652466
2467246824690000000032203221322232233224322532263227322832290000
00002160216121622163216421652166216721682169216A216B000000000000
A3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF01FF02FF03FFE5FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFF3CFF3DFF3EFF3F
FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
A4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000304130423043304430453046304730483049304A304B304C304D304E304F
3050305130523053305430553056305730583059305A305B305C305D305E305F
3060306130623063306430653066306730683069306A306B306C306D306E306F
3070307130723073307430753076307730783079307A307B307C307D307E307F
3080308130823083308430853086308730883089308A308B308C308D308E308F
3090309130923093000000000000000000000000000000000000000000000000
A5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000000
A6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000039103920393039403950396039703980399039A039B039C039D039E039F
03A003A103A303A403A503A603A703A803A90000000000000000000000000000
000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C303C403C503C603C703C803C90000000000000000000000000000
FE35FE36FE39FE3AFE3FFE40FE3DFE3EFE41FE42FE43FE4400000000FE3BFE3C
FE37FE38FE310000FE33FE340000000000000000000000000000000000000000
A7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000004100411041204130414041504010416041704180419041A041B041C041D
041E041F0420042104220423042404250426042704280429042A042B042C042D
042E042F00000000000000000000000000000000000000000000000000000000
000004300431043204330434043504510436043704380439043A043B043C043D
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000000000
A8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
02CA02CB02D920132015202520352105210921962197219821992215221F2223
22522266226722BF2550255125522553255425552556255725582559255A255B
255C255D255E255F2560256125622563256425652566256725682569256A256B
256C256D256E256F257025712572257325812582258325842585258625870000
25882589258A258B258C258D258E258F25932594259525BC25BD25E225E325E4
25E5260922953012301D301E0000000000000000000000000000000000000000
0000010100E101CE00E0011300E9011B00E8012B00ED01D000EC014D00F301D2
00F2016B00FA01D400F901D601D801DA01DC00FC00EA02510000014401480000
0261000000000000000031053106310731083109310A310B310C310D310E310F
3110311131123113311431153116311731183119311A311B311C311D311E311F
3120312131223123312431253126312731283129000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
30213022302330243025302630273028302932A3338E338F339C339D339E33A1
33C433CE33D133D233D5FE30FFE2FFE400002121323100002010000000000000
30FC309B309C30FD30FE3006309D309EFE49FE4AFE4BFE4CFE4DFE4EFE4FFE50
FE51FE52FE54FE55FE56FE57FE59FE5AFE5BFE5CFE5DFE5EFE5FFE60FE610000
FE62FE63FE64FE65FE66FE68FE69FE6AFE6B0000000000000000000000000000
0000000000000000000000003007000000000000000000000000000000000000
00000000000000002500250125022503250425052506250725082509250A250B
250C250D250E250F2510251125122513251425152516251725182519251A251B
251C251D251E251F2520252125222523252425252526252725282529252A252B
252C252D252E252F2530253125322533253425352536253725382539253A253B
253C253D253E253F2540254125422543254425452546254725482549254A254B
0000000000000000000000000000000000000000000000000000000000000000
AA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
72DC72DD72DF72E272E372E472E572E672E772EA72EB72F572F672F972FD72FE
72FF73007302730473057306730773087309730B730C730D730F731073117312
731473187319731A731F732073237324732673277328732D732F733073327333
73357336733A733B733C733D7340734173427343734473457346734773480000
7349734A734B734C734E734F7351735373547355735673587359735A735B735C
735D735E735F736173627363736473657366736773687369736A736B736E7370
7371000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
AB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
73727373737473757376737773787379737A737B737C737D737F738073817382
7383738573867388738A738C738D738F73907392739373947395739773987399
739A739C739D739E73A073A173A373A473A573A673A773A873AA73AC73AD73B1
73B473B573B673B873B973BC73BD73BE73BF73C173C373C473C573C673C70000
73CB73CC73CE73D273D373D473D573D673D773D873DA73DB73DC73DD73DF73E1
73E273E373E473E673E873EA73EB73EC73EE73EF73F073F173F373F473F573F6
73F7000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
AC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
73F873F973FA73FB73FC73FD73FE73FF740074017402740474077408740B740C
740D740E741174127413741474157416741774187419741C741D741E741F7420
74217423742474277429742B742D742F74317432743774387439743A743B743D
743E743F744074427443744474457446744774487449744A744B744C744D0000
744E744F7450745174527453745474567458745D746074617462746374647465
7466746774687469746A746B746C746E746F7471747274737474747574787479
747A000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
AD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
747B747C747D747F748274847485748674887489748A748C748D748F74917492
7493749474957496749774987499749A749B749D749F74A074A174A274A374A4
74A574A674AA74AB74AC74AD74AE74AF74B074B174B274B374B474B574B674B7
74B874B974BB74BC74BD74BE74BF74C074C174C274C374C474C574C674C70000
74C874C974CA74CB74CC74CD74CE74CF74D074D174D374D474D574D674D774D8
74D974DA74DB74DD74DF74E174E574E774E874E974EA74EB74EC74ED74F074F1
74F2000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
AE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
74F374F574F874F974FA74FB74FC74FD74FE7500750175027503750575067507
75087509750A750B750C750E751075127514751575167517751B751D751E7520
752175227523752475267527752A752E753475367539753C753D753F75417542
75437544754675477549754A754D755075517552755375557556755775580000
755D755E755F75607561756275637564756775687569756B756C756D756E756F
757075717573757575767577757A757B757C757D757E75807581758275847585
7587000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
AF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
75887589758A758C758D758E7590759375957598759B759C759E75A275A675A7
75A875A975AA75AD75B675B775BA75BB75BF75C075C175C675CB75CC75CE75CF
75D075D175D375D775D975DA75DC75DD75DF75E075E175E575E975EC75ED75EE
75EF75F275F375F575F675F775F875FA75FB75FD75FE76027604760676070000
76087609760B760D760E760F76117612761376147616761A761C761D761E7621
762376277628762C762E762F76317632763676377639763A763B763D76417642
7644000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
B0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
76457646764776487649764A764B764E764F7650765176527653765576577658
7659765A765B765D765F766076617662766476657666766776687669766A766C
766D766E767076717672767376747675767676777679767A767C767F76807681
768376857689768A768C768D768F769076927694769576977698769A769B0000
769C769D769E769F76A076A176A276A376A576A676A776A876A976AA76AB76AC
76AD76AF76B076B376B576B676B776B876B976BA76BB76BC76BD76BE76C076C1
76C3554A963F57C3632854CE550954C07691764C853C77EE827E788D72319698
978D6C285B894FFA630966975CB880FA684880AE660276CE51F9655671AC7FF1
888450B2596561CA6FB382AD634C625253ED54277B06516B75A45DF462D48DCB
9776628A8019575D97387F627238767D67CF767E64464F708D2562DC7A176591
73ED642C6273822C9881677F7248626E62CC4F3474E3534A529E7ECA90A65E2E
6886699C81807ED168D278C5868C9551508D8C2482DE80DE5305891252650000
B1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
76C476C776C976CB76CC76D376D576D976DA76DC76DD76DE76E076E176E276E3
76E476E676E776E876E976EA76EB76EC76ED76F076F376F576F676F776FA76FB
76FD76FF77007702770377057706770A770C770E770F77107711771277137714
7715771677177718771B771C771D771E77217723772477257727772A772B0000
772C772E773077317732773377347739773B773D773E773F7742774477457746
77487749774A774B774C774D774E774F77527753775477557756775777587759
775C858496F94FDD582199715B9D62B162A566B48C799C8D7206676F789160B2
535153178F8880CC8D1D94A1500D72C8590760EB711988AB595482EF672C7B28
5D297EF7752D6CF58E668FF8903C9F3B6BD491197B145F7C78A784D6853D6BD5
6BD96BD65E015E8775F995ED655D5F0A5FC58F9F58C181C2907F965B97AD8FB9
7F168D2C62414FBF53D8535E8FA88FA98FAB904D68075F6A819888689CD6618B
522B762A5F6C658C6FD26EE85BBE6448517551B067C44E1979C9997C70B30000
B2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
775D775E775F7760776477677769776A776D776E776F77707771777277737774
7775777677777778777A777B777C7781778277837786778777887789778A778B
778F77907793779477957796779777987799779A779B779C779D779E77A177A3
77A477A677A877AB77AD77AE77AF77B177B277B477B677B777B877B977BA0000
77BC77BE77C077C177C277C377C477C577C677C777C877C977CA77CB77CC77CE
77CF77D077D177D277D377D477D577D677D877D977DA77DD77DE77DF77E077E1
77E475C55E7673BB83E064AD62E894B56CE2535A52C3640F94C27B944F2F5E1B
82368116818A6E246CCA9A736355535C54FA886557E04E0D5E036B657C3F90E8
601664E6731C88C16750624D8D22776C8E2991C75F6983DC8521991053C28695
6B8B60ED60E8707F82CD82314ED36CA785CF64CD7CD969FD66F9834953957B56
4FA7518C6D4B5C428E6D63D253C9832C833667E578B4643D5BDF5C945DEE8BE7
62C667F48C7A640063BA8749998B8C177F2094F24EA7961098A4660C73160000
B3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
77E677E877EA77EF77F077F177F277F477F577F777F977FA77FB77FC78037804
7805780678077808780A780B780E780F7810781378157819781B781E78207821
782278247828782A782B782E782F78317832783378357836783D783F78417842
78437844784678487849784A784B784D784F78517853785478587859785A0000
785B785C785E785F7860786178627863786478657866786778687869786F7870
78717872787378747875787678787879787A787B787D787E787F788078817882
7883573A5C1D5E38957F507F80A05382655E7545553150218D856284949E671D
56326F6E5DE2543570928F66626F64A463A35F7B6F8890F481E38FB05C186668
5FF16C8996488D81886C649179F057CE6A59621054484E587A0B60E96F848BDA
627F901E9A8B79E4540375F4630153196C608FDF5F1B9A70803B9F7F4F885C3A
8D647FC565A570BD514551B2866B5D075BA062BD916C75748E0C7A2061017B79
4EC77EF877854E1181ED521D51FA6A7153A88E87950496CF6EC19664695A0000
B4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7884788578867888788A788B788F789078927894789578967899789D789E78A0
78A278A478A678A878A978AA78AB78AC78AD78AE78AF78B578B678B778B878BA
78BB78BC78BD78BF78C078C278C378C478C678C778C878CC78CD78CE78CF78D1
78D278D378D678D778D878DA78DB78DC78DD78DE78DF78E078E178E278E30000
78E478E578E678E778E978EA78EB78ED78EE78EF78F078F178F378F578F678F8
78F978FB78FC78FD78FE78FF79007902790379047906790779087909790A790B
790C784050A877D7641089E6590463E35DDD7A7F693D4F20823955984E3275AE
7A975E625E8A95EF521B5439708A6376952457826625693F918755076DF37EAF
882262337EF075B5832878C196CC8F9E614874F78BCD6B64523A8D506B21806A
847156F153064ECE4E1B51D17C97918B7C074FC38E7F7BE17A9C64675D1450AC
810676017CB96DEC7FE067515B585BF878CB64AE641363AA632B9519642D8FBE
7B5476296253592754466B7950A362345E266B864EE38D37888B5F85902E0000
B5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
790D790E790F791079117912791479157916791779187919791A791B791C791D
791F792079217922792379257926792779287929792A792B792C792D792E792F
793079317932793379357936793779387939793D793F79427943794479457947
794A794B794C794D794E794F7950795179527954795579587959796179630000
796479667969796A796B796C796E79707971797279737974797579767979797B
797C797D797E797F798279837986798779887989798B798C798D798E79907991
79926020803D62C54E39535590F863B880C665E66C2E4F4660EE6DE18BDE5F39
86CB5F536321515A83616863520063638E4850125C9B79775BFC52307A3B60BC
905376D75FB75F9776848E6C706F767B7B4977AA51F3909358244F4E6EF48FEA
654C7B1B72C46DA47FDF5AE162B55E95573084827B2C5E1D5F1F90127F1498A0
63826EC7789870B95178975B57AB75354F4375385E9760E659606DC06BBF7889
53FC96D551CB52016389540A94938C038DCC7239789F87768FED8C0D53E00000
B6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7993799479957996799779987999799B799C799D799E799F79A079A179A279A3
79A479A579A679A879A979AA79AB79AC79AD79AE79AF79B079B179B279B479B5
79B679B779B879BC79BF79C279C479C579C779C879CA79CC79CE79CF79D079D3
79D479D679D779D979DA79DB79DC79DD79DE79E079E179E279E579E879EA0000
79EC79EE79F179F279F379F479F579F679F779F979FA79FC79FE79FF7A017A04
7A057A077A087A097A0A7A0C7A0F7A107A117A127A137A157A167A187A197A1B
7A1C4E0176EF53EE948998769F0E952D5B9A8BA24E224E1C51AC846361C252A8
680B4F97606B51BB6D1E515C6296659796618C46901775D890FD77636BD2728A
72EC8BFB583577798D4C675C9540809A5EA66E2159927AEF77ED953B6BB565AD
7F0E58065151961F5BF958A954288E726566987F56E4949D76FE9041638754C6
591A593A579B8EB267358DFA8235524160F0581586FE5CE89E454FC4989D8BB9
5A2560765384627C904F9102997F6069800C513F80335C1499756D314E8C0000
B7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7A1D7A1F7A217A227A247A257A267A277A287A297A2A7A2B7A2C7A2D7A2E7A2F
7A307A317A327A347A357A367A387A3A7A3E7A407A417A427A437A447A457A47
7A487A497A4A7A4B7A4C7A4D7A4E7A4F7A507A527A537A547A557A567A587A59
7A5A7A5B7A5C7A5D7A5E7A5F7A607A617A627A637A647A657A667A677A680000
7A697A6A7A6B7A6C7A6D7A6E7A6F7A717A727A737A757A7B7A7C7A7D7A7E7A82
7A857A877A897A8A7A8B7A8C7A8E7A8F7A907A937A947A997A9A7A9B7A9E7AA1
7AA28D3053D17F5A7B4F4F104E4F96006CD573D085E95E06756A7FFB6A0A77FE
94927E4151E170E653CD8FD483038D2972AF996D6CDB574A82B365B980AA623F
963259A84EFF8BBF7EBA653E83F2975E556198DE80A5532A8BFD542080BA5E9F
6CB88D3982AC915A54296C1B52067EB7575F711A6C7E7C89594B4EFD5FFF6124
7CAA4E305C0167AB87025CF0950B98CE75AF70FD902251AF7F1D8BBD594951E4
4F5B5426592B657780A45B75627662C28F905E456C1F7B264F0F4FD8670D0000
B8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7AA37AA47AA77AA97AAA7AAB7AAE7AAF7AB07AB17AB27AB47AB57AB67AB77AB8
7AB97ABA7ABB7ABC7ABD7ABE7AC07AC17AC27AC37AC47AC57AC67AC77AC87AC9
7ACA7ACC7ACD7ACE7ACF7AD07AD17AD27AD37AD47AD57AD77AD87ADA7ADB7ADC
7ADD7AE17AE27AE47AE77AE87AE97AEA7AEB7AEC7AEE7AF07AF17AF27AF30000
7AF47AF57AF67AF77AF87AFB7AFC7AFE7B007B017B027B057B077B097B0C7B0D
7B0E7B107B127B137B167B177B187B1A7B1C7B1D7B1F7B217B227B237B277B29
7B2D6D6E6DAA798F88B15F17752B629A8F854FEF91DC65A7812F81515E9C8150
8D74526F89868D4B590D50854ED8961C723681798D1F5BCC8BA3964459877F1A
54905676560E8BE565396982949976D66E895E727518674667D17AFF809D8D76
611F79C665628D635188521A94A27F38809B7EB25C976E2F67607BD9768B9AD8
818F7F947CD5641E95507A3F544A54E56B4C640162089E3D80F3759952729769
845B683C86E49601969494EC4E2A54047ED968398DDF801566F45E9A7FB90000
B9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7B2F7B307B327B347B357B367B377B397B3B7B3D7B3F7B407B417B427B437B44
7B467B487B4A7B4D7B4E7B537B557B577B597B5C7B5E7B5F7B617B637B647B65
7B667B677B687B697B6A7B6B7B6C7B6D7B6F7B707B737B747B767B787B7A7B7C
7B7D7B7F7B817B827B837B847B867B877B887B897B8A7B8B7B8C7B8E7B8F0000
7B917B927B937B967B987B997B9A7B9B7B9E7B9F7BA07BA37BA47BA57BAE7BAF
7BB07BB27BB37BB57BB67BB77BB97BBA7BBB7BBC7BBD7BBE7BBF7BC07BC27BC3
7BC457C2803F68975DE5653B529F606D9F9A4F9B8EAC516C5BAB5F135DE96C5E
62F18D21517194A952FE6C9F82DF72D757A267848D2D591F8F9C83C754957B8D
4F306CBD5B6459D19F1353E486CA9AA88C3780A16545987E56FA96C7522E74DC
52505BE1630289024E5662D0602A68FA51735B9851A089C27BA199867F5060EF
704C8D2F51495E7F901B747089C4572D78455F529F9F95FA8F689B3C8BE17678
684267DC8DEA8D35523D8F8A6EDA68CD950590ED56FD679C88F98FC754C80000
BA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7BC57BC87BC97BCA7BCB7BCD7BCE7BCF7BD07BD27BD47BD57BD67BD77BD87BDB
7BDC7BDE7BDF7BE07BE27BE37BE47BE77BE87BE97BEB7BEC7BED7BEF7BF07BF2
7BF37BF47BF57BF67BF87BF97BFA7BFB7BFD7BFF7C007C017C027C037C047C05
7C067C087C097C0A7C0D7C0E7C107C117C127C137C147C157C177C187C190000
7C1A7C1B7C1C7C1D7C1E7C207C217C227C237C247C257C287C297C2B7C2C7C2D
7C2E7C2F7C307C317C327C337C347C357C367C377C397C3A7C3B7C3C7C3D7C3E
7C429AB85B696D776C264EA55BB39A87916361A890AF97E9542B6DB55BD251FD
558A7F557FF064BC634D65F161BE608D710A6C576C49592F676D822A58D5568E
8C6A6BEB90DD597D801753F76D695475559D837783CF683879BE548C4F555408
76D28C8996026CB36DB88D6B89109E648D3A563F9ED175D55F8872E0606854FC
4EA86A2A886160528F7054C470D886799E3F6D2A5B8F5F187EA255894FAF7334
543C539A5019540E547C4E4E5FFD745A58F6846B80E1877472D07CCA6E560000
BB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7C437C447C457C467C477C487C497C4A7C4B7C4C7C4E7C4F7C507C517C527C53
7C547C557C567C577C587C597C5A7C5B7C5C7C5D7C5E7C5F7C607C617C627C63
7C647C657C667C677C687C697C6A7C6B7C6C7C6D7C6E7C6F7C707C717C727C75
7C767C777C787C797C7A7C7E7C7F7C807C817C827C837C847C857C867C870000
7C887C8A7C8B7C8C7C8D7C8E7C8F7C907C937C947C967C997C9A7C9B7CA07CA1
7CA37CA67CA77CA87CA97CAB7CAC7CAD7CAF7CB07CB47CB57CB67CB77CB87CBA
7CBB5F27864E552C62A44E926CAA623782B154D7534E733E6ED1753B52125316
8BDD69D05F8A60006DEE574F6B2273AF68538FD87F13636260A3552475EA8C62
71156DA35BA65E7B8352614C9EC478FA87577C27768751F060F6714C66435E4C
604D8C0E707063258F895FBD606286D456DE6BC160946167534960E066668D3F
79FD4F1A70E96C478BB38BF27ED88364660F5A5A9B426D516DF78C416D3B4F19
706B83B7621660D1970D8D27797851FB573E57FA673A75787A3D79EF7B950000
BC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7CBF7CC07CC27CC37CC47CC67CC97CCB7CCE7CCF7CD07CD17CD27CD37CD47CD8
7CDA7CDB7CDD7CDE7CE17CE27CE37CE47CE57CE67CE77CE97CEA7CEB7CEC7CED
7CEE7CF07CF17CF27CF37CF47CF57CF67CF77CF97CFA7CFC7CFD7CFE7CFF7D00
7D017D027D037D047D057D067D077D087D097D0B7D0C7D0D7D0E7D0F7D100000
7D117D127D137D147D157D167D177D187D197D1A7D1B7D1C7D1D7D1E7D1F7D21
7D237D247D257D267D287D297D2A7D2C7D2D7D2E7D307D317D327D337D347D35
7D36808C99658FF96FC08BA59E2159EC7EE97F095409678168D88F917C4D96C6
53CA602575BE6C7253735AC97EA7632451E0810A5DF184DF628051805B634F0E
796D524260B86D4E5BC45BC28BA18BB065E25FCC964559937EE77EAA560967B7
59394F735BB652A0835A988A8D3E753294BE50477A3C4EF767B69A7E5AC16B7C
76D1575A5C167B3A95F4714E517C80A9827059787F04832768C067EC78B17877
62E363617B804FED526A51CF835069DB92748DF58D3189C1952E7BAD4EF60000
BD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7D377D387D397D3A7D3B7D3C7D3D7D3E7D3F7D407D417D427D437D447D457D46
7D477D487D497D4A7D4B7D4C7D4D7D4E7D4F7D507D517D527D537D547D557D56
7D577D587D597D5A7D5B7D5C7D5D7D5E7D5F7D607D617D627D637D647D657D66
7D677D687D697D6A7D6B7D6C7D6D7D6F7D707D717D727D737D747D757D760000
7D787D797D7A7D7B7D7C7D7D7D7E7D7F7D807D817D827D837D847D857D867D87
7D887D897D8A7D8B7D8C7D8D7D8E7D8F7D907D917D927D937D947D957D967D97
7D98506582305251996F6E106E856DA75EFA50F559DC5C066D466C5F7586848B
686859568BB253209171964D854969127901712680F64EA490CA6D479A845A07
56BC640594F077EB4FA5811A72E189D2997A7F347EDE527F655991758F7F8F83
53EB7A9663ED63A5768679F888579636622A52AB8282685467706377776B7AED
6D017ED389E359D0621285C982A5754C501F4ECB75A58BEB5C4A5DFE7B4B65A4
91D14ECA6D25895F7D2795264EC58C288FDB9773664B79818FD170EC6D780000
BE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7D997D9A7D9B7D9C7D9D7D9E7D9F7DA07DA17DA27DA37DA47DA57DA77DA87DA9
7DAA7DAB7DAC7DAD7DAF7DB07DB17DB27DB37DB47DB57DB67DB77DB87DB97DBA
7DBB7DBC7DBD7DBE7DBF7DC07DC17DC27DC37DC47DC57DC67DC77DC87DC97DCA
7DCB7DCC7DCD7DCE7DCF7DD07DD17DD27DD37DD47DD57DD67DD77DD87DD90000
7DDA7DDB7DDC7DDD7DDE7DDF7DE07DE17DE27DE37DE47DE57DE67DE77DE87DE9
7DEA7DEB7DEC7DED7DEE7DEF7DF07DF17DF27DF37DF47DF57DF67DF77DF87DF9
7DFA5C3D52B283465162830E775B66769CB84EAC60CA7CBE7CB37ECF4E958B66
666F988897595883656C955C5F8475C997567ADF7ADE51C070AF7A9863EA7A76
7EA0739697ED4E4570784E5D915253A9655165E781FC8205548E5C31759A97A0
62D872D975BD5C459A7983CA5C40548077E94E3E6CAE805A62D2636E5DE85177
8DDD8E1E952F4FF153E560E770AC526763509E435A1F5026773753777EE26485
652B628963985014723589C951B38BC07EDD574783CC94A7519B541B5CFB0000
BF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7DFB7DFC7DFD7DFE7DFF7E007E017E027E037E047E057E067E077E087E097E0A
7E0B7E0C7E0D7E0E7E0F7E107E117E127E137E147E157E167E177E187E197E1A
7E1B7E1C7E1D7E1E7E1F7E207E217E227E237E247E257E267E277E287E297E2A
7E2B7E2C7E2D7E2E7E2F7E307E317E327E337E347E357E367E377E387E390000
7E3A7E3C7E3D7E3E7E3F7E407E427E437E447E457E467E487E497E4A7E4B7E4C
7E4D7E4E7E4F7E507E517E527E537E547E557E567E577E587E597E5A7E5B7E5C
7E5D4FCA7AE36D5A90E19A8F55805496536154AF5F0063E9697751EF6168520A
582A52D8574E780D770B5EB761777CE0625B62974EA27095800362F770E49760
577782DB67EF68F578D5989779D158F354B353EF6E34514B523B5BA28BFE80AF
554357A660735751542D7A7A60505B5463A762A053E362635BC767AF54ED7A9F
82E691775E9388E4593857AE630E8DE880EF57577B774FA95FEB5BBD6B3E5321
7B5072C2684677FF773665F751B54E8F76D45CBF7AA58475594E9B4150800000
C0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7E5E7E5F7E607E617E627E637E647E657E667E677E687E697E6A7E6B7E6C7E6D
7E6E7E6F7E707E717E727E737E747E757E767E777E787E797E7A7E7B7E7C7E7D
7E7E7E7F7E807E817E837E847E857E867E877E887E897E8A7E8B7E8C7E8D7E8E
7E8F7E907E917E927E937E947E957E967E977E987E997E9A7E9C7E9D7E9E0000
7EAE7EB47EBB7EBC7ED67EE47EEC7EF97F0A7F107F1E7F377F397F3B7F3C7F3D
7F3E7F3F7F407F417F437F467F477F487F497F4A7F4B7F4C7F4D7F4E7F4F7F52
7F53998861276E8357646606634656F062EC62695ED39614578362C955878721
814A8FA3556683B167658D5684DD5A6A680F62E67BEE961151706F9C8C3063FD
89C861D27F0670C26EE57405699472FC5ECA90CE67176D6A635E52B372628001
4F6C59E5916A70D96D9D52D24E5096F7956D857E78CA7D2F5121579264C2808B
7C7B6CEA68F1695E51B7539868A872819ECE7BF172F879BB6F137406674E91CC
9CA4793C83898354540F68174E3D538952B1783E5386522950884F8B4FD00000
C1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7F567F597F5B7F5C7F5D7F5E7F607F637F647F657F667F677F6B7F6C7F6D7F6F
7F707F737F757F767F777F787F7A7F7B7F7C7F7D7F7F7F807F827F837F847F85
7F867F877F887F897F8B7F8D7F8F7F907F917F927F937F957F967F977F987F99
7F9B7F9C7FA07FA27FA37FA57FA67FA87FA97FAA7FAB7FAC7FAD7FAE7FB10000
7FB37FB47FB57FB67FB77FBA7FBB7FBE7FC07FC27FC37FC47FC67FC77FC87FC9
7FCB7FCD7FCF7FD07FD17FD27FD37FD67FD77FD97FDA7FDB7FDC7FDD7FDE7FE2
7FE375E27ACB7C926CA596B6529B748354E94FE9805483B28FDE95705EC9601C
6D9F5E18655B813894FE604B70BC7EC37CAE51C968817CB1826F4E248F8691CF
667E4EAE8C0564A9804A50DA759771CE5BE58FBD6F664E86648295635ED66599
521788C270C852A3730E7433679778F797164E3490BB9CDE6DCB51DB8D41541D
62CE73B283F196F69F8494C34F367F9A51CC707596755CAD988653E64EE46E9C
740969B4786B998F7559521876246D4167F3516D9F99804B54997B3C7ABF0000
C2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7FE47FE77FE87FEA7FEB7FEC7FED7FEF7FF27FF47FF57FF67FF77FF87FF97FFA
7FFD7FFE7FFF8002800780088009800A800E800F80118013801A801B801D801E
801F802180238024802B802C802D802E802F8030803280348039803A803C803E
8040804180448045804780488049804E804F8050805180538055805680570000
8059805B805C805D805E805F806080618062806380648065806680678068806B
806C806D806E806F807080728073807480758076807780788079807A807B807C
807D9686578462E29647697C5A0464027BD36F0F964B82A6536298855E907089
63B35364864F9C819E93788C97328DEF8D429E7F6F5E79845F559646622E9A74
541594DD4FA365C55C655C617F1586516C2F5F8B73876EE47EFF5CE6631B5B6A
6EE653754E7163A0756562A18F6E4F264ED16CA67EB68BBA841D87BA7F57903B
95237BA99AA188F8843D6D1B9A867EDC59889EBB739B780186829A6C9A82561B
541757CB4E709EA653568FC881097792999286EE6EE1851366FC61626F2B0000
C3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
807E8081808280858088808A808D808E808F8090809180928094809580978099
809E80A380A680A780A880AC80B080B380B580B680B880B980BB80C580C780C8
80C980CA80CB80CF80D080D180D280D380D480D580D880DF80E080E280E380E6
80EE80F580F780F980FB80FE80FF8100810181038104810581078108810B0000
810C811581178119811B811C811D811F81208121812281238124812581268127
81288129812A812B812D812E813081338134813581378139813A813B813C813D
813F8C298292832B76F26C135FD983BD732B8305951A6BDB77DB94C6536F8302
51925E3D8C8C8D384E4873AB679A68859176970971646CA177095A9295416BCF
7F8E66275BD059B95A9A95E895F74EEC840C84996AAC76DF9530731B68A65B5F
772F919A97617CDC8FF78C1C5F257C7379D889C56CCC871C5BC65E4268C97720
7EF55195514D52C95A297F05976282D763CF778485D079D26E3A5E9959998511
706D6C1162BF76BF654F60AF95FD660E879F9E2394ED540D547D8C2C64780000
C4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
81408141814281438144814581478149814D814E814F8152815681578158815B
815C815D815E815F816181628163816481668168816A816B816C816F81728173
81758176817781788181818381848185818681878189818B818C818D818E8190
8192819381948195819681978199819A819E819F81A081A181A281A481A50000
81A781A981AB81AC81AD81AE81AF81B081B181B281B481B581B681B781B881B9
81BC81BD81BE81BF81C481C581C781C881C981CB81CD81CE81CF81D081D181D2
81D3647986116A21819C78E864699B5462B9672B83AB58A89ED86CAB6F205BDE
964C8C0B725F67D062C772614EA959C66BCD589366AE5E5552DF6155672876EE
776672677A4662FF54EA545094A090A35A1C7EB36C164E435976801059485357
753796BE56CA63208111607C95F96DD65462998151855AE980FD59AE9713502A
6CE55C3C62DF4F60533F817B90066EBA852B62C85E7478BE64B5637B5FF55A18
917F9E1F5C3F634F80425B7D556E954A954D6D8560A867E072DE51DD5B810000
C5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
81D481D581D681D781D881D981DA81DB81DC81DD81DE81DF81E081E181E281E4
81E581E681E881E981EB81EE81EF81F081F181F281F581F681F781F881F981FA
81FD81FF8203820782088209820A820B820E820F821182138215821682178218
8219821A821D822082248225822682278229822E8232823A823C823D823F0000
8240824182428243824582468248824A824C824D824E82508251825282538254
8255825682578259825B825C825D825E82608261826282638264826582668267
826962E76CDE725B626D94AE7EBD81136D53519C5F04597452AA601259736696
8650759F632A61E67CEF8BFA54E66B279E256BB485D5545550766CA4556A8DB4
722C5E156015743662CD6392724C5F986E436D3E65006F5876D878D076FC7554
522453DB4E535E9E65C1802A80D6629B5486522870AE888D8DD16CE1547880DA
57F988F48D54966A914D4F696C9B55B776C6783062A870F96F8E5F6D84EC68DA
787C7BF781A8670B9E4F636778B0576F78129739627962AB528874356BD70000
C6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
826A826B826C826D82718275827682778278827B827C82808281828382858286
82878289828C82908293829482958296829A829B829E82A082A282A382A782B2
82B582B682BA82BB82BC82BF82C082C282C382C582C682C982D082D682D982DA
82DD82E282E782E882E982EA82EC82ED82EE82F082F282F382F582F682F80000
82FA82FC82FD82FE82FF8300830A830B830D831083128313831683188319831D
831E831F83208321832283238324832583268329832A832E833083328337833B
833D5564813E75B276AE533975DE50FB5C418B6C7BC7504F72479A9798D86F02
74E27968648777A562FC98918D2B54C180584E52576A82F9840D5E7351ED74F6
8BC45C4F57616CFC98875A4678349B448FEB7C955256625194FA4EC683868461
83E984B257D467345703666E6D668C3166DD7011671F6B3A6816621A59BB4E03
51C46F0667D26C8F517668CB59476B6775665D0E81109F5065D7794879419A91
8D775C824E5E4F01542F5951780C56686C148FC45F036C7D6CE38BAB63900000
C7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
833E833F83418342834483458348834A834B834C834D834E8353835583568357
83588359835D836283708371837283738374837583768379837A837E837F8380
838183828383838483878388838A838B838C838D838F83908391839483958396
83978399839A839D839F83A183A283A383A483A583A683A783AC83AD83AE0000
83AF83B583BB83BE83BF83C283C383C483C683C883C983CB83CD83CE83D083D1
83D283D383D583D783D983DA83DB83DE83E283E383E483E683E783E883EB83EC
83ED60706D3D72756266948E94C553438FC17B7E4EDF8C264E7E9ED494B194B3
524D6F5C90636D458C3458115D4C6B206B4967AA545B81547F8C589985375F3A
62A26A47953965726084686577A74E544FA85DE7979864AC7FD85CED4FCF7A8D
520783044E14602F7A8394A64FB54EB279E6743452E482B964D279BD5BDD6C81
97528F7B6C22503E537F6E0564CE66746C3060C598778BF75E86743C7A7779CB
4E1890B174036C4256DA914B6CC58D8B533A86C666F28EAF5C489A716E200000
C8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
83EE83EF83F383F483F583F683F783FA83FB83FC83FE83FF8400840284058407
84088409840A84108412841384148415841684178419841A841B841E841F8420
8421842284238429842A842B842C842D842E842F843084328433843484358436
84378439843A843B843E843F8440844184428443844484458447844884490000
844A844B844C844D844E844F8450845284538454845584568458845D845E845F
8460846284648465846684678468846A846E846F84708472847484778479847B
847C53D65A369F8B8DA353BB570898A76743919B6CC9516875CA62F372AC5238
529D7F3A7094763853749E4A69B7786E96C088D97FA4713671C3518967D374E4
58E4651856B78BA9997662707ED560F970ED58EC4EC14EBA5FCD97E74EFB8BA4
5203598A7EAB62544ECD65E5620E833884C98363878D71946EB65BB97ED25197
63C967D480898339881551125B7A59828FB14E736C5D516589258F6F962E854A
745E951095F06DA682E55F3164926D128428816E9CC3585E8D5B4E0953C10000
C9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
847D847E847F848084818483848484858486848A848D848F8490849184928493
8494849584968498849A849B849D849E849F84A084A284A384A484A584A684A7
84A884A984AA84AB84AC84AD84AE84B084B184B384B584B684B784BB84BC84BE
84C084C284C384C584C684C784C884CB84CC84CE84CF84D284D484D584D70000
84D884D984DA84DB84DC84DE84E184E284E484E784E884E984EA84EB84ED84EE
84EF84F184F284F384F484F584F684F784F884F984FA84FB84FD84FE85008501
85024F1E6563685155D34E2764149A9A626B5AC2745F82726DA968EE50E7838E
7802674052396C997EB150BB5565715E7B5B665273CA82EB67495C715220717D
886B95EA965564C58D6181B355846C5562477F2E58924F2455468D4F664C4E0A
5C1A88F368A2634E7A0D70E7828D52FA97F65C1154E890B57ECD59628D4A86C7
820C820D8D6664445C0461516D89793E8BBE78377533547B4F388EAB6DF15A20
7EC5795E6C885BA15A76751A80BE614E6E1758F0751F7525727253477EF30000
CA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8503850485058506850785088509850A850B850D850E850F8510851285148515
851685188519851B851C851D851E852085228523852485258526852785288529
852A852D852E852F8530853185328533853485358536853E853F854085418542
8544854585468547854B854C854D854E854F8550855185528553855485550000
85578558855A855B855C855D855F85608561856285638565856685678569856A
856B856C856D856E856F8570857185738575857685778578857C857D857F8580
8581770176DB526980DC57235E08593172EE65BD6E7F8BD75C388671534177F3
62FE65F64EC098DF86805B9E8BC653F277E24F7F5C4E9A7659CB5F0F793A58EB
4E1667FF4E8B62ED8A93901D52BF662F55DC566C90024ED54F8D91CA99706C0F
5E0260435BA489C68BD56536624B99965B885BFF6388552E53D77626517D852C
67A268B36B8A62928F9353D482126DD1758F4E668D4E5B70719F85AF669166D9
7F7287009ECD9F205C5E672F8FF06811675F620D7AD658855EB665706F310000
CB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
85828583858685888589858A858B858C858D858E859085918592859385948595
8596859785988599859A859D859E859F85A085A185A285A385A585A685A785A9
85AB85AC85AD85B185B285B385B485B585B685B885BA85BB85BC85BD85BE85BF
85C085C285C385C485C585C685C785C885CA85CB85CC85CD85CE85D185D20000
85D485D685D785D885D985DA85DB85DD85DE85DF85E085E185E285E385E585E6
85E785E885EA85EB85EC85ED85EE85EF85F085F185F285F385F485F585F685F7
85F860555237800D6454887075295E05681362F4971C53CC723D8C016C347761
7A0E542E77AC987A821C8BF47855671470C165AF64955636601D79C153F84E1D
6B7B80865BFA55E356DB4F3A4F3C99725DF3677E80386002988290015B8B8BBC
8BF5641C825864DE55FD82CF91654FD77D20901F7C9F50F358516EAF5BBF8BC9
80839178849C7B97867D968B968F7EE59AD3788E5C817A57904296A7795F5B59
635F7B0B84D168AD55067F2974107D2295016240584C4ED65B83597958540000
CC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
85F985FA85FC85FD85FE860086018602860386048606860786088609860A860B
860C860D860E860F86108612861386148615861786188619861A861B861C861D
861E861F86208621862286238624862586268628862A862B862C862D862E862F
863086318632863386348635863686378639863A863B863D863E863F86400000
864186428643864486458646864786488649864A864B864C8652865386558656
865786588659865B865C865D865F866086618663866486658666866786688669
866A736D631E8E4B8E0F80CE82D462AC53F06CF0915E592A60016C70574D644A
8D2A762B6EE9575B6A8075F06F6D8C2D8C0857666BEF889278B363A253F970AD
6C645858642A580268E0819B55107CD650188EBA6DCC8D9F70EB638F6D9B6ED4
7EE68404684390036DD896768BA85957727985E4817E75BC8A8A68AF52548E22
951163D098988E44557C4F5366FF568F60D56D9552435C4959296DFB586B7530
751C606C82148146631167618FE2773A8DF38D3494C15E165385542C70C30000
CD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
866D866F86708672867386748675867686778678868386848685868686878688
8689868E868F86908691869286948696869786988699869A869B869E869F86A0
86A186A286A586A686AB86AD86AE86B286B386B786B886B986BB86BC86BD86BE
86BF86C186C286C386C586C886CC86CD86D286D386D586D686D786DA86DC0000
86DD86E086E186E286E386E586E686E786E886EA86EB86EC86EF86F586F686F7
86FA86FB86FC86FD86FF8701870487058706870B870C870E870F871087118714
87166C405EF7505C4EAD5EAD633A8247901A6850916E77B3540C94DC5F647AE5
687663457B527EDF75DB507762955934900F51F879C37A8156FE5F9290146D82
5C60571F541051546E4D56E263A89893817F8715892A9000541E5C6F81C062D6
625881319E3596409A6E9A7C692D59A562D3553E631654C786D96D3C5A0374E6
889C6B6A59168C4C5F2F6E7E73A9987D4E3870F75B8C7897633D665A769660CB
5B9B5A494E0781556C6A738B4EA167897F515F8065FA671B5FD859845A010000
CE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8719871B871D871F87208724872687278728872A872B872C872D872F87308732
87338735873687388739873A873C873D8740874187428743874487458746874A
874B874D874F8750875187528754875587568758875A875B875C875D875E875F
876187628766876787688769876A876B876C876D876F87718772877387750000
877787788779877A877F878087818784878687878789878A878C878E878F8790
8791879287948795879687988799879A879B879C879D879E87A087A187A287A3
87A45DCD5FAE537197E68FDD684556F4552F60DF4E3A6F4D7EF482C7840E59D4
4F1F4F2A5C3E7EAC672A851A5473754F80C355829B4F4F4D6E2D8C135C096170
536B761F6E29868A658795FB7EB9543B7A337D0A95EE55E17FC174EE631D8717
6DA17A9D621165A1536763E16C835DEB545C94A84E4C6C618BEC5C4B65E0829C
68A7543E54346BCB6B664E9463425348821E4F0D4FAE575E620A96FE66647269
52FF52A1609F8BEF661471996790897F785277FD6670563B54389521727A0000
CF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
87A587A687A787A987AA87AE87B087B187B287B487B687B787B887B987BB87BC
87BE87BF87C187C287C387C487C587C787C887C987CC87CD87CE87CF87D087D4
87D587D687D787D887D987DA87DC87DD87DE87DF87E187E287E387E487E687E7
87E887E987EB87EC87ED87EF87F087F187F287F387F487F587F687F787F80000
87FA87FB87FC87FD87FF880088018802880488058806880788088809880B880C
880D880E880F8810881188128814881788188819881A881C881D881E881F8820
88237A00606F5E0C6089819D591560DC718470EF6EAA6C5072806A8488AD5E2D
4E605AB3559C94E36D177CFB9699620F7EC6778E867E5323971E8F9666875CE1
4FA072ED4E0B53A6590F54136380952851484ED99C9C7EA454B88D2488548237
95F26D8E5F265ACC663E966973B0732E53BF817A99857FA15BAA967796507EBF
76F853A2957699997BB189446E584E617FD479658BE660F354CD4EAB98795DF7
6A6150CF54118C618427785D9704524A54EE56A395006D885BB56DC666530000
D0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
882488258826882788288829882A882B882C882D882E882F8830883188338834
8835883688378838883A883B883D883E883F8841884288438846884788488849
884A884B884E884F8850885188528853885588568858885A885B885C885D885E
885F886088668867886A886D886F8871887388748875887688788879887A0000
887B887C88808883888688878889888A888C888E888F88908891889388948895
889788988899889A889B889D889E889F88A088A188A388A588A688A788A888A9
88AA5C0F5B5D6821809655787B11654869544E9B6B47874E978B534F631F643A
90AA659C80C18C10519968B0537887F961C86CC46CFB8C225C5185AA82AF950C
6B238F9B65B05FFB5FC34FE18845661F8165732960FA51745211578B5F6290A2
884C91925E78674F602759D3514451F680F853086C7996C4718A4F114FEE7F9E
673D55C5950879C088967EE3589F620C9700865A5618987B5F908BB884C49157
53D965ED5E8F755C60647D6E5A7F7EEA7EED8F6955A75BA360AC65CB73840000
D1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
88AC88AE88AF88B088B288B388B488B588B688B888B988BA88BB88BD88BE88BF
88C088C388C488C788C888CA88CB88CC88CD88CF88D088D188D388D688D788DA
88DB88DC88DD88DE88E088E188E688E788E988EA88EB88EC88ED88EE88EF88F2
88F588F688F788FA88FB88FD88FF890089018903890489058906890789080000
8909890B890C890D890E890F891189148915891689178918891C891D891E891F
89208922892389248926892789288929892C892D892E892F8931893289338935
89379009766377297EDA9774859B5B667A7496EA884052CB718F5FAA65EC8BE2
5BFB9A6F5DE16B896C5B8BAD8BAF900A8FC5538B62BC9E269E2D54404E2B82BD
7259869C5D1688596DAF96C554D14E9A8BB6710954BD960970DF6DF976D04E25
781487125CA95EF68A00989C960E708E6CBF594463A9773C884D6F1482735830
71D5538C781A96C155015F6671305BB48C1A9A8C6B83592E9E2F79E76768626C
4F6F75A17F8A6D0B96336C274EF075D2517B68376F3E90808170599674760000
D2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
89388939893A893B893C893D893E893F89408942894389458946894789488949
894A894B894C894D894E894F8950895189528953895489558956895789588959
895A895B895C895D896089618962896389648965896789688969896A896B896C
896D896E896F8970897189728973897489758976897789788979897A897C0000
897D897E8980898289848985898789888989898A898B898C898D898E898F8990
899189928993899489958996899789988999899A899B899C899D899E899F89A0
89A164475C2790657A918C2359DA54AC8200836F898180006930564E80367237
91CE51B64E5F987563964E1A53F666F3814B591C6DB24E0058F9533B63D694F1
4F9D4F0A886398905937905779FB4EEA80F075916C825B9C59E85F5D69058681
501A5DF24E5977E34EE5827A6291661390915C794EBF5F7981C69038808475AB
4EA688D4610F6BC55FC64E4976CA6EA28BE38BAE8C0A8BD15F027FFC7FCC7ECE
8335836B56E06BB797F3963459FB541F94F66DEB5BC5996E5C395F1596900000
D3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
89A289A389A489A589A689A789A889A989AA89AB89AC89AD89AE89AF89B089B1
89B289B389B489B589B689B789B889B989BA89BB89BC89BD89BE89BF89C089C3
89CD89D389D489D589D789D889D989DB89DD89DF89E089E189E289E489E789E8
89E989EA89EC89ED89EE89F089F189F289F489F589F689F789F889F989FA0000
89FB89FC89FD89FE89FF8A018A028A038A048A058A068A088A098A0A8A0B8A0C
8A0D8A0E8A0F8A108A118A128A138A148A158A168A178A188A198A1A8A1B8A1C
8A1D537082F16A315A749E705E947F2883B984248425836787478FCE8D6276C8
5F719896786C662054DF62E54F6381C375C85EB896CD8E0A86F9548F6CF36D8C
6C38607F52C775285E7D4F1860A05FE75C24753190AE94C072B96CB96E389149
670953CB53F34F5191C98BF153C85E7C8FC26DE44E8E76C26986865E611A8206
4F594FDE903E9C7C61096E1D6E1496854E885A3196E84E0E5C7F79B95B878BED
7FBD738957DF828B90C15401904755BB5CEA5FA161086B3272F180B28A890000
D4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8A1E8A1F8A208A218A228A238A248A258A268A278A288A298A2A8A2B8A2C8A2D
8A2E8A2F8A308A318A328A338A348A358A368A378A388A398A3A8A3B8A3C8A3D
8A3F8A408A418A428A438A448A458A468A478A498A4A8A4B8A4C8A4D8A4E8A4F
8A508A518A528A538A548A558A568A578A588A598A5A8A5B8A5C8A5D8A5E0000
8A5F8A608A618A628A638A648A658A668A678A688A698A6A8A6B8A6C8A6D8A6E
8A6F8A708A718A728A738A748A758A768A778A788A7A8A7B8A7C8A7D8A7E8A7F
8A806D745BD388D598848C6B9A6D9E336E0A51A4514357A38881539F63F48F95
56ED54585706733F6E907F188FDC82D1613F6028966266F07EA68D8A8DC394A5
5CB37CA4670860A6960580184E9190E75300966851418FD08574915D665597F5
5B55531D78386742683D54C9707E5BB08F7D518D572854B1651266828D5E8D43
810F846C906D7CDF51FF85FB67A365E96FA186A48E81566A90207682707671E5
8D2362E952196CFD8D3C600E589E618E66FE8D60624E55B36E23672D8F670000
D5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8A818A828A838A848A858A868A878A888A8B8A8C8A8D8A8E8A8F8A908A918A92
8A948A958A968A978A988A998A9A8A9B8A9C8A9D8A9E8A9F8AA08AA18AA28AA3
8AA48AA58AA68AA78AA88AA98AAA8AAB8AAC8AAD8AAE8AAF8AB08AB18AB28AB3
8AB48AB58AB68AB78AB88AB98ABA8ABB8ABC8ABD8ABE8ABF8AC08AC18AC20000
8AC38AC48AC58AC68AC78AC88AC98ACA8ACB8ACC8ACD8ACE8ACF8AD08AD18AD2
8AD38AD48AD58AD68AD78AD88AD98ADA8ADB8ADC8ADD8ADE8ADF8AE08AE18AE2
8AE394E195F87728680569A8548B4E4D70B88BC86458658B5B857A84503A5BE8
77BB6BE18A797C986CBE76CF65A98F975D2D5C5586386808536062187AD96E5B
7EFD6A1F7AE05F706F335F20638C6DA867564E085E108D264ED780C07634969C
62DB662D627E6CBC8D7571677F695146808753EC906E629854F286F08F998005
951785178FD96D5973CD659F771F7504782781FB8D1E94884FA6679575B98BCA
9707632F9547963584B8632377415F8172F04E896014657462EF6B63653F0000
D6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8AE48AE58AE68AE78AE88AE98AEA8AEB8AEC8AED8AEE8AEF8AF08AF18AF28AF3
8AF48AF58AF68AF78AF88AF98AFA8AFB8AFC8AFD8AFE8AFF8B008B018B028B03
8B048B058B068B088B098B0A8B0B8B0C8B0D8B0E8B0F8B108B118B128B138B14
8B158B168B178B188B198B1A8B1B8B1C8B1D8B1E8B1F8B208B218B228B230000
8B248B258B278B288B298B2A8B2B8B2C8B2D8B2E8B2F8B308B318B328B338B34
8B358B368B378B388B398B3A8B3B8B3C8B3D8B3E8B3F8B408B418B428B438B44
8B455E2775C790D18BC1829D679D652F5431871877E580A281026C414E4B7EC7
804C76F4690D6B966267503C4F84574063076B628DBE53EA65E87EB85FD7631A
63B781F381F47F6E5E1C5CD95236667A79E97A1A8D28709975D46EDE6CBB7A92
4E2D76C55FE0949F88777EC879CD80BF91CD4EF24F17821F54685DDE6D328BCC
7CA58F7480985E1A549276B15B99663C9AA473E0682A86DB6731732A8BF88BDB
90107AF970DB716E62C477A956314E3B845767F152A986C08D2E94F87B510000
D7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8B468B478B488B498B4A8B4B8B4C8B4D8B4E8B4F8B508B518B528B538B548B55
8B568B578B588B598B5A8B5B8B5C8B5D8B5E8B5F8B608B618B628B638B648B65
8B678B688B698B6A8B6B8B6D8B6E8B6F8B708B718B728B738B748B758B768B77
8B788B798B7A8B7B8B7C8B7D8B7E8B7F8B808B818B828B838B848B858B860000
8B878B888B898B8A8B8B8B8C8B8D8B8E8B8F8B908B918B928B938B948B958B96
8B978B988B998B9A8B9B8B9C8B9D8B9E8B9F8BAC8BB18BBB8BC78BD08BEA8C09
8C1E4F4F6CE8795D9A7B6293722A62FD4E1378168F6C64B08D5A7BC668695E84
88C55986649E58EE72B6690E95258FFD8D5857607F008C0651C6634962D95353
684C74228301914C55447740707C6D4A517954A88D4459FF6ECB6DC45B5C7D2B
4ED47C7D6ED35B5081EA6E0D5B579B0368D58E2A5B977EFC603B7EB590B98D70
594F63CD79DF8DB3535265CF79568BC5963B7EC494BB7E825634918967007F6A
5C0A907566285DE64F5067DE505A4F5C57505EA7000000000000000000000000
D8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8C388C398C3A8C3B8C3C8C3D8C3E8C3F8C408C428C438C448C458C488C4A8C4B
8C4D8C4E8C4F8C508C518C528C538C548C568C578C588C598C5B8C5C8C5D8C5E
8C5F8C608C638C648C658C668C678C688C698C6C8C6D8C6E8C6F8C708C718C72
8C748C758C768C778C7B8C7C8C7D8C7E8C7F8C808C818C838C848C868C870000
8C888C8B8C8D8C8E8C8F8C908C918C928C938C958C968C978C998C9A8C9B8C9C
8C9D8C9E8C9F8CA08CA18CA28CA38CA48CA58CA68CA78CA88CA98CAA8CAB8CAC
8CAD4E8D4E0C51404E105EFF53454E154E984E1E9B325B6C56694E2879BA4E3F
53154E47592D723B536E6C1056DF80E499976BD3777E9F174E364E9F9F104E5C
4E694E9382885B5B556C560F4EC4538D539D53A353A553AE97658D5D531A53F5
5326532E533E8D5C5366536352025208520E522D5233523F5240524C525E5261
525C84AF527D528252815290529351827F544EBB4EC34EC94EC24EE84EE14EEB
4EDE4F1B4EF34F224F644EF54F254F274F094F2B4F5E4F6765384F5A4F5D0000
D9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8CAE8CAF8CB08CB18CB28CB38CB48CB58CB68CB78CB88CB98CBA8CBB8CBC8CBD
8CBE8CBF8CC08CC18CC28CC38CC48CC58CC68CC78CC88CC98CCA8CCB8CCC8CCD
8CCE8CCF8CD08CD18CD28CD38CD48CD58CD68CD78CD88CD98CDA8CDB8CDC8CDD
8CDE8CDF8CE08CE18CE28CE38CE48CE58CE68CE78CE88CE98CEA8CEB8CEC0000
8CED8CEE8CEF8CF08CF18CF28CF38CF48CF58CF68CF78CF88CF98CFA8CFB8CFC
8CFD8CFE8CFF8D008D018D028D038D048D058D068D078D088D098D0A8D0B8D0C
8D0D4F5F4F574F324F3D4F764F744F914F894F834F8F4F7E4F7B4FAA4F7C4FAC
4F944FE64FE84FEA4FC54FDA4FE34FDC4FD14FDF4FF85029504C4FF3502C500F
502E502D4FFE501C500C50255028507E504350555048504E506C507B50A550A7
50A950BA50D6510650ED50EC50E650EE5107510B4EDD6C3D4F584F654FCE9FA0
6C467C74516E5DFD9EC999985181591452F9530D8A07531051EB591951554EA0
51564EB3886E88A44EB5811488D279805B3488037FB851AB51B151BD51BC0000
DA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8D0E8D0F8D108D118D128D138D148D158D168D178D188D198D1A8D1B8D1C8D20
8D518D528D578D5F8D658D688D698D6A8D6C8D6E8D6F8D718D728D788D798D7A
8D7B8D7C8D7D8D7E8D7F8D808D828D838D868D878D888D898D8C8D8D8D8E8D8F
8D908D928D938D958D968D978D988D998D9A8D9B8D9C8D9D8D9E8DA08DA10000
8DA28DA48DA58DA68DA78DA88DA98DAA8DAB8DAC8DAD8DAE8DAF8DB08DB28DB6
8DB78DB98DBB8DBD8DC08DC18DC28DC58DC78DC88DC98DCA8DCD8DD08DD28DD3
8DD451C7519651A251A58BA08BA68BA78BAA8BB48BB58BB78BC28BC38BCB8BCF
8BCE8BD28BD38BD48BD68BD88BD98BDC8BDF8BE08BE48BE88BE98BEE8BF08BF3
8BF68BF98BFC8BFF8C008C028C048C078C0C8C0F8C118C128C148C158C168C19
8C1B8C188C1D8C1F8C208C218C258C278C2A8C2B8C2E8C2F8C328C338C358C36
5369537A961D962296219631962A963D963C964296499654965F9667966C9672
96749688968D969796B09097909B909D909990AC90A190B490B390B690BA0000
DB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8DD58DD88DD98DDC8DE08DE18DE28DE58DE68DE78DE98DED8DEE8DF08DF18DF2
8DF48DF68DFC8DFE8DFF8E008E018E028E038E048E068E078E088E0B8E0D8E0E
8E108E118E128E138E158E168E178E188E198E1A8E1B8E1C8E208E218E248E25
8E268E278E288E2B8E2D8E308E328E338E348E368E378E388E3B8E3C8E3E0000
8E3F8E438E458E468E4C8E4D8E4E8E4F8E508E538E548E558E568E578E588E5A
8E5B8E5C8E5D8E5E8E5F8E608E618E628E638E648E658E678E688E6A8E6B8E6E
8E7190B890B090CF90C590BE90D090C490C790D390E690E290DC90D790DB90EB
90EF90FE91049122911E91239131912F913991439146520D594252A252AC52AD
52BE54FF52D052D652F053DF71EE77CD5EF451F551FC9B2F53B65F01755A5DEF
574C57A957A1587E58BC58C558D15729572C572A57335739572E572F575C573B
574257695785576B5786577C577B5768576D5776577357AD57A4578C57B257CF
57A757B4579357A057D557D857DA57D957D257B857F457EF57F857E457DD0000
DC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8E738E758E778E788E798E7A8E7B8E7D8E7E8E808E828E838E848E868E888E89
8E8A8E8B8E8C8E8D8E8E8E918E928E938E958E968E978E988E998E9A8E9B8E9D
8E9F8EA08EA18EA28EA38EA48EA58EA68EA78EA88EA98EAA8EAD8EAE8EB08EB1
8EB38EB48EB58EB68EB78EB88EB98EBB8EBC8EBD8EBE8EBF8EC08EC18EC20000
8EC38EC48EC58EC68EC78EC88EC98ECA8ECB8ECC8ECD8ECF8ED08ED18ED28ED3
8ED48ED58ED68ED78ED88ED98EDA8EDB8EDC8EDD8EDE8EDF8EE08EE18EE28EE3
8EE4580B580D57FD57ED5800581E5819584458205865586C58815889589A5880
99A89F1961FF8279827D827F828F828A82A88284828E82918297829982AB82B8
82BE82B082C882CA82E3829882B782AE82CB82CC82C182A982B482A182AA829F
82C482CE82A482E1830982F782E4830F830782DC82F482D282D8830C82FB82D3
8311831A83068314831582E082D5831C8351835B835C83088392833C83348331
839B835E832F834F83478343835F834083178360832D833A8333836683650000
DD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8EE58EE68EE78EE88EE98EEA8EEB8EEC8EED8EEE8EEF8EF08EF18EF28EF38EF4
8EF58EF68EF78EF88EF98EFA8EFB8EFC8EFD8EFE8EFF8F008F018F028F038F04
8F058F068F078F088F098F0A8F0B8F0C8F0D8F0E8F0F8F108F118F128F138F14
8F158F168F178F188F198F1A8F1B8F1C8F1D8F1E8F1F8F208F218F228F230000
8F248F258F268F278F288F298F2A8F2B8F2C8F2D8F2E8F2F8F308F318F328F33
8F348F358F368F378F388F398F3A8F3B8F3C8F3D8F3E8F3F8F408F418F428F43
8F448368831B8369836C836A836D836E83B0837883B383B483A083AA8393839C
8385837C83B683A9837D83B8837B8398839E83A883BA83BC83C1840183E583D8
58078418840B83DD83FD83D6841C84388411840683D483DF840F840383F883F9
83EA83C583C0842683F083E1845C8451845A8459847384878488847A84898478
843C844684698476848C848E8431846D84C184CD84D084E684BD84D384CA84BF
84BA84E084A184B984B4849784E584E3850C750D853884F08539851F853A0000
DE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8F458F468F478F488F498F4A8F4B8F4C8F4D8F4E8F4F8F508F518F528F538F54
8F558F568F578F588F598F5A8F5B8F5C8F5D8F5E8F5F8F608F618F628F638F64
8F658F6A8F808F8C8F928F9D8FA08FA18FA28FA48FA58FA68FA78FAA8FAC8FAD
8FAE8FAF8FB28FB38FB48FB58FB78FB88FBA8FBB8FBC8FBF8FC08FC38FC60000
8FC98FCA8FCB8FCC8FCD8FCF8FD28FD68FD78FDA8FE08FE18FE38FE78FEC8FEF
8FF18FF28FF48FF58FF68FFA8FFB8FFC8FFE8FFF90079008900C900E90139015
90188556853B84FF84FC8559854885688564855E857A77A285438572857B85A4
85A88587858F857985AE859C858585B985B785B085D385C185DC85FF86278605
86298616863C5EFE5F08593C594180375955595A5958530F5C225C255C2C5C34
624C626A629F62BB62CA62DA62D762EE632262F66339634B634363AD63F66371
637A638E63B4636D63AC638A636963AE63BC63F263F863E063FF63C463DE63CE
645263C663BE64456441640B641B6420640C64266421645E6484646D64960000
DF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9019901C902390249025902790289029902A902B902C90309031903290339034
90379039903A903D903F904090439045904690489049904A904B904C904E9054
905590569059905A905C905D905E905F906090619064906690679069906A906B
906C906F90709071907290739076907790789079907A907B907C907E90810000
90849085908690879089908A908C908D908E908F90909092909490969098909A
909C909E909F90A090A490A590A790A890A990AB90AD90B290B790BC90BD90BF
90C0647A64B764B8649964BA64C064D064D764E464E265096525652E5F0B5FD2
75195F11535F53F153FD53E953E853FB541254165406544B5452545354545456
54435421545754595423543254825494547754715464549A549B548454765466
549D54D054AD54C254B454D254A754A654D354D4547254A354D554BB54BF54CC
54D954DA54DC54A954AA54A454DD54CF54DE551B54E7552054FD551454F35522
5523550F55115527552A5567558F55B55549556D55415555553F5550553C0000
E0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
90C290C390C690C890C990CB90CC90CD90D290D490D590D690D890D990DA90DE
90DF90E090E390E490E590E990EA90EC90EE90F090F190F290F390F590F690F7
90F990FA90FB90FC90FF91009101910391059106910791089109910A910B910C
910D910E910F911091119112911391149115911691179118911A911B911C0000
911D911F91209121912491259126912791289129912A912B912C912D912E9130
9132913391349135913691379138913A913B913C913D913E913F914091419142
91445537555655755576557755335530555C558B55D2558355B155B955885581
559F557E55D65591557B55DF55BD55BE5594559955EA55F755C9561F55D155EB
55EC55D455E655DD55C455EF55E555F255F355CC55CD55E855F555E48F94561E
5608560C56015624562355FE56005627562D565856395657562C564D56625659
565C564C5654568656645671566B567B567C5685569356AF56D456D756DD56E1
56F556EB56F956FF5704570A5709571C5E0F5E195E145E115E315E3B5E3C0000
E1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9145914791489151915391549155915691589159915B915C915F916091669167
9168916B916D9173917A917B917C9180918191829183918491869188918A918E
918F9193919491959196919791989199919C919D919E919F91A091A191A491A5
91A691A791A891A991AB91AC91B091B191B291B391B691B791B891B991BB0000
91BC91BD91BE91BF91C091C191C291C391C491C591C691C891CB91D091D291D3
91D491D591D691D791D891D991DA91DB91DD91DE91DF91E091E191E291E391E4
91E55E375E445E545E5B5E5E5E615C8C5C7A5C8D5C905C965C885C985C995C91
5C9A5C9C5CB55CA25CBD5CAC5CAB5CB15CA35CC15CB75CC45CD25CE45CCB5CE5
5D025D035D275D265D2E5D245D1E5D065D1B5D585D3E5D345D3D5D6C5D5B5D6F
5D5D5D6B5D4B5D4A5D695D745D825D995D9D8C735DB75DC55F735F775F825F87
5F895F8C5F955F995F9C5FA85FAD5FB55FBC88625F6172AD72B072B472B772B8
72C372C172CE72CD72D272E872EF72E972F272F472F7730172F3730372FA0000
E2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
91E691E791E891E991EA91EB91EC91ED91EE91EF91F091F191F291F391F491F5
91F691F791F891F991FA91FB91FC91FD91FE91FF920092019202920392049205
9206920792089209920A920B920C920D920E920F921092119212921392149215
9216921792189219921A921B921C921D921E921F922092219222922392240000
92259226922792289229922A922B922C922D922E922F92309231923292339234
92359236923792389239923A923B923C923D923E923F92409241924292439244
924572FB731773137321730A731E731D7315732273397325732C733873317350
734D73577360736C736F737E821B592598E7592459029963996799689969996A
996B996C99749977997D998099849987998A998D999099919993999499955E80
5E915E8B5E965EA55EA05EB95EB55EBE5EB38D535ED25ED15EDB5EE85EEA81BA
5FC45FC95FD65FCF60035FEE60045FE15FE45FFE600560065FEA5FED5FF86019
60356026601B600F600D6029602B600A603F602160786079607B607A60420000
E3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9246924792489249924A924B924C924D924E924F925092519252925392549255
9256925792589259925A925B925C925D925E925F926092619262926392649265
9266926792689269926A926B926C926D926E926F927092719272927392759276
927792789279927A927B927C927D927E927F9280928192829283928492850000
9286928792889289928A928B928C928D928F9290929192929293929492959296
929792989299929A929B929C929D929E929F92A092A192A292A392A492A592A6
92A7606A607D6096609A60AD609D60836092608C609B60EC60BB60B160DD60D8
60C660DA60B4612061266115612360F46100610E612B614A617561AC619461A7
61B761D461F55FDD96B395E995EB95F195F395F595F695FC95FE960396049606
9608960A960B960C960D960F96129615961696179619961A4E2C723F62156C35
6C546C5C6C4A6CA36C856C906C946C8C6C686C696C746C766C866CA96CD06CD4
6CAD6CF76CF86CF16CD76CB26CE06CD66CFA6CEB6CEE6CB16CD36CEF6CFE0000
E4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
92A892A992AA92AB92AC92AD92AF92B092B192B292B392B492B592B692B792B8
92B992BA92BB92BC92BD92BE92BF92C092C192C292C392C492C592C692C792C9
92CA92CB92CC92CD92CE92CF92D092D192D292D392D492D592D692D792D892D9
92DA92DB92DC92DD92DE92DF92E092E192E292E392E492E592E692E792E80000
92E992EA92EB92EC92ED92EE92EF92F092F192F292F392F492F592F692F792F8
92F992FA92FB92FC92FD92FE92FF930093019302930393049305930693079308
93096D396D276D0C6D436D486D076D046D196D0E6D2B6D4D6D2E6D356D1A6D4F
6D526D546D336D916D6F6D9E6DA06D5E6D936D946D5C6D606D7C6D636E1A6DC7
6DC56DDE6E0E6DBF6DE06E116DE66DDD6DD96E166DAB6E0C6DAE6E2B6E6E6E4E
6E6B6EB26E5F6E866E536E546E326E256E446EDF6EB16E986EE06F2D6EE26EA5
6EA76EBD6EBB6EB76ED76EB46ECF6E8F6EC26E9F6F626F466F476F246F156EF9
6F2F6F366F4B6F746F2A6F096F296F896F8D6F8C6F786F726F7C6F7A6FD10000
E5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
930A930B930C930D930E930F9310931193129313931493159316931793189319
931A931B931C931D931E931F9320932193229323932493259326932793289329
932A932B932C932D932E932F9330933193329333933493359336933793389339
933A933B933C933D933F93409341934293439344934593469347934893490000
934A934B934C934D934E934F9350935193529353935493559356935793589359
935A935B935C935D935E935F9360936193629363936493659366936793689369
936B6FC96FA76FB96FB66FC26FE16FEE6FDE6FE06FEF701A7023701B70397035
704F705E5B805B845B955B935BA55BB8752F9A9E64345BE45BEE89305BF08E47
8B078FB68FD38FD58FE58FEE8FE48FE98FE68FF38FE890059004900B90269011
900D9016902190359036902D902F9044905190529050906890589062905B66B9
9074907D908290889083908B5F505F575F565F585C3B54AB5C505C595B715C63
5C667FBC5F2A5F295F2D82745F3C9B3B5C6E59815983598D59A959AA59A30000
E6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
936C936D936E936F9370937193729373937493759376937793789379937A937B
937C937D937E937F9380938193829383938493859386938793889389938A938B
938C938D938E9390939193929393939493959396939793989399939A939B939C
939D939E939F93A093A193A293A393A493A593A693A793A893A993AA93AB0000
93AC93AD93AE93AF93B093B193B293B393B493B593B693B793B893B993BA93BB
93BC93BD93BE93BF93C093C193C293C393C493C593C693C793C893C993CB93CC
93CD599759CA59AB599E59A459D259B259AF59D759BE5A055A0659DD5A0859E3
59D859F95A0C5A095A325A345A115A235A135A405A675A4A5A555A3C5A625A75
80EC5AAA5A9B5A775A7A5ABE5AEB5AB25AD25AD45AB85AE05AE35AF15AD65AE6
5AD85ADC5B095B175B165B325B375B405C155C1C5B5A5B655B735B515B535B62
9A759A779A789A7A9A7F9A7D9A809A819A859A889A8A9A909A929A939A969A98
9A9B9A9C9A9D9A9F9AA09AA29AA39AA59AA77E9F7EA17EA37EA57EA87EA90000
E7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
93CE93CF93D093D193D293D393D493D593D793D893D993DA93DB93DC93DD93DE
93DF93E093E193E293E393E493E593E693E793E893E993EA93EB93EC93ED93EE
93EF93F093F193F293F393F493F593F693F793F893F993FA93FB93FC93FD93FE
93FF9400940194029403940494059406940794089409940A940B940C940D0000
940E940F9410941194129413941494159416941794189419941A941B941C941D
941E941F9420942194229423942494259426942794289429942A942B942C942D
942E7EAD7EB07EBE7EC07EC17EC27EC97ECB7ECC7ED07ED47ED77EDB7EE07EE1
7EE87EEB7EEE7EEF7EF17EF27F0D7EF67EFA7EFB7EFE7F017F027F037F077F08
7F0B7F0C7F0F7F117F127F177F197F1C7F1B7F1F7F217F227F237F247F257F26
7F277F2A7F2B7F2C7F2D7F2F7F307F317F327F337F355E7A757F5DDB753E9095
738E739173AE73A2739F73CF73C273D173B773B373C073C973C873E573D9987C
740A73E973E773DE73BA73F2740F742A745B7426742574287430742E742C0000
E8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
942F9430943194329433943494359436943794389439943A943B943C943D943F
9440944194429443944494459446944794489449944A944B944C944D944E944F
9450945194529453945494559456945794589459945A945B945C945D945E945F
9460946194629463946494659466946794689469946A946C946D946E946F0000
9470947194729473947494759476947794789479947A947B947C947D947E947F
9480948194829483948494919496949894C794CF94D394D494DA94E694FB951C
9520741B741A7441745C7457745574597477746D747E749C748E748074817487
748B749E74A874A9749074A774D274BA97EA97EB97EC674C6753675E67486769
67A56787676A6773679867A7677567A8679E67AD678B6777677C67F0680967D8
680A67E967B0680C67D967B567DA67B367DD680067C367B867E2680E67C167FD
6832683368606861684E6862684468646883681D68556866684168676840683E
684A6849682968B5688F687468776893686B68C2696E68FC691F692068F90000
E9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
95279533953D95439548954B9555955A9560956E95749575957795789579957A
957B957C957D957E9580958195829583958495859586958795889589958A958B
958C958D958E958F9590959195929593959495959596959795989599959A959B
959C959D959E959F95A095A195A295A395A495A595A695A795A895A995AA0000
95AB95AC95AD95AE95AF95B095B195B295B395B495B595B695B795B895B995BA
95BB95BC95BD95BE95BF95C095C195C295C395C495C595C695C795C895C995CA
95CB692468F0690B6901695768E369106971693969606942695D6984696B6980
69986978693469CC6987698869CE6989696669636979699B69A769BB69AB69AD
69D469B169C169CA69DF699569E0698D69FF6A2F69ED6A176A186A6569F26A44
6A3E6AA06A506A5B6A356A8E6A796A3D6A286A586A7C6A916A906AA96A976AAB
733773526B816B826B876B846B926B936B8D6B9A6B9B6BA16BAA8F6B8F6D8F71
8F728F738F758F768F788F778F798F7A8F7C8F7E8F818F828F848F878F8B0000
EA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
95CC95CD95CE95CF95D095D195D295D395D495D595D695D795D895D995DA95DB
95DC95DD95DE95DF95E095E195E295E395E495E595E695E795EC95FF96079613
9618961B961E96209623962496259626962796289629962B962C962D962F9630
963796389639963A963E96419643964A964E964F965196529653965696570000
96589659965A965C965D965E9660966396659666966B966D966E966F96709671
967396789679967A967B967C967D967E967F9680968196829683968496879689
968A8F8D8F8E8F8F8F988F9A8ECE620B6217621B621F6222622162256224622C
81E774EF74F474FF750F75117513653465EE65EF65F0660A6619677266036615
6600708566F7661D66346631663666358006665F66546641664F665666616657
66776684668C66A7669D66BE66DB66DC66E666E98D328D338D368D3B8D3D8D40
8D458D468D488D498D478D4D8D558D5989C789CA89CB89CC89CE89CF89D089D1
726E729F725D7266726F727E727F7284728B728D728F72926308633263B00000
EB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
968C968E96919692969396959696969A969B969D969E969F96A096A196A296A3
96A496A596A696A896A996AA96AB96AC96AD96AE96AF96B196B296B496B596B7
96B896BA96BB96BF96C296C396C896CA96CB96D096D196D396D496D696D796D8
96D996DA96DB96DC96DD96DE96DF96E196E296E396E496E596E696E796EB0000
96EC96ED96EE96F096F196F296F496F596F896FA96FB96FC96FD96FF97029703
9705970A970B970C97109711971297149715971797189719971A971B971D971F
9720643F64D880046BEA6BF36BFD6BF56BF96C056C076C066C0D6C156C186C19
6C1A6C216C296C246C2A6C3265356555656B724D72527256723086625216809F
809C809380BC670A80BD80B180AB80AD80B480B780E780E880E980EA80DB80C2
80C480D980CD80D7671080DD80EB80F180F480ED810D810E80F280FC67158112
8C5A8136811E812C811881328148814C815381748159815A817181608169817C
817D816D8167584D5AB58188818281916ED581A381AA81CC672681CA81BB0000
EC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
972197229723972497259726972797289729972B972C972E972F973197339734
973597369737973A973B973C973D973F97409741974297439744974597469747
97489749974A974B974C974D974E974F975097519754975597579758975A975C
975D975F97639764976697679768976A976B976C976D976E976F977097710000
97729775977797789779977A977B977D977E977F978097819782978397849786
978797889789978A978C978E978F979097939795979697979799979A979B979C
979D81C181A66B246B376B396B436B466B5998D198D298D398D598D998DA6BB3
5F406BC289F365909F51659365BC65C665C465C365CC65CE65D265D67080709C
7096709D70BB70C070B770AB70B170E870CA711071137116712F71317173715C
716871457172714A7178717A719871B371B571A871A071E071D471E771F9721D
7228706C7118716671B9623E623D624362486249793B794079467949795B795C
7953795A796279577960796F7967797A7985798A799A79A779B35FD15FD00000
ED
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
979E979F97A197A297A497A597A697A797A897A997AA97AC97AE97B097B197B3
97B597B697B797B897B997BA97BB97BC97BD97BE97BF97C097C197C297C397C4
97C597C697C797C897C997CA97CB97CC97CD97CE97CF97D097D197D297D397D4
97D597D697D797D897D997DA97DB97DC97DD97DE97DF97E097E197E297E30000
97E497E597E897EE97EF97F097F197F297F497F797F897F997FA97FB97FC97FD
97FE97FF9800980198029803980498059806980798089809980A980B980C980D
980E603C605D605A606760416059606360AB6106610D615D61A9619D61CB61D1
62068080807F6C936CF66DFC77F677F87800780978177818781165AB782D781C
781D7839783A783B781F783C7825782C78237829784E786D7856785778267850
7847784C786A789B7893789A7887789C78A178A378B278B978A578D478D978C9
78EC78F2790578F479137924791E79349F9B9EF99EFB9EFC76F17704770D76F9
77077708771A77227719772D7726773577387750775177477743775A77680000
EE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
980F9810981198129813981498159816981798189819981A981B981C981D981E
981F9820982198229823982498259826982798289829982A982B982C982D982E
982F9830983198329833983498359836983798389839983A983B983C983D983E
983F9840984198429843984498459846984798489849984A984B984C984D0000
984E984F9850985198529853985498559856985798589859985A985B985C985D
985E985F9860986198629863986498659866986798689869986A986B986C986D
986E77627765777F778D777D7780778C7791779F77A077B077B577BD753A7540
754E754B7548755B7572757975837F587F617F5F8A487F687F747F717F797F81
7F7E76CD76E58832948594869487948B948A948C948D948F9490949494979495
949A949B949C94A394A494AB94AA94AD94AC94AF94B094B294B494B694B794B8
94B994BA94BC94BD94BF94C494C894C994CA94CB94CC94CD94CE94D094D194D2
94D594D694D794D994D894DB94DE94DF94E094E294E494E594E794E894EA0000
EF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
986F98709871987298739874988B988E98929895989998A398A898A998AA98AB
98AC98AD98AE98AF98B098B198B298B398B498B598B698B798B898B998BA98BB
98BC98BD98BE98BF98C098C198C298C398C498C598C698C798C898C998CA98CB
98CC98CD98CF98D098D498D698D798DB98DC98DD98E098E198E298E398E40000
98E598E698E998EA98EB98EC98ED98EE98EF98F098F198F298F398F498F598F6
98F798F898F998FA98FB98FC98FD98FE98FF9900990199029903990499059906
990794E994EB94EE94EF94F394F494F594F794F994FC94FD94FF950395029506
95079509950A950D950E950F951295139514951595169518951B951D951E951F
9522952A952B9529952C953195329534953695379538953C953E953F95429535
9544954595469549954C954E954F9552955395549556955795589559955B955E
955F955D95619562956495659566956795689569956A956B956C956F95719572
9573953A77E777EC96C979D579ED79E379EB7A065D477A037A027A1E7A140000
F0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
99089909990A990B990C990E990F991199129913991499159916991799189919
991A991B991C991D991E991F9920992199229923992499259926992799289929
992A992B992C992D992F9930993199329933993499359936993799389939993A
993B993C993D993E993F99409941994299439944994599469947994899490000
994A994B994C994D994E994F99509951995299539956995799589959995A995B
995C995D995E995F99609961996299649966997399789979997B997E99829983
99897A397A377A519ECF99A57A707688768E7693769976A474DE74E0752C9E20
9E229E289E299E2A9E2B9E2C9E329E319E369E389E379E399E3A9E3E9E419E42
9E449E469E479E489E499E4B9E4C9E4E9E519E559E579E5A9E5B9E5C9E5E9E63
9E669E679E689E699E6A9E6B9E6C9E719E6D9E7375927594759675A0759D75AC
75A375B375B475B875C475B175B075C375C275D675CD75E375E875E675E475EB
75E7760375F175FC75FF761076007605760C7617760A76257618761576190000
F1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
998C998E999A999B999C999D999E999F99A099A199A299A399A499A699A799A9
99AA99AB99AC99AD99AE99AF99B099B199B299B399B499B599B699B799B899B9
99BA99BB99BC99BD99BE99BF99C099C199C299C399C499C599C699C799C899C9
99CA99CB99CC99CD99CE99CF99D099D199D299D399D499D599D699D799D80000
99D999DA99DB99DC99DD99DE99DF99E099E199E299E399E499E599E699E799E8
99E999EA99EB99EC99ED99EE99EF99F099F199F299F399F499F599F699F799F8
99F9761B763C762276207640762D7630763F76357643763E7633764D765E7654
765C7656766B766F7FCA7AE67A787A797A807A867A887A957AA67AA07AAC7AA8
7AAD7AB3886488698872887D887F888288A288C688B788BC88C988E288CE88E3
88E588F1891A88FC88E888FE88F0892189198913891B890A8934892B89368941
8966897B758B80E576B276B477DC801280148016801C80208022802580268027
802980288031800B803580438046804D80528069807189839878988098830000
F2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
99FA99FB99FC99FD99FE99FF9A009A019A029A039A049A059A069A079A089A09
9A0A9A0B9A0C9A0D9A0E9A0F9A109A119A129A139A149A159A169A179A189A19
9A1A9A1B9A1C9A1D9A1E9A1F9A209A219A229A239A249A259A269A279A289A29
9A2A9A2B9A2C9A2D9A2E9A2F9A309A319A329A339A349A359A369A379A380000
9A399A3A9A3B9A3C9A3D9A3E9A3F9A409A419A429A439A449A459A469A479A48
9A499A4A9A4B9A4C9A4D9A4E9A4F9A509A519A529A539A549A559A569A579A58
9A599889988C988D988F9894989A989B989E989F98A198A298A598A6864D8654
866C866E867F867A867C867B86A8868D868B86AC869D86A786A386AA869386A9
86B686C486B586CE86B086BA86B186AF86C986CF86B486E986F186F286ED86F3
86D0871386DE86F486DF86D886D18703870786F88708870A870D87098723873B
871E8725872E871A873E87488734873187298737873F87828722877D877E877B
87608770874C876E878B87538763877C876487598765879387AF87A887D20000
F3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9A5A9A5B9A5C9A5D9A5E9A5F9A609A619A629A639A649A659A669A679A689A69
9A6A9A6B9A729A839A899A8D9A8E9A949A959A999AA69AA99AAA9AAB9AAC9AAD
9AAE9AAF9AB29AB39AB49AB59AB99ABB9ABD9ABE9ABF9AC39AC49AC69AC79AC8
9AC99ACA9ACD9ACE9ACF9AD09AD29AD49AD59AD69AD79AD99ADA9ADB9ADC0000
9ADD9ADE9AE09AE29AE39AE49AE59AE79AE89AE99AEA9AEC9AEE9AF09AF19AF2
9AF39AF49AF59AF69AF79AF89AFA9AFC9AFD9AFE9AFF9B009B019B029B049B05
9B0687C68788878587AD8797878387AB87E587AC87B587B387CB87D387BD87D1
87C087CA87DB87EA87E087EE8816881387FE880A881B88218839883C7F367F42
7F447F4582107AFA7AFD7B087B037B047B157B0A7B2B7B0F7B477B387B2A7B19
7B2E7B317B207B257B247B337B3E7B1E7B587B5A7B457B757B4C7B5D7B607B6E
7B7B7B627B727B717B907BA67BA77BB87BAC7B9D7BA87B857BAA7B9C7BA27BAB
7BB47BD17BC17BCC7BDD7BDA7BE57BE67BEA7C0C7BFE7BFC7C0F7C167C0B0000
F4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9B079B099B0A9B0B9B0C9B0D9B0E9B109B119B129B149B159B169B179B189B19
9B1A9B1B9B1C9B1D9B1E9B209B219B229B249B259B269B279B289B299B2A9B2B
9B2C9B2D9B2E9B309B319B339B349B359B369B379B389B399B3A9B3D9B3E9B3F
9B409B469B4A9B4B9B4C9B4E9B509B529B539B559B569B579B589B599B5A0000
9B5B9B5C9B5D9B5E9B5F9B609B619B629B639B649B659B669B679B689B699B6A
9B6B9B6C9B6D9B6E9B6F9B709B719B729B739B749B759B769B779B789B799B7A
9B7B7C1F7C2A7C267C387C417C4081FE82018202820481EC8844822182228223
822D822F8228822B8238823B82338234823E82448249824B824F825A825F8268
887E8885888888D888DF895E7F9D7F9F7FA77FAF7FB07FB27C7C65497C917C9D
7C9C7C9E7CA27CB27CBC7CBD7CC17CC77CCC7CCD7CC87CC57CD77CE8826E66A8
7FBF7FCE7FD57FE57FE17FE67FE97FEE7FF37CF87D777DA67DAE7E477E9B9EB8
9EB48D738D848D948D918DB18D678D6D8C478C49914A9150914E914F91640000
F5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9B7C9B7D9B7E9B7F9B809B819B829B839B849B859B869B879B889B899B8A9B8B
9B8C9B8D9B8E9B8F9B909B919B929B939B949B959B969B979B989B999B9A9B9B
9B9C9B9D9B9E9B9F9BA09BA19BA29BA39BA49BA59BA69BA79BA89BA99BAA9BAB
9BAC9BAD9BAE9BAF9BB09BB19BB29BB39BB49BB59BB69BB79BB89BB99BBA0000
9BBB9BBC9BBD9BBE9BBF9BC09BC19BC29BC39BC49BC59BC69BC79BC89BC99BCA
9BCB9BCC9BCD9BCE9BCF9BD09BD19BD29BD39BD49BD59BD69BD79BD89BD99BDA
9BDB9162916191709169916F917D917E917291749179918C91859190918D9191
91A291A391AA91AD91AE91AF91B591B491BA8C559E7E8DB88DEB8E058E598E69
8DB58DBF8DBC8DBA8DC48DD68DD78DDA8DDE8DCE8DCF8DDB8DC68DEC8DF78DF8
8DE38DF98DFB8DE48E098DFD8E148E1D8E1F8E2C8E2E8E238E2F8E3A8E408E39
8E358E3D8E318E498E418E428E518E528E4A8E708E768E7C8E6F8E748E858E8F
8E948E908E9C8E9E8C788C828C8A8C858C988C94659B89D689DE89DA89DC0000
F6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9BDC9BDD9BDE9BDF9BE09BE19BE29BE39BE49BE59BE69BE79BE89BE99BEA9BEB
9BEC9BED9BEE9BEF9BF09BF19BF29BF39BF49BF59BF69BF79BF89BF99BFA9BFB
9BFC9BFD9BFE9BFF9C009C019C029C039C049C059C069C079C089C099C0A9C0B
9C0C9C0D9C0E9C0F9C109C119C129C139C149C159C169C179C189C199C1A0000
9C1B9C1C9C1D9C1E9C1F9C209C219C229C239C249C259C269C279C289C299C2A
9C2B9C2C9C2D9C2E9C2F9C309C319C329C339C349C359C369C379C389C399C3A
9C3B89E589EB89EF8A3E8B26975396E996F396EF970697019708970F970E972A
972D9730973E9F809F839F859F869F879F889F899F8A9F8C9EFE9F0B9F0D96B9
96BC96BD96CE96D277BF96E0928E92AE92C8933E936A93CA938F943E946B9C7F
9C829C859C869C879C887A239C8B9C8E9C909C919C929C949C959C9A9C9B9C9E
9C9F9CA09CA19CA29CA39CA59CA69CA79CA89CA99CAB9CAD9CAE9CB09CB19CB2
9CB39CB49CB59CB69CB79CBA9CBB9CBC9CBD9CC49CC59CC69CC79CCA9CCB0000
F7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9C3C9C3D9C3E9C3F9C409C419C429C439C449C459C469C479C489C499C4A9C4B
9C4C9C4D9C4E9C4F9C509C519C529C539C549C559C569C579C589C599C5A9C5B
9C5C9C5D9C5E9C5F9C609C619C629C639C649C659C669C679C689C699C6A9C6B
9C6C9C6D9C6E9C6F9C709C719C729C739C749C759C769C779C789C799C7A0000
9C7B9C7D9C7E9C809C839C849C899C8A9C8C9C8F9C939C969C979C989C999C9D
9CAA9CAC9CAF9CB99CBE9CBF9CC09CC19CC29CC89CC99CD19CD29CDA9CDB9CE0
9CE19CCC9CCD9CCE9CCF9CD09CD39CD49CD59CD79CD89CD99CDC9CDD9CDF9CE2
977C978597919792979497AF97AB97A397B297B49AB19AB09AB79E589AB69ABA
9ABC9AC19AC09AC59AC29ACB9ACC9AD19B459B439B479B499B489B4D9B5198E8
990D992E995599549ADF9AE19AE69AEF9AEB9AFB9AED9AF99B089B0F9B139B1F
9B239EBD9EBE7E3B9E829E879E889E8B9E9293D69E9D9E9F9EDB9EDC9EDD9EE0
9EDF9EE29EE99EE79EE59EEA9EEF9F229F2C9F2F9F399F379F3D9F3E9F440000
F8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9CE39CE49CE59CE69CE79CE89CE99CEA9CEB9CEC9CED9CEE9CEF9CF09CF19CF2
9CF39CF49CF59CF69CF79CF89CF99CFA9CFB9CFC9CFD9CFE9CFF9D009D019D02
9D039D049D059D069D079D089D099D0A9D0B9D0C9D0D9D0E9D0F9D109D119D12
9D139D149D159D169D179D189D199D1A9D1B9D1C9D1D9D1E9D1F9D209D210000
9D229D239D249D259D269D279D289D299D2A9D2B9D2C9D2D9D2E9D2F9D309D31
9D329D339D349D359D369D379D389D399D3A9D3B9D3C9D3D9D3E9D3F9D409D41
9D42000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
F9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9D439D449D459D469D479D489D499D4A9D4B9D4C9D4D9D4E9D4F9D509D519D52
9D539D549D559D569D579D589D599D5A9D5B9D5C9D5D9D5E9D5F9D609D619D62
9D639D649D659D669D679D689D699D6A9D6B9D6C9D6D9D6E9D6F9D709D719D72
9D739D749D759D769D779D789D799D7A9D7B9D7C9D7D9D7E9D7F9D809D810000
9D829D839D849D859D869D879D889D899D8A9D8B9D8C9D8D9D8E9D8F9D909D91
9D929D939D949D959D969D979D989D999D9A9D9B9D9C9D9D9D9E9D9F9DA09DA1
9DA2000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9DA39DA49DA59DA69DA79DA89DA99DAA9DAB9DAC9DAD9DAE9DAF9DB09DB19DB2
9DB39DB49DB59DB69DB79DB89DB99DBA9DBB9DBC9DBD9DBE9DBF9DC09DC19DC2
9DC39DC49DC59DC69DC79DC89DC99DCA9DCB9DCC9DCD9DCE9DCF9DD09DD19DD2
9DD39DD49DD59DD69DD79DD89DD99DDA9DDB9DDC9DDD9DDE9DDF9DE09DE10000
9DE29DE39DE49DE59DE69DE79DE89DE99DEA9DEB9DEC9DED9DEE9DEF9DF09DF1
9DF29DF39DF49DF59DF69DF79DF89DF99DFA9DFB9DFC9DFD9DFE9DFF9E009E01
9E02000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9E039E049E059E069E079E089E099E0A9E0B9E0C9E0D9E0E9E0F9E109E119E12
9E139E149E159E169E179E189E199E1A9E1B9E1C9E1D9E1E9E249E279E2E9E30
9E349E3B9E3C9E409E4D9E509E529E539E549E569E599E5D9E5F9E609E619E62
9E659E6E9E6F9E729E749E759E769E779E789E799E7A9E7B9E7C9E7D9E800000
9E819E839E849E859E869E899E8A9E8C9E8D9E8E9E8F9E909E919E949E959E96
9E979E989E999E9A9E9B9E9C9E9E9EA09EA19EA29EA39EA49EA59EA79EA89EA9
9EAA000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9EAB9EAC9EAD9EAE9EAF9EB09EB19EB29EB39EB59EB69EB79EB99EBA9EBC9EBF
9EC09EC19EC29EC39EC59EC69EC79EC89ECA9ECB9ECC9ED09ED29ED39ED59ED6
9ED79ED99EDA9EDE9EE19EE39EE49EE69EE89EEB9EEC9EED9EEE9EF09EF19EF2
9EF39EF49EF59EF69EF79EF89EFA9EFD9EFF9F009F019F029F039F049F050000
9F069F079F089F099F0A9F0C9F0F9F119F129F149F159F169F189F1A9F1B9F1C
9F1D9F1E9F1F9F219F239F249F259F269F279F289F299F2A9F2B9F2D9F2E9F30
9F31000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9F329F339F349F359F369F389F3A9F3C9F3F9F409F419F429F439F459F469F47
9F489F499F4A9F4B9F4C9F4D9F4E9F4F9F529F539F549F559F569F579F589F59
9F5A9F5B9F5C9F5D9F5E9F5F9F609F619F629F639F649F659F669F679F689F69
9F6A9F6B9F6C9F6D9F6E9F6F9F709F719F729F739F749F759F769F779F780000
9F799F7A9F7B9F7C9F7D9F7E9F819F829F8D9F8E9F8F9F909F919F929F939F94
9F959F969F979F989F9C9F9D9F9E9FA19FA29FA39FA49FA5F92CF979F995F9E7
F9F1000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FA0CFA0DFA0EFA0FFA11FA13FA14FA18FA1FFA20FA21FA23FA24FA27FA28FA29
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/cp949.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
# Encoding file: cp949, multi-byte
M
003F 0 125
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
81
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000AC02AC03AC05AC06AC0BAC0CAC0DAC0EAC0FAC18AC1EAC1FAC21AC22AC23
AC25AC26AC27AC28AC29AC2AAC2BAC2EAC32AC33AC3400000000000000000000
0000AC35AC36AC37AC3AAC3BAC3DAC3EAC3FAC41AC42AC43AC44AC45AC46AC47
AC48AC49AC4AAC4CAC4EAC4FAC50AC51AC52AC53AC5500000000000000000000
0000AC56AC57AC59AC5AAC5BAC5DAC5EAC5FAC60AC61AC62AC63AC64AC65AC66
AC67AC68AC69AC6AAC6BAC6CAC6DAC6EAC6FAC72AC73AC75AC76AC79AC7BAC7C
AC7DAC7EAC7FAC82AC87AC88AC8DAC8EAC8FAC91AC92AC93AC95AC96AC97AC98
AC99AC9AAC9BAC9EACA2ACA3ACA4ACA5ACA6ACA7ACABACADACAEACB1ACB2ACB3
ACB4ACB5ACB6ACB7ACBAACBEACBFACC0ACC2ACC3ACC5ACC6ACC7ACC9ACCAACCB
ACCDACCEACCFACD0ACD1ACD2ACD3ACD4ACD6ACD8ACD9ACDAACDBACDCACDDACDE
ACDFACE2ACE3ACE5ACE6ACE9ACEBACEDACEEACF2ACF4ACF7ACF8ACF9ACFAACFB
ACFEACFFAD01AD02AD03AD05AD07AD08AD09AD0AAD0BAD0EAD10AD12AD130000
82
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000AD14AD15AD16AD17AD19AD1AAD1BAD1DAD1EAD1FAD21AD22AD23AD24AD25
AD26AD27AD28AD2AAD2BAD2EAD2FAD30AD31AD32AD3300000000000000000000
0000AD36AD37AD39AD3AAD3BAD3DAD3EAD3FAD40AD41AD42AD43AD46AD48AD4A
AD4BAD4CAD4DAD4EAD4FAD51AD52AD53AD55AD56AD5700000000000000000000
0000AD59AD5AAD5BAD5CAD5DAD5EAD5FAD60AD62AD64AD65AD66AD67AD68AD69
AD6AAD6BAD6EAD6FAD71AD72AD77AD78AD79AD7AAD7EAD80AD83AD84AD85AD86
AD87AD8AAD8BAD8DAD8EAD8FAD91AD92AD93AD94AD95AD96AD97AD98AD99AD9A
AD9BAD9EAD9FADA0ADA1ADA2ADA3ADA5ADA6ADA7ADA8ADA9ADAAADABADACADAD
ADAEADAFADB0ADB1ADB2ADB3ADB4ADB5ADB6ADB8ADB9ADBAADBBADBCADBDADBE
ADBFADC2ADC3ADC5ADC6ADC7ADC9ADCAADCBADCCADCDADCEADCFADD2ADD4ADD5
ADD6ADD7ADD8ADD9ADDAADDBADDDADDEADDFADE1ADE2ADE3ADE5ADE6ADE7ADE8
ADE9ADEAADEBADECADEDADEEADEFADF0ADF1ADF2ADF3ADF4ADF5ADF6ADF70000
83
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000ADFAADFBADFDADFEAE02AE03AE04AE05AE06AE07AE0AAE0CAE0EAE0FAE10
AE11AE12AE13AE15AE16AE17AE18AE19AE1AAE1BAE1C00000000000000000000
0000AE1DAE1EAE1FAE20AE21AE22AE23AE24AE25AE26AE27AE28AE29AE2AAE2B
AE2CAE2DAE2EAE2FAE32AE33AE35AE36AE39AE3BAE3C00000000000000000000
0000AE3DAE3EAE3FAE42AE44AE47AE48AE49AE4BAE4FAE51AE52AE53AE55AE57
AE58AE59AE5AAE5BAE5EAE62AE63AE64AE66AE67AE6AAE6BAE6DAE6EAE6FAE71
AE72AE73AE74AE75AE76AE77AE7AAE7EAE7FAE80AE81AE82AE83AE86AE87AE88
AE89AE8AAE8BAE8DAE8EAE8FAE90AE91AE92AE93AE94AE95AE96AE97AE98AE99
AE9AAE9BAE9CAE9DAE9EAE9FAEA0AEA1AEA2AEA3AEA4AEA5AEA6AEA7AEA8AEA9
AEAAAEABAEACAEADAEAEAEAFAEB0AEB1AEB2AEB3AEB4AEB5AEB6AEB7AEB8AEB9
AEBAAEBBAEBFAEC1AEC2AEC3AEC5AEC6AEC7AEC8AEC9AECAAECBAECEAED2AED3
AED4AED5AED6AED7AEDAAEDBAEDDAEDEAEDFAEE0AEE1AEE2AEE3AEE4AEE50000
84
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000AEE6AEE7AEE9AEEAAEECAEEEAEEFAEF0AEF1AEF2AEF3AEF5AEF6AEF7AEF9
AEFAAEFBAEFDAEFEAEFFAF00AF01AF02AF03AF04AF0500000000000000000000
0000AF06AF09AF0AAF0BAF0CAF0EAF0FAF11AF12AF13AF14AF15AF16AF17AF18
AF19AF1AAF1BAF1CAF1DAF1EAF1FAF20AF21AF22AF2300000000000000000000
0000AF24AF25AF26AF27AF28AF29AF2AAF2BAF2EAF2FAF31AF33AF35AF36AF37
AF38AF39AF3AAF3BAF3EAF40AF44AF45AF46AF47AF4AAF4BAF4CAF4DAF4EAF4F
AF51AF52AF53AF54AF55AF56AF57AF58AF59AF5AAF5BAF5EAF5FAF60AF61AF62
AF63AF66AF67AF68AF69AF6AAF6BAF6CAF6DAF6EAF6FAF70AF71AF72AF73AF74
AF75AF76AF77AF78AF7AAF7BAF7CAF7DAF7EAF7FAF81AF82AF83AF85AF86AF87
AF89AF8AAF8BAF8CAF8DAF8EAF8FAF92AF93AF94AF96AF97AF98AF99AF9AAF9B
AF9DAF9EAF9FAFA0AFA1AFA2AFA3AFA4AFA5AFA6AFA7AFA8AFA9AFAAAFABAFAC
AFADAFAEAFAFAFB0AFB1AFB2AFB3AFB4AFB5AFB6AFB7AFBAAFBBAFBDAFBE0000
85
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000AFBFAFC1AFC2AFC3AFC4AFC5AFC6AFCAAFCCAFCFAFD0AFD1AFD2AFD3AFD5
AFD6AFD7AFD8AFD9AFDAAFDBAFDDAFDEAFDFAFE0AFE100000000000000000000
0000AFE2AFE3AFE4AFE5AFE6AFE7AFEAAFEBAFECAFEDAFEEAFEFAFF2AFF3AFF5
AFF6AFF7AFF9AFFAAFFBAFFCAFFDAFFEAFFFB002B00300000000000000000000
0000B005B006B007B008B009B00AB00BB00DB00EB00FB011B012B013B015B016
B017B018B019B01AB01BB01EB01FB020B021B022B023B024B025B026B027B029
B02AB02BB02CB02DB02EB02FB030B031B032B033B034B035B036B037B038B039
B03AB03BB03CB03DB03EB03FB040B041B042B043B046B047B049B04BB04DB04F
B050B051B052B056B058B05AB05BB05CB05EB05FB060B061B062B063B064B065
B066B067B068B069B06AB06BB06CB06DB06EB06FB070B071B072B073B074B075
B076B077B078B079B07AB07BB07EB07FB081B082B083B085B086B087B088B089
B08AB08BB08EB090B092B093B094B095B096B097B09BB09DB09EB0A3B0A40000
86
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B0A5B0A6B0A7B0AAB0B0B0B2B0B6B0B7B0B9B0BAB0BBB0BDB0BEB0BFB0C0
B0C1B0C2B0C3B0C6B0CAB0CBB0CCB0CDB0CEB0CFB0D200000000000000000000
0000B0D3B0D5B0D6B0D7B0D9B0DAB0DBB0DCB0DDB0DEB0DFB0E1B0E2B0E3B0E4
B0E6B0E7B0E8B0E9B0EAB0EBB0ECB0EDB0EEB0EFB0F000000000000000000000
0000B0F1B0F2B0F3B0F4B0F5B0F6B0F7B0F8B0F9B0FAB0FBB0FCB0FDB0FEB0FF
B100B101B102B103B104B105B106B107B10AB10DB10EB10FB111B114B115B116
B117B11AB11EB11FB120B121B122B126B127B129B12AB12BB12DB12EB12FB130
B131B132B133B136B13AB13BB13CB13DB13EB13FB142B143B145B146B147B149
B14AB14BB14CB14DB14EB14FB152B153B156B157B159B15AB15BB15DB15EB15F
B161B162B163B164B165B166B167B168B169B16AB16BB16CB16DB16EB16FB170
B171B172B173B174B175B176B177B17AB17BB17DB17EB17FB181B183B184B185
B186B187B18AB18CB18EB18FB190B191B195B196B197B199B19AB19BB19D0000
87
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B19EB19FB1A0B1A1B1A2B1A3B1A4B1A5B1A6B1A7B1A9B1AAB1ABB1ACB1AD
B1AEB1AFB1B0B1B1B1B2B1B3B1B4B1B5B1B6B1B7B1B800000000000000000000
0000B1B9B1BAB1BBB1BCB1BDB1BEB1BFB1C0B1C1B1C2B1C3B1C4B1C5B1C6B1C7
B1C8B1C9B1CAB1CBB1CDB1CEB1CFB1D1B1D2B1D3B1D500000000000000000000
0000B1D6B1D7B1D8B1D9B1DAB1DBB1DEB1E0B1E1B1E2B1E3B1E4B1E5B1E6B1E7
B1EAB1EBB1EDB1EEB1EFB1F1B1F2B1F3B1F4B1F5B1F6B1F7B1F8B1FAB1FCB1FE
B1FFB200B201B202B203B206B207B209B20AB20DB20EB20FB210B211B212B213
B216B218B21AB21BB21CB21DB21EB21FB221B222B223B224B225B226B227B228
B229B22AB22BB22CB22DB22EB22FB230B231B232B233B235B236B237B238B239
B23AB23BB23DB23EB23FB240B241B242B243B244B245B246B247B248B249B24A
B24BB24CB24DB24EB24FB250B251B252B253B254B255B256B257B259B25AB25B
B25DB25EB25FB261B262B263B264B265B266B267B26AB26BB26CB26DB26E0000
88
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B26FB270B271B272B273B276B277B278B279B27AB27BB27DB27EB27FB280
B281B282B283B286B287B288B28AB28BB28CB28DB28E00000000000000000000
0000B28FB292B293B295B296B297B29BB29CB29DB29EB29FB2A2B2A4B2A7B2A8
B2A9B2ABB2ADB2AEB2AFB2B1B2B2B2B3B2B5B2B6B2B700000000000000000000
0000B2B8B2B9B2BAB2BBB2BCB2BDB2BEB2BFB2C0B2C1B2C2B2C3B2C4B2C5B2C6
B2C7B2CAB2CBB2CDB2CEB2CFB2D1B2D3B2D4B2D5B2D6B2D7B2DAB2DCB2DEB2DF
B2E0B2E1B2E3B2E7B2E9B2EAB2F0B2F1B2F2B2F6B2FCB2FDB2FEB302B303B305
B306B307B309B30AB30BB30CB30DB30EB30FB312B316B317B318B319B31AB31B
B31DB31EB31FB320B321B322B323B324B325B326B327B328B329B32AB32BB32C
B32DB32EB32FB330B331B332B333B334B335B336B337B338B339B33AB33BB33C
B33DB33EB33FB340B341B342B343B344B345B346B347B348B349B34AB34BB34C
B34DB34EB34FB350B351B352B353B357B359B35AB35DB360B361B362B3630000
89
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B366B368B36AB36CB36DB36FB372B373B375B376B377B379B37AB37BB37C
B37DB37EB37FB382B386B387B388B389B38AB38BB38D00000000000000000000
0000B38EB38FB391B392B393B395B396B397B398B399B39AB39BB39CB39DB39E
B39FB3A2B3A3B3A4B3A5B3A6B3A7B3A9B3AAB3ABB3AD00000000000000000000
0000B3AEB3AFB3B0B3B1B3B2B3B3B3B4B3B5B3B6B3B7B3B8B3B9B3BAB3BBB3BC
B3BDB3BEB3BFB3C0B3C1B3C2B3C3B3C6B3C7B3C9B3CAB3CDB3CFB3D1B3D2B3D3
B3D6B3D8B3DAB3DCB3DEB3DFB3E1B3E2B3E3B3E5B3E6B3E7B3E9B3EAB3EBB3EC
B3EDB3EEB3EFB3F0B3F1B3F2B3F3B3F4B3F5B3F6B3F7B3F8B3F9B3FAB3FBB3FD
B3FEB3FFB400B401B402B403B404B405B406B407B408B409B40AB40BB40CB40D
B40EB40FB411B412B413B414B415B416B417B419B41AB41BB41DB41EB41FB421
B422B423B424B425B426B427B42AB42CB42DB42EB42FB430B431B432B433B435
B436B437B438B439B43AB43BB43CB43DB43EB43FB440B441B442B443B4440000
8A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B445B446B447B448B449B44AB44BB44CB44DB44EB44FB452B453B455B456
B457B459B45AB45BB45CB45DB45EB45FB462B464B46600000000000000000000
0000B467B468B469B46AB46BB46DB46EB46FB470B471B472B473B474B475B476
B477B478B479B47AB47BB47CB47DB47EB47FB481B48200000000000000000000
0000B483B484B485B486B487B489B48AB48BB48CB48DB48EB48FB490B491B492
B493B494B495B496B497B498B499B49AB49BB49CB49EB49FB4A0B4A1B4A2B4A3
B4A5B4A6B4A7B4A9B4AAB4ABB4ADB4AEB4AFB4B0B4B1B4B2B4B3B4B4B4B6B4B8
B4BAB4BBB4BCB4BDB4BEB4BFB4C1B4C2B4C3B4C5B4C6B4C7B4C9B4CAB4CBB4CC
B4CDB4CEB4CFB4D1B4D2B4D3B4D4B4D6B4D7B4D8B4D9B4DAB4DBB4DEB4DFB4E1
B4E2B4E5B4E7B4E8B4E9B4EAB4EBB4EEB4F0B4F2B4F3B4F4B4F5B4F6B4F7B4F9
B4FAB4FBB4FCB4FDB4FEB4FFB500B501B502B503B504B505B506B507B508B509
B50AB50BB50CB50DB50EB50FB510B511B512B513B516B517B519B51AB51D0000
8B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B51EB51FB520B521B522B523B526B52BB52CB52DB52EB52FB532B533B535
B536B537B539B53AB53BB53CB53DB53EB53FB542B54600000000000000000000
0000B547B548B549B54AB54EB54FB551B552B553B555B556B557B558B559B55A
B55BB55EB562B563B564B565B566B567B568B569B56A00000000000000000000
0000B56BB56CB56DB56EB56FB570B571B572B573B574B575B576B577B578B579
B57AB57BB57CB57DB57EB57FB580B581B582B583B584B585B586B587B588B589
B58AB58BB58CB58DB58EB58FB590B591B592B593B594B595B596B597B598B599
B59AB59BB59CB59DB59EB59FB5A2B5A3B5A5B5A6B5A7B5A9B5ACB5ADB5AEB5AF
B5B2B5B6B5B7B5B8B5B9B5BAB5BEB5BFB5C1B5C2B5C3B5C5B5C6B5C7B5C8B5C9
B5CAB5CBB5CEB5D2B5D3B5D4B5D5B5D6B5D7B5D9B5DAB5DBB5DCB5DDB5DEB5DF
B5E0B5E1B5E2B5E3B5E4B5E5B5E6B5E7B5E8B5E9B5EAB5EBB5EDB5EEB5EFB5F0
B5F1B5F2B5F3B5F4B5F5B5F6B5F7B5F8B5F9B5FAB5FBB5FCB5FDB5FEB5FF0000
8C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B600B601B602B603B604B605B606B607B608B609B60AB60BB60CB60DB60E
B60FB612B613B615B616B617B619B61AB61BB61CB61D00000000000000000000
0000B61EB61FB620B621B622B623B624B626B627B628B629B62AB62BB62DB62E
B62FB630B631B632B633B635B636B637B638B639B63A00000000000000000000
0000B63BB63CB63DB63EB63FB640B641B642B643B644B645B646B647B649B64A
B64BB64CB64DB64EB64FB650B651B652B653B654B655B656B657B658B659B65A
B65BB65CB65DB65EB65FB660B661B662B663B665B666B667B669B66AB66BB66C
B66DB66EB66FB670B671B672B673B674B675B676B677B678B679B67AB67BB67C
B67DB67EB67FB680B681B682B683B684B685B686B687B688B689B68AB68BB68C
B68DB68EB68FB690B691B692B693B694B695B696B697B698B699B69AB69BB69E
B69FB6A1B6A2B6A3B6A5B6A6B6A7B6A8B6A9B6AAB6ADB6AEB6AFB6B0B6B2B6B3
B6B4B6B5B6B6B6B7B6B8B6B9B6BAB6BBB6BCB6BDB6BEB6BFB6C0B6C1B6C20000
8D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B6C3B6C4B6C5B6C6B6C7B6C8B6C9B6CAB6CBB6CCB6CDB6CEB6CFB6D0B6D1
B6D2B6D3B6D5B6D6B6D7B6D8B6D9B6DAB6DBB6DCB6DD00000000000000000000
0000B6DEB6DFB6E0B6E1B6E2B6E3B6E4B6E5B6E6B6E7B6E8B6E9B6EAB6EBB6EC
B6EDB6EEB6EFB6F1B6F2B6F3B6F5B6F6B6F7B6F9B6FA00000000000000000000
0000B6FBB6FCB6FDB6FEB6FFB702B703B704B706B707B708B709B70AB70BB70C
B70DB70EB70FB710B711B712B713B714B715B716B717B718B719B71AB71BB71C
B71DB71EB71FB720B721B722B723B724B725B726B727B72AB72BB72DB72EB731
B732B733B734B735B736B737B73AB73CB73DB73EB73FB740B741B742B743B745
B746B747B749B74AB74BB74DB74EB74FB750B751B752B753B756B757B758B759
B75AB75BB75CB75DB75EB75FB761B762B763B765B766B767B769B76AB76BB76C
B76DB76EB76FB772B774B776B777B778B779B77AB77BB77EB77FB781B782B783
B785B786B787B788B789B78AB78BB78EB793B794B795B79AB79BB79DB79E0000
8E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B79FB7A1B7A2B7A3B7A4B7A5B7A6B7A7B7AAB7AEB7AFB7B0B7B1B7B2B7B3
B7B6B7B7B7B9B7BAB7BBB7BCB7BDB7BEB7BFB7C0B7C100000000000000000000
0000B7C2B7C3B7C4B7C5B7C6B7C8B7CAB7CBB7CCB7CDB7CEB7CFB7D0B7D1B7D2
B7D3B7D4B7D5B7D6B7D7B7D8B7D9B7DAB7DBB7DCB7DD00000000000000000000
0000B7DEB7DFB7E0B7E1B7E2B7E3B7E4B7E5B7E6B7E7B7E8B7E9B7EAB7EBB7EE
B7EFB7F1B7F2B7F3B7F5B7F6B7F7B7F8B7F9B7FAB7FBB7FEB802B803B804B805
B806B80AB80BB80DB80EB80FB811B812B813B814B815B816B817B81AB81CB81E
B81FB820B821B822B823B826B827B829B82AB82BB82DB82EB82FB830B831B832
B833B836B83AB83BB83CB83DB83EB83FB841B842B843B845B846B847B848B849
B84AB84BB84CB84DB84EB84FB850B852B854B855B856B857B858B859B85AB85B
B85EB85FB861B862B863B865B866B867B868B869B86AB86BB86EB870B872B873
B874B875B876B877B879B87AB87BB87DB87EB87FB880B881B882B883B8840000
8F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B885B886B887B888B889B88AB88BB88CB88EB88FB890B891B892B893B894
B895B896B897B898B899B89AB89BB89CB89DB89EB89F00000000000000000000
0000B8A0B8A1B8A2B8A3B8A4B8A5B8A6B8A7B8A9B8AAB8ABB8ACB8ADB8AEB8AF
B8B1B8B2B8B3B8B5B8B6B8B7B8B9B8BAB8BBB8BCB8BD00000000000000000000
0000B8BEB8BFB8C2B8C4B8C6B8C7B8C8B8C9B8CAB8CBB8CDB8CEB8CFB8D1B8D2
B8D3B8D5B8D6B8D7B8D8B8D9B8DAB8DBB8DCB8DEB8E0B8E2B8E3B8E4B8E5B8E6
B8E7B8EAB8EBB8EDB8EEB8EFB8F1B8F2B8F3B8F4B8F5B8F6B8F7B8FAB8FCB8FE
B8FFB900B901B902B903B905B906B907B908B909B90AB90BB90CB90DB90EB90F
B910B911B912B913B914B915B916B917B919B91AB91BB91CB91DB91EB91FB921
B922B923B924B925B926B927B928B929B92AB92BB92CB92DB92EB92FB930B931
B932B933B934B935B936B937B938B939B93AB93BB93EB93FB941B942B943B945
B946B947B948B949B94AB94BB94DB94EB950B952B953B954B955B956B9570000
90
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B95AB95BB95DB95EB95FB961B962B963B964B965B966B967B96AB96CB96E
B96FB970B971B972B973B976B977B979B97AB97BB97D00000000000000000000
0000B97EB97FB980B981B982B983B986B988B98BB98CB98FB990B991B992B993
B994B995B996B997B998B999B99AB99BB99CB99DB99E00000000000000000000
0000B99FB9A0B9A1B9A2B9A3B9A4B9A5B9A6B9A7B9A8B9A9B9AAB9ABB9AEB9AF
B9B1B9B2B9B3B9B5B9B6B9B7B9B8B9B9B9BAB9BBB9BEB9C0B9C2B9C3B9C4B9C5
B9C6B9C7B9CAB9CBB9CDB9D3B9D4B9D5B9D6B9D7B9DAB9DCB9DFB9E0B9E2B9E6
B9E7B9E9B9EAB9EBB9EDB9EEB9EFB9F0B9F1B9F2B9F3B9F6B9FBB9FCB9FDB9FE
B9FFBA02BA03BA04BA05BA06BA07BA09BA0ABA0BBA0CBA0DBA0EBA0FBA10BA11
BA12BA13BA14BA16BA17BA18BA19BA1ABA1BBA1CBA1DBA1EBA1FBA20BA21BA22
BA23BA24BA25BA26BA27BA28BA29BA2ABA2BBA2CBA2DBA2EBA2FBA30BA31BA32
BA33BA34BA35BA36BA37BA3ABA3BBA3DBA3EBA3FBA41BA43BA44BA45BA460000
91
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BA47BA4ABA4CBA4FBA50BA51BA52BA56BA57BA59BA5ABA5BBA5DBA5EBA5F
BA60BA61BA62BA63BA66BA6ABA6BBA6CBA6DBA6EBA6F00000000000000000000
0000BA72BA73BA75BA76BA77BA79BA7ABA7BBA7CBA7DBA7EBA7FBA80BA81BA82
BA86BA88BA89BA8ABA8BBA8DBA8EBA8FBA90BA91BA9200000000000000000000
0000BA93BA94BA95BA96BA97BA98BA99BA9ABA9BBA9CBA9DBA9EBA9FBAA0BAA1
BAA2BAA3BAA4BAA5BAA6BAA7BAAABAADBAAEBAAFBAB1BAB3BAB4BAB5BAB6BAB7
BABABABCBABEBABFBAC0BAC1BAC2BAC3BAC5BAC6BAC7BAC9BACABACBBACCBACD
BACEBACFBAD0BAD1BAD2BAD3BAD4BAD5BAD6BAD7BADABADBBADCBADDBADEBADF
BAE0BAE1BAE2BAE3BAE4BAE5BAE6BAE7BAE8BAE9BAEABAEBBAECBAEDBAEEBAEF
BAF0BAF1BAF2BAF3BAF4BAF5BAF6BAF7BAF8BAF9BAFABAFBBAFDBAFEBAFFBB01
BB02BB03BB05BB06BB07BB08BB09BB0ABB0BBB0CBB0EBB10BB12BB13BB14BB15
BB16BB17BB19BB1ABB1BBB1DBB1EBB1FBB21BB22BB23BB24BB25BB26BB270000
92
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BB28BB2ABB2CBB2DBB2EBB2FBB30BB31BB32BB33BB37BB39BB3ABB3FBB40
BB41BB42BB43BB46BB48BB4ABB4BBB4CBB4EBB51BB5200000000000000000000
0000BB53BB55BB56BB57BB59BB5ABB5BBB5CBB5DBB5EBB5FBB60BB62BB64BB65
BB66BB67BB68BB69BB6ABB6BBB6DBB6EBB6FBB70BB7100000000000000000000
0000BB72BB73BB74BB75BB76BB77BB78BB79BB7ABB7BBB7CBB7DBB7EBB7FBB80
BB81BB82BB83BB84BB85BB86BB87BB89BB8ABB8BBB8DBB8EBB8FBB91BB92BB93
BB94BB95BB96BB97BB98BB99BB9ABB9BBB9CBB9DBB9EBB9FBBA0BBA1BBA2BBA3
BBA5BBA6BBA7BBA9BBAABBABBBADBBAEBBAFBBB0BBB1BBB2BBB3BBB5BBB6BBB8
BBB9BBBABBBBBBBCBBBDBBBEBBBFBBC1BBC2BBC3BBC5BBC6BBC7BBC9BBCABBCB
BBCCBBCDBBCEBBCFBBD1BBD2BBD4BBD5BBD6BBD7BBD8BBD9BBDABBDBBBDCBBDD
BBDEBBDFBBE0BBE1BBE2BBE3BBE4BBE5BBE6BBE7BBE8BBE9BBEABBEBBBECBBED
BBEEBBEFBBF0BBF1BBF2BBF3BBF4BBF5BBF6BBF7BBFABBFBBBFDBBFEBC010000
93
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BC03BC04BC05BC06BC07BC0ABC0EBC10BC12BC13BC19BC1ABC20BC21BC22
BC23BC26BC28BC2ABC2BBC2CBC2EBC2FBC32BC33BC3500000000000000000000
0000BC36BC37BC39BC3ABC3BBC3CBC3DBC3EBC3FBC42BC46BC47BC48BC4ABC4B
BC4EBC4FBC51BC52BC53BC54BC55BC56BC57BC58BC5900000000000000000000
0000BC5ABC5BBC5CBC5EBC5FBC60BC61BC62BC63BC64BC65BC66BC67BC68BC69
BC6ABC6BBC6CBC6DBC6EBC6FBC70BC71BC72BC73BC74BC75BC76BC77BC78BC79
BC7ABC7BBC7CBC7DBC7EBC7FBC80BC81BC82BC83BC86BC87BC89BC8ABC8DBC8F
BC90BC91BC92BC93BC96BC98BC9BBC9CBC9DBC9EBC9FBCA2BCA3BCA5BCA6BCA9
BCAABCABBCACBCADBCAEBCAFBCB2BCB6BCB7BCB8BCB9BCBABCBBBCBEBCBFBCC1
BCC2BCC3BCC5BCC6BCC7BCC8BCC9BCCABCCBBCCCBCCEBCD2BCD3BCD4BCD6BCD7
BCD9BCDABCDBBCDDBCDEBCDFBCE0BCE1BCE2BCE3BCE4BCE5BCE6BCE7BCE8BCE9
BCEABCEBBCECBCEDBCEEBCEFBCF0BCF1BCF2BCF3BCF7BCF9BCFABCFBBCFD0000
94
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BCFEBCFFBD00BD01BD02BD03BD06BD08BD0ABD0BBD0CBD0DBD0EBD0FBD11
BD12BD13BD15BD16BD17BD18BD19BD1ABD1BBD1CBD1D00000000000000000000
0000BD1EBD1FBD20BD21BD22BD23BD25BD26BD27BD28BD29BD2ABD2BBD2DBD2E
BD2FBD30BD31BD32BD33BD34BD35BD36BD37BD38BD3900000000000000000000
0000BD3ABD3BBD3CBD3DBD3EBD3FBD41BD42BD43BD44BD45BD46BD47BD4ABD4B
BD4DBD4EBD4FBD51BD52BD53BD54BD55BD56BD57BD5ABD5BBD5CBD5DBD5EBD5F
BD60BD61BD62BD63BD65BD66BD67BD69BD6ABD6BBD6CBD6DBD6EBD6FBD70BD71
BD72BD73BD74BD75BD76BD77BD78BD79BD7ABD7BBD7CBD7DBD7EBD7FBD82BD83
BD85BD86BD8BBD8CBD8DBD8EBD8FBD92BD94BD96BD97BD98BD9BBD9DBD9EBD9F
BDA0BDA1BDA2BDA3BDA5BDA6BDA7BDA8BDA9BDAABDABBDACBDADBDAEBDAFBDB1
BDB2BDB3BDB4BDB5BDB6BDB7BDB9BDBABDBBBDBCBDBDBDBEBDBFBDC0BDC1BDC2
BDC3BDC4BDC5BDC6BDC7BDC8BDC9BDCABDCBBDCCBDCDBDCEBDCFBDD0BDD10000
95
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BDD2BDD3BDD6BDD7BDD9BDDABDDBBDDDBDDEBDDFBDE0BDE1BDE2BDE3BDE4
BDE5BDE6BDE7BDE8BDEABDEBBDECBDEDBDEEBDEFBDF100000000000000000000
0000BDF2BDF3BDF5BDF6BDF7BDF9BDFABDFBBDFCBDFDBDFEBDFFBE01BE02BE04
BE06BE07BE08BE09BE0ABE0BBE0EBE0FBE11BE12BE1300000000000000000000
0000BE15BE16BE17BE18BE19BE1ABE1BBE1EBE20BE21BE22BE23BE24BE25BE26
BE27BE28BE29BE2ABE2BBE2CBE2DBE2EBE2FBE30BE31BE32BE33BE34BE35BE36
BE37BE38BE39BE3ABE3BBE3CBE3DBE3EBE3FBE40BE41BE42BE43BE46BE47BE49
BE4ABE4BBE4DBE4FBE50BE51BE52BE53BE56BE58BE5CBE5DBE5EBE5FBE62BE63
BE65BE66BE67BE69BE6BBE6CBE6DBE6EBE6FBE72BE76BE77BE78BE79BE7ABE7E
BE7FBE81BE82BE83BE85BE86BE87BE88BE89BE8ABE8BBE8EBE92BE93BE94BE95
BE96BE97BE9ABE9BBE9CBE9DBE9EBE9FBEA0BEA1BEA2BEA3BEA4BEA5BEA6BEA7
BEA9BEAABEABBEACBEADBEAEBEAFBEB0BEB1BEB2BEB3BEB4BEB5BEB6BEB70000
96
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BEB8BEB9BEBABEBBBEBCBEBDBEBEBEBFBEC0BEC1BEC2BEC3BEC4BEC5BEC6
BEC7BEC8BEC9BECABECBBECCBECDBECEBECFBED2BED300000000000000000000
0000BED5BED6BED9BEDABEDBBEDCBEDDBEDEBEDFBEE1BEE2BEE6BEE7BEE8BEE9
BEEABEEBBEEDBEEEBEEFBEF0BEF1BEF2BEF3BEF4BEF500000000000000000000
0000BEF6BEF7BEF8BEF9BEFABEFBBEFCBEFDBEFEBEFFBF00BF02BF03BF04BF05
BF06BF07BF0ABF0BBF0CBF0DBF0EBF0FBF10BF11BF12BF13BF14BF15BF16BF17
BF1ABF1EBF1FBF20BF21BF22BF23BF24BF25BF26BF27BF28BF29BF2ABF2BBF2C
BF2DBF2EBF2FBF30BF31BF32BF33BF34BF35BF36BF37BF38BF39BF3ABF3BBF3C
BF3DBF3EBF3FBF42BF43BF45BF46BF47BF49BF4ABF4BBF4CBF4DBF4EBF4FBF52
BF53BF54BF56BF57BF58BF59BF5ABF5BBF5CBF5DBF5EBF5FBF60BF61BF62BF63
BF64BF65BF66BF67BF68BF69BF6ABF6BBF6CBF6DBF6EBF6FBF70BF71BF72BF73
BF74BF75BF76BF77BF78BF79BF7ABF7BBF7CBF7DBF7EBF7FBF80BF81BF820000
97
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BF83BF84BF85BF86BF87BF88BF89BF8ABF8BBF8CBF8DBF8EBF8FBF90BF91
BF92BF93BF95BF96BF97BF98BF99BF9ABF9BBF9CBF9D00000000000000000000
0000BF9EBF9FBFA0BFA1BFA2BFA3BFA4BFA5BFA6BFA7BFA8BFA9BFAABFABBFAC
BFADBFAEBFAFBFB1BFB2BFB3BFB4BFB5BFB6BFB7BFB800000000000000000000
0000BFB9BFBABFBBBFBCBFBDBFBEBFBFBFC0BFC1BFC2BFC3BFC4BFC6BFC7BFC8
BFC9BFCABFCBBFCEBFCFBFD1BFD2BFD3BFD5BFD6BFD7BFD8BFD9BFDABFDBBFDD
BFDEBFE0BFE2BFE3BFE4BFE5BFE6BFE7BFE8BFE9BFEABFEBBFECBFEDBFEEBFEF
BFF0BFF1BFF2BFF3BFF4BFF5BFF6BFF7BFF8BFF9BFFABFFBBFFCBFFDBFFEBFFF
C000C001C002C003C004C005C006C007C008C009C00AC00BC00CC00DC00EC00F
C010C011C012C013C014C015C016C017C018C019C01AC01BC01CC01DC01EC01F
C020C021C022C023C024C025C026C027C028C029C02AC02BC02CC02DC02EC02F
C030C031C032C033C034C035C036C037C038C039C03AC03BC03DC03EC03F0000
98
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C040C041C042C043C044C045C046C047C048C049C04AC04BC04CC04DC04E
C04FC050C052C053C054C055C056C057C059C05AC05B00000000000000000000
0000C05DC05EC05FC061C062C063C064C065C066C067C06AC06BC06CC06DC06E
C06FC070C071C072C073C074C075C076C077C078C07900000000000000000000
0000C07AC07BC07CC07DC07EC07FC080C081C082C083C084C085C086C087C088
C089C08AC08BC08CC08DC08EC08FC092C093C095C096C097C099C09AC09BC09C
C09DC09EC09FC0A2C0A4C0A6C0A7C0A8C0A9C0AAC0ABC0AEC0B1C0B2C0B7C0B8
C0B9C0BAC0BBC0BEC0C2C0C3C0C4C0C6C0C7C0CAC0CBC0CDC0CEC0CFC0D1C0D2
C0D3C0D4C0D5C0D6C0D7C0DAC0DEC0DFC0E0C0E1C0E2C0E3C0E6C0E7C0E9C0EA
C0EBC0EDC0EEC0EFC0F0C0F1C0F2C0F3C0F6C0F8C0FAC0FBC0FCC0FDC0FEC0FF
C101C102C103C105C106C107C109C10AC10BC10CC10DC10EC10FC111C112C113
C114C116C117C118C119C11AC11BC121C122C125C128C129C12AC12BC12E0000
99
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C132C133C134C135C137C13AC13BC13DC13EC13FC141C142C143C144C145
C146C147C14AC14EC14FC150C151C152C153C156C15700000000000000000000
0000C159C15AC15BC15DC15EC15FC160C161C162C163C166C16AC16BC16CC16D
C16EC16FC171C172C173C175C176C177C179C17AC17B00000000000000000000
0000C17CC17DC17EC17FC180C181C182C183C184C186C187C188C189C18AC18B
C18FC191C192C193C195C197C198C199C19AC19BC19EC1A0C1A2C1A3C1A4C1A6
C1A7C1AAC1ABC1ADC1AEC1AFC1B1C1B2C1B3C1B4C1B5C1B6C1B7C1B8C1B9C1BA
C1BBC1BCC1BEC1BFC1C0C1C1C1C2C1C3C1C5C1C6C1C7C1C9C1CAC1CBC1CDC1CE
C1CFC1D0C1D1C1D2C1D3C1D5C1D6C1D9C1DAC1DBC1DCC1DDC1DEC1DFC1E1C1E2
C1E3C1E5C1E6C1E7C1E9C1EAC1EBC1ECC1EDC1EEC1EFC1F2C1F4C1F5C1F6C1F7
C1F8C1F9C1FAC1FBC1FEC1FFC201C202C203C205C206C207C208C209C20AC20B
C20EC210C212C213C214C215C216C217C21AC21BC21DC21EC221C222C2230000
9A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C224C225C226C227C22AC22CC22EC230C233C235C236C237C238C239C23A
C23BC23CC23DC23EC23FC240C241C242C243C244C24500000000000000000000
0000C246C247C249C24AC24BC24CC24DC24EC24FC252C253C255C256C257C259
C25AC25BC25CC25DC25EC25FC261C262C263C264C26600000000000000000000
0000C267C268C269C26AC26BC26EC26FC271C272C273C275C276C277C278C279
C27AC27BC27EC280C282C283C284C285C286C287C28AC28BC28CC28DC28EC28F
C291C292C293C294C295C296C297C299C29AC29CC29EC29FC2A0C2A1C2A2C2A3
C2A6C2A7C2A9C2AAC2ABC2AEC2AFC2B0C2B1C2B2C2B3C2B6C2B8C2BAC2BBC2BC
C2BDC2BEC2BFC2C0C2C1C2C2C2C3C2C4C2C5C2C6C2C7C2C8C2C9C2CAC2CBC2CC
C2CDC2CEC2CFC2D0C2D1C2D2C2D3C2D4C2D5C2D6C2D7C2D8C2D9C2DAC2DBC2DE
C2DFC2E1C2E2C2E5C2E6C2E7C2E8C2E9C2EAC2EEC2F0C2F2C2F3C2F4C2F5C2F7
C2FAC2FDC2FEC2FFC301C302C303C304C305C306C307C30AC30BC30EC30F0000
9B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C310C311C312C316C317C319C31AC31BC31DC31EC31FC320C321C322C323
C326C327C32AC32BC32CC32DC32EC32FC330C331C33200000000000000000000
0000C333C334C335C336C337C338C339C33AC33BC33CC33DC33EC33FC340C341
C342C343C344C346C347C348C349C34AC34BC34CC34D00000000000000000000
0000C34EC34FC350C351C352C353C354C355C356C357C358C359C35AC35BC35C
C35DC35EC35FC360C361C362C363C364C365C366C367C36AC36BC36DC36EC36F
C371C373C374C375C376C377C37AC37BC37EC37FC380C381C382C383C385C386
C387C389C38AC38BC38DC38EC38FC390C391C392C393C394C395C396C397C398
C399C39AC39BC39CC39DC39EC39FC3A0C3A1C3A2C3A3C3A4C3A5C3A6C3A7C3A8
C3A9C3AAC3ABC3ACC3ADC3AEC3AFC3B0C3B1C3B2C3B3C3B4C3B5C3B6C3B7C3B8
C3B9C3BAC3BBC3BCC3BDC3BEC3BFC3C1C3C2C3C3C3C4C3C5C3C6C3C7C3C8C3C9
C3CAC3CBC3CCC3CDC3CEC3CFC3D0C3D1C3D2C3D3C3D4C3D5C3D6C3D7C3DA0000
9C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C3DBC3DDC3DEC3E1C3E3C3E4C3E5C3E6C3E7C3EAC3EBC3ECC3EEC3EFC3F0
C3F1C3F2C3F3C3F6C3F7C3F9C3FAC3FBC3FCC3FDC3FE00000000000000000000
0000C3FFC400C401C402C403C404C405C406C407C409C40AC40BC40CC40DC40E
C40FC411C412C413C414C415C416C417C418C419C41A00000000000000000000
0000C41BC41CC41DC41EC41FC420C421C422C423C425C426C427C428C429C42A
C42BC42DC42EC42FC431C432C433C435C436C437C438C439C43AC43BC43EC43F
C440C441C442C443C444C445C446C447C449C44AC44BC44CC44DC44EC44FC450
C451C452C453C454C455C456C457C458C459C45AC45BC45CC45DC45EC45FC460
C461C462C463C466C467C469C46AC46BC46DC46EC46FC470C471C472C473C476
C477C478C47AC47BC47CC47DC47EC47FC481C482C483C484C485C486C487C488
C489C48AC48BC48CC48DC48EC48FC490C491C492C493C495C496C497C498C499
C49AC49BC49DC49EC49FC4A0C4A1C4A2C4A3C4A4C4A5C4A6C4A7C4A8C4A90000
9D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C4AAC4ABC4ACC4ADC4AEC4AFC4B0C4B1C4B2C4B3C4B4C4B5C4B6C4B7C4B9
C4BAC4BBC4BDC4BEC4BFC4C0C4C1C4C2C4C3C4C4C4C500000000000000000000
0000C4C6C4C7C4C8C4C9C4CAC4CBC4CCC4CDC4CEC4CFC4D0C4D1C4D2C4D3C4D4
C4D5C4D6C4D7C4D8C4D9C4DAC4DBC4DCC4DDC4DEC4DF00000000000000000000
0000C4E0C4E1C4E2C4E3C4E4C4E5C4E6C4E7C4E8C4EAC4EBC4ECC4EDC4EEC4EF
C4F2C4F3C4F5C4F6C4F7C4F9C4FBC4FCC4FDC4FEC502C503C504C505C506C507
C508C509C50AC50BC50DC50EC50FC511C512C513C515C516C517C518C519C51A
C51BC51DC51EC51FC520C521C522C523C524C525C526C527C52AC52BC52DC52E
C52FC531C532C533C534C535C536C537C53AC53CC53EC53FC540C541C542C543
C546C547C54BC54FC550C551C552C556C55AC55BC55CC55FC562C563C565C566
C567C569C56AC56BC56CC56DC56EC56FC572C576C577C578C579C57AC57BC57E
C57FC581C582C583C585C586C588C589C58AC58BC58EC590C592C593C5940000
9E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C596C599C59AC59BC59DC59EC59FC5A1C5A2C5A3C5A4C5A5C5A6C5A7C5A8
C5AAC5ABC5ACC5ADC5AEC5AFC5B0C5B1C5B2C5B3C5B600000000000000000000
0000C5B7C5BAC5BFC5C0C5C1C5C2C5C3C5CBC5CDC5CFC5D2C5D3C5D5C5D6C5D7
C5D9C5DAC5DBC5DCC5DDC5DEC5DFC5E2C5E4C5E6C5E700000000000000000000
0000C5E8C5E9C5EAC5EBC5EFC5F1C5F2C5F3C5F5C5F8C5F9C5FAC5FBC602C603
C604C609C60AC60BC60DC60EC60FC611C612C613C614C615C616C617C61AC61D
C61EC61FC620C621C622C623C626C627C629C62AC62BC62FC631C632C636C638
C63AC63CC63DC63EC63FC642C643C645C646C647C649C64AC64BC64CC64DC64E
C64FC652C656C657C658C659C65AC65BC65EC65FC661C662C663C664C665C666
C667C668C669C66AC66BC66DC66EC670C672C673C674C675C676C677C67AC67B
C67DC67EC67FC681C682C683C684C685C686C687C68AC68CC68EC68FC690C691
C692C693C696C697C699C69AC69BC69DC69EC69FC6A0C6A1C6A2C6A3C6A60000
9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C6A8C6AAC6ABC6ACC6ADC6AEC6AFC6B2C6B3C6B5C6B6C6B7C6BBC6BCC6BD
C6BEC6BFC6C2C6C4C6C6C6C7C6C8C6C9C6CAC6CBC6CE00000000000000000000
0000C6CFC6D1C6D2C6D3C6D5C6D6C6D7C6D8C6D9C6DAC6DBC6DEC6DFC6E2C6E3
C6E4C6E5C6E6C6E7C6EAC6EBC6EDC6EEC6EFC6F1C6F200000000000000000000
0000C6F3C6F4C6F5C6F6C6F7C6FAC6FBC6FCC6FEC6FFC700C701C702C703C706
C707C709C70AC70BC70DC70EC70FC710C711C712C713C716C718C71AC71BC71C
C71DC71EC71FC722C723C725C726C727C729C72AC72BC72CC72DC72EC72FC732
C734C736C738C739C73AC73BC73EC73FC741C742C743C745C746C747C748C749
C74BC74EC750C759C75AC75BC75DC75EC75FC761C762C763C764C765C766C767
C769C76AC76CC76DC76EC76FC770C771C772C773C776C777C779C77AC77BC77F
C780C781C782C786C78BC78CC78DC78FC792C793C795C799C79BC79CC79DC79E
C79FC7A2C7A7C7A8C7A9C7AAC7ABC7AEC7AFC7B1C7B2C7B3C7B5C7B6C7B70000
A0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C7B8C7B9C7BAC7BBC7BEC7C2C7C3C7C4C7C5C7C6C7C7C7CAC7CBC7CDC7CF
C7D1C7D2C7D3C7D4C7D5C7D6C7D7C7D9C7DAC7DBC7DC00000000000000000000
0000C7DEC7DFC7E0C7E1C7E2C7E3C7E5C7E6C7E7C7E9C7EAC7EBC7EDC7EEC7EF
C7F0C7F1C7F2C7F3C7F4C7F5C7F6C7F7C7F8C7F9C7FA00000000000000000000
0000C7FBC7FCC7FDC7FEC7FFC802C803C805C806C807C809C80BC80CC80DC80E
C80FC812C814C817C818C819C81AC81BC81EC81FC821C822C823C825C826C827
C828C829C82AC82BC82EC830C832C833C834C835C836C837C839C83AC83BC83D
C83EC83FC841C842C843C844C845C846C847C84AC84BC84EC84FC850C851C852
C853C855C856C857C858C859C85AC85BC85CC85DC85EC85FC860C861C862C863
C864C865C866C867C868C869C86AC86BC86CC86DC86EC86FC872C873C875C876
C877C879C87BC87CC87DC87EC87FC882C884C888C889C88AC88EC88FC890C891
C892C893C895C896C897C898C899C89AC89BC89CC89EC8A0C8A2C8A3C8A40000
A1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C8A5C8A6C8A7C8A9C8AAC8ABC8ACC8ADC8AEC8AFC8B0C8B1C8B2C8B3C8B4
C8B5C8B6C8B7C8B8C8B9C8BAC8BBC8BEC8BFC8C0C8C100000000000000000000
0000C8C2C8C3C8C5C8C6C8C7C8C9C8CAC8CBC8CDC8CEC8CFC8D0C8D1C8D2C8D3
C8D6C8D8C8DAC8DBC8DCC8DDC8DEC8DFC8E2C8E3C8E500000000000000000000
0000C8E6C8E7C8E8C8E9C8EAC8EBC8ECC8EDC8EEC8EFC8F0C8F1C8F2C8F3C8F4
C8F6C8F7C8F8C8F9C8FAC8FBC8FEC8FFC901C902C903C907C908C909C90AC90B
C90E30003001300200B72025202600A8300300AD20152225FF3C223C20182019
201C201D3014301530083009300A300B300C300D300E300F3010301100B100D7
00F7226022642265221E223400B0203220332103212BFFE0FFE1FFE526422640
222022A52312220222072261225200A7203B2606260525CB25CF25CE25C725C6
25A125A025B325B225BD25BC219221902191219321943013226A226B221A223D
221D2235222B222C2208220B2286228722822283222A222922272228FFE20000
A2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C910C912C913C914C915C916C917C919C91AC91BC91CC91DC91EC91FC920
C921C922C923C924C925C926C927C928C929C92AC92B00000000000000000000
0000C92DC92EC92FC930C931C932C933C935C936C937C938C939C93AC93BC93C
C93DC93EC93FC940C941C942C943C944C945C946C94700000000000000000000
0000C948C949C94AC94BC94CC94DC94EC94FC952C953C955C956C957C959C95A
C95BC95CC95DC95EC95FC962C964C965C966C967C968C969C96AC96BC96DC96E
C96F21D221D42200220300B4FF5E02C702D802DD02DA02D900B802DB00A100BF
02D0222E2211220F00A42109203025C125C025B725B626642660266126652667
2663229925C825A325D025D1259225A425A525A825A725A625A92668260F260E
261C261E00B62020202121952197219921962198266D2669266A266C327F321C
211633C7212233C233D821210000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C971C972C973C975C976C977C978C979C97AC97BC97DC97EC97FC980C981
C982C983C984C985C986C987C98AC98BC98DC98EC98F00000000000000000000
0000C991C992C993C994C995C996C997C99AC99CC99EC99FC9A0C9A1C9A2C9A3
C9A4C9A5C9A6C9A7C9A8C9A9C9AAC9ABC9ACC9ADC9AE00000000000000000000
0000C9AFC9B0C9B1C9B2C9B3C9B4C9B5C9B6C9B7C9B8C9B9C9BAC9BBC9BCC9BD
C9BEC9BFC9C2C9C3C9C5C9C6C9C9C9CBC9CCC9CDC9CEC9CFC9D2C9D4C9D7C9D8
C9DBFF01FF02FF03FF04FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFFE6FF3DFF3EFF3F
FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
A4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C9DEC9DFC9E1C9E3C9E5C9E6C9E8C9E9C9EAC9EBC9EEC9F2C9F3C9F4C9F5
C9F6C9F7C9FAC9FBC9FDC9FEC9FFCA01CA02CA03CA0400000000000000000000
0000CA05CA06CA07CA0ACA0ECA0FCA10CA11CA12CA13CA15CA16CA17CA19CA1A
CA1BCA1CCA1DCA1ECA1FCA20CA21CA22CA23CA24CA2500000000000000000000
0000CA26CA27CA28CA2ACA2BCA2CCA2DCA2ECA2FCA30CA31CA32CA33CA34CA35
CA36CA37CA38CA39CA3ACA3BCA3CCA3DCA3ECA3FCA40CA41CA42CA43CA44CA45
CA46313131323133313431353136313731383139313A313B313C313D313E313F
3140314131423143314431453146314731483149314A314B314C314D314E314F
3150315131523153315431553156315731583159315A315B315C315D315E315F
3160316131623163316431653166316731683169316A316B316C316D316E316F
3170317131723173317431753176317731783179317A317B317C317D317E317F
3180318131823183318431853186318731883189318A318B318C318D318E0000
A5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CA47CA48CA49CA4ACA4BCA4ECA4FCA51CA52CA53CA55CA56CA57CA58CA59
CA5ACA5BCA5ECA62CA63CA64CA65CA66CA67CA69CA6A00000000000000000000
0000CA6BCA6CCA6DCA6ECA6FCA70CA71CA72CA73CA74CA75CA76CA77CA78CA79
CA7ACA7BCA7CCA7ECA7FCA80CA81CA82CA83CA85CA8600000000000000000000
0000CA87CA88CA89CA8ACA8BCA8CCA8DCA8ECA8FCA90CA91CA92CA93CA94CA95
CA96CA97CA99CA9ACA9BCA9CCA9DCA9ECA9FCAA0CAA1CAA2CAA3CAA4CAA5CAA6
CAA7217021712172217321742175217621772178217900000000000000000000
2160216121622163216421652166216721682169000000000000000000000000
0000039103920393039403950396039703980399039A039B039C039D039E039F
03A003A103A303A403A503A603A703A803A90000000000000000000000000000
000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C303C403C503C603C703C803C90000000000000000000000000000
A6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CAA8CAA9CAAACAABCAACCAADCAAECAAFCAB0CAB1CAB2CAB3CAB4CAB5CAB6
CAB7CAB8CAB9CABACABBCABECABFCAC1CAC2CAC3CAC500000000000000000000
0000CAC6CAC7CAC8CAC9CACACACBCACECAD0CAD2CAD4CAD5CAD6CAD7CADACADB
CADCCADDCADECADFCAE1CAE2CAE3CAE4CAE5CAE6CAE700000000000000000000
0000CAE8CAE9CAEACAEBCAEDCAEECAEFCAF0CAF1CAF2CAF3CAF5CAF6CAF7CAF8
CAF9CAFACAFBCAFCCAFDCAFECAFFCB00CB01CB02CB03CB04CB05CB06CB07CB09
CB0A25002502250C251025182514251C252C25242534253C25012503250F2513
251B251725232533252B253B254B2520252F25282537253F251D253025252538
254225122511251A251925162515250E250D251E251F25212522252625272529
252A252D252E25312532253525362539253A253D253E25402541254325442545
2546254725482549254A00000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CB0BCB0CCB0DCB0ECB0FCB11CB12CB13CB15CB16CB17CB19CB1ACB1BCB1C
CB1DCB1ECB1FCB22CB23CB24CB25CB26CB27CB28CB2900000000000000000000
0000CB2ACB2BCB2CCB2DCB2ECB2FCB30CB31CB32CB33CB34CB35CB36CB37CB38
CB39CB3ACB3BCB3CCB3DCB3ECB3FCB40CB42CB43CB4400000000000000000000
0000CB45CB46CB47CB4ACB4BCB4DCB4ECB4FCB51CB52CB53CB54CB55CB56CB57
CB5ACB5BCB5CCB5ECB5FCB60CB61CB62CB63CB65CB66CB67CB68CB69CB6ACB6B
CB6C3395339633972113339833C433A333A433A533A63399339A339B339C339D
339E339F33A033A133A233CA338D338E338F33CF3388338933C833A733A833B0
33B133B233B333B433B533B633B733B833B93380338133823383338433BA33BB
33BC33BD33BE33BF33903391339233933394212633C033C1338A338B338C33D6
33C533AD33AE33AF33DB33A933AA33AB33AC33DD33D033D333C333C933DC33C6
0000000000000000000000000000000000000000000000000000000000000000
A8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CB6DCB6ECB6FCB70CB71CB72CB73CB74CB75CB76CB77CB7ACB7BCB7CCB7D
CB7ECB7FCB80CB81CB82CB83CB84CB85CB86CB87CB8800000000000000000000
0000CB89CB8ACB8BCB8CCB8DCB8ECB8FCB90CB91CB92CB93CB94CB95CB96CB97
CB98CB99CB9ACB9BCB9DCB9ECB9FCBA0CBA1CBA2CBA300000000000000000000
0000CBA4CBA5CBA6CBA7CBA8CBA9CBAACBABCBACCBADCBAECBAFCBB0CBB1CBB2
CBB3CBB4CBB5CBB6CBB7CBB9CBBACBBBCBBCCBBDCBBECBBFCBC0CBC1CBC2CBC3
CBC400C600D000AA0126000001320000013F014100D8015200BA00DE0166014A
00003260326132623263326432653266326732683269326A326B326C326D326E
326F3270327132723273327432753276327732783279327A327B24D024D124D2
24D324D424D524D624D724D824D924DA24DB24DC24DD24DE24DF24E024E124E2
24E324E424E524E624E724E824E9246024612462246324642465246624672468
2469246A246B246C246D246E00BD2153215400BC00BE215B215C215D215E0000
A9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CBC5CBC6CBC7CBC8CBC9CBCACBCBCBCCCBCDCBCECBCFCBD0CBD1CBD2CBD3
CBD5CBD6CBD7CBD8CBD9CBDACBDBCBDCCBDDCBDECBDF00000000000000000000
0000CBE0CBE1CBE2CBE3CBE5CBE6CBE8CBEACBEBCBECCBEDCBEECBEFCBF0CBF1
CBF2CBF3CBF4CBF5CBF6CBF7CBF8CBF9CBFACBFBCBFC00000000000000000000
0000CBFDCBFECBFFCC00CC01CC02CC03CC04CC05CC06CC07CC08CC09CC0ACC0B
CC0ECC0FCC11CC12CC13CC15CC16CC17CC18CC19CC1ACC1BCC1ECC1FCC20CC23
CC2400E6011100F001270131013301380140014200F8015300DF00FE0167014B
01493200320132023203320432053206320732083209320A320B320C320D320E
320F3210321132123213321432153216321732183219321A321B249C249D249E
249F24A024A124A224A324A424A524A624A724A824A924AA24AB24AC24AD24AE
24AF24B024B124B224B324B424B5247424752476247724782479247A247B247C
247D247E247F24802481248200B900B200B32074207F20812082208320840000
AA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CC25CC26CC2ACC2BCC2DCC2FCC31CC32CC33CC34CC35CC36CC37CC3ACC3F
CC40CC41CC42CC43CC46CC47CC49CC4ACC4BCC4DCC4E00000000000000000000
0000CC4FCC50CC51CC52CC53CC56CC5ACC5BCC5CCC5DCC5ECC5FCC61CC62CC63
CC65CC67CC69CC6ACC6BCC6CCC6DCC6ECC6FCC71CC7200000000000000000000
0000CC73CC74CC76CC77CC78CC79CC7ACC7BCC7CCC7DCC7ECC7FCC80CC81CC82
CC83CC84CC85CC86CC87CC88CC89CC8ACC8BCC8CCC8DCC8ECC8FCC90CC91CC92
CC93304130423043304430453046304730483049304A304B304C304D304E304F
3050305130523053305430553056305730583059305A305B305C305D305E305F
3060306130623063306430653066306730683069306A306B306C306D306E306F
3070307130723073307430753076307730783079307A307B307C307D307E307F
3080308130823083308430853086308730883089308A308B308C308D308E308F
3090309130923093000000000000000000000000000000000000000000000000
AB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CC94CC95CC96CC97CC9ACC9BCC9DCC9ECC9FCCA1CCA2CCA3CCA4CCA5CCA6
CCA7CCAACCAECCAFCCB0CCB1CCB2CCB3CCB6CCB7CCB900000000000000000000
0000CCBACCBBCCBDCCBECCBFCCC0CCC1CCC2CCC3CCC6CCC8CCCACCCBCCCCCCCD
CCCECCCFCCD1CCD2CCD3CCD5CCD6CCD7CCD8CCD9CCDA00000000000000000000
0000CCDBCCDCCCDDCCDECCDFCCE0CCE1CCE2CCE3CCE5CCE6CCE7CCE8CCE9CCEA
CCEBCCEDCCEECCEFCCF1CCF2CCF3CCF4CCF5CCF6CCF7CCF8CCF9CCFACCFBCCFC
CCFD30A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000000
AC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CCFECCFFCD00CD02CD03CD04CD05CD06CD07CD0ACD0BCD0DCD0ECD0FCD11
CD12CD13CD14CD15CD16CD17CD1ACD1CCD1ECD1FCD2000000000000000000000
0000CD21CD22CD23CD25CD26CD27CD29CD2ACD2BCD2DCD2ECD2FCD30CD31CD32
CD33CD34CD35CD36CD37CD38CD3ACD3BCD3CCD3DCD3E00000000000000000000
0000CD3FCD40CD41CD42CD43CD44CD45CD46CD47CD48CD49CD4ACD4BCD4CCD4D
CD4ECD4FCD50CD51CD52CD53CD54CD55CD56CD57CD58CD59CD5ACD5BCD5DCD5E
CD5F04100411041204130414041504010416041704180419041A041B041C041D
041E041F0420042104220423042404250426042704280429042A042B042C042D
042E042F00000000000000000000000000000000000000000000000000000000
000004300431043204330434043504510436043704380439043A043B043C043D
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000000000
AD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CD61CD62CD63CD65CD66CD67CD68CD69CD6ACD6BCD6ECD70CD72CD73CD74
CD75CD76CD77CD79CD7ACD7BCD7CCD7DCD7ECD7FCD8000000000000000000000
0000CD81CD82CD83CD84CD85CD86CD87CD89CD8ACD8BCD8CCD8DCD8ECD8FCD90
CD91CD92CD93CD96CD97CD99CD9ACD9BCD9DCD9ECD9F00000000000000000000
0000CDA0CDA1CDA2CDA3CDA6CDA8CDAACDABCDACCDADCDAECDAFCDB1CDB2CDB3
CDB4CDB5CDB6CDB7CDB8CDB9CDBACDBBCDBCCDBDCDBECDBFCDC0CDC1CDC2CDC3
CDC5000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
AE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CDC6CDC7CDC8CDC9CDCACDCBCDCDCDCECDCFCDD1CDD2CDD3CDD4CDD5CDD6
CDD7CDD8CDD9CDDACDDBCDDCCDDDCDDECDDFCDE0CDE100000000000000000000
0000CDE2CDE3CDE4CDE5CDE6CDE7CDE9CDEACDEBCDEDCDEECDEFCDF1CDF2CDF3
CDF4CDF5CDF6CDF7CDFACDFCCDFECDFFCE00CE01CE0200000000000000000000
0000CE03CE05CE06CE07CE09CE0ACE0BCE0DCE0ECE0FCE10CE11CE12CE13CE15
CE16CE17CE18CE1ACE1BCE1CCE1DCE1ECE1FCE22CE23CE25CE26CE27CE29CE2A
CE2B000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
AF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CE2CCE2DCE2ECE2FCE32CE34CE36CE37CE38CE39CE3ACE3BCE3CCE3DCE3E
CE3FCE40CE41CE42CE43CE44CE45CE46CE47CE48CE4900000000000000000000
0000CE4ACE4BCE4CCE4DCE4ECE4FCE50CE51CE52CE53CE54CE55CE56CE57CE5A
CE5BCE5DCE5ECE62CE63CE64CE65CE66CE67CE6ACE6C00000000000000000000
0000CE6ECE6FCE70CE71CE72CE73CE76CE77CE79CE7ACE7BCE7DCE7ECE7FCE80
CE81CE82CE83CE86CE88CE8ACE8BCE8CCE8DCE8ECE8FCE92CE93CE95CE96CE97
CE99000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
B0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CE9ACE9BCE9CCE9DCE9ECE9FCEA2CEA6CEA7CEA8CEA9CEAACEABCEAECEAF
CEB0CEB1CEB2CEB3CEB4CEB5CEB6CEB7CEB8CEB9CEBA00000000000000000000
0000CEBBCEBCCEBDCEBECEBFCEC0CEC2CEC3CEC4CEC5CEC6CEC7CEC8CEC9CECA
CECBCECCCECDCECECECFCED0CED1CED2CED3CED4CED500000000000000000000
0000CED6CED7CED8CED9CEDACEDBCEDCCEDDCEDECEDFCEE0CEE1CEE2CEE3CEE6
CEE7CEE9CEEACEEDCEEECEEFCEF0CEF1CEF2CEF3CEF6CEFACEFBCEFCCEFDCEFE
CEFFAC00AC01AC04AC07AC08AC09AC0AAC10AC11AC12AC13AC14AC15AC16AC17
AC19AC1AAC1BAC1CAC1DAC20AC24AC2CAC2DAC2FAC30AC31AC38AC39AC3CAC40
AC4BAC4DAC54AC58AC5CAC70AC71AC74AC77AC78AC7AAC80AC81AC83AC84AC85
AC86AC89AC8AAC8BAC8CAC90AC94AC9CAC9DAC9FACA0ACA1ACA8ACA9ACAAACAC
ACAFACB0ACB8ACB9ACBBACBCACBDACC1ACC4ACC8ACCCACD5ACD7ACE0ACE1ACE4
ACE7ACE8ACEAACECACEFACF0ACF1ACF3ACF5ACF6ACFCACFDAD00AD04AD060000
B1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CF02CF03CF05CF06CF07CF09CF0ACF0BCF0CCF0DCF0ECF0FCF12CF14CF16
CF17CF18CF19CF1ACF1BCF1DCF1ECF1FCF21CF22CF2300000000000000000000
0000CF25CF26CF27CF28CF29CF2ACF2BCF2ECF32CF33CF34CF35CF36CF37CF39
CF3ACF3BCF3CCF3DCF3ECF3FCF40CF41CF42CF43CF4400000000000000000000
0000CF45CF46CF47CF48CF49CF4ACF4BCF4CCF4DCF4ECF4FCF50CF51CF52CF53
CF56CF57CF59CF5ACF5BCF5DCF5ECF5FCF60CF61CF62CF63CF66CF68CF6ACF6B
CF6CAD0CAD0DAD0FAD11AD18AD1CAD20AD29AD2CAD2DAD34AD35AD38AD3CAD44
AD45AD47AD49AD50AD54AD58AD61AD63AD6CAD6DAD70AD73AD74AD75AD76AD7B
AD7CAD7DAD7FAD81AD82AD88AD89AD8CAD90AD9CAD9DADA4ADB7ADC0ADC1ADC4
ADC8ADD0ADD1ADD3ADDCADE0ADE4ADF8ADF9ADFCADFFAE00AE01AE08AE09AE0B
AE0DAE14AE30AE31AE34AE37AE38AE3AAE40AE41AE43AE45AE46AE4AAE4CAE4D
AE4EAE50AE54AE56AE5CAE5DAE5FAE60AE61AE65AE68AE69AE6CAE70AE780000
B2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CF6DCF6ECF6FCF72CF73CF75CF76CF77CF79CF7ACF7BCF7CCF7DCF7ECF7F
CF81CF82CF83CF84CF86CF87CF88CF89CF8ACF8BCF8D00000000000000000000
0000CF8ECF8FCF90CF91CF92CF93CF94CF95CF96CF97CF98CF99CF9ACF9BCF9C
CF9DCF9ECF9FCFA0CFA2CFA3CFA4CFA5CFA6CFA7CFA900000000000000000000
0000CFAACFABCFACCFADCFAECFAFCFB1CFB2CFB3CFB4CFB5CFB6CFB7CFB8CFB9
CFBACFBBCFBCCFBDCFBECFBFCFC0CFC1CFC2CFC3CFC5CFC6CFC7CFC8CFC9CFCA
CFCBAE79AE7BAE7CAE7DAE84AE85AE8CAEBCAEBDAEBEAEC0AEC4AECCAECDAECF
AED0AED1AED8AED9AEDCAEE8AEEBAEEDAEF4AEF8AEFCAF07AF08AF0DAF10AF2C
AF2DAF30AF32AF34AF3CAF3DAF3FAF41AF42AF43AF48AF49AF50AF5CAF5DAF64
AF65AF79AF80AF84AF88AF90AF91AF95AF9CAFB8AFB9AFBCAFC0AFC7AFC8AFC9
AFCBAFCDAFCEAFD4AFDCAFE8AFE9AFF0AFF1AFF4AFF8B000B001B004B00CB010
B014B01CB01DB028B044B045B048B04AB04CB04EB053B054B055B057B0590000
B3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CFCCCFCDCFCECFCFCFD0CFD1CFD2CFD3CFD4CFD5CFD6CFD7CFD8CFD9CFDA
CFDBCFDCCFDDCFDECFDFCFE2CFE3CFE5CFE6CFE7CFE900000000000000000000
0000CFEACFEBCFECCFEDCFEECFEFCFF2CFF4CFF6CFF7CFF8CFF9CFFACFFBCFFD
CFFECFFFD001D002D003D005D006D007D008D009D00A00000000000000000000
0000D00BD00CD00DD00ED00FD010D012D013D014D015D016D017D019D01AD01B
D01CD01DD01ED01FD020D021D022D023D024D025D026D027D028D029D02AD02B
D02CB05DB07CB07DB080B084B08CB08DB08FB091B098B099B09AB09CB09FB0A0
B0A1B0A2B0A8B0A9B0ABB0ACB0ADB0AEB0AFB0B1B0B3B0B4B0B5B0B8B0BCB0C4
B0C5B0C7B0C8B0C9B0D0B0D1B0D4B0D8B0E0B0E5B108B109B10BB10CB110B112
B113B118B119B11BB11CB11DB123B124B125B128B12CB134B135B137B138B139
B140B141B144B148B150B151B154B155B158B15CB160B178B179B17CB180B182
B188B189B18BB18DB192B193B194B198B19CB1A8B1CCB1D0B1D4B1DCB1DD0000
B4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D02ED02FD030D031D032D033D036D037D039D03AD03BD03DD03ED03FD040
D041D042D043D046D048D04AD04BD04CD04DD04ED04F00000000000000000000
0000D051D052D053D055D056D057D059D05AD05BD05CD05DD05ED05FD061D062
D063D064D065D066D067D068D069D06AD06BD06ED06F00000000000000000000
0000D071D072D073D075D076D077D078D079D07AD07BD07ED07FD080D082D083
D084D085D086D087D088D089D08AD08BD08CD08DD08ED08FD090D091D092D093
D094B1DFB1E8B1E9B1ECB1F0B1F9B1FBB1FDB204B205B208B20BB20CB214B215
B217B219B220B234B23CB258B25CB260B268B269B274B275B27CB284B285B289
B290B291B294B298B299B29AB2A0B2A1B2A3B2A5B2A6B2AAB2ACB2B0B2B4B2C8
B2C9B2CCB2D0B2D2B2D8B2D9B2DBB2DDB2E2B2E4B2E5B2E6B2E8B2EBB2ECB2ED
B2EEB2EFB2F3B2F4B2F5B2F7B2F8B2F9B2FAB2FBB2FFB300B301B304B308B310
B311B313B314B315B31CB354B355B356B358B35BB35CB35EB35FB364B3650000
B5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D095D096D097D098D099D09AD09BD09CD09DD09ED09FD0A0D0A1D0A2D0A3
D0A6D0A7D0A9D0AAD0ABD0ADD0AED0AFD0B0D0B1D0B200000000000000000000
0000D0B3D0B6D0B8D0BAD0BBD0BCD0BDD0BED0BFD0C2D0C3D0C5D0C6D0C7D0CA
D0CBD0CCD0CDD0CED0CFD0D2D0D6D0D7D0D8D0D9D0DA00000000000000000000
0000D0DBD0DED0DFD0E1D0E2D0E3D0E5D0E6D0E7D0E8D0E9D0EAD0EBD0EED0F2
D0F3D0F4D0F5D0F6D0F7D0F9D0FAD0FBD0FCD0FDD0FED0FFD100D101D102D103
D104B367B369B36BB36EB370B371B374B378B380B381B383B384B385B38CB390
B394B3A0B3A1B3A8B3ACB3C4B3C5B3C8B3CBB3CCB3CEB3D0B3D4B3D5B3D7B3D9
B3DBB3DDB3E0B3E4B3E8B3FCB410B418B41CB420B428B429B42BB434B450B451
B454B458B460B461B463B465B46CB480B488B49DB4A4B4A8B4ACB4B5B4B7B4B9
B4C0B4C4B4C8B4D0B4D5B4DCB4DDB4E0B4E3B4E4B4E6B4ECB4EDB4EFB4F1B4F8
B514B515B518B51BB51CB524B525B527B528B529B52AB530B531B534B5380000
B6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D105D106D107D108D109D10AD10BD10CD10ED10FD110D111D112D113D114
D115D116D117D118D119D11AD11BD11CD11DD11ED11F00000000000000000000
0000D120D121D122D123D124D125D126D127D128D129D12AD12BD12CD12DD12E
D12FD132D133D135D136D137D139D13BD13CD13DD13E00000000000000000000
0000D13FD142D146D147D148D149D14AD14BD14ED14FD151D152D153D155D156
D157D158D159D15AD15BD15ED160D162D163D164D165D166D167D169D16AD16B
D16DB540B541B543B544B545B54BB54CB54DB550B554B55CB55DB55FB560B561
B5A0B5A1B5A4B5A8B5AAB5ABB5B0B5B1B5B3B5B4B5B5B5BBB5BCB5BDB5C0B5C4
B5CCB5CDB5CFB5D0B5D1B5D8B5ECB610B611B614B618B625B62CB634B648B664
B668B69CB69DB6A0B6A4B6ABB6ACB6B1B6D4B6F0B6F4B6F8B700B701B705B728
B729B72CB72FB730B738B739B73BB744B748B74CB754B755B760B764B768B770
B771B773B775B77CB77DB780B784B78CB78DB78FB790B791B792B796B7970000
B7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D16ED16FD170D171D172D173D174D175D176D177D178D179D17AD17BD17D
D17ED17FD180D181D182D183D185D186D187D189D18A00000000000000000000
0000D18BD18CD18DD18ED18FD190D191D192D193D194D195D196D197D198D199
D19AD19BD19CD19DD19ED19FD1A2D1A3D1A5D1A6D1A700000000000000000000
0000D1A9D1AAD1ABD1ACD1ADD1AED1AFD1B2D1B4D1B6D1B7D1B8D1B9D1BBD1BD
D1BED1BFD1C1D1C2D1C3D1C4D1C5D1C6D1C7D1C8D1C9D1CAD1CBD1CCD1CDD1CE
D1CFB798B799B79CB7A0B7A8B7A9B7ABB7ACB7ADB7B4B7B5B7B8B7C7B7C9B7EC
B7EDB7F0B7F4B7FCB7FDB7FFB800B801B807B808B809B80CB810B818B819B81B
B81DB824B825B828B82CB834B835B837B838B839B840B844B851B853B85CB85D
B860B864B86CB86DB86FB871B878B87CB88DB8A8B8B0B8B4B8B8B8C0B8C1B8C3
B8C5B8CCB8D0B8D4B8DDB8DFB8E1B8E8B8E9B8ECB8F0B8F8B8F9B8FBB8FDB904
B918B920B93CB93DB940B944B94CB94FB951B958B959B95CB960B968B9690000
B8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D1D0D1D1D1D2D1D3D1D4D1D5D1D6D1D7D1D9D1DAD1DBD1DCD1DDD1DED1DF
D1E0D1E1D1E2D1E3D1E4D1E5D1E6D1E7D1E8D1E9D1EA00000000000000000000
0000D1EBD1ECD1EDD1EED1EFD1F0D1F1D1F2D1F3D1F5D1F6D1F7D1F9D1FAD1FB
D1FCD1FDD1FED1FFD200D201D202D203D204D205D20600000000000000000000
0000D208D20AD20BD20CD20DD20ED20FD211D212D213D214D215D216D217D218
D219D21AD21BD21CD21DD21ED21FD220D221D222D223D224D225D226D227D228
D229B96BB96DB974B975B978B97CB984B985B987B989B98AB98DB98EB9ACB9AD
B9B0B9B4B9BCB9BDB9BFB9C1B9C8B9C9B9CCB9CEB9CFB9D0B9D1B9D2B9D8B9D9
B9DBB9DDB9DEB9E1B9E3B9E4B9E5B9E8B9ECB9F4B9F5B9F7B9F8B9F9B9FABA00
BA01BA08BA15BA38BA39BA3CBA40BA42BA48BA49BA4BBA4DBA4EBA53BA54BA55
BA58BA5CBA64BA65BA67BA68BA69BA70BA71BA74BA78BA83BA84BA85BA87BA8C
BAA8BAA9BAABBAACBAB0BAB2BAB8BAB9BABBBABDBAC4BAC8BAD8BAD9BAFC0000
B9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D22AD22BD22ED22FD231D232D233D235D236D237D238D239D23AD23BD23E
D240D242D243D244D245D246D247D249D24AD24BD24C00000000000000000000
0000D24DD24ED24FD250D251D252D253D254D255D256D257D258D259D25AD25B
D25DD25ED25FD260D261D262D263D265D266D267D26800000000000000000000
0000D269D26AD26BD26CD26DD26ED26FD270D271D272D273D274D275D276D277
D278D279D27AD27BD27CD27DD27ED27FD282D283D285D286D287D289D28AD28B
D28CBB00BB04BB0DBB0FBB11BB18BB1CBB20BB29BB2BBB34BB35BB36BB38BB3B
BB3CBB3DBB3EBB44BB45BB47BB49BB4DBB4FBB50BB54BB58BB61BB63BB6CBB88
BB8CBB90BBA4BBA8BBACBBB4BBB7BBC0BBC4BBC8BBD0BBD3BBF8BBF9BBFCBBFF
BC00BC02BC08BC09BC0BBC0CBC0DBC0FBC11BC14BC15BC16BC17BC18BC1BBC1C
BC1DBC1EBC1FBC24BC25BC27BC29BC2DBC30BC31BC34BC38BC40BC41BC43BC44
BC45BC49BC4CBC4DBC50BC5DBC84BC85BC88BC8BBC8CBC8EBC94BC95BC970000
BA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D28DD28ED28FD292D293D294D296D297D298D299D29AD29BD29DD29ED29F
D2A1D2A2D2A3D2A5D2A6D2A7D2A8D2A9D2AAD2ABD2AD00000000000000000000
0000D2AED2AFD2B0D2B2D2B3D2B4D2B5D2B6D2B7D2BAD2BBD2BDD2BED2C1D2C3
D2C4D2C5D2C6D2C7D2CAD2CCD2CDD2CED2CFD2D0D2D100000000000000000000
0000D2D2D2D3D2D5D2D6D2D7D2D9D2DAD2DBD2DDD2DED2DFD2E0D2E1D2E2D2E3
D2E6D2E7D2E8D2E9D2EAD2EBD2ECD2EDD2EED2EFD2F2D2F3D2F5D2F6D2F7D2F9
D2FABC99BC9ABCA0BCA1BCA4BCA7BCA8BCB0BCB1BCB3BCB4BCB5BCBCBCBDBCC0
BCC4BCCDBCCFBCD0BCD1BCD5BCD8BCDCBCF4BCF5BCF6BCF8BCFCBD04BD05BD07
BD09BD10BD14BD24BD2CBD40BD48BD49BD4CBD50BD58BD59BD64BD68BD80BD81
BD84BD87BD88BD89BD8ABD90BD91BD93BD95BD99BD9ABD9CBDA4BDB0BDB8BDD4
BDD5BDD8BDDCBDE9BDF0BDF4BDF8BE00BE03BE05BE0CBE0DBE10BE14BE1CBE1D
BE1FBE44BE45BE48BE4CBE4EBE54BE55BE57BE59BE5ABE5BBE60BE61BE640000
BB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D2FBD2FCD2FDD2FED2FFD302D304D306D307D308D309D30AD30BD30FD311
D312D313D315D317D318D319D31AD31BD31ED322D32300000000000000000000
0000D324D326D327D32AD32BD32DD32ED32FD331D332D333D334D335D336D337
D33AD33ED33FD340D341D342D343D346D347D348D34900000000000000000000
0000D34AD34BD34CD34DD34ED34FD350D351D352D353D354D355D356D357D358
D359D35AD35BD35CD35DD35ED35FD360D361D362D363D364D365D366D367D368
D369BE68BE6ABE70BE71BE73BE74BE75BE7BBE7CBE7DBE80BE84BE8CBE8DBE8F
BE90BE91BE98BE99BEA8BED0BED1BED4BED7BED8BEE0BEE3BEE4BEE5BEECBF01
BF08BF09BF18BF19BF1BBF1CBF1DBF40BF41BF44BF48BF50BF51BF55BF94BFB0
BFC5BFCCBFCDBFD0BFD4BFDCBFDFBFE1C03CC051C058C05CC060C068C069C090
C091C094C098C0A0C0A1C0A3C0A5C0ACC0ADC0AFC0B0C0B3C0B4C0B5C0B6C0BC
C0BDC0BFC0C0C0C1C0C5C0C8C0C9C0CCC0D0C0D8C0D9C0DBC0DCC0DDC0E40000
BC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D36AD36BD36CD36DD36ED36FD370D371D372D373D374D375D376D377D378
D379D37AD37BD37ED37FD381D382D383D385D386D38700000000000000000000
0000D388D389D38AD38BD38ED392D393D394D395D396D397D39AD39BD39DD39E
D39FD3A1D3A2D3A3D3A4D3A5D3A6D3A7D3AAD3ACD3AE00000000000000000000
0000D3AFD3B0D3B1D3B2D3B3D3B5D3B6D3B7D3B9D3BAD3BBD3BDD3BED3BFD3C0
D3C1D3C2D3C3D3C6D3C7D3CAD3CBD3CCD3CDD3CED3CFD3D1D3D2D3D3D3D4D3D5
D3D6C0E5C0E8C0ECC0F4C0F5C0F7C0F9C100C104C108C110C115C11CC11DC11E
C11FC120C123C124C126C127C12CC12DC12FC130C131C136C138C139C13CC140
C148C149C14BC14CC14DC154C155C158C15CC164C165C167C168C169C170C174
C178C185C18CC18DC18EC190C194C196C19CC19DC19FC1A1C1A5C1A8C1A9C1AC
C1B0C1BDC1C4C1C8C1CCC1D4C1D7C1D8C1E0C1E4C1E8C1F0C1F1C1F3C1FCC1FD
C200C204C20CC20DC20FC211C218C219C21CC21FC220C228C229C22BC22D0000
BD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D3D7D3D9D3DAD3DBD3DCD3DDD3DED3DFD3E0D3E2D3E4D3E5D3E6D3E7D3E8
D3E9D3EAD3EBD3EED3EFD3F1D3F2D3F3D3F5D3F6D3F700000000000000000000
0000D3F8D3F9D3FAD3FBD3FED400D402D403D404D405D406D407D409D40AD40B
D40CD40DD40ED40FD410D411D412D413D414D415D41600000000000000000000
0000D417D418D419D41AD41BD41CD41ED41FD420D421D422D423D424D425D426
D427D428D429D42AD42BD42CD42DD42ED42FD430D431D432D433D434D435D436
D437C22FC231C232C234C248C250C251C254C258C260C265C26CC26DC270C274
C27CC27DC27FC281C288C289C290C298C29BC29DC2A4C2A5C2A8C2ACC2ADC2B4
C2B5C2B7C2B9C2DCC2DDC2E0C2E3C2E4C2EBC2ECC2EDC2EFC2F1C2F6C2F8C2F9
C2FBC2FCC300C308C309C30CC30DC313C314C315C318C31CC324C325C328C329
C345C368C369C36CC370C372C378C379C37CC37DC384C388C38CC3C0C3D8C3D9
C3DCC3DFC3E0C3E2C3E8C3E9C3EDC3F4C3F5C3F8C408C410C424C42CC4300000
BE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D438D439D43AD43BD43CD43DD43ED43FD441D442D443D445D446D447D448
D449D44AD44BD44CD44DD44ED44FD450D451D452D45300000000000000000000
0000D454D455D456D457D458D459D45AD45BD45DD45ED45FD461D462D463D465
D466D467D468D469D46AD46BD46CD46ED470D471D47200000000000000000000
0000D473D474D475D476D477D47AD47BD47DD47ED481D483D484D485D486D487
D48AD48CD48ED48FD490D491D492D493D495D496D497D498D499D49AD49BD49C
D49DC434C43CC43DC448C464C465C468C46CC474C475C479C480C494C49CC4B8
C4BCC4E9C4F0C4F1C4F4C4F8C4FAC4FFC500C501C50CC510C514C51CC528C529
C52CC530C538C539C53BC53DC544C545C548C549C54AC54CC54DC54EC553C554
C555C557C558C559C55DC55EC560C561C564C568C570C571C573C574C575C57C
C57DC580C584C587C58CC58DC58FC591C595C597C598C59CC5A0C5A9C5B4C5B5
C5B8C5B9C5BBC5BCC5BDC5BEC5C4C5C5C5C6C5C7C5C8C5C9C5CAC5CCC5CE0000
BF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D49ED49FD4A0D4A1D4A2D4A3D4A4D4A5D4A6D4A7D4A8D4AAD4ABD4ACD4AD
D4AED4AFD4B0D4B1D4B2D4B3D4B4D4B5D4B6D4B7D4B800000000000000000000
0000D4B9D4BAD4BBD4BCD4BDD4BED4BFD4C0D4C1D4C2D4C3D4C4D4C5D4C6D4C7
D4C8D4C9D4CAD4CBD4CDD4CED4CFD4D1D4D2D4D3D4D500000000000000000000
0000D4D6D4D7D4D8D4D9D4DAD4DBD4DDD4DED4E0D4E1D4E2D4E3D4E4D4E5D4E6
D4E7D4E9D4EAD4EBD4EDD4EED4EFD4F1D4F2D4F3D4F4D4F5D4F6D4F7D4F9D4FA
D4FCC5D0C5D1C5D4C5D8C5E0C5E1C5E3C5E5C5ECC5EDC5EEC5F0C5F4C5F6C5F7
C5FCC5FDC5FEC5FFC600C601C605C606C607C608C60CC610C618C619C61BC61C
C624C625C628C62CC62DC62EC630C633C634C635C637C639C63BC640C641C644
C648C650C651C653C654C655C65CC65DC660C66CC66FC671C678C679C67CC680
C688C689C68BC68DC694C695C698C69CC6A4C6A5C6A7C6A9C6B0C6B1C6B4C6B8
C6B9C6BAC6C0C6C1C6C3C6C5C6CCC6CDC6D0C6D4C6DCC6DDC6E0C6E1C6E80000
C0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D4FED4FFD500D501D502D503D505D506D507D509D50AD50BD50DD50ED50F
D510D511D512D513D516D518D519D51AD51BD51CD51D00000000000000000000
0000D51ED51FD520D521D522D523D524D525D526D527D528D529D52AD52BD52C
D52DD52ED52FD530D531D532D533D534D535D536D53700000000000000000000
0000D538D539D53AD53BD53ED53FD541D542D543D545D546D547D548D549D54A
D54BD54ED550D552D553D554D555D556D557D55AD55BD55DD55ED55FD561D562
D563C6E9C6ECC6F0C6F8C6F9C6FDC704C705C708C70CC714C715C717C719C720
C721C724C728C730C731C733C735C737C73CC73DC740C744C74AC74CC74DC74F
C751C752C753C754C755C756C757C758C75CC760C768C76BC774C775C778C77C
C77DC77EC783C784C785C787C788C789C78AC78EC790C791C794C796C797C798
C79AC7A0C7A1C7A3C7A4C7A5C7A6C7ACC7ADC7B0C7B4C7BCC7BDC7BFC7C0C7C1
C7C8C7C9C7CCC7CEC7D0C7D8C7DDC7E4C7E8C7ECC800C801C804C808C80A0000
C1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D564D566D567D56AD56CD56ED56FD570D571D572D573D576D577D579D57A
D57BD57DD57ED57FD580D581D582D583D586D58AD58B00000000000000000000
0000D58CD58DD58ED58FD591D592D593D594D595D596D597D598D599D59AD59B
D59CD59DD59ED59FD5A0D5A1D5A2D5A3D5A4D5A6D5A700000000000000000000
0000D5A8D5A9D5AAD5ABD5ACD5ADD5AED5AFD5B0D5B1D5B2D5B3D5B4D5B5D5B6
D5B7D5B8D5B9D5BAD5BBD5BCD5BDD5BED5BFD5C0D5C1D5C2D5C3D5C4D5C5D5C6
D5C7C810C811C813C815C816C81CC81DC820C824C82CC82DC82FC831C838C83C
C840C848C849C84CC84DC854C870C871C874C878C87AC880C881C883C885C886
C887C88BC88CC88DC894C89DC89FC8A1C8A8C8BCC8BDC8C4C8C8C8CCC8D4C8D5
C8D7C8D9C8E0C8E1C8E4C8F5C8FCC8FDC900C904C905C906C90CC90DC90FC911
C918C92CC934C950C951C954C958C960C961C963C96CC970C974C97CC988C989
C98CC990C998C999C99BC99DC9C0C9C1C9C4C9C7C9C8C9CAC9D0C9D1C9D30000
C2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D5CAD5CBD5CDD5CED5CFD5D1D5D3D5D4D5D5D5D6D5D7D5DAD5DCD5DED5DF
D5E0D5E1D5E2D5E3D5E6D5E7D5E9D5EAD5EBD5EDD5EE00000000000000000000
0000D5EFD5F0D5F1D5F2D5F3D5F6D5F8D5FAD5FBD5FCD5FDD5FED5FFD602D603
D605D606D607D609D60AD60BD60CD60DD60ED60FD61200000000000000000000
0000D616D617D618D619D61AD61BD61DD61ED61FD621D622D623D625D626D627
D628D629D62AD62BD62CD62ED62FD630D631D632D633D634D635D636D637D63A
D63BC9D5C9D6C9D9C9DAC9DCC9DDC9E0C9E2C9E4C9E7C9ECC9EDC9EFC9F0C9F1
C9F8C9F9C9FCCA00CA08CA09CA0BCA0CCA0DCA14CA18CA29CA4CCA4DCA50CA54
CA5CCA5DCA5FCA60CA61CA68CA7DCA84CA98CABCCABDCAC0CAC4CACCCACDCACF
CAD1CAD3CAD8CAD9CAE0CAECCAF4CB08CB10CB14CB18CB20CB21CB41CB48CB49
CB4CCB50CB58CB59CB5DCB64CB78CB79CB9CCBB8CBD4CBE4CBE7CBE9CC0CCC0D
CC10CC14CC1CCC1DCC21CC22CC27CC28CC29CC2CCC2ECC30CC38CC39CC3B0000
C3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D63DD63ED63FD641D642D643D644D646D647D64AD64CD64ED64FD650D652
D653D656D657D659D65AD65BD65DD65ED65FD660D66100000000000000000000
0000D662D663D664D665D666D668D66AD66BD66CD66DD66ED66FD672D673D675
D676D677D678D679D67AD67BD67CD67DD67ED67FD68000000000000000000000
0000D681D682D684D686D687D688D689D68AD68BD68ED68FD691D692D693D695
D696D697D698D699D69AD69BD69CD69ED6A0D6A2D6A3D6A4D6A5D6A6D6A7D6A9
D6AACC3CCC3DCC3ECC44CC45CC48CC4CCC54CC55CC57CC58CC59CC60CC64CC66
CC68CC70CC75CC98CC99CC9CCCA0CCA8CCA9CCABCCACCCADCCB4CCB5CCB8CCBC
CCC4CCC5CCC7CCC9CCD0CCD4CCE4CCECCCF0CD01CD08CD09CD0CCD10CD18CD19
CD1BCD1DCD24CD28CD2CCD39CD5CCD60CD64CD6CCD6DCD6FCD71CD78CD88CD94
CD95CD98CD9CCDA4CDA5CDA7CDA9CDB0CDC4CDCCCDD0CDE8CDECCDF0CDF8CDF9
CDFBCDFDCE04CE08CE0CCE14CE19CE20CE21CE24CE28CE30CE31CE33CE350000
C4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D6ABD6ADD6AED6AFD6B1D6B2D6B3D6B4D6B5D6B6D6B7D6B8D6BAD6BCD6BD
D6BED6BFD6C0D6C1D6C2D6C3D6C6D6C7D6C9D6CAD6CB00000000000000000000
0000D6CDD6CED6CFD6D0D6D2D6D3D6D5D6D6D6D8D6DAD6DBD6DCD6DDD6DED6DF
D6E1D6E2D6E3D6E5D6E6D6E7D6E9D6EAD6EBD6ECD6ED00000000000000000000
0000D6EED6EFD6F1D6F2D6F3D6F4D6F6D6F7D6F8D6F9D6FAD6FBD6FED6FFD701
D702D703D705D706D707D708D709D70AD70BD70CD70DD70ED70FD710D712D713
D714CE58CE59CE5CCE5FCE60CE61CE68CE69CE6BCE6DCE74CE75CE78CE7CCE84
CE85CE87CE89CE90CE91CE94CE98CEA0CEA1CEA3CEA4CEA5CEACCEADCEC1CEE4
CEE5CEE8CEEBCEECCEF4CEF5CEF7CEF8CEF9CF00CF01CF04CF08CF10CF11CF13
CF15CF1CCF20CF24CF2CCF2DCF2FCF30CF31CF38CF54CF55CF58CF5CCF64CF65
CF67CF69CF70CF71CF74CF78CF80CF85CF8CCFA1CFA8CFB0CFC4CFE0CFE1CFE4
CFE8CFF0CFF1CFF3CFF5CFFCD000D004D011D018D02DD034D035D038D03C0000
C5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D715D716D717D71AD71BD71DD71ED71FD721D722D723D724D725D726D727
D72AD72CD72ED72FD730D731D732D733D736D737D73900000000000000000000
0000D73AD73BD73DD73ED73FD740D741D742D743D745D746D748D74AD74BD74C
D74DD74ED74FD752D753D755D75AD75BD75CD75DD75E00000000000000000000
0000D75FD762D764D766D767D768D76AD76BD76DD76ED76FD771D772D773D775
D776D777D778D779D77AD77BD77ED77FD780D782D783D784D785D786D787D78A
D78BD044D045D047D049D050D054D058D060D06CD06DD070D074D07CD07DD081
D0A4D0A5D0A8D0ACD0B4D0B5D0B7D0B9D0C0D0C1D0C4D0C8D0C9D0D0D0D1D0D3
D0D4D0D5D0DCD0DDD0E0D0E4D0ECD0EDD0EFD0F0D0F1D0F8D10DD130D131D134
D138D13AD140D141D143D144D145D14CD14DD150D154D15CD15DD15FD161D168
D16CD17CD184D188D1A0D1A1D1A4D1A8D1B0D1B1D1B3D1B5D1BAD1BCD1C0D1D8
D1F4D1F8D207D209D210D22CD22DD230D234D23CD23DD23FD241D248D25C0000
C6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D78DD78ED78FD791D792D793D794D795D796D797D79AD79CD79ED79FD7A0
D7A1D7A2D7A30000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D264D280D281D284D288D290D291D295D29CD2A0D2A4D2ACD2B1D2B8D2B9
D2BCD2BFD2C0D2C2D2C8D2C9D2CBD2D4D2D8D2DCD2E4D2E5D2F0D2F1D2F4D2F8
D300D301D303D305D30CD30DD30ED310D314D316D31CD31DD31FD320D321D325
D328D329D32CD330D338D339D33BD33CD33DD344D345D37CD37DD380D384D38C
D38DD38FD390D391D398D399D39CD3A0D3A8D3A9D3ABD3ADD3B4D3B8D3BCD3C4
D3C5D3C8D3C9D3D0D3D8D3E1D3E3D3ECD3EDD3F0D3F4D3FCD3FDD3FFD4010000
C7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D408D41DD440D444D45CD460D464D46DD46FD478D479D47CD47FD480D482
D488D489D48BD48DD494D4A9D4CCD4D0D4D4D4DCD4DFD4E8D4ECD4F0D4F8D4FB
D4FDD504D508D50CD514D515D517D53CD53DD540D544D54CD54DD54FD551D558
D559D55CD560D565D568D569D56BD56DD574D575D578D57CD584D585D587D588
D589D590D5A5D5C8D5C9D5CCD5D0D5D2D5D8D5D9D5DBD5DDD5E4D5E5D5E8D5EC
D5F4D5F5D5F7D5F9D600D601D604D608D610D611D613D614D615D61CD6200000
C8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D624D62DD638D639D63CD640D645D648D649D64BD64DD651D654D655D658
D65CD667D669D670D671D674D683D685D68CD68DD690D694D69DD69FD6A1D6A8
D6ACD6B0D6B9D6BBD6C4D6C5D6C8D6CCD6D1D6D4D6D7D6D9D6E0D6E4D6E8D6F0
D6F5D6FCD6FDD700D704D711D718D719D71CD720D728D729D72BD72DD734D735
D738D73CD744D747D749D750D751D754D756D757D758D759D760D761D763D765
D769D76CD770D774D77CD77DD781D788D789D78CD790D798D799D79BD79D0000
CA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F3D4F73504750F952A053EF547554E556095AC15BB6668767B667B767EF
6B4C73C275C27A3C82DB8304885788888A368CC88DCF8EFB8FE699D5523B5374
5404606A61646BBC73CF811A89BA89D295A34F83520A58BE597859E65E725E79
61C763C0674667EC687F6F97764E770B78F57A087AFF7C21809D826E82718AEB
95934E6B559D66F76E3478A37AED845B8910874E97A852D8574E582A5D4C611F
61BE6221656267D16A446E1B751875B376E377B07D3A90AF945194529F950000
CB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000053235CAC753280DB92409598525B580859DC5CA15D175EB75F3A5F4A6177
6C5F757A75867CE07D737DB17F8C81548221859189418B1B92FC964D9C474ECB
4EF7500B51F1584F6137613E6168653969EA6F1175A5768676D67B8782A584CB
F90093A7958B55805BA25751F9017CB37FB991B5502853BB5C455DE862D2636E
64DA64E76E2070AC795B8DDD8E1EF902907D924592F84E7E4EF650655DFE5EFA
61066957817186548E4793759A2B4E5E5091677068405109528D52926AA20000
CC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077BC92109ED452AB602F8FF2504861A963ED64CA683C6A846FC0818889A1
96945805727D72AC75047D797E6D80A9898B8B7490639D5162896C7A6F547D50
7F3A8A23517C614A7B9D8B199257938C4EAC4FD3501E50BE510652C152CD537F
577058835E9A5F91617661AC64CE656C666F66BB66F468976D87708570F1749F
74A574CA75D9786C78EC7ADF7AF67D457D938015803F811B83968B668F159015
93E1980398389A5A9BE84FC25553583A59515B635C4660B86212684268B00000
CD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000068E86EAA754C767878CE7A3D7CFB7E6B7E7C8A088AA18C3F968E9DC453E4
53E9544A547156FA59D15B645C3B5EAB62F765376545657266A067AF69C16CBD
75FC7690777E7A3F7F94800380A1818F82E682FD83F085C1883188B48AA5F903
8F9C932E96C798679AD89F1354ED659B66F2688F7A408C379D6056F057645D11
660668B168CD6EFE7428889E9BE46C68F9049AA84F9B516C5171529F5B545DE5
6050606D62F163A7653B73D97A7A86A38CA2978F4E325BE16208679C74DC0000
CE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000079D183D38A878AB28DE8904E934B98465ED369E885FF90EDF90551A05B98
5BEC616368FA6B3E704C742F74D87BA17F5083C589C08CAB95DC9928522E605D
62EC90024F8A5149532158D95EE366E06D38709A72C273D67B5080F1945B5366
639B7F6B4E565080584A58DE602A612762D069D09B415B8F7D1880B18F5F4EA4
50D154AC55AC5B0C5DA05DE7652A654E68216A4B72E1768E77EF7D5E7FF981A0
854E86DF8F038F4E90CA99039A559BAB4E184E454E5D4EC74FF1517752FE0000
CF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000534053E353E5548E5614577557A25BC75D875ED061FC62D8655167B867E9
69CB6B506BC66BEC6C426E9D707872D77396740377BF77E97A767D7F800981FC
8205820A82DF88628B338CFC8EC0901190B1926492B699D29A459CE99DD79F9C
570B5C4083CA97A097AB9EB4541B7A987FA488D98ECD90E158005C4863987A9F
5BAE5F137A797AAE828E8EAC5026523852F85377570862F363726B0A6DC37737
53A5735785688E7695D5673A6AC36F708A6D8ECC994BF90666776B788CB40000
D0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009B3CF90753EB572D594E63C669FB73EA78457ABA7AC57CFE8475898F8D73
903595A852FB574775477B6083CC921EF9086A58514B524B5287621F68D86975
969950C552A452E461C365A4683969FF747E7B4B82B983EB89B28B398FD19949
F9094ECA599764D266116A8E7434798179BD82A9887E887F895FF90A93264F0B
53CA602562716C727D1A7D664E98516277DC80AF4F014F0E5176518055DC5668
573B57FA57FC5914594759935BC45C905D0E5DF15E7E5FCC628065D765E30000
D1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000671E671F675E68CB68C46A5F6B3A6C236C7D6C826DC773987426742A7482
74A37578757F788178EF794179477948797A7B957D007DBA7F888006802D808C
8A188B4F8C488D779321932498E299519A0E9A0F9A659E927DCA4F76540962EE
685491D155AB513AF90BF90C5A1C61E6F90D62CF62FFF90EF90FF910F911F912
F91390A3F914F915F916F917F9188AFEF919F91AF91BF91C6696F91D7156F91E
F91F96E3F920634F637A5357F921678F69606E73F9227537F923F924F9250000
D2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007D0DF926F927887256CA5A18F928F929F92AF92BF92C4E43F92D51675948
67F08010F92E59735E74649A79CA5FF5606C62C8637B5BE75BD752AAF92F5974
5F296012F930F931F9327459F933F934F935F936F937F93899D1F939F93AF93B
F93CF93DF93EF93FF940F941F942F9436FC3F944F94581BF8FB260F1F946F947
8166F948F9495C3FF94AF94BF94CF94DF94EF94FF950F9515AE98A25677B7D10
F952F953F954F955F956F95780FDF958F9595C3C6CE5533F6EBA591A83360000
D3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E394EB64F4655AE571858C75F5665B765E66A806BB56E4D77ED7AEF7C1E
7DDE86CB88929132935B64BB6FBE737A75B890545556574D61BA64D466C76DE1
6E5B6F6D6FB975F0804381BD854189838AC78B5A931F6C9375537B548E0F905D
5510580258585E626207649E68E075767CD687B39EE84EE35788576E59275C0D
5CB15E365F85623464E173B381FA888B8CB8968A9EDB5B855FB760B350125200
52305716583558575C0E5C605CF65D8B5EA65F9260BC63116389641768430000
D4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000068F96AC26DD86E216ED46FE471FE76DC777979B17A3B840489A98CED8DF3
8E4890039014905390FD934D967697DC6BD27006725872A27368776379BF7BE4
7E9B8B8058A960C7656665FD66BE6C8C711E71C98C5A98134E6D7A814EDD51AC
51CD52D5540C61A76771685068DF6D1E6F7C75BC77B37AE580F484639285515C
6597675C679375D87AC78373F95A8C469017982D5C6F81C0829A9041906F920D
5F975D9D6A5971C8767B7B4985E48B0491279A30558761F6F95B76697F850000
D5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000863F87BA88F8908FF95C6D1B70D973DE7D61843DF95D916A99F1F95E4E82
53756B046B12703E721B862D9E1E524C8FA35D5064E5652C6B166FEB7C437E9C
85CD896489BD62C981D8881F5ECA67176D6A72FC7405746F878290DE4F865D0D
5FA0840A51B763A075654EAE5006516951C968816A117CAE7CB17CE7826F8AD2
8F1B91CF4FB6513752F554425EEC616E623E65C56ADA6FFE792A85DC882395AD
9A629A6A9E979ECE529B66C66B77701D792B8F6297426190620065236F230000
D6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000714974897DF4806F84EE8F269023934A51BD521752A36D0C70C888C25EC9
65826BAE6FC27C3E73754EE44F3656F9F95F5CBA5DBA601C73B27B2D7F9A7FCE
8046901E923496F6974898189F614F8B6FA779AE91B496B752DEF960648864C4
6AD36F5E7018721076E780018606865C8DEF8F0597329B6F9DFA9E75788C797F
7DA083C993049E7F9E938AD658DF5F046727702774CF7C60807E512170287262
78CA8CC28CDA8CF496F74E8650DA5BEE5ED6659971CE764277AD804A84FC0000
D7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000907C9B279F8D58D85A415C626A136DDA6F0F763B7D2F7E37851E893893E4
964B528965D267F369B46D416E9C700F7409746075597624786B8B2C985E516D
622E96784F96502B5D196DEA7DB88F2A5F8B61446817F961968652D2808B51DC
51CC695E7A1C7DBE83F196754FDA52295398540F550E5C6560A7674E68A86D6C
728172F874067483F96275E27C6C7F797FB8838988CF88E191CC91D096E29BC9
541D6F7E71D0749885FA8EAA96A39C579E9F67976DCB743381E89716782C0000
D8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007ACB7B207C926469746A75F278BC78E899AC9B549EBB5BDE5E556F20819C
83AB90884E07534D5A295DD25F4E6162633D666966FC6EFF6F2B7063779E842C
8513883B8F1399459C3B551C62B9672B6CAB8309896A977A4EA159845FD85FD9
671B7DB27F548292832B83BD8F1E909957CB59B95A925BD06627679A68856BCF
71647F758CB78CE390819B4581088C8A964C9A409EA55B5F6C13731B76F276DF
840C51AA8993514D519552C968C96C94770477207DBF7DEC97629EB56EC50000
D9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000851151A5540D547D660E669D69276E9F76BF7791831784C2879F91699298
9CF488824FAE519252DF59C65E3D61556478647966AE67D06A216BCD6BDB725F
72617441773877DB801782BC83058B008B288C8C67286C90726776EE77667A46
9DA96B7F6C92592267268499536F589359995EDF63CF663467736E3A732B7AD7
82D7932852D95DEB61AE61CB620A62C764AB65E069596B666BCB712173F7755D
7E46821E8302856A8AA38CBF97279D6158A89ED85011520E543B554F65870000
DA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006C767D0A7D0B805E868A958096EF52FF6C95726954735A9A5C3E5D4B5F4C
5FAE672A68B669636E3C6E4477097C737F8E85878B0E8FF797619EF45CB760B6
610D61AB654F65FB65FC6C116CEF739F73C97DE195945BC6871C8B10525D535A
62CD640F64B267346A386CCA73C0749E7B947C957E1B818A823685848FEB96F9
99C14F34534A53CD53DB62CC642C6500659169C36CEE6F5873ED7554762276E4
76FC78D078FB792C7D46822C87E08FD4981298EF52C362D464A56E246F510000
DB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000767C8DCB91B192629AEE9B435023508D574A59A85C285E475F77623F653E
65B965C16609678B699C6EC278C57D2180AA8180822B82B384A1868C8A2A8B17
90A696329F90500D4FF3F96357F95F9862DC6392676F6E43711976C380CC80DA
88F488F589198CE08F29914D966A4F2F4F705E1B67CF6822767D767E9B445E61
6A0A716971D4756AF9647E41854385E998DC4F107B4F7F7095A551E15E0668B5
6C3E6C4E6CDB72AF7BC483036CD5743A50FB528858C164D86A9774A776560000
DC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000078A7861795E29739F965535E5F018B8A8FA88FAF908A522577A59C499F08
4E19500251755C5B5E77661E663A67C468C570B3750175C579C97ADD8F279920
9A084FDD582158315BF6666E6B656D116E7A6F7D73E4752B83E988DC89138B5C
8F144F0F50D55310535C5B935FA9670D798F8179832F8514890789868F398F3B
99A59C12672C4E764FF859495C015CEF5CF0636768D270FD71A2742B7E2B84EC
8702902292D29CF34E0D4ED84FEF50855256526F5426549057E0592B5A660000
DD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005B5A5B755BCC5E9CF9666276657765A76D6E6EA572367B267C3F7F368150
8151819A8240829983A98A038CA08CE68CFB8D748DBA90E891DC961C964499D9
9CE7531752065429567458B35954596E5FFF61A4626E66106C7E711A76C67C89
7CDE7D1B82AC8CC196F0F9674F5B5F175F7F62C25D29670B68DA787C7E439D6C
4E1550995315532A535159835A625E8760B2618A624962796590678769A76BD4
6BD66BD76BD86CB8F968743575FA7812789179D579D87C837DCB7FE180A50000
DE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000813E81C283F2871A88E88AB98B6C8CBB9119975E98DB9F3B56AC5B2A5F6C
658C6AB36BAF6D5C6FF17015725D73AD8CA78CD3983B61916C3780589A014E4D
4E8B4E9B4ED54F3A4F3C4F7F4FDF50FF53F253F8550655E356DB58EB59625A11
5BEB5BFA5C045DF35E2B5F99601D6368659C65AF67F667FB68AD6B7B6C996CD7
6E23700973457802793E7940796079C17BE97D177D728086820D838E84D186C7
88DF8A508A5E8B1D8CDC8D668FAD90AA98FC99DF9E9D524AF9696714F96A0000
DF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005098522A5C7165636C5573CA7523759D7B97849C917897304E7764926BBA
715E85A94E09F96B674968EE6E17829F8518886B63F76F81921298AF4E0A50B7
50CF511F554655AA56175B405C195CE05E385E8A5EA05EC260F368516A616E58
723D724072C076F879657BB17FD488F389F48A738C618CDE971C585E74BD8CFD
55C7F96C7A617D2282727272751F7525F96D7B19588558FB5DBC5E8F5EB65F90
60556292637F654D669166D966F8681668F27280745E7B6E7D6E7DD67F720000
E0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000080E5821285AF897F8A93901D92E49ECD9F205915596D5E2D60DC66146673
67906C506DC56F5F77F378A984C691CB932B4ED950CA514855845B0B5BA36247
657E65CB6E32717D74017444748774BF766C79AA7DDA7E557FA8817A81B38239
861A87EC8A758DE3907892919425994D9BAE53685C5169546CC46D296E2B820C
859B893B8A2D8AAA96EA9F67526166B96BB27E9687FE8D0D9583965D651D6D89
71EEF96E57CE59D35BAC602760FA6210661F665F732973F976DB77017B6C0000
E1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008056807281658AA091924E1652E26B726D177A057B397D30F96F8CB053EC
562F58515BB55C0F5C115DE2624063836414662D68B36CBC6D886EAF701F70A4
71D27526758F758E76197B117BE07C2B7D207D39852C856D86078A34900D9061
90B592B797F69A374FD75C6C675F6D917C9F7E8C8B168D16901F5B6B5DFD640D
84C0905C98E173875B8B609A677E6DDE8A1F8AA69001980C5237F9707051788E
9396887091D74FEE53D755FD56DA578258FD5AC25B885CAB5CC05E2561010000
E2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000620D624B6388641C653665786A396B8A6C346D196F3171E772E973787407
74B27626776179C07A577AEA7CB97D8F7DAC7E617F9E81298331849084DA85EA
88968AB08B908F3890429083916C929692B9968B96A796A896D6970098089996
9AD39B1A53D4587E59195B705BBF6DD16F5A719F742174B9808583FD5DE15F87
5FAA604265EC6812696F6A536B896D356DF373E376FE77AC7B4D7D148123821C
834084F485638A628AC49187931E980699B4620C88538FF092655D075D270000
E3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005D69745F819D87686FD562FE7FD2893689724E1E4E5850E752DD5347627F
66077E698805965E4F8D5319563659CB5AA45C385C4E5C4D5E025F11604365BD
662F664267BE67F4731C77E2793A7FC5849484CD89968A668A698AE18C558C7A
57F45BD45F0F606F62ED690D6B966E5C71847BD287558B588EFE98DF98FE4F38
4F814FE1547B5A205BB8613C65B0666871FC7533795E7D33814E81E3839885AA
85CE87038A0A8EAB8F9BF9718FC559315BA45BE660895BE95C0B5FC36C810000
E4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9726DF1700B751A82AF8AF64EC05341F97396D96C0F4E9E4FC45152555E
5A255CE86211725982BD83AA86FE88598A1D963F96C599139D099D5D580A5CB3
5DBD5E4460E1611563E16A026E2591029354984E9C109F775B895CB86309664F
6848773C96C1978D98549B9F65A18B018ECB95BC55355CA95DD65EB56697764C
83F495C758D362BC72CE9D284EF0592E600F663B6B8379E79D26539354C057C3
5D16611B66D66DAF788D827E969897445384627C63966DB27E0A814B984D0000
E5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006AFB7F4C9DAF9E1A4E5F503B51B6591C60F963F66930723A8036F97491CE
5F31F975F9767D0482E5846F84BB85E58E8DF9774F6FF978F97958E45B436059
63DA6518656D6698F97A694A6A236D0B7001716C75D2760D79B37A70F97B7F8A
F97C8944F97D8B9391C0967DF97E990A57045FA165BC6F01760079A68A9E99AD
9B5A9F6C510461B662916A8D81C6504358305F6671098A008AFA5B7C86164FFA
513C56B4594463A96DF95DAA696D51864E884F59F97FF980F9815982F9820000
E6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9836B5F6C5DF98474B57916F9858207824583398F3F8F5DF9869918F987
F988F9894EA6F98A57DF5F796613F98BF98C75AB7E798B6FF98D90069A5B56A5
582759F85A1F5BB4F98E5EF6F98FF9906350633BF991693D6C876CBF6D8E6D93
6DF56F14F99270DF71367159F99371C371D5F994784F786FF9957B757DE3F996
7E2FF997884D8EDFF998F999F99A925BF99B9CF6F99CF99DF99E60856D85F99F
71B1F9A0F9A195B153ADF9A2F9A3F9A467D3F9A5708E71307430827682D20000
E7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9A695BB9AE59E7D66C4F9A771C18449F9A8F9A9584BF9AAF9AB5DB85F71
F9AC6620668E697969AE6C386CF36E366F416FDA701B702F715071DF7370F9AD
745BF9AE74D476C87A4E7E93F9AFF9B082F18A608FCEF9B19348F9B29719F9B3
F9B44E42502AF9B5520853E166F36C6D6FCA730A777F7A6282AE85DD8602F9B6
88D48A638B7D8C6BF9B792B3F9B8971398104E944F0D4FC950B25348543E5433
55DA586258BA59675A1B5BE4609FF9B961CA655665FF666468A76C5A6FB30000
E8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000070CF71AC73527B7D87088AA49C329F075C4B6C8373447389923A6EAB7465
761F7A697E15860A514058C564C174EE751576707FC1909596CD99546E2674E6
7AA97AAA81E586D987788A1B5A495B8C5B9B68A169006D6373A97413742C7897
7DE97FEB81188155839E8C4C962E981166F05F8065FA67896C6A738B502D5A03
6B6A77EE59165D6C5DCD7325754FF9BAF9BB50E551F9582F592D599659DA5BE5
F9BCF9BD5DA262D76416649364FEF9BE66DCF9BF6A48F9C071FF7464F9C10000
E9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A887AAF7E477E5E80008170F9C287EF89818B209059F9C390809952617E
6B326D747E1F89258FB14FD150AD519752C757C758895BB95EB8614269956D8C
6E676EB6719474627528752C8073833884C98E0A939493DEF9C44E8E4F515076
512A53C853CB53F35B875BD35C24611A618265F4725B7397744076C279507991
79B97D067FBD828B85D5865E8FC2904790F591EA968596E896E952D65F6765ED
6631682F715C7A3690C1980A4E91F9C56A526B9E6F907189801882B885530000
EA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000904B969596F297FB851A9B314E90718A96C45143539F54E15713571257A3
5A9B5AC45BC36028613F63F46C856D396E726E907230733F745782D188818F45
9060F9C6966298589D1B67088D8A925E4F4D504950DE5371570D59D45A015C09
617066906E2D7232744B7DEF80C3840E8466853F875F885B89188B02905597CB
9B4F4E734F915112516AF9C7552F55A95B7A5BA55E7C5E7D5EBE60A060DF6108
610963C465386709F9C867D467DAF9C9696169626CB96D27F9CA6E38F9CB0000
EB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006FE173367337F9CC745C7531F9CD7652F9CEF9CF7DAD81FE843888D58A98
8ADB8AED8E308E42904A903E907A914991C9936EF9D0F9D15809F9D26BD38089
80B2F9D3F9D45141596B5C39F9D5F9D66F6473A780E48D07F9D79217958FF9D8
F9D9F9DAF9DB807F620E701C7D68878DF9DC57A0606961476BB78ABE928096B1
4E59541F6DEB852D967097F398EE63D66CE3909151DD61C981BA9DF94F9D501A
51005B9C610F61FF64EC69056BC5759177E37FA98264858F87FB88638ABC0000
EC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008B7091AB4E8C4EE54F0AF9DDF9DE593759E8F9DF5DF25F1B5F5B6021F9E0
F9E1F9E2F9E3723E73E5F9E4757075CDF9E579FBF9E6800C8033808482E18351
F9E7F9E88CBD8CB39087F9E9F9EA98F4990CF9EBF9EC703776CA7FCA7FCC7FFC
8B1A4EBA4EC152035370F9ED54BD56E059FB5BC55F155FCD6E6EF9EEF9EF7D6A
8335F9F086938A8DF9F1976D9777F9F2F9F34E004F5A4F7E58F965E56EA29038
93B099B94EFB58EC598A59D96041F9F4F9F57A14F9F6834F8CC3516553440000
ED
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9F7F9F8F9F94ECD52695B5582BF4ED4523A54A859C959FF5B505B575B5C
606361486ECB7099716E738674F775B578C17D2B800581EA8328851785C98AEE
8CC796CC4F5C52FA56BC65AB6628707C70B872357DBD828D914C96C09D725B71
68E76B986F7A76DE5C9166AB6F5B7BB47C2A883696DC4E084ED75320583458BB
58EF596C5C075E335E845F35638C66B267566A1F6AA36B0C6F3F7246F9FA7350
748B7AE07CA7817881DF81E7838A846C8523859485CF88DD8D1391AC95770000
EE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000969C518D54C957285BB0624D6750683D68936E3D6ED3707D7E2188C18CA1
8F099F4B9F4E722D7B8F8ACD931A4F474F4E5132548059D05E9562B56775696E
6A176CAE6E1A72D9732A75BD7BB87D3582E783F9845785F78A5B8CAF8E879019
90B896CE9F5F52E3540A5AE15BC2645865756EF472C4F9FB76847A4D7B1B7C4D
7E3E7FDF837B8B2B8CCA8D648DE18E5F8FEA8FF9906993D14F434F7A50B35168
5178524D526A5861587C59605C085C555EDB609B623068136BBF6C086FB10000
EF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000714E742075307538755176727B4C7B8B7BAD7BC67E8F8A6E8F3E8F49923F
92939322942B96FB985A986B991E5207622A62986D5976647ACA7BC07D765360
5CBE5E976F3870B97C9897119B8E9EDE63A5647A87764E014E954EAD505C5075
544859C35B9A5E405EAD5EF75F8160C5633A653F657465CC6676667867FE6968
6A896B636C406DC06DE86E1F6E5E701E70A1738E73FD753A775B7887798E7A0B
7A7D7CBE7D8E82478A028AEA8C9E912D914A91D8926692CC9320970697560000
F0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000975C98029F0E52365291557C58245E1D5F1F608C63D068AF6FDF796D7B2C
81CD85BA88FD8AF88E44918D9664969B973D984C9F4A4FCE514651CB52A95632
5F145F6B63AA64CD65E9664166FA66F9671D689D68D769FD6F156F6E716771E5
722A74AA773A7956795A79DF7A207A957C977CDF7D447E70808785FB86A48A54
8ABF8D998E819020906D91E3963B96D59CE565CF7C078DB393C35B585C0A5352
62D9731D50275B975F9E60B0616B68D56DD9742E7A2E7D427D9C7E31816B0000
F1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008E2A8E35937E94184F5057505DE65EA7632B7F6A4E3B4F4F4F8F505A59DD
80C4546A546855FE594F5B995DDE5EDA665D673167F1682A6CE86D326E4A6F8D
70B773E075877C4C7D027D2C7DA2821F86DB8A3B8A858D708E8A8F339031914E
9152944499D07AF97CA54FCA510151C657C85BEF5CFB66596A3D6D5A6E966FEC
710C756F7AE388229021907596CB99FF83014E2D4EF2884691CD537D6ADB696B
6C41847A589E618E66FE62EF70DD751175C77E5284B88B498D084E4B53EA0000
F2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054AB573057405FD763016307646F652F65E8667A679D67B36B626C606C9A
6F2C77E57825794979577D1980A2810281F3829D82B787188A8CF9FC8D048DBE
907276F47A197A377E548077550755D45875632F64226649664B686D699B6B84
6D256EB173CD746874A1755B75B976E1771E778B79E67E097E1D81FB852F8897
8A3A8CD18EEB8FB0903293AD9663967397074F8453F159EA5AC95E19684E74C6
75BE79E97A9281A386ED8CEA8DCC8FED659F6715F9FD57F76F577DDD8F2F0000
F3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000093F696C65FB561F26F844E144F98501F53C955DF5D6F5DEE6B216B6478CB
7B9AF9FE8E498ECA906E6349643E77407A84932F947F9F6A64B06FAF71E674A8
74DA7AC47C127E827CB27E988B9A8D0A947D9910994C52395BDF64E6672D7D2E
50ED53C358796158615961FA65AC7AD98B928B9650095021527555315A3C5EE0
5F706134655E660C663666A269CD6EC46F32731676217A938139825983D684BC
50B557F05BC05BE85F6963A178267DB583DC852191C791F5518A67F57B560000
F4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008CAC51C459BB60BD8655501CF9FF52545C3A617D621A62D364F265A56ECC
7620810A8E60965F96BB4EDF5343559859295DDD64C56CC96DFA73947A7F821B
85A68CE48E10907791E795E1962197C651F854F255865FB964A46F887DB48F1F
8F4D943550C95C166CBE6DFB751B77BB7C3D7C648A798AC2581E59BE5E166377
7252758A776B8ADC8CBC8F125EF366746DF8807D83C18ACB97519BD6FA005243
66FF6D956EEF7DE08AE6902E905E9AD4521D527F54E86194628462DB68A20000
F5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006912695A6A3570927126785D7901790E79D27A0D8096827882D583498549
8C828D859162918B91AE4FC356D171ED77D7870089F85BF85FD6675190A853E2
585A5BF560A4618164607E3D80708525928364AE50AC5D146700589C62BD63A8
690E69786A1E6E6B76BA79CB82BB84298ACF8DA88FFD9112914B919C93109318
939A96DB9A369C0D4E11755C795D7AFA7B517BC97E2E84C48E598E748EF89010
6625693F744351FA672E9EDC51455FE06C9687F2885D887760B481B584030000
F6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008D0553D6543956345A365C31708A7FE0805A810681ED8DA391899A5F9DF2
50744EC453A060FB6E2C5C644F88502455E45CD95E5F606568946CBB6DC471BE
75D475F476617A1A7A497DC77DFB7F6E81F486A98F1C96C999B39F52524752C5
98ED89AA4E0367D26F064FB55BE267956C886D78741B782791DD937C87C479E4
7A315FEB4ED654A4553E58AE59A560F0625362D6673669558235964099B199DD
502C53535544577CFA016258FA0264E2666B67DD6FC16FEF742274388A170000
F7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000094385451560657665F48619A6B4E705870AD7DBB8A95596A812B63A27708
803D8CAA5854642D69BB5B955E116E6FFA038569514C53F0592A6020614B6B86
6C706CF07B1E80CE82D48DC690B098B1FA0464C76FA464916504514E5410571F
8A0E615F6876FA0575DB7B527D71901A580669CC817F892A9000983950785957
59AC6295900F9B2A615D727995D657615A465DF4628A64AD64FA67776CE26D3E
722C743678347F7782AD8DDB981752245742677F724874E38CA98FA692110000
F8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000962A516B53ED634C4F695504609665576C9B6D7F724C72FD7A1789878C9D
5F6D6F8E70F981A8610E4FBF504F624172477BC77DE87FE9904D97AD9A198CB6
576A5E7367B0840D8A5554205B165E635EE25F0A658380BA853D9589965B4F48
5305530D530F548654FA57035E036016629B62B16355FA066CE16D6675B17832
80DE812F82DE846184B2888D8912900B92EA98FD9B915E4566B466DD70117206
FA074FF5527D5F6A615367536A196F0274E2796888688C7998C798C49A430000
F9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054C17A1F69538AF78C4A98A899AE5F7C62AB75B276AE88AB907F96425339
5F3C5FC56CCC73CC7562758B7B4682FE999D4E4F903C4E0B4F5553A6590F5EC8
66306CB37455837787668CC09050971E9C1558D15B7886508B149DB45BD26068
608D65F16C576F226FA3701A7F557FF095919592965097D352728F4451FD542B
54B85563558A6ABB6DB57DD88266929C96779E79540854C876D286E495A495D4
965C4EA24F0959EE5AE65DF760526297676D68416C866E2F7F38809B822A0000
FA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FA08FA0998054EA5505554B35793595A5B695BB361C869776D77702387F9
89E38A728AE7908299ED9AB852BE683850165E78674F8347884C4EAB541156AE
73E6911597FF9909995799995653589F865B8A3161B26AF6737B8ED26B4796AA
9A57595572008D6B97694FD45CF45F2661F8665B6CEB70AB738473B973FE7729
774D7D437D627E2382378852FA0A8CE29249986F5B517A74884098015ACC4FE0
5354593E5CFD633E6D7972F98105810783A292CF98304EA851445211578B0000
FB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F626CC26ECE7005705070AF719273E97469834A87A28861900890A293A3
99A8516E5F5760E0616766B385598E4A91AF978B4E4E4E92547C58D558FA597D
5CB55F2762366248660A66676BEB6D696DCF6E566EF86F946FE06FE9705D72D0
7425745A74E07693795C7CCA7E1E80E182A6846B84BF864E865F87748B778C6A
93AC9800986560D1621691775A5A660F6DF76E3E743F9B425FFD60DA7B0F54C4
5F186C5E6CD36D2A70D87D0586798A0C9D3B5316548C5B056A3A706B75750000
FC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000798D79BE82B183EF8A718B418CA89774FA0B64F4652B78BA78BB7A6B4E38
559A59505BA65E7B60A363DB6B61666568536E19716574B07D0890849A699C25
6D3B6ED1733E8C4195CA51F05E4C5FA8604D60F66130614C6643664469A56CC1
6E5F6EC96F62714C749C76877BC17C27835287579051968D9EC3532F56DE5EFB
5F8A6062609461F7666667036A9C6DEE6FAE7070736A7E6A81BE833486D48AA8
8CC4528373725B966A6B940454EE56865B5D6548658566C9689F6D8D6DC60000
FD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000723B80B491759A4D4FAF5019539A540E543C558955C55E3F5F8C673D7166
73DD900552DB52F3586458CE7104718F71FB85B08A13668885A855A76684714A
8431534955996BC15F595FBD63EE668971478AF18F1D9EBE4F11643A70CB7566
866760648B4E9DF8514751F653086D3680F89ED166156B23709875D554035C79
7D078A166B206B3D6B46543860706D3D7FD5820850D651DE559C566B56CD59EC
5B095E0C619961986231665E66E6719971B971BA72A779A77A007FB28A700000

Added library/encoding/cp950.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
# Encoding file: cp950, multi-byte
M
003F 0 88
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3000FF0C30013002FF0E2027FF1BFF1AFF1FFF01FE3020262025FE50FE51FE52
00B7FE54FE55FE56FE57FF5C2013FE312014FE332574FE34FE4FFF08FF09FE35
FE36FF5BFF5DFE37FE3830143015FE39FE3A30103011FE3BFE3C300A300BFE3D
FE3E30083009FE3FFE40300C300DFE41FE42300E300FFE43FE44FE59FE5A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FE5BFE5CFE5DFE5E20182019201C201D301D301E20352032FF03FF06FF0A
203B00A7300325CB25CF25B325B225CE2606260525C725C625A125A025BD25BC
32A3210500AFFFE3FF3F02CDFE49FE4AFE4DFE4EFE4BFE4CFE5FFE60FE61FF0B
FF0D00D700F700B1221AFF1CFF1EFF1D226622672260221E22522261FE62FE63
FE64FE65FE66FF5E2229222A22A52220221F22BF33D233D1222B222E22352234
26402642229522992191219321902192219621972199219822252223FF0F0000
A2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF3C2215FE68FF04FFE53012FFE0FFE1FF05FF2021032109FE69FE6AFE6B33D5
339C339D339E33CE33A1338E338F33C400B05159515B515E515D5161516355E7
74E97CCE25812582258325842585258625872588258F258E258D258C258B258A
2589253C2534252C2524251C2594250025022595250C251025142518256D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000256E2570256F2550255E256A256125E225E325E525E4257125722573FF10
FF11FF12FF13FF14FF15FF16FF17FF18FF192160216121622163216421652166
216721682169302130223023302430253026302730283029534153445345FF21
FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2FFF30FF31
FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF41FF42FF43FF44FF45FF46FF47
FF48FF49FF4AFF4BFF4CFF4DFF4EFF4FFF50FF51FF52FF53FF54FF55FF560000
A3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF57FF58FF59FF5A039103920393039403950396039703980399039A039B039C
039D039E039F03A003A103A303A403A503A603A703A803A903B103B203B303B4
03B503B603B703B803B903BA03BB03BC03BD03BE03BF03C003C103C303C403C5
03C603C703C803C931053106310731083109310A310B310C310D310E310F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00003110311131123113311431153116311731183119311A311B311C311D311E
311F312031213122312331243125312631273128312902D902C902CA02C702CB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E004E594E014E034E434E5D4E864E8C4EBA513F5165516B51E052005201529B
53155341535C53C84E094E0B4E084E0A4E2B4E3851E14E454E484E5F4E5E4E8E
4EA15140520352FA534353C953E3571F58EB5915592759735B505B515B535BF8
5C0F5C225C385C715DDD5DE55DF15DF25DF35DFE5E725EFE5F0B5F13624D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E114E104E0D4E2D4E304E394E4B5C394E884E914E954E924E944EA24EC1
4EC04EC34EC64EC74ECD4ECA4ECB4EC4514351415167516D516E516C519751F6
52065207520852FB52FE52FF53165339534853475345535E538453CB53CA53CD
58EC5929592B592A592D5B545C115C245C3A5C6F5DF45E7B5EFF5F145F155FC3
62086236624B624E652F6587659765A465B965E566F0670867286B206B626B79
6BCB6BD46BDB6C0F6C34706B722A7236723B72477259725B72AC738B4E190000
A5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E164E154E144E184E3B4E4D4E4F4E4E4EE54ED84ED44ED54ED64ED74EE34EE4
4ED94EDE514551445189518A51AC51F951FA51F8520A52A0529F530553065317
531D4EDF534A534953615360536F536E53BB53EF53E453F353EC53EE53E953E8
53FC53F853F553EB53E653EA53F253F153F053E553ED53FB56DB56DA59160000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000592E5931597459765B555B835C3C5DE85DE75DE65E025E035E735E7C5F01
5F185F175FC5620A625362546252625165A565E6672E672C672A672B672D6B63
6BCD6C116C106C386C416C406C3E72AF7384738974DC74E67518751F75287529
7530753175327533758B767D76AE76BF76EE77DB77E277F3793A79BE7A747ACB
4E1E4E1F4E524E534E694E994EA44EA64EA54EFF4F094F194F0A4F154F0D4F10
4F114F0F4EF24EF64EFB4EF04EF34EFD4F014F0B514951475146514851680000
A6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5171518D51B0521752115212520E521652A3530853215320537053715409540F
540C540A54105401540B54045411540D54085403540E5406541256E056DE56DD
573357305728572D572C572F57295919591A59375938598459785983597D5979
598259815B575B585B875B885B855B895BFA5C165C795DDE5E065E765E740000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F0F5F1B5FD95FD6620E620C620D62106263625B6258653665E965E865EC
65ED66F266F36709673D6734673167356B216B646B7B6C166C5D6C576C596C5F
6C606C506C556C616C5B6C4D6C4E7070725F725D767E7AF97C737CF87F367F8A
7FBD80018003800C80128033807F8089808B808C81E381EA81F381FC820C821B
821F826E8272827E866B8840884C8863897F96214E324EA84F4D4F4F4F474F57
4F5E4F344F5B4F554F304F504F514F3D4F3A4F384F434F544F3C4F464F630000
A7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4F5C4F604F2F4F4E4F364F594F5D4F484F5A514C514B514D517551B651B75225
52245229522A522852AB52A952AA52AC532353735375541D542D541E543E5426
544E542754465443543354485442541B5429544A5439543B5438542E54355436
5420543C54405431542B541F542C56EA56F056E456EB574A57515740574D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005747574E573E5750574F573B58EF593E599D599259A8599E59A359995996
598D59A45993598A59A55B5D5B5C5B5A5B5B5B8C5B8B5B8F5C2C5C405C415C3F
5C3E5C905C915C945C8C5DEB5E0C5E8F5E875E8A5EF75F045F1F5F645F625F77
5F795FD85FCC5FD75FCD5FF15FEB5FF85FEA6212621162846297629662806276
6289626D628A627C627E627962736292626F6298626E62956293629162866539
653B653865F166F4675F674E674F67506751675C6756675E6749674667600000
A8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
675367576B656BCF6C426C5E6C996C816C886C896C856C9B6C6A6C7A6C906C70
6C8C6C686C966C926C7D6C836C726C7E6C746C866C766C8D6C946C986C827076
707C707D707872627261726072C472C27396752C752B75377538768276EF77E3
79C179C079BF7A767CFB7F5580968093809D8098809B809A80B2826F82920000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000828B828D898B89D28A008C378C468C558C9D8D648D708DB38EAB8ECA8F9B
8FB08FC28FC68FC58FC45DE1909190A290AA90A690A3914991C691CC9632962E
9631962A962C4E264E564E734E8B4E9B4E9E4EAB4EAC4F6F4F9D4F8D4F734F7F
4F6C4F9B4F8B4F864F834F704F754F884F694F7B4F964F7E4F8F4F914F7A5154
51525155516951775176517851BD51FD523B52385237523A5230522E52365241
52BE52BB5352535453535351536653775378537953D653D453D7547354750000
A9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5496547854955480547B5477548454925486547C549054715476548C549A5462
5468548B547D548E56FA57835777576A5769576157665764577C591C59495947
59485944595459BE59BB59D459B959AE59D159C659D059CD59CB59D359CA59AF
59B359D259C55B5F5B645B635B975B9A5B985B9C5B995B9B5C1A5C485C450000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005C465CB75CA15CB85CA95CAB5CB15CB35E185E1A5E165E155E1B5E115E78
5E9A5E975E9C5E955E965EF65F265F275F295F805F815F7F5F7C5FDD5FE05FFD
5FF55FFF600F6014602F60356016602A6015602160276029602B601B62166215
623F623E6240627F62C962CC62C462BF62C262B962D262DB62AB62D362D462CB
62C862A862BD62BC62D062D962C762CD62B562DA62B162D862D662D762C662AC
62CE653E65A765BC65FA66146613660C66066602660E6600660F6615660A0000
AA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6607670D670B676D678B67956771679C677367776787679D6797676F6770677F
6789677E67906775679A6793677C676A67726B236B666B676B7F6C136C1B6CE3
6CE86CF36CB16CCC6CE56CB36CBD6CBE6CBC6CE26CAB6CD56CD36CB86CC46CB9
6CC16CAE6CD76CC56CF16CBF6CBB6CE16CDB6CCA6CAC6CEF6CDC6CD66CE00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007095708E7092708A7099722C722D723872487267726972C072CE72D972D7
72D073A973A8739F73AB73A5753D759D7599759A768476C276F276F477E577FD
793E7940794179C979C87A7A7A797AFA7CFE7F547F8C7F8B800580BA80A580A2
80B180A180AB80A980B480AA80AF81E581FE820D82B3829D829982AD82BD829F
82B982B182AC82A582AF82B882A382B082BE82B7864E8671521D88688ECB8FCE
8FD48FD190B590B890B190B691C791D195779580961C9640963F963B96440000
AB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
964296B996E89752975E4E9F4EAD4EAE4FE14FB54FAF4FBF4FE04FD14FCF4FDD
4FC34FB64FD84FDF4FCA4FD74FAE4FD04FC44FC24FDA4FCE4FDE4FB751575192
519151A0524E5243524A524D524C524B524752C752C952C352C1530D5357537B
539A53DB54AC54C054A854CE54C954B854A654B354C754C254BD54AA54C10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054C454C854AF54AB54B154BB54A954A754BF56FF5782578B57A057A357A2
57CE57AE579359555951594F594E595059DC59D859FF59E359E85A0359E559EA
59DA59E65A0159FB5B695BA35BA65BA45BA25BA55C015C4E5C4F5C4D5C4B5CD9
5CD25DF75E1D5E255E1F5E7D5EA05EA65EFA5F085F2D5F655F885F855F8A5F8B
5F875F8C5F896012601D60206025600E6028604D60706068606260466043606C
606B606A6064624162DC6316630962FC62ED630162EE62FD630762F162F70000
AC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
62EF62EC62FE62F463116302653F654565AB65BD65E26625662D66206627662F
661F66286631662466F767FF67D367F167D467D067EC67B667AF67F567E967EF
67C467D167B467DA67E567B867CF67DE67F367B067D967E267DD67D26B6A6B83
6B866BB56BD26BD76C1F6CC96D0B6D326D2A6D416D256D0C6D316D1E6D170000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D3B6D3D6D3E6D366D1B6CF56D396D276D386D296D2E6D356D0E6D2B70AB
70BA70B370AC70AF70AD70B870AE70A472307272726F727472E972E072E173B7
73CA73BB73B273CD73C073B3751A752D754F754C754E754B75AB75A475A575A2
75A3767876867687768876C876C676C376C5770176F976F87709770B76FE76FC
770777DC78027814780C780D794679497948794779B979BA79D179D279CB7A7F
7A817AFF7AFD7C7D7D027D057D007D097D077D047D067F387F8E7FBF80040000
AD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8010800D8011803680D680E580DA80C380C480CC80E180DB80CE80DE80E480DD
81F4822282E78303830582E382DB82E6830482E58302830982D282D782F18301
82DC82D482D182DE82D382DF82EF830686508679867B867A884D886B898189D4
8A088A028A038C9E8CA08D748D738DB48ECD8ECC8FF08FE68FE28FEA8FE50000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008FED8FEB8FE48FE890CA90CE90C190C3914B914A91CD95829650964B964C
964D9762976997CB97ED97F3980198A898DB98DF999699994E584EB3500C500D
50234FEF502650254FF8502950165006503C501F501A501250114FFA50005014
50284FF15021500B501950184FF34FEE502D502A4FFE502B5009517C51A451A5
51A251CD51CC51C651CB5256525C5254525B525D532A537F539F539D53DF54E8
55105501553754FC54E554F2550654FA551454E954ED54E1550954EE54EA0000
AE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54E65527550754FD550F5703570457C257D457CB57C35809590F59575958595A
5A115A185A1C5A1F5A1B5A1359EC5A205A235A295A255A0C5A095B6B5C585BB0
5BB35BB65BB45BAE5BB55BB95BB85C045C515C555C505CED5CFD5CFB5CEA5CE8
5CF05CF65D015CF45DEE5E2D5E2B5EAB5EAD5EA75F315F925F915F9060590000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006063606560506055606D6069606F6084609F609A608D6094608C60856096
624762F3630862FF634E633E632F635563426346634F6349633A6350633D632A
632B6328634D634C65486549659965C165C566426649664F66436652664C6645
664166F867146715671768216838684868466853683968426854682968B36817
684C6851683D67F468506840683C6843682A68456813681868416B8A6B896BB7
6C236C276C286C266C246CF06D6A6D956D886D876D666D786D776D596D930000
AF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6D6C6D896D6E6D5A6D746D696D8C6D8A6D796D856D656D9470CA70D870E470D9
70C870CF7239727972FC72F972FD72F872F7738673ED740973EE73E073EA73DE
7554755D755C755A755975BE75C575C775B275B375BD75BC75B975C275B8768B
76B076CA76CD76CE7729771F7720772877E9783078277838781D783478370000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007825782D7820781F7832795579507960795F7956795E795D7957795A79E4
79E379E779DF79E679E979D87A847A887AD97B067B117C897D217D177D0B7D0A
7D207D227D147D107D157D1A7D1C7D0D7D197D1B7F3A7F5F7F947FC57FC18006
8018801580198017803D803F80F1810280F0810580ED80F4810680F880F38108
80FD810A80FC80EF81ED81EC82008210822A822B8228822C82BB832B83528354
834A83388350834983358334834F833283398336831783408331832883430000
B0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8654868A86AA869386A486A9868C86A3869C8870887788818882887D88798A18
8A108A0E8A0C8A158A0A8A178A138A168A0F8A118C488C7A8C798CA18CA28D77
8EAC8ED28ED48ECF8FB1900190068FF790008FFA8FF490038FFD90058FF89095
90E190DD90E29152914D914C91D891DD91D791DC91D995839662966396610000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000965B965D96649658965E96BB98E299AC9AA89AD89B259B329B3C4E7E507A
507D505C50475043504C505A504950655076504E5055507550745077504F500F
506F506D515C519551F0526A526F52D252D952D852D55310530F5319533F5340
533E53C366FC5546556A55665544555E55615543554A55315556554F5555552F
55645538552E555C552C55635533554155575708570B570957DF5805580A5806
57E057E457FA5802583557F757F9592059625A365A415A495A665A6A5A400000
B1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5A3C5A625A5A5A465A4A5B705BC75BC55BC45BC25BBF5BC65C095C085C075C60
5C5C5C5D5D075D065D0E5D1B5D165D225D115D295D145D195D245D275D175DE2
5E385E365E335E375EB75EB85EB65EB55EBE5F355F375F575F6C5F695F6B5F97
5F995F9E5F985FA15FA05F9C607F60A3608960A060A860CB60B460E660BD0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000060C560BB60B560DC60BC60D860D560C660DF60B860DA60C7621A621B6248
63A063A76372639663A263A563776367639863AA637163A963896383639B636B
63A863846388639963A163AC6392638F6380637B63696368637A655D65566551
65596557555F654F655865556554659C659B65AC65CF65CB65CC65CE665D665A
666466686666665E66F952D7671B688168AF68A2689368B5687F687668B168A7
689768B0688368C468AD688668856894689D68A8689F68A168826B326BBA0000
B2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6BEB6BEC6C2B6D8E6DBC6DF36DD96DB26DE16DCC6DE46DFB6DFA6E056DC76DCB
6DAF6DD16DAE6DDE6DF96DB86DF76DF56DC56DD26E1A6DB56DDA6DEB6DD86DEA
6DF16DEE6DE86DC66DC46DAA6DEC6DBF6DE670F97109710A70FD70EF723D727D
7281731C731B73167313731973877405740A7403740673FE740D74E074F60000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000074F7751C75227565756675627570758F75D475D575B575CA75CD768E76D4
76D276DB7737773E773C77367738773A786B7843784E79657968796D79FB7A92
7A957B207B287B1B7B2C7B267B197B1E7B2E7C927C977C957D467D437D717D2E
7D397D3C7D407D307D337D447D2F7D427D327D317F3D7F9E7F9A7FCC7FCE7FD2
801C804A8046812F81168123812B81298130812482028235823782368239838E
839E8398837883A2839683BD83AB8392838A8393838983A08377837B837C0000
B3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
838683A786555F6A86C786C086B686C486B586C686CB86B186AF86C98853889E
888888AB88928896888D888B8993898F8A2A8A1D8A238A258A318A2D8A1F8A1B
8A228C498C5A8CA98CAC8CAB8CA88CAA8CA78D678D668DBE8DBA8EDB8EDF9019
900D901A90179023901F901D90109015901E9020900F90229016901B90140000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000090E890ED90FD915791CE91F591E691E391E791ED91E99589966A96759673
96789670967496769677966C96C096EA96E97AE07ADF980298039B5A9CE59E75
9E7F9EA59EBB50A2508D508550995091508050965098509A670051F152725274
5275526952DE52DD52DB535A53A5557B558055A7557C558A559D55985582559C
55AA55945587558B558355B355AE559F553E55B2559A55BB55AC55B1557E5589
55AB5599570D582F582A58345824583058315821581D582058F958FA59600000
B4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5A775A9A5A7F5A925A9B5AA75B735B715BD25BCC5BD35BD05C0A5C0B5C315D4C
5D505D345D475DFD5E455E3D5E405E435E7E5ECA5EC15EC25EC45F3C5F6D5FA9
5FAA5FA860D160E160B260B660E0611C612360FA611560F060FB60F4616860F1
610E60F6610961006112621F624963A3638C63CF63C063E963C963C663CD0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000063D263E363D063E163D663ED63EE637663F463EA63DB645263DA63F9655E
6566656265636591659065AF666E667066746676666F6691667A667E667766FE
66FF671F671D68FA68D568E068D868D7690568DF68F568EE68E768F968D268F2
68E368CB68CD690D6912690E68C968DA696E68FB6B3E6B3A6B3D6B986B966BBC
6BEF6C2E6C2F6C2C6E2F6E386E546E216E326E676E4A6E206E256E236E1B6E5B
6E586E246E566E6E6E2D6E266E6F6E346E4D6E3A6E2C6E436E1D6E3E6ECB0000
B5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6E896E196E4E6E636E446E726E696E5F7119711A7126713071217136716E711C
724C728472807336732573347329743A742A743374227425743574367434742F
741B7426742875257526756B756A75E275DB75E375D975D875DE75E0767B767C
7696769376B476DC774F77ED785D786C786F7A0D7A087A0B7A057A007A980000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A977A967AE57AE37B497B567B467B507B527B547B4D7B4B7B4F7B517C9F
7CA57D5E7D507D687D557D2B7D6E7D727D617D667D627D707D7355847FD47FD5
800B8052808581558154814B8151814E81398146813E814C815381748212821C
83E9840383F8840D83E083C5840B83C183EF83F183F48457840A83F0840C83CC
83FD83F283CA8438840E840483DC840783D483DF865B86DF86D986ED86D486DB
86E486D086DE885788C188C288B1898389968A3B8A608A558A5E8A3C8A410000
B6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8A548A5B8A508A468A348A3A8A368A568C618C828CAF8CBC8CB38CBD8CC18CBB
8CC08CB48CB78CB68CBF8CB88D8A8D858D818DCE8DDD8DCB8DDA8DD18DCC8DDB
8DC68EFB8EF88EFC8F9C902E90359031903890329036910290F5910990FE9163
916591CF9214921592239209921E920D9210920792119594958F958B95910000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000095939592958E968A968E968B967D96859686968D9672968496C196C596C4
96C696C796EF96F297CC98059806980898E798EA98EF98E998F298ED99AE99AD
9EC39ECD9ED14E8250AD50B550B250B350C550BE50AC50B750BB50AF50C7527F
5277527D52DF52E652E452E252E3532F55DF55E855D355E655CE55DC55C755D1
55E355E455EF55DA55E155C555C655E555C957125713585E585158585857585A
5854586B584C586D584A58625852584B59675AC15AC95ACC5ABE5ABD5ABC0000
B7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5AB35AC25AB25D695D6F5E4C5E795EC95EC85F125F595FAC5FAE611A610F6148
611F60F3611B60F961016108614E614C6144614D613E61346127610D61066137
622162226413643E641E642A642D643D642C640F641C6414640D643664166417
6406656C659F65B06697668966876688669666846698668D67036994696D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000695A697769606954697569306982694A6968696B695E695369796986695D
6963695B6B476B726BC06BBF6BD36BFD6EA26EAF6ED36EB66EC26E906E9D6EC7
6EC56EA56E986EBC6EBA6EAB6ED16E966E9C6EC46ED46EAA6EA76EB4714E7159
7169716471497167715C716C7166714C7165715E714671687156723A72527337
7345733F733E746F745A7455745F745E7441743F7459745B745C757675787600
75F0760175F275F175FA75FF75F475F376DE76DF775B776B7766775E77630000
B8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7779776A776C775C77657768776277EE788E78B078977898788C7889787C7891
7893787F797A797F7981842C79BD7A1C7A1A7A207A147A1F7A1E7A9F7AA07B77
7BC07B607B6E7B677CB17CB37CB57D937D797D917D817D8F7D5B7F6E7F697F6A
7F727FA97FA87FA480568058808680848171817081788165816E8173816B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008179817A81668205824784828477843D843184758466846B8449846C845B
843C8435846184638469846D8446865E865C865F86F9871387088707870086FE
86FB870287038706870A885988DF88D488D988DC88D888DD88E188CA88D588D2
899C89E38A6B8A728A738A668A698A708A878A7C8A638AA08A718A858A6D8A62
8A6E8A6C8A798A7B8A3E8A688C628C8A8C898CCA8CC78CC88CC48CB28CC38CC2
8CC58DE18DDF8DE88DEF8DF38DFA8DEA8DE48DE68EB28F038F098EFE8F0A0000
B9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8F9F8FB2904B904A905390429054903C905590509047904F904E904D9051903E
904191129117916C916A916991C9923792579238923D9240923E925B924B9264
925192349249924D92459239923F925A959896989694969596CD96CB96C996CA
96F796FB96F996F6975697749776981098119813980A9812980C98FC98F40000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000098FD98FE99B399B199B49AE19CE99E829F0E9F139F2050E750EE50E550D6
50ED50DA50D550CF50D150F150CE50E9516251F352835282533153AD55FE5600
561B561755FD561456065609560D560E55F75616561F5608561055F657185716
5875587E58835893588A58795885587D58FD592559225924596A59695AE15AE6
5AE95AD75AD65AD85AE35B755BDE5BE75BE15BE55BE65BE85BE25BE45BDF5C0D
5C625D845D875E5B5E635E555E575E545ED35ED65F0A5F465F705FB961470000
BA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
613F614B617761626163615F615A61586175622A64876458645464A46478645F
647A645164676434646D647B657265A165D765D666A266A8669D699C69A86995
69C169AE69D369CB699B69B769BB69AB69B469D069CD69AD69CC69A669C369A3
6B496B4C6C336F336F146EFE6F136EF46F296F3E6F206F2C6F0F6F026F220000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006EFF6EEF6F066F316F386F326F236F156F2B6F2F6F886F2A6EEC6F016EF2
6ECC6EF771947199717D718A71847192723E729272967344735074647463746A
7470746D750475917627760D760B7609761376E176E37784777D777F776178C1
789F78A778B378A978A3798E798F798D7A2E7A317AAA7AA97AED7AEF7BA17B95
7B8B7B757B977B9D7B947B8F7BB87B877B847CB97CBD7CBE7DBB7DB07D9C7DBD
7DBE7DA07DCA7DB47DB27DB17DBA7DA27DBF7DB57DB87DAD7DD27DC77DAC0000
BB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7F707FE07FE17FDF805E805A808781508180818F8188818A817F818281E781FA
82078214821E824B84C984BF84C684C48499849E84B2849C84CB84B884C084D3
849084BC84D184CA873F871C873B872287258734871887558737872988F38902
88F488F988F888FD88E8891A88EF8AA68A8C8A9E8AA38A8D8AA18A938AA40000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008AAA8AA58AA88A988A918A9A8AA78C6A8C8D8C8C8CD38CD18CD28D6B8D99
8D958DFC8F148F128F158F138FA390609058905C90639059905E9062905D905B
91199118911E917591789177917492789280928592989296927B9293929C92A8
927C929195A195A895A995A395A595A49699969C969B96CC96D29700977C9785
97F69817981898AF98B199039905990C990999C19AAF9AB09AE69B419B429CF4
9CF69CF39EBC9F3B9F4A5104510050FB50F550F9510251085109510551DC0000
BC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
528752885289528D528A52F053B2562E563B56395632563F563456295653564E
565756745636562F56305880589F589E58B3589C58AE58A958A6596D5B095AFB
5B0B5AF55B0C5B085BEE5BEC5BE95BEB5C645C655D9D5D945E625E5F5E615EE2
5EDA5EDF5EDD5EE35EE05F485F715FB75FB561766167616E615D615561820000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000617C6170616B617E61A7619061AB618E61AC619A61A4619461AE622E6469
646F6479649E64B26488649064B064A56493649564A9649264AE64AD64AB649A
64AC649964A264B365756577657866AE66AB66B466B16A236A1F69E86A016A1E
6A1969FD6A216A136A0A69F36A026A0569ED6A116B506B4E6BA46BC56BC66F3F
6F7C6F846F516F666F546F866F6D6F5B6F786F6E6F8E6F7A6F706F646F976F58
6ED56F6F6F606F5F719F71AC71B171A87256729B734E73577469748B74830000
BD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
747E7480757F76207629761F7624762676217622769A76BA76E4778E7787778C
7791778B78CB78C578BA78CA78BE78D578BC78D07A3F7A3C7A407A3D7A377A3B
7AAF7AAE7BAD7BB17BC47BB47BC67BC77BC17BA07BCC7CCA7DE07DF47DEF7DFB
7DD87DEC7DDD7DE87DE37DDA7DDE7DE97D9E7DD97DF27DF97F757F777FAF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007FE98026819B819C819D81A0819A81988517853D851A84EE852C852D8513
851185238521851484EC852584FF850687828774877687608766877887688759
8757874C8753885B885D89108907891289138915890A8ABC8AD28AC78AC48A95
8ACB8AF88AB28AC98AC28ABF8AB08AD68ACD8AB68AB98ADB8C4C8C4E8C6C8CE0
8CDE8CE68CE48CEC8CED8CE28CE38CDC8CEA8CE18D6D8D9F8DA38E2B8E108E1D
8E228E0F8E298E1F8E218E1E8EBA8F1D8F1B8F1F8F298F268F2A8F1C8F1E0000
BE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8F259069906E9068906D90779130912D9127913191879189918B918392C592BB
92B792EA92AC92E492C192B392BC92D292C792F092B295AD95B1970497069707
97099760978D978B978F9821982B981C98B3990A99139912991899DD99D099DF
99DB99D199D599D299D99AB79AEE9AEF9B279B459B449B779B6F9D069D090000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009D039EA99EBE9ECE58A89F5251125118511451105115518051AA51DD5291
529352F35659566B5679566956645678566A566856655671566F566C56625676
58C158BE58C758C5596E5B1D5B345B785BF05C0E5F4A61B2619161A9618A61CD
61B661BE61CA61C8623064C564C164CB64BB64BC64DA64C464C764C264CD64BF
64D264D464BE657466C666C966B966C466C766B86A3D6A386A3A6A596A6B6A58
6A396A446A626A616A4B6A476A356A5F6A486B596B776C056FC26FB16FA10000
BF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6FC36FA46FC16FA76FB36FC06FB96FB66FA66FA06FB471BE71C971D071D271C8
71D571B971CE71D971DC71C371C47368749C74A37498749F749E74E2750C750D
76347638763A76E776E577A0779E779F77A578E878DA78EC78E779A67A4D7A4E
7A467A4C7A4B7ABA7BD97C117BC97BE47BDB7BE17BE97BE67CD57CD67E0A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007E117E087E1B7E237E1E7E1D7E097E107F797FB27FF07FF17FEE802881B3
81A981A881FB820882588259854A855985488568856985438549856D856A855E
8783879F879E87A2878D8861892A89328925892B892189AA89A68AE68AFA8AEB
8AF18B008ADC8AE78AEE8AFE8B018B028AF78AED8AF38AF68AFC8C6B8C6D8C93
8CF48E448E318E348E428E398E358F3B8F2F8F388F338FA88FA6907590749078
9072907C907A913491929320933692F89333932F932292FC932B9304931A0000
C0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9310932693219315932E931995BB96A796A896AA96D5970E97119716970D9713
970F975B975C9766979898309838983B9837982D9839982499109928991E991B
9921991A99ED99E299F19AB89ABC9AFB9AED9B289B919D159D239D269D289D12
9D1B9ED89ED49F8D9F9C512A511F5121513252F5568E56805690568556870000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000568F58D558D358D158CE5B305B2A5B245B7A5C375C685DBC5DBA5DBD5DB8
5E6B5F4C5FBD61C961C261C761E661CB6232623464CE64CA64D864E064F064E6
64EC64F164E264ED6582658366D966D66A806A946A846AA26A9C6ADB6AA36A7E
6A976A906AA06B5C6BAE6BDA6C086FD86FF16FDF6FE06FDB6FE46FEB6FEF6F80
6FEC6FE16FE96FD56FEE6FF071E771DF71EE71E671E571ED71EC71F471E07235
72467370737274A974B074A674A876467642764C76EA77B377AA77B077AC0000
C1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
77A777AD77EF78F778FA78F478EF790179A779AA7A577ABF7C077C0D7BFE7BF7
7C0C7BE07CE07CDC7CDE7CE27CDF7CD97CDD7E2E7E3E7E467E377E327E437E2B
7E3D7E317E457E417E347E397E487E357E3F7E2F7F447FF37FFC807180728070
806F807381C681C381BA81C281C081BF81BD81C981BE81E88209827185AA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008584857E859C8591859485AF859B858785A8858A866787C087D187B387D2
87C687AB87BB87BA87C887CB893B893689448938893D89AC8B0E8B178B198B1B
8B0A8B208B1D8B048B108C418C3F8C738CFA8CFD8CFC8CF88CFB8DA88E498E4B
8E488E4A8F448F3E8F428F458F3F907F907D9084908190829080913991A3919E
919C934D938293289375934A9365934B9318937E936C935B9370935A935495CA
95CB95CC95C895C696B196B896D6971C971E97A097D3984698B699359A010000
C2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
99FF9BAE9BAB9BAA9BAD9D3B9D3F9E8B9ECF9EDE9EDC9EDD9EDB9F3E9F4B53E2
569556AE58D958D85B385F5D61E3623364F464F264FE650664FA64FB64F765B7
66DC67266AB36AAC6AC36ABB6AB86AC26AAE6AAF6B5F6B786BAF7009700B6FFE
70066FFA7011700F71FB71FC71FE71F87377737574A774BF7515765676580000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000765277BD77BF77BB77BC790E79AE7A617A627A607AC47AC57C2B7C277C2A
7C1E7C237C217CE77E547E557E5E7E5A7E617E527E597F487FF97FFB80778076
81CD81CF820A85CF85A985CD85D085C985B085BA85B985A687EF87EC87F287E0
898689B289F48B288B398B2C8B2B8C508D058E598E638E668E648E5F8E558EC0
8F498F4D90879083908891AB91AC91D09394938A939693A293B393AE93AC93B0
9398939A939795D495D695D095D596E296DC96D996DB96DE972497A397A60000
C3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
97AD97F9984D984F984C984E985398BA993E993F993D992E99A59A0E9AC19B03
9B069B4F9B4E9B4D9BCA9BC99BFD9BC89BC09D519D5D9D609EE09F159F2C5133
56A558DE58DF58E25BF59F905EEC61F261F761F661F56500650F66E066DD6AE5
6ADD6ADA6AD3701B701F7028701A701D701570187206720D725872A273780000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000737A74BD74CA74E375877586765F766177C7791979B17A6B7A697C3E7C3F
7C387C3D7C377C407E6B7E6D7E797E697E6A7F857E737FB67FB97FB881D885E9
85DD85EA85D585E485E585F787FB8805880D87F987FE8960895F8956895E8B41
8B5C8B588B498B5A8B4E8B4F8B468B598D088D0A8E7C8E728E878E768E6C8E7A
8E748F548F4E8FAD908A908B91B191AE93E193D193DF93C393C893DC93DD93D6
93E293CD93D893E493D793E895DC96B496E3972A9727976197DC97FB985E0000
C4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9858985B98BC994599499A169A199B0D9BE89BE79BD69BDB9D899D619D729D6A
9D6C9E929E979E939EB452F856A856B756B656B456BC58E45B405B435B7D5BF6
5DC961F861FA65186514651966E667276AEC703E703070327210737B74CF7662
76657926792A792C792B7AC77AF67C4C7C437C4D7CEF7CF08FAE7E7D7E7C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007E827F4C800081DA826685FB85F9861185FA8606860B8607860A88148815
896489BA89F88B708B6C8B668B6F8B5F8B6B8D0F8D0D8E898E818E858E8291B4
91CB9418940393FD95E1973098C49952995199A89A2B9A309A379A359C139C0D
9E799EB59EE89F2F9F5F9F639F615137513856C156C056C259145C6C5DCD61FC
61FE651D651C659566E96AFB6B046AFA6BB2704C721B72A774D674D4766977D3
7C507E8F7E8C7FBC8617862D861A882388228821881F896A896C89BD8B740000
C5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8B778B7D8D138E8A8E8D8E8B8F5F8FAF91BA942E94339435943A94389432942B
95E297389739973297FF9867986599579A459A439A409A3E9ACF9B549B519C2D
9C259DAF9DB49DC29DB89E9D9EEF9F199F5C9F669F67513C513B56C856CA56C9
5B7F5DD45DD25F4E61FF65246B0A6B6170517058738074E4758A766E766C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000079B37C607C5F807E807D81DF8972896F89FC8B808D168D178E918E938F61
9148944494519452973D973E97C397C1986B99559A559A4D9AD29B1A9C499C31
9C3E9C3B9DD39DD79F349F6C9F6A9F9456CC5DD662006523652B652A66EC6B10
74DA7ACA7C647C637C657E937E967E9481E28638863F88318B8A9090908F9463
946094649768986F995C9A5A9A5B9A579AD39AD49AD19C549C579C569DE59E9F
9EF456D158E9652C705E7671767277D77F507F888836883988628B938B920000
C6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8B9682778D1B91C0946A97429748974497C698709A5F9B229B589C5F9DF99DFA
9E7C9E7D9F079F779F725EF36B1670637C6C7C6E883B89C08EA191C194729470
9871995E9AD69B239ECC706477DA8B9A947797C99A629A657E9C8B9C8EAA91C5
947D947E947C9C779C789EF78C54947F9E1A72289A6A9B319E1B9E1E7C720000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
C9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E424E5C51F5531A53824E074E0C4E474E8D56D7FA0C5C6E5F734E0F51874E0E
4E2E4E934EC24EC94EC8519852FC536C53B957205903592C5C105DFF65E16BB3
6BCC6C14723F4E314E3C4EE84EDC4EE94EE14EDD4EDA520C531C534C57225723
5917592F5B815B845C125C3B5C745C735E045E805E825FC9620962506C150000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006C366C436C3F6C3B72AE72B0738A79B8808A961E4F0E4F184F2C4EF54F14
4EF14F004EF74F084F1D4F024F054F224F134F044EF44F1251B1521352095210
52A65322531F534D538A540756E156DF572E572A5734593C5980597C5985597B
597E5977597F5B565C155C255C7C5C7A5C7B5C7E5DDF5E755E845F025F1A5F74
5FD55FD45FCF625C625E626462616266626262596260625A626565EF65EE673E
67396738673B673A673F673C67336C186C466C526C5C6C4F6C4A6C546C4B0000
CA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6C4C7071725E72B472B5738E752A767F7A757F518278827C8280827D827F864D
897E909990979098909B909496229624962096234F564F3B4F624F494F534F64
4F3E4F674F524F5F4F414F584F2D4F334F3F4F61518F51B9521C521E522152AD
52AE530953635372538E538F54305437542A545454455419541C542554180000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000543D544F544154285424544756EE56E756E557415745574C5749574B5752
5906594059A6599859A05997598E59A25990598F59A759A15B8E5B925C285C2A
5C8D5C8F5C885C8B5C895C925C8A5C865C935C955DE05E0A5E0E5E8B5E895E8C
5E885E8D5F055F1D5F785F765FD25FD15FD05FED5FE85FEE5FF35FE15FE45FE3
5FFA5FEF5FF75FFB60005FF4623A6283628C628E628F629462876271627B627A
6270628162886277627D62726274653765F065F465F365F265F5674567470000
CB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
67596755674C6748675D674D675A674B6BD06C196C1A6C786C676C6B6C846C8B
6C8F6C716C6F6C696C9A6C6D6C876C956C9C6C666C736C656C7B6C8E7074707A
726372BF72BD72C372C672C172BA72C573957397739373947392753A75397594
75957681793D80348095809980908092809C8290828F8285828E829182930000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000828A828382848C788FC98FBF909F90A190A5909E90A790A096309628962F
962D4E334F984F7C4F854F7D4F804F874F764F744F894F844F774F4C4F974F6A
4F9A4F794F814F784F904F9C4F944F9E4F924F824F954F6B4F6E519E51BC51BE
5235523252335246523152BC530A530B533C539253945487547F548154915482
5488546B547A547E5465546C54745466548D546F546154605498546354675464
56F756F9576F5772576D576B57715770577657805775577B5773577457620000
CC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5768577D590C594559B559BA59CF59CE59B259CC59C159B659BC59C359D659B1
59BD59C059C859B459C75B625B655B935B955C445C475CAE5CA45CA05CB55CAF
5CA85CAC5C9F5CA35CAD5CA25CAA5CA75C9D5CA55CB65CB05CA65E175E145E19
5F285F225F235F245F545F825F7E5F7D5FDE5FE5602D602660196032600B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006034600A60176033601A601E602C6022600D6010602E60136011600C6009
601C6214623D62AD62B462D162BE62AA62B662CA62AE62B362AF62BB62A962B0
62B8653D65A865BB660965FC66046612660865FB6603660B660D660565FD6611
661066F6670A6785676C678E67926776677B6798678667846774678D678C677A
679F679167996783677D67816778677967946B256B806B7E6BDE6C1D6C936CEC
6CEB6CEE6CD96CB66CD46CAD6CE76CB76CD06CC26CBA6CC36CC66CED6CF20000
CD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6CD26CDD6CB46C8A6C9D6C806CDE6CC06D306CCD6CC76CB06CF96CCF6CE96CD1
709470987085709370867084709170967082709A7083726A72D672CB72D872C9
72DC72D272D472DA72CC72D173A473A173AD73A673A273A073AC739D74DD74E8
753F7540753E758C759876AF76F376F176F076F577F877FC77F977FB77FA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077F77942793F79C57A787A7B7AFB7C757CFD8035808F80AE80A380B880B5
80AD822082A082C082AB829A8298829B82B582A782AE82BC829E82BA82B482A8
82A182A982C282A482C382B682A28670866F866D866E8C568FD28FCB8FD38FCD
8FD68FD58FD790B290B490AF90B390B09639963D963C963A96434FCD4FC54FD3
4FB24FC94FCB4FC14FD44FDC4FD94FBB4FB34FDB4FC74FD64FBA4FC04FB94FEC
5244524952C052C2533D537C539753965399539854BA54A154AD54A554CF0000
CE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54C3830D54B754AE54D654B654C554C654A0547054BC54A254BE547254DE54B0
57B5579E579F57A4578C5797579D579B57945798578F579957A5579A579558F4
590D595359E159DE59EE5A0059F159DD59FA59FD59FC59F659E459F259F759DB
59E959F359F559E059FE59F459ED5BA85C4C5CD05CD85CCC5CD75CCB5CDB0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005CDE5CDA5CC95CC75CCA5CD65CD35CD45CCF5CC85CC65CCE5CDF5CF85DF9
5E215E225E235E205E245EB05EA45EA25E9B5EA35EA55F075F2E5F565F866037
603960546072605E6045605360476049605B604C60406042605F602460446058
6066606E6242624362CF630D630B62F5630E630362EB62F9630F630C62F862F6
63006313631462FA631562FB62F06541654365AA65BF6636662166326635661C
662666226633662B663A661D66346639662E670F671067C167F267C867BA0000
CF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
67DC67BB67F867D867C067B767C567EB67E467DF67B567CD67B367F767F667EE
67E367C267B967CE67E767F067B267FC67C667ED67CC67AE67E667DB67FA67C9
67CA67C367EA67CB6B286B826B846BB66BD66BD86BE06C206C216D286D346D2D
6D1F6D3C6D3F6D126D0A6CDA6D336D046D196D3A6D1A6D116D006D1D6D420000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D016D186D376D036D0F6D406D076D206D2C6D086D226D096D1070B7709F
70BE70B170B070A170B470B570A972417249724A726C72707273726E72CA72E4
72E872EB72DF72EA72E672E3738573CC73C273C873C573B973B673B573B473EB
73BF73C773BE73C373C673B873CB74EC74EE752E7547754875A775AA767976C4
7708770377047705770A76F776FB76FA77E777E878067811781278057810780F
780E780978037813794A794C794B7945794479D579CD79CF79D679CE7A800000
D0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7A7E7AD17B007B017C7A7C787C797C7F7C807C817D037D087D017F587F917F8D
7FBE8007800E800F8014803780D880C780E080D180C880C280D080C580E380D9
80DC80CA80D580C980CF80D780E680CD81FF8221829482D982FE82F9830782E8
830082D5833A82EB82D682F482EC82E182F282F5830C82FB82F682F082EA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000082E482E082FA82F382ED86778674867C86738841884E8867886A886989D3
8A048A078D728FE38FE18FEE8FE090F190BD90BF90D590C590BE90C790CB90C8
91D491D39654964F96519653964A964E501E50055007501350225030501B4FF5
4FF450335037502C4FF64FF75017501C502050275035502F5031500E515A5194
519351CA51C451C551C851CE5261525A5252525E525F5255526252CD530E539E
552654E25517551254E754F354E4551A54FF5504550854EB5511550554F10000
D1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
550A54FB54F754F854E0550E5503550B5701570257CC583257D557D257BA57C6
57BD57BC57B857B657BF57C757D057B957C1590E594A5A195A165A2D5A2E5A15
5A0F5A175A0A5A1E5A335B6C5BA75BAD5BAC5C035C565C545CEC5CFF5CEE5CF1
5CF75D005CF95E295E285EA85EAE5EAA5EAC5F335F305F67605D605A60670000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000604160A26088608060926081609D60836095609B60976087609C608E6219
624662F263106356632C634463456336634363E46339634B634A633C63296341
6334635863546359632D63476333635A63516338635763406348654A654665C6
65C365C465C2664A665F6647665167126713681F681A684968326833683B684B
684F68166831681C6835682B682D682F684E68446834681D6812681468266828
682E684D683A682568206B2C6B2F6B2D6B316B346B6D80826B886BE66BE40000
D2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6BE86BE36BE26BE76C256D7A6D636D646D766D0D6D616D926D586D626D6D6D6F
6D916D8D6DEF6D7F6D866D5E6D676D606D976D706D7C6D5F6D826D986D2F6D68
6D8B6D7E6D806D846D166D836D7B6D7D6D756D9070DC70D370D170DD70CB7F39
70E270D770D270DE70E070D470CD70C570C670C770DA70CE70E1724272780000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000072777276730072FA72F472FE72F672F372FB730173D373D973E573D673BC
73E773E373E973DC73D273DB73D473DD73DA73D773D873E874DE74DF74F474F5
7521755B755F75B075C175BB75C475C075BF75B675BA768A76C9771D771B7710
771377127723771177157719771A772277277823782C78227835782F7828782E
782B782178297833782A78317954795B794F795C79537952795179EB79EC79E0
79EE79ED79EA79DC79DE79DD7A867A897A857A8B7A8C7A8A7A877AD87B100000
D3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7B047B137B057B0F7B087B0A7B0E7B097B127C847C917C8A7C8C7C887C8D7C85
7D1E7D1D7D117D0E7D187D167D137D1F7D127D0F7D0C7F5C7F617F5E7F607F5D
7F5B7F967F927FC37FC27FC08016803E803980FA80F280F980F5810180FB8100
8201822F82258333832D83448319835183258356833F83418326831C83220000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008342834E831B832A8308833C834D8316832483208337832F832983478345
834C8353831E832C834B832783488653865286A286A88696868D8691869E8687
86978686868B869A868586A5869986A186A786958698868E869D869086948843
8844886D88758876887288808871887F886F8883887E8874887C8A128C478C57
8C7B8CA48CA38D768D788DB58DB78DB68ED18ED38FFE8FF590028FFF8FFB9004
8FFC8FF690D690E090D990DA90E390DF90E590D890DB90D790DC90E491500000
D4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
914E914F91D591E291DA965C965F96BC98E39ADF9B2F4E7F5070506A5061505E
50605053504B505D50725048504D5041505B504A506250155045505F5069506B
5063506450465040506E50735057505151D0526B526D526C526E52D652D3532D
539C55755576553C554D55505534552A55515562553655355530555255450000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000550C55325565554E55395548552D553B5540554B570A570757FB581457E2
57F657DC57F4580057ED57FD580857F8580B57F357CF580757EE57E357F257E5
57EC57E1580E57FC581057E75801580C57F157E957F0580D5804595C5A605A58
5A555A675A5E5A385A355A6D5A505A5F5A655A6C5A535A645A575A435A5D5A52
5A445A5B5A485A8E5A3E5A4D5A395A4C5A705A695A475A515A565A425A5C5B72
5B6E5BC15BC05C595D1E5D0B5D1D5D1A5D205D0C5D285D0D5D265D255D0F0000
D5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5D305D125D235D1F5D2E5E3E5E345EB15EB45EB95EB25EB35F365F385F9B5F96
5F9F608A6090608660BE60B060BA60D360D460CF60E460D960DD60C860B160DB
60B760CA60BF60C360CD60C063326365638A6382637D63BD639E63AD639D6397
63AB638E636F63876390636E63AF6375639C636D63AE637C63A4633B639F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006378638563816391638D6370655365CD66656661665B6659665C66626718
687968876890689C686D686E68AE68AB6956686F68A368AC68A96875687468B2
688F68776892687C686B687268AA68806871687E689B6896688B68A0688968A4
6878687B6891688C688A687D6B366B336B376B386B916B8F6B8D6B8E6B8C6C2A
6DC06DAB6DB46DB36E746DAC6DE96DE26DB76DF66DD46E006DC86DE06DDF6DD6
6DBE6DE56DDC6DDD6DDB6DF46DCA6DBD6DED6DF06DBA6DD56DC26DCF6DC90000
D6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6DD06DF26DD36DFD6DD76DCD6DE36DBB70FA710D70F7711770F4710C70F07104
70F3711070FC70FF71067113710070F870F6710B7102710E727E727B727C727F
731D7317730773117318730A730872FF730F731E738873F673F873F574047401
73FD7407740073FA73FC73FF740C740B73F474087564756375CE75D275CF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075CB75CC75D175D0768F768976D37739772F772D7731773277347733773D
7725773B7735784878527849784D784A784C782678457850796479677969796A
7963796B796179BB79FA79F879F679F77A8F7A947A907B357B477B347B257B30
7B227B247B337B187B2A7B1D7B317B2B7B2D7B2F7B327B387B1A7B237C947C98
7C967CA37D357D3D7D387D367D3A7D457D2C7D297D417D477D3E7D3F7D4A7D3B
7D287F637F957F9C7F9D7F9B7FCA7FCB7FCD7FD07FD17FC77FCF7FC9801F0000
D7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
801E801B804780438048811881258119811B812D811F812C811E812181158127
811D8122821182388233823A823482328274839083A383A8838D837A837383A4
8374838F8381839583998375839483A9837D8383838C839D839B83AA838B837E
83A583AF8388839783B0837F83A6838783AE8376839A8659865686BF86B70000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000086C286C186C586BA86B086C886B986B386B886CC86B486BB86BC86C386BD
86BE88528889889588A888A288AA889A889188A1889F889888A78899889B8897
88A488AC888C8893888E898289D689D989D58A308A278A2C8A1E8C398C3B8C5C
8C5D8C7D8CA58D7D8D7B8D798DBC8DC28DB98DBF8DC18ED88EDE8EDD8EDC8ED7
8EE08EE19024900B9011901C900C902190EF90EA90F090F490F290F390D490EB
90EC90E991569158915A9153915591EC91F491F191F391F891E491F991EA0000
D8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
91EB91F791E891EE957A95869588967C966D966B9671966F96BF976A980498E5
9997509B50955094509E508B50A35083508C508E509D5068509C509250825087
515F51D45312531153A453A7559155A855A555AD5577564555A255935588558F
55B5558155A3559255A4557D558C55A6557F559555A1558E570C582958370000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005819581E58275823582857F558485825581C581B5833583F5836582E5839
5838582D582C583B59615AAF5A945A9F5A7A5AA25A9E5A785AA65A7C5AA55AAC
5A955AAE5A375A845A8A5A975A835A8B5AA95A7B5A7D5A8C5A9C5A8F5A935A9D
5BEA5BCD5BCB5BD45BD15BCA5BCE5C0C5C305D375D435D6B5D415D4B5D3F5D35
5D515D4E5D555D335D3A5D525D3D5D315D595D425D395D495D385D3C5D325D36
5D405D455E445E415F585FA65FA55FAB60C960B960CC60E260CE60C461140000
D9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
60F2610A6116610560F5611360F860FC60FE60C161036118611D611060FF6104
610B624A639463B163B063CE63E563E863EF63C3649D63F363CA63E063F663D5
63F263F5646163DF63BE63DD63DC63C463D863D363C263C763CC63CB63C863F0
63D763D965326567656A6564655C65686565658C659D659E65AE65D065D20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000667C666C667B668066716679666A66726701690C68D3690468DC692A68EC
68EA68F1690F68D668F768EB68E468F66913691068F368E1690768CC69086970
68B4691168EF68C6691468F868D068FD68FC68E8690B690A691768CE68C868DD
68DE68E668F468D1690668D468E96915692568C76B396B3B6B3F6B3C6B946B97
6B996B956BBD6BF06BF26BF36C306DFC6E466E476E1F6E496E886E3C6E3D6E45
6E626E2B6E3F6E416E5D6E736E1C6E336E4B6E406E516E3B6E036E2E6E5E0000
DA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6E686E5C6E616E316E286E606E716E6B6E396E226E306E536E656E276E786E64
6E776E556E796E526E666E356E366E5A7120711E712F70FB712E713171237125
71227132711F7128713A711B724B725A7288728972867285728B7312730B7330
73227331733373277332732D732673237335730C742E742C7430742B74160000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000741A7421742D743174247423741D74297420743274FB752F756F756C75E7
75DA75E175E675DD75DF75E475D77695769276DA774677477744774D7745774A
774E774B774C77DE77EC786078647865785C786D7871786A786E787078697868
785E786279747973797279707A027A0A7A037A0C7A047A997AE67AE47B4A7B3B
7B447B487B4C7B4E7B407B587B457CA27C9E7CA87CA17D587D6F7D637D537D56
7D677D6A7D4F7D6D7D5C7D6B7D527D547D697D517D5F7D4E7F3E7F3F7F650000
DB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7F667FA27FA07FA17FD78051804F805080FE80D48143814A8152814F8147813D
814D813A81E681EE81F781F881F98204823C823D823F8275833B83CF83F98423
83C083E8841283E783E483FC83F6841083C683C883EB83E383BF840183DD83E5
83D883FF83E183CB83CE83D683F583C98409840F83DE8411840683C283F30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000083D583FA83C783D183EA841383C383EC83EE83C483FB83D783E2841B83DB
83FE86D886E286E686D386E386DA86EA86DD86EB86DC86EC86E986D786E886D1
88488856885588BA88D788B988B888C088BE88B688BC88B788BD88B2890188C9
89958998899789DD89DA89DB8A4E8A4D8A398A598A408A578A588A448A458A52
8A488A518A4A8A4C8A4F8C5F8C818C808CBA8CBE8CB08CB98CB58D848D808D89
8DD88DD38DCD8DC78DD68DDC8DCF8DD58DD98DC88DD78DC58EEF8EF78EFA0000
DC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8EF98EE68EEE8EE58EF58EE78EE88EF68EEB8EF18EEC8EF48EE9902D9034902F
9106912C910490FF90FC910890F990FB9101910091079105910391619164915F
916291609201920A92259203921A9226920F920C9200921291FF91FD92069204
92279202921C92249219921792059216957B958D958C95909687967E96880000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000096899683968096C296C896C396F196F0976C9770976E980798A998EB9CE6
9EF94E834E844EB650BD50BF50C650AE50C450CA50B450C850C250B050C150BA
50B150CB50C950B650B851D7527A5278527B527C55C355DB55CC55D055CB55CA
55DD55C055D455C455E955BF55D2558D55CF55D555E255D655C855F255CD55D9
55C25714585358685864584F584D5849586F5855584E585D58595865585B583D
5863587158FC5AC75AC45ACB5ABA5AB85AB15AB55AB05ABF5AC85ABB5AC60000
DD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5AB75AC05ACA5AB45AB65ACD5AB95A905BD65BD85BD95C1F5C335D715D635D4A
5D655D725D6C5D5E5D685D675D625DF05E4F5E4E5E4A5E4D5E4B5EC55ECC5EC6
5ECB5EC75F405FAF5FAD60F76149614A612B614561366132612E6146612F614F
612961406220916862236225622463C563F163EB641064126409642064240000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000064336443641F641564186439643764226423640C64266430642864416435
642F640A641A644064256427640B63E7641B642E6421640E656F659265D36686
668C66956690668B668A66996694667867206966695F6938694E69626971693F
6945696A6939694269576959697A694869496935696C6933693D696568F06978
693469696940696F69446976695869416974694C693B694B6937695C694F6951
69326952692F697B693C6B466B456B436B426B486B416B9BFA0D6BFB6BFC0000
DE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6BF96BF76BF86E9B6ED66EC86E8F6EC06E9F6E936E946EA06EB16EB96EC66ED2
6EBD6EC16E9E6EC96EB76EB06ECD6EA66ECF6EB26EBE6EC36EDC6ED86E996E92
6E8E6E8D6EA46EA16EBF6EB36ED06ECA6E976EAE6EA371477154715271637160
7141715D716271727178716A7161714271587143714B7170715F715071530000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007144714D715A724F728D728C72917290728E733C7342733B733A7340734A
73497444744A744B7452745174577440744F7450744E74427446744D745474E1
74FF74FE74FD751D75797577698375EF760F760375F775FE75FC75F975F87610
75FB75F675ED75F575FD769976B576DD7755775F776077527756775A77697767
77547759776D77E07887789A7894788F788478957885788678A1788378797899
78807896787B797C7982797D79797A117A187A197A127A177A157A227A130000
DF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7A1B7A107AA37AA27A9E7AEB7B667B647B6D7B747B697B727B657B737B717B70
7B617B787B767B637CB27CB47CAF7D887D867D807D8D7D7F7D857D7A7D8E7D7B
7D837D7C7D8C7D947D847D7D7D927F6D7F6B7F677F687F6C7FA67FA57FA77FDB
7FDC8021816481608177815C8169815B816281726721815E81768167816F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000081448161821D8249824482408242824584F1843F845684768479848F848D
846584518440848684678430844D847D845A845984748473845D8507845E8437
843A8434847A8443847884328445842983D9844B842F8442842D845F84708439
844E844C8452846F84C5848E843B8447843684338468847E8444842B84608454
846E8450870B870486F7870C86FA86D686F5874D86F8870E8709870186F6870D
870588D688CB88CD88CE88DE88DB88DA88CC88D08985899B89DF89E589E40000
E0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
89E189E089E289DC89E68A768A868A7F8A618A3F8A778A828A848A758A838A81
8A748A7A8C3C8C4B8C4A8C658C648C668C868C848C858CCC8D688D698D918D8C
8D8E8D8F8D8D8D938D948D908D928DF08DE08DEC8DF18DEE8DD08DE98DE38DE2
8DE78DF28DEB8DF48F068EFF8F018F008F058F078F088F028F0B9052903F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000090449049903D9110910D910F911191169114910B910E916E916F92489252
9230923A926692339265925E9283922E924A9246926D926C924F92609267926F
92369261927092319254926392509272924E9253924C92569232959F959C959E
959B969296939691969796CE96FA96FD96F896F59773977797789772980F980D
980E98AC98F698F999AF99B299B099B59AAD9AAB9B5B9CEA9CED9CE79E809EFD
50E650D450D750E850F350DB50EA50DD50E450D350EC50F050EF50E350E00000
E1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
51D85280528152E952EB533053AC56275615560C561255FC560F561C56015613
560255FA561D560455FF55F95889587C5890589858865881587F5874588B587A
58875891588E587658825888587B5894588F58FE596B5ADC5AEE5AE55AD55AEA
5ADA5AED5AEB5AF35AE25AE05ADB5AEC5ADE5ADD5AD95AE85ADF5B775BE00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005BE35C635D825D805D7D5D865D7A5D815D775D8A5D895D885D7E5D7C5D8D
5D795D7F5E585E595E535ED85ED15ED75ECE5EDC5ED55ED95ED25ED45F445F43
5F6F5FB6612C61286141615E61716173615261536172616C618061746154617A
615B6165613B616A6161615662296227622B642B644D645B645D647464766472
6473647D6475646664A6644E6482645E645C644B645364606450647F643F646C
646B645964656477657365A066A166A0669F67056704672269B169B669C90000
E2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
69A069CE699669B069AC69BC69916999698E69A7698D69A969BE69AF69BF69C4
69BD69A469D469B969CA699A69CF69B3699369AA69A1699E69D96997699069C2
69B569A569C66B4A6B4D6B4B6B9E6B9F6BA06BC36BC46BFE6ECE6EF56EF16F03
6F256EF86F376EFB6F2E6F096F4E6F196F1A6F276F186F3B6F126EED6F0A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006F366F736EF96EEE6F2D6F406F306F3C6F356EEB6F076F0E6F436F056EFD
6EF66F396F1C6EFC6F3A6F1F6F0D6F1E6F086F21718771907189718071857182
718F717B718671817197724472537297729572937343734D7351734C74627473
7471747574727467746E750075027503757D759076167608760C76157611760A
761476B87781777C77857782776E7780776F777E778378B278AA78B478AD78A8
787E78AB789E78A578A078AC78A278A47998798A798B79967995799479930000
E3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
79977988799279907A2B7A4A7A307A2F7A287A267AA87AAB7AAC7AEE7B887B9C
7B8A7B917B907B967B8D7B8C7B9B7B8E7B857B9852847B997BA47B827CBB7CBF
7CBC7CBA7DA77DB77DC27DA37DAA7DC17DC07DC57D9D7DCE7DC47DC67DCB7DCC
7DAF7DB97D967DBC7D9F7DA67DAE7DA97DA17DC97F737FE27FE37FE57FDE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008024805D805C8189818681838187818D818C818B8215849784A484A1849F
84BA84CE84C284AC84AE84AB84B984B484C184CD84AA849A84B184D0849D84A7
84BB84A2849484C784CC849B84A984AF84A884D6849884B684CF84A084D784D4
84D284DB84B084918661873387238728876B8740872E871E87218719871B8743
872C8741873E874687208732872A872D873C8712873A87318735874287268727
87388724871A8730871188F788E788F188F288FA88FE88EE88FC88F688FB0000
E4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
88F088EC88EB899D89A1899F899E89E989EB89E88AAB8A998A8B8A928A8F8A96
8C3D8C688C698CD58CCF8CD78D968E098E028DFF8E0D8DFD8E0A8E038E078E06
8E058DFE8E008E048F108F118F0E8F0D9123911C91209122911F911D911A9124
9121911B917A91729179917392A592A49276929B927A92A0929492AA928D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000092A6929A92AB92799297927F92A392EE928E9282929592A2927D928892A1
928A9286928C929992A7927E928792A9929D928B922D969E96A196FF9758977D
977A977E978397809782977B97849781977F97CE97CD981698AD98AE99029900
9907999D999C99C399B999BB99BA99C299BD99C79AB19AE39AE79B3E9B3F9B60
9B619B5F9CF19CF29CF59EA750FF5103513050F85106510750F650FE510B510C
50FD510A528B528C52F152EF56485642564C56355641564A5649564656580000
E5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
565A56405633563D562C563E5638562A563A571A58AB589D58B158A058A358AF
58AC58A558A158FF5AFF5AF45AFD5AF75AF65B035AF85B025AF95B015B075B05
5B0F5C675D995D975D9F5D925DA25D935D955DA05D9C5DA15D9A5D9E5E695E5D
5E605E5C7DF35EDB5EDE5EE15F495FB2618B6183617961B161B061A261890000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000619B619361AF61AD619F619261AA61A1618D616661B3622D646E64706496
64A064856497649C648F648B648A648C64A3649F646864B164986576657A6579
657B65B265B366B566B066A966B266B766AA66AF6A006A066A1769E569F86A15
69F169E46A2069FF69EC69E26A1B6A1D69FE6A2769F269EE6A1469F769E76A40
6A0869E669FB6A0D69FC69EB6A096A046A186A256A0F69F66A266A0769F46A16
6B516BA56BA36BA26BA66C016C006BFF6C026F416F266F7E6F876FC66F920000
E6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6F8D6F896F8C6F626F4F6F856F5A6F966F766F6C6F826F556F726F526F506F57
6F946F936F5D6F006F616F6B6F7D6F676F906F536F8B6F696F7F6F956F636F77
6F6A6F7B71B271AF719B71B071A0719A71A971B5719D71A5719E71A471A171AA
719C71A771B37298729A73587352735E735F7360735D735B7361735A73590000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000736274877489748A74867481747D74857488747C747975087507757E7625
761E7619761D761C7623761A7628761B769C769D769E769B778D778F77897788
78CD78BB78CF78CC78D178CE78D478C878C378C478C9799A79A179A0799C79A2
799B6B767A397AB27AB47AB37BB77BCB7BBE7BAC7BCE7BAF7BB97BCA7BB57CC5
7CC87CCC7CCB7DF77DDB7DEA7DE77DD77DE17E037DFA7DE67DF67DF17DF07DEE
7DDF7F767FAC7FB07FAD7FED7FEB7FEA7FEC7FE67FE88064806781A3819F0000
E7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
819E819581A2819981978216824F825382528250824E82518524853B850F8500
8529850E8509850D851F850A8527851C84FB852B84FA8508850C84F4852A84F2
851584F784EB84F384FC851284EA84E9851684FE8528851D852E850284FD851E
84F68531852684E784E884F084EF84F9851885208530850B8519852F86620000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000875687638764877787E1877387588754875B87528761875A8751875E876D
876A8750874E875F875D876F876C877A876E875C8765874F877B877587628767
8769885A8905890C8914890B891789188919890689168911890E890989A289A4
89A389ED89F089EC8ACF8AC68AB88AD38AD18AD48AD58ABB8AD78ABE8AC08AC5
8AD88AC38ABA8ABD8AD98C3E8C4D8C8F8CE58CDF8CD98CE88CDA8CDD8CE78DA0
8D9C8DA18D9B8E208E238E258E248E2E8E158E1B8E168E118E198E268E270000
E8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8E148E128E188E138E1C8E178E1A8F2C8F248F188F1A8F208F238F168F179073
9070906F9067906B912F912B9129912A91329126912E91859186918A91819182
9184918092D092C392C492C092D992B692CF92F192DF92D892E992D792DD92CC
92EF92C292E892CA92C892CE92E692CD92D592C992E092DE92E792D192D30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000092B592E192C692B4957C95AC95AB95AE95B096A496A296D3970597089702
975A978A978E978897D097CF981E981D9826982998289820981B982798B29908
98FA9911991499169917991599DC99CD99CF99D399D499CE99C999D699D899CB
99D799CC9AB39AEC9AEB9AF39AF29AF19B469B439B679B749B719B669B769B75
9B709B689B649B6C9CFC9CFA9CFD9CFF9CF79D079D009CF99CFB9D089D059D04
9E839ED39F0F9F10511C51135117511A511151DE533453E156705660566E0000
E9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
567356665663566D5672565E5677571C571B58C858BD58C958BF58BA58C258BC
58C65B175B195B1B5B215B145B135B105B165B285B1A5B205B1E5BEF5DAC5DB1
5DA95DA75DB55DB05DAE5DAA5DA85DB25DAD5DAF5DB45E675E685E665E6F5EE9
5EE75EE65EE85EE55F4B5FBC619D61A8619661C561B461C661C161CC61BA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000061BF61B8618C64D764D664D064CF64C964BD648964C364DB64F364D96533
657F657C65A266C866BE66C066CA66CB66CF66BD66BB66BA66CC67236A346A66
6A496A676A326A686A3E6A5D6A6D6A766A5B6A516A286A5A6A3B6A3F6A416A6A
6A646A506A4F6A546A6F6A696A606A3C6A5E6A566A556A4D6A4E6A466B556B54
6B566BA76BAA6BAB6BC86BC76C046C036C066FAD6FCB6FA36FC76FBC6FCE6FC8
6F5E6FC46FBD6F9E6FCA6FA870046FA56FAE6FBA6FAC6FAA6FCF6FBF6FB80000
EA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6FA26FC96FAB6FCD6FAF6FB26FB071C571C271BF71B871D671C071C171CB71D4
71CA71C771CF71BD71D871BC71C671DA71DB729D729E736973667367736C7365
736B736A747F749A74A074947492749574A1750B7580762F762D7631763D7633
763C76357632763076BB76E6779A779D77A1779C779B77A277A3779577990000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000779778DD78E978E578EA78DE78E378DB78E178E278ED78DF78E079A47A44
7A487A477AB67AB87AB57AB17AB77BDE7BE37BE77BDD7BD57BE57BDA7BE87BF9
7BD47BEA7BE27BDC7BEB7BD87BDF7CD27CD47CD77CD07CD17E127E217E177E0C
7E1F7E207E137E0E7E1C7E157E1A7E227E0B7E0F7E167E0D7E147E257E247F43
7F7B7F7C7F7A7FB17FEF802A8029806C81B181A681AE81B981B581AB81B081AC
81B481B281B781A781F282558256825785568545856B854D8553856185580000
EB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
854085468564854185628544855185478563853E855B8571854E856E85758555
85678560858C8566855D85548565856C866386658664879B878F879787938792
87888781879687988779878787A3878587908791879D87848794879C879A8789
891E89268930892D892E89278931892289298923892F892C891F89F18AE00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008AE28AF28AF48AF58ADD8B148AE48ADF8AF08AC88ADE8AE18AE88AFF8AEF
8AFB8C918C928C908CF58CEE8CF18CF08CF38D6C8D6E8DA58DA78E338E3E8E38
8E408E458E368E3C8E3D8E418E308E3F8EBD8F368F2E8F358F328F398F378F34
90769079907B908690FA913391359136919391909191918D918F9327931E9308
931F9306930F937A9338933C931B9323931293019346932D930E930D92CB931D
92FA9325931392F992F793349302932492FF932993399335932A9314930C0000
EC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
930B92FE9309930092FB931695BC95CD95BE95B995BA95B695BF95B595BD96A9
96D4970B9712971097999797979497F097F89835982F98329924991F99279929
999E99EE99EC99E599E499F099E399EA99E999E79AB99ABF9AB49ABB9AF69AFA
9AF99AF79B339B809B859B879B7C9B7E9B7B9B829B939B929B909B7A9B950000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009B7D9B889D259D179D209D1E9D149D299D1D9D189D229D109D199D1F9E88
9E869E879EAE9EAD9ED59ED69EFA9F129F3D51265125512251245120512952F4
5693568C568D568656845683567E5682567F568158D658D458CF58D25B2D5B25
5B325B235B2C5B275B265B2F5B2E5B7B5BF15BF25DB75E6C5E6A5FBE5FBB61C3
61B561BC61E761E061E561E461E861DE64EF64E964E364EB64E464E865816580
65B665DA66D26A8D6A966A816AA56A896A9F6A9B6AA16A9E6A876A936A8E0000
ED
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A956A836AA86AA46A916A7F6AA66A9A6A856A8C6A926B5B6BAD6C096FCC6FA9
6FF46FD46FE36FDC6FED6FE76FE66FDE6FF26FDD6FE26FE871E171F171E871F2
71E471F071E27373736E736F749774B274AB749074AA74AD74B174A574AF7510
75117512750F7584764376487649764776A476E977B577AB77B277B777B60000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077B477B177A877F078F378FD790278FB78FC78F2790578F978FE790479AB
79A87A5C7A5B7A567A587A547A5A7ABE7AC07AC17C057C0F7BF27C007BFF7BFB
7C0E7BF47C0B7BF37C027C097C037C017BF87BFD7C067BF07BF17C107C0A7CE8
7E2D7E3C7E427E3398487E387E2A7E497E407E477E297E4C7E307E3B7E367E44
7E3A7F457F7F7F7E7F7D7FF47FF2802C81BB81C481CC81CA81C581C781BC81E9
825B825A825C85838580858F85A7859585A0858B85A3857B85A4859A859E0000
EE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8577857C858985A1857A85788557858E85968586858D8599859D858185A28582
858885858579857685988590859F866887BE87AA87AD87C587B087AC87B987B5
87BC87AE87C987C387C287CC87B787AF87C487CA87B487B687BF87B887BD87DE
87B289358933893C893E894189528937894289AD89AF89AE89F289F38B1E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008B188B168B118B058B0B8B228B0F8B128B158B078B0D8B088B068B1C8B13
8B1A8C4F8C708C728C718C6F8C958C948CF98D6F8E4E8E4D8E538E508E4C8E47
8F438F409085907E9138919A91A2919B9199919F91A1919D91A093A1938393AF
936493569347937C9358935C93769349935093519360936D938F934C936A9379
935793559352934F93719377937B9361935E936393679380934E935995C795C0
95C995C395C595B796AE96B096AC9720971F9718971D9719979A97A1979C0000
EF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
979E979D97D597D497F198419844984A9849984598439925992B992C992A9933
9932992F992D99319930999899A399A19A0299FA99F499F799F999F899F699FB
99FD99FE99FC9A039ABE9AFE9AFD9B019AFC9B489B9A9BA89B9E9B9B9BA69BA1
9BA59BA49B869BA29BA09BAF9D339D419D679D369D2E9D2F9D319D389D300000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009D459D429D439D3E9D379D409D3D7FF59D2D9E8A9E899E8D9EB09EC89EDA
9EFB9EFF9F249F239F229F549FA05131512D512E5698569C5697569A569D5699
59705B3C5C695C6A5DC05E6D5E6E61D861DF61ED61EE61F161EA61F061EB61D6
61E964FF650464FD64F86501650364FC659465DB66DA66DB66D86AC56AB96ABD
6AE16AC66ABA6AB66AB76AC76AB46AAD6B5E6BC96C0B7007700C700D70017005
7014700E6FFF70006FFB70266FFC6FF7700A720171FF71F9720371FD73760000
F0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
74B874C074B574C174BE74B674BB74C275147513765C76647659765076537657
765A76A676BD76EC77C277BA78FF790C79137914790979107912791179AD79AC
7A5F7C1C7C297C197C207C1F7C2D7C1D7C267C287C227C257C307E5C7E507E56
7E637E587E627E5F7E517E607E577E537FB57FB37FF77FF8807581D181D20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000081D0825F825E85B485C685C085C385C285B385B585BD85C785C485BF85CB
85CE85C885C585B185B685D2862485B885B785BE866987E787E687E287DB87EB
87EA87E587DF87F387E487D487DC87D387ED87D887E387A487D787D9880187F4
87E887DD8953894B894F894C89468950895189498B2A8B278B238B338B308B35
8B478B2F8B3C8B3E8B318B258B378B268B368B2E8B248B3B8B3D8B3A8C428C75
8C998C988C978CFE8D048D028D008E5C8E628E608E578E568E5E8E658E670000
F1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8E5B8E5A8E618E5D8E698E548F468F478F488F4B9128913A913B913E91A891A5
91A791AF91AA93B5938C939293B7939B939D938993A7938E93AA939E93A69395
93889399939F938D93B1939193B293A493A893B493A393A595D295D395D196B3
96D796DA5DC296DF96D896DD97239722972597AC97AE97A897AB97A497AA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000097A297A597D797D997D697D897FA98509851985298B89941993C993A9A0F
9A0B9A099A0D9A049A119A0A9A059A079A069AC09ADC9B089B049B059B299B35
9B4A9B4C9B4B9BC79BC69BC39BBF9BC19BB59BB89BD39BB69BC49BB99BBD9D5C
9D539D4F9D4A9D5B9D4B9D599D569D4C9D579D529D549D5F9D589D5A9E8E9E8C
9EDF9F019F009F169F259F2B9F2A9F299F289F4C9F5551345135529652F753B4
56AB56AD56A656A756AA56AC58DA58DD58DB59125B3D5B3E5B3F5DC35E700000
F2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5FBF61FB65076510650D6509650C650E658465DE65DD66DE6AE76AE06ACC6AD1
6AD96ACB6ADF6ADC6AD06AEB6ACF6ACD6ADE6B606BB06C0C7019702770207016
702B702170227023702970177024701C702A720C720A72077202720572A572A6
72A472A372A174CB74C574B774C37516766077C977CA77C477F1791D791B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007921791C7917791E79B07A677A687C337C3C7C397C2C7C3B7CEC7CEA7E76
7E757E787E707E777E6F7E7A7E727E747E687F4B7F4A7F837F867FB77FFD7FFE
807881D781D582648261826385EB85F185ED85D985E185E885DA85D785EC85F2
85F885D885DF85E385DC85D185F085E685EF85DE85E2880087FA880387F687F7
8809880C880B880687FC880887FF880A88028962895A895B89578961895C8958
895D8959898889B789B689F68B508B488B4A8B408B538B568B548B4B8B550000
F3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8B518B428B528B578C438C778C768C9A8D068D078D098DAC8DAA8DAD8DAB8E6D
8E788E738E6A8E6F8E7B8EC28F528F518F4F8F508F538FB49140913F91B091AD
93DE93C793CF93C293DA93D093F993EC93CC93D993A993E693CA93D493EE93E3
93D593C493CE93C093D293E7957D95DA95DB96E19729972B972C972897260000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000097B397B797B697DD97DE97DF985C9859985D985798BF98BD98BB98BE9948
9947994399A699A79A1A9A159A259A1D9A249A1B9A229A209A279A239A1E9A1C
9A149AC29B0B9B0A9B0E9B0C9B379BEA9BEB9BE09BDE9BE49BE69BE29BF09BD4
9BD79BEC9BDC9BD99BE59BD59BE19BDA9D779D819D8A9D849D889D719D809D78
9D869D8B9D8C9D7D9D6B9D749D759D709D699D859D739D7B9D829D6F9D799D7F
9D879D689E949E919EC09EFC9F2D9F409F419F4D9F569F579F58533756B20000
F4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
56B556B358E35B455DC65DC75EEE5EEF5FC05FC161F9651765166515651365DF
66E866E366E46AF36AF06AEA6AE86AF96AF16AEE6AEF703C7035702F70377034
703170427038703F703A70397040703B703370417213721472A8737D737C74BA
76AB76AA76BE76ED77CC77CE77CF77CD77F27925792379277928792479290000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000079B27A6E7A6C7A6D7AF77C497C487C4A7C477C457CEE7E7B7E7E7E817E80
7FBA7FFF807981DB81D9820B82688269862285FF860185FE861B860085F68604
86098605860C85FD8819881088118817881388168963896689B989F78B608B6A
8B5D8B688B638B658B678B6D8DAE8E868E888E848F598F568F578F558F588F5A
908D9143914191B791B591B291B3940B941393FB9420940F941493FE94159410
94289419940D93F5940093F79407940E9416941293FA940993F8940A93FF0000
F5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
93FC940C93F69411940695DE95E095DF972E972F97B997BB97FD97FE98609862
9863985F98C198C29950994E9959994C994B99539A329A349A319A2C9A2A9A36
9A299A2E9A389A2D9AC79ACA9AC69B109B129B119C0B9C089BF79C059C129BF8
9C409C079C0E9C069C179C149C099D9F9D999DA49D9D9D929D989D909D9B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009DA09D949D9C9DAA9D979DA19D9A9DA29DA89D9E9DA39DBF9DA99D969DA6
9DA79E999E9B9E9A9EE59EE49EE79EE69F309F2E9F5B9F609F5E9F5D9F599F91
513A51395298529756C356BD56BE5B485B475DCB5DCF5EF161FD651B6B026AFC
6B036AF86B0070437044704A7048704970457046721D721A7219737E7517766A
77D0792D7931792F7C547C537CF27E8A7E877E887E8B7E867E8D7F4D7FBB8030
81DD8618862A8626861F8623861C86198627862E862186208629861E86250000
F6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8829881D881B88208824881C882B884A896D8969896E896B89FA8B798B788B45
8B7A8B7B8D108D148DAF8E8E8E8C8F5E8F5B8F5D91469144914591B9943F943B
94369429943D943C94309439942A9437942C9440943195E595E495E39735973A
97BF97E1986498C998C698C0995899569A399A3D9A469A449A429A419A3A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009A3F9ACD9B159B179B189B169B3A9B529C2B9C1D9C1C9C2C9C239C289C29
9C249C219DB79DB69DBC9DC19DC79DCA9DCF9DBE9DC59DC39DBB9DB59DCE9DB9
9DBA9DAC9DC89DB19DAD9DCC9DB39DCD9DB29E7A9E9C9EEB9EEE9EED9F1B9F18
9F1A9F319F4E9F659F649F924EB956C656C556CB59715B4B5B4C5DD55DD15EF2
65216520652665226B0B6B086B096C0D7055705670577052721E721F72A9737F
74D874D574D974D7766D76AD793579B47A707A717C577C5C7C597C5B7C5A0000
F7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7CF47CF17E917F4F7F8781DE826B863486358633862C86328636882C88288826
882A8825897189BF89BE89FB8B7E8B848B828B868B858B7F8D158E958E948E9A
8E928E908E968E978F608F629147944C9450944A944B944F9447944594489449
9446973F97E3986A986998CB9954995B9A4E9A539A549A4C9A4F9A489A4A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009A499A529A509AD09B199B2B9B3B9B569B559C469C489C3F9C449C399C33
9C419C3C9C379C349C329C3D9C369DDB9DD29DDE9DDA9DCB9DD09DDC9DD19DDF
9DE99DD99DD89DD69DF59DD59DDD9EB69EF09F359F339F329F429F6B9F959FA2
513D529958E858E759725B4D5DD8882F5F4F62016203620465296525659666EB
6B116B126B0F6BCA705B705A7222738273817383767077D47C677C667E95826C
863A86408639863C8631863B863E88308832882E883389768974897389FE0000
F8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8B8C8B8E8B8B8B888C458D198E988F648F6391BC94629455945D9457945E97C4
97C598009A569A599B1E9B1F9B209C529C589C509C4A9C4D9C4B9C559C599C4C
9C4E9DFB9DF79DEF9DE39DEB9DF89DE49DF69DE19DEE9DE69DF29DF09DE29DEC
9DF49DF39DE89DED9EC29ED09EF29EF39F069F1C9F389F379F369F439F4F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009F719F709F6E9F6F56D356CD5B4E5C6D652D66ED66EE6B13705F7061705D
7060722374DB74E577D5793879B779B67C6A7E977F89826D8643883888378835
884B8B948B958E9E8E9F8EA08E9D91BE91BD91C2946B9468946996E597469743
974797C797E59A5E9AD59B599C639C679C669C629C5E9C609E029DFE9E079E03
9E069E059E009E019E099DFF9DFD9E049EA09F1E9F469F749F759F7656D4652E
65B86B186B196B176B1A7062722672AA77D877D979397C697C6B7CF67E9A0000
F9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7E987E9B7E9981E081E18646864786488979897A897C897B89FF8B988B998EA5
8EA48EA3946E946D946F9471947397499872995F9C689C6E9C6D9E0B9E0D9E10
9E0F9E129E119EA19EF59F099F479F789F7B9F7A9F79571E70667C6F883C8DB2
8EA691C394749478947694759A609C749C739C719C759E149E139EF69F0A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009FA4706870657CF7866A883E883D883F8B9E8C9C8EA98EC9974B98739874
98CC996199AB9A649A669A679B249E159E179F4862076B1E7227864C8EA89482
948094819A699A689B2E9E197229864B8B9F94839C799EB776759A6B9C7A9E1D
7069706A9EA49F7E9F499F98788192B988CF58BB60527CA75AFA255425662557
2560256C2563255A2569255D255225642555255E256A256125582567255B2553
25652556255F256B256225592568255C25512550256D256E2570256F25930000

Added library/encoding/dingbats.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: dingbats, single-byte
S
003F 1 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
00202701270227032704260E2706270727082709261B261E270C270D270E270F
2710271127122713271427152716271727182719271A271B271C271D271E271F
2720272127222723272427252726272726052729272A272B272C272D272E272F
2730273127322733273427352736273727382739273A273B273C273D273E273F
2740274127422743274427452746274727482749274A274B25CF274D25A0274F
27502751275225B225BC25C6275625D727582759275A275B275C275D275E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000276127622763276427652766276726632666266526602460246124622463
2464246524662467246824692776277727782779277A277B277C277D277E277F
2780278127822783278427852786278727882789278A278B278C278D278E278F
2790279127922793279421922194219527982799279A279B279C279D279E279F
27A027A127A227A327A427A527A627A727A827A927AA27AB27AC27AD27AE27AF
000027B127B227B327B427B527B627B727B827B927BA27BB27BC27BD27BE0000

Added library/encoding/euc-cn.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
# Encoding file: euc-cn, multi-byte
M
003F 0 82
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030003001300230FB02C902C700A8300330052015FF5E2225202620182019
201C201D3014301530083009300A300B300C300D300E300F3016301730103011
00B100D700F72236222722282211220F222A222922082237221A22A522252220
23122299222B222E2261224C2248223D221D2260226E226F22642265221E2235
22342642264000B0203220332103FF0400A4FFE0FFE1203000A7211626062605
25CB25CF25CE25C725C625A125A025B325B2203B219221902191219330130000
A2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000024882489248A248B248C248D248E248F2490249124922493249424952496
249724982499249A249B247424752476247724782479247A247B247C247D247E
247F248024812482248324842485248624872460246124622463246424652466
2467246824690000000032203221322232233224322532263227322832290000
00002160216121622163216421652166216721682169216A216B000000000000
A3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF01FF02FF03FFE5FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFF3CFF3DFF3EFF3F
FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
A4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000304130423043304430453046304730483049304A304B304C304D304E304F
3050305130523053305430553056305730583059305A305B305C305D305E305F
3060306130623063306430653066306730683069306A306B306C306D306E306F
3070307130723073307430753076307730783079307A307B307C307D307E307F
3080308130823083308430853086308730883089308A308B308C308D308E308F
3090309130923093000000000000000000000000000000000000000000000000
A5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000000
A6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000039103920393039403950396039703980399039A039B039C039D039E039F
03A003A103A303A403A503A603A703A803A90000000000000000000000000000
000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C303C403C503C603C703C803C90000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000004100411041204130414041504010416041704180419041A041B041C041D
041E041F0420042104220423042404250426042704280429042A042B042C042D
042E042F00000000000000000000000000000000000000000000000000000000
000004300431043204330434043504510436043704380439043A043B043C043D
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000000000
A8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000010100E101CE00E0011300E9011B00E8012B00ED01D000EC014D00F301D2
00F2016B00FA01D400F901D601D801DA01DC00FC00EA00000000000000000000
0000000000000000000031053106310731083109310A310B310C310D310E310F
3110311131123113311431153116311731183119311A311B311C311D311E311F
3120312131223123312431253126312731283129000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000002500250125022503250425052506250725082509250A250B
250C250D250E250F2510251125122513251425152516251725182519251A251B
251C251D251E251F2520252125222523252425252526252725282529252A252B
252C252D252E252F2530253125322533253425352536253725382539253A253B
253C253D253E253F2540254125422543254425452546254725482549254A254B
0000000000000000000000000000000000000000000000000000000000000000
B0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000554A963F57C3632854CE550954C07691764C853C77EE827E788D72319698
978D6C285B894FFA630966975CB880FA684880AE660276CE51F9655671AC7FF1
888450B2596561CA6FB382AD634C625253ED54277B06516B75A45DF462D48DCB
9776628A8019575D97387F627238767D67CF767E64464F708D2562DC7A176591
73ED642C6273822C9881677F7248626E62CC4F3474E3534A529E7ECA90A65E2E
6886699C81807ED168D278C5868C9551508D8C2482DE80DE5305891252650000
B1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000858496F94FDD582199715B9D62B162A566B48C799C8D7206676F789160B2
535153178F8880CC8D1D94A1500D72C8590760EB711988AB595482EF672C7B28
5D297EF7752D6CF58E668FF8903C9F3B6BD491197B145F7C78A784D6853D6BD5
6BD96BD65E015E8775F995ED655D5F0A5FC58F9F58C181C2907F965B97AD8FB9
7F168D2C62414FBF53D8535E8FA88FA98FAB904D68075F6A819888689CD6618B
522B762A5F6C658C6FD26EE85BBE6448517551B067C44E1979C9997C70B30000
B2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075C55E7673BB83E064AD62E894B56CE2535A52C3640F94C27B944F2F5E1B
82368116818A6E246CCA9A736355535C54FA886557E04E0D5E036B657C3F90E8
601664E6731C88C16750624D8D22776C8E2991C75F6983DC8521991053C28695
6B8B60ED60E8707F82CD82314ED36CA785CF64CD7CD969FD66F9834953957B56
4FA7518C6D4B5C428E6D63D253C9832C833667E578B4643D5BDF5C945DEE8BE7
62C667F48C7A640063BA8749998B8C177F2094F24EA7961098A4660C73160000
B3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000573A5C1D5E38957F507F80A05382655E7545553150218D856284949E671D
56326F6E5DE2543570928F66626F64A463A35F7B6F8890F481E38FB05C186668
5FF16C8996488D81886C649179F057CE6A59621054484E587A0B60E96F848BDA
627F901E9A8B79E4540375F4630153196C608FDF5F1B9A70803B9F7F4F885C3A
8D647FC565A570BD514551B2866B5D075BA062BD916C75748E0C7A2061017B79
4EC77EF877854E1181ED521D51FA6A7153A88E87950496CF6EC19664695A0000
B4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000784050A877D7641089E6590463E35DDD7A7F693D4F20823955984E3275AE
7A975E625E8A95EF521B5439708A6376952457826625693F918755076DF37EAF
882262337EF075B5832878C196CC8F9E614874F78BCD6B64523A8D506B21806A
847156F153064ECE4E1B51D17C97918B7C074FC38E7F7BE17A9C64675D1450AC
810676017CB96DEC7FE067515B585BF878CB64AE641363AA632B9519642D8FBE
7B5476296253592754466B7950A362345E266B864EE38D37888B5F85902E0000
B5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006020803D62C54E39535590F863B880C665E66C2E4F4660EE6DE18BDE5F39
86CB5F536321515A83616863520063638E4850125C9B79775BFC52307A3B60BC
905376D75FB75F9776848E6C706F767B7B4977AA51F3909358244F4E6EF48FEA
654C7B1B72C46DA47FDF5AE162B55E95573084827B2C5E1D5F1F90127F1498A0
63826EC7789870B95178975B57AB75354F4375385E9760E659606DC06BBF7889
53FC96D551CB52016389540A94938C038DCC7239789F87768FED8C0D53E00000
B6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E0176EF53EE948998769F0E952D5B9A8BA24E224E1C51AC846361C252A8
680B4F97606B51BB6D1E515C6296659796618C46901775D890FD77636BD2728A
72EC8BFB583577798D4C675C9540809A5EA66E2159927AEF77ED953B6BB565AD
7F0E58065151961F5BF958A954288E726566987F56E4949D76FE9041638754C6
591A593A579B8EB267358DFA8235524160F0581586FE5CE89E454FC4989D8BB9
5A2560765384627C904F9102997F6069800C513F80335C1499756D314E8C0000
B7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008D3053D17F5A7B4F4F104E4F96006CD573D085E95E06756A7FFB6A0A77FE
94927E4151E170E653CD8FD483038D2972AF996D6CDB574A82B365B980AA623F
963259A84EFF8BBF7EBA653E83F2975E556198DE80A5532A8BFD542080BA5E9F
6CB88D3982AC915A54296C1B52067EB7575F711A6C7E7C89594B4EFD5FFF6124
7CAA4E305C0167AB87025CF0950B98CE75AF70FD902251AF7F1D8BBD594951E4
4F5B5426592B657780A45B75627662C28F905E456C1F7B264F0F4FD8670D0000
B8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D6E6DAA798F88B15F17752B629A8F854FEF91DC65A7812F81515E9C8150
8D74526F89868D4B590D50854ED8961C723681798D1F5BCC8BA3964459877F1A
54905676560E8BE565396982949976D66E895E727518674667D17AFF809D8D76
611F79C665628D635188521A94A27F38809B7EB25C976E2F67607BD9768B9AD8
818F7F947CD5641E95507A3F544A54E56B4C640162089E3D80F3759952729769
845B683C86E49601969494EC4E2A54047ED968398DDF801566F45E9A7FB90000
B9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000057C2803F68975DE5653B529F606D9F9A4F9B8EAC516C5BAB5F135DE96C5E
62F18D21517194A952FE6C9F82DF72D757A267848D2D591F8F9C83C754957B8D
4F306CBD5B6459D19F1353E486CA9AA88C3780A16545987E56FA96C7522E74DC
52505BE1630289024E5662D0602A68FA51735B9851A089C27BA199867F5060EF
704C8D2F51495E7F901B747089C4572D78455F529F9F95FA8F689B3C8BE17678
684267DC8DEA8D35523D8F8A6EDA68CD950590ED56FD679C88F98FC754C80000
BA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009AB85B696D776C264EA55BB39A87916361A890AF97E9542B6DB55BD251FD
558A7F557FF064BC634D65F161BE608D710A6C576C49592F676D822A58D5568E
8C6A6BEB90DD597D801753F76D695475559D837783CF683879BE548C4F555408
76D28C8996026CB36DB88D6B89109E648D3A563F9ED175D55F8872E0606854FC
4EA86A2A886160528F7054C470D886799E3F6D2A5B8F5F187EA255894FAF7334
543C539A5019540E547C4E4E5FFD745A58F6846B80E1877472D07CCA6E560000
BB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F27864E552C62A44E926CAA623782B154D7534E733E6ED1753B52125316
8BDD69D05F8A60006DEE574F6B2273AF68538FD87F13636260A3552475EA8C62
71156DA35BA65E7B8352614C9EC478FA87577C27768751F060F6714C66435E4C
604D8C0E707063258F895FBD606286D456DE6BC160946167534960E066668D3F
79FD4F1A70E96C478BB38BF27ED88364660F5A5A9B426D516DF78C416D3B4F19
706B83B7621660D1970D8D27797851FB573E57FA673A75787A3D79EF7B950000
BC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000808C99658FF96FC08BA59E2159EC7EE97F095409678168D88F917C4D96C6
53CA602575BE6C7253735AC97EA7632451E0810A5DF184DF628051805B634F0E
796D524260B86D4E5BC45BC28BA18BB065E25FCC964559937EE77EAA560967B7
59394F735BB652A0835A988A8D3E753294BE50477A3C4EF767B69A7E5AC16B7C
76D1575A5C167B3A95F4714E517C80A9827059787F04832768C067EC78B17877
62E363617B804FED526A51CF835069DB92748DF58D3189C1952E7BAD4EF60000
BD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000506582305251996F6E106E856DA75EFA50F559DC5C066D466C5F7586848B
686859568BB253209171964D854969127901712680F64EA490CA6D479A845A07
56BC640594F077EB4FA5811A72E189D2997A7F347EDE527F655991758F7F8F83
53EB7A9663ED63A5768679F888579636622A52AB8282685467706377776B7AED
6D017ED389E359D0621285C982A5754C501F4ECB75A58BEB5C4A5DFE7B4B65A4
91D14ECA6D25895F7D2795264EC58C288FDB9773664B79818FD170EC6D780000
BE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005C3D52B283465162830E775B66769CB84EAC60CA7CBE7CB37ECF4E958B66
666F988897595883656C955C5F8475C997567ADF7ADE51C070AF7A9863EA7A76
7EA0739697ED4E4570784E5D915253A9655165E781FC8205548E5C31759A97A0
62D872D975BD5C459A7983CA5C40548077E94E3E6CAE805A62D2636E5DE85177
8DDD8E1E952F4FF153E560E770AC526763509E435A1F5026773753777EE26485
652B628963985014723589C951B38BC07EDD574783CC94A7519B541B5CFB0000
BF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004FCA7AE36D5A90E19A8F55805496536154AF5F0063E9697751EF6168520A
582A52D8574E780D770B5EB761777CE0625B62974EA27095800362F770E49760
577782DB67EF68F578D5989779D158F354B353EF6E34514B523B5BA28BFE80AF
554357A660735751542D7A7A60505B5463A762A053E362635BC767AF54ED7A9F
82E691775E9388E4593857AE630E8DE880EF57577B774FA95FEB5BBD6B3E5321
7B5072C2684677FF773665F751B54E8F76D45CBF7AA58475594E9B4150800000
C0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000998861276E8357646606634656F062EC62695ED39614578362C955878721
814A8FA3556683B167658D5684DD5A6A680F62E67BEE961151706F9C8C3063FD
89C861D27F0670C26EE57405699472FC5ECA90CE67176D6A635E52B372628001
4F6C59E5916A70D96D9D52D24E5096F7956D857E78CA7D2F5121579264C2808B
7C7B6CEA68F1695E51B7539868A872819ECE7BF172F879BB6F137406674E91CC
9CA4793C83898354540F68174E3D538952B1783E5386522950884F8B4FD00000
C1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075E27ACB7C926CA596B6529B748354E94FE9805483B28FDE95705EC9601C
6D9F5E18655B813894FE604B70BC7EC37CAE51C968817CB1826F4E248F8691CF
667E4EAE8C0564A9804A50DA759771CE5BE58FBD6F664E86648295635ED66599
521788C270C852A3730E7433679778F797164E3490BB9CDE6DCB51DB8D41541D
62CE73B283F196F69F8494C34F367F9A51CC707596755CAD988653E64EE46E9C
740969B4786B998F7559521876246D4167F3516D9F99804B54997B3C7ABF0000
C2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009686578462E29647697C5A0464027BD36F0F964B82A6536298855E907089
63B35364864F9C819E93788C97328DEF8D429E7F6F5E79845F559646622E9A74
541594DD4FA365C55C655C617F1586516C2F5F8B73876EE47EFF5CE6631B5B6A
6EE653754E7163A0756562A18F6E4F264ED16CA67EB68BBA841D87BA7F57903B
95237BA99AA188F8843D6D1B9A867EDC59889EBB739B780186829A6C9A82561B
541757CB4E709EA653568FC881097792999286EE6EE1851366FC61626F2B0000
C3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008C298292832B76F26C135FD983BD732B8305951A6BDB77DB94C6536F8302
51925E3D8C8C8D384E4873AB679A68859176970971646CA177095A9295416BCF
7F8E66275BD059B95A9A95E895F74EEC840C84996AAC76DF9530731B68A65B5F
772F919A97617CDC8FF78C1C5F257C7379D889C56CCC871C5BC65E4268C97720
7EF55195514D52C95A297F05976282D763CF778485D079D26E3A5E9959998511
706D6C1162BF76BF654F60AF95FD660E879F9E2394ED540D547D8C2C64780000
C4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000647986116A21819C78E864699B5462B9672B83AB58A89ED86CAB6F205BDE
964C8C0B725F67D062C772614EA959C66BCD589366AE5E5552DF6155672876EE
776672677A4662FF54EA545094A090A35A1C7EB36C164E435976801059485357
753796BE56CA63208111607C95F96DD65462998151855AE980FD59AE9713502A
6CE55C3C62DF4F60533F817B90066EBA852B62C85E7478BE64B5637B5FF55A18
917F9E1F5C3F634F80425B7D556E954A954D6D8560A867E072DE51DD5B810000
C5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000062E76CDE725B626D94AE7EBD81136D53519C5F04597452AA601259736696
8650759F632A61E67CEF8BFA54E66B279E256BB485D5545550766CA4556A8DB4
722C5E156015743662CD6392724C5F986E436D3E65006F5876D878D076FC7554
522453DB4E535E9E65C1802A80D6629B5486522870AE888D8DD16CE1547880DA
57F988F48D54966A914D4F696C9B55B776C6783062A870F96F8E5F6D84EC68DA
787C7BF781A8670B9E4F636778B0576F78129739627962AB528874356BD70000
C6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005564813E75B276AE533975DE50FB5C418B6C7BC7504F72479A9798D86F02
74E27968648777A562FC98918D2B54C180584E52576A82F9840D5E7351ED74F6
8BC45C4F57616CFC98875A4678349B448FEB7C955256625194FA4EC683868461
83E984B257D467345703666E6D668C3166DD7011671F6B3A6816621A59BB4E03
51C46F0667D26C8F517668CB59476B6775665D0E81109F5065D7794879419A91
8D775C824E5E4F01542F5951780C56686C148FC45F036C7D6CE38BAB63900000
C7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000060706D3D72756266948E94C553438FC17B7E4EDF8C264E7E9ED494B194B3
524D6F5C90636D458C3458115D4C6B206B4967AA545B81547F8C589985375F3A
62A26A47953965726084686577A74E544FA85DE7979864AC7FD85CED4FCF7A8D
520783044E14602F7A8394A64FB54EB279E6743452E482B964D279BD5BDD6C81
97528F7B6C22503E537F6E0564CE66746C3060C598778BF75E86743C7A7779CB
4E1890B174036C4256DA914B6CC58D8B533A86C666F28EAF5C489A716E200000
C8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000053D65A369F8B8DA353BB570898A76743919B6CC9516875CA62F372AC5238
529D7F3A7094763853749E4A69B7786E96C088D97FA4713671C3518967D374E4
58E4651856B78BA9997662707ED560F970ED58EC4EC14EBA5FCD97E74EFB8BA4
5203598A7EAB62544ECD65E5620E833884C98363878D71946EB65BB97ED25197
63C967D480898339881551125B7A59828FB14E736C5D516589258F6F962E854A
745E951095F06DA682E55F3164926D128428816E9CC3585E8D5B4E0953C10000
C9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F1E6563685155D34E2764149A9A626B5AC2745F82726DA968EE50E7838E
7802674052396C997EB150BB5565715E7B5B665273CA82EB67495C715220717D
886B95EA965564C58D6181B355846C5562477F2E58924F2455468D4F664C4E0A
5C1A88F368A2634E7A0D70E7828D52FA97F65C1154E890B57ECD59628D4A86C7
820C820D8D6664445C0461516D89793E8BBE78377533547B4F388EAB6DF15A20
7EC5795E6C885BA15A76751A80BE614E6E1758F0751F7525727253477EF30000
CA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000770176DB526980DC57235E08593172EE65BD6E7F8BD75C388671534177F3
62FE65F64EC098DF86805B9E8BC653F277E24F7F5C4E9A7659CB5F0F793A58EB
4E1667FF4E8B62ED8A93901D52BF662F55DC566C90024ED54F8D91CA99706C0F
5E0260435BA489C68BD56536624B99965B885BFF6388552E53D77626517D852C
67A268B36B8A62928F9353D482126DD1758F4E668D4E5B70719F85AF669166D9
7F7287009ECD9F205C5E672F8FF06811675F620D7AD658855EB665706F310000
CB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000060555237800D6454887075295E05681362F4971C53CC723D8C016C347761
7A0E542E77AC987A821C8BF47855671470C165AF64955636601D79C153F84E1D
6B7B80865BFA55E356DB4F3A4F3C99725DF3677E80386002988290015B8B8BBC
8BF5641C825864DE55FD82CF91654FD77D20901F7C9F50F358516EAF5BBF8BC9
80839178849C7B97867D968B968F7EE59AD3788E5C817A57904296A7795F5B59
635F7B0B84D168AD55067F2974107D2295016240584C4ED65B83597958540000
CC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000736D631E8E4B8E0F80CE82D462AC53F06CF0915E592A60016C70574D644A
8D2A762B6EE9575B6A8075F06F6D8C2D8C0857666BEF889278B363A253F970AD
6C645858642A580268E0819B55107CD650188EBA6DCC8D9F70EB638F6D9B6ED4
7EE68404684390036DD896768BA85957727985E4817E75BC8A8A68AF52548E22
951163D098988E44557C4F5366FF568F60D56D9552435C4959296DFB586B7530
751C606C82148146631167618FE2773A8DF38D3494C15E165385542C70C30000
CD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006C405EF7505C4EAD5EAD633A8247901A6850916E77B3540C94DC5F647AE5
687663457B527EDF75DB507762955934900F51F879C37A8156FE5F9290146D82
5C60571F541051546E4D56E263A89893817F8715892A9000541E5C6F81C062D6
625881319E3596409A6E9A7C692D59A562D3553E631654C786D96D3C5A0374E6
889C6B6A59168C4C5F2F6E7E73A9987D4E3870F75B8C7897633D665A769660CB
5B9B5A494E0781556C6A738B4EA167897F515F8065FA671B5FD859845A010000
CE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005DCD5FAE537197E68FDD684556F4552F60DF4E3A6F4D7EF482C7840E59D4
4F1F4F2A5C3E7EAC672A851A5473754F80C355829B4F4F4D6E2D8C135C096170
536B761F6E29868A658795FB7EB9543B7A337D0A95EE55E17FC174EE631D8717
6DA17A9D621165A1536763E16C835DEB545C94A84E4C6C618BEC5C4B65E0829C
68A7543E54346BCB6B664E9463425348821E4F0D4FAE575E620A96FE66647269
52FF52A1609F8BEF661471996790897F785277FD6670563B54389521727A0000
CF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A00606F5E0C6089819D591560DC718470EF6EAA6C5072806A8488AD5E2D
4E605AB3559C94E36D177CFB9699620F7EC6778E867E5323971E8F9666875CE1
4FA072ED4E0B53A6590F54136380952851484ED99C9C7EA454B88D2488548237
95F26D8E5F265ACC663E966973B0732E53BF817A99857FA15BAA967796507EBF
76F853A2957699997BB189446E584E617FD479658BE660F354CD4EAB98795DF7
6A6150CF54118C618427785D9704524A54EE56A395006D885BB56DC666530000
D0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005C0F5B5D6821809655787B11654869544E9B6B47874E978B534F631F643A
90AA659C80C18C10519968B0537887F961C86CC46CFB8C225C5185AA82AF950C
6B238F9B65B05FFB5FC34FE18845661F8165732960FA51745211578B5F6290A2
884C91925E78674F602759D3514451F680F853086C7996C4718A4F114FEE7F9E
673D55C5950879C088967EE3589F620C9700865A5618987B5F908BB884C49157
53D965ED5E8F755C60647D6E5A7F7EEA7EED8F6955A75BA360AC65CB73840000
D1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009009766377297EDA9774859B5B667A7496EA884052CB718F5FAA65EC8BE2
5BFB9A6F5DE16B896C5B8BAD8BAF900A8FC5538B62BC9E269E2D54404E2B82BD
7259869C5D1688596DAF96C554D14E9A8BB6710954BD960970DF6DF976D04E25
781487125CA95EF68A00989C960E708E6CBF594463A9773C884D6F1482735830
71D5538C781A96C155015F6671305BB48C1A9A8C6B83592E9E2F79E76768626C
4F6F75A17F8A6D0B96336C274EF075D2517B68376F3E90808170599674760000
D2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000064475C2790657A918C2359DA54AC8200836F898180006930564E80367237
91CE51B64E5F987563964E1A53F666F3814B591C6DB24E0058F9533B63D694F1
4F9D4F0A886398905937905779FB4EEA80F075916C825B9C59E85F5D69058681
501A5DF24E5977E34EE5827A6291661390915C794EBF5F7981C69038808475AB
4EA688D4610F6BC55FC64E4976CA6EA28BE38BAE8C0A8BD15F027FFC7FCC7ECE
8335836B56E06BB797F3963459FB541F94F66DEB5BC5996E5C395F1596900000
D3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000537082F16A315A749E705E947F2883B984248425836787478FCE8D6276C8
5F719896786C662054DF62E54F6381C375C85EB896CD8E0A86F9548F6CF36D8C
6C38607F52C775285E7D4F1860A05FE75C24753190AE94C072B96CB96E389149
670953CB53F34F5191C98BF153C85E7C8FC26DE44E8E76C26986865E611A8206
4F594FDE903E9C7C61096E1D6E1496854E885A3196E84E0E5C7F79B95B878BED
7FBD738957DF828B90C15401904755BB5CEA5FA161086B3272F180B28A890000
D4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D745BD388D598848C6B9A6D9E336E0A51A4514357A38881539F63F48F95
56ED54585706733F6E907F188FDC82D1613F6028966266F07EA68D8A8DC394A5
5CB37CA4670860A6960580184E9190E75300966851418FD08574915D665597F5
5B55531D78386742683D54C9707E5BB08F7D518D572854B1651266828D5E8D43
810F846C906D7CDF51FF85FB67A365E96FA186A48E81566A90207682707671E5
8D2362E952196CFD8D3C600E589E618E66FE8D60624E55B36E23672D8F670000
D5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000094E195F87728680569A8548B4E4D70B88BC86458658B5B857A84503A5BE8
77BB6BE18A797C986CBE76CF65A98F975D2D5C5586386808536062187AD96E5B
7EFD6A1F7AE05F706F335F20638C6DA867564E085E108D264ED780C07634969C
62DB662D627E6CBC8D7571677F695146808753EC906E629854F286F08F998005
951785178FD96D5973CD659F771F7504782781FB8D1E94884FA6679575B98BCA
9707632F9547963584B8632377415F8172F04E896014657462EF6B63653F0000
D6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005E2775C790D18BC1829D679D652F5431871877E580A281026C414E4B7EC7
804C76F4690D6B966267503C4F84574063076B628DBE53EA65E87EB85FD7631A
63B781F381F47F6E5E1C5CD95236667A79E97A1A8D28709975D46EDE6CBB7A92
4E2D76C55FE0949F88777EC879CD80BF91CD4EF24F17821F54685DDE6D328BCC
7CA58F7480985E1A549276B15B99663C9AA473E0682A86DB6731732A8BF88BDB
90107AF970DB716E62C477A956314E3B845767F152A986C08D2E94F87B510000
D7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F4F6CE8795D9A7B6293722A62FD4E1378168F6C64B08D5A7BC668695E84
88C55986649E58EE72B6690E95258FFD8D5857607F008C0651C6634962D95353
684C74228301914C55447740707C6D4A517954A88D4459FF6ECB6DC45B5C7D2B
4ED47C7D6ED35B5081EA6E0D5B579B0368D58E2A5B977EFC603B7EB590B98D70
594F63CD79DF8DB3535265CF79568BC5963B7EC494BB7E825634918967007F6A
5C0A907566285DE64F5067DE505A4F5C57505EA7000000000000000000000000
D8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E8D4E0C51404E105EFF53454E154E984E1E9B325B6C56694E2879BA4E3F
53154E47592D723B536E6C1056DF80E499976BD3777E9F174E364E9F9F104E5C
4E694E9382885B5B556C560F4EC4538D539D53A353A553AE97658D5D531A53F5
5326532E533E8D5C5366536352025208520E522D5233523F5240524C525E5261
525C84AF527D528252815290529351827F544EBB4EC34EC94EC24EE84EE14EEB
4EDE4F1B4EF34F224F644EF54F254F274F094F2B4F5E4F6765384F5A4F5D0000
D9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F5F4F574F324F3D4F764F744F914F894F834F8F4F7E4F7B4FAA4F7C4FAC
4F944FE64FE84FEA4FC54FDA4FE34FDC4FD14FDF4FF85029504C4FF3502C500F
502E502D4FFE501C500C50255028507E504350555048504E506C507B50A550A7
50A950BA50D6510650ED50EC50E650EE5107510B4EDD6C3D4F584F654FCE9FA0
6C467C74516E5DFD9EC999985181591452F9530D8A07531051EB591951554EA0
51564EB3886E88A44EB5811488D279805B3488037FB851AB51B151BD51BC0000
DA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000051C7519651A251A58BA08BA68BA78BAA8BB48BB58BB78BC28BC38BCB8BCF
8BCE8BD28BD38BD48BD68BD88BD98BDC8BDF8BE08BE48BE88BE98BEE8BF08BF3
8BF68BF98BFC8BFF8C008C028C048C078C0C8C0F8C118C128C148C158C168C19
8C1B8C188C1D8C1F8C208C218C258C278C2A8C2B8C2E8C2F8C328C338C358C36
5369537A961D962296219631962A963D963C964296499654965F9667966C9672
96749688968D969796B09097909B909D909990AC90A190B490B390B690BA0000
DB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000090B890B090CF90C590BE90D090C490C790D390E690E290DC90D790DB90EB
90EF90FE91049122911E91239131912F913991439146520D594252A252AC52AD
52BE54FF52D052D652F053DF71EE77CD5EF451F551FC9B2F53B65F01755A5DEF
574C57A957A1587E58BC58C558D15729572C572A57335739572E572F575C573B
574257695785576B5786577C577B5768576D5776577357AD57A4578C57B257CF
57A757B4579357A057D557D857DA57D957D257B857F457EF57F857E457DD0000
DC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000580B580D57FD57ED5800581E5819584458205865586C58815889589A5880
99A89F1961FF8279827D827F828F828A82A88284828E82918297829982AB82B8
82BE82B082C882CA82E3829882B782AE82CB82CC82C182A982B482A182AA829F
82C482CE82A482E1830982F782E4830F830782DC82F482D282D8830C82FB82D3
8311831A83068314831582E082D5831C8351835B835C83088392833C83348331
839B835E832F834F83478343835F834083178360832D833A8333836683650000
DD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008368831B8369836C836A836D836E83B0837883B383B483A083AA8393839C
8385837C83B683A9837D83B8837B8398839E83A883BA83BC83C1840183E583D8
58078418840B83DD83FD83D6841C84388411840683D483DF840F840383F883F9
83EA83C583C0842683F083E1845C8451845A8459847384878488847A84898478
843C844684698476848C848E8431846D84C184CD84D084E684BD84D384CA84BF
84BA84E084A184B984B4849784E584E3850C750D853884F08539851F853A0000
DE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008556853B84FF84FC8559854885688564855E857A77A285438572857B85A4
85A88587858F857985AE859C858585B985B785B085D385C185DC85FF86278605
86298616863C5EFE5F08593C594180375955595A5958530F5C225C255C2C5C34
624C626A629F62BB62CA62DA62D762EE632262F66339634B634363AD63F66371
637A638E63B4636D63AC638A636963AE63BC63F263F863E063FF63C463DE63CE
645263C663BE64456441640B641B6420640C64266421645E6484646D64960000
DF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000647A64B764B8649964BA64C064D064D764E464E265096525652E5F0B5FD2
75195F11535F53F153FD53E953E853FB541254165406544B5452545354545456
54435421545754595423543254825494547754715464549A549B548454765466
549D54D054AD54C254B454D254A754A654D354D4547254A354D554BB54BF54CC
54D954DA54DC54A954AA54A454DD54CF54DE551B54E7552054FD551454F35522
5523550F55115527552A5567558F55B55549556D55415555553F5550553C0000
E0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005537555655755576557755335530555C558B55D2558355B155B955885581
559F557E55D65591557B55DF55BD55BE5594559955EA55F755C9561F55D155EB
55EC55D455E655DD55C455EF55E555F255F355CC55CD55E855F555E48F94561E
5608560C56015624562355FE56005627562D565856395657562C564D56625659
565C564C5654568656645671566B567B567C5685569356AF56D456D756DD56E1
56F556EB56F956FF5704570A5709571C5E0F5E195E145E115E315E3B5E3C0000
E1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005E375E445E545E5B5E5E5E615C8C5C7A5C8D5C905C965C885C985C995C91
5C9A5C9C5CB55CA25CBD5CAC5CAB5CB15CA35CC15CB75CC45CD25CE45CCB5CE5
5D025D035D275D265D2E5D245D1E5D065D1B5D585D3E5D345D3D5D6C5D5B5D6F
5D5D5D6B5D4B5D4A5D695D745D825D995D9D8C735DB75DC55F735F775F825F87
5F895F8C5F955F995F9C5FA85FAD5FB55FBC88625F6172AD72B072B472B772B8
72C372C172CE72CD72D272E872EF72E972F272F472F7730172F3730372FA0000
E2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000072FB731773137321730A731E731D7315732273397325732C733873317350
734D73577360736C736F737E821B592598E7592459029963996799689969996A
996B996C99749977997D998099849987998A998D999099919993999499955E80
5E915E8B5E965EA55EA05EB95EB55EBE5EB38D535ED25ED15EDB5EE85EEA81BA
5FC45FC95FD65FCF60035FEE60045FE15FE45FFE600560065FEA5FED5FF86019
60356026601B600F600D6029602B600A603F602160786079607B607A60420000
E3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000606A607D6096609A60AD609D60836092608C609B60EC60BB60B160DD60D8
60C660DA60B4612061266115612360F46100610E612B614A617561AC619461A7
61B761D461F55FDD96B395E995EB95F195F395F595F695FC95FE960396049606
9608960A960B960C960D960F96129615961696179619961A4E2C723F62156C35
6C546C5C6C4A6CA36C856C906C946C8C6C686C696C746C766C866CA96CD06CD4
6CAD6CF76CF86CF16CD76CB26CE06CD66CFA6CEB6CEE6CB16CD36CEF6CFE0000
E4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D396D276D0C6D436D486D076D046D196D0E6D2B6D4D6D2E6D356D1A6D4F
6D526D546D336D916D6F6D9E6DA06D5E6D936D946D5C6D606D7C6D636E1A6DC7
6DC56DDE6E0E6DBF6DE06E116DE66DDD6DD96E166DAB6E0C6DAE6E2B6E6E6E4E
6E6B6EB26E5F6E866E536E546E326E256E446EDF6EB16E986EE06F2D6EE26EA5
6EA76EBD6EBB6EB76ED76EB46ECF6E8F6EC26E9F6F626F466F476F246F156EF9
6F2F6F366F4B6F746F2A6F096F296F896F8D6F8C6F786F726F7C6F7A6FD10000
E5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006FC96FA76FB96FB66FC26FE16FEE6FDE6FE06FEF701A7023701B70397035
704F705E5B805B845B955B935BA55BB8752F9A9E64345BE45BEE89305BF08E47
8B078FB68FD38FD58FE58FEE8FE48FE98FE68FF38FE890059004900B90269011
900D9016902190359036902D902F9044905190529050906890589062905B66B9
9074907D908290889083908B5F505F575F565F585C3B54AB5C505C595B715C63
5C667FBC5F2A5F295F2D82745F3C9B3B5C6E59815983598D59A959AA59A30000
E6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000599759CA59AB599E59A459D259B259AF59D759BE5A055A0659DD5A0859E3
59D859F95A0C5A095A325A345A115A235A135A405A675A4A5A555A3C5A625A75
80EC5AAA5A9B5A775A7A5ABE5AEB5AB25AD25AD45AB85AE05AE35AF15AD65AE6
5AD85ADC5B095B175B165B325B375B405C155C1C5B5A5B655B735B515B535B62
9A759A779A789A7A9A7F9A7D9A809A819A859A889A8A9A909A929A939A969A98
9A9B9A9C9A9D9A9F9AA09AA29AA39AA59AA77E9F7EA17EA37EA57EA87EA90000
E7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007EAD7EB07EBE7EC07EC17EC27EC97ECB7ECC7ED07ED47ED77EDB7EE07EE1
7EE87EEB7EEE7EEF7EF17EF27F0D7EF67EFA7EFB7EFE7F017F027F037F077F08
7F0B7F0C7F0F7F117F127F177F197F1C7F1B7F1F7F217F227F237F247F257F26
7F277F2A7F2B7F2C7F2D7F2F7F307F317F327F337F355E7A757F5DDB753E9095
738E739173AE73A2739F73CF73C273D173B773B373C073C973C873E573D9987C
740A73E973E773DE73BA73F2740F742A745B7426742574287430742E742C0000
E8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000741B741A7441745C7457745574597477746D747E749C748E748074817487
748B749E74A874A9749074A774D274BA97EA97EB97EC674C6753675E67486769
67A56787676A6773679867A7677567A8679E67AD678B6777677C67F0680967D8
680A67E967B0680C67D967B567DA67B367DD680067C367B867E2680E67C167FD
6832683368606861684E6862684468646883681D68556866684168676840683E
684A6849682968B5688F687468776893686B68C2696E68FC691F692068F90000
E9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000692468F0690B6901695768E369106971693969606942695D6984696B6980
69986978693469CC6987698869CE6989696669636979699B69A769BB69AB69AD
69D469B169C169CA69DF699569E0698D69FF6A2F69ED6A176A186A6569F26A44
6A3E6AA06A506A5B6A356A8E6A796A3D6A286A586A7C6A916A906AA96A976AAB
733773526B816B826B876B846B926B936B8D6B9A6B9B6BA16BAA8F6B8F6D8F71
8F728F738F758F768F788F778F798F7A8F7C8F7E8F818F828F848F878F8B0000
EA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008F8D8F8E8F8F8F988F9A8ECE620B6217621B621F6222622162256224622C
81E774EF74F474FF750F75117513653465EE65EF65F0660A6619677266036615
6600708566F7661D66346631663666358006665F66546641664F665666616657
66776684668C66A7669D66BE66DB66DC66E666E98D328D338D368D3B8D3D8D40
8D458D468D488D498D478D4D8D558D5989C789CA89CB89CC89CE89CF89D089D1
726E729F725D7266726F727E727F7284728B728D728F72926308633263B00000
EB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000643F64D880046BEA6BF36BFD6BF56BF96C056C076C066C0D6C156C186C19
6C1A6C216C296C246C2A6C3265356555656B724D72527256723086625216809F
809C809380BC670A80BD80B180AB80AD80B480B780E780E880E980EA80DB80C2
80C480D980CD80D7671080DD80EB80F180F480ED810D810E80F280FC67158112
8C5A8136811E812C811881328148814C815381748159815A817181608169817C
817D816D8167584D5AB58188818281916ED581A381AA81CC672681CA81BB0000
EC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000081C181A66B246B376B396B436B466B5998D198D298D398D598D998DA6BB3
5F406BC289F365909F51659365BC65C665C465C365CC65CE65D265D67080709C
7096709D70BB70C070B770AB70B170E870CA711071137116712F71317173715C
716871457172714A7178717A719871B371B571A871A071E071D471E771F9721D
7228706C7118716671B9623E623D624362486249793B794079467949795B795C
7953795A796279577960796F7967797A7985798A799A79A779B35FD15FD00000
ED
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000603C605D605A606760416059606360AB6106610D615D61A9619D61CB61D1
62068080807F6C936CF66DFC77F677F87800780978177818781165AB782D781C
781D7839783A783B781F783C7825782C78237829784E786D7856785778267850
7847784C786A789B7893789A7887789C78A178A378B278B978A578D478D978C9
78EC78F2790578F479137924791E79349F9B9EF99EFB9EFC76F17704770D76F9
77077708771A77227719772D7726773577387750775177477743775A77680000
EE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077627765777F778D777D7780778C7791779F77A077B077B577BD753A7540
754E754B7548755B7572757975837F587F617F5F8A487F687F747F717F797F81
7F7E76CD76E58832948594869487948B948A948C948D948F9490949494979495
949A949B949C94A394A494AB94AA94AD94AC94AF94B094B294B494B694B794B8
94B994BA94BC94BD94BF94C494C894C994CA94CB94CC94CD94CE94D094D194D2
94D594D694D794D994D894DB94DE94DF94E094E294E494E594E794E894EA0000
EF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000094E994EB94EE94EF94F394F494F594F794F994FC94FD94FF950395029506
95079509950A950D950E950F951295139514951595169518951B951D951E951F
9522952A952B9529952C953195329534953695379538953C953E953F95429535
9544954595469549954C954E954F9552955395549556955795589559955B955E
955F955D95619562956495659566956795689569956A956B956C956F95719572
9573953A77E777EC96C979D579ED79E379EB7A065D477A037A027A1E7A140000
F0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A397A377A519ECF99A57A707688768E7693769976A474DE74E0752C9E20
9E229E289E299E2A9E2B9E2C9E329E319E369E389E379E399E3A9E3E9E419E42
9E449E469E479E489E499E4B9E4C9E4E9E519E559E579E5A9E5B9E5C9E5E9E63
9E669E679E689E699E6A9E6B9E6C9E719E6D9E7375927594759675A0759D75AC
75A375B375B475B875C475B175B075C375C275D675CD75E375E875E675E475EB
75E7760375F175FC75FF761076007605760C7617760A76257618761576190000
F1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000761B763C762276207640762D7630763F76357643763E7633764D765E7654
765C7656766B766F7FCA7AE67A787A797A807A867A887A957AA67AA07AAC7AA8
7AAD7AB3886488698872887D887F888288A288C688B788BC88C988E288CE88E3
88E588F1891A88FC88E888FE88F0892189198913891B890A8934892B89368941
8966897B758B80E576B276B477DC801280148016801C80208022802580268027
802980288031800B803580438046804D80528069807189839878988098830000
F2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009889988C988D988F9894989A989B989E989F98A198A298A598A6864D8654
866C866E867F867A867C867B86A8868D868B86AC869D86A786A386AA869386A9
86B686C486B586CE86B086BA86B186AF86C986CF86B486E986F186F286ED86F3
86D0871386DE86F486DF86D886D18703870786F88708870A870D87098723873B
871E8725872E871A873E87488734873187298737873F87828722877D877E877B
87608770874C876E878B87538763877C876487598765879387AF87A887D20000
F3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000087C68788878587AD8797878387AB87E587AC87B587B387CB87D387BD87D1
87C087CA87DB87EA87E087EE8816881387FE880A881B88218839883C7F367F42
7F447F4582107AFA7AFD7B087B037B047B157B0A7B2B7B0F7B477B387B2A7B19
7B2E7B317B207B257B247B337B3E7B1E7B587B5A7B457B757B4C7B5D7B607B6E
7B7B7B627B727B717B907BA67BA77BB87BAC7B9D7BA87B857BAA7B9C7BA27BAB
7BB47BD17BC17BCC7BDD7BDA7BE57BE67BEA7C0C7BFE7BFC7C0F7C167C0B0000
F4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007C1F7C2A7C267C387C417C4081FE82018202820481EC8844822182228223
822D822F8228822B8238823B82338234823E82448249824B824F825A825F8268
887E8885888888D888DF895E7F9D7F9F7FA77FAF7FB07FB27C7C65497C917C9D
7C9C7C9E7CA27CB27CBC7CBD7CC17CC77CCC7CCD7CC87CC57CD77CE8826E66A8
7FBF7FCE7FD57FE57FE17FE67FE97FEE7FF37CF87D777DA67DAE7E477E9B9EB8
9EB48D738D848D948D918DB18D678D6D8C478C49914A9150914E914F91640000
F5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009162916191709169916F917D917E917291749179918C91859190918D9191
91A291A391AA91AD91AE91AF91B591B491BA8C559E7E8DB88DEB8E058E598E69
8DB58DBF8DBC8DBA8DC48DD68DD78DDA8DDE8DCE8DCF8DDB8DC68DEC8DF78DF8
8DE38DF98DFB8DE48E098DFD8E148E1D8E1F8E2C8E2E8E238E2F8E3A8E408E39
8E358E3D8E318E498E418E428E518E528E4A8E708E768E7C8E6F8E748E858E8F
8E948E908E9C8E9E8C788C828C8A8C858C988C94659B89D689DE89DA89DC0000
F6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000089E589EB89EF8A3E8B26975396E996F396EF970697019708970F970E972A
972D9730973E9F809F839F859F869F879F889F899F8A9F8C9EFE9F0B9F0D96B9
96BC96BD96CE96D277BF96E0928E92AE92C8933E936A93CA938F943E946B9C7F
9C829C859C869C879C887A239C8B9C8E9C909C919C929C949C959C9A9C9B9C9E
9C9F9CA09CA19CA29CA39CA59CA69CA79CA89CA99CAB9CAD9CAE9CB09CB19CB2
9CB39CB49CB59CB69CB79CBA9CBB9CBC9CBD9CC49CC59CC69CC79CCA9CCB0000
F7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009CCC9CCD9CCE9CCF9CD09CD39CD49CD59CD79CD89CD99CDC9CDD9CDF9CE2
977C978597919792979497AF97AB97A397B297B49AB19AB09AB79E589AB69ABA
9ABC9AC19AC09AC59AC29ACB9ACC9AD19B459B439B479B499B489B4D9B5198E8
990D992E995599549ADF9AE19AE69AEF9AEB9AFB9AED9AF99B089B0F9B139B1F
9B239EBD9EBE7E3B9E829E879E889E8B9E9293D69E9D9E9F9EDB9EDC9EDD9EE0
9EDF9EE29EE99EE79EE59EEA9EEF9F229F2C9F2F9F399F379F3D9F3E9F440000

Added library/encoding/euc-jp.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
# Encoding file: euc-jp, multi-byte
M
003F 0 79
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D0000008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8
FF3EFFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0F
FF3C301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3D
FF5BFF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D7
00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C70000
A2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000025C625A125A025B325B225BD25BC203B3012219221902191219330130000
00000000000000000000000000000000000000002208220B2286228722822283
222A2229000000000000000000000000000000002227222800AC21D221D42200
220300000000000000000000000000000000000000000000222022A523122202
220722612252226A226B221A223D221D2235222B222C00000000000000000000
00000000212B2030266F266D266A2020202100B6000000000000000025EF0000
A3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19000000000000000000000000
0000FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3A00000000000000000000
0000FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5A00000000000000000000
A4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000304130423043304430453046304730483049304A304B304C304D304E304F
3050305130523053305430553056305730583059305A305B305C305D305E305F
3060306130623063306430653066306730683069306A306B306C306D306E306F
3070307130723073307430753076307730783079307A307B307C307D307E307F
3080308130823083308430853086308730883089308A308B308C308D308E308F
3090309130923093000000000000000000000000000000000000000000000000
A5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000000
A6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000039103920393039403950396039703980399039A039B039C039D039E039F
03A003A103A303A403A503A603A703A803A90000000000000000000000000000
000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C303C403C503C603C703C803C90000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000004100411041204130414041504010416041704180419041A041B041C041D
041E041F0420042104220423042404250426042704280429042A042B042C042D
042E042F00000000000000000000000000000000000000000000000000000000
000004300431043204330434043504510436043704380439043A043B043C043D
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000000000
A8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000025002502250C251025182514251C252C25242534253C25012503250F2513
251B251725232533252B253B254B2520252F25282537253F251D253025252538
2542000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
B0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E9C55165A03963F54C0611B632859F690228475831C7A5060AA63E16E25
65ED846682A69BF56893572765A162715B9B59D0867B98F47D627DBE9B8E6216
7C9F88B75B895EB563096697684895C7978D674F4EE54F0A4F4D4F9D504956F2
593759D45A015C0960DF610F61706613690570BA754F757079FB7DAD7DEF80C3
840E88638B029055907A533B4E954EA557DF80B290C178EF4E0058F16EA29038
7A328328828B9C2F5141537054BD54E156E059FB5F1598F26DEB80E4852D0000
B1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009662967096A097FB540B53F35B8770CF7FBD8FC296E8536F9D5C7ABA4E11
789381FC6E26561855046B1D851A9C3B59E553A96D6674DC958F56424E91904B
96F2834F990C53E155B65B305F71662066F368046C386CF36D29745B76C87A4E
983482F1885B8A6092ED6DB275AB76CA99C560A68B018D8A95B2698E53AD5186
5712583059445BB45EF6602863A963F46CBF6F14708E7114715971D5733F7E01
827682D185979060925B9D1B586965BC6C5A752551F9592E59655F805FDC0000
B2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000062BC65FA6A2A6B276BB4738B7FC189569D2C9D0E9EC45CA16C96837B5104
5C4B61B681C6687672614E594FFA537860696E297A4F97F34E0B53164EEE4F55
4F3D4FA14F7352A053EF5609590F5AC15BB65BE179D16687679C67B66B4C6CB3
706B73C2798D79BE7A3C7B8782B182DB8304837783EF83D387668AB256298CA8
8FE6904E971E868A4FC45CE862117259753B81E582BD86FE8CC096C5991399D5
4ECB4F1A89E356DE584A58CA5EFB5FEB602A6094606261D0621262D065390000
B3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009B41666668B06D777070754C76867D7582A587F9958B968E8C9D51F152BE
591654B35BB35D16616869826DAF788D84CB88578A7293A79AB86D6C99A886D9
57A367FF86CE920E5283568754045ED362E164B9683C68386BBB737278BA7A6B
899A89D28D6B8F0390ED95A3969497695B665CB3697D984D984E639B7B206A2B
6A7F68B69C0D6F5F5272559D607062EC6D3B6E076ED1845B89108F444E149C39
53F6691B6A3A9784682A515C7AC384B291DC938C565B9D286822830584310000
B4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007CA5520882C574E64E7E4F8351A05BD2520A52D852E75DFB559A582A59E6
5B8C5B985BDB5E725E7960A3611F616361BE63DB656267D1685368FA6B3E6B53
6C576F226F976F4574B0751876E3770B7AFF7BA17C217DE97F367FF0809D8266
839E89B38ACC8CAB908494519593959195A2966597D3992882184E38542B5CB8
5DCC73A9764C773C5CA97FEB8D0B96C19811985498584F014F0E5371559C5668
57FA59475B095BC45C905E0C5E7E5FCC63EE673A65D765E2671F68CB68C40000
B5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006A5F5E306BC56C176C7D757F79485B637A007D005FBD898F8A188CB48D77
8ECC8F1D98E29A0E9B3C4E80507D510059935B9C622F628064EC6B3A72A07591
79477FA987FB8ABC8B7063AC83CA97A05409540355AB68546A588A7078276775
9ECD53745BA2811A865090064E184E454EC74F1153CA54385BAE5F1360256551
673D6C426C726CE3707874037A767AAE7B087D1A7CFE7D6665E7725B53BB5C45
5DE862D262E063196E20865A8A318DDD92F86F0179A69B5A4EA84EAB4EAC0000
B6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F9B4FA050D151477AF6517151F653545321537F53EB55AC58835CE15F37
5F4A602F6050606D631F65596A4B6CC172C272ED77EF80F881058208854E90F7
93E197FF99579A5A4EF051DD5C2D6681696D5C4066F26975738968507C8150C5
52E457475DFE932665A46B236B3D7434798179BD7B4B7DCA82B983CC887F895F
8B398FD191D1541F92804E5D503653E5533A72D7739677E982E68EAF99C699C8
99D25177611A865E55B07A7A50765BD3904796854E326ADB91E75C515C480000
B7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000063987A9F6C9397748F617AAA718A96887C8268177E706851936C52F2541B
85AB8A137FA48ECD90E15366888879414FC250BE521151445553572D73EA578B
59515F625F8460756176616761A963B2643A656C666F68426E1375667A3D7CFB
7D4C7D997E4B7F6B830E834A86CD8A088A638B668EFD981A9D8F82B88FCE9BE8
5287621F64836FC09699684150916B206C7A6F547A747D5088408A2367084EF6
503950265065517C5238526355A7570F58055ACC5EFA61B261F862F363720000
B8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000691C6A29727D72AC732E7814786F7D79770C80A9898B8B198CE28ED29063
9375967A98559A139E785143539F53B35E7B5F266E1B6E90738473FE7D438237
8A008AFA96504E4E500B53E4547C56FA59D15B645DF15EAB5F276238654567AF
6E5672D07CCA88B480A180E183F0864E8A878DE8923796C798679F134E944E92
4F0D53485449543E5A2F5F8C5FA1609F68A76A8E745A78818A9E8AA48B779190
4E5E9BC94EA44F7C4FAF501950165149516C529F52B952FE539A53E354110000
B9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000540E5589575157A2597D5B545B5D5B8F5DE55DE75DF75E785E835E9A5EB7
5F186052614C629762D863A7653B6602664366F4676D6821689769CB6C5F6D2A
6D696E2F6E9D75327687786C7A3F7CE07D057D187D5E7DB18015800380AF80B1
8154818F822A8352884C88618B1B8CA28CFC90CA91759271783F92FC95A4964D
980599999AD89D3B525B52AB53F7540858D562F76FE08C6A8F5F9EB9514B523B
544A56FD7A4091779D609ED273446F09817075115FFD60DA9AA872DB8FBC0000
BA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006B6498034ECA56F0576458BE5A5A606861C7660F6606683968B16DF775D5
7D3A826E9B424E9B4F5053C955065D6F5DE65DEE67FB6C99747378028A509396
88DF57505EA7632B50B550AC518D670054C9585E59BB5BB05F69624D63A1683D
6B736E08707D91C7728078157826796D658E7D3083DC88C18F09969B52645728
67507F6A8CA151B45742962A583A698A80B454B25D0E57FC78959DFA4F5C524A
548B643E6628671467F57A847B567D22932F685C9BAD7B395319518A52370000
BB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005BDF62F664AE64E6672D6BBA85A996D176909BD6634C93069BAB76BF6652
4E09509853C25C7160E864926563685F71E673CA75237B977E8286958B838CDB
9178991065AC66AB6B8B4ED54ED44F3A4F7F523A53F853F255E356DB58EB59CB
59C959FF5B505C4D5E025E2B5FD7601D6307652F5B5C65AF65BD65E8679D6B62
6B7B6C0F7345794979C17CF87D197D2B80A2810281F389968A5E8A698A668A8C
8AEE8CC78CDC96CC98FC6B6F4E8B4F3C4F8D51505B575BFA6148630166420000
BC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006B216ECB6CBB723E74BD75D478C1793A800C803381EA84948F9E6C509E7F
5F0F8B589D2B7AFA8EF85B8D96EB4E0353F157F759315AC95BA460896E7F6F06
75BE8CEA5B9F85007BE0507267F4829D5C61854A7E1E820E51995C0463688D66
659C716E793E7D1780058B1D8ECA906E86C790AA501F52FA5C3A6753707C7235
914C91C8932B82E55BC25F3160F94E3B53D65B88624B67316B8A72E973E07A2E
816B8DA391529996511253D7546A5BFF63886A397DAC970056DA53CE54680000
BD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005B975C315DDE4FEE610162FE6D3279C079CB7D427E4D7FD281ED821F8490
884689728B908E748F2F9031914B916C96C6919C4EC04F4F514553415F93620E
67D46C416E0B73637E2691CD928353D459195BBF6DD1795D7E2E7C9B587E719F
51FA88538FF04FCA5CFB662577AC7AE3821C99FF51C65FAA65EC696F6B896DF3
6E966F6476FE7D145DE190759187980651E6521D6240669166D96E1A5EB67DD2
7F7266F885AF85F78AF852A953D959735E8F5F90605592E4966450B7511F0000
BE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000052DD5320534753EC54E8554655315617596859BE5A3C5BB55C065C0F5C11
5C1A5E845E8A5EE05F70627F628462DB638C63776607660C662D6676677E68A2
6A1F6A356CBC6D886E096E58713C7126716775C77701785D7901796579F07AE0
7B117CA77D39809683D6848B8549885D88F38A1F8A3C8A548A738C618CDE91A4
9266937E9418969C97984E0A4E084E1E4E575197527057CE583458CC5B225E38
60C564FE676167566D4472B675737A6384B88B7291B89320563157F498FE0000
BF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000062ED690D6B9671ED7E548077827289E698DF87558FB15C3B4F384FE14FB5
55075A205BDD5BE95FC3614E632F65B0664B68EE699B6D786DF1753375B9771F
795E79E67D3381E382AF85AA89AA8A3A8EAB8F9B903291DD97074EBA4EC15203
587558EC5C0B751A5C3D814E8A0A8FC59663976D7B258ACF9808916256F353A8
9017543957825E2563A86C34708A77617C8B7FE088709042915493109318968F
745E9AC45D075D69657067A28DA896DB636E6749691983C5981796C088FE0000
C0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006F84647A5BF84E16702C755D662F51C4523652E259D35F8160276210653F
6574661F667468F268166B636E057272751F76DB7CBE805658F088FD897F8AA0
8A938ACB901D91929752975965897A0E810696BB5E2D60DC621A65A566146790
77F37A4D7C4D7E3E810A8CAC8D648DE18E5F78A9520762D963A5644262988A2D
7A837BC08AAC96EA7D76820C87494ED95148534353605BA35C025C165DDD6226
624764B0681368346CC96D456D1767D36F5C714E717D65CB7A7F7BAD7DDA0000
C1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007E4A7FA8817A821B823985A68A6E8CCE8DF59078907792AD929195839BAE
524D55846F387136516879857E5581B37CCE564C58515CA863AA66FE66FD695A
72D9758F758E790E795679DF7C977D207D4486078A34963B90619F2050E75275
53CC53E2500955AA58EE594F723D5B8B5C64531D60E360F3635C6383633F63BB
64CD65E966F95DE369CD69FD6F1571E54E8975E976F87A937CDF7DCF7D9C8061
83498358846C84BC85FB88C58D709001906D9397971C9A1250CF5897618E0000
C2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000081D385358D0890204FC3507452475373606F6349675F6E2C8DB3901F4FD7
5C5E8CCA65CF7D9A53528896517663C35B585B6B5C0A640D6751905C4ED6591A
592A6C708A51553E581559A560F0625367C182356955964099C49A284F535806
5BFE80105CB15E2F5F856020614B623466FF6CF06EDE80CE817F82D4888B8CB8
9000902E968A9EDB9BDB4EE353F059277B2C918D984C9DF96EDD702753535544
5B856258629E62D36CA26FEF74228A1794386FC18AFE833851E786F853EA0000
C3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000053E94F4690548FB0596A81315DFD7AEA8FBF68DA8C3772F89C486A3D8AB0
4E3953585606576662C563A265E66B4E6DE16E5B70AD77ED7AEF7BAA7DBB803D
80C686CB8A95935B56E358C75F3E65AD66966A806BB575378AC7502477E55730
5F1B6065667A6C6075F47A1A7F6E81F48718904599B37BC9755C7AF97B5184C4
901079E97A9283365AE177404E2D4EF25B995FE062BD663C67F16CE8866B8877
8A3B914E92F399D06A177026732A82E784578CAF4E01514651CB558B5BF50000
C4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005E165E335E815F145F355F6B5FB461F2631166A2671D6F6E7252753A773A
80748139817887768ABF8ADC8D858DF3929A957798029CE552C5635776F46715
6C8873CD8CC393AE96736D25589C690E69CC8FFD939A75DB901A585A680263B4
69FB4F436F2C67D88FBB85267DB49354693F6F70576A58F75B2C7D2C722A540A
91E39DB44EAD4F4E505C507552438C9E544858245B9A5E1D5E955EAD5EF75F1F
608C62B5633A63D068AF6C407887798E7A0B7DE082478A028AE68E4490130000
C5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000090B8912D91D89F0E6CE5645864E265756EF476847B1B906993D16EBA54F2
5FB964A48F4D8FED92445178586B59295C555E976DFB7E8F751C8CBC8EE2985B
70B94F1D6BBF6FB1753096FB514E54105835585759AC5C605F926597675C6E21
767B83DF8CED901490FD934D7825783A52AA5EA6571F597460125012515A51AC
51CD520055105854585859575B955CF65D8B60BC6295642D6771684368BC68DF
76D76DD86E6F6D9B706F71C85F5375D879777B497B547B527CD67D7152300000
C6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008463856985E48A0E8B048C468E0F9003900F94199676982D9A3095D850CD
52D5540C58025C0E61A7649E6D1E77B37AE580F48404905392855CE09D07533F
5F975FB36D9C7279776379BF7BE46BD272EC8AAD68036A6151F87A8169345C4A
9CF682EB5BC59149701E56785C6F60C765666C8C8C5A90419813545166C7920D
594890A351854E4D51EA85998B0E7058637A934B696299B47E04757753576960
8EDF96E36C5D4E8C5C3C5F108FE953028CD1808986795EFF65E54E7351650000
C7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000059825C3F97EE4EFB598A5FCD8A8D6FE179B079625BE78471732B71B15E74
5FF5637B649A71C37C984E435EFC4E4B57DC56A260A96FC37D0D80FD813381BF
8FB2899786A45DF4628A64AD898767776CE26D3E743678345A467F7582AD99AC
4FF35EC362DD63926557676F76C3724C80CC80BA8F29914D500D57F95A926885
6973716472FD8CB758F28CE0966A9019877F79E477E784294F2F5265535A62CD
67CF6CCA767D7B947C95823685848FEB66DD6F2072067E1B83AB99C19EA60000
C8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000051FD7BB178727BB880877B486AE85E61808C75517560516B92626E8C767A
91979AEA4F107F70629C7B4F95A59CE9567A585986E496BC4F345224534A53CD
53DB5E06642C6591677F6C3E6C4E724872AF73ED75547E41822C85E98CA97BC4
91C67169981298EF633D6669756A76E478D0854386EE532A5351542659835E87
5F7C60B26249627962AB65906BD46CCC75B276AE789179D87DCB7F7780A588AB
8AB98CBB907F975E98DB6A0B7C3850995C3E5FAE67876BD8743577097F8E0000
C9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009F3B67CA7A175339758B9AED5F66819D83F180985F3C5FC575627B46903C
686759EB5A9B7D10767E8B2C4FF55F6A6A196C376F0274E2796888688A558C79
5EDF63CF75C579D282D7932892F2849C86ED9C2D54C15F6C658C6D5C70158CA7
8CD3983B654F74F64E0D4ED857E0592B5A665BCC51A85E035E9C601662766577
65A7666E6D6E72367B268150819A82998B5C8CA08CE68D74961C96444FAE64AB
6B66821E8461856A90E85C01695398A8847A85574F0F526F5FA95E45670D0000
CA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000798F8179890789866DF55F1762556CB84ECF72699B925206543B567458B3
61A4626E711A596E7C897CDE7D1B96F06587805E4E194F75517558405E635E73
5F0A67C44E26853D9589965B7C73980150FB58C1765678A7522577A585117B86
504F590972477BC77DE88FBA8FD4904D4FBF52C95A295F0197AD4FDD821792EA
570363556B69752B88DC8F147A4252DF58936155620A66AE6BCD7C3F83E95023
4FF853055446583159495B9D5CF05CEF5D295E9662B16367653E65B9670B0000
CB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006CD56CE170F978327E2B80DE82B3840C84EC870289128A2A8C4A90A692D2
98FD9CF39D6C4E4F4EA1508D5256574A59A85E3D5FD85FD9623F66B4671B67D0
68D251927D2180AA81A88B008C8C8CBF927E96325420982C531750D5535C58A8
64B26734726777667A4691E652C36CA16B8658005E4C5954672C7FFB51E176C6
646978E89B549EBB57CB59B96627679A6BCE54E969D95E55819C67959BAA67FE
9C52685D4EA64FE353C862B9672B6CAB8FC44FAD7E6D9EBF4E0761626E800000
CC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006F2B85135473672A9B455DF37B955CAC5BC6871C6E4A84D17A1481085999
7C8D6C11772052D959227121725F77DB97279D61690B5A7F5A1851A5540D547D
660E76DF8FF792989CF459EA725D6EC5514D68C97DBF7DEC97629EBA64786A21
830259845B5F6BDB731B76F27DB280178499513267289ED976EE676252FF9905
5C24623B7C7E8CB0554F60B67D0B958053014E5F51B6591C723A803691CE5F25
77E253845F797D0485AC8A338E8D975667F385AE9453610961086CB976520000
CD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008AED8F38552F4F51512A52C753CB5BA55E7D60A0618263D6670967DA6E67
6D8C733673377531795088D58A98904A909190F596C4878D59154E884F594E0E
8A898F3F981050AD5E7C59965BB95EB863DA63FA64C166DC694A69D86D0B6EB6
719475287AAF7F8A8000844984C989818B218E0A9065967D990A617E62916B32
6C836D747FCC7FFC6DC07F8587BA88F8676583B1983C96F76D1B7D61843D916A
4E7153755D506B046FEB85CD862D89A75229540F5C65674E68A8740674830000
CE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075E288CF88E191CC96E296785F8B73877ACB844E63A0756552896D416E9C
74097559786B7C9296867ADC9F8D4FB6616E65C5865C4E864EAE50DA4E2151CC
5BEE659968816DBC731F764277AD7A1C7CE7826F8AD2907C91CF96759818529B
7DD1502B539867976DCB71D0743381E88F2A96A39C579E9F746058416D997D2F
985E4EE44F364F8B51B752B15DBA601C73B2793C82D3923496B796F6970A9E97
9F6266A66B74521752A370C888C25EC9604B61906F2371497C3E7DF4806F0000
CF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000084EE9023932C54429B6F6AD370898CC28DEF973252B45A415ECA5F046717
697C69946D6A6F0F726272FC7BED8001807E874B90CE516D9E937984808B9332
8AD6502D548C8A716B6A8CC4810760D167A09DF24E994E989C108A6B85C18568
69006E7E78978155000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
D0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F0C4E104E154E2A4E314E364E3C4E3F4E424E564E584E824E858C6B4E8A
82125F0D4E8E4E9E4E9F4EA04EA24EB04EB34EB64ECE4ECD4EC44EC64EC24ED7
4EDE4EED4EDF4EF74F094F5A4F304F5B4F5D4F574F474F764F884F8F4F984F7B
4F694F704F914F6F4F864F9651184FD44FDF4FCE4FD84FDB4FD14FDA4FD04FE4
4FE5501A50285014502A502550054F1C4FF650215029502C4FFE4FEF50115006
504350476703505550505048505A5056506C50785080509A508550B450B20000
D1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000050C950CA50B350C250D650DE50E550ED50E350EE50F950F5510951015102
511651155114511A5121513A5137513C513B513F51405152514C515451627AF8
5169516A516E5180518256D8518C5189518F519151935195519651A451A651A2
51A951AA51AB51B351B151B251B051B551BD51C551C951DB51E0865551E951ED
51F051F551FE5204520B5214520E5227522A522E52335239524F5244524B524C
525E5254526A527452695273527F527D528D529452925271528852918FA80000
D2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008FA752AC52AD52BC52B552C152CD52D752DE52E352E698ED52E052F352F5
52F852F9530653087538530D5310530F5315531A5323532F5331533353385340
534653454E175349534D51D6535E5369536E5918537B53775382539653A053A6
53A553AE53B053B653C37C1296D953DF66FC71EE53EE53E853ED53FA5401543D
5440542C542D543C542E54365429541D544E548F5475548E545F547154775470
5492547B5480547654845490548654C754A254B854A554AC54C454C854A80000
D3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054AB54C254A454BE54BC54D854E554E6550F551454FD54EE54ED54FA54E2
553955405563554C552E555C55455556555755385533555D5599558054AF558A
559F557B557E5598559E55AE557C558355A9558755A855DA55C555DF55C455DC
55E455D4561455F7561655FE55FD561B55F9564E565071DF5634563656325638
566B5664562F566C566A56865680568A56A05694568F56A556AE56B656B456C2
56BC56C156C356C056C856CE56D156D356D756EE56F9570056FF570457090000
D4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005708570B570D57135718571655C7571C572657375738574E573B5740574F
576957C057885761577F5789579357A057B357A457AA57B057C357C657D457D2
57D3580A57D657E3580B5819581D587258215862584B58706BC05852583D5879
588558B9589F58AB58BA58DE58BB58B858AE58C558D358D158D758D958D858E5
58DC58E458DF58EF58FA58F958FB58FC58FD5902590A5910591B68A65925592C
592D59325938593E7AD259555950594E595A5958596259605967596C59690000
D5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000059785981599D4F5E4FAB59A359B259C659E859DC598D59D959DA5A255A1F
5A115A1C5A095A1A5A405A6C5A495A355A365A625A6A5A9A5ABC5ABE5ACB5AC2
5ABD5AE35AD75AE65AE95AD65AFA5AFB5B0C5B0B5B165B325AD05B2A5B365B3E
5B435B455B405B515B555B5A5B5B5B655B695B705B735B755B7865885B7A5B80
5B835BA65BB85BC35BC75BC95BD45BD05BE45BE65BE25BDE5BE55BEB5BF05BF6
5BF35C055C075C085C0D5C135C205C225C285C385C395C415C465C4E5C530000
D6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005C505C4F5B715C6C5C6E4E625C765C795C8C5C915C94599B5CAB5CBB5CB6
5CBC5CB75CC55CBE5CC75CD95CE95CFD5CFA5CED5D8C5CEA5D0B5D155D175D5C
5D1F5D1B5D115D145D225D1A5D195D185D4C5D525D4E5D4B5D6C5D735D765D87
5D845D825DA25D9D5DAC5DAE5DBD5D905DB75DBC5DC95DCD5DD35DD25DD65DDB
5DEB5DF25DF55E0B5E1A5E195E115E1B5E365E375E445E435E405E4E5E575E54
5E5F5E625E645E475E755E765E7A9EBC5E7F5EA05EC15EC25EC85ED05ECF0000
D7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005ED65EE35EDD5EDA5EDB5EE25EE15EE85EE95EEC5EF15EF35EF05EF45EF8
5EFE5F035F095F5D5F5C5F0B5F115F165F295F2D5F385F415F485F4C5F4E5F2F
5F515F565F575F595F615F6D5F735F775F835F825F7F5F8A5F885F915F875F9E
5F995F985FA05FA85FAD5FBC5FD65FFB5FE45FF85FF15FDD60B35FFF60216060
601960106029600E6031601B6015602B6026600F603A605A6041606A6077605F
604A6046604D6063604360646042606C606B60596081608D60E76083609A0000
D8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006084609B60966097609260A7608B60E160B860E060D360B45FF060BD60C6
60B560D8614D6115610660F660F7610060F460FA6103612160FB60F1610D610E
6147613E61286127614A613F613C612C6134613D614261446173617761586159
615A616B6174616F61656171615F615D6153617561996196618761AC6194619A
618A619161AB61AE61CC61CA61C961F761C861C361C661BA61CB7F7961CD61E6
61E361F661FA61F461FF61FD61FC61FE620062086209620D620C6214621B0000
D9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000621E6221622A622E6230623262336241624E625E6263625B62606268627C
62826289627E62926293629662D46283629462D762D162BB62CF62FF62C664D4
62C862DC62CC62CA62C262C7629B62C9630C62EE62F163276302630862EF62F5
6350633E634D641C634F6396638E638063AB637663A3638F6389639F63B5636B
636963BE63E963C063C663E363C963D263F663C4641664346406641364266436
651D64176428640F6467646F6476644E652A6495649364A564A9648864BC0000
DA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000064DA64D264C564C764BB64D864C264F164E7820964E064E162AC64E364EF
652C64F664F464F264FA650064FD6518651C650565246523652B653465356537
65366538754B654865566555654D6558655E655D65726578658265838B8A659B
659F65AB65B765C365C665C165C465CC65D265DB65D965E065E165F16772660A
660365FB6773663566366634661C664F664466496641665E665D666466676668
665F6662667066836688668E668966846698669D66C166B966C966BE66BC0000
DB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000066C466B866D666DA66E0663F66E666E966F066F566F7670F6716671E6726
67279738672E673F67366741673867376746675E676067596763676467896770
67A9677C676A678C678B67A667A1678567B767EF67B467EC67B367E967B867E4
67DE67DD67E267EE67B967CE67C667E76A9C681E684668296840684D6832684E
68B3682B685968636877687F689F688F68AD6894689D689B68836AAE68B96874
68B568A068BA690F688D687E690168CA690868D86922692668E1690C68CD0000
DC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000068D468E768D569366912690468D768E3692568F968E068EF6928692A691A
6923692168C669796977695C6978696B6954697E696E69396974693D69596930
6961695E695D6981696A69B269AE69D069BF69C169D369BE69CE5BE869CA69DD
69BB69C369A76A2E699169A0699C699569B469DE69E86A026A1B69FF6B0A69F9
69F269E76A0569B16A1E69ED6A1469EB6A0A6A126AC16A236A136A446A0C6A72
6A366A786A476A626A596A666A486A386A226A906A8D6AA06A846AA26AA30000
DD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006A9786176ABB6AC36AC26AB86AB36AAC6ADE6AD16ADF6AAA6ADA6AEA6AFB
6B0586166AFA6B126B169B316B1F6B386B3776DC6B3998EE6B476B436B496B50
6B596B546B5B6B5F6B616B786B796B7F6B806B846B836B8D6B986B956B9E6BA4
6BAA6BAB6BAF6BB26BB16BB36BB76BBC6BC66BCB6BD36BDF6BEC6BEB6BF36BEF
9EBE6C086C136C146C1B6C246C236C5E6C556C626C6A6C826C8D6C9A6C816C9B
6C7E6C686C736C926C906CC46CF16CD36CBD6CD76CC56CDD6CAE6CB16CBE0000
DE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006CBA6CDB6CEF6CD96CEA6D1F884D6D366D2B6D3D6D386D196D356D336D12
6D0C6D636D936D646D5A6D796D596D8E6D956FE46D856DF96E156E0A6DB56DC7
6DE66DB86DC66DEC6DDE6DCC6DE86DD26DC56DFA6DD96DE46DD56DEA6DEE6E2D
6E6E6E2E6E196E726E5F6E3E6E236E6B6E2B6E766E4D6E1F6E436E3A6E4E6E24
6EFF6E1D6E386E826EAA6E986EC96EB76ED36EBD6EAF6EC46EB26ED46ED56E8F
6EA56EC26E9F6F416F11704C6EEC6EF86EFE6F3F6EF26F316EEF6F326ECC0000
DF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006F3E6F136EF76F866F7A6F786F816F806F6F6F5B6FF36F6D6F826F7C6F58
6F8E6F916FC26F666FB36FA36FA16FA46FB96FC66FAA6FDF6FD56FEC6FD46FD8
6FF16FEE6FDB7009700B6FFA70117001700F6FFE701B701A6F74701D7018701F
7030703E7032705170637099709270AF70F170AC70B870B370AE70DF70CB70DD
70D9710970FD711C711971657155718871667162714C7156716C718F71FB7184
719571A871AC71D771B971BE71D271C971D471CE71E071EC71E771F571FC0000
E0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000071F971FF720D7210721B7228722D722C72307232723B723C723F72407246
724B72587274727E7282728172877292729672A272A772B972B272C372C672C4
72CE72D272E272E072E172F972F7500F7317730A731C7316731D7334732F7329
7325733E734E734F9ED87357736A7368737073787375737B737A73C873B373CE
73BB73C073E573EE73DE74A27405746F742573F87432743A7455743F745F7459
7441745C746974707463746A7476747E748B749E74A774CA74CF74D473F10000
E1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000074E074E374E774E974EE74F274F074F174F874F7750475037505750C750E
750D75157513751E7526752C753C7544754D754A7549755B7546755A75697564
7567756B756D75787576758675877574758A758975827594759A759D75A575A3
75C275B375C375B575BD75B875BC75B175CD75CA75D275D975E375DE75FE75FF
75FC760175F075FA75F275F3760B760D7609761F762776207621762276247634
7630763B764776487646765C76587661766276687669766A7667766C76700000
E2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000767276767678767C768076837688768B768E769676937699769A76B076B4
76B876B976BA76C276CD76D676D276DE76E176E576E776EA862F76FB77087707
770477297724771E77257726771B773777387747775A7768776B775B7765777F
777E7779778E778B779177A0779E77B077B677B977BF77BC77BD77BB77C777CD
77D777DA77DC77E377EE77FC780C781279267820792A7845788E78747886787C
789A788C78A378B578AA78AF78D178C678CB78D478BE78BC78C578CA78EC0000
E3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000078E778DA78FD78F47907791279117919792C792B794079607957795F795A
79557953797A797F798A799D79A79F4B79AA79AE79B379B979BA79C979D579E7
79EC79E179E37A087A0D7A187A197A207A1F79807A317A3B7A3E7A377A437A57
7A497A617A627A699F9D7A707A797A7D7A887A977A957A987A967AA97AC87AB0
7AB67AC57AC47ABF90837AC77ACA7ACD7ACF7AD57AD37AD97ADA7ADD7AE17AE2
7AE67AED7AF07B027B0F7B0A7B067B337B187B197B1E7B357B287B367B500000
E4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007B7A7B047B4D7B0B7B4C7B457B757B657B747B677B707B717B6C7B6E7B9D
7B987B9F7B8D7B9C7B9A7B8B7B927B8F7B5D7B997BCB7BC17BCC7BCF7BB47BC6
7BDD7BE97C117C147BE67BE57C607C007C077C137BF37BF77C177C0D7BF67C23
7C277C2A7C1F7C377C2B7C3D7C4C7C437C547C4F7C407C507C587C5F7C647C56
7C657C6C7C757C837C907CA47CAD7CA27CAB7CA17CA87CB37CB27CB17CAE7CB9
7CBD7CC07CC57CC27CD87CD27CDC7CE29B3B7CEF7CF27CF47CF67CFA7D060000
E5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007D027D1C7D157D0A7D457D4B7D2E7D327D3F7D357D467D737D567D4E7D72
7D687D6E7D4F7D637D937D897D5B7D8F7D7D7D9B7DBA7DAE7DA37DB57DC77DBD
7DAB7E3D7DA27DAF7DDC7DB87D9F7DB07DD87DDD7DE47DDE7DFB7DF27DE17E05
7E0A7E237E217E127E317E1F7E097E0B7E227E467E667E3B7E357E397E437E37
7E327E3A7E677E5D7E567E5E7E597E5A7E797E6A7E697E7C7E7B7E837DD57E7D
8FAE7E7F7E887E897E8C7E927E907E937E947E967E8E7E9B7E9C7F387F3A0000
E6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007F457F4C7F4D7F4E7F507F517F557F547F587F5F7F607F687F697F677F78
7F827F867F837F887F877F8C7F947F9E7F9D7F9A7FA37FAF7FB27FB97FAE7FB6
7FB88B717FC57FC67FCA7FD57FD47FE17FE67FE97FF37FF998DC80068004800B
801280188019801C80218028803F803B804A804680528058805A805F80628068
80738072807080768079807D807F808480868085809B8093809A80AD519080AC
80DB80E580D980DD80C480DA80D6810980EF80F1811B81298123812F814B0000
E7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000968B8146813E8153815180FC8171816E81658166817481838188818A8180
818281A0819581A481A3815F819381A981B081B581BE81B881BD81C081C281BA
81C981CD81D181D981D881C881DA81DF81E081E781FA81FB81FE820182028205
8207820A820D821082168229822B82388233824082598258825D825A825F8264
82628268826A826B822E827182778278827E828D829282AB829F82BB82AC82E1
82E382DF82D282F482F382FA8393830382FB82F982DE830682DC830982D90000
E8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000833583348316833283318340833983508345832F832B831783188385839A
83AA839F83A283968323838E8387838A837C83B58373837583A0838983A883F4
841383EB83CE83FD840383D8840B83C183F7840783E083F2840D8422842083BD
8438850683FB846D842A843C855A84848477846B84AD846E848284698446842C
846F8479843584CA846284B984BF849F84D984CD84BB84DA84D084C184C684D6
84A1852184FF84F485178518852C851F8515851484FC85408563855885480000
E9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000085418602854B8555858085A485888591858A85A8856D8594859B85EA8587
859C8577857E859085C985BA85CF85B985D085D585DD85E585DC85F9860A8613
860B85FE85FA86068622861A8630863F864D4E558654865F86678671869386A3
86A986AA868B868C86B686AF86C486C686B086C9882386AB86D486DE86E986EC
86DF86DB86EF8712870687088700870386FB87118709870D86F9870A8734873F
8737873B87258729871A8760875F8778874C874E877487578768876E87590000
EA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000087538763876A880587A2879F878287AF87CB87BD87C087D096D687AB87C4
87B387C787C687BB87EF87F287E0880F880D87FE87F687F7880E87D288118816
8815882288218831883688398827883B8844884288528859885E8862886B8881
887E889E8875887D88B5887288828897889288AE889988A2888D88A488B088BF
88B188C388C488D488D888D988DD88F9890288FC88F488E888F28904890C890A
89138943891E8925892A892B89418944893B89368938894C891D8960895E0000
EB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000089668964896D896A896F89748977897E89838988898A8993899889A189A9
89A689AC89AF89B289BA89BD89BF89C089DA89DC89DD89E789F489F88A038A16
8A108A0C8A1B8A1D8A258A368A418A5B8A528A468A488A7C8A6D8A6C8A628A85
8A828A848AA88AA18A918AA58AA68A9A8AA38AC48ACD8AC28ADA8AEB8AF38AE7
8AE48AF18B148AE08AE28AF78ADE8ADB8B0C8B078B1A8AE18B168B108B178B20
8B3397AB8B268B2B8B3E8B288B418B4C8B4F8B4E8B498B568B5B8B5A8B6B0000
EC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008B5F8B6C8B6F8B748B7D8B808B8C8B8E8B928B938B968B998B9A8C3A8C41
8C3F8C488C4C8C4E8C508C558C628C6C8C788C7A8C828C898C858C8A8C8D8C8E
8C948C7C8C98621D8CAD8CAA8CBD8CB28CB38CAE8CB68CC88CC18CE48CE38CDA
8CFD8CFA8CFB8D048D058D0A8D078D0F8D0D8D109F4E8D138CCD8D148D168D67
8D6D8D718D738D818D998DC28DBE8DBA8DCF8DDA8DD68DCC8DDB8DCB8DEA8DEB
8DDF8DE38DFC8E088E098DFF8E1D8E1E8E108E1F8E428E358E308E348E4A0000
ED
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008E478E498E4C8E508E488E598E648E608E2A8E638E558E768E728E7C8E81
8E878E858E848E8B8E8A8E938E918E948E998EAA8EA18EAC8EB08EC68EB18EBE
8EC58EC88ECB8EDB8EE38EFC8EFB8EEB8EFE8F0A8F058F158F128F198F138F1C
8F1F8F1B8F0C8F268F338F3B8F398F458F428F3E8F4C8F498F468F4E8F578F5C
8F628F638F648F9C8F9F8FA38FAD8FAF8FB78FDA8FE58FE28FEA8FEF90878FF4
90058FF98FFA901190159021900D901E9016900B90279036903590398FF80000
EE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000904F905090519052900E9049903E90569058905E9068906F907696A89072
9082907D90819080908A9089908F90A890AF90B190B590E290E4624890DB9102
9112911991329130914A9156915891639165916991739172918B9189918291A2
91AB91AF91AA91B591B491BA91C091C191C991CB91D091D691DF91E191DB91FC
91F591F6921E91FF9214922C92159211925E925792459249926492489295923F
924B9250929C92969293929B925A92CF92B992B792E9930F92FA9344932E0000
EF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000093199322931A9323933A9335933B935C9360937C936E935693B093AC93AD
939493B993D693D793E893E593D893C393DD93D093C893E4941A941494139403
940794109436942B94359421943A944194529444945B94609462945E946A9229
947094759477947D945A947C947E9481947F95829587958A9594959695989599
95A095A895A795AD95BC95BB95B995BE95CA6FF695C395CD95CC95D595D495D6
95DC95E195E595E296219628962E962F9642964C964F964B9677965C965E0000
F0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000965D965F96669672966C968D96989695969796AA96A796B196B296B096B4
96B696B896B996CE96CB96C996CD894D96DC970D96D596F99704970697089713
970E9711970F971697199724972A97309739973D973E97449746974897429749
975C976097649766976852D2976B977197799785977C9781977A9786978B978F
9790979C97A897A697A397B397B497C397C697C897CB97DC97ED9F4F97F27ADF
97F697F5980F980C9838982498219837983D9846984F984B986B986F98700000
F1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000098719874987398AA98AF98B198B698C498C398C698E998EB990399099912
991499189921991D991E99249920992C992E993D993E9942994999459950994B
99519952994C99559997999899A599AD99AE99BC99DF99DB99DD99D899D199ED
99EE99F199F299FB99F89A019A0F9A0599E29A199A2B9A379A459A429A409A43
9A3E9A559A4D9A5B9A579A5F9A629A659A649A699A6B9A6A9AAD9AB09ABC9AC0
9ACF9AD19AD39AD49ADE9ADF9AE29AE39AE69AEF9AEB9AEE9AF49AF19AF70000
F2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009AFB9B069B189B1A9B1F9B229B239B259B279B289B299B2A9B2E9B2F9B32
9B449B439B4F9B4D9B4E9B519B589B749B939B839B919B969B979B9F9BA09BA8
9BB49BC09BCA9BB99BC69BCF9BD19BD29BE39BE29BE49BD49BE19C3A9BF29BF1
9BF09C159C149C099C139C0C9C069C089C129C0A9C049C2E9C1B9C259C249C21
9C309C479C329C469C3E9C5A9C609C679C769C789CE79CEC9CF09D099D089CEB
9D039D069D2A9D269DAF9D239D1F9D449D159D129D419D3F9D3E9D469D480000
F3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009D5D9D5E9D649D519D509D599D729D899D879DAB9D6F9D7A9D9A9DA49DA9
9DB29DC49DC19DBB9DB89DBA9DC69DCF9DC29DD99DD39DF89DE69DED9DEF9DFD
9E1A9E1B9E1E9E759E799E7D9E819E889E8B9E8C9E929E959E919E9D9EA59EA9
9EB89EAA9EAD97619ECC9ECE9ECF9ED09ED49EDC9EDE9EDD9EE09EE59EE89EEF
9EF49EF69EF79EF99EFB9EFC9EFD9F079F0876B79F159F219F2C9F3E9F4A9F52
9F549F639F5F9F609F619F669F679F6C9F6A9F779F729F769F959F9C9FA00000
F4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000582F69C79059746451DC7199000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/euc-kr.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
# Encoding file: euc-kr, multi-byte
M
003F 0 90
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030003001300200B72025202600A8300300AD20152225FF3C223C20182019
201C201D3014301530083009300A300B300C300D300E300F3010301100B100D7
00F7226022642265221E223400B0203220332103212BFFE0FFE1FFE526422640
222022A52312220222072261225200A7203B2606260525CB25CF25CE25C725C6
25A125A025B325B225BD25BC219221902191219321943013226A226B221A223D
221D2235222B222C2208220B2286228722822283222A222922272228FFE20000
A2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000021D221D42200220300B4FF5E02C702D802DD02DA02D900B802DB00A100BF
02D0222E2211220F00A42109203025C125C025B725B626642660266126652667
2663229925C825A325D025D1259225A425A525A825A725A625A92668260F260E
261C261E00B62020202121952197219921962198266D2669266A266C327F321C
211633C7212233C233D821210000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF01FF02FF03FF04FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFFE6FF3DFF3EFF3F
FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
A4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000313131323133313431353136313731383139313A313B313C313D313E313F
3140314131423143314431453146314731483149314A314B314C314D314E314F
3150315131523153315431553156315731583159315A315B315C315D315E315F
3160316131623163316431653166316731683169316A316B316C316D316E316F
3170317131723173317431753176317731783179317A317B317C317D317E317F
3180318131823183318431853186318731883189318A318B318C318D318E0000
A5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000217021712172217321742175217621772178217900000000000000000000
2160216121622163216421652166216721682169000000000000000000000000
0000039103920393039403950396039703980399039A039B039C039D039E039F
03A003A103A303A403A503A603A703A803A90000000000000000000000000000
000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C303C403C503C603C703C803C90000000000000000000000000000
A6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000025002502250C251025182514251C252C25242534253C25012503250F2513
251B251725232533252B253B254B2520252F25282537253F251D253025252538
254225122511251A251925162515250E250D251E251F25212522252625272529
252A252D252E25312532253525362539253A253D253E25402541254325442545
2546254725482549254A00000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
A7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00003395339633972113339833C433A333A433A533A63399339A339B339C339D
339E339F33A033A133A233CA338D338E338F33CF3388338933C833A733A833B0
33B133B233B333B433B533B633B733B833B93380338133823383338433BA33BB
33BC33BD33BE33BF33903391339233933394212633C033C1338A338B338C33D6
33C533AD33AE33AF33DB33A933AA33AB33AC33DD33D033D333C333C933DC33C6
0000000000000000000000000000000000000000000000000000000000000000
A8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000C600D000AA0126000001320000013F014100D8015200BA00DE0166014A
00003260326132623263326432653266326732683269326A326B326C326D326E
326F3270327132723273327432753276327732783279327A327B24D024D124D2
24D324D424D524D624D724D824D924DA24DB24DC24DD24DE24DF24E024E124E2
24E324E424E524E624E724E824E9246024612462246324642465246624672468
2469246A246B246C246D246E00BD2153215400BC00BE215B215C215D215E0000
A9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000E6011100F001270131013301380140014200F8015300DF00FE0167014B
01493200320132023203320432053206320732083209320A320B320C320D320E
320F3210321132123213321432153216321732183219321A321B249C249D249E
249F24A024A124A224A324A424A524A624A724A824A924AA24AB24AC24AD24AE
24AF24B024B124B224B324B424B5247424752476247724782479247A247B247C
247D247E247F24802481248200B900B200B32074207F20812082208320840000
AA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000304130423043304430453046304730483049304A304B304C304D304E304F
3050305130523053305430553056305730583059305A305B305C305D305E305F
3060306130623063306430653066306730683069306A306B306C306D306E306F
3070307130723073307430753076307730783079307A307B307C307D307E307F
3080308130823083308430853086308730883089308A308B308C308D308E308F
3090309130923093000000000000000000000000000000000000000000000000
AB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000000
AC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000004100411041204130414041504010416041704180419041A041B041C041D
041E041F0420042104220423042404250426042704280429042A042B042C042D
042E042F00000000000000000000000000000000000000000000000000000000
000004300431043204330434043504510436043704380439043A043B043C043D
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000000000
B0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000AC00AC01AC04AC07AC08AC09AC0AAC10AC11AC12AC13AC14AC15AC16AC17
AC19AC1AAC1BAC1CAC1DAC20AC24AC2CAC2DAC2FAC30AC31AC38AC39AC3CAC40
AC4BAC4DAC54AC58AC5CAC70AC71AC74AC77AC78AC7AAC80AC81AC83AC84AC85
AC86AC89AC8AAC8BAC8CAC90AC94AC9CAC9DAC9FACA0ACA1ACA8ACA9ACAAACAC
ACAFACB0ACB8ACB9ACBBACBCACBDACC1ACC4ACC8ACCCACD5ACD7ACE0ACE1ACE4
ACE7ACE8ACEAACECACEFACF0ACF1ACF3ACF5ACF6ACFCACFDAD00AD04AD060000
B1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000AD0CAD0DAD0FAD11AD18AD1CAD20AD29AD2CAD2DAD34AD35AD38AD3CAD44
AD45AD47AD49AD50AD54AD58AD61AD63AD6CAD6DAD70AD73AD74AD75AD76AD7B
AD7CAD7DAD7FAD81AD82AD88AD89AD8CAD90AD9CAD9DADA4ADB7ADC0ADC1ADC4
ADC8ADD0ADD1ADD3ADDCADE0ADE4ADF8ADF9ADFCADFFAE00AE01AE08AE09AE0B
AE0DAE14AE30AE31AE34AE37AE38AE3AAE40AE41AE43AE45AE46AE4AAE4CAE4D
AE4EAE50AE54AE56AE5CAE5DAE5FAE60AE61AE65AE68AE69AE6CAE70AE780000
B2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000AE79AE7BAE7CAE7DAE84AE85AE8CAEBCAEBDAEBEAEC0AEC4AECCAECDAECF
AED0AED1AED8AED9AEDCAEE8AEEBAEEDAEF4AEF8AEFCAF07AF08AF0DAF10AF2C
AF2DAF30AF32AF34AF3CAF3DAF3FAF41AF42AF43AF48AF49AF50AF5CAF5DAF64
AF65AF79AF80AF84AF88AF90AF91AF95AF9CAFB8AFB9AFBCAFC0AFC7AFC8AFC9
AFCBAFCDAFCEAFD4AFDCAFE8AFE9AFF0AFF1AFF4AFF8B000B001B004B00CB010
B014B01CB01DB028B044B045B048B04AB04CB04EB053B054B055B057B0590000
B3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B05DB07CB07DB080B084B08CB08DB08FB091B098B099B09AB09CB09FB0A0
B0A1B0A2B0A8B0A9B0ABB0ACB0ADB0AEB0AFB0B1B0B3B0B4B0B5B0B8B0BCB0C4
B0C5B0C7B0C8B0C9B0D0B0D1B0D4B0D8B0E0B0E5B108B109B10BB10CB110B112
B113B118B119B11BB11CB11DB123B124B125B128B12CB134B135B137B138B139
B140B141B144B148B150B151B154B155B158B15CB160B178B179B17CB180B182
B188B189B18BB18DB192B193B194B198B19CB1A8B1CCB1D0B1D4B1DCB1DD0000
B4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B1DFB1E8B1E9B1ECB1F0B1F9B1FBB1FDB204B205B208B20BB20CB214B215
B217B219B220B234B23CB258B25CB260B268B269B274B275B27CB284B285B289
B290B291B294B298B299B29AB2A0B2A1B2A3B2A5B2A6B2AAB2ACB2B0B2B4B2C8
B2C9B2CCB2D0B2D2B2D8B2D9B2DBB2DDB2E2B2E4B2E5B2E6B2E8B2EBB2ECB2ED
B2EEB2EFB2F3B2F4B2F5B2F7B2F8B2F9B2FAB2FBB2FFB300B301B304B308B310
B311B313B314B315B31CB354B355B356B358B35BB35CB35EB35FB364B3650000
B5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B367B369B36BB36EB370B371B374B378B380B381B383B384B385B38CB390
B394B3A0B3A1B3A8B3ACB3C4B3C5B3C8B3CBB3CCB3CEB3D0B3D4B3D5B3D7B3D9
B3DBB3DDB3E0B3E4B3E8B3FCB410B418B41CB420B428B429B42BB434B450B451
B454B458B460B461B463B465B46CB480B488B49DB4A4B4A8B4ACB4B5B4B7B4B9
B4C0B4C4B4C8B4D0B4D5B4DCB4DDB4E0B4E3B4E4B4E6B4ECB4EDB4EFB4F1B4F8
B514B515B518B51BB51CB524B525B527B528B529B52AB530B531B534B5380000
B6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B540B541B543B544B545B54BB54CB54DB550B554B55CB55DB55FB560B561
B5A0B5A1B5A4B5A8B5AAB5ABB5B0B5B1B5B3B5B4B5B5B5BBB5BCB5BDB5C0B5C4
B5CCB5CDB5CFB5D0B5D1B5D8B5ECB610B611B614B618B625B62CB634B648B664
B668B69CB69DB6A0B6A4B6ABB6ACB6B1B6D4B6F0B6F4B6F8B700B701B705B728
B729B72CB72FB730B738B739B73BB744B748B74CB754B755B760B764B768B770
B771B773B775B77CB77DB780B784B78CB78DB78FB790B791B792B796B7970000
B7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B798B799B79CB7A0B7A8B7A9B7ABB7ACB7ADB7B4B7B5B7B8B7C7B7C9B7EC
B7EDB7F0B7F4B7FCB7FDB7FFB800B801B807B808B809B80CB810B818B819B81B
B81DB824B825B828B82CB834B835B837B838B839B840B844B851B853B85CB85D
B860B864B86CB86DB86FB871B878B87CB88DB8A8B8B0B8B4B8B8B8C0B8C1B8C3
B8C5B8CCB8D0B8D4B8DDB8DFB8E1B8E8B8E9B8ECB8F0B8F8B8F9B8FBB8FDB904
B918B920B93CB93DB940B944B94CB94FB951B958B959B95CB960B968B9690000
B8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B96BB96DB974B975B978B97CB984B985B987B989B98AB98DB98EB9ACB9AD
B9B0B9B4B9BCB9BDB9BFB9C1B9C8B9C9B9CCB9CEB9CFB9D0B9D1B9D2B9D8B9D9
B9DBB9DDB9DEB9E1B9E3B9E4B9E5B9E8B9ECB9F4B9F5B9F7B9F8B9F9B9FABA00
BA01BA08BA15BA38BA39BA3CBA40BA42BA48BA49BA4BBA4DBA4EBA53BA54BA55
BA58BA5CBA64BA65BA67BA68BA69BA70BA71BA74BA78BA83BA84BA85BA87BA8C
BAA8BAA9BAABBAACBAB0BAB2BAB8BAB9BABBBABDBAC4BAC8BAD8BAD9BAFC0000
B9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BB00BB04BB0DBB0FBB11BB18BB1CBB20BB29BB2BBB34BB35BB36BB38BB3B
BB3CBB3DBB3EBB44BB45BB47BB49BB4DBB4FBB50BB54BB58BB61BB63BB6CBB88
BB8CBB90BBA4BBA8BBACBBB4BBB7BBC0BBC4BBC8BBD0BBD3BBF8BBF9BBFCBBFF
BC00BC02BC08BC09BC0BBC0CBC0DBC0FBC11BC14BC15BC16BC17BC18BC1BBC1C
BC1DBC1EBC1FBC24BC25BC27BC29BC2DBC30BC31BC34BC38BC40BC41BC43BC44
BC45BC49BC4CBC4DBC50BC5DBC84BC85BC88BC8BBC8CBC8EBC94BC95BC970000
BA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BC99BC9ABCA0BCA1BCA4BCA7BCA8BCB0BCB1BCB3BCB4BCB5BCBCBCBDBCC0
BCC4BCCDBCCFBCD0BCD1BCD5BCD8BCDCBCF4BCF5BCF6BCF8BCFCBD04BD05BD07
BD09BD10BD14BD24BD2CBD40BD48BD49BD4CBD50BD58BD59BD64BD68BD80BD81
BD84BD87BD88BD89BD8ABD90BD91BD93BD95BD99BD9ABD9CBDA4BDB0BDB8BDD4
BDD5BDD8BDDCBDE9BDF0BDF4BDF8BE00BE03BE05BE0CBE0DBE10BE14BE1CBE1D
BE1FBE44BE45BE48BE4CBE4EBE54BE55BE57BE59BE5ABE5BBE60BE61BE640000
BB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BE68BE6ABE70BE71BE73BE74BE75BE7BBE7CBE7DBE80BE84BE8CBE8DBE8F
BE90BE91BE98BE99BEA8BED0BED1BED4BED7BED8BEE0BEE3BEE4BEE5BEECBF01
BF08BF09BF18BF19BF1BBF1CBF1DBF40BF41BF44BF48BF50BF51BF55BF94BFB0
BFC5BFCCBFCDBFD0BFD4BFDCBFDFBFE1C03CC051C058C05CC060C068C069C090
C091C094C098C0A0C0A1C0A3C0A5C0ACC0ADC0AFC0B0C0B3C0B4C0B5C0B6C0BC
C0BDC0BFC0C0C0C1C0C5C0C8C0C9C0CCC0D0C0D8C0D9C0DBC0DCC0DDC0E40000
BC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C0E5C0E8C0ECC0F4C0F5C0F7C0F9C100C104C108C110C115C11CC11DC11E
C11FC120C123C124C126C127C12CC12DC12FC130C131C136C138C139C13CC140
C148C149C14BC14CC14DC154C155C158C15CC164C165C167C168C169C170C174
C178C185C18CC18DC18EC190C194C196C19CC19DC19FC1A1C1A5C1A8C1A9C1AC
C1B0C1BDC1C4C1C8C1CCC1D4C1D7C1D8C1E0C1E4C1E8C1F0C1F1C1F3C1FCC1FD
C200C204C20CC20DC20FC211C218C219C21CC21FC220C228C229C22BC22D0000
BD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C22FC231C232C234C248C250C251C254C258C260C265C26CC26DC270C274
C27CC27DC27FC281C288C289C290C298C29BC29DC2A4C2A5C2A8C2ACC2ADC2B4
C2B5C2B7C2B9C2DCC2DDC2E0C2E3C2E4C2EBC2ECC2EDC2EFC2F1C2F6C2F8C2F9
C2FBC2FCC300C308C309C30CC30DC313C314C315C318C31CC324C325C328C329
C345C368C369C36CC370C372C378C379C37CC37DC384C388C38CC3C0C3D8C3D9
C3DCC3DFC3E0C3E2C3E8C3E9C3EDC3F4C3F5C3F8C408C410C424C42CC4300000
BE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C434C43CC43DC448C464C465C468C46CC474C475C479C480C494C49CC4B8
C4BCC4E9C4F0C4F1C4F4C4F8C4FAC4FFC500C501C50CC510C514C51CC528C529
C52CC530C538C539C53BC53DC544C545C548C549C54AC54CC54DC54EC553C554
C555C557C558C559C55DC55EC560C561C564C568C570C571C573C574C575C57C
C57DC580C584C587C58CC58DC58FC591C595C597C598C59CC5A0C5A9C5B4C5B5
C5B8C5B9C5BBC5BCC5BDC5BEC5C4C5C5C5C6C5C7C5C8C5C9C5CAC5CCC5CE0000
BF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C5D0C5D1C5D4C5D8C5E0C5E1C5E3C5E5C5ECC5EDC5EEC5F0C5F4C5F6C5F7
C5FCC5FDC5FEC5FFC600C601C605C606C607C608C60CC610C618C619C61BC61C
C624C625C628C62CC62DC62EC630C633C634C635C637C639C63BC640C641C644
C648C650C651C653C654C655C65CC65DC660C66CC66FC671C678C679C67CC680
C688C689C68BC68DC694C695C698C69CC6A4C6A5C6A7C6A9C6B0C6B1C6B4C6B8
C6B9C6BAC6C0C6C1C6C3C6C5C6CCC6CDC6D0C6D4C6DCC6DDC6E0C6E1C6E80000
C0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C6E9C6ECC6F0C6F8C6F9C6FDC704C705C708C70CC714C715C717C719C720
C721C724C728C730C731C733C735C737C73CC73DC740C744C74AC74CC74DC74F
C751C752C753C754C755C756C757C758C75CC760C768C76BC774C775C778C77C
C77DC77EC783C784C785C787C788C789C78AC78EC790C791C794C796C797C798
C79AC7A0C7A1C7A3C7A4C7A5C7A6C7ACC7ADC7B0C7B4C7BCC7BDC7BFC7C0C7C1
C7C8C7C9C7CCC7CEC7D0C7D8C7DDC7E4C7E8C7ECC800C801C804C808C80A0000
C1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C810C811C813C815C816C81CC81DC820C824C82CC82DC82FC831C838C83C
C840C848C849C84CC84DC854C870C871C874C878C87AC880C881C883C885C886
C887C88BC88CC88DC894C89DC89FC8A1C8A8C8BCC8BDC8C4C8C8C8CCC8D4C8D5
C8D7C8D9C8E0C8E1C8E4C8F5C8FCC8FDC900C904C905C906C90CC90DC90FC911
C918C92CC934C950C951C954C958C960C961C963C96CC970C974C97CC988C989
C98CC990C998C999C99BC99DC9C0C9C1C9C4C9C7C9C8C9CAC9D0C9D1C9D30000
C2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C9D5C9D6C9D9C9DAC9DCC9DDC9E0C9E2C9E4C9E7C9ECC9EDC9EFC9F0C9F1
C9F8C9F9C9FCCA00CA08CA09CA0BCA0CCA0DCA14CA18CA29CA4CCA4DCA50CA54
CA5CCA5DCA5FCA60CA61CA68CA7DCA84CA98CABCCABDCAC0CAC4CACCCACDCACF
CAD1CAD3CAD8CAD9CAE0CAECCAF4CB08CB10CB14CB18CB20CB21CB41CB48CB49
CB4CCB50CB58CB59CB5DCB64CB78CB79CB9CCBB8CBD4CBE4CBE7CBE9CC0CCC0D
CC10CC14CC1CCC1DCC21CC22CC27CC28CC29CC2CCC2ECC30CC38CC39CC3B0000
C3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CC3CCC3DCC3ECC44CC45CC48CC4CCC54CC55CC57CC58CC59CC60CC64CC66
CC68CC70CC75CC98CC99CC9CCCA0CCA8CCA9CCABCCACCCADCCB4CCB5CCB8CCBC
CCC4CCC5CCC7CCC9CCD0CCD4CCE4CCECCCF0CD01CD08CD09CD0CCD10CD18CD19
CD1BCD1DCD24CD28CD2CCD39CD5CCD60CD64CD6CCD6DCD6FCD71CD78CD88CD94
CD95CD98CD9CCDA4CDA5CDA7CDA9CDB0CDC4CDCCCDD0CDE8CDECCDF0CDF8CDF9
CDFBCDFDCE04CE08CE0CCE14CE19CE20CE21CE24CE28CE30CE31CE33CE350000
C4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CE58CE59CE5CCE5FCE60CE61CE68CE69CE6BCE6DCE74CE75CE78CE7CCE84
CE85CE87CE89CE90CE91CE94CE98CEA0CEA1CEA3CEA4CEA5CEACCEADCEC1CEE4
CEE5CEE8CEEBCEECCEF4CEF5CEF7CEF8CEF9CF00CF01CF04CF08CF10CF11CF13
CF15CF1CCF20CF24CF2CCF2DCF2FCF30CF31CF38CF54CF55CF58CF5CCF64CF65
CF67CF69CF70CF71CF74CF78CF80CF85CF8CCFA1CFA8CFB0CFC4CFE0CFE1CFE4
CFE8CFF0CFF1CFF3CFF5CFFCD000D004D011D018D02DD034D035D038D03C0000
C5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D044D045D047D049D050D054D058D060D06CD06DD070D074D07CD07DD081
D0A4D0A5D0A8D0ACD0B4D0B5D0B7D0B9D0C0D0C1D0C4D0C8D0C9D0D0D0D1D0D3
D0D4D0D5D0DCD0DDD0E0D0E4D0ECD0EDD0EFD0F0D0F1D0F8D10DD130D131D134
D138D13AD140D141D143D144D145D14CD14DD150D154D15CD15DD15FD161D168
D16CD17CD184D188D1A0D1A1D1A4D1A8D1B0D1B1D1B3D1B5D1BAD1BCD1C0D1D8
D1F4D1F8D207D209D210D22CD22DD230D234D23CD23DD23FD241D248D25C0000
C6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D264D280D281D284D288D290D291D295D29CD2A0D2A4D2ACD2B1D2B8D2B9
D2BCD2BFD2C0D2C2D2C8D2C9D2CBD2D4D2D8D2DCD2E4D2E5D2F0D2F1D2F4D2F8
D300D301D303D305D30CD30DD30ED310D314D316D31CD31DD31FD320D321D325
D328D329D32CD330D338D339D33BD33CD33DD344D345D37CD37DD380D384D38C
D38DD38FD390D391D398D399D39CD3A0D3A8D3A9D3ABD3ADD3B4D3B8D3BCD3C4
D3C5D3C8D3C9D3D0D3D8D3E1D3E3D3ECD3EDD3F0D3F4D3FCD3FDD3FFD4010000
C7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D408D41DD440D444D45CD460D464D46DD46FD478D479D47CD47FD480D482
D488D489D48BD48DD494D4A9D4CCD4D0D4D4D4DCD4DFD4E8D4ECD4F0D4F8D4FB
D4FDD504D508D50CD514D515D517D53CD53DD540D544D54CD54DD54FD551D558
D559D55CD560D565D568D569D56BD56DD574D575D578D57CD584D585D587D588
D589D590D5A5D5C8D5C9D5CCD5D0D5D2D5D8D5D9D5DBD5DDD5E4D5E5D5E8D5EC
D5F4D5F5D5F7D5F9D600D601D604D608D610D611D613D614D615D61CD6200000
C8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D624D62DD638D639D63CD640D645D648D649D64BD64DD651D654D655D658
D65CD667D669D670D671D674D683D685D68CD68DD690D694D69DD69FD6A1D6A8
D6ACD6B0D6B9D6BBD6C4D6C5D6C8D6CCD6D1D6D4D6D7D6D9D6E0D6E4D6E8D6F0
D6F5D6FCD6FDD700D704D711D718D719D71CD720D728D729D72BD72DD734D735
D738D73CD744D747D749D750D751D754D756D757D758D759D760D761D763D765
D769D76CD770D774D77CD77DD781D788D789D78CD790D798D799D79BD79D0000
CA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F3D4F73504750F952A053EF547554E556095AC15BB6668767B667B767EF
6B4C73C275C27A3C82DB8304885788888A368CC88DCF8EFB8FE699D5523B5374
5404606A61646BBC73CF811A89BA89D295A34F83520A58BE597859E65E725E79
61C763C0674667EC687F6F97764E770B78F57A087AFF7C21809D826E82718AEB
95934E6B559D66F76E3478A37AED845B8910874E97A852D8574E582A5D4C611F
61BE6221656267D16A446E1B751875B376E377B07D3A90AF945194529F950000
CB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000053235CAC753280DB92409598525B580859DC5CA15D175EB75F3A5F4A6177
6C5F757A75867CE07D737DB17F8C81548221859189418B1B92FC964D9C474ECB
4EF7500B51F1584F6137613E6168653969EA6F1175A5768676D67B8782A584CB
F90093A7958B55805BA25751F9017CB37FB991B5502853BB5C455DE862D2636E
64DA64E76E2070AC795B8DDD8E1EF902907D924592F84E7E4EF650655DFE5EFA
61066957817186548E4793759A2B4E5E5091677068405109528D52926AA20000
CC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077BC92109ED452AB602F8FF2504861A963ED64CA683C6A846FC0818889A1
96945805727D72AC75047D797E6D80A9898B8B7490639D5162896C7A6F547D50
7F3A8A23517C614A7B9D8B199257938C4EAC4FD3501E50BE510652C152CD537F
577058835E9A5F91617661AC64CE656C666F66BB66F468976D87708570F1749F
74A574CA75D9786C78EC7ADF7AF67D457D938015803F811B83968B668F159015
93E1980398389A5A9BE84FC25553583A59515B635C4660B86212684268B00000
CD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000068E86EAA754C767878CE7A3D7CFB7E6B7E7C8A088AA18C3F968E9DC453E4
53E9544A547156FA59D15B645C3B5EAB62F765376545657266A067AF69C16CBD
75FC7690777E7A3F7F94800380A1818F82E682FD83F085C1883188B48AA5F903
8F9C932E96C798679AD89F1354ED659B66F2688F7A408C379D6056F057645D11
660668B168CD6EFE7428889E9BE46C68F9049AA84F9B516C5171529F5B545DE5
6050606D62F163A7653B73D97A7A86A38CA2978F4E325BE16208679C74DC0000
CE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000079D183D38A878AB28DE8904E934B98465ED369E885FF90EDF90551A05B98
5BEC616368FA6B3E704C742F74D87BA17F5083C589C08CAB95DC9928522E605D
62EC90024F8A5149532158D95EE366E06D38709A72C273D67B5080F1945B5366
639B7F6B4E565080584A58DE602A612762D069D09B415B8F7D1880B18F5F4EA4
50D154AC55AC5B0C5DA05DE7652A654E68216A4B72E1768E77EF7D5E7FF981A0
854E86DF8F038F4E90CA99039A559BAB4E184E454E5D4EC74FF1517752FE0000
CF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000534053E353E5548E5614577557A25BC75D875ED061FC62D8655167B867E9
69CB6B506BC66BEC6C426E9D707872D77396740377BF77E97A767D7F800981FC
8205820A82DF88628B338CFC8EC0901190B1926492B699D29A459CE99DD79F9C
570B5C4083CA97A097AB9EB4541B7A987FA488D98ECD90E158005C4863987A9F
5BAE5F137A797AAE828E8EAC5026523852F85377570862F363726B0A6DC37737
53A5735785688E7695D5673A6AC36F708A6D8ECC994BF90666776B788CB40000
D0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009B3CF90753EB572D594E63C669FB73EA78457ABA7AC57CFE8475898F8D73
903595A852FB574775477B6083CC921EF9086A58514B524B5287621F68D86975
969950C552A452E461C365A4683969FF747E7B4B82B983EB89B28B398FD19949
F9094ECA599764D266116A8E7434798179BD82A9887E887F895FF90A93264F0B
53CA602562716C727D1A7D664E98516277DC80AF4F014F0E5176518055DC5668
573B57FA57FC5914594759935BC45C905D0E5DF15E7E5FCC628065D765E30000
D1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000671E671F675E68CB68C46A5F6B3A6C236C7D6C826DC773987426742A7482
74A37578757F788178EF794179477948797A7B957D007DBA7F888006802D808C
8A188B4F8C488D779321932498E299519A0E9A0F9A659E927DCA4F76540962EE
685491D155AB513AF90BF90C5A1C61E6F90D62CF62FFF90EF90FF910F911F912
F91390A3F914F915F916F917F9188AFEF919F91AF91BF91C6696F91D7156F91E
F91F96E3F920634F637A5357F921678F69606E73F9227537F923F924F9250000
D2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007D0DF926F927887256CA5A18F928F929F92AF92BF92C4E43F92D51675948
67F08010F92E59735E74649A79CA5FF5606C62C8637B5BE75BD752AAF92F5974
5F296012F930F931F9327459F933F934F935F936F937F93899D1F939F93AF93B
F93CF93DF93EF93FF940F941F942F9436FC3F944F94581BF8FB260F1F946F947
8166F948F9495C3FF94AF94BF94CF94DF94EF94FF950F9515AE98A25677B7D10
F952F953F954F955F956F95780FDF958F9595C3C6CE5533F6EBA591A83360000
D3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E394EB64F4655AE571858C75F5665B765E66A806BB56E4D77ED7AEF7C1E
7DDE86CB88929132935B64BB6FBE737A75B890545556574D61BA64D466C76DE1
6E5B6F6D6FB975F0804381BD854189838AC78B5A931F6C9375537B548E0F905D
5510580258585E626207649E68E075767CD687B39EE84EE35788576E59275C0D
5CB15E365F85623464E173B381FA888B8CB8968A9EDB5B855FB760B350125200
52305716583558575C0E5C605CF65D8B5EA65F9260BC63116389641768430000
D4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000068F96AC26DD86E216ED46FE471FE76DC777979B17A3B840489A98CED8DF3
8E4890039014905390FD934D967697DC6BD27006725872A27368776379BF7BE4
7E9B8B8058A960C7656665FD66BE6C8C711E71C98C5A98134E6D7A814EDD51AC
51CD52D5540C61A76771685068DF6D1E6F7C75BC77B37AE580F484639285515C
6597675C679375D87AC78373F95A8C469017982D5C6F81C0829A9041906F920D
5F975D9D6A5971C8767B7B4985E48B0491279A30558761F6F95B76697F850000
D5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000863F87BA88F8908FF95C6D1B70D973DE7D61843DF95D916A99F1F95E4E82
53756B046B12703E721B862D9E1E524C8FA35D5064E5652C6B166FEB7C437E9C
85CD896489BD62C981D8881F5ECA67176D6A72FC7405746F878290DE4F865D0D
5FA0840A51B763A075654EAE5006516951C968816A117CAE7CB17CE7826F8AD2
8F1B91CF4FB6513752F554425EEC616E623E65C56ADA6FFE792A85DC882395AD
9A629A6A9E979ECE529B66C66B77701D792B8F6297426190620065236F230000
D6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000714974897DF4806F84EE8F269023934A51BD521752A36D0C70C888C25EC9
65826BAE6FC27C3E73754EE44F3656F9F95F5CBA5DBA601C73B27B2D7F9A7FCE
8046901E923496F6974898189F614F8B6FA779AE91B496B752DEF960648864C4
6AD36F5E7018721076E780018606865C8DEF8F0597329B6F9DFA9E75788C797F
7DA083C993049E7F9E938AD658DF5F046727702774CF7C60807E512170287262
78CA8CC28CDA8CF496F74E8650DA5BEE5ED6659971CE764277AD804A84FC0000
D7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000907C9B279F8D58D85A415C626A136DDA6F0F763B7D2F7E37851E893893E4
964B528965D267F369B46D416E9C700F7409746075597624786B8B2C985E516D
622E96784F96502B5D196DEA7DB88F2A5F8B61446817F961968652D2808B51DC
51CC695E7A1C7DBE83F196754FDA52295398540F550E5C6560A7674E68A86D6C
728172F874067483F96275E27C6C7F797FB8838988CF88E191CC91D096E29BC9
541D6F7E71D0749885FA8EAA96A39C579E9F67976DCB743381E89716782C0000
D8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007ACB7B207C926469746A75F278BC78E899AC9B549EBB5BDE5E556F20819C
83AB90884E07534D5A295DD25F4E6162633D666966FC6EFF6F2B7063779E842C
8513883B8F1399459C3B551C62B9672B6CAB8309896A977A4EA159845FD85FD9
671B7DB27F548292832B83BD8F1E909957CB59B95A925BD06627679A68856BCF
71647F758CB78CE390819B4581088C8A964C9A409EA55B5F6C13731B76F276DF
840C51AA8993514D519552C968C96C94770477207DBF7DEC97629EB56EC50000
D9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000851151A5540D547D660E669D69276E9F76BF7791831784C2879F91699298
9CF488824FAE519252DF59C65E3D61556478647966AE67D06A216BCD6BDB725F
72617441773877DB801782BC83058B008B288C8C67286C90726776EE77667A46
9DA96B7F6C92592267268499536F589359995EDF63CF663467736E3A732B7AD7
82D7932852D95DEB61AE61CB620A62C764AB65E069596B666BCB712173F7755D
7E46821E8302856A8AA38CBF97279D6158A89ED85011520E543B554F65870000
DA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006C767D0A7D0B805E868A958096EF52FF6C95726954735A9A5C3E5D4B5F4C
5FAE672A68B669636E3C6E4477097C737F8E85878B0E8FF797619EF45CB760B6
610D61AB654F65FB65FC6C116CEF739F73C97DE195945BC6871C8B10525D535A
62CD640F64B267346A386CCA73C0749E7B947C957E1B818A823685848FEB96F9
99C14F34534A53CD53DB62CC642C6500659169C36CEE6F5873ED7554762276E4
76FC78D078FB792C7D46822C87E08FD4981298EF52C362D464A56E246F510000
DB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000767C8DCB91B192629AEE9B435023508D574A59A85C285E475F77623F653E
65B965C16609678B699C6EC278C57D2180AA8180822B82B384A1868C8A2A8B17
90A696329F90500D4FF3F96357F95F9862DC6392676F6E43711976C380CC80DA
88F488F589198CE08F29914D966A4F2F4F705E1B67CF6822767D767E9B445E61
6A0A716971D4756AF9647E41854385E998DC4F107B4F7F7095A551E15E0668B5
6C3E6C4E6CDB72AF7BC483036CD5743A50FB528858C164D86A9774A776560000
DC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000078A7861795E29739F965535E5F018B8A8FA88FAF908A522577A59C499F08
4E19500251755C5B5E77661E663A67C468C570B3750175C579C97ADD8F279920
9A084FDD582158315BF6666E6B656D116E7A6F7D73E4752B83E988DC89138B5C
8F144F0F50D55310535C5B935FA9670D798F8179832F8514890789868F398F3B
99A59C12672C4E764FF859495C015CEF5CF0636768D270FD71A2742B7E2B84EC
8702902292D29CF34E0D4ED84FEF50855256526F5426549057E0592B5A660000
DD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005B5A5B755BCC5E9CF9666276657765A76D6E6EA572367B267C3F7F368150
8151819A8240829983A98A038CA08CE68CFB8D748DBA90E891DC961C964499D9
9CE7531752065429567458B35954596E5FFF61A4626E66106C7E711A76C67C89
7CDE7D1B82AC8CC196F0F9674F5B5F175F7F62C25D29670B68DA787C7E439D6C
4E1550995315532A535159835A625E8760B2618A624962796590678769A76BD4
6BD66BD76BD86CB8F968743575FA7812789179D579D87C837DCB7FE180A50000
DE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000813E81C283F2871A88E88AB98B6C8CBB9119975E98DB9F3B56AC5B2A5F6C
658C6AB36BAF6D5C6FF17015725D73AD8CA78CD3983B61916C3780589A014E4D
4E8B4E9B4ED54F3A4F3C4F7F4FDF50FF53F253F8550655E356DB58EB59625A11
5BEB5BFA5C045DF35E2B5F99601D6368659C65AF67F667FB68AD6B7B6C996CD7
6E23700973457802793E7940796079C17BE97D177D728086820D838E84D186C7
88DF8A508A5E8B1D8CDC8D668FAD90AA98FC99DF9E9D524AF9696714F96A0000
DF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005098522A5C7165636C5573CA7523759D7B97849C917897304E7764926BBA
715E85A94E09F96B674968EE6E17829F8518886B63F76F81921298AF4E0A50B7
50CF511F554655AA56175B405C195CE05E385E8A5EA05EC260F368516A616E58
723D724072C076F879657BB17FD488F389F48A738C618CDE971C585E74BD8CFD
55C7F96C7A617D2282727272751F7525F96D7B19588558FB5DBC5E8F5EB65F90
60556292637F654D669166D966F8681668F27280745E7B6E7D6E7DD67F720000
E0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000080E5821285AF897F8A93901D92E49ECD9F205915596D5E2D60DC66146673
67906C506DC56F5F77F378A984C691CB932B4ED950CA514855845B0B5BA36247
657E65CB6E32717D74017444748774BF766C79AA7DDA7E557FA8817A81B38239
861A87EC8A758DE3907892919425994D9BAE53685C5169546CC46D296E2B820C
859B893B8A2D8AAA96EA9F67526166B96BB27E9687FE8D0D9583965D651D6D89
71EEF96E57CE59D35BAC602760FA6210661F665F732973F976DB77017B6C0000
E1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008056807281658AA091924E1652E26B726D177A057B397D30F96F8CB053EC
562F58515BB55C0F5C115DE2624063836414662D68B36CBC6D886EAF701F70A4
71D27526758F758E76197B117BE07C2B7D207D39852C856D86078A34900D9061
90B592B797F69A374FD75C6C675F6D917C9F7E8C8B168D16901F5B6B5DFD640D
84C0905C98E173875B8B609A677E6DDE8A1F8AA69001980C5237F9707051788E
9396887091D74FEE53D755FD56DA578258FD5AC25B885CAB5CC05E2561010000
E2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000620D624B6388641C653665786A396B8A6C346D196F3171E772E973787407
74B27626776179C07A577AEA7CB97D8F7DAC7E617F9E81298331849084DA85EA
88968AB08B908F3890429083916C929692B9968B96A796A896D6970098089996
9AD39B1A53D4587E59195B705BBF6DD16F5A719F742174B9808583FD5DE15F87
5FAA604265EC6812696F6A536B896D356DF373E376FE77AC7B4D7D148123821C
834084F485638A628AC49187931E980699B4620C88538FF092655D075D270000
E3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005D69745F819D87686FD562FE7FD2893689724E1E4E5850E752DD5347627F
66077E698805965E4F8D5319563659CB5AA45C385C4E5C4D5E025F11604365BD
662F664267BE67F4731C77E2793A7FC5849484CD89968A668A698AE18C558C7A
57F45BD45F0F606F62ED690D6B966E5C71847BD287558B588EFE98DF98FE4F38
4F814FE1547B5A205BB8613C65B0666871FC7533795E7D33814E81E3839885AA
85CE87038A0A8EAB8F9BF9718FC559315BA45BE660895BE95C0B5FC36C810000
E4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9726DF1700B751A82AF8AF64EC05341F97396D96C0F4E9E4FC45152555E
5A255CE86211725982BD83AA86FE88598A1D963F96C599139D099D5D580A5CB3
5DBD5E4460E1611563E16A026E2591029354984E9C109F775B895CB86309664F
6848773C96C1978D98549B9F65A18B018ECB95BC55355CA95DD65EB56697764C
83F495C758D362BC72CE9D284EF0592E600F663B6B8379E79D26539354C057C3
5D16611B66D66DAF788D827E969897445384627C63966DB27E0A814B984D0000
E5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006AFB7F4C9DAF9E1A4E5F503B51B6591C60F963F66930723A8036F97491CE
5F31F975F9767D0482E5846F84BB85E58E8DF9774F6FF978F97958E45B436059
63DA6518656D6698F97A694A6A236D0B7001716C75D2760D79B37A70F97B7F8A
F97C8944F97D8B9391C0967DF97E990A57045FA165BC6F01760079A68A9E99AD
9B5A9F6C510461B662916A8D81C6504358305F6671098A008AFA5B7C86164FFA
513C56B4594463A96DF95DAA696D51864E884F59F97FF980F9815982F9820000
E6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9836B5F6C5DF98474B57916F9858207824583398F3F8F5DF9869918F987
F988F9894EA6F98A57DF5F796613F98BF98C75AB7E798B6FF98D90069A5B56A5
582759F85A1F5BB4F98E5EF6F98FF9906350633BF991693D6C876CBF6D8E6D93
6DF56F14F99270DF71367159F99371C371D5F994784F786FF9957B757DE3F996
7E2FF997884D8EDFF998F999F99A925BF99B9CF6F99CF99DF99E60856D85F99F
71B1F9A0F9A195B153ADF9A2F9A3F9A467D3F9A5708E71307430827682D20000
E7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9A695BB9AE59E7D66C4F9A771C18449F9A8F9A9584BF9AAF9AB5DB85F71
F9AC6620668E697969AE6C386CF36E366F416FDA701B702F715071DF7370F9AD
745BF9AE74D476C87A4E7E93F9AFF9B082F18A608FCEF9B19348F9B29719F9B3
F9B44E42502AF9B5520853E166F36C6D6FCA730A777F7A6282AE85DD8602F9B6
88D48A638B7D8C6BF9B792B3F9B8971398104E944F0D4FC950B25348543E5433
55DA586258BA59675A1B5BE4609FF9B961CA655665FF666468A76C5A6FB30000
E8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000070CF71AC73527B7D87088AA49C329F075C4B6C8373447389923A6EAB7465
761F7A697E15860A514058C564C174EE751576707FC1909596CD99546E2674E6
7AA97AAA81E586D987788A1B5A495B8C5B9B68A169006D6373A97413742C7897
7DE97FEB81188155839E8C4C962E981166F05F8065FA67896C6A738B502D5A03
6B6A77EE59165D6C5DCD7325754FF9BAF9BB50E551F9582F592D599659DA5BE5
F9BCF9BD5DA262D76416649364FEF9BE66DCF9BF6A48F9C071FF7464F9C10000
E9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A887AAF7E477E5E80008170F9C287EF89818B209059F9C390809952617E
6B326D747E1F89258FB14FD150AD519752C757C758895BB95EB8614269956D8C
6E676EB6719474627528752C8073833884C98E0A939493DEF9C44E8E4F515076
512A53C853CB53F35B875BD35C24611A618265F4725B7397744076C279507991
79B97D067FBD828B85D5865E8FC2904790F591EA968596E896E952D65F6765ED
6631682F715C7A3690C1980A4E91F9C56A526B9E6F907189801882B885530000
EA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000904B969596F297FB851A9B314E90718A96C45143539F54E15713571257A3
5A9B5AC45BC36028613F63F46C856D396E726E907230733F745782D188818F45
9060F9C6966298589D1B67088D8A925E4F4D504950DE5371570D59D45A015C09
617066906E2D7232744B7DEF80C3840E8466853F875F885B89188B02905597CB
9B4F4E734F915112516AF9C7552F55A95B7A5BA55E7C5E7D5EBE60A060DF6108
610963C465386709F9C867D467DAF9C9696169626CB96D27F9CA6E38F9CB0000
EB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006FE173367337F9CC745C7531F9CD7652F9CEF9CF7DAD81FE843888D58A98
8ADB8AED8E308E42904A903E907A914991C9936EF9D0F9D15809F9D26BD38089
80B2F9D3F9D45141596B5C39F9D5F9D66F6473A780E48D07F9D79217958FF9D8
F9D9F9DAF9DB807F620E701C7D68878DF9DC57A0606961476BB78ABE928096B1
4E59541F6DEB852D967097F398EE63D66CE3909151DD61C981BA9DF94F9D501A
51005B9C610F61FF64EC69056BC5759177E37FA98264858F87FB88638ABC0000
EC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008B7091AB4E8C4EE54F0AF9DDF9DE593759E8F9DF5DF25F1B5F5B6021F9E0
F9E1F9E2F9E3723E73E5F9E4757075CDF9E579FBF9E6800C8033808482E18351
F9E7F9E88CBD8CB39087F9E9F9EA98F4990CF9EBF9EC703776CA7FCA7FCC7FFC
8B1A4EBA4EC152035370F9ED54BD56E059FB5BC55F155FCD6E6EF9EEF9EF7D6A
8335F9F086938A8DF9F1976D9777F9F2F9F34E004F5A4F7E58F965E56EA29038
93B099B94EFB58EC598A59D96041F9F4F9F57A14F9F6834F8CC3516553440000
ED
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9F7F9F8F9F94ECD52695B5582BF4ED4523A54A859C959FF5B505B575B5C
606361486ECB7099716E738674F775B578C17D2B800581EA8328851785C98AEE
8CC796CC4F5C52FA56BC65AB6628707C70B872357DBD828D914C96C09D725B71
68E76B986F7A76DE5C9166AB6F5B7BB47C2A883696DC4E084ED75320583458BB
58EF596C5C075E335E845F35638C66B267566A1F6AA36B0C6F3F7246F9FA7350
748B7AE07CA7817881DF81E7838A846C8523859485CF88DD8D1391AC95770000
EE
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000969C518D54C957285BB0624D6750683D68936E3D6ED3707D7E2188C18CA1
8F099F4B9F4E722D7B8F8ACD931A4F474F4E5132548059D05E9562B56775696E
6A176CAE6E1A72D9732A75BD7BB87D3582E783F9845785F78A5B8CAF8E879019
90B896CE9F5F52E3540A5AE15BC2645865756EF472C4F9FB76847A4D7B1B7C4D
7E3E7FDF837B8B2B8CCA8D648DE18E5F8FEA8FF9906993D14F434F7A50B35168
5178524D526A5861587C59605C085C555EDB609B623068136BBF6C086FB10000
EF
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000714E742075307538755176727B4C7B8B7BAD7BC67E8F8A6E8F3E8F49923F
92939322942B96FB985A986B991E5207622A62986D5976647ACA7BC07D765360
5CBE5E976F3870B97C9897119B8E9EDE63A5647A87764E014E954EAD505C5075
544859C35B9A5E405EAD5EF75F8160C5633A653F657465CC6676667867FE6968
6A896B636C406DC06DE86E1F6E5E701E70A1738E73FD753A775B7887798E7A0B
7A7D7CBE7D8E82478A028AEA8C9E912D914A91D8926692CC9320970697560000
F0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000975C98029F0E52365291557C58245E1D5F1F608C63D068AF6FDF796D7B2C
81CD85BA88FD8AF88E44918D9664969B973D984C9F4A4FCE514651CB52A95632
5F145F6B63AA64CD65E9664166FA66F9671D689D68D769FD6F156F6E716771E5
722A74AA773A7956795A79DF7A207A957C977CDF7D447E70808785FB86A48A54
8ABF8D998E819020906D91E3963B96D59CE565CF7C078DB393C35B585C0A5352
62D9731D50275B975F9E60B0616B68D56DD9742E7A2E7D427D9C7E31816B0000
F1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008E2A8E35937E94184F5057505DE65EA7632B7F6A4E3B4F4F4F8F505A59DD
80C4546A546855FE594F5B995DDE5EDA665D673167F1682A6CE86D326E4A6F8D
70B773E075877C4C7D027D2C7DA2821F86DB8A3B8A858D708E8A8F339031914E
9152944499D07AF97CA54FCA510151C657C85BEF5CFB66596A3D6D5A6E966FEC
710C756F7AE388229021907596CB99FF83014E2D4EF2884691CD537D6ADB696B
6C41847A589E618E66FE62EF70DD751175C77E5284B88B498D084E4B53EA0000
F2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054AB573057405FD763016307646F652F65E8667A679D67B36B626C606C9A
6F2C77E57825794979577D1980A2810281F3829D82B787188A8CF9FC8D048DBE
907276F47A197A377E548077550755D45875632F64226649664B686D699B6B84
6D256EB173CD746874A1755B75B976E1771E778B79E67E097E1D81FB852F8897
8A3A8CD18EEB8FB0903293AD9663967397074F8453F159EA5AC95E19684E74C6
75BE79E97A9281A386ED8CEA8DCC8FED659F6715F9FD57F76F577DDD8F2F0000
F3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000093F696C65FB561F26F844E144F98501F53C955DF5D6F5DEE6B216B6478CB
7B9AF9FE8E498ECA906E6349643E77407A84932F947F9F6A64B06FAF71E674A8
74DA7AC47C127E827CB27E988B9A8D0A947D9910994C52395BDF64E6672D7D2E
50ED53C358796158615961FA65AC7AD98B928B9650095021527555315A3C5EE0
5F706134655E660C663666A269CD6EC46F32731676217A938139825983D684BC
50B557F05BC05BE85F6963A178267DB583DC852191C791F5518A67F57B560000
F4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008CAC51C459BB60BD8655501CF9FF52545C3A617D621A62D364F265A56ECC
7620810A8E60965F96BB4EDF5343559859295DDD64C56CC96DFA73947A7F821B
85A68CE48E10907791E795E1962197C651F854F255865FB964A46F887DB48F1F
8F4D943550C95C166CBE6DFB751B77BB7C3D7C648A798AC2581E59BE5E166377
7252758A776B8ADC8CBC8F125EF366746DF8807D83C18ACB97519BD6FA005243
66FF6D956EEF7DE08AE6902E905E9AD4521D527F54E86194628462DB68A20000
F5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006912695A6A3570927126785D7901790E79D27A0D8096827882D583498549
8C828D859162918B91AE4FC356D171ED77D7870089F85BF85FD6675190A853E2
585A5BF560A4618164607E3D80708525928364AE50AC5D146700589C62BD63A8
690E69786A1E6E6B76BA79CB82BB84298ACF8DA88FFD9112914B919C93109318
939A96DB9A369C0D4E11755C795D7AFA7B517BC97E2E84C48E598E748EF89010
6625693F744351FA672E9EDC51455FE06C9687F2885D887760B481B584030000
F6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008D0553D6543956345A365C31708A7FE0805A810681ED8DA391899A5F9DF2
50744EC453A060FB6E2C5C644F88502455E45CD95E5F606568946CBB6DC471BE
75D475F476617A1A7A497DC77DFB7F6E81F486A98F1C96C999B39F52524752C5
98ED89AA4E0367D26F064FB55BE267956C886D78741B782791DD937C87C479E4
7A315FEB4ED654A4553E58AE59A560F0625362D6673669558235964099B199DD
502C53535544577CFA016258FA0264E2666B67DD6FC16FEF742274388A170000
F7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000094385451560657665F48619A6B4E705870AD7DBB8A95596A812B63A27708
803D8CAA5854642D69BB5B955E116E6FFA038569514C53F0592A6020614B6B86
6C706CF07B1E80CE82D48DC690B098B1FA0464C76FA464916504514E5410571F
8A0E615F6876FA0575DB7B527D71901A580669CC817F892A9000983950785957
59AC6295900F9B2A615D727995D657615A465DF4628A64AD64FA67776CE26D3E
722C743678347F7782AD8DDB981752245742677F724874E38CA98FA692110000
F8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000962A516B53ED634C4F695504609665576C9B6D7F724C72FD7A1789878C9D
5F6D6F8E70F981A8610E4FBF504F624172477BC77DE87FE9904D97AD9A198CB6
576A5E7367B0840D8A5554205B165E635EE25F0A658380BA853D9589965B4F48
5305530D530F548654FA57035E036016629B62B16355FA066CE16D6675B17832
80DE812F82DE846184B2888D8912900B92EA98FD9B915E4566B466DD70117206
FA074FF5527D5F6A615367536A196F0274E2796888688C7998C798C49A430000
F9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054C17A1F69538AF78C4A98A899AE5F7C62AB75B276AE88AB907F96425339
5F3C5FC56CCC73CC7562758B7B4682FE999D4E4F903C4E0B4F5553A6590F5EC8
66306CB37455837787668CC09050971E9C1558D15B7886508B149DB45BD26068
608D65F16C576F226FA3701A7F557FF095919592965097D352728F4451FD542B
54B85563558A6ABB6DB57DD88266929C96779E79540854C876D286E495A495D4
965C4EA24F0959EE5AE65DF760526297676D68416C866E2F7F38809B822A0000
FA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FA08FA0998054EA5505554B35793595A5B695BB361C869776D77702387F9
89E38A728AE7908299ED9AB852BE683850165E78674F8347884C4EAB541156AE
73E6911597FF9909995799995653589F865B8A3161B26AF6737B8ED26B4796AA
9A57595572008D6B97694FD45CF45F2661F8665B6CEB70AB738473B973FE7729
774D7D437D627E2382378852FA0A8CE29249986F5B517A74884098015ACC4FE0
5354593E5CFD633E6D7972F98105810783A292CF98304EA851445211578B0000
FB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F626CC26ECE7005705070AF719273E97469834A87A28861900890A293A3
99A8516E5F5760E0616766B385598E4A91AF978B4E4E4E92547C58D558FA597D
5CB55F2762366248660A66676BEB6D696DCF6E566EF86F946FE06FE9705D72D0
7425745A74E07693795C7CCA7E1E80E182A6846B84BF864E865F87748B778C6A
93AC9800986560D1621691775A5A660F6DF76E3E743F9B425FFD60DA7B0F54C4
5F186C5E6CD36D2A70D87D0586798A0C9D3B5316548C5B056A3A706B75750000
FC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000798D79BE82B183EF8A718B418CA89774FA0B64F4652B78BA78BB7A6B4E38
559A59505BA65E7B60A363DB6B61666568536E19716574B07D0890849A699C25
6D3B6ED1733E8C4195CA51F05E4C5FA8604D60F66130614C6643664469A56CC1
6E5F6EC96F62714C749C76877BC17C27835287579051968D9EC3532F56DE5EFB
5F8A6062609461F7666667036A9C6DEE6FAE7070736A7E6A81BE833486D48AA8
8CC4528373725B966A6B940454EE56865B5D6548658566C9689F6D8D6DC60000
FD
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000723B80B491759A4D4FAF5019539A540E543C558955C55E3F5F8C673D7166
73DD900552DB52F3586458CE7104718F71FB85B08A13668885A855A76684714A
8431534955996BC15F595FBD63EE668971478AF18F1D9EBE4F11643A70CB7566
866760648B4E9DF8514751F653086D3680F89ED166156B23709875D554035C79
7D078A166B206B3D6B46543860706D3D7FD5820850D651DE559C566B56CD59EC
5B095E0C619961986231665E66E6719971B971BA72A779A77A007FB28A700000

Added library/encoding/gb12345.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
# Encoding file: gb12345, double-byte
D
233F 0 83
21
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030003001300230FB02C902C700A8300330052015FF5E2225202620182019
201C201D3014301530083009300A300B300C300D300E300F3016301730103011
00B100D700F72236222722282211220F222A222922082237221A22A522252220
23122299222B222E2261224C2248223D221D2260226E226F22642265221E2235
22342642264000B0203220332103FF0400A4FFE0FFE1203000A7211626062605
25CB25CF25CE25C725C625A125A025B325B2203B219221902191219330130000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
22
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000024882489248A248B248C248D248E248F2490249124922493249424952496
249724982499249A249B247424752476247724782479247A247B247C247D247E
247F248024812482248324842485248624872460246124622463246424652466
2467246824690000000032203221322232233224322532263227322832290000
00002160216121622163216421652166216721682169216A216B000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
23
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF01FF02FF03FFE5FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFF3CFF3DFF3EFF3F
FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
24
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000304130423043304430453046304730483049304A304B304C304D304E304F
3050305130523053305430553056305730583059305A305B305C305D305E305F
3060306130623063306430653066306730683069306A306B306C306D306E306F
3070307130723073307430753076307730783079307A307B307C307D307E307F
3080308130823083308430853086308730883089308A308B308C308D308E308F
3090309130923093000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
25
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
26
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000039103920393039403950396039703980399039A039B039C039D039E039F
03A003A103A303A403A503A603A703A803A90000000000000000000000000000
000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C303C403C503C603C703C803C90000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
27
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000004100411041204130414041504010416041704180419041A041B041C041D
041E041F0420042104220423042404250426042704280429042A042B042C042D
042E042F00000000000000000000000000000000000000000000000000000000
000004300431043204330434043504510436043704380439043A043B043C043D
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
28
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000010100E101CE00E0011300E9011B00E8012B00ED01D000EC014D00F301D2
00F2016B00FA01D400F901D601D801DA01DC00FC00EA00000000000000000000
0000000000000000000031053106310731083109310A310B310C310D310E310F
3110311131123113311431153116311731183119311A311B311C311D311E311F
3120312131223123312431253126312731283129000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
29
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000002500250125022503250425052506250725082509250A250B
250C250D250E250F2510251125122513251425152516251725182519251A251B
251C251D251E251F2520252125222523252425252526252725282529252A252B
252C252D252E252F2530253125322533253425352536253725382539253A253B
253C253D253E253F2540254125422543254425452546254725482549254A254B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
30
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000554A963F57C3632854CE550954C0769A764C85F977EE827E7919611B9698
978D6C285B894FFA630966975CB880FA68489AAF660276CE51F9655671AC7FF1
895650B2596561CA6FB382AD634C625253ED54277B06516B75A45DF462D48DCB
9776628A801958E997387F777238767D67CF767E64FA4F70655762DC7A176591
73ED642C6273822C9812677F7248626E62CC4F3474E3534A8FA67D4690A65E6B
6886699C81807D8168D278C5868C938A508D8B1782DE80DE5305891252650000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
31
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000858496F94FDD582198FD5BF662B1583166B48C799B917206676F789160B2
535153178F2980CC8C9D92C7500D72FD5099618A711988AB595482EF672C7B28
5D297DB3752D6CF58E668FF8903C9F3B6BD491197B465F7C78A784D6853D7562
65836BD65E635E8775F99589655D5F0A5FC58F9F58C181C2907F965B97AD908A
7DE88CB662414FBF8B8A535E8FA88FAF8FAE904D6A195F6A819888689C49618B
522B765F5F6C658C70156FF18CD364EF517551B067C44E1979C9990570B30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
32
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075C55E7673BB83E064AD64A592626CE2535A52C3640F92517B944F2F5E1B
82368116818A6E246CCA99C16355535C54FA88DC57E04E0D5E036B657C3F90E8
601664E6731C88C16750624D8CA1776C8E2991C75F6983DC8521991053C38836
6B98615A615871E684BC825950096EC485CF64CD7CD969FD66F9834953A07B56
5074518C6E2C5C648E6D63D253C9832C833667E578B4643D5BDF5C945DEE8A6B
62C667F48C7A6519647B87EC995E8B927E8F93DF752395E1986B660C73160000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
33
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000583456175E389577511F81785EE0655E66A2553150218D8562849214671D
56326F6E5DE2543570928ECA626F64A463A35FB96F8890F481E38FB058756668
5FF16C8996738D81896F64917A3157CE6A59621054484E587A0B61F26F848AA0
627F901E9A0179E4540375F4630153196C6090725F1B99B3803B9F524F885C3A
8D647FC565A571BE5145885D87F25D075BF562BD916C75878E8A7A2061017C4C
4EC77DA27785919C81ED521D51FA6A7153A88E8792E496DB6EC19664695A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
34
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000790E513277D7641089F8865563E35DDD7A7F693D50B3823955984E327621
7A975E625E8A95D652755439708A6376931857826625693F918755076DF37D14
882262337DBD75B5832878C196CC8FAD614874F78A5E6B64523A8CDC6B218070
847156F153065F9E53E251D17C97918B7C074FC38EA57BE17AC464675D1450AC
810676017CB96DEC7FE067515B585BF878CB64AE641363AA632B932F642D9054
7B5476296253592754466B7950A362345E366B864EE38CB8888B5F85902E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
35
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006020803D64D44E3955AE913264A381BD65E66C2E4F46619A6DE18A955F48
86CB757664CB9EE885696A94520064178E4850125CF679B15C0E52307A3B60BC
905376D75FB75F9776848E6C71C8767B7B4977AA51F3912758244F4E6EF48FEA
65757B1B72C46ECC7FDF5AE162B55E95573084827B2C5E1D5F1F905E7DE0985B
63826EC778989EDE5178975B588A96FB4F4375385E9760E659606FB16BBF7889
53FC96D551CB52016389540A91E38ABF8DCC7239789F87768FED8ADC758A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
36
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E0176EF53EE91D898029F0E93205B9A8A024E22677151AC846361C252D5
68DF4F97606B51CD6D1E515C62969B2596618C46901775D890FD77636BD272A2
73688B80583577798CED675C934D809A5EA66E2159927AEF77ED935B6BB565B7
7DDE58065151968A5C0D58A956788E726566981356E4920D76FE9041638754C6
591A596A579B8EB267358DFA8235524160F058AE86FE5CE89D5D4FC4984D8A1B
5A2560E15384627C904F910299136069800C51528033723E990C6D314E8C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
37
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008CB3767C7F707B4F4F104E4F95A56CD573D085E95E06756A7FFB6A0A792C
91E97E4151E1716953CD8FD47BC48CA972AF98EF6CDB574A82B365B980AA623F
963259A84EFF8A2A7D21653E83F2975E556198DB80A5532A8AB9542080BA5EE2
6CB88CBB82AC915A54296C1B52067D1B58B3711A6C7E7C89596E4EFD5FFF61A4
7CDE8C505C01695387025CF092D298A8760B70FD902299AE7E2B8AF759499CF3
4F5B5426592B6577819A5B75627662C28F3B5E456C1F7B264F0F4FD8670D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
38
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D6E6DAA798F88B15F17752B64AB8F144FEF91DC65A7812F81515E9C8150
8D74526F89868CE65FA950854ED8961C723681798CA05BCC8A0396445A667E1B
54905676560E8A7265396982922384CB6E895E797518674667D17AFF809D8D95
611F79C665628D1B5CA1525B92FC7F38809B7DB15D176E2F67607BD9768B9AD8
818F7F947CD5641E93AC7A3F544A54E56B4C64F162089D3F80F3759952729769
845B683C86E495A39694927B500B54047D6668398DDF801566F45E9A7FB90000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
39
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000057C2803F68975DE5653B529F606D9F944F9B8EAC516C5BAB5F13978F6C5E
62F18CA25171920E52FE6E9D82DF72D757A269CB8CFC591F8F9C83C754957B8D
4F306CBD5B6459D19F1353E488319AA88C3780A16545986756FA96C7522E74DC
526E5BE1630289024E5662D0602A68FA95DC5B9851A089C07BA199287F506163
704C8CAB51495EE3901B7470898F572D78456B789F9C95A88ECC9B3C8A6D7678
68426AC38DEA8CB4528A8F256EDA68CD934B90ED570B679C88F9904E54C80000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009AB85B696D776C264EA55BB399ED916361A890AF97D3542B6DB55BD251FD
558A7F557FF064BC634D65F161BE608D710A6C576F22592F676D822A58D5568E
8C6A6BEB90DD597D8017865F6D695475559D837783CF683879BE548C4F555408
76D28C8995A16CB36DB88D6B89109DB48CC0563F9ED175D55F8872E0606854FC
4EA86A2A886160528F5F54C470D886799D3B6D2A5B8F5F187D0555894FAF7334
543C539A50195F8C547C4E4E5FFD745A58FA846B80E1877472D07CCA6E560000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F27864E552C8B774E926EEC623782B1562983EF733E6ED1756B52835316
8A7169D05F8A61F76DEE58DE6B6174B0685390847DE963DB60A3559A76138C62
71656E195BA65E7B8352614C9EC478FA87577C27768751F060F6714C66435E4C
604D8B0A707063EE8F1D5FBD606286D456DE6BC160946167534960E066668CC4
7A62670371F4532F8AF18AA87E6A8477660F5A5A9B426E3E6DF78C416D3B4F19
706B7372621660D1970D8CA8798D64CA573E57FA6A5F75787A3D7A4D7B950000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000808C99518FF96FC08B4F9DC459EC7E3E7DDD5409697568D88F2F7C4D96C6
53CA602575BE6C7253735AC97D1A64E05E7E810A5DF1858A628051805B634F0E
796D529160B86FDF5BC45BC28A088A1865E25FCC969B59937E7C7D00560967B7
593E4F735BB652A083A298308CC87532924050477A3C50F967B699D55AC16BB2
76E358055C167B8B9593714E517C80A9827159787DD87E6D6AA267EC78B19E7C
63C064BF7C215109526A51CF85A66ABB94528E108CE4898B93757BAD4EF60000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000050658266528D991E6F386FFA6F975EFA50F559DC5C076F3F6C5F75868523
69F3596C8B1B532091AC964D854969127901712681A04EA490CA6F869A555B0C
56BC652A927877EF50E5811A72E189D299037E737D5E527F655991758F4E8F03
53EB7A9663ED63A5768679F88857968E622A52AB7BC0685467706377776B7AED
6F547D5089E359D0621285C982A5754C501F4ECB75A58AA15C4A5DFE7B4B65A4
91D14ECA6D25895F7DCA932650C58B3990329773664979818FD171FC6D780000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000076E152C1834651628396775B66769BE84EAC9A5A7CBE7CB37D934E958B66
666F9838975C5883656C93E15F9175D997567ADF7AF651C870AF7A9863EA7A76
7CFE739697ED4E4570784E5D915253A96551820A81FC8205548E5C31759A97A0
62D872D975BD5C4599D283CA5C40548077E982096CAE805A62D264DA5DE85177
8DDD8E1E92F84FF153E561FC70AC528763509D515A1F5026773753777D796485
652B628963985014723589BA51B38A237D76574783CC921E8ECD541B5CFB0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004FCA7AE36D5A90E199FF55805496536154AF958B63E9697751F16168520A
582A52D8574E780D770B5EB761777CE0625B62974EA27095800362F770E49760
577782DB67EF68F578D5984679D16BBB54B353EF6E34514B523B5BA28AB280AF
554358BE61C75751542D7A7A60505B5463A7647353E362635BC767AF54ED7A9F
82E691775EAB89328A8757AE630E8DE880EF584A7B7751085FEB5BEC6B3E5321
7B5072C268467926773666E051B5866776D45DCB7ABA8475594E9B4150800000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
40
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000994B61276F7057646606634656F062EC64F45ED395CA578362C95587881F
81D88FA35566840A4F868CF485CD5A6A6B0465147C4395CC862D703E8B95652C
89BD61F67E9C721B6FEB7405699472FC5ECA90CE67176D6A648852DE72628001
4F6C59E5916A70D96F8752D26A0296F79433857E78CA7D2F512158D864C2808B
985E6CEA68F1695E51B7539868A872819ECE7C6C72F896E270557406674E88CF
9BC979AE83898354540F68179E9753B252F5792B6B77522950884F8B4FD00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
41
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075E27ACB7C92701D96B8529B748354E95006806F84EE9023942E5EC96190
6F237C3E658281C993C8620071497DF47CE751C968817CB1826F51698F1B91CF
667E4EAE8AD264A9804A50DA764271CE5BE5907C6F664E86648294105ED66599
521788C270C852A373757433679778F7971681E891309C576DCB51DB8CC3541D
62CE73B283F196F69F6192344F367F9A51CC974896755DBA981853E64EE46E9C
740969B4786B993E7559528976246D4167F3516D9F8D807E56A87C607ABF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
42
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000968658DF650F96B46A135A41645F7C0D6F0F964B860676E798715EEC7210
64C46EF7865C9B6F9E93788C97328DEF8CC29E7F6F5E798493329678622E9A62
541592C14FA365C55C655C627E37616E6C2F5F8B73876FFE7DD15DD265235B7F
706453754E8263A0756563848F2A502B4F966DEA7DB88AD6863F87BA7F85908F
947C7C6E9A3E88F8843D6D1B99F17D615ABD9EBB746A78BC879E99AC99E1561B
55CE57CB8CB79EA58CE390818109779E9945883B6EFF851366FC61626F2B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
43
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008B3E8292832B76F26C135FD983BD732B830593286BDB77DB925A536F8302
51925E3D8C8C8CBF9EBD73AB679A68859176970971646CA177095A9293826BCF
7F8E66275BD059B95A9A958060B65011840C84996AAC76DF9333731B59225B5F
772F919A97617CDC8FF78B0E5F4C7C7379D889936CCC871C5BC65E4268C97720
7DBF5195514D52C95A297DEC976282D763CF778485D079D26E3A5EDF59998511
6EC56C1162BF76BF654F61AB95A9660E879F9CF49298540D547D8B2C64780000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
44
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000647986116A21819C78E864699B5462B9672B83AB58A89ED86CAB6F205BDE
964C8B00725F67D062C77261755D59C66BCD589366AE5E5552DF6155672876EE
776672677A4662FF54EA5450920990A35A1C7D0D6C164E435976801059485357
753796E356CA6493816660F19B276DD65462991251855AE980FD59AE9713502A
6CE55C3C64EC4F60533F81A990066EBA852B62C85E7478BE6506637B5FF55A18
91C09CE55C3F634F80765B7D5699947793B36D8560A86AB8737051DD5BE70000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
45
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000064F06FD8725B626D92157D1081BF6FC38FB25F04597452AA601259736696
86507627632A61E67CEF8AFE54E66B509DD76BC685D5561450766F1A556A8DB4
722C5E156015743662CD6392724C5F986E436D3E65006F5876E478D076FC7554
522453DB4E539F9065C1802A80D6629B5486522870AE888D8DD16CE1547880DA
57F988F48CE0966A914D4F696C9B567476C6783062A870F96F8E5F6D84EC68DA
787C7BF781A8670B9D6C636778B0576F78129739627962AB528874356BD70000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
46
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005564813E75B276AE533975DE50FB5C418B6C7BC7504F72479A1998C46F02
74E27968648777A562FC983B8CA754C180584E52576A860B840D5E73619174F6
8A555C4F57616F5198175A4678349B448FEB7C95525664B292EA50D583868461
83E984B257D46A385703666E6D668B5C66DD7011671F6B3A68F2621A59BB4E03
51C46F0667D26C8F517668CB59476B6775665D0E81CD9F4A65D7794879419A0E
8D778C484E5E4F0155535951780C56686C238FC468C46C7D6CE38A1663900000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
47
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000060706D3D727D626691FA925B534390777C3D4EDF8B194E7E9ED493229257
524D6F5B90636DFA8B7458795D4C6B206B4969CD55C681547F8C58BB85945F3A
64366A47936C657260846A4B77A755AC50D15DE7979864AC7FF95CED4FCF7AC5
520783044E14602F7ACA6B3D4FB589AA79E6743452E482B964D279BD5BE26C81
97528F156C2B50BE537F6E0564CE66746C3060C598038ACB617674CA7AAE79CB
4E1890B174036C4256DA914B6CC58DA8534086C666F28EC05C489A456E200000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
48
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000053D65A369F728DA353BB570898746B0A919B6CC9516875CA62F372AC5238
52F87F3A7094763853749D7269B778BA96C088D97FA4713671C3518967D374E4
58E4651856B78B93995264FE7E5E60F971B158EC4EC14EBA5FCD97CC4EFB8A8D
5203598A7D0962544ECD65E5620E833884C969AE878D71946EB65BB97D685197
63C967D480898339881551125B7A59828FB14E736C5D516589258EDF962E854A
745E92ED958F6F6482E55F316492705185A9816E9C13585E8CFD4E0953C10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
49
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000050986563685155D355AA64149A3763835AC2745F82726F8068EE50E7838E
78026BBA52396C997D1750BB5565715E7BE966EC73CA82EB67495C715220717D
886B9583965D64C58D0D81B355846C5562477E55589250B755468CDE664C4E0A
5C1A88F368A2634E7A0D71D2828D52FA97F65C1154E890B57D3959628CD286C7
820C63688D66651D5C0461FE6D89793E8A2D78377533547B4F388EAB6DF15A20
7D33795E6C885BE95B38751A814E614E6EF28072751F7525727253477E690000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000770176DB526952DD80565E2B5931734565BD6FD58A695C388671534177F3
62FE66424EC098DF87555BE68B5853F277E24F7F5C4E99DB59CB5F0F793A58EB
4E1667FF4E8B62ED8A93901D52E2662F55DC566C90694ED54F8D91CB98FE6C0F
5E0260435BA489968A666536624B99965B8858FD6388552E53D776267378852C
6A1E68B36B8A62928F3853D482126DD1758F66F88D165B70719F85AF669166D9
7F7287009ECD9F205C6C88538FF06A39675F620D7AEA58855EB665786F310000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000060555237800D6454887075295E25681362F4971C96D9723D8AB06C347761
7A0E542E77AC9806821C8AAC78A96714720D65AF64955636601D79C153F87D72
6B7B80865BFA55E356DB4F3A4F3C98FC5DF39B068073616B980C90015B8B8A1F
8AA6641C825864FB55FD860791654FD77D20901F7C9F50F358516EAF5BBF8A34
80859178849C7B9796D6968B96A87D8F9AD3788E6B727A57904296A7795F5B6B
640D7B0B84D168AD55067E2E74637D2293966240584C4ED65B83597958540000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000737A64BB8E4B8E0F80CE82D462AC81FA6CF0915E592A614B6C70574D6524
8CAA7671705858C76A8075F06F6D8B5A8AC757666BEF889278B363A2560670AD
6E6F5858642A580268E0819B55107CD650188EBA6DCC8D9F71D9638F6FE46ED4
7E278404684390036DD896768A0E5957727985E49A3075BC8B0468AF52548E22
92BB63D0984C8E44557C9AD466FF568F60D56D9552435C4959296DFB586B7530
751C606C821481466311689D8FE2773A8DF38CBC94355E165EF3807D70F40000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006C405EF7505C4EAD5EAD633A8247901A6850916E77B3540C92855F647AE5
687663457B527D7175DB50776295982D900F51F879C37A8157165F9290145857
5C60571F541051546E4D571863A8983D817F8715892A9000541E5C6F81C062D6
625881319D15964099B199DD6A6259A562D3553E631654C786D97AAA5A0374E6
896A6B6A59168C4C5F4E706373A998114E3870F75B8C7897633D665A769660CB
5B9B5A49842C81556C6A738B4EA167897DB25F8065FA671B5FD859845A010000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005DCD5FAE537197CB90556845570D552F60DF72326FF07DAD8466840E59D4
504950DE5C3E7DEF672A851A5473754F80C355829B4F4F4D6E2D8B025C096170
885B761F6E29868A6587805E7D0B543B7A697D0A554F55E17FC174EE64BE8778
6E267AA9621165A1536763E16C835DEB55DA93A270CF6C618AA35C4B7121856A
68A7543E54346BCB6B664E9463425348821E4F0D4FAE5862620A972766647269
52FF52D9609F8AA4661471996790897F785277FD6670563B5438932B72A70000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A00606F5E0C6089819D591560DC718470EF6EAA6C5072806A8489725E2D
7FD25AB3559C92916D177CFB969962327D30778E87665323971E8F4466875CFD
4FE072F94E0B53A6590F56876380934151484ED99BAE7E9654B88CE2929C8237
95916D8E5F265ACC986F96AA73FE737B7E23817A99217FA161B2967796507DAB
76F853A2947299997BB189446E5891097FD479658A7360F397FF4EAB98055DF7
6A6150CF54118C61856D785D9704524A54EE56C292B76D885BB56DC666C90000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
50
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005C0F5B5D68218096562F7B11654869544E9B6B47874E978B5354633E643A
90AA659C81058AE75BEB68B0537887F961C86CC470098B1D5C5185AA82AF92C5
6B238F9B65B05FFB5FC34FE191C1661F8165732960FA82085211578B5F6290A2
884C91925E78674F602759D3514451F680F853086C7996C4718A4F114FEE7F9E
673D55C592B979C088967D89589F620C9700865A561898085F908A3184C49157
53D965ED5E8F755C60647D6E5A7F7DD27E8C8ED255A75BA361F865CB73840000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
51
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009078766C77297D629774859B5B787A7496EA884052DB718F5FAA65EC8A62
5C0B99B45DE16B896C5B8A138A0A905C8FC558D362BC9D099D2854404E2B82BD
7259869C5D1688596DAF96C5555E4E9E8A1D710954BD95B970DF6DF99E7D56B4
781487125CA95EF68A00985495BB708E6CBF594463A9773C884D6F1482775830
71D553AD786F96C155015F6671305BB48AFA9A576B83592E9D2679E7694A63DA
4F6F760D7F8A6D0B967D6C274EF07662990A6A236F3E90808170599674760000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
52
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006447582F90657A918B2159DA54AC820085E5898180006930564E8036723A
91CE51B64E5F98016396696D844966F3814B591C6DB24E0058F991AB63D692A5
4F9D4F0A886398245937907A79FB510080F075916C825B9C59E85F5D690587FB
501A5DF24E5977E34EE585DD6291661390915C7951045F7981C69038808475AB
4EA688D4610F6BC561B67FA976CA6EA28A638B708ABC8B6F5F027FFC7FCC7E79
8335852D56E06BB797F3967059FB541F92806DEB5BC598F25C395F1596B10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
53
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000537082F16AFB5B309DF961C97E93746987A271DF719288058FCE8D0F76C8
5F717A4E786C662055B264C150AD81C376705EB896CD8E3486F9548F6CF36D8C
6C38607F52C775285E7D512A60A061825C24753190F5923E73366CB96E389149
670953CB53F34F5191C98A9853C85E7C8FC26DE44E8E76C26986865E611A8F3F
99184FDE903E9B5A61096E1D6F0196854E885A3196E882075DBC79B95B878A9E
7FBD738957DF828B9B315401904755BB5CEA5FA161086B32734480B28B7D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D745BD388D598108C6B99AD9D1B6DF551A4514357A38881539F63F48F45
571254E15713733F6E907DE3906082D198586028966266F07D048D8A8E8D9470
5CB37CA4670860A695B2801896F29116530096955141904B85F49196668897F5
5B55531D783896DC683D54C9707E5BB08F09518D572854B1652266AB8D0A8D1C
81DF846C906D7CDF947F85FB68D765E96FA186A48E81566A902076827AC871E5
8CAC64C752476FA48CCA600E589E618E66FE8D08624E55B36E23672D8ECB0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
55
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000935895987728680569A8548B4E4D70B88A5064589F4B5B857A8450B55BE8
77BB6C088A797C986CBE76DE65AC8F3E5D845C55863868E7536062307AD96E5B
7DBB6A1F7AE05F706F335F35638C6F3267564E085E338CEC4ED781397634969C
62DB662D627E6CBC8D9971677F695146808753EC906E629854F287C48F4D8005
937A851790196D5973CD659F771F7504782781FB8C9E91DD5075679575B98A3A
9707632F93AE966384B86399775C5F817319722D6014657462EF6B63653F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
56
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005E407665912D8B49829D679D652F5431871877E580A281026C414E4B7E54
807776F4690D6B9657F7503C4F84574063076B628DBE887965E87D195FD7646F
64F281F381F47F6E5E5F5CD95236667A79E97A1A8CEA709975D46EEF6CBB7A92
4E2D76C55FE0941888777D427A2E816B91CD4EF28846821F54685DDE6D328B05
7CA58EF880985E1A549276BA5B99665D9A5F73E0682A86DB6731732A8AF88A85
90107AF971ED716E62C477DA56D14E3B845767F152A986C08CAF94447BC90000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
57
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F4F6CE8795D99D06293722A62FD5C0878DA8F4964B08CFA7BC66A01838A
88DD599D649E58EF72C0690E93108FFD8D05589C7DB48AC46E96634962D95353
684C74228301914C55447740707C6FC1517954A88CC759FF6ECB6DC45B5C7D2B
4ED47C7D6ED35B5081EA6F2C5B579B0368D58E2A5B977D9C7E3D7E3191128D70
594F63CD79DF8DB3535265CF79568A5B963B7D44947D7E825634918967007F6A
5C0A907566285DE64F5067DE505A4F5C57505EA7000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
58
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E8D4E0C51404E105EFF53454E154E984E1E9B325B6C56694E2879BA4E3F
53154E47592D723B536E6C1056DF80E499976BD3777E9F174E364E9F9F104E5C
4E694E9382885B5B55C7560F4EC45399539D53B453A553AE97688D0B531A53F5
532D5331533E8CFE5366536352025208520E52445233528C5274524C525E5261
525C84AF527D528252815290529351827F544EBB4EC34EC94EC24EE84EE14EEB
4EDE50B44EF34F224F644EF5500050964F094F474F5E4F6765384F5A4F5D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F5F4F574F324F3D4F764F744F914F894F834F8F4F7E4F7B51154F7C5102
4F945114513C51374FC54FDA4FE34FDC4FD14FDF4FF85029504C4FF3502C500F
502E502D4FFE501C500C5025502850E8504350555048504E506C50C2513B5110
513A50BA50D6510650ED50EC50E650EE5107510B4EDD6C3D4F5850C94FCE9FA0
6C467CF4516E5DFD9ECC999856C5591452F9530D8A0753109CEC591951554EA0
51564EB3886E88A4893B81E088D279805B3488037FB851AB51B151BD51BC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000051C7519651A251A58A018A108A0C8A158B338A4E8A258A418A368A468A54
8A588A528A868A848A7F8A708A7C8A758A6C8A6E8ACD8AE28A618A9A8AA58A91
8A928ACF8AD18AC98ADB8AD78AC28AB68AF68AEB8B148B018AE48AED8AFC8AF3
8AE68AEE8ADE8B288B9C8B168B1A8B108B2B8B2D8B568B598B4E8B9E8B6B8B96
5369537A961D962296219631962A963D963C964296589654965F9689966C9672
96749688968D969796B09097909B913A9099911490A190B490B390B691340000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000090B890B090DF90C590BE913690C490C79106914890E290DC90D790DB90EB
90EF90FE91049122911E91239131912F91399143914682BB595052F152AC52AD
52BE54FF52D052D652F053DF71EE77CD5EF451F551FC9B2F53B65F01755A5DF0
574C580A57A1587E58BC58C558D15729572C572A573358D9572E572F58E2573B
5742576958E0576B58DA577C577B5768576D5776577357E157A4578C584F57CF
57A75816579357A057D55852581D586457D257B857F457EF57F857E457DD0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000580B580D57FD57ED5800581E5819584458205865586C58815889589A5880
99A89F1961FF8279827D827F828F828A82A88284828E8291858C829982AB8553
82BE82B085F682CA82E3829882B782AE83A7840784EF82A982B482A182AA829F
82C482E782A482E1830982F782E48622830782DC82F482D282D8830C82FB82D3
8526831A8306584B716282E082D5831C8351855884FD83088392833C83348331
839B854E832F834F8347834385888340831785BA832D833A833372966ECE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008541831B85CE855284C08452846483B083788494843583A083AA8393839C
8385837C859F83A9837D8555837B8398839E83A89DAF849383C1840183E583D8
58078418840B83DD83FD83D6841C84388411840683D483DF840F840383F883F9
83EA83C583C07E0883F083E1845C8451845A8459847385468488847A85628478
843C844684698476851E848E8431846D84C184CD84D09A4084BD84D384CA84BF
84BA863A84A184B984B4849793A38577850C750D853884F0861E851F85FA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008556853B84FF84FC8559854885688564855E857A77A285438604857B85A4
85A88587858F857985EA859C858585B985B785B0861A85C185DC85FF86278605
86298616863C5EFE5F08593C596980375955595A5958530F5C225C255C2C5C37
624C636B647662BB62CA62DA62D762EE649F62F66339634B634363AD63F66371
637A638E6451636D63AC638A636963AE645C63F263F863E064B363C463DE63CE
645263C663BE65046441640B641B6420640C64266421645E6516646D64960000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000647A64F764FC6499651B64C064D064D764E464E265096525652E5F0B5FD2
75195F11535F53F1563053E953E853FB541254165406544B563856C8545456A6
54435421550454BC5423543254825494547754715464549A5680548454765466
565D54D054AD54C254B4566054A754A6563555F6547254A3566654BB54BF54CC
567254DA568C54A954AA54A4566554CF54DE561C54E7562E54FD551454F355E9
5523550F55115527552A5616558F55B5554956C055415555553F5550553C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
60
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005537555655755576557755335530555C558B55D2558355B155B955885581
559F557E55D65591557B55DF560D56B35594559955EA55F755C9561F55D156C1
55EC55D455E655DD55C455EF55E555F2566F55CC55CD55E855F555E48F61561E
5608560C560156B6562355FE56005627562D565856395657562C564D56625659
5695564C5654568656645671566B567B567C5685569356AF56D456D756DD56E1
570756EB56F956FF5704570A5709571C5E435E195E145E115E6C5E585E570000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
61
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005E375E445E545E5B5E5E5E615C8C5C7A5C8D5C905D875C885CF45C995C91
5D505C9C5CB55CA25D2C5CAC5CAB5CB15CA35CC15CB75DA75CD25DA05CCB5D22
5D975D0D5D275D265D2E5D245D1E5D065D1B5DB85D3E5D345D3D5D6C5D5B5D6F
5D815D6B5D4B5D4A5D695D745D825D995D9D8C735DB75DD45F735F775F825F87
5F89540E5FA05F995F9C5FA85FAD5FB55FBC88625F6172AD72B072B473777341
72C372C172CE72CD72D272E8736A72E9733B72F472F7730172F3736B72FA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
62
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000072FB731773137380730A731E731D737C732273397325732C733873317350
734D73577360736C736F737E821B592598E75924590298E0993398E9993C98EA
98EB98ED98F4990999114F59991B9937993F994399489949994A994C99625E80
5EE15E8B5E965EA55EA05EB95EB55EBE5EB38CE15ED25ED15EDB5EE85EEA81BA
5FC45FC95FD661FA61AE5FEE616A5FE15FE4613E60B561345FEA5FED5FF86019
60356026601B600F600D6029602B600A61CC6021615F61E860FB613760420000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
63
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000606A60F26096609A6173609D60836092608C609B611C60BB60B160DD60D8
60C660DA60B4612061926115612360F46100610E612B614A617561AC619461A7
61B761D461F55FDD96B39582958695C8958E9594958C95E595AD95AB9B2E95AC
95BE95B69B2995BF95BD95BC95C395CB95D495D095D595DE4E2C723F62156C35
6C546C5C6C4A70436C856C906C946C8C6C686C696C746C766C866F596CD06CD4
6CAD702770186CF16CD76CB26CE06CD66FFC6CEB6CEE6CB16CD36CEF6D870000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
64
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D396D276D0C6D796E5E6D076D046D196D0E6D2B6FAE6D2E6D356D1A700F
6EF86F6F6D336D916D6F6DF66F7F6D5E6D936D946D5C6D606D7C6D636E1A6DC7
6DC56DDE70066DBF6DE06FA06DE66DDD6DD9700B6DAB6E0C6DAE6E2B6E6E6E4E
6E6B6EB26E5F6E866E536E546E326E256E4470676EB16E9870446F2D70056EA5
6EA76EBD6EBB6EB76F776EB46ECF6E8F6EC26E9F6F627020701F6F246F156EF9
6F2F6F3670326F746F2A6F096F296F896F8D6F8C6F786F726F7C6F7A70280000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
65
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006FC96FA76FB96FB66FC26FE16FEE6FDE6FE06FEF701A7023701B70397035
705D705E5B805B845B955B935BA55BB8752F9A2B64345BE45BEE89305BF08E47
8B078FB68FD38FD58FE58FEE8FE490878FE690158FE890059004900B90909011
900D9016902190359036902D902F9044905190529050906890589062905B66B9
9074907D908290889083908B5F505F575F565F585C3B54AB5C505C595B715C63
5C687FBC5F335F295F2D82745F3C9B3B5C6E59815983598D5AF55AD759A30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
66
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000599759CA5B00599E59A459D259B259AF59D759BE5A6D5B0859DD5B4C59E3
59D859F95A0C5A095AA75AFB5A115A235A135A405A675A4A5A555A3C5A625B0B
80EC5AAA5A9B5A775A7A5ABE5AEB5AB25B215B2A5AB85AE05AE35B195AD65AE6
5AD85ADC5B095B175B165B325B375B405C155C1C5B5A5B655B735B515B535B62
99D499DF99D99A369A5B99D199D89A4D9A4A99E29A6A9A0F9A0D9A059A429A2D
9A169A419A2E9A389A439A449A4F9A659A647CF97D067D027D077D087E8A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
67
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007D1C7D157D137D3A7D327D317E107D3C7D407D3F7D5D7D4E7D737D867D83
7D887DBE7DBA7DCB7DD47DC47D9E7DAC7DB97DA37DB07DC77DD97DD77DF97DF2
7E627DE67DF67DF17E0B7DE17E097E1D7E1F7E1E7E2D7E0A7E117E7D7E397E35
7E327E467E457E887E5A7E527E6E7E7E7E707E6F7E985E7A757F5DDB753E9095
738E74A3744B73A2739F73CF73C274CF73B773B373C073C973C873E573D9980A
740A73E973E773DE74BD743F7489742A745B7426742574287430742E742C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
68
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000741B741A7441745C74577455745974A6746D747E749C74D4748074817487
748B749E74A874A9749074A774DA74BA97D997DE97DC674C6753675E674869AA
6AEA6787676A677367986898677568D66A05689F678B6777677C67F06ADB67D8
6AF367E967B06AE867D967B567DA67B367DD680067C367B867E26ADF67C16A89
68326833690F6A48684E6968684469BF6883681D68556A3A68416A9C68406B12
684A6849682968B5688F687468776893686B6B1E696E68FC6ADD69E768F90000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
69
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006B0F68F0690B6901695768E369106971693969606942695D6B16696B6980
69986978693469CC6AEC6ADA69CE6AF8696669636979699B69A769BB69AB69AD
69D469B169C169CA6AB369956AE7698D69FF6AA369ED6A176A186A6569F26A44
6A3E6AA06A506A5B6A356A8E6AD36A3D6A286A586ADE6A916A906AA96A976AAB
733773526B816B826BA46B846B9E6BAE6B8D6BAB6B9B6BAF6BAA8ED48EDB8EF2
8EFB8F648EF98EFC8EEB8EE48F628EFA8EFE8F0A8F078F058F128F268F1E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008F1F8F1C8F338F468F548ECE62146227621B621F62226221622562246229
81E7750C74F474FF750F75117513653465EE65EF65F0660A66C7677266036615
6600708566F7661D66346631663666358006665F66C46641664F668966616657
66776684668C66D6669D66BE66DB66DC66E666E98CC18CB08CBA8CBD8D048CB2
8CC58D108CD18CDA8CD58CEB8CE78CFB899889AC89A189BF89A689AF89B289B7
726E729F725D7266726F727E727F7284728B728D728F72926308633263B00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000643F64D880046BEA6BF36BFD6BFF6BF96C056C0C6C066C0D6C156C186C19
6C1A6C216C2C6C246C2A6C3265356555656B725872527256723086625216809F
809C809380BC670A80BD80B180AB80AD80B480B76727815680E981DA80DB80C2
80C480D980CD80D7671080DD811B80F180F480ED81BE810E80F280FC67158112
8C5A8161811E812C811881328148814C815381748159815A817181608169817C
817D816D8167584D5AB58188818281CF6ED581A381AA81CC672681CA81BB0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000081C181A66B5F6B376B396B436B466B5998AE98AF98B698BC98C698C86BB3
5F408F4289F365909F4F659565BC65C665C465C365CC65CE65D265D6716C7152
7096719770BB70C070B770AB70B171C170CA7110711371DC712F71317173715C
716871457172714A7178717A719871B371B571A871A071E071D471E771F9721D
7228706C71FE716671B9623E623D624362486249793B794079467949795B795C
7953795A79B079577960798E7967797A79AA798A799A79A779B35FD15FD00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000061DF605D605A606760416059606361646106610D615D61A9619D61CB61E3
62078080807F6C936FA96DFC78EF77F878AD780978687818781165AB782D78B8
781D7839792A7931781F783C7825782C78237829784E786D786478FD78267850
7847784C786A78E77893789A788778E378A178A378B278B978A578D478D978C9
78EC78F2790578F479137924791E79349F959EF99EFB9EFC76F17704779876F9
77077708771A77227719772D772677357738775E77BC77477743775A77680000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077627765777F778D777D7780778C7791779F77A077B077B577BD753A7540
754E754B7548755B7572757975837F587F617F5F8A487F687F867F717F797F88
7F7E76CD76E5883291D291D391D491D991D791D591F791E791E4934691F591F9
9208922692459211921092019227920492259200923A9266923792339255923D
9238925E926C926D923F9460923092499248924D922E9239943892AC92A0927A
92AA92EE92CF940392E3943A92B192A693A7929692CC92A993F59293927F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000093A9929A931A92AB9283940B92A892A39412933892F193D792E592F092EF
92E892BC92DD92F69426942792C392DF92E6931293069369931B934093019315
932E934393079308931F93199365934793769354936493AA9370938493E493D8
9428938793CC939893B893BF93A693B093B5944C93E293DC93DD93CD93DE93C3
93C793D19414941D93F794659413946D9420947993F99419944A9432943F9454
9463937E77E777EC96C979D579ED79E379EB7A065D477A037A027A1E7A140000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
70
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A397A377A619ECF99A57A707688768E7693769976A474DE74E0752C9CE9
9CF69D079D069D239D879E159D1D9D1F9DE59D2F9DD99D309D429E1E9D539E1D
9D609D529DF39D5C9D619D939D6A9D6F9D899D989D9A9DC09DA59DA99DC29DBC
9E1A9DD39DDA9DEF9DE69DF29DF89E0C9DFA9E1B7592759476647658759D7667
75A375B375B475B875C475B175B075C375C2760275CD75E3764675E675E47647
75E7760375F175FC75FF761076007649760C761E760A7625763B761576190000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
71
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000761B763C762276207640762D7630766D76357643766E7633764D76697654
765C76567672766F7FCA7AE67A787A797A807A867A887A957AC77AA07AAC7AA8
7AB67AB3886488698872887D887F888288A2896088B788BC88C9893388CE895D
894788F1891A88FC88E888FE88F08921891989138938890A8964892B89368941
8966897B758B80E576B876B477DC801280148016801C8020802E80258026802C
802980288031800B803580438046807980528075807189839807980E980F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
72
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009821981C6F4198269837984E98539873986298599865986C9870864D8654
866C87E38806867A867C867B86A8868D868B8706869D86A786A386AA869386A9
86B686C486B5882386B086BA86B186AF86C987F686B486E986FA87EF86ED8784
86D0871386DE881086DF86D886D18703870786F88708870A870D87098723873B
871E8725872E871A873E87C88734873187298737873F87828722877D8811877B
87608770874C876E878B8753876387BB876487598765879387AF87CE87D20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
73
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000087C68788878587AD8797878387AB87E587AC87B587B387CB87D387BD87D1
87C087CA87DB87EA87E087EE8816881387FE880A881B88218839883C7F367F4C
7F447F4582107AFA7AFD7B087BE47B047B677B0A7B2B7B0F7B477B387B2A7B19
7B2E7B317B207B257B247B337C697B1E7B587BF37B457B757B4C7B8F7B607B6E
7B7B7B627B727B717B907C007BCB7BB87BAC7B9D7C5C7B857C1E7B9C7BA27C2B
7BB47C237BC17BCC7BDD7BDA7BE57BE67BEA7C0C7BFE7BFC7C0F7C6A7C0B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
74
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007C1F7C2A7C267C387C5F7C4081FE82018202820481EC8844822182228264
822D822F8228822B8238826B82338234823E82448249824B824F825A825F8268
887E88CA888888D888DF895E7F9D7FA57FA77FAF7FB07FB27C7C65497C917CF2
7CF67C9E7CA27CB27CBC7CBD7CDD7CC77CCC7CCD7CC87CC57CD77CE8826E66A8
7FBF7FCE7FD57FE57FE17FE67FE97FEE7FF37CF87E367DA67DAE7E477E9B9EA9
9EB48D738D848D948D918DB28D678D6D8C478C49914A9150914E914F91640000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
75
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009162916191709169916F91C591C3917291749179918C91859190918D9191
91A291A391AA91AD91AE91AF91B591B491BA8C559E7A8E898DEB8E058E598E69
8DB58DBF8DBC8DBA8E4C8DD68DD78DDA8E928DCE8DCF8DDB8DC68DEC8E7A8E55
8DE38E9A8E8B8DE48E098DFD8E148E1D8E1F8E938E2E8E238E918E3A8E408E39
8E358E3D8E318E498E418E428EA18E638E4A8E708E768E7C8E6F8E748E858EAA
8E948E908EA68E9E8C788C828C8A8C858C988C94659B89D689F489DA89DC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
76
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000089E589EB89F68A3E8B26975A96E9974296EF9706973D9708970F970E972A
97449730973E9F549F5F9F599F609F5C9F669F6C9F6A9F779EFD9EFF9F0996B9
96BC96BD96CE96D277BF8B8E928E947E92C893E8936A93CA938F943E946B9B77
9B749B819B839B8E9C787A4C9B929C5F9B909BAD9B9A9BAA9B9E9C6D9BAB9B9D
9C589BC19C7A9C319C399C239C379BC09BCA9BC79BFD9BD69BEA9BEB9BE19BE4
9BE79BDD9BE29BF09BDB9BF49BD49C5D9C089C109C0D9C129C099BFF9C200000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
77
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009C329C2D9C289C259C299C339C3E9C489C3B9C359C459C569C549C529C67
977C978597C397BD979497C997AB97A397B297B49AB19AB09AB79DBB9AB69ABA
9ABC9AC19AC09ACF9AC29AD69AD59AD19B459B439B589B4E9B489B4D9B519957
995C992E995599549ADF9AE19AE69AEF9AEB9AFB9AED9AF99B089B0F9B229B1F
9B234E489EBE7E3B9E829E879E889E8B9E9293D69E9D9E9F9EDB9EDC9EDD9EE0
9EDF9EE29EF79EE79EE59EF29EEF9F229F2C9F2F9F399F379F3D9F3E9F440000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
78
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000896C95C693365F4685147E94538251B24E119F635679515A6DC09F156597
56419AEE83034E3089075E727A4098B35E7F95A49B0D52128FF45F597A6B98E2
51E050A24EF7835085915118636E6372524B5938774F8721814A7E8D91CC66C6
5E1877AD9E7556C99EF46FDB61DE77C770309EB5884A95E282F951ED62514EC6
673497C67C647E3497A69EAF786E820D672F677E56CC53F098B16AAF7F4E6D82
7CF04E074FC27E6B9E7956AE9B1A846F53F690C179A67C72613F4E919AD20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
79
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075C796BB53EA7DFB88FD79CD78437B5151C6000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/gb1988.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: gb1988, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
002000210022002300A500250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D203E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
# Encoding file: gb2312, double-byte
D
233F 0 81
21
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030003001300230FB02C902C700A8300330052015FF5E2225202620182019
201C201D3014301530083009300A300B300C300D300E300F3016301730103011
00B100D700F72236222722282211220F222A222922082237221A22A522252220
23122299222B222E2261224C2248223D221D2260226E226F22642265221E2235
22342642264000B0203220332103FF0400A4FFE0FFE1203000A7211626062605
25CB25CF25CE25C725C625A125A025B325B2203B219221902191219330130000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
22
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000024882489248A248B248C248D248E248F2490249124922493249424952496
249724982499249A249B247424752476247724782479247A247B247C247D247E
247F248024812482248324842485248624872460246124622463246424652466
2467246824690000000032203221322232233224322532263227322832290000
00002160216121622163216421652166216721682169216A216B000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
23
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF01FF02FF03FFE5FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFF3CFF3DFF3EFF3F
FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
24
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000304130423043304430453046304730483049304A304B304C304D304E304F
3050305130523053305430553056305730583059305A305B305C305D305E305F
3060306130623063306430653066306730683069306A306B306C306D306E306F
3070307130723073307430753076307730783079307A307B307C307D307E307F
3080308130823083308430853086308730883089308A308B308C308D308E308F
3090309130923093000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
25
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
26
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000039103920393039403950396039703980399039A039B039C039D039E039F
03A003A103A303A403A503A603A703A803A90000000000000000000000000000
000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C303C403C503C603C703C803C90000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
27
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000004100411041204130414041504010416041704180419041A041B041C041D
041E041F0420042104220423042404250426042704280429042A042B042C042D
042E042F00000000000000000000000000000000000000000000000000000000
000004300431043204330434043504510436043704380439043A043B043C043D
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
28
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000010100E101CE00E0011300E9011B00E8012B00ED01D000EC014D00F301D2
00F2016B00FA01D400F901D601D801DA01DC00FC00EA00000000000000000000
0000000000000000000031053106310731083109310A310B310C310D310E310F
3110311131123113311431153116311731183119311A311B311C311D311E311F
3120312131223123312431253126312731283129000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
29
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000002500250125022503250425052506250725082509250A250B
250C250D250E250F2510251125122513251425152516251725182519251A251B
251C251D251E251F2520252125222523252425252526252725282529252A252B
252C252D252E252F2530253125322533253425352536253725382539253A253B
253C253D253E253F2540254125422543254425452546254725482549254A254B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
30
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000554A963F57C3632854CE550954C07691764C853C77EE827E788D72319698
978D6C285B894FFA630966975CB880FA684880AE660276CE51F9655671AC7FF1
888450B2596561CA6FB382AD634C625253ED54277B06516B75A45DF462D48DCB
9776628A8019575D97387F627238767D67CF767E64464F708D2562DC7A176591
73ED642C6273822C9881677F7248626E62CC4F3474E3534A529E7ECA90A65E2E
6886699C81807ED168D278C5868C9551508D8C2482DE80DE5305891252650000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
31
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000858496F94FDD582199715B9D62B162A566B48C799C8D7206676F789160B2
535153178F8880CC8D1D94A1500D72C8590760EB711988AB595482EF672C7B28
5D297EF7752D6CF58E668FF8903C9F3B6BD491197B145F7C78A784D6853D6BD5
6BD96BD65E015E8775F995ED655D5F0A5FC58F9F58C181C2907F965B97AD8FB9
7F168D2C62414FBF53D8535E8FA88FA98FAB904D68075F6A819888689CD6618B
522B762A5F6C658C6FD26EE85BBE6448517551B067C44E1979C9997C70B30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
32
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075C55E7673BB83E064AD62E894B56CE2535A52C3640F94C27B944F2F5E1B
82368116818A6E246CCA9A736355535C54FA886557E04E0D5E036B657C3F90E8
601664E6731C88C16750624D8D22776C8E2991C75F6983DC8521991053C28695
6B8B60ED60E8707F82CD82314ED36CA785CF64CD7CD969FD66F9834953957B56
4FA7518C6D4B5C428E6D63D253C9832C833667E578B4643D5BDF5C945DEE8BE7
62C667F48C7A640063BA8749998B8C177F2094F24EA7961098A4660C73160000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
33
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000573A5C1D5E38957F507F80A05382655E7545553150218D856284949E671D
56326F6E5DE2543570928F66626F64A463A35F7B6F8890F481E38FB05C186668
5FF16C8996488D81886C649179F057CE6A59621054484E587A0B60E96F848BDA
627F901E9A8B79E4540375F4630153196C608FDF5F1B9A70803B9F7F4F885C3A
8D647FC565A570BD514551B2866B5D075BA062BD916C75748E0C7A2061017B79
4EC77EF877854E1181ED521D51FA6A7153A88E87950496CF6EC19664695A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
34
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000784050A877D7641089E6590463E35DDD7A7F693D4F20823955984E3275AE
7A975E625E8A95EF521B5439708A6376952457826625693F918755076DF37EAF
882262337EF075B5832878C196CC8F9E614874F78BCD6B64523A8D506B21806A
847156F153064ECE4E1B51D17C97918B7C074FC38E7F7BE17A9C64675D1450AC
810676017CB96DEC7FE067515B585BF878CB64AE641363AA632B9519642D8FBE
7B5476296253592754466B7950A362345E266B864EE38D37888B5F85902E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
35
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006020803D62C54E39535590F863B880C665E66C2E4F4660EE6DE18BDE5F39
86CB5F536321515A83616863520063638E4850125C9B79775BFC52307A3B60BC
905376D75FB75F9776848E6C706F767B7B4977AA51F3909358244F4E6EF48FEA
654C7B1B72C46DA47FDF5AE162B55E95573084827B2C5E1D5F1F90127F1498A0
63826EC7789870B95178975B57AB75354F4375385E9760E659606DC06BBF7889
53FC96D551CB52016389540A94938C038DCC7239789F87768FED8C0D53E00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
36
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E0176EF53EE948998769F0E952D5B9A8BA24E224E1C51AC846361C252A8
680B4F97606B51BB6D1E515C6296659796618C46901775D890FD77636BD2728A
72EC8BFB583577798D4C675C9540809A5EA66E2159927AEF77ED953B6BB565AD
7F0E58065151961F5BF958A954288E726566987F56E4949D76FE9041638754C6
591A593A579B8EB267358DFA8235524160F0581586FE5CE89E454FC4989D8BB9
5A2560765384627C904F9102997F6069800C513F80335C1499756D314E8C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
37
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008D3053D17F5A7B4F4F104E4F96006CD573D085E95E06756A7FFB6A0A77FE
94927E4151E170E653CD8FD483038D2972AF996D6CDB574A82B365B980AA623F
963259A84EFF8BBF7EBA653E83F2975E556198DE80A5532A8BFD542080BA5E9F
6CB88D3982AC915A54296C1B52067EB7575F711A6C7E7C89594B4EFD5FFF6124
7CAA4E305C0167AB87025CF0950B98CE75AF70FD902251AF7F1D8BBD594951E4
4F5B5426592B657780A45B75627662C28F905E456C1F7B264F0F4FD8670D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
38
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D6E6DAA798F88B15F17752B629A8F854FEF91DC65A7812F81515E9C8150
8D74526F89868D4B590D50854ED8961C723681798D1F5BCC8BA3964459877F1A
54905676560E8BE565396982949976D66E895E727518674667D17AFF809D8D76
611F79C665628D635188521A94A27F38809B7EB25C976E2F67607BD9768B9AD8
818F7F947CD5641E95507A3F544A54E56B4C640162089E3D80F3759952729769
845B683C86E49601969494EC4E2A54047ED968398DDF801566F45E9A7FB90000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
39
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000057C2803F68975DE5653B529F606D9F9A4F9B8EAC516C5BAB5F135DE96C5E
62F18D21517194A952FE6C9F82DF72D757A267848D2D591F8F9C83C754957B8D
4F306CBD5B6459D19F1353E486CA9AA88C3780A16545987E56FA96C7522E74DC
52505BE1630289024E5662D0602A68FA51735B9851A089C27BA199867F5060EF
704C8D2F51495E7F901B747089C4572D78455F529F9F95FA8F689B3C8BE17678
684267DC8DEA8D35523D8F8A6EDA68CD950590ED56FD679C88F98FC754C80000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009AB85B696D776C264EA55BB39A87916361A890AF97E9542B6DB55BD251FD
558A7F557FF064BC634D65F161BE608D710A6C576C49592F676D822A58D5568E
8C6A6BEB90DD597D801753F76D695475559D837783CF683879BE548C4F555408
76D28C8996026CB36DB88D6B89109E648D3A563F9ED175D55F8872E0606854FC
4EA86A2A886160528F7054C470D886799E3F6D2A5B8F5F187EA255894FAF7334
543C539A5019540E547C4E4E5FFD745A58F6846B80E1877472D07CCA6E560000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F27864E552C62A44E926CAA623782B154D7534E733E6ED1753B52125316
8BDD69D05F8A60006DEE574F6B2273AF68538FD87F13636260A3552475EA8C62
71156DA35BA65E7B8352614C9EC478FA87577C27768751F060F6714C66435E4C
604D8C0E707063258F895FBD606286D456DE6BC160946167534960E066668D3F
79FD4F1A70E96C478BB38BF27ED88364660F5A5A9B426D516DF78C416D3B4F19
706B83B7621660D1970D8D27797851FB573E57FA673A75787A3D79EF7B950000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000808C99658FF96FC08BA59E2159EC7EE97F095409678168D88F917C4D96C6
53CA602575BE6C7253735AC97EA7632451E0810A5DF184DF628051805B634F0E
796D524260B86D4E5BC45BC28BA18BB065E25FCC964559937EE77EAA560967B7
59394F735BB652A0835A988A8D3E753294BE50477A3C4EF767B69A7E5AC16B7C
76D1575A5C167B3A95F4714E517C80A9827059787F04832768C067EC78B17877
62E363617B804FED526A51CF835069DB92748DF58D3189C1952E7BAD4EF60000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000506582305251996F6E106E856DA75EFA50F559DC5C066D466C5F7586848B
686859568BB253209171964D854969127901712680F64EA490CA6D479A845A07
56BC640594F077EB4FA5811A72E189D2997A7F347EDE527F655991758F7F8F83
53EB7A9663ED63A5768679F888579636622A52AB8282685467706377776B7AED
6D017ED389E359D0621285C982A5754C501F4ECB75A58BEB5C4A5DFE7B4B65A4
91D14ECA6D25895F7D2795264EC58C288FDB9773664B79818FD170EC6D780000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005C3D52B283465162830E775B66769CB84EAC60CA7CBE7CB37ECF4E958B66
666F988897595883656C955C5F8475C997567ADF7ADE51C070AF7A9863EA7A76
7EA0739697ED4E4570784E5D915253A9655165E781FC8205548E5C31759A97A0
62D872D975BD5C459A7983CA5C40548077E94E3E6CAE805A62D2636E5DE85177
8DDD8E1E952F4FF153E560E770AC526763509E435A1F5026773753777EE26485
652B628963985014723589C951B38BC07EDD574783CC94A7519B541B5CFB0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004FCA7AE36D5A90E19A8F55805496536154AF5F0063E9697751EF6168520A
582A52D8574E780D770B5EB761777CE0625B62974EA27095800362F770E49760
577782DB67EF68F578D5989779D158F354B353EF6E34514B523B5BA28BFE80AF
554357A660735751542D7A7A60505B5463A762A053E362635BC767AF54ED7A9F
82E691775E9388E4593857AE630E8DE880EF57577B774FA95FEB5BBD6B3E5321
7B5072C2684677FF773665F751B54E8F76D45CBF7AA58475594E9B4150800000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
40
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000998861276E8357646606634656F062EC62695ED39614578362C955878721
814A8FA3556683B167658D5684DD5A6A680F62E67BEE961151706F9C8C3063FD
89C861D27F0670C26EE57405699472FC5ECA90CE67176D6A635E52B372628001
4F6C59E5916A70D96D9D52D24E5096F7956D857E78CA7D2F5121579264C2808B
7C7B6CEA68F1695E51B7539868A872819ECE7BF172F879BB6F137406674E91CC
9CA4793C83898354540F68174E3D538952B1783E5386522950884F8B4FD00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
41
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075E27ACB7C926CA596B6529B748354E94FE9805483B28FDE95705EC9601C
6D9F5E18655B813894FE604B70BC7EC37CAE51C968817CB1826F4E248F8691CF
667E4EAE8C0564A9804A50DA759771CE5BE58FBD6F664E86648295635ED66599
521788C270C852A3730E7433679778F797164E3490BB9CDE6DCB51DB8D41541D
62CE73B283F196F69F8494C34F367F9A51CC707596755CAD988653E64EE46E9C
740969B4786B998F7559521876246D4167F3516D9F99804B54997B3C7ABF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
42
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009686578462E29647697C5A0464027BD36F0F964B82A6536298855E907089
63B35364864F9C819E93788C97328DEF8D429E7F6F5E79845F559646622E9A74
541594DD4FA365C55C655C617F1586516C2F5F8B73876EE47EFF5CE6631B5B6A
6EE653754E7163A0756562A18F6E4F264ED16CA67EB68BBA841D87BA7F57903B
95237BA99AA188F8843D6D1B9A867EDC59889EBB739B780186829A6C9A82561B
541757CB4E709EA653568FC881097792999286EE6EE1851366FC61626F2B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
43
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008C298292832B76F26C135FD983BD732B8305951A6BDB77DB94C6536F8302
51925E3D8C8C8D384E4873AB679A68859176970971646CA177095A9295416BCF
7F8E66275BD059B95A9A95E895F74EEC840C84996AAC76DF9530731B68A65B5F
772F919A97617CDC8FF78C1C5F257C7379D889C56CCC871C5BC65E4268C97720
7EF55195514D52C95A297F05976282D763CF778485D079D26E3A5E9959998511
706D6C1162BF76BF654F60AF95FD660E879F9E2394ED540D547D8C2C64780000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
44
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000647986116A21819C78E864699B5462B9672B83AB58A89ED86CAB6F205BDE
964C8C0B725F67D062C772614EA959C66BCD589366AE5E5552DF6155672876EE
776672677A4662FF54EA545094A090A35A1C7EB36C164E435976801059485357
753796BE56CA63208111607C95F96DD65462998151855AE980FD59AE9713502A
6CE55C3C62DF4F60533F817B90066EBA852B62C85E7478BE64B5637B5FF55A18
917F9E1F5C3F634F80425B7D556E954A954D6D8560A867E072DE51DD5B810000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
45
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000062E76CDE725B626D94AE7EBD81136D53519C5F04597452AA601259736696
8650759F632A61E67CEF8BFA54E66B279E256BB485D5545550766CA4556A8DB4
722C5E156015743662CD6392724C5F986E436D3E65006F5876D878D076FC7554
522453DB4E535E9E65C1802A80D6629B5486522870AE888D8DD16CE1547880DA
57F988F48D54966A914D4F696C9B55B776C6783062A870F96F8E5F6D84EC68DA
787C7BF781A8670B9E4F636778B0576F78129739627962AB528874356BD70000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
46
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005564813E75B276AE533975DE50FB5C418B6C7BC7504F72479A9798D86F02
74E27968648777A562FC98918D2B54C180584E52576A82F9840D5E7351ED74F6
8BC45C4F57616CFC98875A4678349B448FEB7C955256625194FA4EC683868461
83E984B257D467345703666E6D668C3166DD7011671F6B3A6816621A59BB4E03
51C46F0667D26C8F517668CB59476B6775665D0E81109F5065D7794879419A91
8D775C824E5E4F01542F5951780C56686C148FC45F036C7D6CE38BAB63900000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
47
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000060706D3D72756266948E94C553438FC17B7E4EDF8C264E7E9ED494B194B3
524D6F5C90636D458C3458115D4C6B206B4967AA545B81547F8C589985375F3A
62A26A47953965726084686577A74E544FA85DE7979864AC7FD85CED4FCF7A8D
520783044E14602F7A8394A64FB54EB279E6743452E482B964D279BD5BDD6C81
97528F7B6C22503E537F6E0564CE66746C3060C598778BF75E86743C7A7779CB
4E1890B174036C4256DA914B6CC58D8B533A86C666F28EAF5C489A716E200000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
48
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000053D65A369F8B8DA353BB570898A76743919B6CC9516875CA62F372AC5238
529D7F3A7094763853749E4A69B7786E96C088D97FA4713671C3518967D374E4
58E4651856B78BA9997662707ED560F970ED58EC4EC14EBA5FCD97E74EFB8BA4
5203598A7EAB62544ECD65E5620E833884C98363878D71946EB65BB97ED25197
63C967D480898339881551125B7A59828FB14E736C5D516589258F6F962E854A
745E951095F06DA682E55F3164926D128428816E9CC3585E8D5B4E0953C10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
49
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F1E6563685155D34E2764149A9A626B5AC2745F82726DA968EE50E7838E
7802674052396C997EB150BB5565715E7B5B665273CA82EB67495C715220717D
886B95EA965564C58D6181B355846C5562477F2E58924F2455468D4F664C4E0A
5C1A88F368A2634E7A0D70E7828D52FA97F65C1154E890B57ECD59628D4A86C7
820C820D8D6664445C0461516D89793E8BBE78377533547B4F388EAB6DF15A20
7EC5795E6C885BA15A76751A80BE614E6E1758F0751F7525727253477EF30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000770176DB526980DC57235E08593172EE65BD6E7F8BD75C388671534177F3
62FE65F64EC098DF86805B9E8BC653F277E24F7F5C4E9A7659CB5F0F793A58EB
4E1667FF4E8B62ED8A93901D52BF662F55DC566C90024ED54F8D91CA99706C0F
5E0260435BA489C68BD56536624B99965B885BFF6388552E53D77626517D852C
67A268B36B8A62928F9353D482126DD1758F4E668D4E5B70719F85AF669166D9
7F7287009ECD9F205C5E672F8FF06811675F620D7AD658855EB665706F310000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000060555237800D6454887075295E05681362F4971C53CC723D8C016C347761
7A0E542E77AC987A821C8BF47855671470C165AF64955636601D79C153F84E1D
6B7B80865BFA55E356DB4F3A4F3C99725DF3677E80386002988290015B8B8BBC
8BF5641C825864DE55FD82CF91654FD77D20901F7C9F50F358516EAF5BBF8BC9
80839178849C7B97867D968B968F7EE59AD3788E5C817A57904296A7795F5B59
635F7B0B84D168AD55067F2974107D2295016240584C4ED65B83597958540000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000736D631E8E4B8E0F80CE82D462AC53F06CF0915E592A60016C70574D644A
8D2A762B6EE9575B6A8075F06F6D8C2D8C0857666BEF889278B363A253F970AD
6C645858642A580268E0819B55107CD650188EBA6DCC8D9F70EB638F6D9B6ED4
7EE68404684390036DD896768BA85957727985E4817E75BC8A8A68AF52548E22
951163D098988E44557C4F5366FF568F60D56D9552435C4959296DFB586B7530
751C606C82148146631167618FE2773A8DF38D3494C15E165385542C70C30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006C405EF7505C4EAD5EAD633A8247901A6850916E77B3540C94DC5F647AE5
687663457B527EDF75DB507762955934900F51F879C37A8156FE5F9290146D82
5C60571F541051546E4D56E263A89893817F8715892A9000541E5C6F81C062D6
625881319E3596409A6E9A7C692D59A562D3553E631654C786D96D3C5A0374E6
889C6B6A59168C4C5F2F6E7E73A9987D4E3870F75B8C7897633D665A769660CB
5B9B5A494E0781556C6A738B4EA167897F515F8065FA671B5FD859845A010000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005DCD5FAE537197E68FDD684556F4552F60DF4E3A6F4D7EF482C7840E59D4
4F1F4F2A5C3E7EAC672A851A5473754F80C355829B4F4F4D6E2D8C135C096170
536B761F6E29868A658795FB7EB9543B7A337D0A95EE55E17FC174EE631D8717
6DA17A9D621165A1536763E16C835DEB545C94A84E4C6C618BEC5C4B65E0829C
68A7543E54346BCB6B664E9463425348821E4F0D4FAE575E620A96FE66647269
52FF52A1609F8BEF661471996790897F785277FD6670563B54389521727A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A00606F5E0C6089819D591560DC718470EF6EAA6C5072806A8488AD5E2D
4E605AB3559C94E36D177CFB9699620F7EC6778E867E5323971E8F9666875CE1
4FA072ED4E0B53A6590F54136380952851484ED99C9C7EA454B88D2488548237
95F26D8E5F265ACC663E966973B0732E53BF817A99857FA15BAA967796507EBF
76F853A2957699997BB189446E584E617FD479658BE660F354CD4EAB98795DF7
6A6150CF54118C618427785D9704524A54EE56A395006D885BB56DC666530000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
50
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005C0F5B5D6821809655787B11654869544E9B6B47874E978B534F631F643A
90AA659C80C18C10519968B0537887F961C86CC46CFB8C225C5185AA82AF950C
6B238F9B65B05FFB5FC34FE18845661F8165732960FA51745211578B5F6290A2
884C91925E78674F602759D3514451F680F853086C7996C4718A4F114FEE7F9E
673D55C5950879C088967EE3589F620C9700865A5618987B5F908BB884C49157
53D965ED5E8F755C60647D6E5A7F7EEA7EED8F6955A75BA360AC65CB73840000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
51
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009009766377297EDA9774859B5B667A7496EA884052CB718F5FAA65EC8BE2
5BFB9A6F5DE16B896C5B8BAD8BAF900A8FC5538B62BC9E269E2D54404E2B82BD
7259869C5D1688596DAF96C554D14E9A8BB6710954BD960970DF6DF976D04E25
781487125CA95EF68A00989C960E708E6CBF594463A9773C884D6F1482735830
71D5538C781A96C155015F6671305BB48C1A9A8C6B83592E9E2F79E76768626C
4F6F75A17F8A6D0B96336C274EF075D2517B68376F3E90808170599674760000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
52
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000064475C2790657A918C2359DA54AC8200836F898180006930564E80367237
91CE51B64E5F987563964E1A53F666F3814B591C6DB24E0058F9533B63D694F1
4F9D4F0A886398905937905779FB4EEA80F075916C825B9C59E85F5D69058681
501A5DF24E5977E34EE5827A6291661390915C794EBF5F7981C69038808475AB
4EA688D4610F6BC55FC64E4976CA6EA28BE38BAE8C0A8BD15F027FFC7FCC7ECE
8335836B56E06BB797F3963459FB541F94F66DEB5BC5996E5C395F1596900000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
53
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000537082F16A315A749E705E947F2883B984248425836787478FCE8D6276C8
5F719896786C662054DF62E54F6381C375C85EB896CD8E0A86F9548F6CF36D8C
6C38607F52C775285E7D4F1860A05FE75C24753190AE94C072B96CB96E389149
670953CB53F34F5191C98BF153C85E7C8FC26DE44E8E76C26986865E611A8206
4F594FDE903E9C7C61096E1D6E1496854E885A3196E84E0E5C7F79B95B878BED
7FBD738957DF828B90C15401904755BB5CEA5FA161086B3272F180B28A890000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D745BD388D598848C6B9A6D9E336E0A51A4514357A38881539F63F48F95
56ED54585706733F6E907F188FDC82D1613F6028966266F07EA68D8A8DC394A5
5CB37CA4670860A6960580184E9190E75300966851418FD08574915D665597F5
5B55531D78386742683D54C9707E5BB08F7D518D572854B1651266828D5E8D43
810F846C906D7CDF51FF85FB67A365E96FA186A48E81566A90207682707671E5
8D2362E952196CFD8D3C600E589E618E66FE8D60624E55B36E23672D8F670000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
55
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000094E195F87728680569A8548B4E4D70B88BC86458658B5B857A84503A5BE8
77BB6BE18A797C986CBE76CF65A98F975D2D5C5586386808536062187AD96E5B
7EFD6A1F7AE05F706F335F20638C6DA867564E085E108D264ED780C07634969C
62DB662D627E6CBC8D7571677F695146808753EC906E629854F286F08F998005
951785178FD96D5973CD659F771F7504782781FB8D1E94884FA6679575B98BCA
9707632F9547963584B8632377415F8172F04E896014657462EF6B63653F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
56
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005E2775C790D18BC1829D679D652F5431871877E580A281026C414E4B7EC7
804C76F4690D6B966267503C4F84574063076B628DBE53EA65E87EB85FD7631A
63B781F381F47F6E5E1C5CD95236667A79E97A1A8D28709975D46EDE6CBB7A92
4E2D76C55FE0949F88777EC879CD80BF91CD4EF24F17821F54685DDE6D328BCC
7CA58F7480985E1A549276B15B99663C9AA473E0682A86DB6731732A8BF88BDB
90107AF970DB716E62C477A956314E3B845767F152A986C08D2E94F87B510000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
57
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F4F6CE8795D9A7B6293722A62FD4E1378168F6C64B08D5A7BC668695E84
88C55986649E58EE72B6690E95258FFD8D5857607F008C0651C6634962D95353
684C74228301914C55447740707C6D4A517954A88D4459FF6ECB6DC45B5C7D2B
4ED47C7D6ED35B5081EA6E0D5B579B0368D58E2A5B977EFC603B7EB590B98D70
594F63CD79DF8DB3535265CF79568BC5963B7EC494BB7E825634918967007F6A
5C0A907566285DE64F5067DE505A4F5C57505EA7000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
58
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E8D4E0C51404E105EFF53454E154E984E1E9B325B6C56694E2879BA4E3F
53154E47592D723B536E6C1056DF80E499976BD3777E9F174E364E9F9F104E5C
4E694E9382885B5B556C560F4EC4538D539D53A353A553AE97658D5D531A53F5
5326532E533E8D5C5366536352025208520E522D5233523F5240524C525E5261
525C84AF527D528252815290529351827F544EBB4EC34EC94EC24EE84EE14EEB
4EDE4F1B4EF34F224F644EF54F254F274F094F2B4F5E4F6765384F5A4F5D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F5F4F574F324F3D4F764F744F914F894F834F8F4F7E4F7B4FAA4F7C4FAC
4F944FE64FE84FEA4FC54FDA4FE34FDC4FD14FDF4FF85029504C4FF3502C500F
502E502D4FFE501C500C50255028507E504350555048504E506C507B50A550A7
50A950BA50D6510650ED50EC50E650EE5107510B4EDD6C3D4F584F654FCE9FA0
6C467C74516E5DFD9EC999985181591452F9530D8A07531051EB591951554EA0
51564EB3886E88A44EB5811488D279805B3488037FB851AB51B151BD51BC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000051C7519651A251A58BA08BA68BA78BAA8BB48BB58BB78BC28BC38BCB8BCF
8BCE8BD28BD38BD48BD68BD88BD98BDC8BDF8BE08BE48BE88BE98BEE8BF08BF3
8BF68BF98BFC8BFF8C008C028C048C078C0C8C0F8C118C128C148C158C168C19
8C1B8C188C1D8C1F8C208C218C258C278C2A8C2B8C2E8C2F8C328C338C358C36
5369537A961D962296219631962A963D963C964296499654965F9667966C9672
96749688968D969796B09097909B909D909990AC90A190B490B390B690BA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000090B890B090CF90C590BE90D090C490C790D390E690E290DC90D790DB90EB
90EF90FE91049122911E91239131912F913991439146520D594252A252AC52AD
52BE54FF52D052D652F053DF71EE77CD5EF451F551FC9B2F53B65F01755A5DEF
574C57A957A1587E58BC58C558D15729572C572A57335739572E572F575C573B
574257695785576B5786577C577B5768576D5776577357AD57A4578C57B257CF
57A757B4579357A057D557D857DA57D957D257B857F457EF57F857E457DD0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000580B580D57FD57ED5800581E5819584458205865586C58815889589A5880
99A89F1961FF8279827D827F828F828A82A88284828E82918297829982AB82B8
82BE82B082C882CA82E3829882B782AE82CB82CC82C182A982B482A182AA829F
82C482CE82A482E1830982F782E4830F830782DC82F482D282D8830C82FB82D3
8311831A83068314831582E082D5831C8351835B835C83088392833C83348331
839B835E832F834F83478343835F834083178360832D833A8333836683650000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008368831B8369836C836A836D836E83B0837883B383B483A083AA8393839C
8385837C83B683A9837D83B8837B8398839E83A883BA83BC83C1840183E583D8
58078418840B83DD83FD83D6841C84388411840683D483DF840F840383F883F9
83EA83C583C0842683F083E1845C8451845A8459847384878488847A84898478
843C844684698476848C848E8431846D84C184CD84D084E684BD84D384CA84BF
84BA84E084A184B984B4849784E584E3850C750D853884F08539851F853A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008556853B84FF84FC8559854885688564855E857A77A285438572857B85A4
85A88587858F857985AE859C858585B985B785B085D385C185DC85FF86278605
86298616863C5EFE5F08593C594180375955595A5958530F5C225C255C2C5C34
624C626A629F62BB62CA62DA62D762EE632262F66339634B634363AD63F66371
637A638E63B4636D63AC638A636963AE63BC63F263F863E063FF63C463DE63CE
645263C663BE64456441640B641B6420640C64266421645E6484646D64960000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000647A64B764B8649964BA64C064D064D764E464E265096525652E5F0B5FD2
75195F11535F53F153FD53E953E853FB541254165406544B5452545354545456
54435421545754595423543254825494547754715464549A549B548454765466
549D54D054AD54C254B454D254A754A654D354D4547254A354D554BB54BF54CC
54D954DA54DC54A954AA54A454DD54CF54DE551B54E7552054FD551454F35522
5523550F55115527552A5567558F55B55549556D55415555553F5550553C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
60
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005537555655755576557755335530555C558B55D2558355B155B955885581
559F557E55D65591557B55DF55BD55BE5594559955EA55F755C9561F55D155EB
55EC55D455E655DD55C455EF55E555F255F355CC55CD55E855F555E48F94561E
5608560C56015624562355FE56005627562D565856395657562C564D56625659
565C564C5654568656645671566B567B567C5685569356AF56D456D756DD56E1
56F556EB56F956FF5704570A5709571C5E0F5E195E145E115E315E3B5E3C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
61
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005E375E445E545E5B5E5E5E615C8C5C7A5C8D5C905C965C885C985C995C91
5C9A5C9C5CB55CA25CBD5CAC5CAB5CB15CA35CC15CB75CC45CD25CE45CCB5CE5
5D025D035D275D265D2E5D245D1E5D065D1B5D585D3E5D345D3D5D6C5D5B5D6F
5D5D5D6B5D4B5D4A5D695D745D825D995D9D8C735DB75DC55F735F775F825F87
5F895F8C5F955F995F9C5FA85FAD5FB55FBC88625F6172AD72B072B472B772B8
72C372C172CE72CD72D272E872EF72E972F272F472F7730172F3730372FA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
62
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000072FB731773137321730A731E731D7315732273397325732C733873317350
734D73577360736C736F737E821B592598E7592459029963996799689969996A
996B996C99749977997D998099849987998A998D999099919993999499955E80
5E915E8B5E965EA55EA05EB95EB55EBE5EB38D535ED25ED15EDB5EE85EEA81BA
5FC45FC95FD65FCF60035FEE60045FE15FE45FFE600560065FEA5FED5FF86019
60356026601B600F600D6029602B600A603F602160786079607B607A60420000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
63
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000606A607D6096609A60AD609D60836092608C609B60EC60BB60B160DD60D8
60C660DA60B4612061266115612360F46100610E612B614A617561AC619461A7
61B761D461F55FDD96B395E995EB95F195F395F595F695FC95FE960396049606
9608960A960B960C960D960F96129615961696179619961A4E2C723F62156C35
6C546C5C6C4A6CA36C856C906C946C8C6C686C696C746C766C866CA96CD06CD4
6CAD6CF76CF86CF16CD76CB26CE06CD66CFA6CEB6CEE6CB16CD36CEF6CFE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
64
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006D396D276D0C6D436D486D076D046D196D0E6D2B6D4D6D2E6D356D1A6D4F
6D526D546D336D916D6F6D9E6DA06D5E6D936D946D5C6D606D7C6D636E1A6DC7
6DC56DDE6E0E6DBF6DE06E116DE66DDD6DD96E166DAB6E0C6DAE6E2B6E6E6E4E
6E6B6EB26E5F6E866E536E546E326E256E446EDF6EB16E986EE06F2D6EE26EA5
6EA76EBD6EBB6EB76ED76EB46ECF6E8F6EC26E9F6F626F466F476F246F156EF9
6F2F6F366F4B6F746F2A6F096F296F896F8D6F8C6F786F726F7C6F7A6FD10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
65
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006FC96FA76FB96FB66FC26FE16FEE6FDE6FE06FEF701A7023701B70397035
704F705E5B805B845B955B935BA55BB8752F9A9E64345BE45BEE89305BF08E47
8B078FB68FD38FD58FE58FEE8FE48FE98FE68FF38FE890059004900B90269011
900D9016902190359036902D902F9044905190529050906890589062905B66B9
9074907D908290889083908B5F505F575F565F585C3B54AB5C505C595B715C63
5C667FBC5F2A5F295F2D82745F3C9B3B5C6E59815983598D59A959AA59A30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
66
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000599759CA59AB599E59A459D259B259AF59D759BE5A055A0659DD5A0859E3
59D859F95A0C5A095A325A345A115A235A135A405A675A4A5A555A3C5A625A75
80EC5AAA5A9B5A775A7A5ABE5AEB5AB25AD25AD45AB85AE05AE35AF15AD65AE6
5AD85ADC5B095B175B165B325B375B405C155C1C5B5A5B655B735B515B535B62
9A759A779A789A7A9A7F9A7D9A809A819A859A889A8A9A909A929A939A969A98
9A9B9A9C9A9D9A9F9AA09AA29AA39AA59AA77E9F7EA17EA37EA57EA87EA90000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
67
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007EAD7EB07EBE7EC07EC17EC27EC97ECB7ECC7ED07ED47ED77EDB7EE07EE1
7EE87EEB7EEE7EEF7EF17EF27F0D7EF67EFA7EFB7EFE7F017F027F037F077F08
7F0B7F0C7F0F7F117F127F177F197F1C7F1B7F1F7F217F227F237F247F257F26
7F277F2A7F2B7F2C7F2D7F2F7F307F317F327F337F355E7A757F5DDB753E9095
738E739173AE73A2739F73CF73C273D173B773B373C073C973C873E573D9987C
740A73E973E773DE73BA73F2740F742A745B7426742574287430742E742C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
68
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000741B741A7441745C7457745574597477746D747E749C748E748074817487
748B749E74A874A9749074A774D274BA97EA97EB97EC674C6753675E67486769
67A56787676A6773679867A7677567A8679E67AD678B6777677C67F0680967D8
680A67E967B0680C67D967B567DA67B367DD680067C367B867E2680E67C167FD
6832683368606861684E6862684468646883681D68556866684168676840683E
684A6849682968B5688F687468776893686B68C2696E68FC691F692068F90000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
69
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000692468F0690B6901695768E369106971693969606942695D6984696B6980
69986978693469CC6987698869CE6989696669636979699B69A769BB69AB69AD
69D469B169C169CA69DF699569E0698D69FF6A2F69ED6A176A186A6569F26A44
6A3E6AA06A506A5B6A356A8E6A796A3D6A286A586A7C6A916A906AA96A976AAB
733773526B816B826B876B846B926B936B8D6B9A6B9B6BA16BAA8F6B8F6D8F71
8F728F738F758F768F788F778F798F7A8F7C8F7E8F818F828F848F878F8B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008F8D8F8E8F8F8F988F9A8ECE620B6217621B621F6222622162256224622C
81E774EF74F474FF750F75117513653465EE65EF65F0660A6619677266036615
6600708566F7661D66346631663666358006665F66546641664F665666616657
66776684668C66A7669D66BE66DB66DC66E666E98D328D338D368D3B8D3D8D40
8D458D468D488D498D478D4D8D558D5989C789CA89CB89CC89CE89CF89D089D1
726E729F725D7266726F727E727F7284728B728D728F72926308633263B00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000643F64D880046BEA6BF36BFD6BF56BF96C056C076C066C0D6C156C186C19
6C1A6C216C296C246C2A6C3265356555656B724D72527256723086625216809F
809C809380BC670A80BD80B180AB80AD80B480B780E780E880E980EA80DB80C2
80C480D980CD80D7671080DD80EB80F180F480ED810D810E80F280FC67158112
8C5A8136811E812C811881328148814C815381748159815A817181608169817C
817D816D8167584D5AB58188818281916ED581A381AA81CC672681CA81BB0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000081C181A66B246B376B396B436B466B5998D198D298D398D598D998DA6BB3
5F406BC289F365909F51659365BC65C665C465C365CC65CE65D265D67080709C
7096709D70BB70C070B770AB70B170E870CA711071137116712F71317173715C
716871457172714A7178717A719871B371B571A871A071E071D471E771F9721D
7228706C7118716671B9623E623D624362486249793B794079467949795B795C
7953795A796279577960796F7967797A7985798A799A79A779B35FD15FD00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000603C605D605A606760416059606360AB6106610D615D61A9619D61CB61D1
62068080807F6C936CF66DFC77F677F87800780978177818781165AB782D781C
781D7839783A783B781F783C7825782C78237829784E786D7856785778267850
7847784C786A789B7893789A7887789C78A178A378B278B978A578D478D978C9
78EC78F2790578F479137924791E79349F9B9EF99EFB9EFC76F17704770D76F9
77077708771A77227719772D7726773577387750775177477743775A77680000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077627765777F778D777D7780778C7791779F77A077B077B577BD753A7540
754E754B7548755B7572757975837F587F617F5F8A487F687F747F717F797F81
7F7E76CD76E58832948594869487948B948A948C948D948F9490949494979495
949A949B949C94A394A494AB94AA94AD94AC94AF94B094B294B494B694B794B8
94B994BA94BC94BD94BF94C494C894C994CA94CB94CC94CD94CE94D094D194D2
94D594D694D794D994D894DB94DE94DF94E094E294E494E594E794E894EA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000094E994EB94EE94EF94F394F494F594F794F994FC94FD94FF950395029506
95079509950A950D950E950F951295139514951595169518951B951D951E951F
9522952A952B9529952C953195329534953695379538953C953E953F95429535
9544954595469549954C954E954F9552955395549556955795589559955B955E
955F955D95619562956495659566956795689569956A956B956C956F95719572
9573953A77E777EC96C979D579ED79E379EB7A065D477A037A027A1E7A140000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
70
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A397A377A519ECF99A57A707688768E7693769976A474DE74E0752C9E20
9E229E289E299E2A9E2B9E2C9E329E319E369E389E379E399E3A9E3E9E419E42
9E449E469E479E489E499E4B9E4C9E4E9E519E559E579E5A9E5B9E5C9E5E9E63
9E669E679E689E699E6A9E6B9E6C9E719E6D9E7375927594759675A0759D75AC
75A375B375B475B875C475B175B075C375C275D675CD75E375E875E675E475EB
75E7760375F175FC75FF761076007605760C7617760A76257618761576190000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
71
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000761B763C762276207640762D7630763F76357643763E7633764D765E7654
765C7656766B766F7FCA7AE67A787A797A807A867A887A957AA67AA07AAC7AA8
7AAD7AB3886488698872887D887F888288A288C688B788BC88C988E288CE88E3
88E588F1891A88FC88E888FE88F0892189198913891B890A8934892B89368941
8966897B758B80E576B276B477DC801280148016801C80208022802580268027
802980288031800B803580438046804D80528069807189839878988098830000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
72
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009889988C988D988F9894989A989B989E989F98A198A298A598A6864D8654
866C866E867F867A867C867B86A8868D868B86AC869D86A786A386AA869386A9
86B686C486B586CE86B086BA86B186AF86C986CF86B486E986F186F286ED86F3
86D0871386DE86F486DF86D886D18703870786F88708870A870D87098723873B
871E8725872E871A873E87488734873187298737873F87828722877D877E877B
87608770874C876E878B87538763877C876487598765879387AF87A887D20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
73
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000087C68788878587AD8797878387AB87E587AC87B587B387CB87D387BD87D1
87C087CA87DB87EA87E087EE8816881387FE880A881B88218839883C7F367F42
7F447F4582107AFA7AFD7B087B037B047B157B0A7B2B7B0F7B477B387B2A7B19
7B2E7B317B207B257B247B337B3E7B1E7B587B5A7B457B757B4C7B5D7B607B6E
7B7B7B627B727B717B907BA67BA77BB87BAC7B9D7BA87B857BAA7B9C7BA27BAB
7BB47BD17BC17BCC7BDD7BDA7BE57BE67BEA7C0C7BFE7BFC7C0F7C167C0B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
74
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007C1F7C2A7C267C387C417C4081FE82018202820481EC8844822182228223
822D822F8228822B8238823B82338234823E82448249824B824F825A825F8268
887E8885888888D888DF895E7F9D7F9F7FA77FAF7FB07FB27C7C65497C917C9D
7C9C7C9E7CA27CB27CBC7CBD7CC17CC77CCC7CCD7CC87CC57CD77CE8826E66A8
7FBF7FCE7FD57FE57FE17FE67FE97FEE7FF37CF87D777DA67DAE7E477E9B9EB8
9EB48D738D848D948D918DB18D678D6D8C478C49914A9150914E914F91640000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
75
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009162916191709169916F917D917E917291749179918C91859190918D9191
91A291A391AA91AD91AE91AF91B591B491BA8C559E7E8DB88DEB8E058E598E69
8DB58DBF8DBC8DBA8DC48DD68DD78DDA8DDE8DCE8DCF8DDB8DC68DEC8DF78DF8
8DE38DF98DFB8DE48E098DFD8E148E1D8E1F8E2C8E2E8E238E2F8E3A8E408E39
8E358E3D8E318E498E418E428E518E528E4A8E708E768E7C8E6F8E748E858E8F
8E948E908E9C8E9E8C788C828C8A8C858C988C94659B89D689DE89DA89DC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
76
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000089E589EB89EF8A3E8B26975396E996F396EF970697019708970F970E972A
972D9730973E9F809F839F859F869F879F889F899F8A9F8C9EFE9F0B9F0D96B9
96BC96BD96CE96D277BF96E0928E92AE92C8933E936A93CA938F943E946B9C7F
9C829C859C869C879C887A239C8B9C8E9C909C919C929C949C959C9A9C9B9C9E
9C9F9CA09CA19CA29CA39CA59CA69CA79CA89CA99CAB9CAD9CAE9CB09CB19CB2
9CB39CB49CB59CB69CB79CBA9CBB9CBC9CBD9CC49CC59CC69CC79CCA9CCB0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
77
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009CCC9CCD9CCE9CCF9CD09CD39CD49CD59CD79CD89CD99CDC9CDD9CDF9CE2
977C978597919792979497AF97AB97A397B297B49AB19AB09AB79E589AB69ABA
9ABC9AC19AC09AC59AC29ACB9ACC9AD19B459B439B479B499B489B4D9B5198E8
990D992E995599549ADF9AE19AE69AEF9AEB9AFB9AED9AF99B089B0F9B139B1F
9B239EBD9EBE7E3B9E829E879E889E8B9E9293D69E9D9E9F9EDB9EDC9EDD9EE0
9EDF9EE29EE99EE79EE59EEA9EEF9F229F2C9F2F9F399F379F3D9F3E9F440000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/iso2022-jp.enc.

























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
# Encoding file: iso2022-jp, escape-driven
E
name		iso2022-jp
init		{}
final		{}
iso8859-1	\x1b(B
jis0201		\x1b(J
jis0208		\x1b$@
jis0208		\x1b$B
jis0212		\x1b$(D
gb2312		\x1b$A
ksc5601		\x1b$(C

Added library/encoding/iso2022-kr.enc.















>
>
>
>
>
>
>
1
2
3
4
5
6
7
# Encoding file: iso2022-kr, escape-driven
E
name		iso2022-kr
init		\x1b$)C
final		{}
iso8859-1	\x0f
ksc5601		\x0e

Added library/encoding/iso2022.enc.

































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Encoding file: iso2022, escape-driven
E
name		iso2022
init		{}
final		{}
iso8859-1	\x1b(B
jis0201		\x1b(J
gb1988		\x1b(T
jis0208		\x1b$@
jis0208		\x1b$B
jis0212		\x1b$(D
gb2312		\x1b$A
ksc5601		\x1b$(C
jis0208		\x1b&@\x1b$B


Added library/encoding/iso8859-1.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-1, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
00D000D100D200D300D400D500D600D700D800D900DA00DB00DC00DD00DE00DF
00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
00F000F100F200F300F400F500F600F700F800F900FA00FB00FC00FD00FE00FF

Added library/encoding/iso8859-2.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-2, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A0010402D8014100A4013D015A00A700A80160015E0164017900AD017D017B
00B0010502DB014200B4013E015B02C700B80161015F0165017A02DD017E017C
015400C100C2010200C40139010600C7010C00C9011800CB011A00CD00CE010E
01100143014700D300D4015000D600D70158016E00DA017000DC00DD016200DF
015500E100E2010300E4013A010700E7010D00E9011900EB011B00ED00EE010F
01110144014800F300F4015100F600F70159016F00FA017100FC00FD016302D9

Added library/encoding/iso8859-3.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-3, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A0012602D800A300A40000012400A700A80130015E011E013400AD0000017B
00B0012700B200B300B400B5012500B700B80131015F011F013500BD0000017C
00C000C100C2000000C4010A010800C700C800C900CA00CB00CC00CD00CE00CF
000000D100D200D300D4012000D600D7011C00D900DA00DB00DC016C015C00DF
00E000E100E2000000E4010B010900E700E800E900EA00EB00EC00ED00EE00EF
000000F100F200F300F4012100F600F7011D00F900FA00FB00FC016D015D02D9

Added library/encoding/iso8859-4.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-4, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A001040138015600A40128013B00A700A8016001120122016600AD017D00AF
00B0010502DB015700B40129013C02C700B80161011301230167014A017E014B
010000C100C200C300C400C500C6012E010C00C9011800CB011600CD00CE012A
01100145014C013600D400D500D600D700D8017200DA00DB00DC0168016A00DF
010100E100E200E300E400E500E6012F010D00E9011900EB011700ED00EE012B
01110146014D013700F400F500F600F700F8017300FA00FB00FC0169016B02D9

Added library/encoding/iso8859-5.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-5, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A0040104020403040404050406040704080409040A040B040C00AD040E040F
0410041104120413041404150416041704180419041A041B041C041D041E041F
0420042104220423042404250426042704280429042A042B042C042D042E042F
0430043104320433043404350436043704380439043A043B043C043D043E043F
0440044104420443044404450446044704480449044A044B044C044D044E044F
2116045104520453045404550456045704580459045A045B045C00A7045E045F

Added library/encoding/iso8859-6.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-6, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0660066106620663066406650666066706680669003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A000000000000000A40000000000000000000000000000060C00AD00000000
00000000000000000000000000000000000000000000061B000000000000061F
0000062106220623062406250626062706280629062A062B062C062D062E062F
0630063106320633063406350636063706380639063A00000000000000000000
0640064106420643064406450646064706480649064A064B064C064D064E064F
0650065106520000000000000000000000000000000000000000000000000000

Added library/encoding/iso8859-7.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-7, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A002BD02BC00A30000000000A600A700A800A9000000AB00AC00AD00002015
00B000B100B200B303840385038600B703880389038A00BB038C00BD038E038F
0390039103920393039403950396039703980399039A039B039C039D039E039F
03A003A1000003A303A403A503A603A703A803A903AA03AB03AC03AD03AE03AF
03B003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C203C303C403C503C603C703C803C903CA03CB03CC03CD03CE0000

Added library/encoding/iso8859-8.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-8, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A0000000A200A300A400A500A600A700A800A900D700AB00AC00AD00AE203E
00B000B100B200B300B400B500B600B700B800B900F700BB00BC00BD00BE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000002017
05D005D105D205D305D405D505D605D705D805D905DA05DB05DC05DD05DE05DF
05E005E105E205E305E405E505E605E705E805E905EA00000000000000000000

Added library/encoding/iso8859-9.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-9, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
011E00D100D200D300D400D500D600D700D800D900DA00DB00DC0130015E00DF
00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
011F00F100F200F300F400F500F600F700F800F900FA00FB00FC0131015F00FF

Added library/encoding/jis0201.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: jis0201, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D203E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/jis0208.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
# Encoding file: jis0208, double-byte
D
2129 0 77
21
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8
FF3EFFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0F
FF3C301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3D
FF5BFF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D7
00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C70000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
22
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000025C625A125A025B325B225BD25BC203B3012219221902191219330130000
00000000000000000000000000000000000000002208220B2286228722822283
222A2229000000000000000000000000000000002227222800AC21D221D42200
220300000000000000000000000000000000000000000000222022A523122202
220722612252226A226B221A223D221D2235222B222C00000000000000000000
00000000212B2030266F266D266A2020202100B6000000000000000025EF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
23
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19000000000000000000000000
0000FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3A00000000000000000000
0000FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5A00000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
24
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000304130423043304430453046304730483049304A304B304C304D304E304F
3050305130523053305430553056305730583059305A305B305C305D305E305F
3060306130623063306430653066306730683069306A306B306C306D306E306F
3070307130723073307430753076307730783079307A307B307C307D307E307F
3080308130823083308430853086308730883089308A308B308C308D308E308F
3090309130923093000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
25
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
26
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000039103920393039403950396039703980399039A039B039C039D039E039F
03A003A103A303A403A503A603A703A803A90000000000000000000000000000
000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C303C403C503C603C703C803C90000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
27
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000004100411041204130414041504010416041704180419041A041B041C041D
041E041F0420042104220423042404250426042704280429042A042B042C042D
042E042F00000000000000000000000000000000000000000000000000000000
000004300431043204330434043504510436043704380439043A043B043C043D
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
28
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000025002502250C251025182514251C252C25242534253C25012503250F2513
251B251725232533252B253B254B2520252F25282537253F251D253025252538
2542000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
30
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E9C55165A03963F54C0611B632859F690228475831C7A5060AA63E16E25
65ED846682A69BF56893572765A162715B9B59D0867B98F47D627DBE9B8E6216
7C9F88B75B895EB563096697684895C7978D674F4EE54F0A4F4D4F9D504956F2
593759D45A015C0960DF610F61706613690570BA754F757079FB7DAD7DEF80C3
840E88638B029055907A533B4E954EA557DF80B290C178EF4E0058F16EA29038
7A328328828B9C2F5141537054BD54E156E059FB5F1598F26DEB80E4852D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
31
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009662967096A097FB540B53F35B8770CF7FBD8FC296E8536F9D5C7ABA4E11
789381FC6E26561855046B1D851A9C3B59E553A96D6674DC958F56424E91904B
96F2834F990C53E155B65B305F71662066F368046C386CF36D29745B76C87A4E
983482F1885B8A6092ED6DB275AB76CA99C560A68B018D8A95B2698E53AD5186
5712583059445BB45EF6602863A963F46CBF6F14708E7114715971D5733F7E01
827682D185979060925B9D1B586965BC6C5A752551F9592E59655F805FDC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
32
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000062BC65FA6A2A6B276BB4738B7FC189569D2C9D0E9EC45CA16C96837B5104
5C4B61B681C6687672614E594FFA537860696E297A4F97F34E0B53164EEE4F55
4F3D4FA14F7352A053EF5609590F5AC15BB65BE179D16687679C67B66B4C6CB3
706B73C2798D79BE7A3C7B8782B182DB8304837783EF83D387668AB256298CA8
8FE6904E971E868A4FC45CE862117259753B81E582BD86FE8CC096C5991399D5
4ECB4F1A89E356DE584A58CA5EFB5FEB602A6094606261D0621262D065390000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
33
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009B41666668B06D777070754C76867D7582A587F9958B968E8C9D51F152BE
591654B35BB35D16616869826DAF788D84CB88578A7293A79AB86D6C99A886D9
57A367FF86CE920E5283568754045ED362E164B9683C68386BBB737278BA7A6B
899A89D28D6B8F0390ED95A3969497695B665CB3697D984D984E639B7B206A2B
6A7F68B69C0D6F5F5272559D607062EC6D3B6E076ED1845B89108F444E149C39
53F6691B6A3A9784682A515C7AC384B291DC938C565B9D286822830584310000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
34
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007CA5520882C574E64E7E4F8351A05BD2520A52D852E75DFB559A582A59E6
5B8C5B985BDB5E725E7960A3611F616361BE63DB656267D1685368FA6B3E6B53
6C576F226F976F4574B0751876E3770B7AFF7BA17C217DE97F367FF0809D8266
839E89B38ACC8CAB908494519593959195A2966597D3992882184E38542B5CB8
5DCC73A9764C773C5CA97FEB8D0B96C19811985498584F014F0E5371559C5668
57FA59475B095BC45C905E0C5E7E5FCC63EE673A65D765E2671F68CB68C40000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
35
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006A5F5E306BC56C176C7D757F79485B637A007D005FBD898F8A188CB48D77
8ECC8F1D98E29A0E9B3C4E80507D510059935B9C622F628064EC6B3A72A07591
79477FA987FB8ABC8B7063AC83CA97A05409540355AB68546A588A7078276775
9ECD53745BA2811A865090064E184E454EC74F1153CA54385BAE5F1360256551
673D6C426C726CE3707874037A767AAE7B087D1A7CFE7D6665E7725B53BB5C45
5DE862D262E063196E20865A8A318DDD92F86F0179A69B5A4EA84EAB4EAC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
36
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F9B4FA050D151477AF6517151F653545321537F53EB55AC58835CE15F37
5F4A602F6050606D631F65596A4B6CC172C272ED77EF80F881058208854E90F7
93E197FF99579A5A4EF051DD5C2D6681696D5C4066F26975738968507C8150C5
52E457475DFE932665A46B236B3D7434798179BD7B4B7DCA82B983CC887F895F
8B398FD191D1541F92804E5D503653E5533A72D7739677E982E68EAF99C699C8
99D25177611A865E55B07A7A50765BD3904796854E326ADB91E75C515C480000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
37
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000063987A9F6C9397748F617AAA718A96887C8268177E706851936C52F2541B
85AB8A137FA48ECD90E15366888879414FC250BE521151445553572D73EA578B
59515F625F8460756176616761A963B2643A656C666F68426E1375667A3D7CFB
7D4C7D997E4B7F6B830E834A86CD8A088A638B668EFD981A9D8F82B88FCE9BE8
5287621F64836FC09699684150916B206C7A6F547A747D5088408A2367084EF6
503950265065517C5238526355A7570F58055ACC5EFA61B261F862F363720000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
38
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000691C6A29727D72AC732E7814786F7D79770C80A9898B8B198CE28ED29063
9375967A98559A139E785143539F53B35E7B5F266E1B6E90738473FE7D438237
8A008AFA96504E4E500B53E4547C56FA59D15B645DF15EAB5F276238654567AF
6E5672D07CCA88B480A180E183F0864E8A878DE8923796C798679F134E944E92
4F0D53485449543E5A2F5F8C5FA1609F68A76A8E745A78818A9E8AA48B779190
4E5E9BC94EA44F7C4FAF501950165149516C529F52B952FE539A53E354110000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
39
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000540E5589575157A2597D5B545B5D5B8F5DE55DE75DF75E785E835E9A5EB7
5F186052614C629762D863A7653B6602664366F4676D6821689769CB6C5F6D2A
6D696E2F6E9D75327687786C7A3F7CE07D057D187D5E7DB18015800380AF80B1
8154818F822A8352884C88618B1B8CA28CFC90CA91759271783F92FC95A4964D
980599999AD89D3B525B52AB53F7540858D562F76FE08C6A8F5F9EB9514B523B
544A56FD7A4091779D609ED273446F09817075115FFD60DA9AA872DB8FBC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006B6498034ECA56F0576458BE5A5A606861C7660F6606683968B16DF775D5
7D3A826E9B424E9B4F5053C955065D6F5DE65DEE67FB6C99747378028A509396
88DF57505EA7632B50B550AC518D670054C9585E59BB5BB05F69624D63A1683D
6B736E08707D91C7728078157826796D658E7D3083DC88C18F09969B52645728
67507F6A8CA151B45742962A583A698A80B454B25D0E57FC78959DFA4F5C524A
548B643E6628671467F57A847B567D22932F685C9BAD7B395319518A52370000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005BDF62F664AE64E6672D6BBA85A996D176909BD6634C93069BAB76BF6652
4E09509853C25C7160E864926563685F71E673CA75237B977E8286958B838CDB
9178991065AC66AB6B8B4ED54ED44F3A4F7F523A53F853F255E356DB58EB59CB
59C959FF5B505C4D5E025E2B5FD7601D6307652F5B5C65AF65BD65E8679D6B62
6B7B6C0F7345794979C17CF87D197D2B80A2810281F389968A5E8A698A668A8C
8AEE8CC78CDC96CC98FC6B6F4E8B4F3C4F8D51505B575BFA6148630166420000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006B216ECB6CBB723E74BD75D478C1793A800C803381EA84948F9E6C509E7F
5F0F8B589D2B7AFA8EF85B8D96EB4E0353F157F759315AC95BA460896E7F6F06
75BE8CEA5B9F85007BE0507267F4829D5C61854A7E1E820E51995C0463688D66
659C716E793E7D1780058B1D8ECA906E86C790AA501F52FA5C3A6753707C7235
914C91C8932B82E55BC25F3160F94E3B53D65B88624B67316B8A72E973E07A2E
816B8DA391529996511253D7546A5BFF63886A397DAC970056DA53CE54680000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005B975C315DDE4FEE610162FE6D3279C079CB7D427E4D7FD281ED821F8490
884689728B908E748F2F9031914B916C96C6919C4EC04F4F514553415F93620E
67D46C416E0B73637E2691CD928353D459195BBF6DD1795D7E2E7C9B587E719F
51FA88538FF04FCA5CFB662577AC7AE3821C99FF51C65FAA65EC696F6B896DF3
6E966F6476FE7D145DE190759187980651E6521D6240669166D96E1A5EB67DD2
7F7266F885AF85F78AF852A953D959735E8F5F90605592E4966450B7511F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000052DD5320534753EC54E8554655315617596859BE5A3C5BB55C065C0F5C11
5C1A5E845E8A5EE05F70627F628462DB638C63776607660C662D6676677E68A2
6A1F6A356CBC6D886E096E58713C7126716775C77701785D7901796579F07AE0
7B117CA77D39809683D6848B8549885D88F38A1F8A3C8A548A738C618CDE91A4
9266937E9418969C97984E0A4E084E1E4E575197527057CE583458CC5B225E38
60C564FE676167566D4472B675737A6384B88B7291B89320563157F498FE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000062ED690D6B9671ED7E548077827289E698DF87558FB15C3B4F384FE14FB5
55075A205BDD5BE95FC3614E632F65B0664B68EE699B6D786DF1753375B9771F
795E79E67D3381E382AF85AA89AA8A3A8EAB8F9B903291DD97074EBA4EC15203
587558EC5C0B751A5C3D814E8A0A8FC59663976D7B258ACF9808916256F353A8
9017543957825E2563A86C34708A77617C8B7FE088709042915493109318968F
745E9AC45D075D69657067A28DA896DB636E6749691983C5981796C088FE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
40
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006F84647A5BF84E16702C755D662F51C4523652E259D35F8160276210653F
6574661F667468F268166B636E057272751F76DB7CBE805658F088FD897F8AA0
8A938ACB901D91929752975965897A0E810696BB5E2D60DC621A65A566146790
77F37A4D7C4D7E3E810A8CAC8D648DE18E5F78A9520762D963A5644262988A2D
7A837BC08AAC96EA7D76820C87494ED95148534353605BA35C025C165DDD6226
624764B0681368346CC96D456D1767D36F5C714E717D65CB7A7F7BAD7DDA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
41
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007E4A7FA8817A821B823985A68A6E8CCE8DF59078907792AD929195839BAE
524D55846F387136516879857E5581B37CCE564C58515CA863AA66FE66FD695A
72D9758F758E790E795679DF7C977D207D4486078A34963B90619F2050E75275
53CC53E2500955AA58EE594F723D5B8B5C64531D60E360F3635C6383633F63BB
64CD65E966F95DE369CD69FD6F1571E54E8975E976F87A937CDF7DCF7D9C8061
83498358846C84BC85FB88C58D709001906D9397971C9A1250CF5897618E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
42
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000081D385358D0890204FC3507452475373606F6349675F6E2C8DB3901F4FD7
5C5E8CCA65CF7D9A53528896517663C35B585B6B5C0A640D6751905C4ED6591A
592A6C708A51553E581559A560F0625367C182356955964099C49A284F535806
5BFE80105CB15E2F5F856020614B623466FF6CF06EDE80CE817F82D4888B8CB8
9000902E968A9EDB9BDB4EE353F059277B2C918D984C9DF96EDD702753535544
5B856258629E62D36CA26FEF74228A1794386FC18AFE833851E786F853EA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
43
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000053E94F4690548FB0596A81315DFD7AEA8FBF68DA8C3772F89C486A3D8AB0
4E3953585606576662C563A265E66B4E6DE16E5B70AD77ED7AEF7BAA7DBB803D
80C686CB8A95935B56E358C75F3E65AD66966A806BB575378AC7502477E55730
5F1B6065667A6C6075F47A1A7F6E81F48718904599B37BC9755C7AF97B5184C4
901079E97A9283365AE177404E2D4EF25B995FE062BD663C67F16CE8866B8877
8A3B914E92F399D06A177026732A82E784578CAF4E01514651CB558B5BF50000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
44
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005E165E335E815F145F355F6B5FB461F2631166A2671D6F6E7252753A773A
80748139817887768ABF8ADC8D858DF3929A957798029CE552C5635776F46715
6C8873CD8CC393AE96736D25589C690E69CC8FFD939A75DB901A585A680263B4
69FB4F436F2C67D88FBB85267DB49354693F6F70576A58F75B2C7D2C722A540A
91E39DB44EAD4F4E505C507552438C9E544858245B9A5E1D5E955EAD5EF75F1F
608C62B5633A63D068AF6C407887798E7A0B7DE082478A028AE68E4490130000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
45
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000090B8912D91D89F0E6CE5645864E265756EF476847B1B906993D16EBA54F2
5FB964A48F4D8FED92445178586B59295C555E976DFB7E8F751C8CBC8EE2985B
70B94F1D6BBF6FB1753096FB514E54105835585759AC5C605F926597675C6E21
767B83DF8CED901490FD934D7825783A52AA5EA6571F597460125012515A51AC
51CD520055105854585859575B955CF65D8B60BC6295642D6771684368BC68DF
76D76DD86E6F6D9B706F71C85F5375D879777B497B547B527CD67D7152300000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
46
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008463856985E48A0E8B048C468E0F9003900F94199676982D9A3095D850CD
52D5540C58025C0E61A7649E6D1E77B37AE580F48404905392855CE09D07533F
5F975FB36D9C7279776379BF7BE46BD272EC8AAD68036A6151F87A8169345C4A
9CF682EB5BC59149701E56785C6F60C765666C8C8C5A90419813545166C7920D
594890A351854E4D51EA85998B0E7058637A934B696299B47E04757753576960
8EDF96E36C5D4E8C5C3C5F108FE953028CD1808986795EFF65E54E7351650000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
47
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000059825C3F97EE4EFB598A5FCD8A8D6FE179B079625BE78471732B71B15E74
5FF5637B649A71C37C984E435EFC4E4B57DC56A260A96FC37D0D80FD813381BF
8FB2899786A45DF4628A64AD898767776CE26D3E743678345A467F7582AD99AC
4FF35EC362DD63926557676F76C3724C80CC80BA8F29914D500D57F95A926885
6973716472FD8CB758F28CE0966A9019877F79E477E784294F2F5265535A62CD
67CF6CCA767D7B947C95823685848FEB66DD6F2072067E1B83AB99C19EA60000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
48
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000051FD7BB178727BB880877B486AE85E61808C75517560516B92626E8C767A
91979AEA4F107F70629C7B4F95A59CE9567A585986E496BC4F345224534A53CD
53DB5E06642C6591677F6C3E6C4E724872AF73ED75547E41822C85E98CA97BC4
91C67169981298EF633D6669756A76E478D0854386EE532A5351542659835E87
5F7C60B26249627962AB65906BD46CCC75B276AE789179D87DCB7F7780A588AB
8AB98CBB907F975E98DB6A0B7C3850995C3E5FAE67876BD8743577097F8E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
49
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009F3B67CA7A175339758B9AED5F66819D83F180985F3C5FC575627B46903C
686759EB5A9B7D10767E8B2C4FF55F6A6A196C376F0274E2796888688A558C79
5EDF63CF75C579D282D7932892F2849C86ED9C2D54C15F6C658C6D5C70158CA7
8CD3983B654F74F64E0D4ED857E0592B5A665BCC51A85E035E9C601662766577
65A7666E6D6E72367B268150819A82998B5C8CA08CE68D74961C96444FAE64AB
6B66821E8461856A90E85C01695398A8847A85574F0F526F5FA95E45670D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000798F8179890789866DF55F1762556CB84ECF72699B925206543B567458B3
61A4626E711A596E7C897CDE7D1B96F06587805E4E194F75517558405E635E73
5F0A67C44E26853D9589965B7C73980150FB58C1765678A7522577A585117B86
504F590972477BC77DE88FBA8FD4904D4FBF52C95A295F0197AD4FDD821792EA
570363556B69752B88DC8F147A4252DF58936155620A66AE6BCD7C3F83E95023
4FF853055446583159495B9D5CF05CEF5D295E9662B16367653E65B9670B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006CD56CE170F978327E2B80DE82B3840C84EC870289128A2A8C4A90A692D2
98FD9CF39D6C4E4F4EA1508D5256574A59A85E3D5FD85FD9623F66B4671B67D0
68D251927D2180AA81A88B008C8C8CBF927E96325420982C531750D5535C58A8
64B26734726777667A4691E652C36CA16B8658005E4C5954672C7FFB51E176C6
646978E89B549EBB57CB59B96627679A6BCE54E969D95E55819C67959BAA67FE
9C52685D4EA64FE353C862B9672B6CAB8FC44FAD7E6D9EBF4E0761626E800000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006F2B85135473672A9B455DF37B955CAC5BC6871C6E4A84D17A1481085999
7C8D6C11772052D959227121725F77DB97279D61690B5A7F5A1851A5540D547D
660E76DF8FF792989CF459EA725D6EC5514D68C97DBF7DEC97629EBA64786A21
830259845B5F6BDB731B76F27DB280178499513267289ED976EE676252FF9905
5C24623B7C7E8CB0554F60B67D0B958053014E5F51B6591C723A803691CE5F25
77E253845F797D0485AC8A338E8D975667F385AE9453610961086CB976520000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008AED8F38552F4F51512A52C753CB5BA55E7D60A0618263D6670967DA6E67
6D8C733673377531795088D58A98904A909190F596C4878D59154E884F594E0E
8A898F3F981050AD5E7C59965BB95EB863DA63FA64C166DC694A69D86D0B6EB6
719475287AAF7F8A8000844984C989818B218E0A9065967D990A617E62916B32
6C836D747FCC7FFC6DC07F8587BA88F8676583B1983C96F76D1B7D61843D916A
4E7153755D506B046FEB85CD862D89A75229540F5C65674E68A8740674830000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075E288CF88E191CC96E296785F8B73877ACB844E63A0756552896D416E9C
74097559786B7C9296867ADC9F8D4FB6616E65C5865C4E864EAE50DA4E2151CC
5BEE659968816DBC731F764277AD7A1C7CE7826F8AD2907C91CF96759818529B
7DD1502B539867976DCB71D0743381E88F2A96A39C579E9F746058416D997D2F
985E4EE44F364F8B51B752B15DBA601C73B2793C82D3923496B796F6970A9E97
9F6266A66B74521752A370C888C25EC9604B61906F2371497C3E7DF4806F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000084EE9023932C54429B6F6AD370898CC28DEF973252B45A415ECA5F046717
697C69946D6A6F0F726272FC7BED8001807E874B90CE516D9E937984808B9332
8AD6502D548C8A716B6A8CC4810760D167A09DF24E994E989C108A6B85C18568
69006E7E78978155000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
50
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F0C4E104E154E2A4E314E364E3C4E3F4E424E564E584E824E858C6B4E8A
82125F0D4E8E4E9E4E9F4EA04EA24EB04EB34EB64ECE4ECD4EC44EC64EC24ED7
4EDE4EED4EDF4EF74F094F5A4F304F5B4F5D4F574F474F764F884F8F4F984F7B
4F694F704F914F6F4F864F9651184FD44FDF4FCE4FD84FDB4FD14FDA4FD04FE4
4FE5501A50285014502A502550054F1C4FF650215029502C4FFE4FEF50115006
504350476703505550505048505A5056506C50785080509A508550B450B20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
51
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000050C950CA50B350C250D650DE50E550ED50E350EE50F950F5510951015102
511651155114511A5121513A5137513C513B513F51405152514C515451627AF8
5169516A516E5180518256D8518C5189518F519151935195519651A451A651A2
51A951AA51AB51B351B151B251B051B551BD51C551C951DB51E0865551E951ED
51F051F551FE5204520B5214520E5227522A522E52335239524F5244524B524C
525E5254526A527452695273527F527D528D529452925271528852918FA80000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
52
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008FA752AC52AD52BC52B552C152CD52D752DE52E352E698ED52E052F352F5
52F852F9530653087538530D5310530F5315531A5323532F5331533353385340
534653454E175349534D51D6535E5369536E5918537B53775382539653A053A6
53A553AE53B053B653C37C1296D953DF66FC71EE53EE53E853ED53FA5401543D
5440542C542D543C542E54365429541D544E548F5475548E545F547154775470
5492547B5480547654845490548654C754A254B854A554AC54C454C854A80000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
53
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054AB54C254A454BE54BC54D854E554E6550F551454FD54EE54ED54FA54E2
553955405563554C552E555C55455556555755385533555D5599558054AF558A
559F557B557E5598559E55AE557C558355A9558755A855DA55C555DF55C455DC
55E455D4561455F7561655FE55FD561B55F9564E565071DF5634563656325638
566B5664562F566C566A56865680568A56A05694568F56A556AE56B656B456C2
56BC56C156C356C056C856CE56D156D356D756EE56F9570056FF570457090000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005708570B570D57135718571655C7571C572657375738574E573B5740574F
576957C057885761577F5789579357A057B357A457AA57B057C357C657D457D2
57D3580A57D657E3580B5819581D587258215862584B58706BC05852583D5879
588558B9589F58AB58BA58DE58BB58B858AE58C558D358D158D758D958D858E5
58DC58E458DF58EF58FA58F958FB58FC58FD5902590A5910591B68A65925592C
592D59325938593E7AD259555950594E595A5958596259605967596C59690000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
55
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000059785981599D4F5E4FAB59A359B259C659E859DC598D59D959DA5A255A1F
5A115A1C5A095A1A5A405A6C5A495A355A365A625A6A5A9A5ABC5ABE5ACB5AC2
5ABD5AE35AD75AE65AE95AD65AFA5AFB5B0C5B0B5B165B325AD05B2A5B365B3E
5B435B455B405B515B555B5A5B5B5B655B695B705B735B755B7865885B7A5B80
5B835BA65BB85BC35BC75BC95BD45BD05BE45BE65BE25BDE5BE55BEB5BF05BF6
5BF35C055C075C085C0D5C135C205C225C285C385C395C415C465C4E5C530000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
56
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005C505C4F5B715C6C5C6E4E625C765C795C8C5C915C94599B5CAB5CBB5CB6
5CBC5CB75CC55CBE5CC75CD95CE95CFD5CFA5CED5D8C5CEA5D0B5D155D175D5C
5D1F5D1B5D115D145D225D1A5D195D185D4C5D525D4E5D4B5D6C5D735D765D87
5D845D825DA25D9D5DAC5DAE5DBD5D905DB75DBC5DC95DCD5DD35DD25DD65DDB
5DEB5DF25DF55E0B5E1A5E195E115E1B5E365E375E445E435E405E4E5E575E54
5E5F5E625E645E475E755E765E7A9EBC5E7F5EA05EC15EC25EC85ED05ECF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
57
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005ED65EE35EDD5EDA5EDB5EE25EE15EE85EE95EEC5EF15EF35EF05EF45EF8
5EFE5F035F095F5D5F5C5F0B5F115F165F295F2D5F385F415F485F4C5F4E5F2F
5F515F565F575F595F615F6D5F735F775F835F825F7F5F8A5F885F915F875F9E
5F995F985FA05FA85FAD5FBC5FD65FFB5FE45FF85FF15FDD60B35FFF60216060
601960106029600E6031601B6015602B6026600F603A605A6041606A6077605F
604A6046604D6063604360646042606C606B60596081608D60E76083609A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
58
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006084609B60966097609260A7608B60E160B860E060D360B45FF060BD60C6
60B560D8614D6115610660F660F7610060F460FA6103612160FB60F1610D610E
6147613E61286127614A613F613C612C6134613D614261446173617761586159
615A616B6174616F61656171615F615D6153617561996196618761AC6194619A
618A619161AB61AE61CC61CA61C961F761C861C361C661BA61CB7F7961CD61E6
61E361F661FA61F461FF61FD61FC61FE620062086209620D620C6214621B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000621E6221622A622E6230623262336241624E625E6263625B62606268627C
62826289627E62926293629662D46283629462D762D162BB62CF62FF62C664D4
62C862DC62CC62CA62C262C7629B62C9630C62EE62F163276302630862EF62F5
6350633E634D641C634F6396638E638063AB637663A3638F6389639F63B5636B
636963BE63E963C063C663E363C963D263F663C4641664346406641364266436
651D64176428640F6467646F6476644E652A6495649364A564A9648864BC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000064DA64D264C564C764BB64D864C264F164E7820964E064E162AC64E364EF
652C64F664F464F264FA650064FD6518651C650565246523652B653465356537
65366538754B654865566555654D6558655E655D65726578658265838B8A659B
659F65AB65B765C365C665C165C465CC65D265DB65D965E065E165F16772660A
660365FB6773663566366634661C664F664466496641665E665D666466676668
665F6662667066836688668E668966846698669D66C166B966C966BE66BC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000066C466B866D666DA66E0663F66E666E966F066F566F7670F6716671E6726
67279738672E673F67366741673867376746675E676067596763676467896770
67A9677C676A678C678B67A667A1678567B767EF67B467EC67B367E967B867E4
67DE67DD67E267EE67B967CE67C667E76A9C681E684668296840684D6832684E
68B3682B685968636877687F689F688F68AD6894689D689B68836AAE68B96874
68B568A068BA690F688D687E690168CA690868D86922692668E1690C68CD0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000068D468E768D569366912690468D768E3692568F968E068EF6928692A691A
6923692168C669796977695C6978696B6954697E696E69396974693D69596930
6961695E695D6981696A69B269AE69D069BF69C169D369BE69CE5BE869CA69DD
69BB69C369A76A2E699169A0699C699569B469DE69E86A026A1B69FF6B0A69F9
69F269E76A0569B16A1E69ED6A1469EB6A0A6A126AC16A236A136A446A0C6A72
6A366A786A476A626A596A666A486A386A226A906A8D6AA06A846AA26AA30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006A9786176ABB6AC36AC26AB86AB36AAC6ADE6AD16ADF6AAA6ADA6AEA6AFB
6B0586166AFA6B126B169B316B1F6B386B3776DC6B3998EE6B476B436B496B50
6B596B546B5B6B5F6B616B786B796B7F6B806B846B836B8D6B986B956B9E6BA4
6BAA6BAB6BAF6BB26BB16BB36BB76BBC6BC66BCB6BD36BDF6BEC6BEB6BF36BEF
9EBE6C086C136C146C1B6C246C236C5E6C556C626C6A6C826C8D6C9A6C816C9B
6C7E6C686C736C926C906CC46CF16CD36CBD6CD76CC56CDD6CAE6CB16CBE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006CBA6CDB6CEF6CD96CEA6D1F884D6D366D2B6D3D6D386D196D356D336D12
6D0C6D636D936D646D5A6D796D596D8E6D956FE46D856DF96E156E0A6DB56DC7
6DE66DB86DC66DEC6DDE6DCC6DE86DD26DC56DFA6DD96DE46DD56DEA6DEE6E2D
6E6E6E2E6E196E726E5F6E3E6E236E6B6E2B6E766E4D6E1F6E436E3A6E4E6E24
6EFF6E1D6E386E826EAA6E986EC96EB76ED36EBD6EAF6EC46EB26ED46ED56E8F
6EA56EC26E9F6F416F11704C6EEC6EF86EFE6F3F6EF26F316EEF6F326ECC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006F3E6F136EF76F866F7A6F786F816F806F6F6F5B6FF36F6D6F826F7C6F58
6F8E6F916FC26F666FB36FA36FA16FA46FB96FC66FAA6FDF6FD56FEC6FD46FD8
6FF16FEE6FDB7009700B6FFA70117001700F6FFE701B701A6F74701D7018701F
7030703E7032705170637099709270AF70F170AC70B870B370AE70DF70CB70DD
70D9710970FD711C711971657155718871667162714C7156716C718F71FB7184
719571A871AC71D771B971BE71D271C971D471CE71E071EC71E771F571FC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
60
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000071F971FF720D7210721B7228722D722C72307232723B723C723F72407246
724B72587274727E7282728172877292729672A272A772B972B272C372C672C4
72CE72D272E272E072E172F972F7500F7317730A731C7316731D7334732F7329
7325733E734E734F9ED87357736A7368737073787375737B737A73C873B373CE
73BB73C073E573EE73DE74A27405746F742573F87432743A7455743F745F7459
7441745C746974707463746A7476747E748B749E74A774CA74CF74D473F10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
61
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000074E074E374E774E974EE74F274F074F174F874F7750475037505750C750E
750D75157513751E7526752C753C7544754D754A7549755B7546755A75697564
7567756B756D75787576758675877574758A758975827594759A759D75A575A3
75C275B375C375B575BD75B875BC75B175CD75CA75D275D975E375DE75FE75FF
75FC760175F075FA75F275F3760B760D7609761F762776207621762276247634
7630763B764776487646765C76587661766276687669766A7667766C76700000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
62
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000767276767678767C768076837688768B768E769676937699769A76B076B4
76B876B976BA76C276CD76D676D276DE76E176E576E776EA862F76FB77087707
770477297724771E77257726771B773777387747775A7768776B775B7765777F
777E7779778E778B779177A0779E77B077B677B977BF77BC77BD77BB77C777CD
77D777DA77DC77E377EE77FC780C781279267820792A7845788E78747886787C
789A788C78A378B578AA78AF78D178C678CB78D478BE78BC78C578CA78EC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
63
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000078E778DA78FD78F47907791279117919792C792B794079607957795F795A
79557953797A797F798A799D79A79F4B79AA79AE79B379B979BA79C979D579E7
79EC79E179E37A087A0D7A187A197A207A1F79807A317A3B7A3E7A377A437A57
7A497A617A627A699F9D7A707A797A7D7A887A977A957A987A967AA97AC87AB0
7AB67AC57AC47ABF90837AC77ACA7ACD7ACF7AD57AD37AD97ADA7ADD7AE17AE2
7AE67AED7AF07B027B0F7B0A7B067B337B187B197B1E7B357B287B367B500000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
64
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007B7A7B047B4D7B0B7B4C7B457B757B657B747B677B707B717B6C7B6E7B9D
7B987B9F7B8D7B9C7B9A7B8B7B927B8F7B5D7B997BCB7BC17BCC7BCF7BB47BC6
7BDD7BE97C117C147BE67BE57C607C007C077C137BF37BF77C177C0D7BF67C23
7C277C2A7C1F7C377C2B7C3D7C4C7C437C547C4F7C407C507C587C5F7C647C56
7C657C6C7C757C837C907CA47CAD7CA27CAB7CA17CA87CB37CB27CB17CAE7CB9
7CBD7CC07CC57CC27CD87CD27CDC7CE29B3B7CEF7CF27CF47CF67CFA7D060000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
65
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007D027D1C7D157D0A7D457D4B7D2E7D327D3F7D357D467D737D567D4E7D72
7D687D6E7D4F7D637D937D897D5B7D8F7D7D7D9B7DBA7DAE7DA37DB57DC77DBD
7DAB7E3D7DA27DAF7DDC7DB87D9F7DB07DD87DDD7DE47DDE7DFB7DF27DE17E05
7E0A7E237E217E127E317E1F7E097E0B7E227E467E667E3B7E357E397E437E37
7E327E3A7E677E5D7E567E5E7E597E5A7E797E6A7E697E7C7E7B7E837DD57E7D
8FAE7E7F7E887E897E8C7E927E907E937E947E967E8E7E9B7E9C7F387F3A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
66
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007F457F4C7F4D7F4E7F507F517F557F547F587F5F7F607F687F697F677F78
7F827F867F837F887F877F8C7F947F9E7F9D7F9A7FA37FAF7FB27FB97FAE7FB6
7FB88B717FC57FC67FCA7FD57FD47FE17FE67FE97FF37FF998DC80068004800B
801280188019801C80218028803F803B804A804680528058805A805F80628068
80738072807080768079807D807F808480868085809B8093809A80AD519080AC
80DB80E580D980DD80C480DA80D6810980EF80F1811B81298123812F814B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
67
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000968B8146813E8153815180FC8171816E81658166817481838188818A8180
818281A0819581A481A3815F819381A981B081B581BE81B881BD81C081C281BA
81C981CD81D181D981D881C881DA81DF81E081E781FA81FB81FE820182028205
8207820A820D821082168229822B82388233824082598258825D825A825F8264
82628268826A826B822E827182778278827E828D829282AB829F82BB82AC82E1
82E382DF82D282F482F382FA8393830382FB82F982DE830682DC830982D90000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
68
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000833583348316833283318340833983508345832F832B831783188385839A
83AA839F83A283968323838E8387838A837C83B58373837583A0838983A883F4
841383EB83CE83FD840383D8840B83C183F7840783E083F2840D8422842083BD
8438850683FB846D842A843C855A84848477846B84AD846E848284698446842C
846F8479843584CA846284B984BF849F84D984CD84BB84DA84D084C184C684D6
84A1852184FF84F485178518852C851F8515851484FC85408563855885480000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
69
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000085418602854B8555858085A485888591858A85A8856D8594859B85EA8587
859C8577857E859085C985BA85CF85B985D085D585DD85E585DC85F9860A8613
860B85FE85FA86068622861A8630863F864D4E558654865F86678671869386A3
86A986AA868B868C86B686AF86C486C686B086C9882386AB86D486DE86E986EC
86DF86DB86EF8712870687088700870386FB87118709870D86F9870A8734873F
8737873B87258729871A8760875F8778874C874E877487578768876E87590000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000087538763876A880587A2879F878287AF87CB87BD87C087D096D687AB87C4
87B387C787C687BB87EF87F287E0880F880D87FE87F687F7880E87D288118816
8815882288218831883688398827883B8844884288528859885E8862886B8881
887E889E8875887D88B5887288828897889288AE889988A2888D88A488B088BF
88B188C388C488D488D888D988DD88F9890288FC88F488E888F28904890C890A
89138943891E8925892A892B89418944893B89368938894C891D8960895E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000089668964896D896A896F89748977897E89838988898A8993899889A189A9
89A689AC89AF89B289BA89BD89BF89C089DA89DC89DD89E789F489F88A038A16
8A108A0C8A1B8A1D8A258A368A418A5B8A528A468A488A7C8A6D8A6C8A628A85
8A828A848AA88AA18A918AA58AA68A9A8AA38AC48ACD8AC28ADA8AEB8AF38AE7
8AE48AF18B148AE08AE28AF78ADE8ADB8B0C8B078B1A8AE18B168B108B178B20
8B3397AB8B268B2B8B3E8B288B418B4C8B4F8B4E8B498B568B5B8B5A8B6B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008B5F8B6C8B6F8B748B7D8B808B8C8B8E8B928B938B968B998B9A8C3A8C41
8C3F8C488C4C8C4E8C508C558C628C6C8C788C7A8C828C898C858C8A8C8D8C8E
8C948C7C8C98621D8CAD8CAA8CBD8CB28CB38CAE8CB68CC88CC18CE48CE38CDA
8CFD8CFA8CFB8D048D058D0A8D078D0F8D0D8D109F4E8D138CCD8D148D168D67
8D6D8D718D738D818D998DC28DBE8DBA8DCF8DDA8DD68DCC8DDB8DCB8DEA8DEB
8DDF8DE38DFC8E088E098DFF8E1D8E1E8E108E1F8E428E358E308E348E4A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008E478E498E4C8E508E488E598E648E608E2A8E638E558E768E728E7C8E81
8E878E858E848E8B8E8A8E938E918E948E998EAA8EA18EAC8EB08EC68EB18EBE
8EC58EC88ECB8EDB8EE38EFC8EFB8EEB8EFE8F0A8F058F158F128F198F138F1C
8F1F8F1B8F0C8F268F338F3B8F398F458F428F3E8F4C8F498F468F4E8F578F5C
8F628F638F648F9C8F9F8FA38FAD8FAF8FB78FDA8FE58FE28FEA8FEF90878FF4
90058FF98FFA901190159021900D901E9016900B90279036903590398FF80000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000904F905090519052900E9049903E90569058905E9068906F907696A89072
9082907D90819080908A9089908F90A890AF90B190B590E290E4624890DB9102
9112911991329130914A9156915891639165916991739172918B9189918291A2
91AB91AF91AA91B591B491BA91C091C191C991CB91D091D691DF91E191DB91FC
91F591F6921E91FF9214922C92159211925E925792459249926492489295923F
924B9250929C92969293929B925A92CF92B992B792E9930F92FA9344932E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000093199322931A9323933A9335933B935C9360937C936E935693B093AC93AD
939493B993D693D793E893E593D893C393DD93D093C893E4941A941494139403
940794109436942B94359421943A944194529444945B94609462945E946A9229
947094759477947D945A947C947E9481947F95829587958A9594959695989599
95A095A895A795AD95BC95BB95B995BE95CA6FF695C395CD95CC95D595D495D6
95DC95E195E595E296219628962E962F9642964C964F964B9677965C965E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
70
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000965D965F96669672966C968D96989695969796AA96A796B196B296B096B4
96B696B896B996CE96CB96C996CD894D96DC970D96D596F99704970697089713
970E9711970F971697199724972A97309739973D973E97449746974897429749
975C976097649766976852D2976B977197799785977C9781977A9786978B978F
9790979C97A897A697A397B397B497C397C697C897CB97DC97ED9F4F97F27ADF
97F697F5980F980C9838982498219837983D9846984F984B986B986F98700000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
71
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000098719874987398AA98AF98B198B698C498C398C698E998EB990399099912
991499189921991D991E99249920992C992E993D993E9942994999459950994B
99519952994C99559997999899A599AD99AE99BC99DF99DB99DD99D899D199ED
99EE99F199F299FB99F89A019A0F9A0599E29A199A2B9A379A459A429A409A43
9A3E9A559A4D9A5B9A579A5F9A629A659A649A699A6B9A6A9AAD9AB09ABC9AC0
9ACF9AD19AD39AD49ADE9ADF9AE29AE39AE69AEF9AEB9AEE9AF49AF19AF70000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
72
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009AFB9B069B189B1A9B1F9B229B239B259B279B289B299B2A9B2E9B2F9B32
9B449B439B4F9B4D9B4E9B519B589B749B939B839B919B969B979B9F9BA09BA8
9BB49BC09BCA9BB99BC69BCF9BD19BD29BE39BE29BE49BD49BE19C3A9BF29BF1
9BF09C159C149C099C139C0C9C069C089C129C0A9C049C2E9C1B9C259C249C21
9C309C479C329C469C3E9C5A9C609C679C769C789CE79CEC9CF09D099D089CEB
9D039D069D2A9D269DAF9D239D1F9D449D159D129D419D3F9D3E9D469D480000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
73
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009D5D9D5E9D649D519D509D599D729D899D879DAB9D6F9D7A9D9A9DA49DA9
9DB29DC49DC19DBB9DB89DBA9DC69DCF9DC29DD99DD39DF89DE69DED9DEF9DFD
9E1A9E1B9E1E9E759E799E7D9E819E889E8B9E8C9E929E959E919E9D9EA59EA9
9EB89EAA9EAD97619ECC9ECE9ECF9ED09ED49EDC9EDE9EDD9EE09EE59EE89EEF
9EF49EF69EF79EF99EFB9EFC9EFD9F079F0876B79F159F219F2C9F3E9F4A9F52
9F549F639F5F9F609F619F669F679F6C9F6A9F779F729F769F959F9C9FA00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
74
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000582F69C79059746451DC7199000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/jis0212.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
# Encoding file: jis0212, double-byte
D
2244 0 68
22
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000002D8
02C700B802D902DD00AF02DB02DA007E03840385000000000000000000000000
0000000000A100A600BF00000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000BA00AA00A900AE2122
00A4211600000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
26
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000038603880389038A03AA0000038C0000038E03AB0000038F000000000000
000003AC03AD03AE03AF03CA039003CC03C203CD03CB03B003CE000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
27
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000004020403040404050406040704080409040A040B040C040E040F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000004520453045404550456045704580459045A045B045C045E045F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
29
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000C60110000001260000013200000141013F0000014A00D8015200000166
00DE000000000000000000000000000000000000000000000000000000000000
000000E6011100F00127013101330138014201400149014B00F8015300DF0167
00FE000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
2A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000C100C000C400C2010201CD0100010400C500C301060108010C00C7010A
010E00C900C800CB00CA011A0116011201180000011C011E01220120012400CD
00CC00CF00CE01CF0130012A012E0128013401360139013D013B014301470145
00D100D300D200D600D401D10150014C00D5015401580156015A015C0160015E
0164016200DA00D900DC00DB016C01D30170016A0172016E016801D701DB01D9
01D5017400DD017801760179017D017B00000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
2B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000E100E000E400E2010301CE0101010500E500E301070109010D00E7010B
010F00E900E800EB00EA011B01170113011901F5011D011F00000121012500ED
00EC00EF00EE01D00000012B012F012901350137013A013E013C014401480146
00F100F300F200F600F401D20151014D00F5015501590157015B015D0161015F
0165016300FA00F900FC00FB016D01D40171016B0173016F016901D801DC01DA
01D6017500FD00FF0177017A017E017C00000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
30
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E024E044E054E0C4E124E1F4E234E244E284E2B4E2E4E2F4E304E354E40
4E414E444E474E514E5A4E5C4E634E684E694E744E754E794E7F4E8D4E964E97
4E9D4EAF4EB94EC34ED04EDA4EDB4EE04EE14EE24EE84EEF4EF14EF34EF54EFD
4EFE4EFF4F004F024F034F084F0B4F0C4F124F154F164F174F194F2E4F314F60
4F334F354F374F394F3B4F3E4F404F424F484F494F4B4F4C4F524F544F564F58
4F5F4F634F6A4F6C4F6E4F714F774F784F794F7A4F7D4F7E4F814F824F840000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
31
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F854F894F8A4F8C4F8E4F904F924F934F944F974F994F9A4F9E4F9F4FB2
4FB74FB94FBB4FBC4FBD4FBE4FC04FC14FC54FC64FC84FC94FCB4FCC4FCD4FCF
4FD24FDC4FE04FE24FF04FF24FFC4FFD4FFF5000500150045007500A500C500E
5010501350175018501B501C501D501E50225027502E50305032503350355040
5041504250455046504A504C504E50515052505350575059505F506050625063
50665067506A506D50705071503B5081508350845086508A508E508F50900000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
32
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005092509350945096509B509C509E509F50A050A150A250AA50AF50B050B9
50BA50BD50C050C350C450C750CC50CE50D050D350D450D850DC50DD50DF50E2
50E450E650E850E950EF50F150F650FA50FE5103510651075108510B510C510D
510E50F2511051175119511B511C511D511E512351275128512C512D512F5131
513351345135513851395142514A514F5153515551575158515F51645166517E
51835184518B518E5198519D51A151A351AD51B851BA51BC51BE51BF51C20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
33
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000051C851CF51D151D251D351D551D851DE51E251E551EE51F251F351F451F7
5201520252055212521352155216521852225228523152325235523C52455249
525552575258525A525C525F526052615266526E527752785279528052825285
528A528C52935295529652975298529A529C52A452A552A652A752AF52B052B6
52B752B852BA52BB52BD52C052C452C652C852CC52CF52D152D452D652DB52DC
52E152E552E852E952EA52EC52F052F152F452F652F753005303530A530B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
34
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000530C531153135318531B531C531E531F5325532753285329532B532C532D
533053325335533C533D533E5342534C534B5359535B536153635365536C536D
53725379537E538353875388538E539353945399539D53A153A453AA53AB53AF
53B253B453B553B753B853BA53BD53C053C553CF53D253D353D553DA53DD53DE
53E053E653E753F554025413541A542154275428542A542F5431543454355443
54445447544D544F545E54625464546654675469546B546D546E5474547F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
35
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054815483548554885489548D549154955496549C549F54A154A654A754A9
54AA54AD54AE54B154B754B954BA54BB54BF54C654CA54CD54CE54E054EA54EC
54EF54F654FC54FE54FF55005501550555085509550C550D550E5515552A552B
553255355536553B553C553D554155475549554A554D555055515558555A555B
555E5560556155645566557F5581558255865588558E558F5591559255935594
559755A355A455AD55B255BF55C155C355C655C955CB55CC55CE55D155D20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
36
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000055D355D755D855DB55DE55E255E955F655FF56055608560A560D560E560F
5610561156125619562C56305633563556375639563B563C563D563F56405641
5643564456465649564B564D564F5654565E566056615662566356665669566D
566F567156725675568456855688568B568C56955699569A569D569E569F56A6
56A756A856A956AB56AC56AD56B156B356B756BE56C556C956CA56CB56CF56D0
56CC56CD56D956DC56DD56DF56E156E456E556E656E756E856F156EB56ED0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
37
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000056F656F7570157025707570A570C57115715571A571B571D572057225723
572457255729572A572C572E572F57335734573D573E573F57455746574C574D
57525762576557675768576B576D576E576F5770577157735774577557775779
577A577B577C577E57815783578C579457975799579A579C579D579E579F57A1
579557A757A857A957AC57B857BD57C757C857CC57CF57D557DD57DE57E457E6
57E757E957ED57F057F557F657F857FD57FE57FF580358045808580957E10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
38
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000580C580D581B581E581F582058265827582D58325839583F5849584C584D
584F58505855585F58615864586758685878587C587F58805881588758885889
588A588C588D588F589058945896589D58A058A158A258A658A958B158B258C4
58BC58C258C858CD58CE58D058D258D458D658DA58DD58E158E258E958F35905
5906590B590C5912591359148641591D5921592359245928592F593059335935
5936593F59435946595259535959595B595D595E595F59615963596B596D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
39
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000596F5972597559765979597B597C598B598C598E599259955997599F59A4
59A759AD59AE59AF59B059B359B759BA59BC59C159C359C459C859CA59CD59D2
59DD59DE59DF59E359E459E759EE59EF59F159F259F459F75A005A045A0C5A0D
5A0E5A125A135A1E5A235A245A275A285A2A5A2D5A305A445A455A475A485A4C
5A505A555A5E5A635A655A675A6D5A775A7A5A7B5A7E5A8B5A905A935A965A99
5A9C5A9E5A9F5AA05AA25AA75AAC5AB15AB25AB35AB55AB85ABA5ABB5ABF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005AC45AC65AC85ACF5ADA5ADC5AE05AE55AEA5AEE5AF55AF65AFD5B005B01
5B085B175B345B195B1B5B1D5B215B255B2D5B385B415B4B5B4C5B525B565B5E
5B685B6E5B6F5B7C5B7D5B7E5B7F5B815B845B865B8A5B8E5B905B915B935B94
5B965BA85BA95BAC5BAD5BAF5BB15BB25BB75BBA5BBC5BC05BC15BCD5BCF5BD6
5BD75BD85BD95BDA5BE05BEF5BF15BF45BFD5C0C5C175C1E5C1F5C235C265C29
5C2B5C2C5C2E5C305C325C355C365C595C5A5C5C5C625C635C675C685C690000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005C6D5C705C745C755C7A5C7B5C7C5C7D5C875C885C8A5C8F5C925C9D5C9F
5CA05CA25CA35CA65CAA5CB25CB45CB55CBA5CC95CCB5CD25CDD5CD75CEE5CF1
5CF25CF45D015D065D0D5D125D2B5D235D245D265D275D315D345D395D3D5D3F
5D425D435D465D485D555D515D595D4A5D5F5D605D615D625D645D6A5D6D5D70
5D795D7A5D7E5D7F5D815D835D885D8A5D925D935D945D955D995D9B5D9F5DA0
5DA75DAB5DB05DB45DB85DB95DC35DC75DCB5DD05DCE5DD85DD95DE05DE40000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005DE95DF85DF95E005E075E0D5E125E145E155E185E1F5E205E2E5E285E32
5E355E3E5E4B5E505E495E515E565E585E5B5E5C5E5E5E685E6A5E6B5E6C5E6D
5E6E5E705E805E8B5E8E5EA25EA45EA55EA85EAA5EAC5EB15EB35EBD5EBE5EBF
5EC65ECC5ECB5ECE5ED15ED25ED45ED55EDC5EDE5EE55EEB5F025F065F075F08
5F0E5F195F1C5F1D5F215F225F235F245F285F2B5F2C5F2E5F305F345F365F3B
5F3D5F3F5F405F445F455F475F4D5F505F545F585F5B5F605F635F645F670000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F6F5F725F745F755F785F7A5F7D5F7E5F895F8D5F8F5F965F9C5F9D5FA2
5FA75FAB5FA45FAC5FAF5FB05FB15FB85FC45FC75FC85FC95FCB5FD05FD15FD2
5FD35FD45FDE5FE15FE25FE85FE95FEA5FEC5FED5FEE5FEF5FF25FF35FF65FFA
5FFC6007600A600D6013601460176018601A601F6024602D6033603560406047
60486049604C6051605460566057605D606160676071607E607F608260866088
608A608E6091609360956098609D609E60A260A460A560A860B060B160B70000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000060BB60BE60C260C460C860C960CA60CB60CE60CF60D460D560D960DB60DD
60DE60E260E560F260F560F860FC60FD61026107610A610C6110611161126113
6114611661176119611C611E6122612A612B6130613161356136613761396141
614561466149615E6160616C61726178617B617C617F6180618161836184618B
618D6192619361976198619C619D619F61A061A561A861AA61AD61B861B961BC
61C061C161C261CE61CF61D561DC61DD61DE61DF61E161E261E761E961E50000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000061EC61ED61EF620162036204620762136215621C62206222622362276229
622B6239623D6242624362446246624C62506251625262546256625A625C6264
626D626F6273627A627D628D628E628F629062A662A862B362B662B762BA62BE
62BF62C462CE62D562D662DA62EA62F262F462FC62FD63036304630A630B630D
63106313631663186329632A632D633563366339633C63416342634363446346
634A634B634E6352635363546358635B63656366636C636D6371637463750000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
40
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006378637C637D637F638263846387638A6390639463956399639A639E63A4
63A663AD63AE63AF63BD63C163C563C863CE63D163D363D463D563DC63E063E5
63EA63EC63F263F363F563F863F96409640A6410641264146418641E64206422
642464256429642A642F64306435643D643F644B644F6451645264536454645A
645B645C645D645F646064616463646D64736474647B647D64856487648F6490
649164986499649B649D649F64A164A364A664A864AC64B364BD64BE64BF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
41
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000064C464C964CA64CB64CC64CE64D064D164D564D764E464E564E964EA64ED
64F064F564F764FB64FF6501650465086509650A650F6513651465166519651B
651E651F652265266529652E6531653A653C653D654365476549655065526554
655F65606567656B657A657D65816585658A659265956598659D65A065A365A6
65AE65B265B365B465BF65C265C865C965CE65D065D465D665D865DF65F065F2
65F465F565F965FE65FF6600660466086609660D6611661266156616661D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
42
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000661E662166226623662466266629662A662B662C662E6630663166336639
6637664066456646664A664C6651664E665766586659665B665C6660666166FB
666A666B666C667E66736675667F667766786679667B6680667C668B668C668D
669066926699669A669B669C669F66A066A466AD66B166B266B566BB66BF66C0
66C266C366C866CC66CE66CF66D466DB66DF66E866EB66EC66EE66FA67056707
670E67136719671C672067226733673E674567476748674C67546755675D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
43
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006766676C676E67746776677B67816784678E678F67916793679667986799
679B67B067B167B267B567BB67BC67BD67F967C067C267C367C567C867C967D2
67D767D967DC67E167E667F067F267F667F7685268146819681D681F68286827
682C682D682F683068316833683B683F68446845684A684C685568576858685B
686B686E686F68706871687268756879687A687B687C68826884688668886896
6898689A689C68A168A368A568A968AA68AE68B268BB68C568C868CC68CF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
44
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000068D068D168D368D668D968DC68DD68E568E868EA68EB68EC68ED68F068F1
68F568F668FB68FC68FD69066909690A69106911691369166917693169336935
6938693B694269456949694E6957695B696369646965696669686969696C6970
69716972697A697B697F6980698D69926996699869A169A569A669A869AB69AD
69AF69B769B869BA69BC69C569C869D169D669D769E269E569EE69EF69F169F3
69F569FE6A006A016A036A0F6A116A156A1A6A1D6A206A246A286A306A320000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
45
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006A346A376A3B6A3E6A3F6A456A466A496A4A6A4E6A506A516A526A556A56
6A5B6A646A676A6A6A716A736A7E6A816A836A866A876A896A8B6A916A9B6A9D
6A9E6A9F6AA56AAB6AAF6AB06AB16AB46ABD6ABE6ABF6AC66AC96AC86ACC6AD0
6AD46AD56AD66ADC6ADD6AE46AE76AEC6AF06AF16AF26AFC6AFD6B026B036B06
6B076B096B0F6B106B116B176B1B6B1E6B246B286B2B6B2C6B2F6B356B366B3B
6B3F6B466B4A6B4D6B526B566B586B5D6B606B676B6B6B6E6B706B756B7D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
46
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006B7E6B826B856B976B9B6B9F6BA06BA26BA36BA86BA96BAC6BAD6BAE6BB0
6BB86BB96BBD6BBE6BC36BC46BC96BCC6BD66BDA6BE16BE36BE66BE76BEE6BF1
6BF76BF96BFF6C026C046C056C096C0D6C0E6C106C126C196C1F6C266C276C28
6C2C6C2E6C336C356C366C3A6C3B6C3F6C4A6C4B6C4D6C4F6C526C546C596C5B
6C5C6C6B6C6D6C6F6C746C766C786C796C7B6C856C866C876C896C946C956C97
6C986C9C6C9F6CB06CB26CB46CC26CC66CCD6CCF6CD06CD16CD26CD46CD60000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
47
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006CDA6CDC6CE06CE76CE96CEB6CEC6CEE6CF26CF46D046D076D0A6D0E6D0F
6D116D136D1A6D266D276D286C676D2E6D2F6D316D396D3C6D3F6D576D5E6D5F
6D616D656D676D6F6D706D7C6D826D876D916D926D946D966D976D986DAA6DAC
6DB46DB76DB96DBD6DBF6DC46DC86DCA6DCE6DCF6DD66DDB6DDD6DDF6DE06DE2
6DE56DE96DEF6DF06DF46DF66DFC6E006E046E1E6E226E276E326E366E396E3B
6E3C6E446E456E486E496E4B6E4F6E516E526E536E546E576E5C6E5D6E5E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
48
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006E626E636E686E736E7B6E7D6E8D6E936E996EA06EA76EAD6EAE6EB16EB3
6EBB6EBF6EC06EC16EC36EC76EC86ECA6ECD6ECE6ECF6EEB6EED6EEE6EF96EFB
6EFD6F046F086F0A6F0C6F0D6F166F186F1A6F1B6F266F296F2A6F2F6F306F33
6F366F3B6F3C6F2D6F4F6F516F526F536F576F596F5A6F5D6F5E6F616F626F68
6F6C6F7D6F7E6F836F876F886F8B6F8C6F8D6F906F926F936F946F966F9A6F9F
6FA06FA56FA66FA76FA86FAE6FAF6FB06FB56FB66FBC6FC56FC76FC86FCA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
49
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006FDA6FDE6FE86FE96FF06FF56FF96FFC6FFD7000700570067007700D7017
70207023702F703470377039703C7043704470487049704A704B70547055705D
705E704E70647065706C706E70757076707E7081708570867094709570967097
7098709B70A470AB70B070B170B470B770CA70D170D370D470D570D670D870DC
70E470FA71037104710571067107710B710C710F711E7120712B712D712F7130
713171387141714571467147714A714B715071527157715A715C715E71600000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000071687179718071857187718C7192719A719B71A071A271AF71B071B271B3
71BA71BF71C071C171C471CB71CC71D371D671D971DA71DC71F871FE72007207
7208720972137217721A721D721F7224722B722F723472387239724172427243
7245724E724F7250725372557256725A725C725E726072637268726B726E726F
727172777278727B727C727F72847289728D728E7293729B72A872AD72AE72B1
72B472BE72C172C772C972CC72D572D672D872DF72E572F372F472FA72FB0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000072FE7302730473057307730B730D7312731373187319731E732273247327
7328732C733173327335733A733B733D7343734D7350735273567358735D735E
735F7360736673677369736B736C736E736F737173777379737C738073817383
73857386738E73907393739573977398739C739E739F73A073A273A573A673AA
73AB73AD73B573B773B973BC73BD73BF73C573C673C973CB73CC73CF73D273D3
73D673D973DD73E173E373E673E773E973F473F573F773F973FA73FB73FD0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000073FF7400740174047407740A7411741A741B7424742674287429742A742B
742C742D742E742F74307431743974407443744474467447744B744D74517452
7457745D7462746674677468746B746D746E7471747274807481748574867487
7489748F74907491749274987499749A749C749F74A074A174A374A674A874A9
74AA74AB74AE74AF74B174B274B574B974BB74BF74C874C974CC74D074D374D8
74DA74DB74DE74DF74E474E874EA74EB74EF74F474FA74FB74FC74FF75060000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000075127516751775207521752475277529752A752F75367539753D753E753F
7540754375477548754E755075527557755E755F7561756F75717579757A757B
757C757D757E7581758575907592759375957599759C75A275A475B475BA75BF
75C075C175C475C675CC75CE75CF75D775DC75DF75E075E175E475E775EC75EE
75EF75F175F9760076027603760476077608760A760C760F7612761376157616
7619761B761C761D761E7623762576267629762D763276337635763876390000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000763A763C764A764076417643764476457649764B76557659765F76647665
766D766E766F7671767476817685768C768D7695769B769C769D769F76A076A2
76A376A476A576A676A776A876AA76AD76BD76C176C576C976CB76CC76CE76D4
76D976E076E676E876EC76F076F176F676F976FC77007706770A770E77127714
771577177719771A771C77227728772D772E772F7734773577367739773D773E
774277457746774A774D774E774F775277567757775C775E775F776077620000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077647767776A776C7770777277737774777A777D77807784778C778D7794
77957796779A779F77A277A777AA77AE77AF77B177B577BE77C377C977D177D2
77D577D977DE77DF77E077E477E677EA77EC77F077F177F477F877FB78057806
7809780D780E7811781D782178227823782D782E783078357837784378447847
7848784C784E7852785C785E78607861786378647868786A786E787A787E788A
788F7894789878A1789D789E789F78A478A878AC78AD78B078B178B278B30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
50
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000078BB78BD78BF78C778C878C978CC78CE78D278D378D578D678E478DB78DF
78E078E178E678EA78F278F3790078F678F778FA78FB78FF7906790C7910791A
791C791E791F7920792579277929792D793179347935793B793D793F79447945
7946794A794B794F795179547958795B795C79677969796B79727979797B797C
797E798B798C799179937994799579967998799B799C79A179A879A979AB79AF
79B179B479B879BB79C279C479C779C879CA79CF79D479D679DA79DD79DE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
51
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000079E079E279E579EA79EB79ED79F179F879FC7A027A037A077A097A0A7A0C
7A117A157A1B7A1E7A217A277A2B7A2D7A2F7A307A347A357A387A397A3A7A44
7A457A477A487A4C7A557A567A597A5C7A5D7A5F7A607A657A677A6A7A6D7A75
7A787A7E7A807A827A857A867A8A7A8B7A907A917A947A9E7AA07AA37AAC7AB3
7AB57AB97ABB7ABC7AC67AC97ACC7ACE7AD17ADB7AE87AE97AEB7AEC7AF17AF4
7AFB7AFD7AFE7B077B147B1F7B237B277B297B2A7B2B7B2D7B2E7B2F7B300000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
52
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007B317B347B3D7B3F7B407B417B477B4E7B557B607B647B667B697B6A7B6D
7B6F7B727B737B777B847B897B8E7B907B917B967B9B7B9E7BA07BA57BAC7BAF
7BB07BB27BB57BB67BBA7BBB7BBC7BBD7BC27BC57BC87BCA7BD47BD67BD77BD9
7BDA7BDB7BE87BEA7BF27BF47BF57BF87BF97BFA7BFC7BFE7C017C027C037C04
7C067C097C0B7C0C7C0E7C0F7C197C1B7C207C257C267C287C2C7C317C337C34
7C367C397C3A7C467C4A7C557C517C527C537C597C5A7C5B7C5C7C5D7C5E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
53
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007C617C637C677C697C6D7C6E7C707C727C797C7C7C7D7C867C877C8F7C94
7C9E7CA07CA67CB07CB67CB77CBA7CBB7CBC7CBF7CC47CC77CC87CC97CCD7CCF
7CD37CD47CD57CD77CD97CDA7CDD7CE67CE97CEB7CF57D037D077D087D097D0F
7D117D127D137D167D1D7D1E7D237D267D2A7D2D7D317D3C7D3D7D3E7D407D41
7D477D487D4D7D517D537D577D597D5A7D5C7D5D7D657D677D6A7D707D787D7A
7D7B7D7F7D817D827D837D857D867D887D8B7D8C7D8D7D917D967D977D9D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007D9E7DA67DA77DAA7DB37DB67DB77DB97DC27DC37DC47DC57DC67DCC7DCD
7DCE7DD77DD97E007DE27DE57DE67DEA7DEB7DED7DF17DF57DF67DF97DFA7E08
7E107E117E157E177E1C7E1D7E207E277E287E2C7E2D7E2F7E337E367E3F7E44
7E457E477E4E7E507E527E587E5F7E617E627E657E6B7E6E7E6F7E737E787E7E
7E817E867E877E8A7E8D7E917E957E987E9A7E9D7E9E7F3C7F3B7F3D7F3E7F3F
7F437F447F477F4F7F527F537F5B7F5C7F5D7F617F637F647F657F667F6D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
55
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007F717F7D7F7E7F7F7F807F8B7F8D7F8F7F907F917F967F977F9C7FA17FA2
7FA67FAA7FAD7FB47FBC7FBF7FC07FC37FC87FCE7FCF7FDB7FDF7FE37FE57FE8
7FEC7FEE7FEF7FF27FFA7FFD7FFE7FFF80078008800A800D800E800F80118013
80148016801D801E801F802080248026802C802E80308034803580378039803A
803C803E80408044806080648066806D8071807580818088808E809C809E80A6
80A780AB80B880B980C880CD80CF80D280D480D580D780D880E080ED80EE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
56
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000080F080F280F380F680F980FA80FE8103810B811681178118811C811E8120
81248127812C81308135813A813C81458147814A814C81528157816081618167
81688169816D816F817781818190818481858186818B818E81968198819B819E
81A281AE81B281B481BB81CB81C381C581CA81CE81CF81D581D781DB81DD81DE
81E181E481EB81EC81F081F181F281F581F681F881F981FD81FF82008203820F
821382148219821A821D82218222822882328234823A82438244824582460000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
57
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000824B824E824F82518256825C826082638267826D8274827B827D827F8280
82818283828482878289828A828E8291829482968298829A829B82A082A182A3
82A482A782A882A982AA82AE82B082B282B482B782BA82BC82BE82BF82C682D0
82D582DA82E082E282E482E882EA82ED82EF82F682F782FD82FE830083018307
8308830A830B8354831B831D831E831F83218322832C832D832E833083338337
833A833C833D8342834383448347834D834E8351835583568357837083780000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
58
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000837D837F8380838283848386838D83928394839583988399839B839C839D
83A683A783A983AC83BE83BF83C083C783C983CF83D083D183D483DD835383E8
83EA83F683F883F983FC84018406840A840F84118415841983AD842F84398445
84478448844A844D844F84518452845684588459845A845C8460846484658467
846A84708473847484768478847C847D84818485849284938495849E84A684A8
84A984AA84AF84B184B484BA84BD84BE84C084C284C784C884CC84CF84D30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000084DC84E784EA84EF84F084F184F284F7853284FA84FB84FD850285038507
850C850E8510851C851E85228523852485258527852A852B852F853385348536
853F8546854F855085518552855385568559855C855D855E855F856085618562
8564856B856F8579857A857B857D857F8581858585868589858B858C858F8593
8598859D859F85A085A285A585A785B485B685B785B885BC85BD85BE85BF85C2
85C785CA85CB85CE85AD85D885DA85DF85E085E685E885ED85F385F685FC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000085FF860086048605860D860E86108611861286188619861B861E86218627
862986368638863A863C863D864086428646865286538656865786588659865D
866086618662866386648669866C866F867586768677867A868D869186968698
869A869C86A186A686A786A886AD86B186B386B486B586B786B886B986BF86C0
86C186C386C586D186D286D586D786DA86DC86E086E386E586E7868886FA86FC
86FD870487058707870B870E870F8710871387148719871E871F872187230000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008728872E872F873187328739873A873C873D873E874087438745874D8758
875D876187648765876F87718772877B8783878487858786878787888789878B
878C879087938795879787988799879E87A087A387A787AC87AD87AE87B187B5
87BE87BF87C187C887C987CA87CE87D587D687D987DA87DC87DF87E287E387E4
87EA87EB87ED87F187F387F887FA87FF8801880388068809880A880B88108819
8812881388148818881A881B881C881E881F8828882D882E8830883288350000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000883A883C88418843884588488849884A884B884E8851885588568858885A
885C885F88608864886988718879887B88808898889A889B889C889F88A088A8
88AA88BA88BD88BE88C088CA88CB88CC88CD88CE88D188D288D388DB88DE88E7
88EF88F088F188F588F789018906890D890E890F8915891689188919891A891C
892089268927892889308931893289358939893A893E89408942894589468949
894F89528957895A895B895C896189628963896B896E897089738975897A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000897B897C897D8989898D899089948995899B899C899F89A089A589B089B4
89B589B689B789BC89D489D589D689D789D889E589E989EB89ED89F189F389F6
89F989FD89FF8A048A058A078A0F8A118A128A148A158A1E8A208A228A248A26
8A2B8A2C8A2F8A358A378A3D8A3E8A408A438A458A478A498A4D8A4E8A538A56
8A578A588A5C8A5D8A618A658A678A758A768A778A798A7A8A7B8A7E8A7F8A80
8A838A868A8B8A8F8A908A928A968A978A998A9F8AA78AA98AAE8AAF8AB30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008AB68AB78ABB8ABE8AC38AC68AC88AC98ACA8AD18AD38AD48AD58AD78ADD
8ADF8AEC8AF08AF48AF58AF68AFC8AFF8B058B068B0B8B118B1C8B1E8B1F8B0A
8B2D8B308B378B3C8B428B438B448B458B468B488B528B538B548B598B4D8B5E
8B638B6D8B768B788B798B7C8B7E8B818B848B858B8B8B8D8B8F8B948B958B9C
8B9E8B9F8C388C398C3D8C3E8C458C478C498C4B8C4F8C518C538C548C578C58
8C5B8C5D8C598C638C648C668C688C698C6D8C738C758C768C7B8C7E8C860000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008C878C8B8C908C928C938C998C9B8C9C8CA48CB98CBA8CC58CC68CC98CCB
8CCF8CD68CD58CD98CDD8CE18CE88CEC8CEF8CF08CF28CF58CF78CF88CFE8CFF
8D018D038D098D128D178D1B8D658D698D6C8D6E8D7F8D828D848D888D8D8D90
8D918D958D9E8D9F8DA08DA68DAB8DAC8DAF8DB28DB58DB78DB98DBB8DC08DC5
8DC68DC78DC88DCA8DCE8DD18DD48DD58DD78DD98DE48DE58DE78DEC8DF08DBC
8DF18DF28DF48DFD8E018E048E058E068E0B8E118E148E168E208E218E220000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
60
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008E238E268E278E318E338E368E378E388E398E3D8E408E418E4B8E4D8E4E
8E4F8E548E5B8E5C8E5D8E5E8E618E628E698E6C8E6D8E6F8E708E718E798E7A
8E7B8E828E838E898E908E928E958E9A8E9B8E9D8E9E8EA28EA78EA98EAD8EAE
8EB38EB58EBA8EBB8EC08EC18EC38EC48EC78ECF8ED18ED48EDC8EE88EEE8EF0
8EF18EF78EF98EFA8EED8F008F028F078F088F0F8F108F168F178F188F1E8F20
8F218F238F258F278F288F2C8F2D8F2E8F348F358F368F378F3A8F408F410000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
61
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008F438F478F4F8F518F528F538F548F558F588F5D8F5E8F658F9D8FA08FA1
8FA48FA58FA68FB58FB68FB88FBE8FC08FC18FC68FCA8FCB8FCD8FD08FD28FD3
8FD58FE08FE38FE48FE88FEE8FF18FF58FF68FFB8FFE900290049008900C9018
901B90289029902F902A902C902D903390349037903F90439044904C905B905D
906290669067906C90709074907990859088908B908C908E9090909590979098
9099909B90A090A190A290A590B090B290B390B490B690BD90CC90BE90C30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
62
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000090C490C590C790C890D590D790D890D990DC90DD90DF90E590D290F690EB
90EF90F090F490FE90FF91009104910591069108910D91109114911691179118
911A911C911E912091259122912391279129912E912F91319134913691379139
913A913C913D914391479148914F915391579159915A915B916191649167916D
91749179917A917B9181918391859186918A918E91919193919491959198919E
91A191A691A891AC91AD91AE91B091B191B291B391B691BB91BC91BD91BF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
63
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000091C291C391C591D391D491D791D991DA91DE91E491E591E991EA91EC91ED
91EE91EF91F091F191F791F991FB91FD9200920192049205920692079209920A
920C92109212921392169218921C921D92239224922592269228922E922F9230
92339235923692389239923A923C923E92409242924392469247924A924D924E
924F925192589259925C925D926092619265926792689269926E926F92709275
9276927792789279927B927C927D927F92889289928A928D928E929292970000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
64
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009299929F92A092A492A592A792A892AB92AF92B292B692B892BA92BB92BC
92BD92BF92C092C192C292C392C592C692C792C892CB92CC92CD92CE92D092D3
92D592D792D892D992DC92DD92DF92E092E192E392E592E792E892EC92EE92F0
92F992FB92FF930093029308930D931193149315931C931D931E931F93219324
932593279329932A933393349336933793479348934993509351935293559357
9358935A935E9364936593679369936A936D936F937093719373937493760000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
65
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000937A937D937F9380938193829388938A938B938D938F939293959398939B
939E93A193A393A493A693A893AB93B493B593B693BA93A993C193C493C593C6
93C793C993CA93CB93CC93CD93D393D993DC93DE93DF93E293E693E793F993F7
93F893FA93FB93FD94019402940494089409940D940E940F941594169417941F
942E942F9431943294339434943B943F943D944394459448944A944C94559459
945C945F946194639468946B946D946E946F9471947294849483957895790000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
66
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000957E95849588958C958D958E959D959E959F95A195A695A995AB95AC95B4
95B695BA95BD95BF95C695C895C995CB95D095D195D295D395D995DA95DD95DE
95DF95E095E495E6961D961E9622962496259626962C96319633963796389639
963A963C963D9641965296549656965796589661966E9674967B967C967E967F
9681968296839684968996919696969A969D969F96A496A596A696A996AE96AF
96B396BA96CA96D25DB296D896DA96DD96DE96DF96E996EF96F196FA97020000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
67
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000970397059709971A971B971D97219722972397289731973397419743974A
974E974F975597579758975A975B97639767976A976E9773977697779778977B
977D977F978097899795979697979799979A979E979F97A297AC97AE97B197B2
97B597B697B897B997BA97BC97BE97BF97C197C497C597C797C997CA97CC97CD
97CE97D097D197D497D797D897D997DD97DE97E097DB97E197E497EF97F197F4
97F797F897FA9807980A9819980D980E98149816981C981E9820982398260000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
68
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000982B982E982F98309832983398359825983E98449847984A985198529853
985698579859985A9862986398659866986A986C98AB98AD98AE98B098B498B7
98B898BA98BB98BF98C298C598C898CC98E198E398E598E698E798EA98F398F6
9902990799089911991599169917991A991B991C991F992299269927992B9931
99329933993499359939993A993B993C99409941994699479948994D994E9954
99589959995B995C995E995F9960999B999D999F99A699B099B199B299B50000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
69
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000099B999BA99BD99BF99C399C999D399D499D999DA99DC99DE99E799EA99EB
99EC99F099F499F599F999FD99FE9A029A039A049A0B9A0C9A109A119A169A1E
9A209A229A239A249A279A2D9A2E9A339A359A369A389A479A419A449A4A9A4B
9A4C9A4E9A519A549A569A5D9AAA9AAC9AAE9AAF9AB29AB49AB59AB69AB99ABB
9ABE9ABF9AC19AC39AC69AC89ACE9AD09AD29AD59AD69AD79ADB9ADC9AE09AE4
9AE59AE79AE99AEC9AF29AF39AF59AF99AFA9AFD9AFF9B009B019B029B030000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009B049B059B089B099B0B9B0C9B0D9B0E9B109B129B169B199B1B9B1C9B20
9B269B2B9B2D9B339B349B359B379B399B3A9B3D9B489B4B9B4C9B559B569B57
9B5B9B5E9B619B639B659B669B689B6A9B6B9B6C9B6D9B6E9B739B759B779B78
9B799B7F9B809B849B859B869B879B899B8A9B8B9B8D9B8F9B909B949B9A9B9D
9B9E9BA69BA79BA99BAC9BB09BB19BB29BB79BB89BBB9BBC9BBE9BBF9BC19BC7
9BC89BCE9BD09BD79BD89BDD9BDF9BE59BE79BEA9BEB9BEF9BF39BF79BF80000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009BF99BFA9BFD9BFF9C009C029C0B9C0F9C119C169C189C199C1A9C1C9C1E
9C229C239C269C279C289C299C2A9C319C359C369C379C3D9C419C439C449C45
9C499C4A9C4E9C4F9C509C539C549C569C589C5B9C5D9C5E9C5F9C639C699C6A
9C5C9C6B9C689C6E9C709C729C759C779C7B9CE69CF29CF79CF99D0B9D029D11
9D179D189D1C9D1D9D1E9D2F9D309D329D339D349D3A9D3C9D459D3D9D429D43
9D479D4A9D539D549D5F9D639D629D659D699D6A9D6B9D709D769D779D7B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009D7C9D7E9D839D849D869D8A9D8D9D8E9D929D939D959D969D979D989DA1
9DAA9DAC9DAE9DB19DB59DB99DBC9DBF9DC39DC79DC99DCA9DD49DD59DD69DD7
9DDA9DDE9DDF9DE09DE59DE79DE99DEB9DEE9DF09DF39DF49DFE9E0A9E029E07
9E0E9E109E119E129E159E169E199E1C9E1D9E7A9E7B9E7C9E809E829E839E84
9E859E879E8E9E8F9E969E989E9B9E9E9EA49EA89EAC9EAE9EAF9EB09EB39EB4
9EB59EC69EC89ECB9ED59EDF9EE49EE79EEC9EED9EEE9EF09EF19EF29EF50000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009EF89EFF9F029F039F099F0F9F109F119F129F149F169F179F199F1A9F1B
9F1F9F229F269F2A9F2B9F2F9F319F329F349F379F399F3A9F3C9F3D9F3F9F41
9F439F449F459F469F479F539F559F569F579F589F5A9F5D9F5E9F689F699F6D
9F6E9F6F9F709F719F739F759F7A9F7D9F8F9F909F919F929F949F969F979F9E
9FA19FA29FA39FA5000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/ksc5601.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
# Encoding file: ksc5601, double-byte
D
233F 0 89
21
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030003001300200B72025202600A8300300AD20152225FF3C223C20182019
201C201D3014301530083009300A300B300C300D300E300F3010301100B100D7
00F7226022642265221E223400B0203220332103212BFFE0FFE1FFE526422640
222022A52312220222072261225200A7203B2606260525CB25CF25CE25C725C6
25A125A025B325B225BD25BC219221902191219321943013226A226B221A223D
221D2235222B222C2208220B2286228722822283222A222922272228FFE20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
22
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000021D221D42200220300B4FF5E02C702D802DD02DA02D900B802DB00A100BF
02D0222E2211220F00A42109203025C125C025B725B626642660266126652667
2663229925C825A325D025D1259225A425A525A825A725A625A92668260F260E
261C261E00B62020202121952197219921962198266D2669266A266C327F321C
211633C7212233C233D821210000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
23
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF01FF02FF03FF04FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFFE6FF3DFF3EFF3F
FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
24
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000313131323133313431353136313731383139313A313B313C313D313E313F
3140314131423143314431453146314731483149314A314B314C314D314E314F
3150315131523153315431553156315731583159315A315B315C315D315E315F
3160316131623163316431653166316731683169316A316B316C316D316E316F
3170317131723173317431753176317731783179317A317B317C317D317E317F
3180318131823183318431853186318731883189318A318B318C318D318E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
25
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000217021712172217321742175217621772178217900000000000000000000
2160216121622163216421652166216721682169000000000000000000000000
0000039103920393039403950396039703980399039A039B039C039D039E039F
03A003A103A303A403A503A603A703A803A90000000000000000000000000000
000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C303C403C503C603C703C803C90000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
26
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000025002502250C251025182514251C252C25242534253C25012503250F2513
251B251725232533252B253B254B2520252F25282537253F251D253025252538
254225122511251A251925162515250E250D251E251F25212522252625272529
252A252D252E25312532253525362539253A253D253E25402541254325442545
2546254725482549254A00000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
27
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00003395339633972113339833C433A333A433A533A63399339A339B339C339D
339E339F33A033A133A233CA338D338E338F33CF3388338933C833A733A833B0
33B133B233B333B433B533B633B733B833B93380338133823383338433BA33BB
33BC33BD33BE33BF33903391339233933394212633C033C1338A338B338C33D6
33C533AD33AE33AF33DB33A933AA33AB33AC33DD33D033D333C333C933DC33C6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
28
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000C600D000AA0126000001320000013F014100D8015200BA00DE0166014A
00003260326132623263326432653266326732683269326A326B326C326D326E
326F3270327132723273327432753276327732783279327A327B24D024D124D2
24D324D424D524D624D724D824D924DA24DB24DC24DD24DE24DF24E024E124E2
24E324E424E524E624E724E824E9246024612462246324642465246624672468
2469246A246B246C246D246E00BD2153215400BC00BE215B215C215D215E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
29
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000E6011100F001270131013301380140014200F8015300DF00FE0167014B
01493200320132023203320432053206320732083209320A320B320C320D320E
320F3210321132123213321432153216321732183219321A321B249C249D249E
249F24A024A124A224A324A424A524A624A724A824A924AA24AB24AC24AD24AE
24AF24B024B124B224B324B424B5247424752476247724782479247A247B247C
247D247E247F24802481248200B900B200B32074207F20812082208320840000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
2A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000304130423043304430453046304730483049304A304B304C304D304E304F
3050305130523053305430553056305730583059305A305B305C305D305E305F
3060306130623063306430653066306730683069306A306B306C306D306E306F
3070307130723073307430753076307730783079307A307B307C307D307E307F
3080308130823083308430853086308730883089308A308B308C308D308E308F
3090309130923093000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
2B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
2C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000004100411041204130414041504010416041704180419041A041B041C041D
041E041F0420042104220423042404250426042704280429042A042B042C042D
042E042F00000000000000000000000000000000000000000000000000000000
000004300431043204330434043504510436043704380439043A043B043C043D
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
30
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000AC00AC01AC04AC07AC08AC09AC0AAC10AC11AC12AC13AC14AC15AC16AC17
AC19AC1AAC1BAC1CAC1DAC20AC24AC2CAC2DAC2FAC30AC31AC38AC39AC3CAC40
AC4BAC4DAC54AC58AC5CAC70AC71AC74AC77AC78AC7AAC80AC81AC83AC84AC85
AC86AC89AC8AAC8BAC8CAC90AC94AC9CAC9DAC9FACA0ACA1ACA8ACA9ACAAACAC
ACAFACB0ACB8ACB9ACBBACBCACBDACC1ACC4ACC8ACCCACD5ACD7ACE0ACE1ACE4
ACE7ACE8ACEAACECACEFACF0ACF1ACF3ACF5ACF6ACFCACFDAD00AD04AD060000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
31
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000AD0CAD0DAD0FAD11AD18AD1CAD20AD29AD2CAD2DAD34AD35AD38AD3CAD44
AD45AD47AD49AD50AD54AD58AD61AD63AD6CAD6DAD70AD73AD74AD75AD76AD7B
AD7CAD7DAD7FAD81AD82AD88AD89AD8CAD90AD9CAD9DADA4ADB7ADC0ADC1ADC4
ADC8ADD0ADD1ADD3ADDCADE0ADE4ADF8ADF9ADFCADFFAE00AE01AE08AE09AE0B
AE0DAE14AE30AE31AE34AE37AE38AE3AAE40AE41AE43AE45AE46AE4AAE4CAE4D
AE4EAE50AE54AE56AE5CAE5DAE5FAE60AE61AE65AE68AE69AE6CAE70AE780000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
32
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000AE79AE7BAE7CAE7DAE84AE85AE8CAEBCAEBDAEBEAEC0AEC4AECCAECDAECF
AED0AED1AED8AED9AEDCAEE8AEEBAEEDAEF4AEF8AEFCAF07AF08AF0DAF10AF2C
AF2DAF30AF32AF34AF3CAF3DAF3FAF41AF42AF43AF48AF49AF50AF5CAF5DAF64
AF65AF79AF80AF84AF88AF90AF91AF95AF9CAFB8AFB9AFBCAFC0AFC7AFC8AFC9
AFCBAFCDAFCEAFD4AFDCAFE8AFE9AFF0AFF1AFF4AFF8B000B001B004B00CB010
B014B01CB01DB028B044B045B048B04AB04CB04EB053B054B055B057B0590000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
33
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B05DB07CB07DB080B084B08CB08DB08FB091B098B099B09AB09CB09FB0A0
B0A1B0A2B0A8B0A9B0ABB0ACB0ADB0AEB0AFB0B1B0B3B0B4B0B5B0B8B0BCB0C4
B0C5B0C7B0C8B0C9B0D0B0D1B0D4B0D8B0E0B0E5B108B109B10BB10CB110B112
B113B118B119B11BB11CB11DB123B124B125B128B12CB134B135B137B138B139
B140B141B144B148B150B151B154B155B158B15CB160B178B179B17CB180B182
B188B189B18BB18DB192B193B194B198B19CB1A8B1CCB1D0B1D4B1DCB1DD0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
34
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B1DFB1E8B1E9B1ECB1F0B1F9B1FBB1FDB204B205B208B20BB20CB214B215
B217B219B220B234B23CB258B25CB260B268B269B274B275B27CB284B285B289
B290B291B294B298B299B29AB2A0B2A1B2A3B2A5B2A6B2AAB2ACB2B0B2B4B2C8
B2C9B2CCB2D0B2D2B2D8B2D9B2DBB2DDB2E2B2E4B2E5B2E6B2E8B2EBB2ECB2ED
B2EEB2EFB2F3B2F4B2F5B2F7B2F8B2F9B2FAB2FBB2FFB300B301B304B308B310
B311B313B314B315B31CB354B355B356B358B35BB35CB35EB35FB364B3650000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
35
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B367B369B36BB36EB370B371B374B378B380B381B383B384B385B38CB390
B394B3A0B3A1B3A8B3ACB3C4B3C5B3C8B3CBB3CCB3CEB3D0B3D4B3D5B3D7B3D9
B3DBB3DDB3E0B3E4B3E8B3FCB410B418B41CB420B428B429B42BB434B450B451
B454B458B460B461B463B465B46CB480B488B49DB4A4B4A8B4ACB4B5B4B7B4B9
B4C0B4C4B4C8B4D0B4D5B4DCB4DDB4E0B4E3B4E4B4E6B4ECB4EDB4EFB4F1B4F8
B514B515B518B51BB51CB524B525B527B528B529B52AB530B531B534B5380000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
36
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B540B541B543B544B545B54BB54CB54DB550B554B55CB55DB55FB560B561
B5A0B5A1B5A4B5A8B5AAB5ABB5B0B5B1B5B3B5B4B5B5B5BBB5BCB5BDB5C0B5C4
B5CCB5CDB5CFB5D0B5D1B5D8B5ECB610B611B614B618B625B62CB634B648B664
B668B69CB69DB6A0B6A4B6ABB6ACB6B1B6D4B6F0B6F4B6F8B700B701B705B728
B729B72CB72FB730B738B739B73BB744B748B74CB754B755B760B764B768B770
B771B773B775B77CB77DB780B784B78CB78DB78FB790B791B792B796B7970000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
37
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B798B799B79CB7A0B7A8B7A9B7ABB7ACB7ADB7B4B7B5B7B8B7C7B7C9B7EC
B7EDB7F0B7F4B7FCB7FDB7FFB800B801B807B808B809B80CB810B818B819B81B
B81DB824B825B828B82CB834B835B837B838B839B840B844B851B853B85CB85D
B860B864B86CB86DB86FB871B878B87CB88DB8A8B8B0B8B4B8B8B8C0B8C1B8C3
B8C5B8CCB8D0B8D4B8DDB8DFB8E1B8E8B8E9B8ECB8F0B8F8B8F9B8FBB8FDB904
B918B920B93CB93DB940B944B94CB94FB951B958B959B95CB960B968B9690000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
38
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000B96BB96DB974B975B978B97CB984B985B987B989B98AB98DB98EB9ACB9AD
B9B0B9B4B9BCB9BDB9BFB9C1B9C8B9C9B9CCB9CEB9CFB9D0B9D1B9D2B9D8B9D9
B9DBB9DDB9DEB9E1B9E3B9E4B9E5B9E8B9ECB9F4B9F5B9F7B9F8B9F9B9FABA00
BA01BA08BA15BA38BA39BA3CBA40BA42BA48BA49BA4BBA4DBA4EBA53BA54BA55
BA58BA5CBA64BA65BA67BA68BA69BA70BA71BA74BA78BA83BA84BA85BA87BA8C
BAA8BAA9BAABBAACBAB0BAB2BAB8BAB9BABBBABDBAC4BAC8BAD8BAD9BAFC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
39
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BB00BB04BB0DBB0FBB11BB18BB1CBB20BB29BB2BBB34BB35BB36BB38BB3B
BB3CBB3DBB3EBB44BB45BB47BB49BB4DBB4FBB50BB54BB58BB61BB63BB6CBB88
BB8CBB90BBA4BBA8BBACBBB4BBB7BBC0BBC4BBC8BBD0BBD3BBF8BBF9BBFCBBFF
BC00BC02BC08BC09BC0BBC0CBC0DBC0FBC11BC14BC15BC16BC17BC18BC1BBC1C
BC1DBC1EBC1FBC24BC25BC27BC29BC2DBC30BC31BC34BC38BC40BC41BC43BC44
BC45BC49BC4CBC4DBC50BC5DBC84BC85BC88BC8BBC8CBC8EBC94BC95BC970000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BC99BC9ABCA0BCA1BCA4BCA7BCA8BCB0BCB1BCB3BCB4BCB5BCBCBCBDBCC0
BCC4BCCDBCCFBCD0BCD1BCD5BCD8BCDCBCF4BCF5BCF6BCF8BCFCBD04BD05BD07
BD09BD10BD14BD24BD2CBD40BD48BD49BD4CBD50BD58BD59BD64BD68BD80BD81
BD84BD87BD88BD89BD8ABD90BD91BD93BD95BD99BD9ABD9CBDA4BDB0BDB8BDD4
BDD5BDD8BDDCBDE9BDF0BDF4BDF8BE00BE03BE05BE0CBE0DBE10BE14BE1CBE1D
BE1FBE44BE45BE48BE4CBE4EBE54BE55BE57BE59BE5ABE5BBE60BE61BE640000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000BE68BE6ABE70BE71BE73BE74BE75BE7BBE7CBE7DBE80BE84BE8CBE8DBE8F
BE90BE91BE98BE99BEA8BED0BED1BED4BED7BED8BEE0BEE3BEE4BEE5BEECBF01
BF08BF09BF18BF19BF1BBF1CBF1DBF40BF41BF44BF48BF50BF51BF55BF94BFB0
BFC5BFCCBFCDBFD0BFD4BFDCBFDFBFE1C03CC051C058C05CC060C068C069C090
C091C094C098C0A0C0A1C0A3C0A5C0ACC0ADC0AFC0B0C0B3C0B4C0B5C0B6C0BC
C0BDC0BFC0C0C0C1C0C5C0C8C0C9C0CCC0D0C0D8C0D9C0DBC0DCC0DDC0E40000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C0E5C0E8C0ECC0F4C0F5C0F7C0F9C100C104C108C110C115C11CC11DC11E
C11FC120C123C124C126C127C12CC12DC12FC130C131C136C138C139C13CC140
C148C149C14BC14CC14DC154C155C158C15CC164C165C167C168C169C170C174
C178C185C18CC18DC18EC190C194C196C19CC19DC19FC1A1C1A5C1A8C1A9C1AC
C1B0C1BDC1C4C1C8C1CCC1D4C1D7C1D8C1E0C1E4C1E8C1F0C1F1C1F3C1FCC1FD
C200C204C20CC20DC20FC211C218C219C21CC21FC220C228C229C22BC22D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C22FC231C232C234C248C250C251C254C258C260C265C26CC26DC270C274
C27CC27DC27FC281C288C289C290C298C29BC29DC2A4C2A5C2A8C2ACC2ADC2B4
C2B5C2B7C2B9C2DCC2DDC2E0C2E3C2E4C2EBC2ECC2EDC2EFC2F1C2F6C2F8C2F9
C2FBC2FCC300C308C309C30CC30DC313C314C315C318C31CC324C325C328C329
C345C368C369C36CC370C372C378C379C37CC37DC384C388C38CC3C0C3D8C3D9
C3DCC3DFC3E0C3E2C3E8C3E9C3EDC3F4C3F5C3F8C408C410C424C42CC4300000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C434C43CC43DC448C464C465C468C46CC474C475C479C480C494C49CC4B8
C4BCC4E9C4F0C4F1C4F4C4F8C4FAC4FFC500C501C50CC510C514C51CC528C529
C52CC530C538C539C53BC53DC544C545C548C549C54AC54CC54DC54EC553C554
C555C557C558C559C55DC55EC560C561C564C568C570C571C573C574C575C57C
C57DC580C584C587C58CC58DC58FC591C595C597C598C59CC5A0C5A9C5B4C5B5
C5B8C5B9C5BBC5BCC5BDC5BEC5C4C5C5C5C6C5C7C5C8C5C9C5CAC5CCC5CE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C5D0C5D1C5D4C5D8C5E0C5E1C5E3C5E5C5ECC5EDC5EEC5F0C5F4C5F6C5F7
C5FCC5FDC5FEC5FFC600C601C605C606C607C608C60CC610C618C619C61BC61C
C624C625C628C62CC62DC62EC630C633C634C635C637C639C63BC640C641C644
C648C650C651C653C654C655C65CC65DC660C66CC66FC671C678C679C67CC680
C688C689C68BC68DC694C695C698C69CC6A4C6A5C6A7C6A9C6B0C6B1C6B4C6B8
C6B9C6BAC6C0C6C1C6C3C6C5C6CCC6CDC6D0C6D4C6DCC6DDC6E0C6E1C6E80000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
40
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C6E9C6ECC6F0C6F8C6F9C6FDC704C705C708C70CC714C715C717C719C720
C721C724C728C730C731C733C735C737C73CC73DC740C744C74AC74CC74DC74F
C751C752C753C754C755C756C757C758C75CC760C768C76BC774C775C778C77C
C77DC77EC783C784C785C787C788C789C78AC78EC790C791C794C796C797C798
C79AC7A0C7A1C7A3C7A4C7A5C7A6C7ACC7ADC7B0C7B4C7BCC7BDC7BFC7C0C7C1
C7C8C7C9C7CCC7CEC7D0C7D8C7DDC7E4C7E8C7ECC800C801C804C808C80A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
41
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C810C811C813C815C816C81CC81DC820C824C82CC82DC82FC831C838C83C
C840C848C849C84CC84DC854C870C871C874C878C87AC880C881C883C885C886
C887C88BC88CC88DC894C89DC89FC8A1C8A8C8BCC8BDC8C4C8C8C8CCC8D4C8D5
C8D7C8D9C8E0C8E1C8E4C8F5C8FCC8FDC900C904C905C906C90CC90DC90FC911
C918C92CC934C950C951C954C958C960C961C963C96CC970C974C97CC988C989
C98CC990C998C999C99BC99DC9C0C9C1C9C4C9C7C9C8C9CAC9D0C9D1C9D30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
42
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000C9D5C9D6C9D9C9DAC9DCC9DDC9E0C9E2C9E4C9E7C9ECC9EDC9EFC9F0C9F1
C9F8C9F9C9FCCA00CA08CA09CA0BCA0CCA0DCA14CA18CA29CA4CCA4DCA50CA54
CA5CCA5DCA5FCA60CA61CA68CA7DCA84CA98CABCCABDCAC0CAC4CACCCACDCACF
CAD1CAD3CAD8CAD9CAE0CAECCAF4CB08CB10CB14CB18CB20CB21CB41CB48CB49
CB4CCB50CB58CB59CB5DCB64CB78CB79CB9CCBB8CBD4CBE4CBE7CBE9CC0CCC0D
CC10CC14CC1CCC1DCC21CC22CC27CC28CC29CC2CCC2ECC30CC38CC39CC3B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
43
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CC3CCC3DCC3ECC44CC45CC48CC4CCC54CC55CC57CC58CC59CC60CC64CC66
CC68CC70CC75CC98CC99CC9CCCA0CCA8CCA9CCABCCACCCADCCB4CCB5CCB8CCBC
CCC4CCC5CCC7CCC9CCD0CCD4CCE4CCECCCF0CD01CD08CD09CD0CCD10CD18CD19
CD1BCD1DCD24CD28CD2CCD39CD5CCD60CD64CD6CCD6DCD6FCD71CD78CD88CD94
CD95CD98CD9CCDA4CDA5CDA7CDA9CDB0CDC4CDCCCDD0CDE8CDECCDF0CDF8CDF9
CDFBCDFDCE04CE08CE0CCE14CE19CE20CE21CE24CE28CE30CE31CE33CE350000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
44
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000CE58CE59CE5CCE5FCE60CE61CE68CE69CE6BCE6DCE74CE75CE78CE7CCE84
CE85CE87CE89CE90CE91CE94CE98CEA0CEA1CEA3CEA4CEA5CEACCEADCEC1CEE4
CEE5CEE8CEEBCEECCEF4CEF5CEF7CEF8CEF9CF00CF01CF04CF08CF10CF11CF13
CF15CF1CCF20CF24CF2CCF2DCF2FCF30CF31CF38CF54CF55CF58CF5CCF64CF65
CF67CF69CF70CF71CF74CF78CF80CF85CF8CCFA1CFA8CFB0CFC4CFE0CFE1CFE4
CFE8CFF0CFF1CFF3CFF5CFFCD000D004D011D018D02DD034D035D038D03C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
45
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D044D045D047D049D050D054D058D060D06CD06DD070D074D07CD07DD081
D0A4D0A5D0A8D0ACD0B4D0B5D0B7D0B9D0C0D0C1D0C4D0C8D0C9D0D0D0D1D0D3
D0D4D0D5D0DCD0DDD0E0D0E4D0ECD0EDD0EFD0F0D0F1D0F8D10DD130D131D134
D138D13AD140D141D143D144D145D14CD14DD150D154D15CD15DD15FD161D168
D16CD17CD184D188D1A0D1A1D1A4D1A8D1B0D1B1D1B3D1B5D1BAD1BCD1C0D1D8
D1F4D1F8D207D209D210D22CD22DD230D234D23CD23DD23FD241D248D25C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
46
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D264D280D281D284D288D290D291D295D29CD2A0D2A4D2ACD2B1D2B8D2B9
D2BCD2BFD2C0D2C2D2C8D2C9D2CBD2D4D2D8D2DCD2E4D2E5D2F0D2F1D2F4D2F8
D300D301D303D305D30CD30DD30ED310D314D316D31CD31DD31FD320D321D325
D328D329D32CD330D338D339D33BD33CD33DD344D345D37CD37DD380D384D38C
D38DD38FD390D391D398D399D39CD3A0D3A8D3A9D3ABD3ADD3B4D3B8D3BCD3C4
D3C5D3C8D3C9D3D0D3D8D3E1D3E3D3ECD3EDD3F0D3F4D3FCD3FDD3FFD4010000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
47
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D408D41DD440D444D45CD460D464D46DD46FD478D479D47CD47FD480D482
D488D489D48BD48DD494D4A9D4CCD4D0D4D4D4DCD4DFD4E8D4ECD4F0D4F8D4FB
D4FDD504D508D50CD514D515D517D53CD53DD540D544D54CD54DD54FD551D558
D559D55CD560D565D568D569D56BD56DD574D575D578D57CD584D585D587D588
D589D590D5A5D5C8D5C9D5CCD5D0D5D2D5D8D5D9D5DBD5DDD5E4D5E5D5E8D5EC
D5F4D5F5D5F7D5F9D600D601D604D608D610D611D613D614D615D61CD6200000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
48
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D624D62DD638D639D63CD640D645D648D649D64BD64DD651D654D655D658
D65CD667D669D670D671D674D683D685D68CD68DD690D694D69DD69FD6A1D6A8
D6ACD6B0D6B9D6BBD6C4D6C5D6C8D6CCD6D1D6D4D6D7D6D9D6E0D6E4D6E8D6F0
D6F5D6FCD6FDD700D704D711D718D719D71CD720D728D729D72BD72DD734D735
D738D73CD744D747D749D750D751D754D756D757D758D759D760D761D763D765
D769D76CD770D774D77CD77DD781D788D789D78CD790D798D799D79BD79D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004F3D4F73504750F952A053EF547554E556095AC15BB6668767B667B767EF
6B4C73C275C27A3C82DB8304885788888A368CC88DCF8EFB8FE699D5523B5374
5404606A61646BBC73CF811A89BA89D295A34F83520A58BE597859E65E725E79
61C763C0674667EC687F6F97764E770B78F57A087AFF7C21809D826E82718AEB
95934E6B559D66F76E3478A37AED845B8910874E97A852D8574E582A5D4C611F
61BE6221656267D16A446E1B751875B376E377B07D3A90AF945194529F950000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000053235CAC753280DB92409598525B580859DC5CA15D175EB75F3A5F4A6177
6C5F757A75867CE07D737DB17F8C81548221859189418B1B92FC964D9C474ECB
4EF7500B51F1584F6137613E6168653969EA6F1175A5768676D67B8782A584CB
F90093A7958B55805BA25751F9017CB37FB991B5502853BB5C455DE862D2636E
64DA64E76E2070AC795B8DDD8E1EF902907D924592F84E7E4EF650655DFE5EFA
61066957817186548E4793759A2B4E5E5091677068405109528D52926AA20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000077BC92109ED452AB602F8FF2504861A963ED64CA683C6A846FC0818889A1
96945805727D72AC75047D797E6D80A9898B8B7490639D5162896C7A6F547D50
7F3A8A23517C614A7B9D8B199257938C4EAC4FD3501E50BE510652C152CD537F
577058835E9A5F91617661AC64CE656C666F66BB66F468976D87708570F1749F
74A574CA75D9786C78EC7ADF7AF67D457D938015803F811B83968B668F159015
93E1980398389A5A9BE84FC25553583A59515B635C4660B86212684268B00000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000068E86EAA754C767878CE7A3D7CFB7E6B7E7C8A088AA18C3F968E9DC453E4
53E9544A547156FA59D15B645C3B5EAB62F765376545657266A067AF69C16CBD
75FC7690777E7A3F7F94800380A1818F82E682FD83F085C1883188B48AA5F903
8F9C932E96C798679AD89F1354ED659B66F2688F7A408C379D6056F057645D11
660668B168CD6EFE7428889E9BE46C68F9049AA84F9B516C5171529F5B545DE5
6050606D62F163A7653B73D97A7A86A38CA2978F4E325BE16208679C74DC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000079D183D38A878AB28DE8904E934B98465ED369E885FF90EDF90551A05B98
5BEC616368FA6B3E704C742F74D87BA17F5083C589C08CAB95DC9928522E605D
62EC90024F8A5149532158D95EE366E06D38709A72C273D67B5080F1945B5366
639B7F6B4E565080584A58DE602A612762D069D09B415B8F7D1880B18F5F4EA4
50D154AC55AC5B0C5DA05DE7652A654E68216A4B72E1768E77EF7D5E7FF981A0
854E86DF8F038F4E90CA99039A559BAB4E184E454E5D4EC74FF1517752FE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
4F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000534053E353E5548E5614577557A25BC75D875ED061FC62D8655167B867E9
69CB6B506BC66BEC6C426E9D707872D77396740377BF77E97A767D7F800981FC
8205820A82DF88628B338CFC8EC0901190B1926492B699D29A459CE99DD79F9C
570B5C4083CA97A097AB9EB4541B7A987FA488D98ECD90E158005C4863987A9F
5BAE5F137A797AAE828E8EAC5026523852F85377570862F363726B0A6DC37737
53A5735785688E7695D5673A6AC36F708A6D8ECC994BF90666776B788CB40000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
50
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00009B3CF90753EB572D594E63C669FB73EA78457ABA7AC57CFE8475898F8D73
903595A852FB574775477B6083CC921EF9086A58514B524B5287621F68D86975
969950C552A452E461C365A4683969FF747E7B4B82B983EB89B28B398FD19949
F9094ECA599764D266116A8E7434798179BD82A9887E887F895FF90A93264F0B
53CA602562716C727D1A7D664E98516277DC80AF4F014F0E5176518055DC5668
573B57FA57FC5914594759935BC45C905D0E5DF15E7E5FCC628065D765E30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
51
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000671E671F675E68CB68C46A5F6B3A6C236C7D6C826DC773987426742A7482
74A37578757F788178EF794179477948797A7B957D007DBA7F888006802D808C
8A188B4F8C488D779321932498E299519A0E9A0F9A659E927DCA4F76540962EE
685491D155AB513AF90BF90C5A1C61E6F90D62CF62FFF90EF90FF910F911F912
F91390A3F914F915F916F917F9188AFEF919F91AF91BF91C6696F91D7156F91E
F91F96E3F920634F637A5357F921678F69606E73F9227537F923F924F9250000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
52
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007D0DF926F927887256CA5A18F928F929F92AF92BF92C4E43F92D51675948
67F08010F92E59735E74649A79CA5FF5606C62C8637B5BE75BD752AAF92F5974
5F296012F930F931F9327459F933F934F935F936F937F93899D1F939F93AF93B
F93CF93DF93EF93FF940F941F942F9436FC3F944F94581BF8FB260F1F946F947
8166F948F9495C3FF94AF94BF94CF94DF94EF94FF950F9515AE98A25677B7D10
F952F953F954F955F956F95780FDF958F9595C3C6CE5533F6EBA591A83360000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
53
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00004E394EB64F4655AE571858C75F5665B765E66A806BB56E4D77ED7AEF7C1E
7DDE86CB88929132935B64BB6FBE737A75B890545556574D61BA64D466C76DE1
6E5B6F6D6FB975F0804381BD854189838AC78B5A931F6C9375537B548E0F905D
5510580258585E626207649E68E075767CD687B39EE84EE35788576E59275C0D
5CB15E365F85623464E173B381FA888B8CB8968A9EDB5B855FB760B350125200
52305716583558575C0E5C605CF65D8B5EA65F9260BC63116389641768430000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000068F96AC26DD86E216ED46FE471FE76DC777979B17A3B840489A98CED8DF3
8E4890039014905390FD934D967697DC6BD27006725872A27368776379BF7BE4
7E9B8B8058A960C7656665FD66BE6C8C711E71C98C5A98134E6D7A814EDD51AC
51CD52D5540C61A76771685068DF6D1E6F7C75BC77B37AE580F484639285515C
6597675C679375D87AC78373F95A8C469017982D5C6F81C0829A9041906F920D
5F975D9D6A5971C8767B7B4985E48B0491279A30558761F6F95B76697F850000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
55
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000863F87BA88F8908FF95C6D1B70D973DE7D61843DF95D916A99F1F95E4E82
53756B046B12703E721B862D9E1E524C8FA35D5064E5652C6B166FEB7C437E9C
85CD896489BD62C981D8881F5ECA67176D6A72FC7405746F878290DE4F865D0D
5FA0840A51B763A075654EAE5006516951C968816A117CAE7CB17CE7826F8AD2
8F1B91CF4FB6513752F554425EEC616E623E65C56ADA6FFE792A85DC882395AD
9A629A6A9E979ECE529B66C66B77701D792B8F6297426190620065236F230000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
56
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000714974897DF4806F84EE8F269023934A51BD521752A36D0C70C888C25EC9
65826BAE6FC27C3E73754EE44F3656F9F95F5CBA5DBA601C73B27B2D7F9A7FCE
8046901E923496F6974898189F614F8B6FA779AE91B496B752DEF960648864C4
6AD36F5E7018721076E780018606865C8DEF8F0597329B6F9DFA9E75788C797F
7DA083C993049E7F9E938AD658DF5F046727702774CF7C60807E512170287262
78CA8CC28CDA8CF496F74E8650DA5BEE5ED6659971CE764277AD804A84FC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
57
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000907C9B279F8D58D85A415C626A136DDA6F0F763B7D2F7E37851E893893E4
964B528965D267F369B46D416E9C700F7409746075597624786B8B2C985E516D
622E96784F96502B5D196DEA7DB88F2A5F8B61446817F961968652D2808B51DC
51CC695E7A1C7DBE83F196754FDA52295398540F550E5C6560A7674E68A86D6C
728172F874067483F96275E27C6C7F797FB8838988CF88E191CC91D096E29BC9
541D6F7E71D0749885FA8EAA96A39C579E9F67976DCB743381E89716782C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
58
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007ACB7B207C926469746A75F278BC78E899AC9B549EBB5BDE5E556F20819C
83AB90884E07534D5A295DD25F4E6162633D666966FC6EFF6F2B7063779E842C
8513883B8F1399459C3B551C62B9672B6CAB8309896A977A4EA159845FD85FD9
671B7DB27F548292832B83BD8F1E909957CB59B95A925BD06627679A68856BCF
71647F758CB78CE390819B4581088C8A964C9A409EA55B5F6C13731B76F276DF
840C51AA8993514D519552C968C96C94770477207DBF7DEC97629EB56EC50000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000851151A5540D547D660E669D69276E9F76BF7791831784C2879F91699298
9CF488824FAE519252DF59C65E3D61556478647966AE67D06A216BCD6BDB725F
72617441773877DB801782BC83058B008B288C8C67286C90726776EE77667A46
9DA96B7F6C92592267268499536F589359995EDF63CF663467736E3A732B7AD7
82D7932852D95DEB61AE61CB620A62C764AB65E069596B666BCB712173F7755D
7E46821E8302856A8AA38CBF97279D6158A89ED85011520E543B554F65870000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006C767D0A7D0B805E868A958096EF52FF6C95726954735A9A5C3E5D4B5F4C
5FAE672A68B669636E3C6E4477097C737F8E85878B0E8FF797619EF45CB760B6
610D61AB654F65FB65FC6C116CEF739F73C97DE195945BC6871C8B10525D535A
62CD640F64B267346A386CCA73C0749E7B947C957E1B818A823685848FEB96F9
99C14F34534A53CD53DB62CC642C6500659169C36CEE6F5873ED7554762276E4
76FC78D078FB792C7D46822C87E08FD4981298EF52C362D464A56E246F510000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000767C8DCB91B192629AEE9B435023508D574A59A85C285E475F77623F653E
65B965C16609678B699C6EC278C57D2180AA8180822B82B384A1868C8A2A8B17
90A696329F90500D4FF3F96357F95F9862DC6392676F6E43711976C380CC80DA
88F488F589198CE08F29914D966A4F2F4F705E1B67CF6822767D767E9B445E61
6A0A716971D4756AF9647E41854385E998DC4F107B4F7F7095A551E15E0668B5
6C3E6C4E6CDB72AF7BC483036CD5743A50FB528858C164D86A9774A776560000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000078A7861795E29739F965535E5F018B8A8FA88FAF908A522577A59C499F08
4E19500251755C5B5E77661E663A67C468C570B3750175C579C97ADD8F279920
9A084FDD582158315BF6666E6B656D116E7A6F7D73E4752B83E988DC89138B5C
8F144F0F50D55310535C5B935FA9670D798F8179832F8514890789868F398F3B
99A59C12672C4E764FF859495C015CEF5CF0636768D270FD71A2742B7E2B84EC
8702902292D29CF34E0D4ED84FEF50855256526F5426549057E0592B5A660000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005B5A5B755BCC5E9CF9666276657765A76D6E6EA572367B267C3F7F368150
8151819A8240829983A98A038CA08CE68CFB8D748DBA90E891DC961C964499D9
9CE7531752065429567458B35954596E5FFF61A4626E66106C7E711A76C67C89
7CDE7D1B82AC8CC196F0F9674F5B5F175F7F62C25D29670B68DA787C7E439D6C
4E1550995315532A535159835A625E8760B2618A624962796590678769A76BD4
6BD66BD76BD86CB8F968743575FA7812789179D579D87C837DCB7FE180A50000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000813E81C283F2871A88E88AB98B6C8CBB9119975E98DB9F3B56AC5B2A5F6C
658C6AB36BAF6D5C6FF17015725D73AD8CA78CD3983B61916C3780589A014E4D
4E8B4E9B4ED54F3A4F3C4F7F4FDF50FF53F253F8550655E356DB58EB59625A11
5BEB5BFA5C045DF35E2B5F99601D6368659C65AF67F667FB68AD6B7B6C996CD7
6E23700973457802793E7940796079C17BE97D177D728086820D838E84D186C7
88DF8A508A5E8B1D8CDC8D668FAD90AA98FC99DF9E9D524AF9696714F96A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005098522A5C7165636C5573CA7523759D7B97849C917897304E7764926BBA
715E85A94E09F96B674968EE6E17829F8518886B63F76F81921298AF4E0A50B7
50CF511F554655AA56175B405C195CE05E385E8A5EA05EC260F368516A616E58
723D724072C076F879657BB17FD488F389F48A738C618CDE971C585E74BD8CFD
55C7F96C7A617D2282727272751F7525F96D7B19588558FB5DBC5E8F5EB65F90
60556292637F654D669166D966F8681668F27280745E7B6E7D6E7DD67F720000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
60
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000080E5821285AF897F8A93901D92E49ECD9F205915596D5E2D60DC66146673
67906C506DC56F5F77F378A984C691CB932B4ED950CA514855845B0B5BA36247
657E65CB6E32717D74017444748774BF766C79AA7DDA7E557FA8817A81B38239
861A87EC8A758DE3907892919425994D9BAE53685C5169546CC46D296E2B820C
859B893B8A2D8AAA96EA9F67526166B96BB27E9687FE8D0D9583965D651D6D89
71EEF96E57CE59D35BAC602760FA6210661F665F732973F976DB77017B6C0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
61
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008056807281658AA091924E1652E26B726D177A057B397D30F96F8CB053EC
562F58515BB55C0F5C115DE2624063836414662D68B36CBC6D886EAF701F70A4
71D27526758F758E76197B117BE07C2B7D207D39852C856D86078A34900D9061
90B592B797F69A374FD75C6C675F6D917C9F7E8C8B168D16901F5B6B5DFD640D
84C0905C98E173875B8B609A677E6DDE8A1F8AA69001980C5237F9707051788E
9396887091D74FEE53D755FD56DA578258FD5AC25B885CAB5CC05E2561010000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
62
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000620D624B6388641C653665786A396B8A6C346D196F3171E772E973787407
74B27626776179C07A577AEA7CB97D8F7DAC7E617F9E81298331849084DA85EA
88968AB08B908F3890429083916C929692B9968B96A796A896D6970098089996
9AD39B1A53D4587E59195B705BBF6DD16F5A719F742174B9808583FD5DE15F87
5FAA604265EC6812696F6A536B896D356DF373E376FE77AC7B4D7D148123821C
834084F485638A628AC49187931E980699B4620C88538FF092655D075D270000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
63
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005D69745F819D87686FD562FE7FD2893689724E1E4E5850E752DD5347627F
66077E698805965E4F8D5319563659CB5AA45C385C4E5C4D5E025F11604365BD
662F664267BE67F4731C77E2793A7FC5849484CD89968A668A698AE18C558C7A
57F45BD45F0F606F62ED690D6B966E5C71847BD287558B588EFE98DF98FE4F38
4F814FE1547B5A205BB8613C65B0666871FC7533795E7D33814E81E3839885AA
85CE87038A0A8EAB8F9BF9718FC559315BA45BE660895BE95C0B5FC36C810000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
64
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9726DF1700B751A82AF8AF64EC05341F97396D96C0F4E9E4FC45152555E
5A255CE86211725982BD83AA86FE88598A1D963F96C599139D099D5D580A5CB3
5DBD5E4460E1611563E16A026E2591029354984E9C109F775B895CB86309664F
6848773C96C1978D98549B9F65A18B018ECB95BC55355CA95DD65EB56697764C
83F495C758D362BC72CE9D284EF0592E600F663B6B8379E79D26539354C057C3
5D16611B66D66DAF788D827E969897445384627C63966DB27E0A814B984D0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
65
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006AFB7F4C9DAF9E1A4E5F503B51B6591C60F963F66930723A8036F97491CE
5F31F975F9767D0482E5846F84BB85E58E8DF9774F6FF978F97958E45B436059
63DA6518656D6698F97A694A6A236D0B7001716C75D2760D79B37A70F97B7F8A
F97C8944F97D8B9391C0967DF97E990A57045FA165BC6F01760079A68A9E99AD
9B5A9F6C510461B662916A8D81C6504358305F6671098A008AFA5B7C86164FFA
513C56B4594463A96DF95DAA696D51864E884F59F97FF980F9815982F9820000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
66
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9836B5F6C5DF98474B57916F9858207824583398F3F8F5DF9869918F987
F988F9894EA6F98A57DF5F796613F98BF98C75AB7E798B6FF98D90069A5B56A5
582759F85A1F5BB4F98E5EF6F98FF9906350633BF991693D6C876CBF6D8E6D93
6DF56F14F99270DF71367159F99371C371D5F994784F786FF9957B757DE3F996
7E2FF997884D8EDFF998F999F99A925BF99B9CF6F99CF99DF99E60856D85F99F
71B1F9A0F9A195B153ADF9A2F9A3F9A467D3F9A5708E71307430827682D20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
67
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9A695BB9AE59E7D66C4F9A771C18449F9A8F9A9584BF9AAF9AB5DB85F71
F9AC6620668E697969AE6C386CF36E366F416FDA701B702F715071DF7370F9AD
745BF9AE74D476C87A4E7E93F9AFF9B082F18A608FCEF9B19348F9B29719F9B3
F9B44E42502AF9B5520853E166F36C6D6FCA730A777F7A6282AE85DD8602F9B6
88D48A638B7D8C6BF9B792B3F9B8971398104E944F0D4FC950B25348543E5433
55DA586258BA59675A1B5BE4609FF9B961CA655665FF666468A76C5A6FB30000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
68
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000070CF71AC73527B7D87088AA49C329F075C4B6C8373447389923A6EAB7465
761F7A697E15860A514058C564C174EE751576707FC1909596CD99546E2674E6
7AA97AAA81E586D987788A1B5A495B8C5B9B68A169006D6373A97413742C7897
7DE97FEB81188155839E8C4C962E981166F05F8065FA67896C6A738B502D5A03
6B6A77EE59165D6C5DCD7325754FF9BAF9BB50E551F9582F592D599659DA5BE5
F9BCF9BD5DA262D76416649364FEF9BE66DCF9BF6A48F9C071FF7464F9C10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
69
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00007A887AAF7E477E5E80008170F9C287EF89818B209059F9C390809952617E
6B326D747E1F89258FB14FD150AD519752C757C758895BB95EB8614269956D8C
6E676EB6719474627528752C8073833884C98E0A939493DEF9C44E8E4F515076
512A53C853CB53F35B875BD35C24611A618265F4725B7397744076C279507991
79B97D067FBD828B85D5865E8FC2904790F591EA968596E896E952D65F6765ED
6631682F715C7A3690C1980A4E91F9C56A526B9E6F907189801882B885530000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000904B969596F297FB851A9B314E90718A96C45143539F54E15713571257A3
5A9B5AC45BC36028613F63F46C856D396E726E907230733F745782D188818F45
9060F9C6966298589D1B67088D8A925E4F4D504950DE5371570D59D45A015C09
617066906E2D7232744B7DEF80C3840E8466853F875F885B89188B02905597CB
9B4F4E734F915112516AF9C7552F55A95B7A5BA55E7C5E7D5EBE60A060DF6108
610963C465386709F9C867D467DAF9C9696169626CB96D27F9CA6E38F9CB0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006FE173367337F9CC745C7531F9CD7652F9CEF9CF7DAD81FE843888D58A98
8ADB8AED8E308E42904A903E907A914991C9936EF9D0F9D15809F9D26BD38089
80B2F9D3F9D45141596B5C39F9D5F9D66F6473A780E48D07F9D79217958FF9D8
F9D9F9DAF9DB807F620E701C7D68878DF9DC57A0606961476BB78ABE928096B1
4E59541F6DEB852D967097F398EE63D66CE3909151DD61C981BA9DF94F9D501A
51005B9C610F61FF64EC69056BC5759177E37FA98264858F87FB88638ABC0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008B7091AB4E8C4EE54F0AF9DDF9DE593759E8F9DF5DF25F1B5F5B6021F9E0
F9E1F9E2F9E3723E73E5F9E4757075CDF9E579FBF9E6800C8033808482E18351
F9E7F9E88CBD8CB39087F9E9F9EA98F4990CF9EBF9EC703776CA7FCA7FCC7FFC
8B1A4EBA4EC152035370F9ED54BD56E059FB5BC55F155FCD6E6EF9EEF9EF7D6A
8335F9F086938A8DF9F1976D9777F9F2F9F34E004F5A4F7E58F965E56EA29038
93B099B94EFB58EC598A59D96041F9F4F9F57A14F9F6834F8CC3516553440000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F9F7F9F8F9F94ECD52695B5582BF4ED4523A54A859C959FF5B505B575B5C
606361486ECB7099716E738674F775B578C17D2B800581EA8328851785C98AEE
8CC796CC4F5C52FA56BC65AB6628707C70B872357DBD828D914C96C09D725B71
68E76B986F7A76DE5C9166AB6F5B7BB47C2A883696DC4E084ED75320583458BB
58EF596C5C075E335E845F35638C66B267566A1F6AA36B0C6F3F7246F9FA7350
748B7AE07CA7817881DF81E7838A846C8523859485CF88DD8D1391AC95770000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000969C518D54C957285BB0624D6750683D68936E3D6ED3707D7E2188C18CA1
8F099F4B9F4E722D7B8F8ACD931A4F474F4E5132548059D05E9562B56775696E
6A176CAE6E1A72D9732A75BD7BB87D3582E783F9845785F78A5B8CAF8E879019
90B896CE9F5F52E3540A5AE15BC2645865756EF472C4F9FB76847A4D7B1B7C4D
7E3E7FDF837B8B2B8CCA8D648DE18E5F8FEA8FF9906993D14F434F7A50B35168
5178524D526A5861587C59605C085C555EDB609B623068136BBF6C086FB10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000714E742075307538755176727B4C7B8B7BAD7BC67E8F8A6E8F3E8F49923F
92939322942B96FB985A986B991E5207622A62986D5976647ACA7BC07D765360
5CBE5E976F3870B97C9897119B8E9EDE63A5647A87764E014E954EAD505C5075
544859C35B9A5E405EAD5EF75F8160C5633A653F657465CC6676667867FE6968
6A896B636C406DC06DE86E1F6E5E701E70A1738E73FD753A775B7887798E7A0B
7A7D7CBE7D8E82478A028AEA8C9E912D914A91D8926692CC9320970697560000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
70
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000975C98029F0E52365291557C58245E1D5F1F608C63D068AF6FDF796D7B2C
81CD85BA88FD8AF88E44918D9664969B973D984C9F4A4FCE514651CB52A95632
5F145F6B63AA64CD65E9664166FA66F9671D689D68D769FD6F156F6E716771E5
722A74AA773A7956795A79DF7A207A957C977CDF7D447E70808785FB86A48A54
8ABF8D998E819020906D91E3963B96D59CE565CF7C078DB393C35B585C0A5352
62D9731D50275B975F9E60B0616B68D56DD9742E7A2E7D427D9C7E31816B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
71
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008E2A8E35937E94184F5057505DE65EA7632B7F6A4E3B4F4F4F8F505A59DD
80C4546A546855FE594F5B995DDE5EDA665D673167F1682A6CE86D326E4A6F8D
70B773E075877C4C7D027D2C7DA2821F86DB8A3B8A858D708E8A8F339031914E
9152944499D07AF97CA54FCA510151C657C85BEF5CFB66596A3D6D5A6E966FEC
710C756F7AE388229021907596CB99FF83014E2D4EF2884691CD537D6ADB696B
6C41847A589E618E66FE62EF70DD751175C77E5284B88B498D084E4B53EA0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
72
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054AB573057405FD763016307646F652F65E8667A679D67B36B626C606C9A
6F2C77E57825794979577D1980A2810281F3829D82B787188A8CF9FC8D048DBE
907276F47A197A377E548077550755D45875632F64226649664B686D699B6B84
6D256EB173CD746874A1755B75B976E1771E778B79E67E097E1D81FB852F8897
8A3A8CD18EEB8FB0903293AD9663967397074F8453F159EA5AC95E19684E74C6
75BE79E97A9281A386ED8CEA8DCC8FED659F6715F9FD57F76F577DDD8F2F0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
73
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000093F696C65FB561F26F844E144F98501F53C955DF5D6F5DEE6B216B6478CB
7B9AF9FE8E498ECA906E6349643E77407A84932F947F9F6A64B06FAF71E674A8
74DA7AC47C127E827CB27E988B9A8D0A947D9910994C52395BDF64E6672D7D2E
50ED53C358796158615961FA65AC7AD98B928B9650095021527555315A3C5EE0
5F706134655E660C663666A269CD6EC46F32731676217A938139825983D684BC
50B557F05BC05BE85F6963A178267DB583DC852191C791F5518A67F57B560000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
74
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008CAC51C459BB60BD8655501CF9FF52545C3A617D621A62D364F265A56ECC
7620810A8E60965F96BB4EDF5343559859295DDD64C56CC96DFA73947A7F821B
85A68CE48E10907791E795E1962197C651F854F255865FB964A46F887DB48F1F
8F4D943550C95C166CBE6DFB751B77BB7C3D7C648A798AC2581E59BE5E166377
7252758A776B8ADC8CBC8F125EF366746DF8807D83C18ACB97519BD6FA005243
66FF6D956EEF7DE08AE6902E905E9AD4521D527F54E86194628462DB68A20000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
75
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00006912695A6A3570927126785D7901790E79D27A0D8096827882D583498549
8C828D859162918B91AE4FC356D171ED77D7870089F85BF85FD6675190A853E2
585A5BF560A4618164607E3D80708525928364AE50AC5D146700589C62BD63A8
690E69786A1E6E6B76BA79CB82BB84298ACF8DA88FFD9112914B919C93109318
939A96DB9A369C0D4E11755C795D7AFA7B517BC97E2E84C48E598E748EF89010
6625693F744351FA672E9EDC51455FE06C9687F2885D887760B481B584030000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
76
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00008D0553D6543956345A365C31708A7FE0805A810681ED8DA391899A5F9DF2
50744EC453A060FB6E2C5C644F88502455E45CD95E5F606568946CBB6DC471BE
75D475F476617A1A7A497DC77DFB7F6E81F486A98F1C96C999B39F52524752C5
98ED89AA4E0367D26F064FB55BE267956C886D78741B782791DD937C87C479E4
7A315FEB4ED654A4553E58AE59A560F0625362D6673669558235964099B199DD
502C53535544577CFA016258FA0264E2666B67DD6FC16FEF742274388A170000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
77
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000094385451560657665F48619A6B4E705870AD7DBB8A95596A812B63A27708
803D8CAA5854642D69BB5B955E116E6FFA038569514C53F0592A6020614B6B86
6C706CF07B1E80CE82D48DC690B098B1FA0464C76FA464916504514E5410571F
8A0E615F6876FA0575DB7B527D71901A580669CC817F892A9000983950785957
59AC6295900F9B2A615D727995D657615A465DF4628A64AD64FA67776CE26D3E
722C743678347F7782AD8DDB981752245742677F724874E38CA98FA692110000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
78
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000962A516B53ED634C4F695504609665576C9B6D7F724C72FD7A1789878C9D
5F6D6F8E70F981A8610E4FBF504F624172477BC77DE87FE9904D97AD9A198CB6
576A5E7367B0840D8A5554205B165E635EE25F0A658380BA853D9589965B4F48
5305530D530F548654FA57035E036016629B62B16355FA066CE16D6675B17832
80DE812F82DE846184B2888D8912900B92EA98FD9B915E4566B466DD70117206
FA074FF5527D5F6A615367536A196F0274E2796888688C7998C798C49A430000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
79
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000054C17A1F69538AF78C4A98A899AE5F7C62AB75B276AE88AB907F96425339
5F3C5FC56CCC73CC7562758B7B4682FE999D4E4F903C4E0B4F5553A6590F5EC8
66306CB37455837787668CC09050971E9C1558D15B7886508B149DB45BD26068
608D65F16C576F226FA3701A7F557FF095919592965097D352728F4451FD542B
54B85563558A6ABB6DB57DD88266929C96779E79540854C876D286E495A495D4
965C4EA24F0959EE5AE65DF760526297676D68416C866E2F7F38809B822A0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FA08FA0998054EA5505554B35793595A5B695BB361C869776D77702387F9
89E38A728AE7908299ED9AB852BE683850165E78674F8347884C4EAB541156AE
73E6911597FF9909995799995653589F865B8A3161B26AF6737B8ED26B4796AA
9A57595572008D6B97694FD45CF45F2661F8665B6CEB70AB738473B973FE7729
774D7D437D627E2382378852FA0A8CE29249986F5B517A74884098015ACC4FE0
5354593E5CFD633E6D7972F98105810783A292CF98304EA851445211578B0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00005F626CC26ECE7005705070AF719273E97469834A87A28861900890A293A3
99A8516E5F5760E0616766B385598E4A91AF978B4E4E4E92547C58D558FA597D
5CB55F2762366248660A66676BEB6D696DCF6E566EF86F946FE06FE9705D72D0
7425745A74E07693795C7CCA7E1E80E182A6846B84BF864E865F87748B778C6A
93AC9800986560D1621691775A5A660F6DF76E3E743F9B425FFD60DA7B0F54C4
5F186C5E6CD36D2A70D87D0586798A0C9D3B5316548C5B056A3A706B75750000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000798D79BE82B183EF8A718B418CA89774FA0B64F4652B78BA78BB7A6B4E38
559A59505BA65E7B60A363DB6B61666568536E19716574B07D0890849A699C25
6D3B6ED1733E8C4195CA51F05E4C5FA8604D60F66130614C6643664469A56CC1
6E5F6EC96F62714C749C76877BC17C27835287579051968D9EC3532F56DE5EFB
5F8A6062609461F7666667036A9C6DEE6FAE7070736A7E6A81BE833486D48AA8
8CC4528373725B966A6B940454EE56865B5D6548658566C9689F6D8D6DC60000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000723B80B491759A4D4FAF5019539A540E543C558955C55E3F5F8C673D7166
73DD900552DB52F3586458CE7104718F71FB85B08A13668885A855A76684714A
8431534955996BC15F595FBD63EE668971478AF18F1D9EBE4F11643A70CB7566
866760648B4E9DF8514751F653086D3680F89ED166156B23709875D554035C79
7D078A166B206B3D6B46543860706D3D7FD5820850D651DE559C566B56CD59EC
5B095E0C619961986231665E66E6719971B971BA72A779A77A007FB28A700000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/macCentEuro.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macCentEuro, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C40100010100C9010400D600DC00E10105010C00E4010D0106010700E90179
017A010E00ED010F01120113011600F3011700F400F600F500FA011A011B00FC
202000B0011800A300A7202200B600DF00AE00A92122011900A822600123012E
012F012A22642265012B0136220222110142013B013C013D013E0139013A0145
0146014300AC221A01440147220600AB00BB202600A00148015000D50151014C
20132014201C201D2018201900F725CA014D0154015501582039203A01590156
01570160201A201E0161015A015B00C10164016500CD017D017E016A00D300D4
016B016E00DA016F017001710172017300DD00FD0137017B0141017C012202C7

Added library/encoding/macCroatian.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macCroatian, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C400C500C700C900D100D600DC00E100E000E200E400E300E500E700E900E8
00EA00EB00ED00EC00EE00EF00F100F300F200F400F600F500FA00F900FB00FC
202000B000A200A300A7202200B600DF00AE0160212200B400A82260017D00D8
221E00B122642265220600B522022211220F0161222B00AA00BA2126017E00F8
00BF00A100AC221A01922248010600AB010C202600A000C000C300D501520153
01102014201C201D2018201900F725CAF8FF00A9204400A42039203A00C600BB
201300B7201A201E203000C2010700C1010D00C800CD00CE00CF00CC00D300D4
011100D200DA00DB00D9013102C602DC00AF03C000CB02DA00B800CA00E602C7

Added library/encoding/macCyrillic.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macCyrillic, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0410041104120413041404150416041704180419041A041B041C041D041E041F
0420042104220423042404250426042704280429042A042B042C042D042E042F
202000B000A200A300A7202200B6040600AE00A9212204020452226004030453
221E00B122642265045600B522020408040404540407045704090459040A045A
0458040500AC221A01922248220600AB00BB202600A0040B045B040C045C0455
20132014201C201D2018201900F7201E040E045E040F045F211604010451044F
0430043104320433043404350436043704380439043A043B043C043D043E043F
0440044104420443044404450446044704480449044A044B044C044D044E00A4

Added library/encoding/macDingbats.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macDingbats, single-byte
S
003F 1 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
00202701270227032704260E2706270727082709261B261E270C270D270E270F
2710271127122713271427152716271727182719271A271B271C271D271E271F
2720272127222723272427252726272726052729272A272B272C272D272E272F
2730273127322733273427352736273727382739273A273B273C273D273E273F
2740274127422743274427452746274727482749274A274B25CF274D25A0274F
27502751275225B225BC25C6275625D727582759275A275B275C275D275E007F
F8D7F8D8F8D9F8DAF8DBF8DCF8DDF8DEF8DFF8E0F8E1F8E2F8E3F8E4008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000276127622763276427652766276726632666266526602460246124622463
2464246524662467246824692776277727782779277A277B277C277D277E277F
2780278127822783278427852786278727882789278A278B278C278D278E278F
2790279127922793279421922194219527982799279A279B279C279D279E279F
27A027A127A227A327A427A527A627A727A827A927AA27AB27AC27AD27AE27AF
000027B127B227B327B427B527B627B727B827B927BA27BB27BC27BD27BE0000

Added library/encoding/macGreek.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macGreek, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C400B900B200C900B300D600DC038500E000E200E4038400A800E700E900E8
00EA00EB00A3212200EE00EF202200BD203000F400F600A600AD00F900FB00FC
2020039303940398039B039E03A000DF00AE00A903A303AA00A7226000B00387
039100B12264226500A503920395039603970399039A039C03A603AB03A803A9
03AC039D00AC039F03A1224803A400AB00BB202600A003A503A7038603880153
20132015201C201D2018201900F70389038A038C038E03AD03AE03AF03CC038F
03CD03B103B203C803B403B503C603B303B703B903BE03BA03BB03BC03BD03BF
03C003CE03C103C303C403B803C903C203C703C503B603CA03CB039003B0F8A0

Added library/encoding/macIceland.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macIceland, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C400C500C700C900D100D600DC00E100E000E200E400E300E500E700E900E8
00EA00EB00ED00EC00EE00EF00F100F300F200F400F600F500FA00F900FB00FC
00DD00B000A200A300A7202200B600DF00AE00A9212200B400A8226000C600D8
221E00B12264226500A500B522022211220F03C0222B00AA00BA212600E600F8
00BF00A100AC221A01922248220600AB00BB202600A000C000C300D501520153
20132014201C201D2018201900F725CA00FF0178204400A400D000F000DE00FE
00FD00B7201A201E203000C200CA00C100CB00C800CD00CE00CF00CC00D300D4
F8FF00D200DA00DB00D9013102C602DC00AF02D802D902DA00B802DD02DB02C7

Added library/encoding/macJapan.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
# Encoding file: macJapan, multi-byte
M
003F 0 46
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00A0FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000A921222026
81
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E
203EFF3F30FD30FE309D309E30034EDD30053006300730FC20142010FF0FFF3C
301C2016FF5C22EF202520182019201C201DFF08FF0930143015FF3BFF3DFF5B
FF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D70000
00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6
25A125A025B325B225BD25BC203B301221922190219121933013000000000000
000000000000000000000000000000002208220B2286228722822283222A2229
000000000000000000000000000000002227222800AC21D221D4220022030000
0000000000000000000000000000000000000000222022A52312220222072261
2252226A226B221A223D221D2235222B222C0000000000000000000000000000
212B2030266F266D266A2020202100B6000000000000000025EF000000000000
82
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000FF10
FF11FF12FF13FF14FF15FF16FF17FF18FF190000000000000000000000000000
FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2FFF30
FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3A000000000000000000000000
0000FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5A00000000000000003041
30423043304430453046304730483049304A304B304C304D304E304F30503051
30523053305430553056305730583059305A305B305C305D305E305F30603061
30623063306430653066306730683069306A306B306C306D306E306F30703071
30723073307430753076307730783079307A307B307C307D307E307F30803081
30823083308430853086308730883089308A308B308C308D308E308F30903091
3092309300000000000000000000000000000000000000000000000000000000
83
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
30A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF30B0
30B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF30C0
30C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF30D0
30D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF0000
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000391
03920393039403950396039703980399039A039B039C039D039E039F03A003A1
03A303A403A503A603A703A803A90000000000000000000000000000000003B1
03B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF03C003C1
03C303C403C503C603C703C803C9000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
84
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
04100411041204130414041504010416041704180419041A041B041C041D041E
041F0420042104220423042404250426042704280429042A042B042C042D042E
042F000000000000000000000000000000000000000000000000000000000000
04300431043204330434043504510436043704380439043A043B043C043D0000
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000002500
2502250C251025182514251C252C25242534253C25012503250F2513251B2517
25232533252B253B254B2520252F25282537253F251D25302525253825420000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
85
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
2460246124622463246424652466246724682469246A246B246C246D246E246F
2470247124722473000000000000000000000000000000000000000024742475
2476247724782479247A247B247C247D247E247F248024812482248324842485
2486248700000000000000000000000000000000000000002776277727780000
2779277A277B277C277D277E0000000000000000000000000000000000000000
0000F8A124882489248A248B248C248D248E248F249000000000000000002160
216121622163216421652166216721682169216A216BF8A2F8A3F8A400000000
0000000000002170217121722173217421752176217721782179217A217BF8A5
F8A6F8A700000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000249C249D249E249F24A0
24A124A224A324A424A524A624A724A824A924AA24AB24AC24AD24AE24AF24B0
24B124B224B324B424B500000000000000000000000000000000000000000000
86
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
339C339F339D33A033A4F8A833A133A5339E33A2338EF8A9338F33C433963397
F8AA339833B333B233B133B0210933D433CB3390338533863387F8AB00000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000211633CD2121F8AC2664
2667266126622660266326652666000000000000000000000000000000000000
0000000000003020260E30040000000000000000000000000000000000000000
0000000000000000000000000000261E261C261D261F21C621C421C5F8AD21E8
21E621E721E9F8AEF8AFF8B0F8B1000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
87
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
3230322A322B322C322D322E322F32403237324232433239323A3231323E3234
3232323B323632333235323C323D323F32380000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000059275C0F32A432A532A632A732A832A93296329D3298329E63A732993349
3322334D3314331633053333334E330333363318331533273351334A33393357
330D334233233326333B332B00000000000000000000000000003300331E332A
3331334700000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000337E337D337C337B0000000000000000000000000000
0000000000000000000000000000000000000000337FF8B2F8B3000000000000
88
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
222E221F22BF0000000000000000000000000000000000000000000000000000
0000000000000000301DF8B40000000000000000000000000000000000000000
000000000000000000000000000000003094000030F730F830F930FA00000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000004E9C
55165A03963F54C0611B632859F690228475831C7A5060AA63E16E2565ED8466
82A69BF56893572765A162715B9B59D0867B98F47D627DBE9B8E62167C9F88B7
5B895EB563096697684895C7978D674F4EE54F0A4F4D4F9D504956F2593759D4
5A015C0960DF610F61706613690570BA754F757079FB7DAD7DEF80C3840E8863
8B029055907A533B4E954EA557DF80B290C178EF4E0058F16EA290387A328328
828B9C2F5141537054BD54E156E059FB5F1598F26DEB80E4852D000000000000
89
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9662967096A097FB540B53F35B8770CF7FBD8FC296E8536F9D5C7ABA4E117893
81FC6E26561855046B1D851A9C3B59E553A96D6674DC958F56424E91904B96F2
834F990C53E155B65B305F71662066F368046C386CF36D29745B76C87A4E9834
82F1885B8A6092ED6DB275AB76CA99C560A68B018D8A95B2698E53AD51860000
5712583059445BB45EF6602863A963F46CBF6F14708E7114715971D5733F7E01
827682D185979060925B9D1B586965BC6C5A752551F9592E59655F805FDC62BC
65FA6A2A6B276BB4738B7FC189569D2C9D0E9EC45CA16C96837B51045C4B61B6
81C6687672614E594FFA537860696E297A4F97F34E0B53164EEE4F554F3D4FA1
4F7352A053EF5609590F5AC15BB65BE179D16687679C67B66B4C6CB3706B73C2
798D79BE7A3C7B8782B182DB8304837783EF83D387668AB256298CA88FE6904E
971E868A4FC45CE862117259753B81E582BD86FE8CC096C5991399D54ECB4F1A
89E356DE584A58CA5EFB5FEB602A6094606261D0621262D06539000000000000
8A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9B41666668B06D777070754C76867D7582A587F9958B968E8C9D51F152BE5916
54B35BB35D16616869826DAF788D84CB88578A7293A79AB86D6C99A886D957A3
67FF86CE920E5283568754045ED362E164B9683C68386BBB737278BA7A6B899A
89D28D6B8F0390ED95A3969497695B665CB3697D984D984E639B7B206A2B0000
6A7F68B69C0D6F5F5272559D607062EC6D3B6E076ED1845B89108F444E149C39
53F6691B6A3A9784682A515C7AC384B291DC938C565B9D286822830584317CA5
520882C574E64E7E4F8351A05BD2520A52D852E75DFB559A582A59E65B8C5B98
5BDB5E725E7960A3611F616361BE63DB656267D1685368FA6B3E6B536C576F22
6F976F4574B0751876E3770B7AFF7BA17C217DE97F367FF0809D8266839E89B3
8ACC8CAB908494519593959195A2966597D3992882184E38542B5CB85DCC73A9
764C773C5CA97FEB8D0B96C19811985498584F014F0E5371559C566857FA5947
5B095BC45C905E0C5E7E5FCC63EE673A65D765E2671F68CB68C4000000000000
8B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A5F5E306BC56C176C7D757F79485B637A007D005FBD898F8A188CB48D778ECC
8F1D98E29A0E9B3C4E80507D510059935B9C622F628064EC6B3A72A075917947
7FA987FB8ABC8B7063AC83CA97A05409540355AB68546A588A70782767759ECD
53745BA2811A865090064E184E454EC74F1153CA54385BAE5F13602565510000
673D6C426C726CE3707874037A767AAE7B087D1A7CFE7D6665E7725B53BB5C45
5DE862D262E063196E20865A8A318DDD92F86F0179A69B5A4EA84EAB4EAC4F9B
4FA050D151477AF6517151F653545321537F53EB55AC58835CE15F375F4A602F
6050606D631F65596A4B6CC172C272ED77EF80F881058208854E90F793E197FF
99579A5A4EF051DD5C2D6681696D5C4066F26975738968507C8150C552E45747
5DFE932665A46B236B3D7434798179BD7B4B7DCA82B983CC887F895F8B398FD1
91D1541F92804E5D503653E5533A72D7739677E982E68EAF99C699C899D25177
611A865E55B07A7A50765BD3904796854E326ADB91E75C515C48000000000000
8C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
63987A9F6C9397748F617AAA718A96887C8268177E706851936C52F2541B85AB
8A137FA48ECD90E15366888879414FC250BE521151445553572D73EA578B5951
5F625F8460756176616761A963B2643A656C666F68426E1375667A3D7CFB7D4C
7D997E4B7F6B830E834A86CD8A088A638B668EFD981A9D8F82B88FCE9BE80000
5287621F64836FC09699684150916B206C7A6F547A747D5088408A2367084EF6
503950265065517C5238526355A7570F58055ACC5EFA61B261F862F36372691C
6A29727D72AC732E7814786F7D79770C80A9898B8B198CE28ED290639375967A
98559A139E785143539F53B35E7B5F266E1B6E90738473FE7D4382378A008AFA
96504E4E500B53E4547C56FA59D15B645DF15EAB5F276238654567AF6E5672D0
7CCA88B480A180E183F0864E8A878DE8923796C798679F134E944E924F0D5348
5449543E5A2F5F8C5FA1609F68A76A8E745A78818A9E8AA48B7791904E5E9BC9
4EA44F7C4FAF501950165149516C529F52B952FE539A53E35411000000000000
8D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
540E5589575157A2597D5B545B5D5B8F5DE55DE75DF75E785E835E9A5EB75F18
6052614C629762D863A7653B6602664366F4676D6821689769CB6C5F6D2A6D69
6E2F6E9D75327687786C7A3F7CE07D057D187D5E7DB18015800380AF80B18154
818F822A8352884C88618B1B8CA28CFC90CA91759271783F92FC95A4964D0000
980599999AD89D3B525B52AB53F7540858D562F76FE08C6A8F5F9EB9514B523B
544A56FD7A4091779D609ED273446F09817075115FFD60DA9AA872DB8FBC6B64
98034ECA56F0576458BE5A5A606861C7660F6606683968B16DF775D57D3A826E
9B424E9B4F5053C955065D6F5DE65DEE67FB6C99747378028A50939688DF5750
5EA7632B50B550AC518D670054C9585E59BB5BB05F69624D63A1683D6B736E08
707D91C7728078157826796D658E7D3083DC88C18F09969B5264572867507F6A
8CA151B45742962A583A698A80B454B25D0E57FC78959DFA4F5C524A548B643E
6628671467F57A847B567D22932F685C9BAD7B395319518A5237000000000000
8E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5BDF62F664AE64E6672D6BBA85A996D176909BD6634C93069BAB76BF66524E09
509853C25C7160E864926563685F71E673CA75237B977E8286958B838CDB9178
991065AC66AB6B8B4ED54ED44F3A4F7F523A53F853F255E356DB58EB59CB59C9
59FF5B505C4D5E025E2B5FD7601D6307652F5B5C65AF65BD65E8679D6B620000
6B7B6C0F7345794979C17CF87D197D2B80A2810281F389968A5E8A698A668A8C
8AEE8CC78CDC96CC98FC6B6F4E8B4F3C4F8D51505B575BFA6148630166426B21
6ECB6CBB723E74BD75D478C1793A800C803381EA84948F9E6C509E7F5F0F8B58
9D2B7AFA8EF85B8D96EB4E0353F157F759315AC95BA460896E7F6F0675BE8CEA
5B9F85007BE0507267F4829D5C61854A7E1E820E51995C0463688D66659C716E
793E7D1780058B1D8ECA906E86C790AA501F52FA5C3A6753707C7235914C91C8
932B82E55BC25F3160F94E3B53D65B88624B67316B8A72E973E07A2E816B8DA3
91529996511253D7546A5BFF63886A397DAC970056DA53CE5468000000000000
8F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5B975C315DDE4FEE610162FE6D3279C079CB7D427E4D7FD281ED821F84908846
89728B908E748F2F9031914B916C96C6919C4EC04F4F514553415F93620E67D4
6C416E0B73637E2691CD928353D459195BBF6DD1795D7E2E7C9B587E719F51FA
88538FF04FCA5CFB662577AC7AE3821C99FF51C65FAA65EC696F6B896DF30000
6E966F6476FE7D145DE190759187980651E6521D6240669166D96E1A5EB67DD2
7F7266F885AF85F78AF852A953D959735E8F5F90605592E4966450B7511F52DD
5320534753EC54E8554655315617596859BE5A3C5BB55C065C0F5C115C1A5E84
5E8A5EE05F70627F628462DB638C63776607660C662D6676677E68A26A1F6A35
6CBC6D886E096E58713C7126716775C77701785D7901796579F07AE07B117CA7
7D39809683D6848B8549885D88F38A1F8A3C8A548A738C618CDE91A49266937E
9418969C97984E0A4E084E1E4E575197527057CE583458CC5B225E3860C564FE
676167566D4472B675737A6384B88B7291B89320563157F498FE000000000000
90
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
62ED690D6B9671ED7E548077827289E698DF87558FB15C3B4F384FE14FB55507
5A205BDD5BE95FC3614E632F65B0664B68EE699B6D786DF1753375B9771F795E
79E67D3381E382AF85AA89AA8A3A8EAB8F9B903291DD97074EBA4EC152035875
58EC5C0B751A5C3D814E8A0A8FC59663976D7B258ACF9808916256F353A80000
9017543957825E2563A86C34708A77617C8B7FE088709042915493109318968F
745E9AC45D075D69657067A28DA896DB636E6749691983C5981796C088FE6F84
647A5BF84E16702C755D662F51C4523652E259D35F8160276210653F6574661F
667468F268166B636E057272751F76DB7CBE805658F088FD897F8AA08A938ACB
901D91929752975965897A0E810696BB5E2D60DC621A65A56614679077F37A4D
7C4D7E3E810A8CAC8D648DE18E5F78A9520762D963A5644262988A2D7A837BC0
8AAC96EA7D76820C87494ED95148534353605BA35C025C165DDD6226624764B0
681368346CC96D456D1767D36F5C714E717D65CB7A7F7BAD7DDA000000000000
91
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7E4A7FA8817A821B823985A68A6E8CCE8DF59078907792AD929195839BAE524D
55846F387136516879857E5581B37CCE564C58515CA863AA66FE66FD695A72D9
758F758E790E795679DF7C977D207D4486078A34963B90619F2050E7527553CC
53E2500955AA58EE594F723D5B8B5C64531D60E360F3635C6383633F63BB0000
64CD65E966F95DE369CD69FD6F1571E54E8975E976F87A937CDF7DCF7D9C8061
83498358846C84BC85FB88C58D709001906D9397971C9A1250CF5897618E81D3
85358D0890204FC3507452475373606F6349675F6E2C8DB3901F4FD75C5E8CCA
65CF7D9A53528896517663C35B585B6B5C0A640D6751905C4ED6591A592A6C70
8A51553E581559A560F0625367C182356955964099C49A284F5358065BFE8010
5CB15E2F5F856020614B623466FF6CF06EDE80CE817F82D4888B8CB89000902E
968A9EDB9BDB4EE353F059277B2C918D984C9DF96EDD7027535355445B856258
629E62D36CA26FEF74228A1794386FC18AFE833851E786F853EA000000000000
92
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
53E94F4690548FB0596A81315DFD7AEA8FBF68DA8C3772F89C486A3D8AB04E39
53585606576662C563A265E66B4E6DE16E5B70AD77ED7AEF7BAA7DBB803D80C6
86CB8A95935B56E358C75F3E65AD66966A806BB575378AC7502477E557305F1B
6065667A6C6075F47A1A7F6E81F48718904599B37BC9755C7AF97B5184C40000
901079E97A9283365AE177404E2D4EF25B995FE062BD663C67F16CE8866B8877
8A3B914E92F399D06A177026732A82E784578CAF4E01514651CB558B5BF55E16
5E335E815F145F355F6B5FB461F2631166A2671D6F6E7252753A773A80748139
817887768ABF8ADC8D858DF3929A957798029CE552C5635776F467156C8873CD
8CC393AE96736D25589C690E69CC8FFD939A75DB901A585A680263B469FB4F43
6F2C67D88FBB85267DB49354693F6F70576A58F75B2C7D2C722A540A91E39DB4
4EAD4F4E505C507552438C9E544858245B9A5E1D5E955EAD5EF75F1F608C62B5
633A63D068AF6C407887798E7A0B7DE082478A028AE68E449013000000000000
93
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
90B8912D91D89F0E6CE5645864E265756EF476847B1B906993D16EBA54F25FB9
64A48F4D8FED92445178586B59295C555E976DFB7E8F751C8CBC8EE2985B70B9
4F1D6BBF6FB1753096FB514E54105835585759AC5C605F926597675C6E21767B
83DF8CED901490FD934D7825783A52AA5EA6571F597460125012515A51AC0000
51CD520055105854585859575B955CF65D8B60BC6295642D6771684368BC68DF
76D76DD86E6F6D9B706F71C85F5375D879777B497B547B527CD67D7152308463
856985E48A0E8B048C468E0F9003900F94199676982D9A3095D850CD52D5540C
58025C0E61A7649E6D1E77B37AE580F48404905392855CE09D07533F5F975FB3
6D9C7279776379BF7BE46BD272EC8AAD68036A6151F87A8169345C4A9CF682EB
5BC59149701E56785C6F60C765666C8C8C5A90419813545166C7920D594890A3
51854E4D51EA85998B0E7058637A934B696299B47E047577535769608EDF96E3
6C5D4E8C5C3C5F108FE953028CD1808986795EFF65E54E735165000000000000
94
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59825C3F97EE4EFB598A5FCD8A8D6FE179B079625BE78471732B71B15E745FF5
637B649A71C37C984E435EFC4E4B57DC56A260A96FC37D0D80FD813381BF8FB2
899786A45DF4628A64AD898767776CE26D3E743678345A467F7582AD99AC4FF3
5EC362DD63926557676F76C3724C80CC80BA8F29914D500D57F95A9268850000
6973716472FD8CB758F28CE0966A9019877F79E477E784294F2F5265535A62CD
67CF6CCA767D7B947C95823685848FEB66DD6F2072067E1B83AB99C19EA651FD
7BB178727BB880877B486AE85E61808C75517560516B92626E8C767A91979AEA
4F107F70629C7B4F95A59CE9567A585986E496BC4F345224534A53CD53DB5E06
642C6591677F6C3E6C4E724872AF73ED75547E41822C85E98CA97BC491C67169
981298EF633D6669756A76E478D0854386EE532A5351542659835E875F7C60B2
6249627962AB65906BD46CCC75B276AE789179D87DCB7F7780A588AB8AB98CBB
907F975E98DB6A0B7C3850995C3E5FAE67876BD8743577097F8E000000000000
95
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9F3B67CA7A175339758B9AED5F66819D83F180985F3C5FC575627B46903C6867
59EB5A9B7D10767E8B2C4FF55F6A6A196C376F0274E2796888688A558C795EDF
63CF75C579D282D7932892F2849C86ED9C2D54C15F6C658C6D5C70158CA78CD3
983B654F74F64E0D4ED857E0592B5A665BCC51A85E035E9C6016627665770000
65A7666E6D6E72367B268150819A82998B5C8CA08CE68D74961C96444FAE64AB
6B66821E8461856A90E85C01695398A8847A85574F0F526F5FA95E45670D798F
8179890789866DF55F1762556CB84ECF72699B925206543B567458B361A4626E
711A596E7C897CDE7D1B96F06587805E4E194F75517558405E635E735F0A67C4
4E26853D9589965B7C73980150FB58C1765678A7522577A585117B86504F5909
72477BC77DE88FBA8FD4904D4FBF52C95A295F0197AD4FDD821792EA57036355
6B69752B88DC8F147A4252DF58936155620A66AE6BCD7C3F83E950234FF85305
5446583159495B9D5CF05CEF5D295E9662B16367653E65B9670B000000000000
96
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6CD56CE170F978327E2B80DE82B3840C84EC870289128A2A8C4A90A692D298FD
9CF39D6C4E4F4EA1508D5256574A59A85E3D5FD85FD9623F66B4671B67D068D2
51927D2180AA81A88B008C8C8CBF927E96325420982C531750D5535C58A864B2
6734726777667A4691E652C36CA16B8658005E4C5954672C7FFB51E176C60000
646978E89B549EBB57CB59B96627679A6BCE54E969D95E55819C67959BAA67FE
9C52685D4EA64FE353C862B9672B6CAB8FC44FAD7E6D9EBF4E0761626E806F2B
85135473672A9B455DF37B955CAC5BC6871C6E4A84D17A14810859997C8D6C11
772052D959227121725F77DB97279D61690B5A7F5A1851A5540D547D660E76DF
8FF792989CF459EA725D6EC5514D68C97DBF7DEC97629EBA64786A2183025984
5B5F6BDB731B76F27DB280178499513267289ED976EE676252FF99055C24623B
7C7E8CB0554F60B67D0B958053014E5F51B6591C723A803691CE5F2577E25384
5F797D0485AC8A338E8D975667F385AE9453610961086CB97652000000000000
97
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8AED8F38552F4F51512A52C753CB5BA55E7D60A0618263D6670967DA6E676D8C
733673377531795088D58A98904A909190F596C4878D59154E884F594E0E8A89
8F3F981050AD5E7C59965BB95EB863DA63FA64C166DC694A69D86D0B6EB67194
75287AAF7F8A8000844984C989818B218E0A9065967D990A617E62916B320000
6C836D747FCC7FFC6DC07F8587BA88F8676583B1983C96F76D1B7D61843D916A
4E7153755D506B046FEB85CD862D89A75229540F5C65674E68A87406748375E2
88CF88E191CC96E296785F8B73877ACB844E63A0756552896D416E9C74097559
786B7C9296867ADC9F8D4FB6616E65C5865C4E864EAE50DA4E2151CC5BEE6599
68816DBC731F764277AD7A1C7CE7826F8AD2907C91CF96759818529B7DD1502B
539867976DCB71D0743381E88F2A96A39C579E9F746058416D997D2F985E4EE4
4F364F8B51B752B15DBA601C73B2793C82D3923496B796F6970A9E979F6266A6
6B74521752A370C888C25EC9604B61906F2371497C3E7DF4806F000000000000
98
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
84EE9023932C54429B6F6AD370898CC28DEF973252B45A415ECA5F046717697C
69946D6A6F0F726272FC7BED8001807E874B90CE516D9E937984808B93328AD6
502D548C8A716B6A8CC4810760D167A09DF24E994E989C108A6B85C185686900
6E7E789781550000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000005F0C
4E104E154E2A4E314E364E3C4E3F4E424E564E584E824E858C6B4E8A82125F0D
4E8E4E9E4E9F4EA04EA24EB04EB34EB64ECE4ECD4EC44EC64EC24ED74EDE4EED
4EDF4EF74F094F5A4F304F5B4F5D4F574F474F764F884F8F4F984F7B4F694F70
4F914F6F4F864F9651184FD44FDF4FCE4FD84FDB4FD14FDA4FD04FE44FE5501A
50285014502A502550054F1C4FF650215029502C4FFE4FEF5011500650435047
6703505550505048505A5056506C50785080509A508550B450B2000000000000
99
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
50C950CA50B350C250D650DE50E550ED50E350EE50F950F55109510151025116
51155114511A5121513A5137513C513B513F51405152514C515451627AF85169
516A516E5180518256D8518C5189518F519151935195519651A451A651A251A9
51AA51AB51B351B151B251B051B551BD51C551C951DB51E0865551E951ED0000
51F051F551FE5204520B5214520E5227522A522E52335239524F5244524B524C
525E5254526A527452695273527F527D528D529452925271528852918FA88FA7
52AC52AD52BC52B552C152CD52D752DE52E352E698ED52E052F352F552F852F9
530653087538530D5310530F5315531A5323532F533153335338534053465345
4E175349534D51D6535E5369536E5918537B53775382539653A053A653A553AE
53B053B653C37C1296D953DF66FC71EE53EE53E853ED53FA5401543D5440542C
542D543C542E54365429541D544E548F5475548E545F5471547754705492547B
5480547654845490548654C754A254B854A554AC54C454C854A8000000000000
9A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54AB54C254A454BE54BC54D854E554E6550F551454FD54EE54ED54FA54E25539
55405563554C552E555C55455556555755385533555D5599558054AF558A559F
557B557E5598559E55AE557C558355A9558755A855DA55C555DF55C455DC55E4
55D4561455F7561655FE55FD561B55F9564E565071DF56345636563256380000
566B5664562F566C566A56865680568A56A05694568F56A556AE56B656B456C2
56BC56C156C356C056C856CE56D156D356D756EE56F9570056FF570457095708
570B570D57135718571655C7571C572657375738574E573B5740574F576957C0
57885761577F5789579357A057B357A457AA57B057C357C657D457D257D3580A
57D657E3580B5819581D587258215862584B58706BC05852583D5879588558B9
589F58AB58BA58DE58BB58B858AE58C558D358D158D758D958D858E558DC58E4
58DF58EF58FA58F958FB58FC58FD5902590A5910591B68A65925592C592D5932
5938593E7AD259555950594E595A5958596259605967596C5969000000000000
9B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59785981599D4F5E4FAB59A359B259C659E859DC598D59D959DA5A255A1F5A11
5A1C5A095A1A5A405A6C5A495A355A365A625A6A5A9A5ABC5ABE5ACB5AC25ABD
5AE35AD75AE65AE95AD65AFA5AFB5B0C5B0B5B165B325AD05B2A5B365B3E5B43
5B455B405B515B555B5A5B5B5B655B695B705B735B755B7865885B7A5B800000
5B835BA65BB85BC35BC75BC95BD45BD05BE45BE65BE25BDE5BE55BEB5BF05BF6
5BF35C055C075C085C0D5C135C205C225C285C385C395C415C465C4E5C535C50
5C4F5B715C6C5C6E4E625C765C795C8C5C915C94599B5CAB5CBB5CB65CBC5CB7
5CC55CBE5CC75CD95CE95CFD5CFA5CED5D8C5CEA5D0B5D155D175D5C5D1F5D1B
5D115D145D225D1A5D195D185D4C5D525D4E5D4B5D6C5D735D765D875D845D82
5DA25D9D5DAC5DAE5DBD5D905DB75DBC5DC95DCD5DD35DD25DD65DDB5DEB5DF2
5DF55E0B5E1A5E195E115E1B5E365E375E445E435E405E4E5E575E545E5F5E62
5E645E475E755E765E7A9EBC5E7F5EA05EC15EC25EC85ED05ECF000000000000
9C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5ED65EE35EDD5EDA5EDB5EE25EE15EE85EE95EEC5EF15EF35EF05EF45EF85EFE
5F035F095F5D5F5C5F0B5F115F165F295F2D5F385F415F485F4C5F4E5F2F5F51
5F565F575F595F615F6D5F735F775F835F825F7F5F8A5F885F915F875F9E5F99
5F985FA05FA85FAD5FBC5FD65FFB5FE45FF85FF15FDD60B35FFF602160600000
601960106029600E6031601B6015602B6026600F603A605A6041606A6077605F
604A6046604D6063604360646042606C606B60596081608D60E76083609A6084
609B60966097609260A7608B60E160B860E060D360B45FF060BD60C660B560D8
614D6115610660F660F7610060F460FA6103612160FB60F1610D610E6147613E
61286127614A613F613C612C6134613D614261446173617761586159615A616B
6174616F61656171615F615D6153617561996196618761AC6194619A618A6191
61AB61AE61CC61CA61C961F761C861C361C661BA61CB7F7961CD61E661E361F6
61FA61F461FF61FD61FC61FE620062086209620D620C6214621B000000000000
9D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
621E6221622A622E6230623262336241624E625E6263625B62606268627C6282
6289627E62926293629662D46283629462D762D162BB62CF62FF62C664D462C8
62DC62CC62CA62C262C7629B62C9630C62EE62F163276302630862EF62F56350
633E634D641C634F6396638E638063AB637663A3638F6389639F63B5636B0000
636963BE63E963C063C663E363C963D263F663C4641664346406641364266436
651D64176428640F6467646F6476644E652A6495649364A564A9648864BC64DA
64D264C564C764BB64D864C264F164E7820964E064E162AC64E364EF652C64F6
64F464F264FA650064FD6518651C650565246523652B65346535653765366538
754B654865566555654D6558655E655D65726578658265838B8A659B659F65AB
65B765C365C665C165C465CC65D265DB65D965E065E165F16772660A660365FB
6773663566366634661C664F664466496641665E665D666466676668665F6662
667066836688668E668966846698669D66C166B966C966BE66BC000000000000
9E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
66C466B866D666DA66E0663F66E666E966F066F566F7670F6716671E67266727
9738672E673F67366741673867376746675E67606759676367646789677067A9
677C676A678C678B67A667A1678567B767EF67B467EC67B367E967B867E467DE
67DD67E267EE67B967CE67C667E76A9C681E684668296840684D6832684E0000
68B3682B685968636877687F689F688F68AD6894689D689B68836AAE68B96874
68B568A068BA690F688D687E690168CA690868D86922692668E1690C68CD68D4
68E768D569366912690468D768E3692568F968E068EF6928692A691A69236921
68C669796977695C6978696B6954697E696E69396974693D695969306961695E
695D6981696A69B269AE69D069BF69C169D369BE69CE5BE869CA69DD69BB69C3
69A76A2E699169A0699C699569B469DE69E86A026A1B69FF6B0A69F969F269E7
6A0569B16A1E69ED6A1469EB6A0A6A126AC16A236A136A446A0C6A726A366A78
6A476A626A596A666A486A386A226A906A8D6AA06A846AA26AA3000000000000
9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A9786176ABB6AC36AC26AB86AB36AAC6ADE6AD16ADF6AAA6ADA6AEA6AFB6B05
86166AFA6B126B169B316B1F6B386B3776DC6B3998EE6B476B436B496B506B59
6B546B5B6B5F6B616B786B796B7F6B806B846B836B8D6B986B956B9E6BA46BAA
6BAB6BAF6BB26BB16BB36BB76BBC6BC66BCB6BD36BDF6BEC6BEB6BF36BEF0000
9EBE6C086C136C146C1B6C246C236C5E6C556C626C6A6C826C8D6C9A6C816C9B
6C7E6C686C736C926C906CC46CF16CD36CBD6CD76CC56CDD6CAE6CB16CBE6CBA
6CDB6CEF6CD96CEA6D1F884D6D366D2B6D3D6D386D196D356D336D126D0C6D63
6D936D646D5A6D796D596D8E6D956FE46D856DF96E156E0A6DB56DC76DE66DB8
6DC66DEC6DDE6DCC6DE86DD26DC56DFA6DD96DE46DD56DEA6DEE6E2D6E6E6E2E
6E196E726E5F6E3E6E236E6B6E2B6E766E4D6E1F6E436E3A6E4E6E246EFF6E1D
6E386E826EAA6E986EC96EB76ED36EBD6EAF6EC46EB26ED46ED56E8F6EA56EC2
6E9F6F416F11704C6EEC6EF86EFE6F3F6EF26F316EEF6F326ECC000000000000
E0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6F3E6F136EF76F866F7A6F786F816F806F6F6F5B6FF36F6D6F826F7C6F586F8E
6F916FC26F666FB36FA36FA16FA46FB96FC66FAA6FDF6FD56FEC6FD46FD86FF1
6FEE6FDB7009700B6FFA70117001700F6FFE701B701A6F74701D7018701F7030
703E7032705170637099709270AF70F170AC70B870B370AE70DF70CB70DD0000
70D9710970FD711C711971657155718871667162714C7156716C718F71FB7184
719571A871AC71D771B971BE71D271C971D471CE71E071EC71E771F571FC71F9
71FF720D7210721B7228722D722C72307232723B723C723F72407246724B7258
7274727E7282728172877292729672A272A772B972B272C372C672C472CE72D2
72E272E072E172F972F7500F7317730A731C7316731D7334732F73297325733E
734E734F9ED87357736A7368737073787375737B737A73C873B373CE73BB73C0
73E573EE73DE74A27405746F742573F87432743A7455743F745F74597441745C
746974707463746A7476747E748B749E74A774CA74CF74D473F1000000000000
E1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
74E074E374E774E974EE74F274F074F174F874F7750475037505750C750E750D
75157513751E7526752C753C7544754D754A7549755B7546755A756975647567
756B756D75787576758675877574758A758975827594759A759D75A575A375C2
75B375C375B575BD75B875BC75B175CD75CA75D275D975E375DE75FE75FF0000
75FC760175F075FA75F275F3760B760D7609761F762776207621762276247634
7630763B764776487646765C76587661766276687669766A7667766C76707672
76767678767C768076837688768B768E769676937699769A76B076B476B876B9
76BA76C276CD76D676D276DE76E176E576E776EA862F76FB7708770777047729
7724771E77257726771B773777387747775A7768776B775B7765777F777E7779
778E778B779177A0779E77B077B677B977BF77BC77BD77BB77C777CD77D777DA
77DC77E377EE77FC780C781279267820792A7845788E78747886787C789A788C
78A378B578AA78AF78D178C678CB78D478BE78BC78C578CA78EC000000000000
E2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
78E778DA78FD78F47907791279117919792C792B794079607957795F795A7955
7953797A797F798A799D79A79F4B79AA79AE79B379B979BA79C979D579E779EC
79E179E37A087A0D7A187A197A207A1F79807A317A3B7A3E7A377A437A577A49
7A617A627A699F9D7A707A797A7D7A887A977A957A987A967AA97AC87AB00000
7AB67AC57AC47ABF90837AC77ACA7ACD7ACF7AD57AD37AD97ADA7ADD7AE17AE2
7AE67AED7AF07B027B0F7B0A7B067B337B187B197B1E7B357B287B367B507B7A
7B047B4D7B0B7B4C7B457B757B657B747B677B707B717B6C7B6E7B9D7B987B9F
7B8D7B9C7B9A7B8B7B927B8F7B5D7B997BCB7BC17BCC7BCF7BB47BC67BDD7BE9
7C117C147BE67BE57C607C007C077C137BF37BF77C177C0D7BF67C237C277C2A
7C1F7C377C2B7C3D7C4C7C437C547C4F7C407C507C587C5F7C647C567C657C6C
7C757C837C907CA47CAD7CA27CAB7CA17CA87CB37CB27CB17CAE7CB97CBD7CC0
7CC57CC27CD87CD27CDC7CE29B3B7CEF7CF27CF47CF67CFA7D06000000000000
E3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7D027D1C7D157D0A7D457D4B7D2E7D327D3F7D357D467D737D567D4E7D727D68
7D6E7D4F7D637D937D897D5B7D8F7D7D7D9B7DBA7DAE7DA37DB57DC77DBD7DAB
7E3D7DA27DAF7DDC7DB87D9F7DB07DD87DDD7DE47DDE7DFB7DF27DE17E057E0A
7E237E217E127E317E1F7E097E0B7E227E467E667E3B7E357E397E437E370000
7E327E3A7E677E5D7E567E5E7E597E5A7E797E6A7E697E7C7E7B7E837DD57E7D
8FAE7E7F7E887E897E8C7E927E907E937E947E967E8E7E9B7E9C7F387F3A7F45
7F4C7F4D7F4E7F507F517F557F547F587F5F7F607F687F697F677F787F827F86
7F837F887F877F8C7F947F9E7F9D7F9A7FA37FAF7FB27FB97FAE7FB67FB88B71
7FC57FC67FCA7FD57FD47FE17FE67FE97FF37FF998DC80068004800B80128018
8019801C80218028803F803B804A804680528058805A805F8062806880738072
807080768079807D807F808480868085809B8093809A80AD519080AC80DB80E5
80D980DD80C480DA80D6810980EF80F1811B81298123812F814B000000000000
E4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
968B8146813E8153815180FC8171816E81658166817481838188818A81808182
81A0819581A481A3815F819381A981B081B581BE81B881BD81C081C281BA81C9
81CD81D181D981D881C881DA81DF81E081E781FA81FB81FE8201820282058207
820A820D821082168229822B82388233824082598258825D825A825F82640000
82628268826A826B822E827182778278827E828D829282AB829F82BB82AC82E1
82E382DF82D282F482F382FA8393830382FB82F982DE830682DC830982D98335
83348316833283318340833983508345832F832B831783188385839A83AA839F
83A283968323838E8387838A837C83B58373837583A0838983A883F4841383EB
83CE83FD840383D8840B83C183F7840783E083F2840D8422842083BD84388506
83FB846D842A843C855A84848477846B84AD846E848284698446842C846F8479
843584CA846284B984BF849F84D984CD84BB84DA84D084C184C684D684A18521
84FF84F485178518852C851F8515851484FC8540856385588548000000000000
E5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
85418602854B8555858085A485888591858A85A8856D8594859B85EA8587859C
8577857E859085C985BA85CF85B985D085D585DD85E585DC85F9860A8613860B
85FE85FA86068622861A8630863F864D4E558654865F86678671869386A386A9
86AA868B868C86B686AF86C486C686B086C9882386AB86D486DE86E986EC0000
86DF86DB86EF8712870687088700870386FB87118709870D86F9870A8734873F
8737873B87258729871A8760875F8778874C874E877487578768876E87598753
8763876A880587A2879F878287AF87CB87BD87C087D096D687AB87C487B387C7
87C687BB87EF87F287E0880F880D87FE87F687F7880E87D28811881688158822
88218831883688398827883B8844884288528859885E8862886B8881887E889E
8875887D88B5887288828897889288AE889988A2888D88A488B088BF88B188C3
88C488D488D888D988DD88F9890288FC88F488E888F28904890C890A89138943
891E8925892A892B89418944893B89368938894C891D8960895E000000000000
E6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
89668964896D896A896F89748977897E89838988898A8993899889A189A989A6
89AC89AF89B289BA89BD89BF89C089DA89DC89DD89E789F489F88A038A168A10
8A0C8A1B8A1D8A258A368A418A5B8A528A468A488A7C8A6D8A6C8A628A858A82
8A848AA88AA18A918AA58AA68A9A8AA38AC48ACD8AC28ADA8AEB8AF38AE70000
8AE48AF18B148AE08AE28AF78ADE8ADB8B0C8B078B1A8AE18B168B108B178B20
8B3397AB8B268B2B8B3E8B288B418B4C8B4F8B4E8B498B568B5B8B5A8B6B8B5F
8B6C8B6F8B748B7D8B808B8C8B8E8B928B938B968B998B9A8C3A8C418C3F8C48
8C4C8C4E8C508C558C628C6C8C788C7A8C828C898C858C8A8C8D8C8E8C948C7C
8C98621D8CAD8CAA8CBD8CB28CB38CAE8CB68CC88CC18CE48CE38CDA8CFD8CFA
8CFB8D048D058D0A8D078D0F8D0D8D109F4E8D138CCD8D148D168D678D6D8D71
8D738D818D998DC28DBE8DBA8DCF8DDA8DD68DCC8DDB8DCB8DEA8DEB8DDF8DE3
8DFC8E088E098DFF8E1D8E1E8E108E1F8E428E358E308E348E4A000000000000
E7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8E478E498E4C8E508E488E598E648E608E2A8E638E558E768E728E7C8E818E87
8E858E848E8B8E8A8E938E918E948E998EAA8EA18EAC8EB08EC68EB18EBE8EC5
8EC88ECB8EDB8EE38EFC8EFB8EEB8EFE8F0A8F058F158F128F198F138F1C8F1F
8F1B8F0C8F268F338F3B8F398F458F428F3E8F4C8F498F468F4E8F578F5C0000
8F628F638F648F9C8F9F8FA38FAD8FAF8FB78FDA8FE58FE28FEA8FEF90878FF4
90058FF98FFA901190159021900D901E9016900B90279036903590398FF8904F
905090519052900E9049903E90569058905E9068906F907696A890729082907D
90819080908A9089908F90A890AF90B190B590E290E4624890DB910291129119
91329130914A9156915891639165916991739172918B9189918291A291AB91AF
91AA91B591B491BA91C091C191C991CB91D091D691DF91E191DB91FC91F591F6
921E91FF9214922C92159211925E925792459249926492489295923F924B9250
929C92969293929B925A92CF92B992B792E9930F92FA9344932E000000000000
E8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
93199322931A9323933A9335933B935C9360937C936E935693B093AC93AD9394
93B993D693D793E893E593D893C393DD93D093C893E4941A9414941394039407
94109436942B94359421943A944194529444945B94609462945E946A92299470
94759477947D945A947C947E9481947F95829587958A95949596959895990000
95A095A895A795AD95BC95BB95B995BE95CA6FF695C395CD95CC95D595D495D6
95DC95E195E595E296219628962E962F9642964C964F964B9677965C965E965D
965F96669672966C968D96989695969796AA96A796B196B296B096B496B696B8
96B996CE96CB96C996CD894D96DC970D96D596F99704970697089713970E9711
970F971697199724972A97309739973D973E97449746974897429749975C9760
97649766976852D2976B977197799785977C9781977A9786978B978F9790979C
97A897A697A397B397B497C397C697C897CB97DC97ED9F4F97F27ADF97F697F5
980F980C9838982498219837983D9846984F984B986B986F9870000000000000
E9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
98719874987398AA98AF98B198B698C498C398C698E998EB9903990999129914
99189921991D991E99249920992C992E993D993E9942994999459950994B9951
9952994C99559997999899A599AD99AE99BC99DF99DB99DD99D899D199ED99EE
99F199F299FB99F89A019A0F9A0599E29A199A2B9A379A459A429A409A430000
9A3E9A559A4D9A5B9A579A5F9A629A659A649A699A6B9A6A9AAD9AB09ABC9AC0
9ACF9AD19AD39AD49ADE9ADF9AE29AE39AE69AEF9AEB9AEE9AF49AF19AF79AFB
9B069B189B1A9B1F9B229B239B259B279B289B299B2A9B2E9B2F9B329B449B43
9B4F9B4D9B4E9B519B589B749B939B839B919B969B979B9F9BA09BA89BB49BC0
9BCA9BB99BC69BCF9BD19BD29BE39BE29BE49BD49BE19C3A9BF29BF19BF09C15
9C149C099C139C0C9C069C089C129C0A9C049C2E9C1B9C259C249C219C309C47
9C329C469C3E9C5A9C609C679C769C789CE79CEC9CF09D099D089CEB9D039D06
9D2A9D269DAF9D239D1F9D449D159D129D419D3F9D3E9D469D48000000000000
EA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9D5D9D5E9D649D519D509D599D729D899D879DAB9D6F9D7A9D9A9DA49DA99DB2
9DC49DC19DBB9DB89DBA9DC69DCF9DC29DD99DD39DF89DE69DED9DEF9DFD9E1A
9E1B9E1E9E759E799E7D9E819E889E8B9E8C9E929E959E919E9D9EA59EA99EB8
9EAA9EAD97619ECC9ECE9ECF9ED09ED49EDC9EDE9EDD9EE09EE59EE89EEF0000
9EF49EF69EF79EF99EFB9EFC9EFD9F079F0876B79F159F219F2C9F3E9F4A9F52
9F549F639F5F9F609F619F669F679F6C9F6A9F779F729F769F959F9C9FA0582F
69C79059746451DC719900000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
EB
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F8B5F8B60000000000000000000000000000000000000000000000000000
F8B7FE33000000000000000000000000000000000000F8B8FE31F8B900000000
F8BAF8BBF8BCF8BDFE300000000000000000FE35FE36FE39FE3AF8BEF8BFFE37
FE38FE3FFE40FE3DFE3EFE41FE42FE43FE44FE3BFE3C00000000000000000000
0000F8C000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
EC
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000F8C1
0000F8C20000F8C30000F8C40000F8C500000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F8C600000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000F8C70000F8C80000F8C9000000000000000000000000F8CA000000000000
0000000000000000000000000000000000000000000000000000000000000000
ED
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
F8CB0000F8CC0000F8CD0000F8CE0000F8CF0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000F8D00000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000F8D10000F8D20000F8D3000000000000000000000000F8D40000
00000000000000000000F8D5F8D6000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/macRoman.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macRoman, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C400C500C700C900D100D600DC00E100E000E200E400E300E500E700E900E8
00EA00EB00ED00EC00EE00EF00F100F300F200F400F600F500FA00F900FB00FC
202000B000A200A300A7202200B600DF00AE00A9212200B400A8226000C600D8
221E00B12264226500A500B522022211220F03C0222B00AA00BA212600E600F8
00BF00A100AC221A01922248220600AB00BB202600A000C000C300D501520153
20132014201C201D2018201900F725CA00FF0178204400A42039203AFB01FB02
202100B7201A201E203000C200CA00C100CB00C800CD00CE00CF00CC00D300D4
F8FF00D200DA00DB00D9013102C602DC00AF02D802D902DA00B802DD02DB02C7

Added library/encoding/macRomania.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macRomania, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C400C500C700C900D100D600DC00E100E000E200E400E300E500E700E900E8
00EA00EB00ED00EC00EE00EF00F100F300F200F400F600F500FA00F900FB00FC
202000B000A200A300A7202200B600DF00AE00A9212200B400A822600102015E
221E00B12264226500A500B522022211220F03C0222B00AA00BA21260103015F
00BF00A100AC221A01922248220600AB00BB202600A000C000C300D501520153
20132014201C201D2018201900F725CA00FF0178204400A42039203A01620163
202100B7201A201E203000C200CA00C100CB00C800CD00CE00CF00CC00D300D4
F8FF00D200DA00DB00D9013102C602DC00AF02D802D902DA00B802DD02DB02C7

Added library/encoding/macThai.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macThai, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00AB00BB2026F88CF88FF892F895F898F88BF88EF891F894F897201C201DF899
FFFD2022F884F889F885F886F887F888F88AF88DF890F893F89620182019FFFD
00A00E010E020E030E040E050E060E070E080E090E0A0E0B0E0C0E0D0E0E0E0F
0E100E110E120E130E140E150E160E170E180E190E1A0E1B0E1C0E1D0E1E0E1F
0E200E210E220E230E240E250E260E270E280E290E2A0E2B0E2C0E2D0E2E0E2F
0E300E310E320E330E340E350E360E370E380E390E3AFEFF200B201320140E3F
0E400E410E420E430E440E450E460E470E480E490E4A0E4B0E4C0E4D21220E4F
0E500E510E520E530E540E550E560E570E580E5900AE00A9FFFDFFFDFFFDFFFD

Added library/encoding/macTurkish.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macTurkish, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C400C500C700C900D100D600DC00E100E000E200E400E300E500E700E900E8
00EA00EB00ED00EC00EE00EF00F100F300F200F400F600F500FA00F900FB00FC
202000B000A200A300A7202200B600DF00AE00A9212200B400A8226000C600D8
221E00B12264226500A500B522022211220F03C0222B00AA00BA212600E600F8
00BF00A100AC221A01922248220600AB00BB202600A000C000C300D501520153
20132014201C201D2018201900F725CA00FF0178011E011F01300131015E015F
202100B7201A201E203000C200CA00C100CB00C800CD00CE00CF00CC00D300D4
F8FF00D200DA00DB00D9F8A002C602DC00AF02D802D902DA00B802DD02DB02C7

Added library/encoding/macUkraine.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: macUkraine, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0410041104120413041404150416041704180419041A041B041C041D041E041F
0420042104220423042404250426042704280429042A042B042C042D042E042F
202000B0049000A300A7202200B6040600AE00A9212204020452226004030453
221E00B122642265045600B504910408040404540407045704090459040A045A
0458040500AC221A01922248220600AB00BB202600A0040B045B040C045C0455
20132014201C201D2018201900F7201E040E045E040F045F211604010451044F
0430043104320433043404350436043704380439043A043B043C043D043E043F
0440044104420443044404450446044704480449044A044B044C044D044E00A4

Added library/encoding/shiftjis.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
# Encoding file: shiftjis, multi-byte
M
003F 0 40
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080000000000000000000850086008700000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
81
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E
FFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0FFF3C
301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3DFF5B
FF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D70000
00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6
25A125A025B325B225BD25BC203B301221922190219121933013000000000000
000000000000000000000000000000002208220B2286228722822283222A2229
000000000000000000000000000000002227222800AC21D221D4220022030000
0000000000000000000000000000000000000000222022A52312220222072261
2252226A226B221A223D221D2235222B222C0000000000000000000000000000
212B2030266F266D266A2020202100B6000000000000000025EF000000000000
82
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000FF10
FF11FF12FF13FF14FF15FF16FF17FF18FF190000000000000000000000000000
FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2FFF30
FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3A000000000000000000000000
0000FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5A00000000000000003041
30423043304430453046304730483049304A304B304C304D304E304F30503051
30523053305430553056305730583059305A305B305C305D305E305F30603061
30623063306430653066306730683069306A306B306C306D306E306F30703071
30723073307430753076307730783079307A307B307C307D307E307F30803081
30823083308430853086308730883089308A308B308C308D308E308F30903091
3092309300000000000000000000000000000000000000000000000000000000
83
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
30A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF30B0
30B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF30C0
30C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF30D0
30D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF0000
30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
30F030F130F230F330F430F530F6000000000000000000000000000000000391
03920393039403950396039703980399039A039B039C039D039E039F03A003A1
03A303A403A503A603A703A803A90000000000000000000000000000000003B1
03B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF03C003C1
03C303C403C503C603C703C803C9000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
84
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
04100411041204130414041504010416041704180419041A041B041C041D041E
041F0420042104220423042404250426042704280429042A042B042C042D042E
042F000000000000000000000000000000000000000000000000000000000000
04300431043204330434043504510436043704380439043A043B043C043D0000
043E043F0440044104420443044404450446044704480449044A044B044C044D
044E044F00000000000000000000000000000000000000000000000000002500
2502250C251025182514251C252C25242534253C25012503250F2513251B2517
25232533252B253B254B2520252F25282537253F251D25302525253825420000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
88
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000004E9C
55165A03963F54C0611B632859F690228475831C7A5060AA63E16E2565ED8466
82A69BF56893572765A162715B9B59D0867B98F47D627DBE9B8E62167C9F88B7
5B895EB563096697684895C7978D674F4EE54F0A4F4D4F9D504956F2593759D4
5A015C0960DF610F61706613690570BA754F757079FB7DAD7DEF80C3840E8863
8B029055907A533B4E954EA557DF80B290C178EF4E0058F16EA290387A328328
828B9C2F5141537054BD54E156E059FB5F1598F26DEB80E4852D000000000000
89
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9662967096A097FB540B53F35B8770CF7FBD8FC296E8536F9D5C7ABA4E117893
81FC6E26561855046B1D851A9C3B59E553A96D6674DC958F56424E91904B96F2
834F990C53E155B65B305F71662066F368046C386CF36D29745B76C87A4E9834
82F1885B8A6092ED6DB275AB76CA99C560A68B018D8A95B2698E53AD51860000
5712583059445BB45EF6602863A963F46CBF6F14708E7114715971D5733F7E01
827682D185979060925B9D1B586965BC6C5A752551F9592E59655F805FDC62BC
65FA6A2A6B276BB4738B7FC189569D2C9D0E9EC45CA16C96837B51045C4B61B6
81C6687672614E594FFA537860696E297A4F97F34E0B53164EEE4F554F3D4FA1
4F7352A053EF5609590F5AC15BB65BE179D16687679C67B66B4C6CB3706B73C2
798D79BE7A3C7B8782B182DB8304837783EF83D387668AB256298CA88FE6904E
971E868A4FC45CE862117259753B81E582BD86FE8CC096C5991399D54ECB4F1A
89E356DE584A58CA5EFB5FEB602A6094606261D0621262D06539000000000000
8A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9B41666668B06D777070754C76867D7582A587F9958B968E8C9D51F152BE5916
54B35BB35D16616869826DAF788D84CB88578A7293A79AB86D6C99A886D957A3
67FF86CE920E5283568754045ED362E164B9683C68386BBB737278BA7A6B899A
89D28D6B8F0390ED95A3969497695B665CB3697D984D984E639B7B206A2B0000
6A7F68B69C0D6F5F5272559D607062EC6D3B6E076ED1845B89108F444E149C39
53F6691B6A3A9784682A515C7AC384B291DC938C565B9D286822830584317CA5
520882C574E64E7E4F8351A05BD2520A52D852E75DFB559A582A59E65B8C5B98
5BDB5E725E7960A3611F616361BE63DB656267D1685368FA6B3E6B536C576F22
6F976F4574B0751876E3770B7AFF7BA17C217DE97F367FF0809D8266839E89B3
8ACC8CAB908494519593959195A2966597D3992882184E38542B5CB85DCC73A9
764C773C5CA97FEB8D0B96C19811985498584F014F0E5371559C566857FA5947
5B095BC45C905E0C5E7E5FCC63EE673A65D765E2671F68CB68C4000000000000
8B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A5F5E306BC56C176C7D757F79485B637A007D005FBD898F8A188CB48D778ECC
8F1D98E29A0E9B3C4E80507D510059935B9C622F628064EC6B3A72A075917947
7FA987FB8ABC8B7063AC83CA97A05409540355AB68546A588A70782767759ECD
53745BA2811A865090064E184E454EC74F1153CA54385BAE5F13602565510000
673D6C426C726CE3707874037A767AAE7B087D1A7CFE7D6665E7725B53BB5C45
5DE862D262E063196E20865A8A318DDD92F86F0179A69B5A4EA84EAB4EAC4F9B
4FA050D151477AF6517151F653545321537F53EB55AC58835CE15F375F4A602F
6050606D631F65596A4B6CC172C272ED77EF80F881058208854E90F793E197FF
99579A5A4EF051DD5C2D6681696D5C4066F26975738968507C8150C552E45747
5DFE932665A46B236B3D7434798179BD7B4B7DCA82B983CC887F895F8B398FD1
91D1541F92804E5D503653E5533A72D7739677E982E68EAF99C699C899D25177
611A865E55B07A7A50765BD3904796854E326ADB91E75C515C48000000000000
8C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
63987A9F6C9397748F617AAA718A96887C8268177E706851936C52F2541B85AB
8A137FA48ECD90E15366888879414FC250BE521151445553572D73EA578B5951
5F625F8460756176616761A963B2643A656C666F68426E1375667A3D7CFB7D4C
7D997E4B7F6B830E834A86CD8A088A638B668EFD981A9D8F82B88FCE9BE80000
5287621F64836FC09699684150916B206C7A6F547A747D5088408A2367084EF6
503950265065517C5238526355A7570F58055ACC5EFA61B261F862F36372691C
6A29727D72AC732E7814786F7D79770C80A9898B8B198CE28ED290639375967A
98559A139E785143539F53B35E7B5F266E1B6E90738473FE7D4382378A008AFA
96504E4E500B53E4547C56FA59D15B645DF15EAB5F276238654567AF6E5672D0
7CCA88B480A180E183F0864E8A878DE8923796C798679F134E944E924F0D5348
5449543E5A2F5F8C5FA1609F68A76A8E745A78818A9E8AA48B7791904E5E9BC9
4EA44F7C4FAF501950165149516C529F52B952FE539A53E35411000000000000
8D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
540E5589575157A2597D5B545B5D5B8F5DE55DE75DF75E785E835E9A5EB75F18
6052614C629762D863A7653B6602664366F4676D6821689769CB6C5F6D2A6D69
6E2F6E9D75327687786C7A3F7CE07D057D187D5E7DB18015800380AF80B18154
818F822A8352884C88618B1B8CA28CFC90CA91759271783F92FC95A4964D0000
980599999AD89D3B525B52AB53F7540858D562F76FE08C6A8F5F9EB9514B523B
544A56FD7A4091779D609ED273446F09817075115FFD60DA9AA872DB8FBC6B64
98034ECA56F0576458BE5A5A606861C7660F6606683968B16DF775D57D3A826E
9B424E9B4F5053C955065D6F5DE65DEE67FB6C99747378028A50939688DF5750
5EA7632B50B550AC518D670054C9585E59BB5BB05F69624D63A1683D6B736E08
707D91C7728078157826796D658E7D3083DC88C18F09969B5264572867507F6A
8CA151B45742962A583A698A80B454B25D0E57FC78959DFA4F5C524A548B643E
6628671467F57A847B567D22932F685C9BAD7B395319518A5237000000000000
8E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5BDF62F664AE64E6672D6BBA85A996D176909BD6634C93069BAB76BF66524E09
509853C25C7160E864926563685F71E673CA75237B977E8286958B838CDB9178
991065AC66AB6B8B4ED54ED44F3A4F7F523A53F853F255E356DB58EB59CB59C9
59FF5B505C4D5E025E2B5FD7601D6307652F5B5C65AF65BD65E8679D6B620000
6B7B6C0F7345794979C17CF87D197D2B80A2810281F389968A5E8A698A668A8C
8AEE8CC78CDC96CC98FC6B6F4E8B4F3C4F8D51505B575BFA6148630166426B21
6ECB6CBB723E74BD75D478C1793A800C803381EA84948F9E6C509E7F5F0F8B58
9D2B7AFA8EF85B8D96EB4E0353F157F759315AC95BA460896E7F6F0675BE8CEA
5B9F85007BE0507267F4829D5C61854A7E1E820E51995C0463688D66659C716E
793E7D1780058B1D8ECA906E86C790AA501F52FA5C3A6753707C7235914C91C8
932B82E55BC25F3160F94E3B53D65B88624B67316B8A72E973E07A2E816B8DA3
91529996511253D7546A5BFF63886A397DAC970056DA53CE5468000000000000
8F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5B975C315DDE4FEE610162FE6D3279C079CB7D427E4D7FD281ED821F84908846
89728B908E748F2F9031914B916C96C6919C4EC04F4F514553415F93620E67D4
6C416E0B73637E2691CD928353D459195BBF6DD1795D7E2E7C9B587E719F51FA
88538FF04FCA5CFB662577AC7AE3821C99FF51C65FAA65EC696F6B896DF30000
6E966F6476FE7D145DE190759187980651E6521D6240669166D96E1A5EB67DD2
7F7266F885AF85F78AF852A953D959735E8F5F90605592E4966450B7511F52DD
5320534753EC54E8554655315617596859BE5A3C5BB55C065C0F5C115C1A5E84
5E8A5EE05F70627F628462DB638C63776607660C662D6676677E68A26A1F6A35
6CBC6D886E096E58713C7126716775C77701785D7901796579F07AE07B117CA7
7D39809683D6848B8549885D88F38A1F8A3C8A548A738C618CDE91A49266937E
9418969C97984E0A4E084E1E4E575197527057CE583458CC5B225E3860C564FE
676167566D4472B675737A6384B88B7291B89320563157F498FE000000000000
90
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
62ED690D6B9671ED7E548077827289E698DF87558FB15C3B4F384FE14FB55507
5A205BDD5BE95FC3614E632F65B0664B68EE699B6D786DF1753375B9771F795E
79E67D3381E382AF85AA89AA8A3A8EAB8F9B903291DD97074EBA4EC152035875
58EC5C0B751A5C3D814E8A0A8FC59663976D7B258ACF9808916256F353A80000
9017543957825E2563A86C34708A77617C8B7FE088709042915493109318968F
745E9AC45D075D69657067A28DA896DB636E6749691983C5981796C088FE6F84
647A5BF84E16702C755D662F51C4523652E259D35F8160276210653F6574661F
667468F268166B636E057272751F76DB7CBE805658F088FD897F8AA08A938ACB
901D91929752975965897A0E810696BB5E2D60DC621A65A56614679077F37A4D
7C4D7E3E810A8CAC8D648DE18E5F78A9520762D963A5644262988A2D7A837BC0
8AAC96EA7D76820C87494ED95148534353605BA35C025C165DDD6226624764B0
681368346CC96D456D1767D36F5C714E717D65CB7A7F7BAD7DDA000000000000
91
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7E4A7FA8817A821B823985A68A6E8CCE8DF59078907792AD929195839BAE524D
55846F387136516879857E5581B37CCE564C58515CA863AA66FE66FD695A72D9
758F758E790E795679DF7C977D207D4486078A34963B90619F2050E7527553CC
53E2500955AA58EE594F723D5B8B5C64531D60E360F3635C6383633F63BB0000
64CD65E966F95DE369CD69FD6F1571E54E8975E976F87A937CDF7DCF7D9C8061
83498358846C84BC85FB88C58D709001906D9397971C9A1250CF5897618E81D3
85358D0890204FC3507452475373606F6349675F6E2C8DB3901F4FD75C5E8CCA
65CF7D9A53528896517663C35B585B6B5C0A640D6751905C4ED6591A592A6C70
8A51553E581559A560F0625367C182356955964099C49A284F5358065BFE8010
5CB15E2F5F856020614B623466FF6CF06EDE80CE817F82D4888B8CB89000902E
968A9EDB9BDB4EE353F059277B2C918D984C9DF96EDD7027535355445B856258
629E62D36CA26FEF74228A1794386FC18AFE833851E786F853EA000000000000
92
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
53E94F4690548FB0596A81315DFD7AEA8FBF68DA8C3772F89C486A3D8AB04E39
53585606576662C563A265E66B4E6DE16E5B70AD77ED7AEF7BAA7DBB803D80C6
86CB8A95935B56E358C75F3E65AD66966A806BB575378AC7502477E557305F1B
6065667A6C6075F47A1A7F6E81F48718904599B37BC9755C7AF97B5184C40000
901079E97A9283365AE177404E2D4EF25B995FE062BD663C67F16CE8866B8877
8A3B914E92F399D06A177026732A82E784578CAF4E01514651CB558B5BF55E16
5E335E815F145F355F6B5FB461F2631166A2671D6F6E7252753A773A80748139
817887768ABF8ADC8D858DF3929A957798029CE552C5635776F467156C8873CD
8CC393AE96736D25589C690E69CC8FFD939A75DB901A585A680263B469FB4F43
6F2C67D88FBB85267DB49354693F6F70576A58F75B2C7D2C722A540A91E39DB4
4EAD4F4E505C507552438C9E544858245B9A5E1D5E955EAD5EF75F1F608C62B5
633A63D068AF6C407887798E7A0B7DE082478A028AE68E449013000000000000
93
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
90B8912D91D89F0E6CE5645864E265756EF476847B1B906993D16EBA54F25FB9
64A48F4D8FED92445178586B59295C555E976DFB7E8F751C8CBC8EE2985B70B9
4F1D6BBF6FB1753096FB514E54105835585759AC5C605F926597675C6E21767B
83DF8CED901490FD934D7825783A52AA5EA6571F597460125012515A51AC0000
51CD520055105854585859575B955CF65D8B60BC6295642D6771684368BC68DF
76D76DD86E6F6D9B706F71C85F5375D879777B497B547B527CD67D7152308463
856985E48A0E8B048C468E0F9003900F94199676982D9A3095D850CD52D5540C
58025C0E61A7649E6D1E77B37AE580F48404905392855CE09D07533F5F975FB3
6D9C7279776379BF7BE46BD272EC8AAD68036A6151F87A8169345C4A9CF682EB
5BC59149701E56785C6F60C765666C8C8C5A90419813545166C7920D594890A3
51854E4D51EA85998B0E7058637A934B696299B47E047577535769608EDF96E3
6C5D4E8C5C3C5F108FE953028CD1808986795EFF65E54E735165000000000000
94
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59825C3F97EE4EFB598A5FCD8A8D6FE179B079625BE78471732B71B15E745FF5
637B649A71C37C984E435EFC4E4B57DC56A260A96FC37D0D80FD813381BF8FB2
899786A45DF4628A64AD898767776CE26D3E743678345A467F7582AD99AC4FF3
5EC362DD63926557676F76C3724C80CC80BA8F29914D500D57F95A9268850000
6973716472FD8CB758F28CE0966A9019877F79E477E784294F2F5265535A62CD
67CF6CCA767D7B947C95823685848FEB66DD6F2072067E1B83AB99C19EA651FD
7BB178727BB880877B486AE85E61808C75517560516B92626E8C767A91979AEA
4F107F70629C7B4F95A59CE9567A585986E496BC4F345224534A53CD53DB5E06
642C6591677F6C3E6C4E724872AF73ED75547E41822C85E98CA97BC491C67169
981298EF633D6669756A76E478D0854386EE532A5351542659835E875F7C60B2
6249627962AB65906BD46CCC75B276AE789179D87DCB7F7780A588AB8AB98CBB
907F975E98DB6A0B7C3850995C3E5FAE67876BD8743577097F8E000000000000
95
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9F3B67CA7A175339758B9AED5F66819D83F180985F3C5FC575627B46903C6867
59EB5A9B7D10767E8B2C4FF55F6A6A196C376F0274E2796888688A558C795EDF
63CF75C579D282D7932892F2849C86ED9C2D54C15F6C658C6D5C70158CA78CD3
983B654F74F64E0D4ED857E0592B5A665BCC51A85E035E9C6016627665770000
65A7666E6D6E72367B268150819A82998B5C8CA08CE68D74961C96444FAE64AB
6B66821E8461856A90E85C01695398A8847A85574F0F526F5FA95E45670D798F
8179890789866DF55F1762556CB84ECF72699B925206543B567458B361A4626E
711A596E7C897CDE7D1B96F06587805E4E194F75517558405E635E735F0A67C4
4E26853D9589965B7C73980150FB58C1765678A7522577A585117B86504F5909
72477BC77DE88FBA8FD4904D4FBF52C95A295F0197AD4FDD821792EA57036355
6B69752B88DC8F147A4252DF58936155620A66AE6BCD7C3F83E950234FF85305
5446583159495B9D5CF05CEF5D295E9662B16367653E65B9670B000000000000
96
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6CD56CE170F978327E2B80DE82B3840C84EC870289128A2A8C4A90A692D298FD
9CF39D6C4E4F4EA1508D5256574A59A85E3D5FD85FD9623F66B4671B67D068D2
51927D2180AA81A88B008C8C8CBF927E96325420982C531750D5535C58A864B2
6734726777667A4691E652C36CA16B8658005E4C5954672C7FFB51E176C60000
646978E89B549EBB57CB59B96627679A6BCE54E969D95E55819C67959BAA67FE
9C52685D4EA64FE353C862B9672B6CAB8FC44FAD7E6D9EBF4E0761626E806F2B
85135473672A9B455DF37B955CAC5BC6871C6E4A84D17A14810859997C8D6C11
772052D959227121725F77DB97279D61690B5A7F5A1851A5540D547D660E76DF
8FF792989CF459EA725D6EC5514D68C97DBF7DEC97629EBA64786A2183025984
5B5F6BDB731B76F27DB280178499513267289ED976EE676252FF99055C24623B
7C7E8CB0554F60B67D0B958053014E5F51B6591C723A803691CE5F2577E25384
5F797D0485AC8A338E8D975667F385AE9453610961086CB9765200000000FF5E
97
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8AED8F38552F4F51512A52C753CB5BA55E7D60A0618263D6670967DA6E676D8C
733673377531795088D58A98904A909190F596C4878D59154E884F594E0E8A89
8F3F981050AD5E7C59965BB95EB863DA63FA64C166DC694A69D86D0B6EB67194
75287AAF7F8A8000844984C989818B218E0A9065967D990A617E62916B320000
6C836D747FCC7FFC6DC07F8587BA88F8676583B1983C96F76D1B7D61843D916A
4E7153755D506B046FEB85CD862D89A75229540F5C65674E68A87406748375E2
88CF88E191CC96E296785F8B73877ACB844E63A0756552896D416E9C74097559
786B7C9296867ADC9F8D4FB6616E65C5865C4E864EAE50DA4E2151CC5BEE6599
68816DBC731F764277AD7A1C7CE7826F8AD2907C91CF96759818529B7DD1502B
539867976DCB71D0743381E88F2A96A39C579E9F746058416D997D2F985E4EE4
4F364F8B51B752B15DBA601C73B2793C82D3923496B796F6970A9E979F6266A6
6B74521752A370C888C25EC9604B61906F2371497C3E7DF4806F000000000000
98
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
84EE9023932C54429B6F6AD370898CC28DEF973252B45A415ECA5F046717697C
69946D6A6F0F726272FC7BED8001807E874B90CE516D9E937984808B93328AD6
502D548C8A716B6A8CC4810760D167A09DF24E994E989C108A6B85C185686900
6E7E789781550000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000005F0C
4E104E154E2A4E314E364E3C4E3F4E424E564E584E824E858C6B4E8A82125F0D
4E8E4E9E4E9F4EA04EA24EB04EB34EB64ECE4ECD4EC44EC64EC24ED74EDE4EED
4EDF4EF74F094F5A4F304F5B4F5D4F574F474F764F884F8F4F984F7B4F694F70
4F914F6F4F864F9651184FD44FDF4FCE4FD84FDB4FD14FDA4FD04FE44FE5501A
50285014502A502550054F1C4FF650215029502C4FFE4FEF5011500650435047
6703505550505048505A5056506C50785080509A508550B450B2000000000000
99
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
50C950CA50B350C250D650DE50E550ED50E350EE50F950F55109510151025116
51155114511A5121513A5137513C513B513F51405152514C515451627AF85169
516A516E5180518256D8518C5189518F519151935195519651A451A651A251A9
51AA51AB51B351B151B251B051B551BD51C551C951DB51E0865551E951ED0000
51F051F551FE5204520B5214520E5227522A522E52335239524F5244524B524C
525E5254526A527452695273527F527D528D529452925271528852918FA88FA7
52AC52AD52BC52B552C152CD52D752DE52E352E698ED52E052F352F552F852F9
530653087538530D5310530F5315531A5323532F533153335338534053465345
4E175349534D51D6535E5369536E5918537B53775382539653A053A653A553AE
53B053B653C37C1296D953DF66FC71EE53EE53E853ED53FA5401543D5440542C
542D543C542E54365429541D544E548F5475548E545F5471547754705492547B
5480547654845490548654C754A254B854A554AC54C454C854A8000000000000
9A
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
54AB54C254A454BE54BC54D854E554E6550F551454FD54EE54ED54FA54E25539
55405563554C552E555C55455556555755385533555D5599558054AF558A559F
557B557E5598559E55AE557C558355A9558755A855DA55C555DF55C455DC55E4
55D4561455F7561655FE55FD561B55F9564E565071DF56345636563256380000
566B5664562F566C566A56865680568A56A05694568F56A556AE56B656B456C2
56BC56C156C356C056C856CE56D156D356D756EE56F9570056FF570457095708
570B570D57135718571655C7571C572657375738574E573B5740574F576957C0
57885761577F5789579357A057B357A457AA57B057C357C657D457D257D3580A
57D657E3580B5819581D587258215862584B58706BC05852583D5879588558B9
589F58AB58BA58DE58BB58B858AE58C558D358D158D758D958D858E558DC58E4
58DF58EF58FA58F958FB58FC58FD5902590A5910591B68A65925592C592D5932
5938593E7AD259555950594E595A5958596259605967596C5969000000000000
9B
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
59785981599D4F5E4FAB59A359B259C659E859DC598D59D959DA5A255A1F5A11
5A1C5A095A1A5A405A6C5A495A355A365A625A6A5A9A5ABC5ABE5ACB5AC25ABD
5AE35AD75AE65AE95AD65AFA5AFB5B0C5B0B5B165B325AD05B2A5B365B3E5B43
5B455B405B515B555B5A5B5B5B655B695B705B735B755B7865885B7A5B800000
5B835BA65BB85BC35BC75BC95BD45BD05BE45BE65BE25BDE5BE55BEB5BF05BF6
5BF35C055C075C085C0D5C135C205C225C285C385C395C415C465C4E5C535C50
5C4F5B715C6C5C6E4E625C765C795C8C5C915C94599B5CAB5CBB5CB65CBC5CB7
5CC55CBE5CC75CD95CE95CFD5CFA5CED5D8C5CEA5D0B5D155D175D5C5D1F5D1B
5D115D145D225D1A5D195D185D4C5D525D4E5D4B5D6C5D735D765D875D845D82
5DA25D9D5DAC5DAE5DBD5D905DB75DBC5DC95DCD5DD35DD25DD65DDB5DEB5DF2
5DF55E0B5E1A5E195E115E1B5E365E375E445E435E405E4E5E575E545E5F5E62
5E645E475E755E765E7A9EBC5E7F5EA05EC15EC25EC85ED05ECF000000000000
9C
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
5ED65EE35EDD5EDA5EDB5EE25EE15EE85EE95EEC5EF15EF35EF05EF45EF85EFE
5F035F095F5D5F5C5F0B5F115F165F295F2D5F385F415F485F4C5F4E5F2F5F51
5F565F575F595F615F6D5F735F775F835F825F7F5F8A5F885F915F875F9E5F99
5F985FA05FA85FAD5FBC5FD65FFB5FE45FF85FF15FDD60B35FFF602160600000
601960106029600E6031601B6015602B6026600F603A605A6041606A6077605F
604A6046604D6063604360646042606C606B60596081608D60E76083609A6084
609B60966097609260A7608B60E160B860E060D360B45FF060BD60C660B560D8
614D6115610660F660F7610060F460FA6103612160FB60F1610D610E6147613E
61286127614A613F613C612C6134613D614261446173617761586159615A616B
6174616F61656171615F615D6153617561996196618761AC6194619A618A6191
61AB61AE61CC61CA61C961F761C861C361C661BA61CB7F7961CD61E661E361F6
61FA61F461FF61FD61FC61FE620062086209620D620C6214621B000000000000
9D
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
621E6221622A622E6230623262336241624E625E6263625B62606268627C6282
6289627E62926293629662D46283629462D762D162BB62CF62FF62C664D462C8
62DC62CC62CA62C262C7629B62C9630C62EE62F163276302630862EF62F56350
633E634D641C634F6396638E638063AB637663A3638F6389639F63B5636B0000
636963BE63E963C063C663E363C963D263F663C4641664346406641364266436
651D64176428640F6467646F6476644E652A6495649364A564A9648864BC64DA
64D264C564C764BB64D864C264F164E7820964E064E162AC64E364EF652C64F6
64F464F264FA650064FD6518651C650565246523652B65346535653765366538
754B654865566555654D6558655E655D65726578658265838B8A659B659F65AB
65B765C365C665C165C465CC65D265DB65D965E065E165F16772660A660365FB
6773663566366634661C664F664466496641665E665D666466676668665F6662
667066836688668E668966846698669D66C166B966C966BE66BC000000000000
9E
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
66C466B866D666DA66E0663F66E666E966F066F566F7670F6716671E67266727
9738672E673F67366741673867376746675E67606759676367646789677067A9
677C676A678C678B67A667A1678567B767EF67B467EC67B367E967B867E467DE
67DD67E267EE67B967CE67C667E76A9C681E684668296840684D6832684E0000
68B3682B685968636877687F689F688F68AD6894689D689B68836AAE68B96874
68B568A068BA690F688D687E690168CA690868D86922692668E1690C68CD68D4
68E768D569366912690468D768E3692568F968E068EF6928692A691A69236921
68C669796977695C6978696B6954697E696E69396974693D695969306961695E
695D6981696A69B269AE69D069BF69C169D369BE69CE5BE869CA69DD69BB69C3
69A76A2E699169A0699C699569B469DE69E86A026A1B69FF6B0A69F969F269E7
6A0569B16A1E69ED6A1469EB6A0A6A126AC16A236A136A446A0C6A726A366A78
6A476A626A596A666A486A386A226A906A8D6AA06A846AA26AA3000000000000
9F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6A9786176ABB6AC36AC26AB86AB36AAC6ADE6AD16ADF6AAA6ADA6AEA6AFB6B05
86166AFA6B126B169B316B1F6B386B3776DC6B3998EE6B476B436B496B506B59
6B546B5B6B5F6B616B786B796B7F6B806B846B836B8D6B986B956B9E6BA46BAA
6BAB6BAF6BB26BB16BB36BB76BBC6BC66BCB6BD36BDF6BEC6BEB6BF36BEF0000
9EBE6C086C136C146C1B6C246C236C5E6C556C626C6A6C826C8D6C9A6C816C9B
6C7E6C686C736C926C906CC46CF16CD36CBD6CD76CC56CDD6CAE6CB16CBE6CBA
6CDB6CEF6CD96CEA6D1F884D6D366D2B6D3D6D386D196D356D336D126D0C6D63
6D936D646D5A6D796D596D8E6D956FE46D856DF96E156E0A6DB56DC76DE66DB8
6DC66DEC6DDE6DCC6DE86DD26DC56DFA6DD96DE46DD56DEA6DEE6E2D6E6E6E2E
6E196E726E5F6E3E6E236E6B6E2B6E766E4D6E1F6E436E3A6E4E6E246EFF6E1D
6E386E826EAA6E986EC96EB76ED36EBD6EAF6EC46EB26ED46ED56E8F6EA56EC2
6E9F6F416F11704C6EEC6EF86EFE6F3F6EF26F316EEF6F326ECC000000000000
E0
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
6F3E6F136EF76F866F7A6F786F816F806F6F6F5B6FF36F6D6F826F7C6F586F8E
6F916FC26F666FB36FA36FA16FA46FB96FC66FAA6FDF6FD56FEC6FD46FD86FF1
6FEE6FDB7009700B6FFA70117001700F6FFE701B701A6F74701D7018701F7030
703E7032705170637099709270AF70F170AC70B870B370AE70DF70CB70DD0000
70D9710970FD711C711971657155718871667162714C7156716C718F71FB7184
719571A871AC71D771B971BE71D271C971D471CE71E071EC71E771F571FC71F9
71FF720D7210721B7228722D722C72307232723B723C723F72407246724B7258
7274727E7282728172877292729672A272A772B972B272C372C672C472CE72D2
72E272E072E172F972F7500F7317730A731C7316731D7334732F73297325733E
734E734F9ED87357736A7368737073787375737B737A73C873B373CE73BB73C0
73E573EE73DE74A27405746F742573F87432743A7455743F745F74597441745C
746974707463746A7476747E748B749E74A774CA74CF74D473F1000000000000
E1
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
74E074E374E774E974EE74F274F074F174F874F7750475037505750C750E750D
75157513751E7526752C753C7544754D754A7549755B7546755A756975647567
756B756D75787576758675877574758A758975827594759A759D75A575A375C2
75B375C375B575BD75B875BC75B175CD75CA75D275D975E375DE75FE75FF0000
75FC760175F075FA75F275F3760B760D7609761F762776207621762276247634
7630763B764776487646765C76587661766276687669766A7667766C76707672
76767678767C768076837688768B768E769676937699769A76B076B476B876B9
76BA76C276CD76D676D276DE76E176E576E776EA862F76FB7708770777047729
7724771E77257726771B773777387747775A7768776B775B7765777F777E7779
778E778B779177A0779E77B077B677B977BF77BC77BD77BB77C777CD77D777DA
77DC77E377EE77FC780C781279267820792A7845788E78747886787C789A788C
78A378B578AA78AF78D178C678CB78D478BE78BC78C578CA78EC000000000000
E2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
78E778DA78FD78F47907791279117919792C792B794079607957795F795A7955
7953797A797F798A799D79A79F4B79AA79AE79B379B979BA79C979D579E779EC
79E179E37A087A0D7A187A197A207A1F79807A317A3B7A3E7A377A437A577A49
7A617A627A699F9D7A707A797A7D7A887A977A957A987A967AA97AC87AB00000
7AB67AC57AC47ABF90837AC77ACA7ACD7ACF7AD57AD37AD97ADA7ADD7AE17AE2
7AE67AED7AF07B027B0F7B0A7B067B337B187B197B1E7B357B287B367B507B7A
7B047B4D7B0B7B4C7B457B757B657B747B677B707B717B6C7B6E7B9D7B987B9F
7B8D7B9C7B9A7B8B7B927B8F7B5D7B997BCB7BC17BCC7BCF7BB47BC67BDD7BE9
7C117C147BE67BE57C607C007C077C137BF37BF77C177C0D7BF67C237C277C2A
7C1F7C377C2B7C3D7C4C7C437C547C4F7C407C507C587C5F7C647C567C657C6C
7C757C837C907CA47CAD7CA27CAB7CA17CA87CB37CB27CB17CAE7CB97CBD7CC0
7CC57CC27CD87CD27CDC7CE29B3B7CEF7CF27CF47CF67CFA7D06000000000000
E3
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
7D027D1C7D157D0A7D457D4B7D2E7D327D3F7D357D467D737D567D4E7D727D68
7D6E7D4F7D637D937D897D5B7D8F7D7D7D9B7DBA7DAE7DA37DB57DC77DBD7DAB
7E3D7DA27DAF7DDC7DB87D9F7DB07DD87DDD7DE47DDE7DFB7DF27DE17E057E0A
7E237E217E127E317E1F7E097E0B7E227E467E667E3B7E357E397E437E370000
7E327E3A7E677E5D7E567E5E7E597E5A7E797E6A7E697E7C7E7B7E837DD57E7D
8FAE7E7F7E887E897E8C7E927E907E937E947E967E8E7E9B7E9C7F387F3A7F45
7F4C7F4D7F4E7F507F517F557F547F587F5F7F607F687F697F677F787F827F86
7F837F887F877F8C7F947F9E7F9D7F9A7FA37FAF7FB27FB97FAE7FB67FB88B71
7FC57FC67FCA7FD57FD47FE17FE67FE97FF37FF998DC80068004800B80128018
8019801C80218028803F803B804A804680528058805A805F8062806880738072
807080768079807D807F808480868085809B8093809A80AD519080AC80DB80E5
80D980DD80C480DA80D6810980EF80F1811B81298123812F814B000000000000
E4
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
968B8146813E8153815180FC8171816E81658166817481838188818A81808182
81A0819581A481A3815F819381A981B081B581BE81B881BD81C081C281BA81C9
81CD81D181D981D881C881DA81DF81E081E781FA81FB81FE8201820282058207
820A820D821082168229822B82388233824082598258825D825A825F82640000
82628268826A826B822E827182778278827E828D829282AB829F82BB82AC82E1
82E382DF82D282F482F382FA8393830382FB82F982DE830682DC830982D98335
83348316833283318340833983508345832F832B831783188385839A83AA839F
83A283968323838E8387838A837C83B58373837583A0838983A883F4841383EB
83CE83FD840383D8840B83C183F7840783E083F2840D8422842083BD84388506
83FB846D842A843C855A84848477846B84AD846E848284698446842C846F8479
843584CA846284B984BF849F84D984CD84BB84DA84D084C184C684D684A18521
84FF84F485178518852C851F8515851484FC8540856385588548000000000000
E5
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
85418602854B8555858085A485888591858A85A8856D8594859B85EA8587859C
8577857E859085C985BA85CF85B985D085D585DD85E585DC85F9860A8613860B
85FE85FA86068622861A8630863F864D4E558654865F86678671869386A386A9
86AA868B868C86B686AF86C486C686B086C9882386AB86D486DE86E986EC0000
86DF86DB86EF8712870687088700870386FB87118709870D86F9870A8734873F
8737873B87258729871A8760875F8778874C874E877487578768876E87598753
8763876A880587A2879F878287AF87CB87BD87C087D096D687AB87C487B387C7
87C687BB87EF87F287E0880F880D87FE87F687F7880E87D28811881688158822
88218831883688398827883B8844884288528859885E8862886B8881887E889E
8875887D88B5887288828897889288AE889988A2888D88A488B088BF88B188C3
88C488D488D888D988DD88F9890288FC88F488E888F28904890C890A89138943
891E8925892A892B89418944893B89368938894C891D8960895E000000000000
E6
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
89668964896D896A896F89748977897E89838988898A8993899889A189A989A6
89AC89AF89B289BA89BD89BF89C089DA89DC89DD89E789F489F88A038A168A10
8A0C8A1B8A1D8A258A368A418A5B8A528A468A488A7C8A6D8A6C8A628A858A82
8A848AA88AA18A918AA58AA68A9A8AA38AC48ACD8AC28ADA8AEB8AF38AE70000
8AE48AF18B148AE08AE28AF78ADE8ADB8B0C8B078B1A8AE18B168B108B178B20
8B3397AB8B268B2B8B3E8B288B418B4C8B4F8B4E8B498B568B5B8B5A8B6B8B5F
8B6C8B6F8B748B7D8B808B8C8B8E8B928B938B968B998B9A8C3A8C418C3F8C48
8C4C8C4E8C508C558C628C6C8C788C7A8C828C898C858C8A8C8D8C8E8C948C7C
8C98621D8CAD8CAA8CBD8CB28CB38CAE8CB68CC88CC18CE48CE38CDA8CFD8CFA
8CFB8D048D058D0A8D078D0F8D0D8D109F4E8D138CCD8D148D168D678D6D8D71
8D738D818D998DC28DBE8DBA8DCF8DDA8DD68DCC8DDB8DCB8DEA8DEB8DDF8DE3
8DFC8E088E098DFF8E1D8E1E8E108E1F8E428E358E308E348E4A000000000000
E7
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
8E478E498E4C8E508E488E598E648E608E2A8E638E558E768E728E7C8E818E87
8E858E848E8B8E8A8E938E918E948E998EAA8EA18EAC8EB08EC68EB18EBE8EC5
8EC88ECB8EDB8EE38EFC8EFB8EEB8EFE8F0A8F058F158F128F198F138F1C8F1F
8F1B8F0C8F268F338F3B8F398F458F428F3E8F4C8F498F468F4E8F578F5C0000
8F628F638F648F9C8F9F8FA38FAD8FAF8FB78FDA8FE58FE28FEA8FEF90878FF4
90058FF98FFA901190159021900D901E9016900B90279036903590398FF8904F
905090519052900E9049903E90569058905E9068906F907696A890729082907D
90819080908A9089908F90A890AF90B190B590E290E4624890DB910291129119
91329130914A9156915891639165916991739172918B9189918291A291AB91AF
91AA91B591B491BA91C091C191C991CB91D091D691DF91E191DB91FC91F591F6
921E91FF9214922C92159211925E925792459249926492489295923F924B9250
929C92969293929B925A92CF92B992B792E9930F92FA9344932E000000000000
E8
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
93199322931A9323933A9335933B935C9360937C936E935693B093AC93AD9394
93B993D693D793E893E593D893C393DD93D093C893E4941A9414941394039407
94109436942B94359421943A944194529444945B94609462945E946A92299470
94759477947D945A947C947E9481947F95829587958A95949596959895990000
95A095A895A795AD95BC95BB95B995BE95CA6FF695C395CD95CC95D595D495D6
95DC95E195E595E296219628962E962F9642964C964F964B9677965C965E965D
965F96669672966C968D96989695969796AA96A796B196B296B096B496B696B8
96B996CE96CB96C996CD894D96DC970D96D596F99704970697089713970E9711
970F971697199724972A97309739973D973E97449746974897429749975C9760
97649766976852D2976B977197799785977C9781977A9786978B978F9790979C
97A897A697A397B397B497C397C697C897CB97DC97ED9F4F97F27ADF97F697F5
980F980C9838982498219837983D9846984F984B986B986F9870000000000000
E9
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
98719874987398AA98AF98B198B698C498C398C698E998EB9903990999129914
99189921991D991E99249920992C992E993D993E9942994999459950994B9951
9952994C99559997999899A599AD99AE99BC99DF99DB99DD99D899D199ED99EE
99F199F299FB99F89A019A0F9A0599E29A199A2B9A379A459A429A409A430000
9A3E9A559A4D9A5B9A579A5F9A629A659A649A699A6B9A6A9AAD9AB09ABC9AC0
9ACF9AD19AD39AD49ADE9ADF9AE29AE39AE69AEF9AEB9AEE9AF49AF19AF79AFB
9B069B189B1A9B1F9B229B239B259B279B289B299B2A9B2E9B2F9B329B449B43
9B4F9B4D9B4E9B519B589B749B939B839B919B969B979B9F9BA09BA89BB49BC0
9BCA9BB99BC69BCF9BD19BD29BE39BE29BE49BD49BE19C3A9BF29BF19BF09C15
9C149C099C139C0C9C069C089C129C0A9C049C2E9C1B9C259C249C219C309C47
9C329C469C3E9C5A9C609C679C769C789CE79CEC9CF09D099D089CEB9D039D06
9D2A9D269DAF9D239D1F9D449D159D129D419D3F9D3E9D469D48000000000000
EA
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
9D5D9D5E9D649D519D509D599D729D899D879DAB9D6F9D7A9D9A9DA49DA99DB2
9DC49DC19DBB9DB89DBA9DC69DCF9DC29DD99DD39DF89DE69DED9DEF9DFD9E1A
9E1B9E1E9E759E799E7D9E819E889E8B9E8C9E929E959E919E9D9EA59EA99EB8
9EAA9EAD97619ECC9ECE9ECF9ED09ED49EDC9EDE9EDD9EE09EE59EE89EEF0000
9EF49EF69EF79EF99EFB9EFC9EFD9F079F0876B79F159F219F2C9F3E9F4A9F52
9F549F639F5F9F609F619F669F679F6C9F6A9F779F729F769F959F9C9FA0582F
69C79059746451DC719900000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000

Added library/encoding/symbol.enc.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: symbol, single-byte
S
003F 1 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002122000023220300250026220D002800292217002B002C2212002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
22450391039203A70394039503A603930397039903D1039A039B039C039D039F
03A0039803A103A303A403A503C203A9039E03A80396005B2234005D22A5005F
F8E503B103B203C703B403B503C603B303B703B903D503BA03BB03BC03BD03BF
03C003B803C103C303C403C503D603C903BE03C803B6007B007C007D223C007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
000003D2203222642044221E0192266326662665266021942190219121922193
00B000B12033226500D7221D2202202200F72260226122482026F8E6F8E721B5
21352111211C21182297229522052229222A2283228722842282228622082209
2220220700AE00A92122220F221A22C500AC2227222821D421D021D121D221D3
22C42329F8E8F8E9F8EA2211F8EBF8ECF8EDF8EEF8EFF8F0F8F1F8F2F8F3F8F4
F8FF232A222B2320F8F52321F8F6F8F7F8F8F8F9F8FAF8FBF8FCF8FDF8FE0000

Changes to library/history.tcl.

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
# history.tcl --
#
# Implementation of the history command.
#
# SCCS: @(#) history.tcl 1.7 97/08/07 16:45:50
#
# 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.
#

# The tcl::history array holds the history list and
# some additional bookkeeping variables.
#
# nextid	the index used for the next history list item.
# keep		the max size of the history list
# oldest	the index of the oldest item in the history.

namespace eval tcl {
    variable history
    if ![info exists history] {
	array set history {
	    nextid	0
	    keep	20
	    oldest	-20
	}
    }
}




|
















|







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
# history.tcl --
#
# Implementation of the history command.
#
# RCS: @(#) $Id: history.tcl,v 1.1.2.2 1998/09/24 23:59:05 stanton Exp $
#
# 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.
#

# The tcl::history array holds the history list and
# some additional bookkeeping variables.
#
# nextid	the index used for the next history list item.
# keep		the max size of the history list
# oldest	the index of the oldest item in the history.

namespace eval tcl {
    variable history
    if {![info exists history]} {
	array set history {
	    nextid	0
	    keep	20
	    oldest	-20
	}
    }
}
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
	    if {$len > 2} {
		return -code error "wrong # args: should be \"history keep ?count?\""
	    }
	    if {$len == 1} {
		return [tcl::HistKeep]
	    } else {
		set limit [lindex $args 1]
		if {[catch {expr $limit}] || ($limit < 0)} {
		    return -code error "illegal keep count \"$limit\""
		}
		return [tcl::HistKeep $limit]
	    }
	}
	n* { # history nextid

	    if {$len > 1} {
		return -code error "wrong # args: should be \"history nextid\""
	    }
	    if {![string match $key* nextid]} {
		return -code error "bad option \"$key\": must be $options"
	    }
	    return [expr $tcl::history(nextid) + 1]
	}
	r* { # history redo

	    if {$len > 2} {
		return -code error "wrong # args: should be \"history redo ?event?\""
	    }
	    if {![string match $key* redo]} {







|













|







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
	    if {$len > 2} {
		return -code error "wrong # args: should be \"history keep ?count?\""
	    }
	    if {$len == 1} {
		return [tcl::HistKeep]
	    } else {
		set limit [lindex $args 1]
		if {[catch {expr {~$limit}}] || ($limit < 0)} {
		    return -code error "illegal keep count \"$limit\""
		}
		return [tcl::HistKeep $limit]
	    }
	}
	n* { # history nextid

	    if {$len > 1} {
		return -code error "wrong # args: should be \"history nextid\""
	    }
	    if {![string match $key* nextid]} {
		return -code error "bad option \"$key\": must be $options"
	    }
	    return [expr {$tcl::history(nextid) + 1}]
	}
	r* { # history redo

	    if {$len > 2} {
		return -code error "wrong # args: should be \"history redo ?event?\""
	    }
	    if {![string match $key* redo]} {
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

 proc tcl::HistKeep {{limit {}}} {
    variable history
    if {[string length $limit] == 0} {
	return $history(keep)
    } else {
	set oldold $history(oldest)
	set history(oldest) [expr $history(nextid) - $limit]
	for {} {$oldold <= $history(oldest)} {incr oldold} {
	    if {[info exists history($oldold)]} {unset history($oldold)}
	}
	set history(keep) $limit
    }
}








|







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

 proc tcl::HistKeep {{limit {}}} {
    variable history
    if {[string length $limit] == 0} {
	return $history(keep)
    } else {
	set oldold $history(oldest)
	set history(oldest) [expr {$history(nextid) - $limit}]
	for {} {$oldold <= $history(oldest)} {incr oldold} {
	    if {[info exists history($oldold)]} {unset history($oldold)}
	}
	set history(keep) $limit
    }
}

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#
# Results:
#	A formatted history list

 proc tcl::HistInfo {{num {}}} {
    variable history
    if {$num == {}} {
	set num [expr $history(keep) + 1]
    }
    set result {}
    set newline ""
    for {set i [expr $history(nextid) - $num + 1]} \
	    {$i <= $history(nextid)} {incr i} {
	if ![info exists history($i)] {
	    continue
	}
	set cmd [string trimright $history($i) \ \n]
	regsub -all \n $cmd "\n\t" cmd
	append result $newline[format "%6d  %s" $i $cmd]
	set newline \n
    }







|



|

|







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#
# Results:
#	A formatted history list

 proc tcl::HistInfo {{num {}}} {
    variable history
    if {$num == {}} {
	set num [expr {$history(keep) + 1}]
    }
    set result {}
    set newline ""
    for {set i [expr {$history(nextid) - $num + 1}]} \
	    {$i <= $history(nextid)} {incr i} {
	if {![info exists history($i)]} {
	    continue
	}
	set cmd [string trimright $history($i) \ \n]
	regsub -all \n $cmd "\n\t" cmd
	append result $newline[format "%6d  %s" $i $cmd]
	set newline \n
    }
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
#		a command or by matching a command with string match.
#
# Results:
#	The index into history, or an error if the index didn't match.

 proc tcl::HistIndex {event} {
    variable history
    if {[catch {expr $event}]} {
	for {set i $history(nextid)} {[info exists history($i)]} {incr i -1} {
	    if {[string match $event* $history($i)]} {
		return $i;
	    }
	    if {[string match $event $history($i)]} {
		return $i;
	    }
	}
	return -code error "no event matches \"$event\""
    } elseif {$event <= 0} {
	set i [expr $history(nextid) + $event]
    } else {
	set i $event
    }
    if {$i <= $history(oldest)} {
	return -code error "event \"$event\" is too far in the past"
    }
    if {$i > $history(nextid)} {







|










|







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
#		a command or by matching a command with string match.
#
# Results:
#	The index into history, or an error if the index didn't match.

 proc tcl::HistIndex {event} {
    variable history
    if {[catch {expr {~$event}}]} {
	for {set i $history(nextid)} {[info exists history($i)]} {incr i -1} {
	    if {[string match $event* $history($i)]} {
		return $i;
	    }
	    if {[string match $event $history($i)]} {
		return $i;
	    }
	}
	return -code error "no event matches \"$event\""
    } elseif {$event <= 0} {
	set i [expr {$history(nextid) + $event}]
    } else {
	set i $event
    }
    if {$i <= $history(oldest)} {
	return -code error "event \"$event\" is too far in the past"
    }
    if {$i > $history(nextid)} {

Changes to library/http/http.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# http.tcl --
#
#	Client-side HTTP for GET, POST, and HEAD commands.
#	These routines can be used in untrusted code that uses 
#	the Safesock security policy.  These procedures use a 
#	callback interface to avoid using vwait, which is not 
#	defined in the safe base.
#
# See the file "license.terms" for information on usage and
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) http.tcl 1.8 97/10/28 16:23:30

package provide http 2.0	;# This uses Tcl namespaces

namespace eval http {
    variable http

    array set http {











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# http.tcl --
#
#	Client-side HTTP for GET, POST, and HEAD commands.
#	These routines can be used in untrusted code that uses 
#	the Safesock security policy.  These procedures use a 
#	callback interface to avoid using vwait, which is not 
#	defined in the safe base.
#
# See the file "license.terms" for information on usage and
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: http.tcl,v 1.1.2.4 1999/02/10 23:31:21 stanton Exp $

package provide http 2.0	;# This uses Tcl namespaces

namespace eval http {
    variable http

    array set http {
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	if {[regexp -- $pat $flag]} {
	    return $http($flag)
	} else {
	    return -code error "Unknown option $flag, must be: $usage"
	}
    } else {
	foreach {flag value} $args {
	    if [regexp -- $pat $flag] {
		set http($flag) $value
	    } else {
		return -code error "Unknown option $flag, must be: $usage"
	    }
	}
    }
}







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	if {[regexp -- $pat $flag]} {
	    return $http($flag)
	} else {
	    return -code error "Unknown option $flag, must be: $usage"
	}
    } else {
	foreach {flag value} $args {
	    if {[regexp -- $pat $flag]} {
		set http($flag) $value
	    } else {
		return -code error "Unknown option $flag, must be: $usage"
	    }
	}
    }
}
95
96
97
98
99
100
101


102

103
104
105
106
107
108
109
    if {[info exists state(-command)]} {
	if {[catch {eval $state(-command) {$token}} err]} {
	    if {[string length $errormsg] == 0} {
		set state(error) [list $err $errorInfo $errorCode]
		set state(status) error
	    }
	}


	unset state(-command)

    }
}

# http::reset --
#
#	See documentaion for details.
#







>
>
|
>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    if {[info exists state(-command)]} {
	if {[catch {eval $state(-command) {$token}} err]} {
	    if {[string length $errormsg] == 0} {
		set state(error) [list $err $errorInfo $errorCode]
		set state(status) error
	    }
	}
	if {[info exist state(-command)]} {
	    # Command callback may already have unset our state
	    unset state(-command)
	}
    }
}

# http::reset --
#
#	See documentaion for details.
#
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#				-blocksize, -validate, -headers, -timeout
# Results:
#        Returns a token for this connection.


proc http::geturl { url args } {
    variable http
    if ![info exists http(uid)] {
	set http(uid) 0
    }
    set token [namespace current]::[incr http(uid)]
    variable $token
    upvar 0 $token state
    reset $token
    array set state {







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#				-blocksize, -validate, -headers, -timeout
# Results:
#        Returns a token for this connection.


proc http::geturl { url args } {
    variable http
    if {![info exists http(uid)]} {
	set http(uid) 0
    }
    set token [namespace current]::[incr http(uid)]
    variable $token
    upvar 0 $token state
    reset $token
    array set state {
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    }
    set options {-blocksize -channel -command -handler -headers \
		-progress -query -validate -timeout}
    set usage [join $options ", "]
    regsub -all -- - $options {} options
    set pat ^-([join $options |])$
    foreach {flag value} $args {
	if [regexp $pat $flag] {
	    # Validate numbers
	    if {[info exists state($flag)] && \
		    [regexp {^[0-9]+$} $state($flag)] && \
		    ![regexp {^[0-9]+$} $value]} {
		return -code error "Bad value for $flag ($value), must be integer"
	    }
	    set state($flag) $value







|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    }
    set options {-blocksize -channel -command -handler -headers \
		-progress -query -validate -timeout}
    set usage [join $options ", "]
    regsub -all -- - $options {} options
    set pat ^-([join $options |])$
    foreach {flag value} $args {
	if {[regexp $pat $flag]} {
	    # Validate numbers
	    if {[info exists state($flag)] && \
		    [regexp {^[0-9]+$} $state($flag)] && \
		    ![regexp {^[0-9]+$} $value]} {
		return -code error "Bad value for $flag ($value), must be integer"
	    }
	    set state($flag) $value
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
}

 proc http::Event {token} {
    variable $token
    upvar 0 $token state
    set s $state(sock)

    if [::eof $s] then {
	Eof $token
	return
    }
    if {$state(state) == "header"} {
	set n [gets $s line]
	if {$n == 0} {
	    set state(state) body
	    if ![regexp -nocase ^text $state(type)] {
		# Turn off conversions for non-text data
		fconfigure $s -translation binary
		if {[info exists state(-channel)]} {
		    fconfigure $state(-channel) -translation binary
		}
	    }
	    if {[info exists state(-channel)] &&
		    ![info exists state(-handler)]} {
		# Initiate a sequence of background fcopies
		fileevent $s readable {}
		CopyStart $s $token
	    }
	} elseif {$n > 0} {
	    if [regexp -nocase {^content-type:(.+)$} $line x type] {
		set state(type) [string trim $type]
	    }
	    if [regexp -nocase {^content-length:(.+)$} $line x length] {
		set state(totalsize) [string trim $length]
	    }
	    if [regexp -nocase {^([^:]+):(.+)$} $line x key value] {
		lappend state(meta) $key $value
	    } elseif {[regexp ^HTTP $line]} {
		set state(http) $line
	    }
	}
    } else {
	if [catch {
	    if {[info exists state(-handler)]} {
		set n [eval $state(-handler) {$s $token}]
	    } else {
		set block [read $s $state(-blocksize)]
		set n [string length $block]
		if {$n >= 0} {
		    append state(body) $block
		}
	    }
	    if {$n >= 0} {
		incr state(currentsize) $n
	    }
	} err] {
	    Finish $token $err
	} else {
	    if [info exists state(-progress)] {
		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
	    }
	}
    }
}
 proc http::CopyStart {s token} {
    variable $token
    upvar 0 $token state
    if [catch {
	fcopy $s $state(-channel) -size $state(-blocksize) -command \
	    [list http::CopyDone $token]
    } err] {
	Finish $token $err
    }
}
 proc http::CopyDone {token count {error {}}} {
    variable $token
    upvar 0 $token state
    set s $state(sock)
    incr state(currentsize) $count
    if [info exists state(-progress)] {
	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
    }

    if {([string length $error] != 0)} {
	Finish $token $error
    } elseif {[::eof $s]} {
	Eof $token
    } else {
	CopyStart $s $token
    }
}
 proc http::Eof {token} {
    variable $token







|







|













|


|


|






|












|


|








|


|








|


>


|







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
}

 proc http::Event {token} {
    variable $token
    upvar 0 $token state
    set s $state(sock)

     if {[::eof $s]} {
	Eof $token
	return
    }
    if {$state(state) == "header"} {
	set n [gets $s line]
	if {$n == 0} {
	    set state(state) body
	    if {![regexp -nocase ^text $state(type)]} {
		# Turn off conversions for non-text data
		fconfigure $s -translation binary
		if {[info exists state(-channel)]} {
		    fconfigure $state(-channel) -translation binary
		}
	    }
	    if {[info exists state(-channel)] &&
		    ![info exists state(-handler)]} {
		# Initiate a sequence of background fcopies
		fileevent $s readable {}
		CopyStart $s $token
	    }
	} elseif {$n > 0} {
	    if {[regexp -nocase {^content-type:(.+)$} $line x type]} {
		set state(type) [string trim $type]
	    }
	    if {[regexp -nocase {^content-length:(.+)$} $line x length]} {
		set state(totalsize) [string trim $length]
	    }
	    if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
		lappend state(meta) $key $value
	    } elseif {[regexp ^HTTP $line]} {
		set state(http) $line
	    }
	}
    } else {
	if {[catch {
	    if {[info exists state(-handler)]} {
		set n [eval $state(-handler) {$s $token}]
	    } else {
		set block [read $s $state(-blocksize)]
		set n [string length $block]
		if {$n >= 0} {
		    append state(body) $block
		}
	    }
	    if {$n >= 0} {
		incr state(currentsize) $n
	    }
	} err]} {
	    Finish $token $err
	} else {
	    if {[info exists state(-progress)]} {
		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
	    }
	}
    }
}
 proc http::CopyStart {s token} {
    variable $token
    upvar 0 $token state
    if {[catch {
	fcopy $s $state(-channel) -size $state(-blocksize) -command \
	    [list http::CopyDone $token]
    } err]} {
	Finish $token $err
    }
}
 proc http::CopyDone {token count {error {}}} {
    variable $token
    upvar 0 $token state
    set s $state(sock)
    incr state(currentsize) $count
    if {[info exists state(-progress)]} {
	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
    }
    # At this point the token may have been reset
    if {([string length $error] != 0)} {
	Finish $token $error
    } elseif {[catch {::eof $s} iseof] || $iseof} {
	Eof $token
    } else {
	CopyStart $s $token
    }
}
 proc http::Eof {token} {
    variable $token

Changes to library/http1.0/http.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# http.tcl
# Client-side HTTP for GET, POST, and HEAD commands.
# These routines can be used in untrusted code that uses the Safesock
# security policy.
# These procedures use a callback interface to avoid using vwait,
# which is not defined in the safe base.
#
# SCCS: @(#) http.tcl 1.10 97/10/29 16:12:55
#
# See the http.n man page for documentation

package provide http 1.0

array set http {
    -accept */*







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# http.tcl
# Client-side HTTP for GET, POST, and HEAD commands.
# These routines can be used in untrusted code that uses the Safesock
# security policy.
# These procedures use a callback interface to avoid using vwait,
# which is not defined in the safe base.
#
# RCS: @(#) $Id: http.tcl,v 1.1.2.2 1998/09/24 23:59:07 stanton Exp $
#
# See the http.n man page for documentation

package provide http 1.0

array set http {
    -accept */*
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	if {[regexp -- $pat $flag]} {
	    return $http($flag)
	} else {
	    return -code error "Unknown option $flag, must be: $usage"
	}
    } else {
	foreach {flag value} $args {
	    if [regexp -- $pat $flag] {
		set http($flag) $value
	    } else {
		return -code error "Unknown option $flag, must be: $usage"
	    }
	}
    }
}







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	if {[regexp -- $pat $flag]} {
	    return $http($flag)
	} else {
	    return -code error "Unknown option $flag, must be: $usage"
	}
    } else {
	foreach {flag value} $args {
	    if {[regexp -- $pat $flag]} {
		set http($flag) $value
	    } else {
		return -code error "Unknown option $flag, must be: $usage"
	    }
	}
    }
}
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	set errorlist $state(error)
	unset state(error)
	eval error $errorlist
    }
}
proc http_get { url args } {
    global http
    if ![info exists http(uid)] {
	set http(uid) 0
    }
    set token http#[incr http(uid)]
    upvar #0 $token state
    http_reset $token
    array set state {
	-blocksize 	8192







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	set errorlist $state(error)
	unset state(error)
	eval error $errorlist
    }
}
proc http_get { url args } {
    global http
    if {![info exists http(uid)]} {
	set http(uid) 0
    }
    set token http#[incr http(uid)]
    upvar #0 $token state
    http_reset $token
    array set state {
	-blocksize 	8192
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    }
    set options {-blocksize -channel -command -handler -headers \
		-progress -query -validate -timeout}
    set usage [join $options ", "]
    regsub -all -- - $options {} options
    set pat ^-([join $options |])$
    foreach {flag value} $args {
	if [regexp $pat $flag] {
	    # Validate numbers
	    if {[info exists state($flag)] && \
		    [regexp {^[0-9]+$} $state($flag)] && \
		    ![regexp {^[0-9]+$} $value]} {
		return -code error "Bad value for $flag ($value), must be integer"
	    }
	    set state($flag) $value







|







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    }
    set options {-blocksize -channel -command -handler -headers \
		-progress -query -validate -timeout}
    set usage [join $options ", "]
    regsub -all -- - $options {} options
    set pat ^-([join $options |])$
    foreach {flag value} $args {
	if {[regexp $pat $flag]} {
	    # Validate numbers
	    if {[info exists state($flag)] && \
		    [regexp {^[0-9]+$} $state($flag)] && \
		    ![regexp {^[0-9]+$} $value]} {
		return -code error "Bad value for $flag ($value), must be integer"
	    }
	    set state($flag) $value
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
    return $state(currentsize)
}

 proc httpEvent {token} {
    upvar #0 $token state
    set s $state(sock)

    if [eof $s] then {
	httpEof $token
	return
    }
    if {$state(state) == "header"} {
	set n [gets $s line]
	if {$n == 0} {
	    set state(state) body
	    if ![regexp -nocase ^text $state(type)] {
		# Turn off conversions for non-text data
		fconfigure $s -translation binary
		if {[info exists state(-channel)]} {
		    fconfigure $state(-channel) -translation binary
		}
	    }
	    if {[info exists state(-channel)] &&
		    ![info exists state(-handler)]} {
		# Initiate a sequence of background fcopies
		fileevent $s readable {}
		httpCopyStart $s $token
	    }
	} elseif {$n > 0} {
	    if [regexp -nocase {^content-type:(.+)$} $line x type] {
		set state(type) [string trim $type]
	    }
	    if [regexp -nocase {^content-length:(.+)$} $line x length] {
		set state(totalsize) [string trim $length]
	    }
	    if [regexp -nocase {^([^:]+):(.+)$} $line x key value] {
		lappend state(meta) $key $value
	    } elseif {[regexp ^HTTP $line]} {
		set state(http) $line
	    }
	}
    } else {
	if [catch {
	    if {[info exists state(-handler)]} {
		set n [eval $state(-handler) {$s $token}]
	    } else {
		set block [read $s $state(-blocksize)]
		set n [string length $block]
		if {$n >= 0} {
		    append state(body) $block
		}
	    }
	    if {$n >= 0} {
		incr state(currentsize) $n
	    }
	} err] {
	    httpFinish $token $err
	} else {
	    if [info exists state(-progress)] {
		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
	    }
	}
    }
}
 proc httpCopyStart {s token} {
    upvar #0 $token state
    if [catch {
	fcopy $s $state(-channel) -size $state(-blocksize) -command \
	    [list httpCopyDone $token]
    } err] {
	httpFinish $token $err
    }
}
 proc httpCopyDone {token count {error {}}} {
    upvar #0 $token state
    set s $state(sock)
    incr state(currentsize) $count
    if [info exists state(-progress)] {
	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
    }
    if {([string length $error] != 0)} {
	httpFinish $token $error
    } elseif {[eof $s]} {
	httpEof $token
    } else {







|







|













|


|


|






|












|


|







|


|







|







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
    return $state(currentsize)
}

 proc httpEvent {token} {
    upvar #0 $token state
    set s $state(sock)

     if {[eof $s]} {
	httpEof $token
	return
    }
    if {$state(state) == "header"} {
	set n [gets $s line]
	if {$n == 0} {
	    set state(state) body
	    if {![regexp -nocase ^text $state(type)]} {
		# Turn off conversions for non-text data
		fconfigure $s -translation binary
		if {[info exists state(-channel)]} {
		    fconfigure $state(-channel) -translation binary
		}
	    }
	    if {[info exists state(-channel)] &&
		    ![info exists state(-handler)]} {
		# Initiate a sequence of background fcopies
		fileevent $s readable {}
		httpCopyStart $s $token
	    }
	} elseif {$n > 0} {
	    if {[regexp -nocase {^content-type:(.+)$} $line x type]} {
		set state(type) [string trim $type]
	    }
	    if {[regexp -nocase {^content-length:(.+)$} $line x length]} {
		set state(totalsize) [string trim $length]
	    }
	    if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
		lappend state(meta) $key $value
	    } elseif {[regexp ^HTTP $line]} {
		set state(http) $line
	    }
	}
    } else {
	if {[catch {
	    if {[info exists state(-handler)]} {
		set n [eval $state(-handler) {$s $token}]
	    } else {
		set block [read $s $state(-blocksize)]
		set n [string length $block]
		if {$n >= 0} {
		    append state(body) $block
		}
	    }
	    if {$n >= 0} {
		incr state(currentsize) $n
	    }
	} err]} {
	    httpFinish $token $err
	} else {
	    if {[info exists state(-progress)]} {
		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
	    }
	}
    }
}
 proc httpCopyStart {s token} {
    upvar #0 $token state
    if {[catch {
	fcopy $s $state(-channel) -size $state(-blocksize) -command \
	    [list httpCopyDone $token]
    } err]} {
	httpFinish $token $err
    }
}
 proc httpCopyDone {token count {error {}}} {
    upvar #0 $token state
    set s $state(sock)
    incr state(currentsize) $count
    if {[info exists state(-progress)]} {
	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
    }
    if {([string length $error] != 0)} {
	httpFinish $token $error
    } elseif {[eof $s]} {
	httpEof $token
    } else {
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# 2 Convert every other character to an array lookup
# 3 Escape constructs that are "special" to the tcl parser
# 4 "subst" the result, doing all the array substitutions
 
 proc httpMapReply {string} {
    global httpFormMap
    set alphanumeric	a-zA-Z0-9
    if ![info exists httpFormMap] {
	 
	for {set i 1} {$i <= 256} {incr i} {
	    set c [format %c $i]
	    if {![string match \[$alphanumeric\] $c]} {
		set httpFormMap($c) %[format %.2x $i]
	    }
	}







|







341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# 2 Convert every other character to an array lookup
# 3 Escape constructs that are "special" to the tcl parser
# 4 "subst" the result, doing all the array substitutions
 
 proc httpMapReply {string} {
    global httpFormMap
    set alphanumeric	a-zA-Z0-9
    if {![info exists httpFormMap]} {
	 
	for {set i 1} {$i <= 256} {incr i} {
	    set c [format %c $i]
	    if {![string match \[$alphanumeric\] $c]} {
		set httpFormMap($c) %[format %.2x $i]
	    }
	}

Changes to library/http2.0/http.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# http.tcl --
#
#	Client-side HTTP for GET, POST, and HEAD commands.
#	These routines can be used in untrusted code that uses 
#	the Safesock security policy.  These procedures use a 
#	callback interface to avoid using vwait, which is not 
#	defined in the safe base.
#
# See the file "license.terms" for information on usage and
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) http.tcl 1.8 97/10/28 16:23:30

package provide http 2.0	;# This uses Tcl namespaces

namespace eval http {
    variable http

    array set http {











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# http.tcl --
#
#	Client-side HTTP for GET, POST, and HEAD commands.
#	These routines can be used in untrusted code that uses 
#	the Safesock security policy.  These procedures use a 
#	callback interface to avoid using vwait, which is not 
#	defined in the safe base.
#
# See the file "license.terms" for information on usage and
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: http.tcl,v 1.1.2.4 1999/02/10 23:31:21 stanton Exp $

package provide http 2.0	;# This uses Tcl namespaces

namespace eval http {
    variable http

    array set http {
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	if {[regexp -- $pat $flag]} {
	    return $http($flag)
	} else {
	    return -code error "Unknown option $flag, must be: $usage"
	}
    } else {
	foreach {flag value} $args {
	    if [regexp -- $pat $flag] {
		set http($flag) $value
	    } else {
		return -code error "Unknown option $flag, must be: $usage"
	    }
	}
    }
}







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	if {[regexp -- $pat $flag]} {
	    return $http($flag)
	} else {
	    return -code error "Unknown option $flag, must be: $usage"
	}
    } else {
	foreach {flag value} $args {
	    if {[regexp -- $pat $flag]} {
		set http($flag) $value
	    } else {
		return -code error "Unknown option $flag, must be: $usage"
	    }
	}
    }
}
95
96
97
98
99
100
101


102

103
104
105
106
107
108
109
    if {[info exists state(-command)]} {
	if {[catch {eval $state(-command) {$token}} err]} {
	    if {[string length $errormsg] == 0} {
		set state(error) [list $err $errorInfo $errorCode]
		set state(status) error
	    }
	}


	unset state(-command)

    }
}

# http::reset --
#
#	See documentaion for details.
#







>
>
|
>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    if {[info exists state(-command)]} {
	if {[catch {eval $state(-command) {$token}} err]} {
	    if {[string length $errormsg] == 0} {
		set state(error) [list $err $errorInfo $errorCode]
		set state(status) error
	    }
	}
	if {[info exist state(-command)]} {
	    # Command callback may already have unset our state
	    unset state(-command)
	}
    }
}

# http::reset --
#
#	See documentaion for details.
#
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#				-blocksize, -validate, -headers, -timeout
# Results:
#        Returns a token for this connection.


proc http::geturl { url args } {
    variable http
    if ![info exists http(uid)] {
	set http(uid) 0
    }
    set token [namespace current]::[incr http(uid)]
    variable $token
    upvar 0 $token state
    reset $token
    array set state {







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#				-blocksize, -validate, -headers, -timeout
# Results:
#        Returns a token for this connection.


proc http::geturl { url args } {
    variable http
    if {![info exists http(uid)]} {
	set http(uid) 0
    }
    set token [namespace current]::[incr http(uid)]
    variable $token
    upvar 0 $token state
    reset $token
    array set state {
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    }
    set options {-blocksize -channel -command -handler -headers \
		-progress -query -validate -timeout}
    set usage [join $options ", "]
    regsub -all -- - $options {} options
    set pat ^-([join $options |])$
    foreach {flag value} $args {
	if [regexp $pat $flag] {
	    # Validate numbers
	    if {[info exists state($flag)] && \
		    [regexp {^[0-9]+$} $state($flag)] && \
		    ![regexp {^[0-9]+$} $value]} {
		return -code error "Bad value for $flag ($value), must be integer"
	    }
	    set state($flag) $value







|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    }
    set options {-blocksize -channel -command -handler -headers \
		-progress -query -validate -timeout}
    set usage [join $options ", "]
    regsub -all -- - $options {} options
    set pat ^-([join $options |])$
    foreach {flag value} $args {
	if {[regexp $pat $flag]} {
	    # Validate numbers
	    if {[info exists state($flag)] && \
		    [regexp {^[0-9]+$} $state($flag)] && \
		    ![regexp {^[0-9]+$} $value]} {
		return -code error "Bad value for $flag ($value), must be integer"
	    }
	    set state($flag) $value
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
}

 proc http::Event {token} {
    variable $token
    upvar 0 $token state
    set s $state(sock)

    if [::eof $s] then {
	Eof $token
	return
    }
    if {$state(state) == "header"} {
	set n [gets $s line]
	if {$n == 0} {
	    set state(state) body
	    if ![regexp -nocase ^text $state(type)] {
		# Turn off conversions for non-text data
		fconfigure $s -translation binary
		if {[info exists state(-channel)]} {
		    fconfigure $state(-channel) -translation binary
		}
	    }
	    if {[info exists state(-channel)] &&
		    ![info exists state(-handler)]} {
		# Initiate a sequence of background fcopies
		fileevent $s readable {}
		CopyStart $s $token
	    }
	} elseif {$n > 0} {
	    if [regexp -nocase {^content-type:(.+)$} $line x type] {
		set state(type) [string trim $type]
	    }
	    if [regexp -nocase {^content-length:(.+)$} $line x length] {
		set state(totalsize) [string trim $length]
	    }
	    if [regexp -nocase {^([^:]+):(.+)$} $line x key value] {
		lappend state(meta) $key $value
	    } elseif {[regexp ^HTTP $line]} {
		set state(http) $line
	    }
	}
    } else {
	if [catch {
	    if {[info exists state(-handler)]} {
		set n [eval $state(-handler) {$s $token}]
	    } else {
		set block [read $s $state(-blocksize)]
		set n [string length $block]
		if {$n >= 0} {
		    append state(body) $block
		}
	    }
	    if {$n >= 0} {
		incr state(currentsize) $n
	    }
	} err] {
	    Finish $token $err
	} else {
	    if [info exists state(-progress)] {
		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
	    }
	}
    }
}
 proc http::CopyStart {s token} {
    variable $token
    upvar 0 $token state
    if [catch {
	fcopy $s $state(-channel) -size $state(-blocksize) -command \
	    [list http::CopyDone $token]
    } err] {
	Finish $token $err
    }
}
 proc http::CopyDone {token count {error {}}} {
    variable $token
    upvar 0 $token state
    set s $state(sock)
    incr state(currentsize) $count
    if [info exists state(-progress)] {
	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
    }

    if {([string length $error] != 0)} {
	Finish $token $error
    } elseif {[::eof $s]} {
	Eof $token
    } else {
	CopyStart $s $token
    }
}
 proc http::Eof {token} {
    variable $token







|







|













|


|


|






|












|


|








|


|








|


>


|







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
}

 proc http::Event {token} {
    variable $token
    upvar 0 $token state
    set s $state(sock)

     if {[::eof $s]} {
	Eof $token
	return
    }
    if {$state(state) == "header"} {
	set n [gets $s line]
	if {$n == 0} {
	    set state(state) body
	    if {![regexp -nocase ^text $state(type)]} {
		# Turn off conversions for non-text data
		fconfigure $s -translation binary
		if {[info exists state(-channel)]} {
		    fconfigure $state(-channel) -translation binary
		}
	    }
	    if {[info exists state(-channel)] &&
		    ![info exists state(-handler)]} {
		# Initiate a sequence of background fcopies
		fileevent $s readable {}
		CopyStart $s $token
	    }
	} elseif {$n > 0} {
	    if {[regexp -nocase {^content-type:(.+)$} $line x type]} {
		set state(type) [string trim $type]
	    }
	    if {[regexp -nocase {^content-length:(.+)$} $line x length]} {
		set state(totalsize) [string trim $length]
	    }
	    if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
		lappend state(meta) $key $value
	    } elseif {[regexp ^HTTP $line]} {
		set state(http) $line
	    }
	}
    } else {
	if {[catch {
	    if {[info exists state(-handler)]} {
		set n [eval $state(-handler) {$s $token}]
	    } else {
		set block [read $s $state(-blocksize)]
		set n [string length $block]
		if {$n >= 0} {
		    append state(body) $block
		}
	    }
	    if {$n >= 0} {
		incr state(currentsize) $n
	    }
	} err]} {
	    Finish $token $err
	} else {
	    if {[info exists state(-progress)]} {
		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
	    }
	}
    }
}
 proc http::CopyStart {s token} {
    variable $token
    upvar 0 $token state
    if {[catch {
	fcopy $s $state(-channel) -size $state(-blocksize) -command \
	    [list http::CopyDone $token]
    } err]} {
	Finish $token $err
    }
}
 proc http::CopyDone {token count {error {}}} {
    variable $token
    upvar 0 $token state
    set s $state(sock)
    incr state(currentsize) $count
    if {[info exists state(-progress)]} {
	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
    }
    # At this point the token may have been reset
    if {([string length $error] != 0)} {
	Finish $token $error
    } elseif {[catch {::eof $s} iseof] || $iseof} {
	Eof $token
    } else {
	CopyStart $s $token
    }
}
 proc http::Eof {token} {
    variable $token

Changes to library/http2.1/http.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# http.tcl --
#
#	Client-side HTTP for GET, POST, and HEAD commands.
#	These routines can be used in untrusted code that uses 
#	the Safesock security policy.  These procedures use a 
#	callback interface to avoid using vwait, which is not 
#	defined in the safe base.
#
# See the file "license.terms" for information on usage and
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) http.tcl 1.8 97/10/28 16:23:30

package provide http 2.0	;# This uses Tcl namespaces

namespace eval http {
    variable http

    array set http {











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# http.tcl --
#
#	Client-side HTTP for GET, POST, and HEAD commands.
#	These routines can be used in untrusted code that uses 
#	the Safesock security policy.  These procedures use a 
#	callback interface to avoid using vwait, which is not 
#	defined in the safe base.
#
# See the file "license.terms" for information on usage and
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: http.tcl,v 1.1.2.4 1999/02/10 23:31:21 stanton Exp $

package provide http 2.0	;# This uses Tcl namespaces

namespace eval http {
    variable http

    array set http {
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	if {[regexp -- $pat $flag]} {
	    return $http($flag)
	} else {
	    return -code error "Unknown option $flag, must be: $usage"
	}
    } else {
	foreach {flag value} $args {
	    if [regexp -- $pat $flag] {
		set http($flag) $value
	    } else {
		return -code error "Unknown option $flag, must be: $usage"
	    }
	}
    }
}







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	if {[regexp -- $pat $flag]} {
	    return $http($flag)
	} else {
	    return -code error "Unknown option $flag, must be: $usage"
	}
    } else {
	foreach {flag value} $args {
	    if {[regexp -- $pat $flag]} {
		set http($flag) $value
	    } else {
		return -code error "Unknown option $flag, must be: $usage"
	    }
	}
    }
}
95
96
97
98
99
100
101


102

103
104
105
106
107
108
109
    if {[info exists state(-command)]} {
	if {[catch {eval $state(-command) {$token}} err]} {
	    if {[string length $errormsg] == 0} {
		set state(error) [list $err $errorInfo $errorCode]
		set state(status) error
	    }
	}


	unset state(-command)

    }
}

# http::reset --
#
#	See documentaion for details.
#







>
>
|
>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    if {[info exists state(-command)]} {
	if {[catch {eval $state(-command) {$token}} err]} {
	    if {[string length $errormsg] == 0} {
		set state(error) [list $err $errorInfo $errorCode]
		set state(status) error
	    }
	}
	if {[info exist state(-command)]} {
	    # Command callback may already have unset our state
	    unset state(-command)
	}
    }
}

# http::reset --
#
#	See documentaion for details.
#
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#				-blocksize, -validate, -headers, -timeout
# Results:
#        Returns a token for this connection.


proc http::geturl { url args } {
    variable http
    if ![info exists http(uid)] {
	set http(uid) 0
    }
    set token [namespace current]::[incr http(uid)]
    variable $token
    upvar 0 $token state
    reset $token
    array set state {







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#				-blocksize, -validate, -headers, -timeout
# Results:
#        Returns a token for this connection.


proc http::geturl { url args } {
    variable http
    if {![info exists http(uid)]} {
	set http(uid) 0
    }
    set token [namespace current]::[incr http(uid)]
    variable $token
    upvar 0 $token state
    reset $token
    array set state {
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    }
    set options {-blocksize -channel -command -handler -headers \
		-progress -query -validate -timeout}
    set usage [join $options ", "]
    regsub -all -- - $options {} options
    set pat ^-([join $options |])$
    foreach {flag value} $args {
	if [regexp $pat $flag] {
	    # Validate numbers
	    if {[info exists state($flag)] && \
		    [regexp {^[0-9]+$} $state($flag)] && \
		    ![regexp {^[0-9]+$} $value]} {
		return -code error "Bad value for $flag ($value), must be integer"
	    }
	    set state($flag) $value







|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    }
    set options {-blocksize -channel -command -handler -headers \
		-progress -query -validate -timeout}
    set usage [join $options ", "]
    regsub -all -- - $options {} options
    set pat ^-([join $options |])$
    foreach {flag value} $args {
	if {[regexp $pat $flag]} {
	    # Validate numbers
	    if {[info exists state($flag)] && \
		    [regexp {^[0-9]+$} $state($flag)] && \
		    ![regexp {^[0-9]+$} $value]} {
		return -code error "Bad value for $flag ($value), must be integer"
	    }
	    set state($flag) $value
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
}

 proc http::Event {token} {
    variable $token
    upvar 0 $token state
    set s $state(sock)

    if [::eof $s] then {
	Eof $token
	return
    }
    if {$state(state) == "header"} {
	set n [gets $s line]
	if {$n == 0} {
	    set state(state) body
	    if ![regexp -nocase ^text $state(type)] {
		# Turn off conversions for non-text data
		fconfigure $s -translation binary
		if {[info exists state(-channel)]} {
		    fconfigure $state(-channel) -translation binary
		}
	    }
	    if {[info exists state(-channel)] &&
		    ![info exists state(-handler)]} {
		# Initiate a sequence of background fcopies
		fileevent $s readable {}
		CopyStart $s $token
	    }
	} elseif {$n > 0} {
	    if [regexp -nocase {^content-type:(.+)$} $line x type] {
		set state(type) [string trim $type]
	    }
	    if [regexp -nocase {^content-length:(.+)$} $line x length] {
		set state(totalsize) [string trim $length]
	    }
	    if [regexp -nocase {^([^:]+):(.+)$} $line x key value] {
		lappend state(meta) $key $value
	    } elseif {[regexp ^HTTP $line]} {
		set state(http) $line
	    }
	}
    } else {
	if [catch {
	    if {[info exists state(-handler)]} {
		set n [eval $state(-handler) {$s $token}]
	    } else {
		set block [read $s $state(-blocksize)]
		set n [string length $block]
		if {$n >= 0} {
		    append state(body) $block
		}
	    }
	    if {$n >= 0} {
		incr state(currentsize) $n
	    }
	} err] {
	    Finish $token $err
	} else {
	    if [info exists state(-progress)] {
		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
	    }
	}
    }
}
 proc http::CopyStart {s token} {
    variable $token
    upvar 0 $token state
    if [catch {
	fcopy $s $state(-channel) -size $state(-blocksize) -command \
	    [list http::CopyDone $token]
    } err] {
	Finish $token $err
    }
}
 proc http::CopyDone {token count {error {}}} {
    variable $token
    upvar 0 $token state
    set s $state(sock)
    incr state(currentsize) $count
    if [info exists state(-progress)] {
	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
    }

    if {([string length $error] != 0)} {
	Finish $token $error
    } elseif {[::eof $s]} {
	Eof $token
    } else {
	CopyStart $s $token
    }
}
 proc http::Eof {token} {
    variable $token







|







|













|


|


|






|












|


|








|


|








|


>


|







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
}

 proc http::Event {token} {
    variable $token
    upvar 0 $token state
    set s $state(sock)

     if {[::eof $s]} {
	Eof $token
	return
    }
    if {$state(state) == "header"} {
	set n [gets $s line]
	if {$n == 0} {
	    set state(state) body
	    if {![regexp -nocase ^text $state(type)]} {
		# Turn off conversions for non-text data
		fconfigure $s -translation binary
		if {[info exists state(-channel)]} {
		    fconfigure $state(-channel) -translation binary
		}
	    }
	    if {[info exists state(-channel)] &&
		    ![info exists state(-handler)]} {
		# Initiate a sequence of background fcopies
		fileevent $s readable {}
		CopyStart $s $token
	    }
	} elseif {$n > 0} {
	    if {[regexp -nocase {^content-type:(.+)$} $line x type]} {
		set state(type) [string trim $type]
	    }
	    if {[regexp -nocase {^content-length:(.+)$} $line x length]} {
		set state(totalsize) [string trim $length]
	    }
	    if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
		lappend state(meta) $key $value
	    } elseif {[regexp ^HTTP $line]} {
		set state(http) $line
	    }
	}
    } else {
	if {[catch {
	    if {[info exists state(-handler)]} {
		set n [eval $state(-handler) {$s $token}]
	    } else {
		set block [read $s $state(-blocksize)]
		set n [string length $block]
		if {$n >= 0} {
		    append state(body) $block
		}
	    }
	    if {$n >= 0} {
		incr state(currentsize) $n
	    }
	} err]} {
	    Finish $token $err
	} else {
	    if {[info exists state(-progress)]} {
		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
	    }
	}
    }
}
 proc http::CopyStart {s token} {
    variable $token
    upvar 0 $token state
    if {[catch {
	fcopy $s $state(-channel) -size $state(-blocksize) -command \
	    [list http::CopyDone $token]
    } err]} {
	Finish $token $err
    }
}
 proc http::CopyDone {token count {error {}}} {
    variable $token
    upvar 0 $token state
    set s $state(sock)
    incr state(currentsize) $count
    if {[info exists state(-progress)]} {
	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
    }
    # At this point the token may have been reset
    if {([string length $error] != 0)} {
	Finish $token $error
    } elseif {[catch {::eof $s} iseof] || $iseof} {
	Eof $token
    } else {
	CopyStart $s $token
    }
}
 proc http::Eof {token} {
    variable $token

Changes to library/http2.3/http.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# http.tcl --
#
#	Client-side HTTP for GET, POST, and HEAD commands.
#	These routines can be used in untrusted code that uses 
#	the Safesock security policy.  These procedures use a 
#	callback interface to avoid using vwait, which is not 
#	defined in the safe base.
#
# See the file "license.terms" for information on usage and
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) http.tcl 1.8 97/10/28 16:23:30

package provide http 2.0	;# This uses Tcl namespaces

namespace eval http {
    variable http

    array set http {











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# http.tcl --
#
#	Client-side HTTP for GET, POST, and HEAD commands.
#	These routines can be used in untrusted code that uses 
#	the Safesock security policy.  These procedures use a 
#	callback interface to avoid using vwait, which is not 
#	defined in the safe base.
#
# See the file "license.terms" for information on usage and
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: http.tcl,v 1.1.2.4 1999/02/10 23:31:21 stanton Exp $

package provide http 2.0	;# This uses Tcl namespaces

namespace eval http {
    variable http

    array set http {
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	if {[regexp -- $pat $flag]} {
	    return $http($flag)
	} else {
	    return -code error "Unknown option $flag, must be: $usage"
	}
    } else {
	foreach {flag value} $args {
	    if [regexp -- $pat $flag] {
		set http($flag) $value
	    } else {
		return -code error "Unknown option $flag, must be: $usage"
	    }
	}
    }
}







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
	if {[regexp -- $pat $flag]} {
	    return $http($flag)
	} else {
	    return -code error "Unknown option $flag, must be: $usage"
	}
    } else {
	foreach {flag value} $args {
	    if {[regexp -- $pat $flag]} {
		set http($flag) $value
	    } else {
		return -code error "Unknown option $flag, must be: $usage"
	    }
	}
    }
}
95
96
97
98
99
100
101


102

103
104
105
106
107
108
109
    if {[info exists state(-command)]} {
	if {[catch {eval $state(-command) {$token}} err]} {
	    if {[string length $errormsg] == 0} {
		set state(error) [list $err $errorInfo $errorCode]
		set state(status) error
	    }
	}


	unset state(-command)

    }
}

# http::reset --
#
#	See documentaion for details.
#







>
>
|
>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    if {[info exists state(-command)]} {
	if {[catch {eval $state(-command) {$token}} err]} {
	    if {[string length $errormsg] == 0} {
		set state(error) [list $err $errorInfo $errorCode]
		set state(status) error
	    }
	}
	if {[info exist state(-command)]} {
	    # Command callback may already have unset our state
	    unset state(-command)
	}
    }
}

# http::reset --
#
#	See documentaion for details.
#
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#				-blocksize, -validate, -headers, -timeout
# Results:
#        Returns a token for this connection.


proc http::geturl { url args } {
    variable http
    if ![info exists http(uid)] {
	set http(uid) 0
    }
    set token [namespace current]::[incr http(uid)]
    variable $token
    upvar 0 $token state
    reset $token
    array set state {







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#				-blocksize, -validate, -headers, -timeout
# Results:
#        Returns a token for this connection.


proc http::geturl { url args } {
    variable http
    if {![info exists http(uid)]} {
	set http(uid) 0
    }
    set token [namespace current]::[incr http(uid)]
    variable $token
    upvar 0 $token state
    reset $token
    array set state {
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    }
    set options {-blocksize -channel -command -handler -headers \
		-progress -query -validate -timeout}
    set usage [join $options ", "]
    regsub -all -- - $options {} options
    set pat ^-([join $options |])$
    foreach {flag value} $args {
	if [regexp $pat $flag] {
	    # Validate numbers
	    if {[info exists state($flag)] && \
		    [regexp {^[0-9]+$} $state($flag)] && \
		    ![regexp {^[0-9]+$} $value]} {
		return -code error "Bad value for $flag ($value), must be integer"
	    }
	    set state($flag) $value







|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    }
    set options {-blocksize -channel -command -handler -headers \
		-progress -query -validate -timeout}
    set usage [join $options ", "]
    regsub -all -- - $options {} options
    set pat ^-([join $options |])$
    foreach {flag value} $args {
	if {[regexp $pat $flag]} {
	    # Validate numbers
	    if {[info exists state($flag)] && \
		    [regexp {^[0-9]+$} $state($flag)] && \
		    ![regexp {^[0-9]+$} $value]} {
		return -code error "Bad value for $flag ($value), must be integer"
	    }
	    set state($flag) $value
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
}

 proc http::Event {token} {
    variable $token
    upvar 0 $token state
    set s $state(sock)

    if [::eof $s] then {
	Eof $token
	return
    }
    if {$state(state) == "header"} {
	set n [gets $s line]
	if {$n == 0} {
	    set state(state) body
	    if ![regexp -nocase ^text $state(type)] {
		# Turn off conversions for non-text data
		fconfigure $s -translation binary
		if {[info exists state(-channel)]} {
		    fconfigure $state(-channel) -translation binary
		}
	    }
	    if {[info exists state(-channel)] &&
		    ![info exists state(-handler)]} {
		# Initiate a sequence of background fcopies
		fileevent $s readable {}
		CopyStart $s $token
	    }
	} elseif {$n > 0} {
	    if [regexp -nocase {^content-type:(.+)$} $line x type] {
		set state(type) [string trim $type]
	    }
	    if [regexp -nocase {^content-length:(.+)$} $line x length] {
		set state(totalsize) [string trim $length]
	    }
	    if [regexp -nocase {^([^:]+):(.+)$} $line x key value] {
		lappend state(meta) $key $value
	    } elseif {[regexp ^HTTP $line]} {
		set state(http) $line
	    }
	}
    } else {
	if [catch {
	    if {[info exists state(-handler)]} {
		set n [eval $state(-handler) {$s $token}]
	    } else {
		set block [read $s $state(-blocksize)]
		set n [string length $block]
		if {$n >= 0} {
		    append state(body) $block
		}
	    }
	    if {$n >= 0} {
		incr state(currentsize) $n
	    }
	} err] {
	    Finish $token $err
	} else {
	    if [info exists state(-progress)] {
		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
	    }
	}
    }
}
 proc http::CopyStart {s token} {
    variable $token
    upvar 0 $token state
    if [catch {
	fcopy $s $state(-channel) -size $state(-blocksize) -command \
	    [list http::CopyDone $token]
    } err] {
	Finish $token $err
    }
}
 proc http::CopyDone {token count {error {}}} {
    variable $token
    upvar 0 $token state
    set s $state(sock)
    incr state(currentsize) $count
    if [info exists state(-progress)] {
	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
    }

    if {([string length $error] != 0)} {
	Finish $token $error
    } elseif {[::eof $s]} {
	Eof $token
    } else {
	CopyStart $s $token
    }
}
 proc http::Eof {token} {
    variable $token







|







|













|


|


|






|












|


|








|


|








|


>


|







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
}

 proc http::Event {token} {
    variable $token
    upvar 0 $token state
    set s $state(sock)

     if {[::eof $s]} {
	Eof $token
	return
    }
    if {$state(state) == "header"} {
	set n [gets $s line]
	if {$n == 0} {
	    set state(state) body
	    if {![regexp -nocase ^text $state(type)]} {
		# Turn off conversions for non-text data
		fconfigure $s -translation binary
		if {[info exists state(-channel)]} {
		    fconfigure $state(-channel) -translation binary
		}
	    }
	    if {[info exists state(-channel)] &&
		    ![info exists state(-handler)]} {
		# Initiate a sequence of background fcopies
		fileevent $s readable {}
		CopyStart $s $token
	    }
	} elseif {$n > 0} {
	    if {[regexp -nocase {^content-type:(.+)$} $line x type]} {
		set state(type) [string trim $type]
	    }
	    if {[regexp -nocase {^content-length:(.+)$} $line x length]} {
		set state(totalsize) [string trim $length]
	    }
	    if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
		lappend state(meta) $key $value
	    } elseif {[regexp ^HTTP $line]} {
		set state(http) $line
	    }
	}
    } else {
	if {[catch {
	    if {[info exists state(-handler)]} {
		set n [eval $state(-handler) {$s $token}]
	    } else {
		set block [read $s $state(-blocksize)]
		set n [string length $block]
		if {$n >= 0} {
		    append state(body) $block
		}
	    }
	    if {$n >= 0} {
		incr state(currentsize) $n
	    }
	} err]} {
	    Finish $token $err
	} else {
	    if {[info exists state(-progress)]} {
		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
	    }
	}
    }
}
 proc http::CopyStart {s token} {
    variable $token
    upvar 0 $token state
    if {[catch {
	fcopy $s $state(-channel) -size $state(-blocksize) -command \
	    [list http::CopyDone $token]
    } err]} {
	Finish $token $err
    }
}
 proc http::CopyDone {token count {error {}}} {
    variable $token
    upvar 0 $token state
    set s $state(sock)
    incr state(currentsize) $count
    if {[info exists state(-progress)]} {
	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
    }
    # At this point the token may have been reset
    if {([string length $error] != 0)} {
	Finish $token $error
    } elseif {[catch {::eof $s} iseof] || $iseof} {
	Eof $token
    } else {
	CopyStart $s $token
    }
}
 proc http::Eof {token} {
    variable $token

Changes to library/init.tcl.

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
# init.tcl --
#
# Default system startup file for Tcl-based applications.  Defines
# "unknown" procedure and auto-load facilities.
#
# SCCS: @(#) init.tcl 1.95 97/11/19 17:16:34
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

if {[info commands package] == ""} {
    error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]"
}
package require -exact Tcl 8.0

# Compute the auto path to use in this interpreter.
# (auto_path could be already set, in safe interps for instance)















if {![info exists auto_path]} {

    if [catch {set auto_path $env(TCLLIBPATH)}] {

	set auto_path ""
    }
}


if {[lsearch -exact $auto_path [info library]] < 0} {
    lappend auto_path [info library]
}


catch {
    foreach __dir $tcl_pkgPath {
	if {[lsearch -exact $auto_path $__dir] < 0} {
	    lappend auto_path $__dir
	}
    }


    unset __dir
}









































# Setup the unknown package handler

package unknown tclPkgUnknown

# Conditionalize for presence of exec.






|



>








|


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

>
|
>



>
>
|
|
|
>
>
|





>
>


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







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
# init.tcl --
#
# Default system startup file for Tcl-based applications.  Defines
# "unknown" procedure and auto-load facilities.
#
# RCS: @(#) $Id: init.tcl,v 1.1.2.7 1999/03/13 23:49:48 rjohnson Exp $
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

if {[info commands package] == ""} {
    error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]"
}
package require -exact Tcl 8.1

# Compute the auto path to use in this interpreter.
# The values on the path come from several locations:
#
# The environment variable TCLLIBPATH
#
# tcl_library, which is the directory containing this init.tcl script.
# tclInitScript.h searches around for the directory containing this
# init.tcl and defines tcl_library to that location before sourcing it.
#
# The parent directory of tcl_library. Adding the parent
# means that packages in peer directories will be found automatically.
#
# tcl_pkgPath, which is set by the platform-specific initialization routines
#	On UNIX it is compiled in
#	On Windows it comes from the registry
#	On Macintosh it is "Tool Command Language" in the Extensions folder

if {![info exists auto_path]} {
    if {[info exist env(TCLLIBPATH)]} {
	set auto_path $env(TCLLIBPATH)
    } else {
	set auto_path ""
    }
}
if {[string compare [info library] {}]} {
    foreach __dir [list [info library] [file dirname [info library]]] {
	if {[lsearch -exact $auto_path $__dir] < 0} {
	    lappend auto_path $__dir
	}
    }
}
if {[info exist tcl_pkgPath]} {
    foreach __dir $tcl_pkgPath {
	if {[lsearch -exact $auto_path $__dir] < 0} {
	    lappend auto_path $__dir
	}
    }
}
if {[info exists __dir]} {
    unset __dir
}
  
# Windows specific end of initialization

if {(![interp issafe]) && ($tcl_platform(platform) == "windows")} {
    namespace eval tcl {
	proc envTraceProc {lo n1 n2 op} {
	    set x $::env($n2)
	    set ::env($lo) $x
	    set ::env([string toupper $lo]) $x
	}
    }
    foreach p [array names env] {
	set u [string toupper $p]
	if {$u != $p} {
	    switch -- $u {
		COMSPEC -
		PATH {
		    if {![info exists env($u)]} {
			set env($u) $env($p)
		    }
		    trace variable env($p) w [list tcl::envTraceProc $p]
		    trace variable env($u) w [list tcl::envTraceProc $p]
		}
	    }
	}
    }
    if {[info exists p]} {
	unset p
    }
    if {[info exists u]} {
	unset u
    }
    if {![info exists env(COMSPEC)]} {
	if {$tcl_platform(os) == {Windows NT}} {
	    set env(COMSPEC) cmd.exe
	} else {
	    set env(COMSPEC) command.com
	}
    }
}

# Setup the unknown package handler

package unknown tclPkgUnknown

# Conditionalize for presence of exec.

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
# differently, specially when stderr is not available)

if {[info commands tclLog] == ""} {
    proc tclLog {string} {
	catch {puts stderr $string}
    }
}

# The procs defined in this file that have a leading space
# are 'hidden' from auto_mkindex because they are not
# auto-loadable.


# unknown --
# This procedure is called when a Tcl command is invoked that doesn't
# exist in the interpreter.  It takes the following steps to make the
# command available:
#


#	1. See if the autoload facility can locate the command in a
#	   Tcl script file.  If so, load it and execute it.
#	2. If the command was invoked interactively at top-level:
#	    (a) see if the command exists as an executable UNIX program.
#		If so, "exec" the command.
#	    (b) see if the command requests csh-like history substitution
#		in one of the common forms !!, !<number>, or ^old^new.  If
#		so, emulate csh's history substitution.
#	    (c) see if the command is a unique abbreviation for another
#		command.  If so, invoke the command.
#
# Arguments:
# args -	A list whose elements are the words of the original
#		command, including the command name.

 proc unknown args {
    global auto_noexec auto_noload env unknown_pending tcl_interactive
    global errorCode errorInfo















    # Save the values of errorCode and errorInfo variables, since they
    # may get modified if caught errors occur below.  The variables will
    # be restored just before re-executing the missing command.

    set savedErrorCode $errorCode
    set savedErrorInfo $errorInfo
    set name [lindex $args 0]
    if ![info exists auto_noload] {
	#
	# Make sure we're not trying to load the same proc twice.
	#
	if [info exists unknown_pending($name)] {
	    return -code error "self-referential recursion in \"unknown\" for command \"$name\"";
	}
	set unknown_pending($name) pending;
	set ret [catch {auto_load $name [uplevel 1 {namespace current}]} msg]
	unset unknown_pending($name);
	if {$ret != 0} {
	    return -code $ret -errorcode $errorCode \
		"error while autoloading \"$name\": $msg"
	}
	if ![array size unknown_pending] {
	    unset unknown_pending
	}
	if $msg {
	    set errorCode $savedErrorCode
	    set errorInfo $savedErrorInfo
	    set code [catch {uplevel 1 $args} msg]
	    if {$code ==  1} {
		#
		# Strip the last five lines off the error stack (they're
		# from the "uplevel" command).
		#

		set new [split $errorInfo \n]
		set new [join [lrange $new 0 [expr [llength $new] - 6]] \n]
		return -code error -errorcode $errorCode \
			-errorinfo $new $msg
	    } else {
		return -code $code $msg
	    }
	}
    }

    if {([info level] == 1) && ([info script] == "") \
	    && [info exists tcl_interactive] && $tcl_interactive} {
	if ![info exists auto_noexec] {
	    set new [auto_execok $name]
	    if {$new != ""} {
		set errorCode $savedErrorCode
		set errorInfo $savedErrorInfo
		set redir ""
		if {[info commands console] == ""} {
		    set redir ">&@stdout <@stdin"







<
<
<
<
<






>
>
|

|












|


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








|



|









|


|










|










|







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
# differently, specially when stderr is not available)

if {[info commands tclLog] == ""} {
    proc tclLog {string} {
	catch {puts stderr $string}
    }
}






# unknown --
# This procedure is called when a Tcl command is invoked that doesn't
# exist in the interpreter.  It takes the following steps to make the
# command available:
#
#	1. See if the command has the form "namespace inscope ns cmd" and
#	   if so, concatenate its arguments onto the end and evaluate it.
#	2. See if the autoload facility can locate the command in a
#	   Tcl script file.  If so, load it and execute it.
#	3. If the command was invoked interactively at top-level:
#	    (a) see if the command exists as an executable UNIX program.
#		If so, "exec" the command.
#	    (b) see if the command requests csh-like history substitution
#		in one of the common forms !!, !<number>, or ^old^new.  If
#		so, emulate csh's history substitution.
#	    (c) see if the command is a unique abbreviation for another
#		command.  If so, invoke the command.
#
# Arguments:
# args -	A list whose elements are the words of the original
#		command, including the command name.

proc unknown args {
    global auto_noexec auto_noload env unknown_pending tcl_interactive
    global errorCode errorInfo

    # If the command word has the form "namespace inscope ns cmd"
    # then concatenate its arguments onto the end and evaluate it.

    set cmd [lindex $args 0]
    if {[regexp "^namespace\[ \t\n\]+inscope" $cmd] && [llength $cmd] == 4} {
        set arglist [lrange $args 1 end]
	set ret [catch {uplevel $cmd $arglist} result]
        if {$ret == 0} {
            return $result
        } else {
	    return -code $ret -errorcode $errorCode $result
        }
    }

    # Save the values of errorCode and errorInfo variables, since they
    # may get modified if caught errors occur below.  The variables will
    # be restored just before re-executing the missing command.

    set savedErrorCode $errorCode
    set savedErrorInfo $errorInfo
    set name [lindex $args 0]
    if {![info exists auto_noload]} {
	#
	# Make sure we're not trying to load the same proc twice.
	#
	if {[info exists unknown_pending($name)]} {
	    return -code error "self-referential recursion in \"unknown\" for command \"$name\"";
	}
	set unknown_pending($name) pending;
	set ret [catch {auto_load $name [uplevel 1 {namespace current}]} msg]
	unset unknown_pending($name);
	if {$ret != 0} {
	    return -code $ret -errorcode $errorCode \
		"error while autoloading \"$name\": $msg"
	}
	if {![array size unknown_pending]} {
	    unset unknown_pending
	}
	if {$msg} {
	    set errorCode $savedErrorCode
	    set errorInfo $savedErrorInfo
	    set code [catch {uplevel 1 $args} msg]
	    if {$code ==  1} {
		#
		# Strip the last five lines off the error stack (they're
		# from the "uplevel" command).
		#

		set new [split $errorInfo \n]
		set new [join [lrange $new 0 [expr {[llength $new] - 6}]] \n]
		return -code error -errorcode $errorCode \
			-errorinfo $new $msg
	    } else {
		return -code $code $msg
	    }
	}
    }

    if {([info level] == 1) && ([info script] == "") \
	    && [info exists tcl_interactive] && $tcl_interactive} {
	if {![info exists auto_noexec]} {
	    set new [auto_execok $name]
	    if {$new != ""} {
		set errorCode $savedErrorCode
		set errorInfo $savedErrorInfo
		set redir ""
		if {[info commands console] == ""} {
		    set redir ">&@stdout <@stdin"
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
	    set newcmd [history event]
	} elseif {[regexp {^!(.+)$} $name dummy event]} {
	    set newcmd [history event $event]
	} elseif {[regexp {^\^([^^]*)\^([^^]*)\^?$} $name dummy old new]} {
	    set newcmd [history event -1]
	    catch {regsub -all -- $old $newcmd $new newcmd}
	}
	if [info exists newcmd] {
	    tclLog $newcmd
	    history change $newcmd 0
	    return [uplevel $newcmd]
	}

	set ret [catch {set cmds [info commands $name*]} msg]
	if {[string compare $name "::"] == 0} {







|







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
	    set newcmd [history event]
	} elseif {[regexp {^!(.+)$} $name dummy event]} {
	    set newcmd [history event $event]
	} elseif {[regexp {^\^([^^]*)\^([^^]*)\^?$} $name dummy old new]} {
	    set newcmd [history event -1]
	    catch {regsub -all -- $old $newcmd $new newcmd}
	}
	if {[info exists newcmd]} {
	    tclLog $newcmd
	    history change $newcmd 0
	    return [uplevel $newcmd]
	}

	set ret [catch {set cmds [info commands $name*]} msg]
	if {[string compare $name "::"] == 0} {
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
#
# Arguments: 
# cmd -			Name of the command to find and load.
# namespace (optional)  The namespace where the command is being used - must be
#                       a canonical namespace as returned [namespace current]
#                       for instance. If not given, namespace current is used.

 proc auto_load {cmd {namespace {}}} {
    global auto_index auto_oldpath auto_path env errorInfo errorCode

    if {[string length $namespace] == 0} {
	set namespace [uplevel {namespace current}]
    }
    set nameList [auto_qualify $cmd $namespace]
    # workaround non canonical auto_index entries that might be around
    # from older auto_mkindex versions
    lappend nameList $cmd
    foreach name $nameList {
	if [info exists auto_index($name)] {
	    uplevel #0 $auto_index($name)
	    return [expr {[info commands $name] != ""}]
	}
    }
    if ![info exists auto_path] {
	return 0
    }




























    if [info exists auto_oldpath] {
	if {$auto_oldpath == $auto_path} {
	    return 0
	}
    }
    set auto_oldpath $auto_path

    # Check if we are a safe interpreter. In that case, we support only
    # newer format tclIndex files.

    set issafe [interp issafe]
    for {set i [expr [llength $auto_path] - 1]} {$i >= 0} {incr i -1} {
	set dir [lindex $auto_path $i]
	set f ""
	if {$issafe} {
	    catch {source [file join $dir tclIndex]}
	} elseif [catch {set f [open [file join $dir tclIndex]]}] {
	    continue
	} else {
	    set error [catch {
		set id [gets $f]
		if {$id == "# Tcl autoload index file, version 2.0"} {
		    eval [read $f]
		} elseif {$id == \







|
|









|




|


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










|




|







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
#
# Arguments: 
# cmd -			Name of the command to find and load.
# namespace (optional)  The namespace where the command is being used - must be
#                       a canonical namespace as returned [namespace current]
#                       for instance. If not given, namespace current is used.

proc auto_load {cmd {namespace {}}} {
    global auto_index auto_oldpath auto_path

    if {[string length $namespace] == 0} {
	set namespace [uplevel {namespace current}]
    }
    set nameList [auto_qualify $cmd $namespace]
    # workaround non canonical auto_index entries that might be around
    # from older auto_mkindex versions
    lappend nameList $cmd
    foreach name $nameList {
	if {[info exists auto_index($name)]} {
	    uplevel #0 $auto_index($name)
	    return [expr {[info commands $name] != ""}]
	}
    }
    if {![info exists auto_path]} {
	return 0
    }

    if {![auto_load_index]} {
	return 0
    }

    foreach name $nameList {
	if {[info exists auto_index($name)]} {
	    uplevel #0 $auto_index($name)
	    if {[info commands $name] != ""} {
		return 1
	    }
	}
    }
    return 0
}

# auto_load_index --
# Loads the contents of tclIndex files on the auto_path directory
# list.  This is usually invoked within auto_load to load the index
# of available commands.  Returns 1 if the index is loaded, and 0 if
# the index is already loaded and up to date.
#
# Arguments: 
# None.

proc auto_load_index {} {
    global auto_index auto_oldpath auto_path errorInfo errorCode

    if {[info exists auto_oldpath]} {
	if {$auto_oldpath == $auto_path} {
	    return 0
	}
    }
    set auto_oldpath $auto_path

    # Check if we are a safe interpreter. In that case, we support only
    # newer format tclIndex files.

    set issafe [interp issafe]
    for {set i [expr {[llength $auto_path] - 1}]} {$i >= 0} {incr i -1} {
	set dir [lindex $auto_path $i]
	set f ""
	if {$issafe} {
	    catch {source [file join $dir tclIndex]}
	} elseif {[catch {set f [open [file join $dir tclIndex]]}]} {
	    continue
	} else {
	    set error [catch {
		set id [gets $f]
		if {$id == "# Tcl autoload index file, version 2.0"} {
		    eval [read $f]
		} elseif {$id == \
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
		    error \
		      "[file join $dir tclIndex] isn't a proper Tcl index file"
		}
	    } msg]
	    if {$f != ""} {
		close $f
	    }
	    if $error {
		error $msg $errorInfo $errorCode
	    }
	}
    }
    foreach name $nameList {
	if [info exists auto_index($name)] {
	    uplevel #0 $auto_index($name)
	    if {[info commands $name] != ""} {
		return 1
	    }
	}
    }
    return 0
}

# auto_qualify --

# compute a fully qualified names list for use in the auto_index array.
# For historical reasons, commands in the global namespace do not have leading
# :: in the index key. The list has two elements when the command name is
# relative (no leading ::) and the namespace is not the global one. Otherwise
# only one name is returned (and searched in the auto_index).
#
# Arguments -
# cmd		The command name. Can be any name accepted for command
#               invocations (Like "foo::::bar").
# namespace	The namespace where the command is being used - must be
#               a canonical namespace as returned by [namespace current]
#               for instance.

 proc auto_qualify {cmd namespace} {

    # count separators and clean them up
    # (making sure that foo:::::bar will be treated as foo::bar)
    set n [regsub -all {::+} $cmd :: cmd]

    # Ignore namespace if the name starts with ::
    # Handle special case of only leading ::







|




<
<
<
<
|
<
<
<
<



>
|












|







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
		    error \
		      "[file join $dir tclIndex] isn't a proper Tcl index file"
		}
	    } msg]
	    if {$f != ""} {
		close $f
	    }
	    if {$error} {
		error $msg $errorInfo $errorCode
	    }
	}
    }




    return 1




}

# auto_qualify --
#
# Compute a fully qualified names list for use in the auto_index array.
# For historical reasons, commands in the global namespace do not have leading
# :: in the index key. The list has two elements when the command name is
# relative (no leading ::) and the namespace is not the global one. Otherwise
# only one name is returned (and searched in the auto_index).
#
# Arguments -
# cmd		The command name. Can be any name accepted for command
#               invocations (Like "foo::::bar").
# namespace	The namespace where the command is being used - must be
#               a canonical namespace as returned by [namespace current]
#               for instance.

proc auto_qualify {cmd namespace} {

    # count separators and clean them up
    # (making sure that foo:::::bar will be treated as foo::bar)
    set n [regsub -all {::+} $cmd :: cmd]

    # Ignore namespace if the name starts with ::
    # Handle special case of only leading ::
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
	} else {
	    # ( foo::bar , ::sub ) -> ::sub::foo::bar ::foo::bar
	    return [list ${namespace}::$cmd ::$cmd]
	}
    }
}











if {[string compare $tcl_platform(platform) windows] == 0} {

















# auto_execok --
#
# Returns string that indicates name of program to execute if 
# name corresponds to a shell builtin or an executable in the
# Windows search path, or "" otherwise.  Builds an associative 
# array auto_execs that caches information about previous checks, 
# for speed.
#
# Arguments: 
# name -			Name of a command.


# Windows version.
#
# Note that info executable doesn't work under Windows, so we have to
# look for files with .exe, .com, or .bat extensions.  Also, the path
# may be in the Path or PATH environment variables, and path
# components are separated with semicolons, not colons as under Unix.
#
proc auto_execok name {
    global auto_execs env tcl_platform

    if [info exists auto_execs($name)] {
	return $auto_execs($name)
    }
    set auto_execs($name) ""

    if {[lsearch -exact {cls copy date del erase dir echo mkdir md rename 
	    ren rmdir rd time type ver vol} $name] != -1} {
	return [set auto_execs($name) [list $env(COMSPEC) /c $name]]







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












>










|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
	} else {
	    # ( foo::bar , ::sub ) -> ::sub::foo::bar ::foo::bar
	    return [list ${namespace}::$cmd ::$cmd]
	}
    }
}

# auto_import --
#
# Invoked during "namespace import" to make see if the imported commands
# reside in an autoloaded library.  If so, the commands are loaded so
# that they will be available for the import links.  If not, then this
# procedure does nothing.
#
# Arguments -
# pattern	The pattern of commands being imported (like "foo::*")
#               a canonical namespace as returned by [namespace current]

proc auto_import {pattern} {
    global auto_index

    set ns [uplevel namespace current]
    set patternList [auto_qualify $pattern $ns]

    auto_load_index

    foreach pattern $patternList {
        foreach name [array names auto_index] {
            if {[string match $pattern $name] && "" == [info commands $name]} {
                uplevel #0 $auto_index($name)
            }
        }
    }
}

# auto_execok --
#
# Returns string that indicates name of program to execute if 
# name corresponds to a shell builtin or an executable in the
# Windows search path, or "" otherwise.  Builds an associative 
# array auto_execs that caches information about previous checks, 
# for speed.
#
# Arguments: 
# name -			Name of a command.

if {[string compare $tcl_platform(platform) windows] == 0} {
# Windows version.
#
# Note that info executable doesn't work under Windows, so we have to
# look for files with .exe, .com, or .bat extensions.  Also, the path
# may be in the Path or PATH environment variables, and path
# components are separated with semicolons, not colons as under Unix.
#
proc auto_execok name {
    global auto_execs env tcl_platform

    if {[info exists auto_execs($name)]} {
	return $auto_execs($name)
    }
    set auto_execs($name) ""

    if {[lsearch -exact {cls copy date del erase dir echo mkdir md rename 
	    ren rmdir rd time type ver vol} $name] != -1} {
	return [set auto_execs($name) [list $env(COMSPEC) /c $name]]
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
	    }
	}
    }
    return ""
}

} else {

# auto_execok --
#
# Returns string that indicates name of program to execute if 
# name corresponds to an executable in the path. Builds an associative 
# array auto_execs that caches information about previous checks, 
# for speed.
#
# Arguments: 
# name -			Name of a command.

# Unix version.
#
proc auto_execok name {
    global auto_execs env

    if [info exists auto_execs($name)] {
	return $auto_execs($name)
    }
    set auto_execs($name) ""
    if {[llength [file split $name]] != 1} {
	if {[file executable $name] && ![file isdirectory $name]} {
	    set auto_execs($name) [list $name]
	}







<
<
<
<
<
<
<
<
<
<
<





|







527
528
529
530
531
532
533











534
535
536
537
538
539
540
541
542
543
544
545
546
	    }
	}
    }
    return ""
}

} else {











# Unix version.
#
proc auto_execok name {
    global auto_execs env

    if {[info exists auto_execs($name)]} {
	return $auto_execs($name)
    }
    set auto_execs($name) ""
    if {[llength [file split $name]] != 1} {
	if {[file executable $name] && ![file isdirectory $name]} {
	    set auto_execs($name) [list $name]
	}
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
	    return $auto_execs($name)
	}
    }
    return ""
}

}
# auto_reset --
# Destroy all cached information for auto-loading and auto-execution,
# so that the information gets recomputed the next time it's needed.
# Also delete any procedures that are listed in the auto-load index
# except those defined in this file.
#
# Arguments: 
# None.

proc auto_reset {} {
    global auto_execs auto_index auto_oldpath
    foreach p [info procs] {
	if {[info exists auto_index($p)] && ![string match auto_* $p]
		&& ([lsearch -exact {unknown pkg_mkIndex tclPkgSetup
			tclMacPkgSearch tclPkgUnknown} $p] < 0)} {
	    rename $p {}
	}
    }
    catch {unset auto_execs}
    catch {unset auto_index}
    catch {unset auto_oldpath}
}

# auto_mkindex --
# Regenerate a tclIndex file from Tcl source files.  Takes as argument
# the name of the directory in which the tclIndex file is to be placed,
# followed by any number of glob patterns to use in that directory to
# locate all of the relevant files. It does not parse or source the file
# so the generated index will not contain the appropriate namespace qualifiers
# if you don't explicitly specify it.
#
# Arguments: 
# dir -			Name of the directory in which to create an index.
# args -		Any number of additional arguments giving the
#			names of files within dir.  If no additional
#			are given auto_mkindex will look for *.tcl.

proc auto_mkindex {dir args} {
    global errorCode errorInfo
    set oldDir [pwd]
    cd $dir
    set dir [pwd]
    append index "# Tcl autoload index file, version 2.0\n"
    append index "# This file is generated by the \"auto_mkindex\" command\n"
    append index "# and sourced to set up indexing information for one or\n"
    append index "# more commands.  Typically each line is a command that\n"
    append index "# sets an element in the auto_index array, where the\n"
    append index "# element name is the name of a command and the value is\n"
    append index "# a script that loads the command.\n\n"
    if {$args == ""} {
	set args *.tcl
    }
    foreach file [eval glob $args] {
	set f ""
	set error [catch {
	    set f [open $file]
	    while {[gets $f line] >= 0} {
		if [regexp {^proc[ 	]+([^ 	]*)} $line match procName] {
		    set procName [lindex [auto_qualify $procName "::"] 0]
		    append index "set [list auto_index($procName)]"
		    append index " \[list source \[file join \$dir [list $file]\]\]\n"
		}
	    }
	    close $f
	} msg]
	if $error {
	    set code $errorCode
	    set info $errorInfo
	    catch {close $f}
	    cd $oldDir
	    error $msg $info $code
	}
    }
    set f ""
    set error [catch {
	set f [open tclIndex w]
	puts $f $index nonewline
	close $f
	cd $oldDir
    } msg]
    if $error {
	set code $errorCode
	set info $errorInfo
	catch {close $f}
	cd $oldDir
	error $msg $info $code
    }
}

# pkg_mkIndex --
# This procedure creates a package index in a given directory.  The
# package index consists of a "pkgIndex.tcl" file whose contents are
# a Tcl script that sets up package information with "package require"
# commands.  The commands describe all of the packages defined by the
# files given as arguments.
#
# Arguments:
# dir -			Name of the directory in which to create the index.
# args -		Any number of additional arguments, each giving
#			a glob pattern that matches the names of one or
#			more shared libraries or Tcl script files in
#			dir.

proc pkg_mkIndex {dir args} {
    global errorCode errorInfo
    if {[llength $args] == 0} {
	return -code error "wrong # args: should be\
		\"pkg_mkIndex dir pattern ?pattern ...?\"";
    }
    append index "# Tcl package index file, version 1.0\n"
    append index "# This file is generated by the \"pkg_mkIndex\" command\n"
    append index "# and sourced either when an application starts up or\n"
    append index "# by a \"package unknown\" script.  It invokes the\n"
    append index "# \"package ifneeded\" command to set up package-related\n"
    append index "# information so that packages will be loaded automatically\n"
    append index "# in response to \"package require\" commands.  When this\n"
    append index "# script is sourced, the variable \$dir must contain the\n"
    append index "# full path name of this file's directory.\n"
    set oldDir [pwd]
    cd $dir
    foreach file [eval glob $args] {
	# For each file, figure out what commands and packages it provides.
	# To do this, create a child interpreter, load the file into the
	# interpreter, and get a list of the new commands and packages
	# that are defined.  Define an empty "package unknown" script so
	# that there are no recursive package inclusions.

	set c [interp create]

	# If Tk is loaded in the parent interpreter, load it into the
	# child also, in case the extension depends on it.

	foreach pkg [info loaded] {
	    if {[lindex $pkg 1] == "Tk"} {
		$c eval {set argv {-geometry +0+0}}
		load [lindex $pkg 0] Tk $c
		break
	    }
	}
	$c eval [list set file $file]
	if [catch {
	    $c eval {
		proc dummy args {}
		rename package package-orig
		proc package {what args} {
		    switch -- $what {
			require { return ; # ignore transitive requires }
			default { eval package-orig {$what} $args }
		    }
		}
		proc pkgGetAllNamespaces {{root {}}} {
		    set list $root
                    foreach ns [namespace children $root] {
                        eval lappend list [pkgGetAllNamespaces $ns]
                    }
                    return $list
                }
		package unknown dummy
		set origCmds [info commands]
		set dir ""		;# in case file is pkgIndex.tcl
		set pkgs ""

		# Try to load the file if it has the shared library extension,
		# otherwise source it.  It's important not to try to load
		# files that aren't shared libraries, because on some systems
		# (like SunOS) the loader will abort the whole application
		# when it gets an error.

		if {[string compare [file extension $file] \
			[info sharedlibextension]] == 0} {

		    # The "file join ." command below is necessary.  Without
		    # it, if the file name has no \'s and we're on UNIX, the
		    # load command will invoke the LD_LIBRARY_PATH search
		    # mechanism, which could cause the wrong file to be used.

		    load [file join . $file]
		    set type load
		} else {
		    source $file
		    set type source
		}
		foreach ns [pkgGetAllNamespaces] {
		    namespace import ${ns}::*
		}
		foreach i [info commands] {
		    set cmds($i) 1
		}
		foreach i $origCmds {
		    catch {unset cmds($i)}

		}
		foreach i [array names cmds] {
		    # reverse engineer which namespace a command comes from
		    set absolute [namespace origin $i]
		    if {[string compare ::$i $absolute] != 0} {
			set cmds($absolute) 1
			unset cmds($i)
		    }
		}
		foreach i [package names] {
		    if {([string compare [package provide $i] ""] != 0)
			    && ([string compare $i Tcl] != 0)
			    && ([string compare $i Tk] != 0)} {
			lappend pkgs [list $i [package provide $i]]
		    }
		}
	    }
	} msg] {
	    tclLog "error while loading or sourcing $file: $msg"
	}
	foreach pkg [$c eval set pkgs] {
	    lappend files($pkg) [list $file [$c eval set type] \
		    [lsort [$c eval array names cmds]]]
	}
	interp delete $c
    }
    foreach pkg [lsort [array names files]] {
	append index "\npackage ifneeded $pkg\
		\[list tclPkgSetup \$dir [lrange $pkg 0 0] [lrange $pkg 1 1]\
		[list $files($pkg)]\]"
    }
    set f [open pkgIndex.tcl w]
    puts $f $index
    close $f
    cd $oldDir
}

# tclPkgSetup --
# This is a utility procedure use by pkgIndex.tcl files.  It is invoked
# as part of a "package ifneeded" script.  It calls "package provide"
# to indicate that a package is available, then sets entries in the
# auto_index array so that the package's files will be auto-loaded when
# the commands are used.
#
# Arguments:
# dir -			Directory containing all the files for this package.
# pkg -			Name of the package (no version number).
# version -		Version number for the package, such as 2.1.3.
# files -		List of files that constitute the package.  Each
#			element is a sub-list with three elements.  The first
#			is the name of a file relative to $dir, the second is
#			"load" or "source", indicating whether the file is a
#			loadable binary or a script to source, and the third
#			is a list of commands defined by this file.

proc tclPkgSetup {dir pkg version files} {
    global auto_index

    package provide $pkg $version
    foreach fileInfo $files {
	set f [lindex $fileInfo 0]
	set type [lindex $fileInfo 1]
	foreach cmd [lindex $fileInfo 2] {
	    if {$type == "load"} {
		set auto_index($cmd) [list load [file join $dir $f] $pkg]
	    } else {
		set auto_index($cmd) [list source [file join $dir $f]]
	    } 
	}
    }
}

# tclMacPkgSearch --
# The procedure is used on the Macintosh to search a given directory for files
# with a TEXT resource named "pkgIndex".  If it exists it is sourced in to the
# interpreter to setup the package database.

proc tclMacPkgSearch {dir} {
    foreach x [glob -nocomplain [file join $dir *.shlb]] {
	if [file isfile $x] {
	    set res [resource open $x]
	    foreach y [resource list TEXT $res] {
		if {$y == "pkgIndex"} {source -rsrc pkgIndex}
	    }
	    catch {resource close $res}
	}
    }
}

# tclPkgUnknown --
# This procedure provides the default for the "package unknown" function.
# It is invoked when a package that's needed can't be found.  It scans
# the auto_path directories and their immediate children looking for
# pkgIndex.tcl files and sources any such files that are found to setup
# the package database.  (On the Macintosh we also search for pkgIndex
# TEXT resources in all files.)
#
# Arguments:
# name -		Name of desired package.  Not used.
# version -		Version of desired package.  Not used.
# exact -		Either "-exact" or omitted.  Not used.

proc tclPkgUnknown {name version {exact {}}} {
    global auto_path tcl_platform env

    if ![info exists auto_path] {
	return
    }
    for {set i [expr [llength $auto_path] - 1]} {$i >= 0} {incr i -1} {
	# we can't use glob in safe interps, so enclose the following
	# in a catch statement
	catch {
	    foreach file [glob -nocomplain [file join [lindex $auto_path $i] \
		    * pkgIndex.tcl]] {
		set dir [file dirname $file]
		if [catch {source $file} msg] {
		    tclLog "error reading package index file $file: $msg"
		}
	    }
        }
	set dir [lindex $auto_path $i]
	set file [file join $dir pkgIndex.tcl]
	# safe interps usually don't have "file readable", nor stderr channel
	if {[interp issafe] || [file readable $file]} {
	    if {[catch {source $file} msg] && ![interp issafe]}  {
		tclLog "error reading package index file $file: $msg"
	    }
	}
	# On the Macintosh we also look in the resource fork 
	# of shared libraries
	# We can't use tclMacPkgSearch in safe interps because it uses glob
	if {(![interp issafe]) && ($tcl_platform(platform) == "macintosh")} {
	    set dir [lindex $auto_path $i]
	    tclMacPkgSearch $dir
	    foreach x [glob -nocomplain [file join $dir *]] {
		if [file isdirectory $x] {
		    set dir $x
		    tclMacPkgSearch $dir
		}
	    }
	}
    }
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
556
557
558
559
560
561
562














































































































































































































































































































































	    return $auto_execs($name)
	}
    }
    return ""
}

}














































































































































































































































































































































Changes to library/ldAout.tcl.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#	The input archives and object files are examined with the "nm"
#	command to determine whether the modules initialization
#	entry and safe initialization entry are present.  A trivial
#	C function that locates the entries is composed, compiled, and
#	its .o file placed before all others in the command; then
#	"ld" is executed to bind the objects together.
#
# SCCS: @(#) ldAout.tcl 1.12 96/11/30 17:11:02
#
# Copyright (c) 1995, by General Electric Company. All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# This work was supported in part by the ARPA Manufacturing Automation







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#	The input archives and object files are examined with the "nm"
#	command to determine whether the modules initialization
#	entry and safe initialization entry are present.  A trivial
#	C function that locates the entries is composed, compiled, and
#	its .o file placed before all others in the command; then
#	"ld" is executed to bind the objects together.
#
# RCS: @(#) $Id: ldAout.tcl,v 1.1.2.2 1998/12/02 20:08:06 welch Exp $
#
# Copyright (c) 1995, by General Electric Company. All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# This work was supported in part by the ARPA Manufacturing Automation
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
    }
    if {$minusO} {
      set outputFile $a
      set minusO 0
    } elseif {![string compare $a -o]} {
      set minusO 1
    }
    if [regexp {^-[lL]} $a] {
	lappend libraries $a
	if [regexp {^-L} $a] {
	    lappend libdirs [string range $a 2 end]
	}
    } elseif {$seenDotO} {
	lappend tail $a
    } else {
	lappend head $a
    }
  }
  lappend libdirs /lib /usr/lib

  # MIPS -- If there are corresponding G0 libraries, replace the
  # ordinary ones with the G0 ones.

  set libs {}
  foreach lib $libraries {
      if [regexp {^-l} $lib] {
	  set lname [string range $lib 2 end]
	  foreach dir $libdirs {
	      if [file exists [file join $dir lib${lname}_G0.a]] {
		  set lname ${lname}_G0
		  break
	      }
	  }
	  lappend libs -l$lname
      } else {
	  lappend libs $lib
      }
  }
  set libraries $libs

  # Extract the module name from the "-o" option

  if {![info exists outputFile]} {
    error "-o option must be supplied to link a Tcl load module"
  }
  set m [file tail $outputFile]
  if [regexp {\.a$} $outputFile] {
    set shlib_suffix .a
  } else {
    set shlib_suffix ""
  }
  if [regexp {\..*$} $outputFile match] {
    set l [expr [string length $m] - [string length $match]]
  } else {
    error "Output file does not appear to have a suffix"
  }
  set modName [string tolower [string range $m 0 [expr $l-1]]]
  if [regexp {^lib} $modName] {
    set modName [string range $modName 3 end]
  }
  if [regexp {[0-9\.]*(_g0)?$} $modName match] {
    set modName [string range $modName 0 [expr [string length $modName]-[string length $match]-1]]
  }
  set modName "[string toupper [string index $modName 0]][string range $modName 1 end]"
  
  # Catalog initialization entry points found in the module

  set f [open $nmCommand r]
  while {[gets $f l] >= 0} {
    if [regexp {T[ 	]*_?([A-Z][a-z0-9_]*_(Safe)?Init(__FP10Tcl_Interp)?)$} $l trash symbol] {
      if {![regexp {_?([A-Z][a-z0-9_]*_(Safe)?Init)} $symbol trash s]} {
	set s $symbol
      }
      append entryProtos {extern int } $symbol { (); } \n
      append entryPoints {  } \{ { "} $s {", } $symbol { } \} , \n
    }
  }







|

|















|


|

















|




|
|



|
|


|
|







|







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
    }
    if {$minusO} {
      set outputFile $a
      set minusO 0
    } elseif {![string compare $a -o]} {
      set minusO 1
    }
    if {[regexp {^-[lL]} $a]} {
	lappend libraries $a
	if {[regexp {^-L} $a]} {
	    lappend libdirs [string range $a 2 end]
	}
    } elseif {$seenDotO} {
	lappend tail $a
    } else {
	lappend head $a
    }
  }
  lappend libdirs /lib /usr/lib

  # MIPS -- If there are corresponding G0 libraries, replace the
  # ordinary ones with the G0 ones.

  set libs {}
  foreach lib $libraries {
      if {[regexp {^-l} $lib]} {
	  set lname [string range $lib 2 end]
	  foreach dir $libdirs {
	      if {[file exists [file join $dir lib${lname}_G0.a]]} {
		  set lname ${lname}_G0
		  break
	      }
	  }
	  lappend libs -l$lname
      } else {
	  lappend libs $lib
      }
  }
  set libraries $libs

  # Extract the module name from the "-o" option

  if {![info exists outputFile]} {
    error "-o option must be supplied to link a Tcl load module"
  }
  set m [file tail $outputFile]
  if {[regexp {\.a$} $outputFile]} {
    set shlib_suffix .a
  } else {
    set shlib_suffix ""
  }
  if {[regexp {\..*$} $outputFile match]} {
    set l [expr {[string length $m] - [string length $match]}]
  } else {
    error "Output file does not appear to have a suffix"
  }
  set modName [string tolower [string range $m 0 [expr {$l-1}]]]
  if {[regexp {^lib} $modName]} {
    set modName [string range $modName 3 end]
  }
  if {[regexp {[0-9\.]*(_g0)?$} $modName match]} {
    set modName [string range $modName 0 [expr {[string length $modName]-[string length $match]-1}]]
  }
  set modName "[string toupper [string index $modName 0]][string range $modName 1 end]"
  
  # Catalog initialization entry points found in the module

  set f [open $nmCommand r]
  while {[gets $f l] >= 0} {
    if {[regexp {T[ 	]*_?([A-Z][a-z0-9_]*_(Safe)?Init(__FP10Tcl_Interp)?)$} $l trash symbol]} {
      if {![regexp {_?([A-Z][a-z0-9_]*_(Safe)?Init)} $symbol trash s]} {
	set s $symbol
      }
      append entryProtos {extern int } $symbol { (); } \n
      append entryPoints {  } \{ { "} $s {", } $symbol { } \} , \n
    }
  }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

  # Now compose and execute the ld command that packages the module

  if {$shlib_suffix == ".a"} {
    set ldCommand "ar cr $outputFile"
    regsub { -o} $tail {} tail
  } else {
  set ldCommand ld
  foreach item $head {
    lappend ldCommand $item
  }
  }
  lappend ldCommand tcl$modName.o
  foreach item $tail {
    lappend ldCommand $item
  }
  puts stderr $ldCommand
  eval exec $ldCommand







|
|
|
|







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

  # Now compose and execute the ld command that packages the module

  if {$shlib_suffix == ".a"} {
    set ldCommand "ar cr $outputFile"
    regsub { -o} $tail {} tail
  } else {
    set ldCommand ld
    foreach item $head {
      lappend ldCommand $item
    }
  }
  lappend ldCommand tcl$modName.o
  foreach item $tail {
    lappend ldCommand $item
  }
  puts stderr $ldCommand
  eval exec $ldCommand

Added library/msgcat/msgcat.tcl.



































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# msgcat.tcl --
#
#	This file defines various procedures which implement a
#	message catalog facility for Tcl programs.  It should be
#	loaded with the command "package require msgcat".
#
# Copyright (c) 1998 by Scriptics Corporation.
# Copyright (c) 1998 by Mark Harrison.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# RCS: @(#) $Id: msgcat.tcl,v 1.1.2.5 1998/12/10 01:40:55 stanton Exp $

package provide msgcat 1.0

namespace eval msgcat {
    namespace export mc mcset mclocale mcpreferences mcunknown

    # Records the current locale as passed to mclocale
    variable locale ""

    # Records the list of locales to search
    variable loclist {}

    # Records the mapping between source strings and translated strings.  The
    # array key is of the form "<locale>,<namespace>,<src>" and the value is
    # the translated string.
    array set msgs {}
}

# msgcat::mc --
#
#	Find the translation for the given string based on the current
#	locale setting.
#
# Arguments:
#	src	The string to translate.
#
# Results:
#	Returns the translatd string.

proc msgcat::mc {src} {
    set ns [uplevel {namespace current}]
    foreach loc $::msgcat::loclist {
	if {[info exists ::msgcat::msgs($loc,$ns,$src)]} {
	    return $::msgcat::msgs($loc,$ns,$src)
	}
    }
    # we have not found the translation
    return [uplevel 1 [list [namespace origin mcunknown] \
	    $::msgcat::locale $src]]
}

# msgcat::mclocale --
#
#	Query or set the current locale.
#
# Arguments:
#	newLocale	(Optional) The new locale string. Locale strings
#			should be composed of one or more sublocale parts
#			separated by underscores (e.g. en_US).
#
# Results:
#	Returns the current locale.

proc msgcat::mclocale {args} {
    set len [llength $args]

    if {$len > 1} {
	error {wrong # args: should be "mclocale ?newLocale?"}
    }

    set args [string tolower $args]
    if {$len == 1} {
	set ::msgcat::locale $args
	set ::msgcat::loclist {}
	set word ""
	foreach part [split $args _] {
	    set word [string trimleft "${word}_${part}" _]
	    set ::msgcat::loclist \
                    [linsert $::msgcat::loclist 0 $word]
	}
    }
    return $::msgcat::locale
}

# msgcat::mcpreferences --
#
#	Fetch the list of locales used to look up strings, ordered from
#	most preferred to least preferred.
#
# Arguments:
#	None.
#
# Results:
#	Returns an ordered list of the locales preferred by the user.

proc msgcat::mcpreferences {} {
    return $::msgcat::loclist
}

# msgcat::mcload --
#
#	Attempt to load message catalogs for each locale in the
#	preference list from the specified directory.
#
# Arguments:
#	langdir		The directory to search.
#
# Results:
#	Returns the number of message catalogs that were loaded.

proc msgcat::mcload {langdir} {
    set x 0
    foreach p [::msgcat::mcpreferences] {
	set langfile [file join $langdir $p.msg]
	if {[file exists $langfile]} {
	    incr x
	    uplevel [list source $langfile]
	}
    }
    return $x
}

# msgcat::mcset --
#
#	Set the translation for a given string in a specified locale.
#
# Arguments:
#	locale		The locale to use.
#	src		The source string.
#	dest		(Optional) The translated string.  If omitted,
#			the source string is used.
#
# Results:
#	Returns the new locale.

proc msgcat::mcset {locale src {dest ""}} {
    if {$dest == ""} {
	set dest $src
    }

    set ns [uplevel {namespace current}]

    set ::msgcat::msgs([string tolower $locale],$ns,$src) $dest
    return $dest
}

# msgcat::mcunknown --
#
#	This routine is called by msgcat::mc if a translation cannot
#	be found for a string.  This routine is intended to be replaced
#	by an application specific routine for error reporting
#	purposes.  The default behavior is to return the source string.  
#
# Arguments:
#	locale		The current locale.
#	src		The string to be translated.
#
# Results:
#	Returns the translated value.

proc msgcat::mcunknown {locale src} {
    return $src
}

# Initialize the default locale

namespace eval msgcat {
    # set default locale, try to get from environment
    if {[info exists ::env(LANG)]} {
        mclocale $::env(LANG)
    } else {
        mclocale "C"
    }
}

Added library/msgcat/pkgIndex.tcl.



>
1
package ifneeded msgcat 1.0 [list source [file join $dir msgcat.tcl]]

Added library/msgcat1.0/msgcat.tcl.



































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# msgcat.tcl --
#
#	This file defines various procedures which implement a
#	message catalog facility for Tcl programs.  It should be
#	loaded with the command "package require msgcat".
#
# Copyright (c) 1998 by Scriptics Corporation.
# Copyright (c) 1998 by Mark Harrison.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# RCS: @(#) $Id: msgcat.tcl,v 1.1.2.5 1998/12/10 01:40:55 stanton Exp $

package provide msgcat 1.0

namespace eval msgcat {
    namespace export mc mcset mclocale mcpreferences mcunknown

    # Records the current locale as passed to mclocale
    variable locale ""

    # Records the list of locales to search
    variable loclist {}

    # Records the mapping between source strings and translated strings.  The
    # array key is of the form "<locale>,<namespace>,<src>" and the value is
    # the translated string.
    array set msgs {}
}

# msgcat::mc --
#
#	Find the translation for the given string based on the current
#	locale setting.
#
# Arguments:
#	src	The string to translate.
#
# Results:
#	Returns the translatd string.

proc msgcat::mc {src} {
    set ns [uplevel {namespace current}]
    foreach loc $::msgcat::loclist {
	if {[info exists ::msgcat::msgs($loc,$ns,$src)]} {
	    return $::msgcat::msgs($loc,$ns,$src)
	}
    }
    # we have not found the translation
    return [uplevel 1 [list [namespace origin mcunknown] \
	    $::msgcat::locale $src]]
}

# msgcat::mclocale --
#
#	Query or set the current locale.
#
# Arguments:
#	newLocale	(Optional) The new locale string. Locale strings
#			should be composed of one or more sublocale parts
#			separated by underscores (e.g. en_US).
#
# Results:
#	Returns the current locale.

proc msgcat::mclocale {args} {
    set len [llength $args]

    if {$len > 1} {
	error {wrong # args: should be "mclocale ?newLocale?"}
    }

    set args [string tolower $args]
    if {$len == 1} {
	set ::msgcat::locale $args
	set ::msgcat::loclist {}
	set word ""
	foreach part [split $args _] {
	    set word [string trimleft "${word}_${part}" _]
	    set ::msgcat::loclist \
                    [linsert $::msgcat::loclist 0 $word]
	}
    }
    return $::msgcat::locale
}

# msgcat::mcpreferences --
#
#	Fetch the list of locales used to look up strings, ordered from
#	most preferred to least preferred.
#
# Arguments:
#	None.
#
# Results:
#	Returns an ordered list of the locales preferred by the user.

proc msgcat::mcpreferences {} {
    return $::msgcat::loclist
}

# msgcat::mcload --
#
#	Attempt to load message catalogs for each locale in the
#	preference list from the specified directory.
#
# Arguments:
#	langdir		The directory to search.
#
# Results:
#	Returns the number of message catalogs that were loaded.

proc msgcat::mcload {langdir} {
    set x 0
    foreach p [::msgcat::mcpreferences] {
	set langfile [file join $langdir $p.msg]
	if {[file exists $langfile]} {
	    incr x
	    uplevel [list source $langfile]
	}
    }
    return $x
}

# msgcat::mcset --
#
#	Set the translation for a given string in a specified locale.
#
# Arguments:
#	locale		The locale to use.
#	src		The source string.
#	dest		(Optional) The translated string.  If omitted,
#			the source string is used.
#
# Results:
#	Returns the new locale.

proc msgcat::mcset {locale src {dest ""}} {
    if {$dest == ""} {
	set dest $src
    }

    set ns [uplevel {namespace current}]

    set ::msgcat::msgs([string tolower $locale],$ns,$src) $dest
    return $dest
}

# msgcat::mcunknown --
#
#	This routine is called by msgcat::mc if a translation cannot
#	be found for a string.  This routine is intended to be replaced
#	by an application specific routine for error reporting
#	purposes.  The default behavior is to return the source string.  
#
# Arguments:
#	locale		The current locale.
#	src		The string to be translated.
#
# Results:
#	Returns the translated value.

proc msgcat::mcunknown {locale src} {
    return $src
}

# Initialize the default locale

namespace eval msgcat {
    # set default locale, try to get from environment
    if {[info exists ::env(LANG)]} {
        mclocale $::env(LANG)
    } else {
        mclocale "C"
    }
}

Added library/msgcat1.0/pkgIndex.tcl.



>
1
package ifneeded msgcat 1.0 [list source [file join $dir msgcat.tcl]]

Added library/opt/optparse.tcl.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
# optparse.tcl --
#
#       (private) Option parsing package
#       Primarily used internally by the safe:: code.
#
#	WARNING: This code will go away in a future release
#	of Tcl.  It is NOT supported and you should not rely
#	on it.  If your code does rely on this package you
#	may directly incorporate this code into your application.
#
# RCS: @(#) $Id: optparse.tcl,v 1.1.2.2 1999/03/12 23:20:44 rjohnson Exp $

package provide opt 0.4.1

namespace eval ::tcl {

    # Exported APIs
    namespace export OptKeyRegister OptKeyDelete OptKeyError OptKeyParse \
             OptProc OptProcArgGiven OptParse \
	     Lempty Lget \
             Lassign Lvarpop Lvarpop1 Lvarset Lvarincr Lfirst Lrest \
             SetMax SetMin


#################  Example of use / 'user documentation'  ###################

    proc OptCreateTestProc {} {

	# Defines ::tcl::OptParseTest as a test proc with parsed arguments
	# (can't be defined before the code below is loaded (before "OptProc"))

	# Every OptProc give usage information on "procname -help".
	# Try "tcl::OptParseTest -help" and "tcl::OptParseTest -a" and
	# then other arguments.
	# 
	# example of 'valid' call:
	# ::tcl::OptParseTest save -4 -pr 23 -libsok SybTcl\
	#		-nostatics false ch1
	OptProc OptParseTest {
            {subcommand -choice {save print} "sub command"}
            {arg1 3 "some number"}
            {-aflag}
            {-intflag      7}
            {-weirdflag                    "help string"}
            {-noStatics                    "Not ok to load static packages"}
            {-nestedloading1 true           "OK to load into nested slaves"}
            {-nestedloading2 -boolean true "OK to load into nested slaves"}
            {-libsOK        -choice {Tk SybTcl}
		                      "List of packages that can be loaded"}
            {-precision     -int 12        "Number of digits of precision"}
            {-intval        7               "An integer"}
            {-scale         -float 1.0     "Scale factor"}
            {-zoom          1.0             "Zoom factor"}
            {-arbitrary     foobar          "Arbitrary string"}
            {-random        -string 12   "Random string"}
            {-listval       -list {}       "List value"}
            {-blahflag       -blah abc       "Funny type"}
	    {arg2 -boolean "a boolean"}
	    {arg3 -choice "ch1 ch2"}
	    {?optarg? -list {} "optional argument"}
        } {
	    foreach v [info locals] {
		puts stderr [format "%14s : %s" $v [set $v]]
	    }
	}
    }

###################  No User serviceable part below ! ###############
# You should really not look any further :
# The following is private unexported undocumented unblessed... code 
# time to hit "q" ;-) !

# Hmmm... ok, you really want to know ?

# You've been warned... Here it is...

    # Array storing the parsed descriptions
    variable OptDesc;
    array set OptDesc {};
    # Next potentially free key id (numeric)
    variable OptDescN 0;

# Inside algorithm/mechanism description:
# (not for the faint hearted ;-)
#
# The argument description is parsed into a "program tree"
# It is called a "program" because it is the program used by
# the state machine interpreter that use that program to
# actually parse the arguments at run time.
#
# The general structure of a "program" is
# notation (pseudo bnf like)
#    name :== definition        defines "name" as being "definition" 
#    { x y z }                  means list of x, y, and z  
#    x*                         means x repeated 0 or more time
#    x+                         means "x x*"
#    x?                         means optionally x
#    x | y                      means x or y
#    "cccc"                     means the literal string
#
#    program        :== { programCounter programStep* }
#
#    programStep    :== program | singleStep
#
#    programCounter :== {"P" integer+ }
#
#    singleStep     :== { instruction parameters* }
#
#    instruction    :== single element list
#
# (the difference between singleStep and program is that \
#   llength [Lfirst $program] >= 2
# while
#   llength [Lfirst $singleStep] == 1
# )
#
# And for this application:
#
#    singleStep     :== { instruction varname {hasBeenSet currentValue} type 
#                         typeArgs help }
#    instruction    :== "flags" | "value"
#    type           :== knowType | anyword
#    knowType       :== "string" | "int" | "boolean" | "boolflag" | "float"
#                       | "choice"
#
# for type "choice" typeArgs is a list of possible choices, the first one
# is the default value. for all other types the typeArgs is the default value
#
# a "boolflag" is the type for a flag whose presence or absence, without
# additional arguments means respectively true or false (default flag type).
#
# programCounter is the index in the list of the currently processed
# programStep (thus starting at 1 (0 is {"P" prgCounterValue}).
# If it is a list it points toward each currently selected programStep.
# (like for "flags", as they are optional, form a set and programStep).

# Performance/Implementation issues
# ---------------------------------
# We use tcl lists instead of arrays because with tcl8.0
# they should start to be much faster.
# But this code use a lot of helper procs (like Lvarset)
# which are quite slow and would be helpfully optimized
# for instance by being written in C. Also our struture
# is complex and there is maybe some places where the
# string rep might be calculated at great exense. to be checked.

#
# Parse a given description and saves it here under the given key
# generate a unused keyid if not given
#
proc ::tcl::OptKeyRegister {desc {key ""}} {
    variable OptDesc;
    variable OptDescN;
    if {[string compare $key ""] == 0} {
        # in case a key given to us as a parameter was a number
        while {[info exists OptDesc($OptDescN)]} {incr OptDescN}
        set key $OptDescN;
        incr OptDescN;
    }
    # program counter
    set program [list [list "P" 1]];

    # are we processing flags (which makes a single program step)
    set inflags 0;

    set state {};

    # flag used to detect that we just have a single (flags set) subprogram.
    set empty 1;

    foreach item $desc {
	if {$state == "args"} {
	    # more items after 'args'...
	    return -code error "'args' special argument must be the last one";
	}
        set res [OptNormalizeOne $item];
        set state [Lfirst $res];
        if {$inflags} {
            if {$state == "flags"} {
		# add to 'subprogram'
                lappend flagsprg $res;
            } else {
                # put in the flags
                # structure for flag programs items is a list of
                # {subprgcounter {prg flag 1} {prg flag 2} {...}}
                lappend program $flagsprg;
                # put the other regular stuff
                lappend program $res;
		set inflags 0;
		set empty 0;
            }
        } else {
           if {$state == "flags"} {
               set inflags 1;
               # sub program counter + first sub program
               set flagsprg [list [list "P" 1] $res];
           } else {
               lappend program $res;
               set empty 0;
           }
       }
   }
   if {$inflags} {
       if {$empty} {
	   # We just have the subprogram, optimize and remove
	   # unneeded level:
	   set program $flagsprg;
       } else {
	   lappend program $flagsprg;
       }
   }

   set OptDesc($key) $program;

   return $key;
}

#
# Free the storage for that given key
#
proc ::tcl::OptKeyDelete {key} {
    variable OptDesc;
    unset OptDesc($key);
}

    # Get the parsed description stored under the given key.
    proc OptKeyGetDesc {descKey} {
        variable OptDesc;
        if {![info exists OptDesc($descKey)]} {
            return -code error "Unknown option description key \"$descKey\"";
        }
        set OptDesc($descKey);
    }

# Parse entry point for ppl who don't want to register with a key,
# for instance because the description changes dynamically.
#  (otherwise one should really use OptKeyRegister once + OptKeyParse
#   as it is way faster or simply OptProc which does it all)
# Assign a temporary key, call OptKeyParse and then free the storage
proc ::tcl::OptParse {desc arglist} {
    set tempkey [OptKeyRegister $desc];
    set ret [catch {uplevel [list ::tcl::OptKeyParse $tempkey $arglist]} res];
    OptKeyDelete $tempkey;
    return -code $ret $res;
}

# Helper function, replacement for proc that both
# register the description under a key which is the name of the proc
# (and thus unique to that code)
# and add a first line to the code to call the OptKeyParse proc
# Stores the list of variables that have been actually given by the user
# (the other will be sets to their default value)
# into local variable named "Args".
proc ::tcl::OptProc {name desc body} {
    set namespace [uplevel namespace current];
    if {   ([string match $name "::*"]) 
        || ([string compare $namespace "::"]==0)} {
        # absolute name or global namespace, name is the key
        set key $name;
    } else {
        # we are relative to some non top level namespace:
        set key "${namespace}::${name}";
    }
    OptKeyRegister $desc $key;
    uplevel [list proc $name args "set Args \[::tcl::OptKeyParse $key \$args\]\n$body"];
    return $key;
}
# Check that a argument has been given
# assumes that "OptProc" has been used as it will check in "Args" list
proc ::tcl::OptProcArgGiven {argname} {
    upvar Args alist;
    expr {[lsearch $alist $argname] >=0}
}

    #######
    # Programs/Descriptions manipulation

    # Return the instruction word/list of a given step/(sub)program
    proc OptInstr {lst} {
	Lfirst $lst;
    }
    # Is a (sub) program or a plain instruction ?
    proc OptIsPrg {lst} {
	expr {[llength [OptInstr $lst]]>=2}
    }
    # Is this instruction a program counter or a real instr
    proc OptIsCounter {item} {
	expr {[Lfirst $item]=="P"}
    }
    # Current program counter (2nd word of first word)
    proc OptGetPrgCounter {lst} {
	Lget $lst {0 1}
    }
    # Current program counter (2nd word of first word)
    proc OptSetPrgCounter {lstName newValue} {
	upvar $lstName lst;
	set lst [lreplace $lst 0 0 [concat "P" $newValue]];
    }
    # returns a list of currently selected items.
    proc OptSelection {lst} {
	set res {};
	foreach idx [lrange [Lfirst $lst] 1 end] {
	    lappend res [Lget $lst $idx];
	}
	return $res;
    }

    # Advance to next description
    proc OptNextDesc {descName} {
        uplevel [list Lvarincr $descName {0 1}];
    }

    # Get the current description, eventually descend
    proc OptCurDesc {descriptions} {
        lindex $descriptions [OptGetPrgCounter $descriptions];
    }
    # get the current description, eventually descend
    # through sub programs as needed.
    proc OptCurDescFinal {descriptions} {
        set item [OptCurDesc $descriptions];
	# Descend untill we get the actual item and not a sub program
        while {[OptIsPrg $item]} {
            set item [OptCurDesc $item];
        }
	return $item;
    }
    # Current final instruction adress
    proc OptCurAddr {descriptions {start {}}} {
	set adress [OptGetPrgCounter $descriptions];
	lappend start $adress;
	set item [lindex $descriptions $adress];
	if {[OptIsPrg $item]} {
	    return [OptCurAddr $item $start];
	} else {
	    return $start;
	}
    }
    # Set the value field of the current instruction
    proc OptCurSetValue {descriptionsName value} {
	upvar $descriptionsName descriptions
	# get the current item full adress
        set adress [OptCurAddr $descriptions];
	# use the 3th field of the item  (see OptValue / OptNewInst)
	lappend adress 2
	Lvarset descriptions $adress [list 1 $value];
	#                                  ^hasBeenSet flag
    }

    # empty state means done/paste the end of the program
    proc OptState {item} {
        Lfirst $item
    }
    
    # current state
    proc OptCurState {descriptions} {
        OptState [OptCurDesc $descriptions];
    }

    #######
    # Arguments manipulation

    # Returns the argument that has to be processed now
    proc OptCurrentArg {lst} {
        Lfirst $lst;
    }
    # Advance to next argument
    proc OptNextArg {argsName} {
        uplevel [list Lvarpop1 $argsName];
    }
    #######





    # Loop over all descriptions, calling OptDoOne which will
    # eventually eat all the arguments.
    proc OptDoAll {descriptionsName argumentsName} {
	upvar $descriptionsName descriptions
	upvar $argumentsName arguments;
#	puts "entered DoAll";
	# Nb: the places where "state" can be set are tricky to figure
	#     because DoOne sets the state to flagsValue and return -continue
	#     when needed...
	set state [OptCurState $descriptions];
	# We'll exit the loop in "OptDoOne" or when state is empty.
        while 1 {
	    set curitem [OptCurDesc $descriptions];
	    # Do subprograms if needed, call ourselves on the sub branch
	    while {[OptIsPrg $curitem]} {
		OptDoAll curitem arguments
#		puts "done DoAll sub";
		# Insert back the results in current tree;
		Lvarset1nc descriptions [OptGetPrgCounter $descriptions]\
			$curitem;
		OptNextDesc descriptions;
		set curitem [OptCurDesc $descriptions];
                set state [OptCurState $descriptions];
	    }
#           puts "state = \"$state\" - arguments=($arguments)";
	    if {[Lempty $state]} {
		# Nothing left to do, we are done in this branch:
		break;
	    }
	    # The following statement can make us terminate/continue
	    # as it use return -code {break, continue, return and error}
	    # codes
            OptDoOne descriptions state arguments;
	    # If we are here, no special return code where issued,
	    # we'll step to next instruction :
#           puts "new state  = \"$state\"";
	    OptNextDesc descriptions;
	    set state [OptCurState $descriptions];
        }
    }

    # Process one step for the state machine,
    # eventually consuming the current argument.
    proc OptDoOne {descriptionsName stateName argumentsName} {
        upvar $argumentsName arguments;
        upvar $descriptionsName descriptions;
	upvar $stateName state;

	# the special state/instruction "args" eats all
	# the remaining args (if any)
	if {($state == "args")} {
	    if {![Lempty $arguments]} {
		# If there is no additional arguments, leave the default value
		# in.
		OptCurSetValue descriptions $arguments;
		set arguments {};
	    }
#            puts "breaking out ('args' state: consuming every reminding args)"
	    return -code break;
	}

	if {[Lempty $arguments]} {
	    if {$state == "flags"} {
		# no argument and no flags : we're done
#                puts "returning to previous (sub)prg (no more args)";
		return -code return;
	    } elseif {$state == "optValue"} {
		set state next; # not used, for debug only
		# go to next state
		return ;
	    } else {
		return -code error [OptMissingValue $descriptions];
	    }
	} else {
	    set arg [OptCurrentArg $arguments];
	}

        switch $state {
            flags {
                # A non-dash argument terminates the options, as does --

                # Still a flag ?
                if {![OptIsFlag $arg]} {
                    # don't consume the argument, return to previous prg
                    return -code return;
                }
                # consume the flag
                OptNextArg arguments;
                if {[string compare "--" $arg] == 0} {
                    # return from 'flags' state
                    return -code return;
                }

                set hits [OptHits descriptions $arg];
                if {$hits > 1} {
                    return -code error [OptAmbigous $descriptions $arg]
                } elseif {$hits == 0} {
                    return -code error [OptFlagUsage $descriptions $arg]
                }
		set item [OptCurDesc $descriptions];
                if {[OptNeedValue $item]} {
		    # we need a value, next state is
		    set state flagValue;
                } else {
                    OptCurSetValue descriptions 1;
                }
		# continue
		return -code continue;
            }
	    flagValue -
	    value {
		set item [OptCurDesc $descriptions];
                # Test the values against their required type
		if {[catch {OptCheckType $arg\
			[OptType $item] [OptTypeArgs $item]} val]} {
		    return -code error [OptBadValue $item $arg $val]
		}
                # consume the value
                OptNextArg arguments;
		# set the value
		OptCurSetValue descriptions $val;
		# go to next state
		if {$state == "flagValue"} {
		    set state flags
		    return -code continue;
		} else {
		    set state next; # not used, for debug only
		    return ; # will go on next step
		}
	    }
	    optValue {
		set item [OptCurDesc $descriptions];
                # Test the values against their required type
		if {![catch {OptCheckType $arg\
			[OptType $item] [OptTypeArgs $item]} val]} {
		    # right type, so :
		    # consume the value
		    OptNextArg arguments;
		    # set the value
		    OptCurSetValue descriptions $val;
		}
		# go to next state
		set state next; # not used, for debug only
		return ; # will go on next step
	    }
        }
	# If we reach this point: an unknown
	# state as been entered !
	return -code error "Bug! unknown state in DoOne \"$state\"\
		(prg counter [OptGetPrgCounter $descriptions]:\
			[OptCurDesc $descriptions])";
    }

# Parse the options given the key to previously registered description
# and arguments list
proc ::tcl::OptKeyParse {descKey arglist} {

    set desc [OptKeyGetDesc $descKey];

    # make sure -help always give usage
    if {[string compare "-help" [string tolower $arglist]] == 0} {
	return -code error [OptError "Usage information:" $desc 1];
    }

    OptDoAll desc arglist;

    if {![Lempty $arglist]} {
	return -code error [OptTooManyArgs $desc $arglist];
    }
    
    # Analyse the result
    # Walk through the tree:
    OptTreeVars $desc "#[expr {[info level]-1}]" ;
}

    # determine string length for nice tabulated output
    proc OptTreeVars {desc level {vnamesLst {}}} {
	foreach item $desc {
	    if {[OptIsCounter $item]} continue;
	    if {[OptIsPrg $item]} {
		set vnamesLst [OptTreeVars $item $level $vnamesLst];
	    } else {
		set vname [OptVarName $item];
		upvar $level $vname var
		if {[OptHasBeenSet $item]} {
#		    puts "adding $vname"
		    # lets use the input name for the returned list
		    # it is more usefull, for instance you can check that
		    # no flags at all was given with expr
		    # {![string match "*-*" $Args]}
		    lappend vnamesLst [OptName $item];
		    set var [OptValue $item];
		} else {
		    set var [OptDefaultValue $item];
		}
	    }
	}
	return $vnamesLst
    }


# Check the type of a value
# and emit an error if arg is not of the correct type
# otherwise returns the canonical value of that arg (ie 0/1 for booleans)
proc ::tcl::OptCheckType {arg type {typeArgs ""}} {
#    puts "checking '$arg' against '$type' ($typeArgs)";

    # only types "any", "choice", and numbers can have leading "-"

    switch -exact -- $type {
        int {
            if {![regexp {^(-+)?[0-9]+$} $arg]} {
                error "not an integer"
            }
	    return $arg;
        }
        float {
            return [expr {double($arg)}]
        }
	script -
        list {
	    # if llength fail : malformed list
            if {[llength $arg]==0} {
		if {[OptIsFlag $arg]} {
		    error "no values with leading -"
		}
	    }
	    return $arg;
        }
        boolean {
	    if {![regexp -nocase {^(true|false|0|1)$} $arg]} {
		error "non canonic boolean"
            }
	    # convert true/false because expr/if is broken with "!,...
	    if {$arg} {
		return 1
	    } else {
		return 0
	    }
        }
        choice {
            if {[lsearch -exact $typeArgs $arg] < 0} {
                error "invalid choice"
            }
	    return $arg;
        }
	any {
	    return $arg;
	}
	string -
	default {
            if {[OptIsFlag $arg]} {
                error "no values with leading -"
            }
	    return $arg
        }
    }
    return neverReached;
}

    # internal utilities

    # returns the number of flags matching the given arg
    # sets the (local) prg counter to the list of matches
    proc OptHits {descName arg} {
        upvar $descName desc;
        set hits 0
        set hitems {}
	set i 1;

	set larg [string tolower $arg];
	set len  [string length $larg];
	set last [expr {$len-1}];

        foreach item [lrange $desc 1 end] {
            set flag [OptName $item]
	    # lets try to match case insensitively
	    # (string length ought to be cheap)
	    set lflag [string tolower $flag];
	    if {$len == [string length $lflag]} {
		if {[string compare $larg $lflag]==0} {
		    # Exact match case
		    OptSetPrgCounter desc $i;
		    return 1;
		}
	    } else {
		if {[string compare $larg [string range $lflag 0 $last]]==0} {
		    lappend hitems $i;
		    incr hits;
		}
            }
	    incr i;
        }
	if {$hits} {
	    OptSetPrgCounter desc $hitems;
	}
        return $hits
    }

    # Extract fields from the list structure:

    proc OptName {item} {
        lindex $item 1;
    }
    # 
    proc OptHasBeenSet {item} {
	Lget $item {2 0};
    }
    # 
    proc OptValue {item} {
	Lget $item {2 1};
    }

    proc OptIsFlag {name} {
        string match "-*" $name;
    }
    proc OptIsOpt {name} {
        string match {\?*} $name;
    }
    proc OptVarName {item} {
        set name [OptName $item];
        if {[OptIsFlag $name]} {
            return [string range $name 1 end];
        } elseif {[OptIsOpt $name]} {
	    return [string trim $name "?"];
	} else {
            return $name;
        }
    }
    proc OptType {item} {
        lindex $item 3
    }
    proc OptTypeArgs {item} {
        lindex $item 4
    }
    proc OptHelp {item} {
        lindex $item 5
    }
    proc OptNeedValue {item} {
        string compare [OptType $item] boolflag
    }
    proc OptDefaultValue {item} {
        set val [OptTypeArgs $item]
        switch -exact -- [OptType $item] {
            choice {return [lindex $val 0]}
	    boolean -
	    boolflag {
		# convert back false/true to 0/1 because expr !$bool
		# is broken..
		if {$val} {
		    return 1
		} else {
		    return 0
		}
	    }
        }
        return $val
    }

    # Description format error helper
    proc OptOptUsage {item {what ""}} {
        return -code error "invalid description format$what: $item\n\
                should be a list of {varname|-flagname ?-type? ?defaultvalue?\
                ?helpstring?}";
    }


    # Generate a canonical form single instruction
    proc OptNewInst {state varname type typeArgs help} {
	list $state $varname [list 0 {}] $type $typeArgs $help;
	#                          ^  ^
	#                          |  |
	#               hasBeenSet=+  +=currentValue
    }

    # Translate one item to canonical form
    proc OptNormalizeOne {item} {
        set lg [Lassign $item varname arg1 arg2 arg3];
#       puts "called optnormalizeone '$item' v=($varname), lg=$lg";
        set isflag [OptIsFlag $varname];
	set isopt  [OptIsOpt  $varname];
        if {$isflag} {
            set state "flags";
        } elseif {$isopt} {
	    set state "optValue";
	} elseif {[string compare $varname "args"]} {
	    set state "value";
	} else {
	    set state "args";
	}

	# apply 'smart' 'fuzzy' logic to try to make
	# description writer's life easy, and our's difficult :
	# let's guess the missing arguments :-)

        switch $lg {
            1 {
                if {$isflag} {
                    return [OptNewInst $state $varname boolflag false ""];
                } else {
                    return [OptNewInst $state $varname any "" ""];
                }
            }
            2 {
                # varname default
                # varname help
                set type [OptGuessType $arg1]
                if {[string compare $type "string"] == 0} {
                    if {$isflag} {
			set type boolflag
			set def false
		    } else {
			set type any
			set def ""
		    }
		    set help $arg1
                } else {
                    set help ""
                    set def $arg1
                }
                return [OptNewInst $state $varname $type $def $help];
            }
            3 {
                # varname type value
                # varname value comment
		
                if {[regexp {^-(.+)$} $arg1 x type]} {
		    # flags/optValue as they are optional, need a "value",
		    # on the contrary, for a variable (non optional),
	            # default value is pointless, 'cept for choices :
		    if {$isflag || $isopt || ($type == "choice")} {
			return [OptNewInst $state $varname $type $arg2 ""];
		    } else {
			return [OptNewInst $state $varname $type "" $arg2];
		    }
                } else {
                    return [OptNewInst $state $varname\
			    [OptGuessType $arg1] $arg1 $arg2]
                }
            }
            4 {
                if {[regexp {^-(.+)$} $arg1 x type]} {
		    return [OptNewInst $state $varname $type $arg2 $arg3];
                } else {
                    return -code error [OptOptUsage $item];
                }
            }
            default {
                return -code error [OptOptUsage $item];
            }
        }
    }

    # Auto magic lasy type determination
    proc OptGuessType {arg} {
        if {[regexp -nocase {^(true|false)$} $arg]} {
            return boolean
        }
        if {[regexp {^(-+)?[0-9]+$} $arg]} {
            return int
        }
        if {![catch {expr {double($arg)}}]} {
            return float
        }
        return string
    }

    # Error messages front ends

    proc OptAmbigous {desc arg} {
        OptError "ambigous option \"$arg\", choose from:" [OptSelection $desc]
    }
    proc OptFlagUsage {desc arg} {
        OptError "bad flag \"$arg\", must be one of" $desc;
    }
    proc OptTooManyArgs {desc arguments} {
        OptError "too many arguments (unexpected argument(s): $arguments),\
		usage:"\
		$desc 1
    }
    proc OptParamType {item} {
	if {[OptIsFlag $item]} {
	    return "flag";
	} else {
	    return "parameter";
	}
    }
    proc OptBadValue {item arg {err {}}} {
#       puts "bad val err = \"$err\"";
        OptError "bad value \"$arg\" for [OptParamType $item]"\
		[list $item]
    }
    proc OptMissingValue {descriptions} {
#        set item [OptCurDescFinal $descriptions];
        set item [OptCurDesc $descriptions];
        OptError "no value given for [OptParamType $item] \"[OptName $item]\"\
		(use -help for full usage) :"\
		[list $item]
    }

proc ::tcl::OptKeyError {prefix descKey {header 0}} {
    OptError $prefix [OptKeyGetDesc $descKey] $header;
}

    # determine string length for nice tabulated output
    proc OptLengths {desc nlName tlName dlName} {
	upvar $nlName nl;
	upvar $tlName tl;
	upvar $dlName dl;
	foreach item $desc {
	    if {[OptIsCounter $item]} continue;
	    if {[OptIsPrg $item]} {
		OptLengths $item nl tl dl
	    } else {
		SetMax nl [string length [OptName $item]]
		SetMax tl [string length [OptType $item]]
		set dv [OptTypeArgs $item];
		if {[OptState $item] != "header"} {
		    set dv "($dv)";
		}
		set l [string length $dv];
		# limit the space allocated to potentially big "choices"
		if {([OptType $item] != "choice") || ($l<=12)} {
		    SetMax dl $l
		} else {
		    if {![info exists dl]} {
			set dl 0
		    }
		}
	    }
	}
    }
    # output the tree
    proc OptTree {desc nl tl dl} {
	set res "";
	foreach item $desc {
	    if {[OptIsCounter $item]} continue;
	    if {[OptIsPrg $item]} {
		append res [OptTree $item $nl $tl $dl];
	    } else {
		set dv [OptTypeArgs $item];
		if {[OptState $item] != "header"} {
		    set dv "($dv)";
		}
		append res [format "\n    %-*s %-*s %-*s %s" \
			$nl [OptName $item] $tl [OptType $item] \
			$dl $dv [OptHelp $item]]
	    }
	}
	return $res;
    }

# Give nice usage string
proc ::tcl::OptError {prefix desc {header 0}} {
    # determine length
    if {$header} {
	# add faked instruction
	set h [list [OptNewInst header Var/FlagName Type Value Help]];
	lappend h   [OptNewInst header ------------ ---- ----- ----];
	lappend h   [OptNewInst header {( -help} "" "" {gives this help )}]
	set desc [concat $h $desc]
    }
    OptLengths $desc nl tl dl
    # actually output 
    return "$prefix[OptTree $desc $nl $tl $dl]"
}


################     General Utility functions   #######################

#
# List utility functions
# Naming convention:
#     "Lvarxxx" take the list VARiable name as argument
#     "Lxxxx"   take the list value as argument
#               (which is not costly with Tcl8 objects system
#                as it's still a reference and not a copy of the values)
#

# Is that list empty ?
proc ::tcl::Lempty {list} {
    expr {[llength $list]==0}
}

# Gets the value of one leaf of a lists tree
proc ::tcl::Lget {list indexLst} {
    if {[llength $indexLst] <= 1} {
        return [lindex $list $indexLst];
    }
    Lget [lindex $list [Lfirst $indexLst]] [Lrest $indexLst];
}
# Sets the value of one leaf of a lists tree
# (we use the version that does not create the elements because
#  it would be even slower... needs to be written in C !)
# (nb: there is a non trivial recursive problem with indexes 0,
#  which appear because there is no difference between a list
#  of 1 element and 1 element alone : [list "a"] == "a" while 
#  it should be {a} and [listp a] should be 0 while [listp {a b}] would be 1
#  and [listp "a b"] maybe 0. listp does not exist either...)
proc ::tcl::Lvarset {listName indexLst newValue} {
    upvar $listName list;
    if {[llength $indexLst] <= 1} {
        Lvarset1nc list $indexLst $newValue;
    } else {
        set idx [Lfirst $indexLst];
        set targetList [lindex $list $idx];
        # reduce refcount on targetList (not really usefull now,
	# could be with optimizing compiler)
#        Lvarset1 list $idx {};
        # recursively replace in targetList
        Lvarset targetList [Lrest $indexLst] $newValue;
        # put updated sub list back in the tree
        Lvarset1nc list $idx $targetList;
    }
}
# Set one cell to a value, eventually create all the needed elements
# (on level-1 of lists)
variable emptyList {}
proc ::tcl::Lvarset1 {listName index newValue} {
    upvar $listName list;
    if {$index < 0} {return -code error "invalid negative index"}
    set lg [llength $list];
    if {$index >= $lg} {
        variable emptyList;
        for {set i $lg} {$i<$index} {incr i} {
            lappend list $emptyList;
        }
        lappend list $newValue;
    } else {
        set list [lreplace $list $index $index $newValue];
    }
}
# same as Lvarset1 but no bound checking / creation
proc ::tcl::Lvarset1nc {listName index newValue} {
    upvar $listName list;
    set list [lreplace $list $index $index $newValue];
}
# Increments the value of one leaf of a lists tree
# (which must exists)
proc ::tcl::Lvarincr {listName indexLst {howMuch 1}} {
    upvar $listName list;
    if {[llength $indexLst] <= 1} {
        Lvarincr1 list $indexLst $howMuch;
    } else {
        set idx [Lfirst $indexLst];
        set targetList [lindex $list $idx];
        # reduce refcount on targetList
        Lvarset1nc list $idx {};
        # recursively replace in targetList
        Lvarincr targetList [Lrest $indexLst] $howMuch;
        # put updated sub list back in the tree
        Lvarset1nc list $idx $targetList;
    }
}
# Increments the value of one cell of a list
proc ::tcl::Lvarincr1 {listName index {howMuch 1}} {
    upvar $listName list;
    set newValue [expr {[lindex $list $index]+$howMuch}];
    set list [lreplace $list $index $index $newValue];
    return $newValue;
}
# Returns the first element of a list
proc ::tcl::Lfirst {list} {
    lindex $list 0
}
# Returns the rest of the list minus first element
proc ::tcl::Lrest {list} {
    lrange $list 1 end
}
# Removes the first element of a list
# and returns the new list value
proc ::tcl::Lvarpop1 {listName} {
    upvar $listName list;
    set list [lrange $list 1 end];
}
# Same but returns the removed element
# (Like the tclX version)
proc ::tcl::Lvarpop {listName} {
    upvar $listName list;
    set el [Lfirst $list];
    set list [lrange $list 1 end];
    return $el;
}
# Assign list elements to variables and return the length of the list
proc ::tcl::Lassign {list args} {
    # faster than direct blown foreach (which does not byte compile)
    set i 0;
    set lg [llength $list];
    foreach vname $args {
        if {$i>=$lg} break
        uplevel [list set $vname [lindex $list $i]];
        incr i;
    }
    return $lg;
}

# Misc utilities

# Set the varname to value if value is greater than varname's current value
# or if varname is undefined
proc ::tcl::SetMax {varname value} {
    upvar 1 $varname var
    if {![info exists var] || $value > $var} {
        set var $value
    }
}

# Set the varname to value if value is smaller than varname's current value
# or if varname is undefined
proc ::tcl::SetMin {varname value} {
    upvar 1 $varname var
    if {![info exists var] || $value < $var} {
        set var $value
    }
}


    # everything loaded fine, lets create the test proc:
 #    OptCreateTestProc
    # Don't need the create temp proc anymore:
 #    rename OptCreateTestProc {}
}

Added library/opt/pkgIndex.tcl.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
# Tcl package index file, version 1.1
# This file is generated by the "pkg_mkIndex -direct" command
# and sourced either when an application starts up or
# by a "package unknown" script.  It invokes the
# "package ifneeded" command to set up package-related
# information so that packages will be loaded automatically
# in response to "package require" commands.  When this
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.

package ifneeded opt 0.4.1 [list source [file join $dir optparse.tcl]]

Deleted library/opt0.1/optparse.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
# optparse.tcl --
#
#       (Private) option parsing package
#
#       This might be documented and exported in 8.1
#       and some function hopefully moved to the C core for
#       efficiency, if there is enough demand. (mail! ;-)
#
#  Author:    Laurent Demailly  - [email protected] - [email protected]
#
#  Credits:
#             this is a complete 'over kill' rewrite by me, from a version
#             written initially with Brent Welch, itself initially
#             based on work with Steve Uhler. Thanks them !
#
# SCCS: @(#) optparse.tcl 1.13 97/08/21 11:50:42

package provide opt 0.2

namespace eval ::tcl {

    # Exported APIs
    namespace export OptKeyRegister OptKeyDelete OptKeyError OptKeyParse \
             OptProc OptProcArgGiven OptParse \
             Lassign Lvarpop Lvarset Lvarincr Lfirst \
             SetMax SetMin


#################  Example of use / 'user documentation'  ###################

    proc OptCreateTestProc {} {

	# Defines ::tcl::OptParseTest as a test proc with parsed arguments
	# (can't be defined before the code below is loaded (before "OptProc"))

	# Every OptProc give usage information on "procname -help".
	# Try "tcl::OptParseTest -help" and "tcl::OptParseTest -a" and
	# then other arguments.
	# 
	# example of 'valid' call:
	# ::tcl::OptParseTest save -4 -pr 23 -libsok SybTcl\
	#		-nostatics false ch1
	OptProc OptParseTest {
            {subcommand -choice {save print} "sub command"}
            {arg1 3 "some number"}
            {-aflag}
            {-intflag      7}
            {-weirdflag                    "help string"}
            {-noStatics                    "Not ok to load static packages"}
            {-nestedloading1 true           "OK to load into nested slaves"}
            {-nestedloading2 -boolean true "OK to load into nested slaves"}
            {-libsOK        -choice {Tk SybTcl}
		                      "List of packages that can be loaded"}
            {-precision     -int 12        "Number of digits of precision"}
            {-intval        7               "An integer"}
            {-scale         -float 1.0     "Scale factor"}
            {-zoom          1.0             "Zoom factor"}
            {-arbitrary     foobar          "Arbitrary string"}
            {-random        -string 12   "Random string"}
            {-listval       -list {}       "List value"}
            {-blahflag       -blah abc       "Funny type"}
	    {arg2 -boolean "a boolean"}
	    {arg3 -choice "ch1 ch2"}
	    {?optarg? -list {} "optional argument"}
        } {
	    foreach v [info locals] {
		puts stderr [format "%14s : %s" $v [set $v]]
	    }
	}
    }

###################  No User serviceable part below ! ###############
# You should really not look any further :
# The following is private unexported undocumented unblessed... code 
# time to hit "q" ;-) !

# Hmmm... ok, you really want to know ?

# You've been warned... Here it is...

    # Array storing the parsed descriptions
    variable OptDesc;
    array set OptDesc {};
    # Next potentially free key id (numeric)
    variable OptDescN 0;

# Inside algorithm/mechanism description:
# (not for the faint hearted ;-)
#
# The argument description is parsed into a "program tree"
# It is called a "program" because it is the program used by
# the state machine interpreter that use that program to
# actually parse the arguments at run time.
#
# The general structure of a "program" is
# notation (pseudo bnf like)
#    name :== definition        defines "name" as being "definition" 
#    { x y z }                  means list of x, y, and z  
#    x*                         means x repeated 0 or more time
#    x+                         means "x x*"
#    x?                         means optionally x
#    x | y                      means x or y
#    "cccc"                     means the literal string
#
#    program        :== { programCounter programStep* }
#
#    programStep    :== program | singleStep
#
#    programCounter :== {"P" integer+ }
#
#    singleStep     :== { instruction parameters* }
#
#    instruction    :== single element list
#
# (the difference between singleStep and program is that \
#   llength [Lfirst $program] >= 2
# while
#   llength [Lfirst $singleStep] == 1
# )
#
# And for this application:
#
#    singleStep     :== { instruction varname {hasBeenSet currentValue} type 
#                         typeArgs help }
#    instruction    :== "flags" | "value"
#    type           :== knowType | anyword
#    knowType       :== "string" | "int" | "boolean" | "boolflag" | "float"
#                       | "choice"
#
# for type "choice" typeArgs is a list of possible choices, the first one
# is the default value. for all other types the typeArgs is the default value
#
# a "boolflag" is the type for a flag whose presence or absence, without
# additional arguments means respectively true or false (default flag type).
#
# programCounter is the index in the list of the currently processed
# programStep (thus starting at 1 (0 is {"P" prgCounterValue}).
# If it is a list it points toward each currently selected programStep.
# (like for "flags", as they are optional, form a set and programStep).

# Performance/Implementation issues
# ---------------------------------
# We use tcl lists instead of arrays because with tcl8.0
# they should start to be much faster.
# But this code use a lot of helper procs (like Lvarset)
# which are quite slow and would be helpfully optimized
# for instance by being written in C. Also our struture
# is complex and there is maybe some places where the
# string rep might be calculated at great exense. to be checked.

#
# Parse a given description and saves it here under the given key
# generate a unused keyid if not given
#
proc ::tcl::OptKeyRegister {desc {key ""}} {
    variable OptDesc;
    variable OptDescN;
    if {[string compare $key ""] == 0} {
        # in case a key given to us as a parameter was a number
        while {[info exists OptDesc($OptDescN)]} {incr OptDescN}
        set key $OptDescN;
        incr OptDescN;
    }
    # program counter
    set program [list [list "P" 1]];

    # are we processing flags (which makes a single program step)
    set inflags 0;

    set state {};

    # flag used to detect that we just have a single (flags set) subprogram.
    set empty 1;

    foreach item $desc {
	if {$state == "args"} {
	    # more items after 'args'...
	    return -code error "'args' special argument must be the last one";
	}
        set res [OptNormalizeOne $item];
        set state [Lfirst $res];
        if {$inflags} {
            if {$state == "flags"} {
		# add to 'subprogram'
                lappend flagsprg $res;
            } else {
                # put in the flags
                # structure for flag programs items is a list of
                # {subprgcounter {prg flag 1} {prg flag 2} {...}}
                lappend program $flagsprg;
                # put the other regular stuff
                lappend program $res;
		set inflags 0;
		set empty 0;
            }
        } else {
           if {$state == "flags"} {
               set inflags 1;
               # sub program counter + first sub program
               set flagsprg [list [list "P" 1] $res];
           } else {
               lappend program $res;
               set empty 0;
           }
       }
   }
   if {$inflags} {
       if {$empty} {
	   # We just have the subprogram, optimize and remove
	   # unneeded level:
	   set program $flagsprg;
       } else {
	   lappend program $flagsprg;
       }
   }

   set OptDesc($key) $program;

   return $key;
}

#
# Free the storage for that given key
#
proc ::tcl::OptKeyDelete {key} {
    variable OptDesc;
    unset OptDesc($key);
}

    # Get the parsed description stored under the given key.
    proc OptKeyGetDesc {descKey} {
        variable OptDesc;
        if {![info exists OptDesc($descKey)]} {
            return -code error "Unknown option description key \"$descKey\"";
        }
        set OptDesc($descKey);
    }

# Parse entry point for ppl who don't want to register with a key,
# for instance because the description changes dynamically.
#  (otherwise one should really use OptKeyRegister once + OptKeyParse
#   as it is way faster or simply OptProc which does it all)
# Assign a temporary key, call OptKeyParse and then free the storage
proc ::tcl::OptParse {desc arglist} {
    set tempkey [OptKeyRegister $desc];
    set ret [catch {uplevel [list ::tcl::OptKeyParse $tempkey $arglist]} res];
    OptKeyDelete $tempkey;
    return -code $ret $res;
}

# Helper function, replacement for proc that both
# register the description under a key which is the name of the proc
# (and thus unique to that code)
# and add a first line to the code to call the OptKeyParse proc
# Stores the list of variables that have been actually given by the user
# (the other will be sets to their default value)
# into local variable named "Args".
proc ::tcl::OptProc {name desc body} {
    set namespace [uplevel namespace current];
    if {   ([string match $name "::*"]) 
        || ([string compare $namespace "::"]==0)} {
        # absolute name or global namespace, name is the key
        set key $name;
    } else {
        # we are relative to some non top level namespace:
        set key "${namespace}::${name}";
    }
    OptKeyRegister $desc $key;
    uplevel [list proc $name args "set Args \[::tcl::OptKeyParse $key \$args\]\n$body"];
    return $key;
}
# Check that a argument has been given
# assumes that "OptProc" has been used as it will check in "Args" list
proc ::tcl::OptProcArgGiven {argname} {
    upvar Args alist;
    expr {[lsearch $alist $argname] >=0}
}

    #######
    # Programs/Descriptions manipulation

    # Return the instruction word/list of a given step/(sub)program
    proc OptInstr {lst} {
	Lfirst $lst;
    }
    # Is a (sub) program or a plain instruction ?
    proc OptIsPrg {lst} {
	expr {[llength [OptInstr $lst]]>=2}
    }
    # Is this instruction a program counter or a real instr
    proc OptIsCounter {item} {
	expr {[Lfirst $item]=="P"}
    }
    # Current program counter (2nd word of first word)
    proc OptGetPrgCounter {lst} {
	Lget $lst {0 1}
    }
    # Current program counter (2nd word of first word)
    proc OptSetPrgCounter {lstName newValue} {
	upvar $lstName lst;
	set lst [lreplace $lst 0 0 [concat "P" $newValue]];
    }
    # returns a list of currently selected items.
    proc OptSelection {lst} {
	set res {};
	foreach idx [lrange [Lfirst $lst] 1 end] {
	    lappend res [Lget $lst $idx];
	}
	return $res;
    }

    # Advance to next description
    proc OptNextDesc {descName} {
        uplevel [list Lvarincr $descName {0 1}];
    }

    # Get the current description, eventually descend
    proc OptCurDesc {descriptions} {
        lindex $descriptions [OptGetPrgCounter $descriptions];
    }
    # get the current description, eventually descend
    # through sub programs as needed.
    proc OptCurDescFinal {descriptions} {
        set item [OptCurDesc $descriptions];
	# Descend untill we get the actual item and not a sub program
        while {[OptIsPrg $item]} {
            set item [OptCurDesc $item];
        }
	return $item;
    }
    # Current final instruction adress
    proc OptCurAddr {descriptions {start {}}} {
	set adress [OptGetPrgCounter $descriptions];
	lappend start $adress;
	set item [lindex $descriptions $adress];
	if {[OptIsPrg $item]} {
	    return [OptCurAddr $item $start];
	} else {
	    return $start;
	}
    }
    # Set the value field of the current instruction
    proc OptCurSetValue {descriptionsName value} {
	upvar $descriptionsName descriptions
	# get the current item full adress
        set adress [OptCurAddr $descriptions];
	# use the 3th field of the item  (see OptValue / OptNewInst)
	lappend adress 2
	Lvarset descriptions $adress [list 1 $value];
	#                                  ^hasBeenSet flag
    }

    # empty state means done/paste the end of the program
    proc OptState {item} {
        Lfirst $item
    }
    
    # current state
    proc OptCurState {descriptions} {
        OptState [OptCurDesc $descriptions];
    }

    #######
    # Arguments manipulation

    # Returns the argument that has to be processed now
    proc OptCurrentArg {lst} {
        Lfirst $lst;
    }
    # Advance to next argument
    proc OptNextArg {argsName} {
        uplevel [list Lvarpop $argsName];
    }
    #######





    # Loop over all descriptions, calling OptDoOne which will
    # eventually eat all the arguments.
    proc OptDoAll {descriptionsName argumentsName} {
	upvar $descriptionsName descriptions
	upvar $argumentsName arguments;
#	puts "entered DoAll";
	# Nb: the places where "state" can be set are tricky to figure
	#     because DoOne sets the state to flagsValue and return -continue
	#     when needed...
	set state [OptCurState $descriptions];
	# We'll exit the loop in "OptDoOne" or when state is empty.
        while 1 {
	    set curitem [OptCurDesc $descriptions];
	    # Do subprograms if needed, call ourselves on the sub branch
	    while {[OptIsPrg $curitem]} {
		OptDoAll curitem arguments
#		puts "done DoAll sub";
		# Insert back the results in current tree;
		Lvarset1nc descriptions [OptGetPrgCounter $descriptions]\
			$curitem;
		OptNextDesc descriptions;
		set curitem [OptCurDesc $descriptions];
                set state [OptCurState $descriptions];
	    }
#           puts "state = \"$state\" - arguments=($arguments)";
	    if {[Lempty $state]} {
		# Nothing left to do, we are done in this branch:
		break;
	    }
	    # The following statement can make us terminate/continue
	    # as it use return -code {break, continue, return and error}
	    # codes
            OptDoOne descriptions state arguments;
	    # If we are here, no special return code where issued,
	    # we'll step to next instruction :
#           puts "new state  = \"$state\"";
	    OptNextDesc descriptions;
	    set state [OptCurState $descriptions];
        }
        if  {![Lempty $arguments]} {
            return -code error [OptTooManyArgs $descriptions $arguments];
        }
    }

    # Process one step for the state machine,
    # eventually consuming the current argument.
    proc OptDoOne {descriptionsName stateName argumentsName} {
        upvar $argumentsName arguments;
        upvar $descriptionsName descriptions;
	upvar $stateName state;

	# the special state/instruction "args" eats all
	# the remaining args (if any)
	if {($state == "args")} {
	    OptCurSetValue descriptions $arguments;
	    set arguments {};
#            puts "breaking out ('args' state: consuming every reminding args)"
	    return -code break;
	}

	if {[Lempty $arguments]} {
	    if {$state == "flags"} {
		# no argument and no flags : we're done
#                puts "returning to previous (sub)prg (no more args)";
		return -code return;
	    } elseif {$state == "optValue"} {
		set state next; # not used, for debug only
		# go to next state
		return ;
	    } else {
		return -code error [OptMissingValue $descriptions];
	    }
	} else {
	    set arg [OptCurrentArg $arguments];
	}

        switch $state {
            flags {
                # A non-dash argument terminates the options, as does --

                # Still a flag ?
                if {![OptIsFlag $arg]} {
                    # don't consume the argument, return to previous prg
                    return -code return;
                }
                # consume the flag
                OptNextArg arguments;
                if {[string compare "--" $arg] == 0} {
                    # return from 'flags' state
                    return -code return;
                }

                set hits [OptHits descriptions $arg];
                if {$hits > 1} {
                    return -code error [OptAmbigous $descriptions $arg]
                } elseif {$hits == 0} {
                    return -code error [OptFlagUsage $descriptions $arg]
                }
		set item [OptCurDesc $descriptions];
                if {[OptNeedValue $item]} {
		    # we need a value, next state is
		    set state flagValue;
                } else {
                    OptCurSetValue descriptions 1;
                }
		# continue
		return -code continue;
            }
	    flagValue -
	    value {
		set item [OptCurDesc $descriptions];
                # Test the values against their required type
		if [catch {OptCheckType $arg\
			[OptType $item] [OptTypeArgs $item]} val] {
		    return -code error [OptBadValue $item $arg $val]
		}
                # consume the value
                OptNextArg arguments;
		# set the value
		OptCurSetValue descriptions $val;
		# go to next state
		if {$state == "flagValue"} {
		    set state flags
		    return -code continue;
		} else {
		    set state next; # not used, for debug only
		    return ; # will go on next step
		}
	    }
	    optValue {
		set item [OptCurDesc $descriptions];
                # Test the values against their required type
		if ![catch {OptCheckType $arg\
			[OptType $item] [OptTypeArgs $item]} val] {
		    # right type, so :
		    # consume the value
		    OptNextArg arguments;
		    # set the value
		    OptCurSetValue descriptions $val;
		}
		# go to next state
		set state next; # not used, for debug only
		return ; # will go on next step
	    }
        }
	# If we reach this point: an unknown
	# state as been entered !
	return -code error "Bug! unknown state in DoOne \"$state\"\
		(prg counter [OptGetPrgCounter $descriptions]:\
			[OptCurDesc $descriptions])";
    }

# Parse the options given the key to previously registered description
# and arguments list
proc ::tcl::OptKeyParse {descKey arglist} {

    set desc [OptKeyGetDesc $descKey];

    # make sure -help always give usage
    if {[string compare "-help" [string tolower $arglist]] == 0} {
	return -code error [OptError "Usage information:" $desc 1];
    }

    OptDoAll desc arglist;
    
    # Analyse the result
    # Walk through the tree:
    OptTreeVars $desc "#[expr [info level]-1]" ;
}

    # determine string length for nice tabulated output
    proc OptTreeVars {desc level {vnamesLst {}}} {
	foreach item $desc {
	    if {[OptIsCounter $item]} continue;
	    if {[OptIsPrg $item]} {
		set vnamesLst [OptTreeVars $item $level $vnamesLst];
	    } else {
		set vname [OptVarName $item];
		upvar $level $vname var
		if {[OptHasBeenSet $item]} {
#		    puts "adding $vname"
		    # lets use the input name for the returned list
		    # it is more usefull, for instance you can check that
		    # no flags at all was given with expr
		    # {![string match "*-*" $Args]}
		    lappend vnamesLst [OptName $item];
		    set var [OptValue $item];
		} else {
		    set var [OptDefaultValue $item];
		}
	    }
	}
	return $vnamesLst
    }


# Check the type of a value
# and emit an error if arg is not of the correct type
# otherwise returns the canonical value of that arg (ie 0/1 for booleans)
proc ::tcl::OptCheckType {arg type {typeArgs ""}} {
#    puts "checking '$arg' against '$type' ($typeArgs)";

    # only types "any", "choice", and numbers can have leading "-"

    switch -exact -- $type {
        int {
            if ![regexp {^(-+)?[0-9]+$} $arg] {
                error "not an integer"
            }
	    return $arg;
        }
        float {
            return [expr double($arg)]
        }
	script -
        list {
	    # if llength fail : malformed list
            if {[llength $arg]==0} {
		if {[OptIsFlag $arg]} {
		    error "no values with leading -"
		}
	    }
	    return $arg;
        }
        boolean {
	    if ![regexp -nocase {^(true|false|0|1)$} $arg] {
		error "non canonic boolean"
            }
	    # convert true/false because expr/if is broken with "!,...
	    if {$arg} {
		return 1
	    } else {
		return 0
	    }
        }
        choice {
            if {[lsearch -exact $typeArgs $arg] < 0} {
                error "invalid choice"
            }
	    return $arg;
        }
	any {
	    return $arg;
	}
	string -
	default {
            if {[OptIsFlag $arg]} {
                error "no values with leading -"
            }
	    return $arg
        }
    }
    return neverReached;
}

    # internal utilities

    # returns the number of flags matching the given arg
    # sets the (local) prg counter to the list of matches
    proc OptHits {descName arg} {
        upvar $descName desc;
        set hits 0
        set hitems {}
	set i 1;

	set larg [string tolower $arg];
	set len  [string length $larg];
	set last [expr $len-1];

        foreach item [lrange $desc 1 end] {
            set flag [OptName $item]
	    # lets try to match case insensitively
	    # (string length ought to be cheap)
	    set lflag [string tolower $flag];
	    if {$len == [string length $lflag]} {
		if {[string compare $larg $lflag]==0} {
		    # Exact match case
		    OptSetPrgCounter desc $i;
		    return 1;
		}
	    } else {
		if {[string compare $larg [string range $lflag 0 $last]]==0} {
		    lappend hitems $i;
		    incr hits;
		}
            }
	    incr i;
        }
	if {$hits} {
	    OptSetPrgCounter desc $hitems;
	}
        return $hits
    }

    # Extract fields from the list structure:

    proc OptName {item} {
        lindex $item 1;
    }
    # 
    proc OptHasBeenSet {item} {
	Lget $item {2 0};
    }
    # 
    proc OptValue {item} {
	Lget $item {2 1};
    }

    proc OptIsFlag {name} {
        string match "-*" $name;
    }
    proc OptIsOpt {name} {
        string match {\?*} $name;
    }
    proc OptVarName {item} {
        set name [OptName $item];
        if {[OptIsFlag $name]} {
            return [string range $name 1 end];
        } elseif {[OptIsOpt $name]} {
	    return [string trim $name "?"];
	} else {
            return $name;
        }
    }
    proc OptType {item} {
        lindex $item 3
    }
    proc OptTypeArgs {item} {
        lindex $item 4
    }
    proc OptHelp {item} {
        lindex $item 5
    }
    proc OptNeedValue {item} {
        string compare [OptType $item] boolflag
    }
    proc OptDefaultValue {item} {
        set val [OptTypeArgs $item]
        switch -exact -- [OptType $item] {
            choice {return [lindex $val 0]}
	    boolean -
	    boolflag {
		# convert back false/true to 0/1 because expr !$bool
		# is broken..
		if {$val} {
		    return 1
		} else {
		    return 0
		}
	    }
        }
        return $val
    }

    # Description format error helper
    proc OptOptUsage {item {what ""}} {
        return -code error "invalid description format$what: $item\n\
                should be a list of {varname|-flagname ?-type? ?defaultvalue?\
                ?helpstring?}";
    }


    # Generate a canonical form single instruction
    proc OptNewInst {state varname type typeArgs help} {
	list $state $varname [list 0 {}] $type $typeArgs $help;
	#                          ^  ^
	#                          |  |
	#               hasBeenSet=+  +=currentValue
    }

    # Translate one item to canonical form
    proc OptNormalizeOne {item} {
        set lg [Lassign $item varname arg1 arg2 arg3];
#       puts "called optnormalizeone '$item' v=($varname), lg=$lg";
        set isflag [OptIsFlag $varname];
	set isopt  [OptIsOpt  $varname];
        if {$isflag} {
            set state "flags";
        } elseif {$isopt} {
	    set state "optValue";
	} elseif {[string compare $varname "args"]} {
	    set state "value";
	} else {
	    set state "args";
	}

	# apply 'smart' 'fuzzy' logic to try to make
	# description writer's life easy, and our's difficult :
	# let's guess the missing arguments :-)

        switch $lg {
            1 {
                if {$isflag} {
                    return [OptNewInst $state $varname boolflag false ""];
                } else {
                    return [OptNewInst $state $varname any "" ""];
                }
            }
            2 {
                # varname default
                # varname help
                set type [OptGuessType $arg1]
                if {[string compare $type "string"] == 0} {
                    if {$isflag} {
			set type boolflag
			set def false
		    } else {
			set type any
			set def ""
		    }
		    set help $arg1
                } else {
                    set help ""
                    set def $arg1
                }
                return [OptNewInst $state $varname $type $def $help];
            }
            3 {
                # varname type value
                # varname value comment
		
                if [regexp {^-(.+)$} $arg1 x type] {
		    # flags/optValue as they are optional, need a "value",
		    # on the contrary, for a variable (non optional),
	            # default value is pointless, 'cept for choices :
		    if {$isflag || $isopt || ($type == "choice")} {
			return [OptNewInst $state $varname $type $arg2 ""];
		    } else {
			return [OptNewInst $state $varname $type "" $arg2];
		    }
                } else {
                    return [OptNewInst $state $varname\
			    [OptGuessType $arg1] $arg1 $arg2]
                }
            }
            4 {
                if [regexp {^-(.+)$} $arg1 x type] {
		    return [OptNewInst $state $varname $type $arg2 $arg3];
                } else {
                    return -code error [OptOptUsage $item];
                }
            }
            default {
                return -code error [OptOptUsage $item];
            }
        }
    }

    # Auto magic lasy type determination
    proc OptGuessType {arg} {
        if [regexp -nocase {^(true|false)$} $arg] {
            return boolean
        }
        if [regexp {^(-+)?[0-9]+$} $arg] {
            return int
        }
        if ![catch {expr double($arg)}] {
            return float
        }
        return string
    }

    # Error messages front ends

    proc OptAmbigous {desc arg} {
        OptError "ambigous option \"$arg\", choose from:" [OptSelection $desc]
    }
    proc OptFlagUsage {desc arg} {
        OptError "bad flag \"$arg\", must be one of" $desc;
    }
    proc OptTooManyArgs {desc arguments} {
        OptError "too many arguments (unexpected argument(s): $arguments),\
		usage:"\
		$desc 1
    }
    proc OptParamType {item} {
	if {[OptIsFlag $item]} {
	    return "flag";
	} else {
	    return "parameter";
	}
    }
    proc OptBadValue {item arg {err {}}} {
#       puts "bad val err = \"$err\"";
        OptError "bad value \"$arg\" for [OptParamType $item]"\
		[list $item]
    }
    proc OptMissingValue {descriptions} {
#        set item [OptCurDescFinal $descriptions];
        set item [OptCurDesc $descriptions];
        OptError "no value given for [OptParamType $item] \"[OptName $item]\"\
		(use -help for full usage) :"\
		[list $item]
    }

proc ::tcl::OptKeyError {prefix descKey {header 0}} {
    OptError $prefix [OptKeyGetDesc $descKey] $header;
}

    # determine string length for nice tabulated output
    proc OptLengths {desc nlName tlName dlName} {
	upvar $nlName nl;
	upvar $tlName tl;
	upvar $dlName dl;
	foreach item $desc {
	    if {[OptIsCounter $item]} continue;
	    if {[OptIsPrg $item]} {
		OptLengths $item nl tl dl
	    } else {
		SetMax nl [string length [OptName $item]]
		SetMax tl [string length [OptType $item]]
		set dv [OptTypeArgs $item];
		if {[OptState $item] != "header"} {
		    set dv "($dv)";
		}
		set l [string length $dv];
		# limit the space allocated to potentially big "choices"
		if {([OptType $item] != "choice") || ($l<=12)} {
		    SetMax dl $l
		} else {
		    if {![info exists dl]} {
			set dl 0
		    }
		}
	    }
	}
    }
    # output the tree
    proc OptTree {desc nl tl dl} {
	set res "";
	foreach item $desc {
	    if {[OptIsCounter $item]} continue;
	    if {[OptIsPrg $item]} {
		append res [OptTree $item $nl $tl $dl];
	    } else {
		set dv [OptTypeArgs $item];
		if {[OptState $item] != "header"} {
		    set dv "($dv)";
		}
		append res [format "\n    %-*s %-*s %-*s %s" \
			$nl [OptName $item] $tl [OptType $item] \
			$dl $dv [OptHelp $item]]
	    }
	}
	return $res;
    }

# Give nice usage string
proc ::tcl::OptError {prefix desc {header 0}} {
    # determine length
    if {$header} {
	# add faked instruction
	set h [list [OptNewInst header Var/FlagName Type Value Help]];
	lappend h   [OptNewInst header ------------ ---- ----- ----];
	lappend h   [OptNewInst header {( -help} "" "" {gives this help )}]
	set desc [concat $h $desc]
    }
    OptLengths $desc nl tl dl
    # actually output 
    return "$prefix[OptTree $desc $nl $tl $dl]"
}


################     General Utility functions   #######################

#
# List utility functions
# Naming convention:
#     "Lvarxxx" take the list VARiable name as argument
#     "Lxxxx"   take the list value as argument
#               (which is not costly with Tcl8 objects system
#                as it's still a reference and not a copy of the values)
#

# Is that list empty ?
proc ::tcl::Lempty {list} {
    expr {[llength $list]==0}
}

# Gets the value of one leaf of a lists tree
proc ::tcl::Lget {list indexLst} {
    if {[llength $indexLst] <= 1} {
        return [lindex $list $indexLst];
    }
    Lget [lindex $list [Lfirst $indexLst]] [Lrest $indexLst];
}
# Sets the value of one leaf of a lists tree
# (we use the version that does not create the elements because
#  it would be even slower... needs to be written in C !)
# (nb: there is a non trivial recursive problem with indexes 0,
#  which appear because there is no difference between a list
#  of 1 element and 1 element alone : [list "a"] == "a" while 
#  it should be {a} and [listp a] should be 0 while [listp {a b}] would be 1
#  and [listp "a b"] maybe 0. listp does not exist either...)
proc ::tcl::Lvarset {listName indexLst newValue} {
    upvar $listName list;
    if {[llength $indexLst] <= 1} {
        Lvarset1nc list $indexLst $newValue;
    } else {
        set idx [Lfirst $indexLst];
        set targetList [lindex $list $idx];
        # reduce refcount on targetList (not really usefull now,
	# could be with optimizing compiler)
#        Lvarset1 list $idx {};
        # recursively replace in targetList
        Lvarset targetList [Lrest $indexLst] $newValue;
        # put updated sub list back in the tree
        Lvarset1nc list $idx $targetList;
    }
}
# Set one cell to a value, eventually create all the needed elements
# (on level-1 of lists)
variable emptyList {}
proc ::tcl::Lvarset1 {listName index newValue} {
    upvar $listName list;
    if {$index < 0} {return -code error "invalid negative index"}
    set lg [llength $list];
    if {$index >= $lg} {
        variable emptyList;
        for {set i $lg} {$i<$index} {incr i} {
            lappend list $emptyList;
        }
        lappend list $newValue;
    } else {
        set list [lreplace $list $index $index $newValue];
    }
}
# same as Lvarset1 but no bound checking / creation
proc ::tcl::Lvarset1nc {listName index newValue} {
    upvar $listName list;
    set list [lreplace $list $index $index $newValue];
}
# Increments the value of one leaf of a lists tree
# (which must exists)
proc ::tcl::Lvarincr {listName indexLst {howMuch 1}} {
    upvar $listName list;
    if {[llength $indexLst] <= 1} {
        Lvarincr1 list $indexLst $howMuch;
    } else {
        set idx [Lfirst $indexLst];
        set targetList [lindex $list $idx];
        # reduce refcount on targetList
        Lvarset1nc list $idx {};
        # recursively replace in targetList
        Lvarincr targetList [Lrest $indexLst] $howMuch;
        # put updated sub list back in the tree
        Lvarset1nc list $idx $targetList;
    }
}
# Increments the value of one cell of a list
proc ::tcl::Lvarincr1 {listName index {howMuch 1}} {
    upvar $listName list;
    set newValue [expr [lindex $list $index]+$howMuch];
    set list [lreplace $list $index $index $newValue];
    return $newValue;
}
# Returns the first element of a list
proc ::tcl::Lfirst {list} {
    lindex $list 0
}
# Returns the rest of the list minus first element
proc ::tcl::Lrest {list} {
    lrange $list 1 end
}
# Removes the first element of a list
proc ::tcl::Lvarpop {listName} {
    upvar $listName list;
    set list [lrange $list 1 end];
}
# Same but returns the removed element
proc ::tcl::Lvarpop2 {listName} {
    upvar $listName list;
    set el [Lfirst $list];
    set list [lrange $list 1 end];
    return $el;
}
# Assign list elements to variables and return the length of the list
proc ::tcl::Lassign {list args} {
    # faster than direct blown foreach (which does not byte compile)
    set i 0;
    set lg [llength $list];
    foreach vname $args {
        if {$i>=$lg} break
        uplevel [list set $vname [lindex $list $i]];
        incr i;
    }
    return $lg;
}

# Misc utilities

# Set the varname to value if value is greater than varname's current value
# or if varname is undefined
proc ::tcl::SetMax {varname value} {
    upvar 1 $varname var
    if {![info exists var] || $value > $var} {
        set var $value
    }
}

# Set the varname to value if value is smaller than varname's current value
# or if varname is undefined
proc ::tcl::SetMin {varname value} {
    upvar 1 $varname var
    if {![info exists var] || $value < $var} {
        set var $value
    }
}


    # everything loaded fine, lets create the test proc:
    OptCreateTestProc
    # Don't need the create temp proc anymore:
    rename OptCreateTestProc {}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted library/opt0.1/pkgIndex.tcl.

1
2
3
4
5
6
7
# Tcl package index file, version 1.0
# This file is NOT generated by the "pkg_mkIndex" command
# because if someone just did "package require opt", let's just load
# the package now, so they can readily use it
# and even "namespace import tcl::*" ...
# (tclPkgSetup just makes things slow and do not work so well with namespaces)
package ifneeded opt 0.2 [list source [file join $dir optparse.tcl]]
<
<
<
<
<
<
<














Added library/opt0.4/optparse.tcl.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
# optparse.tcl --
#
#       (private) Option parsing package
#       Primarily used internally by the safe:: code.
#
#	WARNING: This code will go away in a future release
#	of Tcl.  It is NOT supported and you should not rely
#	on it.  If your code does rely on this package you
#	may directly incorporate this code into your application.
#
# RCS: @(#) $Id: optparse.tcl,v 1.1.2.2 1999/03/12 23:20:44 rjohnson Exp $

package provide opt 0.4.1

namespace eval ::tcl {

    # Exported APIs
    namespace export OptKeyRegister OptKeyDelete OptKeyError OptKeyParse \
             OptProc OptProcArgGiven OptParse \
	     Lempty Lget \
             Lassign Lvarpop Lvarpop1 Lvarset Lvarincr Lfirst Lrest \
             SetMax SetMin


#################  Example of use / 'user documentation'  ###################

    proc OptCreateTestProc {} {

	# Defines ::tcl::OptParseTest as a test proc with parsed arguments
	# (can't be defined before the code below is loaded (before "OptProc"))

	# Every OptProc give usage information on "procname -help".
	# Try "tcl::OptParseTest -help" and "tcl::OptParseTest -a" and
	# then other arguments.
	# 
	# example of 'valid' call:
	# ::tcl::OptParseTest save -4 -pr 23 -libsok SybTcl\
	#		-nostatics false ch1
	OptProc OptParseTest {
            {subcommand -choice {save print} "sub command"}
            {arg1 3 "some number"}
            {-aflag}
            {-intflag      7}
            {-weirdflag                    "help string"}
            {-noStatics                    "Not ok to load static packages"}
            {-nestedloading1 true           "OK to load into nested slaves"}
            {-nestedloading2 -boolean true "OK to load into nested slaves"}
            {-libsOK        -choice {Tk SybTcl}
		                      "List of packages that can be loaded"}
            {-precision     -int 12        "Number of digits of precision"}
            {-intval        7               "An integer"}
            {-scale         -float 1.0     "Scale factor"}
            {-zoom          1.0             "Zoom factor"}
            {-arbitrary     foobar          "Arbitrary string"}
            {-random        -string 12   "Random string"}
            {-listval       -list {}       "List value"}
            {-blahflag       -blah abc       "Funny type"}
	    {arg2 -boolean "a boolean"}
	    {arg3 -choice "ch1 ch2"}
	    {?optarg? -list {} "optional argument"}
        } {
	    foreach v [info locals] {
		puts stderr [format "%14s : %s" $v [set $v]]
	    }
	}
    }

###################  No User serviceable part below ! ###############
# You should really not look any further :
# The following is private unexported undocumented unblessed... code 
# time to hit "q" ;-) !

# Hmmm... ok, you really want to know ?

# You've been warned... Here it is...

    # Array storing the parsed descriptions
    variable OptDesc;
    array set OptDesc {};
    # Next potentially free key id (numeric)
    variable OptDescN 0;

# Inside algorithm/mechanism description:
# (not for the faint hearted ;-)
#
# The argument description is parsed into a "program tree"
# It is called a "program" because it is the program used by
# the state machine interpreter that use that program to
# actually parse the arguments at run time.
#
# The general structure of a "program" is
# notation (pseudo bnf like)
#    name :== definition        defines "name" as being "definition" 
#    { x y z }                  means list of x, y, and z  
#    x*                         means x repeated 0 or more time
#    x+                         means "x x*"
#    x?                         means optionally x
#    x | y                      means x or y
#    "cccc"                     means the literal string
#
#    program        :== { programCounter programStep* }
#
#    programStep    :== program | singleStep
#
#    programCounter :== {"P" integer+ }
#
#    singleStep     :== { instruction parameters* }
#
#    instruction    :== single element list
#
# (the difference between singleStep and program is that \
#   llength [Lfirst $program] >= 2
# while
#   llength [Lfirst $singleStep] == 1
# )
#
# And for this application:
#
#    singleStep     :== { instruction varname {hasBeenSet currentValue} type 
#                         typeArgs help }
#    instruction    :== "flags" | "value"
#    type           :== knowType | anyword
#    knowType       :== "string" | "int" | "boolean" | "boolflag" | "float"
#                       | "choice"
#
# for type "choice" typeArgs is a list of possible choices, the first one
# is the default value. for all other types the typeArgs is the default value
#
# a "boolflag" is the type for a flag whose presence or absence, without
# additional arguments means respectively true or false (default flag type).
#
# programCounter is the index in the list of the currently processed
# programStep (thus starting at 1 (0 is {"P" prgCounterValue}).
# If it is a list it points toward each currently selected programStep.
# (like for "flags", as they are optional, form a set and programStep).

# Performance/Implementation issues
# ---------------------------------
# We use tcl lists instead of arrays because with tcl8.0
# they should start to be much faster.
# But this code use a lot of helper procs (like Lvarset)
# which are quite slow and would be helpfully optimized
# for instance by being written in C. Also our struture
# is complex and there is maybe some places where the
# string rep might be calculated at great exense. to be checked.

#
# Parse a given description and saves it here under the given key
# generate a unused keyid if not given
#
proc ::tcl::OptKeyRegister {desc {key ""}} {
    variable OptDesc;
    variable OptDescN;
    if {[string compare $key ""] == 0} {
        # in case a key given to us as a parameter was a number
        while {[info exists OptDesc($OptDescN)]} {incr OptDescN}
        set key $OptDescN;
        incr OptDescN;
    }
    # program counter
    set program [list [list "P" 1]];

    # are we processing flags (which makes a single program step)
    set inflags 0;

    set state {};

    # flag used to detect that we just have a single (flags set) subprogram.
    set empty 1;

    foreach item $desc {
	if {$state == "args"} {
	    # more items after 'args'...
	    return -code error "'args' special argument must be the last one";
	}
        set res [OptNormalizeOne $item];
        set state [Lfirst $res];
        if {$inflags} {
            if {$state == "flags"} {
		# add to 'subprogram'
                lappend flagsprg $res;
            } else {
                # put in the flags
                # structure for flag programs items is a list of
                # {subprgcounter {prg flag 1} {prg flag 2} {...}}
                lappend program $flagsprg;
                # put the other regular stuff
                lappend program $res;
		set inflags 0;
		set empty 0;
            }
        } else {
           if {$state == "flags"} {
               set inflags 1;
               # sub program counter + first sub program
               set flagsprg [list [list "P" 1] $res];
           } else {
               lappend program $res;
               set empty 0;
           }
       }
   }
   if {$inflags} {
       if {$empty} {
	   # We just have the subprogram, optimize and remove
	   # unneeded level:
	   set program $flagsprg;
       } else {
	   lappend program $flagsprg;
       }
   }

   set OptDesc($key) $program;

   return $key;
}

#
# Free the storage for that given key
#
proc ::tcl::OptKeyDelete {key} {
    variable OptDesc;
    unset OptDesc($key);
}

    # Get the parsed description stored under the given key.
    proc OptKeyGetDesc {descKey} {
        variable OptDesc;
        if {![info exists OptDesc($descKey)]} {
            return -code error "Unknown option description key \"$descKey\"";
        }
        set OptDesc($descKey);
    }

# Parse entry point for ppl who don't want to register with a key,
# for instance because the description changes dynamically.
#  (otherwise one should really use OptKeyRegister once + OptKeyParse
#   as it is way faster or simply OptProc which does it all)
# Assign a temporary key, call OptKeyParse and then free the storage
proc ::tcl::OptParse {desc arglist} {
    set tempkey [OptKeyRegister $desc];
    set ret [catch {uplevel [list ::tcl::OptKeyParse $tempkey $arglist]} res];
    OptKeyDelete $tempkey;
    return -code $ret $res;
}

# Helper function, replacement for proc that both
# register the description under a key which is the name of the proc
# (and thus unique to that code)
# and add a first line to the code to call the OptKeyParse proc
# Stores the list of variables that have been actually given by the user
# (the other will be sets to their default value)
# into local variable named "Args".
proc ::tcl::OptProc {name desc body} {
    set namespace [uplevel namespace current];
    if {   ([string match $name "::*"]) 
        || ([string compare $namespace "::"]==0)} {
        # absolute name or global namespace, name is the key
        set key $name;
    } else {
        # we are relative to some non top level namespace:
        set key "${namespace}::${name}";
    }
    OptKeyRegister $desc $key;
    uplevel [list proc $name args "set Args \[::tcl::OptKeyParse $key \$args\]\n$body"];
    return $key;
}
# Check that a argument has been given
# assumes that "OptProc" has been used as it will check in "Args" list
proc ::tcl::OptProcArgGiven {argname} {
    upvar Args alist;
    expr {[lsearch $alist $argname] >=0}
}

    #######
    # Programs/Descriptions manipulation

    # Return the instruction word/list of a given step/(sub)program
    proc OptInstr {lst} {
	Lfirst $lst;
    }
    # Is a (sub) program or a plain instruction ?
    proc OptIsPrg {lst} {
	expr {[llength [OptInstr $lst]]>=2}
    }
    # Is this instruction a program counter or a real instr
    proc OptIsCounter {item} {
	expr {[Lfirst $item]=="P"}
    }
    # Current program counter (2nd word of first word)
    proc OptGetPrgCounter {lst} {
	Lget $lst {0 1}
    }
    # Current program counter (2nd word of first word)
    proc OptSetPrgCounter {lstName newValue} {
	upvar $lstName lst;
	set lst [lreplace $lst 0 0 [concat "P" $newValue]];
    }
    # returns a list of currently selected items.
    proc OptSelection {lst} {
	set res {};
	foreach idx [lrange [Lfirst $lst] 1 end] {
	    lappend res [Lget $lst $idx];
	}
	return $res;
    }

    # Advance to next description
    proc OptNextDesc {descName} {
        uplevel [list Lvarincr $descName {0 1}];
    }

    # Get the current description, eventually descend
    proc OptCurDesc {descriptions} {
        lindex $descriptions [OptGetPrgCounter $descriptions];
    }
    # get the current description, eventually descend
    # through sub programs as needed.
    proc OptCurDescFinal {descriptions} {
        set item [OptCurDesc $descriptions];
	# Descend untill we get the actual item and not a sub program
        while {[OptIsPrg $item]} {
            set item [OptCurDesc $item];
        }
	return $item;
    }
    # Current final instruction adress
    proc OptCurAddr {descriptions {start {}}} {
	set adress [OptGetPrgCounter $descriptions];
	lappend start $adress;
	set item [lindex $descriptions $adress];
	if {[OptIsPrg $item]} {
	    return [OptCurAddr $item $start];
	} else {
	    return $start;
	}
    }
    # Set the value field of the current instruction
    proc OptCurSetValue {descriptionsName value} {
	upvar $descriptionsName descriptions
	# get the current item full adress
        set adress [OptCurAddr $descriptions];
	# use the 3th field of the item  (see OptValue / OptNewInst)
	lappend adress 2
	Lvarset descriptions $adress [list 1 $value];
	#                                  ^hasBeenSet flag
    }

    # empty state means done/paste the end of the program
    proc OptState {item} {
        Lfirst $item
    }
    
    # current state
    proc OptCurState {descriptions} {
        OptState [OptCurDesc $descriptions];
    }

    #######
    # Arguments manipulation

    # Returns the argument that has to be processed now
    proc OptCurrentArg {lst} {
        Lfirst $lst;
    }
    # Advance to next argument
    proc OptNextArg {argsName} {
        uplevel [list Lvarpop1 $argsName];
    }
    #######





    # Loop over all descriptions, calling OptDoOne which will
    # eventually eat all the arguments.
    proc OptDoAll {descriptionsName argumentsName} {
	upvar $descriptionsName descriptions
	upvar $argumentsName arguments;
#	puts "entered DoAll";
	# Nb: the places where "state" can be set are tricky to figure
	#     because DoOne sets the state to flagsValue and return -continue
	#     when needed...
	set state [OptCurState $descriptions];
	# We'll exit the loop in "OptDoOne" or when state is empty.
        while 1 {
	    set curitem [OptCurDesc $descriptions];
	    # Do subprograms if needed, call ourselves on the sub branch
	    while {[OptIsPrg $curitem]} {
		OptDoAll curitem arguments
#		puts "done DoAll sub";
		# Insert back the results in current tree;
		Lvarset1nc descriptions [OptGetPrgCounter $descriptions]\
			$curitem;
		OptNextDesc descriptions;
		set curitem [OptCurDesc $descriptions];
                set state [OptCurState $descriptions];
	    }
#           puts "state = \"$state\" - arguments=($arguments)";
	    if {[Lempty $state]} {
		# Nothing left to do, we are done in this branch:
		break;
	    }
	    # The following statement can make us terminate/continue
	    # as it use return -code {break, continue, return and error}
	    # codes
            OptDoOne descriptions state arguments;
	    # If we are here, no special return code where issued,
	    # we'll step to next instruction :
#           puts "new state  = \"$state\"";
	    OptNextDesc descriptions;
	    set state [OptCurState $descriptions];
        }
    }

    # Process one step for the state machine,
    # eventually consuming the current argument.
    proc OptDoOne {descriptionsName stateName argumentsName} {
        upvar $argumentsName arguments;
        upvar $descriptionsName descriptions;
	upvar $stateName state;

	# the special state/instruction "args" eats all
	# the remaining args (if any)
	if {($state == "args")} {
	    if {![Lempty $arguments]} {
		# If there is no additional arguments, leave the default value
		# in.
		OptCurSetValue descriptions $arguments;
		set arguments {};
	    }
#            puts "breaking out ('args' state: consuming every reminding args)"
	    return -code break;
	}

	if {[Lempty $arguments]} {
	    if {$state == "flags"} {
		# no argument and no flags : we're done
#                puts "returning to previous (sub)prg (no more args)";
		return -code return;
	    } elseif {$state == "optValue"} {
		set state next; # not used, for debug only
		# go to next state
		return ;
	    } else {
		return -code error [OptMissingValue $descriptions];
	    }
	} else {
	    set arg [OptCurrentArg $arguments];
	}

        switch $state {
            flags {
                # A non-dash argument terminates the options, as does --

                # Still a flag ?
                if {![OptIsFlag $arg]} {
                    # don't consume the argument, return to previous prg
                    return -code return;
                }
                # consume the flag
                OptNextArg arguments;
                if {[string compare "--" $arg] == 0} {
                    # return from 'flags' state
                    return -code return;
                }

                set hits [OptHits descriptions $arg];
                if {$hits > 1} {
                    return -code error [OptAmbigous $descriptions $arg]
                } elseif {$hits == 0} {
                    return -code error [OptFlagUsage $descriptions $arg]
                }
		set item [OptCurDesc $descriptions];
                if {[OptNeedValue $item]} {
		    # we need a value, next state is
		    set state flagValue;
                } else {
                    OptCurSetValue descriptions 1;
                }
		# continue
		return -code continue;
            }
	    flagValue -
	    value {
		set item [OptCurDesc $descriptions];
                # Test the values against their required type
		if {[catch {OptCheckType $arg\
			[OptType $item] [OptTypeArgs $item]} val]} {
		    return -code error [OptBadValue $item $arg $val]
		}
                # consume the value
                OptNextArg arguments;
		# set the value
		OptCurSetValue descriptions $val;
		# go to next state
		if {$state == "flagValue"} {
		    set state flags
		    return -code continue;
		} else {
		    set state next; # not used, for debug only
		    return ; # will go on next step
		}
	    }
	    optValue {
		set item [OptCurDesc $descriptions];
                # Test the values against their required type
		if {![catch {OptCheckType $arg\
			[OptType $item] [OptTypeArgs $item]} val]} {
		    # right type, so :
		    # consume the value
		    OptNextArg arguments;
		    # set the value
		    OptCurSetValue descriptions $val;
		}
		# go to next state
		set state next; # not used, for debug only
		return ; # will go on next step
	    }
        }
	# If we reach this point: an unknown
	# state as been entered !
	return -code error "Bug! unknown state in DoOne \"$state\"\
		(prg counter [OptGetPrgCounter $descriptions]:\
			[OptCurDesc $descriptions])";
    }

# Parse the options given the key to previously registered description
# and arguments list
proc ::tcl::OptKeyParse {descKey arglist} {

    set desc [OptKeyGetDesc $descKey];

    # make sure -help always give usage
    if {[string compare "-help" [string tolower $arglist]] == 0} {
	return -code error [OptError "Usage information:" $desc 1];
    }

    OptDoAll desc arglist;

    if {![Lempty $arglist]} {
	return -code error [OptTooManyArgs $desc $arglist];
    }
    
    # Analyse the result
    # Walk through the tree:
    OptTreeVars $desc "#[expr {[info level]-1}]" ;
}

    # determine string length for nice tabulated output
    proc OptTreeVars {desc level {vnamesLst {}}} {
	foreach item $desc {
	    if {[OptIsCounter $item]} continue;
	    if {[OptIsPrg $item]} {
		set vnamesLst [OptTreeVars $item $level $vnamesLst];
	    } else {
		set vname [OptVarName $item];
		upvar $level $vname var
		if {[OptHasBeenSet $item]} {
#		    puts "adding $vname"
		    # lets use the input name for the returned list
		    # it is more usefull, for instance you can check that
		    # no flags at all was given with expr
		    # {![string match "*-*" $Args]}
		    lappend vnamesLst [OptName $item];
		    set var [OptValue $item];
		} else {
		    set var [OptDefaultValue $item];
		}
	    }
	}
	return $vnamesLst
    }


# Check the type of a value
# and emit an error if arg is not of the correct type
# otherwise returns the canonical value of that arg (ie 0/1 for booleans)
proc ::tcl::OptCheckType {arg type {typeArgs ""}} {
#    puts "checking '$arg' against '$type' ($typeArgs)";

    # only types "any", "choice", and numbers can have leading "-"

    switch -exact -- $type {
        int {
            if {![regexp {^(-+)?[0-9]+$} $arg]} {
                error "not an integer"
            }
	    return $arg;
        }
        float {
            return [expr {double($arg)}]
        }
	script -
        list {
	    # if llength fail : malformed list
            if {[llength $arg]==0} {
		if {[OptIsFlag $arg]} {
		    error "no values with leading -"
		}
	    }
	    return $arg;
        }
        boolean {
	    if {![regexp -nocase {^(true|false|0|1)$} $arg]} {
		error "non canonic boolean"
            }
	    # convert true/false because expr/if is broken with "!,...
	    if {$arg} {
		return 1
	    } else {
		return 0
	    }
        }
        choice {
            if {[lsearch -exact $typeArgs $arg] < 0} {
                error "invalid choice"
            }
	    return $arg;
        }
	any {
	    return $arg;
	}
	string -
	default {
            if {[OptIsFlag $arg]} {
                error "no values with leading -"
            }
	    return $arg
        }
    }
    return neverReached;
}

    # internal utilities

    # returns the number of flags matching the given arg
    # sets the (local) prg counter to the list of matches
    proc OptHits {descName arg} {
        upvar $descName desc;
        set hits 0
        set hitems {}
	set i 1;

	set larg [string tolower $arg];
	set len  [string length $larg];
	set last [expr {$len-1}];

        foreach item [lrange $desc 1 end] {
            set flag [OptName $item]
	    # lets try to match case insensitively
	    # (string length ought to be cheap)
	    set lflag [string tolower $flag];
	    if {$len == [string length $lflag]} {
		if {[string compare $larg $lflag]==0} {
		    # Exact match case
		    OptSetPrgCounter desc $i;
		    return 1;
		}
	    } else {
		if {[string compare $larg [string range $lflag 0 $last]]==0} {
		    lappend hitems $i;
		    incr hits;
		}
            }
	    incr i;
        }
	if {$hits} {
	    OptSetPrgCounter desc $hitems;
	}
        return $hits
    }

    # Extract fields from the list structure:

    proc OptName {item} {
        lindex $item 1;
    }
    # 
    proc OptHasBeenSet {item} {
	Lget $item {2 0};
    }
    # 
    proc OptValue {item} {
	Lget $item {2 1};
    }

    proc OptIsFlag {name} {
        string match "-*" $name;
    }
    proc OptIsOpt {name} {
        string match {\?*} $name;
    }
    proc OptVarName {item} {
        set name [OptName $item];
        if {[OptIsFlag $name]} {
            return [string range $name 1 end];
        } elseif {[OptIsOpt $name]} {
	    return [string trim $name "?"];
	} else {
            return $name;
        }
    }
    proc OptType {item} {
        lindex $item 3
    }
    proc OptTypeArgs {item} {
        lindex $item 4
    }
    proc OptHelp {item} {
        lindex $item 5
    }
    proc OptNeedValue {item} {
        string compare [OptType $item] boolflag
    }
    proc OptDefaultValue {item} {
        set val [OptTypeArgs $item]
        switch -exact -- [OptType $item] {
            choice {return [lindex $val 0]}
	    boolean -
	    boolflag {
		# convert back false/true to 0/1 because expr !$bool
		# is broken..
		if {$val} {
		    return 1
		} else {
		    return 0
		}
	    }
        }
        return $val
    }

    # Description format error helper
    proc OptOptUsage {item {what ""}} {
        return -code error "invalid description format$what: $item\n\
                should be a list of {varname|-flagname ?-type? ?defaultvalue?\
                ?helpstring?}";
    }


    # Generate a canonical form single instruction
    proc OptNewInst {state varname type typeArgs help} {
	list $state $varname [list 0 {}] $type $typeArgs $help;
	#                          ^  ^
	#                          |  |
	#               hasBeenSet=+  +=currentValue
    }

    # Translate one item to canonical form
    proc OptNormalizeOne {item} {
        set lg [Lassign $item varname arg1 arg2 arg3];
#       puts "called optnormalizeone '$item' v=($varname), lg=$lg";
        set isflag [OptIsFlag $varname];
	set isopt  [OptIsOpt  $varname];
        if {$isflag} {
            set state "flags";
        } elseif {$isopt} {
	    set state "optValue";
	} elseif {[string compare $varname "args"]} {
	    set state "value";
	} else {
	    set state "args";
	}

	# apply 'smart' 'fuzzy' logic to try to make
	# description writer's life easy, and our's difficult :
	# let's guess the missing arguments :-)

        switch $lg {
            1 {
                if {$isflag} {
                    return [OptNewInst $state $varname boolflag false ""];
                } else {
                    return [OptNewInst $state $varname any "" ""];
                }
            }
            2 {
                # varname default
                # varname help
                set type [OptGuessType $arg1]
                if {[string compare $type "string"] == 0} {
                    if {$isflag} {
			set type boolflag
			set def false
		    } else {
			set type any
			set def ""
		    }
		    set help $arg1
                } else {
                    set help ""
                    set def $arg1
                }
                return [OptNewInst $state $varname $type $def $help];
            }
            3 {
                # varname type value
                # varname value comment
		
                if {[regexp {^-(.+)$} $arg1 x type]} {
		    # flags/optValue as they are optional, need a "value",
		    # on the contrary, for a variable (non optional),
	            # default value is pointless, 'cept for choices :
		    if {$isflag || $isopt || ($type == "choice")} {
			return [OptNewInst $state $varname $type $arg2 ""];
		    } else {
			return [OptNewInst $state $varname $type "" $arg2];
		    }
                } else {
                    return [OptNewInst $state $varname\
			    [OptGuessType $arg1] $arg1 $arg2]
                }
            }
            4 {
                if {[regexp {^-(.+)$} $arg1 x type]} {
		    return [OptNewInst $state $varname $type $arg2 $arg3];
                } else {
                    return -code error [OptOptUsage $item];
                }
            }
            default {
                return -code error [OptOptUsage $item];
            }
        }
    }

    # Auto magic lasy type determination
    proc OptGuessType {arg} {
        if {[regexp -nocase {^(true|false)$} $arg]} {
            return boolean
        }
        if {[regexp {^(-+)?[0-9]+$} $arg]} {
            return int
        }
        if {![catch {expr {double($arg)}}]} {
            return float
        }
        return string
    }

    # Error messages front ends

    proc OptAmbigous {desc arg} {
        OptError "ambigous option \"$arg\", choose from:" [OptSelection $desc]
    }
    proc OptFlagUsage {desc arg} {
        OptError "bad flag \"$arg\", must be one of" $desc;
    }
    proc OptTooManyArgs {desc arguments} {
        OptError "too many arguments (unexpected argument(s): $arguments),\
		usage:"\
		$desc 1
    }
    proc OptParamType {item} {
	if {[OptIsFlag $item]} {
	    return "flag";
	} else {
	    return "parameter";
	}
    }
    proc OptBadValue {item arg {err {}}} {
#       puts "bad val err = \"$err\"";
        OptError "bad value \"$arg\" for [OptParamType $item]"\
		[list $item]
    }
    proc OptMissingValue {descriptions} {
#        set item [OptCurDescFinal $descriptions];
        set item [OptCurDesc $descriptions];
        OptError "no value given for [OptParamType $item] \"[OptName $item]\"\
		(use -help for full usage) :"\
		[list $item]
    }

proc ::tcl::OptKeyError {prefix descKey {header 0}} {
    OptError $prefix [OptKeyGetDesc $descKey] $header;
}

    # determine string length for nice tabulated output
    proc OptLengths {desc nlName tlName dlName} {
	upvar $nlName nl;
	upvar $tlName tl;
	upvar $dlName dl;
	foreach item $desc {
	    if {[OptIsCounter $item]} continue;
	    if {[OptIsPrg $item]} {
		OptLengths $item nl tl dl
	    } else {
		SetMax nl [string length [OptName $item]]
		SetMax tl [string length [OptType $item]]
		set dv [OptTypeArgs $item];
		if {[OptState $item] != "header"} {
		    set dv "($dv)";
		}
		set l [string length $dv];
		# limit the space allocated to potentially big "choices"
		if {([OptType $item] != "choice") || ($l<=12)} {
		    SetMax dl $l
		} else {
		    if {![info exists dl]} {
			set dl 0
		    }
		}
	    }
	}
    }
    # output the tree
    proc OptTree {desc nl tl dl} {
	set res "";
	foreach item $desc {
	    if {[OptIsCounter $item]} continue;
	    if {[OptIsPrg $item]} {
		append res [OptTree $item $nl $tl $dl];
	    } else {
		set dv [OptTypeArgs $item];
		if {[OptState $item] != "header"} {
		    set dv "($dv)";
		}
		append res [format "\n    %-*s %-*s %-*s %s" \
			$nl [OptName $item] $tl [OptType $item] \
			$dl $dv [OptHelp $item]]
	    }
	}
	return $res;
    }

# Give nice usage string
proc ::tcl::OptError {prefix desc {header 0}} {
    # determine length
    if {$header} {
	# add faked instruction
	set h [list [OptNewInst header Var/FlagName Type Value Help]];
	lappend h   [OptNewInst header ------------ ---- ----- ----];
	lappend h   [OptNewInst header {( -help} "" "" {gives this help )}]
	set desc [concat $h $desc]
    }
    OptLengths $desc nl tl dl
    # actually output 
    return "$prefix[OptTree $desc $nl $tl $dl]"
}


################     General Utility functions   #######################

#
# List utility functions
# Naming convention:
#     "Lvarxxx" take the list VARiable name as argument
#     "Lxxxx"   take the list value as argument
#               (which is not costly with Tcl8 objects system
#                as it's still a reference and not a copy of the values)
#

# Is that list empty ?
proc ::tcl::Lempty {list} {
    expr {[llength $list]==0}
}

# Gets the value of one leaf of a lists tree
proc ::tcl::Lget {list indexLst} {
    if {[llength $indexLst] <= 1} {
        return [lindex $list $indexLst];
    }
    Lget [lindex $list [Lfirst $indexLst]] [Lrest $indexLst];
}
# Sets the value of one leaf of a lists tree
# (we use the version that does not create the elements because
#  it would be even slower... needs to be written in C !)
# (nb: there is a non trivial recursive problem with indexes 0,
#  which appear because there is no difference between a list
#  of 1 element and 1 element alone : [list "a"] == "a" while 
#  it should be {a} and [listp a] should be 0 while [listp {a b}] would be 1
#  and [listp "a b"] maybe 0. listp does not exist either...)
proc ::tcl::Lvarset {listName indexLst newValue} {
    upvar $listName list;
    if {[llength $indexLst] <= 1} {
        Lvarset1nc list $indexLst $newValue;
    } else {
        set idx [Lfirst $indexLst];
        set targetList [lindex $list $idx];
        # reduce refcount on targetList (not really usefull now,
	# could be with optimizing compiler)
#        Lvarset1 list $idx {};
        # recursively replace in targetList
        Lvarset targetList [Lrest $indexLst] $newValue;
        # put updated sub list back in the tree
        Lvarset1nc list $idx $targetList;
    }
}
# Set one cell to a value, eventually create all the needed elements
# (on level-1 of lists)
variable emptyList {}
proc ::tcl::Lvarset1 {listName index newValue} {
    upvar $listName list;
    if {$index < 0} {return -code error "invalid negative index"}
    set lg [llength $list];
    if {$index >= $lg} {
        variable emptyList;
        for {set i $lg} {$i<$index} {incr i} {
            lappend list $emptyList;
        }
        lappend list $newValue;
    } else {
        set list [lreplace $list $index $index $newValue];
    }
}
# same as Lvarset1 but no bound checking / creation
proc ::tcl::Lvarset1nc {listName index newValue} {
    upvar $listName list;
    set list [lreplace $list $index $index $newValue];
}
# Increments the value of one leaf of a lists tree
# (which must exists)
proc ::tcl::Lvarincr {listName indexLst {howMuch 1}} {
    upvar $listName list;
    if {[llength $indexLst] <= 1} {
        Lvarincr1 list $indexLst $howMuch;
    } else {
        set idx [Lfirst $indexLst];
        set targetList [lindex $list $idx];
        # reduce refcount on targetList
        Lvarset1nc list $idx {};
        # recursively replace in targetList
        Lvarincr targetList [Lrest $indexLst] $howMuch;
        # put updated sub list back in the tree
        Lvarset1nc list $idx $targetList;
    }
}
# Increments the value of one cell of a list
proc ::tcl::Lvarincr1 {listName index {howMuch 1}} {
    upvar $listName list;
    set newValue [expr {[lindex $list $index]+$howMuch}];
    set list [lreplace $list $index $index $newValue];
    return $newValue;
}
# Returns the first element of a list
proc ::tcl::Lfirst {list} {
    lindex $list 0
}
# Returns the rest of the list minus first element
proc ::tcl::Lrest {list} {
    lrange $list 1 end
}
# Removes the first element of a list
# and returns the new list value
proc ::tcl::Lvarpop1 {listName} {
    upvar $listName list;
    set list [lrange $list 1 end];
}
# Same but returns the removed element
# (Like the tclX version)
proc ::tcl::Lvarpop {listName} {
    upvar $listName list;
    set el [Lfirst $list];
    set list [lrange $list 1 end];
    return $el;
}
# Assign list elements to variables and return the length of the list
proc ::tcl::Lassign {list args} {
    # faster than direct blown foreach (which does not byte compile)
    set i 0;
    set lg [llength $list];
    foreach vname $args {
        if {$i>=$lg} break
        uplevel [list set $vname [lindex $list $i]];
        incr i;
    }
    return $lg;
}

# Misc utilities

# Set the varname to value if value is greater than varname's current value
# or if varname is undefined
proc ::tcl::SetMax {varname value} {
    upvar 1 $varname var
    if {![info exists var] || $value > $var} {
        set var $value
    }
}

# Set the varname to value if value is smaller than varname's current value
# or if varname is undefined
proc ::tcl::SetMin {varname value} {
    upvar 1 $varname var
    if {![info exists var] || $value < $var} {
        set var $value
    }
}


    # everything loaded fine, lets create the test proc:
 #    OptCreateTestProc
    # Don't need the create temp proc anymore:
 #    rename OptCreateTestProc {}
}

Added library/opt0.4/pkgIndex.tcl.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
# Tcl package index file, version 1.1
# This file is generated by the "pkg_mkIndex -direct" command
# and sourced either when an application starts up or
# by a "package unknown" script.  It invokes the
# "package ifneeded" command to set up package-related
# information so that packages will be loaded automatically
# in response to "package require" commands.  When this
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.

package ifneeded opt 0.4.1 [list source [file join $dir optparse.tcl]]

Added library/package.tcl.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































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

# pkg_compareExtension --
#
#  Used internally by pkg_mkIndex to compare the extension of a file to
#  a given extension. On Windows, it uses a case-insensitive comparison
#  because the file system can be file insensitive.
#
# Arguments:
#  fileName	name of a file whose extension is compared
#  ext		(optional) The extension to compare against; you must
#		provide the starting dot.
#		Defaults to [info sharedlibextension]
#
# Results:
#  Returns 1 if the extension matches, 0 otherwise

proc pkg_compareExtension { fileName {ext {}} } {
    global tcl_platform
    if {[string length $ext] == 0} {
	set ext [info sharedlibextension]
    }
    if {[string compare $tcl_platform(platform) "windows"] == 0} {
	return [expr {[string compare \
		[string tolower [file extension $fileName]] \
		[string tolower $ext]] == 0}]
    } else {
	return [expr {[string compare [file extension $fileName] $ext] == 0}]
    }
}

# pkg_mkIndex --
# This procedure creates a package index in a given directory.  The
# package index consists of a "pkgIndex.tcl" file whose contents are
# a Tcl script that sets up package information with "package require"
# commands.  The commands describe all of the packages defined by the
# files given as arguments.
#
# Arguments:
# -direct		(optional) If this flag is present, the generated
#			code in pkgMkIndex.tcl will cause the package to be
#			loaded when "package require" is executed, rather
#			than lazily when the first reference to an exported
#			procedure in the package is made.
# -verbose		(optional) Verbose output; the name of each file that
#			was successfully rocessed is printed out. Additionally,
#			if processing of a file failed a message is printed.
# -load pat		(optional) Preload any packages whose names match
#			the pattern.  Used to handle DLLs that depend on
#			other packages during their Init procedure.
# dir -			Name of the directory in which to create the index.
# args -		Any number of additional arguments, each giving
#			a glob pattern that matches the names of one or
#			more shared libraries or Tcl script files in
#			dir.

proc pkg_mkIndex {args} {
    global errorCode errorInfo
    set usage {"pkg_mkIndex ?-direct? ?-verbose? ?-load pattern? ?--? dir ?pattern ...?"};

    set argCount [llength $args]
    if {$argCount < 1} {
	return -code error "wrong # args: should be\n$usage"
    }

    set more ""
    set direct 0
    set doVerbose 0
    set loadPat ""
    for {set idx 0} {$idx < $argCount} {incr idx} {
	set flag [lindex $args $idx]
	switch -glob -- $flag {
	    -- {
		# done with the flags
		incr idx
		break
	    }
	    -verbose {
		set doVerbose 1
	    }
	    -direct {
		set direct 1
		append more " -direct"
	    }
	    -load {
		incr idx
		set loadPat [lindex $args $idx]
		append more " -load $loadPat"
	    }
	    -* {
		return -code error "unknown flag $flag: should be\n$usage"
	    }
	    default {
		# done with the flags
		break
	    }
	}
    }

    set dir [lindex $args $idx]
    set patternList [lrange $args [expr {$idx + 1}] end]
    if {[llength $patternList] == 0} {
	set patternList [list "*.tcl" "*[info sharedlibextension]"]
    }

    append index "# Tcl package index file, version 1.1\n"
    append index "# This file is generated by the \"pkg_mkIndex$more\" command\n"
    append index "# and sourced either when an application starts up or\n"
    append index "# by a \"package unknown\" script.  It invokes the\n"
    append index "# \"package ifneeded\" command to set up package-related\n"
    append index "# information so that packages will be loaded automatically\n"
    append index "# in response to \"package require\" commands.  When this\n"
    append index "# script is sourced, the variable \$dir must contain the\n"
    append index "# full path name of this file's directory.\n"
    set oldDir [pwd]
    cd $dir

    if {[catch {eval glob $patternList} fileList]} {
	global errorCode errorInfo
	cd $oldDir
	return -code error -errorcode $errorCode -errorinfo $errorInfo $fileList
    }
    foreach file $fileList {
	# For each file, figure out what commands and packages it provides.
	# To do this, create a child interpreter, load the file into the
	# interpreter, and get a list of the new commands and packages
	# that are defined.

	if {[string compare $file "pkgIndex.tcl"] == 0} {
	    continue
	}

	# Changed back to the original directory before initializing the
	# slave in case TCL_LIBRARY is a relative path (e.g. in the test
	# suite). 

	cd $oldDir
	set c [interp create]

	# Load into the child any packages currently loaded in the parent
	# interpreter that match the -load pattern.

	foreach pkg [info loaded] {
	    if {! [string match $loadPat [lindex $pkg 1]]} {
		continue
	    }
	    if {[lindex $pkg 1] == "Tk"} {
		$c eval {set argv {-geometry +0+0}}
	    }
	    if {[catch {
		load [lindex $pkg 0] [lindex $pkg 1] $c
	    } err]} {
		if {$doVerbose} {
		    tclLog "warning: load [lindex $pkg 0] [lindex $pkg 1]\nfailed with: $err"
		}
	    } else {
		if {$doVerbose} {
		    tclLog "loaded [lindex $pkg 0] [lindex $pkg 1]"
		}
	    }
	}
	cd $dir

	$c eval {
	    # Stub out the package command so packages can
	    # require other packages.

	    rename package __package_orig
	    proc package {what args} {
		switch -- $what {
		    require { return ; # ignore transitive requires }
		    default { eval __package_orig {$what} $args }
		}
	    }
	    proc tclPkgUnknown args {}
	    package unknown tclPkgUnknown

	    # Stub out the unknown command so package can call
	    # into each other during their initialilzation.

	    proc unknown {args} {}

	    # Stub out the auto_import mechanism

	    proc auto_import {args} {}

	    # reserve the ::tcl namespace for support procs
	    # and temporary variables.  This might make it awkward
	    # to generate a pkgIndex.tcl file for the ::tcl namespace.

	    namespace eval ::tcl {
		variable file		;# Current file being processed
		variable direct		;# -direct flag value
		variable x		;# Loop variable
		variable debug		;# For debugging
		variable type		;# "load" or "source", for -direct
		variable namespaces	;# Existing namespaces (e.g., ::tcl)
		variable packages	;# Existing packages (e.g., Tcl)
		variable origCmds	;# Existing commands
		variable newCmds	;# Newly created commands
		variable newPkgs {}	;# Newly created packages
	    }
	}

	$c eval [list set ::tcl::file $file]
	$c eval [list set ::tcl::direct $direct]

	# Download needed procedures into the slave because we've
	# just deleted the unknown procedure.  This doesn't handle
	# procedures with default arguments.

	foreach p {pkg_compareExtension} {
	    $c eval [list proc $p [info args $p] [info body $p]]
	}

	if {[catch {
	    $c eval {
		set ::tcl::debug "loading or sourcing"

		# we need to track command defined by each package even in
		# the -direct case, because they are needed internally by
		# the "partial pkgIndex.tcl" step above.

		proc ::tcl::GetAllNamespaces {{root ::}} {
		    set list $root
		    foreach ns [namespace children $root] {
			eval lappend list [::tcl::GetAllNamespaces $ns]
		    }
		    return $list
		}

		# initialize the list of existing namespaces, packages, commands

		foreach ::tcl::x [::tcl::GetAllNamespaces] {
		    set ::tcl::namespaces($::tcl::x) 1
		}
		foreach ::tcl::x [package names] {
		    set ::tcl::packages($::tcl::x) 1
		}
		set ::tcl::origCmds [info commands]

		# Try to load the file if it has the shared library
		# extension, otherwise source it.  It's important not to
		# try to load files that aren't shared libraries, because
		# on some systems (like SunOS) the loader will abort the
		# whole application when it gets an error.

		if {[pkg_compareExtension $::tcl::file [info sharedlibextension]]} {
		    # The "file join ." command below is necessary.
		    # Without it, if the file name has no \'s and we're
		    # on UNIX, the load command will invoke the
		    # LD_LIBRARY_PATH search mechanism, which could cause
		    # the wrong file to be used.

		    set ::tcl::debug loading
		    load [file join . $::tcl::file]
		    set ::tcl::type load
		} else {
		    set ::tcl::debug sourcing
		    source $::tcl::file
		    set ::tcl::type source
		}

		# See what new namespaces appeared, and import commands
		# from them.  Only exported commands go into the index.

		foreach ::tcl::x [::tcl::GetAllNamespaces] {
		    if {! [info exists ::tcl::namespaces($::tcl::x)]} {
			namespace import -force ${::tcl::x}::*
		    }
		}

		# Figure out what commands appeared

		foreach ::tcl::x [info commands] {
		    set ::tcl::newCmds($::tcl::x) 1
		}
		foreach ::tcl::x $::tcl::origCmds {
		    catch {unset ::tcl::newCmds($::tcl::x)}
		}
		foreach ::tcl::x [array names ::tcl::newCmds] {
		    # reverse engineer which namespace a command comes from
		    
		    set ::tcl::abs [namespace origin $::tcl::x]

		    # special case so that global names have no leading
		    # ::, this is required by the unknown command

		    set ::tcl::abs [auto_qualify $::tcl::abs ::]

		    if {[string compare $::tcl::x $::tcl::abs] != 0} {
			# Name changed during qualification

			set ::tcl::newCmds($::tcl::abs) 1
			unset ::tcl::newCmds($::tcl::x)
		    }
		}

		# Look through the packages that appeared, and if there is
		# a version provided, then record it

		foreach ::tcl::x [package names] {
		    if {([string compare [package provide $::tcl::x] ""] != 0) \
			    && ![info exists ::tcl::packages($::tcl::x)]} {
			lappend ::tcl::newPkgs \
			    [list $::tcl::x [package provide $::tcl::x]]
		    }
		}
	    }
	} msg] == 1} {
	    set what [$c eval set ::tcl::debug]
	    if {$doVerbose} {
		tclLog "warning: error while $what $file: $msg"
	    }
	} else {
	    set type [$c eval set ::tcl::type]
	    set cmds [lsort [$c eval array names ::tcl::newCmds]]
	    set pkgs [$c eval set ::tcl::newPkgs]
	    if {[llength $pkgs] > 1} {
		tclLog "warning: \"$file\" provides more than one package ($pkgs)"
	    }
	    foreach pkg $pkgs {
		# cmds is empty/not used in the direct case
		lappend files($pkg) [list $file $type $cmds]
	    }

	    if {$doVerbose} {
		tclLog "processed $file"
	    }
	    interp delete $c
	}
    }

    foreach pkg [lsort [array names files]] {
	append index "\npackage ifneeded $pkg "
	if {$direct} {
	    set cmdList {}
	    foreach elem $files($pkg) {
		set file [lindex $elem 0]
		set type [lindex $elem 1]
		lappend cmdList "\[list $type \[file join \$dir\
			[list $file]\]\]"
	    }
	    append index [join $cmdList "\\n"]
	} else {
	    append index "\[list tclPkgSetup \$dir [lrange $pkg 0 0]\
		    [lrange $pkg 1 1] [list $files($pkg)]\]"
	}
    }
    set f [open pkgIndex.tcl w]
    puts $f $index
    close $f
    cd $oldDir
}

# tclPkgSetup --
# This is a utility procedure use by pkgIndex.tcl files.  It is invoked
# as part of a "package ifneeded" script.  It calls "package provide"
# to indicate that a package is available, then sets entries in the
# auto_index array so that the package's files will be auto-loaded when
# the commands are used.
#
# Arguments:
# dir -			Directory containing all the files for this package.
# pkg -			Name of the package (no version number).
# version -		Version number for the package, such as 2.1.3.
# files -		List of files that constitute the package.  Each
#			element is a sub-list with three elements.  The first
#			is the name of a file relative to $dir, the second is
#			"load" or "source", indicating whether the file is a
#			loadable binary or a script to source, and the third
#			is a list of commands defined by this file.

proc tclPkgSetup {dir pkg version files} {
    global auto_index

    package provide $pkg $version
    foreach fileInfo $files {
	set f [lindex $fileInfo 0]
	set type [lindex $fileInfo 1]
	foreach cmd [lindex $fileInfo 2] {
	    if {$type == "load"} {
		set auto_index($cmd) [list load [file join $dir $f] $pkg]
	    } else {
		set auto_index($cmd) [list source [file join $dir $f]]
	    } 
	}
    }
}

# tclMacPkgSearch --
# The procedure is used on the Macintosh to search a given directory for files
# with a TEXT resource named "pkgIndex".  If it exists it is sourced in to the
# interpreter to setup the package database.

proc tclMacPkgSearch {dir} {
    foreach x [glob -nocomplain [file join $dir *.shlb]] {
	if {[file isfile $x]} {
	    set res [resource open $x]
	    foreach y [resource list TEXT $res] {
		if {$y == "pkgIndex"} {source -rsrc pkgIndex}
	    }
	    catch {resource close $res}
	}
    }
}

# tclPkgUnknown --
# This procedure provides the default for the "package unknown" function.
# It is invoked when a package that's needed can't be found.  It scans
# the auto_path directories and their immediate children looking for
# pkgIndex.tcl files and sources any such files that are found to setup
# the package database.  (On the Macintosh we also search for pkgIndex
# TEXT resources in all files.)
#
# Arguments:
# name -		Name of desired package.  Not used.
# version -		Version of desired package.  Not used.
# exact -		Either "-exact" or omitted.  Not used.

proc tclPkgUnknown {name version {exact {}}} {
    global auto_path tcl_platform env

    if {![info exists auto_path]} {
	return
    }
    for {set i [expr {[llength $auto_path] - 1}]} {$i >= 0} {incr i -1} {
	# we can't use glob in safe interps, so enclose the following
	# in a catch statement
	catch {
	    foreach file [glob -nocomplain [file join [lindex $auto_path $i] \
		    * pkgIndex.tcl]] {
		set dir [file dirname $file]
		if {[catch {source $file} msg]} {
		    tclLog "error reading package index file $file: $msg"
		}
	    }
        }
	set dir [lindex $auto_path $i]
	set file [file join $dir pkgIndex.tcl]
	# safe interps usually don't have "file readable", nor stderr channel
	if {[interp issafe] || [file readable $file]} {
	    if {[catch {source $file} msg] && ![interp issafe]}  {
		tclLog "error reading package index file $file: $msg"
	    }
	}
	# On the Macintosh we also look in the resource fork 
	# of shared libraries
	# We can't use tclMacPkgSearch in safe interps because it uses glob
	if {(![interp issafe]) && ($tcl_platform(platform) == "macintosh")} {
	    set dir [lindex $auto_path $i]
	    tclMacPkgSearch $dir
	    foreach x [glob -nocomplain [file join $dir *]] {
		if {[file isdirectory $x]} {
		    set dir $x
		    tclMacPkgSearch $dir
		}
	    }
	}
    }
}

Changes to library/parray.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# parray:
# Print the contents of a global array on stdout.
#
# SCCS: @(#) parray.tcl 1.9 96/02/16 08:56:44
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

proc parray {a {pattern *}} {
    upvar 1 $a array
    if ![array exists array] {
	error "\"$a\" isn't an array"
    }
    set maxl 0
    foreach name [lsort [array names array $pattern]] {
	if {[string length $name] > $maxl} {
	    set maxl [string length $name]
	}



|










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# parray:
# Print the contents of a global array on stdout.
#
# RCS: @(#) $Id: parray.tcl,v 1.1.2.2 1998/09/24 23:59:06 stanton Exp $
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

proc parray {a {pattern *}} {
    upvar 1 $a array
    if {![array exists array]} {
	error "\"$a\" isn't an array"
    }
    set maxl 0
    foreach name [lsort [array names array $pattern]] {
	if {[string length $name] > $maxl} {
	    set maxl [string length $name]
	}

Changes to library/safe.tcl.

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
# See the safe.n man page for details.
#
# 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.
#
# SCCS: @(#) safe.tcl 1.26 97/08/21 11:57:20

#
# The implementation is based on namespaces. These naming conventions
# are followed:
# Private procs starts with uppercase.
# Public  procs are exported and starts with lowercase
#

# Needed utilities package
package require opt 0.2;

# Create the safe namespace
namespace eval ::safe {

    # Exported API:
    namespace export interpCreate interpInit interpConfigure interpDelete \
	    interpAddToAccessPath interpFindInAccessPath \
	    setLogCmd ;

# Proto/dummy declarations for auto_mkIndex
proc ::safe::interpCreate {} {}
proc ::safe::interpInit {} {}
proc ::safe::interpConfigure {} {}


    ####
    #
    # Setup the arguments parsing
    #
    ####








|









|








<
<
<
<
<
<







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
# See the safe.n man page for details.
#
# 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: safe.tcl,v 1.1.2.4 1999/04/06 00:43:17 redman Exp $

#
# The implementation is based on namespaces. These naming conventions
# are followed:
# Private procs starts with uppercase.
# Public  procs are exported and starts with lowercase
#

# Needed utilities package
package require opt 0.4.1;

# Create the safe namespace
namespace eval ::safe {

    # Exported API:
    namespace export interpCreate interpInit interpConfigure interpDelete \
	    interpAddToAccessPath interpFindInAccessPath \
	    setLogCmd ;







    ####
    #
    # Setup the arguments parsing
    #
    ####

413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
	set n [Set $nname];
	Set [PathToken $n $slave] $path;

	set token "\$[PathToken $n]";

	Lappend [VirtualPathListName $slave] $token;
	Lappend [PathListName $slave] $path;
	Set $nname [expr $n+1];

	SyncAccessPath $slave;

	return $token;
    }

    # This procedure applies the initializations to an already existing







|







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
	set n [Set $nname];
	Set [PathToken $n $slave] $path;

	set token "\$[PathToken $n]";

	Lappend [VirtualPathListName $slave] $token;
	Lappend [PathListName $slave] $path;
	Set $nname [expr {$n+1}];

	SyncAccessPath $slave;

	return $token;
    }

    # This procedure applies the initializations to an already existing
441
442
443
444
445
446
447







448
449
450
451
452
453
454

	# These aliases let the slave load files to define new commands

	# NB we need to add [namespace current], aliases are always
	# absolute paths.
	::interp alias $slave source {} [namespace current]::AliasSource $slave
	::interp alias $slave load {} [namespace current]::AliasLoad $slave








	# This alias lets the slave have access to a subset of the 'file'
	# command functionality.

	AliasSubset $slave file file dir.* join root.* ext.* tail \
		path.* split








>
>
>
>
>
>
>







435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

	# These aliases let the slave load files to define new commands

	# NB we need to add [namespace current], aliases are always
	# absolute paths.
	::interp alias $slave source {} [namespace current]::AliasSource $slave
	::interp alias $slave load {} [namespace current]::AliasLoad $slave

	# This alias lets the slave use the encoding names, convertfrom,
	# convertto, and system, but not "encoding system <name>" to set
	# the system encoding.

	::interp alias $slave encoding {} [namespace current]::AliasEncoding \
		$slave

	# This alias lets the slave have access to a subset of the 'file'
	# command functionality.

	AliasSubset $slave file file dir.* join root.* ext.* tail \
		path.* split

524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
	set hookname [DeleteHookName $slave];
	if {[Exists $hookname]} {
	    set hook [Set $hookname];
	    if {![::tcl::Lempty $hook]} {
		# remove the hook now, otherwise if the hook
		# calls us somehow, we'll loop
		Unset $hookname;
		if {[catch {eval $hook $slave} err]} {
		    Log $slave "Delete hook error ($err)";
		}
	    }
	}

	# Discard the global array of state associated with the slave, and
	# delete the interpreter.







|







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
	set hookname [DeleteHookName $slave];
	if {[Exists $hookname]} {
	    set hook [Set $hookname];
	    if {![::tcl::Lempty $hook]} {
		# remove the hook now, otherwise if the hook
		# calls us somehow, we'll loop
		Unset $hookname;
		if {[catch {eval $hook [list $slave]} err]} {
		    Log $slave "Delete hook error ($err)";
		}
	    }
	}

	# Discard the global array of state associated with the slave, and
	# delete the interpreter.
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
    #
    proc TranslatePath {slave path} {
	# somehow strip the namespaces 'functionality' out (the danger
	# is that we would strip valid macintosh "../" queries... :
	if {[regexp {(::)|(\.\.)} $path]} {
	    error "invalid characters in path $path";
	}
	set n [expr [Set [PathNumberName $slave]]-1];
	for {} {$n>=0} {incr n -1} {
	    # fill the token virtual names with their real value
	    set [PathToken $n] [Set [PathToken $n $slave]];
	}
	# replaces the token by their value
	subst -nobackslashes -nocommands $path;
    }







|







678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
    #
    proc TranslatePath {slave path} {
	# somehow strip the namespaces 'functionality' out (the danger
	# is that we would strip valid macintosh "../" queries... :
	if {[regexp {(::)|(\.\.)} $path]} {
	    error "invalid characters in path $path";
	}
	set n [expr {[Set [PathNumberName $slave]]-1}];
	for {} {$n>=0} {incr n -1} {
	    # fill the token virtual names with their real value
	    set [PathToken $n] [Set [PathToken $n $slave]];
	}
	# replaces the token by their value
	subst -nobackslashes -nocommands $path;
    }
885
886
887
888
889
890
891
892

893




































	    append pat $sep$sub
	    set sep |
	}
	append pat )\$
	::interp alias $slave $alias {}\
		[namespace current]::Subset $slave $target $pat
    }


}












































>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
	    append pat $sep$sub
	    set sep |
	}
	append pat )\$
	::interp alias $slave $alias {}\
		[namespace current]::Subset $slave $target $pat
    }

    # AliasEncoding is the target of the "encoding" alias in safe interpreters.

    proc AliasEncoding {slave args} {

	set argc [llength $args];

	set okpat "^(name.*|convert.*)\$"
	set subcommand [lindex $args 0]

	if {[regexp $okpat $subcommand]} {
	    return [eval ::interp invokehidden $slave encoding $subcommand \
		    [lrange $args 1 end]]
	}

	if {[string match $subcommand system]} {
	    if {$argc == 1} {
		# passed all the tests , lets source it:
		if {[catch {::interp invokehidden \
			$slave encoding system} msg]} {
		    Log $slave $msg;
		    return -code error "script error";
		}
	    } else {
		set msg "wrong # args: should be \"encoding system\"";
		Log $slave $msg;
		error $msg;
	    }
	} else {
	    set msg "wrong # args: should be \"encoding option ?arg ...?\"";
	    Log $slave $msg;
	    error $msg;
	}
	
	
	return $msg
    }

}

Changes to library/tclIndex.

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
# Tcl autoload index file, version 2.0
# This file is generated by the "auto_mkindex" command
# and sourced to set up indexing information for one or
# more commands.  Typically each line is a command that
# sets an element in the auto_index array, where the
# element name is the name of a command and the value is
# a script that loads the command.

set auto_index(auto_execok) [list source [file join $dir init.tcl]]
set auto_index(auto_reset) [list source [file join $dir init.tcl]]

set auto_index(auto_mkindex) [list source [file join $dir init.tcl]]




















set auto_index(pkg_mkIndex) [list source [file join $dir init.tcl]]
set auto_index(tclPkgSetup) [list source [file join $dir init.tcl]]
set auto_index(tclMacPkgSearch) [list source [file join $dir init.tcl]]
set auto_index(tclPkgUnknown) [list source [file join $dir init.tcl]]
set auto_index(parray) [list source [file join $dir parray.tcl]]
























set auto_index(tclLdAout) [list source [file join $dir ldAout.tcl]]















set auto_index(tcl_wordBreakAfter) [list source [file join $dir word.tcl]]
set auto_index(tcl_wordBreakBefore) [list source [file join $dir word.tcl]]
set auto_index(tcl_endOfWord) [list source [file join $dir word.tcl]]
set auto_index(tcl_startOfNextWord) [list source [file join $dir word.tcl]]
set auto_index(tcl_startOfPreviousWord) [list source [file join $dir word.tcl]]
set auto_index(::safe::interpCreate) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpInit) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpConfigure) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpFindInAccessPath) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpAddToAccessPath) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpDelete) [list source [file join $dir safe.tcl]]
set auto_index(::safe::setLogCmd) [list source [file join $dir safe.tcl]]
set auto_index(history) [list source [file join $dir history.tcl]]








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

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





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








# Tcl autoload index file, version 2.0
# This file is generated by the "auto_mkindex" command
# and sourced to set up indexing information for one or
# more commands.  Typically each line is a command that
# sets an element in the auto_index array, where the
# element name is the name of a command and the value is
# a script that loads the command.


set auto_index(auto_reset) [list source [file join $dir auto.tcl]]
set auto_index(tcl_findLibrary) [list source [file join $dir auto.tcl]]
set auto_index(auto_mkindex) [list source [file join $dir auto.tcl]]
set auto_index(auto_mkindex_old) [list source [file join $dir auto.tcl]]
set auto_index(::auto_mkindex_parser::init) [list source [file join $dir auto.tcl]]
set auto_index(::auto_mkindex_parser::cleanup) [list source [file join $dir auto.tcl]]
set auto_index(::auto_mkindex_parser::mkindex) [list source [file join $dir auto.tcl]]
set auto_index(::auto_mkindex_parser::hook) [list source [file join $dir auto.tcl]]
set auto_index(::auto_mkindex_parser::slavehook) [list source [file join $dir auto.tcl]]
set auto_index(::auto_mkindex_parser::command) [list source [file join $dir auto.tcl]]
set auto_index(::auto_mkindex_parser::commandInit) [list source [file join $dir auto.tcl]]
set auto_index(::auto_mkindex_parser::fullname) [list source [file join $dir auto.tcl]]
set auto_index(history) [list source [file join $dir history.tcl]]
set auto_index(::tcl::HistAdd) [list source [file join $dir history.tcl]]
set auto_index(::tcl::HistKeep) [list source [file join $dir history.tcl]]
set auto_index(::tcl::HistClear) [list source [file join $dir history.tcl]]
set auto_index(::tcl::HistInfo) [list source [file join $dir history.tcl]]
set auto_index(::tcl::HistRedo) [list source [file join $dir history.tcl]]
set auto_index(::tcl::HistIndex) [list source [file join $dir history.tcl]]
set auto_index(::tcl::HistEvent) [list source [file join $dir history.tcl]]
set auto_index(::tcl::HistChange) [list source [file join $dir history.tcl]]
set auto_index(tclLdAout) [list source [file join $dir ldAout.tcl]]
set auto_index(pkg_compareExtension) [list source [file join $dir package.tcl]]
set auto_index(pkg_mkIndex) [list source [file join $dir package.tcl]]
set auto_index(tclPkgSetup) [list source [file join $dir package.tcl]]
set auto_index(tclMacPkgSearch) [list source [file join $dir package.tcl]]
set auto_index(tclPkgUnknown) [list source [file join $dir package.tcl]]
set auto_index(parray) [list source [file join $dir parray.tcl]]
set auto_index(::safe::InterpStatics) [list source [file join $dir safe.tcl]]
set auto_index(::safe::InterpNested) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpCreate) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpInit) [list source [file join $dir safe.tcl]]
set auto_index(::safe::CheckInterp) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpConfigure) [list source [file join $dir safe.tcl]]
set auto_index(::safe::InterpCreate) [list source [file join $dir safe.tcl]]
set auto_index(::safe::InterpSetConfig) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpFindInAccessPath) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpAddToAccessPath) [list source [file join $dir safe.tcl]]
set auto_index(::safe::InterpInit) [list source [file join $dir safe.tcl]]
set auto_index(::safe::AddSubDirs) [list source [file join $dir safe.tcl]]
set auto_index(::safe::interpDelete) [list source [file join $dir safe.tcl]]
set auto_index(::safe::setLogCmd) [list source [file join $dir safe.tcl]]
set auto_index(::safe::SyncAccessPath) [list source [file join $dir safe.tcl]]
set auto_index(::safe::InterpStateName) [list source [file join $dir safe.tcl]]
set auto_index(::safe::IsInterp) [list source [file join $dir safe.tcl]]
set auto_index(::safe::PathToken) [list source [file join $dir safe.tcl]]
set auto_index(::safe::PathListName) [list source [file join $dir safe.tcl]]
set auto_index(::safe::VirtualPathListName) [list source [file join $dir safe.tcl]]
set auto_index(::safe::PathNumberName) [list source [file join $dir safe.tcl]]
set auto_index(::safe::StaticsOkName) [list source [file join $dir safe.tcl]]
set auto_index(::safe::NestedOkName) [list source [file join $dir safe.tcl]]
set auto_index(::safe::Toplevel) [list source [file join $dir safe.tcl]]
set auto_index(::safe::Set) [list source [file join $dir safe.tcl]]
set auto_index(::safe::Lappend) [list source [file join $dir safe.tcl]]
set auto_index(::safe::Unset) [list source [file join $dir safe.tcl]]
set auto_index(::safe::Exists) [list source [file join $dir safe.tcl]]
set auto_index(::safe::GetAccessPath) [list source [file join $dir safe.tcl]]
set auto_index(::safe::StaticsOk) [list source [file join $dir safe.tcl]]
set auto_index(::safe::NestedOk) [list source [file join $dir safe.tcl]]
set auto_index(::safe::DeleteHookName) [list source [file join $dir safe.tcl]]
set auto_index(::safe::TranslatePath) [list source [file join $dir safe.tcl]]
set auto_index(::safe::Log) [list source [file join $dir safe.tcl]]
set auto_index(::safe::CheckFileName) [list source [file join $dir safe.tcl]]
set auto_index(::safe::AliasSource) [list source [file join $dir safe.tcl]]
set auto_index(::safe::AliasLoad) [list source [file join $dir safe.tcl]]
set auto_index(::safe::FileInAccessPath) [list source [file join $dir safe.tcl]]
set auto_index(::safe::Subset) [list source [file join $dir safe.tcl]]
set auto_index(::safe::AliasSubset) [list source [file join $dir safe.tcl]]
set auto_index(tcl_wordBreakAfter) [list source [file join $dir word.tcl]]
set auto_index(tcl_wordBreakBefore) [list source [file join $dir word.tcl]]
set auto_index(tcl_endOfWord) [list source [file join $dir word.tcl]]
set auto_index(tcl_startOfNextWord) [list source [file join $dir word.tcl]]
set auto_index(tcl_startOfPreviousWord) [list source [file join $dir word.tcl]]








Changes to library/word.tcl.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# word.tcl --
#
# This file defines various procedures for computing word boundaries
# in strings.  This file is primarily needed so Tk text and entry
# widgets behave properly for different platforms.
#
# Copyright (c) 1996 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.
# 
# SCCS: @(#) word.tcl 1.2 96/11/20 14:07:22
# 
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# The following variables are used to determine which characters are
# interpreted as white space.  

if {$tcl_platform(platform) == "windows"} {
    # Windows style - any but space, tab, or newline
    set tcl_wordchars "\[^ \t\n\]"







>




|
<
<
<
<







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




14
15
16
17
18
19
20
# word.tcl --
#
# This file defines various procedures for computing word boundaries
# in strings.  This file is primarily needed so Tk text and entry
# widgets behave properly for different platforms.
#
# Copyright (c) 1996 by Sun Microsystems, Inc.
# Copyright (c) 1998 by Scritpics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# RCS: @(#) $Id: word.tcl,v 1.1.2.2 1998/09/24 23:59:07 stanton Exp $





# The following variables are used to determine which characters are
# interpreted as white space.  

if {$tcl_platform(platform) == "windows"} {
    # Windows style - any but space, tab, or newline
    set tcl_wordchars "\[^ \t\n\]"
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
# Arguments:
# str -		String to search.
# start -	Index into string specifying starting point.

proc tcl_wordBreakAfter {str start} {
    global tcl_nonwordchars tcl_wordchars
    set str [string range $str $start end]
    if [regexp -indices "$tcl_wordchars$tcl_nonwordchars|$tcl_nonwordchars$tcl_wordchars" $str result] {
	return [expr [lindex $result 1] + $start]
    }
    return -1
}

# tcl_wordBreakBefore --
#
# This procedure returns the index of the first word boundary
# before the starting point in the given string, or -1 if there
# are no more boundaries in the given string.  The index returned
# refers to the second character of the pair that comprises a boundary.
#
# Arguments:
# str -		String to search.
# start -	Index into string specifying starting point.

proc tcl_wordBreakBefore {str start} {
    global tcl_nonwordchars tcl_wordchars
    if {[string compare $start end] == 0} {
	set start [string length $str]
    }
    if [regexp -indices "^.*($tcl_wordchars$tcl_nonwordchars|$tcl_nonwordchars$tcl_wordchars)" [string range $str 0 $start] result] {
	return [lindex $result 1]
    }
    return -1
}

# tcl_endOfWord --
#
# This procedure returns the index of the first end-of-word location
# after a starting index in the given string.  An end-of-word location
# is defined to be the first whitespace character following the first
# non-whitespace character after the starting point.  Returns -1 if
# there are no more words after the starting point.
#
# Arguments:
# str -		String to search.
# start -	Index into string specifying starting point.

proc tcl_endOfWord {str start} {
    global tcl_nonwordchars tcl_wordchars
    if [regexp -indices "$tcl_nonwordchars*$tcl_wordchars+$tcl_nonwordchars" \
	    [string range $str $start end] result] {
	return [expr [lindex $result 1] + $start]
    }
    return -1
}

# tcl_startOfNextWord --
#
# This procedure returns the index of the first start-of-word location
# after a starting index in the given string.  A start-of-word
# location is defined to be a non-whitespace character following a
# whitespace character.  Returns -1 if there are no more start-of-word
# locations after the starting point.
#
# Arguments:
# str -		String to search.
# start -	Index into string specifying starting point.

proc tcl_startOfNextWord {str start} {
    global tcl_nonwordchars tcl_wordchars
    if [regexp -indices "$tcl_wordchars*$tcl_nonwordchars+$tcl_wordchars" \
	    [string range $str $start end] result] {
	return [expr [lindex $result 1] + $start]
    }
    return -1
}

# tcl_startOfPreviousWord --
#
# This procedure returns the index of the first start-of-word location
# before a starting index in the given string.
#
# Arguments:
# str -		String to search.
# start -	Index into string specifying starting point.

proc tcl_startOfPreviousWord {str start} {
    global tcl_nonwordchars tcl_wordchars
    if {[string compare $start end] == 0} {
	set start [string length $str]
    }
    if [regexp -indices \
	    "$tcl_nonwordchars*($tcl_wordchars+)$tcl_nonwordchars*\$" \
	    [string range $str 0 [expr $start - 1]] result word] {
	return [lindex $word 0]
    }
    return -1
}







|
|




















|



















|
|
|


















|
|
|


















|

|




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
# Arguments:
# str -		String to search.
# start -	Index into string specifying starting point.

proc tcl_wordBreakAfter {str start} {
    global tcl_nonwordchars tcl_wordchars
    set str [string range $str $start end]
    if {[regexp -indices "$tcl_wordchars$tcl_nonwordchars|$tcl_nonwordchars$tcl_wordchars" $str result]} {
	return [expr {[lindex $result 1] + $start}]
    }
    return -1
}

# tcl_wordBreakBefore --
#
# This procedure returns the index of the first word boundary
# before the starting point in the given string, or -1 if there
# are no more boundaries in the given string.  The index returned
# refers to the second character of the pair that comprises a boundary.
#
# Arguments:
# str -		String to search.
# start -	Index into string specifying starting point.

proc tcl_wordBreakBefore {str start} {
    global tcl_nonwordchars tcl_wordchars
    if {[string compare $start end] == 0} {
	set start [string length $str]
    }
    if {[regexp -indices "^.*($tcl_wordchars$tcl_nonwordchars|$tcl_nonwordchars$tcl_wordchars)" [string range $str 0 $start] result]} {
	return [lindex $result 1]
    }
    return -1
}

# tcl_endOfWord --
#
# This procedure returns the index of the first end-of-word location
# after a starting index in the given string.  An end-of-word location
# is defined to be the first whitespace character following the first
# non-whitespace character after the starting point.  Returns -1 if
# there are no more words after the starting point.
#
# Arguments:
# str -		String to search.
# start -	Index into string specifying starting point.

proc tcl_endOfWord {str start} {
    global tcl_nonwordchars tcl_wordchars
    if {[regexp -indices "$tcl_nonwordchars*$tcl_wordchars+$tcl_nonwordchars" \
	    [string range $str $start end] result]} {
	return [expr {[lindex $result 1] + $start}]
    }
    return -1
}

# tcl_startOfNextWord --
#
# This procedure returns the index of the first start-of-word location
# after a starting index in the given string.  A start-of-word
# location is defined to be a non-whitespace character following a
# whitespace character.  Returns -1 if there are no more start-of-word
# locations after the starting point.
#
# Arguments:
# str -		String to search.
# start -	Index into string specifying starting point.

proc tcl_startOfNextWord {str start} {
    global tcl_nonwordchars tcl_wordchars
    if {[regexp -indices "$tcl_wordchars*$tcl_nonwordchars+$tcl_wordchars" \
	    [string range $str $start end] result]} {
	return [expr {[lindex $result 1] + $start}]
    }
    return -1
}

# tcl_startOfPreviousWord --
#
# This procedure returns the index of the first start-of-word location
# before a starting index in the given string.
#
# Arguments:
# str -		String to search.
# start -	Index into string specifying starting point.

proc tcl_startOfPreviousWord {str start} {
    global tcl_nonwordchars tcl_wordchars
    if {[string compare $start end] == 0} {
	set start [string length $str]
    }
    if {[regexp -indices \
	    "$tcl_nonwordchars*($tcl_wordchars+)$tcl_nonwordchars*\$" \
	    [string range $str 0 [expr {$start - 1}]] result word]} {
	return [lindex $word 0]
    }
    return -1
}

Changes to license.terms.

1
2
3
4
5
6
7
8
9
10
11
This software is copyrighted by the Regents of the University of
California, Sun Microsystems, Inc., and other parties.  The following
terms apply to all files associated with the software unless explicitly
disclaimed in individual files.

The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
that existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written agreement,
license, or royalty fee is required for any of the authorized uses.
Modifications to this software may be copyrighted by their authors

|
|
|







1
2
3
4
5
6
7
8
9
10
11
This software is copyrighted by the Regents of the University of
California, Sun Microsystems, Inc., Scriptics Corporation,
and other parties.  The following terms apply to all files associated
with the software unless explicitly disclaimed in individual files.

The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
that existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written agreement,
license, or royalty fee is required for any of the authorized uses.
Modifications to this software may be copyrighted by their authors

Changes to mac/Background.doc.

1
2
3
4
5
6
7
8
9
10
11
Notes about the Background Only application template
====================================================

SCCS: @(#) Background.doc 1.1 97/11/03 17:05:54

We have included sample code and project files for making a Background-Only
 application (BOA) in Tcl.  This could be used for server processes (like the 
Tcl Web-Server).  

Files:
------



|







1
2
3
4
5
6
7
8
9
10
11
Notes about the Background Only application template
====================================================

RCS: @(#) $Id: Background.doc,v 1.1.2.1 1998/09/24 23:59:08 stanton Exp $

We have included sample code and project files for making a Background-Only
 application (BOA) in Tcl.  This could be used for server processes (like the 
Tcl Web-Server).  

Files:
------

Changes to mac/MW_TclAppleScriptHeader.pch.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
 *  compiler flags.  See MetroWerks documention for more details.
 *
 * 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.
 *
 * SCCS: @(#) MW_TclAppleScriptHeader.pch 1.1 97/09/09 16:38:07
 */

/*
 * To use the compilied header you need to set the "Prefix file" in
 * the "C/C++ Language" preference panel to point to the created
 * compilied header.  The name of the header depends on the
 * architecture we are compiling for (see the code below).  For
 * example, for a 68k app the prefix file should be: MW_TclHeader68K.
 */

#if __POWERPC__
#pragma precompile_target "MW_TclAppleScriptHeaderPPC"
#include "MW_TclHeaderPPC"
#elif __CFM68K__
#pragma precompile_target "MW_TclAppleScriptHeaderCFM68K"
#include "MW_TclHeaderCFM68K"
#else







|









>







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
 *  compiler flags.  See MetroWerks documention for more details.
 *
 * 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: MW_TclAppleScriptHeader.pch,v 1.1.2.2 1998/11/11 04:08:26 stanton Exp $
 */

/*
 * To use the compilied header you need to set the "Prefix file" in
 * the "C/C++ Language" preference panel to point to the created
 * compilied header.  The name of the header depends on the
 * architecture we are compiling for (see the code below).  For
 * example, for a 68k app the prefix file should be: MW_TclHeader68K.
 */

#if __POWERPC__
#pragma precompile_target "MW_TclAppleScriptHeaderPPC"
#include "MW_TclHeaderPPC"
#elif __CFM68K__
#pragma precompile_target "MW_TclAppleScriptHeaderCFM68K"
#include "MW_TclHeaderCFM68K"
#else

Changes to mac/MW_TclHeader.pch.

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
 *  compiler flags.  See MetroWerks documention for more details.
 *
 * 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.
 *
 * SCCS: @(#) MW_TclHeader.pch 1.27 97/11/20 18:45:25
 */

/*
 * To use the compilied header you need to set the "Prefix file" in
 * the "C/C++ Language" preference panel to point to the created
 * compilied header.  The name of the header depends on the
 * architecture we are compiling for (see the code below).  For
 * example, for a 68k app the prefix file should be: MW_TclHeader68K.
 */
#if __POWERPC__
#pragma precompile_target "MW_TclHeaderPPC"
#elif __CFM68K__
#pragma precompile_target "MW_TclHeaderCFM68K"
#else
#pragma precompile_target "MW_TclHeader68K"
#endif

/*
 * Macintosh Tcl must be compiled with certain compiler options to
 * ensure that it will work correctly.  The following pragmas are 
 * used to ensure that those options are set correctly.  An error
 * will occur at compile time if they are not set correctly.
 */

#if !__option(enumsalwaysint)
#error Tcl requires the Metrowerks setting "Enums always ints".
#endif

#if !defined(__POWERPC__)
#if !__option(far_data)
#error Tcl requires the Metrowerks setting "Far data".
#endif
#endif

#if !defined(__POWERPC__)
#if !__option(fourbyteints)
#error Tcl requires the Metrowerks setting "4 byte ints".
#endif
#endif

#if !defined(__POWERPC__)
#if !__option(IEEEdoubles)
#error Tcl requires the Metrowerks setting "8 byte doubles".
#endif
#endif

/*
 * The define is used most everywhere to tell Tcl (or any Tcl
 * extensions) that we are compiling for the Macintosh platform.
 */

#define MAC_TCL

/*
 * The following defines control the behavior of the Macintosh
 * Universial Headers.
 */

#define SystemSevenOrLater 1
#define STRICT_CONTROLS 1
#define STRICT_WINDOWS  1

/*
 * Define the following symbol if you want
 * comprehensive debugging turned on.
 */

/* #define TCL_DEBUG */

#ifdef TCL_DEBUG
#   define TCL_MEM_DEBUG
#   define TCL_TEST
#endif


/*
 * For a while, we will continue to use the old routine names, so that
 * people with older versions of CodeWarrior will still be able to compile
 * the source (albeit they will have to update the project files themselves).
 *
 * At some point, we will convert over to the new routine names.
 */
 
#define OLDROUTINENAMES 1

/*
 * Place any includes below that will are needed by the majority of the
 * and is OK to be in any file in the system.  The pragma's are used
 * to control what functions are exported in the Tcl shared library.
 */

#pragma export on
#include "tcl.h"
#include "tclMac.h"
#include "tclInt.h"

#pragma export off








|

















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











>
|

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
 *  compiler flags.  See MetroWerks documention for more details.
 *
 * 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: MW_TclHeader.pch,v 1.1.2.3 1998/11/11 04:08:26 stanton Exp $
 */

/*
 * To use the compilied header you need to set the "Prefix file" in
 * the "C/C++ Language" preference panel to point to the created
 * compilied header.  The name of the header depends on the
 * architecture we are compiling for (see the code below).  For
 * example, for a 68k app the prefix file should be: MW_TclHeader68K.
 */
#if __POWERPC__
#pragma precompile_target "MW_TclHeaderPPC"
#elif __CFM68K__
#pragma precompile_target "MW_TclHeaderCFM68K"
#else
#pragma precompile_target "MW_TclHeader68K"
#endif







#include "tclMacCommonPch.h"





























































/*
 * Place any includes below that will are needed by the majority of the
 * and is OK to be in any file in the system.  The pragma's are used
 * to control what functions are exported in the Tcl shared library.
 */

#pragma export on
#include "tcl.h"
#include "tclMac.h"
#include "tclInt.h"

#pragma export reset

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
Tcl 8.0p1 for Macintosh

by Ray Johnson
Sun Microsystems Laboratories
rjohnson@eng.sun.com





SCCS: @(#) README 1.30 97/11/20 22:01:16

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

The main new feature is the Tcl compilier.  You should certainly
notice the speed improvements.  Any problems are probably
generic rather than Mac specific.  If you have questions or
comments about the compilier feel free to forward them to the
author of the compilier: Brian Lewis <[email protected]>.
Several things were fixed/changed since the a1 release so be
sure to check this out.

The largest incompatible change on the Mac is the removal of the
following commands: "rm", "rmdir", "mkdir", "mv" and "cp".  These
commands were never really supported and their functionality is
superceded by the file command.

I've also added in a new "AppleScript" command.  This was contributed
by Jim Ingham who is a new member of the Tcl group.  It's very cool.
The command isn't actually in the core - you need to do a "package
require Tclapplescript" to get access to it.  This code is officially
unsupported and will change in the next release.  However, the core
functionality is there and is stable enough to use.  Documentation 
can be found in "AppleScript.html" in the mac subdirectory.

The resource command has also been rewacked.  You can now read and
write any Mac resource.  Tcl now has the new (and VERY COOL) binary
command that will allow you to pack and unpack the resources into
useful Tcl code. We will eventually provide Tcl libraries for
accessing the most common resources.

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

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 mac
  subdirectory 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.0.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.0.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.0.1.sea.hqx

    This release contains the complete source for Tcl 8.0.  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://sunscript.sun.com/man/tcl8.0/contents.html

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

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





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 1
	Mac Tcl 8.0 (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 1, 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.0: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,
|


|
|
>
>
>
>

|












|
|
<
<
<
<
<

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

|


















|
|



















>








|







|





|

|










|


|



>
>
>
>










|
|



|

|







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

by Ray Johnson
Scriptics Corporation
rjohnson@scriptics.com
with major help from
Jim Ingham
Cygnus Solutions
[email protected]

RCS: @(#) $Id: README,v 1.1.2.4 1999/02/12 00:57:59 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,
179
180
181
182
183
184
185
186
187
  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
jingham@eng.sun.com








|

168
169
170
171
172
173
174
175
176
  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
jingham@cygnus.com

Changes to mac/bugs.doc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Known bug list for Tcl 8.0 for Macintosh

by Ray Johnson
Sun Microsystems Laboratories
[email protected]

SCCS: @(#) bugs.doc 1.6 97/08/13 18:09:12

This was a new feature as of Tcl7.6b1 and as such I'll started with
a clean slate.  I currently know of no reproducable bugs.  I often
get vague reports - but nothing I've been able to confirm.  Let
me know what bugs you find!

The Macintosh version of Tcl passes most all tests in the Tcl






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
Known bug list for Tcl 8.0 for Macintosh

by Ray Johnson
Sun Microsystems Laboratories
[email protected]

RCS: @(#) $Id: bugs.doc,v 1.1.2.1 1998/09/24 23:59:08 stanton Exp $

This was a new feature as of Tcl7.6b1 and as such I'll started with
a clean slate.  I currently know of no reproducable bugs.  I often
get vague reports - but nothing I've been able to confirm.  Let
me know what bugs you find!

The Macintosh version of Tcl passes most all tests in the Tcl

Changes to mac/libmoto.doc.

1
2
3
4
5
6
7
8
9
10
11
Notes about the use of libmoto
------------------------------

@(#) libmoto.doc 1.1 96/07/17 14:29:48

First of all, libmoto is not required!  If you don't have it, you
can simply remove the library reference from the project file and
everything should compile just fine.

The libmoto library replaces certain functions in the MathLib and
ANSI libraries.  Motorola has optimized the functions in the library



|







1
2
3
4
5
6
7
8
9
10
11
Notes about the use of libmoto
------------------------------

RCS: @(#) $Id: libmoto.doc,v 1.1.2.1 1998/09/24 23:59:08 stanton Exp $

First of all, libmoto is not required!  If you don't have it, you
can simply remove the library reference from the project file and
everything should compile just fine.

The libmoto library replaces certain functions in the MathLib and
ANSI libraries.  Motorola has optimized the functions in the library

Changes to mac/morefiles.doc.

1
2
3
4
5
6
7
8
9
10
11
Notes about MoreFiles, dnr.c & other non-Tcl source files
---------------------------------------------------------

@(#) morefiles.doc 1.4 97/08/13 12:57:08

The Macintosh distribution uses several source files that don't
actually ship with Tcl.  This sometimes causes problems or confusion
to developers.  This document should help clear up a few things.

dnr.c
-----



|







1
2
3
4
5
6
7
8
9
10
11
Notes about MoreFiles, dnr.c & other non-Tcl source files
---------------------------------------------------------

RCS: @(#) $Id: morefiles.doc,v 1.1.2.1 1998/09/24 23:59:09 stanton Exp $

The Macintosh distribution uses several source files that don't
actually ship with Tcl.  This sometimes causes problems or confusion
to developers.  This document should help clear up a few things.

dnr.c
-----

Changes to mac/porting.notes.

1
2
3
4
5
6
7
8
9
10
11
Porting Notes
-------------

@(#) porting.notes 1.5 96/07/31 14:59:28

Currently, the Macintosh version Tcl only compilies with the
CodeWarrior C compilier from MetroWerks.  It should be straight
forward to port the Tcl source to MPW.

Tcl on the Mac no longer requires the use of GUSI.  It should now
be easier to port Tcl/Tk to other compiliers such as Symantic C



|







1
2
3
4
5
6
7
8
9
10
11
Porting Notes
-------------

RCS: @(#) $Id: porting.notes,v 1.1.2.1 1998/09/24 23:59:09 stanton Exp $

Currently, the Macintosh version Tcl only compilies with the
CodeWarrior C compilier from MetroWerks.  It should be straight
forward to port the Tcl source to MPW.

Tcl on the Mac no longer requires the use of GUSI.  It should now
be easier to port Tcl/Tk to other compiliers such as Symantic C

Changes to mac/tclMac.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tclMac.h --
 *
 *	Declarations of Macintosh specific public variables and procedures.
 *
 * 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.
 *
 * SCCS: @(#) tclMac.h 1.8 97/06/24 18:59:08
 */

#ifndef _TCLMAC
#define _TCLMAC

#ifndef _TCL
#   include "tcl.h"










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tclMac.h --
 *
 *	Declarations of Macintosh specific public variables and procedures.
 *
 * 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: tclMac.h,v 1.1.2.4 1999/03/10 06:49:24 stanton Exp $
 */

#ifndef _TCLMAC
#define _TCLMAC

#ifndef _TCL
#   include "tcl.h"
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
 * to shared libraries that link with this library.
 */
 
#pragma export on

typedef int (*Tcl_MacConvertEventPtr) _ANSI_ARGS_((EventRecord *eventPtr));

/*
 * This is needed by the shells to handle Macintosh events.
 */
 
EXTERN void  Tcl_MacSetEventProc _ANSI_ARGS_((Tcl_MacConvertEventPtr procPtr));

/*
 * These routines are useful for handling using scripts from resources 
 * in the application shell
 */
 
EXTERN char *	Tcl_MacConvertTextResource _ANSI_ARGS_((Handle resource));
EXTERN int 	Tcl_MacEvalResource _ANSI_ARGS_((Tcl_Interp *interp,
		    char *resourceName, int resourceNumber, char *fileName));
EXTERN Handle	Tcl_MacFindResource _ANSI_ARGS_((Tcl_Interp *interp,
		    long resourceType, char *resourceName,
		    int resourceNumber, char *resFileRef, int * releaseIt));

/* These routines support the new OSType object type (i.e. the packed 4
 * character type and creator codes).
 */
 								  
EXTERN int		Tcl_GetOSTypeFromObj _ANSI_ARGS_((Tcl_Interp *interp,
			    Tcl_Obj *objPtr, OSType *osTypePtr));
EXTERN void		Tcl_SetOSTypeObj _ANSI_ARGS_((Tcl_Obj *objPtr, 
			    OSType osType));
EXTERN Tcl_Obj *	Tcl_NewOSTypeObj _ANSI_ARGS_((OSType osType));



/*
 * The following routines are utility functions in Tcl.  They are exported
 * here because they are needed in Tk.  They are not officially supported,
 * however.  The first set are from the MoreFiles package.
 */

EXTERN pascal	OSErr	FSpGetDirectoryID(const FSSpec *spec,
			    long *theDirID, Boolean *isDirectory);
EXTERN pascal	short	FSpOpenResFileCompat(const FSSpec *spec,
			    SignedByte permission);
EXTERN pascal	void	FSpCreateResFileCompat(const FSSpec *spec,
			    OSType creator, OSType fileType,
			    ScriptCode scriptTag);
/* 
 * Like the MoreFiles routines these fix problems in the standard
 * Mac calls.  These routines is from tclMacUtils.h.
 */

EXTERN int 	FSpLocationFromPath _ANSI_ARGS_((int length, char *path,
		    FSSpecPtr theSpec));
EXTERN OSErr 	FSpPathFromLocation _ANSI_ARGS_((FSSpecPtr theSpec,
		    int *length, Handle *fullPath));

/*
 * These are not in MSL 2.1.2, so we need to export them from the
 * Tcl shared library.  They are found in the compat directory
 * except the panic routine which is found in tclMacPanic.h.
 */
 
EXTERN int	strncasecmp _ANSI_ARGS_((CONST char *s1,
			    CONST char *s2, size_t n));
EXTERN int	strcasecmp _ANSI_ARGS_((CONST char *s1,
			    CONST char *s2));
EXTERN void	panic _ANSI_ARGS_(TCL_VARARGS(char *,format));

#pragma export reset

#endif /* _TCLMAC */







<
<
<
|
<

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



27
28
29
30
31
32
33



34

35



























































36
37
38
 * to shared libraries that link with this library.
 */
 
#pragma export on

typedef int (*Tcl_MacConvertEventPtr) _ANSI_ARGS_((EventRecord *eventPtr));




#include "tclPlatDecls.h"





























































#pragma export reset

#endif /* _TCLMAC */

Changes to mac/tclMacAETE.r.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *      Tk Shells.
 *
 * 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.
 *
 * SCCS: @(#) tclMacAETE.r 1.1 97/11/03 17:06:22
 */

#define SystemSevenOrLater 1

#include <Types.r>
#include <SysTypes.r>
#include <AEUserTermTypes.r>







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *      Tk Shells.
 *
 * 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: tclMacAETE.r,v 1.1.2.1 1998/09/24 23:59:09 stanton Exp $
 */

#define SystemSevenOrLater 1

#include <Types.r>
#include <SysTypes.r>
#include <AEUserTermTypes.r>

Changes to mac/tclMacAlloc.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson
 *.
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacAlloc.c 1.13 97/07/24 14:42:19
 */

#include "tclMacInt.h"
#include "tclInt.h"
#include <Memory.h>
#include <stdlib.h>
#include <string.h>


/*
 * Flags that are used by ConfigureMemory to define how the allocator
 * should work.  They can be or'd together.
 */
#define MEMORY_ALL_SYS 1	/* All memory should come from the system
heap. */







|







>







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) 1996-1997 Sun Microsystems, Inc.
 *
 * Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson
 *.
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclMacAlloc.c,v 1.1.2.3 1999/03/10 06:49:24 stanton Exp $
 */

#include "tclMacInt.h"
#include "tclInt.h"
#include <Memory.h>
#include <stdlib.h>
#include <string.h>


/*
 * Flags that are used by ConfigureMemory to define how the allocator
 * should work.  They can be or'd together.
 */
#define MEMORY_ALL_SYS 1	/* All memory should come from the system
heap. */
238
239
240
241
242
243
244

245
246
247
248
249
250
251
    void * ptr)		/* Free this system memory. */
{
    Handle hand;
    OSErr err;

    hand = * (Handle *) ((Ptr) ptr - sizeof(Handle));
    DisposeHandle(hand);

    err = MemError();
}

/*
 *----------------------------------------------------------------------
 *
 * CleanUpExitProc --







>







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
    void * ptr)		/* Free this system memory. */
{
    Handle hand;
    OSErr err;

    hand = * (Handle *) ((Ptr) ptr - sizeof(Handle));
    DisposeHandle(hand);
    *hand = NULL;
    err = MemError();
}

/*
 *----------------------------------------------------------------------
 *
 * CleanUpExitProc --
268
269
270
271
272
273
274

275

276
277
278
279
280
281
282
CleanUpExitProc()
{
    ListEl * memRecord;

    while (systemMemory != NULL) {
	memRecord = systemMemory;
	systemMemory = memRecord->next;

	DisposeHandle(memRecord->memoryHandle);

	DisposePtr((void *) memRecord);
    }
}

/*
 *----------------------------------------------------------------------
 *







>
|
>







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
CleanUpExitProc()
{
    ListEl * memRecord;

    while (systemMemory != NULL) {
	memRecord = systemMemory;
	systemMemory = memRecord->next;
        if (*(memRecord->memoryHandle) != NULL) {
            DisposeHandle(memRecord->memoryHandle);
        }
	DisposePtr((void *) memRecord);
    }
}

/*
 *----------------------------------------------------------------------
 *
299
300
301
302
303
304
305

306

307
308
309
310
311

312

313
314
315
316
317
318
319
FreeAllMemory()
{
    ListEl * memRecord;

    while (systemMemory != NULL) {
	memRecord = systemMemory;
	systemMemory = memRecord->next;

	DisposeHandle(memRecord->memoryHandle);

	DisposePtr((void *) memRecord);
    }
    while (appMemory != NULL) {
	memRecord = appMemory;
	appMemory = memRecord->next;

	DisposeHandle(memRecord->memoryHandle);

	DisposePtr((void *) memRecord);
    }
}

/*
 *----------------------------------------------------------------------
 *







>
|
>





>
|
>







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
FreeAllMemory()
{
    ListEl * memRecord;

    while (systemMemory != NULL) {
	memRecord = systemMemory;
	systemMemory = memRecord->next;
	if (*(memRecord->memoryHandle) != NULL) {
            DisposeHandle(memRecord->memoryHandle);
        }
	DisposePtr((void *) memRecord);
    }
    while (appMemory != NULL) {
	memRecord = appMemory;
	appMemory = memRecord->next;
	if (*(memRecord->memoryHandle) != NULL) {
            DisposeHandle(memRecord->memoryHandle);
        }
	DisposePtr((void *) memRecord);
    }
}

/*
 *----------------------------------------------------------------------
 *

Changes to mac/tclMacAppInit.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
/* 
 * tclMacAppInit.c --
 *
 *	Provides a version of the Tcl_AppInit procedure for the example shell.
 *
 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
 * 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.
 *
 * SCCS: @(#) tclMacAppInit.c 1.20 97/07/28 11:03:58
 */

#include "tcl.h"
#include "tclInt.h"
#include "tclPort.h"
#include "tclMac.h"
#include "tclMacInt.h"

#if defined(THINK_C)
#   include <console.h>
#elif defined(__MWERKS__)
#   include <SIOUX.h>
short InstallConsole _ANSI_ARGS_((short fd));
#endif

#ifdef TCL_TEST


EXTERN int		TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
#endif /* TCL_TEST */

/*
 * Forward declarations for procedures defined later in this file:
 */

static int		MacintoshInit _ANSI_ARGS_((void));











|
















>
>
|
|







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
/* 
 * tclMacAppInit.c --
 *
 *	Provides a version of the Tcl_AppInit procedure for the example shell.
 *
 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
 * 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: tclMacAppInit.c,v 1.1.2.4 1999/02/10 23:31:21 stanton Exp $
 */

#include "tcl.h"
#include "tclInt.h"
#include "tclPort.h"
#include "tclMac.h"
#include "tclMacInt.h"

#if defined(THINK_C)
#   include <console.h>
#elif defined(__MWERKS__)
#   include <SIOUX.h>
short InstallConsole _ANSI_ARGS_((short fd));
#endif

#ifdef TCL_TEST
extern int		Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp));
extern int		Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
extern int		TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp));
extern int		Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
#endif /* TCL_TEST */

/*
 * Forward declarations for procedures defined later in this file:
 */

static int		MacintoshInit _ANSI_ARGS_((void));
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in interp->result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */








|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in the interp's result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */

104
105
106
107
108
109
110





111
112
113
114
115
116
117
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
            (Tcl_PackageInitProc *) NULL);
    if (TclObjTest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }





#endif /* TCL_TEST */

    /*
     * Call the init procedures for included packages.  Each call should
     * look like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {







>
>
>
>
>







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
            (Tcl_PackageInitProc *) NULL);
    if (TclObjTest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    if (Procbodytest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init,
            Procbodytest_SafeInit);
#endif /* TCL_TEST */

    /*
     * Call the init procedures for included packages.  Each call should
     * look like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {

Changes to mac/tclMacApplication.r.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclMacApplication.r --
 *
 *	This file creates resources for use Tcl Shell application.
 *	It should be viewed as an example of how to create a new
 *	Tcl application using the shared Tcl libraries.
 *
 * 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.
 *
 * SCCS: @(#) tclMacApplication.r 1.2 97/06/20 11:27:07
 */

#include <Types.r>
#include <SysTypes.r>

/*
 * The folowing include and defines help construct












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclMacApplication.r --
 *
 *	This file creates resources for use Tcl Shell application.
 *	It should be viewed as an example of how to create a new
 *	Tcl application using the shared Tcl libraries.
 *
 * 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: tclMacApplication.r,v 1.1.2.1 1998/09/24 23:59:10 stanton Exp $
 */

#include <Types.r>
#include <SysTypes.r>

/*
 * The folowing include and defines help construct

Changes to mac/tclMacBOAAppInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclMacBOAAppInit.c --
 *
 *	Provides a version of the Tcl_AppInit procedure for a 
 *      Macintosh Background Only Application.
 *
 * 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.
 *
 * SCCS: @(#) tclMacBOAAppInit.c 1.1 97/11/03 17:06:21
 */

#include "tcl.h"
#include "tclInt.h"
#include "tclPort.h"
#include "tclMac.h"
#include "tclMacInt.h"











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclMacBOAAppInit.c --
 *
 *	Provides a version of the Tcl_AppInit procedure for a 
 *      Macintosh Background Only Application.
 *
 * 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: tclMacBOAAppInit.c,v 1.1.2.2 1998/09/24 23:59:10 stanton Exp $
 */

#include "tcl.h"
#include "tclInt.h"
#include "tclPort.h"
#include "tclMac.h"
#include "tclMacInt.h"
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in interp->result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */








|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in the interp's result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */

Changes to mac/tclMacBOAMain.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclMacBGMain.c --
 *
 *	Main program for Macintosh Background Only Application shells.
 *
 * 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.
 *
 * SCCS: @(#) tclMacBOAMain.c 1.1 97/11/03 17:06:22
 */

#include "tcl.h"
#include "tclInt.h"
#include "tclMacInt.h"
#include <Resources.h>
#include <Notification.h>










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclMacBGMain.c --
 *
 *	Main program for Macintosh Background Only Application shells.
 *
 * 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: tclMacBOAMain.c,v 1.1.2.2 1998/09/24 23:59:10 stanton Exp $
 */

#include "tcl.h"
#include "tclInt.h"
#include "tclMacInt.h"
#include <Resources.h>
#include <Notification.h>
143
144
145
146
147
148
149
150

151
152
153
154
155
156

157
158
159
160
161
162
163
164
	    ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY);
    
    /*
     * Invoke application-specific initialization.
     */

    if ((*appInitProc)(interp) != TCL_OK) {
	    Tcl_DString errStr;

	    Tcl_DStringInit(&errStr);
	    Tcl_DStringAppend(&errStr,
		    "application-specific initialization failed: \n", -1);
	    Tcl_DStringAppend(&errStr, interp->result, -1);
	    Tcl_DStringAppend(&errStr, "\n", 1);
	    TclMacDoNotification(Tcl_DStringValue(&errStr));

	    goto done;
    }

    /*
     * Install the BGNotify command:
     */
    
    if ( Tcl_CreateObjCommand(interp, "bgnotify", Tcl_MacBGNotifyObjCmd, NULL,







|
>
|
|
|
|
|
|
>
|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
	    ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY);
    
    /*
     * Invoke application-specific initialization.
     */

    if ((*appInitProc)(interp) != TCL_OK) {
	Tcl_DString errStr;

	Tcl_DStringInit(&errStr);
	Tcl_DStringAppend(&errStr,
		"application-specific initialization failed: \n", -1);
	Tcl_DStringAppend(&errStr, Tcl_GetStringResult(interp), -1);
	Tcl_DStringAppend(&errStr, "\n", 1);
	TclMacDoNotification(Tcl_DStringValue(&errStr));
	Tcl_DStringFree(&errStr);
	goto done;
    }

    /*
     * Install the BGNotify command:
     */
    
    if ( Tcl_CreateObjCommand(interp, "bgnotify", Tcl_MacBGNotifyObjCmd, NULL,
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
	if (code != TCL_OK) {
            Tcl_DString errStr;
            
            Tcl_DStringInit(&errStr);
            Tcl_DStringAppend(&errStr, " Error sourcing resource or file: ", -1);
            Tcl_DStringAppend(&errStr, fileName, -1);
            Tcl_DStringAppend(&errStr, "\n\nError was: ", -1);
            Tcl_DStringAppend(&errStr, interp->result, -1);
                        
            TclMacDoNotification(Tcl_DStringValue(&errStr));
                        
        }
	goto done;
    }


    /*
     * Rather than calling exit, invoke the "exit" command so that







|
<

|







190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
	if (code != TCL_OK) {
            Tcl_DString errStr;
            
            Tcl_DStringInit(&errStr);
            Tcl_DStringAppend(&errStr, " Error sourcing resource or file: ", -1);
            Tcl_DStringAppend(&errStr, fileName, -1);
            Tcl_DStringAppend(&errStr, "\n\nError was: ", -1);
            Tcl_DStringAppend(&errStr, Tcl_GetStringResult(interp), -1);

            TclMacDoNotification(Tcl_DStringValue(&errStr));
	    Tcl_DStringFree(&errStr);
        }
	goto done;
    }


    /*
     * Rather than calling exit, invoke the "exit" command so that
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
    resultPtr = Tcl_GetObjResult(interp);
    
    if ( objc != 2 ) {
        Tcl_WrongNumArgs(interp, 1, objv, "message");
        return TCL_ERROR;
    }
    
    TclMacDoNotification(Tcl_GetStringFromObj(objv[1], (int *) NULL));
    return TCL_OK;
           
}


/*
 *----------------------------------------------------------------------







|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
    resultPtr = Tcl_GetObjResult(interp);
    
    if ( objc != 2 ) {
        Tcl_WrongNumArgs(interp, 1, objv, "message");
        return TCL_ERROR;
    }
    
    TclMacDoNotification(Tcl_GetString(objv[1]));
    return TCL_OK;
           
}


/*
 *----------------------------------------------------------------------

Changes to mac/tclMacChan.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
/* 
 * tclMacChan.c
 *
 *	Channel drivers for Macintosh channels for the
 *	console fds.
 *
 * 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.
 *
 * SCCS: @(#) tclMacChan.c 1.43 97/06/20 11:27:48
 */

#include "tclInt.h"
#include "tclPort.h"
#include "tclMacInt.h"
#include <Aliases.h>
#include <Errors.h>
#include <Files.h>
#include <Gestalt.h>
#include <Processes.h>
#include <Strings.h>
#include <FSpCompat.h>
#include <MoreFiles.h>
#include <MoreFilesExtras.h>

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

static int initialized = 0;

/*
 * The following are flags returned by GetOpenMode.  They
 * are or'd together to determine how opening and handling
 * a file should occur.
 */












|















<
<
<
<
<
<







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
/* 
 * tclMacChan.c
 *
 *	Channel drivers for Macintosh channels for the
 *	console fds.
 *
 * 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: tclMacChan.c,v 1.1.2.4 1999/04/14 00:34:52 surles Exp $
 */

#include "tclInt.h"
#include "tclPort.h"
#include "tclMacInt.h"
#include <Aliases.h>
#include <Errors.h>
#include <Files.h>
#include <Gestalt.h>
#include <Processes.h>
#include <Strings.h>
#include <FSpCompat.h>
#include <MoreFiles.h>
#include <MoreFilesExtras.h>








/*
 * The following are flags returned by GetOpenMode.  They
 * are or'd together to determine how opening and handling
 * a file should occur.
 */

62
63
64
65
66
67
68
69


70
71
72




73
74
75
76
77
78
79
80
81
    				 * are being watched. */
    int appendMode;		/* Flag to tell if in O_APPEND mode or not. */
    int volumeRef;		/* Flag to tell if in O_APPEND mode or not. */
    int pending;		/* 1 if message is pending on queue. */
    struct FileState *nextPtr;	/* Pointer to next registered file. */
} FileState;

/*


 * The following pointer refers to the head of the list of files managed
 * that are being watched for file events.
 */





static FileState *firstFilePtr;

/*
 * The following structure is what is added to the Tcl event queue when
 * file events are generated.
 */

typedef struct FileEvent {







<
>
>
|
|
<
>
>
>
>

|







56
57
58
59
60
61
62

63
64
65
66

67
68
69
70
71
72
73
74
75
76
77
78
79
    				 * are being watched. */
    int appendMode;		/* Flag to tell if in O_APPEND mode or not. */
    int volumeRef;		/* Flag to tell if in O_APPEND mode or not. */
    int pending;		/* 1 if message is pending on queue. */
    struct FileState *nextPtr;	/* Pointer to next registered file. */
} FileState;


typedef struct ThreadSpecificData {
    int initialized;		/* True after the thread initializes */
    FileState *firstFilePtr;	/* the head of the list of files managed
				 * that are being watched for file events. */

    Tcl_Channel stdinChannel;
    Tcl_Channel stdoutChannel;	/* Note - these seem unused */
    Tcl_Channel stderrChannel;
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * The following structure is what is added to the Tcl event queue when
 * file events are generated.
 */

typedef struct FileEvent {
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
		            ClientData clientData));
static void		FileCheckProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static int		FileClose _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp));
static int		FileEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
			    int flags));
static void		FileInit _ANSI_ARGS_((void));
static int		FileInput _ANSI_ARGS_((ClientData instanceData,
			    char *buf, int toRead, int *errorCode));
static int		FileOutput _ANSI_ARGS_((ClientData instanceData,
			    char *buf, int toWrite, int *errorCode));
static int		FileSeek _ANSI_ARGS_((ClientData instanceData,
			    long offset, int mode, int *errorCode));
static void		FileSetupProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static int		GetOpenMode _ANSI_ARGS_((Tcl_Interp *interp,
        		    char *string));
static Tcl_Channel	OpenFileChannel _ANSI_ARGS_((char *fileName, int mode, 
			    int permissions, int *errorCodePtr));
static int		StdIOBlockMode _ANSI_ARGS_((ClientData instanceData,
			    int mode));
static int		StdIOClose _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp));
static int		StdIOInput _ANSI_ARGS_((ClientData instanceData,
			    char *buf, int toRead, int *errorCode));
static int		StdIOOutput _ANSI_ARGS_((ClientData instanceData,







|









|
|
|







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
		            ClientData clientData));
static void		FileCheckProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static int		FileClose _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp));
static int		FileEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
			    int flags));
static ThreadSpecificData *FileInit _ANSI_ARGS_((void));
static int		FileInput _ANSI_ARGS_((ClientData instanceData,
			    char *buf, int toRead, int *errorCode));
static int		FileOutput _ANSI_ARGS_((ClientData instanceData,
			    char *buf, int toWrite, int *errorCode));
static int		FileSeek _ANSI_ARGS_((ClientData instanceData,
			    long offset, int mode, int *errorCode));
static void		FileSetupProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static int		GetOpenMode _ANSI_ARGS_((Tcl_Interp *interp,
        		    CONST char *string));
static Tcl_Channel	OpenFileChannel _ANSI_ARGS_((CONST char *fileName, 
			    int mode, int permissions, int *errorCodePtr));
static int		StdIOBlockMode _ANSI_ARGS_((ClientData instanceData,
			    int mode));
static int		StdIOClose _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp));
static int		StdIOInput _ANSI_ARGS_((ClientData instanceData,
			    char *buf, int toRead, int *errorCode));
static int		StdIOOutput _ANSI_ARGS_((ClientData instanceData,
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
 */
 
typedef void (*TclGetStdChannelsProc) _ANSI_ARGS_((Tcl_Channel *stdinPtr,
	Tcl_Channel *stdoutPtr, Tcl_Channel *stderrPtr));
	
TclGetStdChannelsProc getStdChannelsProc = NULL;

/*
 * Static variables to hold channels for stdin, stdout and stderr.
 */

static Tcl_Channel stdinChannel = NULL;
static Tcl_Channel stdoutChannel = NULL;
static Tcl_Channel stderrChannel = NULL;

/*
 *----------------------------------------------------------------------
 *
 * FileInit --
 *
 *	This function initializes the file channel event source.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new event source.
 *
 *----------------------------------------------------------------------
 */

static void
FileInit()
{



    initialized = 1;
    firstFilePtr = NULL;
    Tcl_CreateEventSource(FileSetupProc, FileCheckProc, NULL);
    Tcl_CreateExitHandler(FileChannelExitHandler, NULL);


}

/*
 *----------------------------------------------------------------------
 *
 * FileChannelExitHandler --
 *







<
<
<
<
<
<
<

















|


>
>
>
|
|
|
|
>
>







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
 */
 
typedef void (*TclGetStdChannelsProc) _ANSI_ARGS_((Tcl_Channel *stdinPtr,
	Tcl_Channel *stdoutPtr, Tcl_Channel *stderrPtr));
	
TclGetStdChannelsProc getStdChannelsProc = NULL;









/*
 *----------------------------------------------------------------------
 *
 * FileInit --
 *
 *	This function initializes the file channel event source.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new event source.
 *
 *----------------------------------------------------------------------
 */

static ThreadSpecificData *
FileInit()
{
    ThreadSpecificData *tsdPtr =
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
	tsdPtr->firstFilePtr = NULL;
	Tcl_CreateEventSource(FileSetupProc, FileCheckProc, NULL);
	Tcl_CreateThreadExitHandler(FileChannelExitHandler, NULL);
    }
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FileChannelExitHandler --
 *
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
 */

static void
FileChannelExitHandler(
    ClientData clientData)	/* Old window proc */
{
    Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL);
    initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * FileSetupProc --
 *







<







224
225
226
227
228
229
230

231
232
233
234
235
236
237
 */

static void
FileChannelExitHandler(
    ClientData clientData)	/* Old window proc */
{
    Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL);

}

/*
 *----------------------------------------------------------------------
 *
 * FileSetupProc --
 *
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
void
FileSetupProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    FileState *infoPtr;
    Tcl_Time blockTime = { 0, 0 };


    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Check to see if there is a ready file.  If so, poll.
     */


    for (infoPtr = firstFilePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask) {
	    Tcl_SetMaxBlockTime(&blockTime);
	    break;
	}
    }
}








>









>
|







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
void
FileSetupProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    FileState *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 file.  If so, poll.
     */

    for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask) {
	    Tcl_SetMaxBlockTime(&blockTime);
	    break;
	}
    }
}

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
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    FileEvent *evPtr;
    FileState *infoPtr;
    int sentMsg = 0;
    Tcl_Time blockTime = { 0, 0 };


    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Queue events for any ready files that don't already have events
     * queued (caused by persistent states that won't generate WinSock
     * events).
     */


    for (infoPtr = firstFilePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask && !infoPtr->pending) {
	    infoPtr->pending = 1;
	    evPtr = (FileEvent *) ckalloc(sizeof(FileEvent));
	    evPtr->header.proc = FileEventProc;
	    evPtr->infoPtr = infoPtr;
	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
	}







>











>
|







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
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    FileEvent *evPtr;
    FileState *infoPtr;
    int sentMsg = 0;
    Tcl_Time blockTime = { 0, 0 };
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Queue events for any ready files that don't already have events
     * queued (caused by persistent states that won't generate WinSock
     * events).
     */

    for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask && !infoPtr->pending) {
	    infoPtr->pending = 1;
	    evPtr = (FileEvent *) ckalloc(sizeof(FileEvent));
	    evPtr->header.proc = FileEventProc;
	    evPtr->infoPtr = infoPtr;
	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
	}
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
FileEventProc(
    Tcl_Event *evPtr,		/* Event to service. */
    int flags)			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    FileEvent *fileEvPtr = (FileEvent *)evPtr;
    FileState *infoPtr;


    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the list of watched files for the one whose handle
     * matches the event.  We do this rather than simply dereferencing
     * the handle in the event so that files can be deleted while the
     * event is in the queue.
     */


    for (infoPtr = firstFilePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (fileEvPtr->infoPtr == infoPtr) {
	    infoPtr->pending = 0;
	    Tcl_NotifyChannel(infoPtr->fileChan, infoPtr->watchMask);
	    break;
	}
    }
    return 1;







>












>
|







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
FileEventProc(
    Tcl_Event *evPtr,		/* Event to service. */
    int flags)			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    FileEvent *fileEvPtr = (FileEvent *)evPtr;
    FileState *infoPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the list of watched files for the one whose handle
     * matches the event.  We do this rather than simply dereferencing
     * the handle in the event so that files can be deleted while the
     * event is in the queue.
     */

    for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (fileEvPtr->infoPtr == infoPtr) {
	    infoPtr->pending = 0;
	    Tcl_NotifyChannel(infoPtr->fileChan, infoPtr->watchMask);
	    break;
	}
    }
    return 1;
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

static int
StdIOClose(
    ClientData instanceData,	/* Unused. */
    Tcl_Interp *interp)		/* Unused. */
{
    int fd, errorCode = 0;


    /*
     * Invalidate the stdio cache if necessary.  Note that we assume that
     * the stdio file and channel pointers will become invalid at the same
     * time.

     */

    fd = (int) ((FileState*)instanceData)->fileRef;

    if (fd == 0) {
	fd = 0;
	stdinChannel = NULL;
    } else if (fd == 1) {
	stdoutChannel = NULL;
    } else if (fd == 2) {
	stderrChannel = NULL;
    } else {
	panic("recieved invalid std file");
    }

    if (close(fd) < 0) {
	errorCode = errno;
    }

    return errorCode;
}

/*
 *----------------------------------------------------------------------
 *
 * CommonGetHandle --
 *
 *	Called from Tcl_GetChannelFile to retrieve OS handles from inside
 *	a file based channel.
 *
 * Results:
 *	The appropriate handle or NULL if not present. 
 *
 * Side effects:
 *	None.







>





>



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








|







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

static int
StdIOClose(
    ClientData instanceData,	/* Unused. */
    Tcl_Interp *interp)		/* Unused. */
{
    int fd, errorCode = 0;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Invalidate the stdio cache if necessary.  Note that we assume that
     * the stdio file and channel pointers will become invalid at the same
     * time.
     * Do not close standard channels while in thread-exit.
     */

    fd = (int) ((FileState*)instanceData)->fileRef;
    if (!TclInExit()) {
	if (fd == 0) {

	    tsdPtr->stdinChannel = NULL;
	} else if (fd == 1) {
	    tsdPtr->stdoutChannel = NULL;
	} else if (fd == 2) {
	    tsdPtr->stderrChannel = NULL;
	} else {
	    panic("recieved invalid std file");
	}
    
	if (close(fd) < 0) {
	    errorCode = errno;
	}
    }
    return errorCode;
}

/*
 *----------------------------------------------------------------------
 *
 * CommonGetHandle --
 *
 *	Called from Tcl_GetChannelHandle to retrieve OS handles from inside
 *	a file based channel.
 *
 * Results:
 *	The appropriate handle or NULL if not present. 
 *
 * Side effects:
 *	None.
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
    }
    if (objc == 1) {
        resultPtr = Tcl_GetObjResult(interp);
	GetCurrentProcess(&psn);
	sprintf(buf, "0x%08x%08x", psn.highLongOfPSN, psn.lowLongOfPSN);
        Tcl_SetStringObj(resultPtr, buf, -1);
    } else {
        chan = Tcl_GetChannel(interp, Tcl_GetStringFromObj(objv[1], NULL),
                NULL);
        if (chan == (Tcl_Channel) NULL) {
            return TCL_ERROR;
        } 
	/*
	 * We can't create pipelines on the Mac so
	 * this will always return an empty list.
	 */
    }
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetDefaultStdChannel --
 *
 *	Constructs a channel for the specified standard OS handle.
 *
 * Results:
 *	Returns the specified default standard channel, or NULL.
 *
 * Side effects:
 *	May cause the creation of a standard channel and the underlying
 *	file.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclGetDefaultStdChannel(
    int type)			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{
    Tcl_Channel channel = NULL;
    int fd = 0;			/* Initializations needed to prevent */
    int mode = 0;		/* compiler warning (used before set). */
    char *bufMode = NULL;
    char channelName[20];
    int channelPermissions;
    FileState *fileState;

    /*
     * If the channels were not created yet, create them now and
     * store them in the static variables.
     */







|
















|














|






|







641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
    }
    if (objc == 1) {
        resultPtr = Tcl_GetObjResult(interp);
	GetCurrentProcess(&psn);
	sprintf(buf, "0x%08x%08x", psn.highLongOfPSN, psn.lowLongOfPSN);
        Tcl_SetStringObj(resultPtr, buf, -1);
    } else {
        chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]),
                NULL);
        if (chan == (Tcl_Channel) NULL) {
            return TCL_ERROR;
        } 
	/*
	 * We can't create pipelines on the Mac so
	 * this will always return an empty list.
	 */
    }
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpGetDefaultStdChannel --
 *
 *	Constructs a channel for the specified standard OS handle.
 *
 * Results:
 *	Returns the specified default standard channel, or NULL.
 *
 * Side effects:
 *	May cause the creation of a standard channel and the underlying
 *	file.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclpGetDefaultStdChannel(
    int type)			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{
    Tcl_Channel channel = NULL;
    int fd = 0;			/* Initializations needed to prevent */
    int mode = 0;		/* compiler warning (used before set). */
    char *bufMode = NULL;
    char channelName[16 + TCL_INTEGER_SPACE];
    int channelPermissions;
    FileState *fileState;

    /*
     * If the channels were not created yet, create them now and
     * store them in the static variables.
     */
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775

776

777
778
779
780
781
782
783
    
    return channel;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_OpenFileChannel --
 *
 *	Open an File based channel on Unix systems.
 *
 * Results:
 *	The new channel or NULL. If NULL, the output argument
 *	errorCodePtr is set to a POSIX error.
 *
 * Side effects:
 *	May open the channel and may cause creation of a file on the
 *	file system.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_OpenFileChannel(
    Tcl_Interp *interp,			/* Interpreter for error reporting;
                                         * can be NULL. */
    char *fileName,			/* Name of file to open. */
    char *modeString,			/* A list of POSIX open modes or
                                         * a string such as "rw". */
    int permissions)			/* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
{
    Tcl_Channel chan;
    int mode;
    char *nativeName;
    Tcl_DString buffer;
    int errorCode;
    
    mode = GetOpenMode(interp, modeString);
    if (mode == -1) {
	return NULL;
    }

    nativeName = Tcl_TranslateFileName(interp, fileName, &buffer);
    if (nativeName == NULL) {
	return NULL;
    }


    chan = OpenFileChannel(nativeName, mode, permissions, &errorCode);

    Tcl_DStringFree(&buffer);

    if (chan == NULL) {
	Tcl_SetErrno(errorCode);
	if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "couldn't open \"", fileName, "\": ",
                    Tcl_PosixError(interp), (char *) NULL);







|















|











|
|







|
<


|
>
|
>







730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774

775
776
777
778
779
780
781
782
783
784
785
786
787
    
    return channel;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpOpenFileChannel --
 *
 *	Open an File based channel on Unix systems.
 *
 * Results:
 *	The new channel or NULL. If NULL, the output argument
 *	errorCodePtr is set to a POSIX error.
 *
 * Side effects:
 *	May open the channel and may cause creation of a file on the
 *	file system.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclpOpenFileChannel(
    Tcl_Interp *interp,			/* Interpreter for error reporting;
                                         * can be NULL. */
    char *fileName,			/* Name of file to open. */
    char *modeString,			/* A list of POSIX open modes or
                                         * a string such as "rw". */
    int permissions)			/* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
{
    Tcl_Channel chan;
    int mode;
    char *native;
    Tcl_DString ds, buffer;
    int errorCode;
    
    mode = GetOpenMode(interp, modeString);
    if (mode == -1) {
	return NULL;
    }

    if (Tcl_TranslateFileName(interp, fileName, &buffer) == NULL) {

	return NULL;
    }
    native = Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&buffer), 
    	    Tcl_DStringLength(&buffer), &ds);
    chan = OpenFileChannel(native, mode, permissions, &errorCode);
    Tcl_DStringFree(&ds);
    Tcl_DStringFree(&buffer);

    if (chan == NULL) {
	Tcl_SetErrno(errorCode);
	if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "couldn't open \"", fileName, "\": ",
                    Tcl_PosixError(interp), (char *) NULL);
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
 *	Will open a Macintosh file.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Channel
OpenFileChannel(
    char *fileName,			/* Name of file to open. */
    int mode,				/* Mode for opening file. */
    int permissions,			/* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
    int *errorCodePtr)			/* Where to store error code. */
{
    int channelPermissions;
    Tcl_Channel chan;
    char macPermision;
    FSSpec fileSpec;
    OSErr err;
    short fileRef;
    FileState *fileState;
    char channelName[64];
    
    /*
     * Note we use fsRdWrShPerm instead of fsRdWrPerm which allows shared
     * writes on a file.  This isn't common on a mac but is common with 
     * Windows and UNIX and the feature is used by Tcl.
     */








|













|







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
 *	Will open a Macintosh file.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Channel
OpenFileChannel(
    CONST char *fileName,		/* Name of file to open (native). */
    int mode,				/* Mode for opening file. */
    int permissions,			/* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
    int *errorCodePtr)			/* Where to store error code. */
{
    int channelPermissions;
    Tcl_Channel chan;
    char macPermision;
    FSSpec fileSpec;
    OSErr err;
    short fileRef;
    FileState *fileState;
    char channelName[16 + TCL_INTEGER_SPACE];
    
    /*
     * Note we use fsRdWrShPerm instead of fsRdWrPerm which allows shared
     * writes on a file.  This isn't common on a mac but is common with 
     * Windows and UNIX and the feature is used by Tcl.
     */

913
914
915
916
917
918
919





























920
921
922
923
924
925
926
            ckfree((char *) fileState);
            return NULL;
        }
    }
    
    return chan;
}






























/*
 *----------------------------------------------------------------------
 *
 * FileBlockMode --
 *
 *	Set blocking or non-blocking mode on channel.  Macintosh files







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







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
            ckfree((char *) fileState);
            return NULL;
        }
    }
    
    return chan;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_MakeFileChannel --
 *
 *	Makes a Tcl_Channel from an existing OS level file handle.
 *
 * Results:
 *	The Tcl_Channel created around the preexisting OS level file handle.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_MakeFileChannel(handle, mode)
    ClientData handle;		/* OS level handle. */
    int mode;			/* ORed combination of TCL_READABLE and
                                 * TCL_WRITABLE to indicate file mode. */
{
    /*
     * Not implemented yet.
     */

    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * FileBlockMode --
 *
 *	Set blocking or non-blocking mode on channel.  Macintosh files
1186
1187
1188
1189
1190
1191
1192

1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
    int mask)				/* Events of interest; an OR-ed
                                         * combination of TCL_READABLE,
                                         * TCL_WRITABLE and TCL_EXCEPTION. */
{
    FileState **nextPtrPtr, *ptr;
    FileState *infoPtr = (FileState *) instanceData;
    int oldMask = infoPtr->watchMask;


    if (!initialized) {
	FileInit();
    }

    infoPtr->watchMask = mask;
    if (infoPtr->watchMask) {
	if (!oldMask) {
	    infoPtr->nextPtr = firstFilePtr;
	    firstFilePtr = infoPtr;
	}
    } else {
	if (oldMask) {
	    /*
	     * Remove the file from the list of watched files.
	     */

	    for (nextPtrPtr = &firstFilePtr, ptr = *nextPtrPtr;
		 ptr != NULL;
		 nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
		if (infoPtr == ptr) {
		    *nextPtrPtr = ptr->nextPtr;
		    break;
		}
	    }







>

<
|
<




|
|







|







1219
1220
1221
1222
1223
1224
1225
1226
1227

1228

1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
    int mask)				/* Events of interest; an OR-ed
                                         * combination of TCL_READABLE,
                                         * TCL_WRITABLE and TCL_EXCEPTION. */
{
    FileState **nextPtrPtr, *ptr;
    FileState *infoPtr = (FileState *) instanceData;
    int oldMask = infoPtr->watchMask;
    ThreadSpecificData *tsdPtr;


    tsdPtr = FileInit();


    infoPtr->watchMask = mask;
    if (infoPtr->watchMask) {
	if (!oldMask) {
	    infoPtr->nextPtr = tsdPtr->firstFilePtr;
	    tsdPtr->firstFilePtr = infoPtr;
	}
    } else {
	if (oldMask) {
	    /*
	     * Remove the file from the list of watched files.
	     */

	    for (nextPtrPtr = &(tsdPtr->firstFilePtr), ptr = *nextPtrPtr;
		 ptr != NULL;
		 nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
		if (infoPtr == ptr) {
		    *nextPtrPtr = ptr->nextPtr;
		    break;
		}
	    }
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
 * Description:
 *	Computes a POSIX mode mask from a given string and also sets
 *	a flag to indicate whether the caller should seek to EOF during
 *	opening of the file.
 *
 * Results:
 *	On success, returns mode to pass to "open". If an error occurs, the
 *	returns -1 and if interp is not NULL, sets interp->result to an
 *	error message.
 *
 * Side effects:
 *	Sets the integer referenced by seekFlagPtr to 1 if the caller
 *	should seek to EOF during opening the file.
 *
 * Special note:
 *	This code is based on a prototype implementation contributed
 *	by Mark Diekhans.
 *
 *----------------------------------------------------------------------
 */

static int
GetOpenMode(
    Tcl_Interp *interp,			/* Interpreter to use for error
					 * reporting - may be NULL. */
    char *string)			/* Mode string, e.g. "r+" or
					 * "RDONLY CREAT". */
{
    int mode, modeArgc, c, i, gotRW;
    char **modeArgv, *flag;

    /*
     * Check for the simpler fopen-like access modes (e.g. "r").  They
     * are distinguished from the POSIX access modes by the presence
     * of a lower-case first letter.
     */

    mode = 0;






    if (islower(UCHAR(string[0]))) {
	switch (string[0]) {
	    case 'r':
		mode = TCL_RDONLY;
		break;
	    case 'w':
		mode = TCL_WRONLY|TCL_CREAT|TCL_TRUNC;
		break;







|

















|












>
>
>
>
>
>
|







1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
 * Description:
 *	Computes a POSIX mode mask from a given string and also sets
 *	a flag to indicate whether the caller should seek to EOF during
 *	opening of the file.
 *
 * Results:
 *	On success, returns mode to pass to "open". If an error occurs, the
 *	returns -1 and if interp is not NULL, sets the interp's result to an
 *	error message.
 *
 * Side effects:
 *	Sets the integer referenced by seekFlagPtr to 1 if the caller
 *	should seek to EOF during opening the file.
 *
 * Special note:
 *	This code is based on a prototype implementation contributed
 *	by Mark Diekhans.
 *
 *----------------------------------------------------------------------
 */

static int
GetOpenMode(
    Tcl_Interp *interp,			/* Interpreter to use for error
					 * reporting - may be NULL. */
    CONST char *string)			/* Mode string, e.g. "r+" or
					 * "RDONLY CREAT". */
{
    int mode, modeArgc, c, i, gotRW;
    char **modeArgv, *flag;

    /*
     * Check for the simpler fopen-like access modes (e.g. "r").  They
     * are distinguished from the POSIX access modes by the presence
     * of a lower-case first letter.
     */

    mode = 0;
    /*
     * Guard against international characters before using byte oriented
     * routines.
     */

    if (!(string[0] & 0x80)
	    && islower(UCHAR(string[0]))) { /* INTL: ISO only. */
	switch (string[0]) {
	    case 'r':
		mode = TCL_RDONLY;
		break;
	    case 'w':
		mode = TCL_WRONLY|TCL_CREAT|TCL_TRUNC;
		break;

Changes to mac/tclMacDNR.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
 *	and then includes the dnr.c file.
 *
 * 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.
 *
 * SCCS: @(#) tclMacDNR.c 1.2 97/01/28 10:37:21
 */

#pragma ANSI_strict off
#include <dnr.c>
#pragma ANSI_strict reset







|





11
12
13
14
15
16
17
18
19
20
21
22
23
 *	and then includes the dnr.c file.
 *
 * 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: tclMacDNR.c,v 1.1.2.1 1998/09/24 23:59:10 stanton Exp $
 */

#pragma ANSI_strict off
#include <dnr.c>
#pragma ANSI_strict reset

Changes to mac/tclMacEnv.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclMacEnv.c --
 *
 *	Implements the "environment" on a Macintosh.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacEnv.c 1.29 96/12/06 14:19:57
 */

#include <Gestalt.h>
#include <Folders.h>
#include <TextUtils.h>
#include <Resources.h>
#include <string.h>










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclMacEnv.c --
 *
 *	Implements the "environment" on a Macintosh.
 *
 * Copyright (c) 1995-1996 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: tclMacEnv.c,v 1.1.2.1 1998/09/24 23:59:10 stanton Exp $
 */

#include <Gestalt.h>
#include <Folders.h>
#include <TextUtils.h>
#include <Resources.h>
#include <string.h>

Changes to mac/tclMacExit.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * Copyright (c) 1995 Dave Nebinger.
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacExit.c 1.6 97/11/20 18:37:38
 */

#include "tclInt.h"
#include "tclMacInt.h"
#include <SegLoad.h>
#include <Traps.h>
#include <Processes.h>







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * Copyright (c) 1995 Dave Nebinger.
 * Copyright (c) 1995-1996 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: tclMacExit.c,v 1.1.2.3 1998/12/02 20:08:07 welch Exp $
 */

#include "tclInt.h"
#include "tclMacInt.h"
#include <SegLoad.h>
#include <Traps.h>
#include <Processes.h>
100
101
102
103
104
105
106
107
108
109
110














111


112
113
114
115
116
117
118
 * Side effects:
 *	We exit the process.
 *
 *----------------------------------------------------------------------
 */

void
TclPlatformExit(
    int status)		/* Ignored. */
{
    TclMacExitHandler();














    ExitToShell();


}

/*
 *----------------------------------------------------------------------
 *
 * TclMacExitHandler --
 *







|



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

>
>







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
 * Side effects:
 *	We exit the process.
 *
 *----------------------------------------------------------------------
 */

void
TclpExit(
    int status)		/* Ignored. */
{
    TclMacExitHandler();

/* 
 * If we are using the Metrowerks Standard Library, then we will call its exit so that it
 * will get a chance to clean up temp files, and so forth.  It always calls the standard 
 * ExitToShell, so the Tcl handlers will also get called.
 *   
 * If you have another exit, make sure that it does not patch ExitToShell, and does
 * call it.  If so, it will probably work as well.
 *
 */
 
#ifdef __MSL__    
    exit(status);
#else
    ExitToShell();
#endif

}

/*
 *----------------------------------------------------------------------
 *
 * TclMacExitHandler --
 *

Changes to mac/tclMacFCmd.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclMacFCmd.c --
 *
 * Implements the Macintosh specific portions of the file manipulation
 * subcommands of the "file" command.
 *
 * 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.
 *
 * SCCS: @(#) tclMacFCmd.c 1.22 97/05/20 15:44:26
 */

#include "tclInt.h"
#include "tclMac.h"
#include "tclMacInt.h"
#include "tclPort.h"
#include <FSpCompat.h>






|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclMacFCmd.c --
 *
 * Implements the Macintosh specific portions of the file manipulation
 * subcommands of the "file" command.
 *
 * Copyright (c) 1996-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: tclMacFCmd.c,v 1.1.2.2 1998/09/24 23:59:11 stanton Exp $
 */

#include "tclInt.h"
#include "tclMac.h"
#include "tclMacInt.h"
#include "tclPort.h"
#include <FSpCompat.h>
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <Finder.h>

/*
 * Callback for the file attributes code.
 */

static int		GetFileFinderAttributes _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		GetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj **readOnlyPtrPtr));
static int		SetFileFinderAttributes _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj *attributePtr));
static int		SetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj *readOnlyPtr));

/*
 * These are indeces into the tclpFileAttrsStrings table below.
 */

#define MAC_CREATOR_ATTRIBUTE	0







|


|


|


|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <Finder.h>

/*
 * Callback for the file attributes code.
 */

static int		GetFileFinderAttributes _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		GetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj **readOnlyPtrPtr));
static int		SetFileFinderAttributes _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj *attributePtr));
static int		SetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj *readOnlyPtr));

/*
 * These are indeces into the tclpFileAttrsStrings table below.
 */

#define MAC_CREATOR_ATTRIBUTE	0
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
 */

static pascal Boolean 	CopyErrHandler _ANSI_ARGS_((OSErr error, 
			    short failedOperation,
			    short srcVRefNum, long srcDirID,
			    StringPtr srcName, short dstVRefNum,
			    long dstDirID,StringPtr dstName));










OSErr			FSpGetFLockCompat _ANSI_ARGS_((const FSSpec *specPtr, 
			    Boolean *lockedPtr));
static OSErr		GenerateUniqueName _ANSI_ARGS_((short vRefNum, 
			    long dirID1, long dirID2, Str31 uniqueName));
static OSErr		GetFileSpecs _ANSI_ARGS_((char *path, FSSpec *pathSpecPtr,

			    FSSpec *dirSpecPtr,	Boolean *pathExistsPtr,	
			    Boolean *pathIsDirectoryPtr));
static OSErr		MoveRename _ANSI_ARGS_((const FSSpec *srcSpecPtr, 
			    const FSSpec *dstSpecPtr, StringPtr copyName));
static int		Pstrequal _ANSI_ARGS_((ConstStr255Param stringA, 
			    ConstStr255Param stringB));
                 
/*
 *---------------------------------------------------------------------------
 *
 * TclpRenameFile --
 *
 *      Changes the name of an existing file or directory, from src to dst.
 *	If src and dst refer to the same file or directory, does nothing
 *	and returns success.  Otherwise if dst already exists, it will be
 *	deleted and replaced by src subject to the following conditions:
 *	    If src is a directory, dst may be an empty directory.
 *	    If src is a file, dst may be a file.







>
>
>
>
>
>
>
>
>
>




|
>
|









|







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

static pascal Boolean 	CopyErrHandler _ANSI_ARGS_((OSErr error, 
			    short failedOperation,
			    short srcVRefNum, long srcDirID,
			    StringPtr srcName, short dstVRefNum,
			    long dstDirID,StringPtr dstName));
static int		DoCopyDirectory _ANSI_ARGS_((CONST char *src,
			    CONST char *dst, Tcl_DString *errorPtr));
static int		DoCopyFile _ANSI_ARGS_((CONST char *src, 
			    CONST char *dst));
static int		DoCreateDirectory _ANSI_ARGS_((CONST char *path));
static int		DoDeleteFile _ANSI_ARGS_((CONST char *path));
static int		DoRemoveDirectory _ANSI_ARGS_((CONST char *path, 
			    int recursive, Tcl_DString *errorPtr));
static int		DoRenameFile _ANSI_ARGS_((CONST char *src,
			    CONST char *dst));
OSErr			FSpGetFLockCompat _ANSI_ARGS_((const FSSpec *specPtr, 
			    Boolean *lockedPtr));
static OSErr		GenerateUniqueName _ANSI_ARGS_((short vRefNum, 
			    long dirID1, long dirID2, Str31 uniqueName));
static OSErr		GetFileSpecs _ANSI_ARGS_((CONST char *path, 
			    FSSpec *pathSpecPtr, FSSpec *dirSpecPtr,	
			    Boolean *pathExistsPtr, 
			    Boolean *pathIsDirectoryPtr));
static OSErr		MoveRename _ANSI_ARGS_((const FSSpec *srcSpecPtr, 
			    const FSSpec *dstSpecPtr, StringPtr copyName));
static int		Pstrequal _ANSI_ARGS_((ConstStr255Param stringA, 
			    ConstStr255Param stringB));
                 
/*
 *---------------------------------------------------------------------------
 *
 * TclpRenameFile, DoRenameFile --
 *
 *      Changes the name of an existing file or directory, from src to dst.
 *	If src and dst refer to the same file or directory, does nothing
 *	and returns success.  Otherwise if dst already exists, it will be
 *	deleted and replaced by src subject to the following conditions:
 *	    If src is a directory, dst may be an empty directory.
 *	    If src is a file, dst may be a file.
119
120
121
122
123
124
125
126






127















128
129
130
131
132
133
134
 *	delete if errno is EXDEV.
 *
 *---------------------------------------------------------------------------
 */

int
TclpRenameFile( 
    char *src,    		/* Pathname of file or dir to be renamed. */






    char *dst)     		/* New pathname for file or directory. */















{
    FSSpec srcFileSpec, dstFileSpec, dstDirSpec;
    OSErr err; 
    long srcID, dummy;
    Boolean srcIsDirectory, dstIsDirectory, dstExists, dstLocked;

    err = FSpLocationFromPath(strlen(src), src, &srcFileSpec);







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







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
 *	delete if errno is EXDEV.
 *
 *---------------------------------------------------------------------------
 */

int
TclpRenameFile( 
    CONST char *src,		/* Pathname of file or dir to be renamed
				 * (UTF-8). */
    CONST char *dst)		/* New pathname of file or directory
				 * (UTF-8). */
{
    int result;
    Tcl_DString srcString, dstString;

    Tcl_UtfToExternalDString(NULL, src, -1, &srcString);
    Tcl_UtfToExternalDString(NULL, dst, -1, &dstString);
    result = DoRenameFile(Tcl_DStringValue(&srcString),
	    Tcl_DStringValue(&dstString));
    Tcl_DStringFree(&srcString);
    Tcl_DStringFree(&dstString);
    return result;
}

static int
DoRenameFile(
    CONST char *src,		/* Pathname of file or dir to be renamed
				 * (native). */
    CONST char *dst)		/* New pathname of file or directory
				 * (native). */
{
    FSSpec srcFileSpec, dstFileSpec, dstDirSpec;
    OSErr err; 
    long srcID, dummy;
    Boolean srcIsDirectory, dstIsDirectory, dstExists, dstLocked;

    err = FSpLocationFromPath(strlen(src), src, &srcFileSpec);
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
        if (srcIsDirectory) {
	    if (dstIsDirectory) {
		/*
		 * The following call will remove an empty directory.  If it
		 * fails, it's because it wasn't empty.
		 */
		 
                if (TclpRemoveDirectory(dst, 0, NULL) != TCL_OK) {
                    return TCL_ERROR;
                }
                
                /*
		 * Now that that empty directory is gone, we can try
		 * renaming src.  If that fails, we'll put this empty
		 * directory back, for completeness.







|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
        if (srcIsDirectory) {
	    if (dstIsDirectory) {
		/*
		 * The following call will remove an empty directory.  If it
		 * fails, it's because it wasn't empty.
		 */
		 
                if (DoRemoveDirectory(dst, 0, NULL) != TCL_OK) {
                    return TCL_ERROR;
                }
                
                /*
		 * Now that that empty directory is gone, we can try
		 * renaming src.  If that fails, we'll put this empty
		 * directory back, for completeness.
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
    }    

    end:    
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpCopyFile --
 *
 *      Copy a single file (not a directory).  If dst already exists and
 *	is not a directory, it is removed.
 *
 * Results:
 *	If the file was successfully copied, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the
 *	error.  Some possible values for errno are:
 *
 *	EACCES:     src or dst parent directory can't be read and/or written.
 *	EISDIR:	    src or dst is a directory.
 *	ENOENT:	    src doesn't exist.  src or dst is "".
 *
 * Side effects:
 *      This procedure will also copy symbolic links, block, and
 *      character devices, and fifos.  For symbolic links, the links 
 *      themselves will be copied and not what they point to.  For the
 *	other special file types, the directory entry will be copied and
 *	not the contents of the device that it refers to.
 *
 *---------------------------------------------------------------------------
 */
 
int 
TclpCopyFile(
    char *src,			/* Pathname of file to be copied. */
    char *dst)			/* Pathname of file to copy to. */
{
    OSErr err, dstErr;
    Boolean dstExists, dstIsDirectory, dstLocked;
    FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpFileSpec;
    Str31 tmpName;
	
    err = FSpLocationFromPath(strlen(src), src, &srcFileSpec);
    if (err == noErr) {
        err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists,
        	&dstIsDirectory);
    }
    if (dstExists) {
        if (dstIsDirectory) {
            errno = EISDIR;
            return TCL_ERROR;
        }
        err = FSpGetFLockCompat(&dstFileSpec, &dstLocked);
        if (dstLocked) {
            FSpRstFLockCompat(&dstFileSpec);
        }
        
        /*
         * Backup dest file.
         */
         
        dstErr = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, 
    	        dstFileSpec.parID, tmpName);
        if (dstErr == noErr) {
            dstErr = FSpRenameCompat(&dstFileSpec, tmpName);
        }   
    }
    if (err == noErr) {
    	err = FSpFileCopy(&srcFileSpec, &dstDirSpec, 
    		(StringPtr) dstFileSpec.name, NULL, 0, true);
    }
    if ((dstExists != false) && (dstErr == noErr)) {
        FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID,
        	tmpName, &tmpFileSpec);
	if (err == noErr) {
	    /* 
	     * Delete backup file. 
	     */
	     
	    FSpDeleteCompat(&tmpFileSpec);
	} else {
	
	    /* 
	     * Restore backup file.
	     */
	     
	    FSpDeleteCompat(&dstFileSpec);
	    FSpRenameCompat(&tmpFileSpec, dstFileSpec.name);
	    if (dstLocked) {
	        FSpSetFLockCompat(&dstFileSpec);
	    }
	}
    }
    
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpDeleteFile --
 *
 *      Removes a single file (not a directory).
 *
 * Results:
 *	If the file was successfully deleted, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the
 *	error.  Some possible values for errno are:
 *
 *	EACCES:     a parent directory can't be read and/or written.
 *	EISDIR:	    path is a directory.
 *	ENOENT:	    path doesn't exist or is "".
 *
 * Side effects:
 *      The file is deleted, even if it is read-only.
 *
 *---------------------------------------------------------------------------
 */

int
TclpDeleteFile( 
    char *path)			/* Pathname of file to be removed. */
{
    OSErr err;
    FSSpec fileSpec;
    Boolean isDirectory;
    long dirID;
	
    err = FSpLocationFromPath(strlen(path), path, &fileSpec);
    if (err == noErr) {
	/*
     	 * Since FSpDeleteCompat will delete an empty directory, make sure
     	 * that this isn't a directory first.
         */
        
        FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
	if (isDirectory == true) {
            errno = EISDIR;
            return TCL_ERROR;
        }
    }
    err = FSpDeleteCompat(&fileSpec);
    if (err == fLckdErr) {
    	FSpRstFLockCompat(&fileSpec);
    	err = FSpDeleteCompat(&fileSpec);
    	if (err != noErr) {
    	    FSpSetFLockCompat(&fileSpec);
    	}
    }
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpCreateDirectory --
 *
 *      Creates the specified directory.  All parent directories of the
 *	specified directory must already exist.  The directory is
 *	automatically created with permissions so that user can access
 *	the new directory and create new files or subdirectories in it.
 *
 * Results:
 *	If the directory was successfully created, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR and errno is set to
 *	indicate the error.  Some possible values for errno are:
 *
 *	EACCES:     a parent directory can't be read and/or written.
 *	EEXIST:	    path already exists.
 *	ENOENT:	    a parent directory doesn't exist.
 *
 * Side effects:
 *      A directory is created with the current umask, except that
 *	permission for u+rwx will always be added.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCreateDirectory(
    char *path)			/* Pathname of directory to create. */
{
    OSErr err;
    FSSpec dirSpec;
    long outDirID;
	
    err = FSpLocationFromPath(strlen(path), path, &dirSpec);
    if (err == noErr) {
        err = dupFNErr;		/* EEXIST. */
    } else if (err == fnfErr) {
        err = FSpDirCreateCompat(&dirSpec, smSystemScript, &outDirID);
    } 
    
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpCopyDirectory --
 *
 *      Recursively copies a directory.  The target directory dst must
 *	not already exist.  Note that this function does not merge two
 *	directory hierarchies, even if the target directory is an an
 *	empty directory.
 *
 * Results:
 *	If the directory was successfully copied, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR, errno is set to indicate
 *	the error, and the pathname of the file that caused the error
 *	is stored in errorPtr.  See TclpCreateDirectory and TclpCopyFile
 *	for a description of possible values for errno.
 *
 * Side effects:
 *      An exact copy of the directory hierarchy src will be created
 *	with the name dst.  If an error occurs, the error will
 *      be returned immediately, and remaining files will not be
 *	processed.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCopyDirectory(
    char *src,			/* Pathname of directory to be copied.  */
    char *dst,			/* Pathname of target directory. */
    Tcl_DString *errorPtr)	/* If non-NULL, initialized DString for
				 * error reporting. */
{
    OSErr err, saveErr;
    long srcID, tmpDirID;
    FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpDirSpec, tmpFileSpec;
    Boolean srcIsDirectory, srcLocked;
    Boolean dstIsDirectory, dstExists;
    Str31 tmpName;

    err = FSpLocationFromPath(strlen(src), src, &srcFileSpec);
    if (err == noErr) {
    	err = FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory);
    }
    if (err == noErr) {
        if (srcIsDirectory == false) {
            err = afpObjectTypeErr;	/* ENOTDIR. */
        }
    }
    if (err == noErr) {
        err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists,
        	&dstIsDirectory);
    }
    if (dstExists) {
        if (dstIsDirectory == false) {
            err = afpObjectTypeErr;	/* ENOTDIR. */
        } else {
            err = dupFNErr;		/* EEXIST. */
        }
    }
    if (err != noErr) {
        goto done;
    }        
    if ((srcFileSpec.vRefNum == dstFileSpec.vRefNum) &&
    	    (srcFileSpec.parID == dstFileSpec.parID) &&
            (Pstrequal(srcFileSpec.name, dstFileSpec.name) != 0)) {
        /*
         * Copying on top of self.  No-op.
         */
                    
        goto done;
    }

    /*
     * This algorthm will work making a copy of the source directory in
     * the current directory with a new name, in a new directory with the
     * same name, and in a new directory with a new name:
     *
     * 1. Make dstDir/tmpDir.
     * 2. Copy srcDir/src to dstDir/tmpDir/src
     * 3. Rename dstDir/tmpDir/src to dstDir/tmpDir/dst (if necessary).
     * 4. CatMove dstDir/tmpDir/dst to dstDir/dst.
     * 5. Remove dstDir/tmpDir.
     */
                
    err = FSpGetFLockCompat(&srcFileSpec, &srcLocked);
    if (srcLocked) {
        FSpRstFLockCompat(&srcFileSpec);
    }
    if (err == noErr) {
        err = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, 
    	        dstFileSpec.parID, tmpName);
    }
    if (err == noErr) {
        FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID,
        	tmpName, &tmpDirSpec);
        err = FSpDirCreateCompat(&tmpDirSpec, smSystemScript, &tmpDirID);
    }
    if (err == noErr) {
	err = FSpDirectoryCopy(&srcFileSpec, &tmpDirSpec, NULL, 0, true,
	    	CopyErrHandler);
    }
    
    /* 
     * Even if the Copy failed, Rename/Move whatever did get copied to the
     * appropriate final destination, if possible.  
     */
     
    saveErr = err;
    err = noErr;
    if (Pstrequal(srcFileSpec.name, dstFileSpec.name) == 0) {
        err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID, 
        	srcFileSpec.name, &tmpFileSpec);
        if (err == noErr) {
            err = FSpRenameCompat(&tmpFileSpec, dstFileSpec.name);
        }
    }
    if (err == noErr) {
        err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID,
        	dstFileSpec.name, &tmpFileSpec);
    }
    if (err == noErr) {
        err = FSpCatMoveCompat(&tmpFileSpec, &dstDirSpec);
    }
    if (err == noErr) {
        if (srcLocked) {
            FSpSetFLockCompat(&dstFileSpec);
        }
    }
    
    FSpDeleteCompat(&tmpDirSpec);
    
    if (saveErr != noErr) {
        err = saveErr;
    }
    
    done:
    if (err != noErr) {
        errno = TclMacOSErrorToPosixError(err);
        if (errorPtr != NULL) {
            Tcl_DStringAppend(errorPtr, dst, -1);
        }
        return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CopyErrHandler --
 *
 *      This procedure is called from the MoreFiles procedure 
 *      FSpDirectoryCopy whenever an error occurs.
 *
 * Results:
 *      False if the condition should not be considered an error, true
 *      otherwise.
 *
 * Side effects:
 *      Since FSpDirectoryCopy() is called only after removing any 
 *      existing target directories, there shouldn't be any errors.
 *      
 *----------------------------------------------------------------------
 */

static pascal Boolean 
CopyErrHandler(
    OSErr error,		/* Error that occured */
    short failedOperation,	/* operation that caused the error */
    short srcVRefNum,		/* volume ref number of source */
    long srcDirID,		/* directory id of source */
    StringPtr srcName,		/* name of source */
    short dstVRefNum,		/* volume ref number of dst */
    long dstDirID,		/* directory id of dst */
    StringPtr dstName)		/* name of dst directory */
{
    return true;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpRemoveDirectory --
 *
 *	Removes directory (and its contents, if the recursive flag is set).
 *
 * Results:
 *	If the directory was successfully removed, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR, errno is set to indicate
 *	the error, and the pathname of the file that caused the error
 *	is stored in errorPtr.  Some possible values for errno are:
 *
 *	EACCES:     path directory can't be read and/or written.
 *	EEXIST:	    path is a non-empty directory.
 *	EINVAL:	    path is a root directory.
 *	ENOENT:	    path doesn't exist or is "".
 * 	ENOTDIR:    path is not a directory.
 *
 * Side effects:
 *	Directory removed.  If an error occurs, the error will be returned
 *	immediately, and remaining files will not be deleted.
 *
 *---------------------------------------------------------------------------
 */
 
int
TclpRemoveDirectory(
    char *path,			/* Pathname of directory to be removed. */
    int recursive,		/* If non-zero, removes directories that
				 * are nonempty.  Otherwise, will only remove
				 * empty directories. */
    Tcl_DString *errorPtr)	/* If non-NULL, initialized DString for
				 * error reporting. */
{				 
    OSErr err;
    FSSpec fileSpec;
    long dirID;
    int locked;
    Boolean isDirectory;
    CInfoPBRec pb;
    Str255 fileName;

    locked = 0;
    err = FSpLocationFromPath(strlen(path), path, &fileSpec);
    if (err != noErr) {
        goto done;
    }   

    /*
     * Since FSpDeleteCompat will delete a file, make sure this isn't
     * a file first.
     */
         
    isDirectory = 1;
    FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
    if (isDirectory == 0) {
        errno = ENOTDIR;
        return TCL_ERROR;
    }
    
    err = FSpDeleteCompat(&fileSpec);
    if (err == fLckdErr) {
        locked = 1;
    	FSpRstFLockCompat(&fileSpec);
    	err = FSpDeleteCompat(&fileSpec);
    }
    if (err == noErr) {
	return TCL_OK;
    }
    if (err != fBsyErr) {
        goto done;
    }
     
    if (recursive == 0) {
	/*
	 * fBsyErr means one of three things: file busy, directory not empty, 
	 * or working directory control block open.  Determine if directory
	 * is empty. If directory is not empty, return EEXIST.
	 */

	pb.hFileInfo.ioVRefNum = fileSpec.vRefNum;
	pb.hFileInfo.ioDirID = dirID;
	pb.hFileInfo.ioNamePtr = (StringPtr) fileName;
	pb.hFileInfo.ioFDirIndex = 1;
	if (PBGetCatInfoSync(&pb) == noErr) {
	    err = dupFNErr;	/* EEXIST */
	    goto done;
	}
    }
	
    /*
     * DeleteDirectory removes a directory and all its contents, including
     * any locked files.  There is no interface to get the name of the 
     * file that caused the error, if an error occurs deleting this tree,
     * unless we rewrite DeleteDirectory ourselves.
     */
	 
    err = DeleteDirectory(fileSpec.vRefNum, dirID, NULL);

    done:
    if (err != noErr) {
	if (errorPtr != NULL) {
	    Tcl_DStringAppend(errorPtr, path, -1);
	}
        if (locked) {
            FSpSetFLockCompat(&fileSpec);
        }
    	errno = TclMacOSErrorToPosixError(err);
    	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------------------
 *
 * MoveRename --







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







254
255
256
257
258
259
260

















































































































































































































































































































































































































































































































261
262
263
264
265
266
267
    }    

    end:    
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return TCL_ERROR;
    }

















































































































































































































































































































































































































































































































    return TCL_OK;
}

/*
 *--------------------------------------------------------------------------
 *
 * MoveRename --
840
841
842
843
844
845
846












































































































































































































































































































































































































































































































































































































847
848
849
850
851
852
853
854
855
856
857
858
            FSpSetFLockCompat(&dstFileSpec);
        } else {
            FSpSetFLockCompat(srcFileSpecPtr);
        }
    }
    return err;
}     












































































































































































































































































































































































































































































































































































































			    
/*
 *---------------------------------------------------------------------------
 *
 * GetFileSpecs --
 *
 * 	Generate a filename that is not in either of the two specified
 *	directories (on the same volume). 
 *
 * Results:
 *	Standard macintosh error.  On success, uniqueName is filled with 
 *	the name of the temporary file.







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




|







375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
            FSpSetFLockCompat(&dstFileSpec);
        } else {
            FSpSetFLockCompat(srcFileSpecPtr);
        }
    }
    return err;
}     

/*
 *---------------------------------------------------------------------------
 *
 * TclpCopyFile, DoCopyFile --
 *
 *      Copy a single file (not a directory).  If dst already exists and
 *	is not a directory, it is removed.
 *
 * Results:
 *	If the file was successfully copied, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the
 *	error.  Some possible values for errno are:
 *
 *	EACCES:     src or dst parent directory can't be read and/or written.
 *	EISDIR:	    src or dst is a directory.
 *	ENOENT:	    src doesn't exist.  src or dst is "".
 *
 * Side effects:
 *      This procedure will also copy symbolic links, block, and
 *      character devices, and fifos.  For symbolic links, the links 
 *      themselves will be copied and not what they point to.  For the
 *	other special file types, the directory entry will be copied and
 *	not the contents of the device that it refers to.
 *
 *---------------------------------------------------------------------------
 */
 
int 
TclpCopyFile(
    CONST char *src,		/* Pathname of file to be copied (UTF-8). */
    CONST char *dst)		/* Pathname of file to copy to (UTF-8). */
{
    int result;
    Tcl_DString srcString, dstString;

    Tcl_UtfToExternalDString(NULL, src, -1, &srcString);
    Tcl_UtfToExternalDString(NULL, dst, -1, &dstString);
    result = DoCopyFile(Tcl_DStringValue(&srcString), 
    	    Tcl_DStringValue(&dstString));
    Tcl_DStringFree(&srcString);
    Tcl_DStringFree(&dstString);
    return result;
}

static int
DoCopyFile(
    CONST char *src,		/* Pathname of file to be copied (native). */
    CONST char *dst)		/* Pathname of file to copy to (native). */
{
    OSErr err, dstErr;
    Boolean dstExists, dstIsDirectory, dstLocked;
    FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpFileSpec;
    Str31 tmpName;
	
    err = FSpLocationFromPath(strlen(src), src, &srcFileSpec);
    if (err == noErr) {
        err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists,
        	&dstIsDirectory);
    }
    if (dstExists) {
        if (dstIsDirectory) {
            errno = EISDIR;
            return TCL_ERROR;
        }
        err = FSpGetFLockCompat(&dstFileSpec, &dstLocked);
        if (dstLocked) {
            FSpRstFLockCompat(&dstFileSpec);
        }
        
        /*
         * Backup dest file.
         */
         
        dstErr = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, 
    	        dstFileSpec.parID, tmpName);
        if (dstErr == noErr) {
            dstErr = FSpRenameCompat(&dstFileSpec, tmpName);
        }   
    }
    if (err == noErr) {
    	err = FSpFileCopy(&srcFileSpec, &dstDirSpec, 
    		(StringPtr) dstFileSpec.name, NULL, 0, true);
    }
    if ((dstExists != false) && (dstErr == noErr)) {
        FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID,
        	tmpName, &tmpFileSpec);
	if (err == noErr) {
	    /* 
	     * Delete backup file. 
	     */
	     
	    FSpDeleteCompat(&tmpFileSpec);
	} else {
	
	    /* 
	     * Restore backup file.
	     */
	     
	    FSpDeleteCompat(&dstFileSpec);
	    FSpRenameCompat(&tmpFileSpec, dstFileSpec.name);
	    if (dstLocked) {
	        FSpSetFLockCompat(&dstFileSpec);
	    }
	}
    }
    
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpDeleteFile, DoDeleteFile --
 *
 *      Removes a single file (not a directory).
 *
 * Results:
 *	If the file was successfully deleted, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the
 *	error.  Some possible values for errno are:
 *
 *	EACCES:     a parent directory can't be read and/or written.
 *	EISDIR:	    path is a directory.
 *	ENOENT:	    path doesn't exist or is "".
 *
 * Side effects:
 *      The file is deleted, even if it is read-only.
 *
 *---------------------------------------------------------------------------
 */

int
TclpDeleteFile( 
    CONST char *path)		/* Pathname of file to be removed (UTF-8). */
{
    int result;
    Tcl_DString pathString;

    Tcl_UtfToExternalDString(NULL, path, -1, &pathString);
    result = DoDeleteFile(Tcl_DStringValue(&pathString));
    Tcl_DStringFree(&pathString);
    return result;
}

static int
DoDeleteFile(
    CONST char *path)		/* Pathname of file to be removed (native). */
{
    OSErr err;
    FSSpec fileSpec;
    Boolean isDirectory;
    long dirID;
    
    err = FSpLocationFromPath(strlen(path), path, &fileSpec);
    if (err == noErr) {
	/*
     	 * Since FSpDeleteCompat will delete an empty directory, make sure
     	 * that this isn't a directory first.
         */
        
        FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
	if (isDirectory == true) {
            errno = EISDIR;
            return TCL_ERROR;
        }
    }
    err = FSpDeleteCompat(&fileSpec);
    if (err == fLckdErr) {
    	FSpRstFLockCompat(&fileSpec);
    	err = FSpDeleteCompat(&fileSpec);
    	if (err != noErr) {
    	    FSpSetFLockCompat(&fileSpec);
    	}
    }
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpCreateDirectory, DoCreateDirectory --
 *
 *      Creates the specified directory.  All parent directories of the
 *	specified directory must already exist.  The directory is
 *	automatically created with permissions so that user can access
 *	the new directory and create new files or subdirectories in it.
 *
 * Results:
 *	If the directory was successfully created, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR and errno is set to
 *	indicate the error.  Some possible values for errno are:
 *
 *	EACCES:     a parent directory can't be read and/or written.
 *	EEXIST:	    path already exists.
 *	ENOENT:	    a parent directory doesn't exist.
 *
 * Side effects:
 *      A directory is created with the current umask, except that
 *	permission for u+rwx will always be added.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCreateDirectory(
    CONST char *path)		/* Pathname of directory to create (UTF-8). */
{
    int result;
    Tcl_DString pathString;

    Tcl_UtfToExternalDString(NULL, path, -1, &pathString);
    result = DoCreateDirectory(Tcl_DStringValue(&pathString));
    Tcl_DStringFree(&pathString);
    return result;
}

static int
DoCreateDirectory(
    CONST char *path)		/* Pathname of directory to create (native). */
{
    OSErr err;
    FSSpec dirSpec;
    long outDirID;
	
    err = FSpLocationFromPath(strlen(path), path, &dirSpec);
    if (err == noErr) {
        err = dupFNErr;		/* EEXIST. */
    } else if (err == fnfErr) {
        err = FSpDirCreateCompat(&dirSpec, smSystemScript, &outDirID);
    } 
    
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpCopyDirectory, DoCopyDirectory --
 *
 *      Recursively copies a directory.  The target directory dst must
 *	not already exist.  Note that this function does not merge two
 *	directory hierarchies, even if the target directory is an an
 *	empty directory.
 *
 * Results:
 *	If the directory was successfully copied, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR, errno is set to indicate
 *	the error, and the pathname of the file that caused the error
 *	is stored in errorPtr.  See TclpCreateDirectory and TclpCopyFile
 *	for a description of possible values for errno.
 *
 * Side effects:
 *      An exact copy of the directory hierarchy src will be created
 *	with the name dst.  If an error occurs, the error will
 *      be returned immediately, and remaining files will not be
 *	processed.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCopyDirectory(
    CONST char *src,		/* Pathname of directory to be copied
				 * (UTF-8). */
    CONST char *dst,		/* Pathname of target directory (UTF-8). */
    Tcl_DString *errorPtr)	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    int result;
    Tcl_DString srcString, dstString;

    Tcl_UtfToExternalDString(NULL, src, -1, &srcString);
    Tcl_UtfToExternalDString(NULL, dst, -1, &dstString);
    result = DoCopyDirectory(Tcl_DStringValue(&srcString),
	    Tcl_DStringValue(&dstString), errorPtr);
    Tcl_DStringFree(&srcString);
    Tcl_DStringFree(&dstString);
    return result;
}

static int
DoCopyDirectory(
    CONST char *src,		/* Pathname of directory to be copied
				 * (UTF-8). */
    CONST char *dst,		/* Pathname of target directory (UTF-8). */
    Tcl_DString *errorPtr)	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    OSErr err, saveErr;
    long srcID, tmpDirID;
    FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpDirSpec, tmpFileSpec;
    Boolean srcIsDirectory, srcLocked;
    Boolean dstIsDirectory, dstExists;
    Str31 tmpName;

    err = FSpLocationFromPath(strlen(src), src, &srcFileSpec);
    if (err == noErr) {
    	err = FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory);
    }
    if (err == noErr) {
        if (srcIsDirectory == false) {
            err = afpObjectTypeErr;	/* ENOTDIR. */
        }
    }
    if (err == noErr) {
        err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists,
        	&dstIsDirectory);
    }
    if (dstExists) {
        if (dstIsDirectory == false) {
            err = afpObjectTypeErr;	/* ENOTDIR. */
        } else {
            err = dupFNErr;		/* EEXIST. */
        }
    }
    if (err != noErr) {
        goto done;
    }        
    if ((srcFileSpec.vRefNum == dstFileSpec.vRefNum) &&
    	    (srcFileSpec.parID == dstFileSpec.parID) &&
            (Pstrequal(srcFileSpec.name, dstFileSpec.name) != 0)) {
        /*
         * Copying on top of self.  No-op.
         */
                    
        goto done;
    }

    /*
     * This algorthm will work making a copy of the source directory in
     * the current directory with a new name, in a new directory with the
     * same name, and in a new directory with a new name:
     *
     * 1. Make dstDir/tmpDir.
     * 2. Copy srcDir/src to dstDir/tmpDir/src
     * 3. Rename dstDir/tmpDir/src to dstDir/tmpDir/dst (if necessary).
     * 4. CatMove dstDir/tmpDir/dst to dstDir/dst.
     * 5. Remove dstDir/tmpDir.
     */
                
    err = FSpGetFLockCompat(&srcFileSpec, &srcLocked);
    if (srcLocked) {
        FSpRstFLockCompat(&srcFileSpec);
    }
    if (err == noErr) {
        err = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, 
    	        dstFileSpec.parID, tmpName);
    }
    if (err == noErr) {
        FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID,
        	tmpName, &tmpDirSpec);
        err = FSpDirCreateCompat(&tmpDirSpec, smSystemScript, &tmpDirID);
    }
    if (err == noErr) {
	err = FSpDirectoryCopy(&srcFileSpec, &tmpDirSpec, NULL, 0, true,
	    	CopyErrHandler);
    }
    
    /* 
     * Even if the Copy failed, Rename/Move whatever did get copied to the
     * appropriate final destination, if possible.  
     */
     
    saveErr = err;
    err = noErr;
    if (Pstrequal(srcFileSpec.name, dstFileSpec.name) == 0) {
        err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID, 
        	srcFileSpec.name, &tmpFileSpec);
        if (err == noErr) {
            err = FSpRenameCompat(&tmpFileSpec, dstFileSpec.name);
        }
    }
    if (err == noErr) {
        err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID,
        	dstFileSpec.name, &tmpFileSpec);
    }
    if (err == noErr) {
        err = FSpCatMoveCompat(&tmpFileSpec, &dstDirSpec);
    }
    if (err == noErr) {
        if (srcLocked) {
            FSpSetFLockCompat(&dstFileSpec);
        }
    }
    
    FSpDeleteCompat(&tmpDirSpec);
    
    if (saveErr != noErr) {
        err = saveErr;
    }
    
    done:
    if (err != noErr) {
        errno = TclMacOSErrorToPosixError(err);
        if (errorPtr != NULL) {
            Tcl_ExternalToUtfDString(NULL, dst, -1, errorPtr);
        }
        return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CopyErrHandler --
 *
 *      This procedure is called from the MoreFiles procedure 
 *      FSpDirectoryCopy whenever an error occurs.
 *
 * Results:
 *      False if the condition should not be considered an error, true
 *      otherwise.
 *
 * Side effects:
 *      Since FSpDirectoryCopy() is called only after removing any 
 *      existing target directories, there shouldn't be any errors.
 *      
 *----------------------------------------------------------------------
 */

static pascal Boolean 
CopyErrHandler(
    OSErr error,		/* Error that occured */
    short failedOperation,	/* operation that caused the error */
    short srcVRefNum,		/* volume ref number of source */
    long srcDirID,		/* directory id of source */
    StringPtr srcName,		/* name of source */
    short dstVRefNum,		/* volume ref number of dst */
    long dstDirID,		/* directory id of dst */
    StringPtr dstName)		/* name of dst directory */
{
    return true;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpRemoveDirectory, DoRemoveDirectory --
 *
 *	Removes directory (and its contents, if the recursive flag is set).
 *
 * Results:
 *	If the directory was successfully removed, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR, errno is set to indicate
 *	the error, and the pathname of the file that caused the error
 *	is stored in errorPtr.  Some possible values for errno are:
 *
 *	EACCES:     path directory can't be read and/or written.
 *	EEXIST:	    path is a non-empty directory.
 *	EINVAL:	    path is a root directory.
 *	ENOENT:	    path doesn't exist or is "".
 * 	ENOTDIR:    path is not a directory.
 *
 * Side effects:
 *	Directory removed.  If an error occurs, the error will be returned
 *	immediately, and remaining files will not be deleted.
 *
 *---------------------------------------------------------------------------
 */
 
int
TclpRemoveDirectory(
    CONST char *path,		/* Pathname of directory to be removed
				 * (UTF-8). */
    int recursive,		/* If non-zero, removes directories that
				 * are nonempty.  Otherwise, will only remove
				 * empty directories. */
    Tcl_DString *errorPtr)	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    int result;
    Tcl_DString pathString;

    Tcl_UtfToExternalDString(NULL, path, -1, &pathString);
    result = DoRemoveDirectory(Tcl_DStringValue(&pathString), recursive, 
    	    errorPtr);
    Tcl_DStringFree(&pathString);

    return result;
}

static int
DoRemoveDirectory(
    CONST char *path,		/* Pathname of directory to be removed
				 * (native). */
    int recursive,		/* If non-zero, removes directories that
				 * are nonempty.  Otherwise, will only remove
				 * empty directories. */
    Tcl_DString *errorPtr)	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    OSErr err;
    FSSpec fileSpec;
    long dirID;
    int locked;
    Boolean isDirectory;
    CInfoPBRec pb;
    Str255 fileName;


    locked = 0;
    err = FSpLocationFromPath(strlen(path), path, &fileSpec);
    if (err != noErr) {
        goto done;
    }   

    /*
     * Since FSpDeleteCompat will delete a file, make sure this isn't
     * a file first.
     */
         
    isDirectory = 1;
    FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
    if (isDirectory == 0) {
        errno = ENOTDIR;
        return TCL_ERROR;
    }
    
    err = FSpDeleteCompat(&fileSpec);
    if (err == fLckdErr) {
        locked = 1;
    	FSpRstFLockCompat(&fileSpec);
    	err = FSpDeleteCompat(&fileSpec);
    }
    if (err == noErr) {
	return TCL_OK;
    }
    if (err != fBsyErr) {
        goto done;
    }
     
    if (recursive == 0) {
	/*
	 * fBsyErr means one of three things: file busy, directory not empty, 
	 * or working directory control block open.  Determine if directory
	 * is empty. If directory is not empty, return EEXIST.
	 */

	pb.hFileInfo.ioVRefNum = fileSpec.vRefNum;
	pb.hFileInfo.ioDirID = dirID;
	pb.hFileInfo.ioNamePtr = (StringPtr) fileName;
	pb.hFileInfo.ioFDirIndex = 1;
	if (PBGetCatInfoSync(&pb) == noErr) {
	    err = dupFNErr;	/* EEXIST */
	    goto done;
	}
    }
	
    /*
     * DeleteDirectory removes a directory and all its contents, including
     * any locked files.  There is no interface to get the name of the 
     * file that caused the error, if an error occurs deleting this tree,
     * unless we rewrite DeleteDirectory ourselves.
     */
	 
    err = DeleteDirectory(fileSpec.vRefNum, dirID, NULL);

    done:
    if (err != noErr) {
	if (errorPtr != NULL) {
	    Tcl_UtfToExternalDString(NULL, path, -1, errorPtr);
	}
        if (locked) {
            FSpSetFLockCompat(&fileSpec);
        }
    	errno = TclMacOSErrorToPosixError(err);
    	return TCL_ERROR;
    }
    return TCL_OK;
}
			    
/*
 *---------------------------------------------------------------------------
 *
 * GenerateUniqueName --
 *
 * 	Generate a filename that is not in either of the two specified
 *	directories (on the same volume). 
 *
 * Results:
 *	Standard macintosh error.  On success, uniqueName is filled with 
 *	the name of the temporary file.
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static OSErr
GetFileSpecs(
    char *path,			/* The path to query. */
    FSSpec *pathSpecPtr,	/* Filled with information about path. */
    FSSpec *dirSpecPtr,		/* Filled with information about path's
    				 * parent directory. */
    Boolean *pathExistsPtr,	/* Set to true if path actually exists, 
    				 * false if it doesn't or there was an 
    				 * error reading the specified path. */
    Boolean *pathIsDirectoryPtr)/* Set to true if path is itself a directory,







|







1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static OSErr
GetFileSpecs(
    CONST char *path,		/* The path to query. */
    FSSpec *pathSpecPtr,	/* Filled with information about path. */
    FSSpec *dirSpecPtr,		/* Filled with information about path's
    				 * parent directory. */
    Boolean *pathExistsPtr,	/* Set to true if path actually exists, 
    				 * false if it doesn't or there was an 
    				 * error reading the specified path. */
    Boolean *pathIsDirectoryPtr)/* Set to true if path is itself a directory,
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
 *----------------------------------------------------------------------
 */

static int
GetFileFinderAttributes(
    Tcl_Interp *interp,		/* The interp to report errors with. */
    int objIndex,		/* The index of the attribute option. */
    char *fileName,		/* The name of the file. */
    Tcl_Obj **attributePtrPtr)	/* A pointer to return the object with. */
{
    OSErr err;
    FSSpec fileSpec;
    FInfo finfo;
    
    err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);







|







1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
 *----------------------------------------------------------------------
 */

static int
GetFileFinderAttributes(
    Tcl_Interp *interp,		/* The interp to report errors with. */
    int objIndex,		/* The index of the attribute option. */
    CONST char *fileName,	/* The name of the file. */
    Tcl_Obj **attributePtrPtr)	/* A pointer to return the object with. */
{
    OSErr err;
    FSSpec fileSpec;
    FInfo finfo;
    
    err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
    	    }
    	}
    }
    
    if (err != noErr) {
    	errno = TclMacOSErrorToPosixError(err);
    	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
    		"couldn't get attributes for file \"", fileName, "\": ",
    		Tcl_PosixError(interp), (char *) NULL);
    	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|







1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
    	    }
    	}
    }
    
    if (err != noErr) {
    	errno = TclMacOSErrorToPosixError(err);
    	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
    		"could not read \"", fileName, "\": ",
    		Tcl_PosixError(interp), (char *) NULL);
    	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
 *----------------------------------------------------------------------
 */

static int
GetFileReadOnly(
    Tcl_Interp *interp,		/* The interp to report errors with. */
    int objIndex,		/* The index of the attribute. */
    char *fileName,		/* The name of the file. */
    Tcl_Obj **readOnlyPtrPtr)	/* A pointer to return the object with. */
{
    OSErr err;
    FSSpec fileSpec;
    CInfoPBRec paramBlock;
    
    err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);







|







1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
 *----------------------------------------------------------------------
 */

static int
GetFileReadOnly(
    Tcl_Interp *interp,		/* The interp to report errors with. */
    int objIndex,		/* The index of the attribute. */
    CONST char *fileName,	/* The name of the file. */
    Tcl_Obj **readOnlyPtrPtr)	/* A pointer to return the object with. */
{
    OSErr err;
    FSSpec fileSpec;
    CInfoPBRec paramBlock;
    
    err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
    	    		paramBlock.hFileInfo.ioFlAttrib & 1);
    	    }
    	}
    }
    if (err != noErr) {
    	errno = TclMacOSErrorToPosixError(err);
    	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
    		"couldn't get attributes for file \"", fileName, "\": ",
    		Tcl_PosixError(interp), (char *) NULL);
    	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|







1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
    	    		paramBlock.hFileInfo.ioFlAttrib & 1);
    	    }
    	}
    }
    if (err != noErr) {
    	errno = TclMacOSErrorToPosixError(err);
    	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
    		"could not read \"", fileName, "\": ",
    		Tcl_PosixError(interp), (char *) NULL);
    	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
 *----------------------------------------------------------------------
 */

static int
SetFileFinderAttributes(
    Tcl_Interp *interp,		/* The interp to report errors with. */
    int objIndex,		/* The index of the attribute. */
    char *fileName,		/* The name of the file. */
    Tcl_Obj *attributePtr)	/* The command line object. */
{
    OSErr err;
    FSSpec fileSpec;
    FInfo finfo;
    
    err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);







|







1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
 *----------------------------------------------------------------------
 */

static int
SetFileFinderAttributes(
    Tcl_Interp *interp,		/* The interp to report errors with. */
    int objIndex,		/* The index of the attribute. */
    CONST char *fileName,	/* The name of the file. */
    Tcl_Obj *attributePtr)	/* The command line object. */
{
    OSErr err;
    FSSpec fileSpec;
    FInfo finfo;
    
    err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
    	    return TCL_ERROR;
    	}
    }
    
    if (err != noErr) {
    	errno = TclMacOSErrorToPosixError(err);
    	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
    		"couldn't set attributes for file \"", fileName, "\": ",
    		Tcl_PosixError(interp), (char *) NULL);
    	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|







1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
    	    return TCL_ERROR;
    	}
    }
    
    if (err != noErr) {
    	errno = TclMacOSErrorToPosixError(err);
    	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
    		"could not read \"", fileName, "\": ",
    		Tcl_PosixError(interp), (char *) NULL);
    	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
 *----------------------------------------------------------------------
 */

static int
SetFileReadOnly(
    Tcl_Interp *interp,		/* The interp to report errors with. */
    int objIndex,		/* The index of the attribute. */
    char *fileName,		/* The name of the file. */
    Tcl_Obj *readOnlyPtr)	/* The command line object. */
{
    OSErr err;
    FSSpec fileSpec;
    HParamBlockRec paramBlock;
    int hidden;
    







|







1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
 *----------------------------------------------------------------------
 */

static int
SetFileReadOnly(
    Tcl_Interp *interp,		/* The interp to report errors with. */
    int objIndex,		/* The index of the attribute. */
    CONST char *fileName,	/* The name of the file. */
    Tcl_Obj *readOnlyPtr)	/* The command line object. */
{
    OSErr err;
    FSSpec fileSpec;
    HParamBlockRec paramBlock;
    int hidden;
    
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
    	    err = fnfErr;
    	}
    }
    
    if (err != noErr) {
    	errno = TclMacOSErrorToPosixError(err);
    	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
    		"couldn't set attributes for file \"", fileName, "\": ",
    		Tcl_PosixError(interp), (char *) NULL);
    	return TCL_ERROR;
    }
    return TCL_OK;
}

/*







|







1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
    	    err = fnfErr;
    	}
    }
    
    if (err != noErr) {
    	errno = TclMacOSErrorToPosixError(err);
    	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
    		"could not read \"", fileName, "\": ",
    		Tcl_PosixError(interp), (char *) NULL);
    	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397

1398

1399
1400


1401
1402
1403
1404
1405
1406
1407
1408
 *	the list of volumes.
 *
 * Side effects:
 *	None
 *
 *---------------------------------------------------------------------------
 */

int
TclpListVolumes( 
		Tcl_Interp *interp)    /* Interpreter to which to pass the volume list */
{
    HParamBlockRec pb;
    Str255 name;
    OSErr theError = noErr;
    Tcl_Obj *resultPtr, *elemPtr;
    short volIndex = 1;


    resultPtr = Tcl_NewObj();
        
    /*
     * We use two facts:
     * 1) The Mac volumes are enumerated by the ioVolIndex parameter of
     * the HParamBlockRec.  They run through the integers contiguously, 
     * starting at 1.  
     * 2) PBHGetVInfoSync returns an error when you ask for a volume index
     * that does not exist.
     * 
     */
        
    while ( 1 ) {
        pb.volumeParam.ioNamePtr = (StringPtr) & name;
        pb.volumeParam.ioVolIndex = volIndex;
                
        theError = PBHGetVInfoSync(&pb);

        if ( theError != noErr ) {
            break;
        }
                

        elemPtr = Tcl_NewStringObj((char *) name + 1, (int) name[0]);

        Tcl_AppendToObj(elemPtr, ":", 1);
        Tcl_ListObjAppendElement(interp, resultPtr, elemPtr);


                
        volIndex++;             
    }
        
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;      
}








<









>














|







|
>
|
>


>
>








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
 *	the list of volumes.
 *
 * Side effects:
 *	None
 *
 *---------------------------------------------------------------------------
 */

int
TclpListVolumes( 
		Tcl_Interp *interp)    /* Interpreter to which to pass the volume list */
{
    HParamBlockRec pb;
    Str255 name;
    OSErr theError = noErr;
    Tcl_Obj *resultPtr, *elemPtr;
    short volIndex = 1;
    Tcl_DString dstr;

    resultPtr = Tcl_NewObj();
        
    /*
     * We use two facts:
     * 1) The Mac volumes are enumerated by the ioVolIndex parameter of
     * the HParamBlockRec.  They run through the integers contiguously, 
     * starting at 1.  
     * 2) PBHGetVInfoSync returns an error when you ask for a volume index
     * that does not exist.
     * 
     */
        
    while ( 1 ) {
        pb.volumeParam.ioNamePtr = (StringPtr) &name;
        pb.volumeParam.ioVolIndex = volIndex;
                
        theError = PBHGetVInfoSync(&pb);

        if ( theError != noErr ) {
            break;
        }
        
        Tcl_ExternalToUtfDString(NULL, (char *) &name[1], name[0], &dstr);  
        elemPtr = Tcl_NewStringObj(Tcl_DStringValue(&dstr),
		Tcl_DStringLength(&dstr));
        Tcl_AppendToObj(elemPtr, ":", 1);
        Tcl_ListObjAppendElement(interp, resultPtr, elemPtr);
        
        Tcl_DStringFree(&dstr);
                
        volIndex++;             
    }
        
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;      
}

Changes to mac/tclMacFile.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclMacFile.c --
 *
 *      This file implements the channel drivers for Macintosh
 *	files.  It also comtains Macintosh version of other Tcl
 *	functions that deal with the file system.
 *
 * 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.
 *
 * SCCS: @(#) tclMacFile.c 1.57 97/04/23 16:23:05
 */

/*
 * Note: This code eventually needs to support async I/O.  In doing this
 * we will need to keep track of all current async I/O.  If exit to shell
 * is called - we shouldn't exit until all asyc I/O completes.
 */







|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclMacFile.c --
 *
 *      This file implements the channel drivers for Macintosh
 *	files.  It also comtains Macintosh version of other Tcl
 *	functions that deal with the file system.
 *
 * Copyright (c) 1995-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: tclMacFile.c,v 1.1.2.3 1998/10/06 00:37:43 stanton Exp $
 */

/*
 * Note: This code eventually needs to support async I/O.  In doing this
 * we will need to keep track of all current async I/O.  If exit to shell
 * is called - we shouldn't exit until all asyc I/O completes.
 */
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246





247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
#include <Strings.h>
#include <Types.h>
#include <MoreFiles.h>
#include <MoreFilesExtras.h>
#include <FSpCompat.h>

/*
 * Static variables used by the TclMacStat function.
 */
static int initalized = false;
static long gmt_offset;

/*
 * The variable below caches the name of the current working directory
 * in order to avoid repeated calls to getcwd.  The string is malloc-ed.
 * NULL means the cache needs to be refreshed.
 */

static char *currentDir =  NULL;

/*
 *----------------------------------------------------------------------
 *
 * TclChdir --
 *
 *	Change the current working directory.
 *
 * Results:
 *	The result is a standard Tcl result.  If an error occurs and 
 *	interp isn't NULL, an error message is left in interp->result.
 *
 * Side effects:
 *	The working directory for this application is changed.  Also
 *	the cache maintained used by TclGetCwd is deallocated and
 *	set to NULL.
 *
 *----------------------------------------------------------------------
 */

int
TclChdir(
    Tcl_Interp *interp,		/* If non NULL, used for error reporting. */
    char *dirName)		/* Path to new working directory. */
{
    FSSpec spec;
    OSErr err;
    Boolean isFolder;
    long dirID;

    if (currentDir != NULL) {
	ckfree(currentDir);
	currentDir = NULL;
    }

    err = FSpLocationFromPath(strlen(dirName), dirName, &spec);
    if (err != noErr) {
	errno = ENOENT;
	goto chdirError;
    }
    
    err = FSpGetDirectoryID(&spec, &dirID, &isFolder);
    if (err != noErr) {
	errno = ENOENT;
	goto chdirError;
    }

    if (isFolder != true) {
	errno = ENOTDIR;
	goto chdirError;
    }

    err = FSpSetDefaultDir(&spec);
    if (err != noErr) {
	switch (err) {
	    case afpAccessDenied:
		errno = EACCES;
		break;
	    default:
		errno = ENOENT;
	}
	goto chdirError;
    }

    return TCL_OK;
    chdirError:
    if (interp != NULL) {
	Tcl_AppendResult(interp, "couldn't change working directory to \"",
		dirName, "\": ", Tcl_PosixError(interp), (char *) NULL);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetCwd --
 *
 *	Return the path name of the current working directory.
 *
 * Results:
 *	The result is the full path name of the current working
 *	directory, or NULL if an error occurred while figuring it
 *	out.  If an error occurs and interp isn't NULL, an error
 *	message is left in interp->result.
 *
 * Side effects:
 *	The path name is cached to avoid having to recompute it
 *	on future calls;  if it is already cached, the cached
 *	value is returned.
 *
 *----------------------------------------------------------------------
 */

char *
TclGetCwd(
    Tcl_Interp *interp)		/* If non NULL, used for error reporting. */
{
    FSSpec theSpec;
    int length;
    Handle pathHandle = NULL;
    
    if (currentDir == NULL) {
	if (FSpGetDefaultDir(&theSpec) != noErr) {
	    if (interp != NULL) {
		interp->result = "error getting working directory name";
	    }
	    return NULL;
	}
	if (FSpPathFromLocation(&theSpec, &length, &pathHandle) != noErr) {
	    if (interp != NULL) {
		interp->result = "error getting working directory name";
	    }
	    return NULL;
	}
	HLock(pathHandle);
	currentDir = (char *) ckalloc((unsigned) (length + 1));
	strcpy(currentDir, *pathHandle);
	HUnlock(pathHandle);
	DisposeHandle(pathHandle);	
    }
    return currentDir;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_WaitPid --
 *
 *	Fakes a call to wait pid.
 *
 * Results:
 *	Always returns -1.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Pid
Tcl_WaitPid(
    Tcl_Pid pid,
    int *statPtr,
    int options)
{
    return (Tcl_Pid) -1;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FindExecutable --
 *
 *	This procedure computes the absolute path name of the current
 *	application, given its argv[0] value.  However, this
 *	implementation doesn't use of need the argv[0] value.  NULL
 *	may be passed in its place.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The variable tclExecutableName gets filled in with the file
 *	name for the application, if we figured it out.  If we couldn't
 *	figure it out, Tcl_FindExecutable is set to NULL.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_FindExecutable(
    char *argv0)		/* The value of the application's argv[0]. */
{
    ProcessSerialNumber psn;
    ProcessInfoRec info;
    Str63 appName;
    FSSpec fileSpec;
    int pathLength;
    Handle pathName = NULL;
    OSErr err;



    
    GetCurrentProcess(&psn);
    info.processInfoLength = sizeof(ProcessInfoRec);
    info.processName = appName;
    info.processAppSpec = &fileSpec;
    GetProcessInformation(&psn, &info);

    if (tclExecutableName != NULL) {
	ckfree(tclExecutableName);
	tclExecutableName = NULL;
    }
    
    err = FSpPathFromLocation(&fileSpec, &pathLength, &pathName);

    tclExecutableName = (char *) ckalloc((unsigned) pathLength + 1);
    HLock(pathName);
    strcpy(tclExecutableName, *pathName);
    HUnlock(pathName);
    DisposeHandle(pathName);	





}

/*
 *----------------------------------------------------------------------
 *
 * TclGetUserHome --
 *
 *	This function takes the passed in user name and finds the
 *	corresponding home directory specified in the password file.
 *
 * Results:
 *	On a Macintosh we always return a NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclGetUserHome(
    char *name,			/* User name to use to find home directory. */
    Tcl_DString *bufferPtr)	/* May be used to hold result.  Must not hold
				 * anything at the time of the call, and need
				 * not even be initialized. */
{
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TclMatchFiles --
 *
 *	This routine is used by the globbing code to search a
 *	directory for all files which match a given pattern.
 *
 * Results: 
 *	If the tail argument is NULL, then the matching files are
 *	added to the interp->result.  Otherwise, TclDoGlob is called
 *	recursively for each matching subdirectory.  The return value
 *	is a standard Tcl result indicating whether an error occurred
 *	in globbing.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------- */

int
TclMatchFiles(
    Tcl_Interp *interp,		/* Interpreter to receive results. */
    char *separators,		/* Directory separators to pass to TclDoGlob. */
    Tcl_DString *dirPtr,	/* Contains path to directory to search. */
    char *pattern,		/* Pattern to match against. */
    char *tail)			/* Pointer to end of pattern.  Tail must
				 * point to a location in pattern. */

{
    char *dirName, *patternEnd = tail;
    char savedChar;
    int result = TCL_OK;
    int baseLength = Tcl_DStringLength(dirPtr);
    CInfoPBRec pb;
    OSErr err;
    FSSpec dirSpec;
    Boolean isDirectory;
    long dirID;
    short itemIndex;
    Str255 fileName;
    

    /*
     * Make sure that the directory part of the name really is a
     * directory.
     */

    dirName = dirPtr->string;







|

|

|
<
<
<
<
<

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








|















|








>
>
>













<
<

|


>
>
>
>
>





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






|










|





|
>












|







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
#include <Strings.h>
#include <Types.h>
#include <MoreFiles.h>
#include <MoreFilesExtras.h>
#include <FSpCompat.h>

/*
 * Static variables used by the TclpStat function.
 */
static int initialized = false;
static long gmt_offset;
TCL_DECLARE_MUTEX(gmtMutex)




























































































































































/*
 *----------------------------------------------------------------------
 *
 * Tcl_FindExecutable --
 *
 *	This procedure computes the absolute path name of the current
 *	application, given its argv[0] value.  However, this
 *	implementation doesn't need the argv[0] value.  NULL
 *	may be passed in its place.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The variable tclExecutableName gets filled in with the file
 *	name for the application, if we figured it out.  If we couldn't
 *	figure it out, Tcl_FindExecutable is set to NULL.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_FindExecutable(
    CONST char *argv0)		/* The value of the application's argv[0]. */
{
    ProcessSerialNumber psn;
    ProcessInfoRec info;
    Str63 appName;
    FSSpec fileSpec;
    int pathLength;
    Handle pathName = NULL;
    OSErr err;
    Tcl_DString ds;
    
    TclInitSubsystems(argv0);
    
    GetCurrentProcess(&psn);
    info.processInfoLength = sizeof(ProcessInfoRec);
    info.processName = appName;
    info.processAppSpec = &fileSpec;
    GetProcessInformation(&psn, &info);

    if (tclExecutableName != NULL) {
	ckfree(tclExecutableName);
	tclExecutableName = NULL;
    }
    
    err = FSpPathFromLocation(&fileSpec, &pathLength, &pathName);


    HLock(pathName);
    Tcl_ExternalToUtfDString(NULL, *pathName, pathLength, &ds);
    HUnlock(pathName);
    DisposeHandle(pathName);	

    tclExecutableName = (char *) ckalloc((unsigned) 
    	    (Tcl_DStringLength(&ds) + 1));
    strcpy(tclExecutableName, Tcl_DStringValue(&ds));
    Tcl_DStringFree(&ds);
}

/*
 *----------------------------------------------------------------------
 *



























 * TclpMatchFiles --
 *
 *	This routine is used by the globbing code to search a
 *	directory for all files which match a given pattern.
 *
 * Results: 
 *	If the tail argument is NULL, then the matching files are
 *	added to the the interp's result.  Otherwise, TclDoGlob is called
 *	recursively for each matching subdirectory.  The return value
 *	is a standard Tcl result indicating whether an error occurred
 *	in globbing.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------- */

int
TclpMatchFiles(
    Tcl_Interp *interp,		/* Interpreter to receive results. */
    char *separators,		/* Directory separators to pass to TclDoGlob. */
    Tcl_DString *dirPtr,	/* Contains path to directory to search. */
    char *pattern,		/* Pattern to match against. */
    char *tail)			/* Pointer to end of pattern.  Tail must
				 * point to a location in pattern and must
				 * not be static.*/
{
    char *dirName, *patternEnd = tail;
    char savedChar;
    int result = TCL_OK;
    int baseLength = Tcl_DStringLength(dirPtr);
    CInfoPBRec pb;
    OSErr err;
    FSSpec dirSpec;
    Boolean isDirectory;
    long dirID;
    short itemIndex;
    Str255 fileName;
    Tcl_DString fileString;    

    /*
     * Make sure that the directory part of the name really is a
     * directory.
     */

    dirName = dirPtr->string;
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379
380
381
382
383
384
385
386

387
388
389
390

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674


675
676

677


678
679
680
681
682
683
684

	/*
	 * Now check to see if the file matches.  If there are more
	 * characters to be processed, then ensure matching files are
	 * directories before calling TclDoGlob. Otherwise, just add
	 * the file to the result.
	 */


	p2cstr(fileName);
	if (Tcl_StringMatch((char *) fileName, pattern)) {
	    Tcl_DStringSetLength(dirPtr, baseLength);
	    Tcl_DStringAppend(dirPtr, (char *) fileName, -1);
	    if (tail == NULL) {
		if ((dirPtr->length > 1) &&
			(strchr(dirPtr->string+1, ':') == NULL)) {
		    Tcl_AppendElement(interp, dirPtr->string+1);
		} else {
		    Tcl_AppendElement(interp, dirPtr->string);
		}
	    } else if ((pb.hFileInfo.ioFlAttrib & ioDirMask) != 0) {
		Tcl_DStringAppend(dirPtr, ":", 1);
		result = TclDoGlob(interp, separators, dirPtr, tail);
		if (result != TCL_OK) {

		    break;
		}
	    }
	}

	
	itemIndex++;
    }
    *patternEnd = savedChar;

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclMacStat --
 *
 *	This function replaces the library version of stat.  The stat
 *	function provided by most Mac compiliers is rather broken and
 *	incomplete.
 *
 * Results:
 *	See stat documentation.
 *
 * Side effects:
 *	See stat documentation.
 *
 *----------------------------------------------------------------------
 */

int
TclMacStat(
    char *path,
    struct stat *buf)
{
    HFileInfo fpb;
    HVolumeParam vpb;
    OSErr err;
    FSSpec fileSpec;
    Boolean isDirectory;
    long dirID;
    
    err = FSpLocationFromPath(strlen(path), path, &fileSpec);
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return -1;
    }
    
    /*
     * Fill the fpb & vpb struct up with info about file or directory.
     */
     
    FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
    vpb.ioVRefNum = fpb.ioVRefNum = fileSpec.vRefNum;
    vpb.ioNamePtr = fpb.ioNamePtr = fileSpec.name;
    if (isDirectory) {
	fpb.ioDirID = fileSpec.parID;
    } else {
	fpb.ioDirID = dirID;
    }

    fpb.ioFDirIndex = 0;
    err = PBGetCatInfoSync((CInfoPBPtr)&fpb);
    if (err == noErr) {
	vpb.ioVolIndex = 0;
	err = PBHGetVInfoSync((HParmBlkPtr)&vpb);
	if (err == noErr && buf != NULL) {
	    /* 
	     * Files are always readable by everyone.
	     */
	     
	    buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH;

	    /* 
	     * Use the Volume Info & File Info to fill out stat buf.
	     */
	    if (fpb.ioFlAttrib & 0x10) {
		buf->st_mode |= S_IFDIR;
		buf->st_nlink = 2;
	    } else {
		buf->st_nlink = 1;
		if (fpb.ioFlFndrInfo.fdFlags & 0x8000) {
		    buf->st_mode |= S_IFLNK;
		} else {
		    buf->st_mode |= S_IFREG;
		}
	    }
	    if ((fpb.ioFlAttrib & 0x10) || (fpb.ioFlFndrInfo.fdType == 'APPL')) {
	    	/*
	    	 * Directories and applications are executable by everyone.
	    	 */
	    	 
	    	buf->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
	    }
	    if ((fpb.ioFlAttrib & 0x01) == 0){
	    	/* 
	    	 * If not locked, then everyone has write acces.
	    	 */
	    	 
	        buf->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
	    }
	    buf->st_ino = fpb.ioDirID;
	    buf->st_dev = fpb.ioVRefNum;
	    buf->st_uid = -1;
	    buf->st_gid = -1;
	    buf->st_rdev = 0;
	    buf->st_size = fpb.ioFlLgLen;
	    buf->st_blksize = vpb.ioVAlBlkSiz;
	    buf->st_blocks = (buf->st_size + buf->st_blksize - 1)
		/ buf->st_blksize;

	    /*
	     * The times returned by the Mac file system are in the
	     * local time zone.  We convert them to GMT so that the
	     * epoch starts from GMT.  This is also consistant with
	     * what is returned from "clock seconds".
	     */
	    if (initalized == false) {
		MachineLocation loc;
    
		ReadLocation(&loc);
		gmt_offset = loc.u.gmtDelta & 0x00ffffff;
		if (gmt_offset & 0x00800000) {
		    gmt_offset = gmt_offset | 0xff000000;
		}
		initalized = true;
	    }
	    buf->st_atime = buf->st_mtime = fpb.ioFlMdDat - gmt_offset;
	    buf->st_ctime = fpb.ioFlCrDat - gmt_offset;

	}
    }

    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
    }
    
    return (err == noErr ? 0 : -1);
}

/*
 *----------------------------------------------------------------------
 *
 * TclMacReadlink --
 *
 *	This function replaces the library version of readlink.
 *
 * Results:
 *	See readlink documentation.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclMacReadlink(
    char *path,
    char *buf,
    int size)
{
    HFileInfo fpb;
    OSErr err;
    FSSpec fileSpec;
    Boolean isDirectory;
    Boolean wasAlias;
    long dirID;
    char fileName[256];
    char *end;
    Handle theString = NULL;
    int pathSize;

    /*
     * Remove ending colons if they exist.
     */
    while ((strlen(path) != 0) && (path[strlen(path) - 1] == ':')) {
	path[strlen(path) - 1] = NULL;
    }

    if (strchr(path, ':') == NULL) {
	strcpy(fileName, path);
	path = NULL;
    } else {
	end = strrchr(path, ':') + 1;
	strcpy(fileName, end);
	*end = NULL;
    }
    c2pstr(fileName);
    
    /*
     * Create the file spec for the directory of the file
     * we want to look at.
     */
    if (path != NULL) {
	err = FSpLocationFromPath(strlen(path), path, &fileSpec);
	if (err != noErr) {
	    errno = EINVAL;
	    return -1;
	}
    } else {
	FSMakeFSSpecCompat(0, 0, NULL, &fileSpec);
    }
    
    /*
     * Fill the fpb struct up with info about file or directory.
     */
    FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
    fpb.ioVRefNum = fileSpec.vRefNum;
    fpb.ioDirID = dirID;
    fpb.ioNamePtr = (StringPtr) fileName;

    fpb.ioFDirIndex = 0;
    err = PBGetCatInfoSync((CInfoPBPtr)&fpb);
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return -1;
    } else {
	if (fpb.ioFlAttrib & 0x10) {
	    errno = EINVAL;
	    return -1;
	} else {
	    if (fpb.ioFlFndrInfo.fdFlags & 0x8000) {
		/*
		 * The file is a link!
		 */
	    } else {
		errno = EINVAL;
		return -1;
	    }
	}
    }
    
    /*
     * If we are here it's really a link - now find out
     * where it points to.
     */
    err = FSMakeFSSpecCompat(fileSpec.vRefNum, dirID, (StringPtr) fileName, &fileSpec);
    if (err == noErr) {
	err = ResolveAliasFile(&fileSpec, true, &isDirectory, &wasAlias);
    }
    if ((err == fnfErr) || wasAlias) {
	err = FSpPathFromLocation(&fileSpec, &pathSize, &theString);
	if ((err != noErr) || (pathSize > size)) {
	    DisposeHandle(theString);
	    errno = ENAMETOOLONG;
	    return -1;
	}
    } else {
    	errno = EINVAL;
	return -1;
    }

    strncpy(buf, *theString, pathSize);
    DisposeHandle(theString);
    
    return pathSize;
}

/*
 *----------------------------------------------------------------------
 *
 * TclMacAccess --
 *
 *	This function replaces the library version of access.  The
 *	access function provided by most Mac compiliers is rather 
 *	broken or incomplete.
 *
 * Results:
 *	See access documentation.
 *
 * Side effects:
 *	See access documentation.
 *
 *----------------------------------------------------------------------
 */

int
TclMacAccess(
    const char *path,
    int mode)
{
    HFileInfo fpb;
    HVolumeParam vpb;
    OSErr err;
    FSSpec fileSpec;
    Boolean isDirectory;
    long dirID;


    int full_mode = 0;


    err = FSpLocationFromPath(strlen(path), (char *) path, &fileSpec);


    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return -1;
    }
    
    /*
     * Fill the fpb & vpb struct up with info about file or directory.







|
>
|
|

|











>




>











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

|
<
<











|
|
|







>
>


>
|
>
>







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

	/*
	 * Now check to see if the file matches.  If there are more
	 * characters to be processed, then ensure matching files are
	 * directories before calling TclDoGlob. Otherwise, just add
	 * the file to the result.
	 */
	 
	Tcl_ExternalToUtfDString(NULL, (char *) fileName + 1, fileName[0],
		&fileString);
	if (Tcl_StringMatch(Tcl_DStringValue(&fileString), pattern)) {
	    Tcl_DStringSetLength(dirPtr, baseLength);
	    Tcl_DStringAppend(dirPtr, Tcl_DStringValue(&fileString), -1);
	    if (tail == NULL) {
		if ((dirPtr->length > 1) &&
			(strchr(dirPtr->string+1, ':') == NULL)) {
		    Tcl_AppendElement(interp, dirPtr->string+1);
		} else {
		    Tcl_AppendElement(interp, dirPtr->string);
		}
	    } else if ((pb.hFileInfo.ioFlAttrib & ioDirMask) != 0) {
		Tcl_DStringAppend(dirPtr, ":", 1);
		result = TclDoGlob(interp, separators, dirPtr, tail);
		if (result != TCL_OK) {
		    Tcl_DStringFree(&fileString);
		    break;
		}
	    }
	}
	Tcl_DStringFree(&fileString);
	
	itemIndex++;
    }
    *patternEnd = savedChar;

    return result;
}

/*
 *----------------------------------------------------------------------
 *























































































































































































































































 * TclpAccess --
 *
 *	This function replaces the library version of access().


 *
 * Results:
 *	See access documentation.
 *
 * Side effects:
 *	See access documentation.
 *
 *----------------------------------------------------------------------
 */

int
TclpAccess(
    CONST char *path,		/* Path of file to access (UTF-8). */
    int mode)			/* Permission setting. */
{
    HFileInfo fpb;
    HVolumeParam vpb;
    OSErr err;
    FSSpec fileSpec;
    Boolean isDirectory;
    long dirID;
    Tcl_DString ds;
    char *native;
    int full_mode = 0;

    native = Tcl_UtfToExternalDString(NULL, path, -1, &ds);
    err = FSpLocationFromPath(Tcl_DStringLength(&ds), native, &fileSpec);
    Tcl_DStringFree(&ds);

    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return -1;
    }
    
    /*
     * Fill the fpb & vpb struct up with info about file or directory.
738
739
740
741
742
743
744























































































































































































































































































































































































































745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
    
    return 0;
}

/*
 *----------------------------------------------------------------------
 *























































































































































































































































































































































































































 * TclMacFOpenHack --
 *
 *	This function replaces fopen.  It supports paths with alises.
 *	Note, remember to undefine the fopen macro!
 *
 * Results:
 *	See fopen documentation.
 *
 * Side effects:
 *	See fopen documentation.
 *
 *----------------------------------------------------------------------
 */

#undef fopen
FILE *
TclMacFOpenHack(
    const char *path,
    const char *mode)
{
    OSErr err;
    FSSpec fileSpec;
    Handle pathString = NULL;
    int size;
    FILE * f;
    







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

















|
|







323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
    
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpChdir --
 *
 *	This function replaces the library version of chdir().
 *
 * Results:
 *	See chdir() documentation.
 *
 * Side effects:
 *	See chdir() documentation.  Also the cache maintained used by 
 *	TclGetCwd() is deallocated and set to NULL.
 *
 *----------------------------------------------------------------------
 */

int
TclpChdir(
    CONST char *dirName)     	/* Path to new working directory (UTF-8). */
{
    FSSpec spec;
    OSErr err;
    Boolean isFolder;
    long dirID;
    Tcl_DString ds;
    char *native;

    native = Tcl_UtfToExternalDString(NULL, dirName, -1, &ds);
    err = FSpLocationFromPath(Tcl_DStringLength(&ds), native, &spec);
    Tcl_DStringFree(&ds);

    if (err != noErr) {
	errno = ENOENT;
	return -1;
    }
    
    err = FSpGetDirectoryID(&spec, &dirID, &isFolder);
    if (err != noErr) {
	errno = ENOENT;
	return -1;
    }

    if (isFolder != true) {
	errno = ENOTDIR;
	return -1;
    }

    err = FSpSetDefaultDir(&spec);
    if (err != noErr) {
	switch (err) {
	    case afpAccessDenied:
		errno = EACCES;
		break;
	    default:
		errno = ENOENT;
	}
	return -1;
    }

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpGetCwd --
 *
 *	This function replaces the library version of getcwd().
 *
 * Results:
 *	The result is a pointer to a string specifying the current
 *	directory, or NULL if the current directory could not be
 *	determined.  If NULL is returned, an error message is left in the
 *	interp's result.  Storage for the result string is allocated in
 *	bufferPtr; the caller must call Tcl_DStringFree() when the result
 *	is no longer needed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpGetCwd(
    Tcl_Interp *interp,		/* If non-NULL, used for error reporting. */
    Tcl_DString *bufferPtr)	/* Uninitialized or free DString filled
				 * with name of current directory. */
{
    FSSpec theSpec;
    int length;
    Handle pathHandle = NULL;
    
    if (FSpGetDefaultDir(&theSpec) != noErr) {
 	if (interp != NULL) {
	    Tcl_SetResult(interp, "error getting working directory name",
		    TCL_STATIC);
	}
	return NULL;
    }
    if (FSpPathFromLocation(&theSpec, &length, &pathHandle) != noErr) {
 	if (interp != NULL) {
	     Tcl_SetResult(interp, "error getting working directory name",
		    TCL_STATIC);
	}
	return NULL;
    }
    HLock(pathHandle);
    Tcl_ExternalToUtfDString(NULL, *pathHandle, length, bufferPtr);
    HUnlock(pathHandle);
    DisposeHandle(pathHandle);	

    return Tcl_DStringValue(bufferPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpReadlink --
 *
 *	This function replaces the library version of readlink().
 *
 * Results:
 *	The result is a pointer to a string specifying the contents
 *	of the symbolic link given by 'path', or NULL if the symbolic
 *	link could not be read.  Storage for the result string is
 *	allocated in bufferPtr; the caller must call Tcl_DStringFree()
 *	when the result is no longer needed.
 *
 * Side effects:
 *	See readlink() documentation.
 *
 *---------------------------------------------------------------------------
 */

char *
TclpReadlink(
    CONST char *path,		/* Path of file to readlink (UTF-8). */
    Tcl_DString *linkPtr)	/* Uninitialized or free DString filled
				 * with contents of link (UTF-8). */
{
    HFileInfo fpb;
    OSErr err;
    FSSpec fileSpec;
    Boolean isDirectory;
    Boolean wasAlias;
    long dirID;
    char fileName[257];
    char *end;
    Handle theString = NULL;
    int pathSize;
    Tcl_DString ds;
    char *native;
    
    native = Tcl_UtfToExternalDString(NULL, path, -1, &ds);

    /*
     * Remove ending colons if they exist.
     */
     
    while ((strlen(native) != 0) && (path[strlen(native) - 1] == ':')) {
	native[strlen(native) - 1] = NULL;
    }

    if (strchr(native, ':') == NULL) {
	strcpy(fileName + 1, native);
	native = NULL;
    } else {
	end = strrchr(native, ':') + 1;
	strcpy(fileName + 1, end);
	*end = NULL;
    }
    fileName[0] = (char) strlen(fileName + 1);
    
    /*
     * Create the file spec for the directory of the file
     * we want to look at.
     */

    if (native != NULL) {
	err = FSpLocationFromPath(strlen(native), native, &fileSpec);
	if (err != noErr) {
	    Tcl_DStringFree(&ds);
	    errno = EINVAL;
	    return NULL;
	}
    } else {
	FSMakeFSSpecCompat(0, 0, NULL, &fileSpec);
    }
    Tcl_DStringFree(&ds);
    
    /*
     * Fill the fpb struct up with info about file or directory.
     */

    FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
    fpb.ioVRefNum = fileSpec.vRefNum;
    fpb.ioDirID = dirID;
    fpb.ioNamePtr = (StringPtr) fileName;

    fpb.ioFDirIndex = 0;
    err = PBGetCatInfoSync((CInfoPBPtr)&fpb);
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return NULL;
    } else {
	if (fpb.ioFlAttrib & 0x10) {
	    errno = EINVAL;
	    return NULL;
	} else {
	    if (fpb.ioFlFndrInfo.fdFlags & 0x8000) {
		/*
		 * The file is a link!
		 */
	    } else {
		errno = EINVAL;
		return NULL;
	    }
	}
    }
    
    /*
     * If we are here it's really a link - now find out
     * where it points to.
     */
    err = FSMakeFSSpecCompat(fileSpec.vRefNum, dirID, (StringPtr) fileName, 
    	    &fileSpec);
    if (err == noErr) {
	err = ResolveAliasFile(&fileSpec, true, &isDirectory, &wasAlias);
    }
    if ((err == fnfErr) || wasAlias) {
	err = FSpPathFromLocation(&fileSpec, &pathSize, &theString);
	if (err != noErr) {
	    DisposeHandle(theString);
	    errno = ENAMETOOLONG;
	    return NULL;
	}
    } else {
    	errno = EINVAL;
	return NULL;
    }
    
    Tcl_ExternalToUtfDString(NULL, *theString, pathSize, linkPtr);
    DisposeHandle(theString);
    
    return Tcl_DStringValue(linkPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpStat --
 *
 *	This function replaces the library version of stat().
 *
 * Results:
 *	See stat() documentation.
 *
 * Side effects:
 *	See stat() documentation.
 *
 *----------------------------------------------------------------------
 */

int
TclpStat(
    CONST char *path,		/* Path of file to stat (in UTF-8). */
    struct stat *bufPtr)	/* Filled with results of stat call. */
{
    HFileInfo fpb;
    HVolumeParam vpb;
    OSErr err;
    FSSpec fileSpec;
    Boolean isDirectory;
    long dirID;
    Tcl_DString ds;
    
    path = Tcl_UtfToExternalDString(NULL, path, -1, &ds);
    err = FSpLocationFromPath(Tcl_DStringLength(&ds), path, &fileSpec);
    Tcl_DStringFree(&ds);
    
    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
	return -1;
    }
    
    /*
     * Fill the fpb & vpb struct up with info about file or directory.
     */
     
    FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
    vpb.ioVRefNum = fpb.ioVRefNum = fileSpec.vRefNum;
    vpb.ioNamePtr = fpb.ioNamePtr = fileSpec.name;
    if (isDirectory) {
	fpb.ioDirID = fileSpec.parID;
    } else {
	fpb.ioDirID = dirID;
    }

    fpb.ioFDirIndex = 0;
    err = PBGetCatInfoSync((CInfoPBPtr)&fpb);
    if (err == noErr) {
	vpb.ioVolIndex = 0;
	err = PBHGetVInfoSync((HParmBlkPtr)&vpb);
	if (err == noErr && bufPtr != NULL) {
	    /* 
	     * Files are always readable by everyone.
	     */
	     
	    bufPtr->st_mode = S_IRUSR | S_IRGRP | S_IROTH;

	    /* 
	     * Use the Volume Info & File Info to fill out stat buf.
	     */
	    if (fpb.ioFlAttrib & 0x10) {
		bufPtr->st_mode |= S_IFDIR;
		bufPtr->st_nlink = 2;
	    } else {
		bufPtr->st_nlink = 1;
		if (fpb.ioFlFndrInfo.fdFlags & 0x8000) {
		    bufPtr->st_mode |= S_IFLNK;
		} else {
		    bufPtr->st_mode |= S_IFREG;
		}
	    }
	    if ((fpb.ioFlAttrib & 0x10) || (fpb.ioFlFndrInfo.fdType == 'APPL')) {
	    	/*
	    	 * Directories and applications are executable by everyone.
	    	 */
	    	 
	    	bufPtr->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
	    }
	    if ((fpb.ioFlAttrib & 0x01) == 0){
	    	/* 
	    	 * If not locked, then everyone has write acces.
	    	 */
	    	 
	        bufPtr->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
	    }
	    bufPtr->st_ino = fpb.ioDirID;
	    bufPtr->st_dev = fpb.ioVRefNum;
	    bufPtr->st_uid = -1;
	    bufPtr->st_gid = -1;
	    bufPtr->st_rdev = 0;
	    bufPtr->st_size = fpb.ioFlLgLen;
	    bufPtr->st_blksize = vpb.ioVAlBlkSiz;
	    bufPtr->st_blocks = (bufPtr->st_size + bufPtr->st_blksize - 1)
		/ bufPtr->st_blksize;

	    /*
	     * The times returned by the Mac file system are in the
	     * local time zone.  We convert them to GMT so that the
	     * epoch starts from GMT.  This is also consistant with
	     * what is returned from "clock seconds".
	     */

	    Tcl_MutexLock(&gmtMutex);
	    if (initialized == false) {
		MachineLocation loc;
    
		ReadLocation(&loc);
		gmt_offset = loc.u.gmtDelta & 0x00ffffff;
		if (gmt_offset & 0x00800000) {
		    gmt_offset = gmt_offset | 0xff000000;
		}
		initialized = true;
	    }
	    Tcl_MutexUnlock(&gmtMutex);

	    bufPtr->st_atime = bufPtr->st_mtime = fpb.ioFlMdDat - gmt_offset;
	    bufPtr->st_ctime = fpb.ioFlCrDat - gmt_offset;
	}
    }

    if (err != noErr) {
	errno = TclMacOSErrorToPosixError(err);
    }
    
    return (err == noErr ? 0 : -1);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_WaitPid --
 *
 *	Fakes a call to wait pid.
 *
 * Results:
 *	Always returns -1.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Pid
Tcl_WaitPid(
    Tcl_Pid pid,
    int *statPtr,
    int options)
{
    return (Tcl_Pid) -1;
}

/*
 *----------------------------------------------------------------------
 *
 * TclMacFOpenHack --
 *
 *	This function replaces fopen.  It supports paths with alises.
 *	Note, remember to undefine the fopen macro!
 *
 * Results:
 *	See fopen documentation.
 *
 * Side effects:
 *	See fopen documentation.
 *
 *----------------------------------------------------------------------
 */

#undef fopen
FILE *
TclMacFOpenHack(
    CONST char *path,
    CONST char *mode)
{
    OSErr err;
    FSSpec fileSpec;
    Handle pathString = NULL;
    int size;
    FILE * f;
    

Changes to mac/tclMacInit.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
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
/*
 * tclMacInit.c --
 *
 *	Contains the Mac-specific interpreter initialization functions.
 *
 * 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.
 *
 * SCCS: @(#) tclMacInit.c 1.39 97/09/23 13:17:30
 */






#include <Files.h>

#include <Gestalt.h>
#include <TextUtils.h>
#include <Resources.h>
#include <Strings.h>
#include "tclInt.h"
#include "tclMacInt.h"






























































































































































































































































































































































































































































/*
 *----------------------------------------------------------------------
 *
 * TclPlatformInit --
 *
 *	Performs Mac-specific interpreter initialization related to the
 *      tcl_platform and tcl_library variables.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets "tcl_library" & "tcl_platfrom" Tcl variable
 *
 *----------------------------------------------------------------------
 */

void
TclPlatformInit(
    Tcl_Interp *interp)		/* Tcl interpreter to initialize. */
{
    char *libDir;
    Tcl_DString path, libPath;
    long int gestaltResult;
    int minor, major;

    char versStr[10];




    /*
     * Set runtime C variable that tells cross platform C functions
     * what platform they are running on.  This can change at
     * runtime for testing purposes.
     */

    tclPlatform = TCL_PLATFORM_MAC;



    


    /*



     * Define the tcl_platfrom variable.
     */
    Tcl_SetVar2(interp, "tcl_platform", "platform", "macintosh",
	    TCL_GLOBAL_ONLY);
    Tcl_SetVar2(interp, "tcl_platform", "os", "MacOS", TCL_GLOBAL_ONLY);
    Gestalt(gestaltSystemVersion, &gestaltResult);
    major = (gestaltResult & 0x0000FF00) >> 8;
    minor = (gestaltResult & 0x000000F0) >> 4;
    sprintf(versStr, "%d.%d", major, minor);
    Tcl_SetVar2(interp, "tcl_platform", "osVersion", versStr, TCL_GLOBAL_ONLY);
#if GENERATINGPOWERPC
    Tcl_SetVar2(interp, "tcl_platform", "machine", "ppc", TCL_GLOBAL_ONLY);
#else
    Tcl_SetVar2(interp, "tcl_platform", "machine", "68k", TCL_GLOBAL_ONLY);
#endif

    /*
     * The tcl_library path can be found in one of two places.  As an element
     * in the env array.  Or the default which is to a folder in side the
     * Extensions folder of your system.
     */
     
    Tcl_DStringInit(&path);
    libDir = Tcl_GetVar2(interp, "env", "TCL_LIBRARY", TCL_GLOBAL_ONLY);
    if (libDir != NULL) {
	Tcl_SetVar(interp, "tcl_library", libDir, TCL_GLOBAL_ONLY);
    } else {
	libDir = Tcl_GetVar2(interp, "env", "EXT_FOLDER", TCL_GLOBAL_ONLY);
	if (libDir != NULL) {
	    Tcl_JoinPath(1, &libDir, &path);
	    
	    Tcl_DStringInit(&libPath);
	    Tcl_DStringAppend(&libPath, ":Tool Command Language:tcl", -1);
	    Tcl_DStringAppend(&libPath, TCL_VERSION, -1);
	    Tcl_JoinPath(1, &libPath.string, &path);
	    Tcl_DStringFree(&libPath);
	    Tcl_SetVar(interp, "tcl_library", path.string, TCL_GLOBAL_ONLY);
	} else {
	    Tcl_SetVar(interp, "tcl_library", "no library", TCL_GLOBAL_ONLY);
	}
    }
    
    /*
     * Now create the tcl_pkgPath variable.
     */
    Tcl_DStringSetLength(&path, 0);
    libDir = Tcl_GetVar2(interp, "env", "EXT_FOLDER", TCL_GLOBAL_ONLY);
    if (libDir != NULL) {
	Tcl_JoinPath(1, &libDir, &path);
	libDir = ":Tool Command Language:";
	Tcl_JoinPath(1, &libDir, &path);
	Tcl_SetVar(interp, "tcl_pkgPath", path.string,
		TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT);
    } else {
	Tcl_SetVar(interp, "tcl_pkgPath", "no extension folder",
		TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT);
    }
    Tcl_DStringFree(&path);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCheckStackSpace --
 *





|




|


>
>
>
>
>

>






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


|

|

|
|
>





|





|
|

<
<

|
>
|
>
>
>

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















|
|
<

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


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







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


495
496
497
498
499
500
501
502


503
504

505
506
507
508
509
510
511
512
513
514
515
516
517

518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

535
536
537
538
539


540
541

542








543
544
545















546
547
548
549
550
551
552
553
/*
 * tclMacInit.c --
 *
 *	Contains the Mac-specific interpreter initialization functions.
 *
 * Copyright (c) 1995-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: tclMacInit.c,v 1.1.2.5 1999/04/14 00:34:52 surles Exp $
 */

#include <AppleEvents.h>
#include <AEDataModel.h>
#include <AEObjects.h>
#include <AEPackObject.h>
#include <AERegistry.h>
#include <Files.h>
#include <Folders.h>
#include <Gestalt.h>
#include <TextUtils.h>
#include <Resources.h>
#include <Strings.h>
#include "tclInt.h"
#include "tclMacInt.h"
#include "tclPort.h"

/*
 * The following string is the startup script executed in new
 * interpreters.  It looks on the library path and in the resource fork for
 * a script "init.tcl" that is compatible with this version of Tcl.  The
 * init.tcl script does all of the real work of initialization.
 */
 
static char initCmd[] = "\
proc sourcePath {file} {\n\
  set dirs {}\n\
  foreach i $::auto_path {\n\
    set init [file join $i $file.tcl]\n\
    if {[catch {uplevel #0 [list source $init]}] == 0} {\n\
      return\n\
    }\n\
  }\n\
  if {[catch {uplevel #0 [list source -rsrc $file]}] == 0} {\n\
    return\n\
  }\n\
  rename sourcePath {}\n\
  set msg \"can't find $file resource or a usable $file.tcl file\n\"\n\
  append msg \"in the following directories:\n\"\n\
  append msg \"    $::auto_path\n\"\n\
  append msg \" perhaps you need to install Tcl or set your \n\"\n\
  append msg \"TCL_LIBRARY environment variable?\"\n\
  error $msg\n\
}\n\
if {[info exists env(EXT_FOLDER)]} {\n\
  lappend tcl_pkgPath [file join $env(EXT_FOLDER) {:Tool Command Language}]\n\
}\n\
if {[info exists tcl_pkgPath] == 0} {\n\
  set tcl_pkgPath {no extension folder}\n\
}\n\
sourcePath Init\n\
sourcePath Auto\n\
sourcePath Package\n\
sourcePath History\n\
sourcePath Word\n\
rename sourcePath {}";

/*
 * The following structures are used to map the script/language codes of a 
 * font to the name that should be passed to Tcl_GetEncoding() to obtain
 * the encoding for that font.  The set of numeric constants is fixed and 
 * defined by Apple.
 */
 
typedef struct Map {
    int numKey;
    char *strKey;
} Map;
 
static Map scriptMap[] = {
    {smRoman,		"macRoman"},
    {smJapanese,	"macJapan"},
    {smTradChinese,	"macChinese"},
    {smKorean,		"macKorean"},
    {smArabic,		"macArabic"},
    {smHebrew,		"macHebrew"},
    {smGreek,		"macGreek"},
    {smCyrillic,	"macCyrillic"},
    {smRSymbol,		"macRSymbol"},
    {smDevanagari,	"macDevanagari"},
    {smGurmukhi,	"macGurmukhi"},
    {smGujarati,	"macGujarati"},
    {smOriya,		"macOriya"},
    {smBengali,		"macBengali"},
    {smTamil,		"macTamil"},
    {smTelugu,		"macTelugu"},
    {smKannada,		"macKannada"},
    {smMalayalam,	"macMalayalam"},
    {smSinhalese,	"macSinhalese"},
    {smBurmese,		"macBurmese"},
    {smKhmer,		"macKhmer"},
    {smThai,		"macThailand"},
    {smLaotian,		"macLaos"},
    {smGeorgian,	"macGeorgia"},
    {smArmenian,	"macArmenia"},
    {smSimpChinese,	"macSimpChinese"},
    {smTibetan,		"macTIbet"},
    {smMongolian,	"macMongolia"},
    {smGeez,		"macEthiopia"},
    {smEastEurRoman,	"macCentEuro"},
    {smVietnamese,	"macVietnam"},
    {smExtArabic,	"macSindhi"},
    {NULL,		NULL}
};    

static Map romanMap[] = {
    {langCroatian,	"macCroatian"},
    {langSlovenian,	"macCroatian"},
    {langIcelandic,	"macIceland"},
    {langRomanian,	"macRomania"},
    {langTurkish,	"macTurkish"},
    {langGreek,		"macGreek"},
    {NULL,		NULL}
};

static Map cyrillicMap[] = {
    {langUkrainian,	"macUkraine"},
    {langBulgarian,	"macBulgaria"},
    {NULL,		NULL}
};

static int		GetFinderFont(int *finderID);


/*
 *----------------------------------------------------------------------
 *
 * GetFinderFont --
 *
 *	Gets the "views" font of the Macintosh Finder
 *
 * Results:
 *	Standard Tcl result, and sets finderID to the font family
 *      id for the current finder font.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
static int
GetFinderFont(int *finderID)
{
    OSErr err = noErr;
    OSType finderPrefs, viewFont = 'vfnt';
    DescType returnType;
    Size returnSize;
    long result, sys8Mask = 0x0800;
    static AppleEvent outgoingAevt = {typeNull, NULL};
    AppleEvent returnAevt;
    AEAddressDesc fndrAddress;
    AEDesc nullContainer = {typeNull, NULL}, 
           tempDesc = {typeNull, NULL}, 
           tempDesc2 = {typeNull, NULL}, 
           finalDesc = {typeNull, NULL};
    const OSType finderSignature = 'MACS';
    
    
    if (outgoingAevt.descriptorType == typeNull) {
        if ((Gestalt(gestaltSystemVersion, &result) != noErr)
	        || (result >= sys8Mask)) {
            finderPrefs = 'pfrp';
        } else {
	    finderPrefs = 'pvwp';
        }
        
        AECreateDesc(typeApplSignature, &finderSignature,
		sizeof(finderSignature), &fndrAddress);
            
        err = AECreateAppleEvent(kAECoreSuite, kAEGetData, &fndrAddress, 
                kAutoGenerateReturnID, kAnyTransactionID, &outgoingAevt);
                
        AEDisposeDesc(&fndrAddress);
    
        /*
         * The structure is:
         * the property view font ('vfnt')
         *    of the property view preferences ('pvwp')
         *        of the Null Container (i.e. the Finder itself). 
         */
         
        AECreateDesc(typeType, &finderPrefs, sizeof(finderPrefs), &tempDesc);
        err = CreateObjSpecifier(typeType, &nullContainer, formPropertyID,
		&tempDesc, true, &tempDesc2);
        AECreateDesc(typeType, &viewFont, sizeof(viewFont), &tempDesc);
        err = CreateObjSpecifier(typeType, &tempDesc2, formPropertyID,
		&tempDesc, true, &finalDesc);
    
        AEPutKeyDesc(&outgoingAevt, keyDirectObject, &finalDesc);
        AEDisposeDesc(&finalDesc);
    }
             
    err = AESend(&outgoingAevt, &returnAevt, kAEWaitReply, kAEHighPriority,
	    kAEDefaultTimeout, NULL, NULL);
    if (err == noErr) {
        err = AEGetKeyPtr(&returnAevt, keyDirectObject, typeInteger, 
                &returnType, (void *) finderID, sizeof(int), &returnSize);
        if (err == noErr) {
            return TCL_OK;
        }
    }
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclMacGetFontEncoding --
 *
 *	Determine the encoding of the specified font.  The encoding
 *	can be used to convert bytes from UTF-8 into the encoding of
 *	that font.
 *
 * Results:
 *	The return value is a string that specifies the font's encoding
 *	and that can be passed to Tcl_GetEncoding() to construct the
 *	encoding.  If the font's encoding could not be identified, NULL
 *	is returned.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
char *
TclMacGetFontEncoding(
    int fontId)
{
    int script, lang;
    char *name;
    Map *mapPtr;
    
    script = FontToScript(fontId);    
    lang = GetScriptVariable(script, smScriptLang);
    name = NULL;
    if (script == smRoman) {
        for (mapPtr = romanMap; mapPtr->strKey != NULL; mapPtr++) {
            if (mapPtr->numKey == lang) {
                name = mapPtr->strKey;
                break;
            }
        }
    } else if (script == smCyrillic) {
        for (mapPtr = cyrillicMap; mapPtr->strKey != NULL; mapPtr++) {
            if (mapPtr->numKey == lang) {
                name = mapPtr->strKey;
                break;
            }
        }
    }
    if (name == NULL) {
        for (mapPtr = scriptMap; mapPtr->strKey != NULL; mapPtr++) {
            if (mapPtr->numKey == script) {
                name = mapPtr->strKey;
                break;
            }
        }
    }
    return name;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpInitPlatform --
 *
 *	Initialize all the platform-dependant things like signals and
 *	floating-point error handling.
 *
 *	Called at process initialization time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TclpInitPlatform()
{
    tclPlatform = TCL_PLATFORM_MAC;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpInitLibraryPath --
 *
 *	Initialize the library path at startup.  We have a minor
 *	metacircular problem that we don't know the encoding of the
 *	operating system but we may need to talk to operating system
 *	to find the library directories so that we know how to talk to
 *	the operating system.
 *
 *	We do not know the encoding of the operating system.
 *	We do know that the encoding is some multibyte encoding.
 *	In that multibyte encoding, the characters 0..127 are equivalent
 *	    to ascii.
 *
 *	So although we don't know the encoding, it's safe:
 *	    to look for the last colon character in a path in the encoding.
 *	    to append an ascii string to a path.
 *	    to pass those strings back to the operating system.
 *
 *	But any strings that we remembered before we knew the encoding of
 *	the operating system must be translated to UTF-8 once we know the
 *	encoding so that the rest of Tcl can use those strings.
 *
 *	This call sets the library path to strings in the unknown native
 *	encoding.  TclpSetInitialEncodings() will translate the library
 *	path from the native encoding to UTF-8 as soon as it determines
 *	what the native encoding actually is.
 *
 *	Called at process initialization time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TclpInitLibraryPath(argv0)
    CONST char *argv0;		/* Name of executable from argv[0] to main().
				 * Not used because we can determine the name
				 * by querying the module handle. */
{
    Tcl_Obj *objPtr, *pathPtr;
    char *str;
    Tcl_DString ds;
    
    TclMacCreateEnv();

    pathPtr = Tcl_NewObj();
    
    str = TclGetEnv("TCL_LIBRARY", &ds);
    if ((str != NULL) && (str[0] != '\0')) {
	/*
	 * If TCL_LIBRARY is set, search there.
	 */
	 
	objPtr = Tcl_NewStringObj(str, -1);
	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
	Tcl_DStringFree(&ds);
    }
    
    objPtr = TclGetLibraryPath();
    if (objPtr != NULL) {
        Tcl_ListObjAppendList(NULL, pathPtr, objPtr);
    }
    
    /*
     * lappend path [file join $env(EXT_FOLDER) \
     *      ":Tool Command Language:tcl[info version]"
     */

    str = TclGetEnv("EXT_FOLDER", &ds);
    if ((str != NULL) && (str[0] != '\0')) {
        objPtr = Tcl_NewStringObj(str, -1);
        if (str[strlen(str) - 1] != ':') {
            Tcl_AppendToObj(objPtr, ":", 1);
        }
        Tcl_AppendToObj(objPtr, "Tool Command Language:tcl" TCL_VERSION, -1);
	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
	Tcl_DStringFree(&ds);
    }    
    TclSetLibraryPath(pathPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpSetInitialEncodings --
 *
 *	Based on the locale, determine the encoding of the operating
 *	system and the default encoding for newly opened files.
 *
 *	Called at process initialization time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The Tcl library path is converted from native encoding to UTF-8.
 *
 *---------------------------------------------------------------------------
 */

void
TclpSetInitialEncodings()
{
    CONST char *encoding;
    Tcl_Obj *pathPtr;
    int fontId;
    
    fontId = 0;
    GetFinderFont(&fontId);
    encoding = TclMacGetFontEncoding(fontId);
    if (encoding == NULL) {
        encoding = "macRoman";
    }
    
    Tcl_SetSystemEncoding(NULL, encoding);
    
    /*
     * Until the system encoding was actually set, the library path was
     * actually in the native multi-byte encoding, and not really UTF-8
     * as advertised.  We cheated as follows:
     *
     * 1. It was safe to allow the Tcl_SetSystemEncoding() call to 
     * append the ASCII chars that make up the encoding's filename to 
     * the names (in the native encoding) of directories in the library 
     * path, since all Unix multi-byte encodings have ASCII in the
     * beginning.
     *
     * 2. To open the encoding file, the native bytes in the file name
     * were passed to the OS, without translating from UTF-8 to native,
     * because the name was already in the native encoding.
     *
     * Now that the system encoding was actually successfully set,
     * translate all the names in the library path to UTF-8.  That way,
     * next time we search the library path, we'll translate the names 
     * from UTF-8 to the system encoding which will be the native 
     * encoding.
     */

    pathPtr = TclGetLibraryPath();
    if (pathPtr != NULL) {
    	int i, objc;
	Tcl_Obj **objv;
	
	objc = 0;
	Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);
	for (i = 0; i < objc; i++) {
	    int length;
	    char *string;
	    Tcl_DString ds;

	    string = Tcl_GetStringFromObj(objv[i], &length);
	    Tcl_ExternalToUtfDString(NULL, string, length, &ds);
	    Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds), 
		    Tcl_DStringLength(&ds));
	    Tcl_DStringFree(&ds);
	}
    }

    /*
     * Keep the iso8859-1 encoding preloaded.  The IO package uses it for
     * gets on a binary channel.
     */

    Tcl_GetEncoding(NULL, "iso8859-1"); 
}   

/*
 *---------------------------------------------------------------------------
 *
 * TclpSetVariables --
 *
 *	Performs platform-specific interpreter initialization related to
 *	the tcl_library and tcl_platform variables, and other platform-
 *	specific things.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets "tcl_library" and "tcl_platform" Tcl variables.
 *
 *----------------------------------------------------------------------
 */

void
TclpSetVariables(interp)
    Tcl_Interp *interp;
{


    long int gestaltResult;
    int minor, major, objc;
    Tcl_Obj **objv;
    char versStr[2 * TCL_INTEGER_SPACE];
    char *str;
    Tcl_Obj *pathPtr;
    Tcl_DString ds;



    str = "no library";
    pathPtr = TclGetLibraryPath();

    if (pathPtr != NULL) {
        objc = 0;
        Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);
        if (objc > 0) {
            str = Tcl_GetStringFromObj(objv[0], NULL);
        }
    }
    Tcl_SetVar(interp, "tcl_library", str, TCL_GLOBAL_ONLY);
    
    if (pathPtr != NULL) {
        Tcl_SetVar2Ex(interp, "tcl_pkgPath", NULL, pathPtr, TCL_GLOBAL_ONLY);
    }
    

    Tcl_SetVar2(interp, "tcl_platform", "platform", "macintosh",
	    TCL_GLOBAL_ONLY);
    Tcl_SetVar2(interp, "tcl_platform", "os", "MacOS", TCL_GLOBAL_ONLY);
    Gestalt(gestaltSystemVersion, &gestaltResult);
    major = (gestaltResult & 0x0000FF00) >> 8;
    minor = (gestaltResult & 0x000000F0) >> 4;
    sprintf(versStr, "%d.%d", major, minor);
    Tcl_SetVar2(interp, "tcl_platform", "osVersion", versStr, TCL_GLOBAL_ONLY);
#if GENERATINGPOWERPC
    Tcl_SetVar2(interp, "tcl_platform", "machine", "ppc", TCL_GLOBAL_ONLY);
#else
    Tcl_SetVar2(interp, "tcl_platform", "machine", "68k", TCL_GLOBAL_ONLY);
#endif

    /*
     * Copy USER or LOGIN environment variable into tcl_platform(user)
     * These are set by SystemVariables in tclMacEnv.c

     */

    Tcl_DStringInit(&ds);
    str = TclGetEnv("USER", &ds);
    if (str == NULL) {


	str = TclGetEnv("LOGIN", &ds);
	if (str == NULL) {

	    str = "";








	}
    }
    Tcl_SetVar2(interp, "tcl_platform", "user", str, TCL_GLOBAL_ONLY);















    Tcl_DStringFree(&ds);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCheckStackSpace --
 *
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
 * Tcl_Init --
 *
 *	This procedure is typically invoked by Tcl_AppInit procedures
 *	to perform additional initialization for a Tcl interpreter,
 *	such as sourcing the "init.tcl" script.
 *
 * Results:
 *	Returns a standard Tcl completion code and sets interp->result
 *	if there is an error.
 *
 * Side effects:
 *	Depends on what's in the init.tcl script.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Init(
    Tcl_Interp *interp)		/* Interpreter to initialize. */
{
    static char initCmd[] =
	"if {[catch {source -rsrc Init}] != 0} {\n\
	if [file exists [info library]:init.tcl] {\n\
	    source [info library]:init.tcl\n\
	} else {\n\
	    set msg \"can't find Init resource or [info library]:init.tcl;\"\n\
	    append msg \" perhaps you need to\\ninstall Tcl or set your \"\n\
	    append msg \"TCL_LIBRARY environment variable?\"\n\
	    error $msg\n\
	}\n}\n\
        if {[catch {source -rsrc History}] != 0} {\n\
	if [file exists [info library]:history.tcl] {\n\
	    source [info library]:history.tcl\n\
	} else {\n\
	    set msg \"can't find History resource or [info library]:history.tcl;\"\n\
	    append msg \" perhaps you need to\\ninstall Tcl or set your \"\n\
	    append msg \"TCL_LIBRARY environment variable?\"\n\
	    error $msg\n\
	}\n}\n\
        if {[catch {source -rsrc Word}] != 0} {\n\
	if [file exists [info library]:word.tcl] {\n\
	    source [info library]:word.tcl\n\
	} else {\n\
	    set msg \"can't find Word resource or [info library]:word.tcl;\"\n\
	    append msg \" perhaps you need to\\ninstall Tcl or set your \"\n\
	    append msg \"TCL_LIBRARY environment variable?\"\n\
	    error $msg\n\
	}\n}";

    /*
     * For Macintosh applications the Init function may be contained in
     * the application resources.  If it exists we use it - otherwise we
     * look in the tcl_library directory.  Ditto for the history command.
     */
    





    return Tcl_Eval(interp, initCmd);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SourceRCFile --







|












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






|
>
>
>
>
>







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
 * Tcl_Init --
 *
 *	This procedure is typically invoked by Tcl_AppInit procedures
 *	to perform additional initialization for a Tcl interpreter,
 *	such as sourcing the "init.tcl" script.
 *
 * Results:
 *	Returns a standard Tcl completion code and sets the interp's result
 *	if there is an error.
 *
 * Side effects:
 *	Depends on what's in the init.tcl script.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Init(
    Tcl_Interp *interp)		/* Interpreter to initialize. */
{
    Tcl_Obj *pathPtr;




























    /*
     * For Macintosh applications the Init function may be contained in
     * the application resources.  If it exists we use it - otherwise we
     * look in the tcl_library directory.  Ditto for the history command.
     */

    pathPtr = TclGetLibraryPath();
    if (pathPtr == NULL) {
	pathPtr = Tcl_NewObj();
    }
    Tcl_SetVar2Ex(interp, "auto_path", NULL, pathPtr, TCL_GLOBAL_ONLY);
    return Tcl_Eval(interp, initCmd);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SourceRCFile --
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

            c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
            if (c != (Tcl_Channel) NULL) {
                Tcl_Close(NULL, c);
		if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
		    errChannel = Tcl_GetStdChannel(TCL_STDERR);
		    if (errChannel) {
			Tcl_Write(errChannel, interp->result, -1);
			Tcl_Write(errChannel, "\n", 1);
		    }
		}
	    }
	}
        Tcl_DStringFree(&temp);
    }

    fileName = Tcl_GetVar(interp, "tcl_rcRsrcName", TCL_GLOBAL_ONLY);

    if (fileName != NULL) {
	c2pstr(fileName);
	h = GetNamedResource('TEXT', (StringPtr) fileName);
	p2cstr((StringPtr) fileName);
	if (h != NULL) {
	    if (Tcl_MacEvalResource(interp, fileName, 0, NULL) != TCL_OK) {
		errChannel = Tcl_GetStdChannel(TCL_STDERR);
		if (errChannel) {
		    Tcl_Write(errChannel, interp->result, -1);
		    Tcl_Write(errChannel, "\n", 1);
		}
	    }
	    Tcl_ResetResult(interp);
	    ReleaseResource(h);
	}
    }
}







|
|

















|
|







660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694

            c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
            if (c != (Tcl_Channel) NULL) {
                Tcl_Close(NULL, c);
		if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
		    errChannel = Tcl_GetStdChannel(TCL_STDERR);
		    if (errChannel) {
			Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
			Tcl_WriteChars(errChannel, "\n", 1);
		    }
		}
	    }
	}
        Tcl_DStringFree(&temp);
    }

    fileName = Tcl_GetVar(interp, "tcl_rcRsrcName", TCL_GLOBAL_ONLY);

    if (fileName != NULL) {
	c2pstr(fileName);
	h = GetNamedResource('TEXT', (StringPtr) fileName);
	p2cstr((StringPtr) fileName);
	if (h != NULL) {
	    if (Tcl_MacEvalResource(interp, fileName, 0, NULL) != TCL_OK) {
		errChannel = Tcl_GetStdChannel(TCL_STDERR);
		if (errChannel) {
		    Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
		    Tcl_WriteChars(errChannel, "\n", 1);
		}
	    }
	    Tcl_ResetResult(interp);
	    ReleaseResource(h);
	}
    }
}

Changes to mac/tclMacInt.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tclMacInt.h --
 *
 *	Declarations of Macintosh specific shared variables and procedures.
 *
 * 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.
 *
 * SCCS: @(#) tclMacInt.h 1.24 97/09/09 16:22:01
 */

#ifndef _TCLMACINT
#define _TCLMACINT

#ifndef _TCL
#   include "tcl.h"





|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tclMacInt.h --
 *
 *	Declarations of Macintosh specific shared variables and procedures.
 *
 * Copyright (c) 1996-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: tclMacInt.h,v 1.1.2.3 1999/03/10 06:49:25 stanton Exp $
 */

#ifndef _TCLMACINT
#define _TCLMACINT

#ifndef _TCL
#   include "tcl.h"
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
#define TCL_RESOURCE_DONT_CLOSE  2

/*
 * Typedefs used by Macintosh parts of Tcl.
 */
typedef pascal void (*ExitToShellProcPtr)(void);

/*
 * Prototypes for functions found in the tclMacUtil.c compatability library.
 */

EXTERN int 	FSpGetDefaultDir _ANSI_ARGS_((FSSpecPtr theSpec));
EXTERN int 	FSpSetDefaultDir _ANSI_ARGS_((FSSpecPtr theSpec));
EXTERN OSErr 	FSpFindFolder _ANSI_ARGS_((short vRefNum, OSType folderType,
		    Boolean createFolder, FSSpec *spec));
EXTERN void	GetGlobalMouse _ANSI_ARGS_((Point *mouse));

/*
 * Prototypes of Mac only internal functions.
 */

EXTERN void	TclCreateMacEventSource _ANSI_ARGS_((void));
EXTERN int	TclMacConsoleInit _ANSI_ARGS_((void));
EXTERN void	TclMacExitHandler _ANSI_ARGS_((void));
EXTERN void	TclMacInitExitToShell _ANSI_ARGS_((int usePatch));
EXTERN OSErr	TclMacInstallExitToShellPatch _ANSI_ARGS_((
		    ExitToShellProcPtr newProc));
EXTERN int	TclMacOSErrorToPosixError _ANSI_ARGS_((int error));
EXTERN void	TclMacRemoveTimer _ANSI_ARGS_((void *timerToken));
EXTERN void *	TclMacStartTimer _ANSI_ARGS_((long ms));
EXTERN int	TclMacTimerExpired _ANSI_ARGS_((void *timerToken));
EXTERN int	TclMacRegisterResourceFork _ANSI_ARGS_((short fileRef, Tcl_Obj *tokenPtr,
                    int insert));	
EXTERN short	TclMacUnRegisterResourceFork _ANSI_ARGS_((char *tokenPtr, Tcl_Obj *resultPtr));	
		    
#pragma export reset

#endif /* _TCLMACINT */







<
<
<
<
<
<
<
<
<
<




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



42
43
44
45
46
47
48










49
50
51
52



53


54
55



56

57
58
59
60
#define TCL_RESOURCE_DONT_CLOSE  2

/*
 * Typedefs used by Macintosh parts of Tcl.
 */
typedef pascal void (*ExitToShellProcPtr)(void);











/*
 * Prototypes of Mac only internal functions.
 */




EXTERN char *	TclMacGetFontEncoding _ANSI_ARGS_((int fontId));


EXTERN int	TclMacHaveThreads(void);




#include "tclIntPlatDecls.h"

    
#pragma export reset

#endif /* _TCLMACINT */

Changes to mac/tclMacInterupt.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclMacInterupt.c --
 *
 *	This file contains routines that deal with the Macintosh's low level
 *	time manager.  This code provides a better resolution timer than what
 *	can be provided by WaitNextEvent.  
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacInterupt.c 1.16 96/12/12 19:22:01
 */

#include "tclInt.h"
#include "tclMacInt.h"
#include <LowMem.h>
#include <Processes.h>
#include <Timer.h>












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclMacInterupt.c --
 *
 *	This file contains routines that deal with the Macintosh's low level
 *	time manager.  This code provides a better resolution timer than what
 *	can be provided by WaitNextEvent.  
 *
 * Copyright (c) 1996 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: tclMacInterupt.c,v 1.1.2.1 1998/09/24 23:59:13 stanton Exp $
 */

#include "tclInt.h"
#include "tclMacInt.h"
#include <LowMem.h>
#include <Processes.h>
#include <Timer.h>

Changes to mac/tclMacLibrary.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *	file.
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacLibrary.c 1.6 97/11/20 19:29:42
 */

/*
 * Here is another place that we are using the old routine names...
 */
 
#define OLDROUTINENAMES 1







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *	file.
 *
 * Copyright (c) 1996 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: tclMacLibrary.c,v 1.1.2.1 1998/09/24 23:59:13 stanton Exp $
 */

/*
 * Here is another place that we are using the old routine names...
 */
 
#define OLDROUTINENAMES 1

Changes to mac/tclMacLibrary.r.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclMacLibrary.r --
 *
 *	This file creates resources used by the Tcl shared library.
 *	Many thanks go to "Jay Lieske, Jr." <[email protected]> who
 *	wrote the initial version of this file.
 *
 * 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.
 *
 * SCCS: @(#) tclMacLibrary.r 1.5 97/09/23 12:53:28
 */

#include <Types.r>
#include <SysTypes.r>

/*
 * The folowing include and defines help construct












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclMacLibrary.r --
 *
 *	This file creates resources used by the Tcl shared library.
 *	Many thanks go to "Jay Lieske, Jr." <[email protected]> who
 *	wrote the initial version of this file.
 *
 * 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: tclMacLibrary.r,v 1.1.2.2 1998/09/24 23:59:13 stanton Exp $
 */

#include <Types.r>
#include <SysTypes.r>

/*
 * The folowing include and defines help construct
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
 * require some predetermined file structure - all needed Tcl "files"
 * are located within the application.  To source a file for the
 * resource fork the source command has been modified to support
 * sourcing from resources.  In the below case "source -rsrc {Init}"
 * will load the TEXT resource named "Init".
 */

read 'TEXT' (TCL_LIBRARY_RESOURCES, "Init", purgeable) "::library:init.tcl";
read 'TEXT' (TCL_LIBRARY_RESOURCES + 1, "History", purgeable) "::library:history.tcl";
read 'TEXT' (TCL_LIBRARY_RESOURCES + 2, "Word", purgeable,preload) "::library:word.tcl";

/*
 * The following are icons for the shared library.
 */

data 'icl4' (2000, "Tcl Shared Library", purgeable) {
	$"0FFF FFFF FFFF FFFF FFFF FFFF FFFF 0000"







|
<
<







137
138
139
140
141
142
143
144


145
146
147
148
149
150
151
 * require some predetermined file structure - all needed Tcl "files"
 * are located within the application.  To source a file for the
 * resource fork the source command has been modified to support
 * sourcing from resources.  In the below case "source -rsrc {Init}"
 * will load the TEXT resource named "Init".
 */

#include "tclMacTclCode.r"



/*
 * The following are icons for the shared library.
 */

data 'icl4' (2000, "Tcl Shared Library", purgeable) {
	$"0FFF FFFF FFFF FFFF FFFF FFFF FFFF 0000"

Changes to mac/tclMacLoad.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tclMacLoad.c --
 *
 *	This procedure provides a version of the TclLoadFile for use
 *	on the Macintosh.  This procedure will only work with systems 
 *	that use the Code Fragment Manager.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacLoad.c 1.20 97/11/20 18:39:20
 */

#include <CodeFragments.h>
#include <Errors.h>
#include <Resources.h>
#include <Strings.h>
#include <FSpCompat.h>







|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tclMacLoad.c --
 *
 *	This procedure provides a version of the TclLoadFile for use
 *	on the Macintosh.  This procedure will only work with systems 
 *	that use the Code Fragment Manager.
 *
 * 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: tclMacLoad.c,v 1.1.2.2 1998/09/24 23:59:13 stanton Exp $
 */

#include <CodeFragments.h>
#include <Errors.h>
#include <Resources.h>
#include <Strings.h>
#include <FSpCompat.h>
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
 *
 *	This procedure is called to carry out dynamic loading of binary
 *	code for the Macintosh.  This implementation is based on the
 *	Code Fragment Manager & will not work on other systems.
 *
 * Results:
 *	The result is TCL_ERROR, and an error message is left in
 *	interp->result.
 *
 * Side effects:
 *	New binary code is loaded.
 *
 *----------------------------------------------------------------------
 */

int
TclLoadFile(
    Tcl_Interp *interp,		/* Used for error reporting. */
    char *fileName,		/* Name of the file containing the desired
				 * code. */
    char *sym1, char *sym2,	/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr,
    Tcl_PackageInitProc **proc2Ptr)
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */



{
    CFragConnectionID connID;
    Ptr dummy;
    OSErr err;
    CFragSymbolClass symClass;
    FSSpec fileSpec;
    short fragFileRef, saveFileRef;
    Handle fragResource;
    UInt32 offset = 0;
    UInt32 length = kCFragGoesToEOF;
    char packageName[255];
    Str255 errName;


    
    /*
     * First thing we must do is infer the package name from the sym1
     * variable.  This is kind of dumb since the caller actually knows
     * this value, it just doesn't give it to us.
     */
    strcpy(packageName, sym1);
    *packageName = (char) tolower(*packageName);
    packageName[strlen(packageName) - 5] = NULL;
    

    err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);


    if (err != noErr) {
	interp->result = "could not locate shared library";
	return TCL_ERROR;
    }
    
    /*
     * See if this fragment has a 'cfrg' resource.  It will tell us were
     * to look for the fragment in the file.  If it doesn't exist we will
     * assume we have a ppc frag using the whole data fork.  If it does
     * exist we find the frag that matches the one we are looking for and
     * get the offset and size from the resource.
     */

    saveFileRef = CurResFile();
    SetResLoad(false);
    fragFileRef = FSpOpenResFile(&fileSpec, fsRdPerm);
    SetResLoad(true);
    if (fragFileRef != -1) {
	UseResFile(fragFileRef);
	fragResource = Get1Resource(kCFragResourceType, kCFragResourceID);







|








|






|


>
>
>












>
>







|
|

>

>
>

|




|





>







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
 *
 *	This procedure is called to carry out dynamic loading of binary
 *	code for the Macintosh.  This implementation is based on the
 *	Code Fragment Manager & will not work on other systems.
 *
 * Results:
 *	The result is TCL_ERROR, and an error message is left in
 *	the interp's result.
 *
 * Side effects:
 *	New binary code is loaded.
 *
 *----------------------------------------------------------------------
 */

int
TclpLoadFile(
    Tcl_Interp *interp,		/* Used for error reporting. */
    char *fileName,		/* Name of the file containing the desired
				 * code. */
    char *sym1, char *sym2,	/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr,
    Tcl_PackageInitProc **proc2Ptr,
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */
    ClientData *clientDataPtr)	/* Filled with token for dynamically loaded
				 * file which will be passed back to 
				 * TclpUnloadFile() to unload the file. */
{
    CFragConnectionID connID;
    Ptr dummy;
    OSErr err;
    CFragSymbolClass symClass;
    FSSpec fileSpec;
    short fragFileRef, saveFileRef;
    Handle fragResource;
    UInt32 offset = 0;
    UInt32 length = kCFragGoesToEOF;
    char packageName[255];
    Str255 errName;
    Tcl_DString ds;
    char *native;
    
    /*
     * First thing we must do is infer the package name from the sym1
     * variable.  This is kind of dumb since the caller actually knows
     * this value, it just doesn't give it to us.
     */
    strcpy(packageName, sym1);
    Tcl_UtfToLower(packageName);
    *(Tcl_UtfAtIndex(packageName, Tcl_NumUtfChars(packageName, -1) - 5)) = 0;
    
    native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
    err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);
    Tcl_DStringFree(&ds);
    
    if (err != noErr) {
	Tcl_SetResult(interp, "could not locate shared library", TCL_STATIC);
	return TCL_ERROR;
    }
    
    /*
     * See if this fragment has a 'cfrg' resource.  It will tell us where
     * to look for the fragment in the file.  If it doesn't exist we will
     * assume we have a ppc frag using the whole data fork.  If it does
     * exist we find the frag that matches the one we are looking for and
     * get the offset and size from the resource.
     */
     
    saveFileRef = CurResFile();
    SetResLoad(false);
    fragFileRef = FSpOpenResFile(&fileSpec, fsRdPerm);
    SetResLoad(true);
    if (fragFileRef != -1) {
	UseResFile(fragFileRef);
	fragResource = Get1Resource(kCFragResourceType, kCFragResourceID);
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
	return TCL_ERROR;
    }
    
    c2pstr(sym1);
    err = FindSymbol(connID, (StringPtr) sym1, (Ptr *) proc1Ptr, &symClass);
    p2cstr((StringPtr) sym1);
    if (err != fragNoErr || symClass == kDataCFragSymbol) {
	interp->result =
	    "could not find Initialization routine in library";

	return TCL_ERROR;
    }

    c2pstr(sym2);
    err = FindSymbol(connID, (StringPtr) sym2, (Ptr *) proc2Ptr, &symClass);
    p2cstr((StringPtr) sym2);
    if (err != fragNoErr || symClass == kDataCFragSymbol) {
	*proc2Ptr = NULL;
    }
    


    return TCL_OK;



























}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *







|
|
>










>
>

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







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
	return TCL_ERROR;
    }
    
    c2pstr(sym1);
    err = FindSymbol(connID, (StringPtr) sym1, (Ptr *) proc1Ptr, &symClass);
    p2cstr((StringPtr) sym1);
    if (err != fragNoErr || symClass == kDataCFragSymbol) {
	Tcl_SetResult(interp,
		"could not find Initialization routine in library",
		TCL_STATIC);
	return TCL_ERROR;
    }

    c2pstr(sym2);
    err = FindSymbol(connID, (StringPtr) sym2, (Ptr *) proc2Ptr, &symClass);
    p2cstr((StringPtr) sym2);
    if (err != fragNoErr || symClass == kDataCFragSymbol) {
	*proc2Ptr = NULL;
    }
    
    *clientDataPtr = (ClientData) connID;
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpUnloadFile --
 *
 *	Unloads a dynamically loaded binary code file from memory.
 *	Code pointers in the formerly loaded file are no longer valid
 *	after calling this function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Does nothing.  Can anything be done?
 *
 *----------------------------------------------------------------------
 */

void
TclpUnloadFile(clientData)
    ClientData clientData;	/* ClientData returned by a previous call
				 * to TclpLoadFile().  The clientData is 
				 * a token that represents the loaded 
				 * file. */
{
}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *

Changes to mac/tclMacMSLPrefix.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclMacMSLPrefix.h --
 *
 *  A wrapper for the MSL ansi_prefix.mac.h file.  This just turns export on
 *  after including the MSL prefix file, so we can export symbols from the MSL
 *  and through the Tcl shared libraries
 *  
 *
 * 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.
 *
 * SCCS: @(#) tclMac.h 1.2 97/03/18 10:58:49
 */

#include <ansi_prefix.mac.h>
/*
 * "export" is a MetroWerks specific pragma.  It flags the linker that  
 * any symbols that are defined when this pragma is on will be exported 
 * to shared libraries that link with this library.













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclMacMSLPrefix.h --
 *
 *  A wrapper for the MSL ansi_prefix.mac.h file.  This just turns export on
 *  after including the MSL prefix file, so we can export symbols from the MSL
 *  and through the Tcl shared libraries
 *  
 *
 * 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: tclMacMSLPrefix.h,v 1.1.2.2 1998/09/24 23:59:13 stanton Exp $
 */

#include <ansi_prefix.mac.h>
/*
 * "export" is a MetroWerks specific pragma.  It flags the linker that  
 * any symbols that are defined when this pragma is on will be exported 
 * to shared libraries that link with this library.

Changes to mac/tclMacMath.h.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *	are passed around and used, they will crash hard on the 68K.
 *
 * 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.
 *
 * SCCS: @(#) tclMacMath.h 1.2 97/07/28 11:04:02
 */

#ifndef _TCLMACMATH
#define _TCLMACMATH

#include <math.h>








|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *	are passed around and used, they will crash hard on the 68K.
 *
 * 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: tclMacMath.h,v 1.1.2.1 1998/09/24 23:59:13 stanton Exp $
 */

#ifndef _TCLMACMATH
#define _TCLMACMATH

#include <math.h>

Changes to mac/tclMacNotify.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
/* 
 * tclMacNotify.c --
 *
 *	This file contains Macintosh-specific procedures for the notifier,
 *	which is the lowest-level part of the Tcl event loop.  This file
 *	works together with ../generic/tclNotify.c.
 *




 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacNotify.c 1.36 97/05/07 19:09:29
 */

#include "tclInt.h"
#include "tclPort.h"
#include "tclMac.h"
#include "tclMacInt.h"
#include <signal.h>
#include <Events.h>
#include <LowMem.h>
#include <Processes.h>
#include <Timer.h>



/* 
 * This is necessary to work around a bug in Apple's Universal header files
 * for the CFM68K libraries.
 */








>
>
>
>





|











>







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
/* 
 * tclMacNotify.c --
 *
 *	This file contains Macintosh-specific procedures for the notifier,
 *	which is the lowest-level part of the Tcl event loop.  This file
 *	works together with ../generic/tclNotify.c.
 *
 *	The Mac notifier only polls for system and OS events, so it is process
 *	wide, rather than thread specific.  However, this means that the convert
 *	event proc will have to arbitrate which events go to which threads.
 *
 * Copyright (c) 1995-1996 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: tclMacNotify.c,v 1.1.2.4 1999/03/24 04:25:16 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"
#include "tclMac.h"
#include "tclMacInt.h"
#include <signal.h>
#include <Events.h>
#include <LowMem.h>
#include <Processes.h>
#include <Timer.h>
#include <Threads.h>


/* 
 * This is necessary to work around a bug in Apple's Universal header files
 * for the CFM68K libraries.
 */

77
78
79
80
81
82
83































































































84
85
86

87
88
89
90
91
92
93
static void		InitNotifier _ANSI_ARGS_((void));
static void		NotifierExitHandler _ANSI_ARGS_((
			    ClientData clientData));

/*
 *----------------------------------------------------------------------
 *































































































 * InitNotifier --
 *
 *	Initializes the notifier structure.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new exit handler.
 *







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


|
>







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
static void		InitNotifier _ANSI_ARGS_((void));
static void		NotifierExitHandler _ANSI_ARGS_((
			    ClientData clientData));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_InitNotifier --
 *
 *	Initializes the platform specific notifier state.  There is no thread
 *	specific platform notifier on the Mac, so this really doesn't do 
 *	anything.  However, we need to return the ThreadID, since the generic
 *	notifier hands this back to us in AlertThread.
 *
 * Results:
 *	Returns the threadID for this thread.  
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

ClientData
Tcl_InitNotifier()
{
    
#ifdef TCL_THREADS
    ThreadID curThread;
    if (TclMacHaveThreads()) {
        GetCurrentThread(&curThread);
        return (ClientData) curThread;
    } else {
        return NULL;
    }
#else
    return NULL;
#endif

}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FinalizeNotifier --
 *
 *	This function is called to cleanup the notifier state before
 *	a thread is terminated.  There is no platform thread specific
 *	notifier, so this does nothing.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_FinalizeNotifier(clientData)
    ClientData clientData;	/* Pointer to notifier data. */
{
    /* Nothing to do on the Mac */
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AlertNotifier --
 *
 *	Wake up the specified notifier from any thread. This routine
 *	is called by the platform independent notifier code whenever
 *	the Tcl_ThreadAlert routine is called.  This routine is
 *	guaranteed not to be called on a given notifier after
 *	Tcl_FinalizeNotifier is called for that notifier.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Calls YieldToThread from this thread.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AlertNotifier(clientData)
    ClientData clientData;	/* Pointer to thread data. */
{

#ifdef TCL_THREADS
    if (TclMacHaveThreads()) {
        YieldToThread((ThreadID) clientData);
    }
#endif

}

/*
 *----------------------------------------------------------------------
 *
 * InitNotifier --
 *
 *	Initializes the notifier structure.  Note - this function is never
 *	used.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new exit handler.
 *
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118

/*
 *----------------------------------------------------------------------
 *
 * NotifierExitHandler --
 *
 *	This function is called to cleanup the notifier state before
 *	Tcl is unloaded.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *







|
>







205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

/*
 *----------------------------------------------------------------------
 *
 * NotifierExitHandler --
 *
 *	This function is called to cleanup the notifier state before
 *	Tcl is unloaded.  This function is never used, since InitNotifier
 *	isn't either.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
242
243
244
245
246
247
248























249
250
251
252
253
254
255
	notifier.timerActive = 1;
    }
}

/*
 *----------------------------------------------------------------------
 *























 * Tcl_WaitForEvent --
 *
 *	This function is called by Tcl_DoOneEvent to wait for new
 *	events on the message queue.  If the block time is 0, then
 *	Tcl_WaitForEvent just polls the event queue without blocking.
 *
 * Results:







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







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
	notifier.timerActive = 1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ServiceModeHook --
 *
 *	This function is invoked whenever the service mode changes.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ServiceModeHook(mode)
    int mode;			/* Either TCL_SERVICE_ALL, or
				 * TCL_SERVICE_NONE. */
{
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_WaitForEvent --
 *
 *	This function is called by Tcl_DoOneEvent to wait for new
 *	events on the message queue.  If the block time is 0, then
 *	Tcl_WaitForEvent just polls the event queue without blocking.
 *
 * Results:
342
343
344
345
346
347
348











349
350
351
352
353
354
355
		if ((*notifier.eventProcPtr)(&macEvent) == true) {
		    found = 1;
		}
	    }
	}
    }
    TclMacRemoveTimer(timerToken);











    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Sleep --







>
>
>
>
>
>
>
>
>
>
>







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
		if ((*notifier.eventProcPtr)(&macEvent) == true) {
		    found = 1;
		}
	    }
	}
    }
    TclMacRemoveTimer(timerToken);
    
    /*
     * Yield time to nay other thread at this point.  If we find that the
     * apps thrash too switching between threads, we can put a timer here,
     * and only yield when the timer fires.
     */
     
    if (TclMacHaveThreads()) {
        YieldToAnyThread();
    }
    
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Sleep --
377
378
379
380
381
382
383


384
385
386
387
388
389
390
391
    if (ms <= 0) {
	return;
    }
    
    timerToken = TclMacStartTimer((long) ms);
    while (1) {
	WaitNextEvent(0, &dummy, (ms / 16.66) + 1, NULL);


	
	if (TclMacTimerExpired(timerToken)) {
	    break;
	}
    }
    TclMacRemoveTimer(timerToken);
}








>
>
|







513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
    if (ms <= 0) {
	return;
    }
    
    timerToken = TclMacStartTimer((long) ms);
    while (1) {
	WaitNextEvent(0, &dummy, (ms / 16.66) + 1, NULL);
        if (TclMacHaveThreads()) {
	    YieldToAnyThread();
	}
	if (TclMacTimerExpired(timerToken)) {
	    break;
	}
    }
    TclMacRemoveTimer(timerToken);
}


Changes to mac/tclMacOSA.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * Copyright (c) 1996 Lucent Technologies and Jim Ingham
 * 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.
 *
 * SCCS: @(#) tclMacOSA.c 1.7 97/06/18 14:29:58
 */

#define MAC_TCL

#include <Aliases.h>
#include <string.h>
#include <AppleEvents.h>







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * Copyright (c) 1996 Lucent Technologies and Jim Ingham
 * 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: tclMacOSA.c,v 1.1.2.2 1998/09/24 23:59:14 stanton Exp $
 */

#define MAC_TCL

#include <Aliases.h>
#include <string.h>
#include <AppleEvents.h>
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
{
    static unsigned short contextIndex = 0;
    tclOSAContext *contextStruct;
    Tcl_HashEntry *hashEntry;
    int newPtr;

    if (contextName == NULL) {
	contextName = ckalloc(24 * sizeof(char));
	sprintf(contextName, "OSAContext%d", contextIndex++);
    } else if (*contextName == '\0') {
	sprintf(contextName, "OSAContext%d", contextIndex++);
    }
	
    hashEntry = Tcl_CreateHashEntry(&theComponent->contextTable,
	    contextName, &newPtr);	







|







1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
{
    static unsigned short contextIndex = 0;
    tclOSAContext *contextStruct;
    Tcl_HashEntry *hashEntry;
    int newPtr;

    if (contextName == NULL) {
	contextName = ckalloc(16 + TCL_INTEGER_SPACE);
	sprintf(contextName, "OSAContext%d", contextIndex++);
    } else if (*contextName == '\0') {
	sprintf(contextName, "OSAContext%d", contextIndex++);
    }
	
    hashEntry = Tcl_CreateHashEntry(&theComponent->contextTable,
	    contextName, &newPtr);	
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
    char *scriptName,
    char *fileName)
{
    Handle resHandle;
    Str255 rezName;
    int result = TCL_OK;
    short saveRef, fileRef = -1;
    char idStr[64];
    FSSpec fileSpec;
    Tcl_DString buffer;
    char *nativeName;
    OSErr myErr = noErr;
    OSAID scriptID;
    Size scriptSize;
    AEDesc scriptData;







|







2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
    char *scriptName,
    char *fileName)
{
    Handle resHandle;
    Str255 rezName;
    int result = TCL_OK;
    short saveRef, fileRef = -1;
    char idStr[16 + TCL_INTEGER_SPACE];
    FSSpec fileSpec;
    Tcl_DString buffer;
    char *nativeName;
    OSErr myErr = noErr;
    OSAID scriptID;
    Size scriptSize;
    AEDesc scriptData;
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
    char *fileName,
    OSAID *resultID)
{
    Handle sourceData;
    Str255 rezName;
    int result = TCL_OK;
    short saveRef, fileRef = -1;
    char idStr[64];
    FSSpec fileSpec;
    Tcl_DString buffer;
    char *nativeName;

    saveRef = CurResFile();
	
    if (fileName != NULL) {







|







2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
    char *fileName,
    OSAID *resultID)
{
    Handle sourceData;
    Str255 rezName;
    int result = TCL_OK;
    short saveRef, fileRef = -1;
    char idStr[16 + TCL_INTEGER_SPACE];
    FSSpec fileSpec;
    Tcl_DString buffer;
    char *nativeName;

    saveRef = CurResFile();
	
    if (fileName != NULL) {

Changes to mac/tclMacOSA.r.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tkMacOSA.r --
 *
 *	This file creates resources used by the AppleScript package.
 *
 * 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.
 *
 * SCCS: @(#) tclMacOSA.r 1.6 97/11/20 18:40:02
 */

#include <Types.r>
#include <SysTypes.r>

/*
 * The folowing include and defines help construct










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tkMacOSA.r --
 *
 *	This file creates resources used by the AppleScript package.
 *
 * 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: tclMacOSA.r,v 1.1.2.1 1998/09/24 23:59:14 stanton Exp $
 */

#include <Types.r>
#include <SysTypes.r>

/*
 * The folowing include and defines help construct

Changes to mac/tclMacPanic.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 
 * tclMacPanic.c --
 *
 *	Source code for the "panic" library procedure used in "Simple Shell";
 *	other Mac applications will probably override this with a more robust
 *	application-specific panic procedure.
 *
 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacPanic.c 1.14 97/11/20 18:41:06
 */


#include <Events.h>
#include <Controls.h>
#include <Windows.h>
#include <TextEdit.h>













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 
 * tclMacPanic.c --
 *
 *	Source code for the "panic" library procedure used in "Simple Shell";
 *	other Mac applications will probably override this with a more robust
 *	application-specific panic procedure.
 *
 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
 * Copyright (c) 1995-1996 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: tclMacPanic.c,v 1.1.2.1 1998/09/24 23:59:14 stanton Exp $
 */


#include <Events.h>
#include <Controls.h>
#include <Windows.h>
#include <TextEdit.h>

Changes to mac/tclMacPort.h.

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
/*
 * tclMacPort.h --
 *
 *	This header file handles porting issues that occur because of
 *	differences between the Mac and Unix. It should be the only
 *	file that contains #ifdefs to handle different flavors of OS.
 *
 * 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.
 *
 * SCCS: @(#) tclMacPort.h 1.75 97/08/11 10:18:07
 */


#ifndef _MACPORT
#define _MACPORT

#ifndef _TCL
#include "tcl.h"
#endif








#include "tclErrno.h"
#include <float.h>

/* Includes */
#ifdef THINK_C
	/*
	 * The Symantic C code has not been tested
	 * and probably will not work.
	 */
#   include <pascal.h>
#   include <posix.h>
#   include <string.h>
#   include <fcntl.h>
#   include <pwd.h>
#   include <sys/param.h>
#   include <sys/types.h>
#   include <sys/stat.h>
#   include <unistd.h>
#elif defined(__MWERKS__)
#   include <time.h>
#   include <unistd.h>

/*
 * The following definitions are usually found if fcntl.h.
 * However, MetroWerks has screwed that file up a couple of times
 * and all we need are the defines.
 */

#define O_RDWR	  0x0		/* open the file in read/write mode */
#define O_RDONLY  0x1		/* open the file in read only mode */
#define O_WRONLY  0x2		/* open the file in write only mode */
#define O_APPEND  0x0100	/* open the file in append mode */
#define O_CREAT	  0x0200	/* create the file if it doesn't exist */
#define O_EXCL	  0x0400	/* if the file exists don't create it again */
#define O_TRUNC	  0x0800	/* truncate the file after opening it */

/*
 * MetroWerks stat.h file is rather weak.  The defines
 * after the include are needed to fill in the missing
 * defines.
 */

#   include <stat.h>
#   ifndef S_IFIFO
#	define   S_IFIFO	0x0100
#   endif
#   ifndef S_IFBLK
#	define   S_IFBLK	0x0600
#   endif
#   ifndef S_ISLNK
#	define   S_ISLNK(m)	(((m)&(S_IFMT)) == (S_IFLNK))
#   endif
#   ifndef S_ISSOCK
#	define   S_ISSOCK(m)	(((m)&(S_IFMT)) == (S_IFSOCK))
#   endif
#   ifndef S_IRWXU
#	define	S_IRWXU	00007		/* read, write, execute: owner */
#   	define	S_IRUSR	00004		/* read permission: owner */
#   	define	S_IWUSR	00002		/* write permission: owner */
#   	define	S_IXUSR	00001		/* execute permission: owner */
#   	define	S_IRWXG	00007		/* read, write, execute: group */
#   	define	S_IRGRP	00004		/* read permission: group */
#   	define	S_IWGRP	00002		/* write permission: group */
#   	define	S_IXGRP	00001		/* execute permission: group */
#   	define	S_IRWXO	00007		/* read, write, execute: other */
#   	define	S_IROTH	00004		/* read permission: other */
#   	define	S_IWOTH	00002		/* write permission: other */
#   	define	S_IXOTH	00001		/* execute permission: other */
#   endif

#   define isatty(arg) 1

/* 
 * Defines used by access function.  This function is provided
 * by Mac Tcl as the function TclMacAccess.
 */
 
#   define	F_OK		0	/* test for existence of file */
#   define	X_OK		0x01	/* test for execute or search permission */
#   define	W_OK		0x02	/* test for write permission */
#   define	R_OK		0x04	/* test for read permission */



















#endif

/*
 * waitpid doesn't work on a Mac - the following makes
 * Tcl compile without errors.  These would normally
 * be defined in sys/wait.h on UNIX systems.
 */


#define WNOHANG 1
#define WIFSTOPPED(stat) (1)
#define WIFSIGNALED(stat) (1)
#define WIFEXITED(stat) (1)
#define WIFSTOPSIG(stat) (1)
#define WIFTERMSIG(stat) (1)
#define WIFEXITSTATUS(stat) (1)
#define WEXITSTATUS(stat) (1)
#define WTERMSIG(status) (1)
#define WSTOPSIG(status) (1)













/*
 * Define "NBBY" (number of bits per byte) if it's not already defined.
 */

#ifndef NBBY
#   define NBBY 8
#endif

/*
 * These functions always return dummy values on Mac.
 */
#ifndef geteuid
#   define geteuid() 1
#endif
#ifndef getpid
#   define getpid() -1
#endif




#define NO_SYS_ERRLIST
#define WAIT_STATUS_TYPE int


/*



 * Make sure that MAXPATHLEN is defined.

 */




#ifndef MAXPATHLEN
#   ifdef PATH_MAX
#       define MAXPATHLEN PATH_MAX
#   else
#       define MAXPATHLEN 2048
#   endif
#endif

/*


 * The following functions are declared in tclInt.h but don't do anything

 * on Macintosh systems.
 */











#define TclSetSystemEnv(a,b)


/*
 * Many signals are not supported on the Mac and are thus not defined in
 * <signal.h>.  They are defined here so that Tcl will compile with less

 * modification.
  */

#ifndef SIGQUIT



#define SIGQUIT 300
#endif

#ifndef SIGPIPE





#define SIGPIPE 13
#endif



#ifndef SIGHUP
#define SIGHUP  100
#endif

extern char **environ;

/*
 * Prototypes needed for compatability
 */

EXTERN int 	TclMacCreateEnv _ANSI_ARGS_((void));
EXTERN int	strncasecmp _ANSI_ARGS_((CONST char *s1,
			    CONST char *s2, size_t n));

/*
 * The following declarations belong in tclInt.h, but depend on platform
 * specific types (e.g. struct tm).
 */

EXTERN struct tm *	TclpGetDate _ANSI_ARGS_((const time_t *tp,
			    int useGMT));
EXTERN size_t		TclStrftime _ANSI_ARGS_((char *s, size_t maxsize,
			    const char *format, const struct tm *t));

#define tzset()
#define TclpGetPid(pid)	    ((unsigned long) (pid))

/*
 * The following prototypes and defines replace the Macintosh version
 * of the POSIX functions "stat" and "access".  The various compilier 
 * vendors don't implement this function well nor consistantly.
 */
EXTERN int TclMacStat _ANSI_ARGS_((char *path, struct stat *buf));
#define stat(path, bufPtr) TclMacStat(path, bufPtr)
#define lstat(path, bufPtr) TclMacStat(path, bufPtr)
EXTERN int TclMacAccess _ANSI_ARGS_((const char *filename, int mode));
#define access(path, mode) TclMacAccess(path, mode)
EXTERN FILE * TclMacFOpenHack _ANSI_ARGS_((const char *path,
	const char *mode));
#define fopen(path, mode) TclMacFOpenHack(path, mode)
EXTERN int TclMacReadlink _ANSI_ARGS_((char *path, char *buf, int size));
#define readlink(fileName, buffer, size) TclMacReadlink(fileName, buffer, size)
#ifdef TCL_TEST
#define chmod(path, mode) TclMacChmod(path, mode)
EXTERN int	TclMacChmod(char *path, int mode);
#endif

/*
 * Defines for Tcl internal commands that aren't really needed on
 * the Macintosh.  They all act as no-ops.
 */
#define TclCreateCommandChannel(out, in, err, num, pidPtr)	NULL
#define TclClosePipeFile(x)

/*
 * These definitions force putenv & company to use the version
 * supplied with Tcl.
 */
#ifndef putenv
#   define unsetenv	TclUnsetEnv
#   define putenv	Tcl_PutEnv
#   define setenv	TclSetEnv
void	TclSetEnv(CONST char *name, CONST char *value);
int	Tcl_PutEnv(CONST char *string);
void	TclUnsetEnv(CONST char *name);
#endif

/*
 * The default platform eol translation on Mac is TCL_TRANSLATE_CR:


 */

#define	TCL_PLATFORM_TRANSLATION	TCL_TRANSLATE_CR

/*
 * Declare dynamic loading extension macro.
 */

#define TCL_SHLIB_EXT ".shlb"

/*


 * The following define should really be in tclInt.h, but tclInt.h does
 * not include tclPort.h, which includes the "struct stat" definition.
 */

EXTERN int              TclpSameFile _ANSI_ARGS_((char *file1, char *file2,
			    struct stat *sourceStatBufPtr, 
		            struct stat *destStatBufPtr)) ;


#endif /* _MACPORT */












|

>




|
|


>
>
>
>
>
>
>



<

















>





>
|
|
|
|
|
|
|






>


|


|


|


|


|
|
|
|
|
|
|
|
|
|
|
|


|



|


|
|
|
|

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








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



















>
>
>
|
<
>


>
>
>
|
>


>
>
>
|
<
<
<
|
<
<


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

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

<
>
>
>
>
>
|
<

>
>
|
|

<
<





<



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














|
>
>


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


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

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197



198


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221


222
223
224
225
226
227
228
229
230

231

232
233
234
235
236
237

238
239
240
241
242
243


244
245
246
247
248

249
250
251








































252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272



273
274
275

276
277
278
279

280



281
282
283
/*
 * tclMacPort.h --
 *
 *	This header file handles porting issues that occur because of
 *	differences between the Mac and Unix. It should be the only
 *	file that contains #ifdefs to handle different flavors of OS.
 *
 * 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: tclMacPort.h,v 1.1.2.5 1999/03/11 01:50:32 stanton Exp $
 */


#ifndef _MACPORT
#define _MACPORT

#ifndef _TCLINT
#   include "tclInt.h"
#endif

/*
 *---------------------------------------------------------------------------
 * The following sets of #includes and #ifdefs are required to get Tcl to
 * compile on the macintosh.
 *---------------------------------------------------------------------------
 */

#include "tclErrno.h"
#include <float.h>


#ifdef THINK_C
	/*
	 * The Symantic C code has not been tested
	 * and probably will not work.
	 */
#   include <pascal.h>
#   include <posix.h>
#   include <string.h>
#   include <fcntl.h>
#   include <pwd.h>
#   include <sys/param.h>
#   include <sys/types.h>
#   include <sys/stat.h>
#   include <unistd.h>
#elif defined(__MWERKS__)
#   include <time.h>
#   include <unistd.h>

/*
 * The following definitions are usually found if fcntl.h.
 * However, MetroWerks has screwed that file up a couple of times
 * and all we need are the defines.
 */

#   define O_RDWR	  	0x0	/* open the file in read/write mode */
#   define O_RDONLY  		0x1	/* open the file in read only mode */
#   define O_WRONLY  		0x2	/* open the file in write only mode */
#   define O_APPEND  		0x0100	/* open the file in append mode */
#   define O_CREAT	  	0x0200	/* create the file if it doesn't exist */
#   define O_EXCL	  	0x0400	/* if the file exists don't create it again */
#   define O_TRUNC	  	0x0800	/* truncate the file after opening it */

/*
 * MetroWerks stat.h file is rather weak.  The defines
 * after the include are needed to fill in the missing
 * defines.
 */

#   include <stat.h>
#   ifndef S_IFIFO
#	define S_IFIFO		0x0100
#   endif
#   ifndef S_IFBLK
#	define S_IFBLK		0x0600
#   endif
#   ifndef S_ISLNK
#	define S_ISLNK(m)	(((m)&(S_IFMT)) == (S_IFLNK))
#   endif
#   ifndef S_ISSOCK
#	define S_ISSOCK(m)	(((m)&(S_IFMT)) == (S_IFSOCK))
#   endif
#   ifndef S_IRWXU
#	define S_IRWXU		00007	/* read, write, execute: owner */
#   	define S_IRUSR		00004	/* read permission: owner */
#   	define S_IWUSR		00002	/* write permission: owner */
#   	define S_IXUSR		00001	/* execute permission: owner */
#   	define S_IRWXG		00007	/* read, write, execute: group */
#   	define S_IRGRP		00004	/* read permission: group */
#   	define S_IWGRP		00002	/* write permission: group */
#   	define S_IXGRP		00001	/* execute permission: group */
#   	define S_IRWXO		00007	/* read, write, execute: other */
#   	define S_IROTH		00004	/* read permission: other */
#   	define S_IWOTH		00002	/* write permission: other */
#   	define S_IXOTH		00001	/* execute permission: other */
#   endif

#   define isatty(arg) 		1

/* 
 * Defines used by access function.  This function is provided
 * by Mac Tcl as the function TclpAccess.
 */
 
#   define F_OK			0	/* test for existence of file */
#   define X_OK			0x01	/* test for execute or search permission */
#   define W_OK			0x02	/* test for write permission */
#   define R_OK			0x04	/* test for read permission */

#endif	/* __MWERKS__ */

/*
 * Many signals are not supported on the Mac and are thus not defined in
 * <signal.h>.  They are defined here so that Tcl will compile with less
 * modification.
  */

#ifndef SIGQUIT
#define SIGQUIT 300
#endif

#ifndef SIGPIPE
#define SIGPIPE 13
#endif

#ifndef SIGHUP
#define SIGHUP  100
#endif

/*
 * waitpid doesn't work on a Mac - the following makes
 * Tcl compile without errors.  These would normally
 * be defined in sys/wait.h on UNIX systems.
 */

#define WAIT_STATUS_TYPE 	int
#define WNOHANG 		1
#define WIFSTOPPED(stat) 	(1)
#define WIFSIGNALED(stat) 	(1)
#define WIFEXITED(stat) 	(1)
#define WIFSTOPSIG(stat) 	(1)
#define WIFTERMSIG(stat) 	(1)
#define WIFEXITSTATUS(stat) 	(1)
#define WEXITSTATUS(stat) 	(1)
#define WTERMSIG(status) 	(1)
#define WSTOPSIG(status) 	(1)

/*
 * Make sure that MAXPATHLEN is defined.
 */

#ifndef MAXPATHLEN
#   ifdef PATH_MAX
#       define MAXPATHLEN PATH_MAX
#   else
#       define MAXPATHLEN 2048
#   endif
#endif

/*
 * Define "NBBY" (number of bits per byte) if it's not already defined.
 */

#ifndef NBBY
#   define NBBY 8
#endif

/*
 * These functions always return dummy values on Mac.
 */
#ifndef geteuid
#   define geteuid() 1
#endif
#ifndef getpid
#   define getpid() -1
#endif

/*
 * Variables provided by the C library.
 */
 

extern char **environ;

/*
 *---------------------------------------------------------------------------
 * The following macros and declarations represent the interface between 
 * generic and mac-specific parts of Tcl.  Some of the macros may override 
 * functions declared in tclInt.h.
 *---------------------------------------------------------------------------
 */

/*
 * The default platform eol translation on Mac is TCL_TRANSLATE_CR:
 */




#define	TCL_PLATFORM_TRANSLATION	TCL_TRANSLATE_CR



/*
 * Declare dynamic loading extension macro.
 */

#define TCL_SHLIB_EXT ".shlb"

/*
 * The following define is bogus and needs to be fixed.  It claims that
 * struct tm has the timezone string in it, which is not true.  However,
 * the code that works around this fact does not compile on the Mac, since
 * it relies on the fact that time.h has a "timezone" variable, which the
 * Metrowerks time.h does not have...
 * 
 * The Mac timezone stuff never worked (clock format 0 -format %Z returns "Z")
 * so this just keeps the status quo.  The real answer is to not use the
 * MSL strftime, and provide the needed compat functions...
 * 
 */
 
#define HAVE_TM_ZONE 
 
/*


 * The following macros have trivial definitions, allowing generic code to 
 * address platform-specific issues.
 */
 
#define TclpAsyncMark(async)
#define TclpGetPid(pid)	    	((unsigned long) (pid))
#define TclpGetUserHome(n, b)	(NULL)
#define TclSetSystemEnv(a,b)
#define tzset()



/*
 * The following defines replace the Macintosh version of the POSIX
 * functions "stat" and "access".  The various compilier vendors
 * don't implement this function well nor consistantly.
 */
#define lstat(path, bufPtr) TclStat(path, bufPtr)


#define fopen(path, mode) TclMacFOpenHack(path, mode)
#define readlink(fileName, buffer, size) TclMacReadlink(fileName, buffer, size)
#ifdef TCL_TEST
#define chmod(path, mode) TclMacChmod(path, mode)
#endif



/*
 * Prototypes needed for compatability
 */


EXTERN int	strncasecmp _ANSI_ARGS_((CONST char *s1,
			    CONST char *s2, size_t n));









































/*
 * These definitions force putenv & company to use the version
 * supplied with Tcl.
 */
#ifndef putenv
#   define unsetenv	TclUnsetEnv
#   define putenv	Tcl_PutEnv
#   define setenv	TclSetEnv
void	TclSetEnv(CONST char *name, CONST char *value);
int	Tcl_PutEnv(CONST char *string);
void	TclUnsetEnv(CONST char *name);
#endif

/*
 * Platform specific mutex definition used by memory allocators.
 * These are all no-ops on the Macintosh, since the threads are
 * all cooperative.
 */

#ifdef TCL_THREADS
typedef int TclpMutex;



#define	TclpMutexInit(a)
#define	TclpMutexLock(a)
#define	TclpMutexUnlock(a)

#else
typedef int TclpMutex;
#define	TclpMutexInit(a)
#define	TclpMutexLock(a)

#define	TclpMutexUnlock(a)



#endif /* TCL_THREADS */

#endif /* _MACPORT */

Deleted mac/tclMacProjects.sit.hqx.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
(This file must be converted with BinHex 4.0)
:%R4ME%eKBe"bEfTPBh4c,R0TG!"6594%8dP8)3#3!`*39!#3"(@,8dP8)3!"!!*
39(*-BA8#!*!%&J!!)#!1G'0X6@&M8(*[DQ9MG(-!N"'MU!#3!p%"J!*L!hF!N!-
(!*!2KJ!!!J$rN!3$!+df8!b`K1qP!*!&$&1Y!*!&!Nr1rpIrq`#3"Tfh!!d23Np
"Ae4ME&0SC@aXFbkj!*!3IPF!N"%@!!![#`#3!aErN!4069"b3eG*43%!VllJ3l#
%lG3!N!8"UPS!N!BZ&3!!BV3!N!CrmJB!kh(#A3JIG)6GpKBPYieXKYrQ8hkaMLE
2)i``3VPN(l19QGqQFLURPpb,r$jfDiCR+Y1h[AU8HjYe2GZ%fbAKC*maF[YXB%F
fiB4h$Q+EeE(YNAeq4RKQ6ik6jdrB(K#fb6EGK'GQN[fkMr#1l)'%Aa6Sm!Hd!Uc
(,MplhDIbmcBMqmKY`XNQ[mNQQp`QYmPqm6`+X(jR$I)kXr20JH`FYFpciANj@0J
qHrCjA@cKTPY[DfFPffaV(5[GCPSA[r)k[Nc-M"I2kc+rXc-[-ehXq"@rHXqV-c1
q[#i$hR@m%H6,HjhIQBfd33-6!![JV-[VE0LJAfZcVENK)pbHl$MCj"D6,3#Fi$X
!,pp"&AbrC)a*ihr%T$kb!IprEXa,,d6mQK31`CGT409+r&q&#hr%Q*-8VhcFQ)j
ZM3YTI2[ZD-qhqQ2K-hFm)5TG$R*qFQTGkT!!p,P2pDBMCFE(kfPI'8ra)p3E(rP
Hmf&MhM$1RdjK8X*Cf0Zec*pZfI@Pc%(Qd!5!+Pc(I!*cG2rd+(2)P+aIb4Im[6h
U""C06pf@AQ22j5BUmil8pe1E$cV"c%3EEM6Q*pPNLNQM8iUK%$-+Z1KhQ+!ATkj
2E8NrXQf#JYi8F#iGYF@fa[I3Y6Bc$ImMD6CS5G3Ph`#L9A%PAlcq&QSkq%lKE%M
Xl(TjqVXBrqf+DCE80N@a0q)rUpM[4"fhh`Ia2dfa[m1r)*!!BMdc&&Z%`dc&(Sr
$BBTY`Q'@BXr$BECLeq"`Z'+rUVNKp[Xic&(XicJFUGKri6"A)%L2Me,X1"b19Q`
0$[-8Z`L(qBVp)!i,&(Xe$Pf+rCVQKGJIip#Yf0rLd#0SB6Ck&9Z-3jpLMm8KTpL
j10"rBXr&JAZ)r4J1rBUp!BF"aAiEKd(&rKm13iVp-`l$JQ(,H@f-[La4M*PqK'*
2aZ'4LJ&Gd&eLe(fXBY5p9,&hik"a`m3qM!1c3qaIF(K8('[Rh"k['$@IS0LT1$a
DXA0`1&%a-1dNaDl'i@6&IPli3qbG1(bRBTUrYl8VpSmi2#D1G4"(Q#PLc!2e%L2
RFBTY`!&X)FCm'mc8X4IKX&bakh"BSGJ[il"5XIILF*TLp'#9BTr!BE9LAm,Kp$L
@*6DGS4Kcm%6&U"qF)FEmICGLcm,K6-9q'!I"j5cajLc&IJ@(GBVp(JkMLYf&`j-
8q`GK0I!,"UaA$!bJrm5B@fSR4YqC4f+F0bU'EJ)Z%32rcP2XTh%!NiQ"IqFV"[i
p4E(2i2$GF@`D-IkTLS'*Qa9McTqQ',hBSYJ1(*kZf%Y`Z%!akYkUf+rMF+&LIiE
$-a3$KjiCakD65fa6$%aNhSR4EfD0'2A$CBKGL3-p*rB+(*kYQ1C)E4A&k,&3[1Q
FqdX9qdmF`'hpc5!IZ%`am)jq%Q2QKEr0B"rK-X5q(iIR+rCD(%4YQR%M$PFS"Yl
3(f+I`Z%&F@`Q1CZ`ZjQXqi@+JF9J'M&`iIX8SpI85`b-%3Bk%ebflCf+86Ic6Za
2F2JKaIiD"qiNGMF1m$lp(8BqKTj'$&laSiU"PF`[-I!#6N'-hVe8-@Ekaa9l"`l
J2l'2i[!baIi0Kjq)Bl2)cH"pa*LYPbX'EPfV',-(KK2M,QDCf!di[&+a2mAK*aA
l0!k[LQ1cb@Pr5M%i'0K,$*l!M"!$"jP6BX`E256f1Kaq4V(I`S%iXBrKm,1+I4Q
(RiYMKj02[Piaq"*mKaMi$ZFL"JE"UBNa*lqJ',cN6BVp!3krU0MIi2$Q1(B%XH'
A&!2lhk)BFh1pBY4+,F6!bVFU"Ll!0BJa$r"VBMIK`"`4qd-F`%CLIiA$fa6lGac
J"IUE3ll0RF6JC$FV"KplZf*J2hK1M(lrKQ,d!#`LaLb"$m6)J3m5!rY[83c1F@X
F1j+Fqef+dA[QN4MF&Hj-$-i'Rb8'2d'[)!B@[dFa-1*h&D1rF%"LGq!!rb)'hlS
YMXfPaS(q3!bZcQ`5!`ZC&f,8qMl&`26E&@21rNJaCJ1Z3BamF*JB@!9fkHmSFM[
k3!apiIf+`DXrS"Lib)`3Jfr!)iL"JhFUaMbMca#MYJmTKNi$apHIN8FqSKJm!h`
Q"SF$hiM"-p%LL-&ji+6%`1Lr8!bmq%[&k#Qi3Hc[F8#VdGmmkNG`+f,S&r!1B["
`m)dB(2+6LX&Yi%6%`!PQK"KBJ`j$M0QJRm5B9l"#Ir1T3e%l-I$qXiSaVpa$$+k
'cN!-r[02LS(Gk#h%`!ki*c&Qi&m9JbGp,SiYS"j!R"MDbZF9JaGq36(`liZ+`Ar
3%iJa0r!JB[35M#9'cIm4alTB(cb8'"J2eb#'&S$f43b1+VTQ&hL4NrbkJ$G1fH`
#"LMTIehSYC,qYa!DR0(VL'Np5%Rr@`KG3dRr@`LHV+6r,33I8p,r&Q)@PI5rKF!
M*Ie[)AUYT2pe3ip6d[qkS8mSkArGi#K+qPmhZ,H5rYF0EUHNrh8$`j6d[fjJU*,
qeiej9Y,rHP#cN[lA!ce!5IrV!DiSkAmpQ(8PrDm(2&P*rqX"ae25rhV!2C6d[aj
JST,qe`-X80,rHY%l*If[&pU2N[lA#mkKT2reJJFSkAqpi$T'rb5QF89*rqX&2e(
5rhU"+dVkAbpQ@dRrkd12P25r2Xk0k(ppd*+8p,mqD"p+qPmIZ,U5rYF(VULNrr@
"cbMTIhh!8bAp,iFj9p,rFZL&N[kA!bG@d[pbd'Z8p,mFm&K*rmYaEN6rbi'R+HP
r1A!'*Id["ha8d[m@BBD9p,p&a"M4raDaPk,r,B,ZSk6r,B+qS+6r,3+r9G,r&S&
I+HPrLm!(P25raF!JSbd6dr1MT2mY4Vk5rVFBHTD5rVFBr%a*reX-IUDNrbeQ,dA
r@mbj&2f289A5rrSa`dVkAcma4[5rIZKC5[TI2rXRqPmrCe(d[hj`5#ApVapF48R
r'b#ZL2ihJ0P@d[m'L-'Lr`e`eNAr'i$1SU6r$8!M80,r"SL4S[m0%,G%raX%2LV
TIi1B95ApEa#DKj,q0`K0bQMba$5290,r"SRaS[m0JPXUkAq$i$C+qYm3F&P*raX
#lLMTId1B'5ApE`KR*Ie[#&U4N[ih"%e(5ImE)Yk,rMF%lUfNr`f"CbVTId2J5dV
khc$l+[VI-,&Ip,pKBTMSIm2SYC,q0`bHT+6r$82R8Y,rKU(&+1Pr`p!4P25rBH+
Ck(r$a$24rdE!6j6d[a(@,IVI#$$,H"Q)kIP8d[p'8(r$EHBlq-!,qNhYm"2`!*`
"JjJ*CSFHd60`(Vi"$f!'dI1B$l4+F"01!1D!4q!(H!,@J!(-1l-0AX,Mi$0`+AJ
+Fi8H!Jiccr"#H!4m"Vi)Ii3AJBAJ*"J+4i3(JHp`9VJ'(!$-KNI!(q!+i$Di$pl
$#q!5m!Ei#,`)MJXIJ4I"0H&dm%#i)p`%rL0BDc4dH"*F$ii(Gi4$J5R-0p`6[JI
f``8J"I"DZ"ki#Hq%4m1h`94i(c`@VJQRJ#H!Sq!NQ!L1JQ0J(eS[I-(jEm"'H#R
B!aD"1q!0A"JH$Ym&Rq(RF('`8AKGr+&MDJkDK8CL+,[Sb-926`QZ*bdK'`dKIp*
q+I[PAC3FXM49@@P"rq[5TPa-Zlr(ieZHbj%2AV9NPhrUSAU#B0NY4Gq5+UI*N68
lZhMTSN+Tfmd2Zl9F6M4ar"-,QIRd2-jHQ$mRRbRPJm!0@PGlBK,KYkNRjbcX1)Y
SU1qGPR9V)kl6pmrC#HD'*Q6QphBY+Bak`lQD[f,a!&VRr&jfc&2bp-9Z3`I"`,+
$,b$)@Eq!8-S!2i!Hi"dS"GU!DC&f2!DIUjXHZGl`d40k3mrS&IfMPr5$[SMmj%(
iQ)@4JpN@5!B!IH`80Q3K'M5-rb(m$q*r%IiAilmIrchicq)IVEFArdIMIcVqCq0
r&[ke69$6P`GK1E4Y&J$kQp!@fbIc-"I$LQKiYJ26"h-pVG@DZpb6aD@%PR+5XNb
h+-FB)lrfKIG55pi0jcj'8Im[`EmH6#0dCI(IMrm"r!rLIaMr2IM[aIpdr2GC"f5
a8EkIEr25)-cArN8,I3#IqJ1-1P0`IZ!M8Z&)%13$%J)"J@"!,"cjJ3a"1"`'qK8
qqN4rc2R'Y3p"Iqq6PbRm()[c[(hhU4)G)SlLM3p3-L5A2J6GiTZFdRK8,&%9!Ua
MN!"arCr#re(iRiGrc0XCr-r(rdcm(iEr,[bhilm$reRm6m2r,2`IBDE)0[Brhrm
a)FhDeqB,RDZmX$YI'5kj%U+rrL@E%&!3Ll`jT[J(ek!m)(aj"0BHq!-@0&Kec+'
HrCaZ-QHEEV*b3AE@E*Nl'PmXC34kKA4qkP2QUY4A8SqPYfjIjB#P$LXG&MUXFpM
4X0aKRF-bKe81bak@2+ab@15`aQ'*``U("3lV'jBhV'jBh,#CB@R$bSD&69[lX!4
K"F)#K28(5a'@)D`r@(k`qQ!j`P+%e3H,$pBH,$eBHE$`B0h"XS09"iX1eK`X18`
!&KaM68,kaRk![)lXM68!'4YE!TB&V!IB%*!!bV%[B#r!QS`P'ANF1c)fC14dl!F
!!*L$C1lNF[!&H4ej(SX$9JGNFf4ij(HX#eMZX0TKXF0DKf825al@1K%*M+92@rE
-)1[CaMU(C3kV("BjV(&BiV$#BB($qSEP$DZEXEKKKp1f!Da#@)5`"Q%j`P+%03K
,%&BJ,%PBMV!#B3(#qS2P"kX2&KqX29KkX2*JiF'kJf8(U`i@(@0G`P+024Tl*YC
T,0PB$V&1BjR')STP'dXf0PJXdPK8X83M(f#"a[U-j4RE*4CRV-hB)V%bBf('XSa
p'GXbGQ9Xb[3C134T""A8kE$B*V"E3$L3!%kJD0JVN!"8X)9J-d&D!G@a*cMC"6X
&&JcX'PJSX%0J+A&,EV"bB09)C"Xi)VCGl,VBG,(R`Yq`p@,2aAD,(4GV*lCIl,K
B9V()BV[&KSR0&RXYYPVXY0KSXFpLQm8ZLde@fiHa(@)ha'D)[4$E)VC%l)AB#V%
6BQ[%YSLG%"XKpN&XJpJ&X3PL$m3@L"d3'b$f2farf2f`q4Rl)lB8l"hB9E$RS$5
$S9KbX1eJTm(ZSZmfpKGp[eN6J)9@ef&@!m"jG)h'QS1G"SX-eKKX--j5!b(%iS+
0"RX0PL(X,9KCX1KJ)mFqMQdFHc%fG'cQf&La8@-2akD1$4el1&CG,-rB`,&rBr(
'lSh0'hXhYQlXh0LiX@pMfmEZKqd31aff6@b"@#UaMfQ1J!d-qaFf0'aQf,q`I@(
h`ZD&[3YE&hBZE&cBYl"YBGI#TS8p#eZ@XDYK0B,*B6Z#Bf(Y`DD$&3QE&0BJV$i
)j9KkX"Za6S%e#Q!Y+a5`$X2XX%KKMF*bK8d+1a(f+#aAf++`,f'C`MU&93PVNl-
ZlIN15Z3H")&'UM3R`j&eDd!+3p6G'!4H$6F233+$F4kZl$eBE0Y0KVdKj1,lqUe
["Cm19"mPQ1TeX#pUKkp'-p@cGH5!9kk@A!G55'jHAmF*F*!!L2RBIYrM"FABa-@
5Nc38#+-db6)'Vm'RQRD[De2hT9-(4Afj#GaQRT0)X9l00p%4ej8CrAep-K,EVlf
VIl$ZMP5(F1VA&pd5"CVXJTlH6[TTj,a%jhkG"h8HdIN42'0XbPH8QTVe3lrQPr*
1VcG8bpHS"U4i%8+XA(K8mm,diGR&ZZSLPr*1TkUEVXZ1eZ@cG$j#qEh+0hNkhU2
il'CaQCH`[fHlJ6p@+d69TA9E6QIAmq(QVGR$H'[B[S`U-a9$++36-a9IR"MLPEb
2MR,AD1cjmX(BUZDfC2VQGlBi,I-l&RAJ10U6@D69$Vk8Va1DQ5@5QN-#Rb1aSKj
6b9fI[[A-1Y(d!p$,23J)QBdFBaJipE&,%#K@bq"6+@dqd[R'P"VHipBZ5N*i$`,
UmMhh"-A"@[6ae!2h)+$11(!2)LZQdpBpL,Cc*[UG[`F"m6`U+dB5+Y3MZmJN9`Y
[B6ee-U'c%"r0`V[GG5-!BDTYhB-)1Zh!2BLTPqqj*qS2BZZ1!rF!mYX1h)-)qm`
$pi#AfrIGil(q[ZP`a)ZifDYiSCF[HDZe+qHqc`2JbYiFZV@b9mQ(rbMr`%II-@m
P6N8NHX6q*!p1MX'VQ(GTYA"P,$PSj3$e3)6-NJ!C#iajD5m(df9H(,`mFQ-ZVeC
l-)K,#ia[F!0&G'BB*,*ZD!@#flfK-XTG1ZcE@&Y2"C2dM(c"4CPY!cepJdYDSDN
[CA4Y2La'jifCrV&+k*AG+'hj'3-p6XEHSPYd,'1k)#RG0@PTc36&CY0(#hkjkT8
mGpL*EBbQ[hB-)JdcE(,NH9aD,44jc5QYEDe"X93[9Nr!GUq3!!mp[i*kG64UeGV
&LK)FVEP20-$9QM[HQ69le-Ri`kjT@Ja')P&)CaCRPh[dP@'RQ!*pMCN#hC9e!e(
%cT1Z)4LFeIN66[0QcKiq-@26C-ad1'Hc6H+bEBd`4JHGPHXT9reDk#$H0LpI+[P
q"FhFAL9ZV*bCQ6%MbY6"dAa3b*HLk0RZDS2cmU"XPQ6k&LcB9X0SjrC`A211iXQ
!V5@QhF*9$Y0AZ---5,i[1Yk@c5hH(RDGND"dKQLqHT1m[KI)%Nc#j[SNf$a3jV6
HhLKDQ+``hd@,5+Bc%QM3+4)[iPfpI,NVUMKr2@fa%Q)H+'41BRfad!QE&438`C9
0&F#6H`cX-B`@-b[P9DIAPN#Ac2e`!jfZkeek%h-$XU($BDi&!dK,rMil*-%9p'F
C@jkr!Y6M9SIPG#ZJ"q"SR1J3NaY0@`hX&4Y'K8Pb-K!"+6")C6%j`HF#VE,Pk-!
@%)J,Jd,0UiEa3136`TUM@ebKq4c6MiYhhK4eUC!!DDDVP&,N06#l&9hJEIUL&9h
ac%IBZk)VCJ8Aq*A!,lQY36Jf&*!!mef-qmrSl6c(VB44R1[AjVd+BZlq&9f2Jd4
!e&Cd%EUN"kX@GB*8*AF@1C'p85ia`4#2BNb-5JXDiX)aNb9MAFIZ&,Ndl*D4lm-
1VH[B`9b5a+4hmIf*'D$3[8+TX3'0!9hA8AFQeEq1jldU2T@[!d2Krp#5[!*[kbL
A*QYF[6kI,f)$e1'4+J5YeMcdNY'rE8r"jHFiaJ@PhIHlaE9qYip0)#bk#%hS1Q&
QhH#qci3H*"6YeJ'TcRrN&Hc@-*ecNarXeKi!Y*fp3f(`e+'Y6q,c8k`AD$YU3T5
6,h,3KUXD0L4(F!GX!2r0(Bjm8MD-krI!F3FmBPZHA&$RQrRFZMlqCfIGX1D[G'Z
MJF-YIlQ"BrUG%e0Y'kp*Y5fI1pMRp(FAcE(1!%mV@UE2`6Bc[HCTd4e6Tbmd)mj
Jr,)"B8QTkGr50SR8T[5F$IHBLbkkU2k[lVpkQGQbCF[frpGJHfX8[hlpqPeh(2b
[pV4f9e+lrq(rPTY[6NLSdhhqL,k$$meF,`%qh&-l1f(dM%cYJ0$h&(C!G$bp!d,
I`ik&drEF%a5Rlf((!RYQ@[H``'fe[5Ilp#i'I3p'KkRG$V*NDfTRJlk((3Y61a[
d25bMQpVCS1pK&m28cJCp$cX@TRBLk([`"drYBY$hS%e-lAD3!0A[8lXLj*k,%Va
h0[J+2NF#f!MK#"8,6aeCJi-iEaV,1TeIK"eNEP8K#h$GqmaBU1[HCmELA2Fq-aC
91SfCjE$ZJ3`XIR@2H'#CUlc2aLc`G&XU@0BTll-a5e6PI6CQ'DUmcmBX)CEhfCJ
PZZjpC[44hQGMhQ-Mll-alk@4ppQBKF$b2K[cIKKjRiejIiZmcmDmI8AHCf2HK5,
[Xc([,C(hf5JZjT6hf5JZYCAhf5JZ+CAhf5JZ(49MRf)[jAdfLXZ8jAdfLJZ6jAd
fLXYrjAdf+IC5hQH6BLrNI6BT,P59*9iT,JD9r4-T1Rj%FdpaNE'mcbE&jFEb2TX
8Ppl+qfc-BQTjadH+#ilPI6EQE@Vb2TX8&kc+qfa5l+@mcbE&aEEb2TX8&4ajRdf
+LjrPI6BT,MU@ppQNL4(b2TXdje$HCj0QIq9p0ZRkQdU)X5K9a2-dPbI,qfc5A0i
Xll0*FqQX[-mQ6Bb4ppQNZ5aB92mdHbC,6p0FZL[[XdPcXE@mcbE0KG6b1SN-F8h
HCj2Kh-VlE$,XPlc2*X1PVI)qQ`bG9[)qQ`aa3YjRNq'LBAQIMAN(Qkc`cR!"XVc
2*N2mNrICC,Lm9YjRNq%LBAQI6BD,J'ArAiBi)HqcbI"p4r)qQhELYEc2TTeB+@X
9fiP0mMkEGQ+"[-qQRA-Pll0TCarPI6EYh(dLll0Tjh*XHCp01aIkb[YXfVRF@Gj
RdmjHb[YXfSN6mMkEGZ+h[-qQR8Z1jAdflF4XHCq0S4,b2TX1iVLmckD$IC,hfCJ
hYiP4Yi0pN[ICG,!AmMkE$Z+"[-qQJrjDHCp0"r&-hQI6`BA5mMkE$Li6&Sp'"rX
Nll2TB*rNI6BGA(iZ'pilb#e%Zmq5fmMlE,,N$')AbE*RmMkE,2&)$+KCcVDmcbE
,1C(hf@4jP[ICC,NB@pE`C,N!@pjRPL8Hb2[-XX3$m3kE0lV9hp@bji022!qNch%
k5r5H[h(YMp$0Br4D+NrEp`+Tbb%UA!P8d$chU)Bklf2lAXKh5m5Sm,dEcpq!0H4
RL8Ali$k0%+L)Bki+jcE4pm!qae`DqAX!QM(h4IiH@#c2f'RGBjlVdp`iQVm(rM1
e19AIJ`S`YX%dI`mUja&ll[Q"jMhQf3TIl52Uk'2fE8ie,`M45YKAld%aRA,Ak(Y
38*ZZP+JH&0@Qbb@k"q@Nk9k*lN(aE,TVSRY3CTXE6$haPKG2`QII4S6M*3X#1bX
4c[P[elHVp[B4Yq,@[%*L'b!BB89[E9R@AXiRYf'!`3(lR$L0!m[#85`apEI"JD,
!2E1*!eGJ,DkA$3J-$Kc@a!&[QdaJheIIPQk2Gj'Y(kYb4rSbEDhhUD'"+[(0BL8
F#$DCqp13!%"aAB&qlFkbjXD`p5&H",'P0Par0m1bk"8%bqCjPAEcaa[mA6LJp3(
$#kG``*bH8bllPIEFf"$H5*(VU44+Bm-*BD6"i%$f,cLJfD1A$!3F$ZMA,#eVjp0
'YS6*E9B5G64`3$m98Z['DrfDZm$$Uc*bTl5HeRTUdKSL'$i`23&U[h#ZQmp4*',
h#hpP2(iC[6kErF,jH2#Ia&YjZr1V2CfUZ4U2[XNqY(V9V+@9Pp4eS)llqrH0qTV
phhYIYHlQ2II2cB'C(Dr$,rGU1V[0`$ab@l2-f5pk(lBCq14Fl&kiV4Ek-fj&lpX
fJlX5ilBCJ!2hE$0`lQAlTVpPjXqhq,0`J-1d&l82@bfZ6icEDR&AY0A#[VLBEHV
6AJ3[q)qeBK"SL2Q3!(QipFCmVHEjYEql6raC1)"qb'XVr(0EpAec2[4(RC+i"J5
bPq*KqmC@IIefGAR6ZAl3qE*Fc9rK&N)Rk`8&mhMU4Ur5Rk&+F#N!il)Gb9I-RK@
Cd%jh+lXcjF(Tj83TYjJjQJm+qG*%UC+Yl@kAH*@4B%IfUQ%[p(GHZGU[l+c4,-0
[P#mcX'T9@-[[V'rP@"$kCHH0lPYAqVAKRGR,#`8h#*aF2LcZ6&dajT@'Rkk*0lR
AKiI-dl`J(`4ZHHL*8FJrjVfF@'rZbTQC'6-Q4XXQ0bE,[[mpQC943N+eG@41Y)l
d@ZY)(1eFm'4@I9T(-ae"'50hL9[DNAUfZhULda[bY4%hG!EF-0cGDLL4eN%ZV8D
j1iS6!"PR&[%acShJXC3SBe$+FrdZe&r%aQTb--"aXL"MR'1!-Fk)FE(@HB'`1$G
"a6Jj"X8i-mE%1$1#a&*L$#ZPl1Si4AKBD&`"$LZjp@%5-#`-5"i,5iRM2FXMB5N
2)#`ReDBcJX%i-dE"1$-"`3)da"LS-pBAhG)1r!ZbLYJAj%@i&bG*`q-FepH`eL,
@*BR"D!D*JR&"h1"E%)faVG44JD%J,m'd)$('Xb!VaV)J+m+a1#R'JcJc'Bd)Zm,
Q&(#VQ&FH$-'VX1PjV)U6kRh*Be5F!ci9%NV6&H&5N!!9Be+3!*AJ86M'-4DG0(Y
dJT!!&9+,U&4)MU#TR#R0,LHk"KHE8%5U@RB`PB9X`Da#NJ'Z3NU-A[8C%23T*#F
i9XL1`Db3!"SM@L%eJV9bCS`KjI6DE%8S9qaI!HUUbBh*%Y!VcNSHqFUC%kh,Bf!
j%5#XC0@R0B,%3QU-LiA8""b,H"%MT--$Nh@Q&qc86*lBlr493krXVGiPM"L8@6F
@9XHH8Xc1bHl)XPl$Y5kD8b@IFD9PS8%+,5IU1Z1NFTN"1BK,,(!p+Dq3!+4,#a,
+C4A'+UkY!XG5B#969eR)+TGUi@N#U8XAa'"GbNi3SR4"!54+k6(HPl)Mb+mPap"
CZd(3XjEVS,)m&!AiEq3($+#FEdP!+5mHl9*f00hej,''ZI%[*Ai9!4)HfEaJ[0d
4[DNPlaV62-QTjF*ckSR0FBMC6LNl*MbPl#+",q9((,k@h'aP8@jDdI9lbFHP*U+
2bkYS&LkeT+#ja%3UFRP&X5K+5f5C+$F8CU+XDRY,SP%K-j+0JXa!1()C#GpbH8A
'&DG9QT(RBLkP4[*FFN8-,+C@feI8ZD+djNJ9Y+iS5p5Z1+AFf%6aFRPe(AC&ek4
qEY2V#VV0(40aEAV$bQ#6krUlcDdTm'&UAFm1ma0&1m`XbGFb!JdP2XSZDr'5A96
ME9CGHl#j0I8KRpTS8NQEX'N6)SLpB-be%DFhfeXc&S5TNk0B04H%QE'p)*p@Ehl
GBQ"c'm*9(Gf5r)B'@FHh*,qT$9F3,NQZUjJ0M+YH8*)$bbKAQS@QQPR$Z9*kSQK
@N!!Z5Di,94@XUbA(1PB6lC)EaZA`1Yk9mQXDE32aUKFd"V1Xe*C"Vj*E9@XVX"H
V$(ANUe`aVZR9mDpbaB5Z9d("5[kBYYI!`XBG9E@PM)M9-CR3q'Ui@,fKS[09d,'
52kEe96#bQCrSI8fNV&bb8r1VifAeLUEZed$0aKhM)ea6rmV`@8p[+)!9%!ejjEU
1Cj84Qpq3!%CXmVJfB[1EiSM0EUJM0VNZMi5j$9)HAP"Lj@&UQAr,,$3PNLLp)L*
)HL+5f,5'5Q+6kc**2VICUV*3B[-QP4*l`lK8%ZH2YENZPS5j1`Hc*TH%U3@p**r
AQ)+'BQ+6Qj**(IG+&c4&NcVbP5iBNddUf&I+EJJR$I5Vh9"Qk'Am+`r&Q(K53m"
bINNqU@"J+EXKS&43X*jGN!"3QMKBZQ*#4+NMBIQ#ZSc5`-,D$FdaV5JTC6LX*YH
dP!SJ&RKL(41VGdc)+A9NV0ia+DK8m,&k`ELNdN$*jL8e4Pl'bYUm6-SU0F5XA9%
99LUi@EeJA&UTS1IB"59aTBQKe9Yfb5Ye*+hG-5D`02#dHFR%30FePM+`0[+E+NX
&AR@#6KYh2ERFNZh**9Cp6bkhE(abQ5ARNdY-V%p4AXQS%bARR6T4@Z6,#ITFYMm
98Q-$8C!!'KUJA%V*!H85%`Y8R&GY5@5#FMPe&j6,VYUJLVQe0LC'U#K[E-#+9UJ
ScAQKiTa+KdYZ+*FB`j(Iq8ZC`kE'R#-2pm@[Ub1AkhfKd+IKIhQe@NS'U'0YYRI
H[R[dDXYF6jNlN!$TE2f1YERH"3N"G@c-c%m'k1[C!rel+Vb[MJfG5aDe$K90)3M
D61UhDmhKrF2fJXlZpr1i)PmUqAl&kAC,pN@ekTF24c&ea5@AmfcUZ1$CHYFZGQ,
q2$BGVSj(cNJ+U'0A3ljHakk(j2lr1RB@XVq1#eG9cFc9Fq0j[H(Hi[L[jkBCRhX
hhRY`j3B$bQcRpr4SPVF%S`lblEaqGM1@q8NGfricViIAkpJe(Y3KLX0iBfdG@Zc
a"04a`@4R@hfpUPR(*",YVf1hEZ('GI)cGH``aEdiE5@8YJLSA@U#dqGQq[Ec'1j
Br4b6fHSAa[BhEIF(rlJXU$h('ZkTBdHa0,6[(Le&6I'c(H&B3N!GI%Xa*0rUkbM
qKA(R&FcLjrpJh'LQYHmJiak[`a[!Z0I0@qMXZfGYE[(qIRJqQ2YB9`mbpkNkpM(
hU6Vf-IFpGGc$h&YeY*LlHd1e2i#j0rVa)(-IEqapc,e9aclQhLMM!HEHUQ-hFpG
e6*&hbp`[((PKlVdIM&Zlq1Th('6FBhA`H3)BYeiQGF,VR1C@U1)hlDq-5GHa%aR
ZC8a6GHaM1R[UZ)ITY1Ui&mNEG6b!j+dkGS1HVX-X%@XKa&)mR@Bb2kp)6%b)VZ-
j3b[feV&ZD-Aq1UCP*f`BmR9QXjRZjq&[l2XDiQRI'*1iTilYch*&AFGff-bDTUp
JSVHkba-#qRU)-`4FHMFRhep(#cPhceN`(jG2MYRA[KQ4lh!#BfC&kZ10apm&9@P
-KDTqS3VefXZYqZJ&U'0P+3J-)%B$b&JG'Z[TDpYHRGbSKPk!IKLec`Y3Ke2l*Z[
BVrCY#mXPdlXZVZ2&Qf$YbUDA)(ld@pV5dpkdbI`i2HZ#hr6HQRBfhiXVj`1E2SA
mGkGRREFf2HfGEED1Ch'+a[ZaGmj%CEQSqXbm)V%B)*USBe02cM'YUbIVf0X2Sl*
i!HE9U#aHJ$Vi,*berEZ[TJip(QhrRBqcr)Sl54P80TY,!2$TkRITf)QIT,G(*%m
i(eEf[IXCEFTqEXBQ2m0K[!"eV&P4@pk+rfre&9EUVr!X6Rj9,T4m)4IkpRb%A1M
EmqS2m)SC,R3)2d$J69je[`0REerp%mSeRh#UrqfVU301G@Jq@KD[YU16hcaHNpp
qTZ0AmRJGqMa,(Up,Uj2XY09A(i(,@h[&$RdH%+pB!d!Hm)U0)E8[`#Z@Am&8[b5
E2-(F24A-e!Z!R(i&T0VlY4EPH%!d(Br,TTc*cd1JaIL"0Z8FqMa,Qh,fDc(e3V`
%'hGfIV*aCqIRhpUidl,rYde0U[$rlf0`rSdp![FbVdBG$c+[mBEFalaDGAJRpL2
XCele3[`#HaCX(4G1cKP&k0F)@P)`FBmIJ"'B1V`5HarmDCXiec5!VA0p&+Xjr&p
e@446!j[AmHaKdKI[Z'(0YVe1L[&S%fF[hQ8ZHjh8TKZR)[r'e+DEPU8Z1H)d@iI
RDa0R'DGVQcL,11dhhm6T4@$ZIL#ApL4cja2QVLiiFPN#!(2h5fhL2$6h$fXC0R&
ZUG`#9@P-KDTqS3VeLA9@II3#e&(Ha&QZSlCaX+L+'GA3#p!2SrCj!HS)0R&1e,&
Il62Ejpk@DfcL9"HQ[SfihX5TeYe@0HY6epjpifIAT#irR@#L0h(1VL$rUY5eAjq
I@[G$h"GYRa[[apij+frL,0G4fm4CV+1mLI1KIKL9a3X`VdCPm3,8`9IBa2P3Add
Gm5E1KqTiH+@cLI2KD-qE1!r@mA#)C"1Rf3F6IACjM1rRfl`d#216@1*"q*6j2jb
fl2-8qQ!q(+jV1XlUi2rXV"[@r*9ZE65)V*DjJ@2kR406E4Z[5E8YRc[Bjr4h&mf
acJ"2+eUQcc'T-fibjY9h6*fqd)`iJhfD221PR1k0LYb4RV2K(M-q2Kk&p9RGIr@
bEI(J2iQhmRER9hXk9A-e(Rf6I@MeUPP,+bqTkd!GprI['r8eqlrh[QVGcA[ZRjX
$-cYH4dIb#dHSI5N3HU@Ipq@Efj,TQprCiV6-leM8JH0S6fC45k*+rc0Ecm),&fr
rZ6%RQA)30RAHc0BPf(R6IU`a,f0QhPf9fAVf*i`jrQH%9jejbDkLMXIr#$)[fRE
RfDMJFDeBXb*eTKqdeGaXc*ZrUQVd,IP-,DM03`G5UY0P5Rih$Y1V0@c!5Yhf'X3
#0&1[af%JcVb&cS58[I3,M6Z2(83XEHp%fESZcVck+TBAC0k0`jSimq6I)GCZ1i!
fG9bFq9+D+6TY*[Y'j-iE[S6BY(TQ1mABZA(QJL-4Qe(26&-,PGjm%P2C0Yefl5@
0ITji-Q+K2hp6imjVIS$BSRTLkSj'2ppr&f+,lCeX@T6HA2)BBXb1l3!#T[6cQQX
3'l+C+!*bjafh)"D!C2U44Mq[B'a*K"hDY6Bi"p(jj6!JGXJ%kTR@[6`*GAE-,BH
4Cbr)h)4SpmF4dTRErHe65ciGQ)8l3C8i8h&@C!D1Z3qa8fdUfheNEYjq2Q,JJUe
Q9Z21mcq'f12VQFG44jDjH384K58JpXlE'M2`[LX3@fjRMETNEYl)rJ5H[4648Hl
md0X3@f8cIl-a0fqP%RbklGT)ScGhpL"fIMeaN!#EGD5IXlL*k#Pf#N&ZZI-kS'c
EQf`rhpASjq9%SUIDDXL8hR36"cEEL6)Afm`q6RZJqJj4Qj-lAd5m#A6PSHmfq[R
aKBKT-l"Q&hT2ePCLqqTb1,)Gfmr&QqB!Up4*j@U!QFPRDPar&"3TjH9kJp#NMq"
dA9Q[F`(iJ'-AHDC`0FbN60$VJ4"SjJ'UR!1d1r8"K-i3%JPkDlc4H([ZfLB5"CR
RI4(9I,TC6B$iI0h[DL*4F1G'90*,4[*SS9Gmjp!0GR,6Fbj'6$-SQ8*d,CRF'i'
GE9I@-dGjMjhFp0R%0&L*qFiJcj!!+A`('FfEkjR([SFA2cYi!L@ANQHic(!'G#@
pC$S1Td8ad91SqF2&Vi"jZe26%@5H"hNi4pIZcCU1@'AT[V3j(F'GQfj&qipTBRY
mTpkk&[DQ8!dBda9eZR2DKi!*X#Ich3"eZ(Y0R(N5J%40UfHZ[3bYhaTPCMrj+$,
Re$1r#*jl`XAaRCRr4qD4&YY"Z8amjqI14LE-c(B!C*`IhrRNcb06hfZr(NEXj(D
q%M1NAQicB@kciX`Rh)c-HIA-iiRkYm9eI[$6b03F@qk%ejd5hrR)Eb"cJFh%9Mm
c[[2,$b066k@&kHXZ`H'MmChU8iJYY(FqYh(RYH$MLXKN[Rj1iG,icUGr"TNpp@T
H#6c-a+L5hB)T9+qbdr'HaR6FfSr-J*RfRdGfB+[C#)44PTRfIkr4cp@()M0JTMh
N3BI&QG213@E!6)I1Y"`Lqm#Gb!bBD3qCTFcD@8!Q44CJ[Y2*YGiECmi!qe2(eI[
jkZXiNlDDflq-@-"QRm4TH'HFH42BRl*XpKLS'M)Gf8I"i4@jQ+RQ0EF$9Ha%GID
FL`5`fRbjecB`UK2)ULclZ`bGl9S9Cji#VUBXqh[5jJC'I36SUZVZ5,8851)`UKH
9+-X,-m3+QF+2JD)TZp@dRbU!aDMXJjJZ4GCS-d0Hf(NbBSV-c(`$4#["U&AX@V!
PiX3[@)cU2!SST+a$IiK)*$0p-QGJV@8al%18k9Mf8@5HCEN+H'%a+[Y"SV(e'R$
RKJC'h3NqVHSfSlEMhY[!U$QS@4%Ac(FeX&d`U[0dSTHZ6UB$eFNKZ'DrDX"b)K$
1BP6fDq"8LR@Ell&J*DkI@iNh+%+fdkpVB03MhSI-Ff`eGeQ-kP`$VU-@fcZ[Emc
DQ8"-YF6@q5@,8GRV`"i9')Ep9S1V#dCeRJN'V6M*PK1aGG*L9'F*h%CC&H#%YcH
QihLS0-UU!#qr[i&4XmNl!K9J!@IBBP6f6XbhXLV!GH"%`U1b[`*l9&B&@!1Q)"M
9H43QAGAAKUNCd,S%Sl+hI`i*`@S[44b3!#Rmm%05e@`(8-3%Sfkp(TQ"FT!!CLp
NEVDKYmVZC&c!6JY'c5FV#aD-,!$IGaLe"Ja0fIeqA83%QHNP`&YPpmKNL2mb(DH
#Mb[V2H`&mML-HJZkV+abf881,KMeQ@mL-r#YGAfJ`46H"!9+fDf('pSE21Vc[d"
QS*fQbCEXG(3H6FBBZ+DlS*%i(RAq6j%CU+Spl)$YCrC5GKVfE,k&l+I&U1`Q6+5
bIUQ&TcCie"Y3Xb)EY0A!j'6@MZ-8"SV[!,XN'28"U+,+1JqA!RNF4Qe$Pj@eKhd
(ka)HGIGhN!!CZ#GlU$l+G,`-+Sd#ca2ddUcABG4dG&QY01Cr!*!$)#!03eFa-5"
3FQpUC@0dF`#3%[IA!*!$i3'3!!*b!iF!N!-4!*!$KJ!"U18!N!-@!!![H`!!!J$
rN!3$!,#$ZID`JlX)!*!&!r1h!*!&!APUrr$rq!#3"[bX$C!$0MKVT8aTBR*KFRN
ZZ5kj!*!3G0B!N"![#`!!3hN!!#m,rj!%68e38N0A588"!+YZchk`'-Mj!!""!J!
!)e`!!!ZT!!!(jCKeMGB!N!D&K3l!VCPCfU#Adq`k(mr0SZAPZP"1[iZfF[HTVFc
M0$Q98cFG*-pc%hTikXNmfDe[I,AMjaA,h#c+Ml$ERN8jZAhQGA3IXb+FE!Ql1LP
2XXNqNr"1`[B4(YYNRfQAq8Qf%8iii4hKQE&Y%Nliff3&[VUqHZXm0l0EQDeXRad
l`Vrc#+IEc&mNr!$)"ZJ%!Y"[3J!B!(ciL`#cmCqKa'*6XUlr#6l"%iYCXqk`al%
Tr*ilXh,*jI@qMV!FAQDreS3[A#jhSl0eIMA$',(B(r%GCf2`jK8!4b`%U$*9dS2
$!6j*F3ia!Sb1a5SY$cr$X3c%XZkkJ'-fa+#pPQ1()'CGG4r(LLP'f`-F'dA[6LM
M@!(&qfSAamBJaR)QF'`XaEMQ&a`EKhm6@2!f!X`$)NhQY[M,XB!*!f8JdS1h[mG
-(41b'#%!B"%rGD4)TQaASj%p8HE3KBZ2&q2H`RTBYZN6fm-8c%Bf$()3BQ`T+J@
CYI0QP*EZ*,AKSV1HR$Z2BT8rQZd0KAh"b#+ljfdG@IPMk`qr[U5jqZ4QPlY*-[,
+b1HMC'KK*-M!5TcaIc0U0)j,j'K528Z8L!-$1**DC--9F)@m+"63Sd-ac)+2343
q#eqbZEYN6C(+T&28S2+L)Q-Dj@95RGS9e06Jcc6**AZ3!*5UkFN'6mSD131a$aM
!b+1-RIkDll+#5X6EmBlVL-2Mkh-IZ@lBGm8[q#kZK3M&G@&PUH,jVqZfAIDpqRX
&!Dk,Db(QF0drDJbVaN9rehDXr)Pefcjkb,$VaVlJZU3@BJlIVAM0GhQ'ePV%ke2
rj6j@rQ6IjL-['2EGa&fq5fJKjR$ImYIFCc-8MhK#rmjmV2bTGG[UcaPfhrKGlM1
d%+Ki,qTpahY2L`HmCfJK32&HEPc[L-rrP[PBq60p0lN1(IEHK%([k9S)85VYCCT
IlIcr5MYf@GA8kD+!5MZKK3$&GpPB@(AkSmUlAG3+k,ZZV&F3d%90DL&#m9ddk&[
UplhE4f89$20GK5$!GdNY4"bq+`8,cB3NAc%k"%h3Vh3Z[46Jq"Kpr!P0-'4EA'T
3pUJTLPDB!L2B*Y2+a(f(#HP#ibS!-m'frG&"&q-ref#3!(J6J8`qB('Q,r4fFK#
QR&2QZk@kUJ99p-ph+C'`HSB5AU**GI,TXY3dU9%kLTAfAm&+&meTDC!!'QZlB,,
84,Hj*40al15NDh&+k-F&%qZJ8fTT3$U&D-FfNpP8R6'Hf&Rk!3)6%4K(ScL83J$
1jSPQqbhc-"aX#G#)$GX+,0[4U359X-rMZ09,#96@PNKi2bcKlDh04@aVLaRrL6F
!kbG"hZ1##SG4@E&+Rq8Cd+qhN!$dLfZSiqYUmEkD,35@k3M)(NIl3PEfK4#-(Vf
3!!mIBD*MCEdp-'V93c"qkS0GXFIQi2Z9-,V!#N8rH!SHDUp%["p'AGR0bYC2jVc
+HLp1m#lVVHI[-3i8MD5D)K[a'iK2l,C2pm,$V)dldR69R8Cmc+'ShqEIqM(1rAV
mhS*D-*QK+(FeXL"1"9b2S[aZeJ8MEPi1Rb,m&Rb*SIR-8ZbQMEq%"fjGE@K!4V$
"eXG@`pC(!EBq83Zr(iYCBM+1RI(hI9K!hF#k`66'JH923j28&!f&e($%8D[)AL@
X15"hA3AVRN"m'0[8A-V12`)p8V13!&eidKc%h@a6'fPRaEm*mAE)[E5(G8X5BRI
L2k6M8apK&jli)1%82hEEQXq`YAqi"2&%JF)fY4b0H!m(4khGM2KXa2XS[Skh68D
mAqG6I)N4r`ELJhH+4r%IdZ1[Z4raj4cRmFqrciLI`(8p@l#B36iKp()hX&%1KdX
0+c8q[k**apJVl181dBS(-"GD(4ie%*)M$Q&,,X3jbK["8U!R`jQ9*dVe[Z!5*Eb
Mc-Jd)VMGcMp(5*pa9@jhr3I96M[qUd)K[aL!KmY92cFG*`p(AUAj!DS352UABVM
Fp6@#!"kY6QSp#3"dE@aUh%R`G4l8Z-U`Gh4j0+d8f,CZX08PadQY'cKQQb[lrDS
DP'S9Il`9`Llq2)GBdqdmXa-2dliZQXh9+MRrccPYfU!lG"jQZfID0#%!M`blCkm
JVr,Bf`&k9GG3LXJV2*5PS5hIA+RlpDTlH19#H1&G5',CPG#SR-REEYB6U2X"E-Z
h#["p2pYbE6ZlF(4&dUq*TZ"EHK3NH!`eb(+4Ke[@2,*rYl#kVL&C%`A`m+586HY
+T5[aX"#22CRS)!q6IDL1XL!2XQcUk$bd[ARDJM*8D3'HTq02Gq6TNjd0qqZB!JT
5-e6*H&920-dMIDMq#221Z!L!KpEPldM(bA0Ale-9H85LJJ!HG-afG-PlZVV*LqQ
D2Ad%)"8j5[p5M$FUmN%H`S#+['&Z(I@BKr4`Z9[6HSJq+[YGUVj4f3raH+@bhmr
M3'@rApF$PAfDall+RSj4fE0c#pY&!*Ap6Mf'+rY"B9q[l0-m$P6f1fQm@GN2m4!
(92CQZkCd[Zplm8G&MVZ(ASVa4N@qL`FG38"&hZS,PTG*5bYR[Pf4CrqcSN+LHc2
(`BTUL-FVPG"q23j83QNH"c2p6Kj[C[SK(KRfSDaS44kB'2DAlQBl6RLQ-YP!af+
h3iL(fV%iaD1KBh'D4lEV2f-H#G&G6RePer[RjBaS4E@i8rIa`!cN6p@D)iQ(ApB
dbBNc36J9pEckFFGMVD!X%J,SqN(0NDc&KfVkJcc5Q6AYXf4'M+4XpVH6`dG%hmY
"HEbl+3HrJefV`5lALbICjEUh*p(G&!,`F2Se$6!$BAiCj*'&Y3)AINqIRRFPK3"
km'kL%)"([*ZBiR'`QjKTliS%r&HlG4lREF(Ajl%l%#mkVC6eE!V"*,BKY2RUPDc
[1%Sfa3$j3AbrNQh`hXCkISAaiM`@SiYfkr'bci`ZMLqdakmCf-**mk!CD+"4mIG
pclXi3J#rmLk1%)!((BX3)*r4-3X"r%&ba%Il6DIrGFKrH+A"FiDJ(ej-c2&@K5)
31@3%mBX(%UF)-VNIk%mhRSKi-X+jB[dP4r-J5`q4H(mM[XM)DIEiTf1MFPmcD2!
FEaaaJ*c2FJQ`ZpRGTPX)ZJBE4f0f6E98iQ5a,QZqUl80&G@RkhG21!`F'be8*C2
Sbd(BAFmZD)hR'`(3D@[6)R)iY4p@J($)aS@dZB1RaHIH8Uj-*X[[Jf@6%%4a9X4
A$SYTcVFTbkGA&P-YSXmX-Zcqd*m@Rjb-1`c%"mBGU),qY#)Cl(a"N!$Tq69"Hil
*KV'`bf9m`TG6@1*XQ&GG)TA-UfUZ`UYl[V1j4,4L!CZq!54qRP[1ETVLKU-Sfah
'ESH-d!,H%Cm8#Z-3`J5`ec490f2%bjUD'ir!qpHfmc$hmqBqVcUFa8"EN`S*#ed
#4q0e0Q'0,9L[!r#*fEDI!ifTi'JCCQ-[I"aR)[K!3+J+F&r!b&l#ZXcJ3ia[A6P
V)bc$e5Y6HHbeX!Dai`JEQ3Qi$@Ad0B5&li(,%IX4BE11K'mJpKZ1M3)XkXCQ%hE
5lq#(!-ImP,!9Tm,YL0e0@&5&H`!U@JNEf`%2)RBDB611JDF41j[crLl$6639&a'
fH$P$I@HF5YLCKc2d`ic2%AEfPfP,bSb[%2DKm@`@`,(R%MDpL&8MKLj$99D`"BK
Y*'cQVjQ-E3`qaA$FeaRU2@XYB92'-*bNFr!faV((Xe@)RF@0YTN@R-hQ-6jb$Z#
Z+XEhjKqkNYk0j%[UmpeKGE(LL8MSAmfR"Qeah1A62(Pm3LJaGj*$-f41eDZFS!4
(*1I*q$-MV,%,FhVBT`6NS+ADkiZSBA10'ScN'r15F6*a[&81"hh"6Xh'1kN'MEb
i#Y9,)f&CbhG'YBJDN!"19*DGSBDpQUh+ie&`)-BY4lSd5l-FlP3LYVP4RppV"-a
Hi-3P5NSN'XUK5A4$X`,#j[Ndl!dVJ3l8B%4b6*h(LE2A"kcL5KP`A#L,XmD&`A*
Sk8bF''(2%NYZT-NL#-IpH$b$S%eII)$k"4@r$E[e#Dlr!`!!$3$VX9lc'QeDjQh
fDGmCjE5hD#FrQqQeCJ2#k8$#2(j'f%@1%caI6rTiTQm%Rr6)bXL)(4R`)jb-'6P
1MK01KS`FLa`R$"mCm#182#I(Rl!MM($##6pbP$$b,)m`bI(c#2H58-)*Hm+12#1
-X#2(J!!DZ'D%%NkHPRLf!P$m@FF*NMJ!%`qm!JdkMm9908N)#H([1N)fh54Nmf,
-B[Ml"2lqL+qA5*M8emBd1DkQ-NT5N40eRE+8N!!emMSK(hr3mJPj!dM1#`12N!$
kK6e5['iJRL5K#kICEaIChpA6F$CH6BHFPMA&`R6HF[Yla5`Hp&MGSfTbAEZ5P,2
EkL)34Y,VYJ!mXip8QBcX&`UEQY36X[i,U"`LBH0mD2JQeCHqUQRP(2f)UK2bQk*
fN3@%e$D3!(EmS`kK(Q'8)%l2rJmKPQ@&aNamq'mUpR[CrVCB@1#8U-PRL4j2GUY
5SPG0biha4a6`9JN@-&aV-UR'jeQm`PNXYPK%KUAd2!QbDBj&b'*4Bl&SkphRN5#
YA!ZE463pjV1Sj9VBLVC(8JQ2aZk+,qLbm9KJJ`BXZY++lV&iKV0BlV$3C@dd8f+
bTD*&0#HdD1!XPPSXHP9G'6c-H@bSl+kBP&DmhI9La4Ilj+`kUX9,2RfYiSYq06l
LqH+&#SX"*HA[LfFV,0j0+cQ2KA-GcE23PD6(iRmc,($j&&P8DI+3!*c,q+[B4#k
aU)B@VGR$DFrQ&'k1KEh664E"SB-A&9VXPE,qbX&cF1HdS&I+AL8YDI2V$fm[ei*
k0$)LP69elQ&Ad3JSq*X,Kh$!)T9Sl43XD$SJ@(4e#aC29PMd("!XRJVFC5BArMC
'Q['B"Ee5+)YS,U20dpM$@5`#LcC*piA!fmaC9)&&q6$'@bEF&4f6dri&5%LcF&F
d*mG(KDK14Z6kSRbNildU2%U2p&l*2lc@#(Geb)%V#&NS&1f8XX-"$5H"FYh9U@4
e94`B6V,QqU)VRC!!FhdI(CURdF*Cd&[(M"h%'EL5XeK)@I59c8Aq,hCA9epPBD`
0&1dVRmEN1H(dEL8GR&dXpA5GhJfR#iZ50`-YN!!Q"PSm,9Md5)SI!Z)K9IAF9Bk
'm&E2XCLqX1NqciUYdmDeS$XpF"CpEiQY%j1dE(#qe3JYBL0$C5hU1!Zkdf0U9XR
ekpipqRc!3T1cXMEQLET4l)ZB9JjN#'d@Z#aSQJJaPI53!1r8YrQqS"kP`CYR#Vb
)8,4b&m"!`ZR[5B%5N!"qKS@6V$J88fJk$0+L3f0#j94f2@4K1cfVDqQiP*AM+@q
6ETeMBEYV@CZ#'JJp4b0UKZreE9b,DRUNq`6-YjfcU'R[ceM&$jp'SkI&D"*,A3m
1p4fFaA,D4QQ6Xb1kQZNC+MRHDDBm9*5b-#XY[KK0rhM8r+b'd`Ie)(Zfd&fRVf"
D4(1k*Me@C+H$Dk@f)LNfMRep+A4d)2Vq!*d!dd39b6#`,M28bpLc$*9RZ2R`cYm
Y9$U"`Jb9*jc!QQ5SNdJSLkKZSTPI-2UYMBS*%XNLUTYJ'RrqX-I@&4-N5TD(r!6
+1(laTSf+#4)N%e8N6R$1GHDKkdL-6&54-)(K,FEe&M)-aT9R(Q$SS'+#HjLjJGr
2B(LEFEf0Dj&ajGHPFHlF1cBU*VM)'#Uri)al8adf+LDi`*Mcq-8'EjpL,Mq&I*@
KmMc@q2,XpcCA6*!!iM2RmG3IcVR#2(3&,3rcZK5Y%12Bq(i(GA`r@KdcU)m-N3m
hMcNlVhN-R5S69A5``2!JihS3ZCqTUmJ*iEFmFeiH594KSj55+qcL+ED9Tp#'-e&
&Hmii2KPb0XTN#-fUSK[F*KBmN!"JENJJRf+kmMc,Q1KU#"daZ@+#M*NTa$0Tk,,
%4X8%UDH*+P*5E*pa#j91N!"bX[h+8e%ijbmE&41deBTZF0YYaVPIepS+BB,f51'
b+E90M&pqEV94-8(6UFM9E8BC&cipDD0LJYkBL5TkCXC%kSEM[030j'CX+r1F$Aj
EbTbh&!NAmbY2a)aMhfb`86&"%l+SUpZFa%DBB,YK!Zd1Y[0i'`3-9c'ZUj!!3KI
fDbQe"YC'KVS4q9p"ee*H#+ae$(8GfS1QVU*YL,drk+#1$k)99h5$fk,$9Y@F2G5
X)89QEZ#T-h4Cca4DMcDJb9@d"k(,!DE3!I3CL`Ujr8GJ(@+SKmM@&M-G%4NDX0B
`e$9N@i[*9@4Q*mr@G&LSG%+f@kJL)jY&EE4345BfLlV$iHTPB,1S,eQS)[1D4@f
b&I)cVPR8R4DU5+0Q8AICZm&26Sd6AqQfAc&"ciPG0V`ACC`iFYj"2A)Hl@lE$9i
E2"rHIFICHE[[S)GGh&jZR4(l8@@E8N9,HHCLHh6T'5H1jKf&MZE4Q@,lPAHXN!#
jh(2ZSB[hd*-YAJ"ZVpDiIqN2'a86G1J+f8DTFiIlmbkl41qL'mC3HCF-@0FBkM8
dB4JUEmiB2ehrcPB)%c3mf(A)H`E)icTY9%c316"448F"ZYaR#Ye(&j!!h9km1`K
GcM#&cU#&a9"jD`YA8"1lKjV3TLpQ0Qll(TG*MYdS1I45f8h*Hkcjm#lLk)UD3D5
`+ARA![[a+YZ89p(3+H3ST8D2-IAC'cBU*QMa&K,L8N-@ZS5C3Q(56Lqfe1IrCZ%
@+Tf%kf-*c0(+VQf)G@Ia[d#B[m%UApN*ljq1Y5HcdlLdl4q1pFY$$ak`(q%h)8*
r3j[3r`%!!!d0$cBiDk96D@e`E'98Bf`ZZ3#3%!E$!*!3,hX!!&&h!!![#rq3"%e
08&*$9dP&!3#VEXprX!1PB!!!-k-!!!I`!!!+Y3!!!YN"qhUm!*!'L-m0`+hAQEh
-NjQYl19'`fq@C02M0&[CZQQhfDClhB`FmeUCPmQTR%US9alKCi5H'Cl6NpfDcr&
Aj@qfbDCF3VH%pHPHb@h@a3CZBj&pNLhKX51FFX)PYpRAJ"&+'1'a66E,cCj`XMh
###HFF,,2kpKQ(D'FENBifICNNld#Ar8eF,000VZYlmPAYXq,59MN0M[#pT-Y18k
HK5FEH$f"!23kH`!'!*CQJ*RiVl9&)S9Thpq26c!L%AhD#qBB9XLrXqH8,R[-kHd
)qN5AafIHUF%h$VF8FLjbI8,*G!Vp5r41U,)Sb+a[PY)RCVSRJYrMS`R'45+PZQ0
riTJ@XE6$AqDB!6&SVZ,BH-6dDelPf%6+dA58BcRdEQ%*aib8EeXlabBJaM,c16D
*FMcp%XIbm&m$1[c+J"5UK'K-ifAapp#""K0T%3RMecpc$SF'@@5S!,#)468TNZS
f"cT$&l+8d8G+p#2kAFr#,&hcqC0jc+#2)U-k'iBb@8$(X*2%i%L%84#8Vha5E0`
)-#p#2rk%0%cAf30qYbF`c&82KC!!`ISdAI([SH"XU&d"#d%UViY9hU#+3+fTP-4
YLaa#GIRLF[V2YSXK+A#h+#f6K@VhFVIJR&SRh-`X[BmcbjePpE9#A98l6"1Fp$@
rB-TFB,IZa1DqccLP'YU%qPUNNiY&Z%T6`3jUJl!+Y$GX`$H6m$q21LM92F!AHAF
imD8[a(iNB)C8Z!-BXmkHaZTbYc,TU`13!2I,PhLra0*QdN0'',pT0daqjR[YNEI
,Q,3HHIeL,BcIfS2jeL*Z!92RGLCYr"E[!G*$TRKRN!$@lk2hP!GbIdfUT#0H4R`
LchqP"ika*Uk'jXNASrQaIf$rf[Zk$r1d4r1(Ud#6!VQ[l8!@a#R-pFMpeAE@$KR
eqf!0i6rZBP+Xh8DHqml,V1JR[+YL[Yh8-CRjf#[-XVq4@CiVCM0cd#P0H6LUP`$
Ta@@X(eLkY8hdLj,ABch8LNqeERQCJ0q6ihVfZdbX[ci&rq0[!"kG#PQr8kRS-K'
-0BS01DlI*KIT&p03`4pjLrAhk0N5B+R@$VI(fV#DP@`1`VKa5q*pS+3R$$PV"Z$
'SMGi(bMCh!AMM(S`rHL2-0$3L(J[j'cYCL@26Z1m5RTiI8@a'[iHmi"T,$R(G-4
h%jr6I8$*2pJ(5MBI8I,h'(NI-)eCLbb)Nj(VBFVZTMl`dp9`2q%(mH@*2J"($f(
Ai2QS%!c3rrCDr#q'rYm#[$QT&bhTNZMl,C!!$VYC0fJQ@1eZ6ke6F(B'J`%TC+d
5hDfL*&YKc$GQXqjmiX0BRm[#(VJ*Dk4b#9YhDaRL$YEA40T4hp%JhJaM0SCCYb!
JpL,q"a@mk#ffEY(MK&2qb22hV@F2rQB$iR&RaIVULa%2Fc$R`Ef)cd9m#q9Am+C
TL2FUI#CZL1EI6Ac`Qr*4rJ%Prhe(%&r0FClrJ9HMqH1iSQFpF$l"jP+UJ8P$09$
MEC(FNPH8V@SU0C!!0e3$L-CDJ9T+$D![e&XpJBkJ1f49Er'&hF"bV&Cl3")V[6j
4&MjPRQfH&EF%+LPp!%H"ci,1U$6$1D@h#$9Hrc+4bZTNT%Bc1"bf[f9)4Pkj`e(
cXH[&F5Z8"i-qG3!HGR[0r'5H,,4'`U)1FJJNrCNFGNG0T8S!M`EE!R8!AHZFG@F
*AZ(KUQKdDFdYl4jCYJ$lI6FBUJFRS[SR1'DBlrEj!J'r8#AkBQ0"p[!Q$M(RchK
A)aiDXfH%Vm(H)0KQfUC22eFG#Sm8XfIkG&8!(PUcCd53!!piM%a$2p!e1%cN-Jp
a4I$!GlZ8HRhb&HlH#-mpM#4@EZ@*D'kXAdK6-'!(GKMaI5mlX,1CV4XhHl"HP4@
!$r8`aRNNKX9MN!#(`belh,lc`LUk"Yfb@J!2cl#b59h*YK%2(I'id)P'H@M-#4q
P3ajeiUU4(!S2HD42ke#'FVQ$pqRBdcrhk8CEl88IBk3NP3NRdaV`G#Cj*)2mKb4
,#G0`LBIFlQY*jXPb9,bV+[))GDS%m+")-@19I+5VJfSakGQ6S3,Lb&(k-cQZ1[*
c2&3$((RYr'VD08MSBAFd*293qh$flkKkeGNRH&afpKGjA(,f&h@pj1b62#ilHrD
Ph'Be!'Gr9Spr1rYc`PjapNNHPjcp@4VAR(f#4p,CDj1f2UkV,,CGVh[e$dH1kl0
RFPaej1r`S&!*F130A[qX%Q&&kCcr1I,dIcNU*$V518BG9B,(C5Gd8Bp,6LM*Bl6
6Rq9aVG-RH'M0LDkS4alB'#jDpa5ccc[FcNj-,-jA#2%)Y#`GjP(EXM6*)phqiCT
(A(5l6GNk[al[G83pUX8Vp9dHf)&m`ejc,2(`Z@9CX1&H&'i%$DNIUhMd#Z+GUJ#
kIZ`j"Vei`Y12mNKfeQ5G$AE%d(#C[4qCI&hkSak8aDHEE[m2F'TeEXVeeaLFF[d
m(*pZUJ,`X2PN'E!$BAmjab-0[3)ArX+FRNmP93(di00%93!HX@RL-)r4D@+UZ6h
8iA[+SI#ip`#q[THpJ,MT,JX,p`@KL'dV+(fULfhj($@ELAKE`ir[ZpLfr$dXr"V
QLr&BLP9dASrhkL`kaI%',p3V6A'521JH!0$CK1YeckFiUJ$ebUFiUJ!m+(5U!2f
-)N89S$j)MYMY$-hbIpcEb+acVa5U!qeq1H$rMm0!KS`q0-ckAiHL)K*8#1S[04!
2%k6bHU"rqZ+0L$FMh+e@AR)d#p)31Ci$RS8dp1,+R5!"$`8*K6KL[[N+IFUVl29
NlQJmIFrP@Xc$L0Gj'1V`B-mA#(XD"dF6q&D,pXMTT+9iE8'40G[Hd)55+#[9jcF
FMSF"Y,`SP-)!GPMClalU0bT!dG3NKr$SP,U$"&6'ZA6&KPIlUEI8+`HEj4l3pDQ
#+-j-r'U@1NhXSLkI[,T&AN6a0JbG$Ih6!Ca'Z[@JHP#iaeh3f5YIG#0,`lrH$id
"Fq'8+rT6IBRF!P[YJSS#S@""ZDXF2af,E+i#YC85-2#T36a1h4GNU`H#-mKP6fC
pS!NZjK2a[+#%5`Mjm%QRUqiQc,MT"*f8AMl8jfjM@6IF5%9'Q2dJ&12RA-)qZ`9
p1J$IP(@*31XTZ&+'bf4@`,YMM*mZ$1d([0E#EL0Xc'1!aq3BAbeCkS6PL$e#@1S
m`'l)MK&feal!LbPDRX2iGIJDBQX)#ab&Eb1fKE#UJl!GTa2l#2-e`$0iTBPICCP
q#2BLaR1BASG$!!9dD4#Nfq&Pa2JQ@r8Gm#CLI%YibJ$m!6%AB@0h-G5kN!$I+Ta
Db[!UBL(A,(mZ`bXYK9b26rq3!1(L3K(I5PPi$rX-BRb-fANr`cG&I!4B8mHFU!4
ILTQhLpd18%b,AC!!pJ4V!jL44CLY&QrK`3cPp0CHZX`hNqHiSBX`pJCKf3iTX&6
dK!5X9GNEm"YLZ0dVHl,i0P"mab56pX9XJ9CaSHM2'0`GimqLDE1M'j!!XC3a[-%
YqEhq0PPAdHS0"D58bS!rC1"cdQMLV"M[LK8Kb5eRfcVP8+"$Z%9FHAG!DT80j4k
2L1XZ$RHSAGDjh&+E'$,-lr6k@U-*daIEm%55'1S-CY+HH93P)f%,[$*1IX@1&Y3
MBh!*RHH*X9I@Tf+U4H'iD,C+1bE,T*-b-@+%R53fH'mQM5"FjZ2jSJ30bPN$e-m
[qJ`iLipcr6m!#J!plGD6HZb-8-+HV13CH6alFSbXl!R&Xb1-8%)**60kC'9+EL9
XPATNY50--Q2V5I'%VE,$8ra&9LpfK"%DBB3H18CSj"JC8h+-c0L6!C-F*EFQqC@
`)d0fC-D1(#1h4ZD-M#Jj4LKj4SiG'6"bM"`ME!9Zd"&+D**RbXM+E'@2ChEN'8%
1!b$i!`lV5J$0YNf%%!II)`L&EX2h2Xbbm1f$lcdNS,1)4h%aVjQ5@YC0m`-`f1(
C[q$I3$a2H3Fa,f&2kp)*+DFlGUfUk3jBpVAJaq05"m+,+KHPY&'U&UZ'lV6'lR!
29Pq-,5C[[@*RdrN[MfZ@%6VpNM(rm*Ef!qqjad-Ifp5Cmr,qG)1,FK`rq$DfN4i
lcF*!bR*02fJCh$qIjF9R6mQ@d510`Fid#q'*DlVPIX&pT4jPe,4pAG&RrP'28@T
r`VEFUQefEEHSabNeT1K@E5FJ5J@5%%B4P#40iM[`C#+kQTRA(9I@ZJlXp,2rMN@
8@@4+9hk+L)'&8Y4fipMEXaLJ&Z195XSbHL+i3BQ&m"SFr0DM&K&Sb+'4dDZbDC4
ql)A(T9PX@4bJ@AM0)eHl&RXfXr!EQqU)S*!!8AmR3Gm*faENhMieP5P-b51M&f5
SfZm@(VGMFAKm8NdPLr&KimcSp-R%MNkSCa&6LQiCX%#AI*PYMh$(JU-@JiUDPR)
ebc9QG,bUhf+0H&cFQV[l9&prr*kE9l,T**l!%T)e$"UK)FcHT93m33*e$EDZVKS
*jJS6k#655N'(0IKKMC[26dcPm36DJe#$YPPTT9Dj18c&%fK43JeDGf9TITP4BB*
#00HJ"qUUZ-$0d9c&"45Qe'$[kqY2+S`+%hJY%'V`ZPKjG1S35`JQm&+K@rlVCG2
Jcke4+TkJ#%dSk*6kQiFePK#Hc-E@S01Jqi9`0ZfiT'4Z[VX%K6i*ph,CT1PX2"A
1ijqXUPpZYre,m+lRirJ1EZrr!!d!#8*eD@aN)&4ME'98Bf`ZZ3#3%#8F!*!33hN
!!)3!N!-[#rq3"%&38%aKF'ad)3#[M5YCVkGYX!!!BLm!N!Bb'3#3"0ZT!*!)9Z`
1`)qRR'Ei#i"qD&MCjqARf6IbXh0NqINHGj!!Smj@jRGHCckRJ`C0[0lY`!BfY*R
A'h,-CQPR#,#hJBeYCZm"(""!VPpfCCqRQh8,Ej!!4@BJHC!!c##CE!,a"-#"66`
m%424JFZ)*Z2PKA2QAIc4R"j,DH"JH$Yl42f1T%L2!iN(NpGMrL&8Zhp98A&qG(4
HX5"[EUbmFY53!0'Yi8TqIikTqDj[0,LEmdcT#S`(`K((fGKLYlKYM--X$mjR'ML
D-RXG1Sqb1VJmdIQ`1b02[b1SrU1YU8FL*qcYVArH3er1kE'FKbIL$Xe[0QGqc0A
8BNaLZY#@S@RIRdYP[cQKPEBPb1#$Z3[HlDdr@NST5bCEDfQ(*@e(9!dBA4SYVbU
*9KB@983VmXU,bLUMXE+biU+m@'94D8RRk0c5UZM-USV+k05LFPK&*4@9XH,LD$r
N+"J9jXXLNPNMUdSU!++mY'TDB63@V5JS,bUSL*C1MHBAaBT,Tb'f0&T3NKqY+S[
1,UUd+DD%l9P@(#Z*6LdYYhfD&Bf1,L`SL4E-+FLVUN6kbX+#-%'@8L1bqQG&ak-
@HE'5NY,+RfSfYEadCTM2e55DR9p8#95E5JPd0RpB5jZpD&25388Pq3APJ!RmdG)
bQkiL'LX[k+@Lbk*M#f198E4*1%pk48F9&K3A9h51$LZD8Kjc95k2pLqY,,5jqTA
R&4C9&Z499L&j0,GdGN&jlS$1dGekc+M*-US3f2*Ya+K+e#D[1KEIL0,+JQLAk1b
#D(jTe*BkVkUm[+#NXRKZ['8'$"Uq@ippE'P4KBV5**S5C!MVE6ZR0!(HiKf%!J,
LL0+5,R$9S"b3!-$@fI8"%XdU++p!r@h[SLHMD,&B!NZd`N'0T`M4frN`Zl4NKmV
SY),+X#9$I$@IDkKS98Pa389&Q$#[X,5d!VdD`SNhCU`BD!TMX`TXm9bPE8PXU8Y
3Z+NS6B9Y24Z1cV")-AQSBEJ@%+@66jQ`)mR4CmFq8@1m(H)4GMC'kC)q[BQ[@!I
IahKja(jQI9G[&RAeZ[9HHXePJpUhkM,B4R6VIIQ&eK[0-ZY[@$iYfY@,pXiV+kR
XpkRCd'E`dQ[D(0ZqeG#q8p1'AQXf6*0CR1Qecc*IM6KJ40@)rBLk4XB[kYTl4-l
S)8!lrr*@(5C()e26bV`qG-@M"hES'VRLe1MSD0T6Pe2MeRfTFGcA(,lQBaCeV4q
G[15![HD2cZP3BMC8)aTaTaNpP+CeXXKLCF@9AAYAj*99PV@q[*0&0kdZiL*GHpZ
DPY(PRDliDP`1-PBQ-##ZZFeUi`H0c"i8GX6m)30'Y!dpCpSikkM9,cGh@"J#Yif
3!2P%+GJmjN5*&Q355aU*T&"+LP"D'P0QICSIE80pqrDMk,Vjmc12SljT4e-dC3&
&T5pPFT3b*C-b8p)S-bf&STP#ID0-mr[+%63rj8LQY)(!-6L&dXDP88Tq*RNVJ*2
YTJ2F&Vm(ZpCbSRPVX-kX)cEVb6-EU*E4P)(PTT8amrXBXhbH-@Z`l+c$Zal["V`
D-3Da'MNf)0Ik@SMhN!#(N3rfI2L"`H,BJ(FpeAT[(AN2!#F$Vm8I(b,i-RlFYYE
C!9,pC@a1N!#"1Y'Q"1Y@[P'$))-L+fX5V+196m#C5'$$N5qC)"kH5"#'Kr%ZJ3h
Iq&Sb34MqQJ0J%aL$m0A,N`MdkJd)Md35#6DZA)A`jFN%'eCQ2)&`LQad#6*Sq8U
%NdXB@8AV)[L)(%,8%3PXH"L2F+5diF[$H&YQQ`$K6fb)KiG93IM+H(KB-S5[6)6
6aR8fI(Nbr,80@m*AVkS*Ya@X#EF9I'0$G6KP,&qe,Q0P-YbfK%hbB`0AKbHk,[R
ejIRTIHY%@fIf6eZEX[M)Nr[eE4eYNcQ`mE(Y-YY(@r5Pq6`rBhQV0Ah@c9Z2ZD1
0Q@Ikk&BE@Uh[Xkl2QKE,`d&Lh`b(bD#RV$H5%B*FYhb9lFZ-5#5F#@EGUR"BE(a
MBcJN0QDXYUA,X'f'(JhlliPeb*@"&N4US(TLJdfpF9ASTJfV3MH'8,+Qm9UDq(*
XPrIi9Uc8Ie,Ch"p$#p5YRZKB,P)TYGjam2MMeT!!KlA$[N6eZB3fb#hH&D'pfV[
#TGZ[cD"B4IkBIU1LhE1kGl0[1U*5l!l#319KU5"5m2'-1%"X5#Q)h)j5&3bC(JE
9`Ej4+i$4Z"[jPE&bV-h&44@9#Gm`q"69)YiRc*C*DDRB@cfcN@U6(m$dZe&UFG%
8R"3XfYV%-m05#J84#UJH+@c-bpaaBQl@(EEFU9L0lFB8)4A!c(3!bXVb3MXA0`+
%KM!me#XpJPdD-"$r"aJ+-(l!h-N-B0E[4QN9KA%Jm#"A##A$38(4U8k%kP"p5VG
3-#9'f4`*,&Mdc2GSahS"c'Jh5XGG#DH3!($&Yl@0qm0V#r`+U8*FYG!0p50!eB!
bE+9(&Fh%*FV1S$L`HJ$f(D)E"M"r"'C,93-X,&J$"`cY4BdLe-J#X`Al#9K$!&Z
2Hd+6!'B),$aIE!)@qUZ"0AE!!R4A8cbf%bS+riLV#A"p5mh-0`&-fe8iGB5J3Nm
)4e%cKd@K0jY(U$RDa`ml#X&a(1BEZkfQiQe",48-+ADccRaY[Q,c0BD%qFUQD)Q
h&889M(!NeD8'jNYU(F#`9FdV,-LE89CDK+Z3!"e,cTpVr@idY5BH'QDYEli3mi9
&&-AEKYSU'#'LKY6BI%lE"c#DGk-)'UkmXUbmG$VZBR&[V[-U(#A$ZMDN4RBcahB
[e"CSfP&l"81+%0X%jGk"1LJBhT!!H%Nr-jqD6hcc'6A1LKA-ULc&YP"5KBi*ekb
6U4-q0TqL0ZB6fc3G%M-jPcS+G35)6V5MJL(PBCL2)fdA"3-pXeei+-Sb(b[+5J"
1-ap49r1K$l0a9XAFLY,LdPLq"CPB*@,S&89G5HbK&B2II%$GI"JTrY5LiJ*&h9b
CX593p`Ke4rG%HVRlp*M+SZ)+#e,-KlC&FC05e)@i0,kb[4qBpkPf0pUZ+Nb%6$[
LhFQmTfJRNTa`[Z65cV5,JK&@1B0bD&HKAC&Q0pTG`8LC%)CeT4l8dlaVeLSiC%r
8)J-cUKIYS@")-@iY'@M%hZBG4Ee*5X+F$@P2fN["i1jf-k+'jQhI[)fk&KH86&1
dPbY8"SE"@i&jkem$K-dlYX*l92IpQjjjdiEdG0hB$!AZ3hd9$(5IpEFcDkLIH51
!fDBEC4a899!q&iYRI0Z,"``U,Fpa!8,p82VqjR9&r9ejQP0VmeTJAYZfFSPjhEB
J0Qp&IDZlEh9J9[qVU',HYEfleVERlRJ(d%!&)kaR0c460Je5--*kGU0HjPADfl`
5`,6M-9bRA58UiYl4cLZd0m!-0LmV%!E#QR5RhFa,JARThc9jf9Ed&9[43G89I6%
`,e,$EP3Efh0j!Hl8*D&VC1J5'JM!3m`,LSDiUE%RKXP3fXFmEjj6F-KHQ"*lSN1
'dA!&)i5&#@'H$Fbc@f%T'ZlDI5rUBjlac$1f*[ZipKJ!a`M+86$#[@)!CCZRa6a
Y8q48PqfT`$celk)rEa[a19[j&bb%A4`%l'"Q9@"@ECkNjMhEVqhajTSR&DCSFQ0
k`UaNmi4&JL19Q#IYH4Q4'9KDb6H2dlidNNDChp0S'Q-H-iqD4aK"f-RfaDE`X(R
)2'JH-#[-r@DjZ5m`$fmE1i&jk&p9$Fb$[be5[RPJfbS8Q"8eK3r-r9YEP3dZRfc
ZXi[T5#bQpk*epJYJeT`G8QNrK0k$TKJE`2cM35'9aL,"hGMqa`8`rh)U5+9a5()
APSVa!FarhJ"5D6`5hSN9I8)!mjqlI5T03-)lX(T2$'$qFfG2TBP)H$Xe0lF&-2q
bM+HDfq`m'%@5BQieYhMQ9YXaYq"kJSR!k4J+Y6,0cG6"h'4ZT%Qd[lR"KrZA4I8
Q1f4ZY!0NNMAfaa5jRVUEkmbejKTcYER+A1NM`1f5[VPZf`iDQ'YV1Ydhem4AYF"
FrHrP+6"ArED8"1E+VG1MMVQ"pZfdjXfZdb-NfFrQ2&#AqNqa&l&h1Nr(4D*"*qZ
N'6[5GYPj0JcpA*J6"M'#8V0Ic(PN1VFJ0Ae@GIbBM(3DBmpX9p!"'-+6'3i-pJ1
Ucf`(#Kf)b"K086$#Qi%pCH94[S)4,PefU&p1"HDb!'E,EU5Ub[*MP3@*@DV'K1l
i-"8U!*bTjP*&8kXhN!"PJ9N@6S6#dTN&CE(+3ZI*K8I-TED$,l0eb8r8TC!!TJP
0!j!!3LT5-1+R"SqQ%kjCdpe#C#I(*CkjK&M4M'UX&`IQiV$*A)I0LK8RA2[&3'F
V!UTLQUPJK"H!&"5XK%S9$'rIm(b46f9d%*8VQ')C(`%1,4@%HdZ&+ir#PD9+U!T
!CY&X"51mG#LXiaI4(,28KaQI@2QPHG86+c0qkCMM,Kf+kTNP00H(NH+lb,RZKT+
"%mI"jN*&"j2NK4H#ZR3)(DTJa#m'QHD#`&c`eij5G+KVN!"-h%[2pmhj`*GA13I
A!a$Ka#beLpYX[)I4i3T'@,c'e-+FCmiejrMQ2"4[q2$FNF0M-`UbbmZ(ii52Srp
mXS9NFkk&F)k&F$MHHHCX4I-FK*E8eL`fCjNcIE-i$Q&!F8@ZUlrP$53JR'8KJ$)
MjQcE"CA*5jmjSjBj!`h*Ndp@k%"[C,bM6kIjjM3I*VS+Kqq#m[*SpHafHi"#Kb8
R`+Q"169FV*!!D@E&Y0!HAM&0c'N@ElRViXlSmb1%MN$PMU5M&)b`LTeTQ$Q&&Y$
[I*KZ9mM(*6p@-F10)(`1l`+5+5'-2HKS1NE"L2YldV&dR))4pqp1#qPi"52Zhj9
1S"-9M,KrCcU*&LNBFAphP238"52ZldURdQN+4YJQZ,A4k4%kh9jDlGRHm3R!1!#
0#&ZfSY0F(h6"&HlN`*bmG8DFi["da8hPM!LGB8qXED,PXD)+F03X13!p8eVHbei
R!@T4iS+bNeRNQd8B+*LSZ)+Hk1*`36-R"HDN2c@GSZ0GMPeaI6R40bFQFarRiRD
R(ZB%hjb3!)`laJl"fQLMAR5Q3H1Fk3TPr@G&k#`-ijDM#NZV828Ki-)P9[q`CQ%
cp,%PBh1mAE9rKleb)5fQXhfB+Ik8bK*-fFAZ@0)EFqdFSA13!1jF1Nr"#((faNR
Qr!LGMa*ii`[FGC(1`hZ"39GIi*,JDN-A4ZK#E!XbSM6-BF#&5+@c!IKB@Q+1m@'
Qq2P6Ll%h,(&*"q#8Y$4#5cFK5cA(@(K(iEh)(+hS)RFi'SlCG$&GBRj(ba3FiEP
a1$Eq5qNb"5-m0`l(VRbj@D$SFRGZY2iVk%S&)c`hjY*SFj4[MV*P"ke5dC@*[,P
dP6P5d98Z$rcQ#0mFBIZ[SKK,`T'fHaEBVVr-e@dd$K*A4qMU6A96G)REb5CLPlb
'VP8``P`6DC+Clf(8)m@ee40jAQ$Qr@dR3jf4ETP$&%2YVk2V&B`3%6C6FlKR$MG
'dIA9L!i,c'(E%"eY%C8k"#PBU@l)S"ZNC9TL'5&q`fjNra(J'c"f5$Ci+H&U&`*
EE[[$mJZkMTi4lC%9*d&[qUiE'JcU2p#HbP1[Ec#J0,pJE+bm[!LXR5%$Xm'1f6h
,RF(rcjIkqE8I"DQ@GQJV%@FXerXa5F2K"CAPPSBkSb+k#6'Z"'"eTPk2&pX*pDm
Z@UrUK*YF0EPlrD9bY6'1,Sp0,A2lZBHpXLF16eAB,bk)j"E'`&[G+6UKY+6Jck9
-(eSdFiF+ajFG(V1,ljE[PkEbN6XkT'4DBF`KrhIVN!#I0@T!eb%j`l2hlQIl4QJ
QhKX00ZdEL5f2FbTZ$cFTZXR0RDNdc4`5Q%1fcCe$,BSTH'qQ@a5-j&AdB$1AcF&
fY-ke+@l"Hb[GTQ#%0jF8F(0ZTcX8M160CBkCE@B&CNji8l,ASj!!ij9I9"jk(H0
VB&'jQ0PfrCKP*alB,2DQB8pXGp*G#NBi8e-3HMIGBih``*!!JQhlAP1Pk&kh%eM
rI3Bl`ReZPl$qjA5rJK'Rp`5Q`MF9i5'K"*H4qa0jDp-+!rq+"+lDp)!j50%$ETQ
'hj64JkE8KpNiUb"@AM&eDRjjpI)HT4MmLKkdc491DM(S0$B(@31PBi-,$"X3F"A
G8chp5`*6XR@c[5Yj(U+(-ZJKI[dr%ScpiId'M0SmpZIE2UmeT+*`CUc!BIh$f+p
Bm36'[XfeIkTMh[eIr(,q0Dfqk$YSa-#4YK,aX9rRab4Ue0b+bS+Cd8'Pa5&D4S-
"25V92&kSATXcp)UAj6mE$2&I@Z6r(q*ZE0q'pf&k4-&)$YbC"UFQi'!$V%+2i(f
8(P-``S'EKK(hHhTF`8J1h"QddN`2B2kG@E)5B*i`Z%`q86f5#J06q#Y("UM&J1'
Pk2(U-qH63Nm#c#Tk5X%!ppap6`XpM@c6c06!62Z0[L!'Se2S+Ec2d,-+4[aD@TZ
HSqF9M$JaUaDpB%#RHX%G&Dhr4AT*`BJh`(BQhq5C+B(*rmI'!3"LF*j5p&+5X@K
L[SNP6idB$SUHVfk2!`0ci-mAB(S@YAZCAP%``YVjb2dUVEC'#-$(rM%CccmBFDZ
V!4m3Q!0#`$J-jC9@P95'RJ(@)r3+!,p')$QpjJ#Rim$q"Ue4--)&+"h-U6IT,3A
$fjdC&pGQCRpkQplaBD,%T91Q+lK$X29!!C`8Q%Rr+-ilVK%EiY5feNa8Y0BY8GE
rVTQJk&f(hIVISrF9M2"!djLDQ['q'CrNMEh[F&ZL)"JLilB0(6Di*V'CD([a,CF
e(G4Q%%r'rXUJA92G4Z#[l%G0Ze&33l'"XjSe4+qMQ6kJ$a8-EaabYX60jL-cKN!
#r-K0ZLa`-ci4qJ5*2UA2&)b`kl*!T9Y(RbXBi3M+`SP`0(eK4J8`rdNdq!*`[M3
M&AhT6U9G3HVlLVj@--,biE4TpJh-[PXAaDpGRQkJLq3'*MI"c(#G%,VFa"H$5l3
B,(b+2UpZMCc!j'aMJhf'mRaM4LMkaKheHU)*[UAep"epVq!)MhSpF@lmJ6BS'1%
XX%I1M3EXX)d1*[aQ@'#'ED-Fi6k[D)1E`U!MQRdm!rDc!Y#`pIU!1UH&0)TK''(
'Y9iIkXr-SM$E3U!J$CUKJ4RkeiQT3#e0eRe)B)EmI5G",B8p-eLajbiTS+CaLQ)
FppdTG+$Cfc0lflD#A)qJ+B5hie6&S(VEaKK-qh!Y6P---VI&24M%ZN'"'I3hQKb
R1@K$D+M*pJa1BF)Jp(*Y-e!aQ0kf'8E3D2D&IB3&(&%FZ'BB3IZbiR3&(NN)!C3
k-m!c!d!X!58T@IIqJHRrMlU$Zm-CTTpL8,PYh8F#FUCL5(pBC*EjeYFcI9%Fdmm
@(`F"4Gql-SbP59b(kbUZ3i+4$Im%VXIe&GGc04K,idbI`26CfU2e(FKa00lXj4R
35a@$q*dShjk"fI2RKFL-X-bf-9XRS),F5`LN0E8a[326qlH9i%0d330ZU,L"+qd
8+Z"'h&Ka)eHL+C4Rp[!-L+b+`I41P+KAB(VpSm-D!PX6de0aNq50MTXUEZU3!0N
EA3r2p!!Cf[5dNq8aT'['c48hUli0l'jfBl1lABefXh1U1Gi@h&+"24AH"L+8`Dd
iUVK9p@eJ9fjYGJR-V[r,SZA@J06'l+bi6A9eG`V-6Z(D"3fSa'("qK*R"E1cR3L
irLVS[VJ,JGc,EB9"kZEYZChLlDY,f0edBi2eN!!0MU(#S(YcHpj"-4LCa8k,aR6
P$Q`J[KAK$U#V0iRfUjJ4M8dTVDU-cVED$JQP)0#A,B)Gm(EN6SSl*SMEbQ6aMYc
C0eQr%'%BP'V,ed!TZ)[TSKMmkrMjME-LR!A'H0Y35b,H`"9@J#J82STCeNDm#((
54KGFCENc1"5GZ5Z$"0ij3GTJd-1,F3F3UXAGcBi+Qh&)iV$qRB6"jZDGH4I&S((
(ZH+mDi4h45ZR1XdT9q4Gm1l'Zb[H,DRC`$dLh!-,IZfN*T9,"5Sbpc5SEmmNLi"
l4EJALT!!B[@Q`L`'Gd`f1pUUG8291[)HTS0[1LDB(aaRDUG4EHiGiGieZ9-0P*@
%3D2R2AN[aAXQ,K(eZ!rh9Bb1X"YK1YAKIJD0$9kfZdc8iIim3$(SfIBkN!!"MPG
lhl42d$`B@iZ0XhYq1pqd5p)kGV"cC4-l'`S$fiG6h!k$bY+`#jecG'R)VKIH#l8
Cb0Q+3@bfFkFqQ1TY64Xf8$eLdmD@,a[[)0jEm5!hGfb+eMbB$B6K)P"fDdh00Xd
Gbp'*E9,jFTd'RMB2iD'+KlM*8aq-mbM[`m0m%reemS!&E5F2j#aiZ'QP1%k8Y[i
4%4k"Hd+(F2*JNFL$HKD)#RmH29D(*6jq@YP'(SC'EXNjR1ZEPXRaNq2'6d0Ua[Z
D&SVhGH2(qNF+Md3&4r&SaD15c(`H%q%af1eUaH@rA+P(ipf2abVHcb9U4)ejA)6
(@@U0*Hf'5FEL(@q`XBah5D#D`4-L2'(,j'PZ#pE#&L`A"@['%de6hc4,6Tk*,RG
cDX'6)MaTbq4TDQ'#N!$1qr-"bKk%E@1eS4ei-KqSH,+E2'fS(FG-%m@JKGV*Bre
61%ma++Gf`V5&YN"Mhc416Kk`6QdFa#a-)pmd5NkH*REb31F[-ANJ,Y+3!0+k8BS
G"EB5S+Cb2KFScRGcTJ2i[`e-I6B0E)hVfa3B&6b9TbQHkZD-69'2#pQ!kK,K`Kr
RM'-b@pNf4e&fI38q+4IaG-9&lL$6JBlM'9aXk[*-KA9,F)e!6%mZi9)&pCV`$Y'
"ZR!C(k4`Q3hVei%kQMU"UE1TISS2FVh@N6TcHB6,IqakKF3KPQkd+eF`'J8mdX6
G#@S`8+RCK#A1KZa1Zh"9K+YUqPCaX5YFEcU#Cr&XNm&c&-pbi(T62jl,"bZHkm#
"aQE5!j2qkiKAI(##cpDA$iR`)6rY3BTRZe9d)-Ai81&$d81(mH'+ilc4J664+*l
(mhh3XhkCeI2FV"j)Hr-4"UFAm#i6rL00S2K)9`MV2bV#4d&iSp[!2`rVDY'rZ(4
IXPca'4jB!aTDUD"NH-ER"3`U*lSS2XK"fl5$I$#0iU00EF9(Zd&ZrFF)Jh[)ar*
aLSpejE"RU)84AKMZN5&b0dU1`hXmRk!Bj%DE"c)-I'+%6h6lC[A)!FQ66c)iBjf
8Z#cYbiXL['M,+!F*L`dfk&5fI-9DI,**p8fYj#Jr18R$ie-LI-U@8CjUBB++bkH
Dl45IkNEj*$6VDAbkiY2F+*m%j[FC"ZHh-p`SYricq5c&i&EDNEdr66DHEl!0adI
j@5l1%[$&0b$ba%Fjq#1+6kmHj4cJU'K[5[QPm8N,MfX!-H!FL)%iPq)jESD!F-Z
,K4HM@QIc1BT"PV3c**m1J3V8ZAbH$c,(,c2NA$FcmQNDRkmaGXk[pPqJYH)i1G2
k,ic`K6KUp[crCNLdI9bLdJd6VDf"UU6bHH6TMEb%PrTkBh+B,(($T*!!+[JL[8(
a4@kB@2r&`L"ZmL@m6$%BkVBZK65$,ih`TAmB*L!qmQ9mZH)ihh)'PI!9%ElL$m-
%4%qq8[qJq%UATi31iUXLI0AQBD*rX#@$A&`U,dA*[ZHVpAHqrMij6+jfZ5YT0Pm
6i@Xf$a2pRB8*3LaIUpFV[YB0Nd24YGIapBU[Fm2N8*V(0qK[&GrJKSRehmJh+3C
RcJk0`fLHrXEAZ(V(K`RBFcEZ8$T-IqhVVa2$4(pV4d-eT90r&HL[IKiQHVdG*R9
Y4R$dE&N@B(ZlQ@p4I,1Vk!)kKQq0m+eEZN[a,G8![`cdPcm$j1NSqfemZf+3!)R
X%VU3!"EU,r6RV+(5a2TcfaQhilf$le3-QTeG3Qf+GA`ADdM%4ILZ(ipX@i4$A3Z
$MmGhmcf+lhDEh%*kMqrPqr4R[&`ab(K@@()KhFIhm`V&)0NjrfAm!$qSq!%hE4E
5)Rj)IkVi)FFRXIk(p5H+3AkbQk$e2m+2+Rl%94lXFreaS$rH['BqkTVQH$U*(i[
`Bc9MJ$9NReK$!%VaJ`lbUA3arejrT2Mh$V,e2kir92bifjUYIb8rS4M%+&Z#8qN
XIT*A+Al5P3!%G[e"S$riE4N&!FS@j63kNjq+m&0EMRH+Rh$JcU%,q@Pq4[(6$Y`
jG+jq2p$[r`EZ'3IZA,U!Rih`XeXUEY@Mp%F@C*c*H#AGaFrTpa5$2@8VE2h2m`Z
+RhG&Z*+ZiaIj*F8[ZL*F59ITG`2plPr(Lq)i6qSUZTCIM[$,@fDlBT!!XLbX'qN
fIS9I9Ib+Jh8MhD6A"RVY9PJJ5&PB0p'Y[$V#UlG8&4)pLZpcZpF+HS0I%`EIL9r
R0a5rlRD[&I5bISIAm*ZqIZIAh@Z0fl9@J%rjPRjE-HK%&VMe[ahKYlIZkjY8F80
Ka&#XX'E&HYZZ+U"CkEIi(9lVklH5feA)Pr,"kAZDhp9[+RlAE9I@rjl`HkMNqrb
"BY#KE#8HTXIi``KrD%pTbARl!Gk2q'2&)#,C*)r45[iN`TrB%mhQ`I`ahNre'X@
IZN3VD49r&Z(2YZa@9Ya83fmVPGHLB'r`1[fkVpp)lPC3B,1jRk(RqI-)IljPYl)
5@3ak'AqKAe--lT*YX&I3P9rb9iT"BE+le5[d'RqY9b[qfZe@e[m0BpIkaZe3Vp*
VqP9I[jVFVEjeFDr3UrS9Alq5h+e@fpD2mk$Xk[0bS&qQG)MEj*G#LXHD+,hSefa
92l1j3&Zh"AN,#mPkrNiak%1fPQr4@[iq`Yrrf$#+[k['pP+JArSM0Vi(YIk"X49
EEK15[Nr[kaIe#kaIY&d%J5RK$AJh-MEhMG8TRYI2XEC#90S+86')5i`$K',M"YE
lA+bI&4EapE1r$#``N!"#8YMl2&%m59(L*IcMC6Y*93+LNI12N9U5TU4@`Vq[e"C
I5Hf%IlJ%%P%#VT!!m`m4*HP+9-+I,4Q5U53MiHmRGD5Z%T!!H*ar6kNRpCA85rK
l5J0TU!6-'1II94T*Bb@0%[lZdN5D+QQ5m(H4CY*F#HJVcYp4@NK,*H#U12m1dNU
L5L")k2aYTE@d83)'L[1hNVDb[4+3!%LF[jQdNrC+`"KarLDbJh43![k(mcH3!)k
#rS(3Rr2AN4fPXa,32*aI54I*JT(`"p*9ZLN"3F2jDdPhf8P*pi6INjeP&b8lare
NC&IC63NNpTcr"pPGHLJ"hm,j[j@HdNX*&1fFrd[C3hSVf52KrdcfP,d8eU9`3,e
2(dQIL23"BE2"b)*BrYcUeD1USUKNQK-`NEM@hNIdUAl'emmNa%B%@RefarL-[T!
![[TT"G(P-!rmqLPI2aA2`pT+UNN["rP,qNEk4D5I&IUd%Yd*BNY)T&%#kT%GbGr
5phU9VeF"3Q9X#U##FQ,MIL#YRr6eNmNiU+cC1-1LRr$e%mQiRF)ipMK9Vr6ebQ3
Fj""YA#hfpH0iNR&CBHNXX8hr2Y#rrqpe@%+j4KrdUdcTVap6iY6qV&mrkZY(Ni@
(lUZ56Q(K38kV,`-L-J#-K,Ufm#!m9A-ViY@(@U5Y6J0ZV"rap52*kV4hq*T`8re
`S"qZ18C)5'[b`G*U+32e3dS'ZPc`k`Gpr@#b&JrCC#"8f9UdiMD5(C(X4#f'&CA
-X1dq%l)8aI&DJ%9PDp'@fqX(I2e!XKBY(EiGZ)0H%HJ92brA!PkBV8Y(lLb$p2d
+ejJ`,rakZDqA*qYb[`AVq'IFKE[*hK(F$0)T,Hb4@'@m'Z#jf@TdjehdIEkq,eN
0L,$EZ&fjKllAerFQim$QXh%pZEHqapIh*10!kE0aHh*IIEH[F8L+ai&LD12km8"
pPkr[5XD"`@MMXRQ`[Y2AGbEM)&YViiE`-(f(Vqp)a[NZEMMRkYYpIAXb$[a+'lF
[MpDhqIUfC&bULa[$ir5Y[Vie'3IeAYXpihQ#$0Dh+(%UM0D[E`ldc6pYM+`K!jF
US'lTQf5)$2Ae6BP6J'$cXeJQFElXSfp8XNpi#JMp`d5'390pZ)a3iJK!#*XX14%
SBH$)-L"@NJHe!EZqb`LmZIS'*ENZcf5H)[Y'"-+$N!$0!*R),X-hf-d6FR+T-K5
&Z&j'kZYmEIAM`K9I4VV-"9`SSb)bUMTcUVl13V6[D"QMC(4ii11CI,MX*f2eYIS
D*IZ&4al%9-Si'DpNA,Md`emQ%r695LD%5hrSRbL6&%LJB@H9F*QqbYGA*CCqQH6
LCR+*[Y,A9bDArU[YQ('N)C!!9LTNriMX[k8(P)`05C-mQ`q@!j4!#-lfd@bHUkm
3$@didGID"VM'eR%-hXPbS"*,#-)D2SrRkF[eCD`[YbNJf#B#k6L*b43Pi!KCJBP
jI*6N#8BRZ%!@f$`q3PmU'JT[5L$ZPVJB,![dXT!!DcTcES))#9H#"iNp6k4!TLS
"k`Gh9P!i&ZK,C"VV5h"RP@R3YQd9(BA*#e9YHdk+#bdR&+bcXV,#T8m%A#%TP#)
PKDiC&q"Z-&eQk)[e43TDZrD`"faR5,(-9,E#YMNAm(&5)U8+R4L1+p"(p0*!,re
YRA*53r`l2PE+)P,f4ak0i'aYmCh!TmK"8Ui%T#',l`3q85m*p*,Im%'Vaq)lN8q
@LSL!0lU*&L33[m1*MaIc4UN850D*9-NX*9@ZkS[j$TNYFr5&qJ)Pd(fc99r-9mK
F19J*&1GX94EcqA+)(+V%+Fc"IlBq2p$REel6R+SFU"[Rb@%41H`20#H"@Th&XS5
AbH%b6mRK$JXi%rUm3*qh'FXmKf8TAb,c)rK*JXheK%#H(5CAmbebK"bTm,-$G[@
(rbBj5KBS1FS"ZjU[dHF'qYbYNd3*f$jfSPl$0mV[j'JP[h1CVq8Ep6Q"2ZI2FYi
#4T!!cA%05""R"rVXEBaG*@!Y*@EDiN![rYY-dj!!hQ0pJCe+)'c*-A+XNQ0FIpl
*VmTaXP#ITFp8!Q+4lFmlqA%jANj3FVcVU6[j2MP46P,L"0IJ[dZI%HJc0[H8iaL
"Mh#[,)V)SNfF3L8J)PNF+rJ419P183*1NF@aJKr3T`Ikp-diR$)F1!F2bkN41A9
,Ed)Sb[EQNrbLR#DR+`($b2EQNrbmR#%Si"N1'+lrqV4!RlDY0mpd[EQ+Rj1cC,%
5F)jXjUG`Gcmed)"GSp8Z%'fcdD[i+Ae+S#(0YkdVU`P+qZ4!RlbY+b&&b0T+%3V
NqZ4X[8M*fDiV9f1BRL2RkT2dL8T!LE&GZCSrNI2NI#@3!)1chE5Dhj3,j%)P)"l
CiUcQer3*J6jKkd(K3YGCVr%D@4+4*6q5!!4m*J[V(Ij!PJT@P+81&XlLq[K!(lm
9&QK(&YCDIPmZMXM&@aS@T#REX1[i1lP%PLQ"F*YYf(AmV9`UPbQje)&FajrVKB&
HZ+eK,h-0qcPr)jI,&8SZGjQri'rdFB%qlQG4Hi%JRFhc15lIa`Ekf&pEGePekai
6k'1fYHj*YR92Y"[V)QYFE0dAf8k'`+GF+9FTXB*hN!!"`+H2PUYC3a-Z)PH(,*e
0ff0)4SM'LIYZEl`+lc9bV4))`')@!-!GFTeFVhqRXAb!"@9P+`4Ah4X%T`L`S0#
dm0H5Qq4Q*8iV$(j2(aASShlEkaaj#4IU9,NP)VIm5(Q4'adi(bIQ@q8f*EFkF,i
%qNJm[i'lcB%,*&eZMmMY@qB#L&FBV0*3EN&e"B`QZ92Z8S,lN!!YH8-FCHq@Hr3
4HVi5U)ECNMI%SIKHZ8m*L%Uf+JeaQ&iZZ)Y"*Fa@TD%dd[-#2@rc-R'rUd%MD5S
V)J)Tj8e,#G6',)k@1&!r)!mUHF$KD#QYp1'"2R`cMJFGMPE54Kk+b%0EDJQU!@D
FG-+Pq@&j4!QB8*Kam(HA4`A(6E#G,,"1XU-q,0"10r![-`jU%CKaZ(KhNpr,idS
J5Q`cGjCZqY"!(rSr2eXJN!"hXMPa0GH("2U3!&rRACbMCHIG`B%qH0Zm1m)11+L
ALGb&Gk8mS34X+e`YT)Idd(2e(0C3PQ102jN4!99+RY5cPH$-E0Zj"lTmP6bPCqN
U*DYF1rI!NHeTH8B*P+CX'rE!AIeCH8l*Xkjq2D5RVJ`dC%)fYH&cVJel5Qpj2L,
2rh3$J2L8aG*AXZ8&H9(*#`j,AqQR+`*GX4N,U&-@5cmC+#p&j+8Y,If8'dr$-'4
I&S%ZP,`LVbS"`mA@FjM-P0AbQLlA"bPClHSj62DAeq80*G!MXM8B*[[+'RP6L9-
cJRqi,JYdfGBekNeAMq'5+fp&j+drE'IJlPKBSf@m[#h[+((b6r#2dD@",Yd+kad
(D`aZIQXMXRC,QChqP"`S4I+Z[+F%'P"fFKdSdq4pq8#*dhU#2kC,!PfbEA+"kQ3
R9dbQbSIbNC)2AHBT-PA2$26-rrRT"J&,bZE%48mA"lViemN&GDV%j*S4k"RE*TG
G2c8%r84HaIZaI+,NBpI'*E*)2TA2p(50)ae%S@`EPmJm@5HI+eRRqUe%+Z3,q9,
*&kii1-lT`N!AEZfh,efrP8UjI"@4VhlNJmVR$YBXh,ZqPQq81"%Sq'IVDB'HYK8
@'&J@eQ`j@,k0b,GEfKKD6lD0Mm64CVemTf5pDq-MFGMjARj3mVd$HD3FTDF'HZU
f0JCCbVEa8A+XE*!!M8UJl'3c,j!!Bh9"S![qjkFXa)P(!F-#R4rSr&rEH"12+br
3HG[D'0*eV+f)R8$(5l6'e9Hl0MiC3aVNF4h61"C$B-UfmFQbe!2e4hRJBGPq1eR
1m$`[4AR3Jl,&`49+6`ldj*pS!-Tc'P&bLTcZE4IaYYY%k&1H1$5,jA`[eDZP2*!
!$bbDaEMG("$S!rk%"J*5&XhCFTkA&[(50[FYIM!Tl0Y,j"U[YZFVcj'qi,r+#lb
)mJ)($iF6[AqJprpEhhV3IE*pZdbZp*5AVMa)5GR-PmU9HP+J*rhmEaUHdjG#hN[
ea%"2r+9A26!c%Vdk)G!6Y[9Uc2BUrSP*Y#fRKMBSDfKSLVC5S4TbZkbKm#X#LVH
Ai@8U$q`eZdVH+AIUmASFkr%f"F6Fa-[%@mHVUl`k)A-!+HlfkLR2D9,"HjFH'qL
aIkZ&Klp'mHVVrC4Ahf'm"fH&-ASdkc%@ifKE%2bKMc"qVF0VS%FT$mbiZ-U4(UR
hC3ha0GD3!'BA$3@f6*S-VN@Zep"Vj$AfQRK0@HFLbQY)+6T(Mp$$pE"!jra$25l
3)hi613cdm,q,qHYKreD$5[FDiDm'p$k8ViIU)9icVlNH(-$ppaUPDdLdT1Lp[4D
HhKXr4q#e!1GF$`VdS*q&&$A8UM+pCL#ZC1Z"HN#JXrqD+G!$YiVB"RV!Rh5m-lh
Q8+Zj3IIArA4Ih8I[TII8[I8H%#)r3d1B@rH%B[D&ZJFYeE[VhI5ZHKHkZTEZlm6
FIGd[,R([kljaK8KIppNQNZrV[EDTd2Ykcfd#mi(ZrDIk#@T&2NVP5&Xq#ZE)46k
+jYJpRYiG(VhE0PUTVhH0Xfem90MaFHVS`93d)rZ'R$9ekB$ke2,0NNj[,AQl[If
0Jj5F6V#f#kh8dV(8Cjcp"CF2PV6lX0hMl5l#qhLlMpYpmZPRaE0LP"QM1M'U'k&
k1C1TIS`DG)j"4kJ&T8h2[Q%mE9H8IF1BR+8C'HPHBcY-GUBlp%kkZpI5Dk@l"A$
rTYLTGl,c%kbK6!rX0pded&hr1KSb2DLHd8-k5hIaY9AqqPQeepGGiRV!G65Q)+S
IG%5GqDh1fGIM[a1m*VC1RHPa[D2Zj%@peVTM!2GrMp4d$CTTLZlJYI%dQ)6T(YK
qT(F)p!kr5+YUe#86[jq6UY[VGRTlh9DhdDd$hAjEcN#hfcSDYrqV5PkJfriUHaI
S0PX&p!,GHUYdBDEAQY*d9,I5,A8,h9`hddeeNd"(IqYTAlH+cp*!Yrcl,flS&R(
C8PmhM`Z*qYUU4FdScF-mEBSqcbXY,mJVU5bSl[0-p`-FZXNr9T8kZL-9GCS1)E3
hff-5VXLq-@I*a,FR6Cb`BY+%*HpdhLRlTTa'e2rLL@[I,XBNR&%)j*f@AY)1rbe
4+rZ@R'AfrbD#Ll+IbCQH-CiD,LZblKP`&m&Gkk)C,E0[R*JchUc-X6%cl!aXDQG
,BilU4VUKepEEAMF)G12rAFBdL0BTZVlAcY0J@+CllHb%U4ISHVp)mqQ'GX+daB5
TUq[S6*fKdl8+G0eY130GjpIcI+"VK*m#MGq!qDr,8k$6IlTU"&TYAEJc[HdTPl-
de1qi"rI5!ILM[UkYdh3Y(Q&CQM`""-PbVY+TI!JIa3Y"+P[%Tr#&I#PI`9H"ph3
V2`B@cV2m-JJYEr1(r!Pr"[,'pp*(EiFcESS-`(&hEmR"HA886UjPZ-mG*[1eKe[
HU9TNL9bX'HIQff@&2!6fr[2bNV`PDcFDq8UqhDLplEbdM4YpMH8S[Ri&bIA,UM6
TfVqZArM0VIMkCI@4l2VPke6V+5h&')-#HAbl`bpfK6683(Yr)RN&8%5YS4F&fUN
BrC'p%N!"k*mhrf#MqGGp0GLSrh@q#cCZr1ZaU)jZ)2HYHI1YYpqC1@[YZqp&+#h
RX3mlBpaqp1E(Rhb+Q-q5-6IQA)50dZSQ`iC+1G9Yhi+',Sf"XYk#fX5SrTYB-,&
IaUJ4mXDSF6,c6H1T9BbD),jTM*V&U(NBhk)Q[PD-@Q+J!eNVh1BD!9A8)SAG1N4
UAm4G()-8(1*JYdh'KHLh"lTf-8,!$L'k$NPd0iIS1QEIR"1M6T0TahEfM9&Rf&e
qHTI'Sl0#ld9aEpI3Hh(Ffqfr-[rj[D3GUY)p4MX9fj,XR#K*$(p"BjI`@9K&m,m
Pq,Q5@h*3k9hM&GmYhP[6d3flarZY4c`QIGQ5'2AXh#llPM!e)UeiT-f`4df'hXN
-k*3piafc9df'2SN-B4DJlKY(hbqHj4*JkKr(0U!Qmm!Dp0Ra$)-50321[H0i"pG
N(9*6ND(a$2[8C"L@c("*$(m3J3b`4p4Nb+QT@CKT@8C1ESCR(J1KecaU&FmH`95
hrr1""8aprrVVi"a[q8P"r&G'MdEi'`PU$PpQ49i&ITq!&YVIJS0pT[ep0pJAMFi
H0aU*VkfSR'[23!pAP&9JRk*R"Z3-c%EFkre($,3UXGqihhGMFEr[aZRZjpfiD9&
H-54AZ6dQX[A["0[kpbV%L32fd&&$*Z!((hLrXEQP82U(q''S14rrjK[)4N2`1Zk
$j[SmcQrH2+8`c)(I*)%mq((@PaEqID#,`b%dU9h[fGq`#he4mYb22q"AZ1U6Pm[
jM3Bk62Eri4,j8Zb2$XDaTMJ"rM0$Re11$hhEfEk)qfV036ekaheh`lI,"m[$1Je
`L%)IMVh*qNfcV[m($3!,3R9TE'3J9A4TE(0ME#kj!*!3Uq8!N""4G`!!XKN!!#m
,rj!%39"36'&`E(3K!+q0'8#[Thr$!!"AC!#3"LfT!*!%6+X!N!M[k3l!6ir6j+X
"d'qBSj9pARkH@@rRCqI)FZ4cch,8fFVmcZ[-jr6lE1*P0[#b0j[Bc-[[c-j"0V1
*fG6,%1"eCK1EfFcH!cJJJ&`rlXQcKr*cBCXYE1&3XT!!#5JjN!!m*#KB#-36!!G
fGSBRBL)Dr#940PkH0'r(*%5-AA&H[fYKeeNalkHVB6GE-HrRJf!I[-,V2V'J-$F
dZ,bJX%b3!$NVA&SqU%pfBlJLhpmM+Vq9YAZhFjiKZ3jY&1A&L!P3A0[T4&8q*4*
E'9,P1B9Ca@8&T`iU,dh0q5HJ3%rI(,lL[,ir`CkpV-[bEi!QIpPYlei1ZcAmhm&
1AGCPa81`TklB9@0mGE[q@5VlRHTELC9""Kr-)r!HE2fKBSUI2mTD#eV-EjSaX8G
fFDKdBP'S2,qJ,&5@8eT38Ki+Pj38&Z5%b`Z+LeU(TK42$%fB@&BH'P03#UZJU+`
mA&JBkSBFHB2mI+P%!j*kKFYb"hFE&'UAfLl0[NR!'Tm-l%a#F@b,S1$MmC'ka![
&)r)!5P!`T-!2LU-UP+KJa2@*9%r6J@DR"l0K'UQ**ERKmVb5dZ*aH6RPT!EllLc
R&MS3F!*QKd*MFR%Nr5qHqB9UT&&LI['%[**`HElcC-%MCJFDeqbdG8Q-eL@I2#%
23)+N&!`TMG3PLC)9$*lJqpRm('Gq*PD8A)(e*mrm4,A5k-$5[2+*T8@6`S94e`R
K3J&+S45UUQ")TQd!bU0U9&h"L$[HlpYFUN%eUCD#+H@)m0#aYDQ1JZ'A4e&61NM
S)!#T5r88$,5*"9EEE+IkjXF!c$UTiEa*jF@ja6P&%`X,LDBKE`U&#`[+&08RX65
JU,VjJ4S%B-3(A'3$NN*dB6*UdG"mVkJKLH8[kfp%)3A$Vh)bTCM[222G(afP+13
D"'8fh`E-Ym#A8hjU1C[[EDIp#)2Ui@e-643-[hKeU)(jaRaYYJA-0bMHJ!&C!`H
%aqHPPjB1)1S+pTT'YT!!E,kf%,CC#%h`0M9If@l`)65%pd[cKINmB,k-31K4@*E
PkQm*-!VK#`[KFfYmCEZJMLZ@4d(c@4Ac'4U54me4k-#iJC'1rT310Tm%B++V3)e
jTD@K9[KFp"bb2S8HM6(!9XpXTC3d5N#Q#@9MIAY!f9JaReLmY9`AYdDI0a0UKXS
eTd-8$,q+VDQrqCKD8-X!c$UTC92+LR-,LmH'bmBl#X,Rm,BJ'Hh$1*TDdD%+4X6
I%@mE"52L2iT5UDf#%I'hTc4UTf"%r)I6BA5iJK(aYm13!0"H`BMifp+4G*5#iEF
*X&'()(9!Ib4RjqH&4[[$9I'B8-Mf)mTlP1Z$0T4U2[,-4hXiSVh$daD&k"K%dHT
5M5DKdR""@9iZKT!![""kTVLd8mL"1Yb"DNH(Q3m$jN-3#KJ9K061a4e14jJ2222
"2jT1!D'IScdGDGi2Q2GMZGZiZ+1SJpN5-&YLFBGD%M`3&HP%RFal#UCI+1Xr1SK
Z1jJD$XS[RSLUp`RPj1IPM#mT,LJUpf[Q0d-A@c)fla%P8%Z+-jZT-ad6J"NI'&e
H"*EY60`AJ$U$eii91KETZP"A"F2(L@68,8MG8)+iBAPP&S`JNe"hmkkLlLl*-8M
E)dJp-#e)4V'I`laV!4m$`1p36l-T!$-qN!!lTV"F88qAY!IeS[3JTIq+,-&XX[!
1`G[,E&4)%$mFQ3D!QikMhZCYkU2J%+"#c&$U5rd8$#R%R$Z!XN&9EbRU6e,Njmc
'Qk&JX*f@XbME["N`EpUbjaHJ#KR4[&Q8DGj3P1Rb`'pH$jMAEIq9&@*)H-0fceZ
fkrZjZQA6%-S+)Qe&h46eGM2C#$U*MUH"#SDID`500+r&QGGXLS%9M2bUCelppjN
-G8BkX+p&&%EY"e'fJZ%M#Y0SmdUFHF8BK8V%%,hXQCIh)YVSceF136a'UX(*0&J
D*ND(%H*hTpQ4-f&Pc4l&ZAP$`U@P"F@PS6ipdc%i(j9k"'CAM%qFrFM*rKJejq@
j2$MTD,VKb8[p5DA$#a[KEmf$JpIe'0)RRDLU2pVj`0EBrJKNja5fc4iIkT!!Q[E
lHQ"&AkpApjkSbEqMrrqqK+qAIqBPG-[+kQmV%GNb92mY5Dd"HH@PaC2c5XHAKAj
&M$d!YK3*+r(1XJ4A8E41&3PrGHh+hHRI+RFJ,D%Pi6%PEMk2`h$ANBE44,U#EJK
QjBI,mN+(KBBA&qApXj4*I3XQ(&)@bV*J"i6r[VMj9e-&N!!le+GSE(lB)Ir[eU&
!kU!HEIYN$NJrVT[Y'd%I#jeJAP*d!R&rT"L$6F33"IlcH@F-M68[HZE&[EccNN@
4J(FS$9-`--VBR4HC&m`'0LpBDYeJ8`c$1ja'+"MqcL8HbjD4G++#%GZj2'r@Qh@
HHClUTe&`E&kjf`VP&T6kAVIck9P3+QDp(6r@@FBl-ET!D83R#DKCD"5GV'"`5D6
SB3'MLRR121ZCjrcKF%aaD8kH4H8m2U*REBe1aMZDFK3-P0&IVCPR+*GKB#@6L`'
L6kKA*'8)@kY`+$qF-cj89SaC,&`HQPL@9eTQ*e0rT99B-,SdA$SPP"-Z#[NirB%
0X,%c+LkGiXDX(,aj0%E"L#&qQXBb$#!HLe'S@kLm1$3k$b!Rj!&AdGK3-A#8@X4
fGiE!heGRS*3Bc048M1%@k4Lmq95JB2KE(m[bifLmH8V"p([)lX#`,V,p1i'+&!b
fV"@(9Le@91`B!9lcT'HHr,14U!MT5m`6LNSFS4`!9+FS1X@PapE021kCarIdi41
fUFGAE%)H-f[0S`(cf0j0#*ZePJiHY96cP#ee!Gj5XdC4U9Yi938jP"%'3NabGZ#
ULFh04*UNB2METjTB8%dfMbLDl!C'kcr92+b`er3(6HZI3UFT'2ji94FlViF#jL&
rbe48UZLdD0kkG,Tj80(T89aek3ccJ+)ch+B&IV1DcM6h"f$@5Fd,PjD0'C0E@P(
2%)AK9h5QC9k,TjDBqfeC(l$'JpCif"U2f#E"IMBk'YlRQI[fV$h+AG'UBU9f9M+
GaHp8cS5B![M%K&i&4EPjTFhiqe%c#)XHqr,J!qHEap1f1$qq+lG13mb$j[(MCN@
S0C%cFckali"Z23EYRJQR@G+TdUFXId)icf(pfdaBYRBpCN+E+iVqr`b"[hebrE*
'hh6YPG&cS+e%C#DXqPX50@K+@ARH"$"iSBq@3@a!MdV9Ma5Udqi-R5*PqCm0*Va
rYFMrRI$mQFkXX53i!Zp8QUCJa%DbHmdpE1ke$(+26@'Ep'bDVQ$i)eNL"[ecD)D
#%4[*lUCcc9dH6$Z5qGZQmR#T(FdLhQcR&6SAB-icGbSkVi+A9RPQ&G9*Si$,#A)
SMrVk`bIQ6PZZZbbEcDKBK*m[G$l!A%!c&BcB($G,#$1lZF1Xp-`GIMQJ"bJYMbl
PR6HkNcFBmB9QiVf3!'BV'*&pqS&d%9fXB2J%MIkM5m`+4CHiYE2eck&,&Ba)!aa
JPTYPjRE2,2pV*PeQDhQlVH@PMR(YV(0E`0`@@dD[X-%A9l6(8XmXr9-M3,04ZlP
dQB,Kebk!h*I6&GE`!36)-lILfGm*#M39!lc%-dYm`*JEFiSR&TAlRKl@)h3C!&p
*9bNB2Z!N,1IRdG8+KMm&*@'&IJeGUf$%(F@-RA`pF`YG4pF(B+,%aD2(+EKpX0@
TTVRC-cIr9CcVA52@`U4dJeQXk!Bh59RrM@D4SKXGGZZI6`X8$(q&9`H6e-+!@3M
FKAP&@,NZF,KV84ecNfGZfNXkE"CC!PaXHa(b(CX9%JZc`$-,pQC9"2&0Y)hQHfB
qe8dM,l+*pC2"Q@@G2V(49@LQQfLKJK%h&$NEBJHab0a)+2%Lah5T@(cF,(3c%Ye
#5a3-[qY5XHLqPCBU'$i&T@+*I!2GCUlhB2j[+FTYJ(1lZ8l4l@kChKCEpQ@dA-(
`biIPYlR@-pIZQ4DAZcaBf*YV2(10[rJ"4lK1m&f1mF9FCrRZHYY'5bYDifV2A"h
0kCC%[QZJla)-8N)Vc$a&+pcDYb1DB#AG3DX)Jm0+YrEYL)AdAA5hJZ&cJ9f$hf2
!5rFiQ2#E+cecj4kBE+kb9EREX6"fk1D+1(1&$ER$Y9iAE+6[&ESAaEL2lPF`r0E
VJPhhDX+i[YS"aBlFA1kCbrpJ6%82906p-XpFpTmc#Gd2`!qDZBSHG+Z4(UM$3iS
JZ(,,mTlQdML$IDZBZACk@BAhBF*DiQ(A',faRPj$MbSB2ZlHe-I-mFbF2BfJk&%
(V3re0CI%Q8Z-%AS%U0BDc%"VA60NB-ImQ0"M#(ZFX,Cjh$9$"[EE6a+@3dmk#"P
BS9m8CbkbdU1R+ZSqfc1crkVl%m$fY,P3dG1ZlJ-"q4P&ccKN!fQ3!*N9CfDK11C
#@ha)h"6GkFS`"!6a,$fRB-J)hcqFeY&k"F1[`4!DDQCkCZDH(Ph[3')jD5k)-aJ
R&6eA8Elc2A2qR`14QBI&0bMl6`C8Y0J"JDV)R1HCmrD2"![4"Fr6"JA$,qeSl2a
HS"F9$,p%@$bDFq2-ZEC%,eD8D)CRC[c9B4Z!l59cMU+A+VDi,bYkf5'c@pcTF@B
kXCKc,,0-arX+[DTJa(B$CjYTE-kfSa'8@d+[iRf0APF`r0e!%22H'r5QJK(E$8b
PYmaC(X`QDC4mbX5mdLRBia@Af"9N@53!fp*-&b$d&L#pEFj8p(C&GFr`c"Rqf!9
PAh5aB(h4YB,"+Nc-@CB4hSaX#14KfLLd%@!fd6X+4Ub%Tj[6f*aZ5hLD,H%lH0q
Pc3T'E,FkKGjM'#MRHeJ+(K6U9MBq&"jG2,%m00PZF1fUe@ie1VQGk@Dm@qKp"F0
Ii+%-jP6kJ+!)1R@I91S$TqLa1kD2c'4&(mAdHr4aN!!qKNURk4#,0p,!f0F@qh,
(b@'VkiN8)5,VQ@chpKp#C61*YK*%BC0LXTkY&Q8!@DV3TfDLSNqGc-Ik2a2k$)l
2k3X&``F2-54p'D3[8IZ%3IPjKB84TFmAH,qLE3U'RmIZHlm1dYGSq!2lqc[XJUJ
SD"[HE`bB$pV4U-lNfb"pLb,%GmGDfXpLS#"N-p&@l408VBbq-k8"Q&&Y%(5Q0RF
LqZ2l)(fr+hH#34m*[Brh"rT4`BKX)UV6G[T*`I!R`L5XpRif@#Vr(0e-9+9I#2V
,Apaf)"NU`*+!+BN*JADi1$[R&`F-&+J4iFmTPPGqUQ#M)Xm8q5aZbD#mf1p#jm`
ZpM@p3MqL0MY*+aJqlp5J'QD#JFB20@@$2Ck3!-CV'-L-iafEBM`c'p"A%)Z6aP6
[9pka+ra`D3lU"#+B@!SGJ&2e#J[(+8EA@ZDT3Bh01)lR!`*Qh,qBKb&YYF`$25F
RQ!,&#DlEV,p+N!#VB*r3`QFH$")jH@9PN!#br*0kV'!K3MmJr`3q!)fFciPmB-$
N4qQ(S35cp&1,kR(!M&8-pDZP(q[hK+&Pj5!Va8&AJ9T8Qj1#R)5qU1+[3l0kZ&*
$RXV*R+)BLPDE#-*6VKVNUPCmG@5(m5i*T+YFcBa4A-dPU8-(FI8J9kpN(Lc0fBb
e"80ZNmFe6'l!j%@CKfZih2@T!GF-FXe+jXQe-12`eZ,DLQXjjQP#Kh!G2NKa(FF
m6DJCec8jLZXkjV(qHPaIF6h(-%fTQ4NG-+1Mc-2eA9`6+%A$!411-3qfMBUK&Sm
bcmQH1CN5dbMH8S'Y4'fm$ELKBPmK+pM"Yc#Mc%PX4YNDRf463#[,M6LNZ*(M'C[
L4'l-jN6,-ieriaN-M18&15%dI&PqZ$3[er89e)lFK*XUEZ)@-LeS*Kr-cFa)EUl
iB*,Mr*L1I!Lh8!c4RYe$Y+!fh*,"05eGr5!G05-m-q,AqLPZjAUY*EAQ3i0mk'p
GVaKL8SXPMGTcDfkMZ(A&hQQiCiE[aJ,GT-8#Q5LR"MPe9pmUEZB+ejR1jVDFCSC
a1m9Y(EM1e)d2im-9(qE!3HKSKRTQk$k+9`cTTe-mGZ8MJRc%lh13!1)d0iVfT$#
h&fk2(MU5Me*mT12URM6#$1%1h$&JKZcMkJk1Uh[5FGc*R+!B8fI8Il3CV2KS9`M
VlacNcK$%T[Am*eN2LVAf),qe3l&b46KmX$91X,cB%EbBcFI`X3'6(52bBab4pkC
"h-8-8JaGU#9bkqmU$#8SGq2ZLVZjFQ!0a6f#h-1I)hhNMNUkiqh*kBSMiXpqP-'
pJYc,cCX9P*11pcJc82&adFh5mG`lb,dVU4ck(cE3P#6`X5MCmGc(C!A-m6%Ula-
6DR,I)+UeQmUc,-bMm2BcQBVl15SIL@EYc`-8pL-qPBqN8CaK-K4$*@UTh2Sc18Y
a4#9k)Sdb!`*Q3)c+Xe`F0'ZQIm$dMe&jKQ8%5&#M90l2-rhmR9*ZFB4TiA%0)!C
b*$($E%B)L5f(j)+hMKFq(Y8Db1LpJBj$FL%NkX[C2$KJqZlMN!"XaaQjd)bGB2S
S2U(#2m6d9J`KRfd8kamDj+&BDREmrcNNe"`KGPd3)C2HeX!++)%(Sc12if%m2'#
1Lj%*G(k@62+TM%HBAST(1$+arT(#)e(R%rNN"GQ0AjGm'XqMJMcUEf3#)4qIc'(
&*lXmikQ)4`Gjp0r)"-SqcM%JR4bATiK1iG`JjeD5#I5UE(VCNJe(bATbRZN4-$e
MC*,RFTI6C"i6j$'9C0,$`Kb%Gk`""ijeC()'ZMDI-9iML5@6-fJUMc2G&)pcC',
pilP3SF9pdML6TTUZ!G-e4LDBefcF'9#$G3QB,M%bk@DTSD##6)lec,&lb+5lVHe
)Ql'j+mX-6'm6Z%LKR(j&Cp$jA"`%Q0hGTELS!Z!aRMRQ6i$F&'8[i9-80$Mq%$U
,CTR1jQJfR@e$(@dlia5mTBbqKpE1$U%f45G'*6[C)E6mYb9E,f`H3$%Ca89Yi()
YM*Q+*r)Na42G*$H,2ZE*I+VTb&-83j'([NA-)h`DRkiB5M[R[iA2i$-9Rq(BCKC
G`QHC$SV2FRS5kjpU-**"r'3R3HZIaQFVk0,mbXqL#mf4RMPbpjKjYQZD#qPLRKl
NkEYSJ-e4eZKJdjcT)-qPKAb1DDri(!ICqQHB)a62F&1cpCr,jbQ'--U@B#jGaHI
c"BV2Gb@!YXFFlTR$p`qMf&MESPa'9r,-)-qXA0iT2Xq"ZiCZj&PmSH*C$Kad1ZB
`cabf(pb&$YbeG!22$[,XbST$P-fQ[38CN6-ZT3Ii)S2a'ZST@f(V[jJ[8Aba+m*
5@X&cq&,&Fe`4PN+fNZDCY$rS4A&%*h8E,HHj3CjEbHf+)FUbX&E4[A`CAkli-JF
,@K(6eM0Ypm##3-V#ZT2Zi5Z#I%9P9F'kLNpeXpGDHTH[&)EHLDrLHBU[FV2A@RV
6T2,9I%h!T1kE[DjfXpCDHS+[0GKK3%jNJ9[rG8'qEXqmEPP`%U6#GLhZj-*jP50
@'cZU3'CP@[2eI%2!Y)j09ljH+J"4aSYmScP8mBeZZV,qqF,c8FN&I*0Lb+&X*Ck
NChKKN!!AfP9DM'p[`VZ)&bZ'%-NQHBE@mFe"[YQZD(B6mf+mYaM8q4DAD"eYi#9
"AP)j@d'kbZC3@l!E8,#@I+YT%6!YBl29V5lh5r3U,`hbdXVC#X*5BFM,q$CcL'*
SPfb$[B@Z[*fA+BD%bFj@Ep%QAQk`MPVZCL[VAm%V&Dp`-p6EY-Nd#aMXJ5+ce8S
ApaE%"JF(c-'afDUjEIf)$XU12Ndpdj55dZL!h1)aU$P-P&l-)EDU(@dZD,4Y3EC
J),Q$9bQ'I-M@FJYpb(F'qFlI'NEaUJTX66c6j1rBH"*UI4IIVGKUQj!!G#YY0Be
0L!dZ3E%*fADi'qmpI+rLHbT50$)0f65b+4VD&"!ZmAem[q,l('&Yj8,6J&Ic!`(
6B"pKVADLX+dmJKrNKa3r'282iiIj%F83'MRrB&l$MbTlfF(jMqHer*MLY9(r!(k
FRe!-VC!!mrIK*rNTa8p'rHRm0$qMq1QS[aXrbmmTKSM(qBrKGEaHmEUS[b-rcaX
83aRMr1hj"Aj4m3Y4IcYqL9p@r&,8hiCIi9F93llLr#hj0AjG-E3UcRm)[m&[+Ri
MkQr+Er(ELU&!FIj'[*%h+BD)a2RVm6[mVQ)S4Tcr)0l-lbQ'rX2jDr)@IPraPUL
r+Rr!(bU'c-2j&Ar%(m1)qMhHbTmSKN$$qD[`TrbCiNqMrMMqR,p3r(R%$lR!Prb
9iLqMrPpi'hqY'(S,jrq4[q&[&Am6pAr,hr(hLVq,qVrL(rK(a6miJYT+Rr(f)'q
(B,2Q`,a`lT5+d@0LQEdJi1MU4dGARp'ATRl!e)qHSq([hBca&Ah$2jPkLL-##IK
0hB#T'mR$TTi&mDf$r#hp`$m(q@FS093)Ae6BiJYT&(rY+2P(b$B1#TL$!+%m2"T
3)6QaFEq3!$Ce!UC1,1i,&fFJ@+SG-,9MFCrjF@LI"&-VB'V&iMjaF98J4+L**aE
hX9mkY'23e2"-MIhMm)GqiG(-+Ib,UDiBFK+E(Aj6,@#Ua3U2Bb1+hrF,$bDS`6Z
#[!1+K'Ufm"!m9@JV)Y9rce@R*YFa931QDU`klcTm"d&5N!$LQC6Gb`KIeK3!-6A
NR5CCm8kA#hk6&$"*X9SNff3390PD0-)UA`GC4f[4[k"S['hh#6KF8KLT"948YKC
0ZEP4!4bBLGELGBF2Hhi6p%a`ch!0ACLY5dYXlBha&12-QXd,[`N%$+Dl5&dm#pE
Tcm$@DEKV"[K*P1Mh5,Jm8JhSh'`ef[%4"Y+5!f29f1$LfR-(NaJ`LE%iU2PXA%I
ZE+S%6*9B(#4p0ZiBlQS5!LBK&JH*SBhVaMd0P$-(a1+JB,4akGcEa!G-I#cZ#4I
AKrZEZ)#"%LS5pjL,'m"C4J)388EMS+qdFFGcYJ(ei+"!*1i4&cHBKaTFKS03+K,
hN!$V(Ua-KE94d2Rih31reTl@[dq-5')Rk`FS6Zm8NEL!hKPG"BJi,#-j9q,e$L@
i)SC9J1mr3!5Al54"ULKa!L#%MC,%S#6D*8Z2F&%16JlBm9fUi$e3rk,N3*GR&)q
@3&!#pXj6*PERb+&r3Cc'cES%L8-KIKC2ra632dG(I2&FjMc1Pf"3JK@C%c4Z$3T
$pLT+NT5!EE$J`iEb,%Q@&,eGrkJNf9rb)+CFUNSe*EK(Jk%IrK+TVRp38YdIqRe
r$DQT""SHfeP&A++r$qM[Sd1re(4af(lUl`,kZqM3Vhm!cBJ6$@'9@5DeJP+VXJH
8T2LL55`G6j2D5R$cc[E4C*kL[aApV@f!lEB"l"8j5F*E4`j5BJ9"U1e8RUUrd9q
crXDQX+IL"&IbT+l88`+0N!#p-M'9cj(kdN!*Y%!@f&3q@fm6MBYb5KV%0JEk+dp
rj@Y0*db*#L(KLZSJ"HIVT+%d8J,9$rDX2)0Rk#mPa"SA+B-5`P@h4U&"B0k**Ii
kb@h[Ti3LDNaFJI'(2K&SKD5a0&(5f$AM$1M-QXV"qJ[pZ4,XHl(B!lBVT*Nd9i*
6FEBjCr"-184D+$R%dG8-2PGrjZR2rQ1F%T`3X9eh,PmJ,B25mZmk'X(DfZ+EcCG
++cP8#84$&YpX[NKrkZP2pq-le1'lL1G)kk#dhLd,%Kc(`iU2jr&1D525"P92PEC
+8Ph9jr(pNLEYp#GkUa,FTE09RmHhbQ&bZ",FTE09QFIAba(5AZ&dS9q9HAberYM
6(qmDdm6GP-1bm$Sj-LK(rNhQ*)Fl,20jX4`P(C5i@hA`,p!IHIUMh9Jk1#`,H*&
d$%V(bRUfFf4b1pmYRH4S*4LJ-2V$IkGdPQ18i-5E"BE&QIl3darZB4+&H[L-ZSa
AbE(54FQa,[0bAU8rm,5lD)IE458P1EkGPG9$#44"0XFbAUlIpr6lHa@l5U"DLR,
D&Np[qAG1dcK1b(UVC58)YU5VG&-#KB6YcpAmYR5A([Sp[9N*K%@f2eIcFp*6dTA
dG$feQKq4AR+FJL$!,`lfArTG6lqlZkHFaSJIi)HPGe"krkST9!)KNX@aPTq52Y*
A#64&&JFfAISG6lqc'dGIKq-aIP,k"D9IC@qLefe[2Xq[5hmCS!3+)pZEcr1VNL'
C5M)F-+bip#C2EpVEQjQZ0cI`+j)PabZ"jXKQIS&Id4Xp[C%#VMGY#B%E&qKXp!C
q3ErYkEIhG@@&3%QrjHQhpRBPcJLbhQblXK[HJIT0*30G9fi%Q3k5E2f'IPd**$'
f+cIb&c*B6P!bf(A64Rj2KXK3*Hk#'2bEp'ZHIZh2KB)-GCfeL6I,X+!-qdd%)0!
c@9JIm#FbA%BS'HjJBIfQArAdUhYJ3ACNBAh)@f9N8%C@0La%8lCKYr&2FU+FT!3
hJ'c$EZ-ICC5FV!6A`ba)l1$d+jjqC@r$iQ+BEGL[q3F*bfJPBCIj'rj"[qcTPrh
bP19(k"3H$%!qSBjfHElQEr4,RRjTAqZH90'k,hVDh@,lYpDeK`cekhCLIG-D1$[
+fTiG&9c+P"a"@d!!K1N4U`64,dJHDpaR#dUHVp,jGAVda3LKL($IcBeS4aNMBj@
-mEN!!1kAI#R3'r6c5Y"@i!,%9*Ga-Pi*9&"S@[LV5+&-8"Bb+JKrR&l[kIAljcS
RAT)il#q+JQL[5XQ,J,dYZ!"f#-95SX3G*S2Idq[`l!H(Uf3@R#G*FNT36URN"3L
[3+a55qk@8J&&L*3*GJ[3VYZ5em))0e%QkHIdXdT`1Xb@["B'imPbUK))P@a9DNN
pQ5+R+F'T-&Z9@P*E2q2TChB2%kHj'Y6'QZ$dS*bqHbM"b6',Sb''mM2N6#9R1"`
BrIA6RRjk0iic(Bj'dN61#XTCPE@%e-#+k9[*i6*9TLQ"%JSF"hml19ZQ+i(Db3,
$h+fIm[46HcN1eb,!FA)S*ZCcC)D5FecQeT+QRr6dNa4+Sb5R,LkcE@T,'I(lE3Z
r%TahXMN2PGEk#8mrXBr[)KSYbhH2HrVa[AchR#8iHlN29iY&cTAcP%"YKEf-G*!
!$[Sa[CEeBcD&[3mRN!"+bIRk85ARZhEZJ#kr3'EU0IS4*4HiGZk!5A#@A+J%PkC
X'hD3!'0NYPbNC,DVA`ITU"rfp-1lfa!h8@`EGX3JIR&3,[jp"i$M8aC,9dQA5f5
1NNXF&XblqL&22l3E#k46&NXh6,UA"ZA5bTDHkHLT[p`KFd9`&dSZNmZ9A1EUf9m
Qb"9bTAj32k$N#PI2rTK[VT*j5R#2b0DJ[a`[9mXe5Y`e)cZZkY@HAVeRM,V'e@-
!aY&VJh,YhkBcD(FXV'`C*YI*p8VFq5Ii"q[l2Ahr(PMA1eL$CDMF%*3E+X[XlNr
*b9)J0mTm*EJ"CCRVC"NV#q3Q*Hl@%raKICqRlp[,A*!!1PRQ#Q0b@5L,P#adQ8I
,'(f[Tqpec1@Aa'FZ1k0&r$jcqC-D9&)f*kBlIBqRlpR(A,K1&@@ZZceppelQXVI
m0+lkL9b1Gl(FV'5aDq-LN!$%,E*%hkA[9)+M8,D0Ld$KYmT5*EHkIL[#A(+Eh+l
N0PHF)LR@UcbpDNqrhHlkV4KMcE+J,2Y0$bT,(Da*FVSXPa9+h"%Sq#IV1capaaj
B8'"C@*2P0&NCP*@9EBaE6lD0TmZ&i+Y95Zj`E6aGCXUGFTH51ah)kA+1AZRTPA[
E'')TfmERJ+l[PRZ8i,+6c6a$,Y!V2,hLE`1)Dq1+!F4[BhFmbJi`HVQRPqpVi`S
GPelQk@9lfaLRkeME)hD#1ejbVdC,hZ[DH!k+ITrFVfr6D&XFQ,*Y2!ImY9V!cY"
KfAkE!ljq8"j5JRY3YMKcj&*pUkG[r9d'S-6GL**,jA*j1)J,1"@#2L821$6cj(T
j40BSJIM!STNR9qXPRPlb$c3i)'A4A!h5IM3SMeEf,GEeYQmAb6*C+imTFD)[q'q
6aq8**BmlH)YNXEl&dlIXl9[FIE*pZeL@bT2bP"+FNV+CEjDPqQC2hqaZJ)E,rDE
e2Akl+R(hT5`VkX@HAVb[9k(-L2EU)Nm[fYZVYpPHA@Vh)MM5*aT(%PRMN!#QD"`
1&BdEYDbIYjd-LEFm,FmSJAV0MT+VCE9HU'pL[G#QZ-QQH!E[Xr+FNQGpj3"52#M
VP,LE9,E&p3*2,pLlcAm1!0CVc$EV(FD(j#&pSlk"pBd@i`ff)20Kd1Z)I9jMX))
b,R,P5&qRVf@0ifZXm@F'SR'"$D)%(,e*J9Bf39mM'q3&H9&HNTGCAi-MVl+"i[A
9HTkq5PrTkD[rZL(RkARl6aekqUVpeb!pIH9rhi4+NKHS5SUqJK,ejISbH89HeA-
pZ2qc4NND8e1m[P4HLp-3%5I*De#HkcQHR[2R189pQ@f&9b"IZ84IV#rbp#9rC2,
daAZ1(A[kSRrFHdq49h'cCV#HV5r8Xr4-IB%qAjqRcm8G[ijk"KfYcm&Pp4jk1UA
VXr8d29@I49P9p'ahp$qJ,icm#N&!ciVFL3cSQAYrTL#J,pMlY`)"IIlH(a(`p(R
rU*qJ9K4!UCad+i##1BP4!%9c'TmiI6BmHYTHF@P!6ieSEJ+SX&2P909cU@"mqKf
CQk[456@SiAY&VEE-Ilpjfh&"LXpX"HX!hdSS(N*GKYSIF2KNIV02QchAl#DmccA
l[0NAAhj91#P-+@'U'UCU3DUH1BTUK+PQkc#Z#6@Ja((TG`bM!`V5laLFZ5!j18P
HY'4b*TfScp#Rbq[bKMl0Jh[rh8jpKQ94A!e,%@MJp"426rQ$'P,N$4$XUAUbRN4
RkBND9(RU(hH-@H0UPb!2'Q[LhP1r!9dH15*F9Cp'S4Tdi*V-0FP$+"&EFC,mc2H
VNGI5YXZ(VG0A$ND*Al)P,U-CZP5I)Qr+@lV%JrXrf$K*Bj-CVi[Pl6L0C@Q53#j
)ZXM64IqkcDTa(#Y&hN6&*qK#29k2d`8Dl$KKEdj2&qjKeI&rR0Rcp,KpGr-mAE$
R!TqRmrIF2Nb4Yc"9M09MG*l1e6PkY!lVNcdpGMmG"$6ffci0HcT[rpQpJ-k0h$d
0k*c)*G+!YVHIaKIRJ)V$D2bFBYcK,LV2UfMm&*mZ2AhbAe0199e#"Dh'39[rAR1
3!1MDp&@CmdHm2h,%m,8MKmrrS29KkAGQeUEZ#dGmq(iK5(4mIMf+El9J8E2aKe+
9p,Xc&im$4AShTEq815jj'09DA'$Giq%ZJ,[+6H-ETUmDN6R-V-Zd-H-YIEjXZ@8
8[DP2dLI+4YQN4hT`rrFFTh'[*9k2N!"hiM5%&dRbMQ@BiCiHrUrEIKThUP*N)aK
QQ"kUKqJ6p'#GlHPKHh0kqMq10hNDh"PEThVkK$p@9jiHr2YDa02CHbEf&0Q%[d(
i@!r#qEb[k9XpN!#qemIV,*fT-b!k6S)+Z$VN[BGbUKl!4h"RlX'pZ$IhjD&@6mQ
j2)D,H6V2K,*Y,Pr"er&#[TQAm&+qNlIVr[bclXFl@%23Q3JC!`5+dK,Ep51aDqi
V[D@IlS2ekNMG'fZq8l#K1dXI*aGM%h5Yh+"lB8Qc8UI,`r+SlKP!HD+6'a3lNFR
0hNc5@IXQYmcBj*B4QG`#fVpl9&`-'[-[(IQ$BEq)MYA6IIqK%[0dRphk*%rhrN2
qiZRMrNXdi1PHrl@JpA6kIqhr20hcMfe696e5(YRmhTEh2jJ`kF12F*`a-I1C6eZ
$EMpllr-[[N6-9l'B9CNhB4LeKjGKipBj9@[HJ2SZ#%2chS#DK+R'HjK0-CU'U6E
bJ[eMQHmF4Sh#G"$LkiDTATMUqr%0GX9A#90$%$U3!$A#FUmf8)8X8YL0ID6f4Gc
#-'l*)3jfdeLFMrjJS'X@*J3FiU0V%80hPiqZCITGQ@&U0BS1E@EI-,@'hHEhGd%
N1YAhhK6aY[@p#b2HY2q9qCr[SQDS5VX`(9CS5h*iY#4Kr1Z(RGmRB45*bmmF0`R
c#LVG2P,a)b1p03lGF&5NhcT%BT)@c`p6apE0dZrf8b1b8b6$dEXbG)jP3+FF%qQ
BBhGPk",0i'F"kUi4p0dL@4B"8rF)YKkl-[IFK6ipNU&AY'E!H9`%EqpG@I[XUSJ
p@'Bcp0Z9SAmX`k)`IP)$'@"Rl-U3!,QVCRkQaFQC@FRfa`J`F!9rIZFG(#'R,IE
(F`V+lHNZc'bqS#[b(a(Z[h6FX&ZQfV3*99bB$ah4p[#dYKf28UTEdC4)LYKI,C6
YrNNErjpXF[2'&"6KFU8pGP#59eTZrh1KX""h`hC0b!l!j!+)bI!(#lB3*B9Kqb-
-a5k01dU"%`@U`2h,3Q33aVmcP*@RKN+$lDqCf"VkIchLl`53!-cqdS+p*qPIG-A
b-`"5YKGGSemGrbDKqq`rkB4S84I)Bfq&iKUh8,%ic6M"E'mE0iRDaU9eAV$XPPl
0'lATE5251LqjdAT$U@El(@['KYV'K6VRP"59Gr[5l'M5Hm'b*KFdEp5hkjM%[X[
0MV%bL92LQUHDlc*1bTLBJH0kEB2$,QRE15-cZ`r36P[5U-@S8("-BNPF&lVekC0
EY!hH1MH8(8TmB3R9DGb9kN4mpH'V2rL5YM9#SqDIG1bdl-`@4@C("D+-e5Dl,ie
YCC'&5`V,fhBZbbNT,fQmT*9&0lBDiS*YFBc,AXPIdZV@liCQ)Q0j&!2LkYZX0Vl
A`(4l1!ZVa$ip-TVkRLYYR(98X6r6%6P2kdG!JNAaq11I8h'4CJE8m6JE),J[%)p
IjdP-C%UT3G2`mbeGZhDMd,CTde*Q8YI%mbJ82i0#%2#Qi+KN#M6e+I'*P*)B6k%
8r%e+L'PD9fM1TX92abpip!51h[(BFZ'b3blfeQZ"%hF'r6fRa4m(Z`S@p&-K3m@
[ec"q,bF12me6"ArMBhrXTa%@QPf-@629Q-hieB0YH,IMhB&A)mBJ9L2($Z6DAJA
aFFL$Da9VB%q$(aJXMKeiYe19MlG4h'2!L@-hEXrUEpRYKp-DZlpYPN!U[Z6G#C*
4*pc(V8Lf$Rr(8T%JQB,VGLAB4Z[@`aP0B-14,jBJ%Kj0i)Ilm5k"$Gqj+CE!$pr
N!0J%aL"mijSB!Vea"m+$`@L#RHXf)(a0,-'1GFRV%8j"r"q+6C!!6'[@)CaF`Z!
'fKE%K`03[Kpe4!)ElXFM(#PYq"SrhTEC*N$iHYb-m-2pUL!FIqcKKrXP3rLkD$M
Yh'E$em6#0qfS$0qiB9HiVH#ZF&["GhG8K&2bQJhENYI&`Yf2-Hb)K8H59)4(Zbl
fGH9T59fVKKURG%rm-(lHp$RGZMB108RT@HH#CLR03`fkdM5HPVbQdHBZfkCZ"qp
SBkDD,VV4MNEEZfcVXVR"'Tp)l*[X-"RdP28'Nhf3!0[@E,"pQ4`-qTaJYQh`b@,
RZcYpNYLC[0'@,YQf'AV8llrefj!!+aNYL04!YAk(6EecJqqQ(4Ym0dJS9Y0),Aq
)6(,fTjNLI`HLe2q3!$)I9UXJFX`8#C43I5BmJD'E+3l6KRhY9H3"Z$TI$U82cY(
+6XKbSP23VhplaAhlAe!I4bqT2Xjh*CIPP1'i1%fhFalXLqdm"[ZDl25Kq&FEZVQ
XI)V9A$cF)l0R1[c2GXrSD8HV,C%jl-[)(2DcQm)iS5#Rd"lDUiEGPI8hK'hpVI+
K$S"pj+!q`qhebZj$m(pAGR4e9!C2hb(A%IlH!lG1'm,hZIAC1X#A%Tp[I30Zjll
$lUXqdrS'hBHiG5iZBbjmq!F'JhYM'FJa"1ScJpY)'8r$YphKb%5qBGLJqVih%2G
#*'i6I,hT5Yqh&6PQ1er@jiMEl(`$Ym'ha2N'(3(I+jqXXElX9I"PZArcb,CBlh+
BXPq$Vrcr!3!!$3!-3fKKEQGP)&"KG'KcE#kj!*!3p2J!N"#%!*!$lF)!!#m,rj!
%39"36'&`E(3K!+qR+)f[TbcC!!"a+`#3"MXj!*!%*c`!N!JT"`i!Cj66$(m"d1p
bNU19I9jq$Z`kFj!!RF2mI+p*CPjR+r0l1r1+ITp0[0lH$`8fmr1DfF"VC"1cUCd
K`0l,lqaXB(2a(P"iekp"hhN,bmdk`MZb#IMN3$)!b81#JS@!H),A2,2c!)53!%+
)i[P#&1%[jaJKDQ3*,eCB@"BV'CYI9KV'KVLB9XG(ZSq,&Bh0MqE%bXD94JQjFf)
PCB2l$+Q282Mp%[rPZleklcBZFXbq@TdLk"!KU)LQUjRU0+eQ#MT)+-4,eHRU$+e
1&l)i[&mFE2'$,D*+PNM,+biG&b[*cq2)i$#Le4P#6N5HBLT4Xb*UPSL)e-&PXE+
#A!'-Y$V0P6@&MPHce4bYCVZbTM#!0E[m!49raiDRY"fA,$iFpmGrEij(LdA+[&&
mQYpNAX-"NlX2+Bk@6#k+PSdV+)f@jTB86#U,aLC0+Lc)"56&4FfMdiSR4bG1,Lf
,MLNS`DQJU,3-E4EYLKcjJm0m,G'0H`r+,md[LrGDLaDkEm(%D*qLXH0L%k-YSQe
EYFPUeD'GeN1f&9PBPPp5LVVc89PKIR45Q,T*,,GX-ZUE&LdZ`U'!JFQ2PNiV,FZ
I'%maTVJN@P3mY@QdH!b++!`6$-NYE$9N3R455I(ir0bbdTCk--$)$IXrcf&59Kb
043X,J#$5PZ6R&TINP8CcLi[+BJ9&"89M`bU+#r2#'U1aSVc`3P(qe2"#bfLdcaL
1FLe4B0LJ3I0S39PdDJ(U(jdIcFX[c#r,cd1DE+3YQ9T3QVrYHK`)p)QS&T+B%1R
#%jNi4j+0b[d04X1r5I`'Gh*8,1cF5FJE0b2f#Ijb`'(fqeCULQLPXMV0AhapVmE
e@[6Q'eQGEVL'Sp'@p[XlPSq0YP,46VQ6LXUkIQDh01JpIh'$@BhVpHdb*Uh[VAE
,@*SL-eAMP[EV!8F0Q$cJ-#&D4BDIfkV6J1`KI9$YM"[U04N9MBa*Qk3kLaZI1VT
*UmL0&d5(400HZ%(8U0p&e)M(DL0@HqLjVDT%4mdlkZ!C3l+E&0NYj480@'D(p"9
MQh&PX8Q&CDdkPHC1+TY8riCQA0hBbVJADG@*-CdNEQKfipH(Cb0M@D)'h+[0@IP
qVd%pHi8G-D02p`%0`mJPI)m$&EVQj23,Vb$-0fL'%#RJb@1M3Xc-&*,5"&'+5%N
KNCBQ4@B9-52D3(6TdP9%0mqBN6PEG%NlA846CSSSG4'C-LSb+90NTU5*c,38%Fd
Nd58UaB`ZG,+BNA++&'Np8%I[&*&fH*T)bFX8DJAUP-c,U*[V9cKA@#l%p$8Jhme
#fZq&XPY%"@Y%"ULiRV8c1PZlI,UeDd$0Qr(r([mYq"[FXEKVN!"M#h*pA`(h&I*
)j-0j"Z+SJH[BJ[rhSX+(Qi9k&(9+e-[eadN%AmE2Xm&Q*T!!mLpMHi)-i#5f*YL
mmVeY&@5)b-TY#6D,PFmKQ%M!ej%[Q5"q2C%J["lHG`RiH["1-N&ir4eA!#H`&YG
A,dp@B&C[`I9)**%J@,N+ejFR%faCQI%FVSY)i"*NL18VF9fiK*&9BR-%Ra#Z3Z#
)"(`p[)rV5-RAPiIh'@C1J1[2EBPI$e("pCAakb&NZ,ibF9d%QrRkmZ6eGlEXZ,j
keEEVM1#fkicJHe[+ViZ-jDXfCka-AZH@i#3r0h$jp86A*EmZFNCkPdV4qTRGdMD
Nc$hP[+jGkNFEC2DS-DY4CZ0SR5jLKTb4XEcHQXkEThm2hM(@6VHG6EdYpEl[[,R
cQMV,3b,KIiDVbD+R1"V*#)[F[(`9pf9'*"*bJYfm+L5,i,dJ*)NJBc9$Pm&YKKi
0qqqjcFL9J4C%DP6eh"C1(D`+`f,,UM!-%NTL'XI5Z[%b($AMikM@rj[+R2Nd@U"
b1D0MZ%J9UA[14X3lI)e3'$[i,d39X83XT5I8HH)NR!1F`fr-T&kadVbKA3G(@lG
XRFArG0a+i4P%SLU&S3,V"X6NK(L"Q*!!8R"c$j'UFD$ai58ImdB&2Y60%VSX0lj
VBB$$X&Zhp%0BL`T#pJecHL)03a*+U5JmM32[1d)!rBM`aCj#(p$qd%Ap#NDAa%U
QYEb2)5EN*!c$@Z-3TQ1-dL1BNj&ZdU6FAp*Tr$0%TXBK6!G!4D@)U)4Z51GdD06
"ij!!-j%[%rr+BNq03jK2!HSU%@5V+M)BMF%&%l(230C%`MhaVbUUD4c#K#PSLHS
48Cd6FS'r*Ub'I`faPmBK6)Jf%M8MSLBM8MVZ(rRf`Vq@U+ea#21PSRrU4%3G31@
&k18A*R29aVqZ$E5Skh*93(I9LiKkZ&L0`GLkM0Q'ZX9-4#L-X%DSVh%)HaUBB(j
Xi1031dY%bLCXE@P%Yh9d!pI4%B$9N!"%3a5bYfLNF3K43,Z+aK(410&$3bEmh+5
0m0p(00%iK!NefVPT4$40p0#[#C[JhdcXUh%)%kDM[CY(42-%#3bCX,fTpm@rK@L
TF3M6J4#`Ga#YZ1@f0[@%4,k@q'H*eKU(-&mQq+*04,4*N!$',rPDilqIf&rM%1D
V"2CS'a&Y'BlbPNkQfarr!qa2@KcJdP8'cZdLSKe[q)B9P)j,G192R+`qrZe&"ie
$f*@e4%[lSqMSim"G'CmT`NNN'3dR$#dkZUkX"GJ2*(%J#ZPNIp!#Dk*$`f[lLS0
5"AD)f"!F,$Vl1&E1%K8`G"6&*ZD(J3%)D&`1BDS,,,T%"2BkSR,(M[f,5r*lB8i
UaGL`ImX$1M*NUD)cU[P1G,AIqMKb0CK4A$8)Z'UkZQVf4V0hLiKZ[e@cRk['IXY
Gm!0h33ImZiXH'JFUG,11rFCq,HdhQ!$XejbL"rip45q0!aAJIL[dkb'LYmC"pBQ
Rr-TqDEr`l&HL4XYBrT5bBL``LbBA&VSapMc4$*qdAh,9Ac!,p8l-2$(4K`3Ad9F
FUR'JN[MmdNrdecJ!Nch#4G`!ZeQ,!BQ#dqcR)YYqjZ&BSb9QaZ,#iPJH&jNBe@)
J8bfb"I(D&E1$r96NH$LNH$b#DT&62V3-M)L"B)T)afk6#c!@$LdV+#ae02%CY`"
'B5hkKb[J%1P2I2Z*U*JPpTJF*N+Q3r%I*!CV(#LECbc-+%2%8)e$#'F'*T2$a$#
0!q$MH"@lbAjX2r,YTT!!DRKG(Si1H38PBG30%Md+5XKqc%"ma"J-+mGJSfmhLX`
XNCSlZB4cmKRCY"MUF[JLBMrdlBFlF"U-rq&LZ-C"(4jZ1Jm84pJ2a!JYMR$)0!G
lEK!MlASI4elYPr#XlbM3a8)#*$%5T4aTefPaT+$450`#P(#8'+9a#$Zf"3MqD2Z
q&NF,bJh[Ck(94fXF3S!`-pLe[Phl1iLMA@qf&+hX'XqZ3FrQPKeE*Zhlh!@MA!%
B)Zal[Rd[T%)-m0c9BB#jMZ`klTVe2$Yrm(X',8Di1QU*U(hAYqrqClJQ-4bBjpT
hY-KelG-*B1ECe3,&j,Rfb8(V[#h'f,Gm(2pXRc%SCDap8iZaVRd'SLA(L3+03ca
qQ"J[*QJF`RBD##STY'pS!BEQGZ,i4&'NF3K4(#J'fGGpqrV[l96NfJN-C9rcl'[
*GRU$ffQ#Z`bk%X848B`E&6U@6@MI-LXF&,3SF!@#[ZbV[ReeClZpbHhf&VIEkTh
YPZrUk#akf&GmqmVIFbrCGjL`HZ%r54bMF8M1*LrEPk4pQBRj*8ja$2iP!P4IiQD
6r6$kPBR*'SH`*6RPLf++IF((mFq@R)*#TYT9@N`YTpRRIIYm+#*K--0K+ic`Y%8
@Uc+b,h#26'EDjqmK#%#QD4c#i5C&2#L1)h%F#MYHR+"a#)HA&($cFq*%Zp,$-6i
Yj4ARPNp,QI(Kj83h['$4ECm9*hNiT%"H`cG2FK"KAf'ImHdcZb$#`T6%#IK2&c-
d$Z%d`LZ-Nm8T'JFU#Z1eaDPLTXC"YNDmTUKYRrEXdkJfTf[@IPT!CF-FT((c02Z
8&UFj("'h6pSRa1QHI4)ipZqI-qL3!*,m-Ea`Fb[6'B)aP8J"T%l(q2Ui1%2-mR"
%CB2bFcA#i4L0H8M-*M%E4FfaMfNaa`'4)5VE4chlD"`)XSpa)E03b!TaTRh%`a%
hJE3@CcS@`lC)R"84Cr%dec8h0lqde+dThFcl#*2'8`ci+H8Y[Ybhbm2q`8`q#I#
9KT%FMK#kNF6CiKb03pJkpE"219HFTh%)DEJH&M,RL`Xd$L'3!29%IIX`fBHjaJX
F*29&!rZ3!'FI!P4-FaUcF,,f"hhlB&Jl*[KilBM%Dcm(Y9pS(p$L3MGY0!DEA'6
[&aGVFC(MP`2%[H)5JJk$a+9LVXBK6(3!-PjQPiR,YEK-T"b"'he4c"AL5RZIZ%S
M3$h$1`2&eH)DM3-93M64&b2Z2(Z[&[-F+h"m[PLJF3LEm9$4hplMfAZ!ib63M"B
,()iBfqhG[VdlT(e-()aM''!BTEfA@q%D4b$p-4pGDqr5iPTA)XFALN8DKl#8!5,
(hZRE1hIZ5KDj,2fa#9MUfk@L@TDSL2(#,@E#N!"6QdPl&aGpTF0q#1MV1R'pA@,
[d!M3`F"k#)Dr'm50'SF3Q#%BV@qbYfYaN`1'icH,@c31BFP$-IcFjY[EGUjGER&
C-%,C@helkfjJEQGJER6%-!`cpq+)@!a+#d8M@Pc[f[SSd-kY*'l&TGX%3,R0FFp
4'#[Z%%Xd$J#Y)Z*6a&+l@)ZPEZR%m6Y6aCfJae[%AH*Z$mG%VplPF"k&bISHHl-
@pcLF1Ak[Z%rM%#*iY"KYEr,Y66Ya[XpP'BA"rNEIhVJEjjZCU1m'%MH)CH*q$mF
8$i52U@bC3b)IJqd$pRSY(R$X`r%(lA8D("FL`r'(a--DKj!!IFD)mAD4CaFPkhM
BBC'2BAZKEaIZC*rVQ2'[Cc$Z"aMALZ9fJBGMLTGG8M"@3f35JM%4Xq-MGVi@McJ
`1,l#cY0LK31$iim+c#@21M#+4)QpaV2A*1Yic)'3!paHlGZVGi)aMm'!E$,9,Z$
)BQlj*HA$`&@q[5V4H#jcI"BJF6ZSi(&lT4D21bUB"SCi3MbTF3Lh"G-`%$iPRYB
iK19-%mIC+halaFlC3SZRhEKb(%E-CdJmJr+HY4JARRATMa2(fmYmHpRrS'%[Cq#
H,!GZVQrRrM(&f#Yj5&l#H0r"NIXipe81a6-`PD`8cfNF3K62`0cf[-!!rVbV$E1
L[G5hPqj#FC9$F4DQ[aG)[!!8Al5AD2'L5cp,c,BAqrELhlZ4,04V@MaAMZ*&[Ve
SCk8qKUNrZ%k,bed0(F6"pN,IA[MhkTM%A1$dNRKCia#1d4GK*VV!RLpHmH`&m6'
DUhEVJ'eMp2R-Bkq!ami6V`SXFXj,6Vq[ZSRL%XalVdI%klp2[q)eC$jA['(2mA"
-$1"[Z0RKFSaSEkD+0j(LE2'@2F[$-6(p[q@kl!TaP6f6l*R-AfIai4bH@Pl'rff
a@Z-3JVP3,,&cl'caMQIRr!8Q0$5TiKh81dZm+plcF%b!qDi$mcV-5@XLBXhrJ2N
H-TmKePVX(Xj)JVR@JAN64UIh8mAl5('D@'GRHMJQ`&cRQKA$R6h9YkIZE2K81j-
42Td4AShrHSYYbAU(m&*aVchCcV$62AYb(1&"qEebrS%`0MPNTr2K&0k,hIml$fP
aX81NU@KQ6r,Y5AqX)Z`$c&I6bR8m'c,%"UUEPUKEb2GiGI5r!RcGKrA"IU"5Z)-
+#m18K(emA(D&aH#['@rVkrIUeS2Ap+Qh9qeHR*Fr,&C58J$T9TmH25%kD0I5VH$
rRbreLeXhqDNX+@8NiYVT2Ap18UerIPP*mG6mNJQPdDd9SbqJf%h&Q*dk"kKe+`H
YBhR#VD&YZ6[q$h)9X55i)6CQNZXlKCej"bb#*k0[VilNM)Y"CG`QHN4a8Ij[8+C
$'VF2H)Z,l4rMKG'1lmqQmXTPGIp[k`L[jH$ZVITNpqpj5&IZ'a,-ParB%lAiS(b
$HS)pAYS6H#BlRZRT4"Eji'B'P,4B64iR2K3Ea8ILBl%*FZG2a@GfQMh@6T@iL-h
NKm+c8qaN@fC,EBNpaNkbaEE)6[6YP2mXd(dlqHqYVfr,rKkI2&Zk@f$Lfj,G+el
I(V00$Z(E5IrFPNX,0TB@BlqdD,adY!+Pf%,aZF)K,9emcJ6Mial,h+TM)eT(e%Y
(Yb$*"!'Pm!44)4hLb3UmVfX+139,CGU+GZPS*k3B,lj31-Kdm38,PEp-&9pL5LQ
!m1FV(mIIpPkTiLZN'#HkfE%qMVpYCP,Y@%CUNkL3!'R(L0ifhqD*Vm8h0YG$q%m
j$NL,N!!,EIdei"lYfp'r,qmca6IJKCJBD)qfSqa4pNJldSk`4pMKpR"4l1'Ldp4
ipZMG@KcIMYV4I8IpVAcalC(rl%r2MN5j%iTc#cdl!T(FiY(M2AX%#SI--cqhU#b
r[2$-%'E2$SmV(RcJp5pkU'4caHKQDpDf'Kr"K[6Pl%FVLiV0aZmV8RUq1M5lZQJ
!8BS3)cliX$!LdLD-Ub9%XmFrDMb[dB4pK6FLHlMGM"alF`lj5ij0MFUcI*D4$P*
&R`i6NqeKGUMi9RaRKrJ)r`ZBG(XBFmGJmEh#!Gca2DUdJh`lD0IHIbL$rbe'f)%
fafEE!EDrlHIEJ6[cq6CRjpMTfqaG1j%"[`qd[ZfrDeILfhkrVj3baAFBUcEB3fe
IfmIfYSH)Xf`[fp2fX0eY0p[9GS%Lrf#af"jN1pN$aHZfSeKM1hMfd,JF`V0pGmX
S20XR[L$`E1ri(X"$L@lGS'`[4'c2hIS&crD)lqipfch*2Gf5h02e,qlT%Yr"qVE
clr6Z!pRI10fc"m9hRClY&&md+U#IkJ(qIbe@20YKpe+LNKdL(Pj6@GcIE1fmN!$
QXTZYDlDqqB3T'cli%)be[RR21l,(6rQSFFmP),0,jSriH"1),-*%TUU,N8aZY29
1bV@I0Pri@I1d1U,Y`XqEaf$F8%IXmfNBUR3YrMKAaVNbcRZQpl`VHm'L#9-Dp9`
bA+Ka`dA&"GH'85E&Zl1EEBL*+Z[@Mjp5Q!iJUSEaDZ[@,dL%J99ecR6X82!R0(`
CYVhi!62VMa)"l%9q+&G3rd6L*pcF)L$9hH)N36bf'f%e$NP*8$Y3k!'qE4G1VC-
RjFA+mZ1+FU'(KZ%F&bD`2NPTffS*ENpX#rIhlIiK-iiVRTM2M1dLc0GNfr*BG3$
M!Tfh`f@F**+%3T4-d9)P9)j+lL&6YG`MZGDaqbN,TDZ@UH@eY[&YQj!!8d[bbbD
A&%f*BI[[3SI&#NP#,biVb$3Y+cJ98SV)Pa@PTf9&S3D'bXNmkFZ)e&VkJYM-`aG
lbh5CS6&+K2"Sd9"QNS3q@eD5PE@XP0$h9,HYjCifbl1Yrp3T5HLdHF1MaCkfPDc
Lf9B*RC+XiKEX%2,)UVDPPP@GE)EMe@4e,@(&`LK$0'aEq,E&cSl5XRT5,'bEHlC
j8X%'1aHbf*f3!)4+ApD3!(YT@F1"9d28XI[DCVDTCrH0-f,rf)6mRL8PrH(1X(9
0"liQfj4,J"TFeV40Y+cT5UJV'YTpE'2Eb,2la%[SAPMkcdeIBbkK%4pJ'k0PA!l
2%Xbp+pLpdC!!FY4j@ND%'K6[k)DbPQhJfBEF9CKqmdY+SZ@6Ja[1YB3Q2F%!pAe
E2jb&N@PLkGM`h,pd,0N'A#m-",L,Qk22Dj1%6Ph@NA8eb$K%XERSCk1bRSak0KS
Icr-+LmI'5LFi#X,RkUhRY[$0aB'b[QbJ*G64,Yj"0T4lD`RTZBZhNieNBbfK,(I
aYR)ILDlC*a(I6cD9U+GT)YjDlLZED`QPZ)ZhNLdNZ#!Z''mZ@XK@%GQ+"HP$i--
`1Y6J`VJ"$M'XLT%Yb`@MpAaEEaG(0(IeY"*C-LXLXeMehb"D%S-2N!!cH%$2B-N
(!6iA"A%l&p9DY,&e29XAK!*'M@VCa0f$iYc@m5f-!(jY1LdEZaaY)C@YlGRDbGb
3!16c[ADL[DhP@Fa(mA[!NI8k(84(fGV@e*!!N!#%3('m685fJ9bllZ"aaC1"HKr
i@16R6TK8A&"8&Q)@0N0RKNcDQYM[`4T(fEhNIR*rcqk&!NHA&B&P-6$`KVi6A%I
DNQ`,!MK!YY-b,S([*!k5l51b25"3`r1GX&Qf`lq$VD&P"jIN)('`l"L4(GNbBN"
aQ-2#"bP9lSq#UmX$E6A29NI"H@-+bl3md#AY,RV*6K(CD@YPUEBDPeFAri0X95d
aa,))Ucqik@$Cf9D4AE3m1(6A`Th$C9IC6FZZ6RA6A`b4hHfH@N+(lY4K3f32f92
,(NjeNb1'f-UHVFb`MbX!#K#MZl`jXTHYT'8[P`GaQqRC61krdN)-#C@iHl"!eV*
E3ZXk6"i5NBGXa8e,G"N6iJKaP1`YqfJ*J6VR'J&&EiDbF&[4XNmj)kIl0[eI-jQ
Y`ZQkZ)UJ%CCpjD%D24T@""@deFTUDcAN#XQ+)Vk0l+kS+PINPIYJE##*9TApV+p
P2i%IDk6'bIjDaTAUBk![pRcVlDl*j`9aJ#S'b'`Y"j3[L#[D0'NVFYYJf8N5)RU
C)`GUQH2Qk44433k5Jl8F9$j29l#TGJrI9[L2R"eU0l+3!!TS#6@k8mfQbb&bU*C
aXA`+VKiQKq(JKXF8iF[$,DEQ`efrFhbi99T#MXdm`I%Mj!JYMh$G84'l4I)XG,B
B%SY+Y"b4b&Y4MV3BV5&GGh99P%GD&(YN3TCEd9KjP$'HX4L8mQ-PT@2'j*@8$fC
4%80Fbk1iZF)Z*!-$2-Rk"'P4SE5+$bN-EVP@h`5q#AC0,G$VadGr15T$MT,[rUm
%LSlqAEX2hUlSB&QVU0#RG0c%@,kVpHI[YY)9cd(4`EQ161e98*5ARa`@rmp(9bf
Zpf@AAJ0k$')NiSS1X2,f6`pfaMqpX"MMDL8D$08$UGTaS$TZcp!a$X[rEU$2q,0
&rSmq)e4Nb)(i(beM@X)C)8kiCS[j54UiA8R$aL3bK[pSQD[PD%HiDD#i2*Q[CGa
QJ&2q+-HB(hcMV%V#16&K`HLLF40'NV!DN!"McIGDMLfRT1pmJj8V0XjEP4Ma@+L
q0pm$"J0l%#fKfdqXX-D4K$f",*!!il@%,F!N9ibF3-K!jP[cM@qq$H'!2@&*@@+
GjU+*ECU"U`K*Z"V)3MP45c5!BjD+XNJ@DeQ8m2ZS)#HCVc9U$"G'($p'JRZ2566
!(ZBVmkAj`MGIrA[L-'`kBYKd4%)I&,F&-TXpXcQa4M)`1G(SM@4lI1kEcrrBlU%
#NU85mbF'4mE13ql*FJS1VJ"2q1Bcr2lZ"#fRP"ImU@mq$3[QYARaj++b-0+G)b6
,82"8HDb@8eh"kD+1R#D2dh+D'i$545ej[$a"5rJ,Y-15-N28-Tr)%q9*R[NN[UA
@mN4Al*kLUYRN'qFkmLFi*lP'V#CUbZRQBbhK(F"$&-GRQ)mdMa"F1mG2PUGSHE)
E[QZ)QQDMCcEbaMbr#-Z5Z0+qQUKK2[60KlY*4aUBR%J$Za-Y6h"Ci6eN2[$0"lZ
cDRPFH4YYm-d'860,q2%G5TJ-`4`1KX3QMd8cR5TRDRQU%m[A&6&jQPN[6pIb0-G
d,F9)H3E*-j!!D*DFVH8Xeh8Y4AXj4jkTj4a(35h&!@DG2-ZmljYeredLRi9bcMC
VYB56!+r"S!Z5jmKcY6c(`BHeP9RMQc@l"X9cNlBRjMhI[*F3@EK1#%11mFQXCEj
MUa3*9i4%DlcVQhF61Gd+)!`0#N-NBEdJcc2[D!P4+5pX1U!*cTFAb![P49UHlaB
f(83RHE'm4-Z,(4I`!ZY5XeV,5a-+f)lQEGqm[DY-D9Bc+TFi&ZiS$M4[+326%#h
KPF#YeeRdP(0*3L%V,j1ADhQCDlh1STZm3PkTj48*$j%ZjNhI[,Q6-E@mXKch0hc
caVpR%RNj#Vl+[+lP9@k6dKdiA+hPeBNe9`rcQM+[F9ZpcY2,KIKI)qGT#9m$ESc
HiP!jAbl3%PB*A(G[dFHmkTYAGc@#PM"2i0,kL,lQ&@9HXCBNI"INYHCP,Dpec6!
!qkq&*"ILfL*jRCD,A$--%!2PpI)',H%@`#8-%0RQ*@9HBY(!$H@i[qLE&rq$1q`
3j)hQ"5eK5F#i$d,*0fPj8p)[aUa5CKA!-E!j)326&5d[FM!-!d(F,'r4mQCS3X,
i%A+a[&A,a3k$BH*`mla[R([+EcekUbX5GN6Q1@8Ja0BblU2!m+hdcFSr"L)$DaM
IV0r&J&Sk'f#fhM$2qZEC[dF#f*[)fq6Y@XD0&NC$3('(A+,P(3kLd5,A2+2--`a
4Z9lI21fETrr6B9$ZbkAQ+5eKdT!!f0(GUH@GVM,Xk-b6bN",6`Dq*#6K2bc[NRG
V'4SfZ0h!%qCaD@#K)XhMR1*Zr1q4pfS*$`IH$84%KVa2,Y2b[[,G`'2bI[1SEai
6$E*%aM'6mdZQ`8LaH"+l0jE',r3U,XPf&dMHMj)H-#ZdI+!Fh8GmmmKZEfFb+jJ
4(Q9'@"EI%0"$mN'5-(#3!!r*Kl9mU"c#jHCKDH#2+JfF88JqM2pbqBKQCA'KXj!
!03r*&G)m"$MP#VLSl"AY@MSK'KYG2"N1[Z0L@)BAZeeiD%T%%NB0mP(jQ*D2*[c
!Y(P32LkIm-b$IiNFB+$!ZhKHYceT(Y!5VCGB[cd9N8p"XYP`'0FEEq$5D&jak,i
m0FBEq6J)EL&[S-K1P8m)CHkA6mYR2(0rFL(r0&I*ESS9j,-'V3PI"9l3Fh`P5GJ
Gb1INmeU#p1)@C(*94+i+ADMCFM#qShmHraINLeUqN!$d5j3[4H4,'2!V1Y1qJX3
krdAmAcEhDIPbFN-XAiR)9`"#5VGL$*+FaF"m3CTPM0Sc31eHqDUjac2h*VIkF4H
"01aLAS[)elEP6MAhF*Q2iIqkI%2,ea1EL$hPQr)Y,Gpd%b&8XI*Y!rTk1l'CU#4
A5db9Ua1'2TA-ACkj+lR#ImIGicRr6XrFQ9MCQlZC9f!mN!"JSk@q@4Ub1*0"@A(
BK5iiT$JdE52j"V"j9lkRjEZ1GkU)+QD*Z8-D0Tm`E$iKhm0rMF3-[XEa$UHiAEi
[$I6L%INqjS9D@hQ(p4HaNPcJ"#+BA*,[1QdYrZ[NHLhA1HDT)ZUEfq3'qB&RE[Z
,H6BijS(ETIc3B%lkd(8EacG'j%EX%jU%c)0"JXd1S%(rMAVB%6912lGb)hq!4Pi
X2j)IHfCaNRkJ4QEkUBDpd#D$%@f6Saq1Id,b%b$iUIa-bdmG!Y9%GIPj4(l1cPr
K*M3(!Jb'qM2m0mX[Y)5$-LHU,QV),b2b5jC0(0!H+cp1mJAqAjQEYIc+*B(pT[`
k)VrH`6c`Jj(Q&JEXB`"fNrc'h1LCQj,-mih,A4Z,V@mMmYXGc(-MPlNHrqmNPTM
I1HCT)2D42mJIYB3+N!#CTi&S*(mbQ)UKr@2QiIJ@'@Lja6&-3p()A1qCkj2-%lK
l$84$FjeRVNXbc`h-2$q@-mmLhb`5D9NLKDQ!NIJHIb1Kh6#1CjU)*QDKZ9DDKBc
aYCc#`ZdD4mh3-mp`LJA3raRi[N4`G3I2B'#%mA`8$4rhUHHd8"d5+8V4"0ERK8`
6''6Y3DPQ2PA3"'GBf1$M6JG+SiUDlE9j$p&%Y##2I%h3L6"q6846-mmhmlELTmP
h[3CY1N8La2kKflTH8d9A5jCS5jV508&GPYJlAH1EDlEA![dJep*Dl%mC%FVBeVH
D8Ke`RF6*P%Q9c098@F291bbZNqK+He)96AZkiL"4-PIjjUUr+&j6PB4@U3Y9M4$
dBMr23CSUZ9'dKiK405,B`9*eUU'TZZ2U(Q+%ZC,fSTUHZI*2VLBS!CQVHiK$U*D
j3P1YmRKYFlQQfJi)MYH*8"diEQAeq)fXhCX#Z,AG``1L5EML(!iV(@QZ!-X40)I
Q-UT,p6`$dbj(j!3C&40jEc'BSQDZTUJMFSlA*i*!MaT33df`L'8iX)DL[51dpil
A$"""Z%H0U,'Q4Ll2S@)!l41KIGbm@8ijMI&[BLl9""'Ffb`0T+B4DVU$bLpPb1B
bC28!f5A8c&cXQ8X59%jaeeK)V'MI#%(e[Sh+,qBbDq$Ih&bNUEQMmT&SeKE88P-
,4q8Ma5KUC5l8e-T41FHcU,8Q1-BbC4mT4TN,2(0"JXS*HMUq0e)FDFlhc2P*+Vq
3!"NKVKjN+Mr20qIYI"%#QBXBfkXj)pb*Q82b`&YYL0S!VIeSIdhl13l*%mHEFkN
Y(H#CFrrL%-M`Q$2ba&KUCml4"-9G)YlHR+fT[@X8MRH)8!FX06[mIa`5EB`V[#k
)NmRCI)!V6bSGJ-imLcV5JCij+dNQ@*d`QB`6TG6*R+N*AV9-*K`rL%$,4!G6Cde
a4pTaBJ*eLF#1rfFb3Dh8PETTLR[06K"&e$e#hAmKNflipc"c0%'pahQ+a$(8-`,
RZHeN-SFKBdXK1K#3!-fQAQD@CfBRb35+2XjG*UE5)4'-20[*C"DA#EpIkQh1d06
ENFN*k0Sqe&F6HTA*j!3aR3ieTfZ#45Z6#FIl8Ap0d-`aDC`STT[62--'3Bj-S*l
MHbH)%me-cma-NJQmJ$4"`CFJNe0pipb$IL16-aKE1(eTJLDEBCQ*k@d!C@XDi"#
G+FkJR!MPl1JZcHDaL3*2mFdTIa5)Ya33$D4"QL!QiL&dMTKM6MBcT$QC'iUGK`K
@Y$5BKQL#c)k(8%iaRBC+!dZL#!hpHFR@#jX(8-b!iU)@#,N@KKk2$U0KQJjcNp`
Fm5%G6X205A5%*SMaq$d)Fm6$0)*'DZb!ir(Vk8Jk5K1%@m`fFm5j0-UFU'Q8dj0
`r'KcJLD)RhJ5j(L-4QZ+fm,1%@HDihecr2Ba-fi(HkBiKh)Md!0YT3&Tf-I'`-*
'8qJmkm&hm9V+-mGT!K0ab4c20p-dBB2$8c2(ap"B64"'-33AL%YT("9S'ZFJZ%"
FD)lecE&r$k-33$%S&m+"FA`%pY(EPhHDi1[+aF&BLbC3S5EBV(*aPiXVc&6I62f
l1$3X&hH&Z*SQ4QML$X5Rm3&Q2*VL5XDEa2e8C+CS-&b)--H,DC)Q#(NCK*[%EA3
-P@JkaS&`NlMC62E0j$qHa`(+#XZr'6D%T4'#SQ`EYfZ#+)[,@L,ZS6+DV1%T%*B
&#ha6jTZbA@9")-9P,49hdj3)6GQ"kK5ZE,LE[9D)pfJU%I41G#bKFipeXpF+mDB
TTH2SH-q`#p#rCLmiV[+XY8)m6LFBi!ij%4I1m4-MG1+ZHCeCF!TH+X"VFCDJm`T
`qiL&1P-*-LYc$*e%dcec6(+k#[95(JcjAU3C"Udh`deA($qCm(!*SP2S9%f3!%-
a%Nq)TfPQK'Eb+Lh*YkILIaTK9S%3LC-m,9E5'4%kJeFdfiRjG2aRQ@*0XebLP@)
9cBl3l"fc&IXB'@Md8QNk!#ZL1@DLCiU5Xa8m9MRh5q*91M0#CqkBVA#6#2)b1XZ
!Zk"GiJCl#eej0Q'8KB5*CkZha$YdVTQJ#@DS2&Yar$`kAa-F6RQ'HPZmBmClCRa
bYS**+Ypl5laY#Ma6N!#FVG$bQZ)k+"jpa[PQR%L(9e"Hm4KJML1J*`-C*TQ610F
4$T!!pc'3!&a!f"6%V9EIKbVkSJKGp(2$D,U`[,Da[KRlMpTS',#qQ#l4a0SQ*0d
S0TSa*PmD+(fPBCmNJXdUA8VB`PaDRL,2j%S$!b9TS&)NJR#*,L-XL#jcK,94&TV
4G!9GkCR4Ia%@2&PC&,C4MU#Vk'T0F%KdmH&d$Fh6"+'4L`qPqE4!dra%I#"G5`X
e`9$9aI[6)VT1%l4#,Yk(VUFE0&fIL2HN'qNQ66FQiPhTCVT&%d3m,Ri3,DCE05e
1a$[3EA5l*LKMA,`Yh8&,0-'#e-9Ede+k8p254,`&h89hDi*maF@EdMedVbCS99a
m(lU2PQQ##lq,0k6lk3&08+#iH$ekN!!HdJ34LB[ASSGTZ5BS4Pam,hU%9QL#rX2
&Up+Mp*LQ4a2a5[3i2D%*-JmAer3N2B9$)Zl6dr5-*JJdA,`#28XV06fEL#YkMTl
Ap&`m,LbYSKFdV8V%Ik)Ak590d&Ziq(Id-VfL#6D),[i9[8U[DASe%IqFAUFh0,h
Z#'UMf%4[4ZK0Q)jA(C3IbjY@2RT-,Z@A56LkJLNMdp8QmCQ*HBEYY8)M#AV0c4L
ILbrT,A1dTVK!!R%cbM1MiRQN1CU,H-@9r*AiPYk1d0[mAS)S[S5`aEPl%f4M6-R
IL4r08Cij#L@8a8DM9%K1q0j2`TJM2A0NmKkX1IQHK@"TT'IBLX[G@aRHJlY0UKR
K'6EQF[FJQZ*l&D4RMX![HFmCPE)[M4RZQq&rMm1`13A`N!"ICG*UFlJQb%Ni1q*
QQ'H'*B'(S&-6c&J"2*aXUY!l%AU((d(!`%2`9+kYL+1r`U&69GB`KhN'Diii1XY
GIA[*QQDSEiCZAdD%XLC2eT*ek9f$p3VX+MNAiQD`C`BRX4M#b5#SBLcUb3EdAS6
H5f$4Vk"S!VIl4$J1&XDaJ)U+X@JS'jY"RKQ8a-*Cml,&LKRS'fIKpGY`$9dBip*
80UFe*NI6'TFAFC2YQH`N,MPFV01I`BFPLpC'D#d%1'PKMm6+iQK!jmCSY*ElQ`'
H'C!!410fGkqYE'rkHkCrmKl8I(b[JqaNqRQQAr)H*(emlb$Ca4cU'AEXF[FJ-H4
lA@82dpFcIC2hS'$NHcePEp2(-qcFjHjGjqleNIe-Emq`MjHl"qGS[YGIjTK$2-1
ZAZiHp*9mEk!FBRTjKMfqh,ejlYj3HEMTkCQHbAYXJShZ'5k2S2G0$dh[Zqj"h(6
h6IGI*dCTi)k3!%TABV,Z4ZYS[@IB%-bY!YDj@NE+20TJZQVD%+i#`[J(42"KT!p
TSbBR!-+e8I44K$lL*8[h@&%Zh!E#)4qqJr5akD,TBjGRP"a0Qb+dL4eDX[R"#4L
'mH3CDESb%$!R0ChT%h1`CcSR4ra2A1Cm#2FrMG#RjCP6cF&F)Q5[p"PpVZQcF-%
R*mU6D$0pB3ibR64Y$TFmZ&0'Ap*AQVi-Khl%*p(AjN"0AiG$IaMrKVl9"!d2GeB
4G2XG2G-a1I4rkqj0P%@QJfFk*)Iq!jPQR'K)6T+Pp&f%[Y[4!jTJNJM4*-6[ap(
hQQ"lahdd98iclFR!pi[-3G`!H,m1dHIird!rDQ*"%-3hdb&EEfF1N!#Q(DH!'4I
4MrMr4&Xd352%"K26jDN8N!$4"#d3&cCGRQcDNS&lPbC6[M(BhcIlKeV6LG-53NL
%%MT)JXFB`IG$%e3r@0[*QA+Qf8p*DIE$RP9*'-EALr),95C2#YG*mGGf410Uc*B
Y@iC$(f3qq*05@X'*K*Ya*Vc#8Y3HTSeTV4Af[9MXSED,9DUUS"AH%m,019219QQ
USPCTMUjQ3XUHj4Yi(rdj6LRh'K4jQTbP[)MbrU'M89KEFheRbI19Vb*D366%pCd
&#AXVhl6kZclhI"4jYMa2kBM5ff9"#PjRf2I)Z6*3kD4J2+Sb9+C@'3leZI)q98P
90Le0#kdU1G6RbK[9RUU+9[!CBe6QbUY89990+c`,K9'C+bmccAh6I0ZBTZ!XaKK
F*Up8e50`VrYCjU6J6-Dec*1,9!fePeCi-3VA-Nr10r[kCYrYYHcPDTN[&kUD%99
c"ji`(Q-bZ8AHT@UTfPT"+i64(r'PUSkUUe8G9pJYFV&TjTYQZjK%+kKpQ&%Abb@
URSTU9FpP[P8Z-8epdc6dSLSX')eANS6RR*cZ'Uq2#A0!H@fDq+E*AkqaJQST`@R
lq'DIIh'DiGG%Q4E-5""XUIUUJ9EeAAmZNfqVKQT[dpJddJV#)Zl2CI*Ce8JeeJU
1B0a6bq6$DKr94#Xm1BA"@3BemYkqfAYl6cQ0NEaI2U5D4P66VCT#V5"%iMT@b#G
9-i9AAcQc,X3I03epdh"l(IZk1Kk96kMQ%G9m4frZlAVcHIQkDU&DDJ@&%IIQmr*
9KGFkDGA+&IDmA'8Dq+E"lYl-FVfj5VkL@UXf@N&ca*PIN!#[Q2UqU5mmejX-)HT
Zifk[NLqBU'pJZlDl+lF+P1VjTYlZVS60R$4X-kIJ++Ef-b#Ar9aAVJDClUrDQMS
'"!4*$(IPD[QT1N#edqS!edfVj9V9ARA3#X)M"JHkA&2,0l9f[C(,1B2*Gq3De6'
L1[iX!P$3-h&Ckq9(kN$955YiJR&Ckq8'8p-h-&rE@4CN4ec@"VP4(444"qeS@)L
QZ'%hbar8`DUc9V!+iiEG,,p6A94AVEUi)U&+0A[jCUrG$3Y6-@lB,q5hUTX#8F,
kLc0r+Eme0Aa6)i5RG&bF6K("!"35DRHAj`[jTDRZ'dKHGlGZjr,@VHDEDVYEY`k
hEQfH@1[b!5mDN`C6-HBpr(ZSRPVKL5fB(JQIUDTk531rViMU&DTdYNk2S4JK'KI
ZZlN4,QMU%09E+b`r`!8Si$l94r8e9FbHQTI3i!,Ff9-GU[TTKHNI6BYi"G9I$G$
+HB8KVNaPhe6qHkjciL@-UDNU1k+bIjDm+,c9KB[c+%2PU)&DiB8YA"`8UDB5IRm
A0p!9je1k'K5"8q*fAS$`#X3+6HGGDM!T+*V8%$98Ub%1mQV86KfQKTP-Nk%9A--
BmQUdMcTF$GF`H3P4U8Dee"&UK&C`#@08UP&eNqiE,,kf$K0i%JTM8*eUUT%40A,
l8!+h-DkM,M984kUMY$V5e3(&TY'qdG[V1-V98BmDU&%40@S(PT!!'S$MU"RYTij
@-DfJK!,()GjDM9Dj@N(Ya)8eShe0a$I1%qjr1!kL-A!Fl8YC+NrPDjAR-MHR,12
laKI4,$al+&5APA+E-T6aH0LfL'[PRQ@#'TSEccIHAh`AefJaheAd6FAGI)GRP8N
$cca53r%ISmCU"E89pM,8(ZV(0&0"'MM,531EE&+3!%UTF5C9Uh'ZRGZMb`[8H,1
(5G'U`,9cHqUM*UK#VG#0h)EYk5!e849TjGkrJRJ(ShbMYVHKHrF+GD"1UMLL`UH
YE0m"!!qZT3[e9*28-9T0FV9dSDi'R)AR-ffY"G)TVU8Vp9!P%9@bSkAKk-hde)r
Z8+@N3)HU6%h@UXcKfBmQULPUUS&LA129D#'HrHK)GDbDTKAmL"L$IM43(DH1emU
j'5(H2l"qB(H08FFl22T6MMSKSNliC6U$GSI,'N,$eBRU*+fFr42L3`2M"fCA@AK
B#TFeP!jAdb0UqJkBRIm8(8d&DSBk@H19C5&c(8eMe5RU9(kGA9MNd43,!Mm)GM-
AT%l-A$%DNhM(ACKj0)eallB,Q5Z%*'3ZRY(LmC!!ZF**$5STcJReB2#6(rcd&h2
"R5V1A-'2I[$MEZCL'cqBqU'&mDLAa+2b`MBZSR29,$8lq#(iAZ2*H-Q(k-e4CfU
&e`BN(U*hPMTEUl2+(k,hR4pmYk[IcLjrL0ij%AA1,`r41l2m)AVRU[1dFLC3L%m
0[[@$EhH9"38@Pc@9MP2R4p6j1pSBANrFaUI3QHS#GD&@&lJf2S9QUi[8a9VKG5P
F*24U`6Gqm-hZ0SCBLY[i9*UP,P'ADJ9R*mimNfB&Ar["elm-)+k0b`H3!,#0RAN
8DTJCI18(H$l5lMBZeh%&ArV"PrpUi`$@G6*J%cXmpBr8h1!,VHDk0Mi2*(fCZMc
B((bZ&3bQZ)h2SrRU#R@P9Y"KFEqG4aHVUp69@X%2LX'"ULhic!mqqe8'S*AcL+,
ck5*e684GXeA3Tp@9VTUjG*@DTqCV"I%"9c1A,JXqpB02reN0$+5iQX[S5V8JSKE
Xk&ZXklP[&p*LGDeDU*86I5&qXeUNVY2+[Bm&m8A"*hl`bHkqKHm6pqdLZNPGVfl
3#PC5R2NkZLRBj!HER%emV#aXfM!5YUY@cPm+HDm,2[D$MrrUeILEAVKA2r+$MhE
h+YlA*)2289F!NcibF2q6"Yk2C0JUe-"+94UiYj+#a&[GU'l5#ZSe(L@AdE*JBr#
K$$Cb!4pb#VcI4GfXEY%+$hH"FJ!T(P#,YA+H9)MH(hcJ"arm#`Ye#`Ui0GLJ&9l
I`M8q5!m'ki0e-X"6NQ6!MdS+0Z!Jld@Hfi,hYB)b,Zjb&+`0eXJ!jQXb`(2`+)!
$@kEi8D3'lkREe4eUL9UUlT3"(ZU@U@iA+F'l`6["kZ"Y2h![6rV62Fi2h[Rh@`Q
#eArl32V"frqA'e5kZJ22%`MH%MCi-hK$hDAZ$Plh%Iih4ZN"2)"5JYI825Ti$Bm
882G!FakmkJH[rQ'N'1$j5CRU,U'#9i+AJjImi*@GQIcJj9dQYRl`dMmpQM29hA#
Vf4#m',`3V!UH$ji,9JE2"Xr)9M)VH&Uf#Ck5l@A(i%RC+AJLH$ai,(K8(P)KH0%
CGA["#iPh"35ViJk4A[$mRbm-#2JC4hmiM(["bYhQiAl`l$raSq!Cq%J'r!)M&Qe
j`90aFC%A2"PApkMJ#85#ahI,5VhJXEMDaJ[i$8@XakN8[#i+*X$Q(km!1+U+U,Z
fU0RlmpBejXF!T)3fqhZ%Tp6LBD,ciIc'YBrQ0IUidE10&Z$rE+02'RhkfHH&8f$
e$hYr12Y(a*lCSd59Q+J+MrpUH!T&f[LHG``AHa6d['0Sp[b-M(5eK-PNK4`F2")
X9rHUqi+(r@$&[adl!cc8L!,iK@8UU0q#KrcJSCh8N!#Ti(SQ4`82"Jpi!6YrrH(
Dk`82a2f!+`82L`bJlcF&c[,pjMe[ajX#e&,'kAkC(b`,lP2,e2h"[Aj`rpq8QKl
J-6XT`6hU!4@!lG)9e(iLZ0X2l[l6@M@!#eHQ@SDji+lJcQ"TX#5i)lMG$qlDRG-
2lYa&M8YhZZ6j`C+rE1rmi)jG"RTqF2XZkm*-GEp)#fi,EJd@"lF%0`Fh"6F'0rM
"EArhY"IFQRL%4E$iEpFm,q#(#i@2D`KZMKZ*HJ'l4B92E`KZh2hJ"Mqii6qM5UA
JAP(!,lX3DaZ$#9IJY3[c4U`E1H+)&512Q,HqHCZH5r(kK@lAMYL`$LpG5!eIZY"
XrN*q`N8&['*KdAM`R,qJjd[Cic1'LfU,#MJm!H%#K#XXQ&$A[@PKC6EIQF!FH#G
cbr9b@A"GX%JpU"i+&[V"pIrh-"CJ8Nm*VP82U`#ZN!$T#UmH%X%#2eM`Tc9IX)J
CjN%`c2aJAR"0F(9`9A#P(mcIRG-2j[feR[H$EFC2IR$ecXf6(ecekeE$$klF0A"
RUSIJh[j8F!@d-Lr*9i,,j@["CF(Fi0,J%VP4IJkjaYIb@i+e9(!a9D8kY$IY3df
aV1k!*@ehkNQ(8!lPdRLD5+9BLTf)cG-C0*[1T)[ScH!LHMZiN!$HSIGS,Ae%QqK
6qNjjd0G99c@$#e46e6`iAh98"`ARU@`e5)e8Si*c9E%U85HSkF%jkKaeIR#fZNB
Y#-lbJLZ5ipIPbI',ACU#ZAq0AjFQabrf4q,ab`XZjNKa-@MXSZ4dGf&FKZS(&ra
6j18(f0pYP4IjJA-aqSGka3r1rHr1h`r1qHpqe3r1rZrkcJr1fVNXUK3XT)IAV(e
rhIU*mGGPC$rp-Em[Bp2D6clp$(Fq6pjCNVd!%bAl*Z--Ph*4ZA%GdAFqASd"DQf
!Kf'XaB#*q6)QUL0[604)CPikA05,LEe`[fC-e)U*fZ(p1Y[Z9iL*ZL"d9&B2ZlR
UU#V+PH*F2kb8rlL(GfSdi(Xi0dcH#k[I'p8eLJPFf#HXVNQbZM[$kTVf[$-l*TU
0%[XfiRp-0-HjaDrrqI(E,F2SJRLd94Lp0Kl0qMhcErq&MB"+kjKS8mL3!1bAJ#5
'p`rb%$i&SiJDKkGmB&i"dQhML"m3lkhak)CfmAjV(lq6[QKH6(4ShUMRA@&Uh1`
Bch$JYJbGNKR3+5cHiSijH&Z'cSN-B4C8h59HIGGiPS@SU9ZmYZlE-[IB9MdE4A'
'AJR-8#FE3('p[EGPlE-0NEla$)GZbp![Q@&K$+p$3!DF"fc,N!#p$E-`dk+-l"`
m0H3c)DZSjHPUZB"+p*(J6,8LA6h#X8H$1HUaG!Ald4VUm@#fHL*G`A1L+PB4Xlb
!hl*8QPFk`3[BbLTh6(&K4$d"C[0lj%r*,bbH0$%INcUrU5LBNlcr''[`%frDG*I
26&jH`ES![+@(h`N8[J@#,B!XhTSVl93m+!%c0qE#b)r[[SXhCHeiS#qH-Y'q'Xa
M4@h%-NYc5q%E*1E`)f0a[S3I!i[cJL%p$aq#a,H@PNhMlG36TC0+-HD*PlTRpqL
*Hqpf'p#$c@ZrGBq"PH3H!b[6h90JCFf#h%)m!%3faU$!m6BiFrcJFGLmi0ahF*m
Mm+3NHGL`R')m3!#ZpU%9I[bEBI(m'2K`af-`)'dKahHTR6)Zc!'(2,L@cqCB+Pj
M#'[6m"jFBT1@qR!AMFHJKXA@&4mHeJQc3#2((cM%e35*Hc)I4-I*@U%TjZq5-1B
`#'-TH&P()TED'(KdLXI')lEr4mXj9J(VkX6MIY1JC%VL"qfH%2mr$3d@F("MT8&
`F'aP8f0bDA"d8fK-D@)ZZ3#3#4DG!*!3XKN!!2[B!!![#rq3"%e08&*$9dP&!3#
Y,$I#X!1PI3!!-Tm!!!I`!!!+Y3!!![&bjHld!*!'*a%0`09PJeCQCLEhj1EKYlU
P$G`VNe0ZENC@`XKQALXl1Ee1Q@jkPXI2+hCiDRK16hEV`)fr+Rr6IFb18,+2pB6
YSi6(kYLPC'[NpKZjcFKa5TjYFPZ6E%)j*C[`Fa2Z&8[##0X5IK&11$QfcpKqYQQ
hIA)mYXNqXJ*IA9Hff@D%RlIerGEfXD)4&VQYK'ebQffb*Fr#N`e-m!,KJHfm(S!
"`,3P!!lm@Pc4+&LAlm9I!(j(f)T8JU+c1IC*J'a&mAfR@&%#FT92p5Z4UXCbIjh
MU8B"XhJN0D+rUXUmRq!FhSQ1QdS,GD6`-E$L%c1YLq*lY2jARTfi"T!!#@,$1ED
4X"E'X8l#MRXiGSJRG")@[)9MAq6BE*ilK@2e(%[Pf'UH)m5alEbZVq"$!"ZqdX"
+R@"%,Qq,[iF0"%aN3D30Arr-f4F#XNJc!@""3E@B6kmNb4&ZiYhdYbLL"c8L2Ba
h0@YMUF)A6ZCa3-S*ETI#ILT6!GJBB2FC%Bdb#S,'kdq+,9X!CU2Jc)lbAkL'U6C
h1#6j`ReF8f!5T,%ZS5AqIUFKX,m)L8!5liXeIX8NS0G-61+H-Smi[hK4-Ae(Z1@
)'VjI9PGSiRaTT54@h9ST6QB&(GpM"IF999H)PD@0N!!V9Y&V6Yk%@F!@2SAL[LG
M`RaS%+XVN!"1&MEK-qa0BBc&#@[!F[0Qr'FXIR0)3DR[!GCbGHKp*HHL(Uh#$&D
i&aKc6XpP"3r[BZVAMd(1kcrRHSQYcG4(-Q$dSjd`lZPGMG'hLjLk#ANGfJ#MYlG
M[Xf)&d"fd`kQE[Nfe`$eNHbi-ULEpY$rP!HbINe958@mL2K%$hbY(GjJ5hNeK#G
I-[+MIU"qlIjY!2-d'[RE5N'`3YB[IiJXL&-EVdI@VhD`4NLVhJ2V#Ip*#e0MFK[
GqreAfC6RZDTL2R)fGPD`YjN9l-0D[,#-6FXX!*M`$D0H)U6Q&l&ZB+R1"MNNUhk
IFcqj'iZNV4$a25jHcfj[0ZZZYZ)hrJr!ilG#qKp-+P3QLQ(BN!!6p@[I4I@,e9$
(f`rJGcGE!Lc*'C4mcYVYV(#V!U0',BRV3'&l'f5Z2`Dh6$R#GD"`D`Z-bNL"l1I
q"%GV0b$H!CRE@eRKilQF9f%llbm$+qIrBal)(YR)GD"`DbIa1Dd$H[iH(5MFHPM
2hjl"G5"lq!CN3C`bH$fb4l55$[bd'4iNr%AmXeF(i$Il-4[24ieJKqkh0m#aJp1
KqhJq("hEJCB8r6RrIaZN3LGV"H%QTe[b995*98f+%PBMcP*CUTG9c3R$(j[1@XF
6(mDk[!AXSBRB)b9,f&FA&L(ZB9e,UADN1`,Lbf$iPME@+SU)[B4I4FHR[-@8CIQ
%8rlSJ3FfXBfrhiaih&QaVQVk[if$Q4Yh)ci,m@f8AmHAjL,HSI-CXpR)hdPmm%h
j+2ma2Im$Ka&[jMM2rp![M2aaA+pR0A!qbV+Ce!0M6r8!6L085IA,QY-dT3G3#e1
F[R"3N5*1-aFYC*P1TcZXbLAqJ+b*YcZQ1qj`QUcS!-#BCm'@SBZKaq-5brfK&6*
CcC140*JK%6R&(Nrjaij['AjTL'J1`-2Y,Tq6b*11YN!X#j*$S0+IbH(fP*HB"2#
SFFde"kKVC9AP@B)Im[$1Ur9D((@02NhV!(Dm&Ha12K2PND+m48rl(#N3#)G$BUN
FL)h%f!pqa0@)q4E6G)(c%"bqIVjfGihSQZDD1[9FGqJmV!lIe+QQ!$`X$Ppr36l
Jd6m*r+#Z5Kq4+ccN9FUd089k[clj'VNhJI#XPj(%kZe3+DrK-p18ZhJ[ilrlm+X
)djT&GZ3JGe*k[j*aqemp-Z)m"JDP`j'(4p*m8Z"mBI@k+T*Q&X$$eeIC4&h*YK%
2'r'iS%5AH3L1!4pPSAkp'$S2V9qRE9L'BLh)G6VfkepeZYC9-HKM-LK*bB#6U3r
lQK)m%N(q3pA8!G-`a%0V$03PmU4ljPfX+[+)0*N%m+#`1V",2UUVKhT4Gq3cCLi
`Eh(N@2Sc1DikmR-m6!-FHF@Fq9aKqq[KpY3NkQ(fiHcIUqT9Ccr!iiUc(q3aj1`
(kcVNl"-m,MTl#X2CXd-r+c!$F2CRkr&[ChqZX"mkq`52)@GrPXBeCcr!)q(XEFJ
MBHleZQTb`ifq0rp`j$0QVML6ikSMIim(K8Q!)kraKqiS&&I0R((GNDIqbe%KdAl
PZ1bS"RKFF8+$p4Kb3JNHPjAq,)pV5Mr!`q)B8-88j)(#-'MGVBk![dr1HLF@jcZ
%H)6VP[IaU+KERZ#4k[l[QNHmk'jAkIAFTcXqSBJT@#hHU4GjS!)&qVcQ51)4N!!
d6A6KAK4Z"*fUIUcMd5[)pjN#e29Mcp(Ma3Fmr@8H#@90p&Q2)NEkfZcp'-CAK6r
5S(3qh96HA)K6Uh06VRHMCmV9)-DRQkB!2&`"6308)05AFcb5d5[``PqBdr1TT#P
!2IJdd45!4fbDf-IMmM3abG%B#3E+fh3HApk('bV*3LhLfCm[%%EHZ`pbK$YIQ96
H+BJ(Am18Be#lAXIr1i8lAp`KM&b(@mma(XZaLmlAie+I'9-F[h+KAfNr)m'$GZ'
"6JEFk(Xqa6%&k&Fqa6%&i%&K-`A3-`UV+8"r8$PLGb1%PCGZ694VXKU5J[*eLi)
-'6d%jVc1`$3NU"(-AhSJ(YQ3!"56RKi*iJMZ9[01dG&d5%D%IicrRiANIeaGZ4L
c-I5p(YC5HrU@bAria-&hVlXJcp0*Cq*fY9&@A&)bcJX-$5RXB1((AB`$,qaPIEr
lP0kB!-A5T9U%RedbF`KUibb`#)BXRZaUdXSHXI`af,V!k`ZJQ*5&r"'r&2#[N8Y
8U5%SKkk8m%E&GIjH@3hk3e,N'RfXCRD23qf0N4&Ii-4TV0XGI)jKXK)l8HAC+'`
aLIT!ihf!1kf"1ScH$LbrY$YL3K$XK!XkHq'+lN-*r29q#(E-jH(M!m-1QVY%9Tk
VBZkm2$&[EV'h'*qH-TFhcfbP"Hck&C4Br1@f(Q[ZpRcU-2ibMR@"S#cL%r%F4F8
PK2&`@j@hFL*QI,3h[l@$$rAT2KeBR`#kFCG&@0+$N!#2ceQ%TI`CI6S!hj49fS$
@8h#P$1",D`&[EV&*K$AA!&jVBIF39[KG`%0UM+q@&$d(+a(l&Q(H-N!eC'm3GTX
#H$(&`R2-q!Tm%l(e2-IRi!R%Y[&ZI`&fS-(E6GLB)$`0-2&K`Zj1!raRBMYK#jk
(rFL'ApT+fJQ[)XBpdH3S(%AX-i60fJ"r4)`@Vf$#@SDecXXKV(3R`iZ!HBYi@ae
NH+8PMbpVI2Bi`m@&bAbM9eh(2SdB[`D6XirKTXTNAV19M&8"61&h"Y@lf@+!UAa
$H[%cV!%JRerBbfc'1h#3!-pl#(E6"5S(ch&c#f(X#'%M2'TiZHb,L0LVQMmFXXG
`YercTI0YS2L1b6$D&h1&kq@lj&"DcqiBrme)1m,BJ)bPM1%eNKVbKaSdflakIb5
X@N[#SBLGcdQ0a1Nah[0@494*'q&UdL,KS,K!ARer@+hAl-8qRicV,KiTdUMC[*,
D)%IXFjVmJASMBHSL&jj)NL00bM$D-cHUP%(BA,q'Nemj@)Ie51YC3ZGjBZcepDP
Be3`iAM4AL4Z6$D16-M&LK*dNeR0[*TNJA1EMq3b#G[fX!GB[*!IX1)Z2Frdr#X"
ep*@YdXjV3#LC82)VB8H1NT@4CbYCbB345KLK%EBH1HD4Sq6`-I&-I15BC,LH$-p
12#0iHTSIS4HK&lQ9N@2NQ'6%*-q1M#QC8d*PC,D5#5-d-Q,Nf40'MT%"*30'MT&
Mj#PKj"QC-A+-(*-F"6km9eeQK*'M(D%RSB6L'@%%4B``!!)F8%ib+a8(!"M1IS$
%!ja,L1Ni1h"qJ8l)JJ4TGAM@VAK"5V2pB(0pU2q**&9a$q$L-`eNr%G2iRapaU4
QPe0QjDD9'NKjPPqTHDEP!r49Xpri*-'R&Nd(aC@pNRIh(EjY4GqIi1XZh""dYZA
rjHX+6'I-b#q#p2`&,P9$rlU%IiNG2iJc6CP!PMEIT6F!2HH)MLAC)jD8(*cc11m
a&6%9-F9IjDVB)R`qY3"*1)0JRVh&$D@kb*5!VjpGb0*qVf&2ZBk9SLJJpr[cZeC
H`CIAG3hCkha#$Q"#D2bR`@1NA'"CDC3Yb808')-R!5jm3!$c,#ZJ`NMB*,6+Xa3
Lac&jKC+*iFYBXfjEC9,mZ3S+eVD+(Uj#0%6'h&I4'DQ3!0G44DYTZ!TUQF&-0Z0
21Z9$airYU+!Qh&Ca)ZpL6!h6Xpd!$6P3%IA+RSVHXI)Gb`b-QN[&fYDKr&B4rVT
(T`2,Ze8bV8-RH-2[Hj%SP!,Ukcp0%+AbPk0KjirATJ0lbXUdj85mHbU`fB@%)d1
LE21qL(,240+h@ZHJ+qK4Trp8%IA&PJV[8)8DUFq&VX5TA,Rq1XIZqd'Y6!K)R$9
1i5kV,,3Hj@APBl2*kY4iK%!(CifcLP`09LrSfJJKQ)X`TA%,0aihUkaH(*iS%S,
C#PRM,$CH[I`U@"'""(FSEYRPZB&9lLXKS!KIMeTefEmFX5+#24mf@R`A2*8IVR&
@3["5#Af0,aYdFk2Pk`Cfa)mdl(8+*QHQPD%C0RGk!GX)fdP@G-d2$dBfrfN0$je
VZ$HZMcKi9,GDkbTpG-1k[ERC@X+lANV6$Yd!r`%!!!f3!h"`Bk9-D@*bBA*j,VP
`G&0S6'PL,VN!N!QCLJ#3%1h#!!%0rJ!!,`[rN!4069"53eG*43%!V5`hTE!Bb43
!!$#J!!!MA!!!#H%!!!I9lB`j4J#3"TI&$F$9*A0J!dk6dfkccm0[YHJJ@cIPY#-
X5PCZK2NbMp02QA)kb-JqYSmHRKUHkAAQEr`92q@a66MG6lH%ZaPKYqNQq`L2AG&
Y,2+mJG&0119N5flV2R+F8%)**fc66BiIf5`*)ca'H-r)*V`Ra`R[fAGNNp[(pNP
Z"EjUX0PY@K(ZE@Qh*P[EANH2X-KY*E`4fB`m2ccC`1X*"+$Af3-`!&Me3B"Lr$I
BJN%`GMq&6`"q49K2#N("p4aE!C!!l[Fl(kahGbL5dQmj)1"EZph4D'ZYV@)3a2J
6IMDq8Ac6J`$,Y`+8l!FM2RJ[`-FSclADqh`cFI8%1*E1XGf%$6#1M4&fbX'aRr+
%9X*kVq2B4cQfRZG1jPJRae)ieXpcH$Nf`RAp)Ai)B-+[9+j&12*i@I`P6#"J)J-
L3rMeYjba%*!!4DS1!)Y`e*%L5C,&emHVkFp46KpFI2`)IEH`)CBLI14-RK)`88f
(i@#3!&%3Y$3Ur,jp!1ZaAD`2mMHN3)V*l[0+6Pp-+5-83#SE&`BLhj2"f9#l!9J
,jY12CS0bTBFB40i%))NAb*eZ[ij!dHQ8a2YV(@*GaHB+qXqdb`(&GiHXp+KLRA5
l*$CGhbJ@XT,4Vl+5EH8Y$@*MM3[ba#EkUXaIYJlBTJ2BjCr-@PB(A@*,!p,*`A*
8f10#R[!5X610![3Z3f!4Y9*U)3"hm8CcqLYT#EB*"l9)GKaBLV9,pXU+ffNp6#h
H)+Np)Ri[LG6fmHCFGVc&L2q40`!2A!mC[p@TU,#cCNR6lri*dLqXSBEIrbMq2m'
f!NZbpNT1DiZ(PAl"$r2REqAQ!4XG+adHJZb2Ri6VLRlT#[kQ(0m2`2bXC-MplXY
`SU8'm9()(KPNT3rNF9kP`rG'H*F1er2hQ!GbVh(KNa6%aiK2m-LRKq%PeXBV8RM
iD#JrpP$8Eq)AT-2c@[lKV"S3M*!!Qhi2XL"1@9b2h-a"jS,8lqq!6a(q0,l%e0a
c"*rkqM&iiI!p)3h)P*MKj0'pF2a8!Ik2`BRhB*I)3p[)hqq(&"KMJb!XX0SPCd1
6f06RprZ8J,9'PMTP4E9#qTI@X-'Pa)HamHB5YQXjeNMe9VCR8cRL$MEH4YSPilq
!H$ZNlaYLJk+)f&(mpfYidDrCRSd[%dljJdGfISlYIR%[iK'$`XCELK%IiQ$flJR
%eb'qRr*VH&XHiU-DRi9l3rR(L!pq8cl+Ie,,[r0ja(G`R1IIpE03rJLZkGQ#CJE
jq0[,U!mN@jfqAVm8X1Ujp!'@EEADIBTFlIE)URLMCBePY99RT3m!,$`)TLbY'6S
F0V(HlHf4PE-f)fNQ3b)@96JFpHqkRAEmVr$l2IS!21cfqXT%RJ`F@BQe[H3352T
c1Hb1qQUG!"kYYJhk!,Sf0M@H*rJ@MqDU,Fd'5iI,UDSP`%i0JVNZ1Jj+ISKMjNV
*ir(j['+0l!Q23YLpph')06h$ZaVa%#c1DEjQHkYSHjpYjFUTkY"i'#h1P5Ye!AJ
B,-jT3GlN-6d"HP0AIic)C4lbG[qKE`eSpIV`6lKl)ccR@5642`+0mTeml*Cm+ap
`XN12CH(l8AES3$[E-hp0Y&l*Z2e2Mk`)MrL!,"ej1#69+ANZ#+[TkTG8[3!HcTL
b#9h*YK%2%r'if)RQH!L@Z)mb)3mUf9KS206T2Qe#'5V8AYkR`dr2pZNYYSBC(j0
&5DVM6UE6jqa,m%J%q3p&9H+QBCD(k[*d*2*N1+SZUBSm!Rdk!6`SM"DXNUZk1UJ
@08HqYQbMISXM4qR2jEMLb+Gik!BimSE+1TSaar@`1eS6HZKp12[A9,hLl1-m,M[
l'4kccRj'eePRRq"abGP6K*`pqf41Zak!Xcq[acqFrC5`EcRl")pCChqHaY[12Xj
$2m$C'bfUh291hHYr12+eC6hRFPaaj+raS0!*F15YEZrU8R&lfGVr12+8[cXU*$V
G1HBF9Cc(C5FdSmHX%dV`Q1[djhQmhHRM2!b@H&G-4KlB''DXZp(LFFIDfHQ*aB8
+)4kqMZiBMiD1lJ52&2Yrec`LSYYYZ,QM"a"[G-4N9)YAkL8Hf)%m-Dpj$I(`5+S
UfR![#MH#*Y829cak"AQE,S#ZlhU1U"H2HrSj(SR1QULcD%F-a-VXVj('9d5[pU!
-2Yf8[)rMe'TUb[9U4+GFc`e&TTZk!$aX(P8&l%$BAkCic%1[`)@r1+IR8dPG!$h
i0&%AJ%GiQKMM-6G06,+i!VfH4a`DMlX2iHZlf3m3cre`#4XDpi19MI6A2$,!pYp
-c@BK3+BAh`q`%Hm40[4cc"IQdBe9G%'20qSX0-9aqbr@U`&(1!NHY!-0Y#Vq6Yh
c+BiZ3,hb+BiZ!!m+Nbj!2k-`kJ,8"mN4AZdAERppb6qY8HSAkh`ZVqVcrY0K)%0
'(`+crXZKk)J%&B,q5`e%)KH5`UdRfS)iJV[9[&)d0!2Q)F,r3Zm2`VcAcfjFL[8
BfPi2'pMbbMQ-Ir1*J+qHpd#HVb3Y`qeU6GC-HfYEXp1MEGI(0U)LBDD$+,`ZH&'
`CmmF@*QX+cfID'Y6!j*bYG(S!359F3iBK&"E2&29e#ZMcI)*-)hVJLM1F[R*)(f
Dq$CfH8-D1S99D"*S%&k!hi@65FL,R2%M1JU&q`I@LP$1RM1X*ZLE1$aI3*Yp&Ri
J5*Jm%h3a"$2Q`LPAk+Il%MRjYSB09IPLrSD+jJVmG06DQ[2e9NV!V&e"#FFIMkX
*"EI9&*,,AX,'3I"[jK2a4Ai&Pa#@`Je0cBh,-H0pTr-E4rP3RlZ06C9!4mjb#0Y
@"FAiZBi`ef2Sd`(iTUaT*j!!0FH9-Y`$E`5mYF3+#-Yq'MBMaUqQp0`&(d!-VkM
Je5@%%AZ"X-`A!5F#l2H%hA`-m'++J8rr&hm#2SrB,X*@ZH%VL(f0X-+$m#J1pVj
(f2)I`AI`aY0R#8Yq%LB3qb*Kk4)FaQXY#lKQAiCML0e)Q,X!6L$'Hr%Y4q&hL0h
'H43ae(V&BX)bFKLHK&[45TMXCALPC88AB6A$$"FAmUZiPM[B6BKKGH%@fBmCEUV
Nmp@`['GB%d!"lqkf$c(8Zp"1f!fIBFLK+)hA9LhHri+L@hLK6G$eT@+HBr%!BH`
KAK-1aGFY1`-LeUVUpRR0BGcZ9TdCI"XSXQ154[YL0PqRI+[X6BhZM[&RSE5QUNj
h`+FBUhhH3'CS'c+F2Sbh5SVAlHe5cAa1'NUF%HCGY6fJ5'UQV8m0q(V&MA,r(6k
P8c9A1*dbVVXiT)",069,5TFF-&IfZ6fGSB3TQfei)NN1p2R6D-mmT&)@B4[F+Nj
qjGi1e#!eZS61mi6CDqY6BD9#F&JSNkhDMXR5k+4-Q"KKCiK&lmh-)`LAqALq%%'
cGYB!pI2+(M21iL0Fr`m0!&6@1I#bXlbm6%[lcLLR[CfGr1cYG@)$`ZQPl$aq4YL
4jq,jHY,(-hdMq+G(9NB'R,!M!hk%Nc%MamNa-QEN@13BBIM)J"pKj$NjrS4&'1'
%%hlN+1(N@8rBNHFHi9j('''%2@&(RK&'f*&M3!#GZE)e6[Q4ij36KQFV!&AAC`4
*()!T-"jSd(NXUZYa3NJ&rYB5XZB')@[RBaE"hbI`pc[mfNa#T(j*a&#MHL+Pa68
e9YHY+M(9-(H&$J,MVaF#(L(eFrU8D0eJ0'k1e!fNe+JfT%8*QFF`+Kr!-EbU,M@
T'TU$b6pHbRi[Qm+$(X[kG%2Ye1+UZD'Z(ESS9YdkB+FqUQhjQ'c+iP@%(%h+H"p
H*@6f83V(hba#&MH3!%lmS`kK(Z'8#+RTfr-qa(+Yd*L+M[aM"IDDf@qA"5FBF[K
8@p%iV0)DMq[44PM%Ibp2XkK`@Fah@E52+-NC%Q50d+,+C4&1MKG)N!$&3J['SQ2
RlS"&5eR4c[C%V%$MPFFXi2X##qbq4lkSF9Rd*#h9'%YCMjLX+f[4Np6b$(*EEeS
,aL+FPLbf#"B,A"BlG8XE1LKiV#V[VSL5e!UlUd(iJVPVYfVUBdBdlp0AbqiDd+1
M"9qm@(EAS*B)pXA+XKE[*,9dJF@Lab`X,9jJm95C4DqZ"([dT8N@Z(ab[TKVU-0
U1K8XG!IjAaC-LdTS86Tdm-*##iH&H6"CC1%j`GHL66'$aBARi8kcS,G1QjC8M*N
PLYFU&+8HE4p95XkSNBUfJd+`r`KjVXJL%@[YPLaS1L"Cp24+&Nq@@I6YP5aQ&ph
P*"I"6Rp0X+#h$Q846UH-'4T[#4Ec`+*$X3)Km0B+&R2"SR5Nibf8lJU2UmRJMXb
Q,p-XU,[#D68k*N9pAE#J[LLGqRME"![U8AVUle5#mffjG&HA@R3&)A1NdlX9Fk4
)BklFAGfDDHRb`2#50GmA2FQBQZlri-!-M4f#"EeeR!K%RS&,")XjP%9rb9cN@H%
,4i[qdQP-RTFEX+Hr[(C@5+IhDXRLfF966prT[A#kY#MCAY5LH1VM25eCp#PD%#A
LeFYp36Ha+IG&Zh4k+DE#HdCS3AGkd9Rd[5'dS2XLSKKQmAbV%LbS&T(4iC)@GB)
&hHQ)j%h9'#r)X9Sk2@+8!KP#1`%&,A465`pBKG[i"F'#CT)JS#@(!kHq+Ca128V
MZi)3H'h5&qAV!Y*,TlqV&*@!p*-X['5&T@R9#63AKQKcS6'Q#bTETeN`AbcXd&$
JS)GNZji5Zl4*X+LNjh9!`(Qddq'cU1SF5,NGM)$'q[pmi@Na&XFkYSSRpSBC,AJ
[*+#a8E#SS5`k9(28dP0p`hR(G`J@LlJ@iE4P+)m8D43XUNh,5%B98idQ#THAej,
jQiAcXa)XKUaL$ZkLZl[+!CC*XAhNm`X9K`I$l`h5#6!G9*RT!ZXL4lf)2FY44BD
E#@hjc8@P%bM-88A##Dcc(28m%XSFUTpSCQD0IFP3-8%LQ82e%dclMfpf-&da3D,
NHLK)S1aMjfi`9%b3!#!jU$*aJR1ZF3pG3f,NS-U%#3a[FUihN@&`VL,c!%-2&42
F`p`0iRi'`eZFkbhFR*bVZ&(YXfIICULBi#,MU1+#XqpHk@+SQ1!#imi6&aZmICU
lr$6b9BiUmPMlXjqqCP`a3BV2R5G5IcMR%[I3*A4&R1Y5GN[X)kIfH+LRpU!E-SR
kd"#C821iYr1Dap([FP"P(``-ph'Zqj!!qcQkbT`3IXY`jf@3!%4P0dSqZF)Z[X+
hmK9dT(+kqTdUU"RMZXD3!'6c2555Er[iS9mU$MN+BB*NLHXUNLKlSUH"S@+#M0P
"PCQdIHam082&"+QRJbT68QbI8biUR5#Ij,U+2"21ZFT3-8(R,HFK[b0RRrej"9-
)%c5IFUKq8mVqpC16$"86G%kbpe#qSf,rq%-V3m8%l61(UfbVf41*kjlc%YH4Qr'
Y,()fq'd"Gpi#j'6FVb*AXipmXBUKBS)qCFi0I[m5'f'#liB*Y$[icK0Y%$"FbVN
Z4CDGhDrjl"YBUcRUDQ4Z@9hc'4f`DMPU,CU-MUkbqBLp2q5KRKT#YblR"Vq,Kee
XH(ZSf8#+c0dJ8QISXT)VY"*pY4aArh5!,[Zj3[[44(43CA-4@(XjkPkb[X9*4f4
ZGI+RULiAP8l)"KG9jP46U"XCeb#AQN*YG&&PJM5&ZUR&G813!"M"!mZj'jD6cCk
ZK5a`LQZ6LbTcb#R8,C-ZpeZ[d18!9qJ!NP"Aeb!jYBqIX,`lli5&RVDlmi*HGbD
dlEDh[EEG4LmlYe(mHL-fRFjhRSl@mZ6YpI"QXimIcRJ+(FkJrF3hT@K,)6fjked
fjqkL0j[EjAl2eVjhiAH'LJRDF0Q8)YqH`b9jKpq8Gp$biULL&3DX2cRURqLdF&6
4JE'r[rB98`J6G$AiR5FD!dM@ZKNU*QJ21+LbE3"GlR'&lU(9akmSd3+%,QHi3QI
3Tq+SSRq&HkD*AcC0k-ARdKHr4ip0PqBl,if'+Em145-e%pT+2&e4''M,hZ@L0B%
Fj$*24#kMXC0042)0(r[+TpXC+LDN`ld!C&BqG3'%(b6%qBBXe!aaA81NNeifLD1
28f`AP8j#pE[3D+T!2hCa3k6AY0Jhk!mXkFE'q$E5'6FIi0,r-b!8'9#(lprR(q'
E#N+rSGf0r`%!!!d0$h"`Bk96D@e`E'98Bf`ZZ90S6'PL,VN!N!Qq+!#3%2[B!!%
FA!!!,`[rN!4069"53eG*43%!V5`h`V!$TDd!!$+I!!!)k!!!#V%!!!-pe*!!&38
!N!EC*!h!VCp0C(j[0XAc8klAbeIQTYc00Y[VCQ3cVlAR0&01*G3ZfmBfSBHRKZI
dV$@IikmkZmdfiA3c3VH%j4&fHph'ZYK!`Xr)IX)M2"EK0,)CZFeZ+pQ%%NSfiHF
QQh@a*)c`''&E`XNq"ahEccElMQabqpJHN!!9q1TkpTYZYNp[kjZYE5efK%9Z+q%
0M'c*mm16$EbH3!"kR6d!!i$TL`#Xq'qdKm0JDRN+R`$mNV$&b35&jh$X*S$d3-$
p9CHR0H#9UYeHkdi$[RD+FY!eVrS'RV82rA0dMb`V8*'#"m'%RjMTXf(m(U'qbV%
39fq3!'0$1,D@X!l'X4l#MMXjpL*2D#1XG6c(2X1a16ah%XFD1CE-X@8mKipM@lQ
Z2m32!jMa+`9-9!PDC21bq&ZB`B#*M)L%m1[[1I[$J#a5G!"B8*!!&ZAdP5"Dr@f
mQ[iDKI4"K8JIfRF0#l&N`kG2jE&#dJPZPm25PbNIc!b`qV3)KaN&34286iU0'`(
QB-1C%qC25-0NXm2[%phqIUj*N!!,+DcAd"(prNY"B(d4%S3%AKI,23'GJ&V6-BR
EjcQ&mU)&4I5IlT!!JV*rU53[9S4bFBNSZ'kX%UD`r1k[XI`l#QXUKDUbCXJ@A23
e0fILE'#hlF6Q[LGMBMNd#6@95#F6Lr!ZpQ2fV$%APS0al!Cm-aVrae!(TES(Z)Y
hKj0ILGRBMpSaJ`Nq"BcCCQ5cr(Yh-IQ,af$-6jlMr4*,QmRhCF#)66d`l[&GcH&
I&c*j2I*kF4@-f0U&q6BJRJpCEGZC[2%V[!I)pf9&1i1mIJqpTcb3!2Nc8L8Cm8,
L%plrq5jiPG9a03b2(G$bBrr!rVAl&el-dkcP$j@"`35C,qp!&X3Ta2A)r1PfeJ`
T0AYJ*H(Il@"bT0f'RrVkmfcUphKAaAcNE#`XrqPZPVmAYALkRNdIPJm`mAj0,`'
5m`VC%@$*YLE**mNHYfdIZ4ZMU#`@m(YF9-mMe9RX5)d*rk0[!"kk%G*qSe24CF)
BQJdjS9rA,Y)[SU'+Gqh(rpeX%E!%@k[SYMANXB,0!4JqI&'d$a4dK@$BbQ-`IZT
KhJF+0RI!m)`Nb(Vbph#d)3RaEKLfYC-92*60H49dmIV5X!Vq([0!eY"QhJF+0[F
3Rp0p3-dIk`-&Q`qTqEXbH"r)'V)+@4#R$+j(9RSRpB([Vi$9K$q$,drf!IMj[P@
D"P3)&MKfB!-F1Ck,rce`G(3h@P,djrcp&NL'(YB*KT%fKqLZG!QZYN$!,`GYCC,
B+-Q+$BBm1)0e6L!qM29@jl-eNl"'5KHaGEF9)ZjN[A@N(I8G!q,e-'4ML(8+!Q)
(m$qJiP0raGE0$a&1qF2lleR2eVkb!I'SXf+p0AQ)KcJiE1eZa'FM[SAbUhKG0Z,
G+Tp4'l6m2F3([bNIj6qQjVrR%1)V1-lcVhP*bar&96eVJ2-*e-qL'KMG9`-9RJC
CP$f5BY00U3(XK8NfYlme)!CYHLkpN!!0XpNFIPNUpAJP4IL3!(@'p4DEcNSI!"M
e"*Jce'ESG0U&#Sp[X84@me3N$'D)ajJLTl2L!mGAMrp&JB"A(i#(`e%a0jiR$@f
"-+q9(!**IbD(`eP4UK2!SpCHV!qJDj@VkLc"YhP8PbbX0PSEQYf+NJrXH#GBbQ2
6`+4(1'DC+hUpIVp2+*1mNC%BZhm6KjMV@Gl9L)I"kVl)eq+S&Hc6lG1QRDX1PBI
*kTif64H!Kp(U[LM)@c`Z6J,IdMA36q3D$kNpX2HE(@Up2[BMlYi)ccb)**CYK5T
T1CqC*Yh+jpYXlii-I0r0pZkXCqZ'ciM9+aQhrqQ4%H8a-#JGJMbFSZ)@[HH&9A8
0L)TH!!ph[l*aAFQf%3mcmEM3LDlb-&J(I*54k[95U$b8LhhDM$)8+Dfm6dHHrUP
2,l4A$[UB$%T51Z"N'[hZYML2H*!!rj!!&AR!0&cKS64l'q*jdT`PPe4&(X%fR3!
H&#BV9XPlZMUT&P9(2R2@I2d@4il5RmPahC'Iik%Ei-JVjjE6R(e!$iHc0Uk(hSH
cIeh9kmjqJ-FeCcr)iiUc(p6eLV12mlMNl#NdCmmqPeQ["q$XcqVa6fGr6YLhRAf
Faa9RIjE'1mjqJ%IFfCZ44pcFUlSU8Y2lGDrriFKRcPTm*XGe4rik$`UG!%GHkr(
G8L#dcjVjVL02rSHM3U)A1mG94cA!ijS6'Y6MLK1+mlMDkFrbH+I6$r!`@JHkBK,
b`-B`D0e09UqR[jfGR&LFVa$Li@pSkHG4fG!5jj(Xq1qD4e4dKlhXhGbR+clH%C0
3,9kTPhKJ"r,fHmfKa--V+STJaldSh!MU8cp5mHJ9T$Yd!A6p`(2%[2L!Tlr+)pj
Cih8@kiM"rM*l-e,jU["l25L06cG&hlGaDR9Zb[9Da+CF,i5LddeG!"jfVk)!GL$
X,qGi*+*Ai-*IQ02cUD3ZJ"jmQUJ,`#-b6HcRFA@DQ'"Y$VCkYcP9(RI[aGGhXam
JRR9R2J[e"Z!4pZM"(GXkf*D28E-CKAFPI2LqJchk6$%,[Bcj)MaDX)V1kh'jcV3
TMLG`S9jT2b21JhEKJ8i'[&rhI)UM#e#[I)UM#m#$`U`,d-mS6,S!p8&b41j''*D
mF@XLY8TF*T6lQhf+hrF[Ki%-'AdBQ1hI$N9(*+J3p&pU)"TCN!!3D6fa&X34h+h
QPD+LDC!!L!Mrdpir!BP[A&fj&(-`e,dHeV(`p#f6rr#*JUpGGd'HTj21`ZeU9GC
d4fdGh[Y4,`cdEd4&``*'IYa&1r$#$UVlhAhp4JFSkZU8)"jFdRH3!)$+1"1-"V8
,aJlj8&#[M$A,li#j9`G#F@aMZ(&AdZi*PSQqaY2$`FZ#Cr',8ISdm5hUmKRUI6!
"+dh)4E-`T5r*8Sr5V(UEe"diHcQ%6p"l,15A[A31JTe`39pJ,aLBN8[c$4bHMk6
02LZr$fAJAfq'`B+jF-UPrA4I)M2(APPFNL2N&"G9&q'RFjkp1NG[T33XXDN"a4p
[kl%9Vp6I60eZ(1X&3f!"YajM!M)Z)8b!bDlUUNQBFG0*1UCZ2Y6REX2d-0#0Zdc
#%PC$(Rl1*LcT$qM6!ILQE#!%C-eaT3cJ%`m!hYaLZB50V3HmeX*Z*qcQMB#(e"K
I,5Pl#CBJpJ"K`Gm"6J6BUi5eZ`![TKKj$[N`I!QaPB40fJB2)lD&X,BeX"d0hQl
#XTq%ar(e[B3PMJ0m-kQ,X')4pJ&-jTHf@Zk%ja($LeB!0lA#8F3q6YMXjq#hL0(
L&8ci-N1YFmB3YR3e`iZ!13X)beh1m%T,$Pr@8-BcA&bB`MGkE82C4a$Mef$FfaP
ZUNcKQJADQ!YJ+Vmcq1'2XNm#61-EdJ@6@40!(Vq`*pIK(6M)ic8%ZqN#PCAR'0Y
"'$Y-@,T6pVG)lU#!YDTir$j,"(Gi&(FDh`D+lTLNdVkBhGmSh5Vj8Q+lBrbCPMC
Gfi#-T)cJYD,XmrLD&(0*SbISPdfPIPr3`ZHN@Z+d#1q5pU!X+ZRf0LASEaAQ5mZ
@qZ9'a9,NGNZilZ)8Jmf+Z9U8Qk5JC@kEapZS*8aHB-F659+`,C!!5R[QQNSCK"9
l&*cm5Ud0U%G+E!QGjiQ`9pHR)UTTF&3dHkN$NkA55CN)-F*1%B[GQdNN#*IjH$k
0S%8pDi$kq55["@Ia8Dlr"`#3!`[!hGUPNlU9(@%R18D1(EQ9-$+K(6PU4aKKj0Q
4Ba*kNTAG5QiPYai66`mI)e3bA%q+CbHH(CjkR4iPc`KE'EReb$&bp-JcFNc###A
2b$2b0$*K4ii4YMiC-FQ%%AEN'''%NQH%%RD%(AP''$P+D16B%AD%N@IN'"P3mZc
)J!+AYaicb8TSK0Q!($e2*N%5)`b!!11"dRUmNXRS!%#`lJ0`jV"H4dh#fS4e$Vq
kJ%+l+klSIRPBeIA2Pl'22bUq(G81S*6lq@)C-j20k%Pr9%YPNpN,V(QTkVKLb2f
mX8(KT+R'`T!$QNr0Ebr,3k$jNqNKri"UC-DcLQUXqE(D$V$r"RcTQ3&DHJQ2Mce
LVH6&a(HmUYqp((3rH3Idi4cYR["C[@0A2[f)K,M*9H+Q1YBFeN[%JjS(0DIa3$K
-`G+Z5A$$EK5$j$Pf1-HQL02Nl3FQZeLr6pC'4RA9ck*&lpF(Dj`pq)+5&%Ah2+r
3#j!!%)cr0(L%N3ZYLdE)M1-i@aK(G`*d[1(cljL'9JKEQi5emPQbP"fQSXH55R"
d0*,@c)$bKh+Eq&kRF#&&A$8fr2RcVP-36Z(P@@b"Y'jN`5JB3PrUA*h#XdVaGIG
C&"jG5ihJNJ`-CHUCZLX8M[II+(J@,B,Ll`bl9LQU'j[MH#0T8mfH55SUVY606I#
,`ZTVP50pTa-"53S&kKM0'a3YXD3jh)M"HKAIGBVYXF(3`(MDe%E8HKL9HIT*%6`
P4rbKV8LGUa6XFPUKm1"#lf!)1+ZEL9CmqEkS8IMilUVF1B(XEiU@bUcf@QRDXeh
XRqmP"F-F6c%&+(HejkIiBIBD+F5ND*JTi1#ZpZc@@*[ip0Rc8AEN5Tb9+G$-@He
Y8j5eIT%3+RKG@20NAb0PHN3KKIM*4*`T1%Z@UcelTDH4Cb62A*N#6M&$MHe4P$X
A5CiRe,N),M&$MBeqpqCm'mNR3ReKTZ"eB#9NAa1PkGRc)L&8m$,KZk&abC4Z(GS
MA&("fmTbY@qa-MhmPVXb"@mT+b(lpLVG,Y`4V%c*I5cMjX00k*L@SSCe+*1,EHa
iH)9ppk@`[R,Tda2X3j,9Xm[,e5EmRd(E@3ql@[i$!*!$$3d1F("MT94ME&0S6'P
L,VQj8fK-D@)ZZ3#3#@#V!*!2!3hq!!%UFJ!!,`[rN!4069"53eG*43%!V5`h`V!
$TF%!!$+I!!!)E!!!#Ud!!!,jPjp3V!#3"L0r$F$9CB2@,M16HhCjH*CZCT1pXRA
6,MIG+f&N-epfFYT&C8VS)#2m2-)16`h2k9RV`)fr+Xp0pdQjK**0@%pB5[Da1RB
Tf4Ujr4kjcFKa5Qkc6EDA4cDKK1iMr0c25T-``Q1%2q'%Nf2l22HccAkEj2DaHV)
#AeeA[pPQTEIerGEfXD)4&VQYK'ebQffb*Fr#N`e-m!,KJEh1(S!"`-aP!!lm@Yc
4+&LERX9I!(j0f+T8JU,c12BaJ!a&mAfpfKHSDLchecQHD"6`EkqN4US@9NrN@8q
LEdIA$@@cG+6J)E$L%c2G(FAh+2f[I$Ya$83iPXka$B5e-Bje%hE8bl(p2+',X1#
0(2XFaqEah#NFUqGB+XI@mK`KMQhRZVk%$`&Xq%S$+e@#%AQm,2iH0K!`N3@4$Rc
p-fGI#-JLc35!"39TXBKH5C)Mh-bVk@p44!mU4(SBlaV@`9+&cjl)ii#8Bp`ZK[e
N*LIB''$e'4'0-JU#aZY2LLeE!1CK`jNAjEq3!)DT0Nmi*2R#I9a6B!UNX4kK,Il
qDd&JI4%5J54H&beqa55JeNa-iVD&AR&4mC*LqJlhb"%eI+HXVY,%4G*U5DbkU9+
FbTaGMc,R(88e&@*P@52NL9Ad+XQI-"IBiLH`ZHr+R,!)'X5D#U56M8Ai)q&E`N6
,@p!#PV'EmCmaq-fP$NTe$h!Al`l(AmPjf)r@B!BV,!I'A,2cQ,1MPDPI1J+jVlh
-qb@@0P-Ib)44$hE$Z#HIDScqVSLTQj!!erle-'Tl*qCELVJ6FTTh-(A,ehJ28"r
)LAF'GG-ZqTrb32B[5*98a)Z)6h6[aNjiJkhJDJL2l62bBrr!rVAc9`(-dfMNlbJ
$`3VC2hmF@4#R$Uj(pZXl@#1NeHb#GB6rX)fTXABEIIDEVl"T2qCG&I14Xl%cjdp
@-ZGZe1+j+@aQPK0J`TF0[84)R9(%$J&,G6A))9Reqealb0eB*'f9L1paF6d29HH
`3c9@r-Er!AMi*XMi[8P&PiPL'$ENQ(kG6j&q-3ee[(-[IRHbCF#5A%(*jkTkQ49
X9@$Nb'Aa2P$3f3&Ckil!MG-1mMj3X,804QDQ3-icIi6$9BmMhJ9CfpYC`F0jR&G
"*km[!b[Rrf-Hb"R4b2Y!`GCZiR1U$qMjHrY!`GB$H[l160i(FY,A)`[LP-Reb"R
H6RhJZ9DiPr$RmFrMI3"qZ@HpS3%9JKf1l#[$lfBiG,3E$SrT3NZ+rTcr[`e5SCZ
eJh#$bb2j+UV%UQC&#DX49jNXeFZUjS,dKfDcp[(%Kl'HDLHlEa,@51NbG[rL)X5
pV'F&D8Gp4d"m*D4[k@$YSSMB2[`U1MlY6ACrf4(#+ApdlcfEf)EIE%BmlUaB6md
-a$XiQ,9K*q*c%Gp'qA9m44lLA6UIdCZ0r0h%"pq8Mr)IdI2IF`$a9Slcr2Ipc-J
Iah8pDi$c89B@8Jf-19N$1*93*G8[Dbl6P"V!ATMLmS@$LK4aQERd3TEPFRR#UPc
U$mLDq!R(E-FXPmP+(`!Br66B-[9Qk2@kaA*rD*9-9[0%*!eQ5%4ZXGGErT(M@iR
IBN8*Q!2`m(M+5a*j-Y!@L!Z$j"")qY-j20lb8T-!(VAZqHB!ZPC@9CiKq!'2kJ9
,Ubf1ZNDITR8"1pS1GKHILI*)8GkNTle%#J6#iC!!@#B(BL-apZh[m@l%I,I6G)(
c%"bqIVjf6khSRZQH2[eXGHJmV!lIp1QQ!$`X$Pqr)1rck*m%[UqVdNIN-JpjM6+
cT8L[emGH*IFQ%*lp)T*BZadUj4Bq-dfjKGFbrVXE[iS`Xe9N"erJ6NU[9c*Zrp-
M-mjMB&#DMMbmNZD6!ZH%eA99*-dXJ)H[6pQ%VQ6EL)H0H*c[4*Gi#)i"(f@KHVd
31JqY[drE8)CL,FMlG1cA[r6TTHk+34q658P+"ja-IGMAR1#4#2)IUUB1Q)BK(PT
MS#k4*m1li)+Ub#25E",!Jm,U`#Vj8&F[eD,Zb1F8hQVHiXK4qY-jVMMbXca-!aa
j4FNLhQ(lpI"iDa0kQ(diqhG9[H,X"hKFG[D$2)DFrD#Z3miq`H1#XkF`R$hEre1
R'B#c2k2([jhp@@%rF2B*(N21rJb0UmjqJ%I#fGZ3!%I#h1ZkDR,$pEShrh$NF`T
ARFjaaC'rbi2#*-#4erT$X`V%0B9cVMRbe(mj+L6DhcNZ1DS"(THGd+!H3diS`H0
5Tcr$ifUR(q"KF3ada46NJBeKd,TE(3&rAcXl2V%i9b(%)ecAe-HMSUiT`529mpm
eMlMS(RICYGbR+Ml4%903,9kT&hKJ"`VdHFd4a#-JDCVSaVdSh!JkUAkXiY%Vb(H
B!ZMkNHISpH)$R[i5Md4R6G4CEdH-p*ACHc'-V`Trf)-bq(46qHeLR&UGRA+p%le
6VJBa2Ydd"H$K$QJDB!I#rR+@4c*k"5lmq6NpRdUD!ZM"TiQQ!$aLdm3q(THQL8Q
1aNJ`80kKmrM#EYa354D@)Tlc'DF`B[PZb"9ZIQP+HEFJ[[!UTKb0[HXer,pEZ2R
j(F+)Zh(V1FDM#D[SR"iAkmbBi[L9mr9+qaN*(V3,$h3bi(VGmbQ1+8#pmLQ1+3!
2#TXT3$qMX*S#e!I*%EXE)DbqH'ZL4T29N!!8P+pC&'6)k#%`ec8'TL&"K@$q8J2
ab)'N@1[TE8%F`GeUALNkQJ(*L2#2mIr6N!$mMkXV&f)HKVlA`pU@RVTPmKmqFI#
Gkbl)me653YbZ0Q6&*5AM[-$3N!$#$KCqh-8im-*He2Hl6rBE%k"BX8+,i-%PF`F
*U)bc`5)BEI&%991[l'f@2`"E$q$a+'`Q#d2qL&m+q&[N8P9U#-UKba*H9ecRAbf
V3Ap)LPbPMfVQp$V8if',q!+&$Mkm-'q*lf+ACm1`a,!1F*Fe8$F&ebHR[Pf"j4G
h4d`)JKec3@FZA0&p+)'rhJ["MVQmI(aJf%&cPmM1GeI-Aj!!,qE2,kiZaUGhSEX
khfbP"1ck&C4Br2Qf(QXp[2RM"r#AFD`("'8*RiMR+LSZ)Bb(b9A9PC-`ii2(meZ
lq&#IlY1"p4'J'hICK#AG#c2`1CH`P$qK6`IJQl*+"p"k#Uk8!Acq,X#E@f`+BDf
eJ0GDf'f%&A`$m*!!'Z1V*8A2`'V%[NTBmdV!EXMHi$)k!5qQ@(L1U6[J+iLY)fc
j1RJ%X@f%TEm11p$Jl56-p`Gi%Q$5&`QE'!EmCe)RB@)&l!'Bc#pYP86J&F5i24V
lI6L-f+F*@hd6[)8B,9l"a$D'@ZIR%KBqc2!LB2i5`LCR-Ec5NXqA09SU'#iZ618
E[FNEf5F4ipGJJX8-0e@QFXfD[X1U!+E494QBi'Hh!dcR'p+IfXJD!'E`#hXjMq)
G1*M"D`KfdJ8U"mmaYSd`GT!!X1&H0G`Nqb)LeUVQ$iIX-GcMeh`CI"XS[Q-bM2E
&h1&kq4BjP0Dl1mCr-p)10cBJBbPMH+fNK[bK"XffS0iI#D[@dR!SBZGc8L0a4Sc
hJM849G+'ZjZe5$JShLU[[61XeQ[fBTp2aR8AVa4Te'c9NYSJ4q`PcIj![C%`GBN
E6b6*N@CP'1fC'bTP%MEIVq(N9`l@S4jT[8[S2%q-[Eiq&920J11LZ8XpQ'`BRC5
*%52X",(HHc2*"1%b(mpR%,6VC`e3[j!!(,$M,$l1pIm!N!-,`(Ad2ECHRFFPR+a
N`XMM#502#Hh)8GP+RT&Rj#NjTS5Qj&Cbkh9i'Tj'f%S'M2ak8M`lmB6KkH%lRj+
M%@ENeXJaFN`bSNHHNMNl-UGfC%E*M*%j)j3-'*Nb`Ti`mS``-QINf*%*"EkqSjR
A5GK+ISh32$b6))N4"N!!!JlVJ-r`TZXk!-$`[J53!-62*(k$MRFAhPqJ'h+J`'"
kE+(ZHS&@X[d!3(R2Q5V!cME81#NmLZ"PM*Q5AG0-GpV5"M62mYejcl4mJ%`M4p`
)*hRT+G0"ZCTAp4kp`I20D2p)AJ*CXflJ![[k&0BK$p$h#P,8PBNe5"rbHXYhTCj
Yq5GqG*raf-!U`2!+,kAB#NXT$Yk,H$pKDDbPXCEdAdVB+RbqZ)cpq4q,HIBDAb3
EUbb*Sd6RmR+1h[FEpQcGX63D"@5rZh+JI"02AYG,5'q+'dB!+Y,aV`D(NEQXjC3
LHki18f$Fq!pJk!-@F*l9FHL&!Nm&HXUT#Urd"DC6VTSm$l,@3VeMf5ZrK3A0iD'
&6)LXfE%)ChrI!YS@AXH#NS4EU"p&cZeC8&B0kITSeV&V[qFQj!U,+#@&43,T2-(
L3k'mfp(GV"@pN!!@f@RhD#ESR2[HLqlpAPc)MaY&E64,6FAK1,))lGX@jihLa*h
+Q86%r@%KBU!i&eMHrDTTR8K%1G2Z4D*F$5KarNaAQ""YLhkH@VIRj`*leMTZDZ,
B!RF*UA$DN!#HX,-M2$RL5@K0ESq`*6qBVe%&&%'01hp!9F8%a*QfU5jZX+@bALT
3"EU%Dj`E,H2D@pBN+P@J@e$MR'JCpQ4)Y5HK4dl$k45e2QeYXDBrip5S!JP"M5F
B@4[5&5Z3!*3cG*V0kbqf-kaC'CdS8!@cPHGLR-8EDeX2@A0UV$*&&G`a1$AH5C!
!9BqSGGa[IP&rqL+V%9%EZ&[Y86Zlf+EkE&03HHAH93dc$2F1G9`[dGk2dI3iFad
$I!hI,HX&"aIk+1YZdBGZ@!pfGU*(q#p"'D3hP0Er!*!$$3d@8N9"4%e&,QpXC#"
$9b"`FQpUC@0dF`#3#4-H!*!2!4aF!!%[f!!!,`[rN!4849K838a'33%!V6CC3V#
$Z[`!!!'D!!!)h3!!!58!!!24cTJFa!#3"USQ%3!)(03FJKJ31)9R4#2T%CD+3bR
TZ$mA@+C4l#FT[VLi0T(LAC-5%[e*2TiHaUeli+MJ!fL+c-cdk!)VHcSGN!$9G'U
6J%!jMpQ56kaeF[e0@`(NIY"TIBYZaPSZ#Jh%Q6a,T&"-4%TDC"$eBGaHiK6#F$r
UE,#$K6'4MH2L[2ePY((0QJiVbFa)MrLFX4C&XrV9P%k*E55PCMmU5Cp"9'4'1-Z
-Lf[I(`peHXRTR!r8LlC+CmbYQ6M-8l)b+*0iU$1*`cN"2!)9[(l15!V2AXTrX0k
2IkXDVJbafq3iprDLfarSC$QJ-RJmccPl4rQGfdfBlQaj86C'lbPj8raYH`fTHV#
M8'J$b0qMPE-r&2B(JPdGlSZC1ZG+q#P'FmIFrq"C&J!!#diTH3##$'"#b9-bSBI
R4`Nr`JJPP%cibZNASCa`)j6`p5+FF$)$k)'TbJ6)L`0mp2K+d-F*1MK"1P"Pe1[
NbSmFIm+0m#2SiRLb(S#H2IR@*kE8kB3r6(I'FL6Mm'JLY5C`NhcBN!!1Z2@",Rc
,hqX3$0kqmVDPdp0MHZa-dbRSe@cFQPSH)+X6Ya@YRMap8,m*RNkcVqb@YfD9Gdb
@(pL5V[f$d)%h(&9dR3K2-3A[eRC$%24pcklPGN+im510NG9[4XAqhCK'q!eX@8H
1&G%ekCkF*`Xr(+MAaLAm#N8JL8`U`c['UarA(D35p@268DFM0Cf'DJ[UkC(Cd9R
e+9JlEBp*ZeDHKp0+UC8A*"NaZmEk#-NKq2H!(61`k%F%UCp)Fdr*Cl%"fA"*TFD
+XDGdJ0S2%(dd&['`dC0MSHr*ei)Z5lrcJGrQe*e@ReHIU8%hphS0Hji3Q-&B-r'
!mp$N))LP#-B!)B`&f'`LHhLMDN4DcNc+m%'`YYc2QFGPLb"(dc,j1eJ"[*DXUB-
1"Jl95M)mFbK1DmPq60TDD*8#LVTr#Rr-&km"3+6fj@33Ul%&lGaJhPVr+%cQN!#
G+hA`jZcqjfmbM8hebm%*,9!L#+N1,H'dJ0VNPPJe9Kd-3r1AhXh0a4pkH&Kf%#f
#S[15JjfFi&LDIV#-jfH$L,5dRc$"*5dlYXAG2h*LG5FAZeHe&i@T+a(C+6&bY`H
P$M*,5%%qklpGV,EkjjR2$X!aJ9$a-0&D$,#rE))C8XN%c4LZINU-S[#S+LmCIC!
!cK!11deUqPDTKG4E#6HFSVUI*E5mS8,K!P#'dQb6&3RCYY``3[+#19G%q2Pb0#J
ISIRVG`)P&)Z1ppJB(MhdimJaJ93H!'Mi@T5Rd"MAQVaaB1MMKa)()M6L(,6@B,f
BHK4EN!#q(9UB3)UXA%[2l9N8ah+I0m'm'dV4rqeSET!!ClSCr)6[ZI3NaM(h`Qa
[Df2ZM6pYS!15DA,kLjYTqqaZXl1YS@d*(H%rQQ&[D0Y6m!1*dN[C42ALBTH99bc
,bIS$"qQCTrb*Z50"rfpQi4b*Qd1"l6*AaQdb0RkSM+88"F*R6F)JpAKak0@bKl,
Y2',&a88HM(5M8lHhF9*1#le06*L"L`EY&BZD,)Hj"+6$2Ri5Rb0DhFpTR[Dhf-I
XGEF$AHi+SpLrp2"q'$L2d"SE9NEE)@cJ*[*N!9d'%SFBi[m"%%kr&p8R32,F9C9
DmY6@hedY,YpG65D,AUqEhF!6qMhQ++lae#2F)Uqq0MeGZh@RHrAHp"8f(jkqB,H
ZiZJUl!(e2`d0$R0ST90TEA"XC94ME#kjF(*[DQ9MG(-!N!N1MJ#3$`%UFJ!"2CB
!!#m,rj!%68e38N0A588"!+dX0m+`!k9%!!!bR`!!"h3!!!Ua!!!#REUK4DF!N!B
@d3h!e@86QCrCbJDCKprUCMD3!+rGTYfQR*+9-,+C,cXjlD*b+U'$[1dCSH'Ti6R
ef+f6MEmU6qiQQh)*h4,@5GKYZSh9XB&NDj&pK%GZ-l+PQh$*E9C+RK*+0Z(R*T[
PCTX44KMKK1fAF-+[-pDlf@p'1,R0,X)M+r$9GI@EEEC2EqZEVHhcBNGBj,B5(YR
(pNZH(jjXB))A#!rXGIB!$!!+&J$Bm@Yb4U0JA[3XrJ,`'m)@Ta)8RF@a6`*NU0j
[eIS#BEpFjr(ERj3&r0XY+C(DZA@Ii&P2SAq+RP'9dc@Nk"%`ia-ch4I&pdMYVc`
VFI9(1$D-BkX*kf!FkbAXQ*YM,r'%$X)#0h,XmabEaA1RF+b&BkNF@mCc"$QfQH[
k-h`)B-&A'TLT%[6)j@Aael#!J)P-L(6Kkqmj"d*!&QN'!#`S5)Yjp%U5l+%fANe
rL9*k8#(53hrAXbk@+Yal-SmG8SjcHbHXTc)9JS8"9TmHd5LM)'LmpU4B[ajJ&MD
F@9(q#fQBDR'&JT)R0-!e"5C$'ZX61Z,[2aF%eKFK%8MLGG(Z#aX%e*U"5G`aebh
1+jYI4Yp-Paa43[I)bQ*9R#FYNF6DQfV%+Db`jpZXm1l5qQUaTY),Z@)Y[FVc*X`
%G[Z6f0ahC%fB"keLI6A5bF%L[*mp`AiK[!(YB,TK(Iic"VpMUB05h30mJAH(%kr
NA1a(5c'$'Hi#aK`cFPRK3pZBmTA$-2EPRr0qLDA0P)HcB15'AKMhe$C[p(HP6&Q
,[&jD#5-hGf1qGBJAJUeY#e2@Ij2h!19K@l`c+'Yhd2q8"h*H)995%5mP2Y%pAqU
')kb*Ub%mrTbH(rX(pUrYVrNaMeI2he8*JKPbIV89@4#R,Uj(cUqh-#qNeHq!&B6
rU)-TXABEIIBlcl1T2qCG&I14Xl'b`Th,@H%Ze',R3PD3!&d)-1'VZPiLT1DAXS2
!8KfYFP"@I"l(ER)h*NPG,1*lA&c2Jh8fGV$HM0ri2`#2hJ3C4`dUZN`83lFKarA
VhNEka668m1ipq0h1&J",FJ3NMk0K!5[D')B4)aE%qd"4GaGNVcJ-0dip`2Y!dFB
1'*'9!VCRhS4$$5@)pd$fjNj@p'JZjeA8cHY,akVirjJ(E-1p[!m8EH`P2UIlJ*D
r[`m8EGb[jHr1iRh!0Q`PXL"1@9`2@fBRpB'I,)F(#ImTrRQL$m#VZeIU'P!K@1(
JXA`i[(F'((`c"3k0k8&,L[kFrlm*8U'AGB)`bZ'520@eBQeE1"a5)Sj+@@U4&G8
"`akC`6V(%ar'qZS+fDU*@#-9#pLDfdX4Gl1q*Y+1qSk!q%)BYVk,GBSLBXrK0kc
K8epRDqE52f(+(phc`&UfqVIV%)ml+pCARipi&`Hc9fp(I#ELQbLrKMIP)YkMm4Q
p6XrI5hc`6INSrf%Yr`2l%9r1FCjre5rer(&Fdl-H1*r``K+UJ6'RDU$+eka)LNp
@(BBT0B#p--AK#3A#8X4Kj0),@EE$i3STFSA2,k[LTq`cl0-G"LYp!'$ddf$*dTU
Kfqd8Uhc"a6*CcC140*3K%@2,h1kUMahI3[b@KF0qB`!H,PG9H5*2"YS#F@k!(!*
*IbD(bee9B4$!Sm%jfaK!ejVDQV-%hqG40kHacQ4[pRT8Y4$BX8k`e[#C+)q85Kb
6B)XYPrcq8#JS9XVqf%L-[Ak%3q`EDcE4QhJ)GXp&[PCAJqJXF%kEGUik0"jQZfI
D0%-!(LDljk)Jlr'i1!Pm6pI`!*'V215PiB,f8UeH(hq"h*Y!H-iq*,&X-p6)l9V
phXTVQ5C!q,p@V`IfFLHPe5XCYrrTN4AR-6JS(BBmh*,UNIcRKG9d$8ZU83!2ci#
b#9h*YK%2#r'id)QZm"$XJcl+&+[A#k(a8#rfD3[+8+B'H*q1rIV(2YhSV"lb-9Q
8T',3bE5%2'd*(SNJrk'SbU"TZ-a$pIUE%hNbh(-ZUBSm)Qd'!6`Sc(DXNJpeG9-
YDSkmZ13fiaC(MY+IbA(0NCrMB4MJb+[,jp'FI9!2PlXKSBI4Kl0r@p9VcRk3!-G
9Ccr%il+c(p,eXV02m,MNl'2E93B#c[kX([pdpZH%IGrC*hKFG[CRDAcJl!Gj**b
p"ANNc,fQUbUhIP6haKq1[,KNmCNFeacjfc`S$!)FHB-[1,e)A&T5I0f4Trl$85(
4LjhMLU-Dj((9#3hTFGN**AKFkI4RHAc3k3GjQ1b$A6%&H@"M',,ZCV[I0p$16N`
XcPF)m3Je,aVJ8Gfm+-%MeI@I0Bqik#jRjIAFTbXqd4&68#eHUCGiB!Ib$hM0iF6
$,kQUk-5p+0`)1U9qV1,4+mKh'`,SqV(Rk2ILJjlq#Sp%Cdh8@Ap(M!b8fEZ4cPH
&2qa"'Abkf60T*dkYcNfjhSVq+GH'6I(TTL%!$kGI93%l%2DAFcb5d5Y`i5r-kIP
8dK"!$cj00!6J%CXQ$[#i-Ne-XRXM!Ap9PmEMrPfiA*FX0#*ZqebK-2bZAI#U82c
&Se@pJVMh"8`j'R[AbrKrVe#m[&-BIKpZ2FGi,-)U1Ur(1h@Q6h&mi3[e5[XC#4k
d#`pd-Z#MZZG6(%1!HZ96(%-!(K3@3i"q4Q%f"+J2NL0f0d*BmXkYLAT99S*53,j
Z8C!!)D1(`"cA'4L'""@#m8X0a--'5E(@dpq#1)+leEa50$3$NK(K(rhrTb(jEeG
A,X8X$'f[Kh8dRVjPmQmqFI#Ykbl)mh65%YbZeQ60G$8diF%IlF,!`%C82+aJiXG
Gp!-[E*qfhhfUhaJ!4916'X'$5mB1%P!Cji"*d0[LbDUQAYRI,(m)PMk8c"Id4Ab
5hpIq,mGQ!+"i8d4@!VkJ&2Q[BE6aLe('02%$k[)MY!0K)KS'FE,U[6NFpN`jNB6
qdla0qPDF[HcA@NJM[qaPF"$XZ![k-RY4B#DZba-i2"p&QhefIKp+i+ph3l"L,MF
I(qKfd0JPF[+FeE2Rj)PjXm[Ub[$TRZZXbc0D+3'VGJ8P&RqiVFIZY4fp'EXGM'0
p))6RmiRif,##5`MMB9*YAFe%c,MK4(jc$arUFlGKIJcSaPd1B8N23MiqCa+@mR[
dk3"m8cEF"@60FD8-1DF$hYaLN`PVh!TiVBAG3GM)l`-H8Q0mYF6r'La"l1Z%YGm
*1"&J4`JVAJ9i-FA%FpLq"ep$E!9K`@ai$$%qT`ZBB!XD[1f%M5k!T`!Q2N5BHJ6
`RiRGK*9e`@k!5Ic59R-c2)mBRqf@[`L(%2X-BER$i3h%D2%+4MBae$T[,''Z()B
A!I2Q%rET@aKHDFRMbaS6[XY`F@%+hqLGEQ+h)-D[`FamKZ'QbK5Z@F&X9JX`PDl
+32dVl%k!DAa$fJQX&5#IApMll$km!`Ij[)CJ1efJX[-F0h33aJi3PZP@3SYN6d6
%@P9pSD!eKVYmULH$E`2&Gdc5D9r-'@U4Ej@$DIflBr`h2@fQ[J%C5aR$'b3Pk!Z
fUTBj,Ej)5$&AK))4+jq6kSNcBVcR,)dSNTVTE&-MSB"iQlcXRT!!dU*Dbc`H'GG
Gh&,%UeVU*+99MPM,fhcq&MeKkR`RRNL5)fhKG0SceeA+)Qbf6mA*VaaS4Mh5qTI
3HCiBHfep+UDD$XG&FeDi-&NkRC5*%52X*,(qHc2*"1%b(mqR%l4UC`e3[k$XYq)
X2Xler`#3!`V!hGVlRB5GMFL%NPm**i``3MYb$%p@`JNP6mNcFQ`p`RiPE#@h(Q&
iTNH15BEiC(KfUicJUFr`(hP'+$P'eL2(b$(*-r+-c"Pj4Tk4BdH1ND-HQ9%bBi5
5#5-64KJj4JD-$"Jj4SiG1IEN'"NbmSa-+2$ea9E#EL8$YK*'f"(k!K"'RK(N8-)
!#("!!%#@!(DMi3%!`cN(%%rJ2)DDLA-#jc1mCB$$I+*LHq@DihRXbfem*`pApeM
r"A!Zr@E3,eedUllPhhb0jk[$m#Lrj*)60&Uql36TiqQcM5X1KC*L`1jrq[$$,e@
kV2"F*pMPSlNRJGr%3lc3l[ceBlPCJ!Xc3RU*-h(M(NZ%mZerDaRiI("YYZbZ0$d
R6D[$%X'E%d1%-hKbTPP%plDFN!!&@(lk+mZp!`iMFU9PH)%pL*fQ`PJm!($UVGa
r[JR6N!!A68*2j9S)*4RDAX8*3X-H8dBYmTf#5BU8SVKB[Ei,-UdT5TEp*iliL%)
PZPp5j*V03YhG"U%'&45apmJ3YD@LS)CF0$*'821U1hZ4r*C&[fXPaD&q&TjV@k(
EU"[qL!+EIC!!4C5-SYL(rNZYHZLZ1!Dff1mX*VFTX!-9a!i$`042#R&,&HUKieq
eE%d4EH8SLhM*#QYMJ!%ddQ6&CQRkp8[2Xk`6K+dU+F#PUkBGZXEN&ZYQl2(rhl&
1jIabK44-@'5XfkI(&qc)GF''5CQ3!0l`pBmEYeLlC"EcT-#8fSEa4U2A"QY6Jj'
#V5N5dLhEIGaj`YU8%#RB6-*90eRh4H'9FN8&@e&XVQl4AZ`1ZY*V8["h)(-GrbD
kMdiH8DbNV"l&MaV(rZ@ECM%3RcDfH[JZeL'f+Tmcmei`+*4cG$(,cV@YVIiMr&[
cHAT$VI82!!!0$3T8Bfa6D'9XE#kjBf`ZZA"bEfTPBh4c!*!*k0X!N!m",pJ!!8X
m!!![#rq3"%e08&*$9dP&!3#Y,$I#X!1P*J!!-Tm!!!I`!!!+F3!!!X8d$l-C!*!
'Jc!0`08PmeZChjX0mK+rfFQeb9k6f4&fNT8``[9DQ8@lU*Zkk5$EaSVGQZ%jpGL
Yq4Yre56h56[#pV20)SaXZNhhX8[*2PCNNq0(EM1bTH3f)lGCHH3TB@36(YYNXbk
ffCD`,H'ac3M[f$jMQffff@mMccr#)a6imGI9*2ITEIfeDfdI+hD%4@iViC(EE*-
YHAjiXS%*AL!mX0IC!`J!+&`!i-#[aGhC#GE&6q-[!,mRE%N'3Cdc',X0),2'(kS
1++'3!12aJ)4rHReUV(T1cBFi)mGIrMJGlB2,*qY)dGI!LNr-Y,S6hi2d[`VXa$8
8Bk`IBaX)Da'-G4$fUTHaJjc349M6#-BqaGJ-cTh1@!0M'BbYi"aKaVDaVMr$K`3
fI'@#P5V"L(`ZLlq($54-C%'N&9rrc*N-#9PNQJ#`S#!YjY)VcHH)0(-er5e+k%'
&5!rMA5YD4BCdlkNm$NJr`He+f-pNFS*0!&DI%CfGJS+J@r8RaHE0!$1`iFcSj&p
)``bE*a,fq50*VZN`&M,&6UNPmIjV3@"p%4+$0+k,PF'S58#YQCM%AA1mmYc5HDA
dcIBS-6@b6&'AD2*Fhe+IA$fU5KiRR1f2#ZFp*E@9FP9j!2,PDRV0,"Jj(F4((XI
Q[MYRj&aSP'XVN8iZ&Z&piKGLRf8XSTCE0Z&V+(k(83HPZJHiMl[$b9HII1a(bc'
$&Hi')9a6mSAcJIe#rG*a'2ELIZkA@0T#hCJ$JalUJ1&22"RSI,P%U!mLVi2VB0#
f0Xbh!h%Rj$9[&qVQEh!28$IQ*6U$qZ"ZqTrb31j[5C8-a%Z)6qHcAfL$Pm4#9N0
kl$NM2rB2l&qlIKI#2!%MIfXj5&E)rI81C%'F@PQ2h0pX&`()V0d0D`Mr3BY3iqf
fmqP[(K$MImKG&I14Xl%,jc-9`VN(YAKQN5JFi!3Bq@9$,aNb*TD)Sb!bA)e+@&'
$IYGHFMF@RlC%a[I`K*j(Dr,%d9SVIK2r!$`m#V*H-DRS-TdBKJdjS9rENk4IA%-
GEhX@[l[%!K"TVLDIhe@p@a4YLF,!J3X5ID#SV48'V$N1)mBIi6j3Y+8&"ZDN3pl
hAi0MeBmLhJi$YUd943rR-kqL0Ui[!k[Jrc%2j282F"mSfY*"I-lf!6er9amSfR*
)cpq@`hdJVpmkC%'FFPL2[1bee!GqY!V@%rjMr20N(i$$HpFC'P!Kf1(SDqP`I0m
812lF9MJfY"dY+ITcrRmVC%!(5Ld0GRPmrXTUZESj'SfS-9HjiQY39-f9V$@aXmC
l"Pm%r6DhRNVb1RikAm*CLCfe%a(AF`hBX![akBK[jIb-,ma([*e`XAE)*V(K$jX
3la$hMilLQr*4rZ0krXmI3R`9ijcrrPmCq4-i8FBFV)q),LUQ'KKkTJBUJ[@U6`d
Ub5S`'DN"l)AT,RqN+HU,ZFaFHU%Bi(*j)USb1aK50(Q5BiTMXXYNT3m!$(N+E$P
k-r4khA*&-,a%)DYj+Y*k-k4L@+RA@r'"ieZ%hp*S0'31`-2MUCLCbT1&YN#Hdd3
1JD3rPm2MVCKY%X#McMh,(%$AUZUUm`6Ii9&60Vr'iUJ2q$A0#H,9Y@#[iTNS4hS
jMNQ`aFldK8+45&JZ9d,aNCK8Z*)KmI-ml,Jk$mRKlqCVpp6*lN,hK!NAUN2RBAA
i*d``"H"KFILl"AQE4rFNm'eGSdNLehNSbk1&+d[dHRhX"A*[@)mPN!$l2**BX3f
UP*8m-dfrJfXCrpe$p5S9VT,&NAhXT24k*H2f2ceb%Mak"UApN!#(ekIjID',`ZU
k4RfD@3!2Ie,CP+jNfiL(MAKFkN6AH%L1(KpPSAUp($S2VEY2fe#'8Uf*qh6mepI
lp(ahCDq2bD%NXhZF6%2%hjcLN3Vb(kUQpTL'Ucbd3+JqP5I,@hCC9H34DcB*i%&
KG@#9[+FVM4m-4ckeq%lc&NH1dTr,FF14Aq"K'Z$)+fI1T6PlMaiHEee+$l-2Crq
QUMHFI3q2kmkqPmG9CpqVke9RRq*afGP6'-jH(2bTd`c!fCrAipr1rS+`lcMl&)q
Vc[imMAHGI3q2P,1h)Bq8ZGGeeC6'pq[Hr-146beHFLl($8Iq*Jm+N`"(AKF-6bk
5PaG2[HR)-rlPU*!!D(IRZ1DSHRKFGd+pHPae3LNHecVpH4l[G[SH(KC(6eG-4al
B'(UYZp84#LEEfFQ*aF8+)4k4qX9*(TAeLe-m-McrAI0)L1jaPpr-IEEL8ada(GA
L5Vh-!cY3+1Neqa12N!"2df3hlNAK4Y!CpH-9Mej"ZFF830F22%HA&qrap0GiT$T
VUXkk1Q)X@@C[49pH&Ak["fAaG22`Y`kJ'li`jASMZUCFSpS6dde6!"lZN!#Q!AB
Jl#mAH24"Vm$#AjV6me65&%!2RLDD![#)6a162+j0%p-FJ9K6U+*9jr(C2CLPMc3
ImEa21UAqGqq"`p+d5Dp8G%Mb[KF`j4$XA5rLrah5Y,&VTIkVFHXjcQ-a9Y&&2Dl
8Q6(&#8B[e5[YCk4id#imd-Q!pqZHTcLQ!2A+8aa6!"i80P1!INCK03@S$j)MIMG
#@RVPeN5YTUKKAj0bdk)J3d%25A4[6TZK""@#q8X0*#)2dZ+YTkX&-B+le9`T1TS
&I4$KMr(r8p$R(eGA,XF-$(f[4l6-2h[,j$pm%Z!Eeef3!1ICT-@iADh,QZfT@iL
AIr3,!mQ0U%6B`F,(AB`$,q*jIErl6,ma!BU&#l8B(P`bGj!!J-Si&bb5d4C296A
ebUjQq6f`l63&89cNmF8SFjVi,RAjIZJ8C$i5*KFlR2@6aTe*XLbS"A4[daF[j9J
1k5eN2Prf-MXSh"-Zk)[LPj+`X$6IaZ(jB0VXFr"p+)PIEi9NaeaH(KmBGY$F*A)
,h*@cbJVNJPQP0DAip-jaea5BVC5!AEq#%Sr6YrA%[B0AI4Ll(3`A1d'+cZ1*q,#
SLNX)Ym+BkTUUdCMaSC2jVHdme'HhBAd%k-CG,Q&Tkf%L2UF6P[jRp1N![#NEE3@
bjVK5K[qe!YlF%R4T#qSP`'XYiLl#bVi1H%K0m'V*lDYK+@*I*@ckB-#*J(L*-28
@`!XX&XkamQ2`&F6@%&Eb'AJ%XDf%6IS*E%H$YiX`*2N%`1J('2X1i$qMf`JEXJ2
f!ScK5eZC)q!!BMcE(I-b(-2AlDc(2[J6BRb**AZp3+d,KM(A-3)[!KE-)qbMIa4
iBDD!Pc8qFC[!aB9a[0'lE+LBKKKIJaRDAq#QbMM@l0-E46A!H,SU!pTqmA'!#E`
KAEKD0!*-j!Yldcq(Gq"J)YF3l+),9!l1F8X,BH))kq&9)iX9Idc'@Y@#NE!pMRZ
#QMq,Yi%51bCpD9r-(@P3lP$#Q9flBrbEN6EEf)#-TicMG6ie(!`hDVDbKQ!XSPT
R4m)a1mp*MF4CFGjPbf1U6mYf0fZa5*0mTl*L@84Yd1bPIVq#kbjHAbbJf@TmDU-
5XmpX$SBDM)3Cmpai)NQ*08IldTkjS9)1BE1#'NjqPDCke#1cD`QGmm6CkqY6FG8
-1#'DHlB(Nr@PNc*aBS5G)YCeEkB23EM-arN-JREpV!(U&eC#GTc&*lMq(`V!GFa
@'a!fm$TbM$`M[a*'RT'9(6QfNT8`3JNP+hP'MUe(f+rN9X,@BiGRkj0MNZ&k-J"
fUq`!U-p@,r+-d1[)HZ3B15BC-3ND+"Qa)mI)8Br-+*NamS`m)a0''$P'"S`-'$P
'MKdj4KLC-I+-($XbSF#(ppDV@pR+b'!PM$"b9,C+f"%88F)!#("!1FQUe`8!-*a
(!3,hFDiMCZ,FJr-jrK+J35aBXN5d@19#I%81p66ee`FES'Q5,dam1E[5,$I[[-'
hc6"kLLq5[kVSE1lmijXVF+IHDPSmHMbkN!#m&6eA[mEK)$Q*rX`1q@MZFX$(3Z`
K#fN#j`V1Zbb-@"Ja`hNU5GJDI*jGK4!F3M$0AZ''FAZ0'DjF2lDDS2d$4AZT)AL
8SS2FEdq-V$q,,ffD1@4[b`NTJ%@PF9H$adLj`K*DPUhVCkJ`NTL(8qpNrR8$`T!
!mCU%9Q8d2'5rDiPmf8Sh'YQDlFDYhbUTEqL093444BNl1r`rZQLX)L+pq#YNCUb
#EDXJ#CFV0rqS#2G9k"p33lmYP4I8N!$*H#,Z9%9PiQKSU',3Y9*1*&YcHI0kfH,
BRT--re,Kl3AbCEFk&6"Xr,'+ICMa3U[QfNXm2K%6f&'"Pi!5-6A%'+VSYiG5mEe
,B`[*LcqlG2$f$T-q8M%hk#jK@fAAVYILcE'+B$pP+Fp02j8E9ekN@-Ga@a9#3*1
XIJT(V,T-MYq-2HhdHpBTA9JX%B)1HallVGc6jUdqklb&IHLaq[hCIGaj`YV%5JK
QbqX,2iXpIINCDp0P3`J%C"Vm0YRiZ(Q2YI0Q,N-)'#TjdrC!VNh@TXiP"(2VqHV
R[2XbqeVjLJJfXZHVhq!pr3'bdMBKH!e)KkEA3rI4bF0++b(,4ljJ'f%lkBDCFlb
$NDem`MYbjK,Z&Fb-F,l9mhRkQ%9qBfYVX)4h[4DM(ES"rJ-0!!j9F'4KG'8J0MK
V)&4ME("bEfTPBh4c!*!*I`B!N!m"2CB!!9A4!!![#rq3"%&38%aKF'ad)3#Y,$L
SVkM%6J!!%4!!N!B+*3#3"1iL!*!),Vm-`2MVQ#GEcq[CbjrbTd8"k(946[[dqF3
S0mV91Tr62N*rUedQfB6rbMa,QABH@8pDjbDFE,CZRh$#R`ciN5hC%NifqDfh#Ip
Sj&Q%4fi6hNYZNeZh(GR(HRUFmM2G6KaBEjHAH5XIC*6r@X#'[lj00b2l*-I*E3Q
2(#Hc6G#cm34!"jdGRNJMSX#G4(kmfMhki1-2%c%6'3rTJdrm5M"&aL2!dU3aqcF
RqX*@4+eU(&3p[E&'(HVGiD5eDAe2&D"rSepqMjr9FDQ$,!Jqm6!p)&iAV)5rdAF
b0[DZ2[M,PaNId8)#laH8YM%rX2ZSiYE&dk(3E@3dhN683D5ZqmhdpcFb(lcr%D,
'#(NfmX`"8!NF)kh4eXBUkVl9ihVdpK1FZrfh2(hl2[kN-dhU9Srqk2dR)(41k$q
YNZm@Zr+F*MRG)HRM8X&9R0alEj4UAqhH*CdMkhVL+MNbV+b"D%UPHT24K+A#L83
XfKZfS[(K#pAZq)JD'NPCUMqD4"8G6PRK@%be3#1bbGDVJqQ+pR#UEh2,*R94h88
0m[VKe4f!GiedFQ%FL8aJfQ#q,fkGh'$1Sa)6KEl6*XhM8e6U3h&Q!mdIfQf&NcX
L9NUJ(JFbUC5d$Bi"mZKSYNlcb@ZLd)CXQNBqJhbdL-a9M4XIZ5Dk24P1lUll0A6
`H2%D2'15iFK*Ed`$M6Q$!L+h+6U%VL)XmS)m)kSPH2d8-&(S-H&KUR,mKFBj11!
[4#+!0dJ,6"4f+d[)`jr63Kq+LJBb-$**+j'-licd@RQdfd&0")IGLK)UjFpFr"P
T1Lf!Qd98CU+`hF`R(dr6'9)XE+$5@(4lIc3@XB&f!0)qf`-QJFidk%`Bm+dGLFE
ke'BV'NXj[5r$HaD9QbM34BP5iVr6f4S+M-2Cp"hDU$B2pmD(KL,$&Z)JSQ*Kc,Y
eFec&SX14P,,L$L[Z*)1+ppXiTNAeaf0pND5+pYYTFA0if()mPq-pKmie843pIdS
9'JTiVU!VkE)j8E(iVbb+#K`TS*'qU"92eMRZcX@lQ-ic846GrBdU044`9dNYG+A
#d#8L5@Xh@T6XME4'NfUeUPkI'KJ+4f+V@b1l)V&i3KUq1MqGUG8@9S@kKYA9MXI
cm#UU-P%82Aj#e4S+H+bQ@UT@UBL&%E&(86TBG&T6B$P@U[!ZSD8QLQ+-I-`IDIb
aa-K()V%8lrP8Bk,3Sq!E#*B,U0C%i9UIPrb3!,2mJCFrT2+kF'5A&8GB$ir%BN4
TX1qMjIJdcNTiI5#4@eZ)h(TDTY-bQ&K1+d`8HY+QqHP#@QQL3%rQfCEVq(f6kJU
'$IiVeI0lAT6PGDRGUAJX(Zi6Ni8&)ab,)TEV5AG@*3rrK4Um+0aH#5Q6'NL,JkF
MhplemEYI*CM1lmN-[#m0@qRS5D[ImI%l0,q"jShB-3B2+r"H4"HE+23ZM'-!FhN
*A@ULX2Zj#'0r'Ddb8D"rJLrQ2p2Pr,B2T56aGSR&`PlKS2R93UI,BDk4hc+Td@P
"'Ch0*hemmZYY41HhC-lHPVDYQQhEQcjqNi)09*+-@,[#-E[H%SkC@-*XM3!&q3d
I[h'kY4IM[B*I0qN+FQq$5K9QDM9Gb5GibJ5JVd(i9#%KQZJU%iAYT)UUqEL2Mhr
PpLTR+DLQ*Ac-aFG)-j'hVQY"ZB"@m&&D`dHm+"%M#0G)-UPQTpU*%C2@1"D@)5k
D$@V'PV$)f5Z3!2f5qqeK$'qIXbSGN3*,UXC6JV`Z2Dh"'k)@%d8amPlM9c9q6A4
H&BN@['[j&C2@cNUmc#pTr,*)[#4@AT'8!M-3*"H9m*pS(EAb*0DF0JdJ9Ujej1E
$r#)IiKGmI2MVFIAaLppZBciqp&8qHIQ&Eq,@6kfNZrPjDRHKd2h8,YhbNHP#Pc3
rY9&TN!!RU*DIih'kQMTic![i[r(pR,4pA&TlY43Gk2Ucr!`rc3IjMp6Xj@IckHV
PClj*C4mr24Fa2MliE36ki1l,*&R!Bp5`I'UlE-[e1l%jYahUHQSKqCF,J`CAN!#
VlI$QVYm2DSYTrV+G*mqiRP`$!C*3!Grmr0La!h*lb"pMC*H6J``'5aCc&4lZXj-
N04#4)F"3fcX@"Yk,aXXk8[MXD-"'59KTR%mZ(BSHENBBlXI#3pJK51[F`Y2eVPe
8lfTSfRIJCqdeP5XlK0(302U3!+#UMUGrRYQKkPfUU6FaE,@mclRUMRd(UZqUUG`
3k[GXH)ac1r4G@Y"98iIVb`fG)jeEX$`CeppEhp6CeE-HEY1MPE8h+U2INh!edrk
$0pA@'rYrU(U8jrP4+Um+8ANHU`"@XIRHqM*eipiEeU4lZQU(16IVU20*lYP!1jD
,Xh!LCY8hTAS69U*UG,Qifl%32+1q5AUDS0(PqcrCfJ9&Uq!"[!T4&AllY@hYpN5
NekrVA')M$`K2J0+@lZjVmTF4Qk%MD0bi)pfLL1i)iYb!'iVZ*MF1-Kk24X%b5UY
U#S9D5'A6kH$G&2,F5FTp"bNp4%&089!28Y$YSD$(65U)J&FDT82k$bMY[NdM6bY
mG1!iXp9$lMiNpP2`UFRG#Vl&[`YeDBCS$pB%l+NDMKSZA&*+FI@4Fe%PFlUC1E1
(H3URUbcHDE`j[+I!BA"235-(VHP5m&h3`A8TJcS0("l%4`l[0*@qR5AAlq"6Jem
lB*d3XAH`dep@!Q6f#ra6)#$lp$m%XQ2(ja`%b"LE%mM5f$M!JS$3S9F8b0-,!ME
GjMX#3Tmj@K5`k8FG!b,!$2U460("U5-jd!fM)$!c0J&kTLL3!"X,M)01"NjC)K#
Jc"MSj!JD%j3em"%j$Y&(#!MGjS-15D&RE,kd@34!(mIabkEEA3&p,%qh@`Ek@)&
1-eQKCiVdSlR6p#-6Fh6Ti"aG1RJm0dZR3'BL'aJVdTd6F+j)ci[-dJY69ra#@YS
I@U#UJQXp*pd2hRCI5kK+93GEbqmk2eLM&SFSVD8$QFUTjZbHDH61+HBph(bU-PF
jhCaYRPUFXB0%hS$ML6&6JKS"ff3f-b&c'6!-1a-i1f'(aFca'6XNCJ*(T(8"'62
-U$eriePS"6##N!#'Ur'F5-p-f$$P*Q`B)96XDEkAMFlje6l&jXqeT[Qr23[RkZ)
mD$JqPLbk'iKhka5jN!$AmXVpidI8U*r35qcDTIqN)$GhKGFQ@dFVCGZSd1kKB+S
hp6eJpmLQ*&Z)E$5SIpV6YV8(`SqPV0hLrJqT4'S!pD&eADeYi"eEfpNU5mURcND
MkFj'SrQGI8Bl*pSE`hP*UiRfTJ5r',AJD`Ekqh$fd6CX@VqY$I@@klVMf(5el8i
S!*RFeL-hq@kLmi!e1[GjqV%fHFf$lJ("2%pUNqe0Lqi@c1q(4PQHplSf'FD8feJ
12'bHmRr"I"hBGqArJM+D,jk8imNVfMMQfeJG2#Ab[%[JpARRh`(['Qfb,HGJ[VA
3f1YJCMZ`MMb'LGUfe2Qr`,m"@+ec`III"1a#aj0r@*YFGrMr$3!49A"NBA4P)'&
XE#"8Bf`i,M"UC@0dF`#3#3i-!*!2!8Xm!!')DJ!!,`[rN!4"8&"-BA"XG#%!V5`
iU,!DCEd!!&q3!!#3"M)T!*!%Sb-!N!JD3Jl!MkIji5m!qJecY,,23BkX0`IC1E+
F@3jbe0R+r-lVc1IdqfcLp6DaL8eciR9HFd1#fG61FQjqCcQe3Ckp"h"!!,Pq$FU
qiqGQhF+lML`GQ8(bN!#-)"NY"1)*`*PfGKkHL)RSN!"8SS0amX*SV+#b)1Z)dT+
#D$k1SPKakE4C"G4Up)+QZR!"FBdaCIQabS*SV,Ji1MU[Z&[(E#'K2L0'$)f9&9F
ffaicq!"ZqpG[qBhYZehMBT-AE4NrqY#8rGX35HrM+,YEM,S0T-+Rj[HKf[-HqHV
`)@E,V$BH8CrMU2CmTQj(HG5lpl'8[ZmkSRR[rR!ihScVeSa'(*AZAAAmHV2jq)I
0TZ(c+AT8ZPbeL#Rph'CQaAb28VSY*J*'Kb128JC5D[9$%6qUS1(KZ0U6+(e(RH+
efa[RlMBH,D@8aC2YE8QEa5f'cqShZM4D2UXN@PPB9"'Yb#X[+UZ-aXV+LS[bBT9
&T5AYSh0,Cd9RcUUSM%iY+XHYU+5Ld[C-(q3S'"AQk`KB$AVrT8'fI8fh0P[T9'!
YX$dA,5X[R9k3!&GCB3(8$IZA+)0mbX)pNN`ZiDdq6P[l4)QMY,4A6q*V0b,f#8i
HIT!!fG6*QdfG[1bH5fkmHN#VTKd'fKIC2Dqjh%DM(FfQj5ZQ46YjdCjjC5@9I6i
cQjX2A(*Mmj0E04hFHfVki*[-jQNbQl1m9Kh0em-2'6jVq%&%R5,Mcqc8FhMZk%&
!1rqDTQdQ4b06dmZmAR6YNiHfk45jpZcSk'MkmpG3r@DpUAimeJLa4Q21l&3l1RR
a)I[2(jhETX4XVN)dr&icHM"0DfZ4@B,Te,-LVkbbV0NeE5fkD6Aa,Y+TTkeT'9h
6pYU[aq8LBf8#!pieXPRYq`%MF`D%(6&r8,rK,F,)qIDG$D4CrJUI)'aIb(bL&,6
Ti9'L"9R%NNiL+C55)T5HcT49QqC(Qi1BqP"dircj@DG3lr36+CUbJ+,5Ql)i5PQ
549NTkC59RN,4,+(H8DEj[H9BQTpb(&LU2h!-6+(dFHQ8NTp&hNVJC%X,`'haHlL
RV3$MJIA-4Q+cL6bcQG+-TNa`9&0Mj[FbCX8mBpD"XcELh)4c-dk00`C[0A*X4Uj
0DAM[)3mM(qlc%3F'Lf-ccNf8p[j'mKi"6JCHLcp1)[JbIk5QMCC!UVl-l3Nb85I
DQQ$MUVAE%'45C0@f""YTeE-)*K,BjmLA6""rRNJ32JrIZ`6fqCBeb36Kmc81J%e
J$*krY5+*3,qe'FmMN85#,DY@irQ+C),0Uc+IaA1+E(%*-QR&+M`RPc#bQMC'm"%
jK+JM%YMRiAXm4dVlI%AihTEC*X$cCcI(RiG9`I09mHGKbI"m9H)jEGPSRkp)2Pq
cHFIcYeC[HfiVZ1fjVH$Dc9A2+A2&kSfCUj,2E8[B*$mfF0Ac40FP[pim2k0hM@L
cV,lTlk9FH0bL2VfE4CYRpDprFXZX9Y('[@NqcmpFdA4GVihc0S&hY$(c6#rGG(2
66EdfpPVAH%9)*2E-G*J-HXT')jNKb)dV9YZqc)a%3Ni`'eH(C,&PlCD3!#5fC,j
P5jGTf``p'[EIXaZ4+a-YL04!pHaQQhV,kM"-QeH(BC!!8,+Qm9VZjHDZF!D,cfP
+rHH)9E1+"8()UC4Dka4%r((Vb!09fj1S0Kh1IH4N,a,H@hYAZh3(A68J9T%rTXq
SD1H1RE2YQB&A+CDh'DJm%$'43SaRa!&LUNM"bfU8UR#4kH%M(abG&Z"50jZUcja
E'5ZI9P"CB81MA8K4'[(J-&Ge5XG!!3M9b9Him-aiiB))"95,e$lGKL`E@M5P2&B
qYq-pYV5#d9%`1#U&La6ER)KRQ#d+8f@BhXBc)qJiT#mVbpZ4RJfB8P"&`3"D3q%
5BN"eUDECV0!q)3BEVa8"JMU8D8X`UQJQ*Q(d@J)&q&'S"XlD9%IK%U,!p%jec3r
+cVN@KBhALe!pLm*@iLF82eJ8GA$@Tpd8,L'+&,45!r1pSJB1KBdhM&"$S-b`+*!
!Ie3KLTS!mEd&X4[14Y4Bi4+#3%Y5%r1GSLB1K)dhM9"6&0`2!438*k[`R3A3''I
8E&+BZ8-!U@M5CZCE4FdF!"Y[(U(QYJS9KAmYjEF!JD%-`95F,@KhK3Z3!)4XC,i
aIfEcMFhcCjYLGj`YUCA#*550J*6jQPS(Z$6+TJL@$q@9F9+,4dHiU+,@VK`"4Fa
AR[N+%bke!TSfY)I#*85639RQ5fSEi&)cQp++LkC-,5SZ#!-$%&$8eQ()!%HdLe!
lp((3GeC4FAjd6'94FB9MQ6e`YUF1#KG8-4bfc4I8NA%"mA5N!fP)G%a*AZR-Q38
PP5%6&mH`1DQF8aSY,LSTU)K@PVTATBklYr(ee0,Lr),bD0(8F1mb*eC5k6"h`0Q
*XK8Z5F`EU62E!69#R@PIkV)YUBAiPke1N3dA*+)&q8@9TH8G(ETXR([5AJUA*,V
2D@r'"HMfTMkdVjdNbJV++qHL419j"If,bU-pSXd(9461M"88pqKI-,ZJZ,6-&Va
(BZ6S84QZeASdGaMh`YQ&pP'i*$&q4PdC&f$XLJjY(UdSU%5,K+eS+jK%fLVabN(
C"fFhkUj`5G,)TqB60TpD'X%f5+JlcKkdVm*&L[#q"XLT*qfRF2%'a90qE$ib(rV
QBkVI-9B`Zl)8Dkq5@FA&EXCE4'haXIR)NYH(GVMC,c(FG+,pKIB(L&l8@q%LjI(
094rUUh""6DU&'kaqjJ0&r4+!)qCpkQrqj10D[f2&h)V5iY*B[J@CQ-PLa88BJ2U
6f'8GYPcQ2FVaF8Ra,8NTbL%Z$3H3!$5c)6!ErSh"a2c*pX!(YQ"pA6jEkRF$mbj
9ckCUXd)D!iEH1!I3!3SAb88lCS,G"p)JK8YBceSB#!E6%)8,kQIMMFdl005X$h#
e6$c&dQ*LJR24q"!R0"6JKTPeLSDj%Y5QhFcD`+cG1IH*`E*'c(TEYL&9CAXl-'p
69MDPPKG8cSi9KrH$BX@+"VNFQD$c0B&CXk1d"q!FEYj50*a5*L",-h4X,Sd`EjS
h&!+b2mLR'3D0!fQN`L9%dSbDQpF$mrUrS4hTKS,Qe-+mjTRAL"@0)'mNRV5QGZC
9'Q9HmA%&MB"F#mV,Se9Gl@K%d5J(B3m-'+-M0"T$@5dh9i$l,Hm2L+&jmd0k-kr
BbjZfMGq`NEGX6II&1FDmV'K-&H@pC&jNmj,0mk,0ml+P),c-a1i0NrB,G"#00Ar
%$$11aT[Rc@Vc(1-4TVb$3#h2QPAQ'I1dHFSmDCi`M`IQfCfp'CK9[ipHJARQhmM
)0dr[iYE!2,@YE`2cj0qDMmd6YX#2fpU1*8NaMp%%$jHd$*U!X42$RKhQkf%%ENV
02C5E-e$[Y#cc+1eR(M%VD5*0-Jrl#2p+mSrBrPPTHf1L[8bL9,2#2'3H0!qBqfQ
dEeE%1GJh$qhLlX!mZ+1J$ra1P!(3rEAN0Fc$P0efh45lVHJd28+Fmd,ZbTU8dGD
qS"RYb-YjD8cZSc1i-9AIBrTlGFD69jLC3H2Y1ZBq1KJ8F!JM!#BpZ'SG-ePS-Pi
H5M'&5cJ5f5A%&-T6Z)3-EbRPAXShp`5i0XNQ05[F+#8k2VjJLVHmN!!PU`*cYk+
#+Vkq+c"h8HeX5LmXR9P3&UXXG*%4L)LjfcEC2EBZHBQk&0*8SDN!-Sd+&5la5FU
M)TUZF%RXI-bGRVR6dZld+Uah"1D1N!#cd$@cbNYX!m9$k#%"0+%C"2+HBHFEZbS
TS*P8SR$a$J`e"2P85Q9dQ-*9l$Bp`%K36TM!bPejl*B#GEB$q#bDVA!*"cP&pFc
Y0-IFjZ-D*jAmdV`U8XQ+$h*ch##RU*DjP3lhF8RahF[$hBLBLCA5A,0Fd9b5[(#
DU8P(d*%+Pq4dFdYJE[QjSa3Gk4S%fbTcXfpZ"VkmbX-Vf5bhRADE(4YQicb+MPD
iK-@VMbRZ*R1MZF%h0k&i`iD0'$NX0U-JTlam'0DM@+M1*eY)0MGD#$GB#%IM2-C
FVqJB"k%*TU$Vc,AQ'YpF&iI3VlKLK+ZrhFNQ)&aV)8!K)qCkf`899GZCUp2-e@K
)RVa)S32$3FTQ[SVQQ@8qVVm18[1U''"TB*D'r)P--bZQKIGK&G2%,,0i$h0Gh"j
p2Pr3Q%,(dR%+Pl#+l6(+ANR(d`)I9dITq9!)a5TQ1!V#jr!H6c)PK,%[R8!R+Pc
LmHjd%TfXF)R(Zp)TY&$K%SphS92T0)9,2,iAR8jR+&cLmFjd*U(qCbELRHJX1P[
K%VB*pNYd6S61XI["dGMDK'1$(4BKdF#-TqKXe`FGU+1j)M"Al15)43i2GNGdES6
1aHD`G[0SHDbSSL!rA!HKCdV,Hf#cCd'Gi8"eTMh0%YmX!D'!8D1+6R2[pU+pcH,
!,2jEdbPDk(*Ja@-ZpmhPbG`RZhGGUCZjc$HA*GqGk*D*hE'K1FpFUZJm9bJE2cm
#'F[Ze'48BHNX9(e30+q`)'p'@@P4I*d@0J2f,RBbZ06Z(aG!5A)*A8!AqVLQq&-
U5m#b&lK0FNr`fN9#&b(G(qKLK8Z)%mXJZL4#PpMGl2L#q'E[BTbA'L5je#AC$fZ
Hbb*dQGe$$mHBB-RXBJ[i3J$q!eeZ,[*a6I(cTaCMrhLj5pS2+jA&%9Um&9QUZFM
#1`lR%R1K)R5@A8`-!cGG39HD#fLT3N$f`q3c$12V-VT+i5,&Q2H'B9P`Y6PIdG8
N*@(1dA30ADY`iFk)Mk$4jMcIR'I,APL%+PbEb$Z#VM2R+VV1j8(FR11EFfcr944
M5$MAGJr83SUZFR8EM3(lqJKG[l9ZLUjd-pP%1S4ZS"X9,Q%Z1e@IlCQcEBSEUaM
jV-#FpBqC$(9'ZU8183be[iPZ9VL%L')da5cbc#*M&0eFKHM-`*bj#p'&&P&*e6,
mPNbk4CUN*iB4iV9f)[XI!EjqB`IPf#fL(H"#B#YXIpKpHDI4-k*BFrk8mHE"`B#
qrHdQ-2@@1[e+m`['aXV,LdV,Si2kjd"&dE@Mfr,plbreLjXq$P+YT-Y@)LlUUr9
MNVV$#LV,5qF8P-qSL'j&M,8"&(1TYq"FL+VeV5TDMkU%@d2EF[IipmT9"reF%jY
DjZCc$h0PGb`JCS(%,iZ-+)a9&%6hM%k!p[,[TF`BA$5cG89dK!8l,'B(hahIVdh
P)hGd8-Qd`TK$rYqY3hl(8Idk$FSGPR0!(pXh3RD$YYaJ'PY1E$9b8l%ZZ&A4VBj
hTY)dFhTJ6Yr&1fGB&$'FYp(Y#TIN6ZidFbUEdbbeRQT6h)lc$VT6i4,ZA&+`XlU
,X$5jUfVRXY#FBNi1c-*`@@6A3Z'#2VqS2)`kU3q@i'+JeK&cXQ@mZa-,P+CdMj!
!P9RF5rFTA+!BG0rp3[FMfdRQa-#F&!k(i6,GSR+4%0'*YNEhiAb!(P5i*"Ic*p"
$M!Yff!pKBcSS1L#H-JSj35aD'-ZE%Df`)SCBCA4@48&jKC-`i$%fIeC4%mf,PEM
eI6L`!6Cf4UAP@(4Ba!rLA%%2+eb5L"I35XB&L&GLJG[(V[qR3+b!14Di5UC&5i'
Mh#,HVQ,BUP3&T54KGZ`B&cBmM2-4HP6K%Qjpl,,N-AVF(+p`$A[)3dFq)I3%%Me
*6bPFf,+@eHFmVHKTa`L)QZ-#!pRY[cF52BAdcjKM&6hM#+8D8+e5Y-UPKm,'c!q
`'2QP$iqe6Ieie5CNRMR'(1fEHEXf)@b1XA4`Y+@DiffT(mAjV$P+dE0Zi98$j2!
FV9DiK!0A(@aZRUFr+Pc#l9-Gk)&H-0Jf[H!'4KYrd4bKk%8hD0Vi5i50mdYZ['T
!MFaFhm`0Yd`PjBTH6Z4Y3+qB`a@pNX$9J&ieFa5pkMBYL*[Cp*UCjH0D[f0"V,a
LkY6mmUTk4LQ'Z+,A,20D2(A&31A+CSkp306-jJKl1G)f#4DmLG%3DqI+R@Z2eDj
S0E"5Hcf6AZHhrdH#QA"BRhkMYXq%GXP%DA&0c0mchPbamPR-K$EA`DN$LNSJpIP
rm,R$i6HpYHq+!F2lMl59L-q%0Al-SNE0VDJXQ!N'Ym)LC!@a!6dUe5JKhYQHS8H
m,2qc`B6hDi[mh`N[R1R-8CB%lm6j"VfTF%Q1C"@QR!dDP!h+,r3QcVGSMF)P(-R
5XC*mQpBUA*)Mf@'dcT3&Z2j6k,)1B0DE8NAVUhLT*$!P9$qEI*F6j&#CL!e&6!`
5LF'JTQKYe5,m(D&h!1CGfU"`5Fjal`QpKf`c6A&JC[iZ`a#$MK,DJ202p,l#*Ej
2VdiId)F+PlJb+Bdq-M-8IH6@cMEq-AfLF)Nh3$8ch45C`X"-rpG-LJi58fKVq8P
56@LQq@CDFKQ0!L[kX+SpTJCQkLmD!ASIYIZ82P1iK,AcNIYcfQJ[)3!IUSS#(2r
5!N*IRJ#F(jMm%$$QaVc5@9$8f8Jr'a(k$)#rS#m9,L(J$+JG[k+[&5lK&*3"CFQ
Ik4Z&LpH9V8bUSFQMEfQ6MbY+A$S&3S9[(9K)3Xf8`%cj9h%fZ8DXLdRT1`0"aRG
ZNV,almfKLVjhf'hm"i,bp!Hh`UZ25@UbEbB$Gh&"#9DZQahZZP6I("+B3hD4$K[
i4,#*f9lmaQ@&a0%F(*L$Gf99p(99'dd+c#4UN!"03A`6'bC$F)30KX4'Ak+CYT!
!9VKiij!!X`P@*-C-C)#'6YJbA8HDa#cS)m(08e"SKPhANETa#PG6R1)SU#1@b"-
ieB`2c)6rP+)`C+@FCXBT6R2,p%kd*kGcGFATVRaBITZaJ4Rlbl6)8!VE20R8f4`
8Q)2#a3mi`R9#'(+-,`CP&6-HEF69UPTM6'$'*(+k*9%B'KQ'8'H8acHM&IYZlGX
G64"`K"9R+!lFfVFlpH4-cP+FkEJ!Dh#ZB8BTVZ&J)Qj'"QEN6TKX-)XUKUq$C@&
)(mf"RX(+3c%84,EeHP%1ea5'#*aVF@h&Y9cVpD+qA)IV+UlMJ%,6D%B%CX62M+N
B!ZC%hA-$Nr[2QB3KJ1CkCVMLHQiedJpeU+qiIQ*ChYm-m`c8*f+'i`+0Mr"Zh%!
aC-Zf-3E5%'l)M43hG,LK864$!c0dCb-SEZ5J$D,"CSKRKKJMh!#S'T["#TUTX"Q
'dfKZ)Y`%cjTb9(&6e`c$k8"ZaXd9ajA0`bRA$2)-e)D+QeI9I@"J"[kVlT!!9(!
,Fi$L&UlZ)`&jGm@l1f3M)4SFi*N"+)ij`"BI8JA`J5[$@""%5fkP'"TS#0)3Rm#
YZBeL+*aY$FE51*-6Q*bG2GV'JE6#[rkHk@r,ekUUI2d#dqqAJFL-YX+eL6XC8&N
cNB4JXQpJq[iq%QKd`4lF9M&%dlDd8kL!fh&laHeFL5"!-hdmdmH@U(e9LAS("KB
U[hGB@f$VB(STlT!!h1*b4m8G(6+laGhI-rY$"QjkfEPi$G*eiQc&SB6Dl3Ef-ch
Cl'G()rLY#%-(cCej6i9a+p`0`#U!pq+p&Hp9Y4[BPlZB(S(CPjTR8qCKX`V+jf+
29eTQ9j!!&I%(f*EQZJI#8$[c2UDliRfUUYXY-0h#X3YQ$BR&JSdPaE$G,52dX)b
`Gha$)!pb9q'Z!010!@DVm,QVfBG09e[#I@`*)AcQ(Vb[BJLI%l[9,S`UGd%jZ5H
@JVY&qe6-L-DQP-kUM-ka'eblDV9E$@5d##!ejIeiIm@JAkGF9QC[lX@pIE2hVe)
TKL,(+RT3#ZjMpP+-TSlVplK[K2Y#r0TLV-8EEf$XDdZh#pDhbAVf`YiHjM'HfC2
lFArIl*Q3!29`2i[5'MfNFBlTV"LUD#[cXI%"`P!cm`%m82%"5EF'(K6K3@MPe0$
C`#Pp'#TR(Xa$&()Rr"KiD!3dNNR9R5Y%89`8a%0`$M2J$BLCicS6(KlKi5K#5Pq
XTF-X"PS&0TM58lNrUYD*Fde(hh4+D)-B%QZE1jfUmiJ)MpL@1pA!R%-BJR)qN!"
(+Mi`XBQSaD-B8q-S0a&Q8!dHBcSSKJ,BE5CUm%%m9[&"EMZ3!!N9B([IY%m)JAL
XHfIRr(DqDCF8rR5`[$+kLSdJa'dEXVJPJmV5X!YGF(4TU&%@(SRDM12aLXFjhUP
0YFdHTJfE2@c9VHd9MmFjJ5FURZ"iakCScC2BY,Dm-`Rc3X1Y['0Aq,(b203*4$#
Vh1RkH5,1JrN3KI9Nb$beB624LLIcSEjTp4[c30TUQ3H''a`c,4A(A,ICq*3)6m%
qS8h)2"JNmJSU+L"Pq6[e@-&#R(jDfNBq&)fm1qGa[Qpf6p*2RU1IZY53!!Y-#`@
a3%Jr0Mj9'&T@RXEB+%ac&DK,pEJS`NABJ+5&kp!4S#pEDR3q6qFCLU&SYBRU8Ad
ZMV#YSVG20fK@E4*FHDE"1$V6*B%9#*G%Z'3(mc5h"B2j8bVRSf$0Z04%IG-Xb6b
P,MFF3,JXJVhLGZD"ji[`)6J2ih,&KcRQD8kYZB+4'J4SQDFjYH4CTURL@BjjE(`
fce%mfc&-#fTTQ[LQ5C*jjVKh9LrIf$H0Nmc6e$*2C4Ac0!T-)dV2TK4,"EB5j6J
2jlQ+3i@XYHjSBaUD"Q`DfKShX#NJ)H%Mq%M&4cLHX5Pfik2Bl'CjjUJIH3B$Bf9
4AK30Ae%B+im,l2P)R%Ic-BU2GJZC0R3+cq2jTMiIUhJH#3Cb[1R1ar(aLL(DXhZ
)0Y5"&r!*LZ%GCqX(9a&6,c$eYYC2m3N*PApl2M(#*rlBpBSK*V9BXUN,Rm3R+ck
TDZp80c"eYf1"EY*Lk3`EMP-LI-Uf[P93'S5&kdR(mN)qeG6Kda4$ffA"pD3qI$U
ISIKd"`j#4e-l-,9rShM&N!"q1X9MEcic`QIq0!FT2Y@0S[dTaSZ%&k'(cZ+c&Cr
PZ,Sr665eq"`qecHeIZ2UFaaApkF$q$a68r&j9I(c63h&jlY#f2J&%Ei!CKrCrIp
1eU15V6dUE1eSXPaa$SF5JNe0bi[RJKHcq%+'@M-V5H3A1L)I5+2i$bC6-A5KPXK
Yr'*K+%(j%Vj8m5@Z((B0G9Q%,`[Rb"#jSj*,F9l1LaA(aCp$D$J[LI!50fp@8Fj
LR&FBl2ZZ5'b@$Z3V)hcP$LU(U4)EH%LPmN8SQH+P*Z*$$jQJmU9*S5B[Lr#b(93
1VblKXh&HC3,&9cNURi4Q[CU[83ceU+Ab565CVc@qBUK%,CAEq(9m[H+i5[4JQQb
Uq`C13h%U[pkpQd3(Qh6I`0NY6Z@qC34)8"08$PHRY(#RP&mDCeT%A!1)#@aYkpL
-%"*E$XN(EpdJI!1UG52IT2K'ab(jG+4*jC[j&YqNrXBK0c[1b+GT[0aJEEbm+Rk
V59%-)CpY&"Zr,F+hBDRCrIp`##aRh,SJ6LC@0'1XPT0[3@GkI$[Ii4XX$H*N!Tf
I*C0#UZ!lM5L'@B%P%aZr5rJZe2PZ[NFaG(Zf,S8dJqq0m,er)4-)qIJq[PraI5l
2$#VK"b,m`&r)"-SqIY"JBrDJbe0#Kr&$%AjS"jRB6Cfae-"hS'43V'VM3bQ6)*-
9,RFPcH'()rc`GM,4b#0m%mk9@LYHkFMN+(6Y)rbSiNFFQ4a&mrJa[8AaBij-E2a
aIN,aiiidMUCjHV1[0bI*j!Rh$SB%qJGIrj!!)"-0hbh&MbE*4(mIk1pr)41YE@h
K"URi@&H@"CMHRZ5R&%1kCbZkJ%lLTb2mp)lZ8[a8&F$[![hG,`$j'*6p'9kPq"N
hK#kNKAU6rTBe,+aB@c-VASAc@Aj1-E4fGJLe+ElKeDcKBaAKe6mZf3CJm`#+'9j
DdJ%Kem)3jI(cr%I&clY*EL'pcbr`LrV2r**L+2+XVH0#L$"IjPF83fRRiPIcUrb
DiPFGfbbN-rPerEALejfHa-EId&mTK[M*6S)frLDrTIK09rQ&G+Vq-Y"IEKmchh*
0FbUG`@XL['BE$E$qbPkqYQPHFj!!ckBVq@hpKH+h(@3EAkXh+PlVTQBEAmIV&8-
BC8Y`0Ph!lr#lLYpa*6LEcY'I"rVchiG4#+"X8FkKmhP$K$IX@0iTAZr!3B$2lr'
I&,rR`%(HVcm,p'HrJrZ6!hFaAFE[4rMp(4@(R4CVq(JTMXXCVk2lq!2pU@+STfb
&EIa$rNMaKki)ep(0r$&rS[KM9i6Vk(Vp5D!rqCPH&-Ge8YI66IaTK$rG`Hf+)FU
bX'kPZrJcrPcaC`l@VA5ErMM3(qq%"B'8KA8EhFNE)laa4eAKLkAi46GlVD5er)8
`p%lm*B-X[R5cedTkAAr%Ar1IIIh4El2Aefl@@NQ2m6Ik3m@3!"0Ci$EqEB5rh6Q
[@aDF$DQ`ABXR(-qfM9JD*PZT$*Q9rS!hmAHqrL!jAB9k+4m#f6rbprTpaGqlkFV
'Ia$q!CAFc"K$))HbPALFRQ)GB@eAD8QqhB)6`j!!BJa#0XP6Y%Si)PDDP,D0Q-0
6p*m8)Q'L9E4D[)M!8@RVE+@YbCCqhaEX1a6X28R4'haYREV#f3UZUQ(Z&qKPU4D
4DMYQU`ff(T!!PdQUIPF*Y%Zf`GkJYC)Qk8SJBE+ce4Zd4UVVGj6!J0$19MEZ5k$
%Gc28Ql4'VrIeqX4X*B&l"r'MAZIVGFRCkKfd2TaHNk22fN#[T3bi&1@A6NA0F8A
T4EpVU`S$2X8[ZB+m3qp,4*35b)GX,Gq"&$%M)KNr0S`5Z$iQX,dGk,IrLShrL&T
R5TB5Ufe#dJrS!le'[m9kMHdLDfm&BeQ4'P*6#A`6%bRHe'q`YMCBfYTJ#B4,8NY
U+kRP#1X$,YD[5afTkq[AIb8XJBQL&B9p`"1PRY4A8Lm4(bql53-P%"Ujq"KT+)f
80%c%$j6'dN3*l!pGI*JdPDJ5D)9FI*!!0*2Q5Z!9lH)jdN*f9`*[3aI[)bfPP4+
)H&am2fNYEC5d6X5lbak#qN!Ciq*GT*fd9p)Z%HmX(D5M%PMrZAJ(k56C5L"IFI%
pT,2XU34D&4G[,A[*hNTJY1IL,D5,l+-%#K3AEbTGTCX5L%KF[+&dPaj+S"KamGe
NAqQT"2S2&kmMqmRq#Z0)2&j$HNP[*D"V&eI54rVLNSJ(dNrk+m'ZdmA6*%F'+-P
*a$dj3!BU6&%Z6NB'b@!PD'BArd''b&!Pd&Ziq,Fb6)BV'CD)Ib@j-N*"h"k2Ibi
(bNJPF(#c"28"I5bM)M)+JXdk)`YLqA1V4SpC&GC"`0%9[0`XAAe-RqRAI2eD`Sj
'4VJCih2k8NEV9jA%"4+)keGmr8Sm$qYA,BMK$[*Ap)f-LFJBDbFDaCF3YS4#'L9
$(59r5prVPhhp-L"8aUB!+L3RpYd2T29,[RiTq@kJHfGBp)ZqIM(jEN$iMMe1e5r
iqSAN1qLkl,Xdp[8IF56I1Gmr+c(8c`IkqImBKq(YE!Z2C9+@(+4A+i'Fa'C(A$r
RkqH5KBF(V4+SU9"iVX'eC@a%aN+480-@(S+R+Qe&[2S`jlE9UF2epE1qIMCCR4i
1(c4qHP@J9feE4NJSDr+KpfXLir3c5XDjA)MVThhpG,)@cpKN%&6C@M6PjM)q)Z-
6Y4KD9$,$Y[Y-'*F8afX"&C@Y43YZTCrbp92*@ZcTm%&ETjm-p*1r$0F#ACLYbal
FALES*j4-F(N4eirlq[&NAH"9Tm6TclJ$Cm[%#24l'C3HpNLX-Pi0k0aX06Vch[S
aAcq@V!Dm4qfl,Ya02qVV4j2[S1DcllTc6rf)Vap*[S1NcllEMh[VPEjHQA`(LD&
peiIlkiGprA$b(45-pPd1$p3VI'dplGblU(XhL)IUKhcp82)Gr'(YZf%m3MrSk`H
6lk#[Y1m1j0(k!9mrN!"m"e0Dqfi-Mp2hqrVqj,[3[0ERm6a"*ZRlP%abhB1i[MI
3prid-E+'HefUe-9NIBmF,)IiqTl%+N"JA'#a61*mQDc[9M)jA!@%m80&i'`R-CQ
La!Q!m'bbj%@JFXH5T9qX*!q@!q'!2`9R[Vj,5El,-jQR5%&%#Uc28blQ$cX-hf8
R6hM@TFSK+-5G-PAIiHXlNb2q9*HjJ!YP@N5Q9@91eAGBL*!![8UK&#NT$"Gm2*1
2NHNb3pqZEe1`SV9,(VbTP'+CUHc)Lk%Im6)TdEFU62afk!rMT9+Q""SHfeNPA+D
AqhTjFZJ[FqpQFSQqaGHh*)Iq@bh010%3Ph'&("D4`hEdJ*)CS@L5jr!48Ui`mSG
p0)IRkTY&hf`Ei(EE!0C&$P*)N3S"ALX)`[*L(Xr60qNE@GpN8eLV1"MSLFb5f8U
J%E)Z%r2iH*NMKbZ"&XJ#QmI(kKY%`e&1bH&9'i2V!hhp2da""ICe-PH18!,9$rD
X%1!Xd0I*NDb[`jj9MS4(F02S+$$[V,*`R45hFil'eCK`J3Q(2K&SKH3S19V*8Di
C&d"qISc-dpIUDj4Jhi[&(V#G*r2P@!@Er,!j&r!TFT`FVq3i4eF3rqLV!hhelq2
8mDlV6Z#6C8&%&[a94`1rr"$IDAb@R#!R+S&Sb1)lM8rA9`AkUYraRHM`R3i0cNN
41@Ql,%KJMSF9(j3Z@q4NNC04p90NSC*6A08[j([N9$P0,p0,PF#AcPEp3Vj@6TF
cP-#AcPEP3Vj8cT4&5Xjd9B&S4PmCk#ZhMfR18ii[iN[NV)LFp4HCNjcKX#cQCA+
fR+2%HG8K[N4I%HJVYQ-jaf&C`N[Ph)LFZk1HTcNbZB([N!$cj(`Pd!TKp%Im0VP
!,P3#LcF,l!Dq85m*p**rf)S,e$k@8@rN@q8LqB15LecQQrK@[6M3cY%1hN8`d3l
[)dEd8`*&N!$0!B@+[Mc3Pqp5l#U"DLR"DCF&qV*rF*U'15(VTCD9)0L5Lq85*4H
lrVbAhj4,j6*pUFBE#)YXIpl,cmMPXPM*jDkRlZ@(C)PFS@5*+mkpI*qq10!AEqm
TTc'#P14"Z6)L9fl9&#U"%-RL@-P2b&*CTJ5D)SYM*6qLra$S2fc(XFcKH)3IPkX
LFY@1hVc-pHCcr+TF,D"4+)aXEcl(,mZeFTf5Daf`jhLe[LM3&qhUcHYFEklQPq4
kZ8%*0%Ffmr2mNVi`d"H5lhV6PK#ii8"RAkrQjr8&JElJYkkX%LMTm`0prUkZK)d
JkdYX9ek#mdCpRT)EA9Hq"6+p5@l@jfS`'53aYL[IiNrP&PQZj"EA6@raHVP9-0J
j"c(%eqLc!hhfcSA#EDkce[!kZ6dLYrmS!K$SQ5bX$IbKh#&h+VR$`GV!lqQc!Rh
@6PL3!"eC@1ra"h*A41lDdE!36GQ'hFMIbGebMj+lAF0Zj'rPAX&B$[F`#h)MIk%
A"AV4VSD&BjKYf#ri'lPI(P"b[m[m*33"C`Ekc,!m&B9a1N8%!e")U!qi2&r`PrU
-3*ra@q[H8p@kT`IDHE(pHqYD)d0pMTeBcl-Af)kbYVDM!ZG5H9!H8J+r-8b2f1Z
,2Ne@X)Br@d4@K#UGVG0M+%D)aSAlEQjm#1I$XP)*PLMJ!J#i4ak44r@T'P-99&$
@ZF&ZT4q6aj9!"B@Q46a0RT!!*j9!lB3+)ZlT8`*pbZpcR4-[L5HTmP4%R[T4mL+
21h!q&ZP2#cCMcTJ-m8#IM10hF(!PXq!#bC!!94&CYB-A),`#X8TG8-fc)P!dbA1
#25!fIlENGE%dIPlqU%r5'&9K(@C,AKH,l"IN4583+YQUe-ALr#9j@3QX`Qa9kNS
pI8+J6pJq6,cXDP"2'XJV%APPqe!#bc',S`N@k+r+DdTHG6LD5&1p)0!,YZ1!rEE
&d95DbqX4HAe(,5%eX#C2EE%*Id2H9!)P&$J1mFlbPUa4!V@6"GC@fZRM!hhm,Sk
$@`3i$K[jE(PEeLTjff9Z,pRkZ%!I4p&Xr1a!U#kVX'eU5aQ2Kff,Z",B1pQFf1V
VB`0pl'pm&pGS@EkE(qMjZrMZ*%Y`eVP29Z0F*qZ93'f&[BadNfjkRMk'p6bE`[V
$#D45mSl'jZ-GemlGd1A[bJCpP$j5bEZZREYK$rqH32)#TbREKYf`phpI2P$b[UY
I0qQZM`Md%G[Em!2AKYfPTh`BN3prfJ(!I-TLk3d0`%IbXC+2(*EHdNI2$I6Fl9J
JRE*BqNKrq53LRqaSk3f1RSE+F[P8",j3mTPmVZ3c9mqK-P-fbKIkF$e(b8CAck&
B'RiTAbQ"(j'Y`9$S",k@2bYaEND)$p1c!celjaMeCeH2B6*#[SR)0hqCcU$GXE"
'bhMj9MBTFIC2L)r4X`)pDbHX63l@'"NRhdANZaePG[j6@')@bIIbJa*i3&RQ1P5
Qb@ECSX4j25%Hdj@"VYc&A*!!1PRQLXP8d@+8D*Gj#MDB&B'ZF-`9PL4N,MZMaH-
KFi@6'P450LGfUESmd1@r-4IFU4,-G9LJ$p[&A0E,6m296q4c6$SBF"9qLLCXia)
jda22df@k9(N`KE*YA#,c["5[Q[,`(aQfhdUN`N[edT5AkST6)U@k*0!P[r5EKer
*X2e@+Z9HHX4,re%2kZ'[0#bXfA+N9phcPHG-S"#ISfF'HZC1@&"J@9Kcj!J[L(M
"pMEfi29NfrJi1G@,H%VK2cV#0Mj16[%b[%cPi8Fd,%JX&R9aS)[rdFBHa&+fMBr
(chKNH6@8"fFRQhQ"R+aR"(V'A`B3emC9!iKYBmqC4`($!Mdpd00rE@0[UikV+0"
&ZpSBhR5X,5i22PjH69fS[*UZM4I*FUq@9eY2de19"i-TfmD,C)PAakZV21L`E,m
YN[1mHPjpjF%2bS*B*'ITJN!Ar#3$8*lcL*+cj&a[YiLhfeC"Rr,U1M3AbU9H!kq
KmL!qX'JZP)YdIU$criB'"P)@c89bLGFSiMADdEGBepZqA5ShHSfp*XTcSLr%VrH
DHP(P0AA`X$,6HB(1fp@h@$RE[PdQehR0[1E+Jj@8cAb9A+HR"(U+m`#09BC0'dE
#GP@HmjG#hUYd,0#ahhS9bSa%VaiDk%0hpHSdfkZ`e44Y$6Bd6"*C`dK60)a$4F1
MP[9#5mL3!(Kl,EcGPHIqc!-ESA[eC(d)kmNfa5'ffI&R(Pj,VjAb@SE+!D5ihfZ
Y21G*KHKpqZ"!(rb2@RMi'3q[MCkN22b-KmAiJ$bJ*qS*V1&aaGVbKjk%#q-R0,`
pp(MP34NAGcR5ir4BeM"IBch@jS%$@aBXU92e39jEVjhAhZ[JG@50[q[*mYT5LKk
M4qY4HQ5Jarc,25l3Shmh13cdU(rqai%HqGpZ8"PH1rbDJMk3!2,d#*hViGq%p2!
!iAr@+%0$RCDLKhQG23d6SJb[-c6RHQLJKrjLT+MK!*[PGB*`CBJHV!F&HXM2Q3)
pH+I0FD!(rFhT2F[,KP[0,AUJ2N!2d$Qk[qkRqqSq%'ZIUh[6qESA208[dr[6BVf
IlURhe6hSqM3pd0RpqrU!q%m3q(T!h#(5ecQlIU2!erehrDH!Vr[YqJ@"32Ip@rd
%Y5)ITA+L,4m&Fq)L(d9ckKj2liH)lVP,9ZVVIH0U'am9GRUF'RSi&Fh)@CklVLB
G8TZDV#pTqmlLGe[CIhK)b@f,@lA`PPSkPRVK(b8SrF2&,6pUq8c,+h!qdr+6PTp
qpRRal"KPaDK'M'VL&f0b*e2Y'09T(i128'0+RjkcI$a9+mTC2LCh5@CQKYIHNNP
hZPYhdefp2Efpp$i"`VmlGZTZPMrK&jEP3IfQZ`5kbmr8N!$Pl3@#h9[[TIH%0Vb
ccJldhMml',1'AjFJ$aUVmbk6AepMka2D"pI3qe#d0P9INEXLFbcq'FRql%4KlVX
e+GM$YXYllA0Z'B-5Gl!PlN4VG8IG`G[Ekk,E"`Mr"aYRD*JrTqKfhMkHKXYFKJH
K)1QfJ@llUbZVKLe@PVFh+Vk(EU0EkeDkTGipd([XbKRS0MYCYIA2"RZ"E[@EBek
J@qldhJ[dlMYG$l1m,T5Z@qMQZTQ1kUDkL@kX'`@kaHpdi1[QF4S1G,2I$IGm(Bd
lR[UkDGb$e0I@p@P'D4kSZ$%D2km8$Y`PP399MCrPr[9$0rVAP&0$YkHLYY2E%De
["4*GQA0VlZ+*ldkD1'(PT!Q,0l6I-qHfh(V8pmU*lleE$"+G8GL3!&,D,PRD%Mr
%NCCc4qkbkD$)i!Vm+mIdc2&8GeQ4$Fp!Z!MKY#YQ0-QjG@,ZH,-UelkCBHQcSq@
@KK"K0Y#lH9fpEVTqS"[qVcP1`dmb4GIcZRXD@i`-VlYPQ,U"KK2V2ecp0"bUXVb
ZB*JkZVDZT@[U'MSVd(9fj3cdIpJf"EV@eN9US'[q[,3+G)fI&L+"cYSjUfGjh@J
%pp@C9K6+`h8'*+"+4h5JICl#49aXTBKm)TqLUr1CI!&I"[h@PEb-Ei-Hk3&qL"r
QTk&YfF$[mkG@Am)DHMY2UN&q-%URBdfD*Q1a2*dSH9+!rHCK@'UGC,Fm1P@Za2U
MQY`ZGqN8H8T@b5[bZ[EN3rP%[T([Y(MTAU$CfmeVT$&UC#BRYicNj'EGNR6NYmN
Y5%jZ@!'&NjZ[3mHMdP,3@1Ka&!k'DA%&Dk"6rkB2#c4m(EBUN`+GmV2`*G$HImN
&!Sfr,2VADKE9rkr0A`#6R(rI-pA3pH@KGH[IHAI$c0R[rHRp#+AR2[94Hp$YaqX
rqI3c[2NmqHE@h#X`M&V,CGcKFNie@c@Q`8YLpPG`U(Q-DUr(E)V40%EeN!!A#kY
NjY['8p-BlBEh$@,8-%D0`[H0Yle2Le%6%$U3!$A&@UmH8%8Y8YbEK8MYLAGAaZ!
LKhHiYdLq#p([$R3YBi3(V80dEC,SEJr4lC&cHfk-fNkQGLhY'D2fZ(Iik9`5Ipd
aM&i4MhB+SeI'SpRrP[R[jp+@U%VR'1eCE%Zb9k)N-Ia#NChICf-8m3TcTmr'[)*
+GiPAI*piEde(0h50peZhq*Z-CBYMe,epbj`l`Y4if51HBGpY'ASQ-k"6pSYhc2l
E-[4+C!Lc!(A[12Sqm5a,JDP[(&ZrECRlEd1I%mm`)&%ci$`JMRIJYUb$YP9NF$c
$N!"Y'BBQ-bb0iIFdN!!"pq(E-Z4ZUeQBD9PQlSK-cc`2,E#")3'Ejr$R'*KY-Ap
&[RrlE8L4Gr`&RT311,QaGBYS"(Zm,2XEEiJYV-LV`"m&d2RfYpY`[f*dcMMB2G"
0&C9cl3,TmBUb#Sa6p%+rh2j`&k@hq`l[EreP[h'rhFELIVZ0-pa2Yh'$SVaLr-`
&Y`)KfrLHZ0[irS9BHH!qH05J#IKj$$jSl)K5kd-rKHBE'#a[Xkq(*jEpm!i#FLa
")BXS$0rp`FCUR@*Me@#3!*0mpm$@h,#NF$'i1Dk4dV1aDM2`qi1YH")6h)U5q@!
TNh`(2aIlR4r'-*mQBYKr*f29QQf0KAlr(ki)ka6q-*MllB"8H-mQkaIqi-$r"`!
!$3!19A"NBA4P)&"33b"8Bf`i,M"UC@0dF`#3#9Z8!*!2!9A4!!'5l`!!,`[rN!4
"8&"-BA"XG#%!V5`iU+qS`VB!!"%@!*!'#K8!N!36(3#3#"+i$-$ikjKR[Y4M,cI
+RaB&S0G&1Ffkp9NMSjabY4`3CY[SEqPeQh@%%rjiDRLDXP[cbAV5iqFQa`PEYi4
hK&pN`)pXmTaXXXPJXilX)jY'RNIfNprNpT(*5RK(0YRRdH18jbR[I!IbJ9d1BUe
m&1@r&J"3eEFTGlrN1,NYiC(Mj$C"e!BJ!(Tjf4%LMBJ#0P%YIZf4M)LP*Y2a4$b
jAic%%Q)mP4(fK#@qEXC#KY%AVpf6(M0Y5``0G60r5%Ih)60M$rH20!(k0rVCqrR
jZkjbN!#e'eJC9)4($STXDLS6Xi5CL8h%Tkf3!"$pYSLC56&U`B1Tj*J`lAE$U"Q
hdqhK-+T3GLUC-%Hc)IJ96Nq0KQhSQ$4MBF2S(aH(S%BN8UQ$l+0T`m*i9SbPBP1
69Y*QYTJ`Tbf4cX#'#k2rXBVIADVbR#0*2*6XifE'4BVF4flRkZ(@)jX'TVT(8L)
cPA4NCf1CH0S@CMUGL-G-1jj+AUBFQ*c+fQ)mRN%96fCY-j%3AHKK$DYq)FMblPZ
N+VMM%Lcb8l4kUFr-MZhT'KEE3YXLr0H#j3l!&iedFQPXN!!"6$YBmXbYNa[-094
PS0!2+0)DHCDUI5Jf4+KQmT!!E@Ef@hD@S4%(-ULDY0f1!2,S'!5GDXKVS0!Q&8d
MRjpmY*k-G$VfNa[MSaNcFbMdDr6"jmA[PmX'qCefl)hKKc(R8B$E$FFRi6JLS04
3,R2A+[be&$"3k!RQBH++mK00&U&!IX)Y![L$Y0C!SDbX)SrmQ0Ej8$4%b)pabYM
T61U!&E0,k*!!JaUdcV'LLUVP4blj%@NkVB@Dp94RS&"UDXJRPqJm,YC&U$S4(af
2*b`&p!&Jqj3'6!*Ym0-'#2$YR)SRaX3H1jl)1YlAi6qIkJd8F*&MPZ6Ik3)0"FE
K![S'I8hX55+q9#Ca&#C-C)&pCdSJIUfXX&-1+q@NKNL0+pb*jF5BP4&aPA6L6M0
T1jVVm9p)&aNS+TSrT!B0"63hd29dp@T6P[L[R)ScE*94DbaZTc)K4pe&q$I5a3D
+LVS2U&&$!A@0e%AA)e*6D5YM(q,0)@Eea$1LA66hCbFQ65[4hQ00@iP8QJe[,de
RYKh"[6d8D@pf0&k-Ae#6JD+LmAeUeP"!Bc1e8V2)@MC'4)dL1eK4fP*Q19+Dm'q
Lc3D+5Sbm*pr9j(XF)qpbLmhi,k%@!i8H"pq2B,Q8@Jd8V[j5bhGN3ElYPHp3IFL
dTZd8JM`jP8J3jF"qN!$Dm$4Ci2"kQb1hY4bjBGULdaD)D+1Y"JUGP`hX@A3CA@k
JJ#GVP153!$aM8+JXf#rr4Q(jPKGPI5Kl+*Y+T-`a&PPH2Xa%(,%F*YeCSccb6BT
i8ELp(&)'48K,JDFMhpl`b6Fq6c"G[X8cF)B0ZpcTaeDrlT1[8df%eNbT')1'VIL
hd48'#Rd3iaM!A&j*9aNSP*rV-ICAdc8'#[M(q%Ej9lT@[ZC$b8NmbV&BhLXFY,4
Dk(3Ya'fAVaUdhE'JMLk3!+Gpm[3AfiJZAq8jHieYZfE&YPGmmK8+4UJUBpR6CN,
9Hmf%J390p3K38,lXNbqIXrB+r0I*P`bkMYbhS%X6CUUGVTF[bN8$J,i$iG1%K1L
J'``85NN60FY62RRUFl8h1%Y"-ff5*ehb*'N'mYCe%bLAdPCjJRE)iek8L"'%UjA
*L*@TGQ,%S"f1K#f)LdirG@*,@1rX&FKqc[dq%m-ljUa+alPiNFGiNC'Af0-@r&(
jJN(4PFKlAMkRbHHjch2Fj`@1)$!$3A*4PI`,8RZRr$0fQ'i0)2DT,R,,Cq@#2#D
ImFPR[jK&ReciDYAbb@1IKipA2[0PPYE56Y,GmQRUFD(3DkQ(hI+4iB*,@Lee8h9
3rSPDj90bRRUT6clT"IcIE(k+ECpRDhZjk)2VFh*@2L%IPhqN6UqF+d@R9mjq'EN
qqF4UI[MNierPQ`rU2SZ*YI**LV3YM[)U($k!YEMhkF((eP&Y'c2Si&Cbp4lE-rL
lJpT'UYPbi24j0j0V)X#"!EVrij-R(i8GMD8M$1pT`cD@`eMj(L1'*bbf(q1X9LH
-ZKH@mjC4ILS8X#J50KARmA&$d)mlNA&(XFF39J25"[E+TE"VQX+Z5-I$MrkdVkA
amPh-L(6-r)K4%C*,[mM[&f'Ak)LPNhEA'9PXh[A`SmhhY66ZMSjlG[p-&[IVdeV
3e4+5l`rF0M!eX"FlNIrQ"m)G!i-Mr9#EQfPX[9hiaceT9bFGrF-GV@(rdHq,%H&
jDSEUQk*8Am)DJ$AXH5"F*firFYZ1h-KJDe)@9a30r%D1l+EpEDc-6#IXF%FfPVE
6660YV'lr1[$mi3lf0%dcE8IIhcH)MRCC!hJ0h*AjI6IepUQ*b29h$fa5b%2-Bk#
kDfMSaY,"3c&d4)`EjjLlF)kj0iJV!NiMZT[FZ,0i2"S&kbJRQLNDl5*4b1@#pe2
8med5lRY*k&%+DS+#HT!!JQi2"6eZ%N(NYY!S&p@r66Rh24TjHU"M&fiZqccN(N0
@2`DG'TqUS*[eZe"AjiN1)rfaIQUi9EK`)+R'-BH[3)e5jMUPc"q@FK(AUJ,q*Ia
&r'I"NH#H4BmLHLe9Jqp#(ab0mUKc`+'"G46a,e(eD`9br4Bk0HK9dHU%L&UYcVd
#"mM+#hcD)-"VmMmD&'C2V5S)N!"rGV9"J@ER!*BE-"hp+Je+p()$49GmT`(6Pdp
8'LMk#8F!0j!!%[6MqBU#XmH,S2[pj3E,Xr1JjbX0LV1"1G$*M`X90`K3IKCdFKV
kjkRJab0b&-*(0'#kiS11PNc2+clEc!e!Rm005p'9+k$2PZM+-Y"Rbh4D,M!pAk'
I+*kM(jpITE1$Uh4fm&4aK8k"r(`K-&ZKmdK`Nhm1m!Up2(@9&p9bYG'eSLQidh2
DrB0l(Zb+0SRQB%rpICF%@m6'+1@dA#$IZ0KC1,b%h$NVj@(CHEDaf,M8@HKFh*K
A3F*r`0%N-91-qJ0+C#%rch-Cm2Y9*XM#[!U,j92,+L5@!mICZJ#2'@C8cGpF!Ed
#'%'dKUUj)VGHRPF`&HF9M"#UH&VbmNVRiUUZVk8,V@(mEm9DYj+##13UUPTrIqP
+baGDjfCE4hI6Gr4p1*fJeNlUEjEEVGlFYB@HQ8CH0"Ud4bLBM@@r"Hal[#6a!M,
FIdX[P$l#5`h`hirdlKZ"J+HcpL&fiBeX1MZ"qX2Z`CjHdM4pjd!2pK6Y3QHTd9U
FT8Dl`PPTY"ha@!+()feh2*CPI#pUaNFRaXG`d0'5haa+BEh9i)'kFC1fF-YPP*0
bL1KLB$K[+Gi2JD'[`QD!EAGZiV8$`$cF$laI!G[XRQ$-mdYJNIAhUakDYY"G+2%
@`-0@Sl#hJ@&4Ne+3!1F$B,YBDah9V!9fUk2*blf21Ifm6H"Kc9*BLlCJjZJKK@d
$Ejq$qDi'liL$'GH"GdF*ZaYB`qYjjFGfB(j(4qfY`)Eq$`#3!`d!'&9`C'&dC5"
8Bf`J8fKPE'`J*L"6D%aTBJ#3"hL-!*!2!BKU!!'GS!!!,`[rN!4"8&"-BA"XG#%
!V5`iU+qS`d3!!"&B!*!'#N%!N!42``#3#2IC$-$9-Fpmq`EF+$GD&)"H(H@HT9q
$2%fZPJ01Vil3jdH[fk`MR2"If4UHTUbemrCkdMUkb5E(eLhKC"2qC-#2F2+m)jX
-q%HfC0-f1AjN(aPXF[[)C#@m)rYB6i[b-fmlL!hN!lH$2&YjAKlP[aB!80@hf@E
lb#E(b'd*Ma`RU0J%&4Y2!(63fH'*""%&RbF+i"82f0CBLab`TA@hE8f0TD8pBFR
akDQS(8Y-4H)aZhClFLaL@h)d'TFM%eBm,TY3ha$E*3hi')l`Ql*("NBE!*rlIR&
qrj818VP6aUDd`ejfQiE&Y"a2a-HXP%b-bjR$Date$U1c+4YDe,fD9B,89PZpP%V498
HY+h#f10L(d*3&GIMSRUNfY%cKREYX5UMpSeL1PCT@kl0CRFL191CLSRG%j@fG-h
+MCXfA9%YZb"lYfk'jfbA&$k8h+Q,'CF*FMpf1eH2VheXcH"dpfK#TUDjHl'd6%G
6XD3Y)mPN2"D0m+KFaYf6Np0T@il(8UKL8fNlJQRTJSBeS[A369S9rXqBF%Z'qb,
TXHeG)h*MbmBfIJ0JZB2SM##$A)*EC!)6GaB8h3Dj`9a"C5B+BimQPDR691j$XE+
0+LCRl%KUYf@R'4Te)*2+5@c6@L[)Bf!8$+SJViP#6'UD)*qII&4$J@3bqJ4QAip
mbkmKK-H,edqQLF+)XbM`J&Sb+H$S-ald8j!!3Z69fSJ04eZS*6CJiJfT[!N"E3#
pT8VeT8Q9MJ('Ur`BFM3J2I(%5'`53`3R440I3N,P@DF-EcA9Q#MJK#1*e"IUFk'
qB*h2@D)'lhQddN5K"k5F+Y3LRHp$8GG'ISaTbNkQ%RZXU&e!Kah8T21GGT564hh
Q8Tq4-'JPh065"5B+lFC,I[8TVI+KU'UMmRKXehJXEQQJ$i"*Ua`2ASc6KAkk%#h
fECf1aFINGMX@6cX$G3(H1PTYSN!A1D"*rBdZ%LJ`BaI4MA5ph$i968a1@P1f$Y"
i""PMhj@3!2(BP)A86MLXK*0'R+D-FfJAmM@QmeAH&CQb(FqVmGD60&'82(p#$3)
&2$I3CVVUM#KEr&Iq&F+mJ&TM-6Z"b0EZ*0j'@Q1L+,RlQ#i@+1$ZBZULc4*$Pl4
5pJaDP)TD2E'8E*H0!qQ*bBJ9EqqapPVa4*)EhPkBcR5l(BeIdp,@$NrXF3hH5kM
*4&(bq&Hk9+#!adYT,6A+Y'9M423SFJG,6TZ+,-G+%pkeY-j%8BU4Me41U)mi4R)
XX3j[-kdh84Jam$Qm,U-0*JVA3%(b3h9+IH"9(e*Y5m6DDbH`)%a0aq0%'E!ISQC
m3ThLm2U!$@`S"RNVY4M%Np0+E5B+)k9T!GT)PjXSd*-9`2edKAVIT#Z+K[hU,h5
PHXq,XVBP2C01a"14-6CCA#L``#(XVb6$@F!mkPfkbS[#lH@3!$,T+K)*(EIPkKf
IHZGFJKRU2Ck"plPKPcYkh1UhIHTYUQLM&G-kaZ#K$Hqhk'S6K6'%F3`L"+kK65B
+hFpU*%dlE6C4S(q-VeCrTJjedSH5NhJAaf*a@h(3`X*L8!I-AD[H-ZPDT`8eG)&
kdkIHr'V(-G4E2'FRZ@fEPp[fKNqp3D%f+NYCpYj)A0Fl)R'60MNDf&R8kcleqYR
@ASehLeS`D3ZjEi&+!fDdNm,UK$TZ!M#f)(`DG+TY09&S*`h8U)lje,&cEVFk5`%
58KeeUD-N6!U6kbC3,UAekNr8V9lcSN5-)&bY9%SZ6l86)bCe1aE@)Bpkr05$(D,
Df5Z3!2fFqhd4$1qBMMIe'KFRH)b2-l,!29f2YeHpDP,[FZ5pSPi@kKA@HCPeAZ8
)!M-B`Mj@T[j)IA5G1S)GTPm!42leN9XG9LqT3qT&RcVme5cke%[IV&SqGHKFq(M
9LepRDB#Z)m1YAU!"&`TAJ!E3*qaC3DTbS8mL32e8(P,cY%%pV`l50VTHcAN"rcH
GF43aS)AQBN%1dIASqh2U@I@-1U$q3$eHp9`K2,hUfDp$ekHH1C-J2RAJQi6c`Gf
rJk*5c9&Emm)ZhUKEprK*p"iDHVU+!Xh-S$[ANk[hm2DKhpdT9P2&ZMdRclZCA"0
"MJc3r9mF2riNfY&511$S6@dLNV,'j&iVaEHAiTBi20bY%b20HcS89cUl&'EIL`R
JYD2ikC6!jN[BNjb2VbL5IYVC3@)reL6#QN"LF)GDE(AYT9CA@mIM6rkXVkPq3cm
cfMTQ(f98YUM&AfChbeDAl)JQTqbZ8bVIf2riNihh0G9[#iplYMfPmVZ0[5,NDQT
4R`cH0MJpZ!0,N[rQ"eXl"SG'"q!f-eZrpRET(rFNACfdrm!GDe[pqaq@Sp,c`Lc
90S5TYS$9!D[ErQ"VMEcpXGZfC%D(eNkTr,+M`GqSd@fdZjQG4C*aZl8M(8hDbBE
CCRDhZ`SmIfX(pc4*Xmhl2pNj"%@lk!'m1PCPIYp0[Aek)M)$hB0V02))maJSlaS
H[U&`9p%-!iRMaLASENPdE`KR"9aJ$$HjFFlai0!9UU'-E+4`Z)YN,T-*h8pKc`p
)ZZmPDB3T*#5&M"#&h"i+HG`N3`D&TD"-f2JqCGch#2,d`%HrQc`l2H3H3hJr$Cq
#,dr`cIjGU-Zc42Z`#@#l&6L&Z("2+FI0L)p0p8TP1TA+lP0U!@Ha(0j&[(QmTm&
4i*k'4KjDLqAJZk#$fe3@G3Bi2,#220j&+Rml4klI`UH!Ajfd6SMSAH[XPq-!@Ik
#ra!)mKEqGi(F(2DCCB%JqHI1#14SlL$!SJ$6S9F5+0#,!TUZqBi!djH1P33drCK
MJ!@8![eSYZ6Jp0%mk(jr8@"TEKldE%NJ2aFm#$VjFIaLJ5"Pjd!R4p!r6cNr2L,
()IS)!DCV2ZL3!'4k9[1jc5`!qN'F`$4GG`AdZ3*GY`cdZ5+GPR*-cjESar*Rk8I
Rcp#jJfISh-%6q@8k"E2cZH"FLFiM`5,r(1"PHR(U5PpBC!,K5YN3fZSjkIl423p
eK4YNBkLRpVj,3NebGCJb)K2-eLpdj[BY)RG1+l92GCkZcpF[GZBk&eCRGC!!m"Y
d2#R-&+2qS$DCbmlcA!EpITd*+MH[`f,Ta*)1LDAJ8@jGN!$($$1UjqpJ$PT"M##
NiHTJRU@AjM9-qAN0)i4+25hdFUYcfY9RhX)Tf$6rYh&9,BFLmVQ-bUV["q,GZ8!
Z*$HrI2&ST6A'$mA(A)ZI'ka3@$#@VrRL5-pX2HmGGH)"#['Z"1b"G$6pAGj(H,G
"rC24hTfM%(iUEFq`qpqRNqN*e)HkKhTk`6ZqGE#(ej92RGe''-jZ)`,1CL0@aD*
a(*4%8bbDC[abe)a[Q4JI`k&(E"XCZ+8ApBj[$bH`r)TGP&&UQ(Yej"EXM[V1rMe
JNRR!ILb1p(@i*aMcR!*[Y2TqaJ)h!+YcH"85'#*3Bqh!B%FT549KF555`3+MDUM
L9[#`1E''&pVGKadpEabm@`Zml`$VTdFdaMhSF$"I"PMB`FalSCdVB!I!DhXhUr[
a-$#2mjp!B"EB0BkR`+q!hI&r!!d!$99`C'&dC5"8Bf`i,M"PE'`J*L"6D%aTBJ#
3"lG*!*!2!C,[!!'SG3!!,`[rN!4"8&"-BA"XG#%!V5`iU+qS`r-!!"(%!*!'#Q8
!N!3Z@3#3#&'+$-$ikjKR[MelZ9&ZY#LHAKIP4NZYFQ!dZGTPF[TGp2PTYeP(11'
8Vfc0ARCVjj(eT(9ZXXQaG8XifB3rf4*qC*0RK*00"TX9f8Hi4jj&pT%C2r+EV)6
RN!!@V8[+"qP!2SXe@[Pb2+2me`lBUQqcl$TbR0b@m-Ka-Yd%04Y2!(63fH'*0#)
+0"2jm@Th,eUT2j+ZTJ2-4)Y'J&@HcJT@YJSba'aX6`k&VDJj%)Q[Efc5`HN2Tka
Yh31e`TI['rbElrIRGPeQ)iXIdqM`3A1`ELalB'8A"8c85Di08D8JlBHSUP"A5hh
`jUlXL&XK0He(XJGkEqkGq-93BR!mBF@'"`Flpm*4l`kL(R"(P)13!ehCiDm9ldP
&alk5*,T09DkcA@*m++96U[0QJT`("k9kB2A"PEd6Q`B5CQTLh,4'BfNc(8R&NTB
C6LEMX8MBLLA',c(h*5E-XBQdC3l(8UKLifNV()qEEG#)EP0kME#e226[-C'@r,%
cR"lDhVE0A0HiVNPH(eK12cUMN8i169TN!02f&"5G1MR"A%4P"JTpYb+9mcb9He!
XDk++XAe@1$85YG)#$GL3!%(PT28SV6*bk4J&R5V)ED$3aK40)iqA2,58M#[@ErR
GeYLZ9$LeVr&Kk1"air@5BD$3ik)*h-Gc"[PXHF(pA[+,I$)C15Z[mCai-2!'D,'
"3RP!GfN*j`eDBRX3I+NA$XiK[l4J@f`-Fi33+VV)LmCL[*AmT8'9YJX(TZ%FrX+
!UR)Kq$)[,4-AdSPrZ[J#,[K,X9+'pebU-P$!LZ3FmHFmUr(RSM-V%P9ick2P"JS
eD5jbmprTI!q+kLEbBYj69M+9f"f0@!@dhdB01YrZKiXUq$-(IdDD6X[KTTT@'#L
8'`mCr$Hk`)0L5419af1lKQ2aU!)k!4KdJHh"Jl'V`B2QHpSRB[%KFlX9LkIYd9b
"ek4D!`@k+%P2r#R9D5JJ@dIAd4CcqhJN-6B@(EH3!'94-aj'@&Qh*XaiE$bD0Uf
%c8VBX@BQKK@1N6'(%r'KD-U-$DZSZc8mEYQHDr'ZT&8'LT,RrkF,046`I#&YS-[
2L)V&Ei)d*R#dL%D(BPBLe@Ll@i@hRLib8*6Fr4qYeP$!h@TUS`dQKLiC69Rld+*
8*0S45jR0CPehHR3X()dhGd6h4Z1*T$5mZ6#Gk@C,E620GEE(Lr"H6!d'LT,(6fL
0KJ)Hem"PRCQ1@KJ40BV5`C,6qL,,YY+!pa*DDk!Sa8L12pBi*c(bX8LXaGY)331
&(J2IKdPZSR8'#NGh3I)MrT!!2h$c4e69')lZY4,B0-BRiR'L$0Mh83-qM6q8m2T
!0S*eaBdJ5*IUG#P-r)JZ-e$S+8AcdH9dKB%#29N%h%YAm[X'A9Ndl1AhD$fIGU1
XDNc[5bILLI#3!*JXELEKH!aE`hV5l8h1aAqPUp`SR'i*+B1Z)LfK8VZFhrA`Zpm
QQ-kRC3EHPiCGBHY*Upram$Y8d85,*P5-`F0PH*YTJi&#lm-iqT&Q,A5eJ8,eFbR
#Eb1e'LM32m&Am0X8iVFm+#@*GdNX&YFH'beX2MU&B+k0hc33(+S&PA3H[q(K0lj
EPR4q8qEX,@PEkd,EA[I`ka4SSV*8e0SEMUYk4cKZd0@fKTm#212KQE1YhB#hR8m
Ce%l1'k&5LiRG4"emNNmB!250#*pDC0jQkM43+#He9-I(2Acm@lHGpP*34b[j03H
r4TT"(H5i(T5,D!hrKDlK9pdS%5-)efJUC5j-Y4dM"PeM@d!!8THAZV$G,,Ah#Q5
rj(jR'--lT1+0AjALT)ca#8&158q$H,ZTad"4LVaAq'@0Aa'GPd@L"qm@IXQJ,3X
5drbLaY-LmD*BH8P5#Nar!&YE'IqCYY+er!)Q[9F$L$9a+cRjH6l'8rbFKjrrEP`
pI1b(EFc$8prQNjZIqcjZIA3Yk8iq5Rd1&%iIp@'ha$)Q@qib"cUPqDLAbJ-m5H[
i@Ak'qZNkIYS0q$m4rUbdrKPTElm8ek(c6r'6r!3rcSp4PjZI+L5XQjrm2TNpr-5
CQ2(`icr%S!IZrT8QLrPTDQUBf58,I(#hPl60,r3pZS4m$F+J2@[)XIR&lAf2lG&
@8-A&Zpmqj`CbM2SP9d$hIR(bj"'dBfhKA#6VA(rr*M-m2Q4LIcGa!dJVF*Z&a6*
LTNHMFHN9GR1eEf(ih4J!@8f+RiS*,0f%rF[qj'4MdQpE@dJlM(f+X2Z3!0DlJfH
$MVd8G$5e2($N`FlkQV9G`QKU1I4V3Fe'R[e$GX3-1Xb@5(,FD[Z)mh9G$abTZl1
qTLFdl1TjL2-MqPiYi+K[j%rPC#4(TD$hKRZ$,Eep!pe`QcP8XhV3p!klNSj@1[c
8,DZ$hX1r0!G-ec'FV(#qULTJeF#UYpmEV$3($pkm-623YhUFm`Z1HKrKJ4iDD4"
Ri@6F#VDN)dNV@AZS3Gb0,!(2'fb4RLET8-2K6hIf3G%UHJ#[@P5&hhRpjNie%CR
Z6EdV&A*!H!+8YrAhEbdFF44$4q!iFADkc55k)i$6!mipZT1FZ"fjA"S&+LPMeP%
Se%CQ,T-*h%8Kemr*G0j"TKkLJ'C53!p3`1QLJ-Y*CJ!VP+P4*U6rM$,1fc9bGF"
(Pj0F1ehN(%*k2`UIQTbji&[m1e#ACiRfcmJZV)iT$Ta[j%SPPkdDjN`VFhBrm`a
ZF$QmXhMcH1I"BA$RSC'(eQ`jq!lSi"#@4Cd"$JrL)iphPXVIcC(M6r#T`Dm+@MY
%e$jfpXY*J#amrUm%r,+Zrd-J0iP0Cd(!6pl*-`)jQM`+X#JJG1L9"!VdSS#L+li
Y)25j%b8"46pK'a!"CY#2CdX1jSrR3IGkL`*cNe1JCdX#q8Rr8G$*LcZE#2JT1`N
kfB,H+FTjm4(C$Y&(#!KGm8'(T0#cLLpY&J(3Mq,LTZLU+k"2&ZLUCD"2&ZNdPa0
kYN3rN6p,2cjeKLiG2%1A$Tl+,p$*Rjh+q5G,G"N*%IPkJ"ISaDNVI5%Yi`XY0QX
$lDkhRIIIIPpEU0DX#h48hAPKS0jF%D+-P[&RDfCDFrYRN6[cc2ZjGEiQAc2EQQZ
G@C&935+[hrE%Q#P"[AjP-THGNVRdHldU%cJhTF*LlY5F#SNjrh&TR9r'$$1UjZp
S$PTqM##NiHTSAU6RTK4-q5N&)i4+25hdXXfq)kZEFZ(ZE"6[mrpGZ*BXC#,LZBc
+PYi&a,ecKK`)ERRP+$*+&qM[kEe5Dh2k(8@j-hm1D0-GKfTNlDM@lUD!V%V!lNj
(dMq4G84@'p5r'GLmF`$#$k@YIGKpkBPd-Mf+qS90I4fiEp$*pYi1f9BqXeFE6EG
A'meR,cEDmPJNMTZ69Kq,T!@r&,AJ'dH(Kh!,dRUfGGqi'I@1(rFRd&eY&f@BX8Z
60RdMGK"edrmTX&A#!rBVEAVVrFj4`5TZ!QrpdVX%mcd-E+$!ZdHElX3DTV!(`F-
+bQa5a4&Y1Tc"rX+992%dH&LF4--0l8fiB5MX9I"Z+["1`ZYppTm9lY2J0GQBjd2
Sj@c-q!4HNcEQZa`DYpKrArMQSAh-rLI"A`QHDA[be`(crJm!)5%1G'0X6@&M8(*
[DQ9MG(-!N"E4!B!#BJ0h!*!$!3!"RD!!N!B[#`#3!iB!!!)!rj!%!`#Y0P!-X)6
[T3#3"3@H%3#3"3'RIrrArrX!N!D6%3d0$%eKBe4ME#"08d`ZZ6"PE'`J*L"6D%a
TBJ#3"`M!!*!3,`X!!F`h!*!$&[q3"%e08(*$9dP&!3#[Pr(PX)6YiJ!!!4i!!6%
D!*!$G3!!)QfB5M6Q!*!'TA)4!!LbdAJqT3$Ldi`fC,5RjQK+Ai"mIT)55NR(rQ!
RhrRBieJEr!(4ZNIl*!6+H@RGIKmki-8R!-9[k,6f!G5lBNkrLTCcYI[RD%XEcYA
ZQU-YUc9A1cT(1l[bA%fISeALZGUYfCUp2jR1V['eF45UEf%5!!!1q+X'1FM2@@C
*qAQG[4hPGVfac3TZce[V1Qmc1cHcbkm"fbYEXmkLlqhef55ihq[YK0Z%qq'Hj+"
1(Y`2ph8La@YL)kqa$5(C6q"qi6j)i1f$Qq`MQ`&M!35-[miZZpCQH1EK+EGhX`d
*lmJq-YRNf(kfm4X#j$Rb1h`bR@kc,#XQppQ@[@LZh*GCeS5[L6eKbm-lBbaEcdh
@10XkF-"e2(!!*f0k3#(LLepX@9YIc#FqYM9KA%1k)j&-qaP96N`U-0'q0ADGpqi
m*K2H0V@SH'rEPXXRX[NJ`q%M26!f8CIHI5L&-6`ZNq42F'VKP-@YcH5'42++9+)
jPFh9lHa0`*E)AP66Gc8chf&091q*ic1*j0@*(DRqr#HTIeeZIh[9rm5QrEPmUMh
HPXMP8VPZrh%VGRFdY`fN*p9`RY2N1c"bU"p0LXepGrSER`*5H$CEEA5"EaZM0YV
-YrA(LlPek-a[Q[1mpX$UY4ZfUGqdX*l4"BGD+CMjYA04`'#!eRNX,9TSaZmj%HE
qXfA09hX988"%+bChMGaMj"iVYi#d04kJNRZ#h"2PRJ4'bAfLh&2NRLVh0,P2NRZ
kh$2NRLRh,,PRbce(lVPbRbch2,P2NAZqh+I+$GLI*RHYh+I,IBEF#q4H+2HCFTm
Ppb+jcjEl(,R2PAZah1I*IElFGA*I)2F5Z5q8qb)T*AH$S,YM@5rhik5S8R8$ZpK
lbUrdTA)Z**XBcJpdZX1K*F"#j`Y[HJKQS5"6"-1*hhL9f-XIh9A%FFmL(@ISL@-
AU*mQP+"fI90YBf1m0Rj"I2(LZVIGcdSZPE1mXA%Y',+PLa,pkC!!MfIFC$r(RK$
lpjd0j@Ij2`U8`(%Z%Lm$ZXAbAaKED,fQCT'K5HGCpKBhVKYaHM(QJQ*Hp,TTF$Q
V&33jX"3A$*p!EkRYfA)l*-UbrPAZ#@Vl-,fUYKr!P64pFTkXYJI!NG4fX6bQU+e
"(P29eP`J%2BqHCbNY[qN0F6f+RR-80Ylj6&6ECq6abber8JHXl99U1NFY3(PFpA
f3(QFV,CemTLRYU3m6P(EIRNBq"IEFq9aUYTH)`rULBdDR+Df,mQM9QdrPFITbZc
ST628KJmpL)dq@+Lf+q4aTYSH+iqce,CE(UDcaAC6!@eVrTXmcP%E06KAEG4JXGV
ZNXGjMXfdqIPUSkCeDJ-$,P"E[6b@U#fK1)i0R#)1YKI*Jpl"pKCj2%KYRjE(JpA
fIAP3@b#&a"qL0[*HUMCL294YMj6(-V9"VLp4fj2Pm6#e[93HrdjYEjA(`pAf'D"
9EE!d%9%iim#Hj@UM2eHSMAcLDYXN$fU1$FUq8Qh2P-FUYGdXMm[9pLjjd+IB2Uq
BLHdRmPMMf-D$LBp3'cd[r-(BU#pBKke*(Q!10[*@IMAq1I*S90XEj8&IB+2''p3
'YK%I+!DA0kS0A+#Hf+M[P@VE*Sr0DRZ52,DSl6r,Bk[Dk+HVe2CCH6a+EG6edBj
Y![Mq',949c!+'re$MYM!Eq'0aRDp2-!3E263GVAG)Jm`&Y[Aj8&-E2pEH3G8!Jl
3SMB`DiIDk$&9GbDfbS-Efp2NX8YYj(UefX"&4$CXhj!!K`Sh%hmPM`l(0JP-8R9
X%VL684ZpmALelC&(9QhJRmSlNqJE&DdQd6GJ0EDIbB1BFLE$BIDU$Eb'ef!$8q!
Af1L"Dp6f&(NS,j`-jX'rX,eI(Np8flIN35r,-C6U@VA"6j4$RJJQJTrBk'Ib`ND
pRUSfH"9pLZd0mU#2X)(P6eFE'(#$BjX#"[`(YF&2RU%fm1C'YG'hi#FfFS#cB)-
[rNHeI8)Hce)E2"GH+@FUf!N'BU2[U3mfm"6qKBdqIjlDb1hjDRZp2&kJYY[Nm8+
er9!Hrq6BTS'Ap#mf1*A4*-3'0hL*fX!DqJiE048&b0KH*`m`%pZRj2&Ie!E2qaI
(GK+F&[c"4Uqr6'e`K[qU0[$Vj@UMPekKYRq6ab[9pR&j`1q``DIK[(+Q`b0IV6D
i)Mf&$Cj$I'cJ,r`8'hMa@V94DfU)$GbLAl"p34ld2MEi)Va$cJakm8eUSeIHV$B
i%V`2'lK#,YM!1"9BCY#VEeFEHEj$E4q4ac[9"NH%6mQC#8GrYpVJ`qp4'aJ'KQ1
$Bla2EH!QH)J0[2L!fUMl"pAf-AR!0E$"#fpeE!KXeSI8"[DMA@#$Ve)IE2#ZMkS
02N!Zf-!EX!8EZG+Rf2!"dl$pGhPm8QdSA'#&R0P`8(!9'l`A6SF0rRDlfZ!BGkL
0ZX)TX)%&k"[BU#2F%aZFK[l&pNYjI0'acB%rS30JJm0r@@e`bkqS$Flc9E@"F``
HB!0(lP3E[3&(`iB2q@,lZ6bqkGMQSX[!4l#K+AaEEI$HlkJ062fZfZ!N2@TUa0!
C9&`,DUZVhTf86lD*9YV3Y,BaQfTTh9HhNcYCRD23+4!["AZK5NH4,JFL#i%&X#'
XJ#P%&a)%8B@J3T3K$a"8L#Q%&#*+Ld)m)C`363JQa"*##C'%3%)F)G53!%E))L3
43J#aJp""X#"`%%0)#331iJCKJcJ#k"!fL"S%$@)')B1)3F!JAK!ZL"B%#f)&SB*
)36!K8C!!$NJ6K!"#K$!#@8%)3@#"6#!X))!JI#$!),"!#K%m)'`)(!JE#"S38`3
-K!X%#dJ"!JA#"))%3JeL"!)#iJ0%'B)&XB*33D3JD"!`L"3%#Z)%JB1-3C`J6"!
P#",%#%)%%B)!3A`J2*!!'JJ1a!C#!p'$c%"L)#q3!"D%084Ma'*%BK@@MDL-8!b
*4(K"I!BI%@)4(e&Q%$%3"5"'#,&!,L)+!MQLGfAk")%#`4b4(B%CdSLJM'L-k)C
`$%''r#0m)m*!cK%E)(f)64!b"(+%@84@L#d#,-)Z`Ld#,!3834,d4YK&q%)B4@"
&@)9i)k3L,##1)2!Jp%(q%8B4Va!e)*H)S!KcL$53!$l%Cm4+4%V),D)NBLHN'P%
5-4)4$RCSfile$83SV3K[L)Q)$BL-L)Z!MK4ma!4%3m4$4%+%-N4'4#0)9B3P-3!P8!M&S
i3TTUih8bBQ)YApHdZMCHZlCeHcD4h@pYkQMG9pZd1j0*bf4FBVZmYUAfYHEVNPD
LV5fGj0f4Dph@dYU@bQ(-YZChmTEKX5a4YZG5L@`5Pqfl@eT5f@fYDE%PNqRfpN4
(-kDG#GFThC&,Yk8`YLI),#R*Y#B6EGZbU4fYiZbkjIGR8[*ZEXfQNRNRGLUElH"
0(4`2eq,%00C-QK+eY+86HGF0flEf4(lRYKeYZe-dJ(K*A40YC0Lq2CI2YREX`*4
UGelE@RCh*-QM[6@AG&,052b,@R)iC@3DFT[E'8@MNfj'NXQhL1(a1@NNH@HG(XJ
P%afij9ThG#6D-,KT1`BR6E(PdfdQ(TEG*Y$qA+TMMaMbVHe8c$beYXQ1I*[DC,$
4,IRZMYCF[VPJh1HDLU&hjh-G#C22-JmBkJ34,,PV9lH$"B`M@5XSEVUMpST8@mC
Uf1b-*aP2-6BQT+aYaVSKGBdPlq@jGQY,I2fU9Ai1M5Y,jQ80qf[,16GX,6KB(X9
Aqc+aENbf98*f1PP0UpG[fL,P01r,fp,E%fedUc%hT$TfHmC'1M59GFfE@cZDdh[
a,UCdmG*(e'@bZdUjip0@cPaFr(l"h0#iZ@4f1dD0fM&BLef"H9NQNhaP)EG+N8d
R5"`r"0A)TI+lfM0e&%G(&8D11fJ&Yh-(VH#,lU!92-dGY)+$ZB0@m#jhd!Sqj3j
D`B[F35[iN5[98!ehd!V1VB0@KP[VS*AKccTSCI3'(E3bHS%1@KNY3!HY$-rA35[
$RAA3b["R(E3bI&J(V5`'8(63b[T&J3rEj+b$9MBq1QKP`eeed-U'UqUJP8dIk+#
9$Hr835ZE2Y""+a[ZU)0@0Ta2"keXDUq$9MBDJ`jDf@J+1QKPSahSS*@02U1$9MD
kL`jDfHJT1QKPSk2SS*@00U+$9MEkK`jDfI5($PVCD!XkD'@M'HLJPFe!J`jDfI5
($PV&`!99bf,dT!jDaHJ6(E5+NEm1@XAJl6TS&B0rkk"9$'c33DXB2&N(V@*`C"f
dLX'(GG!U"MESS&8-(8S(V@*S6MTS&8-ldN'V',AA3DXBfSS1@X@SX3jDa4K+d%'
V''+`$PV9J(FkD&8$MZLJP4Pkdd'V'ZUSJeCQk%d(V@V3"A63USCHed%V-`#RJeB
eD%3kD&@$hUD$9MASC6TS9B2@TB0@0HK@1QKP"Z0k"eQM2JkeTVISAc#&AUF[A'd
*EZ,V5q!,h-,ASZ!1i$Hi"%H!'i"c[Ti%rS2lp#Yi"FE6ar3iH%(rJIqq9UEpE(S
C,+12kAm`#1bRPm%T9d-$bhcG#j`$1qKKF,fU6B("[LlQDQ*J'aJ1GS20i#qi$"k
$`iU9%3#(['4dZM#8DiMHfMGHrhe4UXl5-C+)YV0+)+'-#Z[HH2e2[RRJ`+H8VdD
d(AJCA-bm"3pNaL#Q3hH&8jl`Mf`lih5KKDljF@p(*63ZcUU,QZRG'LEhd84C69&
D6h(mh,hU`MR&98)6Y,cG`fLFRQ%dFrTAC!M#6Pf6f*23I6aeel6UB(IKA,@kXAE
0mL[4%56ZK)C8GNHUG[h`&U,KQTYe)44K62hDblFNVfjYEXbQGfeZ%TQj"1Je-He
VeXEia606GG%6TA-&j+l&6ch(LF,,Uh+j,Ipq)J$@6Ihpr,NIJ!#c&1I)Z5FrGJi
j)"*eN!"G0%MIMT'&AceM,i8628#%IYH0aDbl#C0"d`hVeqZZ$qI8A,jKNbi,XH`
TRH0R)S'Z@VefTF#"VHqB[Q[d28EIBr8p6YrMpAf#[LISHk+q*qPlXVj2e2F8I8r
9pc4pRk6[kEbPN!!ce$j6hl2d29[IFr3p9pmRkhZH[Nr4phapRkV["qMl0(hAk[Y
dICqKl`AkAUM[-r9pPViA&GXU0VNdaPGSNV2eIBkqcpAhBRfITqrcLmR8R0#4fQZ
QSm6SGPfG[Lr3pa*pAkK[(3BC@&H'&(#2Q&m9mK(`+i+p2p!D$U#k3VXVXM-`J"L
2f1i,l3`Pk)",9-)jfP[X%V1GIT+(,&TFYN`'qA4!*TVY'+ilaSSYDdMPXqQpUHc
9ZGUQ[!bE*V,0,VGb4MZMcN$#E+i60B9499NKU!4`Q@iBAFC+`DC-+YRDdKTeaKC
X*XhX!4`3G@#2['Aff2@),X1"Q`8(Z[P!BHP`C*TQB+m8(+LaDYJYUkYPelCfA*h
5jB"(cj6b%J)CXUJN'ZNQ3MR(A4IKRI['6D*Z6J6%$!TY(!N`5a0*FQ3kChVhYTE
YrRa1C-9dMX`04!"N'"0@k5jfL35Seq(YjfCpKb%CC[6"[(XQMb)$-[PGk6UY"eI
-L`X+,5Y9C-M3'L2h@,RCq6aHlK2NRL$h4,NRb6eClK2PRL,h9,QRbAf5h02PRLR
h,,PRbce(lVPbRbch2,P2NAZqh+I+r3#j6j1l9Zl6j6j$lJ9b,j6l6,R2NRZ4h'I
,IBlFjmUp@1lcj$jIlMUj,j!!HiRF&jVKNjKXqA'AfNHqR*Q,iZ[V9bkUA95rI10
bH6DZMQr896a4+FF9P'511`T!8(,hE*914*fJT#Zd)Re1a*@J&$dKbd3c(+-Z4!P
)1,qAHCb*Eef'&l8c`qaY+&Lf3JC4C5PXd@0PFfXql6ZX5RINLqD'eBe0YI&dFqV
b9%I&c9%AC'9Q4kUYiX['$pN-klYPiir+C"j6Hp$PB(lUZ6Q4lC!!jDXjhc@aSc9
C'dpNDXe5%`RHRT(0XRi0#b&8!+Qk$PDS8Y$9'fVACf3eDqXeT96BUe,0)Kl[bN"
fQ'i3Z1bZe,kP&aqX2PjGPF1T1e[eU&fj,jp0q'd5hjh,TpYV(j(D[cHGEIBpPbH
6+HQE4YQBklZYf0hDeYbG"c*5I@Z1p6(Yfm[&+bT-CDIZ-MNl9JmfJ10iX-hMUaV
-5YC#TCh0V!Gc8-q$54L5dY9HH2@9Y$L&9AD5CE!9MqjH01YeZjTI0Zp@UpD8hTe
0TTS5,5P**GA5f8,G9GZBN!$&22RDTP3qheRP9C*CE8-LNc&q,L)BVl@bD,L%ILL
$cSUI5TN-R-RHRibXrZRdZV+KY!'i'eYmjc+mq*jG&I5Gbd8XZCD4bIFXG8V&XGc
L&@qhbbYqAPZA#Yi*Apfq"I!Tq5U)q6jP0Z&lPMU`bl'R-$hYHE$,IIFZ)$hSh&[
1%Ta@(!IEc3I9LTr"e5kRDUR,k1TlPJ(@pkc`,Yqh4,dUMY9bq35XF`Gf&b*@r%Z
J@('Zi',&[`b0&Hm51PDFIB#XqTDDYKT!'k(U1Y!,CE$XGIF!TX[GJFb+@`Ne+mi
qF2EipTI+KFq+AcH#9L*83,62Ik$-2T4@I3meCK&3UkjJDSpIAaH8N!#eiP`#eiT
c*lj@h(f)VIVfeE#NG(3ZfHVQRT8!CIjCmHlLS*8!R6bdiPlQSKA[%KqY1TG*8M@
#bcbU[S00dFP2Hrd,T+l,AhPUaDr-95[H*ElDica3-)qh9K`2FYG+L#lqfKGJX0`
P(PYe(Qj6Rmp@I3fRlA(XEiFbYkeiPrPYaE[#F5[q*CjEGHi[C4m-kdKB!-4ZL(i
SG[f(`0J0-3$(ES"q3(Epqb$CGqr[GMp'Gj2ihN'E$%"c18)9VE`)AI$XH[B$Y1[
I"p%Ppk(L(B4Ter838,Y"KU#k-d43rMkipYh$&Zk&E0ql%l4,VS-0dJrFVRmrG,[
qJq$Y4ZL$EpppX,#$%$i#h`&dMm$f)FJ1i(S)UN1B(S6S)AJHKZCK@1k&j!#1Kk!
iJ1%q#"k&ha(S(B(G)FJ0iAB3D[YJGJKL!hJ0S(8B9SFJG4"1qk&d4*)+"+N41HU
3!"J95&&$3P3S3`f+8%-5e,!!05`rpBT2JI3d*$`&XP1Ik$3U1Bd)6L0bdj!!f"4
+6B0#8jr-0#3b"4*6)$!0bdY$iY+JY&34PL+5Ml1Ef-a)bl$d1"Ci4-,Y*KiEJEH
E'-%R-QdhXGR$%9fhQpKKK+fTk,69a!iI-2T!40b1DVBU*DVr$K-eFp`rUH'H@P6
@Q$Z4rpZ5RcqV[m@kr[1eeK2[@$L6IcfG(pYMcGRCh-D["plDY(($!ZQecc5XA,I
*rG-ATrpLcrqCqi0RGm5Hrk[5TVhBm`ki2`85FA"kDaTGFS`Z0[L["P%qrq`3+EH
SPXA,mQ6K-NIrYlY`D[Ml@5F1)9M+(-Ba[m&e1!iE!eRZ(-CKBSB&d'%F0Jqb*$U
-!ipQNA3BK`f',*X1il$PN!#&e'%F0L'bY$U-`lC%&PZ(FGLSb2,V-!jE&eQ3!"h
'B6-M5l6$1'a[C0&f')F0Mc-1af%,*%Zl`cKXLQ5aGaL(6C)XrJlMX'f5jH"K($C
5XN!mM-2@5TD-Kh(BE-NLmM!1fbpC9Kl'B8-Q#mh$1'c4C1Pj')G0Qba'$q1`MC2
Pk@%F0RDbB$f-`eC2PV#(F9"H@03HaQ%l+-[F`cKX%'AKHaL(,D-XK3rMX)Q8aI&
K(,D9XP`qM-0'8aE3Kh'JV5bT$q1`'C9&pQ%FmjZ&Kq1`BC@&q'%FYV#b0$q-`kC
@&ZZ(FGMQb[,p-!iEAbrYMq-Hm@FVl'@(ik!#,MmFKqfb+`l(iBqJiSIMm,Z0km-
irb!pR(mN%#E"12b5qFD9@cE@EHrr*8rRP2jaZqqB2(EQfrQ&q$mIjNC-(VZ'-8h
q%hX8p8`H)lrH`MpjK`FU%FB)km%[@9c9QY'rBrjEAC[65IkL13+Jll1jl(hr`cf
5"kFZbCp!r+fZ*Sm4BRY[(T%Q[h"NeNJ0MZcClZL$rX&brmLH(bFBfI2M"#0lITa
JC-q2%icXqA'#N6dr6M#bjmF*4[Em1-()RKmR'0Rci`3MHhkFB'62Ma1-l2PaJT%
p2di`XZI(#8Efr$M"b*iIKap!iAqG`MM"D*mI*aMYmq-%SheqR'#dcim6M2EjFB,
42Mp1-0VRa`P'qr`i`@LI(bFBlI2M"+0pITaJY-q2%icfqA'#d6ir6M$DjmF*4[[
m1-&SRamR'1hci`5MIAkFB,62Ma1-p[PaJY%q2di`fZI(#8Elr$M"D*mI*aMYmq2
F1pSRA[H1pSRA[D0piRA[D*pih6[D&q&rBYD8dGq@R'Gq!r[i3H&GRXRm4G6hmQK
S@-XrrKmkXZQZGR8l)aj8YMG'3q2D85AphM`faqZM!HUkS@P$AiDrcm1Ga%MQFMq
el&mh@p-qdZ`&'$[Ef+U6'2B0kme38Zc(Yj1'NmH)YLp+ZV-8IU!lh$`@`r!M!I)
B,XM[mKLHI2YrHB56"[IPNGVRj1%5I2Zbkfjarh+aaRkLYG#qBFeYP[fMqCGGpj+
*pR@aci[p*fimq`B[Mq%"R0&kH*-c)i1"NSHZbamXV*1(r00!4%!Hb819$HYkA6'
2!)Q1jT'ek-1Q'ppVqR(VdJrC'kFHm*!!G#X63IBkHpeEfZb'@jE3T1,r'iPcUlA
4rZJCCPc)j*'cGJBil@clY`a3HpPei[5@q2T4(N1-950-*RTL)LLhXfhdGrAPh`P
'q9NZ[cXL)!p1R66*AqV+C1ISIae'Ic"ZU@a[M$m`lX%m)J-BprS9DqkHb@[F2&U
2L!rQ2P$92c$hd6b1-2I42)i`pl[cZ)qjKhNBj[lcQq3@c+jjKB`*1-cGr+#p`p`
IqI3LFfm5Zq(V6ZGkHIb@ZII9idr-IE#`[fIZB4j(Q(YI'RpNlQ%HRFcpdPRh-IG
,CeDBHfU(0B66$!@E(aATBHjh'Tb1r'$F&bqpZMI'(aMh3"kFL!$',6mrmX#,DSY
r-Y*j6VbI-@eCHR&rM2XCdfJH4jM1hARFah6#2$*@1YPfmh1Xf$[1YQCYIk1iEE2
hLRh@[*[&GRf"%8LMLF1UpB*iHfrqS2(IpGTA&r)3CK%4N!$(%@E49pFr-SX`Ma%
3PMc-6lJ%-C`m8MPVmH)"CN%5UCb#TpL"XiS#i#(R8"iqKF0FcZ21alPE51VDL[p
EI2!8&4ZRBIZ42,fpm`GNbfIppPfMH8`bP'VSGfLR'1eX`cP6l"[@$9Eqi2%VlfP
RN3"ja0YNSi'cf'!J$hFI3D$b'XdV%U!H4UZ+"-M$eDU#2)jU9@EIab!MN!!TjUH
GGB8bJ*PEAe&Q"1pK*V5ilf1`([IdQ@S%VCQKIN8M'16f6KjQh`H,+)lh[G%))J(
ke@J%N3"j'#4hpR6mYDiQ$rCd(1q2#3dMrpXq2Ejf8j13!+&8bl(+XeE$U1#3!+U
K2+VUG4H5Si*(!Z4Ke'YTaGa3(KAeZXS99IXBcU06A4[-3jKd4%!H3PdM![*Sbaf
UKka4+IppDMN2MpZ,&K-98!r4BU)"mK!i#r))mDb3!)GS"-Ibm&6RR9EZ,rMUe50
M)FB%r9&5R3Ik!idT)L!2dCL1p@ZRaK3&N!"(2QIp[FmQ&ArkYLIJ4'8%GpNr[[(
E9ZbY@kaCGel[HFpqbPY,&5-EXI1`Ira--dm6Zf3Z[,h!##)#mK"'%"'3!)FJH94
!(TQ)J,VZY$+CBhN8jMi%UBlPdBP8Imf$8jFBaSq9rN5LjP,)BrXGAKlT+)!m*K9
r$Dd(mFBEeE$K-kq[HGQfbi`+0Ir"$r+mjhppi2r'**iTe*L9@r+HDKJ*N!#(8HN
L!I*`9ESJMkT+9mKM0@XYA9AX8$fU@r!UH4J9+K+JVQC5jAJH[+GZf*R)j0,0qr[
jd&`('@jrH&3!-N3"j1'T8%0j9,F@9$V48k(qRJHkG#4!A4h%L`,)`d8m)6&(%Br
5pL"H8LCHKZT4R4E[c8-B984!(X+")`,b%!iF&C!!4bBLS+l-8"j(FSp,(kY(L8X
Ibk165dF"j*%eUYJKjL9V!Ja3(qUch(!HZQhJ8"jQfi#-1J9j9,F092)`F`ddrR'
m0i`b%L!2`bLGKKhXMi0E!LTe0E12N3"jF)`kHkbZ6(#Y5hIdDKlZX4XD'NIffpj
pc(c%b&S$kj6SYld'`6Qk'cTLDDr"hdl%dPk$61E3,S'`VN@YiG#jCpHjYarKq)N
!fBr3"b"rh)m`J044!IX4`[%)RBq)"1LJk!$Q(P("6#-"N!!c@J'TlMRKFXJ)%%d
R`Q8lC(!L#,5Bk+$YN!$(6X65GXLM@Na[)P%%@Xa`$*hl1(5LYlC-KLZ[V'Rh-lL
Kc6lh-lM42)i`Z0%mMM#iZr1iMm'&HIb@HIAPm5IQ09L3!0mcVc#2)mbV,idr-Ur
42(l,[(S6L5MBj69d+VZmqNmd!#-`H84+l2)+9hPC*d92D)[ap6F0E5VdN!"Kp0p
Lc%k`5)!meZc+YY6*rCHk`L`L6M6+D-Kr#IU(bI!r'mEFYI8*-SPlQJcZ@ZfjI"%
"aYbe@9lM(Q0CNr%X!Y@BZlE)eTiC(a8,RKf9R'TH+SqcaE29MhQPc!l2F@0+RM8
rp#SJQiP2`I-k*mq#jjDjPP8V1'$M+AQkRRV1PRYb*L[lTUEGqQDaZAmSB&R-)bp
a2"mp4fba!L$)[FEaA2)0LZ9j[PlZ%ac2Lcp$qTlRf`&)ar2"+m8feR@d*mVMBXG
crjYS&mm6%+Yc2+qG,EEaRLIpSRQqCbBfch02`E2Pkf+Ei(NqLASiRX[ALBfm(Fq
R&$cIqN+a6I)mRbk2'ah2P9qL8ec2Q"!(qjQ1jbAI%SF6AFqaTmTMRZ0j)eJ!a6"
Rh'Tjc(3mEB"XPZXjrF1568clKL%Yk8VTGQ%"mB9LRGZHci%GfT[5dmqaV1F,JCT
m3R[HF&r2mbVTK*S2LHQfpRaEZY62q$p6(P-N*UMLaG`U(A3kf,'N2EqMM"fbMIA
-RdZecf[2j#4QdI24dTULk0LrEPbEbe[6fUQkfG4Sr&pF3+p#c#X&mGEq5')q5#S
!GRX9f#!B21D@BU89D`3rC9[N%pj@V,6RZ98%P5@,LYQiRJZq*6,2Q+m@+qh&[2+
edP%2%p1(Y6X+Q%BA#NjVjpDIqJbaQ9fdR&f#lC-[-jla2C[%i9pGce@##,&Qar0
5UBEeEklRc9,6q%l(mdA-r,r'kiiIH(J6ra@bN!"84F(i$(V!mIcZR@*lR9HE[5#
@irNcYL5"Y%l-C96DmG`26Vr"mla#(KpekRR4Xm8Q[H5FFkE)BkN6mbD`%0ae2''
-$Kq)[ffEf1!%jP`KpE5rjRMH$SkmaBZjS4$c&qm4QpRFC$`Ikb&ir&U`9$VC1AX
NYc%1KiLrJ$qGJ"miq%N0RHkSA`!lHBHAM@aKYlBlRX[SlhHkRS[I9DMRZbi5'hB
RjPeJXq2j[(m4flXpcepjD"brjFGLSh,QR$Zed'[ASCbmer8mMhlmX&1"'RM(qec
20@ZN1fBl-4ZH*3l[Gch2IcaC1jk[HkMB2Z"9l@FH`iVrXm5h2ZKkAL2i%Y11qKC
+(0MS91"dH5ad2,ra'l(GkRR#UV4Uc9[%"JX`ja&`MHFkRMqJ!X)fR,2LP4k6LjX
YFKra-%T`fXA#HI2!%GIc`UG+QNk[e9mU0ZYMVZFPdN'+KI82T2khZClIqdS"#jm
%@RcFkhCiS',KEA#G6hLH$r'`X(iP+24*ca01je5k[RDTf$lPHFVQ@"F,hrNraIC
Tca0XGl!`rJA3$REU)1Z62HbSEi6*hHlaY38&A2Zr+&phZ*i2&ckJ@&Kr&5cZXel
-#`SaVbIQjca81EQ!K@m'p6r[HYiN(-A&`TDALm-A[+V0+(6(8q%GAr5bZGc$`RL
+[S'G1Tj`%mA#&"cRbejY,LPJiD[TI1P+MING$`[V,`)G3&HR1d"5lE@PF2#[H6(
rMiH&m64L(Rc&R%Yrk@&KrCAJ#$cFR18JUf,KFd%me!-([HKFaF,pF*e[ZTi!X)Z
&Yp$Yp+J6mpS#&MiG$H,ERLGGT&9VqPpLSlj1"8!HaF)XUYCh25am9!%,hrN#3-Z
brMm!$3d28N9"4%e&,R"bEfTPBh4cE#!Q)&0S6'PL!*!(1mB!N!m"U18!!G(0!*!
$&[q3"&4&@&4"6%C"!3#[f%,pX)6`$!!!!CS!!!YU!*!$T3!!")%fNF*0!*!'CE%
4!!JFe"b#'($`eCIG05NKdCrNL`SqJ+E)6!pi)*68-j63U8d#!UAH950UIVlBrG4
l@Vd0N!"hJ02kPZrDRLEK1C`6`#03`H[RM+4`Z1Aj6J#9Vp$lmDqrI9S&L0dfabQ
YLkVT6TB$UN%jcd32RXA[h(jUIS$FZfBMU@,Z+AP6r-hpHPDq`P'SFer%hk09+dH
6r)&J9iIlBUE1Z4*qLY(F-IHFNQB"#djAmJ!%'F#FF(+EE8U1KSmI'A$###-66PX
*Tq3S2qAd#&rMK&eN`JR!#V!#V+Idm1I&!3Edq%V3a`Nk1%%k8&hIGFDTK*2M*q'
%45DF(#I(bA%bi8H3!-!T@F-,p(CpTH@be9ARhE9@-G"c)F5C$G%R&BfcJ9E1Nh*
YCaTMeh5PQ[`LeTV1TDU%1$8q4()VNNec6"ZAU*8E@KQl*"0*bf!dj"aG*mJXhCe
YR&`1qXC'&fTaUhf!@AE"$f&bHR9$`5@[0%Q[DR1V+k+c5%TD@QK%N!$J6mDA3Na
@XAXjRH+r+L6Eb%@S%0Hd5iYTK)p@ULN5AA%bRKVREMK''@(8"15K8UYYc,R9mPB
63&M)4E0"R"jSE#MC+,eH#Ji'KPj8(ih")))%90*UT6P4q1Na3Ml0%V%MdQal6,S
5hm$SR@&8%,E#ik#2i68iXTTGZ$dMb-Ci26L1AQIEST8hH*6`NN@8@fU#Ha#B%GT
dB1LcYeHJX`326rCCT"[VlUM'EhB*D@#3!2-*ZPR4mbfLi+6i&f0bp-KS534p!FU
I"@U6UR[Bi9TFe6S`Z5@IN3V63*(VBiE%hNM[$EjGHNFIJfjSEXKBe55NbE*#,P!
kFF0a,C*T!$c06XmrHI(&I4JSL`qb1!b2,DDrlpJ`#i--5jPH9-%!*YU$@bNr`R0
iB+l,ib%+TV53!0NeNR((CrCK22YFSKm$@pXlUbV%2h-f!Yb!GJ)rA*RRmpI9Mf#
&V3(8R#Cir3NUb0"VXr$5'i#5q855cV06r!VSlrr#TPfi*P!+h'TXiF21bh8VUG@
UPYD%&R&bj`cY8N$+C58QNdPfXH)+,l%6bQkYi4AX[K`&j"&A@"mNA9l1%#@Ej5q
2%Cjm16qM'Id[Zm[Uml1,Vpp5-m4DMDi@$kiBkq,U%I#rA%dQ!Qj'J$*aQEHKJ"6
!"1p!UdqCZiLjlPI(&VlU`0V2G%`BMDj62a6Kc@!B2faT(Q8d+Q05NYS88552N!"
r&f8+(N49F6U[)BXipU+KjT&bF,SX6Yq,2MR94`c$S-Pr@ee*TbGAJh+[LZSJG$j
,kUCKlVD5!hTpjGf#,TI`Iq%ll#BICI8$H1qjQjZfDiVm8l`lqJ*E'pN,GDrEbci
*Ef(D#B1rXMlZ6Em$DLFm-2KE9'(,r%jii"!2YMMmJQ+@,5e)iYA&bEIh1$kb+1Q
99$GVcb2kqBA&f2dA[j%LZ2dE*"$i!0+Jr`G,J""D82b(#JM,$Rk$mUD,"bckLZV
Vk)5PjPN+)`alM[[UQ"I$B4S3AdMDC)d#aKKLGbE@CEIX6&c-6eLQFaEEX-rN9lc
bj0VRa4#9R-[ZfPI`1eRQCj!!lFIcRmUPri[bSI2j5N5c0aM[jHM$KjNmPS11UD1
PlM3fYP8mC'AVqRAD*pe[6E&A`E@!YaJ-81U1F@()m`ac,8UVF#8ajCEKS$P!1MD
Fk#(',39AQA`HZCISMH0e2rDmrLlKX$,%bIlchKFj3a`0Z!`LrErF)iCa[3GN@`Y
('2fIQjE1l,U@VEJfE39*I2T8fc@ITIJNp4m!N!-0%&4ME'&`F'aPFf0bDA"d,VN
J*L"6D%aTBJ#3"`Gm!*!2!F`h!!(TaJ#3!aErN!4069"b3eG*43%!VpP[Pl#%ldN
!N!EYrJ#3"KH*!*!$DJ#3"T1b$Z[RpGR%Dl+`cXfZGAXjmPGqpJXrSpZ,EGV+*Pl
+UCaqClR2@#YENrh+EThXpGZH,FHAiiZaC5*K1hk4ECe2GPlfjN8@[KMEK*-G@6a
bLjIQ)YQphj(&b('bm'AL'GQ56IDjX*EMC,'"f6'J!cMaecIT(16CfHFeb(fakmN
Yj"Bl4YM#!0J#3!$1L9pH1*Q-14`1&qjV()jRrXAKq*VAiDMk'pMh12(S2TE,C4+
6jl@ibm5f&EGEE2IKpSMYREM,aIC4h"9Lqa,Z5V&p!rFd5C2j9)RYeAK-&pXU2'D
)E4-H-mAfCMaQL@dr(V2&pK%mUXAfD6aUa2B921D)l4!HFlA0Y352H@+l$BrjBVX
EM`9Lbq$a3f*l'ai,aIBK2#i4ffI`Z&4XIih()QdV)hjH*EE,m9JXYR9i-(IDGJQ
qD2Xj2)"(CIX02)J&fSJEaUIYlr#i3Y[Fa-0Va(B$(PH+V3@2Um5@`10UX6fXFDp
X[ih(Y@,l8cbZ%pYcH#c90JmaXdaXYq#aA'c%[8pX$q"a[GJqJ!IV30ZRm&JKYUI
aZ&&Xhm(M*QdV*djZ&Y[YH2b`f%*i-&rDIK+2@m9'I+m8farM3Fc54Nc8DPX&HB%
F44YcBekdYH*aKpJkm(LGf0k$"hQ'YYr$ir9Lq`XmkX6fEhLXeVC+iYN[0ZD`4Qa
[`'1Yf0k+"c&1fiIa@#qf,q#a3@bX@Eff65-I0BL0f0JSYL!HM@)Mj`A%4Rkp8f`
Iak0*E%rK`CLdr4-HGfPE&6QV@@c%$rQ"YMBmL![DL!Pb,'h[aQ1cf*JIip$fC6b
fL1dIm5"2NUl*Qq3%fXJ,a!*YV0FEaEB(Mh[%4KjpNpKq$BpYB[Xm([H+lCYiN!!
(+!'S!ED,M6`9&K[cDaIEEM`LBYZ(a`kar3SH1m9'RLEIdNC0%"8YBUBja!Re((8
Fp4Ye'r8-p4je'r@Dk$5P"iP4kK(b,r8BG4Me&c8%qBdkLca"A88p48kLIU+Z*)q
6[mREPJiJ6j'[bE(NCh)jG3$jQEa-2LB2Nhr*Zq4EmLcjPEa+2L@2NMr*%p36j$h
b(AQ1r%EH*#q5hmKVj$2b+RQ6I%BH)hq4YmKAj#Rb%hQ*I%3H)[q3!(I)0q3CmLr
e((8Fp4Ye'h81p4je'r8DG4Ve)[8JG4Ve'A8Cp4MjMIU,ZSYkLha+I89G46e&(8@
0),V5B($)M3m"eLq)T1lRbYC`,*4+a5+CF$UDbMV@4G1CV,FPXM-H5@3GY5&IXL2
VD)aZppE(8mPdeR[,bSf13,#YB&iGLX@5bB4h3b5@FJ6D[2lVr8ZAkN"YhQ!S%`l
&P,8jmS!MZ(CG)A4Y)*,H'I%f)FHZ1V6X3XlG2[jeJ9Y@lZPf#JEpMQ`i&JL&%6!
G5ZreKFAHe&,AD8XlkKLf4B9PG[@*E#5p)a51d"J)C9A+JCC'Eh0()KZ04j!!QQp
0Bk0b8I832emq(SVSA4HkjZESYTAYefT(4!Zd55JiU+S"#Ye*D$F9-BmZ9Y0'N!!
B"8'diUl,a"eEr%hVE"JT[abUD!C#0"LLNBc[%ij8+[`K!BHM&Vl,@GJB%JHDZKc
KS"`C%AB03RUZp0h!S*PG-8EGf1XXe96qfN2Ea$eRl%*Z[emK&d'CGZN'fY(-lEa
3bAJbQqaMN9c!bB,daI+f*$[5iBLMC@mQ'iPlEEJaM%C'S'dEE(R+f4!*Y8I5[P4
Bj+XjiP!48X%G9L28K&iR!eKG3DZE5(9SG41TJ+aZ)T@4e8fN`V(L8ZPCh83U0UZ
E5'9QG41TrU@Ek'$(5lU*MJIc+[9R4DAb[%r8+Xr(4,AbI&EU`m0ZKh36(AmVDTE
R@k*UHGM0NQkLNh@4EU+618Jhd8N&+0e%*a@XG"1G9)V56A4518ShdFRZNA36RHm
3p8MEqh-iFciQf+(YF9'AY$dTkT-feNqkLFjR4)h5GP"8+@hXE%NhdFAk56I4a6T
+0p(&Z0*0G&'"5MI44@8Zh83A&E0d%ee8bp*0G"'AdNedXDl56A6p%Kl56A4p!Jr
T*VVBeC0ZSSYG3qNQZPJrk5Dk[SZ(G"2,L$hT*TDa&Y*0,'0YT*YB4Xk3!'jL'9@
qG"-0#iGi)iE)Hq3QBSki)QD)*f+0059@L"eb$IQ2R%QZ)8H5(iJ0eTam3Lb4,mN
R9RH&I%+Z*(m3cq31eTlF5)iJ(a$Mj"&b*r&#h&LG"SYlbC2%(MQ5Z#1(NPF+h4h
L5cKSiNMRTL`V&(m8Jmc6kb*-UPRc(fHhr[#,+"T@(TDhUH(NXLIqL(9,Sa#A9Y@
)C`+"',GdLhQJ$00acm3p#rGX)JVh$0b9Z#Y`9q&f1j`S#@kqG'!A2FV+q(+2BG"
5CIQMNXMP9)'AZT6R0-Pa"VSU@Y&QI&1#eP+)1VFFYT(rl)E3@d,q@#L63E[LJ@L
U*r6@qU#hS@ic1iB@p[+PmV$),(Had%H,h&9DJ0bMqedr1+Y`kS*"0#bG$fe"kqh
#B6kfFC2c%HFdeipdel%R5i",9jAFj!4Bb%f+X+e@TUh+V9kQl8!*Sf5IjD#kQZ3
KMiBXHC!!r'laA4mA@YeQmUDPeFd"Kpq-AUSR3PC*qH`ZVBkJZFcTZ(5`9m0H@Mq
A+3,6+4@iV-"-MR*KPKbrp"+VCFi6Up1aH,!BdNGmX4KRL,@cG%#-VP`2CkZkj5a
P,UPQ2ZeCZ5S$GjZ#pEj81V)MH[mJRZ9PSd2J3MjC)6@"4d%mX+0Y"bF2,,8D6X8
iK(Y0,Kq6Jl3dj*p+KrZ5i8m,a`r#0jk1GZ`FDd6SNeG@e,5jlcdrb&Ue8e3RDdh
MqLhK2G(fB$UjZkd&fVcm#30!AEGYbf4$kIrYq&`i&+@U@AVm[0`Y-aiJm,r9rTQ
Ukck59hAiDR#lFAY`6mGGKEXFG`AZ5YbcF&IMRXeB1HYJNm4ZPNPRPjiZ0,R4f*!
!cmJ'Yb0p1CF*MJHJ"p$VR+kqNAU9RSSQpN65Cr1BfrI"Y604ma[6J'8mGbB6-J(
KD)a!)2J5pI3HIX"R'`(r9SHCV%CrC$Prq0@HAaR-!(RiQrCc!XAS`ApT&RBdKMq
@i83B!d!H$E[61hbicp@9Rr!#EAkC3()H(mdYc32r9FlQdETf5kY[HqP69qHIrm'
MmYL9MCm$2r'KmYKG3Z-8AP8HBpc*'3AMKaff#ra""YiD6FQ%QI0eE8q'1IR&!)$
lG#BY8eR1jm(MJpJGBGQTZUSmMR3iAmT$#hF1%"L81i[-%dSR%'L8@8A$ThXQad$
PJid6$(-m$f1!3QPDhA#-1EZ'Lr3I3iA5'H21cX%SShNXPGrf&r)S&H4d(U-%r2d
maTRm4"k4qdX&Q6aDQCl(Uke-akV4031R@)p8D,3VF6U2dS#4mEVbfk59a`J6RFi
M0DT1aqYUjf%%81iUMda%CSRpcc&2+1kTRelGNjIk6bEEB3M)JmF(N!#FUbY(Uq4
ElJ0"+X`6bYe3S8b0!-aT9Q#UUD1C!4rdc58pRD1c"elUk3cRB6ET1TrUa3bKif`
[CL+2NlfBL6a1pQ+1jA'L&c1HKhQK&c0BMeGk-F1&2G1,'FrMC#pQ-)fAHc%6HCc
Ua3`NBL,SaC4Lb,c$dF0KL11jpJj-2(+-(cfG)5)kfp-T-ViTS+GM$"QcC!qGX51
B!-TJJ$N'L'N-HJD!XrZ[l[IQEZKM6pm`$8a0+-eP-S0-``#VMQZ$![F,,q-chCE
I0b%`3eiPp'N%$TrL&!Re2V$[H8b`R[PX6a+G%kT-ENG0@bp3ZC+60aeBq1jl$ah
k-fXbVCRYF0UR24G(XF+b!rX1AR[Sd'1RTq@Bb!lR'(9TKD@D&6iTNkZ0E+HXHZ)
691R8(0kNS1XBi#E5U1R5Q&jZ6djeGID[E%8#I`kcA6JCKa1%,jQ-`bQrQ#)ZITa
M2&!I6KPH2TN2TaEl"LI+rN3q$LI0cCh-Ke291C&EmKRSrX1IdpBR*Xr#Ra2CEjf
-`kp1R!)q'XFJI-TGr-X"R9fIL'DMS9MdJFLkG%M[4R,Ur0qI#TerDb3GMbC#f9I
59hm5A'S#YKXI*6"Qh"JhfG*C@lXcNSLNSf&M'b%S(LJcb%diGGAUIR*,4iSrJ@Y
PZ`Z6'MXi$i%(U!F#N@`kH9mN[5IMEFQ'%ZfKG,YXZ,1hPRX-qI8V'BmR%lA"MZf
aD0KER`M(1YSMCM#k8(V!r5)23$8Bb8M!iJ%2qd5eJ@3kXLk+Rd,H&EkEI6HCeMS
'LJFUlIpQa8'UT61[Ijf[3U)'Z!RSDPZK`R&LhDAZIiSVI,*4P$RP'%"qS"$'eXC
I4VF6D+PI@k1@VNY%XYkepkGLk#UF&C(eQ$M(X*Jm9pU6`'"fMZabCB3j*Sr"55j
-K90$Yd``%p6QAHe[@V2fDZr9DqTDkr!-e[YEC9-lBp-aQ8hjZiK!k%GKrF)&JhZ
%@XFmX)cALfGmC19raH9#K@TIZkkUerSl-YPNh,XaX[HqC,TGE8*DF+m,Kb1C$1C
,ChIeqVD'X1%"Yil0CU1*REhZr(Q'EiDT9*rckSjSV"hXR8eMCRHh,lmUqC2YNI@
44*rVQQL'Dh6&YmG!qdImjCI6%8q1FSf%HjD@VG9$Z2%a0S@+p3E@hQfKG++[MV,
IAlGAIE1h+B9pBI(YScFIYF%20[Y+p@j2Ued(Lk4m0`Gkh2+l0J#NL8LX*i"-"Mp
DAA%r@Pj1+4Z%)Pe(S*JIF(E%%l1Vqpd'LUmRLJm8'&2,MeCAEHXdaR!k4T(QG)!
5eqNB)i5R)a4C6`FBTVkFIa&dZ5$pb-Zj$q"-m$*#Ki83Jk3K)IU)8EX@f9%('+E
)[2p)#3I)8[Z1-kD18U,0cKLM-"JQd*cr"+#(U$6RITK2mlj&T"5C93FSdU[q#MV
'Va+N5,!5SF5`%Q5%BL9%N@-P`M$*jJ-83CQ2dSr+[2m!p#cJM""YCia"LV&Lp&'
Yq"Dj9L)-NfdK`'JK"qK@R-Ij9X+8#,FV5!N1`j5E$h!-hN1NQrFrc,S&ja()&(P
A)K5*&m((@*F4LT4,pa,I-X))fG+rb,4d(kCCblX)3LY%2`)Yj`'%+A5-8'XZ`##
4U!"pT%V()U25ICK1EHrKXJd3+6h(@C3a5K5DMe!Xqc"j@YjMS"fL6F[j-'IDRN1
i+,)Ph6ZT8V,`+[CUM'B-$cp@c*5R['qG"I2,Y)E1$kekqhLSLMABlb+"K6f0%lZ
I'`q1qH9$+qLaDhjfepaTqc-T[$LI06GhHMJ1[lr2Qic$rihc*q0`([H#b6M(jh%
M$ZGaAmGLUTL$FlEKaARF0dcQVEB9(jphM6LFRcdaCaYa1$plBXkffKeeFXifiR!
1q)hMG65i(M*J@A068f["U@apmbDe#4"Ye5el-pP)A1B+4L2F#+PbAAhM@QSRHA[
NA5l[#RQV10`p30k@[5UIS1Y5p#-NZleH$$(dYZb+B6dZYLEKVP*$b1Q58T@m,IX
XH8r,Tq5FLC5D@ZUmQ@4(1QaRJ9UA5E6CmUk4GlAiikpS(b$Fa`'"+LP!i$h$f!!
)q-f8pb3J%-99H&X!J9h"LS!31rEc9CP`crh1"G32Vk#ZpZh2a6Lc56!ci,lm24[
R-cjhi9HlS4H3!$Q`#j!!%H0clhrLi[M'5aFp#K1mZYCdU,VSI9M6SIbLG@&0KfR
iUX922dHrVKDqeTUR[LCcpE!9NhQEEVmFQi,143A#CdrccB`SimXa`L`p`4BHQjK
US-@VF9p1Jc8#i`VFVbNiA)Rl+S5XXLCLU"%CK3K(aQLB8Q"ahIGJBCEMB+I$FfF
b8@T41!1"i%XV6r8HI0&`U0QX)aY8eHJeAFiIlT!!AJH0E3E)`pqd[h04Ulk$hH&
Cf0%BrPKQE12h%hNdl%l[m1%q9eF1JJZdqGHB!I$4h0*Fh*VpG"jU*rVYT4Q4Ud1
a@$+Cm'k)a)Dfh9Gjl-V'ci(IhUPrG`Q08hJe"qb-[l8qk,h!(f6JVG(8a-li8h8
e6qb-cq0$Dff%CDIUU[*i)$V%,kIbQ&JBEC&j3ZN%!SfVaq2JEkfe,6p+1eMjB1-
%`ac2`aLJ8*T@0aaMcQ$E4$d-&8TRM$["9(T)qe"9V6b@,M8&j&%Ub1Nm4JRiqhQ
--rQ*22#Ci`,fY6)pMeGEQBj9!hR)Q2VK`ZSmX(@!)5#2m'KPaq[+JAY@(L0-G$U
2e+Jk(DqVRBF43,QV2$+4R4Ii`cbKZ+FQ2f*2J3PGPFPf'!,bi2%"*1IUbV'Hq5d
4"S*8Q#H8Zk&#Q4S"Q01X`&46Cf,TG20(6qI`(Za@jFrdG)Ec-*YdR8reBSE3FEB
A-j((b9l-4"iRHc((mMM4LaR2`lc3LaQXabZpQ1(#RZR&M1GaXKFcQ-E,[CL*2%l
eBJB5-4(dBNSap*iNT4KEr%d6HSJal+l&)%D-(cfG)5)kfp-T-ViTS+GcXG6bbme
pX'fH`j&p'eNlRXRQQF4pX*AIBM!5X*bHHGAY2VMP)r##TiZHLCkm+Z(TZ!DHd8,
-Zc&![a)TZbA2XQpBRP[r(Y2Fh`)2b62RH4F@[jS06kINQI2FXK,6lTrKE-*i9R8
%C#SKUSBFUq(TH!LHC,5F*hilc'$4&mDcQAa-I@C3'ma#6&E0MYRf2Nccj`Mj'I&
X,0N6XaUeX5UGVmdMk&2m!Y#a,*l+G(VH$86jR`"feX@c1r19eQF1jlTHQNT(GMJ
mdcKLIj(PHGPQ42FU6rH$C'"l)kXV8!&AZijCa9f$&eZH9ci0K$bV24qm(3j,l$`
E@!cYZIGjTQGlhNPdk$`r1`Ffqhr)(2kVUp)alrN(f$KK8RY5jFh5-ErpUl#TZC-
mYh0CpXrTQ*Fraf,C-Am-MjADFqX"f04S5ZAj1m5D92V0,+2PHFG2!ha2kjM,bBT
Af6'"+)RTZBDY5AXBij`[N5Ce0Qpr@,1C2SrF$`M85ma(iF!pZA6-lpVSF,rpJl#
T'CJmUbJ%YQ[2Vrd(E,B'A-8+k(Ukrq"MX#fc21Ib-90l2R`*E-[YQ0r"BjkZ`1f
XY-rbI$eA*G"BFhrU0f'lh[CFL-H61ZE1$m"Q6`*qp$0!a`)GFarie,(#M[PAH(a
5aec)2HeZY$`ICTiD(Ck9hi,Y*X[cm3eJ&8(8M9q%!lB!!drr,RTCB#fEFf@V!M!
Hd&fc1mqj1Fq[)%qbc`h#ZChl*P5r2mqjGXc0B*fDEbTQeCcE&I1a(%YH83FE0a&
6TaPSQ,9"B`#PdK0-eENAD,GBFP8!$VGDRPr!eKF@5eD`3`PG)APq,XH5'cm2fff
@jr`2jeMbd9q%cGiFBrkRFmKpjlGKHkhYqBFjPRcq5C+MjEQ)@N9B%UZ"JZMXQ%r
P@1@&CYKHChNZi*)-JXr,eT*-,-rY3,[&NNZq62ME-DNQK&QIqeIBL"hY5Ei8P[a
hVK&KGdEE`FB@5bCB@eZ0cU%#%A5i@&ZlHrNUD%0K58mGP42VSr-NfU@Hcaf%cHi
8,0KNXk6Rj[I!YYlfT&S@PNcq%@aJ*['NpK*&XTRBV,Fm&h0e#Ff5lJ0N"qSGGAC
")3P,HVDbD[D2LGhcFbbjr8f`fGhUa6N0iDRiCGM)(cVQRpJXkGj2MSCk!Z1"jAi
'('@cT%cd"RpL*G*jE-9B,'PlEJ*kUPPG5jPf6J&ImN+H*HfBV@!l*Gb@#8YfaTa
,VD&Cd[e4lUV@C(Qq#k`L,1RC6+4BHmNj'S"pB8RheeQ&Zbc2Md1(@b`C)Zl)4ZV
8%*qLPTj#*m(4BPH!DN*BmJRU3RZ*ZcP8PX+5qqP&p1ZBa+0Q58mCe5*dVhMHR@2
*4ZU`0TXPL@l4N[G#G6Zff*j[cE&N`cYJB`lUm"1dX+6lFHV2VAE-Rmr&[1eCf0j
Jm`"eSI$!Ma*4El3mNq!aB8RhVfq$`cdf1ULDK58Vf4BPXfK-8e@+P[`YmL,MDXr
p1CEmi!++&lXflmeTbEpNM[C(f`ASh`K,ZVp+E@2hQ1D4)S3P2G6YGXIS,L*FY+6
cA54lbh-IXV'dj"HCLIhG*d-0V9R5rG@[`fErYPp#65-DiVdF3fhrk[STF+E&NRp
12B3q#rSUL,FI,1QX#6CL99Mh2l1[B[H,jK%G`ALQS![&NkVCmZaN[$RX995M&m0
qK(4TrKm!!!d19'0X6'PLFQ&bD@9c,VNZZ5!Q)&0S6'PL!*!(Sa3!N!m"dFd!!L#
6!*!$&[q3"%e08(*$9dP&!3#[[Z!5X)6Ze`#3"3)rGJ#3"MCG!!#E#!#3"KXA"[L
,4EB,ImP#D-ZaKHdMLi36MPri`XP#Dq&&ZqAi*@'%,8S@HR[YZ)00C4kK!ql9@Gb
9VH'C*kG1q1V4SPf4ff`Ii3XRYlaNajBM[h[*FXCflm8**i`XaeV)[[KLC$Qfm+X
M#eQ1h,CM,@HXKI!MYf0pTRX3DcRI,SrF3PDXm!HmfRAYBpZ"hF+Z@eJ,!&R)E#'
hb5E$K@bb@cGCEG5NXipb-kmc,bFfciP0SRCpY-kADj1m,Xqm"RC1mVYd[jQ,ATq
Gk6A*5HIRjA9mmIh&3AlRZr$&FcPR,QpRGKjCI2+lb#Blb5DhMba(&V+3!0X#!!'
FGEVDpAD&2`E!SYGY9Zbl#'[KYr$&10Q3!*qh!GL#2q#"jGQJ9+pA2-r,)HZph-$
&b'QHYfSBqpdqL[qPZpC2)Zrh["mDplc9EA[(9i$Ipb'U9!+8rKqm4lqNYm+lZ!G
!&1Ep-X@"qN*m&Z2mp1Q83[TUri"r8HlfjAG4%LqFpEe@UqhiF-[A"p239-AhPYr
d[*pVk4FZRRI4U`Ve@V&82rG@&@4[PIr4h2j-lhK-crZ`Ib+hFX8kEah2F+rRIEl
JrH"5VPC0MfmCD$6$hHA&Pr2#5el6re,TNb@mYbF2Dc6af+9D)#eiDb'&PN163RU
QX-!Uc3')6#a(5%ej,YmS4j`1&H4BeUZ-TSI4NKlamY`&ZC%9PhD,N!#T"VSi8-&
5Q%(k9lL5h2-Yj'XF(amP[*IY12h)[iM(0hD8IVaN+FT+5iRD`[DETdU9c@&a*Qb
1MqI2KkV51djr(qLrdcrYdMq9@dTVp@@ADm,rI*II(-A&j[qPp+qqY,IL%[*`)LN
iU9,HY4Cpl$0CAXKdGm,RGD2HP4[d(eYaY8`IZYEcAKeJ@)cFR061#l[%Tj!!P*l
Ap)rNVXKpX90bGcC+(aJYlfS@QhXhMMIVYi5P1#L8Sj+hj,LfA*[)"rPkY9'ZK-e
PejXhA)[MjR"6@$[YGe'j0[m-()9Cm&Xd8ilVTk!@efZR-&U,8DPBHIiCb(GYX9N
VefDMCGqPa6h&ji,@lleS-@i@6f%f,84a[4Um+Gal@ldjFmUhX93+SbJB,mCcTac
c#qA+c,24c0c`TZH5"(l0jDJB4@&eecHI&-kG'35hmQ-fVFYIGGAcbD&FZh+MkIS
#!B9CdDT8lhJXq%@2"HI1ai*EkmMehr)TCf0VILLUNPEE`mUbimT`hr2[ZUVBR!h
MB$+-ip-2ZaLdBB9LSj&icY``rhb9BmGLP@0AVR)P2hVfNTYqB[DM+XFZXXS9RUG
Bj6Tpr8aQhd+9+lmhe59f,98jpLe81ABX9$Pfj#TAmLX8MT*cC`CaP5Zm@&MP1Pb
lFS1UA#%V6*8Vq8@2CDTFb3e9VYfRR)eFjGLa81ABX96P#Y@M8193r`4lEC[$[B2
-qCkGE-lh,G'jJU-Tm!8rVZC"r*eXVH4FS#5qXq'#[Sp2"Rf2GPEAr[+'L2QqC9l
R1lF61pqcRGRjRL9U9h"XTdX&lh)kPGKGm(!Gp+lSfje-KZ!&#9*NH!A(q-f+(+r
JTdPHk059R5@DjhZfmccIXdcdJY*3U)%kqDAA4HAS&-GXQ3M''R'j@Ylh$5STUmQ
+KEK"3l(GEdeKf@GCX63f'44#hU6mM1daKLA,""Nk8T5q8dHBA2N,8EEc3!Ubh8r
%b$lP%#rmcf*CF#lb3q2C39L-FiQA'pFLX65H)E-X1KEC@Y(ETfY&[i#EmB1Af'@
lVk'Al+[jTI%T*UMa$$1dj0Me-%(b'UHHl1eS*(3iGcpRb)f,MR'k&GKad8r4ij*
6qDQ,"0Pi&KQbm@c[h"MIX(96G#`r&c0Di64lB2e!0&Ij9M9Nhd)aC-G5,@6IX"5
bCk%5XL-A`T*I)6&,c[63*EHZG`k,B)HVAc3+VUS%XNZK!V)M&m"f[r+6k2,(2Kh
9Mle,aDr6YqXCZI59r+)%-i@[j)Dkeql6qF+&UXH1KD,(MX@DakjFmNTqRHp8,(M
Gh+qEpd@FEarIkqCkA6`[jRKPIYI&l4lKGBp`ZK+IkqCbA6bZQm1emlIph#hLE4&
Rkq*V-9FVml4fMYE&clUj@6F[FhCpHScVc1l)d(P)-GSR2c%Nj`rIE8*Qc)B"Ykc
CIJXTarE%p`kN'0'6hjmL+mhf0D5HSI`KXYV#KejMYM%SIFb'U9UDP24Z4+Nef`d
SrFb'Z2ZElIG4"TJ0XmLRQHdI815!XV$p#1Ade*E8f`ddfe#8-m`f&f@3!0P@@Pl
!GMA+B,1p&'@)fAiEj5bcLEQUa+9Qqb)+iS,YZbMRQ!eMHaMD3SSKRZ&Q%a2ALF[
0eS)b`Q`E88DD$I0aSmaf"mTSXld,"EN$'pkqhQarMd*6E+Pr3aQAfY,+XI&Q3``
6c)BKXiPQ@iXbb@b)@mb05GY[S%`aflY4TTVY8bKi3pLqML*(e)6YqeC28$T34fD
B$HmZ"YLNE6E+,,1KhX!1ffD81@Dl"DA"E'p#3Cl#pXFSmmb'R*Y[0Z6FJY3Qja0
TJ#kV[*86fm+'0fSd'q,1Qfd,#NeLCZp%`53mE'p&@@5fpk0Jm!kf"e'@Q1dl+"H
B$EQ1A%Cj4"eCDME%ID(C%$FNE0HK,$2EVk%X0p[E8&DBl8p3a-bpY2dYbX9QqaF
8e#YGIY[-KKUdbQc)Yp9Q3raVc)Bm3ll$KYUfcQa[4N(YKHdM+1[0pK$+"V2K[5m
efhqLA*ED+P9rAf!fe+E,cBEmZF*Xm%&pJ`hMceHDl6A'0@"$RZ&pB2XXbP9QqbB
+DM*XU'hAT,BUmB4VcBDkKPb'$EQ+r))0X9e[0V`hYKr!K[IHCVEl8,DEl5XS0$P
ET6cEQGSNK3%IJ3dFJ%K`YHVAEV-KYfQZY9V[GD2CEN@jb@`BSAkKf6k)3U2Je3q
Jl$AEpe"HP0TUa,9S`,K'A1)PCN1p3jf%$EQ0Yi80EieiBEXGK3ClDpk(FT[C2SD
#QJ2E9e&HEVCr43'Qq2U)qi&h`)DkJYS)'qVb+mf'Z[-UXb&RIYeXd&pYYYp$!Bq
!l4-S[fNfF%6N2Q`r3!'r%epIFEAAQJfmi8kcSHlIC6E8apHC$IRrHV2KVGpJ0Z6
C'mhf!46`#0LqJ!)H"a[b'h9!I,AL`-#%$E`"p4mfj$GU-Qb)qqeQ3ehj(E-K2j&
IX#&qm',B%2FlcICA+1"ZX(d,"AN"flqMJ&Z*VjrUfA[-"Pi(RJXEF[fpCN2YITr
C8,2q`'c)fcmd'plaEV0p#1@2c2DA++LaX(d$"Hm$fip48)[%eermr"kcSFk"jm)
'[SFk#4[i$lJBE1!!L"%f[-H(cBBD!"i"'plkSfC$R`#m"MC`#p3Lf&$c2QkfRk#
J9SK[J()#Q,#"'rqCf9#(Z[H3!(4ri!IJZq#ji,IJaq$&i,IJYAKIm'G`FI"0a)S
F"am"T`%A38d(*`H2"Um$e`A("GF#Td@Y30kLAS,,iSh3#d$G4Ld$j`Ir!1p!VU"
QSRkKCS0RJ&q!9i$IJ,q!9i"2J%H!2i!hJ#q!*i!IS1k!$i!(S2kMlU-'JJHKeU2
'SlDM0U#rJPa#2`9p&13jHJ2SSi#rS@m#NS1kMli'kM"i(rJHqMV)Fh!mm"'3!%l
d9Y"635m&244`A[3iG0m(046e3bpe3(e&6`#m'(`8A!Rm&r`C["Rm&r89I"Ie"C`
FI"4m(0`42"*m%K`5h"&F(K`HR"KF'&`%h"HF&h`)("#F!I85("Hp!Y44p!E3%`#
r"8F"0`%R!4F"ad(G!KF""`(h!!F#a`(h!1F!ed#0"lF!T`#A!)G!c39R!&F!4`!
h!#F!9`)I!!p!r8FY4-e'V8D04Qe'c8G04fe'68BY"LG!c8FY4Je'l8A04De&M89
Y48e&,8804He%c85Y4)dNlZ"rX[H@8KULQL(EYPkJK0alGV&(X+L$&JmNPFSYYV"
&IB@&,L+8*$+&c##cb%VND'39FK5b$MQ!Y39GLem5[Vf2l%iLrHi5E-ELeIQR'T2
(GkZS#"$P)dYUp*U1"'elYD0Mpi"e&`jmj68CDJ23d9dCM#cUEUd'#CSUDZV[(YK
AYJj%m+hI-KjX(ET"&6")(9kPSpDUq#plH#P1A!4-UUTAeK'V@)-P&(U65l`3TX+
lB&8kNk*Q,q4NbK-F$L9q8fAd1kMaGfLG5kP@q(9L`0)k&r@J&jiV',r-mR!2Mep
ZLU&4#8AbEh`f)0I-Tp-,XVB3aXhkE@&c2JU5)CkfbbH#+rheKqrbeqmHR"i,*ME
2H9F%Np,brCHp`I1h3EH'Ikc[XUhHE$"Yl9Vl643Vk9Z0'k,QKASm(l+Ar0&U2%Y
M)(9LZ65*PP(bGG9'"'ESf8M$aPXa2XVFFr,%JcM3`)&Ja'JRe6rlTQNebIHqGlq
hpkQNTHCGpAYprNHfU6AaS(K6)[F(lrIfINlM'ZVl2(*fk[NPN@ArPG-U4c@Tjjd
D"D!@YHJpL*VM2CakALp563eVJ3Qb9TGklK9PTIDei1)J`e@Tjai4AQTQ#dr3hFq
NRPp@ki&Dfk+[)CS)hTV8Fil)1M@k4EF$EB*2T*iE4DHTl5eb"Jd8b4!6ZGH+5&)
6A(4(40XLDHrj*G&fDSQ,IJ!D29HQRTp8Ji3Dj-*6Y!3'[5VeR#G+6Zeb`IRa(MG
AidL0(MeB)lph825pip5!GXp'03#Q911+'N+K*pUcZQi82'@MLI,Qlp4!S5Dpq0$
+'TPkpPAEJ9VfP!hdDUp6)i`Dq)4aTfAKTl%Khi)pA25j!,DVZ@!q"m6f+k5a(ZC
bcAc(QcC*H!mB0rA(h#jIAApqE(LN2qJI(TSD3QhGNTqb'69AbLHB'IA(#Krk`i+
!96"M)-FHD3DPq$hCm4-0+$94,)D5Ir&DrNT%[&PkH(66MY*mH8Cc`'XRf8Vibpj
Pf5GS6ENQYR058p)CX2'eDm@MD!J+FI!CU*XUApHIjqc+T6!RQa0-Y'9+Q+QqG2,
Fc)!IrkUlQh#km$dEch5jIDk3!0@Xf3Xd85#UC8ZY(*H,&ABr,'i@CkXKLmL1ILF
E1LVq9@'c@Ui9iqq%$ek&GDCkdiF3lHY-h306%mFqAQIkb*lXacI+DL6`(XbNkCN
bM!1KTD9Rdm!3+a+P-cJcX1)5i(qZU+',20RHK'aQ6r,$[4GNq8hG$1rJf*!!q*l
"I!EhfALI`hdU$XPMNJQM`3S0d9GUf$JEeX*QZG5cVHALTG26SJjX+rCZU`'b$XK
Tfd61YSUe,63Dp@Dmd5D9A@U&`@[4NK)M!`dE0aEUc9#VphB(2ce`cF$9[GE)JGH
L2j!!%am)HNjYFE%f8fc1-29"ZhrE4S0mUZfS9ZZeRQ3P!S09LKFq9JF%Hh59m34
C"c,LKCYBdlNalYh@+T+mX)*I(6NL0X(Mb*&R)R%2(%&bG0H+qF5T*XAAe3XeR6k
I+f)&`31p30l49E0'!65dCkU1*cq9a*cG1Qk-FKjmMmiM(Tr%IhErQ-YXVBTMEL8
)l@!`j`XFrkUl0h`ikhB`Z""f`6J3)K3aGRC4*(hUAUU$9@IBHBXGZ&MMK[fU@'L
(REPB@SEGZYL0Llfh@15'KA"i16"fE$h&cPMXHF9q@Hb@4Am4bpZ`Z"&lCV'b$U[
K-(@*[J6f[Q,[,[E"JYTM[4Y@V@'r,PEFBEm,GU1#e@-r,IB&B(mY&VDKHi!p[pM
$Lrfmf1q,RElBdiY9EpMaLhff@)D((F$SdQ)P'kCrpFjI,)ZMhHGbcbpfjQ)R-IE
@BTFZdJ-lH,'V'$2a@15'0A@J#pK4Lrfk@0#(AEISG@!&R0jTLefhf'A,qhZa+eM
[lX8HB1`baRT"l#p'ka8lM,%M'IZ4p5jN%$[XS-(D#EeA@HpEaUjPV*VM2F[BrD[
h0@#2!hBfS*Z#P3hB8iZpa&LBT2IjBXm`lbl'LN$H@iaGa)rXBmBZClf,'EYMX41
BG`&MlbrYQIrTPreQ2eSkl8QfElJfZ)0Ei(-Km"$4,ACrl'Pj&[Hr-V(h#jMGiAJ
%V3(l#IBa`k$[`T!!qjJ&`ZKN3E1VTME'@HU`f)NQ1@eTTjMHi9lbdcYi5Rl`!Fm
Vq6QUeK2cYf`lTlr)'f6L%`9AMHbB'QL8AYU1,Z*3PpHdKe&qdfIL8"qD02)pGRR
edQZH(24@c*c`9QrDQ6[@HX$(lUfK*4-`Nlh[D9pN-XcEGh[IdUimq$lGTke0TQT
EYqFR&QTFMq05kY-@pjk9ccKd9H`p`j8%m+2GC(3pJ3'R@bN%$ZV@QM-iAKF(M(a
P"kG!a"N(AEGe,Kjdj6DFLBII"lcc8KFhZR@lAX!aHB&ZhKk(JmlM5mrJd*8M%JI
GbE8Z(R3`Ap["k9j**h$3%EhKI$a&UeYZ+LLS$A`64fPr)DU[lSAV1ce+phZ8qYr
P@cc+IAbq4H6RIAap0`Rhm4rTZHYq1hV[TAiljL2dl4jk"S2Zl(%eI)9a6&fKNA@
D"#"EG+&(CQK![,VZK')U3mqak#Y*m'&k3er)K)N9I5%6*M"dc`iY9EU3!%PH$%)
A-XR,31K#*RR4KjihrCa9!RbiqSJZC%SmBC8"(kjIdKFbiEhdK8c`eaFbS5,3K8b
H-TdZC2+8`A3KNkI-T!ZC2%h2d)9-mNSRZT!!bG-d#Ph)j+QV4aFbHCT@S3ZC2%f
Ed)9-RUB`k'!&6qp0r4K2&j(3K8b51G+&60jI@k@#lFY@X@$$"6Pd)C1Rbi6S3LE
[+DYNX2f(965N-h+5'J4*j3aGb*681p+&6%RKdS9-5H8hAFL89-@L#jQ5QN#L#jQ
5QNkKjRC5NdCd)905Nced)905rA1kN!!T+@j+&c)P0F&$&c,*bk,S3UDN,MqK#jQ
51Q'",Q4+kQ`'ZT!!+DP*D@SV*C86G#&68KG3dB9-mK)TZT!!+IQd9@"GbUJhN9)
0SJZC8US4G#&65RP)&c+Pp+E8H8XT0VU3!#QPb5+Uh#P0j0#&6#P08G'&6#R9!lU
3!#QP+5LkN!!TT9%#ZT!!+D9V@@K,GNUAVY#&6#R91EU3!#QPA+F,Q9+I4U'HCNV
R5Y$j%@RP0adFNGCEdSN4DG8Q1LSLV9T!Cd5NP9Gd1%4DEd5R3U3e08E(3D49fqJ
FL,6HNJk!5'Z#Ldjq5'Z#L)j[51X#'$Uh)De,AqM!KV41K+!,QG,+AEU3!#QYUir
S3UDd,[+K2QMkXbM8Y8Tr"B8ZC**A9G'&6"Ra#TTFbSJ2d*4B4[@8,Q6+U%j4PcD
Mh+8,Q6,+0lU3!#QMGk3,Q6,#T3ZC-TT!S`ZC-TS+S`ZC-Z)VG#&64TI08#FrS`Y
Pk%+QM%k)S%CSjZp4k%+Qc--S02U58CfQ#jNbfSa*&c*P9C[T3UDXkMX0e'G9lqK
#TUcbQ5jNbLTrU,Z@9Cad)90@18SA-Q8eU8)A-Q9e'3eGb*39Vk+Gd&R9'1SGC4p
&S3ZCXVTdLLjNbUQZd)9-1A%5ZT!!59jj44Fbj94Ek8+QR1SAAFL88pfK#jPbbP@
kN!!TTabJ#jPbHJZkN!!T*jj%&c,PG!81AFL8dmNGG#&66YFXdB9-1H8@AFL8dd9
0G#&6lMp3k%+Q#[%rZT!!U8+mKbjNUP#HG9mRi%cie"lm4-k@-f0*F`D*@fh%K6Q
*(d"@)UZ3!0A)'Q3IC&pN,E)IXMpb!2)dC"hbG14!j"R)3FJcNB143j!!Cb(24Z+
)iR13!-13!-14jb*()%FL4b&()mFJkj&MNH13!114%j!!%j'6N!#6N913!&14dj!
!dj(R)@FJCb*R)@FMjb!EN!"cNI13!214#j!!#j(R)aZ4H@36XKQj*$hbeph4jAB
EI1Bm!A%,k&9DH,@P8JjR!YZ'L40qKT%@#BlP`qTFDI1h*8j)$YRE'!FrJGp1"Nb
#N`hN8)XB@42iMC9+[643-Q[6A,'@'4I9pQ5fjQd6Q@ea[MV6-BT3I@0,,3kE#if
ikl#PBebdf$8ZVmIPhAXcXcM$Ed[R'9D'8AfK@HS%ePB[c@I'9BbIq-E9YI*LalL
RA-Q-&p@,HUCGi@bif%Lp'U1p0BXbAicD!HHC@0aP6p%dAq`N4"-@#PXmHH2Qc03
bQTQ@[GP--MRTA@"FY0KSTYCQjL'9aFqS4AZBM566c@&TS3d3T"EbDRQarG",3N1
lS"M0Q8AFJlUMr@`YYCP`F@cA,@fV5%0kmTDaYKiN4mYB&LCf0QM,lML,J(*(*Y)
@U`KiMGd@&@H[$pTDE%EfAUhcXfEB&8CKFdrEE9FlY9VV8APa-VB-%3Ca"D)I#"+
F2)0(@e18bcDUfp@UET0QkL9[Z%a94"Bde4Yk$5500V8ed[)(fid9(QH2%XH[MQ4
V$U2jZ0iSc#SiheRGmLJmGXI0@UNBKD@U(YkXULMABiN[Mh8Ye9l+U1AeQK+",f0
08#E%IPYehD[d'&ELqN@"+a*(eN"j'k2HF*KJapQfHPcAZ*Kbf3)!e8LJ6k,@kIU
R))0k5(Cj+D1q#PX(*01TFG[NPL!r)&Fm64XeBeeQP8APkQ)TP(%Cf53KS0&%Q%4
CYYfX-$BX"BUREDNQMbeF%Qp8RGe4)h@fLTZBiEG`-NmFj*K)6h9-l-L2AArp8Jc
Lb%Ffbh$e)MJ6,Ul6%*0V"E-1Q)`8-+`Q+*J4P'DPL@5rT*m4X)Bj%[JhMiiQ9XS
'lG)@cq3ck&,ZE+VASMS8BRHmX#ZT6hZ$E`4m5H*3M&N3)P%JLNL"8iM'ek(UYq8
VT6L&J"8%)Pe3ZSb,INV1HK90q`Y6N!$d1#XQNh#SM#MIB@Z[+GqmBHE+EP6+NA1
%RJc2UGq,d0@6FVBZ,MFMRI'T"Y%EdQ9GA8pHM'MBC&*jJaT[5RcKa4BAPpjXcra
bP69jm['PK*5PUTa)!B3X2*hTjfFZZ#ca9%&4VNl5JjUR6[&2M'CK4R-4XJ@C4)U
cb14P@KNNMX$-)5Z3!*A)+Q3eXJEC"pNA@B[XKqb2()!m$9Q(2"dj%(N'FK$b614
Jj"$N@FLcN814jb#()BFMcd@13)j%MN+14Sj"eL2()XFKab-R)#FL*b%R)kFJTb+
R)DFMcd213-j%cN,14Xj"0L$R)ZFKjb-A)"FLcdFf)S1l0a`!Ppr8,29JA(9Eap3
%T0c6``k*Q`rIFC+6cDlA6++ll9XU&PDS#YG5&F5GPU"1$VG[Z@fS#+V#GUV#Rd0
Sk9*54p[hSZ4q#Di+,kBUI+R9HYUQ3PeXhrrZai[hUVJIEV05@plF!9G'iCda+9c
DUBE0%jL),ZpD`c4ab8ppHJ-*Q"P#,QhNG$YX)-&Z"SbjPMD3!'$A!QEDH31*hMk
#[3VP$55Pl52BDi!p"pKTJ*PiC*8$BJZ*mq$VZU2"rE+Ed3&bqGN[6JG!R8qPZiC
%fDrT&EG(A03$9pbP@I+#'#IFT9RCRR#ACU&G*UlD+0B"Ilf#1kd5b$SJlR6mkB9
4BQ0-JrII#1kZ1L$kKC)Ar[cLX0D&A48f-,A85T@&Q4jKT%(@JFF[6m2&B5kb)U$
V3%92Z)[$8!HUHX*G*)JkJ)P"c*UT+51KLjRHVl9DRp!@fm,R$i5lhMlhbpjlE-h
'YQaXS+EYf()H#l86mcMk2J"XbmE@CQc(TUhBMSE2JC@MiM(f)Qp'6N9Z3fj(lN$
Z40k!h)AFMGb$["(CM&b%A)aFJV`!fB*FLV`3H4&b'A)jFJ@b&ANaFL@b$EN+Z4U
j"VN@Z3jj#A)pFJ2b8Z4Pb"FJ,dGHJGb)["+j#ENCH4AbDZ3eb'Z4@j!!eb'[4fj
&6N014jk(R)'FLCb&R)fFJfa!cNA13mj(,N!Z4*k2E%6QN8PN#MNC139j%h)d%V@
Nb&QrHefVGIcdA8M11-lUk[KF&,F'*Ee,AYPA0cLp%r$%Ka-"'KX0ZfcJ4"c,#U0
f'82m&9IkGRh,aNIYBSD6FDc0fd81*pjejH6%Q3L2ab&[mEPbcLY&d@%1X,MG@lR
4,PB3AdAMbe),1ije3IM)%9hcN!$`5fp*,X+3!((dV'lY[3dSL'1mAAMaUcJHIC!
!aq0ip2bP*q)i%-La1,!FHr+q`64IlcNqerVUB%lf1Sj+U0Pl+&Nf2C5ji)T055i
,hiH3!$Yckpi@q&miPLbXNA%FZ!MTd(ZJJ56MH$3pRVK4DD0G(['V1*kpG8PprSe
+)JjELCkiGHR!Kh6Yr@3FZlfjFh@DpS[,3UeG5h8DbmGlBfeI80ljL6hV$S#pAq!
IZk*Q$i#&ciMMm%80a6hVA4q@PVX"iX!RPp(rr`qRNKbm5p(p`EM&bhCM2-QiicL
F!Bala4Zh[R,-E(%pIpIRq'$ZdDXqbG`2aR'%Z4q-i`Kc2a6(cjKlEabpc"dI-AI
[mBI@p`"Jl[[HifRQ(MrXFHEH'mF4jVi[M+HBHfmF2FaGa('3!,`VjRl9l2rR[I1
$FBYV(,SaRQ6F84ci(!'-HffjG[A2")XEVMh$Z#[rPc'*1!j8KU1-k@!F4jM1S6K
qaR4kicKDbII&m93PlifMTqL*1%6H(f,Q[GGCQil%rJ`4FHcBC4FGGArLL*5$F93
@rZYXJ)T#)@rh2*hi(UYi6@NQ(STMkmYF8F5"LilPk5PL1,hdZ(j'E`lEPjDHH0H
6R-(RdMfFr&JF[C@c*mrmr0Mc8TSppP8R"bcZVc&pNqlMcLpYSkX8GD(+Ap#&ZLE
)ZSp1J$LD+P(N8@*%!BRL%,8HljSiebHAA8-R`([)ETm6)!lGlE0a(1[fA4YA+pl
SJ6519ac9Y@A*(GJ(hVSqYqUY4lQJBXBMDdI[b`A(MJ-TjS$lI3Erqh1[Ir"$Z9A
[5&E3bMLZ8aE&lh%ickM,XU9a0Pr4BT'&D(mFZ-!bS8-e6qDpl,)i!I*9GPQF!((
J8q8XmGehPA')p%Km,cp`qmm"bZ!9#Z2I2Q1MrF0SGbre5+cU26(jd$6fVV1p+IA
T(,1Ij$"1J$L@hY,F2B"mlPh"5Yd9-i[f+h1KdKG`S42j%A#K%rRU$TJ9NecSC2e
!"9jIEV`bJA2iAGd6R@Yma+QHIeFC4mpYY)IM1(Kkq*!!hQmcA[BlaR6F5M0H*cr
(dScAcXC,l,6hA9d%8pjL9ZcNj`#C&GYA3*kD&BXUY5YJ9N`aGhP-H6G)V[F%FhG
8-&-R319d+e5U`pr"`klF(cdGKmZQ(2Xj#(SaEU"015Frap+QR'1pQ1j!R!3EG`j
mY((R`1IHfVM61rkIk1Y9-IprK-'j0rB)('9Hqq*iQRR&$h+FHIA'iCcBMh#-HA8
(iKEBXk$L%!HKl[m3K0KEVdM"IK`h!#13!(%i*IBqq(FMlKmCHr5V@EUIe&9h0b+
f['mm2phSJ[N`DlYdk)BKbGVZK4ebHVhYmSRJ5RrpiE[mpEX(TmH#LFechKA"T,4
mrf9[i%MhMl0#rBYpPfheCS0TZj,mk1G#k2'9hr5C104RHR-l5UpjFY"E-A2#@le
TCqjBk`%IZlH'QH2JlV'pll&*c&6JlEZpEqP@6[JqcAPUNqY'@VIRl3jEKa,R58+
LF9FGIZI,9pHI(aXHk3rkKiHQKP"EYq5Rl2Kp9mU(#P!c-6CQ9pfVVf,6a(5lcq+
YIZj#F1'iH-[S#2"H&bajBIYbF((&![NR68qCRMBpBhV@p*cT&DCAQPjPHVAT0DE
h-Ef[kE@Qpc1p[qRb(A$PV(QRe#9,Pif,LaJ)kc66PjKHCrVTTJmdr3c6"jPqTZQ
$64pLqPQQRfhk8022-AfBkF002pId%DD20(f8kD00(f0k[HPM6GI[10ld#DC20(f
5kC00Rf,k901RQ6lGp20-Rf(k600RQ6lEp$QQ0jJqYjYVk9HrF$PkN!$EmdbIErS
#daHDIVlTMDER6@mbr8,6QlYa9k`jFrBfP53FY%"kUJYEUA2KrE1iUF`*&MbkLe&
e)IlbA'k+3IM,FLEdE"HRHZAb1GhdhJ*%jV-)A1DTX'Xr@DZ%,ZZ1m(qKk6,[K5l
c9HJhQBkV,4lrF*p$-ZNMCHab26IFaA+TRR%Abk9l`PdXph$lBMNRh'9DQCja&mX
pIUNDA5cR,,Y-Um,9!Ap8`*m8F)a9!eN(+R[#A5chF)qjLqAFChFS68RhNbrYV(@
SZ$ZaGHfhIp0l%jXhHHb!G!I6GUf(lYfrG0@)*hYiKa)'21@ZHHrSRrEKIkprp#-
lrAIrX1jpFdcGSI6i05[b$U@S6RIGS95Xdilb1j4F#XcG$E5Mh$*hI-6F[9pB[E-
(!(0h5pfKG$,[6fNClP$D@$Y#9bRU3T@rS![eR30Cpp%*%)Hj3bQ+Sq[HRQ*A6(B
0R3$[)EYp6S!ir$Z8pXGaV0XREkqjMqe`qJiPldlr)HcL$LA[`%FEhNErd0l0pqc
h$rkXLSQi3kQfK[r,r%1e6rS(RJ#2Ekq*hq0`RTNlP+)iZZj3+XCKlP"krMeNPm8
*N!#[XX[L")J$(pe-mrblbMM8(8V2ah'+D(1(NRYl%kHm,elQk+Qh`bC1bGbGE*X
i$q6p+4A%*XjcrEXEIr[-*XklCljIe0R%L9[,8mQYj9QlYIbj*hD$IELafqXCGh0
lTUImcHfBijFhYaIUJ,UUHN[[X)[DMp5"C-qiQpZchlkjh89fK[q6YpF,pZJN+`+
k$P6dK,Zj(AA!)AGcZj!!Q#0B,88kbADb3IPSUJZF&1UD-cKH&fFdkLdC6PD`rRG
Efb"`--Qfi3b1(jc!QBakUm1CJ[SbKc-90C[Kj%kpYm'CKTTl)5m-cR68#SH$cGk
9$QF'DTA$`F4BYF1CK9VMF'DMpR%iFe$l1Kc3L9U(-aHeRm1CKpVIiFa((H"`&U#
HjR!@SYBj(+c41phK0+)1G$MBd(''`m(QM%%1Ca(UQ3i(%qb$(Fi5e#%1"eZTch)
i,DKR1jbPU%-G$[B"RH0`X*PPQ-0CKMVFi5a(2GIKV%!GiA!`PMV5i9b-1XVKV%3
GlA$D8-FiR&@Sp3jR0HTBKl-'GCc$@BXkhZ'X3jhJF#j"RHK`eU01FMJE8#FlR%Y
4TcLFbe#R1T`AS%jc1*HM6RFi@!"aRX2"iXXC$JHce6-G$QDjCcNFh$dcfq&JEGF
FKi-GZJd1"j[EjMSFc2l2FcKE81Fl(-b8,h!if%qmd1&JSp6j$JHl6aSGcRE8[-2
CJGVNF,$0SGRKh)#kb1&JbmGLKi1G"%XF$PB5A1"`X(1KaH(FK2SDemGk)HTV-ac
GUHU)jfE80lTqeel80jh(199(q(Uk`XbUE&HBF@aAQ(&X9jKaE&HBF@aAQ(&X9jK
aE&HBF@aAQ(&X9jKaE&HBF@aAQ(&X9jKaE&HBF@aAQ(&X9jKaE&HBF@aAQ(&X9jK
aE&HBF@aAQ(&X9jKaE&HBF@aAQ(&X9jKaE&HBF@aAQ(&X9jKaE&HBF@aAQ(&X9jK
aE&HBF@aAQ(&X9jKaE&HBF@aAQ(&X9jKaE&HBF@aAQ(&X9jKaE&HBF@aAQ(&X9jK
aE&HBF@aAQ(&X9jKaE&HBFG`!A@'1ahD&'FGfK4R(GS8CahD&'FGfK4R(GS8CahD
&'HF83k%V,&J-L%``"Ej[kPei!5+D!MFi)'64&,M"%C3URJ)h1"R8D!VFi'!rD$3
&ER#`365D!MFi&DM4&,M"U850TX!06K9U0!9ZF+T4SbP`Je1$'Nf"'j`qU0%8Z-(
TLaT0J4ZF@Y4S#YcJB!Pa0!9ZF2UM4P2J"QF!DM3&ER"13ifQ`!e1(@Sd"@j`6NH
0TX!0cN$8D!VFi*b"'Nf"'aaaJ93m"@j`cN50TX!0cQ$8D!VFi!a"MDE!$FjCU0%
8Z-%j'c@D!MFi3e'M+A#$F`jU0!9ZF($66$3&ER#'SdC6i!ERA04S#YcJM%#0TX!
0cNM8D!VFi)a#MDE!$3kfM846i!CR$'Sd"@j`kP'M+A#$-aBeQJ)h1103SbP`Ji0
Y+0%8Z-'CJ"T0J4ZFLDM4&,M"QB3D6B%E('aKLDE!$3kfX%46i!B(@eLL+A#$Jbd
Xd45i`F%@PQJ+h1"J#dXd"@j`X)8PQJ)h10M#%Nf"'aaXBBQQ`!d1YV"%8q!'"eY
BSLP`Ji-Y,0%8Z-("&TCS#YcJB!Y,e1mh1*LhLkE!$3lQlD)TF)1$HEYS#YcJB0i
ZQJ)h1*LhLkE!$3lQlD)TF)1$,II4&,M"`9aH0!9ZF$"(&r6Rpme9##r-X`ApqAd
iTpi)Rq!cMrARK6mJPQ8ib4Gad*m2q[Ja$[Vc34mraJRlmc%1q[0"[cr'3Amqk12
(11M2"hhm'#IXcmFik-m(rIiB"rhjS)mIik!r(r6aBacdji-qISb$rRc3aipad*m
2q[Ja$[Vc34mraN&r2ZMMacMSc`Gpr"JRl-qRAX3*qr-a6YLIMh(#rRb-%rERBjb
`2arMK2hj'#IXcmFiBAmqaJRlmc&1f*q2FF,qI)`6pZGMR,!r(q1%rINB*qc2acK
KIcl'#I[c-8lBRipa`[jmM"2fjf1FX$mIii6pq4J(rIQJlalMS$mIp2&MR,!r(q1
%rINB*qc2acKKIcl'3Amqk,[(11M2"hhm'#IXcmFiBAmqaJRlmc%1q[0"2ch'3Am
qk12(11M2"hhm'#IXcmFiBAmqaJRlmc&1f*q2FF,qI2T&(26RJcjdM)2qI0$(Mh(
3R`rkq$%1q[0"(cr'3Amqk12(1'&r2XC"IclSpmFik-m(II`B"hYc$[ERK6rfejb
#*26Rpkqm1M)#bcKf"*Cal!JXipJ4@-Da)l#-BdGJ'FH1`$+1(B&P($X#bcKf"*C
al!JXipJ4@-Da)l#-BdGJ'FH1`$+1(B&P($X#bcKf"*Cal!JXipJ4@-Da)l#-BdG
J'FH1`$+1(B&P($X#bcKf"*Cal!JXipJ4@-Da)l#-BdGJ'FH1`$+1'f!%PZ1a)l#
-BdGJ'FH1`$+1(B&P($X#bcKf"*Cal!JXipJ4@0pikT)`!ZZ5qC,XZK@d6[l1Pkq
Z2cmf20)Ip!m263fKYQl*6kQVje$jX&"XqGLfSF,)`-J1MH"dIQKrb$&Z++5[pJr
i&q9ZAiiNqrfKcAhccS"0crlDN!#H6Fq-BcFp-iiEB0-caf-h2611hI6-1(E6-q2
B6Fq-BcFp-ilGp-`iGY-cipK0ciaM0cdcMYhdc$Kfdc2Mf%h2M'-h2611hI6-1(E
6-q1i!6BpFcafdc2Mf%h2M'-h2611hI6-1(E6-q2B6Fq-BcFp-ilGp-`iGY-cipK
0ciaM0cdcMYhdc$Kfdc2Mf%h2M'-h2611hI6-1(E6-q2B6Fq-BcFp-ilGp-`iGY-
cipK0ciaM0cdcMYhdc$Kfdc2MZ!%f2A-mGY-cipK0ciaM0cdcMYhdc$Kfdc2Mf%h
2M1-'f26-mGK0cicM"YMdc2(B6Fq-BcFp-ilGp-`iGY-cipK0ciaM0cdcMYhdc$L
RHJQERT2H*AhR"i!(pqkDrpd84BFprfYhH#XhkPj'p98d[Lbe22rVIIM)[bEkTVF
NZf8F621rNrF0T[Pkcr'jePF(Fl,A2F`XaYj$b5$S80S1&CZ5A"Dq$b&hjYDp,I#
rF#aCK1GBQ[pe#FcYARZZ6Y2FVLc8fV98TpeEFl[%Z1-eDZi2aZd!fU,Q@'$ZEU!
YDTDjib2QlMhqd2SH!-cGrE0&VBHjLcJ1NRGrqpR*[(H!E$rEYdAiUHeRqlF41`)
BGqqUM-TH&CXbR"-E,Y`6Qb#F!"XFC)9a5Qa-U#bmZ)G0I4@&3PlAG6X![XFUAP1
DLBILf2Sb9a4aB)[aX(bpfLKA6MqZRp'E`qrZ!2IIib4Rm,Pd$bFr&NG[jHc*-cm
rpVbbE[hJ9heqAAhIT2Zimd[Ek#T&ADMb&h5KVJQblU-6)!kjC9kY`BlLd0ZVECp
FGJfG!1mKZhe1J$KdYmr'FDcE*lI$Ah3JMH-94jN3bH9fB"pikrVFUVFHCFI$RCSfile$I
@MYkA#iiG"e*XIqMh'Ic[clhq`3rP9Ve$dq4Q1hcm(SIcM,SX@aTRma8Y&PQ)pXF
KYm0MEIR*[*GG&LG![XSZLa-J$RbdeIhjGj9aL24)I#mr6JeY,Q9)Rp`q4@[jhh3
i`,BSlM+8p-Nhdc-EJQHP2%eI-(hbaMYBp#im8r,FIMSSl25Zah2,%ZBkL0l0Ik-
$$e5FU41CTl$XB$)mYcq0dhLqb[0Z1X*-16a&R0U6r0q08Y9SXVXKq5GrJ5eBMV`
H16,e[&HA-G!#CI'pY)-jr#PXZ1Y"I5,@a+qPRVGTC&&ZbX(RkFD!TDRRK0r!KYX
Gj*Hj"f9+kVRL8pK`VB2br(B(-h85'ej"4I-6P0QTjkfkeJ!A1FJ[U4cYNhUqjdC
XZ-&"IZ1**Qh4l&80`Y80mXXpKP+AH[Ej3fbiXd&&JlSi12@m6l2%Z+a"IMrqFmj
1@*Gk[[*h&E2r0TMM6UHHVIq1$GFcU'JZ3aQ8HVEm(6EFbk!m8HXTSpi[&0!NjAQ
V)P#H(p5qHYc%S$,h!bJ2@ZCLFcqZB&"jJdT0f6&EliQl&e3dVp%E+Xp2UHiKGq3
h"FlL2Cak[PYlYA(EJ[bbBM18(Hp8R,KQ38AcPXkV9DXhM2X9&#BfNAmQpC6A)1"
L"9A@40jlDe,2pp9a`)d++JY446k4HRj$HBD+)ErTZMYK8Z,TIH@Gf'"ARQ+cGp,
HFm#ri)"Bj6IVdhKZ6MfrrcXii0B%QCijhRck,aNQ,NX38P4MNDQc9*F'9H0)GCV
UB2VNp%(2Icm9VrCJ08ikqllR1ZB&EJ,6!h1VhP*lM[M82r'HU+Cp`83&,k`F6rj
q*fqqrK!fh+fJ2*'Y9(2(XJG#AUUJ22qQJhRlRGK`Qi,br%DRjMji+cCFSb#rqFS
LURLE$Q,$r3Rb5reaTqC@UX,JiJ6PL9T)Q!rSrJ$FQ+!m`9'SUYbZ14jFPD$H'rF
@8-hpV%CVrF-Rjpr3UERI8[5i(%&K)PqSUQclE@bi&8&jBQXreGbl&61Z3j!!Ab0
[f(Gck[PQe8kICkFqf+Qj@m8Im#)UQVC1cEeHH+LKb[2PRBaU8)A!P3I+%e@5DZi
hYf,$A3H+$B)l8Fepp5mUKrak)ejDCmI[L[NJGq3hPPUJDqlR9*R"l16A5VC6cI@
H[NhP6([1Q1jNafIr%KXZ-T!!hcK99Pdl(K#8pP`TlN8epkh`5RPeJIcDU&1kj[l
MK"j,Hki5KkDDHkGfLq#b![R0HeG@Fj0hX440hP)J[l8hG@VZ2hd4"ea2),p,k+$
SQVY*Y46h%XLDfr#q6Xh0I8$KbCVl-EUSU("A@-dPKLPBmal2[iHkl0GFhh-YZpP
ZK`(l09GlMRL8&k[AQqZD'r"9I+JmQV-L8h"lJFV2(h9UlYe#`E8&LT&mSB-TZjc
)2IR09,ZDDZiV9AZ3!2'U$TLDqfQGbBXE#Y3$I,j6)3DU&[V62EPrl062&k["iAG
M2(A*U%jr8CMq")kRHNjapPI$a6qjFc1Y(eechrPC(2aZYrHj6PA*+4+mMhSEF%H
UZIrmG@cqPLUF69#hdqSdpZ,KPJ)9$ITP9(0R+pY4+99')I0dc88PmkIqkP@A+D0
Z8FAd*klUpHj8FpqZGeR@pQc3@e$04F&,E-[L"%1NM,T$V(Y&&JdB%Y@S+e4[GGX
S-3ere$ahZjMfa9NdU)b8(9[d,V#VD&lAHE@r8%F$R%*qFmAYUHC18Sd@I5$eA8i
9d69hM5*"(LK--$QUZIe8Ej%(kJ@`'B4UlJ1U!@[ERYI6kp%eplir`f&Gfr-11LD
kjNj9[`05IKqQ(ZUDqcP9-Y(2%C99G*!!CRfXbh1TGb-UkfFmVda2bMYZ0GIhA)1
erZH9#&4cYHH)IbD[aSKVk*VVBlBYdJ`5&DlLTQSmHkSI*AEEh!h[5,kZfSM!$$`
[)4Yq#1Y0h6Fq'XAdI&#M0f5F#2d+kSJ&Q1[K%0YJjpi"AJ$XbQIRPhb5%LfbeII
d183EQ218492--qKI)8484XUepiU9#Vj$,i!k32RCmMJfe!p9#j%[9!Y[&!0!YLM
-qe'Z6$frXNH&`Frf0f4aTLj9"dQ[`NKFUGUZiNaGr-[Br(89+I8(+-kr&Zr`Hk#
ALVe5R'rq"faqPh@QDTq+-h[Ked33r&U)ESQ+-hY-HH-2cDEZcZ,-hLJQkqqXfD$
DSH,-rYKGf-4XY+J3)QIZSL1@f'a9KITqkC06'ccrRI#YIZfUiRZZT3[brRH61rG
D&QV2%Bp41qTPe9A&aea(R2I3SI#ZX8VNpaFP0dEr5E'Br2eLTEUMlpAJGF4LmVm
LVZ*h9ImIh5bURrQ@UVIZ"RYIjh@TIZE[9EI1hb@8PN9P4rk$RmIQphA(+EF8mfR
kUAZaqE0)BcqHFBMmNlq+cHriMU964F`Rrq[L%hKA&Fe,-ZD6Ie39`TqC'#rZU*K
2df[&9G$h8CM)9TAYHE99%PNhq[A8D@)qqI[9$I2lqH2&CJRcfkU5IJ0r[(L8UK$
j2k+H*V+CK1q"55bcDD9k-DKY+M[HPQ9(dhAU6U#c)EmVP&qUGZ5I8!GAj$P9)R"
(pClj4p3hfjZp`)FcETcrZ2LG2bJfr[k-Vc80r"BfriEFmH,6P'XIK0%NP%IU"A!
lL1*VqCDLZDAYH5AXL2KDdiq,UD2(,EpVC99mV@P!A"6p-P9Cd@P6fG'd9P8&3aI
bq`&FL[KDrV"Bc'eCR1K8Ufj$rK2+&23cj6GI&9Lp@Y12L'QM2b@r694*kMBdr55
pMi6H9(jh+EY9&ZB2kYA[D(YZ9#GGaGPm5081R%*9#2!"&@Icfm9[hYAfr*!!Q,q
+XrQ[e*G"cC'em#[UUe#fIeAE%$!eS0J5-Qp509TLIr65i2VD-kc6Q#bSJXQKRK(
Qr`%!N!30#e4ME&0SC@aXFbkjFbkj,VNJ*L"6D%aTBJ#3"lp+!*!2!HR'!!*2j!#
3!aErN!4069"b3eG*43%!VllJ3l#%l`d!N!8#51`!N!BZi3!!Dri!N!C92!B!a6)
h)e[bY+hEMK`R@r&E`JQRA@jTYYN4IQl+*EHCVAeH8GPkQpTah8mfi4422CR+$Tq
rm8rjq4djlLE(1X,)*M`**EH2E(,mb)6Y)rX)2m)fZdeSqmMam`JRa`NMV)[m*YY
1k`NlFTa`)r`*[`JRqb4d(pPN$qb08+$$(c!eZmlbY[6i18Jj*CcmIX,*FE,*FI,
lb*lJ1F&IepQSXdPfAV'ADefXcR0l0SKYZZf-RGcVBJZlcGakRGFeB!YVd,1Yfqp
BREQFpMD`JEf$cP"JAZIeIZGhC*m0NLa(GRiDBC[FcSrX1&Nmblad1A+,PjfpQF"
B!!&hkhQGAAEjf@NmZYRPKQbch-m)Jl`MqpN#`"D!J2(!Pqph&9cA9NUPB'HVe,*
[`(jHU3rUm'r3m101AGAl+GL[+hAa68V0(r&A$MQjNeAUlV[TH0l`a"rhN!"G0XS
`5AVMi3jZ$H%3bpr@@qZ01VFr2(h(Sk*5kirqRk)0D(06Ye4[bBfNQdrEH,)DMP6
%1!XPcGI*h2f6U1bFR`cc4K-h2IlPd#M($r16N!#SLr,G0eVTZVGZfA)bD0RQ")!
XE-9m!VhA`!BcR8p5fC5!3,jlj)b&26cUYdR!R5Q`8pP(-rl4ID'DHf('GBb#HkE
#MF$1CZeJDP[P[p)#SET0HdBl2'ZK@S)bh+c8,c+*&(fDB,B@*impp*8,E1l+YG9
j[VR"f[ak2[b&k)plZRri()mc2jGV4d,2lcl4Ah[bFFi+bP#i0%Yk)h1X3cDIP02
i(E$R8ZflfY(8(k[B%pIaJ('b%R-UbmfLdb4BhTCCIf0R`@ieMD,Tjh,Tmjf3!2Y
Edr5Ie6F'SH(r#d#NA%Z03[0Q+f`eR+*YqZmN-%KJkBP0dDkKI!lp,f4UA0iUHlD
TS`rD&k*P$ceqbi9@8)VaY@8Ib[QGZ+bV$L3")1h`#DY)I+AfE%UE&CAQPQZ8qT!
!6[kVb!3+YF+1)C88#`FA,KM-K@f$(3XlRSa[J*dA@,Mjma338RkHV(GP6r'pmlh
#0q-fP#lXc2RZ4V-3kKNV++KMS5XYTb1YTpfbCa'TLX(2AR%03XmbejM1bFJPPV2
T,eGUZUA)EL-S'2C8UKUpd[!GbqN,MNF[,&UK1h(P)YHCb('aFC-aPElf`-,0S@p
-j0I9(i4Z@ErHh(+ckaFRSZFA#QB3k$NM,%f%,ZLhl1+V14fli[V*jL(b"#X`JX!
Xpll5#S6hpKD"IFAY@T*H[(LUYD,JMCh9eC*"@QQ[G"-5UU8MFP2T#1mY(B(Gc5f
RS[UkY6[G'*64FZHDp[(3NmfY8j9HBIKpCUMRc6!m@HT&Z,%pBhKH&,Zq0!@3!%P
N#4q6f"JHbi(D"Z8i@qpLrL9XV!Dl"Nk#&4Q6'!1-585#Llf99`K,BP086))68%`
L%da-)Q0),!FQX&+1VVC6M)I&`KAKX#HfVjN8$)X08X$#FZ"Jc3T)@)i$##Y"[Gd
C`f!5QD"J%TQ#B"%D%Jb8L18Pdck1IbkUK(dZ,XDp*%J,RX6BZZCc,@&G'ZKDd`8
UaMQr`6IR6E#YA&'&)4HABTS,62$-459BjU*L(%Z#%Ma))Y2@L,%VAj`LETAL+Sf
KH*8[HJ'VNU#qZK3`+SN"RiS"jHk+FFP&*CMNSP)mbVGaJNA(VYJd4FL+S598+JE
(d&5*e'*A!Qf"5d8S)99[Y1[+BV4L9M()!&Fa*%'[[Kj3p#N'TcK@M%l!V"LD)&S
a0)De5Q5#)CA`hYk+8Dj8[b,89B-hGTD#AUPA#XKALGa8ZJ)'9J)"`TkS[Qk0)E%
BQZ"L-63&aa*H*!KTmF"%,E'##FhNd4ekeJZYXVAeK$"L8'CCIqK"K1b*2$9c2%V
dkf9j2@1L1&AbQ@4D%4Sdd8UJj*N%9G*dj#"*XFMe0,eLN!#NjJ)UD4AE+XQY"ii
e`Cj)bE)B98NeJUG05&fq)!(VFR5+%18,LL"4$Nr`[K`G3hj[F!+G[6FSH[E'@UL
X0%84rMI'1`C3LBp)3$NZDHebG0cGIF%$"E2YA`lm+3+N2,,rJX&bar5Q0hK,QaC
)6QmX2+F[X,mG%VC6MNi)6cQk41$,m6'(l`hZ,f9*EPU`jMA*aiDQSSq0kp%XE'K
C3E1"U94NidTL84b@bM*aE&kBLD1Uj5f,4XA)@$CbN8iiXK%Thl*a*FD9K288Sm$
&E%J[bE2"2@*J+E4D[T,1&BIeYe44kiUM91e+3LU&648['jG!R@IL2!9f,Ha6BFq
"I4,XNf'C`AiDl,Q`Cm1ZJEd3pJcB&m0H#RXQl%YJA`Ul'[D2B4N01arfkE#8HMd
X)deR`Ci1qdaBQG)12J[lH0JR`$i4pP@`Pm0H!AXPl-YKA`Pl&HbVB9m$qc,B9m"
H$IYDf0I"[Kk@1EFh`Vi*pXf`Ei&p+qcEB0m1q`lBGm*H"RX0l,YJVi@p$TB*dME
BFE$MB9YKam"1J*d)bcKj#f`$l,4SZLe3@f$r",B*PX'Vjm$@`qCJpi1G$,Xrl!'
`8f#R`YU*f!0K(b#6@3`KbTbHQH4LC28`f-0Kjm$+M&C`&Hb$BBq!24*f,LbcD!I
$2Kcf%0L,BCm,qd$Bjm%bEGF"1`[f+0LMBBq"PHQei&VBHE#cBDI$2Jbf%eE'N!!
$cYFI"$X6pRf`liHp%IBQf2I![KG@CXD#[E!IK(dhl!f`Ym$H#RXEl)GJ2``VmhV
"IYL2`Yi1qc(BMm0q![D6X-c`A3ql'2D2B'A',mM!RJ6lD0M(`#k$lBBp%CCacY0
J6i#p"2B&X!YKA`Ml)YMjX!YJ(`Yl-Zabf"@`Tm#H#VX)pMMBPE#VB"m"qdKBT[c
-5*hAi9![qSmk8A2kJ&kRYm%!X*IDJJ(8P4T63fT*IF&1F"GFTXjJ'Ed2jY$Rp!D
B$SD"(q!%@!4fdH[d'[e(,i*lB!Zp!6D"(r30r@Ha!lbJ$fh[d%[J#(J%eS"2B"U
B!hk"Vf!HH!LHJN2J'lh0S8r"26!4I!8l`6c`&i`#%m!!-!eX"UIJ%H!XZ!Q1JJe
J&aJ1jS)0i!Mm!Pi#Gi&R`%(!'l!DlJ)f`hr!II!GV)HAJ12J2$`)22BB('QbDE!
0X2["6SHG$0X-f`Bl&[BJf*Q`(E$d06dk1aVkRSAbKl!Cf#cX40Kkf"aX!f`EE#Y
X#bbG3IFFHJ'EKMU6"bIP)CE(d!rd!$J"AS!IC1"h114[XBYkf2kh0H034qT*lDL
KAq&3NpQc@Bj$B0YK'f!lB'I"(Laadf#R`cE$cSKUQ"`I`!)'(mcjhpPm,m"a@eI
-%A4USqM9C90f@PqheD*'NTc6fh,kfXBEb0IZhfT4(2bqIcG#[$1QZXdN[cpJjrk
*3JllNm@"I-fc#0Jc+ZMYQcNdFD5)LV5k*`@hTB6QUfYUAp0Gf'39U9bZc!-+2#&
l80`+KHKB0QXC,GKLV@@%pLk3!0EL&mS"Gh*3-5`c3l'!BA*3,5a@SEVBI&"2BC`
F9&)B+JGebLTr+*X`4!kUT@A6+*'@MD1Q@I4(1820iA`1&Jl2q4YB&![1Yf"45MM
r$S[#3RQTSeQ%*6i8&G35I#K0q2'KXU$+i%1YSIli8*&34[#K6U%Ni80&3XR"KiU
,BS-203lP"Kq+,+S02K4$mX@(!JMQik1@U$AirJirU&$ilXB2+JqqIm-2DJIY55e
4TI"4#j3aI+K6U&Ri8(a3Zr#K+1NbN3b9(e3SI#MCe"`ILLfU%cl34&@H$09Xe#P
mp#J+($l86K3iI035K3lIAq%(93hIRILK*[Mq#6qSBIKqK"rk#hJ")m!6I23KUKS
qkSZkKXmUD[K3Ue$Fm+&JSE,K3kP(QF1(!XbGq-!Be$Ym+0f+T&R@6*A1l'2iJ@A
LZ`XrU)[irK8r5JlVL'ZSI2MS@rS,(r8#(r#KX+(-i81C4+R$"di3L`q9('84(qS
ppF5(HSrUL!rm3rA%Kj+-)SR[-rK"%FAh&F&HI1!%+LLq(q)(M!+L`@[UJ!qX"!I
`J8dSTIM!!T4@I239+LSqkSLULJpe%884(`SJIRbSkkL$q*K-3&h%4bhT6AcJ")S
X2[!Ep4(I"Z%,q-"XF-P5#C4EI1!iUL3qkS4DLBmq4`A'4jhS,hc8J[VJ!`p3-[(
"PTMSm08F0MqYYK`VY!`E8dbl8r!!U%ZV3p-[@ii4[TZq2d&0fVBYdDP"i6mc(Ge
HD(9UCARZ'!CZEV!E`Z#pk5f&623@@%&kbhdl(`[VQr)k@D&,9BY6m5b@+(kVc88
CPmVM%eJGp4Y&,pR5jKAB%MCaE%[BqY,9'%"2&S9*h*)NLLeKIIh0,1A`fGPrNGT
6h$5CQ8haCbVUJBU6)ZM`-9[#VY-He[kF'KVI#PRT63r3m86-+1aNNS-NX*rV&0Q
C4F8*BkLS3mE$KA,lmX!mJdGQf%m#@QF,rYQT2bI@)[SB)FF'f2Nr%j!!V,+!4l4
(SlT"aX9'P[0X!h2!CrL'[d9PeSYVV4Q0&p[!GUaYE1m`!lIIahKi%%El(1GlAK[
%K6N&qPHBJAJN-Zr%Xkah)jcVV0ibdTe6G#ZqS-f"1[!NSf!Lc5$IPZhUVJ-aR%2
[8JbJQrq9kBjq"f2BCdGKmpIPfr4dj4BTdH(d58+DZLh5R'0V1)*F)4T*AQX@pEJ
AmfYhiN)(Sd@1'hH19bMaQRPepA9"b4j*9MTJR98`3XYeN!#[H105,9d[ATcG[[P
+!@bZl9IUf+&KjVH$-3iS@((SXHdDTP6F)eIQ+d8Ab$@Q#maXZI&%r53jZ-CCC#a
FELeC89b8VS4TQiQl[4*Y!MY2V+b8U2DfXZIkS8lf[X#`EGGe8-ae(R%M'UdR8T`
kUBjAaX'$H&3mk%jR@eV'FT!!3I2BRH4X#A"R"DlDdAh&1db$&1S#Z#l0V4phfmU
S8bZ$Yj!![3PHhJjNFCf`HU36SMK3jS6fpXKEl+am[2@@N!"-)P*SN!!3pCI`VLp
p[5[1Z(!pC8Nh2pJq-@d5"4pk["*4P%XSKU[m-J4T1Eh(`"l0''&Q6hV9lSe5S%V
QIVL"K%ZqFrBceT%0FHGM)c#!Y"6ZLjV%A8&pf2m3A`(UFD[&FUVPk!%iQJ4Da14
'8eB$Hk@#N@%DR$D%)`8'U5*-6['j5+ZLG-3K5c2@Q8("Yl``ESK#3$lRq"DED#(
'e11FLC[L+K8M6AH93dUm"QDhB!ei@hkc3i+p#pE%V1"-e`PFfk`,`[lHJ*c[(0a
r8R[c6DB64Rk6d,*m)h`qTj2"4%QN@hYJj+a*YHPX8h1YAY[8f0Q)hqkfG+H-9[P
5cQpRGB[lkDd+(X9UN!"FBHGGhBS+TdReU9CbjI34A5Y4VFK(%Q&@D&-q%PSrF[d
@&H`h-aXp%`pj29$+ab4IL!bClYY4qA+Pa$NMUU82B4V@Kj!!B65C*E-118`DQS(
4`8NYkCSaicV2'8[Ih*(1R)F(B[V"9c20hDq4jqH)I"5[Er"09#6+jKF65S+b9Tl
lriMZ*Sck%Cd"CHDLImpbE)$N`[bdQ80RN!$8$*!!mVS!$K1NCR,8AXhSU*'3!!L
!FHlNVNaRV$PeKfrQf)l"YQA-d(G[0[e0JFj'DmpIhU%[dZS(lp2U0kcUbZSGV59
eKClRhi,D"5Z9YJkEX!jkY'E"f[J9"ST+"XTQr&5QhM+(8LYh2kPfl0JaBX2RlZe
44imH(EG[`240l,pKeki6GpaRUcAY[5[0hIpJEhr``B5%21ha4p3GI1L2p4,J`pE
FJeNemIl'`[l%R@I-q$K@crfKV%(`Z4hr%eYYEqAq4c`4@rf*["e&rJeE,ILG6If
eZ1(iAVCDblRUMmp3(@UekXqP&TIQY512AIAER9prr8I[UqEGImqZ[YR4Xd0jf$e
-jXe1BY(Zd0ckYark'6BIqN,H+*3lQ!#3!,ArB9*Hhcc&PXl)AGUr%A,[EA32'0)
iF`pidc4c$hM%0Y$U2@(e(M#VCI3HZmDXI!qieMTj6j`hZ-Ifd9Sqi1,ibAXZUGj
M0LVrY)j-)cem+Zq#JleSamhF`jkd4mlF`eD"*D2hp)dAQ,Imj0q190R$X[8H2p$
b$&rcmFY06(X!*MjDaeE491rh`8emL!+D[",0E&6CHH,pF(k!ZHKB!3d(9-FXTA(
rUTemPQ1QX12M"9&!T42$$jcFEZ12k-3q,6VUa1,U1l-96rE6jV@jC,QG8kr0#`e
PTqe2lf(fGd3le,RH*mcF`mlN+C1DCC`hfZ[8mjUUh)0@1[qm"LT4l-apa-`pD+8
$@[1ZHb3H6AUNMK*[jM"UfVA%Sb'2e&[LkBZ4HNXmZl0(kmJqj`(0[(!2QdF(Y2$
#2H$&D4`!-2Y$L[R`#Jjl$kaM"(mNLThE!l-*KA[Bf$%`ke#iK`dI!c--KA[Bicf
LQGplMiIqH-hHcq&&f-B8R@4,FS&i9ULdjf`6XTIQh,mGVR#'-AMRaL+6'Jpb5&I
hdlk!Fr9j!$b8SA+I$q!&X(k5JmKURml$%,"pAJmRILD3!%m#,Rd)0,(kZ!0YM6c
)H*ifNr#i,11*0T0`G11$fdcbZqdMXGqHdFdNkIfe[(IA*kj(rlhhjVeh1m[Q[[%
(p0rZHr`(GUJ(Ulfk%81#iD5j#GZ@kT[iGNrBZXfAr41k2ZLGDJFYNeF"&ADU$5N
AIJ$fA2*[9Lj'eBEdIcGlV[VlmpjElpr8`hq3!2IZI@C$2GPrAfdA@jT2pC6c3"5
ZE5Z,Yj&&eXZ`VEckjKdIh9D6`Y0+Gjiaidp6mG4T,Z`$mAqm3!ZQe0U4cFSEbl5
`*hCdM6cV-T`lqU)HQDPCe0EHc1F[k[mXqHq3!2q$UcGRDNkm`%H#Z%L5VZFr1aN
+&fB['RqKM`bYD9E0FYPNr[-35[e[P@6-2I,I*[rM*AkFh$pGlVIj6"1rZ8rZDC!
!rlCU-HUL*c[NRlQLTC2Efq@rSATE`r[(RYNM(D3Cf6+E#XLG-k4#TR,LRmPr9SS
8FQQHce`+Vqq*hXkM"C!!bkE)rp468kck1$Z[cr&'c%a[d6!m!Lm&NcJb(GQ*+[G
`aFLZ8lRRClY6!8Ijj8@Nd6hQHB$ZZ*fMFJmML[Np+jPApmS!ir,,kdUMHl+[lT@
"2XM[[-PlA(,3#rRYR,Q(r62(cpc$ATj(cGc$Qe"'pX$)2HcP'GQcSUp%AC[![ir
&4h!J2(!jmhrcpPpLPr4U[NSj1EkDp3hHPE2e[B$Y543[jK(dbX,@`EE#MS'YKmh
"0X!f`EE"MS8G$kZ[1Hdj%8kDe`XB*5*XD1Jc(G1h#Jh+Y&f[M"GSGAVaZmAA0q!
G@[+XS2`0AV*MC+"kiX$6M+5b$Yq'!mKhZ85ikD0)bFl)HrZAphYmkeqR[,l3TiB
1)@82QBSSiB!ESr+R)B("!AP29fGe!m$b%#rEA1-A4`E61U2A2(DZYT`'pHB0rLi
F-"06ScKJrXiVPpd%VfD[i8$$Ah&!f+1[M#ND(*!!9apd0[#*VQ[#j$EGd1#![0Z
hXk%KirTQLiAANEB[V9YHYbaT$4&#$cM!FPLQVmfD9"YT(!mFh$idK2(M'a2@3+&
i*Q,8b+i+MP$K#+##[16r)Dr2UrR3cRiBfbfL`SQ$(ri1hXCr,0qilfmllE,[)im
+Fm%9IUa8H@59XjrY,1"kT!39ZM$[RaNHrY@K"$G-m&#mLIE,!b-HXpNSI9J#-Eb
d*Sfc$bHS2P`KQYM2bF5qG`K!2"`RHV"5[,R"e`B$-!PK2jkic3heLA!6qhFQaNh
XJ`-H[iRpl[jHl!GZEh-+GRma)B`dr(TLhdF'!KB(r(!6qcFNaNhXhaP0l'I8qkG
IDMSehSMkKm0$9RKpJ"mJMk@CpYARla&Ufpj@TJC+CI[Z@*TVEdN)b'0PZLNCS+i
RjcXQ-pbCaiVQlXkkhT)U"%'pd[k`A9fdGR5MIq1Zb,I!X'dAVd!ibE3VVlX*[hT
2j![cm45EbH2-FrR+iaUkPU3A,hkp1f`H$ekF&*!!ajD#r$b2,BrDqApjE%jNHaj
RErE8S3HfaIekdp1PiGq[dZLIp!6QrLlDV6V-VHSb6(XdVLP'2ETKA`hLEpB1lHr
4lVTiH5@2TrbhAhP1J-PM5hZ3!%Hh%43-qh4KScc@m*N6AS!mcMaEf9TGH8k-c@-
)LEER-Icd%pUeGN`HkeAT$%j,'HB(C48"Y3e0FAT91M[0BlKMd4Y-jLbhd$pGY1%
$rhK'i,r"'VEQXEjNpjkrTl[jI&8PM`[k%`,bi-a"NrbZVVc(Bq39-Ii2aLf9lE[
M2XBpQ)FhJ(%[@lefqQNM5h2VTq[Kq@$Z!e@pMlQ2j,'0ZBrNXBfjhj2(9ZCHbk2
'h$R+h-2EjrFN!$$hMIAi&A-I,1a1jPl,BaYchjM',jPl,BpKjLjjM*!!piLjRph
hrllhIM"ZHFe5hahh-Hk"2$LH!-DpdR+@I9cI[1+D5FEGp$CMNM`f)m1pM'NNMfe
-jjimYM+G@Klh)[R'2(k*j,8mKN&2mT!![Vq(QFqaVE0S99!N0R@)j(&HlmBcH5c
Vh6LG4e2QM3Hc0fBbkGDr`pr!q4RLGF@GH%mHkmja4FQ$&j`bChSq4Sl5iVU12X[
FN!!380HpR-&ak@&1[Mf2'R)1pjRVM`[1YYR26N[d,,e0'$-f8KrA1!p"94T3SDS
RVd,G09"4(ld!HA6C3D!!-3)J!hN)eP2Ai)a1EP4$,d!pM0VR"FM$URe$H@aAqji
5PQfe&fq9)ip,X4%Y[%-l![rNcpGV!`FpY8[Emm5q[GZdRGF46!l!Ne(14IccY6f
20fN$cdFEe%`H6f8A$GCMY-p8C9RVRHjA*"B$4*[bi&f&!CqIZ,I[MFVL"HKASl*
i!I,J4(!@r+HZ*JpTMq"rrI%BecRhd,-`NmQpmp5jmZ(K@$AU%Fa,RTKmk-VHH9U
ELSlYXD&M1)`A))r&'rd0GE#rUbZXe&maXcKdUP`S2ANZp)Iqb(1K2r5V2f"@c(#
K[IJ"!TpZHG-61+0ep8mSeacP9,q[UmPMq-@MShQ-2"6a`15h'DqKXjhTq*9Q[2B
Hcp+-erRH@ACDUkZ2B-TECXAf(Jr)V0K'!2RPV0J!8[X#CX8+cfVZZk3KHB+jHbU
BU4F!1Id+5$9kDSYb2##DMXGP8ml3m4"S-AkJ66PlMfGT8mjf,DB[%5r"aTh04cI
ZE$lqVBdlYI(rS#DTB[jr'i2cEq`4Z*GjEFcM9maVX#!lQ9FY$qr%IS6Yc+X[%Er
!RS8S$r2NjB&$%V+00#)&Qqla!c!#NiGABZr$2[A$5cr@[6G!H*[R2Y(#5cm16)a
lk3GmS&RQLaVaahc4Q2Hd$r0&(VUh[bFi)&lI'L8`1*!!6BbE-r[jI*([E-kX-6&
ZcXc-&hRIjXbLq5*Ih*aCLjSerEUYi6-ZhC,"jGIQVE*RQjf&%iY`IA#6Dfa*@h2
qP3iqQ-1E-4BhhY")feC9Dm`V6*CIhU%[dZS(lp2U0kcUbZSGV59eKClRhi,D"5Z
9YQirRUVpqCS&De@IhT@0%Y+hGQIdeN(aE%LYh2fN'KiHMYcb(cjhEmqBhpR8AiX
EMUr@G#6RUMmq3h@SeDSrPeTFQYH12(E9EhGqrI8I[DqDGrmpZrTQ4mm1jL&l8r`
[,+(RC,!L8bD$cHGp1C0UdpQQjPUpYUQaXa'rh@hTcYT%PIVVQrZR#N`+)L53!""
UpeIZi3heVC9lFRc5I1'Lr$h6m([#j$dZ1EPR1RiAcY`c!lq,+[FdM0pc5I8HAS%
bBDU1KAYQiRI*k$ep"%(ZkF"[if3qm6fcm0X`Fmr"q'fDZHF3r1D5!qlCTe)iXT0
V3Q@SSAeK21C`k0XTb-9,iMH'Y1cV2T!!"&#5ih'Fma4Y3*ZEZZAB$GNAq"HYLM&
(ITZLal'dCr[2,'NIcYT8%8jDep5qTVZ`b5VQI(IMq[aV,d(`TVe8q16SGE[Q0,C
qKEr9pjGNPQb0I1(45k**"!r6qdXHXRA9f,XhT4mI0I95BBRG`(l0,,P9eeimM#%
a2pK,K5XiAAfTF)V6I[1A#RX4Q,XIk"9V3mbGBeqXqmdMp3N!c0d[p9,K[Afr6m[
`8Z([I[XTX08"&DTkmLV8c-'+qZJ&b+2b8Z&+(Y8AfDDUQ&%0[3$e-'UI&b!2UrB
0jE&Gl61[Fedb-2T5iFbF9$ImmP,Kc,c2(9)r6eflp+Af!bRpm01i8PiU21jRL2q
ce,8,YkIQID'qNSGjRHYJ28ElV2*5i8SHeCF+ThP8ALUmTaj'CI%#p+Y4@E`!HA#
+,aAH8eH64r*5i6ejl#2D[&6B-lH*-rc0Vb0Iq2@lG[,I3l@*dr4[Y)Pc6E"*Vdc
8HpFfFDBilB2Ia2PljZj$fX3CVG[h"c"hRpBQcT'qhkGPf-4jmj8rJUVdLif$H4A
UM6XVkU-A))rl0h'QUTK4$Ed!p6"URaFJ$k[f$H@aAHflCa2RXEHIfX4jl+dR0h%
1eQ1dcqlIa*RQFImQcM32Sl*i!IV9U#aHJ$`iZcGaTR8eHIak%fHDalk9cLE1aD2
!eVJVm[91q,rfRXJAjJm2m0r$T#pZH'$Ef&kRN!$qRKI@Q4lGX+m'm6GVKrEhD(G
G[,b5KcGU%qI2phR&QcJV10flLE1%dhlc6CaH"1EZ"jV5hXEF`p[Rpb3!-(I[d5E
1AdaAlqhlI9U'6CaVR)HJ+JfS80@69k(Z'ULSMek!2#UE1#Yjp'iF,+PL4MAd!Y6
$U(eHJ$cF*Xj0H@aAqmcfZ3rN4MGaKRGS4q#A6CcK`%&2ADAYU9faGjZfmcU#L@c
LE(-3rhaYcf@2D!22iljiqpaJ28ElV,+*Xj*(lbE18Kk96CalkQ&8&Lp![aU9a3Z
3!!HRZ)Pc6ee0(XNQcMejl#2DE1,-`@E9((VNN@DY5Q[iGiRpB)Gh[)A!JFiqdc&
pUj!!f!B)B3SrGF5"TaR*E4KJF!!q8+p5$I%Bb[*qMibbXp8dLUBI*+N"3fKMMMm
mJ3-L9Mc$m#dc33d*3Zjcb"!(cJjppfE6ha6SqG"`LSCIK-`0'Pc8N!$*Yq[TKY@
@dk$H[-(IK31L&qEH`J(cGekjl$S0ZIjHfbVSE8l"lLmQK*%'J`-0Im8"BBpH-K#
`10")[I"-,&YF%bDh5BEKTF#"*Z*!CmEec4DXh9b[,keEAVFXD3d4$"pSIZrBmZE
fVIfkMi2cjRCr(!kB[8$a#GAdq*S(jkbq-3L0XeML36KKp)UA0HGR5hd`KdRRaBd
h00+f9EI@Qpd"bbr[d"GTpB2hDI8E9R9PpBl@NVT#cr0[3Hf#P8TEYeqTMcjDXf#
YkY1lXY*jjQ6deN(aE%LYh2fN'KiHMYcb(cjhEmqBhpR8AiXEMUr@G#6RUMmq3h@
SeDSrPeTFQYH12(E9EhGqrI8I[DqDGrmpZrTQ4mm1jT%l#%UceV&#bl#YVHGfGf`
m(J"'Y$SdrE,P'1'lkCZh5IJ3Z)5(i`MlRjLhbTjYkTd&@emBP+lf[-+LX5Z)LqE
-@[EKF8MI3BJXGPKe)!'K0Z%RFG4hTICX5TX9eH8@+"RlkqKQH@@`IYkA-kNfR@e
UVY9VQaSl'r(EhCEZV%eLD31,!`I#@UbI"jX9hmQ`9ZeLadkpq&i-blZR10I!STY
`2JAE+,i[`cD*lapKQb9PmQN4hd(iD48IZ$9'I+IMCkcid%AEa(FjIKJY`(FMIXD
,lbra-d&mhm$242(p$eXpmQ9Birh%abkYbH*EM*rpaEF@2l*hbrKHJ*mTiRXpIUD
+li25,rMZ`-m$a!I+6iYp@IE'G2(0a-m-m4f((j8+XphiSIliRSiIlX(h-[adL1q
Gq*NP[NrLjf$ar5eq$K(I[q"(SDZ126aEI04&@8NGHrT"iMX&2kTBelRi18amj(f
iq-KlM[KJ,3m4heIa3qrJqajqMSappHcEZH)Mjk2%p`MmQ2I5Lqp8r"`M2NLYUU[
eGq,RSH*lKq!2[SrLjf(Lqa*qp2%6p82iHAMXba&(k#Pmp!2jiL2QNH*EJ4rP4$R
f0bYfm&f-RrRLZ`Sr1S@EqaCq9"r22B)IRBE0X3B,aAFAIR5k,2F5INk-I3h%*Yh
mf-!qH,6ib"qF`8IrkAam!l9SR8CZf)kITH)$EaiM[[IM*e,*JMRI`ip+iJe(mI0
BmIfcB$A`#`BX&amB32hadEINMSqkdiriq&mT2LDD`59mi0pTiRX6IX"NI1$Iim3
(rMeHI0r&ca0LAa-arSRL!a0ALimqee9!6Db&,ZKTiUb"k[Y01r#M-`00c&[hT6A
GMam9-TTqJKrGVp9%(0,0$FhN%MVIdda-T0ra8@r9rCZC[qi,Dpk#(jhLE[ibIR5
QX*NUj,RLSmEJ*$lkAVAKjTIa!fl,D5%Id)Qe&Z+GcNkdX1G9`'PK(AA'Sq8fr$a
,I'r%ciAL%l8Jf#`qm)Eki2X(r1MSC#Xjfjq+MlbI)ck`'%c$"bim9hc8QRcaJ6'
-LZ"l!hiZ%4pjdqri[S#I&iV[QrMK6R`r`!qm6miBmV&,a3H[H)Ri`%Vk&api!DI
!4qeH,MjkqM,aL4)F%2rab8VQi%[Lqdrm[#VfM58hJrIKSlId"GeML9YALSrH!m2
aF4HpM1mQr1M1[l'2iHGUmAdE2kq0I@hNY+m6(a`-l-8(6k"(m)'$p#NqqSdDiRX
,IYiX[NrJ"cqqVq(RVH,l-AlH&[['N8rUAX"aj%[`(AcJ1j`,(aJ%TmC(Rla,I2#
5DmAh'IaF*lkramqlBppiBX0la!IfAbmqqZB'mC%VZH!$+pQ#M3pFJ'[JSarJerK
Z`3ppK1qcq&'&IMah9(j!I2q&(hL"R!RNfpb*$djfUrMJBlH*$q`(cr&4l`q,MaU
!4IMS*I!"(c(`3AaJrqhLJh0m,2C0*1IqZ2LS2If)$qi+GmB(Ce-9EL,j#AU&TqR
8$AA`N62#[5DTFK"@ThhVKMl9U9+,`)UEYb'bX'1MEZJcd$UQ)5,,519RK31LcND
NXVlScY1!+I1!Fif5Te&M6H5TB-32!JVN'%P@,[)dF*lf&bQ*4ARDb1MNb"+D24p
lN!!c"kR81$8e*$E1LL0[*kijr6`NJp!l$bIk@B8Yd-McVSSMAd&-Gp0P'6,FaA(
N3kPN@I8YZ)#DcE`imR(NA&D,LeMkQ$LbMFcI+R14eR"%(2PbmM'Vd`9cb'`dcjZ
)P&De#pT`Cje%[SMBVaUHA)&+-#Q1R%,%9d92$PamDKcjXFIK8he2L)!S0j0kiXK
A-hY9qq5!lh9aj11*bkVp5AI!A!k))dmKNUX5+!IFeilkm-2`U5iSI8-AMSdM2d)
QU#UKT!J(rh3Fq5Pb6G8-TB%+(A8#kkN+SP3!IDBeM[`XApZ[HU)dZY3cI#+1[*'
-5Y9&U3$F3l[M[Fa6Y8Dj$f9$UcDCl%b94kN!YIQ,1,+&[&ae5"(hK(Q(Pm54(b4
DU#STR3[hqfJFq@eU%DT4#P6!bZI%N5(CVLU@)Rm*&QDNRY1T'DPq+H+6-,9--Bl
m$k+3!+UCJISqY+LM[KK(6U-f)0UQS,%`rEQXl!(P-#"1+`l@$A@MBUH#McHmVaa
'@h*Fj'R)XC(-q1KbD&09XC%Gck"r-cpQjmUG)(JbSe"AaGa[%4088D@ImjKl$2A
,r#JQ#SAHH6Q9$&9E"AcKm)UjAk6HSGUV("LP)YkjC1kUa%SAJZ@+%*1S[kSZ+l8
"V44clk"US5UYG'%"FbmR,eI09L),Q,Z"D1''$lV4paCclbBI9MeAlU6E&9@H6FE
YCNiDH)GLlQdrJ%qehN#p$-A@BZiel%3hUaa5Ke$-[C!!U+3kX23RADLBqbbU1DS
+UmDR(E@3!2UADX452Y4CaGc[8)e3a9L+40D+Z9G6ae,p@1j%+G@1ZTjXAp9NLD6
ZLP&I)ZDUYL`#XU#+aGb!@+K+Xpb*MU6Gm89LQZV1%NQP,AD!'kT#5bRJ'SUjee%
cG41r#c'qC6(h@e3r9+'@Y1"!LVP[TYkXHVANLF+LQ(XVle2e@Q44kAD,ZGqQrZ)
HmV3DM-pLlVQr4B!Ufi&@KKjR-AFLX8FdlEUKpDMjA(JFjLV$&$BV1Z2CB#5j9B+
j,[*dm-#CB,0"[@#ZMHai'KbUJleL-6HCp`V*4V9[$U2bUHUk($3iaGcEb!G8DjI
XBD*kjq1)mhBD+@JKBLRQ[TVBVMUmS-S24l(`Fe6"9*8A3%$c8B3iL(UQfj496p9
G-IG5pTfED-p`2N!apaV@e'fcbR)L3r2m#T959I0&SKAYbQ,Z!mJ(h1DB,"8b4CA
h-8G9qJ9cZ8-aG`)Vl9jmF$Akdf,ZhH6J1J8J"ie9-IFLGSV1"%LP[cq+Z9hdZ3e
k1I*DlDKR%BRFpV)QpSPLlN[*HA9k3'4qf,9LlVZT-HSXJ@!((%)lkJjU"6TC)*(
JQQ,8&@3NG[3qF+"`@X`pKbLV8`Gb*pUHGXG&e2"d"N'k!j9GUhB"F83R%U3fp*G
LlKH)[cUI)!+kU2X@Fap'(UA6#Y+Se&-aG`he5TeG%)5%b5RQ(NJ&@#FC4%BAIQ)
ap`kb#jeV%2&FXV'Bqh'bHCeb#,42!&8XjKj($9-k40LX-*!!ZCa1X*LVfSf`@G'
&cN)0``("h(bNB%#'#UN`B)1j6Zma6!%HC$%hL64X6r[QViNE1QNK&8#(9m`G5dD
MFaH#KI5ahRN9'CP1B3KBdDf+Z4G3fG'C$+NbM-SL(MaA*c3%LHKl4BLh8hqfUjZ
$TH5#LVPAF+,,V9F1141KQ$Z$f1&f04a&Y9Ac[*JFh'f$Z"MpBM(hJCb,F([aMb(
5+kTmJ`MTaPH2T(k[Q$Z2R-2Z@!rRJB90,X@4AbFlGlXmc9b@BZlhU35jr5pcUD)
VjVk"16[Gm%MLV(E8Fri%RpXC-CIpTCKlqqrJFj[Rcb"q+ZDqLE--6VNmQP0%9Ue
$9h+EUqB5qa5MEL(,GTVQ1Z4T-II2UA$S")Td&(a0Zq09R'e`Z`VQ8Q(3UKh)6YI
T&+N0(&Sap`M@aHQYjf-+a@,Z&839YrAM%ZVcLVR2T%VP"T'2MTLreSEZF*Y,AS"
D@-cp(KQRcVM)%)RJY-AFk84MRAJ*Y+p"(l5BZiV+SmbrL!BXfGj+hR#5B+kUSS+
XSSpFKXKF56$A4Di!FR93q6K--0G'GK`&VRH3!$0Bc(9hVJ*ZA!pqdqbA`lja$IK
8)2&98(Bb(bYl!Hl-4ki%ehS*TM,#Kh,Y33Kf$K,TT)l36G"(9HMmRFY4e3iLh+f
S!$f@9m3%(@C4khZl4$VH[K,h2BL+a'b*G1aL*AMl#Q,XZb3bf8Kb#(%YkX+'$*8
'Yh6Y%#SQ8HFfIZ3T8L%E@8Gp-%,*KKHTNHK8NHJhi0SCFH6GC"SkBb3XKQP!cI0
jj0BkF56iLCi@jGR`3r*[R6m5VN)24(NfANTY6DH4T'rS!FhcR94eG$C*q!#+NHC
j$R&0*j@%@+1%D*jIilbTcLh4CrPkISJX3DHB"&$JcjVR(Db6cM3*#U%M4(NfcQD
11Z%NiJmiShdcLlfQmdk#3LLZQZGrF`T9TjqNRR5Gj[N$mJkCK4)F%0ai"R99LfZ
UkBY+Fi$5PJ)rRAlM)PHKCpDc8be#f-L1Sp!FCP%lYlMQlP`1,*p&hL$BBE$3c3k
BHU)q4M`UDj!!CHYXPJ`Mb&58DKIC1eJeRG3+0+TSLZ$CUmQBG@iVd&i!$l))rNV
QUP0F8NY33ERAPmJVGDC,+N"r4Y`V@dr-eJN[b36H%E'Bl(ELTmjlbCfI(q9HAk@
qU00I3LVK34(hb[B5jh8@61k%L8AF+pY$K0(*-%'9JUlrBfT'lQdB,`1b+[I+pT(
MkY5Bb%p`S1M1V%HQVM0N%JQ1+5HkN3a6*mS#l5VJKI,Fl!l1DHTmQ@JNU&RD(Cq
QKUc6CN)$d6XLl-KHH!3qR6d6Q3Z'U28mL8LNNfK5!HDe)RDH[BbcEMUA*RI#Sj3
aANY8e5NeZC-j+Q@-Rk6@TM0V!ReS&a&Mc*Bj3k)6E)&@"bh*-XBl1DIQhVRa'R)
0CB`r)YlSG*Z!(6J3G8HfMTaACpd#E3Q`64PMGJGhCqMNQr3RHNfNGf4A%Tpd$Nj
i,XLU9EZC'VK1a3RSdd@4hT(p009+RC%6'%-Y8EAK)q6Y1M%Rc33UG*H$9fB1&P#
TXT'*-YV&HYV)K(YeNA[Cb!4cMb&A'3GH#&p20*q6f,QAbCdDqAm!N!-K)3jdBfa
0B@03FQpUC@0dF`#3&Y%"J!*L!hF!N!-"!!)JN`#3"aB!N!1'!!!#!2q3"!-!V6C
3$,#%lk8!N!8-8kd!N!8#6elrerrl!*!'F!rhL`!!:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to mac/tclMacResource.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclMacResource.c --
 *
 *	This file contains several commands that manipulate or use
 *	Macintosh resources.  Included are extensions to the "source"
 *	command, the mac specific "beep" and "resource" commands, and
 *	administration for open resource file references.
 *
 * 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.
 *
 * SCCS: @(#) tclMacResource.c 1.35 97/11/24 15:03:58
 */

#include <Errors.h>
#include <FSpCompat.h>
#include <Processes.h>
#include <Resources.h>
#include <Sound.h>













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclMacResource.c --
 *
 *	This file contains several commands that manipulate or use
 *	Macintosh resources.  Included are extensions to the "source"
 *	command, the mac specific "beep" and "resource" commands, and
 *	administration for open resource file references.
 *
 * 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: tclMacResource.c,v 1.1.2.4 1999/04/14 00:34:52 surles Exp $
 */

#include <Errors.h>
#include <FSpCompat.h>
#include <Processes.h>
#include <Resources.h>
#include <Sound.h>
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
    int objc,				/* Number of arguments. */
    Tcl_Obj *CONST objv[])		/* Argument values. */
{
    Tcl_Obj *resultPtr, *objPtr;
    int index, result;
    long fileRef, rsrcId;
    FSSpec fileSpec;
    Tcl_DString buffer;
    char *nativeName;
    char *stringPtr;
    char errbuf[16];
    OpenResourceFork *resourceRef;
    Handle resource = NULL;
    OSErr err;
    int count, i, limitSearch = false, length;
    short id, saveRef, resInfo;







<
<







130
131
132
133
134
135
136


137
138
139
140
141
142
143
    int objc,				/* Number of arguments. */
    Tcl_Obj *CONST objv[])		/* Argument values. */
{
    Tcl_Obj *resultPtr, *objPtr;
    int index, result;
    long fileRef, rsrcId;
    FSSpec fileSpec;


    char *stringPtr;
    char errbuf[16];
    OpenResourceFork *resourceRef;
    Handle resource = NULL;
    OSErr err;
    int count, i, limitSearch = false, length;
    short id, saveRef, resInfo;
392
393
394
395
396
397
398

399
400
401
402
403
404
405
406
407
408
	        stringPtr = Tcl_GetStringFromObj(resourceForkList, &length);
	        Tcl_SetStringObj(resultPtr, stringPtr, length);
	    } else {
                FCBPBRec fileRec;
                Handle pathHandle;
                short pathLength;
                Str255 fileName;

	        
	        if (strcmp(Tcl_GetStringFromObj(objv[2], NULL), "ROM Map")
			    == 0) {
	            Tcl_SetStringObj(resultPtr,"no file path for ROM Map", -1);
	            return TCL_ERROR;
	        }
	        
	        resourceRef = GetRsrcRefFromObj(objv[2], 1, "files", resultPtr);
	        if (resourceRef == NULL) {
	            return TCL_ERROR;







>

|
<







390
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
	        stringPtr = Tcl_GetStringFromObj(resourceForkList, &length);
	        Tcl_SetStringObj(resultPtr, stringPtr, length);
	    } else {
                FCBPBRec fileRec;
                Handle pathHandle;
                short pathLength;
                Str255 fileName;
                Tcl_DString dstr;
	        
	        if (strcmp(Tcl_GetString(objv[2]), "ROM Map") == 0) {

	            Tcl_SetStringObj(resultPtr,"no file path for ROM Map", -1);
	            return TCL_ERROR;
	        }
	        
	        resourceRef = GetRsrcRefFromObj(objv[2], 1, "files", resultPtr);
	        if (resourceRef == NULL) {
	            return TCL_ERROR;
425
426
427
428
429
430
431


432
433
434

435
436
437
438
439
440
441
                if ( err != noErr) {
                    Tcl_SetStringObj(resultPtr,
                            "could not get file path from token", -1);
                    return TCL_ERROR;
                }
                
                HLock(pathHandle);


                Tcl_SetStringObj(resultPtr,*pathHandle,pathLength);
                HUnlock(pathHandle);
                DisposeHandle(pathHandle);

            }                    	    
	    return TCL_OK;
	case RESOURCE_LIST:			
	    if (!((objc == 3) || (objc == 4))) {
		Tcl_WrongNumArgs(interp, 2, objv, "resourceType ?resourceRef?");
		return TCL_ERROR;
	    }







>
>
|


>







423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
                if ( err != noErr) {
                    Tcl_SetStringObj(resultPtr,
                            "could not get file path from token", -1);
                    return TCL_ERROR;
                }
                
                HLock(pathHandle);
                Tcl_ExternalToUtfDString(NULL, *pathHandle, pathLength, &dstr);
                
                Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&dstr), Tcl_DStringLength(&dstr));
                HUnlock(pathHandle);
                DisposeHandle(pathHandle);
                Tcl_DStringFree(&dstr);
            }                    	    
	    return TCL_OK;
	case RESOURCE_LIST:			
	    if (!((objc == 3) || (objc == 4))) {
		Tcl_WrongNumArgs(interp, 2, objv, "resourceType ?resourceRef?");
		return TCL_ERROR;
	    }
467
468
469
470
471
472
473

474
475
476
477
478
479
480
		    resource = Get1IndResource(rezType, i);
		} else {
		    resource = GetIndResource(rezType, i);
		}
		if (resource != NULL) {
		    GetResInfo(resource, &id, (ResType *) &rezType, theName);
		    if (theName[0] != 0) {

			objPtr = Tcl_NewStringObj((char *) theName + 1,
				theName[0]);
		    } else {
			objPtr = Tcl_NewIntObj(id);
		    }
		    ReleaseResource(resource);
		    result = Tcl_ListObjAppendElement(interp, resultPtr,







>







468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
		    resource = Get1IndResource(rezType, i);
		} else {
		    resource = GetIndResource(rezType, i);
		}
		if (resource != NULL) {
		    GetResInfo(resource, &id, (ResType *) &rezType, theName);
		    if (theName[0] != 0) {
		        
			objPtr = Tcl_NewStringObj((char *) theName + 1,
				theName[0]);
		    } else {
			objPtr = Tcl_NewIntObj(id);
		    }
		    ReleaseResource(resource);
		    result = Tcl_ListObjAppendElement(interp, resultPtr,
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
	    SetResLoad(true);
	
	    if (limitSearch) {
		UseResFile(saveRef);
	    }
	
	    return TCL_OK;
	case RESOURCE_OPEN:			




	    if (!((objc == 3) || (objc == 4))) {
		Tcl_WrongNumArgs(interp, 2, objv, "fileName ?permissions?");
		return TCL_ERROR;
	    }
	    stringPtr = Tcl_GetStringFromObj(objv[2], &length);
	    nativeName = Tcl_TranslateFileName(interp, stringPtr, &buffer);
	    if (nativeName == NULL) {
		return TCL_ERROR;
	    }


	    err = FSpLocationFromPath(strlen(nativeName), nativeName,
		    &fileSpec) ;

	    Tcl_DStringFree(&buffer);

	    if (!((err == noErr) || (err == fnfErr))) {
		Tcl_AppendStringsToObj(resultPtr,
			"invalid path", (char *) NULL);
		return TCL_ERROR;
	    }

	    /*
	     * Get permissions for the file.  We really only understand
	     * read-only and shared-read-write.  If no permissions are 
	     * given we default to read only.







|
>
>
>
>




|
|
<
|

>
>
|
<
>

>

|
<







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
	    SetResLoad(true);
	
	    if (limitSearch) {
		UseResFile(saveRef);
	    }
	
	    return TCL_OK;
	case RESOURCE_OPEN: {
	    Tcl_DString ds, buffer;
	    char *str, *native;
	    int length;
	    			
	    if (!((objc == 3) || (objc == 4))) {
		Tcl_WrongNumArgs(interp, 2, objv, "fileName ?permissions?");
		return TCL_ERROR;
	    }
	    str = Tcl_GetStringFromObj(objv[2], &length);
	    if (Tcl_TranslateFileName(interp, str, &buffer) == NULL) {

	        return TCL_ERROR;
	    }
	    native = Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&buffer),
	    	    Tcl_DStringLength(&buffer), &ds);
	    err = FSpLocationFromPath(Tcl_DStringLength(&ds), native, &fileSpec);

	    Tcl_DStringFree(&ds);
	    Tcl_DStringFree(&buffer);

	    if (!((err == noErr) || (err == fnfErr))) {
		Tcl_AppendStringsToObj(resultPtr, "invalid path", (char *) NULL);

		return TCL_ERROR;
	    }

	    /*
	     * Get permissions for the file.  We really only understand
	     * read-only and shared-read-write.  If no permissions are 
	     * given we default to read only.
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
		}
		switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
		    case O_RDONLY:
			macPermision = fsRdPerm;
		    break;
		    case O_WRONLY:
		    case O_RDWR:
			macPermision = fsRdWrShPerm;
			break;
		    default:
			panic("Tcl_ResourceObjCmd: invalid mode value");
		    break;
		}
	    } else {
		macPermision = fsRdPerm;







|







533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
		}
		switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
		    case O_RDONLY:
			macPermision = fsRdPerm;
		    break;
		    case O_WRONLY:
		    case O_RDWR:
			macPermision = fsRdWrPerm;
			break;
		    default:
			panic("Tcl_ResourceObjCmd: invalid mode value");
		    break;
		}
	    } else {
		macPermision = fsRdPerm;
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
	    SetResLoad(false); 
	    fileRef = (long) FSpOpenResFileCompat(&fileSpec, macPermision);
	    SetResLoad(true);
	    
	    if (fileRef == -1) {
	    	err = ResError();
		if (((err == fnfErr) || (err == eofErr)) &&
			(macPermision == fsRdWrShPerm)) {
		    /*
		     * No resource fork existed for this file.  Since we are
		     * opening it for writing we will create the resource fork
		     * now.
		     */
		     
		    HCreateResFile(fileSpec.vRefNum, fileSpec.parID,







|







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
	    SetResLoad(false); 
	    fileRef = (long) FSpOpenResFileCompat(&fileSpec, macPermision);
	    SetResLoad(true);
	    
	    if (fileRef == -1) {
	    	err = ResError();
		if (((err == fnfErr) || (err == eofErr)) &&
			(macPermision == fsRdWrPerm)) {
		    /*
		     * No resource fork existed for this file.  Since we are
		     * opening it for writing we will create the resource fork
		     * now.
		     */
		     
		    HCreateResFile(fileSpec.vRefNum, fileSpec.parID,
596
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611
            
            Tcl_SetStringObj(resultPtr, "", 0);
            if (TclMacRegisterResourceFork(fileRef, resultPtr, 
                    TCL_RESOURCE_CHECK_IF_OPEN) != TCL_OK) {
                CloseResFile(fileRef);
		return TCL_ERROR;
            }

	    return TCL_OK;

	case RESOURCE_READ:			
	    if (!((objc == 4) || (objc == 5))) {
		Tcl_WrongNumArgs(interp, 2, objv,
			"resourceType resourceId ?resourceRef?");
		return TCL_ERROR;
	    }








<

>







603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
            
            Tcl_SetStringObj(resultPtr, "", 0);
            if (TclMacRegisterResourceFork(fileRef, resultPtr, 
                    TCL_RESOURCE_CHECK_IF_OPEN) != TCL_OK) {
                CloseResFile(fileRef);
		return TCL_ERROR;
            }

	    return TCL_OK;
	}
	case RESOURCE_READ:			
	    if (!((objc == 4) || (objc == 5))) {
		Tcl_WrongNumArgs(interp, 2, objv,
			"resourceType resourceId ?resourceRef?");
		return TCL_ERROR;
	    }

625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
	    }
	
	    resource = Tcl_MacFindResource(interp, rezType, resourceId,
		rsrcId, stringPtr, &releaseIt);
			    
	    if (resource != NULL) {
		size = GetResourceSizeOnDisk(resource);
		Tcl_SetStringObj(resultPtr, *resource, size);

		/*
		 * Don't release the resource unless WE loaded it...
		 */
		 
		if (releaseIt) {
		    ReleaseResource(resource);







|







632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
	    }
	
	    resource = Tcl_MacFindResource(interp, rezType, resourceId,
		rsrcId, stringPtr, &releaseIt);
			    
	    if (resource != NULL) {
		size = GetResourceSizeOnDisk(resource);
		Tcl_SetByteArrayObj(resultPtr, (unsigned char *) *resource, size);

		/*
		 * Don't release the resource unless WE loaded it...
		 */
		 
		if (releaseIt) {
		    ReleaseResource(resource);
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
		        i += 1;
		        break;
		}
	    }
	    if (Tcl_GetOSTypeFromObj(interp, objv[i], &rezType) != TCL_OK) {
		return TCL_ERROR;
	    }
	    stringPtr = Tcl_GetStringFromObj(objv[i+1], &length);

	    if (gotInt == false) {
		rsrcId = UniqueID(rezType);
	    }
	    if (resourceId == NULL) {
		resourceId = (char *) "\p";
	    }







|







743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
		        i += 1;
		        break;
		}
	    }
	    if (Tcl_GetOSTypeFromObj(interp, objv[i], &rezType) != TCL_OK) {
		return TCL_ERROR;
	    }
	    stringPtr = (char *) Tcl_GetByteArrayFromObj(objv[i+1], &length);

	    if (gotInt == false) {
		rsrcId = UniqueID(rezType);
	    }
	    if (resourceId == NULL) {
		resourceId = (char *) "\p";
	    }
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
	    
	    if (limitSearch) {
		UseResFile(saveRef);
	    }

	    return result;
	default:
	    panic("Tcl_GetIndexFromObject returned unrecognized option");
	    return TCL_ERROR;	/* Should never be reached. */
    }
}

/*
 *----------------------------------------------------------------------
 *







|







905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
	    
	    if (limitSearch) {
		UseResFile(saveRef);
	    }

	    return result;
	default:
	    panic("Tcl_GetIndexFromObj returned unrecognized option");
	    return TCL_ERROR;	/* Should never be reached. */
    }
}

/*
 *----------------------------------------------------------------------
 *
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

    if (objc < 2 || objc > 4)  {
    	errStr = errNum;
    	goto sourceFmtErr;
    }
    
    if (objc == 2)  {
	string = TclGetStringFromObj(objv[1], &length);
	return Tcl_EvalFile(interp, string);
    }
    
    /*
     * The following code supports a few older forms of this command
     * for backward compatability.
     */
    string = TclGetStringFromObj(objv[1], &length);
    if (!strcmp(string, "-rsrc") || !strcmp(string, "-rsrcname")) {
	rsrcName = TclGetStringFromObj(objv[2], &length);
    } else if (!strcmp(string, "-rsrcid")) {
	if (Tcl_GetLongFromObj(interp, objv[2], &rsrcID) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
    	errStr = errBad;
    	goto sourceFmtErr;
    }
    
    if (objc == 4) {
	fileName = TclGetStringFromObj(objv[3], &length);
    }
    return Tcl_MacEvalResource(interp, rsrcName, rsrcID, fileName);
	
    sourceFmtErr:
    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), errStr, "should be \"",
		Tcl_GetStringFromObj(objv[0], (int *) NULL),
		" fileName\" or \"",
		Tcl_GetStringFromObj(objv[0], (int *) NULL),
		" -rsrc name ?fileName?\" or \"", 
		Tcl_GetStringFromObj(objv[0], (int *) NULL),
		" -rsrcid id ?fileName?\"", (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_BeepObjCmd --







|







|

|










|





<
|
<
|
|
|







950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983

984

985
986
987
988
989
990
991
992
993
994

    if (objc < 2 || objc > 4)  {
    	errStr = errNum;
    	goto sourceFmtErr;
    }
    
    if (objc == 2)  {
	string = Tcl_GetStringFromObj(objv[1], &length);
	return Tcl_EvalFile(interp, string);
    }
    
    /*
     * The following code supports a few older forms of this command
     * for backward compatability.
     */
    string = Tcl_GetStringFromObj(objv[1], &length);
    if (!strcmp(string, "-rsrc") || !strcmp(string, "-rsrcname")) {
	rsrcName = Tcl_GetStringFromObj(objv[2], &length);
    } else if (!strcmp(string, "-rsrcid")) {
	if (Tcl_GetLongFromObj(interp, objv[2], &rsrcID) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
    	errStr = errBad;
    	goto sourceFmtErr;
    }
    
    if (objc == 4) {
	fileName = Tcl_GetStringFromObj(objv[3], &length);
    }
    return Tcl_MacEvalResource(interp, rsrcName, rsrcID, fileName);
	
    sourceFmtErr:
    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), errStr, "should be \"",

		Tcl_GetString(objv[0]), " fileName\" or \"",

		Tcl_GetString(objv[0]),	" -rsrc name ?fileName?\" or \"", 
		Tcl_GetString(objv[0]), " -rsrcid id ?fileName?\"",
		(char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_BeepObjCmd --
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113

	    if (volume >= 0) {
		SetSoundVolume(0, RESET_VOLUME);
	    }
	} else {
	    Tcl_AppendStringsToObj(resultPtr, " \"", sndArg, 
		    "\" is not a valid sound.  (Try ",
		    Tcl_GetStringFromObj(objv[0], (int *) NULL),
		    " -list)", NULL);
	    return TCL_ERROR;
	}
    }

    return TCL_OK;

    beepUsage:







<
|







1103
1104
1105
1106
1107
1108
1109

1110
1111
1112
1113
1114
1115
1116
1117

	    if (volume >= 0) {
		SetSoundVolume(0, RESET_VOLUME);
	    }
	} else {
	    Tcl_AppendStringsToObj(resultPtr, " \"", sndArg, 
		    "\" is not a valid sound.  (Try ",

		    Tcl_GetString(objv[0]), " -list)", NULL);
	    return TCL_ERROR;
	}
    }

    return TCL_OK;

    beepUsage:
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
    int resourceNumber,		/* Resource id of source. */
    char *fileName)		/* Name of file to process.
				   NULL if application resource. */
{
    Handle sourceText;
    Str255 rezName;
    char msg[200];
    int result;
    short saveRef, fileRef = -1;
    char idStr[64];
    FSSpec fileSpec;
    Tcl_DString buffer;
    char *nativeName;

    saveRef = CurResFile();
	
    if (fileName != NULL) {
	OSErr err;
	
	nativeName = Tcl_TranslateFileName(interp, fileName, &buffer);
	if (nativeName == NULL) {
	    return TCL_ERROR;
	}
	err = FSpLocationFromPath(strlen(nativeName), nativeName, &fileSpec);

	Tcl_DStringFree(&buffer);
	if (err != noErr) {
	    Tcl_AppendResult(interp, "Error finding the file: \"", 
		fileName, "\".", NULL);
	    return TCL_ERROR;
	}
		
	fileRef = FSpOpenResFileCompat(&fileSpec, fsRdPerm);
	if (fileRef == -1) {
	    Tcl_AppendResult(interp, "Error reading the file: \"", 
		fileName, "\".", NULL);
	    return TCL_ERROR;
	}
		
	UseResFile(fileRef);

    } else {
	/*
	 * The default behavior will search through all open resource files.
	 * This may not be the behavior you desire.  If you want the behavior
	 * of this call to *only* search the application resource fork, you
	 * must call UseResFile at this point to set it to the application
	 * file.  This means you must have already obtained the application's 







|















|
>















>







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
    int resourceNumber,		/* Resource id of source. */
    char *fileName)		/* Name of file to process.
				   NULL if application resource. */
{
    Handle sourceText;
    Str255 rezName;
    char msg[200];
    int result, iOpenedResFile = false;
    short saveRef, fileRef = -1;
    char idStr[64];
    FSSpec fileSpec;
    Tcl_DString buffer;
    char *nativeName;

    saveRef = CurResFile();
	
    if (fileName != NULL) {
	OSErr err;
	
	nativeName = Tcl_TranslateFileName(interp, fileName, &buffer);
	if (nativeName == NULL) {
	    return TCL_ERROR;
	}
	err = FSpLocationFromPath(strlen(nativeName), nativeName,
                &fileSpec);
	Tcl_DStringFree(&buffer);
	if (err != noErr) {
	    Tcl_AppendResult(interp, "Error finding the file: \"", 
		fileName, "\".", NULL);
	    return TCL_ERROR;
	}
		
	fileRef = FSpOpenResFileCompat(&fileSpec, fsRdPerm);
	if (fileRef == -1) {
	    Tcl_AppendResult(interp, "Error reading the file: \"", 
		fileName, "\".", NULL);
	    return TCL_ERROR;
	}
		
	UseResFile(fileRef);
	iOpenedResFile = true;
    } else {
	/*
	 * The default behavior will search through all open resource files.
	 * This may not be the behavior you desire.  If you want the behavior
	 * of this call to *only* search the application resource fork, you
	 * must call UseResFile at this point to set it to the application
	 * file.  This means you must have already obtained the application's 
1309
1310
1311
1312
1313
1314
1315
1316

1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332

















1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
	 * We now evaluate the Tcl source
	 */
	result = Tcl_Eval(interp, sourceStr);
	ckfree(sourceStr);
	if (result == TCL_RETURN) {
	    result = TCL_OK;
	} else if (result == TCL_ERROR) {
	    sprintf(msg, "\n    (rsrc \"%.150s\" line %d)", resourceName,

		    interp->errorLine);
	    Tcl_AddErrorInfo(interp, msg);
	}
				
	goto rezEvalCleanUp;
    }
	
    rezEvalError:
    sprintf(idStr, "ID=%d", resourceNumber);
    Tcl_AppendResult(interp, "The resource \"",
	    (resourceName != NULL ? resourceName : idStr),
	    "\" could not be loaded from ",
	    (fileName != NULL ? fileName : "application"),
	    ".", NULL);

    rezEvalCleanUp:

















    if (fileRef != -1) {
	CloseResFile(fileRef);
    }

    UseResFile(saveRef);
	
    return result;
}

/*
 *-----------------------------------------------------------------------------
 *
 * Tcl_MacConvertTextResource --







|
>
















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




<
<







1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360


1361
1362
1363
1364
1365
1366
1367
	 * We now evaluate the Tcl source
	 */
	result = Tcl_Eval(interp, sourceStr);
	ckfree(sourceStr);
	if (result == TCL_RETURN) {
	    result = TCL_OK;
	} else if (result == TCL_ERROR) {
	    sprintf(msg, "\n    (rsrc \"%.150s\" line %d)",
                    resourceName,
		    interp->errorLine);
	    Tcl_AddErrorInfo(interp, msg);
	}
				
	goto rezEvalCleanUp;
    }
	
    rezEvalError:
    sprintf(idStr, "ID=%d", resourceNumber);
    Tcl_AppendResult(interp, "The resource \"",
	    (resourceName != NULL ? resourceName : idStr),
	    "\" could not be loaded from ",
	    (fileName != NULL ? fileName : "application"),
	    ".", NULL);

    rezEvalCleanUp:

    /* 
     * TRICKY POINT: The code that you are sourcing here could load a
     * shared library.  This will go AHEAD of the resource we stored away
     * in saveRef on the resource path.  
     * If you restore the saveRef in this case, you will never be able
     * to get to the resources in the shared library, since you are now
     * pointing too far down on the resource list.  
     * So, we only reset the current resource file if WE opened a resource
     * explicitly, and then only if the CurResFile is still the 
     * one we opened... 
     */
     
    if (iOpenedResFile && (CurResFile() == fileRef)) {
        UseResFile(saveRef);
    }
	
    if (fileRef != -1) {
	CloseResFile(fileRef);
    }



    return result;
}

/*
 *-----------------------------------------------------------------------------
 *
 * Tcl_MacConvertTextResource --
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
    int length;
    long newOSType;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    string = TclGetStringFromObj(objPtr, &length);

    if (length != 4) {
	if (interp != NULL) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "expected Macintosh OS type but got \"", string, "\"",
		    (char *) NULL);







|







1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
    int length;
    long newOSType;

    /*
     * Get the string representation. Make it up-to-date if necessary.
     */

    string = Tcl_GetStringFromObj(objPtr, &length);

    if (length != 4) {
	if (interp != NULL) {
	    Tcl_ResetResult(interp);
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "expected Macintosh OS type but got \"", string, "\"",
		    (char *) NULL);
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
 *
 * TclMacRegisterResourceFork --
 *
 *	Register an open resource fork in the table of open resources 
 *	managed by the procedures in this file.  If the resource file
 *      is already registered with the table, then no new token is made.
 *
 *      The bahavior is controlled by the value of tokenPtr, and of the 
 *	flags variable.  For tokenPtr, the possibilities are:
 *	  - NULL: The new token is auto-generated, but not returned.
 *        - The string value of tokenPtr is the empty string: Then
 *		the new token is auto-generated, and returned in tokenPtr
 *	  - tokenPtr has a value: The string value will be used for the token,
 *		unless it is already in use, in which case a new token will
 *		be generated, and returned in tokenPtr.







|







1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
 *
 * TclMacRegisterResourceFork --
 *
 *	Register an open resource fork in the table of open resources 
 *	managed by the procedures in this file.  If the resource file
 *      is already registered with the table, then no new token is made.
 *
 *      The behavior is controlled by the value of tokenPtr, and of the 
 *	flags variable.  For tokenPtr, the possibilities are:
 *	  - NULL: The new token is auto-generated, but not returned.
 *        - The string value of tokenPtr is the empty string: Then
 *		the new token is auto-generated, and returned in tokenPtr
 *	  - tokenPtr has a value: The string value will be used for the token,
 *		unless it is already in use, in which case a new token will
 *		be generated, and returned in tokenPtr.
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
 *	        resource fork is already opened by this Tcl shell, and return 
 *	        an error without registering the resource fork.
 *
 * Results:
 *	Standard Tcl Result
 *
 * Side effects:
 *	An entry is added to the resource name table.
 *
 *----------------------------------------------------------------------
 */

int
TclMacRegisterResourceFork(
    short fileRef,        	/* File ref for an open resource fork. */







|







1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
 *	        resource fork is already opened by this Tcl shell, and return 
 *	        an error without registering the resource fork.
 *
 * Results:
 *	Standard Tcl Result
 *
 * Side effects:
 *	An entry may be added to the resource name table.
 *
 *----------------------------------------------------------------------
 */

int
TclMacRegisterResourceFork(
    short fileRef,        	/* File ref for an open resource fork. */
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858


1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874

1875
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
   
    if (!initialized) {
        ResourceInit();
    }
    
    /*
     * If we were asked to, check that this file has not been opened
     * already.
     */
     


    if (flags & TCL_RESOURCE_CHECK_IF_OPEN) {
        Tcl_HashSearch search;
        short oldFileRef;
        FCBPBRec newFileRec, oldFileRec;
        OSErr err;
        
        oldFileRec.ioCompletion = NULL;
        oldFileRec.ioFCBIndx = 0;
        oldFileRec.ioNamePtr = NULL;
        
        newFileRec.ioCompletion = NULL;
        newFileRec.ioFCBIndx = 0;
        newFileRec.ioNamePtr = NULL;
        newFileRec.ioVRefNum = 0;
        newFileRec.ioRefNum = fileRef;
        err = PBGetFCBInfo(&newFileRec, false);

            
        
        resourceHashPtr = Tcl_FirstHashEntry(&resourceTable, &search);
        while (resourceHashPtr != NULL) {
            
            oldFileRef = (short) Tcl_GetHashKey(&resourceTable,
                    resourceHashPtr);
            


            
            oldFileRec.ioVRefNum = 0;
            oldFileRec.ioRefNum = oldFileRef;
            err = PBGetFCBInfo(&oldFileRec, false);
            
            /*
             * err might not be noErr either because the file has closed 
             * out from under us somehow, which is bad but we're not going
             * to fix it here, OR because it is the ROM MAP, which has a 
             * fileRef, but can't be gotten to by PBGetFCBInfo.
             */
             
            if ((oldFileRef == fileRef) ||
                    ((err == noErr) 
                    && (newFileRec.ioFCBVRefNum == oldFileRec.ioFCBVRefNum)
                    && (newFileRec.ioFCBFlNm == oldFileRec.ioFCBFlNm))) {







                
                resourceId = (char *) Tcl_GetHashValue(resourceHashPtr);






		Tcl_SetStringObj(tokenPtr, resourceId, -1);

                return TCL_OK;
            }
            
            resourceHashPtr = Tcl_NextHashEntry(&search);
        }
        
        
    }





    

    resourceHashPtr = Tcl_CreateHashEntry(&resourceTable,
		(char *) fileRef, &new);


    if (!new) {
        if (tokenPtr != NULL) {
            resourceId = (char *) Tcl_GetHashValue(resourceHashPtr);
            Tcl_SetStringObj(tokenPtr, resourceId, -1);
        }
        return  TCL_OK;
    }
    
    
    /*
     * If we were passed in a result pointer which is not an empty
     * string, attempt to use that as the key.  If the key already
     * exists, silently fall back on resource%d...
     */
     
    if (tokenPtr != NULL) {







|


>
>


|













>




<


|
>
>
|










<
<
|

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


|
|
|
>
>
>
>
>
|
>
|

>
>

|

|

|
|
|
<







1871
1872
1873
1874
1875
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
1971
1972
   
    if (!initialized) {
        ResourceInit();
    }
    
    /*
     * If we were asked to, check that this file has not been opened
     * already with a different permission.  It it has, then return an error.
     */
     
    new = 1;
    
    if (flags & TCL_RESOURCE_CHECK_IF_OPEN) {
        Tcl_HashSearch search;
        short oldFileRef, filePermissionFlag;
        FCBPBRec newFileRec, oldFileRec;
        OSErr err;
        
        oldFileRec.ioCompletion = NULL;
        oldFileRec.ioFCBIndx = 0;
        oldFileRec.ioNamePtr = NULL;
        
        newFileRec.ioCompletion = NULL;
        newFileRec.ioFCBIndx = 0;
        newFileRec.ioNamePtr = NULL;
        newFileRec.ioVRefNum = 0;
        newFileRec.ioRefNum = fileRef;
        err = PBGetFCBInfo(&newFileRec, false);
        filePermissionFlag = ( newFileRec.ioFCBFlags >> 12 ) & 0x1;
            
        
        resourceHashPtr = Tcl_FirstHashEntry(&resourceTable, &search);
        while (resourceHashPtr != NULL) {

            oldFileRef = (short) Tcl_GetHashKey(&resourceTable,
                    resourceHashPtr);
            if (oldFileRef == fileRef) {
                new = 0;
                break;
            }
            oldFileRec.ioVRefNum = 0;
            oldFileRec.ioRefNum = oldFileRef;
            err = PBGetFCBInfo(&oldFileRec, false);
            
            /*
             * err might not be noErr either because the file has closed 
             * out from under us somehow, which is bad but we're not going
             * to fix it here, OR because it is the ROM MAP, which has a 
             * fileRef, but can't be gotten to by PBGetFCBInfo.
             */


            if ((err == noErr) 
                    && (newFileRec.ioFCBVRefNum == oldFileRec.ioFCBVRefNum)
                    && (newFileRec.ioFCBFlNm == oldFileRec.ioFCBFlNm)) {
                /*
		 * In MacOS 8.1 it seems like we get different file refs even
                 * though we pass the same file & permissions.  This is not
                 * what Inside Mac says should happen, but it does, so if it
                 * does, then close the new res file and return the original
                 * one...
		 */
                 

                if (filePermissionFlag == ((oldFileRec.ioFCBFlags >> 12) & 0x1)) {
                    CloseResFile(fileRef);
                    new = 0;
                    break;
                } else {
                    if (tokenPtr != NULL) {
                        Tcl_SetStringObj(tokenPtr, "Resource already open with different permissions.", -1);
                    }   	
                    return TCL_ERROR;
                }
            }
            resourceHashPtr = Tcl_NextHashEntry(&search);
        }
    }
       
    
    /*
     * If the file has already been opened with these same permissions, then it
     * will be in our list and we will have set new to 0 above.
     * So we will just return the token (if tokenPtr is non-null)
     */
     
    if (new) {
        resourceHashPtr = Tcl_CreateHashEntry(&resourceTable,
		(char *) fileRef, &new);
    }
    
    if (!new) {
        if (tokenPtr != NULL) {   
            resourceId = (char *) Tcl_GetHashValue(resourceHashPtr);
	    Tcl_SetStringObj(tokenPtr, resourceId, -1);
        }
        return TCL_OK;
    }        


    /*
     * If we were passed in a result pointer which is not an empty
     * string, attempt to use that as the key.  If the key already
     * exists, silently fall back on resource%d...
     */
     
    if (tokenPtr != NULL) {

Changes to mac/tclMacResource.r.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * Copyright (c) 1993-94 Lockheed Missle & Space Company
 * Copyright (c) 1994-97 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacResource.r 1.19 97/09/23 12:51:41
 */

#include <Types.r>
#include <SysTypes.r>

/*
 * The folowing include and defines help construct







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * Copyright (c) 1993-94 Lockheed Missle & Space Company
 * Copyright (c) 1994-97 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: tclMacResource.r,v 1.1.2.2 1998/09/24 23:59:17 stanton Exp $
 */

#include <Types.r>
#include <SysTypes.r>

/*
 * The folowing include and defines help construct
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 * require some predetermined file structure - all needed Tcl "files"
 * are located within the application.  To source a file for the
 * resource fork the source command has been modified to support
 * sourcing from resources.  In the below case "source -rsrc {Init}"
 * will load the TEXT resource named "Init".
 */

read 'TEXT' (0, "Init", purgeable, preload) "::library:init.tcl";
read 'TEXT' (1, "History", purgeable,preload) "::library:history.tcl";
read 'TEXT' (2, "Word", purgeable,preload) "::library:word.tcl";

/*
 * The following resource is used when creating the 'env' variable in
 * the Macintosh environment.  The creation mechanisim looks for the
 * 'STR#' resource named "Tcl Environment Variables" rather than a
 * specific resource number.  (In other words, feel free to change the
 * resource id if it conflicts with your application.)  Each string in







|
<
<







63
64
65
66
67
68
69
70


71
72
73
74
75
76
77
 * require some predetermined file structure - all needed Tcl "files"
 * are located within the application.  To source a file for the
 * resource fork the source command has been modified to support
 * sourcing from resources.  In the below case "source -rsrc {Init}"
 * will load the TEXT resource named "Init".
 */

#include "tclMacTclCode.r"



/*
 * The following resource is used when creating the 'env' variable in
 * the Macintosh environment.  The creation mechanisim looks for the
 * 'STR#' resource named "Tcl Environment Variables" rather than a
 * specific resource number.  (In other words, feel free to change the
 * resource id if it conflicts with your application.)  Each string in

Changes to mac/tclMacShLib.exp.

193
194
195
196
197
198
199

200
201
202
203
204
205
206
SetForeignPrivs
SetHasCustomIcon
SetIsInvisible
SetIsStationery
SetNameLocked
Share
StrToAddr

TclAllocateFreeObjects
TclChdir
TclCleanupByteCode
TclCleanupCommand
TclCompileBreakCmd
TclCompileCatchCmd
TclCompileContinueCmd







>







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
SetForeignPrivs
SetHasCustomIcon
SetIsInvisible
SetIsStationery
SetNameLocked
Share
StrToAddr
TclAccess
TclAllocateFreeObjects
TclChdir
TclCleanupByteCode
TclCleanupCommand
TclCompileBreakCmd
TclCompileCatchCmd
TclCompileContinueCmd
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
TclDeleteExecEnv
TclDeleteVars
TclDoGlob
TclEmitForwardJump
TclExecuteByteCode
TclExpandCodeArray
TclExpandJumpFixupArray
TclExpandParseValue
TclExprFloatError
TclFileAttrsCmd
TclFileCopyCmd
TclFileDeleteCmd
TclFileMakeDirsCmd
TclFileRenameCmd
TclFindElement







<







247
248
249
250
251
252
253

254
255
256
257
258
259
260
TclDeleteExecEnv
TclDeleteVars
TclDoGlob
TclEmitForwardJump
TclExecuteByteCode
TclExpandCodeArray
TclExpandJumpFixupArray

TclExprFloatError
TclFileAttrsCmd
TclFileCopyCmd
TclFileDeleteCmd
TclFileMakeDirsCmd
TclFileRenameCmd
TclFindElement
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
TclInvoke
TclInvokeObjectCommand
TclInvokeStringCommand
TclIsProc
TclLoadFile
TclLooksLikeInt
TclLookupVar
TclMacAccess
TclMacCreateEnv
TclMacExitHandler
TclMacFOpenHack
TclMacInitExitToShell
TclMacInstallExitToShellPatch
TclMacOSErrorToPosixError
TclMacReadlink
TclMacRemoveTimer
TclMacStartTimer
TclMacStat
TclMacTimerExpired
TclMatchFiles
TclNeedSpace
TclObjIndexForString
TclObjInterpProc
TclObjInvoke
TclObjInvokeGlobal
TclParseBraces
TclParseNestedCmd
TclParseQuotes
TclPlatformExit
TclPlatformInit
TclPreventAliasLoop
TclPrintByteCodeObj
TclPrintInstruction
TclPrintSource
TclRegComp
TclRegError
TclRegExec
TclRenameCommand
TclResetShadowedCmdRefs
TclServiceIdle
TclSetElementOfIndexedArray
TclSetEnv
TclSetIndexedScalar
TclSetupEnv
TclSockGetPort

TclTeardownNamespace
TclTestChannelCmd
TclTestChannelEventCmd
TclUnsetEnv
TclUpdateReturnInfo
TclWordEnd
Tcl_AddErrorInfo







|









|







<
<
<

















>







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
TclInvoke
TclInvokeObjectCommand
TclInvokeStringCommand
TclIsProc
TclLoadFile
TclLooksLikeInt
TclLookupVar
TclpAccess
TclMacCreateEnv
TclMacExitHandler
TclMacFOpenHack
TclMacInitExitToShell
TclMacInstallExitToShellPatch
TclMacOSErrorToPosixError
TclMacReadlink
TclMacRemoveTimer
TclMacStartTimer
TclpStat
TclMacTimerExpired
TclMatchFiles
TclNeedSpace
TclObjIndexForString
TclObjInterpProc
TclObjInvoke
TclObjInvokeGlobal



TclPlatformExit
TclPlatformInit
TclPreventAliasLoop
TclPrintByteCodeObj
TclPrintInstruction
TclPrintSource
TclRegComp
TclRegError
TclRegExec
TclRenameCommand
TclResetShadowedCmdRefs
TclServiceIdle
TclSetElementOfIndexedArray
TclSetEnv
TclSetIndexedScalar
TclSetupEnv
TclSockGetPort
TclStat
TclTeardownNamespace
TclTestChannelCmd
TclTestChannelEventCmd
TclUnsetEnv
TclUpdateReturnInfo
TclWordEnd
Tcl_AddErrorInfo
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
Tcl_GetsObjCmd
Tcl_GlobCmd
Tcl_GlobalEval
Tcl_GlobalEvalObj
Tcl_GlobalObjCmd
Tcl_HashStats
Tcl_HideCommand
Tcl_HistoryCmd
Tcl_IfCmd
Tcl_Import
Tcl_IncrCmd
Tcl_InfoObjCmd
Tcl_Init
Tcl_InitHashTable
Tcl_InitMemory







<







522
523
524
525
526
527
528

529
530
531
532
533
534
535
Tcl_GetsObjCmd
Tcl_GlobCmd
Tcl_GlobalEval
Tcl_GlobalEvalObj
Tcl_GlobalObjCmd
Tcl_HashStats
Tcl_HideCommand

Tcl_IfCmd
Tcl_Import
Tcl_IncrCmd
Tcl_InfoObjCmd
Tcl_Init
Tcl_InitHashTable
Tcl_InitMemory

Changes to mac/tclMacSock.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclMacSock.c
 *
 *	Channel drivers for Macintosh sockets.
 *
 * 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.
 *
 * SCCS: @(#) tclMacSock.c 1.59 97/10/09 18:24:42
 */

#include "tclInt.h"
#include "tclPort.h"
#include "tclMacInt.h"
#include <AddressXlation.h>
#include <Aliases.h>










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclMacSock.c
 *
 *	Channel drivers for Macintosh sockets.
 *
 * 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: tclMacSock.c,v 1.1.2.3 1999/04/14 00:34:53 surles Exp $
 */

#include "tclInt.h"
#include "tclPort.h"
#include "tclMacInt.h"
#include <AddressXlation.h>
#include <Aliases.h>
236
237
238
239
240
241
242

243
244
245
246
247



248
249
250
251
252
253
254
    {"shell",		514},
    {"printer",		515},
    {"courier",		530},
    {"uucp",		540},
    {NULL,		0},
};


/*
 * Every open socket has an entry on the following list.
 */

static TcpState *socketList = NULL;




/*
 * Globals for holding information about OS support for sockets.
 */

static int socketsTestInited = false;
static int hasSockets = false;







>
|
|
|
|
|
>
>
>







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    {"shell",		514},
    {"printer",		515},
    {"courier",		530},
    {"uucp",		540},
    {NULL,		0},
};

typedef struct ThreadSpecificData {
    /*
     * Every open socket has an entry on the following list.
     */
    
    TcpState *socketList;
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * Globals for holding information about OS support for sockets.
 */

static int socketsTestInited = false;
static int hasSockets = false;
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
#define gestaltMacTCPVersion 'mtcp'
static void
InitSockets()
{
    ParamBlockRec pb; 
    OSErr err;
    long response;







    initialized = 1;
    Tcl_CreateExitHandler(SocketExitHandler, (ClientData) NULL);
	
    if (Gestalt(gestaltMacTCPVersion, &response) == noErr) {
	hasSockets = true;
    } else {
	hasSockets = false;
    }

    if (!hasSockets) {
	return;
    }

    /*
     * Load MacTcp driver and name server resolver.
     */
	
		
    pb.ioParam.ioCompletion = 0L; 
    pb.ioParam.ioNamePtr = "\p.IPP"; 
    pb.ioParam.ioPermssn = fsCurPerm; 
    err = PBOpenSync(&pb); 
    if (err != noErr) {
	hasSockets = 0;
	return;
    }
    driverRefNum = pb.ioParam.ioRefNum; 
	
    socketBufferSize = GetBufferSize();
    err = OpenResolver(NULL);
    if (err != noErr) {
	hasSockets = 0;
	return;
    }

    GetCurrentProcess(&applicationPSN);
    /*
     * Create UPP's for various callback routines.
     */

    resultUPP = NewResultProc(DNRCompletionRoutine);
    completeUPP = NewTCPIOCompletionProc(IOCompletionRoutine);
    closeUPP = NewTCPIOCompletionProc(CloseCompletionRoutine);

    /*
     * Install an ExitToShell patch.  We use this patch instead
     * of the Tcl exit mechanism because we need to ensure that
     * these routines are cleaned up even if we crash or are forced
     * to quit.  There are some circumstances when the Tcl exit
     * handlers may not fire.
     */

    TclMacInstallExitToShellPatch(CleanUpExitProc);
    








    Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);


    initialized = 1;
}

/*
 *----------------------------------------------------------------------
 *
 * SocketExitHandler --
 *







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







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
#define gestaltMacTCPVersion 'mtcp'
static void
InitSockets()
{
    ParamBlockRec pb; 
    OSErr err;
    long response;
    ThreadSpecificData *tsdPtr;
    
    if (! initialized) {
	/*
	 * Do process wide initialization.
	 */

	initialized = 1;

	    
	if (Gestalt(gestaltMacTCPVersion, &response) == noErr) {
	    hasSockets = true;
	} else {
	    hasSockets = false;
	}
    
	if (!hasSockets) {
	    return;
	}
    
	/*
	 * Load MacTcp driver and name server resolver.
	 */
	    
		    
	pb.ioParam.ioCompletion = 0L; 
	pb.ioParam.ioNamePtr = "\p.IPP"; 
	pb.ioParam.ioPermssn = fsCurPerm; 
	err = PBOpenSync(&pb); 
	if (err != noErr) {
	    hasSockets = 0;
	    return;
	}
	driverRefNum = pb.ioParam.ioRefNum; 
	    
	socketBufferSize = GetBufferSize();
	err = OpenResolver(NULL);
	if (err != noErr) {
	    hasSockets = 0;
	    return;
	}
    
	GetCurrentProcess(&applicationPSN);
	/*
	 * Create UPP's for various callback routines.
	 */
    
	resultUPP = NewResultProc(DNRCompletionRoutine);
	completeUPP = NewTCPIOCompletionProc(IOCompletionRoutine);
	closeUPP = NewTCPIOCompletionProc(CloseCompletionRoutine);
    
	/*
	 * Install an ExitToShell patch.  We use this patch instead
	 * of the Tcl exit mechanism because we need to ensure that
	 * these routines are cleaned up even if we crash or are forced
	 * to quit.  There are some circumstances when the Tcl exit
	 * handlers may not fire.
	 */
    
	TclMacInstallExitToShellPatch(CleanUpExitProc);
    }

    /*
     * Do per-thread initialization.
     */

    tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
    if (tsdPtr == NULL) {
	tsdPtr->socketList = NULL;
	Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);
	Tcl_CreateThreadExitHandler(SocketExitHandler, (ClientData) NULL);
    }

}

/*
 *----------------------------------------------------------------------
 *
 * SocketExitHandler --
 *
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
    ClientData clientData)              /* Not used. */
{
    if (hasSockets) {
	Tcl_DeleteEventSource(SocketSetupProc, SocketCheckProc, NULL);
	/* CleanUpExitProc();
	TclMacDeleteExitToShellPatch(CleanUpExitProc); */
    }
    initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TclHasSockets --
 *
 *	This function determines whether sockets are available on the
 *	current system and returns an error in interp if they are not.
 *	Note that interp may be NULL.
 *
 * Results:
 *	Returns TCL_OK if the system supports sockets, or TCL_ERROR with
 *	an error in interp.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclHasSockets(
    Tcl_Interp *interp)		/* Interp for error messages. */
{
    if (!initialized) {
	InitSockets();
    }

    if (hasSockets) {
	return TCL_OK;
    }
    if (interp != NULL) {
	Tcl_AppendResult(interp, "sockets are not available on this system",
		NULL);







<





|
















|


<
|
<







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
    ClientData clientData)              /* Not used. */
{
    if (hasSockets) {
	Tcl_DeleteEventSource(SocketSetupProc, SocketCheckProc, NULL);
	/* CleanUpExitProc();
	TclMacDeleteExitToShellPatch(CleanUpExitProc); */
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TclpHasSockets --
 *
 *	This function determines whether sockets are available on the
 *	current system and returns an error in interp if they are not.
 *	Note that interp may be NULL.
 *
 * Results:
 *	Returns TCL_OK if the system supports sockets, or TCL_ERROR with
 *	an error in interp.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclpHasSockets(
    Tcl_Interp *interp)		/* Interp for error messages. */
{

    InitSockets();


    if (hasSockets) {
	return TCL_OK;
    }
    if (interp != NULL) {
	Tcl_AppendResult(interp, "sockets are not available on this system",
		NULL);
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
static void
SocketSetupProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    TcpState *statePtr;
    Tcl_Time blockTime = { 0, 0 };


    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Check to see if there is a ready socket.  If so, poll.
     */

    for (statePtr = socketList; statePtr != NULL;
	    statePtr = statePtr->nextPtr) {
	if (statePtr->flags & TCP_RELEASE) {
	    continue;
	}
	if (SocketReady(statePtr)) {
	    Tcl_SetMaxBlockTime(&blockTime);
	    break;







>









|







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
static void
SocketSetupProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    TcpState *statePtr;
    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 (statePtr = tsdPtr->socketList; statePtr != NULL;
	    statePtr = statePtr->nextPtr) {
	if (statePtr->flags & TCP_RELEASE) {
	    continue;
	}
	if (SocketReady(statePtr)) {
	    Tcl_SetMaxBlockTime(&blockTime);
	    break;
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
SocketCheckProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    TcpState *statePtr;
    SocketEvent *evPtr;
    TcpState dummyState;


    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 (statePtr = socketList; statePtr != NULL;
	    statePtr = statePtr->nextPtr) {
	/*
	 * Check to see if this socket is dead and needs to be cleaned
	 * up.  We use a dummy statePtr whose only valid field is the
	 * nextPtr to allow the loop to continue even if the element
	 * is deleted.
	 */







>











|







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
SocketCheckProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    TcpState *statePtr;
    SocketEvent *evPtr;
    TcpState dummyState;
    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 (statePtr = tsdPtr->socketList; statePtr != NULL;
	    statePtr = statePtr->nextPtr) {
	/*
	 * Check to see if this socket is dead and needs to be cleaned
	 * up.  We use a dummy statePtr whose only valid field is the
	 * nextPtr to allow the loop to continue even if the element
	 * is deleted.
	 */
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
}

/*
 *----------------------------------------------------------------------
 *
 * TcpGetHandle --
 *
 *	Called from Tcl_GetChannelFile to retrieve handles from inside
 *	a file based channel.
 *
 * Results:
 *	The appropriate handle or NULL if not present. 
 *
 * Side effects:
 *	None.







|







1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
}

/*
 *----------------------------------------------------------------------
 *
 * TcpGetHandle --
 *
 *	Called from Tcl_GetChannelHandle to retrieve handles from inside
 *	a file based channel.
 *
 * Results:
 *	The appropriate handle or NULL if not present. 
 *
 * Side effects:
 *	None.
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
 */

static TcpState *
NewSocketInfo(
    StreamPtr tcpStream)
{
    TcpState *statePtr;


    statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));
    statePtr->tcpStream = tcpStream;
    statePtr->psn = applicationPSN;
    statePtr->flags = 0;
    statePtr->checkMask = 0;
    statePtr->watchMask = 0;
    statePtr->acceptProc = (Tcl_TcpAcceptProc *) NULL;
    statePtr->acceptProcData = (ClientData) NULL;
    statePtr->nextPtr = socketList;
    socketList = statePtr;
    return statePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeSocketInfo --







>









|
|







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

static TcpState *
NewSocketInfo(
    StreamPtr tcpStream)
{
    TcpState *statePtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));
    statePtr->tcpStream = tcpStream;
    statePtr->psn = applicationPSN;
    statePtr->flags = 0;
    statePtr->checkMask = 0;
    statePtr->watchMask = 0;
    statePtr->acceptProc = (Tcl_TcpAcceptProc *) NULL;
    statePtr->acceptProcData = (ClientData) NULL;
    statePtr->nextPtr = tsdPtr->socketList;
    tsdPtr->socketList = statePtr;
    return statePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeSocketInfo --
1501
1502
1503
1504
1505
1506
1507


1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
 *----------------------------------------------------------------------
 */

static void
FreeSocketInfo(
    TcpState *statePtr)		/* The state pointer to free. */
{


    if (statePtr == socketList) {
	socketList = statePtr->nextPtr;
    } else {
	TcpState *p;
	for (p = socketList; p != NULL; p = p->nextPtr) {
	    if (p->nextPtr == statePtr) {
		p->nextPtr = statePtr->nextPtr;
		break;
	    }
	}
    }
    ckfree((char *) statePtr);







>
>
|
|


|







1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
 *----------------------------------------------------------------------
 */

static void
FreeSocketInfo(
    TcpState *statePtr)		/* The state pointer to free. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (statePtr == tsdPtr->socketList) {
	tsdPtr->socketList = statePtr->nextPtr;
    } else {
	TcpState *p;
	for (p = tsdPtr->socketList; p != NULL; p = p->nextPtr) {
	    if (p->nextPtr == statePtr) {
		p->nextPtr = statePtr->nextPtr;
		break;
	    }
	}
    }
    ckfree((char *) statePtr);
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
Tcl_Channel
Tcl_MakeTcpClientChannel(
    ClientData sock)	/* The socket to wrap up into a channel. */
{
    TcpState *statePtr;
    char channelName[20];

    if (TclHasSockets(NULL) != TCL_OK) {
	return NULL;
    }
	
    statePtr = NewSocketInfo((StreamPtr) sock);
    /* TODO: do we need to set the port??? */
    
    sprintf(channelName, "sock%d", socketNumber++);







|







1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
Tcl_Channel
Tcl_MakeTcpClientChannel(
    ClientData sock)	/* The socket to wrap up into a channel. */
{
    TcpState *statePtr;
    char channelName[20];

    if (TclpHasSockets(NULL) != TCL_OK) {
	return NULL;
    }
	
    statePtr = NewSocketInfo((StreamPtr) sock);
    /* TODO: do we need to set the port??? */
    
    sprintf(channelName, "sock%d", socketNumber++);
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
                                         * asynchronous connect. Otherwise
                                         * we do a blocking connect. 
                                         * - currently ignored */
{
    TcpState *statePtr;
    char channelName[20];

    if (TclHasSockets(interp) != TCL_OK) {
	return NULL;
    }
	
    /*
     * Create a new client socket and wrap it in a channel.
     */








|







1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
                                         * asynchronous connect. Otherwise
                                         * we do a blocking connect. 
                                         * - currently ignored */
{
    TcpState *statePtr;
    char channelName[20];

    if (TclpHasSockets(interp) != TCL_OK) {
	return NULL;
    }
	
    /*
     * Create a new client socket and wrap it in a channel.
     */

1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
    Tcl_TcpAcceptProc *acceptProc,	/* Callback for accepting connections
                                         * from new clients. */
    ClientData acceptProcData)		/* Data for the callback. */
{
    TcpState *statePtr;
    char channelName[20];

    if (TclHasSockets(interp) != TCL_OK) {
	return NULL;
    }

    /*
     * Create a new client socket and wrap it in a channel.
     */








|







1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
    Tcl_TcpAcceptProc *acceptProc,	/* Callback for accepting connections
                                         * from new clients. */
    ClientData acceptProcData)		/* Data for the callback. */
{
    TcpState *statePtr;
    char channelName[20];

    if (TclpHasSockets(interp) != TCL_OK) {
	return NULL;
    }

    /*
     * Create a new client socket and wrap it in a channel.
     */

1871
1872
1873
1874
1875
1876
1877

1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
    Tcl_Event *evPtr,		/* Event to service. */
    int flags)			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    TcpState *statePtr;
    SocketEvent *eventPtr = (SocketEvent *) evPtr;
    int mask = 0;


    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Find the specified socket on the socket list.
     */

    for (statePtr = socketList; statePtr != NULL;
	    statePtr = statePtr->nextPtr) {
	if ((statePtr == eventPtr->statePtr) && 
		(statePtr->tcpStream == eventPtr->tcpStream)) {
	    break;
	}
    }








>









|







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
    Tcl_Event *evPtr,		/* Event to service. */
    int flags)			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    TcpState *statePtr;
    SocketEvent *eventPtr = (SocketEvent *) evPtr;
    int mask = 0;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Find the specified socket on the socket list.
     */

    for (statePtr = tsdPtr->socketList; statePtr != NULL;
	    statePtr = statePtr->nextPtr) {
	if ((statePtr == eventPtr->statePtr) && 
		(statePtr->tcpStream == eventPtr->tcpStream)) {
	    break;
	}
    }

2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
    Tcl_DString dString;
    OSErr err;
    
    if (hostnameInited) {
        return hostname;
    }
    
    if (TclHasSockets(NULL) == TCL_OK) {
	err = GetLocalAddress(&ourAddress);
	if (err == noErr) {
	    /*
	     * Search for the doman name and return it if found.  Otherwise, 
	     * just print the IP number to a string and return that.
	     */








|







2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
    Tcl_DString dString;
    OSErr err;
    
    if (hostnameInited) {
        return hostname;
    }
    
    if (TclpHasSockets(NULL) == TCL_OK) {
	err = GetLocalAddress(&ourAddress);
	if (err == noErr) {
	    /*
	     * Search for the doman name and return it if found.  Otherwise, 
	     * just print the IP number to a string and return that.
	     */

2262
2263
2264
2265
2266
2267
2268

2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
 */

static pascal void
CleanUpExitProc()
{
    TCPiopb exitPB;
    TcpState *statePtr;


    while (socketList != NULL) {
	statePtr = socketList;
	socketList = statePtr->nextPtr;

	/*
	 * Close and Release the connection.
	 */

	exitPB.ioCRefNum = driverRefNum;
	exitPB.csCode = TCPClose;







>

|
|
|







2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
 */

static pascal void
CleanUpExitProc()
{
    TCPiopb exitPB;
    TcpState *statePtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    while (tsdPtr->socketList != NULL) {
	statePtr = tsdPtr->socketList;
	tsdPtr->socketList = statePtr->nextPtr;

	/*
	 * Close and Release the connection.
	 */

	exitPB.ioCRefNum = driverRefNum;
	exitPB.csCode = TCPClose;
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
    ip_addr *address)		/* Returned IP address. */
{
    OSErr err;
    int i;
    EventRecord dummy;
    DNRState dnrState;
	
    if (TclHasSockets(NULL) != TCL_OK) {
	return 0;
    }

    /*
     * Call StrToAddr to get the ip number for the passed in domain
     * name.  The call is async, so we must wait for a callback to 
     * tell us when to continue.







|







2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
    ip_addr *address)		/* Returned IP address. */
{
    OSErr err;
    int i;
    EventRecord dummy;
    DNRState dnrState;
	
    if (TclpHasSockets(NULL) != TCL_OK) {
	return 0;
    }

    /*
     * Call StrToAddr to get the ip number for the passed in domain
     * name.  The call is async, so we must wait for a callback to 
     * tell us when to continue.
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
 *	Maps from a string, which could be a service name, to a port.
 *	Used by socket creation code to get port numbers and resolve
 *	registered service names to port numbers.
 *
 * Results:
 *	A standard Tcl result.  On success, the port number is
 *	returned in portPtr. On failure, an error message is left in
 *	interp->result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */








|







2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
 *	Maps from a string, which could be a service name, to a port.
 *	Used by socket creation code to get port numbers and resolve
 *	registered service names to port numbers.
 *
 * Results:
 *	A standard Tcl result.  On success, the port number is
 *	returned in portPtr. On failure, an error message is left in
 *	the interp's result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

2600
2601
2602
2603
2604
2605
2606

2607
2608
2609
2610
2611
2612
2613
2614
2615
 *----------------------------------------------------------------------
 */

static void
ClearZombieSockets()
{
    TcpState *statePtr;


    for (statePtr = socketList; statePtr != NULL;
	    statePtr = statePtr->nextPtr) {
	if (statePtr->flags & TCP_RELEASE) {
	    SocketFreeProc(statePtr);
	    return;
	}
    }
}







>

|







2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
 *----------------------------------------------------------------------
 */

static void
ClearZombieSockets()
{
    TcpState *statePtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    for (statePtr = tsdPtr->socketList; statePtr != NULL;
	    statePtr = statePtr->nextPtr) {
	if (statePtr->flags & TCP_RELEASE) {
	    SocketFreeProc(statePtr);
	    return;
	}
    }
}

Added mac/tclMacTclCode.r.









































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/* 
 * tclMacTclCode.r --
 *
 *	This file creates resources from the Tcl code that is
 *	usually stored in the TCL_LiBRARY
 *
 * 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.
 *
 * SCCS: @(#) tclMacTclCode.r 1.1 98/01/21 22:22:38
 */

#include <Types.r>
#include <SysTypes.r>

#define TCL_LIBRARY_RESOURCES 2000

/* 
 * The mechanisim below loads Tcl source into the resource fork of the
 * application.  The example below creates a TEXT resource named
 * "Init" from the file "init.tcl".  This allows applications to use
 * Tcl to define the behavior of the application without having to
 * require some predetermined file structure - all needed Tcl "files"
 * are located within the application.  To source a file for the
 * resource fork the source command has been modified to support
 * sourcing from resources.  In the below case "source -rsrc {Init}"
 * will load the TEXT resource named "Init".
 */

read 'TEXT' (TCL_LIBRARY_RESOURCES, "Init", purgeable) "::library:init.tcl";
read 'TEXT' (TCL_LIBRARY_RESOURCES + 1, "Auto", purgeable) "::library:auto.tcl";
read 'TEXT' (TCL_LIBRARY_RESOURCES + 2, "Package", purgeable,preload) "::library:package.tcl";
read 'TEXT' (TCL_LIBRARY_RESOURCES + 3, "History", purgeable) "::library:history.tcl";
read 'TEXT' (TCL_LIBRARY_RESOURCES + 4, "Word", purgeable,preload) "::library:word.tcl";

Changes to mac/tclMacTest.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclMacTest.c --
 *
 *	Contains commands for platform specific tests for
 *	the Macintosh platform.
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacTest.c 1.9 97/09/09 16:36:37
 */

#define TCL_TEST

#include "tclInt.h"
#include "tclMacInt.h"
#include "tclMacPort.h"











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclMacTest.c --
 *
 *	Contains commands for platform specific tests for
 *	the Macintosh platform.
 *
 * Copyright (c) 1996 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: tclMacTest.c,v 1.1.2.2 1998/11/11 04:08:27 stanton Exp $
 */

#define TCL_TEST

#include "tclInt.h"
#include "tclMacInt.h"
#include "tclMacPort.h"
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
    if (rsrcID < 0) {
	rsrcID = UniqueID('TEXT');
    }
    
    strcpy((char *) resourceName, rsrcName);
    c2pstr((char *) resourceName);
    
    dataHandle = NewHandle(strlen(data) + 1);
    HLock(dataHandle);
    strcpy(*dataHandle, data);
    HUnlock(dataHandle);
    
    /*
     * Add the resource to the file and close it.
     */
    AddResource(dataHandle, 'TEXT', rsrcID, resourceName);
    
    UpdateResFile(fileRef);
    if (protectIt) {







|



|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
    if (rsrcID < 0) {
	rsrcID = UniqueID('TEXT');
    }
    
    strcpy((char *) resourceName, rsrcName);
    c2pstr((char *) resourceName);
    
    dataHandle = NewHandle(strlen(data));
    HLock(dataHandle);
    strcpy(*dataHandle, data);
    HUnlock(dataHandle);
     
    /*
     * Add the resource to the file and close it.
     */
    AddResource(dataHandle, 'TEXT', rsrcID, resourceName);
    
    UpdateResFile(fileRef);
    if (protectIt) {

Added mac/tclMacThrd.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
/* 
 * tclMacThrd.c --
 *
 *	This file implements the Mac-specific thread support.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-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.
 *
 * SCCS:  @(#) tclMacThrd.c 1.2 98/02/23 16:48:07
 */

#include "tclInt.h"
#include "tclPort.h"
#include "tclMacInt.h"
#include <Threads.h>
#include <Gestalt.h>

#define TCL_MAC_THRD_DEFAULT_STACK (256*1024)


typedef struct TclMacThrdData {
    ThreadID threadID;
    VOID *data;
    struct TclMacThrdData *next;
} TclMacThrdData;

/*
 * This is an array of the Thread Data Keys.  It is a process-wide table.
 * Its size is originally set to 32, but it can grow if needed.
 */
 
static TclMacThrdData **tclMacDataKeyArray;
#define TCL_MAC_INITIAL_KEYSIZE 32

/*
 * These two bits of data store the current maximum number of keys
 * and the keyCounter (which is the number of occupied slots in the
 * KeyData array.
 * 
 */
 
static int maxNumKeys = 0;
static int keyCounter = 0;

/*
 * Prototypes for functions used only in this file
 */
 
TclMacThrdData *GetThreadDataStruct(Tcl_ThreadDataKey keyVal);
TclMacThrdData *RemoveThreadDataStruct(Tcl_ThreadDataKey keyVal);

/*
 *----------------------------------------------------------------------
 *
 * TclMacHaveThreads --
 *
 *	Do we have the Thread Manager?
 *
 * Results:
 *	1 if the ThreadManager is present, 0 otherwise.
 *
 * Side effects:
 *	If this is the first time this is called, the return is cached.
 *
 *----------------------------------------------------------------------
 */

int
TclMacHaveThreads(void)
{
    static initialized = false;
    static int tclMacHaveThreads = false;
    long response = 0;
    OSErr err = noErr;
    
    if (!initialized) {
	err = Gestalt(gestaltThreadMgrAttr, &response);
	if (err == noErr) {
	    tclMacHaveThreads = response | (1 << gestaltThreadMgrPresent);
	}
    }

    return tclMacHaveThreads;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpThreadCreate --
 *
 *	This procedure creates a new thread.
 *
 * Results:
 *	TCL_OK if the thread could be created.  The thread ID is
 *	returned in a parameter.
 *
 * Side effects:
 *	A new thread is created.
 *
 *----------------------------------------------------------------------
 */

int
TclpThreadCreate(idPtr, proc, clientData)
    Tcl_ThreadId *idPtr;		/* Return, the ID of the thread */
    Tcl_ThreadCreateProc proc;		/* Main() function of the thread */
    ClientData clientData;		/* The one argument to Main() */
{

    if (!TclMacHaveThreads()) {
        return TCL_ERROR;
    }
    
#if TARGET_CPU_68K && TARGET_RT_MAC_CFM
    {
        ThreadEntryProcPtr entryProc;
        entryProc = NewThreadEntryProc(proc);
        
        NewThread(kCooperativeThread, entryProc, (void *) clientData, 
            TCL_MAC_THRD_DEFAULT_STACK, kCreateIfNeeded, NULL, (ThreadID *) idPtr);
    }
#else
    NewThread(kCooperativeThread, proc, (void *) clientData, 
        TCL_MAC_THRD_DEFAULT_STACK, kCreateIfNeeded, NULL, (ThreadID *) idPtr);
#endif        
    if ((ThreadID) *idPtr == kNoThreadID) {
        return TCL_ERROR;
    } else {
        return TCL_OK;
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TclpThreadExit --
 *
 *	This procedure terminates the current thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	This procedure terminates the current thread.
 *
 *----------------------------------------------------------------------
 */

void
TclpThreadExit(status)
    int status;
{
    ThreadID curThread;
    
    if (!TclMacHaveThreads()) {
        return;
    }
    
    GetCurrentThread(&curThread);
    DisposeThread(curThread, NULL, false);
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetCurrentThread --
 *
 *	This procedure returns the ID of the currently running thread.
 *
 * Results:
 *	A thread ID.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_ThreadId
Tcl_GetCurrentThread()
{
#ifdef TCL_THREADS
    ThreadID curThread;

    if (!TclMacHaveThreads()) {
        return (Tcl_ThreadId) 0;
    } else {
        GetCurrentThread(&curThread);
        return (Tcl_ThreadId) curThread;
    }
#else
    return (Tcl_ThreadId) 0;
#endif
}


/*
 *----------------------------------------------------------------------
 *
 * TclpInitLock
 *
 *	This procedure is used to grab a lock that serializes initialization
 *	and finalization of Tcl.  On some platforms this may also initialize
 *	the mutex used to serialize creation of more mutexes and thread
 *	local storage keys.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Acquire the initialization mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpInitLock()
{
#ifdef TCL_THREADS
    /* There is nothing to do on the Mac. */;
#endif
}


/*
 *----------------------------------------------------------------------
 *
 * TclpInitUnlock
 *
 *	This procedure is used to release a lock that serializes initialization
 *	and finalization of Tcl.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Release the initialization mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpInitUnlock()
{
#ifdef TCL_THREADS
    /* There is nothing to do on the Mac */;
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * TclpMasterLock
 *
 *	This procedure is used to grab a lock that serializes creation
 *	and finalization of serialization objects.  This interface is
 *	only needed in finalization; it is hidden during
 *	creation of the objects.
 *
 *	This lock must be different than the initLock because the
 *	initLock is held during creation of syncronization objects.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Acquire the master mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpMasterLock()
{
#ifdef TCL_THREADS
    /* There is nothing to do on the Mac */;
#endif
}


/*
 *----------------------------------------------------------------------
 *
 * TclpMasterUnlock
 *
 *	This procedure is used to release a lock that serializes creation
 *	and finalization of synchronization objects.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Release the master mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpMasterUnlock()
{
#ifdef TCL_THREADS
    /* There is nothing to do on the Mac */
#endif
}

#ifdef TCL_THREADS

/*
 *----------------------------------------------------------------------
 *
 * Tcl_MutexLock --
 *
 *	This procedure is invoked to lock a mutex.  This procedure
 *	handles initializing the mutex, if necessary.  The caller
 *	can rely on the fact that Tcl_Mutex is an opaque pointer.
 *	This routine will change that pointer from NULL after first use.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May block the current thread.  The mutex is aquired when
 *	this returns.  Will allocate memory for a pthread_mutex_t
 *	and initialize this the first time this Tcl_Mutex is used.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_MutexLock(mutexPtr)
    Tcl_Mutex *mutexPtr;	/* Really (pthread_mutex_t **) */
{
/* There is nothing to do on the Mac */
}


/*
 *----------------------------------------------------------------------
 *
 * TclpMutexUnlock --
 *
 *	This procedure is invoked to unlock a mutex.  The mutex must
 *	have been locked by Tcl_MutexLock.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The mutex is released when this returns.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_MutexUnlock(mutexPtr)
    Tcl_Mutex *mutexPtr;	/* Really (pthread_mutex_t **) */
{
/* There is nothing to do on the Mac */
}


/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeMutex --
 *
 *	This procedure is invoked to clean up one mutex.  This is only
 *	safe to call at the end of time.
 *
 *	This assumes the Master Lock is held.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The mutex list is deallocated.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeMutex(mutexPtr)
    Tcl_Mutex *mutexPtr;
{
/* There is nothing to do on the Mac */
}


/*
 *----------------------------------------------------------------------
 *
 * TclpThreadDataKeyInit --
 *
 *	This procedure initializes a thread specific data block key.
 *	Each thread has table of pointers to thread specific data.
 *	all threads agree on which table entry is used by each module.
 *	this is remembered in a "data key", that is just an index into
 *	this table.  To allow self initialization, the interface
 *	passes a pointer to this key and the first thread to use
 *	the key fills in the pointer to the key.  The key should be
 *	a process-wide static.
 *
 *      There is no system-wide support for thread specific data on the 
 *	Mac.  So we implement this as an array of pointers.  The keys are
 *	allocated sequentially, and each key maps to a slot in the table.
 *      The table element points to a linked list of the instances of
 *	the data for each thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Will bump the key counter if this is the first time this key
 *      has been initialized.  May grow the DataKeyArray if that is
 *	necessary.
 *
 *----------------------------------------------------------------------
 */

void
TclpThreadDataKeyInit(keyPtr)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (pthread_key_t **) */
{
            
    if (*keyPtr == NULL) {
        keyCounter += 1;
	*keyPtr = (Tcl_ThreadDataKey) keyCounter;
	if (keyCounter > maxNumKeys) {
	    TclMacThrdData **newArray;
	    int i, oldMax = maxNumKeys;
	     
	    maxNumKeys = maxNumKeys + TCL_MAC_INITIAL_KEYSIZE;
	     
	    newArray = (TclMacThrdData **) 
	            ckalloc(maxNumKeys * sizeof(TclMacThrdData *));
	     
	    for (i = 0; i < oldMax; i++) {
	        newArray[i] = tclMacDataKeyArray[i];
	    }
	    for (i = oldMax; i < maxNumKeys; i++) {
	        newArray[i] = NULL;
	    }
	     
	    if (tclMacDataKeyArray != NULL) {
		ckfree((char *) tclMacDataKeyArray);
	    }
	    tclMacDataKeyArray = newArray;
	     
	}             
	/* TclRememberDataKey(keyPtr); */
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpThreadDataKeyGet --
 *
 *	This procedure returns a pointer to a block of thread local storage.
 *
 * Results:
 *	A thread-specific pointer to the data structure, or NULL
 *	if the memory has not been assigned to this key for this thread.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

VOID *
TclpThreadDataKeyGet(keyPtr)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (pthread_key_t **) */
{
    TclMacThrdData *dataPtr;
    
    dataPtr = GetThreadDataStruct(*keyPtr);
    
    if (dataPtr == NULL) {
        return NULL;
    } else {
        return dataPtr->data;
    }
}


/*
 *----------------------------------------------------------------------
 *
 * TclpThreadDataKeySet --
 *
 *	This procedure sets the pointer to a block of thread local storage.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets up the thread so future calls to TclpThreadDataKeyGet with
 *	this key will return the data pointer.
 *
 *----------------------------------------------------------------------
 */

void
TclpThreadDataKeySet(keyPtr, data)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (pthread_key_t **) */
    VOID *data;			/* Thread local storage */
{
    TclMacThrdData *dataPtr;
    ThreadID curThread;
    
    dataPtr = GetThreadDataStruct(*keyPtr);
    
    /* 
     * Is it legal to reset the thread data like this?
     * And if so, who owns the memory?
     */
     
    if (dataPtr != NULL) {
        dataPtr->data = data;
    } else {
        dataPtr = (TclMacThrdData *) ckalloc(sizeof(TclMacThrdData));
        GetCurrentThread(&curThread);
        dataPtr->threadID = curThread;
        dataPtr->data = data;
        dataPtr->next = tclMacDataKeyArray[(int) *keyPtr - 1];
        tclMacDataKeyArray[(int) *keyPtr - 1] = dataPtr;
   }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeThreadData --
 *
 *	This procedure cleans up the thread-local storage.  This is
 *	called once for each thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees up all thread local storage.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeThreadData(keyPtr)
    Tcl_ThreadDataKey *keyPtr;
{
    TclMacThrdData *dataPtr;
    
    if (*keyPtr != NULL) {
        dataPtr = RemoveThreadDataStruct(*keyPtr);
        
	if ((dataPtr != NULL) && (dataPtr->data != NULL)) {
	    ckfree((char *) dataPtr->data);
	    ckfree((char *) dataPtr);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeThreadDataKey --
 *
 *	This procedure is invoked to clean up one key.  This is a
 *	process-wide storage identifier.  The thread finalization code
 *	cleans up the thread local storage itself.
 *
 *      On the Mac, there is really nothing to do here, since the key
 *      is just an array index.  But we set the key to 0 just in case
 *	someone else is relying on that.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The keyPtr value is set to 0.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeThreadDataKey(keyPtr)
    Tcl_ThreadDataKey *keyPtr;
{
    ckfree((char *) tclMacDataKeyArray[(int) *keyPtr - 1]);
    tclMacDataKeyArray[(int) *keyPtr - 1] = NULL;
    *keyPtr = NULL;
}


/*
 *----------------------------------------------------------------------
 *
 * GetThreadDataStruct --
 *
 *	This procedure gets the data structure corresponding to
 *      keyVal for the current process.
 *
 * Results:
 *	The requested key data.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TclMacThrdData *
GetThreadDataStruct(keyVal)
    Tcl_ThreadDataKey keyVal;
{
    ThreadID curThread;
    TclMacThrdData *dataPtr;
    
    /*
     * The keyPtr will only be greater than keyCounter is someone
     * has passed us a key without getting the value from 
     * TclpInitDataKey.
     */
     
    if ((int) keyVal <= 0)  {
        return NULL;
    } else if ((int) keyVal > keyCounter) {
        panic("illegal data key value");
    }
    
    GetCurrentThread(&curThread);
    
    for (dataPtr = tclMacDataKeyArray[(int) keyVal - 1]; dataPtr != NULL;
            dataPtr = dataPtr->next) {
        if (dataPtr->threadID ==  curThread) {
            break;
        }
    }
    
    return dataPtr;
}


/*
 *----------------------------------------------------------------------
 *
 * RemoveThreadDataStruct --
 *
 *	This procedure removes the data structure corresponding to
 *      keyVal for the current process from the list kept for keyVal.
 *
 * Results:
 *	The requested key data is removed from the list, and a pointer 
 *      to it is returned.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TclMacThrdData *
RemoveThreadDataStruct(keyVal)
    Tcl_ThreadDataKey keyVal;
{
    ThreadID curThread;
    TclMacThrdData *dataPtr, *prevPtr;
    
     
    if ((int) keyVal <= 0)  {
        return NULL;
    } else if ((int) keyVal > keyCounter) {
        panic("illegal data key value");
    }
    
    GetCurrentThread(&curThread);
    
    for (dataPtr = tclMacDataKeyArray[(int) keyVal - 1], prevPtr = NULL; 
            dataPtr != NULL;
            prevPtr = dataPtr, dataPtr = dataPtr->next) {
        if (dataPtr->threadID == curThread) {
            break;
        }
    }
    
    if (dataPtr == NULL) {
        /* No body */
    } else if ( prevPtr == NULL) {
        tclMacDataKeyArray[(int) keyVal - 1] = dataPtr->next;
    } else {
        prevPtr->next = dataPtr->next;
    }
    
    return dataPtr; 
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConditionWait --
 *
 *	This procedure is invoked to wait on a condition variable.
 *	On the Mac, mutexes are no-ops, and we just yield.  After
 *	all, it is the application's job to loop till the condition 
 *	variable is changed...
 *
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Will block the current thread till someone else yields.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
    Tcl_Condition *condPtr;	/* Really (pthread_cond_t **) */
    Tcl_Mutex *mutexPtr;	/* Really (pthread_mutex_t **) */
    Tcl_Time *timePtr;		/* Timeout on waiting period */
{
    if (TclMacHaveThreads()) {
        YieldToAnyThread();
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConditionNotify --
 *
 *	This procedure is invoked to signal a condition variable.
 *
 *	The mutex must be held during this call to avoid races,
 *	but this interface does not enforce that.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May unblock another thread.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ConditionNotify(condPtr)
    Tcl_Condition *condPtr;
{
    if (TclMacHaveThreads()) {
         YieldToAnyThread();
    }
}


/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeCondition --
 *
 *	This procedure is invoked to clean up a condition variable.
 *	This is only safe to call at the end of time.
 *
 *	This assumes the Master Lock is held.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The condition variable is deallocated.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeCondition(condPtr)
    Tcl_Condition *condPtr;
{
    /* Nothing to do on the Mac */
}



#endif /* TCL_THREADS */

Added mac/tclMacThrd.h.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tclUnixThrd.h --
 *
 *      This header file defines things for thread support.
 *
 * 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.
 *
 * SCCS: @(#)
 */
 
#ifndef _TCLMACTHRD
#define _TCLMACTHRD

#ifdef TCL_THREADS

#endif /* TCL_THREADS */
#endif /* _TCLMACTHRD */

Changes to mac/tclMacTime.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclMacTime.c --
 *
 *	Contains Macintosh specific versions of Tcl functions that
 *	obtain time values from the operating system.
 *
 * 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.
 *
 * SCCS: @(#) tclMacTime.c 1.19 97/06/27 13:07:10
 */

#include "tclInt.h"
#include "tclPort.h"
#include <OSUtils.h>
#include <Timer.h>
#include <time.h>











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclMacTime.c --
 *
 *	Contains Macintosh specific versions of Tcl functions that
 *	obtain time values from the operating system.
 *
 * 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: tclMacTime.c,v 1.1.2.2 1999/03/10 06:49:25 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"
#include <OSUtils.h>
#include <Timer.h>
#include <time.h>
237
238
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
 *  	The passed in struct tm data structure is modified.
 *
 *----------------------------------------------------------------------
 */

struct tm *
TclpGetDate(
    const time_t *tp,	/* Time struct to fill. */
    int useGMT)		/* True if date should reflect GNT time. */
{

    DateTimeRec dtr;
    MachineLocation loc;
    long int offset;
    static struct tm statictime;
    static const short monthday[12] =
        {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};








|


>







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
 *  	The passed in struct tm data structure is modified.
 *
 *----------------------------------------------------------------------
 */

struct tm *
TclpGetDate(
    TclpTime_t time,	/* Time struct to fill. */
    int useGMT)		/* True if date should reflect GNT time. */
{
    const time_t *tp = (const time_t *)time;
    DateTimeRec dtr;
    MachineLocation loc;
    long int offset;
    static struct tm statictime;
    static const short monthday[12] =
        {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};

Changes to mac/tclMacUnix.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 
 * tclMacUnix.c --
 *
 *	This file contains routines to implement several features
 *	available to the Unix implementation, but that require
 *      extra work to do on a Macintosh.  These include routines
 *      Unix Tcl normally hands off to the Unix OS.
 *
 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMacUnix.c 1.56 96/12/12 19:38:08
 */

#include <Files.h>
#include <Strings.h>
#include <TextUtils.h>
#include <Finder.h>
#include <FSpCompat.h>









|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 
 * tclMacUnix.c --
 *
 *	This file contains routines to implement several features
 *	available to the Unix implementation, but that require
 *      extra work to do on a Macintosh.  These include routines
 *      Unix Tcl normally hands off to the Unix OS.
 *
 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
 * 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: tclMacUnix.c,v 1.1.2.2 1998/09/24 23:59:18 stanton Exp $
 */

#include <Files.h>
#include <Strings.h>
#include <TextUtils.h>
#include <Finder.h>
#include <FSpCompat.h>
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
/*
 * Missing error codes
 */
#define usageErr		500
#define noSourceErr		501
#define isDirErr		502

/*
 * Static functions in this file.
 */

static int	GlobArgs _ANSI_ARGS_((Tcl_Interp *interp,
		    int *argc, char ***argv));

/*
 *----------------------------------------------------------------------
 *
 * GlobArgs --
 *
 *	The following function was taken from Peter Keleher's Alpha
 *	Editor.  *argc should only count the end arguments that should
 *	be globed.  argv should be incremented to point to the first
 *	arg to be globed.
 *
 * Results:
 *	Returns 'true' if it worked & memory was allocated, else 'false'.
 *
 * Side effects:
 *	argv will be alloced, the call will need to release the memory
 *
 *----------------------------------------------------------------------
 */
 
static int
GlobArgs(
    Tcl_Interp *interp,		/* Tcl interpreter. */
    int *argc,			/* Number of arguments. */
    char ***argv)		/* Argument strings. */
{
    int res, len;
    char *list;
	
    /*
     * Places the globbed args all into 'interp->result' as a list.
     */
    res = Tcl_GlobCmd(NULL, interp, *argc + 1, *argv - 1);
    if (res != TCL_OK) {
	return false;
    }
    len = strlen(interp->result);
    list = (char *) ckalloc(len + 1);
    strcpy(list, interp->result);
    Tcl_ResetResult(interp);
	
    res = Tcl_SplitList(interp, list, argc, argv);
    ckfree((char *) list);
    if (res != TCL_OK) {
	return false;
    }
    return true;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_EchoCmd --
 *
 *    Implements the TCL echo command:







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







47
48
49
50
51
52
53






















































54
55
56
57
58
59
60
/*
 * Missing error codes
 */
#define usageErr		500
#define noSourceErr		501
#define isDirErr		502
























































/*
 *----------------------------------------------------------------------
 *
 * Tcl_EchoCmd --
 *
 *    Implements the TCL echo command:
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
    int mode, result, i;

    chan = Tcl_GetChannel(interp, "stdout", &mode);
    if (chan == (Tcl_Channel) NULL) {
        return TCL_ERROR;
    }
    for (i = 1; i < argc; i++) {
	result = Tcl_Write(chan, argv[i], -1);
	if (result < 0) {
	    Tcl_AppendResult(interp, "echo: ", Tcl_GetChannelName(chan),
		    ": ", Tcl_PosixError(interp), (char *) NULL);
	    return TCL_ERROR;
	}
        if (i < (argc - 1)) {
	    Tcl_Write(chan, " ", -1);
	}
    }
    Tcl_Write(chan, "\n", -1);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_LsCmd --
 *
 *	This procedure is invoked to process the "ls" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */
int
Tcl_LsCmd(
    ClientData dummy,			/* Not used. */
    Tcl_Interp *interp,			/* Current interpreter. */
    int argc,				/* Number of arguments. */
    char **argv)			/* Argument strings. */
{
#define STRING_LENGTH 80
#define CR '\n'
    int i, j;
    int fieldLength, len = 0, maxLen = 0, perLine;
    char **origArgv = argv;
    OSErr err;
    CInfoPBRec paramBlock;
    HFileInfo *hpb = (HFileInfo *)&paramBlock;
    DirInfo *dpb = (DirInfo *)&paramBlock;
    char theFile[256];
    char theLine[STRING_LENGTH + 2];
    int fFlag = false, pFlag = false, aFlag = false, lFlag = false,
	cFlag = false, hFlag = false;



    /*
     * Process command flags.  End if argument doesn't start
     * with a dash or is a dash by itself.  The remaining arguments
     * should be files.
     */
    for (i = 1; i < argc; i++) {

	if (argv[i][0] != '-') {
	    break;
	}
		
	if (!strcmp(argv[i], "-")) {
	    i++;
	    break;
	}
		
	for (j = 1 ; argv[i][j] ; ++j) {
	    switch(argv[i][j]) {
	    case 'a':
	    case 'A':
		aFlag = true;
		break;
	    case '1':
		cFlag = false;
		break;







|






|


|






|













|


|
|





<








>
>






|
>
|



|




|
|







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
    int mode, result, i;

    chan = Tcl_GetChannel(interp, "stdout", &mode);
    if (chan == (Tcl_Channel) NULL) {
        return TCL_ERROR;
    }
    for (i = 1; i < argc; i++) {
	result = Tcl_WriteChars(chan, argv[i], -1);
	if (result < 0) {
	    Tcl_AppendResult(interp, "echo: ", Tcl_GetChannelName(chan),
		    ": ", Tcl_PosixError(interp), (char *) NULL);
	    return TCL_ERROR;
	}
        if (i < (argc - 1)) {
	    Tcl_WriteChars(chan, " ", -1);
	}
    }
    Tcl_WriteChars(chan, "\n", -1);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_LsObjCmd --
 *
 *	This procedure is invoked to process the "ls" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */
int
Tcl_LsObjCmd(
    ClientData dummy,			/* Not used. */
    Tcl_Interp *interp,			/* Current interpreter. */
    int objc,				/* Number of arguments. */
    Tcl_Obj *CONST objv[])		/* Argument strings. */
{
#define STRING_LENGTH 80
#define CR '\n'
    int i, j;
    int fieldLength, len = 0, maxLen = 0, perLine;

    OSErr err;
    CInfoPBRec paramBlock;
    HFileInfo *hpb = (HFileInfo *)&paramBlock;
    DirInfo *dpb = (DirInfo *)&paramBlock;
    char theFile[256];
    char theLine[STRING_LENGTH + 2];
    int fFlag = false, pFlag = false, aFlag = false, lFlag = false,
	cFlag = false, hFlag = false;
    char *argv;
    Tcl_Obj *newObjv[2], *resultObjPtr;

    /*
     * Process command flags.  End if argument doesn't start
     * with a dash or is a dash by itself.  The remaining arguments
     * should be files.
     */
    for (i = 1; i < objc; i++) {
    	argv = Tcl_GetString(objv[i]);
	if (argv[0] != '-') {
	    break;
	}
		
	if (!strcmp(argv, "-")) {
	    i++;
	    break;
	}
		
	for (j = 1 ; argv[j] ; ++j) {
	    switch(argv[j]) {
	    case 'a':
	    case 'A':
		aFlag = true;
		break;
	    case '1':
		cFlag = false;
		break;
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
		Tcl_AppendResult(interp, "error - unknown flag ",
			"usage: ls -apCFHl1 ?files? ", NULL);
		return TCL_ERROR;
	    }
	}
    }

    argv += i;
    argc -= i;

    /*
     * No file specifications means we search for all files.
     * Glob will be doing most of the work.
     */
     if (!argc) {
	argc = 1;


	argv = origArgv;
	strcpy(argv[0], "*");
    }

    if (!GlobArgs(interp, &argc, &argv)) {
	Tcl_ResetResult(interp);
	return TCL_ERROR;
    }










    /*
     * There are two major methods for listing files: the long
     * method and the normal method.
     */
    if (lFlag) {
	char	creator[5], type[5], time[16], date[16];
	char	lineTag;
	long	size;
	unsigned short flags;




	/*
	 * Print the header for long listing.
	 */
	if (hFlag) {
	    sprintf(theLine, "T %7s %8s %8s %4s %4s %6s %s",
		    "Size", "ModTime", "ModDate",
		    "CRTR", "TYPE", "Flags", "Name");
	    Tcl_AppendResult(interp, theLine, "\n", NULL);
	    Tcl_AppendResult(interp,
		    "-------------------------------------------------------------\n",
		    NULL);
	}
		
	for (i = 0; i < argc; i++) {
	    strcpy(theFile, argv[i]);
			
	    c2pstr(theFile);
	    hpb->ioCompletion = NULL;
	    hpb->ioVRefNum = 0;
	    hpb->ioFDirIndex = 0;
	    hpb->ioNamePtr = (StringPtr) theFile;
	    hpb->ioDirID = 0L;







|
|





|
|
>
>
|
<


|
|
|

>
>
>
>
>
>
>
>
>










>
>
>














|
|







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
		Tcl_AppendResult(interp, "error - unknown flag ",
			"usage: ls -apCFHl1 ?files? ", NULL);
		return TCL_ERROR;
	    }
	}
    }

    objv += i;
    objc -= i;

    /*
     * No file specifications means we search for all files.
     * Glob will be doing most of the work.
     */
     if (!objc) {
	objc = 1;
	newObjv[0] = Tcl_NewStringObj("*", -1);
	newObjv[1] = NULL;
	objv = newObjv;

    }

    if (Tcl_GlobObjCmd(NULL, interp, objc + 1, objv - 1) != TCL_OK) {
    	Tcl_ResetResult(interp);
    	return TCL_ERROR;
    }

    resultObjPtr = Tcl_GetObjResult(interp);
    Tcl_IncrRefCount(resultObjPtr);
    if (Tcl_ListObjGetElements(interp, resultObjPtr, &objc, &objv) != TCL_OK) {
    	Tcl_DecrRefCount(resultObjPtr);
    	return TCL_ERROR;
    }

    Tcl_ResetResult(interp);

    /*
     * There are two major methods for listing files: the long
     * method and the normal method.
     */
    if (lFlag) {
	char	creator[5], type[5], time[16], date[16];
	char	lineTag;
	long	size;
	unsigned short flags;
	Tcl_Obj *objPtr;
	char *string;
	int length;

	/*
	 * Print the header for long listing.
	 */
	if (hFlag) {
	    sprintf(theLine, "T %7s %8s %8s %4s %4s %6s %s",
		    "Size", "ModTime", "ModDate",
		    "CRTR", "TYPE", "Flags", "Name");
	    Tcl_AppendResult(interp, theLine, "\n", NULL);
	    Tcl_AppendResult(interp,
		    "-------------------------------------------------------------\n",
		    NULL);
	}
		
	for (i = 0; i < objc; i++) {
	    strcpy(theFile, Tcl_GetString(objv[i]));
			
	    c2pstr(theFile);
	    hpb->ioCompletion = NULL;
	    hpb->ioVRefNum = 0;
	    hpb->ioFDirIndex = 0;
	    hpb->ioNamePtr = (StringPtr) theFile;
	    hpb->ioDirID = 0L;
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
	    sprintf(theLine, "%c %7ld %8s %8s %-4.4s %-4.4s 0x%4.4X %s",
		    lineTag, size, time, date, creator, type, flags, theFile);
						 
	    Tcl_AppendResult(interp, theLine, "\n", NULL);
	    
	}
		
	if ((interp->result != NULL) && (*(interp->result) != '\0')) {
	    int slen = strlen(interp->result);
	    if (interp->result[slen - 1] == '\n') {
		interp->result[slen - 1] = '\0';
	    }
	}
    } else {
	/*
	 * Not in long format. We only print files names.  If the
	 * -C flag is set we need to print in multiple coloumns.
	 */
	int argCount, linePos;
	Boolean needNewLine = false;

	/*
	 * Fiend the field length: the length each string printed
	 * to the terminal will be.
	 */
	if (!cFlag) {
	    perLine = 1;
	    fieldLength = STRING_LENGTH;
	} else {
	    for (i = 0; i < argc; i++) {

		len = strlen(argv[i]);
		if (len > maxLen) {
		    maxLen = len;
		}
	    }
	    fieldLength = maxLen + 3;
	    perLine = STRING_LENGTH / fieldLength;
	}

	argCount = 0;
	linePos = 0;
	memset(theLine, ' ', STRING_LENGTH);
	while (argCount < argc) {
	    strcpy(theFile, argv[argCount]);
			
	    c2pstr(theFile);
	    hpb->ioCompletion = NULL;
	    hpb->ioVRefNum = 0;
	    hpb->ioFDirIndex = 0;
	    hpb->ioNamePtr = (StringPtr) theFile;
	    hpb->ioDirID = 0L;







|
|
|
|
<

















|
>
|











|
|







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
	    sprintf(theLine, "%c %7ld %8s %8s %-4.4s %-4.4s 0x%4.4X %s",
		    lineTag, size, time, date, creator, type, flags, theFile);
						 
	    Tcl_AppendResult(interp, theLine, "\n", NULL);
	    
	}
		
	objPtr = Tcl_GetObjResult(interp);
	string = Tcl_GetStringFromObj(objPtr, &length);
	if ((length > 0) && (string[length - 1] == '\n')) {
	    Tcl_SetObjLength(objPtr, length - 1);

	}
    } else {
	/*
	 * Not in long format. We only print files names.  If the
	 * -C flag is set we need to print in multiple coloumns.
	 */
	int argCount, linePos;
	Boolean needNewLine = false;

	/*
	 * Fiend the field length: the length each string printed
	 * to the terminal will be.
	 */
	if (!cFlag) {
	    perLine = 1;
	    fieldLength = STRING_LENGTH;
	} else {
	    for (i = 0; i < objc; i++) {
	    	argv = Tcl_GetString(objv[i]);
		len = strlen(argv);
		if (len > maxLen) {
		    maxLen = len;
		}
	    }
	    fieldLength = maxLen + 3;
	    perLine = STRING_LENGTH / fieldLength;
	}

	argCount = 0;
	linePos = 0;
	memset(theLine, ' ', STRING_LENGTH);
	while (argCount < objc) {
	    strcpy(theFile, Tcl_GetString(objv[argCount]));
			
	    c2pstr(theFile);
	    hpb->ioCompletion = NULL;
	    hpb->ioVRefNum = 0;
	    hpb->ioFDirIndex = 0;
	    hpb->ioNamePtr = (StringPtr) theFile;
	    hpb->ioDirID = 0L;
453
454
455
456
457
458
459
460
461
462
463
464
	    if (needNewLine) {
		Tcl_AppendResult(interp, "\n", theLine, NULL);
	    } else {
		Tcl_AppendResult(interp, theLine, NULL);
	    }
	}
    }
	
    ckfree((char *) argv);
	
    return TCL_OK;
}







|
|
|


414
415
416
417
418
419
420
421
422
423
424
425
	    if (needNewLine) {
		Tcl_AppendResult(interp, "\n", theLine, NULL);
	    } else {
		Tcl_AppendResult(interp, theLine, NULL);
	    }
	}
    }

    Tcl_DecrRefCount(resultObjPtr);
    	
    return TCL_OK;
}

Changes to mac/tclMacUtil.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclMacUtil.c --
 *
 *  This contains utility functions used to help with
 *  implementing Macintosh specific portions of the Tcl port.
 *
 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
 * 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.
 *
 * SCCS: @(#) tclMacUtil.c 1.53 97/07/30 16:46:16
 */

#include "tcl.h"
#include "tclInt.h"
#include "tclMacInt.h"
#include "tclMath.h"
#include "tclMacPort.h"












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclMacUtil.c --
 *
 *  This contains utility functions used to help with
 *  implementing Macintosh specific portions of the Tcl port.
 *
 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
 * 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: tclMacUtil.c,v 1.1.2.2 1998/09/24 23:59:19 stanton Exp $
 */

#include "tcl.h"
#include "tclInt.h"
#include "tclMacInt.h"
#include "tclMath.h"
#include "tclMacPort.h"
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
 *
 *----------------------------------------------------------------------
 */

int
FSpLocationFromPath(
    int length,			/* Length of path. */
    char *path,			/* The path to convert. */
    FSSpecPtr fileSpecPtr)	/* On return the spec for the path. */
{
    Str255 fileName;
    OSErr err;
    short vRefNum;
    long dirID;
    int pos, cur;







|







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
 *
 *----------------------------------------------------------------------
 */

int
FSpLocationFromPath(
    int length,			/* Length of path. */
    CONST char *path,		/* The path to convert. */
    FSSpecPtr fileSpecPtr)	/* On return the spec for the path. */
{
    Str255 fileName;
    OSErr err;
    short vRefNum;
    long dirID;
    int pos, cur;

Changes to tests/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


Tcl Test Suite



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










SCCS: @(#) README 1.6 96/04/17 10:51:11



This directory contains a set of validation tests for the Tcl
commands.  Each of the files whose name ends in ".test" is
intended to fully exercise one or a few Tcl commands.  The

commands tested by a given file are listed in the first line
of the file.

You can run the tests in two ways:

    (a) type "make test" in ../unix; this will run all of the tests.

























    (b) start up tcltest in this directory, then "source" the test
        file (for example, type "source parse.test").  To run all
	of the tests, type "source all".








In either case no output will be generated if all goes well, except
for a listing of the tests..  If there are errors then additional
messages will appear in the format described below.  Note: don't
run the tests as superuser, since this will cause several of the tests
to fail.

The rest of this file provides additional information on the
features of the testing environment.

This approach to testing was designed and initially implemented
by Mary Ann May-Pumphrey of Sun Microsystems.  Many thanks to
her for donating her work back to the public Tcl release.


Definitions file:















































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




The file "defs" defines a collection of procedures and variables

used to run the tests.  It is read in automatically by each of the





.test files if needed, but once it has been read once it will not


be read again by the .test files.  If you change defs while running






tests you'll have to "source" it by hand to load its new contents.




























































Test output:




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














Normally, output only appears when there are errors.  However, if



the variable VERBOSE is set to 1 then tests will be run in "verbose"


mode and output will be generated for each test regardless of


whether it succeeded or failed.  Test output consists of the


following information:




    - the test identifier (which can be used to locate the test code












	    in the .test file)

    - a brief description of the test

    - the contents of the test code



    - the actual results produced by the tests





    - a "PASSED" or "FAILED" message





    - the expected results (if the test failed)






































You can set VERBOSE either interactively (after the defs file has been


read in), or you can change the default value in "defs".



Selecting tests for execution:
------------------------------

Normally, all the tests in a file are run whenever the file is


"source"d.  However, you can select a specific set of tests using


the global variable TESTS.  This variable contains a pattern;  any
test whose identifier matches TESTS will be run.  For example,


the following interactive command causes all of the "for" tests in


groups 2 and 4 to be executed:





    set TESTS {for-[24]*}











TESTS defaults to *, but you can change the default in "defs" if

you wish.





Saving keystrokes:

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

A convenience procedure named "dotests" is included in file
"defs".  It takes two arguments--the name of the test file (such
as "parse.test"), and a pattern selecting the tests you want to
execute.  It sets TESTS to the second argument, calls "source" on
the file specified in the first argument, and restores TESTS to


its pre-call value at the end.






Batch vs. interactive execution:








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

The tests can be run in either batch or interactive mode.  Batch

mode refers to using I/O redirection from a UNIX shell.  For example,
the following command causes the tests in the file named "parse.test"
to be executed:








    tclTest < parse.test > parse.test.results









Users who want to execute the tests in this fashion need to first


ensure that the file "defs" has proper values for the global



variables that control the testing environment (VERBOSE and TESTS).

>
|
>
>
>
|

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

|
|
|
>
|
|

|
>

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

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

|
|
|

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

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

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

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

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

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

>
|
|


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

>
|
>
>
>

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

|
>
|

<
<
<
<
|
>
>
|
>

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

<
>
|
|
|
>
>
>
>

>
>
>
|
>
>

>
>
>
>
>
>
|
>
>
|
>
>
>
|
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69


70


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371




372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
README -- Tcl test suite design document.

RCS: @(#) $Id: README,v 1.1.2.8 1999/04/07 01:59:27 hershey Exp $

Contents:
---------

    1. Introduction
    2. Definitions file
    3. Writing a new test
    4. Constraints
    5. Adding a New Test File
    6. Test output
    7. Selecting tests for execution within a file
    8. Selecting files to be sourced by all.tcl
    9. Incompatibilities with prior Tcl versions

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

This directory contains a set of validation tests for the Tcl commands
and C Library procedures for Tcl.  Each of the files whose name ends
in ".test" is intended to fully exercise the functions in the C source
file that corresponds to the file prefix.  The C functions and/or Tcl
commands tested by a given file are listed in the first line of the
file.

You can run the tests in three ways:

    (a) type "make test" in ../unix; this will run all of the tests.

    (b) type "tcltest <testFile> ?<option> <value>?
	Command line options include:

	-verbose <level>     set the level of verbosity to a substring
			     of "bps".  See the "Test output" section
			     for an explanation of this option.

	-match <matchList>   only run tests that match one or more of
			     the glob patterns in <matchList>

	-skip <skipList>     do not run tests that match one or more
			     of the glob patterns in <skipList>

	-file <globPattern>  only source test files that match
			     <globPattern> (relative to the "tests"
			     directory).  This option only applies
			     when you run the test suite with the
			     "all.tcl" file.

	-constraints <list>  tests with any constraints in <list> will
			     not be skipped.  Not that elements of
			     <list> must exactly match the existing
			     constraints.

    (c) start up tcltest in this directory, then "source" the test
        file (for example, type "source parse.test").  To run all
	of the tests, type "source all.tcl".  To use the options in
	interactive mode, you can set their corresponding tcltest
	namespace variables after sourcing the defs.tcl file.
		  ::tcltest::match
		  ::tcltest::skip
		  ::tcltest::testConfig(nonPortable)
		  ::tcltest::testConfig(knownBug)
		  ::tcltest::testConfig(userInteractive)

In all cases, no output will be generated if all goes well, except for
a listing of the test files and a statistical summary.  If there are
errors, then additional messages will appear in the format described


below.  Note that some tests will be skipped if you run as superuser.



This approach to testing was designed and initially implemented by
Mary Ann May-Pumphrey of Sun Microsystems in the early 1990's.  Many
thanks to her for donating her work back to the public Tcl release.


2. Definitions file:
--------------------

The file "defs.tcl" defines the "tcltest" namespace which contains a
collection of procedures and variables used to run the tests.  It is
read in automatically by each of the .test files if needed, but once
it has been read once it will not be read again by the .test files.
Currently, the following procedures are exported from the "tcltest"
namespace and automatically imported:

    test	      Run a test script.

    cleanupTests      Print stats and remove files created by tests.

    dotests	      Source a test file and run tests of the
		      specified pattern.

    makeFile	      Create a file--the file will automatically
		      be removed by cleanupTests.

    removeFile	      Force a file to be removed.

    makeDirectory     Create a directory--the directory will
		      automatically be removed by cleanupTests.

    removeDirectory   Force a directory to be removed.

    viewFile	      Returns the contents of a file.

    normalizeMsg      Remove extra newlines from a string.

    bytestring	      Construct a string that consists of the
		      requested sequence of bytes, as opposed to a
		      string of properly formed UTF-8 characters.

    set_iso8859_1_locale    Set the locale to iso8859_1.

    restore_locale    Restore the locale to its original setting.

    saveState	      Save the procedure and global variable names.

    restoreState      Restore the procedure and global variable names.

Please refer to the defs.tcl file for more documentation on these
procedures.


3. Writing a new test:
----------------------

The test procedure runs a test script and prints an error message if
the script's result does not match the expected result.  The following
is the spec for the "test" command:

    test <name> <description> ?<constraint>? <script> <expectedAnswer>

The <name> argument should follow the pattern,
"<target>-<majorNum>.<minorNum>".  For white-box (regression) tests,
the target should be the name of the c function or Tcl procedure being
tested.  For black-box tests, the target should be the name of the
feature being tested.  Related tests should share a major number.

The <description> argument is a short textual description of the test,
to help humans understand what it does.

The optional <constraints> argument is list of one or more keywords,
each of which must be the name of an element in the array
"::tcltest::testConfig".  If any of these elements is false or does
not exist, the test is skipped.  Add appropriate constraints (e.g.,
unixOnly) to any tests that should not always be run.  For example, a
test that should only be run on Unix should look like the following:

    test getAttribute-1.1 {testing file permissions} {unixOnly} {
        lindex [file attributes foo.tcl] 5
    } {00644}

See the "Constraints" section for a list of built-in
constraints and information on how to add your own constraints.

The <script> argument contains the script to run to carry out the
test.  It must return a result that can be checked for correctness.
If your script requires that a file be created on the fly, please use
the ::tcltest::makeFile procedure.  If your test requires that a small
file (<50 lines) be checked in, please consider creating the file on
the fly using the ::tcltest::makeFile procedure.  Files created by the
::tcltest::makeFile procedure will automatically be removed by the
::tcltest::cleanupTests call at the end of each test file.

The <expectedAnswer> argument will be compared against the result of
evaluating the <script> argument.  If they match, the test passes,
otherwise the test fails.


4. Constraints:
---------------

Constraints are used to determine whether a test should be skipped.
Each constraint is stored as an index in the array
::tcltest::testConfig.  For example, the unixOnly constraint is
defined as the following:

    set ::tcltest::testConfig(unixOnly) \
	[expr {$tcl_platform(platform) == "unix"}]

If a test is constrained by "unixOnly", then it will only be run if
the value of ::tcltest::testConfig(unixOnly) is true.

The following is a list of constraints defined in the defs.tcl file:

unix            test can only be run on any UNIX platform
pc	        test can only be run on any Windows platform
nt	        test can only be run on any Windows NT platform
95	        test can only be run on any Windows 95 platform
mac	        test can only be run on any Mac platform
unixOrPc        test can only be run on a UNIX or PC platform
macOrPc	        test can only be run on a Mac or PC platform
macOrUnix       test can only be run on a Mac or UNIX platform
tempNotPc	test can not be run on Windows.  This flag is used
		to temporarily disable a test.
tempNotMac	test can not be run on a Mac.  This flag is used
		to temporarily disable a test.
unixCrash       test crashes if it's run on UNIX.  This flag is used
		to temporarily disable a test.
pcCrash 	test crashes if it's run on Windows.  This flag is
		used to temporarily disable a test.
macCrash 	test crashes if it's run on a Mac.  This flag is used
		to temporarily disable a test.

emptyTest	test is empty, and so not worth running, but
                it remains as a place-holder for a test to be
                written in the future.  This constraint always
                causes tests to be skipped.

knownBug	test is known to fail and the bug is not yet
                fixed.  This constraint always causes tests to be
                skipped unless the user specifies otherwise.  See the
                "Introduction" section for more details.

nonPortable	test can only be run in the master Tcl/Tk
		development environment.  Some tests are inherently
		non-portable because they depend on things like word
		length, file system configuration, window manager,
		etc.  These tests are only run in the main Tcl
		development directory where the configuration is
		well known.  This constraint always causes tests to be
		skipped unless the user specifies otherwise.  See the
		"Introduction" section for more details.

userInteraction test requires interaction from the user.  This
                constraint always causes tests to be skipped unless
                the user specifies otherwise.  See the "Introduction"
                section for more details. 

interactive	test can only be run in if the interpreter is in
		interactive mode, that is the global tcl_interactive
		variable is set to 1.

nonBlockFiles	test can only be run if platform supports setting
		files into nonblocking mode

asyncPipeClose	test can only be run if platform supports async
		flush and async close on a pipe

unixExecs	test can only be run if this machine has commands
		such as 'cat', 'echo', etc. available.

hasIsoLocale	test can only be run if can switch to an ISO locale

fonts		test can only be run if the wish app's fonts can
		be controlled by Tk.

root		test can only run if Unix user is root

notRoot		test can only run if Unix user is not root

eformat		test can only run if app has a working version of
		sprintf with respect to the "e" format of
		floating-point numbers.

stdio		test can only be run if the current app can be
		spawned via a pipe


5. Adding a new test file:
--------------------------

Tests files should begin by sourcing the defs.tcl file:

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

Test files sould end by cleaning up after themselves and calling
::tcltest::cleanupTests.  The ::tcltest::cleanupTests procedure prints
statistics about the number of tests that passed, skipped, and failed,
and removes all files that were created using the ::tcltest::makeFile
and ::tcltest::makeDirectory procedures.

    # Remove files created by these tests
    # Change to original working directory
    # Unset global arrays
    ::tcltest::cleanupTests
    return

The all.tcl file will source your new test file if the filename
matches the tests/*.test pattern (as it should).  The names of test
files that contain regression (or glass-box) tests should correspond
to the Tcl or C code file that they are testing.  For example, the
test file for the C file "tclCmdAH.c" is "cmdAH.test".  Test files
that contain black-box tests may not correspond to any Tcl or C code
file so they should match the pattern "*_bb.test".

Be sure your new test file can be run from any working directory.

Be sure no temporary files are left behind by your test file.

Be sure your tests can run cross-platform in both a build environment
as well as an installation environment.  If your test file contains
tests that should not be run in one or more of those cases, please use
the constraints mechanism to skip those tests.


6. Test output:
---------------

After all specified test files are sourced, the number of tests
passed, skipped, and failed is printed to stdout.  Aside from this
statistical information, output can be controlled on a per-test basis
by the ::tcltest::verbose variable.

::tcltest::verbose can be set to any substring or permutation of "bps".
In the string "bps", the 'b' stands for a test's "body", the 'p'
stands for "passed" tests, and the 's' stands for "skipped" tests.
The default value of ::tcltest::verbose is "b".  If 'b' is present, then
the entire body of the test is printed for each failed test, otherwise
only the test's name, desired output, and actual output, are printed
for each failed test.  If 'p' is present, then a line is printed for
each passed test, otherwise no line is printed for passed tests.  If
's' is present, then a line (containing the consraints that cause the
test to be skipped) is printed for each skipped test, otherwise no
line is printed for skipped tests.

You can set ::tcltest::verbose either interactively (after the defs.tcl
file has been sourced) or by the command line argument -verbose, for
example:

      tcltest socket.test -verbose bps


7. Selecting tests for execution within a file:
-----------------------------------------------

Normally, all the tests in a file are run whenever the file is
sourced.  An individual test will be skipped if one of the following
conditions is met:

    1) the "name" of the tests does not match (using glob style
       matching) one or more elements in the ::tcltest::match
       variable

    2) the "name" of the tests matches (using glob style matching) one
       or more elements in the ::tcltest::skip variable

    3) the "constraints" argument to the "test" call, if given,
       contains one or more false elements.

You can set ::tcltest::match and/or ::tcltest::skip
either interactively (after the defs.tcl file has been sourced), or by
the command line arguments -match and -skip, for example:

       tcltest info.test -match '*-5.* *-7.*' -skip '*-7.1*'

Be sure to use the proper quoting convention so that your shell does
not perform the glob substitution on the match or skip patterns you
specify.

The two predefined constraints (knownBug and nonPortable) can be
overridden either interactively (after the defs.tcl file has been
sourced) by setting the ::tcltest::testConfig(<constraint>) variable,
or by using the -constraints command line option with the name of the
constraint in the argument.  The following example shows how to run
tests that are constrained by the knownBug and nonPortable
restricions:

	tcltest all.tcl -constraints "knownBug nonPortable"

See the defs.tcl file for information about each of these constraints.
Other constraints can be added at any time.  See the "Writing a new
test" section below for more details about using built-in constraints
and adding new ones.


8. Selecting files to be sourced by all.tcl:
--------------------------------------------





You can specify the files you want all.tcl to source on the command
line with the -file options.  For example, if you call the
following:

     tcltest all.tcl -file 'unix*.test'

all files in "tests" directory that match the pattern unix*.test will
be sourced by the all.tcl file.  Another useful example is if a
particular test hangs, say "get.test", and you just want to run the
remaining tests, then you can call the following:

     tcltest all.tcl -file '[h-z]*.test'

Note that the argument to -file will be substituted relative to the
"tests" directory.  Be sure to use the proper quoting convention so
that your shell does not perform the glob substitution.


9. Incompatibilities with prior Tcl versions:
---------------------------------------------


1) Global variables such as VERBOSE, TESTS, and testConfig are now
   renamed to use the new "tcltest" namespace.

   old name   new name
   --------   --------
   VERBOSE    ::tcltest::verbose
   TESTS      ::tcltest::match
   testConfig ::tcltest::testConfig

   The introduction of the "tcltest" namespace is a precursor to using
   a "tcltest" package.  This next step will be part of a future Tcl
   version.

2) VERBOSE values are no longer numeric.  Please see the section above
   on "Test output" for the new usage of the ::tcltest::verbose variable.

3) When you run "make test", the working dir for the test suite is now
   the one from which you called "make test", rather than the "tests"
   directory.  This change allows for both unix and windows test
   suites to be run simultaneously without interference with each
   other or with existing files.  All tests must now run independently
   of their working directory.

4) The "all", "defs", and "visual" files are now called "all.tcl",
   "defs.tcl", and "visual_bb.test", respectively.

5) Instead of creating a doAllTests file in the tests directory, to
   run all nonPortable tests, just use the "-constraints nonPortable"
   command line flag.  If you are running interactively, you can set
   the ::tcltest::testConfig(nonPortable) variable to 1 (after
   sourcing the defs.tcl file).

Deleted tests/all.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# This file contains a top-level script to run all of the Tcl
# tests.  Execute it by invoking "source all" when running tclTest
# in this directory.
#
# SCCS: @(#) all 1.8 97/08/01 11:07:14

if {$tcl_platform(os) == "Win32s"} {
    set files [glob *.tes]
} else {
    set files [glob *.test]
}

foreach i [lsort $files] {
    if [string match l.*.test $i] {
	# This is an SCCS lock file;  ignore it.
	continue
    }
    puts stdout $i
    if [catch {source $i} msg] {
	puts $msg
    }	
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































Added tests/all.tcl.

























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# all.tcl --
#
# This file contains a top-level script to run all of the Tcl
# tests.  Execute it by invoking "source all.test" when running tcltest
# in this directory.
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
# 
# RCS: @(#) $Id: all.tcl,v 1.1.2.6 1999/04/07 01:59:27 hershey Exp $

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

puts stdout "Tcl $tcl_patchLevel tests running in interp:  [info nameofexecutable]"
puts stdout "Tests running in working dir:  $::tcltest::workingDir"
if {[llength $::tcltest::skip] > 0} {
    puts stdout "Skipping tests that match:  $::tcltest::skip"
}
if {[llength $::tcltest::match] > 0} {
    puts stdout "Only running tests that match:  $::tcltest::match"
}

# Use command line specified glob pattern (specified by -file or -f)
# if one exists.  Otherwise use *.test.  If given, the file pattern
# should be specified relative to the dir containing this file.  If no
# files are found to match the pattern, print an error message and exit.
set fileIndex [expr {[lsearch $argv "-file"] + 1}]
set fIndex [expr {[lsearch $argv "-f"] + 1}]
if {($fileIndex < 1) || ($fIndex > $fileIndex)} {
    set fileIndex $fIndex
}
if {$fileIndex > 0} {
    set globPattern [file join $::tcltest::testsDir [lindex $argv $fileIndex]]
    puts stdout "Sourcing files that match:  $globPattern"
} else {
    set globPattern [file join $::tcltest::testsDir *.test]
}
set fileList [glob -nocomplain $globPattern]
if {[llength $fileList] < 1} {
    puts "Error: no files found matching $globPattern"
    exit
}
set timeCmd {clock format [clock seconds]}
puts stdout "Tests began at [eval $timeCmd]"

# source each of the specified tests
foreach file [lsort $fileList] {
    set tail [file tail $file]
    if {[string match l.*.test $tail]} {
	# This is an SCCS lockfile; ignore it
	continue
    }
    puts stdout $tail
    if {[catch {source $file} msg]} {
	puts stdout $msg
    }
}

# cleanup
puts stdout "\nTests ended at [eval $timeCmd]"
::tcltest::cleanupTests 1
return











Changes to tests/append.test.

1
2
3
4
5
6
7
8

9
10
11
12
13
14

15
16
17

18
19
20
21
22
23
24
# Commands covered:  append lappend
#
# 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-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) append.test 1.17 97/10/28 15:45:52


if {[string compare test [info procs test]] == 1} then {source defs}

catch {unset x}

test append-1.1 {append command} {
    catch {unset x}
    list [append x 1 2 abc "long string"] $x
} {{12abclong string} {12abclong string}}
test append-1.2 {append command} {
    set x ""
    list [append x first] [append x second] [append x third] $x








>




|

>
|
|

>







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
# Commands covered:  append lappend
#
# 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-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: append.test,v 1.1.2.5 1999/03/24 02:48:55 hershey Exp $

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

test append-1.1 {append command} {
    catch {unset x}
    list [append x 1 2 abc "long string"] $x
} {{12abclong string} {12abclong string}}
test append-1.2 {append command} {
    set x ""
    list [append x first] [append x second] [append x third] $x
166
167
168
169
170
171
172
173
174

















    proc foo {args} {global x; unset x}
    info exists x
    set x
    lappend x 1
    list [info exists x] [catch {set x} msg] $msg
} {0 1 {can't read "x": no such variable}}

catch {unset x}
catch {rename foo ""}
























|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    proc foo {args} {global x; unset x}
    info exists x
    set x
    lappend x 1
    list [info exists x] [catch {set x} msg] $msg
} {0 1 {can't read "x": no such variable}}

catch {unset i x result y}
catch {rename foo ""}
catch {rename check ""}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/assocd.test.

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
# This file tests the AssocData facility of Tcl
#
# 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-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# "@(#) assocd.test 1.5 95/08/02 17:11:37"



if {[string compare test [info procs test]] == 1} then {source defs}

if {[string compare testsetassocdata [info commands testsetassocdata]] != 0} {
    puts "This application hasn't been compiled with the tests for assocData,"
    puts "therefore I am skipping all of these tests."

    return
}

test assocd-1.1 {testing setting assoc data} {
   testsetassocdata a 1
} ""
test assocd-1.2 {testing setting assoc data} {








>




>
|
>
>
|
<




>







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
# This file tests the AssocData facility of Tcl
#
# 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-1994 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: assocd.test,v 1.1.2.6 1999/03/26 19:13:55 hershey Exp $

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


if {[string compare testsetassocdata [info commands testsetassocdata]] != 0} {
    puts "This application hasn't been compiled with the tests for assocData,"
    puts "therefore I am skipping all of these tests."
    ::tcltest::cleanupTests
    return
}

test assocd-1.1 {testing setting assoc data} {
   testsetassocdata a 1
} ""
test assocd-1.2 {testing setting assoc data} {
51
52
53
54
55
56
57
















} ""
test assocd-3.2 {testing deleting assoc data} {
   testdelassocdata 123
} ""
test assocd-3.3 {testing deleting assoc data} {
   list [catch {testdelassocdata nonexistent} msg] $msg
} {0 {}}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
} ""
test assocd-3.2 {testing deleting assoc data} {
   testdelassocdata 123
} ""
test assocd-3.3 {testing deleting assoc data} {
   list [catch {testdelassocdata nonexistent} msg] $msg
} {0 {}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/async.test.

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
# Commands covered:  none
#
# This file contains a collection of tests for Tcl_AsyncCreate and related
# library procedures.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) async.test 1.5 96/04/05 15:29:38




if {[info commands testasync] == {}} {
    puts "This application hasn't been compiled with the \"testasync\""
    puts "command, so I can't test Tcl_AsyncCreate et al."

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

proc async1 {result code} {
    global aresult acode
    set aresult $result
    set acode $code
    return "new result"
}
proc async2 {result code} {








>




>
|
>
>
>




>



<
<







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
# Commands covered:  none
#
# This file contains a collection of tests for Tcl_AsyncCreate and related
# library procedures.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1993 The Regents of the University of California.
# 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: async.test,v 1.1.2.6 1999/03/26 19:13:56 hershey Exp $

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

if {[info commands testasync] == {}} {
    puts "This application hasn't been compiled with the \"testasync\""
    puts "command, so I can't test Tcl_AsyncCreate et al."
    ::tcltest::cleanupTests
    return
}



proc async1 {result code} {
    global aresult acode
    set aresult $result
    set acode $code
    return "new result"
}
proc async2 {result code} {
124
125
126
127
128
129
130

131














set hm4 [testasync create del2]

test async-3.1 {deleting handlers} {
    set x {}
    list [catch {testasync mark $hm2 "foobar" 5} msg] $msg $x
} {3 del2 {0 0 0 del1 del2}}


testasync delete





















>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
set hm4 [testasync create del2]

test async-3.1 {deleting handlers} {
    set x {}
    list [catch {testasync mark $hm2 "foobar" 5} msg] $msg $x
} {3 del2 {0 0 0 del1 del2}}

# cleanup
testasync delete
::tcltest::cleanupTests
return












Added tests/autoMkindex.tcl.



















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# Test file for:
#   auto_mkindex
#
# This file provides example cases for testing the Tcl autoloading
# facility.  Things are much more complicated with namespaces and classes.
# The "auto_mkindex" facility can no longer be built on top of a simple
# regular expression parser.  It must recognize constructs like this:
#
#   namespace eval foo {
#       proc test {x y} { ... }
#       namespace eval bar {
#           proc another {args} { ... }
#       }
#   }
#
# Note that procedures and itcl class definitions can be nested inside
# of namespaces.
#
# Copyright (c) 1993-1998  Lucent Technologies, Inc.

# This shouldn't cause any problems
namespace import -force blt::*

# Should be able to handle "proc" definitions, even if they are
# preceded by white space.

proc normal {x y} {return [expr $x+$y]}
  proc indented {x y} {return [expr $x+$y]}

#
# Should be able to handle proc declarations within namespaces,
# even if they have explicit namespace paths.
#
namespace eval buried {
    proc inside {args} {return "inside: $args"}

    namespace export pub_*
    proc pub_one {args} {return "one: $args"}
    proc pub_two {args} {return "two: $args"}
}
proc buried::within {args} {return "within: $args"}

namespace eval buried {
    namespace eval under {
        proc neath {args} {return "neath: $args"}
    }
    namespace eval ::buried {
        proc relative {args} {return "relative: $args"}
        proc ::top {args} {return "top: $args"}
        proc ::buried::explicit {args} {return "explicit: $args"}
    }
}

# With proper hooks, we should be able to support other commands
# that create procedures

proc buried::myproc {name body args} {
    ::proc $name $body $args
}
namespace eval ::buried {
    proc mycmd1 args {return "mycmd"}
    myproc mycmd2 args {return "mycmd"}
}
::buried::myproc mycmd3 args {return "another"}

proc {buried::my proc} {name body args} {
    ::proc $name $body $args
}
namespace eval ::buried {
    proc mycmd4 args {return "mycmd"}
    {my proc} mycmd5 args {return "mycmd"}
}
{::buried::my proc} mycmd6 args {return "another"}

Added tests/autoMkindex.test.



























































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# Commands covered:  auto_mkindex auto_import
#
# This file contains tests related to autoloading and generating
# the autoloading index.
#
# Copyright (c) 1998  Lucent Technologies, 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: autoMkindex.test,v 1.1.2.6 1999/03/31 19:54:25 welch Exp $

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

# temporarily copy the autoMkindex.tcl file from testsDir to tmpDir
set origMkindexFile [file join $::tcltest::testsDir autoMkindex.tcl]
set newMkindexFile [file join $::tcltest::workingDir autoMkindex.tcl]
if {![catch {file copy $origMkindexFile $newMkindexFile}]} {
    set removeAutoMkindex 1
}

# Save initial state of auto_mkindex_parser

auto_load auto_mkindex
if {[info exist auto_mkindex_parser::initCommands]} {
    set saveCommands $auto_mkindex_parser::initCommands
}
proc AutoMkindexTestReset {} {
    global saveCommands
    if {[info exist saveCommands]} {
	set auto_mkindex_parser::initCommands $saveCommands
    } elseif {[info exist auto_mkindex_parser::initCommands]} {
	unset auto_mkindex_parser::initCommands
    }
}

set result ""

test autoMkindex-1.1 {remove any existing tclIndex file} {
    file delete tclIndex
    file exists tclIndex
} {0}

test autoMkindex-1.2 {build tclIndex based on a test file} {
    auto_mkindex . autoMkindex.tcl
    file exists tclIndex
} {1}

set element "{source [file join . autoMkindex.tcl]}"

test autoMkindex-1.3 {examine tclIndex} {
    file delete tclIndex
    auto_mkindex . autoMkindex.tcl
    namespace eval tcl_autoMkindex_tmp {
        set dir "."
        variable auto_index
        source tclIndex
        set ::result ""
        foreach elem [lsort [array names auto_index]] {
            lappend ::result [list $elem $auto_index($elem)]
        }
    }
    namespace delete tcl_autoMkindex_tmp
    set ::result
} "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {indented $element} {normal $element} {top $element}"


test autoMkindex-2.1 {commands on the autoload path can be imported} {
    file delete tclIndex
    auto_mkindex . autoMkindex.tcl
    set interp [interp create]
    set final [$interp eval {
        namespace eval blt {}
        set auto_path [linsert $auto_path 0 .]
        set info [list [catch {namespace import buried::*} result] $result]
        foreach name [lsort [info commands pub_*]] {
            lappend info $name [namespace origin $name]
        }
        set info
    }]
    interp delete $interp
    set final
} "0 {} pub_one ::buried::pub_one pub_two ::buried::pub_two"

# Test auto_mkindex hooks

# Slave hook executes interesting code in the interp used to watch code.

test autoMkindex-3.1 {slaveHook} {
    auto_mkindex_parser::slavehook {
	_%@namespace eval ::blt {
	    proc foo {} {}
	    _%@namespace export foo
	}
    }
    auto_mkindex_parser::slavehook { _%@namespace import -force ::blt::* }
    file delete tclIndex
    auto_mkindex . autoMkindex.tcl
     
    # Reset initCommands to avoid trashing other tests

    AutoMkindexTestReset
    file exists tclIndex
} 1 

# The auto_mkindex_parser::command is used to register commands
# that create new commands.

test autoMkindex-3.2 {auto_mkindex_parser::command} {
    auto_mkindex_parser::command buried::myproc {name args} {
	variable index
	variable scriptFile
	append index [list set auto_index([fullname $name])] \
		" \[list source \[file join \$dir [list $scriptFile]\]\]\n"
    }
    file delete tclIndex
    auto_mkindex . autoMkindex.tcl
    namespace eval tcl_autoMkindex_tmp {
        set dir "."
        variable auto_index
        source tclIndex
        set ::result ""
        foreach elem [lsort [array names auto_index]] {
            lappend ::result [list $elem $auto_index($elem)]
        }
    }
    namespace delete tcl_autoMkindex_tmp

    # Reset initCommands to avoid trashing other tests

    AutoMkindexTestReset
    set ::result
} "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd2 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {indented $element} {mycmd3 $element} {normal $element} {top $element}"


test autoMkindex-3.3 {auto_mkindex_parser::command} {knownBug} {
    auto_mkindex_parser::command {buried::my proc} {name args} {
	variable index
	variable scriptFile
	puts "my proc $name"
	append index [list set auto_index([fullname $name])] \
		" \[list source \[file join \$dir [list $scriptFile]\]\]\n"
    }
    file delete tclIndex
    auto_mkindex . autoMkindex.tcl
    namespace eval tcl_autoMkindex_tmp {
        set dir "."
        variable auto_index
        source tclIndex
        set ::result ""
        foreach elem [lsort [array names auto_index]] {
            lappend ::result [list $elem $auto_index($elem)]
        }
    }
    namespace delete tcl_autoMkindex_tmp

    # Reset initCommands to avoid trashing other tests

    AutoMkindexTestReset
    proc lvalue {list pattern} {
	set ix [lsearch $list $pattern]
	if {$ix >= 0} {
	    return [lindex $list $ix]
	} else {
	    return {}
	}
    }
    list [lvalue $::result *mycmd4*] [lvalue $::result *mycmd5*] [lvalue $::result *mycmd6*]
} "{::buried::mycmd4 $element} {::buried::mycmd5 $element} {mycmd6 $element}"

# Clean up.

unset result
AutoMkindexTestReset
if {[info exist saveCommands]} {
    unset saveCommands
}
rename AutoMkindexTestReset ""

if {[info exists removeAutoMkindex]} {
    catch {file delete $newMkindexFile}
}
if {[file exists tclIndex]} {
    file delete -force tclIndex
}
::tcltest::cleanupTests

Changes to tests/basic.test.

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
# This file contains tests for the tclBasic.c source file. Tests appear in
# the same order as the C code that they test. The set of tests is
# currently incomplete since it currently includes only new tests for
# code changed for the addition of Tcl namespaces. Other variable-
# related tests appear in several other test files including
# assocd.test, cmdInfo.test, eval.test, expr.test, interp.test,
# and trace.test.
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) basic.test 1.19 97/10/31 16:02:26
#


if {[string compare test [info procs test]] == 1} then {source defs}


catch {namespace delete test_ns_basic}
catch {interp delete test_interp}
catch {rename p ""}
catch {rename q ""}
catch {rename cmd ""}
catch {unset x}












>




|


>
|
>







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
# This file contains tests for the tclBasic.c source file. Tests appear in
# the same order as the C code that they test. The set of tests is
# currently incomplete since it currently includes only new tests for
# code changed for the addition of Tcl namespaces. Other variable-
# related tests appear in several other test files including
# assocd.test, cmdInfo.test, eval.test, expr.test, interp.test,
# and trace.test.
#
# 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: basic.test,v 1.1.2.6 1999/03/25 04:32:16 hershey Exp $
#

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

catch {namespace delete test_ns_basic}
catch {interp delete test_interp}
catch {rename p ""}
catch {rename q ""}
catch {rename cmd ""}
catch {unset x}
36
37
38
39
40
41
42
























43
44
45
46
47
48
49
50
            }
        }
    }
    list [interp eval test_interp {test_ns_basic::p}] \
         [interp delete test_interp]
} {::test_ns_basic {}}

























test basic-2.1 {DeleteInterpProc, destroys interp's global namespace} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        namespace eval test_ns_basic {
            namespace export p
            proc p {} {
                return [namespace current]







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







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
            }
        }
    }
    list [interp eval test_interp {test_ns_basic::p}] \
         [interp delete test_interp]
} {::test_ns_basic {}}

test basic-2.1 {TclHideUnsafeCommands} {emptyTest} {
} {}

test basic-3.1 {Tcl_CallWhenDeleted: see dcall.test} {emptyTest} {
} {}

test basic-4.1 {Tcl_DontCallWhenDeleted: see dcall.test} {emptyTest} {
} {}

test basic-5.1 {Tcl_SetAssocData: see assoc.test} {emptyTest} {
} {}

test basic-6.1 {Tcl_DeleteAssocData: see assoc.test} {emptyTest} {
} {}

test basic-7.1 {Tcl_GetAssocData: see assoc.test} {emptyTest} {
} {}

test basic-8.1 {Tcl_InterpDeleted} {emptyTest} {
} {}

test basic-9.1 {Tcl_DeleteInterp: see interp.test} {emptyTest} {
} {}

test basic-10.1 {DeleteInterpProc, destroys interp's global namespace} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        namespace eval test_ns_basic {
            namespace export p
            proc p {} {
                return [namespace current]
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
    }
    list [interp eval test_interp {test_ns_2::q}] \
         [interp eval test_interp {namespace delete ::}] \
         [catch {interp eval test_interp {set a 123}} msg] $msg \
         [interp delete test_interp]
} {{::test_ns_basic 27} {} 1 {invalid command name "set"} {}}

test basic-3.1 {HiddenCmdsDeleteProc, invalidate cached refs to deleted hidden cmd} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        proc p {} {
            return 27
        }
    }
    interp alias {} localP test_interp p
    list [interp eval test_interp {p}] \
         [localP] \
         [test_interp hide p] \
         [catch {localP} msg] $msg \
         [interp delete test_interp] \
         [catch {localP} msg] $msg
} {27 27 {} 1 {invalid command name "p"} {} 1 {invalid command name "localP"}}

# NB: More tests about hide/expose are found in interp.test

test basic-4.1 {Tcl_HideCommand, names of hidden cmds can't have namespace qualifiers} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        namespace eval test_ns_basic {
            proc p {} {
                return [namespace current]
            }
        }
    }
    list [catch {test_interp hide test_ns_basic::p x} msg] $msg \
	 [catch {test_interp hide x test_ns_basic::p} msg1] $msg1 \
         [interp delete test_interp]
} {1 {can only hide global namespace commands (use rename then hide)} 1 {cannot use namespace qualifiers as hidden commandtoken (rename)} {}}

test basic-4.2 {Tcl_HideCommand, a hidden cmd remembers its containing namespace} {
    catch {namespace delete test_ns_basic}
    catch {rename cmd ""}
    proc cmd {} {   ;# note that this is global
        return [namespace current]
    }
    namespace eval test_ns_basic {
        proc hideCmd {} {







|


















|














|







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
    }
    list [interp eval test_interp {test_ns_2::q}] \
         [interp eval test_interp {namespace delete ::}] \
         [catch {interp eval test_interp {set a 123}} msg] $msg \
         [interp delete test_interp]
} {{::test_ns_basic 27} {} 1 {invalid command name "set"} {}}

test basic-11.1 {HiddenCmdsDeleteProc, invalidate cached refs to deleted hidden cmd} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        proc p {} {
            return 27
        }
    }
    interp alias {} localP test_interp p
    list [interp eval test_interp {p}] \
         [localP] \
         [test_interp hide p] \
         [catch {localP} msg] $msg \
         [interp delete test_interp] \
         [catch {localP} msg] $msg
} {27 27 {} 1 {invalid command name "p"} {} 1 {invalid command name "localP"}}

# NB: More tests about hide/expose are found in interp.test

test basic-12.1 {Tcl_HideCommand, names of hidden cmds can't have namespace qualifiers} {
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        namespace eval test_ns_basic {
            proc p {} {
                return [namespace current]
            }
        }
    }
    list [catch {test_interp hide test_ns_basic::p x} msg] $msg \
	 [catch {test_interp hide x test_ns_basic::p} msg1] $msg1 \
         [interp delete test_interp]
} {1 {can only hide global namespace commands (use rename then hide)} 1 {cannot use namespace qualifiers as hidden commandtoken (rename)} {}}

test basic-12.2 {Tcl_HideCommand, a hidden cmd remembers its containing namespace} {
    catch {namespace delete test_ns_basic}
    catch {rename cmd ""}
    proc cmd {} {   ;# note that this is global
        return [namespace current]
    }
    namespace eval test_ns_basic {
        proc hideCmd {} {
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
         [test_ns_basic::hideCmd] \
         [catch {cmd} msg] $msg \
         [test_ns_basic::exposeCmd] \
         [test_ns_basic::callCmd] \
         [namespace delete test_ns_basic]
} {:: {} 1 {invalid command name "cmd"} {} :: {}}

test basic-5.1 {Tcl_ExposeCommand, a command stays in the global namespace and can not go to another namespace} {
    catch {namespace delete test_ns_basic}
    catch {rename cmd ""}
    proc cmd {} {   ;# note that this is global
        return [namespace current]
    }
    namespace eval test_ns_basic {
        proc hideCmd {} {







|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
         [test_ns_basic::hideCmd] \
         [catch {cmd} msg] $msg \
         [test_ns_basic::exposeCmd] \
         [test_ns_basic::callCmd] \
         [namespace delete test_ns_basic]
} {:: {} 1 {invalid command name "cmd"} {} :: {}}

test basic-13.1 {Tcl_ExposeCommand, a command stays in the global namespace and can not go to another namespace} {
    catch {namespace delete test_ns_basic}
    catch {rename cmd ""}
    proc cmd {} {   ;# note that this is global
        return [namespace current]
    }
    namespace eval test_ns_basic {
        proc hideCmd {} {
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
    list [test_ns_basic::callCmd] \
         [test_ns_basic::hideCmd] \
         [catch {test_ns_basic::exposeCmdFailing} msg] $msg \
         [test_ns_basic::exposeCmdWorkAround] \
         [test_ns_basic::newCmd] \
         [namespace delete test_ns_basic]
} {:: {} 1 {can not expose to a namespace (use expose to toplevel, then rename)} {} ::test_ns_basic {}}
test basic-5.2 {Tcl_ExposeCommand, invalidate cached refs to cmd now being exposed} {
    catch {rename p ""}
    catch {rename cmd ""}
    proc p {} {
        cmd
    }
    proc cmd {} {
        return 42
    }
    list [p] \
         [interp hide {} cmd] \
         [proc cmd {} {return Hello}] \
         [cmd] \
         [rename cmd ""] \
         [interp expose {} cmd] \
         [p]
} {42 {} {} Hello {} {} 42}

if {[info commands testcreatecommand] != {}} {



    test basic-6.1 {Tcl_CreateCommand, new cmd goes into a namespace specified in its name, if any} {
        catch {eval namespace delete [namespace children :: test_ns_*]}
        list [testcreatecommand create] \
             [test_ns_basic::createdcommand] \
             [testcreatecommand delete]
    } {{} {CreatedCommandProc in ::test_ns_basic} {}}
    test basic-6.2 {Tcl_CreateCommand, namespace code ignore single ":"s in middle or end of names} {
        catch {eval namespace delete [namespace children :: test_ns_*]}
        catch {rename value:at: ""}
        list [testcreatecommand create2] \
             [value:at:] \
             [testcreatecommand delete2]
    } {{} {CreatedCommandProc2 in ::} {}}
}

test basic-6.3 {Tcl_CreateObjCommand, new cmd goes into a namespace specified in its name, if any} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    namespace eval test_ns_basic {}
    proc test_ns_basic::cmd {} {  ;# proc requires that ns already exist
        return [namespace current]
    }
    list [test_ns_basic::cmd] \
         [namespace delete test_ns_basic]
} {::test_ns_basic {}}







test basic-7.1 {TclRenameCommand, name of existing cmd can have namespace qualifiers} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename cmd ""}
    namespace eval test_ns_basic {
        proc p {} {
            return "p in [namespace current]"
        }
    }
    list [test_ns_basic::p] \
         [rename test_ns_basic::p test_ns_basic::q] \
         [test_ns_basic::q] 
} {{p in ::test_ns_basic} {} {p in ::test_ns_basic}}
test basic-7.2 {TclRenameCommand, existing cmd must be found} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    list [catch {rename test_ns_basic::p test_ns_basic::q} msg] $msg
} {1 {can't rename "test_ns_basic::p": command doesn't exist}}
test basic-7.3 {TclRenameCommand, delete cmd if new name is empty} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    namespace eval test_ns_basic {
        proc p {} {
            return "p in [namespace current]"
        }
    }
    list [info commands test_ns_basic::*] \
         [rename test_ns_basic::p ""] \
         [info commands test_ns_basic::*]
} {::test_ns_basic::p {} {}}
test basic-7.4 {TclRenameCommand, bad new name} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    namespace eval test_ns_basic {
        proc p {} {
            return "p in [namespace current]"
        }
    }
    rename test_ns_basic::p :::george::martha
} {}
test basic-7.5 {TclRenameCommand, new name must not already exist} {
    namespace eval test_ns_basic {
        proc q {} {
            return 42
        }
    }
    list [catch {rename test_ns_basic::q :::george::martha} msg] $msg
} {1 {can't rename to ":::george::martha": command already exists}}
test basic-7.6 {TclRenameCommand, check for command shadowing by newly renamed cmd} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename p ""}
    catch {rename q ""}
    proc p {} {
        return "p in [namespace current]"
    }
    proc q {} {
        return "q in [namespace current]"
    }
    namespace eval test_ns_basic {
        proc callP {} {
            p
        }
    }
    list [test_ns_basic::callP] \
         [rename q test_ns_basic::p] \
         [test_ns_basic::callP]
} {{p in ::} {} {q in ::test_ns_basic}}








test basic-8.1 {Tcl_GetCommandInfo, names for commands created inside namespaces} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename p ""}
    catch {rename q ""}
    catch {unset x}
    set x [namespace eval test_ns_basic::test_ns_basic2 {
        # the following creates a cmd in the global namespace
        testcmdtoken create p
    }]
    list [testcmdtoken name $x] \
         [rename ::p q] \
         [testcmdtoken name $x]
} {{p ::p} {} {q ::q}}
test basic-8.2 {Tcl_GetCommandInfo, names for commands created outside namespaces} {
    catch {rename q ""}
    set x [testcmdtoken create test_ns_basic::test_ns_basic2::p]
    list [testcmdtoken name $x] \
         [rename test_ns_basic::test_ns_basic2::p q] \
         [testcmdtoken name $x]
} {{p ::test_ns_basic::test_ns_basic2::p} {} {q ::q}}





test basic-9.1 {Tcl_GetCommandFullName} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    namespace eval test_ns_basic1 {
        namespace export cmd*
        proc cmd1 {} {}
        proc cmd2 {} {}
    }
    namespace eval test_ns_basic2 {







|

















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

>
|









>
>
>
>
>
>
|











|



|










|








|







|



















>
>
>
>
>
>
>
|












|






|
>
>
>
>
|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
    list [test_ns_basic::callCmd] \
         [test_ns_basic::hideCmd] \
         [catch {test_ns_basic::exposeCmdFailing} msg] $msg \
         [test_ns_basic::exposeCmdWorkAround] \
         [test_ns_basic::newCmd] \
         [namespace delete test_ns_basic]
} {:: {} 1 {can not expose to a namespace (use expose to toplevel, then rename)} {} ::test_ns_basic {}}
test basic-13.2 {Tcl_ExposeCommand, invalidate cached refs to cmd now being exposed} {
    catch {rename p ""}
    catch {rename cmd ""}
    proc p {} {
        cmd
    }
    proc cmd {} {
        return 42
    }
    list [p] \
         [interp hide {} cmd] \
         [proc cmd {} {return Hello}] \
         [cmd] \
         [rename cmd ""] \
         [interp expose {} cmd] \
         [p]
} {42 {} {} Hello {} {} 42}

if {[info commands testcreatecommand] == ""} {
    puts "This application hasn't been compiled with the testcreatecommand"
    puts "command.  Skipping affected tests."
} else {
test basic-14.1 {Tcl_CreateCommand, new cmd goes into a namespace specified in its name, if any} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    list [testcreatecommand create] \
	 [test_ns_basic::createdcommand] \
	 [testcreatecommand delete]
} {{} {CreatedCommandProc in ::test_ns_basic} {}}
test basic-14.2 {Tcl_CreateCommand, namespace code ignore single ":"s in middle or end of names} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename value:at: ""}
    list [testcreatecommand create2] \
	 [value:at:] \
	 [testcreatecommand delete2]
} {{} {CreatedCommandProc2 in ::} {}}
}

test basic-15.1 {Tcl_CreateObjCommand, new cmd goes into a namespace specified in its name, if any} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    namespace eval test_ns_basic {}
    proc test_ns_basic::cmd {} {  ;# proc requires that ns already exist
        return [namespace current]
    }
    list [test_ns_basic::cmd] \
         [namespace delete test_ns_basic]
} {::test_ns_basic {}}

test basic-16.1 {TclInvokeStringCommand} {emptyTest} {
} {}

test basic-17.1 {TclInvokeObjCommand} {emptyTest} {
} {}

test basic-18.1 {TclRenameCommand, name of existing cmd can have namespace qualifiers} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename cmd ""}
    namespace eval test_ns_basic {
        proc p {} {
            return "p in [namespace current]"
        }
    }
    list [test_ns_basic::p] \
         [rename test_ns_basic::p test_ns_basic::q] \
         [test_ns_basic::q] 
} {{p in ::test_ns_basic} {} {p in ::test_ns_basic}}
test basic-18.2 {TclRenameCommand, existing cmd must be found} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    list [catch {rename test_ns_basic::p test_ns_basic::q} msg] $msg
} {1 {can't rename "test_ns_basic::p": command doesn't exist}}
test basic-18.3 {TclRenameCommand, delete cmd if new name is empty} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    namespace eval test_ns_basic {
        proc p {} {
            return "p in [namespace current]"
        }
    }
    list [info commands test_ns_basic::*] \
         [rename test_ns_basic::p ""] \
         [info commands test_ns_basic::*]
} {::test_ns_basic::p {} {}}
test basic-18.4 {TclRenameCommand, bad new name} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    namespace eval test_ns_basic {
        proc p {} {
            return "p in [namespace current]"
        }
    }
    rename test_ns_basic::p :::george::martha
} {}
test basic-18.5 {TclRenameCommand, new name must not already exist} {
    namespace eval test_ns_basic {
        proc q {} {
            return 42
        }
    }
    list [catch {rename test_ns_basic::q :::george::martha} msg] $msg
} {1 {can't rename to ":::george::martha": command already exists}}
test basic-18.6 {TclRenameCommand, check for command shadowing by newly renamed cmd} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename p ""}
    catch {rename q ""}
    proc p {} {
        return "p in [namespace current]"
    }
    proc q {} {
        return "q in [namespace current]"
    }
    namespace eval test_ns_basic {
        proc callP {} {
            p
        }
    }
    list [test_ns_basic::callP] \
         [rename q test_ns_basic::p] \
         [test_ns_basic::callP]
} {{p in ::} {} {q in ::test_ns_basic}}

test basic-19.1 {Tcl_SetCommandInfo} {emptyTest} {
} {}

if {[info commands testcmdtoken] == {}} {
    puts "This application hasn't been compiled with the \"testcmdtoken\""
    puts "command, so I can't test Tcl_GetCommandInfo."
} else {
test basic-20.1 {Tcl_GetCommandInfo, names for commands created inside namespaces} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename p ""}
    catch {rename q ""}
    catch {unset x}
    set x [namespace eval test_ns_basic::test_ns_basic2 {
        # the following creates a cmd in the global namespace
        testcmdtoken create p
    }]
    list [testcmdtoken name $x] \
         [rename ::p q] \
         [testcmdtoken name $x]
} {{p ::p} {} {q ::q}}
test basic-20.2 {Tcl_GetCommandInfo, names for commands created outside namespaces} {
    catch {rename q ""}
    set x [testcmdtoken create test_ns_basic::test_ns_basic2::p]
    list [testcmdtoken name $x] \
         [rename test_ns_basic::test_ns_basic2::p q] \
         [testcmdtoken name $x]
} {{p ::test_ns_basic::test_ns_basic2::p} {} {q ::q}}
}

test basic-21.1 {Tcl_GetCommandName} {emptyTest} {
} {}

test basic-22.1 {Tcl_GetCommandFullName} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    namespace eval test_ns_basic1 {
        namespace export cmd*
        proc cmd1 {} {}
        proc cmd2 {} {}
    }
    namespace eval test_ns_basic2 {
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











             [namespace which -command q] \
             [namespace which -command p] \
             [namespace which -command cmd1] \
             [namespace which -command ::test_ns_basic2::cmd2]
    }
} {::foreach ::test_ns_basic3::q ::test_ns_basic3::p ::test_ns_basic3::cmd1 ::test_ns_basic2::cmd2}




test basic-10.1 {Tcl_DeleteCommandFromToken, invalidate all compiled code if cmd has compile proc} {
    catch {interp delete test_interp}
    catch {unset x}
    interp create test_interp
    interp eval test_interp {
        proc useSet {} {
            return [set a 123]
        }
    }
    set x [interp eval test_interp {useSet}]
    interp eval test_interp {
        rename set ""
        proc set {args} {
            return "set called with $args"
        }
    }
    list $x \
         [interp eval test_interp {useSet}] \
         [interp delete test_interp]
} {123 {set called with a 123} {}}
test basic-10.2 {Tcl_DeleteCommandFromToken, deleting commands changes command epoch} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename p ""}
    proc p {} {
        return "global p"
    }
    namespace eval test_ns_basic {
        proc p {} {
            return "namespace p"
        }
        proc callP {} {
            p
        }
    }
    list [test_ns_basic::callP] \
         [rename test_ns_basic::p ""] \
         [test_ns_basic::callP]
} {{namespace p} {} {global p}}
test basic-10.3 {Tcl_DeleteCommandFromToken, delete imported cmds that refer to a deleted cmd} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename p ""}
    namespace eval test_ns_basic {
        namespace export p
        proc p {} {return 42}
    }
    namespace eval test_ns_basic2 {
        namespace import ::test_ns_basic::*
        proc callP {} {
            p
        }
    }
    list [test_ns_basic2::callP] \
         [info commands test_ns_basic2::*] \
         [rename test_ns_basic::p ""] \
         [catch {test_ns_basic2::callP} msg] $msg \
         [info commands test_ns_basic2::*]
} {42 {::test_ns_basic2::callP ::test_ns_basic2::p} {} 1 {invalid command name "p"} ::test_ns_basic2::callP}
















































test basic-11.1 {TclObjInvoke, lookup of "unknown" command} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        proc unknown {args} {
            return "global unknown"
        }
        namespace eval test_ns_basic {
            proc unknown {args} {
                return "namespace unknown"
            }
        }
    }
    list [interp alias test_interp newAlias test_interp doesntExist] \
         [catch {interp eval test_interp {newAlias}} msg] $msg \
         [interp delete test_interp]
} {newAlias 0 {global unknown} {}}











test basic-12.1 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {



    testcmdtrace tracetest {set stuff [info tclversion]}
} {{info tclversion} {info tclversion} {set stuff [info tclversion]} {set stuff 8.0}}
test basic-12.2 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {
    testcmdtrace deletetest {set stuff [info tclversion]}
} 8.0
























catch {eval namespace delete [namespace children :: test_ns_*]}
catch {namespace delete george}
catch {interp delete test_interp}
catch {rename p ""}
catch {rename q ""}
catch {rename cmd ""}
catch {rename value:at: ""}
catch {unset x}

set x 0
unset x


















>
>
>
|



















|

















|



















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


















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

|
|

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








>
|
|
>
>
>
>
>
>
>
>
>
>
>
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
             [namespace which -command q] \
             [namespace which -command p] \
             [namespace which -command cmd1] \
             [namespace which -command ::test_ns_basic2::cmd2]
    }
} {::foreach ::test_ns_basic3::q ::test_ns_basic3::p ::test_ns_basic3::cmd1 ::test_ns_basic2::cmd2}

test basic-23.1 {Tcl_DeleteCommand} {emptyTest} {
} {}

test basic-24.1 {Tcl_DeleteCommandFromToken, invalidate all compiled code if cmd has compile proc} {
    catch {interp delete test_interp}
    catch {unset x}
    interp create test_interp
    interp eval test_interp {
        proc useSet {} {
            return [set a 123]
        }
    }
    set x [interp eval test_interp {useSet}]
    interp eval test_interp {
        rename set ""
        proc set {args} {
            return "set called with $args"
        }
    }
    list $x \
         [interp eval test_interp {useSet}] \
         [interp delete test_interp]
} {123 {set called with a 123} {}}
test basic-24.2 {Tcl_DeleteCommandFromToken, deleting commands changes command epoch} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename p ""}
    proc p {} {
        return "global p"
    }
    namespace eval test_ns_basic {
        proc p {} {
            return "namespace p"
        }
        proc callP {} {
            p
        }
    }
    list [test_ns_basic::callP] \
         [rename test_ns_basic::p ""] \
         [test_ns_basic::callP]
} {{namespace p} {} {global p}}
test basic-24.3 {Tcl_DeleteCommandFromToken, delete imported cmds that refer to a deleted cmd} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename p ""}
    namespace eval test_ns_basic {
        namespace export p
        proc p {} {return 42}
    }
    namespace eval test_ns_basic2 {
        namespace import ::test_ns_basic::*
        proc callP {} {
            p
        }
    }
    list [test_ns_basic2::callP] \
         [info commands test_ns_basic2::*] \
         [rename test_ns_basic::p ""] \
         [catch {test_ns_basic2::callP} msg] $msg \
         [info commands test_ns_basic2::*]
} {42 {::test_ns_basic2::callP ::test_ns_basic2::p} {} 1 {invalid command name "p"} ::test_ns_basic2::callP}

test basic-25.1 {TclCleanupCommand} {emptyTest} {
} {}

test basic-26.1 {Tcl_EvalObj: preserve object while evaling it} {
    # If object isn't preserved, errorInfo would be set to
    # "foo\n    while executing\n\"garbage bytes\"" because the object's
    # string would have been freed, leaving garbage bytes for the error
    # message.

    proc bgerror {args} {set ::x $::errorInfo}
    set f [open test1 w]
    fileevent $f writable "fileevent $f writable {}; error foo"
    set x {}
    vwait x
    close $f
    file delete test1
    rename bgerror {}
    set x
} "foo\n    while executing\n\"error foo\""

test basic-27.1 {Tcl_ExprLong} {emptyTest} {
} {}

test basic-28.1 {Tcl_ExprDouble} {emptyTest} {
} {}

test basic-29.1 {Tcl_ExprBoolean} {emptyTest} {
} {}

test basic-30.1 {Tcl_ExprLongObj} {emptyTest} {
} {}

test basic-31.1 {Tcl_ExprDoubleObj} {emptyTest} {
} {}

test basic-32.1 {Tcl_ExprBooleanObj} {emptyTest} {
} {}

test basic-33.1 {TclInvoke} {emptyTest} {
} {}

test basic-34.1 {TclGlobalInvoke} {emptyTest} {
} {}

test basic-35.1 {TclObjInvokeGlobal} {emptyTest} {
} {}

test basic-36.1 {TclObjInvoke, lookup of "unknown" command} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {interp delete test_interp}
    interp create test_interp
    interp eval test_interp {
        proc unknown {args} {
            return "global unknown"
        }
        namespace eval test_ns_basic {
            proc unknown {args} {
                return "namespace unknown"
            }
        }
    }
    list [interp alias test_interp newAlias test_interp doesntExist] \
         [catch {interp eval test_interp {newAlias}} msg] $msg \
         [interp delete test_interp]
} {newAlias 0 {global unknown} {}}

test basic-37.1 {Tcl_ExprString: see expr.test} {emptyTest} {
} {}

test basic-38.1 {Tcl_ExprObj} {emptyTest} {
} {}

if {[info commands testcmdtrace] == {}} {
    puts "This application hasn't been compiled with the \"testcmdtrace\""
    puts "command, so I can't test Tcl_CreateTrace."
} else {
test basic-39.1 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {
    testcmdtrace tracetest {set stuff [expr 14 + 16]}
} {{expr 14 + 16} {expr 14 + 16} {set stuff [expr 14 + 16]} {set stuff 30}}
test basic-39.2 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {
    testcmdtrace tracetest {set stuff [info tclversion]}
} {{info tclversion} {info tclversion} {set stuff [info tclversion]} {set stuff 8.1}}
test basic-39.3 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {
    testcmdtrace deletetest {set stuff [info tclversion]}
} 8.1
}

test basic-40.1 {Tcl_DeleteTrace} {emptyTest} {
} {}

test basic-41.1 {Tcl_AddErrorInfo} {emptyTest} {
} {}

test basic-42.1 {Tcl_AddObjErrorInfo} {emptyTest} {
} {}

test basic-43.1 {Tcl_VarEval} {emptyTest} {
} {}

test basic-44.1 {Tcl_GlobalEval} {emptyTest} {
} {}

test basic-45.1 {Tcl_SetRecursionLimit: see interp.test} {emptyTest} {
} {}

test basic-46.1 {Tcl_AllowExceptions} {emptyTest} {
} {}

# cleanup
catch {eval namespace delete [namespace children :: test_ns_*]}
catch {namespace delete george}
catch {interp delete test_interp}
catch {rename p ""}
catch {rename q ""}
catch {rename cmd ""}
catch {rename value:at: ""}
catch {unset x}
::tcltest::cleanupTests
return












Changes to tests/binary.test.

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
# This file tests the tclBinary.c file and the "binary" Tcl command. 
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) binary.test 1.13 97/09/11 18:50:30



if {[string compare test [info procs test]] == 1} then {source defs}

test binary-1.1 {Tcl_BinaryObjCmd: bad args} {
    list [catch {binary} msg] $msg
} {1 {wrong # args: should be "binary option ?arg arg ...?"}}
test binary-1.2 {Tcl_BinaryObjCmd: bad args} {
    list [catch {binary foo} msg] $msg
} {1 {bad option "foo": must be format, or scan}}

test binary-1.3 {Tcl_BinaryObjCmd: format error} {
    list [catch {binary f} msg] $msg
} {1 {wrong # args: should be "binary format formatString ?arg arg ...?"}}
test binary-1.4 {Tcl_BinaryObjCmd: format} {
    binary format ""
} {}







>




>
|
>
>
|
<






|







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
# This file tests the tclBinary.c file and the "binary" Tcl command. 
#
# 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: binary.test,v 1.1.2.5 1999/03/24 02:48:57 hershey Exp $

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


test binary-1.1 {Tcl_BinaryObjCmd: bad args} {
    list [catch {binary} msg] $msg
} {1 {wrong # args: should be "binary option ?arg arg ...?"}}
test binary-1.2 {Tcl_BinaryObjCmd: bad args} {
    list [catch {binary foo} msg] $msg
} {1 {bad option "foo": must be format or scan}}

test binary-1.3 {Tcl_BinaryObjCmd: format error} {
    list [catch {binary f} msg] $msg
} {1 {wrong # args: should be "binary format formatString ?arg arg ...?"}}
test binary-1.4 {Tcl_BinaryObjCmd: format} {
    binary format ""
} {}
1437
1438
1439
1440
1441
1442
1443
















    catch {unset arg1; unset arg2}
    list [binary scan \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a c1d1 arg1 arg2] $arg1 $arg2
} {2 1 1.6}
test binary-41.8 {ScanNumber: word alignment} {nonPortable pcOnly} {
    catch {unset arg1; unset arg2}
    list [binary scan \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f c1d1 arg1 arg2] $arg1 $arg2
} {2 1 1.6}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
    catch {unset arg1; unset arg2}
    list [binary scan \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a c1d1 arg1 arg2] $arg1 $arg2
} {2 1 1.6}
test binary-41.8 {ScanNumber: word alignment} {nonPortable pcOnly} {
    catch {unset arg1; unset arg2}
    list [binary scan \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f c1d1 arg1 arg2] $arg1 $arg2
} {2 1 1.6}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/case.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  case
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) case.test 1.13 96/02/16 08:55:41



if {[string compare test [info procs test]] == 1} then {source defs}

test case-1.1 {simple pattern} {
    case a in a {format 1} b {format 2} c {format 3} default {format 4}
} 1
test case-1.2 {simple pattern} {
    case b a {format 1} b {format 2} c {format 3} default {format 4}
} 2








>




>
|
>
>
|
<







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
# Commands covered:  case
#
# 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: case.test,v 1.1.2.5 1999/03/24 02:48:58 hershey Exp $

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


test case-1.1 {simple pattern} {
    case a in a {format 1} b {format 2} c {format 3} default {format 4}
} 1
test case-1.2 {simple pattern} {
    case b a {format 1} b {format 2} c {format 3} default {format 4}
} 2
77
78
79
80
81
82
83
















	b {format 2}
	default {format 6}
    }
} {2}
test case-3.3 {single-argument form for pattern/command pairs} {
    list [catch {case z in {a 2 b}} msg] $msg
} {1 {extra case pattern with no body}}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
	b {format 2}
	default {format 6}
    }
} {2}
test case-3.3 {single-argument form for pattern/command pairs} {
    list [catch {case z in {a 2 b}} msg] $msg
} {1 {extra case pattern with no body}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/clock.test.

1
2
3
4
5
6
7

8
9
10
11

12


13
14
15
16
17
18
19
20
21
# Commands covered:  clock
#
# 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) 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.
#

# SCCS: @(#) clock.test 1.17 97/11/24 15:05:38



if {[string compare test [info procs test]] == 1} then {source defs}

test clock-1.1 {clock tests} {
    list [catch {clock} msg] $msg
} {1 {wrong # args: should be "clock option ?arg ...?"}}
test clock-1.2 {clock tests} {
    list [catch {clock foo} msg] $msg
} {1 {bad option "foo": must be clicks, format, scan, or seconds}}






|
>




>
|
>
>
|
<







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

18
19
20
21
22
23
24
# Commands covered:  clock
#
# 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) 1995-1998 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: clock.test,v 1.1.2.5 1999/03/24 02:48:58 hershey Exp $

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


test clock-1.1 {clock tests} {
    list [catch {clock} msg] $msg
} {1 {wrong # args: should be "clock option ?arg ...?"}}
test clock-1.2 {clock tests} {
    list [catch {clock foo} msg] $msg
} {1 {bad option "foo": must be clicks, format, scan, or seconds}}
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

# clock format
test clock-3.1 {clock format tests} {unixOnly} {
    set clockval 657687766
    clock format $clockval -format {%a %b %d %I:%M:%S %p %Y} -gmt true
} {Sun Nov 04 03:02:46 AM 1990}
test clock-3.2 {clock format tests} {































    list [catch {clock format} msg] $msg
} {1 {wrong # args: should be "clock format clockval ?-format string? ?-gmt boolean?"}}
test clock-3.3 {clock format tests} {
    list [catch {clock format foo} msg] $msg
} {1 {expected integer but got "foo"}}
test clock-3.4 {clock format tests} {unixOrPc} {
    set clockval 657687766
    clock format $clockval -format "%a %b %d %I:%M:%S %p %Y" -gmt true
} "Sun Nov 04 03:02:46 AM 1990"
test clock-3.5 {clock format tests} {
    list [catch {clock format a b c d e g} msg] $msg
} {1 {wrong # args: should be "clock format clockval ?-format string? ?-gmt boolean?"}}
test clock-3.6 {clock format tests} {unixOrPc nonPortable} {
    set clockval -1
    clock format $clockval -format "%a %b %d %I:%M:%S %p %Y" -gmt true
} "Wed Dec 31 11:59:59 PM 1969"
test clock-3.7 {clock format tests} {
    list [catch {clock format 123 -bad arg} msg] $msg
} {1 {bad switch "-bad": must be -format, or -gmt}}
test clock-3.8 {clock format tests} {
    clock format 123 -format "x"
} x
test clock-3.9 {clock format tests} {
    clock format 123 -format ""
} ""

# clock scan
test clock-4.1 {clock scan tests} {
    list [catch {clock scan} msg] $msg
} {1 {wrong # args: should be "clock scan dateString ?-base clockValue? ?-gmt boolean?"}}







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


|


|



|


|



|

|
|


|







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

# clock format
test clock-3.1 {clock format tests} {unixOnly} {
    set clockval 657687766
    clock format $clockval -format {%a %b %d %I:%M:%S %p %Y} -gmt true
} {Sun Nov 04 03:02:46 AM 1990}
test clock-3.2 {clock format tests} {
    # TCL_USE_TIMEZONE_VAR

    catch {set oldtz $env(TZ)}
    set env(TZ) PST
    set x {}
    append x [clock format 863800000 -format %Z -gmt 1]
    append x [set env(TZ)]
    catch {unset env(TZ); set env(TZ) $oldtz}
    set x
} {GMTPST}
test clock-3.3 {clock format tests} {
    # tzset() under Borland doesn't seem to set up tzname[] for local 
    # timezone, which caused "clock format" to think that %Z was an invalid
    # string.  Don't care about answer, just that test runs w/o error.

    clock format 863800000 -format %Z
    set x {}
} {}
test clock-3.4 {clock format tests} {
    # tzset() under Borland doesn't seem to set up tzname[] for gmt timezone.
    # tzset() under MSVC has the following weird observed behavior:
    #	 First time we call "clock format [clock seconds] -format %Z -gmt 1"
    #	 we get "GMT", but on all subsequent calls we get the current time 
    #	 zone string, even though env(TZ) is GMT and the variable _timezone 
    #    is 0.

    set x {}
    append x [clock format 863800000 -format %Z -gmt 1]
    append x [clock format 863800000 -format %Z -gmt 1]
} {GMTGMT}
test clock-3.5 {clock format tests} {
    list [catch {clock format} msg] $msg
} {1 {wrong # args: should be "clock format clockval ?-format string? ?-gmt boolean?"}}
test clock-3.6 {clock format tests} {
    list [catch {clock format foo} msg] $msg
} {1 {expected integer but got "foo"}}
test clock-3.7 {clock format tests} {unixOrPc} {
    set clockval 657687766
    clock format $clockval -format "%a %b %d %I:%M:%S %p %Y" -gmt true
} "Sun Nov 04 03:02:46 AM 1990"
test clock-3.8 {clock format tests} {
    list [catch {clock format a b c d e g} msg] $msg
} {1 {wrong # args: should be "clock format clockval ?-format string? ?-gmt boolean?"}}
test clock-3.9 {clock format tests} {unixOrPc nonPortable} {
    set clockval -1
    clock format $clockval -format "%a %b %d %I:%M:%S %p %Y" -gmt true
} "Wed Dec 31 11:59:59 PM 1969"
test clock-3.10 {clock format tests} {
    list [catch {clock format 123 -bad arg} msg] $msg
} {1 {bad switch "-bad": must be -format or -gmt}}
test clock-3.11 {clock format tests} {
    clock format 123 -format "x"
} x
test clock-3.12 {clock format tests} {
    clock format 123 -format ""
} ""

# clock scan
test clock-4.1 {clock scan tests} {
    list [catch {clock scan} msg] $msg
} {1 {wrong # args: should be "clock scan dateString ?-base clockValue? ?-gmt boolean?"}}
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
} {Oct 23,1992 15:00 GMT}
test clock-4.8 {clock scan tests} {
    set time [clock scan "Oct 23,1992 15:00" -gmt true]
    clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
} {Oct 23,1992 15:00 GMT}
test clock-4.9 {clock scan tests} {
    list [catch {clock scan "Jan 12" -bad arg} msg] $msg
} {1 {bad switch "-bad": must be -base, or -gmt}}
# The following two two tests test the two year date policy
test clock-4.10 {clock scan tests} {
    set time [clock scan "1/1/71" -gmt true]
    clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
} {Jan 01,1971 00:00 GMT}
test clock-4.11 {clock scan tests} {
    set time [clock scan "1/1/37" -gmt true]







|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
} {Oct 23,1992 15:00 GMT}
test clock-4.8 {clock scan tests} {
    set time [clock scan "Oct 23,1992 15:00" -gmt true]
    clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
} {Oct 23,1992 15:00 GMT}
test clock-4.9 {clock scan tests} {
    list [catch {clock scan "Jan 12" -bad arg} msg] $msg
} {1 {bad switch "-bad": must be -base or -gmt}}
# The following two two tests test the two year date policy
test clock-4.10 {clock scan tests} {
    set time [clock scan "1/1/71" -gmt true]
    clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
} {Jan 01,1971 00:00 GMT}
test clock-4.11 {clock scan tests} {
    set time [clock scan "1/1/37" -gmt true]
169
170
171
172
173
174
175
















    set time [clock scan "March 1, 2000" -gmt true]
    clock format $time -format %j -gmt true
} {061}
test clock-6.11 {clock roll over dates} {
    set time [clock scan "March 1, 2001" -gmt true]
    clock format $time -format %j -gmt true
} {060}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
    set time [clock scan "March 1, 2000" -gmt true]
    clock format $time -format %j -gmt true
} {061}
test clock-6.11 {clock roll over dates} {
    set time [clock scan "March 1, 2001" -gmt true]
    clock format $time -format %j -gmt true
} {060}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/cmdAH.test.

1
2
3
4
5
6
7

8
9
10
11

12


13
14
15
16

17
18









19



































































































































20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61




62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851

852
853
854







855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925


926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947




948
949
950
951
952
953
954
955
956
957
958
959
960

961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986

987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195




















































1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
1255

1256















# The file tests the tclCmdAH.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) 1996-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.
#

# SCCS: @(#) cmdAH.test 1.35 97/07/22 14:07:43



if {[string compare test [info procs test]] == 1} then {source defs}

global env

set platform [testgetplatform]










test cmdAH-1.1 {Tcl_FileObjCmd} {



































































































































    list [catch file msg] $msg
} {1 {wrong # args: should be "file option ?arg ...?"}}
test cmdAH-1.2 {Tcl_FileObjCmd} {
    list [catch {file x} msg] $msg
} {1 {bad option "x": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-1.3 {Tcl_FileObjCmd} {
    list [catch {file atime} msg] $msg
} {1 {wrong # args: should be "file atime name ?arg ...?"}}


#volume

test cmdAH-2.1 {Tcl_FileObjCmd: volumes} {
    list [catch {file volumes x} msg] $msg	
} {1 {wrong # args: should be "file volumes"}}
test cmdAH-2.2 {Tcl_FileObjCmd: volumes} {
	set volumeList [file volumes]
	if { [llength $volumeList] == 0 } {
		set result 0
	} else {
		set result 1
	}	
} {1}
test cmdAH-2.3 {Tcl_FileObjCmd: volumes} {macOrUnix} {
    set volumeList [file volumes]
    catch [list glob -nocomplain [lindex $volumeList 0]*]
} {0}
test cmdAH-2.4 {Tcl_FileObjCmd: volumes} {pcOnly} {
    set volumeList [file volumes]
    list [catch {lsearch $volumeList "c:/"} element] [expr $element != -1] [catch {list glob -nocomplain [lindex $volumeList $element]*}]
} {0 1 0}

# attributes

test cmdAH-3.1 {Tcl_FileObjCmd - file attrs} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file}] [file delete -force foo.file]
} {0 {}}

# dirname





test cmdAH-4.1 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname a b} msg] $msg
} {1 {wrong # args: should be "file dirname name"}}
test cmdAH-4.2 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname /a/b
} /a
test cmdAH-4.3 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname {}
} .
test cmdAH-4.4 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    file dirname {}
} :
test cmdAH-4.5 {Tcl_FileObjCmd: dirname} {
    testsetplatform win
    file dirname {}
} .
test cmdAH-4.6 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname .def
} .
test cmdAH-4.7 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    file dirname a
} :
test cmdAH-4.8 {Tcl_FileObjCmd: dirname} {
    testsetplatform win
    file dirname a
} .
test cmdAH-4.9 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname a/b/c.d
} a/b
test cmdAH-4.10 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname a/b.c/d
} a/b.c
test cmdAH-4.11 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname /.
} /
test cmdAH-4.12 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname /} msg] $msg
} {0 /}
test cmdAH-4.13 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname /foo} msg] $msg
} {0 /}
test cmdAH-4.14 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname //foo} msg] $msg
} {0 /}
test cmdAH-4.15 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname //foo/bar} msg] $msg
} {0 /foo}
test cmdAH-4.16 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname {//foo\/bar/baz}} msg] $msg
} {0 {/foo\/bar}}
test cmdAH-4.17 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname {//foo\/bar/baz/blat}} msg] $msg
} {0 {/foo\/bar/baz}}
test cmdAH-4.18 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname /foo//} msg] $msg
} {0 /}
test cmdAH-4.19 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname ./a} msg] $msg
} {0 .}
test cmdAH-4.20 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname a/.a} msg] $msg
} {0 a}
test cmdAH-4.21 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname c:foo} msg] $msg
} {0 c:}
test cmdAH-4.22 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname c:} msg] $msg
} {0 c:}
test cmdAH-4.23 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname c:/} msg] $msg
} {0 c:/}
test cmdAH-4.24 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname {c:\foo}} msg] $msg
} {0 c:/}
test cmdAH-4.25 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname {//foo/bar/baz}} msg] $msg
} {0 //foo/bar}
test cmdAH-4.26 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname {//foo/bar}} msg] $msg
} {0 //foo/bar}
test cmdAH-4.27 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname :} msg] $msg
} {0 :}
test cmdAH-4.28 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname :Foo} msg] $msg
} {0 :}
test cmdAH-4.29 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname Foo:} msg] $msg
} {0 Foo:}
test cmdAH-4.30 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname Foo:bar} msg] $msg
} {0 Foo:}
test cmdAH-4.31 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname :Foo:bar} msg] $msg
} {0 :Foo}
test cmdAH-4.32 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname ::} msg] $msg
} {0 :}
test cmdAH-4.33 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname :::} msg] $msg
} {0 ::}
test cmdAH-4.34 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname /foo/bar/} msg] $msg
} {0 foo:}
test cmdAH-4.35 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname /foo/bar} msg] $msg
} {0 foo:}
test cmdAH-4.36 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname /foo} msg] $msg
} {0 foo:}
test cmdAH-4.37 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname foo} msg] $msg
} {0 :}
test cmdAH-4.38 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname ~/foo} msg] $msg
} {0 ~}
test cmdAH-4.39 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname ~bar/foo} msg] $msg
} {0 ~bar}
test cmdAH-4.40 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname ~bar/foo} msg] $msg
} {0 ~bar:}
test cmdAH-4.41 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname ~/foo} msg] $msg
} {0 ~:}
test cmdAH-4.42 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname ~:baz} msg] $msg
} {0 ~:}
test cmdAH-4.43 {Tcl_FileObjCmd: dirname} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform unix
    set result [list [catch {file dirname ~} msg] $msg]
    set env(HOME) $temp
    set result
} {0 /home}
test cmdAH-4.44 {Tcl_FileObjCmd: dirname} {
    global env
    set temp $env(HOME)
    set env(HOME) "~"
    testsetplatform unix
    set result [list [catch {file dirname ~} msg] $msg]
    set env(HOME) $temp
    set result
} {0 ~}
test cmdAH-4.45 {Tcl_FileObjCmd: dirname} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform windows
    set result [list [catch {file dirname ~} msg] $msg]
    set env(HOME) $temp
    set result
} {0 /home}
test cmdAH-4.46 {Tcl_FileObjCmd: dirname} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform mac
    set result [list [catch {file dirname ~} msg] $msg]
    set env(HOME) $temp
    set result
} {0 home:}

# tail

test cmdAH-5.1 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    list [catch {file tail a b} msg] $msg
} {1 {wrong # args: should be "file tail name"}}
test cmdAH-5.2 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail /a/b
} b
test cmdAH-5.3 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail {}
} {}
test cmdAH-5.4 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail {}
} {}
test cmdAH-5.5 {Tcl_FileObjCmd: tail} {
    testsetplatform win
    file tail {}
} {}
test cmdAH-5.6 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail .def
} .def
test cmdAH-5.7 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail a
} a
test cmdAH-5.8 {Tcl_FileObjCmd: tail} {
    testsetplatform win
    file tail a
} a
test cmdAH-5.9 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file ta a/b/c.d
} c.d
test cmdAH-5.10 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail a/b.c/d
} d
test cmdAH-5.11 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail /.
} .
test cmdAH-5.12 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail /
} {}
test cmdAH-5.13 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail /foo
} foo
test cmdAH-5.14 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail //foo
} foo
test cmdAH-5.15 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail //foo/bar
} bar
test cmdAH-5.16 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail {//foo\/bar/baz}
} baz
test cmdAH-5.17 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail {//foo\/bar/baz/blat}
} blat
test cmdAH-5.18 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail /foo//
} foo
test cmdAH-5.19 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail ./a
} a
test cmdAH-5.20 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail a/.a
} .a
test cmdAH-5.21 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:foo
} foo
test cmdAH-5.22 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:
} {}
test cmdAH-5.23 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:/
} {}
test cmdAH-5.24 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail {c:\foo}
} foo
test cmdAH-5.25 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail {//foo/bar/baz}
} baz
test cmdAH-5.26 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail {//foo/bar}
} {}
test cmdAH-5.27 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail :
} :
test cmdAH-5.28 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail :Foo
} Foo
test cmdAH-5.29 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail Foo:
} {}
test cmdAH-5.30 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail Foo:bar
} bar
test cmdAH-5.31 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail :Foo:bar
} bar
test cmdAH-5.32 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail ::
} ::
test cmdAH-5.33 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail :::
} ::
test cmdAH-5.34 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail /foo/bar/
} bar
test cmdAH-5.35 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail /foo/bar
} bar
test cmdAH-5.36 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail /foo
} {}
test cmdAH-5.37 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail foo
} foo
test cmdAH-5.38 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail ~:foo
} foo
test cmdAH-5.39 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail ~bar:foo
} foo
test cmdAH-5.40 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail ~bar/foo
} foo
test cmdAH-5.41 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail ~/foo
} foo
test cmdAH-5.42 {Tcl_FileObjCmd: tail} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform unix
    set result [file tail ~]
    set env(HOME) $temp
    set result
} test
test cmdAH-5.43 {Tcl_FileObjCmd: tail} {
    global env
    set temp $env(HOME)
    set env(HOME) "~"
    testsetplatform unix
    set result [file tail ~]
    set env(HOME) $temp
    set result
} {}
test cmdAH-5.44 {Tcl_FileObjCmd: tail} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform windows
    set result [file tail ~]
    set env(HOME) $temp
    set result
} test
test cmdAH-5.45 {Tcl_FileObjCmd: tail} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform mac
    set result [file tail ~]
    set env(HOME) $temp
    set result
} test
test cmdAH-5.46 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail {f.oo\bar/baz.bat}
} baz.bat
test cmdAH-5.47 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:foo
} foo
test cmdAH-5.48 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:
} {}
test cmdAH-5.49 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:/foo
} foo
test cmdAH-5.50 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail {c:/foo\bar}
} bar
test cmdAH-5.51 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail {foo\bar}
} bar

# rootname

test cmdAH-6.1 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    list [catch {file rootname a b} msg] $msg
} {1 {wrong # args: should be "file rootname name"}}
test cmdAH-6.2 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname {}
} {}
test cmdAH-6.3 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file ro foo
} foo
test cmdAH-6.4 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname foo.
} foo
test cmdAH-6.5 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname .foo
} {}
test cmdAH-6.6 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname abc.def
} abc
test cmdAH-6.7 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname abc.def.ghi
} abc.def
test cmdAH-6.8 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname a/b/c.d
} a/b/c
test cmdAH-6.9 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname a/b.c/d
} a/b.c/d
test cmdAH-6.10 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname a/b.c/
} a/b.c/
test cmdAH-6.11 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file ro foo
} foo
test cmdAH-6.12 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname {}
} {}
test cmdAH-6.13 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname foo.
} foo
test cmdAH-6.14 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname .foo
} {}
test cmdAH-6.15 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname abc.def
} abc
test cmdAH-6.16 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname abc.def.ghi
} abc.def
test cmdAH-6.17 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname a:b:c.d
} a:b:c
test cmdAH-6.18 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname a:b.c:d
} a:b.c:d
test cmdAH-6.19 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname a/b/c.d
} a/b/c
test cmdAH-6.20 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname a/b.c/d
} a/b.c/d
test cmdAH-6.21 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname /a.b
} /a
test cmdAH-6.22 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname foo.c:
} foo.c:
test cmdAH-6.23 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname {}
} {}
test cmdAH-6.24 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file ro foo
} foo
test cmdAH-6.25 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname foo.
} foo
test cmdAH-6.26 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname .foo
} {}
test cmdAH-6.27 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname abc.def
} abc
test cmdAH-6.28 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname abc.def.ghi
} abc.def
test cmdAH-6.29 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a/b/c.d
} a/b/c
test cmdAH-6.30 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a/b.c/d
} a/b.c/d
test cmdAH-6.31 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a\\b.c\\
} a\\b.c\\
test cmdAH-6.32 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a\\b\\c.d
} a\\b\\c
test cmdAH-6.33 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a\\b.c\\d
} a\\b.c\\d
test cmdAH-6.34 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a\\b.c\\
} a\\b.c\\
set num 35
foreach outer { {} a .a a. a.a } {
  foreach inner { {} a .a a. a.a } {
    set thing [format %s/%s $outer $inner]
;   test cmdAH-6.$num {Tcl_FileObjCmd: rootname and extension options} {
	testsetplatform unix
	format %s%s [file rootname $thing] [file ext $thing]
    } $thing
    set num [expr $num+1]
  }
}

# extension

test cmdAH-7.1 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    list [catch {file extension a b} msg] $msg
} {1 {wrong # args: should be "file extension name"}}
test cmdAH-7.2 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension {}
} {}
test cmdAH-7.3 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file ext foo
} {}
test cmdAH-7.4 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension foo.
} .
test cmdAH-7.5 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension .foo
} .foo
test cmdAH-7.6 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension abc.def
} .def
test cmdAH-7.7 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension abc.def.ghi
} .ghi
test cmdAH-7.8 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension a/b/c.d
} .d
test cmdAH-7.9 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension a/b.c/d
} {}
test cmdAH-7.10 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension a/b.c/
} {}
test cmdAH-7.11 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file ext foo
} {}
test cmdAH-7.12 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension {}
} {}
test cmdAH-7.13 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension foo.
} .
test cmdAH-7.14 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension .foo
} .foo
test cmdAH-7.15 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension abc.def
} .def
test cmdAH-7.16 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension abc.def.ghi
} .ghi
test cmdAH-7.17 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension a:b:c.d
} .d
test cmdAH-7.18 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension a:b.c:d
} {}
test cmdAH-7.19 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension a/b/c.d
} .d
test cmdAH-7.20 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension a/b.c/d
} {}
test cmdAH-7.21 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension /a.b
} .b
test cmdAH-7.22 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension foo.c:
} {}
test cmdAH-7.23 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension {}
} {}
test cmdAH-7.24 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file ext foo
} {}
test cmdAH-7.25 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension foo.
} .
test cmdAH-7.26 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension .foo
} .foo
test cmdAH-7.27 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension abc.def
} .def
test cmdAH-7.28 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension abc.def.ghi
} .ghi
test cmdAH-7.29 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a/b/c.d
} .d
test cmdAH-7.30 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a/b.c/d
} {}
test cmdAH-7.31 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a\\b.c\\
} {}
test cmdAH-7.32 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a\\b\\c.d
} .d
test cmdAH-7.33 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a\\b.c\\d
} {}
test cmdAH-7.34 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a\\b.c\\
} {}
set num 35
foreach value {a..b a...b a.c..b ..b} result {..b ...b ..b ..b} {
    foreach p {unix mac windows} {
;	test cmdAH-7.$num {Tcl_FileObjCmd: extension} "
	    testsetplatform $p
	    file extension $value
	" $result
	incr num
    }
}

# pathtype

test cmdAH-8.1 {Tcl_FileObjCmd: pathtype} {
    testsetplatform unix
    list [catch {file pathtype a b} msg] $msg
} {1 {wrong # args: should be "file pathtype name"}}
test cmdAH-8.2 {Tcl_FileObjCmd: pathtype} {
    testsetplatform unix
    file pathtype /a
} absolute
test cmdAH-8.3 {Tcl_FileObjCmd: pathtype} {
    testsetplatform unix
    file p a
} relative
test cmdAH-8.4 {Tcl_FileObjCmd: pathtype} {
    testsetplatform windows
    file pathtype c:a
} volumerelative

# split

test cmdAH-9.1 {Tcl_FileObjCmd: split} {
    testsetplatform unix
    list [catch {file split a b} msg] $msg
} {1 {wrong # args: should be "file split name"}}
test cmdAH-9.2 {Tcl_FileObjCmd: split} {
    testsetplatform unix
    file split a
} a
test cmdAH-9.3 {Tcl_FileObjCmd: split} {
    testsetplatform unix
    file split a/b
} {a b}

# join

test cmdAH-10.1 {Tcl_FileObjCmd: join} {
    testsetplatform unix
    file join a
} a
test cmdAH-10.2 {Tcl_FileObjCmd: join} {
    testsetplatform unix
    file join a b
} a/b
test cmdAH-10.3 {Tcl_FileObjCmd: join} {
    testsetplatform unix
    file join a b c d
} a/b/c/d

# error handling of Tcl_TranslateFileName

test cmdAH-11.1 {Tcl_FileObjCmd} {
    testsetplatform unix
    list [catch {file atime ~_bad_user} msg] $msg
} {1 {user "_bad_user" doesn't exist}}

testsetplatform $platform
makeFile abcde gorp.file
makeDirectory dir.file


# readable








test cmdAH-12.1 {Tcl_FileObjCmd: readable} {
    list [catch {file readable a b} msg] $msg
} {1 {wrong # args: should be "file readable name"}}
testchmod 444 gorp.file
test cmdAH-12.2 {Tcl_FileObjCmd: readable} {
    file readable gorp.file
} 1
testchmod 333 gorp.file
test cmdAH-12.3 {Tcl_FileObjCmd: readable} {unixOnly && !root} {
    file reada gorp.file
} 0

# writable

test cmdAH-13.1 {Tcl_FileObjCmd: writable} {
    list [catch {file writable a b} msg] $msg
} {1 {wrong # args: should be "file writable name"}}
testchmod 555 gorp.file
test cmdAH-13.2 {Tcl_FileObjCmd: writable} {!root} {
    file writable gorp.file
} 0
testchmod 222 gorp.file
test cmdAH-13.3 {Tcl_FileObjCmd: writable} {
    file writable gorp.file
} 1

# executable

file delete -force dir.file gorp.file
file mkdir dir.file
makeFile abcde gorp.file

test cmdAH-14.1 {Tcl_FileObjCmd: executable} {
    list [catch {file executable a b} msg] $msg
} {1 {wrong # args: should be "file executable name"}}
test cmdAH-14.2 {Tcl_FileObjCmd: executable} {
    file executable gorp.file
} 0
test cmdAH-14.3 {Tcl_FileObjCmd: executable} {unix} {
    # Only on unix will setting the execute bit on a regular file
    # cause that file to be executable.   
    
    testchmod 775 gorp.file
    file exe gorp.file
} 1

test cmdAH-14.4 {Tcl_FileObjCmd: executable} {mac} {
    # On mac, the only executable files are of type APPL.

    set x [file exe gorp.file]    
    file attrib gorp.file -type APPL
    lappend x [file exe gorp.file]
} {0 1}
test cmdAH-14.5 {Tcl_FileObjCmd: executable} {pc} {
    # On pc, must be a .exe, .com, etc.
    
    set x [file exe gorp.file]
    makeFile foo gorp.exe
    lappend x [file exe gorp.exe]
    file delete gorp.exe
    set x
} {0 1}
test cmdAH-14.6 {Tcl_FileObjCmd: executable} {
    # Directories are always executable.
    
    file exe dir.file
} 1

file delete -force dir.file  
file delete gorp.file
file delete link.file


# exists

test cmdAH-15.1 {Tcl_FileObjCmd: exists} {
    list [catch {file exists a b} msg] $msg
} {1 {wrong # args: should be "file exists name"}}
test cmdAH-15.2 {Tcl_FileObjCmd: exists} {file exists gorp.file} 0
test cmdAH-15.3 {Tcl_FileObjCmd: exists} {
    file exists [file join dir.file gorp.file]
} 0
catch {
    makeFile abcde gorp.file
    makeDirectory dir.file
    makeFile 12345 [file join dir.file gorp.file]
}
test cmdAH-15.4 {Tcl_FileObjCmd: exists} {
    file exists gorp.file
} 1
test cmdAH-15.5 {Tcl_FileObjCmd: exists} {
    file exists [file join dir.file gorp.file]
} 1

# nativename




test cmdAH-15.6 {Tcl_FileObjCmd: nativename} {
    testsetplatform unix
    list [catch {file nativename a/b} msg] $msg [testsetplatform $platform]
} {0 a/b {}}
test cmdAH-15.7 {Tcl_FileObjCmd: nativename} {
    testsetplatform windows
    list [catch {file nativename a/b} msg] $msg [testsetplatform $platform]
} {0 {a\b} {}}
test cmdAH-15.8 {Tcl_FileObjCmd: nativename} {
    testsetplatform mac
    list [catch {file nativename a/b} msg] $msg [testsetplatform $platform]
} {0 :a:b {}}


test cmdAH-15.9 {Tcl_FileObjCmd: ~ : exists} {
    file exists ~nOsUcHuSeR
} 0
test cmdAH-15.10 {Tcl_FileObjCmd: ~ : nativename} {
    # should probably be 0 in fact...
    catch {file nativename ~nOsUcHuSeR}
} 1

# The test below has to be done in /tmp rather than the current
# directory in order to guarantee (?) a local file system:  some
# NFS file systems won't do the stuff below correctly.

if {$tcl_platform(platform) == "unix"} {
    file delete /tmp/tcl.foo.dir/file
    removeDirectory /tmp/tcl.foo.dir
    makeDirectory /tmp/tcl.foo.dir
    makeFile 12345 /tmp/tcl.foo.dir/file
    exec chmod 000 /tmp/tcl.foo.dir
    if {$user != "root"} {
	test cmdAH-15.9 {Tcl_FileObjCmd: exists} {
	    file exists /tmp/tcl.foo.dir/file
	} 0
    }
    exec chmod 775 /tmp/tcl.foo.dir
    file delete /tmp/tcl.foo.dir/file
    removeDirectory /tmp/tcl.foo.dir

}

# Stat related commands

testsetplatform $platform
file delete gorp.file
makeFile "Test string" gorp.file
catch {exec chmod 765 gorp.file}

# atime

test cmdAH-16.1 {Tcl_FileObjCmd: atime} {
    list [catch {file atime a b} msg] $msg
} {1 {wrong # args: should be "file atime name"}}
test cmdAH-16.2 {Tcl_FileObjCmd: atime} {
    catch {unset stat}
    file stat gorp.file stat
    list [expr {[file mtime gorp.file] == $stat(mtime)}] \
	    [expr {[file atime gorp.file] == $stat(atime)}]
} {1 1}
test cmdAH-16.3 {Tcl_FileObjCmd: atime} {
    string tolower [list [catch {file atime _bogus_} msg] \
	    $msg $errorCode]
} {1 {couldn't stat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}

# isdirectory

test cmdAH-17.1 {Tcl_FileObjCmd: isdirectory} {
    list [catch {file isdirectory a b} msg] $msg
} {1 {wrong # args: should be "file isdirectory name"}}
test cmdAH-17.2 {Tcl_FileObjCmd: isdirectory} {
    file isdirectory gorp.file
} 0
test cmdAH-17.3 {Tcl_FileObjCmd: isdirectory} {
    file isd dir.file
} 1

# isfile

test cmdAH-18.1 {Tcl_FileObjCmd: isfile} {
    list [catch {file isfile a b} msg] $msg
} {1 {wrong # args: should be "file isfile name"}}
test cmdAH-18.2 {Tcl_FileObjCmd: isfile} {file isfile gorp.file} 1
test cmdAH-18.3 {Tcl_FileObjCmd: isfile} {file isfile dir.file} 0

# lstat and readlink:  don't run these tests everywhere, since not all
# sites will have symbolic links

catch {exec ln -s gorp.file link.file}
test cmdAH-19.1 {Tcl_FileObjCmd: lstat} {
    list [catch {file lstat a} msg] $msg
} {1 {wrong # args: should be "file lstat name varName"}}
test cmdAH-19.2 {Tcl_FileObjCmd: lstat} {
    list [catch {file lstat a b c} msg] $msg
} {1 {wrong # args: should be "file lstat name varName"}}
test cmdAH-19.3 {Tcl_FileObjCmd: lstat} {unixOnly nonPortable} {
    catch {unset stat}
    file lstat link.file stat
    lsort [array names stat]
} {atime ctime dev gid ino mode mtime nlink size type uid}
test cmdAH-19.4 {Tcl_FileObjCmd: lstat} {unixOnly nonPortable} {
    catch {unset stat}
    file lstat link.file stat
    list $stat(nlink) [expr $stat(mode)&0777] $stat(type)
} {1 511 link}
test cmdAH-19.5 {Tcl_FileObjCmd: lstat errors} {nonPortable} {
    string tolower [list [catch {file lstat _bogus_ stat} msg] \
	    $msg $errorCode]
} {1 {couldn't lstat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-19.6 {Tcl_FileObjCmd: lstat errors} {
    catch {unset x}
    set x 44
    list [catch {file lstat gorp.file x} msg] $msg $errorCode
} {1 {can't set "x(dev)": variable isn't array} NONE}
catch {unset stat}

# mtime 

test cmdAH-20.1 {Tcl_FileObjCmd: mtime} {
    list [catch {file mtime a b} msg] $msg
} {1 {wrong # args: should be "file mtime name"}}
test cmdAH-20.2 {Tcl_FileObjCmd: mtime} {
    set old [file mtime gorp.file]
    after 2000
    set f [open gorp.file w]
    puts $f "More text"
    close $f
    set new [file mtime gorp.file]
    expr {($new > $old) && ($new <= ($old+5))}
} {1}
test cmdAH-20.3 {Tcl_FileObjCmd: mtime} {
    catch {unset stat}
    file stat gorp.file stat
    list [expr {[file mtime gorp.file] == $stat(mtime)}] \
	    [expr {[file atime gorp.file] == $stat(atime)}]
} {1 1}
test cmdAH-20.4 {Tcl_FileObjCmd: mtime} {
    string tolower [list [catch {file mtime _bogus_} msg] $msg \
	    $errorCode]
} {1 {couldn't stat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-20.5 {Tcl_FileObjCmd: mtime} {
    # Under Unix, use a file in /tmp to avoid clock skew due to NFS.
    # On other platforms, just use a file in the local directory.

    if {$tcl_platform(platform) == "unix"} {
	 set name /tmp/tcl.test
    } else {
	set name tf
    }

    # Borland file times were off by timezone.  Make sure that a new file's
    # time is correct.  10 seconds variance is allowed used due to slow
    # networks or clock skew on a network drive.

    file delete -force $name
    close [open $name w]
    set a [expr abs([clock seconds]-[file mtime $name])<10]
    file delete $name
    set a
} {1}


# owned

test cmdAH-21.1 {Tcl_FileObjCmd: owned} {
    list [catch {file owned a b} msg] $msg
} {1 {wrong # args: should be "file owned name"}}
test cmdAH-21.2 {Tcl_FileObjCmd: owned} {
    file owned gorp.file
} 1
test cmdAH-21.3 {Tcl_FileObjCmd: owned} {unixOnly && !root} {
    file owned /
} 0

# readlink

test cmdAH-22.1 {Tcl_FileObjCmd: readlink} {
    list [catch {file readlink a b} msg] $msg
} {1 {wrong # args: should be "file readlink name"}}
test cmdAH-22.2 {Tcl_FileObjCmd: readlink} {unixOnly nonPortable} {
    file readlink link.file
} gorp.file
test cmdAH-22.3 {Tcl_FileObjCmd: readlink errors} {unixOnly nonPortable} {
    list [catch {file readlink _bogus_} msg] [string tolower $msg] \
	    [string tolower $errorCode]
} {1 {couldn't readlink "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-22.4 {Tcl_FileObjCmd: readlink errors} {macOnly nonPortable} {
    list [catch {file readlink _bogus_} msg] [string tolower $msg] \
	    [string tolower $errorCode]
} {1 {couldn't readlink "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-22.5 {Tcl_FileObjCmd: readlink errors} {pcOnly nonPortable} {
    list [catch {file readlink _bogus_} msg] [string tolower $msg] \
	    [string tolower $errorCode]
} {1 {couldn't readlink "_bogus_": invalid argument} {posix einval {invalid argument}}}

# size

test cmdAH-23.1 {Tcl_FileObjCmd: size} {
    list [catch {file size a b} msg] $msg
} {1 {wrong # args: should be "file size name"}}
test cmdAH-23.2 {Tcl_FileObjCmd: size} {
    set oldsize [file size gorp.file]
    set f [open gorp.file a]
    fconfigure $f -translation lf -eofchar {}
    puts $f "More text"
    close $f
    expr {[file size gorp.file] - $oldsize}
} {10}
test cmdAH-23.3 {Tcl_FileObjCmd: size} {
    string tolower [list [catch {file size _bogus_} msg] $msg \
	    $errorCode]
} {1 {couldn't stat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}

# stat

testsetplatform $platform
makeFile "Test string" gorp.file
catch {exec chmod 765 gorp.file}

test cmdAH-24.1 {Tcl_FileObjCmd: stat} {
    list [catch {file stat _bogus_} msg] $msg $errorCode
} {1 {wrong # args: should be "file stat name varName"} NONE}
test cmdAH-24.2 {Tcl_FileObjCmd: stat} {
    list [catch {file stat _bogus_ a b} msg] $msg $errorCode
} {1 {wrong # args: should be "file stat name varName"} NONE}
test cmdAH-24.3 {Tcl_FileObjCmd: stat} {
    catch {unset stat}
    file stat gorp.file stat
    lsort [array names stat]
} {atime ctime dev gid ino mode mtime nlink size type uid}
test cmdAH-24.4 {Tcl_FileObjCmd: stat} {
    catch {unset stat}
    file stat gorp.file stat
    list $stat(nlink) $stat(size) $stat(type)
} {1 12 file}
test cmdAH-24.5 {Tcl_FileObjCmd: stat} {unix} {
    catch {unset stat}
    file stat gorp.file stat
    expr $stat(mode)&0777
} {501}
test cmdAH-24.6 {Tcl_FileObjCmd: stat} {
    string tolower [list [catch {file stat _bogus_ stat} msg] \
	    $msg $errorCode]
} {1 {couldn't stat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-24.7 {Tcl_FileObjCmd: stat} {
    catch {unset x}
    set x 44
    list [catch {file stat gorp.file x} msg] $msg $errorCode
} {1 {can't set "x(dev)": variable isn't array} NONE}




















































catch {unset stat}

# type

file delete link.file

test cmdAH-25.1 {Tcl_FileObjCmd: type} {
    list [catch {file size a b} msg] $msg
} {1 {wrong # args: should be "file size name"}}
test cmdAH-25.2 {Tcl_FileObjCmd: type} {
    file type dir.file
} directory
test cmdAH-25.3 {Tcl_FileObjCmd: type} {
    file type gorp.file
} file
test cmdAH-25.4 {Tcl_FileObjCmd: type} {unixOnly nonPortable} {
    exec ln -s a/b/c link.file
    set result [file type link.file]
    file delete link.file
    set result
} link
test cmdAH-25.5 {Tcl_FileObjCmd: type} {
    string tolower [list [catch {file type _bogus_} msg] $msg $errorCode]
} {1 {couldn't stat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}

# Error conditions

test cmdAH-26.1 {error conditions} {
    list [catch {file gorp x} msg] $msg
} {1 {bad option "gorp": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-26.2 {error conditions} {
    list [catch {file ex x} msg] $msg
} {1 {ambiguous option "ex": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-26.3 {error conditions} {
    list [catch {file is x} msg] $msg
} {1 {ambiguous option "is": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-26.4 {error conditions} {
    list [catch {file z x} msg] $msg
} {1 {bad option "z": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-26.5 {error conditions} {
    list [catch {file read x} msg] $msg
} {1 {ambiguous option "read": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-26.6 {error conditions} {
    list [catch {file s x} msg] $msg
} {1 {ambiguous option "s": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-26.7 {error conditions} {
    list [catch {file t x} msg] $msg
} {1 {ambiguous option "t": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-26.8 {error conditions} {
    list [catch {file dirname ~woohgy} msg] $msg
} {1 {user "woohgy" doesn't exist}}


testsetplatform $platform
catch {unset platform}

catch {exec chmod 777 dir.file}
file delete -force dir.file
file delete gorp.file
file delete link.file


concat ""





















|
>




>
|
>
>
|
<


>
|

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


|


|

|




|


|







|



|
|





|







>
>
>
>
|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|








|








|








|











|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|








|








|








|








|



|



|



|



|



|






|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|

















|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|



|




|











|



|



|



|






|



|



|






|



|



|






|





<
<
>



>
>
>
>
>
>
>
|



|



|





|



|



|









|


|


|







|






|








|








>
>


|


|
|







|


|




>
>
>
>
|



|



|



|
>
|


|








|
|




|
<
|
<
|

|

>
|



|






|


|





|


|



|


|


|





|


|
|





|


|


|




|




|


|
|








|


|








|





|


|
|









<
|
|











|


|


|





|


|


|


|
|


|
|


|



|


|







|


|



|



|


|


|




|




|




|


|
|




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






|


|


|


|





|

|



|


|


|


|


|


|


|


|



>
|







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

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997


998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140

1141

1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256

1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
# The file tests the tclCmdAH.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) 1996-1998 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: cmdAH.test,v 1.1.2.9 1999/03/24 02:48:59 hershey Exp $

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


global env
set cmdAHwd [pwd]
catch {set platform [testgetplatform]}

test cmdAH-0.1 {Tcl_BreakObjCmd, errors} {
    list [catch {break foo} msg] $msg
} {1 {wrong # args: should be "break"}}
test cmdAH-0.2 {Tcl_BreakObjCmd, success} {
    list [catch {break} msg] $msg
} {3 {}}

# Tcl_CaseObjCmd is tested in case.test

test cmdAH-1.1 {Tcl_CatchObjCmd, errors} {
    list [catch {catch} msg] $msg
} {1 {wrong # args: should be "catch command ?varName?"}}
test cmdAH-1.2 {Tcl_CatchObjCmd, errors} {
    list [catch {catch foo bar baz} msg] $msg
} {1 {wrong # args: should be "catch command ?varName?"}}

test cmdAH-2.1 {Tcl_CdObjCmd} {
    list [catch {cd foo bar} msg] $msg
} {1 {wrong # args: should be "cd ?dirName?"}}
test cmdAH-2.2 {Tcl_CdObjCmd} {
    file delete -force foo
    file mkdir foo
    cd foo
    set result [file tail [pwd]]
    cd ..
    file delete foo
    set result
} foo
test cmdAH-2.3 {Tcl_CdObjCmd} {
    global env
    set oldpwd [pwd]
    set temp $env(HOME)
    set env(HOME) $oldpwd
    file delete -force foo
    file mkdir foo
    cd foo
    cd ~
    set result [string match [pwd] $oldpwd]
    file delete foo
    set env(HOME) $temp
    set result
} 1
test cmdAH-2.4 {Tcl_CdObjCmd} {
    global env
    set oldpwd [pwd]
    set temp $env(HOME)
    set env(HOME) $oldpwd
    file delete -force foo
    file mkdir foo
    cd foo
    cd
    set result [string match [pwd] $oldpwd]
    file delete foo
    set env(HOME) $temp
    set result
} 1
test cmdAH-2.5 {Tcl_CdObjCmd} {
    list [catch {cd ~~} msg] $msg
} {1 {user "~" doesn't exist}}
test cmdAH-2.6 {Tcl_CdObjCmd} {
    list [catch {cd _foobar} msg] $msg
} {1 {couldn't change working directory to "_foobar": no such file or directory}}

test cmdAH-2.7 {Tcl_ConcatObjCmd} {
    concat
} {}
test cmdAH-2.8 {Tcl_ConcatObjCmd} {
    concat a
} a
test cmdAH-2.9 {Tcl_ConcatObjCmd} {
    concat a {b c}
} {a b c}

test cmdAH-3.1 {Tcl_ContinueObjCmd, errors} {
    list [catch {continue foo} msg] $msg
} {1 {wrong # args: should be "continue"}}
test cmdAH-3.2 {Tcl_ContinueObjCmd, success} {
    list [catch {continue} msg] $msg
} {4 {}}

test cmdAH-4.1 {Tcl_EncodingObjCmd} {
    list [catch {encoding} msg] $msg
} {1 {wrong # args: should be "encoding option ?arg ...?"}}
test cmdAH-4.2 {Tcl_EncodingObjCmd} {
    list [catch {encoding foo} msg] $msg
} {1 {bad option "foo": must be convertfrom, convertto, names, or system}}
test cmdAH-4.3 {Tcl_EncodingObjCmd} {
    list [catch {encoding convertto} msg] $msg
} {1 {wrong # args: should be "encoding convertto ?encoding? data"}}
test cmdAH-4.4 {Tcl_EncodingObjCmd} {
    list [catch {encoding convertto foo bar} msg] $msg
} {1 {unknown encoding "foo"}}
test cmdAH-4.5 {Tcl_EncodingObjCmd} {
    set system [encoding system]
    encoding system jis0208
    set x [encoding convertto \u4e4e]
    encoding system $system
    set x
} 8C
test cmdAH-4.6 {Tcl_EncodingObjCmd} {
    set system [encoding system]
    encoding system identity
    set x [encoding convertto jis0208 \u4e4e]
    encoding system $system
    set x
} 8C
test cmdAH-4.7 {Tcl_EncodingObjCmd} {
    list [catch {encoding convertfrom} msg] $msg
} {1 {wrong # args: should be "encoding convertfrom ?encoding? data"}}
test cmdAH-4.8 {Tcl_EncodingObjCmd} {
    list [catch {encoding convertfrom foo bar} msg] $msg
} {1 {unknown encoding "foo"}}
test cmdAH-4.9 {Tcl_EncodingObjCmd} {
    set system [encoding system]
    encoding system jis0208
    set x [encoding convertfrom 8C]
    encoding system $system
    set x
} \u4e4e
test cmdAH-4.10 {Tcl_EncodingObjCmd} {
    set system [encoding system]
    encoding system identity
    set x [encoding convertfrom jis0208 8C]
    encoding system $system
    set x
} \u4e4e
test cmdAH-4.11 {Tcl_EncodingObjCmd} {
    list [catch {encoding names foo} msg] $msg
} {1 {wrong # args: should be "encoding names"}}
test cmdAH-4.12 {Tcl_EncodingObjCmd} {
    list [catch {encoding system foo bar} msg] $msg
} {1 {wrong # args: should be "encoding system ?encoding?"}}
test cmdAH-4.13 {Tcl_EncodingObjCmd} {
    set system [encoding system]
    encoding system identity
    set x [encoding system]
    encoding system $system
    set x
} identity

test cmdAH-5.1 {Tcl_FileObjCmd} {
    list [catch file msg] $msg
} {1 {wrong # args: should be "file option ?arg ...?"}}
test cmdAH-5.2 {Tcl_FileObjCmd} {
    list [catch {file x} msg] $msg
} {1 {bad option "x": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-5.3 {Tcl_FileObjCmd} {
    list [catch {file atime} msg] $msg
} {1 {wrong # args: should be "file atime name"}}


#volume

test cmdAH-6.1 {Tcl_FileObjCmd: volumes} {
    list [catch {file volumes x} msg] $msg	
} {1 {wrong # args: should be "file volumes"}}
test cmdAH-6.2 {Tcl_FileObjCmd: volumes} {
	set volumeList [file volumes]
	if { [llength $volumeList] == 0 } {
		set result 0
	} else {
		set result 1
	}	
} {1}
test cmdAH-6.3 {Tcl_FileObjCmd: volumes} {macOrUnix} {
    set volumeList [file volumes]
    catch [list glob -nocomplain [lindex $volumeList 0]*]
} {0}
test cmdAH-6.4 {Tcl_FileObjCmd: volumes} {pcOnly} {
    set volumeList [string tolower [file volumes]]
    list [catch {lsearch $volumeList "c:/"} element] [expr $element != -1] [catch {list glob -nocomplain [lindex $volumeList $element]*}]
} {0 1 0}

# attributes

test cmdAH-7.1 {Tcl_FileObjCmd - file attrs} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file}] [file delete -force foo.file]
} {0 {}}

# dirname

if {[info commands testsetplatform] == {}} {
    puts "This application hasn't been compiled with the \"testsetplatform\""
    puts "command, so I can't test Tcl_FileObjCmd etc."
} else {
test cmdAH-8.1 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname a b} msg] $msg
} {1 {wrong # args: should be "file dirname name"}}
test cmdAH-8.2 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname /a/b
} /a
test cmdAH-8.3 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname {}
} .
test cmdAH-8.4 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    file dirname {}
} :
test cmdAH-8.5 {Tcl_FileObjCmd: dirname} {
    testsetplatform win
    file dirname {}
} .
test cmdAH-8.6 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname .def
} .
test cmdAH-8.7 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    file dirname a
} :
test cmdAH-8.8 {Tcl_FileObjCmd: dirname} {
    testsetplatform win
    file dirname a
} .
test cmdAH-8.9 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname a/b/c.d
} a/b
test cmdAH-8.10 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname a/b.c/d
} a/b.c
test cmdAH-8.11 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    file dirname /.
} /
test cmdAH-8.12 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname /} msg] $msg
} {0 /}
test cmdAH-8.13 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname /foo} msg] $msg
} {0 /}
test cmdAH-8.14 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname //foo} msg] $msg
} {0 /}
test cmdAH-8.15 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname //foo/bar} msg] $msg
} {0 /foo}
test cmdAH-8.16 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname {//foo\/bar/baz}} msg] $msg
} {0 {/foo\/bar}}
test cmdAH-8.17 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname {//foo\/bar/baz/blat}} msg] $msg
} {0 {/foo\/bar/baz}}
test cmdAH-8.18 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname /foo//} msg] $msg
} {0 /}
test cmdAH-8.19 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname ./a} msg] $msg
} {0 .}
test cmdAH-8.20 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname a/.a} msg] $msg
} {0 a}
test cmdAH-8.21 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname c:foo} msg] $msg
} {0 c:}
test cmdAH-8.22 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname c:} msg] $msg
} {0 c:}
test cmdAH-8.23 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname c:/} msg] $msg
} {0 c:/}
test cmdAH-8.24 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname {c:\foo}} msg] $msg
} {0 c:/}
test cmdAH-8.25 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname {//foo/bar/baz}} msg] $msg
} {0 //foo/bar}
test cmdAH-8.26 {Tcl_FileObjCmd: dirname} {
    testsetplatform windows
    list [catch {file dirname {//foo/bar}} msg] $msg
} {0 //foo/bar}
test cmdAH-8.27 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname :} msg] $msg
} {0 :}
test cmdAH-8.28 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname :Foo} msg] $msg
} {0 :}
test cmdAH-8.29 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname Foo:} msg] $msg
} {0 Foo:}
test cmdAH-8.30 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname Foo:bar} msg] $msg
} {0 Foo:}
test cmdAH-8.31 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname :Foo:bar} msg] $msg
} {0 :Foo}
test cmdAH-8.32 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname ::} msg] $msg
} {0 :}
test cmdAH-8.33 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname :::} msg] $msg
} {0 ::}
test cmdAH-8.34 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname /foo/bar/} msg] $msg
} {0 foo:}
test cmdAH-8.35 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname /foo/bar} msg] $msg
} {0 foo:}
test cmdAH-8.36 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname /foo} msg] $msg
} {0 foo:}
test cmdAH-8.37 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname foo} msg] $msg
} {0 :}
test cmdAH-8.38 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname ~/foo} msg] $msg
} {0 ~}
test cmdAH-8.39 {Tcl_FileObjCmd: dirname} {
    testsetplatform unix
    list [catch {file dirname ~bar/foo} msg] $msg
} {0 ~bar}
test cmdAH-8.40 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname ~bar/foo} msg] $msg
} {0 ~bar:}
test cmdAH-8.41 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname ~/foo} msg] $msg
} {0 ~:}
test cmdAH-8.42 {Tcl_FileObjCmd: dirname} {
    testsetplatform mac
    list [catch {file dirname ~:baz} msg] $msg
} {0 ~:}
test cmdAH-8.43 {Tcl_FileObjCmd: dirname} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform unix
    set result [list [catch {file dirname ~} msg] $msg]
    set env(HOME) $temp
    set result
} {0 /home}
test cmdAH-8.44 {Tcl_FileObjCmd: dirname} {
    global env
    set temp $env(HOME)
    set env(HOME) "~"
    testsetplatform unix
    set result [list [catch {file dirname ~} msg] $msg]
    set env(HOME) $temp
    set result
} {0 ~}
test cmdAH-8.45 {Tcl_FileObjCmd: dirname} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform windows
    set result [list [catch {file dirname ~} msg] $msg]
    set env(HOME) $temp
    set result
} {0 /home}
test cmdAH-8.46 {Tcl_FileObjCmd: dirname} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform mac
    set result [list [catch {file dirname ~} msg] $msg]
    set env(HOME) $temp
    set result
} {0 home:}

# tail

test cmdAH-9.1 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    list [catch {file tail a b} msg] $msg
} {1 {wrong # args: should be "file tail name"}}
test cmdAH-9.2 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail /a/b
} b
test cmdAH-9.3 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail {}
} {}
test cmdAH-9.4 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail {}
} {}
test cmdAH-9.5 {Tcl_FileObjCmd: tail} {
    testsetplatform win
    file tail {}
} {}
test cmdAH-9.6 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail .def
} .def
test cmdAH-9.7 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail a
} a
test cmdAH-9.8 {Tcl_FileObjCmd: tail} {
    testsetplatform win
    file tail a
} a
test cmdAH-9.9 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file ta a/b/c.d
} c.d
test cmdAH-9.10 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail a/b.c/d
} d
test cmdAH-9.11 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail /.
} .
test cmdAH-9.12 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail /
} {}
test cmdAH-9.13 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail /foo
} foo
test cmdAH-9.14 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail //foo
} foo
test cmdAH-9.15 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail //foo/bar
} bar
test cmdAH-9.16 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail {//foo\/bar/baz}
} baz
test cmdAH-9.17 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail {//foo\/bar/baz/blat}
} blat
test cmdAH-9.18 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail /foo//
} foo
test cmdAH-9.19 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail ./a
} a
test cmdAH-9.20 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail a/.a
} .a
test cmdAH-9.21 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:foo
} foo
test cmdAH-9.22 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:
} {}
test cmdAH-9.23 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:/
} {}
test cmdAH-9.24 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail {c:\foo}
} foo
test cmdAH-9.25 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail {//foo/bar/baz}
} baz
test cmdAH-9.26 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail {//foo/bar}
} {}
test cmdAH-9.27 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail :
} :
test cmdAH-9.28 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail :Foo
} Foo
test cmdAH-9.29 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail Foo:
} {}
test cmdAH-9.30 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail Foo:bar
} bar
test cmdAH-9.31 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail :Foo:bar
} bar
test cmdAH-9.32 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail ::
} ::
test cmdAH-9.33 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail :::
} ::
test cmdAH-9.34 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail /foo/bar/
} bar
test cmdAH-9.35 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail /foo/bar
} bar
test cmdAH-9.36 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail /foo
} {}
test cmdAH-9.37 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail foo
} foo
test cmdAH-9.38 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail ~:foo
} foo
test cmdAH-9.39 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail ~bar:foo
} foo
test cmdAH-9.40 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail ~bar/foo
} foo
test cmdAH-9.41 {Tcl_FileObjCmd: tail} {
    testsetplatform mac
    file tail ~/foo
} foo
test cmdAH-9.42 {Tcl_FileObjCmd: tail} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform unix
    set result [file tail ~]
    set env(HOME) $temp
    set result
} test
test cmdAH-9.43 {Tcl_FileObjCmd: tail} {
    global env
    set temp $env(HOME)
    set env(HOME) "~"
    testsetplatform unix
    set result [file tail ~]
    set env(HOME) $temp
    set result
} {}
test cmdAH-9.44 {Tcl_FileObjCmd: tail} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform windows
    set result [file tail ~]
    set env(HOME) $temp
    set result
} test
test cmdAH-9.45 {Tcl_FileObjCmd: tail} {
    global env
    set temp $env(HOME)
    set env(HOME) "/home/test"
    testsetplatform mac
    set result [file tail ~]
    set env(HOME) $temp
    set result
} test
test cmdAH-9.46 {Tcl_FileObjCmd: tail} {
    testsetplatform unix
    file tail {f.oo\bar/baz.bat}
} baz.bat
test cmdAH-9.47 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:foo
} foo
test cmdAH-9.48 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:
} {}
test cmdAH-9.49 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail c:/foo
} foo
test cmdAH-9.50 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail {c:/foo\bar}
} bar
test cmdAH-9.51 {Tcl_FileObjCmd: tail} {
    testsetplatform windows
    file tail {foo\bar}
} bar

# rootname

test cmdAH-10.1 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    list [catch {file rootname a b} msg] $msg
} {1 {wrong # args: should be "file rootname name"}}
test cmdAH-10.2 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname {}
} {}
test cmdAH-10.3 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file ro foo
} foo
test cmdAH-10.4 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname foo.
} foo
test cmdAH-10.5 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname .foo
} {}
test cmdAH-10.6 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname abc.def
} abc
test cmdAH-10.7 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname abc.def.ghi
} abc.def
test cmdAH-10.8 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname a/b/c.d
} a/b/c
test cmdAH-10.9 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname a/b.c/d
} a/b.c/d
test cmdAH-10.10 {Tcl_FileObjCmd: rootname} {
    testsetplatform unix
    file rootname a/b.c/
} a/b.c/
test cmdAH-10.11 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file ro foo
} foo
test cmdAH-10.12 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname {}
} {}
test cmdAH-10.13 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname foo.
} foo
test cmdAH-10.14 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname .foo
} {}
test cmdAH-10.15 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname abc.def
} abc
test cmdAH-10.16 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname abc.def.ghi
} abc.def
test cmdAH-10.17 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname a:b:c.d
} a:b:c
test cmdAH-10.18 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname a:b.c:d
} a:b.c:d
test cmdAH-10.19 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname a/b/c.d
} a/b/c
test cmdAH-10.20 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname a/b.c/d
} a/b.c/d
test cmdAH-10.21 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname /a.b
} /a
test cmdAH-10.22 {Tcl_FileObjCmd: rootname} {
    testsetplatform mac
    file rootname foo.c:
} foo.c:
test cmdAH-10.23 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname {}
} {}
test cmdAH-10.24 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file ro foo
} foo
test cmdAH-10.25 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname foo.
} foo
test cmdAH-10.26 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname .foo
} {}
test cmdAH-10.27 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname abc.def
} abc
test cmdAH-10.28 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname abc.def.ghi
} abc.def
test cmdAH-10.29 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a/b/c.d
} a/b/c
test cmdAH-10.30 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a/b.c/d
} a/b.c/d
test cmdAH-10.31 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a\\b.c\\
} a\\b.c\\
test cmdAH-10.32 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a\\b\\c.d
} a\\b\\c
test cmdAH-10.33 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a\\b.c\\d
} a\\b.c\\d
test cmdAH-10.34 {Tcl_FileObjCmd: rootname} {
    testsetplatform windows
    file rootname a\\b.c\\
} a\\b.c\\
set num 35
foreach outer { {} a .a a. a.a } {
  foreach inner { {} a .a a. a.a } {
    set thing [format %s/%s $outer $inner]
;   test cmdAH-6.$num {Tcl_FileObjCmd: rootname and extension options} {
	testsetplatform unix
	format %s%s [file rootname $thing] [file ext $thing]
    } $thing
    set num [expr $num+1]
  }
}

# extension

test cmdAH-11.1 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    list [catch {file extension a b} msg] $msg
} {1 {wrong # args: should be "file extension name"}}
test cmdAH-11.2 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension {}
} {}
test cmdAH-11.3 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file ext foo
} {}
test cmdAH-11.4 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension foo.
} .
test cmdAH-11.5 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension .foo
} .foo
test cmdAH-11.6 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension abc.def
} .def
test cmdAH-11.7 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension abc.def.ghi
} .ghi
test cmdAH-11.8 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension a/b/c.d
} .d
test cmdAH-11.9 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension a/b.c/d
} {}
test cmdAH-11.10 {Tcl_FileObjCmd: extension} {
    testsetplatform unix
    file extension a/b.c/
} {}
test cmdAH-11.11 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file ext foo
} {}
test cmdAH-11.12 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension {}
} {}
test cmdAH-11.13 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension foo.
} .
test cmdAH-11.14 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension .foo
} .foo
test cmdAH-11.15 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension abc.def
} .def
test cmdAH-11.16 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension abc.def.ghi
} .ghi
test cmdAH-11.17 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension a:b:c.d
} .d
test cmdAH-11.18 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension a:b.c:d
} {}
test cmdAH-11.19 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension a/b/c.d
} .d
test cmdAH-11.20 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension a/b.c/d
} {}
test cmdAH-11.21 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension /a.b
} .b
test cmdAH-11.22 {Tcl_FileObjCmd: extension} {
    testsetplatform mac
    file extension foo.c:
} {}
test cmdAH-11.23 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension {}
} {}
test cmdAH-11.24 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file ext foo
} {}
test cmdAH-11.25 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension foo.
} .
test cmdAH-11.26 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension .foo
} .foo
test cmdAH-11.27 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension abc.def
} .def
test cmdAH-11.28 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension abc.def.ghi
} .ghi
test cmdAH-11.29 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a/b/c.d
} .d
test cmdAH-11.30 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a/b.c/d
} {}
test cmdAH-11.31 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a\\b.c\\
} {}
test cmdAH-11.32 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a\\b\\c.d
} .d
test cmdAH-11.33 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a\\b.c\\d
} {}
test cmdAH-11.34 {Tcl_FileObjCmd: extension} {
    testsetplatform windows
    file extension a\\b.c\\
} {}
set num 35
foreach value {a..b a...b a.c..b ..b} result {.b .b .b .b} {
    foreach p {unix mac windows} {
;	test cmdAH-7.$num {Tcl_FileObjCmd: extension} "
	    testsetplatform $p
	    file extension $value
	" $result
	incr num
    }
}

# pathtype

test cmdAH-12.1 {Tcl_FileObjCmd: pathtype} {
    testsetplatform unix
    list [catch {file pathtype a b} msg] $msg
} {1 {wrong # args: should be "file pathtype name"}}
test cmdAH-12.2 {Tcl_FileObjCmd: pathtype} {
    testsetplatform unix
    file pathtype /a
} absolute
test cmdAH-12.3 {Tcl_FileObjCmd: pathtype} {
    testsetplatform unix
    file p a
} relative
test cmdAH-12.4 {Tcl_FileObjCmd: pathtype} {
    testsetplatform windows
    file pathtype c:a
} volumerelative

# split

test cmdAH-13.1 {Tcl_FileObjCmd: split} {
    testsetplatform unix
    list [catch {file split a b} msg] $msg
} {1 {wrong # args: should be "file split name"}}
test cmdAH-13.2 {Tcl_FileObjCmd: split} {
    testsetplatform unix
    file split a
} a
test cmdAH-13.3 {Tcl_FileObjCmd: split} {
    testsetplatform unix
    file split a/b
} {a b}

# join

test cmdAH-14.1 {Tcl_FileObjCmd: join} {
    testsetplatform unix
    file join a
} a
test cmdAH-14.2 {Tcl_FileObjCmd: join} {
    testsetplatform unix
    file join a b
} a/b
test cmdAH-14.3 {Tcl_FileObjCmd: join} {
    testsetplatform unix
    file join a b c d
} a/b/c/d

# error handling of Tcl_TranslateFileName

test cmdAH-15.1 {Tcl_FileObjCmd} {
    testsetplatform unix
    list [catch {file atime ~_bad_user} msg] $msg
} {1 {user "_bad_user" doesn't exist}}

testsetplatform $platform


}

# readable

if {[info commands testchmod] == {}} {
    puts "This application hasn't been compiled with the \"testchmod\""
    puts "command, so I can't test Tcl_FileObjCmd etc."
} else {
makeFile abcde gorp.file
makeDirectory dir.file

test cmdAH-16.1 {Tcl_FileObjCmd: readable} {
    list [catch {file readable a b} msg] $msg
} {1 {wrong # args: should be "file readable name"}}
testchmod 444 gorp.file
test cmdAH-16.2 {Tcl_FileObjCmd: readable} {
    file readable gorp.file
} 1
testchmod 333 gorp.file
test cmdAH-16.3 {Tcl_FileObjCmd: readable} {unixOnly notRoot} {
    file reada gorp.file
} 0

# writable

test cmdAH-17.1 {Tcl_FileObjCmd: writable} {
    list [catch {file writable a b} msg] $msg
} {1 {wrong # args: should be "file writable name"}}
testchmod 555 gorp.file
test cmdAH-17.2 {Tcl_FileObjCmd: writable} {notRoot} {
    file writable gorp.file
} 0
testchmod 222 gorp.file
test cmdAH-17.3 {Tcl_FileObjCmd: writable} {
    file writable gorp.file
} 1

# executable

file delete -force dir.file gorp.file
file mkdir dir.file
makeFile abcde gorp.file

test cmdAH-18.1 {Tcl_FileObjCmd: executable} {
    list [catch {file executable a b} msg] $msg
} {1 {wrong # args: should be "file executable name"}}
test cmdAH-18.2 {Tcl_FileObjCmd: executable} {
    file executable gorp.file
} 0
test cmdAH-18.3 {Tcl_FileObjCmd: executable} {unixOnly} {
    # Only on unix will setting the execute bit on a regular file
    # cause that file to be executable.   
    
    testchmod 775 gorp.file
    file exe gorp.file
} 1

test cmdAH-18.4 {Tcl_FileObjCmd: executable} {macOnly} {
    # On mac, the only executable files are of type APPL.

    set x [file exe gorp.file]    
    file attrib gorp.file -type APPL
    lappend x [file exe gorp.file]
} {0 1}
test cmdAH-18.5 {Tcl_FileObjCmd: executable} {pcOnly} {
    # On pc, must be a .exe, .com, etc.
    
    set x [file exe gorp.file]
    makeFile foo gorp.exe
    lappend x [file exe gorp.exe]
    file delete gorp.exe
    set x
} {0 1}
test cmdAH-18.6 {Tcl_FileObjCmd: executable} {
    # Directories are always executable.
    
    file exe dir.file
} 1

file delete -force dir.file  
file delete gorp.file
file delete link.file
}

# exists

test cmdAH-19.1 {Tcl_FileObjCmd: exists} {
    list [catch {file exists a b} msg] $msg
} {1 {wrong # args: should be "file exists name"}}
test cmdAH-19.2 {Tcl_FileObjCmd: exists} {file exists gorp.file} 0
test cmdAH-19.3 {Tcl_FileObjCmd: exists} {
    file exists [file join dir.file gorp.file]
} 0
catch {
    makeFile abcde gorp.file
    makeDirectory dir.file
    makeFile 12345 [file join dir.file gorp.file]
}
test cmdAH-19.4 {Tcl_FileObjCmd: exists} {
    file exists gorp.file
} 1
test cmdAH-19.5 {Tcl_FileObjCmd: exists} {
    file exists [file join dir.file gorp.file]
} 1

# nativename
if {[info commands testsetplatform] == {}} {
    puts "This application hasn't been compiled with the \"testsetplatform\""
    puts "command, so I can't test Tcl_FileObjCmd etc."
} else {
test cmdAH-19.6 {Tcl_FileObjCmd: nativename} {
    testsetplatform unix
    list [catch {file nativename a/b} msg] $msg [testsetplatform $platform]
} {0 a/b {}}
test cmdAH-19.7 {Tcl_FileObjCmd: nativename} {
    testsetplatform windows
    list [catch {file nativename a/b} msg] $msg [testsetplatform $platform]
} {0 {a\b} {}}
test cmdAH-19.8 {Tcl_FileObjCmd: nativename} {
    testsetplatform mac
    list [catch {file nativename a/b} msg] $msg [testsetplatform $platform]
} {0 :a:b {}}
}

test cmdAH-19.9 {Tcl_FileObjCmd: ~ : exists} {
    file exists ~nOsUcHuSeR
} 0
test cmdAH-19.10 {Tcl_FileObjCmd: ~ : nativename} {
    # should probably be 0 in fact...
    catch {file nativename ~nOsUcHuSeR}
} 1

# The test below has to be done in /tmp rather than the current
# directory in order to guarantee (?) a local file system:  some
# NFS file systems won't do the stuff below correctly.

test cmdAH-19.11 {Tcl_FileObjCmd: exists} {unixOnly notRoot} {
    removeFile /tmp/tcl.foo.dir/file
    removeDirectory /tmp/tcl.foo.dir
    makeDirectory /tmp/tcl.foo.dir
    makeFile 12345 /tmp/tcl.foo.dir/file
    exec chmod 000 /tmp/tcl.foo.dir


    set result [file exists /tmp/tcl.foo.dir/file]


    exec chmod 775 /tmp/tcl.foo.dir
    removeFile /tmp/tcl.foo.dir/file
    removeDirectory /tmp/tcl.foo.dir
    set result
} 0

# Stat related commands

catch {testsetplatform $platform}
file delete gorp.file
makeFile "Test string" gorp.file
catch {exec chmod 765 gorp.file}

# atime

test cmdAH-20.1 {Tcl_FileObjCmd: atime} {
    list [catch {file atime a b} msg] $msg
} {1 {wrong # args: should be "file atime name"}}
test cmdAH-20.2 {Tcl_FileObjCmd: atime} {
    catch {unset stat}
    file stat gorp.file stat
    list [expr {[file mtime gorp.file] == $stat(mtime)}] \
	    [expr {[file atime gorp.file] == $stat(atime)}]
} {1 1}
test cmdAH-20.3 {Tcl_FileObjCmd: atime} {
    string tolower [list [catch {file atime _bogus_} msg] \
	    $msg $errorCode]
} {1 {could not read "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}

# isdirectory

test cmdAH-21.1 {Tcl_FileObjCmd: isdirectory} {
    list [catch {file isdirectory a b} msg] $msg
} {1 {wrong # args: should be "file isdirectory name"}}
test cmdAH-21.2 {Tcl_FileObjCmd: isdirectory} {
    file isdirectory gorp.file
} 0
test cmdAH-21.3 {Tcl_FileObjCmd: isdirectory} {
    file isd dir.file
} 1

# isfile

test cmdAH-22.1 {Tcl_FileObjCmd: isfile} {
    list [catch {file isfile a b} msg] $msg
} {1 {wrong # args: should be "file isfile name"}}
test cmdAH-22.2 {Tcl_FileObjCmd: isfile} {file isfile gorp.file} 1
test cmdAH-22.3 {Tcl_FileObjCmd: isfile} {file isfile dir.file} 0

# lstat and readlink:  don't run these tests everywhere, since not all
# sites will have symbolic links

catch {exec ln -s gorp.file link.file}
test cmdAH-23.1 {Tcl_FileObjCmd: lstat} {
    list [catch {file lstat a} msg] $msg
} {1 {wrong # args: should be "file lstat name varName"}}
test cmdAH-23.2 {Tcl_FileObjCmd: lstat} {
    list [catch {file lstat a b c} msg] $msg
} {1 {wrong # args: should be "file lstat name varName"}}
test cmdAH-23.3 {Tcl_FileObjCmd: lstat} {unixOnly nonPortable} {
    catch {unset stat}
    file lstat link.file stat
    lsort [array names stat]
} {atime ctime dev gid ino mode mtime nlink size type uid}
test cmdAH-23.4 {Tcl_FileObjCmd: lstat} {unixOnly nonPortable} {
    catch {unset stat}
    file lstat link.file stat
    list $stat(nlink) [expr $stat(mode)&0777] $stat(type)
} {1 511 link}
test cmdAH-23.5 {Tcl_FileObjCmd: lstat errors} {nonPortable} {
    string tolower [list [catch {file lstat _bogus_ stat} msg] \
	    $msg $errorCode]
} {1 {could not read "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-23.6 {Tcl_FileObjCmd: lstat errors} {
    catch {unset x}
    set x 44
    list [catch {file lstat gorp.file x} msg] $msg $errorCode
} {1 {can't set "x(dev)": variable isn't array} NONE}
catch {unset stat}

# mtime 

test cmdAH-24.1 {Tcl_FileObjCmd: mtime} {
    list [catch {file mtime a b} msg] $msg
} {1 {wrong # args: should be "file mtime name"}}
test cmdAH-24.2 {Tcl_FileObjCmd: mtime} {
    set old [file mtime gorp.file]
    after 2000
    set f [open gorp.file w]
    puts $f "More text"
    close $f
    set new [file mtime gorp.file]
    expr {($new > $old) && ($new <= ($old+5))}
} {1}
test cmdAH-24.3 {Tcl_FileObjCmd: mtime} {
    catch {unset stat}
    file stat gorp.file stat
    list [expr {[file mtime gorp.file] == $stat(mtime)}] \
	    [expr {[file atime gorp.file] == $stat(atime)}]
} {1 1}
test cmdAH-24.4 {Tcl_FileObjCmd: mtime} {
    string tolower [list [catch {file mtime _bogus_} msg] $msg \
	    $errorCode]
} {1 {could not read "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-24.5 {Tcl_FileObjCmd: mtime} {
    # Under Unix, use a file in /tmp to avoid clock skew due to NFS.
    # On other platforms, just use a file in the local directory.

    if {$tcl_platform(platform) == "unix"} {
	 set name /tmp/tcl.test
    } else {
	set name tf
    }


    # Make sure that a new file's time is correct.  10 seconds variance 
    # is allowed used due to slow networks or clock skew on a network drive.

    file delete -force $name
    close [open $name w]
    set a [expr abs([clock seconds]-[file mtime $name])<10]
    file delete $name
    set a
} {1}


# owned

test cmdAH-25.1 {Tcl_FileObjCmd: owned} {
    list [catch {file owned a b} msg] $msg
} {1 {wrong # args: should be "file owned name"}}
test cmdAH-25.2 {Tcl_FileObjCmd: owned} {
    file owned gorp.file
} 1
test cmdAH-25.3 {Tcl_FileObjCmd: owned} {unixOnly notRoot} {
    file owned /
} 0

# readlink

test cmdAH-26.1 {Tcl_FileObjCmd: readlink} {
    list [catch {file readlink a b} msg] $msg
} {1 {wrong # args: should be "file readlink name"}}
test cmdAH-26.2 {Tcl_FileObjCmd: readlink} {unixOnly nonPortable} {
    file readlink link.file
} gorp.file
test cmdAH-26.3 {Tcl_FileObjCmd: readlink errors} {unixOnly nonPortable} {
    list [catch {file readlink _bogus_} msg] [string tolower $msg] \
	    [string tolower $errorCode]
} {1 {could not readlink "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-26.4 {Tcl_FileObjCmd: readlink errors} {macOnly nonPortable} {
    list [catch {file readlink _bogus_} msg] [string tolower $msg] \
	    [string tolower $errorCode]
} {1 {could not readlink "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-26.5 {Tcl_FileObjCmd: readlink errors} {pcOnly nonPortable} {
    list [catch {file readlink _bogus_} msg] [string tolower $msg] \
	    [string tolower $errorCode]
} {1 {could not readlink "_bogus_": invalid argument} {posix einval {invalid argument}}}

# size

test cmdAH-27.1 {Tcl_FileObjCmd: size} {
    list [catch {file size a b} msg] $msg
} {1 {wrong # args: should be "file size name"}}
test cmdAH-27.2 {Tcl_FileObjCmd: size} {
    set oldsize [file size gorp.file]
    set f [open gorp.file a]
    fconfigure $f -translation lf -eofchar {}
    puts $f "More text"
    close $f
    expr {[file size gorp.file] - $oldsize}
} {10}
test cmdAH-27.3 {Tcl_FileObjCmd: size} {
    string tolower [list [catch {file size _bogus_} msg] $msg \
	    $errorCode]
} {1 {could not read "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}

# stat

catch {testsetplatform $platform}
makeFile "Test string" gorp.file
catch {exec chmod 765 gorp.file}

test cmdAH-28.1 {Tcl_FileObjCmd: stat} {
    list [catch {file stat _bogus_} msg] $msg $errorCode
} {1 {wrong # args: should be "file stat name varName"} NONE}
test cmdAH-28.2 {Tcl_FileObjCmd: stat} {
    list [catch {file stat _bogus_ a b} msg] $msg $errorCode
} {1 {wrong # args: should be "file stat name varName"} NONE}
test cmdAH-28.3 {Tcl_FileObjCmd: stat} {
    catch {unset stat}
    file stat gorp.file stat
    lsort [array names stat]
} {atime ctime dev gid ino mode mtime nlink size type uid}
test cmdAH-28.4 {Tcl_FileObjCmd: stat} {
    catch {unset stat}
    file stat gorp.file stat
    list $stat(nlink) $stat(size) $stat(type)
} {1 12 file}
test cmdAH-28.5 {Tcl_FileObjCmd: stat} {unixOnly} {
    catch {unset stat}
    file stat gorp.file stat
    expr $stat(mode)&0777
} {501}
test cmdAH-28.6 {Tcl_FileObjCmd: stat} {
    string tolower [list [catch {file stat _bogus_ stat} msg] \
	    $msg $errorCode]
} {1 {could not read "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-28.7 {Tcl_FileObjCmd: stat} {
    catch {unset x}
    set x 44
    list [catch {file stat gorp.file x} msg] $msg $errorCode
} {1 {can't set "x(dev)": variable isn't array} NONE}
test cmdAH-28.8 {Tcl_FileObjCmd: stat} {
    # Sign extension of purported unsigned short to int.

    close [open foo.test w]
    file stat foo.test stat
    set x [expr {$stat(mode) > 0}]
    file delete foo.test
    set x
} 1
test cmdAH-28.9 {Tcl_FileObjCmd: stat} {pcOnly} {
    # stat of root directory was failing.
    # don't care about answer, just that test runs.

    # relative paths that resolve to root
    set old [pwd]
    cd c:/
    file stat c: stat	    
    file stat c:. stat
    file stat . stat
    cd $old

    file stat / stat
    file stat c:/ stat
    file stat c:/. stat
} {}
test cmdAH-28.10 {Tcl_FileObjCmd: stat} {pcOnly nonPortable} {
    # stat of root directory was failing.
    # don't care about answer, just that test runs.

    file stat //pop/$env(USERNAME) stat
    file stat //pop/$env(USERNAME)/ stat
    file stat //pop/$env(USERNAME)/. stat
} {}    
test cmdAH-28.11 {Tcl_FileObjCmd: stat} {pcOnly nonPortable} {
    # stat of network directory was returning id of current local drive.

    set old [pwd]
    cd c:/

    file stat //pop/$env(USERNAME) stat
    cd $old
    expr {$stat(dev) == 2}
} 0
test cmdAH-28.12 {Tcl_FileObjCmd: stat} {
    # stat(mode) with S_IFREG flag was returned as a negative number
    # if mode_t was a short instead of an unsigned short.

    close [open foo.test w]
    file stat foo.test stat
    file delete foo.test
    expr {$stat(mode) > 0}
} 1
catch {unset stat}

# type

file delete link.file

test cmdAH-29.1 {Tcl_FileObjCmd: type} {
    list [catch {file size a b} msg] $msg
} {1 {wrong # args: should be "file size name"}}
test cmdAH-29.2 {Tcl_FileObjCmd: type} {
    file type dir.file
} directory
test cmdAH-29.3 {Tcl_FileObjCmd: type} {
    file type gorp.file
} file
test cmdAH-29.4 {Tcl_FileObjCmd: type} {unixOnly nonPortable} {
    exec ln -s a/b/c link.file
    set result [file type link.file]
    file delete link.file
    set result
} link
test cmdAH-29.5 {Tcl_FileObjCmd: type} {
    string tolower [list [catch {file type _bogus_} msg] $msg $errorCode]
} {1 {could not read "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}

# Error conditions

test cmdAH-30.1 {error conditions} {
    list [catch {file gorp x} msg] $msg
} {1 {bad option "gorp": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-30.2 {error conditions} {
    list [catch {file ex x} msg] $msg
} {1 {ambiguous option "ex": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-30.3 {error conditions} {
    list [catch {file is x} msg] $msg
} {1 {ambiguous option "is": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-30.4 {error conditions} {
    list [catch {file z x} msg] $msg
} {1 {bad option "z": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-30.5 {error conditions} {
    list [catch {file read x} msg] $msg
} {1 {ambiguous option "read": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-30.6 {error conditions} {
    list [catch {file s x} msg] $msg
} {1 {ambiguous option "s": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-30.7 {error conditions} {
    list [catch {file t x} msg] $msg
} {1 {ambiguous option "t": must be atime, attributes, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype, readable, readlink, rename, rootname, size, split, stat, tail, type, volumes, or writable}}
test cmdAH-30.8 {error conditions} {
    list [catch {file dirname ~woohgy} msg] $msg
} {1 {user "woohgy" doesn't exist}}

# cleanup
catch {testsetplatform $platform}
catch {unset platform}

catch {exec chmod 777 dir.file}
file delete -force dir.file
file delete gorp.file
file delete link.file

cd $cmdAHwd

::tcltest::cleanupTests
return













Changes to tests/cmdIL.test.

1
2
3
4
5

6
7
8
9

10


11
12
13
14
15
16
17
18
19
# This file contains a collection of tests for the procedures in the
# file tclCmdIL.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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) cmdIL.test 1.18 97/09/18 11:42:12



if {[string compare test [info procs test]] == 1} then {source defs}

test cmdIL-1.1 {Tcl_LsortObjCmd procedure} {
    list [catch {lsort} msg] $msg
} {1 {wrong # args: should be "lsort ?options? list"}}
test cmdIL-1.2 {Tcl_LsortObjCmd procedure} {
    list [catch {lsort -foo {1 3 2 5}} msg] $msg
} {1 {bad option "-foo": must be -ascii, -command, -decreasing, -dictionary, -increasing, -index, -integer, or -real}}





>




>
|
>
>
|
<







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

16
17
18
19
20
21
22
# This file contains a collection of tests for the procedures in the
# file tclCmdIL.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: cmdIL.test,v 1.1.2.6 1999/03/24 02:48:59 hershey Exp $

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


test cmdIL-1.1 {Tcl_LsortObjCmd procedure} {
    list [catch {lsort} msg] $msg
} {1 {wrong # args: should be "lsort ?options? list"}}
test cmdIL-1.2 {Tcl_LsortObjCmd procedure} {
    list [catch {lsort -foo {1 3 2 5}} msg] $msg
} {1 {bad option "-foo": must be -ascii, -command, -decreasing, -dictionary, -increasing, -index, -integer, or -real}}
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
} {x1 x2 x3 x4 abc def}
test cmdIL-1.7 {Tcl_LsortObjCmd procedure, -decreasing option} {
    lsort -decreasing {d e c b a d35 d300}
} {e d35 d300 d c b a}
test cmdIL-1.8 {Tcl_LsortObjCmd procedure, -dictionary option} {
    lsort -dictionary {d e c b a d35 d300}
} {a b c d d35 d300 e}
test cmdIL-1.9 {Tcl_LsortObjCmd procedure, -increasing option} {



    lsort -decreasing -increasing {d e c b a d35 d300}
} {a b c d d300 d35 e}
test cmdIL-1.10 {Tcl_LsortObjCmd procedure, -index option} {
    list [catch {lsort -index {1 3 2 5}} msg] $msg
} {1 {"-index" option must be followed by list index}}
test cmdIL-1.11 {Tcl_LsortObjCmd procedure, -index option} {
    list [catch {lsort -index foo {1 3 2 5}} msg] $msg
} {1 {bad index "foo": must be integer or "end"}}
test cmdIL-1.12 {Tcl_LsortObjCmd procedure, -index option} {
    lsort -index end -integer {{2 25} {10 20 50 100} {3 16 42} 1}
} {1 {2 25} {3 16 42} {10 20 50 100}}
test cmdIL-1.13 {Tcl_LsortObjCmd procedure, -index option} {
    lsort -index 1 -integer {{1 25 100} {3 16 42} {10 20 50}}
} {{3 16 42} {10 20 50} {1 25 100}}
test cmdIL-1.14 {Tcl_LsortObjCmd procedure, -integer option} {
    lsort -integer {24 6 300 18}
} {6 18 24 300}
test cmdIL-1.15 {Tcl_LsortObjCmd procedure, -integer option} {
    list [catch {lsort -integer {1 3 2.4}} msg] $msg
} {1 {expected integer but got "2.4"}}
test cmdIL-1.16 {Tcl_LsortObjCmd procedure, -real option} {
    lsort -real {24.2 6e3 150e-1}
} {150e-1 24.2 6e3}
test cmdIL-1.17 {Tcl_LsortObjCmd procedure, bogus list} {
    list [catch {lsort "1 2 3 \{ 4"} msg] $msg
} {1 {unmatched open brace in list}}
test cmdIL-1.18 {Tcl_LsortObjCmd procedure, empty list} {
    lsort {}
} {}

# Can't think of any good tests for the MergeSort and MergeLists
# procedures, except a bunch of random lists to sort.

test cmdIL-2.1 {MergeSort and MergeLists procedures} {







|
>
>
>


|


|


|


|


|


|


|


|


|







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
} {x1 x2 x3 x4 abc def}
test cmdIL-1.7 {Tcl_LsortObjCmd procedure, -decreasing option} {
    lsort -decreasing {d e c b a d35 d300}
} {e d35 d300 d c b a}
test cmdIL-1.8 {Tcl_LsortObjCmd procedure, -dictionary option} {
    lsort -dictionary {d e c b a d35 d300}
} {a b c d d35 d300 e}
test cmdIL-1.9 {Tcl_LsortObjCmd procedure, -dictionary option} {
    lsort -dictionary {1k 0k 10k}
} {0k 1k 10k}
test cmdIL-1.10 {Tcl_LsortObjCmd procedure, -increasing option} {
    lsort -decreasing -increasing {d e c b a d35 d300}
} {a b c d d300 d35 e}
test cmdIL-1.11 {Tcl_LsortObjCmd procedure, -index option} {
    list [catch {lsort -index {1 3 2 5}} msg] $msg
} {1 {"-index" option must be followed by list index}}
test cmdIL-1.12 {Tcl_LsortObjCmd procedure, -index option} {
    list [catch {lsort -index foo {1 3 2 5}} msg] $msg
} {1 {bad index "foo": must be integer or "end"}}
test cmdIL-1.13 {Tcl_LsortObjCmd procedure, -index option} {
    lsort -index end -integer {{2 25} {10 20 50 100} {3 16 42} 1}
} {1 {2 25} {3 16 42} {10 20 50 100}}
test cmdIL-1.14 {Tcl_LsortObjCmd procedure, -index option} {
    lsort -index 1 -integer {{1 25 100} {3 16 42} {10 20 50}}
} {{3 16 42} {10 20 50} {1 25 100}}
test cmdIL-1.15 {Tcl_LsortObjCmd procedure, -integer option} {
    lsort -integer {24 6 300 18}
} {6 18 24 300}
test cmdIL-1.16 {Tcl_LsortObjCmd procedure, -integer option} {
    list [catch {lsort -integer {1 3 2.4}} msg] $msg
} {1 {expected integer but got "2.4"}}
test cmdIL-1.17 {Tcl_LsortObjCmd procedure, -real option} {
    lsort -real {24.2 6e3 150e-1}
} {150e-1 24.2 6e3}
test cmdIL-1.18 {Tcl_LsortObjCmd procedure, bogus list} {
    list [catch {lsort "1 2 3 \{ 4"} msg] $msg
} {1 {unmatched open brace in list}}
test cmdIL-1.19 {Tcl_LsortObjCmd procedure, empty list} {
    lsort {}
} {}

# Can't think of any good tests for the MergeSort and MergeLists
# procedures, except a bunch of random lists to sort.

test cmdIL-2.1 {MergeSort and MergeLists procedures} {
247
248
249
250
251
252
253


































































} {ABcd abCD}
test cmdIL-4.22 {DictionaryCompare procedure, case} {
    lsort -dictionary {ABcd aBCd}
} {ABcd aBCd}
test cmdIL-4.23 {DictionaryCompare procedure, case} {
    lsort -dictionary {ABcd AbCd}
} {ABcd AbCd}









































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
} {ABcd abCD}
test cmdIL-4.22 {DictionaryCompare procedure, case} {
    lsort -dictionary {ABcd aBCd}
} {ABcd aBCd}
test cmdIL-4.23 {DictionaryCompare procedure, case} {
    lsort -dictionary {ABcd AbCd}
} {ABcd AbCd}
test cmdIL-4.24 {DictionaryCompare procedure, international characters} {hasIsoLocale} {
    ::tcltest::set_iso8859_1_locale
    set result [lsort -dictionary "a b c A B C \xe3 \xc4"]
    ::tcltest::restore_locale
    set result
} "A a B b C c \xe3 \xc4"
test cmdIL-4.25 {DictionaryCompare procedure, international characters} {hasIsoLocale} {
    ::tcltest::set_iso8859_1_locale
    set result [lsort -dictionary "a23\xe3 a23\xc5 a23\xe4"]
    ::tcltest::restore_locale
    set result
} "a23\xe3 a23\xe4 a23\xc5"
test cmdIL-4.26 {DefaultCompare procedure, signed characters} {
    set l [lsort [list "abc\200" "abc"]]
    set viewlist {}
    foreach s $l {
	set viewelem ""
	set len [string length $s]
	for {set i 0} {$i < $len} {incr i} {
	    set c [string index $s $i]
	    scan $c %c d
	    if {$d > 0 && $d < 128} {
		append viewelem $c
	    } else {
		append viewelem "\\[format %03o $d]"
	    }
	}
	lappend viewlist $viewelem
    }
    set viewlist
} [list "abc" "abc\\200"]
test cmdIL-4.27 {DictionaryCompare procedure, signed characters} {
    set l [lsort -dictionary [list "abc\200" "abc"]]
    set viewlist {}
    foreach s $l {
	set viewelem ""
	set len [string length $s]
	for {set i 0} {$i < $len} {incr i} {
	    set c [string index $s $i]
	    scan $c %c d
	    if {$d > 0 && $d < 128} {
		append viewelem $c
	    } else {
		append viewelem "\\[format %03o $d]"
	    }
	}
	lappend viewlist $viewelem
    }
    set viewlist
} [list "abc" "abc\\200"]

# cleanup
::tcltest::cleanupTests
return












Changes to tests/cmdInfo.test.

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
# Commands covered:  none
#
# This file contains a collection of tests for Tcl_GetCommandInfo,
# Tcl_SetCommandInfo, Tcl_CreateCommand, Tcl_DeleteCommand, and
# Tcl_NameOfCommand.  Sourcing this file into Tcl runs the tests
# and generates output for errors.  No output means no errors were
# found.
#
# Copyright (c) 1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) cmdInfo.test 1.10 97/06/20 14:51:12




if {[info commands testcmdinfo] == {}} {
    puts "This application hasn't been compiled with the \"testcmdinfo\""
    puts "command, so I can't test Tcl_GetCommandInfo etc."

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

test cmdinfo-1.1 {command procedure and clientData} {
    testcmdinfo create x1
    testcmdinfo get x1
} {CmdProc1 original CmdDelProc1 original :: stringProc}
test cmdinfo-1.2 {command procedure and clientData} {
    testcmdinfo create x1
    x1










>




>
|
>
>
>




>



<
<







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
# Commands covered:  none
#
# This file contains a collection of tests for Tcl_GetCommandInfo,
# Tcl_SetCommandInfo, Tcl_CreateCommand, Tcl_DeleteCommand, and
# Tcl_NameOfCommand.  Sourcing this file into Tcl runs the tests
# and generates output for errors.  No output means no errors were
# found.
#
# Copyright (c) 1993 The Regents of the University of California.
# 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: cmdInfo.test,v 1.1.2.6 1999/03/26 19:13:56 hershey Exp $

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

if {[info commands testcmdinfo] == {}} {
    puts "This application hasn't been compiled with the \"testcmdinfo\""
    puts "command, so I can't test Tcl_GetCommandInfo etc."
    ::tcltest::cleanupTests
    return
}



test cmdinfo-1.1 {command procedure and clientData} {
    testcmdinfo create x1
    testcmdinfo get x1
} {CmdProc1 original CmdDelProc1 original :: stringProc}
test cmdinfo-1.2 {command procedure and clientData} {
    testcmdinfo create x1
    x1
89
90
91
92
93
94
95

96
97


98











test cmdinfo-6.1 {Names for commands created when outside namespaces} {
    set x [testcmdtoken create cmdInfoNs1::cmdInfoNs2::testCmd]
    set y [testcmdtoken name $x]
    rename cmdInfoNs1::cmdInfoNs2::testCmd newTestCmd2
    eval lappend y [testcmdtoken name $x]
} {testCmd ::cmdInfoNs1::cmdInfoNs2::testCmd newTestCmd2 ::newTestCmd2}


catch {namespace delete cmdInfoNs1::cmdInfoNs2 cmdInfoNs1}
catch {rename x1 ""}


concat {}


















>


>
>
|
>
>
>
>
>
>
>
>
>
>
>
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
test cmdinfo-6.1 {Names for commands created when outside namespaces} {
    set x [testcmdtoken create cmdInfoNs1::cmdInfoNs2::testCmd]
    set y [testcmdtoken name $x]
    rename cmdInfoNs1::cmdInfoNs2::testCmd newTestCmd2
    eval lappend y [testcmdtoken name $x]
} {testCmd ::cmdInfoNs1::cmdInfoNs2::testCmd newTestCmd2 ::newTestCmd2}

# cleanup
catch {namespace delete cmdInfoNs1::cmdInfoNs2 cmdInfoNs1}
catch {rename x1 ""}
::tcltest::cleanupTests
return












Added tests/cmdMZ.test.











































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































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

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

# Tcl_PwdObjCmd

test cmdMZ-1.1 {Tcl_PwdObjCmd} {
    list [catch {pwd a} msg] $msg
} {1 {wrong # args: should be "pwd"}}
test cmdMZ-1.2 {Tcl_PwdObjCmd: simple pwd} {
    catch pwd
} 0
test cmdMZ-1.3 {Tcl_PwdObjCmd: simple pwd} {
    expr [string length pwd]>0
} 1
test cmdMZ-1.4 {Tcl_PwdObjCmd: failure} {unixOnly} {
    file delete -force foo
    file mkdir foo
    set cwd [pwd]
    cd foo
    file attr . -permissions 000
    set result [list [catch {pwd} msg] $msg]
    cd $cwd
    file delete -force foo
    set result
} {1 {error getting working directory name: permission denied}}

# The tests for Tcl_RegexpObjCmd, Tcl_RegsubObjCmd are in regexp.test

# Tcl_RenameObjCmd

test cmdMZ-2.1 {Tcl_RenameObjCmd: error conditions} {
    list [catch {rename r1} msg] $msg $errorCode
} {1 {wrong # args: should be "rename oldName newName"} NONE}
test cmdMZ-2.2 {Tcl_RenameObjCmd: error conditions} {
    list [catch {rename r1 r2 r3} msg] $msg $errorCode
} {1 {wrong # args: should be "rename oldName newName"} NONE}
test cmdMZ-2.3 {Tcl_RenameObjCmd: success} {
    catch {rename r2 {}}
    proc r1 {} {return "r1"}
    rename r1 r2
    r2
} {r1}
test cmdMZ-2.4 {Tcl_RenameObjCmd: success} {
    proc r1 {} {return "r1"}
    rename r1 {}
    list [catch {r1} msg] $msg
} {1 {invalid command name "r1"}}

# The tests for Tcl_ReturnObjCmd are in proc-old.test
# The tests for Tcl_ScanObjCmd are in scan.test

# Tcl_SourceObjCmd

test cmdMZ-3.1 {Tcl_SourceObjCmd: error conditions} {macOnly} {
    list [catch {source} msg] $msg
} {1 {wrong # args: should be "source fileName" or "source -rsrc name ?fileName?" or "source -rsrcid id ?fileName?"}}
test cmdMZ-3.2 {Tcl_SourceObjCmd: error conditions} {macOnly} {
    list [catch {source a b} msg] $msg
} {1 {wrong # args: should be "source fileName" or "source -rsrc name ?fileName?" or "source -rsrcid id ?fileName?"}}
test cmdMZ-3.3 {Tcl_SourceObjCmd: error conditions} {unixOrPc} {
    list [catch {source} msg] $msg
} {1 {wrong # args: should be "source fileName"}}
test cmdMZ-3.4 {Tcl_SourceObjCmd: error conditions} {unixOrPc} {
    list [catch {source a b} msg] $msg
} {1 {wrong # args: should be "source fileName"}}
test cmdMZ-3.5 {Tcl_SourceObjCmd: error in script} {
    makeFile {
	set x 146
	error "error in sourced file"
	set y $x
    } source.file
    list [catch {source source.file} msg] $msg $errorInfo
} {1 {error in sourced file} {error in sourced file
    while executing
"error "error in sourced file""
    (file "source.file" line 3)
    invoked from within
"source source.file"}}
test cmdMZ-3.6 {Tcl_SourceObjCmd: simple script} {
    makeFile {list result} source.file
    source source.file
} result

# Tcl_SplitObjCmd

test cmdMZ-4.1 {Tcl_SplitObjCmd: split errors} {
    list [catch split msg] $msg $errorCode
} {1 {wrong # args: should be "split string ?splitChars?"} NONE}
test cmdMZ-4.2 {Tcl_SplitObjCmd: split errors} {
    list [catch {split a b c} msg] $msg $errorCode
} {1 {wrong # args: should be "split string ?splitChars?"} NONE}
test cmdMZ-4.3 {Tcl_SplitObjCmd: basic split commands} {
    split "a\n b\t\r c\n "
} {a {} b {} {} c {} {}}
test cmdMZ-4.4 {Tcl_SplitObjCmd: basic split commands} {
    split "word 1xyzword 2zword 3" xyz
} {{word 1} {} {} {word 2} {word 3}}
test cmdMZ-4.5 {Tcl_SplitObjCmd: basic split commands} {
    split "12345" {}
} {1 2 3 4 5}
test cmdMZ-4.6 {Tcl_SplitObjCmd: basic split commands} {
    split "a\}b\[c\{\]\$"
} "a\\}b\\\[c\\{\\\]\\\$"
test cmdMZ-4.7 {Tcl_SplitObjCmd: basic split commands} {
    split {} {}
} {}
test cmdMZ-4.8 {Tcl_SplitObjCmd: basic split commands} {
    split {}
} {}
test cmdMZ-4.9 {Tcl_SplitObjCmd: basic split commands} {
    split {   }
} {{} {} {} {}}
test cmdMZ-4.10 {Tcl_SplitObjCmd: basic split commands} {
    proc foo {} {
        set x {}
        foreach f [split {]\n} {}] {
            append x $f
        }
        return $x	
    }
    foo
} {]\n}
test cmdMZ-4.11 {Tcl_SplitObjCmd: basic split commands} {
    proc foo {} {
        set x ab\000c
        set y [split $x {}]
        return $y
    }
    foo
} "a b \000 c"
test cmdMZ-4.12 {Tcl_SplitObjCmd: basic split commands} {
    split "a0ab1b2bbb3\000c4" ab\000c
} {{} 0 {} 1 2 {} {} 3 {} 4}
test cmdMZ-4.13 {Tcl_SplitObjCmd: basic split commands} {
    # if not UTF-8 aware, result is "a {} {} b qw\xe5 {} N wq"
    split "a\u4e4eb qw\u5e4e\x4e wq" " \u4e4e"
} "a b qw\u5e4eN wq"

# Tcl_StringObjCmd

test cmdMZ-5.1 {Tcl_StringObjCmd: error conditions} {
    list [catch {string} msg] $msg
} {1 {wrong # args: should be "string option arg ?arg ...?"}}
test cmdMZ-5.2 {Tcl_StringObjCmd: error conditions} {
    list [catch {string gorp a b} msg] $msg
} {1 {bad option "gorp": must be compare, first, index, last, length, match, range, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}

test cmdMZ-6.1 {Tcl_StringObjCmd: string compare} {
    list [catch {string compare a} msg] $msg
} {1 {wrong # args: should be "string compare string1 string2"}}
test cmdMZ-6.2 {Tcl_StringObjCmd: string compare} {
    list [catch {string compare a b c} msg] $msg
} {1 {wrong # args: should be "string compare string1 string2"}}
test cmdMZ-6.3 {Tcl_StringObjCmd: string compare} {
    string compare abcde abdef
} -1
test cmdMZ-6.4 {Tcl_StringObjCmd: string compare} {
    string c abcde ABCDE
} 1
test cmdMZ-6.5 {Tcl_StringObjCmd: string compare} {
    string compare abcde abcde
} 0
test cmdMZ-6.6 {Tcl_StringObjCmd: string compare} {
    string compare ab abcde
} -1
test cmdMZ-6.7 {Tcl_StringObjCmd: string compare} {
    string compare abcde ab
} 1
test cmdMZ-6.8 {Tcl_StringObjCmd: string compare} {
    string compare cde ab
} 1
test cmdMZ-6.9 {Tcl_StringObjCmd: string compare} {
    string compare ab cde
} -1
test cmdMZ-6.10 {Tcl_StringObjCmd: string compare, unicode} {
    string compare ab\u7266 ab\u7267
} -1
test cmdMZ-6.11 {Tcl_StringObjCmd: string compare, high bit} {
    # This test will fail if the underlying comparaison
    # is using signed chars instead of unsigned chars.
    # (like SunOS's default memcmp thus the compat/memcmp.c)
    string compare "\x80" "@"
    # Nb this tests works also in utf8 space because \x80 is
    # translated into a 2 or more bytes but whose first byte has
    # the high bit set.
} 1

test cmdMZ-7.1 {Tcl_StringObjCmd: string first} {
    list [catch {string first a} msg] $msg
} {1 {wrong # args: should be "string first string1 string2"}}
test cmdMZ-7.2 {Tcl_StringObjCmd: string first} {
    list [catch {string first a b c} msg] $msg
} {1 {wrong # args: should be "string first string1 string2"}}
test cmdMZ-7.3 {Tcl_StringObjCmd: string first} {
    string first bq abcdefgbcefgbqrs
} 12
test cmdMZ-7.4 {Tcl_StringObjCmd: string first} {
    string fir bcd abcdefgbcefgbqrs
} 1
test cmdMZ-7.5 {Tcl_StringObjCmd: string first} {
    string f b abcdefgbcefgbqrs
} 1
test cmdMZ-7.6 {Tcl_StringObjCmd: string first} {
    string first xxx x123xx345xxx789xxx012
} 9
test cmdMZ-7.7 {Tcl_StringObjCmd: string first} {
    string first "" x123xx345xxx789xxx012
} -1
test cmdMZ-7.8 {Tcl_StringObjCmd: string first, unicode} {
    string first x abc\u7266x
} 4
test cmdMZ-7.9 {Tcl_StringObjCmd: string first, unicode} {
    string first \u7266 abc\u7266x
} 3

test cmdMZ-8.1 {Tcl_StringObjCmd: string index} {
    list [catch {string index} msg] $msg
} {1 {wrong # args: should be "string index string charIndex"}}
test cmdMZ-8.2 {Tcl_StringObjCmd: string index} {
    list [catch {string index a b c} msg] $msg
} {1 {wrong # args: should be "string index string charIndex"}}
test cmdMZ-8.3 {Tcl_StringObjCmd: string index} {
    list [catch {string index a xyz} msg] $msg
} {1 {expected integer but got "xyz"}}
test cmdMZ-8.4 {Tcl_StringObjCmd: string index} {
    string index abcde 0
} a
test cmdMZ-8.5 {Tcl_StringObjCmd: string index} {
    string i abcde 4
} e
test cmdMZ-8.6 {Tcl_StringObjCmd: string index} {
    string index abcde 5
} {}
test cmdMZ-8.7 {Tcl_StringObjCmd: string index} {
    list [catch {string index abcde -10} msg] $msg
} {0 {}}
test cmdMZ-8.8 {Tcl_StringObjCmd: string index, unicode} {
    string index abc\u7266d 4
} d
test cmdMZ-8.9 {Tcl_StringObjCmd: string index, unicode} {
    string index abc\u7266d 3
} \u7266

test cmdMZ-9.1 {Tcl_StringObjCmd: string last} {
    list [catch {string last a} msg] $msg
} {1 {wrong # args: should be "string last string1 string2"}}
test cmdMZ-9.2 {Tcl_StringObjCmd: string last} {
    list [catch {string last a b c} msg] $msg
} {1 {wrong # args: should be "string last string1 string2"}}
test cmdMZ-9.3 {Tcl_StringObjCmd: string last} {
    string la xxx xxxx123xx345x678
} 1
test cmdMZ-9.4 {Tcl_StringObjCmd: string last} {
    string last xx xxxx123xx345x678
} 7
test cmdMZ-9.5 {Tcl_StringObjCmd: string last} {
    string las x xxxx123xx345x678
} 12
test cmdMZ-9.6 {Tcl_StringObjCmd: string last, unicode} {
    string las x xxxx12\u7266xx345x678
} 12
test cmdMZ-9.7 {Tcl_StringObjCmd: string last, unicode} {
    string las \u7266 xxxx12\u7266xx345x678
} 6

test cmdMZ-10.1 {Tcl_StringObjCmd: string length} {
    list [catch {string length} msg] $msg
} {1 {wrong # args: should be "string length string"}}
test cmdMZ-10.2 {Tcl_StringObjCmd: string length} {
    list [catch {string length a b} msg] $msg
} {1 {wrong # args: should be "string length string"}}
test cmdMZ-10.3 {Tcl_StringObjCmd: string length} {
    string length "a little string"
} 15
test cmdMZ-10.4 {Tcl_StringObjCmd: string length} {
    string le ""
} 0
test cmdMZ-10.5 {Tcl_StringObjCmd: string length, unicode} {
    string le "abcd\u7266"
} 5

test cmdMZ-11.1 {Tcl_StringObjCmd: string match} {
    list [catch {string match a} msg] $msg
} {1 {wrong # args: should be "string match pattern string"}}
test cmdMZ-11.2 {Tcl_StringObjCmd: string match} {
    list [catch {string match a b c} msg] $msg
} {1 {wrong # args: should be "string match pattern string"}}
test cmdMZ-11.3 {Tcl_StringObjCmd: string match} {
    string match abc abc
} 1
test cmdMZ-11.4 {Tcl_StringObjCmd: string match} {
    string m abc abd
} 0

test cmdMZ-12.1 {Tcl_StringObjCmd: string range} {
    list [catch {string range} msg] $msg
} {1 {wrong # args: should be "string range string first last"}}
test cmdMZ-12.2 {Tcl_StringObjCmd: string range} {
    list [catch {string range a 1} msg] $msg
} {1 {wrong # args: should be "string range string first last"}}
test cmdMZ-12.3 {Tcl_StringObjCmd: string range} {
    list [catch {string range a 1 2 3} msg] $msg
} {1 {wrong # args: should be "string range string first last"}}
test cmdMZ-12.4 {Tcl_StringObjCmd: string range} {
    list [catch {string range abc abc 1} msg] $msg
} {1 {bad index "abc": must be integer or "end"}}
test cmdMZ-12.5 {Tcl_StringObjCmd: string range} {
    list [catch {string range abc 1 eof} msg] $msg
} {1 {bad index "eof": must be integer or "end"}}
test cmdMZ-12.6 {Tcl_StringObjCmd: string range, first < 0} {
    string range abcdefghijklmnop -3 2
} {abc}
test cmdMZ-12.7 {Tcl_StringObjCmd: string range} {
    string range abcdefghijklmnop 2 14
} {cdefghijklmno}
test cmdMZ-12.8 {Tcl_StringObjCmd: string range, last > length} {
    string range abcdefghijklmnop 7 1000
} {hijklmnop}
test cmdMZ-12.9 {Tcl_StringObjCmd: string range} {
    string range abcdefghijklmnop 10 e
} {klmnop}
test cmdMZ-12.10 {Tcl_StringObjCmd: string range, last < first} {
    string range abcdefghijklmnop 10 9
} {}
test cmdMZ-12.11 {Tcl_StringObjCmd: string range} {
    string range abcdefghijklmnop -3 -2
} {}
test cmdMZ-12.12 {Tcl_StringObjCmd: string range} {
    string range abcdefghijklmnop 1000 1010
} {}
test cmdMZ-12.13 {Tcl_StringObjCmd: string range} {
    string range abcdefghijklmnop -100 end
} {abcdefghijklmnop}
test cmdMZ-12.14 {Tcl_StringObjCmd: string range} {
    string range abcdefghijklmnop end end
} {p}
test cmdMZ-12.15 {Tcl_StringObjCmd: string range} {
    string range abcdefghijklmnop e 1000
} {p}
test cmdMZ-12.16 {Tcl_StringObjCmd: string range, unicode} {
    string range ab\u7266cdefghijklmnop 5 5
} e
test cmdMZ-12.17 {Tcl_StringObjCmd: string range, unicode} {
    string range ab\u7266cdefghijklmnop 2 3
} \u7266c

test cmdMZ-13.1 {Tcl_StringObjCmd: string tolower} {
    list [catch {string tolower} msg] $msg
} {1 {wrong # args: should be "string tolower string"}}
test cmdMZ-13.2 {Tcl_StringObjCmd: string tolower} {
    list [catch {string tolower a b} msg] $msg
} {1 {wrong # args: should be "string tolower string"}}
test cmdMZ-13.3 {Tcl_StringObjCmd: string tolower} {
    string tolower ABCDeF
} {abcdef}
test cmdMZ-13.4 {Tcl_StringObjCmd: string tolower} {
    string tolower "ABC  XyZ"
} {abc  xyz}
test cmdMZ-13.5 {Tcl_StringObjCmd: string tolower} {
    string tolower {123#$&*()}
} {123#$&*()}
test cmdMZ-13.6 {Tcl_StringObjCmd: string tolower, unicode} {
     string tolower ABCabc\xc7\xe7
} "abcabc\xe7\xe7"

test cmdMZ-14.1 {Tcl_StringObjCmd: string toupper} {
    list [catch {string toupper} msg] $msg
} {1 {wrong # args: should be "string toupper string"}}
test cmdMZ-14.2 {Tcl_StringObjCmd: string toupper} {
    list [catch {string toupper a b} msg] $msg
} {1 {wrong # args: should be "string toupper string"}}
test cmdMZ-14.3 {Tcl_StringObjCmd: string toupper} {
    string toupper abCDEf
} {ABCDEF}
test cmdMZ-14.4 {Tcl_StringObjCmd: string toupper} {
    string toupper "abc xYz"
} {ABC XYZ}
test cmdMZ-14.5 {Tcl_StringObjCmd: string toupper} {
    string toupper {123#$&*()}
} {123#$&*()}
test cmdMZ-14.6 {Tcl_StringObjCmd: string toupper, unicode} {
    string toupper ABCabc\xc7\xe7
} "ABCABC\xc7\xc7"

test cmdMZ-15.1 {Tcl_StringObjCmd: string totitle} {
    list [catch {string totitle} msg] $msg
} {1 {wrong # args: should be "string totitle string"}}
test cmdMZ-15.2 {Tcl_StringObjCmd: string totitle} {
    list [catch {string totitle a b} msg] $msg
} {1 {wrong # args: should be "string totitle string"}}
test cmdMZ-15.3 {Tcl_StringObjCmd: string totitle} {
    string totitle abCDEf
} {Abcdef}
test cmdMZ-15.4 {Tcl_StringObjCmd: string totitle} {
    string totitle "abc xYz"
} {Abc xyz}
test cmdMZ-15.5 {Tcl_StringObjCmd: string totitle} {
    string totitle {123#$&*()}
} {123#$&*()}
test cmdMZ-15.6 {Tcl_StringObjCmd: string totitle, unicode} {
    string totitle ABCabc\xc7\xe7
} "Abcabc\xe7\xe7"
test cmdMZ-15.7 {Tcl_StringObjCmd: string totitle, unicode} {
    string totitle \u01f3BCabc\xc7\xe7
} "\u01f2bcabc\xe7\xe7"

test cmdMZ-16.1 {Tcl_StringObjCmd: string trim} {
    list [catch {string trim} msg] $msg
} {1 {wrong # args: should be "string trim string ?chars?"}}
test cmdMZ-16.2 {Tcl_StringObjCmd: string trim} {
    list [catch {string trim a b c} msg] $msg
} {1 {wrong # args: should be "string trim string ?chars?"}}
test cmdMZ-16.3 {Tcl_StringObjCmd: string trim} {
    string trim "    XYZ      "
} {XYZ}
test cmdMZ-16.4 {Tcl_StringObjCmd: string trim} {
    string trim "\t\nXYZ\t\n\r\n"
} {XYZ}
test cmdMZ-16.5 {Tcl_StringObjCmd: string trim} {
    string trim "  A XYZ A    "
} {A XYZ A}
test cmdMZ-16.6 {Tcl_StringObjCmd: string trim} {
    string trim "XXYYZZABC XXYYZZ" ZYX
} {ABC }
test cmdMZ-16.7 {Tcl_StringObjCmd: string trim} {
    string trim "    \t\r      "
} {}
test cmdMZ-16.8 {Tcl_StringObjCmd: string trim} {
    string trim {abcdefg} {}
} {abcdefg}
test cmdMZ-16.9 {Tcl_StringObjCmd: string trim} {
    string trim {}
} {}
test cmdMZ-16.10 {Tcl_StringObjCmd: string trim} {
    string trim ABC DEF
} {ABC}
test cmdMZ-16.11 {Tcl_StringObjCmd: string trim, unicode} {
    string trim "\xe7\xe8 AB\xe7C \xe8\xe7" \xe7\xe8
} " AB\xe7C "

test cmdMZ-17.1 {Tcl_StringObjCmd: string trimleft} {
    string trimleft "    XYZ      "
} {XYZ      }
test cmdMZ-17.2 {Tcl_StringObjCmd: string trimleft} {
    list [catch {string trimleft} msg] $msg
} {1 {wrong # args: should be "string trimleft string ?chars?"}}
test cmdMZ-17.3 {Tcl_StringObjCmd: string trimleft} {
    string length [string trimleft " "]
} {0}

test cmdMZ-18.1 {Tcl_StringObjCmd: string trimright} {
    string trimright "    XYZ      "
} {    XYZ}
test cmdMZ-18.2 {Tcl_StringObjCmd: string trimright} {
    string trimright "   "
} {}
test cmdMZ-18.3 {Tcl_StringObjCmd: string trimright} {
    string trimright ""
} {}
test cmdMZ-18.4 {Tcl_StringObjCmd: string trimright errors} {
    list [catch {string trimright} msg] $msg
} {1 {wrong # args: should be "string trimright string ?chars?"}}
test cmdMZ-18.5 {Tcl_StringObjCmd: string trimright errors} {
    list [catch {string trimg a} msg] $msg
} {1 {bad option "trimg": must be compare, first, index, last, length, match, range, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}

test cmdMZ-19.1 {Tcl_StringObjCmd: string wordend} {
    list [catch {string wordend a} msg] $msg
} {1 {wrong # args: should be "string wordend string index"}}
test cmdMZ-19.2 {Tcl_StringObjCmd: string wordend} {
    list [catch {string wordend a b c} msg] $msg
} {1 {wrong # args: should be "string wordend string index"}}
test cmdMZ-19.3 {Tcl_StringObjCmd: string wordend} {
    list [catch {string wordend a gorp} msg] $msg
} {1 {expected integer but got "gorp"}}
test cmdMZ-19.4 {Tcl_StringObjCmd: string wordend} {
    string wordend abc. -1
} 3
test cmdMZ-19.5 {Tcl_StringObjCmd: string wordend} {
    string wordend abc. 100
} 4
test cmdMZ-19.6 {Tcl_StringObjCmd: string wordend} {
    string wordend "word_one two three" 2
} 8
test cmdMZ-19.7 {Tcl_StringObjCmd: string wordend} {
    string wordend "one .&# three" 5
} 6
test cmdMZ-19.8 {Tcl_StringObjCmd: string wordend} {
    string worde "x.y" 0
} 1
test cmdMZ-19.9 {Tcl_StringObjCmd: string wordend, unicode} {
    string wordend "xyz\u00c7de fg" 0
} 6
test cmdMZ-19.10 {Tcl_StringObjCmd: string wordend, unicode} {
    string wordend "xyz\uc700de fg" 0
} 6
test cmdMZ-19.11 {Tcl_StringObjCmd: string wordend, unicode} {
    string wordend "xyz\u203fde fg" 0
} 6
test cmdMZ-19.12 {Tcl_StringObjCmd: string wordend, unicode} {
    string wordend "xyz\u2045de fg" 0
} 3
test cmdMZ-19.13 {Tcl_StringObjCmd: string wordend, unicode} {
    string wordend "\uc700\uc700 abc" 8
} 6

test cmdMZ-20.1 {Tcl_StringObjCmd: string wordstart} {
    list [catch {string word a} msg] $msg
} {1 {ambiguous option "word": must be compare, first, index, last, length, match, range, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
test cmdMZ-20.2 {Tcl_StringObjCmd: string wordstart} {
    list [catch {string wordstart a} msg] $msg
} {1 {wrong # args: should be "string wordstart string index"}}
test cmdMZ-20.3 {Tcl_StringObjCmd: string wordstart} {
    list [catch {string wordstart a b c} msg] $msg
} {1 {wrong # args: should be "string wordstart string index"}}
test cmdMZ-20.4 {Tcl_StringObjCmd: string wordstart} {
    list [catch {string wordstart a gorp} msg] $msg
} {1 {expected integer but got "gorp"}}
test cmdMZ-20.5 {Tcl_StringObjCmd: string wordstart} {
    string wordstart "one two three_words" 400
} 8
test cmdMZ-20.6 {Tcl_StringObjCmd: string wordstart} {
    string wordstart "one two three_words" 2
} 0
test cmdMZ-20.7 {Tcl_StringObjCmd: string wordstart} {
    string wordstart "one two three_words" -2
} 0
test cmdMZ-20.8 {Tcl_StringObjCmd: string wordstart} {
    string wordstart "one .*&^ three" 6
} 6
test cmdMZ-20.9 {Tcl_StringObjCmd: string wordstart} {
    string wordstart "one two three" 4
} 4
test cmdMZ-20.10 {Tcl_StringObjCmd: string wordstart, unicode} {
    string wordstart "one tw\u00c7o three" 7
} 4
test cmdMZ-20.11 {Tcl_StringObjCmd: string wordstart, unicode} {
    string wordstart "ab\uc700\uc700 cdef ghi" 12
} 10
test cmdMZ-20.12 {Tcl_StringObjCmd: string wordstart, unicode} {
    string wordstart "\uc700\uc700 abc" 8
} 3

# The tests for Tcl_SubstObjCmd are in subst.test
# The tests for Tcl_SwitchObjCmd are in switch.test
# There are no tests for Tcl_TimeObjCmd
# The tests for Tcl_TraceObjCmd and TraceVarProc are in trace.test
# The tests for Tcl_WhileObjCmd are in while.test

# cleanup
::tcltest::cleanupTests
return













Added tests/compExpr-old.test.































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
# Commands covered: expr
#
# This file contains the original set of tests for the compilation (and
# indirectly execution) of Tcl's expr command. A new set of tests covering
# the new implementation are in the files "parseExpr.test and
# "compExpr.test". Sourcing this file into Tcl runs the tests and generates
# output for errors. No output means no errors were found.
#
# Copyright (c) 1996-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: compExpr-old.test,v 1.1.2.4 1999/03/24 02:49:01 hershey Exp $

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

if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
    set gotT1 0
    puts "This application hasn't been compiled with the \"T1\" and"
    puts "\"T2\" math functions, so I'll skip some of the expr tests."
} else {
    set gotT1 1
}

# procedures used below

proc put_hello_char {c} {
    global a
    append a [format %c $c]
    return $c
}
proc hello_world {} {
    global a
    set a ""
    set L1 [set l0 [set h_1 [set q 0]]]
    for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
        :!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
        ?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
        [incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
        :[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
        ?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
        expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
    }
    set a
}

proc 12days {a b c} {
    global xxx
    expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \
	[expr 1-$b] [string range $c [12days -86 0 [string range $c 1 end]] \
	end]] end]]:1};expr {$a<$b?[12days [expr $a+1] $b $c]:3};expr {[12days \
	-94 [expr $a-27] $c]&&$a==2?$b<13?[12days 2 [expr $b+1] "%s %d %d\n"]:9
	:16}]:$a<0?$a<-72?[12days $b $a "@n'+,#'/*\{\}w+/w#cdnr/+,\{\}r/*de\}+,/*\{*+,/w\{%+,/w#q#n+,/#\{l+,/n\{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,\}\{w+K w'K:'+\}e#';dq#'l q#'+d'K#!/+k#;q#'r\}eKK#\}w'r\}eKK\{nl\]'/#;#q#n')\{)#\}w')\{)\{nl\]'/+#n';d\}rw' i;# )\{nl\]!/n\{n#'; r\{#w'r nc\{nl\]'/#\{l,+'K \{rw' iK\{;\[\{nl\]'/w#q#n'wk nw' iwk\{KK\{nl\]!/w\{%'l##w#' i; :\{nl\]'/*\{q#'ld;r'\}\{nlwb!/*de\}'c ;;\{nl'-\{\}rw\]'/+,\}##'*\}#nc,',#nw\]'/+kd'+e\}+;#'rdq#w! nr'/ ') \}+\}\{rl#'\{n' ')# \}'+\}##(!!/"]
	:$a<-50?[string compare [format %c $b] [string index $c 0]]==0?[append \
	xxx [string index $c 31];scan [string index $c 31] %c x;set x]
	:[12days -65 $b [string range $c 1 end]]:[12days [expr ([string compare \
	[string index $c 0] "/"]==0)+$a] $b [string range $c 1 end]]:0<$a
	?[12days 2 2 "%s"]:[string compare [string index $c 0] "/"]==0||
	[12days 0 [12days -61 [scan [string index $c 0] %c x; set x] \
	"!ek;dc i@bK'(q)-\[w\]*%n+r3#l,\{\}:\nuwloca-O;m .vpbks,fxntdCeghiry"] \
	[string range $c 1 end]]}
}
proc do_twelve_days {} {
    global xxx
    set xxx ""
    12days 1 1 1
    string length $xxx
}

# start of tests

catch {unset a b i x}

test expr-1.1 {TclCompileExprCmd: no expression} {
    list [catch {expr  } msg] $msg
} {1 {wrong # args: should be "expr arg ?arg ...?"}}
test expr-1.2 {TclCompileExprCmd: one expression word} {
    expr -25
} -25
test expr-1.3 {TclCompileExprCmd: two expression words} {
    expr -8.2   -6
} -14.2
test expr-1.4 {TclCompileExprCmd: five expression words} {
    expr 20 - 5 +10 -7
} 18
test expr-1.5 {TclCompileExprCmd: quoted expression word} {
    expr "0005"
} 5
test expr-1.6 {TclCompileExprCmd: quoted expression word} {
    catch {expr "0005"zxy} msg
    set msg
} {extra characters after close-quote}
test expr-1.7 {TclCompileExprCmd: expression word in braces} {
    expr {-0005}
} -5
test expr-1.8 {TclCompileExprCmd: expression word in braces} {
    expr {{-0x1234}}
} -4660
test expr-1.9 {TclCompileExprCmd: expression word in braces} {
    catch {expr {-0005}foo} msg
    set msg
} {extra characters after close-brace}
test expr-1.10 {TclCompileExprCmd: other expression word in braces} {
    expr 4*[llength "6 2"]
} 8
test expr-1.11 {TclCompileExprCmd: expression word terminated by ;} {
    expr 4*[llength "6 2"];
} 8
test expr-1.12 {TclCompileExprCmd: inlined expr (in "catch") inside other catch} {
    set a xxx
    catch {
	# Might not be a number
	set a [expr 10*$a]
    }
} 1
test expr-1.13 {TclCompileExprCmd: second level of substitutions in expr not in braces with single var reference} {
    set a xxx
    set x 27;  set bool {$x};  if $bool {set a foo}
    set a
} foo
test expr-1.14 {TclCompileExprCmd: second level of substitutions in expr with comparison as top-level operator} {
    set a xxx
    set x 2;  set b {$x};  set a [expr $b == 2]
    set a
} 1

test expr-2.1 {TclCompileExpr: are builtin functions registered?} {
    expr double(5*[llength "6 2"])
} 10.0
test expr-2.2 {TclCompileExpr: error in expr} {
    catch {expr 2**3} msg
    set msg
} {syntax error in expression "2**3"}
test expr-2.3 {TclCompileExpr: junk after legal expr} {
    catch {expr 7*[llength "a b"]foo} msg
    set msg
} {syntax error in expression "7*2foo"}
test expr-2.4 {TclCompileExpr: numeric expr string rep == formatted int rep} {
    expr {0001}
} 1

test expr-3.1 {CompileCondExpr: just lor expr} {expr 3||0} 1
test expr-3.2 {CompileCondExpr: error in lor expr} {
    catch {expr x||3} msg
    set msg
} {syntax error in expression "x||3"} 
test expr-3.3 {CompileCondExpr: test true arm} {expr 3>2?44:66} 44
test expr-3.4 {CompileCondExpr: error compiling true arm} {
    catch {expr 3>2?2**3:66} msg
    set msg
} {syntax error in expression "3>2?2**3:66"}
test expr-3.5 {CompileCondExpr: test false arm} {expr 2>3?44:66} 66
test expr-3.6 {CompileCondExpr: error compiling false arm} {
    catch {expr 2>3?44:2**3} msg
    set msg
} {syntax error in expression "2>3?44:2**3"}
test expr-3.7 {CompileCondExpr: long arms & nested cond exprs} {nonPortable} {
    puts "Note: doing test expr-3.7 which can take several minutes to run"
    hello_world
} {Hello world}
catch {unset xxx}
test expr-3.8 {CompileCondExpr: long arms & nested cond exprs} {nonPortable} {
    puts "Note: doing test expr-3.8 which can take several minutes to run"
    do_twelve_days
} 2358
catch {unset xxx}

test expr-4.1 {CompileLorExpr: just land expr} {expr 1.3&&3.3} 1
test expr-4.2 {CompileLorExpr: error in land expr} {
    catch {expr x&&3} msg
    set msg
} {syntax error in expression "x&&3"} 
test expr-4.3 {CompileLorExpr: simple lor exprs} {expr 0||1.0} 1
test expr-4.4 {CompileLorExpr: simple lor exprs} {expr 3.0||0.0} 1
test expr-4.5 {CompileLorExpr: simple lor exprs} {expr 0||0||1} 1
test expr-4.6 {CompileLorExpr: error compiling lor arm} {
    catch {expr 2**3||4.0} msg
    set msg
} {syntax error in expression "2**3||4.0"}
test expr-4.7 {CompileLorExpr: error compiling lor arm} {
    catch {expr 1.3||2**3} msg
    set msg
} {syntax error in expression "1.3||2**3"}
test expr-4.8 {CompileLorExpr: error compiling lor arms} {
    list [catch {expr {"a"||"b"}} msg] $msg
} {1 {expected boolean value but got "a"}}
test expr-4.9 {CompileLorExpr: long lor arm} {
    set a "abcdefghijkl"
    set i 7
    expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
} 1

test expr-5.1 {CompileLandExpr: just bitor expr} {expr 7|0x13} 23
test expr-5.2 {CompileLandExpr: error in bitor expr} {
    catch {expr x|3} msg
    set msg
} {syntax error in expression "x|3"} 
test expr-5.3 {CompileLandExpr: simple land exprs} {expr 0&&1.0} 0
test expr-5.4 {CompileLandExpr: simple land exprs} {expr 0&&0} 0
test expr-5.5 {CompileLandExpr: simple land exprs} {expr 3.0&&1.2} 1
test expr-5.6 {CompileLandExpr: simple land exprs} {expr 1&&1&&2} 1
test expr-5.7 {CompileLandExpr: error compiling land arm} {
    catch {expr 2**3&&4.0} msg
    set msg
} {syntax error in expression "2**3&&4.0"}
test expr-5.8 {CompileLandExpr: error compiling land arm} {
    catch {expr 1.3&&2**3} msg
    set msg
} {syntax error in expression "1.3&&2**3"}
test expr-5.9 {CompileLandExpr: error compiling land arm} {
    list [catch {expr {"a"&&"b"}} msg] $msg
} {1 {expected boolean value but got "a"}}
test expr-5.10 {CompileLandExpr: long land arms} {
    set a "abcdefghijkl"
    set i 7
    expr {[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]}
} 1

test expr-6.1 {CompileBitXorExpr: just bitand expr} {expr 7&0x13} 3
test expr-6.2 {CompileBitXorExpr: error in bitand expr} {
    catch {expr x|3} msg
    set msg
} {syntax error in expression "x|3"} 
test expr-6.3 {CompileBitXorExpr: simple bitxor exprs} {expr 7^0x13} 20
test expr-6.4 {CompileBitXorExpr: simple bitxor exprs} {expr 3^0x10} 19
test expr-6.5 {CompileBitXorExpr: simple bitxor exprs} {expr 0^7} 7
test expr-6.6 {CompileBitXorExpr: simple bitxor exprs} {expr -1^7} -8
test expr-6.7 {CompileBitXorExpr: error compiling bitxor arm} {
    catch {expr 2**3|6} msg
    set msg
} {syntax error in expression "2**3|6"}
test expr-6.8 {CompileBitXorExpr: error compiling bitxor arm} {
    catch {expr 2^x} msg
    set msg
} {syntax error in expression "2^x"}
test expr-6.9 {CompileBitXorExpr: runtime error in bitxor arm} {
    list [catch {expr {24.0^3}} msg] $msg
} {1 {can't use floating-point value as operand of "^"}}
test expr-6.10 {CompileBitXorExpr: runtime error in bitxor arm} {
    list [catch {expr {"a"^"b"}} msg] $msg
} {1 {can't use non-numeric string as operand of "^"}}

test expr-7.1 {CompileBitAndExpr: just equality expr} {expr 3==2} 0
test expr-7.2 {CompileBitAndExpr: just equality expr} {expr 2.0==2} 1
test expr-7.3 {CompileBitAndExpr: just equality expr} {expr 3.2!=2.2} 1
test expr-7.4 {CompileBitAndExpr: just equality expr} {expr {"abc" == "abd"}} 0
test expr-7.5 {CompileBitAndExpr: error in equality expr} {
    catch {expr x==3} msg
    set msg
} {syntax error in expression "x==3"} 
test expr-7.6 {CompileBitAndExpr: simple bitand exprs} {expr 7&0x13} 3
test expr-7.7 {CompileBitAndExpr: simple bitand exprs} {expr 0xf2&0x53} 82
test expr-7.8 {CompileBitAndExpr: simple bitand exprs} {expr 3&6} 2
test expr-7.9 {CompileBitAndExpr: simple bitand exprs} {expr -1&-7} -7
test expr-7.10 {CompileBitAndExpr: error compiling bitand arm} {
    catch {expr 2**3&6} msg
    set msg
} {syntax error in expression "2**3&6"}
test expr-7.11 {CompileBitAndExpr: error compiling bitand arm} {
    catch {expr 2&x} msg
    set msg
} {syntax error in expression "2&x"}
test expr-7.12 {CompileBitAndExpr: runtime error in bitand arm} {
    list [catch {expr {24.0&3}} msg] $msg
} {1 {can't use floating-point value as operand of "&"}}
test expr-7.13 {CompileBitAndExpr: runtime error in bitand arm} {
    list [catch {expr {"a"&"b"}} msg] $msg
} {1 {can't use non-numeric string as operand of "&"}}

test expr-8.1 {CompileEqualityExpr: just relational expr} {expr 3>=2} 1
test expr-8.2 {CompileEqualityExpr: just relational expr} {expr 2<=2.1} 1
test expr-8.3 {CompileEqualityExpr: just relational expr} {expr 3.2>"2.2"} 1
test expr-8.4 {CompileEqualityExpr: just relational expr} {expr {"0y"<"0x12"}} 0
test expr-8.5 {CompileEqualityExpr: error in relational expr} {
    catch {expr x>3} msg
    set msg
} {syntax error in expression "x>3"} 
test expr-8.6 {CompileEqualityExpr: simple equality exprs} {expr 7==0x13} 0
test expr-8.7 {CompileEqualityExpr: simple equality exprs} {expr -0xf2!=0x53} 1
test expr-8.8 {CompileEqualityExpr: simple equality exprs} {expr {"12398712938788234-1298379" != ""}} 1
test expr-8.9 {CompileEqualityExpr: simple equality exprs} {expr -1!="abc"} 1
test expr-8.10 {CompileEqualityExpr: error compiling equality arm} {
    catch {expr 2**3==6} msg
    set msg
} {syntax error in expression "2**3==6"}
test expr-8.11 {CompileEqualityExpr: error compiling equality arm} {
    catch {expr 2!=x} msg
    set msg
} {syntax error in expression "2!=x"}


test expr-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12
test expr-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63
test expr-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1
test expr-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8

# The following test is different for 32-bit versus 64-bit
# architectures because LONG_MIN is different

if {0x80000000 > 0} {
    test expr-9.5 {CompileRelationalExpr: shift expr producing LONG_MIN} {nonPortable} {
	expr {1<<63}
    } -9223372036854775808
} else {
    test expr-9.5 {CompileRelationalExpr: shift expr producing LONG_MIN} {nonPortable} {
	expr {1<<31}
    } -2147483648
}
test expr-9.6 {CompileRelationalExpr: error in shift expr} {
    catch {expr x>>3} msg
    set msg
} {syntax error in expression "x>>3"} 
test expr-9.7 {CompileRelationalExpr: simple relational exprs} {expr 0xff>=+0x3} 1
test expr-9.8 {CompileRelationalExpr: simple relational exprs} {expr -0xf2<0x3} 1
test expr-9.9 {CompileRelationalExpr: error compiling relational arm} {
    catch {expr 2**3>6} msg
    set msg
} {syntax error in expression "2**3>6"}
test expr-9.10 {CompileRelationalExpr: error compiling relational arm} {
    catch {expr 2<x} msg
    set msg
} {syntax error in expression "2<x"}

test expr-10.1 {CompileShiftExpr: just add expr} {expr 4+-2} 2
test expr-10.2 {CompileShiftExpr: just add expr} {expr 0xff-2} 253
test expr-10.3 {CompileShiftExpr: just add expr} {expr -1--2} 1
test expr-10.4 {CompileShiftExpr: just add expr} {expr 1-0123} -82
test expr-10.5 {CompileShiftExpr: error in add expr} {
    catch {expr x+3} msg
    set msg
} {syntax error in expression "x+3"}
test expr-10.6 {CompileShiftExpr: simple shift exprs} {expr 0xff>>0x3} 31
test expr-10.7 {CompileShiftExpr: simple shift exprs} {expr -0xf2<<0x3} -1936
test expr-10.8 {CompileShiftExpr: error compiling shift arm} {
    catch {expr 2**3>>6} msg
    set msg
} {syntax error in expression "2**3>>6"}
test expr-10.9 {CompileShiftExpr: error compiling shift arm} {
    catch {expr 2<<x} msg
    set msg
} {syntax error in expression "2<<x"}
test expr-10.10 {CompileShiftExpr: runtime error} {
    list [catch {expr {24.0>>43}} msg] $msg
} {1 {can't use floating-point value as operand of ">>"}}
test expr-10.11 {CompileShiftExpr: runtime error} {
    list [catch {expr {"a"<<"b"}} msg] $msg
} {1 {can't use non-numeric string as operand of "<<"}}

test expr-11.1 {CompileAddExpr: just multiply expr} {expr 4*-2} -8
test expr-11.2 {CompileAddExpr: just multiply expr} {expr 0xff%2} 1
test expr-11.3 {CompileAddExpr: just multiply expr} {expr -1/2} -1
test expr-11.4 {CompileAddExpr: just multiply expr} {expr 7891%0123} 6
test expr-11.5 {CompileAddExpr: error in multiply expr} {
    catch {expr x*3} msg
    set msg
} {syntax error in expression "x*3"}
test expr-11.6 {CompileAddExpr: simple add exprs} {expr 0xff++0x3} 258
test expr-11.7 {CompileAddExpr: simple add exprs} {expr -0xf2--0x3} -239
test expr-11.8 {CompileAddExpr: error compiling add arm} {
    catch {expr 2**3+6} msg
    set msg
} {syntax error in expression "2**3+6"}
test expr-11.9 {CompileAddExpr: error compiling add arm} {
    catch {expr 2-x} msg
    set msg
} {syntax error in expression "2-x"}
test expr-11.10 {CompileAddExpr: runtime error} {
    list [catch {expr {24.0+"xx"}} msg] $msg
} {1 {can't use non-numeric string as operand of "+"}}
test expr-11.11 {CompileAddExpr: runtime error} {
    list [catch {expr {"a"-"b"}} msg] $msg
} {1 {can't use non-numeric string as operand of "-"}}
test expr-11.12 {CompileAddExpr: runtime error} {
    list [catch {expr {3/0}} msg] $msg
} {1 {divide by zero}}
test expr-11.13 {CompileAddExpr: runtime error} {
    list [catch {expr {2.3/0.0}} msg] $msg
} {1 {divide by zero}}

test expr-12.1 {CompileMultiplyExpr: just unary expr} {expr ~4} -5
test expr-12.2 {CompileMultiplyExpr: just unary expr} {expr --5} 5
test expr-12.3 {CompileMultiplyExpr: just unary expr} {expr !27} 0
test expr-12.4 {CompileMultiplyExpr: just unary expr} {expr ~0xff00ff} -16711936
test expr-12.5 {CompileMultiplyExpr: error in unary expr} {
    catch {expr ~x} msg
    set msg
} {syntax error in expression "~x"}
test expr-12.6 {CompileMultiplyExpr: simple multiply exprs} {expr 0xff*0x3} 765
test expr-12.7 {CompileMultiplyExpr: simple multiply exprs} {expr -0xf2%-0x3} -2
test expr-12.8 {CompileMultiplyExpr: error compiling multiply arm} {
    catch {expr 2*3%%6} msg
    set msg
} {syntax error in expression "2*3%%6"}
test expr-12.9 {CompileMultiplyExpr: error compiling multiply arm} {
    catch {expr 2*x} msg
    set msg
} {syntax error in expression "2*x"}
test expr-12.10 {CompileMultiplyExpr: runtime error} {
    list [catch {expr {24.0*"xx"}} msg] $msg
} {1 {can't use non-numeric string as operand of "*"}}
test expr-12.11 {CompileMultiplyExpr: runtime error} {
    list [catch {expr {"a"/"b"}} msg] $msg
} {1 {can't use non-numeric string as operand of "/"}}

test expr-13.1 {CompileUnaryExpr: unary exprs} {expr -0xff} -255
test expr-13.2 {CompileUnaryExpr: unary exprs} {expr +000123} 83
test expr-13.3 {CompileUnaryExpr: unary exprs} {expr +--++36} 36
test expr-13.4 {CompileUnaryExpr: unary exprs} {expr !2} 0
test expr-13.5 {CompileUnaryExpr: unary exprs} {expr +--+-62.0} -62.0
test expr-13.6 {CompileUnaryExpr: unary exprs} {expr !0.0} 1
test expr-13.7 {CompileUnaryExpr: unary exprs} {expr !0xef} 0
test expr-13.8 {CompileUnaryExpr: error compiling unary expr} {
    catch {expr ~x} msg
    set msg
} {syntax error in expression "~x"}
test expr-13.9 {CompileUnaryExpr: error compiling unary expr} {
    catch {expr !1.x} msg
    set msg
} {syntax error in expression "!1.x"}
test expr-13.10 {CompileUnaryExpr: runtime error} {
    list [catch {expr {~"xx"}} msg] $msg
} {1 {can't use non-numeric string as operand of "~"}}
test expr-13.11 {CompileUnaryExpr: runtime error} {
    list [catch {expr ~4.0} msg] $msg
} {1 {can't use floating-point value as operand of "~"}}
test expr-13.12 {CompileUnaryExpr: just primary expr} {expr 0x123} 291
test expr-13.13 {CompileUnaryExpr: just primary expr} {
    set a 27
    expr $a
} 27
test expr-13.14 {CompileUnaryExpr: just primary expr} {
    expr double(27)
} 27.0
test expr-13.15 {CompileUnaryExpr: just primary expr} {expr "123"} 123
test expr-13.16 {CompileUnaryExpr: error in primary expr} {
    catch {expr [set]} msg
    set msg
} {wrong # args: should be "set varName ?newValue?"}
test expr-14.1 {CompilePrimaryExpr: literal primary} {expr 1} 1
test expr-14.2 {CompilePrimaryExpr: literal primary} {expr 123} 123
test expr-14.3 {CompilePrimaryExpr: literal primary} {expr 0xff} 255
test expr-14.4 {CompilePrimaryExpr: literal primary} {expr 00010} 8
test expr-14.5 {CompilePrimaryExpr: literal primary} {expr 62.0} 62.0
test expr-14.6 {CompilePrimaryExpr: literal primary} {
    expr 3.1400000
} 3.14
test expr-14.7 {CompilePrimaryExpr: literal primary} {expr {{abcde}<{abcdef}}} 1
test expr-14.8 {CompilePrimaryExpr: literal primary} {expr {{abc\
def} < {abcdef}}} 1
test expr-14.9 {CompilePrimaryExpr: literal primary} {expr {{abc\tde} > {abc\tdef}}} 0
test expr-14.10 {CompilePrimaryExpr: literal primary} {expr {{123}}} 123
test expr-14.11 {CompilePrimaryExpr: var reference primary} {
    set i 789
    list [expr {$i}] [expr $i]
} {789 789}
test expr-14.12 {CompilePrimaryExpr: var reference primary} {
    set i {789}    ;# test expr's aggressive conversion to numeric semantics
    list [expr {$i}] [expr $i]
} {789 789}
test expr-14.13 {CompilePrimaryExpr: var reference primary} {
    catch {unset a}
    set a(foo) foo
    set a(bar) bar
    set a(123) 123
    set result ""
    lappend result [expr $a(123)] [expr {$a(bar)<$a(foo)}]
    catch {unset a}
    set result
} {123 1}
test expr-14.14 {CompilePrimaryExpr: var reference primary} {
    set i 123    ;# test "$var.0" floating point conversion hack
    list [expr $i] [expr $i.0] [expr $i.0/12.0]
} {123 123.0 10.25}
test expr-14.15 {CompilePrimaryExpr: var reference primary} {
    set i 123
    catch {expr $i.2} msg
    set msg
} 123.2
test expr-14.16 {CompilePrimaryExpr: error compiling var reference primary} {
    catch {expr {$a(foo}} msg
    set errorInfo
} {missing )
    while compiling
"expr {$a(foo}"}
test expr-14.17 {CompilePrimaryExpr: string primary that looks like var ref} {
    expr $
} $
test expr-14.18 {CompilePrimaryExpr: quoted string primary} {
    expr "21"
} 21
test expr-14.19 {CompilePrimaryExpr: quoted string primary} {
    set i 123
    set x 456
    expr "$i+$x"
} 579
test expr-14.20 {CompilePrimaryExpr: quoted string primary} {
    set i 3
    set x 6
    expr 2+"$i.$x"
} 5.6
test expr-14.21 {CompilePrimaryExpr: error in quoted string primary} {
    catch {expr "[set]"} msg
    set msg
} {wrong # args: should be "set varName ?newValue?"}
test expr-14.22 {CompilePrimaryExpr: subcommand primary} {
    expr {[set i 123; set i]}
} 123
test expr-14.23 {CompilePrimaryExpr: error in subcommand primary} {
    catch {expr {[set]}} msg
    set errorInfo
} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    while compiling
"expr {[set]}"}
test expr-14.24 {CompilePrimaryExpr: error in subcommand primary} {
    catch {expr {[set i}} msg
    set errorInfo
} {missing close-bracket
    while compiling
"expr {[set i}"}
test expr-14.25 {CompilePrimaryExpr: math function primary} {
    format %.6g [expr exp(1.0)]
} 2.71828
test expr-14.26 {CompilePrimaryExpr: math function primary} {
    format %.6g [expr pow(2.0+0.1,3.0+0.1)]
} 9.97424
test expr-14.27 {CompilePrimaryExpr: error in math function primary} {
    catch {expr sinh::(2.0)} msg
    set errorInfo
} {syntax error in expression "sinh::(2.0)"
    while compiling
"expr sinh::(2.0)"}
test expr-14.28 {CompilePrimaryExpr: subexpression primary} {
    expr 2+(3*4)
} 14
test expr-14.29 {CompilePrimaryExpr: error in subexpression primary} {
    catch {expr 2+(3*[set])} msg
    set errorInfo
} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    while compiling
"expr 2+(3*[set])"}
test expr-14.30 {CompilePrimaryExpr: missing paren in subexpression primary} {
    catch {expr 2+(3*(4+5)} msg
    set errorInfo
} {syntax error in expression "2+(3*(4+5)"
    while compiling
"expr 2+(3*(4+5)"}
test expr-14.31 {CompilePrimaryExpr: just var ref in subexpression primary} {
    set i "5+10"
    list "[expr $i] == 15" "[expr ($i)] == 15" "[eval expr ($i)] == 15"
} {{15 == 15} {15 == 15} {15 == 15}}
test expr-14.32 {CompilePrimaryExpr: unexpected token} {
    catch {expr @} msg
    set errorInfo
} {syntax error in expression "@"
    while compiling
"expr @"}

test expr-15.1 {CompileMathFuncCall: missing parenthesis} {
    catch {expr sinh2.0)} msg
    set errorInfo
} {syntax error in expression "sinh2.0)"
    while compiling
"expr sinh2.0)"}
test expr-15.2 {CompileMathFuncCall: unknown math function} {
    catch {expr whazzathuh(1)} msg
    set errorInfo
} {unknown math function "whazzathuh"
    while compiling
"expr whazzathuh(1)"}
test expr-15.3 {CompileMathFuncCall: too many arguments} {
    catch {expr sin(1,2,3)} msg
    set errorInfo
} {too many arguments for math function
    while compiling
"expr sin(1,2,3)"}
test expr-15.4 {CompileMathFuncCall: ')' found before last required arg} {
    catch {expr sin()} msg
    set errorInfo
} {too few arguments for math function
    while compiling
"expr sin()"}
test expr-15.5 {CompileMathFuncCall: too few arguments} {
    catch {expr pow(1)} msg
    set errorInfo
} {too few arguments for math function
    while compiling
"expr pow(1)"}
test expr-15.6 {CompileMathFuncCall: missing ')'} {
    catch {expr sin(1} msg
    set errorInfo
} {syntax error in expression "sin(1"
    while compiling
"expr sin(1"}
if $gotT1 {
    test expr-15.7 {CompileMathFuncCall: call registered math function} {
	expr 2*T1()
    } 246
    test expr-15.8 {CompileMathFuncCall: call registered math function} {
	expr T2()*3
    } 1035

    test expr-15.9 {CompileMathFuncCall: call registered math function} {
	expr T3(21, 37)
    } 37
    test expr-15.10 {CompileMathFuncCall: call registered math function} {
	expr T3(21.2, 37)
    } 37.0
    test expr-15.11 {CompileMathFuncCall: call registered math function} {
	expr T3(-21.2, -17.5)
    } -17.5
}

test expr-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
    catch {unset a}
    set a(VALUE) ff15
    set i 123
    if {[expr 0x$a(VALUE)] & 16} {
        set i {}
    }
    set i
} {}
test expr-16.2 {GetToken: check for string literal in braces} {
    expr {{1}}
} {1}

# Check "expr" and computed command names.

test expr-17.1 {expr and computed command names} {
    set i 0
    set z expr
    $z 1+2
} 3

# Check correct conversion of operands to numbers: If the string looks like
# an integer, convert to integer. Otherwise, if the string looks like a
# double, convert to double.

test expr-18.1 {expr and conversion of operands to numbers} {
    set x [lindex 11 0]
    catch {expr int($x)}
    expr {$x}
} 11

# Check "expr" and interpreter result object resetting before appending
# an error msg during evaluation of exprs not in {}s

test expr-19.1 {expr and interpreter result object resetting} {
    proc p {} {
        set t  10.0
        set x  2.0
        set dx 0.2
        set f  {$dx-$x/10}
        set g  {-$x/5}
        set center 1.0
        set x  [expr $x-$center]
        set dx [expr $dx+$g]
        set x  [expr $x+$f+$center]
        set x  [expr $x+$f+$center]
        set y  [expr round($x)]
    }
    p
} 3

# cleanup
unset a
::tcltest::cleanupTests
return












Added tests/compExpr.test.









































































































































































































































































































































































































































































































































































































































































































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

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

if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
    set gotT1 0
    puts "This application hasn't been compiled with the \"T1\" and"
    puts "\"T2\" math functions, so I'll skip some of the expr tests."
} else {
    set gotT1 1
}

catch {unset a}

test compExpr-1.1 {TclCompileExpr procedure, successful expr parse and compile} {
    expr 1+2
} 3
test compExpr-1.2 {TclCompileExpr procedure, error parsing expr} {
    list [catch {expr 1+2+} msg] $msg
} {1 {syntax error in expression "1+2+"}}
test compExpr-1.3 {TclCompileExpr procedure, error compiling expr} {
    list [catch {expr "foo(123)"} msg] $msg
} {1 {unknown math function "foo"}}
test compExpr-1.4 {TclCompileExpr procedure, expr has no operators} {
    set a {000123}
    expr {$a}
} 83

test compExpr-2.1 {CompileSubExpr procedure, TCL_TOKEN_WORD parse token} {
    catch {unset a}
    set a 27
    expr {"foo$a" < "bar"}
} 0
test compExpr-2.2 {CompileSubExpr procedure, error compiling TCL_TOKEN_WORD parse token} {
    list [catch {expr {"00[expr 1+]" + 17}} msg] $msg
} {1 {syntax error in expression "1+"}}
test compExpr-2.3 {CompileSubExpr procedure, TCL_TOKEN_TEXT parse token} {
    expr {{12345}}
} 12345
test compExpr-2.4 {CompileSubExpr procedure, empty TCL_TOKEN_TEXT parse token} {
    expr {{}}
} {}
test compExpr-2.5 {CompileSubExpr procedure, TCL_TOKEN_BS parse token} {
    expr "\{  \\
 +123 \}"
} 123
test compExpr-2.6 {CompileSubExpr procedure, TCL_TOKEN_COMMAND parse token} {
    expr {[info tclversion] != ""}
} 1
test compExpr-2.7 {CompileSubExpr procedure, TCL_TOKEN_COMMAND parse token} {
    expr {[]}
} {}
test compExpr-2.8 {CompileSubExpr procedure, error in TCL_TOKEN_COMMAND parse token} {
    list [catch {expr {[foo "bar"xxx] + 17}} msg] $msg
} {1 {extra characters after close-quote}}
test compExpr-2.9 {CompileSubExpr procedure, TCL_TOKEN_VARIABLE parse token} {
    catch {unset a}
    set a 123
    expr {$a*2}
} 246
test compExpr-2.10 {CompileSubExpr procedure, TCL_TOKEN_VARIABLE parse token} {
    catch {unset a}
    catch {unset b}
    set a(george) martha
    set b geo
    expr {$a(${b}rge)}
} martha
test compExpr-2.11 {CompileSubExpr procedure, error in TCL_TOKEN_VARIABLE parse token} {
    catch {unset a}
    list [catch {expr {$a + 17}} msg] $msg
} {1 {can't read "a": no such variable}}
test compExpr-2.12 {CompileSubExpr procedure, TCL_TOKEN_SUB_EXPR parse token} {
    expr {27||3? 3<<(1+4) : 4&&9}
} 96
test compExpr-2.13 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} {
    catch {unset a}
    set a 15
    list [catch {expr {27 || "$a[expr 1+]00"}} msg] $msg
} {1 {syntax error in expression "1+"}}
test compExpr-2.14 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, op found} {
    expr {5*6}
} 30
test compExpr-2.15 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, math function found} {
    format %.6g [expr {sin(2.0)}]
} 0.909297
test compExpr-2.16 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, math function not found} {
    list [catch {expr {fred(2.0)}} msg] $msg
} {1 {unknown math function "fred"}}
test compExpr-2.17 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4*2}
} 8
test compExpr-2.18 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4/2}
} 2
test compExpr-2.19 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4%2}
} 0
test compExpr-2.20 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4<<2}
} 16
test compExpr-2.21 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4>>2}
} 1
test compExpr-2.22 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4<2}
} 0
test compExpr-2.23 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4>2}
} 1
test compExpr-2.24 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4<=2}
} 0
test compExpr-2.25 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4>=2}
} 1
test compExpr-2.26 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4==2}
} 0
test compExpr-2.27 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4!=2}
} 1
test compExpr-2.28 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4&2}
} 0
test compExpr-2.29 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4^2}
} 6
test compExpr-2.30 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
    expr {4|2}
} 6
test compExpr-2.31 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, 1 operand} {
    expr {!4}
} 0
test compExpr-2.32 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, 1 operand} {
    expr {~4}
} -5
test compExpr-2.33 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, comparison} {
    catch {unset a}
    set a 15
    expr {$a==15}  ;# compiled out-of-line to runtime call on Tcl_ExprObjCmd
} 1
test compExpr-2.34 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
    expr {+2}
} 2
test compExpr-2.35 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} {
    list [catch {expr {+[expr 1+]}} msg] $msg
} {1 {syntax error in expression "1+"}}
test compExpr-2.36 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
    expr {4+2}
} 6
test compExpr-2.37 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} {
    list [catch {expr {[expr 1+]+5}} msg] $msg
} {1 {syntax error in expression "1+"}}
test compExpr-2.38 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} {
    list [catch {expr {5+[expr 1+]}} msg] $msg
} {1 {syntax error in expression "1+"}}
test compExpr-2.39 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
    expr {-2}
} -2
test compExpr-2.40 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
    expr {4-2}
} 2
test compExpr-2.41 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
    catch {unset a}
    set a true
    expr {0||$a}
} 1
test compExpr-2.42 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} {
    catch {unset a}
    set a 15
    list [catch {expr {27 || "$a[expr 1+]00"}} msg] $msg
} {1 {syntax error in expression "1+"}}
test compExpr-2.43 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
    catch {unset a}
    set a false
    expr {3&&$a}
} 0
test compExpr-2.44 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
    catch {unset a}
    set a false
    expr {$a||1? 1 : 0}
} 1
test compExpr-2.45 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} {
    catch {unset a}
    set a 15
    list [catch {expr {1? 54 : "$a[expr 1+]00"}} msg] $msg
} {1 {syntax error in expression "1+"}}

test compExpr-3.1 {CompileLandOrLorExpr procedure, numeric 1st operand} {
    catch {unset a}
    set a 2
    expr {[set a]||0}
} 1
test compExpr-3.2 {CompileLandOrLorExpr procedure, nonnumeric 1st operand} {
    catch {unset a}
    set a no
    expr {$a&&1}
} 0
test compExpr-3.3 {CompileSubExpr procedure, error in 1st operand} {
    list [catch {expr {[expr *2]||0}} msg] $msg
} {1 {syntax error in expression "*2"}}
test compExpr-3.4 {CompileLandOrLorExpr procedure, result is 1 or 0} {
    catch {unset a}
    catch {unset b}
    set a no
    set b true
    expr {$a || $b}
} 1
test compExpr-3.5 {CompileLandOrLorExpr procedure, short-circuit semantics} {
    catch {unset a}
    set a yes
    expr {$a || [exit]}
} 1
test compExpr-3.6 {CompileLandOrLorExpr procedure, short-circuit semantics} {
    catch {unset a}
    set a no
    expr {$a && [exit]}
} 0
test compExpr-3.7 {CompileLandOrLorExpr procedure, numeric 2nd operand} {
    catch {unset a}
    set a 2
    expr {0||[set a]}
} 1
test compExpr-3.8 {CompileLandOrLorExpr procedure, nonnumeric 2nd operand} {
    catch {unset a}
    set a no
    expr {1&&$a}
} 0
test compExpr-3.9 {CompileLandOrLorExpr procedure, error in 2nd operand} {
    list [catch {expr {0||[expr %2]}} msg] $msg
} {1 {syntax error in expression "%2"}}
test compExpr-3.10 {CompileLandOrLorExpr procedure, long lor/land arm} {
    set a "abcdefghijkl"
    set i 7
    expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
} 1

test compExpr-4.1 {CompileCondExpr procedure, simple test} {
    catch {unset a}
    set a 2
    expr {($a > 1)? "ok" : "nope"}
} ok
test compExpr-4.2 {CompileCondExpr procedure, complex test, convert to numeric} {
    catch {unset a}
    set a no
    expr {[set a]? 27 : -54}
} -54
test compExpr-4.3 {CompileCondExpr procedure, error in test} {
    list [catch {expr {[expr *2]? +1 : -1}} msg] $msg
} {1 {syntax error in expression "*2"}}
test compExpr-4.4 {CompileCondExpr procedure, simple "true" clause} {
    catch {unset a}
    set a no
    expr {1? (27-2) : -54}
} 25
test compExpr-4.5 {CompileCondExpr procedure, convert "true" clause to numeric} {
    catch {unset a}
    set a no
    expr {1? $a : -54}
} no
test compExpr-4.6 {CompileCondExpr procedure, error in "true" clause} {
    list [catch {expr {1? [expr *2] : -127}} msg] $msg
} {1 {syntax error in expression "*2"}}
test compExpr-4.7 {CompileCondExpr procedure, simple "false" clause} {
    catch {unset a}
    set a no
    expr {(2-2)? -3.14159 : "nope"}
} nope
test compExpr-4.8 {CompileCondExpr procedure, convert "false" clause to numeric} {
    catch {unset a}
    set a 00123
    expr {0? 42 : $a}
} 83
test compExpr-4.9 {CompileCondExpr procedure, error in "false" clause} {
    list [catch {expr {1? 15 : [expr *2]}} msg] $msg
} {1 {syntax error in expression "*2"}}

test compExpr-5.1 {CompileMathFuncCall procedure, math function found} {
    format %.6g [expr atan2(1.0, 2.0)]
} 0.463648
test compExpr-5.2 {CompileMathFuncCall procedure, math function not found} {
    list [catch {expr {do_it()}} msg] $msg
} {1 {unknown math function "do_it"}}
if $gotT1 {
    test compExpr-5.3 {CompileMathFuncCall: call registered math function} {
	expr 3*T1()-1
    } 368
    test compExpr-5.4 {CompileMathFuncCall: call registered math function} {
	expr T2()*3
    } 1035
}
test compExpr-5.5 {CompileMathFuncCall procedure, too few arguments} {
    list [catch {expr {atan2(1.0)}} msg] $msg
} {1 {too few arguments for math function}}
test compExpr-5.6 {CompileMathFuncCall procedure, complex argument} {
    format %.6g [expr pow(2.1, 27.5-(24.4*(5%2)))]
} 9.97424
test compExpr-5.7 {CompileMathFuncCall procedure, error in argument} {
    list [catch {expr {sinh(2.*)}} msg] $msg
} {1 {syntax error in expression "sinh(2.*)"}}
test compExpr-5.8 {CompileMathFuncCall procedure, too many arguments} {
    list [catch {expr {sinh(2.0, 3.0)}} msg] $msg
} {1 {too many arguments for math function}}
test compExpr-5.9 {CompileMathFuncCall procedure, too many arguments} {
    list [catch {expr {0 <= rand(5.2)}} msg] $msg
} {1 {too many arguments for math function}}

test compExpr-6.1 {LogSyntaxError procedure, error in expr longer than 60 chars} {
    list [catch {expr {(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)/} -1 foo 3} msg] $msg
} {1 {syntax error in expression "(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+012"}}

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












Changes to tests/compile.test.

1
2
3
4
5
6
7

8
9
10
11

12


13
14
15
16
17
18
19
20
21
# This file contains tests for the file tclCompile.c.
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) compile.test 1.7 97/08/12 13:34:13



if {[string compare test [info procs test]] == 1} then {source defs}

# The following tests are very incomplete, although the rest of the
# test suite covers this file fairly well.

catch {rename p ""}
catch {namespace delete test_ns_compile}
catch {unset x}







>




>
|
>
>
|
<







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

18
19
20
21
22
23
24
# This file contains tests for the file tclCompile.c.
#
# 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: compile.test,v 1.1.2.6 1999/03/24 02:49:02 hershey Exp $

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


# The following tests are very incomplete, although the rest of the
# test suite covers this file fairly well.

catch {rename p ""}
catch {namespace delete test_ns_compile}
catch {unset x}
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















    proc p {} {
        set ::a(1) 1
        return $::a($::a(1))
    }
    list [p] $::a(1) [expr {[lsearch -exact [info globals] a] != 0}]
} {1 1 1}















































test compile-3.1 {TclCompileSetCmd: global scalar names with ::s} {
    catch {unset x}
    catch {unset y}
    set x 123
    proc p {} {
        set ::y 789
        return $::y
    }
    list $::x [expr {[lsearch -exact [info globals] x] != 0}] \
         [p] $::y [expr {[lsearch -exact [info globals] y] != 0}]
} {123 1 789 789 1}
test compile-3.2 {TclCompileSetCmd: global array names with ::s} {
    catch {unset a}
    set ::a(1) 2
    proc p {} {
        set ::a(1) 1
        return $::a($::a(1))
    }
    list $::a(1) [p] [set ::a($::a(1)) 3] $::a(1) [expr {[lsearch -exact [info globals] a] != 0}]
} {2 1 3 3 1}
test compile-3.3 {TclCompileSetCmd: namespace var names with ::s} {
    catch {namespace delete test_ns_compile}
    catch {unset x}
    namespace eval test_ns_compile {
        variable v hello
        variable arr
        set ::x $::test_ns_compile::v
	set ::test_ns_compile::arr(1) 123
    }
    list $::x $::test_ns_compile::arr(1)
} {hello 123}












test compile-4.1 {CollectArgInfo: binary data} {
    list [catch "string length \000foo" msg] $msg
} {0 4}
test compile-4.2 {CollectArgInfo: binary data} {
    list [catch "string length foo\000" msg] $msg
} {0 4}
test compile-4.3 {CollectArgInfo: handle "]" at end of command properly} {
    set x ]
} {]}

test compile-5.1 {UpdateStringOfByteCode: called for duplicate of compiled empty object} {
    proc p {} {
        set x {}
        eval $x
        append x { }
        eval $x
    }
    p
} {}












catch {rename p ""}
catch {namespace delete test_ns_compile}
catch {unset x}
catch {unset y}
catch {unset a}






















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










|








|











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


|


|



|









>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    proc p {} {
        set ::a(1) 1
        return $::a($::a(1))
    }
    list [p] $::a(1) [expr {[lsearch -exact [info globals] a] != 0}]
} {1 1 1}

test compile-3.1 {TclCompileCatchCmd: only catch cmds with scalar vars are compiled inline} {
    catch {unset a}
    set a(1) xyzzyx
    proc p {} {
        global a
        catch {set x 123} a(1)
    }
    list [p] $a(1)
} {0 123}
test compile-3.2 {TclCompileCatchCmd: non-local variables} {
    set ::foo 1
    proc catch-test {} {
	catch {set x 3} ::foo
    }
    catch-test
    set ::foo
} 3

test compile-4.1 {TclCompileForCmd: command substituted test expression} {
    set i 0
    set j 0
    # Should be "forever"
    for {} [expr $i < 3] {} {
	set j [incr i]
	if {$j > 3} break
    }
    set j
} {4}

test compile-5.1 {TclCompileForeachCmd: exception stack} {
    proc foreach-exception-test {} {
	foreach array(index) [list 1 2 3] break
	foreach array(index) [list 1 2 3] break
	foreach scalar [list 1 2 3] break
    }
    list [catch foreach-exception-test result] $result
} {0 {}}
test compile-5.2 {TclCompileForeachCmd: non-local variables} {
    set ::foo 1
    proc foreach-test {} {
	foreach ::foo {1 2 3} {}
    }
    foreach-test
    set ::foo
} 3

test compile-6.1 {TclCompileSetCmd: global scalar names with ::s} {
    catch {unset x}
    catch {unset y}
    set x 123
    proc p {} {
        set ::y 789
        return $::y
    }
    list $::x [expr {[lsearch -exact [info globals] x] != 0}] \
         [p] $::y [expr {[lsearch -exact [info globals] y] != 0}]
} {123 1 789 789 1}
test compile-6.2 {TclCompileSetCmd: global array names with ::s} {
    catch {unset a}
    set ::a(1) 2
    proc p {} {
        set ::a(1) 1
        return $::a($::a(1))
    }
    list $::a(1) [p] [set ::a($::a(1)) 3] $::a(1) [expr {[lsearch -exact [info globals] a] != 0}]
} {2 1 3 3 1}
test compile-6.3 {TclCompileSetCmd: namespace var names with ::s} {
    catch {namespace delete test_ns_compile}
    catch {unset x}
    namespace eval test_ns_compile {
        variable v hello
        variable arr
        set ::x $::test_ns_compile::v
	set ::test_ns_compile::arr(1) 123
    }
    list $::x $::test_ns_compile::arr(1)
} {hello 123}

test compile-7.1 {TclCompileWhileCmd: command substituted test expression} {
    set i 0
    set j 0
    # Should be "forever"
    while [expr $i < 3] {
	set j [incr i]
	if {$j > 3} break
    }
    set j
} {4}

test compile-8.1 {CollectArgInfo: binary data} {
    list [catch "string length \000foo" msg] $msg
} {0 4}
test compile-8.2 {CollectArgInfo: binary data} {
    list [catch "string length foo\000" msg] $msg
} {0 4}
test compile-8.3 {CollectArgInfo: handle "]" at end of command properly} {
    set x ]
} {]}

test compile-9.1 {UpdateStringOfByteCode: called for duplicate of compiled empty object} {
    proc p {} {
        set x {}
        eval $x
        append x { }
        eval $x
    }
    p
} {}

test compile-10.1 {BLACKBOX: exception stack overflow} {
    set x {{0}}
    set y 0
    while {$y < 100} {
	if !$x {incr y}
    }
} {}



# cleanup
catch {rename p ""}
catch {namespace delete test_ns_compile}
catch {unset x}
catch {unset y}
catch {unset a}
::tcltest::cleanupTests
return













Changes to tests/concat.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  concat
#
# 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-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) concat.test 1.10 96/12/20 18:53:31



if {[string compare test [info procs test]] == 1} then {source defs}

test concat-1.1 {simple concatenation} {
    concat a b c d e f g
} {a b c d e f g}
test concat-1.2 {merging lists together} {
    concat a {b c d} {e f g h}
} {a b c d e f g h}








>




>
|
>
>
|
<







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
# Commands covered:  concat
#
# 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-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: concat.test,v 1.1.2.5 1999/03/24 02:49:02 hershey Exp $

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


test concat-1.1 {simple concatenation} {
    concat a b c d e f g
} {a b c d e f g}
test concat-1.2 {merging lists together} {
    concat a {b c d} {e f g h}
} {a b c d e f g h}
40
41
42
43
44
45
46
















} {a b c}
test concat-4.2 {pruning off extra white space} {
    concat x y "  a b c	\n\t  " "   "  " def "
} {x y a b c def}
test concat-4.3 {pruning off extra white space sets length correctly} {
    llength [concat { {{a}} }]
} 1























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
} {a b c}
test concat-4.2 {pruning off extra white space} {
    concat x y "  a b c	\n\t  " "   "  " def "
} {x y a b c def}
test concat-4.3 {pruning off extra white space sets length correctly} {
    llength [concat { {{a}} }]
} 1

# cleanup
::tcltest::cleanupTests
return












Changes to tests/dcall.test.

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
















# Commands covered:  none
#
# This file contains a collection of tests for Tcl_CallWhenDeleted.
# Sourcing this file into Tcl runs the tests and generates output for
# errors.  No output means no errors were found.
#
# Copyright (c) 1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) dcall.test 1.6 96/02/16 08:55:44




if {[info commands testdcall] == {}} {
    puts "This application hasn't been compiled with the \"testdcall\""
    puts "command, so I can't test Tcl_CallWhenDeleted."

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

test dcall-1.1 {deletion callbacks} {
    lsort -increasing [testdcall 1 2 3]
} {1 2 3}
test dcall-1.2 {deletion callbacks} {
    testdcall
} {}
test dcall-1.3 {deletion callbacks} {
    lsort -increasing [testdcall 20 21 22 -22]
} {20 21}
test dcall-1.4 {deletion callbacks} {
    lsort -increasing [testdcall 20 21 22 -20]
} {21 22}
test dcall-1.5 {deletion callbacks} {
    lsort -increasing [testdcall 20 21 22 -21]
} {20 22}
test dcall-1.6 {deletion callbacks} {
    lsort -increasing [testdcall 20 21 22 -21 -22 -20]
} {}
























>




>
|
>
>
>




>



<
<


















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# Commands covered:  none
#
# This file contains a collection of tests for Tcl_CallWhenDeleted.
# Sourcing this file into Tcl runs the tests and generates output for
# errors.  No output means no errors were found.
#
# Copyright (c) 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: dcall.test,v 1.1.2.6 1999/03/26 19:13:57 hershey Exp $

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

if {[info commands testdcall] == {}} {
    puts "This application hasn't been compiled with the \"testdcall\""
    puts "command, so I can't test Tcl_CallWhenDeleted."
    ::tcltest::cleanupTests
    return
}



test dcall-1.1 {deletion callbacks} {
    lsort -increasing [testdcall 1 2 3]
} {1 2 3}
test dcall-1.2 {deletion callbacks} {
    testdcall
} {}
test dcall-1.3 {deletion callbacks} {
    lsort -increasing [testdcall 20 21 22 -22]
} {20 21}
test dcall-1.4 {deletion callbacks} {
    lsort -increasing [testdcall 20 21 22 -20]
} {21 22}
test dcall-1.5 {deletion callbacks} {
    lsort -increasing [testdcall 20 21 22 -21]
} {20 22}
test dcall-1.6 {deletion callbacks} {
    lsort -increasing [testdcall 20 21 22 -21 -22 -20]
} {}

# cleanup
::tcltest::cleanupTests
return












Deleted tests/defs.

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

if ![info exists VERBOSE] {
    set VERBOSE 0
}
if ![info exists TESTS] {
    set TESTS {}
}

# If tests are being run as root, issue a warning message and set a
# variable to prevent some tests from running at all.

set user {}
if {$tcl_platform(platform) == "unix"} {
    catch {set user [exec whoami]}
    if {$user == ""} {
        catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
    }
    if {$user == ""} {set user root}
    if {$user == "root"} {
        puts stdout "Warning: you're executing as root.  I'll have to"
        puts stdout "skip some of the tests, since they'll fail as root."
	set testConfig(root) 1
    }
}

# Some of the tests don't work on some system configurations due to
# differences in word length, file system configuration, etc.  In order
# to prevent false alarms, these tests are generally only run in the
# master development directory for Tcl.  The presence of a file
# "doAllTests" in this directory is used to indicate that the non-portable
# tests should be run.

# If there is no "memory" command (because memory debugging isn't
# enabled), generate a dummy command that does nothing.

if {[info commands memory] == ""} {
    proc memory args {}
}

# Check configuration information that will determine which tests
# to run.  To do this, create an array testConfig.  Each element
# has a 0 or 1 value, and the following elements are defined:
#	unixOnly -	1 means this is a UNIX platform, so it's OK
#			to run tests that only work under UNIX.
#	macOnly -	1 means this is a Mac platform, so it's OK
#			to run tests that only work on Macs.
#	pcOnly -	1 means this is a PC platform, so it's OK to
#			run tests that only work on PCs.
#	unixOrPc -	1 means this is a UNIX or PC platform.
#	macOrPc -	1 means this is a Mac or PC platform.
#	macOrUnix -	1 means this is a Mac or UNIX platform.
#	nonPortable -	1 means this the tests are being running in
#			the master Tcl/Tk development environment;
#			Some tests are inherently non-portable because
#			they depend on things like word length, file system
#			configuration, window manager, etc.  These tests
#			are only run in the main Tcl development directory
#			where the configuration is well known.  The presence
#			of the file "doAllTests" in this directory indicates
#			that it is safe to run non-portable tests.
#       knownBug -      The test is known to fail and the bug is not yet
#                       fixed. The test will be run only if the file
#                       "doBuggyTests" exists (intended for Tcl dev. group
#                       internal use only).
#	tempNotPc -	The inverse of pcOnly.  This flag is used to
#			temporarily disable a test.
#	tempNotMac -	The inverse of macOnly.  This flag is used to
#			temporarily disable a test.
#	nonBlockFiles - 1 means this platform supports setting files into
#			nonblocking mode.
#	asyncPipeClose- 1 means this platform supports async flush and
#			async close on a pipe.
#	unixExecs     - 1 means this machine has commands such as 'cat',
#			'echo' etc available.
#	notIfCompiled -	1 means this that it is safe to run tests that
#                       might fail if the bytecode compiler is used. This
#                       element is set 1 if the file "doAllTests" exists in
#                       this directory. Normally, this element is 0 so that
#                       tests that fail with the bytecode compiler are
#			skipped. As of 11/2/96 these are the history tests
#			since they depend on accurate source location
#			information.

catch {unset testConfig}
if {$tcl_platform(platform) == "unix"} {
    set testConfig(unixOnly) 1
    set testConfig(tempNotPc) 1
    set testConfig(tempNotMac) 1
} else {
    set testConfig(unixOnly) 0
} 
if {$tcl_platform(platform) == "macintosh"} {
    set testConfig(tempNotPc) 1
    set testConfig(macOnly) 1
} else {
    set testConfig(macOnly) 0
} 
if {$tcl_platform(platform) == "windows"} {
    set testConfig(tempNotMac) 1
    set testConfig(pcOnly) 1
} else {
    set testConfig(pcOnly) 0
}
set testConfig(unixOrPc) [expr $testConfig(unixOnly) || $testConfig(pcOnly)]
set testConfig(macOrPc) [expr $testConfig(macOnly) || $testConfig(pcOnly)]
set testConfig(macOrUnix) [expr $testConfig(macOnly) || $testConfig(unixOnly)]
set testConfig(nonPortable)	[expr [file exists doAllTests] || [file exists doAllTe]]
set testConfig(knownBug) [expr [file exists doBuggyTests] || [file exists doBuggyT]]
set testConfig(notIfCompiled) [file exists doAllCompilerTests]

set testConfig(unix)	$testConfig(unixOnly)
set testConfig(mac)	$testConfig(macOnly)
set testConfig(pc)	$testConfig(pcOnly)

set testConfig(nt)	[expr {$tcl_platform(os) == "Windows NT"}]
set testConfig(95)	[expr {$tcl_platform(os) == "Windows 95"}]
set testConfig(win32s)	[expr {$tcl_platform(os) == "Win32s"}]

# The following config switches are used to mark tests that crash on
# certain platforms, so that they can be reactivated again when the
# underlying problem is fixed.

set testConfig(pcCrash) $testConfig(macOrUnix)
set testConfig(macCrash) $testConfig(unixOrPc)
set testConfig(unixCrash) $testConfig(macOrPc)

if {[catch {set f [open defs r]}]} {
    set testConfig(nonBlockFiles) 1
} else {
    if {[expr [catch {fconfigure $f -blocking off}]] == 0} {
	set testConfig(nonBlockFiles) 1
    } else {
	set testConfig(nonBlockFiles) 0
    }
    close $f
}

trace variable testConfig r safeFetch

proc safeFetch {n1 n2 op} {
    global testConfig 

    if {($n2 != {}) && ([info exists testConfig($n2)] == 0)} {
	set testConfig($n2) 0
    }
}

# Test for SCO Unix - cannot run async flushing tests because a potential
# problem with select is apparently interfering. (Mark Diekhans).

if {$tcl_platform(platform) == "unix"} {
    if {[catch {exec uname -X | fgrep {Release = 3.2v}}] == 0} {
	set testConfig(asyncPipeClose) 0
    } else {
	set testConfig(asyncPipeClose) 1
    }
} else {
    set testConfig(asyncPipeClose) 1
}

# Test to see if execed commands such as cat, echo, rm and so forth are
# present on this machine.

set testConfig(unixExecs) 1
if {$tcl_platform(platform) == "macintosh"} {
    set testConfig(unixExecs) 0
}
if {($testConfig(unixExecs) == 1) && ($tcl_platform(platform) == "windows")} {
    if {[catch {exec cat defs}] == 1} {
	set testConfig(unixExecs) 0
    }
    if {($testConfig(unixExecs) == 1) && ([catch {exec echo hello}] == 1)} {
	set testConfig(unixExecs) 0
    }
    if {($testConfig(unixExecs) == 1) && \
		([catch {exec sh -c echo hello}] == 1)} {
	set testConfig(unixExecs) 0
    }
    if {($testConfig(unixExecs) == 1) && ([catch {exec wc defs}] == 1)} {
	set testConfig(unixExecs) 0
    }
    if {$testConfig(unixExecs) == 1} {
	exec echo hello > removeMe
        if {[catch {exec rm removeMe}] == 1} {
	    set testConfig(unixExecs) 0
	}
    }
    if {($testConfig(unixExecs) == 1) && ([catch {exec sleep 1}] == 1)} {
	set testConfig(unixExecs) 0
    }
    if {($testConfig(unixExecs) == 1) && \
		([catch {exec fgrep unixExecs defs}] == 1)} {
	set testConfig(unixExecs) 0
    }
    if {($testConfig(unixExecs) == 1) && ([catch {exec ps}] == 1)} {
	set testConfig(unixExecs) 0
    }
    if {($testConfig(unixExecs) == 1) && \
		([catch {exec echo abc > removeMe}] == 0) && \
		([catch {exec chmod 644 removeMe}] == 1) && \
		([catch {exec rm removeMe}] == 0)} {
	set testConfig(unixExecs) 0
    } else {
	catch {exec rm -f removeMe}
    }
    if {($testConfig(unixExecs) == 1) && \
		([catch {exec mkdir removeMe}] == 1)} {
	set testConfig(unixExecs) 0
    } else {
	catch {exec rm -r removeMe}
    }
    if {$testConfig(unixExecs) == 0} {
	puts stdout "Warning: Unix-style executables are not available, so"
	puts stdout "some tests will be skipped."
    }
}    

proc print_verbose {name description constraints script code answer} {
    puts stdout "\n"
    if {[string length $constraints]} {
	puts stdout "==== $name $description\t--- ($constraints) ---"
    } else {
	puts stdout "==== $name $description"
    }
    puts stdout "==== Contents of test case:"
    puts stdout "$script"
    if {$code != 0} {
	if {$code == 1} {
	    puts stdout "==== Test generated error:"
	    puts stdout $answer
	} elseif {$code == 2} {
	    puts stdout "==== Test generated return exception;  result was:"
	    puts stdout $answer
	} elseif {$code == 3} {
	    puts stdout "==== Test generated break exception"
	} elseif {$code == 4} {
	    puts stdout "==== Test generated continue exception"
	} else {
	    puts stdout "==== Test generated exception $code;  message was:"
	    puts stdout $answer
	}
    } else {
	puts stdout "==== Result was:"
	puts stdout "$answer"
    }
}

# test --
# This procedure runs a test and prints an error message if the
# test fails.  If VERBOSE has been set, it also prints a message
# even if the test succeeds.  The test will be skipped if it
# doesn't match the TESTS variable, or if one of the elements
# of "constraints" turns out not to be true.
#
# Arguments:
# name -		Name of test, in the form foo-1.2.
# description -		Short textual description of the test, to
#			help humans understand what it does.
# constraints -		A list of one or more keywords, each of
#			which must be the name of an element in
#			the array "testConfig".  If any of these
#			elements is zero, the test is skipped.
#			This argument may be omitted.
# script -		Script to run to carry out the test.  It must
#			return a result that can be checked for
#			correctness.
# answer -		Expected result from script.

proc test {name description script answer args} {
    global VERBOSE TESTS testConfig
    if {[string compare $TESTS ""] != 0} then {
	set ok 0
	foreach test $TESTS {
	    if [string match $test $name] then {
		set ok 1
		break
	    }
        }
	if !$ok then return
    }
    set i [llength $args]
    if {$i == 0} {
	set constraints {}
    } elseif {$i == 1} {
	# "constraints" argument exists;  shuffle arguments down, then
	# make sure that the constraints are satisfied.

	set constraints $script
	set script $answer
	set answer [lindex $args 0]
	set doTest 0
	if {[string match {*[$\[]*} $constraints] != 0} {
	    # full expression, e.g. {$foo > [info tclversion]}

	    catch {set doTest [uplevel #0 expr [list $constraints]]} msg
	} elseif {[regexp {[^.a-zA-Z0-9 ]+} $constraints] != 0} {
	    # something like {a || b} should be turned into 
	    # $testConfig(a) || $testConfig(b).

 	    regsub -all {[.a-zA-Z0-9]+} $constraints {$testConfig(&)} c
	    catch {set doTest [eval expr $c]}
	} else {
	    # just simple constraints such as {unixOnly fonts}.

	    set doTest 1
	    foreach constraint $constraints {
		if {![info exists testConfig($constraint)]
			|| !$testConfig($constraint)} {
		    set doTest 0
		    break
		}
	    }
	}
	if {$doTest == 0} {
	    if $VERBOSE then {
		puts stdout "++++ $name SKIPPED: $constraints"
	    }
	    return	
	}
    } else {
	error "wrong # args: must be \"test name description ?constraints? script answer\""
    }
    memory tag $name
    set code [catch {uplevel $script} result]
    if {$code != 0} {
	print_verbose $name $description $constraints $script \
		$code $result
    } elseif {[string compare $result $answer] == 0} then { 
	if $VERBOSE then {
	    if {$VERBOSE > 0} {
		print_verbose $name $description $constraints $script \
		    $code $result
	    }
	    if {$VERBOSE != -2} {
		puts stdout "++++ $name PASSED"
	    }
	}
    } else { 
	print_verbose $name $description $constraints $script \
		$code $result
	puts stdout "---- Result should have been:"
	puts stdout "$answer"
	puts stdout "---- $name FAILED" 
    }
}

proc dotests {file args} {
    global TESTS
    set savedTests $TESTS
    set TESTS $args
    source $file
    set TESTS $savedTests
}

proc normalizeMsg {msg} {
    regsub "\n$" [string tolower $msg] "" msg
    regsub -all "\n\n" $msg "\n" msg
    regsub -all "\n\}" $msg "\}" msg
    return $msg
}

proc makeFile {contents name} {
    set fd [open $name w]
    fconfigure $fd -translation lf
    if {[string index $contents [expr [string length $contents] - 1]] == "\n"} {
	puts -nonewline $fd $contents
    } else {
	puts $fd $contents
    }
    close $fd
}

proc removeFile {name} {
    file delete $name
}

proc makeDirectory {name} {
    file mkdir $name
}

proc removeDirectory {name} {
    file delete -force $name
}

proc viewFile {name} {
    global tcl_platform testConfig
    if {($tcl_platform(platform) == "macintosh") || \
		($testConfig(unixExecs) == 0)} {
	set f [open $name]
	set data [read -nonewline $f]
	close $f
	return $data
    } else {
	exec cat $name
    }
}

# Locate tcltest executable

set tcltest [info nameofexecutable]

if {$tcltest == "{}"} {
    set tcltest {}
    puts "Unable to find tcltest executable, multiple process tests will fail."
}

if {$tcl_platform(os) != "Win32s"} {
    # Don't even try running another copy of tcltest under win32s, or you 
    # get an error dialog about multiple instances.

    catch {
	file delete -force tmp
	set f [open tmp w]
	puts $f {
	    exit
	}
	close $f
	set f [open "|[list $tcltest tmp]" r]
	close $f
	set testConfig(stdio) 1
    }
}

if {($tcl_platform(platform) == "windows") && ($testConfig(stdio) == 0)} {
    puts "(will skip tests that redirect stdio of exec'd 32-bit applications)"
}

catch {socket} msg
set testConfig(socket) [expr {$msg != "sockets are not available on this system"}]

if {$testConfig(socket) == 0} {
    puts "(will skip tests that use sockets)"
}
    
        
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































































































































Added tests/defs.tcl.





























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
# defs.tcl --
#
#	This file contains support code for the Tcl/Tk test suite.It is
#	It is normally sourced by the individual files in the test suite
#	before they run their tests.  This improved approach to testing
#	was designed and initially implemented by Mary Ann May-Pumphrey
#	of Sun Microsystems.
#
# Copyright (c) 1990-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
# 
# RCS: @(#) $Id: defs.tcl,v 1.1.2.11 1999/04/07 01:59:27 hershey Exp $

# Initialize wish shell
if {[info exists tk_version]} {
    tk appname tktest
    wm title . tktest
} else {
    # Ensure that we have a minimal auto_path so we don't pick up extra junk.
    set auto_path [list [info library]]
}

# create the "tcltest" namespace for all testing variables and procedures
namespace eval tcltest {
    set procList [list test cleanupTests dotests saveState restoreState \
	    normalizeMsg makeFile removeFile makeDirectory removeDirectory \
	    viewFile bytestring set_iso8859_1_locale restore_locale \
	    safeFetch]
    if {[info exists tk_version]} {
	lappend procList setupbg dobg bgReady cleanupbg fixfocus
    }
    foreach proc $procList {
	namespace export $proc
    }

    # ::tcltest::verbose defaults to "b"
    variable verbose "b"

    # match defaults to the empty list
    variable match {}

    # skip defaults to the empty list
    variable skip {}

    # Tests should not rely on the current working directory.
    # Files that are part of the test suite should be accessed relative to
    # ::tcltest::testsDir.

    set originalDir [pwd]
    set tDir [file join $originalDir [file dirname [info script]]]
    cd $tDir
    variable testsDir [pwd]
    cd $originalDir

    # Count the number of files tested (0 if all.tcl wasn't called).
    # The all.tcl file will set testSingleFile to false, so stats will
    # not be printed until all.tcl calls the cleanupTests proc.
    # The currentFailure var stores the boolean value of whether the
    # current test file has had any failures.  The failFiles list
    # stores the names of test files that had failures.

    variable numTestFiles 0
    variable testSingleFile true
    variable currentFailure false
    variable failFiles {}

    # Tests should remove all files they create.  The test suite will
    # check the current working dir for files created by the tests.
    # ::tcltest::filesMade keeps track of such files created using the
    # ::tcltest::makeFile and ::tcltest::makeDirectory procedures.
    # ::tcltest::filesExisted stores the names of pre-existing files.

    variable filesMade {}
    variable filesExisted {}

    # ::tcltest::numTests will store test files as indices and the list
    # of files (that should not have been) left behind by the test files.
    array set ::tcltest::createdNewFiles {}

    # initialize ::tcltest::numTests array to keep track fo the number of
    # tests that pass, fial, and are skipped.
    array set numTests [list Total 0 Passed 0 Skipped 0 Failed 0]

    # initialize ::tcltest::skippedBecause array to keep track of
    # constraints that kept tests from running
    array set ::tcltest::skippedBecause {}
}

# If there is no "memory" command (because memory debugging isn't
# enabled), generate a dummy command that does nothing.

if {[info commands memory] == ""} {
    proc memory args {}
}

# ::tcltest::initConfig --
#
# Check configuration information that will determine which tests
# to run.  To do this, create an array ::tcltest::testConfig.  Each
# element has a 0 or 1 value.  If the element is "true" then tests
# with that constraint will be run, otherwise tests with that constraint
# will be skipped.  See the README file for the list of built-in
# constraints defined in this procedure.
#
# Arguments:
#	none
#
# Results:
#	The ::tcltest::testConfig array is reset to have an index for
#	each built-in test constraint.

proc ::tcltest::initConfig {} {

    global tcl_platform tcl_interactive tk_version

    catch {unset ::tcltest::testConfig}

    # The following trace procedure makes it so that we can safely refer to
    # non-existent members of the ::tcltest::testConfig array without causing an
    # error.  Instead, reading a non-existent member will return 0.  This is
    # necessary because tests are allowed to use constraint "X" without ensuring
    # that ::tcltest::testConfig("X") is defined.

    trace variable ::tcltest::testConfig r ::tcltest::safeFetch

    proc ::tcltest::safeFetch {n1 n2 op} {
	if {($n2 != {}) && ([info exists ::tcltest::testConfig($n2)] == 0)} {
	    set ::tcltest::testConfig($n2) 0
	}
    }

    set ::tcltest::testConfig(unixOnly) \
	    [expr {$tcl_platform(platform) == "unix"}]
    set ::tcltest::testConfig(macOnly) \
	    [expr {$tcl_platform(platform) == "macintosh"}]
    set ::tcltest::testConfig(pcOnly) \
	    [expr {$tcl_platform(platform) == "windows"}]

    set ::tcltest::testConfig(unix) $::tcltest::testConfig(unixOnly)
    set ::tcltest::testConfig(mac) $::tcltest::testConfig(macOnly)
    set ::tcltest::testConfig(pc) $::tcltest::testConfig(pcOnly)

    set ::tcltest::testConfig(unixOrPc) \
	    [expr {$::tcltest::testConfig(unix) || $::tcltest::testConfig(pc)}]
    set ::tcltest::testConfig(macOrPc) \
	    [expr {$::tcltest::testConfig(mac) || $::tcltest::testConfig(pc)}]
    set ::tcltest::testConfig(macOrUnix) \
	    [expr {$::tcltest::testConfig(mac) || $::tcltest::testConfig(unix)}]

    set ::tcltest::testConfig(nt) [expr {$tcl_platform(os) == "Windows NT"}]
    set ::tcltest::testConfig(95) [expr {$tcl_platform(os) == "Windows 95"}]

    # The following config switches are used to mark tests that should work,
    # but have been temporarily disabled on certain platforms because they don't
    # and we haven't gotten around to fixing the underlying problem.

    set ::tcltest::testConfig(tempNotPc) [expr {!$::tcltest::testConfig(pc)}]
    set ::tcltest::testConfig(tempNotMac) [expr {!$::tcltest::testConfig(mac)}]
    set ::tcltest::testConfig(tempNotUnix) [expr {!$::tcltest::testConfig(unix)}]

    # The following config switches are used to mark tests that crash on
    # certain platforms, so that they can be reactivated again when the
    # underlying problem is fixed.

    set ::tcltest::testConfig(pcCrash) [expr {!$::tcltest::testConfig(pc)}]
    set ::tcltest::testConfig(macCrash) [expr {!$::tcltest::testConfig(mac)}]
    set ::tcltest::testConfig(unixCrash) [expr {!$::tcltest::testConfig(unix)}]

    # Set the "fonts" constraint for wish apps
    if {[info exists tk_version]} {
	set ::tcltest::testConfig(fonts) 1
	catch {destroy .e}
	entry .e -width 0 -font {Helvetica -12} -bd 1
	.e insert end "a.bcd"
	if {([winfo reqwidth .e] != 37) || ([winfo reqheight .e] != 20)} {
	    set ::tcltest::testConfig(fonts) 0
	}
	destroy .e
	catch {destroy .t}
	text .t -width 80 -height 20 -font {Times -14} -bd 1
	pack .t
	.t insert end "This is\na dot."
	update
	set x [list [.t bbox 1.3] [.t bbox 2.5]]
	destroy .t
	if {[string match {{22 3 6 15} {31 18 [34] 15}} $x] == 0} {
	    set ::tcltest::testConfig(fonts) 0
	}
    }

    # Skip empty tests
    set ::tcltest::testConfig(emptyTest) 0

    # By default, tests that expost known bugs are skipped.
    set ::tcltest::testConfig(knownBug) 0

    # By default, non-portable tests are skipped.
    set ::tcltest::testConfig(nonPortable) 0

    # Some tests require user interaction.
    set ::tcltest::testConfig(userInteraction) 0

    # Some tests must be skipped if the interpreter is not in interactive mode
    set ::tcltest::testConfig(interactive) $tcl_interactive

    # Some tests must be skipped if you are running as root on Unix.
    # Other tests can only be run if you are running as root on Unix.
    set ::tcltest::testConfig(root) 0
    set ::tcltest::testConfig(notRoot) 1
    set user {}
    if {$tcl_platform(platform) == "unix"} {
	catch {set user [exec whoami]}
	if {$user == ""} {
	    catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
	}
	if {($user == "root") || ($user == "")} {
	    set ::tcltest::testConfig(root) 1
	    set ::tcltest::testConfig(notRoot) 0
	}
    }

    # Set nonBlockFiles constraint: 1 means this platform supports
    # setting files into nonblocking mode.
    if {[catch {set f [open defs r]}]} {
	set ::tcltest::testConfig(nonBlockFiles) 1
    } else {
	if {[catch {fconfigure $f -blocking off}] == 0} {
	    set ::tcltest::testConfig(nonBlockFiles) 1
	} else {
	    set ::tcltest::testConfig(nonBlockFiles) 0
	}
	close $f
    }

    # Set asyncPipeClose constraint: 1 means this platform supports
    # async flush and async close on a pipe.
    #
    # Test for SCO Unix - cannot run async flushing tests because a
    # potential problem with select is apparently interfering.
    # (Mark Diekhans).
    if {$tcl_platform(platform) == "unix"} {
	if {[catch {exec uname -X | fgrep {Release = 3.2v}}] == 0} {
	    set ::tcltest::testConfig(asyncPipeClose) 0
	} else {
	    set ::tcltest::testConfig(asyncPipeClose) 1
	}
    } else {
	set ::tcltest::testConfig(asyncPipeClose) 1
    }

    # Test to see if we have a broken version of sprintf with respect
    # to the "e" format of floating-point numbers.
    set ::tcltest::testConfig(eformat) 1
    if {[string compare "[format %g 5e-5]" "5e-05"] != 0} {
	set ::tcltest::testConfig(eformat) 0
    }

    # Test to see if execed commands such as cat, echo, rm and so forth are
    # present on this machine.
    set ::tcltest::testConfig(unixExecs) 1
    if {$tcl_platform(platform) == "macintosh"} {
	set ::tcltest::testConfig(unixExecs) 0
    }
    if {($::tcltest::testConfig(unixExecs) == 1) && \
	    ($tcl_platform(platform) == "windows")} {
	if {[catch {exec cat defs}] == 1} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec echo hello}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec sh -c echo hello}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec wc defs}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {$::tcltest::testConfig(unixExecs) == 1} {
	    exec echo hello > removeMe
	    if {[catch {exec rm removeMe}] == 1} {
		set ::tcltest::testConfig(unixExecs) 0
	    }
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec sleep 1}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec fgrep unixExecs defs}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec ps}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec echo abc > removeMe}] == 0) && \
		([catch {exec chmod 644 removeMe}] == 1) && \
		([catch {exec rm removeMe}] == 0)} {
	    set ::tcltest::testConfig(unixExecs) 0
	} else {
	    catch {exec rm -f removeMe}
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec mkdir removeMe}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	} else {
	    catch {exec rm -r removeMe}
	}
    }
}

::tcltest::initConfig


# ::tcltest::processCmdLineArgs --
#
#	Use command line args to set the verbose, skip, and
#	match variables.  This procedure must be run after
#	constraints are initialized, because some constraints can be
#	overridden.
#
# Arguments:
#	none
#
# Results:
#	::tcltest::verbose is set to <value>

proc ::tcltest::processCmdLineArgs {} {
    global argv

    # The "argv" var doesn't exist in some cases, so use {}
    # The "argv" var doesn't exist in some cases.
    if {(![info exists argv]) || ([llength $argv] < 2)} {
	set flagArray {}
    } else {
	set flagArray $argv
    }

    if {[catch {array set flag $flagArray}]} {
	puts stderr "Error:  odd number of command line args specified:"
	puts stderr "        $argv"
	exit
    }
    
    # Allow for 1-char abbreviations, where applicable (e.g., -match == -m).
    # Note that -verbose cannot be abbreviated to -v in wish because it
    # conflicts with the wish option -visual.
    foreach arg {-verbose -match -skip -constraints} {
	set abbrev [string range $arg 0 1]
	if {([info exists flag($abbrev)]) && \
		([lsearch -exact $flagArray $arg] < \
		[lsearch -exact $flagArray $abbrev])} {
	    set flag($arg) $flag($abbrev)
	}
    }

    # Set ::tcltest::workingDir to [pwd].
    # Save the names of files that already exist in ::tcltest::workingDir.
    set ::tcltest::workingDir [pwd]
    foreach file [glob -nocomplain [file join $::tcltest::workingDir *]] {
	lappend ::tcltest::filesExisted [file tail $file]
    }

    # Set ::tcltest::verbose to the arg of the -verbose flag, if given
    if {[info exists flag(-verbose)]} {
	set ::tcltest::verbose $flag(-verbose)
    }

    # Set ::tcltest::match to the arg of the -match flag, if given
    if {[info exists flag(-match)]} {
	set ::tcltest::match $flag(-match)
    }

    # Set ::tcltest::skip to the arg of the -skip flag, if given
    if {[info exists flag(-skip)]} {
	set ::tcltest::skip $flag(-skip)
    }

    # Use the -constraints flag, if given, to turn on constraints that are
    # turned off by default: userInteractive knownBug nonPortable.  This
    # code fragment must be run after constraints are initialized.
    if {[info exists flag(-constraints)]} {
	foreach elt $flag(-constraints) {
	    set ::tcltest::testConfig($elt) 1
	}
    }
}

::tcltest::processCmdLineArgs


# ::tcltest::cleanupTests --
#
# Remove files and dirs created using the makeFile and makeDirectory
# commands since the last time this proc was invoked.
#
# Print the names of the files created without the makeFile command
# since the tests were invoked.
#
# Print the number tests (total, passed, failed, and skipped) since the
# tests were invoked.
#

proc ::tcltest::cleanupTests {{calledFromAllFile 0}} {
    set tail [file tail [info script]]

    # Remove files and directories created by the :tcltest::makeFile and
    # ::tcltest::makeDirectory procedures.
    # Record the names of files in ::tcltest::workingDir that were not
    # pre-existing, and associate them with the test file that created them.
    if {!$calledFromAllFile} {

	foreach file $::tcltest::filesMade {
	    if {[file exists $file]} {
		catch {file delete -force $file}
	    }
	}
	set currentFiles {}
	foreach file [glob -nocomplain [file join $::tcltest::workingDir *]] {
	    lappend currentFiles [file tail $file]
	}
	set newFiles {}
	foreach file $currentFiles {
	    if {[lsearch -exact $::tcltest::filesExisted $file] == -1} {
		lappend newFiles $file
	    }
	}
	set ::tcltest::filesExisted $currentFiles
	if {[llength $newFiles] > 0} {
	    set ::tcltest::createdNewFiles($tail) $newFiles
	}
    }

    if {$calledFromAllFile || $::tcltest::testSingleFile} {
	# print stats
	puts -nonewline stdout "$tail:"
	foreach index [list "Total" "Passed" "Skipped" "Failed"] {
	    puts -nonewline stdout "\t$index\t$::tcltest::numTests($index)"
	}
	puts stdout ""

	# print number test files sourced
	# print names of files that ran tests which failed
	if {$calledFromAllFile} {
	    puts stdout "Sourced $::tcltest::numTestFiles Test Files."
	    set ::tcltest::numTestFiles 0
	    if {[llength $::tcltest::failFiles] > 0} {
		puts stdout "Files with failing tests: $::tcltest::failFiles"
		set ::tcltest::failFiles {}
	    }
	}

	# if any tests were skipped, print the constraints that kept them
	# from running.
	set constraintList [array names ::tcltest::skippedBecause]
	if {[llength $constraintList] > 0} {
	    puts stdout "Number of tests skipped for each constraint:"
	    foreach constraint [lsort $constraintList] {
		puts stdout \
			"\t$::tcltest::skippedBecause($constraint)\t$constraint"
		unset ::tcltest::skippedBecause($constraint)
	    }
	}

	# report the names of test files in ::tcltest::createdNewFiles, and
	# reset the array to be empty.
	set testFilesThatTurded [lsort [array names ::tcltest::createdNewFiles]]
	if {[llength $testFilesThatTurded] > 0} {
	    puts stdout "Warning: test files left files behind:"
	    foreach testFile $testFilesThatTurded {
		puts "\t$testFile:\t$::tcltest::createdNewFiles($testFile)"
		unset ::tcltest::createdNewFiles($testFile)
	    }
	}

	# reset filesMade, filesExisted, and numTests
	set ::tcltest::filesMade {}
	foreach index [list "Total" "Passed" "Skipped" "Failed"] {
	    set ::tcltest::numTests($index) 0
	}

	# exit only if running Tk in non-interactive mode
	global tk_version tcl_interactive
	if {[info exists tk_version] && !$tcl_interactive} {
	    exit
	}
    } else {
	# if we're deferring stat-reporting until all files are sourced,
	# then add current file to failFile list if any tests in this file
	# failed
	incr ::tcltest::numTestFiles
	if {($::tcltest::currentFailure) && \
		([lsearch -exact $::tcltest::failFiles $tail] == -1)} {
	    lappend ::tcltest::failFiles $tail
	}
	set ::tcltest::currentFailure false
    }
}


# test --
#
# This procedure runs a test and prints an error message if the test fails.
# If ::tcltest::verbose has been set, it also prints a message even if the
# test succeeds.  The test will be skipped if it doesn't match the
# ::tcltest::match variable, if it matches an element in
# ::tcltest::skip, or if one of the elements of "constraints" turns
# out not to be true.
#
# Arguments:
# name -		Name of test, in the form foo-1.2.
# description -		Short textual description of the test, to
#			help humans understand what it does.
# constraints -		A list of one or more keywords, each of
#			which must be the name of an element in
#			the array "::tcltest::testConfig".  If any of these
#			elements is zero, the test is skipped.
#			This argument may be omitted.
# script -		Script to run to carry out the test.  It must
#			return a result that can be checked for
#			correctness.
# expectedAnswer -	Expected result from script.

proc ::tcltest::test {name description script expectedAnswer args} {
    incr ::tcltest::numTests(Total)

    # skip the test if it's name matches an element of skip
    foreach pattern $::tcltest::skip {
	if {[string match $pattern $name]} {
	    incr ::tcltest::numTests(Skipped)
	    return
	}
    }
    # skip the test if it's name doesn't match any element of match
    if {[llength $::tcltest::match] > 0} {
	set ok 0
	foreach pattern $::tcltest::match {
	    if {[string match $pattern $name]} {
		set ok 1
		break
	    }
        }
	if {!$ok} {
	    incr ::tcltest::numTests(Skipped)
	    return
	}
    }
    set i [llength $args]
    if {$i == 0} {
	set constraints {}
    } elseif {$i == 1} {
	# "constraints" argument exists;  shuffle arguments down, then
	# make sure that the constraints are satisfied.

	set constraints $script
	set script $expectedAnswer
	set expectedAnswer [lindex $args 0]
	set doTest 0
	if {[string match {*[$\[]*} $constraints] != 0} {
	    # full expression, e.g. {$foo > [info tclversion]}

	    catch {set doTest [uplevel #0 expr $constraints]}
	} elseif {[regexp {[^.a-zA-Z0-9 ]+} $constraints] != 0} {
	    # something like {a || b} should be turned into 
	    # $::tcltest::testConfig(a) || $::tcltest::testConfig(b).

 	    regsub -all {[.a-zA-Z0-9]+} $constraints \
		    {$::tcltest::testConfig(&)} c
	    catch {set doTest [eval expr $c]}
	} else {
	    # just simple constraints such as {unixOnly fonts}.

	    set doTest 1
	    foreach constraint $constraints {
		if {![info exists ::tcltest::testConfig($constraint)]
			|| !$::tcltest::testConfig($constraint)} {
		    set doTest 0
		    # store the constraint that kept the test from running
		    set constraints $constraint
		    break
		}
	    }
	}
	if {$doTest == 0} {
	    incr ::tcltest::numTests(Skipped)
	    if {[string first s $::tcltest::verbose] != -1} {
		puts stdout "++++ $name SKIPPED: $constraints"
	    }
	    # add the constraint to the list of constraints the kept tests
	    # from running
	    if {[info exists ::tcltest::skippedBecause($constraints)]} {
		incr ::tcltest::skippedBecause($constraints)
	    } else {
		set ::tcltest::skippedBecause($constraints) 1
	    }
	    return	
	}
    } else {
	error "wrong # args: must be \"test name description ?constraints? script expectedAnswer\""
    }
    memory tag $name
    set code [catch {uplevel $script} actualAnswer]
    if {$code != 0 || [string compare $actualAnswer $expectedAnswer] != 0} {
	incr ::tcltest::numTests(Failed)
	set ::tcltest::currentFailure true
	if {[string first b $::tcltest::verbose] == -1} {
	    set script ""
	}
	puts stdout "\n==== $name $description FAILED"
	if {$script != ""} {
	    puts stdout "==== Contents of test case:"
	    puts stdout $script
	}
	if {$code != 0} {
	    if {$code == 1} {
		puts stdout "==== Test generated error:"
		puts stdout $actualAnswer
	    } elseif {$code == 2} {
		puts stdout "==== Test generated return exception;  result was:"
		puts stdout $actualAnswer
	    } elseif {$code == 3} {
		puts stdout "==== Test generated break exception"
	    } elseif {$code == 4} {
		puts stdout "==== Test generated continue exception"
	    } else {
		puts stdout "==== Test generated exception $code;  message was:"
		puts stdout $actualAnswer
	    }
	} else {
	    puts stdout "---- Result was:\n$actualAnswer"
	}
	puts stdout "---- Result should have been:\n$expectedAnswer"
	puts stdout "==== $name FAILED\n" 
    } else { 
	incr ::tcltest::numTests(Passed)
	if {[string first p $::tcltest::verbose] != -1} {
	    puts stdout "++++ $name PASSED"
	}
    }
}

# ::tcltest::dotests --
#
#	takes two arguments--the name of the test file (such
#	as "parse.test"), and a pattern selecting the tests you want to
#	execute.  It sets ::tcltest::matching to the second argument, calls
#	"source" on the file specified in the first argument, and restores
#	::tcltest::matching to its pre-call value at the end.
#
# Arguments:
#	file    name of tests file to source
#	args    pattern selecting the tests you want to execute
#
# Results:
#	none

proc ::tcltest::dotests {file args} {
    set savedTests $::tcltest::match
    set ::tcltest::match $args
    source $file
    set ::tcltest::match $savedTests
}

proc ::tcltest::openfiles {} {
    if {[catch {testchannel open} result]} {
	return {}
    }
    return $result
}

proc ::tcltest::leakfiles {old} {
    if {[catch {testchannel open} new]} {
        return {}
    }
    set leak {}
    foreach p $new {
    	if {[lsearch $old $p] < 0} {
	    lappend leak $p
	}
    }
    return $leak
}

set ::tcltest::saveState {}

proc ::tcltest::saveState {} {
    uplevel #0 {set ::tcltest::saveState [list [info procs] [info vars]]}
}

proc ::tcltest::restoreState {} {
    foreach p [info procs] {
	if {[lsearch [lindex $::tcltest::saveState 0] $p] < 0} {
	    rename $p {}
	}
    }
    foreach p [uplevel #0 {info vars}] {
	if {[lsearch [lindex $::tcltest::saveState 1] $p] < 0} {
	    uplevel #0 "unset $p"
	}
    }
}

proc ::tcltest::normalizeMsg {msg} {
    regsub "\n$" [string tolower $msg] "" msg
    regsub -all "\n\n" $msg "\n" msg
    regsub -all "\n\}" $msg "\}" msg
    return $msg
}

# makeFile --
#
# Create a new file with the name <name>, and write <contents> to it.
#
# If this file hasn't been created via makeFile since the last time
# cleanupTests was called, add it to the $filesMade list, so it will
# be removed by the next call to cleanupTests.
#
proc ::tcltest::makeFile {contents name} {
    set fd [open $name w]
    fconfigure $fd -translation lf
    if {[string index $contents [expr {[string length $contents] - 1}]] == "\n"} {
	puts -nonewline $fd $contents
    } else {
	puts $fd $contents
    }
    close $fd

    set fullName [file join [pwd] $name]
    if {[lsearch -exact $::tcltest::filesMade $fullName] == -1} {
	lappend ::tcltest::filesMade $fullName
    }
}

proc ::tcltest::removeFile {name} {
    file delete $name
}

# makeDirectory --
#
# Create a new dir with the name <name>.
#
# If this dir hasn't been created via makeDirectory since the last time
# cleanupTests was called, add it to the $directoriesMade list, so it will
# be removed by the next call to cleanupTests.
#
proc ::tcltest::makeDirectory {name} {
    file mkdir $name

    set fullName [file join [pwd] $name]
    if {[lsearch -exact $::tcltest::filesMade $fullName] == -1} {
	lappend ::tcltest::filesMade $fullName
    }
}

proc ::tcltest::removeDirectory {name} {
    file delete -force $name
}

proc ::tcltest::viewFile {name} {
    global tcl_platform
    if {($tcl_platform(platform) == "macintosh") || \
		($::tcltest::testConfig(unixExecs) == 0)} {
	set f [open $name]
	set data [read -nonewline $f]
	close $f
	return $data
    } else {
	exec cat $name
    }
}

#
# Construct a string that consists of the requested sequence of bytes,
# as opposed to a string of properly formed UTF-8 characters.  
# This allows the tester to 
# 1. Create denormalized or improperly formed strings to pass to C procedures 
#    that are supposed to accept strings with embedded NULL bytes.
# 2. Confirm that a string result has a certain pattern of bytes, for instance
#    to confirm that "\xe0\0" in a Tcl script is stored internally in 
#    UTF-8 as the sequence of bytes "\xc3\xa0\xc0\x80".
#
# Generally, it's a bad idea to examine the bytes in a Tcl string or to
# construct improperly formed strings in this manner, because it involves
# exposing that Tcl uses UTF-8 internally.

proc ::tcltest::bytestring {string} {
    encoding convertfrom identity $string
}

# Locate tcltest executable

if {![info exists tk_version]} {
    set tcltest [info nameofexecutable]

    if {$tcltest == "{}"} {
	set tcltest {}
    }
}

set ::tcltest::testConfig(stdio) 0
catch {
    catch {file delete -force tmp}
    set f [open tmp w]
    puts $f {
	exit
    }
    close $f

    set f [open "|[list $tcltest tmp]" r]
    close $f
    
    set ::tcltest::testConfig(stdio) 1
}
catch {file delete -force tmp}

# Deliberately call the socket with the wrong number of arguments.  The error
# message you get will indicate whether sockets are available on this system.
catch {socket} msg
set ::tcltest::testConfig(socket) \
	[expr {$msg != "sockets are not available on this system"}]

#
# Internationalization / ISO support procs     -- dl
#
if {[info commands testlocale]==""} {
    # No testlocale command, no tests...
    # (it could be that we are a sub interp and we could just load
    # the Tcltest package but that would interfere with tests
    # that tests packages/loading in slaves...)
    set ::tcltest::testConfig(hasIsoLocale) 0
} else {
    proc ::tcltest::set_iso8859_1_locale {} {
	set ::tcltest::previousLocale [testlocale ctype]
	testlocale ctype $::tcltest::isoLocale
    }

    proc ::tcltest::restore_locale {} {
	testlocale ctype $::tcltest::previousLocale
    }

    if {![info exists ::tcltest::isoLocale]} {
	set ::tcltest::isoLocale fr
        switch $tcl_platform(platform) {
	    "unix" {
		# Try some 'known' values for some platforms:
		switch -exact -- $tcl_platform(os) {
		    "FreeBSD" {
			set ::tcltest::isoLocale fr_FR.ISO_8859-1
		    }
		    HP-UX {
			set ::tcltest::isoLocale fr_FR.iso88591
		    }
		    Linux -
		    IRIX {
			set ::tcltest::isoLocale fr
		    }
		    default {
			# Works on SunOS 4 and Solaris, and maybe others...
			# define it to something else on your system
			#if you want to test those.
			set ::tcltest::isoLocale iso_8859_1
		    }
		}
	    }
	    "windows" {
		set ::tcltest::isoLocale French
	    }
	}
    }

    set ::tcltest::testConfig(hasIsoLocale) \
	    [string length [::tcltest::set_iso8859_1_locale]]
    ::tcltest::restore_locale
} 

#
# procedures that are Tk specific
#
if {[info exists tk_version]} {
    # If the main window isn't already mapped (e.g. because the tests are
    # being run automatically) , specify a precise size for it so that the
    # user won't have to position it manually.

    if {![winfo ismapped .]} {
	wm geometry . +0+0
	update
    }

    # The following code can be used to perform tests involving a second
    # process running in the background.
    
    # Locate the tktest executable

    set ::tcltest::tktest [info nameofexecutable]
    if {$::tcltest::tktest == "{}"} {
	set ::tcltest::tktest {}
	puts stdout \
		"Unable to find tktest executable, skipping multiple process tests."
    }

    # Create background process
    
    proc ::tcltest::setupbg args {
	if {$::tcltest::tktest == ""} {
	    error "you're not running tktest so setupbg should not have been called"
	}
	if {[info exists ::tcltest::fd] && ($::tcltest::fd != "")} {
	    cleanupbg
	}
	
	# The following code segment cannot be run on Windows in Tk8.1b2
	# This bug is logged as a pipe bug (bugID 1495).

	global tcl_platform
	if {$tcl_platform(platform) != "windows"} {
	    set ::tcltest::fd [open "|[list $::tcltest::tktest -geometry +0+0 -name tktest] $args" r+]
	    puts $::tcltest::fd "puts foo; flush stdout"
	    flush $::tcltest::fd
	    if {[gets $::tcltest::fd data] < 0} {
		error "unexpected EOF from \"$::tcltest::tktest\""
	    }
	    if {[string compare $data foo]} {
		error "unexpected output from background process \"$data\""
	    }
	    fileevent $::tcltest::fd readable bgReady
	}
    }
    
    # Send a command to the background process, catching errors and
    # flushing I/O channels
    proc ::tcltest::dobg {command} {
	puts $::tcltest::fd "catch [list $command] msg; update; puts \$msg; puts **DONE**; flush stdout"
	flush $::tcltest::fd
	set ::tcltest::bgDone 0
	set ::tcltest::bgData {}
	tkwait variable ::tcltest::bgDone
	set ::tcltest::bgData
    }

    # Data arrived from background process.  Check for special marker
    # indicating end of data for this command, and make data available
    # to dobg procedure.
    proc ::tcltest::bgReady {} {
	set x [gets $::tcltest::fd]
	if {[eof $::tcltest::fd]} {
	    fileevent $::tcltest::fd readable {}
	    set ::tcltest::bgDone 1
	} elseif {$x == "**DONE**"} {
	    set ::tcltest::bgDone 1
	} else {
	    append ::tcltest::bgData $x
	}
    }

    # Exit the background process, and close the pipes
    proc ::tcltest::cleanupbg {} {
	catch {
	    puts $::tcltest::fd "exit"
	    close $::tcltest::fd
	}
	set ::tcltest::fd ""
    }

    # Clean up focus after using generate event, which
    # can leave the window manager with the wrong impression
    # about who thinks they have the focus. (BW)
    
    proc ::tcltest::fixfocus {} {
	catch {destroy .focus}
	toplevel .focus
	wm geometry .focus +0+0
	entry .focus.e
	.focus.e insert 0 "fixfocus"
	pack .focus.e
	update
	focus -force .focus.e
	destroy .focus
    }
}

# Need to catch the import because it fails if defs.tcl is sourced
# more than once.
catch {namespace import ::tcltest::*}
return

Changes to tests/dstring.test.

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
# Commands covered:  none
#
# This file contains a collection of tests for Tcl's dynamic string
# library procedures.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) dstring.test 1.10 96/10/08 17:40:02




if {[info commands testdstring] == {}} {
    puts "This application hasn't been compiled with the \"testdstring\""
    puts "command, so I can't test Tcl_DStringAppend et al."

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

test dstring-1.1 {appending and retrieving} {
    testdstring free
    testdstring append "abc" -1
    list [testdstring get] [testdstring length]
} {abc 3}
test dstring-1.2 {appending and retrieving} {
    testdstring free








>




>
|
>
>
>




>



<
<







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
# Commands covered:  none
#
# This file contains a collection of tests for Tcl's dynamic string
# library procedures.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 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: dstring.test,v 1.1.2.6 1999/03/26 19:13:58 hershey Exp $

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

if {[info commands testdstring] == {}} {
    puts "This application hasn't been compiled with the \"testdstring\""
    puts "command, so I can't test Tcl_DStringAppend et al."
    ::tcltest::cleanupTests
    return
}



test dstring-1.1 {appending and retrieving} {
    testdstring free
    testdstring append "abc" -1
    list [testdstring get] [testdstring length]
} {abc 3}
test dstring-1.2 {appending and retrieving} {
    testdstring free
241
242
243
244
245
246
247

248














test dstring-6.5 {Tcl_DStringGetResult} {
    set result {}
    lappend result [testdstring gresult special]
    testdstring append z 1
    lappend result [testdstring get]
} {{} {This is a specially-allocated stringz}}


testdstring free





















>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
test dstring-6.5 {Tcl_DStringGetResult} {
    set result {}
    lappend result [testdstring gresult special]
    testdstring append z 1
    lappend result [testdstring get]
} {{} {This is a specially-allocated stringz}}

# cleanup
testdstring free
::tcltest::cleanupTests
return












Added tests/encoding.test.

























































































































































































































































































































































































































































































































































































































































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

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

proc toutf {args} {
    global x
    lappend x "toutf $args"
}
proc fromutf {args} {
    global x
    lappend x "fromutf $args"
}

# Some tests require the testencoding command

set ::tcltest::testConfig(testencoding) \
	[expr {[info commands testencoding] != {}}]


# TclInitEncodingSubsystem is tested by the rest of this file
# TclFinalizeEncodingSubsystem is not currently tested

test encoding-1.1 {Tcl_GetEncoding: system encoding} {testencoding} {
    testencoding create foo toutf fromutf
    set old [encoding system]
    encoding system foo
    set x {}
    encoding convertto abcd
    encoding system $old
    testencoding delete foo
    set x
} {{fromutf }}
test encoding-1.2 {Tcl_GetEncoding: existing encoding} {testencoding} {
    testencoding create foo toutf fromutf
    set x {}
    encoding convertto foo abcd
    testencoding delete foo
    set x
} {{fromutf }}
test encoding-1.3 {Tcl_GetEncoding: load encoding} {
    list [encoding convertto jis0208 \u4e4e] \
	[encoding convertfrom jis0208 8C]
} "8C \u4e4e"

test encoding-2.1 {Tcl_FreeEncoding: refcount == 0} {
    encoding convertto jis0208 \u4e4e
} {8C}
test encoding-2.2 {Tcl_FreeEncoding: refcount != 0} {testencoding} {
    set system [encoding system]
    set path [testencoding path]
    encoding system jis0208		;# incr ref count
    testencoding path .
    set x [encoding convertto jis0208 \u4e4e]	;# old one found   
    encoding system identity
    lappend x [catch {encoding convertto jis0208 \u4e4e} msg] $msg
    encoding system identity
    testencoding path $path
    encoding system $system
    set x
} {8C 1 {unknown encoding "jis0208"}}

test encoding-3.1 {Tcl_GetEncodingName, NULL} {
    set old [encoding system]
    encoding system jis0208
    set x [encoding system]
    encoding system $old
    set x
} {jis0208}
test encoding-3.2 {Tcl_GetEncodingName, non-null} {
    set old [fconfigure stdout -encoding]
    fconfigure stdout -encoding jis0208
    set x [fconfigure stdout -encoding]
    fconfigure stdout -encoding $old
    set x
} {jis0208}

test encoding-4.1 {Tcl_GetEncodingNames} {testencoding} {
    file mkdir tmp/encoding
    close [open tmp/encoding/junk.enc w]
    close [open tmp/encoding/junk2.enc w]
    cd tmp
    set path [testencoding path]
    testencoding path {}
    catch {unset encodings}
    catch {unset x}
    foreach encoding [encoding names] {
	set encodings($encoding) 1
    }
    testencoding path .
    foreach encoding [encoding names] {
	if {![info exists encodings($encoding)]} {
	    lappend x $encoding
	}
    }
    testencoding path $path
    cd ..
    file delete -force tmp
    lsort $x
} {junk junk2}

test encoding-5.1 {Tcl_SetSystemEncoding} {
    set old [encoding system]
    encoding system jis0208
    set x [encoding convertto \u4e4e]
    encoding system identity
    encoding system $old
    set x
} {8C}
test encoding-5.2 {Tcl_SetSystemEncoding: test ref count} {
    set old [encoding system]
    encoding system $old
    string compare $old [encoding system]
} {0}

test encoding-6.1 {Tcl_CreateEncoding: new} {testencoding} {
    testencoding create foo {toutf 1} {fromutf 2}
    set x {}
    encoding convertfrom foo abcd
    encoding convertto foo abcd
    testencoding delete foo
    set x
} {{toutf 1} {fromutf 2}}
test encoding-6.2 {Tcl_CreateEncoding: replace encoding} {testencoding} {
    testencoding create foo {toutf a} {fromutf b}
    set x {}
    encoding convertfrom foo abcd
    encoding convertto foo abcd
    testencoding delete foo
    set x
} {{toutf a} {fromutf b}}

test encoding-7.1 {Tcl_ExternalToUtfDString: small buffer} {
    encoding convertfrom jis0208 8c8c8c8c
} "\u543e\u543e\u543e\u543e"
test encoding-7.2 {Tcl_UtfToExternalDString: big buffer} {
    set a 8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C
    append a $a
    append a $a
    append a $a
    append a $a
    set x [encoding convertfrom jis0208 $a]
    list [string length $x] [string index $x 0]
} "512 \u4e4e"

test encoding-8.1 {Tcl_ExternalToUtf} {
    set f [open dummy w]
    fconfigure $f -translation binary -encoding iso8859-1
    puts -nonewline $f "ab\x8c\xc1g"
    close $f
    set f [open dummy r]
    fconfigure $f -translation binary -encoding shiftjis    
    set x [read $f]
    close $f
    file delete dummy
    set x
} "ab\u4e4eg"

test encoding-9.1 {Tcl_UtfToExternalDString: small buffer} {
    encoding convertto jis0208 "\u543e\u543e\u543e\u543e"
} {8c8c8c8c}
test encoding-9.2 {Tcl_UtfToExternalDString: big buffer} {
    set a \u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e
    append a $a
    append a $a
    append a $a
    append a $a
    append a $a
    append a $a
    set x [encoding convertto jis0208 $a]
    list [string length $x] [string range $x 0 1]
} "1024 8C"

test encoding-10.1 {Tcl_UtfToExternal} {
    set f [open dummy w]
    fconfigure $f -translation binary -encoding shiftjis
    puts -nonewline $f "ab\u4e4eg"
    close $f
    set f [open dummy r]
    fconfigure $f -translation binary -encoding iso8859-1
    set x [read $f]
    close $f
    file delete dummy
    set x
} "ab\x8c\xc1g"

test encoding-11.1 {LoadEncodingFile: unknown encoding} {testencoding} {
    set system [encoding system]
    set path [testencoding path]
    encoding system iso8859-1
    testencoding path {}
    set x [list [catch {encoding convertto jis0208 \u4e4e} msg] $msg]
    testencoding path $path
    encoding system $system
    lappend x [encoding convertto jis0208 \u4e4e]
} {1 {unknown encoding "jis0208"} 8C}
test encoding-11.2 {LoadEncodingFile: single-byte} {
    encoding convertfrom jis0201 \xa1
} "\uff61"
test encoding-11.3 {LoadEncodingFile: double-byte} {
    encoding convertfrom jis0208 8C
} "\u4e4e"
test encoding-11.4 {LoadEncodingFile: multi-byte} {
    encoding convertfrom shiftjis \x8c\xc1
} "\u4e4e"
test encoding-11.5 {LoadEncodingFile: escape file} {
    encoding convertto iso2022 \u4e4e
} "\x1b(B\x1b$@8C"
test encoding-11.6 {LoadEncodingFile: invalid file} {testencoding} {
    set system [encoding system]
    set path [testencoding path]
    encoding system identity
    testencoding path tmp
    file mkdir tmp/encoding
    set f [open tmp/encoding/splat.enc w]
    fconfigure $f -translation binary 
    puts $f "abcdefghijklmnop"
    close $f
    set x [list [catch {encoding convertto splat \u4e4e} msg] $msg]
    file delete -force tmp
    catch {file delete encoding}
    testencoding path $path
    encoding system $system
    set x
} {1 {invalid encoding file "splat"}}

# OpenEncodingFile is fully tested by the rest of the tests in this file.

test encoding-12.1 {LoadTableEncoding: normal encoding} {
    set x [encoding convertto iso8859-3 \u120]
    append x [encoding convertto iso8859-3 \ud5]
    append x [encoding convertfrom iso8859-3 \xd5]
} "\xd5?\u120"
test encoding-12.2 {LoadTableEncoding: single-byte encoding} {
    set x [encoding convertto iso8859-3 ab\u0120g] 
    append x [encoding convertfrom iso8859-3 ab\xd5g]
} "ab\xd5gab\u120g"
test encoding-12.3 {LoadTableEncoding: multi-byte encoding} {
    set x [encoding convertto shiftjis ab\u4e4eg] 
    append x [encoding convertfrom shiftjis ab\x8c\xc1g]
} "ab\x8c\xc1gab\u4e4eg"
test encoding-12.4 {LoadTableEncoding: double-byte encoding} {
    set x [encoding convertto jis0208 \u4e4e\u3b1]
    append x [encoding convertfrom jis0208 8C&A]
} "8C&A\u4e4e\u3b1"
test encoding-12.5 {LoadTableEncoding: symbol encoding} {
    set x [encoding convertto symbol \u3b3]
    append x [encoding convertto symbol \u67]
    append x [encoding convertfrom symbol \x67]
} "\x67\x67\u3b3"

test encoding-13.1 {LoadEscapeTable} {
    set x [encoding convertto iso2022 ab\u4e4e\u68d9g]
} "\x1b(Bab\x1b$@8C\x1b$(DD%\x1b(Bg"

test encoding-14.1 {BinaryProc} {
    encoding convertto identity \x12\x34\x56\xff\x69
} "\x12\x34\x56\xc3\xbf\x69"

test encoding-15.1 {UtfToUtfProc} {
    encoding convertto utf-8 \xa3
} "\xc2\xa3"

test encoding-16.1 {UnicodeToUtfProc} {
    encoding convertfrom unicode NN
} "\u4e4e"

test encoding-17.1 {UtfToUnicodeProc} {
} {}

test encoding-18.1 {TableToUtfProc} {
} {}

test encoding-19.1 {TableFromUtfProc} {
} {}

test encoding-20.1 {TableFreefProc} {
} {}

test encoding-21.1 {EscapeToUtfProc} {
} {}

test encoding-22.1 {EscapeFromUtfProc} {
} {}

# EscapeFreeProc, GetTableEncoding, unilen
# are fully tested by the rest of this file

# cleanup
::tcltest::cleanupTests
return














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
22
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) env.test 1.14 97/10/31 17:00:03



if {[string compare test [info procs test]] == 1} then {source defs}

#
# These tests will run on any platform (and indeed crashed
# on the Mac).  So put them before you test for the existance
# of exec.
#
test env-1.1 {propagation of env values to child interpreters} {








>




>
|
>
>
|
<







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
# 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.1.2.9 1999/04/07 02:46:18 hershey 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
# on the Mac).  So put them before you test for the existance
# of exec.
#
test env-1.1 {propagation of env values to child interpreters} {
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
# want to make sure it runs.
#
test env-1.2 {lappend to env value} {
    catch {unset env(test)}
    set env(test) aaaaaaaaaaaaaaaa
    append env(test) bbbbbbbbbbbbbb
    unset env(test)
} {}    





if {[info commands exec] == ""} {
    puts "exec not implemented for this machine"

    return

}

if {$tcl_platform(os) == "Win32s"} {
    puts "Cannot run multiple copies of tcl at the same time under Win32s"
    return
}



   
set f [open printenv w]
puts $f {
    proc lrem {listname name} {
	upvar $listname list
	set i [lsearch $list $name]
	if {$i >= 0} {
	    set list [lreplace $list $i $i]
	}
	return $list
    }
	
    set names [lsort [array names env]]
    if {$tcl_platform(platform) == "windows"} {
	lrem names HOME
        lrem names COMSPEC
	lrem names ComSpec
	lrem names ""
    }	
    foreach name {TCL_LIBRARY PATH LD_LIBRARY_PATH} {
	lrem names $name
    }
    foreach p $names {
	puts "$p=$env($p)"
    }
}
close $f







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

<
<
<
|
>
>
>
|


















|







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
# want to make sure it runs.
#
test env-1.2 {lappend to env value} {
    catch {unset env(test)}
    set env(test) aaaaaaaaaaaaaaaa
    append env(test) bbbbbbbbbbbbbb
    unset env(test)
} {}
test env-1.3 {reflection of env by "array names"} {
    catch {interp delete child}
    catch {unset env(test)}
    interp create child
    child eval {set env(test) garbage}
    set names [array names env]
    interp delete child
    set ix [lsearch $names test]
    catch {unset env(test)}
    expr {$ix >= 0}
} {1}





# Some tests require the "exec" command.
# Skip them if exec is not defined.
set ::tcltest::testConfig(execCommandExists) [expr {[info commands exec] != ""}]

set f [open printenv w]
puts $f {
    proc lrem {listname name} {
	upvar $listname list
	set i [lsearch $list $name]
	if {$i >= 0} {
	    set list [lreplace $list $i $i]
	}
	return $list
    }
	
    set names [lsort [array names env]]
    if {$tcl_platform(platform) == "windows"} {
	lrem names HOME
        lrem names COMSPEC
	lrem names ComSpec
	lrem names ""
    }	
    foreach name {TCL_LIBRARY PATH LD_LIBRARY_PATH PURE_PROG_NAME DISPLAY SHLIB_PATH } {
	lrem names $name
    }
    foreach p $names {
	puts "$p=$env($p)"
    }
}
close $f
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














    set env2($name) $env($name)
    unset env($name)
}

# Added the following lines so that child tcltest can actually find its
# library if the initial tcltest is run from a non-standard place.
# ('saved' env vars)
foreach name {TCL_LIBRARY PATH LD_LIBRARY_PATH} {
  if {[info exists env2($name)]} {
     set env($name) $env2($name);
  }
}

test env-2.1 {adding environment variables} {
    getenv
} {}

set env(NAME1) "test string"
test env-2.2 {adding environment variables} {
    getenv
} {NAME1=test string}

set env(NAME2) "more"
test env-2.3 {adding environment variables} {
    getenv
} {NAME1=test string
NAME2=more}

set env(XYZZY) "garbage"
test env-2.4 {adding environment variables} {
    getenv
} {NAME1=test string
NAME2=more
XYZZY=garbage}

set env(NAME2) "new value"
test env-3.1 {changing environment variables} {
    getenv


} {NAME1=test string
NAME2=new value
XYZZY=garbage}

unset env(NAME2)
test env-4.1 {unsetting environment variables} {
    getenv


} {NAME1=test string
XYZZY=garbage}
unset env(NAME1)
test env-4.2 {unsetting environment variables} {
    getenv


} {XYZZY=garbage}
















































































# Restore the environment variables at the end of the test.

foreach name [array names env] {
    unset env($name)
}
foreach name [array names env2] {
    set env($name) $env2($name)
}


file delete printenv





















|





|




|




|





|






|
|
>
>




<
|
|
>
>


|
|
|
>
>

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










>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    set env2($name) $env($name)
    unset env($name)
}

# Added the following lines so that child tcltest can actually find its
# library if the initial tcltest is run from a non-standard place.
# ('saved' env vars)
foreach name {TCL_LIBRARY PATH LD_LIBRARY_PATH DISPLAY SHLIB_PATH} {
  if {[info exists env2($name)]} {
     set env($name) $env2($name);
  }
}

test env-2.1 {adding environment variables} {execCommandExists} {
    getenv
} {}

set env(NAME1) "test string"
test env-2.2 {adding environment variables} {execCommandExists} {
    getenv
} {NAME1=test string}

set env(NAME2) "more"
test env-2.3 {adding environment variables} {execCommandExists} {
    getenv
} {NAME1=test string
NAME2=more}

set env(XYZZY) "garbage"
test env-2.4 {adding environment variables} {execCommandExists} {
    getenv
} {NAME1=test string
NAME2=more
XYZZY=garbage}

set env(NAME2) "new value"
test env-3.1 {changing environment variables} {execCommandExists} {
    set result [getenv]
    unset env(NAME2)
    set result
} {NAME1=test string
NAME2=new value
XYZZY=garbage}


test env-4.1 {unsetting environment variables} {execCommandExists} {
    set result [getenv]
    unset env(NAME1)
    set result
} {NAME1=test string
XYZZY=garbage}

test env-4.2 {unsetting environment variables} {execCommandExists} {
    set result [getenv]
    unset env(XYZZY)
    set result
} {XYZZY=garbage}

test env-4.3 {setting international environment variables} {execCommandExists} {
    set env(\ua7) \ub6
    getenv
} "\ua7=\ub6"
test env-4.4 {changing international environment variables} {execCommandExists} {
    set env(\ua7) \ua7
    getenv
} "\ua7=\ua7"
test env-4.5 {unsetting international environment variables} {execCommandExists} {
    set env(\ub6) \ua7
    unset env(\ua7)
    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
    # contain no entries.  The "array names" call synchs up
    # the C-level environ array with the Tcl level env array.
    # Make sure an empty Tcl array is created.

    set x [array get env]
    foreach e [array names env] {
	unset env($e)
    }
    set result [catch {array names env}]
    array set env $x
    set result
} {0}
test env-5.2 {corner cases - unset the env array} {} {
    # Unsetting a variable in an interp detaches the C-level
    # traces from the Tcl "env" variable.

    interp create i 
    i eval { unset env }
    i eval { set env(THIS_SHOULDNT_EXIST) a}
    set result [info exist env(THIS_SHOULDNT_EXIST)]
    interp delete i
    set result
} {0}
test env-5.3 {corner cases - unset the env in master should unset child} {} {
    # Variables deleted in a master interp should be deleted in
    # child interp too.

    interp create i 
    i eval { set env(THIS_SHOULD_EXIST) a}
    set result [set env(THIS_SHOULD_EXIST)]
    unset env(THIS_SHOULD_EXIST)
    lappend result [i eval {catch {set env(THIS_SHOULD_EXIST)}}]
    interp delete i
    set result
} {a 1}
test env-5.4 {corner cases - unset the env array} {knownBug} {
    # The info exist command should be in synch with the env array.
    # Know Bug: 1737

    interp create i 
    i eval { set env(THIS_SHOULD_EXIST) a}
    set     result [info exists env(THIS_SHOULD_EXIST)]
    lappend result [set env(THIS_SHOULD_EXIST)]
    lappend result [info exists env(THIS_SHOULD_EXIST)]
    interp delete i
    set result
} {1 a 1}
test env-5.5 {corner cases - cannot have null entries on Windows} {pcOnly} {
    set env() a
    catch {set env()}
} {1}


# Restore the environment variables at the end of the test.

foreach name [array names env] {
    unset env($name)
}
foreach name [array names env2] {
    set env($name) $env2($name)
}

# cleanup
file delete printenv
::tcltest::cleanupTests
return












Changes to tests/error.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  error, catch
#
# 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-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) error.test 1.22 97/08/12 17:02:43



if {[string compare test [info procs test]] == 1} then {source defs}

proc foo {} {
    global errorInfo
    set a [catch {format [error glorp2]} b]
    error {Human-generated}
}









>




>
|
>
>
|
<







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
# Commands covered:  error, catch
#
# 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-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: error.test,v 1.1.2.5 1999/03/24 02:49:05 hershey Exp $

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


proc foo {} {
    global errorInfo
    set a [catch {format [error glorp2]} b]
    error {Human-generated}
}

167
168
169
170
171
172
173

174

175












# Make sure that catch resets error information

test error-6.1 {catch must reset error state} {
    catch {error outer [catch {error inner inner.errorInfo inner.errorCode}]}
    list $errorCode $errorInfo
} {NONE 1}


catch {rename p ""}

return ""



















>

>
|
>
>
>
>
>
>
>
>
>
>
>
>
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# Make sure that catch resets error information

test error-6.1 {catch must reset error state} {
    catch {error outer [catch {error inner inner.errorInfo inner.errorCode}]}
    list $errorCode $errorInfo
} {NONE 1}

# cleanup
catch {rename p ""}
::tcltest::cleanupTests
return 












Changes to tests/eval.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  eval
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) eval.test 1.10 97/07/02 16:40:56



if {[string compare test [info procs test]] == 1} then {source defs}

test eval-1.1 {single argument} {
    eval {format 22}
} 22
test eval-1.2 {multiple arguments} {
    set a {$b}
    set b xyzzy








>




>
|
>
>
|
<







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
# Commands covered:  eval
#
# 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: eval.test,v 1.1.2.5 1999/03/24 02:49:05 hershey Exp $

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


test eval-1.1 {single argument} {
    eval {format 22}
} 22
test eval-1.2 {multiple arguments} {
    set a {$b}
    set b xyzzy
49
50
51
52
53
54
55
















\"error \"test error\"\"
    (\"eval\" body line 3)
    invoked from within
\"eval {
	set a 1
	error \"test error\"
    }\""























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
\"error \"test error\"\"
    (\"eval\" body line 3)
    invoked from within
\"eval {
	set a 1
	error \"test error\"
    }\""

# cleanup
::tcltest::cleanupTests
return












Changes to tests/event.test.

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
# This file contains a collection of tests for the procedures in the file
# tclEvent.c, which includes the "update", and "vwait" Tcl
# commands.  Sourcing this file into Tcl runs the tests and generates
# output for errors.  No output means no errors were found.
#
# 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.
#

# "@(#) event.test 1.35 97/08/11 11:58:38"



if {[string compare test [info procs test]] == 1} then {source defs}







if {[catch {testfilehandler create 0 off off}] == 0 } {
    test event-1.1 {Tcl_CreateFileHandler, reading} {
	testfilehandler close
	testfilehandler create 0 readable off
	testfilehandler clear 0
	testfilehandler oneevent
	set result ""
	lappend result [testfilehandler counts 0]
	testfilehandler fillpartial 0
	testfilehandler oneevent
	lappend result [testfilehandler counts 0]
	testfilehandler oneevent
	lappend result [testfilehandler counts 0]
	testfilehandler close
	set result
    } {{0 0} {1 0} {2 0}}
    test event-1.2 {Tcl_CreateFileHandler, writing} {nonPortable} {
	# This test is non-portable because on some systems (e.g.
	# SunOS 4.1.3) pipes seem to be writable always.
	testfilehandler close
	testfilehandler create 0 off writable
	testfilehandler clear 0
	testfilehandler oneevent
	set result ""
	lappend result [testfilehandler counts 0]
	testfilehandler fillpartial 0
	testfilehandler oneevent
	lappend result [testfilehandler counts 0]
	testfilehandler fill 0
	testfilehandler oneevent
	lappend result [testfilehandler counts 0]
	testfilehandler close
	set result
    } {{0 1} {0 2} {0 2}}
    test event-1.3 {Tcl_DeleteFileHandler} {nonPortable} {
	testfilehandler close
	testfilehandler create 2 disabled disabled
	testfilehandler create 1 readable writable
	testfilehandler create 0 disabled disabled
	testfilehandler fillpartial 1
	set result ""
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler create 1 off off
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler close
	set result
    } {{0 1} {1 1} {1 2} {0 0}}

    test event-2.1 {Tcl_DeleteFileHandler} {nonPortable} {
	testfilehandler close
	testfilehandler create 2 disabled disabled
	testfilehandler create 1 readable writable
	testfilehandler fillpartial 1
	set result ""
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler create 1 off off
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler close
	set result
    } {{0 1} {1 1} {1 2} {0 0}}
    test event-2.2 {Tcl_DeleteFileHandler, fd reused & events still pending} {nonPortable} {

	testfilehandler close
	testfilehandler create 0 readable writable
	testfilehandler fillpartial 0
	set result ""
	testfilehandler oneevent
	lappend result [testfilehandler counts 0]
	testfilehandler close
	testfilehandler create 0 readable writable
	testfilehandler oneevent
	lappend result [testfilehandler counts 0]
	testfilehandler close
	set result
    } {{0 1} {0 0}}

    test event-3.1 {FileHandlerCheckProc, TCL_FILE_EVENTS off } {
	testfilehandler close
	testfilehandler create 1 readable writable
	testfilehandler fillpartial 1
	testfilehandler windowevent
	set result [testfilehandler counts 1]
	testfilehandler close
	set result
    } {0 0}

    test event-4.1 {FileHandlerEventProc, race between event and disabling} {nonPortable} {

	update
	testfilehandler close
	testfilehandler create 2 disabled disabled
	testfilehandler create 1 readable writable
	testfilehandler fillpartial 1
	set result ""
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler create 1 disabled disabled
	testfilehandler oneevent
	lappend result [testfilehandler counts 1]
	testfilehandler close
	set result
    } {{0 1} {1 1} {1 2} {0 0}}
    test event-4.2 {FileHandlerEventProc, TCL_FILE_EVENTS off} {nonPortable} {

	update
	testfilehandler close
	testfilehandler create 1 readable writable
	testfilehandler create 2 readable writable
	testfilehandler fillpartial 1
	testfilehandler fillpartial 2
	testfilehandler oneevent
	set result ""
	lappend result [testfilehandler counts 1] [testfilehandler counts 2]
	testfilehandler windowevent
	lappend result [testfilehandler counts 1] [testfilehandler counts 2]
	testfilehandler close
	set result
    } {{0 0} {0 1} {0 0} {0 1}}
    testfilehandler close
    update
}

test event-5.1 {Tcl_BackgroundError, HandleBgErrors procedures} {
    catch {rename bgerror {}}
    proc bgerror msg {
	global errorInfo errorCode x
	lappend x [list $msg $errorInfo $errorCode]
    }






>




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

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

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

|
|
|
|
|
|
|
|
|

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







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
# This file contains a collection of tests for the procedures in the file
# tclEvent.c, which includes the "update", and "vwait" Tcl
# commands.  Sourcing this file into Tcl runs the tests and generates
# output for errors.  No output means no errors were found.
#
# Copyright (c) 1995-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: event.test,v 1.1.2.7 1999/03/26 19:13:58 hershey Exp $

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

set ::tcltest::testConfig(testfilehandler) \
	[expr {[info commands testfilehandler] != {}}]
set ::tcltest::testConfig(testexithandler) \
	[expr {[info commands testexithandler] != {}}]
set ::tcltest::testConfig(testfilewait) \
	[expr {[info commands testfilewait] != {}}]


test event-1.1 {Tcl_CreateFileHandler, reading} {testfilehandler} {
    testfilehandler close
    testfilehandler create 0 readable off
    testfilehandler clear 0
    testfilehandler oneevent
    set result ""
    lappend result [testfilehandler counts 0]
    testfilehandler fillpartial 0
    testfilehandler oneevent
    lappend result [testfilehandler counts 0]
    testfilehandler oneevent
    lappend result [testfilehandler counts 0]
    testfilehandler close
    set result
} {{0 0} {1 0} {2 0}}
test event-1.2 {Tcl_CreateFileHandler, writing} {testfilehandler nonPortable} {
    # This test is non-portable because on some systems (e.g.
    # SunOS 4.1.3) pipes seem to be writable always.
    testfilehandler close
    testfilehandler create 0 off writable
    testfilehandler clear 0
    testfilehandler oneevent
    set result ""
    lappend result [testfilehandler counts 0]
    testfilehandler fillpartial 0
    testfilehandler oneevent
    lappend result [testfilehandler counts 0]
    testfilehandler fill 0
    testfilehandler oneevent
    lappend result [testfilehandler counts 0]
    testfilehandler close
    set result
} {{0 1} {0 2} {0 2}}
test event-1.3 {Tcl_DeleteFileHandler} {testfilehandler nonPortable} {
    testfilehandler close
    testfilehandler create 2 disabled disabled
    testfilehandler create 1 readable writable
    testfilehandler create 0 disabled disabled
    testfilehandler fillpartial 1
    set result ""
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler create 1 off off
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler close
    set result
} {{0 1} {1 1} {1 2} {0 0}}

test event-2.1 {Tcl_DeleteFileHandler} {testfilehandler nonPortable} {
    testfilehandler close
    testfilehandler create 2 disabled disabled
    testfilehandler create 1 readable writable
    testfilehandler fillpartial 1
    set result ""
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler create 1 off off
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler close
    set result
} {{0 1} {1 1} {1 2} {0 0}}
test event-2.2 {Tcl_DeleteFileHandler, fd reused & events still pending} \
	{testfilehandler nonPortable} {
    testfilehandler close
    testfilehandler create 0 readable writable
    testfilehandler fillpartial 0
    set result ""
    testfilehandler oneevent
    lappend result [testfilehandler counts 0]
    testfilehandler close
    testfilehandler create 0 readable writable
    testfilehandler oneevent
    lappend result [testfilehandler counts 0]
    testfilehandler close
    set result
} {{0 1} {0 0}}

test event-3.1 {FileHandlerCheckProc, TCL_FILE_EVENTS off } {testfilehandler} {
    testfilehandler close
    testfilehandler create 1 readable writable
    testfilehandler fillpartial 1
    testfilehandler windowevent
    set result [testfilehandler counts 1]
    testfilehandler close
    set result
} {0 0}

test event-4.1 {FileHandlerEventProc, race between event and disabling} \
	{testfilehandler nonPortable} {
    update
    testfilehandler close
    testfilehandler create 2 disabled disabled
    testfilehandler create 1 readable writable
    testfilehandler fillpartial 1
    set result ""
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler create 1 disabled disabled
    testfilehandler oneevent
    lappend result [testfilehandler counts 1]
    testfilehandler close
    set result
} {{0 1} {1 1} {1 2} {0 0}}
test event-4.2 {FileHandlerEventProc, TCL_FILE_EVENTS off} \
	{testfilehandler nonPortable} {
    update
    testfilehandler close
    testfilehandler create 1 readable writable
    testfilehandler create 2 readable writable
    testfilehandler fillpartial 1
    testfilehandler fillpartial 2
    testfilehandler oneevent
    set result ""
    lappend result [testfilehandler counts 1] [testfilehandler counts 2]
    testfilehandler windowevent
    lappend result [testfilehandler counts 1] [testfilehandler counts 2]
    testfilehandler close
    set result
} {{0 0} {0 1} {0 0} {0 1}}

update


test event-5.1 {Tcl_BackgroundError, HandleBgErrors procedures} {
    catch {rename bgerror {}}
    proc bgerror msg {
	global errorInfo errorCode x
	lappend x [list $msg $errorInfo $errorCode]
    }
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
# that. the other option would be to use fork a test but it
# then becomes more a file/exec test than a bgerror test.

# end of bgerror tests
catch {rename bgerror {}}


if {[info commands testexithandler] != ""} {
    test event-8.1 {Tcl_CreateExitHandler procedure} {stdio} {
	set child [open |[list [info nameofexecutable]] r+]
	puts $child "testexithandler create 41; testexithandler create 4"
	puts $child "testexithandler create 6; exit"
	flush $child
	set result [read $child]
	close $child
	set result
    } {even 6
even 4
odd 41
}

    test event-9.1 {Tcl_DeleteExitHandler procedure} {stdio} {
	set child [open |[list [info nameofexecutable]] r+]
	puts $child "testexithandler create 41; testexithandler create 4"
	puts $child "testexithandler create 6; testexithandler delete 41"
	puts $child "testexithandler create 16; exit"
	flush $child
	set result [read $child]
	close $child
	set result
    } {even 16
even 6
even 4
}
    test event-9.2 {Tcl_DeleteExitHandler procedure} {stdio} {
	set child [open |[list [info nameofexecutable]] r+]
	puts $child "testexithandler create 41; testexithandler create 4"
	puts $child "testexithandler create 6; testexithandler delete 4"
	puts $child "testexithandler create 16; exit"
	flush $child
	set result [read $child]
	close $child
	set result
    } {even 16
even 6
odd 41
}
    test event-9.3 {Tcl_DeleteExitHandler procedure} {stdio} {
	set child [open |[list [info nameofexecutable]] r+]
	puts $child "testexithandler create 41; testexithandler create 4"
	puts $child "testexithandler create 6; testexithandler delete 6"
	puts $child "testexithandler create 16; exit"
	flush $child
	set result [read $child]
	close $child
	set result
    } {even 16
even 4
odd 41
}
    test event-9.4 {Tcl_DeleteExitHandler procedure} {stdio} {
	set child [open |[list [info nameofexecutable]] r+]
	puts $child "testexithandler create 41; testexithandler delete 41"
	puts $child "testexithandler create 16; exit"
	flush $child
	set result [read $child]
	close $child
	set result
    } {even 16
}
}

test event-10.1 {Tcl_Exit procedure} {stdio} {
    set child [open |[list [info nameofexecutable]] r+]
    puts $child "exit 3"
    list [catch {close $child} msg] $msg [lindex $errorCode 0] \
        [lindex $errorCode 2]







<
|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
<







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
# that. the other option would be to use fork a test but it
# then becomes more a file/exec test than a bgerror test.

# end of bgerror tests
catch {rename bgerror {}}



test event-8.1 {Tcl_CreateExitHandler procedure} {stdio testexithandler} {
    set child [open |[list [info nameofexecutable]] r+]
    puts $child "testexithandler create 41; testexithandler create 4"
    puts $child "testexithandler create 6; exit"
    flush $child
    set result [read $child]
    close $child
    set result
} {even 6
even 4
odd 41
}

test event-9.1 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
    set child [open |[list [info nameofexecutable]] r+]
    puts $child "testexithandler create 41; testexithandler create 4"
    puts $child "testexithandler create 6; testexithandler delete 41"
    puts $child "testexithandler create 16; exit"
    flush $child
    set result [read $child]
    close $child
    set result
} {even 16
even 6
even 4
}
test event-9.2 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
    set child [open |[list [info nameofexecutable]] r+]
    puts $child "testexithandler create 41; testexithandler create 4"
    puts $child "testexithandler create 6; testexithandler delete 4"
    puts $child "testexithandler create 16; exit"
    flush $child
    set result [read $child]
    close $child
    set result
    } {even 16
even 6
odd 41
}
test event-9.3 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
    set child [open |[list [info nameofexecutable]] r+]
    puts $child "testexithandler create 41; testexithandler create 4"
    puts $child "testexithandler create 6; testexithandler delete 6"
    puts $child "testexithandler create 16; exit"
    flush $child
    set result [read $child]
    close $child
    set result
} {even 16
even 4
odd 41
}
test event-9.4 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
    set child [open |[list [info nameofexecutable]] r+]
    puts $child "testexithandler create 41; testexithandler delete 41"
    puts $child "testexithandler create 16; exit"
    flush $child
    set result [read $child]
    close $child
    set result
} {even 16

}

test event-10.1 {Tcl_Exit procedure} {stdio} {
    set child [open |[list [info nameofexecutable]] r+]
    puts $child "exit 3"
    list [catch {close $child} msg] $msg [lindex $errorCode 0] \
        [lindex $errorCode 2]
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395

test event-11.5 {Tcl_VwaitCmd procedure: round robin scheduling, 2 sources} {socket} {
    set f1 [open test1 w]
    proc accept {s args} {
	puts $s foobar
	close $s
    }
    set s1 [socket -server accept 5000]
    set s2 [socket 127.0.0.1 5000]
    close $s1
    set x 0
    set y 0
    set z 0
    fileevent $s2 readable { incr z }
    vwait z
    fileevent $f1 writable { incr x; if { $y == 3 } { set z done } }







|
|







389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404

test event-11.5 {Tcl_VwaitCmd procedure: round robin scheduling, 2 sources} {socket} {
    set f1 [open test1 w]
    proc accept {s args} {
	puts $s foobar
	close $s
    }
    set s1 [socket -server accept 5001]
    set s2 [socket 127.0.0.1 5001]
    close $s1
    set x 0
    set y 0
    set z 0
    fileevent $s2 readable { incr z }
    vwait z
    fileevent $f1 writable { incr x; if { $y == 3 } { set z done } }
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














    set y before
    set z before
    after 300
    update
    list $x $y $z
} {x-done before z-done}

if {[info commands testfilehandler] != ""} {
    test event-13.1 {Tcl_WaitForFile procedure, readable} unixOnly {
	foreach i [after info] {
	    after cancel $i
	}
	after 100 set x timeout
	testfilehandler close
	testfilehandler create 1 off off
	set x "no timeout"
	set result [testfilehandler wait 1 readable 0]
	update
	testfilehandler close
	list $result $x
    } {{} {no timeout}}
    test event-13.2 {Tcl_WaitForFile procedure, readable} unixOnly {
	foreach i [after info] {
	    after cancel $i
	}
	after 100 set x timeout
	testfilehandler close
	testfilehandler create 1 off off
	set x "no timeout"
	set result [testfilehandler wait 1 readable 100]
	update
	testfilehandler close
	list $result $x
    } {{} timeout}
    test event-13.3 {Tcl_WaitForFile procedure, readable} unixOnly {
	foreach i [after info] {
	    after cancel $i
	}
	after 100 set x timeout
	testfilehandler close
	testfilehandler create 1 off off
	testfilehandler fillpartial 1
	set x "no timeout"
	set result [testfilehandler wait 1 readable 100]
	update
	testfilehandler close
	list $result $x
    } {readable {no timeout}}
    test event-13.4 {Tcl_WaitForFile procedure, writable} {unixOnly nonPortable} {

	foreach i [after info] {
	    after cancel $i
	}
	after 100 set x timeout
	testfilehandler close
	testfilehandler create 1 off off
	testfilehandler fill 1
	set x "no timeout"
	set result [testfilehandler wait 1 writable 0]
	update
	testfilehandler close
	list $result $x
    } {{} {no timeout}}
    test event-13.5 {Tcl_WaitForFile procedure, writable} {unixOnly nonPortable} {

	foreach i [after info] {
	    after cancel $i
	}
	after 100 set x timeout
	testfilehandler close
	testfilehandler create 1 off off
	testfilehandler fill 1
	set x "no timeout"
	set result [testfilehandler wait 1 writable 100]
	update
	testfilehandler close
	list $result $x
    } {{} timeout}
    test event-13.6 {Tcl_WaitForFile procedure, writable} unixOnly {
	foreach i [after info] {
	    after cancel $i
	}
	after 100 set x timeout
	testfilehandler close
	testfilehandler create 1 off off
	set x "no timeout"
	set result [testfilehandler wait 1 writable 100]
	update
	testfilehandler close
	list $result $x
    } {writable {no timeout}}
    test event-13.7 {Tcl_WaitForFile procedure, don't call other event handlers} unixOnly {
	foreach i [after info] {
	    after cancel $i
	}
	after 100 lappend x timeout
	after idle lappend x idle
	testfilehandler close
	testfilehandler create 1 off off
	set x ""
	set result [list [testfilehandler wait 1 readable 200] $x]
	update
	testfilehandler close
	lappend result $x
    } {{} {} {timeout idle}}
}

if {[info commands testfilewait] != ""} {
    test event-13.8 {Tcl_WaitForFile procedure, waiting indefinitely} unixOnly {
	set f [open "|sleep 2" r]
	set result ""
	lappend result [testfilewait $f readable 100]
	lappend result [testfilewait $f readable -1]
	close $f
	set result
    } {{} readable}
}

foreach i [after info] {
    after cancel $i
}





















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



>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    set y before
    set z before
    after 300
    update
    list $x $y $z
} {x-done before z-done}


test event-13.1 {Tcl_WaitForFile procedure, readable} {testfilehandler} {
    foreach i [after info] {
	after cancel $i
    }
    after 100 set x timeout
    testfilehandler close
    testfilehandler create 1 off off
    set x "no timeout"
    set result [testfilehandler wait 1 readable 0]
    update
    testfilehandler close
    list $result $x
} {{} {no timeout}}
test event-13.2 {Tcl_WaitForFile procedure, readable} testfilehandler {
    foreach i [after info] {
	after cancel $i
    }
    after 100 set x timeout
    testfilehandler close
    testfilehandler create 1 off off
    set x "no timeout"
    set result [testfilehandler wait 1 readable 100]
    update
    testfilehandler close
    list $result $x
} {{} timeout}
test event-13.3 {Tcl_WaitForFile procedure, readable} testfilehandler {
    foreach i [after info] {
	after cancel $i
    }
    after 100 set x timeout
    testfilehandler close
    testfilehandler create 1 off off
    testfilehandler fillpartial 1
    set x "no timeout"
    set result [testfilehandler wait 1 readable 100]
    update
    testfilehandler close
    list $result $x
} {readable {no timeout}}
test event-13.4 {Tcl_WaitForFile procedure, writable} \
	{testfilehandler nonPortable} {
    foreach i [after info] {
	after cancel $i
    }
    after 100 set x timeout
    testfilehandler close
    testfilehandler create 1 off off
    testfilehandler fill 1
    set x "no timeout"
    set result [testfilehandler wait 1 writable 0]
    update
    testfilehandler close
    list $result $x
} {{} {no timeout}}
test event-13.5 {Tcl_WaitForFile procedure, writable} \
	{testfilehandler nonPortable} {
    foreach i [after info] {
	after cancel $i
    }
    after 100 set x timeout
    testfilehandler close
    testfilehandler create 1 off off
    testfilehandler fill 1
    set x "no timeout"
    set result [testfilehandler wait 1 writable 100]
    update
    testfilehandler close
    list $result $x
} {{} timeout}
test event-13.6 {Tcl_WaitForFile procedure, writable} testfilehandler {
    foreach i [after info] {
	after cancel $i
    }
    after 100 set x timeout
    testfilehandler close
    testfilehandler create 1 off off
    set x "no timeout"
    set result [testfilehandler wait 1 writable 100]
    update
    testfilehandler close
    list $result $x
} {writable {no timeout}}
test event-13.7 {Tcl_WaitForFile procedure, don't call other event handlers} testfilehandler {
    foreach i [after info] {
	after cancel $i
    }
    after 100 lappend x timeout
    after idle lappend x idle
    testfilehandler close
    testfilehandler create 1 off off
    set x ""
    set result [list [testfilehandler wait 1 readable 200] $x]
    update
    testfilehandler close
    lappend result $x
} {{} {} {timeout idle}}



test event-13.8 {Tcl_WaitForFile procedure, waiting indefinitely} testfilewait {
    set f [open "|sleep 2" r]
    set result ""
    lappend result [testfilewait $f readable 100]
    lappend result [testfilewait $f readable -1]
    close $f
    set result
} {{} readable}

# cleanup
foreach i [after info] {
    after cancel $i
}
::tcltest::cleanupTests
return












Changes to tests/exec.test.

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
# Commands covered:  exec
#
# 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-1994 The Regents of the University of California.
# 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.
#
# SCCS: @(#) exec.test 1.58 97/08/01 11:10:00

if {[string compare test [info procs test]] == 1} then {source defs}

# If exec is not defined just return with no error
# Some platforms like the Macintosh do not have the exec command
if {[info commands exec] == ""} {
    puts "exec not implemented for this machine"
    return
}
if {$testConfig(stdio) == 0} {
    return
}




set f [open echo w]
puts $f {
    puts -nonewline [lindex $argv 0]
    foreach str [lrange $argv 1 end] {
	puts -nonewline " $str"
    }








>




|

<
|
<
<
|
<
<

<
<
|
>
>
>







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
# Commands covered:  exec
#
# 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-1994 The Regents of the University of California.
# Copyright (c) 1994-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: exec.test,v 1.1.2.5 1999/03/24 02:49:06 hershey Exp $


if {[lsearch [namespace children] ::tcltest] == -1} {


    source [file join [pwd] [file dirname [info script]] defs.tcl]


}



# All tests require the "exec" command.
# Skip them if exec is not defined.
set ::tcltest::testConfig(execCommandExists) [expr {[info commands exec] != ""}]

set f [open echo w]
puts $f {
    puts -nonewline [lindex $argv 0]
    foreach str [lrange $argv 1 end] {
	puts -nonewline " $str"
    }
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284






285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311










312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426

427
428
429
430
431
432
433
puts $f {
    exit $argv
}
close $f

# Basic operations.

test exec-1.1 {basic exec operation} {
    exec $tcltest echo a b c
} "a b c"
test exec-1.2 {pipelining} {
    exec $tcltest echo a b c d | $tcltest cat | $tcltest cat
} "a b c d"
test exec-1.3 {pipelining} {
    set a [exec $tcltest echo a b c d | $tcltest cat | $tcltest wc]
    list [scan $a "%d %d %d" b c d] $b $c
} {3 1 4}
set arg {12345678901234567890123456789012345678901234567890}
set arg "$arg$arg$arg$arg$arg$arg"
test exec-1.4 {long command lines} {
    exec $tcltest echo $arg
} $arg
set arg {}

# I/O redirection: input from Tcl command.

test exec-2.1 {redirecting input from immediate source} {
    exec $tcltest cat << "Sample text"
} {Sample text}
test exec-2.2 {redirecting input from immediate source} {
    exec << "Sample text" $tcltest cat | $tcltest cat
} {Sample text}
test exec-2.3 {redirecting input from immediate source} {
    exec $tcltest cat << "Sample text" | $tcltest cat
} {Sample text}
test exec-2.4 {redirecting input from immediate source} {
    exec $tcltest cat | $tcltest cat << "Sample text"
} {Sample text}
test exec-2.5 {redirecting input from immediate source} {
    exec $tcltest cat "<<Joined to arrows"
} {Joined to arrows}

# I/O redirection: output to file.

file delete gorp.file
test exec-3.1 {redirecting output to file} {
    exec $tcltest echo "Some simple words" > gorp.file
    exec $tcltest cat gorp.file
} "Some simple words"
test exec-3.2 {redirecting output to file} {
    exec $tcltest echo "More simple words" | >gorp.file $tcltest cat | $tcltest cat
    exec $tcltest cat gorp.file
} "More simple words"
test exec-3.3 {redirecting output to file} {
    exec > gorp.file $tcltest echo "Different simple words" | $tcltest cat | $tcltest cat
    exec $tcltest cat gorp.file
} "Different simple words"
test exec-3.4 {redirecting output to file} {
    exec $tcltest echo "Some simple words" >gorp.file
    exec $tcltest cat gorp.file
} "Some simple words"
test exec-3.5 {redirecting output to file} {
    exec $tcltest echo "First line" >gorp.file
    exec $tcltest echo "Second line" >> gorp.file
    exec $tcltest cat gorp.file
} "First line\nSecond line"
test exec-3.6 {redirecting output to file} {
    exec $tcltest echo "First line" >gorp.file
    exec $tcltest echo "Second line" >>gorp.file
    exec $tcltest cat gorp.file
} "First line\nSecond line"
test exec-3.7 {redirecting output to file} {
    set f [open gorp.file w]
    puts $f "Line 1"
    flush $f
    exec $tcltest echo "More text" >@ $f
    exec $tcltest echo >@$f "Even more"
    puts $f "Line 3"
    close $f
    exec $tcltest cat gorp.file
} "Line 1\nMore text\nEven more\nLine 3"

# I/O redirection: output and stderr to file.

file delete gorp.file
test exec-4.1 {redirecting output and stderr to file} {
    exec $tcltest echo "test output" >& gorp.file
    exec $tcltest cat gorp.file
} "test output"
test exec-4.2 {redirecting output and stderr to file} {
    list [exec $tcltest sh -c "echo foo bar 1>&2" >&gorp.file] \
	    [exec $tcltest cat gorp.file]
} {{} {foo bar}}
test exec-4.3 {redirecting output and stderr to file} {
    exec $tcltest echo "first line" > gorp.file
    list [exec $tcltest sh -c "echo foo bar 1>&2" >>&gorp.file] \
	    [exec $tcltest cat gorp.file]
} "{} {first line\nfoo bar}"
test exec-4.4 {redirecting output and stderr to file} {
    set f [open gorp.file w]
    puts $f "Line 1"
    flush $f
    exec $tcltest echo "More text" >&@ $f
    exec $tcltest echo >&@$f "Even more"
    puts $f "Line 3"
    close $f
    exec $tcltest cat gorp.file
} "Line 1\nMore text\nEven more\nLine 3"
test exec-4.5 {redirecting output and stderr to file} {
    set f [open gorp.file w]
    puts $f "Line 1"
    flush $f
    exec >&@ $f $tcltest sh -c "echo foo bar 1>&2"
    exec >&@$f $tcltest sh -c "echo xyzzy 1>&2"
    puts $f "Line 3"
    close $f
    exec $tcltest cat gorp.file
} "Line 1\nfoo bar\nxyzzy\nLine 3"

# I/O redirection: input from file.

exec $tcltest echo "Just a few thoughts" > gorp.file
test exec-5.1 {redirecting input from file} {
    exec $tcltest cat < gorp.file
} {Just a few thoughts}
test exec-5.2 {redirecting input from file} {
    exec $tcltest cat | $tcltest cat < gorp.file
} {Just a few thoughts}
test exec-5.3 {redirecting input from file} {
    exec $tcltest cat < gorp.file | $tcltest cat
} {Just a few thoughts}
test exec-5.4 {redirecting input from file} {
    exec < gorp.file $tcltest cat | $tcltest cat
} {Just a few thoughts}
test exec-5.5 {redirecting input from file} {
    exec $tcltest cat <gorp.file
} {Just a few thoughts}
test exec-5.6 {redirecting input from file} {
    set f [open gorp.file r]
    set result [exec $tcltest cat <@ $f]
    close $f
    set result
} {Just a few thoughts}
test exec-5.7 {redirecting input from file} {
    set f [open gorp.file r]
    set result [exec <@$f $tcltest cat]
    close $f
    set result
} {Just a few thoughts}

# I/O redirection: standard error through a pipeline.

test exec-6.1 {redirecting stderr through a pipeline} {
    exec $tcltest sh -c "echo foo bar" |& $tcltest cat
} "foo bar"
test exec-6.2 {redirecting stderr through a pipeline} {
    exec $tcltest sh -c "echo foo bar 1>&2" |& $tcltest cat
} "foo bar"
test exec-6.3 {redirecting stderr through a pipeline} {
    exec $tcltest sh -c "echo foo bar 1>&2" \
	|& $tcltest sh -c "echo second msg 1>&2 ; cat" |& $tcltest cat
} "second msg\nfoo bar"

# I/O redirection: combinations.

catch {exec rm -f gorp.file2}
test exec-7.1 {multiple I/O redirections} {
    exec << "command input" > gorp.file2 $tcltest cat < gorp.file
    exec $tcltest cat gorp.file2
} {Just a few thoughts}
test exec-7.2 {multiple I/O redirections} {
    exec < gorp.file << "command input" $tcltest cat
} {command input}

# Long input to command and output from command.

set a "0123456789 xxxxxxxxx abcdefghi ABCDEFGHIJK\n"
set a [concat $a $a $a $a]
set a [concat $a $a $a $a]
set a [concat $a $a $a $a]
set a [concat $a $a $a $a]
test exec-8.1 {long input and output} {
    exec $tcltest cat << $a
} $a







# Commands that return errors.

test exec-9.1 {commands returning errors} {
    set x [catch {exec gorp456} msg]
    list $x [string tolower $msg] [string tolower $errorCode]
} {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}}
test exec-9.2 {commands returning errors} {
    string tolower [list [catch {exec $tcltest echo foo | foo123} msg] $msg $errorCode]
} {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}}
test exec-9.3 {commands returning errors} {
    list [catch {exec $tcltest sleep 1 | $tcltest exit 43 | $tcltest sleep 1} msg] $msg
} {1 {child process exited abnormally}}
test exec-9.4 {commands returning errors} {
    list [catch {exec $tcltest exit 43 | $tcltest echo "foo bar"} msg] $msg
} {1 {foo bar
child process exited abnormally}}
test exec-9.5 {commands returning errors} {
    list [catch {exec gorp456 | $tcltest echo a b c} msg] [string tolower $msg]
} {1 {couldn't execute "gorp456": no such file or directory}}
test exec-9.6 {commands returning errors} {
    list [catch {exec $tcltest sh -c "echo error msg 1>&2"} msg] $msg
} {1 {error msg}}
test exec-9.7 {commands returning errors} {
    list [catch {exec $tcltest sh -c "echo error msg 1>&2" \
		     | $tcltest sh -c "echo error msg 1>&2"} msg] $msg
} {1 {error msg
error msg}}











# Errors in executing the Tcl command, as opposed to errors in the
# processes that are invoked.

test exec-10.1 {errors in exec invocation} {
    list [catch {exec} msg] $msg
} {1 {wrong # args: should be "exec ?switches? arg ?arg ...?"}}
test exec-10.2 {errors in exec invocation} {
    list [catch {exec | cat} msg] $msg
} {1 {illegal use of | or |& in command}}
test exec-10.3 {errors in exec invocation} {
    list [catch {exec cat |} msg] $msg
} {1 {illegal use of | or |& in command}}
test exec-10.4 {errors in exec invocation} {
    list [catch {exec cat | | cat} msg] $msg
} {1 {illegal use of | or |& in command}}
test exec-10.5 {errors in exec invocation} {
    list [catch {exec cat | |& cat} msg] $msg
} {1 {illegal use of | or |& in command}}
test exec-10.6 {errors in exec invocation} {
    list [catch {exec cat |&} msg] $msg
} {1 {illegal use of | or |& in command}}
test exec-10.7 {errors in exec invocation} {
    list [catch {exec cat <} msg] $msg
} {1 {can't specify "<" as last word in command}}
test exec-10.8 {errors in exec invocation} {
    list [catch {exec cat >} msg] $msg
} {1 {can't specify ">" as last word in command}}
test exec-10.9 {errors in exec invocation} {
    list [catch {exec cat <<} msg] $msg
} {1 {can't specify "<<" as last word in command}}
test exec-10.10 {errors in exec invocation} {
    list [catch {exec cat >>} msg] $msg
} {1 {can't specify ">>" as last word in command}}
test exec-10.11 {errors in exec invocation} {
    list [catch {exec cat >&} msg] $msg
} {1 {can't specify ">&" as last word in command}}
test exec-10.12 {errors in exec invocation} {
    list [catch {exec cat >>&} msg] $msg
} {1 {can't specify ">>&" as last word in command}}
test exec-10.13 {errors in exec invocation} {
    list [catch {exec cat >@} msg] $msg
} {1 {can't specify ">@" as last word in command}}
test exec-10.14 {errors in exec invocation} {
    list [catch {exec cat <@} msg] $msg
} {1 {can't specify "<@" as last word in command}}
test exec-10.15 {errors in exec invocation} {
    list [catch {exec cat < a/b/c} msg] [string tolower $msg]
} {1 {couldn't read file "a/b/c": no such file or directory}}
test exec-10.16 {errors in exec invocation} {
    list [catch {exec cat << foo > a/b/c} msg] [string tolower $msg]
} {1 {couldn't write file "a/b/c": no such file or directory}}
test exec-10.17 {errors in exec invocation} {
    list [catch {exec cat << foo > a/b/c} msg] [string tolower $msg]
} {1 {couldn't write file "a/b/c": no such file or directory}}
set f [open gorp.file w]
test exec-10.18 {errors in exec invocation} {
    list [catch {exec cat <@ $f} msg] $msg
} "1 {channel \"$f\" wasn't opened for reading}"
close $f
set f [open gorp.file r]
test exec-10.19 {errors in exec invocation} {
    list [catch {exec cat >@ $f} msg] $msg
} "1 {channel \"$f\" wasn't opened for writing}"
close $f
test exec-10.20 {errors in exec invocation} {
    list [catch {exec ~non_existent_user/foo/bar} msg] $msg
} {1 {user "non_existent_user" doesn't exist}}
test exec-10.21 {errors in exec invocation} {
    list [catch {exec $tcltest true | ~xyzzy_bad_user/x | false} msg] $msg
} {1 {user "xyzzy_bad_user" doesn't exist}}

# Commands in background.

test exec-11.1 {commands in background} {
    set x [lindex [time {exec $tcltest sleep 2 &}] 0]
    expr $x<1000000
} 1
test exec-11.2 {commands in background} {
    list [catch {exec $tcltest echo a &b} msg] $msg
} {0 {a &b}}
test exec-11.3 {commands in background} {
    llength [exec $tcltest sleep 1 &]
} 1
test exec-11.4 {commands in background} {
    llength [exec $tcltest sleep 1 | $tcltest sleep 1 | $tcltest sleep 1 &]
} 3
test exec-11.5 {commands in background} {
    set f [open gorp.file w]
    puts $f { catch { exec [info nameofexecutable] echo foo & } }
    close $f
    string compare "foo" [exec $tcltest gorp.file]
} 0

# Make sure that background commands are properly reaped when
# they eventually die.

exec $tcltest sleep 3
test exec-12.1 {reaping background processes} {unixOnly nonPortable} {

    for {set i 0} {$i < 20} {incr i} {
	exec echo foo > /dev/null &
    }
    exec sleep 1
    catch {exec ps | fgrep "echo foo" | fgrep -v fgrep | wc} msg
    lindex $msg 0
} 0
test exec-12.2 {reaping background processes} {unixOnly nonPortable} {

    exec sleep 2 | sleep 2 | sleep 2 &
    catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
    set x [lindex $msg 0]
    exec sleep 3
    catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
    list $x [lindex $msg 0]
} {3 0}
test exec-12.3 {reaping background processes} {unixOnly nonPortable} {

    exec sleep 1000 &
    exec sleep 1000 &
    set x [exec ps | fgrep "sleep" | fgrep -v fgrep]
    set pids {}
    foreach i [split $x \n] {
	lappend pids [lindex $i 0]
    }







|


|


|





|






|


|


|


|


|






|



|



|



|



|




|




|













|



|



|




|









|













|


|


|


|


|


|





|








|


|


|






|
|



|










|



>
>
>
>
>
>


|



|


|


|



|


|


|




>
>
>
>
>
>
>
>
>
>




|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|



|




|



|


|





|



|


|


|


|










|
>







|
>







|
>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
puts $f {
    exit $argv
}
close $f

# Basic operations.

test exec-1.1 {basic exec operation} {execCommandExists stdio} {
    exec $tcltest echo a b c
} "a b c"
test exec-1.2 {pipelining} {execCommandExists stdio} {
    exec $tcltest echo a b c d | $tcltest cat | $tcltest cat
} "a b c d"
test exec-1.3 {pipelining} {execCommandExists stdio} {
    set a [exec $tcltest echo a b c d | $tcltest cat | $tcltest wc]
    list [scan $a "%d %d %d" b c d] $b $c
} {3 1 4}
set arg {12345678901234567890123456789012345678901234567890}
set arg "$arg$arg$arg$arg$arg$arg"
test exec-1.4 {long command lines} {execCommandExists stdio} {
    exec $tcltest echo $arg
} $arg
set arg {}

# I/O redirection: input from Tcl command.

test exec-2.1 {redirecting input from immediate source} {execCommandExists stdio} {
    exec $tcltest cat << "Sample text"
} {Sample text}
test exec-2.2 {redirecting input from immediate source} {execCommandExists stdio} {
    exec << "Sample text" $tcltest cat | $tcltest cat
} {Sample text}
test exec-2.3 {redirecting input from immediate source} {execCommandExists stdio} {
    exec $tcltest cat << "Sample text" | $tcltest cat
} {Sample text}
test exec-2.4 {redirecting input from immediate source} {execCommandExists stdio} {
    exec $tcltest cat | $tcltest cat << "Sample text"
} {Sample text}
test exec-2.5 {redirecting input from immediate source} {execCommandExists stdio} {
    exec $tcltest cat "<<Joined to arrows"
} {Joined to arrows}

# I/O redirection: output to file.

file delete gorp.file
test exec-3.1 {redirecting output to file} {execCommandExists stdio} {
    exec $tcltest echo "Some simple words" > gorp.file
    exec $tcltest cat gorp.file
} "Some simple words"
test exec-3.2 {redirecting output to file} {execCommandExists stdio} {
    exec $tcltest echo "More simple words" | >gorp.file $tcltest cat | $tcltest cat
    exec $tcltest cat gorp.file
} "More simple words"
test exec-3.3 {redirecting output to file} {execCommandExists stdio} {
    exec > gorp.file $tcltest echo "Different simple words" | $tcltest cat | $tcltest cat
    exec $tcltest cat gorp.file
} "Different simple words"
test exec-3.4 {redirecting output to file} {execCommandExists stdio} {
    exec $tcltest echo "Some simple words" >gorp.file
    exec $tcltest cat gorp.file
} "Some simple words"
test exec-3.5 {redirecting output to file} {execCommandExists stdio} {
    exec $tcltest echo "First line" >gorp.file
    exec $tcltest echo "Second line" >> gorp.file
    exec $tcltest cat gorp.file
} "First line\nSecond line"
test exec-3.6 {redirecting output to file} {execCommandExists stdio} {
    exec $tcltest echo "First line" >gorp.file
    exec $tcltest echo "Second line" >>gorp.file
    exec $tcltest cat gorp.file
} "First line\nSecond line"
test exec-3.7 {redirecting output to file} {execCommandExists stdio} {
    set f [open gorp.file w]
    puts $f "Line 1"
    flush $f
    exec $tcltest echo "More text" >@ $f
    exec $tcltest echo >@$f "Even more"
    puts $f "Line 3"
    close $f
    exec $tcltest cat gorp.file
} "Line 1\nMore text\nEven more\nLine 3"

# I/O redirection: output and stderr to file.

file delete gorp.file
test exec-4.1 {redirecting output and stderr to file} {execCommandExists stdio} {
    exec $tcltest echo "test output" >& gorp.file
    exec $tcltest cat gorp.file
} "test output"
test exec-4.2 {redirecting output and stderr to file} {execCommandExists stdio} {
    list [exec $tcltest sh -c "echo foo bar 1>&2" >&gorp.file] \
	    [exec $tcltest cat gorp.file]
} {{} {foo bar}}
test exec-4.3 {redirecting output and stderr to file} {execCommandExists stdio} {
    exec $tcltest echo "first line" > gorp.file
    list [exec $tcltest sh -c "echo foo bar 1>&2" >>&gorp.file] \
	    [exec $tcltest cat gorp.file]
} "{} {first line\nfoo bar}"
test exec-4.4 {redirecting output and stderr to file} {execCommandExists stdio} {
    set f [open gorp.file w]
    puts $f "Line 1"
    flush $f
    exec $tcltest echo "More text" >&@ $f
    exec $tcltest echo >&@$f "Even more"
    puts $f "Line 3"
    close $f
    exec $tcltest cat gorp.file
} "Line 1\nMore text\nEven more\nLine 3"
test exec-4.5 {redirecting output and stderr to file} {execCommandExists stdio} {
    set f [open gorp.file w]
    puts $f "Line 1"
    flush $f
    exec >&@ $f $tcltest sh -c "echo foo bar 1>&2"
    exec >&@$f $tcltest sh -c "echo xyzzy 1>&2"
    puts $f "Line 3"
    close $f
    exec $tcltest cat gorp.file
} "Line 1\nfoo bar\nxyzzy\nLine 3"

# I/O redirection: input from file.

exec $tcltest echo "Just a few thoughts" > gorp.file
test exec-5.1 {redirecting input from file} {execCommandExists stdio} {
    exec $tcltest cat < gorp.file
} {Just a few thoughts}
test exec-5.2 {redirecting input from file} {execCommandExists stdio} {
    exec $tcltest cat | $tcltest cat < gorp.file
} {Just a few thoughts}
test exec-5.3 {redirecting input from file} {execCommandExists stdio} {
    exec $tcltest cat < gorp.file | $tcltest cat
} {Just a few thoughts}
test exec-5.4 {redirecting input from file} {execCommandExists stdio} {
    exec < gorp.file $tcltest cat | $tcltest cat
} {Just a few thoughts}
test exec-5.5 {redirecting input from file} {execCommandExists stdio} {
    exec $tcltest cat <gorp.file
} {Just a few thoughts}
test exec-5.6 {redirecting input from file} {execCommandExists stdio} {
    set f [open gorp.file r]
    set result [exec $tcltest cat <@ $f]
    close $f
    set result
} {Just a few thoughts}
test exec-5.7 {redirecting input from file} {execCommandExists stdio} {
    set f [open gorp.file r]
    set result [exec <@$f $tcltest cat]
    close $f
    set result
} {Just a few thoughts}

# I/O redirection: standard error through a pipeline.

test exec-6.1 {redirecting stderr through a pipeline} {execCommandExists stdio} {
    exec $tcltest sh -c "echo foo bar" |& $tcltest cat
} "foo bar"
test exec-6.2 {redirecting stderr through a pipeline} {execCommandExists stdio} {
    exec $tcltest sh -c "echo foo bar 1>&2" |& $tcltest cat
} "foo bar"
test exec-6.3 {redirecting stderr through a pipeline} {execCommandExists stdio} {
    exec $tcltest sh -c "echo foo bar 1>&2" \
	|& $tcltest sh -c "echo second msg 1>&2 ; cat" |& $tcltest cat
} "second msg\nfoo bar"

# I/O redirection: combinations.

file delete gorp.file2
test exec-7.1 {multiple I/O redirections} {execCommandExists stdio} {
    exec << "command input" > gorp.file2 $tcltest cat < gorp.file
    exec $tcltest cat gorp.file2
} {Just a few thoughts}
test exec-7.2 {multiple I/O redirections} {execCommandExists stdio} {
    exec < gorp.file << "command input" $tcltest cat
} {command input}

# Long input to command and output from command.

set a "0123456789 xxxxxxxxx abcdefghi ABCDEFGHIJK\n"
set a [concat $a $a $a $a]
set a [concat $a $a $a $a]
set a [concat $a $a $a $a]
set a [concat $a $a $a $a]
test exec-8.1 {long input and output} {execCommandExists stdio} {
    exec $tcltest cat << $a
} $a

# More than 20 arguments to exec.

test exec-8.1 {long input and output} {execCommandExists stdio} {
    exec $tcltest echo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23}

# Commands that return errors.

test exec-9.1 {commands returning errors} {execCommandExists stdio} {
    set x [catch {exec gorp456} msg]
    list $x [string tolower $msg] [string tolower $errorCode]
} {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}}
test exec-9.2 {commands returning errors} {execCommandExists stdio} {
    string tolower [list [catch {exec $tcltest echo foo | foo123} msg] $msg $errorCode]
} {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}}
test exec-9.3 {commands returning errors} {execCommandExists stdio} {
    list [catch {exec $tcltest sleep 1 | $tcltest exit 43 | $tcltest sleep 1} msg] $msg
} {1 {child process exited abnormally}}
test exec-9.4 {commands returning errors} {execCommandExists stdio} {
    list [catch {exec $tcltest exit 43 | $tcltest echo "foo bar"} msg] $msg
} {1 {foo bar
child process exited abnormally}}
test exec-9.5 {commands returning errors} {execCommandExists stdio} {
    list [catch {exec gorp456 | $tcltest echo a b c} msg] [string tolower $msg]
} {1 {couldn't execute "gorp456": no such file or directory}}
test exec-9.6 {commands returning errors} {execCommandExists stdio} {
    list [catch {exec $tcltest sh -c "echo error msg 1>&2"} msg] $msg
} {1 {error msg}}
test exec-9.7 {commands returning errors} {execCommandExists stdio} {
    list [catch {exec $tcltest sh -c "echo error msg 1>&2" \
		     | $tcltest sh -c "echo error msg 1>&2"} msg] $msg
} {1 {error msg
error msg}}
test exec-9.8 {commands returning errors} {execCommandExists stdio} {
    set f [open err w]
    puts $f {
	puts stdout out
	puts stderr err
    }
    close $f
    list [catch {exec $tcltest err} msg] $msg
} {1 {out
err}}

# Errors in executing the Tcl command, as opposed to errors in the
# processes that are invoked.

test exec-10.1 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec} msg] $msg
} {1 {wrong # args: should be "exec ?switches? arg ?arg ...?"}}
test exec-10.2 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec | cat} msg] $msg
} {1 {illegal use of | or |& in command}}
test exec-10.3 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat |} msg] $msg
} {1 {illegal use of | or |& in command}}
test exec-10.4 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat | | cat} msg] $msg
} {1 {illegal use of | or |& in command}}
test exec-10.5 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat | |& cat} msg] $msg
} {1 {illegal use of | or |& in command}}
test exec-10.6 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat |&} msg] $msg
} {1 {illegal use of | or |& in command}}
test exec-10.7 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat <} msg] $msg
} {1 {can't specify "<" as last word in command}}
test exec-10.8 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat >} msg] $msg
} {1 {can't specify ">" as last word in command}}
test exec-10.9 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat <<} msg] $msg
} {1 {can't specify "<<" as last word in command}}
test exec-10.10 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat >>} msg] $msg
} {1 {can't specify ">>" as last word in command}}
test exec-10.11 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat >&} msg] $msg
} {1 {can't specify ">&" as last word in command}}
test exec-10.12 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat >>&} msg] $msg
} {1 {can't specify ">>&" as last word in command}}
test exec-10.13 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat >@} msg] $msg
} {1 {can't specify ">@" as last word in command}}
test exec-10.14 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat <@} msg] $msg
} {1 {can't specify "<@" as last word in command}}
test exec-10.15 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat < a/b/c} msg] [string tolower $msg]
} {1 {couldn't read file "a/b/c": no such file or directory}}
test exec-10.16 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat << foo > a/b/c} msg] [string tolower $msg]
} {1 {couldn't write file "a/b/c": no such file or directory}}
test exec-10.17 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat << foo > a/b/c} msg] [string tolower $msg]
} {1 {couldn't write file "a/b/c": no such file or directory}}
set f [open gorp.file w]
test exec-10.18 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat <@ $f} msg] $msg
} "1 {channel \"$f\" wasn't opened for reading}"
close $f
set f [open gorp.file r]
test exec-10.19 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec cat >@ $f} msg] $msg
} "1 {channel \"$f\" wasn't opened for writing}"
close $f
test exec-10.20 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec ~non_existent_user/foo/bar} msg] $msg
} {1 {user "non_existent_user" doesn't exist}}
test exec-10.21 {errors in exec invocation} {execCommandExists stdio} {
    list [catch {exec $tcltest true | ~xyzzy_bad_user/x | false} msg] $msg
} {1 {user "xyzzy_bad_user" doesn't exist}}

# Commands in background.

test exec-11.1 {commands in background} {execCommandExists stdio} {
    set x [lindex [time {exec $tcltest sleep 2 &}] 0]
    expr $x<1000000
} 1
test exec-11.2 {commands in background} {execCommandExists stdio} {
    list [catch {exec $tcltest echo a &b} msg] $msg
} {0 {a &b}}
test exec-11.3 {commands in background} {execCommandExists stdio} {
    llength [exec $tcltest sleep 1 &]
} 1
test exec-11.4 {commands in background} {execCommandExists stdio} {
    llength [exec $tcltest sleep 1 | $tcltest sleep 1 | $tcltest sleep 1 &]
} 3
test exec-11.5 {commands in background} {execCommandExists stdio} {
    set f [open gorp.file w]
    puts $f { catch { exec [info nameofexecutable] echo foo & } }
    close $f
    string compare "foo" [exec $tcltest gorp.file]
} 0

# Make sure that background commands are properly reaped when
# they eventually die.

exec $tcltest sleep 3
test exec-12.1 {reaping background processes} \
	{execCommandExists stdio unixOnly nonPortable} {
    for {set i 0} {$i < 20} {incr i} {
	exec echo foo > /dev/null &
    }
    exec sleep 1
    catch {exec ps | fgrep "echo foo" | fgrep -v fgrep | wc} msg
    lindex $msg 0
} 0
test exec-12.2 {reaping background processes} \
	{execCommandExists stdio unixOnly nonPortable} {
    exec sleep 2 | sleep 2 | sleep 2 &
    catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
    set x [lindex $msg 0]
    exec sleep 3
    catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
    list $x [lindex $msg 0]
} {3 0}
test exec-12.3 {reaping background processes} \
	{execCommandExists stdio unixOnly nonPortable} {
    exec sleep 1000 &
    exec sleep 1000 &
    set x [exec ps | fgrep "sleep" | fgrep -v fgrep]
    set pids {}
    foreach i [split $x \n] {
	lappend pids [lindex $i 0]
    }
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















    }
    catch {exec ps | fgrep "sleep" | fgrep -v fgrep | wc} msg
    list $x [lindex $msg 0]
} {2 0}

# Make sure "errorCode" is set correctly.

test exec-13.1 {setting errorCode variable} {
    list [catch {exec $tcltest cat < a/b/c} msg] [string tolower $errorCode]
} {1 {posix enoent {no such file or directory}}}
test exec-13.2 {setting errorCode variable} {
    list [catch {exec $tcltest cat > a/b/c} msg] [string tolower $errorCode]
} {1 {posix enoent {no such file or directory}}}
test exec-13.3 {setting errorCode variable} {
    set x [catch {exec _weird_cmd_} msg]
    list $x [string tolower $msg] [lindex $errorCode 0] \
	    [string tolower [lrange $errorCode 2 end]]
} {1 {couldn't execute "_weird_cmd_": no such file or directory} POSIX {{no such file or directory}}}

# Switches before the first argument

test exec-14.1 {-keepnewline switch} {
    exec -keepnewline $tcltest echo foo
} "foo\n"
test exec-14.2 {-keepnewline switch} {
    list [catch {exec -keepnewline} msg] $msg
} {1 {wrong # args: should be "exec ?switches? arg ?arg ...?"}}
test exec-14.3 {unknown switch} {
    list [catch {exec -gorp} msg] $msg
} {1 {bad switch "-gorp": must be -keepnewline or --}}
test exec-14.4 {-- switch} {
    list [catch {exec -- -gorp} msg] [string tolower $msg]
} {1 {couldn't execute "-gorp": no such file or directory}}

# Redirecting standard error separately from standard output

test exec-15.1 {standard error redirection} {
    exec $tcltest echo "First line" > gorp.file
    list [exec $tcltest sh -c "echo foo bar 1>&2" 2> gorp.file] \
	    [exec $tcltest cat gorp.file]
} {{} {foo bar}}
test exec-15.2 {standard error redirection} {
    list [exec $tcltest sh -c "echo foo bar 1>&2" \
		| $tcltest echo biz baz >gorp.file 2> gorp.file2] \
	    [exec $tcltest cat gorp.file] \
	    [exec $tcltest cat gorp.file2]
} {{} {biz baz} {foo bar}}
test exec-15.3 {standard error redirection} {
    list [exec $tcltest sh -c "echo foo bar 1>&2" \
	        | $tcltest echo biz baz 2>gorp.file > gorp.file2] \
	    [exec $tcltest cat gorp.file] \
	    [exec $tcltest cat gorp.file2]
} {{} {foo bar} {biz baz}}
test exec-15.4 {standard error redirection} {
    set f [open gorp.file w]
    puts $f "Line 1"
    flush $f
    exec $tcltest sh -c "echo foo bar 1>&2" 2>@ $f
    puts $f "Line 3"
    close $f
    exec $tcltest cat gorp.file
} {Line 1
foo bar
Line 3}
test exec-15.5 {standard error redirection} {
    exec $tcltest echo "First line" > gorp.file
    exec $tcltest sh -c "echo foo bar 1>&2" 2>> gorp.file
    exec $tcltest cat gorp.file
} {First line
foo bar}
test exec-15.6 {standard error redirection} {
    exec $tcltest sh -c "echo foo bar 1>&2" > gorp.file2 2> gorp.file \
	    >& gorp.file 2> gorp.file2 | $tcltest echo biz baz
    list [exec $tcltest cat gorp.file] [exec $tcltest cat gorp.file2]
} {{biz baz} {foo bar}}

test exec-16.1 {flush output before exec} {
    set f [open gorp.file w]
    puts $f "First line"
    exec $tcltest echo "Second line" >@ $f
    puts $f "Third line"
    close $f
    exec $tcltest cat gorp.file
} {First line
Second line
Third line}
test exec-16.2 {flush output before exec} {} {
    set f [open gorp.file w]
    puts $f "First line"
    exec $tcltest << {puts stderr {Second line}} >&@ $f > gorp.file2
    puts $f "Third line"
    close $f
    exec $tcltest cat gorp.file
} {First line
Second line
Third line}

test exec-17.1 { inheriting standard I/O } {
    set f [open script w]
    puts $f {close stdout
	set f [open gorp.file w]
	catch {exec [info nameofexecutable] echo foobar &}
	exec [info nameofexecutable] sleep 2
	close $f
    }
    close $f
    catch {exec $tcltest script} result
    set f [open gorp.file r]
    lappend result [read $f]
    close $f
    set result
} {{foobar
}}


file delete script gorp.file gorp.file2
file delete echo cat wc sh sleep exit






















|


|


|







|


|


|


|





|




|





|





|










|





|





|









|










|
















>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    }
    catch {exec ps | fgrep "sleep" | fgrep -v fgrep | wc} msg
    list $x [lindex $msg 0]
} {2 0}

# Make sure "errorCode" is set correctly.

test exec-13.1 {setting errorCode variable} {execCommandExists stdio} {
    list [catch {exec $tcltest cat < a/b/c} msg] [string tolower $errorCode]
} {1 {posix enoent {no such file or directory}}}
test exec-13.2 {setting errorCode variable} {execCommandExists stdio} {
    list [catch {exec $tcltest cat > a/b/c} msg] [string tolower $errorCode]
} {1 {posix enoent {no such file or directory}}}
test exec-13.3 {setting errorCode variable} {execCommandExists stdio} {
    set x [catch {exec _weird_cmd_} msg]
    list $x [string tolower $msg] [lindex $errorCode 0] \
	    [string tolower [lrange $errorCode 2 end]]
} {1 {couldn't execute "_weird_cmd_": no such file or directory} POSIX {{no such file or directory}}}

# Switches before the first argument

test exec-14.1 {-keepnewline switch} {execCommandExists stdio} {
    exec -keepnewline $tcltest echo foo
} "foo\n"
test exec-14.2 {-keepnewline switch} {execCommandExists stdio} {
    list [catch {exec -keepnewline} msg] $msg
} {1 {wrong # args: should be "exec ?switches? arg ?arg ...?"}}
test exec-14.3 {unknown switch} {execCommandExists stdio} {
    list [catch {exec -gorp} msg] $msg
} {1 {bad switch "-gorp": must be -keepnewline or --}}
test exec-14.4 {-- switch} {execCommandExists stdio} {
    list [catch {exec -- -gorp} msg] [string tolower $msg]
} {1 {couldn't execute "-gorp": no such file or directory}}

# Redirecting standard error separately from standard output

test exec-15.1 {standard error redirection} {execCommandExists stdio} {
    exec $tcltest echo "First line" > gorp.file
    list [exec $tcltest sh -c "echo foo bar 1>&2" 2> gorp.file] \
	    [exec $tcltest cat gorp.file]
} {{} {foo bar}}
test exec-15.2 {standard error redirection} {execCommandExists stdio} {
    list [exec $tcltest sh -c "echo foo bar 1>&2" \
		| $tcltest echo biz baz >gorp.file 2> gorp.file2] \
	    [exec $tcltest cat gorp.file] \
	    [exec $tcltest cat gorp.file2]
} {{} {biz baz} {foo bar}}
test exec-15.3 {standard error redirection} {execCommandExists stdio} {
    list [exec $tcltest sh -c "echo foo bar 1>&2" \
	        | $tcltest echo biz baz 2>gorp.file > gorp.file2] \
	    [exec $tcltest cat gorp.file] \
	    [exec $tcltest cat gorp.file2]
} {{} {foo bar} {biz baz}}
test exec-15.4 {standard error redirection} {execCommandExists stdio} {
    set f [open gorp.file w]
    puts $f "Line 1"
    flush $f
    exec $tcltest sh -c "echo foo bar 1>&2" 2>@ $f
    puts $f "Line 3"
    close $f
    exec $tcltest cat gorp.file
} {Line 1
foo bar
Line 3}
test exec-15.5 {standard error redirection} {execCommandExists stdio} {
    exec $tcltest echo "First line" > gorp.file
    exec $tcltest sh -c "echo foo bar 1>&2" 2>> gorp.file
    exec $tcltest cat gorp.file
} {First line
foo bar}
test exec-15.6 {standard error redirection} {execCommandExists stdio} {
    exec $tcltest sh -c "echo foo bar 1>&2" > gorp.file2 2> gorp.file \
	    >& gorp.file 2> gorp.file2 | $tcltest echo biz baz
    list [exec $tcltest cat gorp.file] [exec $tcltest cat gorp.file2]
} {{biz baz} {foo bar}}

test exec-16.1 {flush output before exec} {execCommandExists stdio} {
    set f [open gorp.file w]
    puts $f "First line"
    exec $tcltest echo "Second line" >@ $f
    puts $f "Third line"
    close $f
    exec $tcltest cat gorp.file
} {First line
Second line
Third line}
test exec-16.2 {flush output before exec} {execCommandExists stdio} {
    set f [open gorp.file w]
    puts $f "First line"
    exec $tcltest << {puts stderr {Second line}} >&@ $f > gorp.file2
    puts $f "Third line"
    close $f
    exec $tcltest cat gorp.file
} {First line
Second line
Third line}

test exec-17.1 { inheriting standard I/O } {execCommandExists stdio} {
    set f [open script w]
    puts $f {close stdout
	set f [open gorp.file w]
	catch {exec [info nameofexecutable] echo foobar &}
	exec [info nameofexecutable] sleep 2
	close $f
    }
    close $f
    catch {exec $tcltest script} result
    set f [open gorp.file r]
    lappend result [read $f]
    close $f
    set result
} {{foobar
}}

# cleanup
file delete script gorp.file gorp.file2
file delete echo cat wc sh sleep exit
file delete err
::tcltest::cleanupTests
return












Changes to tests/execute.test.

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
# This file contains tests for the tclExecute.c source file. Tests appear
# in the same order as the C code that they test. The set of tests is
# currently incomplete since it currently includes only new tests for
# code changed for the addition of Tcl namespaces. Other execution-
# related tests appear in several other test files including
# namespace.test, basic.test, eval.test, for.test, etc.
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) execute.test 1.5 97/08/12 11:16:31



if {[string compare test [info procs test]] == 1} then {source defs}

catch {eval namespace delete [namespace children :: test_ns_*]}
catch {rename foo ""}
catch {unset x}
catch {unset y}
catch {unset msg}






























































































































































































































































































































































































































test execute-1.1 {Tcl_GetCommandFromObj, convert to tclCmdNameType} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {unset x}
    catch {unset y}
    namespace eval test_ns_1 {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_1::test_ns_2 {
        namespace import ::test_ns_1::*
    }
    set x "test_ns_1::"
    set y "test_ns_2::"
    list [namespace which -command ${x}${y}cmd1] \
         [catch {namespace which -command ${x}${y}cmd2} msg] $msg \
         [catch {namespace which -command ${x}${y}:cmd2} msg] $msg
} {::test_ns_1::test_ns_2::cmd1 0 {} 0 {}}
test execute-1.2 {Tcl_GetCommandFromObj, check if cached tclCmdNameType is invalid} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename foo ""}
    catch {unset l}
    proc foo {} {
        return "global foo"
    }
    namespace eval test_ns_1 {











>




>
|
>
>
|
<







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

















|







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

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

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


catch {eval namespace delete [namespace children :: test_ns_*]}
catch {rename foo ""}
catch {unset x}
catch {unset y}
catch {unset msg}

set ::tcltest::testConfig(testobj) \
	[expr {[info commands testobj] != {} \
	&& [info commands testdoubleobj] != {} \
	&& [info commands teststringobj] != {} \
	&& [info commands testobj] != {}}]

# Tests for the omnibus TclExecuteByteCode function:

# INST_DONE not tested
# INST_PUSH1 not tested
# INST_PUSH4 not tested
# INST_POP not tested
# INST_DUP not tested
# INST_CONCAT1 not tested
# INST_INVOKE_STK4 not tested
# INST_INVOKE_STK1 not tested
# INST_EVAL_STK not tested
# INST_EXPR_STK not tested
# INST_LOAD_SCALAR1 not tested
# INST_LOAD_SCALAR4 not tested
# INST_LOAD_SCALAR_STK not tested
# INST_LOAD_ARRAY4 not tested
# INST_LOAD_ARRAY1 not tested
# INST_LOAD_ARRAY_STK not tested
# INST_LOAD_STK not tested
# INST_STORE_SCALAR4 not tested
# INST_STORE_SCALAR1 not tested
# INST_STORE_SCALAR_STK not tested
# INST_STORE_ARRAY4 not tested
# INST_STORE_ARRAY1 not tested
# INST_STORE_ARRAY_STK not tested
# INST_STORE_STK not tested
# INST_INCR_SCALAR1 not tested
# INST_INCR_SCALAR_STK not tested
# INST_INCR_STK not tested
# INST_INCR_ARRAY1 not tested
# INST_INCR_ARRAY_STK not tested
# INST_INCR_SCALAR1_IMM not tested
# INST_INCR_SCALAR_STK_IMM not tested
# INST_INCR_STK_IMM not tested
# INST_INCR_ARRAY1_IMM not tested
# INST_INCR_ARRAY_STK_IMM not tested
# INST_JUMP1 not tested
# INST_JUMP4 not tested
# INST_JUMP_TRUE4 not tested
# INST_JUMP_TRUE1 not tested
# INST_JUMP_FALSE4 not tested
# INST_JUMP_FALSE1 not tested
# INST_LOR not tested
# INST_LAND not tested
# INST_EQ not tested
# INST_NEQ not tested
# INST_LT not tested
# INST_GT not tested
# INST_LE not tested
# INST_GE not tested
# INST_MOD not tested
# INST_LSHIFT not tested
# INST_RSHIFT not tested
# INST_BITOR not tested
# INST_BITXOR not tested
# INST_BITAND not tested

# INST_ADD is partially tested:
test execute-1.1 {TclExecuteByteCode, INST_ADD, op1 is int} {testobj} {
    set x [testintobj set 0 1]
    expr {$x + 1}
} 2
test execute-1.2 {TclExecuteByteCode, INST_ADD, op1 is double} {testobj} {
    set x [testdoubleobj set 0 1]
    expr {$x + 1}
} 2.0
test execute-1.3 {TclExecuteByteCode, INST_ADD, op1 is double with string} {testobj} {
    set x [testintobj set 0 1]
    testobj convert 0 double
    expr {$x + 1}
} 2
test execute-1.4 {TclExecuteByteCode, INST_ADD, op1 is string int} {testobj} {
    set x [teststringobj set 0 1]
    expr {$x + 1}
} 2
test execute-1.5 {TclExecuteByteCode, INST_ADD, op1 is string double} {testobj} {
    set x [teststringobj set 0 1.0]
    expr {$x + 1}
} 2.0
test execute-1.6 {TclExecuteByteCode, INST_ADD, op1 is non-numeric} {testobj} {
    set x [teststringobj set 0 foo]
    list [catch {expr {$x + 1}} msg] $msg
} {1 {can't use non-numeric string as operand of "+"}}
test execute-1.7 {TclExecuteByteCode, INST_ADD, op2 is int} {testobj} {
    set x [testintobj set 0 1]
    expr {1 + $x}
} 2
test execute-1.8 {TclExecuteByteCode, INST_ADD, op2 is double} {testobj} {
    set x [testdoubleobj set 0 1]
    expr {1 + $x}
} 2.0
test execute-1.9 {TclExecuteByteCode, INST_ADD, op2 is double with string} {testobj} {
    set x [testintobj set 0 1]
    testobj convert 0 double
    expr {1 + $x}
} 2
test execute-1.10 {TclExecuteByteCode, INST_ADD, op2 is string int} {testobj} {
    set x [teststringobj set 0 1]
    expr {1 + $x}
} 2
test execute-1.11 {TclExecuteByteCode, INST_ADD, op2 is string double} {testobj} {
    set x [teststringobj set 0 1.0]
    expr {1 + $x}
} 2.0
test execute-1.12 {TclExecuteByteCode, INST_ADD, op2 is non-numeric} {testobj} {
    set x [teststringobj set 0 foo]
    list [catch {expr {1 + $x}} msg] $msg
} {1 {can't use non-numeric string as operand of "+"}}

# INST_SUB is partially tested:
test execute-1.13 {TclExecuteByteCode, INST_SUB, op1 is int} {testobj} {
    set x [testintobj set 0 1]
    expr {$x - 1}
} 0
test execute-1.14 {TclExecuteByteCode, INST_SUB, op1 is double} {testobj} {
    set x [testdoubleobj set 0 1]
    expr {$x - 1}
} 0.0
test execute-1.15 {TclExecuteByteCode, INST_SUB, op1 is double with string} {testobj} {
    set x [testintobj set 0 1]
    testobj convert 0 double
    expr {$x - 1}
} 0
test execute-1.16 {TclExecuteByteCode, INST_SUB, op1 is string int} {testobj} {
    set x [teststringobj set 0 1]
    expr {$x - 1}
} 0
test execute-1.17 {TclExecuteByteCode, INST_SUB, op1 is string double} {testobj} {
    set x [teststringobj set 0 1.0]
    expr {$x - 1}
} 0.0
test execute-1.18 {TclExecuteByteCode, INST_SUB, op1 is non-numeric} {testobj} {
    set x [teststringobj set 0 foo]
    list [catch {expr {$x - 1}} msg] $msg
} {1 {can't use non-numeric string as operand of "-"}}
test execute-1.19 {TclExecuteByteCode, INST_SUB, op2 is int} {testobj} {
    set x [testintobj set 0 1]
    expr {1 - $x}
} 0
test execute-1.20 {TclExecuteByteCode, INST_SUB, op2 is double} {testobj} {
    set x [testdoubleobj set 0 1]
    expr {1 - $x}
} 0.0
test execute-1.21 {TclExecuteByteCode, INST_SUB, op2 is double with string} {testobj} {
    set x [testintobj set 0 1]
    testobj convert 0 double
    expr {1 - $x}
} 0
test execute-1.22 {TclExecuteByteCode, INST_SUB, op2 is string int} {testobj} {
    set x [teststringobj set 0 1]
    expr {1 - $x}
} 0
test execute-1.23 {TclExecuteByteCode, INST_SUB, op2 is string double} {testobj} {
    set x [teststringobj set 0 1.0]
    expr {1 - $x}
} 0.0
test execute-1.24 {TclExecuteByteCode, INST_SUB, op2 is non-numeric} {testobj} {
    set x [teststringobj set 0 foo]
    list [catch {expr {1 - $x}} msg] $msg
} {1 {can't use non-numeric string as operand of "-"}}

# INST_MULT is partially tested:
test execute-1.25 {TclExecuteByteCode, INST_MULT, op1 is int} {testobj} {
    set x [testintobj set 1 1]
    expr {$x * 1}
} 1
test execute-1.26 {TclExecuteByteCode, INST_MULT, op1 is double} {testobj} {
    set x [testdoubleobj set 1 2.0]
    expr {$x * 1}
} 2.0
test execute-1.27 {TclExecuteByteCode, INST_MULT, op1 is double with string} {testobj} {
    set x [testintobj set 1 2]
    testobj convert 1 double
    expr {$x * 1}
} 2
test execute-1.28 {TclExecuteByteCode, INST_MULT, op1 is string int} {testobj} {
    set x [teststringobj set 1 1]
    expr {$x * 1}
} 1
test execute-1.29 {TclExecuteByteCode, INST_MULT, op1 is string double} {testobj} {
    set x [teststringobj set 1 1.0]
    expr {$x * 1}
} 1.0
test execute-1.30 {TclExecuteByteCode, INST_MULT, op1 is non-numeric} {testobj} {
    set x [teststringobj set 1 foo]
    list [catch {expr {$x * 1}} msg] $msg
} {1 {can't use non-numeric string as operand of "*"}}
test execute-1.31 {TclExecuteByteCode, INST_MULT, op2 is int} {testobj} {
    set x [testintobj set 1 1]
    expr {1 * $x}
} 1
test execute-1.32 {TclExecuteByteCode, INST_MULT, op2 is double} {testobj} {
    set x [testdoubleobj set 1 2.0]
    expr {1 * $x}
} 2.0
test execute-1.33 {TclExecuteByteCode, INST_MULT, op2 is double with string} {testobj} {
    set x [testintobj set 1 2]
    testobj convert 1 double
    expr {1 * $x}
} 2
test execute-1.34 {TclExecuteByteCode, INST_MULT, op2 is string int} {testobj} {
    set x [teststringobj set 1 1]
    expr {1 * $x}
} 1
test execute-1.35 {TclExecuteByteCode, INST_MULT, op2 is string double} {testobj} {
    set x [teststringobj set 1 1.0]
    expr {1 * $x}
} 1.0
test execute-1.36 {TclExecuteByteCode, INST_MULT, op2 is non-numeric} {testobj} {
    set x [teststringobj set 1 foo]
    list [catch {expr {1 * $x}} msg] $msg
} {1 {can't use non-numeric string as operand of "*"}}

# INST_DIV is partially tested:
test execute-1.37 {TclExecuteByteCode, INST_DIV, op1 is int} {testobj} {
    set x [testintobj set 1 1]
    expr {$x / 1}
} 1
test execute-1.38 {TclExecuteByteCode, INST_DIV, op1 is double} {testobj} {
    set x [testdoubleobj set 1 2.0]
    expr {$x / 1}
} 2.0
test execute-1.39 {TclExecuteByteCode, INST_DIV, op1 is double with string} {testobj} {
    set x [testintobj set 1 2]
    testobj convert 1 double
    expr {$x / 1}
} 2
test execute-1.40 {TclExecuteByteCode, INST_DIV, op1 is string int} {testobj} {
    set x [teststringobj set 1 1]
    expr {$x / 1}
} 1
test execute-1.41 {TclExecuteByteCode, INST_DIV, op1 is string double} {testobj} {
    set x [teststringobj set 1 1.0]
    expr {$x / 1}
} 1.0
test execute-1.42 {TclExecuteByteCode, INST_DIV, op1 is non-numeric} {testobj} {
    set x [teststringobj set 1 foo]
    list [catch {expr {$x / 1}} msg] $msg
} {1 {can't use non-numeric string as operand of "/"}}
test execute-1.43 {TclExecuteByteCode, INST_DIV, op2 is int} {testobj} {
    set x [testintobj set 1 1]
    expr {2 / $x}
} 2
test execute-1.44 {TclExecuteByteCode, INST_DIV, op2 is double} {testobj} {
    set x [testdoubleobj set 1 1.0]
    expr {2 / $x}
} 2.0
test execute-1.45 {TclExecuteByteCode, INST_DIV, op2 is double with string} {testobj} {
    set x [testintobj set 1 1]
    testobj convert 1 double
    expr {2 / $x}
} 2
test execute-1.46 {TclExecuteByteCode, INST_DIV, op2 is string int} {testobj} {
    set x [teststringobj set 1 1]
    expr {2 / $x}
} 2
test execute-1.47 {TclExecuteByteCode, INST_DIV, op2 is string double} {testobj} {
    set x [teststringobj set 1 1.0]
    expr {2 / $x}
} 2.0
test execute-1.48 {TclExecuteByteCode, INST_DIV, op2 is non-numeric} {testobj} {
    set x [teststringobj set 1 foo]
    list [catch {expr {1 / $x}} msg] $msg
} {1 {can't use non-numeric string as operand of "/"}}

# INST_UPLUS is partially tested:
test execute-1.49 {TclExecuteByteCode, INST_UPLUS, op is int} {testobj} {
    set x [testintobj set 1 1]
    expr {+ $x}
} 1
test execute-1.50 {TclExecuteByteCode, INST_UPLUS, op is double} {testobj} {
    set x [testdoubleobj set 1 1.0]
    expr {+ $x}
} 1.0
test execute-1.51 {TclExecuteByteCode, INST_UPLUS, op is double with string} {testobj} {
    set x [testintobj set 1 1]
    testobj convert 1 double
    expr {+ $x}
} 1
test execute-1.52 {TclExecuteByteCode, INST_UPLUS, op is string int} {testobj} {
    set x [teststringobj set 1 1]
    expr {+ $x}
} 1
test execute-1.53 {TclExecuteByteCode, INST_UPLUS, op is string double} {testobj} {
    set x [teststringobj set 1 1.0]
    expr {+ $x}
} 1.0
test execute-1.54 {TclExecuteByteCode, INST_UPLUS, op is non-numeric} {testobj} {
    set x [teststringobj set 1 foo]
    list [catch {expr {+ $x}} msg] $msg
} {1 {can't use non-numeric string as operand of "+"}}

# INST_UMINUS is partially tested:
test execute-1.55 {TclExecuteByteCode, INST_UMINUS, op is int} {testobj} {
    set x [testintobj set 1 1]
    expr {- $x}
} -1
test execute-1.56 {TclExecuteByteCode, INST_UMINUS, op is double} {testobj} {
    set x [testdoubleobj set 1 1.0]
    expr {- $x}
} -1.0
test execute-1.57 {TclExecuteByteCode, INST_UMINUS, op is double with string} {testobj} {
    set x [testintobj set 1 1]
    testobj convert 1 double
    expr {- $x}
} -1
test execute-1.58 {TclExecuteByteCode, INST_UMINUS, op is string int} {testobj} {
    set x [teststringobj set 1 1]
    expr {- $x}
} -1
test execute-1.59 {TclExecuteByteCode, INST_UMINUS, op is string double} {testobj} {
    set x [teststringobj set 1 1.0]
    expr {- $x}
} -1.0
test execute-1.60 {TclExecuteByteCode, INST_UMINUS, op is non-numeric} {testobj} {
    set x [teststringobj set 1 foo]
    list [catch {expr {- $x}} msg] $msg
} {1 {can't use non-numeric string as operand of "-"}}

# INST_LNOT is partially tested:
test execute-1.61 {TclExecuteByteCode, INST_LNOT, op is int} {testobj} {
    set x [testintobj set 1 2]
    expr {! $x}
} 0
test execute-1.62 {TclExecuteByteCode, INST_LNOT, op is int} {testobj} {
    set x [testintobj set 1 0]
    expr {! $x}
} 1
test execute-1.63 {TclExecuteByteCode, INST_LNOT, op is double} {testobj} {
    set x [testdoubleobj set 1 1.0]
    expr {! $x}
} 0
test execute-1.64 {TclExecuteByteCode, INST_LNOT, op is double} {testobj} {
    set x [testdoubleobj set 1 0.0]
    expr {! $x}
} 1
test execute-1.65 {TclExecuteByteCode, INST_LNOT, op is double with string} {testobj} {
    set x [testintobj set 1 1]
    testobj convert 1 double
    expr {! $x}
} 0
test execute-1.66 {TclExecuteByteCode, INST_LNOT, op is double with string} {testobj} {
    set x [testintobj set 1 0]
    testobj convert 1 double
    expr {! $x}
} 1
test execute-1.67 {TclExecuteByteCode, INST_LNOT, op is string int} {testobj} {
    set x [teststringobj set 1 1]
    expr {! $x}
} 0
test execute-1.68 {TclExecuteByteCode, INST_LNOT, op is string int} {testobj} {
    set x [teststringobj set 1 0]
    expr {! $x}
} 1
test execute-1.69 {TclExecuteByteCode, INST_LNOT, op is string double} {testobj} {
    set x [teststringobj set 1 1.0]
    expr {! $x}
} 0
test execute-1.70 {TclExecuteByteCode, INST_LNOT, op is string double} {testobj} {
    set x [teststringobj set 1 0.0]
    expr {! $x}
} 1
test execute-1.71 {TclExecuteByteCode, INST_LNOT, op is non-numeric} {testobj} {
    set x [teststringobj set 1 foo]
    list [catch {expr {! $x}} msg] $msg
} {1 {can't use non-numeric string as operand of "!"}}

# INST_BITNOT not tested
# INST_CALL_BUILTIN_FUNC1 not tested
# INST_CALL_FUNC1 not tested

# INST_TRY_CVT_TO_NUMERIC is partially tested:
test execute-1.72 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is int} {testobj} {
    set x [testintobj set 1 1]
    expr {$x}
} 1
test execute-1.73 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is double} {testobj} {
    set x [testdoubleobj set 1 1.0]
    expr {$x}
} 1.0
test execute-1.74 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is double with string} {testobj} {
    set x [testintobj set 1 1]
    testobj convert 1 double
    expr {$x}
} 1
test execute-1.75 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is string int} {testobj} {
    set x [teststringobj set 1 1]
    expr {$x}
} 1
test execute-1.76 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is string double} {testobj} {
    set x [teststringobj set 1 1.0]
    expr {$x}
} 1.0
test execute-1.77 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is non-numeric} {testobj} {
    set x [teststringobj set 1 foo]
    expr {$x}
} foo

# INST_BREAK not tested
# INST_CONTINUE not tested
# INST_FOREACH_START4 not tested
# INST_FOREACH_STEP4 not tested
# INST_BEGIN_CATCH4 not tested
# INST_END_CATCH not tested
# INST_PUSH_RESULT not tested
# INST_PUSH_RETURN_CODE not tested

test execute-2.1 {Tcl_GetCommandFromObj, convert to tclCmdNameType} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {unset x}
    catch {unset y}
    namespace eval test_ns_1 {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
        proc cmd2 {args} {return "cmd2: $args"}
    }
    namespace eval test_ns_1::test_ns_2 {
        namespace import ::test_ns_1::*
    }
    set x "test_ns_1::"
    set y "test_ns_2::"
    list [namespace which -command ${x}${y}cmd1] \
         [catch {namespace which -command ${x}${y}cmd2} msg] $msg \
         [catch {namespace which -command ${x}${y}:cmd2} msg] $msg
} {::test_ns_1::test_ns_2::cmd1 0 {} 0 {}}
test execute-2.2 {Tcl_GetCommandFromObj, check if cached tclCmdNameType is invalid} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename foo ""}
    catch {unset l}
    proc foo {} {
        return "global foo"
    }
    namespace eval test_ns_1 {
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















        proc foo {} {
            return "namespace foo"
        }
    }
    lappend l [test_ns_1::whichFoo]
    set l
} {::foo ::test_ns_1::foo}
test execute-1.3 {Tcl_GetCommandFromObj, command never found} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename foo ""}
    namespace eval test_ns_1 {
        proc foo {} {
            return "namespace foo"
        }
    }
    namespace eval test_ns_1 {
        proc foo {} {
            return "namespace foo"
        }
    }
    list [namespace eval test_ns_1 {namespace which -command foo}] \
         [rename test_ns_1::foo ""] \
         [catch {namespace eval test_ns_1 {namespace which -command foo}} msg] $msg
} {::test_ns_1::foo {} 0 {}}

test execute-2.1 {SetCmdNameFromAny, set cmd name to empty heap string if NULL} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {unset l}
    proc {} {} {return {}}
    {}
    set l {}
    lindex {} 0
    {}
} {}

test execute-3.1 {UpdateStringOfCmdName: called for duplicate of empty cmdName object} {
    proc {} {} {}
    proc { } {} {}
    proc p {} {
        set x {}
        $x
        append x { }
        $x
    }
    p
} {}


catch {eval namespace delete [namespace children :: test_ns_*]}
catch {rename foo ""}
catch {rename p ""}
catch {rename {} ""}
catch {rename { } ""}
catch {unset x}
catch {unset y}
catch {unset msg}


concat {}






















|

















|









|











>








>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
        proc foo {} {
            return "namespace foo"
        }
    }
    lappend l [test_ns_1::whichFoo]
    set l
} {::foo ::test_ns_1::foo}
test execute-2.3 {Tcl_GetCommandFromObj, command never found} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {rename foo ""}
    namespace eval test_ns_1 {
        proc foo {} {
            return "namespace foo"
        }
    }
    namespace eval test_ns_1 {
        proc foo {} {
            return "namespace foo"
        }
    }
    list [namespace eval test_ns_1 {namespace which -command foo}] \
         [rename test_ns_1::foo ""] \
         [catch {namespace eval test_ns_1 {namespace which -command foo}} msg] $msg
} {::test_ns_1::foo {} 0 {}}

test execute-3.1 {SetCmdNameFromAny, set cmd name to empty heap string if NULL} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    catch {unset l}
    proc {} {} {return {}}
    {}
    set l {}
    lindex {} 0
    {}
} {}

test execute-4.1 {UpdateStringOfCmdName: called for duplicate of empty cmdName object} {
    proc {} {} {}
    proc { } {} {}
    proc p {} {
        set x {}
        $x
        append x { }
        $x
    }
    p
} {}

# cleanup
catch {eval namespace delete [namespace children :: test_ns_*]}
catch {rename foo ""}
catch {rename p ""}
catch {rename {} ""}
catch {rename { } ""}
catch {unset x}
catch {unset y}
catch {unset msg}
::tcltest::cleanupTests
return
















Changes to tests/expr-old.test.

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16

17

18
19
20
21
22
23
24
# Commands covered: expr
#
# This file contains the original set of tests for Tcl's expr command.
# Since the expr command is now compiled, a new set of tests covering
# the new implementation is in the file "expr.test". Sourcing this file
# into Tcl runs the tests and generates output for errors.
# No output means no errors were found.
#
# Copyright (c) 1991-1994 The Regents of the University of California.
# 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.
#
# SCCS: @(#) expr-old.test 1.63 97/10/31 17:23:24


if {[string compare test [info procs test]] == 1} then {source defs}


if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
    set gotT1 0
    puts "This application hasn't been compiled with the \"T1\" and"
    puts "\"T2\" math functions, so I'll skip some of the expr tests."
} else {
    set gotT1 1




|
|
|



>




|

>
|
>







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
# Commands covered: expr
#
# This file contains the original set of tests for Tcl's expr command.
# Since the expr command is now compiled, a new set of tests covering
# the new implementation are in the files "parseExpr.test and
# "compExpr.test". Sourcing this file into Tcl runs the tests and generates
# output for errors. No output means no errors were found.
#
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-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: expr-old.test,v 1.1.2.5 1999/03/24 02:49:07 hershey Exp $

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

if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
    set gotT1 0
    puts "This application hasn't been compiled with the \"T1\" and"
    puts "\"T2\" math functions, so I'll skip some of the expr tests."
} else {
    set gotT1 1
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
test expr-old-25.12 {type conversions} {expr 2>"ab"} 0
test expr-old-25.13 {type conversions} {expr {2>" "}} 1
test expr-old-25.14 {type conversions} {expr {"24.1a" > 24.1}} 1
test expr-old-25.15 {type conversions} {expr {24.1 > "24.1a"}} 0
test expr-old-25.16 {type conversions} {expr 2+2.5} 4.5
test expr-old-25.17 {type conversions} {expr 2+2.5} 4.5
test expr-old-25.18 {type conversions} {expr 2.0e2} 200.0
test expr-old-25.19 {type conversions} {expr 2.0e15} 2e+15
test expr-old-25.20 {type conversions} {expr 10.0} 10.0

# Various error conditions.

test expr-old-26.1 {error conditions} {
    list [catch {expr 2+"a"} msg] $msg
} {1 {can't use non-numeric string as operand of "+"}}







|







401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
test expr-old-25.12 {type conversions} {expr 2>"ab"} 0
test expr-old-25.13 {type conversions} {expr {2>" "}} 1
test expr-old-25.14 {type conversions} {expr {"24.1a" > 24.1}} 1
test expr-old-25.15 {type conversions} {expr {24.1 > "24.1a"}} 0
test expr-old-25.16 {type conversions} {expr 2+2.5} 4.5
test expr-old-25.17 {type conversions} {expr 2+2.5} 4.5
test expr-old-25.18 {type conversions} {expr 2.0e2} 200.0
test expr-old-25.19 {type conversions} {eformat} {expr 2.0e15} 2e+15
test expr-old-25.20 {type conversions} {expr 10.0} 10.0

# Various error conditions.

test expr-old-26.1 {error conditions} {
    list [catch {expr 2+"a"} msg] $msg
} {1 {can't use non-numeric string as operand of "+"}}
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
    list [catch {expr 2:3} msg] $msg
} {1 {syntax error in expression "2:3"}}
test expr-old-26.15 {error conditions} {
    list [catch {expr a@b} msg] $msg
} {1 {syntax error in expression "a@b"}}
test expr-old-26.16 {error conditions} {
    list [catch {expr a[b} msg] $msg
} {1 {missing close-bracket or close-brace}}
test expr-old-26.17 {error conditions} {
    list [catch {expr a`b} msg] $msg
} {1 {syntax error in expression "a`b"}}
test expr-old-26.18 {error conditions} {
    list [catch {expr \"a\"\{b} msg] $msg
} {1 {missing close-brace}}
test expr-old-26.19 {error conditions} {
    list [catch {expr a} msg] $msg
} {1 {syntax error in expression "a"}}
test expr-old-26.20 {error conditions} {
    list [catch expr msg] $msg
} {1 {wrong # args: should be "expr arg ?arg ...?"}}








|





|







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
    list [catch {expr 2:3} msg] $msg
} {1 {syntax error in expression "2:3"}}
test expr-old-26.15 {error conditions} {
    list [catch {expr a@b} msg] $msg
} {1 {syntax error in expression "a@b"}}
test expr-old-26.16 {error conditions} {
    list [catch {expr a[b} msg] $msg
} {1 {missing close-bracket}}
test expr-old-26.17 {error conditions} {
    list [catch {expr a`b} msg] $msg
} {1 {syntax error in expression "a`b"}}
test expr-old-26.18 {error conditions} {
    list [catch {expr \"a\"\{b} msg] $msg
} {1 syntax\ error\ in\ expression\ \"\"a\"\{b\"}
test expr-old-26.19 {error conditions} {
    list [catch {expr a} msg] $msg
} {1 {syntax error in expression "a"}}
test expr-old-26.20 {error conditions} {
    list [catch expr msg] $msg
} {1 {wrong # args: should be "expr arg ?arg ...?"}}

773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
    } 1035
}
test expr-old-32.45 {math functions in expressions} {
    expr (0 <= rand()) && (rand() < 1)
} {1}
test expr-old-32.46 {math functions in expressions} {
    list [catch {expr rand(24)} msg] $msg
} {1 {syntax error in expression "rand(24)"}}
test expr-old-32.47 {math functions in expressions} {
    list [catch {expr srand()} msg] $msg
} {1 {syntax error in expression "srand()"}}
test expr-old-32.48 {math functions in expressions} {
    list [catch {expr srand(3.79)} msg] $msg
} {1 {can't use floating-point value as argument to srand}}
test expr-old-32.49 {math functions in expressions} {
    list [catch {expr srand("")} msg] $msg
} {1 {can't use non-numeric string as argument to srand}}
test expr-old-32.50 {math functions in expressions} {







|


|







776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
    } 1035
}
test expr-old-32.45 {math functions in expressions} {
    expr (0 <= rand()) && (rand() < 1)
} {1}
test expr-old-32.46 {math functions in expressions} {
    list [catch {expr rand(24)} msg] $msg
} {1 {too many arguments for math function}}
test expr-old-32.47 {math functions in expressions} {
    list [catch {expr srand()} msg] $msg
} {1 {too few arguments for math function}}
test expr-old-32.48 {math functions in expressions} {
    list [catch {expr srand(3.79)} msg] $msg
} {1 {can't use floating-point value as argument to srand}}
test expr-old-32.49 {math functions in expressions} {
    list [catch {expr srand("")} msg] $msg
} {1 {can't use non-numeric string as argument to srand}}
test expr-old-32.50 {math functions in expressions} {
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
test expr-old-34.16 {errors in math functions} {
    list [catch {expr round(-1.0e30)} msg] $msg $errorCode
} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
if $gotT1 {
    test expr-old-34.17 {errors in math functions} {
	list [catch {expr T1(4)} msg] $msg
    } {1 {syntax error in expression "T1(4)"}}
}

test expr-old-36.1 {ExprLooksLikeInt procedure} {
    list [catch {expr 0289} msg] $msg
} {1 {syntax error in expression "0289"}}
test expr-old-36.2 {ExprLooksLikeInt procedure} {
    set x 0289
    list [catch {expr {$x+1}} msg] $msg
} {1 {can't use non-numeric string as operand of "+"}}
test expr-old-36.3 {ExprLooksLikeInt procedure} {
    list [catch {expr 0289.1} msg] $msg
} {0 289.1}
test expr-old-36.4 {ExprLooksLikeInt procedure} {
    set x 0289.1
    list [catch {expr {$x+1}} msg] $msg
} {0 290.1}







|








|







861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
test expr-old-34.16 {errors in math functions} {
    list [catch {expr round(-1.0e30)} msg] $msg $errorCode
} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
if $gotT1 {
    test expr-old-34.17 {errors in math functions} {
	list [catch {expr T1(4)} msg] $msg
    } {1 {too many arguments for math function}}
}

test expr-old-36.1 {ExprLooksLikeInt procedure} {
    list [catch {expr 0289} msg] $msg
} {1 {syntax error in expression "0289"}}
test expr-old-36.2 {ExprLooksLikeInt procedure} {
    set x 0289
    list [catch {expr {$x+1}} msg] $msg
} {1 {can't use floating-point value as operand of "+"}}
test expr-old-36.3 {ExprLooksLikeInt procedure} {
    list [catch {expr 0289.1} msg] $msg
} {0 289.1}
test expr-old-36.4 {ExprLooksLikeInt procedure} {
    set x 0289.1
    list [catch {expr {$x+1}} msg] $msg
} {0 290.1}
896
897
898
899
900
901
902




903
904
905
906





907
908
909
910
911
912
913
914
915
916
917
918
919
920
















test expr-old-36.9 {ExprLooksLikeInt procedure} {
    list [catch {expr 24E1} msg] $msg
} {0 240.0}
test expr-old-36.10 {ExprLooksLikeInt procedure} {nonPortable unixOnly} {
    list [catch {expr 78e} msg] $msg
} {1 {syntax error in expression "78e"}}





test expr-old-37.1 {Check that Tcl_ExprLong doesn't modify interpreter result if no error} {
    testexprlong
} {This is a result: 5}






test expr-old-38.1 {Verify Tcl_ExprString's basic operation} {
    list [testexprstring "1+4"] [testexprstring "2*3+4.2"] \
        [catch {testexprstring "1+"} msg] $msg
} {5 10.2 1 {syntax error in expression "1+"}}


# Special test for Pentium arithmetic bug of 1994:

if {(4195835.0 - (4195835.0/3145727.0)*3145727.0) == 256.0} {
    puts "Warning: this machine contains a defective Pentium processor"
    puts "that performs arithmetic incorrectly.  I recommend that you"
    puts "call Intel customer service immediately at 1-800-628-8686"
    puts "to request a replacement processor."
}























>
>
>
>



|
>
>
>
>
>




|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
test expr-old-36.9 {ExprLooksLikeInt procedure} {
    list [catch {expr 24E1} msg] $msg
} {0 240.0}
test expr-old-36.10 {ExprLooksLikeInt procedure} {nonPortable unixOnly} {
    list [catch {expr 78e} msg] $msg
} {1 {syntax error in expression "78e"}}

if {[info commands testexprlong] == {}} {
    puts "This application hasn't been compiled with the \"testexprlong\""
    puts "command, so I can't test Tcl_ExprLong etc."
} else {
test expr-old-37.1 {Check that Tcl_ExprLong doesn't modify interpreter result if no error} {
    testexprlong
} {This is a result: 5}
}

if {[info commands testexprstring] == {}} {
    puts "This application hasn't been compiled with the \"testexprstring\""
    puts "command, so I can't test Tcl_ExprString etc."
} else {
test expr-old-38.1 {Verify Tcl_ExprString's basic operation} {
    list [testexprstring "1+4"] [testexprstring "2*3+4.2"] \
        [catch {testexprstring "1+"} msg] $msg
} {5 10.2 1 {syntax error in expression "1+"}}
}

# Special test for Pentium arithmetic bug of 1994:

if {(4195835.0 - (4195835.0/3145727.0)*3145727.0) == 256.0} {
    puts "Warning: this machine contains a defective Pentium processor"
    puts "that performs arithmetic incorrectly.  I recommend that you"
    puts "call Intel customer service immediately at 1-800-628-8686"
    puts "to request a replacement processor."
}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/expr.test.

1
2
3
4
5
6
7

8
9
10
11

12


13
14
15
16
17
18
19
20
21
# Commands covered: expr
#
# 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) 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.
#

# SCCS: @(#) expr.test 1.39 97/11/03 16:04:47



if {[string compare test [info procs test]] == 1} then {source defs}

if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
    set gotT1 0
    puts "This application hasn't been compiled with the \"T1\" and"
    puts "\"T2\" math functions, so I'll skip some of the expr tests."
} else {
    set gotT1 1







>




>
|
>
>
|
<







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

18
19
20
21
22
23
24
# Commands covered: expr
#
# 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) 1996-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: expr.test,v 1.1.2.6 1999/04/02 23:44:37 stanton Exp $

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


if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
    set gotT1 0
    puts "This application hasn't been compiled with the \"T1\" and"
    puts "\"T2\" math functions, so I'll skip some of the expr tests."
} else {
    set gotT1 1
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
} 18
test expr-1.5 {TclCompileExprCmd: quoted expression word} {
    expr "0005"
} 5
test expr-1.6 {TclCompileExprCmd: quoted expression word} {
    catch {expr "0005"zxy} msg
    set msg
} {quoted string doesn't terminate properly}
test expr-1.7 {TclCompileExprCmd: expression word in braces} {
    expr {-0005}
} -5
test expr-1.8 {TclCompileExprCmd: expression word in braces} {
    expr {{-0x1234}}
} -4660
test expr-1.9 {TclCompileExprCmd: expression word in braces} {
    catch {expr {-0005}foo} msg
    set msg
} {argument word in braces doesn't terminate properly}
test expr-1.10 {TclCompileExprCmd: other expression word in braces} {
    expr 4*[llength "6 2"]
} 8
test expr-1.11 {TclCompileExprCmd: expression word terminated by ;} {
    expr 4*[llength "6 2"];
} 8
test expr-1.12 {TclCompileExprCmd: inlined expr (in "catch") inside other catch} {







|









|







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
} 18
test expr-1.5 {TclCompileExprCmd: quoted expression word} {
    expr "0005"
} 5
test expr-1.6 {TclCompileExprCmd: quoted expression word} {
    catch {expr "0005"zxy} msg
    set msg
} {extra characters after close-quote}
test expr-1.7 {TclCompileExprCmd: expression word in braces} {
    expr {-0005}
} -5
test expr-1.8 {TclCompileExprCmd: expression word in braces} {
    expr {{-0x1234}}
} -4660
test expr-1.9 {TclCompileExprCmd: expression word in braces} {
    catch {expr {-0005}foo} msg
    set msg
} {extra characters after close-brace}
test expr-1.10 {TclCompileExprCmd: other expression word in braces} {
    expr 4*[llength "6 2"]
} 8
test expr-1.11 {TclCompileExprCmd: expression word terminated by ;} {
    expr 4*[llength "6 2"];
} 8
test expr-1.12 {TclCompileExprCmd: inlined expr (in "catch") inside other catch} {
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
    catch {expr $i.2} msg
    set msg
} 123.2
test expr-14.16 {CompilePrimaryExpr: error compiling var reference primary} {
    catch {expr {$a(foo}} msg
    set errorInfo
} {missing )
    (parsing index for array "a")
    while compiling
"expr {$a(foo}"}
test expr-14.17 {CompilePrimaryExpr: string primary that looks like var ref} {
    expr $
} $
test expr-14.18 {CompilePrimaryExpr: quoted string primary} {
    expr "21"







<







478
479
480
481
482
483
484

485
486
487
488
489
490
491
    catch {expr $i.2} msg
    set msg
} 123.2
test expr-14.16 {CompilePrimaryExpr: error compiling var reference primary} {
    catch {expr {$a(foo}} msg
    set errorInfo
} {missing )

    while compiling
"expr {$a(foo}"}
test expr-14.17 {CompilePrimaryExpr: string primary that looks like var ref} {
    expr $
} $
test expr-14.18 {CompilePrimaryExpr: quoted string primary} {
    expr "21"
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
    while compiling
"set"
    while compiling
"expr {[set]}"}
test expr-14.24 {CompilePrimaryExpr: error in subcommand primary} {
    catch {expr {[set i}} msg
    set errorInfo
} {missing close-bracket or close-brace
    while compiling
"set i"
    while compiling
"expr {[set i}"}
test expr-14.25 {CompilePrimaryExpr: math function primary} {
    format %.6g [expr exp(1.0)]
} 2.71828
test expr-14.26 {CompilePrimaryExpr: math function primary} {
    format %.6g [expr pow(2.0+0.1,3.0+0.1)]
} 9.97424
test expr-14.27 {CompilePrimaryExpr: error in math function primary} {
    catch {expr sinh::(2.0)} msg
    set errorInfo
} {syntax error in expression "sinh::(2.0)"
    while executing
"expr sinh::(2.0)"}
test expr-14.28 {CompilePrimaryExpr: subexpression primary} {
    expr 2+(3*4)
} 14
test expr-14.29 {CompilePrimaryExpr: error in subexpression primary} {
    catch {expr 2+(3*[set])} msg
    set errorInfo
} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    while compiling
"expr 2+(3*[set])"}
test expr-14.30 {CompilePrimaryExpr: missing paren in subexpression primary} {
    catch {expr 2+(3*(4+5)} msg
    set errorInfo
} {syntax error in expression "2+(3*(4+5)"
    while executing
"expr 2+(3*(4+5)"}
test expr-14.31 {CompilePrimaryExpr: just var ref in subexpression primary} {
    set i "5+10"
    list "[expr $i] == 15" "[expr ($i)] == 15" "[eval expr ($i)] == 15"
} {{15 == 15} {15 == 15} {15 == 15}}
test expr-14.32 {CompilePrimaryExpr: unexpected token} {
    catch {expr @} msg
    set errorInfo
} {syntax error in expression "@"
    while executing
"expr @"}

test expr-15.1 {CompileMathFuncCall: missing parenthesis} {
    catch {expr sinh2.0)} msg
    set errorInfo
} {syntax error in expression "sinh2.0)"
    while executing
"expr sinh2.0)"}
test expr-15.2 {CompileMathFuncCall: unknown math function} {
    catch {expr whazzathuh(1)} msg
    set errorInfo
} {unknown math function "whazzathuh"
    while executing
"expr whazzathuh(1)"}
test expr-15.3 {CompileMathFuncCall: too many arguments} {
    catch {expr sin(1,2,3)} msg
    set errorInfo
} {too many arguments for math function
    while executing
"expr sin(1,2,3)"}
test expr-15.4 {CompileMathFuncCall: ')' found before last required arg} {
    catch {expr sin()} msg
    set errorInfo
} {syntax error in expression "sin()"
    while executing
"expr sin()"}
test expr-15.5 {CompileMathFuncCall: too few arguments} {
    catch {expr pow(1)} msg
    set errorInfo
} {too few arguments for math function
    while executing
"expr pow(1)"}
test expr-15.6 {CompileMathFuncCall: missing ')'} {
    catch {expr sin(1} msg
    set errorInfo
} {syntax error in expression "sin(1"
    while executing
"expr sin(1"}
if $gotT1 {
    test expr-15.7 {CompileMathFuncCall: call registered math function} {
	expr 2*T1()
    } 246
    test expr-15.8 {CompileMathFuncCall: call registered math function} {
	expr T2()*3







|
<
<












|
















|









|






|





|





|




|
|





|





|







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
    while compiling
"set"
    while compiling
"expr {[set]}"}
test expr-14.24 {CompilePrimaryExpr: error in subcommand primary} {
    catch {expr {[set i}} msg
    set errorInfo
} {missing close-bracket


    while compiling
"expr {[set i}"}
test expr-14.25 {CompilePrimaryExpr: math function primary} {
    format %.6g [expr exp(1.0)]
} 2.71828
test expr-14.26 {CompilePrimaryExpr: math function primary} {
    format %.6g [expr pow(2.0+0.1,3.0+0.1)]
} 9.97424
test expr-14.27 {CompilePrimaryExpr: error in math function primary} {
    catch {expr sinh::(2.0)} msg
    set errorInfo
} {syntax error in expression "sinh::(2.0)"
    while compiling
"expr sinh::(2.0)"}
test expr-14.28 {CompilePrimaryExpr: subexpression primary} {
    expr 2+(3*4)
} 14
test expr-14.29 {CompilePrimaryExpr: error in subexpression primary} {
    catch {expr 2+(3*[set])} msg
    set errorInfo
} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    while compiling
"expr 2+(3*[set])"}
test expr-14.30 {CompilePrimaryExpr: missing paren in subexpression primary} {
    catch {expr 2+(3*(4+5)} msg
    set errorInfo
} {syntax error in expression "2+(3*(4+5)"
    while compiling
"expr 2+(3*(4+5)"}
test expr-14.31 {CompilePrimaryExpr: just var ref in subexpression primary} {
    set i "5+10"
    list "[expr $i] == 15" "[expr ($i)] == 15" "[eval expr ($i)] == 15"
} {{15 == 15} {15 == 15} {15 == 15}}
test expr-14.32 {CompilePrimaryExpr: unexpected token} {
    catch {expr @} msg
    set errorInfo
} {syntax error in expression "@"
    while compiling
"expr @"}

test expr-15.1 {CompileMathFuncCall: missing parenthesis} {
    catch {expr sinh2.0)} msg
    set errorInfo
} {syntax error in expression "sinh2.0)"
    while compiling
"expr sinh2.0)"}
test expr-15.2 {CompileMathFuncCall: unknown math function} {
    catch {expr whazzathuh(1)} msg
    set errorInfo
} {unknown math function "whazzathuh"
    while compiling
"expr whazzathuh(1)"}
test expr-15.3 {CompileMathFuncCall: too many arguments} {
    catch {expr sin(1,2,3)} msg
    set errorInfo
} {too many arguments for math function
    while compiling
"expr sin(1,2,3)"}
test expr-15.4 {CompileMathFuncCall: ')' found before last required arg} {
    catch {expr sin()} msg
    set errorInfo
} {too few arguments for math function
    while compiling
"expr sin()"}
test expr-15.5 {CompileMathFuncCall: too few arguments} {
    catch {expr pow(1)} msg
    set errorInfo
} {too few arguments for math function
    while compiling
"expr pow(1)"}
test expr-15.6 {CompileMathFuncCall: missing ')'} {
    catch {expr sin(1} msg
    set errorInfo
} {syntax error in expression "sin(1"
    while compiling
"expr sin(1"}
if $gotT1 {
    test expr-15.7 {CompileMathFuncCall: call registered math function} {
	expr 2*T1()
    } 246
    test expr-15.8 {CompileMathFuncCall: call registered math function} {
	expr T2()*3
663
664
665
666
667
668
669





































670


        set x  [expr $x+$f+$center]
        set x  [expr $x+$f+$center]
        set y  [expr round($x)]
    }
    p
} 3






































unset a









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

>
>
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
        set x  [expr $x+$f+$center]
        set x  [expr $x+$f+$center]
        set y  [expr round($x)]
    }
    p
} 3

# Test for incorrect "double evaluation" semantics

test expr-20.1 {wrong brace matching} {
    catch {unset l}
    catch {unset r}
    catch {unset q}
    catch {unset cmd}
    catch {unset a}
    set l "\{"; set r "\}"; set q "\""
    set cmd "expr $l$q|$q == $q$r$q$r"
    list [catch $cmd a] $a
} {1 {extra characters after close-brace}}
test expr-20.2 {double invocation of variable traces} {knownBug} {
    set exprtracecounter 0
    proc exprtraceproc {args} {
       upvar #0 exprtracecounter counter
       set argc [llength $args]
       set extraargs [lrange $args 0 [expr {$argc - 4}]]
       set name [lindex $args [expr {$argc - 3}]]
       upvar 1 $name var
       if {[incr counter] % 2 == 1} {
           set var "$counter oops [concat $extraargs]"
       } else {
           set var "$counter + [concat $extraargs]"
       }
    }
    trace variable exprtracevar r [list exprtraceproc 10]
    list [catch {expr "$exprtracevar + 20"} a] $a \
        [catch {expr "$exprtracevar + 20"} b] $b \
        [unset exprtracevar exprtracecounter]
} {1 {syntax error in expression "1 oops 10 + 20"} 0 32 {}}
test expr-20.3 {broken substitution of integer digits} {
    # fails with 8.0.x, but not 8.1b2
    list [set a 000; expr 0x1$a] [set a 1; expr ${a}000]
} {4096 1000}

# cleanup
unset a
::tcltest::cleanupTests
return

Changes to tests/fCmd.test.

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
# This file tests the tclFCmd.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) 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.
#
# SCCS: @(#) fCmd.test 1.33 97/11/03 15:58:08
#


if {[string compare test [info procs test]] == 1} then {source defs}

set platform [testgetplatform]

if {$user == "root"} {
    puts "Skipping fCmd tests.  They depend on not being able to write to"
    puts "certain directories.  It would be too dangerous to run them as root."

    return
}



if {"[info commands testchmod]" != "testchmod"} {
    puts "Skipping fCmd tests. This application does not seem to have the"
    puts "testchmod command that is needed to run these tests."

    return
}













proc createfile {file {string a}} {
    set f [open $file w]
    puts -nonewline $f $string
    close $f
    return $string
}







>




|


>
|
|
<

|
|
|
>


>
>




>


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







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
# This file tests the tclFCmd.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) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 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: fCmd.test,v 1.1.2.8 1999/03/26 19:13:59 hershey Exp $
#

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


if {[string compare testgetplatform [info commands testgetplatform]] != 0} {
    puts "This application hasn't been compiled with the \"testgetplatform\""
    puts "command, therefore I am skipping all of these tests."
    ::tcltest::cleanupTests
    return
}

set platform [testgetplatform]

if {"[info commands testchmod]" != "testchmod"} {
    puts "Skipping fCmd tests. This application does not seem to have the"
    puts "testchmod command that is needed to run these tests."
    ::tcltest::cleanupTests
    return
}

# Several tests require need to match results against the unix username
set user {}
if {$tcl_platform(platform) == "unix"} {
    catch {set user [exec whoami]}
    if {$user == ""} {
	catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
    }
    if {$user == ""} {
	set user "root"
    }
}

proc createfile {file {string a}} {
    set f [open $file w]
    puts -nonewline $f $string
    close $f
    return $string
}
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
270












271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392






393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507

508
509
510
511
512
513

514
515
516
517
518
519

520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535
536

537
538
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
554
555

556
557
558
559
560
561
562

563
564
565
566
567
568
569
570

571
572
573
574
575
576

577
578
579
580
581
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
    foreach p ". $args" {
	set x ""
	catch {
	    set x [glob [file join $p tf*] [file join $p td*]]
	}
	foreach file $x {
	    if {[catch {file delete -force -- $file}]} {
		openup $file
		file delete -force -- $file
	    }
	}
    }
}

proc contents {file} {
    set f [open $file r]
    set r [read $f]
    close $f
    set r
}

set testConfig(NT) 0
set testConfig(95) 0

switch $tcl_platform(os) {
    "Windows NT" {set testConfig(NT) 1}
    "Windows 95" {set testConfig(95) 1}
}

set testConfig(fileSharing) 0
set testConfig(notFileSharing) 1

if {$tcl_platform(platform) == "macintosh"} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    if {[catch {file attributes foo.dir -readonly 1}] == 0} {
    	set testConfig(fileSharing) 1
    	set testConfig(notFileSharing) 0
    }
    file delete -force foo.dir
}

set testConfig(xdev) 0

if {$tcl_platform(platform) == "unix"} {
    if {[catch {set m1 [exec df .]; set m2 [exec df /tmp]}] == 0} {
	set m1 [string range $m1 0 [expr [string first " " $m1]-1]]
	set m2 [string range $m2 0 [expr [string first " " $m2]-1]]
	if {$m1 != "" && $m2 != "" && $m1 != $m2 && [file exists $m1] && [file exists $m2]} {
	    set testConfig(xdev) 1
	}
    }
}

set root [lindex [file split [pwd]] 0]

# A really long file name
# length of long is 1216 chars, which should be greater than any static
# buffer or allowable filename.

set long "abcdefghihjllmnopqrstuvwxyz01234567890"
append long $long
append long $long
append long $long
append long $long
append long $long

test fCmd-1.1 {TclFileRenameCmd} {
    cleanup
    createfile tf1
    file rename tf1 tf2
    glob tf*
} {tf2}

test fCmd-2.1 {TclFileCopyCmd} {
    cleanup
    createfile tf1
    file copy tf1 tf2
    lsort [glob tf*]
} {tf1 tf2}

test fCmd-3.1 {FileCopyRename: FileForceOption fails} {
    list [catch {file rename -xyz} msg] $msg
} {1 {bad option "-xyz": should be -force or --}}
test fCmd-3.2 {FileCopyRename: not enough args} {
    list [catch {file rename xyz} msg] $msg
} {1 {wrong # args: should be "file rename ?options? source ?source ...? target"}}
test fCmd-3.3 {FileCopyRename: Tcl_TranslateFileName fails} {
    list [catch {file rename xyz ~nonexistantuser} msg] $msg
} {1 {user "nonexistantuser" doesn't exist}}
test fCmd-3.4 {FileCopyRename: Tcl_TranslateFileName passes} {
    cleanup
    list [catch {file copy tf1 ~} msg] $msg
} {1 {error copying "tf1": no such file or directory}}
test fCmd-3.5 {FileCopyRename: target doesn't exist: stat(target) != 0} {
    cleanup
    list [catch {file rename tf1 tf2 tf3} msg] $msg
} {1 {error renaming: target "tf3" is not a directory}}
test fCmd-3.6 {FileCopyRename: target tf3 is not a directory: !S_ISDIR(target)} {

    cleanup
    createfile tf3
    list [catch {file rename tf1 tf2 tf3} msg] $msg
} {1 {error renaming: target "tf3" is not a directory}}
test fCmd-3.7 {FileCopyRename: target exists & is directory} {
    cleanup
    file mkdir td1
    createfile tf1 tf1
    file rename tf1 td1
    contents [file join td1 tf1]
} {tf1}
test fCmd-3.8 {FileCopyRename: too many arguments: argc - i > 2} {
    cleanup
    list [catch {file rename tf1 tf2 tf3} msg] $msg
} {1 {error renaming: target "tf3" is not a directory}}
test fCmd-3.9 {FileCopyRename: too many arguments: argc - i > 2} {
    cleanup
    list [catch {file copy -force -- tf1 tf2 tf3} msg] $msg
} {1 {error copying: target "tf3" is not a directory}}
test fCmd-3.10 {FileCopyRename: just 2 arguments} {
    cleanup
    createfile tf1 tf1
    file rename tf1 tf2
    contents tf2
} {tf1}
test fCmd-3.11 {FileCopyRename: just 2 arguments} {
    cleanup
    createfile tf1 tf1
    file rename -force -force -- tf1 tf2
    contents tf2
} {tf1}
test fCmd-3.12 {FileCopyRename: move each source: 1 source} {
    cleanup
    createfile tf1 tf1
    file mkdir td1
    file rename tf1 td1
    contents [file join td1 tf1]
} {tf1}
test fCmd-3.13 {FileCopyRename: move each source: multiple sources} {
    cleanup
    createfile tf1 tf1
    createfile tf2 tf2
    createfile tf3 tf3
    createfile tf4 tf4
    file mkdir td1
    file rename tf1 tf2 tf3 tf4 td1
    list [contents [file join td1 tf1]] [contents [file join td1 tf2]] \
	[contents [file join td1 tf3]] [contents [file join td1 tf4]]
} {tf1 tf2 tf3 tf4}
test fCmd-3.14 {FileCopyRename: FileBasename fails} {
    cleanup
    file mkdir td1
    list [catch {file rename ~nonexistantuser td1} msg] $msg
} {1 {user "nonexistantuser" doesn't exist}}
test fCmd-3.15 {FileCopyRename: source[0] == '\0'} {unixOrPc} {
    cleanup
    file mkdir td1
    list [catch {file rename / td1} msg] $msg
} {1 {error renaming "/" to "td1": file already exists}}
test fCmd-3.16 {FileCopyRename: break on first error} {
    cleanup
    createfile tf1 
    createfile tf2 
    createfile tf3 
    createfile tf4 
    file mkdir td1
    createfile [file join td1 tf3]
    list [catch {file rename tf1 tf2 tf3 tf4 td1} msg] $msg
} [subst {1 {error renaming "tf3" to "[file join td1 tf3]": file already exists}}]

test fCmd-4.1 {TclFileMakeDirsCmd: make each dir: 1 dir} {
    cleanup
    file mkdir td1
    glob td*
} {td1}
test fCmd-4.2 {TclFileMakeDirsCmd: make each dir: multiple dirs} {
    cleanup
    file mkdir td1 td2 td3
    lsort [glob td*]
} {td1 td2 td3}
test fCmd-4.3 {TclFileMakeDirsCmd: stops on first error} {
    cleanup
    createfile tf1
    catch {file mkdir td1 td2 tf1 td3 td4}
    glob td1 td2 tf1 td3 td4
} {td1 td2 tf1}
test fCmd-4.4 {TclFileMakeDirsCmd: Tcl_TranslateFileName fails} {
    cleanup
    list [catch {file mkdir ~nonexistantuser} msg] $msg
} {1 {user "nonexistantuser" doesn't exist}}
test fCmd-4.5 {TclFileMakeDirsCmd: Tcl_SplitPath returns 0: *name == '\0'} {

    cleanup
    list [catch {file mkdir ""} msg] $msg
} {1 {can't create directory "": no such file or directory}}
test fCmd-4.6 {TclFileMakeDirsCmd: one level deep} {
    cleanup
    file mkdir td1
    glob td1
} {td1}
test fCmd-4.7 {TclFileMakeDirsCmd: multi levels deep} {
    cleanup
    file mkdir [file join td1 td2 td3 td4]
    glob td1 [file join td1 td2]
} "td1 [file join td1 td2]"
test fCmd-4.8 {TclFileMakeDirsCmd: already exist: lstat(target) == 0} {












    cleanup
    file mkdir td1
    set x [file exist td1]
    file mkdir td1
    list $x [file exist td1]
} {1 1}
test fCmd-4.9 {TclFileMakeDirsCmd: exists, not dir} {
    cleanup
    createfile tf1
    list [catch {file mkdir tf1} msg] $msg
} [subst {1 {can't create directory "[file join tf1]": file already exists}}]
test fCmd-4.10 {TclFileMakeDirsCmd: exists, is dir} {
    cleanup
    file mkdir td1
    set x [file exist td1]
    file mkdir td1
    list $x [file exist td1]
} {1 1}
test fCmd-4.11 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} {unixOnly} {

    cleanup
    file mkdir td1/td2/td3
    testchmod 000 td1/td2
    set msg [list [catch {file mkdir td1/td2/td3/td4} msg] $msg]
    testchmod 755 td1/td2
    set msg
} {1 {can't create directory "td1/td2/td3": permission denied}}
test fCmd-4.12 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} {macOnly} {
    cleanup
    list [catch {file mkdir nonexistantvolume:} msg] $msg
} {1 {can't create directory "nonexistantvolume:": invalid argument}}
test fCmd-4.13 {TclFileMakeDirsCmd: doesn't exist: errno == ENOENT} {
    cleanup
    set x [file exist td1]
    file mkdir td1
    list $x [file exist td1]
} {0 1}
test fCmd-4.14 {TclFileMakeDirsCmd: TclpCreateDirectory fails} {unixOnly} {

    cleanup
    file delete -force foo
    file mkdir foo
    file attr foo -perm 040000
    set result [list [catch {file mkdir foo/tf1} msg] $msg]
    file delete -force foo
    set result
} {1 {can't create directory "foo/tf1": permission denied}}
test fCmd-4.15 {TclFileMakeDirsCmd: TclpCreateDirectory fails} {macOnly} {
    list [catch {file mkdir ${root}:} msg] $msg
} [subst {1 {can't create directory "${root}:": no such file or directory}}]
test fCmd-4.16 {TclFileMakeDirsCmd: TclpCreateDirectory succeeds} {
    cleanup
    file mkdir tf1
    file exists tf1
} {1}

test fCmd-5.1 {TclFileDeleteCmd: FileForceOption fails} {
    list [catch {file delete -xyz} msg] $msg
} {1 {bad option "-xyz": should be -force or --}}
test fCmd-5.2 {TclFileDeleteCmd: not enough args} {
    list [catch {file delete -force -force} msg] $msg
} {1 {wrong # args: should be "file delete ?options? file ?file ...?"}}
test fCmd-5.3 {TclFileDeleteCmd: 1 file} {
    cleanup
    createfile tf1
    createfile tf2
    file mkdir td1
    file delete tf2
    glob tf* td*
} {tf1 td1}
test fCmd-5.4 {TclFileDeleteCmd: multiple files} {
    cleanup
    createfile tf1
    createfile tf2
    file mkdir td1
    set x [list [file exist tf1] [file exist tf2] [file exist td1]]
    file delete tf1 td1 tf2
    lappend x [file exist tf1] [file exist tf2] [file exist tf3]
} {1 1 1 0 0 0}
test fCmd-5.5 {TclFileDeleteCmd: stop at first error} {unixOrPc} {
    cleanup
    createfile tf1
    createfile tf2
    file mkdir td1
    catch {file delete tf1 td1 $root tf2}
    list [file exist tf1] [file exist tf2] [file exist td1]
} {0 1 0}
test fCmd-5.6 {TclFileDeleteCmd: Tcl_TranslateFileName fails} {
    list [catch {file delete ~nonexistantuser} msg] $msg
} {1 {user "nonexistantuser" doesn't exist}}
test fCmd-5.7 {TclFileDeleteCmd: Tcl_TranslateFileName succeeds} {
    catch {file delete ~/tf1}
    createfile ~/tf1
    file delete ~/tf1
} {}
test fCmd-5.8 {TclFileDeleteCmd: file doesn't exist: lstat(name) != 0} {
    cleanup
    set x [file exist tf1]
    file delete tf1
    list $x [file exist tf1]
} {0 0}    
test fCmd-5.9 {TclFileDeleteCmd: is directory} {
    cleanup
    file mkdir td1
    file delete td1
    file exist td1
} {0}
test fCmd-5.10 {TclFileDeleteCmd: TclpRemoveDirectory fails} {
    cleanup
    file mkdir td1/td2
    list [catch {file delete td1} msg] $msg
} {1 {error deleting "td1": directory not empty}}

test fCmd-6.1 {CopyRenameOneFile: bad source} {
    # can't test this, because it's caught by FileCopyRename
} {}
test fCmd-6.2 {CopyRenameOneFile: bad target} {
    # can't test this, because it's caught by FileCopyRename
} {}
test fCmd-6.3 {CopyRenameOneFile: lstat(source) != 0} {
    cleanup
    list [catch {file rename tf1 tf2} msg] $msg
} {1 {error renaming "tf1": no such file or directory}}
test fCmd-6.4 {CopyRenameOneFile: lstat(source) == 0} {






    cleanup
    createfile tf1
    file rename tf1 tf2
    glob tf*
} {tf2}
test fCmd-6.5 {CopyRenameOneFile: lstat(target) != 0} {
    cleanup
    createfile tf1
    file rename tf1 tf2
    glob tf*
} {tf2}
test fCmd-6.6 {CopyRenameOneFile: errno != ENOENT} {unixOnly} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    createfile tf1
    set msg [list [catch {file rename tf1 td1} msg] $msg]
    testchmod 755 td1
    set msg
} {1 {error renaming "tf1" to "td1/tf1": permission denied}}
test fCmd-6.7 {CopyRenameOneFile: errno != ENOENT} {95} {
    cleanup
    createfile tf1
    list [catch {file rename tf1 $long} msg] $msg
} [subst {1 {error renaming "tf1" to "$long": file name too long}}]
test fCmd-6.8 {CopyRenameOneFile: errno != ENOENT} {macOnly} {
    cleanup
    createfile tf1
    list [catch {file rename tf1 $long} msg] $msg
} [subst {1 {error renaming "tf1" to "$long": file name too long}}]
test fCmd-6.9 {CopyRenameOneFile: errno == ENOENT} {unixOnly} {
    cleanup
    createfile tf1
    file rename tf1 tf2
    glob tf*
} {tf2}
test fCmd-6.10 {CopyRenameOneFile: lstat(target) == 0} {
    cleanup
    createfile tf1
    createfile tf2
    list [catch {file rename tf1 tf2} msg] $msg
} {1 {error renaming "tf1" to "tf2": file already exists}}
test fCmd-6.11 {CopyRenameOneFile: force == 0} {
    cleanup
    createfile tf1
    createfile tf2
    list [catch {file rename tf1 tf2} msg] $msg
} {1 {error renaming "tf1" to "tf2": file already exists}}
test fCmd-6.12 {CopyRenameOneFile: force != 0} {
    cleanup
    createfile tf1
    createfile tf2
    file rename -force tf1 tf2
    glob tf*
} {tf2}
test fCmd-6.13 {CopyRenameOneFile: source is dir, target is file} {
    cleanup
    file mkdir td1
    file mkdir td2
    createfile [file join td2 td1]
    list [catch {file rename -force td1 td2} msg] $msg
} [subst {1 {can't overwrite file "[file join td2 td1]" with directory "td1"}}]
test fCmd-6.14 {CopyRenameOneFile: source is file, target is dir} {
    cleanup
    createfile tf1
    file mkdir [file join td1 tf1]
    list [catch {file rename -force tf1 td1} msg] $msg
} [subst {1 {can't overwrite directory "[file join td1 tf1]" with file "tf1"}}]
test fCmd-6.15 {CopyRenameOneFile: TclpRenameFile succeeds} {
    cleanup
    file mkdir [file join td1 td2]
    file mkdir td2
    createfile [file join td2 tf1]
    file rename -force td2 td1
    file exists [file join td1 td2 tf1]
} {1}
test fCmd-6.16 {CopyRenameOneFile: TclpCopyRenameOneFile fails} {
    cleanup
    file mkdir [file join td1 td2]
    createfile [file join td1 td2 tf1]
    file mkdir td2
    list [catch {file rename -force td2 td1} msg] $msg
} [subst {1 {error renaming "td2" to "[file join td1 td2]": file already exists}}]
test fCmd-6.17 {CopyRenameOneFile: errno == EINVAL} {!$testConfig(win32s) || ($root == "C:/")} {
    # Don't run this test under Win32s on a drive mounted from an NT 
    # machine; it causes the NT machine to die.


    cleanup
    list [catch {file rename -force $root tf1} msg] $msg
} [subst {1 {error renaming "$root" to "tf1": trying to rename a volume or move a directory into itself}}]
test fCmd-6.18 {CopyRenameOneFile: errno != EXDEV} {
    cleanup
    file mkdir [file join td1 td2]
    createfile [file join td1 td2 tf1]
    file mkdir td2
    list [catch {file rename -force td2 td1} msg] $msg
} [subst {1 {error renaming "td2" to "[file join td1 td2]": file already exists}}]
test fCmd-6.19 {CopyRenameOneFile: errno == EXDEV} {unixOnly} {
    cleanup /tmp
    createfile tf1
    file rename tf1 /tmp
    glob tf* /tmp/tf1
} {/tmp/tf1}
test fCmd-6.20 {CopyRenameOneFile: errno == EXDEV} {pcOnly} {
    catch {file delete -force c:/tcl8975@ d:/tcl8975@}
    file mkdir c:/tcl8975@
    if [catch {file rename c:/tcl8975@ d:/}] {
	list d:/tcl8975@
    } else {
	set msg [glob c:/tcl8975@ d:/tcl8975@]
	file delete -force d:/tcl8975@
	set msg
    }
} {d:/tcl8975@}
test fCmd-6.21 {CopyRenameOneFile: copy/rename: S_ISDIR(source)} {unixOnly} {

    cleanup /tmp
    file mkdir td1
    file rename td1 /tmp
    glob td* /tmp/td*
} {/tmp/td1}
test fCmd-6.22 {CopyRenameOneFile: copy/rename: !S_ISDIR(source)} {unixOnly} {

    cleanup /tmp
    createfile tf1
    file rename tf1 /tmp
    glob tf* /tmp/tf*
} {/tmp/tf1}
test fCmd-6.23 {CopyRenameOneFile: TclpCopyDirectory failed} {unixOnly xdev} {

    cleanup /tmp
    file mkdir td1/td2/td3
    exec chmod 000 td1
    set msg [list [catch {file rename td1 /tmp} msg] $msg]
    exec chmod 755 td1
    set msg 
} {1 {error renaming "td1": permission denied}}
test fCmd-6.24 {CopyRenameOneFile: error uses original name} {unixOnly} {

    cleanup
    file mkdir ~/td1/td2
    exec chmod 000 [file join [file dirname ~] [file tail ~] td1]
    set msg [list [catch {file copy ~/td1 td1} msg] $msg]
    exec chmod 755 [file join [file dirname ~] [file tail ~] td1]
    file delete -force ~/td1
    set msg
} {1 {error copying "~/td1": permission denied}}
test fCmd-6.25 {CopyRenameOneFile: error uses original name} {unixOnly} {

    cleanup
    file mkdir td2
    file mkdir ~/td1
    exec chmod 000 [file join [file dirname ~] [file tail ~] td1]
    set msg [list [catch {file copy td2 ~/td1} msg] $msg]
    exec chmod 755 [file join [file dirname ~] [file tail ~] td1]
    file delete -force ~/td1
    set msg
} {1 {error copying "td2" to "~/td1/td2": permission denied}}
test fCmd-6.26 {CopyRenameOneFile: doesn't use original name} {unixOnly} {

    cleanup
    file mkdir ~/td1/td2
    exec chmod 000 [file join [file dirname ~] [file tail ~] td1 td2]
    set msg [list [catch {file copy ~/td1 td1} msg] $msg]
    exec chmod 755 [file join [file dirname ~] [file tail ~] td1 td2]
    file delete -force ~/td1
    set msg
} "1 {error copying \"~/td1\" to \"td1\": \"[file join [file dirname ~] [file tail ~] td1 td2]\": permission denied}"
test fCmd-6.27 {CopyRenameOneFile: TclpCopyDirectory failed} {unixOnly xdev} {

    cleanup /tmp
    file mkdir td1/td2/td3
    file mkdir /tmp/td1
    createfile /tmp/td1/tf1
    list [catch {file rename -force td1 /tmp} msg] $msg
} {1 {error renaming "td1" to "/tmp/td1": file already exists}}
test fCmd-6.28 {CopyRenameOneFile: TclpCopyDirectory failed} {unixOnly xdev} {

    cleanup /tmp
    file mkdir td1/td2/td3
    exec chmod 000 td1/td2/td3 
    set msg [list [catch {file rename td1 /tmp} msg] $msg]
    exec chmod 755 td1/td2/td3 
    set msg
} {1 {error renaming "td1" to "/tmp/td1": "td1/td2/td3": permission denied}}
test fCmd-6.29 {CopyRenameOneFile: TclpCopyDirectory passed} {unixOnly xdev} {

    cleanup /tmp
    file mkdir td1/td2/td3
    file rename td1 /tmp
    glob td* /tmp/td1/t*
} {/tmp/td1/td2}
test fCmd-6.30 {CopyRenameOneFile: TclpRemoveDirectory failed} {unixOnly} {

    cleanup
    file mkdir foo/bar
    file attr foo -perm 040555
    set msg [list [catch {file rename foo/bar /tmp} msg] $msg]
    set a1 {1 {can't unlink "foo/bar": permission denied}}
    set result [expr {$msg == $a1}]
    catch {file delete /tmp/bar}
    catch {file attr foo -perm 040777}
    catch {file delete -force foo}
    set result
} {1}
test fCmd-6.31 {CopyRenameOneFile: TclpDeleteFile passed} {unixOnly xdev} {

    catch {cleanup /tmp}
    file mkdir /tmp/td1
    createfile /tmp/td1/tf1
    file rename /tmp/td1/tf1 tf1
    list [file exists /tmp/td1/tf1] [file exists tf1]
} {0 1}
test fCmd-6.32 {CopyRenameOneFile: copy} {
    cleanup
    list [catch {file copy tf1 tf2} msg] $msg
} {1 {error copying "tf1": no such file or directory}}
catch {cleanup /tmp}

test fCmd-7.1 {FileForceOption: none} {
    cleanup
    file mkdir [file join tf1 tf2]
    list [catch {file delete tf1} msg] $msg
} {1 {error deleting "tf1": directory not empty}}
test fCmd-7.2 {FileForceOption: -force} {
    cleanup
    file mkdir [file join tf1 tf2]
    file delete -force tf1
} {}
test fCmd-7.3 {FileForceOption: --} {
    createfile -tf1
    file delete -- -tf1
} {}
test fCmd-7.4 {FileForceOption: bad option} {
    createfile -tf1
    set msg [list [catch {file delete -tf1} msg] $msg]
    file delete -- -tf1
    set msg
} {1 {bad option "-tf1": should be -force or --}}
test fCmd-7.5 {FileForceOption: multiple times through loop} {
    createfile --
    createfile -force
    file delete -force -force -- -- -force
    list [catch {glob -- -- -force} msg] $msg
} {1 {no files matched glob patterns "-- -force"}}

test fCmd-8.1 {FileBasename: basename of ~user: argc == 1 && *path == ~} {unixOnly} {

    file mkdir td1
    file attr td1 -perm 040000
    set result [list [catch {file rename ~$user td1} msg] $msg]
    file delete -force td1
    set result
} "1 {error renaming \"~$user\" to \"td1/[file tail ~$user]\": permission denied}"

test fCmd-9.1 {file rename: comprehensive: EACCES} {unixOnly} {
    cleanup
    file mkdir td1
    file mkdir td2
    file attr td2 -perm 040000
    set result [list [catch {file rename td1 td2/} msg] $msg]
    file delete -force td2
    file delete -force td1
    set result
} {1 {error renaming "td1" to "td2/td1": permission denied}}
test fCmd-9.2 {file rename: comprehensive: source doesn't exist} {
    cleanup
    list [catch {file rename tf1 tf2} msg] $msg
} {1 {error renaming "tf1": no such file or directory}}
test fCmd-9.3 {file rename: comprehensive: file to new name} {
    cleanup
    createfile tf1
    createfile tf2
    testchmod 444 tf2
    file rename tf1 tf3
    file rename tf2 tf4
    list [lsort [glob tf*]] [file writable tf3] [file writable tf4]
} {{tf3 tf4} 1 0}    
test fCmd-9.4 {file rename: comprehensive: dir to new name} {unixOrPc} {
    cleanup
    file mkdir td1 td2
    testchmod 555 td2
    file rename td1 td3
    file rename td2 td4
    list [lsort [glob td*]] [file writable td3] [file writable td4]
} {{td3 td4} 1 0}    
test fCmd-9.5 {file rename: comprehensive: file to self} {
    cleanup
    createfile tf1 tf1
    createfile tf2 tf2
    testchmod 444 tf2
    file rename -force tf1 tf1
    file rename -force tf2 tf2
    list [contents tf1] [contents tf2] [file writable tf1] [file writable tf2]
} {tf1 tf2 1 0}    
test fCmd-9.6 {file rename: comprehensive: dir to self} {unixOrPc} {
    cleanup
    file mkdir td1
    file mkdir td2
    testchmod 555 td2
    file rename -force td1 .
    file rename -force td2 .
    list [lsort [glob td*]] [file writable td1] [file writable td2]
} {{td1 td2} 1 0}    
test fCmd-9.7 {file rename: comprehensive: file to existing file} {
    cleanup
    createfile tf1
    createfile tf2
    createfile tfs1
    createfile tfs2
    createfile tfs3
    createfile tfs4







|
|












<
<
<
<
<
<
<
<
|
|





|
|




|






|

















|






|






|


|


|


|



|



|
>




|






|



|



|





|





|






|










|




|




|










|




|




|





|



|
>



|




|




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






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











|





|
>











|





|


|


|







|








|







|


|




|





|





|





|


|


|



|
>
>
>
>
>
>





<
<
<
<
<
<
|


















|





|





|





|






|






|





|







|






<
<
<

>



|






|
















|
>





|
>





|
>







|
>








|
>









|
>








|
>






|
>







|
>





|
>



|
<
|



|
|
|
>






|





|




|




|



|





|






|
>







|









|



|








|







|








|








|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104








105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299












300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416






417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488



489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601

602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
    foreach p ". $args" {
	set x ""
	catch {
	    set x [glob [file join $p tf*] [file join $p td*]]
	}
	foreach file $x {
	    if {[catch {file delete -force -- $file}]} {
		catch {openup $file}
		catch {file delete -force -- $file}
	    }
	}
    }
}

proc contents {file} {
    set f [open $file r]
    set r [read $f]
    close $f
    set r
}









set ::tcltest::testConfig(fileSharing) 0
set ::tcltest::testConfig(notFileSharing) 1

if {$tcl_platform(platform) == "macintosh"} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    if {[catch {file attributes foo.dir -readonly 1}] == 0} {
    	set ::tcltest::testConfig(fileSharing) 1
    	set ::tcltest::testConfig(notFileSharing) 0
    }
    file delete -force foo.dir
}

set ::tcltest::testConfig(xdev) 0

if {$tcl_platform(platform) == "unix"} {
    if {[catch {set m1 [exec df .]; set m2 [exec df /tmp]}] == 0} {
	set m1 [string range $m1 0 [expr [string first " " $m1]-1]]
	set m2 [string range $m2 0 [expr [string first " " $m2]-1]]
	if {$m1 != "" && $m2 != "" && $m1 != $m2 && [file exists $m1] && [file exists $m2]} {
	    set ::tcltest::testConfig(xdev) 1
	}
    }
}

set root [lindex [file split [pwd]] 0]

# A really long file name
# length of long is 1216 chars, which should be greater than any static
# buffer or allowable filename.

set long "abcdefghihjllmnopqrstuvwxyz01234567890"
append long $long
append long $long
append long $long
append long $long
append long $long

test fCmd-1.1 {TclFileRenameCmd} {notRoot} {
    cleanup
    createfile tf1
    file rename tf1 tf2
    glob tf*
} {tf2}

test fCmd-2.1 {TclFileCopyCmd} {notRoot} {
    cleanup
    createfile tf1
    file copy tf1 tf2
    lsort [glob tf*]
} {tf1 tf2}

test fCmd-3.1 {FileCopyRename: FileForceOption fails} {notRoot} {
    list [catch {file rename -xyz} msg] $msg
} {1 {bad option "-xyz": should be -force or --}}
test fCmd-3.2 {FileCopyRename: not enough args} {notRoot} {
    list [catch {file rename xyz} msg] $msg
} {1 {wrong # args: should be "file rename ?options? source ?source ...? target"}}
test fCmd-3.3 {FileCopyRename: Tcl_TranslateFileName fails} {notRoot} {
    list [catch {file rename xyz ~nonexistantuser} msg] $msg
} {1 {user "nonexistantuser" doesn't exist}}
test fCmd-3.4 {FileCopyRename: Tcl_TranslateFileName passes} {notRoot} {
    cleanup
    list [catch {file copy tf1 ~} msg] $msg
} {1 {error copying "tf1": no such file or directory}}
test fCmd-3.5 {FileCopyRename: target doesn't exist: stat(target) != 0} {notRoot} {
    cleanup
    list [catch {file rename tf1 tf2 tf3} msg] $msg
} {1 {error renaming: target "tf3" is not a directory}}
test fCmd-3.6 {FileCopyRename: target tf3 is not a dir: !S_ISDIR(target)} \
	{notRoot} {
    cleanup
    createfile tf3
    list [catch {file rename tf1 tf2 tf3} msg] $msg
} {1 {error renaming: target "tf3" is not a directory}}
test fCmd-3.7 {FileCopyRename: target exists & is directory} {notRoot} {
    cleanup
    file mkdir td1
    createfile tf1 tf1
    file rename tf1 td1
    contents [file join td1 tf1]
} {tf1}
test fCmd-3.8 {FileCopyRename: too many arguments: argc - i > 2} {notRoot} {
    cleanup
    list [catch {file rename tf1 tf2 tf3} msg] $msg
} {1 {error renaming: target "tf3" is not a directory}}
test fCmd-3.9 {FileCopyRename: too many arguments: argc - i > 2} {notRoot} {
    cleanup
    list [catch {file copy -force -- tf1 tf2 tf3} msg] $msg
} {1 {error copying: target "tf3" is not a directory}}
test fCmd-3.10 {FileCopyRename: just 2 arguments} {notRoot} {
    cleanup
    createfile tf1 tf1
    file rename tf1 tf2
    contents tf2
} {tf1}
test fCmd-3.11 {FileCopyRename: just 2 arguments} {notRoot} {
    cleanup
    createfile tf1 tf1
    file rename -force -force -- tf1 tf2
    contents tf2
} {tf1}
test fCmd-3.12 {FileCopyRename: move each source: 1 source} {notRoot} {
    cleanup
    createfile tf1 tf1
    file mkdir td1
    file rename tf1 td1
    contents [file join td1 tf1]
} {tf1}
test fCmd-3.13 {FileCopyRename: move each source: multiple sources} {notRoot} {
    cleanup
    createfile tf1 tf1
    createfile tf2 tf2
    createfile tf3 tf3
    createfile tf4 tf4
    file mkdir td1
    file rename tf1 tf2 tf3 tf4 td1
    list [contents [file join td1 tf1]] [contents [file join td1 tf2]] \
	[contents [file join td1 tf3]] [contents [file join td1 tf4]]
} {tf1 tf2 tf3 tf4}
test fCmd-3.14 {FileCopyRename: FileBasename fails} {notRoot} {
    cleanup
    file mkdir td1
    list [catch {file rename ~nonexistantuser td1} msg] $msg
} {1 {user "nonexistantuser" doesn't exist}}
test fCmd-3.15 {FileCopyRename: source[0] == '\0'} {notRoot unixOrPc} {
    cleanup
    file mkdir td1
    list [catch {file rename / td1} msg] $msg
} {1 {error renaming "/" to "td1": file already exists}}
test fCmd-3.16 {FileCopyRename: break on first error} {notRoot} {
    cleanup
    createfile tf1 
    createfile tf2 
    createfile tf3 
    createfile tf4 
    file mkdir td1
    createfile [file join td1 tf3]
    list [catch {file rename tf1 tf2 tf3 tf4 td1} msg] $msg
} [subst {1 {error renaming "tf3" to "[file join td1 tf3]": file already exists}}]

test fCmd-4.1 {TclFileMakeDirsCmd: make each dir: 1 dir} {notRoot} {
    cleanup
    file mkdir td1
    glob td*
} {td1}
test fCmd-4.2 {TclFileMakeDirsCmd: make each dir: multiple dirs} {notRoot} {
    cleanup
    file mkdir td1 td2 td3
    lsort [glob td*]
} {td1 td2 td3}
test fCmd-4.3 {TclFileMakeDirsCmd: stops on first error} {notRoot} {
    cleanup
    createfile tf1
    catch {file mkdir td1 td2 tf1 td3 td4}
    glob td1 td2 tf1 td3 td4
} {td1 td2 tf1}
test fCmd-4.4 {TclFileMakeDirsCmd: Tcl_TranslateFileName fails} {notRoot} {
    cleanup
    list [catch {file mkdir ~nonexistantuser} msg] $msg
} {1 {user "nonexistantuser" doesn't exist}}
test fCmd-4.5 {TclFileMakeDirsCmd: Tcl_SplitPath returns 0: *name == '\0'} \
	{notRoot} {
    cleanup
    list [catch {file mkdir ""} msg] $msg
} {1 {can't create directory "": no such file or directory}}
test fCmd-4.6 {TclFileMakeDirsCmd: one level deep} {notRoot} {
    cleanup
    file mkdir td1
    glob td1
} {td1}
test fCmd-4.7 {TclFileMakeDirsCmd: multi levels deep} {notRoot} {
    cleanup
    file mkdir [file join td1 td2 td3 td4]
    glob td1 [file join td1 td2]
} "td1 [file join td1 td2]"
test fCmd-4.8 {TclFileMakeDirsCmd: already exist: lstat(target) == 0} {notRoot} {
    cleanup
    file mkdir td1
    set x [file exist td1]
    file mkdir td1
    list $x [file exist td1]
} {1 1}
test fCmd-4.9 {TclFileMakeDirsCmd: exists, not dir} {notRoot} {
    cleanup
    createfile tf1
    list [catch {file mkdir tf1} msg] $msg
} [subst {1 {can't create directory "[file join tf1]": file already exists}}]
test fCmd-4.10 {TclFileMakeDirsCmd: exists, is dir} {notRoot} {
    cleanup
    file mkdir td1
    set x [file exist td1]
    file mkdir td1
    list $x [file exist td1]
} {1 1}












test fCmd-4.11 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} \
	{unixOnly notRoot} {
    cleanup
    file mkdir td1/td2/td3
    testchmod 000 td1/td2
    set msg [list [catch {file mkdir td1/td2/td3/td4} msg] $msg]
    testchmod 755 td1/td2
    set msg
} {1 {can't create directory "td1/td2/td3": permission denied}}
test fCmd-4.12 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} {macOnly} {
    cleanup
    list [catch {file mkdir nonexistantvolume:} msg] $msg
} {1 {can't create directory "nonexistantvolume:": invalid argument}}
test fCmd-4.13 {TclFileMakeDirsCmd: doesn't exist: errno == ENOENT} {notRoot} {
    cleanup
    set x [file exist td1]
    file mkdir td1
    list $x [file exist td1]
} {0 1}
test fCmd-4.14 {TclFileMakeDirsCmd: TclpCreateDirectory fails} \
	{unixOnly notRoot} {
    cleanup
    file delete -force foo
    file mkdir foo
    file attr foo -perm 040000
    set result [list [catch {file mkdir foo/tf1} msg] $msg]
    file delete -force foo
    set result
} {1 {can't create directory "foo/tf1": permission denied}}
test fCmd-4.15 {TclFileMakeDirsCmd: TclpCreateDirectory fails} {macOnly} {
    list [catch {file mkdir ${root}:} msg] $msg
} [subst {1 {can't create directory "${root}:": no such file or directory}}]
test fCmd-4.16 {TclFileMakeDirsCmd: TclpCreateDirectory succeeds} {notRoot} {
    cleanup
    file mkdir tf1
    file exists tf1
} {1}

test fCmd-5.1 {TclFileDeleteCmd: FileForceOption fails} {notRoot} {
    list [catch {file delete -xyz} msg] $msg
} {1 {bad option "-xyz": should be -force or --}}
test fCmd-5.2 {TclFileDeleteCmd: not enough args} {notRoot} {
    list [catch {file delete -force -force} msg] $msg
} {1 {wrong # args: should be "file delete ?options? file ?file ...?"}}
test fCmd-5.3 {TclFileDeleteCmd: 1 file} {notRoot} {
    cleanup
    createfile tf1
    createfile tf2
    file mkdir td1
    file delete tf2
    glob tf* td*
} {tf1 td1}
test fCmd-5.4 {TclFileDeleteCmd: multiple files} {notRoot} {
    cleanup
    createfile tf1
    createfile tf2
    file mkdir td1
    set x [list [file exist tf1] [file exist tf2] [file exist td1]]
    file delete tf1 td1 tf2
    lappend x [file exist tf1] [file exist tf2] [file exist tf3]
} {1 1 1 0 0 0}
test fCmd-5.5 {TclFileDeleteCmd: stop at first error} {notRoot unixOrPc} {
    cleanup
    createfile tf1
    createfile tf2
    file mkdir td1
    catch {file delete tf1 td1 $root tf2}
    list [file exist tf1] [file exist tf2] [file exist td1]
} {0 1 0}
test fCmd-5.6 {TclFileDeleteCmd: Tcl_TranslateFileName fails} {notRoot} {
    list [catch {file delete ~nonexistantuser} msg] $msg
} {1 {user "nonexistantuser" doesn't exist}}
test fCmd-5.7 {TclFileDeleteCmd: Tcl_TranslateFileName succeeds} {notRoot} {
    catch {file delete ~/tf1}
    createfile ~/tf1
    file delete ~/tf1
} {}
test fCmd-5.8 {TclFileDeleteCmd: file doesn't exist: lstat(name) != 0} {notRoot} {
    cleanup
    set x [file exist tf1]
    file delete tf1
    list $x [file exist tf1]
} {0 0}    
test fCmd-5.9 {TclFileDeleteCmd: is directory} {notRoot} {
    cleanup
    file mkdir td1
    file delete td1
    file exist td1
} {0}
test fCmd-5.10 {TclFileDeleteCmd: TclpRemoveDirectory fails} {notRoot} {
    cleanup
    file mkdir td1/td2
    list [catch {file delete td1} msg] $msg
} {1 {error deleting "td1": directory not empty}}

test fCmd-6.1 {CopyRenameOneFile: bad source} {notRoot} {
    # can't test this, because it's caught by FileCopyRename
} {}
test fCmd-6.2 {CopyRenameOneFile: bad target} {notRoot} {
    # can't test this, because it's caught by FileCopyRename
} {}
test fCmd-6.3 {CopyRenameOneFile: lstat(source) != 0} {notRoot} {
    cleanup
    list [catch {file rename tf1 tf2} msg] $msg
} {1 {error renaming "tf1": no such file or directory}}
test fCmd-6.4 {CopyRenameOneFile: lstat(source) == 0} {notRoot} {
    cleanup
    createfile tf1
    file rename tf1 tf2
    glob tf*
} {tf2}
test fCmd-6.5 {CopyRenameOneFile: lstat(target) != 0} {notRoot} {
    cleanup
    createfile tf1
    file rename tf1 tf2
    glob tf*
} {tf2}






test fCmd-6.6 {CopyRenameOneFile: errno != ENOENT} {unixOnly notRoot} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    createfile tf1
    set msg [list [catch {file rename tf1 td1} msg] $msg]
    testchmod 755 td1
    set msg
} {1 {error renaming "tf1" to "td1/tf1": permission denied}}
test fCmd-6.7 {CopyRenameOneFile: errno != ENOENT} {95} {
    cleanup
    createfile tf1
    list [catch {file rename tf1 $long} msg] $msg
} [subst {1 {error renaming "tf1" to "$long": file name too long}}]
test fCmd-6.8 {CopyRenameOneFile: errno != ENOENT} {macOnly} {
    cleanup
    createfile tf1
    list [catch {file rename tf1 $long} msg] $msg
} [subst {1 {error renaming "tf1" to "$long": file name too long}}]
test fCmd-6.9 {CopyRenameOneFile: errno == ENOENT} {unixOnly notRoot} {
    cleanup
    createfile tf1
    file rename tf1 tf2
    glob tf*
} {tf2}
test fCmd-6.10 {CopyRenameOneFile: lstat(target) == 0} {notRoot} {
    cleanup
    createfile tf1
    createfile tf2
    list [catch {file rename tf1 tf2} msg] $msg
} {1 {error renaming "tf1" to "tf2": file already exists}}
test fCmd-6.11 {CopyRenameOneFile: force == 0} {notRoot} {
    cleanup
    createfile tf1
    createfile tf2
    list [catch {file rename tf1 tf2} msg] $msg
} {1 {error renaming "tf1" to "tf2": file already exists}}
test fCmd-6.12 {CopyRenameOneFile: force != 0} {notRoot} {
    cleanup
    createfile tf1
    createfile tf2
    file rename -force tf1 tf2
    glob tf*
} {tf2}
test fCmd-6.13 {CopyRenameOneFile: source is dir, target is file} {notRoot} {
    cleanup
    file mkdir td1
    file mkdir td2
    createfile [file join td2 td1]
    list [catch {file rename -force td1 td2} msg] $msg
} [subst {1 {can't overwrite file "[file join td2 td1]" with directory "td1"}}]
test fCmd-6.14 {CopyRenameOneFile: source is file, target is dir} {notRoot} {
    cleanup
    createfile tf1
    file mkdir [file join td1 tf1]
    list [catch {file rename -force tf1 td1} msg] $msg
} [subst {1 {can't overwrite directory "[file join td1 tf1]" with file "tf1"}}]
test fCmd-6.15 {CopyRenameOneFile: TclpRenameFile succeeds} {notRoot} {
    cleanup
    file mkdir [file join td1 td2]
    file mkdir td2
    createfile [file join td2 tf1]
    file rename -force td2 td1
    file exists [file join td1 td2 tf1]
} {1}
test fCmd-6.16 {CopyRenameOneFile: TclpCopyRenameOneFile fails} {notRoot} {
    cleanup
    file mkdir [file join td1 td2]
    createfile [file join td1 td2 tf1]
    file mkdir td2
    list [catch {file rename -force td2 td1} msg] $msg
} [subst {1 {error renaming "td2" to "[file join td1 td2]": file already exists}}]




test fCmd-6.17 {CopyRenameOneFile: errno == EINVAL} {notRoot} {
    cleanup
    list [catch {file rename -force $root tf1} msg] $msg
} [subst {1 {error renaming "$root" to "tf1": trying to rename a volume or move a directory into itself}}]
test fCmd-6.18 {CopyRenameOneFile: errno != EXDEV} {notRoot} {
    cleanup
    file mkdir [file join td1 td2]
    createfile [file join td1 td2 tf1]
    file mkdir td2
    list [catch {file rename -force td2 td1} msg] $msg
} [subst {1 {error renaming "td2" to "[file join td1 td2]": file already exists}}]
test fCmd-6.19 {CopyRenameOneFile: errno == EXDEV} {unixOnly notRoot} {
    cleanup /tmp
    createfile tf1
    file rename tf1 /tmp
    glob tf* /tmp/tf1
} {/tmp/tf1}
test fCmd-6.20 {CopyRenameOneFile: errno == EXDEV} {pcOnly} {
    catch {file delete -force c:/tcl8975@ d:/tcl8975@}
    file mkdir c:/tcl8975@
    if [catch {file rename c:/tcl8975@ d:/}] {
	list d:/tcl8975@
    } else {
	set msg [glob c:/tcl8975@ d:/tcl8975@]
	file delete -force d:/tcl8975@
	set msg
    }
} {d:/tcl8975@}
test fCmd-6.21 {CopyRenameOneFile: copy/rename: S_ISDIR(source)} \
	{unixOnly notRoot} {
    cleanup /tmp
    file mkdir td1
    file rename td1 /tmp
    glob td* /tmp/td*
} {/tmp/td1}
test fCmd-6.22 {CopyRenameOneFile: copy/rename: !S_ISDIR(source)} \
	{unixOnly notRoot} {
    cleanup /tmp
    createfile tf1
    file rename tf1 /tmp
    glob tf* /tmp/tf*
} {/tmp/tf1}
test fCmd-6.23 {CopyRenameOneFile: TclpCopyDirectory failed} \
	{unixOnly notRoot xdev} {
    cleanup /tmp
    file mkdir td1/td2/td3
    exec chmod 000 td1
    set msg [list [catch {file rename td1 /tmp} msg] $msg]
    exec chmod 755 td1
    set msg 
} {1 {error renaming "td1": permission denied}}
test fCmd-6.24 {CopyRenameOneFile: error uses original name} \
	{unixOnly notRoot} {
    cleanup
    file mkdir ~/td1/td2
    exec chmod 000 [file join [file dirname ~] [file tail ~] td1]
    set msg [list [catch {file copy ~/td1 td1} msg] $msg]
    exec chmod 755 [file join [file dirname ~] [file tail ~] td1]
    file delete -force ~/td1
    set msg
} {1 {error copying "~/td1": permission denied}}
test fCmd-6.25 {CopyRenameOneFile: error uses original name} \
	{unixOnly notRoot} {
    cleanup
    file mkdir td2
    file mkdir ~/td1
    exec chmod 000 [file join [file dirname ~] [file tail ~] td1]
    set msg [list [catch {file copy td2 ~/td1} msg] $msg]
    exec chmod 755 [file join [file dirname ~] [file tail ~] td1]
    file delete -force ~/td1
    set msg
} {1 {error copying "td2" to "~/td1/td2": permission denied}}
test fCmd-6.26 {CopyRenameOneFile: doesn't use original name} \
	{unixOnly notRoot} {
    cleanup
    file mkdir ~/td1/td2
    exec chmod 000 [file join [file dirname ~] [file tail ~] td1 td2]
    set msg [list [catch {file copy ~/td1 td1} msg] $msg]
    exec chmod 755 [file join [file dirname ~] [file tail ~] td1 td2]
    file delete -force ~/td1
    set msg
} "1 {error copying \"~/td1\" to \"td1\": \"[file join [file dirname ~] [file tail ~] td1 td2]\": permission denied}"
test fCmd-6.27 {CopyRenameOneFile: TclpCopyDirectory failed} \
	{unixOnly notRoot xdev} {
    cleanup /tmp
    file mkdir td1/td2/td3
    file mkdir /tmp/td1
    createfile /tmp/td1/tf1
    list [catch {file rename -force td1 /tmp} msg] $msg
} {1 {error renaming "td1" to "/tmp/td1": file already exists}}
test fCmd-6.28 {CopyRenameOneFile: TclpCopyDirectory failed} \
	{unixOnly notRoot xdev} {
    cleanup /tmp
    file mkdir td1/td2/td3
    exec chmod 000 td1/td2/td3 
    set msg [list [catch {file rename td1 /tmp} msg] $msg]
    exec chmod 755 td1/td2/td3 
    set msg
} {1 {error renaming "td1" to "/tmp/td1": "td1/td2/td3": permission denied}}
test fCmd-6.29 {CopyRenameOneFile: TclpCopyDirectory passed} \
	{unixOnly notRoot xdev} {
    cleanup /tmp
    file mkdir td1/td2/td3
    file rename td1 /tmp
    glob td* /tmp/td1/t*
} {/tmp/td1/td2}
test fCmd-6.30 {CopyRenameOneFile: TclpRemoveDirectory failed} \
	{unixOnly notRoot} {
    cleanup
    file mkdir foo/bar
    file attr foo -perm 040555
    set catchResult [catch {file rename foo/bar /tmp} msg]

    set msg [lindex [split $msg :] end]
    catch {file delete /tmp/bar}
    catch {file attr foo -perm 040777}
    catch {file delete -force foo}
    list $catchResult $msg
} {1 { permission denied}}
test fCmd-6.31 {CopyRenameOneFile: TclpDeleteFile passed} \
	{unixOnly notRoot xdev} {
    catch {cleanup /tmp}
    file mkdir /tmp/td1
    createfile /tmp/td1/tf1
    file rename /tmp/td1/tf1 tf1
    list [file exists /tmp/td1/tf1] [file exists tf1]
} {0 1}
test fCmd-6.32 {CopyRenameOneFile: copy} {notRoot} {
    cleanup
    list [catch {file copy tf1 tf2} msg] $msg
} {1 {error copying "tf1": no such file or directory}}
catch {cleanup /tmp}

test fCmd-7.1 {FileForceOption: none} {notRoot} {
    cleanup
    file mkdir [file join tf1 tf2]
    list [catch {file delete tf1} msg] $msg
} {1 {error deleting "tf1": directory not empty}}
test fCmd-7.2 {FileForceOption: -force} {notRoot} {
    cleanup
    file mkdir [file join tf1 tf2]
    file delete -force tf1
} {}
test fCmd-7.3 {FileForceOption: --} {notRoot} {
    createfile -tf1
    file delete -- -tf1
} {}
test fCmd-7.4 {FileForceOption: bad option} {notRoot} {
    createfile -tf1
    set msg [list [catch {file delete -tf1} msg] $msg]
    file delete -- -tf1
    set msg
} {1 {bad option "-tf1": should be -force or --}}
test fCmd-7.5 {FileForceOption: multiple times through loop} {notRoot} {
    createfile --
    createfile -force
    file delete -force -force -- -- -force
    list [catch {glob -- -- -force} msg] $msg
} {1 {no files matched glob patterns "-- -force"}}

test fCmd-8.1 {FileBasename: basename of ~user: argc == 1 && *path == ~} \
	{unixOnly notRoot} {
    file mkdir td1
    file attr td1 -perm 040000
    set result [list [catch {file rename ~$user td1} msg] $msg]
    file delete -force td1
    set result
} "1 {error renaming \"~$user\" to \"td1/[file tail ~$user]\": permission denied}"

test fCmd-9.1 {file rename: comprehensive: EACCES} {unixOnly notRoot} {
    cleanup
    file mkdir td1
    file mkdir td2
    file attr td2 -perm 040000
    set result [list [catch {file rename td1 td2/} msg] $msg]
    file delete -force td2
    file delete -force td1
    set result
} {1 {error renaming "td1" to "td2/td1": permission denied}}
test fCmd-9.2 {file rename: comprehensive: source doesn't exist} {notRoot} {
    cleanup
    list [catch {file rename tf1 tf2} msg] $msg
} {1 {error renaming "tf1": no such file or directory}}
test fCmd-9.3 {file rename: comprehensive: file to new name} {notRoot} {
    cleanup
    createfile tf1
    createfile tf2
    testchmod 444 tf2
    file rename tf1 tf3
    file rename tf2 tf4
    list [lsort [glob tf*]] [file writable tf3] [file writable tf4]
} {{tf3 tf4} 1 0}    
test fCmd-9.4 {file rename: comprehensive: dir to new name} {unixOrPc notRoot} {
    cleanup
    file mkdir td1 td2
    testchmod 555 td2
    file rename td1 td3
    file rename td2 td4
    list [lsort [glob td*]] [file writable td3] [file writable td4]
} {{td3 td4} 1 0}    
test fCmd-9.5 {file rename: comprehensive: file to self} {notRoot} {
    cleanup
    createfile tf1 tf1
    createfile tf2 tf2
    testchmod 444 tf2
    file rename -force tf1 tf1
    file rename -force tf2 tf2
    list [contents tf1] [contents tf2] [file writable tf1] [file writable tf2]
} {tf1 tf2 1 0}    
test fCmd-9.6 {file rename: comprehensive: dir to self} {notRoot unixOrPc} {
    cleanup
    file mkdir td1
    file mkdir td2
    testchmod 555 td2
    file rename -force td1 .
    file rename -force td2 .
    list [lsort [glob td*]] [file writable td1] [file writable td2]
} {{td1 td2} 1 0}    
test fCmd-9.7 {file rename: comprehensive: file to existing file} {notRoot} {
    cleanup
    createfile tf1
    createfile tf2
    createfile tfs1
    createfile tfs2
    createfile tfs3
    createfile tfs4
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
    set msg [list [catch {file rename tf1 tf2} msg] $msg]
    file rename -force tfs1 tfd1
    file rename -force tfs2 tfd2
    file rename -force tfs3 tfd3
    file rename -force tfs4 tfd4
    list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4] 
} {{tf1 tf2 tfd1 tfd2 tfd3 tfd4} {1 {error renaming "tf1" to "tf2": file already exists}} 1 1 0 0}
test fCmd-9.8 {file rename: comprehensive: dir to empty dir} {
    # Under unix, you can rename a read-only directory, but you can't
    # move it into another directory.

    cleanup
    file mkdir td1
    file mkdir [file join td2 td1]
    file mkdir tds1







|







723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
    set msg [list [catch {file rename tf1 tf2} msg] $msg]
    file rename -force tfs1 tfd1
    file rename -force tfs2 tfd2
    file rename -force tfs3 tfd3
    file rename -force tfs4 tfd4
    list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4] 
} {{tf1 tf2 tfd1 tfd2 tfd3 tfd4} {1 {error renaming "tf1" to "tf2": file already exists}} 1 1 0 0}
test fCmd-9.8 {file rename: comprehensive: dir to empty dir} {notRoot} {
    # Under unix, you can rename a read-only directory, but you can't
    # move it into another directory.

    cleanup
    file mkdir td1
    file mkdir [file join td2 td1]
    file mkdir tds1
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818

819
820
821
822
823
824

825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
    } else {
	set w3 0
	set w4 0
    }
    list [lsort [glob td*]] $msg [file writable [file join tdd1 tds1]] \
    [file writable [file join tdd2 tds2]] $w3 $w4
} [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4} {1 {error renaming "td1" to "[file join td2 td1]": file already exists}} 1 1 0 0}]
test fCmd-9.9 {file rename: comprehensive: dir to non-empty dir} {
    cleanup
    file mkdir tds1
    file mkdir tds2
    file mkdir [file join tdd1 tds1 xxx]
    file mkdir [file join tdd2 tds2 xxx]
    if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
	testchmod 555 tds2
    }
    set a1 [list [catch {file rename -force tds1 tdd1} msg] $msg]
    set a2 [list [catch {file rename -force tds2 tdd2} msg] $msg]
    if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
	set w2 [file writable tds2]
    } else {
	set w2 0
    }
    list [lsort [glob td*]] $a1 $a2 [file writable tds1] $w2
} [subst {{tdd1 tdd2 tds1 tds2} {1 {error renaming "tds1" to "[file join tdd1 tds1]": file already exists}} {1 {error renaming "tds2" to "[file join tdd2 tds2]": file already exists}} 1 0}]
test fCmd-9.10 {file rename: comprehensive: file to new name and dir} {
    cleanup
    createfile tf1
    createfile tf2
    file mkdir td1
    testchmod 444 tf2
    file rename tf1 [file join td1 tf3]
    file rename tf2 [file join td1 tf4]
    list [catch {glob tf*}] [lsort [glob [file join td1 t*]]] \
    [file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
} [subst {1 {[file join td1 tf3] [file join td1 tf4]} 1 0}]
test fCmd-9.11 {file rename: comprehensive: dir to new name and dir} {
    cleanup
    file mkdir td1
    file mkdir td2
    file mkdir td3
    if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
	testchmod 555 td2
    }
    file rename td1 [file join td3 td3]
    file rename td2 [file join td3 td4]
    if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
	set w4 [file writable [file join td3 td4]]
    } else {
        set w4 0
    }
    list [lsort [glob td*]] [lsort [glob [file join td3 t*]]] \
    [file writable [file join td3 td3]] $w4
} [subst {td3 {[file join td3 td3] [file join td3 td4]} 1 0}]
test fCmd-9.12 {file rename: comprehensive: target exists} {
    cleanup
    file mkdir [file join td1 td2] [file join td2 td1]
    if {$tcl_platform(platform) != "macintosh"} {
    	testchmod 555 [file join td2 td1]
    }
    file mkdir [file join td3 td4] [file join td4 td3]
    file rename -force td3 td4
    set msg [list [file exists td3] [file exists [file join td4 td3 td4]] \
    [catch {file rename td1 td2} msg] $msg]
    if {$tcl_platform(platform) != "macintosh"} {
    	testchmod 755 [file join td2 td1]
    }
    set msg
} [subst {0 1 1 {error renaming "td1" to "[file join td2 td1]": file already exists}}]
test fCmd-9.13 {file rename: comprehensive: can't overwrite target} {
    cleanup
    file mkdir [file join td1 td2] [file join td2 td1 td4]
    list [catch {file rename -force td1 td2} msg] $msg
} [subst {1 {error renaming "td1" to "[file join td2 td1]": file already exists}}]
test fCmd-9.14 {file rename: comprehensive: dir into self} {
    cleanup
    file mkdir td1
    list [glob td*] [list [catch {file rename td1 td1} msg] $msg]
} [subst {td1 {1 {error renaming "td1" to "[file join td1 td1]": trying to rename a volume or move a directory into itself}}}]
test fCmd-9.15 {file rename: comprehensive: source and target incompatible} {

    cleanup
    file mkdir td1
    createfile tf1
    list [catch {file rename -force td1 tf1} msg] $msg
} {1 {can't overwrite file "tf1" with directory "td1"}}
test fCmd-9.16 {file rename: comprehensive: source and target incompatible} {

    cleanup
    file mkdir td1/tf1
    createfile tf1
    list [catch {file rename -force tf1 td1} msg] $msg
} [subst {1 {can't overwrite directory "[file join td1 tf1]" with file "tf1"}}]

test fCmd-10.1 {file copy: comprehensive: source doesn't exist} {
    cleanup
    list [catch {file copy tf1 tf2} msg] $msg
} {1 {error copying "tf1": no such file or directory}}
test fCmd-10.2 {file copy: comprehensive: file to new name} {
    cleanup
    createfile tf1 tf1
    createfile tf2 tf2
    testchmod 444 tf2
    file copy tf1 tf3
    file copy tf2 tf4
    list [lsort [glob tf*]] [contents tf3] [contents tf4] [file writable tf3] [file writable tf4]
} {{tf1 tf2 tf3 tf4} tf1 tf2 1 0}
test fCmd-10.3 {file copy: comprehensive: dir to new name} {unixOrPc} {
    cleanup
    file mkdir [file join td1 tdx]
    file mkdir [file join td2 tdy]
    testchmod 555 td2
    file copy td1 td3
    file copy td2 td4
    set msg [list [lsort [glob td*]] [glob [file join td3 t*]] \
	    [glob [file join td4 t*]] [file writable td3] [file writable td4]]
    if {$tcl_platform(platform) != "macintosh"} {
    	testchmod 755 td2
    	testchmod 755 td4
    }
    set msg
} [subst {{td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 0}]
test fCmd-10.4 {file copy: comprehensive: file to existing file} {
    cleanup
    createfile tf1
    createfile tf2
    createfile tfs1
    createfile tfs2
    createfile tfs3
    createfile tfs4







|

















|










|

















|














|




|




|
>





|
>






|



|








|














|







761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
    } else {
	set w3 0
	set w4 0
    }
    list [lsort [glob td*]] $msg [file writable [file join tdd1 tds1]] \
    [file writable [file join tdd2 tds2]] $w3 $w4
} [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4} {1 {error renaming "td1" to "[file join td2 td1]": file already exists}} 1 1 0 0}]
test fCmd-9.9 {file rename: comprehensive: dir to non-empty dir} {notRoot} {
    cleanup
    file mkdir tds1
    file mkdir tds2
    file mkdir [file join tdd1 tds1 xxx]
    file mkdir [file join tdd2 tds2 xxx]
    if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
	testchmod 555 tds2
    }
    set a1 [list [catch {file rename -force tds1 tdd1} msg] $msg]
    set a2 [list [catch {file rename -force tds2 tdd2} msg] $msg]
    if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
	set w2 [file writable tds2]
    } else {
	set w2 0
    }
    list [lsort [glob td*]] $a1 $a2 [file writable tds1] $w2
} [subst {{tdd1 tdd2 tds1 tds2} {1 {error renaming "tds1" to "[file join tdd1 tds1]": file already exists}} {1 {error renaming "tds2" to "[file join tdd2 tds2]": file already exists}} 1 0}]
test fCmd-9.10 {file rename: comprehensive: file to new name and dir} {notRoot} {
    cleanup
    createfile tf1
    createfile tf2
    file mkdir td1
    testchmod 444 tf2
    file rename tf1 [file join td1 tf3]
    file rename tf2 [file join td1 tf4]
    list [catch {glob tf*}] [lsort [glob [file join td1 t*]]] \
    [file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
} [subst {1 {[file join td1 tf3] [file join td1 tf4]} 1 0}]
test fCmd-9.11 {file rename: comprehensive: dir to new name and dir} {notRoot} {
    cleanup
    file mkdir td1
    file mkdir td2
    file mkdir td3
    if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
	testchmod 555 td2
    }
    file rename td1 [file join td3 td3]
    file rename td2 [file join td3 td4]
    if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
	set w4 [file writable [file join td3 td4]]
    } else {
        set w4 0
    }
    list [lsort [glob td*]] [lsort [glob [file join td3 t*]]] \
    [file writable [file join td3 td3]] $w4
} [subst {td3 {[file join td3 td3] [file join td3 td4]} 1 0}]
test fCmd-9.12 {file rename: comprehensive: target exists} {notRoot} {
    cleanup
    file mkdir [file join td1 td2] [file join td2 td1]
    if {$tcl_platform(platform) != "macintosh"} {
    	testchmod 555 [file join td2 td1]
    }
    file mkdir [file join td3 td4] [file join td4 td3]
    file rename -force td3 td4
    set msg [list [file exists td3] [file exists [file join td4 td3 td4]] \
    [catch {file rename td1 td2} msg] $msg]
    if {$tcl_platform(platform) != "macintosh"} {
    	testchmod 755 [file join td2 td1]
    }
    set msg
} [subst {0 1 1 {error renaming "td1" to "[file join td2 td1]": file already exists}}]
test fCmd-9.13 {file rename: comprehensive: can't overwrite target} {notRoot} {
    cleanup
    file mkdir [file join td1 td2] [file join td2 td1 td4]
    list [catch {file rename -force td1 td2} msg] $msg
} [subst {1 {error renaming "td1" to "[file join td2 td1]": file already exists}}]
test fCmd-9.14 {file rename: comprehensive: dir into self} {notRoot} {
    cleanup
    file mkdir td1
    list [glob td*] [list [catch {file rename td1 td1} msg] $msg]
} [subst {td1 {1 {error renaming "td1" to "[file join td1 td1]": trying to rename a volume or move a directory into itself}}}]
test fCmd-9.15 {file rename: comprehensive: source and target incompatible} \
	{notRoot} {
    cleanup
    file mkdir td1
    createfile tf1
    list [catch {file rename -force td1 tf1} msg] $msg
} {1 {can't overwrite file "tf1" with directory "td1"}}
test fCmd-9.16 {file rename: comprehensive: source and target incompatible} \
	{notRoot} {
    cleanup
    file mkdir td1/tf1
    createfile tf1
    list [catch {file rename -force tf1 td1} msg] $msg
} [subst {1 {can't overwrite directory "[file join td1 tf1]" with file "tf1"}}]

test fCmd-10.1 {file copy: comprehensive: source doesn't exist} {notRoot} {
    cleanup
    list [catch {file copy tf1 tf2} msg] $msg
} {1 {error copying "tf1": no such file or directory}}
test fCmd-10.2 {file copy: comprehensive: file to new name} {notRoot} {
    cleanup
    createfile tf1 tf1
    createfile tf2 tf2
    testchmod 444 tf2
    file copy tf1 tf3
    file copy tf2 tf4
    list [lsort [glob tf*]] [contents tf3] [contents tf4] [file writable tf3] [file writable tf4]
} {{tf1 tf2 tf3 tf4} tf1 tf2 1 0}
test fCmd-10.3 {file copy: comprehensive: dir to new name} {notRoot unixOrPc} {
    cleanup
    file mkdir [file join td1 tdx]
    file mkdir [file join td2 tdy]
    testchmod 555 td2
    file copy td1 td3
    file copy td2 td4
    set msg [list [lsort [glob td*]] [glob [file join td3 t*]] \
	    [glob [file join td4 t*]] [file writable td3] [file writable td4]]
    if {$tcl_platform(platform) != "macintosh"} {
    	testchmod 755 td2
    	testchmod 755 td4
    }
    set msg
} [subst {{td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 0}]
test fCmd-10.4 {file copy: comprehensive: file to existing file} {notRoot} {
    cleanup
    createfile tf1
    createfile tf2
    createfile tfs1
    createfile tfs2
    createfile tfs3
    createfile tfs4
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
    set msg [list [catch {file copy tf1 tf2} msg] $msg]
    file copy -force tfs1 tfd1
    file copy -force tfs2 tfd2
    file copy -force tfs3 tfd3
    file copy -force tfs4 tfd4
    list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4] 
} {{tf1 tf2 tfd1 tfd2 tfd3 tfd4 tfs1 tfs2 tfs3 tfs4} {1 {error copying "tf1" to "tf2": file already exists}} 1 1 0 0}
test fCmd-10.5 {file copy: comprehensive: dir to empty dir} {
    cleanup
    file mkdir td1
    file mkdir [file join td2 td1]
    file mkdir tds1
    file mkdir tds2
    file mkdir tds3
    file mkdir tds4







|







899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
    set msg [list [catch {file copy tf1 tf2} msg] $msg]
    file copy -force tfs1 tfd1
    file copy -force tfs2 tfd2
    file copy -force tfs3 tfd3
    file copy -force tfs4 tfd4
    list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4] 
} {{tf1 tf2 tfd1 tfd2 tfd3 tfd4 tfs1 tfs2 tfs3 tfs4} {1 {error copying "tf1" to "tf2": file already exists}} 1 1 0 0}
test fCmd-10.5 {file copy: comprehensive: dir to empty dir} {notRoot} {
    cleanup
    file mkdir td1
    file mkdir [file join td2 td1]
    file mkdir tds1
    file mkdir tds2
    file mkdir tds3
    file mkdir tds4
900
901
902
903
904
905
906
907

908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929

930
931
932
933
934
935
936
937
938
939
940

941
942
943
944
945
946

947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131

1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364

1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521

1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607
1608

1609
1610
1611
1612
1613
1614
1615
1616
1617

1618
1619
1620
1621
1622
1623
1624
1625
1626

1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641

1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653

1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665

1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681

1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746

1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789

1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814

1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858

1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
    set a1 [list [catch {file copy td1 td2} msg] $msg]
    set a2 [list [catch {file copy -force tds1 tdd1} msg] $msg]
    set a3 [catch {file copy -force tds2 tdd2}]
    set a4 [catch {file copy -force tds3 tdd3}]
    set a5 [catch {file copy -force tds4 tdd4}]
    list [lsort [glob td*]] $a1 $a2 $a3 $a4 $a5 
} [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4 tds1 tds2 tds3 tds4} {1 {error copying "td1" to "[file join td2 td1]": file already exists}} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} 1 1 1}]
test fCmd-10.6 {file copy: comprehensive: dir to non-empty dir} {unixOrPc} {

    cleanup
    file mkdir tds1
    file mkdir tds2
    file mkdir [file join tdd1 tds1 xxx]
    file mkdir [file join tdd2 tds2 xxx]
    testchmod 555 tds2
    set a1 [list [catch {file copy -force tds1 tdd1} msg] $msg]
    set a2 [list [catch {file copy -force tds2 tdd2} msg] $msg]
    list [lsort [glob td*]] $a1 $a2 [file writable tds1] [file writable tds2]
} [subst {{tdd1 tdd2 tds1 tds2} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} {1 {error copying "tds2" to "[file join tdd2 tds2]": file already exists}} 1 0}]
test fCmd-10.7 {file rename: comprehensive: file to new name and dir} {
    cleanup
    createfile tf1
    createfile tf2
    file mkdir td1
    testchmod 444 tf2
    file copy tf1 [file join td1 tf3]
    file copy tf2 [file join td1 tf4]
    list [lsort [glob tf*]] [lsort [glob [file join td1 t*]]] \
    [file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
} [subst {{tf1 tf2} {[file join td1 tf3] [file join td1 tf4]} 1 0}]
test fCmd-10.8 {file rename: comprehensive: dir to new name and dir} {unixOrPc} {

    cleanup
    file mkdir td1
    file mkdir td2
    file mkdir td3
    testchmod 555 td2
    file copy td1 [file join td3 td3]
    file copy td2 [file join td3 td4]
    list [lsort [glob td*]] [lsort [glob [file join td3 t*]]] \
    [file writable [file join td3 td3]] [file writable [file join td3 td4]]
} [subst {{td1 td2 td3} {[file join td3 td3] [file join td3 td4]} 1 0}]
test fCmd-10.9 {file copy: comprehensive: source and target incompatible} {

    cleanup
    file mkdir td1
    createfile tf1
    list [catch {file copy -force td1 tf1} msg] $msg
} {1 {can't overwrite file "tf1" with directory "td1"}}
test fCmd-10.10 {file copy: comprehensive: source and target incompatible} {

    cleanup
    file mkdir [file join td1 tf1]
    createfile tf1
    list [catch {file copy -force tf1 td1} msg] $msg
} [subst {1 {can't overwrite directory "[file join td1 tf1]" with file "tf1"}}]
cleanup    

# old tests    

test fCmd-11.1 {TclFileRenameCmd: -- option } {
    catch {file delete -force -- -tfa1}
    set s [createfile -tfa1]
    file rename -- -tfa1 tfa2
    set result [expr [checkcontent tfa2 $s] && ![file exists -tfa1]]
    file delete tfa2
    set result
} {1}

test fCmd-11.2 {TclFileRenameCmd: bad option } {
    catch {file delete -force -- tfa1}
    set s [createfile tfa1]
    set r1 [catch {file rename -x tfa1 tfa2}]
    set result [expr $r1 && [checkcontent tfa1 $s] && ![file exists tfa2]]
    file delete tfa1
    set result
} {1}

test fCmd-11.3 {TclFileRenameCmd: bad \# args} {
    catch {file rename -- }
} {1}

test fCmd-11.4 {TclFileRenameCmd: target filename translation failing} {
     global env
     set temp $env(HOME)
     unset env(HOME)
     set result [catch {file rename tfa ~/foobar }]
     set env(HOME) $temp
     set result
 } {1}

test fCmd-11.5 {TclFileRenameCmd: more than one source and target is not a directory} {
    catch {file delete -force -- tfa1 tfa2 tfa3}
    createfile tfa1 
    createfile tfa2 
    createfile tfa3 
    set result [catch {file rename tfa1 tfa2 tfa3}]
    file delete tfa1 tfa2 tfa3
    set result
} {1}

test fCmd-11.6 {TclFileRenameCmd: : single file into directory  } {
    catch {file delete -force -- tfa1 tfad}
    set s [createfile tfa1]
    file mkdir tfad
    file rename tfa1 tfad
    set result [expr [checkcontent tfad/tfa1 $s] && ![file exists tfa1]]
    file delete -force tfad
    set result
} {1}

test fCmd-11.7 {TclFileRenameCmd: : multiple files into directory  } {
    catch {file delete -force -- tfa1 tfa2 tfad}
    set s1 [createfile tfa1 ]
    set s2 [createfile tfa2 ]
    file mkdir tfad
    file rename tfa1 tfa2 tfad
    set r1 [checkcontent tfad/tfa1 $s1]
    set r2 [checkcontent tfad/tfa2 $s2]
    
    set result [expr $r1 && $r2 && ![file exists tfa1] && ![file exists tfa2]]
	    
    file delete -force tfad
    set result
} {1}

test fCmd-11.8 {TclFileRenameCmd: error renaming file to directory } {
    catch {file delete -force -- tfa tfad}
    set s [createfile tfa ]
    file mkdir tfad
    file mkdir tfad/tfa
    set r1 [catch {file rename tfa tfad}]
    set r2 [checkcontent tfa $s]
    set r3 [file isdir tfad]
    set result [expr $r1 && $r2 && $r3 ]
    file delete -force tfa tfad
    set result
} {1}

#
# Coverage tests for renamefile() ;
#
test fCmd-12.1 {renamefile: source filename translation failing} {
    global env
    set temp $env(HOME)
    unset env(HOME)
    set result [catch {file rename ~/tfa1 tfa2}]
    set env(HOME) $temp
    set result
} {1}

test fCmd-12.2 {renamefile: src filename translation failing} {
    global env
    set temp $env(HOME)
    unset env(HOME)
    set s [createfile tfa1]
    file mkdir tfad
    set result [catch {file rename tfa1 ~/tfa2 tfad}]
    set env(HOME) $temp
    file delete -force tfad
    set result
} {1}

test fCmd-12.3 {renamefile: stat failing on source} {
    catch {file delete -force -- tfa1 tfa2}
    set r1 [catch {file rename tfa1 tfa2}]
    expr {$r1 && ![file exists tfa1] && ![file exists tfa2]}
} {1}

test fCmd-12.4 {renamefile: error renaming file to directory } {
    catch {file delete -force -- tfa tfad}
    set s1 [createfile tfa ]
    file mkdir tfad
    file mkdir tfad/tfa
    set r1 [catch {file rename tfa tfad}]
    set r2 [checkcontent tfa $s1]
    set r3 [file isdir tfad/tfa]
    set result [expr $r1 && $r2 && $r3]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-12.5 {renamefile: error renaming directory to file } {
    catch {file delete -force -- tfa tfad}
    file mkdir tfa
    file mkdir tfad
    set s [createfile tfad/tfa]
    set r1 [catch {file rename tfa tfad}]
    set r2 [checkcontent tfad/tfa $s]
    set r3 [file isdir tfad]
    set r4 [file isdir tfa]
    set result [expr $r1 && $r2 && $r3 && $r4 ]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-12.6 {renamefile: TclRenameFile succeeding } {
    catch {file delete -force -- tfa1 tfa2}
    set s [createfile tfa1]
    file rename tfa1 tfa2
    set result [expr [checkcontent tfa2 $s] && ![file exists tfa1]]
    file delete tfa2
    set result
} {1}

test fCmd-12.7 {renamefile: renaming directory into offspring} {
    catch {file delete -force -- tfad}
    file mkdir tfad
    file mkdir tfad/dir
    set result [catch {file rename tfad tfad/dir}]
    file delete -force tfad 
    set result
} {1}

test fCmd-12.8 {renamefile: generic error } {unixOnly} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    file mkdir tfa/dir
    exec chmod 555 tfa
    set result [catch {file rename tfa/dir tfa2}]
    exec chmod 777 tfa
    file delete -force tfa
    set result
} {1}


test fCmd-12.9 {renamefile: moving a file across volumes } {unixOnly} {
    catch {file delete -force -- tfa /tmp/tfa}
    set s [createfile tfa ]
    file rename tfa /tmp
    set result [expr [checkcontent /tmp/tfa $s] && ![file exists tfa]]
    file delete /tmp/tfa
    set result
} {1}

test fCmd-12.10 {renamefile: moving a directory across volumes } {unixOnly} {

    catch {file delete -force -- tfad /tmp/tfad}
    file mkdir tfad
    set s [createfile tfad/a ]
    file rename tfad /tmp
    set restul [expr [checkcontent /tmp/tfad/a $s] && ![file exists tfad]]
    file delete -force /tmp/tfad
    set result
} {1}

#
# Coverage tests for TclCopyFilesCmd()
#
test fCmd-13.1 {TclCopyFilesCmd: -force option } {
    catch {file delete -force -- tfa1}
    set s [createfile tfa1]
    file copy -force  tfa1 tfa2
    set result [expr [checkcontent tfa2 $s] && [checkcontent tfa1 $s]]
    file delete tfa1 tfa2
    set result
} {1}

test fCmd-13.2 {TclCopyFilesCmd: -- option } {
    catch {file delete -force -- tfa1}
    set s [createfile -tfa1]
    file copy --  -tfa1 tfa2
    set result [expr [checkcontent tfa2 $s] &&  [checkcontent -tfa1 $s]]
    file delete -- -tfa1 tfa2
    set result
} {1}

test fCmd-13.3 {TclCopyFilesCmd: bad option } {
    catch {file delete -force -- tfa1}
    set s [createfile tfa1]
    set r1 [catch {file copy -x tfa1 tfa2}]
    set result [expr $r1 && [checkcontent tfa1 $s] && ![file exists tfa2]]
    file delete tfa1
    set result
} {1}

test fCmd-13.4 {TclCopyFilesCmd: bad \# args} {
    catch {file copy -- }
} {1}

test fCmd-13.5 {TclCopyFilesCmd: target filename translation failing} {
     global env
     set temp $env(HOME)
    unset env(HOME)
     set result [catch {file copy tfa ~/foobar }]
     set env(HOME) $temp
     set result
 } {1}

test fCmd-13.6 {TclCopyFilesCmd: more than one source and target is not a directory} {
    catch {file delete -force -- tfa1 tfa2 tfa3}
    createfile tfa1 
    createfile tfa2 
    createfile tfa3 
    set result [catch {file copy tfa1 tfa2 tfa3}]
    file delete tfa1 tfa2 tfa3
    set result
} {1}

test fCmd-13.7 {TclCopyFilesCmd: : single file into directory  } {
    catch {file delete -force -- tfa1 tfad}
    set s [createfile tfa1]
    file mkdir tfad
    file copy tfa1 tfad
    set result [expr [checkcontent tfad/tfa1 $s] &&  [checkcontent tfa1 $s]]
    file delete -force tfad tfa1
    set result
} {1}

test fCmd-13.8 {TclCopyFilesCmd: : multiple files into directory  } {
    catch {file delete -force -- tfa1 tfa2 tfad}
    set s1 [createfile tfa1 ]
    set s2 [createfile tfa2 ]
    file mkdir tfad
    file copy tfa1 tfa2 tfad
    set r1 [checkcontent tfad/tfa1 $s1]
    set r2 [checkcontent tfad/tfa2 $s2]
    set r3 [checkcontent tfa1 $s1]
    set r4 [checkcontent tfa2 $s2]
    set result [expr $r1 && $r2 && $r3 && $r4 ]
	    
    file delete -force tfad tfa1 tfa2
    set result
} {1}

test fCmd-13.9 {TclCopyFilesCmd: error copying file to directory } {
    catch {file delete -force -- tfa tfad}
    set s [createfile tfa ]
    file mkdir tfad
    file mkdir tfad/tfa
    set r1 [catch {file copy tfa tfad}]
    set r2 [expr [checkcontent tfa $s] && [file isdir tfad/tfa]]
    set r3 [file isdir tfad]
    set result [expr $r1 && $r2 && $r3 ]
    file delete -force tfa tfad
    set result
} {1}

#
# Coverage tests for copyfile()
# 
test fCmd-14.1 {copyfile: source filename translation failing} {
    global env
    set temp $env(HOME)
    unset env(HOME)
    set result [catch {file copy ~/tfa1 tfa2}]
    set env(HOME) $temp
    set result
} {1}

test fCmd-14.2 {copyfile: dst filename translation failing} {
    global env
    set temp $env(HOME)
    unset env(HOME)
    set s [createfile tfa1]
    file mkdir tfad
    set r1 [catch {file copy tfa1 ~/tfa2 tfad}]
    set result [expr $r1 && [checkcontent tfad/tfa1 $s]]
    set env(HOME) $temp
    file delete -force tfa1 tfad
    set result
} {1}

test fCmd-14.3 {copyfile: stat failing on source} {
    catch {file delete -force -- tfa1 tfa2}
    set r1 [catch {file copy tfa1 tfa2}]
    expr $r1 && ![file exists tfa1] && ![file exists tfa2]
} {1}

test fCmd-14.4 {copyfile: error copying file to directory } {
    catch {file delete -force -- tfa tfad}
    set s1 [createfile tfa ]
    file mkdir tfad
    file mkdir tfad/tfa
    set r1 [catch {file copy tfa tfad}]
    set r2 [checkcontent tfa $s1]
    set r3 [file isdir tfad]
    set r4 [file isdir tfad/tfa]
    set result [expr $r1 && $r2 && $r3 && $r4 ]
    file delete -force tfa tfad
    set result
} {1}

 test fCmd-14.5 {copyfile: error copying directory to file } {
     catch {file delete -force -- tfa tfad}
     file mkdir tfa
     file mkdir tfad
     set s [createfile tfad/tfa]
     set r1 [catch {file copy tfa tfad}]
     set r2 [checkcontent tfad/tfa $s]
     set r3 [file isdir tfad]
     set r4 [file isdir tfa]
     set result [expr $r1 && $r2 && $r3 && $r4 ]
     file delete -force tfa tfad
     set result
} {1}

test fCmd-14.6 {copyfile: copy file succeeding } {
    catch {file delete -force -- tfa tfa2}
    set s [createfile tfa]
    file copy tfa tfa2
    set result [expr  [checkcontent tfa $s] && [checkcontent tfa2 $s]]
    file delete tfa tfa2
    set result
} {1}

test fCmd-14.7 {copyfile: copy directory succeeding } {
    catch {file delete -force -- tfa tfa2}
    file mkdir tfa
    set s [createfile tfa/file]
    file copy tfa tfa2
    set result [expr [checkcontent tfa/file $s] && [checkcontent tfa2/file $s]]
    file delete -force tfa tfa2
    set result
} {1}

test fCmd-14.8 {copyfile: copy directory failing } {unixOnly} {
    catch {file delete -force -- tfa}
    file mkdir tfa/dir/a/b/c
    exec chmod 000 tfa/dir
    set r1 [catch {file copy tfa tfa2}]
    exec chmod 777 tfa/dir
    set result $r1
    file delete -force tfa tfa2
    set result
} {1}

#
# Coverage tests for TclMkdirCmd()
#
test fCmd-15.1 {TclMakeDirsCmd: target filename translation failing} {
    global env
    set temp $env(HOME)
    unset env(HOME) 
    set result [catch {file mkdir ~/tfa}]
    set env(HOME) $temp
    set result
} {1}
#
# Can Tcl_SplitPath return argc == 0? If so them we need a
# test for that code.
#
test fCmd-15.2 {TclMakeDirsCmd - one directory } {
    catch {file delete -force -- tfa}
    file mkdir tfa
    set result [file isdirectory tfa]
    file delete tfa
    set result
} {1}

test fCmd-15.3 {TclMakeDirsCmd: - two directories } {
    catch {file delete -force -- tfa1 tfa2}
    file mkdir tfa1 tfa2
    set result [expr [file isdirectory tfa1] && [file isdirectory tfa2]]
    file delete tfa1 tfa2
    set result
} {1}

test fCmd-15.4 {TclMakeDirsCmd - stat failing } {unixOnly} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    createfile tfa/file
    exec chmod 000 tfa
    set result [catch {file mkdir tfa/file}]
    exec chmod 777 tfa
    file delete -force tfa
    set result
} {1}

test fCmd-15.5 {TclMakeDirsCmd: - making a directory several levels deep } {

    catch {file delete -force -- tfa}
    file mkdir tfa/a/b/c
    set result [file isdir tfa/a/b/c]
    file delete -force tfa
    set result
} {1}

    
test fCmd-15.6 {TclMakeDirsCmd: - trying to overwrite a file } {
    catch {file delete -force -- tfa}
    set s [createfile tfa]
    set r1 [catch {file mkdir tfa}]
    set r2 [file isdir tfa]
    set r3 [file exists tfa]
    set result [expr $r1 && !$r2 && $r3 && [checkcontent tfa $s]]
    file delete tfa
    set result
} {1}

test fCmd-15.7 {TclMakeDirsCmd - making several directories } {
    catch {file delete -force -- tfa1 tfa2}
    file mkdir tfa1 tfa2/a/b/c
    set result [expr [file isdir tfa1] && [file isdir tfa2/a/b/c]]
    file delete -force tfa1 tfa2
    set result
} {1}

test fCmd-15.8 {TclFileMakeDirsCmd: trying to create an existing dir} {
    file mkdir tfa
    file mkdir tfa
    set result [file isdir tfa]
    file delete tfa
    set result
} {1}


# Coverage tests for TclDeleteFilesCommand()
test fCmd-16.1 { test the -- argument } {
    catch {file delete -force -- tfa}
    createfile tfa
    file delete -- tfa
    file exists tfa
} {0}

test fCmd-16.2 { test the -force and -- arguments } {
    catch {file delete -force -- tfa}
    createfile tfa
    file delete -force -- tfa
    file exists tfa
} {0}

test fCmd-16.3 { test bad option } {
    catch {file delete -force -- tfa}
    createfile tfa
    set result [catch {file delete -dog tfa}]
    file delete tfa
    set result
} {1}

test fCmd-16.4 { test not enough args } {
    catch {file delete}
} {1}

test fCmd-16.5 { test not enough args with options } {
    catch {file delete --}
} {1}

test fCmd-16.6 {delete: source filename translation failing} {
    global env
    set temp $env(HOME)
    unset env(HOME)
    set result [catch {file delete ~/tfa}]
    set env(HOME) $temp
    set result
} {1}

test fCmd-16.7 {remove a non-empty directory without -force } {
    catch {file delete -force -- tfa}
    file mkdir tfa
    createfile tfa/a
    set result [catch  {file delete tfa }]
    file delete -force tfa
    set result
} {1}

test fCmd-16.8 {remove a normal file } {
    catch {file delete -force -- tfa}
    file mkdir tfa
    createfile tfa/a
    set result [catch  {file delete tfa }]
    file delete -force tfa
    set result
} {1}

test fCmd-16.9 {error while deleting file } {unixOnly} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    createfile tfa/a
    exec chmod 555 tfa
    set result [catch  {file delete tfa/a }]
    #######
    #######  If any directory in a tree that is being removed does not 
    #######  have write permission, the process will fail!
    #######  This is also the case with "rm -rf"
    #######
    exec chmod 777 tfa
    file delete -force tfa
    set result
} {1}

test fCmd-16.10 {deleting multiple files } {
    catch {file delete -force -- tfa1 tfa2}
    createfile tfa1
    createfile tfa2
    file delete tfa1 tfa2
    expr ![file exists tfa1] && ![file exists tfa2]
} {1}

test fCmd-16.11 { TclFileDeleteCmd: removing a nonexistant file} {
    catch {file delete -force -- tfa}
    file delete tfa
    set result 1
} {1}

# More coverage tests for mkpath()
 test fCmd-17.1 {mkdir stat failing on target but not ENOENT } {unixOnly} {
     catch {file delete -force -- tfa1}
     file mkdir tfa1
     exec chmod 555 tfa1
     set result [catch {file mkdir tfa1/tfa2}]
     exec chmod 777 tfa1
     file delete -force tfa1
     set result
} {1}

test fCmd-17.2 {mkdir several levels deep - relative } {
    catch {file delete -force -- tfa}
    file mkdir tfa/a/b
    set result [file isdir tfa/a/b ]
    file delete tfa/a/b tfa/a tfa
    set result
} {1}

test fCmd-17.3 {mkdir several levels deep - absolute } {
    catch {file delete -force -- tfa}
    set f [file join [pwd] tfa a ]
    file mkdir $f
    set result [file isdir $f ]
    file delete $f [file join [pwd] tfa]
    set result
} {1}

#
# Functionality tests for TclFileRenameCmd()
#

test fCmd-18.1 {TclFileRenameCmd: rename (first form) in the same directory} {

    catch {file delete -force -- tfad}
    file mkdir tfad/dir
    cd tfad/dir
    set s [createfile foo ]
    file rename  foo bar
    file rename bar ./foo
    file rename ./foo bar
    file rename ./bar ./foo
    file rename foo ../dir/bar
    file rename ../dir/bar ./foo
    file rename ../../tfad/dir/foo ../../tfad/dir/bar
    file rename [file join [pwd] bar] foo
    file rename foo [file join [pwd] bar]
    set result [expr [checkcontent bar $s] && ![file exists foo]]
    cd ../..
    file delete -force tfad
    set result
} {1}

test fCmd-18.2 {TclFileRenameCmd: single dir to nonexistant } {
    catch {file delete -force -- tfa1 tfa2}
    file mkdir tfa1
    file rename tfa1 tfa2
    set result [expr [file exists tfa2] && ![file exists tfa1]]
    file delete tfa2
    set result
} {1}

test fCmd-18.3 {TclFileRenameCmd: mixed dirs and files into directory  } {
    catch {file delete -force -- tfa1 tfad1 tfad2}
    set s [createfile tfa1 ]
    file mkdir tfad1 tfad2
    file rename tfa1 tfad1 tfad2
    set r1 [checkcontent  tfad2/tfa1 $s]
    set r2 [file isdir tfad2/tfad1]
    set result [expr $r1 && $r2 && ![file exists tfa1] && ![file exists tfad1]]
    file delete tfad2/tfa1
    file delete -force tfad2
    set result
} {1}

test fCmd-18.4 {TclFileRenameCmd: attempt to replace non-dir with dir } {
    catch {file delete -force -- tfa tfad}
    set s [createfile tfa ]
    file mkdir tfad
    set r1 [catch {file rename tfad tfa}]
    set r2 [checkcontent tfa $s]
    set r3 [file isdir tfad]
    set result [expr $r1 && $r2 && $r3 ]
    file delete tfa tfad
    set result
} {1}

test fCmd-18.5 {TclFileRenameCmd: attempt to replace dir with non-dir } {
    catch {file delete -force -- tfa tfad}
    set s [createfile tfa ]
    file mkdir tfad/tfa
    set r1 [catch {file rename tfa tfad}]
    set r2 [checkcontent tfa $s]
    set r3 [file isdir tfad/tfa]
    set result [expr $r1 && $r2 && $r3 ]
    file delete -force  tfa tfad
    set result
} {1}

#
# On Windows there is no easy way to determine if two files are the same
#
test fCmd-18.6 {TclFileRenameCmd: rename a file to itself} {macOrUnix}  {
    catch {file delete -force -- tfa}
    set s [createfile tfa]
    set r1 [catch {file rename tfa tfa}]
    set result [expr $r1 && [checkcontent tfa $s]]
    file delete tfa
    set result
} {1}

test fCmd-18.7 {TclFileRenameCmd: rename dir on top of another empty dir w/o -force} {

    catch {file delete -force -- tfa tfad}
    file mkdir tfa tfad/tfa
    set r1 [catch {file rename tfa tfad}]
    set result [expr $r1 && [file isdir tfa]]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-18.8 {TclFileRenameCmd: rename dir on top of another empty dir w/ -force} {

    catch {file delete -force -- tfa tfad}
    file mkdir tfa tfad/tfa
    file rename -force tfa tfad
    set result [expr ![file isdir tfa]]
    file delete -force tfad
    set result
} {1}

test fCmd-18.9 {TclFileRenameCmd: rename dir on top of a non-empty dir w/o -force} {

    catch {file delete -force -- tfa tfad}
    file mkdir tfa tfad/tfa/file
    set r1 [catch {file rename tfa tfad}]
    set result [expr $r1 && [file isdir tfa] && [file isdir tfad/tfa/file]]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-18.10 {TclFileRenameCmd: rename dir on top of a non-empty dir w/ -force} {

    catch {file delete -force -- tfa tfad}
    file mkdir tfa tfad/tfa/file
    set r1 [catch {file rename -force tfa tfad}]
    set result [expr $r1 && [file isdir tfa] && [file isdir tfad/tfa/file]]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-18.11 {TclFileRenameCmd: rename a non-existant file} {
    catch {file delete -force -- tfa1}
    set r1 [catch {file rename tfa1 tfa2}]
    set result [expr $r1 && ![file exists tfa1] && ![file exists tfa2]]
} {1}

test fCmd-18.12 {TclFileRenameCmd : rename a symbolic link to file} {unixOnly} {

    catch {file delete -force -- tfa1 tfa2 tfa3}
	
    set s [createfile tfa1]
    exec ln -s tfa1 tfa2
    file rename tfa2 tfa3
    set t [file type tfa3]
    set result [expr { $t == "link" }]
    file delete tfa1 tfa3
    set result
} {1}

test fCmd-18.13 {TclFileRenameCmd : rename a symbolic link to dir} {unixOnly} {

    catch {file delete -force -- tfa1 tfa2 tfa3}
	
    file mkdir tfa1
    exec ln -s tfa1 tfa2
    file rename tfa2 tfa3
    set t [file type tfa3]
    set result [expr { $t == "link" }]
    file delete tfa1 tfa3
    set result
} {1}

test fCmd-18.14 {TclFileRenameCmd : rename a path with sym link} {unixOnly} {

    catch {file delete -force -- tfa1 tfa2 tfa3}
	
    file mkdir tfa1/a/b/c/d
    file mkdir tfa2
    set f [file join [pwd] tfa1/a/b] 
    set f2 [file join [pwd] {tfa2/b alias}]
    exec ln -s $f $f2
    file rename {tfa2/b alias/c} tfa3
    set r1 [file isdir tfa3]
    set r2 [file exists tfa1/a/b/c]
    set result [expr $r1 && !$r2]
    file delete -force tfa1 tfa2 tfa3
    set result
} {1}

test fCmd-18.15 {TclFileRenameCmd : rename a file to a symlink dir} {unixOnly} {

    catch {file delete -force -- tfa1 tfa2 tfalink}
	
    file mkdir tfa1
    set s [createfile tfa2]
    exec ln -s tfa1 tfalink

    file rename tfa2 tfalink
    set result [checkcontent tfa1/tfa2 $s ]
    file delete -force tfa1 tfalink
    set result
} {1}

test fCmd-18.16 {TclFileRenameCmd : rename a dangling symlink} {unixOnly} {
    catch {file delete -force -- tfa1 tfalink}
	
    file mkdir tfa1
    exec ln -s tfa1 tfalink
    file delete tfa1 
    file rename tfalink tfa2
    set result [expr [string compare [file type tfa2] "link"] == 0]
    file delete tfa2
    set result
} {1}


#
# Coverage tests for TclUnixRmdir
#
test fCmd-19.1 { remove empty directory } {
    catch {file delete -force -- tfa}
    file mkdir tfa
    file delete tfa
    file exists tfa
} {0}

test fCmd-19.2 { rmdir error besides EEXIST} {unixOnly} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    file mkdir tfa/a
    exec chmod 555 tfa
    set result [catch {file delete tfa/a}]
    exec chmod 777 tfa
    file delete -force tfa
    set result
} {1}

test fCmd-19.3 { recursive remove } {
    catch {file delete -force -- tfa}
    file mkdir tfa
    file mkdir tfa/a
    file delete -force tfa
    file exists tfa
} {0}

#
# TclUnixDeleteFile and TraversalDelete are covered by tests from the 
# TclDeleteFilesCmd suite
#
#

#
# Coverage tests for TraverseUnixTree(), called from TclDeleteFilesCmd
#

test fCmd-20.1 {TraverseUnixTree : failure opening a subdirectory directory } {unixOnly} {

    catch {file delete -force -- tfa}
    file mkdir tfa
    file mkdir tfa/a
    exec chmod 000 tfa/a
    set result [catch {file delete -force tfa}]
    exec chmod 777 tfa/a
    file delete -force tfa
    set result
} {1}


#
# Feature testing for TclCopyFilesCmd
# 
test fCmd-21.1 {copy : single file to nonexistant } {
    catch {file delete -force -- tfa1 tfa2}
    set s [createfile tfa1]
    file copy tfa1 tfa2
    set result [expr [checkcontent tfa2 $s] && [checkcontent tfa1 $s]]
    file delete tfa1 tfa2
    set result
} {1}

test fCmd-21.2 {copy : single dir to nonexistant } {
    catch {file delete -force -- tfa1 tfa2}
    file mkdir tfa1
    file copy tfa1 tfa2
    set result [expr [file isdir tfa2] && [file isdir tfa1]]
    file delete tfa1 tfa2
    set result
} {1}

test fCmd-21.3 {copy : single file into directory  } {
    catch {file delete -force -- tfa1 tfad}
    set s [createfile tfa1]
    file mkdir tfad
    file copy tfa1 tfad
    set result [expr [checkcontent tfad/tfa1 $s] && [checkcontent tfa1 $s]]
    file delete -force tfa1 tfad
    set result
} {1}

test fCmd-21.4 {copy : more than one source and target is not a directory} {

    catch {file delete -force -- tfa1 tfa2 tfa3}
    createfile tfa1 
    createfile tfa2 
    createfile tfa3 
    set result [catch {file copy tfa1 tfa2 tfa3}]
    file delete tfa1 tfa2 tfa3
    set result
} {1}

test fCmd-21.5 {copy : multiple files into directory  } {
    catch {file delete -force -- tfa1 tfa2 tfad}
    set s1 [createfile tfa1 ]
    set s2 [createfile tfa2 ]
    file mkdir tfad
    file copy tfa1 tfa2 tfad
    set r1 [checkcontent tfad/tfa1 $s1]
    set r2 [checkcontent tfad/tfa2 $s2]
    set r3 [checkcontent tfa1 $s1]
    set r4 [checkcontent tfa2 $s2]
    set result [expr $r1 && $r2 && $r3 && $r4]
    file delete -force tfa1 tfa2 tfad
    set result
} {1}

test fCmd-21.6 {copy : mixed dirs and files into directory  } {notFileSharing} {

    catch {file delete -force -- tfa1 tfad1 tfad2}
    set s [createfile tfa1 ]
    file mkdir tfad1 tfad2
    file copy tfa1 tfad1 tfad2
    set r1 [checkcontent [file join tfad2 tfa1] $s]
    set r2 [file isdir [file join tfad2 tfad1]]
    set r3 [checkcontent tfa1 $s]
    set result [expr $r1 && $r2 && $r3 && [file isdir tfad1]]
    file delete -force tfa1 tfad1 tfad2
    set result
} {1}

test fCmd-21.7 {TclCopyFilesCmd : copy a dangling link } {unixOnly} {
    file mkdir tfad1
    exec ln -s tfad1 tfalink
    file delete tfad1
    file copy tfalink tfalink2
    set result [string match [file type tfalink2] link]
    file delete tfalink tfalink2 
    set result
} {1}

test fCmd-21.8 {TclCopyFilesCmd : copy a link } {unixOnly} {
    file mkdir tfad1
    exec ln -s tfad1 tfalink
    file copy tfalink tfalink2
    set r1 [file type tfalink]
    set r2 [file type tfalink2]
    set r3 [file isdir tfad1]
    set result [expr {("$r1" == "link" ) && ("$r2" == "link" ) && $r3}]
    file delete tfad1 tfalink tfalink2
    set result
} {1}

test fCmd-21.9 {TclCopyFilesCmd : copy dir with a link in it } {unixOnly} {
    file mkdir tfad1
    exec ln -s "[pwd]/tfad1" tfad1/tfalink
    file copy tfad1 tfad2
    set result [string match [file type tfad2/tfalink] link]
    file delete -force tfad1 tfad2
    set result
} {1}

test fCmd-21.10 {TclFileCopyCmd: copy dir on top of another empty dir w/o -force} {

    catch {file delete -force -- tfa tfad}
    file mkdir tfa [file join tfad tfa]
    set r1 [catch {file copy tfa tfad}]
    set result [expr $r1 && [file isdir tfa]]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-21.11 {TclFileCopyCmd: copy dir on top of a dir w/o -force} {
    catch {file delete -force -- tfa tfad}
    file mkdir tfa [file join tfad tfa file]
    set r1 [catch {file copy tfa tfad}]
    set result [expr $r1 && [file isdir tfa] && [file isdir [file join tfad tfa file]]]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-21.12 {TclFileCopyCmd: copy dir on top of a non-empty dir w/ -force} {

    catch {file delete -force -- tfa tfad}
    file mkdir tfa [file join tfad tfa file]
    set r1 [catch {file copy -force tfa tfad}]
    set result [expr $r1 && [file isdir tfa] && [file isdir [file join tfad tfa file]]]
    file delete -force tfa tfad
    set result
} {1}
   
#
# Coverage testing for TclpRenameFile
#
test fCmd-22.1 { TclpRenameFile : rename and overwrite in a single dir } {
    catch {file delete -force -- tfa1 tfa2}
    set s [createfile tfa1]
    set s2 [createfile tfa2 q]
	
    set r1 [catch {rename tfa1 tfa2}]
    file rename -force tfa1 tfa2
    set result [expr $r1 && [checkcontent tfa2 $s]]
    file delete [glob tfa1 tfa2]
    set result
} {1}

test fCmd-22.2 { TclpRenameFile : attempt to overwrite itself } {macOrUnix} {
    catch {file delete -force -- tfa1}
    set s [createfile tfa1]	
    file rename -force tfa1 tfa1
    set result [checkcontent tfa1 $s]
    file delete tfa1 
    set result
} {1}

test fCmd-22.3 { TclpRenameFile : rename dir to existing dir } {
    catch {file delete -force -- d1 tfad}
    file mkdir d1 [file join tfad d1]
    set r1 [catch {file rename d1 tfad}]
    set result [expr $r1 && [file isdir d1] && [file isdir [file join tfad d1]]]
    file delete -force d1 tfad
    set result
} {1}

test fCmd-22.4 { TclpRenameFile : rename dir to dir several levels deep } {
    catch {file delete -force -- d1 tfad}
    file mkdir d1 [file join tfad a b c]
    file rename d1 [file join tfad a b c d1]
    set result [expr ![file isdir d1] && [file isdir [file join tfad a b c d1]]]
    file delete -force [glob d1 tfad]
    set result
} {1}


#
# TclMacCopyFile needs to be redone.
#
test fCmd-22.5 { TclMacCopyFile : copy and overwrite in a single dir } {
    catch {file delete -force -- tfa1 tfa2}
    set s [createfile tfa1]
    set s2 [createfile tfa2 q]

    set r1 [catch {file copy tfa1 tfa2}]
    file copy -force tfa1 tfa2
    set result [expr $r1 && [checkcontent tfa2 $s] && [checkcontent tfa1 $s]]







|
>










|










|
>










|
>





|
>









|








|












|








|









|









|














|















|








|











|





|












|













|








|








|











|








|
>












|








|








|








|












|









|









|















|















|








|












|





|













|













|








|









|













|











|







|







|










|
>








|










|







|









|






|






|







|



|



|








|








|








|















|







|






|









|







|












|
>



















|








|












|











|














|








|
>








|
>








|
>








|
>








|





|
>











|
>











|
>















|
>












|















|






|










|

















|
>














|








|








|









|
>









|














|
>












|









|











|








|
>








|








|
>











|











|








|








|












|







924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
    set a1 [list [catch {file copy td1 td2} msg] $msg]
    set a2 [list [catch {file copy -force tds1 tdd1} msg] $msg]
    set a3 [catch {file copy -force tds2 tdd2}]
    set a4 [catch {file copy -force tds3 tdd3}]
    set a5 [catch {file copy -force tds4 tdd4}]
    list [lsort [glob td*]] $a1 $a2 $a3 $a4 $a5 
} [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4 tds1 tds2 tds3 tds4} {1 {error copying "td1" to "[file join td2 td1]": file already exists}} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} 1 1 1}]
test fCmd-10.6 {file copy: comprehensive: dir to non-empty dir} \
	{notRoot unixOrPc} {
    cleanup
    file mkdir tds1
    file mkdir tds2
    file mkdir [file join tdd1 tds1 xxx]
    file mkdir [file join tdd2 tds2 xxx]
    testchmod 555 tds2
    set a1 [list [catch {file copy -force tds1 tdd1} msg] $msg]
    set a2 [list [catch {file copy -force tds2 tdd2} msg] $msg]
    list [lsort [glob td*]] $a1 $a2 [file writable tds1] [file writable tds2]
} [subst {{tdd1 tdd2 tds1 tds2} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} {1 {error copying "tds2" to "[file join tdd2 tds2]": file already exists}} 1 0}]
test fCmd-10.7 {file rename: comprehensive: file to new name and dir} {notRoot} {
    cleanup
    createfile tf1
    createfile tf2
    file mkdir td1
    testchmod 444 tf2
    file copy tf1 [file join td1 tf3]
    file copy tf2 [file join td1 tf4]
    list [lsort [glob tf*]] [lsort [glob [file join td1 t*]]] \
    [file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
} [subst {{tf1 tf2} {[file join td1 tf3] [file join td1 tf4]} 1 0}]
test fCmd-10.8 {file rename: comprehensive: dir to new name and dir} \
	{notRoot unixOrPc} {
    cleanup
    file mkdir td1
    file mkdir td2
    file mkdir td3
    testchmod 555 td2
    file copy td1 [file join td3 td3]
    file copy td2 [file join td3 td4]
    list [lsort [glob td*]] [lsort [glob [file join td3 t*]]] \
    [file writable [file join td3 td3]] [file writable [file join td3 td4]]
} [subst {{td1 td2 td3} {[file join td3 td3] [file join td3 td4]} 1 0}]
test fCmd-10.9 {file copy: comprehensive: source and target incompatible} \
	{notRoot} {
    cleanup
    file mkdir td1
    createfile tf1
    list [catch {file copy -force td1 tf1} msg] $msg
} {1 {can't overwrite file "tf1" with directory "td1"}}
test fCmd-10.10 {file copy: comprehensive: source and target incompatible} \
	{notRoot} {
    cleanup
    file mkdir [file join td1 tf1]
    createfile tf1
    list [catch {file copy -force tf1 td1} msg] $msg
} [subst {1 {can't overwrite directory "[file join td1 tf1]" with file "tf1"}}]
cleanup    

# old tests    

test fCmd-11.1 {TclFileRenameCmd: -- option } {notRoot} {
    catch {file delete -force -- -tfa1}
    set s [createfile -tfa1]
    file rename -- -tfa1 tfa2
    set result [expr [checkcontent tfa2 $s] && ![file exists -tfa1]]
    file delete tfa2
    set result
} {1}

test fCmd-11.2 {TclFileRenameCmd: bad option } {notRoot} {
    catch {file delete -force -- tfa1}
    set s [createfile tfa1]
    set r1 [catch {file rename -x tfa1 tfa2}]
    set result [expr $r1 && [checkcontent tfa1 $s] && ![file exists tfa2]]
    file delete tfa1
    set result
} {1}

test fCmd-11.3 {TclFileRenameCmd: bad \# args} {
    catch {file rename -- }
} {1}

test fCmd-11.4 {TclFileRenameCmd: target filename translation failing} {notRoot} {
     global env
     set temp $env(HOME)
     unset env(HOME)
     set result [catch {file rename tfa ~/foobar }]
     set env(HOME) $temp
     set result
 } {1}

test fCmd-11.5 {TclFileRenameCmd: > 1 source & target is not a dir} {notRoot} {
    catch {file delete -force -- tfa1 tfa2 tfa3}
    createfile tfa1 
    createfile tfa2 
    createfile tfa3 
    set result [catch {file rename tfa1 tfa2 tfa3}]
    file delete tfa1 tfa2 tfa3
    set result
} {1}

test fCmd-11.6 {TclFileRenameCmd: : single file into directory} {notRoot} {
    catch {file delete -force -- tfa1 tfad}
    set s [createfile tfa1]
    file mkdir tfad
    file rename tfa1 tfad
    set result [expr [checkcontent tfad/tfa1 $s] && ![file exists tfa1]]
    file delete -force tfad
    set result
} {1}

test fCmd-11.7 {TclFileRenameCmd: : multiple files into directory} {notRoot} {
    catch {file delete -force -- tfa1 tfa2 tfad}
    set s1 [createfile tfa1 ]
    set s2 [createfile tfa2 ]
    file mkdir tfad
    file rename tfa1 tfa2 tfad
    set r1 [checkcontent tfad/tfa1 $s1]
    set r2 [checkcontent tfad/tfa2 $s2]
    
    set result [expr $r1 && $r2 && ![file exists tfa1] && ![file exists tfa2]]
	    
    file delete -force tfad
    set result
} {1}

test fCmd-11.8 {TclFileRenameCmd: error renaming file to directory} {notRoot} {
    catch {file delete -force -- tfa tfad}
    set s [createfile tfa ]
    file mkdir tfad
    file mkdir tfad/tfa
    set r1 [catch {file rename tfa tfad}]
    set r2 [checkcontent tfa $s]
    set r3 [file isdir tfad]
    set result [expr $r1 && $r2 && $r3 ]
    file delete -force tfa tfad
    set result
} {1}

#
# Coverage tests for renamefile() ;
#
test fCmd-12.1 {renamefile: source filename translation failing} {notRoot} {
    global env
    set temp $env(HOME)
    unset env(HOME)
    set result [catch {file rename ~/tfa1 tfa2}]
    set env(HOME) $temp
    set result
} {1}

test fCmd-12.2 {renamefile: src filename translation failing} {notRoot} {
    global env
    set temp $env(HOME)
    unset env(HOME)
    set s [createfile tfa1]
    file mkdir tfad
    set result [catch {file rename tfa1 ~/tfa2 tfad}]
    set env(HOME) $temp
    file delete -force tfad
    set result
} {1}

test fCmd-12.3 {renamefile: stat failing on source} {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    set r1 [catch {file rename tfa1 tfa2}]
    expr {$r1 && ![file exists tfa1] && ![file exists tfa2]}
} {1}

test fCmd-12.4 {renamefile: error renaming file to directory} {notRoot} {
    catch {file delete -force -- tfa tfad}
    set s1 [createfile tfa ]
    file mkdir tfad
    file mkdir tfad/tfa
    set r1 [catch {file rename tfa tfad}]
    set r2 [checkcontent tfa $s1]
    set r3 [file isdir tfad/tfa]
    set result [expr $r1 && $r2 && $r3]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-12.5 {renamefile: error renaming directory to file} {notRoot} {
    catch {file delete -force -- tfa tfad}
    file mkdir tfa
    file mkdir tfad
    set s [createfile tfad/tfa]
    set r1 [catch {file rename tfa tfad}]
    set r2 [checkcontent tfad/tfa $s]
    set r3 [file isdir tfad]
    set r4 [file isdir tfa]
    set result [expr $r1 && $r2 && $r3 && $r4 ]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-12.6 {renamefile: TclRenameFile succeeding} {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    set s [createfile tfa1]
    file rename tfa1 tfa2
    set result [expr [checkcontent tfa2 $s] && ![file exists tfa1]]
    file delete tfa2
    set result
} {1}

test fCmd-12.7 {renamefile: renaming directory into offspring} {notRoot} {
    catch {file delete -force -- tfad}
    file mkdir tfad
    file mkdir tfad/dir
    set result [catch {file rename tfad tfad/dir}]
    file delete -force tfad 
    set result
} {1}

test fCmd-12.8 {renamefile: generic error} {unixOnly notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    file mkdir tfa/dir
    exec chmod 555 tfa
    set result [catch {file rename tfa/dir tfa2}]
    exec chmod 777 tfa
    file delete -force tfa
    set result
} {1}


test fCmd-12.9 {renamefile: moving a file across volumes} {unixOnly notRoot} {
    catch {file delete -force -- tfa /tmp/tfa}
    set s [createfile tfa ]
    file rename tfa /tmp
    set result [expr [checkcontent /tmp/tfa $s] && ![file exists tfa]]
    file delete /tmp/tfa
    set result
} {1}

test fCmd-12.10 {renamefile: moving a directory across volumes } \
	{unixOnly notRoot} {
    catch {file delete -force -- tfad /tmp/tfad}
    file mkdir tfad
    set s [createfile tfad/a ]
    file rename tfad /tmp
    set restul [expr [checkcontent /tmp/tfad/a $s] && ![file exists tfad]]
    file delete -force /tmp/tfad
    set result
} {1}

#
# Coverage tests for TclCopyFilesCmd()
#
test fCmd-13.1 {TclCopyFilesCmd: -force option} {notRoot} {
    catch {file delete -force -- tfa1}
    set s [createfile tfa1]
    file copy -force  tfa1 tfa2
    set result [expr [checkcontent tfa2 $s] && [checkcontent tfa1 $s]]
    file delete tfa1 tfa2
    set result
} {1}

test fCmd-13.2 {TclCopyFilesCmd: -- option} {notRoot} {
    catch {file delete -force -- tfa1}
    set s [createfile -tfa1]
    file copy --  -tfa1 tfa2
    set result [expr [checkcontent tfa2 $s] &&  [checkcontent -tfa1 $s]]
    file delete -- -tfa1 tfa2
    set result
} {1}

test fCmd-13.3 {TclCopyFilesCmd: bad option} {notRoot} {
    catch {file delete -force -- tfa1}
    set s [createfile tfa1]
    set r1 [catch {file copy -x tfa1 tfa2}]
    set result [expr $r1 && [checkcontent tfa1 $s] && ![file exists tfa2]]
    file delete tfa1
    set result
} {1}

test fCmd-13.4 {TclCopyFilesCmd: bad \# args} {notRoot} {
    catch {file copy -- }
} {1}

test fCmd-13.5 {TclCopyFilesCmd: target filename translation failing} {
     global env
     set temp $env(HOME)
    unset env(HOME)
     set result [catch {file copy tfa ~/foobar }]
     set env(HOME) $temp
     set result
 } {1}

test fCmd-13.6 {TclCopyFilesCmd: > 1 source & target is not a dir} {notRoot} {
    catch {file delete -force -- tfa1 tfa2 tfa3}
    createfile tfa1 
    createfile tfa2 
    createfile tfa3 
    set result [catch {file copy tfa1 tfa2 tfa3}]
    file delete tfa1 tfa2 tfa3
    set result
} {1}

test fCmd-13.7 {TclCopyFilesCmd: single file into directory} {notRoot} {
    catch {file delete -force -- tfa1 tfad}
    set s [createfile tfa1]
    file mkdir tfad
    file copy tfa1 tfad
    set result [expr [checkcontent tfad/tfa1 $s] &&  [checkcontent tfa1 $s]]
    file delete -force tfad tfa1
    set result
} {1}

test fCmd-13.8 {TclCopyFilesCmd: multiple files into directory} {notRoot} {
    catch {file delete -force -- tfa1 tfa2 tfad}
    set s1 [createfile tfa1 ]
    set s2 [createfile tfa2 ]
    file mkdir tfad
    file copy tfa1 tfa2 tfad
    set r1 [checkcontent tfad/tfa1 $s1]
    set r2 [checkcontent tfad/tfa2 $s2]
    set r3 [checkcontent tfa1 $s1]
    set r4 [checkcontent tfa2 $s2]
    set result [expr $r1 && $r2 && $r3 && $r4 ]
	    
    file delete -force tfad tfa1 tfa2
    set result
} {1}

test fCmd-13.9 {TclCopyFilesCmd: error copying file to directory} {notRoot} {
    catch {file delete -force -- tfa tfad}
    set s [createfile tfa ]
    file mkdir tfad
    file mkdir tfad/tfa
    set r1 [catch {file copy tfa tfad}]
    set r2 [expr [checkcontent tfa $s] && [file isdir tfad/tfa]]
    set r3 [file isdir tfad]
    set result [expr $r1 && $r2 && $r3 ]
    file delete -force tfa tfad
    set result
} {1}

#
# Coverage tests for copyfile()
# 
test fCmd-14.1 {copyfile: source filename translation failing} {notRoot} {
    global env
    set temp $env(HOME)
    unset env(HOME)
    set result [catch {file copy ~/tfa1 tfa2}]
    set env(HOME) $temp
    set result
} {1}

test fCmd-14.2 {copyfile: dst filename translation failing} {notRoot} {
    global env
    set temp $env(HOME)
    unset env(HOME)
    set s [createfile tfa1]
    file mkdir tfad
    set r1 [catch {file copy tfa1 ~/tfa2 tfad}]
    set result [expr $r1 && [checkcontent tfad/tfa1 $s]]
    set env(HOME) $temp
    file delete -force tfa1 tfad
    set result
} {1}

test fCmd-14.3 {copyfile: stat failing on source} {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    set r1 [catch {file copy tfa1 tfa2}]
    expr $r1 && ![file exists tfa1] && ![file exists tfa2]
} {1}

test fCmd-14.4 {copyfile: error copying file to directory} {notRoot} {
    catch {file delete -force -- tfa tfad}
    set s1 [createfile tfa ]
    file mkdir tfad
    file mkdir tfad/tfa
    set r1 [catch {file copy tfa tfad}]
    set r2 [checkcontent tfa $s1]
    set r3 [file isdir tfad]
    set r4 [file isdir tfad/tfa]
    set result [expr $r1 && $r2 && $r3 && $r4 ]
    file delete -force tfa tfad
    set result
} {1}

 test fCmd-14.5 {copyfile: error copying directory to file} {notRoot} {
     catch {file delete -force -- tfa tfad}
     file mkdir tfa
     file mkdir tfad
     set s [createfile tfad/tfa]
     set r1 [catch {file copy tfa tfad}]
     set r2 [checkcontent tfad/tfa $s]
     set r3 [file isdir tfad]
     set r4 [file isdir tfa]
     set result [expr $r1 && $r2 && $r3 && $r4 ]
     file delete -force tfa tfad
     set result
} {1}

test fCmd-14.6 {copyfile: copy file succeeding} {notRoot} {
    catch {file delete -force -- tfa tfa2}
    set s [createfile tfa]
    file copy tfa tfa2
    set result [expr  [checkcontent tfa $s] && [checkcontent tfa2 $s]]
    file delete tfa tfa2
    set result
} {1}

test fCmd-14.7 {copyfile: copy directory succeeding} {notRoot} {
    catch {file delete -force -- tfa tfa2}
    file mkdir tfa
    set s [createfile tfa/file]
    file copy tfa tfa2
    set result [expr [checkcontent tfa/file $s] && [checkcontent tfa2/file $s]]
    file delete -force tfa tfa2
    set result
} {1}

test fCmd-14.8 {copyfile: copy directory failing} {unixOnly notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa/dir/a/b/c
    exec chmod 000 tfa/dir
    set r1 [catch {file copy tfa tfa2}]
    exec chmod 777 tfa/dir
    set result $r1
    file delete -force tfa tfa2
    set result
} {1}

#
# Coverage tests for TclMkdirCmd()
#
test fCmd-15.1 {TclMakeDirsCmd: target filename translation failing} {notRoot} {
    global env
    set temp $env(HOME)
    unset env(HOME) 
    set result [catch {file mkdir ~/tfa}]
    set env(HOME) $temp
    set result
} {1}
#
# Can Tcl_SplitPath return argc == 0? If so them we need a
# test for that code.
#
test fCmd-15.2 {TclMakeDirsCmd - one directory } {notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    set result [file isdirectory tfa]
    file delete tfa
    set result
} {1}

test fCmd-15.3 {TclMakeDirsCmd: - two directories} {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    file mkdir tfa1 tfa2
    set result [expr [file isdirectory tfa1] && [file isdirectory tfa2]]
    file delete tfa1 tfa2
    set result
} {1}

test fCmd-15.4 {TclMakeDirsCmd - stat failing} {unixOnly notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    createfile tfa/file
    exec chmod 000 tfa
    set result [catch {file mkdir tfa/file}]
    exec chmod 777 tfa
    file delete -force tfa
    set result
} {1}

test fCmd-15.5 {TclMakeDirsCmd: - making a directory several levels deep} \
	{notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa/a/b/c
    set result [file isdir tfa/a/b/c]
    file delete -force tfa
    set result
} {1}

    
test fCmd-15.6 {TclMakeDirsCmd: - trying to overwrite a file} {notRoot} {
    catch {file delete -force -- tfa}
    set s [createfile tfa]
    set r1 [catch {file mkdir tfa}]
    set r2 [file isdir tfa]
    set r3 [file exists tfa]
    set result [expr $r1 && !$r2 && $r3 && [checkcontent tfa $s]]
    file delete tfa
    set result
} {1}

test fCmd-15.7 {TclMakeDirsCmd - making several directories} {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    file mkdir tfa1 tfa2/a/b/c
    set result [expr [file isdir tfa1] && [file isdir tfa2/a/b/c]]
    file delete -force tfa1 tfa2
    set result
} {1}

test fCmd-15.8 {TclFileMakeDirsCmd: trying to create an existing dir} {notRoot} {
    file mkdir tfa
    file mkdir tfa
    set result [file isdir tfa]
    file delete tfa
    set result
} {1}


# Coverage tests for TclDeleteFilesCommand()
test fCmd-16.1 { test the -- argument } {notRoot} {
    catch {file delete -force -- tfa}
    createfile tfa
    file delete -- tfa
    file exists tfa
} {0}

test fCmd-16.2 { test the -force and -- arguments } {notRoot} {
    catch {file delete -force -- tfa}
    createfile tfa
    file delete -force -- tfa
    file exists tfa
} {0}

test fCmd-16.3 { test bad option } {notRoot} {
    catch {file delete -force -- tfa}
    createfile tfa
    set result [catch {file delete -dog tfa}]
    file delete tfa
    set result
} {1}

test fCmd-16.4 { test not enough args } {notRoot} {
    catch {file delete}
} {1}

test fCmd-16.5 { test not enough args with options } {notRoot} {
    catch {file delete --}
} {1}

test fCmd-16.6 {delete: source filename translation failing} {notRoot} {
    global env
    set temp $env(HOME)
    unset env(HOME)
    set result [catch {file delete ~/tfa}]
    set env(HOME) $temp
    set result
} {1}

test fCmd-16.7 {remove a non-empty directory without -force } {notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    createfile tfa/a
    set result [catch  {file delete tfa }]
    file delete -force tfa
    set result
} {1}

test fCmd-16.8 {remove a normal file } {notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    createfile tfa/a
    set result [catch  {file delete tfa }]
    file delete -force tfa
    set result
} {1}

test fCmd-16.9 {error while deleting file } {unixOnly notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    createfile tfa/a
    exec chmod 555 tfa
    set result [catch  {file delete tfa/a }]
    #######
    #######  If any directory in a tree that is being removed does not 
    #######  have write permission, the process will fail!
    #######  This is also the case with "rm -rf"
    #######
    exec chmod 777 tfa
    file delete -force tfa
    set result
} {1}

test fCmd-16.10 {deleting multiple files} {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    createfile tfa1
    createfile tfa2
    file delete tfa1 tfa2
    expr ![file exists tfa1] && ![file exists tfa2]
} {1}

test fCmd-16.11 { TclFileDeleteCmd: removing a nonexistant file} {notRoot} {
    catch {file delete -force -- tfa}
    file delete tfa
    set result 1
} {1}

# More coverage tests for mkpath()
 test fCmd-17.1 {mkdir stat failing on target but not ENOENT} {unixOnly notRoot} {
     catch {file delete -force -- tfa1}
     file mkdir tfa1
     exec chmod 555 tfa1
     set result [catch {file mkdir tfa1/tfa2}]
     exec chmod 777 tfa1
     file delete -force tfa1
     set result
} {1}

test fCmd-17.2 {mkdir several levels deep - relative } {notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa/a/b
    set result [file isdir tfa/a/b ]
    file delete tfa/a/b tfa/a tfa
    set result
} {1}

test fCmd-17.3 {mkdir several levels deep - absolute } {notRoot} {
    catch {file delete -force -- tfa}
    set f [file join [pwd] tfa a ]
    file mkdir $f
    set result [file isdir $f ]
    file delete $f [file join [pwd] tfa]
    set result
} {1}

#
# Functionality tests for TclFileRenameCmd()
#

test fCmd-18.1 {TclFileRenameCmd: rename (first form) in the same directory} \
	{notRoot} {
    catch {file delete -force -- tfad}
    file mkdir tfad/dir
    cd tfad/dir
    set s [createfile foo ]
    file rename  foo bar
    file rename bar ./foo
    file rename ./foo bar
    file rename ./bar ./foo
    file rename foo ../dir/bar
    file rename ../dir/bar ./foo
    file rename ../../tfad/dir/foo ../../tfad/dir/bar
    file rename [file join [pwd] bar] foo
    file rename foo [file join [pwd] bar]
    set result [expr [checkcontent bar $s] && ![file exists foo]]
    cd ../..
    file delete -force tfad
    set result
} {1}

test fCmd-18.2 {TclFileRenameCmd: single dir to nonexistant} {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    file mkdir tfa1
    file rename tfa1 tfa2
    set result [expr [file exists tfa2] && ![file exists tfa1]]
    file delete tfa2
    set result
} {1}

test fCmd-18.3 {TclFileRenameCmd: mixed dirs and files into directory} {notRoot} {
    catch {file delete -force -- tfa1 tfad1 tfad2}
    set s [createfile tfa1 ]
    file mkdir tfad1 tfad2
    file rename tfa1 tfad1 tfad2
    set r1 [checkcontent  tfad2/tfa1 $s]
    set r2 [file isdir tfad2/tfad1]
    set result [expr $r1 && $r2 && ![file exists tfa1] && ![file exists tfad1]]
    file delete tfad2/tfa1
    file delete -force tfad2
    set result
} {1}

test fCmd-18.4 {TclFileRenameCmd: attempt to replace non-dir with dir} {notRoot} {
    catch {file delete -force -- tfa tfad}
    set s [createfile tfa ]
    file mkdir tfad
    set r1 [catch {file rename tfad tfa}]
    set r2 [checkcontent tfa $s]
    set r3 [file isdir tfad]
    set result [expr $r1 && $r2 && $r3 ]
    file delete tfa tfad
    set result
} {1}

test fCmd-18.5 {TclFileRenameCmd: attempt to replace dir with non-dir} {notRoot} {
    catch {file delete -force -- tfa tfad}
    set s [createfile tfa ]
    file mkdir tfad/tfa
    set r1 [catch {file rename tfa tfad}]
    set r2 [checkcontent tfa $s]
    set r3 [file isdir tfad/tfa]
    set result [expr $r1 && $r2 && $r3 ]
    file delete -force  tfa tfad
    set result
} {1}

#
# On Windows there is no easy way to determine if two files are the same
#
test fCmd-18.6 {TclFileRenameCmd: rename a file to itself} {macOrUnix notRoot} {
    catch {file delete -force -- tfa}
    set s [createfile tfa]
    set r1 [catch {file rename tfa tfa}]
    set result [expr $r1 && [checkcontent tfa $s]]
    file delete tfa
    set result
} {1}

test fCmd-18.7 {TclFileRenameCmd: rename dir on top of another empty dir w/o -force} \
	{notRoot} {
    catch {file delete -force -- tfa tfad}
    file mkdir tfa tfad/tfa
    set r1 [catch {file rename tfa tfad}]
    set result [expr $r1 && [file isdir tfa]]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-18.8 {TclFileRenameCmd: rename dir on top of another empty dir w/ -force} \
	{notRoot} {
    catch {file delete -force -- tfa tfad}
    file mkdir tfa tfad/tfa
    file rename -force tfa tfad
    set result [expr ![file isdir tfa]]
    file delete -force tfad
    set result
} {1}

test fCmd-18.9 {TclFileRenameCmd: rename dir on top of a non-empty dir w/o -force} \
	{notRoot} {
    catch {file delete -force -- tfa tfad}
    file mkdir tfa tfad/tfa/file
    set r1 [catch {file rename tfa tfad}]
    set result [expr $r1 && [file isdir tfa] && [file isdir tfad/tfa/file]]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-18.10 {TclFileRenameCmd: rename dir on top of a non-empty dir w/ -force} \
	{notRoot} {
    catch {file delete -force -- tfa tfad}
    file mkdir tfa tfad/tfa/file
    set r1 [catch {file rename -force tfa tfad}]
    set result [expr $r1 && [file isdir tfa] && [file isdir tfad/tfa/file]]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-18.11 {TclFileRenameCmd: rename a non-existant file} {notRoot} {
    catch {file delete -force -- tfa1}
    set r1 [catch {file rename tfa1 tfa2}]
    set result [expr $r1 && ![file exists tfa1] && ![file exists tfa2]]
} {1}

test fCmd-18.12 {TclFileRenameCmd : rename a symbolic link to file} \
	{unixOnly notRoot} {
    catch {file delete -force -- tfa1 tfa2 tfa3}
	
    set s [createfile tfa1]
    exec ln -s tfa1 tfa2
    file rename tfa2 tfa3
    set t [file type tfa3]
    set result [expr { $t == "link" }]
    file delete tfa1 tfa3
    set result
} {1}

test fCmd-18.13 {TclFileRenameCmd : rename a symbolic link to dir} \
	{unixOnly notRoot} {
    catch {file delete -force -- tfa1 tfa2 tfa3}
	
    file mkdir tfa1
    exec ln -s tfa1 tfa2
    file rename tfa2 tfa3
    set t [file type tfa3]
    set result [expr { $t == "link" }]
    file delete tfa1 tfa3
    set result
} {1}

test fCmd-18.14 {TclFileRenameCmd : rename a path with sym link} \
	{unixOnly notRoot} {
    catch {file delete -force -- tfa1 tfa2 tfa3}
	
    file mkdir tfa1/a/b/c/d
    file mkdir tfa2
    set f [file join [pwd] tfa1/a/b] 
    set f2 [file join [pwd] {tfa2/b alias}]
    exec ln -s $f $f2
    file rename {tfa2/b alias/c} tfa3
    set r1 [file isdir tfa3]
    set r2 [file exists tfa1/a/b/c]
    set result [expr $r1 && !$r2]
    file delete -force tfa1 tfa2 tfa3
    set result
} {1}

test fCmd-18.15 {TclFileRenameCmd : rename a file to a symlink dir} \
	{unixOnly notRoot} {
    catch {file delete -force -- tfa1 tfa2 tfalink}
	
    file mkdir tfa1
    set s [createfile tfa2]
    exec ln -s tfa1 tfalink

    file rename tfa2 tfalink
    set result [checkcontent tfa1/tfa2 $s ]
    file delete -force tfa1 tfalink
    set result
} {1}

test fCmd-18.16 {TclFileRenameCmd: rename a dangling symlink} {unixOnly notRoot} {
    catch {file delete -force -- tfa1 tfalink}
	
    file mkdir tfa1
    exec ln -s tfa1 tfalink
    file delete tfa1 
    file rename tfalink tfa2
    set result [expr [string compare [file type tfa2] "link"] == 0]
    file delete tfa2
    set result
} {1}


#
# Coverage tests for TclUnixRmdir
#
test fCmd-19.1 { remove empty directory } {notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    file delete tfa
    file exists tfa
} {0}

test fCmd-19.2 { rmdir error besides EEXIST} {unixOnly notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    file mkdir tfa/a
    exec chmod 555 tfa
    set result [catch {file delete tfa/a}]
    exec chmod 777 tfa
    file delete -force tfa
    set result
} {1}

test fCmd-19.3 { recursive remove } {notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    file mkdir tfa/a
    file delete -force tfa
    file exists tfa
} {0}

#
# TclUnixDeleteFile and TraversalDelete are covered by tests from the 
# TclDeleteFilesCmd suite
#
#

#
# Coverage tests for TraverseUnixTree(), called from TclDeleteFilesCmd
#

test fCmd-20.1 {TraverseUnixTree : failure opening a subdirectory directory } \
	{unixOnly notRoot} {
    catch {file delete -force -- tfa}
    file mkdir tfa
    file mkdir tfa/a
    exec chmod 000 tfa/a
    set result [catch {file delete -force tfa}]
    exec chmod 777 tfa/a
    file delete -force tfa
    set result
} {1}


#
# Feature testing for TclCopyFilesCmd
# 
test fCmd-21.1 {copy : single file to nonexistant } {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    set s [createfile tfa1]
    file copy tfa1 tfa2
    set result [expr [checkcontent tfa2 $s] && [checkcontent tfa1 $s]]
    file delete tfa1 tfa2
    set result
} {1}

test fCmd-21.2 {copy : single dir to nonexistant } {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    file mkdir tfa1
    file copy tfa1 tfa2
    set result [expr [file isdir tfa2] && [file isdir tfa1]]
    file delete tfa1 tfa2
    set result
} {1}

test fCmd-21.3 {copy : single file into directory  } {notRoot} {
    catch {file delete -force -- tfa1 tfad}
    set s [createfile tfa1]
    file mkdir tfad
    file copy tfa1 tfad
    set result [expr [checkcontent tfad/tfa1 $s] && [checkcontent tfa1 $s]]
    file delete -force tfa1 tfad
    set result
} {1}

test fCmd-21.4 {copy : more than one source and target is not a directory} \
	{notRoot} {
    catch {file delete -force -- tfa1 tfa2 tfa3}
    createfile tfa1 
    createfile tfa2 
    createfile tfa3 
    set result [catch {file copy tfa1 tfa2 tfa3}]
    file delete tfa1 tfa2 tfa3
    set result
} {1}

test fCmd-21.5 {copy : multiple files into directory  } {notRoot} {
    catch {file delete -force -- tfa1 tfa2 tfad}
    set s1 [createfile tfa1 ]
    set s2 [createfile tfa2 ]
    file mkdir tfad
    file copy tfa1 tfa2 tfad
    set r1 [checkcontent tfad/tfa1 $s1]
    set r2 [checkcontent tfad/tfa2 $s2]
    set r3 [checkcontent tfa1 $s1]
    set r4 [checkcontent tfa2 $s2]
    set result [expr $r1 && $r2 && $r3 && $r4]
    file delete -force tfa1 tfa2 tfad
    set result
} {1}

test fCmd-21.6 {copy: mixed dirs and files into directory} \
	{notRoot notFileSharing} {
    catch {file delete -force -- tfa1 tfad1 tfad2}
    set s [createfile tfa1 ]
    file mkdir tfad1 tfad2
    file copy tfa1 tfad1 tfad2
    set r1 [checkcontent [file join tfad2 tfa1] $s]
    set r2 [file isdir [file join tfad2 tfad1]]
    set r3 [checkcontent tfa1 $s]
    set result [expr $r1 && $r2 && $r3 && [file isdir tfad1]]
    file delete -force tfa1 tfad1 tfad2
    set result
} {1}

test fCmd-21.7 {TclCopyFilesCmd: copy a dangling link} {unixOnly notRoot} {
    file mkdir tfad1
    exec ln -s tfad1 tfalink
    file delete tfad1
    file copy tfalink tfalink2
    set result [string match [file type tfalink2] link]
    file delete tfalink tfalink2 
    set result
} {1}

test fCmd-21.8 {TclCopyFilesCmd : copy a link } {unixOnly notRoot} {
    file mkdir tfad1
    exec ln -s tfad1 tfalink
    file copy tfalink tfalink2
    set r1 [file type tfalink]
    set r2 [file type tfalink2]
    set r3 [file isdir tfad1]
    set result [expr {("$r1" == "link" ) && ("$r2" == "link" ) && $r3}]
    file delete tfad1 tfalink tfalink2
    set result
} {1}

test fCmd-21.9 {TclCopyFilesCmd: copy dir with a link in it} {unixOnly notRoot} {
    file mkdir tfad1
    exec ln -s "[pwd]/tfad1" tfad1/tfalink
    file copy tfad1 tfad2
    set result [string match [file type tfad2/tfalink] link]
    file delete -force tfad1 tfad2
    set result
} {1}

test fCmd-21.10 {TclFileCopyCmd: copy dir on top of another empty dir w/o -force} \
	{notRoot} {
    catch {file delete -force -- tfa tfad}
    file mkdir tfa [file join tfad tfa]
    set r1 [catch {file copy tfa tfad}]
    set result [expr $r1 && [file isdir tfa]]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-21.11 {TclFileCopyCmd: copy dir on top of a dir w/o -force} {notRoot} {
    catch {file delete -force -- tfa tfad}
    file mkdir tfa [file join tfad tfa file]
    set r1 [catch {file copy tfa tfad}]
    set result [expr $r1 && [file isdir tfa] && [file isdir [file join tfad tfa file]]]
    file delete -force tfa tfad
    set result
} {1}

test fCmd-21.12 {TclFileCopyCmd: copy dir on top of a non-empty dir w/ -force} \
	{notRoot} {
    catch {file delete -force -- tfa tfad}
    file mkdir tfa [file join tfad tfa file]
    set r1 [catch {file copy -force tfa tfad}]
    set result [expr $r1 && [file isdir tfa] && [file isdir [file join tfad tfa file]]]
    file delete -force tfa tfad
    set result
} {1}
   
#
# Coverage testing for TclpRenameFile
#
test fCmd-22.1 {TclpRenameFile: rename and overwrite in a single dir} {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    set s [createfile tfa1]
    set s2 [createfile tfa2 q]
	
    set r1 [catch {rename tfa1 tfa2}]
    file rename -force tfa1 tfa2
    set result [expr $r1 && [checkcontent tfa2 $s]]
    file delete [glob tfa1 tfa2]
    set result
} {1}

test fCmd-22.2 {TclpRenameFile: attempt to overwrite itself} {macOrUnix notRoot} {
    catch {file delete -force -- tfa1}
    set s [createfile tfa1]	
    file rename -force tfa1 tfa1
    set result [checkcontent tfa1 $s]
    file delete tfa1 
    set result
} {1}

test fCmd-22.3 { TclpRenameFile : rename dir to existing dir } {notRoot} {
    catch {file delete -force -- d1 tfad}
    file mkdir d1 [file join tfad d1]
    set r1 [catch {file rename d1 tfad}]
    set result [expr $r1 && [file isdir d1] && [file isdir [file join tfad d1]]]
    file delete -force d1 tfad
    set result
} {1}

test fCmd-22.4 {TclpRenameFile: rename dir to dir several levels deep} {notRoot} {
    catch {file delete -force -- d1 tfad}
    file mkdir d1 [file join tfad a b c]
    file rename d1 [file join tfad a b c d1]
    set result [expr ![file isdir d1] && [file isdir [file join tfad a b c d1]]]
    file delete -force [glob d1 tfad]
    set result
} {1}


#
# TclMacCopyFile needs to be redone.
#
test fCmd-22.5 {TclMacCopyFile: copy and overwrite in a single dir} {notRoot} {
    catch {file delete -force -- tfa1 tfa2}
    set s [createfile tfa1]
    set s2 [createfile tfa2 q]

    set r1 [catch {file copy tfa1 tfa2}]
    file copy -force tfa1 tfa2
    set result [expr $r1 && [checkcontent tfa2 $s] && [checkcontent tfa1 $s]]
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078

2079
2080
2081
2082

2083
2084
2085
2086


2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101

2102














#

#
# TclMacRmdir
# Error cases are not covered.
#

test fCmd-23.1 { TclMacRmdir : trying to remove a nonempty directory } {
    catch {file delete -force -- tfad}
	
    file mkdir [file join tfad dir]
	
    set result [catch {file delete tfad}]
    file delete -force tfad 
    set result
} {1}

#
# TclMacDeleteFile	
# Error cases are not covered.
#
test fCmd-24.1 { TclMacDeleteFile : deleting a normal file } {
    catch {file delete -force -- tfa1}
	
    createfile tfa1
    file delete tfa1
    file exists tfa1
} {0}

#
# TclMacCopyDirectory
# Error cases are not covered.
#
test fCmd-25.1 { TclMacCopyDirectory : copying a normal directory} {notFileSharing} {

    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir [file join tfad1 a b c]
    file copy tfad1 tfad2
    set result [expr [file isdir [file join tfad1 a b c]] && [file isdir [file join tfad2 a b c]]]
    file delete -force tfad1 tfad2
    set result
} {1}

test fCmd-25.2 { TclMacCopyDirectory : copying a short path normal directory} {notFileSharing} {

    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir tfad1
    file copy tfad1 tfad2
    set result [expr [file isdir tfad1] && [file isdir tfad2]]
    file delete tfad1 tfad2
    set result
} {1}

test fCmd-25.3 { TclMacCopyDirectory : copying dirs between different dirs} {notFileSharing} {

    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir [file join tfad1 x y z]
    file mkdir [file join tfad2 dir]
    file copy tfad1 [file join tfad2 dir]
    set result [expr [file isdir [file join tfad1 x y z]] && [file isdir [file join tfad2 dir tfad1 x y z]]]
    file delete -force tfad1 tfad2
    set result
} {1}

#
# Functionality tests for TclDeleteFilesCmd
#

test fCmd-26.1 { TclDeleteFilesCmd : delete symlink} {unixOnly} {
    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir tfad1
    exec ln -s tfad1 tfalink
    file delete tfalink

    set r1 [file isdir tfad1]
    set r2 [file exists tfalink]
    
    set result [expr $r1 && !$r2]
    file delete tfad1
    set result
} {1}

test fCmd-26.2 { TclDeleteFilesCmd : delete dir with symlink} {unixOnly} {
    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir tfad1
    file mkdir tfad2
    exec ln -s tfad1 [file join tfad2 link]
    file delete -force tfad2

    set r1 [file isdir tfad1]
    set r2 [file exists tfad2]
    
    set result [expr $r1 && !$r2]
    file delete tfad1
    set result
} {1}

test fCmd-26.3 { TclDeleteFilesCmd : delete dangling symlink} {unixOnly} {
    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir tfad1
    exec ln -s tfad1 tfad2
    file delete tfad1
    file delete tfad2

    set r1 [file exists tfad1]
    set r2 [file exists tfad2]
    
    set result [expr !$r1 && !$r2]
    set result
} {1}

test fCmd-27.1 {TclFileAttrsCmd - wrong # args} {
    list [catch {file attributes a b c d} msg] $msg
} {1 {wrong # args: must be "file attributes name ?option? ?value? ?option value? ..."}}
test fCmd-27.2 {TclFileAttrsCmd - Tcl_TranslateFileName fails} {
    testsetplatform unix
    list [catch {file attributes ~_bad_user} msg] $msg [testsetplatform $platform]
} {1 {user "_bad_user" doesn't exist} {}}
test fCmd-27.3 {TclFileAttrsCmd - all attributes} {
    catch {file delete -force -- foo.tmp}
    createfile foo.tmp
    list [catch {file attributes foo.tmp} msg] [expr {[llength $msg] > 0}] [file delete -force -- foo.tmp]
} {0 1 {}}
test fCmd-27.4 {TclFileAttrsCmd - getting one option} {
    catch {file delete -force -- foo.tmp}
    createfile foo.tmp
    set attrs [file attributes foo.tmp]
    list [catch {eval file attributes foo.tmp [lindex $attrs 0]}] [file delete -force -- foo.tmp]
} {0 {}}


set testConfig(tclGroup) 0
if {($tcl_platform(platform) == "macintosh") \
	|| ($tcl_platform(platform) == "windows")} {
    set testConfig(tclGroup) 1

} elseif {[catch {exec {groups}} groupList] == 0} {
    if {[lsearch $groupList tcl] != -1} {
	set testConfig(tclGroup) 1
    }


}

test fCmd-27.5 {TclFileAttrsCmd - setting one option} {tclGroup} {
    catch {file delete -force -- foo.tmp}
    createfile foo.tmp
    set attrs [file attributes foo.tmp]
    list [catch {eval file attributes foo.tmp [lrange $attrs 0 1]} msg] $msg [file delete -force -- foo.tmp]
} {0 {} {}}
test fCmd-27.6 {TclFileAttrsCmd - setting more than one option} {tclGroup} {
    catch {file delete -force -- foo.tmp}
    createfile foo.tmp
    set attrs [file attributes foo.tmp]
    list [catch {eval file attributes foo.tmp [lrange $attrs 0 3]} msg] $msg [file delete -force -- foo.tmp]
} {0 {} {}}


cleanup





















|













|











|
>









|
>









|
>














|














|















|














<
<
<
















>
|
<
|
|
>
|
|
|

>
>


|





|






>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
#

#
# TclMacRmdir
# Error cases are not covered.
#

test fCmd-23.1 {TclMacRmdir: trying to remove a nonempty directory} {notRoot} {
    catch {file delete -force -- tfad}
	
    file mkdir [file join tfad dir]
	
    set result [catch {file delete tfad}]
    file delete -force tfad 
    set result
} {1}

#
# TclMacDeleteFile	
# Error cases are not covered.
#
test fCmd-24.1 {TclMacDeleteFile: deleting a normal file} {notRoot} {
    catch {file delete -force -- tfa1}
	
    createfile tfa1
    file delete tfa1
    file exists tfa1
} {0}

#
# TclMacCopyDirectory
# Error cases are not covered.
#
test fCmd-25.1 { TclMacCopyDirectory : copying a normal directory} \
	{notRoot notFileSharing} {
    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir [file join tfad1 a b c]
    file copy tfad1 tfad2
    set result [expr [file isdir [file join tfad1 a b c]] && [file isdir [file join tfad2 a b c]]]
    file delete -force tfad1 tfad2
    set result
} {1}

test fCmd-25.2 { TclMacCopyDirectory : copying a short path normal directory} \
	{notRoot notFileSharing} {
    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir tfad1
    file copy tfad1 tfad2
    set result [expr [file isdir tfad1] && [file isdir tfad2]]
    file delete tfad1 tfad2
    set result
} {1}

test fCmd-25.3 { TclMacCopyDirectory : copying dirs between different dirs} \
	{notRoot notFileSharing} {
    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir [file join tfad1 x y z]
    file mkdir [file join tfad2 dir]
    file copy tfad1 [file join tfad2 dir]
    set result [expr [file isdir [file join tfad1 x y z]] && [file isdir [file join tfad2 dir tfad1 x y z]]]
    file delete -force tfad1 tfad2
    set result
} {1}

#
# Functionality tests for TclDeleteFilesCmd
#

test fCmd-26.1 { TclDeleteFilesCmd : delete symlink} {unixOnly notRoot} {
    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir tfad1
    exec ln -s tfad1 tfalink
    file delete tfalink

    set r1 [file isdir tfad1]
    set r2 [file exists tfalink]
    
    set result [expr $r1 && !$r2]
    file delete tfad1
    set result
} {1}

test fCmd-26.2 { TclDeleteFilesCmd : delete dir with symlink} {unixOnly notRoot} {
    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir tfad1
    file mkdir tfad2
    exec ln -s tfad1 [file join tfad2 link]
    file delete -force tfad2

    set r1 [file isdir tfad1]
    set r2 [file exists tfad2]
    
    set result [expr $r1 && !$r2]
    file delete tfad1
    set result
} {1}

test fCmd-26.3 { TclDeleteFilesCmd : delete dangling symlink} {unixOnly notRoot} {
    catch {file delete -force -- tfad1 tfad2}
		
    file mkdir tfad1
    exec ln -s tfad1 tfad2
    file delete tfad1
    file delete tfad2

    set r1 [file exists tfad1]
    set r2 [file exists tfad2]
    
    set result [expr !$r1 && !$r2]
    set result
} {1}




test fCmd-27.2 {TclFileAttrsCmd - Tcl_TranslateFileName fails} {
    testsetplatform unix
    list [catch {file attributes ~_bad_user} msg] $msg [testsetplatform $platform]
} {1 {user "_bad_user" doesn't exist} {}}
test fCmd-27.3 {TclFileAttrsCmd - all attributes} {
    catch {file delete -force -- foo.tmp}
    createfile foo.tmp
    list [catch {file attributes foo.tmp} msg] [expr {[llength $msg] > 0}] [file delete -force -- foo.tmp]
} {0 1 {}}
test fCmd-27.4 {TclFileAttrsCmd - getting one option} {
    catch {file delete -force -- foo.tmp}
    createfile foo.tmp
    set attrs [file attributes foo.tmp]
    list [catch {eval file attributes foo.tmp [lindex $attrs 0]}] [file delete -force -- foo.tmp]
} {0 {}}

# Find a group that exists on this Unix system, or else skip tests that
# require Unix groups.

if {$tcl_platform(platform) == "unix"} {
    set ::tcltest::testConfig(foundGroup) 0
    catch {
	set groupList [exec groups]
	set group [lindex $groupList 0]
	set ::tcltest::testConfig(foundGroup) 1
    }
} else {
    set ::tcltest::testConfig(foundGroup) 1
}

test fCmd-27.5 {TclFileAttrsCmd - setting one option} {foundGroup} {
    catch {file delete -force -- foo.tmp}
    createfile foo.tmp
    set attrs [file attributes foo.tmp]
    list [catch {eval file attributes foo.tmp [lrange $attrs 0 1]} msg] $msg [file delete -force -- foo.tmp]
} {0 {} {}}
test fCmd-27.6 {TclFileAttrsCmd - setting more than one option} {foundGroup} {
    catch {file delete -force -- foo.tmp}
    createfile foo.tmp
    set attrs [file attributes foo.tmp]
    list [catch {eval file attributes foo.tmp [lrange $attrs 0 3]} msg] $msg [file delete -force -- foo.tmp]
} {0 {} {}}

# cleanup
cleanup
::tcltest::cleanupTests
return












Changes to tests/fileName.test.

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
# This file tests the filename manipulation routines.
#
# 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) 1995-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) fileName.test 1.31 97/08/19 18:45:07


if {[string compare test [info procs test]] == 1} then {source defs}


if {[info commands testsetplatform] == {}} {
    puts "This application hasn't been compiled with the \"testsetplatform\""
    puts "command, so I can't test the filename conversion procedures."

    return 
} 

global env
set platform [testgetplatform]

test filename-1.1 {Tcl_GetPathType: unix} {







>




|

>
|
>




>







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
# This file tests the filename manipulation routines.
#
# 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) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 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: fileName.test,v 1.1.2.9 1999/04/06 22:01:43 hershey Exp $

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

if {[info commands testsetplatform] == {}} {
    puts "This application hasn't been compiled with the \"testsetplatform\""
    puts "command, so I can't test the filename conversion procedures."
    ::tcltest::cleanupTests
    return 
} 

global env
set platform [testgetplatform]

test filename-1.1 {Tcl_GetPathType: unix} {
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
test filename-10.22 {Tcl_TranslateFileName} {
    testsetplatform windows
    list [catch {testtranslatefilename foo//bar} msg] $msg
} {0 {foo\bar}}

testsetplatform $platform

test filename-10.23 {Tcl_TranslateFileName} {nonPortable unixOnly} {
    # this test fails if ~ouster is not /home/ouster
    list [catch {testtranslatefilename ~ouster} msg] $msg
} {0 /home/ouster}
test filename-10.24 {Tcl_TranslateFileName} {nonPortable unixOnly} {
    # this test fails if ~ouster is not /home/ouster
    list [catch {testtranslatefilename ~ouster/foo} msg] $msg
} {0 /home/ouster/foo}


test filename-11.1 {Tcl_GlobCmd} {
    list [catch {glob} msg] $msg







|



|







1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
test filename-10.22 {Tcl_TranslateFileName} {
    testsetplatform windows
    list [catch {testtranslatefilename foo//bar} msg] $msg
} {0 {foo\bar}}

testsetplatform $platform

test filename-10.23 {Tcl_TranslateFileName} {unixOnly nonPortable} {
    # this test fails if ~ouster is not /home/ouster
    list [catch {testtranslatefilename ~ouster} msg] $msg
} {0 /home/ouster}
test filename-10.24 {Tcl_TranslateFileName} {unixOnly nonPortable} {
    # this test fails if ~ouster is not /home/ouster
    list [catch {testtranslatefilename ~ouster/foo} msg] $msg
} {0 /home/ouster/foo}


test filename-11.1 {Tcl_GlobCmd} {
    list [catch {glob} msg] $msg
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
close [open globTest/x1.c w]
close [open globTest/y1.c w]
close [open globTest/z1.c w]
close [open "globTest/weird name.c" w]
close [open globTest/a1/b1/x2.c w]
close [open globTest/a1/b2/y2.c w]

# Cannot create a file with the following names under Win32s.  We have to
# skip the tests that are checking the difference between a "." or "," in
# the file name vs. a "." or "," in the glob pattern.

catch {close [open globTest/.1 w]}
catch {close [open globTest/x,z1.c w]}

test filename-11.14 {Tcl_GlobCmd} {
    list [catch {glob ~/globTest} msg] $msg
} [list 0 [list [file join $env(HOME) globTest]]]
test filename-11.15 {Tcl_GlobCmd} {







<
<
<
<







1103
1104
1105
1106
1107
1108
1109




1110
1111
1112
1113
1114
1115
1116
close [open globTest/x1.c w]
close [open globTest/y1.c w]
close [open globTest/z1.c w]
close [open "globTest/weird name.c" w]
close [open globTest/a1/b1/x2.c w]
close [open globTest/a1/b2/y2.c w]





catch {close [open globTest/.1 w]}
catch {close [open globTest/x,z1.c w]}

test filename-11.14 {Tcl_GlobCmd} {
    list [catch {glob ~/globTest} msg] $msg
} [list 0 [list [file join $env(HOME) globTest]]]
test filename-11.15 {Tcl_GlobCmd} {
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
} "0 $globPreResult$x1"
test filename-13.7 {globbing with brace substitution} {
    list [catch {glob globTest/\{x\}1.c} msg] $msg
} "0 $globPreResult$x1"
test filename-13.8 {globbing with brace substitution} {
    list [catch {glob globTest/\{x\{\}\}1.c} msg] $msg
} "0 $globPreResult$x1"
test filename-13.9 {globbing with brace substitution} {!win32s} {
    list [lsort [catch {glob globTest/\{x,y\}1.c} msg]] $msg
} [list 0 [list $globPreResult$x1 $globPreResult$y1]]
test filename-13.10 {globbing with brace substitution} {!win32s} {
    list [lsort [catch {glob globTest/\{x,,y\}1.c} msg]] $msg
} [list 0 [list $globPreResult$x1 $globPreResult$y1]]
test filename-13.11 {globbing with brace substitution} {unixOrPc && !win32s} {
    list [lsort [catch {glob globTest/\{x,x\\,z,z\}1.c} msg]] $msg
} {0 {globTest/x1.c globTest/x,z1.c globTest/z1.c}}
test filename-13.12 {globbing with brace substitution} {macOnly} {
    list [lsort [catch {glob globTest/\{x,x\\,z,z\}1.c} msg]] $msg
} {0 {:globTest:x1.c :globTest:x,z1.c :globTest:z1.c}}
test filename-13.13 {globbing with brace substitution} {
    lsort [glob globTest/{a,b,x,y}1.c]







|


|


|







1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
} "0 $globPreResult$x1"
test filename-13.7 {globbing with brace substitution} {
    list [catch {glob globTest/\{x\}1.c} msg] $msg
} "0 $globPreResult$x1"
test filename-13.8 {globbing with brace substitution} {
    list [catch {glob globTest/\{x\{\}\}1.c} msg] $msg
} "0 $globPreResult$x1"
test filename-13.9 {globbing with brace substitution} {
    list [lsort [catch {glob globTest/\{x,y\}1.c} msg]] $msg
} [list 0 [list $globPreResult$x1 $globPreResult$y1]]
test filename-13.10 {globbing with brace substitution} {
    list [lsort [catch {glob globTest/\{x,,y\}1.c} msg]] $msg
} [list 0 [list $globPreResult$x1 $globPreResult$y1]]
test filename-13.11 {globbing with brace substitution} {unixOrPc} {
    list [lsort [catch {glob globTest/\{x,x\\,z,z\}1.c} msg]] $msg
} {0 {globTest/x1.c globTest/x,z1.c globTest/z1.c}}
test filename-13.12 {globbing with brace substitution} {macOnly} {
    list [lsort [catch {glob globTest/\{x,x\\,z,z\}1.c} msg]] $msg
} {0 {:globTest:x1.c :globTest:x,z1.c :globTest:z1.c}}
test filename-13.13 {globbing with brace substitution} {
    lsort [glob globTest/{a,b,x,y}1.c]
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
test filename-13.21 {globbing with brace substitution} {macOnly} {
    lsort [glob globTest/{a,x}1/*/{x,y}*]
} {:globTest:a1:b1:x2.c :globTest:a1:b2:y2.c}
test filename-13.22 {globbing with brace substitution} {
    list [catch {glob globTest/\{a,x\}1/*/\{} msg] $msg
} {1 {unmatched open-brace in file name}}

test filename-14.1 {asterisks, question marks, and brackets} {unixOrPc && !win32s} {
    lsort [glob g*/*.c]
} {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
test filename-14.1 {asterisks, question marks, and brackets} {win32s} {
    lsort [glob g*/*.c]
} {globtest/weirdn~1.c globtest/x1.c globtest/y1.c globtest/z1.c}
test filename-14.2 {asterisks, question marks, and brackets} {macOnly} {
    lsort [glob g*/*.c]
} {{:globTest:weird name.c} :globTest:x,z1.c :globTest:x1.c :globTest:y1.c :globTest:z1.c}
test filename-14.3 {asterisks, question marks, and brackets} {unixOrPc} {
    lsort [glob globTest/?1.c]
} {globTest/x1.c globTest/y1.c globTest/z1.c}
test filename-14.4 {asterisks, question marks, and brackets} {macOnly} {
    lsort [glob globTest/?1.c]
} {:globTest:x1.c :globTest:y1.c :globTest:z1.c}
test filename-14.5 {asterisks, question marks, and brackets} {unixOrPc && !win32s} {
    lsort [glob */*/*/*.c]
} {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
test filename-14.5 {asterisks, question marks, and brackets} {win32s} {
    lsort [glob */*/*/*.c]
} {globtest/a1/b1/x2.c globtest/a1/b2/y2.c}
test filename-14.6 {asterisks, question marks, and brackets} {macOnly} {
    lsort [glob */*/*/*.c]
} {:globTest:a1:b1:x2.c :globTest:a1:b2:y2.c}
test filename-14.7 {asterisks, question marks, and brackets} {unixOrPc && !win32s} {
    lsort [glob globTest/*]
} {globTest/a1 globTest/a2 globTest/a3 {globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
test filename-14.7 {asterisks, question marks, and brackets} {win32s} {
    lsort [glob globTest/*]
} {globTest/a1 globTest/a2 globTest/a3 globTest/weirdn~1.c globTest/x1.c globTest/y1.c globTest/z1.c}
test filename-14.8 {asterisks, question marks, and brackets} {macOnly} {
    lsort [glob globTest/*]
} {:globTest:.1 :globTest:a1 :globTest:a2 :globTest:a3 {:globTest:weird name.c} :globTest:x,z1.c :globTest:x1.c :globTest:y1.c :globTest:z1.c}
test filename-14.9 {asterisks, question marks, and brackets} {unixOrPc && !win32s} {
    lsort [glob globTest/.*]
} {globTest/. globTest/.. globTest/.1}
test filename-14.9 {asterisks, question marks, and brackets} {win32s} {
    lsort [glob globTest/.*]
} {globTest/. globTest/..}
test filename-14.10 {asterisks, question marks, and brackets} {macOnly} {
    lsort [glob globTest/.*]
} {:globTest:.1}
test filename-14.11 {asterisks, question marks, and brackets} {unixOrPc} {
    lsort [glob globTest/*/*]
} {globTest/a1/b1 globTest/a1/b2 globTest/a2/b3}
test filename-14.12 {asterisks, question marks, and brackets} {macOnly} {







|


<
<
<









|


<
<
<



|


<
<
<



|


<
<
<







1210
1211
1212
1213
1214
1215
1216
1217
1218
1219



1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231



1232
1233
1234
1235
1236
1237



1238
1239
1240
1241
1242
1243



1244
1245
1246
1247
1248
1249
1250
test filename-13.21 {globbing with brace substitution} {macOnly} {
    lsort [glob globTest/{a,x}1/*/{x,y}*]
} {:globTest:a1:b1:x2.c :globTest:a1:b2:y2.c}
test filename-13.22 {globbing with brace substitution} {
    list [catch {glob globTest/\{a,x\}1/*/\{} msg] $msg
} {1 {unmatched open-brace in file name}}

test filename-14.1 {asterisks, question marks, and brackets} {unixOrPc} {
    lsort [glob g*/*.c]
} {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}



test filename-14.2 {asterisks, question marks, and brackets} {macOnly} {
    lsort [glob g*/*.c]
} {{:globTest:weird name.c} :globTest:x,z1.c :globTest:x1.c :globTest:y1.c :globTest:z1.c}
test filename-14.3 {asterisks, question marks, and brackets} {unixOrPc} {
    lsort [glob globTest/?1.c]
} {globTest/x1.c globTest/y1.c globTest/z1.c}
test filename-14.4 {asterisks, question marks, and brackets} {macOnly} {
    lsort [glob globTest/?1.c]
} {:globTest:x1.c :globTest:y1.c :globTest:z1.c}
test filename-14.5 {asterisks, question marks, and brackets} {unixOrPc} {
    lsort [glob */*/*/*.c]
} {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}



test filename-14.6 {asterisks, question marks, and brackets} {macOnly} {
    lsort [glob */*/*/*.c]
} {:globTest:a1:b1:x2.c :globTest:a1:b2:y2.c}
test filename-14.7 {asterisks, question marks, and brackets} {unixOrPc} {
    lsort [glob globTest/*]
} {globTest/a1 globTest/a2 globTest/a3 {globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}



test filename-14.8 {asterisks, question marks, and brackets} {macOnly} {
    lsort [glob globTest/*]
} {:globTest:.1 :globTest:a1 :globTest:a2 :globTest:a3 {:globTest:weird name.c} :globTest:x,z1.c :globTest:x1.c :globTest:y1.c :globTest:z1.c}
test filename-14.9 {asterisks, question marks, and brackets} {unixOrPc} {
    lsort [glob globTest/.*]
} {globTest/. globTest/.. globTest/.1}



test filename-14.10 {asterisks, question marks, and brackets} {macOnly} {
    lsort [glob globTest/.*]
} {:globTest:.1}
test filename-14.11 {asterisks, question marks, and brackets} {unixOrPc} {
    lsort [glob globTest/*/*]
} {globTest/a1/b1 globTest/a1/b2 globTest/a2/b3}
test filename-14.12 {asterisks, question marks, and brackets} {macOnly} {
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323

1324
1325
1326
1327

1328
1329

1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355





























































1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448


1449











    global env
    set temp $env(HOME)
    set env(HOME) [file join $env(HOME) globTest]
    set result [list [catch {glob ~/z*} msg] $msg]
    set env(HOME) $temp
    set result
} [list 0 [list [file join $env(HOME) globTest z1.c]]]
test filename-14.18 {asterisks, question marks, and brackets} {unixOrPc && !win32s} {
    list [catch {lsort [glob globTest/*.c goo/*]} msg] $msg
} {0 {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}}
test filename-14.18 {asterisks, question marks, and brackets} {win32s} {
    list [catch {lsort [glob globTest/*.c goo/*]} msg] $msg
} {0 {globTest/weirdn~1.c globTest/x1.c globTest/y1.c globTest/z1.c}}
test filename-14.19 {asterisks, question marks, and brackets} {macOnly} {
    list [catch {lsort [glob globTest/*.c goo/*]} msg] $msg
} {0 {{:globTest:weird name.c} :globTest:x,z1.c :globTest:x1.c :globTest:y1.c :globTest:z1.c}}
test filename-14.20 {asterisks, question marks, and brackets} {
    list [catch {glob -nocomplain goo/*} msg] $msg
} {0 {}}
test filename-14.21 {asterisks, question marks, and brackets} {
    list [catch {glob globTest/*/gorp} msg] $msg
} {1 {no files matched glob pattern "globTest/*/gorp"}}
test filename-14.22 {asterisks, question marks, and brackets} {
    list [catch {glob goo/* x*z foo?q} msg] $msg
} {1 {no files matched glob patterns "goo/* x*z foo?q"}}
test filename-14.23 {slash globbing} {unixOrPc} {
    glob /
} /
test filename-14.24 {slash globbing} {pcOnly} {
    glob {\\}
} /

# The following tests are only valid for Unix systems.

if {$tcl_platform(platform) == "unix"} {
    # On some systems, like AFS, "000" protection doesn't prevent
    # access by owner, so the following test is not portable.

    exec chmod 000 globTest/a1
    test filename-15.1 {unix specific globbing} {nonPortable} {
	string tolower [list [catch {glob globTest/a1/*} msg]  $msg $errorCode]
    } {1 {couldn't read directory "globtest/a1": permission denied} {posix eacces {permission denied}}}
    test filename-15.2 {unix specific no complain: no errors} {nonPortable} {
	glob -nocomplain globTest/a1/*
    } {}
    test filename-15.3 {unix specific no complain: no errors, good result} {nonPortable knownBug} {

	# test fails because if an error occur , the interp's result
	# is reset...
	glob -nocomplain globTest/a2 globTest/a1/* globTest/a3
    } {globTest/a2 globTest/a3}

    exec chmod 755 globTest/a1
    test filename-15.4 {unix specific no complain: no errors, good result} {nonPortable knownBug} {

	# test fails because if an error occur , the interp's result
	# is reset... (or you don't run at sunscript where the
	# outser and demailly's users exists
	glob -nocomplain ~ouster ~foo ~demailly
    } {/home/ouster /home/demailly}
    test filename-15.5 {unix specific globbing} {nonPortable} {
	glob ~ouster/.csh*
    } "/home/ouster/.cshrc"
    close [open globTest/odd\\\[\]*?\{\}name w]
    test filename-15.6 {unix specific globbing} {
	global env
	set temp $env(HOME)
	set env(HOME) $env(HOME)/globTest/odd\\\[\]*?\{\}name
	set result [list [catch {glob ~} msg] $msg]
	set env(HOME) $temp
	set result
    } [list 0 [list [glob ~]/globTest/odd\\\[\]*?\{\}name]]
    exec rm -f globTest/odd\\\[\]*?\{\}name
}

# The following tests are only valid for Windows systems.

if {$tcl_platform(platform) == "windows"} {
    set temp [pwd]
    cd c:/
    catch {





























































	removeDirectory globTest
	makeDirectory globTest
	close [open globTest/x1.BAT w]
	close [open globTest/y1.Bat w]
	close [open globTest/z1.bat w]
    }
    
    test filename-16.1 {windows specific globbing} {!win32s} {
	lsort [glob globTest/*.bat]
    } {globTest/x1.BAT globTest/y1.Bat globTest/z1.bat}
    test filename-16.1 {windows specific globbing} {win32s} {
	lsort [glob globTest/*.bat]
    } {globTest/x1.bat globTest/y1.bat globTest/z1.bat}
    test filename-16.2 {windows specific globbing} {
	glob c:
    } c:
    test filename-16.3 {windows specific globbing} {
	glob c:\\\\
	} c:/
    test filename-16.4 {windows specific globbing} {
	glob c:/
    } c:/
    test filename-16.5 {windows specific globbing} {!win32s} {
	glob c:*Test
    } c:globTest
    test filename-16.5 {windows specific globbing} {win32s} {
	glob c:*Test
    } c:globtest
    test filename-16.6 {windows specific globbing} {!win32s} {
	glob c:\\\\*Test
    } c:/globTest
    test filename-16.6 {windows specific globbing} {win32s} {
	glob c:\\\\*Test
    } c:/globtest
    test filename-16.7 {windows specific globbing} {!win32s} {
	glob c:/*Test
    } c:/globTest
    test filename-16.7 {windows specific globbing} {win32s} {
	glob c:/*Test
    } c:/globtest
    test filename-16.8 {windows specific globbing} {!win32s} {
	lsort [glob c:globTest/*.bat]
    } {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
    test filename-16.8 {windows specific globbing} {win32s} {
	lsort [glob c:globTest/*.bat]
    } {c:globTest/x1.bat c:globTest/y1.bat c:globTest/z1.bat}
    test filename-16.9 {windows specific globbing} {!win32s} {
	lsort [glob c:/globTest/*.bat]
    } {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
    test filename-16.9 {windows specific globbing} {win32s} {
	lsort [glob c:/globTest/*.bat]
    } {c:/globTest/x1.bat c:/globTest/y1.bat c:/globTest/z1.bat}
    test filename-16.10 {windows specific globbing} {!win32s} {
	lsort [glob c:globTest\\\\*.bat]
    } {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
    test filename-16.10 {windows specific globbing} {win32s} {
	lsort [glob c:globTest\\\\*.bat]
    } {c:globTest/x1.bat c:globTest/y1.bat c:globTest/z1.bat}
    test filename-16.11 {windows specific globbing} {!win32s} {
	lsort [glob c:\\\\globTest\\\\*.bat]
    } {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
    test filename-16.11 {windows specific globbing} {win32s} {
	lsort [glob c:\\\\globTest\\\\*.bat]
    } {c:/globTest/x1.bat c:/globTest/y1.bat c:/globTest/z1.bat}

    removeDirectory globTest

    if {($testConfig(nonPortable) != 0) && [catch {cd //gaspode/d}] == 0} {
	removeDirectory globTest
	makeDirectory globTest

	close [open globTest/x1.BAT w]
	close [open globTest/y1.Bat w]
	close [open globTest/z1.bat w]

	test filename-16.12 {windows specific globbing} {
	    glob //gaspode/d/*Test
	} //gaspode/d/globTest
	test filename-16.13 {windows specific globbing} {
	    glob {\\\\gaspode\\d\\*Test}
	} //gaspode/d/globTest

	removeDirectory globTest
    }	    

    cd $temp
}

removeDirectory globTest
set env(HOME) $oldhome

testsetplatform $platform
catch {unset oldhome platform temp result}


concat ""


















|


<
<
<




















<
<
|
|

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


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

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

<


>
>
|
>
>
>
>
>
>
>
>
>
>
>
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275



1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295


1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336


1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405

1406

















1407







































1408

1409



1410














1411

1412

1413

1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
    global env
    set temp $env(HOME)
    set env(HOME) [file join $env(HOME) globTest]
    set result [list [catch {glob ~/z*} msg] $msg]
    set env(HOME) $temp
    set result
} [list 0 [list [file join $env(HOME) globTest z1.c]]]
test filename-14.18 {asterisks, question marks, and brackets} {unixOrPc} {
    list [catch {lsort [glob globTest/*.c goo/*]} msg] $msg
} {0 {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}}



test filename-14.19 {asterisks, question marks, and brackets} {macOnly} {
    list [catch {lsort [glob globTest/*.c goo/*]} msg] $msg
} {0 {{:globTest:weird name.c} :globTest:x,z1.c :globTest:x1.c :globTest:y1.c :globTest:z1.c}}
test filename-14.20 {asterisks, question marks, and brackets} {
    list [catch {glob -nocomplain goo/*} msg] $msg
} {0 {}}
test filename-14.21 {asterisks, question marks, and brackets} {
    list [catch {glob globTest/*/gorp} msg] $msg
} {1 {no files matched glob pattern "globTest/*/gorp"}}
test filename-14.22 {asterisks, question marks, and brackets} {
    list [catch {glob goo/* x*z foo?q} msg] $msg
} {1 {no files matched glob patterns "goo/* x*z foo?q"}}
test filename-14.23 {slash globbing} {unixOrPc} {
    glob /
} /
test filename-14.24 {slash globbing} {pcOnly} {
    glob {\\}
} /

# The following tests are only valid for Unix systems.


# On some systems, like AFS, "000" protection doesn't prevent
# access by owner, so the following test is not portable.

catch {exec chmod 000 globTest/a1}
test filename-15.1 {unix specific globbing} {unixOnly nonPortable} {
    string tolower [list [catch {glob globTest/a1/*} msg]  $msg $errorCode]
} {1 {couldn't read directory "globtest/a1": permission denied} {posix eacces {permission denied}}}
test filename-15.2 {unix specific no complain: no errors} {unixOnly nonPortable} {
    glob -nocomplain globTest/a1/*
} {}
test filename-15.3 {unix specific no complain: no errors, good result} \
	{unixOnly nonPortable knownBug} {
    # test fails because if an error occur , the interp's result
    # is reset...
    glob -nocomplain globTest/a2 globTest/a1/* globTest/a3
} {globTest/a2 globTest/a3}

catch {exec chmod 755 globTest/a1}
test filename-15.4 {unix specific no complain: no errors, good result} \
	{unixOnly nonPortable knownBug} {
    # test fails because if an error occurs, the interp's result
    # is reset... or you don't run at scriptics where the
    # outser and welch users exists
    glob -nocomplain ~ouster ~foo ~welch
} {/home/ouster /home/welch}
test filename-15.5 {unix specific globbing} {unixOnly nonPortable} {
    glob ~ouster/.csh*
} "/home/ouster/.cshrc"
catch {close [open globTest/odd\\\[\]*?\{\}name w]}
test filename-15.6 {unix specific globbing} {unixOnly} {
    global env
    set temp $env(HOME)
    set env(HOME) $env(HOME)/globTest/odd\\\[\]*?\{\}name
    set result [list [catch {glob ~} msg] $msg]
    set env(HOME) $temp
    set result
} [list 0 [list [glob ~]/globTest/odd\\\[\]*?\{\}name]]
catch {exec rm -f globTest/odd\\\[\]*?\{\}name}


# The following tests are only valid for Windows systems.


set temp [pwd]
catch {cd c:/}
catch {
    cd c:/
    removeDirectory globTest
    makeDirectory globTest
    close [open globTest/x1.BAT w]
    close [open globTest/y1.Bat w]
    close [open globTest/z1.bat w]
}

test filename-16.1 {windows specific globbing} {pcOnly} {
    lsort [glob globTest/*.bat]
} {globTest/x1.BAT globTest/y1.Bat globTest/z1.bat}
test filename-16.2 {windows specific globbing} {pcOnly} {
    glob c:
} c:
test filename-16.3 {windows specific globbing} {pcOnly} {
    glob c:\\\\
} c:/
test filename-16.4 {windows specific globbing} {pcOnly} {
    glob c:/
} c:/
test filename-16.5 {windows specific globbing} {pcOnly} {
    glob c:*Test
} c:globTest
test filename-16.6 {windows specific globbing} {pcOnly} {
    glob c:\\\\*Test
} c:/globTest
test filename-16.7 {windows specific globbing} {pcOnly} {
    glob c:/*Test
} c:/globTest
test filename-16.8 {windows specific globbing} {pcOnly} {
    lsort [glob c:globTest/*.bat]
} {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
test filename-16.9 {windows specific globbing} {pcOnly} {
    lsort [glob c:/globTest/*.bat]
} {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
test filename-16.10 {windows specific globbing} {pcOnly} {
    lsort [glob c:globTest\\\\*.bat]
} {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
test filename-16.11 {windows specific globbing} {pcOnly} {
    lsort [glob c:\\\\globTest\\\\*.bat]
} {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}

# some tests require a shared C drive

if {[catch {cd //[info hostname]/c}]} {
    set ::tcltest::testConfig(sharedCdrive) 0
} else {
    set ::tcltest::testConfig(sharedCdrive) 1
}

test filename-16.12 {windows specific globbing} {pcOnly sharedCdrive} {
    cd //[info hostname]/c
    removeDirectory globTest
    makeDirectory globTest
    close [open globTest/x1.BAT w]
    close [open globTest/y1.Bat w]
    close [open globTest/z1.bat w]
    glob //[info hostname]/c/*Test
} //[info hostname]/c/globTest
test filename-16.13 {windows specific globbing} {pcOnly sharedCdrive} {
    cd //[info hostname]/c
    removeDirectory globTest
    makeDirectory globTest
    close [open globTest/x1.BAT w]
    close [open globTest/y1.Bat w]
    close [open globTest/z1.bat w]

    glob "\\\\\\\\[info hostname]\\\\c\\\\*Test"

















} //[info hostname]/c/globTest









































# cleanup



file delete -force //[info hostname]/c/globTest














cd $temp

file delete -force globTest

set env(HOME) $oldhome

testsetplatform $platform
catch {unset oldhome platform temp result}
::tcltest::cleanupTests
return












Changes to tests/for-old.test.

8
9
10
11
12
13
14

15


16
17
18
19
20
21
22
23
24
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) for-old.test 1.14 97/01/13 13:42:18



if {[string compare test [info procs test]] == 1} then {source defs}

# Check "for" and its use of continue and break.

catch {unset a i}
test for-old-1.1 {for tests} {
    set a {}
    for {set i 1} {$i<6} {set i [expr $i+1]} {







>
|
>
>
|
<







8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1996 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: for-old.test,v 1.1.2.6 1999/04/02 23:44:38 stanton Exp $

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


# Check "for" and its use of continue and break.

catch {unset a i}
test for-old-1.1 {for tests} {
    set a {}
    for {set i 1} {$i<6} {set i [expr $i+1]} {
60
61
62
63
64
65
66
















test for-old-1.9 {for tests} {
    set a {}
    for {set i 1} {$i<6} {set i [expr $i+1]; if $i==4 break} {
	set a [concat $a $i]
    }
    set a
} {1 2 3}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
test for-old-1.9 {for tests} {
    set a {}
    for {set i 1} {$i<6} {set i [expr $i+1]; if $i==4 break} {
	set a [concat $a $i]
    }
    set a
} {1 2 3}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/for.test.

1
2
3
4
5
6
7
8
9
10
11

12


13
14
15
16
17
18
19
20
21
# Commands covered:  for, continue, break
#
# 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) 1996 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) for.test 1.10 97/07/02 16:40:59



if {[string compare test [info procs test]] == 1} then {source defs}

# Basic "for" operation.

test for-1.1 {TclCompileForCmd: missing initial command} {
    list [catch {for} msg] $msg
} {1 {wrong # args: should be "for start test next command"}}
test for-1.2 {TclCompileForCmd: error in initial command} {











>
|
>
>
|
<







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

17
18
19
20
21
22
23
# Commands covered:  for, continue, break
#
# 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) 1996 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: for.test,v 1.1.2.6 1999/04/02 23:44:38 stanton Exp $

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


# Basic "for" operation.

test for-1.1 {TclCompileForCmd: missing initial command} {
    list [catch {for} msg] $msg
} {1 {wrong # args: should be "for start test next command"}}
test for-1.2 {TclCompileForCmd: error in initial command} {
578
579
580
581
582
583
584
585





















































586






























587
































588







589
590
591
592




































        if [string match GLOBTESTDIR/dir2/* $z] {
            break
        }
    } j
    set j
} {}

# Check "for" and computed command names.




















































































test for-5.1 {for and computed command names} {
































    set j 0







    set z for
    $z {set i 0} {$i<10} {incr i} {set j $i}
    set j
} 9











































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

|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
        if [string match GLOBTESTDIR/dir2/* $z] {
            break
        }
    } j
    set j
} {}

# Basic "for" operation with computed command names.
test for-5.1 {for cmd with computed command names: missing initial command} {
    set z for
    list [catch {$z} msg] $msg
} {1 {wrong # args: should be "for start test next command"}}
test for-5.2 {for cmd with computed command names: error in initial command} {
    set z for
    list [catch {$z {set}} msg] $msg $errorInfo
} {1 {wrong # args: should be "for start test next command"} {wrong # args: should be "for start test next command"
    while executing
"$z {set}"}}
test for-5.3 {for cmd with computed command names: missing test expression} {
    set z for
    catch {$z {set i 0}} msg
    set msg
} {wrong # args: should be "for start test next command"}
test for-5.4 {for cmd with computed command names: error in test expression} {
    set z for
    catch {$z {set i 0} {$i<}} msg
    set errorInfo
} {wrong # args: should be "for start test next command"
    while executing
"$z {set i 0} {$i<}"}
test for-5.5 {for cmd with computed command names: test expression is enclosed in quotes} {
    set z for
    set i 0
    $z {} "$i > 5" {incr i} {}
} {}
test for-5.6 {for cmd with computed command names: missing "next" command} {
    set z for
    catch {$z {set i 0} {$i < 5}} msg
    set msg
} {wrong # args: should be "for start test next command"}
test for-5.7 {for cmd with computed command names: missing command body} {
    set z for
    catch {$z {set i 0} {$i < 5} {incr i}} msg
    set msg
} {wrong # args: should be "for start test next command"}
test for-5.8 {for cmd with computed command names: error executing command body} {
    set z for
    catch {$z {set i 0} {$i < 5} {incr i} {set}} msg
    set errorInfo
} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    ("for" body line 1)
    invoked from within
"$z {set i 0} {$i < 5} {incr i} {set}"}
test for-5.9 {for cmd with computed command names: simple command body} {
    set z for
    set a {}
    $z {set i 1} {$i<6} {set i [expr $i+1]} {
	if $i==4 break
	set a [concat $a $i]
    }
    set a
} {1 2 3}
test for-5.10 {for cmd with computed command names: command body in quotes} {
    set z for
    set a {}
    $z {set i 1} {$i<6} {set i [expr $i+1]} "append a x"
    set a
} {xxxxx}
test for-5.11 {for cmd with computed command names: computed command body} {
    set z for
    catch {unset x1}
    catch {unset bb}
    catch {unset x2}
    set x1 {append a x1; }
    set bb {break}
    set x2 {; append a x2}
    set a {}
    $z {set i 1} {$i<6} {set i [expr $i+1]} $x1$bb$x2
    set a
} {x1}
test for-5.12 {for cmd with computed command names: error in "next" command} {
    set z for
    catch {$z {set i 0} {$i < 5} {set} {set j 4}} msg
    set errorInfo
} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    ("for" loop-end command)
    invoked from within
"$z {set i 0} {$i < 5} {set} {set j 4}"}
test for-5.13 {for cmd with computed command names: long command body} {
    set z for
    set a {}
    $z {set i 1} {$i<6} {set i [expr $i+1]} {
	if $i==4 break
	if $i>5 continue
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
    }
    set a
} {1 2 3}
test for-5.14 {for cmd with computed command names: for command result} {
    set z for
    set a [$z {set i 0} {$i < 5} {incr i} {}]
    set a
} {}
test for-5.15 {for cmd with computed command names: for command result} {
    set z for
    set a [$z {set i 0} {$i < 5} {incr i} {if $i==3 break}]
    set a
} {}

# Test for incorrect "double evaluation" semantics

test for-6.1 {possible delayed substitution of increment command} {knownBug} {
    # Increment should be 5, and lappend should always append 5
    catch {unset a}
    catch {unset i}
    set a 5
    set i {}
    for {set a 1} {$a < 12} "incr a $a" {lappend i $a}
    set i
} {1 6 11}

test for-6.2 {possible delayed substitution of body command} {knownBug} {
    # Increment should be 5, and lappend should always append 5
    set a 5
    set i {}
    for {set a 1} {$a < 12} {incr a $a} "lappend i $a"
    set i
} {5 5 5 5}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/foreach.test.

1
2
3
4
5
6
7
8
9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  foreach, continue, break
#
# 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-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.
#

# SCCS: @(#) foreach.test 1.8 97/08/12 18:19:27



if {[string compare test [info procs test]] == 1} then {source defs}

catch {unset a}
catch {unset x}

# Basic "foreach" operation.

test foreach-1.1 {basic foreach tests} {












>
|
>
>
|
<







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

18
19
20
21
22
23
24
# Commands covered:  foreach, continue, break
#
# 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-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: foreach.test,v 1.1.2.6 1999/04/02 23:44:38 stanton Exp $

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


catch {unset a}
catch {unset x}

# Basic "foreach" operation.

test foreach-1.1 {basic foreach tests} {
204
205
206
207
208
209
210














211
212














} {a b}
test foreach-5.3 {break tests} {catch {break foo} msg} 1
test foreach-5.4 {break tests} {
    catch {break foo} msg
    set msg
} {wrong # args: should be "break"}















catch {unset a}
catch {unset x}





















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


>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
} {a b}
test foreach-5.3 {break tests} {catch {break foo} msg} 1
test foreach-5.4 {break tests} {
    catch {break foo} msg
    set msg
} {wrong # args: should be "break"}

# Test for incorrect "double evaluation" semantics

test foreach-6.1 {delayed substitution of body} {knownBug} {
    proc foo {} {
       set a 0
       foreach a [list 1 2 3] "
           set x $a
       "
       set x
    }
    foo
} {0}

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












Changes to tests/format.test.

1
2
3
4
5
6
7
8
9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  format
#
# 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-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) format.test 1.29 97/09/03 15:51:02



if {[string compare test [info procs test]] == 1} then {source defs}

# The following code is needed because some versions of SCO Unix have
# a round-off error in sprintf which would cause some of the tests to
# fail.  Someday I hope this code shouldn't be necessary (code added
# 9/9/91).

set roundOffBug 0







|




>
|
>
>
|
<







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

18
19
20
21
22
23
24
# Commands covered:  format
#
# 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-1994 The Regents of the University of California.
# Copyright (c) 1994-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: format.test,v 1.1.2.7 1999/04/02 23:44:38 stanton Exp $

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


# The following code is needed because some versions of SCO Unix have
# a round-off error in sprintf which would cause some of the tests to
# fail.  Someday I hope this code shouldn't be necessary (code added
# 9/9/91).

set roundOffBug 0
74
75
76
77
78
79
80







































81







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437

438












} {                abcd This is a very long test string.                    x                    x}
test format-2.3 {string formatting} {
    format "%.10s %.10s %c %.10s" abcd {This is a very long test string.} 120 x
} {abcd This is a  x x}
test format-2.4 {string formatting} {
    format "%s %s %% %c %s" abcd {This is a very long test string.} 120 x
} {abcd This is a very long test string. % x x}















































test format-3.1 {e and f formats} {
    format "%e %e %e %e" 34.2e12 68.514 -.125 -16000. .000053
} {3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
test format-3.2 {e and f formats} {
    format "%20e %20e %20e %20e" 34.2e12 68.514 -.125 -16000. .000053
} {        3.420000e+13         6.851400e+01        -1.250000e-01        -1.600000e+04}
if {!$roundOffBug} {
    test format-3.3 {e and f formats} {
	format "%.1e %.1e %.1e %.1e" 34.2e12 68.514 -.126 -16000. .000053
    } {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
    test format-3.4 {e and f formats} {
	format "%020e %020e %020e %020e" 34.2e12 68.514 -.126 -16000. .000053
    } {000000003.420000e+13 000000006.851400e+01 -00000001.260000e-01 -00000001.600000e+04}
    test format-3.5 {e and f formats} {
	format "%7.1e %7.1e %7.1e %7.1e" 34.2e12 68.514 -.126 -16000. .000053
    } {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
    test format-3.6 {e and f formats} {
	format "%f %f %f %f" 34.2e12 68.514 -.125 -16000. .000053
    } {34200000000000.000000 68.514000 -0.125000 -16000.000000}
}
test format-3.7 {e and f formats} {nonPortable} {
    format "%.4f %.4f %.4f %.4f %.4f" 34.2e12 68.514 -.125 -16000. .000053
} {34200000000000.0000 68.5140 -0.1250 -16000.0000 0.0001}
test format-3.8 {e and f formats} {
    format "%.4e %.5e %.6e" -9.99996 -9.99996 9.99996
} {-1.0000e+01 -9.99996e+00 9.999960e+00}
test format-3.9 {e and f formats} {
    format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
} {-10.0000 -9.99996 9.999960}
test format-3.10 {e and f formats} {
    format "%20f %-20f %020f" -9.99996 -9.99996 9.99996
} {           -9.999960 -9.999960            0000000000009.999960}
test format-3.11 {e and f formats} {
    format "%-020f %020f" -9.99996 -9.99996 9.99996
} {-9.999960            -000000000009.999960}
test format-3.12 {e and f formats} {
    format "%.0e %#.0e" -9.99996 -9.99996 9.99996
} {-1e+01 -1.e+01}
test format-3.13 {e and f formats} {
    format "%.0f %#.0f" -9.99996 -9.99996 9.99996
} {-10 -10.}
test format-3.14 {e and f formats} {
    format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
} {-10.0000 -9.99996 9.999960}
test format-3.15 {e and f formats} {
    format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
} {  1   1   1   1}
test format-3.16 {e and f formats} {
    format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
} {0.0 0.1 0.0 0.0}

test format-4.1 {g-format} {
    format "%.3g" 12341.0
} {1.23e+04}
test format-4.2 {g-format} {
    format "%.3G" 1234.12345
} {1.23E+03}
test format-4.3 {g-format} {
    format "%.3g" 123.412345
} {123}
test format-4.4 {g-format} {
    format "%.3g" 12.3412345
} {12.3}
test format-4.5 {g-format} {
    format "%.3g" 1.23412345
} {1.23}
test format-4.6 {g-format} {
    format "%.3g" 1.23412345
} {1.23}
test format-4.7 {g-format} {
    format "%.3g" .123412345
} {0.123}
test format-4.8 {g-format} {
    format "%.3g" .012341
} {0.0123}
test format-4.9 {g-format} {
    format "%.3g" .0012341
} {0.00123}
test format-4.10 {g-format} {
    format "%.3g" .00012341
} {0.000123}
test format-4.11 {g-format} {
    format "%.3g" .00001234
} {1.23e-05}
test format-4.12 {g-format} {
    format "%.4g" 9999.6
} {1e+04}
test format-4.13 {g-format} {
    format "%.4g" 999.96
} {1000}
test format-4.14 {g-format} {
    format "%.3g" 1.0
} {1}
test format-4.15 {g-format} {
    format "%.3g" .1
} {0.1}
test format-4.16 {g-format} {
    format "%.3g" .01
} {0.01}
test format-4.17 {g-format} {
    format "%.3g" .001
} {0.001}
test format-4.18 {g-format} {
    format "%.3g" .00001
} {1e-05}
test format-4.19 {g-format} {
    format "%#.3g" 1234.0
} {1.23e+03}
test format-4.20 {g-format} {
    format "%#.3G" 9999.5
} {1.00E+04}

test format-5.1 {floating-point zeroes} {
    format "%e %f %g" 0.0 0.0 0.0 0.0
} {0.000000e+00 0.000000 0}
test format-5.2 {floating-point zeroes} {
    format "%.4e %.4f %.4g" 0.0 0.0 0.0 0.0
} {0.0000e+00 0.0000 0}
test format-5.3 {floating-point zeroes} {
    format "%#.4e %#.4f %#.4g" 0.0 0.0 0.0 0.0
} {0.0000e+00 0.0000 0.000}
test format-5.4 {floating-point zeroes} {
    format "%.0e %.0f %.0g" 0.0 0.0 0.0 0.0
} {0e+00 0 0}
test format-5.5 {floating-point zeroes} {
    format "%#.0e %#.0f %#.0g" 0.0 0.0 0.0 0.0
} {0.e+00 0. 0.}
test format-5.6 {floating-point zeroes} {
    format "%3.0f %3.0f %3.0f %3.0f" 0.0 0.0 0.0 0.0
} {  0   0   0   0}
test format-5.7 {floating-point zeroes} {
    format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
} {  1   1   1   1}
test format-5.8 {floating-point zeroes} {
    format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
} {0.0 0.1 0.0 0.0}

test format-6.1 {various syntax features} {
    format "%*.*f" 12 3 12.345678901
} {      12.346}
test format-6.2 {various syntax features} {
    format "%0*.*f" 12 3 12.345678901
} {00000012.346}
test format-6.3 {various syntax features} {
    format "\*\t\\n"
} {*	\n}

test format-7.1 {error conditions} {
    catch format
} 1
test format-7.2 {error conditions} {
    catch format msg
    set msg
} {wrong # args: should be "format formatString ?arg arg ...?"}
test format-7.3 {error conditions} {
    catch {format %*d}
} 1
test format-7.4 {error conditions} {
    catch {format %*d} msg
    set msg
} {not enough arguments for all format specifiers}
test format-7.5 {error conditions} {
    catch {format %*.*f 12}
} 1
test format-7.6 {error conditions} {
    catch {format %*.*f 12} msg
    set msg
} {not enough arguments for all format specifiers}
test format-7.7 {error conditions} {
    catch {format %*.*f 12 3}
} 1
test format-7.8 {error conditions} {
    catch {format %*.*f 12 3} msg
    set msg
} {not enough arguments for all format specifiers}
test format-7.9 {error conditions} {
    list [catch {format %*d x 3} msg] $msg
} {1 {expected integer but got "x"}}
test format-7.10 {error conditions} {
    list [catch {format %*.*f 2 xyz 3} msg] $msg
} {1 {expected integer but got "xyz"}}
test format-7.11 {error conditions} {
    catch {format %d 2a}
} 1
test format-7.12 {error conditions} {
    catch {format %d 2a} msg
    set msg
} {expected integer but got "2a"}
test format-7.13 {error conditions} {
    catch {format %c 2x}
} 1
test format-7.14 {error conditions} {
    catch {format %c 2x} msg
    set msg
} {expected integer but got "2x"}
test format-7.15 {error conditions} {
    catch {format %f 2.1z}
} 1
test format-7.16 {error conditions} {
    catch {format %f 2.1z} msg
    set msg
} {expected floating-point number but got "2.1z"}
test format-7.17 {error conditions} {
    catch {format ab%}
} 1
test format-7.18 {error conditions} {
    catch {format ab% 12} msg
    set msg
} {format string ended in middle of field specifier}
test format-7.19 {error conditions} {
    catch {format %q x}
} 1
test format-7.20 {error conditions} {
    catch {format %q x} msg
    set msg
} {bad field specifier "q"}
test format-7.21 {error conditions} {
    catch {format %d}
} 1
test format-7.22 {error conditions} {
    catch {format %d} msg
    set msg
} {not enough arguments for all format specifiers}
test format-7.23 {error conditions} {
    catch {format "%d %d" 24 xyz} msg
    set msg
} {expected integer but got "xyz"}

test format-8.1 {long result} {
    set a {1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
    format {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG %s %s} $a $a
} {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}

test format-9.1 {"h" format specifier} {nonPortable} {
    format %hd 0xffff
} -1
test format-9.2 {"h" format specifier} {nonPortable} {
    format %hx 0x10fff
} fff
test format-9.3 {"h" format specifier} {nonPortable} {
    format %hd 0x10000
} 0

test format-10.1 {XPG3 %$n specifiers} {
    format {%2$d %1$d} 4 5
} {5 4}
test format-10.2 {XPG3 %$n specifiers} {
    format {%2$d %1$d %1$d %3$d} 4 5 6
} {5 4 4 6}
test format-10.3 {XPG3 %$n specifiers} {
    list [catch {format {%2$d %3$d} 4 5} msg] $msg
} {1 {"%n$" argument index out of range}}
test format-10.4 {XPG3 %$n specifiers} {
    list [catch {format {%2$d %0$d} 4 5 6} msg] $msg
} {1 {"%n$" argument index out of range}}
test format-10.5 {XPG3 %$n specifiers} {
    list [catch {format {%d %1$d} 4 5 6} msg] $msg
} {1 {cannot mix "%" and "%n$" conversion specifiers}}
test format-10.6 {XPG3 %$n specifiers} {
    list [catch {format {%2$d %d} 4 5 6} msg] $msg
} {1 {cannot mix "%" and "%n$" conversion specifiers}}
test format-10.7 {XPG3 %$n specifiers} {
    list [catch {format {%2$d %3d} 4 5 6} msg] $msg
} {1 {cannot mix "%" and "%n$" conversion specifiers}}
test format-10.8 {XPG3 %$n specifiers} {
    format {%2$*d %3$d} 1 10 4
} {         4 4}
test format-10.9 {XPG3 %$n specifiers} {
    format {%2$.*s %4$d} 1 5 abcdefghijklmnop 44
} {abcde 44}
test format-10.10 {XPG3 %$n specifiers} {
    list [catch {format {%2$*d} 4} msg] $msg
} {1 {"%n$" argument index out of range}}
test format-10.11 {XPG3 %$n specifiers} {
    list [catch {format {%2$*d} 4 5} msg] $msg
} {1 {"%n$" argument index out of range}}
test format-10.12 {XPG3 %$n specifiers} {
    list [catch {format {%2$*d} 4 5 6} msg] $msg
} {0 {    6}}

test format-11.1 {negative width specifiers} {
    format "%*d" -47 25
} {25}
test format-12.1 {tcl_precision fuzzy comparison} {
    catch {unset a}
    catch {unset b}
    catch {unset c}
    catch {unset d}
    set a 0.0000000000001
    set b 0.00000000000001
    set c 0.00000000000000001
    set d [expr $a + $b + $c]
    format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
} {0.0000000000 0.000000000000 0.000000000000110 0.00000000000011001}
test format-12.2 {tcl_precision fuzzy comparison} {
    catch {unset a}
    catch {unset b}
    catch {unset c}
    catch {unset d}
    set a 0.000000000001
    set b 0.000000000000005
    set c 0.0000000000000008
    set d [expr $a + $b + $c]
    format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
} {0.0000000000 0.000000000001 0.000000000001006 0.00000000000100580}
test format-12.3 {tcl_precision fuzzy comparison} {
    catch {unset a}
    catch {unset b}
    catch {unset c}
    set a 0.00000000000099
    set b 0.000000000000011
    set c [expr $a + $b]
    format {%0.10f %0.12f %0.15f %0.17f} $c $c $c $c
} {0.0000000000 0.000000000001 0.000000000001001 0.00000000000100100}
test format-12.4 {tcl_precision fuzzy comparison} {
    catch {unset a}
    catch {unset b}
    catch {unset c}
    set a 0.444444444444
    set b 0.33333333333333
    set c [expr $a + $b]
    format {%0.10f %0.12f %0.15f %0.16f} $c $c $c $c
} {0.7777777778 0.777777777777 0.777777777777330 0.7777777777773300}
test format-12.5 {tcl_precision fuzzy comparison} {
    catch {unset a}
    catch {unset b}
    catch {unset c}
    set a 0.444444444444
    set b 0.99999999999999
    set c [expr $a + $b]
    format {%0.10f %0.12f %0.15f} $c $c $c
} {1.4444444444 1.444444444444 1.444444444443990}
test format-13.1 {testing MAX_FLOAT_SIZE for 0 and 1} {
    format {%s} ""
} {}
test format-13.2 {testing MAX_FLOAT_SIZE for 0 and 1} {
    format {%s} "a"
} {a}

set a "0123456789"
set b ""
for {set i 0} {$i < 290} {incr i} {
    append b $a
}
for {set i 290} {$i < 400} {incr i} {
    test format-14.[expr $i -290] {testing MAX_FLOAT_SIZE} {
        format {%s} $b    
    } $b
    append b "x"
}


catch {unset a}
catch {unset b}
catch {unset c}
catch {unset d}

return



















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

>
>
>
>
>
>
>
|


|



|


|


|


|



|


|


|


|


|


|


|


|


|


|



|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|


|



|


|


|


|


|


|


|


|



|


|


|



|


|



|


|



|


|



|


|



|


|


|


|



|


|



|


|



|


|



|


|



|


|



|




|




|


|


|



|


|


|


|


|


|


|


|


|


|


|


|



|

|
|










|










|








|








|








|


|









|





|




>

>
>
>
>
>
>
>
>
>
>
>
>
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
} {                abcd This is a very long test string.                    x                    x}
test format-2.3 {string formatting} {
    format "%.10s %.10s %c %.10s" abcd {This is a very long test string.} 120 x
} {abcd This is a  x x}
test format-2.4 {string formatting} {
    format "%s %s %% %c %s" abcd {This is a very long test string.} 120 x
} {abcd This is a very long test string. % x x}
test format-2.5 {string formatting, embedded nulls} {
    format "%10s" abc\0def
} "   abc\0def"
test format-2.6 {string formatting, international chars} {
    format "%10s" abc\ufeffdef
} "   abc\ufeffdef"
test format-2.6 {string formatting, international chars} {
    format "%.5s" abc\ufeffdef
} "abc\ufeffd"
test format-2.7 {string formatting, international chars} {
    format "foo\ufeffbar%s" baz
} "foo\ufeffbarbaz"
test format-2.8 {string formatting, width} {
    format "a%5sa" f
} "a    fa"
test format-2.8 {string formatting, width} {
    format "a%-5sa" f
} "af    a"
test format-2.8 {string formatting, width} {
    format "a%2sa" foo
} "afooa"
test format-2.8 {string formatting, width} {
    format "a%0sa" foo
} "afooa"
test format-2.8 {string formatting, precision} {
    format "a%.2sa" foobarbaz
} "afoa"
test format-2.8 {string formatting, precision} {
    format "a%.sa" foobarbaz
} "aa"
test format-2.8 {string formatting, precision} {
    list [catch {format "a%.-2sa" foobarbaz} msg] $msg
} {1 {bad field specifier "-"}}
test format-2.8 {string formatting, width and precision} {
    format "a%5.2sa" foobarbaz
} "a   foa"
test format-2.8 {string formatting, width and precision} {
    format "a%5.7sa" foobarbaz
} "afoobarba"

test format-3.1 {Tcl_FormatObjCmd: character formatting} {
    format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 65 65 65 65 65 65 3 65 -4 65
} "|A|A|A|A|A     |     A|  A|A   |"
test format-3.2 {Tcl_FormatObjCmd: international character formatting} {
    format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 0xa2 0x4e4e 0x25a 0xc3 0xff08 0 3 0x6575 -4 0x4e4f
} "|\ua2|\u4e4e|\u25a|\uc3|\uff08     |     \0|  \u6575|\u4e4f   |"

test format-4.1 {e and f formats} {eformat} {
    format "%e %e %e %e" 34.2e12 68.514 -.125 -16000. .000053
} {3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
test format-4.2 {e and f formats} {eformat} {
    format "%20e %20e %20e %20e" 34.2e12 68.514 -.125 -16000. .000053
} {        3.420000e+13         6.851400e+01        -1.250000e-01        -1.600000e+04}
if {!$roundOffBug} {
    test format-4.3 {e and f formats} {eformat} {
	format "%.1e %.1e %.1e %.1e" 34.2e12 68.514 -.126 -16000. .000053
    } {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
    test format-4.4 {e and f formats} {eformat} {
	format "%020e %020e %020e %020e" 34.2e12 68.514 -.126 -16000. .000053
    } {000000003.420000e+13 000000006.851400e+01 -00000001.260000e-01 -00000001.600000e+04}
    test format-4.5 {e and f formats} {eformat} {
	format "%7.1e %7.1e %7.1e %7.1e" 34.2e12 68.514 -.126 -16000. .000053
    } {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
    test format-4.6 {e and f formats} {
	format "%f %f %f %f" 34.2e12 68.514 -.125 -16000. .000053
    } {34200000000000.000000 68.514000 -0.125000 -16000.000000}
}
test format-4.7 {e and f formats} {nonPortable} {
    format "%.4f %.4f %.4f %.4f %.4f" 34.2e12 68.514 -.125 -16000. .000053
} {34200000000000.0000 68.5140 -0.1250 -16000.0000 0.0001}
test format-4.8 {e and f formats} {eformat} {
    format "%.4e %.5e %.6e" -9.99996 -9.99996 9.99996
} {-1.0000e+01 -9.99996e+00 9.999960e+00}
test format-4.9 {e and f formats} {
    format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
} {-10.0000 -9.99996 9.999960}
test format-4.10 {e and f formats} {
    format "%20f %-20f %020f" -9.99996 -9.99996 9.99996
} {           -9.999960 -9.999960            0000000000009.999960}
test format-4.11 {e and f formats} {
    format "%-020f %020f" -9.99996 -9.99996 9.99996
} {-9.999960            -000000000009.999960}
test format-4.12 {e and f formats} {eformat} {
    format "%.0e %#.0e" -9.99996 -9.99996 9.99996
} {-1e+01 -1.e+01}
test format-4.13 {e and f formats} {
    format "%.0f %#.0f" -9.99996 -9.99996 9.99996
} {-10 -10.}
test format-4.14 {e and f formats} {
    format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
} {-10.0000 -9.99996 9.999960}
test format-4.15 {e and f formats} {
    format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
} {  1   1   1   1}
test format-4.16 {e and f formats} {
    format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
} {0.0 0.1 0.0 0.0}

test format-5.1 {g-format} {eformat} {
    format "%.3g" 12341.0
} {1.23e+04}
test format-5.2 {g-format} {eformat} {
    format "%.3G" 1234.12345
} {1.23E+03}
test format-5.3 {g-format} {
    format "%.3g" 123.412345
} {123}
test format-5.4 {g-format} {
    format "%.3g" 12.3412345
} {12.3}
test format-5.5 {g-format} {
    format "%.3g" 1.23412345
} {1.23}
test format-5.6 {g-format} {
    format "%.3g" 1.23412345
} {1.23}
test format-5.7 {g-format} {
    format "%.3g" .123412345
} {0.123}
test format-5.8 {g-format} {
    format "%.3g" .012341
} {0.0123}
test format-5.9 {g-format} {
    format "%.3g" .0012341
} {0.00123}
test format-5.10 {g-format} {
    format "%.3g" .00012341
} {0.000123}
test format-5.11 {g-format} {eformat} {
    format "%.3g" .00001234
} {1.23e-05}
test format-5.12 {g-format} {eformat} {
    format "%.4g" 9999.6
} {1e+04}
test format-5.13 {g-format} {
    format "%.4g" 999.96
} {1000}
test format-5.14 {g-format} {
    format "%.3g" 1.0
} {1}
test format-5.15 {g-format} {
    format "%.3g" .1
} {0.1}
test format-5.16 {g-format} {
    format "%.3g" .01
} {0.01}
test format-5.17 {g-format} {
    format "%.3g" .001
} {0.001}
test format-5.18 {g-format} {eformat} {
    format "%.3g" .00001
} {1e-05}
test format-5.19 {g-format} {eformat} {
    format "%#.3g" 1234.0
} {1.23e+03}
test format-5.20 {g-format} {eformat} {
    format "%#.3G" 9999.5
} {1.00E+04}

test format-6.1 {floating-point zeroes} {eformat} {
    format "%e %f %g" 0.0 0.0 0.0 0.0
} {0.000000e+00 0.000000 0}
test format-6.2 {floating-point zeroes} {eformat} {
    format "%.4e %.4f %.4g" 0.0 0.0 0.0 0.0
} {0.0000e+00 0.0000 0}
test format-6.3 {floating-point zeroes} {eformat} {
    format "%#.4e %#.4f %#.4g" 0.0 0.0 0.0 0.0
} {0.0000e+00 0.0000 0.000}
test format-6.4 {floating-point zeroes} {eformat} {
    format "%.0e %.0f %.0g" 0.0 0.0 0.0 0.0
} {0e+00 0 0}
test format-6.5 {floating-point zeroes} {eformat} {
    format "%#.0e %#.0f %#.0g" 0.0 0.0 0.0 0.0
} {0.e+00 0. 0.}
test format-6.6 {floating-point zeroes} {
    format "%3.0f %3.0f %3.0f %3.0f" 0.0 0.0 0.0 0.0
} {  0   0   0   0}
test format-6.7 {floating-point zeroes} {
    format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
} {  1   1   1   1}
test format-6.8 {floating-point zeroes} {
    format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
} {0.0 0.1 0.0 0.0}

test format-7.1 {various syntax features} {
    format "%*.*f" 12 3 12.345678901
} {      12.346}
test format-7.2 {various syntax features} {
    format "%0*.*f" 12 3 12.345678901
} {00000012.346}
test format-7.3 {various syntax features} {
    format "\*\t\\n"
} {*	\n}

test format-8.1 {error conditions} {
    catch format
} 1
test format-8.2 {error conditions} {
    catch format msg
    set msg
} {wrong # args: should be "format formatString ?arg arg ...?"}
test format-8.3 {error conditions} {
    catch {format %*d}
} 1
test format-8.4 {error conditions} {
    catch {format %*d} msg
    set msg
} {not enough arguments for all format specifiers}
test format-8.5 {error conditions} {
    catch {format %*.*f 12}
} 1
test format-8.6 {error conditions} {
    catch {format %*.*f 12} msg
    set msg
} {not enough arguments for all format specifiers}
test format-8.7 {error conditions} {
    catch {format %*.*f 12 3}
} 1
test format-8.8 {error conditions} {
    catch {format %*.*f 12 3} msg
    set msg
} {not enough arguments for all format specifiers}
test format-8.9 {error conditions} {
    list [catch {format %*d x 3} msg] $msg
} {1 {expected integer but got "x"}}
test format-8.10 {error conditions} {
    list [catch {format %*.*f 2 xyz 3} msg] $msg
} {1 {expected integer but got "xyz"}}
test format-8.11 {error conditions} {
    catch {format %d 2a}
} 1
test format-8.12 {error conditions} {
    catch {format %d 2a} msg
    set msg
} {expected integer but got "2a"}
test format-8.13 {error conditions} {
    catch {format %c 2x}
} 1
test format-8.14 {error conditions} {
    catch {format %c 2x} msg
    set msg
} {expected integer but got "2x"}
test format-8.15 {error conditions} {
    catch {format %f 2.1z}
} 1
test format-8.16 {error conditions} {
    catch {format %f 2.1z} msg
    set msg
} {expected floating-point number but got "2.1z"}
test format-8.17 {error conditions} {
    catch {format ab%}
} 1
test format-8.18 {error conditions} {
    catch {format ab% 12} msg
    set msg
} {format string ended in middle of field specifier}
test format-8.19 {error conditions} {
    catch {format %q x}
} 1
test format-8.20 {error conditions} {
    catch {format %q x} msg
    set msg
} {bad field specifier "q"}
test format-8.21 {error conditions} {
    catch {format %d}
} 1
test format-8.22 {error conditions} {
    catch {format %d} msg
    set msg
} {not enough arguments for all format specifiers}
test format-8.23 {error conditions} {
    catch {format "%d %d" 24 xyz} msg
    set msg
} {expected integer but got "xyz"}

test format-9.1 {long result} {
    set a {1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
    format {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG %s %s} $a $a
} {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}

test format-10.1 {"h" format specifier} {nonPortable} {
    format %hd 0xffff
} -1
test format-10.2 {"h" format specifier} {nonPortable} {
    format %hx 0x10fff
} fff
test format-10.3 {"h" format specifier} {nonPortable} {
    format %hd 0x10000
} 0

test format-11.1 {XPG3 %$n specifiers} {
    format {%2$d %1$d} 4 5
} {5 4}
test format-11.2 {XPG3 %$n specifiers} {
    format {%2$d %1$d %1$d %3$d} 4 5 6
} {5 4 4 6}
test format-11.3 {XPG3 %$n specifiers} {
    list [catch {format {%2$d %3$d} 4 5} msg] $msg
} {1 {"%n$" argument index out of range}}
test format-11.4 {XPG3 %$n specifiers} {
    list [catch {format {%2$d %0$d} 4 5 6} msg] $msg
} {1 {"%n$" argument index out of range}}
test format-11.5 {XPG3 %$n specifiers} {
    list [catch {format {%d %1$d} 4 5 6} msg] $msg
} {1 {cannot mix "%" and "%n$" conversion specifiers}}
test format-11.6 {XPG3 %$n specifiers} {
    list [catch {format {%2$d %d} 4 5 6} msg] $msg
} {1 {cannot mix "%" and "%n$" conversion specifiers}}
test format-11.7 {XPG3 %$n specifiers} {
    list [catch {format {%2$d %3d} 4 5 6} msg] $msg
} {1 {cannot mix "%" and "%n$" conversion specifiers}}
test format-11.8 {XPG3 %$n specifiers} {
    format {%2$*d %3$d} 1 10 4
} {         4 4}
test format-11.9 {XPG3 %$n specifiers} {
    format {%2$.*s %4$d} 1 5 abcdefghijklmnop 44
} {abcde 44}
test format-11.10 {XPG3 %$n specifiers} {
    list [catch {format {%2$*d} 4} msg] $msg
} {1 {"%n$" argument index out of range}}
test format-11.11 {XPG3 %$n specifiers} {
    list [catch {format {%2$*d} 4 5} msg] $msg
} {1 {"%n$" argument index out of range}}
test format-11.12 {XPG3 %$n specifiers} {
    list [catch {format {%2$*d} 4 5 6} msg] $msg
} {0 {    6}}

test format-12.1 {negative width specifiers} {
    format "%*d" -47 25
} {25                                             }
test format-13.1 {tcl_precision fuzzy comparison} {
    catch {unset a}
    catch {unset b}
    catch {unset c}
    catch {unset d}
    set a 0.0000000000001
    set b 0.00000000000001
    set c 0.00000000000000001
    set d [expr $a + $b + $c]
    format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
} {0.0000000000 0.000000000000 0.000000000000110 0.00000000000011001}
test format-13.2 {tcl_precision fuzzy comparison} {
    catch {unset a}
    catch {unset b}
    catch {unset c}
    catch {unset d}
    set a 0.000000000001
    set b 0.000000000000005
    set c 0.0000000000000008
    set d [expr $a + $b + $c]
    format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
} {0.0000000000 0.000000000001 0.000000000001006 0.00000000000100580}
test format-13.3 {tcl_precision fuzzy comparison} {
    catch {unset a}
    catch {unset b}
    catch {unset c}
    set a 0.00000000000099
    set b 0.000000000000011
    set c [expr $a + $b]
    format {%0.10f %0.12f %0.15f %0.17f} $c $c $c $c
} {0.0000000000 0.000000000001 0.000000000001001 0.00000000000100100}
test format-13.4 {tcl_precision fuzzy comparison} {
    catch {unset a}
    catch {unset b}
    catch {unset c}
    set a 0.444444444444
    set b 0.33333333333333
    set c [expr $a + $b]
    format {%0.10f %0.12f %0.15f %0.16f} $c $c $c $c
} {0.7777777778 0.777777777777 0.777777777777330 0.7777777777773300}
test format-13.5 {tcl_precision fuzzy comparison} {
    catch {unset a}
    catch {unset b}
    catch {unset c}
    set a 0.444444444444
    set b 0.99999999999999
    set c [expr $a + $b]
    format {%0.10f %0.12f %0.15f} $c $c $c
} {1.4444444444 1.444444444444 1.444444444443990}
test format-14.1 {testing MAX_FLOAT_SIZE for 0 and 1} {
    format {%s} ""
} {}
test format-14.2 {testing MAX_FLOAT_SIZE for 0 and 1} {
    format {%s} "a"
} {a}

set a "0123456789"
set b ""
for {set i 0} {$i < 290} {incr i} {
    append b $a
}
for {set i 290} {$i < 400} {incr i} {
    test format-15.[expr $i -290] {testing MAX_FLOAT_SIZE} {
        format {%s} $b    
    } $b
    append b "x"
}

# cleanup
catch {unset a}
catch {unset b}
catch {unset c}
catch {unset d}
::tcltest::cleanupTests
return












Changes to tests/get.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
#
# This file contains a collection of tests for the procedures in the
# file tclGet.c.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) get.test 1.7 97/10/31 17:23:00



if {[string compare test [info procs test]] == 1} then {source defs}

test get-1.1 {Tcl_GetInt procedure} {
    set x 44
    incr x { 	  22}
} {66}
test get-1.2 {Tcl_GetInt procedure} {
    set x 44







>




>
|
>
>
|
<







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

18
19
20
21
22
23
24
# Commands covered:  none
#
# This file contains a collection of tests for the procedures in the
# file tclGet.c.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1995-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: get.test,v 1.1.2.5 1999/03/24 02:49:12 hershey Exp $

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


test get-1.1 {Tcl_GetInt procedure} {
    set x 44
    incr x { 	  22}
} {66}
test get-1.2 {Tcl_GetInt procedure} {
    set x 44
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
















} {0 60}
test get-1.6 {Tcl_GetInt procedure} {
    set x 44
    list [catch {incr x {16	 x}} msg] $msg
} {1 {expected integer but got "16	 x"}}

# The following tests are non-portable because they depend on
# word size.  18446744073709551614

if {0x80000000 > 0} {
    test get-1.7 {Tcl_GetInt procedure} {nonPortable unixOnly} {
	set x 44
	list [catch {incr x 18446744073709551616} msg] $msg $errorCode
    } {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
    test get-1.8 {Tcl_GetInt procedure} {nonPortable} {
	set x 0
	list [catch {incr x 18446744073709551614} msg] $msg
    } {0 -2}
    test get-1.9 {Tcl_GetInt procedure} {nonPortable} {
	set x 0
	list [catch {incr x +18446744073709551614} msg] $msg
    } {0 -2}
    test get-1.10 {Tcl_GetInt procedure} {nonPortable} {
	set x 0
	list [catch {incr x -18446744073709551614} msg] $msg
    } {0 2}
} else {
    test get-1.7 {Tcl_GetInt procedure} {nonPortable unixOnly} {
	set x 44
	list [catch {incr x 4294967296} msg] $msg $errorCode
    } {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
    test get-1.8 {Tcl_GetInt procedure} {nonPortable} {
	set x 0
	list [catch {incr x 4294967294} msg] $msg
    } {0 -2}
    test get-1.9 {Tcl_GetInt procedure} {nonPortable} {
	set x 0
	list [catch {incr x +4294967294} msg] $msg
    } {0 -2}
    test get-1.10 {Tcl_GetInt procedure} {nonPortable} {
	set x 0
	list [catch {incr x -4294967294} msg] $msg
    } {0 2}
}

test get-2.1 {Tcl_GetInt procedure} {
    format %g 1.23
} {1.23}
test get-2.2 {Tcl_GetInt procedure} {
    format %g { 	 1.23 	}
} {1.23}
test get-2.3 {Tcl_GetInt procedure} {
    list [catch {format %g clip} msg] $msg
} {1 {expected floating-point number but got "clip"}}
test get-2.4 {Tcl_GetInt procedure} {nonPortable} {
    list [catch {format %g .000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001} msg] $msg $errorCode
} {1 {floating-point value too small to represent} {ARITH UNDERFLOW {floating-point value too small to represent}}}























|


|



|



|



|




|



|



|



|

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
} {0 60}
test get-1.6 {Tcl_GetInt procedure} {
    set x 44
    list [catch {incr x {16	 x}} msg] $msg
} {1 {expected integer but got "16	 x"}}

# The following tests are non-portable because they depend on
# word size.

if {0x80000000 > 0} {
    test get-1.7 {Tcl_GetInt procedure} {
	set x 44
	list [catch {incr x 18446744073709551616} msg] $msg $errorCode
    } {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
    test get-1.8 {Tcl_GetInt procedure} {
	set x 0
	list [catch {incr x 18446744073709551614} msg] $msg
    } {0 -2}
    test get-1.9 {Tcl_GetInt procedure} {
	set x 0
	list [catch {incr x +18446744073709551614} msg] $msg
    } {0 -2}
    test get-1.10 {Tcl_GetInt procedure} {
	set x 0
	list [catch {incr x -18446744073709551614} msg] $msg
    } {0 2}
} else {
    test get-1.7 {Tcl_GetInt procedure} {
	set x 44
	list [catch {incr x 4294967296} msg] $msg $errorCode
    } {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
    test get-1.8 {Tcl_GetInt procedure} {
	set x 0
	list [catch {incr x 4294967294} msg] $msg
    } {0 -2}
    test get-1.9 {Tcl_GetInt procedure} {
	set x 0
	list [catch {incr x +4294967294} msg] $msg
    } {0 -2}
    test get-1.10 {Tcl_GetInt procedure} {
	set x 0
	list [catch {incr x -4294967294} msg] $msg
    } {0 2}
}

test get-2.1 {Tcl_GetInt procedure} {
    format %g 1.23
} {1.23}
test get-2.2 {Tcl_GetInt procedure} {
    format %g { 	 1.23 	}
} {1.23}
test get-2.3 {Tcl_GetInt procedure} {
    list [catch {format %g clip} msg] $msg
} {1 {expected floating-point number but got "clip"}}
test get-2.4 {Tcl_GetInt procedure} {nonPortable} {
    list [catch {format %g .000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001} msg] $msg $errorCode
} {1 {floating-point value too small to represent} {ARITH UNDERFLOW {floating-point value too small to represent}}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/history.test.

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
# Commands covered:  history
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) history.test 1.15 97/08/13 14:37:10


  

if {[catch {history}]} {
    puts stdout "This version of Tcl was built without the history command;\n"
    puts stdout "history tests will be skipped.\n"

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

set num [history nextid]
history keep 3
history add {set a 12345}
history add {set b [format {A test %s} string]}
history add {Another test}

# "history event"








>




>
|
>
>
|
>



>



<
<







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
# Commands covered:  history
#
# 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: history.test,v 1.1.2.6 1999/03/26 19:14:00 hershey Exp $
  
if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

if {[catch {history}]} {
    puts stdout "This version of Tcl was built without the history command;\n"
    puts stdout "history tests will be skipped.\n"
    ::tcltest::cleanupTests
    return
}



set num [history nextid]
history keep 3
history add {set a 12345}
history add {set b [format {A test %s} string]}
history add {Another test}

# "history event"
204
205
206
207
208
209
210
211















# miscellaneous

test history-9.1 {miscellaneous} {catch {history gorp} msg} 1
test history-9.2 {miscellaneous} {
    catch {history gorp} msg
    set msg
} {bad option "gorp": must be add, change, clear, event, info, keep, nextid, or redo}
























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# miscellaneous

test history-9.1 {miscellaneous} {catch {history gorp} msg} 1
test history-9.2 {miscellaneous} {
    catch {history gorp} msg
    set msg
} {bad option "gorp": must be add, change, clear, event, info, keep, nextid, or redo}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/http.test.

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
# Commands covered:  http::config, http::geturl, http::wait, http::reset
#
# This file contains a collection of tests for the http script library.
# 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-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#

# SCCS: @(#) http2.test 1.8 97/08/13 11:16:50



if {[string compare test [info procs test]] == 1} then {source defs}

if {[catch {package require http 2.0}]} {
    if {[info exist http2]} {
	catch {puts stderr "Cannot load http 2.0 package"}
	return
    } else {
	catch {puts stderr "Running http 2.0 tests in slave interp"}
	set interp [interp create http2]
	$interp eval [list set http2 "running"]
	$interp eval [list source [info script]]
	interp delete $interp
	return
    }
}

############### The httpd_ procedures implement a stub http server. ########
proc httpd_init {{port 8015}} {
    socket -server httpdAccept $port
}
proc httpd_log {args} {
    global httpLog
    if {[info exists httpLog] && $httpLog} {
	puts stderr "httpd: [join $args { }]"
    }
}
array set httpdErrors {
    204 {No Content}
    400 {Bad Request}
    404 {Not Found}
    503 {Service Unavailable}
    504 {Service Temporarily Unavailable}
    }

proc httpdError {sock code args} {
    global httpdErrors
    puts $sock "$code $httpdErrors($code)"
    httpd_log "error: [join $args { }]"
}
proc httpdAccept {newsock ipaddr port} {
    global httpd
    upvar #0 httpd$newsock data

    fconfigure $newsock -blocking 0 -translation {auto crlf}
    httpd_log $newsock Connect $ipaddr $port
    set data(ipaddr) $ipaddr
    fileevent $newsock readable [list httpdRead $newsock]
}

# read data from a client request

proc httpdRead { sock } {
    upvar #0 httpd$sock data

    set readCount [gets $sock line]
    if {![info exists data(state)]} {
	if [regexp {(POST|GET|HEAD) ([^?]+)\??([^ ]*) HTTP/1.0} \
		$line x data(proto) data(url) data(query)] {
	    set data(state) mime
	    httpd_log $sock Query $line






	} else {
	    httpdError $sock 400
	    httpd_log $sock Error "bad first line:$line"
	    httpdSockDone $sock
	}
	return
    }

    # string compare $readCount 0 maps -1 to -1, 0 to 0, and > 0 to 1

    set state [string compare $readCount 0],$data(state),$data(proto)
    httpd_log $sock $state
    switch -- $state {
	-1,mime,HEAD	-
	-1,mime,GET	-
	-1,mime,POST	{
	    # gets would block
	    return
	}
	0,mime,HEAD	-
	0,mime,GET	-
	0,query,POST	{ httpdRespond $sock }
	0,mime,POST	{ set data(state) query }
	1,mime,HEAD	-
	1,mime,POST	-
	1,mime,GET	{
	    if [regexp {([^:]+):[ 	]*(.*)}  $line dummy key value] {
		set data(mime,[string tolower $key]) $value
	    }
	}
	1,query,POST	{
	    append data(query) $line
	    httpdRespond $sock
	}
	default {
	    if [eof $sock] {
		httpd_log $sock Error "unexpected eof on <$data(url)> request"
	    } else {
		httpd_log $sock Error "unhandled state <$state> fetching <$data(url)>"
	    }
	    httpdError $sock 404
	    httpdSockDone $sock
	}
    }
}
proc httpdSockDone { sock } {
upvar #0 httpd$sock data
    unset data
    close $sock
}

# Respond to the query.

set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"
proc httpdRespond { sock } {
    global httpd bindata port
    upvar #0 httpd$sock data

    if {[string match *binary* $data(url)]} {
	set html "$bindata[info hostname]:$port$data(url)"
	set type application/octet-stream
    } else {
	set type text/html

	set html "<html><head><title>HTTP/1.0 TEST</title></head><body>
<h1>Hello, World!</h1>
<h2>$data(proto) $data(url)</h2>
"
	if {[info exists data(query)] && [string length $data(query)]} {
	    append html "<h2>Query</h2>\n<dl>\n"
	    foreach {key value} [split $data(query) &=] {
		append html "<dt>$key<dd>$value\n"
	    }
	    append html </dl>\n
	}
	append html </body></html>
    }

    if {$data(proto) == "HEAD"} {
	puts $sock "HTTP/1.0 200 OK"
    } else {
	puts $sock "HTTP/1.0 200 Data follows"
    }
    puts $sock "Date: [clock format [clock clicks]]"
    puts $sock "Content-Type: $type"
    puts $sock "Content-Length: [string length $html]"
    puts $sock ""
    if {$data(proto) != "HEAD"} {
	fconfigure $sock -translation binary
	puts -nonewline $sock $html
    }
    httpd_log $sock Done ""
    httpdSockDone $sock
}
##################### end server ###########################

set port 8010
if [catch {httpd_init $port} listen] {
    puts stderr "Cannot start http server, http test skipped"
    unset port
    return
}



test http-1.1 {http::config} {
    http::config
} {-accept */* -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -useragent {Tcl http client package 2.0}}

test http-1.2 {http::config} {
    http::config -proxyfilter








>





>
|
>
>
|
<



|


|








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

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







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
# Commands covered:  http::config, http::geturl, http::wait, http::reset
#
# This file contains a collection of tests for the http script library.
# 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-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.1.2.8 1999/04/03 01:19:53 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]} {
	catch {puts "Cannot load http 2.0 package"}
	return
    } else {
	catch {puts "Running http 2.0 tests in slave interp"}
	set interp [interp create http2]
	$interp eval [list set http2 "running"]
	$interp eval [list source [info script]]
	interp delete $interp
	return
    }
}


















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]
    testthread send $httpthread {httpd_init $port}
    puts "Running httpd in thread $httpthread"
} else {


    if ![file exists $httpdFile] {



	puts "Cannot read $httpdFile script, http test skipped"

	unset port







	return











    }




















    source $httpdFile














































    if [catch {httpd_init $port} listen] {
	puts "Cannot start http server, http test skipped"
	unset port
	return
    }
}


test http-1.1 {http::config} {
    http::config
} {-accept */* -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -useragent {Tcl http client package 2.0}}

test http-1.2 {http::config} {
    http::config -proxyfilter
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
} {111}
test http-4.11 {http::Event} {
    set token [http::geturl $url -timeout 1 -command {#}]
    http::reset $token
    http::status $token
} {reset}
test http-4.12 {http::Event} {
    set token [http::geturl $url -timeout 1 -command {#}]
    http::wait $token
    http::status $token
} {timeout}

test http-5.1 {http::formatQuery} {
    http::formatQuery name1 value1 name2 "value two"
} {name1=value1&name2=value+two}







|







256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
} {111}
test http-4.11 {http::Event} {
    set token [http::geturl $url -timeout 1 -command {#}]
    http::reset $token
    http::status $token
} {reset}
test http-4.12 {http::Event} {
    set token [http::geturl $url?timeout=10 -timeout 1 -command {#}]
    http::wait $token
    http::status $token
} {timeout}

test http-5.1 {http::formatQuery} {
    http::formatQuery name1 value1 name2 "value two"
} {name1=value1&name2=value+two}
400
401
402
403
404
405
406

407
408





409















    upvar #0 $token data
    set data(body)
} "<html><head><title>HTTP/1.0 TEST</title></head><body>
<h1>Hello, World!</h1>
<h2>GET http://$url</h2>
</body></html>"


unset url
unset port





close $listen






















>


>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    upvar #0 $token data
    set data(body)
} "<html><head><title>HTTP/1.0 TEST</title></head><body>
<h1>Hello, World!</h1>
<h2>GET http://$url</h2>
</body></html>"

# cleanup
unset url
unset port
if {[info exists httpthread]} {
    testthread send -async $httpthread {
	testthread exit
    }
} else {
    close $listen
}
::tcltest::cleanupTests
return












Added tests/httpd.









































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#
# The httpd_ procedures implement a stub http server.
#
# 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.
#
# SCCS: @(#) httpd 1.2 98/02/20 14:51:59

proc httpd_init {{port 8015}} {
    socket -server httpdAccept $port
}
proc httpd_log {args} {
    global httpLog
    if {[info exists httpLog] && $httpLog} {
	puts stderr "httpd: [join $args { }]"
    }
}
array set httpdErrors {
    204 {No Content}
    400 {Bad Request}
    404 {Not Found}
    503 {Service Unavailable}
    504 {Service Temporarily Unavailable}
    }

proc httpdError {sock code args} {
    global httpdErrors
    puts $sock "$code $httpdErrors($code)"
    httpd_log "error: [join $args { }]"
}
proc httpdAccept {newsock ipaddr port} {
    global httpd
    upvar #0 httpd$newsock data

    fconfigure $newsock -blocking 0 -translation {auto crlf}
    httpd_log $newsock Connect $ipaddr $port
    set data(ipaddr) $ipaddr
    fileevent $newsock readable [list httpdRead $newsock]
}

# read data from a client request

proc httpdRead { sock } {
    upvar #0 httpd$sock data

    set readCount [gets $sock line]
    if {![info exists data(state)]} {
	if [regexp {(POST|GET|HEAD) ([^?]+)\??([^ ]*) HTTP/1.0} \
		$line x data(proto) data(url) data(query)] {
	    set data(state) mime
	    httpd_log $sock Query $line
	} else {
	    httpdError $sock 400
	    httpd_log $sock Error "bad first line:$line"
	    httpdSockDone $sock
	}
	return
    }

    # string compare $readCount 0 maps -1 to -1, 0 to 0, and > 0 to 1

    set state [string compare $readCount 0],$data(state),$data(proto)
    httpd_log $sock $state
    switch -- $state {
	-1,mime,HEAD	-
	-1,mime,GET	-
	-1,mime,POST	{
	    # gets would block
	    return
	}
	0,mime,HEAD	-
	0,mime,GET	-
	0,query,POST	{ httpdRespond $sock }
	0,mime,POST	{ set data(state) query }
	1,mime,HEAD	-
	1,mime,POST	-
	1,mime,GET	{
	    if [regexp {([^:]+):[ 	]*(.*)}  $line dummy key value] {
		set data(mime,[string tolower $key]) $value
	    }
	}
	1,query,POST	{
	    append data(query) $line
	    httpdRespond $sock
	}
	default {
	    if [eof $sock] {
		httpd_log $sock Error "unexpected eof on <$data(url)> request"
	    } else {
		httpd_log $sock Error "unhandled state <$state> fetching <$data(url)>"
	    }
	    httpdError $sock 404
	    httpdSockDone $sock
	}
    }
}
proc httpdSockDone { sock } {
upvar #0 httpd$sock data
    unset data
    close $sock
}

# Respond to the query.

proc httpdRespond { sock } {
    global httpd bindata port
    upvar #0 httpd$sock data

    if {[string match *binary* $data(url)]} {
	set html "$bindata[info hostname]:$port$data(url)"
	set type application/octet-stream
    } else {
	set type text/html

	set html "<html><head><title>HTTP/1.0 TEST</title></head><body>
<h1>Hello, World!</h1>
<h2>$data(proto) $data(url)</h2>
"
	if {[info exists data(query)] && [string length $data(query)]} {
	    append html "<h2>Query</h2>\n<dl>\n"
	    foreach {key value} [split $data(query) &=] {
		append html "<dt>$key<dd>$value\n"
	    }
	    append html </dl>\n
	}
	append html </body></html>
    }

    if {$data(proto) == "HEAD"} {
	puts $sock "HTTP/1.0 200 OK"
    } else {
	puts $sock "HTTP/1.0 200 Data follows"
    }
    puts $sock "Date: [clock format [clock clicks]]"
    puts $sock "Content-Type: $type"
    puts $sock "Content-Length: [string length $html]"
    puts $sock ""
    if {$data(proto) != "HEAD"} {
	fconfigure $sock -translation binary
	puts -nonewline $sock $html
    }
    httpd_log $sock Done ""
    httpdSockDone $sock
}


Changes to tests/httpold.test.

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
# Commands covered:  http_config, http_get, http_wait, http_reset
#
# This file contains a collection of tests for the http script library.
# 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-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) http.test 1.12 97/07/29 17:04:12


if {[string compare test [info procs test]] == 1} then {source defs}


if {[catch {package require http 1.0}]} {
    if {[info exist httpold]} {
	catch {puts stderr "Cannot load http 1.0 package"}

	return
    } else {
	catch {puts stderr "Running http 1.0 tests in slave interp"}
	set interp [interp create httpold]
	$interp eval [list set httpold "running"]
	$interp eval [list source [info script]]
	interp delete $interp

	return
    }
}

############### The httpd_ procedures implement a stub http server. ########
proc httpd_init {{port 8015}} {
    socket -server httpdAccept $port
}
proc httpd_log {args} {
    global httpLog
    if {[info exists httpLog] && $httpLog} {
	puts stderr "httpd: [join $args { }]"
    }
}
array set httpdErrors {
    204 {No Content}
    400 {Bad Request}
    404 {Not Found}
    503 {Service Unavailable}








>




|

>
|
|



|
>


|




>











|







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
# Commands covered:  http_config, http_get, http_wait, http_reset
#
# This file contains a collection of tests for the http script library.
# 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-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: httpold.test,v 1.1.2.9 1999/04/07 00:39:10 stanton Exp $

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

if {[catch {package require http 1.0}]} {
    if {[info exist httpold]} {
	catch {puts "Cannot load http 1.0 package"}
	::tcltest::cleanupTests
	return
    } else {
	catch {puts "Running http 1.0 tests in slave interp"}
	set interp [interp create httpold]
	$interp eval [list set httpold "running"]
	$interp eval [list source [info script]]
	interp delete $interp
	::tcltest::cleanupTests
	return
    }
}

############### The httpd_ procedures implement a stub http server. ########
proc httpd_init {{port 8015}} {
    socket -server httpdAccept $port
}
proc httpd_log {args} {
    global httpLog
    if {[info exists httpLog] && $httpLog} {
	puts "httpd: [join $args { }]"
    }
}
array set httpdErrors {
    204 {No Content}
    400 {Bad Request}
    404 {Not Found}
    503 {Service Unavailable}
141
142
143
144
145
146
147








148
149
150
151
152
153
154
<h1>Hello, World!</h1>
<h2>$data(proto) $data(url)</h2>
"
	if {[info exists data(query)] && [string length $data(query)]} {
	    append html "<h2>Query</h2>\n<dl>\n"
	    foreach {key value} [split $data(query) &=] {
		append html "<dt>$key<dd>$value\n"








	    }
	    append html </dl>\n
	}
	append html </body></html>
    }

    if {$data(proto) == "HEAD"} {







>
>
>
>
>
>
>
>







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<h1>Hello, World!</h1>
<h2>$data(proto) $data(url)</h2>
"
	if {[info exists data(query)] && [string length $data(query)]} {
	    append html "<h2>Query</h2>\n<dl>\n"
	    foreach {key value} [split $data(query) &=] {
		append html "<dt>$key<dd>$value\n"
		if {[string compare $key timeout] == 0} {
		    # Simulate a timeout by not responding,
		    # but clean up our socket later.

		    after 50 [list httpdSockDone $sock]
		    httpd_log $sock Noresponse ""
		    return
		}
	    }
	    append html </dl>\n
	}
	append html </body></html>
    }

    if {$data(proto) == "HEAD"} {
167
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
    httpd_log $sock Done ""
    httpdSockDone $sock
}
##################### end server ###########################

set port 8010
if [catch {httpd_init $port} listen] {
    puts stderr "Cannot start http server, http test skipped"
    unset port

    return
}

test http-1.1 {http_config} {
    http_config
} {-accept */* -proxyfilter httpProxyRequired -proxyhost {} -proxyport {} -useragent {Tcl http client package 1.0}}








|

>







179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
    httpd_log $sock Done ""
    httpdSockDone $sock
}
##################### end server ###########################

set port 8010
if [catch {httpd_init $port} listen] {
    puts "Cannot start http server, http test skipped"
    unset port
    ::tcltest::cleanupTests
    return
}

test http-1.1 {http_config} {
    http_config
} {-accept */* -proxyfilter httpProxyRequired -proxyhost {} -proxyport {} -useragent {Tcl http client package 1.0}}

372
373
374
375
376
377
378


379
380
381
382
383
384
385
386
387
388
389
test http-4.11 {httpEvent} {
    set token [http_get $url -timeout 1 -command {#}]
    http_reset $token
    http_status $token
} {reset}
test http-4.12 {httpEvent} {
    update


    set token [http_get $url -timeout 1 -command {#}]
    update
    http_status $token
} {timeout}

test http-5.1 {http_formatQuery} {
    http_formatQuery name1 value1 name2 "value two"
} {name1=value1&name2=value+two}

test http-5.2 {http_formatQuery} {
    http_formatQuery name1 ~bwelch name2 \xa1\xa2\xa2







>
>
|
|
|
|







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
test http-4.11 {httpEvent} {
    set token [http_get $url -timeout 1 -command {#}]
    http_reset $token
    http_status $token
} {reset}
test http-4.12 {httpEvent} {
    update
    set x {}
    after 500 {lappend x ok}
    set token [http_get $url -timeout 1 -command {lappend x fail}]
    vwait x
    list [http_status $token] $x
} {timeout ok}

test http-5.1 {http_formatQuery} {
    http_formatQuery name1 value1 name2 "value two"
} {name1=value1&name2=value+two}

test http-5.2 {http_formatQuery} {
    http_formatQuery name1 ~bwelch name2 \xa1\xa2\xa2
402
403
404
405
406
407
408

409
410
411














    upvar #0 $token data
    set data(body)
} "<html><head><title>HTTP/1.0 TEST</title></head><body>
<h1>Hello, World!</h1>
<h2>GET http://$url</h2>
</body></html>"


unset url
unset port
close $listen





















>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    upvar #0 $token data
    set data(body)
} "<html><head><title>HTTP/1.0 TEST</title></head><body>
<h1>Hello, World!</h1>
<h2>GET http://$url</h2>
</body></html>"

# cleanup
unset url
unset port
close $listen
::tcltest::cleanupTests
return












Changes to tests/if-old.test.

1
2
3
4
5
6
7
8
9
10

11
12
13
14

15


16
17
18
19
20
21
22
23
24
# Commands covered:  if
#
# This file contains the original set of tests for Tcl's if command.
# Since the if command is now compiled, a new set of tests covering
# the new implementation is in the file "if.test". 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-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) if-old.test 1.10 96/10/22 11:33:06



if {[string compare test [info procs test]] == 1} then {source defs}

test if-old-1.1 {taking proper branch} {
    set a {}
    if 0 {set a 1} else {set a 2}
    set a
} 2
test if-old-1.2 {taking proper branch} {










>




>
|
>
>
|
<







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
# Commands covered:  if
#
# This file contains the original set of tests for Tcl's if command.
# Since the if command is now compiled, a new set of tests covering
# the new implementation is in the file "if.test". 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-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: if-old.test,v 1.1.2.5 1999/03/24 02:49:14 hershey Exp $

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


test if-old-1.1 {taking proper branch} {
    set a {}
    if 0 {set a 1} else {set a 2}
    set a
} 2
test if-old-1.2 {taking proper branch} {
150
151
152
153
154
155
156
















} {1 {wrong # args: no script following "else" argument}}
test if-old-4.10 {error conditions} {
    list [catch {if 0 then foo elseif 0 bar els} msg] $msg
} {1 {invalid command name "els"}}
test if-old-4.11 {error conditions} {
    list [catch {if 0 then foo elseif 0 bar else {[error "error in else clause"]}} msg] $msg
} {1 {error in else clause}}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
} {1 {wrong # args: no script following "else" argument}}
test if-old-4.10 {error conditions} {
    list [catch {if 0 then foo elseif 0 bar els} msg] $msg
} {1 {invalid command name "els"}}
test if-old-4.11 {error conditions} {
    list [catch {if 0 then foo elseif 0 bar else {[error "error in else clause"]}} msg] $msg
} {1 {error in else clause}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/if.test.

1
2
3
4
5
6
7

8
9
10
11

12


13
14
15
16
17
18
19
20
21
# Commands covered:  if
#
# 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) 1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) if.test 1.9 97/07/02 16:40:58



if {[string compare test [info procs test]] == 1} then {source defs}

# Basic "if" operation.

catch {unset a}
test if-1.1 {TclCompileIfCmd: missing if/elseif test} {
    list [catch {if} msg] $msg
} {1 {wrong # args: no expression after "if" argument}}







>




>
|
>
>
|
<







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

18
19
20
21
22
23
24
# Commands covered:  if
#
# 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) 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: if.test,v 1.1.2.7 1999/04/02 23:44:38 stanton Exp $

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


# Basic "if" operation.

catch {unset a}
test if-1.1 {TclCompileIfCmd: missing if/elseif test} {
    list [catch {if} msg] $msg
} {1 {wrong # args: no expression after "if" argument}}
491
492
493
494
495
496
497

498


















499


500



501





502
503




504
















































505






















































































































































































































































































































































































































































































































} 4
test if-4.5 {TclCompileIfCmd: return value} {
    if 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
} def

# Check "if" and computed command names.


test if-5.1 {if and computed command names} {


















    set i 0


    set z if



    $z 1 {





        set i 1
    }




    set i
















































} 1





























































































































































































































































































































































































































































































































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

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

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
} 4
test if-4.5 {TclCompileIfCmd: return value} {
    if 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
} def

# Check "if" and computed command names.

catch {unset a}
test if-5.1 {if cmd with computed command names: missing if/elseif test} {
    set z if
    list [catch {$z} msg] $msg
} {1 {wrong # args: no expression after "if" argument}}

test if-5.2 {if cmd with computed command names: error in if/elseif test} {
    set z if
    list [catch {$z {[error "error in condition"]} foo} msg] $msg
} {1 {error in condition}}
test if-5.3 {if cmd with computed command names: error in if/elseif test} {
    set z if
    list [catch {$z {1+}} msg] $msg $errorInfo
} {1 {syntax error in expression "1+"} {syntax error in expression "1+"
    while executing
"$z {1+}"}}
test if-5.4 {if cmd with computed command names: if/elseif test in braces} {
    set z if
    set a {}
    $z {1<2} {set a 1}
    set a
} {1}
test if-5.5 {if cmd with computed command names: if/elseif test not in braces} {
    set z if
    set a {}
    $z 1<2 {set a 1}
    set a
} {1}
test if-5.6 {if cmd with computed command names: multiline test expr} {
    set z if
    set a {}
    $z {($tcl_platform(platform) != "foobar1") && \
	($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4}
    set a
} 3
test if-5.7 {if cmd with computed command names: "then" after if/elseif test} {
    set z if
    set a {}
    $z 4>3 then {set a 1}
    set a
} {1}
test if-5.8 {if cmd with computed command names: keyword other than "then" after if/elseif test} {
    set z if
    set a {}
    catch {$z 1<2 therefore {set a 1}} msg 
    set msg
} {invalid command name "therefore"}
test if-5.9 {if cmd with computed command names: missing "then" body} {
    set z if
    set a {}
    catch {$z 1<2 then} msg 
    set msg
} {wrong # args: no script following "then" argument}
test if-5.10 {if cmd with computed command names: error in "then" body} {
    set z if
    set a {}
    list [catch {$z {$a!="xxx"} then {set}} msg] $msg $errorInfo
} {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    invoked from within
"$z {$a!="xxx"} then {set}"}}
test if-5.11 {if cmd with computed command names: error in "then" body} {
    set z if
    list [catch {$z 2 then {[error "error in then clause"]}} msg] $msg
} {1 {error in then clause}}
test if-5.12 {if cmd with computed command names: "then" body in quotes} {
    set z if
    set a {}
    $z 27>17 "append a x"
    set a
} {x}
test if-5.13 {if cmd with computed command names: computed "then" body} {
    set z if
    catch {unset x1}
    catch {unset x2}
    set a {}
    set x1 {append a x1}
    set x2 {; append a x2}
    set a {}
    $z 1 $x1$x2
    set a
} {x1x2}
test if-5.14 {if cmd with computed command names: taking proper branch} {
    set z if
    set a {}
    $z 1<2 {set a 1}
    set a
} 1
test if-5.15 {if cmd with computed command names: taking proper branch} {
    set z if
    set a {}
    $z 1>2 {set a 1}
    set a
} {}
test if-5.16 {if cmd with computed command names: test jumpFalse instruction replacement after long "then" body} {
    set z if
    catch {unset i}
    set a {}
    $z 1<2 {
	set a 1
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 2
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 3
    }
    set a
} 3
test if-5.17 {if cmd with computed command names: if/elseif test in quotes} {
    set z if
    set a {}
    list [catch {$z {"0 < 3"} {set a 1}} msg] $msg
} {1 {expected boolean value but got "0 < 3"}}


test if-6.1 {if cmd with computed command names: "elseif" after if/elseif test} {
    set z if
    set a {}
    $z 3>4 {set a 1} elseif 1 {set a 2}
    set a
} {2}
# Since "else" is optional, the "elwood" below is treated as a command.
# But then there shouldn't be any additional argument words for the "if".
test if-6.2 {if cmd with computed command names: keyword other than "elseif"} {
    set z if
    set a {}
    catch {$z 1<2 {set a 1} elwood {set a 2}} msg 
    set msg
} {wrong # args: extra words after "else" clause in "if" command}
test if-6.3 {if cmd with computed command names: missing expression after "elseif"} {
    set z if
    set a {}
    catch {$z 1<2 {set a 1} elseif} msg 
    set msg
} {wrong # args: no expression after "elseif" argument}
test if-6.4 {if cmd with computed command names: error in expression after "elseif"} {
    set z if
    set a {}
    list [catch {$z 3>4 {set a 1} elseif {1>}} msg] $msg $errorInfo
} {1 {syntax error in expression "1>"} {syntax error in expression "1>"
    while executing
"$z 3>4 {set a 1} elseif {1>}"}}
test if-6.5 {if cmd with computed command names: test jumpFalse instruction replacement after long "elseif" body} {
    set z if
    catch {unset i}
    set a {}
    $z 1>2 {
	set a 1
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 2
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 3
    } elseif 1<2 then { #; this if arm should be taken
	set a 4
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 5
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 6
    }
    set a
} 6

test if-7.1 {if cmd with computed command names: "else" clause} {
    set z if
    set a {}
    $z 3>4 {set a 1} elseif {$a == "foo"} {set a 2} else {set a 3}
    set a
} 3
# Since "else" is optional, the "elsex" below is treated as a command.
# But then there shouldn't be any additional argument words for the "if".
test if-7.2 {if cmd with computed command names: keyword other than "else"} {
    set z if
    set a {}
    catch {$z 1<2 then {set a 1} elsex {set a 2}} msg 
    set msg
} {wrong # args: extra words after "else" clause in "if" command}
test if-7.3 {if cmd with computed command names: missing body after "else"} {
    set z if
    set a {}
    catch {$z 2<1 {set a 1} else} msg 
    set msg
} {wrong # args: no script following "else" argument}
test if-7.4 {if cmd with computed command names: error compiling body after "else"} {
    set z if
    set a {}
    catch {$z 2<1 {set a 1} else {set}} msg 
    set errorInfo
} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    invoked from within
"$z 2<1 {set a 1} else {set}"}
test if-7.5 {if cmd with computed command names: extra arguments after "else" argument} {
    set z if
    set a {}
    catch {$z 2<1 {set a 1} else {set a 2} or something} msg 
    set msg
} {wrong # args: extra words after "else" clause in "if" command}
# The following test also checks whether contained loops and other
# commands are properly relocated because a short jump must be replaced
# by a "long distance" one.
test if-7.6 {if cmd with computed command names: test jumpFalse instruction replacement after long "else" clause} {
    set z if
    catch {unset i}
    set a {}
    $z 1>2 {
	set a 1
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 2
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 3
    } elseif 1==2 then { #; this if arm should be taken
	set a 4
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 5
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 6
    } else {
	set a 7
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 8
	while {$a != "xxx"} {
	    break;
	    while {$i >= 0} {
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		$z {[string compare $a "bar"] < 0} {
		    set i $i
		    set i [lindex $s $i]
		}
		set i [expr $i-1]
	    }
	}
	set a 9
    }
    set a
} 9

test if-8.1 {if cmd with computed command names: "if" command result} {
    set z if
    set a {}
    set a [$z 3<4 {set i 27}]
    set a
} 27
test if-8.2 {if cmd with computed command names: "if" command result} {
    set z if
    set a {}
    set a [$z 3>4 {set i 27}]
    set a
} {}
test if-8.3 {if cmd with computed command names: "if" command result} {
    set z if
    set a {}
    set a [$z 0 {set i 1} elseif 1 {set i 2}]
    set a
} 2
test if-8.4 {if cmd with computed command names: "if" command result} {
    set z if
    set a {}
    set a [$z 0 {set i 1} elseif 0 {set i 2} elseif 2>5 {set i 3} else {set i 4}]
    set a
} 4
test if-8.5 {if cmd with computed command names: return value} {
    set z if
    $z 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
} def

test if-9.1 {if cmd with namespace qualifiers} {
    ::if {1} {set x 4}
} 4

# Test for incorrect "double evaluation semantics"

test if-10.1 {delayed substitution of then body} {knownBug} {
    set j 0
    if {[incr j] == 1} "
       set result $j
    "
    set result
} {0}
test if-10.2 {delayed substitution of elseif expression} {knownBug} {
    set j 0
    if {[incr j] == 0} {
       set result badthen
    } elseif "$j == 1" {
       set result badelseif
    } else {
       set result ok
    }
    set result
} {ok}
test if-10.3 {delayed substitution of elseif body} {knownBug} {
    set j 0
    if {[incr j] == 0} {
       set result badthen
    } elseif {1} "
       set result $j
    "
    set result
} {0}
test if-10.4 {delayed substitution of else body} {knownBug} {
    set j 0
    if {[incr j] == 0} {
       set result badthen
    } else "
       set result $j
    "
    set result
} {0}
test if-10.5 {substituted control words} {knownBug} {
    set then then; proc then {} {return badthen}
    set else else; proc else {} {return badelse}
    set elseif elseif; proc elseif {} {return badelseif}
    list [catch {if 1 $then {if 0 {} $elseif 1 {if 0 {} $else {list ok}}}} a] $a
} {0 ok}
test if-10.6 {double invocation of variable traces} {knownBug} {
    set iftracecounter 0
    proc iftraceproc {args} {
       upvar #0 iftracecounter counter
       set argc [llength $args]
       set extraargs [lrange $args 0 [expr {$argc - 4}]]
       set name [lindex $args [expr {$argc - 3}]]
       upvar 1 $name var
       if {[incr counter] % 2 == 1} {
           set var "$counter oops [concat $extraargs]"
       } else {
           set var "$counter + [concat $extraargs]"
       }
    }
    trace variable iftracevar r [list iftraceproc 10]
    list [catch {if "$iftracevar + 20" {}} a] $a \
        [catch {if "$iftracevar + 20" {}} b] $b \
        [unset iftracevar iftracecounter]
} {1 {syntax error in expression "1 oops 10 + 20"} 0 {} {}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/incr-old.test.

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16

17

18
19
20
21
22
23
24
# Commands covered:  incr
#
# This file contains the original set of tests for Tcl's incr command.
# Since the incr command is now compiled, a new set of tests covering
# the new implementation is in the file "incr.test". 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-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) incr-old.test 1.11 96/11/19 16:56:23


if {[string compare test [info procs test]] == 1} then {source defs}


catch {unset x}

test incr-old-1.1 {basic incr operation} {
    set x 23
    list [incr x] $x
} {24 24}










>




|

>
|
>







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
# Commands covered:  incr
#
# This file contains the original set of tests for Tcl's incr command.
# Since the incr command is now compiled, a new set of tests covering
# the new implementation is in the file "incr.test". 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-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: incr-old.test,v 1.1.2.5 1999/03/24 02:49:15 hershey Exp $

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

catch {unset x}

test incr-old-1.1 {basic incr operation} {
    set x 23
    list [incr x] $x
} {24 24}
82
83
84
85
86
87
88



89











    list [catch {incr x 1} msg] $msg
} {1 {expected integer but got "+"}}
test incr-old-2.10 {incr errors} {
    set x {20 x}
    list [catch {incr x 1} msg] $msg
} {1 {expected integer but got "20 x"}}




concat {}


















>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    list [catch {incr x 1} msg] $msg
} {1 {expected integer but got "+"}}
test incr-old-2.10 {incr errors} {
    set x {20 x}
    list [catch {incr x 1} msg] $msg
} {1 {expected integer but got "20 x"}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/incr.test.

1
2
3
4
5
6
7

8
9
10
11

12


13
14
15
16
17
18
19
20
21
# Commands covered:  incr
#
# 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) 1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) incr.test 1.9 97/07/02 16:41:32



if {[string compare test [info procs test]] == 1} then {source defs}

# Basic "incr" operation.

catch {unset x}
catch {unset i}

test incr-1.1 {TclCompileIncrCmd: missing variable name} {







>




>
|
>
>
|
<







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

18
19
20
21
22
23
24
# Commands covered:  incr
#
# 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) 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: incr.test,v 1.1.2.5 1999/03/24 02:49:15 hershey Exp $

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


# Basic "incr" operation.

catch {unset x}
catch {unset i}

test incr-1.1 {TclCompileIncrCmd: missing variable name} {
234
235
236
237
238
239
240
241
242
243
244
245
246








































































































































































































































































test incr-1.29 {TclCompileIncrCmd: runtime error, bad variable value} {
    set x "  -  "
    list [catch {incr x 1} msg] $msg
} {1 {expected integer but got "  -  "}}
    
# Check "incr" and computed command names.

test incr-2.1 {incr and computed command names} {
    set i 5
    set z incr
    $z i -1
    set i
} 4















































































































































































































































































|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
test incr-1.29 {TclCompileIncrCmd: runtime error, bad variable value} {
    set x "  -  "
    list [catch {incr x 1} msg] $msg
} {1 {expected integer but got "  -  "}}
    
# Check "incr" and computed command names.

test incr-2.0 {incr and computed command names} {
    set i 5
    set z incr
    $z i -1
    set i
} 4
catch {unset x}
catch {unset i}

test incr-2.1 {incr command (not compiled): missing variable name} {
    set z incr
    list [catch {$z} msg] $msg
} {1 {wrong # args: should be "incr varName ?increment?"}}
test incr-2.2 {incr command (not compiled): simple variable name} {
    set z incr
    set i 10
    list [$z i] $i
} {11 11}
test incr-2.3 {incr command (not compiled): error compiling variable name} {
    set z incr
    set i 10
    catch {$z "i"xxx} msg
    set msg
} {extra characters after close-quote}
test incr-2.4 {incr command (not compiled): simple variable name in quotes} {
    set z incr
    set i 17
    list [$z "i"] $i
} {18 18}
test incr-2.5 {incr command (not compiled): simple variable name in braces} {
    set z incr
    catch {unset {a simple var}}
    set {a simple var} 27
    list [$z {a simple var}] ${a simple var}
} {28 28}
test incr-2.6 {incr command (not compiled): simple array variable name} {
    set z incr
    catch {unset a}
    set a(foo) 37
    list [$z a(foo)] $a(foo)
} {38 38}
test incr-2.7 {incr command (not compiled): non-simple (computed) variable name} {
    set z incr
    set x "i"
    set i 77
    list [$z $x 2] $i
} {79 79}
test incr-2.8 {incr command (not compiled): non-simple (computed) variable name} {
    set z incr
    set x "i"
    set i 77
    list [$z [set x] +2] $i
} {79 79}

test incr-2.9 {incr command (not compiled): increment given} {
    set z incr
    set i 10
    list [$z i +07] $i
} {17 17}
test incr-2.10 {incr command (not compiled): no increment given} {
    set z incr
    set i 10
    list [$z i] $i
} {11 11}

test incr-2.11 {incr command (not compiled): simple global name} {
    proc p {} {
	set z incr
        global i
        set i 54
        $z i
    }
    p
} {55}
test incr-2.12 {incr command (not compiled): simple local name} {
    proc p {} {
	set z incr
        set foo 100
        $z foo
    }
    p
} {101}
test incr-2.13 {incr command (not compiled): simple but new (unknown) local name} {
    proc p {} {
	set z incr
        $z bar
    }
    catch {p} msg
    set msg
} {can't read "bar": no such variable}
test incr-2.14 {incr command (not compiled): simple local name, >255 locals} {
   proc 260locals {} {
        set z incr
        # create 260 locals
        set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
        set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
        set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
        set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
        set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
        set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
        set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
        set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
        set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
        set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
        set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
        set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
        set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
        set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
        set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
        set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
        set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
        set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
        set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
        set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
        set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
        set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
        set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
        set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
        set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
        set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
        set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
        set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
        set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
        set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
        set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
        set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
        set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
        set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
        set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
        set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
        set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
        set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
        set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
        set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
        set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
        set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
        set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
        set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
        set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
        set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
        set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
        set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
        set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
        set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
        set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
        set z5 0; set z6 0; set z7 0; set z8 0; set z9 0
        # now increment the last one (local var index > 255)
        $z z9
    }
    260locals
} {1}
test incr-2.15 {incr command (not compiled): variable is array} {
    set z incr
    catch {unset a}
    set a(foo) 27
    set x [$z a(foo) 11]
    catch {unset a}
    set x
} 38
test incr-2.16 {incr command (not compiled): variable is array, elem substitutions} {
    set z incr
    catch {unset a}
    set i 5
    set a(foo5) 27
    set x [$z a(foo$i) 11]
    catch {unset a}
    set x
} 38

test incr-2.17 {incr command (not compiled): increment given, simple int} {
    set z incr
    set i 5
    $z i 123
} 128
test incr-2.18 {incr command (not compiled): increment given, simple int} {
    set z incr
    set i 5
    $z i -100
} -95
test incr-2.19 {incr command (not compiled): increment given, but erroneous} {
    set z incr
    set i 5
    catch {$z i [set]} msg
    set errorInfo
} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    while compiling
"$z i [set]"}
test incr-2.20 {incr command (not compiled): increment given, in quotes} {
    set z incr
    set i 25
    $z i "-100"
} -75
test incr-2.21 {incr command (not compiled): increment given, in braces} {
    set z incr
    set i 24
    $z i {126}
} 150
test incr-2.22 {incr command (not compiled): increment given, large int} {
    set z incr
    set i 5
    $z i 200000
} 200005
test incr-2.23 {incr command (not compiled): increment given, formatted int != int} {
    set z incr
    set i 25
    $z i 000012345     ;# an octal literal
} 5374
test incr-2.24 {incr command (not compiled): increment given, formatted int != int} {
    set z incr
    set i 25
    catch {$z i 1a} msg
    set msg
} {expected integer but got "1a"}

test incr-2.25 {incr command (not compiled): too many arguments} {
    set z incr
    set i 10
    catch {$z i 10 20} msg
    set msg
} {wrong # args: should be "incr varName ?increment?"}


test incr-2.26 {incr command (not compiled): runtime error, bad variable name} {
    set z incr
    list [catch {$z {"foo}} msg] $msg $errorInfo
} {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
    (reading value of variable to increment)
    invoked from within
"$z {"foo}"}}
test incr-2.27 {incr command (not compiled): runtime error, bad variable name} {
    set z incr
    list [catch {$z [set]} msg] $msg $errorInfo
} {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    while compiling
"$z [set]"}}
test incr-2.28 {incr command (not compiled): runtime error, readonly variable} {
    set z incr
    proc readonly args {error "variable is read-only"}
    set x 123
    trace var x w readonly
    list [catch {$z x 1} msg] $msg $errorInfo
} {1 {can't set "x": variable is read-only} {can't set "x": variable is read-only
    while executing
"$z x 1"}}
catch {unset x}
test incr-2.29 {incr command (not compiled): runtime error, bad variable value} {
    set z incr
    set x "  -  "
    list [catch {$z x 1} msg] $msg
} {1 {expected integer but got "  -  "}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/indexObj.test.

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
# This file is a Tcl script to test out the the procedures in file
# tkIndexObj.c, which implement indexed table lookups.  The tests here
# are organized in the standard fashion for Tcl tests.
#
# 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.
#
# @(#) indexObj.test 1.3 97/06/23 18:23:09

if {[info procs test] != "test"} {
    source defs
}

if {[info commands testindexobj] == {}} {
    puts "This application hasn't been compiled with the \"testindexobj\""
    puts "command, so I can't test Tcl_GetIndexFromObj etc."

    return 
}

test indexObj-1.1 {exact match} {
    testindexobj 1 1 xyz abc def xyz alm
} {2}
test indexObj-1.2 {exact match} {





>




|

|
|





>







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
# This file is a Tcl script to test out the the procedures in file
# tkIndexObj.c, which implement indexed table lookups.  The tests here
# are organized in the standard fashion for Tcl tests.
#
# 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: indexObj.test,v 1.1.2.6 1999/03/26 19:14:01 hershey Exp $

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

if {[info commands testindexobj] == {}} {
    puts "This application hasn't been compiled with the \"testindexobj\""
    puts "command, so I can't test Tcl_GetIndexFromObj etc."
    ::tcltest::cleanupTests
    return 
}

test indexObj-1.1 {exact match} {
    testindexobj 1 1 xyz abc def xyz alm
} {2}
test indexObj-1.2 {exact match} {
62
63
64
65
66
67
68
















} {42}

test indexObj-4.1 {free old internal representation} {
    set x {a b}
    lindex $x 1
    testindexobj 1 1 $x abc def {a b} zzz
} {2}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
} {42}

test indexObj-4.1 {free old internal representation} {
    set x {a b}
    lindex $x 1
    testindexobj 1 1 $x abc def {a b} zzz
} {2}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/info.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15











16
17
18
19
20
21
22
# Commands covered:  info
#
# 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-1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) info.test 1.39 97/08/01 11:10:24



if {[string compare test [info procs test]] == 1} then {source defs}












test info-1.1 {info args option} {
    proc t1 {a bbb c} {return foo}
    info args t1
} {a bbb c}
test info-1.2 {info args option} {
    proc t1 {{a default1} {bbb default2} {c default3} args} {return foo}







|
>




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







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
# Commands covered:  info
#
# 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-1994 The Regents of the University of California.
# Copyright (c) 1994-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: info.test,v 1.1.2.6 1999/03/24 02:49:16 hershey Exp $

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

# Set up namespaces needed to test operation of "info args", "info body",
# "info default", and "info procs" with imported procedures.

catch {namespace delete test_ns_info1 test_ns_info2}

namespace eval test_ns_info1 {
    namespace export *
    proc p {x} {return "x=$x"}
    proc q {{y 27} z} {return "y=$y"}
}


test info-1.1 {info args option} {
    proc t1 {a bbb c} {return foo}
    info args t1
} {a bbb c}
test info-1.2 {info args option} {
    proc t1 {{a default1} {bbb default2} {c default3} args} {return foo}
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
    list [catch {info args set} msg] $msg
} {1 {"set" isn't a procedure}}
test info-1.6 {info args option} {
    proc t1 {a b} {set c 123; set d $c}
    t1 1 2
    info args t1
} {a b}








test info-2.1 {info body option} {
    proc t1 {} {body of t1}
    info body t1
} {body of t1}
test info-2.2 {info body option} {
    list [catch {info body set} msg] $msg
} {1 {"set" isn't a procedure}}
test info-2.3 {info body option} {
    list [catch {info args set 1} msg] $msg
} {1 {wrong # args: should be "info args procname"}}








# "info cmdcount" is no longer accurate for compiled commands! The expected
# result for info-3.1 used to be "3" and is now "1" since the "set"s have
# been compiled away.
test info-3.1 {info cmdcount option} {
    set x [info cmdcount]
    set y 12345
    set z [info cm]
    expr $z-$x
} 1
test info-3.2 {info body option} {
    list [catch {info cmdcount 1} msg] $msg
} {1 {wrong # args: should be "info cmdcount"}}

test info-4.1 {info commands option} {
    proc t1 {} {}
    proc t2 {} {}
    set x " [info commands] "







>
>
>
>
>
>
>











>
>
>
>
>
>
>










|







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
    list [catch {info args set} msg] $msg
} {1 {"set" isn't a procedure}}
test info-1.6 {info args option} {
    proc t1 {a b} {set c 123; set d $c}
    t1 1 2
    info args t1
} {a b}
test info-1.7 {info args option} {
    catch {namespace delete test_ns_info2}
    namespace eval test_ns_info2 {
        namespace import ::test_ns_info1::*
        list [info args p] [info args q]
    }
} {x {y z}}

test info-2.1 {info body option} {
    proc t1 {} {body of t1}
    info body t1
} {body of t1}
test info-2.2 {info body option} {
    list [catch {info body set} msg] $msg
} {1 {"set" isn't a procedure}}
test info-2.3 {info body option} {
    list [catch {info args set 1} msg] $msg
} {1 {wrong # args: should be "info args procname"}}
test info-2.4 {info body option} {
    catch {namespace delete test_ns_info2}
    namespace eval test_ns_info2 {
        namespace import ::test_ns_info1::*
        list [info body p] [info body q]
    }
} {{return "x=$x"} {return "y=$y"}}

# "info cmdcount" is no longer accurate for compiled commands! The expected
# result for info-3.1 used to be "3" and is now "1" since the "set"s have
# been compiled away.
test info-3.1 {info cmdcount option} {
    set x [info cmdcount]
    set y 12345
    set z [info cm]
    expr $z-$x
} 1
test info-3.2 {info cmdcount option} {
    list [catch {info cmdcount 1} msg] $msg
} {1 {wrong # args: should be "info cmdcount"}}

test info-4.1 {info commands option} {
    proc t1 {} {}
    proc t2 {} {}
    set x " [info commands] "
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
catch {rename _t1_ {}}
catch {rename _t2_ {}}
test info-4.5 {info commands option} {
    list [catch {info commands a b} msg] $msg
} {1 {wrong # args: should be "info commands ?pattern?"}}

test info-5.1 {info complete option} {



    info complete ""
} 1
test info-5.2 {info complete option} {
    info complete "  \n"
} 1
test info-5.3 {info complete option} {
    info complete "abc def"
} 1
test info-5.4 {info complete option} {
    info complete "a b c d e f \t\n"
} 1
test info-5.5 {info complete option} {
    info complete {a b c"d}
} 1
test info-5.6 {info complete option} {
    info complete {a b "c d" e}
} 1
test info-5.7 {info complete option} {
    info complete {a b "c d"}
} 1
test info-5.8 {info complete option} {
    info complete {a b "c d"}
} 1
test info-5.9 {info complete option} {
    info complete {a b "c d}
} 0
test info-5.10 {info complete option} {
    info complete {a b "}
} 0
test info-5.11 {info complete option} {
    info complete {a b "cd"xyz}
} 1
test info-5.12 {info complete option} {
    info complete {a b "c $d() d"}
} 1
test info-5.13 {info complete option} {
    info complete {a b "c $dd("}
} 0
test info-5.14 {info complete option} {
    info complete {a b "c \"}
} 0
test info-5.15 {info complete option} {
    info complete {a b "c [d e f]"}
} 1
test info-5.16 {info complete option} {
    info complete {a b "c [d e f] g"}
} 1
test info-5.17 {info complete option} {
    info complete {a b "c [d e f"}
} 0
test info-5.18 {info complete option} {
    info complete {a {b c d} e}
} 1
test info-5.19 {info complete option} {
    info complete {a {b c d}}
} 1
test info-5.20 {info complete option} {
    info complete "a b\{c d"
} 1
test info-5.21 {info complete option} {
    info complete "a b \{c"
} 0
test info-5.22 {info complete option} {
    info complete "a b \{c{ }"
} 0
test info-5.23 {info complete option} {
    info complete "a b {c d e}xxx"
} 1
test info-5.24 {info complete option} {
    info complete "a b {c \\\{d e}xxx"
} 1
test info-5.25 {info complete option} {
    info complete {a b [ab cd ef]}
} 1
test info-5.26 {info complete option} {
    info complete {a b x[ab][cd][ef] gh}
} 1
test info-5.27 {info complete option} {
    info complete {a b x[ab][cd[ef] gh}
} 0
test info-5.28 {info complete option} {
    info complete {a b x[ gh}
} 0
test info-5.29 {info complete option} {
    info complete {[]]]}
} 1
test info-5.30 {info complete option} {
    info complete {abc x$yyy}
} 1
test info-5.31 {info complete option} {
    info complete "abc x\${abc\[\\d} xyz"
} 1
test info-5.32 {info complete option} {
    info complete "abc x\$\{ xyz"
} 0
test info-5.33 {info complete option} {
    info complete {word $a(xyz)}
} 1
test info-5.34 {info complete option} {
    info complete {word $a(}
} 0
test info-5.35 {info complete option} {
    info complete "set a \\\n"
} 0
test info-5.36 {info complete option} {
    info complete "set a \\n "
} 1
test info-5.37 {info complete option} {
    info complete "set a \\"
} 1
test info-5.38 {info complete option} {
    info complete "foo \\\n\{"
} 0
test info-5.39 {info complete option} {
    info complete " # \{"
} 1
test info-5.40 {info complete option} {
    info complete "foo bar;# \{"
} 1
test info-5.41 {info complete option} {
    info complete "a\nb\n# \{\n# \{\nc\n"
} 1
test info-5.42 {info complete option} {
    info complete "#Incomplete comment\\\n"
} 0
test info-5.43 {info complete option} {
    info complete "#Incomplete comment\\\nBut now it's complete.\n"
} 1
test info-5.44 {info complete option} {
    info complete "# Complete comment\\\\\n"
} 1
test info-5.45 {info complete option} {
    info complete "abc\\\n def"
} 1
test info-5.46 {info complete option} {
    info complete "abc\\\n "
} 1
test info-5.47 {info complete option} {
    info complete "abc\\\n"
} 0

test info-6.1 {info default option} {
    proc t1 {a b {c d} {e "long default value"}} {}
    info default t1 a value
} 0
test info-6.2 {info default option} {
    proc t1 {a b {c d} {e "long default value"}} {}







>
>
>
|


|
|

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

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







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
catch {rename _t1_ {}}
catch {rename _t2_ {}}
test info-4.5 {info commands option} {
    list [catch {info commands a b} msg] $msg
} {1 {wrong # args: should be "info commands ?pattern?"}}

test info-5.1 {info complete option} {
    list [catch {info complete} msg] $msg
} {1 {wrong # args: should be "info complete command"}}
test info-5.2 {info complete option} {
    info complete abc
} 1
test info-5.2 {info complete option} {
    info complete "\{abcd "
} 0
test info-5.3 {info complete option} {





















    info complete {# Comment should be complete command}



} 1













































































































test info-6.1 {info default option} {
    proc t1 {a b {c d} {e "long default value"}} {}
    info default t1 a value
} 0
test info-6.2 {info default option} {
    proc t1 {a b {c d} {e "long default value"}} {}
278
279
280
281
282
283
284







285
286
287
288
289
290
291
} {1 {couldn't store default value in variable "a"}}
test info-6.10 {info default option} {
    catch {unset a}
    set a(0) 88
    proc t1 {{a 18} b} {}
    list [catch {info default t1 a a} msg] $msg
} {1 {couldn't store default value in variable "a"}}







catch {unset a}

test info-7.1 {info exists option} {
    set value foo
    info exists value
} 1
catch {unset _nonexistent_}







>
>
>
>
>
>
>







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
} {1 {couldn't store default value in variable "a"}}
test info-6.10 {info default option} {
    catch {unset a}
    set a(0) 88
    proc t1 {{a 18} b} {}
    list [catch {info default t1 a a} msg] $msg
} {1 {couldn't store default value in variable "a"}}
test info-6.11 {info default option} {
    catch {namespace delete test_ns_info2}
    namespace eval test_ns_info2 {
        namespace import ::test_ns_info1::*
        list [info default p x foo] $foo [info default q y bar] $bar
    }
} {0 {} 1 27}
catch {unset a}

test info-7.1 {info exists option} {
    set value foo
    info exists value
} 1
catch {unset _nonexistent_}
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
set tcl_library $savedLibrary

test info-11.1 {info loaded option} {
    list [catch {info loaded a b} msg] $msg
} {1 {wrong # args: should be "info loaded ?interp?"}}
test info-11.2 {info loaded option} {
    list [catch {info loaded {}}] [catch {info loaded gorp} msg] $msg
} {0 1 {couldn't find slave interpreter named "gorp"}}

test info-12.1 {info locals option} {
    set a 22
    proc t1 {x y} {
        set b 13
        set c testing
        global a







|







313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
set tcl_library $savedLibrary

test info-11.1 {info loaded option} {
    list [catch {info loaded a b} msg] $msg
} {1 {wrong # args: should be "info loaded ?interp?"}}
test info-11.2 {info loaded option} {
    list [catch {info loaded {}}] [catch {info loaded gorp} msg] $msg
} {0 1 {could not find interpreter "gorp"}}

test info-12.1 {info locals option} {
    set a 22
    proc t1 {x y} {
        set b 13
        set c testing
        global a
445
446
447
448
449
450
451







452
453
454
455
456
457
458
    proc t1 {lst} {
        foreach $lst $lst {}
        unset lst
        return [info locals]
    }
    lsort [t1 {a b c c d e f}]
} {a b c d e f}








test info-13.1 {info nameofexecutable option} {
    list [catch {info nameofexecutable foo} msg] $msg
} {1 {wrong # args: should be "info nameofexecutable"}}

test info-14.1 {info patchlevel option} {
    set a [info patchlevel]







>
>
>
>
>
>
>







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
    proc t1 {lst} {
        foreach $lst $lst {}
        unset lst
        return [info locals]
    }
    lsort [t1 {a b c c d e f}]
} {a b c d e f}
test info-12.7 {info locals with temporary variables} {
    proc t1 {} {
        foreach a {b c} {}
        info locals
    }
    t1
} {a}

test info-13.1 {info nameofexecutable option} {
    list [catch {info nameofexecutable foo} msg] $msg
} {1 {wrong # args: should be "info nameofexecutable"}}

test info-14.1 {info patchlevel option} {
    set a [info patchlevel]
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
    lsort [info pr _tt*]
} {_tt1 _tt2}
catch {rename _tt1 {}}
catch {rename _tt2 {}}
test info-15.3 {info procs option} {
    list [catch {info procs 2 3} msg] $msg
} {1 {wrong # args: should be "info procs ?pattern?"}}


set self info.test

if {$tcl_platform(os) == "Win32s"} {
    set self info~1.tes
}


test info-16.1 {info script option} {
    list [catch {info script x} msg] $msg
} {1 {wrong # args: should be "info script"}}
test info-16.2 {info script option} {
    file tail [info sc]
} $self
removeFile gorp.info
makeFile "info script\n" gorp.info
test info-16.3 {info script option} {
    list [source gorp.info] [file tail [info script]]
} [list gorp.info $self]
test info-16.4 {resetting "info script" after errors} {
    catch {source ~_nobody_/foo}
    file tail [info script]
} $self
test info-16.5 {resetting "info script" after errors} {
    catch {source _nonexistent_}
    file tail [info script]
} $self
removeFile gorp.info

test info-17.1 {info sharedlibextension option} {
    list [catch {info sharedlibextension foo} msg] $msg
} {1 {wrong # args: should be "info sharedlibextension"}}

test info-18.1 {info tclversion option} {







|
>
|
>
|
|
|
>






|




|



|



|







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
    lsort [info pr _tt*]
} {_tt1 _tt2}
catch {rename _tt1 {}}
catch {rename _tt2 {}}
test info-15.3 {info procs option} {
    list [catch {info procs 2 3} msg] $msg
} {1 {wrong # args: should be "info procs ?pattern?"}}
test info-15.4 {info procs option} {
    catch {namespace delete test_ns_info2}
    namespace eval test_ns_info2 {
        namespace import ::test_ns_info1::*
        proc r {} {}
        list [info procs] [info procs p*]
    }
} {{p q r} p}

test info-16.1 {info script option} {
    list [catch {info script x} msg] $msg
} {1 {wrong # args: should be "info script"}}
test info-16.2 {info script option} {
    file tail [info sc]
} "info.test"
removeFile gorp.info
makeFile "info script\n" gorp.info
test info-16.3 {info script option} {
    list [source gorp.info] [file tail [info script]]
} [list gorp.info info.test]
test info-16.4 {resetting "info script" after errors} {
    catch {source ~_nobody_/foo}
    file tail [info script]
} "info.test"
test info-16.5 {resetting "info script" after errors} {
    catch {source _nonexistent_}
    file tail [info script]
} "info.test"
removeFile gorp.info

test info-17.1 {info sharedlibextension option} {
    list [catch {info sharedlibextension foo} msg] $msg
} {1 {wrong # args: should be "info sharedlibextension"}}

test info-18.1 {info tclversion option} {
554
555
556
557
558
559
560







561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576

















} {xxa xxx1 xxx2}
test info-19.3 {info vars option} {
    lsort [info vars]
} [lsort [info globals]]
test info-19.4 {info vars option} {
    list [catch {info vars a b} msg] $msg
} {1 {wrong # args: should be "info vars ?pattern?"}}








test info-20.1 {miscellaneous error conditions} {
    list [catch {info} msg] $msg
} {1 {wrong # args: should be "info option ?arg arg ...?"}}
test info-20.2 {miscellaneous error conditions} {
    list [catch {info gorp} msg] $msg
} {1 {bad option "gorp": must be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
test info-20.3 {miscellaneous error conditions} {
    list [catch {info c} msg] $msg
} {1 {ambiguous option "c": must be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
test info-20.4 {miscellaneous error conditions} {
    list [catch {info l} msg] $msg
} {1 {ambiguous option "l": must be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
test info-20.5 {miscellaneous error conditions} {
    list [catch {info s} msg] $msg
} {1 {ambiguous option "s": must be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
























>
>
>
>
>
>
>
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
} {xxa xxx1 xxx2}
test info-19.3 {info vars option} {
    lsort [info vars]
} [lsort [info globals]]
test info-19.4 {info vars option} {
    list [catch {info vars a b} msg] $msg
} {1 {wrong # args: should be "info vars ?pattern?"}}
test info-19.5 {info vars with temporary variables} {
    proc t1 {} {
        foreach a {b c} {}
        info vars
    }
    t1
} {a}

test info-20.1 {miscellaneous error conditions} {
    list [catch {info} msg] $msg
} {1 {wrong # args: should be "info option ?arg arg ...?"}}
test info-20.2 {miscellaneous error conditions} {
    list [catch {info gorp} msg] $msg
} {1 {bad option "gorp": must be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
test info-20.3 {miscellaneous error conditions} {
    list [catch {info c} msg] $msg
} {1 {ambiguous option "c": must be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
test info-20.4 {miscellaneous error conditions} {
    list [catch {info l} msg] $msg
} {1 {ambiguous option "l": must be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
test info-20.5 {miscellaneous error conditions} {
    list [catch {info s} msg] $msg
} {1 {ambiguous option "s": must be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}

# cleanup
catch {namespace delete test_ns_info1 test_ns_info2}
::tcltest::cleanupTests
return












Changes to tests/init.test.

1
2
3
4
5
6
7

8
9
10
11
12
13


14
15
16
17
18
19
20
21
22
# Functionality covered: this file contains a collection of tests for the
# auto loading and namespaces.
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) init.test 1.5 97/11/19 18:08:20




if {[string compare test [info procs test]] == 1} then {source defs}

# Clear out any namespaces called test_ns_*
catch {eval namespace delete [namespace children :: test_ns_*]}

# Six cases - white box testing

test init-1.1 {auto_qualify - absolute cmd - namespace} {







>




|

>
>
|
<







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

18
19
20
21
22
23
24
# Functionality covered: this file contains a collection of tests for the
# auto loading and namespaces.
#
# 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: init.test,v 1.1.2.6 1999/04/02 23:44:39 stanton Exp $

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


# Clear out any namespaces called test_ns_*
catch {eval namespace delete [namespace children :: test_ns_*]}

# Six cases - white box testing

test init-1.1 {auto_qualify - absolute cmd - namespace} {
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
} foo


# we use a sub interp and auto_reset and double the tests because there is 2
# places where auto_loading occur (before loading the indexes files and after)

set testInterp [interp create]
interp eval $testInterp [list set VERBOSE $VERBOSE]
interp eval $testInterp [list set TESTS $TESTS]

interp eval $testInterp {


if {[string compare test [info procs test]] == 1} then {source defs}


auto_reset
catch {rename parray {}}

test init-2.0 {load parray - stage 1} {
    set ret [catch {namespace eval ::test {parray}} error]
    rename parray {} ; # remove it, for the next test - that should not fail.
    list $ret $error
} {1 {no value given for parameter "a" to "parray"}}


test init-2.1 {load parray - stage 2} {
    set ret [catch {namespace eval ::test {parray}} error]
    list $ret $error
} {1 {no value given for parameter "a" to "parray"}}


auto_reset
catch {rename ::safe::setLogCmd {}}
#unset auto_index(::safe::setLogCmd)







|
|



>
|
>





|






|







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


# we use a sub interp and auto_reset and double the tests because there is 2
# places where auto_loading occur (before loading the indexes files and after)

set testInterp [interp create]
interp eval $testInterp [list set argv $argv]
interp eval $testInterp [list source [file join $::tcltest::testsDir defs.tcl]]

interp eval $testInterp {

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

auto_reset
catch {rename parray {}}

test init-2.0 {load parray - stage 1} {
    set ret [catch {namespace eval ::tcltest {parray}} error]
    rename parray {} ; # remove it, for the next test - that should not fail.
    list $ret $error
} {1 {no value given for parameter "a" to "parray"}}


test init-2.1 {load parray - stage 2} {
    set ret [catch {namespace eval ::tcltest {parray}} error]
    list $ret $error
} {1 {no value given for parameter "a" to "parray"}}


auto_reset
catch {rename ::safe::setLogCmd {}}
#unset auto_index(::safe::setLogCmd)
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












auto_reset
package require http 2.0
catch {rename ::http::geturl {}}

test init-2.8 {load http::geturl (package)} {
    # 3 ':' on purpose
    set ret [catch {namespace eval ::test {http:::geturl}} error]
    # removing it, for the next test. should not fail.
    rename ::http::geturl {} ; 
    list $ret $error
} {1 {no value given for parameter "url" to "http:::geturl"}}


test init-3.0 {random stuff in the auto_index, should still work} {
    set auto_index(foo:::bar::blah) {
	namespace eval foo {namespace eval bar {proc blah {} {return 1}}}
    }
    foo:::bar::blah
} 1

}


interp delete $testInterp





















|















>

>
>

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

auto_reset
package require http 2.0
catch {rename ::http::geturl {}}

test init-2.8 {load http::geturl (package)} {
    # 3 ':' on purpose
    set ret [catch {namespace eval ::tcltest {http:::geturl}} error]
    # removing it, for the next test. should not fail.
    rename ::http::geturl {} ; 
    list $ret $error
} {1 {no value given for parameter "url" to "http:::geturl"}}


test init-3.0 {random stuff in the auto_index, should still work} {
    set auto_index(foo:::bar::blah) {
	namespace eval foo {namespace eval bar {proc blah {} {return 1}}}
    }
    foo:::bar::blah
} 1

}

# cleanup
interp delete $testInterp
::tcltest::cleanupTests
return












Changes to tests/interp.test.

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
# This file tests the multiple interpreter facility of Tcl
#
# 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) 1995-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) interp.test 1.64 97/09/04 16:02:23



if {[string compare test [info procs test]] == 1} then {source defs}

# The set of hidden commands is platform dependent:

if {"$tcl_platform(platform)" == "macintosh"} {
    set hidden_cmds {beep cd echo exit fconfigure file glob load ls open pwd socket source}
} else {
    set hidden_cmds {cd exec exit fconfigure file glob load open pwd socket source}
}

foreach i [interp slaves] {
  interp delete $i
}

proc equiv {x} {return $x}

# Part 0: Check out options for interp command
test interp-1.1 {options for interp command} {
    list [catch {interp} msg] $msg
} {1 {wrong # args: should be "interp cmd ?arg ...?"}}
test interp-1.2 {options for interp command} {
    list [catch {interp frobox} msg] $msg
} {1 {bad option "frobox": must be alias, aliases, create, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, marktrusted, slaves, share, target, or transfer}}
test interp-1.3 {options for interp command} {
    interp delete
} ""
test interp-1.4 {options for interp command} {
    list [catch {interp delete foo bar} msg] $msg
} {1 {interpreter named "foo" not found}}
test interp-1.5 {options for interp command} {
    list [catch {interp exists foo bar} msg] $msg
} {1 {wrong # args: should be "interp exists ?path?"}}
#
# test interp-0.6 was removed
#
test interp-1.6 {options for interp command} {







>




>
|
>
>
|
<




|

|




















|







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
# This file tests the multiple interpreter facility of Tcl
#
# 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) 1995-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: interp.test,v 1.1.2.14 1999/04/07 02:38:10 hershey Exp $

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


# The set of hidden commands is platform dependent:

if {"$tcl_platform(platform)" == "macintosh"} {
    set hidden_cmds {beep cd echo encoding exit fconfigure file glob load ls open pwd socket source}
} else {
    set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source}
}

foreach i [interp slaves] {
  interp delete $i
}

proc equiv {x} {return $x}

# Part 0: Check out options for interp command
test interp-1.1 {options for interp command} {
    list [catch {interp} msg] $msg
} {1 {wrong # args: should be "interp cmd ?arg ...?"}}
test interp-1.2 {options for interp command} {
    list [catch {interp frobox} msg] $msg
} {1 {bad option "frobox": must be alias, aliases, create, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, marktrusted, slaves, share, target, or transfer}}
test interp-1.3 {options for interp command} {
    interp delete
} ""
test interp-1.4 {options for interp command} {
    list [catch {interp delete foo bar} msg] $msg
} {1 {could not find interpreter "foo"}}
test interp-1.5 {options for interp command} {
    list [catch {interp exists foo bar} msg] $msg
} {1 {wrong # args: should be "interp exists ?path?"}}
#
# test interp-0.6 was removed
#
test interp-1.6 {options for interp command} {
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
    interp create b -safe
} b
test interp-2.6 {basic interpreter creation} {
    interp create d -safe
} d
test interp-2.7 {basic interpreter creation} {
    list [catch {interp create -froboz} msg] $msg
} {1 {bad option "-froboz": should be -safe}}
test interp-2.8 {basic interpreter creation} {
    interp create -- -froboz
} -froboz
test interp-2.9 {basic interpreter creation} {
    interp create -safe -- -froboz1
} -froboz1
test interp-2.10 {basic interpreter creation} {
    interp create {a x1}
    interp create {a x2}
    interp create {a x3} -safe
} {a x3}
test interp-2.11 {anonymous interps vs existing procs} {
    set x [interp create]
    regexp "interp(\[0-9]+)" $x dummy thenum
    interp delete $x
    incr thenum
    proc interp$thenum {} {}
    set x [interp create]
    regexp "interp(\[0-9]+)" $x dummy anothernum
    expr $anothernum - $thenum
} 1    
test interp-2.12 {anonymous interps vs existing procs} {
    set x [interp create -safe]
    regexp "interp(\[0-9]+)" $x dummy thenum
    interp delete $x
    incr thenum
    proc interp$thenum {} {}
    set x [interp create -safe]
    regexp "interp(\[0-9]+)" $x dummy anothernum
    expr $anothernum - $thenum
} 1    
    
foreach i [interp slaves] {







|















<



|





<







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
    interp create b -safe
} b
test interp-2.6 {basic interpreter creation} {
    interp create d -safe
} d
test interp-2.7 {basic interpreter creation} {
    list [catch {interp create -froboz} msg] $msg
} {1 {bad option "-froboz": must be -safe or --}}
test interp-2.8 {basic interpreter creation} {
    interp create -- -froboz
} -froboz
test interp-2.9 {basic interpreter creation} {
    interp create -safe -- -froboz1
} -froboz1
test interp-2.10 {basic interpreter creation} {
    interp create {a x1}
    interp create {a x2}
    interp create {a x3} -safe
} {a x3}
test interp-2.11 {anonymous interps vs existing procs} {
    set x [interp create]
    regexp "interp(\[0-9]+)" $x dummy thenum
    interp delete $x

    proc interp$thenum {} {}
    set x [interp create]
    regexp "interp(\[0-9]+)" $x dummy anothernum
    expr $anothernum > $thenum
} 1    
test interp-2.12 {anonymous interps vs existing procs} {
    set x [interp create -safe]
    regexp "interp(\[0-9]+)" $x dummy thenum
    interp delete $x

    proc interp$thenum {} {}
    set x [interp create -safe]
    regexp "interp(\[0-9]+)" $x dummy anothernum
    expr $anothernum - $thenum
} 1    
    
foreach i [interp slaves] {
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
    interp slaves
} a
test interp-3.8 {testing interp exists and interp slaves} {
    list [catch {interp slaves a b c} msg] $msg
} {1 {wrong # args: should be "interp slaves ?path?"}}
test interp-3.9 {testing interp exists and interp slaves} {
    interp create {a a2} -safe
    interp slaves a
} {a2}
test interp-3.10 {testing interp exists and interp slaves} {
    interp exists {a a2}
} 1

# Part 3: Testing "interp delete"
test interp-3.11 {testing interp delete} {
    interp delete
} ""
test interp-4.1 {testing interp delete} {
    catch {interp create a}
    interp delete a
} ""
test interp-4.2 {testing interp delete} {
    list [catch {interp delete nonexistent} msg] $msg
} {1 {interpreter named "nonexistent" not found}}
test interp-4.3 {testing interp delete} {
    list [catch {interp delete x y z} msg] $msg
} {1 {interpreter named "x" not found}}
test interp-4.4 {testing interp delete} {
    interp delete
} ""
test interp-4.5 {testing interp delete} {
    interp create a
    interp create {a x1}
    interp delete {a x1}
    interp slaves a
} ""
test interp-4.6 {testing interp delete} {
    interp create c1
    interp create c2
    interp create c3
    interp delete c1 c2 c3
} ""
test interp-4.7 {testing interp delete} {
    interp create c1
    interp create c2
    list [catch {interp delete c1 c2 c3} msg] $msg



} {1 {interpreter named "c3" not found}}

foreach i [interp slaves] {
    interp delete $i
}

# Part 4: Consistency checking - all nondeleted interpreters should be
# there:







|
|














|


|







|
|










>
>
>
|







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
    interp slaves
} a
test interp-3.8 {testing interp exists and interp slaves} {
    list [catch {interp slaves a b c} msg] $msg
} {1 {wrong # args: should be "interp slaves ?path?"}}
test interp-3.9 {testing interp exists and interp slaves} {
    interp create {a a2} -safe
    expr {[lsearch [interp slaves a] a2] >= 0}
} 1
test interp-3.10 {testing interp exists and interp slaves} {
    interp exists {a a2}
} 1

# Part 3: Testing "interp delete"
test interp-3.11 {testing interp delete} {
    interp delete
} ""
test interp-4.1 {testing interp delete} {
    catch {interp create a}
    interp delete a
} ""
test interp-4.2 {testing interp delete} {
    list [catch {interp delete nonexistent} msg] $msg
} {1 {could not find interpreter "nonexistent"}}
test interp-4.3 {testing interp delete} {
    list [catch {interp delete x y z} msg] $msg
} {1 {could not find interpreter "x"}}
test interp-4.4 {testing interp delete} {
    interp delete
} ""
test interp-4.5 {testing interp delete} {
    interp create a
    interp create {a x1}
    interp delete {a x1}
    expr {[lsearch [interp slaves a] x1] >= 0}
} 0
test interp-4.6 {testing interp delete} {
    interp create c1
    interp create c2
    interp create c3
    interp delete c1 c2 c3
} ""
test interp-4.7 {testing interp delete} {
    interp create c1
    interp create c2
    list [catch {interp delete c1 c2 c3} msg] $msg
} {1 {could not find interpreter "c3"}}
test interp-4.8 {testing interp delete} {
    list [catch {interp delete {}} msg] $msg
} {1 {cannot delete the current interpreter}}

foreach i [interp slaves] {
    interp delete $i
}

# Part 4: Consistency checking - all nondeleted interpreters should be
# there:
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
test interp-22.5 {testing interp marktrusted} {
    catch {interp delete a}
    interp create a -safe
    interp create {a b}
    catch {a eval {interp marktrusted b}} msg
    interp delete a
    set msg
} {"interp marktrusted" can only be invoked from a trusted interpreter}
test interp-22.6 {testing interp marktrusted} {
    catch {interp delete a}
    interp create a -safe
    interp create {a b}
    catch {a eval {b marktrusted}} msg
    interp delete a
    set msg
} {"b marktrusted" can only be invoked from a trusted interpreter}
test interp-22.7 {testing interp marktrusted} {
    catch {interp delete a}
    interp create a -safe
    set l ""
    lappend l [interp issafe a]
    interp marktrusted a
    interp create {a b}







|







|







1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
test interp-22.5 {testing interp marktrusted} {
    catch {interp delete a}
    interp create a -safe
    interp create {a b}
    catch {a eval {interp marktrusted b}} msg
    interp delete a
    set msg
} {permission denied: safe interpreter cannot mark trusted}
test interp-22.6 {testing interp marktrusted} {
    catch {interp delete a}
    interp create a -safe
    interp create {a b}
    catch {a eval {b marktrusted}} msg
    interp delete a
    set msg
} {permission denied: safe interpreter cannot mark trusted}
test interp-22.7 {testing interp marktrusted} {
    catch {interp delete a}
    interp create a -safe
    set l ""
    lappend l [interp issafe a]
    interp marktrusted a
    interp create {a b}
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
    lappend l [interp hidden a]
    a alias bar {}
    lappend l [interp aliases a]
    lappend l [interp hidden a]
    interp delete a
    set l
} {{} bar {} bar bar {} {}}
test interp-23.2 {testing hiding vs aliases} {pc || unix} {
    catch {interp delete a}
    interp create a -safe
    set l ""
    lappend l [lsort [interp hidden a]]
    a alias bar bar
    lappend l [interp aliases a]
    lappend l [lsort [interp hidden a]]
    a hide bar
    lappend l [interp aliases a]
    lappend l [lsort [interp hidden a]]
    a alias bar {}
    lappend l [interp aliases a]
    lappend l [lsort [interp hidden a]]
    interp delete a
    set l
} {{cd exec exit fconfigure file glob load open pwd socket source} bar {cd exec exit fconfigure file glob load open pwd socket source} bar {bar cd exec exit fconfigure file glob load open pwd socket source} {} {cd exec exit fconfigure file glob load open pwd socket source}} 

test interp-23.3 {testing hiding vs aliases} {macOnly} {
    catch {interp delete a}
    interp create a -safe
    set l ""
    lappend l [lsort [interp hidden a]]
    a alias bar bar







|















|







1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
    lappend l [interp hidden a]
    a alias bar {}
    lappend l [interp aliases a]
    lappend l [interp hidden a]
    interp delete a
    set l
} {{} bar {} bar bar {} {}}
test interp-23.2 {testing hiding vs aliases} {unixOrPc} {
    catch {interp delete a}
    interp create a -safe
    set l ""
    lappend l [lsort [interp hidden a]]
    a alias bar bar
    lappend l [interp aliases a]
    lappend l [lsort [interp hidden a]]
    a hide bar
    lappend l [interp aliases a]
    lappend l [lsort [interp hidden a]]
    a alias bar {}
    lappend l [interp aliases a]
    lappend l [lsort [interp hidden a]]
    interp delete a
    set l
} {{cd encoding exec exit fconfigure file glob load open pwd socket source} bar {cd encoding exec exit fconfigure file glob load open pwd socket source} bar {bar cd encoding exec exit fconfigure file glob load open pwd socket source} {} {cd encoding exec exit fconfigure file glob load open pwd socket source}} 

test interp-23.3 {testing hiding vs aliases} {macOnly} {
    catch {interp delete a}
    interp create a -safe
    set l ""
    lappend l [lsort [interp hidden a]]
    a alias bar bar
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
1971
1972
1973


1974


1975

1976
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
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
    catch {interp delete a}
    interp create a
    a alias exec foo		;# Relies on exec being a string command!
    interp delete a
} ""



# Interps result transmission


test interp-26.1 {result code transmission 1} {knownBug} {



    # This test currently fails ! (only ok/error are passed, not the other




    # codes). Fixing the code is thus needed...  -- dl



    # (the only other acceptable result list would be

    #  {-1 0 1 0 3 4 5} because of the way return -code return(=2) works)
    # test that all the possibles error codes from Tcl get passed


    catch {interp delete a}
    interp create a
    interp eval a {proc ret {code} {return -code $code $code}}
    set res {}
    # use a for so if a return -code break 'escapes' we would notice
    for {set code -1} {$code<=5} {incr code} {
	lappend res [catch {interp eval a ret $code} msg]

































    }
    interp delete a
    set res
} {-1 0 1 2 3 4 5}

test interp-26.2 {result code transmission 2} {knownBug} {
    # This test currently fails ! (error is cleared)






    # Code fixing is needed...  -- dl




    # (the only other acceptable result list would be

    #  {-1 0 1 0 3 4 5} because of the way return -code return(=2) works)


    # test that all the possibles error codes from Tcl get passed

    set interp [interp create];
    proc MyTestAlias {interp args} {
	global aliasTrace;
	lappend aliasTrace $args;
	eval interp invokehidden [list $interp] $args
    }
    foreach c {return} {
	interp hide $interp  $c;
        interp alias $interp $c {} MyTestAlias $interp $c;
    }
    interp eval $interp {proc ret {code} {return -code $code $code}}
    set res {}
    set aliasTrace {}
    for {set code -1} {$code<=5} {incr code} {
	lappend res [catch {interp eval $interp ret $code} msg]
    }
    interp delete $interp;


    list $res


} {-1 0 1 2 3 4 5}


test interp-26.3 {errorInfo transmission : regular interps} {
    set interp [interp create];
    proc MyError {secret} {
	return -code error "msg"
    }
    proc MyTestAlias {interp args} {
	MyError "some secret"
    }
    interp alias $interp test {} MyTestAlias $interp;
    set res [interp eval $interp {catch test;set errorInfo}]
    interp delete $interp;
    set res
} {msg
    while executing
"MyError "some secret""
    (procedure "test" line 2)
    invoked from within
"catch test"}

test interp-26.4 {errorInfo transmission : safe interps} {knownBug} {
    # this test fails because the errorInfo is fully transmitted
    # whether the interp is safe or not. this is maybe a feature
    # and not a bug.

    set interp [interp create -safe];
    proc MyError {secret} {
	return -code error "msg"
    }
    proc MyTestAlias {interp args} {
	MyError "some secret"
    }
    interp alias $interp test {} MyTestAlias $interp;
    set res [interp eval $interp {catch test;set errorInfo}]
    interp delete $interp;
    set res
} {msg
    while executing
"catch test"}

# Interps & Namespaces
test interp-27.1 {interp aliases & namespaces} {
    set i [interp create];
    set aliasTrace {};
    proc tstAlias {args} { 
	global aliasTrace;







>

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


|



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





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










|



|


>
>
|
>
>
|
>

|














|

|

|

|
|
>













|







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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
    catch {interp delete a}
    interp create a
    a alias exec foo		;# Relies on exec being a string command!
    interp delete a
} ""


#
# Interps result transmission
#

test interp-26.1 {result code transmission : interp eval direct} {
    # Test that all the possibles error codes from Tcl get passed up
    # from the slave interp's context to the master, even though the
    # slave nominally thinks the command is running at the root level.
    
    catch {interp delete a}
    interp create a
    set res {}
    # use a for so if a return -code break 'escapes' we would notice
    for {set code -1} {$code<=5} {incr code} {
	lappend res [catch {interp eval a return -code $code} msg]
    }
    interp delete a
    set res
} {-1 0 1 2 3 4 5}


test interp-26.2 {result code transmission : interp eval indirect} {
    # retcode == 2 == return is special
    catch {interp delete a}
    interp create a
    interp eval a {proc retcode {code} {return -code $code ret$code}}
    set res {}
    # use a for so if a return -code break 'escapes' we would notice
    for {set code -1} {$code<=5} {incr code} {
	lappend res [catch {interp eval a retcode $code} msg] $msg
    }
    interp delete a
    set res
} {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}

test interp-26.3 {result code transmission : aliases} {
    # Test that all the possibles error codes from Tcl get passed up
    # from the slave interp's context to the master, even though the
    # slave nominally thinks the command is running at the root level.
    
    catch {interp delete a}
    interp create a
    set res {}
    proc MyTestAlias {code} {
	return -code $code ret$code
    }
    interp alias a Test {} MyTestAlias
    for {set code -1} {$code<=5} {incr code} {
	lappend res [interp eval a [list catch [list Test $code] msg]]
    }
    interp delete a
    set res
} {-1 0 1 2 3 4 5}

test interp-26.4 {result code transmission: invoke hidden direct--bug 1637} \
	{knownBug} {
    # The known bug is that code 2 is returned, not the -code argument
    catch {interp delete a}
    interp create a
    set res {}
    interp hide a return
    for {set code -1} {$code<=5} {incr code} {
	lappend res [catch {interp invokehidden a return -code $code ret$code}]
    }
    interp delete a
    set res
} {-1 0 1 2 3 4 5}

test interp-26.5 {result code transmission: invoke hidden indirect--bug 1637} \
	{knownBug} {
    # The known bug is that the break and continue should raise errors
    # that they are used outside a loop.
    catch {interp delete a}
    interp create a
    set res {}
    interp eval a {proc retcode {code} {return -code $code ret$code}}
    interp hide a retcode
    for {set code -1} {$code<=5} {incr code} {
	lappend res [catch {interp invokehidden a retcode $code} msg] $msg
    }
    interp delete a
    set res
} {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}

test interp-26.6 {result code transmission: all combined--bug 1637} \
	{knownBug} {
    # Test that all the possibles error codes from Tcl get passed
    # In both directions.  This doesn't work.
    set interp [interp create];
    proc MyTestAlias {interp args} {
	global aliasTrace;
	lappend aliasTrace $args;
	eval interp invokehidden [list $interp] $args
    }
    foreach c {return} {
	interp hide $interp  $c;
        interp alias $interp $c {} MyTestAlias $interp $c;
    }
    interp eval $interp {proc ret {code} {return -code $code ret$code}}
    set res {}
    set aliasTrace {}
    for {set code -1} {$code<=5} {incr code} {
	lappend res [catch {interp eval $interp ret $code} msg] $msg
    }
    interp delete $interp;
    set res
} {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}

# Some tests might need to be added to check for difference between
# toplevel and non toplevel evals.

# End of return code transmission section

test interp-26.7 {errorInfo transmission: regular interps} {
    set interp [interp create];
    proc MyError {secret} {
	return -code error "msg"
    }
    proc MyTestAlias {interp args} {
	MyError "some secret"
    }
    interp alias $interp test {} MyTestAlias $interp;
    set res [interp eval $interp {catch test;set errorInfo}]
    interp delete $interp;
    set res
} {msg
    while executing
"MyError "some secret""
    (procedure "MyTestAlias" line 2)
    invoked from within
"test"}

test interp-26.8 {errorInfo transmission: safe interps--bug 1637} {knownBug} {
    # this test fails because the errorInfo is fully transmitted
    # whether the interp is safe or not.  The errorInfo should never
    # report data from the master interpreter because it could
    # contain sensitive information.
    set interp [interp create -safe];
    proc MyError {secret} {
	return -code error "msg"
    }
    proc MyTestAlias {interp args} {
	MyError "some secret"
    }
    interp alias $interp test {} MyTestAlias $interp;
    set res [interp eval $interp {catch test;set errorInfo}]
    interp delete $interp;
    set res
} {msg
    while executing
"test"}

# Interps & Namespaces
test interp-27.1 {interp aliases & namespaces} {
    set i [interp create];
    set aliasTrace {};
    proc tstAlias {args} { 
	global aliasTrace;
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
#     set res [list [interp eval $i {namespace eval test {bar test1}}]]
#     $i hide test::bar;
#     $i alias test::bar mfoo::bar $i;
#     set res [concat $res [interp eval $i {test::bar test2}]];
#     namespace delete mfoo;
#     interp delete $i;
#     set res
# } {{slave bar called (foo-slave) (bar test1) (::test) (::foo) (test1)} {master bar called (foo-master) (::mfoo) (test2)} {slave bar called (foo-slave) (test::bar test2) (::) (::foo) (test2)}}

#test interp-27.8 {hiding, namespaces and integrity} {
#    namespace eval foo {
#	variable v 3;
#	proc bar {} {variable v; set v}
#	# next command would currently generate an unknown command "bar" error.
#	interp hide {} bar;







|







2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
#     set res [list [interp eval $i {namespace eval test {bar test1}}]]
#     $i hide test::bar;
#     $i alias test::bar mfoo::bar $i;
#     set res [concat $res [interp eval $i {test::bar test2}]];
#     namespace delete mfoo;
#     interp delete $i;
#     set res
# } {{slave bar called (foo-slave) (bar test1) (::tcltest) (::foo) (test1)} {master bar called (foo-master) (::mfoo) (test2)} {slave bar called (foo-slave) (test::bar test2) (::) (::foo) (test2)}}

#test interp-27.8 {hiding, namespaces and integrity} {
#    namespace eval foo {
#	variable v 3;
#	proc bar {} {variable v; set v}
#	# next command would currently generate an unknown command "bar" error.
#	interp hide {} bar;
2246
2247
2248
2249
2250
2251
2252

2253
2254






2255




















2256
2257
2258



# more tests needed...

# Interp & stack
#test interp-29.1 {interp and stack (info level)} {
#} {}


}




























foreach i [interp slaves] {
  interp delete $i
}









>


>
>
>
>
>
>

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



>
>
2319
2320
2321
2322
2323
2324
2325
2326
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

# more tests needed...

# Interp & stack
#test interp-29.1 {interp and stack (info level)} {
#} {}

# End of stack-recursion tests
}

# This test dumps core in Tcl 8.0.3!
test interp-30.1 {deletion of aliases inside namespaces} {
    set i [interp create]
    $i alias ns::cmd list
    $i alias ns::cmd {}
} {}

test interp-31.1 {alias invocation scope} {
    proc mySet {varName value} {
	upvar 1 $varName localVar
	set localVar $value
    }

    interp alias {} myNewSet {} mySet
    proc testMyNewSet {value} {
	myNewSet a $value
	return $a
    }
    catch {unset a}
    set result [testMyNewSet "ok"]
    rename testMyNewSet {}
    rename mySet {}
    rename myNewSet {}
    set result
} ok

# cleanup
foreach i [interp slaves] {
  interp delete $i
}
::tcltest::cleanupTests
return

Changes to tests/io.test.

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
# Functionality covered: operation of all IO commands, and all procedures
# defined in generic/tclIO.c.
#
# 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-1994 The Regents of the University of California.
# 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.
#

# SCCS: @(#) io.test 1.131 97/09/22 11:15:05



if {[string compare test [info procs test]] == 1} then {source defs}

if {"[info commands testchannel]" != "testchannel"} {
    puts "Skipping io tests. This application does not seem to have the"
    puts "testchannel command that is needed to run these tests."
    return
}



removeFile test1
removeFile pipe

# set up a long data file for some of the following tests

set f [open longfile w]
fconfigure $f -eofchar {} -translation lf
for { set i 0 } { $i < 100 } { incr i} {
    puts $f "#123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
\#123456789abcdef01
\#"
    }
close $f


set f [open cat w]
puts $f {
    if {$argv == {}} {
	set argv -
    }
    foreach name $argv {
	if {$name == "-"} {
	    set f stdin
	} elseif {[catch {open $name r} f] != 0} {
	    puts stderr $f
	    continue
	}
	while {[eof $f] == 0} {
	    puts -nonewline stdout [read $f]
	}
	if {$f != "stdin"} {
	    close $f

	}
    }


}
close $f


# These tests are disabled until we decide what to do with "unsupported0".
#
#test io-1.7 {unsupported0 command} {
#    removeFile test1
#    set f1 [open iocmd.test]
#    set f2 [open test1 w]
#    unsupported0 $f1 $f2
#    close $f1























































































































































































































































































#    catch {close $f2}


































#    set s1 [file size [info script]]





#    set s2 [file size test1]

#    set x ok






#    if {"$s1" != "$s2"} {







#        set x broken




























#    }







#    set x












#} ok




















#test io-1.8 {unsupported0 command} {

#    removeFile test1



#    set f1 [open [info script]]






#    set f2 [open test1 w]


#    unsupported0 $f1 $f2 40











































#    close $f1




























































































































































































#    close $f2








#    file size test1








#} 40



#test io-1.9 {unsupported0 command} {




#    removeFile test1








#    set f1 [open [info script]]






#    set f2 [open test1 w]


#    unsupported0 $f1 $f2 -1



#    close $f1











































#    close $f2
#    set x ok


























#    set s1 [file size [info script]]
















#    set s2 [file size test1]
















#    if {$s1 != $s2} {












#        set x broken



















#    }








#    set x



#} ok


















































































#test io-1.10 {unsupported0 command} {unixOrPc} {






























#    removeFile pipe


#    removeFile test1








































































#    set f1 [open pipe w]


















#    puts $f1 {puts ready}













#    puts $f1 {gets stdin}






#    puts $f1 {set f1 [open [info script] r]}



#    puts $f1 {puts [read $f1 100]}

#    puts $f1 {close $f1}












#    close $f1





#    set f1 [open "|[list $tcltest pipe]" r+]

















#    gets $f1



#    puts $f1 ready
#    flush $f1


#    set f2 [open test1 w]






#    set c [unsupported0 $f1 $f2 40]


















































































#    catch {close $f1}




#    close $f2



















































































#    set s1 [file size test1]










#    set x ok















#    if {$s1 != "40"} {









#        set x broken














#    }












#    list $c $x












#} {40 ok}















































































































# Test standard handle management. The functions tested are
# Tcl_SetStdChannel and Tcl_GetStdChannel. Incidentally we are
# also testing channel table management.

if {$tcl_platform(platform) == "macintosh"} {
    set consoleFileNames [list console0 console1 console2]
} else {
    set consoleFileNames [lsort [testchannel open]]
}
test io-1.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {
    set l ""
    lappend l [fconfigure stdin -buffering]
    lappend l [fconfigure stdout -buffering]
    lappend l [fconfigure stderr -buffering]
    lappend l [lsort [testchannel open]]
    set l
} [list line line none $consoleFileNames]
test io-1.2 {Tcl_SetStdChannel and Tcl_GetStdChannel} {
    interp create x
    set l ""
    lappend l [x eval {fconfigure stdin -buffering}]
    lappend l [x eval {fconfigure stdout -buffering}]
    lappend l [x eval {fconfigure stderr -buffering}]
    interp delete x
    set l
} {line line none}
test io-1.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} {stdio} {
    set f [open test1 w]
    puts $f {
	close stdin
	close stdout
	close stderr
	set f [open test1 r]
	set f2 [open test2 w]









>




>
|
>
>
|
<






>
>















>
|
<
|
|

|
<
|
<
|
<
|
|
|
<
|

>


>
>
|
<
>



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

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









|







|








|







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

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48

49

50

51
52
53

54
55
56
57
58
59
60
61

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

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


if {"[info commands testchannel]" != "testchannel"} {
    puts "Skipping io tests. This application does not seem to have the"
    puts "testchannel command that is needed to run these tests."
    return
}

::tcltest::saveState

removeFile test1
removeFile pipe

# set up a long data file for some of the following tests

set f [open longfile w]
fconfigure $f -eofchar {} -translation lf
for { set i 0 } { $i < 100 } { incr i} {
    puts $f "#123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
\#123456789abcdef01
\#"
    }
close $f

makeFile {
    set f stdin

    if {$argv != ""} {
	set f [open $argv]
    }
    fconfigure $f -encoding binary -translation lf -blocking 0 -eofchar \x1a

    fconfigure stdout -encoding binary -translation lf -buffering none

    fileevent $f readable "foo $f"

    proc foo {f} {
	set x [read $f]
	catch {puts -nonewline $x}

	if {[eof $f]} {
	    close $f
	    exit 0
	}
    }
    vwait forever
} cat


set thisScript [file join [pwd] [info script]]

# These tests are disabled until we decide what to do with "unsupported0".
#
test io-1.1 {unsupported0 command} {knownBug} {
    removeFile test1
    set f1 [open iocmd.test]
    set f2 [open test1 w]
    unsupported0 $f1 $f2
    close $f1
    catch {close $f2}
    set s1 [file size $thisScript]
    set s2 [file size test1]
    set x ok
    if {"$s1" != "$s2"} {
        set x broken
    }
    set x
} ok
test io-1.2 {unsupported0 command} {knownBug} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    unsupported0 $f1 $f2 40
    close $f1
    close $f2
    file size test1
} 40
test io-1.3 {unsupported0 command} {knownBug} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    unsupported0 $f1 $f2 -1
    close $f1
    close $f2
    set x ok
    set s1 [file size $thisScript]
    set s2 [file size test1]
    if {$s1 != $s2} {
        set x broken
    }
    set x
} ok
test io-1.4 {unsupported0 command} {knownBug unixOrPc} {
    removeFile pipe
    removeFile test1
    set f1 [open pipe w]
    puts $f1 {puts ready}
    puts $f1 {gets stdin}
    puts $f1 {set f1 [open $thisScript r]}
    puts $f1 {puts [read $f1 100]}
    puts $f1 {close $f1}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    gets $f1
    puts $f1 ready
    flush $f1
    set f2 [open test1 w]
    set c [unsupported0 $f1 $f2 40]
    catch {close $f1}
    close $f2
    set s1 [file size test1]
    set x ok
    if {$s1 != "40"} {
        set x broken
    }
    list $c $x
} {40 ok}

proc contents {file} {
    set f [open $file]
    fconfigure $f -translation binary
    set a [read $f]
    close $f
    return $a
}

test io-1.5 {Tcl_WriteChars: CheckChannelErrors} {emptyTest} {
    # no test, need to cause an async error.
} {}
test io-1.6 {Tcl_WriteChars: WriteBytes} {
    set f [open test1 w]
    fconfigure $f -encoding binary
    puts -nonewline $f "a\u4e4d\0"
    close $f
    contents test1
} "a\x4d\x00"
test io-1.7 {Tcl_WriteChars: WriteChars} {
    set f [open test1 w]
    fconfigure $f -encoding shiftjis
    puts -nonewline $f "a\u4e4d\0"
    close $f
    contents test1
} "a\x93\xe1\x00"

test io-2.1 {WriteBytes} {
    # loop until all bytes are written
    
    set f [open test1 w]
    fconfigure $f  -encoding binary -buffersize 16 -translation crlf
    puts $f "abcdefghijklmnopqrstuvwxyz"
    close $f
    contents test1
} "abcdefghijklmnopqrstuvwxyz\r\n"
test io-2.2 {WriteBytes: savedLF > 0} {
    # After flushing buffer, there was a \n left over from the last
    # \n -> \r\n expansion.  It gets stuck at beginning of this buffer.

    set f [open test1 w]
    fconfigure $f -encoding binary -buffersize 16 -translation crlf
    puts -nonewline $f "123456789012345\n12"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "123456789012345\r" "123456789012345\r\n12"]
test io-2.3 {WriteBytes: flush on line} {
    # Tcl "line" buffering has weird behavior: if current buffer contains
    # a \n, entire buffer gets flushed.  Logical behavior would be to flush
    # only up to the \n.
    
    set f [open test1 w]
    fconfigure $f -encoding binary -buffering line -translation crlf
    puts -nonewline $f "\n12"
    set x [contents test1]
    close $f
    set x
} "\r\n12"
test io-2.4 {WriteBytes: reset sawLF after each buffer} {
    set f [open test1 w]
     fconfigure $f -encoding binary -buffering line -translation lf \
	     -buffersize 16
    puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]

test io-3.1 {WriteChars: compatibility with WriteBytes} {
    # loop until all bytes are written
    
    set f [open test1 w]
    fconfigure $f -encoding ascii -buffersize 16 -translation crlf
    puts $f "abcdefghijklmnopqrstuvwxyz"
    close $f
    contents test1
} "abcdefghijklmnopqrstuvwxyz\r\n"
test io-3.2 {WriteChars: compatibility with WriteBytes: savedLF > 0} {
    # After flushing buffer, there was a \n left over from the last
    # \n -> \r\n expansion.  It gets stuck at beginning of this buffer.

    set f [open test1 w]
    fconfigure $f -encoding ascii -buffersize 16 -translation crlf
    puts -nonewline $f "123456789012345\n12"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "123456789012345\r" "123456789012345\r\n12"]
test io-3.3 {WriteChars: compatibility with WriteBytes: flush on line} {
    # Tcl "line" buffering has weird behavior: if current buffer contains
    # a \n, entire buffer gets flushed.  Logical behavior would be to flush
    # only up to the \n.
    
    set f [open test1 w]
    fconfigure $f -encoding ascii -buffering line -translation crlf
    puts -nonewline $f "\n12"
    set x [contents test1]
    close $f
    set x
} "\r\n12"
test io-3.4 {WriteChars: loop over stage buffer} {
    # stage buffer maps to more than can be queued at once.

    set f [open test1 w]
    fconfigure $f -encoding jis0208 -buffersize 16 
    puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "!)!)!)!)!)!)!)!)" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
test io-3.5 {WriteChars: saved != 0} {
    # Bytes produced by UtfToExternal from end of last channel buffer
    # had to be moved to beginning of next channel buffer to preserve
    # requested buffersize.

    set f [open test1 w]
    fconfigure $f -encoding jis0208 -buffersize 17 
    puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
test io-3.6 {WriteChars: (stageRead + dstWrote == 0)} {
    # One incomplete UTF-8 character at end of staging buffer.  Backup
    # in src to the beginning of that UTF-8 character and try again.
    #
    # Translate the first 16 bytes, produce 14 bytes of output, 2 left over
    # (first two bytes of \uff21 in UTF-8).  Given those two bytes try
    # translating them again, find that no bytes are read produced, and break
    # to outer loop where those two bytes will have the remaining 4 bytes
    # (the last byte of \uff21 plus the all of \uff22) appended.

    set f [open test1 w]
    fconfigure $f -encoding shiftjis -buffersize 16
    puts -nonewline $f "12345678901234\uff21\uff22"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "12345678901234\x82\x60" "12345678901234\x82\x60\x82\x61"]
test io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} {
    # When translating UTF-8 to external, the produced bytes went past end
    # of the channel buffer.  This is done purpose -- we then truncate the
    # bytes at the end of the partial character to preserve the requested
    # blocksize on flush.  The truncated bytes are moved to the beginning
    # of the next channel buffer.

    set f [open test1 w]
    fconfigure $f -encoding jis0208 -buffersize 17 
    puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
test io-3.8 {WriteChars: reset sawLF after each buffer} {
    set f [open test1 w]
    fconfigure $f -encoding ascii -buffering line -translation lf \
	     -buffersize 16
    puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]

test io-4.1 {TranslateOutputEOL: lf} {
    # search for \n

    set f [open test1 w]
    fconfigure $f -buffering line -translation lf
    puts $f "abcde"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "abcde\n" "abcde\n"]
test io-4.2 {TranslateOutputEOL: cr} {
    # search for \n, replace with \r

    set f [open test1 w]
    fconfigure $f -buffering line -translation cr
    puts $f "abcde"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "abcde\r" "abcde\r"]
test io-4.3 {TranslateOutputEOL: crlf} {
    # simple case: search for \n, replace with \r

    set f [open test1 w]
    fconfigure $f -buffering line -translation crlf
    puts $f "abcde"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "abcde\r\n" "abcde\r\n"]
test io-4.4 {TranslateOutputEOL: crlf} {
    # keep storing more bytes in output buffer until output buffer is full.
    # We have 13 bytes initially that would turn into 18 bytes.  Fill
    # dest buffer while (dstEnd < dstMax).

    set f [open test1 w]
    fconfigure $f -translation crlf -buffersize 16
    puts -nonewline $f "1234567\n\n\n\n\nA"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "1234567\r\n\r\n\r\n\r\n\r" "1234567\r\n\r\n\r\n\r\n\r\nA"]
test io-4.5 {TranslateOutputEOL: crlf} {
    # Check for overflow of the destination buffer

    set f [open test1 w]
    fconfigure $f -translation crlf -buffersize 12
    puts -nonewline $f "12345678901\n456789012345678901234"
    close $f
    set x [contents test1]
} "12345678901\r\n456789012345678901234"

test io-5.1 {CheckFlush: not full} {
    set f [open test1 w]
    fconfigure $f 
    puts -nonewline $f "12345678901234567890"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "" "12345678901234567890"]
test io-5.2 {CheckFlush: full} {
    set f [open test1 w]
    fconfigure $f -buffersize 16
    puts -nonewline $f "12345678901234567890"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "1234567890123456" "12345678901234567890"]
test io-5.3 {CheckFlush: not line} {
    set f [open test1 w]
    fconfigure $f -buffering line
    puts -nonewline $f "12345678901234567890"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "" "12345678901234567890"]
test io-5.4 {CheckFlush: line} {
    set f [open test1 w]
    fconfigure $f -buffering line -translation lf -encoding ascii
    puts -nonewline $f "1234567890\n1234567890"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "1234567890\n1234567890" "1234567890\n1234567890"]
test io-5.5 {CheckFlush: none} {
    set f [open test1 w]
    fconfigure $f -buffering none
    puts -nonewline $f "1234567890"
    set x [list [contents test1]]
    close $f
    lappend x [contents test1]
} [list "1234567890" "1234567890"]

test io-6.1 {Tcl_GetsObj: working} {
    set f [open test1 w]
    puts $f "foo\nboo"
    close $f
    set f [open test1]
    set x [gets $f]
    close $f
    set x
} {foo}
test io-6.2 {Tcl_GetsObj: CheckChannelErrors() != 0} {
    # no test, need to cause an async error.
} {}
test io-6.3 {Tcl_GetsObj: how many have we used?} {
    # if (bufPtr != NULL) {oldRemoved = bufPtr->nextRemoved}

    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f "abc\ndefg"
    close $f
    set f [open test1]
    set x [list [tell $f] [gets $f line] [tell $f] [gets $f line] $line]
    close $f
    set x
} {0 3 5 4 defg}
test io-6.4 {Tcl_GetsObj: encoding == NULL} {
    set f [open test1 w]
    fconfigure $f -translation binary
    puts $f "\x81\u1234\0"
    close $f
    set f [open test1]
    fconfigure $f -translation binary
    set x [list [gets $f line] $line]
    close $f
    set x
} [list 3 "\x81\x34\x00"]
test io-6.5 {Tcl_GetsObj: encoding != NULL} {
    set f [open test1 w]
    fconfigure $f -translation binary
    puts $f "\x88\xea\x92\x9a"
    close $f
    set f [open test1]
    fconfigure $f -encoding shiftjis
    set x [list [gets $f line] $line]
    close $f
    set x
} [list 2 "\u4e00\u4e01"]
set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
append a $a
append a $a
test io-6.6 {Tcl_GetsObj: loop test} {
    # if (dst >= dstEnd) 

    set f [open test1 w]
    puts $f $a
    puts $f hi
    close $f
    set f [open test1]
    set x [list [gets $f line] $line]
    close $f
    set x
} [list 256 $a]
test io-6.7 {Tcl_GetsObj: error in input} {stdio} {
    # if (FilterInputBytes(chanPtr, &gs) != 0)

    set f [open "|[list $tcltest cat]" w+]
    puts -nonewline $f "hi\nwould"
    flush $f
    gets $f
    fconfigure $f -blocking 0
    set x [gets $f line]
    close $f
    set x
} {-1}
test io-6.8 {Tcl_GetsObj: remember if EOF is seen} {
    set f [open test1 w]
    puts $f "abcdef\x1aghijk\nwombat"
    close $f
    set f [open test1]
    fconfigure $f -eofchar \x1a
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {6 abcdef -1 {}}
test io-6.9 {Tcl_GetsObj: remember if EOF is seen} {
    set f [open test1 w]
    puts $f "abcdefghijk\nwom\u001abat"
    close $f
    set f [open test1]
    fconfigure $f -eofchar \x1a
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {11 abcdefghijk 3 wom}

# Comprehensive tests

test io-6.10 {Tcl_GetsObj: lf mode: no chars} {
    set f [open test1 w]
    close $f
    set f [open test1]
    fconfigure $f -translation lf
    set x [list [gets $f line] $line]
    close $f
    set x
} {-1 {}}
test io-6.11 {Tcl_GetsObj: lf mode: lone \n} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\n"
    close $f
    set f [open test1]
    fconfigure $f -translation lf
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {0 {} -1 {}}
test io-6.12 {Tcl_GetsObj: lf mode: lone \r} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\r"
    close $f
    set f [open test1]
    fconfigure $f -translation lf
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 1 "\r" -1 ""]
test io-6.13 {Tcl_GetsObj: lf mode: 1 char} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f a
    close $f
    set f [open test1]
    fconfigure $f -translation lf
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {1 a -1 {}}
test io-6.14 {Tcl_GetsObj: lf mode: 1 char followed by EOL} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\n"
    close $f
    set f [open test1]
    fconfigure $f -translation lf
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {1 a -1 {}}
test io-6.15 {Tcl_GetsObj: lf mode: several chars} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
    close $f
    set f [open test1]
    fconfigure $f -translation lf
    set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 4 "abcd" 10 "efgh\rijkl\r" 4 "mnop" -1 ""]
test io-6.16 {Tcl_GetsObj: cr mode: no chars} {
    set f [open test1 w]
    close $f
    set f [open test1]
    fconfigure $f -translation cr
    set x [list [gets $f line] $line]
    close $f
    set x
} {-1 {}}
test io-6.17 {Tcl_GetsObj: cr mode: lone \n} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\n"
    close $f
    set f [open test1]
    fconfigure $f -translation cr
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 1 "\n" -1 ""]
test io-6.18 {Tcl_GetsObj: cr mode: lone \r} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\r"
    close $f
    set f [open test1]
    fconfigure $f -translation cr
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {0 {} -1 {}}
test io-6.19 {Tcl_GetsObj: cr mode: 1 char} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f a
    close $f
    set f [open test1]
    fconfigure $f -translation cr
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {1 a -1 {}}
test io-6.20 {Tcl_GetsObj: cr mode: 1 char followed by EOL} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\r"
    close $f
    set f [open test1]
    fconfigure $f -translation cr
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {1 a -1 {}}
test io-6.21 {Tcl_GetsObj: cr mode: several chars} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
    close $f
    set f [open test1]
    fconfigure $f -translation cr
    set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 9 "abcd\nefgh" 4 "ijkl" 5 "\nmnop" -1 ""]
test io-6.22 {Tcl_GetsObj: crlf mode: no chars} {
    set f [open test1 w]
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [list [gets $f line] $line]
    close $f
    set x
} {-1 {}}
test io-6.23 {Tcl_GetsObj: crlf mode: lone \n} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\n"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 1 "\n" -1 ""]
test io-6.24 {Tcl_GetsObj: crlf mode: lone \r} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\r"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 1 "\r" -1 ""]
test io-6.25 {Tcl_GetsObj: crlf mode: \r\r} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\r\r"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 2 "\r\r" -1 ""]
test io-6.26 {Tcl_GetsObj: crlf mode: \r\n} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\r\n"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 0 "" -1 ""]
test io-6.27 {Tcl_GetsObj: crlf mode: 1 char} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f a
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {1 a -1 {}}
test io-6.28 {Tcl_GetsObj: crlf mode: 1 char followed by EOL} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\r\n"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {1 a -1 {}}
test io-6.29 {Tcl_GetsObj: crlf mode: several chars} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
test io-6.30 {Tcl_GetsObj: crlf mode: buffer exhausted} {
    # if (eol >= dstEnd)

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "123456789012345\r\nabcdefghijklmnoprstuvwxyz"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf -buffersize 16
    set x [list [gets $f line] $line [testchannel inputbuffered $f]]
    close $f
    set x
} [list 15 "123456789012345" 15]
test io-6.31 {Tcl_GetsObj: crlf mode: buffer exhausted, blocked} {stdio} {
    # (FilterInputBytes() != 0)

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -translation {crlf lf} -buffering none
    puts -nonewline $f "bbbbbbbbbbbbbb\r\n123456789012345\r"
    fconfigure $f -buffersize 16
    set x [gets $f]
    fconfigure $f -blocking 0
    lappend x [gets $f line] $line [fblocked $f] [testchannel inputbuffered $f]
    close $f
    set x
} [list "bbbbbbbbbbbbbb" -1 "" 1 16]
test io-6.32 {Tcl_GetsObj: crlf mode: buffer exhausted, more data} {
    # not (FilterInputBytes() != 0)

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "123456789012345\r\n123"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf -buffersize 16
    set x [list [gets $f line] $line [tell $f] [testchannel inputbuffered $f]]
    close $f
    set x
} [list 15 "123456789012345" 17 3]
test io-6.33 {Tcl_GetsObj: crlf mode: buffer exhausted, at eof} {
    # eol still equals dstEnd
    
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "123456789012345\r"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf -buffersize 16
    set x [list [gets $f line] $line [eof $f]]
    close $f
    set x
} [list 16 "123456789012345\r" 1]
test io-6.34 {Tcl_GetsObj: crlf mode: buffer exhausted, not followed by \n} {
    # not (*eol == '\n') 
    
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "123456789012345\rabcd\r\nefg"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf -buffersize 16
    set x [list [gets $f line] $line [tell $f]]
    close $f
    set x
} [list 20 "123456789012345\rabcd" 22]
test io-6.35 {Tcl_GetsObj: auto mode: no chars} {
    set f [open test1 w]
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [list [gets $f line] $line]
    close $f
    set x
} {-1 {}}
test io-6.36 {Tcl_GetsObj: auto mode: lone \n} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\n"
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 0 "" -1 ""]
test io-6.37 {Tcl_GetsObj: auto mode: lone \r} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\r"
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 0 "" -1 ""]
test io-6.38 {Tcl_GetsObj: auto mode: \r\r} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\r\r"
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 0 "" 0 "" -1 ""]
test io-6.39 {Tcl_GetsObj: auto mode: \r\n} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\r\n"
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 0 "" -1 ""]
test io-6.40 {Tcl_GetsObj: auto mode: 1 char} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f a
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {1 a -1 {}}
test io-6.41 {Tcl_GetsObj: auto mode: 1 char followed by EOL} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\r\n"
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [list [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} {1 a -1 {}}
test io-6.42 {Tcl_GetsObj: auto mode: several chars} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [list [gets $f line] $line [gets $f line] $line]
    lappend x [gets $f line] $line [gets $f line] $line [gets $f line] $line
    close $f
    set x
} [list 4 "abcd" 4 "efgh" 4 "ijkl" 4 "mnop" -1 ""]
test io-6.43 {Tcl_GetsObj: input saw cr} {stdio} {
    # if (chanPtr->flags & INPUT_SAW_CR)

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -translation {auto lf} -buffering none
    puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
    fconfigure $f -buffersize 16
    set x [list [gets $f]]
    fconfigure $f -blocking 0
    lappend x [gets $f line] $line [testchannel queuedcr $f] 
    fconfigure $f -blocking 1
    puts -nonewline $f "\nabcd\refg\x1a"
    lappend x [gets $f line] $line [testchannel queuedcr $f]
    lappend x [gets $f line] $line
    close $f
    set x
} [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
test io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} {stdio} {
    # not (*eol == '\n') 

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -translation {auto lf} -buffering none
    puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
    fconfigure $f -buffersize 16
    set x [list [gets $f]]
    fconfigure $f -blocking 0
    lappend x [gets $f line] $line [testchannel queuedcr $f] 
    fconfigure $f -blocking 1
    puts -nonewline $f "abcd\refg\x1a"
    lappend x [gets $f line] $line [testchannel queuedcr $f]
    lappend x [gets $f line] $line
    close $f
    set x
} [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
test io-6.45 {Tcl_GetsObj: input saw cr, skip right number of bytes} {stdio} {
    # Tcl_ExternalToUtf()

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -translation {auto lf} -buffering none
    fconfigure $f -encoding unicode
    puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
    fconfigure $f -buffersize 16
    gets $f
    fconfigure $f -blocking 0
    set x [list [gets $f line] $line [testchannel queuedcr $f]]
    fconfigure $f -blocking 1
    puts -nonewline $f "\nabcd\refg"
    lappend x [gets $f line] $line [testchannel queuedcr $f]
    close $f
    set x
} [list 15 "123456789abcdef" 1 4 "abcd" 0]
test io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eof} {stdio} {
    # memmove()

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -translation {auto lf} -buffering none
    puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
    fconfigure $f -buffersize 16
    gets $f
    fconfigure $f -blocking 0
    set x [list [gets $f line] $line [testchannel queuedcr $f]]
    fconfigure $f -blocking 1
    puts -nonewline $f "\n\x1a"
    lappend x [gets $f line] $line [testchannel queuedcr $f]
    close $f
    set x
} [list 15 "123456789abcdef" 1 -1 "" 0]
test io-6.47 {Tcl_GetsObj: auto mode: \r at end of buffer, peek for \n} {
    # (eol == dstEnd)

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "123456789012345\r\nabcdefghijklmnopq"
    close $f
    set f [open test1]
    fconfigure $f -translation auto -buffersize 16
    set x [list [gets $f] [testchannel inputbuffered $f]]
    close $f
    set x
} [list "123456789012345" 15]    
test io-6.48 {Tcl_GetsObj: auto mode: \r at end of buffer, no more avail} {
    # PeekAhead() did not get any, so (eol >= dstEnd)
    
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "123456789012345\r"
    close $f
    set f [open test1]
    fconfigure $f -translation auto -buffersize 16
    set x [list [gets $f] [testchannel queuedcr $f]]
    close $f
    set x
} [list "123456789012345" 1]
test io-6.49 {Tcl_GetsObj: auto mode: \r followed by \n} {
    # if (*eol == '\n') {skip++}
    
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "123456\r\n78901"
    close $f
    set f [open test1]
    set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
    close $f
    set x
} [list "123456" 0 8 "78901"]
test io-6.50 {Tcl_GetsObj: auto mode: \r not followed by \n} {
    # not (*eol == '\n') 
    
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "123456\r78901"
    close $f
    set f [open test1]
    set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
    close $f
    set x
} [list "123456" 0 7 "78901"]
test io-6.51 {Tcl_GetsObj: auto mode: \n} {
    # else if (*eol == '\n') {goto gotoeol;}
    
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "123456\n78901"
    close $f
    set f [open test1]
    set x [list [gets $f] [tell $f] [gets $f]]
    close $f
    set x
} [list "123456" 7 "78901"]
test io-6.52 {Tcl_GetsObj: saw EOF character} {
    # if (eof != NULL)

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "123456\x1ak9012345\r"
    close $f
    set f [open test1]
    fconfigure $f -eofchar \x1a
    set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
    close $f
    set x
} [list "123456" 0 6 ""]
test io-6.53 {Tcl_GetsObj: device EOF} {
    # didn't produce any bytes

    set f [open test1 w]
    close $f
    set f [open test1]
    set x [list [gets $f line] $line [eof $f]]
    close $f
    set x
} {-1 {} 1}
test io-6.54 {Tcl_GetsObj: device EOF} {
    # got some bytes before EOF.

    set f [open test1 w]
    puts -nonewline $f abc
    close $f
    set f [open test1]
    set x [list [gets $f line] $line [eof $f]]
    close $f
    set x
} {3 abc 1}
test io-6.55 {Tcl_GetsObj: overconverted} {
    # Tcl_ExternalToUtf(), make sure state updated

    set f [open test1 w]
    fconfigure $f -encoding iso2022-jp
    puts $f "there\u4e00ok\n\u4e01more bytes\nhere"
    close $f
    set f [open test1]
    fconfigure $f -encoding iso2022-jp
    set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
    close $f
    set x
} [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"]
test io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} {stdio} {
    update
    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -buffering none
    puts -nonewline $f "foobar"
    fconfigure $f -blocking 0
    set x {}
    after 500 { lappend x timeout }
    fileevent $f readable { lappend x [gets $f] }
    vwait x
    vwait x
    fconfigure $f -blocking 1
    puts -nonewline $f "baz\n"
    after 500 { lappend x timeout }
    fconfigure $f -blocking 0
    vwait x
    vwait x
    close $f
    set x
} {{} timeout foobarbaz timeout}

test io-7.1 {FilterInputBytes: split up character at end of buffer} {
    # (result == TCL_CONVERT_MULTIBYTE)

    set f [open test1 w]
    fconfigure $f -encoding shiftjis
    puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend"
    close $f
    set f [open test1]
    fconfigure $f -encoding shiftjis -buffersize 16
    set x [gets $f]
    close $f
    set x
} "1234567890123\uff10\uff11\uff12\uff13\uff14"
test io-7.2 {FilterInputBytes: split up character in middle of buffer} {
    # (bufPtr->nextAdded < bufPtr->bufLength)
    
    set f [open test1 w]
    fconfigure $f -encoding binary
    puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82"
    close $f
    set f [open test1]
    fconfigure $f -encoding shiftjis
    set x [list [gets $f line] $line [eof $f]]
    close $f
    set x
} [list 10 "1234567890" 0]
test io-7.3 {FilterInputBytes: split up character at EOF} {
    set f [open test1 w]
    fconfigure $f -encoding binary
    puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
    close $f
    set f [open test1]
    fconfigure $f -encoding shiftjis
    set x [list [gets $f line] $line]
    lappend x [tell $f] [testchannel inputbuffered $f] [eof $f]
    lappend x [gets $f line] $line
    close $f
    set x
} [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""]
test io-7.4 {FilterInputBytes: recover from split up character} {stdio} {
    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -encoding binary -buffering none
    puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
    fconfigure $f -encoding shiftjis -blocking 0
    fileevent $f read "ready $f"
    set x {}
    proc ready {f} {
	lappend ::x [gets $f line] $line [fblocked $f]
    }
    vwait x
    fconfigure $f -encoding binary -blocking 1
    puts $f "\x51\x82\x52"
    fconfigure $f -encoding shiftjis
    vwait x
    close $f
    set x
} [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]

test io-8.1 {PeekAhead: only go to device if no more cached data} {
    # (bufPtr->nextPtr == NULL)

    set f [open "test1" w]
    fconfigure $f -encoding ascii -translation lf
    puts -nonewline $f "123456789012345\r\n2345678"
    close $f
    set f [open "test1"]
    fconfigure $f -encoding ascii -translation auto -buffersize 16
    # here
    gets $f
    set x [testchannel inputbuffered $f]
    close $f
    set x
} "7"
test io-8.2 {PeekAhead: only go to device if no more cached data} {stdio} {
    # not (bufPtr->nextPtr == NULL)

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -translation lf -encoding ascii -buffering none
    puts -nonewline $f "123456789012345\r\nbcdefghijklmnopqrstuvwxyz"
    set x {}
    fileevent $f read "ready $f"
    proc ready {f} {
	lappend ::x [gets $f line] $line [testchannel inputbuffered $f]
    }
    fconfigure $f -encoding unicode -buffersize 16 -blocking 0
    vwait x
    fconfigure $f -translation auto -encoding ascii -blocking 1
    # here
    vwait x
    close $f
    set x
} [list -1 "" 42 15 "123456789012345" 25]
test io-8.3 {PeekAhead: no cached data available} {stdio} {
    # (bytesLeft == 0)

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -translation {auto binary}
    puts -nonewline $f "abcdefghijklmno\r"
    flush $f
    set x [list [gets $f line] $line [testchannel queuedcr $f]]
    close $f
    set x
} [list 15 "abcdefghijklmno" 1]
set a "123456789012345678901234567890"
append a "123456789012345678901234567890"
append a "1234567890123456789012345678901"
test io-8.4 {PeekAhead: cached data available in this buffer} {
    # not (bytesLeft == 0)

    set f [open test1 w+]
    fconfigure $f -translation binary
    puts $f "${a}\r\nabcdef"
    close $f
    set f [open test1]
    fconfigure $f -encoding binary -translation auto

    # "${a}\r" was converted in one operation (because ENCODING_LINESIZE
    # is 30).  To check if "\n" follows, calls PeekAhead and determines
    # that cached data is available in buffer w/o having to call driver.

    set x [gets $f]
    close $f
    set x    
} $a
unset a
test io-8.5 {PeekAhead: don't peek if last read was short} {stdio} {
    # (bufPtr->nextAdded < bufPtr->length)

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -translation {auto binary}
    puts -nonewline $f "abcdefghijklmno\r"
    flush $f
    # here
    set x [list [gets $f line] $line [testchannel queuedcr $f]]
    close $f
    set x
} {15 abcdefghijklmno 1}
test io-8.6 {PeekAhead: change to non-blocking mode} {stdio} {
    # ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0) 

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -translation {auto binary} -buffersize 16
    puts -nonewline $f "abcdefghijklmno\r"
    flush $f
    # here
    set x [list [gets $f line] $line [testchannel queuedcr $f]]
    close $f
    set x
} {15 abcdefghijklmno 1}
test io-8.7 {PeekAhead: cleanup} {stdio} {
    # Make sure bytes are removed from buffer.

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -translation {auto binary} -buffering none
    puts -nonewline $f "abcdefghijklmno\r"
    # here
    set x [list [gets $f line] $line [testchannel queuedcr $f]]
    puts -nonewline $f "\x1a"
    lappend x [gets $f line] $line
    close $f
    set x
} {15 abcdefghijklmno 1 -1 {}}
    

test io-9.1 {CommonGetsCleanup} {
} {}

test io-10.1 {Tcl_ReadChars: CheckChannelErrors} {
    # no test, need to cause an async error.
} {}
test io-10.2 {Tcl_ReadChars: loop until enough copied} {
    # one time
    # for (copied = 0; (unsigned) toRead > 0; )

    set f [open "test1" w]
    puts $f abcdefghijklmnop
    close $f

    set f [open "test1"]
    set x [read $f 5]
    close $f
    set x
} {abcde}
test io-10.3 {Tcl_ReadChars: loop until enough copied} {
    # multiple times
    # for (copied = 0; (unsigned) toRead > 0; )

    set f [open "test1" w]
    puts $f abcdefghijklmnopqrstuvwxyz
    close $f

    set f [open "test1"]
    fconfigure $f -buffersize 16
    # here
    set x [read $f 19]
    close $f
    set x
} {abcdefghijklmnopqrs}
test io-10.4 {Tcl_ReadChars: no more in channel buffer} {
    # (copiedNow < 0)

    set f [open "test1" w]
    puts -nonewline $f abcdefghijkl
    close $f

    set f [open "test1"]
    # here
    set x [read $f 1000]
    close $f
    set x
} {abcdefghijkl}
test io-10.5 {Tcl_ReadChars: stop on EOF} {
    # (chanPtr->flags & CHANNEL_EOF)

    set f [open "test1" w]
    puts -nonewline $f abcdefghijkl
    close $f

    set f [open "test1"]
    # here
    set x [read $f 1000]
    close $f
    set x
} {abcdefghijkl}

test io-11.1 {ReadBytes: want to read a lot} {
    # ((unsigned) toRead > (unsigned) srcLen)

    set f [open "test1" w]
    puts -nonewline $f abcdefghijkl
    close $f
    set f [open "test1"]
    fconfigure $f -encoding binary
    # here
    set x [read $f 1000]
    close $f
    set x
} {abcdefghijkl}
test io-11.2 {ReadBytes: want to read all} {
    # ((unsigned) toRead > (unsigned) srcLen)

    set f [open "test1" w]
    puts -nonewline $f abcdefghijkl
    close $f
    set f [open "test1"]
    fconfigure $f -encoding binary
    # here
    set x [read $f]
    close $f
    set x
} {abcdefghijkl}
test io-11.3 {ReadBytes: allocate more space} {
    # (toRead > length - offset - 1)

    set f [open "test1" w]
    puts -nonewline $f abcdefghijklmnopqrstuvwxyz
    close $f
    set f [open "test1"]
    fconfigure $f -buffersize 16 -encoding binary
    # here
    set x [read $f]
    close $f
    set x
} {abcdefghijklmnopqrstuvwxyz}
test io-11.4 {ReadBytes: EOF char found} {
    # (TranslateInputEOL() != 0)

    set f [open "test1" w]
    puts $f abcdefghijklmnopqrstuvwxyz
    close $f
    set f [open "test1"]
    fconfigure $f -eofchar m -encoding binary
    # here
    set x [list [read $f] [eof $f] [read $f] [eof $f]]
    close $f
    set x
} [list "abcdefghijkl" 1 "" 1]
    
test io-12.1 {ReadChars: want to read a lot} {
    # ((unsigned) toRead > (unsigned) srcLen)

    set f [open "test1" w]
    puts -nonewline $f abcdefghijkl
    close $f
    set f [open "test1"]
    # here
    set x [read $f 1000]
    close $f
    set x
} {abcdefghijkl}
test io-12.2 {ReadChars: want to read all} {
    # ((unsigned) toRead > (unsigned) srcLen)

    set f [open "test1" w]
    puts -nonewline $f abcdefghijkl
    close $f
    set f [open "test1"]
    # here
    set x [read $f]
    close $f
    set x
} {abcdefghijkl}
test io-12.3 {ReadChars: allocate more space} {
    # (toRead > length - offset - 1)

    set f [open "test1" w]
    puts -nonewline $f abcdefghijklmnopqrstuvwxyz
    close $f
    set f [open "test1"]
    fconfigure $f -buffersize 16
    # here
    set x [read $f]
    close $f
    set x
} {abcdefghijklmnopqrstuvwxyz}
test io-12.4 {ReadChars: split-up char} {stdio} {
    # (srcRead == 0)

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -encoding binary -buffering none -buffersize 16
    puts -nonewline $f "123456789012345\x96"
    fconfigure $f -encoding shiftjis -blocking 0

    fileevent $f read "ready $f"
    proc ready {f} {
	lappend ::x [read $f] [testchannel inputbuffered $f]
    }
    set x {}

    fconfigure $f -encoding shiftjis
    vwait x
    fconfigure $f -encoding binary -blocking 1
    puts -nonewline $f "\x7b"
    after 500			;# Give the cat process time to catch up
    fconfigure $f -encoding shiftjis -blocking 0
    vwait x
    close $f
    set x
} [list "123456789012345" 1 "\u672c" 0]
test io-12.5 {ReadChars: fileevents on partial characters} {stdio} {
    makeFile {
	fconfigure stdout -encoding binary -buffering none
	gets stdin; puts -nonewline "\xe7"
	gets stdin; puts -nonewline "\x89"
	gets stdin; puts -nonewline "\xa6"
    } test1
    set f [open "|[list $tcltest test1]" r+]
    fileevent $f readable {
	lappend x [read $f]
	if {[eof $f]} {
	    lappend x eof
	}
    }
    puts $f "go1"
    flush $f
    fconfigure $f -blocking 0 -encoding utf-8
    set x {}
    vwait x
    after 500 { lappend x timeout }
    vwait x
    puts $f "go2"
    flush $f
    vwait x
    after 500 { lappend x timeout }
    vwait x
    puts $f "go3"
    flush $f
    vwait x
    vwait x
    lappend x [catch {close $f} msg] $msg
    set x
} "{} timeout {} timeout \u7266 {} eof 0 {}"

test io-13.1 {TranslateInputEOL: cr mode} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\rdef\r"
    close $f
    set f [open test1]
    fconfigure $f -translation cr
    set x [read $f]
    close $f
    set x
} "abcd\ndef\n"
test io-13.2 {TranslateInputEOL: crlf mode} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\r\ndef\r\n"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [read $f]
    close $f
    set x
} "abcd\ndef\n"
test io-13.3 {TranslateInputEOL: crlf mode: naked cr} {
    # (src >= srcMax) 

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\r\ndef\r"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [read $f]
    close $f
    set x
} "abcd\ndef\r"
test io-13.4 {TranslateInputEOL: crlf mode: cr followed by not \n} {
    # (src >= srcMax) 

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\r\ndef\rfgh"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [read $f]
    close $f
    set x
} "abcd\ndef\rfgh"
test io-13.5 {TranslateInputEOL: crlf mode: naked lf} {
    # (src >= srcMax) 

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\r\ndef\nfgh"
    close $f
    set f [open test1]
    fconfigure $f -translation crlf
    set x [read $f]
    close $f
    set x
} "abcd\ndef\nfgh"
test io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} {stdio} {
    # (chanPtr->flags & INPUT_SAW_CR)
    # This test may fail on slower machines.

    set f [open "|[list $tcltest cat]" w+]
    fconfigure $f -blocking 0 -buffering none -translation {auto lf}

    fileevent $f read "ready $f"
    proc ready {f} {
	lappend ::x [read $f] [testchannel queuedcr $f]
    }
    set x {}

    puts -nonewline $f "abcdefghj\r"
    after 500 {set y ok}
    vwait y

    puts -nonewline $f "\n01234"
    after 500 {set y ok}
    vwait y

    close $f
    set x
} [list "abcdefghj\n" 1 "01234" 0]
test io-13.7 {TranslateInputEOL: auto mode: naked \r} {
    # (src >= srcMax)

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\r"
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [list [read $f] [testchannel queuedcr $f]]
    close $f
    set x
} [list "abcd\n" 1]
test io-13.8 {TranslateInputEOL: auto mode: \r\n} {
    # (*src == '\n')

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\r\ndef"
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [read $f]
    close $f
    set x
} "abcd\ndef"
test io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} {
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\rdef"
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [read $f]
    close $f
    set x
} "abcd\ndef"
test io-13.10 {TranslateInputEOL: auto mode: \n} {
    # not (*src == '\r') 

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\ndef"
    close $f
    set f [open test1]
    fconfigure $f -translation auto
    set x [read $f]
    close $f
    set x
} "abcd\ndef"
test io-13.11 {TranslateInputEOL: EOF char} {
    # (*chanPtr->inEofChar != '\0')

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "abcd\ndefgh"
    close $f
    set f [open test1]
    fconfigure $f -translation auto -eofchar e
    set x [read $f]
    close $f
    set x
} "abcd\nd"
test io-13.12 {TranslateInputEOL: find EOF char in src} {
    # (*chanPtr->inEofChar != '\0')

    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "\r\n\r\n\r\nab\r\n\r\ndef\r\n\r\n\r\n"
    close $f
    set f [open test1]
    fconfigure $f -translation auto -eofchar e
    set x [read $f]
    close $f
    set x
} "\n\n\nab\n\nd"
    
# Test standard handle management. The functions tested are
# Tcl_SetStdChannel and Tcl_GetStdChannel. Incidentally we are
# also testing channel table management.

if {$tcl_platform(platform) == "macintosh"} {
    set consoleFileNames [list console0 console1 console2]
} else {
    set consoleFileNames [lsort [testchannel open]]
}
test io-14.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {
    set l ""
    lappend l [fconfigure stdin -buffering]
    lappend l [fconfigure stdout -buffering]
    lappend l [fconfigure stderr -buffering]
    lappend l [lsort [testchannel open]]
    set l
} [list line line none $consoleFileNames]
test io-14.2 {Tcl_SetStdChannel and Tcl_GetStdChannel} {
    interp create x
    set l ""
    lappend l [x eval {fconfigure stdin -buffering}]
    lappend l [x eval {fconfigure stdout -buffering}]
    lappend l [x eval {fconfigure stderr -buffering}]
    interp delete x
    set l
} {line line none}
test io-14.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} {stdio} {
    set f [open test1 w]
    puts $f {
	close stdin
	close stdout
	close stderr
	set f [open test1 r]
	set f2 [open test2 w]
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    close $f2
    set result
} {{
out
} {err
}}
# This test relies on the fact that the smallest available fd is used first.
test io-1.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} {unixOnly} {
    set f [open test1 w]
    puts $f { close stdin
	close stdout
	close stderr
	set f [open test1 r]
	set f2 [open test2 w]
	set f3 [open test3 w]







|







1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
    close $f2
    set result
} {{
out
} {err
}}
# This test relies on the fact that the smallest available fd is used first.
test io-14.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} {unixOnly} {
    set f [open test1 w]
    puts $f { close stdin
	close stdout
	close stderr
	set f [open test1 r]
	set f2 [open test2 w]
	set f3 [open test3 w]
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277


278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404














































405
406
407
408
409
410




411
412
413
414
415
416
417

418
419
420
421
422
423
424

425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452









453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504

505
506
507
508
509
510
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
    close $f2
    set result
} {{ close stdin
file1
} {file2
}}
catch {interp delete z}
test io-1.5 {Tcl_GetChannel: stdio name translation} {
    interp create z
    eof stdin
    catch {z eval flush stdin} msg1
    catch {z eval close stdin} msg2
    catch {z eval flush stdin} msg3
    set result [list $msg1 $msg2 $msg3]
    interp delete z
    set result
} {{channel "stdin" wasn't opened for writing} {} {can not find channel named "stdin"}}
test io-1.6 {Tcl_GetChannel: stdio name translation} {
    interp create z
    eof stdout
    catch {z eval flush stdout} msg1
    catch {z eval close stdout} msg2
    catch {z eval flush stdout} msg3
    set result [list $msg1 $msg2 $msg3]
    interp delete z
    set result
} {{} {} {can not find channel named "stdout"}}
test io-1.7 {Tcl_GetChannel: stdio name translation} {
    interp create z
    eof stderr
    catch {z eval flush stderr} msg1
    catch {z eval close stderr} msg2
    catch {z eval flush stderr} msg3
    set result [list $msg1 $msg2 $msg3]
    interp delete z
    set result
} {{} {} {can not find channel named "stderr"}}
test io-1.8 {reuse of stdio special channels} {unixOnly} {
    removeFile script
    removeFile test1
    set f [open script w]
    puts $f {
	close stderr
	set f [open test1 w]
	puts stderr hello
	close $f
	set f [open test1 r]
	puts [gets $f]
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    set c [gets $f]
    close $f
    set c
} hello
test io-1.9 {reuse of stdio special channels} {stdio} {
    removeFile script
    removeFile test1
    set f [open script w]
    puts $f {
	set f [open test1 w]
	puts $f hello
	close $f
	close stderr
	set f [open "|[list [info nameofexecutable] cat test1]" r]
	puts [gets $f]
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    set c [gets $f]
    close $f
    set c
} hello

# Must add test function for testing Tcl_CreateCloseHandler and


# Tcl_DeleteCloseHandler.


# Test channel table management. The functions tested are
# GetChannelTable, DeleteChannelTable, Tcl_RegisterChannel,
# Tcl_UnregisterChannel, Tcl_GetChannel and Tcl_CreateChannel.
#
# These functions use "eof stdin" to ensure that the standard
# channels are added to the channel table of the interpreter.

test io-2.1 {GetChannelTable, DeleteChannelTable on std handles} {
    set l1 [testchannel refcount stdin]
    eof stdin
    interp create x
    set l ""
    lappend l [expr [testchannel refcount stdin] - $l1]
    x eval {eof stdin}
    lappend l [expr [testchannel refcount stdin] - $l1]
    interp delete x
    lappend l [expr [testchannel refcount stdin] - $l1]
    set l
} {0 1 0}
test io-2.2 {GetChannelTable, DeleteChannelTable on std handles} {
    set l1 [testchannel refcount stdout]
    eof stdin
    interp create x
    set l ""
    lappend l [expr [testchannel refcount stdout] - $l1]
    x eval {eof stdout}
    lappend l [expr [testchannel refcount stdout] - $l1]
    interp delete x
    lappend l [expr [testchannel refcount stdout] - $l1]
    set l
} {0 1 0}
test io-2.3 {GetChannelTable, DeleteChannelTable on std handles} {
    set l1 [testchannel refcount stderr]
    eof stdin
    interp create x
    set l ""
    lappend l [expr [testchannel refcount stderr] - $l1]
    x eval {eof stderr}
    lappend l [expr [testchannel refcount stderr] - $l1]
    interp delete x
    lappend l [expr [testchannel refcount stderr] - $l1]
    set l
} {0 1 0}

test io-2.4 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {
    removeFile test1
    set l ""
    set f [open test1 w]
    lappend l [lindex [testchannel info $f] 15]
    close $f
    if {[catch {lindex [testchannel info $f] 15} msg]} {
	lappend l $msg
    } else {
	lappend l "very broken: $f found after being closed"
    }
    string compare [string tolower $l] \
	[list 1 [format "can not find channel named \"%s\"" $f]]
} 0
test io-2.5 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {
    removeFile test1
    set l ""
    set f [open test1 w]
    lappend l [lindex [testchannel info $f] 15]
    interp create x
    interp share "" $f x
    lappend l [lindex [testchannel info $f] 15]
    x eval close $f
    lappend l [lindex [testchannel info $f] 15]
    interp delete x
    lappend l [lindex [testchannel info $f] 15]
    close $f
    if {[catch {lindex [testchannel info $f] 15} msg]} {
	lappend l $msg
    } else {
	lappend l "very broken: $f found after being closed"
    }
    string compare [string tolower $l] \
	[list 1 2 1 1 [format "can not find channel named \"%s\"" $f]]
} 0
test io-2.6 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {
    removeFile test1
    set l ""
    set f [open test1 w]
    lappend l [lindex [testchannel info $f] 15]
    interp create x
    interp share "" $f x
    lappend l [lindex [testchannel info $f] 15]
    interp delete x
    lappend l [lindex [testchannel info $f] 15]
    close $f
    if {[catch {lindex [testchannel info $f] 15} msg]} {
	lappend l $msg
    } else {
	lappend l "very broken: $f found after being closed"
    }
    string compare [string tolower $l] \
	[list 1 2 1 [format "can not find channel named \"%s\"" $f]]
} 0

test io-2.7 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
    eof stdin
} 0
test io-2.8 {testing Tcl_GetChannel, user opened handle} {
    removeFile test1
    set f [open test1 w]
    set x [eof $f]
    close $f
    set x
} 0
test io-2.9 {Tcl_GetChannel, channel not found} {
    list [catch {eof file34} msg] $msg
} {1 {can not find channel named "file34"}}
test io-2.10 {Tcl_CreateChannel, insertion into channel table} {
    removeFile test1
    set f [open test1 w]
    set l ""
    lappend l [eof $f]
    close $f
    if {[catch {lindex [testchannel info $f] 15} msg]} {
	lappend l $msg
    } else {
	lappend l "very broken: $f found after being closed"
    }
    string compare [string tolower $l] \
	[list 0 [format "can not find channel named \"%s\"" $f]]
} 0















































# Test management of attributes associated with a channel, such as
# its default translation, its name and type, etc. The functions
# tested in this group are Tcl_GetChannelName,
# Tcl_GetChannelType and Tcl_GetChannelFile. Tcl_GetChannelInstanceData
# not tested because files do not use the instance data.





test io-3.1 {Tcl_GetChannelName} {
    removeFile test1
    set f [open test1 w]
    set n [testchannel name $f]
    close $f
    string compare $n $f
} 0

test io-3.2 {Tcl_GetChannelType} {
    removeFile test1
    set f [open test1 w]
    set t [testchannel type $f]
    close $f
    string compare $t file
} 0

test io-3.3 {Tcl_GetChannelFile, input} {
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    puts $f "1234567890\n098765432"
    close $f
    set f [open test1 r]
    gets $f
    set l ""
    lappend l [testchannel inputbuffered $f]
    lappend l [tell $f]
    close $f
    set l
} {10 11}
test io-3.4 {Tcl_GetChannelFile, output} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [tell $f]
    flush $f
    lappend l [testchannel outputbuffered $f]
    lappend l [tell $f]
    close $f
    removeFile test1
    set l
} {6 6 0 6}










# Test flushing. The functions tested here are FlushChannel.

test io-4.1 {FlushChannel, no output buffered} {
    removeFile test1
    set f [open test1 w]
    flush $f
    set s [file size test1]
    close $f
    set s
} 0
test io-4.2 {FlushChannel, some output buffered} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set l ""
    puts $f hello
    lappend l [file size test1]
    flush $f
    lappend l [file size test1]
    close $f
    lappend l [file size test1]
    set l
} {0 6 6}
test io-4.3 {FlushChannel, implicit flush on close} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set l ""
    puts $f hello
    lappend l [file size test1]
    close $f
    lappend l [file size test1]
    set l
} {0 6}
test io-4.4 {FlushChannel, implicit flush when buffer fills} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    fconfigure $f -buffersize 60
    set l ""
    lappend l [file size test1]
    for {set i 0} {$i < 12} {incr i} {
	puts $f hello
    }
    lappend l [file size test1]
    flush $f
    lappend l [file size test1]
    close $f
    set l
} {0 60 72}
test io-4.5 {FlushChannel, implicit flush when buffer fills and on close} {unixOrPc} {

    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffersize 60 -eofchar {}
    set l ""
    lappend l [file size test1]
    for {set i 0} {$i < 12} {incr i} {
	puts $f hello
    }
    lappend l [file size test1]
    close $f
    lappend l [file size test1]
    set l
} {0 60 72}
test io-4.6 {FlushChannel, async flushing, async close} {stdio && asyncPipeClose} {

    removeFile pipe
    removeFile output
    set f [open pipe w]
    puts $f {
	set f [open output w]
	fconfigure $f -translation lf -buffering none -eofchar {}
	while {![eof stdin]} {







|









|









|









|

















|


















|
>
>
|
>








|











|











|











>
|













|




















|


















>
|


|






|


|














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






>
>
>
>
|






>
|






>
|












|














>
>
>
>
>
>
>
>
>



|







|












|










|















|
>













|
>







1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
    close $f2
    set result
} {{ close stdin
file1
} {file2
}}
catch {interp delete z}
test io-14.5 {Tcl_GetChannel: stdio name translation} {
    interp create z
    eof stdin
    catch {z eval flush stdin} msg1
    catch {z eval close stdin} msg2
    catch {z eval flush stdin} msg3
    set result [list $msg1 $msg2 $msg3]
    interp delete z
    set result
} {{channel "stdin" wasn't opened for writing} {} {can not find channel named "stdin"}}
test io-14.6 {Tcl_GetChannel: stdio name translation} {
    interp create z
    eof stdout
    catch {z eval flush stdout} msg1
    catch {z eval close stdout} msg2
    catch {z eval flush stdout} msg3
    set result [list $msg1 $msg2 $msg3]
    interp delete z
    set result
} {{} {} {can not find channel named "stdout"}}
test io-14.7 {Tcl_GetChannel: stdio name translation} {
    interp create z
    eof stderr
    catch {z eval flush stderr} msg1
    catch {z eval close stderr} msg2
    catch {z eval flush stderr} msg3
    set result [list $msg1 $msg2 $msg3]
    interp delete z
    set result
} {{} {} {can not find channel named "stderr"}}
test io-14.8 {reuse of stdio special channels} {stdio} {
    removeFile script
    removeFile test1
    set f [open script w]
    puts $f {
	close stderr
	set f [open test1 w]
	puts stderr hello
	close $f
	set f [open test1 r]
	puts [gets $f]
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    set c [gets $f]
    close $f
    set c
} hello
test io-14.9 {reuse of stdio special channels} {stdio} {
    removeFile script
    removeFile test1
    set f [open script w]
    puts $f {
	set f [open test1 w]
	puts $f hello
	close $f
	close stderr
	set f [open "|[list [info nameofexecutable] cat test1]" r]
	puts [gets $f]
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    set c [gets $f]
    close $f
    set c
} hello

test io-15.1 {Tcl_CreateCloseHandler} {
} {}

test io-16.1 {Tcl_DeleteCloseHandler} {
} {}

# Test channel table management. The functions tested are
# GetChannelTable, DeleteChannelTable, Tcl_RegisterChannel,
# Tcl_UnregisterChannel, Tcl_GetChannel and Tcl_CreateChannel.
#
# These functions use "eof stdin" to ensure that the standard
# channels are added to the channel table of the interpreter.

test io-17.1 {GetChannelTable, DeleteChannelTable on std handles} {
    set l1 [testchannel refcount stdin]
    eof stdin
    interp create x
    set l ""
    lappend l [expr [testchannel refcount stdin] - $l1]
    x eval {eof stdin}
    lappend l [expr [testchannel refcount stdin] - $l1]
    interp delete x
    lappend l [expr [testchannel refcount stdin] - $l1]
    set l
} {0 1 0}
test io-17.2 {GetChannelTable, DeleteChannelTable on std handles} {
    set l1 [testchannel refcount stdout]
    eof stdin
    interp create x
    set l ""
    lappend l [expr [testchannel refcount stdout] - $l1]
    x eval {eof stdout}
    lappend l [expr [testchannel refcount stdout] - $l1]
    interp delete x
    lappend l [expr [testchannel refcount stdout] - $l1]
    set l
} {0 1 0}
test io-17.3 {GetChannelTable, DeleteChannelTable on std handles} {
    set l1 [testchannel refcount stderr]
    eof stdin
    interp create x
    set l ""
    lappend l [expr [testchannel refcount stderr] - $l1]
    x eval {eof stderr}
    lappend l [expr [testchannel refcount stderr] - $l1]
    interp delete x
    lappend l [expr [testchannel refcount stderr] - $l1]
    set l
} {0 1 0}

test io-18.1 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {
    removeFile test1
    set l ""
    set f [open test1 w]
    lappend l [lindex [testchannel info $f] 15]
    close $f
    if {[catch {lindex [testchannel info $f] 15} msg]} {
	lappend l $msg
    } else {
	lappend l "very broken: $f found after being closed"
    }
    string compare [string tolower $l] \
	[list 1 [format "can not find channel named \"%s\"" $f]]
} 0
test io-18.2 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {
    removeFile test1
    set l ""
    set f [open test1 w]
    lappend l [lindex [testchannel info $f] 15]
    interp create x
    interp share "" $f x
    lappend l [lindex [testchannel info $f] 15]
    x eval close $f
    lappend l [lindex [testchannel info $f] 15]
    interp delete x
    lappend l [lindex [testchannel info $f] 15]
    close $f
    if {[catch {lindex [testchannel info $f] 15} msg]} {
	lappend l $msg
    } else {
	lappend l "very broken: $f found after being closed"
    }
    string compare [string tolower $l] \
	[list 1 2 1 1 [format "can not find channel named \"%s\"" $f]]
} 0
test io-18.3 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {
    removeFile test1
    set l ""
    set f [open test1 w]
    lappend l [lindex [testchannel info $f] 15]
    interp create x
    interp share "" $f x
    lappend l [lindex [testchannel info $f] 15]
    interp delete x
    lappend l [lindex [testchannel info $f] 15]
    close $f
    if {[catch {lindex [testchannel info $f] 15} msg]} {
	lappend l $msg
    } else {
	lappend l "very broken: $f found after being closed"
    }
    string compare [string tolower $l] \
	[list 1 2 1 [format "can not find channel named \"%s\"" $f]]
} 0

test io-19.1 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
    eof stdin
} 0
test io-19.2 {testing Tcl_GetChannel, user opened handle} {
    removeFile test1
    set f [open test1 w]
    set x [eof $f]
    close $f
    set x
} 0
test io-19.3 {Tcl_GetChannel, channel not found} {
    list [catch {eof file34} msg] $msg
} {1 {can not find channel named "file34"}}
test io-19.4 {Tcl_CreateChannel, insertion into channel table} {
    removeFile test1
    set f [open test1 w]
    set l ""
    lappend l [eof $f]
    close $f
    if {[catch {lindex [testchannel info $f] 15} msg]} {
	lappend l $msg
    } else {
	lappend l "very broken: $f found after being closed"
    }
    string compare [string tolower $l] \
	[list 0 [format "can not find channel named \"%s\"" $f]]
} 0

test io-20.1 {Tcl_CreateChannel: initial settings} {
	set a [open test2 w]
    set old [encoding system]
    encoding system ascii
    set f [open test1 w]
    set x [fconfigure $f -encoding]
    close $f
    encoding system $old
	close $a
    set x
} {ascii}    
test io-20.2 {Tcl_CreateChannel: initial settings} {pcOnly} {
    set f [open test1 w+]
    set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
    close $f
    set x
} [list [list \x1a ""] {auto crlf}]
test io-20.3 {Tcl_CreateChannel: initial settings} {unixOnly} {
    set f [open test1 w+]
    set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
    close $f
    set x
} {{{} {}} {auto lf}}
test io-20.4 {Tcl_CreateChannel: initial settings} {macOnly} {
    set f [open test1 w+]
    set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
    close $f
    set x
} {{{} {}} {auto cr}}
test io-20.5 {Tcl_CreateChannel: install channel in empty slot} {stdio} {
    set f [open script w]
    puts $f {
	close stdout
	set f1 [open stdout w]
	fconfigure $f1 -buffersize 777
	puts stderr [fconfigure stdout -buffersize]
    }
    close $f
    set f [open "|[list $tcltest script]"]
    catch {close $f} msg
    set msg
} {777}
	
test io-21.1 {CloseChannelsOnExit} {
} {}
    
# Test management of attributes associated with a channel, such as
# its default translation, its name and type, etc. The functions
# tested in this group are Tcl_GetChannelName,
# Tcl_GetChannelType and Tcl_GetChannelFile. Tcl_GetChannelInstanceData
# not tested because files do not use the instance data.

test io-22.1 {Tcl_GetChannelMode} {
    # Not used anywhere in Tcl.
} {}

test io-23.1 {Tcl_GetChannelName} {
    removeFile test1
    set f [open test1 w]
    set n [testchannel name $f]
    close $f
    string compare $n $f
} 0

test io-24.1 {Tcl_GetChannelType} {
    removeFile test1
    set f [open test1 w]
    set t [testchannel type $f]
    close $f
    string compare $t file
} 0

test io-25.1 {Tcl_GetChannelHandle, input} {
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    puts $f "1234567890\n098765432"
    close $f
    set f [open test1 r]
    gets $f
    set l ""
    lappend l [testchannel inputbuffered $f]
    lappend l [tell $f]
    close $f
    set l
} {10 11}
test io-25.2 {Tcl_GetChannelHandle, output} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [tell $f]
    flush $f
    lappend l [testchannel outputbuffered $f]
    lappend l [tell $f]
    close $f
    removeFile test1
    set l
} {6 6 0 6}

test io-26.1 {Tcl_GetChannelInstanceData} {stdio} {
    # "pid" command uses Tcl_GetChannelInstanceData
    # Don't care what pid is (but must be a number), just want to exercise it.

    set f [open "|[list $tcltest << exit]"]
    expr [pid $f]
    close $f
} {}    

# Test flushing. The functions tested here are FlushChannel.

test io-27.1 {FlushChannel, no output buffered} {
    removeFile test1
    set f [open test1 w]
    flush $f
    set s [file size test1]
    close $f
    set s
} 0
test io-27.2 {FlushChannel, some output buffered} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set l ""
    puts $f hello
    lappend l [file size test1]
    flush $f
    lappend l [file size test1]
    close $f
    lappend l [file size test1]
    set l
} {0 6 6}
test io-27.3 {FlushChannel, implicit flush on close} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set l ""
    puts $f hello
    lappend l [file size test1]
    close $f
    lappend l [file size test1]
    set l
} {0 6}
test io-27.4 {FlushChannel, implicit flush when buffer fills} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    fconfigure $f -buffersize 60
    set l ""
    lappend l [file size test1]
    for {set i 0} {$i < 12} {incr i} {
	puts $f hello
    }
    lappend l [file size test1]
    flush $f
    lappend l [file size test1]
    close $f
    set l
} {0 60 72}
test io-27.5 {FlushChannel, implicit flush when buffer fills and on close} \
	{unixOrPc} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffersize 60 -eofchar {}
    set l ""
    lappend l [file size test1]
    for {set i 0} {$i < 12} {incr i} {
	puts $f hello
    }
    lappend l [file size test1]
    close $f
    lappend l [file size test1]
    set l
} {0 60 72}
test io-27.6 {FlushChannel, async flushing, async close} \
	{stdio asyncPipeClose} {
    removeFile pipe
    removeFile output
    set f [open pipe w]
    puts $f {
	set f [open output w]
	fconfigure $f -translation lf -buffering none -eofchar {}
	while {![eof stdin]} {
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
    set counter 0
    while {([file size output] < 65536) && ($counter < 1000)} {
        incr counter
        after 20
        update
    }
    if {$counter == 1000} {
        set result probably_broken
    } else {
        set result ok
    }
} ok

# Tests closing a channel. The functions tested are CloseChannel and Tcl_Close.

test io-5.1 {CloseChannel called when all references are dropped} {
    removeFile test1
    set f [open test1 w]
    interp create x
    interp share "" $f x
    set l ""
    lappend l [testchannel refcount $f]
    x eval close $f
    interp delete x
    lappend l [testchannel refcount $f]
    close $f
    set l
} {2 1}
test io-5.2 {CloseChannel called when all references are dropped} {
    removeFile test1
    set f [open test1 w]
    interp create x
    interp share "" $f x
    puts -nonewline $f abc
    close $f
    x eval puts $f def
    x eval close $f
    interp delete x
    set f [open test1 r]
    set l [gets $f]
    close $f
    set l
} abcdef
test io-5.3 {CloseChannel, not called before output queue is empty} {unixOrPc asyncPipeClose nonPortable tempNotPc} {

    removeFile pipe
    removeFile output
    set f [open pipe w]
    puts $f {

	# Need to not have eof char appended on close, because the other
	# side of the pipe already closed, so that writing would cause an







|







|












|














|
>







2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
    set counter 0
    while {([file size output] < 65536) && ($counter < 1000)} {
        incr counter
        after 20
        update
    }
    if {$counter == 1000} {
        set result "file size only [file size output]"
    } else {
        set result ok
    }
} ok

# Tests closing a channel. The functions tested are CloseChannel and Tcl_Close.

test io-28.1 {CloseChannel called when all references are dropped} {
    removeFile test1
    set f [open test1 w]
    interp create x
    interp share "" $f x
    set l ""
    lappend l [testchannel refcount $f]
    x eval close $f
    interp delete x
    lappend l [testchannel refcount $f]
    close $f
    set l
} {2 1}
test io-28.2 {CloseChannel called when all references are dropped} {
    removeFile test1
    set f [open test1 w]
    interp create x
    interp share "" $f x
    puts -nonewline $f abc
    close $f
    x eval puts $f def
    x eval close $f
    interp delete x
    set f [open test1 r]
    set l [gets $f]
    close $f
    set l
} abcdef
test io-28.3 {CloseChannel, not called before output queue is empty} \
	{stdio asyncPipeClose nonPortable} {
    removeFile pipe
    removeFile output
    set f [open pipe w]
    puts $f {

	# Need to not have eof char appended on close, because the other
	# side of the pipe already closed, so that writing would cause an
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
        set x "$x$x"
    }
    set f [open output w]
    close $f
    set f [open "|[list $tcltest pipe]" r+]
    fconfigure $f -blocking off -eofchar {}

    # Under windows, the first 24576 bytes of $x are copied to $f, and
    # then the writing fails.  

    puts -nonewline $f $x
    close $f
    set counter 0
    while {([file size output] < 20480) && ($counter < 1000)} {
        incr counter
        after 20
        update
    }
    if {$counter == 1000} {
        set result probably_broken
    } else {
        set result ok
    }
} ok
test io-5.4 {Tcl_Close} {
    removeFile test1
    set l ""
    lappend l [lsort [testchannel open]]
    set f [open test1 w]
    lappend l [lsort [testchannel open]]
    close $f
    lappend l [lsort [testchannel open]]
    set x [list $consoleFileNames \
		[lsort [eval list $consoleFileNames $f]] \
		$consoleFileNames]
    string compare $l $x
} 0
test io-5.5 {Tcl_Close vs standard handles} {unixOnly} {
    removeFile script
    set f [open script w]
    puts $f {
	close stdin
	puts [testchannel open]
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    set l [gets $f]
    close $f
    set l
} {file1 file2}

# Test output on channels. The functions tested are Tcl_Write
# and Tcl_Flush.

test io-6.1 {Tcl_Write, channel not writable} {
    list [catch {puts stdin hello} msg] $msg
} {1 {channel "stdin" wasn't opened for writing}}
test io-6.2 {Tcl_Write, empty string} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -eofchar {}
    puts -nonewline $f ""
    close $f
    file size test1
} 0
test io-6.3 {Tcl_Write, nonempty string} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -eofchar {}
    puts -nonewline $f hello
    close $f
    file size test1
} 5
test io-6.4 {Tcl_Write, buffering in full buffering mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffering full -eofchar {}
    puts $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    flush $f
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    close $f
    set l
} {6 0 0 6}
test io-6.5 {Tcl_Write, buffering in line buffering mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffering line -eofchar {}
    puts -nonewline $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    puts $f hello
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    close $f
    set l
} {5 0 0 11}
test io-6.6 {Tcl_Write, buffering in no buffering mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffering none -eofchar {}
    puts -nonewline $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    puts $f hello
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    close $f
    set l
} {0 5 0 11}

test io-6.7 {Tcl_Flush, full buffering} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffering full -eofchar {}
    puts -nonewline $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    puts $f hello
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    flush $f
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    close $f
    set l
} {5 0 11 0 0 11}
test io-6.8 {Tcl_Flush, full buffering} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffering line
    puts -nonewline $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    flush $f
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    puts $f hello
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    flush $f
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    close $f
    set l
} {5 0 0 5 0 11 0 11}
test io-6.9 {Tcl_Flush, channel not writable} {
    list [catch {flush stdin} msg] $msg
} {1 {channel "stdin" wasn't opened for writing}}
test io-6.10 {Tcl_Write, looping and buffering} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    set f2 [open longfile r]
    for {set x 0} {$x < 10} {incr x} {
        puts $f1 [gets $f2]
    }
    close $f2
    close $f1
    file size test1
} 387
test io-6.11 {Tcl_Write, no newline, implicit flush} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -eofchar {}
    set f2 [open longfile r]
    for {set x 0} {$x < 10} {incr x} {
        puts -nonewline $f1 [gets $f2]
    }
    close $f1
    close $f2
    file size test1
} 377
test io-6.12 {Tcl_Write on a pipe} {stdio} {
    removeFile test1
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	set f1 [open longfile r]
	for {set x 0} {$x < 10} {incr x} {
	    puts [gets $f1]
	}
    }
    close $f1
    set f1 [open "|[list $tcltest pipe]" r]
    set f2 [open longfile r]
    set y ok
    for {set x 0} {$x < 10} {incr x} {
        set l1 [gets $f1]
        set l2 [gets $f2]
        if {"$l1" != "$l2"} {
            set y broken
        }
    }
    close $f1
    close $f2
    set y
} ok
test io-6.13 {Tcl_Write to a pipe, line buffered} {stdio} {
    removeFile test1
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	puts [gets stdin]
	puts [gets stdin]
    }
    close $f1
    set y ok
    set f1 [open "|[list $tcltest pipe]" r+]
    fconfigure $f1 -buffering line
    set f2 [open longfile r]
    set line [gets $f2]
    puts $f1 $line
    set backline [gets $f1]
    if {"$line" != "$backline"} {
        set y broken
    }
    set line [gets $f2]
    puts $f1 $line
    set backline [gets $f1]
    if {"$line" != "$backline"} {
        set y broken
    }
    close $f1
    close $f2
    set y
} ok
test io-6.14 {Tcl_Write, buffering and implicit flush at close} {
    removeFile test3
    set f [open test3 w]
    puts -nonewline $f "Text1"
    puts -nonewline $f " Text 2"
    puts $f " Text 3"
    close $f
    set f [open test3 r]
    set x [gets $f]
    close $f
    set x
} {Text1 Text 2 Text 3}
test io-6.15 {Tcl_Flush, channel not open for writing} {
    removeFile test1
    set fd [open test1 w]
    close $fd
    set fd [open test1 r]
    set x [list [catch {flush $fd} msg] $msg]
    close $fd
    string compare $x \
	[list 1 "channel \"$fd\" wasn't opened for writing"]
} 0
test io-6.16 {Tcl_Flush on pipe opened only for reading} {stdio} {
    set fd [open "|[list $tcltest cat longfile]" r]
    set x [list [catch {flush $fd} msg] $msg]
    catch {close $fd}
    string compare $x \
	[list 1 "channel \"$fd\" wasn't opened for writing"]
} 0
test io-6.17 {Tcl_Write buffers, then Tcl_Flush flushes} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf
    puts $f1 hello
    puts $f1 hello
    puts $f1 hello
    flush $f1
    set x [file size test1]
    close $f1
    set x
} 18
test io-6.18 {Tcl_Write and Tcl_Flush intermixed} {
    removeFile test1
    set x ""
    set f1 [open test1 w]
    fconfigure $f1 -translation lf
    puts $f1 hello
    puts $f1 hello
    puts $f1 hello
    flush $f1
    lappend x [file size test1]
    puts $f1 hello
    flush $f1
    lappend x [file size test1]
    puts $f1 hello
    flush $f1
    lappend x [file size test1]
    close $f1
    set x
} {18 24 30}
test io-6.19 {Explicit and implicit flushes} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    set x ""
    puts $f1 hello
    puts $f1 hello
    puts $f1 hello
    flush $f1
    lappend x [file size test1]
    puts $f1 hello
    flush $f1
    lappend x [file size test1]
    puts $f1 hello
    close $f1
    lappend x [file size test1]
    set x
} {18 24 30}
test io-6.20 {Implicit flush when buffer is full} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    set line "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    for {set x 0} {$x < 100} {incr x} {
      puts $f1 $line
    }
    set z ""
    lappend z [file size test1]
    for {set x 0} {$x < 100} {incr x} {
        puts $f1 $line
    }
    lappend z [file size test1]
    close $f1
    lappend z [file size test1]
    set z
} {4096 12288 12600}
test io-6.21 {Tcl_Flush to pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {set x [read stdin 6]}
    puts $f1 {set cnt [string length $x]}
    puts $f1 {puts "read $cnt characters"}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
    flush $f1
    set x [gets $f1]
    catch {close $f1}
    set x
} "read 6 characters"
test io-6.22 {Tcl_Flush called at other end of pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	fconfigure stdout -buffering full
	puts hello
	puts hello
	flush stdout







<
<
<














|












|













<
<
<
|


|







|







|













|













|













>
|
















|



















|


|





|





|





|





|














|
|
|
|
|





|
















|





|





|











|









|






|











|


















|

















|










|






|













|







2132
2133
2134
2135
2136
2137
2138



2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179



2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
        set x "$x$x"
    }
    set f [open output w]
    close $f
    set f [open "|[list $tcltest pipe]" r+]
    fconfigure $f -blocking off -eofchar {}




    puts -nonewline $f $x
    close $f
    set counter 0
    while {([file size output] < 20480) && ($counter < 1000)} {
        incr counter
        after 20
        update
    }
    if {$counter == 1000} {
        set result probably_broken
    } else {
        set result ok
    }
} ok
test io-28.4 {Tcl_Close} {
    removeFile test1
    set l ""
    lappend l [lsort [testchannel open]]
    set f [open test1 w]
    lappend l [lsort [testchannel open]]
    close $f
    lappend l [lsort [testchannel open]]
    set x [list $consoleFileNames \
		[lsort [eval list $consoleFileNames $f]] \
		$consoleFileNames]
    string compare $l $x
} 0
test io-28.5 {Tcl_Close vs standard handles} {stdio unixOnly} {
    removeFile script
    set f [open script w]
    puts $f {
	close stdin
	puts [testchannel open]
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    set l [gets $f]
    close $f
    set l
} {file1 file2}




test io-29.1 {Tcl_WriteChars, channel not writable} {
    list [catch {puts stdin hello} msg] $msg
} {1 {channel "stdin" wasn't opened for writing}}
test io-29.2 {Tcl_WriteChars, empty string} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -eofchar {}
    puts -nonewline $f ""
    close $f
    file size test1
} 0
test io-29.3 {Tcl_WriteChars, nonempty string} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -eofchar {}
    puts -nonewline $f hello
    close $f
    file size test1
} 5
test io-29.4 {Tcl_WriteChars, buffering in full buffering mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffering full -eofchar {}
    puts $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    flush $f
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    close $f
    set l
} {6 0 0 6}
test io-29.5 {Tcl_WriteChars, buffering in line buffering mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffering line -eofchar {}
    puts -nonewline $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    puts $f hello
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    close $f
    set l
} {5 0 0 11}
test io-29.6 {Tcl_WriteChars, buffering in no buffering mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffering none -eofchar {}
    puts -nonewline $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    puts $f hello
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    close $f
    set l
} {0 5 0 11}

test io-29.7 {Tcl_Flush, full buffering} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffering full -eofchar {}
    puts -nonewline $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    puts $f hello
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    flush $f
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    close $f
    set l
} {5 0 11 0 0 11}
test io-29.8 {Tcl_Flush, full buffering} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -buffering line
    puts -nonewline $f hello
    set l ""
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    flush $f
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    puts $f hello
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    flush $f
    lappend l [testchannel outputbuffered $f]
    lappend l [file size test1]
    close $f
    set l
} {5 0 0 5 0 11 0 11}
test io-29.9 {Tcl_Flush, channel not writable} {
    list [catch {flush stdin} msg] $msg
} {1 {channel "stdin" wasn't opened for writing}}
test io-29.10 {Tcl_WriteChars, looping and buffering} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    set f2 [open longfile r]
    for {set x 0} {$x < 10} {incr x} {
	puts $f1 [gets $f2]
    }
    close $f2
    close $f1
    file size test1
} 387
test io-29.11 {Tcl_WriteChars, no newline, implicit flush} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -eofchar {}
    set f2 [open longfile r]
    for {set x 0} {$x < 10} {incr x} {
	puts -nonewline $f1 [gets $f2]
    }
    close $f1
    close $f2
    file size test1
} 377
test io-29.12 {Tcl_WriteChars on a pipe} {stdio} {
    removeFile test1
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	set f1 [open longfile r]
	for {set x 0} {$x < 10} {incr x} {
	    puts [gets $f1]
	}
    }
    close $f1
    set f1 [open "|[list $tcltest pipe]" r]
    set f2 [open longfile r]
    set y ok
    for {set x 0} {$x < 10} {incr x} {
	set l1 [gets $f1]
	set l2 [gets $f2]
	if {"$l1" != "$l2"} {
	    set y broken
	}
    }
    close $f1
    close $f2
    set y
} ok
test io-29.13 {Tcl_WriteChars to a pipe, line buffered} {stdio} {
    removeFile test1
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	puts [gets stdin]
	puts [gets stdin]
    }
    close $f1
    set y ok
    set f1 [open "|[list $tcltest pipe]" r+]
    fconfigure $f1 -buffering line
    set f2 [open longfile r]
    set line [gets $f2]
    puts $f1 $line
    set backline [gets $f1]
    if {"$line" != "$backline"} {
	set y broken
    }
    set line [gets $f2]
    puts $f1 $line
    set backline [gets $f1]
    if {"$line" != "$backline"} {
	set y broken
    }
    close $f1
    close $f2
    set y
} ok
test io-29.14 {Tcl_WriteChars, buffering and implicit flush at close} {
    removeFile test3
    set f [open test3 w]
    puts -nonewline $f "Text1"
    puts -nonewline $f " Text 2"
    puts $f " Text 3"
    close $f
    set f [open test3 r]
    set x [gets $f]
    close $f
    set x
} {Text1 Text 2 Text 3}
test io-29.15 {Tcl_Flush, channel not open for writing} {
    removeFile test1
    set fd [open test1 w]
    close $fd
    set fd [open test1 r]
    set x [list [catch {flush $fd} msg] $msg]
    close $fd
    string compare $x \
	[list 1 "channel \"$fd\" wasn't opened for writing"]
} 0
test io-29.16 {Tcl_Flush on pipe opened only for reading} {stdio} {
    set fd [open "|[list $tcltest cat longfile]" r]
    set x [list [catch {flush $fd} msg] $msg]
    catch {close $fd}
    string compare $x \
	[list 1 "channel \"$fd\" wasn't opened for writing"]
} 0
test io-29.17 {Tcl_WriteChars buffers, then Tcl_Flush flushes} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf
    puts $f1 hello
    puts $f1 hello
    puts $f1 hello
    flush $f1
    set x [file size test1]
    close $f1
    set x
} 18
test io-29.18 {Tcl_WriteChars and Tcl_Flush intermixed} {
    removeFile test1
    set x ""
    set f1 [open test1 w]
    fconfigure $f1 -translation lf
    puts $f1 hello
    puts $f1 hello
    puts $f1 hello
    flush $f1
    lappend x [file size test1]
    puts $f1 hello
    flush $f1
    lappend x [file size test1]
    puts $f1 hello
    flush $f1
    lappend x [file size test1]
    close $f1
    set x
} {18 24 30}
test io-29.19 {Explicit and implicit flushes} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    set x ""
    puts $f1 hello
    puts $f1 hello
    puts $f1 hello
    flush $f1
    lappend x [file size test1]
    puts $f1 hello
    flush $f1
    lappend x [file size test1]
    puts $f1 hello
    close $f1
    lappend x [file size test1]
    set x
} {18 24 30}
test io-29.20 {Implicit flush when buffer is full} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    set line "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    for {set x 0} {$x < 100} {incr x} {
      puts $f1 $line
    }
    set z ""
    lappend z [file size test1]
    for {set x 0} {$x < 100} {incr x} {
	puts $f1 $line
    }
    lappend z [file size test1]
    close $f1
    lappend z [file size test1]
    set z
} {4096 12288 12600}
test io-29.21 {Tcl_Flush to pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {set x [read stdin 6]}
    puts $f1 {set cnt [string length $x]}
    puts $f1 {puts "read $cnt characters"}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
    flush $f1
    set x [gets $f1]
    catch {close $f1}
    set x
} "read 6 characters"
test io-29.22 {Tcl_Flush called at other end of pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	fconfigure stdout -buffering full
	puts hello
	puts hello
	flush stdout
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
    lappend x [gets $f1]
    puts $f1 hello
    flush $f1
    lappend x [gets $f1]
    close $f1
    set x
} {hello hello bye}
test io-6.23 {Tcl_Flush and line buffering at end of pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	puts hello
	puts hello
	gets stdin
	puts bye
    }
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    set x ""
    lappend x [gets $f1]
    lappend x [gets $f1]
    puts $f1 hello
    flush $f1
    lappend x [gets $f1]
    close $f1
    set x
} {hello hello bye}
test io-6.24 {Tcl_Write and Tcl_Flush move end of file} {
    set f [open test3 w]
    puts $f "Line 1"
    puts $f "Line 2"
    set f2 [open test3]
    set x {}
    lappend x [read -nonewline $f2]
    close $f2
    flush $f
    set f2 [open test3]
    lappend x [read -nonewline $f2]
    close $f2
    close $f
    set x
} {{} {Line 1
Line 2}}
test io-6.25 {Implicit flush with Tcl_Flush to command pipelines} {stdio} {
    removeFile test3
    set f [open "|[list $tcltest cat | $tcltest cat > test3]" w]
    puts $f "Line 1"
    puts $f "Line 2"
    close $f
    after 100
    set f [open test3 r]
    set x [read $f]
    close $f
    set x
} {Line 1
Line 2
}    
test io-6.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} {unixOrPc && unixExecs && tempNotPc} {
    set f [open "|[list cat -u]" r+]
    puts $f "Line1"
    flush $f
    set x [gets $f]
    close $f
    set x
} {Line1}
test io-6.27 {Tcl_Flush on closed pipeline} {stdio && tempNotPc} {
    removeFile pipe
    set f [open pipe w]
    puts $f {exit}
    close $f
    set f [open "|[list $tcltest pipe]" r+]
    gets $f
    puts $f output







|



















|













|
<
|










<
|
<
|







|







2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527

2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538

2539

2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
    lappend x [gets $f1]
    puts $f1 hello
    flush $f1
    lappend x [gets $f1]
    close $f1
    set x
} {hello hello bye}
test io-29.23 {Tcl_Flush and line buffering at end of pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	puts hello
	puts hello
	gets stdin
	puts bye
    }
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    set x ""
    lappend x [gets $f1]
    lappend x [gets $f1]
    puts $f1 hello
    flush $f1
    lappend x [gets $f1]
    close $f1
    set x
} {hello hello bye}
test io-29.24 {Tcl_WriteChars and Tcl_Flush move end of file} {
    set f [open test3 w]
    puts $f "Line 1"
    puts $f "Line 2"
    set f2 [open test3]
    set x {}
    lappend x [read -nonewline $f2]
    close $f2
    flush $f
    set f2 [open test3]
    lappend x [read -nonewline $f2]
    close $f2
    close $f
    set x
} "{} {Line 1\nLine 2}"

test io-29.25 {Implicit flush with Tcl_Flush to command pipelines} {stdio} {
    removeFile test3
    set f [open "|[list $tcltest cat | $tcltest cat > test3]" w]
    puts $f "Line 1"
    puts $f "Line 2"
    close $f
    after 100
    set f [open test3 r]
    set x [read $f]
    close $f
    set x

} "Line 1\nLine 2\n"

test io-29.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} {stdio unixExecs} {
    set f [open "|[list cat -u]" r+]
    puts $f "Line1"
    flush $f
    set x [gets $f]
    close $f
    set x
} {Line1}
test io-29.27 {Tcl_Flush on closed pipeline} {stdio} {
    removeFile pipe
    set f [open pipe w]
    puts $f {exit}
    close $f
    set f [open "|[list $tcltest pipe]" r+]
    gets $f
    puts $f output
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123

1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
	} else {
	    set x {this was supposed to fail and did not}
	}
    }
    regsub {".*":} $x {"":} x
    string tolower $x
} {1 {error flushing "": broken pipe} {posix epipe {broken pipe}}}
test io-6.28 {Tcl_Write, lf mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    puts $f hello\nthere\nand\nhere
    flush $f
    set s [file size test1]
    close $f
    set s
} 21
test io-6.29 {Tcl_Write, cr mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    puts $f hello\nthere\nand\nhere
    close $f
    file size test1
} 21
test io-6.30 {Tcl_Write, crlf mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    puts $f hello\nthere\nand\nhere
    close $f
    file size test1
} 25
test io-6.31 {Tcl_Write, background flush} {stdio} {
    removeFile pipe
    removeFile output
    set f [open pipe w]
    puts $f {set f [open output w]}
    puts $f {fconfigure $f -translation lf}
    set x [list while {![eof stdin]}]
    set x "$x {"
    puts $f $x
    puts $f {  puts -nonewline $f [read stdin 4096]}
    puts $f {  flush $f}
    puts $f "}"
    puts $f {close $f}
    close $f
    set x 01234567890123456789012345678901
    for {set i 0} {$i < 11} {incr i} {
        set x "$x$x"
    }
    set f [open output w]
    close $f
    set f [open "|[list $tcltest pipe]" r+]
    fconfigure $f -blocking off
    puts -nonewline $f $x
    close $f
    set counter 0
    while {([file size output] < 65536) && ($counter < 1000)} {
        incr counter
        after 5
        update
    }
    if {$counter == 1000} {
        set result probably_broken
    } else {
        set result ok
    }
} ok
test io-6.32 {Tcl_Write, background flush to slow reader} {stdio && asyncPipeClose} {

    removeFile pipe
    removeFile output
    set f [open pipe w]
    puts $f {set f [open output w]}
    puts $f {fconfigure $f -translation lf}
    set x [list while {![eof stdin]}]
    set x "$x {"
    puts $f $x
    puts $f {  after 20}
    puts $f {  puts -nonewline $f [read stdin 1024]}
    puts $f {  flush $f}
    puts $f "}"
    puts $f {close $f}
    close $f
    set x 01234567890123456789012345678901
    for {set i 0} {$i < 11} {incr i} {
        set x "$x$x"
    }
    set f [open output w]
    close $f
    set f [open "|[list $tcltest pipe]" r+]
    fconfigure $f -blocking off
    puts -nonewline $f $x
    close $f
    set counter 0
    while {([file size output] < 65536) && ($counter < 1000)} {
        incr counter
        after 20
        update
    }
    if {$counter == 1000} {
        set result probably_broken
    } else {
        set result ok
    }
} ok
test io-6.33 {Tcl_Flush, implicit flush on exit} {stdio} {
    set f [open script w]
    puts $f {
	set f [open test1 w]
	fconfigure $f -translation lf
	puts $f hello
	puts $f bye
	puts $f strange
    }
    close $f
    exec $tcltest script
    set f [open test1 r]
    set r [read $f]
    close $f
    set r
} {hello
bye
strange
}

test io-6.34 {Tcl_Close, async flush on close, using sockets} {socket tempNotMac} {
    set c 0
    set x running
    set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
    proc writelots {s l} {
	for {set i 0} {$i < 2000} {incr i} {
	    puts $s $l
	}







|









|







|







|















|









|
|
|


|

|


|
>
















|









|
|
|


|

|


|














<
<
|
<
<
|







2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690


2691


2692
2693
2694
2695
2696
2697
2698
2699
	} else {
	    set x {this was supposed to fail and did not}
	}
    }
    regsub {".*":} $x {"":} x
    string tolower $x
} {1 {error flushing "": broken pipe} {posix epipe {broken pipe}}}
test io-29.28 {Tcl_WriteChars, lf mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    puts $f hello\nthere\nand\nhere
    flush $f
    set s [file size test1]
    close $f
    set s
} 21
test io-29.29 {Tcl_WriteChars, cr mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    puts $f hello\nthere\nand\nhere
    close $f
    file size test1
} 21
test io-29.30 {Tcl_WriteChars, crlf mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    puts $f hello\nthere\nand\nhere
    close $f
    file size test1
} 25
test io-29.31 {Tcl_WriteChars, background flush} {stdio} {
    removeFile pipe
    removeFile output
    set f [open pipe w]
    puts $f {set f [open output w]}
    puts $f {fconfigure $f -translation lf}
    set x [list while {![eof stdin]}]
    set x "$x {"
    puts $f $x
    puts $f {  puts -nonewline $f [read stdin 4096]}
    puts $f {  flush $f}
    puts $f "}"
    puts $f {close $f}
    close $f
    set x 01234567890123456789012345678901
    for {set i 0} {$i < 11} {incr i} {
	set x "$x$x"
    }
    set f [open output w]
    close $f
    set f [open "|[list $tcltest pipe]" r+]
    fconfigure $f -blocking off
    puts -nonewline $f $x
    close $f
    set counter 0
    while {([file size output] < 65536) && ($counter < 1000)} {
	incr counter
	after 5
	update
    }
    if {$counter == 1000} {
	set result "file size only [file size output]"
    } else {
	set result ok
    }
} ok
test io-29.32 {Tcl_WriteChars, background flush to slow reader} \
	{stdio asyncPipeClose} {
    removeFile pipe
    removeFile output
    set f [open pipe w]
    puts $f {set f [open output w]}
    puts $f {fconfigure $f -translation lf}
    set x [list while {![eof stdin]}]
    set x "$x {"
    puts $f $x
    puts $f {  after 20}
    puts $f {  puts -nonewline $f [read stdin 1024]}
    puts $f {  flush $f}
    puts $f "}"
    puts $f {close $f}
    close $f
    set x 01234567890123456789012345678901
    for {set i 0} {$i < 11} {incr i} {
	set x "$x$x"
    }
    set f [open output w]
    close $f
    set f [open "|[list $tcltest pipe]" r+]
    fconfigure $f -blocking off
    puts -nonewline $f $x
    close $f
    set counter 0
    while {([file size output] < 65536) && ($counter < 1000)} {
	incr counter
	after 20
	update
    }
    if {$counter == 1000} {
	set result "file size only [file size output]"
    } else {
	set result ok
    }
} ok
test io-29.33 {Tcl_Flush, implicit flush on exit} {stdio} {
    set f [open script w]
    puts $f {
	set f [open test1 w]
	fconfigure $f -translation lf
	puts $f hello
	puts $f bye
	puts $f strange
    }
    close $f
    exec $tcltest script
    set f [open test1 r]
    set r [read $f]
    close $f
    set r


} "hello\nbye\nstrange\n"


test io-29.34 {Tcl_Close, async flush on close, using sockets} {socket tempNotMac} {
    set c 0
    set x running
    set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
    proc writelots {s l} {
	for {set i 0} {$i < 2000} {incr i} {
	    puts $s $l
	}
1209
1210
1211
1212
1213
1214
1215
1216



1217
1218
1219
1220
1221
1222
1223
    fconfigure $cs -blocking off
    writelots $cs $l
    close $cs
    close $ss
    vwait x
    set c
} 2000
test io-6.35 {Tcl_Close vs fileevent vs multiple interpreters} {socket} {



    catch {interp delete x}
    catch {interp delete y}
    interp create x
    interp create y
    set s [socket -server accept 2828]
    proc accept {s a p} {
	puts $s hello







|
>
>
>







2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
    fconfigure $cs -blocking off
    writelots $cs $l
    close $cs
    close $ss
    vwait x
    set c
} 2000
test io-29.35 {Tcl_Close vs fileevent vs multiple interpreters} {socket tempNotMac} {
    # On Mac, this test screws up sockets such that subsequent tests using port 2828 
    # either cause errors or panic().
     
    catch {interp delete x}
    catch {interp delete y}
    interp create x
    interp create y
    set s [socket -server accept 2828]
    proc accept {s a p} {
	puts $s hello
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496




















1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
    close $s
    interp delete x
    interp delete y
} ""

# Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.

test io-7.1 {Tcl_Write lf, Tcl_Read lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set x [read $f]
    close $f
    set x
} "hello\nthere\nand\nhere\n"
test io-7.2 {Tcl_Write lf, Tcl_Read cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set x [read $f]
    close $f
    set x
} "hello\nthere\nand\nhere\n"
test io-7.3 {Tcl_Write lf, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set x [read $f]
    close $f
    set x
} "hello\nthere\nand\nhere\n"
test io-7.4 {Tcl_Write cr, Tcl_Read cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set x [read $f]
    close $f
    set x
} "hello\nthere\nand\nhere\n"
test io-7.5 {Tcl_Write cr, Tcl_Read lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set x [read $f]
    close $f
    set x
} "hello\rthere\rand\rhere\r"
test io-7.6 {Tcl_Write cr, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set x [read $f]
    close $f
    set x 
} "hello\rthere\rand\rhere\r"
test io-7.7 {Tcl_Write crlf, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set x [read $f]
    close $f
    set x
} "hello\nthere\nand\nhere\n"
test io-7.8 {Tcl_Write crlf, Tcl_Read lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set x [read $f]
    close $f
    set x
} "hello\r\nthere\r\nand\r\nhere\r\n"
test io-7.9 {Tcl_Write crlf, Tcl_Read cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set x [read $f]
    close $f
    set x
} "hello\n\nthere\n\nand\n\nhere\n\n"
test io-7.10 {Tcl_Write lf, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set c [read $f]
    set x [fconfigure $f -translation]
    close $f
    list $c $x
} {{hello
there
and
here
} auto}
test io-7.11 {Tcl_Write cr, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set c [read $f]
    set x [fconfigure $f -translation]
    close $f
    list $c $x
} {{hello
there
and
here
} auto}
test io-7.12 {Tcl_Write crlf, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set c [read $f]
    set x [fconfigure $f -translation]
    close $f
    list $c $x
} {{hello
there
and
here
} auto}

test io-7.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set line "123456789ABCDE"	;# 14 char plus crlf
    puts -nonewline $f x	;# shift crlf across block boundary
    for {set i 0} {$i < 700} {incr i} {
	puts $f $line
    }
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set c [read $f]
    close $f
    string length $c
} [expr 700*15+1]

test io-7.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set line "123456789ABCDE"	;# 14 char plus crlf
    puts -nonewline $f x	;# shift crlf across block boundary
    for {set i 0} {$i < 700} {incr i} {
	puts $f $line
    }
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set c [read $f]
    close $f
    string length $c
} [expr 700*15+1]

test io-7.15 {Tcl_Write mixed, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\rhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set c [read $f]
    close $f
    set c
} {hello
there
and
here
}
test io-7.16 {Tcl_Write ^Z at end, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f hello\nthere\nand\rhere\n\x1a
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set c [read $f]
    close $f
    set c
} {hello
there
and
here
}
test io-7.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} {pcOnly} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -eofchar \x1a -translation lf
    puts $f hello\nthere\nand\rhere
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set c [read $f]
    close $f
    set c
} {hello
there
and
here
}
test io-7.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} {




















    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cghi\nqrs" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1 {} 1}
test io-7.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cghi\nqrs" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1 {} 1}
test io-7.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set s [format "abc\ndef\n%cghi\nqrs" 26]
    puts $f $s
    close $f
    set f [open test1 r]







|











|











|











|











|











|











|











|











|











|















|















|
















|
















|
















|















|















|















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



















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







2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050




















3051
3052
3053
3054
3055
3056
3057
3058
    close $s
    interp delete x
    interp delete y
} ""

# Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.

test io-30.1 {Tcl_Write lf, Tcl_Read lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set x [read $f]
    close $f
    set x
} "hello\nthere\nand\nhere\n"
test io-30.2 {Tcl_Write lf, Tcl_Read cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set x [read $f]
    close $f
    set x
} "hello\nthere\nand\nhere\n"
test io-30.3 {Tcl_Write lf, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set x [read $f]
    close $f
    set x
} "hello\nthere\nand\nhere\n"
test io-30.4 {Tcl_Write cr, Tcl_Read cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set x [read $f]
    close $f
    set x
} "hello\nthere\nand\nhere\n"
test io-30.5 {Tcl_Write cr, Tcl_Read lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set x [read $f]
    close $f
    set x
} "hello\rthere\rand\rhere\r"
test io-30.6 {Tcl_Write cr, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set x [read $f]
    close $f
    set x 
} "hello\rthere\rand\rhere\r"
test io-30.7 {Tcl_Write crlf, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set x [read $f]
    close $f
    set x
} "hello\nthere\nand\nhere\n"
test io-30.8 {Tcl_Write crlf, Tcl_Read lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set x [read $f]
    close $f
    set x
} "hello\r\nthere\r\nand\r\nhere\r\n"
test io-30.9 {Tcl_Write crlf, Tcl_Read cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set x [read $f]
    close $f
    set x
} "hello\n\nthere\n\nand\n\nhere\n\n"
test io-30.10 {Tcl_Write lf, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set c [read $f]
    set x [fconfigure $f -translation]
    close $f
    list $c $x
} {{hello
there
and
here
} auto}
test io-30.11 {Tcl_Write cr, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set c [read $f]
    set x [fconfigure $f -translation]
    close $f
    list $c $x
} {{hello
there
and
here
} auto}
test io-30.12 {Tcl_Write crlf, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set c [read $f]
    set x [fconfigure $f -translation]
    close $f
    list $c $x
} {{hello
there
and
here
} auto}

test io-30.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set line "123456789ABCDE"	;# 14 char plus crlf
    puts -nonewline $f x	;# shift crlf across block boundary
    for {set i 0} {$i < 700} {incr i} {
	puts $f $line
    }
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set c [read $f]
    close $f
    string length $c
} [expr 700*15+1]

test io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set line "123456789ABCDE"	;# 14 char plus crlf
    puts -nonewline $f x	;# shift crlf across block boundary
    for {set i 0} {$i < 700} {incr i} {
	puts $f $line
    }
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set c [read $f]
    close $f
    string length $c
} [expr 700*15+1]

test io-30.15 {Tcl_Write mixed, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\rhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set c [read $f]
    close $f
    set c
} {hello
there
and
here
}
test io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f hello\nthere\nand\rhere\n\x1a
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set c [read $f]
    close $f
    set c
} {hello
there
and
here
}
test io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} {pcOnly} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -eofchar \x1a -translation lf
    puts $f hello\nthere\nand\rhere
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set c [read $f]
    close $f
    set c
} {hello
there
and
here
}
test io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cghi\nqrs" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1 {} 1}
test io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cghi\nqrs" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1 {} 1}




















test io-30.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set s [format "abc\ndef\n%cghi\nqrs" 26]
    puts $f $s
    close $f
    set f [open test1 r]
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} "abc def 0 \x1aghi 0 qrs 0 {} 1"
test io-7.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set s [format "abc\ndef\n%cghi\nqrs" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar {}
    set l ""
    set x [gets $f]
    lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs"]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {0 1 {} 1}
test io-7.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set s [format "abc\ndef\n%cghi\nqrs" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar {}
    set l ""
    set x [gets $f]
    lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs"]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {0 1 {} 1}
test io-7.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}
test io-7.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}
test io-7.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}
test io-7.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}
test io-7.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}
test io-7.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}

# Test end of line translations. Functions tested are Tcl_Write and Tcl_Gets.

test io-8.1 {Tcl_Write lf, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    close $f
    set l
} {hello 6 auto there 12 auto}
test io-8.2 {Tcl_Write cr, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    close $f
    set l
} {hello 6 auto there 12 auto}
test io-8.3 {Tcl_Write crlf, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    close $f
    set l
} {hello 7 auto there 14 auto}
test io-8.4 {Tcl_Write lf, Tcl_Gets lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    close $f
    set l
} {hello 6 lf there 12 lf}
test io-8.5 {Tcl_Write lf, Tcl_Gets cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set l ""
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {20 21 cr 1 {} 21 cr 1}
test io-8.6 {Tcl_Write lf, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set l ""
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {20 21 crlf 1 {} 21 crlf 1}
test io-8.7 {Tcl_Write cr, Tcl_Gets cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {hello 6 cr 0 there 12 cr 0}
test io-8.8 {Tcl_Write cr, Tcl_Gets lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set l ""
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {21 21 lf 1 {} 21 lf 1}
test io-8.9 {Tcl_Write cr, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set l ""
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {21 21 crlf 1 {} 21 crlf 1}
test io-8.10 {Tcl_Write crlf, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {hello 7 crlf 0 there 14 crlf 0}
test io-8.11 {Tcl_Write crlf, Tcl_Gets cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {hello 6 cr 0 6 13 cr 0}
test io-8.12 {Tcl_Write crlf, Tcl_Gets lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set l ""
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {6 7 lf 0 6 14 lf 0}
test io-8.13 {binary mode is synonym of lf mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation binary
    set x [fconfigure $f -translation]
    close $f
    set x
} lf
#
# Test io-9.14 has been removed because "auto" output translation mode is
# not supoprted.
#
test io-8.14 {Tcl_Write mixed, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\rand\r\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-8.15 {Tcl_Write mixed, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f hello\nthere\rand\r\nhere\r
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-8.16 {Tcl_Write mixed, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f hello\nthere\rand\r\nhere\n
    close $f
    set f [open test1 r]
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-8.17 {Tcl_Write mixed, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f hello\nthere\rand\r\nhere\r\n
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-8.18 {Tcl_Write ^Z at end, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "hello\nthere\nand\rhere\n\%c" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-8.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -eofchar \x1a -translation lf
    puts $f hello\nthere\nand\rhere
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-8.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a
    fconfigure $f -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-8.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-8.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]







|










|






|










|






|













|













|













|













|













|
















|
















|
















|
















|

















|


















|
|


















|
|



















|



















|



















|



















|



















|



















|











|


















|


















|

















|


















|



















|


















|


















|

















|







3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} "abc def 0 \x1aghi 0 qrs 0 {} 1"
test io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set s [format "abc\ndef\n%cghi\nqrs" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar {}
    set l ""
    set x [gets $f]
    lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs\n"]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {0 1 {} 1}
test io-30.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set s [format "abc\ndef\n%cghi\nqrs" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar {}
    set l ""
    set x [gets $f]
    lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs\n"]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {0 1 {} 1}
test io-30.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}
test io-30.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}
test io-30.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}
test io-30.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}
test io-30.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}
test io-30.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format abc\ndef\n%cqrs\ntuv 26]
    puts $f $c
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar \x1a
    set c [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $e
} {8 1}

# Test end of line translations. Functions tested are Tcl_Write and Tcl_Gets.

test io-31.1 {Tcl_Write lf, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    close $f
    set l
} {hello 6 auto there 12 auto}
test io-31.2 {Tcl_Write cr, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    close $f
    set l
} {hello 6 auto there 12 auto}
test io-31.3 {Tcl_Write crlf, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    close $f
    set l
} {hello 7 auto there 14 auto}
test io-31.4 {Tcl_Write lf, Tcl_Gets lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    close $f
    set l
} {hello 6 lf there 12 lf}
test io-31.5 {Tcl_Write lf, Tcl_Gets cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set l ""
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {21 21 cr 1 {} 21 cr 1}
test io-31.6 {Tcl_Write lf, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set l ""
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {21 21 crlf 1 {} 21 crlf 1}
test io-31.7 {Tcl_Write cr, Tcl_Gets cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {hello 6 cr 0 there 12 cr 0}
test io-31.8 {Tcl_Write cr, Tcl_Gets lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set l ""
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {21 21 lf 1 {} 21 lf 1}
test io-31.9 {Tcl_Write cr, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set l ""
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {21 21 crlf 1 {} 21 crlf 1}
test io-31.10 {Tcl_Write crlf, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {hello 7 crlf 0 there 14 crlf 0}
test io-31.11 {Tcl_Write crlf, Tcl_Gets cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr
    set l ""
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {hello 6 cr 0 6 13 cr 0}
test io-31.12 {Tcl_Write crlf, Tcl_Gets lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    puts $f hello\nthere\nand\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf
    set l ""
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    lappend l [string length [gets $f]]
    lappend l [tell $f]
    lappend l [fconfigure $f -translation]
    lappend l [eof $f]
    close $f
    set l
} {6 7 lf 0 6 14 lf 0}
test io-31.13 {binary mode is synonym of lf mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation binary
    set x [fconfigure $f -translation]
    close $f
    set x
} lf
#
# Test io-9.14 has been removed because "auto" output translation mode is
# not supoprted.
#
test io-31.14 {Tcl_Write mixed, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts $f hello\nthere\rand\r\nhere
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-31.15 {Tcl_Write mixed, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f hello\nthere\rand\r\nhere\r
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-31.16 {Tcl_Write mixed, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f hello\nthere\rand\r\nhere\n
    close $f
    set f [open test1 r]
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-31.17 {Tcl_Write mixed, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f hello\nthere\rand\r\nhere\r\n
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "hello\nthere\nand\rhere\n\%c" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -eofchar \x1a -translation lf
    puts $f hello\nthere\nand\rhere
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {hello there and here 0 {} 1}
test io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a
    fconfigure $f -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-31.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
test io-8.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]







|







3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
test io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
test io-8.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]







|







3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
test io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246



















2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
test io-8.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-8.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-8.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-8.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-8.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-8.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}



















test io-8.31 {Tcl_Write crlf on block boundary, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set line "123456789ABCDE"	;# 14 char plus crlf
    puts -nonewline $f x	;# shift crlf across block boundary
    for {set i 0} {$i < 700} {incr i} {
	puts $f $line
    }
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set c ""
    while {[gets $f line] >= 0} {
	append c $line\n
    }
    close $f
    string length $c
} [expr 700*15+1]
test io-8.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set line "123456789ABCDE"	;# 14 char plus crlf
    puts -nonewline $f x	;# shift crlf across block boundary
    for {set i 0} {$i < 256} {incr i} {
	puts $f $line
    }
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set c ""
    while {[gets $f line] >= 0} {
	append c $line\n
    }
    close $f
    string length $c
} [expr 256*15+1]


# Test Tcl_Read and buffering.

test io-9.1 {Tcl_Read, channel not readable} {
    list [catch {read stdout} msg] $msg
} {1 {channel "stdout" wasn't opened for reading}}
test io-9.2 {Tcl_Read, zero byte count} {
    read stdin 0
} ""
test io-9.3 {Tcl_Read, negative byte count} {
    set f [open longfile r]
    set l [list [catch {read $f -1} msg] $msg]
    close $f
    set l
} {1 {bad argument "-1": should be "nonewline"}}
test io-9.4 {Tcl_Read, positive byte count} {
    set f [open longfile r]
    set x [read $f 1024]
    set s [string length $x]
    unset x
    close $f
    set s
} 1024
test io-9.5 {Tcl_Read, multiple buffers} {
    set f [open longfile r]
    fconfigure $f -buffersize 100
    set x [read $f 1024]
    set s [string length $x]
    unset x
    close $f
    set s
} 1024
test io-9.6 {Tcl_Read, very large read} {
    set f1 [open longfile r]
    set z [read $f1 1000000]
    close $f1
    set l [string length $z]
    set x ok
    set z [file size longfile]
    if {$z != $l} {
        set x broken
    }
    set x
} ok
test io-9.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
    set f1 [open longfile r]
    fconfigure $f1 -blocking off
    set z [read $f1 20]
    close $f1
    set l [string length $z]
    set x ok
    if {$l != 20} {
        set x broken
    }
    set x
} ok
test io-9.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
    set f1 [open longfile r]
    fconfigure $f1 -blocking off
    set z [read $f1 1000000]
    close $f1
    set x ok
    set l [string length $z]]
    set z [file size longfile]]
    if {$z != $l} {
        set x broken
    }
  set x
} ok
test io-9.9 {Tcl_Read, read to end of file} {
    set f1 [open longfile r]
    set z [read $f1]
    close $f1
    set l [string length $z]
    set x ok
    set z [file size longfile]
    if {$z != $l} {
        set x broken
    }
    set x
} ok
test io-9.10 {Tcl_Read from a pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {puts [gets stdin]}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
    flush $f1
    set x [read $f1]
    close $f1
    set x
} "hello\n"
test io-9.11 {Tcl_Read from a pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {puts [gets stdin]}
    puts $f1 {puts [gets stdin]}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
    flush $f1
    set x ""
    lappend x [read $f1 6]
    puts $f1 hello
    flush $f1
    lappend x [read $f1]
    close $f1
    set x
} {{hello
} {hello
}}
test io-9.12 {Tcl_Read, -nonewline} {
    removeFile test1
    set f1 [open test1 w]
    puts $f1 hello
    puts $f1 bye
    close $f1
    set f1 [open test1 r]
    set c [read -nonewline $f1]
    close $f1
    set c
} {hello
bye}
test io-9.13 {Tcl_Read, -nonewline} {
    removeFile test1
    set f1 [open test1 w]
    puts $f1 hello
    puts $f1 bye
    close $f1
    set f1 [open test1 r]
    set c [read -nonewline $f1]
    close $f1
    list [string length $c] $c
} {9 {hello
bye}}
test io-9.14 {Tcl_Read, reading in small chunks} {
    removeFile test1
    set f [open test1 w]
    puts $f "Two lines: this one"
    puts $f "and this one"
    close $f
    set f [open test1]
    set x [list [read $f 1] [read $f 2] [read $f]]
    close $f
    set x
} {T wo { lines: this one
and this one
}}
test io-9.15 {Tcl_Read, asking for more input than available} {
    removeFile test1
    set f [open test1 w]
    puts $f "Two lines: this one"
    puts $f "and this one"
    close $f
    set f [open test1]
    set x [read $f 100]
    close $f
    set x
} {Two lines: this one
and this one
}
test io-9.16 {Tcl_Read, read to end of file with -nonewline} {
    removeFile test1
    set f [open test1 w]
    puts $f "Two lines: this one"
    puts $f "and this one"
    close $f
    set f [open test1]
    set x [read -nonewline $f]
    close $f
    set x
} {Two lines: this one
and this one}

# Test Tcl_Gets.

test io-10.1 {Tcl_Gets, reading what was written} {
    removeFile test1
    set f1 [open test1 w]
    set y "first line"
    puts $f1 $y
    close $f1
    set f1 [open test1 r]
    set x [gets $f1]
    set z ok
    if {"$x" != "$y"} {
        set z broken
    }
    close $f1
    set z
} ok
test io-10.2 {Tcl_Gets into variable} {
    set f1 [open longfile r]
    set c [gets $f1 x]
    set l [string length x]
    set z ok
    if {$l != $l} {
        set z broken
    }
    close $f1
    set z
} ok
test io-10.3 {Tcl_Gets from pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {puts [gets stdin]}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
    flush $f1
    set x [gets $f1]
    close $f1
    set z ok
    if {"$x" != "hello"} {
        set z broken
    }
    set z
} ok
test io-10.4 {Tcl_Gets with long line} {
    removeFile test3
    set f [open test3 w]
    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    close $f
    set f [open test3]
    set x [gets $f]
    close $f
    set x
} {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
test io-10.5 {Tcl_Gets with long line} {
    set f [open test3]
    set x [gets $f y]
    close $f
    list $x $y
} {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
test io-10.6 {Tcl_Gets and end of file} {
    removeFile test3
    set f [open test3 w]
    puts -nonewline $f "Test1\nTest2"
    close $f
    set f [open test3]
    set x {}
    set y {}
    lappend x [gets $f y] $y
    set y {}
    lappend x [gets $f y] $y
    set y {}
    lappend x [gets $f y] $y
    close $f
    set x
} {5 Test1 5 Test2 -1 {}}
test io-10.7 {Tcl_Gets and bad variable} {
    set f [open test3 w]
    puts $f "Line 1"
    puts $f "Line 2"
    close $f
    catch {unset x}
    set x 24
    set f [open test3 r]
    set result [list [catch {gets $f x(0)} msg] $msg]
    close $f
    set result
} {1 {can't set "x(0)": variable isn't array}}
test io-10.8 {Tcl_Gets, exercising double buffering} {
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    set x ""
    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
    for {set y 0} {$y < 100} {incr y} {puts $f $x}
    close $f
    set f [open test3 r]
    fconfigure $f -translation lf
    for {set y 0} {$y < 100} {incr y} {gets $f}
    close $f
    set y
} 100
test io-10.9 {Tcl_Gets, exercising double buffering} {
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    set x ""
    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
    for {set y 0} {$y < 200} {incr y} {puts $f $x}
    close $f
    set f [open test3 r]
    fconfigure $f -translation lf
    for {set y 0} {$y < 200} {incr y} {gets $f}
    close $f
    set y
} 200
test io-10.10 {Tcl_Gets, exercising double buffering} {
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    set x ""
    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
    for {set y 0} {$y < 300} {incr y} {puts $f $x}
    close $f
    set f [open test3 r]
    fconfigure $f -translation lf
    for {set y 0} {$y < 300} {incr y} {gets $f}
    close $f
    set y
} 300

# Test Tcl_Seek and Tcl_Tell.

test io-11.1 {Tcl_Seek to current position at start of file} {
    set f1 [open longfile r]
    seek $f1 0 current
    set c [tell $f1]
    close $f1
    set c
} 0
test io-11.2 {Tcl_Seek to offset from start} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 10 start
    set c [tell $f1]
    close $f1
    set c
} 10
test io-11.3 {Tcl_Seek to end of file} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 0 end
    set c [tell $f1]
    close $f1
    set c
} 54
test io-11.4 {Tcl_Seek to offset from end of file} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 -10 end
    set c [tell $f1]
    close $f1
    set c
} 44
test io-11.5 {Tcl_Seek to offset from current position} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 10 current
    seek $f1 10 current
    set c [tell $f1]
    close $f1
    set c
} 20
test io-11.6 {Tcl_Seek to offset from end of file} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 -10 end
    set c [tell $f1]
    set r [read $f1]
    close $f1
    list $c $r
} {44 {rstuvwxyz
}}
test io-11.7 {Tcl_Seek to offset from end of file, then to current position} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 -10 end
    set c1 [tell $f1]
    set r1 [read $f1 5]
    seek $f1 0 current
    set c2 [tell $f1]
    close $f1
    list $c1 $r1 $c2
} {44 rstuv 49}
test io-11.8 {Tcl_Seek on pipes: not supported} {stdio} {
    set f1 [open "|[list $tcltest]" r+]
    set x [list [catch {seek $f1 0 current} msg] $msg]
    close $f1
    regsub {".*":} $x {"":} x
    string tolower $x
} {1 {error during seek on "": invalid argument}}
test io-11.9 {Tcl_Seek, testing buffered input flushing} {
    removeFile test3
    set f [open test3 w]
    fconfigure $f -eofchar {}
    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    close $f
    set f [open test3 RDWR]
    set x [read $f 1]







|

















|

















|

















|

















|

















|

















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


















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




|


|


|





|







|








|







|



|







|



|








|



|







|



|











|


















|











|











|












|












|














|









|




|





|




|











|



|













|





|















|











|












|












|















|






|












|












|












|













|














|















|






|







3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799



















3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
test io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-31.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation lf -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-31.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-31.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-31.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-31.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    set s [format "abc\ndef\n%cqrs\ntuv" 26]
    puts $f $s
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar \x1a
    set l ""
    lappend l [gets $f]
    lappend l [gets $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {abc def 0 {} 1}
test io-31.31 {Tcl_Write crlf on block boundary, Tcl_Gets crlf} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set line "123456789ABCDE"	;# 14 char plus crlf
    puts -nonewline $f x	;# shift crlf across block boundary
    for {set i 0} {$i < 700} {incr i} {
	puts $f $line
    }
    close $f
    set f [open test1 r]
    fconfigure $f -translation crlf 
    set c ""
    while {[gets $f line] >= 0} {
	append c $line\n
    }
    close $f
    string length $c
} [expr 700*15+1]
test io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set line "123456789ABCDE"	;# 14 char plus crlf
    puts -nonewline $f x	;# shift crlf across block boundary
    for {set i 0} {$i < 700} {incr i} {
	puts $f $line
    }
    close $f
    set f [open test1 r]
    fconfigure $f -translation auto
    set c ""
    while {[gets $f line] >= 0} {
	append c $line\n
    }
    close $f
    string length $c
} [expr 700*15+1]





















# Test Tcl_Read and buffering.

test io-32.1 {Tcl_Read, channel not readable} {
    list [catch {read stdout} msg] $msg
} {1 {channel "stdout" wasn't opened for reading}}
test io-32.2 {Tcl_Read, zero byte count} {
    read stdin 0
} ""
test io-32.3 {Tcl_Read, negative byte count} {
    set f [open longfile r]
    set l [list [catch {read $f -1} msg] $msg]
    close $f
    set l
} {1 {bad argument "-1": should be "nonewline"}}
test io-32.4 {Tcl_Read, positive byte count} {
    set f [open longfile r]
    set x [read $f 1024]
    set s [string length $x]
    unset x
    close $f
    set s
} 1024
test io-32.5 {Tcl_Read, multiple buffers} {
    set f [open longfile r]
    fconfigure $f -buffersize 100
    set x [read $f 1024]
    set s [string length $x]
    unset x
    close $f
    set s
} 1024
test io-32.6 {Tcl_Read, very large read} {
    set f1 [open longfile r]
    set z [read $f1 1000000]
    close $f1
    set l [string length $z]
    set x ok
    set z [file size longfile]
    if {$z != $l} {
	set x broken
    }
    set x
} ok
test io-32.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
    set f1 [open longfile r]
    fconfigure $f1 -blocking off
    set z [read $f1 20]
    close $f1
    set l [string length $z]
    set x ok
    if {$l != 20} {
	set x broken
    }
    set x
} ok
test io-32.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
    set f1 [open longfile r]
    fconfigure $f1 -blocking off
    set z [read $f1 1000000]
    close $f1
    set x ok
    set l [string length $z]]
    set z [file size longfile]]
    if {$z != $l} {
	set x broken
    }
  set x
} ok
test io-32.9 {Tcl_Read, read to end of file} {
    set f1 [open longfile r]
    set z [read $f1]
    close $f1
    set l [string length $z]
    set x ok
    set z [file size longfile]
    if {$z != $l} {
	set x broken
    }
    set x
} ok
test io-32.10 {Tcl_Read from a pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {puts [gets stdin]}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
    flush $f1
    set x [read $f1]
    close $f1
    set x
} "hello\n"
test io-32.11 {Tcl_Read from a pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {puts [gets stdin]}
    puts $f1 {puts [gets stdin]}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
    flush $f1
    set x ""
    lappend x [read $f1 6]
    puts $f1 hello
    flush $f1
    lappend x [read $f1]
    close $f1
    set x
} {{hello
} {hello
}}
test io-32.12 {Tcl_Read, -nonewline} {
    removeFile test1
    set f1 [open test1 w]
    puts $f1 hello
    puts $f1 bye
    close $f1
    set f1 [open test1 r]
    set c [read -nonewline $f1]
    close $f1
    set c
} {hello
bye}
test io-32.13 {Tcl_Read, -nonewline} {
    removeFile test1
    set f1 [open test1 w]
    puts $f1 hello
    puts $f1 bye
    close $f1
    set f1 [open test1 r]
    set c [read -nonewline $f1]
    close $f1
    list [string length $c] $c
} {9 {hello
bye}}
test io-32.14 {Tcl_Read, reading in small chunks} {
    removeFile test1
    set f [open test1 w]
    puts $f "Two lines: this one"
    puts $f "and this one"
    close $f
    set f [open test1]
    set x [list [read $f 1] [read $f 2] [read $f]]
    close $f
    set x
} {T wo { lines: this one
and this one
}}
test io-32.15 {Tcl_Read, asking for more input than available} {
    removeFile test1
    set f [open test1 w]
    puts $f "Two lines: this one"
    puts $f "and this one"
    close $f
    set f [open test1]
    set x [read $f 100]
    close $f
    set x
} {Two lines: this one
and this one
}
test io-32.16 {Tcl_Read, read to end of file with -nonewline} {
    removeFile test1
    set f [open test1 w]
    puts $f "Two lines: this one"
    puts $f "and this one"
    close $f
    set f [open test1]
    set x [read -nonewline $f]
    close $f
    set x
} {Two lines: this one
and this one}

# Test Tcl_Gets.

test io-33.1 {Tcl_Gets, reading what was written} {
    removeFile test1
    set f1 [open test1 w]
    set y "first line"
    puts $f1 $y
    close $f1
    set f1 [open test1 r]
    set x [gets $f1]
    set z ok
    if {"$x" != "$y"} {
	set z broken
    }
    close $f1
    set z
} ok
test io-33.2 {Tcl_Gets into variable} {
    set f1 [open longfile r]
    set c [gets $f1 x]
    set l [string length x]
    set z ok
    if {$l != $l} {
	set z broken
    }
    close $f1
    set z
} ok
test io-33.3 {Tcl_Gets from pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {puts [gets stdin]}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
    flush $f1
    set x [gets $f1]
    close $f1
    set z ok
    if {"$x" != "hello"} {
	set z broken
    }
    set z
} ok
test io-33.4 {Tcl_Gets with long line} {
    removeFile test3
    set f [open test3 w]
    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    close $f
    set f [open test3]
    set x [gets $f]
    close $f
    set x
} {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
test io-33.5 {Tcl_Gets with long line} {
    set f [open test3]
    set x [gets $f y]
    close $f
    list $x $y
} {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
test io-33.6 {Tcl_Gets and end of file} {
    removeFile test3
    set f [open test3 w]
    puts -nonewline $f "Test1\nTest2"
    close $f
    set f [open test3]
    set x {}
    set y {}
    lappend x [gets $f y] $y
    set y {}
    lappend x [gets $f y] $y
    set y {}
    lappend x [gets $f y] $y
    close $f
    set x
} {5 Test1 5 Test2 -1 {}}
test io-33.7 {Tcl_Gets and bad variable} {
    set f [open test3 w]
    puts $f "Line 1"
    puts $f "Line 2"
    close $f
    catch {unset x}
    set x 24
    set f [open test3 r]
    set result [list [catch {gets $f x(0)} msg] $msg]
    close $f
    set result
} {1 {can't set "x(0)": variable isn't array}}
test io-33.8 {Tcl_Gets, exercising double buffering} {
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    set x ""
    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
    for {set y 0} {$y < 100} {incr y} {puts $f $x}
    close $f
    set f [open test3 r]
    fconfigure $f -translation lf
    for {set y 0} {$y < 100} {incr y} {gets $f}
    close $f
    set y
} 100
test io-33.9 {Tcl_Gets, exercising double buffering} {
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    set x ""
    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
    for {set y 0} {$y < 200} {incr y} {puts $f $x}
    close $f
    set f [open test3 r]
    fconfigure $f -translation lf
    for {set y 0} {$y < 200} {incr y} {gets $f}
    close $f
    set y
} 200
test io-33.10 {Tcl_Gets, exercising double buffering} {
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    set x ""
    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
    for {set y 0} {$y < 300} {incr y} {puts $f $x}
    close $f
    set f [open test3 r]
    fconfigure $f -translation lf
    for {set y 0} {$y < 300} {incr y} {gets $f}
    close $f
    set y
} 300

# Test Tcl_Seek and Tcl_Tell.

test io-34.1 {Tcl_Seek to current position at start of file} {
    set f1 [open longfile r]
    seek $f1 0 current
    set c [tell $f1]
    close $f1
    set c
} 0
test io-34.2 {Tcl_Seek to offset from start} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 10 start
    set c [tell $f1]
    close $f1
    set c
} 10
test io-34.3 {Tcl_Seek to end of file} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 0 end
    set c [tell $f1]
    close $f1
    set c
} 54
test io-34.4 {Tcl_Seek to offset from end of file} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 -10 end
    set c [tell $f1]
    close $f1
    set c
} 44
test io-34.5 {Tcl_Seek to offset from current position} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 10 current
    seek $f1 10 current
    set c [tell $f1]
    close $f1
    set c
} 20
test io-34.6 {Tcl_Seek to offset from end of file} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 -10 end
    set c [tell $f1]
    set r [read $f1]
    close $f1
    list $c $r
} {44 {rstuvwxyz
}}
test io-34.7 {Tcl_Seek to offset from end of file, then to current position} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 -10 end
    set c1 [tell $f1]
    set r1 [read $f1 5]
    seek $f1 0 current
    set c2 [tell $f1]
    close $f1
    list $c1 $r1 $c2
} {44 rstuv 49}
test io-34.8 {Tcl_Seek on pipes: not supported} {stdio} {
    set f1 [open "|[list $tcltest]" r+]
    set x [list [catch {seek $f1 0 current} msg] $msg]
    close $f1
    regsub {".*":} $x {"":} x
    string tolower $x
} {1 {error during seek on "": invalid argument}}
test io-34.9 {Tcl_Seek, testing buffered input flushing} {
    removeFile test3
    set f [open test3 w]
    fconfigure $f -eofchar {}
    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    close $f
    set f [open test3 RDWR]
    set x [read $f 1]
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
    seek $f 50 end
    lappend x [read $f 1]
    seek $f 1
    lappend x [read $f 1]
    close $f
    set x
} {a d a l Y {} b}
test io-11.10 {Tcl_Seek testing flushing of buffered input} {
    set f [open test3 w]
    fconfigure $f -translation lf
    puts $f xyz\n123
    close $f
    set f [open test3 r+]
    fconfigure $f -translation lf
    set x [gets $f]
    seek $f 0 current
    puts $f 456
    close $f
    list $x [viewFile test3]
} "xyz {xyz
456}"
test io-11.11 {Tcl_Seek testing flushing of buffered output} {
    set f [open test3 w]
    puts $f xyz\n123
    close $f
    set f [open test3 w+]
    puts $f xyzzy
    seek $f 2
    set x [gets $f]
    close $f
    list $x [viewFile test3]
} "zzy xyzzy"
test io-11.12 {Tcl_Seek testing combination of write, seek back and read} {
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    puts $f xyz\n123
    close $f
    set f [open test3 a+]
    fconfigure $f -translation lf -eofchar {}
    puts $f xyzzy
    flush $f
    set x [tell $f]
    seek $f -4 cur
    set y [gets $f]
    close $f
    list $x [viewFile test3] $y
} {14 {xyz
123
xyzzy} zzy}
test io-11.13 {Tcl_Tell at start of file} {
    removeFile test1
    set f1 [open test1 w]
    set p [tell $f1]
    close $f1
    set p
} 0
test io-11.14 {Tcl_Tell after seek to end of file} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 0 end
    set c1 [tell $f1]
    close $f1
    set c1
} 54
test io-11.15 {Tcl_Tell combined with seeking} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 10 start
    set c1 [tell $f1]
    seek $f1 10 current
    set c2 [tell $f1]
    close $f1
    list $c1 $c2
} {10 20}
test io-11.16 {Tcl_tell on pipe: always -1} {stdio} {
    set f1 [open "|[list $tcltest]" r+]
    set c [tell $f1]
    close $f1
    set c
} -1
test io-11.17 {Tcl_Tell on pipe: always -1} {stdio} {
    set f1 [open "|[list $tcltest]" r+]
    puts $f1 {puts hello}
    flush $f1
    set c [tell $f1]
    gets $f1
    close $f1
    set c
} -1
test io-11.18 {Tcl_Tell combined with seeking and reading} {
    removeFile test2
    set f [open test2 w]
    fconfigure $f -translation lf -eofchar {}
    puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
    close $f
    set f [open test2]
    fconfigure $f -translation lf
    set x [tell $f]
    read $f 3
    lappend x [tell $f]
    seek $f 2
    lappend x [tell $f]
    seek $f 10 current
    lappend x [tell $f]
    seek $f 0 end
    lappend x [tell $f]
    close $f
    set x
} {0 3 2 12 30}
test io-11.19 {Tcl_Tell combined with opening in append mode} {
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    puts $f "abcdefghijklmnopqrstuvwxyz"
    puts $f "abcdefghijklmnopqrstuvwxyz"
    close $f
    set f [open test3 a]
    set c [tell $f]
    close $f
    set c
} 54
test io-11.20 {Tcl_Tell combined with writing} {
    set f [open test3 w]
    set l ""
    seek $f 29 start
    lappend l [tell $f]
    puts -nonewline $f a
    seek $f 39 start
    lappend l [tell $f]
    puts -nonewline $f a
    lappend l [tell $f]
    seek $f 407 end
    lappend l [tell $f]
    close $f
    set l
} {29 39 40 447}

# Test Tcl_Eof

test io-12.1 {Tcl_Eof} {
    removeFile test1
    set f [open test1 w]
    puts $f hello
    puts $f hello
    close $f
    set f [open test1]
    set x [eof $f]
    lappend x [eof $f]
    gets $f
    lappend x [eof $f]
    gets $f
    lappend x [eof $f]
    gets $f
    lappend x [eof $f]
    lappend x [eof $f]
    close $f
    set x
} {0 0 0 0 1 1}
test io-12.2 {Tcl_Eof with pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {gets stdin}
    puts $f1 {puts hello}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
    set x [eof $f1]
    flush $f1
    lappend x [eof $f1]
    gets $f1
    lappend x [eof $f1]
    gets $f1
    lappend x [eof $f1]
    close $f1
    set x
} {0 0 0 1}
test io-12.3 {Tcl_Eof with pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {gets stdin}
    puts $f1 {puts hello}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello







|













|










|
















|






|












|














|





|








|



















|










|

















|


















|

















|







4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
    seek $f 50 end
    lappend x [read $f 1]
    seek $f 1
    lappend x [read $f 1]
    close $f
    set x
} {a d a l Y {} b}
test io-34.10 {Tcl_Seek testing flushing of buffered input} {
    set f [open test3 w]
    fconfigure $f -translation lf
    puts $f xyz\n123
    close $f
    set f [open test3 r+]
    fconfigure $f -translation lf
    set x [gets $f]
    seek $f 0 current
    puts $f 456
    close $f
    list $x [viewFile test3]
} "xyz {xyz
456}"
test io-34.11 {Tcl_Seek testing flushing of buffered output} {
    set f [open test3 w]
    puts $f xyz\n123
    close $f
    set f [open test3 w+]
    puts $f xyzzy
    seek $f 2
    set x [gets $f]
    close $f
    list $x [viewFile test3]
} "zzy xyzzy"
test io-34.12 {Tcl_Seek testing combination of write, seek back and read} {
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    puts $f xyz\n123
    close $f
    set f [open test3 a+]
    fconfigure $f -translation lf -eofchar {}
    puts $f xyzzy
    flush $f
    set x [tell $f]
    seek $f -4 cur
    set y [gets $f]
    close $f
    list $x [viewFile test3] $y
} {14 {xyz
123
xyzzy} zzy}
test io-34.13 {Tcl_Tell at start of file} {
    removeFile test1
    set f1 [open test1 w]
    set p [tell $f1]
    close $f1
    set p
} 0
test io-34.14 {Tcl_Tell after seek to end of file} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 0 end
    set c1 [tell $f1]
    close $f1
    set c1
} 54
test io-34.15 {Tcl_Tell combined with seeking} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    puts $f1 "abcdefghijklmnopqrstuvwxyz"
    close $f1
    set f1 [open test1 r]
    seek $f1 10 start
    set c1 [tell $f1]
    seek $f1 10 current
    set c2 [tell $f1]
    close $f1
    list $c1 $c2
} {10 20}
test io-34.16 {Tcl_tell on pipe: always -1} {stdio} {
    set f1 [open "|[list $tcltest]" r+]
    set c [tell $f1]
    close $f1
    set c
} -1
test io-34.17 {Tcl_Tell on pipe: always -1} {stdio} {
    set f1 [open "|[list $tcltest]" r+]
    puts $f1 {puts hello}
    flush $f1
    set c [tell $f1]
    gets $f1
    close $f1
    set c
} -1
test io-34.18 {Tcl_Tell combined with seeking and reading} {
    removeFile test2
    set f [open test2 w]
    fconfigure $f -translation lf -eofchar {}
    puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
    close $f
    set f [open test2]
    fconfigure $f -translation lf
    set x [tell $f]
    read $f 3
    lappend x [tell $f]
    seek $f 2
    lappend x [tell $f]
    seek $f 10 current
    lappend x [tell $f]
    seek $f 0 end
    lappend x [tell $f]
    close $f
    set x
} {0 3 2 12 30}
test io-34.19 {Tcl_Tell combined with opening in append mode} {
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    puts $f "abcdefghijklmnopqrstuvwxyz"
    puts $f "abcdefghijklmnopqrstuvwxyz"
    close $f
    set f [open test3 a]
    set c [tell $f]
    close $f
    set c
} 54
test io-34.20 {Tcl_Tell combined with writing} {
    set f [open test3 w]
    set l ""
    seek $f 29 start
    lappend l [tell $f]
    puts -nonewline $f a
    seek $f 39 start
    lappend l [tell $f]
    puts -nonewline $f a
    lappend l [tell $f]
    seek $f 407 end
    lappend l [tell $f]
    close $f
    set l
} {29 39 40 447}

# Test Tcl_Eof

test io-35.1 {Tcl_Eof} {
    removeFile test1
    set f [open test1 w]
    puts $f hello
    puts $f hello
    close $f
    set f [open test1]
    set x [eof $f]
    lappend x [eof $f]
    gets $f
    lappend x [eof $f]
    gets $f
    lappend x [eof $f]
    gets $f
    lappend x [eof $f]
    lappend x [eof $f]
    close $f
    set x
} {0 0 0 0 1 1}
test io-35.2 {Tcl_Eof with pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {gets stdin}
    puts $f1 {puts hello}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
    set x [eof $f1]
    flush $f1
    lappend x [eof $f1]
    gets $f1
    lappend x [eof $f1]
    gets $f1
    lappend x [eof $f1]
    close $f1
    set x
} {0 0 0 1}
test io-35.3 {Tcl_Eof with pipe} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {gets stdin}
    puts $f1 {puts hello}
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    puts $f1 hello
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
    gets $f1
    lappend x [eof $f1]
    gets $f1
    lappend x [eof $f1]
    close $f1
    set x
} {0 0 0 1 1 1}
test io-12.4 {Tcl_Eof, eof detection on nonblocking file} {nonBlockFiles} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    fconfigure $f -blocking off
    set l ""
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {{} 1}
test io-12.5 {Tcl_Eof, eof detection on nonblocking pipe} {stdio} {
    removeFile pipe
    set f [open pipe w]
    puts $f {
	exit
    }
    close $f
    set f [open "|[list $tcltest pipe]" r]
    set l ""
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {{} 1}
test io-12.6 {Tcl_Eof, eof char, lf write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {9 8 1}
test io-12.7 {Tcl_Eof, eof char, lf write, lf read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation lf -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {9 8 1}
test io-12.8 {Tcl_Eof, eof char, cr write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {9 8 1}
test io-12.9 {Tcl_Eof, eof char, cr write, cr read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {9 8 1}
test io-12.10 {Tcl_Eof, eof char, crlf write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {11 8 1}
test io-12.11 {Tcl_Eof, eof char, crlf write, crlf read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {11 8 1}
test io-12.12 {Tcl_Eof, eof char in middle, lf write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {17 8 1}
test io-12.13 {Tcl_Eof, eof char in middle, lf write, lf read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation lf -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {17 8 1}
test io-12.14 {Tcl_Eof, eof char in middle, cr write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {17 8 1}
test io-12.15 {Tcl_Eof, eof char in middle, cr write, cr read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {17 8 1}
test io-12.16 {Tcl_Eof, eof char in middle, crlf write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {21 8 1}
test io-12.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {21 8 1}

# Test Tcl_InputBlocked

test io-13.1 {Tcl_InputBlocked on nonblocking pipe} {unixOrPc tempNotPc} {
    set f1 [open "|[list $tcltest]" r+]
    puts $f1 {puts hello_from_pipe}
    flush $f1
    gets $f1
    fconfigure $f1 -blocking off -buffering full
    puts $f1 {puts hello}
    set x ""
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    flush $f1
    after 200
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    close $f1
    set x
} {{} 1 hello 0 {} 1}
test io-13.2 {Tcl_InputBlocked on blocking pipe} {unixOrPc tempNotPc} {
    set f1 [open "|[list $tcltest]" r+]
    fconfigure $f1 -buffering line
    puts $f1 {puts hello_from_pipe}
    set x ""
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    puts $f1 {exit}
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    lappend x [eof $f1]
    close $f1
    set x
} {hello_from_pipe 0 {} 0 1}
test io-13.3 {Tcl_InputBlocked vs files, short read} {
    removeFile test1
    set f [open test1 w]
    puts $f abcdefghijklmnop
    close $f
    set f [open test1 r]
    set l ""
    lappend l [fblocked $f]
    lappend l [read $f 3]
    lappend l [fblocked $f]
    lappend l [read -nonewline $f]
    lappend l [fblocked $f]
    lappend l [eof $f]
    close $f
    set l
} {0 abc 0 defghijklmnop 0 1}
test io-13.4 {Tcl_InputBlocked vs files, event driven read} {
    proc in {f} {
        global l x
	lappend l [read $f 3]
	if {[eof $f]} {lappend l eof; close $f; set x done}
    }
    removeFile test1
    set f [open test1 w]
    puts $f abcdefghijklmnop
    close $f
    set f [open test1 r]
    set l ""
    fileevent $f readable [list in $f]
    vwait x
    set l
} {abc def ghi jkl mno {p
} eof}
test io-13.5 {Tcl_InputBlocked vs files, short read, nonblocking} {nonBlockFiles} {
    removeFile test1
    set f [open test1 w]
    puts $f abcdefghijklmnop
    close $f
    set f [open test1 r]
    fconfigure $f -blocking off
    set l ""
    lappend l [fblocked $f]
    lappend l [read $f 3]
    lappend l [fblocked $f]
    lappend l [read -nonewline $f]
    lappend l [fblocked $f]
    lappend l [eof $f]
    close $f
    set l
} {0 abc 0 defghijklmnop 0 1}
test io-13.6 {Tcl_InputBlocked vs files, event driven read} {nonBlockFiles} {
    proc in {f} {
        global l x
	lappend l [read $f 3]
	if {[eof $f]} {lappend l eof; close $f; set x done}
    }
    removeFile test1
    set f [open test1 w]
    puts $f abcdefghijklmnop
    close $f
    set f [open test1 r]
    fconfigure $f -blocking off
    set l ""
    fileevent $f readable [list in $f]
    vwait x
    set l
} {abc def ghi jkl mno {p
} eof}

# Test Tcl_InputBuffered

test io-14.1 {Tcl_InputBuffered} {
    set f [open longfile r]
    fconfigure $f -buffersize 4096
    read $f 3
    set l ""
    lappend l [testchannel inputbuffered $f]
    lappend l [tell $f]
    close $f
    set l
} {4093 3}
test io-14.2 {Tcl_InputBuffered, test input flushing on seek} {
    set f [open longfile r]
    fconfigure $f -buffersize 4096
    read $f 3
    set l ""
    lappend l [testchannel inputbuffered $f]
    lappend l [tell $f]
    seek $f 0 current
    lappend l [testchannel inputbuffered $f]
    lappend l [tell $f]
    close $f
    set l
} {4093 3 0 3}

# Test Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize

test io-15.1 {Tcl_GetChannelBufferSize, default buffer size} {
    set f [open longfile r]
    set s [fconfigure $f -buffersize]
    close $f
    set s
} 4096
test io-15.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} {
    set f [open longfile r]
    set l ""
    lappend l [fconfigure $f -buffersize]
    fconfigure $f -buffersize 10000
    lappend l [fconfigure $f -buffersize]
    fconfigure $f -buffersize 1
    lappend l [fconfigure $f -buffersize]







|











|













|













|













|













|













|













|













|














|














|














|














|














|

















|


















|













|















|
















|
















|




















|









|















|





|







4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
    gets $f1
    lappend x [eof $f1]
    gets $f1
    lappend x [eof $f1]
    close $f1
    set x
} {0 0 0 1 1 1}
test io-35.4 {Tcl_Eof, eof detection on nonblocking file} {nonBlockFiles} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    fconfigure $f -blocking off
    set l ""
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {{} 1}
test io-35.5 {Tcl_Eof, eof detection on nonblocking pipe} {stdio} {
    removeFile pipe
    set f [open pipe w]
    puts $f {
	exit
    }
    close $f
    set f [open "|[list $tcltest pipe]" r]
    set l ""
    lappend l [gets $f]
    lappend l [eof $f]
    close $f
    set l
} {{} 1}
test io-35.6 {Tcl_Eof, eof char, lf write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {9 8 1}
test io-35.7 {Tcl_Eof, eof char, lf write, lf read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation lf -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {9 8 1}
test io-35.8 {Tcl_Eof, eof char, cr write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {9 8 1}
test io-35.9 {Tcl_Eof, eof char, cr write, cr read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {9 8 1}
test io-35.10 {Tcl_Eof, eof char, crlf write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {11 8 1}
test io-35.11 {Tcl_Eof, eof char, crlf write, crlf read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar \x1a
    puts $f abc\ndef
    close $f
    set s [file size test1]
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $s $l $e
} {11 8 1}
test io-35.12 {Tcl_Eof, eof char in middle, lf write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {17 8 1}
test io-35.13 {Tcl_Eof, eof char in middle, lf write, lf read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation lf -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {17 8 1}
test io-35.14 {Tcl_Eof, eof char in middle, cr write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {17 8 1}
test io-35.15 {Tcl_Eof, eof char in middle, cr write, cr read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {17 8 1}
test io-35.16 {Tcl_Eof, eof char in middle, crlf write, auto read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {21 8 1}
test io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf -eofchar {}
    set i [format abc\ndef\n%cqrs\nuvw 26]
    puts $f $i
    close $f
    set c [file size test1]
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar \x1a
    set l [string length [read $f]]
    set e [eof $f]
    close $f
    list $c $l $e
} {21 8 1}

# Test Tcl_InputBlocked

test io-36.1 {Tcl_InputBlocked on nonblocking pipe} {stdio} {
    set f1 [open "|[list $tcltest]" r+]
    puts $f1 {puts hello_from_pipe}
    flush $f1
    gets $f1
    fconfigure $f1 -blocking off -buffering full
    puts $f1 {puts hello}
    set x ""
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    flush $f1
    after 200
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    close $f1
    set x
} {{} 1 hello 0 {} 1}
test io-36.2 {Tcl_InputBlocked on blocking pipe} {stdio} {
    set f1 [open "|[list $tcltest]" r+]
    fconfigure $f1 -buffering line
    puts $f1 {puts hello_from_pipe}
    set x ""
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    puts $f1 {exit}
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    lappend x [eof $f1]
    close $f1
    set x
} {hello_from_pipe 0 {} 0 1}
test io-36.3 {Tcl_InputBlocked vs files, short read} {
    removeFile test1
    set f [open test1 w]
    puts $f abcdefghijklmnop
    close $f
    set f [open test1 r]
    set l ""
    lappend l [fblocked $f]
    lappend l [read $f 3]
    lappend l [fblocked $f]
    lappend l [read -nonewline $f]
    lappend l [fblocked $f]
    lappend l [eof $f]
    close $f
    set l
} {0 abc 0 defghijklmnop 0 1}
test io-36.4 {Tcl_InputBlocked vs files, event driven read} {
    proc in {f} {
        global l x
	lappend l [read $f 3]
	if {[eof $f]} {lappend l eof; close $f; set x done}
    }
    removeFile test1
    set f [open test1 w]
    puts $f abcdefghijklmnop
    close $f
    set f [open test1 r]
    set l ""
    fileevent $f readable [list in $f]
    vwait x
    set l
} {abc def ghi jkl mno {p
} eof}
test io-36.5 {Tcl_InputBlocked vs files, short read, nonblocking} {nonBlockFiles} {
    removeFile test1
    set f [open test1 w]
    puts $f abcdefghijklmnop
    close $f
    set f [open test1 r]
    fconfigure $f -blocking off
    set l ""
    lappend l [fblocked $f]
    lappend l [read $f 3]
    lappend l [fblocked $f]
    lappend l [read -nonewline $f]
    lappend l [fblocked $f]
    lappend l [eof $f]
    close $f
    set l
} {0 abc 0 defghijklmnop 0 1}
test io-36.6 {Tcl_InputBlocked vs files, event driven read} {nonBlockFiles} {
    proc in {f} {
        global l x
	lappend l [read $f 3]
	if {[eof $f]} {lappend l eof; close $f; set x done}
    }
    removeFile test1
    set f [open test1 w]
    puts $f abcdefghijklmnop
    close $f
    set f [open test1 r]
    fconfigure $f -blocking off
    set l ""
    fileevent $f readable [list in $f]
    vwait x
    set l
} {abc def ghi jkl mno {p
} eof}

# Test Tcl_InputBuffered

test io-37.1 {Tcl_InputBuffered} {
    set f [open longfile r]
    fconfigure $f -buffersize 4096
    read $f 3
    set l ""
    lappend l [testchannel inputbuffered $f]
    lappend l [tell $f]
    close $f
    set l
} {4093 3}
test io-37.2 {Tcl_InputBuffered, test input flushing on seek} {
    set f [open longfile r]
    fconfigure $f -buffersize 4096
    read $f 3
    set l ""
    lappend l [testchannel inputbuffered $f]
    lappend l [tell $f]
    seek $f 0 current
    lappend l [testchannel inputbuffered $f]
    lappend l [tell $f]
    close $f
    set l
} {4093 3 0 3}

# Test Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize

test io-38.1 {Tcl_GetChannelBufferSize, default buffer size} {
    set f [open longfile r]
    set s [fconfigure $f -buffersize]
    close $f
    set s
} 4096
test io-38.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} {
    set f [open longfile r]
    set l ""
    lappend l [fconfigure $f -buffersize]
    fconfigure $f -buffersize 10000
    lappend l [fconfigure $f -buffersize]
    fconfigure $f -buffersize 1
    lappend l [fconfigure $f -buffersize]
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391

3392
3393
3394

3395
3396
3397
3398
3399
3400
3401

3402

3403
3404

3405

3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441






















































3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521





3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704











3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
    lappend l [fconfigure $f -buffersize]
    close $f
    set l
} {4096 10000 4096 4096 4096 100000 4096}

# Test Tcl_SetChannelOption, Tcl_GetChannelOption

test io-16.1 {Tcl_GetChannelOption} {
    removeFile test1
    set f1 [open test1 w]
    set x [fconfigure $f1 -blocking]
    close $f1
    set x
} 1
#
# Test 17.2 was removed.
#
test io-16.2 {Tcl_GetChannelOption} {
    removeFile test1
    set f1 [open test1 w]
    set x [fconfigure $f1 -buffering]
    close $f1
    set x
} full
test io-16.3 {Tcl_GetChannelOption} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -buffering line
    set x [fconfigure $f1 -buffering]
    close $f1
    set x
} line
test io-16.4 {Tcl_GetChannelOption, Tcl_SetChannelOption} {
    removeFile test1
    set f1 [open test1 w]
    set l ""
    lappend l [fconfigure $f1 -buffering]
    fconfigure $f1 -buffering line
    lappend l [fconfigure $f1 -buffering]
    fconfigure $f1 -buffering none
    lappend l [fconfigure $f1 -buffering]
    fconfigure $f1 -buffering line
    lappend l [fconfigure $f1 -buffering]
    fconfigure $f1 -buffering full
    lappend l [fconfigure $f1 -buffering]
    close $f1
    set l
} {full line none line full}
test io-16.5 {Tcl_GetChannelOption, invariance} {
    removeFile test1
    set f1 [open test1 w]
    set l ""
    lappend l [fconfigure $f1 -buffering]
    lappend l [list [catch {fconfigure $f1 -buffering green} msg] $msg]
    lappend l [fconfigure $f1 -buffering]
    close $f1
    set l
} {full {1 {bad value for -buffering: must be one of full, line, or none}} full}
test io-16.6 {Tcl_SetChannelOption, multiple options} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -buffering line
    puts $f1 hello
    puts $f1 bye
    set x [file size test1]
    close $f1
    set x
} 10
test io-16.7 {Tcl_SetChannelOption, buffering, translation} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf
    puts $f1 hello
    puts $f1 bye
    set x ""
    fconfigure $f1 -buffering line
    lappend x [file size test1]
    puts $f1 really_bye
    lappend x [file size test1]
    close $f1
    set x
} {0 21}
test io-16.8 {Tcl_SetChannelOption, different buffering options} {
    removeFile test1
    set f1 [open test1 w]
    set l ""
    fconfigure $f1 -translation lf -buffering none -eofchar {}
    puts -nonewline $f1 hello
    lappend l [file size test1]
    puts -nonewline $f1 hello
    lappend l [file size test1]
    fconfigure $f1 -buffering full
    puts -nonewline $f1 hello
    lappend l [file size test1]
    fconfigure $f1 -buffering none
    lappend l [file size test1]
    puts -nonewline $f1 hello
    lappend l [file size test1]
    close $f1
    lappend l [file size test1]
    set l
} {5 10 10 10 20 20}
test io-16.9 {Tcl_SetChannelOption, blocking mode} {nonBlockFiles} {
    removeFile test1
    set f1 [open test1 w]
    close $f1
    set f1 [open test1 r]
    set x ""
    lappend x [fconfigure $f1 -blocking]
    fconfigure $f1 -blocking off
    lappend x [fconfigure $f1 -blocking]
    lappend x [gets $f1]
    lappend x [read $f1 1000]
    lappend x [fblocked $f1]
    lappend x [eof $f1]
    close $f1
    set x
} {1 0 {} {} 0 1}
test io-16.10 {Tcl_SetChannelOption, blocking mode} {unixOrPc tempNotPc} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {gets stdin}

    puts $f1 {after 100}
    puts $f1 {puts hi}
    puts $f1 {gets stdin}

    close $f1
    set x ""
    set f1 [open "|[list $tcltest pipe]" r+]
    fconfigure $f1 -blocking off -buffering line
    lappend x [fconfigure $f1 -blocking]
    lappend x [gets $f1]
    lappend x [fblocked $f1]

    puts $f1 hello

    lappend x [gets $f1]
    lappend x [fblocked $f1]

    puts $f1 bye

    lappend x [gets $f1]
    lappend x [fblocked $f1]
    fconfigure $f1 -blocking on
    lappend x [fconfigure $f1 -blocking]
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    lappend x [eof $f1]
    lappend x [gets $f1]
    lappend x [eof $f1]
    close $f1
    set x
} {0 {} 1 {} 1 {} 1 1 hi 0 0 {} 1}
test io-16.11 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -buffersize -10
    set x [fconfigure $f -buffersize]
    close $f
    set x
} 4096
test io-16.12 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -buffersize 10000000
    set x [fconfigure $f -buffersize]
    close $f
    set x
} 4096
test io-16.13 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -buffersize 40000
    set x [fconfigure $f -buffersize]
    close $f
    set x
} 40000






















































test io-16.14 {Tcl_SetChannelOption, setting read mode independently} \
	{socket} {
    proc accept {s a p} {close $s}
    set s1 [socket -server accept 0]
    set port [lindex [fconfigure $s1 -sockname] 2]
    set s2 [socket localhost $port]
    update
    fconfigure $s2 -translation {auto lf}
    set modes [fconfigure $s2 -translation]
    close $s1
    close $s2
    set modes
} {auto lf}
test io-16.15 {Tcl_SetChannelOption, setting read mode independently} \
	{socket} {
    proc accept {s a p} {close $s}
    set s1 [socket -server accept 0]
    set port [lindex [fconfigure $s1 -sockname] 2]
    set s2 [socket localhost $port]
    update
    fconfigure $s2 -translation {auto crlf}
    set modes [fconfigure $s2 -translation]
    close $s1
    close $s2
    set modes
} {auto crlf}
test io-16.16 {Tcl_SetChannelOption, setting read mode independently} \
	{socket} {
    proc accept {s a p} {close $s}
    set s1 [socket -server accept 0]
    set port [lindex [fconfigure $s1 -sockname] 2]
    set s2 [socket localhost $port]
    update
    fconfigure $s2 -translation {auto cr}
    set modes [fconfigure $s2 -translation]
    close $s1
    close $s2
    set modes
} {auto cr}
test io-16.17 {Tcl_SetChannelOption, setting read mode independently} \
	{socket} {
    proc accept {s a p} {close $s}
    set s1 [socket -server accept 0]
    set port [lindex [fconfigure $s1 -sockname] 2]
    set s2 [socket localhost $port]
    update
    fconfigure $s2 -translation {auto auto}
    set modes [fconfigure $s2 -translation]
    close $s1
    close $s2
    set modes
} {auto crlf}

test io-17.1 {POSIX open access modes: RDWR} {
    removeFile test3
    set f [open test3 w]
    puts $f xyzzy
    close $f
    set f [open test3 RDWR]
    puts -nonewline $f "ab"
    seek $f 0 current
    set x [gets $f]
    close $f
    set f [open test3 r]
    lappend x [gets $f]
    close $f
    set x
} {zzy abzzy}
test io-17.2 {POSIX open access modes: CREAT} {unixOnly} {
    removeFile test3
    set f [open test3 {WRONLY CREAT} 0600]
    file stat test3 stats
    set x [format "0%o" [expr $stats(mode)&0777]]
    puts $f "line 1"
    close $f
    set f [open test3 r]
    lappend x [gets $f]
    close $f
    set x
} {0600 {line 1}}





test io-17.3 {POSIX open access modes: CREAT} {$testConfig(unix) && ([exec umask] == 2)} {
    # This test only works if your umask is 2, like ouster's.
    removeFile test3
    set f [open test3 {WRONLY CREAT}]
    close $f
    file stat test3 stats
    format "0%o" [expr $stats(mode)&0777]
} 0664
test io-17.4 {POSIX open access modes: CREAT} {
    removeFile test3
    set f [open test3 w]
    fconfigure $f -eofchar {}
    puts $f xyzzy
    close $f
    set f [open test3 {WRONLY CREAT}]
    fconfigure $f -eofchar {}
    puts -nonewline $f "ab"
    close $f
    set f [open test3 r]
    set x [gets $f]
    close $f
    set x
} abzzy
test io-17.5 {POSIX open access modes: APPEND} {
    removeFile test3
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    puts $f xyzzy
    close $f
    set f [open test3 {WRONLY APPEND}]
    fconfigure $f -translation lf
    puts $f "new line"
    seek $f 0
    puts $f "abc"
    close $f
    set f [open test3 r]
    fconfigure $f -translation lf
    set x ""
    seek $f 6 current
    lappend x [gets $f]
    lappend x [gets $f]
    close $f
    set x
} {{new line} abc}
test io-17.6 {POSIX open access modes: EXCL} {
    removeFile test3
    set f [open test3 w]
    puts $f xyzzy
    close $f
    set msg [list [catch {open test3 {WRONLY CREAT EXCL}} msg] $msg]
    regsub " already " $msg " " msg
    string tolower $msg
} {1 {couldn't open "test3": file exists}}
test io-17.7 {POSIX open access modes: EXCL} {
    removeFile test3
    set f [open test3 {WRONLY CREAT EXCL}]
    fconfigure $f -eofchar {}
    puts $f "A test line"
    close $f
    viewFile test3
} {A test line}
test io-17.8 {POSIX open access modes: TRUNC} {
    removeFile test3
    set f [open test3 w]
    puts $f xyzzy
    close $f
    set f [open test3 {WRONLY TRUNC}]
    puts $f abc
    close $f
    set f [open test3 r]
    set x [gets $f]
    close $f
    set x
} abc
test io-17.9 {POSIX open access modes: NONBLOCK} {nonPortable macOrUnix} {
    removeFile test3
    set f [open test3 {WRONLY NONBLOCK CREAT}]
    puts $f "NONBLOCK test"
    close $f
    set f [open test3 r]
    set x [gets $f]
    close $f
    set x
} {NONBLOCK test}
test io-17.10 {POSIX open access modes: RDONLY} {
    set f [open test1 w]
    puts $f "two lines: this one"
    puts $f "and this"
    close $f
    set f [open test1 RDONLY]
    set x [list [gets $f] [catch {puts $f Test} msg] $msg]
    close $f
    string compare [string tolower $x] \
	[list {two lines: this one} 1 \
		[format "channel \"%s\" wasn't opened for writing" $f]]
} 0
test io-17.11 {POSIX open access modes: RDONLY} {
    removeFile test3
    string tolower [list [catch {open test3 RDONLY} msg] $msg]
} {1 {couldn't open "test3": no such file or directory}}
test io-17.12 {POSIX open access modes: WRONLY} {
    removeFile test3
    string tolower [list [catch {open test3 WRONLY} msg] $msg]
} {1 {couldn't open "test3": no such file or directory}}
test io-17.13 {POSIX open access modes: WRONLY} {
    makeFile xyzzy test3
    set f [open test3 WRONLY]
    fconfigure $f -eofchar {}
    puts -nonewline $f "ab"
    seek $f 0 current
    set x [list [catch {gets $f} msg] $msg]
    close $f
    lappend x [viewFile test3]
    string compare [string tolower $x] \
	[list 1 "channel \"$f\" wasn't opened for reading" abzzy]
} 0
test io-17.14 {POSIX open access modes: RDWR} {
    removeFile test3
    string tolower [list [catch {open test3 RDWR} msg] $msg]
} {1 {couldn't open "test3": no such file or directory}}
test io-17.15 {POSIX open access modes: RDWR} {
    makeFile xyzzy test3
    set f [open test3 RDWR]
    puts -nonewline $f "ab"
    seek $f 0 current
    set x [gets $f]
    close $f
    lappend x [viewFile test3]
} {zzy abzzy}
if {![file exists ~/_test_] && [file writable ~]} {
    test io-17.16 {tilde substitution in open} {
	set f [open ~/_test_ w]
	puts $f "Some text"
	close $f
	set x [file exists [file join $env(HOME) _test_]]
	removeFile [file join $env(HOME) _test_]
	set x
    } 1
}
test io-17.17 {tilde substitution in open} {
    set home $env(HOME)
    unset env(HOME)
    set x [list [catch {open ~/foo} msg] $msg]
    set env(HOME) $home
    set x
} {1 {couldn't find HOME environment variable to expand path}}

test io-18.1 {Tcl_FileeventCmd: errors} {
    list [catch {fileevent foo} msg] $msg
} {1 {wrong # args: must be "fileevent channelId event ?script?}}
test io-18.2 {Tcl_FileeventCmd: errors} {
    list [catch {fileevent foo bar baz q} msg] $msg
} {1 {wrong # args: must be "fileevent channelId event ?script?}}
test io-18.3 {Tcl_FileeventCmd: errors} {
    list [catch {fileevent gorp readable} msg] $msg
} {1 {can not find channel named "gorp"}}
test io-18.4 {Tcl_FileeventCmd: errors} {
    list [catch {fileevent gorp writable} msg] $msg
} {1 {can not find channel named "gorp"}}
test io-18.5 {Tcl_FileeventCmd: errors} {
    list [catch {fileevent gorp who-knows} msg] $msg
} {1 {bad event name "who-knows": must be readable or writable}}

#
# Test fileevent on a file
#

set f [open foo w+]

test io-19.1 {Tcl_FileeventCmd: creating, deleting, querying} {
    list [fileevent $f readable] [fileevent $f writable]
} {{} {}}
test io-19.2 {Tcl_FileeventCmd: replacing} {
    set result {}
    fileevent $f r "first script"
    lappend result [fileevent $f readable]
    fileevent $f r "new script"
    lappend result [fileevent $f readable]
    fileevent $f r "yet another"
    lappend result [fileevent $f readable]
    fileevent $f r ""
    lappend result [fileevent $f readable]
} {{first script} {new script} {yet another} {}}












#
# Test fileevent on a pipe
#

if {($tcl_platform(platform) != "macintosh") && \
	($testConfig(unixExecs) == 1)} {

catch {set f2 [open "|[list cat -u]" r+]}
catch {set f3 [open "|[list cat -u]" r+]}

test io-20.1 {Tcl_FileeventCmd: creating, deleting, querying} {
    set result {}
    fileevent $f readable "script 1"
    lappend result [fileevent $f readable] [fileevent $f writable]
    fileevent $f writable "write script"
    lappend result [fileevent $f readable] [fileevent $f writable]
    fileevent $f readable {}
    lappend result [fileevent $f readable] [fileevent $f writable]
    fileevent $f writable {}
    lappend result [fileevent $f readable] [fileevent $f writable]
} {{script 1} {} {script 1} {write script} {} {write script} {} {}}
test io-20.2 {Tcl_FileeventCmd: deleting when many present} {
    set result {}
    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
    fileevent $f r "read f"
    fileevent $f2 r "read f2"
    fileevent $f3 r "read f3"
    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
    fileevent $f2 r {}
    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
    fileevent $f3 r {}
    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
    fileevent $f r {}
    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
} {{} {} {} {read f} {read f2} {read f3} {read f} {} {read f3} {read f} {} {} {} {} {}}

test io-21.1 {FileEventProc procedure: normal read event} {
    fileevent $f2 readable {
	set x [gets $f2]; fileevent $f2 readable {}
    }
    puts $f2 text; flush $f2
    set x initial
    vwait x
    set x
} {text}
test io-21.2 {FileEventProc procedure: error in read event} {
    proc bgerror args {
	global x
	set x $args
    }
    fileevent $f2 readable {error bogus}
    puts $f2 text; flush $f2
    set x initial
    vwait x
    rename bgerror {}
    list $x [fileevent $f2 readable]
} {bogus {}}
test io-21.3 {FileEventProc procedure: normal write event} {
    fileevent $f2 writable {
	lappend x "triggered"
	incr count -1
	if {$count <= 0} {
	    fileevent $f2 writable {}
	}
    }
    set x initial
    set count 3
    vwait x
    vwait x
    vwait x
    set x
} {initial triggered triggered triggered}
test io-21.4 {FileEventProc procedure: eror in write event} {
    proc bgerror args {
	global x
	set x $args
    }
    fileevent $f2 writable {error bad-write}
    set x initial
    vwait x
    rename bgerror {}
    list $x [fileevent $f2 writable]
} {bad-write {}}
test io-21.5 {FileEventProc procedure: end of file} {unixOrPc} {
    set f4 [open "|[list $tcltest cat << foo]" r]
    fileevent $f4 readable {
	if {[gets $f4 line] < 0} {
	    lappend x eof
	    fileevent $f4 readable {}
	} else {
	    lappend x $line
	}
    }
    set x initial
    vwait x
    vwait x
    close $f4
    set x
} {initial foo eof}

catch {close $f2}
catch {close $f3}

}
	# Closes if {($platform(platform) != "macintosh") && \
	#		($testConfig(unixExecs) == 1)} clause

close $f
makeFile "foo bar" foo
test io-22.1 {DeleteFileEvent, cleanup on close} {
    set f [open foo r]
    fileevent $f readable {
	lappend x "binding triggered: \"[gets $f]\""
	fileevent $f readable {}
    }
    close $f
    set x initial
    after 100 { set y done }
    vwait y
    set x
} {initial}
test io-22.2 {DeleteFileEvent, cleanup on close} {
    set f [open foo r]
    set f2 [open foo r]
    fileevent $f readable {
	    lappend x "f triggered: \"[gets $f]\""
	    fileevent $f readable {}
	}
    fileevent $f2 readable {
	lappend x "f2 triggered: \"[gets $f2]\""
	fileevent $f2 readable {}
    }
    close $f
    set x initial
    vwait x
    close $f2
    set x
} {initial {f2 triggered: "foo bar"}}
test io-22.3 {DeleteFileEvent, cleanup on close} {
    set f [open foo r]
    set f2 [open foo r]
    set f3 [open foo r]
    fileevent $f readable {f script}
    fileevent $f2 readable {f2 script}
    fileevent $f3 readable {f3 script}
    set x {}







|









|






|







|















|









|









|













|



















|















|


|
>
|
|
|
>







>

>


>

>












|







|







|







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




|







|




|







|




|







|




|








|














|











>
>
>
>
>
|







|














|




















|








|







|












|









|











|



|



|











|



|









|








|







|

|
|

|
|


|


|









|


|










>
>
>
>
>
>
>
>
>
>
>





<
<
<



|










|














|








|











|














|










|



















<
<
<



|











|
















|







4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300



5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396



5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
    lappend l [fconfigure $f -buffersize]
    close $f
    set l
} {4096 10000 4096 4096 4096 100000 4096}

# Test Tcl_SetChannelOption, Tcl_GetChannelOption

test io-39.1 {Tcl_GetChannelOption} {
    removeFile test1
    set f1 [open test1 w]
    set x [fconfigure $f1 -blocking]
    close $f1
    set x
} 1
#
# Test 17.2 was removed.
#
test io-39.2 {Tcl_GetChannelOption} {
    removeFile test1
    set f1 [open test1 w]
    set x [fconfigure $f1 -buffering]
    close $f1
    set x
} full
test io-39.3 {Tcl_GetChannelOption} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -buffering line
    set x [fconfigure $f1 -buffering]
    close $f1
    set x
} line
test io-39.4 {Tcl_GetChannelOption, Tcl_SetChannelOption} {
    removeFile test1
    set f1 [open test1 w]
    set l ""
    lappend l [fconfigure $f1 -buffering]
    fconfigure $f1 -buffering line
    lappend l [fconfigure $f1 -buffering]
    fconfigure $f1 -buffering none
    lappend l [fconfigure $f1 -buffering]
    fconfigure $f1 -buffering line
    lappend l [fconfigure $f1 -buffering]
    fconfigure $f1 -buffering full
    lappend l [fconfigure $f1 -buffering]
    close $f1
    set l
} {full line none line full}
test io-39.5 {Tcl_GetChannelOption, invariance} {
    removeFile test1
    set f1 [open test1 w]
    set l ""
    lappend l [fconfigure $f1 -buffering]
    lappend l [list [catch {fconfigure $f1 -buffering green} msg] $msg]
    lappend l [fconfigure $f1 -buffering]
    close $f1
    set l
} {full {1 {bad value for -buffering: must be one of full, line, or none}} full}
test io-39.6 {Tcl_SetChannelOption, multiple options} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -buffering line
    puts $f1 hello
    puts $f1 bye
    set x [file size test1]
    close $f1
    set x
} 10
test io-39.7 {Tcl_SetChannelOption, buffering, translation} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf
    puts $f1 hello
    puts $f1 bye
    set x ""
    fconfigure $f1 -buffering line
    lappend x [file size test1]
    puts $f1 really_bye
    lappend x [file size test1]
    close $f1
    set x
} {0 21}
test io-39.8 {Tcl_SetChannelOption, different buffering options} {
    removeFile test1
    set f1 [open test1 w]
    set l ""
    fconfigure $f1 -translation lf -buffering none -eofchar {}
    puts -nonewline $f1 hello
    lappend l [file size test1]
    puts -nonewline $f1 hello
    lappend l [file size test1]
    fconfigure $f1 -buffering full
    puts -nonewline $f1 hello
    lappend l [file size test1]
    fconfigure $f1 -buffering none
    lappend l [file size test1]
    puts -nonewline $f1 hello
    lappend l [file size test1]
    close $f1
    lappend l [file size test1]
    set l
} {5 10 10 10 20 20}
test io-39.9 {Tcl_SetChannelOption, blocking mode} {nonBlockFiles} {
    removeFile test1
    set f1 [open test1 w]
    close $f1
    set f1 [open test1 r]
    set x ""
    lappend x [fconfigure $f1 -blocking]
    fconfigure $f1 -blocking off
    lappend x [fconfigure $f1 -blocking]
    lappend x [gets $f1]
    lappend x [read $f1 1000]
    lappend x [fblocked $f1]
    lappend x [eof $f1]
    close $f1
    set x
} {1 0 {} {} 0 1}
test io-39.10 {Tcl_SetChannelOption, blocking mode} {stdio} {
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	gets stdin
	after 100
	puts hi
	gets stdin
    }
    close $f1
    set x ""
    set f1 [open "|[list $tcltest pipe]" r+]
    fconfigure $f1 -blocking off -buffering line
    lappend x [fconfigure $f1 -blocking]
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    fconfigure $f1 -blocking on
    puts $f1 hello
    fconfigure $f1 -blocking off
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    fconfigure $f1 -blocking on
    puts $f1 bye
    fconfigure $f1 -blocking off
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    fconfigure $f1 -blocking on
    lappend x [fconfigure $f1 -blocking]
    lappend x [gets $f1]
    lappend x [fblocked $f1]
    lappend x [eof $f1]
    lappend x [gets $f1]
    lappend x [eof $f1]
    close $f1
    set x
} {0 {} 1 {} 1 {} 1 1 hi 0 0 {} 1}
test io-39.11 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -buffersize -10
    set x [fconfigure $f -buffersize]
    close $f
    set x
} 4096
test io-39.12 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -buffersize 10000000
    set x [fconfigure $f -buffersize]
    close $f
    set x
} 4096
test io-39.13 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -buffersize 40000
    set x [fconfigure $f -buffersize]
    close $f
    set x
} 40000
test io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -encoding {} 
    puts -nonewline $f \xe7\x89\xa6
    close $f
    set f [open test1 r]
    fconfigure $f -encoding utf-8
    set x [read $f]
    close $f
    set x
} \u7266
test io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -encoding binary
    puts -nonewline $f \xe7\x89\xa6
    close $f
    set f [open test1 r]
    fconfigure $f -encoding utf-8
    set x [read $f]
    close $f
    set x
} \u7266
test io-39.16 {Tcl_SetChannelOption: -encoding, errors} {
    removeFile test1
    set f [open test1 w]
    set result [list [catch {fconfigure $f -encoding foobar} msg] $msg]
    close $f
    set result
} {1 {unknown encoding "foobar"}}
test io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} {stdio} {
    set f [open "|[list $tcltest cat]" r+]
    fconfigure $f -encoding binary
    puts -nonewline $f "\xe7"
    flush $f
    fconfigure $f -encoding utf-8 -blocking 0
    set x {}
    fileevent $f readable { lappend x [read $f] }
    vwait x
    after 300 { lappend x timeout }
    vwait x
    fconfigure $f -encoding utf-8
    vwait x
    after 300 { lappend x timeout }
    vwait x
    fconfigure $f -encoding binary
    vwait x
    after 300 { lappend x timeout }
    vwait x
    close $f
    set x
} "{} timeout {} timeout \xe7 timeout"

test io-39.18 {Tcl_SetChannelOption, setting read mode independently} \
	{socket} {
    proc accept {s a p} {close $s}
    set s1 [socket -server accept 0]
    set port [lindex [fconfigure $s1 -sockname] 2]
    set s2 [socket 127.0.0.1 $port]
    update
    fconfigure $s2 -translation {auto lf}
    set modes [fconfigure $s2 -translation]
    close $s1
    close $s2
    set modes
} {auto lf}
test io-39.19 {Tcl_SetChannelOption, setting read mode independently} \
	{socket} {
    proc accept {s a p} {close $s}
    set s1 [socket -server accept 0]
    set port [lindex [fconfigure $s1 -sockname] 2]
    set s2 [socket 127.0.0.1 $port]
    update
    fconfigure $s2 -translation {auto crlf}
    set modes [fconfigure $s2 -translation]
    close $s1
    close $s2
    set modes
} {auto crlf}
test io-39.20 {Tcl_SetChannelOption, setting read mode independently} \
	{socket} {
    proc accept {s a p} {close $s}
    set s1 [socket -server accept 0]
    set port [lindex [fconfigure $s1 -sockname] 2]
    set s2 [socket 127.0.0.1 $port]
    update
    fconfigure $s2 -translation {auto cr}
    set modes [fconfigure $s2 -translation]
    close $s1
    close $s2
    set modes
} {auto cr}
test io-39.21 {Tcl_SetChannelOption, setting read mode independently} \
	{socket} {
    proc accept {s a p} {close $s}
    set s1 [socket -server accept 0]
    set port [lindex [fconfigure $s1 -sockname] 2]
    set s2 [socket 127.0.0.1 $port]
    update
    fconfigure $s2 -translation {auto auto}
    set modes [fconfigure $s2 -translation]
    close $s1
    close $s2
    set modes
} {auto crlf}

test io-40.1 {POSIX open access modes: RDWR} {
    removeFile test3
    set f [open test3 w]
    puts $f xyzzy
    close $f
    set f [open test3 RDWR]
    puts -nonewline $f "ab"
    seek $f 0 current
    set x [gets $f]
    close $f
    set f [open test3 r]
    lappend x [gets $f]
    close $f
    set x
} {zzy abzzy}
test io-40.2 {POSIX open access modes: CREAT} {unixOnly} {
    removeFile test3
    set f [open test3 {WRONLY CREAT} 0600]
    file stat test3 stats
    set x [format "0%o" [expr $stats(mode)&0777]]
    puts $f "line 1"
    close $f
    set f [open test3 r]
    lappend x [gets $f]
    close $f
    set x
} {0600 {line 1}}

# some tests can only be run is umask is 2
# if "umask" cannot be run, the tests will be skipped.
catch {set ::tcltest::testConfig(umask2) [expr {[exec umask] == 2}]}

test io-40.3 {POSIX open access modes: CREAT} {unixOnly umask2} {
    # This test only works if your umask is 2, like ouster's.
    removeFile test3
    set f [open test3 {WRONLY CREAT}]
    close $f
    file stat test3 stats
    format "0%o" [expr $stats(mode)&0777]
} 0664
test io-40.4 {POSIX open access modes: CREAT} {
    removeFile test3
    set f [open test3 w]
    fconfigure $f -eofchar {}
    puts $f xyzzy
    close $f
    set f [open test3 {WRONLY CREAT}]
    fconfigure $f -eofchar {}
    puts -nonewline $f "ab"
    close $f
    set f [open test3 r]
    set x [gets $f]
    close $f
    set x
} abzzy
test io-40.5 {POSIX open access modes: APPEND} {
    removeFile test3
    set f [open test3 w]
    fconfigure $f -translation lf -eofchar {}
    puts $f xyzzy
    close $f
    set f [open test3 {WRONLY APPEND}]
    fconfigure $f -translation lf
    puts $f "new line"
    seek $f 0
    puts $f "abc"
    close $f
    set f [open test3 r]
    fconfigure $f -translation lf
    set x ""
    seek $f 6 current
    lappend x [gets $f]
    lappend x [gets $f]
    close $f
    set x
} {{new line} abc}
test io-40.6 {POSIX open access modes: EXCL} {
    removeFile test3
    set f [open test3 w]
    puts $f xyzzy
    close $f
    set msg [list [catch {open test3 {WRONLY CREAT EXCL}} msg] $msg]
    regsub " already " $msg " " msg
    string tolower $msg
} {1 {couldn't open "test3": file exists}}
test io-40.7 {POSIX open access modes: EXCL} {
    removeFile test3
    set f [open test3 {WRONLY CREAT EXCL}]
    fconfigure $f -eofchar {}
    puts $f "A test line"
    close $f
    viewFile test3
} {A test line}
test io-40.8 {POSIX open access modes: TRUNC} {
    removeFile test3
    set f [open test3 w]
    puts $f xyzzy
    close $f
    set f [open test3 {WRONLY TRUNC}]
    puts $f abc
    close $f
    set f [open test3 r]
    set x [gets $f]
    close $f
    set x
} abc
test io-40.9 {POSIX open access modes: NONBLOCK} {nonPortable macOrUnix} {
    removeFile test3
    set f [open test3 {WRONLY NONBLOCK CREAT}]
    puts $f "NONBLOCK test"
    close $f
    set f [open test3 r]
    set x [gets $f]
    close $f
    set x
} {NONBLOCK test}
test io-40.10 {POSIX open access modes: RDONLY} {
    set f [open test1 w]
    puts $f "two lines: this one"
    puts $f "and this"
    close $f
    set f [open test1 RDONLY]
    set x [list [gets $f] [catch {puts $f Test} msg] $msg]
    close $f
    string compare [string tolower $x] \
	[list {two lines: this one} 1 \
		[format "channel \"%s\" wasn't opened for writing" $f]]
} 0
test io-40.11 {POSIX open access modes: RDONLY} {
    removeFile test3
    string tolower [list [catch {open test3 RDONLY} msg] $msg]
} {1 {couldn't open "test3": no such file or directory}}
test io-40.12 {POSIX open access modes: WRONLY} {
    removeFile test3
    string tolower [list [catch {open test3 WRONLY} msg] $msg]
} {1 {couldn't open "test3": no such file or directory}}
test io-40.13 {POSIX open access modes: WRONLY} {
    makeFile xyzzy test3
    set f [open test3 WRONLY]
    fconfigure $f -eofchar {}
    puts -nonewline $f "ab"
    seek $f 0 current
    set x [list [catch {gets $f} msg] $msg]
    close $f
    lappend x [viewFile test3]
    string compare [string tolower $x] \
	[list 1 "channel \"$f\" wasn't opened for reading" abzzy]
} 0
test io-40.14 {POSIX open access modes: RDWR} {
    removeFile test3
    string tolower [list [catch {open test3 RDWR} msg] $msg]
} {1 {couldn't open "test3": no such file or directory}}
test io-40.15 {POSIX open access modes: RDWR} {
    makeFile xyzzy test3
    set f [open test3 RDWR]
    puts -nonewline $f "ab"
    seek $f 0 current
    set x [gets $f]
    close $f
    lappend x [viewFile test3]
} {zzy abzzy}
if {![file exists ~/_test_] && [file writable ~]} {
    test io-40.16 {tilde substitution in open} {
	set f [open ~/_test_ w]
	puts $f "Some text"
	close $f
	set x [file exists [file join $env(HOME) _test_]]
	removeFile [file join $env(HOME) _test_]
	set x
    } 1
}
test io-40.17 {tilde substitution in open} {
    set home $env(HOME)
    unset env(HOME)
    set x [list [catch {open ~/foo} msg] $msg]
    set env(HOME) $home
    set x
} {1 {couldn't find HOME environment variable to expand path}}

test io-41.1 {Tcl_FileeventCmd: errors} {
    list [catch {fileevent foo} msg] $msg
} {1 {wrong # args: should be "fileevent channelId event ?script?"}}
test io-41.2 {Tcl_FileeventCmd: errors} {
    list [catch {fileevent foo bar baz q} msg] $msg
} {1 {wrong # args: should be "fileevent channelId event ?script?"}}
test io-41.3 {Tcl_FileeventCmd: errors} {
    list [catch {fileevent gorp readable} msg] $msg
} {1 {can not find channel named "gorp"}}
test io-41.4 {Tcl_FileeventCmd: errors} {
    list [catch {fileevent gorp writable} msg] $msg
} {1 {can not find channel named "gorp"}}
test io-41.5 {Tcl_FileeventCmd: errors} {
    list [catch {fileevent gorp who-knows} msg] $msg
} {1 {bad event name "who-knows": must be readable or writable}}

#
# Test fileevent on a file
#

set f [open foo w+]

test io-42.1 {Tcl_FileeventCmd: creating, deleting, querying} {
    list [fileevent $f readable] [fileevent $f writable]
} {{} {}}
test io-42.2 {Tcl_FileeventCmd: replacing} {
    set result {}
    fileevent $f r "first script"
    lappend result [fileevent $f readable]
    fileevent $f r "new script"
    lappend result [fileevent $f readable]
    fileevent $f r "yet another"
    lappend result [fileevent $f readable]
    fileevent $f r ""
    lappend result [fileevent $f readable]
} {{first script} {new script} {yet another} {}}
test io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {
    set result {}
    fileevent $f r "first scr\0ipt"
    lappend result [string length [fileevent $f readable]]
    fileevent $f r "new scr\0ipt"
    lappend result [string length [fileevent $f readable]]
    fileevent $f r "yet ano\0ther"
    lappend result [string length [fileevent $f readable]]
    fileevent $f r ""
    lappend result [fileevent $f readable]
} {13 11 12 {}}

#
# Test fileevent on a pipe
#




catch {set f2 [open "|[list cat -u]" r+]}
catch {set f3 [open "|[list cat -u]" r+]}

test io-43.1 {Tcl_FileeventCmd: creating, deleting, querying} {stdio unixExecs} {
    set result {}
    fileevent $f readable "script 1"
    lappend result [fileevent $f readable] [fileevent $f writable]
    fileevent $f writable "write script"
    lappend result [fileevent $f readable] [fileevent $f writable]
    fileevent $f readable {}
    lappend result [fileevent $f readable] [fileevent $f writable]
    fileevent $f writable {}
    lappend result [fileevent $f readable] [fileevent $f writable]
} {{script 1} {} {script 1} {write script} {} {write script} {} {}}
test io-43.2 {Tcl_FileeventCmd: deleting when many present} {stdio unixExecs} {
    set result {}
    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
    fileevent $f r "read f"
    fileevent $f2 r "read f2"
    fileevent $f3 r "read f3"
    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
    fileevent $f2 r {}
    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
    fileevent $f3 r {}
    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
    fileevent $f r {}
    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
} {{} {} {} {read f} {read f2} {read f3} {read f} {} {read f3} {read f} {} {} {} {} {}}

test io-44.1 {FileEventProc procedure: normal read event} {stdio unixExecs} {
    fileevent $f2 readable {
	set x [gets $f2]; fileevent $f2 readable {}
    }
    puts $f2 text; flush $f2
    set x initial
    vwait x
    set x
} {text}
test io-44.2 {FileEventProc procedure: error in read event} {stdio unixExecs} {
    proc bgerror args {
	global x
	set x $args
    }
    fileevent $f2 readable {error bogus}
    puts $f2 text; flush $f2
    set x initial
    vwait x
    rename bgerror {}
    list $x [fileevent $f2 readable]
} {bogus {}}
test io-44.3 {FileEventProc procedure: normal write event} {stdio unixExecs} {
    fileevent $f2 writable {
	lappend x "triggered"
	incr count -1
	if {$count <= 0} {
	    fileevent $f2 writable {}
	}
    }
    set x initial
    set count 3
    vwait x
    vwait x
    vwait x
    set x
} {initial triggered triggered triggered}
test io-44.4 {FileEventProc procedure: eror in write event} {stdio unixExecs} {
    proc bgerror args {
	global x
	set x $args
    }
    fileevent $f2 writable {error bad-write}
    set x initial
    vwait x
    rename bgerror {}
    list $x [fileevent $f2 writable]
} {bad-write {}}
test io-44.5 {FileEventProc procedure: end of file} {stdio unixExecs} {
    set f4 [open "|[list $tcltest cat << foo]" r]
    fileevent $f4 readable {
	if {[gets $f4 line] < 0} {
	    lappend x eof
	    fileevent $f4 readable {}
	} else {
	    lappend x $line
	}
    }
    set x initial
    vwait x
    vwait x
    close $f4
    set x
} {initial foo eof}

catch {close $f2}
catch {close $f3}





close $f
makeFile "foo bar" foo
test io-45.1 {DeleteFileEvent, cleanup on close} {
    set f [open foo r]
    fileevent $f readable {
	lappend x "binding triggered: \"[gets $f]\""
	fileevent $f readable {}
    }
    close $f
    set x initial
    after 100 { set y done }
    vwait y
    set x
} {initial}
test io-45.2 {DeleteFileEvent, cleanup on close} {
    set f [open foo r]
    set f2 [open foo r]
    fileevent $f readable {
	    lappend x "f triggered: \"[gets $f]\""
	    fileevent $f readable {}
	}
    fileevent $f2 readable {
	lappend x "f2 triggered: \"[gets $f2]\""
	fileevent $f2 readable {}
    }
    close $f
    set x initial
    vwait x
    close $f2
    set x
} {initial {f2 triggered: "foo bar"}}
test io-45.3 {DeleteFileEvent, cleanup on close} {
    set f [open foo r]
    set f2 [open foo r]
    set f3 [open foo r]
    fileevent $f readable {f script}
    fileevent $f2 readable {f2 script}
    fileevent $f3 readable {f3 script}
    set x {}
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
	    [catch {fileevent $f3 readable}]
} {0 {f script} 1 0 {f3 script} 0 {f script} 1 1 1 1 1}

# Execute these tests only if the "testfevent" command is present.

if {[info commands testfevent] == "testfevent"} {

test io-23.1 {Tcl event loop vs multiple interpreters} {
    testfevent create
    testfevent cmd {
        set f [open foo r]
        set x "no event"
        fileevent $f readable {
            set x "f triggered: [gets $f]"
            fileevent $f readable {}
        }
    } 
    after 1	;# We must delay because Windows takes a little time to notice
    update
    testfevent cmd {close $f}
    list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
} {{f triggered: foo bar} after}
test io-23.2 {Tcl event loop vs multiple interpreters} {
    testfevent create
    testfevent cmd {
        set x 0
        after 100 {set x triggered}
        vwait x
        set x
    }
} {triggered}
test io-23.3 {Tcl event loop vs multiple interpreters} {
    testfevent create
    testfevent cmd {
        set x 0
        after 10 {lappend x timer}
        after 30
        set result $x
        update idletasks
        lappend result $x
        update
        lappend result $x
    }
} {0 0 {0 timer}}

test io-24.1 {fileevent vs multiple interpreters} {
    set f [open foo r]
    set f2 [open foo r]
    set f3 [open foo r]
    fileevent $f readable {script 1}
    testfevent create
    testfevent share $f2
    testfevent cmd "fileevent $f2 readable {script 2}"
    fileevent $f3 readable {sript 3}
    set x {}
    lappend x [fileevent $f2 readable]
    testfevent delete
    lappend x [fileevent $f readable] [fileevent $f2 readable] \
        [fileevent $f3 readable]
    close $f
    close $f2
    close $f3
    set x
} {{} {script 1} {} {sript 3}}
test io-24.2 {deleting fileevent on interpreter delete} {
    set f [open foo r]
    set f2 [open foo r]
    set f3 [open foo r]
    set f4 [open foo r]
    fileevent $f readable {script 1}
    testfevent create
    testfevent share $f2
    testfevent share $f3
    testfevent cmd "fileevent $f2 readable {script 2}
        fileevent $f3 readable {script 3}"
    fileevent $f4 readable {script 4}
    testfevent delete
    set x [list [fileevent $f readable] [fileevent $f2 readable] \
                [fileevent $f3 readable] [fileevent $f4 readable]]
    close $f
    close $f2
    close $f3
    close $f4
    set x
} {{script 1} {} {} {script 4}}
test io-24.3 {deleting fileevent on interpreter delete} {
    set f [open foo r]
    set f2 [open foo r]
    set f3 [open foo r]
    set f4 [open foo r]
    testfevent create
    testfevent share $f3
    testfevent share $f4
    fileevent $f readable {script 1}
    fileevent $f2 readable {script 2}
    testfevent cmd "fileevent $f3 readable {script 3}
      fileevent $f4 readable {script 4}"
    testfevent delete
    set x [list [fileevent $f readable] [fileevent $f2 readable] \
                [fileevent $f3 readable] [fileevent $f4 readable]]
    close $f
    close $f2
    close $f3
    close $f4
    set x
} {{script 1} {script 2} {} {}}
test io-24.4 {file events on shared files and multiple interpreters} {
    set f [open foo r]
    set f2 [open foo r]
    testfevent create
    testfevent share $f
    testfevent cmd "fileevent $f readable {script 1}"
    fileevent $f readable {script 2}
    fileevent $f2 readable {script 3}
    set x [list [fileevent $f2 readable] \
                [testfevent cmd "fileevent $f readable"] \
                [fileevent $f readable]]
    testfevent delete
    close $f
    close $f2
    set x
} {{script 3} {script 1} {script 2}}
test io-24.5 {file events on shared files, deleting file events} {
    set f [open foo r]
    testfevent create
    testfevent share $f
    testfevent cmd "fileevent $f readable {script 1}"
    fileevent $f readable {script 2}
    testfevent cmd "fileevent $f readable {}"
    set x [list [testfevent cmd "fileevent $f readable"] \
                [fileevent $f readable]]
    testfevent delete
    close $f
    set x
} {{} {script 2}}
test io-24.6 {file events on shared files, deleting file events} {
    set f [open foo r]
    testfevent create
    testfevent share $f
    testfevent cmd "fileevent $f readable {script 1}"
    fileevent $f readable {script 2}
    fileevent $f readable {}
    set x [list [testfevent cmd "fileevent $f readable"] \
                [fileevent $f readable]]
    testfevent delete
    close $f
    set x
} {{script 1} {}}

}

# The above curly closes the test for presence of the "testfevent" command.

test io-25.1 {testing readability conditions} {
    set f [open bar w]
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    close $f







|














|








|













|


















|




















|




















|















|












|

















|







5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
	    [catch {fileevent $f3 readable}]
} {0 {f script} 1 0 {f3 script} 0 {f script} 1 1 1 1 1}

# Execute these tests only if the "testfevent" command is present.

if {[info commands testfevent] == "testfevent"} {

test io-46.1 {Tcl event loop vs multiple interpreters} {
    testfevent create
    testfevent cmd {
        set f [open foo r]
        set x "no event"
        fileevent $f readable {
            set x "f triggered: [gets $f]"
            fileevent $f readable {}
        }
    } 
    after 1	;# We must delay because Windows takes a little time to notice
    update
    testfevent cmd {close $f}
    list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
} {{f triggered: foo bar} after}
test io-46.2 {Tcl event loop vs multiple interpreters} {
    testfevent create
    testfevent cmd {
        set x 0
        after 100 {set x triggered}
        vwait x
        set x
    }
} {triggered}
test io-46.3 {Tcl event loop vs multiple interpreters} {
    testfevent create
    testfevent cmd {
        set x 0
        after 10 {lappend x timer}
        after 30
        set result $x
        update idletasks
        lappend result $x
        update
        lappend result $x
    }
} {0 0 {0 timer}}

test io-47.1 {fileevent vs multiple interpreters} {
    set f [open foo r]
    set f2 [open foo r]
    set f3 [open foo r]
    fileevent $f readable {script 1}
    testfevent create
    testfevent share $f2
    testfevent cmd "fileevent $f2 readable {script 2}"
    fileevent $f3 readable {sript 3}
    set x {}
    lappend x [fileevent $f2 readable]
    testfevent delete
    lappend x [fileevent $f readable] [fileevent $f2 readable] \
        [fileevent $f3 readable]
    close $f
    close $f2
    close $f3
    set x
} {{} {script 1} {} {sript 3}}
test io-47.2 {deleting fileevent on interpreter delete} {
    set f [open foo r]
    set f2 [open foo r]
    set f3 [open foo r]
    set f4 [open foo r]
    fileevent $f readable {script 1}
    testfevent create
    testfevent share $f2
    testfevent share $f3
    testfevent cmd "fileevent $f2 readable {script 2}
        fileevent $f3 readable {script 3}"
    fileevent $f4 readable {script 4}
    testfevent delete
    set x [list [fileevent $f readable] [fileevent $f2 readable] \
                [fileevent $f3 readable] [fileevent $f4 readable]]
    close $f
    close $f2
    close $f3
    close $f4
    set x
} {{script 1} {} {} {script 4}}
test io-47.3 {deleting fileevent on interpreter delete} {
    set f [open foo r]
    set f2 [open foo r]
    set f3 [open foo r]
    set f4 [open foo r]
    testfevent create
    testfevent share $f3
    testfevent share $f4
    fileevent $f readable {script 1}
    fileevent $f2 readable {script 2}
    testfevent cmd "fileevent $f3 readable {script 3}
      fileevent $f4 readable {script 4}"
    testfevent delete
    set x [list [fileevent $f readable] [fileevent $f2 readable] \
                [fileevent $f3 readable] [fileevent $f4 readable]]
    close $f
    close $f2
    close $f3
    close $f4
    set x
} {{script 1} {script 2} {} {}}
test io-47.4 {file events on shared files and multiple interpreters} {
    set f [open foo r]
    set f2 [open foo r]
    testfevent create
    testfevent share $f
    testfevent cmd "fileevent $f readable {script 1}"
    fileevent $f readable {script 2}
    fileevent $f2 readable {script 3}
    set x [list [fileevent $f2 readable] \
                [testfevent cmd "fileevent $f readable"] \
                [fileevent $f readable]]
    testfevent delete
    close $f
    close $f2
    set x
} {{script 3} {script 1} {script 2}}
test io-47.5 {file events on shared files, deleting file events} {
    set f [open foo r]
    testfevent create
    testfevent share $f
    testfevent cmd "fileevent $f readable {script 1}"
    fileevent $f readable {script 2}
    testfevent cmd "fileevent $f readable {}"
    set x [list [testfevent cmd "fileevent $f readable"] \
                [fileevent $f readable]]
    testfevent delete
    close $f
    set x
} {{} {script 2}}
test io-47.6 {file events on shared files, deleting file events} {
    set f [open foo r]
    testfevent create
    testfevent share $f
    testfevent cmd "fileevent $f readable {script 1}"
    fileevent $f readable {script 2}
    fileevent $f readable {}
    set x [list [testfevent cmd "fileevent $f readable"] \
                [fileevent $f readable]]
    testfevent delete
    close $f
    set x
} {{script 1} {}}

}

# The above curly closes the test for presence of the "testfevent" command.

test io-48.1 {testing readability conditions} {
    set f [open bar w]
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    close $f
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
	}
    }
    set l ""
    set x not_done
    vwait x
    list $x $l
} {done {called called called called called called called}}
test io-25.2 {testing readability conditions} {nonBlockFiles} {
    set f [open bar w]
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    close $f







|







5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
	}
    }
    set l ""
    set x not_done
    vwait x
    list $x $l
} {done {called called called called called called called}}
test io-48.2 {testing readability conditions} {nonBlockFiles} {
    set f [open bar w]
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    close $f
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
	}
    }
    set l ""
    set x not_done
    vwait x
    list $x $l
} {done {called called called called called called called}}
test io-25.3 {testing readability conditions} {unixOnly nonBlockFiles} {
    set f [open bar w]
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    close $f







|







5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
	}
    }
    set l ""
    set x not_done
    vwait x
    list $x $l
} {done {called called called called called called called}}
test io-48.3 {testing readability conditions} {unixOnly nonBlockFiles} {
    set f [open bar w]
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    puts $f abcdefg
    close $f
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
    puts $f {set f [open bar r]}
    puts $f {copy_slowly $f}
    puts $f {exit}
    vwait x
    close $f
    list $x $l
} {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
test io-25.4 {lf write, testing readability, ^Z termination, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
    puts $f {set f [open bar r]}
    puts $f {copy_slowly $f}
    puts $f {exit}
    vwait x
    close $f
    list $x $l
} {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
test io-48.4 {lf write, testing readability, ^Z termination, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
    set l ""
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.5 {lf write, testing readability, ^Z in middle, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
    set l ""
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.6 {cr write, testing readability, ^Z termination, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.6 {cr write, testing readability, ^Z termination, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
    set l ""
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.7 {cr write, testing readability, ^Z in middle, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
    set l ""
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.8 {crlf write, testing readability, ^Z termination, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.8 {crlf write, testing readability, ^Z termination, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
    set l ""
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.9 {crlf write, testing readability, ^Z in middle, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
    set l ""
    set f [open test1 r]
    fconfigure $f -translation auto -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.10 {lf write, testing readability, ^Z in middle, lf read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation auto
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation lf
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.11 {lf write, testing readability, ^Z termination, lf read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation lf
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.11 {lf write, testing readability, ^Z termination, lf read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
    set l ""
    set f [open test1 r]
    fconfigure $f -translation lf -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.12 {cr write, testing readability, ^Z in middle, cr read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
    set l ""
    set f [open test1 r]
    fconfigure $f -translation lf -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation cr
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.13 {cr write, testing readability, ^Z termination, cr read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation cr
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.13 {cr write, testing readability, ^Z termination, cr read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation cr
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
    set l ""
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.14 {crlf write, testing readability, ^Z in middle, crlf read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
    set l ""
    set f [open test1 r]
    fconfigure $f -translation cr -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation crlf
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-25.15 {crlf write, testing readability, ^Z termi, crlf read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {







|







5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
    set l ""
    set f [open test1 r]
    fconfigure $f -eofchar \x1a -translation crlf
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}
test io-48.15 {crlf write, testing readability, ^Z termi, crlf read mode} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation crlf
    set c [format "abc\ndef\n%c" 26]
    puts -nonewline $f $c
    close $f
    proc consume {f} {
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}

test io-26.1 {testing crlf reading, leftover cr disgorgment} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\rb\rc\r\n"
    close $f
    set f [open test1 r]
    set l ""







|







5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
    set f [open test1 r]
    fconfigure $f -translation crlf -eofchar \x1a
    fileevent $f readable [list consume $f]
    vwait x
    list $c $l
} {3 {abc def {}}}

test io-49.1 {testing crlf reading, leftover cr disgorgment} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\rb\rc\r\n"
    close $f
    set f [open test1 r]
    set l ""
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
    lappend l [eof $f]
    lappend l [read $f 1]
    lappend l [eof $f]
    close $f
    set l
} "7 a 1 [list \r] 2 b 3 [list \r] 4 c 5 {
} 7 0 {} 1"
test io-26.2 {testing crlf reading, leftover cr disgorgment} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\rb\rc\r\n"
    close $f
    set f [open test1 r]
    set l ""







|







6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
    lappend l [eof $f]
    lappend l [read $f 1]
    lappend l [eof $f]
    close $f
    set l
} "7 a 1 [list \r] 2 b 3 [list \r] 4 c 5 {
} 7 0 {} 1"
test io-49.2 {testing crlf reading, leftover cr disgorgment} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\rb\rc\r\n"
    close $f
    set f [open test1 r]
    set l ""
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
    lappend l [eof $f]
    lappend l [read $f 2]
    lappend l [tell $f]
    lappend l [eof $f]
    close $f
    set l
} "7 [list a\r] 2 [list b\r] 4 [list c\n] 7 0 {} 7 1"
test io-26.3 {testing crlf reading, leftover cr disgorgment} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\rb\rc\r\n"
    close $f
    set f [open test1 r]
    set l ""
    lappend l [file size test1]
    fconfigure $f -translation crlf
    lappend l [read $f 3]
    lappend l [tell $f]
    lappend l [read $f 3]
    lappend l [tell $f]
    lappend l [eof $f]
    lappend l [read $f 3]
    lappend l [tell $f]
    lappend l [eof $f]
    close $f
    set l
} "7 [list a\rb] 3 [list \rc\n] 7 0 {} 7 1"
test io-26.4 {testing crlf reading, leftover cr disgorgment} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\rb\rc\r\n"
    close $f
    set f [open test1 r]
    set l ""
    lappend l [file size test1]
    fconfigure $f -translation crlf
    lappend l [read $f 3]
    lappend l [tell $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [eof $f]
    close $f
    set l
} "7 [list a\rb] 3 [list \rc] 7 0 {} 7 1"
test io-26.5 {testing crlf reading, leftover cr disgorgment} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\rb\rc\r\n"
    close $f
    set f [open test1 r]
    set l ""
    lappend l [file size test1]
    fconfigure $f -translation crlf
    lappend l [set x [gets $f]]
    lappend l [tell $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [eof $f]
    close $f
    set l
} [list 7 a\rb\rc 7 {} 7 1]
    
test io-27.1 {testing handler deletion} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list delhandler $f]
    proc delhandler {f} {
	global z
	set z called
	testchannelevent $f delete 0
    }
    set z not_called
    update
    close $f
    set z
} called
test io-27.2 {testing handler deletion with multiple handlers} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list delhandler $f 1]
    testchannelevent $f add readable [list delhandler $f 0]
    proc delhandler {f i} {
	global z
	lappend z "called delhandler $f $i"
	testchannelevent $f delete 0
    }
    set z ""
    update
    close $f
    string compare [string tolower $z] \
	[list [list called delhandler $f 0] [list called delhandler $f 1]]
} 0
test io-27.3 {testing handler deletion with multiple handlers} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list notcalled $f 1]
    testchannelevent $f add readable [list delhandler $f 0]
    set z ""







|




















|




















|


















|















|

















|







6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
    lappend l [eof $f]
    lappend l [read $f 2]
    lappend l [tell $f]
    lappend l [eof $f]
    close $f
    set l
} "7 [list a\r] 2 [list b\r] 4 [list c\n] 7 0 {} 7 1"
test io-49.3 {testing crlf reading, leftover cr disgorgment} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\rb\rc\r\n"
    close $f
    set f [open test1 r]
    set l ""
    lappend l [file size test1]
    fconfigure $f -translation crlf
    lappend l [read $f 3]
    lappend l [tell $f]
    lappend l [read $f 3]
    lappend l [tell $f]
    lappend l [eof $f]
    lappend l [read $f 3]
    lappend l [tell $f]
    lappend l [eof $f]
    close $f
    set l
} "7 [list a\rb] 3 [list \rc\n] 7 0 {} 7 1"
test io-49.4 {testing crlf reading, leftover cr disgorgment} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\rb\rc\r\n"
    close $f
    set f [open test1 r]
    set l ""
    lappend l [file size test1]
    fconfigure $f -translation crlf
    lappend l [read $f 3]
    lappend l [tell $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [eof $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [eof $f]
    close $f
    set l
} "7 [list a\rb] 3 [list \rc] 7 0 {} 7 1"
test io-49.5 {testing crlf reading, leftover cr disgorgment} {
    removeFile test1
    set f [open test1 w]
    fconfigure $f -translation lf
    puts -nonewline $f "a\rb\rc\r\n"
    close $f
    set f [open test1 r]
    set l ""
    lappend l [file size test1]
    fconfigure $f -translation crlf
    lappend l [set x [gets $f]]
    lappend l [tell $f]
    lappend l [gets $f]
    lappend l [tell $f]
    lappend l [eof $f]
    close $f
    set l
} [list 7 a\rb\rc 7 {} 7 1]
    
test io-50.1 {testing handler deletion} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list delhandler $f]
    proc delhandler {f} {
	global z
	set z called
	testchannelevent $f delete 0
    }
    set z not_called
    update
    close $f
    set z
} called
test io-50.2 {testing handler deletion with multiple handlers} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list delhandler $f 1]
    testchannelevent $f add readable [list delhandler $f 0]
    proc delhandler {f i} {
	global z
	lappend z "called delhandler $f $i"
	testchannelevent $f delete 0
    }
    set z ""
    update
    close $f
    string compare [string tolower $z] \
	[list [list called delhandler $f 0] [list called delhandler $f 1]]
} 0
test io-50.3 {testing handler deletion with multiple handlers} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list notcalled $f 1]
    testchannelevent $f add readable [list delhandler $f 0]
    set z ""
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
    set z ""
    update
    close $f
    string compare [string tolower $z] \
	[list [list delhandler $f 0 called] \
	      [list delhandler $f 0 deleted myself]]
} 0
test io-27.4 {testing handler deletion vs reentrant calls} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list delrecursive $f]
    proc delrecursive {f} {
	global z u







|







6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
    set z ""
    update
    close $f
    string compare [string tolower $z] \
	[list [list delhandler $f 0 called] \
	      [list delhandler $f 0 deleted myself]]
} 0
test io-50.4 {testing handler deletion vs reentrant calls} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list delrecursive $f]
    proc delrecursive {f} {
	global z u
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
    set u toplevel
    set z ""
    update
    close $f
    string compare [string tolower $z] \
	{{delrecursive calling recursive} {delrecursive deleting recursive}}
} 0
test io-27.5 {testing handler deletion vs reentrant calls} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list notcalled $f]
    testchannelevent $f add readable [list del $f]
    proc notcalled {f} {







|







6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
    set u toplevel
    set z ""
    update
    close $f
    string compare [string tolower $z] \
	{{delrecursive calling recursive} {delrecursive deleting recursive}}
} 0
test io-50.5 {testing handler deletion vs reentrant calls} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list notcalled $f]
    testchannelevent $f add readable [list del $f]
    proc notcalled {f} {
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
    set u toplevel
    update
    close $f
    string compare [string tolower $z] \
	[list {del calling recursive} {del deleted notcalled} \
	      {del deleted myself} {del after update}]
} 0
test io-27.6 {testing handler deletion vs reentrant calls} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list second $f]
    testchannelevent $f add readable [list first $f]
    proc first {f} {







|







6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
    set u toplevel
    update
    close $f
    string compare [string tolower $z] \
	[list {del calling recursive} {del deleted notcalled} \
	      {del deleted myself} {del after update}]
} 0
test io-50.6 {testing handler deletion vs reentrant calls} {
    removeFile test1
    set f [open test1 w]
    close $f
    set f [open test1 r]
    testchannelevent $f add readable [list second $f]
    testchannelevent $f add readable [list first $f]
    proc first {f} {
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
    close $f
    string compare [string tolower $z] \
	[list {first called} {first called not toplevel} \
	      {second called, first time} {second called, second time} \
	      {first after update}]
} 0

test io-28.1 {Test old socket deletion on Macintosh} {socket} {
    set x 0
    set result ""
    proc accept {s a p} {
	global x wait
	fconfigure $s -blocking off
	puts $s "sock[incr x]"
	close $s







|







6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
    close $f
    string compare [string tolower $z] \
	[list {first called} {first called not toplevel} \
	      {second called, first time} {second called, second time} \
	      {first after update}]
} 0

test io-51.1 {Test old socket deletion on Macintosh} {socket} {
    set x 0
    set result ""
    proc accept {s a p} {
	global x wait
	fconfigure $s -blocking off
	puts $s "sock[incr x]"
	close $s
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836

4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
    vwait wait
    lappend result [gets $cs]
    close $cs
    close $ss
    set result
} {sock1 sock2 sock3 sock4}

test io-29.1 {TclCopyChannel} {
    removeFile test1
    set f1 [open [info script]]
    set f2 [open test1 w]
    fcopy $f1 $f2 -command { # }
    catch { fcopy $f1 $f2 } msg
    close $f1
    close $f2
    string compare $msg "channel \"$f1\" is busy"
} {0}
test io-29.2 {TclCopyChannel} {
    removeFile test1
    set f1 [open [info script]]
    set f2 [open test1 w]
    set f3 [open [info script]]
    fcopy $f1 $f2 -command { # }
    catch { fcopy $f3 $f2 } msg
    close $f1
    close $f2
    close $f3
    string compare $msg "channel \"$f2\" is busy"
} {0}
test io-29.3 {TclCopyChannel} {
    removeFile test1
    set f1 [open [info script]]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation cr -blocking 0
    set s0 [fcopy $f1 $f2]
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    close $f1
    close $f2
    set s1 [file size [info script]]
    set s2 [file size test1]
    if {("$s1" == "$s2") && ($s0 == $s1)} {
        lappend result ok
    }
    set result
} {0 0 ok}
test io-29.4 {TclCopyChannel} {
    removeFile test1
    set f1 [open [info script]]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation cr -blocking 0
    fcopy $f1 $f2 -size 40
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    close $f1
    close $f2
    lappend result [file size test1]
} {0 0 40}
test io-29.5 {TclCopyChannel} {
    removeFile test1
    set f1 [open [info script]]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation lf -blocking 0
    fcopy $f1 $f2 -size -1
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    close $f1
    close $f2
    set s1 [file size [info script]]
    set s2 [file size test1]
    if {"$s1" == "$s2"} {
        lappend result ok
    }
    set result
} {0 0 ok}
test io-29.6 {TclCopyChannel} {
    removeFile test1
    set f1 [open [info script]]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation lf -blocking 0
    set s0 [fcopy $f1 $f2 -size [expr [file size [info script]] + 5]]
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    close $f1
    close $f2
    set s1 [file size [info script]]
    set s2 [file size test1]
    if {("$s1" == "$s2") && ($s0 == $s1)} {
        lappend result ok
    }
    set result
} {0 0 ok}
test io-29.7 {TclCopyChannel} {
    removeFile test1
    set f1 [open [info script]]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation lf -blocking 0
    fcopy $f1 $f2
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    set s1 [file size [info script]]
    set s2 [file size test1]
    close $f1
    close $f2
    if {"$s1" == "$s2"} {
        lappend result ok
    }
    set result
} {0 0 ok}
test io-29.8 {TclCopyChannel} {stdio} {
    removeFile test1
    removeFile pipe
    set f1 [open pipe w]
    fconfigure $f1 -translation lf
    puts $f1 {
	puts ready
	gets stdin
	set f1 [open [info script] r]
	fconfigure $f1 -translation lf
	puts [read $f1 100]
	close $f1
    }

    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    fconfigure $f1 -translation lf
    gets $f1
    puts $f1 ready
    flush $f1
    set f2 [open test1 w]
    fconfigure $f2 -translation lf
    set s0 [fcopy $f1 $f2 -size 40]
    catch {close $f1}
    close $f2
    list $s0 [file size test1]
} {40 40}

test io-30.1 {CopyData} {
    removeFile test1
    set f1 [open [info script]]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation cr -blocking 0
    fcopy $f1 $f2 -size 0
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    close $f1
    close $f2
    lappend result [file size test1]
} {0 0 0}
test io-30.2 {CopyData} {
    removeFile test1
    set f1 [open [info script]]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation cr -blocking 0
    fcopy $f1 $f2 -command {set s0}
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    vwait s0
    close $f1
    close $f2
    set s1 [file size [info script]]
    set s2 [file size test1]
    if {("$s1" == "$s2") && ($s0 == $s1)} {
        lappend result ok
    }
    set result
} {0 0 ok}
test io-30.3 {CopyData: background read underflow} {unixOnly} {
    removeFile test1
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	puts ready
	flush stdout				;# Don't assume line buffered!
	fcopy stdin stdout -command { set x }







|

|







|

|

|







|

|







|






|

|









|

|







|






|

|



|



|






|

|





|








|




|


|
|
|
|
<
>














|

|









|

|








|






|







6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420

6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
    vwait wait
    lappend result [gets $cs]
    close $cs
    close $ss
    set result
} {sock1 sock2 sock3 sock4}

test io-52.1 {TclCopyChannel} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    fcopy $f1 $f2 -command { # }
    catch { fcopy $f1 $f2 } msg
    close $f1
    close $f2
    string compare $msg "channel \"$f1\" is busy"
} {0}
test io-52.2 {TclCopyChannel} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    set f3 [open $thisScript]
    fcopy $f1 $f2 -command { # }
    catch { fcopy $f3 $f2 } msg
    close $f1
    close $f2
    close $f3
    string compare $msg "channel \"$f2\" is busy"
} {0}
test io-52.3 {TclCopyChannel} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation cr -blocking 0
    set s0 [fcopy $f1 $f2]
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    close $f1
    close $f2
    set s1 [file size $thisScript]
    set s2 [file size test1]
    if {("$s1" == "$s2") && ($s0 == $s1)} {
        lappend result ok
    }
    set result
} {0 0 ok}
test io-52.4 {TclCopyChannel} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation cr -blocking 0
    fcopy $f1 $f2 -size 40
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    close $f1
    close $f2
    lappend result [file size test1]
} {0 0 40}
test io-52.5 {TclCopyChannel} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation lf -blocking 0
    fcopy $f1 $f2 -size -1
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    close $f1
    close $f2
    set s1 [file size $thisScript]
    set s2 [file size test1]
    if {"$s1" == "$s2"} {
        lappend result ok
    }
    set result
} {0 0 ok}
test io-52.6 {TclCopyChannel} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation lf -blocking 0
    set s0 [fcopy $f1 $f2 -size [expr [file size $thisScript] + 5]]
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    close $f1
    close $f2
    set s1 [file size $thisScript]
    set s2 [file size test1]
    if {("$s1" == "$s2") && ($s0 == $s1)} {
        lappend result ok
    }
    set result
} {0 0 ok}
test io-52.7 {TclCopyChannel} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation lf -blocking 0
    fcopy $f1 $f2
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    set s1 [file size $thisScript]
    set s2 [file size test1]
    close $f1
    close $f2
    if {"$s1" == "$s2"} {
        lappend result ok
    }
    set result
} {0 0 ok}
test io-52.8 {TclCopyChannel} {stdio} {
    removeFile test1
    removeFile pipe
    set f1 [open pipe w]
    fconfigure $f1 -translation lf
    puts $f1 "
	puts ready
	gets stdin
	set f1 \[open [list $thisScript] r\]
	fconfigure \$f1 -translation lf
	puts \[read \$f1 100\]
	close \$f1

    "
    close $f1
    set f1 [open "|[list $tcltest pipe]" r+]
    fconfigure $f1 -translation lf
    gets $f1
    puts $f1 ready
    flush $f1
    set f2 [open test1 w]
    fconfigure $f2 -translation lf
    set s0 [fcopy $f1 $f2 -size 40]
    catch {close $f1}
    close $f2
    list $s0 [file size test1]
} {40 40}

test io-53.1 {CopyData} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation cr -blocking 0
    fcopy $f1 $f2 -size 0
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    close $f1
    close $f2
    lappend result [file size test1]
} {0 0 0}
test io-53.2 {CopyData} {
    removeFile test1
    set f1 [open $thisScript]
    set f2 [open test1 w]
    fconfigure $f1 -translation lf -blocking 0
    fconfigure $f2 -translation cr -blocking 0
    fcopy $f1 $f2 -command {set s0}
    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
    vwait s0
    close $f1
    close $f2
    set s1 [file size $thisScript]
    set s2 [file size test1]
    if {("$s1" == "$s2") && ($s0 == $s1)} {
        lappend result ok
    }
    set result
} {0 0 ok}
test io-53.3 {CopyData: background read underflow} {unixOnly} {
    removeFile test1
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
	puts ready
	flush stdout				;# Don't assume line buffered!
	fcopy stdin stdout -command { set x }
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
    close $f1
    after 500
    set f [open test1]
    lappend result [read $f]
    close $f
    set result
} "ready line1 line2 {done\n}"
test io-30.4 {CopyData: background write overflow} {unixOnly} {
    set big aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n
    for {set x 0} {$x < 12} {incr x} {
	append big $big
    }
    removeFile test1
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {







|
|







6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
    close $f1
    after 500
    set f [open test1]
    lappend result [read $f]
    close $f
    set result
} "ready line1 line2 {done\n}"
test io-53.4 {CopyData: background write overflow} {unixOnly} {
    set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
    for {set x 0} {$x < 12} {incr x} {
	append big $big
    }
    removeFile test1
    removeFile pipe
    set f1 [open pipe w]
    puts $f1 {
4940
4941
4942
4943
4944
4945
4946

4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962

4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
	}
    }
    vwait x
    close $f1
    set big {}
    set x
} done


proc FcopyTestAccept {sock args} {
    after 1000 "close $sock"
}
proc FcopyTestDone {bytes {error {}}} {
    global fcopyTestDone
    if {[string length $error]} {
	set fcopyTestDone 1
    } else {
	set fcopyTestDone 0
    }
}
if [catch {socket -server FcopyTestAccept 2828} listen] {
    puts stderr "Skipping fcopy error test"
} else {
    test io-30.5 {CopyData: error during fcopy} {

	set in [open [info script]]	;# 126 K
	set out [socket localhost 2828]
	catch {unset fcopyTestDone}
	close $listen	;# This means the socket open never really succeeds
	fcopy $in $out -command FcopyTestDone
	if ![info exists fcopyTestDone] {
	    vwait fcopyTestDone		;# The error occurs here in the b.g.
	}
	close $in
	close $out
	set fcopyTestDone	;# 1 for error condition
    } 1
}
test io-30.6 {CopyData: error during fcopy} {stdio} {
    removeFile pipe
    removeFile test1
    catch {unset fcopyTestDone}
    set f1 [open pipe w]
    puts $f1 "exit 1"
    close $f1
    set in [open "|[list $tcltest pipe]" r+]
    set out [open test1 w]
    fcopy $in $out -command [list FcopyTestDone]
    if ![info exists fcopyTestDone] {
	vwait fcopyTestDone
    }
    catch {close $in}
    close $out
    set fcopyTestDone	;# 0 for plain end of file
} {0}

test io-31.1 {Recursive channel events} {socket} {
    # This test checks to see if file events are delivered during recursive
    # event loops when there is buffered data on the channel.

    proc accept {s a p} {
	global as
	fconfigure $s -translation lf
	puts $s "line 1\nline2\nline3"







>












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

















|







6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545


6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559

6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
	}
    }
    vwait x
    close $f1
    set big {}
    set x
} done
set result {}

proc FcopyTestAccept {sock args} {
    after 1000 "close $sock"
}
proc FcopyTestDone {bytes {error {}}} {
    global fcopyTestDone
    if {[string length $error]} {
	set fcopyTestDone 1
    } else {
	set fcopyTestDone 0
    }
}



test io-53.5 {CopyData: error during fcopy} {socket} {
    set listen [socket -server FcopyTestAccept 2828]
    set in [open $thisScript]	;# 126 K
    set out [socket 127.0.0.1 2828]
    catch {unset fcopyTestDone}
    close $listen	;# This means the socket open never really succeeds
    fcopy $in $out -command FcopyTestDone
    if ![info exists fcopyTestDone] {
	vwait fcopyTestDone		;# The error occurs here in the b.g.
    }
    close $in
    close $out
    set fcopyTestDone	;# 1 for error condition
} 1

test io-53.6 {CopyData: error during fcopy} {stdio} {
    removeFile pipe
    removeFile test1
    catch {unset fcopyTestDone}
    set f1 [open pipe w]
    puts $f1 "exit 1"
    close $f1
    set in [open "|[list $tcltest pipe]" r+]
    set out [open test1 w]
    fcopy $in $out -command [list FcopyTestDone]
    if ![info exists fcopyTestDone] {
	vwait fcopyTestDone
    }
    catch {close $in}
    close $out
    set fcopyTestDone	;# 0 for plain end of file
} {0}

test io-54.1 {Recursive channel events} {socket} {
    # This test checks to see if file events are delivered during recursive
    # event loops when there is buffered data on the channel.

    proc accept {s a p} {
	global as
	fconfigure $s -translation lf
	puts $s "line 1\nline2\nline3"
5039
5040
5041
5042
5043
5044
5045
5046


5047
5048
5049
5050

5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070

5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090


5091
5092

5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124

5125
5126
5127













5128


5129
5130

5131








5132





5133

5134
5135
5136

5137

5138






5139




5140



5141




5142

5143
























    vwait x
    after cancel $a
    close $as
    close $ss
    close $cs
    list $result $x
} {{{line 1} 1 2} 2}
test io-31.2 {Testing for busy-wait in recursive channel events} {socket} {


    set s [socket -server accept 3939]
    proc accept {s a p} {
	global counter


	set counter 0
	fconfigure $s -blocking off -buffering line -translation lf
	fileevent $s readable "doit $s"
    }
    proc doit {s} {
	global counter

	incr counter
	set l [gets $s]
	if {"$l" == ""} {
	    fileevent $s readable "doit1 $s"
	    after 1000 newline
	}
    }
    proc doit1 {s} {
	global counter

	incr counter
	set l [gets $s]
	close $s

    }
    proc producer {} {
	global writer

	set writer [socket localhost 3939]
	fconfigure $writer -buffering line
	puts -nonewline $writer hello
	flush $writer
    }
    proc newline {} {
	global writer done

	puts $writer hello
	flush $writer
	set done 1
    }
    producer
    vwait done
    close $writer
    close $s


    set counter
} 1

test io-32.1 {ChannelEventScriptInvoker: deletion} {
    proc eventScript {fd} {
	close $fd
	error "planned error"
	set ::x whoops
    }
    proc bgerror {args} {
	set ::x got_error
    }
    set f [open fooBar w]
    fileevent $f writable [list eventScript $f]
    set x not_done
    vwait x
    set x
} {got_error}

test io-33.1 {ChannelTimerProc} {
    set f [open fooBar w]
    puts $f "this is a test"
    close $f
    set f [open fooBar r]
    testchannelevent $f add readable {
	read $f 1
	incr x
    }
    set x 0
    vwait x
    vwait x
    set result $x
    testchannelevent $f set 0 none
    after idle {set y done}
    vwait y

    lappend result $y
} {2 done}














removeFile fooBar


removeFile longfile
removeFile script

removeFile output








removeFile test1





removeFile pipe

removeFile my_script
removeFile foo
removeFile bar

removeFile test2

removeFile test3











file delete cat








set x ""

unset x































|
>
>


|

>





|





|



|




>




|















>
>


>
|















|















>



>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
|
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
|
|
|
>
|
>
|
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
|
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
    vwait x
    after cancel $a
    close $as
    close $ss
    close $cs
    list $result $x
} {{{line 1} 1 2} 2}
test io-54.2 {Testing for busy-wait in recursive channel events} {socket} {
    set accept {}
    set after {}
    set s [socket -server accept 3939]
    proc accept {s a p} {
	global counter accept

	set accept $s
	set counter 0
	fconfigure $s -blocking off -buffering line -translation lf
	fileevent $s readable "doit $s"
    }
    proc doit {s} {
	global counter after

	incr counter
	set l [gets $s]
	if {"$l" == ""} {
	    fileevent $s readable "doit1 $s"
	    set after [after 1000 newline]
	}
    }
    proc doit1 {s} {
	global counter accept

	incr counter
	set l [gets $s]
	close $s
	set accept {}
    }
    proc producer {} {
	global writer

	set writer [socket 127.0.0.1 3939]
	fconfigure $writer -buffering line
	puts -nonewline $writer hello
	flush $writer
    }
    proc newline {} {
	global writer done

	puts $writer hello
	flush $writer
	set done 1
    }
    producer
    vwait done
    close $writer
    close $s
    after cancel $after
    if {$accept != {}} {close $accept}
    set counter
} 1

test io-55.1 {ChannelEventScriptInvoker: deletion} {
    proc eventScript {fd} {
	close $fd
	error "planned error"
	set ::x whoops
    }
    proc bgerror {args} {
	set ::x got_error
    }
    set f [open fooBar w]
    fileevent $f writable [list eventScript $f]
    set x not_done
    vwait x
    set x
} {got_error}

test io-56.1 {ChannelTimerProc} {
    set f [open fooBar w]
    puts $f "this is a test"
    close $f
    set f [open fooBar r]
    testchannelevent $f add readable {
	read $f 1
	incr x
    }
    set x 0
    vwait x
    vwait x
    set result $x
    testchannelevent $f set 0 none
    after idle {set y done}
    vwait y
    close $f
    lappend result $y
} {2 done}

test io-57.1 {buffered data and file events, gets} {
    proc accept {sock args} {
	set ::s2 $sock
    }
    set server [socket -server accept 4040]
    set s [socket 127.0.0.1 4040]
    vwait s2
    update
    fileevent $s2 readable {lappend result readable}
    puts $s "12\n34567890"
    flush $s
    set result [gets $s2]
    after 1000 {lappend result timer}
    vwait result
    lappend result [gets $s2]
    vwait result
    close $s
    close $s2
    close $server
    set result
} {12 readable 34567890 timer}
test io-57.2 {buffered data and file events, read} {
    proc accept {sock args} {
	set ::s2 $sock
    }
    set server [socket -server accept 4041]
    set s [socket 127.0.0.1 4041]
    vwait s2
    update
    fileevent $s2 readable {lappend result readable}
    puts -nonewline $s "1234567890"
    flush $s
    set result [read $s2 1]
    after 1000 {lappend result timer}
    vwait result
    lappend result [read $s2 9]
    vwait result
    close $s
    close $s2
    close $server
    set result
} {1 readable 234567890 timer}
        
test io-58.1 {Tcl_NotifyChannel and error when closing} {unixOrPc} {
    set out [open script w]
    puts $out {
	puts "normal message from pipe"
	puts stderr "error message from pipe"
	exit 1
    }
    proc readit {pipe} {
	global x result
	if {[eof $pipe]} {
	    set x [catch {close $pipe} line]
	    lappend result catch $line
	} else {
	    gets $pipe line
	    lappend result gets $line
	}
    }
    close $out
    set pipe [open "|[list $tcltest] script" r]
    fileevent $pipe readable [list readit $pipe]
    set x ""
    set result ""
    vwait x
    list $x $result
} {1 {gets {normal message from pipe} gets {} catch {error message from pipe}}}

# cleanup
foreach file [list fooBar longfile script output test1 pipe my_script foo \
	bar test2 test3 cat stdout] {
    ::tcltest::removeFile $file
}
restoreState
::tcltest::cleanupTests
return













Changes to tests/ioCmd.test.

1
2
3
4
5
6
7
8
9

10
11
12
13

14


15
16
17
18
19
20
21
22
23
# Commands covered: open, close, gets, read, puts, seek, tell, eof, flush,
#		    fblocked, fconfigure, open, channel, fcopy
#
# 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-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# "@(#) ioCmd.test 1.49 97/10/31 17:23:22"



if {[string compare test [info procs test]] == 1} then {source defs}

removeFile test1
removeFile pipe

set executable [list [info nameofexecutable]]

test iocmd-1.1 {puts command} {









>




>
|
>
>
|
<







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
# Commands covered: open, close, gets, read, puts, seek, tell, eof, flush,
#		    fblocked, fconfigure, open, channel, fcopy
#
# 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-1994 The Regents of the University of California.
# 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: ioCmd.test,v 1.1.2.7 1999/03/24 04:25:42 stanton Exp $

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


removeFile test1
removeFile pipe

set executable [list [info nameofexecutable]]

test iocmd-1.1 {puts command} {
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
    list [catch {seek a b c d e f g} msg] $msg
} {1 {wrong # args: should be "seek channelId offset ?origin?"}}
test iocmd-5.3 {seek command} {
    list [catch {seek stdin gugu} msg] $msg
} {1 {expected integer but got "gugu"}}
test iocmd-5.4 {seek command} {
    list [catch {seek stdin 100 gugu} msg] $msg
} {1 {bad origin "gugu": should be start, current, or end}}

test iocmd-6.1 {tell command} {
    list [catch {tell} msg] $msg
} {1 {wrong # args: should be "tell channelId"}}
test iocmd-6.2 {tell command} {
    list [catch {tell a b c d e} msg] $msg
} {1 {wrong # args: should be "tell channelId"}}







|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
    list [catch {seek a b c d e f g} msg] $msg
} {1 {wrong # args: should be "seek channelId offset ?origin?"}}
test iocmd-5.3 {seek command} {
    list [catch {seek stdin gugu} msg] $msg
} {1 {expected integer but got "gugu"}}
test iocmd-5.4 {seek command} {
    list [catch {seek stdin 100 gugu} msg] $msg
} {1 {bad origin "gugu": must be start, current, or end}}

test iocmd-6.1 {tell command} {
    list [catch {tell} msg] $msg
} {1 {wrong # args: should be "tell channelId"}}
test iocmd-6.2 {tell command} {
    list [catch {tell a b c d e} msg] $msg
} {1 {wrong # args: should be "tell channelId"}}
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
} {1 {bad value for -buffering: must be one of full, line, or none}}
test iocmd-8.6 {fconfigure command} {
    list [catch {fconfigure stdin -translation froboz} msg] $msg
} {1 {bad value for -translation: must be one of auto, binary, cr, lf, crlf, or platform}}
test iocmd-8.7 {fconfigure command} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {}
    set x [fconfigure $f1]
    close $f1
    set x
} {-blocking 1 -buffering full -buffersize 4096 -eofchar {} -translation lf}
test iocmd-8.8 {fconfigure command} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -buffering line -buffersize 3030 \
		-eofchar {}
    set x ""
    lappend x [fconfigure $f1 -buffering]
    lappend x [fconfigure $f1]
    close $f1
    set x
} {line {-blocking 1 -buffering line -buffersize 3030 -eofchar {} -translation lf}}
test iocmd-8.9 {fconfigure command} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation binary -buffering none -buffersize 4040 \
		-eofchar {}
    set x [fconfigure $f1]
    close $f1
    set x
} {-blocking 1 -buffering none -buffersize 4040 -eofchar {} -translation lf}
test iocmd-8.10 {fconfigure command} {
    list [catch {fconfigure a b} msg] $msg
} {1 {can not find channel named "a"}}
test iocmd-8.11 {fconfigure command} {
    list [catch {fconfigure stdout -froboz blarfo} msg] $msg
} {1 {bad option "-froboz": should be one of -blocking, -buffering, -buffersize, -eofchar, or -translation}}
test iocmd-8.12 {fconfigure command} {
    list [catch {fconfigure stdout -b blarfo} msg] $msg
} {1 {bad option "-b": should be one of -blocking, -buffering, -buffersize, -eofchar, or -translation}}
test iocmd-8.13 {fconfigure command} {
    list [catch {fconfigure stdout -buffer blarfo} msg] $msg
} {1 {bad option "-buffer": should be one of -blocking, -buffering, -buffersize, -eofchar, or -translation}}
test iocmd-8.14 {fconfigure command} {
    fconfigure stdin -buffers
} 4096
proc iocmdSSETUP {} {
  uplevel {
	set srv [socket -server iocmdSRV 0];
	set port [lindex [fconfigure $srv -sockname] 2];
	proc iocmdSRV {sock ip port} {close $sock}
	set cli [socket localhost $port];
  }
}
proc iocmdSSHTDWN {} {
  uplevel {
	close $cli;
	close $srv;
	unset cli srv port







|



|




|





|




|



|




















|







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
} {1 {bad value for -buffering: must be one of full, line, or none}}
test iocmd-8.6 {fconfigure command} {
    list [catch {fconfigure stdin -translation froboz} msg] $msg
} {1 {bad value for -translation: must be one of auto, binary, cr, lf, crlf, or platform}}
test iocmd-8.7 {fconfigure command} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -eofchar {} -encoding unicode
    set x [fconfigure $f1]
    close $f1
    set x
} {-blocking 1 -buffering full -buffersize 4096 -encoding unicode -eofchar {} -translation lf}
test iocmd-8.8 {fconfigure command} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation lf -buffering line -buffersize 3030 \
		-eofchar {} -encoding unicode
    set x ""
    lappend x [fconfigure $f1 -buffering]
    lappend x [fconfigure $f1]
    close $f1
    set x
} {line {-blocking 1 -buffering line -buffersize 3030 -encoding unicode -eofchar {} -translation lf}}
test iocmd-8.9 {fconfigure command} {
    removeFile test1
    set f1 [open test1 w]
    fconfigure $f1 -translation binary -buffering none -buffersize 4040 \
		-eofchar {} -encoding binary
    set x [fconfigure $f1]
    close $f1
    set x
} {-blocking 1 -buffering none -buffersize 4040 -encoding binary -eofchar {} -translation lf}
test iocmd-8.10 {fconfigure command} {
    list [catch {fconfigure a b} msg] $msg
} {1 {can not find channel named "a"}}
test iocmd-8.11 {fconfigure command} {
    list [catch {fconfigure stdout -froboz blarfo} msg] $msg
} {1 {bad option "-froboz": should be one of -blocking, -buffering, -buffersize, -eofchar, or -translation}}
test iocmd-8.12 {fconfigure command} {
    list [catch {fconfigure stdout -b blarfo} msg] $msg
} {1 {bad option "-b": should be one of -blocking, -buffering, -buffersize, -eofchar, or -translation}}
test iocmd-8.13 {fconfigure command} {
    list [catch {fconfigure stdout -buffer blarfo} msg] $msg
} {1 {bad option "-buffer": should be one of -blocking, -buffering, -buffersize, -eofchar, or -translation}}
test iocmd-8.14 {fconfigure command} {
    fconfigure stdin -buffers
} 4096
proc iocmdSSETUP {} {
  uplevel {
	set srv [socket -server iocmdSRV 0];
	set port [lindex [fconfigure $srv -sockname] 2];
	proc iocmdSRV {sock ip port} {close $sock}
	set cli [socket 127.0.0.1 $port];
  }
}
proc iocmdSSHTDWN {} {
  uplevel {
	close $cli;
	close $srv;
	unset cli srv port
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
test iocmd-8.18 {fconfigure command / unix tty channel} {nonPortable unixOnly} {
	# might fail if /dev/ttya is unavailable
	set tty [open /dev/ttya]
	set r [list [catch {fconfigure $tty -blah blih} msg] $msg];
	close $tty;
	set r;
} {1 {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -eofchar, -translation, or -mode}}
test iocmd-8.19 {fconfigure command / win tty channel} {pcOnly && !win32s} {
	# None of the com port functions are implemented on Win32s.
	# Also, might fail if com1 is unavailable
	set tty [open com1]
	set r [list [catch {fconfigure $tty -blah blih} msg] $msg];
	close $tty;
	set r;
} {1 {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -eofchar, -translation, or -mode}}

test iocmd-9.1 {eof command} {
    list [catch {eof} msg] $msg $errorCode
} {1 {wrong # args: should be "eof channelId"} NONE}
test iocmd-9.2 {eof command} {
    list [catch {eof a b} msg] $msg $errorCode
} {1 {wrong # args: should be "eof channelId"} NONE}
test iocmd-9.3 {eof command} {
    catch {close file100}
    list [catch {eof file100} msg] $msg $errorCode
} {1 {can not find channel named "file100"} NONE}



test iocmd-10.1 {fblocked command} {
    list [catch {fblocked} msg] $msg
} {1 {wrong # args: should be "fblocked channelId"}}
test iocmd-10.2 {fblocked command} {
    list [catch {fblocked a b c d e f g} msg] $msg
} {1 {wrong # args: should be "fblocked channelId"}}







|
<
|
















>
>







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
test iocmd-8.18 {fconfigure command / unix tty channel} {nonPortable unixOnly} {
	# might fail if /dev/ttya is unavailable
	set tty [open /dev/ttya]
	set r [list [catch {fconfigure $tty -blah blih} msg] $msg];
	close $tty;
	set r;
} {1 {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -eofchar, -translation, or -mode}}
test iocmd-8.19 {fconfigure command / win tty channel} {nonPortable pcOnly} {

	# might fail if com1 is unavailable
	set tty [open com1]
	set r [list [catch {fconfigure $tty -blah blih} msg] $msg];
	close $tty;
	set r;
} {1 {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -eofchar, -translation, or -mode}}

test iocmd-9.1 {eof command} {
    list [catch {eof} msg] $msg $errorCode
} {1 {wrong # args: should be "eof channelId"} NONE}
test iocmd-9.2 {eof command} {
    list [catch {eof a b} msg] $msg $errorCode
} {1 {wrong # args: should be "eof channelId"} NONE}
test iocmd-9.3 {eof command} {
    catch {close file100}
    list [catch {eof file100} msg] $msg $errorCode
} {1 {can not find channel named "file100"} NONE}

# The tests for Tcl_ExecObjCmd are in exec.test

test iocmd-10.1 {fblocked command} {
    list [catch {fblocked} msg] $msg
} {1 {wrong # args: should be "fblocked channelId"}}
test iocmd-10.2 {fblocked command} {
    list [catch {fblocked a b c d e f g} msg] $msg
} {1 {wrong # args: should be "fblocked channelId"}}
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








    list [catch {fcopy $wfile $wfile} msg] $msg
} "1 {channel \"$wfile\" wasn't opened for reading}"
test iocmd-15.9 {Tcl_FcopyObjCmd} {
    list [catch {fcopy $rfile $rfile} msg] $msg
} "1 {channel \"$rfile\" wasn't opened for writing}"
test iocmd-15.10 {Tcl_FcopyObjCmd} {
    list [catch {fcopy $rfile $wfile foo bar} msg] $msg
} {1 {bad switch "foo": must be -size, or -command}}
test iocmd-15.11 {Tcl_FcopyObjCmd} {
    list [catch {fcopy $rfile $wfile -size foo} msg] $msg
} {1 {expected integer but got "foo"}}
test iocmd-15.12 {Tcl_FcopyObjCmd} {
    list [catch {fcopy $rfile $wfile -command bar -size foo} msg] $msg
} {1 {expected integer but got "foo"}}

close $rfile
close $wfile

removeFile test1
removeFile test2
removeFile test3
removeFile test4

# delay long enough for background processes to finish
after 500

removeFile test5



removeFile pipe
removeFile output
set x ""
set x















|










|
|
|
<
>


>
|
>
>
>
|
|
|
|
>
>
>
>
>
>
>
>
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
    list [catch {fcopy $wfile $wfile} msg] $msg
} "1 {channel \"$wfile\" wasn't opened for reading}"
test iocmd-15.9 {Tcl_FcopyObjCmd} {
    list [catch {fcopy $rfile $rfile} msg] $msg
} "1 {channel \"$rfile\" wasn't opened for writing}"
test iocmd-15.10 {Tcl_FcopyObjCmd} {
    list [catch {fcopy $rfile $wfile foo bar} msg] $msg
} {1 {bad switch "foo": must be -size or -command}}
test iocmd-15.11 {Tcl_FcopyObjCmd} {
    list [catch {fcopy $rfile $wfile -size foo} msg] $msg
} {1 {expected integer but got "foo"}}
test iocmd-15.12 {Tcl_FcopyObjCmd} {
    list [catch {fcopy $rfile $wfile -command bar -size foo} msg] $msg
} {1 {expected integer but got "foo"}}

close $rfile
close $wfile

# cleanup
foreach file [list test1 test2 test3 test4] {
    ::tcltest::removeFile $file

}
# delay long enough for background processes to finish
after 500
foreach file [list test5 pipe output] {
    ::tcltest::removeFile $file
}
::tcltest::cleanupTests
return












Added tests/ioUtil.test.





























































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# This file (ioUtil.test) tests the hookable TclStat(), TclAccess(),
# and Tcl_OpenFileChannel, routines in the file generic/tclIOUtils.c.
# Sourcing this file into Tcl runs the tests and generates output for
# errors. No output means no errors were found. 
# 
# 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: ioUtil.test,v 1.1.2.6 1999/03/24 02:49:19 hershey Exp $
 
if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

set unsetScript {
    catch {unset testStat1(size)}
    catch {unset testStat2(size)}
    catch {unset testStat3(size)}
}

test ioUtil-1.1 {TclStat: Check that none of the test procs are there.} {knownBug} {
    catch {file stat testStat1%.fil testStat1} err1
    catch {file stat testStat2%.fil testStat2} err2
    catch {file stat testStat3%.fil testStat3} err3
    list $err1 $err2 $err3
} {{couldn't stat "testStat1%.fil": no such file or directory} {couldn't stat "testStat2%.fil": no such file or directory} {couldn't stat "testStat3%.fil": no such file or directory}}

if {[info commands teststatproc] == {}} {
    puts "This application hasn't been compiled with the \"teststatproc\""
    puts "command, so I can't test Tcl_Stat_* etc."
} else {
test ioUtil-1.2 {TclStatInsertProc: Insert the 3 test TclStat_ procedures.} {
    catch {teststatproc insert TclpStat} err1
    teststatproc insert TestStatProc1
    teststatproc insert TestStatProc2
    teststatproc insert TestStatProc3
    set err1
} {bad arg "insert": must be TestStatProc1, TestStatProc2, or TestStatProc3}

test ioUtil-1.3 {TclStat: Use "file stat ?" to invoke each procedure.} {knownBug} {
    file stat testStat2%.fil testStat2
    file stat testStat1%.fil testStat1
    file stat testStat3%.fil testStat3

    list $testStat2(size) $testStat1(size) $testStat3(size)
} {2345 1234 3456}

eval $unsetScript

test ioUtil-1.4 {TclStatDeleteProc: "TclpStat" function should not be deletedable.} {
    catch {teststatproc delete TclpStat} err2
    set err2
} {"TclpStat": could not be deleteed}

test ioUtil-1.5 {TclStatDeleteProc: Delete the 2nd TclStat procedure.} {knownBug} {
    # Delete the 2nd procedure and test that it longer exists but that
    #   the others do actually return a result.

    teststatproc delete TestStatProc2
    file stat testStat1%.fil testStat1
    catch {file stat testStat2%.fil testStat2} err3
    file stat testStat3%.fil testStat3

    list $testStat1(size) $err3 $testStat3(size)
} {1234 {couldn't stat "testStat2%.fil": no such file or directory} 3456}

eval $unsetScript

test ioUtil-1.6 {TclStatDeleteProc: Delete the 1st TclStat procedure.} {knownBug} {
    # Next delete the 1st procedure and test that only the 3rd procedure
    #   is the only one that exists.

    teststatproc delete TestStatProc1
    catch {file stat testStat1%.fil testStat1} err4
    catch {file stat testStat2%.fil testStat2} err5
    file stat testStat3%.fil testStat3

    list $err4 $err5 $testStat3(size)
} {{couldn't stat "testStat1%.fil": no such file or directory} {couldn't stat "testStat2%.fil": no such file or directory} 3456}

eval $unsetScript

test ioUtil-1.7 {TclStatDeleteProc: Delete the 3rd procedure & verify all are gone.} {knownBug} {
    # Finally delete the 3rd procedure and check that none of the
    #   procedures exist.

    teststatproc delete TestStatProc3
    catch {file stat testStat1%.fil testStat1} err6
    catch {file stat testStat2%.fil testStat2} err7
    catch {file stat testStat3%.fil testStat3} err8

    list $err6 $err7 $err8
} {{couldn't stat "testStat1%.fil": no such file or directory} {couldn't stat "testStat2%.fil": no such file or directory} {couldn't stat "testStat3%.fil": no such file or directory}}

eval $unsetScript

test ioUtil-1.8 {TclStatDeleteProc: Verify that all procs have been deleted.} {knownBug} {
    # Attempt to delete all the Stat procs. again to ensure they no longer
    #   exist and an error is returned.

    catch {teststatproc delete TestStatProc1} err9
    catch {teststatproc delete TestStatProc2} err10
    catch {teststatproc delete TestStatProc3} err11

    list $err9 $err10 $err11
} {{"TestStatProc1": could not be deleteed} {"TestStatProc2": could not be deleteed} {"TestStatProc3": could not be deleteed}}
}

eval $unsetScript


test access-1.1 {TclAccess: Check that none of the test procs are there.} {
    catch {file exists testAccess1%.fil} err1
    catch {file exists testAccess2%.fil} err2
    catch {file exists testAccess3%.fil} err3
    list $err1 $err2 $err3
} {0 0 0}

if {[info commands testaccessproc] == {}} {
    puts "This application hasn't been compiled with the \"testaccessproc\""
    puts "command, so I can't test Tcl_Access_* etc."
} else {
test ioUtil-1.2 {TclAccessInsertProc: Insert the 3 test TclAccess_ procedures.} {
    catch {testaccessproc insert TclpAccess} err1
    testaccessproc insert TestAccessProc1
    testaccessproc insert TestAccessProc2
    testaccessproc insert TestAccessProc3
    set err1
} {bad arg "insert": must be TestAccessProc1, TestAccessProc2, or TestAccessProc3}

test ioUtil-2.3 {TclAccess: Use "file access ?" to invoke each procedure.} {
    list \
    	[file exists testAccess2%.fil] \
   		[file exists testAccess1%.fil] \
		[file exists testAccess3%.fil]
} {1 1 1}

test ioUtil-2.4 {TclAccessDeleteProc: "TclpAccess" function should not be deletedable.} {
    catch {testaccessproc delete TclpAccess} err2
    set err2
} {"TclpAccess": could not be deleteed}

test accesst-1.5 {TclAccessDeleteProc: Delete the 2nd TclAccess procedure.} {
    # Delete the 2nd procedure and test that it longer exists but that
    #   the others do actually return a result.

    testaccessproc delete TestAccessProc2
    set res1 [file exists testAccess1%.fil]
    catch {file exists testAccess2%.fil} err3
    set res2 [file exists testAccess3%.fil]

    list $res1 $err3 $res2
} {1 0 1}

test ioUtil-2.6 {TclAccessDeleteProc: Delete the 1st TclAccess procedure.} {
    # Next delete the 1st procedure and test that only the 3rd procedure
    #   is the only one that exists.

    testaccessproc delete TestAccessProc1
    catch {file exists testAccess1%.fil} err4
    catch {file exists testAccess2%.fil} err5
    set res3 [file exists testAccess3%.fil]

    list $err4 $err5 $res3
} {0 0 1}

test ioUtil-2.7 {TclAccessDeleteProc: Delete the 3rd procedure & verify all are gone.} {
    # Finally delete the 3rd procedure and check that none of the
    #   procedures exist.

    testaccessproc delete TestAccessProc3
    catch {file exists testAccess1%.fil} err6
    catch {file exists testAccess2%.fil} err7
    catch {file exists testAccess3%.fil} err8

    list $err6 $err7 $err8
} {0 0 0}

test ioUtil-2.8 {TclAccessDeleteProc: Verify that all procs have been deleted.} {
    # Attempt to delete all the Access procs. again to ensure they no longer
    #   exist and an error is returned.

    catch {testaccessproc delete TestAccessProc1} err9
    catch {testaccessproc delete TestAccessProc2} err10
    catch {testaccessproc delete TestAccessProc3} err11

    list $err9 $err10 $err11
} {{"TestAccessProc1": could not be deleteed} {"TestAccessProc2": could not be deleteed} {"TestAccessProc3": could not be deleteed}}
}

test ioUtil-3.1 {TclOpenFileChannel: Check that none of the test procs are there.} {
    catch {file exists __testOpenFileChannel1%__.fil} err1
    catch {file exists __testOpenFileChannel2%__.fil} err2
    catch {file exists __testOpenFileChannel3%__.fil} err3
    catch {file exists __testOpenFileChannel1%__.fil} err4
    catch {file exists __testOpenFileChannel2%__.fil} err5
    catch {file exists __testOpenFileChannel3%__.fil} err6
    list $err1 $err2 $err3 $err4 $err5 $err6
} {0 0 0 0 0 0}

if {[info commands testopenfilechannelproc] == {}} {
    puts "This application hasn't been compiled with the \"testopenfilechannelproc\""
    puts "command, so I can't test Tcl_OpenFileChannelInsert"
} else {
test ioUtil-3.2 {TclOpenFileChannelInsertProc: Insert the 3 test TclOpenFileChannel_ procedures.} {
    catch {testopenfilechannelproc insert TclpOpenFileChannel} err1
    testopenfilechannelproc insert TestOpenFileChannelProc1
    testopenfilechannelproc insert TestOpenFileChannelProc2
    testopenfilechannelproc insert TestOpenFileChannelProc3
    set err1
} {bad arg "insert": must be TestOpenFileChannelProc1, TestOpenFileChannelProc2, or TestOpenFileChannelProc3}

test ioUtil-3.3 {TclOpenFileChannel: Use "file openfilechannel ?" to invoke each procedure.} {
	close [open __testOpenFileChannel1%__.fil w]
	close [open __testOpenFileChannel2%__.fil w]
	close [open __testOpenFileChannel3%__.fil w]

	catch {
		close [open testOpenFileChannel1%.fil r]
		close [open testOpenFileChannel2%.fil r]
		close [open testOpenFileChannel3%.fil r]
	} err

	file delete __testOpenFileChannel1%__.fil
	file delete __testOpenFileChannel2%__.fil
	file delete __testOpenFileChannel3%__.fil

	set err
} {}

test ioUtil-3.4 {TclOpenFileChannelDeleteProc: "TclpOpenFileChannel" function should not be deletedable.} {
    catch {testopenfilechannelproc delete TclpOpenFileChannel} err2
    set err2
} {"TclpOpenFileChannel": could not be deleteed}

test openfilechannelt-1.5 {TclOpenFileChannelDeleteProc: Delete the 2nd TclOpenFileChannel procedure.} {
    # Delete the 2nd procedure and test that it longer exists but that
    #   the others do actually return a result.

    testopenfilechannelproc delete TestOpenFileChannelProc2

	close [open __testOpenFileChannel1%__.fil w]
	close [open __testOpenFileChannel3%__.fil w]

	catch {
		close [open testOpenFileChannel1%.fil r]
		catch {close [open testOpenFileChannel2%.fil r]}
		close [open testOpenFileChannel3%.fil r]
	} err3

	file delete __testOpenFileChannel1%__.fil
	file delete __testOpenFileChannel3%__.fil

    set err3
} {}

test ioUtil-3.6 {TclOpenFileChannelDeleteProc: Delete the 1st TclOpenFileChannel procedure.} {
    # Next delete the 1st procedure and test that only the 3rd procedure
    #   is the only one that exists.

    testopenfilechannelproc delete TestOpenFileChannelProc1

	close [open __testOpenFileChannel3%__.fil w]

	catch {
		catch {close [open testOpenFileChannel1%.fil r]}
		catch {close [open testOpenFileChannel2%.fil r]}
		close [open testOpenFileChannel3%.fil r]
	} err4

	file delete __testOpenFileChannel3%__.fil

    set err4
} {}

test ioUtil-3.7 {TclOpenFileChannelDeleteProc: Delete the 3rd procedure & verify all are gone.} {
    # Finally delete the 3rd procedure and check that none of the
    #   procedures exist.

    testopenfilechannelproc delete TestOpenFileChannelProc3
	catch {
		catch [open testOpenFileChannel1%.fil r]
		catch [open testOpenFileChannel2%.fil r]
		catch [open testOpenFileChannel3%.fil r]
	} err5

    set err5
} {1}

test ioUtil-3.8 {TclOpenFileChannelDeleteProc: Verify that all procs have been deleted.} {
    # Attempt to delete all the OpenFileChannel procs. again to ensure they no longer
    #   exist and an error is returned.

    catch {testopenfilechannelproc delete TestOpenFileChannelProc1} err9
    catch {testopenfilechannelproc delete TestOpenFileChannelProc2} err10
    catch {testopenfilechannelproc delete TestOpenFileChannelProc3} err11

    list $err9 $err10 $err11
} {{"TestOpenFileChannelProc1": could not be deleteed} {"TestOpenFileChannelProc2": could not be deleteed} {"TestOpenFileChannelProc3": could not be deleteed}}
}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/join.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  join
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) join.test 1.7 97/10/06 13:04:59



if {[string compare test [info procs test]] == 1} then {source defs}

test join-1.1 {basic join commands} {
    join {a b c} xyz
} axyzbxyzc
test join-1.2 {basic join commands} {
    join {a b c} {}
} abc








>




>
|
>
>
|
<







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
# Commands covered:  join
#
# 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: join.test,v 1.1.2.5 1999/03/24 02:49:20 hershey Exp $

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


test join-1.1 {basic join commands} {
    join {a b c} xyz
} axyzbxyzc
test join-1.2 {basic join commands} {
    join {a b c} {}
} abc
40
41
42
43
44
45
46
47



48











test join-3.1 {joinString is binary ok} {
  string length [join {a b c} a\0b]
} 9

test join-3.2 {join is binary ok} {
  string length [join "a\0b a\0b a\0b"]
} 11
























>
>
>

>
>
>
>
>
>
>
>
>
>
>
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
test join-3.1 {joinString is binary ok} {
  string length [join {a b c} a\0b]
} 9

test join-3.2 {join is binary ok} {
  string length [join "a\0b a\0b a\0b"]
} 11

# cleanup
::tcltest::cleanupTests
return












Changes to tests/lindex.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  lindex
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) lindex.test 1.7 97/02/27 16:53:56



if {[string compare test [info procs test]] == 1} then {source defs}

test lindex-1.1 {basic tests} {
    lindex {a b c} 0} a
test lindex-1.2 {basic tests} {
    lindex {a {b c d} x} 1} {b c d}
test lindex-1.3 {basic tests} {
    lindex {a b\ c\ d x} 1} {b c d}








>




>
|
>
>
|
<







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
# Commands covered:  lindex
#
# 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: lindex.test,v 1.1.2.5 1999/03/24 02:49:20 hershey Exp $

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


test lindex-1.1 {basic tests} {
    lindex {a b c} 0} a
test lindex-1.2 {basic tests} {
    lindex {a {b c d} x} 1} {b c d}
test lindex-1.3 {basic tests} {
    lindex {a b\ c\ d x} 1} {b c d}
68
69
70
71
72
73
74
















} {{}}
test lindex-3.3 {quoted elements} {
    lindex {ab "c d \" x" y} 1
} {c d " x}
test lindex-3.4 {quoted elements} {
    lindex {a b {c d "e} {f g"}} 2
} {c d "e}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
} {{}}
test lindex-3.3 {quoted elements} {
    lindex {ab "c d \" x" y} 1
} {c d " x}
test lindex-3.4 {quoted elements} {
    lindex {a b {c d "e} {f g"}} 2
} {c d "e}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/link.test.

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
# Commands covered:  none
#
# This file contains a collection of tests for Tcl_LinkVar and related
# library procedures.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) link.test 1.12 97/01/21 21:16:04




if {[info commands testlink] == {}} {
    puts "This application hasn't been compiled with the \"testlink\""
    puts "command, so I can't test Tcl_LinkVar et al."

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

foreach i {int real bool string} {
    catch {unset $i}
}
test link-1.1 {reading C variables from Tcl} {
    testlink delete
    testlink set 43 1.23 4 -
    testlink create 1 1 1 1








>




>
|
>
>
>




>



<
<







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
# Commands covered:  none
#
# This file contains a collection of tests for Tcl_LinkVar and related
# library procedures.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 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: link.test,v 1.1.2.6 1999/03/26 19:14:01 hershey Exp $

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

if {[info commands testlink] == {}} {
    puts "This application hasn't been compiled with the \"testlink\""
    puts "command, so I can't test Tcl_LinkVar et al."
    ::tcltest::cleanupTests
    return
}



foreach i {int real bool string} {
    catch {unset $i}
}
test link-1.1 {reading C variables from Tcl} {
    testlink delete
    testlink set 43 1.23 4 -
    testlink create 1 1 1 1
224
225
226
227
228
229
230

231
232
233
234
















    set x
} {}
test link-8.3 {Tcl_UpdateLinkedVar procedure, read-only variable} {
    testlink create 0 0 0 0
    list [catch {testlink update 47 {} {} {}} msg] $msg $int
} {0 {} 47}


testlink delete
foreach i {int real bool string} {
    catch {unset $i}
}























>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    set x
} {}
test link-8.3 {Tcl_UpdateLinkedVar procedure, read-only variable} {
    testlink create 0 0 0 0
    list [catch {testlink update 47 {} {} {}} msg] $msg $int
} {0 {} 47}

testlink set 0 0 0 -
testlink delete
foreach i {int real bool string} {
    catch {unset $i}
}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/linsert.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  linsert
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) linsert.test 1.14 97/11/18 13:54:18



if {[string compare test [info procs test]] == 1} then {source defs}

catch {unset lis}
catch {rename p ""}

test linsert-1.1 {linsert command} {
    linsert {1 2 3 4 5} 0 a
} {a 1 2 3 4 5}








>




>
|
>
>
|
<







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
# Commands covered:  linsert
#
# 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: linsert.test,v 1.1.2.5 1999/03/24 02:49:22 hershey Exp $

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


catch {unset lis}
catch {rename p ""}

test linsert-1.1 {linsert command} {
    linsert {1 2 3 4 5} 0 a
} {a 1 2 3 4 5}
97
98
99
100
101
102
103

104
105














} "a b c"
test linsert-3.2 {linsert won't modify shared argument objects} {
    catch {unset lis}
    set lis [format "a \"%s\" c" "b"]
    linsert $lis 0 [string length $lis]
} "7 a b c"


catch {unset lis}
catch {rename p ""}





















>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
} "a b c"
test linsert-3.2 {linsert won't modify shared argument objects} {
    catch {unset lis}
    set lis [format "a \"%s\" c" "b"]
    linsert $lis 0 [string length $lis]
} "7 a b c"

# cleanup
catch {unset lis}
catch {rename p ""}
::tcltest::cleanupTests
return












Changes to tests/list.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  list
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) list.test 1.22 97/06/23 18:19:17



if {[string compare test [info procs test]] == 1} then {source defs}

# First, a bunch of individual tests

test list-1.1 {basic tests} {list a b c} {a b c}
test list-1.2 {basic tests} {list {a b} c} {{a b} c}
test list-1.3 {basic tests} {list \{a b c} {\{a b c}
test list-1.4 {basic tests} "list a{}} b{} c}" "a\\{\\}\\} b{} 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
# Commands covered:  list
#
# 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: list.test,v 1.1.2.5 1999/03/24 02:49:22 hershey Exp $

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


# First, a bunch of individual tests

test list-1.1 {basic tests} {list a b c} {a b c}
test list-1.2 {basic tests} {list {a b} c} {{a b} c}
test list-1.3 {basic tests} {list \{a b c} {\{a b c}
test list-1.4 {basic tests} "list a{}} b{} c}" "a\\{\\}\\} b{} c\\}"
101
102
103
104
105
106
107
















	set last [expr $last-1]
    }
    return [concat $result $list]
}
test list-3.1 {SetListFromAny and lrange/concat results} {
    slowsort {fred julie alex carol bill annie}
} {alex annie bill carol fred julie}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
	set last [expr $last-1]
    }
    return [concat $result $list]
}
test list-3.1 {SetListFromAny and lrange/concat results} {
    slowsort {fred julie alex carol bill annie}
} {alex annie bill carol fred julie}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/listObj.test.

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
# Functionality covered: operation of the procedures in tclListObj.c that
# implement the Tcl type manager for the list object type.
#
# 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) 1995-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) listObj.test 1.9 97/06/10 15:28:11




if {[info commands testobj] == {}} {
    puts "This application hasn't been compiled with the \"testobj\""
    puts "command, so I can't test the Tcl type and object support."

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

catch {unset x}
test listobj-1.1 {Tcl_GetListObjType} {
    set t [testobj types]
    set first [string first "list" $t]
    set result [expr {$first != -1}]
} {1}

test listobj-2.1 {Tcl_ListObjForObjArray, use in lappend} {
    catch {unset x}
    list [lappend x 1 abc def] [lappend x 1 ghi jkl] $x
} {{1 abc def} {1 abc def 1 ghi jkl} {1 abc def 1 ghi jkl}}
test listobj-2.2 {Tcl_ListObjForObjArray, use in ObjInterpProc} {
    proc return_args {args} {
        return $args
    }
    list [return_args] [return_args x] [return_args x y]
} {{} x {x y}}




test listobj-3.1 {Tcl_ListObjAppend, list conversion} {
    catch {unset x}
    list [lappend x 1 2 abc "long string"] $x
} {{1 2 abc {long string}} {1 2 abc {long string}}}
test listobj-3.2 {Tcl_ListObjAppend, list conversion} {
    set x ""








>




>
|
>
>
>




>



<
<







|



|





>
>
>







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
# Functionality covered: operation of the procedures in tclListObj.c that
# implement the Tcl type manager for the list object type.
#
# 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) 1995-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: listObj.test,v 1.1.2.6 1999/03/26 19:14:02 hershey Exp $

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

if {[info commands testobj] == {}} {
    puts "This application hasn't been compiled with the \"testobj\""
    puts "command, so I can't test the Tcl type and object support."
    ::tcltest::cleanupTests
    return
}



catch {unset x}
test listobj-1.1 {Tcl_GetListObjType} {
    set t [testobj types]
    set first [string first "list" $t]
    set result [expr {$first != -1}]
} {1}

test listobj-2.1 {Tcl_SetListObj, use in lappend} {
    catch {unset x}
    list [lappend x 1 abc def] [lappend x 1 ghi jkl] $x
} {{1 abc def} {1 abc def 1 ghi jkl} {1 abc def 1 ghi jkl}}
test listobj-2.2 {Tcl_SetListObj, use in ObjInterpProc} {
    proc return_args {args} {
        return $args
    }
    list [return_args] [return_args x] [return_args x y]
} {{} x {x y}}
test listobj-2.3 {Tcl_SetListObj, zero element count} {
    list
} {}

test listobj-3.1 {Tcl_ListObjAppend, list conversion} {
    catch {unset x}
    list [lappend x 1 2 abc "long string"] $x
} {{1 2 abc {long string}} {1 2 abc {long string}}}
test listobj-3.2 {Tcl_ListObjAppend, list conversion} {
    set x ""
170
171
172
173
174
175
176
















test listobj-8.1 {SetListFromAny} {
    lindex {0 foo\x00help 2} 1
} "foo\x00help"

test listobj-9.1 {UpdateStringOfList} {
    string length [list foo\x00help]
} 8























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
test listobj-8.1 {SetListFromAny} {
    lindex {0 foo\x00help 2} 1
} "foo\x00help"

test listobj-9.1 {UpdateStringOfList} {
    string length [list foo\x00help]
} 8

# cleanup
::tcltest::cleanupTests
return












Changes to tests/llength.test.

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
















# Commands covered:  llength
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) llength.test 1.4 96/02/16 08:56:11



if {[string compare test [info procs test]] == 1} then {source defs}

test llength-1.1 {length of list} {
    llength {a b c d}
} 4
test llength-1.2 {length of list} {
    llength {a b c {a b {c d}} d}
} 5
test llength-1.3 {length of list} {
    llength {}
} 0

test llength-2.1 {error conditions} {
    list [catch {llength} msg] $msg
} {1 {wrong # args: should be "llength list"}}
test llength-2.2 {error conditions} {
    list [catch {llength 123 2} msg] $msg
} {1 {wrong # args: should be "llength list"}}
test llength-2.3 {error conditions} {
    list [catch {llength "a b c \{"} msg] $msg
} {1 {unmatched open brace in list}}
























>




>
|
>
>
|
<




















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# Commands covered:  llength
#
# 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: llength.test,v 1.1.2.5 1999/03/24 02:49:23 hershey Exp $

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


test llength-1.1 {length of list} {
    llength {a b c d}
} 4
test llength-1.2 {length of list} {
    llength {a b c {a b {c d}} d}
} 5
test llength-1.3 {length of list} {
    llength {}
} 0

test llength-2.1 {error conditions} {
    list [catch {llength} msg] $msg
} {1 {wrong # args: should be "llength list"}}
test llength-2.2 {error conditions} {
    list [catch {llength 123 2} msg] $msg
} {1 {wrong # args: should be "llength list"}}
test llength-2.3 {error conditions} {
    list [catch {llength "a b c \{"} msg] $msg
} {1 {unmatched open brace in list}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/load.test.

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
















# Commands covered:  load
#
# 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) 1995 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) load.test 1.19 96/11/30 16:05:18



if {[string compare test [info procs test]] == 1} then {source defs}

# Figure out what extension is used for shared libraries on this
# platform.

if {$tcl_platform(platform) == "macintosh"} {
    puts "can't run dynamic library tests on macintosh machines"
    return
}
set ext [info sharedlibextension]
set testDir [file join [file dirname [info nameofexecutable]] dltest]
if ![file readable [file join $testDir pkga$ext]] {
    puts "libraries in $testDir haven't been compiled: skipping tests"
    return
}


if [string match *pkga* [set alreadyLoaded [info loaded {}]]] {
    puts "load tests have already been run once:  skipping (can't rerun)"

    return


}






set alreadyTotalLoaded [info loaded]

test load-1.1 {basic errors} {
    list [catch {load} msg] $msg
} {1 {wrong # args: should be "load fileName ?packageName? ?interp?"}}
test load-1.2 {basic errors} {
    list [catch {load a b c d} msg] $msg
} {1 {wrong # args: should be "load fileName ?packageName? ?interp?"}}
test load-1.3 {basic errors} {
    list [catch {load a b foobar} msg] $msg
} {1 {couldn't find slave interpreter named "foobar"}}
test load-1.4 {basic errors} {
    list [catch {load {}} msg] $msg
} {1 {must specify either file name or package name}}
test load-1.5 {basic errors} {
    list [catch {load {} {}} msg] $msg
} {1 {must specify either file name or package name}}
test load-1.6 {basic errors} {
    list [catch {load {} Unknown} msg] $msg
} {1 {package "Unknown" isn't loaded statically}}

test load-2.1 {basic loading, with guess for package name} {

    load [file join $testDir pkga$ext]
    list [pkga_eq abc def] [info commands pkga_*]
} {0 {pkga_eq pkga_quote}}
interp create -safe child
test load-2.2 {loading into a safe interpreter, with package name conversion} {

    load [file join $testDir pkgb$ext] pKgB child
    list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
	    [catch {pkgb_sub 12 10} msg2] $msg2
} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
test load-2.3 {loading with no _Init procedure} {
    list [catch {load [file join $testDir pkgc$ext] foo} msg] $msg
} {1 {couldn't find procedure Foo_Init}}
test load-2.4 {loading with no _SafeInit procedure} {
    list [catch {load [file join $testDir pkga$ext] {} child} msg] $msg
} {1 {can't use package in a safe interpreter: no Pkga_SafeInit procedure}}

test load-3.1 {error in _Init procedure, same interpreter} {

    list [catch {load [file join $testDir pkge$ext] pkge} msg] $msg $errorInfo $errorCode

} {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
    while executing
"open non_existent"
    invoked from within


"load [file join $testDir pkge$ext] pkge"} {POSIX ENOENT {no such file or directory}}}
test load-3.2 {error in _Init procedure, slave interpreter} {

    catch {interp delete x}
    interp create x
    set errorCode foo
    set errorInfo bar
    set result [list [catch {load [file join $testDir pkge$ext] pkge x} msg] \
	    $msg $errorInfo $errorCode]
    interp delete x
    set result
} {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
    while executing
"open non_existent"


    invoked from within
"load [file join $testDir pkge$ext] pkge x"} {POSIX ENOENT {no such file or directory}}}

test load-4.1 {reloading package into same interpreter} {
    list [catch {load [file join $testDir pkga$ext] pkga} msg] $msg
} {0 {}}
test load-4.2 {reloading package into same interpreter} {
    list [catch {load [file join $testDir pkga$ext] pkgb} msg] $msg
} "1 {file \"[file join $testDir pkga$ext\"] is already loaded for package \"Pkga\"}"

test load-5.1 {file name not specified and no static package: pick default} {

    catch {interp delete x}
    interp create x
    load [file join $testDir pkga$ext] pkga
    load {} pkga x
    set result [info loaded x]
    interp delete x
    set result
} "{[file join $testDir pkga$ext] Pkga}"

# On some platforms, like SunOS 4.1.3, these tests can't be run because
# they cause the process to exit.

test load-6.1 {errors loading file} {nonPortable} {
    catch {load foo foo}
} {1}

if {[info command teststaticpkg] != ""} {
    test load-7.1 {Tcl_StaticPackage procedure} {
	set x "not loaded"
	teststaticpkg Test 1 0
	load {} Test
	load {} Test child
	list [set x] [child eval set x]
    } {loaded loaded}
    test load-7.2 {Tcl_StaticPackage procedure} {
	set x "not loaded"
	teststaticpkg Another 0 0
	load {} Another
	child eval {set x "not loaded"}
	list [catch {load {} Another child} msg] $msg [child eval set x] [set x]

    } {1 {can't use package in a safe interpreter: no Another_SafeInit procedure} {not loaded} loaded}
    test load-7.3 {Tcl_StaticPackage procedure} {
	set x "not loaded"
	teststaticpkg More 0 1
	load {} More
	set x
    } {not loaded}
    test load-7.4 {Tcl_StaticPackage procedure, redundant calls} {

	teststaticpkg Double 0 1
	teststaticpkg Double 0 1
	info loaded
    } "{{} Double} {{} More} {{} Another} {{} Test} {[file join $testDir pkge$ext] Pkge} {[file join $testDir pkgb$ext] Pkgb} {[file join $testDir pkga$ext] Pkga} $alreadyTotalLoaded"

    test load-8.1 {TclGetLoadedPackages procedure} {
	info loaded
    } "{{} Double} {{} More} {{} Another} {{} Test} {[file join $testDir pkge$ext] Pkge} {[file join $testDir pkgb$ext] Pkgb} {[file join $testDir pkga$ext] Pkga} $alreadyTotalLoaded"
    test load-8.2 {TclGetLoadedPackages procedure} {
	list [catch {info loaded gorp} msg] $msg
    } {1 {couldn't find slave interpreter named "gorp"}}
    test load-8.3 {TclGetLoadedPackages procedure} {
	list [info loaded {}] [info loaded child]
    } "{{{} Double} {{} More} {{} Another} {{} Test} {[file join $testDir pkga$ext] Pkga} $alreadyLoaded} {{{} Test} {[file join $testDir pkgb$ext] Pkgb}}"
    test load-8.4 {TclGetLoadedPackages procedure} {
	load [file join $testDir pkgb$ext] pkgb
	list [info loaded {}] [lsort [info commands pkgb_*]]
    } "{{[file join $testDir pkgb$ext] Pkgb} {{} Double} {{} More} {{} Another} {{} Test} {[file join $testDir pkga$ext] Pkga} $alreadyLoaded} {pkgb_sub pkgb_unsafe}"
    interp delete child
}























>




>
|
>
>
|
<






<
<
<
|
<
<



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



|


|


|

|
|


|


|



|
>




|
>




|


|



|
>
|
>




>
>

|
>











>
>



|


|



|
>












|




|






|




|
>

|





|
>





|


|

|
|


|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# Commands covered:  load
#
# 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) 1995 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: load.test,v 1.1.2.8 1999/03/26 19:14:02 hershey Exp $

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


# Figure out what extension is used for shared libraries on this
# platform.

if {$tcl_platform(platform) == "macintosh"} {
    puts "can't run dynamic library tests on macintosh machines"



    ::tcltest::cleanupTests


    return
}

# Tests require the existence of one of the DLLs in the dltest directory.
set ext [info sharedlibextension]

set testDir [file join [file dirname [info nameofexecutable]] dltest]
set x [file join $testDir pkga$ext]
set dll "[file tail $x]Required"
set ::tcltest::testConfig($dll) [file readable $x]

# Tests also require that this DLL has not already been loaded.
set loaded "[file tail $x]Loaded"
set alreadyLoaded [info loaded]
set ::tcltest::testConfig($loaded) \
	[expr {![string match *pkga* $alreadyLoaded]}]

set alreadyTotalLoaded [info loaded]

test load-1.1 {basic errors} [list $dll $loaded] {
    list [catch {load} msg] $msg
} {1 {wrong # args: should be "load fileName ?packageName? ?interp?"}}
test load-1.2 {basic errors} [list $dll $loaded] {
    list [catch {load a b c d} msg] $msg
} {1 {wrong # args: should be "load fileName ?packageName? ?interp?"}}
test load-1.3 {basic errors} [list $dll $loaded] {
    list [catch {load a b foobar} msg] $msg
} {1 {could not find interpreter "foobar"}}
test load-1.4 {basic errors} [list $dll $loaded] {
    list [catch {load {}} msg] $msg
} {1 {must specify either file name or package name}}
test load-1.5 {basic errors} [list $dll $loaded] {
    list [catch {load {} {}} msg] $msg
} {1 {must specify either file name or package name}}
test load-1.6 {basic errors} [list $dll $loaded] {
    list [catch {load {} Unknown} msg] $msg
} {1 {package "Unknown" isn't loaded statically}}

test load-2.1 {basic loading, with guess for package name} \
	[list $dll $loaded] {
    load [file join $testDir pkga$ext]
    list [pkga_eq abc def] [info commands pkga_*]
} {0 {pkga_eq pkga_quote}}
interp create -safe child
test load-2.2 {loading into a safe interpreter, with package name conversion} \
	[list $dll $loaded] {
    load [file join $testDir pkgb$ext] pKgB child
    list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
	    [catch {pkgb_sub 12 10} msg2] $msg2
} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
test load-2.3 {loading with no _Init procedure} [list $dll $loaded] {
    list [catch {load [file join $testDir pkgc$ext] foo} msg] $msg
} {1 {couldn't find procedure Foo_Init}}
test load-2.4 {loading with no _SafeInit procedure} [list $dll $loaded] {
    list [catch {load [file join $testDir pkga$ext] {} child} msg] $msg
} {1 {can't use package in a safe interpreter: no Pkga_SafeInit procedure}}

test load-3.1 {error in _Init procedure, same interpreter} \
	[list $dll $loaded] {
    list [catch {load [file join $testDir pkge$ext] pkge} msg] \
	    $msg $errorInfo $errorCode
} {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
    while executing
"open non_existent"
    invoked from within
"if 44 {open non_existent}"
    invoked from within
"load [file join $testDir pkge$ext] pkge"} {POSIX ENOENT {no such file or directory}}}
test load-3.2 {error in _Init procedure, slave interpreter} \
	[list $dll $loaded] {
    catch {interp delete x}
    interp create x
    set errorCode foo
    set errorInfo bar
    set result [list [catch {load [file join $testDir pkge$ext] pkge x} msg] \
	    $msg $errorInfo $errorCode]
    interp delete x
    set result
} {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
    while executing
"open non_existent"
    invoked from within
"if 44 {open non_existent}"
    invoked from within
"load [file join $testDir pkge$ext] pkge x"} {POSIX ENOENT {no such file or directory}}}

test load-4.1 {reloading package into same interpreter} [list $dll $loaded] {
    list [catch {load [file join $testDir pkga$ext] pkga} msg] $msg
} {0 {}}
test load-4.2 {reloading package into same interpreter} [list $dll $loaded] {
    list [catch {load [file join $testDir pkga$ext] pkgb} msg] $msg
} "1 {file \"[file join $testDir pkga$ext\"] is already loaded for package \"Pkga\"}"

test load-5.1 {file name not specified and no static package: pick default} \
	[list $dll $loaded] {
    catch {interp delete x}
    interp create x
    load [file join $testDir pkga$ext] pkga
    load {} pkga x
    set result [info loaded x]
    interp delete x
    set result
} "{[file join $testDir pkga$ext] Pkga}"

# On some platforms, like SunOS 4.1.3, these tests can't be run because
# they cause the process to exit.

test load-6.1 {errors loading file} [list $dll $loaded nonPortable] {
    catch {load foo foo}
} {1}

if {[info command teststaticpkg] != ""} {
    test load-7.1 {Tcl_StaticPackage procedure} [list $dll $loaded] {
	set x "not loaded"
	teststaticpkg Test 1 0
	load {} Test
	load {} Test child
	list [set x] [child eval set x]
    } {loaded loaded}
    test load-7.2 {Tcl_StaticPackage procedure} [list $dll $loaded] {
	set x "not loaded"
	teststaticpkg Another 0 0
	load {} Another
	child eval {set x "not loaded"}
	list [catch {load {} Another child} msg] $msg \
		[child eval set x] [set x]
    } {1 {can't use package in a safe interpreter: no Another_SafeInit procedure} {not loaded} loaded}
    test load-7.3 {Tcl_StaticPackage procedure} [list $dll $loaded] {
	set x "not loaded"
	teststaticpkg More 0 1
	load {} More
	set x
    } {not loaded}
    test load-7.4 {Tcl_StaticPackage procedure, redundant calls} \
	    [list $dll $loaded] {
	teststaticpkg Double 0 1
	teststaticpkg Double 0 1
	info loaded
    } "{{} Double} {{} More} {{} Another} {{} Test} {[file join $testDir pkge$ext] Pkge} {[file join $testDir pkgb$ext] Pkgb} {[file join $testDir pkga$ext] Pkga} $alreadyTotalLoaded"

    test load-8.1 {TclGetLoadedPackages procedure} [list $dll $loaded] {
	info loaded
    } "{{} Double} {{} More} {{} Another} {{} Test} {[file join $testDir pkge$ext] Pkge} {[file join $testDir pkgb$ext] Pkgb} {[file join $testDir pkga$ext] Pkga} $alreadyTotalLoaded"
    test load-8.2 {TclGetLoadedPackages procedure} [list $dll $loaded] {
	list [catch {info loaded gorp} msg] $msg
    } {1 {could not find interpreter "gorp"}}
    test load-8.3 {TclGetLoadedPackages procedure} [list $dll $loaded] {
	list [info loaded {}] [info loaded child]
    } "{{{} Double} {{} More} {{} Another} {{} Test} {[file join $testDir pkga$ext] Pkga} $alreadyLoaded} {{{} Test} {[file join $testDir pkgb$ext] Pkgb}}"
    test load-8.4 {TclGetLoadedPackages procedure} [list $dll $loaded] {
	load [file join $testDir pkgb$ext] pkgb
	list [info loaded {}] [lsort [info commands pkgb_*]]
    } "{{[file join $testDir pkgb$ext] Pkgb} {{} Double} {{} More} {{} Another} {{} Test} {[file join $testDir pkga$ext] Pkga} $alreadyLoaded} {pkgb_sub pkgb_unsafe}"
    interp delete child
}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/lrange.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  lrange
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) lrange.test 1.12 97/06/23 18:19:25



if {[string compare test [info procs test]] == 1} then {source defs}

test lrange-1.1 {range of list elements} {
    lrange {a b c d} 1 2
} {b c}
test lrange-1.2 {range of list elements} {
    lrange {a {bcd e {f g {}}} l14 l15 d} 1 1
} {{bcd e {f g {}}}}








>




>
|
>
>
|
<







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
# Commands covered:  lrange
#
# 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: lrange.test,v 1.1.2.5 1999/03/24 02:49:25 hershey Exp $

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


test lrange-1.1 {range of list elements} {
    lrange {a b c d} 1 2
} {b c}
test lrange-1.2 {range of list elements} {
    lrange {a {bcd e {f g {}}} l14 l15 d} 1 1
} {{bcd e {f g {}}}}
77
78
79
80
81
82
83
















} {1 {bad index "enigma": must be integer or "end"}}
test lrange-2.5 {error conditions} {
    list [catch {lrange "a \{b c" 3 4} msg] $msg
} {1 {unmatched open brace in list}}
test lrange-2.6 {error conditions} {
    list [catch {lrange "a b c \{ d e" 1 4} msg] $msg
} {1 {unmatched open brace in list}}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
} {1 {bad index "enigma": must be integer or "end"}}
test lrange-2.5 {error conditions} {
    list [catch {lrange "a \{b c" 3 4} msg] $msg
} {1 {unmatched open brace in list}}
test lrange-2.6 {error conditions} {
    list [catch {lrange "a b c \{ d e" 1 4} msg] $msg
} {1 {unmatched open brace in list}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/lreplace.test.

1
2
3
4
5
6
7
8

9
10
11
12
13
14

15

16
17
18
19
20
21
22
# Commands covered:  lreplace
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) lreplace.test 1.16 97/10/29 16:32:39


if {[string compare test [info procs test]] == 1} then {source defs}


test lreplace-1.1 {lreplace command} {
    lreplace {1 2 3 4 5} 0 0 a
} {a 2 3 4 5}
test lreplace-1.2 {lreplace command} {
    lreplace {1 2 3 4 5} 1 1 a
} {1 a 3 4 5}








>




|

>
|
>







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
# Commands covered:  lreplace
#
# 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: lreplace.test,v 1.1.2.5 1999/03/24 02:49:25 hershey Exp $

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

test lreplace-1.1 {lreplace command} {
    lreplace {1 2 3 4 5} 0 0 a
} {a 2 3 4 5}
test lreplace-1.2 {lreplace command} {
    lreplace {1 2 3 4 5} 1 1 a
} {1 a 3 4 5}
124
125
126
127
128
129
130

131














    proc p {} {
        lreplace "a b c" 1 1 "x y"
        return "a b c"
    }
    p
} "a b c"


catch {unset foo}





















>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    proc p {} {
        lreplace "a b c" 1 1 "x y"
        return "a b c"
    }
    p
} "a b c"

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












Changes to tests/lsearch.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  lsearch
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) lsearch.test 1.7 97/04/30 13:23:53



if {[string compare test [info procs test]] == 1} then {source defs}

set x {abcd bbcd 123 234 345}
test lsearch-1.1 {lsearch command} {
    lsearch $x 123
} 2
test lsearch-1.2 {lsearch command} {
    lsearch $x 3456








>




>
|
>
>
|
<







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
# Commands covered:  lsearch
#
# 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: lsearch.test,v 1.1.2.6 1999/03/24 02:49:26 hershey Exp $

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


set x {abcd bbcd 123 234 345}
test lsearch-1.1 {lsearch command} {
    lsearch $x 123
} 2
test lsearch-1.2 {lsearch command} {
    lsearch $x 3456
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    lsearch -exact {foo bar cat} bart
} -1
test lsearch-2.5 {search modes} {
    lsearch -exact {foo bar cat} bar
} 1
test lsearch-2.6 {search modes} {
    list [catch {lsearch -regexp {xyz bbcc *bc*} *bc*} msg] $msg
} {1 {couldn't compile regular expression pattern: ?+* follows nothing}}
test lsearch-2.7 {search modes} {
    lsearch -regexp {b.x ^bc xy bcx} ^bc
} 3
test lsearch-2.8 {search modes} {
    lsearch -glob {xyz bbcc *bc*} *bc*
} 1
test lsearch-2.9 {search modes} {







|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    lsearch -exact {foo bar cat} bart
} -1
test lsearch-2.5 {search modes} {
    lsearch -exact {foo bar cat} bar
} 1
test lsearch-2.6 {search modes} {
    list [catch {lsearch -regexp {xyz bbcc *bc*} *bc*} msg] $msg
} {1 {couldn't compile regular expression pattern: quantifier operand invalid}}
test lsearch-2.7 {search modes} {
    lsearch -regexp {b.x ^bc xy bcx} ^bc
} 3
test lsearch-2.8 {search modes} {
    lsearch -glob {xyz bbcc *bc*} *bc*
} 1
test lsearch-2.9 {search modes} {
80
81
82
83
84
85
86
















} 2
test lsearch-4.2 {binary data} {
    set x one
    append x \x00
    append x two
    lsearch -exact [list foo one\000two bar] $x
} 1























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
} 2
test lsearch-4.2 {binary data} {
    set x one
    append x \x00
    append x two
    lsearch -exact [list foo one\000two bar] $x
} 1

# cleanup
::tcltest::cleanupTests
return












Changes to tests/macFCmd.test.

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
















# This file tests the tclfCmd.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 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) macFCmd.test 1.3 97/06/23 18:24:10
#

if {$tcl_platform(platform) != "macintosh"} {
    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

catch {file delete -force foo.dir}
file mkdir foo.dir
if {[catch {file attributes foo.dir -readonly 1}]} {
    set testConfig(fileSharing) 0
    set testConfig(notFileSharing) 1
} else {
    set testConfig(fileSharing) 1
    set testConfig(notFileSharing) 0
}
file delete -force foo.dir

test macFCmd-1.1 {GetFileFinderAttributes - no file} {
    catch {file delete -force foo.file}
    list [catch {file attributes foo.file -creator} msg] $msg
} {1 {couldn't get attributes for file ":foo.file": no such file or directory}}
test macFCmd-1.2 {GetFileFinderAttributes - creator} {
    catch {file delete -force foo.file}
    catch {close [open foo.file w]}
    list [catch {file attributes foo.file -creator} msg] $msg [file delete -force foo.file]

} {0 {MPW } {}}
test macFCmd-1.3 {GetFileFinderAttributes - type} {
    catch {file delete -force foo.file}
    catch {close [open foo.file w]}
    list [catch {file attributes foo.file -type} msg] $msg [file delete -force foo.file]

} {0 TEXT {}}
test macFCmd-1.4 {GetFileFinderAttributes - not hidden} {
    catch {file delete -force foo.file}
    catch {close [open foo.file w]}
    list [catch {file attributes foo.file -hidden} msg] $msg [file delete -force foo.file]

} {0 0 {}}
test macFCmd-1.5 {GetFileFinderAttributes - hidden} {
    catch {file delete -force foo.file}
    catch {close [open foo.file w]}
    file attributes foo.file -hidden 1
    list [catch {file attributes foo.file -hidden} msg] $msg [file delete -force foo.file]

} {0 1 {}}
test macFCmd-1.6 {GetFileFinderAttributes - folder creator} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -creator} msg] $msg [file delete -force foo.dir]

} {0 Fldr {}}
test macFCmd-1.7 {GetFileFinderAttributes - folder type} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -type} msg] $msg [file delete -force foo.dir]

} {0 Fldr {}}
test macFCmd-1.8 {GetFileFinderAttributes - folder hidden} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -hidden} msg] $msg [file delete -force foo.dir]

} {0 0 {}}

test macFCmd-2.1 {GetFileReadOnly - bad file} {
    catch {file delete -force foo.file}
    list [catch {file attributes foo.file -readonly} msg] $msg
} {1 {couldn't get attributes for file ":foo.file": no such file or directory}}
test macFCmd-2.2 {GetFileReadOnly - file not read only} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -readonly} msg] $msg [file delete -force foo.file]

} {0 0 {}}
test macFCmd-2.3 {GetFileReadOnly - file read only} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    file attributes foo.file -readonly 1
    list [catch {file attributes foo.file -readonly} msg] $msg [file delete -force foo.file]

} {0 1 {}}
test macFCmd-2.4 {GetFileReadOnly - directory not read only} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -readonly} msg] $msg [file delete -force foo.dir]

} {0 0 {}}
test macFCmd-2.5 {GetFileReadOnly - directory read only} {fileSharing} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    file attributes foo.dir -readonly 1
    list [catch {file attributes foo.dir -readonly} msg] $msg [file delete -force foo.dir]

} {0 1 {}}

test macFCmd-3.1 {SetFileFinderAttributes - bad file} {
    catch {file delete -force foo.file}
    list [catch {file attributes foo.file -creator FOOO} msg] $msg
} {1 {couldn't set attributes for file ":foo.file": no such file or directory}}
test macFCmd-3.2 {SetFileFinderAttributes - creator} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -creator FOOO} msg] $msg [file attributes foo.file -creator] [file delete -force foo.file]

} {0 {} FOOO {}}
test macFCmd-3.3 {SetFileFinderAttributes - bad creator} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -creator 0} msg] $msg [file delete -force foo.file]

} {1 {expected Macintosh OS type but got "0"} {}}
test macFCmd-3.4 {SetFileFinderAttributes - hidden} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -hidden 1} msg] $msg [file attributes foo.file -hidden] [file delete -force foo.file]

} {0 {} 1 {}}
test macFCmd-3.5 {SetFileFinderAttributes - type} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -type FOOO} msg] $msg [file attributes foo.file -type] [file delete -force foo.file]

} {0 {} FOOO {}}
test macFCmd-3.6 {SetFileFinderAttributes - bad type} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -type 0} msg] $msg [file delete -force foo.file]

} {1 {expected Macintosh OS type but got "0"} {}}
test macFCmd-3.7 {SetFileFinderAttributes - directory} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -creator FOOO} msg] $msg [file delete -force foo.dir]

} {1 {cannot set -creator: ":foo.dir" is a directory} {}}

test macFCmd-4.1 {SetFileReadOnly - bad file} {
    catch {file delete -force foo.file}
    list [catch {file attributes foo.file -readonly 1} msg] $msg
} {1 {couldn't set attributes for file ":foo.file": no such file or directory}}
test macFCmd-4.2 {SetFileReadOnly - file not readonly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -readonly 0} msg] $msg [file attributes foo.file -readonly] [file delete -force foo.file]

} {0 {} 0 {}}
test macFCmd-4.3 {SetFileReadOnly - file readonly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -readonly 1} msg] $msg [file attributes foo.file -readonly] [file delete -force foo.file]

} {0 {} 1 {}}
test macFCmd-4.4 {SetFileReadOnly - directory not readonly} {fileSharing} {

    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -readonly 0} msg] $msg [file attributes foo.dir -readonly] [file delete -force foo.dir]

} {0 {} 0 {}}
test macFCmd-4.5 {SetFileReadOnly - directory not readonly} {notFileSharing} {







    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -readonly 0} msg] $msg [file delete -force foo.dir]
} {1 {cannot set a directory to read-only when File Sharing is turned off} {}}
test macFCmd-4.6 {SetFileReadOnly - directory readonly} {fileSharing} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -readonly 1} msg] $msg [file attributes foo.dir -readonly] [file delete -force foo.dir]
} {0 {} 1 {}}
test macFCmd-4.7 {SetFileReadOnly - directory readonly} {notFileSharing} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -readonly 1} msg] $msg [file delete -force foo.dir]

} {1 {cannot set a directory to read-only when File Sharing is turned off} {}}























>




|


|
|


<
<



|
|

|
|



|



|


|
>

|


|
>

|


|
>

|



|
>

|


|
>

|


|
>

|


|
>


|



|


|
>

|



|
>

|


|
>

|



|
>


|



|


|
>

|


|
>

|


|
>

|


|
>

|


|
>

|


|
>


|



|


|
>

|


|
>

|
>


|
>

|
>
>
>
>
>
>
>


|
<
<
<
<
|

|


|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# This file tests the tclfCmd.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 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: macFCmd.test,v 1.1.2.5 1999/03/24 02:49:26 hershey Exp $
#

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



catch {file delete -force foo.dir}
file mkdir foo.dir
if {[catch {file attributes foo.dir -readonly 1}]} {
    set ::tcltest::testConfig(fileSharing) 0
    set ::tcltest::testConfig(notFileSharing) 1
} else {
    set ::tcltest::testConfig(fileSharing) 1
    set ::tcltest::testConfig(notFileSharing) 0
}
file delete -force foo.dir

test macFCmd-1.1 {GetFileFinderAttributes - no file} {macOnly} {
    catch {file delete -force foo.file}
    list [catch {file attributes foo.file -creator} msg] $msg
} {1 {couldn't get attributes for file ":foo.file": no such file or directory}}
test macFCmd-1.2 {GetFileFinderAttributes - creator} {macOnly} {
    catch {file delete -force foo.file}
    catch {close [open foo.file w]}
    list [catch {file attributes foo.file -creator} msg] $msg \
	    [file delete -force foo.file]
} {0 {MPW } {}}
test macFCmd-1.3 {GetFileFinderAttributes - type} {macOnly} {
    catch {file delete -force foo.file}
    catch {close [open foo.file w]}
    list [catch {file attributes foo.file -type} msg] $msg \
	    [file delete -force foo.file]
} {0 TEXT {}}
test macFCmd-1.4 {GetFileFinderAttributes - not hidden} {macOnly} {
    catch {file delete -force foo.file}
    catch {close [open foo.file w]}
    list [catch {file attributes foo.file -hidden} msg] $msg \
	    [file delete -force foo.file]
} {0 0 {}}
test macFCmd-1.5 {GetFileFinderAttributes - hidden} {macOnly} {
    catch {file delete -force foo.file}
    catch {close [open foo.file w]}
    file attributes foo.file -hidden 1
    list [catch {file attributes foo.file -hidden} msg] $msg \
	    [file delete -force foo.file]
} {0 1 {}}
test macFCmd-1.6 {GetFileFinderAttributes - folder creator} {macOnly} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -creator} msg] $msg \
	    [file delete -force foo.dir]
} {0 Fldr {}}
test macFCmd-1.7 {GetFileFinderAttributes - folder type} {macOnly} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -type} msg] $msg \
	    [file delete -force foo.dir]
} {0 Fldr {}}
test macFCmd-1.8 {GetFileFinderAttributes - folder hidden} {macOnly} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -hidden} msg] $msg \
	    [file delete -force foo.dir]
} {0 0 {}}

test macFCmd-2.1 {GetFileReadOnly - bad file} {macOnly} {
    catch {file delete -force foo.file}
    list [catch {file attributes foo.file -readonly} msg] $msg
} {1 {couldn't get attributes for file ":foo.file": no such file or directory}}
test macFCmd-2.2 {GetFileReadOnly - file not read only} {macOnly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -readonly} msg] $msg \
	    [file delete -force foo.file]
} {0 0 {}}
test macFCmd-2.3 {GetFileReadOnly - file read only} {macOnly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    file attributes foo.file -readonly 1
    list [catch {file attributes foo.file -readonly} msg] $msg \
	    [file delete -force foo.file]
} {0 1 {}}
test macFCmd-2.4 {GetFileReadOnly - directory not read only} {macOnly} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -readonly} msg] $msg \
	    [file delete -force foo.dir]
} {0 0 {}}
test macFCmd-2.5 {GetFileReadOnly - directory read only} {macOnly fileSharing} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    file attributes foo.dir -readonly 1
    list [catch {file attributes foo.dir -readonly} msg] $msg \
	    [file delete -force foo.dir]
} {0 1 {}}

test macFCmd-3.1 {SetFileFinderAttributes - bad file} {macOnly} {
    catch {file delete -force foo.file}
    list [catch {file attributes foo.file -creator FOOO} msg] $msg
} {1 {couldn't set attributes for file ":foo.file": no such file or directory}}
test macFCmd-3.2 {SetFileFinderAttributes - creator} {macOnly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -creator FOOO} msg] $msg \
	    [file attributes foo.file -creator] [file delete -force foo.file]
} {0 {} FOOO {}}
test macFCmd-3.3 {SetFileFinderAttributes - bad creator} {macOnly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -creator 0} msg] $msg \
	    [file delete -force foo.file]
} {1 {expected Macintosh OS type but got "0"} {}}
test macFCmd-3.4 {SetFileFinderAttributes - hidden} {macOnly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -hidden 1} msg] $msg \
	    [file attributes foo.file -hidden] [file delete -force foo.file]
} {0 {} 1 {}}
test macFCmd-3.5 {SetFileFinderAttributes - type} {macOnly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -type FOOO} msg] $msg \
	    [file attributes foo.file -type] [file delete -force foo.file]
} {0 {} FOOO {}}
test macFCmd-3.6 {SetFileFinderAttributes - bad type} {macOnly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -type 0} msg] $msg \
	    [file delete -force foo.file]
} {1 {expected Macintosh OS type but got "0"} {}}
test macFCmd-3.7 {SetFileFinderAttributes - directory} {macOnly} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -creator FOOO} msg] \
	    $msg [file delete -force foo.dir]
} {1 {cannot set -creator: ":foo.dir" is a directory} {}}

test macFCmd-4.1 {SetFileReadOnly - bad file} {macOnly} {
    catch {file delete -force foo.file}
    list [catch {file attributes foo.file -readonly 1} msg] $msg
} {1 {couldn't set attributes for file ":foo.file": no such file or directory}}
test macFCmd-4.2 {SetFileReadOnly - file not readonly} {macOnly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -readonly 0} msg] \
	    $msg [file attributes foo.file -readonly] [file delete -force foo.file]
} {0 {} 0 {}}
test macFCmd-4.3 {SetFileReadOnly - file readonly} {macOnly} {
    catch {file delete -force foo.file}
    close [open foo.file w]
    list [catch {file attributes foo.file -readonly 1} msg] \
	    $msg [file attributes foo.file -readonly] [file delete -force foo.file]
} {0 {} 1 {}}
test macFCmd-4.4 {SetFileReadOnly - directory not readonly} \
	{macOnly fileSharing} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -readonly 0} msg] \
	    $msg [file attributes foo.dir -readonly] [file delete -force foo.dir]
} {0 {} 0 {}}
test macFCmd-4.5 {SetFileReadOnly - directory not readonly} \
	{macOnly notFileSharing} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -readonly 0} msg] $msg \
	    [file delete -force foo.dir]
} {1 {cannot set a directory to read-only when File Sharing is turned off} {}}
test macFCmd-4.6 {SetFileReadOnly - directory readonly} {macOnly fileSharing} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -readonly 1} msg] $msg \




	    [file attributes foo.dir -readonly] [file delete -force foo.dir]
} {0 {} 1 {}}
test macFCmd-4.7 {SetFileReadOnly - directory readonly} {macOnly notFileSharing} {
    catch {file delete -force foo.dir}
    file mkdir foo.dir
    list [catch {file attributes foo.dir -readonly 1} msg] $msg \
	    [file delete -force foo.dir]
} {1 {cannot set a directory to read-only when File Sharing is turned off} {}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/misc.test.

1
2
3
4
5
6
7
8
9

10
11
12
13

14


15
16
17
18
19
20
21
22
23
# Commands covered:  various
#
# This file contains a collection of miscellaneous Tcl tests that
# don't fit naturally in any of the other test files.  Many of these
# tests are pathological cases that caused bugs in earlier Tcl
# releases.
#
# Copyright (c) 1992-1993 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) misc.test 1.12 97/07/02 16:41:34



if {[string compare test [info procs test]] == 1} then {source defs}

test misc-1.1 {error in variable ref. in command in array reference} {
    proc tstProc {} {
	global a
    
	set tst $a([winfo name $zz])
	# this is a bogus comment









>




>
|
>
>
|
<







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
# Commands covered:  various
#
# This file contains a collection of miscellaneous Tcl tests that
# don't fit naturally in any of the other test files.  Many of these
# tests are pathological cases that caused bugs in earlier Tcl
# releases.
#
# Copyright (c) 1992-1993 The Regents of the University of California.
# 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: misc.test,v 1.1.2.5 1999/03/24 02:49:26 hershey Exp $

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


test misc-1.1 {error in variable ref. in command in array reference} {
    proc tstProc {} {
	global a
    
	set tst $a([winfo name $zz])
	# this is a bogus comment
44
45
46
47
48
49
50






51















	# this is a bogus comment
	# this is a bogus comment
	# this is a bogus comment
	# this is a bogus comment
    "
    set msg {}
    list [catch tstProc msg] $msg $errorInfo






} {1 {missing close-bracket or close-brace} missing\ close-bracket\ or\ close-brace\n\ \ \ \ while\ compiling\n\"set\ tst\ \$a(\[winfo\ name\ \$\{zz)\"\n\ \ \ \ (compiling\ body\ of\ proc\ \"tstProc\",\ line\ 4)\n\ \ \ \ invoked\ from\ within\n\"tstProc\"}






















>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
	# this is a bogus comment
	# this is a bogus comment
	# this is a bogus comment
	# this is a bogus comment
    "
    set msg {}
    list [catch tstProc msg] $msg $errorInfo
} {1 {missing close-brace for variable name} {missing close-brace for variable name
    while compiling
"set tst $a([winfo name "
    (compiling body of proc "tstProc", line 4)
    invoked from within
"tstProc"}}

# cleanup
::tcltest::cleanupTests
return












Added tests/msgcat.test.





























































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# Commands covered: ::msgcat::mc ::msgcat::mclocale
#                   ::msgcat::mcpreferences ::msgcat::mcload
#                   ::msgcat::mcset ::msgcat::mcunknown
#
# This file contains a collection of tests for the msgcat script library.
# Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1998 Mark Harrison.
# 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: msgcat.test,v 1.1.2.6 1999/03/24 02:49:27 hershey Exp $

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

if {[catch {package require msgcat 1.0}]} {
    if {[info exist msgcat1]} {
	catch {puts "Cannot load msgcat 1.0 package"}
	return
    } else {
	catch {puts "Running msgcat 1.0 tests in slave interp"}
	set interp [interp create msgcat1]
	$interp eval [list set msgcat1 "running"]
	$interp eval [list source [info script]]
	interp delete $interp
	return
    }
}

set oldlocale [::msgcat::mclocale]

#
# Test the various permutations of mclocale
# and mcpreferences.
#

test msgcat-1.1 {::msgcat::mclocale default} {
    ::msgcat::mclocale
} {c}
test msgcat-1.2 {::msgcat::mcpreferences, single element} {
    ::msgcat::mcpreferences
} {c}
test msgcat-1.3 {::msgcat::mclocale, single element} {
    ::msgcat::mclocale en
} {en}
test msgcat-1.4 {::msgcat::mclocale, single element} {
    ::msgcat::mclocale
} {en}
test msgcat-1.5 {::msgcat::mcpreferences, single element} {
    ::msgcat::mcpreferences
} {en}
test msgcat-1.6 {::msgcat::mclocale, two elements} {
    ::msgcat::mclocale en_US
} {en_us}
test msgcat-1.7 {::msgcat::mclocale, two elements} {
    ::msgcat::mclocale en_US
    ::msgcat::mclocale
} {en_us}
test msgcat-1.8 {::msgcat::mcpreferences, two elements} {
    ::msgcat::mcpreferences
} {en_us en}
test msgcat-1.9 {::msgcat::mclocale, three elements} {
    ::msgcat::mclocale en_US_funky
} {en_us_funky}
test msgcat-1.10 {::msgcat::mclocale, three elements} {
    ::msgcat::mclocale
} {en_us_funky}
test msgcat-1.11 {::msgcat::mcpreferences, three elements} {
    ::msgcat::mcpreferences
} {en_us_funky en_us en}

#
# Test mcset and mcc, ensuring that namespace partitioning
# is working.
#

test msgcat-2.1 {::msgcat::mcset, global scope} {
    ::msgcat::mcset  foo_BAR text1 text2
} {text2}
test msgcat-2.2 {::msgcat::mcset, global scope, default} {
    ::msgcat::mcset  foo_BAR text3
} {text3}
test msgcat-2.2 {::msgcat::mcset, namespace overlap} {
    namespace eval bar {::msgcat::mcset  foo_BAR con1 con1bar}
    namespace eval baz {::msgcat::mcset  foo_BAR con1 con1baz}
} {con1baz}
test msgcat-2.3 {::msgcat::mcset, namespace overlap} {
    ::msgcat::mclocale foo_BAR
    namespace eval bar {::msgcat::mc con1}
} {con1bar}
test msgcat-2.4 {::msgcat::mcset, namespace overlap} {
    ::msgcat::mclocale foo_BAR
    namespace eval baz {::msgcat::mc con1}
} {con1baz}

#
# Test mcset and mc, ensuring that more specific locales
# (e.g. "en_UK") will search less specific locales
# (e.g. "en") for translation strings.
#
# Do this for the 12 permutations of
#     locales: {foo foo_BAR foo_BAR_baz}
#     strings: {ov1 ov2 ov3 ov4}
#     locale foo         defines ov1, ov2, ov3
#     locale foo_BAR     defines      ov2, ov3
#     locale foo_BAR_BAZ defines           ov3
#     (ov4 is defined in none)
# So,
#     ov3 should be resolved in foo, foo_BAR, foo_BAR_baz
#     ov2 should be resolved in foo, foo_BAR
#     ov2 should resolve to foo_BAR in foo_BAR_baz
#     ov1 should be resolved in foo
#     ov1 should resolve to foo in foo_BAR, foo_BAR_baz
#     ov4 should be resolved in none, and call mcunknown
#

test msgcat-3.1 {::msgcat::mcset, overlap} {
    ::msgcat::mcset foo ov1 ov1_foo
    ::msgcat::mcset foo ov2 ov2_foo
    ::msgcat::mcset foo ov3 ov3_foo
    ::msgcat::mcset foo_BAR ov2 ov2_foo_BAR
    ::msgcat::mcset foo_BAR ov3 ov3_foo_BAR
    ::msgcat::mcset foo_BAR_baz ov3 ov3_foo_BAR_baz
} {ov3_foo_BAR_baz}
# top level, locale foo
test msgcat-3.2 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo
    ::msgcat::mc ov1
} {ov1_foo}
test msgcat-3.3 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo
    ::msgcat::mc ov2
} {ov2_foo}
test msgcat-3.4 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo
    ::msgcat::mc ov3
} {ov3_foo}
test msgcat-3.5 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo
    ::msgcat::mc ov4
} {ov4}
# second level, locale foo_BAR
test msgcat-3.6 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo_BAR
    ::msgcat::mc ov1
} {ov1_foo}
test msgcat-3.7 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo_BAR
    ::msgcat::mc ov2
} {ov2_foo_BAR}
test msgcat-3.8 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo_BAR
    ::msgcat::mc ov3
} {ov3_foo_BAR}
test msgcat-3.9 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo_BAR
    ::msgcat::mc ov4
} {ov4}
# third level, locale foo_BAR_baz
test msgcat-3.10 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo_BAR_baz
    ::msgcat::mc ov1
} {ov1_foo}
test msgcat-3.11 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo_BAR_baz
    ::msgcat::mc ov2
} {ov2_foo_BAR}
test msgcat-3.12 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo_BAR_baz
    ::msgcat::mc ov3
} {ov3_foo_BAR_baz}
test msgcat-3.13 {::msgcat::mcset, overlap} {
    ::msgcat::mclocale foo_BAR_baz
    ::msgcat::mc ov4
} {ov4}

#
# Test mcunknown, first the default operation
# and then with an overridden definition.
#

test msgcat-4.1 {::msgcat::mcunknown, default} {
    ::msgcat::mcset foo unk1 "unknown 1"
} {unknown 1}
test msgcat-4.2 {::msgcat::mcunknown, default} {
    ::msgcat::mclocale foo
    ::msgcat::mc unk1
} {unknown 1}
test msgcat-4.3 {::msgcat::mcunknown, default} {
    ::msgcat::mclocale foo
    ::msgcat::mc unk2
} {unk2}
test msgcat-4.4 {::msgcat::mcunknown, overridden} {
    rename ::msgcat::mcunknown oldproc
    proc ::msgcat::mcunknown {dom s} {
        return "unknown:$dom:$s"
    }
    ::msgcat::mclocale foo
    set result [::msgcat::mc unk1]
    rename ::msgcat::mcunknown {}
    rename oldproc ::msgcat::mcunknown
    set result
} {unknown 1}
test msgcat-4.5 {::msgcat::mcunknown, overridden} {
    rename ::msgcat::mcunknown oldproc
    proc ::msgcat::mcunknown {dom s} {
        return "unknown:$dom:$s"
    }
    ::msgcat::mclocale foo
    set result [::msgcat::mc unk2]
    rename ::msgcat::mcunknown {}
    rename oldproc ::msgcat::mcunknown
    set result
} {unknown:foo:unk2}
test msgcat-4.6 {::msgcat::mcunknown, uplevel context} {
    rename ::msgcat::mcunknown oldproc
    proc ::msgcat::mcunknown {dom s} {
        return "unknown:$dom:$s:[info level]"
    }
    ::msgcat::mclocale foo
    set result [::msgcat::mc unk2]
    rename ::msgcat::mcunknown {}
    rename oldproc ::msgcat::mcunknown
    set result
} {unknown:foo:unk2:1}
    

#
# Test mcload.  Need to set up an environment for
# these tests by creating a temporary directory and
# message files.
#

set locales {en en_US en_US_funky}

catch {file mkdir msgdir}
foreach l $locales {
    set fd [open [string tolower [file join msgdir $l.msg]] w]
    puts $fd "::msgcat::mcset $l abc abc-$l"
    close $fd
}

test msgcat-5.1 {::msgcat::mcload} {
    ::msgcat::mclocale en
    ::msgcat::mcload msgdir
} {1}
test msgcat-5.2 {::msgcat::mcload} {
    ::msgcat::mclocale en_US
    ::msgcat::mcload msgdir
} {2}
test msgcat-5.3 {::msgcat::mcload} {
    ::msgcat::mclocale en_US_funky
    ::msgcat::mcload msgdir
} {3}

# Even though en_US_notexist does not exist,
# en_US and en should be loaded.

test msgcat-5.4 {::msgcat::mcload} {
    ::msgcat::mclocale en_US_notexist
    ::msgcat::mcload msgdir
} {2}
test msgcat-5.5 {::msgcat::mcload} {
    ::msgcat::mclocale no_FI_notexist
    ::msgcat::mcload msgdir
} {0}
test msgcat-5.6 {::msgcat::mcload} {
    ::msgcat::mclocale en
    ::msgcat::mc abc
} {abc-en}
test msgcat-5.7 {::msgcat::mcload} {
    ::msgcat::mclocale en_US
    ::msgcat::mc abc
} {abc-en_US}
test msgcat-5.8 {::msgcat::mcload} {
    ::msgcat::mclocale en_US_funky
    ::msgcat::mc abc
} {abc-en_US_funky}
test msgcat-5.9 {::msgcat::mcload} {
    rename ::msgcat::mcunknown oldproc
    proc ::msgcat::mcunknown {dom s} {
        return "unknown:$dom:$s"
    }
    ::msgcat::mclocale no_FI_notexist
    set result [::msgcat::mc abc]
    rename ::msgcat::mcunknown {}
    rename oldproc ::msgcat::mcunknown
    set result
} {unknown:no_fi_notexist:abc}

# cleanup
foreach l $locales {
    file delete [string tolower [file join msgdir $l.msg]]
}

# Clean out the msg catalogs
::msgcat::mclocale $oldlocale
file delete msgdir

::tcltest::cleanupTests
return












Changes to tests/namespace-old.test.

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
# Functionality covered: this file contains slightly modified versions of
# the original tests written by Mike McLennan of Lucent Technologies for
# the procedures in tclNamesp.c that implement Tcl's basic support for
# namespaces. Other namespace-related tests appear in namespace.test
# and variable.test.
#
# 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) 1997 Lucent Technologies

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) namespace-old.test 1.5 97/06/20 14:51:17


if {[string compare test [info procs test]] == 1} then {source defs}


# Clear out any namespaces called test_ns_*
catch {eval namespace delete [namespace children :: test_ns_*]}

test namespace-old-1.1 {usage for "namespace" command} {
    list [catch {namespace} msg] $msg
} {1 {wrong # args: should be "namespace subcommand ?arg ...?"}}











>




|

>
|
>







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
# Functionality covered: this file contains slightly modified versions of
# the original tests written by Mike McLennan of Lucent Technologies for
# the procedures in tclNamesp.c that implement Tcl's basic support for
# namespaces. Other namespace-related tests appear in namespace.test
# and variable.test.
#
# 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) 1997 Lucent Technologies
# 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: namespace-old.test,v 1.1.2.5 1999/03/24 02:49:27 hershey Exp $

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

# Clear out any namespaces called test_ns_*
catch {eval namespace delete [namespace children :: test_ns_*]}

test namespace-old-1.1 {usage for "namespace" command} {
    list [catch {namespace} msg] $msg
} {1 {wrong # args: should be "namespace subcommand ?arg ...?"}}
838
839
840
841
842
843
844
















catch {unset trigger2}
catch {unset sval}
catch {unset msg}
catch {unset x}
catch {unset test_ns_var_global}
catch {unset cmd}
eval namespace delete [namespace children :: test_ns_*]























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
catch {unset trigger2}
catch {unset sval}
catch {unset msg}
catch {unset x}
catch {unset test_ns_var_global}
catch {unset cmd}
eval namespace delete [namespace children :: test_ns_*]

# cleanup
::tcltest::cleanupTests
return












Changes to tests/namespace.test.

1
2
3
4
5
6
7
8

9
10
11
12
13
14

15

16
17
18
19
20
21
22
# Functionality covered: this file contains a collection of tests for the
# procedures in tclNamesp.c that implement Tcl's basic support for
# namespaces. Other namespace-related tests appear in variable.test.
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) namespace.test 1.15 97/07/30 15:26:42


if {[string compare test [info procs test]] == 1} then {source defs}


# Clear out any namespaces called test_ns_*
catch {eval namespace delete [namespace children :: test_ns_*]}

test namespace-1.1 {TclInitNamespaces, GetNamespaceFromObj, NamespaceChildrenCmd} {
    namespace children :: test_ns_*
} {}








>




|

>
|
>







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
# Functionality covered: this file contains a collection of tests for the
# procedures in tclNamesp.c that implement Tcl's basic support for
# namespaces. Other namespace-related tests appear in variable.test.
#
# 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: namespace.test,v 1.1.2.5 1999/03/24 02:49:28 hershey Exp $

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

# Clear out any namespaces called test_ns_*
catch {eval namespace delete [namespace children :: test_ns_*]}

test namespace-1.1 {TclInitNamespaces, GetNamespaceFromObj, NamespaceChildrenCmd} {
    namespace children :: test_ns_*
} {}
218
219
220
221
222
223
224

















225
226
227
228
229
230
231
} {1 {can't import command "cmd1": already exists}}
test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} {
    namespace eval test_ns_import {
        namespace import -force ::test_ns_export::*
        cmd1 555
    }
} {cmd1: 555}


















test namespace-10.1 {Tcl_ForgetImport, check for valid namespaces} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    list [catch {namespace forget xyzzy::*} msg] $msg
} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
test namespace-10.2 {Tcl_ForgetImport, ignores patterns that don't match} {
    namespace eval test_ns_export {







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







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
} {1 {can't import command "cmd1": already exists}}
test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} {
    namespace eval test_ns_import {
        namespace import -force ::test_ns_export::*
        cmd1 555
    }
} {cmd1: 555}
test namespace-9.7 {Tcl_Import, links are preserved if cmd is redefined} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    namespace eval test_ns_export {
        namespace export cmd1
        proc cmd1 {args} {return "cmd1: $args"}
    }
    namespace eval test_ns_import {
        namespace import -force ::test_ns_export::*
    }
    list [test_ns_import::cmd1 a b c] \
         [test_ns_export::cmd1 d e f] \
         [proc test_ns_export::cmd1 {args} {return "new1: $args"}] \
         [namespace origin test_ns_import::cmd1] \
         [namespace origin test_ns_export::cmd1] \
         [test_ns_import::cmd1 g h i] \
         [test_ns_export::cmd1 j k l]
} {{cmd1: a b c} {cmd1: d e f} {} ::test_ns_export::cmd1 ::test_ns_export::cmd1 {new1: g h i} {new1: j k l}}

test namespace-10.1 {Tcl_ForgetImport, check for valid namespaces} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    list [catch {namespace forget xyzzy::*} msg] $msg
} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
test namespace-10.2 {Tcl_ForgetImport, ignores patterns that don't match} {
    namespace eval test_ns_export {
1069
1070
1071
1072
1073
1074
1075

1076
1077
1078
1079
1080














test namespace-38.1 {UpdateStringOfNsName} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    ;# Tcl_NamespaceObjCmd calls UpdateStringOfNsName to get subcmd name
    list [namespace eval {} {namespace current}] \
         [namespace eval {} {namespace current}]
} {:: ::}


catch {rename cmd1 {}}
catch {unset l}
catch {unset msg}
catch {unset trigger}
eval namespace delete [namespace children :: test_ns_*]





















>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
test namespace-38.1 {UpdateStringOfNsName} {
    catch {eval namespace delete [namespace children :: test_ns_*]}
    ;# Tcl_NamespaceObjCmd calls UpdateStringOfNsName to get subcmd name
    list [namespace eval {} {namespace current}] \
         [namespace eval {} {namespace current}]
} {:: ::}

# cleanup
catch {rename cmd1 {}}
catch {unset l}
catch {unset msg}
catch {unset trigger}
eval namespace delete [namespace children :: test_ns_*]
::tcltest::cleanupTests
return












Changes to tests/obj.test.

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
# Functionality covered: this file contains a collection of tests for the
# procedures in tclObj.c that implement Tcl's basic type support and the
# type managers for the types boolean, double, and integer.
#
# Sourcing this file into Tcl runs the tests and generates output for
# errors. No output means no errors were found.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# @(#) obj.test 1.12 97/10/31 17:23:23




if {[info commands testobj] == {}} {
    puts "This application hasn't been compiled with the \"testobj\""
    puts "command, so I can't test the Tcl type and object support."

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} {
    set r 1
    foreach {t} {list boolean cmdName bytecode string int double} {
        set first [string first $t [testobj types]]
        set r [expr {$r && ($first != -1)}]
    }
    set result $r








>




>
|
>
>
>




>



<
<







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
# Functionality covered: this file contains a collection of tests for the
# procedures in tclObj.c that implement Tcl's basic type support and the
# type managers for the types boolean, double, and integer.
#
# Sourcing this file into Tcl runs the tests and generates output for
# errors. No output means no errors were found.
#
# Copyright (c) 1995-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: obj.test,v 1.1.2.6 1999/03/26 19:14:03 hershey Exp $

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

if {[info commands testobj] == {}} {
    puts "This application hasn't been compiled with the \"testobj\""
    puts "command, so I can't test the Tcl type and object support."
    ::tcltest::cleanupTests
    return
}



test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} {
    set r 1
    foreach {t} {list boolean cmdName bytecode string int double} {
        set first [string first $t [testobj types]]
        set r [expr {$r && ($first != -1)}]
    }
    set result $r
79
80
81
82
83
84
85
























86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210






211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
















    lappend result [testobj newobj 1]
    lappend result [testobj duplicate 1 2]    
    lappend result [testintobj get 2]
    lappend result [testobj refcount 1]
    lappend result [testobj refcount 2]
} {{} {} {} {} 2 3}

























test obj-7.1 {Tcl_GetStringFromObj, return existing string rep} {
    set result ""
    lappend result [testintobj set 1 47]
    lappend result [testintobj get 1]
} {47 47}
test obj-7.2 {Tcl_GetStringFromObj, "empty string" object} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [teststringobj append 1 abc -1]
    lappend result [teststringobj get 1]
} {{} abc abc}
test obj-7.3 {Tcl_GetStringFromObj, returns string internal rep (DString)} {
    set result ""
    lappend result [teststringobj set 1 xyz]
    lappend result [teststringobj append 1 abc -1]
    lappend result [teststringobj get 1]
} {xyz xyzabc xyzabc}
test obj-7.4 {Tcl_GetStringFromObj, recompute string rep from internal rep} {
    set result ""
    lappend result [testintobj set 1 77]
    lappend result [testintobj mult10 1]
    lappend result [teststringobj get 1]
} {77 770 770}

test obj-8.1 {Tcl_NewBooleanObj} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testbooleanobj set 1 0]
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 0 boolean 2}

test obj-9.1 {Tcl_SetBooleanObj, existing "empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testobj newobj 1]
    lappend result [testbooleanobj set 1 0]  ;# makes existing obj boolean
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} {} 0 boolean 2}
test obj-9.2 {Tcl_SetBooleanObj, existing non-"empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testintobj set 1 98765]
    lappend result [testbooleanobj set 1 1]  ;# makes existing obj boolean
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 98765 1 boolean 2}

test obj-10.1 {Tcl_GetBooleanFromObj, existing boolean object} {
    set result ""
    lappend result [testbooleanobj set 1 1]
    lappend result [testbooleanobj not 1]    ;# gets existing boolean rep
} {1 0}
test obj-10.2 {Tcl_GetBooleanFromObj, convert to boolean} {
    set result ""
    lappend result [testintobj set 1 47]
    lappend result [testbooleanobj not 1]    ;# must convert to bool
    lappend result [testobj type 1]
} {47 0 boolean}
test obj-10.3 {Tcl_GetBooleanFromObj, error converting to boolean} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} {abc 1 {expected boolean value but got "abc"}}
test obj-10.4 {Tcl_GetBooleanFromObj, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} {{} 1 {expected boolean value but got ""}}

test obj-11.1 {DupBooleanInternalRep} {
    set result ""
    lappend result [testbooleanobj set 1 1]
    lappend result [testobj duplicate 1 2]   ;# uses DupBooleanInternalRep
    lappend result [testbooleanobj get 2]
} {1 1 1}

test obj-12.1 {SetBooleanFromAny, int to boolean special case} {
    set result ""
    lappend result [testintobj set 1 1234]
    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
    lappend result [testobj type 1]
} {1234 0 boolean}
test obj-12.2 {SetBooleanFromAny, double to boolean special case} {
    set result ""
    lappend result [testdoubleobj set 1 3.14159]
    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
    lappend result [testobj type 1]
} {3.14159 0 boolean}
test obj-12.3 {SetBooleanFromAny, special case strings representing booleans} {
    set result ""
    foreach s {yes no true false on off} {
        teststringobj set 1 $s
        lappend result [testbooleanobj not 1]
    }
    lappend result [testobj type 1]
} {0 1 0 1 0 1 boolean}
test obj-12.4 {SetBooleanFromAny, recompute string rep then parse it} {
    set result ""
    lappend result [testintobj set 1 456]
    lappend result [testintobj div10 1]
    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
    lappend result [testobj type 1]
} {456 45 0 boolean}
test obj-12.5 {SetBooleanFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} {abc 1 {expected boolean value but got "abc"}}
test obj-12.6 {SetBooleanFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 x1.0]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} {x1.0 1 {expected boolean value but got "x1.0"}}
test obj-12.7 {SetBooleanFromAny, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} {{} 1 {expected boolean value but got ""}}







test obj-13.1 {UpdateStringOfBoolean} {
    set result ""
    lappend result [testbooleanobj set 1 0]
    lappend result [testbooleanobj not 1]
    lappend result [testbooleanobj get 1]    ;# must update string rep
} {0 1 1}

test obj-14.1 {Tcl_NewDoubleObj} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testdoubleobj set 1 3.1459]
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 3.1459 double 2}

test obj-15.1 {Tcl_SetDoubleObj, existing "empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testobj newobj 1]
    lappend result [testdoubleobj set 1 0.123]  ;# makes existing obj boolean
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} {} 0.123 double 2}
test obj-15.2 {Tcl_SetDoubleObj, existing non-"empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testintobj set 1 98765]
    lappend result [testdoubleobj set 1 27.56]  ;# makes existing obj double
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 98765 27.56 double 2}

test obj-16.1 {Tcl_GetDoubleFromObj, existing double object} {
    set result ""
    lappend result [testdoubleobj set 1 16.1]
    lappend result [testdoubleobj mult10 1]   ;# gets existing double rep
} {16.1 161.0}
test obj-16.2 {Tcl_GetDoubleFromObj, convert to double} {
    set result ""
    lappend result [testintobj set 1 477]
    lappend result [testdoubleobj div10 1]    ;# must convert to bool
    lappend result [testobj type 1]
} {477 47.7 double}
test obj-16.3 {Tcl_GetDoubleFromObj, error converting to double} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testdoubleobj mult10 1} msg]
    lappend result $msg
} {abc 1 {expected floating-point number but got "abc"}}
test obj-16.4 {Tcl_GetDoubleFromObj, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testdoubleobj div10 1} msg]
    lappend result $msg
} {{} 1 {expected floating-point number but got ""}}

test obj-17.1 {DupDoubleInternalRep} {
    set result ""
    lappend result [testdoubleobj set 1 17.1]
    lappend result [testobj duplicate 1 2]      ;# uses DupDoubleInternalRep
    lappend result [testdoubleobj get 2]
} {17.1 17.1 17.1}

test obj-18.1 {SetDoubleFromAny, int to double special case} {
    set result ""
    lappend result [testintobj set 1 1234]
    lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
    lappend result [testobj type 1]
} {1234 12340.0 double}
test obj-18.2 {SetDoubleFromAny, boolean to double special case} {
    set result ""
    lappend result [testbooleanobj set 1 1]
    lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
    lappend result [testobj type 1]
} {1 10.0 double}
test obj-18.3 {SetDoubleFromAny, recompute string rep then parse it} {
    set result ""
    lappend result [testintobj set 1 456]
    lappend result [testintobj div10 1]
    lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
    lappend result [testobj type 1]
} {456 45 450.0 double}
test obj-18.4 {SetDoubleFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testdoubleobj mult10 1} msg]
    lappend result $msg
} {abc 1 {expected floating-point number but got "abc"}}
test obj-18.5 {SetDoubleFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 x1.0]
    lappend result [catch {testdoubleobj mult10 1} msg]
    lappend result $msg
} {x1.0 1 {expected floating-point number but got "x1.0"}}
test obj-18.6 {SetDoubleFromAny, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testdoubleobj div10 1} msg]
    lappend result $msg
} {{} 1 {expected floating-point number but got ""}}

test obj-19.1 {UpdateStringOfDouble} {
    set result ""
    lappend result [testdoubleobj set 1 3.14159]
    lappend result [testdoubleobj mult10 1]
    lappend result [testdoubleobj get 1]   ;# must update string rep
} {3.14159 31.4159 31.4159}

test obj-20.1 {Tcl_NewIntObj} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testintobj set 1 55]
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 55 int 2}

test obj-21.1 {Tcl_SetIntObj, existing "empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testobj newobj 1]
    lappend result [testintobj set 1 77]  ;# makes existing obj int
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} {} 77 int 2}
test obj-21.2 {Tcl_SetIntObj, existing non-"empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testdoubleobj set 1 12.34]
    lappend result [testintobj set 1 77]  ;# makes existing obj int
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 12.34 77 int 2}

test obj-22.1 {Tcl_GetIntFromObj, existing int object} {
    set result ""
    lappend result [testintobj set 1 22]
    lappend result [testintobj mult10 1]   ;# gets existing int rep
} {22 220}
test obj-22.2 {Tcl_GetIntFromObj, convert to int} {
    set result ""
    lappend result [testintobj set 1 477]
    lappend result [testintobj div10 1]    ;# must convert to bool
    lappend result [testobj type 1]
} {477 47 int}
test obj-22.3 {Tcl_GetIntFromObj, error converting to int} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testintobj mult10 1} msg]
    lappend result $msg
} {abc 1 {expected integer but got "abc"}}
test obj-22.4 {Tcl_GetIntFromObj, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testintobj div10 1} msg]
    lappend result $msg
} {{} 1 {expected integer but got ""}}
test obj-22.5 {Tcl_GetIntFromObj, integer too large to represent as non-long error} {nonPortable} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [testintobj inttoobigtest 1]
} {{} 1}

test obj-23.1 {DupIntInternalRep} {
    set result ""
    lappend result [testintobj set 1 23]
    lappend result [testobj duplicate 1 2]    ;# uses DupIntInternalRep
    lappend result [testintobj get 2]
} {23 23 23}

test obj-24.1 {SetIntFromAny, int to int special case} {
    set result ""
    lappend result [testintobj set 1 1234]
    lappend result [testintobj mult10 1]  ;# converts with SetIntFromAny
    lappend result [testobj type 1]
} {1234 12340 int}
test obj-24.2 {SetIntFromAny, boolean to int special case} {
    set result ""
    lappend result [testbooleanobj set 1 1]
    lappend result [testintobj mult10 1]  ;# converts with SetIntFromAny
    lappend result [testobj type 1]
} {1 10 int}
test obj-24.3 {SetIntFromAny, recompute string rep then parse it} {
    set result ""
    lappend result [testintobj set 1 456]
    lappend result [testintobj div10 1]
    lappend result [testintobj mult10 1]  ;# converts with SetIntFromAny
    lappend result [testobj type 1]
} {456 45 450 int}
test obj-24.4 {SetIntFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testintobj mult10 1} msg]
    lappend result $msg
} {abc 1 {expected integer but got "abc"}}
test obj-24.5 {SetIntFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 x17]
    lappend result [catch {testintobj mult10 1} msg]
    lappend result $msg
} {x17 1 {expected integer but got "x17"}}
test obj-24.6 {SetIntFromAny, integer too large} {nonPortable} {
    set result ""
    lappend result [teststringobj set 1 123456789012345678901]
    lappend result [catch {testintobj mult10 1} msg]
    lappend result $msg
} {123456789012345678901 1 {integer value too large to represent}}
test obj-24.7 {SetIntFromAny, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testintobj div10 1} msg]
    lappend result $msg
} {{} 1 {expected integer but got ""}}

test obj-25.1 {UpdateStringOfInt} {
    set result ""
    lappend result [testintobj set 1 512]
    lappend result [testintobj mult10 1]
    lappend result [testintobj get 1]       ;# must update string rep
} {512 5120 5120}

test obj-26.1 {Tcl_NewLongObj} {
    set result ""
    lappend result [testobj freeallvars]
    testintobj setmaxlong 1
    lappend result [testintobj ismaxlong 1]
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 1 int 1}

test obj-27.1 {Tcl_SetLongObj, existing "empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testobj newobj 1]
    lappend result [testintobj setlong 1 77]  ;# makes existing obj long int
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} {} 77 int 2}
test obj-27.2 {Tcl_SetLongObj, existing non-"empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testdoubleobj set 1 12.34]
    lappend result [testintobj setlong 1 77]  ;# makes existing obj long int
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 12.34 77 int 2}

test obj-28.1 {Tcl_GetLongFromObj, existing long integer object} {
    set result ""
    lappend result [testintobj setlong 1 22]
    lappend result [testintobj mult10 1]   ;# gets existing long int rep
} {22 220}
test obj-28.2 {Tcl_GetLongFromObj, convert to long} {
    set result ""
    lappend result [testintobj setlong 1 477]
    lappend result [testintobj div10 1]    ;# must convert to bool
    lappend result [testobj type 1]
} {477 47 int}
test obj-28.3 {Tcl_GetLongFromObj, error converting to long integer} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
    lappend result $msg
} {abc 1 {expected integer but got "abc"}}
test obj-28.4 {Tcl_GetLongFromObj, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
    lappend result $msg
} {{} 1 {expected integer but got ""}}

test obj-29.1 {Ref counting and object deletion, simple types} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testintobj set 1 1024]
    lappend result [testobj assign 1 2]     ;# vars 1 and 2 share the int obj
    lappend result [testobj type 2]
    lappend result [testobj refcount 1]
    lappend result [testobj refcount 2]
    lappend result [testbooleanobj set 2 0] ;# must copy on write, now 2 objs
    lappend result [testobj type 2]
    lappend result [testobj refcount 1]
    lappend result [testobj refcount 2]
} {{} 1024 1024 int 4 4 0 boolean 3 2}

testobj freeallvars























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




|





|





|






|







|







|








|




|





|





|






|






|





|





|







|






|





|





|





>
>
>
>
>
>

|






|







|







|








|




|





|





|






|






|





|





|






|





|





|






|






|







|







|








|




|





|





|





|





|






|





|





|






|





|





|





|






|






|








|







|








|




|





|





|






|














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
    lappend result [testobj newobj 1]
    lappend result [testobj duplicate 1 2]    
    lappend result [testintobj get 2]
    lappend result [testobj refcount 1]
    lappend result [testobj refcount 2]
} {{} {} {} {} 2 3}

test obj-7.1 {Tcl_GetString, return existing string rep} {
    set result ""
    lappend result [testintobj set 1 47]
    lappend result [testintobj get2 1]
} {47 47}
test obj-7.2 {Tcl_GetString, "empty string" object} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [teststringobj append 1 abc -1]
    lappend result [teststringobj get2 1]
} {{} abc abc}
test obj-7.3 {Tcl_GetString, returns string internal rep (DString)} {
    set result ""
    lappend result [teststringobj set 1 xyz]
    lappend result [teststringobj append 1 abc -1]
    lappend result [teststringobj get2 1]
} {xyz xyzabc xyzabc}
test obj-7.4 {Tcl_GetString, recompute string rep from internal rep} {
    set result ""
    lappend result [testintobj set 1 77]
    lappend result [testintobj mult10 1]
    lappend result [teststringobj get2 1]
} {77 770 770}

test obj-8.1 {Tcl_GetStringFromObj, return existing string rep} {
    set result ""
    lappend result [testintobj set 1 47]
    lappend result [testintobj get 1]
} {47 47}
test obj-8.2 {Tcl_GetStringFromObj, "empty string" object} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [teststringobj append 1 abc -1]
    lappend result [teststringobj get 1]
} {{} abc abc}
test obj-8.3 {Tcl_GetStringFromObj, returns string internal rep (DString)} {
    set result ""
    lappend result [teststringobj set 1 xyz]
    lappend result [teststringobj append 1 abc -1]
    lappend result [teststringobj get 1]
} {xyz xyzabc xyzabc}
test obj-8.4 {Tcl_GetStringFromObj, recompute string rep from internal rep} {
    set result ""
    lappend result [testintobj set 1 77]
    lappend result [testintobj mult10 1]
    lappend result [teststringobj get 1]
} {77 770 770}

test obj-9.1 {Tcl_NewBooleanObj} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testbooleanobj set 1 0]
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 0 boolean 2}

test obj-10.1 {Tcl_SetBooleanObj, existing "empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testobj newobj 1]
    lappend result [testbooleanobj set 1 0]  ;# makes existing obj boolean
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} {} 0 boolean 2}
test obj-10.2 {Tcl_SetBooleanObj, existing non-"empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testintobj set 1 98765]
    lappend result [testbooleanobj set 1 1]  ;# makes existing obj boolean
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 98765 1 boolean 2}

test obj-11.1 {Tcl_GetBooleanFromObj, existing boolean object} {
    set result ""
    lappend result [testbooleanobj set 1 1]
    lappend result [testbooleanobj not 1]    ;# gets existing boolean rep
} {1 0}
test obj-11.2 {Tcl_GetBooleanFromObj, convert to boolean} {
    set result ""
    lappend result [testintobj set 1 47]
    lappend result [testbooleanobj not 1]    ;# must convert to bool
    lappend result [testobj type 1]
} {47 0 boolean}
test obj-11.3 {Tcl_GetBooleanFromObj, error converting to boolean} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} {abc 1 {expected boolean value but got "abc"}}
test obj-11.4 {Tcl_GetBooleanFromObj, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} {{} 1 {expected boolean value but got ""}}

test obj-12.1 {DupBooleanInternalRep} {
    set result ""
    lappend result [testbooleanobj set 1 1]
    lappend result [testobj duplicate 1 2]   ;# uses DupBooleanInternalRep
    lappend result [testbooleanobj get 2]
} {1 1 1}

test obj-13.1 {SetBooleanFromAny, int to boolean special case} {
    set result ""
    lappend result [testintobj set 1 1234]
    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
    lappend result [testobj type 1]
} {1234 0 boolean}
test obj-13.2 {SetBooleanFromAny, double to boolean special case} {
    set result ""
    lappend result [testdoubleobj set 1 3.14159]
    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
    lappend result [testobj type 1]
} {3.14159 0 boolean}
test obj-13.3 {SetBooleanFromAny, special case strings representing booleans} {
    set result ""
    foreach s {yes no true false on off} {
        teststringobj set 1 $s
        lappend result [testbooleanobj not 1]
    }
    lappend result [testobj type 1]
} {0 1 0 1 0 1 boolean}
test obj-13.4 {SetBooleanFromAny, recompute string rep then parse it} {
    set result ""
    lappend result [testintobj set 1 456]
    lappend result [testintobj div10 1]
    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
    lappend result [testobj type 1]
} {456 45 0 boolean}
test obj-13.5 {SetBooleanFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} {abc 1 {expected boolean value but got "abc"}}
test obj-13.6 {SetBooleanFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 x1.0]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} {x1.0 1 {expected boolean value but got "x1.0"}}
test obj-13.7 {SetBooleanFromAny, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} {{} 1 {expected boolean value but got ""}}
test obj-13.8 {SetBooleanFromAny, unicode strings} {
    set result ""
    lappend result [teststringobj set 1 1\u7777]
    lappend result [catch {testbooleanobj not 1} msg]
    lappend result $msg
} "1\u7777 1 {expected boolean value but got \"1\u7777\"}"

test obj-14.1 {UpdateStringOfBoolean} {
    set result ""
    lappend result [testbooleanobj set 1 0]
    lappend result [testbooleanobj not 1]
    lappend result [testbooleanobj get 1]    ;# must update string rep
} {0 1 1}

test obj-15.1 {Tcl_NewDoubleObj} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testdoubleobj set 1 3.1459]
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 3.1459 double 2}

test obj-16.1 {Tcl_SetDoubleObj, existing "empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testobj newobj 1]
    lappend result [testdoubleobj set 1 0.123]  ;# makes existing obj boolean
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} {} 0.123 double 2}
test obj-16.2 {Tcl_SetDoubleObj, existing non-"empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testintobj set 1 98765]
    lappend result [testdoubleobj set 1 27.56]  ;# makes existing obj double
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 98765 27.56 double 2}

test obj-17.1 {Tcl_GetDoubleFromObj, existing double object} {
    set result ""
    lappend result [testdoubleobj set 1 16.1]
    lappend result [testdoubleobj mult10 1]   ;# gets existing double rep
} {16.1 161.0}
test obj-17.2 {Tcl_GetDoubleFromObj, convert to double} {
    set result ""
    lappend result [testintobj set 1 477]
    lappend result [testdoubleobj div10 1]    ;# must convert to bool
    lappend result [testobj type 1]
} {477 47.7 double}
test obj-17.3 {Tcl_GetDoubleFromObj, error converting to double} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testdoubleobj mult10 1} msg]
    lappend result $msg
} {abc 1 {expected floating-point number but got "abc"}}
test obj-17.4 {Tcl_GetDoubleFromObj, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testdoubleobj div10 1} msg]
    lappend result $msg
} {{} 1 {expected floating-point number but got ""}}

test obj-18.1 {DupDoubleInternalRep} {
    set result ""
    lappend result [testdoubleobj set 1 17.1]
    lappend result [testobj duplicate 1 2]      ;# uses DupDoubleInternalRep
    lappend result [testdoubleobj get 2]
} {17.1 17.1 17.1}

test obj-19.1 {SetDoubleFromAny, int to double special case} {
    set result ""
    lappend result [testintobj set 1 1234]
    lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
    lappend result [testobj type 1]
} {1234 12340.0 double}
test obj-19.2 {SetDoubleFromAny, boolean to double special case} {
    set result ""
    lappend result [testbooleanobj set 1 1]
    lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
    lappend result [testobj type 1]
} {1 10.0 double}
test obj-19.3 {SetDoubleFromAny, recompute string rep then parse it} {
    set result ""
    lappend result [testintobj set 1 456]
    lappend result [testintobj div10 1]
    lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
    lappend result [testobj type 1]
} {456 45 450.0 double}
test obj-19.4 {SetDoubleFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testdoubleobj mult10 1} msg]
    lappend result $msg
} {abc 1 {expected floating-point number but got "abc"}}
test obj-19.5 {SetDoubleFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 x1.0]
    lappend result [catch {testdoubleobj mult10 1} msg]
    lappend result $msg
} {x1.0 1 {expected floating-point number but got "x1.0"}}
test obj-19.6 {SetDoubleFromAny, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testdoubleobj div10 1} msg]
    lappend result $msg
} {{} 1 {expected floating-point number but got ""}}

test obj-20.1 {UpdateStringOfDouble} {
    set result ""
    lappend result [testdoubleobj set 1 3.14159]
    lappend result [testdoubleobj mult10 1]
    lappend result [testdoubleobj get 1]   ;# must update string rep
} {3.14159 31.4159 31.4159}

test obj-21.1 {Tcl_NewIntObj} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testintobj set 1 55]
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 55 int 2}

test obj-22.1 {Tcl_SetIntObj, existing "empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testobj newobj 1]
    lappend result [testintobj set 1 77]  ;# makes existing obj int
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} {} 77 int 2}
test obj-22.2 {Tcl_SetIntObj, existing non-"empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testdoubleobj set 1 12.34]
    lappend result [testintobj set 1 77]  ;# makes existing obj int
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 12.34 77 int 2}

test obj-23.1 {Tcl_GetIntFromObj, existing int object} {
    set result ""
    lappend result [testintobj set 1 22]
    lappend result [testintobj mult10 1]   ;# gets existing int rep
} {22 220}
test obj-23.2 {Tcl_GetIntFromObj, convert to int} {
    set result ""
    lappend result [testintobj set 1 477]
    lappend result [testintobj div10 1]    ;# must convert to bool
    lappend result [testobj type 1]
} {477 47 int}
test obj-23.3 {Tcl_GetIntFromObj, error converting to int} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testintobj mult10 1} msg]
    lappend result $msg
} {abc 1 {expected integer but got "abc"}}
test obj-23.4 {Tcl_GetIntFromObj, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testintobj div10 1} msg]
    lappend result $msg
} {{} 1 {expected integer but got ""}}
test obj-23.5 {Tcl_GetIntFromObj, integer too large to represent as non-long error} {nonPortable} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [testintobj inttoobigtest 1]
} {{} 1}

test obj-24.1 {DupIntInternalRep} {
    set result ""
    lappend result [testintobj set 1 23]
    lappend result [testobj duplicate 1 2]    ;# uses DupIntInternalRep
    lappend result [testintobj get 2]
} {23 23 23}

test obj-25.1 {SetIntFromAny, int to int special case} {
    set result ""
    lappend result [testintobj set 1 1234]
    lappend result [testintobj mult10 1]  ;# converts with SetIntFromAny
    lappend result [testobj type 1]
} {1234 12340 int}
test obj-25.2 {SetIntFromAny, boolean to int special case} {
    set result ""
    lappend result [testbooleanobj set 1 1]
    lappend result [testintobj mult10 1]  ;# converts with SetIntFromAny
    lappend result [testobj type 1]
} {1 10 int}
test obj-25.3 {SetIntFromAny, recompute string rep then parse it} {
    set result ""
    lappend result [testintobj set 1 456]
    lappend result [testintobj div10 1]
    lappend result [testintobj mult10 1]  ;# converts with SetIntFromAny
    lappend result [testobj type 1]
} {456 45 450 int}
test obj-25.4 {SetIntFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testintobj mult10 1} msg]
    lappend result $msg
} {abc 1 {expected integer but got "abc"}}
test obj-25.5 {SetIntFromAny, error parsing string} {
    set result ""
    lappend result [teststringobj set 1 x17]
    lappend result [catch {testintobj mult10 1} msg]
    lappend result $msg
} {x17 1 {expected integer but got "x17"}}
test obj-25.6 {SetIntFromAny, integer too large} {nonPortable} {
    set result ""
    lappend result [teststringobj set 1 123456789012345678901]
    lappend result [catch {testintobj mult10 1} msg]
    lappend result $msg
} {123456789012345678901 1 {integer value too large to represent}}
test obj-25.7 {SetIntFromAny, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testintobj div10 1} msg]
    lappend result $msg
} {{} 1 {expected integer but got ""}}

test obj-26.1 {UpdateStringOfInt} {
    set result ""
    lappend result [testintobj set 1 512]
    lappend result [testintobj mult10 1]
    lappend result [testintobj get 1]       ;# must update string rep
} {512 5120 5120}

test obj-27.1 {Tcl_NewLongObj} {
    set result ""
    lappend result [testobj freeallvars]
    testintobj setmaxlong 1
    lappend result [testintobj ismaxlong 1]
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 1 int 1}

test obj-28.1 {Tcl_SetLongObj, existing "empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testobj newobj 1]
    lappend result [testintobj setlong 1 77]  ;# makes existing obj long int
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} {} 77 int 2}
test obj-28.2 {Tcl_SetLongObj, existing non-"empty string" object} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testdoubleobj set 1 12.34]
    lappend result [testintobj setlong 1 77]  ;# makes existing obj long int
    lappend result [testobj type 1]
    lappend result [testobj refcount 1]
} {{} 12.34 77 int 2}

test obj-29.1 {Tcl_GetLongFromObj, existing long integer object} {
    set result ""
    lappend result [testintobj setlong 1 22]
    lappend result [testintobj mult10 1]   ;# gets existing long int rep
} {22 220}
test obj-29.2 {Tcl_GetLongFromObj, convert to long} {
    set result ""
    lappend result [testintobj setlong 1 477]
    lappend result [testintobj div10 1]    ;# must convert to bool
    lappend result [testobj type 1]
} {477 47 int}
test obj-29.3 {Tcl_GetLongFromObj, error converting to long integer} {
    set result ""
    lappend result [teststringobj set 1 abc]
    lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
    lappend result $msg
} {abc 1 {expected integer but got "abc"}}
test obj-29.4 {Tcl_GetLongFromObj, error converting from "empty string"} {
    set result ""
    lappend result [testobj newobj 1]
    lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
    lappend result $msg
} {{} 1 {expected integer but got ""}}

test obj-30.1 {Ref counting and object deletion, simple types} {
    set result ""
    lappend result [testobj freeallvars]
    lappend result [testintobj set 1 1024]
    lappend result [testobj assign 1 2]     ;# vars 1 and 2 share the int obj
    lappend result [testobj type 2]
    lappend result [testobj refcount 1]
    lappend result [testobj refcount 2]
    lappend result [testbooleanobj set 2 0] ;# must copy on write, now 2 objs
    lappend result [testobj type 2]
    lappend result [testobj refcount 1]
    lappend result [testobj refcount 2]
} {{} 1024 1024 int 4 4 0 boolean 3 2}

testobj freeallvars

# cleanup
::tcltest::cleanupTests
return












Changes to tests/opt.test.

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
# Package covered:  opt0.1/optparse.tcl
#
# 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-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.
#

# SCCS: @(#) opt.test 1.2 97/08/20 15:57:18



if {[string compare test [info procs test]] == 1} then {source defs}

# the package we are going to test
package require opt 0.1

# we are using implementation specifics to test the package


#### functions tests #####

set n $::tcl::OptDescN
|







>




>
|
>
>
|
<


|







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
# Package covered:  opt1.0/optparse.tcl
#
# 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-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: opt.test,v 1.1.2.5 1999/03/24 02:49:29 hershey Exp $

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


# the package we are going to test
package require opt 0.4.1

# we are using implementation specifics to test the package


#### functions tests #####

set n $::tcl::OptDescN
248
249
250
251
252
253
254
255
































test opt-10.9 {medium size overall test} {
    optTest save tst -m --
} {save 1 tst 7 1}

test opt-10.10 {medium size overall test} {
    list [catch {optTest save tst foo} msg] [lindex [split $msg "\n"] 0]
} {1 {too many arguments (unexpected argument(s): foo), usage:}}









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
test opt-10.9 {medium size overall test} {
    optTest save tst -m --
} {save 1 tst 7 1}

test opt-10.10 {medium size overall test} {
    list [catch {optTest save tst foo} msg] [lindex [split $msg "\n"] 0]
} {1 {too many arguments (unexpected argument(s): foo), usage:}}

test opt-11.1 {too many args test 2} {
    set key [::tcl::OptKeyRegister {-foo}]
    list [catch {::tcl::OptKeyParse $key {-foo blah}} msg] $msg\
	    [::tcl::OptKeyDelete $key]
} {1 {too many arguments (unexpected argument(s): blah), usage:
    Var/FlagName Type     Value   Help
    ------------ ----     -----   ----
    ( -help                       gives this help )
    -foo         boolflag (false) } {}}
test opt-11.2 {default value for args} {
    set args {}
    set key [::tcl::OptKeyRegister {{args -list {a b c} "args..."}}]
    ::tcl::OptKeyParse $key {}
    ::tcl::OptKeyDelete $key
    set args
} {a b c}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/osa.test.

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
















# Commands covered:  AppleScript
#
# 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 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) osa.test 1.4 97/06/23 18:24:24


if {[string compare test [info procs test]] == 1} then {source defs}

# This command only runs on the Macintosh, only run the test if we
# can load the command
if {$tcl_platform(platform) != "macintosh"} {
    puts "skipping: Mac only tests..."
    return
}

if {[info commands AppleScript] == ""} {
    puts "couldn't find AppleScript command..."
    return
}

test osa-1.1 {Tcl_OSAComponentCmd} {
    list [catch AppleScript msg] $msg
} {1 {wrong # args: should be "AppleScript option ?arg ...?"}}
test osa-1.2 {Tcl_OSAComponentCmd} {
    list [catch {AppleScript x} msg] $msg
} {1 {bad option "x": should be compile, decompile, delete, execute, info, load, run or store}}

test osa-1.3 {TclOSACompileCmd} {
    list [catch {AppleScript compile} msg] $msg
} {1 {wrong # args: should be "AppleScript compile ?options? code"}}























>




|

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


|



|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# Commands covered:  AppleScript
#
# 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 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: osa.test,v 1.1.2.5 1999/03/24 02:49:30 hershey Exp $

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






# Only run the test if we can load the AppleScript command
set ::tcltest::testConfig(appleScript) [expr {[info commands AppleScript] != ""}]




test osa-1.1 {Tcl_OSAComponentCmd} {macOnly appleScript} {
    list [catch AppleScript msg] $msg
} {1 {wrong # args: should be "AppleScript option ?arg ...?"}}
test osa-1.2 {Tcl_OSAComponentCmd} {macOnly appleScript} {
    list [catch {AppleScript x} msg] $msg
} {1 {bad option "x": should be compile, decompile, delete, execute, info, load, run or store}}

test osa-1.3 {TclOSACompileCmd} {macOnly appleScript} {
    list [catch {AppleScript compile} msg] $msg
} {1 {wrong # args: should be "AppleScript compile ?options? code"}}

# cleanup
::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
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74


75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259

260
261
262
263


264
265
266


267
268


269

270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333
334
335

336
337
338
339

340
341
342

343
344
345
346
347
348
349

350
351
352
353
354

355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376





377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421

422
423
424
425
426
427

428
429
430

431
432
433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544










































































































































































































































































































































545

























































































































































































546
547
548



549
550
551
552






553
554
555
556





















# Commands covered:  set (plus basic command syntax).  Also tests
# the procedures in the file tclParse.c.
#
# 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-1996 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) parse.test 1.42 97/08/04 11:05:53

if {[string compare test [info procs test]] == 1} then {source defs}

proc fourArgs {a b c d} {
    global arg1 arg2 arg3 arg4
    set arg1 $a
    set arg2 $b
    set arg3 $c
    set arg4 $d
}

proc getArgs args {
    global argv
    set argv $args
}

# Basic argument parsing.

test parse-1.1 {basic argument parsing} {
    set arg1 {}
    fourArgs a b	c 		 d
    list $arg1 $arg2 $arg3 $arg4
} {a b c d}
test parse-1.2 {basic argument parsing} {
    set arg1 {}
    eval "fourArgs 123\v4\f56\r7890"
    list $arg1 $arg2 $arg3 $arg4
} {123 4 56 7890}

# Quotes.

test parse-2.1 {quotes and variable-substitution} {
    getArgs "a b c" d
    set argv
} {{a b c} d}
test parse-2.2 {quotes and variable-substitution} {
    set a 101
    getArgs "a$a b c"
    set argv
} {{a101 b c}}
test parse-2.3 {quotes and variable-substitution} {
    set argv "xy[format xabc]"
    set argv
} {xyxabc}
test parse-2.4 {quotes and variable-substitution} {
    set argv "xy\t"
    set argv
} xy\t
test parse-2.5 {quotes and variable-substitution} {
    set argv "a b	c
d e f"
    set argv
} a\ b\tc\nd\ e\ f
test parse-2.6 {quotes and variable-substitution} {
    set argv a"bcd"e
    set argv
} {a"bcd"e}

# Braces.



test parse-3.1 {braces} {
    getArgs {a b c} d
    set argv
} "{a b c} d"

test parse-3.2 {braces} {
    set a 101
    set argv {a$a b c}
    set b [string index $argv 1]
    set b
} {$}
test parse-3.3 {braces} {
    set argv {a[format xyz] b}
    string length $argv
} 15
test parse-3.4 {braces} {
    set argv {a\nb\}}
    string length $argv
} 6
test parse-3.5 {braces} {
    set argv {{{{}}}}
    set argv
} "{{{}}}"
test parse-3.6 {braces} {
    set argv a{{}}b
    set argv
} "a{{}}b"
test parse-3.7 {braces} {
    set a [format "last]"]
    set a
} {last]}

# Command substitution.

test parse-4.1 {command substitution} {
    set a [format xyz]
    set a
} xyz
test parse-4.2 {command substitution} {
    set a a[format xyz]b[format q]
    set a
} axyzbq
test parse-4.3 {command substitution} {
    set a a[
set b 22;
format %s $b

]b
    set a
} a22b
test parse-4.4 {command substitution} {
    set a 7.7
    if [catch {expr int($a)}] {set a foo}
    set a
} 7.7

# Variable substitution.

test parse-5.1 {variable substitution} {
    set a 123
    set b $a
    set b
} 123
test parse-5.2 {variable substitution} {
    set a 345
    set b x$a.b
    set b
} x345.b
test parse-5.3 {variable substitution} {
    set _123z xx
    set b $_123z^
    set b
} xx^
test parse-5.4 {variable substitution} {
    set a 78
    set b a${a}b
    set b
} a78b
test parse-5.5 {variable substitution} {catch {$_non_existent_} msg} 1
test parse-5.6 {variable substitution} {
    catch {$_non_existent_} msg
    set msg
} {can't read "_non_existent_": no such variable}
test parse-5.7 {array variable substitution} {
    catch {unset a}
    set a(xyz) 123
    set b $a(xyz)foo
    set b
} 123foo
test parse-5.8 {array variable substitution} {
    catch {unset a}
    set "a(x y z)" 123
    set b $a(x y z)foo
    set b
} 123foo
test parse-5.9 {array variable substitution} {
    catch {unset a}; catch {unset qqq}
    set "a(x y z)" qqq
    set $a([format x]\ y [format z]) foo
    set qqq
} foo
test parse-5.10 {array variable substitution} {
    catch {unset a}
    list [catch {set b $a(22)} msg] $msg
} {1 {can't read "a(22)": no such variable}}
test parse-5.11 {array variable substitution} {
    set b a$!
    set b
} {a$!}
test parse-5.12 {array variable substitution} {
    set b a$()
    set b
} {a$()}
catch {unset a}

test parse-5.13 {array variable substitution} {
    catch {unset a}
    set long {This is a very long variable, long enough to cause storage \
	allocation to occur in Tcl_ParseVar.  If that storage isn't getting \
	freed up correctly, then a core leak will occur when this test is \
	run.  This text is probably beginning to sound like drivel, but I've \
	run out of things to say and I need more characters still.}
    set a($long) 777
    set b $a($long)
    list $b [array names a]
} {777 {{This is a very long variable, long enough to cause storage \
	allocation to occur in Tcl_ParseVar.  If that storage isn't getting \
	freed up correctly, then a core leak will occur when this test is \
	run.  This text is probably beginning to sound like drivel, but I've \
	run out of things to say and I need more characters still.}}}
test parse-5.14 {array variable substitution} {
    catch {unset a}; catch {unset b}; catch {unset a1}
    set a1(22) foo
    set a(foo) bar
    set b $a($a1(22))
    set b
} bar
catch {unset a}; catch {unset a1}

# Backslash substitution.

set errNum 1
proc bsCheck {char num} {
    global errNum
;   test parse-6.$errNum {backslash substitution} {
	scan $char %c value
	set value
    } $num
    set errNum [expr $errNum+1]
}

bsCheck \b	8
bsCheck \e	101
bsCheck \f	12
bsCheck \n	10
bsCheck \r	13
bsCheck \t	9
bsCheck \v	11
bsCheck \{	123
bsCheck \}	125
bsCheck \[	91
bsCheck \]	93
bsCheck \$	36
bsCheck \ 	32
bsCheck \;	59
bsCheck \\	92
bsCheck \Ca	67
bsCheck \Ma	77
bsCheck \CMa	67
bsCheck \8a	8
bsCheck \14	12
bsCheck \141	97
bsCheck \340	224
bsCheck b\0	98
bsCheck \x	120
bsCheck \xa	10
bsCheck \x41	65
bsCheck \x541	65

test parse-6.1 {backslash substitution} {
    set a "\a\c\n\]\}"
    string length $a
} 5
test parse-6.2 {backslash substitution} {
    set a {\a\c\n\]\}}
    string length $a
} 10

test parse-6.3 {backslash substitution} {
    set a "abc\
def"
    set a


} {abc def}
test parse-6.4 {backslash substitution} {
    set a {abc\


def}
    set a


} {abc def}

test parse-6.5 {backslash substitution} {
    set msg {}
    set a xxx
    set error [catch {if {24 < \
	35} {set a 22} {set \
	    a 33}} msg]
    list $error $msg $a

} {0 22 22}
test parse-6.6 {backslash substitution} {
    eval "concat abc\\"
} "abc\\"
test parse-6.7 {backslash substitution} {
    eval "concat \\\na"
} "a"
test parse-6.8 {backslash substitution} {
    eval "concat x\\\n   	a"
} "x a"
test parse-6.9 {backslash substitution} {
    eval "concat \\x"
} "x"
test parse-6.10 {backslash substitution} {
    eval "list a b\\\nc d"
} {a b c d}
test parse-6.11 {backslash substitution} {
    eval "list a \"b c\"\\\nd e"
} {a {b c} d e}

# Semi-colon.

test parse-7.1 {semi-colons} {
    set b 0
    getArgs a;set b 2
    set argv
} a
test parse-7.2 {semi-colons} {
    set b 0
    getArgs a;set b 2
    set b
} 2
test parse-7.3 {semi-colons} {
    getArgs a b ; set b 1
    set argv
} {a b}
test parse-7.4 {semi-colons} {
    getArgs a b ; set b 1
    set b
} 1

# The following checks are to ensure that the interpreter's result
# gets re-initialized by Tcl_Eval in all the right places.

test parse-8.1 {result initialization} {concat abc} abc
test parse-8.2 {result initialization} {concat abc; proc foo {} {}} {}
test parse-8.3 {result initialization} {concat abc; proc foo {} $a} {}
test parse-8.4 {result initialization} {proc foo {} [concat abc]} {}
test parse-8.5 {result initialization} {concat abc; } abc

test parse-8.6 {result initialization} {
    eval {
    concat abc
}} abc
test parse-8.7 {result initialization} {} {}
test parse-8.8 {result initialization} {concat abc; ; ;} abc

# Syntax errors.

test parse-9.1 {syntax errors} {catch "set a \{bcd" msg} 1

test parse-9.2 {syntax errors} {
	catch "set a \{bcd" msg
	set msg
} {missing close-brace}

test parse-9.3 {syntax errors} {catch {set a "bcd} msg} 1
test parse-9.4 {syntax errors} {
	catch {set a "bcd} msg

	set msg
} {quoted string doesn't terminate properly}
test parse-9.5 {syntax errors} {catch {set a "bcd"xy} msg} 1
test parse-9.6 {syntax errors} {
	catch {set a "bcd"xy} msg
	set msg
} {quoted string doesn't terminate properly}

test parse-9.7 {syntax errors} {catch "set a {bcd}xy" msg} 1
test parse-9.8 {syntax errors} {
	catch "set a {bcd}xy" msg
	set msg
} {argument word in braces doesn't terminate properly}

test parse-9.9 {syntax errors} {catch {set a [format abc} msg} 1
test parse-9.10 {syntax errors} {
	catch {set a [format abc} msg
	set msg
} {missing close-bracket or close-brace}
test parse-9.11 {syntax errors} {catch gorp-a-lot msg} 1
test parse-9.12 {syntax errors} {
	catch gorp-a-lot msg
	set msg
} {invalid command name "gorp-a-lot"}
test parse-9.13 {syntax errors} {
    set a [concat {a}\
 {b}]
    set a
} {a b}
test parse-9.14 {syntax errors} {
    list [catch {eval \$x[format "%01000d" 0](} msg] $msg $errorInfo
} {1 {missing )} {missing )
    (parsing index for array "x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
    while compiling
"$x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ..."
    ("eval" body line 1)





    invoked from within
"eval \$x[format "%01000d" 0]("}}
test parse-9.15 {syntax errors, missplaced braces} {
    catch {
        proc misplaced_end_brace {} {
            set what foo
            set when [expr ${what}size - [set off$what]}]
    } msg
    set msg
} {wrong # args: should be "proc name args body"}
test parse-9.16 {syntax errors, missplaced braces} {
    catch {
        set a {
            set what foo
            set when [expr ${what}size - [set off$what]}]
    } msg
    set msg
} {argument word in braces doesn't terminate properly}

# Long values (stressing storage management)

set a {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH}

test parse-10.1 {long values} {
    string length $a
} 214
test parse-10.2 {long values} {
    llength $a
} 43
test parse-10.3 {long values} {
    set b "1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH"
    set b
} $a
test parse-10.4 {long values} {
    set b "$a"
    set b
} $a
test parse-10.5 {long values} {
    set b [set a]
    set b
} $a
test parse-10.6 {long values} {
    set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
    string length $b
} 214

test parse-10.7 {long values} {
    set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
    llength $b
} 43
test parse-10.8 {long values} {
    set b

} $a
test parse-10.9 {long values} {
    set a [concat 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL MMMM NNNN OOOO PPPP QQQQ RRRR SSSS TTTT UUUU VVVV WWWW XXXX YYYY ZZZZ]

    llength $a
} 62
set i 0
foreach j [concat 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL MMMM NNNN OOOO PPPP QQQQ RRRR SSSS TTTT UUUU VVVV WWWW XXXX YYYY ZZZZ] {
    set test [string index 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ $i]
    set test $test$test$test$test
    set i [expr $i+1]
    test parse-10.10 {long values} {
	set j
    } $test
}

test parse-10.11 {test buffer overflow in backslashes in braces} {
    expr {"a" == {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101}}
} 0

test parse-11.1 {comments} {
    set a old
    eval {  # set a new}
    set a
} {old}
test parse-11.2 {comments} {
    set a old
    eval "  # set a new\nset a new"
    set a
} {new}
test parse-11.3 {comments} {
    set a old
    eval "  # set a new\\\nset a new"
    set a
} {old}
test parse-11.4 {comments} {
    set a old
    eval "  # set a new\\\\\nset a new"
    set a
} {new}

test parse-12.1 {comments at the end of a bracketed script} {
    set x "[
expr 1+1
# skip this!
]"
} {2}

if {[info command testwordend] == "testwordend"} {
    test parse-13.1 {TclWordEnd procedure} {
	testwordend " 	\n abc"
    } {c}
    test parse-13.2 {TclWordEnd procedure} {
	testwordend "   \\\n"
    } {}
    test parse-13.3 {TclWordEnd procedure} {
	testwordend "   \\\n "
    } { }
    test parse-13.4 {TclWordEnd procedure} {
	testwordend {"abc"}
    } {"}
    test parse-13.5 {TclWordEnd procedure} {
	testwordend {{xyz}}
    } \}
    test parse-13.6 {TclWordEnd procedure} {
	testwordend {{a{}b{}\}} xyz}
    } "\} xyz"
    test parse-13.7 {TclWordEnd procedure} {
	testwordend {abc[this is a]def ghi}
    } {f ghi}
    test parse-13.8 {TclWordEnd procedure} {
	testwordend "puts\\\n\n  "
    } "s\\\n\n  "
    test parse-13.9 {TclWordEnd procedure} {
	testwordend "puts\\\n   	"
    } "s\\\n   	"
    test parse-13.10 {TclWordEnd procedure} {
	testwordend "puts\\\n   	xyz"
    } "s\\\n   	xyz"
    test parse-13.11 {TclWordEnd procedure} {
	testwordend {a$x.$y(a long index) foo}
    } ") foo"
    test parse-13.12 {TclWordEnd procedure} {
	testwordend {abc; def}
    } {; def}
    test parse-13.13 {TclWordEnd procedure} {
	testwordend {abc def}
    } {c def}
    test parse-13.14 {TclWordEnd procedure} {
	testwordend {abc	def}
    } {c	def}
    test parse-13.15 {TclWordEnd procedure} {
	testwordend "abc\ndef"
    } "c\ndef"
    test parse-13.16 {TclWordEnd procedure} {
	testwordend "abc"
    } {c}
    test parse-13.17 {TclWordEnd procedure} {
	testwordend "a\000bc"
    } {c}
    test parse-13.18 {TclWordEnd procedure} {
	testwordend \[a\000\]
    } {]}
    test parse-13.19 {TclWordEnd procedure} {
	testwordend \"a\000\"
    } {"}
    test parse-13.20 {TclWordEnd procedure} {
	testwordend a{\000}b
    } {b}
    test parse-13.21 {TclWordEnd procedure} {
	testwordend "   \000b"
    } {b}
}

test parse-14.1 {TclScriptEnd procedure} {
    info complete {puts [
	expr 1+1
	#this is a comment ]}
} {0}










































































































































































































































































































































test parse-14.2 {TclScriptEnd procedure} {

























































































































































































    info complete "abc\\\n"
} {0}
test parse-14.3 {TclScriptEnd procedure} {



    info complete "abc\\\\\n"
} {1}
test parse-14.4 {TclScriptEnd procedure} {
    info complete "xyz \[abc \{abc\]"






} {0}
test parse-14.5 {TclScriptEnd procedure} {
    info complete "xyz \[abc"
} {0}





















<
<
<
|
|


|
|




|

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


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

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

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

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

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

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




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

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



1
2
3
4
5
6
7
8
9
10
11
12

13







14



15
16
17
18
19









20
21
22


























23

24
25
26
27

28

29
30





31


32
33



34











35
36
37












38



39




40

41
42


43
44
45


46
47




































48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63





64



65

66
67












































68
69



70



71
72
73

74
75
76
77
78
79
80
81
82

83
84
85
86
87


88



89








































90


91
92




93
94
95
96

97
98
99

100
101
102
103

104

105
106
107

108
109

110
111



112
113
114



115
116
117




118

119

120


121
122
123





124
125
126
127
128
129
130




131












132

133

134
135








136
137
138
139
140
141



142



143
144



145

146
147


148
149










150



151
152




153



154
155









156






157

158
159
160
161
162
163
164
165
166
167
168
169





















170
171
172


173

174





175

176

177


178
179

180


181




182

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743



# 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.1.2.12 1999/04/01 21:56:15 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\""
    puts "command, so I can't test the Tcl parser."









    ::tcltest::cleanupTests
    return 
}




























test parse-1.1 {Tcl_ParseCommand procedure, computing string length} {
    testparser [bytestring "foo\0 bar"] -1
} {- foo 1 simple foo 1 text foo 0 {}}
test parse-1.2 {Tcl_ParseCommand procedure, computing string length} {

    testparser "foo bar" -1

} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
test parse-1.3 {Tcl_ParseCommand procedure, leading space} {





    testparser "  \n\t   foo" 0


} {- foo 1 simple foo 1 text foo 0 {}}
test parse-1.4 {Tcl_ParseCommand procedure, leading space} {



    testparser "\f\r\vfoo" 0











} {- foo 1 simple foo 1 text foo 0 {}}
test parse-1.5 {Tcl_ParseCommand procedure, backslash-newline in leading space} {
    testparser "  \\\n foo" 0












} {- foo 1 simple foo 1 text foo 0 {}}



test parse-1.6 {Tcl_ParseCommand procedure, backslash-newline in leading space} {




    testparser {  \a foo} 0

} {- {\a foo} 2 word {\a} 1 backslash {\a} 0 simple foo 1 text foo 0 {}}
test parse-1.7 {Tcl_ParseCommand procedure, missing continuation line in leading space} {


    testparser "   \\\n" 0
} {- {} 0 {}}
test parse-1.8 {Tcl_ParseCommand procedure, eof in leading space} {


    testparser "      foo" 3
} {- {} 0 {   foo}}





































test parse-2.1 {Tcl_ParseCommand procedure, comments} {
    testparser "# foo bar\n foo" 0
} {{# foo bar
} foo 1 simple foo 1 text foo 0 {}}
test parse-2.2 {Tcl_ParseCommand procedure, several comments} {
    testparser " # foo bar\n # another comment\n\n   foo" 0

} {{# foo bar
 # another comment
} foo 1 simple foo 1 text foo 0 {}}
test parse-2.3 {Tcl_ParseCommand procedure, backslash-newline in comments} {
    testparser " # foo bar\\\ncomment on continuation line\nfoo" 0
} {#\ foo\ bar\\\ncomment\ on\ continuation\ line\n foo 1 simple foo 1 text foo 0 {}}
test parse-2.4 {Tcl_ParseCommand procedure, missing continuation line in comment} {
    testparser "#   \\\n" 0
} {#\ \ \ \\\n {} 0 {}}





test parse-2.5 {Tcl_ParseCommand procedure, eof in comment} {



    testparser " # foo bar\nfoo" 8

} {{# foo b} {} 0 {ar
foo}}













































test parse-3.1 {Tcl_ParseCommand procedure, parsing words, skipping space} {



    testparser "foo  bar\t\tx" 0



} {- {foo  bar		x} 3 simple foo 1 text foo 0 simple bar 1 text bar 0 simple x 1 text x 0 {}}
test parse-3.2 {Tcl_ParseCommand procedure, missing continuation line in leading space} {
    testparser "abc  \\\n" 0

} {- abc\ \ \\\n 1 simple abc 1 text abc 0 {}}
test parse-3.3 {Tcl_ParseCommand procedure, parsing words, command ends in space} {
    testparser "foo  ;  bar x" 0
} {- {foo  ;} 1 simple foo 1 text foo 0 {  bar x}}
test parse-3.4 {Tcl_ParseCommand procedure, parsing words, command ends in space} {
    testparser "foo       " 5
} {- {foo  } 1 simple foo 1 text foo 0 {     }}
test parse-3.5 {Tcl_ParseCommand procedure, quoted words} {
    testparser {foo "a b c" d "efg";} 0

} {- {foo "a b c" d "efg";} 4 simple foo 1 text foo 0 simple {"a b c"} 1 text {a b c} 0 simple d 1 text d 0 simple {"efg"} 1 text efg 0 {}}
test parse-3.6 {Tcl_ParseCommand procedure, words in braces} {
    testparser {foo {a $b [concat foo]} {c d}} 0
} {- {foo {a $b [concat foo]} {c d}} 3 simple foo 1 text foo 0 simple {{a $b [concat foo]}} 1 text {a $b [concat foo]} 0 simple {{c d}} 1 text {c d} 0 {}}
test parse-3.7 {Tcl_ParseCommand procedure, error in unquoted word} {


    list [catch {testparser "foo \$\{abc" 0} msg] $msg $errorInfo



} {1 {missing close-brace for variable name} missing\ close-brace\ for\ variable\ name\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"foo\ \\\$\\\{abc\"\ 0\"}











































test parse-4.1 {Tcl_ParseCommand procedure, simple words} {
    testparser {foo} 0




} {- foo 1 simple foo 1 text foo 0 {}}
test parse-4.2 {Tcl_ParseCommand procedure, simple words} {
    testparser {{abc}} 0
} {- {{abc}} 1 simple {{abc}} 1 text abc 0 {}}

test parse-4.3 {Tcl_ParseCommand procedure, simple words} {
    testparser {"c d"} 0
} {- {"c d"} 1 simple {"c d"} 1 text {c d} 0 {}}

test parse-4.4 {Tcl_ParseCommand procedure, simple words} {
    testparser {x$d} 0
} {- {x$d} 1 word {x$d} 3 text x 0 variable {$d} 1 text d 0 {}}
test parse-4.5 {Tcl_ParseCommand procedure, simple words} {

    testparser {"a [foo] b"} 0

} {- {"a [foo] b"} 1 word {"a [foo] b"} 3 text {a } 0 command {[foo]} 0 text { b} 0 {}}
test parse-4.6 {Tcl_ParseCommand procedure, simple words} {
    testparser {$x} 0

} {- {$x} 1 word {$x} 2 variable {$x} 1 text x 0 {}}


test parse-5.1 {Tcl_ParseCommand procedure, backslash-newline terminates word} {
    testparser "{abc}\\\n" 0



} {- \{abc\}\\\n 1 simple {{abc}} 1 text abc 0 {}}
test parse-5.2 {Tcl_ParseCommand procedure, backslash-newline terminates word} {
    testparser "foo\\\nbar" 0



} {- foo\\\nbar 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
test parse-5.3 {Tcl_ParseCommand procedure, word terminator is command terminator} {
    testparser "foo\n bar" 0




} {- {foo

} 1 simple foo 1 text foo 0 { bar}}

test parse-5.4 {Tcl_ParseCommand procedure, word terminator is command terminator} {


    testparser "foo; bar" 0
} {- {foo;} 1 simple foo 1 text foo 0 { bar}}
test parse-5.5 {Tcl_ParseCommand procedure, word terminator is end of string} {





    testparser "\"foo\" bar" 5
} {- {"foo"} 1 simple {"foo"} 1 text foo 0 { bar}}
test parse-5.6 {Tcl_ParseCommand procedure, junk after close quote} {
    list [catch {testparser {foo "bar"x} 0} msg] $msg $errorInfo
} {1 {extra characters after close-quote} {extra characters after close-quote
    (remainder of script: "x")
    invoked from within




"testparser {foo "bar"x} 0"}}












test parse-5.7 {Tcl_ParseCommand procedure, backslash-newline after close quote} {

    testparser "foo \"bar\"\\\nx" 0

} {- foo\ \"bar\"\\\nx 3 simple foo 1 text foo 0 simple {"bar"} 1 text bar 0 simple x 1 text x 0 {}}
test parse-5.8 {Tcl_ParseCommand procedure, junk after close brace} {








    list [catch {testparser {foo {bar}x} 0} msg] $msg $errorInfo
} {1 {extra characters after close-brace} {extra characters after close-brace
    (remainder of script: "x")
    invoked from within
"testparser {foo {bar}x} 0"}}
test parse-5.9 {Tcl_ParseCommand procedure, backslash-newline after close brace} {



    testparser "foo {bar}\\\nx" 0



} {- foo\ \{bar\}\\\nx 3 simple foo 1 text foo 0 simple {{bar}} 1 text bar 0 simple x 1 text x 0 {}}
test parse-5.10 {Tcl_ParseCommand procedure, multiple deletion of non-static buffer} {



    # This test is designed to catch bug 1681.

    list [catch {testparser "a \"\\1\\2\\3\\4\\5\\6\\7\\8\\9\\1\\2\\3\\4\\5\\6\\7\\8" 0} msg] $msg $errorInfo
} "1 {missing \"} {missing \"


    (remainder of script: \"\"\\1\\2\\3\\4\\5\\6\\7\\8\\9\\1\\2\\3\\4\\5\\6\\7\\8\")
    invoked from within










\"testparser \"a \\\"\\\\1\\\\2\\\\3\\\\4\\\\5\\\\6\\\\7\\\\8\\\\9\\\\1\\\\2\\\\3\\\\4\\\\5\\\\6\\\\7\\\\8\" 0\"}"




test parse-6.1 {ParseTokens procedure, empty word} {




    testparser {""} 0



} {- {""} 1 simple {""} 1 text {} 0 {}}
test parse-6.2 {ParseTokens procedure, simple range} {









    testparser {"abc$x.e"} 0






} {- {"abc$x.e"} 1 word {"abc$x.e"} 4 text abc 0 variable {$x} 1 text x 0 text .e 0 {}}

test parse-6.3 {ParseTokens procedure, variable reference} {
    testparser {abc$x.e $y(z)} 0
} {- {abc$x.e $y(z)} 2 word {abc$x.e} 4 text abc 0 variable {$x} 1 text x 0 text .e 0 word {$y(z)} 3 variable {$y(z)} 2 text y 0 text z 0 {}}
test parse-6.4 {ParseTokens procedure, variable reference} {
    list [catch {testparser {$x([a )} 0} msg] $msg
} {1 {missing close-bracket}}
test parse-6.5 {ParseTokens procedure, command substitution} {
    testparser {[foo $x bar]z} 0
} {- {[foo $x bar]z} 1 word {[foo $x bar]z} 2 command {[foo $x bar]} 0 text z 0 {}}
test parse-6.6 {ParseTokens procedure, command substitution} {
    testparser {[foo \] [a b]]} 0
} {- {[foo \] [a b]]} 1 word {[foo \] [a b]]} 1 command {[foo \] [a b]]} 0 {}}





















test parse-6.7 {ParseTokens procedure, error in command substitution} {
    list [catch {testparser {a [b {}c d] e} 0} msg] $msg $errorInfo
} {1 {extra characters after close-brace} {extra characters after close-brace


    (remainder of script: "c d] e")

    invoked from within





"testparser {a [b {}c d] e} 0"}}

test parse-6.8 {ParseTokens procedure, error in command substitution} {

    info complete {a [b {}c d]}


} {1}
test parse-6.9 {ParseTokens procedure, error in command substitution} {

    info complete {a [b "c d}


} {0}




test parse-6.10 {ParseTokens procedure, incomplete sub-command} {

    info complete {puts [
	expr 1+1
	#this is a comment ]}
} {0}
test parse-6.11 {ParseTokens procedure, memory allocation for big nested command} {
    testparser {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 0
} {- {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 1 word {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 1 command {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 0 {}}
test parse-6.12 {ParseTokens procedure, missing close bracket} {
    list [catch {testparser {[foo $x bar} 0} msg] $msg $errorInfo
} {1 {missing close-bracket} {missing close-bracket
    (remainder of script: "[foo $x bar")
    invoked from within
"testparser {[foo $x bar} 0"}}
test parse-6.13 {ParseTokens procedure, backslash-newline without continuation line} {
    list [catch {testparser "\"a b\\\n" 0} msg] $msg $errorInfo
} {1 {missing "} missing\ \"\n\ \ \ \ (remainder\ of\ script:\ \"\"a\ b\\\n\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\\\"a\ b\\\\\\n\"\ 0\"}
test parse-6.14 {ParseTokens procedure, backslash-newline} {
    testparser "b\\\nc" 0
} {- b\\\nc 2 simple b 1 text b 0 simple c 1 text c 0 {}}
test parse-6.15 {ParseTokens procedure, backslash-newline} {
    testparser "\"b\\\nc\"" 0
} {- \"b\\\nc\" 1 word \"b\\\nc\" 3 text b 0 backslash \\\n 0 text c 0 {}}
test parse-6.16 {ParseTokens procedure, backslash substitution} {
    testparser {\n\a\x7f} 0
} {- {\n\a\x7f} 1 word {\n\a\x7f} 3 backslash {\n} 0 backslash {\a} 0 backslash {\x7f} 0 {}}
test parse-6.17 {ParseTokens procedure, null characters} {
    testparser [bytestring "foo\0zz"] 0
} "- [bytestring foo\0zz] 1 word [bytestring foo\0zz] 3 text foo 0 text [bytestring \0] 0 text zz 0 {}"

test parse-7.1 {Tcl_FreeParse and ExpandTokenArray procedures} {
    testparser {$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) } 0
} {- {$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) } 16 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 {}}

test parse-8.1 {Tcl_EvalObjv procedure} {
    testevalobjv 0 concat this is a test
} {this is a test}
test parse-8.2 {Tcl_EvalObjv procedure, unknown commands} {
    rename unknown unknown.old
    set x [catch {testevalobjv 10 asdf poiu} msg]
    rename unknown.old unknown
    list $x $msg
} {1 {invalid command name "asdf"}}
test parse-8.3 {Tcl_EvalObjv procedure, unknown commands} {
    rename unknown unknown.old
    proc unknown args {
	return "unknown $args"
    }
    set x [catch {testevalobjv 0 asdf poiu} msg]
    rename unknown {}
    rename unknown.old unknown
    list $x $msg
} {0 {unknown asdf poiu}}
test parse-8.4 {Tcl_EvalObjv procedure, unknown commands} {
    rename unknown unknown.old
    proc unknown args {
	error "I don't like that command"
    }
    set x [catch {testevalobjv 0 asdf poiu} msg]
    rename unknown {}
    rename unknown.old unknown
    list $x $msg
} {1 {I don't like that command}}
test parse-8.5 {Tcl_EvalObjv procedure, command traces} {
    testevalobjv 0 set x 123
    testcmdtrace tracetest {testevalobjv 0 set x $x}
} {{testevalobjv 0 set x $x} {testevalobjv 0 set x 123} {set x 123} {set x 123}}
test parse-8.7 {Tcl_EvalObjv procedure, TCL_EVAL_GLOBAL flag} {
    proc x {} {
	set y 23
	set z [testevalobjv 1 set y]
	return [list $z $y]
    }
    catch {unset y}
    set y 16
    x
} {16 23}
test parse-8.8 {Tcl_EvalObjv procedure, async handlers} {
    proc async1 {result code} {
	global aresult acode
	set aresult $result
	set acode $code
	return "new result"
    }
    set handler1 [testasync create async1]
    set aresult xxx
    set acode yyy
    set x [list [catch [list testevalobjv 0 testasync mark $handler1 original 0] msg] $msg $acode $aresult]
    testasync delete
    set x
} {0 {new result} 0 original}
test parse-8.9 {Tcl_EvalObjv procedure, exceptional return} {
    list [catch {testevalobjv 0 error message} msg] $msg
} {1 message}

test parse-9.1 {Tcl_LogCommandInfo, line numbers} {
    catch {unset x}
    list [catch {testevalex {for {} 1 {} {


	# asdf
	set x
    }}}] $errorInfo
} {1 {can't read "x": no such variable
    while executing
"set x"
    ("for" body line 5)
    invoked from within
"for {} 1 {} {


	# asdf
	set x
    }"
    invoked from within
"testevalex {for {} 1 {} {


	# asdf
	set x
    }}"}}
test parse-9.2 {Tcl_LogCommandInfo, truncating long commands} {
    list [testevalex {catch {set a b 111111111 222222222 333333333 444444444 555555555 666666666 777777777 888888888 999999999 000000000 aaaaaaaaa bbbbbbbbb ccccccccc ddddddddd eeeeeeeee fffffffff ggggggggg}}] $errorInfo
} {1 {wrong # args: should be "set varName ?newValue?"
    while executing
"set a b 111111111 222222222 333333333 444444444 555555555 666666666 777777777 888888888 999999999 000000000 aaaaaaaaa bbbbbbbbb ccccccccc ddddddddd ee..."}}

test parse-10.1 {Tcl_EvalTokens, simple text} {
    testevalex {concat test}
} {test}
test parse-10.2 {Tcl_EvalTokens, backslash sequences} {
    testevalex {concat test\063\062test}
} {test32test}
test parse-10.3 {Tcl_EvalTokens, nested commands} {
    testevalex {concat [expr 2 + 6]}
} {8}
test parse-10.4 {Tcl_EvalTokens, nested commands} {
    catch {unset a}
    list [catch {testevalex {concat xxx[expr $a]}} msg] $msg
} {1 {can't read "a": no such variable}}
test parse-10.5 {Tcl_EvalTokens, simple variables} {
    set a hello
    testevalex {concat $a}
} {hello}
test parse-10.6 {Tcl_EvalTokens, array variables} {
    catch {unset a}
    set a(12) 46
    testevalex {concat $a(12)}
} {46}
test parse-10.7 {Tcl_EvalTokens, array variables} {
    catch {unset a}
    set a(12) 46
    testevalex {concat $a(1[expr 3 - 1])}
} {46}
test parse-10.8 {Tcl_EvalTokens, array variables} {
    catch {unset a}
    list [catch {testevalex {concat $x($a)}} msg] $msg
} {1 {can't read "a": no such variable}}
test parse-10.9 {Tcl_EvalTokens, array variables} {
    catch {unset a}
    list [catch {testevalex {concat xyz$a(1)}} msg] $msg
} {1 {can't read "a(1)": no such variable}}
test parse-10.10 {Tcl_EvalTokens, object values} {
    set a 123
    testevalex {concat $a}
} {123}
test parse-10.11 {Tcl_EvalTokens, object values} {
    set a 123
    testevalex {concat $a$a$a}
} {123123123}
test parse-10.12 {Tcl_EvalTokens, object values} {
    testevalex {concat [expr 2][expr 4][expr 6]}
} {246}
test parse-10.13 {Tcl_EvalTokens, string values} {
    testevalex {concat {a" b"}}
} {a" b"}
test parse-10.14 {Tcl_EvalTokens, string values} {
    set a 111
    testevalex {concat x$a.$a.$a}
} {x111.111.111}

test parse-11.1 {Tcl_Eval2, TCL_EVAL_GLOBAL flag} {
    proc x {} {
	set y 777
	set z [testevalex "set y" global]
	return [list $z $y]
    }
    catch {unset y}
    set y 321
    x
} {321 777}
test parse-11.2 {Tcl_Eval2, error while parsing} {
    list [catch {testevalex {concat "abc}} msg] $msg
} {1 {missing "}}
test parse-11.3 {Tcl_Eval2, error while collecting words} {
    catch {unset a}
    list [catch {testevalex {concat xyz $a}} msg] $msg
} {1 {can't read "a": no such variable}}
test parse-11.4 {Tcl_Eval2, error in Tcl_EvalObjv call} {
    catch {unset a}
    list [catch {testevalex {_bogus_ a b c d}} msg] $msg
} {1 {invalid command name "_bogus_"}}
test parse-11.5 {Tcl_Eval2, exceptional return} {
    list [catch {testevalex {break}} msg] $msg
} {3 {}}
test parse-11.6 {Tcl_Eval2, freeing memory} {
    testevalex {concat a b c d e f g h i j k l m n o p q r s t u v w x y z}
} {a b c d e f g h i j k l m n o p q r s t u v w x y z}
test parse-11.7 {Tcl_Eval2, multiple commands in script} {
    list [testevalex {set a b; set c d}] $a $c
} {d b d}
test parse-11.8 {Tcl_Eval2, multiple commands in script} {
    list [testevalex {
	set a b
	set c d
    }] $a $c
} {d b d}
test parse-11.9 {Tcl_Eval2, freeing memory after error} {
    catch {unset a}
    list [catch {testevalex {concat a b c d e f g h i j k l m n o p q r s t u v w x y z $a}} msg] $msg
} {1 {can't read "a": no such variable}}
test parse-11.10 {Tcl_EvalTokens, empty commands} {
    testevalex {concat xyz;   }
} {xyz}
test parse-11.11 {Tcl_EvalTokens, empty commands} {
    testevalex "concat abc; ; # this is a comment\n"
} {abc}
test parse-11.12 {Tcl_EvalTokens, empty commands} {
    testevalex {}
} {}

test parse-12.1 {Tcl_ParseVarName procedure, initialization} {
    list [catch {testparsevarname {$a([first second])} 8 0} msg] $msg
} {1 {missing close-bracket}}
test parse-12.2 {Tcl_ParseVarName procedure, initialization} {
    testparsevarname {$a([first second])} 0 0
} {- {} 0 variable {$a([first second])} 2 text a 0 command {[first second]} 0 {}}
test parse-12.3 {Tcl_ParseVarName procedure, initialization} {
    list [catch {testparsevarname {$abcd} 3 0} msg] $msg
} {0 {- {} 0 variable {$ab} 1 text ab 0 cd}}
test parse-12.4 {Tcl_ParseVarName procedure, initialization} {
    testparsevarname {$abcd} 0 0
} {- {} 0 variable {$abcd} 1 text abcd 0 {}}
test parse-12.5 {Tcl_ParseVarName procedure, just a dollar sign} {
    testparsevarname {$abcd} 1 0
} {- {} 0 text {$} 0 abcd}
test parse-12.6 {Tcl_ParseVarName procedure, braced variable name} {
    testparser {${..[]b}cd} 0
} {- {${..[]b}cd} 1 word {${..[]b}cd} 3 variable {${..[]b}} 1 text {..[]b} 0 text cd 0 {}}
test parse-12.7 {Tcl_ParseVarName procedure, braced variable name} {
    testparser "\$\{\{\} " 0
} {- \$\{\{\}\  1 word \$\{\{\} 2 variable \$\{\{\} 1 text \{ 0 {}}
test parse-12.8 {Tcl_ParseVarName procedure, missing close brace} {
    list [catch {testparser "$\{abc" 0} msg] $msg $errorInfo
} {1 {missing close-brace for variable name} missing\ close-brace\ for\ variable\ name\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\$\\\{abc\"\ 0\"}
test parse-12.9 {Tcl_ParseVarName procedure, missing close brace} {
    list [catch {testparsevarname {${bcd}} 4 0} msg] $msg
} {1 {missing close-brace for variable name}}
test parse-12.10 {Tcl_ParseVarName procedure, missing close brace} {
    list [catch {testparsevarname {${bc}} 4 0} msg] $msg
} {1 {missing close-brace for variable name}}
test parse-12.11 {Tcl_ParseVarName procedure, simple variable name} {
    testparser {$az_AZ.} 0
} {- {$az_AZ.} 1 word {$az_AZ.} 3 variable {$az_AZ} 1 text az_AZ 0 text . 0 {}}
test parse-12.12 {Tcl_ParseVarName procedure, simple variable name} {
    testparser {$abcdefg} 4
} {- {$abc} 1 word {$abc} 2 variable {$abc} 1 text abc 0 defg}
test parse-12.13 {Tcl_ParseVarName procedure, simple variable name with ::} {
    testparser {$xyz::ab:c} 0
} {- {$xyz::ab:c} 1 word {$xyz::ab:c} 3 variable {$xyz::ab} 1 text xyz::ab 0 text :c 0 {}}
test parse-12.14 {Tcl_ParseVarName procedure, variable names with many colons} {
    testparser {$xyz:::::c} 0
} {- {$xyz:::::c} 1 word {$xyz:::::c} 2 variable {$xyz:::::c} 1 text xyz:::::c 0 {}}
test parse-12.15 {Tcl_ParseVarName procedure, : vs. ::} {
    testparsevarname {$ab:cd} 0 0
} {- {} 0 variable {$ab} 1 text ab 0 :cd}
test parse-12.16 {Tcl_ParseVarName procedure, eof in ::} {
    testparsevarname {$ab::cd} 4 0
} {- {} 0 variable {$ab} 1 text ab 0 ::cd}
test parse-12.17 {Tcl_ParseVarName procedure, eof in ::} {
    testparsevarname {$ab:::cd} 5 0
} {- {} 0 variable {$ab::} 1 text ab:: 0 :cd}
test parse-12.18 {Tcl_ParseVarName procedure, no variable name} {
    testparser {$$ $.} 0
} {- {$$ $.} 2 word {$$} 2 text {$} 0 text {$} 0 word {$.} 2 text {$} 0 text . 0 {}}
test parse-12.19 {Tcl_ParseVarName procedure, EOF before (} {
    testparsevarname {$ab(cd)} 3 0
} {- {} 0 variable {$ab} 1 text ab 0 (cd)}
test parse-12.20 {Tcl_ParseVarName procedure, array reference} {
    testparser {$x(abc)} 0
} {- {$x(abc)} 1 word {$x(abc)} 3 variable {$x(abc)} 2 text x 0 text abc 0 {}}
test parse-12.21 {Tcl_ParseVarName procedure, array reference} {
    testparser {$x(ab$cde[foo bar])} 0
} {- {$x(ab$cde[foo bar])} 1 word {$x(ab$cde[foo bar])} 6 variable {$x(ab$cde[foo bar])} 5 text x 0 text ab 0 variable {$cde} 1 text cde 0 command {[foo bar]} 0 {}}
test parse-12.22 {Tcl_ParseVarName procedure, array reference} {
    testparser {$x([cmd arg]zz)} 0
} {- {$x([cmd arg]zz)} 1 word {$x([cmd arg]zz)} 4 variable {$x([cmd arg]zz)} 3 text x 0 command {[cmd arg]} 0 text zz 0 {}}
test parse-12.23 {Tcl_ParseVarName procedure, missing close paren in array reference} {
    list [catch {testparser {$x(poiu} 0} msg] $msg $errorInfo
} {1 {missing )} {missing )
    (remainder of script: "(poiu")
    invoked from within
"testparser {$x(poiu} 0"}}
test parse-12.24 {Tcl_ParseVarName procedure, missing close paren in array reference} {
    list [catch {testparsevarname {$ab(cd)} 6 0} msg] $msg $errorInfo
} {1 {missing )} {missing )
    (remainder of script: "(cd)")
    invoked from within
"testparsevarname {$ab(cd)} 6 0"}}
test parse-12.25 {Tcl_ParseVarName procedure, nested array reference} {
    testparser {$x(a$y(b$z))} 0
} {- {$x(a$y(b$z))} 1 word {$x(a$y(b$z))} 8 variable {$x(a$y(b$z))} 7 text x 0 text a 0 variable {$y(b$z)} 4 text y 0 text b 0 variable {$z} 1 text z 0 {}}

test parse-13.1 {Tcl_ParseVar procedure} {
    set abc 24
    testparsevar {$abc.fg}
} {24 .fg}
test parse-13.2 {Tcl_ParseVar procedure, no variable name} {
    testparsevar {$}
} {{$} {}}
test parse-13.3 {Tcl_ParseVar procedure, no variable name} {
    testparsevar {$.123}
} {{$} .123}
test parse-13.4 {Tcl_ParseVar procedure, error looking up variable} {
    catch {unset abc}
    list [catch {testparsevar {$abc}} msg] $msg
} {1 {can't read "abc": no such variable}}
test parse-13.5 {Tcl_ParseVar procedure, error looking up variable} {
    catch {unset abc}
    list [catch {testparsevar {$abc([bogus x y z])}} msg] $msg
} {1 {invalid command name "bogus"}}

test parse-14.1 {Tcl_ParseBraces procedure, computing string length} {
    testparser [bytestring "foo\0 bar"] -1
} {- foo 1 simple foo 1 text foo 0 {}}
test parse-14.2 {Tcl_ParseBraces procedure, computing string length} {
    testparser "foo bar" -1
} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
test parse-14.3 {Tcl_ParseBraces procedure, words in braces} {
    testparser {foo {a $b [concat foo]} {c d}} 0
} {- {foo {a $b [concat foo]} {c d}} 3 simple foo 1 text foo 0 simple {{a $b [concat foo]}} 1 text {a $b [concat foo]} 0 simple {{c d}} 1 text {c d} 0 {}}
test parse-14.4 {Tcl_ParseBraces procedure, empty nested braces} {
    testparser {foo {{}}} 0
} {- {foo {{}}} 2 simple foo 1 text foo 0 simple {{{}}} 1 text {{}} 0 {}}
test parse-14.5 {Tcl_ParseBraces procedure, nested braces} {
    testparser {foo {{a {b} c} {} {d e}}} 0
} {- {foo {{a {b} c} {} {d e}}} 2 simple foo 1 text foo 0 simple {{{a {b} c} {} {d e}}} 1 text {{a {b} c} {} {d e}} 0 {}}
test parse-14.6 {Tcl_ParseBraces procedure, backslashes in words in braces} {
    testparser "foo {a \\n\\\{}" 0
} {- {foo {a \n\{}} 2 simple foo 1 text foo 0 simple {{a \n\{}} 1 text {a \n\{} 0 {}}
test parse-14.7 {Tcl_ParseBraces procedure, missing continuation line in braces} {
    list [catch {testparser "\{abc\\\n" 0} msg] $msg $errorInfo
} {1 {missing close-brace} missing\ close-brace\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\\\n\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\\\{abc\\\\\\n\"\ 0\"}
test parse-14.8 {Tcl_ParseBraces procedure, backslash-newline in braces} {
    testparser "foo {\\\nx}" 0
} {- foo\ \{\\\nx\} 2 simple foo 1 text foo 0 word \{\\\nx\} 2 backslash \\\n 0 text x 0 {}}
test parse-14.9 {Tcl_ParseBraces procedure, backslash-newline in braces} {
    testparser "foo {a \\\n   b}" 0
} {- foo\ \{a\ \\\n\ \ \ b\} 2 simple foo 1 text foo 0 word \{a\ \\\n\ \ \ b\} 3 text {a } 0 backslash \\\n\ \ \  0 text b 0 {}}
test parse-14.10 {Tcl_ParseBraces procedure, backslash-newline in braces} {
    testparser "foo {xyz\\\n }" 0
} {- foo\ \{xyz\\\n\ \} 2 simple foo 1 text foo 0 word \{xyz\\\n\ \} 2 text xyz 0 backslash \\\n\  0 {}}
test parse-14.11 {Tcl_ParseBraces procedure, empty braced string} {
    testparser {foo {}} 0
} {- {foo {}} 2 simple foo 1 text foo 0 simple {{}} 1 text {} 0 {}}
test parse-14.12 {Tcl_ParseBraces procedure, missing close brace} {
    list [catch {testparser "foo \{xy\\\nz" 0} msg] $msg $errorInfo
} {1 {missing close-brace} missing\ close-brace\n\ \ \ \ (remainder\ of\ script:\ \"\{xy\\\nz\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"foo\ \\\{xy\\\\\\nz\"\ 0\"}

test parse-15.1 {Tcl_ParseQuotedString procedure, computing string length} {
    testparser [bytestring "foo\0 bar"] -1
} {- foo 1 simple foo 1 text foo 0 {}}
test parse-15.2 {Tcl_ParseQuotedString procedure, computing string length} {
    testparser "foo bar" -1
} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
test parse-15.3 {Tcl_ParseQuotedString procedure, word is quoted string} {
    testparser {foo "a b c" d "efg";} 0
} {- {foo "a b c" d "efg";} 4 simple foo 1 text foo 0 simple {"a b c"} 1 text {a b c} 0 simple d 1 text d 0 simple {"efg"} 1 text efg 0 {}}
test parse-15.4 {Tcl_ParseQuotedString procedure, garbage after quoted string} {
    list [catch {testparser {foo "a b c"d} 0} msg] $msg $errorInfo
} {1 {extra characters after close-quote} {extra characters after close-quote
    (remainder of script: "d")
    invoked from within
"testparser {foo "a b c"d} 0"}}

test parse-15.5 {CommandComplete procedure} {
    info complete ""
} 1
test parse-15.6 {CommandComplete procedure} {
    info complete "  \n"
} 1
test parse-15.7 {CommandComplete procedure} {
    info complete "abc def"
} 1
test parse-15.8 {CommandComplete procedure} {
    info complete "a b c d e f \t\n"
} 1
test parse-15.9 {CommandComplete procedure} {
    info complete {a b c"d}
} 1
test parse-15.10 {CommandComplete procedure} {
    info complete {a b "c d" e}
} 1
test parse-15.11 {CommandComplete procedure} {
    info complete {a b "c d"}
} 1
test parse-15.12 {CommandComplete procedure} {
    info complete {a b "c d"}
} 1
test parse-15.13 {CommandComplete procedure} {
    info complete {a b "c d}
} 0
test parse-15.14 {CommandComplete procedure} {
    info complete {a b "}
} 0
test parse-15.15 {CommandComplete procedure} {
    info complete {a b "cd"xyz}
} 1
test parse-15.16 {CommandComplete procedure} {
    info complete {a b "c $d() d"}
} 1
test parse-15.17 {CommandComplete procedure} {
    info complete {a b "c $dd("}
} 0
test parse-15.18 {CommandComplete procedure} {
    info complete {a b "c \"}
} 0
test parse-15.19 {CommandComplete procedure} {
    info complete {a b "c [d e f]"}
} 1
test parse-15.20 {CommandComplete procedure} {
    info complete {a b "c [d e f] g"}
} 1
test parse-15.21 {CommandComplete procedure} {
    info complete {a b "c [d e f"}
} 0
test parse-15.22 {CommandComplete procedure} {
    info complete {a {b c d} e}
} 1
test parse-15.23 {CommandComplete procedure} {
    info complete {a {b c d}}
} 1
test parse-15.24 {CommandComplete procedure} {
    info complete "a b\{c d"
} 1
test parse-15.25 {CommandComplete procedure} {
    info complete "a b \{c"
} 0
test parse-15.26 {CommandComplete procedure} {
    info complete "a b \{c{ }"
} 0
test parse-15.27 {CommandComplete procedure} {
    info complete "a b {c d e}xxx"
} 1
test parse-15.28 {CommandComplete procedure} {
    info complete "a b {c \\\{d e}xxx"
} 1
test parse-15.29 {CommandComplete procedure} {
    info complete {a b [ab cd ef]}
} 1
test parse-15.30 {CommandComplete procedure} {
    info complete {a b x[ab][cd][ef] gh}
} 1
test parse-15.31 {CommandComplete procedure} {
    info complete {a b x[ab][cd[ef] gh}
} 0
test parse-15.32 {CommandComplete procedure} {
    info complete {a b x[ gh}
} 0
test parse-15.33 {CommandComplete procedure} {
    info complete {[]]]}
} 1
test parse-15.34 {CommandComplete procedure} {
    info complete {abc x$yyy}
} 1
test parse-15.35 {CommandComplete procedure} {
    info complete "abc x\${abc\[\\d} xyz"
} 1
test parse-15.36 {CommandComplete procedure} {
    info complete "abc x\$\{ xyz"
} 0
test parse-15.37 {CommandComplete procedure} {
    info complete {word $a(xyz)}
} 1
test parse-15.38 {CommandComplete procedure} {
    info complete {word $a(}
} 0
test parse-15.39 {CommandComplete procedure} {
    info complete "set a \\\n"
} 0
test parse-15.40 {CommandComplete procedure} {
    info complete "set a \\\\\n"
} 1
test parse-15.41 {CommandComplete procedure} {
    info complete "set a \\n "
} 1
test parse-15.42 {CommandComplete procedure} {
    info complete "set a \\"
} 1
test parse-15.43 {CommandComplete procedure} {
    info complete "foo \\\n\{"
} 0
test parse-15.44 {CommandComplete procedure} {
    info complete "a\nb\n# \{\n# \{\nc\n"
} 1
test parse-15.45 {CommandComplete procedure} {
    info complete "#Incomplete comment\\\n"
} 0
test parse-15.46 {CommandComplete procedure} {
    info complete "#Incomplete comment\\\nBut now it's complete.\n"
} 1
test parse-15.47 {CommandComplete procedure} {
    info complete "# Complete comment\\\\\n"
} 1
test parse-15.48 {CommandComplete procedure} {
    info complete "abc\\\n def"
} 1
test parse-15.49 {CommandComplete procedure} {
    info complete "abc\\\n "
} 1
test parse-15.50 {CommandComplete procedure} {
    info complete "abc\\\n"
} 0
test parse-15.51 {CommandComplete procedure} "
    info complete \"\\{abc\\}\\{\"
" 1
test parse-15.52 {CommandComplete procedure} {
    info complete "\"abc\"("
} 1
test parse-15.53 {CommandComplete procedure} "
    info complete \" # {\"
" 1
test parse-15.54 {CommandComplete procedure} "
    info complete \"foo bar;# {\"
" 1
test parse-15.55 {CommandComplete procedure} {
    info complete "set x [bytestring \0]; puts hi"
} 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













Added tests/parseExpr.test.



























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































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

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

# Note that the Tcl expression parser (tclParseExpr.c) does not check
# the semantic validity of the expressions it parses. It does not check,
# for example, that a math function actually exists, or that the operands
# of "<<" are integers.

if {[info commands testexprparser] == {}} {
    puts "This application hasn't been compiled with the \"testexprparser\""
    puts "command, so I can't test the Tcl expression parser."
    ::tcltest::cleanupTests
    return 
}

test parseExpr-1.1 {Tcl_ParseExpr procedure, computing string length} {
    testexprparser [bytestring "1+2\0 +3"] -1
} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-1.2 {Tcl_ParseExpr procedure, computing string length} {
    testexprparser "1  + 2" -1
} {- {} 0 subexpr {1  + 2} 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-1.3 {Tcl_ParseExpr procedure, error getting initial lexeme} {nonPortable} {
    list [catch {testexprparser {12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-1.4 {Tcl_ParseExpr procedure, error in conditional expression} {
    list [catch {testexprparser {foo+} -1} msg] $msg
} {1 {syntax error in expression "foo+"}}
test parseExpr-1.5 {Tcl_ParseExpr procedure, lexemes after the expression} {
    list [catch {testexprparser {1+2 345} -1} msg] $msg
} {1 {syntax error in expression "1+2 345"}}

test parseExpr-2.1 {ParseCondExpr procedure, valid test subexpr} {
    testexprparser {2>3? 1 : 0} -1
} {- {} 0 subexpr {2>3? 1 : 0} 11 operator ? 0 subexpr 2>3 5 operator > 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-2.2 {ParseCondExpr procedure, error in test subexpr} {
    list [catch {testexprparser {0 || foo} -1} msg] $msg
} {1 {syntax error in expression "0 || foo"}}
test parseExpr-2.3 {ParseCondExpr procedure, next lexeme isn't "?"} {
    testexprparser {1+2} -1
} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-2.4 {ParseCondExpr procedure, next lexeme is "?"} {
    testexprparser {1+2 ? 3 : 4} -1
} {- {} 0 subexpr {1+2 ? 3 : 4} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-2.5 {ParseCondExpr procedure, bad lexeme after "?"} {nonPortable} {
    list [catch {testexprparser {1+2 ? 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-2.6 {ParseCondExpr procedure, valid "then" subexpression} {
    testexprparser {1? 3 : 4} -1
} {- {} 0 subexpr {1? 3 : 4} 7 operator ? 0 subexpr 1 1 text 1 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-2.7 {ParseCondExpr procedure, error in "then" subexpression} {
    list [catch {testexprparser {1? fred : martha} -1} msg] $msg
} {1 {syntax error in expression "1? fred : martha"}}
test parseExpr-2.8 {ParseCondExpr procedure, lexeme after "then" subexpr isn't ":"} {
    list [catch {testexprparser {1? 2 martha 3} -1} msg] $msg
} {1 {syntax error in expression "1? 2 martha 3"}}
test parseExpr-2.9 {ParseCondExpr procedure, valid "else" subexpression} {
    testexprparser {27||3? 3 : 4&&9} -1
} {- {} 0 subexpr {27||3? 3 : 4&&9} 15 operator ? 0 subexpr 27||3 5 operator || 0 subexpr 27 1 text 27 0 subexpr 3 1 text 3 0 subexpr 3 1 text 3 0 subexpr 4&&9 5 operator && 0 subexpr 4 1 text 4 0 subexpr 9 1 text 9 0 {}}
test parseExpr-2.10 {ParseCondExpr procedure, error in "else" subexpression} {
    list [catch {testexprparser {1? 2 : martha} -1} msg] $msg
} {1 {syntax error in expression "1? 2 : martha"}}

test parseExpr-3.1 {ParseLorExpr procedure, valid logical and subexpr} {
    testexprparser {1&&2 || 3} -1
} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-3.2 {ParseLorExpr procedure, error in logical and subexpr} {
    list [catch {testexprparser {1&&foo || 3} -1} msg] $msg
} {1 {syntax error in expression "1&&foo || 3"}}
test parseExpr-3.3 {ParseLorExpr procedure, next lexeme isn't "||"} {
    testexprparser {1&&2? 1 : 0} -1
} {- {} 0 subexpr {1&&2? 1 : 0} 11 operator ? 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-3.4 {ParseLorExpr procedure, next lexeme is "||"} {
    testexprparser {1&&2 || 3} -1
} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-3.5 {ParseLorExpr procedure, bad lexeme after "||"} {nonPortable} {
    list [catch {testexprparser {1&&2 || 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-3.6 {ParseLorExpr procedure, valid RHS subexpression} {
    testexprparser {1&&2 || 3 || 4} -1
} {- {} 0 subexpr {1&&2 || 3 || 4} 13 operator || 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-3.7 {ParseLorExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {1&&2 || 3 || martha} -1} msg] $msg
} {1 {syntax error in expression "1&&2 || 3 || martha"}}

test parseExpr-4.1 {ParseLandExpr procedure, valid LHS "|" subexpr} {
    testexprparser {1|2 && 3} -1
} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-4.2 {ParseLandExpr procedure, error in LHS "|" subexpr} {
    list [catch {testexprparser {1&&foo && 3} -1} msg] $msg
} {1 {syntax error in expression "1&&foo && 3"}}
test parseExpr-4.3 {ParseLandExpr procedure, next lexeme isn't "&&"} {
    testexprparser {1|2? 1 : 0} -1
} {- {} 0 subexpr {1|2? 1 : 0} 11 operator ? 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-4.4 {ParseLandExpr procedure, next lexeme is "&&"} {
    testexprparser {1|2 && 3} -1
} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-4.5 {ParseLandExpr procedure, bad lexeme after "&&"} {nonPortable} {
    list [catch {testexprparser {1|2 && 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-4.6 {ParseLandExpr procedure, valid RHS subexpression} {
    testexprparser {1|2 && 3 && 4} -1
} {- {} 0 subexpr {1|2 && 3 && 4} 13 operator && 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-4.7 {ParseLandExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {1|2 && 3 && martha} -1} msg] $msg
} {1 {syntax error in expression "1|2 && 3 && martha"}}

test parseExpr-5.1 {ParseBitOrExpr procedure, valid LHS "^" subexpr} {
    testexprparser {1^2 | 3} -1
} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-5.2 {ParseBitOrExpr procedure, error in LHS "^" subexpr} {
    list [catch {testexprparser {1|foo | 3} -1} msg] $msg
} {1 {syntax error in expression "1|foo | 3"}}
test parseExpr-5.3 {ParseBitOrExpr procedure, next lexeme isn't "|"} {
    testexprparser {1^2? 1 : 0} -1
} {- {} 0 subexpr {1^2? 1 : 0} 11 operator ? 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-5.4 {ParseBitOrExpr procedure, next lexeme is "|"} {
    testexprparser {1^2 | 3} -1
} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-5.5 {ParseBitOrExpr procedure, bad lexeme after "|"} {nonPortable} {
    list [catch {testexprparser {1^2 | 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-5.6 {ParseBitOrExpr procedure, valid RHS subexpression} {
    testexprparser {1^2 | 3 | 4} -1
} {- {} 0 subexpr {1^2 | 3 | 4} 13 operator | 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-5.7 {ParseBitOrExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {1^2 | 3 | martha} -1} msg] $msg
} {1 {syntax error in expression "1^2 | 3 | martha"}}

test parseExpr-6.1 {ParseBitXorExpr procedure, valid LHS "&" subexpr} {
    testexprparser {1&2 ^ 3} -1
} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-6.2 {ParseBitXorExpr procedure, error in LHS "&" subexpr} {
    list [catch {testexprparser {1^foo ^ 3} -1} msg] $msg
} {1 {syntax error in expression "1^foo ^ 3"}}
test parseExpr-6.3 {ParseBitXorExpr procedure, next lexeme isn't "^"} {
    testexprparser {1&2? 1 : 0} -1
} {- {} 0 subexpr {1&2? 1 : 0} 11 operator ? 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-6.4 {ParseBitXorExpr procedure, next lexeme is "^"} {
    testexprparser {1&2 ^ 3} -1
} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-6.5 {ParseBitXorExpr procedure, bad lexeme after "^"} {nonPortable} {
    list [catch {testexprparser {1&2 ^ 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-6.6 {ParseBitXorExpr procedure, valid RHS subexpression} {
    testexprparser {1&2 ^ 3 ^ 4} -1
} {- {} 0 subexpr {1&2 ^ 3 ^ 4} 13 operator ^ 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-6.7 {ParseBitXorExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {1&2 ^ 3 ^ martha} -1} msg] $msg
} {1 {syntax error in expression "1&2 ^ 3 ^ martha"}}

test parseExpr-7.1 {ParseBitAndExpr procedure, valid LHS equality subexpr} {
    testexprparser {1==2 & 3} -1
} {- {} 0 subexpr {1==2 & 3} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-7.2 {ParseBitAndExpr procedure, error in LHS equality subexpr} {
    list [catch {testexprparser {1!=foo & 3} -1} msg] $msg
} {1 {syntax error in expression "1!=foo & 3"}}
test parseExpr-7.3 {ParseBitAndExpr procedure, next lexeme isn't "&"} {
    testexprparser {1==2? 1 : 0} -1
} {- {} 0 subexpr {1==2? 1 : 0} 11 operator ? 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-7.4 {ParseBitAndExpr procedure, next lexeme is "&"} {
    testexprparser {1>2 & 3} -1
} {- {} 0 subexpr {1>2 & 3} 9 operator & 0 subexpr 1>2 5 operator > 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-7.5 {ParseBitAndExpr procedure, bad lexeme after "&"} {nonPortable} {
    list [catch {testexprparser {1==2 & 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-7.6 {ParseBitAndExpr procedure, valid RHS subexpression} {
    testexprparser {1<2 & 3 & 4} -1
} {- {} 0 subexpr {1<2 & 3 & 4} 13 operator & 0 subexpr {1<2 & 3} 9 operator & 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-7.7 {ParseBitAndExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {1==2 & 3>2 & martha} -1} msg] $msg
} {1 {syntax error in expression "1==2 & 3>2 & martha"}}

test parseExpr-7.1 {ParseEqualityExpr procedure, valid LHS relational subexpr} {
    testexprparser {1<2 == 3} -1
} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-7.2 {ParseEqualityExpr procedure, error in LHS relational subexpr} {
    list [catch {testexprparser {1>=foo == 3} -1} msg] $msg
} {1 {syntax error in expression "1>=foo == 3"}}
test parseExpr-7.3 {ParseEqualityExpr procedure, next lexeme isn't "==" or "!="} {
    testexprparser {1<2? 1 : 0} -1
} {- {} 0 subexpr {1<2? 1 : 0} 11 operator ? 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-7.4 {ParseEqualityExpr procedure, next lexeme is "==" or "!=} {
    testexprparser {1<2 == 3} -1
} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-7.5 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} {
    testexprparser {1<2 != 3} -1
} {- {} 0 subexpr {1<2 != 3} 9 operator != 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-7.6 {ParseEqualityExpr procedure, bad lexeme after "==" or "!="} {nonPortable} {
    list [catch {testexprparser {1<2 == 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-7.7 {ParseEqualityExpr procedure, valid RHS subexpression} {
    testexprparser {1<2 == 3 == 4} -1
} {- {} 0 subexpr {1<2 == 3 == 4} 13 operator == 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-7.8 {ParseEqualityExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {1<2 == 3 != martha} -1} msg] $msg
} {1 {syntax error in expression "1<2 == 3 != martha"}}

test parseExpr-8.1 {ParseRelationalExpr procedure, valid LHS shift subexpr} {
    testexprparser {1<<2 < 3} -1
} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.2 {ParseRelationalExpr procedure, error in LHS shift subexpr} {
    list [catch {testexprparser {1>=foo < 3} -1} msg] $msg
} {1 {syntax error in expression "1>=foo < 3"}}
test parseExpr-8.3 {ParseRelationalExpr procedure, next lexeme isn't relational op} {
    testexprparser {1<<2? 1 : 0} -1
} {- {} 0 subexpr {1<<2? 1 : 0} 11 operator ? 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-8.4 {ParseRelationalExpr procedure, next lexeme is relational op} {
    testexprparser {1<<2 < 3} -1
} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.5 {ParseRelationalExpr procedure, next lexeme is relational op} {
    testexprparser {1>>2 > 3} -1
} {- {} 0 subexpr {1>>2 > 3} 9 operator > 0 subexpr 1>>2 5 operator >> 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.6 {ParseRelationalExpr procedure, next lexeme is relational op} {
    testexprparser {1<<2 <= 3} -1
} {- {} 0 subexpr {1<<2 <= 3} 9 operator <= 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.7 {ParseRelationalExpr procedure, next lexeme is relational op} {
    testexprparser {1<<2 >= 3} -1
} {- {} 0 subexpr {1<<2 >= 3} 9 operator >= 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-8.8 {ParseRelationalExpr procedure, bad lexeme after relational op} {nonPortable} {
    list [catch {testexprparser {1<<2 < 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-8.9 {ParseRelationalExpr procedure, valid RHS subexpression} {
    testexprparser {1<<2 < 3 < 4} -1
} {- {} 0 subexpr {1<<2 < 3 < 4} 13 operator < 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-8.8 {ParseRelationalExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {1<<2 < 3 > martha} -1} msg] $msg
} {1 {syntax error in expression "1<<2 < 3 > martha"}}

test parseExpr-9.1 {ParseShiftExpr procedure, valid LHS add subexpr} {
    testexprparser {1+2 << 3} -1
} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-9.2 {ParseShiftExpr procedure, error in LHS add subexpr} {
    list [catch {testexprparser {1-foo << 3} -1} msg] $msg
} {1 {syntax error in expression "1-foo << 3"}}
test parseExpr-9.3 {ParseShiftExpr procedure, next lexeme isn't "<<" or ">>"} {
    testexprparser {1+2? 1 : 0} -1
} {- {} 0 subexpr {1+2? 1 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-9.4 {ParseShiftExpr procedure, next lexeme is "<<" or ">>} {
    testexprparser {1+2 << 3} -1
} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-9.5 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} {
    testexprparser {1+2 >> 3} -1
} {- {} 0 subexpr {1+2 >> 3} 9 operator >> 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-9.6 {ParseShiftExpr procedure, bad lexeme after "<<" or ">>"} {nonPortable} {
    list [catch {testexprparser {1+2 << 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-9.7 {ParseShiftExpr procedure, valid RHS subexpression} {
    testexprparser {1+2 << 3 << 4} -1
} {- {} 0 subexpr {1+2 << 3 << 4} 13 operator << 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-9.8 {ParseShiftExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {1+2 << 3 >> martha} -1} msg] $msg
} {1 {syntax error in expression "1+2 << 3 >> martha"}}

test parseExpr-10.1 {ParseAddExpr procedure, valid LHS multiply subexpr} {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.2 {ParseAddExpr procedure, error in LHS multiply subexpr} {
    list [catch {testexprparser {1/foo + 3} -1} msg] $msg
} {1 {syntax error in expression "1/foo + 3"}}
test parseExpr-10.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} {
    testexprparser {1*2? 1 : 0} -1
} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-10.4 {ParseAddExpr procedure, next lexeme is "+" or "-} {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} {
    testexprparser {1*2 - 3} -1
} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} {nonPortable} {
    list [catch {testexprparser {1*2 + 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-10.7 {ParseAddExpr procedure, valid RHS subexpression} {
    testexprparser {1*2 + 3 + 4} -1
} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-10.8 {ParseAddExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {1*2 + 3 - martha} -1} msg] $msg
} {1 {syntax error in expression "1*2 + 3 - martha"}}

test parseExpr-10.1 {ParseAddExpr procedure, valid LHS multiply subexpr} {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.2 {ParseAddExpr procedure, error in LHS multiply subexpr} {
    list [catch {testexprparser {1/foo + 3} -1} msg] $msg
} {1 {syntax error in expression "1/foo + 3"}}
test parseExpr-10.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} {
    testexprparser {1*2? 1 : 0} -1
} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-10.4 {ParseAddExpr procedure, next lexeme is "+" or "-} {
    testexprparser {1*2 + 3} -1
} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} {
    testexprparser {1*2 - 3} -1
} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-10.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} {nonPortable} {
    list [catch {testexprparser {1*2 + 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-10.7 {ParseAddExpr procedure, valid RHS subexpression} {
    testexprparser {1*2 + 3 + 4} -1
} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-10.8 {ParseAddExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {1*2 + 3 - martha} -1} msg] $msg
} {1 {syntax error in expression "1*2 + 3 - martha"}}

test parseExpr-11.1 {ParseMultiplyExpr procedure, valid LHS unary subexpr} {
    testexprparser {+2 * 3} -1
} {- {} 0 subexpr {+2 * 3} 7 operator * 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-11.2 {ParseMultiplyExpr procedure, error in LHS unary subexpr} {nonPortable} {
    list [catch {testexprparser {-12345678901234567890 * 3} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-11.3 {ParseMultiplyExpr procedure, next lexeme isn't "*", "/", or "%"} {
    testexprparser {+2? 1 : 0} -1
} {- {} 0 subexpr {+2? 1 : 0} 9 operator ? 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-11.4 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} {
    testexprparser {-123 * 3} -1
} {- {} 0 subexpr {-123 * 3} 7 operator * 0 subexpr -123 3 operator - 0 subexpr 123 1 text 123 0 subexpr 3 1 text 3 0 {}}
test parseExpr-11.5 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} {
    testexprparser {+-456 / 3} -1
} {- {} 0 subexpr {+-456 / 3} 9 operator / 0 subexpr +-456 5 operator + 0 subexpr -456 3 operator - 0 subexpr 456 1 text 456 0 subexpr 3 1 text 3 0 {}}
test parseExpr-11.6 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} {
    testexprparser {+-456 % 3} -1
} {- {} 0 subexpr {+-456 % 3} 9 operator % 0 subexpr +-456 5 operator + 0 subexpr -456 3 operator - 0 subexpr 456 1 text 456 0 subexpr 3 1 text 3 0 {}}
test parseExpr-11.7 {ParseMultiplyExpr procedure, bad lexeme after "*", "/", or "%"} {nonPortable} {
    list [catch {testexprparser {--++5 / 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-11.8 {ParseMultiplyExpr procedure, valid RHS subexpression} {
    testexprparser {-2 / 3 % 4} -1
} {- {} 0 subexpr {-2 / 3 % 4} 11 operator % 0 subexpr {-2 / 3} 7 operator / 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
test parseExpr-11.9 {ParseMultiplyExpr procedure, error in RHS subexpression} {
    list [catch {testexprparser {++2 / 3 * martha} -1} msg] $msg
} {1 {syntax error in expression "++2 / 3 * martha"}}

test parseExpr-12.1 {ParseUnaryExpr procedure, first token is unary operator} {
    testexprparser {+2} -1
} {- {} 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 {}}
test parseExpr-12.2 {ParseUnaryExpr procedure, first token is unary operator} {
    testexprparser {-2} -1
} {- {} 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 {}}
test parseExpr-12.3 {ParseUnaryExpr procedure, first token is unary operator} {
    testexprparser {~2} -1
} {- {} 0 subexpr ~2 3 operator ~ 0 subexpr 2 1 text 2 0 {}}
test parseExpr-12.4 {ParseUnaryExpr procedure, first token is unary operator} {
    testexprparser {!2} -1
} {- {} 0 subexpr !2 3 operator ! 0 subexpr 2 1 text 2 0 {}}
test parseExpr-12.5 {ParseUnaryExpr procedure, error in lexeme after unary op} {nonPortable} {
    list [catch {testexprparser {-12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-12.6 {ParseUnaryExpr procedure, simple unary expr after unary op} {
    testexprparser {+"1234"} -1
} {- {} 0 subexpr +\"1234\" 3 operator + 0 subexpr {"1234"} 1 text 1234 0 {}}
test parseExpr-12.7 {ParseUnaryExpr procedure, another unary expr after unary op} {
    testexprparser {~!{fred}} -1
} {- {} 0 subexpr ~!{fred} 5 operator ~ 0 subexpr !{fred} 3 operator ! 0 subexpr {{fred}} 1 text fred 0 {}}
test parseExpr-12.8 {ParseUnaryExpr procedure, error in unary expr after unary op} {
    list [catch {testexprparser {+-||27} -1} msg] $msg
} {1 {syntax error in expression "+-||27"}}
test parseExpr-12.9 {ParseUnaryExpr procedure, error in unary expr after unary op} {
    list [catch {testexprparser {+-||27} -1} msg] $msg
} {1 {syntax error in expression "+-||27"}}
test parseExpr-12.10 {ParseUnaryExpr procedure, first token is not unary op} {
    testexprparser {123} -1
} {- {} 0 subexpr 123 1 text 123 0 {}}
test parseExpr-12.11 {ParseUnaryExpr procedure, not unary expr, complex primary expr} {
    testexprparser {(1+2)} -1
} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-12.12 {ParseUnaryExpr procedure, not unary expr, error in primary expr} {nonPortable} {
    list [catch {testexprparser {(12345678901234567890)} -1} msg] $msg
} {1 {integer value too large to represent}}

test parseExpr-13.1 {ParsePrimaryExpr procedure, just parenthesized subexpr} {
    testexprparser {({abc}/{def})} -1
} {- {} 0 subexpr {{abc}/{def}} 5 operator / 0 subexpr {{abc}} 1 text abc 0 subexpr {{def}} 1 text def 0 {}}
test parseExpr-13.2 {ParsePrimaryExpr procedure, bad lexeme after "("} {nonPortable} {
    list [catch {testexprparser {(12345678901234567890)} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-13.3 {ParsePrimaryExpr procedure, valid parenthesized subexpr} {
    testexprparser {({abc}? 2*4 : -6)} -1
} {- {} 0 subexpr {{abc}? 2*4 : -6} 13 operator ? 0 subexpr {{abc}} 1 text abc 0 subexpr 2*4 5 operator * 0 subexpr 2 1 text 2 0 subexpr 4 1 text 4 0 subexpr -6 3 operator - 0 subexpr 6 1 text 6 0 {}}
test parseExpr-13.4 {ParsePrimaryExpr procedure, error in parenthesized subexpr} {
    list [catch {testexprparser {(? 123 : 456)} -1} msg] $msg
} {1 {syntax error in expression "(? 123 : 456)"}}
test parseExpr-13.5 {ParsePrimaryExpr procedure, missing ")" after in parenthesized subexpr} {
    list [catch {testexprparser {({abc}/{def}} -1} msg] $msg
} {1 {syntax error in expression "({abc}/{def}"}}
test parseExpr-13.6 {ParsePrimaryExpr procedure, primary is literal} {
    testexprparser {12345} -1
} {- {} 0 subexpr 12345 1 text 12345 0 {}}
test parseExpr-13.7 {ParsePrimaryExpr procedure, primary is literal} {
    testexprparser {12345.6789} -1
} {- {} 0 subexpr 12345.6789 1 text 12345.6789 0 {}}
test parseExpr-13.8 {ParsePrimaryExpr procedure, primary is var reference} {
    testexprparser {$a} -1
} {- {} 0 subexpr {$a} 2 variable {$a} 1 text a 0 {}}
test parseExpr-13.9 {ParsePrimaryExpr procedure, primary is var reference} {
    testexprparser {$a(hello$there)} -1
} {- {} 0 subexpr {$a(hello$there)} 5 variable {$a(hello$there)} 4 text a 0 text hello 0 variable {$there} 1 text there 0 {}}
test parseExpr-13.10 {ParsePrimaryExpr procedure, primary is var reference} {
    testexprparser {$a()} -1
} {- {} 0 subexpr {$a()} 3 variable {$a()} 2 text a 0 text {} 0 {}}
test parseExpr-13.11 {ParsePrimaryExpr procedure, error in var reference} {
    list [catch {testexprparser {$a(} -1} msg] $msg
} {1 {missing )}}
test parseExpr-13.12 {ParsePrimaryExpr procedure, primary is quoted string} {
    testexprparser {"abc $xyz def"} -1
} {- {} 0 subexpr {"abc $xyz def"} 5 word {"abc $xyz def"} 4 text {abc } 0 variable {$xyz} 1 text xyz 0 text { def} 0 {}}
test parseExpr-13.13 {ParsePrimaryExpr procedure, error in quoted string} {
    list [catch {testexprparser {"$a(12"} -1} msg] $msg
} {1 {missing )}}
test parseExpr-13.14 {ParsePrimaryExpr procedure, quoted string has multiple tokens} {
    testexprparser {"abc [xyz] $def"} -1
} {- {} 0 subexpr {"abc [xyz] $def"} 6 word {"abc [xyz] $def"} 5 text {abc } 0 command {[xyz]} 0 text { } 0 variable {$def} 1 text def 0 {}}
test parseExpr-13.15 {ParsePrimaryExpr procedure, primary is command} {
    testexprparser {[def]} -1
} {- {} 0 subexpr {[def]} 1 command {[def]} 0 {}}
test parseExpr-13.16 {ParsePrimaryExpr procedure, primary is multiple commands} {
    testexprparser {[one; two; three; four;]} -1
} {- {} 0 subexpr {[one; two; three; four;]} 1 command {[one; two; three; four;]} 0 {}}
test parseExpr-13.17 {ParsePrimaryExpr procedure, primary is multiple commands} {
    testexprparser {[one; two; three; four;]} -1
} {- {} 0 subexpr {[one; two; three; four;]} 1 command {[one; two; three; four;]} 0 {}}
test parseExpr-13.18 {ParsePrimaryExpr procedure, missing close bracket} {
    list [catch {testexprparser {[one} -1} msg] $msg
} {1 {missing close-bracket}}
test parseExpr-13.19 {ParsePrimaryExpr procedure, primary is braced string} {
    testexprparser {{hello world}} -1
} {- {} 0 subexpr {{hello world}} 1 text {hello world} 0 {}}
test parseExpr-13.20 {ParsePrimaryExpr procedure, error in primary, which is braced string} {
    list [catch {testexprparser "\{abc\\\n" -1} msg] $msg
} {1 {missing close-brace}}
test parseExpr-13.21 {ParsePrimaryExpr procedure, primary is braced string with multiple tokens} {
    testexprparser "\{  \\
 +123 \}" -1
} {- {} 0 subexpr \{\ \ \\\n\ +123\ \} 4 word \{\ \ \\\n\ +123\ \} 3 text {  } 0 backslash \\\n\  0 text {+123 } 0 {}}
test parseExpr-13.22 {ParsePrimaryExpr procedure, primary is function call} {
    testexprparser {foo(123)} -1
} {- {} 0 subexpr foo(123) 3 operator foo 0 subexpr 123 1 text 123 0 {}}
test parseExpr-13.23 {ParsePrimaryExpr procedure, bad lexeme after function name} {nonPortable} {
    list [catch {testexprparser {foo 12345678901234567890 123)} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-13.24 {ParsePrimaryExpr procedure, lexeme after function name isn't "("} {
    list [catch {testexprparser {foo 27.4 123)} -1} msg] $msg
} {1 {syntax error in expression "foo 27.4 123)"}}
test parseExpr-13.25 {ParsePrimaryExpr procedure, bad lexeme after "("} {nonPortable} {
    list [catch {testexprparser {foo(12345678901234567890)} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-13.26 {ParsePrimaryExpr procedure, function call, one arg} {
    testexprparser {foo(27*4)} -1
} {- {} 0 subexpr foo(27*4) 7 operator foo 0 subexpr 27*4 5 operator * 0 subexpr 27 1 text 27 0 subexpr 4 1 text 4 0 {}}
test parseExpr-13.27 {ParsePrimaryExpr procedure, error in function arg} {
    list [catch {testexprparser {foo(*1-2)} -1} msg] $msg
} {1 {syntax error in expression "foo(*1-2)"}}
test parseExpr-13.28 {ParsePrimaryExpr procedure, error in function arg} {
    list [catch {testexprparser {foo(*1-2)} -1} msg] $msg
} {1 {syntax error in expression "foo(*1-2)"}}
test parseExpr-13.29 {ParsePrimaryExpr procedure, function call, comma after arg} {
    testexprparser {foo(27-2, (-2*[foo]))} -1
} {- {} 0 subexpr {foo(27-2, (-2*[foo]))} 15 operator foo 0 subexpr 27-2 5 operator - 0 subexpr 27 1 text 27 0 subexpr 2 1 text 2 0 subexpr {-2*[foo]} 7 operator * 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 subexpr {[foo]} 1 command {[foo]} 0 {}}
test parseExpr-13.30 {ParsePrimaryExpr procedure, bad lexeme after comma} {nonPortable} {
    list [catch {testexprparser {foo(123, 12345678901234567890)} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-13.31 {ParsePrimaryExpr procedure, lexeme not "," or ")" after arg} {
    list [catch {testexprparser {foo(123 [foo])} -1} msg] $msg
} {1 {syntax error in expression "foo(123 [foo])"}}
test parseExpr-13.32 {ParsePrimaryExpr procedure, bad lexeme after primary} {nonPortable} {
    list [catch {testexprparser {123 12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}

test parseExpr-14.1 {GetLexeme procedure, whitespace before lexeme} {
    testexprparser {   123} -1
} {- {} 0 subexpr 123 1 text 123 0 {}}
test parseExpr-14.2 {GetLexeme procedure, whitespace before lexeme} {
    testexprparser {  \
456} -1
} {- {} 0 subexpr 456 1 text 456 0 {}}
test parseExpr-14.3 {GetLexeme procedure, no lexeme after whitespace} {
    testexprparser { 123 \
   } -1
} {- {} 0 subexpr 123 1 text 123 0 {}}
test parseExpr-14.4 {GetLexeme procedure, integer lexeme} {
    testexprparser {000} -1
} {- {} 0 subexpr 000 1 text 000 0 {}}
test parseExpr-14.5 {GetLexeme procedure, integer lexeme too big} {nonPortable} {
    list [catch {testexprparser {12345678901234567890} -1} msg] $msg
} {1 {integer value too large to represent}}
test parseExpr-14.6 {GetLexeme procedure, bad integer lexeme} {
    list [catch {testexprparser {0999} -1} msg] $msg
} {1 {syntax error in expression "0999"}}
test parseExpr-14.7 {GetLexeme procedure, double lexeme} {
    testexprparser {0.999} -1
} {- {} 0 subexpr 0.999 1 text 0.999 0 {}}
test parseExpr-14.8 {GetLexeme procedure, double lexeme} {
    testexprparser {.123} -1
} {- {} 0 subexpr .123 1 text .123 0 {}}
test parseExpr-14.9 {GetLexeme procedure, double lexeme} {nonPortable unixOnly} {
    testexprparser {nan} -1
} {- {} 0 subexpr nan 1 text nan 0 {}}
test parseExpr-14.10 {GetLexeme procedure, double lexeme} {nonPortable unixOnly} {
    testexprparser {NaN} -1
} {- {} 0 subexpr NaN 1 text NaN 0 {}}
test parseExpr-14.11 {GetLexeme procedure, bad double lexeme too big} {
    list [catch {testexprparser {123.e+99999999999999} -1} msg] $msg
} {1 {floating-point value too large to represent}}
test parseExpr-14.12 {GetLexeme procedure, bad double lexeme} {
    list [catch {testexprparser {123.4x56} -1} msg] $msg
} {1 {syntax error in expression "123.4x56"}}
test parseExpr-14.13 {GetLexeme procedure, lexeme is "["} {
    testexprparser {[foo]} -1
} {- {} 0 subexpr {[foo]} 1 command {[foo]} 0 {}}
test parseExpr-14.14 {GetLexeme procedure, lexeme is open brace} {
    testexprparser {{bar}} -1
} {- {} 0 subexpr {{bar}} 1 text bar 0 {}}
test parseExpr-14.15 {GetLexeme procedure, lexeme is "("} {
    testexprparser {(123)} -1
} {- {} 0 subexpr 123 1 text 123 0 {}}
test parseExpr-14.16 {GetLexeme procedure, lexeme is ")"} {
    testexprparser {(2*3)} -1
} {- {} 0 subexpr 2*3 5 operator * 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.17 {GetLexeme procedure, lexeme is "$"} {
    testexprparser {$wombat} -1
} {- {} 0 subexpr {$wombat} 2 variable {$wombat} 1 text wombat 0 {}}
test parseExpr-14.18 {GetLexeme procedure, lexeme is '"'} {
    testexprparser {"fred"} -1
} {- {} 0 subexpr {"fred"} 1 text fred 0 {}}
test parseExpr-14.19 {GetLexeme procedure, lexeme is ","} {
    testexprparser {foo(1,2)} -1
} {- {} 0 subexpr foo(1,2) 5 operator foo 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-14.20 {GetLexeme procedure, lexeme is "*"} {
    testexprparser {$a*$b} -1
} {- {} 0 subexpr {$a*$b} 7 operator * 0 subexpr {$a} 2 variable {$a} 1 text a 0 subexpr {$b} 2 variable {$b} 1 text b 0 {}}
test parseExpr-14.21 {GetLexeme procedure, lexeme is "/"} {
    testexprparser {5/6} -1
} {- {} 0 subexpr 5/6 5 operator / 0 subexpr 5 1 text 5 0 subexpr 6 1 text 6 0 {}}
test parseExpr-14.22 {GetLexeme procedure, lexeme is "%"} {
    testexprparser {5%[xxx]} -1
} {- {} 0 subexpr {5%[xxx]} 5 operator % 0 subexpr 5 1 text 5 0 subexpr {[xxx]} 1 command {[xxx]} 0 {}}
test parseExpr-14.23 {GetLexeme procedure, lexeme is "+"} {
    testexprparser {1+2} -1
} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-14.24 {GetLexeme procedure, lexeme is "-"} {
    testexprparser {.12-0e27} -1
} {- {} 0 subexpr .12-0e27 5 operator - 0 subexpr .12 1 text .12 0 subexpr 0e27 1 text 0e27 0 {}}
test parseExpr-14.25 {GetLexeme procedure, lexeme is "?" or ":"} {
    testexprparser {$b? 1 : 0} -1
} {- {} 0 subexpr {$b? 1 : 0} 8 operator ? 0 subexpr {$b} 2 variable {$b} 1 text b 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
test parseExpr-14.26 {GetLexeme procedure, lexeme is "<"} {
    testexprparser {2<3} -1
} {- {} 0 subexpr 2<3 5 operator < 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.27 {GetLexeme procedure, lexeme is "<<"} {
    testexprparser {2<<3} -1
} {- {} 0 subexpr 2<<3 5 operator << 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.28 {GetLexeme procedure, lexeme is "<="} {
    testexprparser {2<=3} -1
} {- {} 0 subexpr 2<=3 5 operator <= 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.29 {GetLexeme procedure, lexeme is ">"} {
    testexprparser {2>3} -1
} {- {} 0 subexpr 2>3 5 operator > 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.30 {GetLexeme procedure, lexeme is ">>"} {
    testexprparser {2>>3} -1
} {- {} 0 subexpr 2>>3 5 operator >> 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.31 {GetLexeme procedure, lexeme is ">="} {
    testexprparser {2>=3} -1
} {- {} 0 subexpr 2>=3 5 operator >= 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.32 {GetLexeme procedure, lexeme is "=="} {
    testexprparser {2==3} -1
} {- {} 0 subexpr 2==3 5 operator == 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.33 {GetLexeme procedure, bad lexeme starting with "="} {
    list [catch {testexprparser {2=+3} -1} msg] $msg
} {1 {syntax error in expression "2=+3"}}
test parseExpr-14.34 {GetLexeme procedure, lexeme is "!="} {
    testexprparser {2!=3} -1
} {- {} 0 subexpr 2!=3 5 operator != 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.35 {GetLexeme procedure, lexeme is "!"} {
    testexprparser {!2} -1
} {- {} 0 subexpr !2 3 operator ! 0 subexpr 2 1 text 2 0 {}}
test parseExpr-14.36 {GetLexeme procedure, lexeme is "&&"} {
    testexprparser {2&&3} -1
} {- {} 0 subexpr 2&&3 5 operator && 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.37 {GetLexeme procedure, lexeme is "&"} {
    testexprparser {1&2} -1
} {- {} 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-14.38 {GetLexeme procedure, lexeme is "^"} {
    testexprparser {1^2} -1
} {- {} 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-14.39 {GetLexeme procedure, lexeme is "||"} {
    testexprparser {2||3} -1
} {- {} 0 subexpr 2||3 5 operator || 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.40 {GetLexeme procedure, lexeme is "|"} {
    testexprparser {1|2} -1
} {- {} 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
test parseExpr-14.41 {GetLexeme procedure, lexeme is "~"} {
    testexprparser {~2} -1
} {- {} 0 subexpr ~2 3 operator ~ 0 subexpr 2 1 text 2 0 {}}
test parseExpr-14.42 {GetLexeme procedure, lexeme is func name} {
    testexprparser {george()} -1
} {- {} 0 subexpr george() 1 operator george 0 {}}
test parseExpr-14.43 {GetLexeme procedure, lexeme is func name} {
    testexprparser {harmonic_ratio(2,3)} -1
} {- {} 0 subexpr harmonic_ratio(2,3) 5 operator harmonic_ratio 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
test parseExpr-14.44 {GetLexeme procedure, unknown lexeme} {
    list [catch {testexprparser {@27} -1} msg] $msg
} {1 {syntax error in expression "@27"}}

test parseExpr-15.1 {PrependSubExprTokens procedure, expand token array} {
    testexprparser {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} -1
} {- {} 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 13 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 9 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 5 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 {}}

test parse-16.1 {LogSyntaxError procedure, error in expr longer than 60 chars} {
    list [catch {testexprparser {(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)/} -1} msg] $msg
} {1 {syntax error in expression "(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+012"}}

# cleanup
::tcltest::cleanupTests
return












Added tests/parseOld.test.





































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































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

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

proc fourArgs {a b c d} {
    global arg1 arg2 arg3 arg4
    set arg1 $a
    set arg2 $b
    set arg3 $c
    set arg4 $d
}

proc getArgs args {
    global argv
    set argv $args
}

# Basic argument parsing.

test parseOld-1.1 {basic argument parsing} {
    set arg1 {}
    fourArgs a b	c 		 d
    list $arg1 $arg2 $arg3 $arg4
} {a b c d}
test parseOld-1.2 {basic argument parsing} {
    set arg1 {}
    eval "fourArgs 123\v4\f56\r7890"
    list $arg1 $arg2 $arg3 $arg4
} {123 4 56 7890}

# Quotes.

test parseOld-2.1 {quotes and variable-substitution} {
    getArgs "a b c" d
    set argv
} {{a b c} d}
test parseOld-2.2 {quotes and variable-substitution} {
    set a 101
    getArgs "a$a b c"
    set argv
} {{a101 b c}}
test parseOld-2.3 {quotes and variable-substitution} {
    set argv "xy[format xabc]"
    set argv
} {xyxabc}
test parseOld-2.4 {quotes and variable-substitution} {
    set argv "xy\t"
    set argv
} xy\t
test parseOld-2.5 {quotes and variable-substitution} {
    set argv "a b	c
d e f"
    set argv
} a\ b\tc\nd\ e\ f
test parseOld-2.6 {quotes and variable-substitution} {
    set argv a"bcd"e
    set argv
} {a"bcd"e}

# Braces.

test parseOld-3.1 {braces} {
    getArgs {a b c} d
    set argv
} "{a b c} d"
test parseOld-3.2 {braces} {
    set a 101
    set argv {a$a b c}
    set b [string index $argv 1]
    set b
} {$}
test parseOld-3.3 {braces} {
    set argv {a[format xyz] b}
    string length $argv
} 15
test parseOld-3.4 {braces} {
    set argv {a\nb\}}
    string length $argv
} 6
test parseOld-3.5 {braces} {
    set argv {{{{}}}}
    set argv
} "{{{}}}"
test parseOld-3.6 {braces} {
    set argv a{{}}b
    set argv
} "a{{}}b"
test parseOld-3.7 {braces} {
    set a [format "last]"]
    set a
} {last]}

# Command substitution.

test parseOld-4.1 {command substitution} {
    set a [format xyz]
    set a
} xyz
test parseOld-4.2 {command substitution} {
    set a a[format xyz]b[format q]
    set a
} axyzbq
test parseOld-4.3 {command substitution} {
    set a a[
set b 22;
format %s $b

]b
    set a
} a22b
test parseOld-4.4 {command substitution} {
    set a 7.7
    if [catch {expr int($a)}] {set a foo}
    set a
} 7.7

# Variable substitution.

test parseOld-5.1 {variable substitution} {
    set a 123
    set b $a
    set b
} 123
test parseOld-5.2 {variable substitution} {
    set a 345
    set b x$a.b
    set b
} x345.b
test parseOld-5.3 {variable substitution} {
    set _123z xx
    set b $_123z^
    set b
} xx^
test parseOld-5.4 {variable substitution} {
    set a 78
    set b a${a}b
    set b
} a78b
test parseOld-5.5 {variable substitution} {catch {$_non_existent_} msg} 1
test parseOld-5.6 {variable substitution} {
    catch {$_non_existent_} msg
    set msg
} {can't read "_non_existent_": no such variable}
test parseOld-5.7 {array variable substitution} {
    catch {unset a}
    set a(xyz) 123
    set b $a(xyz)foo
    set b
} 123foo
test parseOld-5.8 {array variable substitution} {
    catch {unset a}
    set "a(x y z)" 123
    set b $a(x y z)foo
    set b
} 123foo
test parseOld-5.9 {array variable substitution} {
    catch {unset a}; catch {unset qqq}
    set "a(x y z)" qqq
    set $a([format x]\ y [format z]) foo
    set qqq
} foo
test parseOld-5.10 {array variable substitution} {
    catch {unset a}
    list [catch {set b $a(22)} msg] $msg
} {1 {can't read "a(22)": no such variable}}
test parseOld-5.11 {array variable substitution} {
    set b a$!
    set b
} {a$!}
test parseOld-5.12 {array variable substitution} {
    set b a$()
    set b
} {a$()}
catch {unset a}
test parseOld-5.13 {array variable substitution} {
    catch {unset a}
    set long {This is a very long variable, long enough to cause storage \
	allocation to occur in Tcl_ParseVar.  If that storage isn't getting \
	freed up correctly, then a core leak will occur when this test is \
	run.  This text is probably beginning to sound like drivel, but I've \
	run out of things to say and I need more characters still.}
    set a($long) 777
    set b $a($long)
    list $b [array names a]
} {777 {{This is a very long variable, long enough to cause storage \
	allocation to occur in Tcl_ParseVar.  If that storage isn't getting \
	freed up correctly, then a core leak will occur when this test is \
	run.  This text is probably beginning to sound like drivel, but I've \
	run out of things to say and I need more characters still.}}}
test parseOld-5.14 {array variable substitution} {
    catch {unset a}; catch {unset b}; catch {unset a1}
    set a1(22) foo
    set a(foo) bar
    set b $a($a1(22))
    set b
} bar
catch {unset a}; catch {unset a1}

test parseOld-7.1 {backslash substitution} {
    set a "\a\c\n\]\}"
    string length $a
} 5
test parseOld-7.2 {backslash substitution} {
    set a {\a\c\n\]\}}
    string length $a
} 10
test parseOld-7.3 {backslash substitution} {
    set a "abc\
def"
    set a
} {abc def}
test parseOld-7.4 {backslash substitution} {
    set a {abc\
def}
    set a
} {abc def}
test parseOld-7.5 {backslash substitution} {
    set msg {}
    set a xxx
    set error [catch {if {24 < \
	35} {set a 22} {set \
	    a 33}} msg]
    list $error $msg $a
} {0 22 22}
test parseOld-7.6 {backslash substitution} {
    eval "concat abc\\"
} "abc\\"
test parseOld-7.7 {backslash substitution} {
    eval "concat \\\na"
} "a"
test parseOld-7.8 {backslash substitution} {
    eval "concat x\\\n   	a"
} "x a"
test parseOld-7.9 {backslash substitution} {
    eval "concat \\x"
} "x"
test parseOld-7.10 {backslash substitution} {
    eval "list a b\\\nc d"
} {a b c d}
test parseOld-7.11 {backslash substitution} {
    eval "list a \"b c\"\\\nd e"
} {a {b c} d e}
test parseOld-7.12 {backslash substitution} {
    list \ua2
} [bytestring "\xc2\xa2"]
test parseOld-7.13 {backslash substitution} {
    list \u4e21
} [bytestring "\xe4\xb8\xa1"]
test parseOld-7.14 {backslash substitution} {
    list \u4e2k
} [bytestring "\xd3\xa2k"]

# Semi-colon.

test parseOld-8.1 {semi-colons} {
    set b 0
    getArgs a;set b 2
    set argv
} a
test parseOld-8.2 {semi-colons} {
    set b 0
    getArgs a;set b 2
    set b
} 2
test parseOld-8.3 {semi-colons} {
    getArgs a b ; set b 1
    set argv
} {a b}
test parseOld-8.4 {semi-colons} {
    getArgs a b ; set b 1
    set b
} 1

# The following checks are to ensure that the interpreter's result
# gets re-initialized by Tcl_Eval in all the right places.

test parseOld-9.1 {result initialization} {concat abc} abc
test parseOld-9.2 {result initialization} {concat abc; proc foo {} {}} {}
test parseOld-9.3 {result initialization} {concat abc; proc foo {} $a} {}
test parseOld-9.4 {result initialization} {proc foo {} [concat abc]} {}
test parseOld-9.5 {result initialization} {concat abc; } abc
test parseOld-9.6 {result initialization} {
    eval {
    concat abc
}} abc
test parseOld-9.7 {result initialization} {} {}
test parseOld-9.8 {result initialization} {concat abc; ; ;} abc

# Syntax errors.

test parseOld-10.1 {syntax errors} {catch "set a \{bcd" msg} 1
test parseOld-10.2 {syntax errors} {
	catch "set a \{bcd" msg
	set msg
} {missing close-brace}
test parseOld-10.3 {syntax errors} {catch {set a "bcd} msg} 1
test parseOld-10.4 {syntax errors} {
	catch {set a "bcd} msg
	set msg
} {missing "}
test parseOld-10.5 {syntax errors} {catch {set a "bcd"xy} msg} 1
test parseOld-10.6 {syntax errors} {
	catch {set a "bcd"xy} msg
	set msg
} {extra characters after close-quote}
test parseOld-10.7 {syntax errors} {catch "set a {bcd}xy" msg} 1
test parseOld-10.8 {syntax errors} {
	catch "set a {bcd}xy" msg
	set msg
} {extra characters after close-brace}
test parseOld-10.9 {syntax errors} {catch {set a [format abc} msg} 1
test parseOld-10.10 {syntax errors} {
	catch {set a [format abc} msg
	set msg
} {missing close-bracket}
test parseOld-10.11 {syntax errors} {catch gorp-a-lot msg} 1
test parseOld-10.12 {syntax errors} {
	catch gorp-a-lot msg
	set msg
} {invalid command name "gorp-a-lot"}
test parseOld-10.13 {syntax errors} {
    set a [concat {a}\
 {b}]
    set a
} {a b}
test parseOld-10.14 {syntax errors} {
    list [catch {eval \$x[format "%01000d" 0](} msg] $msg $errorInfo
} {1 {missing )} {missing )
    while compiling
"$x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000..."
    ("eval" body line 1)
    invoked from within
"eval \$x[format "%01000d" 0]("}}
test parseOld-10.15 {syntax errors, missplaced braces} {
    catch {
        proc misplaced_end_brace {} {
            set what foo
            set when [expr ${what}size - [set off$what]}]
    } msg
    set msg
} {extra characters after close-brace}
test parseOld-10.16 {syntax errors, missplaced braces} {
    catch {
        set a {
            set what foo
            set when [expr ${what}size - [set off$what]}]
    } msg
    set msg
} {extra characters after close-brace}
test parseOld-10.17 {syntax errors, unusual spacing} {
    list [catch {return [ [1]]} msg] $msg
} {1 {invalid command name "1"}}
# Long values (stressing storage management)

set a {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH}

test parseOld-11.1 {long values} {
    string length $a
} 214
test parseOld-11.2 {long values} {
    llength $a
} 43
test parseOld-11.3 {long values} {
    set b "1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH"
    set b
} $a
test parseOld-11.4 {long values} {
    set b "$a"
    set b
} $a
test parseOld-11.5 {long values} {
    set b [set a]
    set b
} $a
test parseOld-11.6 {long values} {
    set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
    string length $b
} 214
test parseOld-11.7 {long values} {
    set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
    llength $b
} 43
test parseOld-11.8 {long values} {
    set b
} $a
test parseOld-11.9 {long values} {
    set a [concat 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL MMMM NNNN OOOO PPPP QQQQ RRRR SSSS TTTT UUUU VVVV WWWW XXXX YYYY ZZZZ]
    llength $a
} 62
set i 0
foreach j [concat 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL MMMM NNNN OOOO PPPP QQQQ RRRR SSSS TTTT UUUU VVVV WWWW XXXX YYYY ZZZZ] {
    set test [string index 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ $i]
    set test $test$test$test$test
    set i [expr $i+1]
    test parseOld-11.10 {long values} {
	set j
    } $test
}
test parseOld-11.11 {test buffer overflow in backslashes in braces} {
    expr {"a" == {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101}}
} 0

test parseOld-12.1 {comments} {
    set a old
    eval {  # set a new}
    set a
} {old}
test parseOld-12.2 {comments} {
    set a old
    eval "  # set a new\nset a new"
    set a
} {new}
test parseOld-12.3 {comments} {
    set a old
    eval "  # set a new\\\nset a new"
    set a
} {old}
test parseOld-12.4 {comments} {
    set a old
    eval "  # set a new\\\\\nset a new"
    set a
} {new}

test parseOld-13.1 {comments at the end of a bracketed script} {
    set x "[
expr 1+1
# skip this!
]"
} {2}

if {[info command testwordend] == "testwordend"} {
    test parseOld-14.1 {TclWordEnd procedure} {
	testwordend " 	\n abc"
    } {c}
    test parseOld-14.2 {TclWordEnd procedure} {
	testwordend "   \\\n"
    } {}
    test parseOld-14.3 {TclWordEnd procedure} {
	testwordend "   \\\n "
    } { }
    test parseOld-14.4 {TclWordEnd procedure} {
	testwordend {"abc"}
    } {"}
    test parseOld-14.5 {TclWordEnd procedure} {
	testwordend {{xyz}}
    } \}
    test parseOld-14.6 {TclWordEnd procedure} {
	testwordend {{a{}b{}\}} xyz}
    } "\} xyz"
    test parseOld-14.7 {TclWordEnd procedure} {
	testwordend {abc[this is a]def ghi}
    } {f ghi}
    test parseOld-14.8 {TclWordEnd procedure} {
	testwordend "puts\\\n\n  "
    } "s\\\n\n  "
    test parseOld-14.9 {TclWordEnd procedure} {
	testwordend "puts\\\n   	"
    } "s\\\n   	"
    test parseOld-14.10 {TclWordEnd procedure} {
	testwordend "puts\\\n   	xyz"
    } "s\\\n   	xyz"
    test parseOld-14.11 {TclWordEnd procedure} {
	testwordend {a$x.$y(a long index) foo}
    } ") foo"
    test parseOld-14.12 {TclWordEnd procedure} {
	testwordend {abc; def}
    } {; def}
    test parseOld-14.13 {TclWordEnd procedure} {
	testwordend {abc def}
    } {c def}
    test parseOld-14.14 {TclWordEnd procedure} {
	testwordend {abc	def}
    } {c	def}
    test parseOld-14.15 {TclWordEnd procedure} {
	testwordend "abc\ndef"
    } "c\ndef"
    test parseOld-14.16 {TclWordEnd procedure} {
	testwordend "abc"
    } {c}
    test parseOld-14.17 {TclWordEnd procedure} {
	testwordend "a\000bc"
    } {c}
    test parseOld-14.18 {TclWordEnd procedure} {
	testwordend \[a\000\]
    } {]}
    test parseOld-14.19 {TclWordEnd procedure} {
	testwordend \"a\000\"
    } {"}
    test parseOld-14.20 {TclWordEnd procedure} {
	testwordend a{\000}b
    } {b}
    test parseOld-14.21 {TclWordEnd procedure} {
	testwordend "   \000b"
    } {b}
}

test parseOld-15.1 {TclScriptEnd procedure} {
    info complete {puts [
	expr 1+1
	#this is a comment ]}
} {0}
test parseOld-15.2 {TclScriptEnd procedure} {
    info complete "abc\\\n"
} {0}
test parseOld-15.3 {TclScriptEnd procedure} {
    info complete "abc\\\\\n"
} {1}
test parseOld-15.4 {TclScriptEnd procedure} {
    info complete "xyz \[abc \{abc\]"
} {0}
test parseOld-15.5 {TclScriptEnd procedure} {
    info complete "xyz \[abc"
} {0}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/pid.test.

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
# Commands covered:  pid
#
# 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-1995 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) pid.test 1.12 96/04/12 11:14:43




# If pid is not defined just return with no error
# Some platforms may not have the pid command implemented
if {[info commands pid] == ""} {
    puts "pid is not implemented for this machine"

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

catch {removeFile test1}

test pid-1.1 {pid command} {
    regexp {(^[0-9]+$)|(^0x[0-9a-fA-F]+$)} [pid]
} 1
test pid-1.2 {pid command} {unixOrPc unixExecs} {
    set f [open {| echo foo | cat >test1} w]








>




>
|
>
>
>





>



<
<







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
# Commands covered:  pid
#
# 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-1995 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: pid.test,v 1.1.2.6 1999/03/26 19:14:05 hershey Exp $

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

# If pid is not defined just return with no error
# Some platforms may not have the pid command implemented
if {[info commands pid] == ""} {
    puts "pid is not implemented for this machine"
    ::tcltest::cleanupTests
    return
}



catch {removeFile test1}

test pid-1.1 {pid command} {
    regexp {(^[0-9]+$)|(^0x[0-9a-fA-F]+$)} [pid]
} 1
test pid-1.2 {pid command} {unixOrPc unixExecs} {
    set f [open {| echo foo | cat >test1} w]
44
45
46
47
48
49
50

51


52











test pid-1.4 {pid command} {
    list [catch {pid a b} msg] $msg
} {1 {wrong # args: should be "pid ?channelId?"}}
test pid-1.5 {pid command} {
    list [catch {pid gorp} msg] $msg
} {1 {can not find channel named "gorp"}}


catch {removeFile test1}


concat {}


















>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
test pid-1.4 {pid command} {
    list [catch {pid a b} msg] $msg
} {1 {wrong # args: should be "pid ?channelId?"}}
test pid-1.5 {pid command} {
    list [catch {pid gorp} msg] $msg
} {1 {can not find channel named "gorp"}}

# cleanup
catch {::tcltest::removeFile test1}
::tcltest::cleanupTests
return












Changes to tests/pkg.test.

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
# Commands covered:  pkg
#
# 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) 1995-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) pkg.test 1.12 97/08/14 01:33:54



if {[string compare test [info procs test]] == 1} then {source defs}

# Do all this in a slave interp to avoid garbaging the
# package list
set i [interp create]
interp eval $i [list set VERBOSE $VERBOSE]
interp eval $i [list set TESTS $TESTS]
interp eval $i {

if {[string compare test [info procs test]] == 1} then {source defs}

eval package forget [package names]
set oldPkgUnknown [package unknown]
package unknown {}
set oldPath $auto_path
set auto_path ""

test pkg-1.1 {Tcl_PkgProvide procedure} {







>




>
|
>
>
|
<




|
|


<
<







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
# Commands covered:  pkg
#
# 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) 1995-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: pkg.test,v 1.1.2.7 1999/03/24 02:49:32 hershey Exp $

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


# Do all this in a slave interp to avoid garbaging the
# package list
set i [interp create]
interp eval $i [list set argv $argv]
interp eval $i [list source [file join $::tcltest::testsDir defs.tcl]]
interp eval $i {



eval package forget [package names]
set oldPkgUnknown [package unknown]
package unknown {}
set oldPath $auto_path
set auto_path ""

test pkg-1.1 {Tcl_PkgProvide procedure} {
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
    package vs 2.3 2.1
} {1}
test pkg-3.52 {Tcl_PackageCmd procedure, "vsatisfies" option} {
    package vs 2.3 1.2
} {0}
test pkg-3.53 {Tcl_PackageCmd procedure, "versions" option} {
    list [catch {package foo} msg] $msg
} {1 {bad option "foo": should be forget, ifneeded, names, provide, require, unknown, vcompare, versions, or vsatisfies}}

# No tests for FindPackage;  can't think up anything detectable
# errors.

test pkg-4.1 {TclFreePackageInfo procedure} {
    interp create foo
    foo eval {







|







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
    package vs 2.3 2.1
} {1}
test pkg-3.52 {Tcl_PackageCmd procedure, "vsatisfies" option} {
    package vs 2.3 1.2
} {0}
test pkg-3.53 {Tcl_PackageCmd procedure, "versions" option} {
    list [catch {package foo} msg] $msg
} {1 {bad option "foo": must be forget, ifneeded, names, present, provide, require, unknown, vcompare, versions, or vsatisfies}}

# No tests for FindPackage;  can't think up anything detectable
# errors.

test pkg-4.1 {TclFreePackageInfo procedure} {
    interp create foo
    foo eval {
551
552
553
554
555
556
557








































































558
559
560
561
562


563














test pkg-6.8 {ComparePkgVersions procedure} {
    package vsatisfies 1 1
} {1}
test pkg-6.9 {ComparePkgVersions procedure} {
    package vsatisfies 2 1
} {0}









































































set auto_path $oldPath
package unknown $oldPkgUnknown
concat

}


interp delete $i





















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





>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
test pkg-6.8 {ComparePkgVersions procedure} {
    package vsatisfies 1 1
} {1}
test pkg-6.9 {ComparePkgVersions procedure} {
    package vsatisfies 2 1
} {0}

test pkg-7.1 {Tcl_PkgPresent procedure, any version} {
    package forget t
    package provide t 2.4
    package present t
} {2.4}
test pkg-7.2 {Tcl_PkgPresent procedure, correct version} {
    package forget t
    package provide t 2.4
    package present t 2.4
} {2.4}
test pkg-7.3 {Tcl_PkgPresent procedure, satisfying version} {
    package forget t
    package provide t 2.4
    package present t 2.0
} {2.4}
test pkg-7.4 {Tcl_PkgPresent procedure, not satisfying version} {
    package forget t
    package provide t 2.4
    list [catch {package present t 2.6} msg] $msg
} {1 {version conflict for package "t": have 2.4, need 2.6}}
test pkg-7.5 {Tcl_PkgPresent procedure, not satisfying version} {
    package forget t
    package provide t 2.4
    list [catch {package present t 1.0} msg] $msg
} {1 {version conflict for package "t": have 2.4, need 1.0}}
test pkg-7.6 {Tcl_PkgPresent procedure, exact version} {
    package forget t
    package provide t 2.4
    package present -exact t 2.4
} {2.4}
test pkg-7.7 {Tcl_PkgPresent procedure, not exact version} {
    package forget t
    package provide t 2.4
    list [catch {package present -exact t 2.3} msg] $msg
} {1 {version conflict for package "t": have 2.4, need 2.3}}
test pkg-7.8 {Tcl_PkgPresent procedure, unknown package} {
    package forget t
    list [catch {package present t} msg] $msg
} {1 {package t is not present}}
test pkg-7.9 {Tcl_PkgPresent procedure, unknown package} {
    package forget t
    list [catch {package present t 2.4} msg] $msg
} {1 {package t 2.4 is not present}}
test pkg-7.10 {Tcl_PkgPresent procedure, unknown package} {
    package forget t
    list [catch {package present -exact t 2.4} msg] $msg
} {1 {package t 2.4 is not present}}
test pkg-7.11 {Tcl_PackageCmd procedure, "present" option} {
    list [catch {package present} msg] $msg
} {1 {wrong # args: should be "package present ?-exact? package ?version?"}}
test pkg-7.12 {Tcl_PackageCmd procedure, "present" option} {
    list [catch {package present a b c} msg] $msg
} {1 {wrong # args: should be "package present ?-exact? package ?version?"}}
test pkg-7.13 {Tcl_PackageCmd procedure, "present" option} {
    list [catch {package present -exact a b c} msg] $msg
} {1 {wrong # args: should be "package present ?-exact? package ?version?"}}
test pkg-7.14 {Tcl_PackageCmd procedure, "present" option} {
    list [catch {package present -bs a b} msg] $msg
} {1 {wrong # args: should be "package present ?-exact? package ?version?"}}
test pkg-7.15 {Tcl_PackageCmd procedure, "present" option} {
    list [catch {package present x a.b} msg] $msg
} {1 {expected version number but got "a.b"}}
test pkg-7.16 {Tcl_PackageCmd procedure, "present" option} {
    list [catch {package present -exact x a.b} msg] $msg
} {1 {expected version number but got "a.b"}}
test pkg-7.17 {Tcl_PackageCmd procedure, "present" option} {
    list [catch {package present -exact x} msg] $msg
} {1 {wrong # args: should be "package present ?-exact? package ?version?"}}
test pkg-7.18 {Tcl_PackageCmd procedure, "present" option} {
    list [catch {package present -exact} msg] $msg
} {1 {wrong # args: should be "package present ?-exact? package ?version?"}}

set auto_path $oldPath
package unknown $oldPkgUnknown
concat

}

# cleanup
interp delete $i
::tcltest::cleanupTests
return












Added tests/pkg/import.tcl.

































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package provide fubar 1.0
    
namespace eval ::fubar:: {
    #
    # export only public functions.
    #
    namespace export {[a-z]*}
}

proc ::fubar::foo {bar} {
    puts "$bar"
    return true
}

namespace import ::fubar::foo

Added tests/pkgMkIndex.test.















































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# This file contains tests for the pkg_mkIndex command.
# Note that the tests are limited to Tcl scripts only, there are no shared
# libraries against which to test.
#
# Sourcing this file into Tcl runs the tests and generates output for
# errors.  No output means no errors were found.
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
# RCS: @(#) $Id: pkgMkIndex.test,v 1.4.2.9 1999/04/07 02:38:11 hershey Exp $

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

# temporarily copy the pkg and pkg1 dirs from testsDir to tmpDir
if {"$::tcltest::testsDir" != "$::tcltest::workingDir"} {
    set origPkgDir [file join $::tcltest::testsDir pkg]
    set newPkgDir [file join $::tcltest::workingDir pkg]
    if {![catch {file copy $origPkgDir $newPkgDir}]} {
	set removePkgDir 1
    }
    if {![catch {file copy "${origPkgDir}1" "${newPkgDir}1"}]} {
	set removePkg1Dir 1
    }
}

# Add the pkg1 directory to auto_path, so that its packages can be found.
# packages in pkg1 are used to test indexing of packages in pkg.
# Make sure that the path to pkg1 is absolute.

set oldDir [pwd]
lappend auto_path [file join $::tcltest::workingDir pkg1]

namespace eval pkgtest {
    # Namespace for procs we can discard
}

# pkgtest::parseArgs --
#
#  Parse an argument list.
#
# Arguments:
#  <flags>	(optional) arguments starting with a dash are collected
#		as options to pkg_mkIndex and passed to pkg_mkIndex.
#  dirPath	the directory to index
#  pattern0	pattern to index
#  ...		pattern to index
#  patternN	pattern to index
#
# Results:
#  Returns a three element list:
#    0: the options
#    1: the directory to index
#    2: the patterns list

proc pkgtest::parseArgs { args } {
    set options ""

    set argc [llength $args]
    for {set iarg 0} {$iarg < $argc} {incr iarg} {
	set a [lindex $args $iarg]
	if {[regexp {^-} $a]} {
	    lappend options $a
	    if {[string compare -load $a] == 0} {
		incr iarg
		lappend options [lindex $args $iarg]
	    }
	} else {
	    break
	}
    }

    set dirPath [lindex $args $iarg]
    incr iarg
    set patternList [lrange $args $iarg end]

    return [list $options $dirPath $patternList]
}

# pkgtest::parseIndex --
#
#  Loads a pkgIndex.tcl file, records all the calls to "package ifneeded".
#
# Arguments:
#  filePath	path to the pkgIndex.tcl file.
#
# Results:
#  Returns a list, in "array set/get" format, where the keys are the package
#  name and version (in the form "$name:$version"), and the values the rest
#  of the command line.

proc pkgtest::parseIndex { filePath } {
    # create a slave interpreter, where we override "package ifneeded"

    set slave [interp create]
    if {[catch {
	$slave eval {
	    rename package package_original
	    proc package { args } {
		if {[string compare [lindex $args 0] ifneeded] == 0} {
		    set pkg [lindex $args 1]
		    set ver [lindex $args 2]
		    set ::PKGS($pkg:$ver) [lindex $args 3]
		} else {
		    return [eval package_original $args]
		}
	    }
	    array set ::PKGS {}
	}

	set dir [file dirname $filePath]
	$slave eval {set curdir [pwd]}
	$slave eval [list cd $dir]
	$slave eval [list set dir $dir]
	$slave eval [list source [file tail $filePath]]
	$slave eval {cd $curdir}

	# Create the list in sorted order, so that we don't get spurious
	# errors because the order has changed.

	array set P {}
	foreach {k v} [$slave eval {array get ::PKGS}] {
	    set P($k) $v
	}

	set PKGS ""
	foreach k [lsort [array names P]] {
	    lappend PKGS $k $P($k)
	}
    } err]} {
	set ei $::errorInfo
	set ec $::errorCode

	catch {interp delete $slave}

	error $ei $ec
    }

    interp delete $slave

    return $PKGS
}

# pkgtest::createIndex --
#
#  Runs pkg_mkIndex for the given directory and set of patterns.
#  This procedure deletes any pkgIndex.tcl file in the target directory,
#  then runs pkg_mkIndex.
#
# Arguments:
#  <flags>	(optional) arguments starting with a dash are collected
#		as options to pkg_mkIndex and passed to pkg_mkIndex.
#  dirPath	the directory to index
#  pattern0	pattern to index
#  ...		pattern to index
#  patternN	pattern to index
#
# Results:
#  Returns a two element list:
#    0: 1 if the procedure encountered an error, 0 otherwise.
#    1: the error result if element 0 was 1

proc pkgtest::createIndex { args } {
    set parsed [eval parseArgs $args]
    set options [lindex $parsed 0]
    set dirPath [lindex $parsed 1]
    set patternList [lindex $parsed 2]

    if {[catch {
	file delete [file join $dirPath pkgIndex.tcl]
	eval pkg_mkIndex $options $dirPath $patternList
    } err]} {
	return [list 1 $err]
    }

    return [list 0 {}]
}

# makePkgList --
#
#  Takes the output of a pkgtest::parseIndex call, filters it and returns a
#  cleaned up list of packages and their actions.
#
# Arguments:
#  inList	output from a pkgtest::parseIndex.
#
# Results:
#  Returns a list of two element lists:
#    0: the name:version
#    1: a list describing the package.
#	For tclPkgSetup packages it consists of:
#	 0: the keyword tclPkgSetup
#	 1: the first file to source, with its exported procedures
#	 2: the second file ...
#	 N: the N-1st file ...

proc makePkgList { inList } {
    set pkgList ""

    foreach {k v} $inList {
	switch [lindex $v 0] {
	    tclPkgSetup {
		set l tclPkgSetup
		foreach s [lindex $v 4] {
		    lappend l $s
		}
	    }

	    source {
		set l $v
	    }

	    default {
		error "can't handle $k $v"
	    }
	}

	lappend pkgList [list $k $l]
    }

    return $pkgList
}

# pkgtest::runIndex --
#
#  Runs pkg_mkIndex, parses the generated index file.
#
# Arguments:
#  <flags>	(optional) arguments starting with a dash are collected
#		as options to pkg_mkIndex and passed to pkg_mkIndex.
#  dirPath	the directory to index
#  pattern0	pattern to index
#  ...		pattern to index
#  patternN	pattern to index
#
# Results:
#  Returns a two element list:
#    0: 1 if the procedure encountered an error, 0 otherwise.
#    1: if no error, this is the parsed generated index file, in the format
#	returned by pkgtest::parseIndex.
#	If error, this is the error result.

proc pkgtest::runIndex { args } {
    set rv [eval createIndex $args]
    if {[lindex $rv 0] == 0} {
	set parsed [eval parseArgs $args]
	set dirPath [lindex $parsed 1]
	set idxFile [file join $dirPath pkgIndex.tcl]

	if {[catch {
	    set result [list 0 [makePkgList [parseIndex $idxFile]]]
	} err]} {
	    set result [list 1 $err]
	}
	file delete $idxFile
    } else {
	set result $rv
    }

    return $result
}

# If there is no match to the patterns, make sure the directory hasn't
# changed on us

test pkgMkIndex-1.1 {nothing matches pattern - current dir is the same} {
    list [pkgtest::runIndex pkg nomatch.tcl] [pwd]
} [list {1 {no files matched glob pattern "nomatch.tcl"}} [pwd]]
cd $oldDir	;# 'cause 8.0.3 is left in the wrong place
test pkgMkIndex-2.1 {simple package} {
    pkgtest::runIndex pkg simple.tcl
} {0 {{simple:1.0 {tclPkgSetup {simple.tcl source {::simple::lower ::simple::upper}}}}}}

test pkgMkIndex-2.2 {simple package - use -direct} {
    pkgtest::runIndex -direct pkg simple.tcl
} "0 {{simple:1.0 {source [file join pkg simple.tcl]}}}"

test pkgMkIndex-3.1 {simple package with global symbols} {
    pkgtest::runIndex pkg global.tcl
} {0 {{global:1.0 {tclPkgSetup {global.tcl source {global_lower global_upper}}}}}}

test pkgMkIndex-4.1 {split package} {
    pkgtest::runIndex pkg pkg2_a.tcl pkg2_b.tcl
} {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}}}}

test pkgMkIndex-4.2 {split package - direct loading} {
    pkgtest::runIndex -direct pkg pkg2_a.tcl pkg2_b.tcl
} "0 {{pkg2:1.0 {source [file join pkg pkg2_a.tcl]
source [file join pkg pkg2_b.tcl]}}}"

# This will fail, with "direct1" procedures in the list of procedures
# provided by std.
# It may also fail, if tclblend is in the auto_path, with an additional
# command "loadJava" which comes from the tclblend pkgIndex.tcl file.
# Both failures are caused by Tcl code executed in pkgIndex.tcl.

test pkgMkIndex-5.1 {requires -direct package} {
    pkgtest::runIndex pkg std.tcl
} {0 {{std:1.0 {tclPkgSetup {std.tcl source {::std::p1 ::std::p2}}}}}}

test pkgMkIndex-6.1 {pkg1 requires pkg3} {
    pkgtest::runIndex pkg pkg1.tcl pkg3.tcl
} {0 {{pkg1:1.0 {tclPkgSetup {pkg1.tcl source {::pkg1::p1-1 ::pkg1::p1-2}}}} {pkg3:1.0 {tclPkgSetup {pkg3.tcl source {::pkg3::p3-1 ::pkg3::p3-2}}}}}}

test pkgMkIndex-6.2 {pkg1 requires pkg3 - use -direct} {
    pkgtest::runIndex -direct pkg pkg1.tcl pkg3.tcl
} "0 {{pkg1:1.0 {source [file join pkg pkg1.tcl]}} {pkg3:1.0 {source [file join pkg pkg3.tcl]}}}"

test pkgMkIndex-7.1 {pkg4 uses pkg3} {
    pkgtest::runIndex pkg pkg4.tcl pkg3.tcl
} {0 {{pkg3:1.0 {tclPkgSetup {pkg3.tcl source {::pkg3::p3-1 ::pkg3::p3-2}}}} {pkg4:1.0 {tclPkgSetup {pkg4.tcl source {::pkg4::p4-1 ::pkg4::p4-2}}}}}}

test pkgMkIndex-7.2 {pkg4 uses pkg3 - use -direct} {
    pkgtest::runIndex -direct pkg pkg4.tcl pkg3.tcl
} "0 {{pkg3:1.0 {source [file join pkg pkg3.tcl]}} {pkg4:1.0 {source [file join pkg pkg4.tcl]}}}"

test pkgMkIndex-8.1 {pkg5 uses pkg2} {
    pkgtest::runIndex pkg pkg5.tcl pkg2_a.tcl pkg2_b.tcl
} {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}} {pkg5:1.0 {tclPkgSetup {pkg5.tcl source {::pkg5::p5-1 ::pkg5::p5-2}}}}}}

test pkgMkIndex-8.2 {pkg5 uses pkg2 - use -direct} {
    pkgtest::runIndex -direct pkg pkg5.tcl pkg2_a.tcl pkg2_b.tcl
} "0 {{pkg2:1.0 {source [file join pkg pkg2_a.tcl]
source [file join pkg pkg2_b.tcl]}} {pkg5:1.0 {source [file join pkg pkg5.tcl]}}}"

test pkgMkIndex-9.1 {circular packages} {
    pkgtest::runIndex pkg circ1.tcl circ2.tcl circ3.tcl
} {0 {{circ1:1.0 {tclPkgSetup {circ1.tcl source {::circ1::c1-1 ::circ1::c1-2 ::circ1::c1-3 ::circ1::c1-4}}}} {circ2:1.0 {tclPkgSetup {circ2.tcl source {::circ2::c2-1 ::circ2::c2-2}}}} {circ3:1.0 {tclPkgSetup {circ3.tcl source ::circ3::c3-1}}}}}

# Some tests require the existence of one of the DLLs in the dltest directory
set x [file join [file dirname [info nameofexecutable]] dltest \
	pkga[info sharedlibextension]]
set dll "[file tail $x]Required"
set ::tcltest::testConfig($dll) [file exists $x]

test pkgMkIndex-10.1 {package in DLL and script} $dll {
    file copy -force $x pkg
    pkgtest::runIndex pkg pkga[info sharedlibextension] pkga.tcl
} "0 {{Pkga:1.0 {tclPkgSetup {pkga[info sharedlibextension] load {pkga_eq pkga_quote}} {pkga.tcl source pkga_neq}}}}"
test pkgMkIndex-10.2 {package in DLL hidden by -load} $dll {
    pkgtest::runIndex -load Pkg* -- pkg pkga[info sharedlibextension]
} {0 {}}

# Tolerate "namespace import" at the global scope

test pkgMkIndex-11.1 {conflicting namespace imports} {
    pkgtest::runIndex pkg import.tcl
} {0 {{fubar:1.0 {tclPkgSetup {import.tcl source ::fubar::foo}}}}}

# cleanup
namespace delete pkgtest
cd $::tcltest::workingDir
if {[info exists removePkgDir]} {
    # strange error deleting the pkg dir only once--needs be done twice!
    catch {file delete -force $newPkgDir}
    catch {file delete -force $newPkgDir}
}
if {[info exists removePkg1Dir]} {
    catch {file delete -force "${newPkgDir}1"}
}
::tcltest::cleanupTests
return











Added tests/platform.test.















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# The file tests the tcl_platform variable
#
# 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) 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: @(#) 

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

test platform-1.1 {TclpSetVariables: tcl_platform} {
    interp create i
    i eval {catch {unset tcl_platform(debug)}}
    set result [i eval {lsort [array names tcl_platform]}]
    interp delete i
    set result
} {byteOrder machine os osVersion platform user}

# cleanup
::tcltest::cleanupTests
return











Changes to tests/proc-old.test.

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
# Commands covered:  proc, return, global
#
# This file, proc-old.test, includes the original set of tests for Tcl's
# proc, return, and global commands. There is now a new file proc.test
# that contains tests for the tclProc.c source file.
#
# 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-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.
#
# SCCS: @(#) proc-old.test 1.31 97/07/02 16:41:36


if {[string compare test [info procs test]] == 1} then {source defs}


catch {rename t1 ""}
catch {rename foo ""}

proc tproc {} {return a; return b}
test proc-old-1.1 {simple procedure call and return} {tproc} a
proc tproc x {











>




|

>
|
>







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
# Commands covered:  proc, return, global
#
# This file, proc-old.test, includes the original set of tests for Tcl's
# proc, return, and global commands. There is now a new file proc.test
# that contains tests for the tclProc.c source file.
#
# 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-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: proc-old.test,v 1.1.2.5 1999/03/24 02:49:34 hershey Exp $

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

catch {rename t1 ""}
catch {rename foo ""}

proc tproc {} {return a; return b}
test proc-old-1.1 {simple procedure call and return} {tproc} a
proc tproc x {
497
498
499
500
501
502
503

504
505














        rename expr.old expr
        if $x then {t1 0} ;# recursive call after foo's code is invalidated
        return 20
    }
    t1 1
} 20


catch {rename t1 ""}
catch {rename foo ""}





















>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
        rename expr.old expr
        if $x then {t1 0} ;# recursive call after foo's code is invalidated
        return 20
    }
    t1 1
} 20

# cleanup
catch {rename t1 ""}
catch {rename foo ""}
::tcltest::cleanupTests
return












Changes to tests/proc.test.

1
2
3
4
5
6
7
8
9
10

11
12
13
14

15


16
17
18
19
20
21
22
23
24
# This file contains tests for the tclProc.c source file. Tests appear in
# the same order as the C code that they test. The set of tests is
# currently incomplete since it includes only new tests, in particular
# tests for code changed for the addition of Tcl namespaces. Other
# procedure-related tests appear in other test files such as proc-old.test.
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) proc.test 1.11 97/08/12 13:31:43



if {[string compare test [info procs test]] == 1} then {source defs}

catch {eval namespace delete [namespace children :: test_ns_*]}
catch {rename p ""}
catch {rename {} ""}
catch {unset msg}

test proc-1.1 {Tcl_ProcObjCmd, put proc in namespace specified in name, if any} {










>




>
|
>
>
|
<







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
# This file contains tests for the tclProc.c source file. Tests appear in
# the same order as the C code that they test. The set of tests is
# currently incomplete since it includes only new tests, in particular
# tests for code changed for the addition of Tcl namespaces. Other
# procedure-related tests appear in other test files such as proc-old.test.
#
# 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: proc.test,v 1.1.2.7 1999/03/26 19:14:06 hershey Exp $

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


catch {eval namespace delete [namespace children :: test_ns_*]}
catch {rename p ""}
catch {rename {} ""}
catch {unset msg}

test proc-1.1 {Tcl_ProcObjCmd, put proc in namespace specified in name, if any} {
157
158
159
160
161
162
163


















































































































































    list [catch {p} msg] $msg
} {1 {no value given for parameter "x" to "p"}}

catch {eval namespace delete [namespace children :: test_ns_*]}
catch {rename p ""}
catch {rename {} ""}
catch {unset msg}

























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
    list [catch {p} msg] $msg
} {1 {no value given for parameter "x" to "p"}}

catch {eval namespace delete [namespace children :: test_ns_*]}
catch {rename p ""}
catch {rename {} ""}
catch {unset msg}

if {[catch {package require procbodytest}]} {
    puts "This application couldn't load the \"procbodytest\" package, so I"
    puts "can't test creation of procs whose bodies have type \"procbody\"."
    ::tcltest::cleanupTests
    return
}

catch {rename p ""}
catch {rename t ""}

# Note that the test require that procedures whose body is used to create
# procbody objects must be executed before the procbodytest::proc command
# is executed, so that the Proc struct is populated correctly (CompiledLocals
# are added at compile time).

test proc-4.1 {TclCreateProc, procbody obj} {
    catch {
	proc p x {return "$x:$x"}
	set rv [p P]
	procbodytest::proc t x p
	lappend rv [t T]
	set rv
    } result
    catch {rename p ""}
    catch {rename t ""}
    set result
} {P:P T:T}

test proc-4.2 {TclCreateProc, procbody obj, use compiled locals} {
    catch {
	proc p x {
	    set y [string tolower $x]
	    return "$x:$y"
	}
	set rv [p P]
	procbodytest::proc t x p
	lappend rv [t T]
	set rv
    } result
    catch {rename p ""}
    catch {rename t ""}
    set result
} {P:p T:t}

test proc-4.3 {TclCreateProc, procbody obj, too many args} {
    catch {
	proc p x {
	    set y [string tolower $x]
	    return "$x:$y"
	}
	set rv [p P]
	procbodytest::proc t {x x1 x2} p
	lappend rv [t T]
	set rv
    } result
    catch {rename p ""}
    catch {rename t ""}
    set result
} {procedure "t": arg list contains 3 entries, precompiled header expects 1}

test proc-4.4 {TclCreateProc, procbody obj, inconsitent arg name} {
    catch {
	proc p {x y z} {
	    set v [join [list $x $y $z]]
	    set w [string tolower $v]
	    return "$v:$w"
	}
	set rv [p P Q R]
	procbodytest::proc t {x x1 z} p
	lappend rv [t S T U]
	set rv
    } result
    catch {rename p ""}
    catch {rename t ""}
    set result
} {procedure "t": formal parameter 1 is inconsistent with precompiled body}

test proc-4.5 {TclCreateProc, procbody obj, inconsitent arg default type} {
    catch {
	proc p {x y {z Z}} {
	    set v [join [list $x $y $z]]
	    set w [string tolower $v]
	    return "$v:$w"
	}
	set rv [p P Q R]
	procbodytest::proc t {x y z} p
	lappend rv [t S T U]
	set rv
    } result
    catch {rename p ""}
    catch {rename t ""}
    set result
} {procedure "t": formal parameter 2 is inconsistent with precompiled body}

test proc-4.6 {TclCreateProc, procbody obj, inconsitent arg default type} {
    catch {
	proc p {x y z} {
	    set v [join [list $x $y $z]]
	    set w [string tolower $v]
	    return "$v:$w"
	}
	set rv [p P Q R]
	procbodytest::proc t {x y {z Z}} p
	lappend rv [t S T U]
	set rv
    } result
    catch {rename p ""}
    catch {rename t ""}
    set result
} {procedure "t": formal parameter 2 is inconsistent with precompiled body}

test proc-4.7 {TclCreateProc, procbody obj, inconsitent arg default value} {
    catch {
	proc p {x y {z Z}} {
	    set v [join [list $x $y $z]]
	    set w [string tolower $v]
	    return "$v:$w"
	}
	set rv [p P Q R]
	procbodytest::proc t {x y {z ZZ}} p
	lappend rv [t S T U]
	set rv
    } result
    catch {rename p ""}
    catch {rename t ""}
    set result
} {procedure "t": formal parameter "z" has default value inconsistent with precompiled body}

# cleanup
catch {rename p ""}
catch {rename t ""}
::tcltest::cleanupTests
return












Changes to tests/pwd.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
















# Commands covered:  pwd
#
# 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-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.
#

# SCCS: @(#) pwd.test 1.2 97/08/13 23:06:41



if {[string compare test [info procs test]] == 1} then {source defs}

test pwd-1.1 {simple pwd} {
	catch pwd
} 0
test pwd-1.2 {simple pwd} {
	expr [string length pwd]>0
} 1
























>




>
|
>
>
|
<







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# Commands covered:  pwd
#
# 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-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: pwd.test,v 1.1.2.4 1999/03/24 02:49:35 hershey Exp $

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


test pwd-1.1 {simple pwd} {
	catch pwd
} 0
test pwd-1.2 {simple pwd} {
	expr [string length pwd]>0
} 1

# cleanup
::tcltest::cleanupTests
return












Added tests/reg.test.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
# reg.test --
#
# 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) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
# RCS: @(#) $Id: reg.test,v 1.1.2.7 1999/04/06 19:03:56 hershey Exp $

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

# All tests require the testregexp command, return if this
# command doesn't exist

set ::tcltest::testConfig(testregexp) \
	[expr {[info commands testregexp] != {}}]

# This file uses some custom procedures, defined below, for regexp regression
# testing.  The name of the procedure indicates the general nature of the
# test:  e for compile error expected, f for match failure expected, m
# for a successful match, and i for a successful match with -indices (used
# in checking things like nonparticipating subexpressions).  There is also
# a "doing" procedure which sets up title and major test number for each
# block of tests, and an "xx" procedure which ignores its arguments and
# arranges for the next invocation of "doing" to announce that some tests
# were bypassed (which is better than just commenting them out).

# The first 3 arguments are constant:  a minor number (which often gets
# a letter or two suffixed to it internally), some flags, and the RE itself.
# For e, the remaining argument is the name of the compile error expected,
# less the leading "REG_".  For the rest, the next argument is the string
# to try the match against.  Remaining arguments are the substring expected
# to be matched, and any substrings expected to be matched by subexpressions.
# (For f, these arguments are optional, and if present are ignored except
# that they indicate how many subexpressions should be presents in the RE.)
# It is an error for the number of subexpression arguments to be wrong.
# Cases involving nonparticipating subexpressions, checking where empty
# substrings are located, etc. should be done using i.

# The flag characters are complex and a bit eclectic.  Generally speaking, 
# lowercase letters are compile options, uppercase are expected re_info
# bits, and nonalphabetics are match options, controls for how the test is 
# run, or testing options.  The one small surprise is that AREs are the
# default, and you must explicitly request lesser flavors of RE.  The flags
# are as follows.  It is admitted that some are not very mnemonic.
# There are some others which are purely debugging tools and are not
# useful in this file.
#
#	-	no-op (placeholder)
#	+	provide fake xy equivalence class
#	%	force small state-set cache in matcher (to test cache replace)
#	^	beginning of string is not beginning of line
#	$	end of string is not end of line
#
#	&	test as both ARE and BRE
#	b	BRE
#	e	ERE
#	a	turn advanced-features bit on (error unless ERE already)
#	q	literal string, no metacharacters at all
#
#	i	case-independent matching
#	o	("opaque") no subexpression capture
#	p	newlines are half-magic, excluded from . and [^ only
#	w	newlines are half-magic, significant to ^ and $ only
#	n	newlines are fully magic, both effects
#	x	expanded RE syntax
#
#	A	backslash-_a_lphanumeric seen
#	B	ERE/ARE literal-_b_race heuristic used
#	E	backslash (_e_scape) seen within []
#	H	looka_h_ead constraint seen
#	I	_i_mpossible to match
#	L	_l_ocale-specific construct seen
#	M	unportable (_m_achine-specific) construct seen
#	N	RE can match empty (_n_ull) string
#	P	non-_P_OSIX construct seen
#	Q	{} _q_uantifier seen
#	R	back _r_eference seen
#	S	POSIX-un_s_pecified syntax seen
#	U	saw original-POSIX botch:  unmatched right paren in ERE (_u_gh)

# The one area we can't easily test is memory-allocation failures (which
# are hard to provoke on command).  Embedded NULs also are not tested at
# the moment, but this is a historical accident which should be fixed.



# test procedures and related

set ask "about"
set xflags "xflags"
set testbypassed 0

# re_info abbreviation mapping table
set infonames(A) "REG_UBSALNUM"
set infonames(B) "REG_UBRACES"
set infonames(E) "REG_UBBS"
set infonames(H) "REG_ULOOKAHEAD"
set infonames(I) "REG_UIMPOSSIBLE"
set infonames(L) "REG_ULOCALE"
set infonames(M) "REG_UUNPORT"
set infonames(N) "REG_UEMPTYMATCH"
set infonames(P) "REG_UNONPOSIX"
set infonames(Q) "REG_UBOUNDS"
set infonames(R) "REG_UBACKREF"
set infonames(S) "REG_UUNSPEC"
set infonames(U) "REG_UPBOTCH"
set infonameorder "RHQBAUEPSMLNI"	;# must match bit order, lsb first

# set major test number and description
proc doing {major desc} {
	global prefix description testbypassed

	if {$testbypassed != 0} {
		puts stdout "!!! bypassed $testbypassed tests in\
					 $major, `$description'"
	}

	set prefix reg-$major
	set description "reg $desc"
	set testbypassed 0
}

# build test number (internal)
proc tno {testid} {
	return [lindex $testid 0]
}

# build description, with possible modifiers (internal)
proc desc {testid} {
	global description

	set d $description
	if {[llength $testid] > 1} {
		set d "([lreplace $testid 0 0]) $d"
	}
	return $d
}

# build trailing options and flags argument from a flags string (internal)
proc flags {fl} {
	global xflags

	set args [list]
	set flags ""
	foreach f [split $fl ""] {
		switch -exact -- $f {
		"i" { lappend args "-nocase" }
		"x" { lappend args "-expanded" }
		"n" { lappend args "-line" }
		"p" { lappend args "-linestop" }
		"w" { lappend args "-lineanchor" }
		"-" { }
		default { append flags $f }
		}
	}
	if {[string compare $flags ""] != 0} {
		lappend args -$xflags $flags
	}
	return $args
}

# build info-flags list from a flags string (internal)
proc infoflags {fl} {
	global infonames infonameorder

	set ret [list]
	foreach f [split $infonameorder ""] {
		if {[string first $f $fl] >= 0} {
			lappend ret $infonames($f)
		}
	}
	return $ret
}

# compilation error expected
proc e {testid flags re err} {
	global prefix ask errorCode

	# if &, test as both ARE and BRE
	set amp [string first "&" $flags]
	if {$amp >= 0} {
		set f [string range $flags 0 [expr $amp - 1]]
		append f [string range $flags [expr $amp + 1] end]
		e [linsert $testid end ARE] ${f} $re $err
		e [linsert $testid end BRE] ${f}b $re $err
		return
	}

	set cmd [concat [list testregexp -$ask] [flags $flags] [list $re]]
	set run "list \[catch \{$cmd\}\] \[lindex \$errorCode 1\]"
	test $prefix.[tno $testid] [desc $testid] {testregexp} $run [list 1 REG_$err]
}

# match failure expected
proc f {testid flags re target args} {
	global prefix description ask

	# if &, test as both ARE and BRE
	set amp [string first "&" $flags]
	if {$amp >= 0} {
		set f [string range $flags 0 [expr $amp - 1]]
		append f [string range $flags [expr $amp + 1] end]
		eval [linsert $args 0 f [linsert $testid end ARE] ${f} $re \
								$target]
		eval [linsert $args 0 f [linsert $testid end BRE] ${f}b $re \
								$target]
		return
	}

	set f [flags $flags]
	set infoflags [infoflags $flags]
	set ccmd [concat [list testregexp -$ask] $f [list $re]]
	set nsub [expr [llength $args] - 1]
	if {$nsub == -1} {
		# didn't tell us number of subexps
		set ccmd "lreplace \[$ccmd\] 0 0"
		set info [list $infoflags]
	} else {
		set info [list $nsub $infoflags]
	}
	lappend testid "compile"
	test $prefix.[tno $testid] [desc $testid] {testregexp} $ccmd $info

	set testid [lreplace $testid end end "execute"]
	set ecmd [concat [list testregexp] $f [list $re $target]]
	test $prefix.[tno $testid] [desc $testid] {testregexp} $ecmd 0
}

# match expected, internal routine that does the work
# parameters like the "real" routines except they don't have "opts",
#  which is a possibly-empty list of switches for the regexp match attempt
proc matchexpected {opts testid flags re target args} {
	global prefix description ask

	# if &, test as both BRE and ARE
	set amp [string first "&" $flags]
	if {$amp >= 0} {
		set f [string range $flags 0 [expr $amp - 1]]
		append f [string range $flags [expr $amp + 1] end]
		eval [concat [list matchexpected $opts \
			[linsert $testid end ARE] ${f} $re $target] $args]
		eval [concat [list matchexpected $opts \
			[linsert $testid end BRE] ${f}b $re $target] $args]
		return
	}

	set f [flags $flags]
	set infoflags [infoflags $flags]
	set ccmd [concat [list testregexp -$ask] $f [list $re]]
	set ecmd [concat [list testregexp] $opts $f [list $re $target]]

	set nsub [expr [llength $args] - 1]
	set names [list]
	set refs ""
	for {set i 0} {$i <= $nsub} {incr i} {
		if {$i == 0} {
			set name match
		} else {
			set name sub$i
		}
		lappend names $name
		append refs " \$$name"
		set $name ""
	}
	if {[string first "o" $flags] >= 0} {	;# REG_NOSUB
		set nsub 0		;# unsigned value cannot be -1
	}
	set ecmd [concat $ecmd $names]
	set erun "list \[$ecmd\] $refs"
	set result [concat [list 1] $args]

	set info [list $nsub $infoflags]
	lappend testid "compile"
	test $prefix.[tno $testid] [desc $testid] {testregexp} $ccmd $info
	set testid [lreplace $testid end end "execute"]
	test $prefix.[tno $testid] [desc $testid] {testregexp} $erun $result
}

# match expected (no missing, empty, or ambiguous submatches)
# m testno flags re target mat submat ...
proc m {args} {
	eval matchexpected [linsert $args 0 [list]]
}

# match expected (full fanciness)
# i testno flags re target mat submat ...
proc i {args} {
	eval matchexpected [linsert $args 0 [list "-indices"]]
}

# test temporarily unimplemented
proc xx {args} {
	global testbypassed

	incr testbypassed
}



# the tests themselves



# support functions and preliminary misc.
# This is sensitive to changes in message wording, but we really have to
# test the code->message expansion at least once.
test regexp-0.1 "regexp error reporting" {
	list [catch {regexp (*) ign} msg] $msg
} {1 {couldn't compile regular expression pattern: quantifier operand invalid}}



doing 1 "basic sanity checks"
m  1	&	abc		abc	abc
f  2	&	abc		def
m  3	&	abc		xyabxabce	abc



doing 2 "invalid option combinations"
e  1	qe	a		INVARG
e  2	qa	a		INVARG
e  3	qx	a		INVARG
e  4	qn	a		INVARG
e  5	ba	a		INVARG



doing 3 "basic syntax"
i  1	&NS	""		a	{0 -1}
m  2	NS	a|		a	a
m  3	-	a|b		a	a
m  4	-	a|b		b	b
m  5	NS	a||b		b	b
m  6	&	ab		ab	ab



doing 4 "parentheses"
m  1	-	(a)e		ae	ae	a
m  2	o	(a)e		ae
m  3	b	{\(a\)b}	ab	ab	a
m  4	-	a((b)c)		abc	abc	bc	b
m  5	-	a(b)(c)		abc	abc	b	c
e  6	-	a(b		EPAREN
e  7	b	{a\(b}		EPAREN
# sigh, we blew it on the specs here... someday this will be fixed in POSIX,
#  but meanwhile, it's fixed in AREs
m  8	eU	a)b		a)b	a)b
e  9	-	a)b		EPAREN
e 10	b	{a\)b}		EPAREN
m 11	P	a(?:b)c		abc	abc
e 12	e	a(?:b)c		BADRPT
i 13	S	a()b		ab	{0 1}	{1 0}
m 14	SP	a(?:)b		ab	ab
i 15	S	a(|b)c		ac	{0 1}	{1 0}
m 16	S	a(b|)c		abc	abc	b



doing 5 "simple one-char matching"
# general case of brackets done later
m  1	&	a.b		axb	axb
f  2	&n	"a.b"		"a\nb"
m  3	&	{a[bc]d}	abd	abd
m  4	&	{a[bc]d}	acd	acd
f  5	&	{a[bc]d}	aed
f  6	&	{a[^bc]d}	abd
m  7	&	{a[^bc]d}	aed	aed
f  8	&p	"a\[^bc]d"	"a\nd"



doing 6 "context-dependent syntax"
# plus odds and ends
e  1	-	*		BADRPT
m  2	b	*		*	*
m  3	b	{\(*\)}		*	*	*
e  4	-	(*)		BADRPT
m  5	b	^*		*	*
e  6	-	^*		BADRPT
f  7	&	^b		^b
m  8	b	x^		x^	x^
f  9	I	x^		x
m 10	n	"\n^"		"x\nb"	"\n"
f 11	bS	{\(^b\)}	^b
m 12	-	(^b)		b	b	b
m 13	&	{x$}		x	x
m 14	bS	{\(x$\)}	x	x	x
m 15	-	{(x$)}		x	x	x
m 16	b	{x$y}		"x\$y"	"x\$y"
f 17	I	{x$y}		xy
m 18	n	"x\$\n"		"x\n"	"x\n"
e 19	-	+		BADRPT
e 20	-	?		BADRPT



doing 7 "simple quantifiers"
m  1	&N	a*		aa	aa
i  2	&N	a*		b	{0 -1}
m  3	-	a+		aa	aa
m  4	-	a?b		ab	ab
m  5	-	a?b		b	b
e  6	-	**		BADRPT
m  7	bN	**		***	***
e  8	&	a**		BADRPT
e  9	&	a**b		BADRPT
e 10	&	***		BADRPT
e 11	*	a++		BADRPT
e 12	*	a?+		BADRPT
e 13	*	a?*		BADRPT
e 14	*	a+*		BADRPT
e 15	*	a*+		BADRPT



doing 8 "braces"
m  1	NQ	"a{0,1}"	""	""
m  2	NQ	"a{0,1}"	ac	a
e  3	-	"a{1,0}"	BADBR
e  4	-	"a{1,2,3}"	BADBR
e  5	-	"a{257}"	BADBR
e  6	-	"a{1000}"	BADBR
e  7	-	"a{1"		EBRACE
e  8	-	"a{1n}"		BADBR
m  9	BS	"a{b"		"a\{b"	"a\{b"
m 10	BS	"a{"		"a\{"	"a\{"
m 11	bQ	{a\{0,1\}b}	cb	b
e 12	b	{a\{0,1}	EBRACE
e 13	-	"a{0,1\\"	BADBR
m 14	Q	"a{0}b"		ab	b
m 15	Q	"a{0,0}b"	ab	b
m 16	Q	"a{0,1}b"	ab	ab
m 17	Q	"a{0,2}b"	b	b
m 18	Q	"a{0,2}b"	aab	aab
m 19	Q	"a{0,}b"	aab	aab
m 20	Q	"a{1,1}b"	aab	ab
m 21	Q	"a{1,3}b"	aaaab	aaab
f 22	Q	"a{1,3}b"	b
m 23	Q	"a{1,}b"	aab	aab
f 24	Q	"a{2,3}b"	ab
m 25	Q	"a{2,3}b"	aaaab	aaab
f 26	Q	"a{2,}b"	ab
m 27	Q	"a{2,}b"	aaaab	aaaab



doing 9 "brackets"
m  1	&	{a[bc]}		ac	ac
m  2	&	{a[-]}		a-	a-
m  3	&	{a[[.-.]]}	a-	a-
m  4	&L	{a[[.zero.]]}	a0	a0
m  5	&LM	{a[[.zero.]-9]}	a2	a2
m  6	&M	{a[0-[.9.]]}	a2	a2
m  7	&+L	{a[[=x=]]}	ax	ax
m  8	&+L	{a[[=x=]]}	ay	ay
f  9	&+L	{a[[=x=]]}	az
e 10	&	{a[0-[=x=]]}	ERANGE
m 11	&L	{a[[:digit:]]}	a0	a0
e 12	&	{a[[:woopsie:]]}	ECTYPE
f 13	&L	{a[[:digit:]]}	ab
e 14	&	{a[0-[:digit:]]}	ERANGE
m 15	&LP	{[[:<:]]a}	a	a
m 16	&LP	{a[[:>:]]}	a	a
e 17	&	{a[[..]]b}	ECOLLATE
e 18	&	{a[[==]]b}	ECOLLATE
e 19	&	{a[[::]]b}	ECTYPE
e 20	&	{a[[.a}		EBRACK
e 21	&	{a[[=a}		EBRACK
e 22	&	{a[[:a}		EBRACK
e 23	&	{a[}		EBRACK
e 24	&	{a[b}		EBRACK
e 25	&	{a[b-}		EBRACK
e 26	&	{a[b-c}		EBRACK
m 27	&M	{a[b-c]}	ab	ab
m 28	&	{a[b-b]}	ab	ab
m 29	&M	{a[1-2]}	a2	a2
e 30	&	{a[c-b]}	ERANGE
e 31	&	{a[a-b-c]}	ERANGE
m 32	&M	{a[--?]b}	a?b	a?b
m 33	&	{a[---]b}	a-b	a-b
m 34	&	{a[]b]c}	a]c	a]c
m 35	EP	{a[\]]b}	a]b	a]b
f 36	bE	{a[\]]b}	a]b
m 37	bE	{a[\]]b}	"a\\]b"	"a\\]b"
m 38	eE	{a[\]]b}	"a\\]b"	"a\\]b"
m 39	EP	{a[\\]b}	"a\\b"	"a\\b"
m 40	eE	{a[\\]b}	"a\\b"	"a\\b"
m 41	bE	{a[\\]b}	"a\\b"	"a\\b"
e 42	-	{a[\Z]b}	EESCAPE
m 43	&	{a[[b]c}	"a\[c"	"a\[c"
m 44	EMP	{a[\u00fe-\u0507][\u00ff-\u0300]b} \
			"a\u0102\u02ffb"	"a\u0102\u02ffb"



doing 10 "anchors and newlines"
m  1	&	^a		a	a
f  2	&^	^a		a
i  3	&N	^		a	{0 -1}
i  4	&	{a$}		aba	{2 2}
f  5	{&$}	{a$}		a
i  6	&N	{$}		ab	{2 1}
m  7	&n	^a		a	a
m  8	&n	"^a"		"b\na"	"a"
i  9	&w	"^a"		"a\na"	{0 0}
i 10	&n^	"^a"		"a\na"	{2 2}
m 11	&n	{a$}		a	a
m 12	&n	"a\$"		"a\nb"	"a"
i 13	&n	"a\$"		"a\na"	{0 0}
i 14	N	^^		a	{0 -1}
m 15	b	^^		^	^
i 16	N	{$$}		a	{1 0}
m 17	b	{$$}		"\$"	"\$"
m 18	&N	{^$}		""	""
f 19	&N	{^$}		a
i 20	&nN	"^\$"		"a\n\nb"	{2 1}
m 21	N	{$^}		""	""
m 22	b	{$^}		"\$^"	"\$^"
m 23	P	{\Aa}		a	a
m 24	^P	{\Aa}		a	a
f 25	^nP	{\Aa}		"b\na"
m 26	P	{a\Z}		a	a
m 27	{$P}	{a\Z}		a	a
f 28	{$nP}	{a\Z}		"a\nb"
e 29	-	^*		BADRPT
e 30	-	{$*}		BADRPT
e 31	-	{\A*}		BADRPT
e 32	-	{\Z*}		BADRPT



doing 11 "boundary constraints"
m  1	&LP	{[[:<:]]a}	a	a
m  2	&LP	{[[:<:]]a}	-a	a
f  3	&LP	{[[:<:]]a}	ba
m  4	&LP	{a[[:>:]]}	a	a
m  5	&LP	{a[[:>:]]}	a-	a
f  6	&LP	{a[[:>:]]}	ab
m  7	bLP	{\<a}		a	a
f  8	bLP	{\<a}		ba
m  9	bLP	{a\>}		a	a
f 10	bLP	{a\>}		ab
m 11	LP	{\ya}		a	a
f 12	LP	{\ya}		ba
m 13	LP	{a\y}		a	a
f 14	LP	{a\y}		ab
m 15	LP	{a\Y}		ab	a
f 16	LP	{a\Y}		a-
f 17	LP	{a\Y}		a
f 18	LP	{-\Y}		-a
m 19	LP	{-\Y}		-%	-
f 20	LP	{\Y-}		a-
e 21	-	{[[:<:]]*}	BADRPT
e 22	-	{[[:>:]]*}	BADRPT
e 23	b	{\<*}		BADRPT
e 24	b	{\>*}		BADRPT
e 25	-	{\y*}		BADRPT
e 26	-	{\Y*}		BADRPT
m 27	LP	{\ma}		a	a
f 28	LP	{\ma}		ba
m 29	LP	{a\M}		a	a
f 30	LP	{a\M}		ab
f 31	ILP	{\Ma}		a
f 32	ILP	{a\m}		a



doing 12 "character classes"
m  1	LP	{a\db}		a0b	a0b
f  2	LP	{a\db}		axb
f  3	LP	{a\Db}		a0b
m  4	LP	{a\Db}		axb	axb
m  5	LP	"a\\sb"		"a b"	"a b"
m  6	LP	"a\\sb"		"a\tb"	"a\tb"
m  7	LP	"a\\sb"		"a\nb"	"a\nb"
f  8	LP	{a\sb}		axb
m  9	LP	{a\Sb}		axb	axb
f 10	LP	"a\\Sb"		"a b"
m 11	LP	{a\wb}		axb	axb
f 12	LP	{a\wb}		a-b
f 13	LP	{a\Wb}		axb
m 14	LP	{a\Wb}		a-b	a-b
m 15	LP	{\y\w+z\y}	adze-guz	guz
m 16	LPE	{a[\d]b}	a1b	a1b
m 17	LPE	"a\[\\s]b"	"a b"	"a b"
m 18	LPE	{a[\w]b}	axb	axb



doing 13 "escapes"
e  1	&	"a\\"		EESCAPE
m  2	-	{a\<b}		a<b	a<b
m  3	e	{a\<b}		a<b	a<b
m  4	bAS	{a\wb}		awb	awb
m  5	eAS	{a\wb}		awb	awb
m  6	PL	"a\\ab"		"a\007b"	"a\007b"
m  7	P	"a\\bb"		"a\bb"	"a\bb"
m  8	P	{a\Bb}		"a\\b"	"a\\b"
m  9	MP	"a\\chb"	"a\bb"	"a\bb"
m 10	MP	"a\\cHb"	"a\bb"	"a\bb"
m 11	LMP	"a\\e"		"a\033"	"a\033"
m 12	P	"a\\fb"		"a\fb"	"a\fb"
m 13	P	"a\\nb"		"a\nb"	"a\nb"
m 14	P	"a\\rb"		"a\rb"	"a\rb"
m 15	P	"a\\tb"		"a\tb"	"a\tb"
m 16	P	"a\\u0008x"	"a\bx"	"a\bx"
e 17	-	{a\u008x}	EESCAPE
m 18	P	"a\\u00088x"	"a\b8x"	"a\b8x"
m 19	P	"a\\U00000008x"	"a\bx"	"a\bx"
e 20	-	{a\U0000008x}	EESCAPE
m 21	P	"a\\vb"		"a\vb"	"a\vb"
m 22	MP	"a\\x08x"	"a\bx"	"a\bx"
e 23	-	{a\xq}		EESCAPE
m 24	MP	"a\\x0008x"	"a\bx"	"a\bx"
e 25	-	{a\z}		EESCAPE
m 26	MP	"a\\010b"	"a\bb"	"a\bb"



doing 14 "back references"
# ugh
m  1	{R[1P}	{a(b*)c\1}	abbcbb	abbcbb	bb
m  2	{R[1P}	{a(b*)c\1}	ac	ac	""
f  3	{R[1P}	{a(b*)c\1}	abbcb
m  4	{R[1P}	{a(b*)\1}	abbcbb	abb	b
m  5	{R[1P}	{a(b|bb)\1}	abbcbb	abb	b
m  6	{R[1P}	{a([bc])\1}	abb	abb	b
f  7	{R[1P}	{a([bc])\1}	abc
m  8	{R[1P}	{a([bc])\1}	abcabb	abb	b
f  9	{R[1P}	{a([bc])*\1}	abc
f 10	{R[1P}	{a([bc])\1}	abB
m 11	{iR[1P}	{a([bc])\1}	abB	abB	b
m 12	{R[1P}	{a([bc])\1+}	abbb	abbb	b
m 13	{QR[1P}	"a(\[bc])\\1{3,4}"	abbbb	abbbb	b
f 14	{QR[1P}	"a(\[bc])\\1{3,4}"	abbb
m 15	{R[1P}	{a([bc])\1*}	abbb	abbb	b
m 16	{R[1P}	{a([bc])\1*}	ab	ab	b
m 17	{R[2P}	{a([bc])(\1*)}	ab	ab	b	""
e 18	-	{a((b)\1)}	ESUBREG
e 19	-	{a(b)c\2}	ESUBREG
m 20	{bR[1}	{a\(b*\)c\1}	abbcbb	abbcbb	bb



doing 15 "octal escapes vs back references"
# initial zero is always octal
m  1	MP	"a\\010b"	"a\bb"	"a\bb"
m  2	MP	"a\\0070b"	"a\0070b"	"a\0070b"
m  3	MP	"a\\07b"	"a\007b"	"a\007b"
m  4	MP	"a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\\07c"	"abbbbbbbbbb\007c" \
	"abbbbbbbbbb\007c"	"b"	"b"	"b"	"b"	"b"	"b" \
	"b"	"b"	"b"	"b"
# a single digit is always a backref
e  5	-	{a\7b}		ESUBREG
# otherwise it's a backref only if within range (barf!)
m  6	MP	"a\\10b"	"a\bb"	"a\bb"
m  7	MP	{a\101b}	aAb	aAb
m  8	RP	{a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\10c}	abbbbbbbbbbbc \
	abbbbbbbbbbbc	b	b	b	b	b	b	b \
	b	b	b
# but we're fussy about border cases -- guys who want octal should use the zero
e  9	-	{a((((((((((b\10))))))))))c}	ESUBREG
# BREs don't have octal, EREs don't have backrefs
m 10	MP	"a\\12b"	"a\nb"	"a\nb"
e 11	b	{a\12b}		ESUBREG
m 12	eAS	{a\12b}		a12b	a12b



doing 16 "expanded syntax"
m  1	xP	"a b c"		"abc"	"abc"
m  2	xP	"a b #oops\nc\td"	"abcd"	"abcd"
m  3	x	"a\\ b\\\tc"	"a b\tc"	"a b\tc"
m  4	xP	"a b\\#c"	"ab#c"	"ab#c"
m  5	xP	"a b\[c d]e"	"ab e"	"ab e"
m  6	xP	"a b\[c#d]e"	"ab#e"	"ab#e"
m  7	xP	"a b\[c#d]e"	"abde"	"abde"
m  8	xSPB	"ab{ d"		"ab\{d"	"ab\{d"
m  9	xPQ	"ab{ 1 , 2 }c"	"abc"	"abc"



doing 17 "misc syntax"
m  1	P	a(?#comment)b	ab	ab



doing 18 "unmatchable REs"
f  1	I	a^b		ab



doing 19 "case independence"
m  1	&i	ab		Ab	Ab
m  2	&i	{a[bc]}		aC	aC
f  3	&i	{a[^bc]}	aB
m  4	&iM	{a[b-d]}	aC	aC
f  5	&iM	{a[^b-d]}	aC



doing 20 "directors and embedded options"
e  1	&	***?		BADPAT
m  2	q	***?		***?	***?
m  3	&P	***=a*b		a*b	a*b
m  4	q	***=a*b		***=a*b	***=a*b
m  5	bLP	{***:\w+}	ab	ab
m  6	eLP	{***:\w+}	ab	ab
e  7	&	***:***=a*b	BADRPT
m  8	&P	***:(?b)a+b	a+b	a+b
m  9	P	(?b)a+b		a+b	a+b
e 10	e	{(?b)\w+}	BADRPT
m 11	bAS	{(?b)\w+}	(?b)w+	(?b)w+
m 12	iP	(?c)a		a	a
f 13	iP	(?c)a		A
m 14	APS	{(?e)\W+}	WW	WW
m 15	P	(?i)a+		Aa	Aa
f 16	P	"(?m)a.b"	"a\nb"
m 17	P	"(?m)^b"	"a\nb"	"b"
f 18	P	"(?n)a.b"	"a\nb"
m 19	P	"(?n)^b"	"a\nb"	"b"
f 20	P	"(?p)a.b"	"a\nb"
f 21	P	"(?p)^b"	"a\nb"
m 22	P	(?q)a+b		a+b	a+b
m 23	nP	"(?s)a.b"	"a\nb"	"a\nb"
m 24	xP	"(?t)a b"	"a b"	"a b"
m 25	P	"(?w)a.b"	"a\nb"	"a\nb"
m 26	P	"(?w)^b"	"a\nb"	"b"
m 27	P	"(?x)a b"	"ab"	"ab"
e 28	-	(?z)ab		BADOPT
m 29	P	(?ici)a+	Aa	Aa
e 30	P	(?i)(?q)a+	BADRPT
m 31	P	(?q)(?i)a+	(?i)a+	(?i)a+
m 32	P	(?qe)a+		a	a
m 33	xP	"(?q)a b"	"a b"	"a b"
m 34	P	"(?qx)a b"	"a b"	"a b"
m 35	P	(?qi)ab		Ab	Ab



doing 21 "capturing"
m  1	-	a(b)c		abc	abc	b
m  2	P	a(?:b)c		xabc	abc
m  3	-	a((b))c		xabcy	abc	b	b
m  4	P	a(?:(b))c	abcy	abc	b
m  5	P	a((?:b))c	abc	abc	b
m  6	P	a(?:(?:b))c	abc	abc
i  7	Q	"a(b){0}c"	ac	{0 1}	{-1 -1}
m  8	-	a(b)c(d)e	abcde	abcde	b	d
m  9	-	(b)c(d)e	bcde	bcde	b	d
m 10	-	a(b)(d)e	abde	abde	b	d
m 11	-	a(b)c(d)	abcd	abcd	b	d
m 12	-	(ab)(cd)	xabcdy	abcd	ab	cd
m 13	-	a(b)?c		xabcy	abc	b
i 14	-	a(b)?c		xacy	{1 2}	{-1 -1}
m 15	-	a(b)?c(d)?e	xabcdey	abcde	b	d
i 16	-	a(b)?c(d)?e	xacdey	{1 4}	{-1 -1}	{3 3}
i 17	-	a(b)?c(d)?e	xabcey	{1 4}	{2 2}	{-1 -1}
i 18	-	a(b)?c(d)?e	xacey	{1 3}	{-1 -1}	{-1 -1}
m 19	-	a(b)*c		xabcy	abc	b
i 20	-	a(b)*c		xabbbcy	{1 5}	{4 4}
i 21	-	a(b)*c		xacy	{1 2}	{-1 -1}
m 22	-	a(b*)c		xabbbcy	abbbc	bbb
m 23	-	a(b*)c		xacy	ac	""
f 24	-	a(b)+c		xacy
m 25	-	a(b)+c		xabcy	abc	b
i 26	-	a(b)+c		xabbbcy	{1 5}	{4 4}
m 27	-	a(b+)c		xabbbcy	abbbc	bbb
i 28	Q	"a(b){2,3}c"	xabbbcy	{1 5}	{4 4}
i 29	Q	"a(b){2,3}c"	xabbcy	{1 4}	{3 3}
f 30	Q	"a(b){2,3}c"	xabcy
m 31	LP	"\\y(\\w+)\\y"	"-- abc-"	"abc"	"abc"
m 32	-	a((b|c)d+)+	abacdbd	acdbd	bd	b
m 33	N	(.*).*		abc	abc	abc
m 34	N	(a*)*		bc	""	""



doing 22 "multicharacter collating elements"
# again ugh
# currently disabled because the fake MCCE we use for testing is unavailable
xx m  1	&+L	{a[c]e}		ace	ace
xx f  2	&+I	{a[c]h}		ach
xx m  3	&+L	{a[[.ch.]]}	ach	ach
xx f  4	&+L	{a[[.ch.]]}	ace
xx m  5	&+L	{a[c[.ch.]]}	ac	ac
xx m  6	&+L	{a[c[.ch.]]}	ace	ac
xx m  7	&+L	{a[c[.ch.]]}	ache	ach
xx f  8	&+L	{a[^c]e}	ace
xx m  9	&+L	{a[^c]e}	abe	abe
xx m 10	&+L	{a[^c]e}	ache	ache
xx f 11	&+L	{a[^[.ch.]]}	ach
xx m 12	&+L	{a[^[.ch.]]}	ace	ac
xx m 13	&+L	{a[^[.ch.]]}	ac	ac
xx m 14	&+L	{a[^[.ch.]]}	abe	ab
xx f 15	&+L	{a[^c[.ch.]]}	ach
xx f 16	&+L	{a[^c[.ch.]]}	ace
xx f 17	&+L	{a[^c[.ch.]]}	ac
xx m 18	&+L	{a[^c[.ch.]]}	abe	ab
xx m 19	&+L	{a[^b]}		ac	ac
xx m 20	&+L	{a[^b]}		ace	ac
xx m 21	&+L	{a[^b]}		ach	ach
xx f 22	&+L	{a[^b]}		abe



doing 23 "lookahead constraints"
m  1	HP	a(?=b)b*	ab	ab
f  2	HP	a(?=b)b*	a
m  3	HP	a(?=b)b*(?=c)c*	abc	abc
f  4	HP	a(?=b)b*(?=c)c*	ab
f  5	HP	a(?!b)b*	ab
m  6	HP	a(?!b)b*	a	a
m  7	HP	(?=b)b		b	b
f  8	HP	(?=b)b		a



doing 24 "non-greedy quantifiers"
m  1	P	ab+?		abb	ab
m  2	P	ab+?c		abbc	abbc
m  3	P	ab*?		abb	a
m  4	P	ab*?c		abbc	abbc
m  5	P	ab??		ab	a
m  6	P	ab??c		abc	abc
m  7	PQ	"ab{2,4}?"	abbbb	abb
m  8	PQ	"ab{2,4}?c"	abbbbc	abbbbc



doing 25 "mixed quantifiers"
xx to be done, actually
xx should include |



doing 26 "tricky cases"
# attempts to trick the matcher into accepting a short match
m  1	-	(week|wee)(night|knights)	weeknights	weeknights \
	wee	knights
m  2	RP	{a(bc*).*\1}	abccbccb	abccbccb	b
m  3	-	{a(b.[bc]*)+}	abcbd	abcbd	bd



doing 27 "implementation misc."
# duplicate arcs are suppressed
m  1	P	a(?:b|b)c	abc	abc
# make color/subcolor relationship go back and forth
m  2	&	{[ab][ab][ab]}	aba	aba
m  3	&	{[ab][ab][ab][ab][ab][ab][ab]}	abababa	abababa



doing 28 "boundary busters etc."
# color-descriptor allocation changes at 10
m  1	&	abcdefghijkl	abcdefghijkl	abcdefghijkl
# so does arc allocation
m  2	P	a(?:b|c|d|e|f|g|h|i|j|k|l|m)n	agn	agn
# subexpression tracking also at 10
m  3	-	a(((((((((((((b)))))))))))))c	abc	abc	b	b	b	b	b	b	b	b	b	b	b	b	b
# state-set handling changes slightly at unsigned size (might be 64...)
# (also stresses arc allocation)
m  4	Q	"ab{1,100}c"	abbc	abbc
m  5	Q	"ab{1,100}c"	abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc \
	abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
m  6	Q	"ab{1,100}c" \
	abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc \
	abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
# force small cache and bust it, several ways
m  7	LP	{\w+abcdefgh}	xyzabcdefgh	xyzabcdefgh
m  8	%LP	{\w+abcdefgh}	xyzabcdefgh	xyzabcdefgh
m  9	%LP	{\w+abcdefghijklmnopqrst}	xyzabcdefghijklmnopqrst \
	xyzabcdefghijklmnopqrst
i 10	%LP	{\w+(abcdefgh)?}	xyz	{0 2}	{-1 -1}
i 11	%LP	{\w+(abcdefgh)?}	xyzabcdefg	{0 9}	{-1 -1}
i 12	%LP	{\w+(abcdefghijklmnopqrst)?}	xyzabcdefghijklmnopqrs \
	{0 21}	{-1 -1}



doing 29 "misc. oddities and old bugs"
e  1	&	***		BADRPT
m  2	N	a?b*		abb	abb
m  3	N	a?b*		bb	bb
m  4	&	a*b		aab	aab
m  5	&	^a*b		aaaab aaaab
m  6	&M	 {[0-6][1-2][0-3][0-6][1-6][0-6]}	010010	010010



doing 0 "flush"			;# to flush any leftover complaints

# cleanup
::tcltest::cleanupTests
return


Changes to tests/regexp.test.

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
# Commands covered:  regexp, regsub
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) regexp.test 1.21 96/12/23 13:59:48



if {[string compare test [info procs test]] == 1} then {source defs}

catch {unset foo}
test regexp-1.1 {basic regexp operation} {
    regexp ab*c abbbc
} 1
test regexp-1.2 {basic regexp operation} {
    regexp ab*c ac
} 1
test regexp-1.3 {basic regexp operation} {
    regexp ab*c ab
} 0
test regexp-1.4 {basic regexp operation} {
    regexp -- -gorp abc-gorpxxx
} 1
test regexp-1.5 {basic regexp operation} {
    regexp {^([^ ]*)[ ]*([^ ]*)} "" a
} 1










test regexp-2.1 {getting substrings back from regexp} {
    set foo {}
    list [regexp ab*c abbbbc foo] $foo
} {1 abbbbc}
test regexp-2.2 {getting substrings back from regexp} {
    set foo {}







|
>




>
|
>
>
|
<

















>
>
>
>
>
>
>
>
>







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
# Commands covered:  regexp, regsub
#
# 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) 1998 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: regexp.test,v 1.1.2.9 1999/03/24 02:49:36 hershey Exp $

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


catch {unset foo}
test regexp-1.1 {basic regexp operation} {
    regexp ab*c abbbc
} 1
test regexp-1.2 {basic regexp operation} {
    regexp ab*c ac
} 1
test regexp-1.3 {basic regexp operation} {
    regexp ab*c ab
} 0
test regexp-1.4 {basic regexp operation} {
    regexp -- -gorp abc-gorpxxx
} 1
test regexp-1.5 {basic regexp operation} {
    regexp {^([^ ]*)[ ]*([^ ]*)} "" a
} 1
test regexp-1.6 {basic regexp operation} {
    list [catch {regexp {} abc} msg] $msg
} {0 1}
test regexp-1.7 {regexp utf compliance} {
    # if not UTF-8 aware, result is "0 1"
    set foo "\u4e4eb q"
    regexp "\u4e4eb q" "a\u4e4eb qw\u5e4e\x4e wq" bar
    list [string compare $foo $bar] [regexp 4 $bar]
} {0 0}

test regexp-2.1 {getting substrings back from regexp} {
    set foo {}
    list [regexp ab*c abbbbc foo] $foo
} {1 abbbbc}
test regexp-2.2 {getting substrings back from regexp} {
    set foo {}
63
64
65
66
67
68
69
70



71
72
73
74
75
76
77
    set foo 2; set f2 2; set f3 2; set f4 2
    list [regexp (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
} {1 a a {} {}}
test regexp-2.7 {getting substrings back from regexp} {
    set foo 1; set f2 1; set f3 1; set f4 1
    list [regexp (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
} {1 ac a {} c}





test regexp-3.1 {-indices option to regexp} {
    set foo {}
    list [regexp -indices ab*c abbbbc foo] $foo
} {1 {0 5}}
test regexp-3.2 {-indices option to regexp} {
    set foo {}







|
>
>
>







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
    set foo 2; set f2 2; set f3 2; set f4 2
    list [regexp (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
} {1 a a {} {}}
test regexp-2.7 {getting substrings back from regexp} {
    set foo 1; set f2 1; set f3 1; set f4 1
    list [regexp (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
} {1 ac a {} c}
test regexp-2.8 {getting substrings back from regexp} {
    set match {}
    list [regexp {^a*b} aaaab match] $match
} {1 aaaab}

test regexp-3.1 {-indices option to regexp} {
    set foo {}
    list [regexp -indices ab*c abbbbc foo] $foo
} {1 {0 5}}
test regexp-3.2 {-indices option to regexp} {
    set foo {}
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    list [regexp -nocase {a(b*)([xy]*)z} aBbbxYXxxZ22 f1 f2 f3] $f1 $f2 $f3
} {1 aBbbxYXxxZ Bbb xYXxx}
test regexp-4.3 {-nocase option to regexp} {
    regexp -nocase FOo abcFOo
} 1
set x abcdefghijklmnopqrstuvwxyz1234567890
set x $x$x$x$x$x$x$x$x$x$x$x$x
test regexp-4.4 {case conversion in regsub} {
    list [regexp -nocase $x $x foo] $foo
} "1 $x"
unset x

test regexp-5.1 {exercise cache of compiled expressions} {
    regexp .*a b
    regexp .*b c
    regexp .*c d
    regexp .*d e
    regexp .*e f







|


|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
    list [regexp -nocase {a(b*)([xy]*)z} aBbbxYXxxZ22 f1 f2 f3] $f1 $f2 $f3
} {1 aBbbxYXxxZ Bbb xYXxx}
test regexp-4.3 {-nocase option to regexp} {
    regexp -nocase FOo abcFOo
} 1
set x abcdefghijklmnopqrstuvwxyz1234567890
set x $x$x$x$x$x$x$x$x$x$x$x$x
test regexp-4.4 {case conversion in regexp} {
    list [regexp -nocase $x $x foo] $foo
} "1 $x"
catch {unset x}

test regexp-5.1 {exercise cache of compiled expressions} {
    regexp .*a b
    regexp .*b c
    regexp .*c d
    regexp .*d e
    regexp .*e f
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
    list [catch {regexp a} msg] $msg
} {1 {wrong # args: should be "regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"}}
test regexp-6.2 {regexp errors} {
    list [catch {regexp -nocase a} msg] $msg
} {1 {wrong # args: should be "regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"}}
test regexp-6.3 {regexp errors} {
    list [catch {regexp -gorp a} msg] $msg
} {1 {bad switch "-gorp": must be -indices, -nocase, or --}}
test regexp-6.4 {regexp errors} {
    list [catch {regexp a( b} msg] $msg
} {1 {couldn't compile regular expression pattern: unmatched ()}}
test regexp-6.5 {regexp errors} {
    list [catch {regexp a( b} msg] $msg
} {1 {couldn't compile regular expression pattern: unmatched ()}}
test regexp-6.6 {regexp errors} {
    list [catch {regexp a a f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1} msg] $msg
} {0 1}
test regexp-6.7 {regexp errors} {
    list [catch {regexp (x)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) xyzzy} msg] $msg
} {1 {couldn't compile regular expression pattern: too many ()}}
test regexp-6.8 {regexp errors} {

    set f1 44
    list [catch {regexp abc abc f1(f2)} msg] $msg
} {1 {couldn't set variable "f1(f2)"}}

test regexp-7.1 {basic regsub operation} {
    list [regsub aa+ xaxaaaxaa 111&222 foo] $foo
} {1 xax111aaa222xaa}







|


|


|





|

>







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
    list [catch {regexp a} msg] $msg
} {1 {wrong # args: should be "regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"}}
test regexp-6.2 {regexp errors} {
    list [catch {regexp -nocase a} msg] $msg
} {1 {wrong # args: should be "regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"}}
test regexp-6.3 {regexp errors} {
    list [catch {regexp -gorp a} msg] $msg
} {1 {bad switch "-gorp": must be -indices, -nocase, -about, -expanded, -line, -linestop, -lineanchor, or --}}
test regexp-6.4 {regexp errors} {
    list [catch {regexp a( b} msg] $msg
} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
test regexp-6.5 {regexp errors} {
    list [catch {regexp a( b} msg] $msg
} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
test regexp-6.6 {regexp errors} {
    list [catch {regexp a a f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1} msg] $msg
} {0 1}
test regexp-6.7 {regexp errors} {
    list [catch {regexp (x)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) xyzzy} msg] $msg
} {0 0}
test regexp-6.8 {regexp errors} {
    catch {unset f1}
    set f1 44
    list [catch {regexp abc abc f1(f2)} msg] $msg
} {1 {couldn't set variable "f1(f2)"}}

test regexp-7.1 {basic regsub operation} {
    list [regsub aa+ xaxaaaxaa 111&222 foo] $foo
} {1 xax111aaa222xaa}
240
241
242
243
244
245
246






247
248
249
250
251
252
253
    set foo xxx
    list [regsub -- -foo abc-foodef "111 " foo] $foo
} {1 {abc111 def}}
test regexp-7.16 {basic regsub operation} {
    set foo xxx
    list [regsub x "" y foo] $foo
} {0 {}}







test regexp-8.1 {case conversion in regsub} {
    list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
} {1 xaAAaAAay}
test regexp-8.2 {case conversion in regsub} {
    list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
} {1 xaAAaAAay}







>
>
>
>
>
>







256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
    set foo xxx
    list [regsub -- -foo abc-foodef "111 " foo] $foo
} {1 {abc111 def}}
test regexp-7.16 {basic regsub operation} {
    set foo xxx
    list [regsub x "" y foo] $foo
} {0 {}}
test regexp-7.17 {regsub utf compliance} {
    # if not UTF-8 aware, result is "0 1"
    set foo "xyz555ijka\u4e4ebpqr"
    regsub a\u4e4eb xyza\u4e4ebijka\u4e4ebpqr 555 bar
    list [string compare $foo $bar] [regexp 4 $bar]
} {0 0}

test regexp-8.1 {case conversion in regsub} {
    list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
} {1 xaAAaAAay}
test regexp-8.2 {case conversion in regsub} {
    list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
} {1 xaAAaAAay}
308
309
310
311
312
313
314
315
316


317
318




































    list [catch {regsub a b c d e f} msg] $msg
} {1 {wrong # args: should be "regsub ?switches? exp string subSpec varName"}}
test regexp-10.5 {regsub errors} {
    list [catch {regsub -gorp a b c} msg] $msg
} {1 {bad switch "-gorp": must be -all, -nocase, or --}}
test regexp-10.6 {regsub errors} {
    list [catch {regsub -nocase a( b c d} msg] $msg
} {1 {couldn't compile regular expression pattern: unmatched ()}}
test regexp-10.7 {regsub errors} {


    list [catch {regsub -nocase aaa aaa xxx f1(f2)} msg] $msg
} {1 {couldn't set variable "f1(f2)"}}











































|

>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    list [catch {regsub a b c d e f} msg] $msg
} {1 {wrong # args: should be "regsub ?switches? exp string subSpec varName"}}
test regexp-10.5 {regsub errors} {
    list [catch {regsub -gorp a b c} msg] $msg
} {1 {bad switch "-gorp": must be -all, -nocase, or --}}
test regexp-10.6 {regsub errors} {
    list [catch {regsub -nocase a( b c d} msg] $msg
} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
test regexp-10.7 {regsub errors} {
    catch {unset f1}
    set f1 44
    list [catch {regsub -nocase aaa aaa xxx f1(f2)} msg] $msg
} {1 {couldn't set variable "f1(f2)"}}

test regexp-11.1 {Tcl_RegExpExec: large number of subexpressions} {
    list [regexp (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) abcdefghijklmnopqrstuvwxyz all a b c d e f g h i j k l m n o p q r s t u v w x y z] $all $a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z
} {1 abcdefghijklmnopqrstuvwxyz a b c d e f g h i j k l m n o p q r s t u v w x y z}

test regexp-12.1 {regsub of a very large string} {
    # This test is designed to stress the memory subsystem in order
    # to catch Bug #933.  It only fails if the Tcl memory allocator
    # is in use.

    set line {BEGIN_TABLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END_TABLE}
    set filedata ""
    for {set i 1} {$i<200} {incr i} {
	append filedata $line
    }
    for {set i 1} {$i<10} {incr i} {
	regsub -all "BEGIN_TABLE " $filedata "" newfiledata
    }
    set x done
} {done}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/registry.test.

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15

16
17
18
19
20




21
22
23
24
25
26
27
28
29
30
31


32
33


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149








150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171








172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214


















215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289






290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
























383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436


437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507


508
509
510
511

512















# registry.test --
#
# This file contains a collection of tests for the registry command.
# Sourcing this file into Tcl runs the tests and generates output for
# errors.  No output means no errors were found.
#
# In order for these tests to run, the registry package must be on the
# auto_path or the registry package must have been loaded already.
#
# Copyright (c) 1997 by Sun Microsystems, Inc.  All rights reserved.

#
# SCCS: @(#) registry.test 1.5 97/08/01 11:14:25

if {$tcl_platform(platform) != "windows"} {
    return

}

if {[string compare test [info procs test]] == 1} then {source defs}

if [catch {package require registry}] {




    puts "Unable to find the registry package. Skipping registry tests."
    return
}

if {$testConfig(win32s)} {
    puts "Skipping registry tests under Win32s"
    return
}

switch $tcl_platform(os) {
    "Windows NT" {set testConfig(NT) 1}


    "Windows 95" {set testConfig(95) 1}
}



set hostname [info hostname]

test registry-1.1 {argument parsing for registry command} {
    list [catch {registry} msg] $msg
} {1 {wrong # args: should be "registry option ?arg arg ...?"}}
test registry-1.2 {argument parsing for registry command} {
    list [catch {registry foo} msg] $msg
} {1 {bad option "foo": must be delete, get, keys, set, type, or values}}

test registry-1.3 {argument parsing for registry command} {
    list [catch {registry d} msg] $msg
} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
test registry-1.4 {argument parsing for registry command} {
    list [catch {registry delete} msg] $msg
} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
test registry-1.5 {argument parsing for registry command} {
    list [catch {registry delete foo bar baz} msg] $msg
} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}

test registry-1.6 {argument parsing for registry command} {
    list [catch {registry g} msg] $msg
} {1 {wrong # args: should be "registry get keyName valueName"}}
test registry-1.7 {argument parsing for registry command} {
    list [catch {registry get} msg] $msg
} {1 {wrong # args: should be "registry get keyName valueName"}}
test registry-1.8 {argument parsing for registry command} {
    list [catch {registry get foo} msg] $msg
} {1 {wrong # args: should be "registry get keyName valueName"}}
test registry-1.9 {argument parsing for registry command} {
    list [catch {registry get foo bar baz} msg] $msg
} {1 {wrong # args: should be "registry get keyName valueName"}}

test registry-1.10 {argument parsing for registry command} {
    list [catch {registry k} msg] $msg
} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
test registry-1.11 {argument parsing for registry command} {
    list [catch {registry keys} msg] $msg
} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
test registry-1.12 {argument parsing for registry command} {
    list [catch {registry keys foo bar baz} msg] $msg
} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}

test registry-1.13 {argument parsing for registry command} {
    list [catch {registry s} msg] $msg
} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
test registry-1.14 {argument parsing for registry command} {
    list [catch {registry set} msg] $msg
} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
test registry-1.15 {argument parsing for registry command} {
    list [catch {registry set foo bar} msg] $msg
} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
test registry-1.16 {argument parsing for registry command} {
    list [catch {registry set foo bar baz blat gorp} msg] $msg
} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}

test registry-1.17 {argument parsing for registry command} {
    list [catch {registry t} msg] $msg
} {1 {wrong # args: should be "registry type keyName valueName"}}
test registry-1.18 {argument parsing for registry command} {
    list [catch {registry type} msg] $msg
} {1 {wrong # args: should be "registry type keyName valueName"}}
test registry-1.19 {argument parsing for registry command} {
    list [catch {registry type foo} msg] $msg
} {1 {wrong # args: should be "registry type keyName valueName"}}
test registry-1.20 {argument parsing for registry command} {
    list [catch {registry type foo bar baz} msg] $msg
} {1 {wrong # args: should be "registry type keyName valueName"}}

test registry-1.21 {argument parsing for registry command} {
    list [catch {registry v} msg] $msg
} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
test registry-1.22 {argument parsing for registry command} {
    list [catch {registry values} msg] $msg
} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
test registry-1.23 {argument parsing for registry command} {
    list [catch {registry values foo bar baz} msg] $msg
} {1 {wrong # args: should be "registry values keyName ?pattern?"}}

test registry-2.1 {DeleteKey: bad key} {
    list [catch {registry delete foo} msg] $msg
} {1 {bad root name "foo": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, or HKEY_CURRENT_CONFIG}}
test registry-2.2 {DeleteKey: bad key} {
    list [catch {registry delete HKEY_CLASSES_ROOT} msg] $msg
} {1 {bad key: cannot delete root keys}}
test registry-2.3 {DeleteKey: bad key} {
    list [catch {registry delete HKEY_CLASSES_ROOT\\} msg] $msg
} {1 {bad key: cannot delete root keys}}
test registry-2.4 {DeleteKey: subkey at root level} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry keys HKEY_CLASSES_ROOT TclFoobar
} {}
test registry-2.5 {DeleteKey: subkey below root level} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test
    registry delete HKEY_CLASSES_ROOT\\TclFoobar\\test
    set result [registry keys HKEY_CLASSES_ROOT TclFoobar\\test]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}
test registry-2.6 {DeleteKey: recursive delete} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test1
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test2\\test3
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result [registry keys HKEY_CLASSES_ROOT TclFoobar]
    set result
} {}
test registry-2.7 {DeleteKey: trailing backslashes} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz
    list [catch {registry delete HKEY_CLASSES_ROOT\\TclFoobar\\} msg] $msg
} {1 {unable to delete key: The configuration registry key is invalid.}}
test registry-2.8 {DeleteKey: failure} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
} {}










test registry-3.1 {DeleteValue} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz test1 blort
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz test2 blat
    registry delete HKEY_CLASSES_ROOT\\TclFoobar\\baz test1
    set result [registry values HKEY_CLASSES_ROOT\\TclFoobar\\baz]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} test2
test registry-3.2 {DeleteValue: bad key} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry delete HKEY_CLASSES_ROOT\\TclFoobar test} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}
test registry-3.3 {DeleteValue: bad value} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz test2 blort
    set result [list [catch {registry delete HKEY_CLASSES_ROOT\\TclFoobar test1} msg] $msg]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {1 {unable to delete value "test1" from key "HKEY_CLASSES_ROOT\TclFoobar": The system cannot find the file specified.}}










test registry-4.1 {GetKeyNames: bad key} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry keys HKEY_CLASSES_ROOT\\TclFoobar} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}
test registry-4.2 {GetKeyNames} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz
    set result [registry keys HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {baz}
test registry-4.3 {GetKeyNames: remote key} {nonPortable} {
    registry set \\\\$hostname\\HKEY_CLASSES_ROOT\\TclFoobar\\baz
    set result [registry keys \\\\gaspode\\HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete \\\\$hostname\\HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {baz}
test registry-4.4 {GetKeyNames: empty key} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    set result [registry keys HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}
test registry-4.5 {GetKeyNames: patterns} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\blat
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\foo
    set result [lsort [registry keys HKEY_CLASSES_ROOT\\TclFoobar b*]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {baz blat}
test registry-4.6 {GetKeyNames: names with spaces} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz\ bar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\blat
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\foo
    set result [lsort [registry keys HKEY_CLASSES_ROOT\\TclFoobar b*]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {{baz bar} blat}



















test registry-5.1 {GetType} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry type HKEY_CLASSES_ROOT\\TclFoobar val1} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}
test registry-5.2 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry type HKEY_CLASSES_ROOT\\TclFoobar val1} msg] $msg
} {1 {unable to get type of value "val1" from key "HKEY_CLASSES_ROOT\TclFoobar": The system cannot find the file specified.}}
test registry-5.3 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar none
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} none
test registry-5.4 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} sz
test registry-5.5 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar sz
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} sz
test registry-5.6 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar expand_sz
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} expand_sz
test registry-5.7 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 binary
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} binary
test registry-5.8 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 dword
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} dword
test registry-5.9 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 dword_big_endian
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} dword_big_endian
test registry-5.10 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 link
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} link
test registry-5.11 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar multi_sz
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} multi_sz
test registry-5.12 {GetType} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 resource_list
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} resource_list
test registry-5.13 {GetType: unknown types} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 24
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 24







test registry-6.1 {GetValue} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry get HKEY_CLASSES_ROOT\\TclFoobar val1} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}
test registry-6.2 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry get HKEY_CLASSES_ROOT\\TclFoobar val1} msg] $msg
} {1 {unable to get value "val1" from key "HKEY_CLASSES_ROOT\TclFoobar": The system cannot find the file specified.}}
test registry-6.3 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar none
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.4 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.5 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.6 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar expand_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.7 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 binary
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 1
test registry-6.8 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 0x20 dword
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 32
test registry-6.9 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 0x20 dword_big_endian
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 32
test registry-6.10 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 link
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 1
test registry-6.11 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.12 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 {foo\ bar baz} multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {{foo bar} baz}
test registry-6.13 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 {} multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}
test registry-6.14 {GetValue: truncation of multivalues with null elements} {

    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 {a {} b} multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} a
test registry-6.15 {GetValue} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 resource_list
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 1
test registry-6.16 {GetValue: unknown types} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 24
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 1

























test registry-7.1 {GetValueNames: bad key} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry values HKEY_CLASSES_ROOT\\TclFoobar} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}
test registry-7.2 {GetValueNames} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar baz foobar
    set result [registry values HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} baz
test registry-7.3 {GetValueNames} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar baz foobar1
    registry set HKEY_CLASSES_ROOT\\TclFoobar blat foobar2
    registry set HKEY_CLASSES_ROOT\\TclFoobar {} foobar3
    set result [lsort [registry values HKEY_CLASSES_ROOT\\TclFoobar]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {{} baz blat}
test registry-7.4 {GetValueNames: remote key} {nonPortable} {
    registry set \\\\$hostname\\HKEY_CLASSES_ROOT\\TclFoobar baz blat
    set result [registry values \\\\gaspode\\HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete \\\\$hostname\\HKEY_CLASSES_ROOT\\TclFoobar
    set result
} baz
test registry-7.5 {GetValueNames: empty key} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    set result [registry values HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}
test registry-7.6 {GetValueNames: patterns} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar baz foobar1
    registry set HKEY_CLASSES_ROOT\\TclFoobar blat foobar2
    registry set HKEY_CLASSES_ROOT\\TclFoobar foo foobar3
    set result [lsort [registry values HKEY_CLASSES_ROOT\\TclFoobar b*]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {baz blat}
test registry-7.7 {GetValueNames: names with spaces} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar baz\ bar foobar1
    registry set HKEY_CLASSES_ROOT\\TclFoobar blat foobar2
    registry set HKEY_CLASSES_ROOT\\TclFoobar foo foobar3
    set result [lsort [registry values HKEY_CLASSES_ROOT\\TclFoobar b*]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {{baz bar} blat}

test registry-8.1 {OpenSubKey} {nonPortable} {


    list [catch {registry keys {\\petrouchka\HKEY_LOCAL_MACHINE}} msg] $msg
} {1 {unable to open key: Access is denied.}}
test registry-8.2 {OpenSubKey} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    set result [registry keys HKEY_CLASSES_ROOT TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} TclFoobar
test registry-8.3 {OpenSubKey} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry keys HKEY_CLASSES_ROOT\\TclFoobar} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}

test registry-9.1 {ParseKeyName: bad keys} {
    list [catch {registry values \\} msg] $msg
} "1 {bad key \"\\\": must start with a valid root}"
test registry-9.2 {ParseKeyName: bad keys} {
    list [catch {registry values \\foobar} msg] $msg
} {1 {bad key "\foobar": must start with a valid root}}
test registry-9.3 {ParseKeyName: bad keys} {
    list [catch {registry values \\\\} msg] $msg
} {1 {ambiguous root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, or HKEY_CURRENT_CONFIG}}
test registry-9.4 {ParseKeyName: bad keys} {
    list [catch {registry values \\\\\\} msg] $msg
} {1 {ambiguous root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, or HKEY_CURRENT_CONFIG}}
test registry-9.5 {ParseKeyName: bad keys} {
    list [catch {registry values \\\\\\HKEY_CLASSES_ROOT} msg] $msg
} {1 {unable to open key: The network address is invalid.}}
test registry-9.6 {ParseKeyName: bad keys} {
    list [catch {registry values \\\\gaspode} msg] $msg
} {1 {ambiguous root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, or HKEY_CURRENT_CONFIG}}
test registry-9.7 {ParseKeyName: bad keys} {
    list [catch {registry values foobar} msg] $msg
} {1 {bad root name "foobar": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, or HKEY_CURRENT_CONFIG}}
test registry-9.8 {ParseKeyName: null keys} {
    list [catch {registry delete HKEY_CLASSES_ROOT\\} msg] $msg
} {1 {bad key: cannot delete root keys}}
test registry-9.9 {ParseKeyName: null keys} {
    list [catch {registry keys HKEY_CLASSES_ROOT\\TclFoobar\\baz} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}

test registry-10.1 {RecursiveDeleteKey} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test1
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test2\\test3
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result [registry keys HKEY_CLASSES_ROOT TclFoobar]
    set result
} {}
test registry-10.2 {RecursiveDeleteKey} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test1
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test2\\test3
    set result [registry delete HKEY_CLASSES_ROOT\\TclFoobar\\test2\\test4]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}

test registry-11.1 {SetValue: recursive creation} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz blat foobar
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar\\baz blat]
} foobar
test registry-11.2 {SetValue: modification} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz blat foobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz blat frob
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar\\baz blat]
} frob
test registry-11.3 {SetValue: failure} {nonPortable} {


    list [catch {registry set {\\petrouchka\HKEY_CLASSES_ROOT\TclFoobar} bar foobar} msg] $msg
} {1 {unable to open key: Access is denied.}}



unset hostname

























>

|

<
|
>


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

>
>



|


|



|


|


|



|


|


|


|



|


|


|



|


|


|


|



|


|


|


|



|


|


|



|

|
|


|


|




|






|






|



|



|
>
>
>
>
>
>
>
>

|








|



|






|
>
>
>
>
>
>
>
>

|



|






|





|






|








|








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

|



|



|





|





|





|





|





|





|





|





|





|





|





>
>
>
>
>
>

|



|



|





|





|





|





|





|





|





|





|





|





|





|
>





|





|





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

|



|






|








|

|



|






|








|









|
>
>
|

|






|




|


|


|

|
|

|
|


|

|
|

|
|


|



|







|








|




|





|
>
>
|



>

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

15
16
17
18

19
20
21
22
23
24
25
26
27
28



29
30

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


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


if {$tcl_platform(platform) == "windows"} {
    if [catch {
	set lib [lindex [glob [file join [pwd] [file dirname \
		[info nameofexecutable]] tclreg*.dll]] 0]
	load $lib registry
    }] {
	puts "Unable to find the registry package. Skipping registry tests."
	return
    }
}




# determine the current locale

set old [testlocale all]
if {![string compare [testlocale all ""] "English_United States.1252"]} {
	# error messages from registry package are already localized.
    set ::tcltest::testConfig(english) 1
}
testlocale all $old
unset old

set hostname [info hostname]

test registry-1.1 {argument parsing for registry command} {pcOnly} {
    list [catch {registry} msg] $msg
} {1 {wrong # args: should be "registry option ?arg arg ...?"}}
test registry-1.2 {argument parsing for registry command} {pcOnly} {
    list [catch {registry foo} msg] $msg
} {1 {bad option "foo": must be delete, get, keys, set, type, or values}}

test registry-1.3 {argument parsing for registry command} {pcOnly} {
    list [catch {registry d} msg] $msg
} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
test registry-1.4 {argument parsing for registry command} {pcOnly} {
    list [catch {registry delete} msg] $msg
} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
test registry-1.5 {argument parsing for registry command} {pcOnly} {
    list [catch {registry delete foo bar baz} msg] $msg
} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}

test registry-1.6 {argument parsing for registry command} {pcOnly} {
    list [catch {registry g} msg] $msg
} {1 {wrong # args: should be "registry get keyName valueName"}}
test registry-1.7 {argument parsing for registry command} {pcOnly} {
    list [catch {registry get} msg] $msg
} {1 {wrong # args: should be "registry get keyName valueName"}}
test registry-1.8 {argument parsing for registry command} {pcOnly} {
    list [catch {registry get foo} msg] $msg
} {1 {wrong # args: should be "registry get keyName valueName"}}
test registry-1.9 {argument parsing for registry command} {pcOnly} {
    list [catch {registry get foo bar baz} msg] $msg
} {1 {wrong # args: should be "registry get keyName valueName"}}

test registry-1.10 {argument parsing for registry command} {pcOnly} {
    list [catch {registry k} msg] $msg
} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
test registry-1.11 {argument parsing for registry command} {pcOnly} {
    list [catch {registry keys} msg] $msg
} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
test registry-1.12 {argument parsing for registry command} {pcOnly} {
    list [catch {registry keys foo bar baz} msg] $msg
} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}

test registry-1.13 {argument parsing for registry command} {pcOnly} {
    list [catch {registry s} msg] $msg
} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
test registry-1.14 {argument parsing for registry command} {pcOnly} {
    list [catch {registry set} msg] $msg
} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
test registry-1.15 {argument parsing for registry command} {pcOnly} {
    list [catch {registry set foo bar} msg] $msg
} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
test registry-1.16 {argument parsing for registry command} {pcOnly} {
    list [catch {registry set foo bar baz blat gorp} msg] $msg
} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}

test registry-1.17 {argument parsing for registry command} {pcOnly} {
    list [catch {registry t} msg] $msg
} {1 {wrong # args: should be "registry type keyName valueName"}}
test registry-1.18 {argument parsing for registry command} {pcOnly} {
    list [catch {registry type} msg] $msg
} {1 {wrong # args: should be "registry type keyName valueName"}}
test registry-1.19 {argument parsing for registry command} {pcOnly} {
    list [catch {registry type foo} msg] $msg
} {1 {wrong # args: should be "registry type keyName valueName"}}
test registry-1.20 {argument parsing for registry command} {pcOnly} {
    list [catch {registry type foo bar baz} msg] $msg
} {1 {wrong # args: should be "registry type keyName valueName"}}

test registry-1.21 {argument parsing for registry command} {pcOnly} {
    list [catch {registry v} msg] $msg
} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
test registry-1.22 {argument parsing for registry command} {pcOnly} {
    list [catch {registry values} msg] $msg
} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
test registry-1.23 {argument parsing for registry command} {pcOnly} {
    list [catch {registry values foo bar baz} msg] $msg
} {1 {wrong # args: should be "registry values keyName ?pattern?"}}

test registry-2.1 {DeleteKey: bad key} {pcOnly} {
    list [catch {registry delete foo} msg] $msg
} {1 {bad root name "foo": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}}
test registry-2.2 {DeleteKey: bad key} {pcOnly} {
    list [catch {registry delete HKEY_CLASSES_ROOT} msg] $msg
} {1 {bad key: cannot delete root keys}}
test registry-2.3 {DeleteKey: bad key} {pcOnly} {
    list [catch {registry delete HKEY_CLASSES_ROOT\\} msg] $msg
} {1 {bad key: cannot delete root keys}}
test registry-2.4 {DeleteKey: subkey at root level} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry keys HKEY_CLASSES_ROOT TclFoobar
} {}
test registry-2.5 {DeleteKey: subkey below root level} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test
    registry delete HKEY_CLASSES_ROOT\\TclFoobar\\test
    set result [registry keys HKEY_CLASSES_ROOT TclFoobar\\test]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}
test registry-2.6 {DeleteKey: recursive delete} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test1
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test2\\test3
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result [registry keys HKEY_CLASSES_ROOT TclFoobar]
    set result
} {}
test registry-2.7 {DeleteKey: trailing backslashes} {pcOnly english} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz
    list [catch {registry delete HKEY_CLASSES_ROOT\\TclFoobar\\} msg] $msg
} {1 {unable to delete key: The configuration registry key is invalid.}}
test registry-2.8 {DeleteKey: failure} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
} {}
test registry-2.9 {DeleteKey: unicode} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test\u00c7bar\\a
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test\u00c7bar\\b
    registry delete HKEY_CLASSES_ROOT\\TclFoobar\\test\u00c7bar
    set result [registry keys HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}

test registry-3.1 {DeleteValue} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz test1 blort
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz test2 blat
    registry delete HKEY_CLASSES_ROOT\\TclFoobar\\baz test1
    set result [registry values HKEY_CLASSES_ROOT\\TclFoobar\\baz]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} test2
test registry-3.2 {DeleteValue: bad key} {pcOnly english} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry delete HKEY_CLASSES_ROOT\\TclFoobar test} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}
test registry-3.3 {DeleteValue: bad value} {pcOnly english} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz test2 blort
    set result [list [catch {registry delete HKEY_CLASSES_ROOT\\TclFoobar test1} msg] $msg]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {1 {unable to delete value "test1" from key "HKEY_CLASSES_ROOT\TclFoobar": The system cannot find the file specified.}}
test registry-3.4 {DeleteValue: Unicode} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\\u00c7baz \u00c7test1 blort
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\\u00c7baz test2 blat
    registry delete HKEY_CLASSES_ROOT\\TclFoobar\\\u00c7baz \u00c7test1
    set result [registry values HKEY_CLASSES_ROOT\\TclFoobar\\\u00c7baz]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} test2

test registry-4.1 {GetKeyNames: bad key} {pcOnly english} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry keys HKEY_CLASSES_ROOT\\TclFoobar} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}
test registry-4.2 {GetKeyNames} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz
    set result [registry keys HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {baz}
test registry-4.3 {GetKeyNames: remote key} {pcOnly nonPortable english} {
    registry set \\\\$hostname\\HKEY_CLASSES_ROOT\\TclFoobar\\baz
    set result [registry keys \\\\gaspode\\HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete \\\\$hostname\\HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {baz}
test registry-4.4 {GetKeyNames: empty key} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    set result [registry keys HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}
test registry-4.5 {GetKeyNames: patterns} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\blat
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\foo
    set result [lsort [registry keys HKEY_CLASSES_ROOT\\TclFoobar b*]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {baz blat}
test registry-4.6 {GetKeyNames: names with spaces} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz\ bar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\blat
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\foo
    set result [lsort [registry keys HKEY_CLASSES_ROOT\\TclFoobar b*]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {{baz bar} blat}
test registry-4.7 {GetKeyNames: Unicode} {pcOnly english} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz\u00c7bar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\blat
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\foo
    set result [lsort [registry keys HKEY_CLASSES_ROOT\\TclFoobar b*]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} "baz\u00c7bar blat"
test registry-4.8 {GetKeyNames: Unicode} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz\u30b7bar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\blat
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\foo
    set result [lsort [registry keys HKEY_CLASSES_ROOT\\TclFoobar b*]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} "baz\u30b7bar blat"

test registry-5.1 {GetType} {pcOnly english} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry type HKEY_CLASSES_ROOT\\TclFoobar val1} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}
test registry-5.2 {GetType} {pcOnly english} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry type HKEY_CLASSES_ROOT\\TclFoobar val1} msg] $msg
} {1 {unable to get type of value "val1" from key "HKEY_CLASSES_ROOT\TclFoobar": The system cannot find the file specified.}}
test registry-5.3 {GetType} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar none
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} none
test registry-5.4 {GetType} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} sz
test registry-5.5 {GetType} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar sz
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} sz
test registry-5.6 {GetType} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar expand_sz
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} expand_sz
test registry-5.7 {GetType} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 binary
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} binary
test registry-5.8 {GetType} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 dword
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} dword
test registry-5.9 {GetType} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 dword_big_endian
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} dword_big_endian
test registry-5.10 {GetType} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 link
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} link
test registry-5.11 {GetType} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar multi_sz
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} multi_sz
test registry-5.12 {GetType} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 resource_list
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} resource_list
test registry-5.13 {GetType: unknown types} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 24
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 24
test registry-5.14 {GetType: Unicode} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar va\u00c7l1 1 24
    set result [registry type HKEY_CLASSES_ROOT\\TclFoobar va\u00c7l1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 24

test registry-6.1 {GetValue} {pcOnly english} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry get HKEY_CLASSES_ROOT\\TclFoobar val1} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}
test registry-6.2 {GetValue} {pcOnly english} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry get HKEY_CLASSES_ROOT\\TclFoobar val1} msg] $msg
} {1 {unable to get value "val1" from key "HKEY_CLASSES_ROOT\TclFoobar": The system cannot find the file specified.}}
test registry-6.3 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar none
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.4 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.5 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.6 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar expand_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.7 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 binary
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 1
test registry-6.8 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 0x20 dword
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 32
test registry-6.9 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 0x20 dword_big_endian
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 32
test registry-6.10 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 link
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 1
test registry-6.11 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 foobar multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.12 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 {foo\ bar baz} multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {{foo bar} baz}
test registry-6.13 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 {} multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}
test registry-6.14 {GetValue: truncation of multivalues with null elements} \
	{pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 {a {} b} multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} a
test registry-6.15 {GetValue} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 resource_list
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 1
test registry-6.16 {GetValue: unknown types} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 1 24
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} 1
test registry-6.17 {GetValue: Unicode value names} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val\u00c71 foobar multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val\u00c71]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} foobar
test registry-6.18 {GetValue: values with Unicode strings} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 {foo ba\u30b7r baz} multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} "foo ba\u30b7r baz"
test registry-6.19 {GetValue: values with Unicode strings} {pcOnly english} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 {foo ba\u00c7r baz} multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} "foo ba\u00c7r baz"
test registry-6.20 {GetValue: values with Unicode strings with embedded nulls} {pcOnly} {
    registry set HKEY_CLASSES_ROOT\\TclFoobar val1 {foo ba\u0000r baz} multi_sz
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar val1]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} "foo ba r baz"

test registry-7.1 {GetValueNames: bad key} {pcOnly english} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry values HKEY_CLASSES_ROOT\\TclFoobar} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}
test registry-7.2 {GetValueNames} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar baz foobar
    set result [registry values HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} baz
test registry-7.3 {GetValueNames} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar baz foobar1
    registry set HKEY_CLASSES_ROOT\\TclFoobar blat foobar2
    registry set HKEY_CLASSES_ROOT\\TclFoobar {} foobar3
    set result [lsort [registry values HKEY_CLASSES_ROOT\\TclFoobar]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {{} baz blat}
test registry-7.4 {GetValueNames: remote key} {pcOnly nonPortable english} {
    registry set \\\\$hostname\\HKEY_CLASSES_ROOT\\TclFoobar baz blat
    set result [registry values \\\\$hostname\\HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete \\\\$hostname\\HKEY_CLASSES_ROOT\\TclFoobar
    set result
} baz
test registry-7.5 {GetValueNames: empty key} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    set result [registry values HKEY_CLASSES_ROOT\\TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}
test registry-7.6 {GetValueNames: patterns} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar baz foobar1
    registry set HKEY_CLASSES_ROOT\\TclFoobar blat foobar2
    registry set HKEY_CLASSES_ROOT\\TclFoobar foo foobar3
    set result [lsort [registry values HKEY_CLASSES_ROOT\\TclFoobar b*]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {baz blat}
test registry-7.7 {GetValueNames: names with spaces} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar baz\ bar foobar1
    registry set HKEY_CLASSES_ROOT\\TclFoobar blat foobar2
    registry set HKEY_CLASSES_ROOT\\TclFoobar foo foobar3
    set result [lsort [registry values HKEY_CLASSES_ROOT\\TclFoobar b*]]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {{baz bar} blat}

test registry-8.1 {OpenSubKey} {pcOnly nonPortable english} {
    # This test will only succeed if the current user does not have registry
    # access on the specified machine.
    list [catch {registry keys {\\mom\HKEY_LOCAL_MACHINE}} msg] $msg
} {1 {unable to open key: Access is denied.}}
test registry-8.2 {OpenSubKey} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar
    set result [registry keys HKEY_CLASSES_ROOT TclFoobar]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} TclFoobar
test registry-8.3 {OpenSubKey} {pcOnly english} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    list [catch {registry keys HKEY_CLASSES_ROOT\\TclFoobar} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}

test registry-9.1 {ParseKeyName: bad keys} {pcOnly} {
    list [catch {registry values \\} msg] $msg
} "1 {bad key \"\\\": must start with a valid root}"
test registry-9.2 {ParseKeyName: bad keys} {pcOnly} {
    list [catch {registry values \\foobar} msg] $msg
} {1 {bad key "\foobar": must start with a valid root}}
test registry-9.3 {ParseKeyName: bad keys} {pcOnly} {
    list [catch {registry values \\\\} msg] $msg
} {1 {ambiguous root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}}
test registry-9.4 {ParseKeyName: bad keys} {pcOnly} {
    list [catch {registry values \\\\\\} msg] $msg
} {1 {ambiguous root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}}
test registry-9.5 {ParseKeyName: bad keys} {pcOnly english} {
    list [catch {registry values \\\\\\HKEY_CLASSES_ROOT} msg] $msg
} {1 {unable to open key: The network address is invalid.}}
test registry-9.6 {ParseKeyName: bad keys} {pcOnly} {
    list [catch {registry values \\\\gaspode} msg] $msg
} {1 {ambiguous root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}}
test registry-9.7 {ParseKeyName: bad keys} {pcOnly} {
    list [catch {registry values foobar} msg] $msg
} {1 {bad root name "foobar": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}}
test registry-9.8 {ParseKeyName: null keys} {pcOnly} {
    list [catch {registry delete HKEY_CLASSES_ROOT\\} msg] $msg
} {1 {bad key: cannot delete root keys}}
test registry-9.9 {ParseKeyName: null keys} {pcOnly english} {
    list [catch {registry keys HKEY_CLASSES_ROOT\\TclFoobar\\baz} msg] $msg
} {1 {unable to open key: The system cannot find the file specified.}}

test registry-10.1 {RecursiveDeleteKey} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test1
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test2\\test3
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result [registry keys HKEY_CLASSES_ROOT TclFoobar]
    set result
} {}
test registry-10.2 {RecursiveDeleteKey} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test1
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\test2\\test3
    set result [registry delete HKEY_CLASSES_ROOT\\TclFoobar\\test2\\test4]
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    set result
} {}

test registry-11.1 {SetValue: recursive creation} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz blat foobar
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar\\baz blat]
} foobar
test registry-11.2 {SetValue: modification} {pcOnly} {
    registry delete HKEY_CLASSES_ROOT\\TclFoobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz blat foobar
    registry set HKEY_CLASSES_ROOT\\TclFoobar\\baz blat frob
    set result [registry get HKEY_CLASSES_ROOT\\TclFoobar\\baz blat]
} frob
test registry-11.3 {SetValue: failure} {pcOnly nonPortable english} {
    # This test will only succeed if the current user does not have registry
    # access on the specified machine.
    list [catch {registry set {\\mom\HKEY_CLASSES_ROOT\TclFoobar} bar foobar} msg] $msg
} {1 {unable to open key: Access is denied.}}


# cleanup
unset hostname
::tcltest::cleanupTests
return













Added tests/remote.tcl.

























































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# This file contains Tcl code to implement a remote server that can be
# used during testing of Tcl socket code. This server is used by some
# of the tests in socket.test.
#
# Source this file in the remote server you are using to test Tcl against.
#
# Copyright (c) 1995-1996 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: remote.tcl,v 1.1.2.3 1999/03/24 02:49:37 hershey Exp $

# Initialize message delimitor

# Initialize command array
catch {unset command}
set command(0) ""
set callerSocket ""

# Detect whether we should print out connection messages etc.
if {![info exists VERBOSE]} {
    set VERBOSE 0
}

proc __doCommands__ {l s} {
    global callerSocket VERBOSE

    if {$VERBOSE} {
	puts "--- Server executing the following for socket $s:"
	puts $l
	puts "---"
    }
    set callerSocket $s
    if {[catch {uplevel #0 $l} msg]} {
	list error $msg
    } else {
	list success $msg
    }
}

proc __readAndExecute__ {s} {
    global command VERBOSE

    set l [gets $s]
    if {[string compare $l "--Marker--Marker--Marker--"] == 0} {
	if {[info exists command($s)]} {
	    puts $s [list error incomplete_command]
	}
	puts $s "--Marker--Marker--Marker--"
	return
    }
    if {[string compare $l ""] == 0} {
	if {[eof $s]} {
	    if {$VERBOSE} {
		puts "Server closing $s, eof from client"
	    }
	    close $s
	}
	return
    }
    append command($s) $l "\n"
    if {[info complete $command($s)]} {
	set cmds $command($s)
	unset command($s)
	puts $s [__doCommands__ $cmds $s]
    }
    if {[eof $s]} {
	if {$VERBOSE} {
	    puts "Server closing $s, eof from client"
	}
	close $s
    }
}

proc __accept__ {s a p} {
    global VERBOSE

    if {$VERBOSE} {
	puts "Server accepts new connection from $a:$p on $s"
    }
    fileevent $s readable [list __readAndExecute__ $s]
    fconfigure $s -buffering line -translation crlf
}

set serverIsSilent 0
for {set i 0} {$i < $argc} {incr i} {
    if {[string compare -serverIsSilent [lindex $argv $i]] == 0} {
	set serverIsSilent 1
	break
    }
}
if {![info exists serverPort]} {
    if {[info exists env(serverPort)]} {
	set serverPort $env(serverPort)
    }
}
if {![info exists serverPort]} {
    for {set i 0} {$i < $argc} {incr i} {
	if {[string compare -port [lindex $argv $i]] == 0} {
	    if {$i < [expr $argc - 1]} {
		set serverPort [lindex $argv [expr $i + 1]]
	    }
	    break
	}
    }
}
if {![info exists serverPort]} {
    set serverPort 2048
}

if {![info exists serverAddress]} {
    if {[info exists env(serverAddress)]} {
	set serverAddress $env(serverAddress)
    }
}
if {![info exists serverAddress]} {
    for {set i 0} {$i < $argc} {incr i} {
	if {[string compare -address [lindex $argv $i]] == 0} {
	    if {$i < [expr $argc - 1]} {
		set serverAddress [lindex $argv [expr $i + 1]]
	    }
	    break
	}
    }
}
if {![info exists serverAddress]} {
    set serverAddress 0.0.0.0
}

if {$serverIsSilent == 0} {
    set l "Remote server listening on port $serverPort, IP $serverAddress."
    puts ""
    puts $l
    for {set c [string length $l]} {$c > 0} {incr c -1} {puts -nonewline "-"}
    puts ""
    puts ""
    puts "You have set the Tcl variables serverAddress to $serverAddress and"
    puts "serverPort to $serverPort. You can set these with the -address and"
    puts "-port command line options, or as environment variables in your"
    puts "shell."
    puts ""
    puts "NOTE: The tests will not work properly if serverAddress is set to"
    puts "\"localhost\" or 127.0.0.1."
    puts ""
    puts "When you invoke tcltest to run the tests, set the variables"
    puts "remoteServerPort to $serverPort and remoteServerIP to"
    puts "[info hostname]. You can set these as environment variables"
    puts "from the shell. The tests will not work properly if you set"
    puts "remoteServerIP to \"localhost\" or 127.0.0.1."
    puts ""
    puts -nonewline "Type Ctrl-C to terminate--> "
    flush stdout
}

if {[catch {set serverSocket \
	[socket -myaddr $serverAddress -server __accept__ $serverPort]} msg]} {
    puts "Server on $serverAddress:$serverPort cannot start: $msg"
} else {
    vwait __server_wait_variable__
}











Changes to tests/rename.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  rename
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) rename.test 1.20 97/06/24 17:26:23



if {[string compare test [info procs test]] == 1} then {source defs}

# Must eliminate the "unknown" command while the test is running,
# especially if the test is being run in a program with its
# own special-purpose unknown command.

catch {rename unknown unknown.old}









>




>
|
>
>
|
<







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
# Commands covered:  rename
#
# 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: rename.test,v 1.1.2.5 1999/03/24 02:49:37 hershey Exp $

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


# Must eliminate the "unknown" command while the test is running,
# especially if the test is being run in a program with its
# own special-purpose unknown command.

catch {rename unknown unknown.old}

159
160
161
162
163
164
165

166
167


168
169
170
171
172








    x
    rename incr incr.old
    proc incr {} {puts "new incr called!"}
    catch {x} msg
    set msg
} {called "incr" with too many arguments}


catch {rename incr {}}
catch {rename incr.old incr}



# Make the file return an empty string (cleaner.).

set x ""
















>


>
>

|

|

>
>
>
>
>
>
>
>
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
    x
    rename incr incr.old
    proc incr {} {puts "new incr called!"}
    catch {x} msg
    set msg
} {called "incr" with too many arguments}

# cleanup
catch {rename incr {}}
catch {rename incr.old incr}
::tcltest::cleanupTests
return













Changes to tests/resource.test.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55










56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

341












# Commands covered:  resource
#
# 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) 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.
#
# SCCS: @(#) resource.test 1.8 97/11/06 12:36:32

# Only run this test on Macintosh systems
if {$tcl_platform(platform) != "macintosh"} {
    return
}
if {[string compare test [info procs test]] == 1} then {source defs}

test resource-1.1 {resource tests} {
    list [catch {resource} msg] $msg
} {1 {wrong # args: should be "resource option ?arg ...?"}}
test resource-1.2 {resource tests} {
    list [catch {resource _bad_} msg] $msg
} {1 {bad option "_bad_": must be close, delete, files, list, open, read, types, or write}}

# resource open & close tests
test resource-2.1 {resource open & close tests} {
    list [catch {resource open} msg] $msg
} {1 {wrong # args: should be "resource open fileName ?permissions?"}}
test resource-2.2 {resource open & close tests} {
    list [catch {resource open resource.test r extraArg} msg] $msg
} {1 {wrong # args: should be "resource open fileName ?permissions?"}}
test resource-2.3 {resource open & close tests} {
    list [catch {resource open resource.test bad_perms} msg] $msg
} {1 {illegal access mode "bad_perms"}}
test resource-2.4 {resource open & close tests} {
    list [catch {resource open _bad_file_} msg] $msg
} {1 {file does not exist}}
test resource-2.5 {resource open & close tests} {
    testWriteTextResource -rsrc fileRsrcName -file rsrc.file  {error "don't source me"}
    set id [resource open rsrc.file]
    resource close $id
    file delete rsrc.file
} {}
test resource-2.6 {resource open & close tests} {
    catch {file delete rsrc.file}
    testWriteTextResource -rsrc fileRsrcName -file rsrc.file  {error "don't source me"}
    set id [resource open rsrc.file]
    set result [string compare [resource open rsrc.file] $id]

    resource close $id
    file delete rsrc.file
    set result
} {0}
test resource-2.7 {resource open & close tests} {










    list [catch {resource close} msg] $msg
} {1 {wrong # args: should be "resource close resourceRef"}}
test resource-2.8 {resource open & close tests} {
    list [catch {resource close foo bar} msg] $msg
} {1 {wrong # args: should be "resource close resourceRef"}}
test resource-2.9 {resource open & close tests} {
    list [catch {resource close _bad_resource_} msg] $msg
} {1 {invalid resource file reference "_bad_resource_"}}
test resource-2.10 {resource open & close tests} {
    set result [catch {resource close System} mssg]
    lappend result $mssg
} {1 {can't close "System" resource file}}
test resource-2.11 {resource open & close tests} {
    set result [catch {resource close application} mssg]
    lappend result $mssg
} {1 {can't close "application" resource file}}

# Tests for listing resources
test resource-3.1 {resource list tests} {
    list [catch {resource list} msg] $msg
} {1 {wrong # args: should be "resource list resourceType ?resourceRef?"}}
test resource-3.2 {resource list tests} {
    list [catch {resource list _bad_type_} msg] $msg
} {1 {expected Macintosh OS type but got "_bad_type_"}}
test resource-3.3 {resource list tests} {
    list [catch {resource list TEXT _bad_ref_} msg] $msg
} {1 {invalid resource file reference "_bad_ref_"}}
test resource-3.4 {resource list tests} {
    list [catch {resource list TEXT _bad_ref_ extraArg} msg] $msg
} {1 {wrong # args: should be "resource list resourceType ?resourceRef?"}}
test resource-3.5 {resource list tests} {
    catch {file delete rsrc.file}
    testWriteTextResource -rsrc fileRsrcName -file rsrc.file  {error "don't source me"}
    set id [resource open rsrc.file]
    catch "resource list TEXT $id" result
    resource close $id
    set result
} {fileRsrcName}
test resource-3.6 {resource list tests} {
    # There should not be any resource of this type
    resource list XXXX
} {}
test resource-3.7 {resource list tests} {
    set resourceList [resource list STR#]
    if {[lsearch $resourceList {Tcl Environment Variables}] == -1} {
        set result {couldn't find resource that should exist}
    } else {
        set result ok
    }
} {ok}

# Tests for reading resources
test resource-4.1 {resource read tests} {
    list [catch {resource read} msg] $msg
} {1 {wrong # args: should be "resource read resourceType resourceId ?resourceRef?"}}
test resource-4.2 {resource read tests} {
    list [catch {resource read TEXT} msg] $msg
} {1 {wrong # args: should be "resource read resourceType resourceId ?resourceRef?"}}
test resource-4.3 {resource read tests} {
    list [catch {resource read STR# {_non_existant_resource_}} msg] $msg
} {1 {could not load resource}}
test resource-4.4 {resource read tests} {
    # The following resource should exist and load OK without error
    catch {resource read STR# {Tcl Environment Variables}}
} {0}

# Tests for getting resource types
test resource-5.1 {resource types tests} {
    list [catch {resource types _bad_ref_} msg] $msg
} {1 {invalid resource file reference "_bad_ref_"}}
test resource-5.2 {resource types tests} {
    list [catch {resource types _bad_ref_ extraArg} msg] $msg
} {1 {wrong # args: should be "resource types ?resourceRef?"}}
test resource-5.3 {resource types tests} {
    # This should never cause an error
    catch {resource types}
} {0}
test resource-5.4 {resource types tests} {
    testWriteTextResource -rsrc fileRsrcName -file rsrc.file  {error "don't source me"}
    set id [resource open rsrc.file]
    set result [resource types $id]
    resource close $id
    set result
} {TEXT}

# resource write tests
test resource-6.1 {resource write tests} {
    list [catch {resource write} msg] $msg
} {1 {wrong # args: should be "resource write ?-id resourceId? ?-name resourceName? ?-file resourceRef? ?-force? resourceType data"}}
test resource-6.2 {resource write tests} {
    list [catch {resource write _bad_type_ data} msg] $msg
} {1 {expected Macintosh OS type but got "_bad_type_"}}
test resource-6.3 {resource write tests} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    resource close $id
    set id [resource open rsrc2.file r]
    set result [catch {resource write -file $id -name Hello TEXT foo} errMsg]
    lappend result [string compare $errMsg "cannot write to resource file \"$id\", it was opened read only"]
    lappend result [lsearch [resource list TEXT $id] Hello]
    resource close $id
    file delete rsrc2.file
    set result   
} {1 0 -1}
test resource-6.4 {resource write tests} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    resource write -file $id -name Hello TEXT {set x "our test data"}
    source -rsrc Hello rsrc2.file
    resource close $id
    file delete rsrc2.file
    set x
} {our test data}
test resource-6.5 {resource write tests} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    resource write -file $id -id 256 TEXT {HAHAHAHAHAHAHA}
    set result [catch {resource write -file $id -id 256 TEXT {HOHOHOHOHOHO}} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {the resource 256 already exists, use "-force" to overwrite it.}}
test resource-6.6 {resource write tests} {
    catch {file delete rsrc2.file}
    testWriteTextResource -rsrc fileRsrcName -rsrcid 256  -file rsrc2.file  -protected {error "don't tread on me"}
    set id [resource open rsrc2.file w]
    set result [catch {resource write -id 256 -force -file $id TEXT {NAHNAHNANAHNAH}} mssg] 
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {could not write resource id 256 of type TEXT, it was protected.}}
test resource-6.7 {resource write tests} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    resource write -file $id -id 256 -name FOO TEXT {set x [list "our first test data"]}
    resource write -file $id -id 256 -name BAR -force TEXT {set x [list "our second test data"]}
    source -rsrcid 256 rsrc2.file
    lappend x [resource list TEXT $id]
    resource close $id
    file delete rsrc2.file
    set x
} {{our second test data} BAR}

#Tests for listing open resource files
test resource-7.1 {resource file tests} {
    catch {resource files foo bar} mssg
    set mssg
} {wrong # args: should be "resource files ?resourceId?"}
test resource-7.2 {resource file tests} {
    catch {file delete rsrc2.file}
    set rsrcFiles [resource files]
    set id [resource open rsrc2.file w]
    set result [string compare $rsrcFiles [lrange [resource files] 1 end]]
    lappend result [string compare $id [lrange [resource files] 0 0]]
    resource close $id
    file delete rsrc2.file
    set result
} {0 0}
test resource-7.3 {resource file tests} {
    set result 0
    foreach file [resource files] {
        if {[catch {resource types $file}] != 0} {
            set result 1
        }
    }
    set result
} {0}
test resource-7.4 {resource file tests} {
    catch {resource files __NO_SUCH_RESOURCE__} mssg
    set mssg
} {invalid resource file reference "__NO_SUCH_RESOURCE__"}
test resource-7.5 {resource file tests} {
    set sys [resource files System]
    string compare $sys [file join $env(SYS_FOLDER) System]
} {0}
test resource-7.6 {resource file tests} {
    set app [resource files application]
    string compare $app [info nameofexecutable]
} {0}

#Tests for the resource delete command
test resource-8.1 {resource delete tests} {
    list [catch {resource delete} msg] $msg
} {1 {wrong # args: should be "resource delete ?-id resourceId? ?-name resourceName? ?-file resourceRef? resourceType"}}
test resource-8.2 {resource delete tests} {
    list [catch {resource delete TEXT} msg] $msg
} {1 {you must specify either "-id" or "-name" or both to "resource delete"}}
test resource-8.3 {resource delete tests} {
    set result [catch {resource delete -file ffffff -id 128 TEXT} mssg]
    lappend result $mssg    
} {1 {invalid resource file reference "ffffff"}}    
test resource-8.4 {resource delete tests} {
    catch {file delete rsrc2.file}
    testWriteTextResource -rsrc fileRsrcName -rsrcid 128 -file rsrc2.file {Some stuff}
    set id [resource open rsrc2.file r]
    set result [catch {resource delete -id 128 -file $id TEXT} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result [string compare $mssg "cannot delete from resource file \"$id\", it was opened read only"]   
} {1 0}
test resource-8.5 {resource delete tests} {
    catch {file delete rsrc2.file}
    testWriteTextResource -rsrc fileRsrcName -rsrcid 128 -file rsrc2.file {Some stuff}
    set id [resource open rsrc2.file w]
    set result [catch {resource delete -id 128 -file $id _bad_type_} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {expected Macintosh OS type but got "_bad_type_"}}
test resource-8.5 {resource delete tests} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    set result [catch {resource delete -id 128 -file $id TEXT} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {resource not found}}
test resource-8.6 {resource delete tests} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    set result [catch {resource delete -name foo -file $id TEXT} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {resource not found}}
test resource-8.7 {resource delete tests} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    resource write -file $id -name foo -id 128 TEXT {some stuff}
    resource write -file $id -name bar -id 129 TEXT {some stuff}
    set result [catch {resource delete -name foo -id 129 -file $id TEXT} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {"-id" and "-name" values do not point to the same resource}}
test resource-8.8 {resource delete tests} {
    catch {file delete rsrc2.file}
    testWriteTextResource -rsrc fileRsrcName -rsrcid 256  -file rsrc2.file  -protected {error "don't tread on me"}
    set id [resource open rsrc2.file w]
    set result [catch {resource delete -id 256 -file $id TEXT } mssg] 
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {resource cannot be deleted: it is protected.}}
test resource-8.9 {resource delete tests} {
    catch {file delete rsrc2.file}
    testWriteTextResource -rsrc fileRsrcName -rsrcid 128 -file rsrc2.file {Some stuff}
    set id [resource open rsrc2.file w]
    set result [resource list TEXT $id]
    resource delete -id 128 -file $id TEXT
    lappend result [resource list TEXT $id]
    resource close $id
    file delete rsrc2.file
    set result
} {fileRsrcName {}}
    
# Tests for the Mac version of the source command
catch {file delete rsrc.file}

testWriteTextResource -rsrc fileRsrcName -rsrcid 128 \
    -file rsrc.file  {set rsrc_foo 1}
test resource-9.1 {source command} {
    catch {unset rsrc_foo}
    source -rsrc fileRsrcName rsrc.file
    list [catch {set rsrc_foo} msg] $msg
} {0 1}
test resource-9.2 {source command} {
    catch {unset rsrc_foo}
    list [catch {source -rsrc no_resource rsrc.file} msg] $msg
} {1 {The resource "no_resource" could not be loaded from rsrc.file.}}
test resource-9.3 {source command} {
    catch {unset rsrc_foo}
    source -rsrcid 128 rsrc.file
    list [catch {set rsrc_foo} msg] $msg
} {0 1}
test resource-9.4 {source command} {
    catch {unset rsrc_foo}
    list [catch {source -rsrcid bad_int rsrc.file} msg] $msg
} {1 {expected integer but got "bad_int"}}
test resource-9.5 {source command} {
    catch {unset rsrc_foo}
    list [catch {source -rsrcid 100 rsrc.file} msg] $msg
} {1 {The resource "ID=100" could not be loaded from rsrc.file.}}

# Clean up and return
catch {file delete rsrc.file}

return



















>




|

|
|
<

<

|


|




|


|


|


|


|





|

|


>



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


|


|


|



|





|


|


|


|


|







|



|









|


|


|


|





|


|


|



|








|


|


|











|








|








|








|












|



|









|








|



|



|





|


|


|



|








|








|







|







|









|








|













>
|
|
<




|



|




|



|




|

>

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

17

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

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# Commands covered:  resource
#
# 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) 1996-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: resource.test,v 1.1.2.5 1999/03/24 02:49:38 hershey Exp $

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

}


test resource-1.1 {resource tests} {macOnly} {
    list [catch {resource} msg] $msg
} {1 {wrong # args: should be "resource option ?arg ...?"}}
test resource-1.2 {resource tests} {macOnly} {
    list [catch {resource _bad_} msg] $msg
} {1 {bad option "_bad_": must be close, delete, files, list, open, read, types, or write}}

# resource open & close tests
test resource-2.1 {resource open & close tests} {macOnly} {
    list [catch {resource open} msg] $msg
} {1 {wrong # args: should be "resource open fileName ?permissions?"}}
test resource-2.2 {resource open & close tests} {macOnly} {
    list [catch {resource open resource.test r extraArg} msg] $msg
} {1 {wrong # args: should be "resource open fileName ?permissions?"}}
test resource-2.3 {resource open & close tests} {macOnly} {
    list [catch {resource open resource.test bad_perms} msg] $msg
} {1 {illegal access mode "bad_perms"}}
test resource-2.4 {resource open & close tests} {macOnly} {
    list [catch {resource open _bad_file_} msg] $msg
} {1 {file does not exist}}
test resource-2.5 {resource open & close tests} {macOnly} {
    testWriteTextResource -rsrc fileRsrcName -file rsrc.file  {error "don't source me"}
    set id [resource open rsrc.file]
    resource close $id
    file delete rsrc.file
} {}
test resource-2.6 {resource open & close tests} {macOnly} {
    catch {file delete rsrc.file}
    testWriteTextResource -rsrc fileRsrcName -file rsrc.file  {A test string}
    set id [resource open rsrc.file]
    set result [string compare [resource open rsrc.file] $id]
    lappend result [resource read TEXT fileRsrcName $id]
    resource close $id
    file delete rsrc.file
    set result
} {0 {A test string}}
test resource-2.7 {resource open & close tests} {macOnly} {
    catch {file delete rsrc.file}
    testWriteTextResource -rsrc fileRsrcName -file rsrc.file  {error "don't source me"}
    set id [resource open rsrc.file r]
    set result [catch {resource open rsrc.file w} mssg]
    resource close $id
    file delete rsrc.file
    lappend result $mssg
    set result
} {1 {Resource already open with different permissions.}}
test resource-2.8 {resource open & close tests} {macOnly} {
    list [catch {resource close} msg] $msg
} {1 {wrong # args: should be "resource close resourceRef"}}
test resource-2.9 {resource open & close tests} {macOnly} {
    list [catch {resource close foo bar} msg] $msg
} {1 {wrong # args: should be "resource close resourceRef"}}
test resource-2.10 {resource open & close tests} {macOnly} {
    list [catch {resource close _bad_resource_} msg] $msg
} {1 {invalid resource file reference "_bad_resource_"}}
test resource-2.11 {resource open & close tests} {macOnly} {
    set result [catch {resource close System} mssg]
    lappend result $mssg
} {1 {can't close "System" resource file}}
test resource-2.12 {resource open & close tests} {macOnly} {
    set result [catch {resource close application} mssg]
    lappend result $mssg
} {1 {can't close "application" resource file}}

# Tests for listing resources
test resource-3.1 {resource list tests} {macOnly} {
    list [catch {resource list} msg] $msg
} {1 {wrong # args: should be "resource list resourceType ?resourceRef?"}}
test resource-3.2 {resource list tests} {macOnly} {
    list [catch {resource list _bad_type_} msg] $msg
} {1 {expected Macintosh OS type but got "_bad_type_"}}
test resource-3.3 {resource list tests} {macOnly} {
    list [catch {resource list TEXT _bad_ref_} msg] $msg
} {1 {invalid resource file reference "_bad_ref_"}}
test resource-3.4 {resource list tests} {macOnly} {
    list [catch {resource list TEXT _bad_ref_ extraArg} msg] $msg
} {1 {wrong # args: should be "resource list resourceType ?resourceRef?"}}
test resource-3.5 {resource list tests} {macOnly} {
    catch {file delete rsrc.file}
    testWriteTextResource -rsrc fileRsrcName -file rsrc.file  {error "don't source me"}
    set id [resource open rsrc.file]
    catch "resource list TEXT $id" result
    resource close $id
    set result
} {fileRsrcName}
test resource-3.6 {resource list tests} {macOnly} {
    # There should not be any resource of this type
    resource list XXXX
} {}
test resource-3.7 {resource list tests} {macOnly} {
    set resourceList [resource list STR#]
    if {[lsearch $resourceList {Tcl Environment Variables}] == -1} {
        set result {couldn't find resource that should exist}
    } else {
        set result ok
    }
} {ok}

# Tests for reading resources
test resource-4.1 {resource read tests} {macOnly} {
    list [catch {resource read} msg] $msg
} {1 {wrong # args: should be "resource read resourceType resourceId ?resourceRef?"}}
test resource-4.2 {resource read tests} {macOnly} {
    list [catch {resource read TEXT} msg] $msg
} {1 {wrong # args: should be "resource read resourceType resourceId ?resourceRef?"}}
test resource-4.3 {resource read tests} {macOnly} {
    list [catch {resource read STR# {_non_existant_resource_}} msg] $msg
} {1 {could not load resource}}
test resource-4.4 {resource read tests} {macOnly} {
    # The following resource should exist and load OK without error
    catch {resource read STR# {Tcl Environment Variables}}
} {0}

# Tests for getting resource types
test resource-5.1 {resource types tests} {macOnly} {
    list [catch {resource types _bad_ref_} msg] $msg
} {1 {invalid resource file reference "_bad_ref_"}}
test resource-5.2 {resource types tests} {macOnly} {
    list [catch {resource types _bad_ref_ extraArg} msg] $msg
} {1 {wrong # args: should be "resource types ?resourceRef?"}}
test resource-5.3 {resource types tests} {macOnly} {
    # This should never cause an error
    catch {resource types}
} {0}
test resource-5.4 {resource types tests} {macOnly} {
    testWriteTextResource -rsrc fileRsrcName -file rsrc.file  {error "don't source me"}
    set id [resource open rsrc.file]
    set result [resource types $id]
    resource close $id
    set result
} {TEXT}

# resource write tests
test resource-6.1 {resource write tests} {macOnly} {
    list [catch {resource write} msg] $msg
} {1 {wrong # args: should be "resource write ?-id resourceId? ?-name resourceName? ?-file resourceRef? ?-force? resourceType data"}}
test resource-6.2 {resource write tests} {macOnly} {
    list [catch {resource write _bad_type_ data} msg] $msg
} {1 {expected Macintosh OS type but got "_bad_type_"}}
test resource-6.3 {resource write tests} {macOnly} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    resource close $id
    set id [resource open rsrc2.file r]
    set result [catch {resource write -file $id -name Hello TEXT foo} errMsg]
    lappend result [string compare $errMsg "cannot write to resource file \"$id\", it was opened read only"]
    lappend result [lsearch [resource list TEXT $id] Hello]
    resource close $id
    file delete rsrc2.file
    set result   
} {1 0 -1}
test resource-6.4 {resource write tests} {macOnly} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    resource write -file $id -name Hello TEXT {set x "our test data"}
    source -rsrc Hello rsrc2.file
    resource close $id
    file delete rsrc2.file
    set x
} {our test data}
test resource-6.5 {resource write tests} {macOnly} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    resource write -file $id -id 256 TEXT {HAHAHAHAHAHAHA}
    set result [catch {resource write -file $id -id 256 TEXT {HOHOHOHOHOHO}} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {the resource 256 already exists, use "-force" to overwrite it.}}
test resource-6.6 {resource write tests} {macOnly} {
    catch {file delete rsrc2.file}
    testWriteTextResource -rsrc fileRsrcName -rsrcid 256  -file rsrc2.file  -protected {error "don't tread on me"}
    set id [resource open rsrc2.file w]
    set result [catch {resource write -id 256 -force -file $id TEXT {NAHNAHNANAHNAH}} mssg] 
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {could not write resource id 256 of type TEXT, it was protected.}}
test resource-6.7 {resource write tests} {macOnly} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    resource write -file $id -id 256 -name FOO TEXT {set x [list "our first test data"]}
    resource write -file $id -id 256 -name BAR -force TEXT {set x [list "our second test data"]}
    source -rsrcid 256 rsrc2.file
    lappend x [resource list TEXT $id]
    resource close $id
    file delete rsrc2.file
    set x
} {{our second test data} BAR}

#Tests for listing open resource files
test resource-7.1 {resource file tests} {macOnly} {
    catch {resource files foo bar} mssg
    set mssg
} {wrong # args: should be "resource files ?resourceId?"}
test resource-7.2 {resource file tests} {macOnly} {
    catch {file delete rsrc2.file}
    set rsrcFiles [resource files]
    set id [resource open rsrc2.file w]
    set result [string compare $rsrcFiles [lrange [resource files] 1 end]]
    lappend result [string compare $id [lrange [resource files] 0 0]]
    resource close $id
    file delete rsrc2.file
    set result
} {0 0}
test resource-7.3 {resource file tests} {macOnly} {
    set result 0
    foreach file [resource files] {
        if {[catch {resource types $file}] != 0} {
            set result 1
        }
    }
    set result
} {0}
test resource-7.4 {resource file tests} {macOnly} {
    catch {resource files __NO_SUCH_RESOURCE__} mssg
    set mssg
} {invalid resource file reference "__NO_SUCH_RESOURCE__"}
test resource-7.5 {resource file tests} {macOnly} {
    set sys [resource files System]
    string compare $sys [file join $env(SYS_FOLDER) System]
} {0}
test resource-7.6 {resource file tests} {macOnly} {
    set app [resource files application]
    string compare $app [info nameofexecutable]
} {0}

#Tests for the resource delete command
test resource-8.1 {resource delete tests} {macOnly} {
    list [catch {resource delete} msg] $msg
} {1 {wrong # args: should be "resource delete ?-id resourceId? ?-name resourceName? ?-file resourceRef? resourceType"}}
test resource-8.2 {resource delete tests} {macOnly} {
    list [catch {resource delete TEXT} msg] $msg
} {1 {you must specify either "-id" or "-name" or both to "resource delete"}}
test resource-8.3 {resource delete tests} {macOnly} {
    set result [catch {resource delete -file ffffff -id 128 TEXT} mssg]
    lappend result $mssg    
} {1 {invalid resource file reference "ffffff"}}    
test resource-8.4 {resource delete tests} {macOnly} {
    catch {file delete rsrc2.file}
    testWriteTextResource -rsrc fileRsrcName -rsrcid 128 -file rsrc2.file {Some stuff}
    set id [resource open rsrc2.file r]
    set result [catch {resource delete -id 128 -file $id TEXT} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result [string compare $mssg "cannot delete from resource file \"$id\", it was opened read only"]   
} {1 0}
test resource-8.5 {resource delete tests} {macOnly} {
    catch {file delete rsrc2.file}
    testWriteTextResource -rsrc fileRsrcName -rsrcid 128 -file rsrc2.file {Some stuff}
    set id [resource open rsrc2.file w]
    set result [catch {resource delete -id 128 -file $id _bad_type_} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {expected Macintosh OS type but got "_bad_type_"}}
test resource-8.5 {resource delete tests} {macOnly} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    set result [catch {resource delete -id 128 -file $id TEXT} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {resource not found}}
test resource-8.6 {resource delete tests} {macOnly} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    set result [catch {resource delete -name foo -file $id TEXT} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {resource not found}}
test resource-8.7 {resource delete tests} {macOnly} {
    catch {file delete rsrc2.file}
    set id [resource open rsrc2.file w]
    resource write -file $id -name foo -id 128 TEXT {some stuff}
    resource write -file $id -name bar -id 129 TEXT {some stuff}
    set result [catch {resource delete -name foo -id 129 -file $id TEXT} mssg]
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {"-id" and "-name" values do not point to the same resource}}
test resource-8.8 {resource delete tests} {macOnly} {
    catch {file delete rsrc2.file}
    testWriteTextResource -rsrc fileRsrcName -rsrcid 256  -file rsrc2.file  -protected {error "don't tread on me"}
    set id [resource open rsrc2.file w]
    set result [catch {resource delete -id 256 -file $id TEXT } mssg] 
    resource close $id
    file delete rsrc2.file
    lappend result $mssg
} {1 {resource cannot be deleted: it is protected.}}
test resource-8.9 {resource delete tests} {macOnly} {
    catch {file delete rsrc2.file}
    testWriteTextResource -rsrc fileRsrcName -rsrcid 128 -file rsrc2.file {Some stuff}
    set id [resource open rsrc2.file w]
    set result [resource list TEXT $id]
    resource delete -id 128 -file $id TEXT
    lappend result [resource list TEXT $id]
    resource close $id
    file delete rsrc2.file
    set result
} {fileRsrcName {}}
    
# Tests for the Mac version of the source command
catch {file delete rsrc.file}
test resource-9.1 {source command} {macOnly} {
    testWriteTextResource -rsrc fileRsrcName -rsrcid 128 \
	    -file rsrc.file  {set rsrc_foo 1}

    catch {unset rsrc_foo}
    source -rsrc fileRsrcName rsrc.file
    list [catch {set rsrc_foo} msg] $msg
} {0 1}
test resource-9.2 {source command} {macOnly} {
    catch {unset rsrc_foo}
    list [catch {source -rsrc no_resource rsrc.file} msg] $msg
} {1 {The resource "no_resource" could not be loaded from rsrc.file.}}
test resource-9.3 {source command} {macOnly} {
    catch {unset rsrc_foo}
    source -rsrcid 128 rsrc.file
    list [catch {set rsrc_foo} msg] $msg
} {0 1}
test resource-9.4 {source command} {macOnly} {
    catch {unset rsrc_foo}
    list [catch {source -rsrcid bad_int rsrc.file} msg] $msg
} {1 {expected integer but got "bad_int"}}
test resource-9.5 {source command} {macOnly} {
    catch {unset rsrc_foo}
    list [catch {source -rsrcid 100 rsrc.file} msg] $msg
} {1 {The resource "ID=100" could not be loaded from rsrc.file.}}

# cleanup
catch {file delete rsrc.file}
::tcltest::cleanupTests
return












Added tests/result.test.













































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# This file tests the routines in tclResult.c.
#
# 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.
#
# SCCS: @(#) result.test 1.4 97/12/08 15:07:49

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

# Some tests require the testsaveresult command

set ::tcltest::testConfig(testsaveresult) \
	[expr {[info commands testsaveresult] != {}}]

test result-1.1 {Tcl_SaveInterpResult} {testsaveresult} {
    testsaveresult small {set x 42} 0
} {small result}
test result-1.2 {Tcl_SaveInterpResult} {testsaveresult} {
    testsaveresult append {set x 42} 0
} {append result}
test result-1.3 {Tcl_SaveInterpResult} {testsaveresult} {
    testsaveresult dynamic {set x 42} 0
} {dynamic result notCalled present}
test result-1.4 {Tcl_SaveInterpResult} {testsaveresult} {
    testsaveresult object {set x 42} 0
} {object result same}
test result-1.5 {Tcl_SaveInterpResult} {testsaveresult} {
    testsaveresult small {set x 42} 1
} {42}
test result-1.6 {Tcl_SaveInterpResult} {testsaveresult} {
    testsaveresult append {set x 42} 1
} {42}
test result-1.7 {Tcl_SaveInterpResult} {testsaveresult} {
    testsaveresult dynamic {set x 42} 1
} {42 called missing}
test result-1.8 {Tcl_SaveInterpResult} {testsaveresult} {
    testsaveresult object {set x 42} 1
} {42 different}


# Tcl_RestoreInterpResult is mostly tested by the previous tests except
# for the following case

test result-2.1 {Tcl_RestoreInterpResult} {testsaveresult} {
    testsaveresult append {cd _foobar} 0
} {append result}

# Tcl_DiscardInterpResult is mostly tested by the previous tests except
# for the following cases

test result-3.1 {Tcl_DiscardInterpResult} {testsaveresult} {
    list [catch {testsaveresult append {cd _foobar} 1} msg] $msg
} {1 {couldn't change working directory to "_foobar": no such file or directory}}
test result-3.2 {Tcl_DiscardInterpResult} {testsaveresult} {
    testsaveresult free {set x 42} 1
} {42}

test result-4.1 {Tcl_SetObjErrorCode - one arg} {testsaveresult} {
    catch {testsetobjerrorcode 1}
    list [set errorCode]
} {1}
test result-4.2 {Tcl_SetObjErrorCode - two args} {testsaveresult} {
    catch {testsetobjerrorcode 1 2}
    list [set errorCode]
} {{1 2}}
test result-4.3 {Tcl_SetObjErrorCode - three args} {testsaveresult} {
    catch {testsetobjerrorcode 1 2 3}
    list [set errorCode]
} {{1 2 3}}
test result-4.4 {Tcl_SetObjErrorCode - four args} {testsaveresult} {
    catch {testsetobjerrorcode 1 2 3 4}
    list [set errorCode]
} {{1 2 3 4}}
test result-4.5 {Tcl_SetObjErrorCode - five args} {testsaveresult} {
    catch {testsetobjerrorcode 1 2 3 4 5}
    list [set errorCode]
} {{1 2 3 4 5}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/safe.test.

1
2
3
4
5
6
7

8
9
10
11

12


13
14
15
16
17
18
19
20
21
# safe.test --
#
# This file contains a collection of tests for safe Tcl, packages loading,
# and using safe interpreters. Sourcing this file into tcl runs the tests
# and generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) safe.test 1.34 97/11/19 14:59:13



if {[string compare test [info procs test]] == 1} then {source defs}

foreach i [interp slaves] {
  interp delete $i
}

# Force actual loading of the safe package 
# because we use un exported (and thus un-autoindexed) APIs







>




>
|
>
>
|
<







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

18
19
20
21
22
23
24
# safe.test --
#
# This file contains a collection of tests for safe Tcl, packages loading,
# and using safe interpreters. Sourcing this file into tcl runs the tests
# and generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1995-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: safe.test,v 1.1.2.8 1999/04/06 00:43:17 redman Exp $

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


foreach i [interp slaves] {
  interp delete $i
}

# Force actual loading of the safe package 
# because we use un exported (and thus un-autoindexed) APIs
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
} {invalid command name "exec"}
test safe-3.2 {calling safe::interpCreate on trusted interp} {
    catch {safe::interpDelete a}
    safe::interpCreate a
    set l [lsort [a aliases]]
    safe::interpDelete a
    set l
} {exit file load source}
test safe-3.3 {calling safe::interpCreate on trusted interp} {
    catch {safe::interpDelete a}
    safe::interpCreate a
    set x [interp eval a {source [file join $tcl_library init.tcl]}]
    safe::interpDelete a
    set x
} ""







|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
} {invalid command name "exec"}
test safe-3.2 {calling safe::interpCreate on trusted interp} {
    catch {safe::interpDelete a}
    safe::interpCreate a
    set l [lsort [a aliases]]
    safe::interpDelete a
    set l
} {encoding exit file load source}
test safe-3.3 {calling safe::interpCreate on trusted interp} {
    catch {safe::interpDelete a}
    safe::interpCreate a
    set x [interp eval a {source [file join $tcl_library init.tcl]}]
    safe::interpDelete a
    set x
} ""
164
165
166
167
168
169
170

171







172
173
174
175
176
177
178
test safe-6.1 {test safe interpreters knowledge of the world} {
    SI; set r [lsort [$I eval {info globals}]]; DI; set r
} {tcl_interactive tcl_patchLevel tcl_platform tcl_version}
test safe-6.2 {test safe interpreters knowledge of the world} {
    SI; set r [$I eval {info script}]; DI; set r
} {}
test safe-6.3 {test safe interpreters knowledge of the world} {

    SI; set r [lsort [$I eval {array names tcl_platform}]]; DI; set r







} {byteOrder platform}

# more test should be added to check that hostname, nameofexecutable,
# aren't leaking infos, but they still do...

# high level general test
test safe-7.1 {tests that everything works at high level} {







>
|
>
>
>
>
>
>
>







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
test safe-6.1 {test safe interpreters knowledge of the world} {
    SI; set r [lsort [$I eval {info globals}]]; DI; set r
} {tcl_interactive tcl_patchLevel tcl_platform tcl_version}
test safe-6.2 {test safe interpreters knowledge of the world} {
    SI; set r [$I eval {info script}]; DI; set r
} {}
test safe-6.3 {test safe interpreters knowledge of the world} {
    SI
    set r [lsort [$I eval {array names tcl_platform}]]
    DI
    # If running a windows-debug shell, remove the "debug" element from r.
    if {$tcl_platform(platform) == "windows" && \
	    [lsearch $r "debug"] != -1} {
	set r [lreplace $r 1 1]
    }
    set r
} {byteOrder platform}

# more test should be added to check that hostname, nameofexecutable,
# aren't leaking infos, but they still do...

# high level general test
test safe-7.1 {tests that everything works at high level} {
427
428
429
430
431
432
433



















































































	    [catch {interp eval $i {interp create x; load {} Tcltest x}} msg] \
	    $msg \
            [safe::interpDelete $i];
} {1 {can't use package in a safe interpreter: no Tcltest_SafeInit procedure} {}}


}


























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
	    [catch {interp eval $i {interp create x; load {} Tcltest x}} msg] \
	    $msg \
            [safe::interpDelete $i];
} {1 {can't use package in a safe interpreter: no Tcltest_SafeInit procedure} {}}


}

test safe-11.1 {testing safe encoding} {
    set i [safe::interpCreate]
    list \
	    [catch {interp eval $i encoding} msg] \
	    $msg \
	    [safe::interpDelete $i];
} {1 {wrong # args: should be "encoding option ?arg ...?"} {}}

test safe-11.2 {testing safe encoding} {
    set i [safe::interpCreate]
    list \
	    [catch {interp eval $i encoding system cp775} msg] \
	    $msg \
	    [safe::interpDelete $i];
} {1 {wrong # args: should be "encoding system"} {}}

test safe-11.3 {testing safe encoding} {
    set i [safe::interpCreate]
    set result [catch {
	string match [encoding system] [interp eval $i encoding system]
    } msg]
    list $result $msg [safe::interpDelete $i]
} {0 1 {}}

test safe-11.4 {testing safe encoding} {
    set i [safe::interpCreate]
    set result [catch {
	string match [encoding names] [interp eval $i encoding names]
    } msg]
    list $result $msg  [safe::interpDelete $i]
} {0 1 {}}

test safe-11.5 {testing safe encoding} {
    set i [safe::interpCreate]
    list \
	    [catch {interp eval $i encoding convertfrom cp1258 foobar} msg] \
	    $msg \
	    [safe::interpDelete $i];
} {0 foobar {}}


test safe-11.6 {testing safe encoding} {
    set i [safe::interpCreate]
    list \
	    [catch {interp eval $i encoding convertto cp1258 foobar} msg] \
	    $msg \
	    [safe::interpDelete $i];
} {0 foobar {}}

test safe-11.7 {testing safe encoding} {
    set i [safe::interpCreate]
    list \
	    [catch {interp eval $i encoding convertfrom} msg] \
	    $msg \
	    [safe::interpDelete $i];
} {1 {wrong # args: should be "encoding convertfrom ?encoding? data"} {}}


test safe-11.8 {testing safe encoding} {
    set i [safe::interpCreate]
    list \
	    [catch {interp eval $i encoding convertto} msg] \
	    $msg \
	    [safe::interpDelete $i];
} {1 {wrong # args: should be "encoding convertto ?encoding? data"} {}}


# cleanup
::tcltest::cleanupTests
return












Changes to tests/scan.test.

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


















# Commands covered:  scan
#
# 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-1994 The Regents of the University of California.
# 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.
#

# SCCS: @(#) scan.test 1.26 97/08/06 08:56:08



if {[string compare test [info procs test]] == 1} then {source defs}











































































































































































































































































































test scan-1.1 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "-20 1476 \n33 0" "%d %d %d %d" a b c d] $a $b $c $d
} {4 -20 1476 33 0}
test scan-1.2 {integer scanning} {
    set a {}; set b {}; set c {}
    list [scan "-45 16 7890 +10" "%2d %*d %10d %d" a b c] $a $b $c
} {3 -4 16 7890}
test scan-1.3 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "-45 16 +10 987" "%ld %d %ld %d" a b c d] $a $b $c $d
} {4 -45 16 10 987}
test scan-1.4 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "14 1ab 62 10" "%d %x %lo %x" a b c d] $a $b $c $d
} {4 14 427 50 16}
test scan-1.5 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "12345670 1234567890ab cdefg" "%o	 %o %x %lx" a b c d] \
	    $a $b $c $d
} {4 2739128 342391 561323 52719}
test scan-1.6 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "ab123-24642" "%2x %3x %3o %2o" a b c d] $a $b $c $d
} {4 171 291 -20 52}
test scan-1.7 {integer scanning} {
    set a {}; set b {}
    list [scan "1234567 234 567  " "%*3x %x %*o %4o" a b] $a $b
} {2 17767 375}
test scan-1.8 {integer scanning} {
    set a {}; set b {}
    list [scan "a	1234" "%d %d" a b] $a $b
} {0 {} {}}
test scan-1.9 {integer scanning} {
    set a {}; set b {}; set c {}; set d {};
    list [scan "12345678" "%2d %2d %2ld %2d" a b c d] $a $b $c $d
} {4 12 34 56 78}
test scan-1.10 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "1 2 " "%hd %d %d %d" a b c d] $a $b $c $d
} {2 1 2 {} {}}
#
# The behavior for scaning intergers larger than MAX_INT is
# not defined by the ANSI spec.  Some implementations wrap the
# input (-16) some return MAX_INT.
#
test scan-1.11 {integer scanning} {nonPortable} {
    set a {}; set b {};
    list [scan "4294967280 4294967280" "%u %d" a b] $a $b

} {2 4294967280 -16}

test scan-2.1 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d
} {3 2.1 -300000000.0 0.99962 {}}
test scan-2.2 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "-1.2345 +8.2 9" "%3e %3lf %f %f" a b c d] $a $b $c $d
} {4 -1.0 234.0 5.0 8.2}
test scan-2.3 {floating-point scanning} {
    set a {}; set b {}; set c {}
    list [scan "1e00004 332E-4 3e+4" "%Lf %*2e %f %f" a b c] $a $c
} {3 10000.0 30000.0}
#
# Some libc implementations consider 3.e- bad input.  The ANSI
# spec states that digits must follow the - sign.
#
test scan-2.4 {floating-point scanning} {nonPortable} {
    set a {}; set b {}; set c {}
    list [scan "1. 47.6 2.e2 3.e-" "%f %*f %f %f" a b c] $a $b $c
} {3 1.0 200.0 3.0}
test scan-2.5 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "4.6 99999.7 876.43e-1 118" "%f %f %f %e" a b c d] $a $b $c $d
} {4 4.6 99999.7 87.643 118.0}
test scan-2.6 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "1.2345 697.0e-3 124 .00005" "%f %e %f %e" a b c d] $a $b $c $d
} {4 1.2345 0.697 124.0 5e-05}
test scan-2.7 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "4.6abc" "%f %f %f %f" a b c d] $a $b $c $d
} {1 4.6 {} {} {}}
test scan-2.8 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "4.6 5.2" "%f %f %f %f" a b c d] $a $b $c $d
} {2 4.6 5.2 {} {}}

test scan-3.1 {string and character scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "abc defghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
} {4 abc def ghijk dum}
test scan-3.2 {string and character scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "a       bcdef" "%c%c%1s %s" a b c d] $a $b $c $d
} {4 97 32 b cdef}
test scan-3.3 {string and character scanning} {
    set a {}; set b {}; set c {}
    list [scan "123456 test " "%*c%*s %s %s %s" a b c] $a $b $c
} {1 test {} {}}
test scan-3.4 {string and character scanning} {
    set a {}; set b {}; set c {}; set d
    list [scan "ababcd01234  f 123450" {%4[abcd] %4[abcd] %[^abcdef] %[^0]} a b c d] $a $b $c $d
} {4 abab cd {01234  } {f 12345}}
test scan-3.5 {string and character scanning} {
    set a {}; set b {}; set c {}
    list [scan "aaaaaabc aaabcdefg  + +  XYZQR" {%*4[a] %s %*4[a]%s%*4[ +]%c} a b c] $a $b $c
} {3 aabc bcdefg 43}













test scan-4.1 {error conditions} {
    catch {scan a}
} 1
test scan-4.2 {error conditions} {
    catch {scan a} msg
    set msg
} {wrong # args: should be "scan string format ?varName varName ...?"}
test scan-4.3 {error conditions} {
    catch {scan "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21}
} 1
test scan-4.4 {error conditions} {
    catch {scan "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21} msg
    set msg
} {too many fields to scan}
test scan-4.5 {error conditions} {
    list [catch {scan a %D} msg] $msg
} {1 {bad scan conversion character "D"}}
test scan-4.6 {error conditions} {
    list [catch {scan a %O} msg] $msg
} {1 {bad scan conversion character "O"}}
test scan-4.7 {error conditions} {
    list [catch {scan a %X} msg] $msg
} {1 {bad scan conversion character "X"}}
test scan-4.8 {error conditions} {
    list [catch {scan a %F} msg] $msg
} {1 {bad scan conversion character "F"}}
test scan-4.9 {error conditions} {
    list [catch {scan a %E} msg] $msg
} {1 {bad scan conversion character "E"}}
test scan-4.10 {error conditions} {
    list [catch {scan a "%d %d" a} msg] $msg
} {1 {different numbers of variable names and field specifiers}}







test scan-4.11 {error conditions} {
    list [catch {scan a "%d %d" a b c} msg] $msg
} {1 {different numbers of variable names and field specifiers}}
test scan-4.12 {error conditions} {
    set a {}; set b {}; set c {}; set d {}
    list [expr {[scan "  a" " a %d %d %d %d" a b c d] <= 0}] $a $b $c $d
} {1 {} {} {} {}}
test scan-4.13 {error conditions} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "1 2" "%d %d %d %d" a b c d] $a $b $c $d
} {2 1 2 {} {}}
test scan-4.14 {error conditions} {
    catch {unset a}
    set a(0) 44
    list [catch {scan 44 %d a} msg] $msg
} {1 {couldn't set variable "a"}}
test scan-4.15 {error conditions} {
    catch {unset a}
    set a(0) 44
    list [catch {scan 44 %c a} msg] $msg
} {1 {couldn't set variable "a"}}
test scan-4.16 {error conditions} {
    catch {unset a}
    set a(0) 44
    list [catch {scan 44 %s a} msg] $msg
} {1 {couldn't set variable "a"}}
test scan-4.17 {error conditions} {
    catch {unset a}
    set a(0) 44
    list [catch {scan 44 %f a} msg] $msg
} {1 {couldn't set variable "a"}}
test scan-4.18 {error conditions} {
    catch {unset a}
    set a(0) 44
    list [catch {scan 44 %f a} msg] $msg
} {1 {couldn't set variable "a"}}
catch {unset a}
test scan-4.19 {error conditions} {
    list [catch {scan 44 %2c a} msg] $msg
} {1 {field width may not be specified in %c conversion}}






test scan-4.20 {error conditions} {
    list [catch {scan abc {%[}} msg] $msg
} {1 {unmatched [ in format string}}




test scan-5.1 {lots of arguments} {
    scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
} 20
test scan-5.2 {lots of arguments} {
    scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
    set a20
} 200

test scan-6.1 {miscellaneous tests} {
    set a {}
    list [scan ab16c ab%dc a] $a
} {1 16}
test scan-6.2 {miscellaneous tests} {
    set a {}
    list [scan ax16c ab%dc a] $a
} {0 {}}
test scan-6.3 {miscellaneous tests} {









    set a {}
    list [catch {scan ab%c114 ab%%c%d a} msg] $msg $a
} {0 1 114}
test scan-6.4 {miscellaneous tests} {
    set a {}
    list [catch {scan ab%c14 ab%%c%d a} msg] $msg $a
} {0 1 14}

test scan-7.1 {alignment in results array (TCL_ALIGN)} {
    scan "123 13.6" "%s %f" a b
    set b
} 13.6
test scan-7.2 {alignment in results array (TCL_ALIGN)} {
    scan "1234567 13.6" "%s %f" a b
    set b
} 13.6
test scan-7.3 {alignment in results array (TCL_ALIGN)} {
    scan "12345678901 13.6" "%s %f" a b
    set b
} 13.6
test scan-7.4 {alignment in results array (TCL_ALIGN)} {
    scan "123456789012345 13.6" "%s %f" a b
    set b
} 13.6
test scan-7.5 {alignment in results array (TCL_ALIGN)} {
    scan "1234567890123456789 13.6" "%s %f" a b
    set b
} 13.6


























>




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

|



|



|



|



|




|



|



|



|



|








|

|
>
|

|



|



|







|



|



|



|



|




|



|



|



|



|



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

|


|



|
<
<
<
<
<
<
<
|

|
|

|
|

|
|

|
|

|


>
>
>
>
>
>
>
|
<
<
<

<
<
<
<


|




|




|




|




|





|


>
>
>
>
>
>
|
|

>
>
>

|


|




|



|



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


|



|



|



|



|



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







449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473



474




475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545




546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
# Commands covered:  scan
#
# 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-1994 The Regents of the University of California.
# Copyright (c) 1994-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: scan.test,v 1.1.2.7 1999/03/24 02:49:39 hershey Exp $

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

test scan-1.1 {BuildCharSet, CharInSet} {
    list [scan foo {%[^o]} x] $x
} {1 f}
test scan-1.2 {BuildCharSet, CharInSet} {
    list [scan \]foo {%[]f]} x] $x
} {1 \]f}
test scan-1.3 {BuildCharSet, CharInSet} {
    list [scan abc-def {%[a-c]} x] $x
} {1 abc}
test scan-1.4 {BuildCharSet, CharInSet} {
    list [scan abc-def {%[a-c]} x] $x
} {1 abc}
test scan-1.5 {BuildCharSet, CharInSet} {
    list [scan -abc-def {%[-ac]} x] $x
} {1 -a}
test scan-1.6 {BuildCharSet, CharInSet} {
    list [scan -abc-def {%[ac-]} x] $x
} {1 -a}
test scan-1.7 {BuildCharSet, CharInSet} {
    list [scan abc-def {%[c-a]} x] $x
} {1 abc}
test scan-1.8 {BuildCharSet, CharInSet} {
    list [scan def-abc {%[^c-a]} x] $x
} {1 def-}

test scan-2.1 {ReleaseCharSet} {
    list [scan abcde {%[abc]} x] $x
} {1 abc}
test scan-2.2 {ReleaseCharSet} {
    list [scan abcde {%[a-c]} x] $x
} {1 abc}

test scan-3.1 {ValidateFormat} {
    list [catch {scan {} {%d%1$d} x} msg] $msg
} {1 {cannot mix "%" and "%n$" conversion specifiers}}
test scan-3.2 {ValidateFormat} {
    list [catch {scan {} {%d%1$d} x} msg] $msg
} {1 {cannot mix "%" and "%n$" conversion specifiers}}
test scan-3.3 {ValidateFormat} {
    list [catch {scan {} {%2$d%d} x} msg] $msg
} {1 {"%n$" argument index out of range}}
test scan-3.4 {ValidateFormat} {
    list [catch {scan {} %d} msg] $msg
} {1 {different numbers of variable names and field specifiers}}
test scan-3.5 {ValidateFormat} {
    list [catch {scan {} {%10c} a} msg] $msg
} {1 {field width may not be specified in %c conversion}}
test scan-3.6 {ValidateFormat} {
    list [catch {scan {} {%*1$d} a} msg] $msg
} {1 {bad scan conversion character "$"}}
test scan-3.7 {ValidateFormat} {
    list [catch {scan {} {%1$d%1$d} a} msg] $msg
} {1 {variable is assigned by multiple "%n$" conversion specifiers}}
test scan-3.8 {ValidateFormat} {
    list [catch {scan {} a x} msg] $msg
} {1 {variable is not assigend by any conversion specifiers}}
test scan-3.9 {ValidateFormat} {
    list [catch {scan {} {%2$s} x y} msg] $msg
} {1 {variable is not assigend by any conversion specifiers}}
test scan-3.10 {ValidateFormat} {
    list [catch {scan {} {%[a} x} msg] $msg
} {1 {unmatched [ in format string}}
test scan-3.11 {ValidateFormat} {
    list [catch {scan {} {%[^a} x} msg] $msg
} {1 {unmatched [ in format string}}
test scan-3.12 {ValidateFormat} {
    list [catch {scan {} {%[]a} x} msg] $msg
} {1 {unmatched [ in format string}}
test scan-3.13 {ValidateFormat} {
    list [catch {scan {} {%[^]a} x} msg] $msg
} {1 {unmatched [ in format string}}

test scan-4.1 {Tcl_ScanObjCmd, argument checks} {
    list [catch {scan} msg] $msg
} {1 {wrong # args: should be "scan string format ?varName varName ...?"}}
test scan-4.2 {Tcl_ScanObjCmd, argument checks} {
    list [catch {scan string} msg] $msg
} {1 {wrong # args: should be "scan string format ?varName varName ...?"}}
test scan-4.3 {Tcl_ScanObjCmd, argument checks} {
    list [catch {scan string format} msg] $msg
} {0 0}
test scan-4.4 {Tcl_ScanObjCmd, whitespace} {
    list [scan {   abc   def   } {%s%s} x y] $x $y
} {2 abc def}
test scan-4.5 {Tcl_ScanObjCmd, whitespace} {
    list [scan {   abc   def   } { %s %s } x y] $x $y
} {2 abc def}
test scan-4.6 {Tcl_ScanObjCmd, whitespace} {
    list [scan {   abc   def   } { %s %s } x y] $x $y
} {2 abc def}
test scan-4.7 {Tcl_ScanObjCmd, literals} {
    scan {   abc   def   } { abc def }
} 0
test scan-4.8 {Tcl_ScanObjCmd, literals} {
    set x {}
    list [scan {   abcg} { abc def %1s} x] $x
} {0 {}}
test scan-4.9 {Tcl_ScanObjCmd, literals} {
    list [scan {   abc%defghi} { abc %% def%n } x] $x
} {1 10}
test scan-4.10 {Tcl_ScanObjCmd, assignment suppression} {
    list [scan {   abc   def   } { %*c%s def } x] $x
} {1 bc}
test scan-4.11 {Tcl_ScanObjCmd, XPG3-style} {
    list [scan {   abc   def   } {%2$s %1$s} x y] $x $y
} {2 def abc}
test scan-4.12 {Tcl_ScanObjCmd, width specifiers} {
    list [scan {abc123456789012} {%3s%3d%3f%3[0-9]%s} a b c d e] $a $b $c $d $e
} {5 abc 123 456.0 789 012}
test scan-4.13 {Tcl_ScanObjCmd, width specifiers} {
    list [scan {abc123456789012} {%3s%3d%3f%3[0-9]%s} a b c d e] $a $b $c $d $e
} {5 abc 123 456.0 789 012}
test scan-4.14 {Tcl_ScanObjCmd, underflow} {
    set x {}
    list [scan {a} {a%d} x] $x
} {-1 {}}
test scan-4.15 {Tcl_ScanObjCmd, underflow} {
    set x {}
    list [scan {} {a%d} x] $x
} {-1 {}}
test scan-4.16 {Tcl_ScanObjCmd, underflow} {
    set x {}
    list [scan {ab} {a%d} x] $x
} {0 {}}
test scan-4.17 {Tcl_ScanObjCmd, underflow} {
    set x {}
    list [scan {a   } {a%d} x] $x
} {-1 {}}
test scan-4.18 {Tcl_ScanObjCmd, skipping whitespace} {
    list [scan {  b} {%c%s} x y] $x $y
} {2 32 b}
test scan-4.19 {Tcl_ScanObjCmd, skipping whitespace} {
    list [scan {  b} {%[^b]%s} x y] $x $y
} {2 {  } b}
test scan-4.20 {Tcl_ScanObjCmd, string scanning} {
    list [scan {abc def} {%s} x] $x
} {1 abc}
test scan-4.21 {Tcl_ScanObjCmd, string scanning} {
    list [scan {abc def} {%0s} x] $x
} {1 abc}
test scan-4.22 {Tcl_ScanObjCmd, string scanning} {
    list [scan {abc def} {%2s} x] $x
} {1 ab}
test scan-4.23 {Tcl_ScanObjCmd, string scanning} {
    list [scan {abc def} {%*s%n} x] $x
} {1 3}
test scan-4.24 {Tcl_ScanObjCmd, charset scanning} {
    list [scan {abcdef} {%[a-c]} x] $x
} {1 abc}
test scan-4.25 {Tcl_ScanObjCmd, charset scanning} {
    list [scan {abcdef} {%0[a-c]} x] $x
} {1 abc}
test scan-4.26 {Tcl_ScanObjCmd, charset scanning} {
    list [scan {abcdef} {%2[a-c]} x] $x
} {1 ab}
test scan-4.27 {Tcl_ScanObjCmd, charset scanning} {
    list [scan {abcdef} {%*[a-c]%n} x] $x
} {1 3}
test scan-4.28 {Tcl_ScanObjCmd, character scanning} {
    list [scan {abcdef} {%c} x] $x
} {1 97}
test scan-4.29 {Tcl_ScanObjCmd, character scanning} {
    list [scan {abcdef} {%*c%n} x] $x
} {1 1}

test scan-4.30 {Tcl_ScanObjCmd, base-10 integer scanning} {
    set x {}
    list [scan {1234567890a} {%3d} x] $x
} {1 123}
test scan-4.31 {Tcl_ScanObjCmd, base-10 integer scanning} {
    set x {}
    list [scan {1234567890a} {%d} x] $x
} {1 1234567890}
test scan-4.32 {Tcl_ScanObjCmd, base-10 integer scanning} {
    set x {}
    list [scan {01234567890a} {%d} x] $x
} {1 1234567890}
test scan-4.33 {Tcl_ScanObjCmd, base-10 integer scanning} {
    set x {}
    list [scan {+01234} {%d} x] $x
} {1 1234}
test scan-4.34 {Tcl_ScanObjCmd, base-10 integer scanning} {
    set x {}
    list [scan {-01234} {%d} x] $x
} {1 -1234}
test scan-4.35 {Tcl_ScanObjCmd, base-10 integer scanning} {
    set x {}
    list [scan {a01234} {%d} x] $x
} {0 {}}
test scan-4.36 {Tcl_ScanObjCmd, base-10 integer scanning} {
    set x {}
    list [scan {0x10} {%d} x] $x
} {1 0}
test scan-4.37 {Tcl_ScanObjCmd, base-8 integer scanning} {
    set x {}
    list [scan {012345678} {%o} x] $x
} {1 342391}
test scan-4.38 {Tcl_ScanObjCmd, base-8 integer scanning} {
    set x {}
    list [scan {+1238 -1239 123a} {%o%*s%o%*s%o} x y z] $x $y $z
} {3 83 -83 83}
test scan-4.39 {Tcl_ScanObjCmd, base-16 integer scanning} {
    set x {}
    list [scan {+1238 -123a 0123} {%x%x%x} x y z] $x $y $z
} {3 4664 -4666 291}
test scan-4.40 {Tcl_ScanObjCmd, base-16 integer scanning} {
    set x {}
    list [scan {aBcDeF AbCdEf 0x1} {%x%x%x} x y z] $x $y $z
} {3 11259375 11259375 0}
test scan-4.41 {Tcl_ScanObjCmd, base-unknown integer scanning} {
    set x {}
    list [scan {10 010 0x10} {%i%i%i} x y z] $x $y $z
} {3 10 8 16}
test scan-4.42 {Tcl_ScanObjCmd, base-unknown integer scanning} {
    set x {}
    list [scan {10 010 0X10} {%i%i%i} x y z] $x $y $z
} {3 10 8 16}
test scan-4.43 {Tcl_ScanObjCmd, integer scanning, odd cases} {
    set x {}
    list [scan {+ } {%i} x] $x
} {0 {}}
test scan-4.44 {Tcl_ScanObjCmd, integer scanning, odd cases} {
    set x {}
    list [scan {+} {%i} x] $x
} {-1 {}}
test scan-4.45 {Tcl_ScanObjCmd, integer scanning, odd cases} {
    set x {}
    list [scan {0x} {%i%s} x y] $x $y
} {2 0 x}
test scan-4.46 {Tcl_ScanObjCmd, integer scanning, odd cases} {
    set x {}
    list [scan {0X} {%i%s} x y] $x $y
} {2 0 X}
test scan-4.47 {Tcl_ScanObjCmd, integer scanning, suppressed} {
    set x {}
    list [scan {123def} {%*i%s} x] $x
} {1 def}
test scan-4.48 {Tcl_ScanObjCmd, float scanning} {
    list [scan {1 2 3} {%e %f %g} x y z] $x $y $z
} {3 1.0 2.0 3.0}
test scan-4.49 {Tcl_ScanObjCmd, float scanning} {
    list [scan {.1 0.2 3.} {%e %f %g} x y z] $x $y $z
} {3 0.1 0.2 3.0}
test scan-4.50 {Tcl_ScanObjCmd, float scanning} {
    list [scan {1234567890a} %f x] $x
} {1 1234567890.0}
test scan-4.51 {Tcl_ScanObjCmd, float scanning} {
    list [scan {+123+45} %f x] $x
} {1 123.0}
test scan-4.52 {Tcl_ScanObjCmd, float scanning} {
    list [scan {-123+45} %f x] $x
} {1 -123.0}
test scan-4.53 {Tcl_ScanObjCmd, float scanning} {
    list [scan {1.0e1} %f x] $x
} {1 10.0}
test scan-4.54 {Tcl_ScanObjCmd, float scanning} {
    list [scan {1.0e-1} %f x] $x
} {1 0.1}
test scan-4.55 {Tcl_ScanObjCmd, odd cases} {
    set x {}
    list [scan {+} %f x] $x
} {-1 {}}
test scan-4.56 {Tcl_ScanObjCmd, odd cases} {
    set x {}
    list [scan {1.0e} %f%s x y] $x $y
} {2 1.0 e}
test scan-4.57 {Tcl_ScanObjCmd, odd cases} {
    set x {}
    list [scan {1.0e+} %f%s x y] $x $y
} {2 1.0 e+}
test scan-4.58 {Tcl_ScanObjCmd, odd cases} {
    set x {}
    set y {}
    list [scan {e1} %f%s x y] $x $y
} {0 {} {}}
test scan-4.59 {Tcl_ScanObjCmd, float scanning} {
    list [scan {1.0e-1x} %*f%n x] $x
} {1 6}

test scan-4.60 {Tcl_ScanObjCmd, set errors} {
    set x {}
    set y {}
    catch {unset z}; array set z {}
    set result [list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] \
	    $msg $x $y]
    unset z
    set result
} {1 {couldn't set variable "z"} abc ghi}
test scan-4.61 {Tcl_ScanObjCmd, set errors} {
    set x {}
    catch {unset y}; array set y {}
    catch {unset z}; array set z {}
    set result [list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] \
	    $msg $x]
    unset y
    unset z
    set result
} {1 {couldn't set variable "z"couldn't set variable "y"} abc}

test scan-5.1 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "-20 1476 \n33 0" "%d %d %d %d" a b c d] $a $b $c $d
} {4 -20 1476 33 0}
test scan-5.2 {integer scanning} {
    set a {}; set b {}; set c {}
    list [scan "-45 16 7890 +10" "%2d %*d %10d %d" a b c] $a $b $c
} {3 -4 16 7890}
test scan-5.3 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "-45 16 +10 987" "%ld %d %ld %d" a b c d] $a $b $c $d
} {4 -45 16 10 987}
test scan-5.4 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "14 1ab 62 10" "%d %x %lo %x" a b c d] $a $b $c $d
} {4 14 427 50 16}
test scan-5.5 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "12345670 1234567890ab cdefg" "%o	 %o %x %lx" a b c d] \
	    $a $b $c $d
} {4 2739128 342391 561323 52719}
test scan-5.6 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "ab123-24642" "%2x %3x %3o %2o" a b c d] $a $b $c $d
} {4 171 291 -20 52}
test scan-5.7 {integer scanning} {
    set a {}; set b {}
    list [scan "1234567 234 567  " "%*3x %x %*o %4o" a b] $a $b
} {2 17767 375}
test scan-5.8 {integer scanning} {
    set a {}; set b {}
    list [scan "a	1234" "%d %d" a b] $a $b
} {0 {} {}}
test scan-5.9 {integer scanning} {
    set a {}; set b {}; set c {}; set d {};
    list [scan "12345678" "%2d %2d %2ld %2d" a b c d] $a $b $c $d
} {4 12 34 56 78}
test scan-5.10 {integer scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "1 2 " "%hd %d %d %d" a b c d] $a $b $c $d
} {2 1 2 {} {}}
#
# The behavior for scaning intergers larger than MAX_INT is
# not defined by the ANSI spec.  Some implementations wrap the
# input (-16) some return MAX_INT.
#
test scan-5.11 {integer scanning} {nonPortable} {
    set a {}; set b {};
    list [scan "4294967280 4294967280" "%u %d" a b] $a \
	    [expr {$b == -16 || $b == 0x7fffffff}]
} {2 4294967280 1}

test scan-6.1 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d
} {3 2.1 -300000000.0 0.99962 {}}
test scan-6.2 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "-1.2345 +8.2 9" "%3e %3lf %f %f" a b c d] $a $b $c $d
} {4 -1.0 234.0 5.0 8.2}
test scan-6.3 {floating-point scanning} {
    set a {}; set b {}; set c {}
    list [scan "1e00004 332E-4 3e+4" "%Lf %*2e %f %f" a b c] $a $c
} {3 10000.0 30000.0}
#
# Some libc implementations consider 3.e- bad input.  The ANSI
# spec states that digits must follow the - sign.
#
test scan-6.4 {floating-point scanning} {
    set a {}; set b {}; set c {}
    list [scan "1. 47.6 2.e2 3.e-" "%f %*f %f %f" a b c] $a $b $c
} {3 1.0 200.0 3.0}
test scan-6.5 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "4.6 99999.7 876.43e-1 118" "%f %f %f %e" a b c d] $a $b $c $d
} {4 4.6 99999.7 87.643 118.0}
test scan-6.6 {floating-point scanning} {eformat} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "1.2345 697.0e-3 124 .00005" "%f %e %f %e" a b c d] $a $b $c $d
} {4 1.2345 0.697 124.0 5e-05}
test scan-6.7 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "4.6abc" "%f %f %f %f" a b c d] $a $b $c $d
} {1 4.6 {} {} {}}
test scan-6.8 {floating-point scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "4.6 5.2" "%f %f %f %f" a b c d] $a $b $c $d
} {2 4.6 5.2 {} {}}

test scan-7.1 {string and character scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "abc defghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
} {4 abc def ghijk dum}
test scan-7.2 {string and character scanning} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "a       bcdef" "%c%c%1s %s" a b c d] $a $b $c $d
} {4 97 32 b cdef}
test scan-7.3 {string and character scanning} {
    set a {}; set b {}; set c {}
    list [scan "123456 test " "%*c%*s %s %s %s" a b c] $a $b $c
} {1 test {} {}}
test scan-7.4 {string and character scanning} {
    set a {}; set b {}; set c {}; set d
    list [scan "ababcd01234  f 123450" {%4[abcd] %4[abcd] %[^abcdef] %[^0]} a b c d] $a $b $c $d
} {4 abab cd {01234  } {f 12345}}
test scan-7.5 {string and character scanning} {
    set a {}; set b {}; set c {}
    list [scan "aaaaaabc aaabcdefg  + +  XYZQR" {%*4[a] %s %*4[a]%s%*4[ +]%c} a b c] $a $b $c
} {3 aabc bcdefg 43}
test scan-7.6 {string and character scanning, unicode} {
    set a {}; set b {}; set c {}; set d {}
    list [scan "abc d\u00c7fghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
} "4 abc d\u00c7f ghijk dum"
test scan-7.7 {string and character scanning, unicode} {
    set a {}; set b {}
    list [scan "ab\u00c7cdef" "ab%c%c" a b] $a $b
} "2 199 99"
test scan-7.8 {string and character scanning, unicode} {
    set a {}; set b {}
    list [scan "ab\ufeffdef" "%\[ab\ufeff\]" a] $a
} "1 ab\ufeff"

test scan-8.1 {error conditions} {
    catch {scan a}
} 1
test scan-8.2 {error conditions} {
    catch {scan a} msg
    set msg
} {wrong # args: should be "scan string format ?varName varName ...?"}
test scan-8.3 {error conditions} {







    list [catch {scan a %D x} msg] $msg
} {1 {bad scan conversion character "D"}}
test scan-8.4 {error conditions} {
    list [catch {scan a %O x} msg] $msg
} {1 {bad scan conversion character "O"}}
test scan-8.5 {error conditions} {
    list [catch {scan a %X x} msg] $msg
} {1 {bad scan conversion character "X"}}
test scan-8.6 {error conditions} {
    list [catch {scan a %F x} msg] $msg
} {1 {bad scan conversion character "F"}}
test scan-8.7 {error conditions} {
    list [catch {scan a %E x} msg] $msg
} {1 {bad scan conversion character "E"}}
test scan-8.8 {error conditions} {
    list [catch {scan a "%d %d" a} msg] $msg
} {1 {different numbers of variable names and field specifiers}}
test scan-8.9 {error conditions} {
    list [catch {scan a "%d %d" a b c} msg] $msg
} {1 {variable is not assigend by any conversion specifiers}}
test scan-8.10 {error conditions} {
    set a {}; set b {}; set c {}; set d {}
    list [expr {[scan "  a" " a %d %d %d %d" a b c d] <= 0}] $a $b $c $d
} {1 {} {} {} {}}
test scan-8.11 {error conditions} {



    set a {}; set b {}; set c {}; set d {}




    list [scan "1 2" "%d %d %d %d" a b c d] $a $b $c $d
} {2 1 2 {} {}}
test scan-8.12 {error conditions} {
    catch {unset a}
    set a(0) 44
    list [catch {scan 44 %d a} msg] $msg
} {1 {couldn't set variable "a"}}
test scan-8.13 {error conditions} {
    catch {unset a}
    set a(0) 44
    list [catch {scan 44 %c a} msg] $msg
} {1 {couldn't set variable "a"}}
test scan-8.14 {error conditions} {
    catch {unset a}
    set a(0) 44
    list [catch {scan 44 %s a} msg] $msg
} {1 {couldn't set variable "a"}}
test scan-8.15 {error conditions} {
    catch {unset a}
    set a(0) 44
    list [catch {scan 44 %f a} msg] $msg
} {1 {couldn't set variable "a"}}
test scan-8.16 {error conditions} {
    catch {unset a}
    set a(0) 44
    list [catch {scan 44 %f a} msg] $msg
} {1 {couldn't set variable "a"}}
catch {unset a}
test scan-8.17 {error conditions} {
    list [catch {scan 44 %2c a} msg] $msg
} {1 {field width may not be specified in %c conversion}}
test scan-8.18 {error conditions} {
    list [catch {scan abc {%[} x} msg] $msg
} {1 {unmatched [ in format string}}
test scan-8.19 {error conditions} {
    list [catch {scan abc {%[^a} x} msg] $msg
} {1 {unmatched [ in format string}}
test scan-8.20 {error conditions} {
    list [catch {scan abc {%[^]a} x} msg] $msg
} {1 {unmatched [ in format string}}
test scan-8.21 {error conditions} {
    list [catch {scan abc {%[]a} x} msg] $msg
} {1 {unmatched [ in format string}}

test scan-9.1 {lots of arguments} {
    scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
} 20
test scan-9.2 {lots of arguments} {
    scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
    set a20
} 200

test scan-10.1 {miscellaneous tests} {
    set a {}
    list [scan ab16c ab%dc a] $a
} {1 16}
test scan-10.2 {miscellaneous tests} {
    set a {}
    list [scan ax16c ab%dc a] $a
} {0 {}}
test scan-10.3 {miscellaneous tests} {
    set a {}
    list [catch {scan ab%c114 ab%%c%d a} msg] $msg $a
} {0 1 114}
test scan-10.4 {miscellaneous tests} {
    set a {}
    list [catch {scan ab%c14 ab%%c%d a} msg] $msg $a
} {0 1 14}
test scan-10.5 {miscellaneous tests} {
    catch {unset arr}
    set arr(2) {}




    list [catch {scan ab%c14 ab%%c%d arr(2)} msg] $msg $arr(2)
} {0 1 14}

test scan-11.1 {alignment in results array (TCL_ALIGN)} {
    scan "123 13.6" "%s %f" a b
    set b
} 13.6
test scan-11.2 {alignment in results array (TCL_ALIGN)} {
    scan "1234567 13.6" "%s %f" a b
    set b
} 13.6
test scan-11.3 {alignment in results array (TCL_ALIGN)} {
    scan "12345678901 13.6" "%s %f" a b
    set b
} 13.6
test scan-11.4 {alignment in results array (TCL_ALIGN)} {
    scan "123456789012345 13.6" "%s %f" a b
    set b
} 13.6
test scan-11.5 {alignment in results array (TCL_ALIGN)} {
    scan "1234567890123456789 13.6" "%s %f" a b
    set b
} 13.6

# cleanup
::tcltest::cleanupTests
return














Added tests/security.test.











































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# security.test --
#
# Functionality covered: this file contains a collection of tests for the
# auto loading and namespaces.
#
# 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.
# All rights reserved.
#
# RCS: @(#) $Id: security.test,v 1.1.2.4 1999/03/24 02:49:39 hershey Exp $

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

# If this proc becomes invoked, then there is a bug

proc BUG {args} {
  set ::BUG 1
}

# Check and Clear the bug flag (to do before each test)
set ::BUG 0

proc CB {} {
    set ret $::BUG
    set ::BUG 0
    return $ret
}


test sec-1.1 {tcl_endOfPreviousWord} {
    catch {tcl_startOfPreviousWord x {[BUG]}}
    CB
} 0

# cleanup
::tcltest::cleanupTests
return











Changes to tests/set-old.test.

1
2
3
4
5
6
7
8
9
10

11
12
13
14

15


16
17
18
19
20
21
22
23
24
# Commands covered:  set, unset, array
#
# This file includes the original set of tests for Tcl's set command.
# Since the set command is now compiled, a new set of tests covering
# the new implementation is in the file "set.test". 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-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.
#

# SCCS: @(#) set-old.test 1.22 97/10/29 14:05:07



if {[string compare test [info procs test]] == 1} then {source defs}

proc ignore args {}

# Simple variable operations.

catch {unset a}
test set-old-1.1 {basic variable setting and unsetting} {










>




>
|
>
>
|
<







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
# Commands covered:  set, unset, array
#
# This file includes the original set of tests for Tcl's set command.
# Since the set command is now compiled, a new set of tests covering
# the new implementation is in the file "set.test". 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-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: set-old.test,v 1.1.2.5 1999/03/24 02:49:40 hershey Exp $

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


proc ignore args {}

# Simple variable operations.

catch {unset a}
test set-old-1.1 {basic variable setting and unsetting} {
470
471
472
473
474
475
476























477
478
479
480
481
482
483
    list [catch {foo 1} msg] $msg
} {0 {}}
test set-old-8.37 {array command, set option} {
    catch {unset aVaRnAmE}
    array set aVaRnAmE {}
    list [info exists aVaRnAmE] [catch {set aVaRnAmE} msg] $msg
} {1 1 {can't read "aVaRnAmE": variable is array}}























test set-old-8.38 {array command, size option} {
    catch {unset a}
    array size a
} {0}
test set-old-8.39 {array command, size option} {
    list [catch {array size a 4} msg] $msg
} {1 {wrong # args: should be "array size arrayName"}}







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







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
    list [catch {foo 1} msg] $msg
} {0 {}}
test set-old-8.37 {array command, set option} {
    catch {unset aVaRnAmE}
    array set aVaRnAmE {}
    list [info exists aVaRnAmE] [catch {set aVaRnAmE} msg] $msg
} {1 1 {can't read "aVaRnAmE": variable is array}}
test set-old-8.37.1 {array command, set scalar} {
    catch {unset aVaRnAmE}
    set aVaRnAmE 1
    list [catch {array set aVaRnAmE {}} msg] $msg
} {1 {can't array set "aVaRnAmE": variable isn't array}}
test set-old-8.37.2 {array command, set alias} {
    catch {unset aVaRnAmE}
    upvar 0 aVaRnAmE anAliAs
    array set anAliAs {}
    list [array exists aVaRnAmE] [catch {set anAliAs} msg] $msg
} {1 1 {can't read "anAliAs": variable is array}}
test set-old-8.37.3 {array command, set element alias} {
    catch {unset aVaRnAmE}
    list [catch {upvar 0 aVaRnAmE(elem) elemAliAs}] \
	    [catch {array set elemAliAs {}} msg] $msg
} {0 1 {can't array set "elemAliAs": variable isn't array}}
test set-old-8.37.4 {array command, empty set with populated array} {
    catch {unset aVaRnAmE}
    array set aVaRnAmE [list e1 v1 e2 v2]
    array set aVaRnAmE {}
    array set aVaRnAmE [list e3 v3]
    list [lsort [array names aVaRnAmE]] [catch {set aVaRnAmE(e2)} msg] $msg
} {{e1 e2 e3} 0 v2}
test set-old-8.38 {array command, size option} {
    catch {unset a}
    array size a
} {0}
test set-old-8.39 {array command, size option} {
    list [catch {array size a 4} msg] $msg
} {1 {wrong # args: should be "array size arrayName"}}
759
760
761
762
763
764
765
766
767
768
769
770



771












	set x(1) 23456
    }
    foo
} 23456

# Must delete variables when done, since these arrays get used as
# scalars by other tests.

catch {unset a}
catch {unset b}
catch {unset c}
catch {unset aVaRnAmE}



return ""



















<




>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
785
786
787
788
789
790
791

792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
	set x(1) 23456
    }
    foo
} 23456

# Must delete variables when done, since these arrays get used as
# scalars by other tests.

catch {unset a}
catch {unset b}
catch {unset c}
catch {unset aVaRnAmE}

# cleanup
::tcltest::cleanupTests
return 












Changes to tests/set.test.

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
# Commands covered:  set
#
# 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) 1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) set.test 1.6 97/06/23 18:18:54



if {[string compare test [info procs test]] == 1} then {source defs}

catch {unset x}
catch {unset i}

test set-1.1 {TclCompileSetCmd: missing variable name} {
    list [catch {set} msg] $msg
} {1 {wrong # args: should be "set varName ?newValue?"}}
test set-1.2 {TclCompileSetCmd: simple variable name} {
    set i 10
    list [set i] $i
} {10 10}
test set-1.3 {TclCompileSetCmd: error compiling variable name} {
    set i 10
    catch {set "i"xxx} msg
    set msg
} {quoted string doesn't terminate properly}
test set-1.4 {TclCompileSetCmd: simple variable name in quotes} {
    set i 17
    list [set "i"] $i
} {17 17}
test set-1.5 {TclCompileSetCmd: simple variable name in braces} {
    catch {unset {a simple var}}
    set {a simple var} 27







>




>
|
>
>
|
<















|







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
# Commands covered:  set
#
# 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) 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: set.test,v 1.1.2.5 1999/03/24 02:49:40 hershey Exp $

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


catch {unset x}
catch {unset i}

test set-1.1 {TclCompileSetCmd: missing variable name} {
    list [catch {set} msg] $msg
} {1 {wrong # args: should be "set varName ?newValue?"}}
test set-1.2 {TclCompileSetCmd: simple variable name} {
    set i 10
    list [set i] $i
} {10 10}
test set-1.3 {TclCompileSetCmd: error compiling variable name} {
    set i 10
    catch {set "i"xxx} msg
    set msg
} {extra characters after close-quote}
test set-1.4 {TclCompileSetCmd: simple variable name in quotes} {
    set i 17
    list [set "i"] $i
} {17 17}
test set-1.5 {TclCompileSetCmd: simple variable name in braces} {
    catch {unset {a simple var}}
    set {a simple var} 27
222
223
224
225
226
227
228

























































































































































































































































229
230
231
232


233












test set-2.5 {set command: runtime error, basic array operations} {
    list [catch {set a(other)} msg] $msg
} {1 {can't read "a(other)": no such element in array}}
test set-2.6 {set command: runtime error, basic array operations} {
    list [catch {set a} msg] $msg
} {1 {can't read "a": variable is array}}


























































































































































































































































catch {unset a}
catch {unset b}
catch {unset i}
catch {unset x}


return ""



















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




>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
test set-2.5 {set command: runtime error, basic array operations} {
    list [catch {set a(other)} msg] $msg
} {1 {can't read "a(other)": no such element in array}}
test set-2.6 {set command: runtime error, basic array operations} {
    list [catch {set a} msg] $msg
} {1 {can't read "a": variable is array}}

# Test the uncompiled version of set

catch {unset a}
catch {unset b}
catch {unset i}
catch {unset x}

test set-3.1 {uncompiled set command: missing variable name} {
    set z set
    list [catch {$z} msg] $msg
} {1 {wrong # args: should be "set varName ?newValue?"}}
test set-3.2 {uncompiled set command: simple variable name} {
    set z set
    $z i 10
    list [$z i] $i
} {10 10}
test set-3.3 {uncompiled set command: error compiling variable name} {
    set z set
    $z i 10
    catch {$z "i"xxx} msg
    $z msg
} {extra characters after close-quote}
test set-3.4 {uncompiled set command: simple variable name in quotes} {
    set z set
    $z i 17
    list [$z "i"] $i
} {17 17}
test set-3.5 {uncompiled set command: simple variable name in braces} {
    set z set
    catch {unset {a simple var}}
    $z {a simple var} 27
    list [$z {a simple var}] ${a simple var}
} {27 27}
test set-3.6 {uncompiled set command: simple array variable name} {
    set z set
    catch {unset a}
    $z a(foo) 37
    list [$z a(foo)] $a(foo)
} {37 37}
test set-3.7 {uncompiled set command: non-simple (computed) variable name} {
    set z set
    $z x "i"
    $z i 77
    list [$z $x] $i
} {77 77}
test set-3.8 {uncompiled set command: non-simple (computed) variable name} {
    set z set
    $z x "i"
    $z i 77
    list [$z [$z x] 2] $i
} {2 2}

test set-3.9 {uncompiled set command: 3rd arg => assignment} {
    set z set
    $z i "abcdef"
    list [$z i] $i
} {abcdef abcdef}
test set-3.10 {uncompiled set command: only two args => just getting value} {
    set z set
    $z i {one two}
    $z i
} {one two}

test set-3.11 {uncompiled set command: simple global name} {
    proc p {} {
	set z set
        global i
        $z i 54
        $z i
    }
    p
} {54}
test set-3.12 {uncompiled set command: simple local name} {
    proc p {bar} {
	set z set
        $z foo $bar
        $z foo
    }
    p 999
} {999}
test set-3.13 {uncompiled set command: simple but new (unknown) local name} {
    set z set
    proc p {} {
	set z set
        $z bar
    }
    catch {p} msg
    $z msg
} {can't read "bar": no such variable}
test set-3.14 {uncompiled set command: simple local name, >255 locals} {
    proc 260locals {} {
	set z set
        # create 260 locals (the last ones with index > 255)
        $z a0 0; $z a1 0; $z a2 0; $z a3 0; $z a4 0
        $z a5 0; $z a6 0; $z a7 0; $z a8 0; $z a9 0
        $z b0 0; $z b1 0; $z b2 0; $z b3 0; $z b4 0
        $z b5 0; $z b6 0; $z b7 0; $z b8 0; $z b9 0
        $z c0 0; $z c1 0; $z c2 0; $z c3 0; $z c4 0
        $z c5 0; $z c6 0; $z c7 0; $z c8 0; $z c9 0
        $z d0 0; $z d1 0; $z d2 0; $z d3 0; $z d4 0
        $z d5 0; $z d6 0; $z d7 0; $z d8 0; $z d9 0
        $z e0 0; $z e1 0; $z e2 0; $z e3 0; $z e4 0
        $z e5 0; $z e6 0; $z e7 0; $z e8 0; $z e9 0
        $z f0 0; $z f1 0; $z f2 0; $z f3 0; $z f4 0
        $z f5 0; $z f6 0; $z f7 0; $z f8 0; $z f9 0
        $z g0 0; $z g1 0; $z g2 0; $z g3 0; $z g4 0
        $z g5 0; $z g6 0; $z g7 0; $z g8 0; $z g9 0
        $z h0 0; $z h1 0; $z h2 0; $z h3 0; $z h4 0
        $z h5 0; $z h6 0; $z h7 0; $z h8 0; $z h9 0
        $z i0 0; $z i1 0; $z i2 0; $z i3 0; $z i4 0
        $z i5 0; $z i6 0; $z i7 0; $z i8 0; $z i9 0
        $z j0 0; $z j1 0; $z j2 0; $z j3 0; $z j4 0
        $z j5 0; $z j6 0; $z j7 0; $z j8 0; $z j9 0
        $z k0 0; $z k1 0; $z k2 0; $z k3 0; $z k4 0
        $z k5 0; $z k6 0; $z k7 0; $z k8 0; $z k9 0
        $z l0 0; $z l1 0; $z l2 0; $z l3 0; $z l4 0
        $z l5 0; $z l6 0; $z l7 0; $z l8 0; $z l9 0
        $z m0 0; $z m1 0; $z m2 0; $z m3 0; $z m4 0
        $z m5 0; $z m6 0; $z m7 0; $z m8 0; $z m9 0
        $z n0 0; $z n1 0; $z n2 0; $z n3 0; $z n4 0
        $z n5 0; $z n6 0; $z n7 0; $z n8 0; $z n9 0
        $z o0 0; $z o1 0; $z o2 0; $z o3 0; $z o4 0
        $z o5 0; $z o6 0; $z o7 0; $z o8 0; $z o9 0
        $z p0 0; $z p1 0; $z p2 0; $z p3 0; $z p4 0
        $z p5 0; $z p6 0; $z p7 0; $z p8 0; $z p9 0
        $z q0 0; $z q1 0; $z q2 0; $z q3 0; $z q4 0
        $z q5 0; $z q6 0; $z q7 0; $z q8 0; $z q9 0
        $z r0 0; $z r1 0; $z r2 0; $z r3 0; $z r4 0
        $z r5 0; $z r6 0; $z r7 0; $z r8 0; $z r9 0
        $z s0 0; $z s1 0; $z s2 0; $z s3 0; $z s4 0
        $z s5 0; $z s6 0; $z s7 0; $z s8 0; $z s9 0
        $z t0 0; $z t1 0; $z t2 0; $z t3 0; $z t4 0
        $z t5 0; $z t6 0; $z t7 0; $z t8 0; $z t9 0
        $z u0 0; $z u1 0; $z u2 0; $z u3 0; $z u4 0
        $z u5 0; $z u6 0; $z u7 0; $z u8 0; $z u9 0
        $z v0 0; $z v1 0; $z v2 0; $z v3 0; $z v4 0
        $z v5 0; $z v6 0; $z v7 0; $z v8 0; $z v9 0
        $z w0 0; $z w1 0; $z w2 0; $z w3 0; $z w4 0
        $z w5 0; $z w6 0; $z w7 0; $z w8 0; $z w9 0
        $z x0 0; $z x1 0; $z x2 0; $z x3 0; $z x4 0
        $z x5 0; $z x6 0; $z x7 0; $z x8 0; $z x9 0
        $z y0 0; $z y1 0; $z y2 0; $z y3 0; $z y4 0
        $z y5 0; $z y6 0; $z y7 0; $z y8 0; $z y9 0
        $z z0 0; $z z1 0; $z z2 0; $z z3 0; $z z4 0
        $z z5 0; $z z6 0; $z z7 0; $z z8 0; $z z9 1234
    }
    260locals
} {1234}
test set-3.15 {uncompiled set command: variable is array} {
    set z set
    catch {unset a}
    $z x 27
    $z x [$z a(foo) 11]
    catch {unset a}
    $z x
} 11
test set-3.16 {uncompiled set command: variable is array, elem substitutions} {
    set z set
    catch {unset a}
    $z i 5
    $z x 789
    $z a(foo5) 27
    $z x [$z a(foo$i)]
    catch {unset a}
    $z x
} 27

test set-3.17 {uncompiled set command: doing assignment, simple int} {
    set z set
    $z i 5
    $z i 123
} 123
test set-3.18 {uncompiled set command: doing assignment, simple int} {
    set z set
    $z i 5
    $z i -100
} -100
test set-3.19 {uncompiled set command: doing assignment, simple but not int} {
    set z set
    $z i 5
    $z i 0x12MNOP
    $z i
} {0x12MNOP}
test set-3.20 {uncompiled set command: doing assignment, in quotes} {
    set z set
    $z i 25
    $z i "-100"
} -100
test set-3.21 {uncompiled set command: doing assignment, in braces} {
    set z set
    $z i 24
    $z i {126}
} 126
test set-3.22 {uncompiled set command: doing assignment, large int} {
    set z set
    $z i 5
    $z i 200000
} 200000
test set-3.23 {uncompiled set command: doing assignment, formatted int != int} {
    set z set
    $z i 25
    $z i 000012345     ;# an octal literal == 5349 decimal
    list $i [incr i]
} {000012345 5350}

test set-3.24 {uncompiled set command: too many arguments} {
    set z set
    $z i 10
    catch {$z i 20 30} msg
    $z msg
} {wrong # args: should be "set varName ?newValue?"}

test set-4.1 {uncompiled set command: runtime error, bad variable name} {
    set z set
    list [catch {$z {"foo}} msg] $msg $errorInfo
} {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
    while executing
"$z {"foo}"}}
test set-4.2 {uncompiled set command: runtime error, not array variable} {
    set z set
    catch {unset b}
    $z b 44
    list [catch {$z b(123)} msg] $msg
} {1 {can't read "b(123)": variable isn't array}}
test set-4.3 {uncompiled set command: runtime error, errors in reading variables} {
     set z set
   catch {unset a}
    $z a(6) 44
    list [catch {$z a(18)} msg] $msg
} {1 {can't read "a(18)": no such element in array}}
test set-4.4 {uncompiled set command: runtime error, readonly variable} {
    set z set
    proc readonly args {error "variable is read-only"}
    $z x 123
    trace var x w readonly
    list [catch {$z x 1} msg] $msg $errorInfo
} {1 {can't set "x": variable is read-only} {can't set "x": variable is read-only
    while executing
"$z x 1"}}
test set-4.5 {uncompiled set command: runtime error, basic array operations} {
    set z set
    list [catch {$z a(other)} msg] $msg
} {1 {can't read "a(other)": no such element in array}}
test set-4.6 {set command: runtime error, basic array operations} {
    set z set
    list [catch {$z a} msg] $msg
} {1 {can't read "a": variable is array}}

# cleanup
catch {unset a}
catch {unset b}
catch {unset i}
catch {unset x}
catch {unset z}
::tcltest::cleanupTests
return 












Changes to tests/socket.test.

1
2
3
4
5
6
7

8
9
10
11


12
13
14
15
16
17
18
# Commands tested in this file: socket.
#
# 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) 1994-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#


# Running socket tests with a remote server:
# ------------------------------------------
# 
# Some tests in socket.test depend on the existence of a remote server to
# which they connect. The remote server must be an instance of tcltest and it
# must run the script found in the file "remote.tcl" in this directory. You
# can start the remote server on any machine reachable from the machine on







>




>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Commands tested in this file: socket.
#
# 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) 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: socket.test,v 1.1.2.11 1999/04/05 22:18:03 stanton Exp $

# Running socket tests with a remote server:
# ------------------------------------------
# 
# Some tests in socket.test depend on the existence of a remote server to
# which they connect. The remote server must be an instance of tcltest and it
# must run the script found in the file "remote.tcl" in this directory. You
# can start the remote server on any machine reachable from the machine on
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68


69
70
71
72
73
74
75
# The preamble of the socket.test file checks to see if the variables are set
# either in Tcl or in the environment; if they are, it attempts to connect to
# the server. If the connection is successful, the tests using the remote
# server will be performed; otherwise, it will attempt to start the remote
# server (via exec) on platforms that support this, on the local host,
# listening at port 2048. If all fails, a message is printed and the tests
# using the remote server are not performed.
#
# SCCS: @(#) socket.test 1.83 97/09/15 16:29:47


if {[string compare test [info procs test]] == 1} then {source defs}

if {$testConfig(socket) == 0} {
    return
}



#
# If remoteServerIP or remoteServerPort are not set, check in the
# environment variables for externally set values.
#

if {![info exists remoteServerIP]} {







|
|
>
|
<

|
<
|
>
>







57
58
59
60
61
62
63
64
65
66
67

68
69

70
71
72
73
74
75
76
77
78
79
# The preamble of the socket.test file checks to see if the variables are set
# either in Tcl or in the environment; if they are, it attempts to connect to
# the server. If the connection is successful, the tests using the remote
# server will be performed; otherwise, it will attempt to start the remote
# server (via exec) on platforms that support this, on the local host,
# listening at port 2048. If all fails, a message is printed and the tests
# using the remote server are not performed.

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


# Some tests require the testthread command


set ::tcltest::testConfig(testthread) \
	[expr {[info commands testthread] != {}}]

#
# If remoteServerIP or remoteServerPort are not set, check in the
# environment variables for externally set values.
#

if {![info exists remoteServerIP]} {
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

#
# Check if we're supposed to do tests against the remote server
#

set doTestsWithRemoteServer 1
if {![info exists remoteServerIP] && ($tcl_platform(platform) != "macintosh")} {
    set remoteServerIP localhost
}
if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
    set remoteServerPort 2048
}

# Attempt to connect to a remote server if one is already running. If it
# is not running or for some other reason the connect fails, attempt to







|







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

#
# Check if we're supposed to do tests against the remote server
#

set doTestsWithRemoteServer 1
if {![info exists remoteServerIP] && ($tcl_platform(platform) != "macintosh")} {
    set remoteServerIP 127.0.0.1
}
if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
    set remoteServerPort 2048
}

# Attempt to connect to a remote server if one is already running. If it
# is not running or for some other reason the connect fails, attempt to
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
if {$doTestsWithRemoteServer} {
    catch {close $commandSocket}
    if {[catch {set commandSocket [socket $remoteServerIP \
						$remoteServerPort]}] != 0} {
	if {[info commands exec] == ""} {
	    set noRemoteTestReason "can't exec"
	    set doTestsWithRemoteServer 0
	} elseif {$testConfig(win32s)} {
	    set noRemoteTestReason "\ncan't run multiple instances of tcltest under win32s."
	    set doTestsWithRemoteServer 0
	} else {
	    set remoteServerIP localhost

	    if {[catch {set remoteProcChan \
				[open "|[list $tcltest remote.tcl \
					-serverIsSilent \
					-port $remoteServerPort \
					-address $remoteServerIP]" \
					w+]} \
		   msg] == 0} {
		after 1000
		if {[catch {set commandSocket [socket $remoteServerIP \







<
<
<

|
>

|







115
116
117
118
119
120
121



122
123
124
125
126
127
128
129
130
131
132
133
if {$doTestsWithRemoteServer} {
    catch {close $commandSocket}
    if {[catch {set commandSocket [socket $remoteServerIP \
						$remoteServerPort]}] != 0} {
	if {[info commands exec] == ""} {
	    set noRemoteTestReason "can't exec"
	    set doTestsWithRemoteServer 0



	} else {
	    set remoteServerIP 127.0.0.1
	    set remoteFile [file join [pwd] remote.tcl]
	    if {[catch {set remoteProcChan \
				[open "|[list $tcltest $remoteFile \
					-serverIsSilent \
					-port $remoteServerPort \
					-address $remoteServerIP]" \
					w+]} \
		   msg] == 0} {
		after 1000
		if {[catch {set commandSocket [socket $remoteServerIP \
141
142
143
144
145
146
147


148

149
150
151
152
153
154
155
156
157
158
	    }
	}
    } else {
	fconfigure $commandSocket -translation crlf -buffering line
    }
}



if {$doTestsWithRemoteServer == 0} {

    puts "Skipping tests with remote server. See tests/socket.test for"
    puts "information on how to run remote server."
    if {[info exists VERBOSE] && ($VERBOSE != 0)} {
	puts "Reason for not doing remote tests: $noRemoteTestReason"
    }
}

#
# If we do the tests, define a command to send a command to the
# remote server.







>
>

>
|
|
<







143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
	    }
	}
    } else {
	fconfigure $commandSocket -translation crlf -buffering line
    }
}

# Some tests are run only if we are doing testing against a remote server.
set ::tcltest::testConfig(doTestsWithRemoteServer) $doTestsWithRemoteServer
if {$doTestsWithRemoteServer == 0} {
    if {[string first s $::tcltest::verbose] != -1} {
    	puts "Skipping tests with remote server. See tests/socket.test for"
	puts "information on how to run remote server."

	puts "Reason for not doing remote tests: $noRemoteTestReason"
    }
}

#
# If we do the tests, define a command to send a command to the
# remote server.
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
	    } else {
		append resp $line "\n"
	    }
	}
    }
}

test socket-1.1 {arg parsing for socket command} {
    list [catch {socket -server} msg] $msg
} {1 {no argument given for -server option}}
test socket-1.2 {arg parsing for socket command} {
    list [catch {socket -server foo} msg] $msg
} {1 {wrong # args: should be either:
socket ?-myaddr addr? ?-myport myport? ?-async? host port
socket -server command ?-myaddr addr? port}}
test socket-1.3 {arg parsing for socket command} {
    list [catch {socket -myaddr} msg] $msg
} {1 {no argument given for -myaddr option}}
test socket-1.4 {arg parsing for socket command} {
    list [catch {socket -myaddr 127.0.0.1} msg] $msg
} {1 {wrong # args: should be either:
socket ?-myaddr addr? ?-myport myport? ?-async? host port
socket -server command ?-myaddr addr? port}}
test socket-1.5 {arg parsing for socket command} {
    list [catch {socket -myport} msg] $msg
} {1 {no argument given for -myport option}}
test socket-1.6 {arg parsing for socket command} {
    list [catch {socket -myport xxxx} msg] $msg
} {1 {expected integer but got "xxxx"}}
test socket-1.7 {arg parsing for socket command} {
    list [catch {socket -myport 2522} msg] $msg
} {1 {wrong # args: should be either:
socket ?-myaddr addr? ?-myport myport? ?-async? host port
socket -server command ?-myaddr addr? port}}
test socket-1.8 {arg parsing for socket command} {
    list [catch {socket -froboz} msg] $msg
} {1 {bad option "-froboz", must be -async, -myaddr, -myport, or -server}}
test socket-1.9 {arg parsing for socket command} {
    list [catch {socket -server foo -myport 2521 3333} msg] $msg
} {1 {Option -myport is not valid for servers}}
test socket-1.10 {arg parsing for socket command} {
    list [catch {socket host 2528 -junk} msg] $msg
} {1 {wrong # args: should be either:
socket ?-myaddr addr? ?-myport myport? ?-async? host port
socket -server command ?-myaddr addr? port}}
test socket-1.11 {arg parsing for socket command} {
    list [catch {socket -server callback 2520 --} msg] $msg
} {1 {wrong # args: should be either:
socket ?-myaddr addr? ?-myport myport? ?-async? host port
socket -server command ?-myaddr addr? port}}
test socket-1.12 {arg parsing for socket command} {
    list [catch {socket foo badport} msg] $msg
} {1 {expected integer but got "badport"}}

test socket-2.1 {tcp connection} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x timed_out"]
	set f [socket -server accept 2828]
	proc accept {file addr port} {
	    global x
	    set x done
            close $file
	}
	puts ready
	vwait x
	after cancel $timer
	close $f
	puts $x
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f x
    if {[catch {socket localhost 2828} msg]} {
        set x $msg
    } else {
        lappend x [gets $f]
        close $msg
    }
    lappend x [gets $f]
    close $f
    set x
} {ready done {}}

if [info exists port] {
    incr port
} else { 
    set port [expr 2048 + [pid]%1024]
}
test socket-2.2 {tcp connection with client port specified} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x done"]
        set f [socket -server accept 2828]
	proc accept {file addr port} {
            global x
            puts "[gets $file] $port"
            close $file
            set x done
	}
	puts ready
	vwait x
	after cancel $timer
	close $f
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f x
    global port
    if {[catch {socket -myport $port localhost 2828} sock]} {
        set x $sock
	close [socket localhost 2828]
	puts stderr $sock
    } else {
        puts $sock hello
	flush $sock
        lappend x [gets $f]
        close $sock
    }
    close $f
    set x
} [list ready "hello $port"]
test socket-2.3 {tcp connection with client interface specified} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x done"]
        set f [socket  -server accept 2828]
	proc accept {file addr port} {
            global x
            puts "[gets $file] $addr"
            close $file
            set x done
	}
	puts ready
	vwait x
	after cancel $timer
	close $f
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f x
    if {[catch {socket -myaddr localhost localhost 2828} sock]} {
        set x $sock
    } else {
        puts $sock hello
	flush $sock
        lappend x [gets $f]
        close $sock
    }
    close $f
    set x
} {ready {hello 127.0.0.1}}
test socket-2.4 {tcp connection with server interface specified} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x done"]
        set f [socket -server accept -myaddr [info hostname] 2828]
	proc accept {file addr port} {
            global x
            puts "[gets $file]"
            close $file
            set x done
	}
	puts ready
	vwait x
	after cancel $timer
	close $f
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f x
    if {[catch {socket [info hostname] 2828} sock]} {
        set x $sock
    } else {
        puts $sock hello
	flush $sock
        lappend x [gets $f]
        close $sock
    }
    close $f
    set x
} {ready hello}
test socket-2.5 {tcp connection with redundant server port} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x done"]
        set f [socket -server accept 2828]
	proc accept {file addr port} {
            global x
            puts "[gets $file]"
            close $file
            set x done
	}
	puts ready
	vwait x
	after cancel $timer
	close $f
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f x
    if {[catch {socket localhost 2828} sock]} {
        set x $sock
    } else {
        puts $sock hello
	flush $sock
        lappend x [gets $f]
        close $sock
    }
    close $f
    set x
} {ready hello}
test socket-2.6 {tcp connection} {} {
    set status ok
    if {![catch {set sock [socket localhost 2828]}]} {
	if {![catch {gets $sock}]} {
	    set status broken
	}
	close $sock
    }
    set status
} ok
test socket-2.7 {echo server, one line} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x done"]
	set f [socket -server accept 2828]
	proc accept {s a p} {
            fileevent $s readable [list echo $s]
	    fconfigure $s -translation lf -buffering line
        }
	proc echo {s} {
	     set l [gets $s]
             if {[eof $s]} {







|


|




|


|




|


|


|




|

|
|


|




|




|



|



















|















|




|















|

|










|




|














|










|




|














|










|




|














|










|

|







|




|







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
	    } else {
		append resp $line "\n"
	    }
	}
    }
}

test socket-1.1 {arg parsing for socket command} {socket} {
    list [catch {socket -server} msg] $msg
} {1 {no argument given for -server option}}
test socket-1.2 {arg parsing for socket command} {socket} {
    list [catch {socket -server foo} msg] $msg
} {1 {wrong # args: should be either:
socket ?-myaddr addr? ?-myport myport? ?-async? host port
socket -server command ?-myaddr addr? port}}
test socket-1.3 {arg parsing for socket command} {socket} {
    list [catch {socket -myaddr} msg] $msg
} {1 {no argument given for -myaddr option}}
test socket-1.4 {arg parsing for socket command} {socket} {
    list [catch {socket -myaddr 127.0.0.1} msg] $msg
} {1 {wrong # args: should be either:
socket ?-myaddr addr? ?-myport myport? ?-async? host port
socket -server command ?-myaddr addr? port}}
test socket-1.5 {arg parsing for socket command} {socket} {
    list [catch {socket -myport} msg] $msg
} {1 {no argument given for -myport option}}
test socket-1.6 {arg parsing for socket command} {socket} {
    list [catch {socket -myport xxxx} msg] $msg
} {1 {expected integer but got "xxxx"}}
test socket-1.7 {arg parsing for socket command} {socket} {
    list [catch {socket -myport 2522} msg] $msg
} {1 {wrong # args: should be either:
socket ?-myaddr addr? ?-myport myport? ?-async? host port
socket -server command ?-myaddr addr? port}}
test socket-1.8 {arg parsing for socket command} {socket} {
    list [catch {socket -froboz} msg] $msg
} {1 {bad option "-froboz": must be -async, -myaddr, -myport, or -server}}
test socket-1.9 {arg parsing for socket command} {socket} {
    list [catch {socket -server foo -myport 2521 3333} msg] $msg
} {1 {Option -myport is not valid for servers}}
test socket-1.10 {arg parsing for socket command} {socket} {
    list [catch {socket host 2528 -junk} msg] $msg
} {1 {wrong # args: should be either:
socket ?-myaddr addr? ?-myport myport? ?-async? host port
socket -server command ?-myaddr addr? port}}
test socket-1.11 {arg parsing for socket command} {socket} {
    list [catch {socket -server callback 2520 --} msg] $msg
} {1 {wrong # args: should be either:
socket ?-myaddr addr? ?-myport myport? ?-async? host port
socket -server command ?-myaddr addr? port}}
test socket-1.12 {arg parsing for socket command} {socket} {
    list [catch {socket foo badport} msg] $msg
} {1 {expected integer but got "badport"}}

test socket-2.1 {tcp connection} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x timed_out"]
	set f [socket -server accept 2828]
	proc accept {file addr port} {
	    global x
	    set x done
            close $file
	}
	puts ready
	vwait x
	after cancel $timer
	close $f
	puts $x
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f x
    if {[catch {socket 127.0.0.1 2828} msg]} {
        set x $msg
    } else {
        lappend x [gets $f]
        close $msg
    }
    lappend x [gets $f]
    close $f
    set x
} {ready done {}}

if [info exists port] {
    incr port
} else { 
    set port [expr 2048 + [pid]%1024]
}
test socket-2.2 {tcp connection with client port specified} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x done"]
        set f [socket -server accept 2829]
	proc accept {file addr port} {
            global x
            puts "[gets $file] $port"
            close $file
            set x done
	}
	puts ready
	vwait x
	after cancel $timer
	close $f
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f x
    global port
    if {[catch {socket -myport $port 127.0.0.1 2829} sock]} {
        set x $sock
	close [socket 127.0.0.1 2829]
	puts stderr $sock
    } else {
        puts $sock hello
	flush $sock
        lappend x [gets $f]
        close $sock
    }
    close $f
    set x
} [list ready "hello $port"]
test socket-2.3 {tcp connection with client interface specified} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x done"]
        set f [socket  -server accept 2830]
	proc accept {file addr port} {
            global x
            puts "[gets $file] $addr"
            close $file
            set x done
	}
	puts ready
	vwait x
	after cancel $timer
	close $f
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f x
    if {[catch {socket -myaddr 127.0.0.1 127.0.0.1 2830} sock]} {
        set x $sock
    } else {
        puts $sock hello
	flush $sock
        lappend x [gets $f]
        close $sock
    }
    close $f
    set x
} {ready {hello 127.0.0.1}}
test socket-2.4 {tcp connection with server interface specified} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x done"]
        set f [socket -server accept -myaddr [info hostname] 2831]
	proc accept {file addr port} {
            global x
            puts "[gets $file]"
            close $file
            set x done
	}
	puts ready
	vwait x
	after cancel $timer
	close $f
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f x
    if {[catch {socket [info hostname] 2831} sock]} {
        set x $sock
    } else {
        puts $sock hello
	flush $sock
        lappend x [gets $f]
        close $sock
    }
    close $f
    set x
} {ready hello}
test socket-2.5 {tcp connection with redundant server port} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x done"]
        set f [socket -server accept 2832]
	proc accept {file addr port} {
            global x
            puts "[gets $file]"
            close $file
            set x done
	}
	puts ready
	vwait x
	after cancel $timer
	close $f
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f x
    if {[catch {socket 127.0.0.1 2832} sock]} {
        set x $sock
    } else {
        puts $sock hello
	flush $sock
        lappend x [gets $f]
        close $sock
    }
    close $f
    set x
} {ready hello}
test socket-2.6 {tcp connection} {socket} {
    set status ok
    if {![catch {set sock [socket 127.0.0.1 2833]}]} {
	if {![catch {gets $sock}]} {
	    set status broken
	}
	close $sock
    }
    set status
} ok
test socket-2.7 {echo server, one line} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set timer [after 2000 "set x done"]
	set f [socket -server accept 2834]
	proc accept {s a p} {
            fileevent $s readable [list echo $s]
	    fconfigure $s -translation lf -buffering line
        }
	proc echo {s} {
	     set l [gets $s]
             if {[eof $s]} {
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
	after cancel $timer
	close $f
	puts done
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f
    set s [socket localhost 2828]
    fconfigure $s -buffering line -translation lf
    puts $s "hello abcdefghijklmnop"

    set x [gets $s]
    close $s
    set y [gets $f]
    close $f
    list $x $y
} {{hello abcdefghijklmnop} done}
test socket-2.8 {echo server, loop 50 times, single connection} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set f [socket -server accept 2828]
	proc accept {s a p} {
            fileevent $s readable [list echo $s]
            fconfigure $s -buffering line
        }
	proc echo {s} {
	     global i
             set l [gets $s]







|


>






|
|
<
<
|







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
	after cancel $timer
	close $f
	puts done
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f
    set s [socket 127.0.0.1 2834]
    fconfigure $s -buffering line -translation lf
    puts $s "hello abcdefghijklmnop"
    after 1000
    set x [gets $s]
    close $s
    set y [gets $f]
    close $f
    list $x $y
} {{hello abcdefghijklmnop} done}
test socket-2.8 {echo server, loop 50 times, single connection} {socket stdio} {
    makeFile {


	set f [socket -server accept 2835]
	proc accept {s a p} {
            fileevent $s readable [list echo $s]
            fconfigure $s -buffering line
        }
	proc echo {s} {
	     global i
             set l [gets $s]
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
	set i 0
	puts ready
	set timer [after 20000 "set x done"]
	vwait x
	after cancel $timer
	close $f
	puts "done $i"
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f
    set s [socket localhost 2828]
    fconfigure $s -buffering line

    for {set x 0} {$x < 50} {incr x} {
        puts $s "hello abcdefghijklmnop"
        gets $s
    }

    close $s
    set x [gets $f]
    close $f
    set x
} {done 50}
test socket-2.9 {socket conflict} {stdio} {
    set s [socket -server accept 2828]
    removeFile script
    set f [open script w]
    puts $f {set f [socket -server accept 2828]}
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f
    after 100
    set x [list [catch {close $f} msg] $msg]
    close $s
    set x
} {1 {couldn't open socket: address already in use
    while executing
"socket -server accept 2828"
    (file "script" line 1)}}
test socket-2.10 {close on accept, accepted socket lives} {
    set done 0
    set timer [after 20000 "set done timed_out"]
    set ss [socket -server accept 2830]
    proc accept {s a p} {
	global ss
	close $ss
	fileevent $s readable "readit $s"







|
<


|

>
|
|
|
|
>

|



|



|











|







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
	set i 0
	puts ready
	set timer [after 20000 "set x done"]
	vwait x
	after cancel $timer
	close $f
	puts "done $i"
    } script

    set f [open "|[list $tcltest script]" r]
    gets $f
    set s [socket 127.0.0.1 2835]
    fconfigure $s -buffering line
    catch {
	for {set x 0} {$x < 50} {incr x} {
	    puts $s "hello abcdefghijklmnop"
	    gets $s
	}
    }
    close $s
    catch {set x [gets $f]}
    close $f
    set x
} {done 50}
test socket-2.9 {socket conflict} {socket stdio} {
    set s [socket -server accept 2828]
    removeFile script
    set f [open script w]
    puts -nonewline $f {socket -server accept 2828}
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f
    after 100
    set x [list [catch {close $f} msg] $msg]
    close $s
    set x
} {1 {couldn't open socket: address already in use
    while executing
"socket -server accept 2828"
    (file "script" line 1)}}
test socket-2.10 {close on accept, accepted socket lives} {socket} {
    set done 0
    set timer [after 20000 "set done timed_out"]
    set ss [socket -server accept 2830]
    proc accept {s a p} {
	global ss
	close $ss
	fileevent $s readable "readit $s"
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
    set cs [socket [info hostname] 2830]
    puts $cs hello
    close $cs
    vwait done
    after cancel $timer
    set done
} 1





























test socket-3.1 {socket conflict} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set f [socket -server accept 2828]
	puts ready
	gets stdin
	close $f
    }
    close $f
    set f [open "|[list $tcltest script]" r+]
    gets $f
    set x [list [catch {socket -server accept 2828} msg] \
		$msg]
    puts $f bye
    close $f
    set x
} {1 {couldn't open socket: address already in use}}
test socket-3.2 {server with several clients} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set t1 [after 30000 "set x timed_out"]
	set t2 [after 31000 "set x timed_out"]
	set t3 [after 32000 "set x timed_out"]
	set counter 0







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

















|







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
    set cs [socket [info hostname] 2830]
    puts $cs hello
    close $cs
    vwait done
    after cancel $timer
    set done
} 1
test socket-2.11 {detecting new data} {socket} {
    proc accept {s a p} {
	global sock
	set sock $s
    }

    set s [socket -server accept 2400]
    set sock ""
    set s2 [socket 127.0.0.1 2400]
    vwait sock
    puts $s2 one
    flush $s2
    after 500
    fconfigure $sock -blocking 0
    set result [gets $sock]
    lappend result [gets $sock]
    fconfigure $sock -blocking 1
    puts $s2 two
    flush $s2
    fconfigure $sock -blocking 0
    lappend result [gets $sock]
    fconfigure $sock -blocking 1
    close $s2
    close $s
    close $sock
    set result
} {one {} two}


test socket-3.1 {socket conflict} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set f [socket -server accept 2828]
	puts ready
	gets stdin
	close $f
    }
    close $f
    set f [open "|[list $tcltest script]" r+]
    gets $f
    set x [list [catch {socket -server accept 2828} msg] \
		$msg]
    puts $f bye
    close $f
    set x
} {1 {couldn't open socket: address already in use}}
test socket-3.2 {server with several clients} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	set t1 [after 30000 "set x timed_out"]
	set t2 [after 31000 "set x timed_out"]
	set t3 [after 32000 "set x timed_out"]
	set counter 0
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
	after cancel $t3
	close $s
	puts $x
    }
    close $f
    set f [open "|[list $tcltest script]" r+]
    set x [gets $f]
    set s1 [socket localhost 2828]
    fconfigure $s1 -buffering line
    set s2 [socket localhost 2828]
    fconfigure $s2 -buffering line
    set s3 [socket localhost 2828]
    fconfigure $s3 -buffering line
    for {set i 0} {$i < 100} {incr i} {
	puts $s1 hello,s1
	gets $s1
	puts $s2 hello,s2
	gets $s2
	puts $s3 hello,s3
	gets $s3
    }
    close $s1
    close $s2
    close $s3
    lappend x [gets $f]
    close $f
    set x
} {ready done}

test socket-4.1 {server with several clients} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	gets stdin
	set s [socket localhost 2828]
	fconfigure $s -buffering line
	for {set i 0} {$i < 100} {incr i} {
	    puts $s hello
	    gets $s
	}
	close $s
	puts bye







|

|

|

















|




|







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
	after cancel $t3
	close $s
	puts $x
    }
    close $f
    set f [open "|[list $tcltest script]" r+]
    set x [gets $f]
    set s1 [socket 127.0.0.1 2828]
    fconfigure $s1 -buffering line
    set s2 [socket 127.0.0.1 2828]
    fconfigure $s2 -buffering line
    set s3 [socket 127.0.0.1 2828]
    fconfigure $s3 -buffering line
    for {set i 0} {$i < 100} {incr i} {
	puts $s1 hello,s1
	gets $s1
	puts $s2 hello,s2
	gets $s2
	puts $s3 hello,s3
	gets $s3
    }
    close $s1
    close $s2
    close $s3
    lappend x [gets $f]
    close $f
    set x
} {ready done}

test socket-4.1 {server with several clients} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	gets stdin
	set s [socket 127.0.0.1 2828]
	fconfigure $s -buffering line
	for {set i 0} {$i < 100} {incr i} {
	    puts $s hello
	    gets $s
	}
	close $s
	puts bye
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687

688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706

707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
    puts $p2 bye
    puts $p3 bye
    close $p1
    close $p2
    close $p3
    set l
} {{p1 bye done} {p2 bye done} {p3 bye done}}
test socket-4.2 {byte order problems, socket numbers, htons} {
    set x ok
    if {[catch {socket -server dodo 0x3000} msg]} {
	set x $msg
    } else {
	close $msg
    }
    set x
} ok

test socket-5.1 {byte order problems, socket numbers, htons} {unixOnly} {
    #
    # THIS TEST WILL FAIL if you are running as superuser.
    #

    set x {couldn't open socket: not owner}
    if {![catch {socket -server dodo 0x1} msg]} {
        set x {htons problem, should be disallowed, are you running as SU?}
	close $msg
    }
    set x
} {couldn't open socket: not owner}
test socket-5.2 {byte order problems, socket numbers, htons} {
    set x {couldn't open socket: port number too high}
    if {![catch {socket -server dodo 0x10000} msg]} {
	set x {port resolution problem, should be disallowed}
	close $msg
    }
    set x
} {couldn't open socket: port number too high}
test socket-5.3 {byte order problems, socket numbers, htons} {unixOnly} {
    #
    # THIS TEST WILL FAIL if you are running as superuser.
    #

    set x {couldn't open socket: not owner}
    if {![catch {socket -server dodo 21} msg]} {
	set x {htons problem, should be disallowed, are you running as SU?}
	close $msg
    }
    set x
} {couldn't open socket: not owner}

test socket-6.1 {accept callback error} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	gets stdin
	socket localhost 2848
    }
    close $f
    set f [open "|[list $tcltest script]" r+]
    proc bgerror args {
	global x
	set x $args
    }
    proc accept {s a p} {expr 10 / 0}
    set s [socket -server accept 2848]
    puts $f hello
    close $f
    set timer [after 10000 "set x timed_out"]
    vwait x
    after cancel $timer
    close $s
    rename bgerror {}
    set x
} {{divide by zero}}

test socket-7.1 {testing socket specific options} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	socket -server accept 2820
	proc accept args {
	    global x
	    set x done
	}
	puts ready
	set timer [after 10000 "set x timed_out"]
	vwait x
	after cancel $timer
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f
    set s [socket localhost 2820]
    set p [fconfigure $s -peername]
    close $s
    close $f
    set l ""
    lappend l [string compare [lindex $p 0] 127.0.0.1]
    lappend l [string compare [lindex $p 2] 2820]
    lappend l [llength $p]
} {0 0 3}
test socket-7.2 {testing socket specific options} {stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	socket -server accept 2821
	proc accept args {
	    global x
	    set x done
	}
	puts ready
	set timer [after 10000 "set x timed_out"]
	vwait x
	after cancel $timer
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f
    set s [socket localhost 2821]
    set p [fconfigure $s -sockname]
    close $s
    close $f
    set l ""
    lappend l [llength $p]
    lappend l [lindex $p 0]
    lappend l [expr [lindex $p 2] == 2821]
} {3 127.0.0.1 0}
test socket-7.3 {testing socket specific options} {
    set s [socket -server accept 2822]
    set l [fconfigure $s]
    close $s
    update
    llength $l
} 10
test socket-7.4 {testing socket specific options} {
    set s [socket -server accept 2823]
    proc accept {s a p} {
	global x
	set x [fconfigure $s -sockname]
	close $s
    }
    set s1 [socket [info hostname] 2823]
    set timer [after 10000 "set x timed_out"]
    vwait x
    after cancel $timer
    close $s
    close $s1
    set l ""
    lappend l [lindex $x 2] [llength $x]
} {2823 3}
test socket-7.5 {testing socket specific options} {unixOrPc} {
    set s [socket -server accept 2829]
    proc accept {s a p} {
	global x
	set x [fconfigure $s -sockname]
	close $s
    }
    set s1 [socket localhost 2829]
    set timer [after 10000 "set x timed_out"]
    vwait x
    after cancel $timer
    close $s
    close $s1
    set l ""
    lappend l [lindex $x 0] [lindex $x 2] [llength $x]
} {127.0.0.1 2829 3}

test socket-8.1 {testing -async flag on sockets} {
    # NOTE: This test may fail on some Solaris 2.4 systems. If it does,
    # check that you have these patches installed (using showrev -p):
    #
    # 101907-05, 101925-02, 101945-14, 101959-03, 101969-05, 101973-03,
    # 101977-03, 101981-02, 101985-01, 102001-03, 102003-01, 102007-01,
    # 102011-02, 102024-01, 102039-01, 102044-01, 102048-01, 102062-03,
    # 102066-04, 102070-01, 102105-01, 102153-03, 102216-01, 102232-01,







|









|
<
<
<
>







|







|
<
<
<
>








|




|



















|
















|








|
















|








|





|
|















|






|









|







699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716



717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733



734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
    puts $p2 bye
    puts $p3 bye
    close $p1
    close $p2
    close $p3
    set l
} {{p1 bye done} {p2 bye done} {p3 bye done}}
test socket-4.2 {byte order problems, socket numbers, htons} {socket} {
    set x ok
    if {[catch {socket -server dodo 0x3000} msg]} {
	set x $msg
    } else {
	close $msg
    }
    set x
} ok

test socket-5.1 {byte order problems, socket numbers, htons} \



	{socket unixOnly notRoot} {
    set x {couldn't open socket: not owner}
    if {![catch {socket -server dodo 0x1} msg]} {
        set x {htons problem, should be disallowed, are you running as SU?}
	close $msg
    }
    set x
} {couldn't open socket: not owner}
test socket-5.2 {byte order problems, socket numbers, htons} {socket} {
    set x {couldn't open socket: port number too high}
    if {![catch {socket -server dodo 0x10000} msg]} {
	set x {port resolution problem, should be disallowed}
	close $msg
    }
    set x
} {couldn't open socket: port number too high}
test socket-5.3 {byte order problems, socket numbers, htons} \



	{socket unixOnly notRoot} {
    set x {couldn't open socket: not owner}
    if {![catch {socket -server dodo 21} msg]} {
	set x {htons problem, should be disallowed, are you running as SU?}
	close $msg
    }
    set x
} {couldn't open socket: not owner}

test socket-6.1 {accept callback error} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	gets stdin
	socket 127.0.0.1 2848
    }
    close $f
    set f [open "|[list $tcltest script]" r+]
    proc bgerror args {
	global x
	set x $args
    }
    proc accept {s a p} {expr 10 / 0}
    set s [socket -server accept 2848]
    puts $f hello
    close $f
    set timer [after 10000 "set x timed_out"]
    vwait x
    after cancel $timer
    close $s
    rename bgerror {}
    set x
} {{divide by zero}}

test socket-7.1 {testing socket specific options} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	socket -server accept 2820
	proc accept args {
	    global x
	    set x done
	}
	puts ready
	set timer [after 10000 "set x timed_out"]
	vwait x
	after cancel $timer
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f
    set s [socket 127.0.0.1 2820]
    set p [fconfigure $s -peername]
    close $s
    close $f
    set l ""
    lappend l [string compare [lindex $p 0] 127.0.0.1]
    lappend l [string compare [lindex $p 2] 2820]
    lappend l [llength $p]
} {0 0 3}
test socket-7.2 {testing socket specific options} {socket stdio} {
    removeFile script
    set f [open script w]
    puts $f {
	socket -server accept 2821
	proc accept args {
	    global x
	    set x done
	}
	puts ready
	set timer [after 10000 "set x timed_out"]
	vwait x
	after cancel $timer
    }
    close $f
    set f [open "|[list $tcltest script]" r]
    gets $f
    set s [socket 127.0.0.1 2821]
    set p [fconfigure $s -sockname]
    close $s
    close $f
    set l ""
    lappend l [llength $p]
    lappend l [lindex $p 0]
    lappend l [expr [lindex $p 2] == 2821]
} {3 127.0.0.1 0}
test socket-7.3 {testing socket specific options} {socket} {
    set s [socket -server accept 2822]
    set l [fconfigure $s]
    close $s
    update
    llength $l
} 12
test socket-7.4 {testing socket specific options} {socket} {
    set s [socket -server accept 2823]
    proc accept {s a p} {
	global x
	set x [fconfigure $s -sockname]
	close $s
    }
    set s1 [socket [info hostname] 2823]
    set timer [after 10000 "set x timed_out"]
    vwait x
    after cancel $timer
    close $s
    close $s1
    set l ""
    lappend l [lindex $x 2] [llength $x]
} {2823 3}
test socket-7.5 {testing socket specific options} {socket unixOrPc} {
    set s [socket -server accept 2829]
    proc accept {s a p} {
	global x
	set x [fconfigure $s -sockname]
	close $s
    }
    set s1 [socket 127.0.0.1 2829]
    set timer [after 10000 "set x timed_out"]
    vwait x
    after cancel $timer
    close $s
    close $s1
    set l ""
    lappend l [lindex $x 0] [lindex $x 2] [llength $x]
} {127.0.0.1 2829 3}

test socket-8.1 {testing -async flag on sockets} {socket} {
    # NOTE: This test may fail on some Solaris 2.4 systems. If it does,
    # check that you have these patches installed (using showrev -p):
    #
    # 101907-05, 101925-02, 101945-14, 101959-03, 101969-05, 101973-03,
    # 101977-03, 101981-02, 101985-01, 102001-03, 102003-01, 102007-01,
    # 102011-02, 102024-01, 102039-01, 102044-01, 102048-01, 102062-03,
    # 102066-04, 102070-01, 102105-01, 102153-03, 102216-01, 102232-01,
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
    vwait x
    set z [gets $s1]
    close $s
    close $s1
    set z
} bye

test socket-9.1 {testing spurious events} {
    set len 0
    set spurious 0
    set done 0
    proc readlittle {s} {
	global spurious done len
	set l [read $s 1]
	if {[string length $l] == 0} {







|







883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
    vwait x
    set z [gets $s1]
    close $s
    close $s1
    set z
} bye

test socket-9.1 {testing spurious events} {socket} {
    set len 0
    set spurious 0
    set done 0
    proc readlittle {s} {
	global spurious done len
	set l [read $s 1]
	if {[string length $l] == 0} {
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
    close $c
    set timer [after 10000 "set done timed_out"]
    vwait done
    after cancel $timer
    close $s
    list $spurious $len
} {0 50}
test socket-9.2 {testing async write, fileevents, flush on close} {} {
    set firstblock ""
    for {set i 0} {$i < 5} {incr i} {set firstblock "a$firstblock$firstblock"}
    set secondblock ""
    for {set i 0} {$i < 16} {incr i} {
	set secondblock "b$secondblock$secondblock"
    }
    set l [socket -server accept 2832]







|







915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
    close $c
    set timer [after 10000 "set done timed_out"]
    vwait done
    after cancel $timer
    close $s
    list $spurious $len
} {0 50}
test socket-9.2 {testing async write, fileevents, flush on close} {socket} {
    set firstblock ""
    for {set i 0} {$i < 5} {incr i} {set firstblock "a$firstblock$firstblock"}
    set secondblock ""
    for {set i 0} {$i < 16} {incr i} {
	set secondblock "b$secondblock$secondblock"
    }
    set l [socket -server accept 2832]
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
    fileevent $s readable "readit $s"
    set timer [after 10000 "set done timed_out"]
    vwait done
    after cancel $timer
    close $l
    set count
} 65566
test socket-9.3 {testing EOF stickyness} {
    proc count_to_eof {s} {
	global count done timer
	set l [gets $s]
	if {[eof $s]} {
	    incr count
	    if {$count > 9} {
		close $s







|







963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
    fileevent $s readable "readit $s"
    set timer [after 10000 "set done timed_out"]
    vwait done
    after cancel $timer
    close $l
    set count
} 65566
test socket-9.3 {testing EOF stickyness} {socket} {
    proc count_to_eof {s} {
	global count done timer
	set l [gets $s]
	if {[eof $s]} {
	    incr count
	    if {$count > 9} {
		close $s
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
    vwait done
    close $s
    set count
} {eof is sticky}

removeFile script

#
# The rest of the tests are run only if we are doing testing against

# a remote server.
#

if {$doTestsWithRemoteServer == 0} {





    return
}

test socket-10.1 {tcp connection} {
    sendCommand {
	set socket9_1_test_server [socket -server accept 2834]
	proc accept {s a p} {
	    puts $s done
	    close $s
	}
    }
    set s [socket $remoteServerIP 2834]
    set r [gets $s]
    close $s
    sendCommand {close $socket9_1_test_server}
    set r
} done
test socket-10.2 {client specifies its port} {
    if {[info exists port]} {
	incr port
    } else {
	set port [expr 2048 + [pid]%1024]
    }
    sendCommand {
	set socket9_2_test_server [socket -server accept 2835]







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

|













|







1005
1006
1007
1008
1009
1010
1011


1012
1013

1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
    vwait done
    close $s
    set count
} {eof is sticky}

removeFile script



test socket-10.1 {testing socket accept callback error handling} {socket} {
    set goterror 0

    proc bgerror args {global goterror; set goterror 1}
    set s [socket -server accept 2898]
    proc accept {s a p} {close $s; error}
    set c [socket 127.0.0.1 2898]
    vwait goterror
    close $s
    close $c
    set goterror
} 1

test socket-11.1 {tcp connection} {socket doTestsWithRemoteServer} {
    sendCommand {
	set socket9_1_test_server [socket -server accept 2834]
	proc accept {s a p} {
	    puts $s done
	    close $s
	}
    }
    set s [socket $remoteServerIP 2834]
    set r [gets $s]
    close $s
    sendCommand {close $socket9_1_test_server}
    set r
} done
test socket-11.2 {client specifies its port} {socket doTestsWithRemoteServer} {
    if {[info exists port]} {
	incr port
    } else {
	set port [expr 2048 + [pid]%1024]
    }
    sendCommand {
	set socket9_2_test_server [socket -server accept 2835]
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
    if {$r == $port} {
	set result ok
    } else {
	set result broken
    }
    set result
} ok
#
# Tests io-10.3, io-10.4 have been removed.
#
test socket-10.3 {trying to connect, no server} {
    set status ok
    if {![catch {set s [socket $remoteServerIp 2836]}]} {
	if {![catch {gets $s}]} {
	    set status broken
	}
	close $s
    }
    set status
} ok
test socket-10.4 {remote echo, one line} {
    sendCommand {
	set socket10_6_test_server [socket -server accept 2836]
	proc accept {s a p} {
	    fileevent $s readable [list echo $s]
	    fconfigure $s -buffering line -translation crlf
	}
	proc echo {s} {







<
<
<
|









|







1055
1056
1057
1058
1059
1060
1061



1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
    if {$r == $port} {
	set result ok
    } else {
	set result broken
    }
    set result
} ok



test socket-11.3 {trying to connect, no server} {socket doTestsWithRemoteServer} {
    set status ok
    if {![catch {set s [socket $remoteServerIp 2836]}]} {
	if {![catch {gets $s}]} {
	    set status broken
	}
	close $s
    }
    set status
} ok
test socket-11.4 {remote echo, one line} {socket doTestsWithRemoteServer} {
    sendCommand {
	set socket10_6_test_server [socket -server accept 2836]
	proc accept {s a p} {
	    fileevent $s readable [list echo $s]
	    fconfigure $s -buffering line -translation crlf
	}
	proc echo {s} {
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
    fconfigure $f -translation crlf -buffering line
    puts $f hello
    set r [gets $f]
    close $f
    sendCommand {close $socket10_6_test_server}
    set r
} hello
test socket-10.5 {remote echo, 50 lines} {
    sendCommand {
	set socket10_7_test_server [socket -server accept 2836]
	proc accept {s a p} {
	    fileevent $s readable [list echo $s]
	    fconfigure $s -buffering line -translation crlf
	}
	proc echo {s} {







|







1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
    fconfigure $f -translation crlf -buffering line
    puts $f hello
    set r [gets $f]
    close $f
    sendCommand {close $socket10_6_test_server}
    set r
} hello
test socket-11.5 {remote echo, 50 lines} {socket doTestsWithRemoteServer} {
    sendCommand {
	set socket10_7_test_server [socket -server accept 2836]
	proc accept {s a p} {
	    fileevent $s readable [list echo $s]
	    fconfigure $s -buffering line -translation crlf
	}
	proc echo {s} {
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
} 50
# Macintosh sockets can have more than one server per port
if {$tcl_platform(platform) == "macintosh"} {
    set conflictResult {0 2836}
} else {
    set conflictResult {1 {couldn't open socket: address already in use}}
}
test socket-10.6 {socket conflict} {
    set s1 [socket -server accept 2836]
    if {[catch {set s2 [socket -server accept 2836]} msg]} {
	set result [list 1 $msg]
    } else {
	set result [list 0 [lindex [fconfigure $s2 -sockname] 2]]
	close $s2
    }
    close $s1
    set result
} $conflictResult
test socket-10.7 {server with several clients} {
    sendCommand {
	set socket10_9_test_server [socket -server accept 2836]
	proc accept {s a p} {
	    fconfigure $s -buffering line
	    fileevent $s readable [list echo $s]
	}
	proc echo {s} {







|










|







1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
} 50
# Macintosh sockets can have more than one server per port
if {$tcl_platform(platform) == "macintosh"} {
    set conflictResult {0 2836}
} else {
    set conflictResult {1 {couldn't open socket: address already in use}}
}
test socket-11.6 {socket conflict} {socket doTestsWithRemoteServer} {
    set s1 [socket -server accept 2836]
    if {[catch {set s2 [socket -server accept 2836]} msg]} {
	set result [list 1 $msg]
    } else {
	set result [list 0 [lindex [fconfigure $s2 -sockname] 2]]
	close $s2
    }
    close $s1
    set result
} $conflictResult
test socket-11.7 {server with several clients} {socket doTestsWithRemoteServer} {
    sendCommand {
	set socket10_9_test_server [socket -server accept 2836]
	proc accept {s a p} {
	    fconfigure $s -buffering line
	    fileevent $s readable [list echo $s]
	}
	proc echo {s} {
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
    }
    close $s1
    close $s2
    close $s3
    sendCommand {close $socket10_9_test_server}
    set i
} 100    
test socket-10.8 {client with several servers} {
    sendCommand {
	set s1 [socket -server "accept 4003" 4003]
	set s2 [socket -server "accept 4004" 4004]
	set s3 [socket -server "accept 4005" 4005]
	proc accept {mp s a p} {
	    puts $s $mp
	    close $s







|







1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
    }
    close $s1
    close $s2
    close $s3
    sendCommand {close $socket10_9_test_server}
    set i
} 100    
test socket-11.8 {client with several servers} {socket doTestsWithRemoteServer} {
    sendCommand {
	set s1 [socket -server "accept 4003" 4003]
	set s2 [socket -server "accept 4004" 4004]
	set s3 [socket -server "accept 4005" 4005]
	proc accept {mp s a p} {
	    puts $s $mp
	    close $s
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
    sendCommand {
	close $s1
	close $s2
	close $s3
    }
    set l
} {4003 {} 1 4004 {} 1 4005 {} 1}
test socket-10.9 {accept callback error} {
    set s [socket -server accept 2836]
    proc accept {s a p} {expr 10 / 0}
    proc bgerror args {
	global x
	set x $args
    }
    if {[catch {sendCommand {







|







1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
    sendCommand {
	close $s1
	close $s2
	close $s3
    }
    set l
} {4003 {} 1 4004 {} 1 4005 {} 1}
test socket-11.9 {accept callback error} {socket doTestsWithRemoteServer} {
    set s [socket -server accept 2836]
    proc accept {s a p} {expr 10 / 0}
    proc bgerror args {
	global x
	set x $args
    }
    if {[catch {sendCommand {
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
    set timer [after 10000 "set x timed_out"]
    vwait x
    after cancel $timer
    close $s
    rename bgerror {}
    set x
} {{divide by zero}}
test socket-10.10 {testing socket specific options} {
    sendCommand {
	set socket10_12_test_server [socket -server accept 2836]
	proc accept {s a p} {close $s}
    }
    set s [socket $remoteServerIP 2836]
    set p [fconfigure $s -peername]
    set n [fconfigure $s -sockname]
    set l ""
    lappend l [lindex $p 2] [llength $p] [llength $p]
    close $s
    sendCommand {close $socket10_12_test_server}
    set l
} {2836 3 3}
test socket-10.11 {testing spurious events} {
    sendCommand {
	set socket10_13_test_server [socket -server accept 2836]
	proc accept {s a p} {
	    fconfigure $s -translation "auto lf"
	    after 100 writesome $s
	}
	proc writesome {s} {







|













|







1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
    set timer [after 10000 "set x timed_out"]
    vwait x
    after cancel $timer
    close $s
    rename bgerror {}
    set x
} {{divide by zero}}
test socket-11.10 {testing socket specific options} {socket doTestsWithRemoteServer} {
    sendCommand {
	set socket10_12_test_server [socket -server accept 2836]
	proc accept {s a p} {close $s}
    }
    set s [socket $remoteServerIP 2836]
    set p [fconfigure $s -peername]
    set n [fconfigure $s -sockname]
    set l ""
    lappend l [lindex $p 2] [llength $p] [llength $p]
    close $s
    sendCommand {close $socket10_12_test_server}
    set l
} {2836 3 3}
test socket-11.11 {testing spurious events} {socket doTestsWithRemoteServer} {
    sendCommand {
	set socket10_13_test_server [socket -server accept 2836]
	proc accept {s a p} {
	    fconfigure $s -translation "auto lf"
	    after 100 writesome $s
	}
	proc writesome {s} {
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
    fileevent $c readable "readlittle $c"
    set timer [after 10000 "set done timed_out"]
    vwait done
    after cancel $timer
    sendCommand {close $socket10_13_test_server}
    list $spurious $len
} {0 2690}
test socket-10.12 {testing EOF stickyness} {
    set counter 0
    set done 0
    proc count_up {s} {
	global counter done after_id
	set l [gets $s]
	if {[eof $s]} {
	    incr counter







|







1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
    fileevent $c readable "readlittle $c"
    set timer [after 10000 "set done timed_out"]
    vwait done
    after cancel $timer
    sendCommand {close $socket10_13_test_server}
    list $spurious $len
} {0 2690}
test socket-11.12 {testing EOF stickyness} {socket doTestsWithRemoteServer} {
    set counter 0
    set done 0
    proc count_up {s} {
	global counter done after_id
	set l [gets $s]
	if {[eof $s]} {
	    incr counter
1276
1277
1278
1279
1280
1281
1282
1283

1284
1285
1286
1287
1288
1289
1290
    set c [socket $remoteServerIP 2836]
    fileevent $c readable "count_up $c"
    set after_id [after 1000 timed_out]
    vwait done
    sendCommand {close $socket10_14_test_server}
    set done
} {EOF is sticky}
test socket-10.13 {testing async write, async flush, async close} {

    proc readit {s} {
	global count done
	set l [read $s]
	incr count [string length $l]
	if {[eof $s]} {
	    close $s
	    set done 1







|
>







1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
    set c [socket $remoteServerIP 2836]
    fileevent $c readable "count_up $c"
    set after_id [after 1000 timed_out]
    vwait done
    sendCommand {close $socket10_14_test_server}
    set done
} {EOF is sticky}
test socket-11.13 {testing async write, async flush, async close} \
	{socket doTestsWithRemoteServer} {
    proc readit {s} {
	global count done
	set l [read $s]
	incr count [string length $l]
	if {[eof $s]} {
	    close $s
	    set done 1
1329
1330
1331
1332
1333
1334
1335





























































































































































































































































































1336
1337
1338
1339
1340
1341



1342
1343
1344








    set timer [after 10000 "set done timed_out"]
    vwait done
    after cancel $timer
    sendCommand {close $l}
    set count
} 65566






























































































































































































































































































if {[string match sock* $commandSocket] == 1} {
   puts $commandSocket exit
   flush $commandSocket
}
catch {close $commandSocket}
catch {close $remoteProcChan}




set x ""
unset x















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






>
>
>

|
|
>
>
>
>
>
>
>
>
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
    set timer [after 10000 "set done timed_out"]
    vwait done
    after cancel $timer
    sendCommand {close $l}
    set count
} 65566

test socket-12.1 {testing inheritance of server sockets} \
	{socket doTestsWithRemoteServer} {
    removeFile script1
    removeFile script2

    # Script1 is just a 10 second delay.  If the server socket
    # is inherited, it will be held open for 10 seconds

    set f [open script1 w]
    puts $f {
	after 10000 exit
	vwait forever
    }
    close $f

    # Script2 creates the server socket, launches script1,
    # waits a second, and exits.  The server socket will now
    # be closed unless script1 inherited it.

    set f [open script2 w]
    puts $f [list set tcltest $tcltest]
    puts $f {
	set f [socket -server accept 2828]
	proc accept { file addr port } {
	    close $file
	}
	exec $tcltest script1 &
	close $f
	after 1000 exit
	vwait forever
    }
    close $f
	
    # Launch script2 and wait 5 seconds

    exec $tcltest script2 &
    after 5000 { set ok_to_proceed 1 }
    vwait ok_to_proceed

    # If we can still connect to the server, the socket got inherited.

    if {[catch {socket 127.0.0.1 2828} msg]} {
	set x {server socket was not inherited}
    } else {
	close $msg
	set x {server socket was inherited}
    }

    removeFile script1
    removeFile script2
    set x
} {server socket was not inherited}
test socket-12.2 {testing inheritance of client sockets} \
	{socket doTestsWithRemoteServer} {
    removeFile script1
    removeFile script2

    # Script1 is just a 10 second delay.  If the server socket
    # is inherited, it will be held open for 10 seconds

    set f [open script1 w]
    puts $f {
	after 10000 exit
	vwait forever
    }
    close $f

    # Script2 opens the client socket and writes to it.  It then
    # launches script1 and exits.  If the child process inherited the
    # client socket, the socket will still be open.

    set f [open script2 w]
    puts $f [list set tcltest $tcltest]
    puts $f {
	set f [socket 127.0.0.1 2829]
	exec $tcltest script1 &
	puts $f testing
	flush $f
	after 1000 exit
	vwait forever
    }
    close $f

    # Create the server socket

    set server [socket -server accept 2829]
    proc accept { file host port } {

	# When the client connects, establish the read handler
	global server
	close $server
	fileevent $file readable [list getdata $file]
	fconfigure $file -buffering line -blocking 0
	return
    }
    proc getdata { file } {

	# Read handler on the accepted socket.
	global x
	global failed
	set status [catch {read $file} data]
	if {$status != 0} {
	    set x {read failed, error was $data}
	    catch { close $file }
	} elseif {[string compare {} $data]} {
	} elseif {[fblocked $file]} {
	} elseif {[eof $file]} {
	    if {$failed} {
		set x {client socket was inherited}
	    } else {
		set x {client socket was not inherited}
	    }
	    catch { close $file }
	} else {
	    set x {impossible case}
	    catch { close $file }
	}
	return
    }

    # If the socket doesn't hit end-of-file in 5 seconds, the
    # script1 process must have inherited the client.

    set failed 0
    after 5000 [list set failed 1]

    # Launch the script2 process

    exec $tcltest script2 &

    vwait x
    if {!$failed} {
	vwait failed
    }
    removeFile script1
    removeFile script2
    set x
} {client socket was not inherited}
test socket-12.3 {testing inheritance of accepted sockets} \
	{socket doTestsWithRemoteServer} {
    removeFile script1
    removeFile script2

    set f [open script1 w]
    puts $f {
	after 10000 exit
	vwait forever
    }
    close $f

    set f [open script2 w]
    puts $f [list set tcltest $tcltest]
    puts $f {
	set server [socket -server accept 2930]
	proc accept { file host port } {
	    global tcltest
	    puts $file {test data on socket}
	    exec $tcltest script1 &
	    after 1000 exit
	}
	vwait forever
    }
    close $f

    # Launch the script2 process and connect to it.  See how long
    # the socket stays open

    exec $tcltest script2 &

    after 1000 set ok_to_proceed 1
    vwait ok_to_proceed

    set f [socket 127.0.0.1 2930]
    fconfigure $f -buffering full -blocking 0
    fileevent $f readable [list getdata $f]

    # If the socket is still open after 5 seconds, the script1 process
    # must have inherited the accepted socket.

    set failed 0
    after 5000 set failed 1

    proc getdata { file } {

	# Read handler on the client socket.
	global x
	global failed
	set status [catch {read $file} data]
	if {$status != 0} {
	    set x {read failed, error was $data}
	    catch { close $file }
	} elseif {[string compare {} $data]} {
	} elseif {[fblocked $file]} {
	} elseif {[eof $file]} {
	    if {$failed} {
		set x {accepted socket was inherited}
	    } else {
		set x {accepted socket was not inherited}
	    }
	    catch { close $file }
	} else {
	    set x {impossible case}
	    catch { close $file }
	}
	return
    }
    
    vwait x

    removeFile script1
    removeFile script2
    set x
} {accepted socket was not inherited}

test socket-13.1 {Testing use of shared socket between two threads} \
	{socket testthread} {

    set mainthread [testthread names]
    proc ThreadReap {} {
	global mainthread
	testthread errorproc ThreadNullError
	while {[llength [testthread names]] > 1} {
	    foreach tid [testthread names] {
		if {$tid != $mainthread} {
		    catch {testthread send -async $tid {testthread exit}}
		    update
		}
	    }
	}
	testthread errorproc ThreadError
	return [llength [testthread names]]
    }

    removeFile script

    set f [open script w]
    puts $f {
	set f [socket -server accept 2828]
	proc accept {s a p} {
            fileevent $s readable [list echo $s]
            fconfigure $s -buffering line
        }
	proc echo {s} {
	     global i
             set l [gets $s]
             if {[eof $s]} {
                 global x
                 close $s
                 set x done
             } else { 
	         incr i
                 puts $s $l
             }
	}
	set i 0
	vwait x
	close $f

	# thread cleans itself up.
	testthread exit
    }
    close $f
    
    # create a thread
    set serverthread [testthread create { source script } ]
    update
    

    set s [socket 127.0.0.1 2828]
    fconfigure $s -buffering line
    catch {
	puts $s "hello"
	gets $s result
    }
    close $s
    update

    after 2000
    ThreadReap
    
    set result

} hello

# cleanup
if {[string match sock* $commandSocket] == 1} {
   puts $commandSocket exit
   flush $commandSocket
}
catch {close $commandSocket}
catch {close $remoteProcChan}
::tcltest::cleanupTests
flush stdout
return











Changes to tests/source.test.

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
# Commands covered:  source
#
# 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-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) source.test 1.26 97/09/24 16:33:37



if {[string compare test [info procs test]] == 1} then {source defs}

test source-1.1 {source command} {
    set x "old x value"
    set y "old y value"
    set z "old z value"
    makeFile {
	set x 22
	set y 33
	set z 44
    } source.file
    source source.file
    list $x $y $z
} {22 33 44}
test source-1.2 {source command} {
    makeFile {list result} source.file
    source source.file
} result

# The mac version of source returns a different result for
# the next two tests.


if {$tcl_platform(platform) == "macintosh"} {
    set retMsg1 {1 {wrong # args: should be "source fileName" or "source -rsrc name ?fileName?" or "source -rsrcid id ?fileName?"}}
    set retMsg2 {1 {bad argument: should be "source fileName" or "source -rsrc name ?fileName?" or "source -rsrcid id ?fileName?"}}

} else {
    set retMsg1 {1 {wrong # args: should be "source fileName"}}
    set retMsg2 {1 {wrong # args: should be "source fileName"}}
}
test source-2.1 {source error conditions} {
    list [catch {source} msg] $msg
} $retMsg1
test source-2.2 {source error conditions} {
    list [catch {source a b} msg] $msg
} $retMsg2
test source-2.3 {source error conditions} {
    makeFile {
	set x 146
	error "error in sourced file"
	set y $x
    } source.file
    list [catch {source source.file} msg] $msg $errorInfo








>




>
|
>
>
|
<

















|
<
|

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







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
# Commands covered:  source
#
# 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-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: source.test,v 1.1.2.5 1999/03/24 02:49:41 hershey Exp $

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


test source-1.1 {source command} {
    set x "old x value"
    set y "old y value"
    set z "old z value"
    makeFile {
	set x 22
	set y 33
	set z 44
    } source.file
    source source.file
    list $x $y $z
} {22 33 44}
test source-1.2 {source command} {
    makeFile {list result} source.file
    source source.file
} result
test source-1.3 {source command} {

    set y {\ }

    set fd [open source.file w]
    fconfigure $fd -translation lf
    puts -nonewline $fd "list a b c "
    puts $fd [string index $y 0]
    puts $fd "d e f"
    close $fd




    source source.file
} {a b c d e f}



test source-2.3 {source error conditions} {
    makeFile {
	set x 146
	error "error in sourced file"
	set y $x
    } source.file
    list [catch {source source.file} msg] $msg $errorInfo
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
    list [catch {source -rsrc _no_exist_} msg] $msg
} [list 1 "The resource \"_no_exist_\" could not be loaded from application."]
test source-4.2 {source error conditions} {macOnly} {
    list [catch {source -rsrcid bad_id} msg] $msg
} [list 1 "expected integer but got \"bad_id\""]
test source-4.3 {source error conditions} {macOnly} {
    list [catch {source -rsrc rsrcName fileName extra} msg] $msg
} $retMsg1
test source-4.4 {source error conditions} {macOnly} {
    list [catch {source non_switch rsrcName} msg] $msg
} $retMsg2
test source-4.5 {source error conditions} {macOnly} {
    list [catch {source -bad_switch argument} msg] $msg
} $retMsg2
test source-5.1 {source resource files} {macOnly} {
    list [catch {source -rsrc rsrcName bad_file} msg] $msg
} [list 1 "Error finding the file: \"bad_file\"."]
test source-5.2 {source resource files} {macOnly} {
    makeFile {return} source.file
    list [catch {source -rsrc rsrcName source.file} msg] $msg
} [list 1 "Error reading the file: \"source.file\"."]







|


|


|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    list [catch {source -rsrc _no_exist_} msg] $msg
} [list 1 "The resource \"_no_exist_\" could not be loaded from application."]
test source-4.2 {source error conditions} {macOnly} {
    list [catch {source -rsrcid bad_id} msg] $msg
} [list 1 "expected integer but got \"bad_id\""]
test source-4.3 {source error conditions} {macOnly} {
    list [catch {source -rsrc rsrcName fileName extra} msg] $msg
} {1 {wrong # args: should be "source fileName" or "source -rsrc name ?fileName?" or "source -rsrcid id ?fileName?"}}
test source-4.4 {source error conditions} {macOnly} {
    list [catch {source non_switch rsrcName} msg] $msg
} {1 {bad argument: should be "source fileName" or "source -rsrc name ?fileName?" or "source -rsrcid id ?fileName?"}}
test source-4.5 {source error conditions} {macOnly} {
    list [catch {source -bad_switch argument} msg] $msg
} {1 {bad argument: should be "source fileName" or "source -rsrc name ?fileName?" or "source -rsrcid id ?fileName?"}}
test source-5.1 {source resource files} {macOnly} {
    list [catch {source -rsrc rsrcName bad_file} msg] $msg
} [list 1 "Error finding the file: \"bad_file\"."]
test source-5.2 {source resource files} {macOnly} {
    makeFile {return} source.file
    list [catch {source -rsrc rsrcName source.file} msg] $msg
} [list 1 "Error reading the file: \"source.file\"."]
176
177
178
179
180
181
182

183


184
185
186
187








test source-6.1 {source is binary ok} {
    set x {}
    makeFile [list set x "a b\0c"] source.file
    source source.file
    string length $x
} 5


catch {removeFile source.file}



# Generate null final value

concat {}















>
|
>
>

|

|
>
>
>
>
>
>
>
>
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
test source-6.1 {source is binary ok} {
    set x {}
    makeFile [list set x "a b\0c"] source.file
    source source.file
    string length $x
} 5

# cleanup
catch {::tcltest::removeFile source.file}
::tcltest::cleanupTests
return












Changes to tests/split.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  split
#
# 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-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) split.test 1.10 97/07/07 16:30:07



if {[string compare test [info procs test]] == 1} then {source defs}

test split-1.1 {basic split commands} {
    split "a\n b\t\r c\n "
} {a {} b {} {} c {} {}}
test split-1.2 {basic split commands} {
    split "word 1xyzword 2zword 3" xyz
} {{word 1} {} {} {word 2} {word 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
# Commands covered:  split
#
# 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-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: split.test,v 1.1.2.4 1999/03/24 02:49:42 hershey Exp $

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


test split-1.1 {basic split commands} {
    split "a\n b\t\r c\n "
} {a {} b {} {} c {} {}}
test split-1.2 {basic split commands} {
    split "word 1xyzword 2zword 3" xyz
} {{word 1} {} {} {word 2} {word 3}}
59
60
61
62
63
64
65

















test split-2.1 {split errors} {
    list [catch split msg] $msg $errorCode
} {1 {wrong # args: should be "split string ?splitChars?"} NONE}
test split-2.2 {split errors} {
    list [catch {split a b c} msg] $msg $errorCode
} {1 {wrong # args: should be "split string ?splitChars?"} NONE}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

test split-2.1 {split errors} {
    list [catch split msg] $msg $errorCode
} {1 {wrong # args: should be "split string ?splitChars?"} NONE}
test split-2.2 {split errors} {
    list [catch {split a b c} msg] $msg $errorCode
} {1 {wrong # args: should be "split string ?splitChars?"} NONE}

# cleanup
::tcltest::cleanupTests
return












Added tests/stack.test.



















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# Tests that the stack size is big enough for the application.
#
# 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) 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: stack.test,v 1.1.2.3 1999/03/24 02:49:42 hershey Exp $

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

# Note that a failure in this test results in a crash of the executable.

test stack-1.1 {maxNestingDepth reached on infinite recursion} {
    proc recurse {} { return [recurse] }
    catch {recurse} rv
    rename recurse {}
    set rv
} {too many nested calls to Tcl_EvalObj (infinite loop?)}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/string.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  string
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) string.test 1.15 97/07/02 16:49:27



if {[string compare test [info procs test]] == 1} then {source defs}

test string-1.1 {string compare} {
    string compare abcde abdef
} -1
test string-1.2 {string compare} {
    string c abcde ABCDE
} 1








>




>
|
>
>
|
<







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
# Commands covered:  string
#
# 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: string.test,v 1.1.2.5 1999/03/24 02:49:43 hershey Exp $

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


test string-1.1 {string compare} {
    string compare abcde abdef
} -1
test string-1.2 {string compare} {
    string c abcde ABCDE
} 1
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    string trimright ""
} {}
test string-10.4 {string trimright errors} {
    list [catch {string trimright} msg] $msg
} {1 {wrong # args: should be "string trimright string ?chars?"}}
test string-10.5 {string trimright errors} {
    list [catch {string trimg a} msg] $msg
} {1 {bad option "trimg": must be compare, first, index, last, length, match, range, tolower, toupper, trim, trimleft, trimright, wordend, or wordstart}}

test string-11.1 {string tolower} {
    string tolower ABCDeF
} {abcdef}
test string-11.2 {string tolower} {
    string tolower "ABC  XyZ"
} {abc  xyz}







|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
    string trimright ""
} {}
test string-10.4 {string trimright errors} {
    list [catch {string trimright} msg] $msg
} {1 {wrong # args: should be "string trimright string ?chars?"}}
test string-10.5 {string trimright errors} {
    list [catch {string trimg a} msg] $msg
} {1 {bad option "trimg": must be compare, first, index, last, length, match, range, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}

test string-11.1 {string tolower} {
    string tolower ABCDeF
} {abcdef}
test string-11.2 {string tolower} {
    string tolower "ABC  XyZ"
} {abc  xyz}
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
} 6
test string-13.8 {string wordend} {
    string worde "x.y" 0
} 1

test string-14.1 {string wordstart} {
    list [catch {string word a} msg] $msg
} {1 {ambiguous option "word": must be compare, first, index, last, length, match, range, tolower, toupper, trim, trimleft, trimright, wordend, or wordstart}}
test string-14.2 {string wordstart} {
    list [catch {string wordstart a} msg] $msg
} {1 {wrong # args: should be "string wordstart string index"}}
test string-14.3 {string wordstart} {
    list [catch {string wordstart a b c} msg] $msg
} {1 {wrong # args: should be "string wordstart string index"}}
test string-14.4 {string wordstart} {







|







349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
} 6
test string-13.8 {string wordend} {
    string worde "x.y" 0
} 1

test string-14.1 {string wordstart} {
    list [catch {string word a} msg] $msg
} {1 {ambiguous option "word": must be compare, first, index, last, length, match, range, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
test string-14.2 {string wordstart} {
    list [catch {string wordstart a} msg] $msg
} {1 {wrong # args: should be "string wordstart string index"}}
test string-14.3 {string wordstart} {
    list [catch {string wordstart a b c} msg] $msg
} {1 {wrong # args: should be "string wordstart string index"}}
test string-14.4 {string wordstart} {
374
375
376
377
378
379
380
381
382
383
384
















} 6
test string-14.9 {string wordend} {
    string wordstart "one two three" 4
} 4

test string-15.1 {error conditions} {
    list [catch {string gorp a b} msg] $msg
} {1 {bad option "gorp": must be compare, first, index, last, length, match, range, tolower, toupper, trim, trimleft, trimright, wordend, or wordstart}}
test string-15.2 {error conditions} {
    list [catch {string} msg] $msg
} {1 {wrong # args: should be "string option arg ?arg ...?"}}























|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
} 6
test string-14.9 {string wordend} {
    string wordstart "one two three" 4
} 4

test string-15.1 {error conditions} {
    list [catch {string gorp a b} msg] $msg
} {1 {bad option "gorp": must be compare, first, index, last, length, match, range, tolower, toupper, totitle, trim, trimleft, trimright, wordend, or wordstart}}
test string-15.2 {error conditions} {
    list [catch {string} msg] $msg
} {1 {wrong # args: should be "string option arg ?arg ...?"}}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/stringObj.test.

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
# Commands covered: none
#
# This file contains tests for the procedures in tclStringObj.c
# that implement the Tcl type manager for the string type.
#
# Sourcing this file into Tcl runs the tests and generates output for
# errors. No output means no errors were found.
#
# 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.
#

# @(#) stringObj.test 1.8 97/04/09 11:29:37




if {[info commands testobj] == {}} {
    puts "This application hasn't been compiled with the \"testobj\""
    puts "command, so I can't test the Tcl type and object support."

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

test stringObj-1.1 {string type registration} {
    set t [testobj types]
    set first [string first "string" $t]
    set result [expr {$first != -1}]
} {1}

test stringObj-2.1 {Tcl_NewStringObj} {









>




>
|
>
>
>




>



<
<







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
# Commands covered: none
#
# This file contains tests for the procedures in tclStringObj.c
# that implement the Tcl type manager for the string type.
#
# Sourcing this file into Tcl runs the tests and generates output for
# errors. No output means no errors were found.
#
# Copyright (c) 1995-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: stringObj.test,v 1.1.2.6 1999/03/26 19:14:06 hershey Exp $

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

if {[info commands testobj] == {}} {
    puts "This application hasn't been compiled with the \"testobj\""
    puts "command, so I can't test the Tcl type and object support."
    ::tcltest::cleanupTests
    return
}



test stringObj-1.1 {string type registration} {
    set t [testobj types]
    set first [string first "string" $t]
    set result [expr {$first != -1}]
} {1}

test stringObj-2.1 {Tcl_NewStringObj} {
183
184
185
186
187
188
189
















    testobj duplicate 1 2
    list [teststringobj length 1] [teststringobj length2 1] \
	    [teststringobj length 2] [teststringobj length2 2] \
	    [teststringobj get 2]
} {5 10 5 5 abcde}

testobj freeallvars























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    testobj duplicate 1 2
    list [teststringobj length 1] [teststringobj length2 1] \
	    [teststringobj length 2] [teststringobj length2 2] \
	    [teststringobj get 2]
} {5 10 5 5 abcde}

testobj freeallvars

# cleanup
::tcltest::cleanupTests
return












Changes to tests/subst.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  subst
#
# 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) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) subst.test 1.8 97/06/23 18:20:15



if {[string compare test [info procs test]] == 1} then {source defs}

test subst-1.1 {basics} {
    list [catch {subst} msg] $msg
} {1 {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}}
test subst-1.2 {basics} {
    list [catch {subst a b c} msg] $msg
} {1 {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}}








>




>
|
>
>
|
<







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
# Commands covered:  subst
#
# 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) 1994 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: subst.test,v 1.1.2.5 1999/03/24 02:49:44 hershey Exp $

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


test subst-1.1 {basics} {
    list [catch {subst} msg] $msg
} {1 {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}}
test subst-1.2 {basics} {
    list [catch {subst a b c} msg] $msg
} {1 {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}}
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
















} {1 {can't read "a": no such variable}}

test subst-7.1 {switches} {
    list [catch {subst foo bar} msg] $msg
} {1 {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}}
test subst-7.2 {switches} {
    list [catch {subst -no bar} msg] $msg
} {1 {bad switch "-no": must be -nobackslashes, -nocommands, or -novariables}}
test subst-7.3 {switches} {
    list [catch {subst -bogus bar} msg] $msg
} {1 {bad switch "-bogus": must be -nobackslashes, -nocommands, or -novariables}}
test subst-7.4 {switches} {
    set x 123
    subst -nobackslashes {abc $x [expr 1+2] \\\x41}
} {abc 123 3 \\\x41}
test subst-7.5 {switches} {
    set x 123
    subst -nocommands {abc $x [expr 1+2] \\\x41}
} {abc 123 [expr 1+2] \A}
test subst-7.6 {switches} {
    set x 123
    subst -novariables {abc $x [expr 1+2] \\\x41}
} {abc $x 3 \A}
test subst-7.7 {switches} {
    set x 123
    subst -nov -nob -noc {abc $x [expr 1+2] \\\x41}
} {abc $x [expr 1+2] \\\x41}























|



















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
} {1 {can't read "a": no such variable}}

test subst-7.1 {switches} {
    list [catch {subst foo bar} msg] $msg
} {1 {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}}
test subst-7.2 {switches} {
    list [catch {subst -no bar} msg] $msg
} {1 {ambiguous switch "-no": must be -nobackslashes, -nocommands, or -novariables}}
test subst-7.3 {switches} {
    list [catch {subst -bogus bar} msg] $msg
} {1 {bad switch "-bogus": must be -nobackslashes, -nocommands, or -novariables}}
test subst-7.4 {switches} {
    set x 123
    subst -nobackslashes {abc $x [expr 1+2] \\\x41}
} {abc 123 3 \\\x41}
test subst-7.5 {switches} {
    set x 123
    subst -nocommands {abc $x [expr 1+2] \\\x41}
} {abc 123 [expr 1+2] \A}
test subst-7.6 {switches} {
    set x 123
    subst -novariables {abc $x [expr 1+2] \\\x41}
} {abc $x 3 \A}
test subst-7.7 {switches} {
    set x 123
    subst -nov -nob -noc {abc $x [expr 1+2] \\\x41}
} {abc $x [expr 1+2] \\\x41}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/switch.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  switch
#
# 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) 1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) switch.test 1.7 97/02/10 17:27:13



if {[string compare test [info procs test]] == 1} then {source defs}

test switch-1.1 {simple patterns} {
    switch a a {format 1} b {format 2} c {format 3} default {format 4}
} 1
test switch-1.2 {simple patterns} {
    switch b a {format 1} b {format 2} c {format 3} default {format 4}
} 2








>




>
|
>
>
|
<







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
# Commands covered:  switch
#
# 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) 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: switch.test,v 1.1.2.6 1999/03/24 02:49:44 hershey Exp $

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


test switch-1.1 {simple patterns} {
    switch a a {format 1} b {format 2} c {format 3} default {format 4}
} 1
test switch-1.2 {simple patterns} {
    switch b a {format 1} b {format 2} c {format 3} default {format 4}
} 2
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
	^a*b$	{concat regexp}
	*b	{concat glob}
	aaaab	{concat exact}
	default	{concat none}
    }
} exact
test switch-3.2 {-exact vs. -glob vs. -regexp} {
    switch -exact -regexp aaaab {
	^a*b$	{concat regexp}
	*b	{concat glob}
	aaaab	{concat exact}
	default	{concat none}
    }
} regexp
test switch-3.3 {-exact vs. -glob vs. -regexp} {







|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
	^a*b$	{concat regexp}
	*b	{concat glob}
	aaaab	{concat exact}
	default	{concat none}
    }
} exact
test switch-3.2 {-exact vs. -glob vs. -regexp} {
    switch -regexp aaaab {
	^a*b$	{concat regexp}
	*b	{concat glob}
	aaaab	{concat exact}
	default	{concat none}
    }
} regexp
test switch-3.3 {-exact vs. -glob vs. -regexp} {
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

test switch-5.1 {errors in -regexp matching} {
    list [catch {switch -regexp aaaab {
	*b	{concat glob}
	aaaab	{concat exact}
	default	{concat none}
    }} msg] $msg
} {1 {couldn't compile regular expression pattern: ?+* follows nothing}}

test switch-6.1 {backslashes in patterns} {
    switch -exact {\a\$\.\[} {
	\a\$\.\[	{concat first}
	\a\\$\.\\[	{concat second}
	\\a\\$\\.\\[	{concat third}
	{\a\\$\.\\[}	{concat fourth}







|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

test switch-5.1 {errors in -regexp matching} {
    list [catch {switch -regexp aaaab {
	*b	{concat glob}
	aaaab	{concat exact}
	default	{concat none}
    }} msg] $msg
} {1 {couldn't compile regular expression pattern: quantifier operand invalid}}

test switch-6.1 {backslashes in patterns} {
    switch -exact {\a\$\.\[} {
	\a\$\.\[	{concat first}
	\a\\$\.\\[	{concat second}
	\\a\\$\\.\\[	{concat third}
	{\a\\$\.\\[}	{concat fourth}
173
174
175
176
177
178
179
















    set msg {}
    switch {2} {
    	1 {set msg 1}
        2 {}
        default {set msg 2}
    }
} {}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    set msg {}
    switch {2} {
    	1 {set msg 1}
        2 {}
        default {set msg 2}
    }
} {}

# cleanup
::tcltest::cleanupTests
return












Added tests/thread.test.

































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# Commands covered:  (test)thread
#
# 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) 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: thread.test,v 1.1.2.6 1999/04/01 23:22:32 welch Exp $

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

if {[info command testthread] == ""} {
    puts "skipping: tests require the testthread command"
    ::tcltest::cleanupTests
    return
}

set mainthread [testthread names]
proc ThreadReap {} {
    global mainthread
    testthread errorproc ThreadNullError
    while {[llength [testthread names]] > 1} {
	foreach tid [testthread names] {
	    if {$tid != $mainthread} {
		catch {testthread send -async $tid {testthread exit}}
		update
	    }
	}
    }
    testthread errorproc ThreadError
    return [llength [testthread names]]
}
testthread errorproc ThreadError
proc ThreadError {id info} {
    global threadError
    set threadError $info
}
proc ThreadNullError {id info} {
    # ignore
}

test thread-1.1 {Tcl_ThreadObjCmd: no args} {
    list [catch {testthread} msg] $msg
} {1 {wrong # args: should be "testthread option ?args?"}}

test thread-1.2 {Tcl_ThreadObjCmd: bad option} {
    list [catch {testthread foo} msg] $msg
} {1 {bad option "foo": must be create, exit, id, names, send, wait, or errorproc}}

test thread-1.3 {Tcl_ThreadObjCmd: initial thread list} {
    list [catch {testthread names} mainthread] [llength $mainthread]
} {0 1}

test thread-1.4 {Tcl_ThreadObjCmd: thread create } {
    set serverthread [testthread create]
    update
    set numthreads [llength [testthread names]]
} {2}
ThreadReap

test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {
    testthread create {set x 5}
    foreach try {0 1 2 4 5 6} {
	# Try various ways to yeild
	update
	after 10
	set l [llength [testthread names]]
	if {$l == 1} {
	    break
	}
    }
    set l
} {1}
ThreadReap

test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {
    testthread create {testthread exit}
    update
    after 10
    llength [testthread names]
} {1}
ThreadReap

test thread-1.7 {Tcl_ThreadObjCmd: thread id args} {
    set x [catch {testthread id x} msg]
    list $x $msg
} {1 {wrong # args: should be "testthread id"}}

test thread-1.8 {Tcl_ThreadObjCmd: thread id} {
    string compare [testthread id] $mainthread
} {0}

test thread-1.9 {Tcl_ThreadObjCmd: thread names args} {
    set x [catch {testthread names x} msg]
    list $x $msg
} {1 {wrong # args: should be "testthread names"}}

test thread-1.10 {Tcl_ThreadObjCmd: thread id} {
    string compare [testthread names] $mainthread
} {0}

test thread-1.11 {Tcl_ThreadObjCmd: send args} {
    set x [catch {testthread send} msg]
    list $x $msg
} {1 {wrong # args: should be "testthread send ?-async? id script"}}

test thread-1.12 {Tcl_ThreadObjCmd: send nonint} {
    set x [catch {testthread send abc command} msg]
    list $x $msg
} {1 {expected integer but got "abc"}}

test thread-1.13 {Tcl_ThreadObjCmd: send args} {
    set serverthread [testthread create]
    set five [testthread send $serverthread {set x 5}]
    ThreadReap
    set five
} 5

test thread-1.14 {Tcl_ThreadObjCmd: send bad id} {
    set tid [expr $mainthread + 10]
    set x [catch {testthread send $tid {set x 5}} msg]
    list $x $msg
} {1 {invalid thread id}}

test thread-1.15 {Tcl_ThreadObjCmd: wait} {
    set serverthread [testthread create {set z 5 ; testthread wait}]
    set five [testthread send $serverthread {set z}]
    ThreadReap
    set five
} 5

test thread-1.16 {Tcl_ThreadObjCmd: errorproc args} {
    set x [catch {testthread errorproc foo bar} msg]
    list $x $msg
} {1 {wrong # args: should be "testthread errorproc proc"}}

test thread-1.17 {Tcl_ThreadObjCmd: errorproc change} {
    testthread errorproc foo
    testthread errorproc ThreadError
} {}

# The tests above also cover:
# TclCreateThread, except when pthread_create fails
# NewThread, safe and regular
# ThreadErrorProc, except for printing to standard error

test thread-2.1 {ListUpdateInner and ListRemove} {
    catch {unset tid}
    foreach t {0 1 2} {
	upvar #0 t$t tid
	set tid [testthread create]
    }
    ThreadReap
} 1

test thread-3.1 {TclThreadList} {
    catch {unset tid}
    set mainthread [testthread names]
    set l1  {}
    foreach t {0 1 2} {
	lappend l1 [testthread create]
    }
    set l2 [testthread names]
    list $l1 $l2
    set c [string compare [lsort -integer [concat $mainthread $l1]] [lsort -integer $l2]]
    ThreadReap
    set c
} 0

test thread-4.1 {TclThreadSend to self} {
    catch {unset x}
    testthread send [testthread id] {
	set x 4
    }
    set x
} {4}

test thread-4.1 {TclThreadSend -async} {
    set mainthread [testthread names]
    set serverthread [testthread create]
    testthread send -async $serverthread {
	after 1000
	testthread exit
    }
    set two [llength [testthread names]]
    after 1500 {set done 1}
    vwait done
    list [llength [testthread names]] $two
} {1 2}

test thread-4.2 {TclThreadSend preserve errorInfo} {
    set mainthread [testthread names]
    set serverthread [testthread create]
    set x [catch {testthread send $serverthread {set undef}} msg]
    list $x $msg $errorInfo
} {1 {can't read "undef": no such variable} {can't read "undef": no such variable
    while executing
"set undef"
    invoked from within
"testthread send $serverthread {set undef}"}}
ThreadReap

test thread-4.3 {TclThreadSend preserve code} {
    set mainthread [testthread names]
    set serverthread [testthread create]
    set x [catch {testthread send $serverthread {break}} msg]
    list $x $msg $errorInfo
} {3 {} {}}
ThreadReap

test thread-4.4 {TclThreadSend preserve errorCode} {
    set mainthread [testthread names]
    set serverthread [testthread create]
    set x [catch {testthread send $serverthread {error ERR INFO CODE}} msg]
    list $x $msg $errorCode
} {1 ERR CODE}
ThreadReap

# cleanup
::tcltest::cleanupTests
return












Changes to tests/timer.test.

1
2
3
4
5
6
7
8
9
10

11
12
13
14

15


16
17
18
19
20
21
22
23
24
# This file contains a collection of tests for the procedures in the
# file tclTimer.c, which includes the "after" Tcl command.  Sourcing
# this file into Tcl runs the tests and generates output for errors.
# No output means no errors were found.
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) timer.test 1.2 97/04/29 11:59:59



if {[string compare test [info procs test]] == 1} then {source defs}

test timer-1.1 {Tcl_CreateTimerHandler procedure} {
    foreach i [after info] {
	after cancel $i
    }
    set x ""
    foreach i {100 200 1000 50 150} {










>




>
|
>
>
|
<







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
# This file contains a collection of tests for the procedures in the
# file tclTimer.c, which includes the "after" Tcl command.  Sourcing
# this file into Tcl runs the tests and generates output for errors.
# No output means no errors were found.
#
# 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: timer.test,v 1.1.2.5 1999/03/24 02:49:45 hershey Exp $

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


test timer-1.1 {Tcl_CreateTimerHandler procedure} {
    foreach i [after info] {
	after cancel $i
    }
    set x ""
    foreach i {100 200 1000 50 150} {
329
330
331
332
333
334
335

336
337
338
339















































































340
341

342
343
344
345
346
347
348
} {1 {wrong # args: should be "after info ?id?"}}
test timer-6.21 {Tcl_AfterCmd, info option} {
    list [catch {after info $childEvent} msg] $msg
} "1 {event \"$childEvent\" doesn't exist}"
test timer-6.22 {Tcl_AfterCmd, info option} {
    list [after info $event1] [after info $event2]
} {{{event 1} idle} {{event 2} timer}}

after cancel $event1
after cancel $event2
interp delete x
















































































set event [after idle foo bar]
scan $event after#%d id

test timer-7.1 {GetAfterEvent procedure} {
    list [catch {after info xfter#$id} msg] $msg
} "1 {event \"xfter#$id\" doesn't exist}"
test timer-7.2 {GetAfterEvent procedure} {
    list [catch {after info afterx$id} msg] $msg
} "1 {event \"afterx$id\" doesn't exist}"
test timer-7.3 {GetAfterEvent procedure} {







>




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


>







332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
} {1 {wrong # args: should be "after info ?id?"}}
test timer-6.21 {Tcl_AfterCmd, info option} {
    list [catch {after info $childEvent} msg] $msg
} "1 {event \"$childEvent\" doesn't exist}"
test timer-6.22 {Tcl_AfterCmd, info option} {
    list [after info $event1] [after info $event2]
} {{{event 1} idle} {{event 2} timer}}

after cancel $event1
after cancel $event2
interp delete x

test timer-6.23 {Tcl_AfterCmd procedure, no option, script with NULL} {
    foreach i [after info] {
	after cancel $i
    }
    set x "hello world"
    after 1 "set x ab\0cd"
    after 10
    update
    string length $x
} {5}
test timer-6.24 {Tcl_AfterCmd procedure, no option, script with NULL} {
    foreach i [after info] {
	after cancel $i
    }
    set x "hello world"
    after 1 set x ab\0cd
    after 10
    update
    string length $x
} {5}
test timer-6.25 {Tcl_AfterCmd procedure, cancel option, script with NULL} {
    foreach i [after info] {
	after cancel $i
    }
    set x "hello world"
    after 1 set x ab\0cd
    after cancel "set x ab\0ef"
    set x [llength [after info]]
    foreach i [after info] {
	after cancel $i
    }
    set x
} {1}
test timer-6.26 {Tcl_AfterCmd procedure, cancel option, script with NULL} {
    foreach i [after info] {
	after cancel $i
    }
    set x "hello world"
    after 1 set x ab\0cd
    after cancel set x ab\0ef
    set y [llength [after info]]
    foreach i [after info] {
	after cancel $i
    }
    set y
} {1}
test timer-6.27 {Tcl_AfterCmd procedure, idle option, script with NULL} {
    foreach i [after info] {
	after cancel $i
    }
    set x "hello world"
    after idle "set x ab\0cd"
    update
    string length $x
} {5}
test timer-6.28 {Tcl_AfterCmd procedure, idle option, script with NULL} {
    foreach i [after info] {
	after cancel $i
    }
    set x "hello world"
    after idle set x ab\0cd
    update
    string length $x
} {5}
test timer-6.29 {Tcl_AfterCmd procedure, info option, script with NULL} {
    foreach i [after info] {
	after cancel $i
    }
    set x "hello world"
    set id junk
    set id [after 1 set x ab\0cd]
    update
    set y [string length [lindex [lindex [after info $id] 0] 2]]
    foreach i [after info] {
	after cancel $i
    }
    set y
} {5}

set event [after idle foo bar]
scan $event after#%d id

test timer-7.1 {GetAfterEvent procedure} {
    list [catch {after info xfter#$id} msg] $msg
} "1 {event \"xfter#$id\" doesn't exist}"
test timer-7.2 {GetAfterEvent procedure} {
    list [catch {after info afterx$id} msg] $msg
} "1 {event \"afterx$id\" doesn't exist}"
test timer-7.3 {GetAfterEvent procedure} {
448
449
450
451
452
453
454
455















    }}
    interp delete x
    set x before
    after 300
    update
    set x
} {before after2 after4}
























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
    }}
    interp delete x
    set x before
    after 300
    update
    set x
} {before after2 after4}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/trace.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  trace
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) trace.test 1.27 97/07/23 17:08:38



if {[string compare test [info procs test]] == 1} then {source defs}

proc traceScalar {name1 name2 op} {
    global info
    set info [list $name1 $name2 $op [catch {uplevel set $name1} msg] $msg]
}
proc traceScalarAppend {name1 name2 op} {
    global info








>




>
|
>
>
|
<







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
# Commands covered:  trace
#
# 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: trace.test,v 1.1.2.5 1999/03/24 02:49:45 hershey Exp $

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


proc traceScalar {name1 name2 op} {
    global info
    set info [list $name1 $name2 $op [catch {uplevel set $name1} msg] $msg]
}
proc traceScalarAppend {name1 name2 op} {
    global info
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
    set info
} {5 1}

# Check operation and syntax of "trace" command.

test trace-13.1 {trace command (overall)} {
    list [catch {trace} msg] $msg
} {1 {too few args: should be "trace option [arg arg ...]"}}
test trace-13.2 {trace command (overall)} {
    list [catch {trace gorp} msg] $msg
} {1 {bad option "gorp": should be variable, vdelete, or vinfo}}
test trace-13.3 {trace command ("variable" option)} {
    list [catch {trace variable x y} msg] $msg
} {1 {wrong # args: should be "trace variable name ops command"}}
test trace-13.4 {trace command ("variable" option)} {
    list [catch {trace var x y z z2} msg] $msg
} {1 {wrong # args: should be "trace variable name ops command"}}
test trace-13.5 {trace command ("variable" option)} {







|


|







609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
    set info
} {5 1}

# Check operation and syntax of "trace" command.

test trace-13.1 {trace command (overall)} {
    list [catch {trace} msg] $msg
} {1 {wrong # args: should be "trace option [arg arg ...]"}}
test trace-13.2 {trace command (overall)} {
    list [catch {trace gorp} msg] $msg
} {1 {bad option "gorp": must be variable, vdelete, or vinfo}}
test trace-13.3 {trace command ("variable" option)} {
    list [catch {trace variable x y} msg] $msg
} {1 {wrong # args: should be "trace variable name ops command"}}
test trace-13.4 {trace command ("variable" option)} {
    list [catch {trace var x y z z2} msg] $msg
} {1 {wrong # args: should be "trace variable name ops command"}}
test trace-13.5 {trace command ("variable" option)} {
959
960
961
962
963
964
965
966















} {0 {a x y}}

# Delete arrays when done, so they can be re-used as scalars
# elsewhere.

catch {unset x}
catch {unset y}
concat {}






















|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
} {0 {a x y}}

# Delete arrays when done, so they can be re-used as scalars
# elsewhere.

catch {unset x}
catch {unset y}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/unixFCmd.test.

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
# This file tests the tclUnixFCmd.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) 1996 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) unixFCmd.test 1.15 97/11/03 15:58:22


if {[string compare test [info procs test]] == 1} then {source defs}




if {$tcl_platform(platform) != "unix"} {
    return
}


if {$user == "root"} {
    puts "Skipping unixFCmd tests.  They depend on not being able to write to"
    puts "certain directories.  It would be too dangerous to run them as root."
    return

}

proc openup {path} {
    testchmod 777 $path
    if {[file isdirectory $path]} {
	catch {
	    foreach p [glob [file join $path *]] {











|

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







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
# This file tests the tclUnixFCmd.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) 1996 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: unixFCmd.test,v 1.1.2.7 1999/03/25 04:32:18 hershey Exp $

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

# Several tests require need to match results against the unix username
set user {}
if {$tcl_platform(platform) == "unix"} {
    catch {set user [exec whoami]}
    if {$user == ""} {
	catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
    }
    if {$user == ""} {


	set user "root"
    }
}

proc openup {path} {
    testchmod 777 $path
    if {[file isdirectory $path]} {
	catch {
	    foreach p [glob [file join $path *]] {
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














		openup $file
		file delete -force -- $file
	    }
	}
    }
}

test unixFCmd-1.1 {TclpRenameFile: EACCES} {
    cleanup
    file mkdir td1/td2/td3
    exec chmod 000 td1/td2
    set msg [list [catch {file rename td1/td2/td3 td2} msg] $msg]
    exec chmod 755 td1/td2
    set msg
} {1 {error renaming "td1/td2/td3": permission denied}}
test unixFCmd-1.2 {TclpRenameFile: EEXIST} {
    cleanup
    file mkdir td1/td2
    file mkdir td2
    list [catch {file rename td2 td1} msg] $msg
} {1 {error renaming "td2" to "td1/td2": file already exists}}
test unixFCmd-1.3 {TclpRenameFile: EINVAL} {
    cleanup
    file mkdir td1
    list [catch {file rename td1 td1} msg] $msg
} {1 {error renaming "td1" to "td1/td1": trying to rename a volume or move a directory into itself}}
test unixFCmd-1.4 {TclpRenameFile: EISDIR} {
    # can't make it happen
} {}
test unixFCmd-1.5 {TclpRenameFile: ENOENT} {
    cleanup
    file mkdir td1
    list [catch {file rename td2 td1} msg] $msg
} {1 {error renaming "td2": no such file or directory}}
test unixFCmd-1.6 {TclpRenameFile: ENOTDIR} {
    # can't make it happen
} {}
test unixFCmd-1.7 {TclpRenameFile: EXDEV} {
    cleanup
    file mkdir foo/bar
    file attr foo -perm 040555
    set msg [list [catch {file rename foo/bar /tmp} msg] $msg]
    set a1 {1 {can't unlink "foo/bar": permission denied}}
    set result [expr {$msg == $a1}]
    catch {file delete /tmp/bar}
    catch {file attr foo -perm 040777}
    catch {file delete -force foo}
    set result





} {1}















test unixFCmd-2.1 {TclpCopyFile: target exists: lstat(dst) == 0} {

    cleanup
    exec touch tf1
    exec touch tf2
    file copy -force tf1 tf2
} {}
test unixFCmd-2.2 {TclpCopyFile: src is symlink} {
    cleanup
    exec ln -s tf1 tf2
    file copy tf2 tf3
    file type tf3
} {link}
test unixFCmd-2.3 {TclpCopyFile: src is block} {
    cleanup
    set null "/dev/null"
    while {[file type $null] != "characterSpecial"} {
	set null [file join [file dirname $null] [file readlink $null]]
    }
    # file copy $null tf1
} {}
test unixFCmd-2.4 {TclpCopyFile: src is fifo} {
    cleanup
    if [catch {exec mknod tf1 p}] {
	list 1
    } else {
	file copy tf1 tf2
	expr {"[file type tf1]" == "[file type tf2]"}
    }
} {1}
test unixFCmd-2.5 {TclpCopyFile: copy attributes} {
    cleanup
    exec touch tf1
    exec chmod 472 tf1
    file copy tf1 tf2
    string range [exec ls -l tf2] 0 9
} {-r--rwx-w-}

test unixFCmd-3.1 {CopyFile not done} {
} {}

test unixFCmd-4.1 {TclpDeleteFile not done} {
} {}

test unixFCmd-5.1 {TclpCreateDirectory not done} {
} {}

test unixFCmd-6.1 {TclpCopyDirectory not done} {
} {}

test unixFCmd-7.1 {TclpRemoveDirectory not done} {
} {}

test unixFCmd-8.1 {TraverseUnixTree not done} {
} {}

test unixFCmd-9.1 {TraversalCopy not done} {
} {}

test unixFCmd-10.1 {TraversalDelete not done} {
} {}

test unixFCmd-11.1 {CopyFileAttrs not done} {
} {}

set testConfig(tclGroup) 0
if {[catch {exec {groups}} groupList] == 0} {
    if {[lsearch $groupList tcl] != -1} {
	set testConfig(tclGroup) 1
    }
}

test unixFCmd-12.1 {GetGroupAttribute - file not found} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -group} msg] $msg
} {1 {could not stat file "foo.test": no such file or directory}}
test unixFCmd-12.2 {GetGroupAttribute - file found} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attributes foo.test -group}] [file delete -force -- foo.test]
} {0 {}}

test unixFCmd-13.1 {GetOwnerAttribute - file not found} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -group} msg] $msg
} {1 {could not stat file "foo.test": no such file or directory}}
test unixFCmd-13.2 {GetOwnerAttribute} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attributes foo.test -owner} msg] [string compare $msg $user] [file delete -force -- foo.test]

} {0 0 {}}

test unixFCmd-14.1 {GetPermissionsAttribute - file not found} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -permissions} msg] $msg
} {1 {could not stat file "foo.test": no such file or directory}}
test unixFCmd-14.2 {GetPermissionsAttribute} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attribute foo.test -permissions}] [file delete -force -- foo.test]

} {0 {}}










#groups hard to test
test unixFCmd-15.1 {SetGroupAttribute - invalid group} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -group foozzz} msg] $msg [file delete -force -- foo.test]

} {1 {could not set group for file "foo.test": group "foozzz" does not exist} {}}
test unixFCmd-15.2 {SetGroupAttribute - invalid file} {tclGroup} {

    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -group tcl} msg] $msg
} {1 {could not set group for file "foo.test": no such file or directory}}

#changing owners hard to do
test unixFCmd-16.1 {SetOwnerAttribute - current owner} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attributes foo.test -owner $user} msg] $msg [string compare [file attributes foo.test -owner] $user] [file delete -force -- foo.test]


} {0 {} 0 {}}
test unixFCmd-16.2 {SetOwnerAttribute - invalid file} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -owner $user} msg] $msg
} {1 {could not set owner for file "foo.test": no such file or directory}}
test unixFCmd-16.3 {SetOwnerAttribute - invalid owner} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -owner foozzz} msg] $msg
} {1 {could not set owner for file "foo.test": user "foozzz" does not exist}}


test unixFCmd-17.1 {SetPermissionsAttribute} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attributes foo.test -permissions 0000} msg] $msg [file attributes foo.test -permissions] [file delete -force -- foo.test]


} {0 {} 00000 {}}
test unixFCmd-17.2 {SetPermissionsAttribute} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -permissions 0000} msg] $msg
} {1 {could not set permissions for file "foo.test": no such file or directory}}
test unixFCmd-17.3 {SetPermissionsAttribute} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attributes foo.test -permissions foo} msg] $msg [file delete -force -- foo.test]

} {1 {expected integer but got "foo"} {}}
test unixFCmd-18.1 {Unix pwd} {nonPortable} {
    # This test is nonportable because SunOS generates a weird error
    # message when the current directory isn't readable.
    set cd [pwd]
    set nd $cd/tstdir
    file mkdir $nd
    cd $nd
    exec chmod 000 $nd
    set r [list [catch {pwd} res] [string range $res 0 36]];
    cd $cd;
    exec chmod 755 $nd
    file delete $nd
    set r
} {1 {error getting working directory name:}}


cleanup





















|







|





|




|


|




|


|



|
<
|



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





|





|







|








|







|


|


|


|


|


|
<
<
<


|


|


|
<
<
<
|
|
<
|


|
|





|


|
|


|
>


|


|
|


|
>


>
>
>
>
>
>
>
>
>

|

|
>

|
>

|



|


|
>
>

|



|





|


|
>
>

|



|


|
>

|














>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170



171
172
173
174
175
176
177
178
179



180
181

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
		openup $file
		file delete -force -- $file
	    }
	}
    }
}

test unixFCmd-1.1 {TclpRenameFile: EACCES} {unixOnly notRoot} {
    cleanup
    file mkdir td1/td2/td3
    exec chmod 000 td1/td2
    set msg [list [catch {file rename td1/td2/td3 td2} msg] $msg]
    exec chmod 755 td1/td2
    set msg
} {1 {error renaming "td1/td2/td3": permission denied}}
test unixFCmd-1.2 {TclpRenameFile: EEXIST} {unixOnly notRoot} {
    cleanup
    file mkdir td1/td2
    file mkdir td2
    list [catch {file rename td2 td1} msg] $msg
} {1 {error renaming "td2" to "td1/td2": file already exists}}
test unixFCmd-1.3 {TclpRenameFile: EINVAL} {unixOnly notRoot} {
    cleanup
    file mkdir td1
    list [catch {file rename td1 td1} msg] $msg
} {1 {error renaming "td1" to "td1/td1": trying to rename a volume or move a directory into itself}}
test unixFCmd-1.4 {TclpRenameFile: EISDIR} {emptyTest unixOnly notRoot} {
    # can't make it happen
} {}
test unixFCmd-1.5 {TclpRenameFile: ENOENT} {unixOnly notRoot} {
    cleanup
    file mkdir td1
    list [catch {file rename td2 td1} msg] $msg
} {1 {error renaming "td2": no such file or directory}}
test unixFCmd-1.6 {TclpRenameFile: ENOTDIR} {emptyTest unixOnly notRoot} {
    # can't make it happen
} {}
test unixFCmd-1.7 {TclpRenameFile: EXDEV} {unixOnly notRoot} {
    cleanup
    file mkdir foo/bar
    file attr foo -perm 040555
    set catchResult [catch {file rename foo/bar /tmp} msg]

    set msg [lindex [split $msg :] end]
    catch {file delete /tmp/bar}
    catch {file attr foo -perm 040777}
    catch {file delete -force foo}
    list $catchResult $msg
} {1 { permission denied}}
test unixFCmd-1.8 {Checking EINTR Bug} {unixOnly notRoot nonPortable} {
    testalarm 
    after 2000
    list [testgotsig] [testgotsig]
} {1 0}
test unixFCmd-1.9 {Checking EINTR Bug} {unixOnly notRoot nonPortable} {
    cleanup
    set f [open tfalarm w]
    puts $f {
	after 2000
	puts "hello world"
	exit 0
    }
    close $f
    testalarm 
    set pipe [open "|[info nameofexecutable] tfalarm" r+]
    set line [read $pipe 1]
    catch {close $pipe}
    list $line [testgotsig]
} {h 1}
test unixFCmd-2.1 {TclpCopyFile: target exists: lstat(dst) == 0} \
	{unixOnly notRoot} {
    cleanup
    exec touch tf1
    exec touch tf2
    file copy -force tf1 tf2
} {}
test unixFCmd-2.2 {TclpCopyFile: src is symlink} {unixOnly notRoot} {
    cleanup
    exec ln -s tf1 tf2
    file copy tf2 tf3
    file type tf3
} {link}
test unixFCmd-2.3 {TclpCopyFile: src is block} {unixOnly notRoot} {
    cleanup
    set null "/dev/null"
    while {[file type $null] != "characterSpecial"} {
	set null [file join [file dirname $null] [file readlink $null]]
    }
    # file copy $null tf1
} {}
test unixFCmd-2.4 {TclpCopyFile: src is fifo} {unixOnly notRoot} {
    cleanup
    if [catch {exec mknod tf1 p}] {
	list 1
    } else {
	file copy tf1 tf2
	expr {"[file type tf1]" == "[file type tf2]"}
    }
} {1}
test unixFCmd-2.5 {TclpCopyFile: copy attributes} {unixOnly notRoot} {
    cleanup
    exec touch tf1
    exec chmod 472 tf1
    file copy tf1 tf2
    string range [exec ls -l tf2] 0 9
} {-r--rwx-w-}

test unixFCmd-3.1 {CopyFile not done} {emptyTest unixOnly notRoot} {
} {}

test unixFCmd-4.1 {TclpDeleteFile not done} {emptyTest unixOnly notRoot} {
} {}

test unixFCmd-5.1 {TclpCreateDirectory not done} {emptyTest unixOnly notRoot} {
} {}

test unixFCmd-6.1 {TclpCopyDirectory not done} {emptyTest unixOnly notRoot} {
} {}

test unixFCmd-7.1 {TclpRemoveDirectory not done} {emptyTest unixOnly notRoot} {
} {}

test unixFCmd-8.1 {TraverseUnixTree not done} {emptyTest unixOnly notRoot} {



} {}

test unixFCmd-9.1 {TraversalCopy not done} {emptyTest unixOnly notRoot} {
} {}

test unixFCmd-10.1 {TraversalDelete not done} {emptyTest unixOnly notRoot} {
} {}

test unixFCmd-11.1 {CopyFileAttrs not done} {emptyTest unixOnly notRoot} {



} {}


test unixFCmd-12.1 {GetGroupAttribute - file not found} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -group} msg] $msg
} {1 {could not read "foo.test": no such file or directory}}
test unixFCmd-12.2 {GetGroupAttribute - file found} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attributes foo.test -group}] [file delete -force -- foo.test]
} {0 {}}

test unixFCmd-13.1 {GetOwnerAttribute - file not found} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -group} msg] $msg
} {1 {could not read "foo.test": no such file or directory}}
test unixFCmd-13.2 {GetOwnerAttribute} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attributes foo.test -owner} msg] \
	    [string compare $msg $user] [file delete -force -- foo.test]
} {0 0 {}}

test unixFCmd-14.1 {GetPermissionsAttribute - file not found} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -permissions} msg] $msg
} {1 {could not read "foo.test": no such file or directory}}
test unixFCmd-14.2 {GetPermissionsAttribute} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attribute foo.test -permissions}] \
	    [file delete -force -- foo.test]
} {0 {}}

# Find a group that exists on this system, or else skip tests that require
# groups
set ::tcltest::testConfig(foundGroup) 0
catch {
    set groupList [exec groups]
    set group [lindex $groupList 0]
    set ::tcltest::testConfig(foundGroup) 1
}

#groups hard to test
test unixFCmd-15.1 {SetGroupAttribute - invalid group} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -group foozzz} msg] \
	    $msg [file delete -force -- foo.test]
} {1 {could not set group for file "foo.test": group "foozzz" does not exist} {}}
test unixFCmd-15.2 {SetGroupAttribute - invalid file} \
	{unixOnly notRoot foundGroup} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -group $group} msg] $msg
} {1 {could not set group for file "foo.test": no such file or directory}}

#changing owners hard to do
test unixFCmd-16.1 {SetOwnerAttribute - current owner} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attributes foo.test -owner $user} msg] \
	    $msg [string compare [file attributes foo.test -owner] $user] \
	    [file delete -force -- foo.test]
} {0 {} 0 {}}
test unixFCmd-16.2 {SetOwnerAttribute - invalid file} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -owner $user} msg] $msg
} {1 {could not set owner for file "foo.test": no such file or directory}}
test unixFCmd-16.3 {SetOwnerAttribute - invalid owner} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -owner foozzz} msg] $msg
} {1 {could not set owner for file "foo.test": user "foozzz" does not exist}}


test unixFCmd-17.1 {SetPermissionsAttribute} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attributes foo.test -permissions 0000} msg] \
	    $msg [file attributes foo.test -permissions] \
	    [file delete -force -- foo.test]
} {0 {} 00000 {}}
test unixFCmd-17.2 {SetPermissionsAttribute} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    list [catch {file attributes foo.test -permissions 0000} msg] $msg
} {1 {could not set permissions for file "foo.test": no such file or directory}}
test unixFCmd-17.3 {SetPermissionsAttribute} {unixOnly notRoot} {
    catch {file delete -force -- foo.test}
    close [open foo.test w]
    list [catch {file attributes foo.test -permissions foo} msg] $msg \
	    [file delete -force -- foo.test]
} {1 {expected integer but got "foo"} {}}
test unixFCmd-18.1 {Unix pwd} {nonPortable unixOnly notRoot} {
    # This test is nonportable because SunOS generates a weird error
    # message when the current directory isn't readable.
    set cd [pwd]
    set nd $cd/tstdir
    file mkdir $nd
    cd $nd
    exec chmod 000 $nd
    set r [list [catch {pwd} res] [string range $res 0 36]];
    cd $cd;
    exec chmod 755 $nd
    file delete $nd
    set r
} {1 {error getting working directory name:}}

# cleanup
cleanup
::tcltest::cleanupTests
return












Added tests/unixFile.test.



























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# This file contains tests for the routines in the file tclUnixFile.c
#
# 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) 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: unixFile.test,v 1.1.2.6 1999/04/02 18:57:09 hershey Exp $

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

if {[info commands testobj] == {}} {
    puts "This application hasn't been compiled with the \"testfindexecutable\""
    puts "command, so I can't test the Tcl_FindExecutable function"
    ::tcltest::cleanupTests
    return
}

catch {
    set oldPath $env(PATH)
    close [open junk w]
    file attributes junk -perm 0777
}
set absPath [file join [pwd] junk]

test unixFile-1.1 {Tcl_FindExecutable} {unixOnly} {
    set env(PATH) ""
    testfindexecutable junk
} $absPath
test unixFile-1.2 {Tcl_FindExecutable} {unixOnly} {
    set env(PATH) "/dummy"
    testfindexecutable junk
} {}
test unixFile-1.3 {Tcl_FindExecutable} {unixOnly} {
    set env(PATH) "/dummy:[pwd]"
    testfindexecutable junk
} $absPath
test unixFile-1.4 {Tcl_FindExecutable} {unixOnly} {
    set env(PATH) "/dummy:"
    testfindexecutable junk
} $absPath
test unixFile-1.5 {Tcl_FindExecutable} {unixOnly} {
    set env(PATH) "/dummy:/dummy"
    testfindexecutable junk
} {}
test unixFile-1.6 {Tcl_FindExecutable} {unixOnly} {
    set env(PATH) "/dummy::/dummy"
    testfindexecutable junk
} $absPath
test unixFile-1.7 {Tcl_FindExecutable} {unixOnly} {
    set env(PATH) ":/dummy"
    testfindexecutable junk
} $absPath

# cleanup
catch {set env(PATH) $oldPath}
file delete junk
::tcltest::cleanupTests
return












Added tests/unixInit.test.



























































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# 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.1.2.9 1999/04/06 20:40:23 stanton 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)}
set env(LANG) C

# Some tests will fail if they are run on a machine that doesn't have
# this Tcl version installed (as opposed to built) on it.
if {[catch {
    set f [open "|[list $tcltest]" w+]
    exec kill -PIPE [pid $f]
    close $f
}]} {
    set ::tcltest::testConfig(installedTcl) 0
} else {
    set ::tcltest::testConfig(installedTcl) 1
}

test unixInit-1.1 {TclpInitPlatform: ignore SIGPIPE} {unixOnly installedTcl} {
    set x {}

    # Watch out for a race condition here.  If tcltest is too slow to start
    # then we'll kill it before it has a chance to set up its signal handler.
    
    set f [open "|[list $tcltest]" w+]
    puts $f "puts hi"
    flush $f
    gets $f
    exec kill -PIPE [pid $f]
    lappend x [catch {close $f}]

    set f [open "|[list $tcltest]" w+]
    puts $f "puts hi"
    flush $f
    gets $f
    exec kill [pid $f]
    lappend x [catch {close $f}]

    set x
} {0 1}

proc getlibpath "{program [list $tcltest]}" {
    set f [open "|$program" w+]
    fconfigure $f -buffering none
    puts $f {puts $tcl_libPath; exit}
    set path [gets $f]
    close $f
    return $path
}

# Some tests require the testgetdefenc command

set ::tcltest::testConfig(testgetdefenc) \
	[expr {[info commands testgetdefenc] != {}}]

test unixInit-2.0 {TclpInitLibraryPath: setting tclDefaultEncodingDir} \
	{unixOnly testgetdefenc} {
    set origDir [testgetdefenc]
    testsetdefenc slappy
    set path [testgetdefenc]
    testsetdefenc $origDir
    set path
} {slappy}
test unixInit-2.1 {TclpInitLibraryPath: value of installLib, developLib} \
	{unixOnly installedTcl} {
    set path [getlibpath]

    set installLib lib/tcl[info tclversion]
    if {[string match {*[ab]*} [info patchlevel]]} {
	set developLib tcl[info patchlevel]/library
    } 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]
    unset env(TCL_LIBRARY)

    lindex $path 0
} "sparkly"
test unixInit-2.3 {TclpInitLibraryPath: TCL_LIBRARY wrong version} \
	{unixOnly installedTcl} {
    # ((pathc > 0) && (strcasecmp(installLib + 4, pathv[pathc - 1]) != 0))

    set env(TCL_LIBRARY) /a/b/tcl1.7
    set path [getlibpath]
    unset env(TCL_LIBRARY)

    lrange $path 0 1
} [list /a/b/tcl1.7 /a/b/tcl[info tclversion]]
test unixInit-2.4 {TclpInitLibraryPath: TCL_LIBRARY: INTL} \
	{unixOnly installedTcl} {
    # Child process translates env variable from native encoding.

    set env(TCL_LIBRARY) "\xa7"
    set x [lindex [getlibpath] 0]
    unset env(TCL_LIBRARY)
    unset env(LANG)

    set x
} "\xa7"
test unixInit-2.5 {TclpInitLibraryPath: compiled-in library path} \
	{emptyTest unixOnly} {
    # cannot test
} {}
test unixInit-2.6 {TclpInitLibraryPath: executable relative} \
	{unixOnly installedTcl} {
    file delete -force /tmp/sparkly
    file mkdir /tmp/sparkly/bin
    file copy $tcltest /tmp/sparkly/bin/tcltest

    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 patchlevel]/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

    set f [open "|[list $tcltest]" w+]
    fconfigure $f -buffering none
    puts $f {puts [encoding system]; exit}
    set enc [gets $f]
    close $f
    unset env(LANG)

    set enc
} {iso8859-1}
test unixInit-3.2 {TclpSetInitialEncodings} {unixOnly installedTcl} {
    set env(LANG) japanese

    set f [open "|[list $tcltest]" w+]
    fconfigure $f -buffering none
    puts $f {puts [encoding system]; exit}
    set enc [gets $f]
    close $f
    unset env(LANG)

    set enc
} {euc-jp}
    
test unixInit-4.1 {TclpSetVariables} {unixOnly} {
    # just make sure they exist

    set a [list $tcl_library $tcl_pkgPath $tcl_platform(os)]
    set a [list $tcl_platform(osVersion) $tcl_platform(machine)]
    set tcl_platform(platform)
} "unix"

test unixInit-5.1 {Tcl_Init} {emptyTest unixOnly} {
    # test initScript
} {}

test unixInit-6.1 {Tcl_SourceRCFile} {emptyTest unixOnly} {
} {}
    
# cleanup
catch {unset env(TCL_LIBRARY); set env(TCL_LIBRARY) $oldlibrary}
catch {unset env(LANG); set env(LANG) $oldlang}
::tcltest::cleanupTests
return












Changes to tests/unixNotfy.test.

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















# This file contains tests for tclUnixNotfy.c.
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) unixNotfy.test 1.3 97/09/15 15:39:53

if {[string compare test [info procs test]] == 1} then {source defs}

if {$tcl_platform(platform) != "unix"} {
    return
}

# The tests should not be run if you have a notifier which is unable to
# detect infinite vwaits, as the tests below will hang. The presence of
# the "testeventloop" command indicates that this is the case.


if {"[info commands testeventloop]" == "testeventloop"} {

    return


}




test unixNotfy-1.1 {Tcl_DeleteFileHandler} {
    catch {vwait x}
    set f [open foo w]
    fileevent $f writable {set x 1}
    vwait x
    close $f
    list [catch {vwait x} msg] $msg
} {1 {can't wait for variable "x":  would wait forever}}
test unixNotfy-1.2 {Tcl_DeleteFileHandler} {
    catch {vwait x}
    set f1 [open foo w]
    set f2 [open foo2 w]
    fileevent $f1 writable {set x 1}
    fileevent $f2 writable {set y 1}
    vwait x
    close $f1
    vwait y
    close $f2
    list [catch {vwait x} msg] $msg
} {1 {can't wait for variable "x":  would wait forever}}


































file delete foo






















>




<
|
<
<
<
<
<



|

>
|
>
|
>
>
|
>
>
>

|







|












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# This file contains tests for tclUnixNotfy.c.
#
# 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: unixNotfy.test,v 1.1.2.8 1999/04/07 01:29:27 stanton Exp $






# The tests should not be run if you have a notifier which is unable to
# detect infinite vwaits, as the tests below will hang. The presence of
# the "testthread" command indicates that this is the case.

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

set ::tcltest::testConfig(testthread) \
	[expr {[info commands testthread] != {}}]

# The next two tests will hang if threads are enabled because the notifier
# will not necessarily wait for ever in this case, so it does not generate
# an error.

test unixNotfy-1.1 {Tcl_DeleteFileHandler} {unixOnly && !testthread} {
    catch {vwait x}
    set f [open foo w]
    fileevent $f writable {set x 1}
    vwait x
    close $f
    list [catch {vwait x} msg] $msg
} {1 {can't wait for variable "x":  would wait forever}}
test unixNotfy-1.2 {Tcl_DeleteFileHandler} {unixOnly && !testthread} {
    catch {vwait x}
    set f1 [open foo w]
    set f2 [open foo2 w]
    fileevent $f1 writable {set x 1}
    fileevent $f2 writable {set y 1}
    vwait x
    close $f1
    vwait y
    close $f2
    list [catch {vwait x} msg] $msg
} {1 {can't wait for variable "x":  would wait forever}}


test unixNotfy-2.1 {Tcl_DeleteFileHandler} {unixOnly testthread} {
    update
    set f [open foo w]
    fileevent $f writable {set x 1}
    vwait x
    close $f
    testthread create "after 500
    testthread send [testthread id] {set x ok}
    testthread exit"
    vwait x
    set x
} {ok}
test unixNotfy-1.2 {Tcl_DeleteFileHandler} {unixOnly testthread} {
    update
    set f1 [open foo w]
    set f2 [open foo2 w]
    fileevent $f1 writable {set x 1}
    fileevent $f2 writable {set y 1}
    vwait x
    close $f1
    vwait y
    close $f2
    testthread create "after 500
    testthread send [testthread id] {set x ok}
    testthread exit"
    vwait x
    set x
} {ok}



# cleanup
file delete foo
file delete foo2
::tcltest::cleanupTests
return












Changes to tests/unknown.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  unknown
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) unknown.test 1.12 96/08/26 11:29:29



if {[string compare test [info procs test]] == 1} then {source defs}

catch {unset x}
catch {rename unknown unknown.old}

test unknown-1.1 {non-existent "unknown" command} {
    list [catch {_non-existent_ foo bar} msg] $msg
} {1 {invalid command name "_non-existent_"}}








>




>
|
>
>
|
<







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
# Commands covered:  unknown
#
# 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: unknown.test,v 1.1.2.5 1999/03/24 02:49:48 hershey Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}


catch {unset x}
catch {rename unknown unknown.old}

test unknown-1.1 {non-existent "unknown" command} {
    list [catch {_non-existent_ foo bar} msg] $msg
} {1 {invalid command name "_non-existent_"}}
52
53
54
55
56
57
58

59
60

61












    error "unknown failed"
}

test unknown-4.1 {errors in "unknown" procedure} {
    list [catch {non-existent a b} msg] $msg $errorCode
} {1 {unknown failed} NONE}


catch {rename unknown {}}
catch {rename unknown.old unknown}

return {}



















>


>
|
>
>
>
>
>
>
>
>
>
>
>
>
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
    error "unknown failed"
}

test unknown-4.1 {errors in "unknown" procedure} {
    list [catch {non-existent a b} msg] $msg $errorCode
} {1 {unknown failed} NONE}

# cleanup
catch {rename unknown {}}
catch {rename unknown.old unknown}
::tcltest::cleanupTests
return 












Changes to tests/uplevel.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  uplevel
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) uplevel.test 1.13 96/02/16 08:56:35



if {[string compare test [info procs test]] == 1} then {source defs}

proc a {x y} {
    newset z [expr $x+$y]
    return $z
}
proc newset {name value} {
    uplevel set $name $value








>




>
|
>
>
|
<







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
# Commands covered:  uplevel
#
# 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: uplevel.test,v 1.1.2.5 1999/03/24 02:49:48 hershey Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}


proc a {x y} {
    newset z [expr $x+$y]
    return $z
}
proc newset {name value} {
    uplevel set $name $value
103
104
105
106
107
108
109
















    global x y
    set x [info level]
    set y [info level 1]
}
a2
test uplevel-5.1 {info level} {set x} 1
test uplevel-5.2 {info level} {set y} a3























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    global x y
    set x [info level]
    set y [info level 1]
}
a2
test uplevel-5.1 {info level} {set x} 1
test uplevel-5.2 {info level} {set y} a3

# cleanup
::tcltest::cleanupTests
return












Changes to tests/upvar.test.

1
2
3
4
5
6
7
8

9
10
11
12

13


14
15
16
17
18
19
20
21
22
# Commands covered:  upvar
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) upvar.test 1.15 97/10/29 18:25:56



if {[string compare test [info procs test]] == 1} then {source defs}

test upvar-1.1 {reading variables with upvar} {
    proc p1 {a b} {set c 22; set d 33; p2}
    proc p2 {} {upvar a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a}
    p1 foo bar
} {foo bar 22 33 abc}
test upvar-1.2 {reading variables with upvar} {








>




>
|
>
>
|
<







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
# Commands covered:  upvar
#
# 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: upvar.test,v 1.1.2.5 1999/03/24 02:49:48 hershey Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}


test upvar-1.1 {reading variables with upvar} {
    proc p1 {a b} {set c 22; set d 33; p2}
    proc p2 {} {upvar a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a}
    p1 foo bar
} {foo bar 22 33 abc}
test upvar-1.2 {reading variables with upvar} {
323
324
325
326
327
328
329





330
331
332
333
334
335
336
        namespace eval ::test_ns_1 {
	    upvar a a
        }
        unset ::test_ns_1::a
    }
    list [catch {MakeLink 1} msg] $msg
} {1 {bad variable name "a": upvar won't create namespace variable that refers to procedure variable}}






if {[info commands testupvar] != {}} {
    test upvar-9.1 {Tcl_UpVar2 procedure} {
	list [catch {testupvar xyz a {} x global} msg] $msg
    } {1 {bad level "xyz"}}
    test upvar-9.2 {Tcl_UpVar2 procedure} {
	catch {unset a}







>
>
>
>
>







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
        namespace eval ::test_ns_1 {
	    upvar a a
        }
        unset ::test_ns_1::a
    }
    list [catch {MakeLink 1} msg] $msg
} {1 {bad variable name "a": upvar won't create namespace variable that refers to procedure variable}}
test upvar-8.10 {upvar will create element alias for new array element} {
    catch {unset upvarArray}
    array set upvarArray {}
    catch {upvar 0 upvarArray(elem) upvarArrayElemAlias}
} {0}

if {[info commands testupvar] != {}} {
    test upvar-9.1 {Tcl_UpVar2 procedure} {
	list [catch {testupvar xyz a {} x global} msg] $msg
    } {1 {bad level "xyz"}}
    test upvar-9.2 {Tcl_UpVar2 procedure} {
	catch {unset a}
387
388
389
390
391
392
393



394











	catch {unset x}
	set a(b) 1234
	foo
    } {1234}
}
catch {unset a}




concat


















>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
	catch {unset x}
	set a(b) 1234
	foo
    } {1234}
}
catch {unset a}

# cleanup
::tcltest::cleanupTests
return












Added tests/utf.test.









































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# This file contains a collection of tests for tclUtf.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: utf.test,v 1.1.2.7 1999/04/06 19:03:58 hershey Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

catch {unset x}

test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} {
    set x \x01
} [bytestring "\x01"]
test utf-1.2 {Tcl_UniCharToUtf: 2 byte sequences} {
    set x "\x00"
} [bytestring "\xc0\x80"]
test utf-1.3 {Tcl_UniCharToUtf: 2 byte sequences} {
    set x "\xe0"
} [bytestring "\xc3\xa0"]
test utf-1.4 {Tcl_UniCharToUtf: 3 byte sequences} {
    set x "\u4e4e"
} [bytestring "\xe4\xb9\x8e"]

test utf-2.1 {Tcl_UtfToUniChar: low ascii} {
    string length "abc"
} {3}
test utf-2.2 {Tcl_UtfToUniChar: naked trail bytes} {
    string length [bytestring "\x82\x83\x84"]
} {3}
test utf-2.3 {Tcl_UtfToUniChar: lead (2-byte) followed by non-trail} {
    string length [bytestring "\xC2"]
} {1}
test utf-2.4 {Tcl_UtfToUniChar: lead (2-byte) followed by trail} {
    string length [bytestring "\xC2\xa2"]
} {1}
test utf-2.5 {Tcl_UtfToUniChar: lead (3-byte) followed by non-trail} {
    string length [bytestring "\xE2"]
} {1}
test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} {
    string length [bytestring "\xE2\xA2"]
} {2}
test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} {
    string length [bytestring "\xE4\xb9\x8e"]
} {1}
test utf-2.8 {Tcl_UtfToUniChar: longer UTF sequences not supported} {
    string length [bytestring "\xF4\xA2\xA2\xA2"]
} {4}

test utf-3.1 {Tcl_UtfCharComplete} {
} {}

test utf-4.1 {Tcl_NumUtfChars: zero length} {
    string length ""
} {0}
test utf-4.2 {Tcl_NumUtfChars: length 1} {
    string length [bytestring "\xC2\xA2"]
} {1}
test utf-4.3 {Tcl_NumUtfChars: long string} {
    string length [bytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"]
} {7}

test utf-5.1 {Tcl_UtfFindFirsts} {
} {}

test utf-6.1 {Tcl_UtfNext} {
} {}

test utf-7.1 {Tcl_UtfPrev} {
} {}

test utf-8.1 {Tcl_UniCharAtIndex: index = 0} {
    string index abcd 0
} {a}
test utf-8.2 {Tcl_UniCharAtIndex: index = 0} {
    string index \u4e4e\u25a 0
} "\u4e4e"
test utf-8.3 {Tcl_UniCharAtIndex: index > 0} {
    string index abcd 2
} {c}
test utf-8.4 {Tcl_UniCharAtIndex: index > 0} {
    string index \u4e4e\u25a\xff\u543 2
} "\uff"

test utf-9.1 {Tcl_UtfAtIndex: index = 0} {
    string range abcd 0 2
} {abc}
test utf-9.2 {Tcl_UtfAtIndex: index > 0} {
    string range \u4e4e\u25a\xff\u543klmnop 1 5
} "\u25a\xff\u543kl"


test utf-10.1 {Tcl_UtfBackslash: dst == NULL} {
    set x \n
} {
}
test utf-10.2 {Tcl_UtfBackslash: \u subst} {
    set x \ua2
} [bytestring "\xc2\xa2"]
test utf-10.3 {Tcl_UtfBackslash: longer \u subst} {
    set x \u4e21
} [bytestring "\xe4\xb8\xa1"]
test utf-10.4 {Tcl_UtfBackslash: stops at first non-hex} {
    set x \u4e2k
} "[bytestring \xd3\xa2]k"
test utf-10.5 {Tcl_UtfBackslash: stops after 4 hex chars} {
    set x \u4e216
} "[bytestring \xe4\xb8\xa1]6"
proc bsCheck {char num} {
    global errNum
    test utf-10.$errNum {backslash substitution} {
	scan $char %c value
	set value
    } $num
    incr errNum
}
set errNum 6
bsCheck \b	8
bsCheck \e	101
bsCheck \f	12
bsCheck \n	10
bsCheck \r	13
bsCheck \t	9
bsCheck \v	11
bsCheck \{	123
bsCheck \}	125
bsCheck \[	91
bsCheck \]	93
bsCheck \$	36
bsCheck \ 	32
bsCheck \;	59
bsCheck \\	92
bsCheck \Ca	67
bsCheck \Ma	77
bsCheck \CMa	67
bsCheck \8a	8
bsCheck \14	12
bsCheck \141	97
bsCheck b\0	98
bsCheck \x	120
bsCheck \xa	10
bsCheck \xA	10
bsCheck \x41	65
bsCheck \x541	65
bsCheck \u	117
bsCheck \uk	117
bsCheck \u41	65
bsCheck \ua	10
bsCheck \uA	10
bsCheck \340	224
bsCheck \ua1	161
bsCheck \u4e21	20001

test utf-11.1 {Tcl_UtfToUpper} {
    string toupper {}
} {}
test utf-11.2 {Tcl_UtfToUpper} {
    string toupper abc
} ABC
test utf-11.3 {Tcl_UtfToUpper} {
    string toupper \u00e3ab
} \u00c3AB
test utf-11.4 {Tcl_UtfToUpper} {
    string toupper \u01e3ab
} \u01e2AB

test utf-12.1 {Tcl_UtfToLower} {
    string tolower {}
} {}
test utf-12.2 {Tcl_UtfToLower} {
    string tolower ABC
} abc
test utf-12.3 {Tcl_UtfToLower} {
    string tolower \u00c3AB
} \u00e3ab
test utf-12.4 {Tcl_UtfToLower} {
    string tolower \u01e2AB
} \u01e3ab

test utf-13.1 {Tcl_UtfToTitle} {
    string totitle {}
} {}
test utf-13.2 {Tcl_UtfToTitle} {
    string totitle abc
} Abc
test utf-13.3 {Tcl_UtfToTitle} {
    string totitle \u00e3ab
} \u00c3ab
test utf-13.4 {Tcl_UtfToTitle} {
    string totitle \u01f3ab
} \u01f2ab

test utf-14.1 {Tcl_UniCharToUpper, negative delta} {
    string toupper aA
} AA
test utf-14.2 {Tcl_UniCharToUpper, positive delta} {
    string toupper \u0178\u00ff
} \u0178\u0178
test utf-14.3 {Tcl_UniCharToUpper, no delta} {
    string toupper !
} !

test utf-15.1 {Tcl_UniCharToLower, negative delta} {
    string tolower aA
} aa
test utf-15.2 {Tcl_UniCharToLower, positive delta} {
    string tolower \u0178\u00ff
} \u00ff\u00ff
test utf-16.1 {Tcl_UniCharToLower, no delta} {
    string tolower !
} !

test utf-17.1 {Tcl_UniCharToTitle, add one for title} {
    string totitle \u01c4
} \u01c5
test utf-17.2 {Tcl_UniCharToTitle, subtract one for title} {
    string totitle \u01c6
} \u01c5
test utf-17.3 {Tcl_UniCharToTitle, subtract delta for title (positive)} {
    string totitle \u017f
} \u0053
test utf-17.4 {Tcl_UniCharToTitle, subtract delta for title (negative)} {
    string totitle \u00ff
} \u0178
test utf-17.5 {Tcl_UniCharToTitle, no delta} {
    string totitle !
} !

test utf-18.1 {TclUniCharLen} {
    list [regexp \\d abc456def foo] $foo
} {1 4}

test utf-19.1 {TclUniCharNcmp} {
} {}

test utf-20.1 {TclUniCharIsAlnum} {
} {}

test utf-21.1 {TclUniCharIsWordChar} {
    string wordend "xyz123_bar fg" 0
} 10
test utf-21.1 {TclUniCharIsWordChar} {
    string wordend "x\u5080z123_bar\u203c fg" 0
} 10
    
test utf-22.1 {TclUniCharIsAlpha} {
} {}

test utf-23.1 {TclUniCharIsDigit} {
} {}

test utf-23.1 {TclUniCharIsSpace} {
} {}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/util.test.

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
# This file is a Tcl script to test the code in the file tclUtil.c.
# This file is organized in the standard fashion for Tcl tests.
#
# 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.
#

# SCCS: @(#) util.test 1.8 97/08/12 15:50:02




if {[info commands testobj] == {}} {
    puts "This application hasn't been compiled with the \"testobj\""
    puts "command, so I can't test the Tcl type and object support."

    return
}

if {[string compare test [info procs test]] == 1} then {source defs}

test util-1.1 {TclFindElement procedure - binary element in middle of list} {
    lindex {0 foo\x00help 1} 1
} "foo\x00help"
test util-1.2 {TclFindElement procedure - binary element at end of list} {
    lindex {0 foo\x00help} 1
} "foo\x00help"




|
>




>
|
>
>
>




>



<
<







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
# This file is a Tcl script to test the code in the file tclUtil.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright (c) 1995-1998 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: util.test,v 1.1.2.7 1999/03/26 19:14:08 hershey Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

if {[info commands testobj] == {}} {
    puts "This application hasn't been compiled with the \"testobj\""
    puts "command, so I can't test the Tcl type and object support."
    ::tcltest::cleanupTests
    return
}



test util-1.1 {TclFindElement procedure - binary element in middle of list} {
    lindex {0 foo\x00help 1} 1
} "foo\x00help"
test util-1.2 {TclFindElement procedure - binary element at end of list} {
    lindex {0 foo\x00help} 1
} "foo\x00help"

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
test util-4.4 {Tcl_ConcatObj - backslash-space at end of argument} {
    concat a {b } c
} {a b c}
test util-4.5 {Tcl_ConcatObj - backslash-space at end of argument} {
    concat a { } c
} {a c}

test util-5.1 {Tcl_SetObjErrorCode - one arg} {

























    catch {testsetobjerrorcode 1}













    list [set errorCode]














































} {1}



test util-5.2 {Tcl_SetObjErrorCode - two args} {
    catch {testsetobjerrorcode 1 2}

    list [set errorCode]

} {{1 2}}
test util-5.3 {Tcl_SetObjErrorCode - three args} {

































    catch {testsetobjerrorcode 1 2 3}






















    list [set errorCode]

} {{1 2 3}}
test util-5.4 {Tcl_SetObjErrorCode - four args} {



    catch {testsetobjerrorcode 1 2 3 4}

    list [set errorCode]

} {{1 2 3 4}}



test util-5.5 {Tcl_SetObjErrorCode - five args} {
    catch {testsetobjerrorcode 1 2 3 4 5}

    list [set errorCode]

} {{1 2 3 4 5}}

test util-6.1 {Tcl_PrintDouble - using tcl_precision} {
    concat x[expr 1.4]
} {x1.4}
test util-6.2 {Tcl_PrintDouble - using tcl_precision} {
    concat x[expr 1.39999999999]
} {x1.39999999999}
test util-6.3 {Tcl_PrintDouble - using tcl_precision} {
    concat x[expr 1.399999999999]
} {x1.4}
test util-6.4 {Tcl_PrintDouble - using tcl_precision} {
    set tcl_precision 5
    concat x[expr 1.123412341234]
} {x1.1234}
set tcl_precision 12
test util-6.4 {Tcl_PrintDouble - make sure there's a decimal point} {
    concat x[expr 2.0]
} {x2.0}
test util-6.5 {Tcl_PrintDouble - make sure there's a decimal point} {
    concat x[expr 3.0e98]
} {x3e+98}

test util-7.1 {TclPrecTraceProc - unset callbacks} {
    set tcl_precision 7
    set x $tcl_precision
    unset tcl_precision







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
|
>
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
|
>
>
>
|
>
|
>
|
>
>
>
|
|
>
|
>
|















|


|







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
test util-4.4 {Tcl_ConcatObj - backslash-space at end of argument} {
    concat a {b } c
} {a b c}
test util-4.5 {Tcl_ConcatObj - backslash-space at end of argument} {
    concat a { } c
} {a c}

test util-5.1 {Tcl_StringMatch} {
    string match ab*c abc
} 1
test util-5.2 {Tcl_StringMatch} {
    string match ab**c abc
} 1
test util-5.3 {Tcl_StringMatch} {
    string match ab* abcdef
} 1
test util-5.4 {Tcl_StringMatch} {
    string match *c abc
} 1
test util-5.5 {Tcl_StringMatch} {
    string match *3*6*9 0123456789
} 1
test util-5.6 {Tcl_StringMatch} {
    string match *3*6*9 01234567890
} 0
test util-5.7 {Tcl_StringMatch: UTF-8} {
    string match *u \u4e4fu
} 1
test util-5.8 {Tcl_StringMatch} {
    string match a?c abc
} 1
test util-5.9 {Tcl_StringMatch: UTF-8} {
    # skip one character in string

    string match a?c a\u4e4fc
} 1
test util-5.10 {Tcl_StringMatch} {
    string match a??c abc
} 0
test util-5.11 {Tcl_StringMatch} {
    string match ?1??4???8? 0123456789
} 1
test util-5.12 {Tcl_StringMatch} {
    string match {[abc]bc} abc
} 1
test util-5.13 {Tcl_StringMatch: UTF-8} {
    # string += Tcl_UtfToUniChar(string, &ch);

    string match "\[\u4e4fxy\]bc" "\u4e4fbc"
} 1
test util-5.14 {Tcl_StringMatch} {
    # if ((*pattern == ']') || (*pattern == '\0'))
    # badly formed pattern

    string match {[]} {[]}
} 0
test util-5.15 {Tcl_StringMatch} {
    # if ((*pattern == ']') || (*pattern == '\0'))
    # badly formed pattern

    string match {[} {[}
} 0
test util-5.16 {Tcl_StringMatch} {
    string match {a[abc]c} abc
} 1
test util-5.17 {Tcl_StringMatch: UTF-8} {
    # pattern += Tcl_UtfToUniChar(pattern, &endChar);
    # get 1 UTF-8 character

    string match "a\[a\u4e4fc]c" "a\u4e4fc"
} 1
test util-5.18 {Tcl_StringMatch: UTF-8} {
    # pattern += Tcl_UtfToUniChar(pattern, &endChar);
    # proper advance: wrong answer would match on UTF trail byte of \u4e4f

    string match {a[a\u4e4fc]c} [bytestring a\u008fc]
} 0
test util-5.19 {Tcl_StringMatch: UTF-8} {
    # pattern += Tcl_UtfToUniChar(pattern, &endChar);
    # proper advance.

    string match {a[a\u4e4fc]c} "acc"
} 1
test util-5.20 {Tcl_StringMatch} {
    string match {a[xyz]c} abc
} 0
test util-5.21 {Tcl_StringMatch} {
    string match {12[2-7]45} 12345
} 1
test util-5.22 {Tcl_StringMatch: UTF-8 range} {
    string match "\[\u4e00-\u4e4f]" "0"
} 0
test util-5.23 {Tcl_StringMatch: UTF-8 range} {
    string match "\[\u4e00-\u4e4f]" "\u4e33"
} 1
test util-5.24 {Tcl_StringMatch: UTF-8 range} {
    string match "\[\u4e00-\u4e4f]" "\uff08"
} 0
test util-5.25 {Tcl_StringMatch} {
    string match {12[ab2-4cd]45} 12345
} 1
test util-5.26 {Tcl_StringMatch} {
    string match {12[ab2-4cd]45} 12b45
} 1
test util-5.27 {Tcl_StringMatch} {
    string match {12[ab2-4cd]45} 12d45
} 1
test util-5.28 {Tcl_StringMatch} {
    string match {12[ab2-4cd]45} 12145
} 0
test util-5.29 {Tcl_StringMatch} {
    string match {12[ab2-4cd]45} 12545
} 0
test util-5.30 {Tcl_StringMatch: forwards range} {
    string match {[k-w]} "z"
} 0
test util-5.31 {Tcl_StringMatch: forwards range} {
    string match {[k-w]} "w"
} 1
test util-5.32 {Tcl_StringMatch: forwards range} {
    string match {[k-w]} "r"
} 1
test util-5.33 {Tcl_StringMatch: forwards range} {
    string match {[k-w]} "k"
} 1
test util-5.34 {Tcl_StringMatch: forwards range} {
    string match {[k-w]} "a"
} 0
test util-5.35 {Tcl_StringMatch: reverse range} {
    string match {[w-k]} "z"
} 0
test util-5.36 {Tcl_StringMatch: reverse range} {
    string match {[w-k]} "w"
} 1
test util-5.37 {Tcl_StringMatch: reverse range} {
    string match {[w-k]} "r"
} 1
test util-5.38 {Tcl_StringMatch: reverse range} {
    string match {[w-k]} "k"
} 1
test util-5.39 {Tcl_StringMatch: reverse range} {
    string match {[w-k]} "a"
} 0
test util-5.40 {Tcl_StringMatch: skip correct number of ']'} {
    string match {[A-]x} Ax
} 0
test util-5.41 {Tcl_StringMatch: skip correct number of ']'} {
    string match {[A-]]x} Ax
} 1
test util-5.42 {Tcl_StringMatch: skip correct number of ']'} {
    string match {[A-]]x} \ue1x
} 0
test util-5.43 {Tcl_StringMatch: skip correct number of ']'} {
    string match \[A-]\ue1]x \ue1x
} 1
test util-5.44 {Tcl_StringMatch: skip correct number of ']'} {
    string match {[A-]h]x} hx
} 1
test util-5.45 {Tcl_StringMatch} {
    # if (*pattern == '\0')
    # badly formed pattern, still treats as a set

    string match {[a} a
} 1
test util-5.46 {Tcl_StringMatch} {
    string match {a\*b} a*b
} 1
test util-5.47 {Tcl_StringMatch} {
    string match {a\*b} ab
} 0
test util-5.48 {Tcl_StringMatch} {
    string match {a\*\?\[\]\\\x} "a*?\[\]\\x"
} 1
test util-5.49 {Tcl_StringMatch} {
    string match ** ""
} 1
test util-5.50 {Tcl_StringMatch} {
    string match *. ""
} 0
test util-5.51 {Tcl_StringMatch} {
    string match "" ""
} 1

test util-6.1 {Tcl_PrintDouble - using tcl_precision} {
    concat x[expr 1.4]
} {x1.4}
test util-6.2 {Tcl_PrintDouble - using tcl_precision} {
    concat x[expr 1.39999999999]
} {x1.39999999999}
test util-6.3 {Tcl_PrintDouble - using tcl_precision} {
    concat x[expr 1.399999999999]
} {x1.4}
test util-6.4 {Tcl_PrintDouble - using tcl_precision} {
    set tcl_precision 5
    concat x[expr 1.123412341234]
} {x1.1234}
set tcl_precision 12
test util-6.5 {Tcl_PrintDouble - make sure there's a decimal point} {
    concat x[expr 2.0]
} {x2.0}
test util-6.6 {Tcl_PrintDouble - make sure there's a decimal point} {eformat} {
    concat x[expr 3.0e98]
} {x3e+98}

test util-7.1 {TclPrecTraceProc - unset callbacks} {
    set tcl_precision 7
    set x $tcl_precision
    unset tcl_precision
119
120
121
122
123
124
125
126
127
128
129
130
131
132















    interp create -safe child
    set x [child eval {
	list [catch {set tcl_precision 8} msg] $msg
    }]
    interp delete child
    list $x $tcl_precision
} {{1 {can't set "tcl_precision": can't modify precision from a safe interpreter}} 12}
test util-7.3 {TclPrecTraceProc - write traces, bogus values} {
    set tcl_precision 12
    list [catch {set tcl_precision abc} msg] $msg $tcl_precision
} {1 {can't set "tcl_precision": improper value for precision} 12}

set tcl_precision 12
concat ""






















|





|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    interp create -safe child
    set x [child eval {
	list [catch {set tcl_precision 8} msg] $msg
    }]
    interp delete child
    list $x $tcl_precision
} {{1 {can't set "tcl_precision": can't modify precision from a safe interpreter}} 12}
test util-7.4 {TclPrecTraceProc - write traces, bogus values} {
    set tcl_precision 12
    list [catch {set tcl_precision abc} msg] $msg $tcl_precision
} {1 {can't set "tcl_precision": improper value for precision} 12}

set tcl_precision 12

# cleanup
::tcltest::cleanupTests
return












Changes to tests/var.test.

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
# This file contains tests for the tclVar.c source file. Tests appear in
# the same order as the C code that they test. The set of tests is
# currently incomplete since it currently includes only new tests for
# code changed for the addition of Tcl namespaces. Other variable-
# related tests appear in several other test files including
# namespace.test, set.test, trace.test, and upvar.test.
#
# 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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) var.test 1.10 97/07/28 18:31:47
#


if {[string compare test [info procs test]] == 1} then {source defs}


catch {rename p ""}
catch {namespace delete test_ns_var}
catch {unset xx}
catch {unset x}
catch {unset y}
catch {unset i}
catch {unset a}
catch {unset arr}

test var-1.1 {TclLookupVar, TCL_PARSE_PART1 flag set} {
    catch {unset a}
    set x "incr"  ;# force no compilation and runtime call to Tcl_IncrCmd 
    set i 10
    set arr(foo) 37
    list [$x i] $i [$x arr(foo)] $arr(foo)
} {11 11 38 38}
test var-1.2 {TclLookupVar, TCL_GLOBAL_ONLY implies global namespace var} {











>




|


>
|
>










|







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
# This file contains tests for the tclVar.c source file. Tests appear in
# the same order as the C code that they test. The set of tests is
# currently incomplete since it currently includes only new tests for
# code changed for the addition of Tcl namespaces. Other variable-
# related tests appear in several other test files including
# namespace.test, set.test, trace.test, and upvar.test.
#
# 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: var.test,v 1.1.2.7 1999/03/24 02:49:50 hershey Exp $
#

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

catch {rename p ""}
catch {namespace delete test_ns_var}
catch {unset xx}
catch {unset x}
catch {unset y}
catch {unset i}
catch {unset a}
catch {unset arr}

test var-1.1 {TclLookupVar, Array handling} {
    catch {unset a}
    set x "incr"  ;# force no compilation and runtime call to Tcl_IncrCmd 
    set i 10
    set arr(foo) 37
    list [$x i] $i [$x arr(foo)] $arr(foo)
} {11 11 38 38}
test var-1.2 {TclLookupVar, TCL_GLOBAL_ONLY implies global namespace var} {
109
110
111
112
113
114
115
























































116
117
118
119
120
121
122
        list [set :] [set v:] [set x:y:] \
             ${:} ${v:} ${x:y:} \
             [expr {[lsearch [info vars] :] != -1}] \
             [expr {[lsearch [info vars] v:] != -1}] \
             [expr {[lsearch [info vars] x:y:] != -1}]
    }
} {123 456 789 123 456 789 1 1 1}

























































test var-2.1 {Tcl_LappendObjCmd, create var if new} {
    catch {unset x}
    lappend x 1 2
} {1 2}

test var-3.1 {MakeUpvar, TCL_NAMESPACE_ONLY not specified for other var} {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
        list [set :] [set v:] [set x:y:] \
             ${:} ${v:} ${x:y:} \
             [expr {[lsearch [info vars] :] != -1}] \
             [expr {[lsearch [info vars] v:] != -1}] \
             [expr {[lsearch [info vars] x:y:] != -1}]
    }
} {123 456 789 123 456 789 1 1 1}
test var-1.15 {TclLookupVar, resurrect variable via upvar to deleted namespace: compiled code path} {
    namespace eval test_ns_var {
	variable foo 2
    }
    proc p {} {
	variable ::test_ns_var::foo
	lappend result [catch {set foo} msg] $msg
	namespace delete ::test_ns_var
	lappend result [catch {set foo 3} msg] $msg
	lappend result [catch {set foo(3) 3} msg] $msg
    }
    p
} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
test var-1.16 {TclLookupVar, resurrect variable via upvar to deleted namespace: uncompiled code path} {
    namespace eval test_ns_var {
	variable result
	namespace eval subns {
	    variable foo 2
	}
	upvar 0 subns::foo foo
	lappend result [catch {set foo} msg] $msg
	namespace delete subns
	lappend result [catch {set foo 3} msg] $msg
	lappend result [catch {set foo(3) 3} msg] $msg
	namespace delete [namespace current]
	set result
    }
} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
test var-1.17 {TclLookupVar, resurrect array element via upvar to deleted array: compiled code path} {
    namespace eval test_ns_var {
	variable result
	proc p {} {
	    array set x {1 2 3 4}
	    upvar 0 x(1) foo
	    lappend result [catch {set foo} msg] $msg
	    unset x
	    lappend result [catch {set foo 3} msg] $msg
	}
	set result [p]
	namespace delete [namespace current]
	set result
    }
} {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
test var-1.18 {TclLookupVar, resurrect array element via upvar to deleted array: uncompiled code path} {
    namespace eval test_ns_var {
	variable result {}
	variable x
	array set x {1 2 3 4}
	upvar 0 x(1) foo
	lappend result [catch {set foo} msg] $msg
	unset x
	lappend result [catch {set foo 3} msg] $msg
	namespace delete [namespace current]
	set result
    }
} {0 2 1 {can't set "foo": upvar refers to element in deleted array}}

test var-2.1 {Tcl_LappendObjCmd, create var if new} {
    catch {unset x}
    lappend x 1 2
} {1 2}

test var-3.1 {MakeUpvar, TCL_NAMESPACE_ONLY not specified for other var} {
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















    }
    proc p {} {   ;# note this proc is at global :: scope
        variable test_ns_var::
        list [set {}] [info vars]
    }
    p
} {{My name is empty} {{}}}











test var-8.1 {TclDeleteVars, "unset" traces are called with fully-qualified var names} {
    catch {namespace delete test_ns_var}
    catch {unset a}
    namespace eval test_ns_var {
        variable v 123
        variable info ""

        proc traceUnset {name1 name2 op} {
            variable info
            set info [concat $info [list $name1 $name2 $op]]
        }

        trace var v u [namespace code traceUnset]
    }
    list [unset test_ns_var::v] $test_ns_var::info
} {{} {test_ns_var::v {} u}}





test var-9.1 {behaviour of TclSetVar without TCL_LEAVE_ERR_MSG flag} {



	testsetnoerr v 1
} 1


test var-9.2 {behaviour of TclGetVar without TCL_LEAVE_ERR_MSG flag} {
	catch {unset v}


	list [catch {testsetnoerr v} res] $res;



} {1 {before get}}
test var-9.3 {behaviour of TclGetVar without TCL_LEAVE_ERR_MSG flag} {
	catch {unset arr}
	set arr(1) 1;
	list [catch {testsetnoerr arr} res] $res;

} {1 {before get}}
test var-9.4 {behaviour of TclGetVar without TCL_LEAVE_ERR_MSG flag} {

	namespace eval ns {variable v nsv}

	testsetnoerr ns::v;
} nsv;

test var-9.5 {behaviour of TclGetVar without TCL_LEAVE_ERR_MSG flag} {
	catch {namespace delete ns}








	list [catch {testsetnoerr ns::v} res] $res;
} {1 {before get}}
test var-9.6 {behaviour of TclSetVar without TCL_LEAVE_ERR_MSG flag} {
	catch {unset arr}
	set arr(1) 1;

	list [catch {testsetnoerr arr 2} res] $res;

} {1 {before set}}
test var-9.7 {behaviour of TclSetVar without TCL_LEAVE_ERR_MSG flag} {
	catch {unset arr}
	set arr(1) 1;

	list [catch {testsetnoerr arr 2} res] $res;

} {1 {before set}}
test var-9.8 {behaviour of TclSetVar without TCL_LEAVE_ERR_MSG flag} {
    # this test currently fails, should not...
    # (some namespace function resets the interp while it should not)
    catch {namespace delete ns}












    list [catch {testsetnoerr ns::v 1} res] $res;

} {1 {before set}}










test var-9.9 {behaviour of TclSetVar without TCL_LEAVE_ERR_MSG flag} {
    proc readonly args {error "read-only"}
    set v 456
    trace var v w readonly

    list [catch {testsetnoerr v 2} msg] $msg

} {1 {before set}}






catch {namespace delete ns}
catch {unset arr}
catch {unset v}

catch {rename p ""}
catch {namespace delete test_ns_var}
catch {namespace delete test_ns_var2}
catch {unset xx}
catch {unset x}
catch {unset y}
catch {unset i}
catch {unset a}
catch {unset xxxxx}
catch {unset aaaaa}























>
>
>
>
>
>
>
>
>
>


















>
>
>
>
|
>
>
>
|
|
>
>
|
|
>
>
|
>
>
>
|
|
|
|
|
>
|
|
>
|
>
|
|
>
|
|
>
>
>
>
>
>
>
>
|
|
|
|
|
>
|
>
|
|
|
|
>
|
>
|
|
<
|
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
|



>
|
>
|
>
>
>
>
>
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
    }
    proc p {} {   ;# note this proc is at global :: scope
        variable test_ns_var::
        list [set {}] [info vars]
    }
    p
} {{My name is empty} {{}}}
test var-7.13 {Tcl_VariableObjCmd, variable named ":"} {
    namespace eval test_ns_var {
        variable : {My name is ":"}
	proc p {} {
	    variable :
	    list [set :] [info vars]
	}
	p
    }
} {{My name is ":"} :}

test var-8.1 {TclDeleteVars, "unset" traces are called with fully-qualified var names} {
    catch {namespace delete test_ns_var}
    catch {unset a}
    namespace eval test_ns_var {
        variable v 123
        variable info ""

        proc traceUnset {name1 name2 op} {
            variable info
            set info [concat $info [list $name1 $name2 $op]]
        }

        trace var v u [namespace code traceUnset]
    }
    list [unset test_ns_var::v] $test_ns_var::info
} {{} {test_ns_var::v {} u}}

if {[info commands testsetnoerr] == {}} {
    puts "This application hasn't been compiled with the \"testsetnoerr\""
    puts "command, so I can't test TclSetVar etc."
} else {
test var-9.1 {behaviour of TclGet/SetVar simple get/set} {
    catch {unset u}; catch {unset v}
    list \
       [set u a; testsetnoerr u] \
       [testsetnoerr v b] \
       [testseterr u] \
       [unset v; testseterr v b]
} [list {before get a} {before set b} {before get a} {before set b}]
test var-9.2 {behaviour of TclGet/SetVar namespace get/set} {
    catch {namespace delete ns}
    namespace eval ns {variable u a; variable v}
    list \
       [testsetnoerr ns::u] \
       [testsetnoerr ns::v b] \
       [testseterr ns::u] \
       [unset ns::v; testseterr ns::v b]
} [list {before get a} {before set b} {before get a} {before set b}]
test var-9.3 {behaviour of TclGetVar no variable} {
    catch {unset u}
    list \
       [catch {testsetnoerr u} res] $res \
       [catch {testseterr u} res] $res
} {1 {before get} 1 {can't read "u": no such variable}}
test var-9.4 {behaviour of TclGetVar no namespace variable} {
    catch {namespace delete ns}
    namespace eval ns {}
    list \
       [catch {testsetnoerr ns::w} res] $res \
       [catch {testseterr ns::w} res] $res
} {1 {before get} 1 {can't read "ns::w": no such variable}}
test var-9.5 {behaviour of TclGetVar no namespace} {
    catch {namespace delete ns}
    list \
       [catch {testsetnoerr ns::u} res] $res \
       [catch {testseterr ns::v} res] $res
} {1 {before get} 1 {can't read "ns::v": no such variable}}
test var-9.6 {behaviour of TclSetVar no namespace} {
    catch {namespace delete ns}
    list \
       [catch {testsetnoerr ns::v 1} res] $res \
       [catch {testseterr ns::v 1} res] $res
} {1 {before set} 1 {can't set "ns::v": parent namespace doesn't exist}}
test var-9.7 {behaviour of TclGetVar array variable} {
    catch {unset arr}
    set arr(1) 1;
    list \
       [catch {testsetnoerr arr} res] $res \
       [catch {testseterr arr} res] $res
} {1 {before get} 1 {can't read "arr": variable is array}}
test var-9.8 {behaviour of TclSetVar array variable} {
    catch {unset arr}
    set arr(1) 1
    list \
       [catch {testsetnoerr arr 2} res] $res \
       [catch {testseterr arr 2} res] $res
} {1 {before set} 1 {can't set "arr": variable is array}}
test var-9.9 {behaviour of TclGetVar read trace success} {

    proc resetvar {val name elem op} {upvar 1 $name v; set v $val}
    catch {unset u}; catch {unset v}
    set u 10
    trace var u r [list resetvar 1]
    trace var v r [list resetvar 2]
    list \
       [testsetnoerr u] \
       [testseterr v]
} {{before get 1} {before get 2}}
test var-9.10 {behaviour of TclGetVar read trace error} {
    proc writeonly args {error "write-only"}
    set v 456
    trace var v r writeonly
    list \
       [catch {testsetnoerr v} msg] $msg \
       [catch {testseterr v} msg] $msg
} {1 {before get} 1 {can't read "v": write-only}}
test var-9.11 {behaviour of TclSetVar write trace success} {
    proc doubleval {name elem op} {upvar 1 $name v; set v [expr {2 * $v}]}
    catch {unset u}; catch {unset v}
    set v 1
    trace var v w doubleval
    trace var u w doubleval
    list \
       [testsetnoerr u 2] \
       [testseterr v 3]
} {{before set 4} {before set 6}}
test var-9.12 {behaviour of TclSetVar write trace error} {
    proc readonly args {error "read-only"}
    set v 456
    trace var v w readonly
    list \
       [catch {testsetnoerr v 2} msg] $msg $v \
       [catch {testseterr v 3} msg] $msg $v
} {1 {before set} 2 1 {can't set "v": read-only} 3}
}
test var-10.1 {can't nest arrays with array set} {
   catch {unset arr}
   list [catch {array set arr(x) {a 1 b 2}} res] $res
} {1 {can't set "arr(x)(a)": variable isn't array}}

catch {namespace delete ns}
catch {unset arr}
catch {unset v}

catch {rename p ""}
catch {namespace delete test_ns_var}
catch {namespace delete test_ns_var2}
catch {unset xx}
catch {unset x}
catch {unset y}
catch {unset i}
catch {unset a}
catch {unset xxxxx}
catch {unset aaaaa}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/while-old.test.

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16

17

18
19
20
21
22
23
24
# Commands covered:  while
#
# This file contains the original set of tests for Tcl's while command.
# Since the while command is now compiled, a new set of tests covering
# the new implementation is in the file "while.test". 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-1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) while-old.test 1.14 97/05/16 10:44:19


if {[string compare test [info procs test]] == 1} then {source defs}


test while-old-1.1 {basic while loops} {
    set count 0
    while {$count < 10} {set count [expr $count+1]}
    set count
} 10
test while-old-1.2 {basic while loops} {










>




|

>
|
>







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
# Commands covered:  while
#
# This file contains the original set of tests for Tcl's while command.
# Since the while command is now compiled, a new set of tests covering
# the new implementation is in the file "while.test". 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-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: while-old.test,v 1.1.2.5 1999/03/24 02:49:50 hershey Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

test while-old-1.1 {basic while loops} {
    set count 0
    while {$count < 10} {set count [expr $count+1]}
    set count
} 10
test while-old-1.2 {basic while loops} {
107
108
109
110
111
112
113
















test while-old-5.1 {while return result} {
    while {0} {set a 400}
} {}
test while-old-5.2 {while return result} {
    set x 1
    while {$x} {set x 0}
} {}























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
test while-old-5.1 {while return result} {
    while {0} {set a 400}
} {}
test while-old-5.2 {while return result} {
    set x 1
    while {$x} {set x 0}
} {}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/while.test.

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
# Commands covered:  while
#
# 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) 1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#

# SCCS: @(#) @(#) while.test 1.9 97/07/02 16:41:35



if {[string compare test [info procs test]] == 1} then {source defs}

# Basic "while" operation.

catch {unset i}
catch {unset a}

test while-1.1 {TclCompileWhileCmd: missing test expression} {
    catch {while } msg
    set msg
} {wrong # args: should be "while test command"}
test while-1.2 {TclCompileWhileCmd: error in test expression} {
    set i 0
    catch {while {$i<}} msg
    set errorInfo
} {syntax error in expression "$i<"
    ("while" test expression)
    while compiling
"while {$i<}"}
test while-1.3 {TclCompileWhileCmd: error in test expression} {
    set err [catch {while {"a"+"b"} {error "loop aborted"}} msg]
    list $err $msg
} {1 {can't use non-numeric string as operand of "+"}}
test while-1.4 {TclCompileWhileCmd: multiline test expr} {
    set value 1
    while {($tcl_platform(platform) != "foobar1") && \







>




>
|
>
>
|
<












|




|







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
# Commands covered:  while
#
# 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) 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: while.test,v 1.1.2.6 1999/04/02 23:44:39 stanton Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}


# Basic "while" operation.

catch {unset i}
catch {unset a}

test while-1.1 {TclCompileWhileCmd: missing test expression} {
    catch {while } msg
    set msg
} {wrong # args: should be "while test command"}
test while-1.2 {TclCompileWhileCmd: error in test expression} {
    set i 0
    catch {while {$i<} break} msg
    set errorInfo
} {syntax error in expression "$i<"
    ("while" test expression)
    while compiling
"while {$i<} break"}
test while-1.3 {TclCompileWhileCmd: error in test expression} {
    set err [catch {while {"a"+"b"} {error "loop aborted"}} msg]
    list $err $msg
} {1 {can't use non-numeric string as operand of "+"}}
test while-1.4 {TclCompileWhileCmd: multiline test expr} {
    set value 1
    while {($tcl_platform(platform) != "foobar1") && \
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





































































































	}
	set a [concat $a $i]
        incr i
    }
    set a
} {1 3}

# Check "while", "break", "continue" and computed command names.

test while-4.1 {while and computed command names} {
    set i 0
    set z while
    $z {$i < 10} {
        incr i
    }
    set i
} 10
















































































































































test while-5.1 {break and computed command names} {
    set i 0
    set z break
    while 1 {
        if {$i > 10} $z
        incr i
    }
    set i
} 11




































































test while-6.1 {continue and computed command names} {
    set i 0
    set z continue
    while 1 {
        incr i
        if {$i < 10} $z
        break
    }
    set i
} 10












































































































|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
	}
	set a [concat $a $i]
        incr i
    }
    set a
} {1 3}

# Check "while" with computed command names.

test while-4.1 {while and computed command names} {
    set i 0
    set z while
    $z {$i < 10} {
        incr i
    }
    set i
} 10
test while-4.2 {while (not compiled): missing test expression} {
    set z while
    catch {$z } msg
    set msg
} {wrong # args: should be "while test command"}
test while-4.3 {while (not compiled): error in test expression} {
    set i 0
    set z while
    catch {$z {$i<} {set x 1}} msg
    set errorInfo
} {syntax error in expression "$i<"
    while executing
"$z {$i<} {set x 1}"}
test while-4.4 {while (not compiled): error in test expression} {
    set z while
    set err [catch {$z {"a"+"b"} {error "loop aborted"}} msg]
    list $err $msg
} {1 {can't use non-numeric string as operand of "+"}}
test while-4.5 {while (not compiled): multiline test expr} {
    set value 1
    set z while
    $z {($tcl_platform(platform) != "foobar1") && \
	    ($tcl_platform(platform) != "foobar2")} {
        incr value
        break
    }
    set value
} {2}
test while-4.6 {while (not compiled): non-numeric boolean test expr} {
    set value 1
    set z while
    $z {"true"} {
	incr value;
	if {$value > 5} {
	    break;
	}
    }
    set value
} 6
test while-4.7 {while (not compiled): test expr is enclosed in quotes} {
    set i 0
    set z while
    $z "$i > 5" {}
} {}
test while-4.8 {while (not compiled): missing command body} {
    set i 0
    set z while
    catch {$z {$i < 5} } msg
    set msg
} {wrong # args: should be "while test command"}
test while-4.9 {while (not compiled): error compiling command body} {
    set i 0
    set z while
    catch {$z {$i < 5} {set}} msg
    set errorInfo
} {wrong # args: should be "set varName ?newValue?"
    while compiling
"set"
    ("while" body line 1)
    invoked from within
"$z {$i < 5} {set}"}
test while-4.10 {while (not compiled): simple command body} {
    set a {}
    set i 1
    set z while
    $z {$i<6} {
	if $i==4 break
	set a [concat $a $i]
        incr i
    }
    set a
} {1 2 3}
test while-4.11 {while (not compiled): command body in quotes} {
    set a {}
    set i 1
    set z while
    $z {$i<6} "append a x; incr i"
    set a
} {xxxxx}
test while-4.12 {while (not compiled): computed command body} {
    set z while
    catch {unset x1}
    catch {unset bb}
    catch {unset x2}
    set x1 {append a x1; }
    set bb {break}
    set x2 {; append a x2; incr i}
    set a {}
    set i 1
    $z {$i<6} $x1$bb$x2
    set a
} {x1}
test while-4.13 {while (not compiled): long command body} {
    set a {}
    set z while
    set i 1
    $z {$i<6} {
	if $i==4 break
	if $i>5 continue
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
        incr i
    }
    set a
} {1 2 3}
test while-4.14 {while (not compiled): while command result} {
    set i 0
    set z while
    set a [$z {$i < 5} {incr i}]
    set a
} {}
test while-4.15 {while (not compiled): while command result} {
    set i 0
    set z while
    set a [$z {$i < 5} {if $i==3 break; incr i}]
    set a
} {}

# Check "break" with computed command names.

test while-5.1 {break and computed command names} {
    set i 0
    set z break
    while 1 {
        if {$i > 10} $z
        incr i
    }
    set i
} 11
test while-5.2 {break tests with computed command names} {
    set a {}
    set i 1
    set z break
    while {$i <= 4} {
	if {$i == 3} $z
	set a [concat $a $i]
        incr i
    }
    set a
} {1 2}
test while-5.3 {break tests, nested loops with computed command names} {
    set msg {}
    set i 1
    set z break
    while {$i <= 4} {
        set a 1
	while {$a <= 2} {
            if {$i>=2 && $a>=2} $z
            set msg [concat $msg "$i.$a"]
            incr a
        }
        incr i
    }
    set msg
} {1.1 1.2 2.1 3.1 4.1}
test while-5.4 {break tests, long command body with computed command names} {
    set a {}
    set i 1
    set z break
    while {$i<6} {
	if $i==2 {incr i; continue}
	if $i==5 $z
	if $i>5 continue
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if $i==4 $z
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
        incr i
    }
    set a
} {1 3}

# Check "continue" with computed command names.

test while-6.1 {continue and computed command names} {
    set i 0
    set z continue
    while 1 {
        incr i
        if {$i < 10} $z
        break
    }
    set i
} 10
test while-6.2 {continue tests} {
    set a {}
    set i 1
    set z continue
    while {$i <= 4} {
        incr i
	if {$i == 3} $z
	set a [concat $a $i]
    }
    set a
} {2 4 5}
test while-6.3 {continue tests with computed command names} {
    set a {}
    set i 1
    set z continue
    while {$i <= 4} {
        incr i
	if {$i != 2} $z
	set a [concat $a $i]
    }
    set a
} {2}
test while-6.4 {continue tests, nested loops with computed command names} {
    set msg {}
    set i 1
    set z continue
    while {$i <= 4} {
        incr i
        set a 1
	while {$a <= 2} {
            incr a
            if {$i>=3 && $a>=3} $z
            set msg [concat $msg "$i.$a"]
        }
    }
    set msg
} {2.2 2.3 3.2 4.2 5.2}
test while-6.5 {continue tests, long command body with computed command names} {
    set a {}
    set i 1
    set z continue
    while {$i<6} {
	if $i==2 {incr i; continue}
	if $i==4 break
	if $i>5 $z
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	if {$i>6 && $tcl_platform(machine)=="xxx"} {
	    catch {set a $a} msg
	    catch {incr i 5} msg
	    catch {incr i -5} msg
	}
	set a [concat $a $i]
        incr i
    }
    set a
} {1 3}

# Test for incorrect "double evaluation" semantics

test while-7.1 {delayed substitution of body} {knownBug} {
    set i 0
    while {[incr i] < 10} "
       set result $i
    "
    set result
} {0}

# cleanup
::tcltest::cleanupTests
return












Added tests/winConsole.test.







































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# This file tests the tclWinConsole.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) 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: winConsole.test,v 1.1.2.2 1999/03/24 02:49:51 hershey Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}


test winConsole-1.1 {Console file channel: non-blocking gets} \
	{pcOnly interactive} {
    
    set oldmode [fconfigure stdin]

    puts stdout "Enter abcdef<return> now: " nonewline
    flush stdout
    fileevent stdin readable {
	if {[gets stdin line] >= 0} {
	    set result $line
	} else {
	    set result "gets failed"
	}
    }

    fconfigure stdin -blocking 0 -buffering line

    set result {}
    vwait result

    #cleanup the fileevent
    fileevent stdin readable {}
    eval fconfigure stdin $oldmode

    set result

}  "abcdef"

#cleanup

::tcltest::cleanupTests
return

Added tests/winDde.test.

















































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# This file tests the tclWinDde.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) 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: winDde.test,v 1.1.2.2 1999/04/05 22:21:40 redman Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

if {$tcl_platform(platform) == "windows"} {
    if [catch {
	set lib [lindex [glob [file join [pwd] [file dirname \
		[info nameofexecutable]] tcldde*.dll]] 0]
	load $lib dde
    }] {
	puts "Unable to find the dde package. Skipping registry tests."
	::tcltest::cleanupTests
	return
    }
}

set scriptName script1.tcl


proc createChildProcess { ddeServerName } {
    
    file delete -force $::scriptName
    
    set f [open $::scriptName w+]
    puts $f {
	if [catch {
	    set lib [lindex [glob [file join [pwd] [file dirname \
		    [info nameofexecutable]] tcldde*.dll]] 0]
	    load $lib dde
	}] {
	    puts "Unable to find the dde package. Skipping registry tests."
	    ::tcltest::cleanupTests
	    return
	}
    }
    puts $f "dde servername $ddeServerName"
    puts $f {
	puts ready
	vwait done
	update
	exit
    }
    close $f
    
    set f [open "|$::tcltest $::scriptName" r]
    gets $f
    return $f
}

test winDde-1.1 {Settings the server's topic name} {pcOnly} {
    list [dde servername foobar] [dde servername] [dde servername self]
}  {foobar foobar self}

test winDde-2.1 {Checking for other services} {pcOnly} {
    expr [llength [dde services {} {}]] >= 0
} 1

test winDde-2.2 {Checking for existence, with service and topic specified} \
	{pcOnly} {
    llength [dde services TclEval self]
} 1

test winDde-2.3 {Checking for existence, with only the service specified} \
	{pcOnly} {
    expr [llength [dde services TclEval {}]] >= 1
} 1

test winDde-3.1 {DDE execute locally} {pcOnly} {
    set a ""
    dde execute TclEval self {set a "foo"}
    set a
} foo

test winDde-3.2 {DDE execute -async locally} {pcOnly} {
    set a ""
    dde execute -async TclEval self {set a "foo"}
    update
    set a
} foo

test winDde-3.3 {DDE request locally} {pcOnly} {
    set a ""
    dde execute TclEval self {set a "foo"}
    dde request TclEval self a
} foo

test winDde-3.4 {DDE eval locally} {pcOnly} {
    set a ""
    dde eval self set a "foo"
} foo

test winDde-4.1 {DDE execute remotely} {pcOnly} {
    set a ""
    set child [createChildProcess child]
    dde execute TclEval child {set a "foo"}

    dde execute TclEval child {set done 1}

    set a
} ""

test winDde-4.2 {DDE execute remotely} {pcOnly} {
    set a ""
    set child [createChildProcess child]
    dde execute -async TclEval child {set a "foo"}

    dde execute TclEval child {set done 1}

    set a
} ""

test winDde-4.3 {DDE request locally} {pcOnly} {
    set a ""
    set child [createChildProcess child]
    dde execute TclEval child {set a "foo"}
    set a [dde request TclEval child a]

    
    dde execute TclEval child {set done 1}

    set a
} foo

test winDde-4.4 {DDE eval locally} {pcOnly} {
    set a ""
    set child [createChildProcess child]
    set a [dde eval child set a "foo"]

    dde execute TclEval child {set done 1}

    set a
} foo


#cleanup
file delete -force $::scriptName
::tcltest::cleanupTests
return

Changes to tests/winFCmd.test.

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
# This file tests the tclWinFCmd.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) 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.
#
# SCCS: @(#) winFCmd.test 1.11 97/10/10 11:50:05
#

if {[string compare test [info procs test]] == 1} then {source defs}

if {$tcl_platform(platform) != "windows"} {
    return
}

proc createfile {file {string a}} {
    set f [open $file w]
    puts -nonewline $f $string
    close $f
    return $string







>




|


|
|
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17


18
19
20
21
22
23
24
# This file tests the tclWinFCmd.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) 1996-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: winFCmd.test,v 1.1.2.6 1999/03/24 02:49:52 hershey Exp $
#

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]


}

proc createfile {file {string a}} {
    set f [open $file w]
    puts -nonewline $f $string
    close $f
    return $string
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
	}
	if {$x != ""} {
	    catch {eval file delete -force -- $x}
	}
    }
}

set testConfig(cdrom) 0
set testConfig(exdev) 0
set testConfig(UNCPath} 0

# find a CD-ROM so we can test read-only filesystems.

set cdrom {}
set nodrive x:
foreach p {d e f g h i j k l m n o p q r s t u v w x y z} {
    set name ${p}:/dummy~~.fil







|
|
<







39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
	}
	if {$x != ""} {
	    catch {eval file delete -force -- $x}
	}
    }
}

set ::tcltest::testConfig(cdrom) 0
set ::tcltest::testConfig(exdev) 0


# find a CD-ROM so we can test read-only filesystems.

set cdrom {}
set nodrive x:
foreach p {d e f g h i j k l m n o p q r s t u v w x y z} {
    set name ${p}:/dummy~~.fil
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318

319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746

747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831



832








833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941





942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973





974




975
976
977
978







979
	        return $f
	    }
	}
    }
    return ""
}

if {$cdrom == ""} {
    puts "Couldn't find a CD-ROM.  Skipping tests that access CD-ROM."
    puts "If you have a CD-ROM, insert a data disk and rerun tests."
} else {
    set testConfig(cdrom) 1
    set cdfile [findfile $cdrom]
}

if {[file exists c:/] && [file exists d:/]} {
    catch {file delete d:/tf1}
    if {[catch {close [open d:/tf1 w]}] == 0} {
	file delete d:/tf1
	set testConfig(exdev) 1
    }
}

if {[file exists //bisque/icepick]} {
    set testConfig(UNCPath) 1
}

file delete -force -- td1
set foo [catch {open td1 w} testfile]
if {$foo} {
    set testConfig(longFileNames) 0
} else {
    close $testfile
    set testConfig(longFileNames) 1
    file delete -force -- td1
}

# A really long file name
# length of longname is 1216 chars, which should be greater than any static
# buffer or allowable filename.

set longname "abcdefghihjllmnopqrstuvwxyz01234567890"
append longname $longname
append longname $longname
append longname $longname
append longname $longname
append longname $longname

# Uses the "testfile" command instead of the "file" command.  The "file"
# command provides several layers of sanity checks on the arguments and
# it can be difficult to actually forward "insane" arguments to the
# low-level posix emulation layer.

test winFCmd-1.1 {TclpRenameFile: errno: EACCES} {cdrom} {
    list [catch {testfile mv $cdfile $cdrom/dummy~~.fil} msg] $msg
} {1 EACCES}
test winFCmd-1.2 {TclpRenameFile: errno: EEXIST} {
    cleanup
    file mkdir td1/td2/td3
    file mkdir td2
    list [catch {testfile mv td2 td1/td2} msg] $msg
} {1 EEXIST} 
test winFCmd-1.3 {TclpRenameFile: errno: EINVAL} {!$testConfig(win32s) || ("[lindex [file split [pwd]] end]" == "C:/")} {
    # Don't run this test under Win32s on a drive mounted from an NT 
    # machine; it causes the NT machine to die.

    cleanup
    list [catch {testfile mv / td1} msg] $msg
} {1 EINVAL}
test winFCmd-1.4 {TclpRenameFile: errno: EINVAL} {
    cleanup
    file mkdir td1
    list [catch {testfile mv td1 td1/td2} msg] $msg
} {1 EINVAL}
test winFCmd-1.5 {TclpRenameFile: errno: EISDIR} {
    cleanup
    file mkdir td1
    createfile tf1
    list [catch {testfile mv tf1 td1} msg] $msg
} {1 EISDIR}
test winFCmd-1.6 {TclpRenameFile: errno: ENOENT} {
    cleanup
    list [catch {testfile mv tf1 tf2} msg] $msg
} {1 ENOENT}
test winFCmd-1.7 {TclpRenameFile: errno: ENOENT} {
    cleanup
    list [catch {testfile mv "" tf2} msg] $msg
} {1 ENOENT}
test winFCmd-1.8 {TclpRenameFile: errno: ENOENT} {
    cleanup
    createfile tf1
    list [catch {testfile mv tf1 ""} msg] $msg
} {1 ENOENT}
test winFCmd-1.9 {TclpRenameFile: errno: ENOTDIR} {
    cleanup
    file mkdir td1
    createfile tf1
    list [catch {testfile mv td1 tf1} msg] $msg
} {1 ENOTDIR}
test winFCmd-1.10 {TclpRenameFile: errno: EXDEV} {exdev} {
    file delete -force d:/tf1
    file mkdir c:/tf1
    set msg [list [catch {testfile mv c:/tf1 d:/tf1} msg] $msg]
    file delete -force c:/tf1
    set msg
} {1 EXDEV}
test winFCmd-1.11 {TclpRenameFile: errno: EACCES} {
    cleanup
    set fd [open tf1 w]
    set msg [list [catch {testfile mv tf1 tf2} msg] $msg]
    close $fd
    set msg
} {1 EACCES}
test winFCmd-1.12 {TclpRenameFile: errno: EACCES} {
    cleanup
    createfile tf1
    set fd [open tf2 w]
    set msg [list [catch {testfile mv tf1 tf2} msg] $msg]
    close $fd
    set msg
} {1 EACCES}
test winFCmd-1.13 {TclpRenameFile: errno: EACCES} {
    cleanup
    list [catch {testfile mv nul tf1} msg] $msg
} {1 EACCES}
test winFCmd-1.14 {TclpRenameFile: errno: EACCES} {95} {
    cleanup
    createfile tf1
    list [catch {testfile mv tf1 nul} msg] $msg
} {1 EACCES}
test winFCmd-1.15 {TclpRenameFile: errno: EEXIST} {nt} {
    cleanup
    createfile tf1
    list [catch {testfile mv tf1 nul} msg] $msg
} {1 EEXIST}
test winFCmd-1.16 {TclpRenameFile: MoveFile() != FALSE} {
    cleanup
    createfile tf1 tf1
    testfile mv tf1 tf2
    list [file exists tf1] [contents tf2]
} {0 tf1}
test winFCmd-1.17 {TclpRenameFile: MoveFile() == FALSE} {
    cleanup
    list [catch {testfile mv tf1 tf2} msg] $msg
} {1 ENOENT} 
test winFCmd-1.18 {TclpRenameFile: srcAttr == -1} {
    cleanup
    list [catch {testfile mv tf1 tf2} msg] $msg
} {1 ENOENT} 
test winFCmd-1.19 {TclpRenameFile: errno == EACCES} {
    cleanup
    list [catch {testfile mv nul tf1} msg] $msg
} {1 EACCES}

# under 95, this would actually succed and move the current dir out from 
# under yourself.
test winFCmd-1.20 {TclpRenameFile: src is dir} {!95} {
    cleanup
    file delete /tf1
    list [catch {testfile mv [pwd] /tf1} msg] $msg
} {1 EACCES}
test winFCmd-1.21 {TclpRenameFile: obscenely long src} {!win32s} {
    # Really long file names cause all the file system calls to lock up,
    # endlessly throwing an access violation and retrying the operation.

    list [catch {testfile mv $longname tf1} msg] $msg
} {1 ENAMETOOLONG}
test winFCmd-1.22 {TclpRenameFile: obscenely long dst} {nt} {
    # return ENOENT if name is too long!
    cleanup
    createfile tf1
    list [catch {testfile mv tf1 $longname} msg] $msg
} {1 ENOENT}
test winFCmd-1.23 {TclpRenameFile: obscenely long dst} {95} {
    cleanup
    createfile tf1
    list [catch {testfile mv tf1 $longname} msg] $msg
} {1 ENAMETOOLONG}
test winFCmd-1.24 {TclpRenameFile: move dir into self} {
    cleanup
    file mkdir td1
    list [catch {testfile mv [pwd]/td1 td1/td2} msg] $msg
} {1 EINVAL}
test winFCmd-1.25 {TclpRenameFile: move a root dir} {!$testConfig(win32s) || ("[lindex [file split [pwd]] end]" == "C:/")} {
    # Don't run this test under Win32s on a drive mounted from an NT 
    # machine; it causes the NT machine to die.

    cleanup
    list [catch {testfile mv / c:/} msg] $msg
} {1 EINVAL}
test winFCmd-1.26 {TclpRenameFile: cross file systems} {cdrom} {
    cleanup
    file mkdir td1
    list [catch {testfile mv td1 $cdrom/td1} msg] $msg
} {1 EXDEV} 
test winFCmd-1.27 {TclpRenameFile: readonly fs} {cdrom} {
    cleanup
    list [catch {testfile mv $cdfile $cdrom/dummy~~.fil} msg] $msg
} {1 EACCES}
test winFCmd-1.28 {TclpRenameFile: open file} {
    cleanup
    set fd [open tf1 w]
    set msg [list [catch {testfile mv tf1 tf2} msg] $msg]
    close $fd
    set msg
} {1 EACCES}    
test winFCmd-1.29 {TclpRenameFile: errno == EEXIST} {
    cleanup
    createfile tf1
    createfile tf2
    testfile mv tf1 tf2
    list [file exist tf1] [file exist tf2]
} {0 1}
test winFCmd-1.30 {TclpRenameFile: src is dir} {
    cleanup
    file mkdir td1
    createfile tf1
    list [catch {testfile mv td1 tf1} msg] $msg
} {1 ENOTDIR} 
test winFCmd-1.31 {TclpRenameFile: dst is dir} {
    cleanup
    file mkdir td1
    file mkdir td2/td2
    list [catch {testfile mv td1 td2} msg] $msg
} {1 EEXIST}
test winFCmd-1.32 {TclpRenameFile: TclpRemoveDirectory fails} {
    cleanup
    file mkdir td1
    file mkdir td2/td2
    list [catch {testfile mv td1 td2} msg] $msg
} {1 EEXIST}
test winFCmd-1.33 {TclpRenameFile: TclpRemoveDirectory succeeds} {
    cleanup
    file mkdir td1/td2
    file mkdir td2
    testfile mv td1 td2
    list [file exist td1] [file exist td2] [file exist td2/td2]
} {0 1 1}
test winFCmd-1.34 {TclpRenameFile: After removing dst dir, MoveFile fails} {exdev} {

    file mkdir d:/td1
    testchmod 000 d:/td1
    set msg [list [catch {testfile mv c:/windows d:/td1} msg] $msg]
    set msg "$msg [file writable d:/td1]"
    file delete d:/td1
    set msg
} {1 EXDEV 0}
test winFCmd-1.35 {TclpRenameFile: src is dir, dst is not} {
    file mkdir td1
    createfile tf1
    list [catch {testfile mv td1 tf1} msg] $msg
} {1 ENOTDIR}
test winFCmd-1.36 {TclpRenameFile: src is not dir, dst is} {
    file mkdir td1
    createfile tf1
    list [catch {testfile mv tf1 td1} msg] $msg
} {1 EISDIR}
test winFCmd-1.37 {TclpRenameFile: src and dst not dir} {
    createfile tf1 tf1
    createfile tf2 tf2
    testfile mv tf1 tf2
    contents tf2
} {tf1}
test winFCmd-1.38 {TclpRenameFile: need to restore temp file} {
    # Can't figure out how to cause this. 
    # Need a file that can't be copied.
} {}

test winFCmd-2.1 {TclpCopyFile: errno: EACCES} {cdrom} {
    cleanup
    list [catch {testfile cp $cdfile $cdrom/dummy~~.fil} msg] $msg
} {1 EACCES}
test winFCmd-2.2 {TclpCopyFile: errno: EISDIR} {
    cleanup
    file mkdir td1
    list [catch {testfile cp td1 tf1} msg] $msg
} {1 EISDIR}
test winFCmd-2.3 {TclpCopyFile: errno: EISDIR} {
    cleanup
    createfile tf1
    file mkdir td1
    list [catch {testfile cp tf1 td1} msg] $msg
} {1 EISDIR}
test winFCmd-2.4 {TclpCopyFile: errno: ENOENT} {
    cleanup
    list [catch {testfile cp tf1 tf2} msg] $msg
} {1 ENOENT}
test winFCmd-2.5 {TclpCopyFile: errno: ENOENT} {
    cleanup
    list [catch {testfile cp "" tf2} msg] $msg
} {1 ENOENT}
test winFCmd-2.6 {TclpCopyFile: errno: ENOENT} {
    cleanup
    createfile tf1
    list [catch {testfile cp tf1 ""} msg] $msg
} {1 ENOENT}
test winFCmd-2.7 {TclpCopyFile: errno: EACCES} {!nt} {
    cleanup
    createfile tf1
    set fd [open tf2 w]
    set msg [list [catch {testfile cp tf1 tf2} msg] $msg]
    close $fd
    set msg
} {1 EACCES}
test winFCmd-2.8 {TclpCopyFile: errno: EACCES} {nt} {
    cleanup
    list [catch {testfile cp nul tf1} msg] $msg
} {1 EACCES}
test winFCmd-2.9 {TclpCopyFile: errno: ENOENT} {95} {
    cleanup
    list [catch {testfile cp nul tf1} msg] $msg
} {1 ENOENT}
test winFCmd-2.10 {TclpCopyFile: CopyFile succeeds} {
    cleanup
    createfile tf1 tf1
    testfile cp tf1 tf2
    list [contents tf1] [contents tf2]
} {tf1 tf1}
test winFCmd-2.11 {TclpCopyFile: CopyFile succeeds} {
    cleanup
    createfile tf1 tf1
    createfile tf2 tf2
    testfile cp tf1 tf2
    list [contents tf1] [contents tf2]
} {tf1 tf1}
test winFCmd-2.12 {TclpCopyFile: CopyFile succeeds} {
    cleanup
    createfile tf1 tf1
    testchmod 000 tf1
    testfile cp tf1 tf2
    list [contents tf2] [file writable tf2]
} {tf1 0}
test winFCmd-2.13 {TclpCopyFile: CopyFile fails} {
    cleanup
    createfile tf1
    file mkdir td1
    list [catch {testfile cp tf1 td1} msg] $msg
} {1 EISDIR} 
test winFCmd-2.14 {TclpCopyFile: errno == EACCES} {
    cleanup
    file mkdir td1
    list [catch {testfile cp td1 tf1} msg] $msg
} {1 EISDIR}
test winFCmd-2.15 {TclpCopyFile: src is directory} {
    cleanup
    file mkdir td1
    list [catch {testfile cp td1 tf1} msg] $msg
} {1 EISDIR}
test winFCmd-2.16 {TclpCopyFile: dst is directory} {
    cleanup
    createfile tf1
    file mkdir td1
    list [catch {testfile cp tf1 td1} msg] $msg
} {1 EISDIR}
test winFCmd-2.17 {TclpCopyFile: dst is readonly} {
    cleanup
    createfile tf1 tf1
    createfile tf2 tf2
    testchmod 000 tf2
    testfile cp tf1 tf2
    list [file writable tf2] [contents tf2]
} {1 tf1}
test winFCmd-2.18 {TclpCopyFile: still can't copy onto dst} {95} {
    cleanup
    createfile tf1
    createfile tf2
    testchmod 000 tf2
    set fd [open tf2]
    set msg [list [catch {testfile cp tf1 tf2} msg] $msg]
    close $fd
    set msg "$msg [file writable tf2]"
} {1 EACCES 0}    

test winFCmd-3.1 {TclpDeleteFile: errno: EACCES} {cdrom} {
    list [catch {testfile rm $cdfile $cdrom/dummy~~.fil} msg] $msg
} {1 EACCES}
test winFCmd-3.2 {TclpDeleteFile: errno: EISDIR} {
    cleanup
    file mkdir td1
    list [catch {testfile rm td1} msg] $msg
} {1 EISDIR} 
test winFCmd-3.3 {TclpDeleteFile: errno: ENOENT} {
    cleanup
    list [catch {testfile rm tf1} msg] $msg
} {1 ENOENT}
test winFCmd-3.4 {TclpDeleteFile: errno: ENOENT} {
    cleanup
    list [catch {testfile rm ""} msg] $msg
} {1 ENOENT}
test winFCmd-3.5 {TclpDeleteFile: errno: EACCES} {
    cleanup
    set fd [open tf1 w]
    set msg [list [catch {testfile rm tf1} msg] $msg]
    close $fd
    set msg
} {1 EACCES}
test winFCmd-3.6 {TclpDeleteFile: errno: EACCES} {
    cleanup
    list [catch {testfile rm nul} msg] $msg
} {1 EACCES}
test winFCmd-3.7 {TclpDeleteFile: DeleteFile succeeds} {
    cleanup
    createfile tf1
    testfile rm tf1
    file exist tf1
} {0}
test winFCmd-3.8 {TclpDeleteFile: DeleteFile fails} {
    cleanup
    file mkdir td1
    list [catch {testfile rm td1} msg] $msg
} {1 EISDIR}
test winFCmd-3.9 {TclpDeleteFile: errno == EACCES} {
    cleanup
    set fd [open tf1 w]
    set msg [list [catch {testfile rm tf1} msg] $msg]
    close $fd
    set msg
} {1 EACCES}
test winFCmd-3.10 {TclpDeleteFile: path is readonly} {
    cleanup
    createfile tf1
    testchmod 000 tf1
    testfile rm tf1
    file exists tf1
} {0}
test winFCmd-3.11 {TclpDeleteFile: still can't remove path} {
    cleanup
    set fd [open tf1 w]
    testchmod 000 tf1
    set msg [list [catch {testfile rm tf1} msg] $msg]
    close $fd
    set msg
} {1 EACCES}

test winFCmd-4.1 {TclpCreateDirectory: errno: EACCES} {cdrom nt} {
    list [catch {testfile mkdir $cdrom/dummy~~.dir} msg] $msg
} {1 EACCES}
test winFCmd-4.2 {TclpCreateDirectory: errno: EACCES} {cdrom 95} {
    list [catch {testfile mkdir $cdrom/dummy~~.dir} msg] $msg
} {1 ENOSPC}
test winFCmd-4.3 {TclpCreateDirectory: errno: EEXIST} {
    cleanup
    file mkdir td1
    list [catch {testfile mkdir td1} msg] $msg
} {1 EEXIST}
test winFCmd-4.4 {TclpCreateDirectory: errno: ENOENT} {
    cleanup
    list [catch {testfile mkdir td1/td2} msg] $msg
} {1 ENOENT}
test winFCmd-4.5 {TclpCreateDirectory: CreateDirectory succeeds} {
    cleanup
    testfile mkdir td1
    file type td1
} {directory}

test winFCmd-5.1 {TclpCopyDirectory: calls TraverseWinTree} {
    cleanup
    file mkdir td1
    testfile cpdir td1 td2
    list [file type td1] [file type td2]
} {directory directory}

test winFCmd-6.1 {TclpRemoveDirectory: errno: EACCES} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    testfile rmdir td1
    file exist td1
} {0}
test winFCmd-6.2 {TclpRemoveDirectory: errno: EEXIST} {
    cleanup
    file mkdir td1/td2
    list [catch {testfile rmdir td1} msg] $msg
} {1 {td1 EEXIST}}
test winFCmd-6.3 {TclpRemoveDirectory: errno: EACCES} {
    # can't test this w/o removing everything on your hard disk first!
    # testfile rmdir /
} {}
test winFCmd-6.4 {TclpRemoveDirectory: errno: ENOENT} {
    cleanup
    list [catch {testfile rmdir td1} msg] $msg
} {1 {td1 ENOENT}}
test winFCmd-6.5 {TclpRemoveDirectory: errno: ENOENT} {
    cleanup
    list [catch {testfile rmdir ""} msg] $msg
} {1 ENOENT}
test winFCmd-6.6 {TclpRemoveDirectory: errno: ENOTDIR} {
    cleanup
    createfile tf1
    list [catch {testfile rmdir tf1} msg] $msg
} {1 {tf1 ENOTDIR}}
test winFCmd-6.7 {TclpRemoveDirectory: RemoveDirectory succeeds} {
    cleanup
    file mkdir td1
    testfile rmdir td1
    file exists td1
} {0}
test winFCmd-6.8 {TclpRemoveDirectory: RemoveDirectory fails} {
    cleanup
    createfile tf1
    list [catch {testfile rmdir tf1} msg] $msg
} {1 {tf1 ENOTDIR}}
test winFCmd-6.9 {TclpRemoveDirectory: errno == EACCES} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    testfile rmdir td1
    file exists td1
} {0}
test winFCmd-6.10 {TclpRemoveDirectory: attr == -1} {!nt} {
    cleanup
    list [catch {testfile rmdir nul} msg] $msg
} {1 {nul EACCES}}
test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} {nt} {
    cleanup
    list [catch {testfile rmdir /} msg] $msg
} {1 {\ EACCES}}
test winFCmd-6.12 {TclpRemoveDirectory: errno == EACCES} {!nt} {
    cleanup
    createfile tf1
    list [catch {testfile rmdir tf1} msg] $msg
} {1 {tf1 ENOTDIR}}
test winFCmd-6.13 {TclpRemoveDirectory: write-protected} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    testfile rmdir td1
    file exists td1
} {0}
test winFCmd-6.14 {TclpRemoveDirectory: check if empty dir} {!nt} {
    cleanup
    file mkdir td1/td2
    list [catch {testfile rmdir td1} msg] $msg
} {1 {td1 EEXIST}}
test winFCmd-6.15 {TclpRemoveDirectory: !recursive} {
    cleanup
    file mkdir td1/td2
    list [catch {testfile rmdir td1} msg] $msg
} {1 {td1 EEXIST}}
test winFCmd-6.16 {TclpRemoveDirectory: recursive, but errno != EEXIST} {
    cleanup
    createfile tf1
    list [catch {testfile rmdir -force tf1} msg] $msg
} {1 {tf1 ENOTDIR}}
test winFCmd-6.17 {TclpRemoveDirectory: calls TraverseWinTree} {
    cleanup
    file mkdir td1/td2
    testfile rmdir -force td1
    file exists td1
} {0}

test winFCmd-7.1 {TraverseWinTree: targetPtr == NULL} {
    cleanup
    file mkdir td1/td2/td3
    testfile rmdir -force td1
    file exists td1
} {0}
test winFCmd-7.2 {TraverseWinTree: targetPtr != NULL} {
    cleanup
    file mkdir td1/td2/td3
    testfile cpdir td1 td2
    list [file exists td1] [file exists td2]
} {1 1}
test winFCmd-7.3 {TraverseWinTree: sourceAttr == -1} {
    cleanup
    list [catch {testfile cpdir td1 td2} msg] $msg
} {1 {td1 ENOENT}}
test winFCmd-7.4 {TraverseWinTree: source isn't directory} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    contents td2/tf1
} {tf1}
test winFCmd-7.5 {TraverseWinTree: call TraversalCopy: DOTREE_F} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    contents td2/tf1
} {tf1}
test winFCmd-7.6 {TraverseWinTree: call TraversalDelete: DOTREE_F} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile rmdir -force td1
    file exists td1
} {0}
test winFCmd-7.7 {TraverseWinTree: append \ to source if necessary} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    contents td2/tf1
} {tf1}    
test winFCmd-7.8 {TraverseWinTree: append \ to source if necessary} {!nt && cdrom} {
    list [catch {testfile rmdir $cdrom/} msg] $msg
} "1 {$cdrom\\ EEXIST}"
test winFCmd-7.9 {TraverseWinTree: append \ to source if necessary} {nt cdrom} {
    list [catch {testfile rmdir $cdrom/} msg] $msg
} "1 {$cdrom\\ EACCES}"
test winFCmd-7.10 {TraverseWinTree: can't read directory: handle == INVALID} {

    # can't make it happen
} {}
test winFCmd-7.11 {TraverseWinTree: call TraversalCopy: DOTREE_PRED} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    list [file exists td2] [file writable td2]
} {1 0}
test winFCmd-7.12 {TraverseWinTree: call TraversalDelete: DOTREE_PRED} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile rmdir -force td1
    file exists td1
} {0}
test winFCmd-7.13 {TraverseWinTree: append \ to target if necessary} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    contents td2/tf1
} {tf1}    
test winFCmd-7.14 {TraverseWinTree: append \ to target if necessary} {!nt} {
    cleanup
    file mkdir td1
    list [catch {testfile cpdir td1 /} msg] $msg
} {1 {\ EEXIST}}
test winFCmd-7.15 {TraverseWinTree: append \ to target if necessary} {nt} {
    cleanup
    file mkdir td1
    list [catch {testfile cpdir td1 /} msg] $msg
} {1 {\ EACCES}}
test winFCmd-7.16 {TraverseWinTree: recurse on files: no files} {
    cleanup
    file mkdir td1
    testfile cpdir td1 td2
} {}
test winFCmd-7.17 {TraverseWinTree: recurse on files: one file} {
    cleanup
    file mkdir td1
    createfile td1/td2
    testfile cpdir td1 td2
    glob td2/*
} {td2/td2}
test winFCmd-7.18 {TraverseWinTree: recurse on files: several files and dir} {

    cleanup
    file mkdir td1
    createfile td1/tf1
    createfile td1/tf2
    file mkdir td1/td2/td3
    createfile td1/tf3
    createfile td1/tf4
    testfile cpdir td1 td2
    glob td2/*
} {td2/tf1 td2/tf2 td2/td2 td2/tf3 td2/tf4}
test winFCmd-7.19 {TraverseWinTree: call TraversalCopy: DOTREE_POSTD} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    list [file exists td2] [file writable td2]
} {1 0}
test winFCmd-7.20 {TraverseWinTree: call TraversalDelete: DOTREE_POSTD} {

    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile rmdir -force td1
    file exists td1
} {0}
test winFCmd-7.21 {TraverseWinTree: fill errorPtr} {
    cleanup
    list [catch {testfile cpdir td1 td2} msg] $msg
} {1 {td1 ENOENT}}

test winFCmd-8.1 {TraversalCopy: DOTREE_F} {
    cleanup
    file mkdir td1
    list [catch {testfile cpdir td1 td1} msg] $msg
} {1 {td1 EEXIST}}
test winFCmd-8.2 {TraversalCopy: DOTREE_PRED} {
    cleanup
    file mkdir td1/td2
    testchmod 000 td1
    testfile cpdir td1 td2
    list [file writable td1] [file writable td1/td2]
} {0 1}
test winFCmd-8.3 {TraversalCopy: DOTREE_POSTD} {
    cleanup
    file mkdir td1
    testfile cpdir td1 td2
} {}

test winFCmd-9.1 {TraversalDelete: DOTREE_F} {
    cleanup
    file mkdir td1
    createfile td1/tf1
    testfile rmdir -force td1
} {}
test winFCmd-9.2 {TraversalDelete: DOTREE_F} {95} {
    cleanup
    file mkdir td1
    set fd [open td1/tf1 w]
    set msg [list [catch {testfile rmdir -force td1} msg] $msg]
    close $fd
    set msg
} {1 {td1\tf1 EACCES}}
test winFCmd-9.3 {TraversalDelete: DOTREE_PRED} {
    cleanup
    file mkdir td1/td2
    testchmod 000 td1
    testfile rmdir -force td1
    file exists td1
} {0}
test winFCmd-9.4 {TraversalDelete: DOTREE_POSTD} {
    cleanup
    file mkdir td1/td1/td3/td4/td5
    testfile rmdir -force td1
} {}

test winFCmd-10.1 {AttributesPosixError - get} {
    cleanup
    list [catch {file attributes td1 -archive} msg] $msg
} {1 {cannot get attribute "-archive" for file "td1": no such file or directory}}
test winFCmd-10.2 {AttributesPosixError - set} {
    cleanup
    list [catch {file attributes td1 -archive 0} msg] $msg
} {1 {cannot set attribute "-archive" for file "td1": no such file or directory}}

test winFCmd-11.1 {GetWinFileAttributes} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -archive} msg] $msg [cleanup]
} {0 1 {}}
test winFCmd-11.2 {GetWinFileAttributes} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -readonly} msg] $msg [cleanup]
} {0 0 {}}
test winFCmd-11.3 {GetWinFileAttributes} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -hidden} msg] $msg [cleanup]
} {0 0 {}}
test winFCmd-11.4 {GetWinFileAttributes} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -system} msg] $msg [cleanup]
} {0 0 {}}












test winFCmd-12.1 {ConvertFileNameFormat} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -longname]} msg] $msg [cleanup]
} {0 td1 {}}
test winFCmd-12.2 {ConvertFileNameFormat} {
    cleanup
    file mkdir td1
    close [open td1/td1 w]
    list [catch {string tolower [file attributes td1/td1 -longname]} msg] $msg [cleanup]
} {0 td1/td1 {}}
test winFCmd-12.3 {ConvertFileNameFormat} {
    cleanup
    file mkdir td1
    file mkdir td1/td2
    close [open td1/td3 w]
    list [catch {string tolower [file attributes td1/td2/../td3 -longname]} msg] $msg [cleanup]
} {0 td1/td2/../td3 {}}
test winFCmd-12.4 {ConvertFileNameFormat} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes ./td1 -longname]} msg] $msg [cleanup]
} {0 ./td1 {}}
test winFCmd-12.5 {ConvertFileNameFormat: absolute path} {
    list [file attributes / -longname] [file attributes \\ -longname]
} {/ /}
test winFCmd-12.6 {ConvertFileNameFormat: absolute path with drive} {
    catch {file delete -force -- c:/td1}
    close [open c:/td1 w]
    list [catch {string tolower [file attributes c:/td1 -longname]} msg] $msg [file delete -force -- c:/td1]
} {0 c:/td1 {}}
test winFCmd-12.7 {ConvertFileNameFormat} {UNCPath} {
    catch {file delete -force -- //bisque/icepick/test/td1}
    close [open //bisque/icepick/test/td1 w]
    list [catch {string tolower [file attributes //bisque/icepick/test/td1 -longname]} msg] $msg [file delete -force -- //bisque/icepick/test/td1]
} {0 //bisque/icepick/test/td1 {}}
test winFCmd-12.8 {ConvertFileNameFormat} {longFileNames} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -longname]} msg] $msg [cleanup]
} {0 td1 {}}
test winFCmd-12.9 {ConvertFileNameFormat} {win32s} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -longname]} msg] $msg [cleanup]
} {0 td1 {}}
test winFCmd-12.10 {ConvertFileNameFormat} {longFileNames} {
    cleanup
    close [open td1td1td1 w]
    list [catch {file attributes td1td1td1 -shortname}] [cleanup]
} {0 {}}
test winFCmd-12.11 {ConvertFileNameFormat} {longFileNames} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -shortname]} msg] $msg [cleanup]
} {0 td1 {}}

test winFCmd-13.1 {GetWinFileLongName} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -longname]} msg] $msg [cleanup]
} {0 td1 {}}

test winFCmd-14.1 {GetWinFileShortName} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -shortname]} msg] $msg [cleanup]
} {0 td1 {}}

test winFCmd-15.1 {SetWinFileAttributes} {
    cleanup
    list [catch {file attributes td1 -archive 0} msg] $msg
} {1 {cannot set attribute "-archive" for file "td1": no such file or directory}}
test winFCmd-15.2 {SetWinFileAttributes - archive} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -archive 1} msg] $msg [file attributes td1 -archive] [cleanup]
} {0 {} 1 {}}
test winFCmd-15.3 {SetWinFileAttributes - archive} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -archive 0} msg] $msg [file attributes td1 -archive] [cleanup]
} {0 {} 0 {}}
test winFCmd-15.4 {SetWinFileAttributes - hidden} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -hidden 1} msg] $msg [file attributes td1 -hidden] [file attributes td1 -hidden 0] [cleanup]
} {0 {} 1 {} {}}
test winFCmd-15.5 {SetWinFileAttributes - hidden} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -hidden 0} msg] $msg [file attributes td1 -hidden] [cleanup]
} {0 {} 0 {}}
test winFCmd-15.6 {SetWinFileAttributes - readonly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -readonly 1} msg] $msg [file attributes td1 -readonly] [cleanup]
} {0 {} 1 {}}
test winFCmd-15.7 {SetWinFileAttributes - readonly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -readonly 0} msg] $msg [file attributes td1 -readonly] [cleanup]
} {0 {} 0 {}}
test winFCmd-15.8 {SetWinFileAttributes - system} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -system 1} msg] $msg [file attributes td1 -system] [cleanup]
} {0 {} 1 {}}
test winFCmd-15.9 {SetWinFileAttributes - system} {





    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -system 0} msg] $msg [file attributes td1 -system] [cleanup]
} {0 {} 0 {}}
test winFCmd-15.10 {SetWinFileAttributes - failing} {cdrom} {
    cleanup
    catch {file attributes $cdfile -archive 1}
} {1}

cleanup

return

foreach source {tef ted tnf tnd "" nul com1} {
    foreach chmodsrc {000 755} {
        foreach dest "tfn tfe tdn tdempty tdfull td1/td2 $p $p/td1 {} nul" {
	    foreach chmoddst {000 755} {
		puts hi
		cleanup
		file delete -force ted tef
		file mkdir ted
		createfile tef
		createfile tfe
		file mkdir tdempty
		file mkdir tdfull/td1/td2

		catch {testchmod $chmodsrc $source}
		catch {testchmod $chmoddst $dest}

		if [catch {file rename $source $dest} msg] {
		    puts "file rename $source ($chmodsrc) $dest ($chmoddst)"
		    puts $msg





		}




	    }
	}
    }
}















|
<
<
<
|







|



<
<
<
<



|


|



















|


|





|
<
<
<



|




|





|



|



|




|





|






|






|







|













|





|



|



|



>
|
|
<




|
<
<
|


|
<
<
<
<
<
<




|




|
<
<
<



|




|



|






|






|





|





|





|






|
>







|




|




|





|




|



|




|





|



|



|




|















|





|






|






|





|




|




|





|


















|


|




|



|



|






|



|





|




|






|






|








|


|


|




|



|





|






|






|




|



|



|



|




|





|




|






|







|




|






|




|




|




|






|





|





|



|






|






|






|






|





|
>


|







|






|






|









|




|






|
>








|
|
|







|
>






|




|




|






|





|













|






|





|


|
|


|

|




|




|




|




>
>
>

>
>
>
>
>
>
>
>
|




|





|






|




|


|




|
<
<
|
|
|




<
<
<
<
<
|




|





|





|





|


|
|




|




|




|




|




|




|




|
>
>
>
>
>

<
<
<
<
<



<
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
|
>
>
>
>
|
|
|
|
>
>
>
>
>
>
>

79
80
81
82
83
84
85
86



87
88
89
90
91
92
93
94
95
96
97
98




99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224

225
226
227
228
229


230
231
232
233






234
235
236
237
238
239
240
241
242
243



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856


857
858
859
860
861
862
863





864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932





933
934
935

936

937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
	        return $f
	    }
	}
    }
    return ""
}

if {$cdrom != ""} {



    set ::tcltest::testConfig(cdrom) 1
    set cdfile [findfile $cdrom]
}

if {[file exists c:/] && [file exists d:/]} {
    catch {file delete d:/tf1}
    if {[catch {close [open d:/tf1 w]}] == 0} {
	file delete d:/tf1
	set ::tcltest::testConfig(exdev) 1
    }
}





file delete -force -- td1
set foo [catch {open td1 w} testfile]
if {$foo} {
    set ::tcltest::testConfig(longFileNames) 0
} else {
    close $testfile
    set ::tcltest::testConfig(longFileNames) 1
    file delete -force -- td1
}

# A really long file name
# length of longname is 1216 chars, which should be greater than any static
# buffer or allowable filename.

set longname "abcdefghihjllmnopqrstuvwxyz01234567890"
append longname $longname
append longname $longname
append longname $longname
append longname $longname
append longname $longname

# Uses the "testfile" command instead of the "file" command.  The "file"
# command provides several layers of sanity checks on the arguments and
# it can be difficult to actually forward "insane" arguments to the
# low-level posix emulation layer.

test winFCmd-1.1 {TclpRenameFile: errno: EACCES} {pcOnly cdrom} {
    list [catch {testfile mv $cdfile $cdrom/dummy~~.fil} msg] $msg
} {1 EACCES}
test winFCmd-1.2 {TclpRenameFile: errno: EEXIST} {pcOnly} {
    cleanup
    file mkdir td1/td2/td3
    file mkdir td2
    list [catch {testfile mv td2 td1/td2} msg] $msg
} {1 EEXIST} 
test winFCmd-1.3 {TclpRenameFile: errno: EINVAL} {pcOnly} {



    cleanup
    list [catch {testfile mv / td1} msg] $msg
} {1 EINVAL}
test winFCmd-1.4 {TclpRenameFile: errno: EINVAL} {pcOnly} {
    cleanup
    file mkdir td1
    list [catch {testfile mv td1 td1/td2} msg] $msg
} {1 EINVAL}
test winFCmd-1.5 {TclpRenameFile: errno: EISDIR} {pcOnly} {
    cleanup
    file mkdir td1
    createfile tf1
    list [catch {testfile mv tf1 td1} msg] $msg
} {1 EISDIR}
test winFCmd-1.6 {TclpRenameFile: errno: ENOENT} {pcOnly} {
    cleanup
    list [catch {testfile mv tf1 tf2} msg] $msg
} {1 ENOENT}
test winFCmd-1.7 {TclpRenameFile: errno: ENOENT} {pcOnly} {
    cleanup
    list [catch {testfile mv "" tf2} msg] $msg
} {1 ENOENT}
test winFCmd-1.8 {TclpRenameFile: errno: ENOENT} {pcOnly} {
    cleanup
    createfile tf1
    list [catch {testfile mv tf1 ""} msg] $msg
} {1 ENOENT}
test winFCmd-1.9 {TclpRenameFile: errno: ENOTDIR} {pcOnly} {
    cleanup
    file mkdir td1
    createfile tf1
    list [catch {testfile mv td1 tf1} msg] $msg
} {1 ENOTDIR}
test winFCmd-1.10 {TclpRenameFile: errno: EXDEV} {pcOnly exdev} {
    file delete -force d:/tf1
    file mkdir c:/tf1
    set msg [list [catch {testfile mv c:/tf1 d:/tf1} msg] $msg]
    file delete -force c:/tf1
    set msg
} {1 EXDEV}
test winFCmd-1.11 {TclpRenameFile: errno: EACCES} {pcOnly} {
    cleanup
    set fd [open tf1 w]
    set msg [list [catch {testfile mv tf1 tf2} msg] $msg]
    close $fd
    set msg
} {1 EACCES}
test winFCmd-1.12 {TclpRenameFile: errno: EACCES} {pcOnly} {
    cleanup
    createfile tf1
    set fd [open tf2 w]
    set msg [list [catch {testfile mv tf1 tf2} msg] $msg]
    close $fd
    set msg
} {1 EACCES}
test winFCmd-1.13 {TclpRenameFile: errno: EACCES} {pcOnly} {
    cleanup
    list [catch {testfile mv nul tf1} msg] $msg
} {1 EACCES}
test winFCmd-1.14 {TclpRenameFile: errno: EACCES} {95} {
    cleanup
    createfile tf1
    list [catch {testfile mv tf1 nul} msg] $msg
} {1 EACCES}
test winFCmd-1.15 {TclpRenameFile: errno: EEXIST} {nt} {
    cleanup
    createfile tf1
    list [catch {testfile mv tf1 nul} msg] $msg
} {1 EEXIST}
test winFCmd-1.16 {TclpRenameFile: MoveFile() != FALSE} {pcOnly} {
    cleanup
    createfile tf1 tf1
    testfile mv tf1 tf2
    list [file exists tf1] [contents tf2]
} {0 tf1}
test winFCmd-1.17 {TclpRenameFile: MoveFile() == FALSE} {pcOnly} {
    cleanup
    list [catch {testfile mv tf1 tf2} msg] $msg
} {1 ENOENT} 
test winFCmd-1.18 {TclpRenameFile: srcAttr == -1} {pcOnly} {
    cleanup
    list [catch {testfile mv tf1 tf2} msg] $msg
} {1 ENOENT} 
test winFCmd-1.19 {TclpRenameFile: errno == EACCES} {pcOnly} {
    cleanup
    list [catch {testfile mv nul tf1} msg] $msg
} {1 EACCES}
test winFCmd-1.20 {TclpRenameFile: src is dir} {nt} {
    # under 95, this would actually succeed and move the current dir out from 
    # under the current process!

    cleanup
    file delete /tf1
    list [catch {testfile mv [pwd] /tf1} msg] $msg
} {1 EACCES}
test winFCmd-1.21 {TclpRenameFile: long src} {pcOnly} {


    cleanup
    list [catch {testfile mv $longname tf1} msg] $msg
} {1 ENAMETOOLONG}
test winFCmd-1.22 {TclpRenameFile: long dst} {pcOnly} {






    cleanup
    createfile tf1
    list [catch {testfile mv tf1 $longname} msg] $msg
} {1 ENAMETOOLONG}
test winFCmd-1.23 {TclpRenameFile: move dir into self} {pcOnly} {
    cleanup
    file mkdir td1
    list [catch {testfile mv [pwd]/td1 td1/td2} msg] $msg
} {1 EINVAL}
test winFCmd-1.24 {TclpRenameFile: move a root dir} {pcOnly} {



    cleanup
    list [catch {testfile mv / c:/} msg] $msg
} {1 EINVAL}
test winFCmd-1.25 {TclpRenameFile: cross file systems} {pcOnly cdrom} {
    cleanup
    file mkdir td1
    list [catch {testfile mv td1 $cdrom/td1} msg] $msg
} {1 EXDEV} 
test winFCmd-1.26 {TclpRenameFile: readonly fs} {pcOnly cdrom} {
    cleanup
    list [catch {testfile mv $cdfile $cdrom/dummy~~.fil} msg] $msg
} {1 EACCES}
test winFCmd-1.27 {TclpRenameFile: open file} {pcOnly} {
    cleanup
    set fd [open tf1 w]
    set msg [list [catch {testfile mv tf1 tf2} msg] $msg]
    close $fd
    set msg
} {1 EACCES}    
test winFCmd-1.28 {TclpRenameFile: errno == EEXIST} {pcOnly} {
    cleanup
    createfile tf1
    createfile tf2
    testfile mv tf1 tf2
    list [file exist tf1] [file exist tf2]
} {0 1}
test winFCmd-1.29 {TclpRenameFile: src is dir} {pcOnly} {
    cleanup
    file mkdir td1
    createfile tf1
    list [catch {testfile mv td1 tf1} msg] $msg
} {1 ENOTDIR} 
test winFCmd-1.30 {TclpRenameFile: dst is dir} {pcOnly} {
    cleanup
    file mkdir td1
    file mkdir td2/td2
    list [catch {testfile mv td1 td2} msg] $msg
} {1 EEXIST}
test winFCmd-1.31 {TclpRenameFile: TclpRemoveDirectory fails} {pcOnly} {
    cleanup
    file mkdir td1
    file mkdir td2/td2
    list [catch {testfile mv td1 td2} msg] $msg
} {1 EEXIST}
test winFCmd-1.32 {TclpRenameFile: TclpRemoveDirectory succeeds} {pcOnly} {
    cleanup
    file mkdir td1/td2
    file mkdir td2
    testfile mv td1 td2
    list [file exist td1] [file exist td2] [file exist td2/td2]
} {0 1 1}
test winFCmd-1.33 {TclpRenameFile: After removing dst dir, MoveFile fails} \
	{pcOnly exdev} {
    file mkdir d:/td1
    testchmod 000 d:/td1
    set msg [list [catch {testfile mv c:/windows d:/td1} msg] $msg]
    set msg "$msg [file writable d:/td1]"
    file delete d:/td1
    set msg
} {1 EXDEV 0}
test winFCmd-1.34 {TclpRenameFile: src is dir, dst is not} {pcOnly} {
    file mkdir td1
    createfile tf1
    list [catch {testfile mv td1 tf1} msg] $msg
} {1 ENOTDIR}
test winFCmd-1.35 {TclpRenameFile: src is not dir, dst is} {pcOnly} {
    file mkdir td1
    createfile tf1
    list [catch {testfile mv tf1 td1} msg] $msg
} {1 EISDIR}
test winFCmd-1.36 {TclpRenameFile: src and dst not dir} {pcOnly} {
    createfile tf1 tf1
    createfile tf2 tf2
    testfile mv tf1 tf2
    contents tf2
} {tf1}
test winFCmd-1.37 {TclpRenameFile: need to restore temp file} {pcOnly} {
    # Can't figure out how to cause this. 
    # Need a file that can't be copied.
} {}

test winFCmd-2.1 {TclpCopyFile: errno: EACCES} {pcOnly cdrom} {
    cleanup
    list [catch {testfile cp $cdfile $cdrom/dummy~~.fil} msg] $msg
} {1 EACCES}
test winFCmd-2.2 {TclpCopyFile: errno: EISDIR} {pcOnly} {
    cleanup
    file mkdir td1
    list [catch {testfile cp td1 tf1} msg] $msg
} {1 EISDIR}
test winFCmd-2.3 {TclpCopyFile: errno: EISDIR} {pcOnly} {
    cleanup
    createfile tf1
    file mkdir td1
    list [catch {testfile cp tf1 td1} msg] $msg
} {1 EISDIR}
test winFCmd-2.4 {TclpCopyFile: errno: ENOENT} {pcOnly} {
    cleanup
    list [catch {testfile cp tf1 tf2} msg] $msg
} {1 ENOENT}
test winFCmd-2.5 {TclpCopyFile: errno: ENOENT} {pcOnly} {
    cleanup
    list [catch {testfile cp "" tf2} msg] $msg
} {1 ENOENT}
test winFCmd-2.6 {TclpCopyFile: errno: ENOENT} {pcOnly} {
    cleanup
    createfile tf1
    list [catch {testfile cp tf1 ""} msg] $msg
} {1 ENOENT}
test winFCmd-2.7 {TclpCopyFile: errno: EACCES} {95} {
    cleanup
    createfile tf1
    set fd [open tf2 w]
    set msg [list [catch {testfile cp tf1 tf2} msg] $msg]
    close $fd
    set msg
} {1 EACCES}
test winFCmd-2.8 {TclpCopyFile: errno: EACCES} {nt} {
    cleanup
    list [catch {testfile cp nul tf1} msg] $msg
} {1 EACCES}
test winFCmd-2.9 {TclpCopyFile: errno: ENOENT} {95} {
    cleanup
    list [catch {testfile cp nul tf1} msg] $msg
} {1 ENOENT}
test winFCmd-2.10 {TclpCopyFile: CopyFile succeeds} {pcOnly} {
    cleanup
    createfile tf1 tf1
    testfile cp tf1 tf2
    list [contents tf1] [contents tf2]
} {tf1 tf1}
test winFCmd-2.11 {TclpCopyFile: CopyFile succeeds} {pcOnly} {
    cleanup
    createfile tf1 tf1
    createfile tf2 tf2
    testfile cp tf1 tf2
    list [contents tf1] [contents tf2]
} {tf1 tf1}
test winFCmd-2.12 {TclpCopyFile: CopyFile succeeds} {pcOnly} {
    cleanup
    createfile tf1 tf1
    testchmod 000 tf1
    testfile cp tf1 tf2
    list [contents tf2] [file writable tf2]
} {tf1 0}
test winFCmd-2.13 {TclpCopyFile: CopyFile fails} {pcOnly} {
    cleanup
    createfile tf1
    file mkdir td1
    list [catch {testfile cp tf1 td1} msg] $msg
} {1 EISDIR} 
test winFCmd-2.14 {TclpCopyFile: errno == EACCES} {pcOnly} {
    cleanup
    file mkdir td1
    list [catch {testfile cp td1 tf1} msg] $msg
} {1 EISDIR}
test winFCmd-2.15 {TclpCopyFile: src is directory} {pcOnly} {
    cleanup
    file mkdir td1
    list [catch {testfile cp td1 tf1} msg] $msg
} {1 EISDIR}
test winFCmd-2.16 {TclpCopyFile: dst is directory} {pcOnly} {
    cleanup
    createfile tf1
    file mkdir td1
    list [catch {testfile cp tf1 td1} msg] $msg
} {1 EISDIR}
test winFCmd-2.17 {TclpCopyFile: dst is readonly} {pcOnly} {
    cleanup
    createfile tf1 tf1
    createfile tf2 tf2
    testchmod 000 tf2
    testfile cp tf1 tf2
    list [file writable tf2] [contents tf2]
} {1 tf1}
test winFCmd-2.18 {TclpCopyFile: still can't copy onto dst} {95} {
    cleanup
    createfile tf1
    createfile tf2
    testchmod 000 tf2
    set fd [open tf2]
    set msg [list [catch {testfile cp tf1 tf2} msg] $msg]
    close $fd
    set msg "$msg [file writable tf2]"
} {1 EACCES 0}    

test winFCmd-3.1 {TclpDeleteFile: errno: EACCES} {pcOnly cdrom} {
    list [catch {testfile rm $cdfile $cdrom/dummy~~.fil} msg] $msg
} {1 EACCES}
test winFCmd-3.2 {TclpDeleteFile: errno: EISDIR} {pcOnly} {
    cleanup
    file mkdir td1
    list [catch {testfile rm td1} msg] $msg
} {1 EISDIR} 
test winFCmd-3.3 {TclpDeleteFile: errno: ENOENT} {pcOnly} {
    cleanup
    list [catch {testfile rm tf1} msg] $msg
} {1 ENOENT}
test winFCmd-3.4 {TclpDeleteFile: errno: ENOENT} {pcOnly} {
    cleanup
    list [catch {testfile rm ""} msg] $msg
} {1 ENOENT}
test winFCmd-3.5 {TclpDeleteFile: errno: EACCES} {pcOnly} {
    cleanup
    set fd [open tf1 w]
    set msg [list [catch {testfile rm tf1} msg] $msg]
    close $fd
    set msg
} {1 EACCES}
test winFCmd-3.6 {TclpDeleteFile: errno: EACCES} {pcOnly} {
    cleanup
    list [catch {testfile rm nul} msg] $msg
} {1 EACCES}
test winFCmd-3.7 {TclpDeleteFile: DeleteFile succeeds} {pcOnly} {
    cleanup
    createfile tf1
    testfile rm tf1
    file exist tf1
} {0}
test winFCmd-3.8 {TclpDeleteFile: DeleteFile fails} {pcOnly} {
    cleanup
    file mkdir td1
    list [catch {testfile rm td1} msg] $msg
} {1 EISDIR}
test winFCmd-3.9 {TclpDeleteFile: errno == EACCES} {pcOnly} {
    cleanup
    set fd [open tf1 w]
    set msg [list [catch {testfile rm tf1} msg] $msg]
    close $fd
    set msg
} {1 EACCES}
test winFCmd-3.10 {TclpDeleteFile: path is readonly} {pcOnly} {
    cleanup
    createfile tf1
    testchmod 000 tf1
    testfile rm tf1
    file exists tf1
} {0}
test winFCmd-3.11 {TclpDeleteFile: still can't remove path} {pcOnly} {
    cleanup
    set fd [open tf1 w]
    testchmod 000 tf1
    set msg [list [catch {testfile rm tf1} msg] $msg]
    close $fd
    set msg
} {1 EACCES}

test winFCmd-4.1 {TclpCreateDirectory: errno: EACCES} {nt cdrom} {
    list [catch {testfile mkdir $cdrom/dummy~~.dir} msg] $msg
} {1 EACCES}
test winFCmd-4.2 {TclpCreateDirectory: errno: EACCES} {95 cdrom} {
    list [catch {testfile mkdir $cdrom/dummy~~.dir} msg] $msg
} {1 ENOSPC}
test winFCmd-4.3 {TclpCreateDirectory: errno: EEXIST} {pcOnly} {
    cleanup
    file mkdir td1
    list [catch {testfile mkdir td1} msg] $msg
} {1 EEXIST}
test winFCmd-4.4 {TclpCreateDirectory: errno: ENOENT} {pcOnly} {
    cleanup
    list [catch {testfile mkdir td1/td2} msg] $msg
} {1 ENOENT}
test winFCmd-4.5 {TclpCreateDirectory: CreateDirectory succeeds} {pcOnly} {
    cleanup
    testfile mkdir td1
    file type td1
} {directory}

test winFCmd-5.1 {TclpCopyDirectory: calls TraverseWinTree} {pcOnly} {
    cleanup
    file mkdir td1
    testfile cpdir td1 td2
    list [file type td1] [file type td2]
} {directory directory}

test winFCmd-6.1 {TclpRemoveDirectory: errno: EACCES} {pcOnly} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    testfile rmdir td1
    file exist td1
} {0}
test winFCmd-6.2 {TclpRemoveDirectory: errno: EEXIST} {pcOnly} {
    cleanup
    file mkdir td1/td2
    list [catch {testfile rmdir td1} msg] $msg
} {1 {td1 EEXIST}}
test winFCmd-6.3 {TclpRemoveDirectory: errno: EACCES} {pcOnly} {
    # can't test this w/o removing everything on your hard disk first!
    # testfile rmdir /
} {}
test winFCmd-6.4 {TclpRemoveDirectory: errno: ENOENT} {pcOnly} {
    cleanup
    list [catch {testfile rmdir td1} msg] $msg
} {1 {td1 ENOENT}}
test winFCmd-6.5 {TclpRemoveDirectory: errno: ENOENT} {pcOnly} {
    cleanup
    list [catch {testfile rmdir ""} msg] $msg
} {1 ENOENT}
test winFCmd-6.6 {TclpRemoveDirectory: errno: ENOTDIR} {pcOnly} {
    cleanup
    createfile tf1
    list [catch {testfile rmdir tf1} msg] $msg
} {1 {tf1 ENOTDIR}}
test winFCmd-6.7 {TclpRemoveDirectory: RemoveDirectory succeeds} {pcOnly} {
    cleanup
    file mkdir td1
    testfile rmdir td1
    file exists td1
} {0}
test winFCmd-6.8 {TclpRemoveDirectory: RemoveDirectory fails} {pcOnly} {
    cleanup
    createfile tf1
    list [catch {testfile rmdir tf1} msg] $msg
} {1 {tf1 ENOTDIR}}
test winFCmd-6.9 {TclpRemoveDirectory: errno == EACCES} {pcOnly} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    testfile rmdir td1
    file exists td1
} {0}
test winFCmd-6.10 {TclpRemoveDirectory: attr == -1} {95} {
    cleanup
    list [catch {testfile rmdir nul} msg] $msg
} {1 {nul EACCES}}
test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} {nt} {
    cleanup
    list [catch {testfile rmdir /} msg] $msg
} {1 {\ EACCES}}
test winFCmd-6.12 {TclpRemoveDirectory: errno == EACCES} {95} {
    cleanup
    createfile tf1
    list [catch {testfile rmdir tf1} msg] $msg
} {1 {tf1 ENOTDIR}}
test winFCmd-6.13 {TclpRemoveDirectory: write-protected} {pcOnly} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    testfile rmdir td1
    file exists td1
} {0}
test winFCmd-6.14 {TclpRemoveDirectory: check if empty dir} {95} {
    cleanup
    file mkdir td1/td2
    list [catch {testfile rmdir td1} msg] $msg
} {1 {td1 EEXIST}}
test winFCmd-6.15 {TclpRemoveDirectory: !recursive} {pcOnly} {
    cleanup
    file mkdir td1/td2
    list [catch {testfile rmdir td1} msg] $msg
} {1 {td1 EEXIST}}
test winFCmd-6.16 {TclpRemoveDirectory: recursive, but errno != EEXIST} {pcOnly} {
    cleanup
    createfile tf1
    list [catch {testfile rmdir -force tf1} msg] $msg
} {1 {tf1 ENOTDIR}}
test winFCmd-6.17 {TclpRemoveDirectory: calls TraverseWinTree} {pcOnly} {
    cleanup
    file mkdir td1/td2
    testfile rmdir -force td1
    file exists td1
} {0}

test winFCmd-7.1 {TraverseWinTree: targetPtr == NULL} {pcOnly} {
    cleanup
    file mkdir td1/td2/td3
    testfile rmdir -force td1
    file exists td1
} {0}
test winFCmd-7.2 {TraverseWinTree: targetPtr != NULL} {pcOnly} {
    cleanup
    file mkdir td1/td2/td3
    testfile cpdir td1 td2
    list [file exists td1] [file exists td2]
} {1 1}
test winFCmd-7.3 {TraverseWinTree: sourceAttr == -1} {pcOnly} {
    cleanup
    list [catch {testfile cpdir td1 td2} msg] $msg
} {1 {td1 ENOENT}}
test winFCmd-7.4 {TraverseWinTree: source isn't directory} {pcOnly} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    contents td2/tf1
} {tf1}
test winFCmd-7.5 {TraverseWinTree: call TraversalCopy: DOTREE_F} {pcOnly} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    contents td2/tf1
} {tf1}
test winFCmd-7.6 {TraverseWinTree: call TraversalDelete: DOTREE_F} {pcOnly} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile rmdir -force td1
    file exists td1
} {0}
test winFCmd-7.7 {TraverseWinTree: append \ to source if necessary} {pcOnly} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    contents td2/tf1
} {tf1}    
test winFCmd-7.8 {TraverseWinTree: append \ to source if necessary} {95 cdrom} {
    list [catch {testfile rmdir $cdrom/} msg] $msg
} "1 {$cdrom\\ EEXIST}"
test winFCmd-7.9 {TraverseWinTree: append \ to source if necessary} {nt cdrom} {
    list [catch {testfile rmdir $cdrom/} msg] $msg
} "1 {$cdrom\\ EACCES}"
test winFCmd-7.10 {TraverseWinTree: can't read directory: handle == INVALID} \
	{pcOnly} {
    # can't make it happen
} {}
test winFCmd-7.11 {TraverseWinTree: call TraversalCopy: DOTREE_PRED} {pcOnly} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    list [file exists td2] [file writable td2]
} {1 0}
test winFCmd-7.12 {TraverseWinTree: call TraversalDelete: DOTREE_PRED} {pcOnly} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile rmdir -force td1
    file exists td1
} {0}
test winFCmd-7.13 {TraverseWinTree: append \ to target if necessary} {pcOnly} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    contents td2/tf1
} {tf1}    
test winFCmd-7.14 {TraverseWinTree: append \ to target if necessary} {95} {
    cleanup
    file mkdir td1
    list [catch {testfile cpdir td1 /} msg] $msg
} {1 {\ EEXIST}}
test winFCmd-7.15 {TraverseWinTree: append \ to target if necessary} {nt} {
    cleanup
    file mkdir td1
    list [catch {testfile cpdir td1 /} msg] $msg
} {1 {\ EACCES}}
test winFCmd-7.16 {TraverseWinTree: recurse on files: no files} {pcOnly} {
    cleanup
    file mkdir td1
    testfile cpdir td1 td2
} {}
test winFCmd-7.17 {TraverseWinTree: recurse on files: one file} {pcOnly} {
    cleanup
    file mkdir td1
    createfile td1/td2
    testfile cpdir td1 td2
    glob td2/*
} {td2/td2}
test winFCmd-7.18 {TraverseWinTree: recurse on files: several files and dir} \
	{pcOnly} {
    cleanup
    file mkdir td1
    createfile td1/tf1
    createfile td1/tf2
    file mkdir td1/td2/td3
    createfile td1/tf3
    createfile td1/tf4
    testfile cpdir td1 td2
    lsort [glob td2/*]
} {td2/td2 td2/tf1 td2/tf2 td2/tf3 td2/tf4}
test winFCmd-7.19 {TraverseWinTree: call TraversalCopy: DOTREE_POSTD} {pcOnly} {
    cleanup
    file mkdir td1
    testchmod 000 td1
    createfile td1/tf1 tf1
    testfile cpdir td1 td2
    list [file exists td2] [file writable td2]
} {1 0}
test winFCmd-7.20 {TraverseWinTree: call TraversalDelete: DOTREE_POSTD} \
	{pcOnly} {
    cleanup
    file mkdir td1
    createfile td1/tf1 tf1
    testfile rmdir -force td1
    file exists td1
} {0}
test winFCmd-7.21 {TraverseWinTree: fill errorPtr} {pcOnly} {
    cleanup
    list [catch {testfile cpdir td1 td2} msg] $msg
} {1 {td1 ENOENT}}

test winFCmd-8.1 {TraversalCopy: DOTREE_F} {pcOnly} {
    cleanup
    file mkdir td1
    list [catch {testfile cpdir td1 td1} msg] $msg
} {1 {td1 EEXIST}}
test winFCmd-8.2 {TraversalCopy: DOTREE_PRED} {pcOnly} {
    cleanup
    file mkdir td1/td2
    testchmod 000 td1
    testfile cpdir td1 td2
    list [file writable td1] [file writable td1/td2]
} {0 1}
test winFCmd-8.3 {TraversalCopy: DOTREE_POSTD} {pcOnly} {
    cleanup
    file mkdir td1
    testfile cpdir td1 td2
} {}

test winFCmd-9.1 {TraversalDelete: DOTREE_F} {pcOnly} {
    cleanup
    file mkdir td1
    createfile td1/tf1
    testfile rmdir -force td1
} {}
test winFCmd-9.2 {TraversalDelete: DOTREE_F} {95} {
    cleanup
    file mkdir td1
    set fd [open td1/tf1 w]
    set msg [list [catch {testfile rmdir -force td1} msg] $msg]
    close $fd
    set msg
} {1 {td1\tf1 EACCES}}
test winFCmd-9.3 {TraversalDelete: DOTREE_PRED} {pcOnly} {
    cleanup
    file mkdir td1/td2
    testchmod 000 td1
    testfile rmdir -force td1
    file exists td1
} {0}
test winFCmd-9.4 {TraversalDelete: DOTREE_POSTD} {pcOnly} {
    cleanup
    file mkdir td1/td1/td3/td4/td5
    testfile rmdir -force td1
} {}

test winFCmd-10.1 {AttributesPosixError - get} {pcOnly} {
    cleanup
    list [catch {file attributes td1 -archive} msg] $msg
} {1 {could not read "td1": no such file or directory}}
test winFCmd-10.2 {AttributesPosixError - set} {pcOnly} {
    cleanup
    list [catch {file attributes td1 -archive 0} msg] $msg
} {1 {could not read "td1": no such file or directory}}

test winFCmd-11.1 {GetWinFileAttributes} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -archive} msg] $msg [cleanup]
} {0 1 {}}
test winFCmd-11.2 {GetWinFileAttributes} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -readonly} msg] $msg [cleanup]
} {0 0 {}}
test winFCmd-11.3 {GetWinFileAttributes} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -hidden} msg] $msg [cleanup]
} {0 0 {}}
test winFCmd-11.4 {GetWinFileAttributes} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -system} msg] $msg [cleanup]
} {0 0 {}}
test winfcmd-11.5 {GetWinFileAttributes} {pcOnly} {
    # attr of relative paths that resolve to root was failing
    # don't care about answer, just that test runs.

    set old [pwd]
    cd c:/
    file attr c:	    
    file attr c:.
    file attr . 
    cd $old
} {}

test winFCmd-12.1 {ConvertFileNameFormat} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -longname]} msg] $msg [cleanup]
} {0 td1 {}}
test winFCmd-12.2 {ConvertFileNameFormat} {pcOnly} {
    cleanup
    file mkdir td1
    close [open td1/td1 w]
    list [catch {string tolower [file attributes td1/td1 -longname]} msg] $msg [cleanup]
} {0 td1/td1 {}}
test winFCmd-12.3 {ConvertFileNameFormat} {pcOnly} {
    cleanup
    file mkdir td1
    file mkdir td1/td2
    close [open td1/td3 w]
    list [catch {string tolower [file attributes td1/td2/../td3 -longname]} msg] $msg [cleanup]
} {0 td1/td2/../td3 {}}
test winFCmd-12.4 {ConvertFileNameFormat} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes ./td1 -longname]} msg] $msg [cleanup]
} {0 ./td1 {}}
test winFCmd-12.5 {ConvertFileNameFormat: absolute path} {pcOnly} {
    list [file attributes / -longname] [file attributes \\ -longname]
} {/ /}
test winFCmd-12.6 {ConvertFileNameFormat: absolute path with drive} {pcOnly} {
    catch {file delete -force -- c:/td1}
    close [open c:/td1 w]
    list [catch {string tolower [file attributes c:/td1 -longname]} msg] $msg [file delete -force -- c:/td1]
} {0 c:/td1 {}}
test winFCmd-12.7 {ConvertFileNameFormat} {nonPortable pcOnly} {


    string tolower [file attributes //bisque/tcl/ws -longname]
} {//bisque/tcl/ws}
test winFCmd-12.8 {ConvertFileNameFormat} {pcOnly longFileNames} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -longname]} msg] $msg [cleanup]
} {0 td1 {}}





test winFCmd-12.10 {ConvertFileNameFormat} {longFileNames pcOnly} {
    cleanup
    close [open td1td1td1 w]
    list [catch {file attributes td1td1td1 -shortname}] [cleanup]
} {0 {}}
test winFCmd-12.11 {ConvertFileNameFormat} {longFileNames pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -shortname]} msg] $msg [cleanup]
} {0 td1 {}}

test winFCmd-13.1 {GetWinFileLongName} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -longname]} msg] $msg [cleanup]
} {0 td1 {}}

test winFCmd-14.1 {GetWinFileShortName} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {string tolower [file attributes td1 -shortname]} msg] $msg [cleanup]
} {0 td1 {}}

test winFCmd-15.1 {SetWinFileAttributes} {pcOnly} {
    cleanup
    list [catch {file attributes td1 -archive 0} msg] $msg
} {1 {could not read "td1": no such file or directory}}
test winFCmd-15.2 {SetWinFileAttributes - archive} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -archive 1} msg] $msg [file attributes td1 -archive] [cleanup]
} {0 {} 1 {}}
test winFCmd-15.3 {SetWinFileAttributes - archive} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -archive 0} msg] $msg [file attributes td1 -archive] [cleanup]
} {0 {} 0 {}}
test winFCmd-15.4 {SetWinFileAttributes - hidden} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -hidden 1} msg] $msg [file attributes td1 -hidden] [file attributes td1 -hidden 0] [cleanup]
} {0 {} 1 {} {}}
test winFCmd-15.5 {SetWinFileAttributes - hidden} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -hidden 0} msg] $msg [file attributes td1 -hidden] [cleanup]
} {0 {} 0 {}}
test winFCmd-15.6 {SetWinFileAttributes - readonly} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -readonly 1} msg] $msg [file attributes td1 -readonly] [cleanup]
} {0 {} 1 {}}
test winFCmd-15.7 {SetWinFileAttributes - readonly} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -readonly 0} msg] $msg [file attributes td1 -readonly] [cleanup]
} {0 {} 0 {}}
test winFCmd-15.8 {SetWinFileAttributes - system} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -system 1} msg] $msg [file attributes td1 -system] [cleanup]
} {0 {} 1 {}}
test winFCmd-15.9 {SetWinFileAttributes - system} {pcOnly} {
    cleanup
    close [open td1 w]
    list [catch {file attributes td1 -system 0} msg] $msg [file attributes td1 -system] [cleanup]
} {0 {} 0 {}}
test winFCmd-15.10 {SetWinFileAttributes - failing} {pcOnly cdrom} {
    cleanup





    catch {file attributes $cdfile -archive 1}
} {1}


# This block of code used to occur after the "return" call, so I'm

# commenting it out and assuming that this code is still under construction.
#foreach source {tef ted tnf tnd "" nul com1} {
#    foreach chmodsrc {000 755} {
#        foreach dest "tfn tfe tdn tdempty tdfull td1/td2 $p $p/td1 {} nul" {
#	    foreach chmoddst {000 755} {
#		puts hi
#		cleanup
#		file delete -force ted tef
#		file mkdir ted
#		createfile tef
#		createfile tfe
#		file mkdir tdempty
#		file mkdir tdfull/td1/td2
#
#		catch {testchmod $chmodsrc $source}
#		catch {testchmod $chmoddst $dest}
#
#		if [catch {file rename $source $dest} msg] {
#		    puts "file rename $source ($chmodsrc) $dest ($chmoddst)"
#		    puts $msg
#		}
#	    }
#	}
#    }
#}

# cleanup
cleanup
::tcltest::cleanupTests
return












Added tests/winFile.test.

































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# This file tests the tclWinFile.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 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: winFile.test,v 1.1.2.5 1999/03/24 02:49:52 hershey Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

test winFile-1.1 {TclpGetUserHome} {pcOnly} {
    list [catch {glob ~nosuchuser} msg] $msg
} {1 {user "nosuchuser" doesn't exist}}
test winFile-1.2 {TclpGetUserHome} {nt nonPortable} {
    # The administrator account should always exist.

    catch {glob ~administrator}
} {0}
test winFile-1.2 {TclpGetUserHome} {95} {
    # Find some user in system.ini and then see if they have a home.

    set f [open $::env(windir)/system.ini]
    set x 0
    while {![eof $f]} {
	set line [gets $f]
	if {$line == "\[Password Lists]"} {
	    gets $f
	    set name [lindex [split [gets $f] =] 0]
	    if {$name != ""} {
		set x [catch {glob ~$name}]
		break
	    }
	}
    }
    close $f
    set x
} {0}
test winFile-1.3 {TclpGetUserHome} {nt nonPortable} {
    catch {glob ~stanton@workgroup}
} {0}

# cleanup
::tcltest::cleanupTests
return












Changes to tests/winNotify.test.

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
















# This file tests the tclWinNotify.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.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) winNotify.test 1.2 97/04/14 17:24:56


if {[string compare test [info procs test]] == 1} then {source defs}

if {$tcl_platform(platform) != "windows"} {
    return
}



# There is no explicit test for InitNotifier or NotifierExitHandler

test winNotify-1.1 {Tcl_SetTimer: positive timeout} {
    set done 0
    after 1000 { set done 1 }
    vwait done
    set done
} 1
test winNotify-1.2 {Tcl_SetTimer: positive timeout, message pending} {
    set x 0
    set y 1
    set a1 [after 0 { incr y }]
    after cancel $a1
    after 500 { incr x }
    vwait x
    list $x $y
} {1 1}
test winNotify-1.3 {Tcl_SetTimer: cancelling positive timeout} {
    set x 0
    set y 1
    set id [after 10000 { incr y }]
    after 0 { incr x }
    vwait x
    after cancel $id
    list $x $y
} {1 1}
test winNotify-1.4 {Tcl_SetTimer: null timeout, message pending} {
    set x 0
    set y 1
    after 0 { incr x }
    after 0 { incr y }
    vwait x
    list $x $y
} {1 2}

test winNotify-2.1 {Tcl_ResetIdleTimer} {
    set x 0
    update
    after idle { incr x }
    vwait x
    set x
} 1
test winNotify-2.2 {Tcl_ResetIdleTimer: message pending} {
    set x 0
    set y 1
    update
    after idle { incr x }
    after idle { incr y }
    update
    list $x $y
} {1 2}

test winNotify-3.1 {NotifierProc: non-modal normal timer} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after 500 { incr x; testeventloop done }
    testeventloop wait
    set x
} 1
test winNotify-3.2 {NotifierProc: non-modal normal timer, rescheduled} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after 500 { incr x; after 100 {incr x; testeventloop done }}
    testeventloop wait
    set x
} 2
test winNotify-3.3 {NotifierProc: modal normal timer} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after 500 { incr x }
    vwait x
    set x
} 1
test winNotify-3.4 {NotifierProc: modal normal timer, rescheduled} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    set y 0
    after 500 { incr y; after 100 {incr x}}
    vwait x
    list $x $y
} {1 1}
test winNotify-3.5 {NotifierProc: non-modal idle timer} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after idle { incr x; testeventloop done }
    testeventloop wait
    set x
} 1
test winNotify-3.6 {NotifierProc: non-modal idle timer, rescheduled} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after idle { incr x; after idle {incr x; testeventloop done }}
    testeventloop wait
    set x
} 2
test winNotify-3.7 {NotifierProc: modal idle timer} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after idle { incr x }
    vwait x
    set x
} 1
test winNotify-3.8 {NotifierProc: modal idle timer, rescheduled} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    set y 0
    after idle { incr y; after idle {incr x}}
    vwait x
    list $x $y
} {1 1}

# Tcl_DoOneEvent is tested by the timer.test, io.test, and event.test files























>




|

>
|
|
<
<
|
>
>



|





|








|








|








|






|









|









|









|









|










|









|









|









|












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# This file tests the tclWinNotify.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: winNotify.test,v 1.1.2.6 1999/03/24 04:25:42 stanton Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}



set ::tcltest::testConfig(testeventloop) \
	[expr {[info commands testeventloop] != {}}]

# There is no explicit test for InitNotifier or NotifierExitHandler

test winNotify-1.1 {Tcl_SetTimer: positive timeout} {pcOnly} {
    set done 0
    after 1000 { set done 1 }
    vwait done
    set done
} 1
test winNotify-1.2 {Tcl_SetTimer: positive timeout, message pending} {pcOnly} {
    set x 0
    set y 1
    set a1 [after 0 { incr y }]
    after cancel $a1
    after 500 { incr x }
    vwait x
    list $x $y
} {1 1}
test winNotify-1.3 {Tcl_SetTimer: cancelling positive timeout} {pcOnly} {
    set x 0
    set y 1
    set id [after 10000 { incr y }]
    after 0 { incr x }
    vwait x
    after cancel $id
    list $x $y
} {1 1}
test winNotify-1.4 {Tcl_SetTimer: null timeout, message pending} {pcOnly} {
    set x 0
    set y 1
    after 0 { incr x }
    after 0 { incr y }
    vwait x
    list $x $y
} {1 2}

test winNotify-2.1 {Tcl_ResetIdleTimer} {pcOnly} {
    set x 0
    update
    after idle { incr x }
    vwait x
    set x
} 1
test winNotify-2.2 {Tcl_ResetIdleTimer: message pending} {pcOnly} {
    set x 0
    set y 1
    update
    after idle { incr x }
    after idle { incr y }
    update
    list $x $y
} {1 2}

test winNotify-3.1 {NotifierProc: non-modal normal timer} {pcOnly testeventloop} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after 500 { incr x; testeventloop done }
    testeventloop wait
    set x
} 1
test winNotify-3.2 {NotifierProc: non-modal normal timer, rescheduled} {pcOnly testeventloop} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after 500 { incr x; after 100 {incr x; testeventloop done }}
    testeventloop wait
    set x
} 2
test winNotify-3.3 {NotifierProc: modal normal timer} {pcOnly} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after 500 { incr x }
    vwait x
    set x
} 1
test winNotify-3.4 {NotifierProc: modal normal timer, rescheduled} {pcOnly} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    set y 0
    after 500 { incr y; after 100 {incr x}}
    vwait x
    list $x $y
} {1 1}
test winNotify-3.5 {NotifierProc: non-modal idle timer} {pcOnly testeventloop} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after idle { incr x; testeventloop done }
    testeventloop wait
    set x
} 1
test winNotify-3.6 {NotifierProc: non-modal idle timer, rescheduled} {pcOnly testeventloop} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after idle { incr x; after idle {incr x; testeventloop done }}
    testeventloop wait
    set x
} 2
test winNotify-3.7 {NotifierProc: modal idle timer} {pcOnly} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    after idle { incr x }
    vwait x
    set x
} 1
test winNotify-3.8 {NotifierProc: modal idle timer, rescheduled} {pcOnly} {
    update
    set x 0
    foreach i [after info] {
	after cancel $i
    }
    set y 0
    after idle { incr y; after idle {incr x}}
    vwait x
    list $x $y
} {1 1}

# Tcl_DoOneEvent is tested by the timer.test, io.test, and event.test files

# cleanup
::tcltest::cleanupTests
return












Changes to tests/winPipe.test.

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
# 
# winPipe.test --
#
# This file contains a collection of tests for tclWinPipe.c

# Sourcing this file into Tcl runs the tests and generates output for 
# errors.  No output means no errors were found.
#
# Copyright (c) 1996 Sun Microsystems, Inc.

#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) winPipe.test 1.11 97/10/09 17:06:16

if {$tcl_platform(platform) != "windows"} {
    return

}


set cat16 [file join $tcl_library ../win/cat16.exe]
set cat32 [file join $tcl_library ../win/cat32.exe]

if {[string compare test [info procs test]] == 1} then {source defs}



if [catch {puts console1 ""}] {
    set testConfig(AllocConsole) 1
} else {
    set testConfig(.console) 1
}

set big aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n
append big $big
append big $big	
append big $big
append big $big
append big $big
append big $big





|




>




|

<
|
>


>
|
|

<
>
>

|
|

|


|







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
# 
# winPipe.test --
#
# This file contains a collection of tests for tclWinPipe.c
#
# Sourcing this file into Tcl runs the tests and generates output for 
# errors.  No output means no errors were found.
#
# Copyright (c) 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: winPipe.test,v 1.1.2.8 1999/03/24 02:49:53 hershey Exp $


if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

set bindir [file join [pwd] [file dirname [info nameofexecutable]]]
set cat16 [file join  $bindir cat16.exe]
set cat32 [file join $bindir cat32.exe]


set ::tcltest::testConfig(cat32) [file exists $cat32]
set ::tcltest::testConfig(cat16) [file exists $cat16]

if {[catch {puts console1 ""}]} {
    set ::tcltest::testConfig(AllocConsole) 1
} else {
    set ::tcltest::testConfig(.console) 1
}

set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
append big $big
append big $big	
append big $big
append big $big
append big $big
append big $big

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
proc contents {file} {
    set f [open $file r]
    set r [read $f]
    close $f
    set r
}








if {$testConfig(stdio) && [file exists $cat32]} {
test winpipe-1.1 {32 bit comprehensive tests: from little file} {
    exec $cat32 < little > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "little stderr32"
test winpipe-1.2 {32 bit comprehensive tests: from big file} {
    exec $cat32 < big > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr32"
test winpipe-1.3 {32 bit comprehensive tests: a little from pipe} {nt} {
    exec more < little | $cat32 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{little\n} stderr32"
test winpipe-1.4 {32 bit comprehensive tests: a little from pipe} {95} {
    exec more < little |& $cat32 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{\nlittle} stderr32"
test winpipe-1.5 {32 bit comprehensive tests: a lot from pipe} {nt} {
    exec more < big | $cat32 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr32"
test winpipe-1.6 {32 bit comprehensive tests: a lot from pipe} {95} {
    exec command /c type big |& $cat32 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr32"
test winpipe-1.7 {32 bit comprehensive tests: from console} {AllocConsole} {

    # would block waiting for human input
} {}
test winpipe-1.8 {32 bit comprehensive tests: from NUL} {
    exec $cat32 < nul > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{} stderr32"
test winpipe-1.9 {32 bit comprehensive tests: from socket} {
    # doesn't work
} {}
test winpipe-1.10 {32 bit comprehensive tests: from nowhere} {.console} {

    exec $cat32 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{} stderr32"
test winpipe-1.11 {32 bit comprehensive tests: from file handle} {

    set f [open "little" r]
    exec $cat32 <@$f > stdout 2> stderr
    close $f
    list [contents stdout] [contents stderr]
} "little stderr32"
test winpipe-1.12 {32 bit comprehensive tests: read from application} {

    set f [open "|$cat32 < little" r]
    gets $f line
    catch {close $f} msg
    list $line $msg
} "little stderr32"
test winpipe-1.13 {32 bit comprehensive tests: a little to file} {

    exec $cat32 < little > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "little stderr32"
test winpipe-1.14 {32 bit comprehensive tests: a lot to file} {

    exec $cat32 < big > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr32"
test winpipe-1.15 {32 bit comprehensive tests: a little to pipe} {nt} {
    exec $cat32 < little | more > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{little\n} stderr32"
test winpipe-1.16 {32 bit comprehensive tests: a little to pipe} {95} {
    exec $cat32 < little | more > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{\nlittle} stderr32"
test winpipe-1.17 {32 bit comprehensive tests: a lot to pipe} {nt} {
    exec $cat32 < big | more > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big\n} stderr32"
test winpipe-1.18 {32 bit comprehensive tests: a lot to pipe} {95} {
    exec $cat32 < big | more > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{\n$big} stderr32"
test winpipe-1.19 {32 bit comprehensive tests: to console} {
    catch {exec $cat32 << "You should see this\n" >@stdout} msg
    set msg
} stderr32
test winpipe-1.20 {32 bit comprehensive tests: to NUL} {
    # some apps hang when sending a large amount to NUL.  $cat32 isn't one.
    catch {exec $cat32 < big > nul} msg
    set msg
} stderr32
test winpipe-1.21 {32 bit comprehensive tests: to nowhere} {.console} {

    exec $cat32 < big >&@stdout 
} {}
test winpipe-1.22 {32 bit comprehensive tests: to file handle} {
    set f1 [open "stdout" w]
    set f2 [open "stderr" w]
    exec $cat32 < little >@$f1 2>@$f2
    close $f1
    close $f2
    list [contents stdout] [contents stderr]
} "little stderr32"
test winpipe-1.23 {32 bit comprehensive tests: write to application} {

    set f [open "|$cat32 > stdout" w]
    puts -nonewline $f "foo"
    catch {close $f} msg
    list [contents stdout] $msg
} "foo stderr32"
test winpipe-1.24 {32 bit comprehensive tests: read/write application} {

    set f [open "|$cat32" r+]
    puts $f $big
    puts $f \032
    flush $f
    set r [read $f 64]
    catch {close $f}
    set r
} "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}

set stderr16 "stderr16"
if {$tcl_platform(os) == "Win32s"} {
    set stderr16 "{}"
}
if [file exists $cat16] {
test winpipe-2.1 {16 bit comprehensive tests: from little file} {
    exec $cat16 < little > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "little $stderr16"
test winpipe-2.2 {16 bit comprehensive tests: from big file} {
    exec $cat16 < big > stdout 2> stderr
    list [contents stdout] [contents stderr] 
} "{$big} $stderr16"
test winpipe-2.3 {16 bit comprehensive tests: a little from pipe} {nt} {
    exec more < little | $cat16 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{little\n} stderr16"
test winpipe-2.4 {16 bit comprehensive tests: a little from pipe} {95} {
    exec more < little | $cat16 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{\nlittle} stderr16"
test winpipe-2.5 {16 bit comprehensive tests: a lot from pipe} {nt} {
    exec $cat16 < big | $cat16 > stdout 2> stderr
    list [contents stdout] [contents stderr] 
} "{$big} stderr16stderr16"
test winpipe-2.6 {16 bit comprehensive tests: a lot from pipe} {95} {
    exec more < big | $cat16 > stdout 2> stderr
    list [contents stdout] [contents stderr] 
} "{\n$big} stderr16"
test winpipe-2.7 {16 bit comprehensive tests: from console} {AllocConsole} {

    # would block waiting for human input
} {}		     
test winpipe-2.8 {16 bit comprehensive tests: from NUL} {nt} {
    exec $cat16 < nul > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{} stderr16"
test winpipe-2.9 {16 bit comprehensive tests: from socket} {
    # doesn't work
} {}
test winpipe-2.10 {16 bit comprehensive tests: from nowhere} {.console} {
    exec $cat16 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{} stderr16"
test winpipe-2.11 {16 bit comprehensive tests: from file handle} {
    set f [open "little" r]
    exec $cat16 <@$f > stdout 2> stderr
    close $f
    list [contents stdout] [contents stderr]
} "little $stderr16"
test winpipe-2.12 {16 bit comprehensive tests: read from application} {
    set f [open "|$cat16 < little" r]
    gets $f line
    catch {close $f} msg
    list $line $msg
} "little $stderr16"
test winpipe-2.13 {16 bit comprehensive tests: a little to file} {
    exec $cat16 < little > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "little $stderr16"
test winpipe-2.14 {16 bit comprehensive tests: a lot to file} {
    exec $cat16 < big > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} $stderr16"
test winpipe-2.15 {16 bit comprehensive tests: a little to pipe} {nt} {
    catch {exec $cat16 < little | more > stdout 2> stderr}
    list [contents stdout] [contents stderr]
} "{little\n} stderr16"
test winpipe-2.16 {16 bit comprehensive tests: a little to pipe} {95} {
    exec $cat16 < little | more > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{\nlittle} stderr16"
test winpipe-2.17 {16 bit comprehensive tests: a lot to pipe} {nt} {
    catch {exec $cat16 < big | more > stdout 2> stderr}
    list [contents stdout] [contents stderr]
} "{$big\n} stderr16"
test winpipe-2.18 {16 bit comprehensive tests: a lot to pipe} {95} {
    exec $cat16 < big | more > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{\n$big} stderr16"
test winpipe-2.19 {16 bit comprehensive tests: to console} {
    catch {exec $cat16 << "You should see this\n" >@stdout} msg
    set msg
} [lindex $stderr16 0]
test winpipe-2.20 {16 bit comprehensive tests: to NUL} {nt} {
    # some apps hang when sending a large amount to NUL.  cat16 isn't one.
    catch {exec $cat16 < big > nul} msg
    set msg
} stderr16
test winpipe-2.21 {16 bit comprehensive tests: to nowhere} {.console} {
    exec $cat16 < big >&@stdout 
} {}
test winpipe-2.22 {16 bit comprehensive tests: to file handle} {
    set f1 [open "stdout" w]
    set f2 [open "stderr" w]
    exec $cat16 < little >@$f1 2>@$f2
    close $f1
    close $f2
    list [contents stdout] [contents stderr]
} "little $stderr16"
test winpipe-2.23 {16 bit comprehensive tests: write to application} {!win32s} {
    set f [open "|$cat16 > stdout" w]
    puts -nonewline $f "foo"
    catch {close $f} msg
    list [contents stdout] $msg
} "foo stderr16"
test winpipe-2.24 {16 bit comprehensive tests: read/write application} {nt} {
    set f [open "|$cat16" r+]
    puts $f $big
    puts $f \032
    flush $f
    set r [read $f 64]
    catch {close $f}
    set r
} "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

}

test winpipe-3.1 {Tcl_WaitPid} {nt} {
    proc readResults {f} {
	global x result
	if { [eof $f] } {
	    close $f
	    set x 1
	} else {
	    set line [read $f ]







>
>
>
>
>
>
>
|
|


|
|



|
|

|
|
<
<
<
<
|


|



|
>


|


|
|


|
>


|
|
>




|
|
>




|
|
>


|
|
>



|
<
<
|
<
|

|
|
<
<
|
<
|

|
|



|




|
>


|






|
|
>




|
|
>







|
|

<
<
<
<
<
|


|
|


|
|
|

|
|
<
<
<
<



|
|

|
|
>


|



|


|



|




|
|




|
|


|
|


|
|
<
<
<
<
|

<
<
<
<
|
|
|

|
|


|
|




|


|






|
|





|







|
>
|
<
|







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
proc contents {file} {
    set f [open $file r]
    set r [read $f]
    close $f
    set r
}

set f [open more w]
puts $f {
    while {[eof stdin] == 0} {
	puts -nonewline [read stdin]
    }
}
close $f

test winpipe-1.1 {32 bit comprehensive tests: from little file} {pcOnly stdio cat32} {
    exec $cat32 < little > stdout 2> stderr
    list [contents stdout] [contents stderr]
} {little stderr32}
test winpipe-1.2 {32 bit comprehensive tests: from big file} {pcOnly stdio cat32} {
    exec $cat32 < big > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr32"
test winpipe-1.3 {32 bit comprehensive tests: a little from pipe} {nt stdio cat32} {
    exec $tcltest more < little | $cat32 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} {little stderr32}
test winpipe-1.4 {32 bit comprehensive tests: a lot from pipe} {nt stdio cat32} {




    exec $tcltest more < big | $cat32 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr32"
test winpipe-1.5 {32 bit comprehensive tests: a lot from pipe} {95 stdio cat32} {
    exec command /c type big |& $cat32 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr32"
test winpipe-1.6 {32 bit comprehensive tests: from console} \
	{pcOnly stdio cat32 AllocConsole} {
    # would block waiting for human input
} {}
test winpipe-1.7 {32 bit comprehensive tests: from NUL} {pcOnly stdio cat32} {
    exec $cat32 < nul > stdout 2> stderr
    list [contents stdout] [contents stderr]
} {{} stderr32}
test winpipe-1.8 {32 bit comprehensive tests: from socket} {pcOnly stdio cat32} {
    # doesn't work
} {}
test winpipe-1.9 {32 bit comprehensive tests: from nowhere} \
	{pcOnly stdio cat32 .console} {
    exec $cat32 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} {{} stderr32}
test winpipe-1.10 {32 bit comprehensive tests: from file handle} \
	{pcOnly stdio cat32} {
    set f [open "little" r]
    exec $cat32 <@$f > stdout 2> stderr
    close $f
    list [contents stdout] [contents stderr]
} {little stderr32}
test winpipe-1.11 {32 bit comprehensive tests: read from application} \
	{pcOnly stdio cat32} {
    set f [open "|$cat32 < little" r]
    gets $f line
    catch {close $f} msg
    list $line $msg
} {little stderr32}
test winpipe-1.12 {32 bit comprehensive tests: a little to file} \
	{pcOnly stdio cat32} {
    exec $cat32 < little > stdout 2> stderr
    list [contents stdout] [contents stderr]
} {little stderr32}
test winpipe-1.13 {32 bit comprehensive tests: a lot to file} \
	{pcOnly stdio cat32} {
    exec $cat32 < big > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr32"
test winpipe-1.14 {32 bit comprehensive tests: a little to pipe} \


	{pcOnly stdio cat32} {

    exec $cat32 < little | $tcltest more > stdout 2> stderr
    list [contents stdout] [contents stderr]
} {little stderr32}
test winpipe-1.15 {32 bit comprehensive tests: a lot to pipe} \


	{pcOnly stdio cat32} {

    exec $cat32 < big | $tcltest more > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr32"
test winpipe-1.16 {32 bit comprehensive tests: to console} {pcOnly stdio cat32} {
    catch {exec $cat32 << "You should see this\n" >@stdout} msg
    set msg
} stderr32
test winpipe-1.17 {32 bit comprehensive tests: to NUL} {pcOnly stdio cat32} {
    # some apps hang when sending a large amount to NUL.  $cat32 isn't one.
    catch {exec $cat32 < big > nul} msg
    set msg
} stderr32
test winpipe-1.18 {32 bit comprehensive tests: to nowhere} \
	{pcOnly stdio cat32 .console} {
    exec $cat32 < big >&@stdout 
} {}
test winpipe-1.19 {32 bit comprehensive tests: to file handle} {pcOnly stdio cat32} {
    set f1 [open "stdout" w]
    set f2 [open "stderr" w]
    exec $cat32 < little >@$f1 2>@$f2
    close $f1
    close $f2
    list [contents stdout] [contents stderr]
} {little stderr32}
test winpipe-1.20 {32 bit comprehensive tests: write to application} \
	{pcOnly stdio cat32} {
    set f [open "|$cat32 > stdout" w]
    puts -nonewline $f "foo"
    catch {close $f} msg
    list [contents stdout] $msg
} {foo stderr32}
test winpipe-1.21 {32 bit comprehensive tests: read/write application} \
	{pcOnly stdio cat32} {
    set f [open "|$cat32" r+]
    puts $f $big
    puts $f \032
    flush $f
    set r [read $f 64]
    catch {close $f}
    set r
} "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"







test winpipe-2.1 {16 bit comprehensive tests: from little file} {pcOnly stdio cat16} {
    exec $cat16 < little > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "little stderr16"
test winpipe-2.2 {16 bit comprehensive tests: from big file} {pcOnly stdio cat16} {
    exec $cat16 < big > stdout 2> stderr
    list [contents stdout] [contents stderr] 
} "{$big} stderr16"
test winpipe-2.3 {16 bit comprehensive tests: a little from pipe} {pcOnly stdio cat16} {
    exec $tcltest more < little | $cat16 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} {little stderr16}
test winpipe-2.4 {16 bit comprehensive tests: a lot from pipe} {nt stdio cat16} {




    exec $cat16 < big | $cat16 > stdout 2> stderr
    list [contents stdout] [contents stderr] 
} "{$big} stderr16stderr16"
test winpipe-2.5 {16 bit comprehensive tests: a lot from pipe} {95 stdio cat16} {
    exec $tcltest more < big | $cat16 > stdout 2> stderr
    list [contents stdout] [contents stderr] 
} "{$big} stderr16"
test winpipe-2.6 {16 bit comprehensive tests: from console} \
	{pcOnly stdio cat16 AllocConsole} {
    # would block waiting for human input
} {}		     
test winpipe-2.7 {16 bit comprehensive tests: from NUL} {nt stdio cat16} {
    exec $cat16 < nul > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{} stderr16"
test winpipe-2.8 {16 bit comprehensive tests: from socket} {pcOnly stdio cat16} {
    # doesn't work
} {}
test winpipe-2.9 {16 bit comprehensive tests: from nowhere} {pcOnly stdio cat16 .console} {
    exec $cat16 > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{} stderr16"
test winpipe-2.10 {16 bit comprehensive tests: from file handle} {pcOnly stdio cat16} {
    set f [open "little" r]
    exec $cat16 <@$f > stdout 2> stderr
    close $f
    list [contents stdout] [contents stderr]
} "little stderr16"
test winpipe-2.11 {16 bit comprehensive tests: read from application} {pcOnly stdio cat16} {
    set f [open "|$cat16 < little" r]
    gets $f line
    catch {close $f} msg
    list $line $msg
} "little stderr16"
test winpipe-2.12 {16 bit comprehensive tests: a little to file} {pcOnly stdio cat16} {
    exec $cat16 < little > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "little stderr16"
test winpipe-2.13 {16 bit comprehensive tests: a lot to file} {pcOnly stdio cat16} {
    exec $cat16 < big > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr16"
test winpipe-2.14 {16 bit comprehensive tests: a little to pipe} {pcOnly stdio cat16} {




    exec $cat16 < little | $tcltest more > stdout 2> stderr
    list [contents stdout] [contents stderr]




} {little stderr16}
test winpipe-2.15 {16 bit comprehensive tests: a lot to pipe} {pcOnly stdio cat16} {
    exec $cat16 < big | $tcltest more > stdout 2> stderr
    list [contents stdout] [contents stderr]
} "{$big} stderr16"
test winpipe-2.16 {16 bit comprehensive tests: to console} {pcOnly stdio cat16} {
    catch {exec $cat16 << "You should see this\n" >@stdout} msg
    set msg
} [lindex stderr16 0]
test winpipe-2.17 {16 bit comprehensive tests: to NUL} {nt stdio cat16} {
    # some apps hang when sending a large amount to NUL.  cat16 isn't one.
    catch {exec $cat16 < big > nul} msg
    set msg
} stderr16
test winpipe-2.18 {16 bit comprehensive tests: to nowhere} {pcOnly stdio cat16 .console} {
    exec $cat16 < big >&@stdout 
} {}
test winpipe-2.19 {16 bit comprehensive tests: to file handle} {pcOnly stdio cat16} {
    set f1 [open "stdout" w]
    set f2 [open "stderr" w]
    exec $cat16 < little >@$f1 2>@$f2
    close $f1
    close $f2
    list [contents stdout] [contents stderr]
} "little stderr16"
test winpipe-2.20 {16 bit comprehensive tests: write to application} {pcOnly stdio cat16} {
    set f [open "|$cat16 > stdout" w]
    puts -nonewline $f "foo"
    catch {close $f} msg
    list [contents stdout] $msg
} "foo stderr16"
test winpipe-2.21 {16 bit comprehensive tests: read/write application} {nt stdio cat16} {
    set f [open "|$cat16" r+]
    puts $f $big
    puts $f \032
    flush $f
    set r [read $f 64]
    catch {close $f}
    set r
} "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
file delete more


test winpipe-4.1 {Tcl_WaitPid} {nt stdio} {
    proc readResults {f} {
	global x result
	if { [eof $f] } {
	    close $f
	    set x 1
	} else {
	    set line [read $f ]
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














catch {set env_tmp $env(TMP)}
catch {set env_temp $env(TEMP)}

set env(TMP) c:/
set env(TEMP) c:/

test winpipe-3.1 {TclpCreateTempFile: cleanup temp files} {
    set x {}
    set existing [glob -nocomplain c:/tcl*.tmp]
    exec $tcltest < nothing 
    foreach p [glob -nocomplain c:/tcl*.tmp] {
	if {[lsearch $existing $p] != -1} {
	    lappend x $p
	}
    }
    set x
} {}
test winpipe-3.2 {TclpCreateTempFile: TMP and TEMP not defined} {
    set tmp $env(TMP)
    set temp $env(TEMP)
    unset env(TMP)
    unset env(TEMP)
    exec $tcltest < nothing
    set env(TMP) $tmp
    set env(TEMP) $temp
    set x {}
} {}
test winpipe-3.3 {TclpCreateTempFile: TMP specifies non-existent directory} {

    set tmp $env(TMP)
    set env(TMP) snarky
    exec $tcltest < nothing
    set env(TMP) $tmp
    set x {}
} {}
test winpipe-3.3 {TclpCreateTempFile: TEMP specifies non-existent directory} {

    set tmp $env(TMP)
    set temp $env(TEMP)
    unset env(TMP)
    set env(TEMP) snarky
    exec $tcltest < nothing
    set env(TMP) $tmp
    set env(TEMP) $temp
    set x {}
} {}














































# restore old values fro env(TMP) and env(TEMP)

if {[catch {set env(TMP) $env_tmp}]} {
    unset $env(TMP)
}
if {[catch {set env(TEMP) $env_temp}]} {
    unset $env(TEMP)
}


file delete big little stdout stderr nothing




















|




|





|









|
>






|
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


|


|


>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413

catch {set env_tmp $env(TMP)}
catch {set env_temp $env(TEMP)}

set env(TMP) c:/
set env(TEMP) c:/

test winpipe-4.1 {TclpCreateTempFile: cleanup temp files} {pcOnly stdio} {
    set x {}
    set existing [glob -nocomplain c:/tcl*.tmp]
    exec $tcltest < nothing 
    foreach p [glob -nocomplain c:/tcl*.tmp] {
	if {[lsearch $existing $p] == -1} {
	    lappend x $p
	}
    }
    set x
} {}
test winpipe-4.2 {TclpCreateTempFile: TMP and TEMP not defined} {pcOnly stdio} {
    set tmp $env(TMP)
    set temp $env(TEMP)
    unset env(TMP)
    unset env(TEMP)
    exec $tcltest < nothing
    set env(TMP) $tmp
    set env(TEMP) $temp
    set x {}
} {}
test winpipe-4.3 {TclpCreateTempFile: TMP specifies non-existent directory} \
	{pcOnly stdio} {
    set tmp $env(TMP)
    set env(TMP) snarky
    exec $tcltest < nothing
    set env(TMP) $tmp
    set x {}
} {}
test winpipe-4.4 {TclpCreateTempFile: TEMP specifies non-existent directory} \
	{pcOnly stdio} {
    set tmp $env(TMP)
    set temp $env(TEMP)
    unset env(TMP)
    set env(TEMP) snarky
    exec $tcltest < nothing
    set env(TMP) $tmp
    set env(TEMP) $temp
    set x {}
} {}

test winpipe-5.1 {PipeSetupProc & PipeCheckProc: read threads} \
	{pcOnly stdio cat32} {
    set f [open "|$cat32" r+]
    fconfigure $f -blocking 0
    fileevent $f writable { set x writable }
    set x {}
    vwait x
    fileevent $f writable {}
    fileevent $f readable { lappend x readable }
    after 100 { lappend x timeout }
    vwait x
    puts $f foobar
    flush $f
    vwait x
    lappend x [read $f]
    after 100 { lappend x timeout }
    vwait x
    lappend x [catch {close $f} msg] $msg
} {writable timeout readable {foobar
} timeout 1 stderr32}
test winpipe-5.2 {PipeSetupProc & PipeCheckProc: write threads} \
	{pcOnly stdio cat32} {
    set f [open "|$cat32" r+]
    fconfigure $f -blocking 0
    fileevent $f writable { set x writable }
    set x {}
    vwait x
    puts -nonewline $f $big$big$big$big
    flush $f
    after 100 { lappend x timeout }
    vwait x
    lappend x [catch {close $f} msg] $msg
} {writable timeout 0 {}}

makeFile {
    puts "[list $argv0 $argv]"
} echoArgs.tcl

test winpipe-4.1 {BuildCommandLine: null arguments} {pcOnly stdio} {
    exec $tcltest echoArgs.tcl foo "" bar
} {echoArgs.tcl {foo {} bar}}
test winpipe-4.1 {BuildCommandLine: null arguments} {pcOnly stdio} {
    exec $tcltest echoArgs.tcl foo \" bar
} {echoArgs.tcl {foo {"} bar}}

# restore old values for env(TMP) and env(TEMP)

if {[catch {set env(TMP) $env_tmp}]} {
    unset env(TMP)
}
if {[catch {set env(TEMP) $env_temp}]} {
    unset env(TEMP)
}

# cleanup
file delete big little stdout stderr nothing echoArgs.tcl
::tcltest::cleanupTests
return











Added tests/winTime.test.



































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# This file tests the tclWinTime.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 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: winTime.test,v 1.1.2.1 1999/04/06 00:29:19 stanton Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

# The next two tests will crash on Windows if the check for negative
# clock values is not done properly.

test winTime-1.1 {TclpGetDate} {pcOnly} {
    set ::env(TZ) JST-9
    set result [clock format -1 -format %Y]
    unset ::env(TZ)
    set result
} {1970}
test winTime-1.2 {TclpGetDate} {pcOnly} {
    set ::env(TZ) PST8
    set result [clock format 1 -format %Y]
    unset ::env(TZ)
    set result
} {1969}

# cleanup
::tcltest::cleanupTests
return












Changes to tools/Makefile.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
# This makefile is used to convert Tcl manual pages into various
# alternate formats:
#
#    Windows help file:  1. Build the winhelp target on Unix
#			 2. Build the helpfile target on Windows
#
#    HTML:		 1. Build the html target on Unix

# SCCS: %Z% $Id: Makefile.in,v 1.1 1998/04/28 18:53:49 stanton Exp $ 

TCL = tcl@TCL_VERSION@@TCL_PATCH_LEVEL@
TK = tk@TCL_VERSION@@TCL_PATCH_LEVEL@
VER=@TCL_WIN_VERSION@


TCL_SOURCE = @srcdir@/..
TK_SOURCE = @srcdir@/../../$(TK)



TCL_DOCS = \
	$(TCL_SOURCE)/doc/*.[13n]

TK_DOCS = \
	$(TK_SOURCE)/doc/*.[13n]


TCLSH = $(TCL_SOURCE)/unix/tclsh






all: winhelp





winhelp: tcl.rtf
html: tcl$(VER).html



man2tcl: man2tcl.c
	$(CC) $(CFLAGS) -o man2tcl man2tcl.c



tcl.rtf: man2help.tcl man2tcl $(TCL_DOCS) $(TK_DOCS)
	$(TCLSH) man2help.tcl tcl $(VER) \
		$(TCL_SOURCE)/doc $(TK_SOURCE)/doc


tcl$(VER).html: man2html.tcl man2tcl $(TCL_DOCS) $(TK_DOCS)
	$(TCLSH) man2html.tcl tcl$(VER).html \
		../.. ${TCL} ${TK}



clean:
	-rm -f man2tcl *.o tcl$(VER).cnt tcl$(VER).rtf

helpfile:
	hc31 tcl.hpj
	mv tcl.hlp tcl$(VER).hlp









|

|
|


>
|
|
>
>







>
|

>
>
>

>
|
>
>
>
>

<
|

>
>
|
<
>
>

|
|
|
>

<
|
|
>
>


|


|
<
<
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


# This makefile is used to convert Tcl manual pages into various
# alternate formats:
#
#    Windows help file:  1. Build the winhelp target on Unix
#			 2. Build the helpfile target on Windows
#
#    HTML:		 1. Build the html target on Unix

# RCS: @(#) $Id: Makefile.in,v 1.1.2.5 1999/03/10 06:49:26 stanton Exp $

TCL = tcl@TCL_VERSION@
TK = tk@TCL_VERSION@
VER=@TCL_WIN_VERSION@

TCL_BIN_DIR = @TCL_BIN_DIR@
TCL_SOURCE = @TCL_SRC_DIR@
TK_SOURCE = $(TCL_SOURCE)/../$(TK)
PRO_SOURCE = $(TCL_SOURCE)/../pro
ITCL_SOURCE = $(TCL_SOURCE)/../itcl3.0.1

TCL_DOCS = \
	$(TCL_SOURCE)/doc/*.[13n]

TK_DOCS = \
	$(TK_SOURCE)/doc/*.[13n]

PRO_DOCS = \
	$(PRO_SOURCE)/doc/man/*.[13n]

ITCL_DOCS = \
	$(ITCL_SOURCE)/itcl/doc/*.[13n] \
	$(ITCL_SOURCE)/itk/doc/*.[13n]

#	$(ITCL_SOURCE)/iwidgets3.0.0/doc/*.[13n]

COREDOCS = $(TCL_DOCS) $(TK_DOCS) 
PRODOCS = $(COREDOCS) $(PRO_DOCS) $(ITCL_DOCS)
TCLSH = $(TCL_BIN_DIR)/tclsh
CC=@CC@


all: core

pro:
	$(MAKE) DOCS="$(PRODOCS)" VER="" rtf


core:
	$(MAKE) DOCS="$(COREDOCS)" rtf

rtf: $(TCL_SOURCE)/tools/man2help.tcl man2tcl $(DOCS)
	LD_LIBRARY_PATH=$(TCL_BIN_DIR) \
	TCL_LIBRARY=$(TCL_SOURCE)/library \
	$(TCLSH) $(TCL_SOURCE)/tools/man2help.tcl tcl "$(VER)" $(DOCS)


winhelp: tcl.rtf

man2tcl: $(TCL_SOURCE)/tools/man2tcl.c
	$(CC) $(CFLAGS) -o man2tcl $(TCL_SOURCE)/tools/man2tcl.c

clean:
	-rm -f man2tcl *.o *.cnt *.rtf

helpfile:
	hcw /c /e tcl.hpj


Added tools/checkLibraryDoc.tcl.





































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# checkLibraryDoc.tcl --
#
# This script attempts to determine what APIs exist in the source base that 
# have not been documented.  By grepping through all of the doc/*.3 man 
# pages, looking for "Pkg_*" (e.g., Tcl_ or Tk_), and comparing this list
# against the list of Pkg_ APIs found in the source (e.g., tcl8.1/*/*.[ch])
# we create six lists:
#      1) APIs in Source not in Docs.
#      2) APIs in Docs not in Source.
#      3) Internal APIs and structs.
#      4) Misc APIs and structs that we are not documenting.
#      5) Command APIs (e.g., Tcl_ArrayObjCmd.)
#      6) Proc pointers (e.g., Tcl_CloseProc.)
# 
# Note: Each list is "a best guess" approximation.  If developers write
# non-standard code, this script will produce erroneous results.  Each
# list should be carefully checked for accuracy. 
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
# 
# RCS: @(#) $Id: checkLibraryDoc.tcl,v 1.1.2.1 1999/04/14 00:26:38 surles Exp $


#lappend auto_path "c:/program\ files/tclpro1.2/win32-ix86/bin"
if {[catch {package require Tclx}]} {
    puts "error: could not load TclX.  Please set TCL_LIBRARY."
    exit 1
}

# A list of structs that are known to be undocumented.

set StructList {
    Tcl_AsyncHandler \
    Tcl_CallFrame \
    Tcl_Condition \
    Tcl_Encoding \
    Tcl_EncodingState \
    Tcl_EncodingType \
    Tcl_EolTranslation \
    Tcl_HashEntry \
    Tcl_HashSearch \
    Tcl_HashTable \
    Tcl_Mutex \
    Tcl_Pid \
    Tcl_QueuePosition \
    Tcl_ResolvedVarInfo \
    Tcl_SavedResult \
    Tcl_ThreadDataKey \
    Tcl_ThreadId \
    Tcl_Time \
    Tcl_TimerToken \
    Tcl_Token \
    Tcl_Trace \
    Tcl_Value \
    Tcl_ValueType \
    Tcl_Var \
}

# Misc junk that appears in the comments of the source.  This just 
# allows us to filter comments that "fool" the script.

set CommentList {
    Tcl_Create\[Obj\]Command \
    Tcl_DecrRefCount\\n \
    Tcl_NewObj\\n \
}

# Main entry point to this script.

proc main {} {
    global argv0 
    global argv 

    set len [llength $argv]
    if {($len != 2) && ($len != 3)} {
	puts "usage: $argv0 pkgName pkgDir \[outFile\]"
	puts "   pkgName == Tcl,Tk"
	puts "   pkgDir  == /home/surles/cvs/tcl8.1"
	exit 1
    }

    set pkg [lindex $argv 0]
    set dir [lindex $argv 1]
    if {[llength $argv] == 3} {
	set file [open [lindex $argv 2] w]
    } else {
	set file stdout
    }

    foreach {c d} [compare [grepCode $dir $pkg] [grepDocs $dir $pkg]] {}
    filter $c $d $dir $pkg $file

    if {$file != "stdout"} {
	close $file
    }
    return
}
    
# Intersect the two list and write out the sets of APIs in one
# list that is not in the other.

proc compare {list1 list2} {
    set inter [intersect3 $list1 $list2]
    return [list [lindex $inter 0] [lindex $inter 2]]
}

# Filter the lists into the six lists we report on.  Then write
# the results to the file.

proc filter {code docs dir pkg {outFile stdout}} {
    # A list of Tcl command APIs.  These are not documented.
    # This list should just be verified for accuracy.

    set cmds  {}
    
    # A list of proc pointer structs.  These are not documented.
    # This list should just be verified for accuracy.

    set procs {}

    # A list of internal declarations.  These are not documented.
    # This list should just be verified for accuracy.

    set decls [grepDecl $dir $pkg]

    # A list of misc. procedure declarations that are not documented.
    # This list should just be verified for accuracy.

    set misc [grepMisc $dir $pkg]

    # A list of APIs in the source, not in the docs.
    # This list should just be verified for accuracy.

    foreach x $code {
	if {[string match *Cmd $x]} {
	    lappend cmds $x
	} elseif {[string match *Proc $x]} {
	    lappend procs $x
	} elseif {[lsearch -exact $decls $x] >= 0} {
	    # No Op.
	} elseif {[lsearch -exact $misc $x] >= 0} {
	    # No Op.
	} else {
	    lappend apis $x
	}
    }

    dump $apis  "APIs in Source not in Docs." $outFile
    dump $docs  "APIs in Docs not in Source." $outFile
    dump $decls "Internal APIs and structs."  $outFile
    dump $misc  "Misc APIs and structs that we are not documenting." $outFile
    dump $cmds  "Command APIs."  $outFile
    dump $procs "Proc pointers." $outFile
    return
}

# Print the list of APIs if the list is not null.

proc dump {list title file} {
    if {$list != {}} {
	puts $file ""
	puts $file $title
	puts $file "---------------------------------------------------------"
	foreach x $list {
	    puts $file $x
	}
    }
}

# Grep into "dir/*/*.[ch]" looking for APIs that match $pkg_*.
# (e.g., Tcl_Exit).  Return a list of APIs.

proc grepCode {dir pkg} {
    set apis [exec grep "${pkg}_\.\*" "${dir}/\*/\*\.\[ch\]" | cat]
    set pat1 ".*(Tcl_\[A-z0-9]+).*$"
 
    foreach a [split $apis "\n"] {
	if {[regexp --  $pat1 $a main n1]} {
	    set result([string trim $n1]) 1
	}
    }
    return [lsort [array names result]]
}

# Grep into "dir/doc/*.3" looking for APIs that match $pkg_*.
# (e.g., Tcl_Exit).  Return a list of APIs.

proc grepDocs {dir pkg} {
    set apis [exec grep "\\fB${pkg}_\.\*\\fR" "${dir}/doc/\*\.3" | cat]
    set pat1 ".*(Tcl_\[A-z0-9]+).*$"

    foreach a $apis {
	if {[regexp -- $pat1 $a main n1]} {
	    set result([string trim $n1]) 1
	}
    }
    return [lsort [array names result]]
}

# Grep into "generic/pkgIntDecls.h" looking for APIs that match $pkg_*.
# (e.g., Tcl_Export).  Return a list of APIs.

proc grepDecl {dir pkg} {
    set file [file join $dir generic "[string tolower $pkg]IntDecls.h"] 
    set apis [exec grep "^EXTERN.*\[ \t\]Tcl_.*" $file | cat]
    set pat1 ".*(Tcl_\[A-z0-9]+).*$"

    foreach a $apis {
	if {[regexp -- $pat1 $a main n1]} {
	    set result([string trim $n1]) 1
	}
    }
    return [lsort [array names result]]
}

# Grep into "*/*.[ch]" looking for APIs that match $pkg_Db*.
# (e.g., Tcl_DbCkalloc).  Return a list of APIs.

proc grepMisc {dir pkg} {
    global CommentList
    global StructList
    
    set apis [exec grep "^EXTERN.*\[ \t\]Tcl_Db.*" "${dir}/\*/\*\.\[ch\]" \
	    | cat]
    set pat1 ".*(Tcl_\[A-z0-9]+).*$"

    foreach a $apis {
	if {[regexp -- $pat1 $a main n1]} {
	    set dbg([string trim $n1]) 1
	}
    }

    set result {}
    eval {lappend result} $StructList
    eval {lappend result} [lsort [array names dbg]]
    eval {lappend result} $CommentList
    return $result
}

main

Changes to tools/configure.in.

1
2
3
4
5
6
7
8













9
10
11
12
13
14
15
16


17
18

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)
# SCCS: %Z% $Id: configure.in,v 1.1 1998/04/28 18:53:49 stanton Exp $ 

# Recover information that Tcl computed with its configure script.














. ../unix/tclConfig.sh

TCL_WIN_VERSION=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
AC_SUBST(TCL_WIN_VERSION)
CC=$TCL_CC
AC_SUBST(CC)
AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_PATCH_LEVEL)



AC_OUTPUT(Makefile)





|



>
>
>
>
>
>
>
>
>
>
>
>
>
|







>
>


>
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
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.1.2.4 1999/03/17 20:16:23 welch 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.
#--------------------------------------------------------------------

AC_ARG_WITH(tcl, [  --with-tcl=DIR          use Tcl 8.1 binaries from DIR], TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd ../../tcl8.1$TCL_PATCH_LEVEL/unix; pwd`)
if test ! -d $TCL_BIN_DIR; then
    AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR doesn't exist)
fi
if test ! -f $TCL_BIN_DIR/tclConfig.sh; then
    AC_MSG_ERROR(There's no tclConfig.sh in $TCL_BIN_DIR;  perhaps you didn't specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?)
fi

. $TCL_BIN_DIR/tclConfig.sh

TCL_WIN_VERSION=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
AC_SUBST(TCL_WIN_VERSION)
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)

Added tools/cvtEOL.tcl.







































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# cvtEOL.tcl --
#
# This file contains a script to parse a Tcl/Tk distribution and
# convert the EOL from \n to \r on all text files.
#
# Copyright (c) 1996-1997 by Sun Microsystems, Inc.
#
# SCCS: @(#) cvtEOL.tcl 1.1 97/01/30 11:33:33
#

#
# Convert files in the distribution to Mac style
#

set distDir [lindex $argv 0]

set dirs {unix mac generic win library compat tests unix/dltest \
	  library/demos library/demos/images bitmaps xlib xlib/X11 .}
set files {*.c *.y *.h *.r *.tcl *.test *.rc *.bc *.vc *.bmp *.html \
	   *.in *.notes *.terms all defs \
	   README ToDo changes tclIndex configure install-sh mkLinks \
	   square widget rmt ixset hello browse rolodex tcolor timer}

foreach x $dirs {
  if [catch {cd $distDir/$x}] continue
  puts "Working on $x..."
  foreach y [eval glob $files] {
    exec chmod 666 $y
    exec cp $y $y.tmp
    exec tr \012 \015 < $y.tmp > $y
    exec chmod 444 $y
    exec rm $y.tmp
  }
}

Added tools/encoding/Makefile.





























































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#
# This file is a Makefile to compile all the encoding files.  
#
# Run "make" to compile all the encoding files (*.txt,*.esc) into the
# format that Tcl can use (*.enc).  It is your responsibility to move the
# encoding files to the appropriate place ($TCL_ROOT/library/encoding
#
# The .txt files in this directory come from the Unicode CD and are covered
# by the following copyright notice:
#
#---------------------------------------------------------------------------
#
# Copyright (c) 1996 Unicode, Inc.  All Rights reserved.
#
# This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
# No claims are made as to fitness for any particular purpose.  No
# warranties of any kind are expressed or implied.  The recipient
# agrees to determine applicability of information provided.  If this
# file has been provided on magnetic media by Unicode, Inc., the sole
# remedy for any claim will be exchange of defective media within 90
# days of receipt.
#
# Recipient is granted the right to make copies in any form for
# internal distribution and to freely use the information supplied
# in the creation of products supporting Unicode.  Unicode, Inc.
# specifically excludes the right to re-distribute this file directly
# to third parties or other organizations whether for profit or not.
#
# In other words:  Don't put this file on the Internet.  People who want to 
# get it over the Internet should do so directly from ftp://unicode.org.  They
# can therefore be assured of getting the most recent and accurate version.
#
#----------------------------------------------------------------------------
#
# The txt2enc program built by this makefile is used to compile individual
# .txt files into .enc files, the format that Tcl understands for encoding 
# files.  This compilation to a different format is allowed by the above
# restriction. 
#
# The files shiftjis.txt and jis0208.txt were modified from the original
# ones provided on the Unicode CD.  The double-width backslash character
# 0x815F in these two Japanese encodings was being mapped to Unicode 005C
# (REVERSE SOLIDUS), the normal backslash character.  They have been
# changed to map 0x815F to Unicode FF3C (FULLWIDTH REVERSE SOLIDUS) and let
# the regular backslash character map to itself.  This follows how cp932
# behaves.
#
# 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.
#
# SCCS: @(#) Makefile 1.1 98/01/28 11:41:36
#

EUC_ENCODINGS = euc-cn.txt euc-kr.txt euc-jp.txt 

encodings: clean txt2enc $(EUC_ENCODINGS)
	@echo Compiling encoding files.
	@for p in *.esc; do \
	    base=`echo $$p | sed 's/\..*$$//'`; \
	    echo $$base.enc; \
	    echo "# Encoding file: $$base, escape-driven" > $$base.enc; \
	    echo "E" >> $$base.enc; \
	    cat $$p >> $$base.enc; \
	done
	@for p in *.txt; do \
	    enc=`echo $$p | sed 's/\..*$$/\.enc/'`; \
	    echo $$enc; \
	    ./txt2enc -e 0 -u 1 $$p > $$enc; \
	done
	@echo 
	@echo Compiling special versions of encoding files.
	@for p in ascii.txt; do \
	    enc=`echo $$p | sed 's/\..*$$/\.enc/'`; \
	    echo $$enc; \
	    ./txt2enc -m $$p > $$enc; \
	done
	@for p in jis0208.txt; do \
	    enc=`echo $$p | sed 's/\..*$$/\.enc/'`; \
	    echo $$enc; \
	    ./txt2enc -e 1 -u 2 $$p > $$enc; \
	done
	@for p in symbol.txt dingbats.txt macDingbats.txt; do \
	    enc=`echo $$p | sed 's/\..*$$/\.enc/'`; \
	    echo $$enc; \
	    ./txt2enc -e 0 -u 1 -s $$p > $$enc; \
	done

clean:
	@rm -f txt2enc *.enc $(EUC_ENCODINGS)

txt2enc: txt2enc.c
	@gcc -o txt2enc txt2enc.c

euc-jp.txt: ascii.txt jis0208.txt Makefile
	@echo Building euc-jp.txt from components.
	@cat ascii.txt > euc-jp.txt
	@grep '^0x[A-F]' jis0201.txt | sed 's/0x/0x8E/' >> euc-jp.txt
	@cat jis0208.txt | awk 'BEGIN {print "ibase=16"} index($$1,"#") != 1 {print substr($$2,3) "+" 8080; print substr($$3,3)}' | bc | awk '{ str = $$1; getline; printf "0x%04x 0x%04x\n", str, $$0}' >> euc-jp.txt

euc-kr.txt: ascii.txt ksc5601.txt Makefile
	@echo Building euc-kr.txt from components.
	@cat ascii.txt > euc-kr.txt
	@cat ksc5601.txt | awk 'BEGIN {print "ibase=16"} index($$1,"#") != 1 {print substr($$1,3) "+" 8080; print substr($$2,3)}' | bc | awk '{ str = $$1; getline; printf "0x%04x 0x%04x\n", str, $$0}' >> euc-kr.txt

euc-cn.txt: ascii.txt gb2312.txt Makefile
	@echo Building euc-cn.txt from components.
	@cat ascii.txt > euc-cn.txt
	@cat gb2312.txt | awk 'BEGIN {print "ibase=16"} index($$1,"#") != 1 {print substr($$1,3) "+" 8080; print substr($$2,3)}' | bc | awk '{ str = $$1; getline; printf "0x%04x 0x%04x\n", str, $$0}' >> euc-cn.txt

Added 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).

Added tools/encoding/ascii.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
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

Added tools/encoding/big5.txt.

more than 10,000 changes

Added tools/encoding/cjk.inf.







































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
--- BEGIN (CJK.INF VERSION 2.1 07/12/96) 185553 BYTES ---
CJK.INF Version 2.1 (July 12, 1996)

Copyright (C) 1995-1996 Ken Lunde. All Rights Reserved.

CJK is a registered trademark and service mark of The Research
  Libraries Group, Inc.

Online Companion to "Understanding Japanese Information Processing"
- ENGLISH: 1993, O'Reilly & Associates, Inc., ISBN 1-56592-043-0
- JAPANESE: 1995, SOFTBANK Corporation, ISBN 4-89052-708-7


	This online document provides information on CJK (that is,
Chinese, Japanese, and Korean) character set standards and encoding
systems. In short, it provides detailed information on how CJK text is
handled electronically. I am happy to share this information with
others, and I would appreciate any comments/feedback on its content.
The current version (master copy) of this document is maintained at:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/cjk.inf

This file may also be obtained by contacting me directly using one of
the e-mail addresses listed in the CONTACT INFORMATION section.


TABLE OF CONTENTS

  VERSION HISTORY
  RESTRICTIONS
  CONTACT INFORMATION
  WHAT HAPPENED TO JAPAN.INF?
  DISCLAIMER
  CONVENTIONS
  INTRODUCTION
  PART 1: WHAT'S UP WITH UJIP?
  PART 2: CJK CHARACTER SET STANDARDS
    2.1: JAPANESE
      2.1.1: JIS X 0201-1976
      2.1.2: JIS X 0208-1990
      2.1.3: JIS X 0212-1990
      2.1.4: JIS X 0221-1995
      2.1.5: JIS X 0213-199X
      2.1.6: OBSOLETE STANDARDS
    2.2: CHINESE (PRC)
      2.2.1: GB 1988-89
      2.2.2: GB 2312-80
      2.2.3: GB 6345.1-86
      2.2.4: GB 7589-87
      2.2.5: GB 7590-87
      2.2.6: GB 8565.2-88
      2.2.7: GB/T 12345-90
      2.2.8: GB/T 13131-9X
      2.2.9: GB/T 13132-9X
      2.2.10: GB 13000.1-93
      2.2.11: ISO-IR-165:1992
      2.2.12: OBSOLETE STANDARDS
    2.3: CHINESE (TAIWAN)
      2.3.1: BIG FIVE
      2.3.2: CNS 11643-1992
      2.3.3: CNS 5205
      2.3.4: OBSOLETE STANDARDS
    2.4: KOREAN
      2.4.1: KS C 5636-1993
      2.4.2: KS C 5601-1992
      2.4.3: KS C 5657-1991
      2.4.4: GB 12052-89
      2.4.5: KS C 5700-1995
      2.4.6: OBSOLETE STANDARDS
    2.5: CJK
      2.5.1: ISO 10646-1:1993
      2.5.2: CCCII
      2.5.3: ANSI Z39.64-1989
    2.6: OTHER
      2.6.1: GB 8045-87
      2.6.2: TCVN-5773:1993
  PART 3: CJK ENCODING SYSTEMS
    3.1: 7-BIT ISO 2022 ENCODING
      3.1.1: CODE SPACE
      3.1.2: ISO-REGISTERED ESCAPE SEQUENCES
      3.1.3: ISO-2022-JP AND ISO-2022-JP-2
      3.1.4: ISO-2022-KR
      3.1.5: ISO-2022-CN AND ISO-2022-CN-EXT
    3.2: EUC ENCODING
      3.2.1: JAPANESE REPRESENTATION
      3.2.2: CHINESE (PRC) REPRESENTATION
      3.2.3: CHINESE (TAIWAN) REPRESENTATION
      3.2.4: KOREAN REPRESENTATION
    3.3: LOCALE-SPECIFIC ENCODINGS
      3.3.1: SHIFT-JIS
      3.3.2: HZ (HZ-GB-2312)
      3.3.3: zW
      3.3.4: BIG FIVE
      3.3.5: JOHAB
      3.3.6: N-BYTE HANGUL
      3.3.7: UCS-2
      3.3.8: UCS-4
      3.3.9: UTF-7
      3.3.10: UTF-8
      3.3.11: UTF-16
      3.3.12: ANSI Z39.64-1989
      3.3.13: BASE64
      3.3.14: IBM DBCS-HOST
      3.3.15: IBM DBCS-PC
      3.3.16: IBM DBCS-/TBCS-EUC
      3.3.17: UNIFIED HANGUL CODE
      3.3.18: TRON CODE
      3.3.19: GBK
    3.4: CJK CODE PAGES
  PART 4: CJK CHARACTER SET COMPATIBILITY ISSUES
    4.1: JAPANESE
    4.2: CHINESE (PRC)
    4.3: CHINESE (TAIWAN)
    4.4: KOREAN
    4.5: ISO 10646-1:1993
    4.6: UNICODE
    4.7: CODE CONVERSION TIPS
  PART 5: CJK-CAPABLE OPERATING SYSTEMS
    5.1: MS-DOS
    5.2: WINDOWS
    5.3: MACINTOSH
    5.4: UNIX AND X WINDOWS
    5.5: OTHERS
  PART 6: CJK TEXT AND INTERNET SERVICES
    6.1: ELECTRONIC MAIL
    6.2: USENET NEWS
    6.3: GOPHER
    6.4: WORLD-WIDE WEB
    6.5: FILE TRANSFER TIPS
  PART 7: CJK TEXT HANDLING SOFTWARE
    7.1: MULE
    7.2: CNPRINT
    7.3: MASS
    7.4: ADOBE TYPE MANAGER (ATM)
    7.5: MACINTOSH SOFTWARE
    7.6: MACBLUE TELNET
    7.7: CXTERM
    7.8: UW-DBM
    7.9: POSTSCRIPT
    7.10: NJWIN
  PART 8: CJK PROGRAMMING ISSUES
    8.1: C AND C++
    8.2: PERL
    8.3: JAVA
  A FINAL NOTE
  ACKNOWLEDGMENTS
  APPENDIX A: INFORMATION SOURCES
    A.1: USENET NEWSGROUPS AND MAILING LISTS
      A.1.1: USENET NEWSGROUPS
      A.1.2: MAILING LISTS
    A.2: INTERNET RESOURCES
      A.2.1: USEFUL FTP SITES
      A.2.2: USEFUL TELNET SITES
      A.2.3: USEFUL GOPHER SITES
      A.2.4: USEFUL WWW SITES
      A.2.5: USEFUL MAIL SERVERS
    A.3: OTHER RESOURCES
      A.3.1: BOOKS
      A.3.2: MAGAZINES
      A.3.3: JOURNALS
      A.3.4: RFCs
      A.3.5: FAQs


VERSION HISTORY

	The following is a complete listing of the earlier versions of
this document along with their release dates and sizes (in bytes):

  Document   Version  Release Date  Size
  ^^^^^^^^   ^^^^^^^  ^^^^^^^^^^^^  ^^^^
  JAPAN.INF  1.0      Unknown       Unknown
  JAPAN.INF  1.1      08/19/91      101,784
  JAPAN.INF  1.2      03/20/92      166,929 (JIS) or 165,639 (Shift-JIS/EUC)
  CJK.INF    1.0      06/09/95      103,985
  CJK.INF    1.1      06/12/95      112,771
  CJK.INF    1.2      06/14/95      125,275
  CJK.INF    1.3      06/16/95      130,069
  CJK.INF    1.4      06/19/95      142,543
  CJK.INF    1.5      06/22/95      146,064
  CJK.INF    1.6      06/29/95      150,882
  CJK.INF    1.7      08/15/95      153,772
  CJK.INF    1.8      09/11/95      157,295
  CJK.INF    1.9      12/18/95      170,698
  CJK.INF    2.0      03/12/96      175,973

With the release of this version, all of the above are now considered
obsolete. Also, note the three-year gap between the last installment
of JAPAN.INF and the first installment of CJK.INF -- I was writing
UJIP and my PhD dissertation during those three years. Ah, so much for
excuses...


RESTRICTIONS

	This document is provided free-of-charge to *anyone*, but no
person or company is permitted to modify, sell, or otherwise
distribute it for profit or other purposes. This document may be
bundled with commercial products only with the prior consent from the
author, and provided that it is not modified in any way whatsoever.
The point here is that I worked long and hard on this document so that
lots of fine folks and companies can benefit from its contents -- not
profit from it.


CONTACT INFORMATION

	I would enjoy hearing from readers of this document, even if
it is just to say "hello" or whatever. I can be contacted as follows:

  Ken Lunde
  Adobe Systems Incorporated
  1585 Charleston Road
  P.O. Box 7900
  Mountain View, CA 94039-7900 USA
  415-962-3866 (office phone)
  415-960-0886 (facsimile)
  [email protected] (preferred)
  [email protected] or [email protected]
  WWW Home Page: http://jasper.ora.com/lunde/

If you wonder what I do for my day job, read on.
	I have been working for Adobe Systems for over four years now
(before that I was a graduate student at UW-Madison), and my current
position is Project Manager, CJK Type Development.


WHAT HAPPENED TO JAPAN.INF?

	Put bluntly, JAPAN.INF died. It first evolved into my first
book entitled "Understanding Japanese Information Processing" (this
book is now into its second printing, and the Japanese translation was
just published). After my book came out, I did attempt to update
JAPAN.INF, but the effort felt a bit futile. I decided that something
fresh was necessary.
	JAPAN.INF also evolved into this document, which breaks the
Japanese barrier by providing similar information on Chinese and
Korean character sets and encodings. It fills the Chinese and Korean
gap, so to speak. My specialty (and hobby, believe it or not) is the
field of CJK character sets and encoding systems, so I felt that
shifting this document more towards those lines was appropriate use of
my (copious) free time (I wish there were more than 24 hours in a
day!). Besides, this document now becomes useful to a much broader
audience.


DISCLAIMER

	Ah yes, the ever popular disclaimer! Here's mine. Although I
list my address here at Adobe Systems Incorporated for contact
purposes, Adobe Systems does not endorse this document which I have
created, and have continued (and will continue) to update on a regular
basis (uh, yeah, I promise this time!). This document is a personal
endeavor to inform people of how CJK text can be handled on a variety
of platforms.


CONVENTIONS

	The notation that is used for detailing Internet resource
information, such as the Internet protocol type, site name, path, and
file follows the URL (Uniform Resource Locator) notation, namely:

  protocol://site-name/path/file

An example URL is as follows:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/00README

The protocol is FTP, the site-name is ftp.ora.com, the path is pub/
examples/nutshell/ujip/, and the file is 00README. Also note that this
same notation is used for invoking FTP on WWW (World Wide Web)
browsing software, such as Mosaic, Netscape, or Lynx.
	Note that most references to HTTP documents use the four-
letter file extension ".html". However, some HTTP documents are on
file systems that support only three-letter file extensions (can you
say "MS-DOS"?), so you may encounter just ".htm". This is just to let
you know that what you see is not a typo.
	References to my book "Understanding Japanese Information
Processing" are (affectionately) abbreviated as UJIP. These references
also apply to the Japanese translation (UJIP-J).
	Hexadecimal values are prefixed with 0x, and every two
hexadecimal digits represent a one-byte value. Other values can be
assumed to be in decimal notation.
	Chinese characters are referred to as kanji (Japanese), hanzi
(Chinese), or hanja (Korean), depending on context.
	References to ISO 10646-1:1993 also refer to Unicode
(usually). I have done this so that I do not have to repeat "Unicode"
in the same context as ISO 10646-1:1993. There are times, however,
when I need to distinguish ISO 10646-1:1993 from Unicode.


INTRODUCTION

	Electronic mail (e-mail), just one of the many Internet
resources, has become a very efficient means of communicating both
locally and world-wide. While it is very simple to send text which
uses only the 94 printable ASCII characters, character sets that
contain more than these ASCII characters pose special problems.
	This document is primarily concerned with CJK character set
and encoding issues. Much of this sort of information is not easily
obtained. This represents one person's attempt at making such
information more widely available.


PART 1: WHAT'S UP WITH UJIP?

	UJIP (First Edition) was published in September 1993 by
O'Reilly & Associates, Incorporated. The second printing (*not* the
Second Edition) was subsequently published in March 1994. The page
count for both printings is unchanged at 470.
	The following files contain the latest information about
changes (additions and corrections) made to UJIP and UJIP-J for
various printings, both for those that have taken place (such as for
the second printing of the English edition) and for those that are
planned (the first digit is the edition, and the second is the
printing):

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/errata/ujip-errata-1-2.txt
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/errata/ujip-errata-1-3.txt
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/errata/ujip-j-errata-1-2.txt

I *highly* recommend that all readers of UJIP obtain these errata
files. Those without FTP access can request copies directly from me.
	The Japanese translation of UJIP (UJIP-J), co-published by
O'Reilly & Associates, Incorporated and SOFTBANK Corporation, was just
released. The translation was done by my good friend Jack Halpern,
along with one of his colleagues, Takeo Suzuki. The Japanese edition
incorporates corrections and updates not yet found in the English
edition. The page count is 535.
	Late-breaking news! I am currently working on UJIP Second
Edition (to be retitled as "Understanding CJK Information Processing"
and abbreviated UCJKIP). If all goes well, it should be available by
January 1997, and will be well over 700 pages. If there was something
you wanted to see in UJIP, now's your chance to send me a request...


PART 2: CJK CHARACTER SET STANDARDS

	These sections describe the character sets used in Japan,
China (PRC and Taiwan), and Korea. Exact numbers of characters are
provided for each character set standard (when known), as well as
tidbits of information not otherwise available. This provides the
basic foundations for understanding how CJK scripts are handled on
computer systems.
	The two basic types of characters enumerated by CJK character
set standards are Chinese characters (kanji, hanzi, or hanja), which
number in the thousands (and, in some cases, tens of thousands), and
characters other than Chinese characters (symbols, numerals, kana
hangul, alphabets, and so on), which usually number in the hundreds
(there are thousands of pre-combined hangul, though).
	If you happen to be running X Windows, it is very easy to
display these CJK character sets (if a bitmapped font for the
character set exists, that is). Here is what I usually do:

o Obtain a BDF (Bitmap Distribution Format) font for the target
  character set. Try the following URLs for starters:

  ftp://cair-archive.kaist.ac.kr/pub/hangul/fonts/
  ftp://etlport.etl.go.jp/pub/mule/fonts/
  ftp://ftp.ifcss.org/pub/software/fonts/{big5,cns,gb,misc,unicode}/bdf/
  ftp://ftp.kuis.kyoto-u.ac.jp/misc/fonts/jisksp-fonts/
  ftp://ftp.net.tsinghua.edu.cn/pub/Chinese/fonts/
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/unix/
  ftp://ftp.technet.sg:/pub/chinese/fonts/
  http://ccic.ifcss.org/www/pub/software/fonts/

  BDF files usually have the string "bdf" somewhere in their file
  name, usually at the end. If the file is compressed (noticing that
  it ends in .gz or .Z is a good indication), decompress it. BDF files
  are text files.

o Convert the BDF file to SNF (Server Natural Format) or PCF (Portable
  Compiled Format) using the programs "bdftosnf" or "bdftopcf,"
  respectively. Example command lines are as follows:

  % bdftopcf jiskan16-1990.bdf > k16-90.pcf
  % bdftosnf jiskan16-1990.bdf > k16-90.snf

  SNF files (and the "bdftosnf" program) are used on X11R4 and
  earlier, and PCF files (and the "bdftopcf" program) are used on
  X11R5 and later.

o Copy the SNF or PCF file to a directory in the font search path (or
  make a new path). Supposing I made a new directory called "fonts" in
  my home directory, I then run "mkfontdir" on the directory
  containing the SNF or PCF files as follows:

  % mkfontdir ~/fonts

  This creates a fonts.dir file in ~/fonts. I can now add this
  directory to my font search path with the following command:

  % xset +fp ~/fonts

o The command "xfd" (X Font Displayer) with the "-fn" switch followed
  by a font name then invokes a window that displays all the
  characters of the font. In the case of two-byte (CJK) fonts, one row
  is displayed at a time. The following is an example command line:

  % xfd -fn -misc-fixed-medium-r-normal--16-150-75-75-c-160-jisx0208.1990-0

  You can create a "fonts.alias" file in the same directory as the
  "fonts.dir" file in order to shorten the name when accessing the
  font. The alias "k16-90" could be used instead if the content of the
  fonts.alias file is as follows:

  k16-90  -misc-fixed-medium-r-normal--16-150-75-75-c-160-jisx0208.1990-0

  Don't forget to execute the following command in order to make the
  X Font Server aware of the new alias:

  % xset fp rehash

  Now you can use a simpler command line for "xfd" as follows:

  % xfd -fn k16-90

	The "X Window System User's Guide" (Volume 3 of the X Window
System series by O'Reilly & Associates, Inc.) provides detailed
information on managing fonts under X Windows (pp 123-160). The
article entitled "The X Administrator: Font Formats and Utilities" (pp
14-34 in "The X Resource," Issue 2), describes the BDF, SNF, and PCF
formats in great detail.
	There is another bitmap format called HBF (Hanzi Bitmap
Format), which is similar to BDF, but optimized for fixed-width
(monospaced) fonts. It is described in the article entitled "The HBF
Font Format: Optimizing Fixed-pitch Font Support" (pp 113-123 in "The
X Resource," Issue 10), and also at the following URL:

  ftp://ftp.ifcss.org/pub/software/fonts/hbf-discussion/

HBF fonts can be found at the following URL:

  ftp://ftp.ifcss.org/pub/software/fonts/{big5,cns,gb,misc,unicode}/hbf/

	Lastly, you may wish to check out my newly-developed CJK
Character Set Server, which generates various CJK character sets with
proper encoding applied. It is written in Perl, and accessed through
an HTML form. This server can be considered an upgrade to my JChar
tool (written in C). The URL is:

  http://jasper.ora.com/lunde/cjk-char.html


2.1: JAPANESE

	All (national) character set standards that originate in Japan
have names that begin with the three letters JIS. JIS is short for
"Japanese Industrial Standard." But it is JSA (Japanese Standards
Association) who publishes the corresponding manuals. Chapter 3 and
Appendixes H and J of UJIP provide more detailed information on
Japanese character set standards.


2.1.1: JIS X 0201-1976

	JIS X 0201-1976 (formerly JIS C 6220-1969; reaffirmed in 1989;
and its revision [with no character set changes] is currently under
public review) enumerates two sets of characters: JIS-Roman and
half-width katakana.
	JIS-Roman is the Japanese equivalent of the ASCII character
set, namely 128 characters consisting of the following:

o 10 numerals
o 52 uppercase and lowercase characters of the Latin alphabet
o 32 symbols (punctuation and so on)
o 34 non-printing characters (white space and control characters)

The term "white space" refers to characters that occupy space, but
have no appearance, such as tabs, spaces, and termination characters
(line feed, carriage return, and form feed).
	So, how are JIS-Roman and ASCII different? The following
three codes are (usually) different:

  Code   ASCII        JIS-Roman
  ^^^^   ^^^^^        ^^^^^^^^^
  0x5C   backslash    yen symbol
  0x7C   broken bar   bar
  0x7E   tilde        overbar

	Half-width katakana consists of 63 characters that provide a
minimal set of characters necessary for expressing Japanese. The
shapes are compressed, and visually occupy a space half that of
*normal* Japanese characters.


2.1.2: JIS X 0208-1990

	This basic Japanese character set standard enumerates 6,879
characters, 6,355 of which are kanji separated into two levels. Kanji
in the first level are arranged by (most frequent) reading, and those
in the second level are arranged by radical then total number of
(remaining) strokes.

o Row 1: 94 symbols
o Row 2: 53 symbols
o Row 3: 10 numerals and 52 uppercase and lowercase Latin alphabet
o Row 4: 83 hiragana
o Row 5: 86 katakana
o Row 6: 48 uppercase and lowercase Greek alphabet
o Row 7: 66 uppercase and lowercase Cyrillic (Russian) alphabet
o Row 8: 32 line-drawing elements
o Rows 16 through 47: 2,965 kanji (JIS Level 1 Kanji; last is 47-51)
o Rows 48 through 84: 3,390 kanji (JIS Level 2 Kanji; last is 84-06)

Appendix B of UJIP provides a complete illustration of the JIS X
0208-1990 character set standard by KUTEN (row-cell) code. Appendix G
(pp 294-317) of "Developing International Software for Windows 95 and
Windows NT" by Nadine Kano illustrates the JIS X 0208-1990 character
set standard plus the Microsoft extensions by Shift-JIS code
(Microsoft calls this Code Page 932).
	Earlier versions of this standard were dated 1978 (JIS C
6226-1978) and 1983 (JIS X 0208-1983, formerly JIS C 6226-1983).
	JIS X 0208 went through a revision (from November 1995 until
February 1996), and is slated for publication sometime in 1996 (to
become JIS X 0208-1996). More information on this revision is
available at the following URL:

  ftp://ftp.tiu.ac.jp/jis/jisx0208/


2.1.3: JIS X 0212-1990

	This supplemental Japanese character set standard enumerates
6,067 characters, 5,801 of which are kanji ordered by radical then
total number of (remaining) strokes. All 5,801 kanji are unique when
compared to those in JIS X 0208-1990 (see Section 2.1.2). The
remaining 266 characters are categorized as non-kanji.

o Row 2: 21 diacritics and symbols
o Row 6: 21 Greek characters with diacritics
o Row 7: 26 Eastern European characters
o Rows 9 through 11: 198 alphabetic characters
o Rows 16 through 77: 5,801 kanji (last is 77-67)

Appendix C of UJIP provides a complete illustration of the JIS X
0212-1990 character set standard by KUTEN (row-cell) code.
	The only commercial operating system that provides JIS X
0212-1990 support is BTRON by Personal Media Corporation:

  http://www.personal-media.co.jp/

Section 3.3.18 provides information about TRON Code (used by BTRON),
and details how it encodes the JIS X 0212-1990 character set.


2.1.4: JIS X 0221-1995

	This document is, for all practical purposes, the Japanese
translation of ISO 10646-1:1993 (see Section 2.5.1). Like ISO
10646-1:1993, it is based on Unicode Version 1.1.
	It is noteworthy that JIS X 0221-1995 enumerates subsets that
are applicable for Japanese use (a brief description of their contents
in parentheses):

o BASIC JAPANESE (JIS X 0208-1990 and JIS X 0201-1976 -- characters
  that can be created by means of combining are not included -- 6,884
  characters)
o JAPANESE NON IDEOGRAPHICS SUPPLEMENT (1,913 characters: all non-
  kanji of JIS X 0212-1990 plus hundreds of non-JIS characters)
o JAPANESE IDEOGRAPHICS SUPPLEMENT 1 (918 frequently-used kanji from
  JIS X 0212-1990, including 28 that are identical to kanji forms in
  JIS C 6226-1978)
o JAPANESE IDEOGRAPHICS SUPPLEMENT 2 (the remainder of JIS X 0212-
  1990, namely 4,883 kanji)
o JAPANESE IDEOGRAPHICS SUPPLEMENT 3 (the remaining kanji of ISO
  10646-1:1993, namely 8,746 characters)
o FULLWIDTH ALPHANUMERICS (94 characters; for compatibility)
o HALFWIDTH KATAKANA (63 characters; for compatibility)

	Pages 893 through 993 provide Kangxi Zidian (a classic
300-year-old Chinese character dictionary containing approximately
50,000 characters) and Dai Kanwa Jiten (also known as Morohashi)
indexes for the entire Chinese character block, namely from 0x4E00
through 0x9FA5.
	At 25,750 Yen, it is actually cheaper than ISO 10646-1:1993!


2.1.5: JIS X 0213-199X

	I recently became aware that JSA plans to publish an extension
to JIS X 0208, containing approximately 2,000 characters (kanji and
non-kanji). A public review of this new standard is planned for Summer
1996. I would expect that its information will eventually be available
at the following URL:

    ftp://ftp.tiu.ac.jp/jis/


2.1.6: OBSOLETE STANDARDS

	JIS C 6226-1978 and JIS X 0208-1983 (formerly JIS C 6226-1983)
have been superseded by JIS X 0208-1990. Section 4.1 provides details
on the changes made between these earlier versions of JIS X 0208.
	JIS X 0221-1995 does not mean the end of JIS X 0201-1976, JIS
X 0208-1990, and JIS X 0212-1990. Instead, it will co-exist with those
standards.


2.2: CHINESE (PRC)

	All character set standards that originate in PRC have
designations that begin with "GB." "GB" is short for "Guo Biao" (which
is, in turn, short for "Guojia Biaojun") and means "National
Standard." A select few also have "/T" attached. The "T" presumably is
short for "Traditional." Section 2.2.11 describes ISO-IR-165:1992,
which is a variant of GB 2312-80. It is included here because of this
relationship.
	Most people correlate GB character set standards with
simplified Chinese, but as you will see below, that is not always the
case.
	There are three basic character sets, each one having a
simplified and traditional version.

  Character Set  Set Number  Character Forms
  ^^^^^^^^^^^^^  ^^^^^^^^^^  ^^^^^^^^^^^^^^^
  GB 2312-80     0           Simplified
  GB/T 12345-90  1           Traditional of GB 2312-80
  GB 7589-87     2           Simplified
  GB/T 13131-9X  3           Traditional of GB 7589-87
  GB 7590-87     4           Simplified
  GB/T 13132-9X  5           Traditional of GB 7590-87


2.2.1: GB 1988-89

	This character set, formerly GB 1988-80 and sometimes referred
to as GB-Roman, is the Chinese analog to ASCII and ISO 646. The main
difference is that the currency symbol (0x24), which is represented as
a dollar sign ($) in ASCII, is represented as a Chinese Yuan
(currency) symbol instead. GB 1988-89 is sometimes referred to as
GB-Roman.


2.2.2: GB 2312-80

	This basic (simplified) Chinese character set standard
enumerates 7,445 characters, 6,763 of which are hanzi separated into
two levels. Hanzi in the first level are arranged by reading, and
those in the second level are arranges by radical then total number of
(remaining) strokes. GB 2312-80 is also known as the "Primary Set,"
GB0 (zero), or just GB.

o Row 1: 94 symbols
o Row 2: 72 numerals
o Row 3: 94 full-width GB 1988-89 characters (see Section 2.2.1)
o Row 4: 83 hiragana
o Row 5: 86 katakana
o Row 6: 48 uppercase and lowercase Greek alphabet
o Row 7: 66 uppercase and lowercase Cyrillic (Russian) alphabet
o Row 8: 26 Pinyin and 37 Bopomofo characters
o Row 9: 76 line-drawing elements (09-04 through 09-79)
o Rows 16 through 55: 3,755 hanzi (Level 1 Hanzi; last is 55-89)
o Rows 56 through 87: 3,008 hanzi (Level 2 Hanzi; last is 87-94)

Compare some of the structure with JIS X 0208-1990, and you will find
many similarities, such as:

o Hiragana, katakana, Greek, and Cyrillic characters are in Rows 4, 5,
  6, and 7, respectively
o Chinese characters begin at Row 16
o Chinese characters are separated into two levels
o Level 1 arranged by reading
o Level 2 arranged by radical then total number of strokes

The Japanese standard, JIS C 6226-1978, came out in 1978, which means
that it pre-dates GB 2312-80. The above similarities could not be by
coincidence, but rather by design.
	Appendix G (pp 318-344) of "Developing International Software
for Windows 95 and Windows NT" by Nadine Kano illustrates the GB 2312-
80 character set standard by EUC code (Microsoft calls this Code Page
936). Code Page 936 incorporates the correction of the hanzi at 79-81,
and the correction of the order of 07-22 and 07-23 (see Section 2.2.3
for more details).


2.2.3: GB 6345.1-86

	This document specifies corrections and additions to GB
2312-80 (see Section 2.2.2). The following is a detailed enumeration
of the changes:

o The form of "g" in Row 3 (position 71) was altered
o Row 8 has six additional Pinyin characters (08-27 through 08-32)
o Row 10 contains half-width versions of Row 3 (94 characters)
o Row 11 contains half-width versions of the Pinyin characters from
  Row 8 (32 characters; 11-01 through 11-32)
o The hanzi at 79-81 was corrected to have a simplified left-side
  radical (this was an error in GB 2312-80)

Note that these changes affect the total number of characters in GB
2312-80 -- an increase of 132 characters. This now makes 7,577 as
the total number of characters in GB 2312-80 (7,445 plus 132).
	There was, however, an undocumented correction made in GB
6345.1-86. The order of characters 07-22 and 07-23 (uppercase
Cyrillic) were reversed. This error is apparently in the first and
perhaps second printing of the GB 2312-80 manual, because the copy I
have is from the third printing, and this has been corrected. Page 145
(Figure 113) of John Clews' "Language Automation Worldwide: The
Development of Character Set Standards" illustrates this error.
Developers should take special note of this -- I have seen GB 2312-80
based font products that propagate this ordering error.


2.2.4: GB 7589-87

	This character set enumerates 7,237 hanzi in Rows 16 through
92 (last is 92-93), and they are ordered by radical then total number
of (remaining) strokes. GB 7589-87 is also known as the "Second
Supplementary Set" or GB2.


2.2.5: GB 7590-87

	This character set enumerates 7,039 hanzi in Rows 16 through
90 (last is 90-83), and they are ordered by radical then total number
of (remaining) strokes. GB 7590-87 is also known as the "Fourth
Supplementary Set" or GB4.


2.2.6: GB 8565.2-88

	This standard makes additions to GB 2312-80 (these additions
are separate from those made in GB 6345.1-86 described in Section
2.2.3). GB 8565.2-88 is also known as GB8. In this case there are 705
additions, indicated as follows:

o Row 13 contains 50 hanzi from GB 7589-87 (last is 13-50)
o Row 14 contains 92 hanzi from GB 7590-87 (last is 14-92)
o Row 15 contains 69 non-hanzi indicating dates and times, plus 24
  miscellaneous hanzi (for personal/place names and radicals; last is
  15-93).
o Rows 90 through 94 contain 470 hanzi from GB 7589-87 (94 each)

GB 8565.2-88 therefore provides a total of 8,150 characters (7,445
plus 705).


2.2.7: GB/T 12345-90

	This character set is nearly identical to GB 2312-80 (see
Section 2.2.2) in terms of the number and arrangement of characters,
but simplified hanzi are replaced by their traditional versions. GB/T
12345-90 is also known as the "Supplementary Set" or GB1.
	The following are some interesting facts about this character
set (some instances of simplified/traditional pairs that appear below
are actually character form differences):

o 29 vertical-use characters (punctuation and parentheses) included in
  Row 6 (06-57 through 06-85).

o 2,118 traditional hanzi replace simplified hanzi in Rows 16 through
  87. The "G1-Unique" appendix of the unofficial version (supplied to
  the CJK-JRG for Han Unification purposes) is missing the following
  four (specifies only 2,114):

  0x5B3B    0x6D2F
  0x5E7C    0x6F71

  But, ISO 10646-1:1993 ended up getting these hanzi included anyway,
  with correct mappings.

o Four simplified/traditional hanzi pairs (eight affected code points)
  in rows 16 through 87 are swapped:

  0x3A73 <-> 0x6161
  0x5577 <-> 0x6167
  0x5360 <-> 0x6245 (see the next bullet)
  0x4334 <-> 0x7761

o One hanzi (0x6245), after being swapped, had its left-side radical
  unsimplified (this character, now at 0x5360, is considered part of
  the 2,118 traditional hanzi from the second bullet):

  0x6245 -> 0x5360

o 103 hanzi included in Rows 88 (94 characters) and 89 (9 characters;
  89-01 through 89-09). These are all related to characters between
  Rows 16 and 87.

  - 41 simplified hanzi from Rows 16 through 87 moved to Rows 88 and
    89 (traditional hanzi are now at the original code points):

    0x3327 -> 0x7827  0x3E5D -> 0x7846  0x4B49 -> 0x7869
    0x3365 -> 0x7828  0x3F64 -> 0x7849  0x4C28 -> 0x786B
    0x3373 -> 0x7829  0x402F -> 0x784B  0x4D3F -> 0x786F
    0x3533 -> 0x782C  0x4030 -> 0x784C  0x4D72 -> 0x7871
    0x356D -> 0x782D  0x406F -> 0x784E  0x5236 -> 0x7878
    0x3637 -> 0x782F  0x4131 -> 0x7850  0x5374 -> 0x7879
    0x3736 -> 0x7832  0x463B -> 0x785C  0x5438 -> 0x787C
    0x3761 -> 0x7833  0x463E -> 0x785D  0x5446 -> 0x787D
    0x3849 -> 0x7835  0x464B -> 0x785E  0x5622 -> 0x7921
    0x3963 -> 0x7838  0x464D -> 0x785F  0x563B -> 0x7923
    0x3B2E -> 0x783B  0x4653 -> 0x7860  0x5656 -> 0x7926
    0x3C38 -> 0x7840  0x4837 -> 0x7866  0x567E -> 0x7928
    0x3C5B -> 0x7842  0x4961 -> 0x7867  0x573C -> 0x7929
    0x3C76 -> 0x7843  0x4A75 -> 0x7868

  - 62 hanzi added to Rows 88 and 89 (the gaps from the above are
    filled in). These were mostly to account for multiple traditional
    hanzi collapsing into a single simplified form.

  - The following code point mappings illustrate how all of these 103
    hanzi are related to hanzi between Rows 16 and 87 (note how many
    of these 103 hanzi map to a single code point):

    0x7821 -> 0x305A  0x7844 -> 0x3D2A  0x7867 -> 0x4961
    0x7822 -> 0x3065  0x7845 -> 0x3E21  0x7868 -> 0x4A75
    0x7823 -> 0x316D  0x7846 -> 0x3E5D  0x7869 -> 0x4B49
    0x7824 -> 0x3170  0x7847 -> 0x3E6D  0x786A -> 0x4B55
    0x7825 -> 0x3237  0x7848 -> 0x3F4B  0x786B -> 0x4C28
    0x7826 -> 0x3245  0x7849 -> 0x3F64  0x786C -> 0x4C28
    0x7827 -> 0x3327  0x784A -> 0x4027  0x786D -> 0x4C28
    0x7828 -> 0x3365  0x784B -> 0x402F  0x786E -> 0x4C33
    0x7829 -> 0x3373  0x784C -> 0x4030  0x786F -> 0x4D3F
    0x782A -> 0x3376  0x784D -> 0x405B  0x7870 -> 0x4D45
    0x782B -> 0x3531  0x784E -> 0x406F  0x7871 -> 0x4D72
    0x782C -> 0x3533  0x784F -> 0x407A  0x7872 -> 0x4F35
    0x782D -> 0x356D  0x7850 -> 0x4131  0x7873 -> 0x4F35
    0x782E -> 0x362C  0x7851 -> 0x414B  0x7874 -> 0x4F4C
    0x782F -> 0x3637  0x7852 -> 0x4231  0x7875 -> 0x4F72
    0x7830 -> 0x3671  0x7853 -> 0x425E  0x7876 -> 0x506B
    0x7831 -> 0x3722  0x7854 -> 0x4339  0x7877 -> 0x5229
    0x7832 -> 0x3736  0x7855 -> 0x4349  0x7878 -> 0x5236
    0x7833 -> 0x3761  0x7856 -> 0x4349  0x7879 -> 0x5374
    0x7834 -> 0x3834  0x7857 -> 0x4349  0x787A -> 0x5379
    0x7835 -> 0x3849  0x7858 -> 0x4356  0x787B -> 0x5375
    0x7836 -> 0x3948  0x7859 -> 0x4366  0x787C -> 0x5438
    0x7837 -> 0x394E  0x785A -> 0x436F  0x787D -> 0x5446
    0x7838 -> 0x3963  0x785B -> 0x3159  0x787E -> 0x5460
    0x7839 -> 0x6358  0x785C -> 0x463B  0x7921 -> 0x5622
    0x783A -> 0x3A7A  0x785D -> 0x463E  0x7922 -> 0x563B
    0x783B -> 0x3B2E  0x785E -> 0x464B  0x7923 -> 0x563B
    0x783C -> 0x3B58  0x785F -> 0x464D  0x7924 -> 0x5642
    0x783D -> 0x3B63  0x7860 -> 0x4653  0x7925 -> 0x5646
    0x783E -> 0x3B71  0x7861 -> 0x4727  0x7926 -> 0x5656
    0x783F -> 0x3C22  0x7862 -> 0x4729  0x7927 -> 0x566C
    0x7840 -> 0x3C38  0x7863 -> 0x4F4B  0x7928 -> 0x567E
    0x7841 -> 0x3C52  0x7864 -> 0x476F  0x7929 -> 0x573C
    0x7842 -> 0x3C5B  0x7865 -> 0x477A
    0x7843 -> 0x3C76  0x7866 -> 0x4837

So, if we total everything up, we see that GB/T 12345-90 has 2,180
hanzi (2,118 are replacements for GB 2312-80 code points, and 62 are
additional) and 29 non-hanzi not found in GB 2312-80.
	Note that the printing of the GB/T 12345-90 has some
character-form errors. The errors I am aware of are as follows:

  Code Point  Description of Error
  ^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^
  0x4125      The upper-left element should be "tree" instead of
              "warrior"
  0x596C      The "bird" radical should not include the "fire" element


2.2.8: GB/T 13131-9X

	This character set is identical to GB 7589-87 (see Section
2.2.4) in terms of number of characters, but simplified hanzi are
replaced by their traditional versions. The exact number of such
substitutions is currently unknown to this author. GB/T 13131-9X is
also known as the "Third Supplementary Set" or GB3.


2.2.9: GB/T 13132-9X

	This character set is identical to GB 7590-87 (see Section
2.2.5) in terms of number of characters, but simplified hanzi are
replaced by their traditional versions. The exact number of such
substitutions is currently unknown to this author. GB/T 13132-9X is
also known as the "Fifth Supplementary Set" or GB5.


2.2.10: GB 13000.1-93

	This document is, for all practical purposes, the Chinese
translation of ISO 10646-1:1993 (see Section 2.5.1).


2.2.11: ISO-IR-165:1992

	This standard, also known as the CCITT Chinese Set, is a
variant of GB 2312-80 with the following characteristics:

o GB 6345.1-86 modifications (including the undocumented one) and
  additions, namely 132 characters (see Section 2.2.3)
o GB 8565.2-88 additions, namely 705 characters (see Section 2.2.6)
o Row 6 contains 22 background (shading) characters (06-60 through
  06-81)
o Row 12 contains 94 hanzi
o Row 13 contains 44 additional hanzi (13-51 through 13-94; fills the
  row)
o Row 15 contains 1 additional hanzi (15-94)

ISO-IR-165:1992 can therefore be considered a superset of GB 2312-80,
GB 6345.1-86, and GB 8565.2-88. This means 8,443 total characters
compared to the 7,445 in GB 2312-80, 7,577 in GB 6345.1-86, and the
8,150 in GB 8565.2-88.


2.2.12: OBSOLETE STANDARDS

	Most GB standards seem to be revised through other documents,
so it is hard to point to a standard and claim that it is obsolete.
The only revision I am aware of is the GB 1988-89 (the original was
named GB 1988-80).


2.3: CHINESE (TAIWAN)

	The sections below describe two major Taiwanese character
sets, namely Big Five and CNS 11643-1992. As you will learn they are
somewhat compatible. CCCII, also developed in Taiwan, is described in
Section 2.5.2.


2.3.1: BIG FIVE

	The Big Five character set is composed of 94 rows of 157
characters each (the 157 characters of each row are encoded in an
initial group of 63 codes followed by the remaining 94 codes). The
following is a break-down of its contents:

o Row 1: 157 symbols
o Row 2: 157 symbols
o Row 3: 94 symbols
o Rows 4 through 38: 5,401 hanzi (Level 1 Hanzi; last is 38-63)
o Rows 41 through 89: 7,652 hanzi (Level 2 Hanzi; last is 89-116)

This forms what I consider to be the basic Big Five set. Actually, two
of the hanzi in Level 2 are duplicates, so there are actually only
7,650 unique hanzi in Level 2.
	There are two major extensions to Big Five. The first really
has no name, and can be considered part of the basic Big Five set as
specified above. It adds the following characters:

o Rows 38-39: 4 Japanese iteration marks, 83 hiragana, 86 katakana, 66
  uppercase and lowercase Cyrillic (Russian) alphabet, 10 circled
  digits, and 10 parenthesized digits

	The other extension was developed by a company called ETen
Information System in Taiwan, and is actually considered to be the
most widely used version of Big Five. It provides the following
extensions to Big Five (different from the above extension):

o Rows 38-40: 10 circled digits, 10 parenthesized digits, 10 lowercase
  Roman numerals, 25 classical radicals, 15 Japanese-specific symbols,
  83 hiragana, 86 katakana, 66 uppercase and lowercase Cyrillic
  (Russian) alphabet, 3 arrows, 10 radical-like hanzi elements, 40
  fraction-like digits, and 7 symbols
o Row 89: 7 hanzi, 33 double-lined line-drawing elements, and a black
  box

	It is *very* important to note that while these two extensions
have many common portions (in particular, hiragana, katakana, the
Cyrillic alphabet, and so on), they do not share the same code points
for such characters.
	Appendix G (pp 407-450) of "Developing International Software
for Windows 95 and Windows NT" by Nadine Kano illustrates the Big Five
character set standard by Big Five code (Microsoft calls this Code
Page 950). Code Page 950 incorporates some of the ETen extensions,
namely those in Row 89.


2.3.2: CNS 11643-1992

	CNS 11643-1992 (also known as CNS 11643 X 5012), by
definition, consists of 16 planes of characters, seven of which have
character assignments. Each plane is a 94-row-by-94-cell matrix
capable of holding a total of 8,836 characters. CNS stands for
"Chinese National Standard."
	CNS 11643-1992 specifies characters only in the first seven
planes. A break-down of characters, by plane, is as follows:

o Plane 1:
  - 438 symbols in Rows 1 through 6
  - 213 classical radicals in Rows 7 through 9
  - 33 graphic representations of control characters in Row 34
  - 5,401 hanzi in Rows 36 through 93 (last is 93-43)
o Plane 2: 7,650 hanzi in Rows 1 through 82 (last is 82-36)
o Plane 3: 6,148 hanzi in Rows 1 through 66 (last is 66-38)
o Plane 4: 7,298 hanzi in Rows 1 through 78 (last is 78-60)
o Plane 5: 8,603 hanzi in Rows 1 through 92 (last is 92-49)
o Plane 6: 6,388 hanzi in Rows 1 through 68 (last is 68-90)
o Plane 7: 6,539 hanzi in Rows 1 through 70 (last is 70-53)

The total number of characters in CNS 11643-1992 is a staggering
48,711 characters, 48,027 of which are hanzi. Also note that number of
hanzi in Plane 1 is identical to Level 1 hanzi of Big Five (see
Section 2.3.1). The 2 extra hanzi in Level 2 hanzi of Big Five are
actually redundant, and are therefore not in CNS 11643-1992 Plane 2.
	It is rumored that Plane 8 is currently being defined, and
will add yet more hanzi to this standard.


2.3.3: CNS 5205

	This character set is Taiwan's analog to ASCII and ISO 646,
and is reportedly rarely used. How it differs from ASCII, if at all,
is unknown to this author.


2.3.4: OBSOLETE STANDARDS

	CNS 11643-1986 specified characters only in the first three
planes, as described in Section 2.3.2. Also, Plane 3 of CNS 11643-1992
was called Plane 14 of CNS 11643-1986.


2.4: KOREAN

	The sections below describe the most current Korean character
sets, namely KS C 5636-1993, KS C 5601-1992, KS C 5657-1991, and KS C
5700-1995. "KS" stands for "Korean Standard."


2.4.1: KS C 5636-1993

	This character set (published on January 6, 1993), formerly KS
C 5636-1989 (published on April 22, 1989) and sometimes referred to as
KS-Roman, is the Korean analog to ASCII and ISO 646-1991. The primary
difference is that the ASCII backslash (0x5C) is represented as a Won
symbol.


2.4.2: KS C 5601-1992

	This basic Korean character set standard enumerates 8,224
characters, 4,888 of which are hanja, and 2,350 of which are pre-
combined hangul. The hanja and hangul blocks are arranged by reading.
The following is a break-down of its contents:

o Row 1: 94 symbols
o Row 2: 69 abbreviations and symbols
o Row 3: 94 full-width KS C 5636-1993 characters (see Section 2.4.1)
o Row 4: 94 hangul elements
o Row 5: 68 lowercase and uppercase Roman numerals and lowercase and
  uppercase Greek alphabet
o Row 6: 68 line-drawing elements
o Row 7: 79 abbreviations
o Row 8: 91 phonetic symbols, circled characters, and fractions
o Row 9: 94 phonetic symbols, parenthesized characters, subscripts,
  and superscripts
o Row 10: 83 hiragana
o Row 11: 86 katakana
o Row 12: 66 lowercase and uppercase Cyrillic (Russian) alphabet
o Rows 16 through 40: 2,350 pre-combined hangul (last is 40-94)
o Rows 42 through 93: 4,888 hanja (last is 93-94)

Rows 41 and 94 are designated for user-defined characters.
	There are many similarities with JIS X 0208-1990 and GB
2312-80, such as hiragana, katakana, Greek, and Cyrillic characters,
but they are assigned to different rows.
	There is an interesting note about the hanja block (Rows 42
through 93). Although there are 4,888 hanja, not all are unique. The
hanja block is arranged by reading, and in those cases when a hanja
has more than one reading, that hanja is duplicated (sometimes more
than once) in the same character set. There are 268 such cases of
duplicate hanja in KS C 5601-1992, meaning that it contains 4,620
unique hanja. If you have a copy of the KS C 5601-1992 manual handy,
you can compare the following four code points:

  0x6445
  0x5162
  0x5525
  0x6879

While most of these cases involve two hanja instances, there are four
hanja that have three instances, and one (listed above) that has four!
This is the only CJK character set that has this property of
intentionally duplicating Chinese characters. See Section 4.4 for more
details.
	Annex 3 of this standard defines the complete set of 11,172
pre-combined hangul characters, also known as Johab. Johab refers to
the encoding method, and is almost like encoding all possible three-
letter words (meaning that most are nonsense). See Section 3.3.5 for
more details on Johab encoding.


2.4.3: KS C 5657-1991

	This character set standard provides supplemental characters
for Korean writing, to include symbols, pre-combined hangul, and
hanja. The following is a break-down of its contents:

o Rows 1 through 7: 613 lowercase and uppercase Latin characters with
  diacritics (see note below)
o Rows 8 through 10: 273 lowercase and uppercase Greek characters with
  diacritics
o Rows 11 through 13: 275 symbols
o Row 14: 27 compound hangul elements
o Rows 16 through 36: 1,930 pre-combined hangul (last is 36-50)
o Rows 37 through 54: 1,675 pre-combined hangul (last is 54-77; see
  note below)
o Rows 55 through 85: 2,856 hanja (last is 85-36)

The KS C 5657-1991 manual has a possible error (or at least an
inconsistency) for Rows 1 through 7. The manual says that there are
615 characters in that range, but I only counted 613. The difference
can be found on page 19 as the following two characters:

  Character Code  Character
  ^^^^^^^^^^^^^^  ^^^^^^^^^
  0x2137          X
  0x217A          TM

An "X" doesn't belong there (it is already in KS C 5601-1992 at code
point 0x2358), and the trademark symbol is also part of KS C 5601-1992
at code point 0x2262. This is why I feel that my count of 613 is more
accurate than what is explicitly stated in the manual on page 2.
	Also, page 2 of the manual says that Rows 37 through 54
contains 1,677 pre-combined hangul, but I only counted 1,675 (17 rows
of 94 characters plus a final row with 77 characters -- do the math
for yourself).
	Here's another interesting note. My official copy of this
standard has all of its 2,856 hanja hand-written.


2.4.4: GB 12052-89

	You may be asking yourself why a GB standard is listed under
the Korean section of this document. Well, there is a rather large
Korean population in China (Korea was considered part of China before
the 1890s), and they need a character set standard for communicating
using hangul. GB 12052-89 is a Korean character set standard
established by China (PRC), and enumerates a total of 5,979
characters.
	The following is the arrangement of this character set:

o Row 1: 94 symbols
o Row 2: 72 numerals
o Row 3: 94 full-width ASCII characters
o Row 4: 83 hiragana
o Row 5: 86 katakana
o Row 6: 48 uppercase and lowercase Greek alphabet
o Row 7: 66 uppercase and lowercase Cyrillic (Russian) alphabet
o Row 8: 26 Pinyin and 37 Bopomofo characters
o Row 9: 76 line-drawing elements (09-04 through 09-79)
o Rows 16 through 37: 2,068 pre-combined hangul (Level 1 Hangul, Part
  1; last is 37-94)
o Rows 38 through 52: 1,356 pre-combined hangul (Level 1 Hangul, Part
  2; last is 52-40)
o Rows 53 through 71: 1,779 pre-combined hangul (Level 2 Hangul; last
  is 71-87)
o Rows 71 through 72: 94 "Idu" hanja (71-89 through 72-88)

	There are a few interesting notes I can make about this
character set:

o Rows 1 through 9 are identical to the same rows in GB 2312-80,
  except that 03-04 is a dollar sign, not a Chinese Yuan (currency)
  symbol.

o The GB 12052-89 manual states on pp 1 and 3 that Rows 53 through 72
  contain 1,876 characters, but I only counted 1,873 (1,779 hangul
  plus 94 hanja).

o The total number of characters, 5,979, is correctly stated in the
  manual although the hangul count is incorrect.

o The arrangement and ordering of these hangul bear no relationship to
  that of KS C 5601-1992. Both standards order by reading, which is
  the only way in which they are similar.

	I am not aware to what extent this character set is being
used (and who might be using it).


2.4.5: KS C 5700-1995

	Korea has developed a new character set standard called KS C
5700-1995. It is equivalent to ISO 10646-1:1993, but have pre-combined
hangul as provided (and ordered) in Unicode Version 2.0 (meaning that
all 11,172 hangul are in a contiguous block).


2.4.6: OBSOLETE STANDARDS

	KS C 5601-1986, KS C 5601-1987, and KS C 5601-1989 are the
same, character-set wise, to KS C 5601-1992. The 1992 edition provides
more material in the form of annexes. KS C 5601-1982, the original
version, enumerated only the 51 basic hangul elements in a one-byte 7-
and 8-bit encoding. This information is still part of KS C 5601-1992,
but in Annex 4.
	There were two earlier multiple-byte standards called KS C
5619-1982 and KIPS. KS C 5619-1982 enumerated 51 hangul elements,
1,316 pre-combined hangul, and 1,672 hanja. KIPS (Korean Information
Processing System) enumerated 2,058 pre-combined hangul and 2,392
hanja. Both have been rendered obsolete by KS C 5601-1987.


2.5: CJK

	The only true CJK character sets available today are CCCII,
ANSI Z39.64-1989 (also known as EACC or REACC), and ISO 10646-1:1993.
ISO 10646-1:1993 is unique in that it goes beyond CJK (Chinese
characters) to provide virtually all commonly-used alphabetic scripts.
	Of these three, only ISO 10646-1:1993 is expected to gain
wide-spread acceptance. CCCII and ANSI Z39.64-1989 are still used
today, but primarily for bibliographic purposes.


2.5.1: ISO 10646-1:1993

	Published by ISO (International Organization for
Standardization) in Switzerland, this character set enumerates over
34,000 characters. Its I-zone ("I" stands for "Ideograph") enumerates
approximately 21,000 Chinese characters, which is the result of a
massive effort by the CJK-JRG (CJK Joint Research Group) called "Han
Unification." The CJK-JRG is now called the IRG (Ideographic
Rapporteur Group), and is off doing additional research for future
Chinese character allocations to ISO 10646-1:1993.
	The Basic Multilingual Plane (BMP) of ISO 10646-1:1993 is
equivalent to Unicode. While Unicode is comprised of a single plane of
characters (which doesn't allow much room for future expansion), ISO
10646-1:1993 contains hundreds of such planes.
	One very nice feature of this standard's manual are the CJK
code correspondence tables in Section 26 (pp 262-698). Four columns
are provided for each ISO 10646-1:1993 I-zone code point -- simplified
Chinese, traditional Chinese, Japanese, and Korean. If the ISO
10646-1:1993 Chinese character maps to one of these locales, the
hexadecimal character code, (decimal) row-cell value, and glyph for
that locale is provided. The corresponding tables in Volume 2 of "The
Unicode Standard" provide character codes (sometimes the hexadecimal
character code, and sometimes the row-cell value) and a single
glyph. Quite unfortunate. I hear that a new edition of "The Unicode
Standard" is about to be released. I hope that this problem has been
addressed.
	ISO 10646-1:1993 does not replace existing national character
set standards. It simply provides a single character set that is a
superset of *most* national character sets. For example, only a
fraction of the 48,027 hanzi in CNS 11643-1992 are included in ISO
10646-1:1993. I feel that it is best to think of ISO 10646-1:1993 as
"just another character set." My philosophy is to support the maximum
number of character sets and encodings as possible.
	A note about ordering this standard. If you order through ANSI
in the United States, try to get an original manual. It is not easy,
though. You see, ANSI has duplication rights for ISO documents.
Photocopying Section 26 (pp 262-698) doesn't do the Chinese characters
much justice, and some characters become hard-to-read. Unfortunately,
there is no way to indicate that you want an original ISO document
through ANSI's ordering process, so some post-ordering haggling may
become necessary.
	More information on ISO 10646-1:1993 can be found at the
following URL:

  http://www.unicode.org/

	Japan, China (PRC), and Korea have developed their own
national standards that are based on ISO 10646-1:1993. They are
designated as JIS X 0221-1995 (see Section 2.1.4), GB 13000.1-93 (see
Section 2.2.10), and KS C 5700-1995 (see Section 2.4.5), respectively.
	Note that these national-standard versions of Unicode are
aligned differently with its three versions:

  Unicode Version 1.0
  Unicode Version 1.1 <-> ISO 10646-1:1993, JIS X 0221-1995, GB 13000.1-93
  Unicode Version 2.0 <-> KS C 5700-1995

One of the major changes made for Unicode Version 2.0 is the inclusion
of all 11,172 hangul. Versions 1.1 has 6,656 hangul.


2.5.2: CCCII

	The Chinese Character Analysis Group in Taiwan developed CCCII
(Chinese Character Code for Information Interchange) in the 1980s.
This character set is composed of 94 planes that have 94 rows and 94
cells (94 x 94 x 94 = 830,584 characters). Furthermore, every six
planes constitute a "layer" (6 x 94 x 94 = 53,016 characters). The
following is the contents of each of the 16 layers (the 16th layer
contains only four planes):

o Layer 1: Symbols and Traditional Chinese characters
o Layer 2: Simplified Chinese characters from PRC
o Layers 3 through 12: Variant Chinese character forms
o Layer 13: Japanese kana and kokuji (Japanese-made kanji)
o Layer 14: Korean hangul
o Layer 15: Reserved
o Layer 16: Miscellaneous characters (Japanese and Korean)

	Layers 1 through 12 have a special meaning and relationship.
The same code point in these layers is designed to hold the same
character, but with different forms. Layer 1 code points contain the
traditional character forms, Layer 2 code points contain the
simplified character forms (if any), and Layers 3 through 12 contain
variant character forms (if any). For example, given a Chinese
character with three forms, its encoding and arrangement may be as
follows:

  Character Form  Code Point  Layer
  ^^^^^^^^^^^^^^  ^^^^^^^^^^  ^^^^^
  Traditional     0x224E41    1
  Simplified      0x284E41    2
  Variant         0x2E4E41    3

Note how the second and third bytes (0x4E41) are identical in all
three instances -- only the first byte's value, which indicates the
layer, differs. Needless to say, this method of arrangement provides
easy access to related Chinese character forms. No wonder it is used
for bibliographic purposes.
	The first layer is composed as follows:

o Plane 1/Row 2: 56 mathematical symbols
o Plane 1/Row 3: The ASCII character set
o Plane 1/Row 11: 35 Chinese punctuation marks
o Plane 1/Rows 12 through 14: 214 classical radicals
o Plane 1/Row 15: 41 Chinese numerical symbols, 37 phonetic symbols,
  and 4 tone marks
o Plane 1/Rows 16 through 67: 4,808 common Chinese characters
o Plane 1/Row 68 through Plane 3/Row 64: 17,032 less common Chinese
  characters
o Plane 3/Row 65 through Plane 6/Row 5: 20,583 rare Chinese characters

Note that Row 1 of all planes is reserved, and never assigned
characters. Take this into account when studying the above table
ranges that span planes (that is, skip Row 1).
	In addition to the above, there are 11,517 simplified Chinese
characters in Layer 2 (3,625 are considered PRC simplified forms, and
the remaining 7,892 are regular simplified forms). This provides a
total of 53,940 Chinese characters.
	Further information on CCCII (to include very interesting
historical notes) can be found on pp 146-149 of John Clews' "Language
Automation Worldwide: The Development of Character Set Standards" and
Chapter 6 of Huang & Huang's "An Introduction to Chinese, Japanese,
and Korean Computing."


2.5.3: ANSI Z39.64-1989

	This national standard is designated as ANSI Z39.64-1989 and
named "East Asian Character Code" (EACC), but was originally known as
REACC (RLIN East Asian Character Code), that is, before it became a
national standard. RLIN stands for "Research Libraries Information
Network," which was developed by the Research Libraries Group (RLG)
located in Mountain View, California.
	RLG's Home Page is at the following URL:

  http://www.rlg.org/

	The structure of ANSI Z39.64-1989 is based on CCCII, but with
a few differences. Many consider it to be superior to and a
replacement for CCCII (see Section 2.5.2).
	The ANSI Z39.64-1989 standard is available through ANSI, but
you should be aware that it is distributed in the form of several
microfiche. Not a terribly useful storage medium these days. I had my
set tranformed into tangible printed pages. You can also obtain this
standard through NISO (National Information Standards Organization)
Press Fulfillment. Their URL is:

  http://www.niso.org/

	EACC has been designated by the Library of Congress as a
character set for use in USMARC (United States MAchine-Readable
Cataloging) records, and is used extensively by East Asian libraries
across North America.
	EACC is also being used in Australia for the National CJK
Project. Check out the following URL for more details:

  http://www.nla.gov.au/1/asian/ncjk/cjkhome.html

	Further information on ANSI Z39.64-1989 (to include very
interesting historical notes) can be found on pp 150-156 of John
Clews' "Language Automation Worldwide: The Development of Character
Set Standards" (although a source at RLG tells me that some of Clews'
facts are wrong) and Chapter 6 of Huang & Huang's "An Introduction to
Chinese, Japanese, and Korean Computing."
	The authoritative paper on EACC is "RLIN East Asian Character
Code and the RLIN CJK Thesaurus" by Karen Smith Yoshimura and Alan
Tucker, published in "Proceedings of the Second Asian-Pacific
Conference on Library Science," May 20-24,1985, Seoul, Korea.


2.6: OTHER

	This section includes character set standards that don't
properly fall under the above sections.


2.6.1: GB 8045-87

	GB 8045-87 is a Mongolian character set standard established
by China (PRC). This standard enumerates 94 Mongolian characters. Of
these 94 characters, 12 are punctuation (vertically-oriented), and the
remaining 82 are characters specific to the Mongolian script.
Mongolian is written vertically like Chinese.
	I do not discuss the encoding for GB 8045-87 in Part 3, so
will do it here. The GB 8045-87 manual describes a 7- and 8-bit
encoding. The 7-bit encoding puts these 94 characters in the standard
ASCII printable range, namely 0x21 through 0x7E. Code point 0x20 is
marked as "MSP" which stands for "Mongolian space." The 8-bit encoding
puts these 94 characters in the range 0xA1 through 0xFE, with the
"MSP" character at code point 0xA0. The GB 1988-89 set is then encoded
in the range 0x21 through 0x7E.


2.6.2: TCVN-5773:1993

	TCVN-5773:1993 (also called NSCII, which is short for Nom
Standard Code for Information Interchange) is the Vietnamese analog to
ISO 10646-1:1993, but adds 1,775 Vietnamese-specific Chinese
characters. These 1,775 characters are encoded in the range 0xA000
through 0xA6EE.
	More information on TCVN-5773:1993 can be found at the
following URL:

  ftp://unicode.org/pub/MappingTables/EastAsiaMaps/

There are two files at the above URL that pertain to this standard.
The first is a README, and the second is a Macintosh HyperCard stack
(requires HyperCard):

  TCVN-NSCII.README
  TCVN-NSCIIstack_1.0.sea.hqx


PART 3: CJK ENCODING SYSTEMS

	These sections describe the various systems for encoding the
character set standards listed in Part 2. The first two described,
7-bit ISO 2022 and EUC, are not specific to a locale, and in some
cases not specific to CJK.
	The CJK Character Set Server at the following URL can generate
character sets based on encodings described in this section:

  http://jasper.ora.com/lunde/cjk-char.html

I suggest that you use this as a way to obtain files that illustrate
these encodings in action.
	But first, please take a peek at the following table, which is
an attempt to illustrate how two Chinese characters (that stand for
"kanji/hanzi/hanja") are encoded using the various methods presented
in the following sections (character codes as hexadecimal digits, and
escape sequences or shift sequences as printable characters):

o Japanese (JIS X 0208-1990 & JIS X 0201-1976):
  - 7-bit ISO 2022        <ESC> & @ <ESC> $ B 0x3441 0x3B7A <ESC> ( J
  - ISO-2022-JP           <ESC> $ B 0x3441 0x3B7A <ESC> ( J
  - EUC                   0xB4C1 0xBBFA
  - Shift-JIS             0x8ABF 0x8E9A

o Simplified Chinese (GB 2312-80 & GB 1988-89 or ASCII):
  - 7-bit ISO 2022        <ESC> $ A 0x3A3A 0x5756 <ESC> ( T
  - ISO-2022-CN           <ESC> $ ) A <SO> 0x3A3A 0x5756 <SI>
  - EUC                   0xBABA 0xD7D6
  - HZ (HZ-GB-2312)       ~{ 0x3A3A 0x5756 ~}
  - zW                    zW 0x3A3A 0x5756

o Traditional Chinese (CNS 11643-1992):
  - 7-bit ISO 2022        <ESC> $ ( G 0x6947 0x4773 <ESC> ( B
  - ISO-2022-CN           <ESC> $ ) G <SO> 0x6947 0x4773 <SI>
  - EUC                   0xE9C7 0xC7F3 or 0x8EA1E9C7 0x8EA1C7F3

o Traditional Chinese (Big Five):
  - Big Five              0xBA7E 0xA672

o Korean (KS C 5601-1992 & ASCII):
  - 7-bit ISO 2022        <ESC> $ ( C 0x7953 0x6D2E <ESC> ( B
  - ISO-2022-KR           <ESC> $ ) C <SO> 0x7953 0x6D2E <SI>
  - EUC                   0xF9D3 0xEDAE
  - Johab                 0xF7D3 0xF1AE

o CJK (ISO 10646-1:1993, JIS X 0221-1995, GB 13000.1-93, or KS C
  5700-1995):
  - UCS-2                 0x6F22 0x5B57
  - UCS-4                 0x00006F22 0x00005B57

The above should have given you a taste of what information the
following sections provide.


3.1: 7-BIT ISO 2022 ENCODING

	7-bit ISO 2022 is the name commonly given to the encoding
system that uses escape sequences to shift between character sets.
(ISO 2022 encoded Japanese text is also known as "JIS" encoding, but
is different from ISO-2022-JP and ISO-2022-JP-2, and will be explained
in Section 3.1.3.) This encoding comes from the ISO 2022-1993
standard.
	An escape sequence, as the name implies, consists of an escape
character followed by a sequence of one or more characters. These
escape sequences are used to change character set of the text
stream. This may also mean a shift from one- to two-byte-per-character
mode (or vice versa).
	7-bit ISO 2022 Character sets fall into two types: one-byte
and two-byte. CJK character sets, for obvious reasons, fall into the
latter group.
	One advantage that 7-bit ISO 2022 encoding has over other
encoding systems is that its escape sequences specify the character
set, thus specify the locale. 7-bit ISO 2022 encoding also encodes
text using only seven-bit bytes, which has the benefit of being able
to survive Internet travel (e-mail).


3.1.1: CODE SPACE

	Each byte in the representation of graphic (printable)
characters fall into the range 0x21 (decimal 33) through 0x7E (decimal
126). For one-byte character sets, this means a maximum of 94
characters. For two-byte character sets, this means a maximum of 8,836
characters (94 x 94 = 8,836).

  One-byte Characters                           Encoding Range
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  first byte range                              0x21-0x7E

  Two-byte Characters                           Encoding Range
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  first byte range                              0x21-0x7E
  second byte range                             0x21-0x7E

White space and control characters (of which the "escape" character is
one) are still found in 0x00-0x20 and 0x7F.


3.1.2: ISO-REGISTERED ESCAPE SEQUENCES

	The following is a table that provides the ISO-registered
escape sequences for various one- and two-byte character sets
mentioned in Part 2 of this document (ISO registration numbers
provided in the fourth column):

  One-byte Character Set  Escape Sequence      Hexadecimal     ISO Reg
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^     ^^^^^^^
  ASCII (ANSI X3.4-1986)  <ESC> ( B            0x1B2842        6
  Half-width katakana     <ESC> ( I            0x1B2849        13
  JIS X 0201-1976 Roman   <ESC> ( J            0x1B284A        14
  GB 1988-89 Roman        <ESC> ( T            0x1B2854        57

  Two-byte Character Set  Escape Sequence      Hexadecimal     ISO Reg
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^     ^^^^^^^
  JIS C 6226-1978         <ESC> $ @            0x1B2440        42
  GB 2312-80              <ESC> $ A            0x1B2441        58
  JIS X 0208-1983         <ESC> $ B            0x1B2442        87
  KS C 5601-1992          <ESC> $ ( C          0x1B242843      149
  JIS X 0212-1990         <ESC> $ ( D          0x1B242844      159
  ISO-IR-165:1992         <ESC> $ ( E          0x1B242845      165
  JIS X 0208-1990         <ESC> & @ <ESC> $ B  0x1B26401B2442  168
  CNS 11643-1992 Plane 1  <ESC> $ ( G          0x1B242847      171
  CNS 11643-1992 Plane 2  <ESC> $ ( H          0x1B242848      172
  CNS 11643-1992 Plane 3  <ESC> $ ( I          0x1B242849      183
  CNS 11643-1992 Plane 4  <ESC> $ ( J          0x1B24284A      184
  CNS 11643-1992 Plane 5  <ESC> $ ( K          0x1B24284B      185
  CNS 11643-1992 Plane 6  <ESC> $ ( L          0x1B24284C      186
  CNS 11643-1992 Plane 7  <ESC> $ ( M          0x1B24284D      187

Note that the first four two-byte character sets do not use an opening
parenthesis (0x28 or "(") in their escape sequences, which means that
they don't follow the 7-bit ISO 2022 rules precisely. They are shorter
for historical reasons, and are retained for backwards compatibility.
Also note that not all of the CJK character set standards described in
Part 2 have ISO-registered escape sequences.
	There are other encoding methods that are similar to 7-bit ISO
2022 in that they are suitable for Internet use, but are locale-
specific. These include HZ and zW encoding, both of which are specific
to the GB 2312-80 character set (see Sections 3.3.2 and 3.3.3).
ISO-2022-JP, ISO-2022-KR, ISO-2022-CN, and ISO-2022-CN-EXT are
described below.


3.1.3: ISO-2022-JP AND ISO-2022-JP-2

	ISO-2022-JP is best described as a subset of 7-bit ISO 2022
encoding for Japanese, and reflects how Japanese text is encoded for
e-mail messages. ISO-2022-JP-2 is an extension that supports
additional character sets.
	There are only four escape sequences permitted in ISO-2022-JP,
indicated as follows:

  One-byte Character Set  Escape Sequence      Hexadecimal
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^
  ASCII (ANSI X3.4-1986)  <ESC> ( B            0x1B2842
  JIS X 0201-1976 Roman   <ESC> ( J            0x1B284A

  Two-byte Character Set  Escape Sequence      Hexadecimal
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^
  JIS C 6226-1978         <ESC> $ @            0x1B2440
  JIS X 0208-1983         <ESC> $ B            0x1B2442

Note the lack of JIS X 0208-1990, JIS X 0212-1990, and half-width
katakana escape sequences. The JIS X 0208-1983 escape sequence is used
to indicate both JIS X 0208-1983 and JIS X 0208-1990 (for practical
reasons).
	ISO-2022-JP-2 permits additional escape sequences, indicated
as follows:

  One-byte Character Set  Escape Sequence      Hexadecimal
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^
  ASCII (ANSI X3.4-1986)  <ESC> ( B            0x1B2842
  JIS X 0201-1976 Roman   <ESC> ( J            0x1B284A

  Two-byte Character Set  Escape Sequence      Hexadecimal
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^
  JIS C 6226-1978         <ESC> $ @            0x1B2440
  JIS X 0208-1983         <ESC> $ B            0x1B2442
  JIS X 0212-1990         <ESC> $ ( D          0x1B242844
  GB 2312-80              <ESC> $ A            0x1B2441
  KS C 5601-1992          <ESC> $ ( C          0x1B242843

With the introduction of ISO-2022-KR (see Section 3.1.4), ISO-2022-CN
(see Section 3.1.5), and ISO-2022-CN-EXT (see Section 3.1.5), the
usefulness of supporting GB 2312-80 and KS C 5601-1992 can be
questioned. However, ISO-2022-JP-2 provides support for JIS X
0212-1990.
	More detailed information on ISO-2022-JP encoding can be found
in RFC 1468. And, more detailed information on ISO-2022-JP-2 encoding
can be found in RFC 1554.


3.1.4: ISO-2022-KR

	ISO-2022-KR is similar to ISO-2022-JP (see Section 3.1.3) in
that it reflects how Korean text is encoded for e-mail messages.
However, its actual implementation is a bit different. Below is a
summary.
	There are only two shift sequences used in ISO-2022-KR,
indicated as follows:

  One-byte Character Set  Shift Sequence       Hexadecimal
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
  ASCII (ANSI X3.4-1986)  <SI>                 0x0F

  Two-byte Character Set  Shift Sequence       Hexadecimal
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
  KS C 5601-1992          <SO>                 0x0E

Furthermore, the following designator sequence must appear only once,
at the beginning of a line, before any KS C 5601-1992 characters (this
usually means that it appears by itself on the first line of the
file):

  <ESC> $ ) C             0x1B242943

It almost looks the same as the KS C 5601-1992 escape sequence in
7-bit ISO 2022, but look again. The opening parenthesis (0x28 or "(")
is replaced by a closing parenthesis (0x29 or ")"). This designator
sequence serves a different purpose than an escape sequence. It is
like a flag indicating that "this document contains KS C 5601-1992
characters." The <SO> and <SI> control characters actually perform the
switching between one- (ASCII) and two-byte (KS C 5601-1992) codes.
	More detailed information on ISO-2022-KR encoding can be found
in RFC 1557.


3.1.5: ISO-2022-CN AND ISO-2022-CN-EXT

	ISO-2022-CN and ISO-2022-CN-EXT are similar to ISO-2022-JP
(see Section 3.1.3) and ISO-2022-KR (see Section 3.1.4) in that they
reflect how Chinese text is encoded for e-mail messages.
	Like with ISO-2022-KR, there are only two shift sequences,
indicated as follows:

  One-byte Character Set  Shift Sequence       Hexadecimal
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
  ASCII (ANSI X3.4-1986)  <SI>                 0x0F

  Two-byte Character Set  Shift Sequence       Hexadecimal
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
  <Too Many to List>      <SO>                 0x0E

But, unlike ISO-2022-KR, there are single shift sequences. Single
shift means that they are used before every (single) character, not
before sequences of characters.

  Single Shift Type       Shift Sequence       Hexadecimal
  ^^^^^^^^^^^^^^^^^       ^^^^^^^^^^^^^^       ^^^^^^^^^^^
  SS2                     <ESC> N              0x1B4E
  SS3                     <ESC> O (not zero!)  0x1B4F

	ISO-2022-CN supports the following character sets using SO and
SS2 designations:

  Character Set           Type   Designation Sequence  Hexadecimal
  ^^^^^^^^^^^^^           ^^^^   ^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^
  GB 2312-80              SO     <ESC> $ ) A           0x1B242941
  CNS 11643-1992 Plane 1  SO     <ESC> $ ) G           0x1B242947
  CNS 11643-1992 Plane 2  SS2    <ESC> $ * H           0x1B242A48

The designator sequences must appear once on a line before any
instance of the character set it designates. If two lines contain
characters from the same character set, both lines must include the
designator sequence (this is so the text can be displayed correctly
when scroll back in a window). This is different behavior from
ISO-2022-KR where the designator sequence appears once in the entire
file (this is because ISO-2022-KR supports a single two-byte character
set).
	ISO-2022-CN-EXT supports the following character sets using
SO, SS2, and SS3 designations (notice how ISO-2022-CN is still
supported in the same manner):

  Character Set           Type   Designation Sequence  Hexadecimal
  ^^^^^^^^^^^^^           ^^^^   ^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^
  GB 2312-80              SO     <ESC> $ ) A           0x1B242941
  GB/T 12345-90           SO     NOT REGISTERED
  ISO-IR-165              SO     <ESC> $ ) E           0x1B242945
  CNS 11643-1992 Plane 1  SO     <ESC> $ ) G           0x1B242947
  CNS 11643-1992 Plane 2  SS2    <ESC> $ * H           0x1B242A48
  GB 7589-87              SS2    NOT REGISTERED
  GB/T 13131-9X           SS2    NOT REGISTERED
  CNS 11643-1992 Plane 3  SS3    <ESC> $ + I           0x1B242B49
  CNS 11643-1992 Plane 4  SS3    <ESC> $ + J           0x1B242B4A
  CNS 11643-1992 Plane 5  SS3    <ESC> $ + K           0x1B242B4B
  CNS 11643-1992 Plane 6  SS3    <ESC> $ + L           0x1B242B4C
  CNS 11643-1992 Plane 7  SS3    <ESC> $ + M           0x1B242B4D
  GB 7590-87              SS3    NOT REGISTERED
  GB/T 13132-9X           SS3    NOT REGISTERED

Support for character sets indicated as NOT REGISTERED will be added
once they are ISO-registered.
	More detailed information on ISO-2022-CN and ISO-2022-CN-EXT
encodings can be found in RFC 1922.


3.2: EUC ENCODING

	EUC stands for "Extended UNIX Code," and is a rich encoding
system from ISO 2022-1993 that is designed to handle large or multiple
character sets. It is primarily used on UNIX systems, such as Sun's
Solaris.
	EUC consists of four codes sets, numbered 0 through 3. The
only code set that is more or less fixed by definition is code set 0,
which is specified to contain ASCII or a locale's equivalent (such as
JIS X 0201-1976 for Japanese or GB 1988-89 for PRC Chinese).
	It is quite common to append the locale name to "EUC" when
designating a specific instance of EUC encoding. Common designations
include EUC-JP, EUC-CN, EUC-KR, and EUC-TW.


3.2.1: JAPANESE REPRESENTATION

	The following table illustrates the Japanese representation of
EUC packed format:

  EUC Code Sets                                 Encoding Range
  ^^^^^^^^^^^^^                                 ^^^^^^^^^^^^^^
  Code set 0 (ASCII or JIS X 0201-1976 Roman):  0x21-0x7E
  Code set 1 (JIS X 0208):                      0xA1A1-0xFEFE
  Code set 2 (half-width katakana):             0x8EA1-0x8EDF
  Code set 3 (JIS X 0212-1990):                 0x8FA1A1-0x8FFEFE

An earlier version of EUC for Japanese used code set 3 as the user-
defined range.


3.2.2: CHINESE (PRC) REPRESENTATION

	The following table illustrates the Chinese (PRC)
representation of EUC packed format:

  EUC Code Sets                                 Encoding Range
  ^^^^^^^^^^^^^                                 ^^^^^^^^^^^^^^
  Code set 0 (ASCII or GB 1988-89):             0x21-0x7E
  Code set 1 (GB 2312-80):                      0xA1A1-0xFEFE
  Code set 2:                                   unused
  Code set 3:                                   unused

Note how code sets 2 and 3 are unused.
	The encoding used on Macintosh is quite similar, but has a
shortened two-byte range (0xA1A1 through 0xFCFE) plus additional
one-byte code points, namely 0x80 ("u" with dieresis), 0xFD
("copyright" symbol: "c" in a circle), 0xFE ("trademark" symbol: "TM"
as a superscript), and 0xFF ("ellipsis" symbol: three dots).


3.2.3: CHINESE (TAIWAN) REPRESENTATION

	The following table illustrates the Chinese (Taiwan)
representation of EUC packed format:

  EUC Code Sets                                 Encoding Range
  ^^^^^^^^^^^^^                                 ^^^^^^^^^^^^^^
  Code set 0 (ASCII):                           0x21-0x7E
  Code set 1 (CNS 11643-1992 Plane 1):          0xA1A1-0xFEFE
  Code set 2 (CNS 11643-1992 Planes 1-16):      0x8EA1A1A1-0x8EB0FEFE
  Code set 3:                                   unused

Note how CNS 11643-1992 Plane 1 is redundantly encoded in code set 1
(two-byte) and code set 2 (four-byte). The second byte of code set 2
indicates the plane number. For example, 0xA1 is Plane 1 and so on up
until 0xB0, which is Plane 16.


3.2.4: KOREAN REPRESENTATION

	The following table illustrates the Korean representation of
EUC packed format (this is also known as "Wansung" encoding -- the
Korean word "wansung" means "pre-compose"):

  EUC Code Sets                                 Encoding Range
  ^^^^^^^^^^^^^                                 ^^^^^^^^^^^^^^
  Code set 0 (ASCII or KS C 5636-1993):         0x21-0x7E
  Code set 1 (KS C 5601-1992):                  0xA1A1-0xFEFE
  Code set 2:                                   unused
  Code set 3:                                   unused

Note how code sets 2 and 3 are unused.
	The encoding used on Macintosh is quite similar, but has a
shortened two-byte range (0xA1A1 through 0xFDFE) plus additional
one-byte code points, namely 0x81 ("won" symbol), 0x82 (hyphen), 0x83
("copyright" symbol: "c" in a circle), 0xFE ("trademark" symbol: "TM"
as a superscript), and 0xFF ("ellipsis" symbol: three dots).
	See Section 3.3.17 for a description of Microsoft's extension
to this encoding, called Unified Hangul Code.


3.3: LOCALE-SPECIFIC ENCODINGS

	The encoding systems described in the following sections are
considered to be locale-specific, namely that are used to encode a
specific character set standard. This is not to say that they are not
widely used (actually, some of these are among the most widely used
encoding systems!), but rather that they are tied to a specific
character set.


3.3.1: SHIFT-JIS

	Shift-JIS (also known as MS Kanji, SJIS, or DBCS-PC) is the
encoding system used on machines that support MS-DOS or Windows, and
also for Macintosh (KanjiTalk or Japanese Language Kit). It was
originally developed by Microsoft Corporation as a way to support the
Japanese character set on MS-DOS. The following tables provide the
Shift-JIS encoding ranges:

  Two-byte Standard Characters                  Encoding Ranges
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
  first byte ranges                             0x81-0x9F, 0xE0-0xEF
  second byte ranges                            0x40-0x7E, 0x80-0xFC

  Two-byte User-defined Characters              Encoding Ranges
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^              ^^^^^^^^^^^^^^^
  first byte range                              0xF0-0xFC
  second byte ranges                            0x40-0x7E, 0x80-0xFC

  One-byte Characters                           Encoding Range
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  Half-width katakana                           0xA1-0xDF
  ASCII/JIS-Roman                               0x21-0x7E

It is important to note that the user-defined range does not
correspond to code points in other encodings that support Japanese,
such as 7-bit ISO 2022 or EUC. This is a portability problem. It is
also unique in that it does not support the JIS X 0212-1990 character
set standard.
	The encoding used on Macintosh is quite similar to the above
table, but has additional one-byte code points, namely 0x80
(backslash), 0xFD ("copyright" symbol: "c" in a circle), 0xFE
("trademark" symbol: "TM" as a superscript), and 0xFF ("ellipsis"
symbol: three dots).


3.3.2: HZ (HZ-GB-2312)

	HZ is a simple yet very powerful and reliable system for
encoding GB 2312-80 text which was developed by Fung Fung Lee
([email protected]). HZ encoding is commonly used when
exchanging e-mail or posting messages to Usenet News (specifically, to
alt.chinese.text).
	The actual encoding ranges used for one- and two-byte
characters is almost identical to 7-bit ISO 2022 encoding (see Section
3.1.1). The first-byte range is limited to 0x21 through 0x77. But,
instead of using an escape sequence to shift between one- and two-byte
character modes, a simple string of two printable characters is used.

  One-byte Character Set  Shift Sequence       Hexadecimal
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
  ASCII                   ~}                   0x7E7D

  Two-byte Character Set  Shift Sequence       Hexadecimal
  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
  GB 2312-80              ~{                   0x7E7B

The tilde character (0x7E) is interpreted as an escape character in HZ
encoding, so it has special meaning. If a tilde character is to appear
in one-byte-per-character mode, it must be doubled (so ~~ would appear
as just ~). This means that there are three escape sequences used in
HZ encoding:

  Escape Sequence  Meaning
  ^^^^^^^^^^^^^^^  ^^^^^^^
  ~~               ~ in one-byte-per-character mode
  ~}               Shift into one-byte-per-character mode
  ~{               Shift into two-byte-per-character mode

There is also a fourth escape sequence, namely ~ plus a newline
character (~\n). This escape sequence is a line-continuation marker to
be consumed with no output produced.
	This method works without problems because the shift sequences
represent empty positions in the very last row of the GB 2312-80 table
(actually, the second- and third-from-last code points). HZ encoding
makes 77 of the 94 rows accessible, and because there are no defined
characters beyond row 77, this causes no problems.
	The complete HZ specification is part of the HZ package,
described in RFC 1843, and available in HTML format. These are
available at the following URLs:

  ftp://ftp.ifcss.org/pub/software/unix/convert/HZ-2.0.tar.gz
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/Ch9/rfc-1843.txt
  http://umunhum.stanford.edu/~lee/chicomp/HZ_spec.html

In addition, RFC 1842 establishes "HZ-GB-2312" as the "charset"
parameter in MIME-encoded e-mail headers. Its properties are identical
to HZ encoding as described in RFC 1843.


3.3.3: zW

	zW encoding, developed by Ya-Gui Wei and Edmund Lai, is older
than and somewhat similar to HZ encoding (HZ is considered to be a
better encoding system, and users are encouraged to switch over to HZ
encoding).
	zW encoding is named by how it encodes each line of GB 2312-80
text, namely lines that contain Chinese text must begin with the two
characters "z" and "W" ("zW"). This encoding method does not permit
the mixture of one- (ASCII) and two-byte (GB 2312-80) characters on a
per-character basis, but rather on a per-line basis. That is, each
line can contain only Chinese or ASCII text, but not both.
	More information on zW encoding can be found as part of the
ZWDOS package available at the following URL:

  ftp://ftp.ifcss.org/pub/software/dos/ZWDOS/


3.3.4: BIG FIVE

	Big Five is the encoding system used on machines that support
MS-DOS or Windows, and also for Macintosh (such as the Chinese
Language Kit or the fully-localized operating system).

  Two-byte Standard Characters                  Encoding Ranges
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
  first byte range                              0xA1-0xFE
  second byte ranges                            0x40-0x7E, 0xA1-0xFE

  One-byte Characters                           Encoding Range
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  ASCII                                         0x21-0x7E

	The encoding used on Macintosh is quite similar to the above,
but has a slightly shortened two-byte range (second byte range up to
0xFC only) plus additional one-byte code points, namely 0x80
(backslash), 0xFD ("copyright" symbol: "c" in a circle), 0xFE
("trademark" symbol: "TM" as a superscript), and 0xFF ("ellipsis"
symbol: three dots).


3.3.5: JOHAB

	Korean hangul characters are typically encoded in what is
known as pre-combined form, namely 2 or 3 hangul elements bound into a
single character. KS C 5601-1992 enumerates 2,350 such pre-combined
forms. While this number is felt to be sufficient for most purposes,
it does not account for the total number of possible permutations. The
encoding system that encodes all possible pre-combined hangul is known
as Johab encoding (also known as "two-byte combination code" -- the
Korean word "johab" means "combine"), and is described in Annex 3 of
the KS C 5601-1992 standard. This encoding is almost like encoding all
possible three-letter words in English -- while all combinations are
possible, only a fraction represent *real* words.
	Pre-combined hangul can be composed of 19 different initial,
21 different medial, and 27 different final hangul elements (28,
actually, if you count the placeholder). This provides a maximum of
11,172 pre-combined hangul. Of these 67 hangul elements, 51 are unique
(some can occur in different positions). Each of these positions are
encoded using five bits each (five bits can encode up to 32 unique
objects). The encoding array looks as follows:

o Bit 1: always on
o Bits 2-6: initial hangul element
o Bits 7-11: medial hangul element
o Bits 12-16: final hangul element

Initial and final elements are consonants, and the medial elements are
vowels. This encoding must be treated as a 16-bite entity because the
bit array of the medial hangul element spans the first and second byte.
	Johab encoding also provides the complete set of KS C 5601-
1992 symbols and hanja, but in different code points. Annex 3 of the
KS C 5601-1992 manual (pp 33-34) contains a complete symbol and hanja
mapping table between EUC and Johab code points. (The KS C 5601-1989
manual did not have this.) The code space ranges for Johab encoding
are as follows:

  One-byte Characters                           Encoding Range
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  ASCII or KS C 5636-1993                       0x21-0x7E

  Two-byte Pre-combined Hangul                  Encoding Ranges
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
  first byte range                              0x84-0xD3
  second byte ranges                            0x41-0x7E, 0x81-0xFE

  Two-byte Symbols and Hanja                    Encoding Ranges
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
  first byte ranges                             0xD8-0xDE, 0xE0-0xF9
  second byte ranges                            0x31-0x7E, 0x91-0xFE

Note that the second byte ranges encode a total of 188 characters, and
that the second byte ranges for hangul and symbols/hanja are slightly
different (yet the same size, namely 188 characters).
	Here is a summary of the above table, which better describes
what is encoded where. Rows 0x84 through 0xD3 provide 80 rows of 188
characters each (15,040 code points, which is more than enough for the
11,172 pre-combined hangul). Row 0xD8 provides 188 user-defined
positions, the same as Rows 41 and 94 in the standard KS C 5601-1992
table. Rows 0xD9 through 0xDE encode Rows 1 through 12 of the standard
KS C 5601-1992 table (symbols). Rows 0xE0 through 0xF9 encode Rows 42
through 94 of the KS C 5601-1992 table (hanja). The following URL
provides a complete mapping table for the KS C 5601-1992 symbols and
hanja:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/non-hangul-codes.txt

The following URLs provides similar information (they are the same
file), but only for the 11,172 pre-combined hangul:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/hangul-codes.txt
  ftp://unicode.org/pub/MappingTables/EastAsiaMaps/hangul-codes.txt

	Of further interest may be that Microsoft designates Johab
encoding as its Code Page 1361. Microsoft if planning to support Johab
encoding for Korean Windows NT.


3.3.6: N-BYTE HANGUL

	In the days before full two-byte capable operating systems,
each of the 51 basic hangul elements were encoding using a single
(7-bit) byte. The encoding range spans 0x40 through 0x7C, but there
are several unassigned gaps. This is known as the "N-byte Hangul"
code, and is described in Annex 4 (page 35) of the KS C 5601-1992
manual.
	The following table illustrates these 51 one-byte code points
(the pronunciation or meaning of the hangul element is provided in
parentheses) and how they map to the three 5-bit arrays in Johab
encoding (expressed as binary patterns):

  Element        Initial  Medial   Final
  ^^^^^^^        ^^^^^^^  ^^^^^^   ^^^^^
  0x40 ("fill")  00001    00010    00001
  0x41 (g)       00010    *****    00010
  0x42 (gg)      00011    *****    00011
  0x43 (gs)      *****    *****    00100
  0x44 (n)       00100    *****    00101
  0x45 (nj)      *****    *****    00110
  0x46 (nh)      *****    *****    00111
  0x47 (d)       00101    *****    01000
  0x48 (dd)      00110    *****    *****
  0x49 (r)       00111    *****    01001
  0x4A (rg)      *****    *****    01010
  0x4B (rm)      *****    *****    01011
  0x4C (rb)      *****    *****    01100
  0x4D (rs)      *****    *****    01101
  0x4E (rt)      *****    *****    01110
  0x4F (rp)      *****    *****    01111
  0x50 (rh)      *****    *****    10000
  0x51 (m)       01000    *****    10001
  0x52 (b)       01001    *****    10011
  0x53 (bb)      01010    *****    *****
  0x54 (bs)      *****    *****    10100
  0x55 (s)       01011    *****    10101
  0x56 (ss)      01100    *****    10110
  0x57 (ng)      01101    *****    10111
  0x58 (j)       01110    *****    11000
  0x59 (jj)      01111    *****    *****
  0x5A (c)       10000    *****    11001
  0x5B (k)       10001    *****    11010
  0x5C (t)       10010    *****    11011
  0x5D (p)       10011    *****    11100
  0x5E (h)       10100    *****    11101
  0x5F UNASSIGNED
  0x60 UNASSIGNED
  0x61 UNASSIGNED
  0x62 (a)       *****    00011    *****
  0x63 (ae)      *****    00100    *****
  0x64 (ya)      *****    00101    *****
  0x65 (yae)     *****    00110    *****
  0x66 (eo)      *****    00111    *****
  0x67 (e)       *****    01010    *****
  0x68 UNASSIGNED
  0x69 UNASSIGNED
  0x6A (yeo)     *****    01011    *****
  0x6B (ye)      *****    01100    *****
  0x6C (o)       *****    01101    *****
  0x6D (wa)      *****    01110    *****
  0x6E (wae)     *****    01111    *****
  0x6F (oe)      *****    10010    *****
  0x70 UNASSIGNED
  0x71 UNASSIGNED
  0x72 (yo)      *****    10011    *****
  0x73 (u)       *****    10100    *****
  0x74 (weo)     *****    10101    *****
  0x75 (we)      *****    10110    *****
  0x76 (wi)      *****    10111    *****
  0x77 (yu)      *****    11010    *****
  0x78 UNASSIGNED
  0x79 UNASSIGNED
  0x7A (eu)      *****    11011    *****
  0x7B (yi)      *****    11100    *****
  0x7C (i)       *****    11101    *****

	There are utilities to convert N-byte Hangul code to other,
more widely-used, encoding methods. Pointers to these and other code
conversion utilities can be found in Section 4.7.


3.3.7: UCS-2

	UCS-2 (Universal Character Set containing 2 bytes) encoding is
one way to encode ISO 10646-1:1993 text, and is considered identical
to Unicode encoding. Its encoding range, which is quite simple, is as
follows:

  ISO 10646-1:1993 Characters                   Encoding Range
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^
  first byte range                              0x00-0xFF
  second byte range                             0x00-0xFF

Yes, folks, the whole range of 65,536 possible code points are
available for encoding characters. The "signature" that indicates a
file using UCS-2 is as follows:

  0xFEFF

	Escape sequences for UCS-2 have already been registered with
ISO, and are as follows:

  ISO 10646-1:1993        Escape Sequence      Hexadecimal     ISO Reg
  ^^^^^^^^^^^^^^^^        ^^^^^^^^^^^^^^^      ^^^^^^^^^^^     ^^^^^^^
  UCS-2 Level 1           <ESC> % / @          0x1B252F40      162
  UCS-2 Level 2           <ESC> % / C          0x1B252F43      174
  UCS-2 Level 3           <ESC> % / E          0x1B252F45      176

So what do these three levels mean? Level 3 means all characters in
ISO 10646-1:1993 with no restrictions (0x0000 through 0xFFFF).
	Level 2 begins to restrict the character set by not including
the following characters or character ranges:

  0x0300-0x0345  0x09D7         0x0BD7         0x11A8-0x11F9
  0x0360-0x0361  0x0A3C         0x0C55-0x0C56  0x20D0-0x20E1
  0x0483-0x0486  0x0A70-0x0A71  0x0CD5-0x0CD6  0x302A-0x302F
  0x093C         0x0ABC         0x0D57         0x3099-0x309A
  0x0953-0x0954  0x0B3C         0x1100-0x1159  0xFE20-0xFE23
  0x09BC         0x0B56-0x0B57  0x115F-0x11A2

These are all combining characters, and represent 364 code points.
	Level 1 further restricts the character set by not including
the following characters or character ranges:

  0x05B0-0x05B9  0x09BE-0x09C4  0x0B47-0x0B48  0x0D02-0x0D03
  0x05BB-0x05BD  0x09C7-0x09C8  0x0B4B-0x0B4D  0x0D3E-0x0D43
  0x05BF         0x09CB-0x09CD  0x0B82-0x0B83  0x0D46-0x0D48
  0x05C1-0x05C2  0x09E2-0x09E3  0x0BBE-0x0BC2  0x0D4A-0x0D4D
  0x064B-0x0652  0x0A02         0x0BC6-0x0BC8  0x0E31
  0x0670         0x0A3E-0x0A42  0x0BCA-0x0BCD  0x0E34-0x0E3A
  0x06D6-0x06E4  0x0A47-0x0A48  0x0C01-0x0C03  0x0E47-0x0E4E
  0x06E7-0x06E8  0x0A4B-0x0A4D  0x0C3E-0x0C44  0x0EB1
  0x06EA-0x06ED  0x0A81-0x0A83  0x0C46-0x0C48  0x0EB4-0x0EB9
  0x0901-0x0903  0x0ABE-0x0AC5  0x0C4A-0x0C4D  0x0EBB-0x0EBC
  0x093E-0x094D  0x0AC7-0x0AC9  0x0C82-0x0C83  0x0EC8-0x0ECD
  0x0951-0x0952  0x0ACB-0x0ACD  0x0CBE-0x0CC4  0xFB1E
  0x0962-0x0963  0x0B01-0x0B03  0x0CC6-0x0CC8
  0x0981-0x0983  0x0B3E-0x0B43  0x0CCA-0x0CCD

These, too, are all combining characters, and represent 586 code
points (222 above plus the 364 characters from the Level 2
restriction).


3.3.8: UCS-4

	UCS-4 (Universal Character Set containing 4 bytes) encoding is
another way to encode ISO 10646-1:1993 text, and is used for future
expansion of the character set. Its encoding range is as follows:

  ISO 10646-1:1993 Characters                   Encoding Range
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^
  first byte range                              0x00-0x7F
  second byte range                             0x00-0xFF
  third byte range                              0x00-0xFF
  fourth byte range                             0x00-0xFF

Note that the first byte range only goes up to 0x7F. This means that
UCS-4 is a 31-bit encoding. And, in case you're wondering, 31 bits
provide 2,147,483,648 code points. The "signature" that indicates a
file using UCS-4 is as follows:

  0x0000 0xFEFF

	Escape sequences for UCS-4 have already been registered with
ISO, and are as follows:

  ISO 10646-1:1993        Escape Sequence      Hexadecimal     ISO Reg
  ^^^^^^^^^^^^^^^^        ^^^^^^^^^^^^^^^      ^^^^^^^^^^^     ^^^^^^^
  UCS-4 Level 1           <ESC> % / A          0x1B252F41      163
  UCS-4 Level 2           <ESC> % / D          0x1B252F44      175
  UCS-4 Level 3           <ESC> % / F          0x1B252F46      177

See the end of Section 3.3.7 for a description of these three levels.
But, in the case of UCS-4, simply prepend "0000" to all the values.


3.3.9: UTF-7

	It turns out that *raw* ISO 10646-1:1993 encoding (that is,
UCS-2 or UCS-4) can cause problems because null bytes (0x00) are
possible (and frequent). Several UTFs (UCS Transformation Formats)
have been developed to deal with this and other problems. I must admit
that I don't know too much about UTFs, and what I provide below is
minimal, but does include pointers to more complete descriptions.
	UTF-7 is a mail-safe 7-bit transformation format for UCS-2
(including UTF-16). It uses straight ASCII for many ASCII characters,
and switches into a Base64 encoding of UCS-2 or UTF-16 for everything
else. It was designed to be usable in MIME-compliant e-mail headers as
well as message bodies, and to pass through gateways to non-ASCII mail
systems (like Bitnet). More detailed information on UTF-7 can be found
in RFC 1642, and a UTF-7 converter is available. The following URLs
provide this information:

  http://www.stonehand.com/unicode/standard/utf7.html
  ftp://unicode.org/pub/Programs/ConvertUTF/


3.3.10: UTF-8

	UTF-8 (also known as UTF-2 or FSS-UTF -- FSS stands for "file
system safe") can represent any character in UCS-2 and UCS-4, and is
officially an annex to ISO 10646-1:1993. It is different from UTF-7 in
that it encodes character sets into 8-bit bytes. UCS-2 and UCS-4 have
problems with some file systems and utilities, so this UTF was
developed.
	More detailed information on UTF-8 and its relationship with
ISO 10646-1:1993 can be found at the following URLs:

  http://www.stonehand.com/unicode/standard/utf8.html
  ftp://unicode.org/pub/Programs/ConvertUTF/

	X/Open Company Limited also published a document that
describes UTF-8 in detail (they call it FSS-UTF), and you can find
information about it at the following URL:

  http://www.xopen.co.uk/public/pubs/catalog/c501.htm

The new programming language called Java supports Unicode through
UTF-8. More information on Java is at the following URL:

  http://www.javasoft.com/


3.3.11: UTF-16

	UTF-16 (formerly UCS-2E), like UTF-8, is now officially an
annex to ISO 10646-1:1993. From what I've read, UTF-16 transforms
UCS-4 into a 16-bit form. UTF-16 can then be further encoded in UTF-7
or UTF-8 (but doing this is not according to the standard -- there is
little to gain by doing so).
	More detailed information on UTF-16 and its relationship with
ISO 10646-1:1993 can be found at the following URLs:

  http://www.stonehand.com/unicode/standard/utf16.html
  ftp://unicode.org/pub/Programs/ConvertUTF/


3.3.12: ANSI Z39.64-1989

	The encoding used for ANSI Z39.64-1989 (and CCCII) is three-
byte 7-bit ISO 2022, namely the following code space:

  Three-byte ANSI Z39.64-1989                   Encoding Range
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^                   ^^^^^^^^^^^^^^
  first byte range                              0x21-0x7E
  second byte range                             0x21-0x7E
  third byte range                              0x21-0x7E


3.3.13: BASE64

	Base64 encoding is mentioned here only because of its common
usage in e-mail headers, and relationship with MIME (Multi-purpose
Internet Mail Extensions). It is also a source of confusion. Base64 is
a method of encoding arbitrary bytes into the safest 64-character
ASCII subset, and is defined in RFC 1341 (which adapted it from RFC
1113). RFC 1341 was made obsolete by RFC 1521. RFC 1522 also provides
useful information, particularly for handling non-ASCII text, and
obsoletes RFC 1342.
	Here is how it works. Every three bytes are encoded as a
four-byte sequence. That is, the 24 bits that make up the three bytes
are split into four 6-bit segments (6 bits can encode up to 64
characters). Each 6-bit segment is then converted into a character in
the Base64 Alphabet (see below). There is a 65th character, "=", which
has a special purpose (it functions as a "pad" if a full three-byte
sequence is not found). This all may sound a bit like uuencoding, but
it is different. The Base64 Alphabet is as follows:

  ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

	My name, written in Japanese kanji, is as follows when it is
EUC-encoded (six bytes, expressed as three groups of hexadecimal
values, one group for each character):

  0xBEAE 0xCED3 0xB7F5

When these three EUC-encoded characters are converted to Base64
encoding, they appear as follows (eight bytes):

  vq7O07f1

	Base64 encoding is most commonly used for encoding non-ASCII
text that appears in e-mail headers. Of all the portions of an e-mail
message, its header gets manipulated the most during transmission, and
Base64 encoding offers a safe way to further encode non-ASCII text so
that it is not altered by mail-routing software. This is where Base64
encoding can cause confusion. For example, what goes through your mind
when you see the following chunk o' text?

  From: [email protected] (=?ISO-2022-JP?B?vq7O07f1?=)

Many folks think that they are seeing ISO-2022-JP encoding. Not
true. The "ISO-2022-JP" portion is just a flag that indicates the
original encoding before Base64 encoding was applied. The actual
Base64-encoded portion is enclosed between question marks (?) as
follows:

  From: [email protected] (=?ISO-2022-JP?B?vq7O07f1?=)
                                        >^^^^^^^^<

The whole string enclosed in parentheses has several components, and
the following explains their purpose and relationships (using the
above string as an example):

  Component      Explanation
  ^^^^^^^^^      ^^^^^^^^^^^
  =?             Signals start of encoded string
  ISO-2022-JP    Charset name ("ISO-2022-JP" is for Japanese)
  ?              Delimiter
  B              Encoding ("B" is for Base64)
  ?              Delimiter
  vq7O07f1       Example string of type "charset" encoded by "encoding"
  ?=             Signals end of encoded string

	One typically does not need to worry about encoding text as
Base64 (MIME-compliant mailing software usually performs this task for
you). The problem is usually trying to decode Base64-encoded text. A
Base64 decoder is available in Perl at the following URL:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/perl/b64decode.pl

Note that this program takes "raw" Base64 data as input. Any non-
Base64 stuff must be stripped. I usually run this from within Mule
("C-u M-| b64decode.pl") after defining a region around the Base64-
encoded material. I hope to replace this program soon with one that
automatically recognizes the Base64-encoded portions.
	Most MIME-compliant e-mail software can decode Base64-encoded
text.


3.3.14: IBM DBCS-HOST

	The oldest two-byte encoding system is IBM's DBCS-Host. DBCS
stands for Double-Byte Character Set. DBCS-Host is still in use on
IBM's mainframe computer systems (hence the use of "Host").
	DBCS-Host encoding is EBCDIC-based, and uses Shift characters,
0x0E and 0x0F, to switch between one- and two-byte mode. Its encoding
specifications are as follows:

  Two-byte Characters                           Encoding Range
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  first byte range                              0x41-0xFE
  second byte range                             0x41-0xFE

  Two-byte "Space" Character                    Code Point
  ^^^^^^^^^^^^^^^^^^^^^^^^^^                    ^^^^^^^^^^
  first- and second byte                        0x4040

  One-byte Characters                           Encoding Range
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  EBCDIC                                        0x41-0xF9

  Shifting Characters                           Code Point
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  Two-byte                                      0x0E
  One-byte                                      0x0F

This same encoding specification is shared by all of IBM's CJK
character sets, namely for Japanese, Simplified Chinese, Traditional
Chinese, and Korean.


3.3.15: IBM DBCS-PC

	IBM's DBCS-PC encoding is used on IBM personal computers (that
is where the "PC" comes from). DBCS-PC encoding is ASCII-based, and
uses the values of characters' bytes themselves to switch between one-
and two-byte mode. Its encoding specifications are as follows:

  Two-byte Characters                           Encoding Ranges
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^^
  first byte range                              0x81-0xFE
  second byte range                             0x40-0x7E, 0x80-0xFE

  One-byte Characters                           Encoding Range
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  ASCII                                         0x21-0x7E

This same encoding specification is shared by all of IBM's CJK
character sets, namely for Japanese, Simplified Chinese, Traditional
Chinese, and Korean.
	DBCS-PC encoding for Japanese, although conforming to the
above encoding specifications, actually uses the same encoding
specifications for Shift-JIS, to include the full user-defined range
(see Section 3.3.1 for more details on Shift-JIS encoding). One big
accommodation is the half-width katakana range, namely 0xA1 through
0xDF. Further, the DBCS-PC code space that is outside the Shift-JIS
specification is unused.
	DBCS-PC encoding for Korean uses the equivalent of EUC code
set 1 code points (0xA1A1 through 0xFEFE) for those characters that
are common with KS C 5601-1992. Those characters that are not common
with KS C 5601-1992, namely IBM's extensions, are within the DBCS-PC
encoding space, but outside EUC encoding space (0x9A through 0xA0).
Many hanja and pre-combined hangul are part of IBM's Korean extension.
	Note that DBCS-PC is sort of useless without a corresponding
SBCS (Single-Byte Character Set) for the one-byte range. Mixing DBCS
and SBCS results in a MBCS (Multiple-Byte Character Set). How these
are mixed to form MBCSs is detailed in Section 3.4.


3.3.16: IBM DBCS-/TBCS-EUC

	IBM has also developed DBCS-EUC and TBCS-EUC encodings. TBCS
stands for Triple-Byte Character Set. These essentially follow the EUC
encoding specifications, and were developed for use with IBM's AIX
(Advanced Interactive Executive) operating system, which is
UNIX-based.
	Refer to Section 3.2 for all the details on EUC encoding.


3.3.17: UNIFIED HANGUL CODE

	Microsoft has developed what is called "Unified Hangul Code"
(UHC) for its Windows 95 operating system (this was also known as
"Extended Wansung"). It is the optional, not standard, character set
of Win95K.
	UHC provides full compatibility with KS C 5601-1992 EUC
encoding (see Section 3.2.4), but adds additional encoding ranges for
holding additional pre-combined hangul (more precisely, the 8,822 that
are needed to fully support the Johab character set). The following is
a table that provides the encoding ranges for UHC encoding:

  Two-byte Standard Characters                  Encoding Ranges
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
  first byte range                              0x81-0xFE
  second byte ranges                            0x41-0x5A, 0x61-0x7A,
                                                and 0x81-0xFE

  One-byte Characters                           Encoding Range
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  ASCII                                         0x21-0x7E

Note that 0xA1A1 through 0xFEFE in the above encoding is still
identical, in terms of character-to-code allocation, with KS C 5601-
1992 in EUC encoding.
	Appendix G (pp 345-406) of "Developing International Software
for Windows 95 and Windows NT" by Nadine Kano illustrates the KS C
5601-1992 character set standard plus these Microsoft extensions
(8,822 pre-combined hangul) by UHC code (Microsoft calls this Code
Page 949).


3.3.18: TRON CODE

	TRON (The Real-time Operating system Nucleus) is an OS
developed in Japan some time ago. Personal Media Corporation has done
work to develop BTRON (Business TRON), which is unique in that it is
the only commercially-available OS that supports JIS X 0212-1990.
	TRON Code provides a one- and two-byte encoding space and a
method for switching between them.
	The following is how the two-byte space in TRON Code is
allocated:

  A-Zone (8,836 characters; JIS X 0208-1990)    Encoding Range
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^^
  first byte range                              0x21-0x7E
  second byte range                             0x21-0x7E

  B-Zone (11,844 characters; JIS X 0212-1990)   Encoding Range
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^
  first byte range                              0x80-0xFD
  second byte range                             0x21-0x7E

  C-Zone (11,844 characters; unassigned)        Encoding Range
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        ^^^^^^^^^^^^^^
  first byte range                              0x21-0x7E
  second byte range                             0x80-0xFD

  D-Zone (15,876 characters; unassigned)        Encoding Range
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        ^^^^^^^^^^^^^^
  first byte range                              0x80-0xFD
  second byte range                             0x80-0xFD

Note how the B-Zone is larger that the conventional 94-by-94
matrix. In fact, the JIS X 0212-1990 portion of the B-Zone is
restricted to 0xA121-0xFD7E (93-by-94 matrix -- 0xFE as a first-byte
value is unavailable, and you will see why in a minute).
	TRON Code implements "language specifying codes" consisting of
two bytes as follows:

  Two-byte Japanese                             0xFE21
  One-byte English                              0xFE80

0xFE21 in a one-byte stream invokes two-byte Japanese mode, and 0xFE80
in a two-byte stream invokes one-byte English mode.
	The following is the one-byte encoding range for TRON Code:

  One-byte Characters                           0x21-0x7E and 0x80-0xFD

Control codes are in 0x00-0x20 and 0x7F (the usual ASCII control code
range). Also, 0xA0 is reserved as a fixed-width space character.


3.3.19: GBK

	GBK is an extension to GB 2312-80 that adds all ISO 10646-
1:1993 (GB 13000.1-93) hanzi not already in GB 2312-80. GBK is defined
as a normative annex of GB 13000.1-93 (see Section 2.2.10). The "K" in
"GBK" is the first sound in the Chinese word meaning "extension" (read
"Kuo Zhan").
	GBK is divided into five levels as follows:

  Level  Encoded Range  Total Code Points  Total Encoded Characters
  ^^^^^  ^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^
  GBK/1  0xA1A1-0xA9FE    846                717
  GBK/2  0xB0A1-0xF7FE  6,768              6,763
  GBK/3  0x8140-0xA0FE  6,080              6,080
  GBK/4  0xAA40-0xFEA0  8,160              8,160
  GBK/5  0xA840-0xA9A0    192                166

	There are also 1,894 user-defined code points as follows:

  Encoded Range  Total Code Points
  ^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^
  0xAAA1-0xAFFE  564
  0xF8A1-0xFEFE  658
  0xA140-0xA7A0  672

	GBK thus provides a total of 23,940 code points, 21,886 of
which are assigned.
	Each "row" in the GBK code table consists of 190 characters.
The following describes the encoding ranges of GBK in detail:

  Two-byte Standard Characters                  Encoding Ranges
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
  first byte range                              0x81-0xFE
  second byte ranges                            0x40-0x7E and 0x80-0xFE

  One-byte Characters                           Encoding Range
  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
  ASCII                                         0x21-0x7E

Note that the sub-range 0xA1A1-0xFEFE in the above encoding is still
identical, in terms of character-to-code allocation, with GB 2312-80
in EUC encoding. GBK is therefore backward-compatible with GB 2312-80
and forward-compatible with ISO 10646-1:1993.
	GBK is the standard character set and encoding for the
Simplified Chinese version of Windows 95.


3.4: CJK CODE PAGES

	Many times one reads about references to "Code Pages" in
material about CJK (and other) character sets and encodings. These are
not literal pages, but rather references to a character set and
encoding combination. In the case of CJK Code Pages, they definitely
comprise more than one page!
	Microsoft refers to its supported CJK character sets and
encodings through such Code Page designations. The following is a
listing of several Microsoft CJK Code Pages along with their
characteristics:

  Code Page  Characteristics
  ^^^^^^^^^  ^^^^^^^^^^^^^^^
  932        JIS X 0208-1990 base, Shift-JIS encoding, Microsoft
             extensions (NEC Row 13 and IBM select characters in
             redundantly encoded in Rows 89 through 92 and Rows 115
             through 119)
  936        GB 2312-80 base, EUC encoding
  949        KS C 5601-1992 base, Unified Hangul Code encoding,
             remaining 8,822 pre-combined hangul as extension (all of
             this is referred to as Unified Hangul Code)
  950        Big Five base, Big Five encoding, Microsoft extensions
             (actually, the ETen extensions of Row 89)
  1361       Johab base, Johab encoding

	IBM also uses Code Page designations, and, in fact, some
designations (and associated characteristics) are nearly identical to
those in the above table, most notably, Code Pages 932 and 936. IBM's
Code Page 932 does not include NEC Row 13 or IBM select characters in
Rows 89 through 92.
	The best way to describe IBM Code Page designations is by
first listing the SBCS (Single-Byte Character Set) and DBCS (Double-
Byte Character Set) Code Page designations (those designated by "Host"
use EBCDIC-based encodings):

  IBM SBCS Code Page          Characteristics
  ^^^^^^^^^^^^^^^^^^          ^^^^^^^^^^^^^^^
  37 (US)                     SBCS-Host
  290 (Japanese)              SBCS-Host
  833 (Korean)                SBCS-Host
  836 (Simplified Chinese)    SBCS-Host
  891 (Korean)                SBCS-PC
  897 (Japanese)              SBCS-PC
  903 (Simplified Chinese)    SBCS-PC
  904 (Traditional Chinese)   SBCS-PC

  IBM DBCS Code Page          Characteristics
  ^^^^^^^^^^^^^^^^^^          ^^^^^^^^^^^^^^^
  300 (Japanese)              DBCS-Host
  301 (Japanese)              DBCS-PC
  834 (Korean)                DBCS-Host
  835 (Traditional Chinese)   DBCS-Host
  837 (Simplified Chinese)    DBCS-Host
  926 (Korean)                DBCS-PC
  927 (Traditional Chinese)   DBCS-PC
  928 (Simplified Chinese)    DBCS-PC

So far there appears to be no relationship with Microsoft's CJK Code
Pages, but when we combine the above SBCS and DBCS Code Pages into
MBCS (Multiple-Byte Character Set) Code Pages, things become a bit
more revealing:

  IBM MBCS Code Page          Characteristics
  ^^^^^^^^^^^^^^^^^^          ^^^^^^^^^^^^^^^
  930 (Japanese)              MBCS-Host (Code Pages 300 and 290)
  932 (Japanese)              MBCS-PC (Code Pages 301 and 897)
  933 (Korean)                MBCS-Host (Code Pages 834 and 833)
  934 (Korean)                MBCS-PC (Code Pages 926 and 891)
  938 (Traditional Chinese)   MBCS-PC (Code Pages 927 and 904)
  936 (Simplified Chinese)    MBCS-PC (Code Pages 928 and 903)
  5031 (Simplified Chinese)   MBCS-Host (Code Pages 837 and 836)
  5033 (Traditional Chinese)  MBCS-Host (Code Pages 835 and 37)

So, you can now see that many of Microsoft's CJK Code Pages are
derived from those established by IBM.
	More detailed information on the encoding specifications for
DBCS-Host and DBCS-PC can be found in Sections 3.3.14 and 3.3.15,
respectively.


PART 4: CJK CHARACTER SET COMPATIBILITY ISSUES

	The sections below provide detailed information about
compatibility issues between CJK character sets, to include tidbits of
useful information.
	One thing to mention first is that conversion to and from
IBM's DBCS-Host (Section 3.3.14) and DBCS-PC (Section 3.3.15)
encodings is table-driven, and fully documented in the following IBM
publication:

o IBM Corporation. "Character Data Representation Architecture - Level
  2, Registry." 1993. IBM order number SC09-1391-01.

Unfortunately, the CJK-related tables are not supplied in machine-
readable format, and must be obtained from IBM directly. The only real
compatibility issue is trying to obtain the conversion tables from
IBM.


4.1: JAPANESE

	In general, when a Japanese character set was revised,
characters were simply added (usually appended at the end). However,
when JIS C 6226-1978 was revised in 1983 (to become JIS X 0208-1983),
a bit more happened (this is still a controversy).
	A detailed treatment of the two main transitions, JIS C 6226-
1978 to JIS X 0208-1983 and JIS X 0208-1983 to JIS X 0208-1990, is
covered in Appendix J of UJIP. I provide machine-readable files that
detail these transitions at the following URL:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/AppJ/

	An interesting side note here is that there is a reason why
there are many lists that illustrate JIS C 6226-1978 and JIS X 0208-
1983 kanji form differences. While most share the same basic set of
changes, there are some inconsistencies. Well, it turns out that JIS C
6226-1978 had ten printings, and not all of them shared the same kanji
forms. If comparisons between JIS C 6226-1978 and JIS X 0208-1983 were
made using different printings of the JIS C 6226-1978 manual, the
results can differ slightly.
	There are also interesting correspondences between JIS X
0208-1990 and JIS X 0212-1990. 28 kanji that vanished during the JIS C
6226-1978 to JIS X 0208-1983 transition (they were replaced by
simplified versions) were restored in JIS X 0212-1990 (at totally
different code points). Appendix J of UJIP discusses this, and a file
at the following URL details the 28 mappings:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/AppJ/TJ2.jis


4.2: CHINESE (PRC)

	The basic PRC standard, GB 2312-80, has been revised, but not
through a later version of the standard. Instead, the revisions were
carried out in the form of three other documents. Specifically, they
are (in order of publication):

o GB 6345.1-86 (see Section 2.2.3)
o GB 8565.2-88 (see Section 2.2.6)
o GB/T 12345-90 (see Section 2.2.7)

Unless you are aware of these documents, figuring out what has been
corrected or added to GB 2312-80 is nearly impossible.


4.3: CHINESE (TAIWAN)

	The first question people think of with regard to Big Five and
CNS 11643-1992 is compatibility. It turns out that Planes 1 and 2 of
CNS 11643-1992 are more or less equivalent to Big Five, but a handful
of hanzi are in a different order. The following tables detail the
mapping from Big Five (with the ETen extension) to CNS 11643-1992
(when using this conversion table, keep in mind the encoding space
ranges for both Big Five and CNS 11643-1992):

Big Five Level 1 Correspondence to CNS 11643-1992 Plane 1:

  0xA140-0xA1F5 <-> 0x2121-0x2256
         0xA1F6 <-> 0x2258
         0xA1F7 <-> 0x2257
  0xA1F8-0xA2AE <-> 0x2259-0x234E
  0xA2AF-0xA3BF <-> 0x2421-0x2570
  0xA3C0-0xA3E0 <-> 0x4221-0x4241  # Symbols for control characters
  0xA440-0xACFD <-> 0x4421-0x5322  # Level 1 Hanzi BEGIN
         0xACFE <-> 0x5753
  0xAD40-0xAFCF <-> 0x5323-0x5752
  0xAFD0-0xBBC7 <-> 0x5754-0x6B4F
  0xBBC8-0xBE51 <-> 0x6B51-0x6F5B
         0xBE52 <-> 0x6B50
  0xBE53-0xC1AA <-> 0x6F5C-0x7534
  0xC1AB-0xC2CA <-> 0x7536-0x7736
         0xC2CB <-> 0x7535
  0xC2CC-0xC360 <-> 0x7737-0x782C
  0xC361-0xC3B8 <-> 0x782E-0x7863
         0xC3B9 <-> 0x7865
         0xC3BA <-> 0x7864
  0xC3BB-0xC455 <-> 0x7866-0x7961
         0xC456 <-> 0x782D
  0xC457-0xC67E <-> 0x7962-0x7D4B  # Level 1 Hanzi END
  0xC6A1-0xC6AA <-> 0x2621-0x262A  # Circled numerals
  0xC6AB-0xC6B4 <-> 0x262B-0x2634  # Parenthesized numerals
  0xC6B5-0xC6BE <-> 0x2635-0x263E  # Lowercase Roman numerals
  0xC6BF-0xC6C0 <-> 0x2723-0x2724  # 213 radicals BEGIN
  0xC6C1-0xC6C2 <-> 0x2726, 0x2728
  0xC6C3-0xC6C5 <-> 0x272D-0x272F
  0xC6C6-0xC6C7 <-> 0x2734, 0x2737
  0xC6C8-0xC6C9 <-> 0x273A, 0x273C
  0xC6CA-0xC6CB <-> 0x2742, 0x2747
  0xC6CC-0xC6CD <-> 0x274E, 0x2753
  0xC6CE-0xC6CF <-> 0x2754-0x2755
  0xC6D0-0xC6D1 <-> 0x2759-0x275A
  0xC6D2-0xC6D3 <-> 0x2761, 0x2766
  0xC6D4-0xC6D5 <-> 0x2829-0x282A
  0xC6D6-0xC6D7 <-> 0x2863, 0x286C # 213 radicals END
  0xC6D8-0xC6E6  -> ******         # Japanese symbols
  0xC6E7-0xC77A  -> ******         # Hiragana
  0xC77B-0xC7F2  -> ******         # Katakana
  0xC7F3-0xC875  -> ******         # Cyrillic alphabet
  0xC876-0xC878  -> ******         # Symbols
         0xC87A  -> ******         # Hanzi element
         0xC87C  -> ******         # Hanzi element
  0xC87E-0xC8A1  -> ******         # Hanzi elements
  0xC8A3-0xC8A4  -> ******         # Hanzi elements
  0xC8A5-0xC8CC  -> ******         # Combined numerals
  0xC8CD-0xC8D3  -> ******         # Japanese symbols

Big Five Level 1 Correspondences to CNS 11643-1992 Plane 4:

         0xC879 <-> 0x2123         # Hanzi element
         0xC87B <-> 0x2124         # Hanzi element
         0xC87D <-> 0x212A         # Hanzi element
         0xC8A2 <-> 0x2152         # Hanzi element

Big Five Level 2 Correspondence to CNS 11643-1992 Plane 1:

         0xC94A  -> 0x4442         # duplicate of 0xA461

Big Five Level 2 Correspondences to CNS 11643-1992 Plane 2:

  0xC940-0xC949 <-> 0x2121-0x212A  # Level 2 Hanzi BEGIN
  0xC94B-0xC96B <-> 0x212B-0x214B
  0xC96C-0xC9BD <-> 0x214D-0x217C
         0xC9BE <-> 0x214C
  0xC9BF-0xC9EC <-> 0x217D-0x224C
  0xC9ED-0xCAF6 <-> 0x224E-0x2438
         0xCAF7 <-> 0x224D
  0xCAF8-0xD6CB <-> 0x2439-0x376E
         0xD6CC <-> 0x3E63
  0xD6CD-0xD779 <-> 0x3770-0x387D
         0xD77A <-> 0x3F6A
  0xD77B-0xDADE <-> 0x387E-0x3E62
         0xDADF <-> 0x376F
  0xDAE0-0xDBA6 <-> 0x3E64-0x3F69
  0xDBA7-0xDDFB <-> 0x3F6B-0x4423
         0xDDFC  -> 0x4176         # duplicate of 0xDCD1
  0xDDFD-0xE8A2 <-> 0x4424-0x554A
  0xE8A3-0xE975 <-> 0x554C-0x5721
  0xE976-0xEB5A <-> 0x5723-0x5A27
  0xEB5B-0xEBF0 <-> 0x5A29-0x5B3E
         0xEBF1 <-> 0x554B
  0xEBF2-0xECDD <-> 0x5B3F-0x5C69
         0xECDE <-> 0x5722
  0xECDF-0xEDA9 <-> 0x5C6A-0x5D73
  0xEDAA-0xEEEA <-> 0x5D75-0x6038
         0xEEEB <-> 0x642F
  0xEEEC-0xF055 <-> 0x6039-0x6242
         0xF056 <-> 0x5D74
  0xF057-0xF0CA <-> 0x6243-0x6336
         0xF0CB <-> 0x5A28
  0xF0CC-0xF162 <-> 0x6337-0x642E
  0xF163-0xF16A <-> 0x6430-0x6437
         0xF16B <-> 0x6761
  0xF16C-0xF267 <-> 0x6438-0x6572
         0xF268 <-> 0x6934
  0xF269-0xF2C2 <-> 0x6573-0x664C
  0xF2C3-0xF374 <-> 0x664E-0x6760
  0xF375-0xF465 <-> 0x6762-0x6933
  0xF466-0xF4B4 <-> 0x6935-0x6961
         0xF4B5 <-> 0x664D
  0xF4B6-0xF4FC <-> 0x6962-0x6A4A
  0xF4FD-0xF662 <-> 0x6A4C-0x6C51
         0xF663 <-> 0x6A4B
  0xF664-0xF976 <-> 0x6C52-0x7165
  0xF977-0xF9C3 <-> 0x7167-0x7233
         0xF9C4 <-> 0x7166
         0xF9C5 <-> 0x7234
         0xF9C6 <-> 0x7240
  0xF9C7-0xF9D1 <-> 0x7235-0x723F
  0xF9D2-0xF9D5 <-> 0x7241-0x7244  # Level 2 Hanzi END
  0xF9DD-0xF9FE  -> ******         # Symbols

Big Five Level 2 Correspondence to CNS 11643-1992 Plane 3:

         0xF9D6 <-> 0x4337         # ETen-specific hanzi
         0xF9D7 <-> 0x4F50         # ETen-specific hanzi
         0xF9D8 <-> 0x444E         # ETen-specific hanzi
         0xF9D9 <-> 0x504A         # ETen-specific hanzi
         0xF9DA <-> 0x2C5D         # ETen-specific hanzi
         0xF9DB <-> 0x3D7E         # ETen-specific hanzi
         0xF9DC <-> 0x4B5C         # ETen-specific hanzi

I adapted the above from material Ross Paterson ([email protected])
kindly made available at the following URL:

  http://www.ifcss.org:8001/www/pub/software/info/cjk-codes/

Check it out. Basically, I just changed the CNS 11643-1992 codes from
decimal row-cell values to hexadecimal codes, and corrected the
mappings to correspond to ETen's Big Five (which is considered to be
the most standard).
	It turns out that corrections were made to Big Five (at least
in the ETen and Microsoft implementations thereof) which made it a bit
closer to CNS 11643-1992 as far as character ordering is concerned.
The following six lines of code correspondences:

  0xCAF8-0xD6CB <-> 0x2439-0x376E
         0xD6CC <-> 0x3E63
  0xD6CD-0xD779 <-> 0x3770-0x387D
         0xD77A <-> 0x3F6A
  0xD77B-0xDADE <-> 0x387E-0x3E62
         0xDADF <-> 0x376F

can now be expressed as the following three lines:

  0xCAF8-0xD779 <-> 0x2439-0x387D
         0xD77A <-> 0x3F6A
  0xD77B-0xDBA6 <-> 0x387E-0x3F69

In essence, the ordering of Big Five characters 0xD6CC and 0xDADF were
reversed. This resulted in the same order as found in CNS 11643-1992
Plane 2.
	As for the two duplicate hanzi in Big Five (as indicated in
the above tables), they have been placed into a compatibility zone in
ISO 10646-1:1993 (this allows for round-trip conversion). The mapping
is as follows:

  Big Five  ISO 10646-1:1993
  ^^^^^^^^  ^^^^^^^^^^^^^^^^
  0xC94A -> 0xFA0C
  0xDDFC -> 0xFA0D

	Speaking of duplicate hanzi, Plane 1 of CNS 11643-1992
contains 213 classical radicals in rows 27 through 29. However, 187 of
them map directly to hanzi code points in Planes 1, 2, and 3 (and
naturally to Big Five). Below is a detailed mapping of these 213
radicals:

  Radical   CNS 11643   Big Five    Radical   CNS 11643   Big Five
  ^^^^^^^   ^^^^^^^^^   ^^^^^^^^    ^^^^^^^   ^^^^^^^^^   ^^^^^^^^
  0x2721 -> 0x4421      0xA440      0x282E -> 0x4678      0xA5D8
  0x2722 -> 0x2121 (3)  ******      0x282F -> 0x4679      0xA5D9
  0x2723 -> 0x2122 (3)  0xC6BF      0x2830 -> 0x467A      0xA5DA
  0x2724 -> 0x2123 (3)	0xC6C0      0x2831 -> 0x467B      0xA5DB
  0x2725 -> 0x4422      0xA441      0x2832 -> 0x467C      0xA5DC
  0x2726 -> 0x2124 (3)	0xC6C1      0x2833 -> 0x2167 (2)  0xC9A8
  0x2727 -> 0x4428      0xA447      0x2834 -> 0x467D      0xA5DD
  0x2728 -> ******	0xC6C2      0x2835 -> 0x467E      0xA5DE
  0x2729 -> 0x4429      0xA448      0x2836 -> 0x4721      0xA5DF
  0x272A -> 0x442A      0xA449      0x2837 -> 0x484C      0xA6CB
  0x272B -> 0x442B      0xA44A      0x2838 -> 0x484D      0xA6CC
  0x272C -> 0x442C      0xA44B      0x2839 -> 0x484E      0xA6CD
  0x272D -> 0x2127 (3)	0xC6C3      0x283A -> 0x484F      0xA6CE
  0x272E -> 0x2128 (3)	0xC6C4      0x283B -> 0x2269 (2)  0xCA49
  0x272F -> ******	0xC6C5      0x283C -> 0x4850      0xA6CF
  0x2730 -> 0x442D      0xA44C      0x283D -> 0x4851      0xA6D0
  0x2731 -> 0x2123 (2)  0xC942      0x283E -> 0x4852      0xA6D1
  0x2732 -> 0x442E      0xA44D      0x283F -> 0x4854      0xA6D3
  0x2733 -> 0x4430      0xA44F      0x2840 -> 0x4855      0xA6D4
  0x2734 -> ******      0xC6C6      0x2841 -> 0x4856      0xA6D5
  0x2735 -> 0x4431      0xA450      0x2842 -> 0x4857      0xA6D6
  0x2736 -> 0x2124 (2)  0xC943      0x2843 -> 0x4858      0xA6D7
  0x2737 -> 0x2129 (3)  0xC6C7      0x2844 -> 0x485B      0xA6DA
  0x2738 -> 0x4432      0xA451      0x2845 -> 0x485C      0xA6DB
  0x2739 -> 0x4433      0xA452      0x2846 -> 0x485D      0xA6DC
  0x273A -> 0x212A (3)  0xC6C8      0x2847 -> 0x485E      0xA6DD
  0x273B -> 0x2125 (2)  0xC944      0x2848 -> 0x485F      0xA6DE
  0x273C -> 0x212B (3)  0xC6C9      0x2849 -> 0x4860      0xA6DF
  0x273D -> 0x4434      0xA453      0x284A -> 0x4861      0xA6E0
  0x273E -> 0x4447      0xA466      0x284B -> 0x4862      0xA6E1
  0x273F -> 0x212A (2)  0xC949      0x284C -> 0x4863      0xA6E2
  0x2740 -> 0x4448      0xA467      0x284D -> 0x226A (2)  0xCA4A
  0x2741 -> 0x4449      0xA468      0x284E -> 0x226F (2)  0xCA4F
  0x2742 -> 0x213A (3)  0xC6CA      0x284F -> 0x4865      0xA6E4
  0x2743 -> 0x444A      0xA469      0x2850 -> 0x4866      0xA6E5
  0x2744 -> 0x444B      0xA46A      0x2851 -> 0x4867      0xA6E6
  0x2745 -> 0x444C      0xA46B      0x2852 -> 0x4868      0xA6E7
  0x2746 -> 0x444D      0xA46C      0x2853 -> 0x2270 (2)  0xCA50
  0x2747 -> 0x213B (3)  0xC6CB      0x2854 -> 0x4B44      0xA8A3
  0x2748 -> 0x4450      0xA46F      0x2855 -> 0x4B45      0xA8A4
  0x2749 -> 0x4451      0xA470      0x2856 -> 0x4B46      0xA8A5
  0x274A -> 0x4452      0xA471      0x2857 -> 0x4B47      0xA8A6
  0x274B -> 0x4453      0xA472      0x2858 -> 0x4B48      0xA8A7
  0x274C -> 0x212B (2)  0xC94B      0x2859 -> 0x4B49      0xA8A8
  0x274D -> 0x4454      0xA473      0x285A -> 0x2524 (2)  0xCBA4
  0x274E -> 0x213C (3)  0xC6CC      0x285B -> 0x4B4A      0xA8A9
  0x274F -> 0x4456      0xA475      0x285C -> 0x4B4B      0xA8AA
  0x2750 -> 0x4457      0xA476      0x285D -> 0x4B4C      0xA8AB
  0x2751 -> 0x445A      0xA479      0x285E -> 0x4B4D      0xA8AC
  0x2752 -> 0x445B      0xA47A      0x285F -> 0x4B4E      0xA8AD
  0x2753 -> 0x213D (3)  0xC6CD      0x2860 -> 0x4B4F      0xA8AE
  0x2754 -> 0x213E (3)  0xC6CE      0x2861 -> 0x4B50      0xA8AF
  0x2755 -> 0x213F (3)  0xC6CF      0x2862 -> 0x4B51      0xA8B0
  0x2756 -> 0x445C      0xA47B      0x2863 -> 0x272F (3)  0xC6D6
  0x2757 -> 0x445D      0xA47C      0x2864 -> 0x4B57      0xA8B6
  0x2758 -> 0x445E      0xA47D      0x2865 -> 0x4B5C      0xA8BB
  0x2759 -> 0x2140 (3)  0xC6D0      0x2866 -> 0x4B5D      0xA8BC
  0x275A -> 0x2142 (3)  0xC6D1      0x2867 -> 0x4B5E      0xA8BD
  0x275B -> 0x212C (2)  0xC94C      0x2868 -> 0x4F5A      0xAAF7
  0x275C -> 0x4540      0xA4DF      0x2869 -> 0x4F5B      0xAAF8
  0x275D -> 0x4541      0xA4E0      0x286A -> 0x4F5C      0xAAF9
  0x275E -> 0x4542      0xA4E1      0x286B -> 0x4F5D      0xAAFA
  0x275F -> 0x4543      0xA4E2      0x286C -> 0x2A7D (3)  0xC6D7
  0x2760 -> 0x4545      0xA4E4      0x286D -> 0x4F63      0xAB41
  0x2761 -> 0x2167 (3)  0xC6D2      0x286E -> 0x4F64      0xAB42
  0x2762 -> 0x4546      0xA4E5      0x286F -> 0x4F65      0xAB43
  0x2763 -> 0x4547      0xA4E6      0x2870 -> 0x4F66      0xAB44
  0x2764 -> 0x4548      0xA4E7      0x2871 -> 0x5372      0xADB1
  0x2765 -> 0x4549      0xA4E8      0x2872 -> 0x5373      0xADB2
  0x2766 -> 0x2169 (3)  0xC6D3      0x2873 -> 0x5374      0xADB3
  0x2767 -> 0x454A      0xA4E9      0x2874 -> 0x5375      0xADB4
  0x2768 -> 0x454B      0xA4EA      0x2875 -> 0x5376      0xADB5
  0x2769 -> 0x454C      0xA4EB      0x2876 -> 0x5377      0xADB6
  0x276A -> 0x454D      0xA4EC      0x2877 -> 0x5378      0xADB7
  0x276B -> 0x454E      0xA4ED      0x2878 -> 0x5379      0xADB8
  0x276C -> 0x454F      0xA4EE      0x2879 -> 0x537A      0xADB9
  0x276D -> 0x4550      0xA4EF      0x287A -> 0x537B      0xADBA
  0x276E -> 0x213F (2)  0xC95F      0x287B -> 0x537C      0xADBB
  0x276F -> 0x4551      0xA4F0      0x287C -> 0x586B      0xB0A8
  0x2770 -> 0x4552      0xA4F1      0x287D -> 0x586C      0xB0A9
  0x2771 -> 0x4553      0xA4F2      0x287E -> 0x586D      0xB0AA
  0x2772 -> 0x4554      0xA4F3      0x2921 -> 0x334C (2)  0xD449
  0x2773 -> 0x2141 (2)  0xC961      0x2922 -> 0x586E      0xB0AB
  0x2774 -> 0x4555      0xA4F4      0x2923 -> 0x334D (2)  0xD44A
  0x2775 -> 0x4556      0xA4F5      0x2924 -> 0x586F      0xB0AC
  0x2776 -> 0x4557      0xA4F6      0x2925 -> 0x5870      0xB0AD
  0x2777 -> 0x4558      0xA4F7      0x2926 -> 0x5E23      0xB3BD
  0x2778 -> 0x4559      0xA4F8      0x2927 -> 0x5E24      0xB3BE
  0x2779 -> 0x2142 (2)  0xC962      0x2928 -> 0x5E25      0xB3BF
  0x277A -> 0x455A      0xA4F9      0x2929 -> 0x5E26      0xB3C0
  0x277B -> 0x455B      0xA4FA      0x292A -> 0x5E27      0xB3C1
  0x277C -> 0x455C      0xA4FB      0x292B -> 0x5E28      0xB3C2
  0x277D -> 0x455D      0xA4FC      0x292C -> 0x6327      0xB6C0
  0x277E -> 0x4668      0xA5C8      0x292D -> 0x6328      0xB6C1
  0x2821 -> 0x4669      0xA5C9      0x292E -> 0x6329      0xB6C2
  0x2822 -> 0x466A      0xA5CA      0x292F -> 0x4155 (2)  0xDCB0
  0x2823 -> 0x466B      0xA5CB      0x2930 -> 0x4875 (2)  0xE0EF
  0x2824 -> 0x466C      0xA5CC      0x2931 -> 0x676F      0xB9A9
  0x2825 -> 0x466D      0xA5CD      0x2932 -> 0x6770      0xB9AA
  0x2826 -> 0x466E      0xA5CE      0x2933 -> 0x6771      0xB9AB
  0x2827 -> 0x4670      0xA5D0      0x2934 -> 0x6B7C      0xBBF3
  0x2828 -> 0x4674      0xA5D4      0x2935 -> 0x6B7D      0xBBF4
  0x2829 -> 0x225B (3)  0xC6D4      0x2936 -> 0x702F      0xBEA6
  0x282A -> 0x225C (3)  0xC6D5      0x2937 -> 0x733E      0xC073
  0x282B -> 0x4675      0xA5D5      0x2938 -> 0x733F      0xC074
  0x282C -> 0x4676      0xA5D6      0x2939 -> 0x6142 (2)  0xEFB6
  0x282D -> 0x4677      0xA5D7


4.4: KOREAN

	The 268 duplicate hanja in KS C 5601-1992 can cause problems
when converting to and from other CJK character sets. When converting
from KS C 5601-1992, two or more hanja can collapse into a single code
point. When converting these 268 hanja to KS C 5601-1992, a decision
about which KS C 5601-1992 code point to map to must be made. The only
exception to this is mapping to and from ISO 10646-1:1993. That
standard encodes these 268 duplicate hanja in a compatibility zone,
namely from 0xF900 through 0xFA0B.
	The following is a listing of 262 hanja that map to two or
more code points (four map to three code points, and one maps to four:
a total of 268 redundantly-encoded hanja) in KS C 5601-1992:

  Standard  Extra     Standard  Extra     Standard  Extra
  ^^^^^^^^  ^^^^^     ^^^^^^^^  ^^^^^     ^^^^^^^^  ^^^^^
  0x4A39 -> 0x4D4F    0x5573 -> 0x6631    0x573C -> 0x6B29
  0x4B3D -> 0x7A22    0x5574 -> 0x6633    0x573E -> 0x6B3A
  0x4C38 -> 0x7A66    0x5575 -> 0x6637    0x573F -> 0x6B3B
  0x4C5A -> 0x4B56    0x5576 -> 0x6638    0x5740 -> 0x6B3D
  0x4C78 -> 0x5050    0x5579 -> 0x663C    0x5741 -> 0x6B41
  0x4D7A -> 0x4E2D    0x557B -> 0x6646    0x5743 -> 0x6B42
  0x4E29 -> 0x7C29    0x557C -> 0x6647    0x5744 -> 0x6B46
  0x4F23 -> 0x4F7B    0x557E -> 0x6652    0x5745 -> 0x6B47
  0x4F4F -> 0x5022    0x5621 -> 0x6656    0x5747 -> 0x6B4C
            0x5038    0x5622 -> 0x6659    0x5748 -> 0x6B4F
  0x5142 -> 0x4B50    0x5623 -> 0x665F    0x5749 -> 0x6B50
  0x5151 -> 0x505D    0x5624 -> 0x6661    0x574A -> 0x6B51
  0x5159 -> 0x547C    0x5625 -> 0x6665    0x574C -> 0x6B58
  0x5167 -> 0x552B    0x5626 -> 0x6664    0x574D -> 0x5270
  0x522F -> 0x5155    0x5627 -> 0x6666    0x574E -> 0x5271
  0x5233 -> 0x657C    0x5628 -> 0x6668    0x574F -> 0x5272
  0x5234 -> 0x6644    0x562A -> 0x666A    0x5750 -> 0x5273
  0x5235 -> 0x664A    0x562B -> 0x666B    0x5752 -> 0x5274
  0x5236 -> 0x665C    0x562D -> 0x666F    0x5753 -> 0x5275
  0x5237 -> 0x6676    0x562E -> 0x6671    0x5754 -> 0x5277
  0x523A -> 0x6677    0x562F -> 0x6675    0x5755 -> 0x5278
  0x523B -> 0x5638    0x5631 -> 0x6679    0x5757 -> 0x6C26
            0x672C    0x5633 -> 0x6721    0x5759 -> 0x6C27
  0x5241 -> 0x564D    0x5634 -> 0x6726    0x575B -> 0x6C2A
  0x5263 -> 0x6871    0x5635 -> 0x6729    0x575D -> 0x6C30
  0x526E -> 0x6A74    0x5637 -> 0x672A    0x575E -> 0x6C31
  0x526F -> 0x6B2A    0x563A -> 0x672D    0x5762 -> 0x6C35
  0x527A -> 0x6C32    0x563B -> 0x6730    0x5765 -> 0x6C38
  0x527B -> 0x6C49    0x563C -> 0x673F    0x5767 -> 0x6C3A
  0x527C -> 0x6C4A    0x563E -> 0x6746    0x576A -> 0x6C40
  0x527E -> 0x7331    0x5640 -> 0x6747    0x576B -> 0x6C41
  0x5321 -> 0x552E    0x5642 -> 0x674B    0x576C -> 0x6C45
  0x5358 -> 0x7738    0x5643 -> 0x674D    0x576E -> 0x6C46
  0x536B -> 0x7748    0x5644 -> 0x674F    0x5770 -> 0x6C55
  0x5378 -> 0x7674    0x5645 -> 0x6750    0x5772 -> 0x6C5D
  0x5441 -> 0x5466    0x5647 -> 0x6753    0x5773 -> 0x6C5E
  0x5457 -> 0x7753    0x5649 -> 0x675F    0x5774 -> 0x6C61
  0x547A -> 0x5154    0x564A -> 0x6764    0x5776 -> 0x6C64
  0x547B -> 0x5158    0x564B -> 0x6766    0x5777 -> 0x6C67
  0x547D -> 0x515B    0x564C -> 0x523E    0x5778 -> 0x6C68
  0x547E -> 0x515C    0x564F -> 0x5242    0x5779 -> 0x6C77
  0x5521 -> 0x515D    0x5650 -> 0x5243    0x577A -> 0x6C78
  0x5522 -> 0x515E    0x5653 -> 0x5244    0x577C -> 0x6C7A
  0x5523 -> 0x515F    0x5654 -> 0x5246    0x5821 -> 0x6D21
  0x5524 -> 0x5160    0x5655 -> 0x5247    0x5822 -> 0x6D22
  0x5526 -> 0x5163    0x5656 -> 0x5248    0x5823 -> 0x6D23
  0x5527 -> 0x5164    0x5657 -> 0x5249    0x5A72 -> 0x5B64
  0x5528 -> 0x5165    0x5658 -> 0x524A    0x5C56 -> 0x5D25
  0x552A -> 0x5166    0x565A -> 0x524B    0x5C5F -> 0x7870
  0x552C -> 0x5168    0x565B -> 0x524D    0x5C74 -> 0x5D55
  0x552D -> 0x5169    0x565C -> 0x524E    0x5D41 -> 0x5B45
  0x552F -> 0x516A    0x565E -> 0x524F    0x5F2F -> 0x616D
  0x5530 -> 0x516B    0x565F -> 0x5250    0x5F52 -> 0x6D6E
  0x5531 -> 0x516D    0x5660 -> 0x5251    0x5F5D -> 0x5F61
  0x5534 -> 0x516F    0x5661 -> 0x5252    0x5F63 -> 0x5E7E
  0x5535 -> 0x5170    0x5662 -> 0x5253    0x6063 -> 0x612D
  0x5536 -> 0x5172    0x5663 -> 0x5254              0x6672
  0x5539 -> 0x5176    0x5665 -> 0x5255    0x607D -> 0x5F68
  0x553D -> 0x517A    0x5666 -> 0x5256    0x6163 -> 0x574B
  0x5540 -> 0x517C    0x5667 -> 0x5257              0x6B52
  0x5541 -> 0x517D    0x566B -> 0x5259    0x6226 -> 0x5E7C
  0x5543 -> 0x517E    0x566C -> 0x525A    0x6326 -> 0x6429
  0x5544 -> 0x5222    0x566F -> 0x525E    0x635B -> 0x723D
  0x5545 -> 0x5223    0x5670 -> 0x525F    0x6427 -> 0x727A
  0x5546 -> 0x5227    0x5671 -> 0x5261    0x6442 -> 0x6777
  0x5547 -> 0x5228    0x5674 -> 0x5262    0x6445 -> 0x5162
  0x5548 -> 0x5229    0x5675 -> 0x6867              0x5525
  0x5549 -> 0x522A    0x5676 -> 0x6868              0x6879
  0x554D -> 0x522B    0x5677 -> 0x6870    0x6534 -> 0x652E
  0x554E -> 0x522D    0x5679 -> 0x6877    0x6636 -> 0x6C2F
  0x5552 -> 0x5232    0x567A -> 0x687B    0x6728 -> 0x6071
  0x5553 -> 0x6531    0x567B -> 0x687E    0x6856 -> 0x6A41
  0x5554 -> 0x6532    0x567E -> 0x6927    0x6C36 -> 0x5764
  0x5555 -> 0x6539    0x5721 -> 0x692C    0x6C56 -> 0x666C
  0x5557 -> 0x653B    0x5723 -> 0x694C    0x6D29 -> 0x7427
  0x5558 -> 0x653C    0x5724 -> 0x5264    0x6D33 -> 0x6E5B
  0x5559 -> 0x6544    0x5726 -> 0x5265    0x6F37 -> 0x746E
  0x555D -> 0x654E    0x5727 -> 0x5266    0x7263 -> 0x6375
  0x555E -> 0x6550    0x5728 -> 0x5267    0x7333 -> 0x4B67
  0x555F -> 0x6552    0x5729 -> 0x5268    0x7351 -> 0x5F33
  0x5561 -> 0x6556    0x572B -> 0x5269    0x742C -> 0x7676
  0x5564 -> 0x657A    0x572C -> 0x526A    0x7658 -> 0x6421
  0x5565 -> 0x657B    0x5730 -> 0x526B    0x7835 -> 0x5C25
  0x5566 -> 0x657E    0x5731 -> 0x6A65    0x786C -> 0x785B
  0x5569 -> 0x6621    0x5733 -> 0x6A77    0x7932 -> 0x5D74
  0x556B -> 0x6624    0x5735 -> 0x6A7C    0x7A3C -> 0x7A21
  0x556C -> 0x6627    0x5736 -> 0x6A7E    0x7B29 -> 0x6741
  0x556F -> 0x662D    0x5738 -> 0x6B24    0x7C41 -> 0x4D68
  0x5571 -> 0x662F    0x573A -> 0x6B27    0x7D3B -> 0x6977
  0x5572 -> 0x6630

The above table represents a weekend of my time (but time well spent,
in my opinion).


4.5: ISO 10646-1:1993

	The Chinese character subset of ISO 10646-1:1993
has excellent round-trip conversion capability with the various
national character sets. Those national character sets with duplicate
characters, such as KS C 5601-1992 (268 hanja) and Big Five (2 hanzi),
have corresponding code points in ISO 10646-1:1993 within
a compatibility zone. See Sections 4.3 and 4.4 for more details.
	Other issues regarding ISO 10646-1:1993 have to do with proper
character rendering (that is, how characters are displayed, printed,
or otherwise imaged). Many (sometimes) subtle character form
differences have been collapsed under ISO 10646-1:1993. Language or
locale was not one of the factors used in performing Han Unification.
This means that it is nearly impossible to create a single ISO 10646-1:
1993 font that meets the character form criteria of each of the four
CJK locales. An ISO 10646-1:1993 code point is not enough information
to render a Chinese character. If the font was specifically designed
for a single locale, it is a non-problem, but if there is any CJK
intent, text must be flagged for language or locale.


4.6: UNICODE

	One of the most interesting (and major) differences between
the current three flavors of Unicode are the number and arrangement of
pre-combined hangul. The following table provides a summary of the
differences:

  Unicode       Number of Pre-combined Hangul   UCS-2 Ranges
  ^^^^^^^       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^
  Version 1.0   2,350 Basic Hangul              0x3400-0x3D3D

  Version 1.1   2,350 Basic Hangul              0x3400-0x3D3D
                1,930 Supplemental Hangul A     0x3D2E-0x44B7
                2,376 Supplemental Hangul B     0x44BE-0x4DFF

  Version 2.0  11,172 Hangul                    0xAC00-0xD7A3

Of the above three versions, the most controversial is Version 2.0.
Why? Because it is located in the user-defined range of Unicode
(O-Zone: 16,384 code points in 0xA000-0xDFFF), and occupies
approximately two-thirds of its space.
	The information in the above table is courtesy of the
following useful document:

  ftp://unicode.org/pub/MappingTables/EastAsiaMaps/Hangul-Codes.txt

The same file is also mirrored at the following URL:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/hangul-codes.txt


4.7: CODE CONVERSION TIPS

	There are two types of conversions that can be performed. The
first type is converting between different encodings for the same
character set. This is usually without problems (but not always). The
second type is converting from one character set to another (it is not
usually relevant whether the underlying encoding has changed or not).
This usually involves the handling of characters that are in one
character set, but not the other. So, what to do?
	I suggest JConv for handling Japanese code conversion (this
means converting between JIS, Shift-JIS, and EUC encodings). This is
in the category of different encodings for the same character set. The
following URLs provide executables or source code:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/mac/jconv-30.hqx
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/mac/jconv-dd-181.hqx
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/dos/jconv.exe
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/src/jconv.c

There are other programs available that do the same basic thing as
JConv, such as kc and nkf. They are available at the following URL:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/unix/

	For software and tables that handles Chinese code conversion
(this includes conversion to and from Japanese), I suggest browsing at
the following URLs:

  ftp://etlport.etl.go.jp/pub/iso-2022-cn/convert/
  ftp://ftp.ifcss.org/pub/software/dos/convert/
  ftp://ftp.ifcss.org/pub/software/mac/convert/
  ftp://ftp.ifcss.org/pub/software/ms-win/convert/
  ftp://ftp.ifcss.org/pub/software/unix/convert/
  ftp://ftp.ifcss.org/pub/software/vms/convert/
  ftp://ftp.net.tsinghua.edu.cn/pub/Chinese/convert/
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/
  ftp://ftp.seed.net.tw/Pub/Chinese/DOS/code-convert/
  http://www.yajima.kuis.kyoto-u.ac.jp/staffs/yasuoka/CJK.html

The latter URL has FTP links to tables created by Koichi Yasuoka
([email protected]).
	The following URLs provide utilities or tables for converting
between various Korean encodings (the last represent the same file):

  ftp://cair-archive.kaist.ac.kr/pub/hangul/code/
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/non-hangul-codes.txt
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/hangul-codes.txt
  ftp://unicode.org/pub/MappingTables/EastAsiaMaps/Hangul-Codes.txt

A popular Korean code conversion utility seems to be "hcode" by
June-Yub Lee ([email protected]).
	Finally, the following URLs provide many Unicode- and CJK-
related mapping tables:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/unicode/
  ftp://unicode.org/pub/MappingTables/
  http://www.yajima.kuis.kyoto-u.ac.jp/staffs/yasuoka/CJK.html

Note that the official and authoritative Unicode mapping tables (from
Unicode values to various international, national and vendor
standards) are maintained by the Unicode Consortium at the following
URL:

  ftp://unicode.org/pub/MappingTables/

Version 2.0 of "The Unicode Standard" (to be published by Addison-
Wesley shortly) will include these mapping tables on CD-ROM.


PART 5: CJK-CAPABLE OPERATING SYSTEMS

	The first step in being able to display CJK text is to obtain
an operating system that handles such text (or an application that
sets up its own CJK-capable environment). Below I describe how
different types of machines can handle CJK text.
	Actually, for the first few releases of CJK.INF, these
subsections will be far from complete (some may even be empty!). The
purpose of CJK.INF is to provide detailed information on character set
standards and encoding systems, so I therefore consider this sort of
information secondary.


5.1: MS-DOS

	I am not aware of any CJK-capable MS-DOS operating system, but
localized versions do exist. CJK support has been introduced with
Microsoft's Windows operating system (see Section 5.2).


5.2: WINDOWS

	Microsoft has CJK versions of its Windows operating system
available. The latest versions of their Windows operating system are
called Windows 95 and Windows NT. Windows 95 supports the same
character sets and encodings as in Windows Version 3.1 -- Windows NT
supports Unicode (ISO 10646-1:1993). Contact Microsoft Corporation for
more details. The URL of their WWW Home Page is:

  http://www.microsoft.com/

Nadine Kano's "Developing International Software for Windows 95 and
Windows NT" provides abundant reference material for how CJK is
supported in Windows 95 and Windows NT. Check it out.
	TwinBridge is a package that adds CJK functionality to non-CJK
Windows. Demo versions of TwinBridge for Japanese and Chinese are at
the following URLs:

  ftp://ftp.netcom.com/pub/tw/twinbrg/Japanese/demo/tbjdemo.zip
  ftp://ftp.netcom.com/pub/tw/twinbrg/Chinese/demo/tbcdemo.zip

	Another useful CJK add-on for Windows 95 is NJWIN (see Section
7.10) by Hongbo Data Systems.


5.3: MACINTOSH

	Macintosh is well-known as a computer that was designed to
handle multilingual texts. There are currently fully-localized
operating systems available for Japanese (KanjiTalk), Chinese
(simplified and traditional available), and Korean (HangulTalk). In
addition, Apple has developed "Language Kits" (*LK) for Chinese (CLK)
and Japanese (JLK). A Korean Language Kit (KLK) will be released
shortly.
	These localized operating systems can usually be installed
together in order to make your system CJK-capable.
	The common portion of these CJK-capable operating systems is a
technology Apple calls "WorldScript II" ("WorldScript I" is for one-
byte scripts). It provides the basic one- and two-byte functionality.


5.4: UNIX AND X WINDOWS

	The typical encoding system used on UNIX and X Windows is EUC
(see Section 3.2). Many systems, such as IBM's AIX, can be configured
to handle both EUC and Shift-JIS (for Japanese). In addition, X11R6 (X
Window System, Version 11, Release 6) has many CJK-capable features.
	If you have a fast PC and a good amount of RAM (more than
4MB), you should consider replacing MS-DOS (and Microsoft Windows,
too, if you have it) with Linux, which is a full-blown UNIX operating
system that runs on Intel processors. You can even run X Windows
(X11R6). "Running Linux" by Matt Welsh and Lar Kaufman is an excellent
guide to installing and using Linux. The companion volume, "Linux
Network Administrator's Guide" by Olaf Kirch is also useful. Because
there is a fine line -- or no line at all -- between a user and System
Administrator when using Linux, "Essential System Administration"
Second Edition by AEleen Frisch is a must-have.
	Linux and Linux information are available at the following
URLs:

  ftp://sunsite.unc.edu/pub/Linux/
  http://sunsite.unc.edu/mdw/linux.html

I personally use Linux, and find it quite useful and powerful. My bias
comes from being a UNIX user. But, you can't beat the price (free),
and all of my favorite text-manipulation tools (such as Perl) are
readily available.


5.5: OTHERS

	No information yet.


PART 6: CJK TEXT AND INTERNET SERVICES

	Part 5 described how CJK text is handled on a machine
internally, but this part goes into the implications of handling such
text externally, namely for information interchange purposes. This
boils down to handling CJK text on Internet services.
	For more detailed information on how these and other Internet
services are used, I suggest "The Whole Internet User's Guide &
Catalog" by Ed Krol. For more information on setting up and
maintaining these and other Internet services, I suggest "Managing
Internet Information Services" by Cricket Liu et al.


6.1: ELECTRONIC MAIL

	The most basic Internet service is electronic mail (henceforth
to be called "e-mail"), which is virtually guaranteed to be available
to all users regardless of their system.
	Several Internet standards (called RFCs, short for Request For
Comments) have been developed to describe how CJK text is to be handled
over e-mail systems (see Section A.3.4).
	The bottom-line is that most e-mail systems do not support
8-bit characters (that is, bytes that have their 8th bit set). Some do
offer 8-bit support, but you can never know what path your e-mail
might take while on route to its recipient. This means that 7-bit ISO
2022 (or equivalent) is the ideal encoding to use when sending CJK
text through e-mail. If your operating system processes another
encoding system, you must convert from that encoding to one that is
compatible with 7-bit ISO 2022.
	However, even 7-bit ISO 2022 encoding can get mangled by
mail-routing software -- the escape character, sometimes even part of
the escape sequence (meaning more than just the escape character), is
stripped. The JConv tool described in Section 4.7 restores stripped
escape sequences for Japanese 7-bit ISO 2022.
	If your mailing software is MIME-compliant, there is a means
to identify the character set and encoding of the message using the
"charset" parameter. Some valid "charset" values include the
following:

o iso-2022-jp     (see Section 3.1.3)
o iso-2022-jp-2   (see Section 3.1.3)
o iso-2022-kr     (see Section 3.1.4)
o iso-2022-cn     (see Section 3.1.5)
o iso-2022-cn-ext (see Section 3.1.5)
o iso-8859-1

Insertion of these values should happen automatically.
	A last-ditch effort to send CJK text through e-mail is to use
uuencode or Base64 encoding (see Section 3.3.13). Base64 is something
that is usually done automatically by mailing software -- explicit
Base64 encoding is not common. The recipient must then run uudecode or
a Base64 decoder to get the original file (if such utilities are
available).


6.2: USENET NEWS

	Usenet News follows many of the same requirements as e-mail,
namely that 7-bit ISO 2022 encoding is ideal. However, some newsgroups
use specific encoding methods, such as:

  alt.chinese.text             (HZ encoding used for Chinese text)
  alt.chinese.text.big5        (Big Five encoding used for Chinese text)
  chinese.flame                (UTF-7)
  chinese.text.unicode         (UTF-8)

Also, the newsgroups in Korean (all begin with "han.*") use EUC (EUC-
KR) because the news-handling software in Korea has been designed to
handle eight-bit characters correctly. Mailing list versions of Korean
newsgroups are likely to use ISO-2022-KR encoding.
	One common problem with Usenet News is that the escape
characters used in 7-bit ISO 2022 encoding are sometimes stripped,
usually by the software used to post the article. This can be quite
annoying. There are programs available, such as JConv, that repair
such files by restoring the escape characters.
	Another common problem are news readers that do not allow
escape characters to function. One simple solution is to "pipe" the
article through a display command, such as "more," "page," "less," or
"cat." This is done by typing a "pipe" character (|) followed by the
command name anywhere within the article being displayed.


6.3: GOPHER

	The World-Wide Web (WWW) has almost eliminated the need for
using Gopher, so I won't discuss it here. Not that I don't appreciate
Gopher servers, but what I mean is that WWW browsing software permits
access to Gopher sites.


6.4: WORLD-WIDE WEB

	First, there are two types of WWW browsers available. The most
common type is the graphics-based browser (examples include Mosaic and
Netscape). Graphics-based browsers have the unfortunate requirement of
a TCP/IP (SLIP and PPP support these protocols) connection. Lynx and
the W3 client for Emacs, which are text-based browsers, can be run
from the host computer through a standard terminal connection. They
don't display all the pretty pictures that folks put into their WWW
documents, but you get all the text (this is, in many ways, a blessing
in disguise -- transferring graphics is what slows down graphics-based
browsers the most). When the W3 client is run using Mule, it becomes a
fully CJK-capable WWW browser. Both Lynx and the W3 client for Emacs
are freely available. A Japanese-capable Lynx is available at the
following URL:

  ftp://ftp.ipc.chiba-u.ac.jp/pub.asada/www/lynx/

There is also a WWW page that provides information on Japanese-capable
Lynx. Its URL is as follows:

  http://www.icsd6.tj.chiba-u.ac.jp/lynx/

	When WWW documents first came online, there was no method for
handling CJK character sets. This has, fortunately, changed. As of
this writing, two commercial WWW browsers support Japanese. They are
Infomosaic by Fujitsu Limited, and Netscape Navigator by Netscape
Communications Corporation (Version 1.1 added Japanese support). Both
are graphics-based browsers. The former can be ordered at the
following URL:

  http://www.fujitsu.co.jp/

The latter can be found at the following URLs:

  http://www.netscape.com/
  ftp://ftp.netscape.com/

	One can also use a delegate server to *filter* Japanese codes
to the one supported by your browser. It is also possible to
"Japanize" existing WWW browsers using assorted tools and patches.
Katsuhiko Momoi ([email protected]) has authored an
excellent guide to Japanizing WWW browsers. Its URL is:

  http://condor.stcloud.msus.edu:20020/netscape.html

I *highly* suggest reading it.
	Japanese-capable WWW browsers support automatic detection of
the three Japanese encoding methods (JIS, Shift-JIS, and EUC). Hey,
but, what about support for the "C" and "K" of CJK? Attempting to
answer this question provides us an answer to another question: "What
is the best encoding method to use for CJK WWW documents?"
	Encoding methods such as EUC and Shift-JIS provide for mixing
only two character sets. This is because they provide no way to *flag*
or *tag* text for locale (character set) information. Without flagging
information, it is impossible to distinguish Japanese EUC from Chinese
or Korean EUC. However, the escape sequences used in 7-bit ISO 2022
encoding explicitly provide locale information. 7-bit ISO 2022 is
ideal for static documents, which is exactly what one finds on WWW.
	My personal recommendation (for the short-term) is to compose
WWW documents (also called HTML documents; HTML stands for Hyper Text
Markup Language) using 7-bit ISO 2022 encoding. The escape sequences
themselves act as explicit flags that indicate locale. However, some
WWW clients are confused by 7-bit ISO 2022 encoding, but the products
by Netscape Communications and Fujitsu Limited prove that this can
work. See the following URL for a description of this problem:

  http://www.ntt.jp/japan/note-on-JP/LibWWW-patch.html

	Check out the following URLs for information on and proposals
for international support for WWW:

  http://www.ebt.com:8080/docs/multilingual-www.html
  http://www.w3.org/hypertext/WWW/International/Overview/

	There is currently an RFC in the works (called an Internet
Draft) to address the problem of internationalizing HTML by using
Unicode. It is very promising. The latest draft is available at the
following URLs:

  ftp://ds.internic.net/internet-drafts/draft-ietf-html-i18n-04.txt.Z
  ftp://ftp.isi.edu/internet-drafts/draft-ietf-html-i18n-04.txt
  ftp://munnari.oz.au/internet-drafts/draft-ietf-html-i18n-04.txt.Z
  ftp://nic.nordu.net/internet-drafts/draft-ietf-html-i18n-04.txt

Note that some have been compressed.


6.5: FILE TRANSFER TIPS

	Although CJK encoding systems such as Shift-JIS and EUC make
extensive use of 8-bit bytes, that does not mean that you need to
treat the data as binary. Such files are simply to be treated as text,
and should be transferred in text mode (for example, FTP's ASCII mode,
which is also called "Type A Transfer").
	When text files are transferred in binary mode (such as FTP's
BINARY mode, which is also called Type I Transfer"), line termination
characters are left unaltered. For example, when transferring a text
file from UNIX to Macintosh, a text transfer will translate the UNIX
newline (0x0A) characters to Macintosh carriage return (0x0D)
characters, but a binary transfer will make no such modifications.
Text-style conversion is typically desired.
	The most common types of files that need to be handled as
binary include tar archives (*.tar), compressed files (*.Z, *.gz,
*.zip, *.zoo, *.lzh, and so on), and executables (*.exe, *.bin, and so
on).


PART 7: CJK TEXT HANDLING SOFTWARE

	This section describes various CJK-capable software packages.
I expect this section to grow with future versions of this document. I
define "CJK-capable" as being able to support Chinese, Japanese, and
Korean text.
	The descriptions I provide below are intentionally short. You
are encouraged to use the information pointers to obtain further
information or the software itself.


7.1: MULE

	Mule (multilingual enhancement to GNU Emacs), written by
Kenichi Handa ([email protected]), is the first (and only?) CJK-capable
editor for UNIX systems, and is freely available under the terms of
the GNU General Public License. Mule was developed from Nemacs
(Nihongo Emacs).
	Mule is available at the following URL:

  ftp://etlport.etl.go.jp/pub/mule/

	Mule, beginning with Version 2.2, includes handy utilities
(any2ps and m2ps) for printing files in any of the encodings supported
by Mule (which is a lot of encodings, by the way). These programs use
BDF fonts. See the beginning of Part 2 for a list of URLs that have
CJK BDF fonts.
	GNU Emacs is a fine editor, and Mule takes it several steps
further by providing multilingual support. I personally use Mule
together with SKK (for Japanese input) -- it is a superb combination.


7.2: CNPRINT

	CNPRINT, developed by Yidao Cai ([email protected]), is a
utility to print CJK text (or convert it to a PostScript file), and is
available for MS-DOS, VMS, and UNIX systems. A wide range of encoding
methods are supported by CNPRINT.
	CNPRINT is available at the following URLs:

  ftp://ftp.ifcss.org/pub/software/{dos,unix,vms}/print/
  ftp://neurophys.wisc.edu/[public.cn]/


7.3: MASS

	MASS (Multilingual Application Support Service), developed at
the National University of Singapore, is a suite of software tools
that speed and ease the development of UNIX-based CJK (actually, more
than just CJK) applications. It supports a wide variety of character
sets and encodings, including ISO 10646-1:1993 (UCS-2, UTF-7, and
UTF-8), EACC, and CCCII.
	More information on MASS, to include contact information for
its developers, can be found at the following URL:

  http://www.iss.nus.sg/RND/MLP/Projects/MASS/MASS.html


7.4: ADOBE TYPE MANAGER (ATM)

	Adobe Type Manager for Macintosh, beginning with Version 3.8,
is CJK-capable (as long as the underlying operating system is CJK-
capable). Actually, ATM generically supports CID-keyed fonts, which
are based on a newly-developed file specification for fonts with large
numbers of characters (like CJK fonts). See Section 7.9 for more
details.
	ATM is very easy to obtain. It is bundled with fonts and
applications from Adobe Systems (chances are you have ATM if you
recently purchased an Adobe product). But what about Windows? The
Windows version of ATM should soon follow with identical
functionality.


7.5: MACINTOSH SOFTWARE

	WorldScript II, a System Extension introduced with System 7,
provides multi-byte script handling, namely CJK support. If a
Macintosh product claims to support WorldScript II, chances are it is
CJK-capable (provided that your operating system has the necessary
extensions loaded).
	The CJK encodings that are supported by WorldScript II capable
applications are the same as made available by the underlying
Macintosh operating system. No import/export of other encodings is
supported at the operating system level. You must run separate
conversion utilities for both import and export. Anyway, below are
some products that are known to be CJK capable.
	Nisus Writer, written by Nisus Software, is fully CJK-capable
as long as you have the appropriate scripts installed (such as CLK for
Chinese or JLK for Japanese). A "Language Key" (read "dongle") is also
required for Chinese and Korean (and some one-byte scripts such as
Arabic and Hebrew). A demo version of Nisus Writer is available at the
following URL:

  ftp://ftp.nisus-soft.com/pub/nisus/demos/

Give it a try! Updates are also available at the same FTP site. Nisus
Software can be contacted using the following e-mail address or
through their WWW page:

  [email protected]
  http://www.nisus-soft.com/

I also suggest reading "The Nisus Way" by Joe Kissell. Chapter 13
provides detailed information about using Nisus Writer with
WorldScript, and includes a CD-ROM containing among other things a
trial (expires after 90 days) version of Nisus Writer and a
non-expiring version of Nisus Compact.
	ClarisWorks by Claris Corporation, beginning with Version 4.0,
is compatible with WorldScript II and all Apple language kits. This
translates into full CJK support. The following URL provides a trial
version of ClarisWorks:

  ftp://ftp.claris.com/pub/USA-Macintosh/Trial_Software/

The following URL has detailed information on this and other Claris
products:

  http://www.claris.com/

	The latest version of WordPerfect by Novell Incorporated is
also compatible with WorldScript II. The following URL has detailed
information:

  http://wp.novell.com/tree.htm


7.6: MACBLUE TELNET

	Although MacBlue Telnet (a modified version of NCSA Telnet) is
Macintosh software, I describe it separately because it does not
require the various Apple Language Kits or localized operating
systems. There are also input methods, adapted from cxterm (see
Section 7.7), available that cover the CJK spectrum (Japanese,
Simplified Chinese, Traditional Chinese, and Korean).
	MacBlue Telnet is available at the following URL:

  ftp://ftp.ifcss.org/pub/software/mac/networking/MacBlueTelnet/

Its associated CJK input methods are at the following URL:

  ftp://ftp.ifcss.org/pub/software/mac/input/


7.7: CXTERM

	This program, cxterm, is a CJK-capable xterm for X Windows
(works with X11R4, X11R5, and X11R6). It is based on the X11R6 xterm.
It is available at the following URL:

  ftp://ftp.ifcss.org/pub/software/x-win/cxterm/

	The following URL is for a program that adds Unicode
capability to cxterm:

  ftp://ftp.ifcss.org/pub/software/unix/convert/hztty-2.0.tar.gz

The following URL adds support for other encodings to cxterm:

  ftp://ftp.ifcss.org/pub/software/unix/convert/BeTTY-1.534.tar.gz


7.8: UW-DBM

	UW-DBM, for Windows 3.1, Windows 95, and Windows NT, is a
program that allows users to handle Chinese (Big Five, GB-2312-80, or
HZ code), Japanese (Shift-JIS), and Korean (KS C 5601-1992)
simultaneously. More information on UW-DBM is available at the
following URL:

  http://www.gy.com/ccd/win95/cjkw95.htm

	A demo version of UW-DBM is available at the following URL:

  ftp://ftp.aimnet.com/pub/users/chinabus/uwdbm40.zip


7.9: POSTSCRIPT

	With the introduction of CID-keyed Font Technology, PostScript
has become fully CJK capable.
	Adobe Systems has developed the following CJK character
collection for CID-keyed fonts (font developers are encouraged to
conform to these specifications):

  Character Collection  CIDs   Supported Character Sets & Encodings
  ^^^^^^^^^^^^^^^^^^^^  ^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Adobe-GB1-1           9,897  GB 2312-80 and GB/T 12345-90; 7-bit ISO
                               2022 and EUC
  Adobe-CNS1-0         14,099  Big Five (ETen extensions) and CNS
                               11643-1992 Planes 1 and 2; Big Five,
                               7-bit ISO 2022, and EUC
  Adobe-Japan1-2        8,720  JIS X 0208-1990; Shift-JIS, 7-bit ISO
                               2022, and EUC
  Adobe-Japan2-0        6,068  JIS X 0212-1990; 7-bit ISO 2022 and EUC
  Adobe-Korea1-1       18,155  KS C 5601-1992 (Macintosh extensions
                               plus Johab); 7-bit ISO 2022, EUC, UHC,
                               and Johab

Note that Macintosh and Windows do not support any of the encodings
for Adobe-Japan2-0, thus fonts based on that specification are
unusable for those platforms.
	Adobe Systems also have a few things in the works (that is,
they are either proposed or in draft form), all of which are
supplements to above character collections (that is, they add CIDs):

  Character Collection  CIDs   Supported Character Sets & Encodings
  ^^^^^^^^^^^^^^^^^^^^  ^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Adobe-CNS1-1         +6,018  Add CNS 11643-1992 Plane 3 support (30
                               of the 6,148 hanzi are in Adobe-CNS1-0)

	To find out more about these CJK character collections or
CID-keyed font technology, contact the Adobe Developers Association.
Several CID-related documents have been published. ADA's contact
information is as follows:

  Adobe Developers Association
  Adobe Systems Incorporated
  1585 Charleston Road
  P.O. Box 7900
  Mountain View, CA 94039-7900
  USA
  +1-415-961-4111 (phone)
  +1-415-967-9231 (facsimile)
  [email protected]
  http://www.adobe.com/Support/

Adobe Systems has recently developed the CID SDK (CID Software
Developers Kit), which is on a single CD-ROM. Contact the Adobe
Developers Association for information on obtaining a copy.
	The complete CID-keyed font file specification and an overview
document are available at the following URLs (as a PostScript or PDF
[Adobe Acrobat] file, respectively):

  ftp://ftp.adobe.com/pub/adobe/DeveloperSupport/TechNotes/PSfiles/
  ftp://ftp.adobe.com/pub/adobe/DeveloperSupport/TechNotes/PDFfiles/

The file names (not provided above due to URL length) are:

  5014.CMap_CIDFont_Spec.ps    (complete CID engineering specification)
  5014.CMap_CIDFont_Spec.pdf
  5092.CID_Overview.ps         (CID technology overview)
  5092.CID_Overview.pdf

Other related files, most character collection specifications, are
available only in PDF format at the latter URL indicated above:

  5004.AFM_Spec.pdf            (Includes CID-keyed AFM specification)
  5078b.pdf                    (Adobe-Japan1-2 character collection)
  5079b.pdf                    (Adobe-GB1-0 character collection)
  5080b.pdf                    (Adobe-CNS1-0 character collection)
  5093b.pdf                    (Adobe-Korea1-0 character collection)
  5094.pdf                     (Adobe CJK CMap file descriptions)
  5097b.pdf                    (Adobe-Japan2-0 character collection)

If you do not have Adobe Acrobat, there is a freely-available Acrobat
Reader (for Macintosh, Windows, MS-DOS, and UNIX) at the following
URL:

  ftp://ftp.adobe.com/pub/adobe/Applications/Acrobat/

	I have also placed some CJK character collection materials,
including prototype Unicode (UCS-2 and UTF-8) CMap files, at the
following URL:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/adobe/

A sample (Adobe-Korea1-0) CIDFont is also available at the above URL.
	There is also a somewhat brief description of CID-keyed fonts
at the end of Chapter 6 in UJIP.


7.10: NJWIN

	Hongbo Data Systems has recently release a ShareWare ($49 USD)
product called NJWIN whose purpose is to force the display of CJK text
in non-CJK applications running under US Windows 95. Actually, there
are two versions: full CJK and Japanese only.
	NJWIN and its full description are available at the following
URL:

  http://www.njstar.com.au/njstar/njwin.htm

Other (popular) URLs that carry NJWIN are as follows:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/windows/
  ftp://ftp.cc.monash.edu.au/pub/nihongo/

	Hongbo Data Systems' e-mail address is:

  [email protected]

Their WWW Home Page is at the following URL:

  http://www.njstar.com.au/


PART 8: CJK PROGRAMMING ISSUES

	This new section describes issues related to using specific
programming languages to process CJK text.


8.1: C AND C++

	At one time I used C on a regular basis for my CJK programming
needs, and released three tools for others to use: JConv, JChar, and
JCode. While these tools are specific to Japanese, they can be easily
adapted for CJK use. Their source code is available at the following
URL:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/src/

	I also provided several C code snippets in Chapter 7 of
UJIP. These are available in machine-readable form at the following
URL:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/Ch7/


8.2: PERL

	Although Perl does not have any special CJK facilities (note
that most implementations of C and C++ do not either), it provides a
powerful programming environment that is useful for many CJK-related
tasks.
	The noteworthy features of Perl are associative arrays and
regular expressions. These are features not found in C or C++, and
allow one to write meaningful code in little time.
	JPerl is an implementation of Perl that provides two-byte
support for Japanese (EUC or Shift-JIS encoding). It is not ideal
because JPerl scripts often cannot run under (non-Japanese) Perl.
	If you often write programs for internal use, I suggest that
you check out Perl to see if it can offer you something. Chances are
that it can. A good place to start looking at Perl are through books
on the subject (see Section A.3.1) and at the following URL:

  http://www.perl.com/

	For those who like additional reading, "The Perl Journal" is
starting up, and information is at the following URL:

  http://work.media.mit.edu/the_perl_journal/


8.3: JAVA

	I am just starting to learn about the Java programming
language (and rightly so since my wife is Javanese!). It seems to have
a lot to offer.
	The most interesting aspects of Java are:

o Built-in support for Unicode and UTF-8.
o The programmer must write code in the object-oriented paradigm.
o Provides a portable way to supply compiled code.
o Security features for Internet use.

More information on Java are at the following URLs:

  http://www.gamelan.com/
  http://www.javasoft.com/

Oh, Gamelan is the name of Javanese music.
	Of the books about Java published thus far, the one I consider
to be the best is "Java in a Nutshell" by David Flanagan.
	One programming feature of Perl that I dearly miss in Java are
regexes (regular expressions). Luckily, some kind person wrote a regex
package for Java based on Perl regexes. Information on this Java regex
package is available at the following URL:

  http://www.win.net/~stevesoft/pat/


A FINAL NOTE

	I hope that the information presented here will prove
useful. I would like to keep the electronic version of this document
as up-to-date as possible, and through readers' input, I am able to
do so.
	Many readers will notice that I am very heavy into UNIX and
Macintosh (well, I recently got my first PC). If anyone has any
information on CJK-capable interfaces for other platforms, please feel
free to send it to me, and I will be sure to include it in the next
version of CJK.INF. Please include sources for the software or
documentation by providing addresses, phone numbers, FTP sites, and so
on.
	Please do not hesitate to ask me further question concerning
any subject presented in this document.


ACKNOWLEDGMENTS

	I would like to express my deepest thanks to Kazumasa Utashiro
of Internet Initiative Japan (IIJ). He taught to me how to send and
receive Japanese text using the 7-bit ISO 2022 codes back in 1989.
With his help I was able to write JAPAN.INF, my book, and this
document in order to inform others about what he has taught me plus
more.
	Next, I thank all the folks at O'Reilly & Associates for
publishing UJIP. Special thanks to Tim O'Reilly for accepting the book
proposal, and to Peter Mui for guiding me through the process. I have
had nothing but good experiences with "them there fine folks."
	I got to know Jack Halpern through UJIP, and he subsequently
translated it into Japanese. Many thanks to him.
	I am also grateful to my employer, Adobe Systems, for letting
me work on interesting CJK-related projects. I really like what I do
here. In particular, I want to thank Dan Mills, my manager, for
putting up with me for these past four years.
	Lastly, I would also like to thank the countless people who
provided comments on JAPAN.INF, UJIP, and CJK.INF. I hope that this
new document lives up to the spirit of my previous efforts.


APPENDIX A: OTHER INFORMATION SOURCES

	One of the most useful types of information are pointers to
other information sources. This appendix provides just that.


A.1: USENET NEWSGROUPS AND MAILING LISTS

	Appendix L of UJIP provided information on a number of mailing
lists. This section supplements that appendix with information on
other useful mailing lists, and points out which ones in UJIP are
relevant to readers of CJK.INF.


A.1.1: USENET NEWSGROUPS

	The following Usenet Newsgroups typically have postings with
information relevant to issues discussed in CJK.INF (in alphabetical
order):

  alt.chinese.computing
  alt.chinese.text                (HZ encoding used for Chinese text)
  alt.chinese.text.big5           (Big Five encoding used for Chinese text)
  alt.japanese.text               (JIS encoding used for Japanese text)
  chinese.flame                   (UTF-7)
  chinese.text.unicode            (UTF-8)
  comp.lang.c
  comp.lang.c++
  comp.lang.java
  comp.lang.perl.misc
  comp.software.international
  comp.std.internat
  fj.editor.mule                  (JIS encoding used for Japanese text)
  fj.kanji                        (JIS encoding used for Japanese text)
  fj.net.infosystems.www.browsers (JIS encoding used for Japanese text)
  fj.news.reader                  (JIS encoding used for Japanese text)
  han.comp.hangul
  han.sys.mac
  sci.lang.japan                  (JIS encoding used for Japanese text)

	If your local news host does not provide a feed of the fj.*
newsgroups (shame on them!), or if you do not have access to Usenet
News, you can alternatively fetch them from the following URL:

  ftp://kuso.shef.ac.uk/pub/News/

The subdirectories correspond to the newsgroup name, but with the
"dots" being replaced by "slashes." For example, the "fj.binaries.mac"
newsgroup is archived in the "fj/binaries/mac" subdirectory. Many
thanks to Earl Kinmonth ([email protected]) for this service.
	There are some sites that carry full feeds of the fj.*
newsgroups, and permit public access (meaning that you can configure
your news reader to point to it). The only one I know of thus far is
as follows:

  ume.cc.tsukuba.ac.jp


A.1.2: MAILING LISTS

	The following are mailing lists that should interest readers
of this document (some are more active than others). The first line
after each entry indicates the address (or addresses) that can be used
for subscribing. The second line is the address for posting.

o CCNET-L MAILING LIST
  [email protected] (or listserv@uga)
  [email protected]

o China Net Mailing List
  [email protected]
  (See http://www.asia-net.com/ or [email protected])

o EASUG (East Asian Software Users Group) Mailing List
  [email protected]
  [email protected]

o EBTI-L (Electronic Buddhist Text Initiative) Mailing List
  [email protected]
  [email protected]

o EFJ (Electronic Frontiers Japan) Mailing List
  [email protected]
  [email protected]

o Hangul Mailing List (han.comp.hangul newsgroup)
  [email protected]
  [email protected]

o INSOFT-L Mailing List
  [email protected]
  [email protected]

o ISO 10646 Mailing List
  [email protected]
  [email protected]

o Japan Net Mailing List
  [email protected]
  (See http://www.asia-net.com/ or [email protected])

o KanjiTalk Mailing List
  [email protected] (or [email protected])
  [email protected] (or [email protected])

o Mac Mailing List (han.sys.mac newsgroup)
  [email protected]
  [email protected]

o Mule Mailing List
  [email protected]
  [email protected] or [email protected]

o NIHONGO Mailing List (sci.lang.japan newsgroup)
  [email protected] (or listserv@mitvma)
  [email protected]

o Nihongo-Hiroba Mailing List
  [email protected]
  [email protected]

o Nisus Mailing List
  [email protected]
  [email protected]

o TLUG (Tokyo Linux User's Group) Mailing List
  [email protected]
  [email protected]

o Unicode Mailing List
  [email protected]
  [email protected]

o WNN User Mailing List
  [email protected]
  [email protected]

o WWW Multilingual Mailing List
  [email protected]
  [email protected]

If the name of the mailing list is part of the subscription address
(such as "easug-request"), the message body should look like this:

  subscribe

Including your name is optional. If username in the subscription
address is "listserv" or "majordomo" (these are names of mailing list
managing software), the mailing list name must appear after
"subscribe" in the message body as follows:

  subscribe ccnet-l

Again, including your name is optional.
	The following URL has information about Japanese-related
mailing lists:

  gopher://gan1.ncc.go.jp/11/INFO/mail-lists/


A.2: INTERNET RESOURCES

	The Internet provides what I would consider to be the greatest
information resources of all. These can be subcategorized into FTP,
Telnet, Gopher, WWW, and e-mail.


A.2.1: USEFUL FTP SITES

	Below are the URLs for useful FTP sites. The directory
specified is the recommended place from which to start poking around
for useful files.

  ftp://cair-archive.kaist.ac.kr/pub/hangul/
  ftp://etlport.etl.go.jp/pub/mule/
  ftp://ftp.adobe.com/pub/adobe/
  ftp://ftp.cc.monash.edu.au/pub/nihongo/
  ftp://ftp.ifcss.org/pub/software/
  ftp://ftp.ora.com/pub/examples/nutshell/ujip/
  ftp://ftp.sra.co.jp/pub/
  ftp://ftp.uwtc.washington.edu/pub/Japanese/
  ftp://kuso.shef.ac.uk/pub/Japanese/
  ftp://unicode.org/pub/

This list is expected to grow.


A.2.2: USEFUL TELNET SITES

	For those who have a NIFTY-Serve account, there is now a very
convenient way to access NIFTY-Serve using telnet. The URL is as
follows:

  telnet://r2.niftyserve.or.jp/

Information about what NIFTY-Serve has to offer (and how to subscribe)
can be found at the following URL:

  http://www.nifty.co.jp/

	Another information service with a similar access mechanism is
CompuServe, whose URL is as follows:

  telnet://compuserve.com/

You will need to press the return key to get the "Host Name:" prompt,
at which time you type "cis" (just follow the menus from this point
on).
	You can also do a search on fj.* newsgroup articles at the
following URL:

  telnet://asahi-net.or.jp/

You login as "fj-db" once you are connected.


A.2.3: USEFUL GOPHER SITES

	I am not too much of a Gopher user. There, of course, is the
following:

  gopher://gopher.ora.com/

Another Gopher site provides information on Japanese-related mailing
lists:

  gopher://gan1.ncc.go.jp/11/INFO/mail-lists/

If you happen to know of others, please let me know.


A.2.4: USEFUL WWW SITES

	Because the World-Wide Web is a constantly changing place (and
more importantly, because I don't want to re-issue a new version of
this document every month!), I will maintain links to useful documents
at my WWW Home Page. Its URL is as follows:

  http://jasper.ora.com/lunde/

If you cannot get to my WWW Home Page, you couldn't get to any that I
would list here anyway.


A.2.5: USEFUL MAIL SERVERS

	In the past (that is, in JAPAN.INF) I included a full list of
the domains in the "jp" hierarchy. That took up a lot of space, and
changes very rapidly. You can now send a request to a mail server in
order to return the most current listing. The mail server is:

  [email protected]

The most common command is "send," and the following arguments can be
supplied to retrieve specific documents (and should be in the message
body, not on the "Subject:" line):

  send help
  send index
  send jpnic/domain-list.txt
  send jpnic/domain-list-e.txt

The first sends back a help file, the second sends back a complete
index of files that can be retrieved (use this one to see what other
useful stuff is available), and the last two send back a complete
listing of domains in the "fj" hierarchy (the last one send it back in
English/romanized).


A.3: OTHER RESOURCES

	This section provides pointers to specific documentation
available electronically or in print.


A.3.1: BOOKS

	There are other useful reference materials available in print
or online, in addition to the various national and international
standards mentioned throughout this document. The following are books
that I recommend for further reading or mental stimulus. (Sorry for
plugging my own books in this list, but they are relevant.)

o Clews, John. "Language Automation Worldwide: The Development of
  Character Set Standards." SESAME Computer Projects. 1988. ISBN
  1-870095-01-4.

o Flanagan, David. "Java in a Nutshell." O'Reilly & Associates,
  Inc. 1996. ISBN 1-56592-183-6.

o Frisch, AEleen. "Essential System Administration." Second Edition.
  O'Reilly & Associates, Inc. 1995. ISBN 1-56592-127-5.

o Huang, Jack & Timothy Huang. "An Introduction to Chinese, Japanese
  and Korean Computing." World Scientific Computing. 1989. ISBN
  9971-50-664-5.

o IBM Corporation. "Character Data Representation Architecture - Level
  2, Registry." 1993. IBM order number SC09-1391-01.

o Kano, Nadine. "Developing International Software for Windows 95 and
  Windows NT." Microsoft Press. 1995. ISBN 1-55615-840-8.

o Kirch, Olaf. "Linux Network Administrator's Guide." O'Reilly &
  Associates, Inc. 1995. ISBN 1-56592-087-2.

o Kissell, Joe. "The Nisus Way." MIS:Press. 1996. ISBN 1-55828-455-9.

o Krol, Ed. "The Whole Internet User's Guide & Catalog." Second
  Edition. O'Reilly & Associates, Inc. 1994. ISBN 1-56592-063-5.

o Liu, Cricket et al. "Managing Internet Information Services."
  O'Reilly & Associates, Inc. 1994. ISBN 1-56592-062-7.

o Lunde, Ken. "Understanding Japanese Information Processing."
  O'Reilly & Associates, Incorporated. 1993. ISBN 1-56592-043-0. LCCN
  PL524.5.L86 1993.

o Lunde, Ken. "Nihongo Joho Shori." SOFTBANK Corporation. 1995. ISBN
  4-89052-708-7.

o Luong, Tuoc V. et al. "Internationalization: Developing Software for
  Global Markets." John Wiley & Sons, Incorporated. 1995. ISBN
  0-471-07661-9.

o Schwartz, Randal L. "Learning Perl." O'Reilly & Associates,
  Incorporated. 1993. ISBN 1-56592-042-2.

o Stallman, Richard M. "GNU Emacs Manual." Tenth edition. Free
  Software Foundation. 1994. ISBN 1-882114-04-3.

o Tuthill, Bill. "Solaris International Developer's Guide." SunSoft
  Press and PTR Prentice Hall. 1993. ISBN 0-13-031063-8.

o Unicode Consortium, The. "The Unicode Standard: Worldwide Character
  Encoding." Version 1.0. Volume 2. Addison-Wesley. 1992. ISBN
  0-201-60845-6.

o Vromans, Johan. "Perl 5 Desktop Reference." O'Reilly & Associates,
  Inc. 1996. ISBN 1-56592-187-9.

o Wall, Larry & Randal L. Schwartz. "Programming Perl." O'Reilly &
  Associates, Incorporated. 1991. ISBN 0-937175-64-1.

o Welsh, Matt & Lar Kaufman. "Running Linux." O'Reilly & Associates,
  Inc. 1995. ISBN 1-56592-100-3.

	If you want to get your hands on any of the national or
international standards mentioned in this document, I suggest the
following:

o The American National Standards Institute can provide ISO, KS, and
  JIS standards. Bear in mind that ISO standards will most likely
  arrive as a photocopy of the original.

  ANSI
  11 West 42nd Street
  New York, NY 10036
  USA
  +1-212-642-4900 (phone)
  +1-212-302-1286 (facsimile)

o The International Organization for Standardization can provide
  ISO standards.

  ISO
  1, rue de Varemb
  Case postale 56
  CH-1211, Geneva 20
  SWITZERLAND
  +41-22-749-01-11 (phone)
  +41-22-733-34-30 (facsimile)
  [email protected] (e-mail)
  http://www.iso.ch/ (WWW)

o Chinese (GB and CNS) standards are the hardest to obtain. It is
  quite unfortunate.


A.3.2: MAGAZINES

o "Computing Japan," published monthly, ISSN 1340-7228,
  [email protected].

o "MANGAJIN," published 10 times per year, ISSN 1051-8177.

o "Multilingual Communications & Computing," published bi-monthly,
  ISSN 1065-7657, [email protected].

o "The Perl Journal," published quarterly, ISSN 1087-903X,
  [email protected].


A.3.3: JOURNALS

o "Chinese Information Processing" (CIP), published bi-monthly, ISSN
  1003-9082. (In Chinese.)

o "Computer Processing of Chinese & Oriental Languages" (CPCOL),
  co-published twice a year by World Scientific Publishing and Chinese
  Language Computer Society (CLCS), ISSN 0715-9048.

o "The Electronic Bodhidharma," published by the International
  Research Institute for Zen (IRIZ) Buddhism, Hanazono University,
  Japan. More information on the organization that publishes this
  journal is available at the following URL:

  http://www.iijnet.or.jp/iriz/irizhtml/irizhome.htm


A.3.4: RFCs

	Many RFCs (Request For Comments) are relevant to this
document. They are:

o RFC 1341: "MIME (Multipurpose Internet Mail Extensions): Mechanisms
  for Specifying and Describing the Format of Internet Message
  Bodies," by Nathaniel Borenstein and Ned Freed, June 1992.

o RFC 1342: "Representation of Non-ASCII Text in Internet Message
  Headers," by Keith Moore, June 1992.

o RFC 1468: "Japanese Character Encoding for Internet Messages," by
  Jun Murai et al., June 1993.

o RFC 1521: "MIME (Multipurpose Internet Mail Extensions) Part One:
  Mechanisms for Specifying and Describing the Format of Internet
  Message Bodies," by Nathaniel Borenstein and Ned Freed, September
  1993. Obsoletes RFC 1341.

o RFC 1522: "MIME (Multipurpose Internet Mail Extensions) Part Two:
  Message Header Extensions for Non-ASCII Text," by Keith Moore,
  September 1993. Obsoletes RFC 1342.

o RFC 1554: "ISO-2022-JP-2: Multilingual Extension of ISO-2022-JP," by
  Masataka Ohta and Kenichi Handa, December 1993.

o RFC 1557: "Korean Character Encoding for Internet Messages," by
  Uhhyung Choi et al., December 1993.

o RFC 1642: "UTF-7: A Mail-Safe Transformation Format of Unicode," by
  David Goldsmith and Mark Davis, July 1994.

o RFC 1815: "Character Sets ISO-10646 and ISO-10646-J-1," by Masataka
  Ohta, July 1995.

o RFC 1842: "ASCII Printable Characters-Based Chinese Character
  Encoding for Internet Messages," by Ya-Gui Wei et al., August 1995.

o RFC 1843: "HZ - A Data Format for Exchanging Files of Arbitrarily
  Mixed Chinese and ASCII Characters," by Fung Fung Lee, August 1995.

o RFC 1922: "Chinese Character Encoding for Internet Messages," by
  Haifeng Zhu et al., March 1996.

These RFCs can be obtained from FTP archives that contain all RFC
documents, such as at the following URLs

  ftp://nic.ddn.mil/rfc/
  ftp://ftp.uu.net/inet/rfc/

But these specific ones are mirrored at the following URL for
convenience:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/Ch9/


A.3.5: FAQs

	There are several FAQ (Frequently Asked Questions) files that
provide useful information. The following is a listing of some along
with their URLs:

o "Japanese Language Information" FAQ (formerly the "sci.lang.japan"
  FAQ) by Rafael Santos ([email protected]) at:

  http://www.mickey.ai.kyutech.ac.jp/cgi-bin/japanese/

  Update announcements are usually posted to the sci.lang.japan
  newsgroup.

o "Programming for Internationalization" FAQ by Michael Gschwind
  ([email protected]) at:

  ftp://ftp.vlsivie.tuwien.ac.at/pub/8bit/ISO-programming

  Also posted to the comp.software.international newsgroup. This and
  other internationalization documents are also accessible through the
  following URL:

  http://www.vlsivie.tuwien.ac.at/mike/i18n.html

o Three FAQs about Internet Service Providers in Japan by Taki Naruto
  ([email protected]), Jesse Casman ([email protected]), and Kenji Yoshida
  ([email protected]), respectively, at:

  http://www.panix.com/~tn/ispj.html
  http://nobunaga.unm.edu/internet.html
  http://cswww2.essex.ac.uk/users/whean/japan/net.html

o "Internationalization Reference List" by Eugene Dorr
  ([email protected]) at:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/i18n-books.txt

  Note really a FAQ, but quite useful because it is a very complete
  listing of I18N-related books.

o "INSOFT-L Service" by Brian Tatro ([email protected]) at:

  http://iquest.com/~btatro/in2.html

  This includes a link to the FAQ for the INSOFT-L Mailing List (see
  Section A.1.2).

o "How to Use Japanese on the Internet with a PC: From Login to WWW"
  by Hideki Hirayama ([email protected]) at:

  ftp://ftp.ora.com/pub/examples/nutshell/ujip/faq/jpn-inet.FAQ

o "Hangul and Internet in Korea" FAQ by Jungshik Shin
  ([email protected]) at:

  http://pantheon.cis.yale.edu/~jshin/faq/
---  END (CJK.INF VERSION 2.1 07/12/96) 185553 BYTES  ---

Added tools/encoding/cp1250.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
269
270
271
272
273
274
275
#
#    Name:     cp1250_WinLatin2 to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp1250_WinLatin2 code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp1250_WinLatin2 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		#UNDEFINED
0x81		#UNDEFINED
0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
0x83		#UNDEFINED
0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
0x85	0x2026	#HORIZONTAL ELLIPSIS
0x86	0x2020	#DAGGER
0x87	0x2021	#DOUBLE DAGGER
0x88		#UNDEFINED
0x89	0x2030	#PER MILLE SIGN
0x8A	0x0160	#LATIN CAPITAL LETTER S WITH CARON
0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
0x8C	0x015A	#LATIN CAPITAL LETTER S WITH ACUTE
0x8D	0x0164	#LATIN CAPITAL LETTER T WITH CARON
0x8E	0x017D	#LATIN CAPITAL LETTER Z WITH CARON
0x8F	0x0179	#LATIN CAPITAL LETTER Z WITH ACUTE
0x90		#UNDEFINED
0x91	0x2018	#LEFT SINGLE QUOTATION MARK
0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
0x95	0x2022	#BULLET
0x96	0x2013	#EN DASH
0x97	0x2014	#EM DASH
0x98		#UNDEFINED
0x99	0x2122	#TRADE MARK SIGN
0x9A	0x0161	#LATIN SMALL LETTER S WITH CARON
0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
0x9C	0x015B	#LATIN SMALL LETTER S WITH ACUTE
0x9D	0x0165	#LATIN SMALL LETTER T WITH CARON
0x9E	0x017E	#LATIN SMALL LETTER Z WITH CARON
0x9F	0x017A	#LATIN SMALL LETTER Z WITH ACUTE
0xA0	0x00A0	#NO-BREAK SPACE
0xA1	0x02C7	#CARON
0xA2	0x02D8	#BREVE
0xA3	0x0141	#LATIN CAPITAL LETTER L WITH STROKE
0xA4	0x00A4	#CURRENCY SIGN
0xA5	0x0104	#LATIN CAPITAL LETTER A WITH OGONEK
0xA6	0x00A6	#BROKEN BAR
0xA7	0x00A7	#SECTION SIGN
0xA8	0x00A8	#DIAERESIS
0xA9	0x00A9	#COPYRIGHT SIGN
0xAA	0x015E	#LATIN CAPITAL LETTER S WITH CEDILLA
0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xAC		#UNDEFINED
0xAD	0x00AD	#SOFT HYPHEN
0xAE	0x00AE	#REGISTERED SIGN
0xAF	0x017B	#LATIN CAPITAL LETTER Z WITH DOT ABOVE
0xB0	0x00B0	#DEGREE SIGN
0xB1	0x00B1	#PLUS-MINUS SIGN
0xB2	0x02DB	#OGONEK
0xB3	0x0142	#LATIN SMALL LETTER L WITH STROKE
0xB4	0x00B4	#ACUTE ACCENT
0xB5	0x00B5	#MICRO SIGN
0xB6	0x00B6	#PILCROW SIGN
0xB7	0x00B7	#MIDDLE DOT
0xB8	0x00B8	#CEDILLA
0xB9	0x0105	#LATIN SMALL LETTER A WITH OGONEK
0xBA	0x015F	#LATIN SMALL LETTER S WITH CEDILLA
0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xBC	0x013D	#LATIN CAPITAL LETTER L WITH CARON
0xBD	0x02DD	#DOUBLE ACUTE ACCENT
0xBE	0x013E	#LATIN SMALL LETTER L WITH CARON
0xBF	0x017C	#LATIN SMALL LETTER Z WITH DOT ABOVE
0xC0	0x0154	#LATIN CAPITAL LETTER R WITH ACUTE
0xC1	0x00C1	#LATIN CAPITAL LETTER A WITH ACUTE
0xC2	0x00C2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xC3	0x0102	#LATIN CAPITAL LETTER A WITH BREVE
0xC4	0x00C4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0xC5	0x0139	#LATIN CAPITAL LETTER L WITH ACUTE
0xC6	0x0106	#LATIN CAPITAL LETTER C WITH ACUTE
0xC7	0x00C7	#LATIN CAPITAL LETTER C WITH CEDILLA
0xC8	0x010C	#LATIN CAPITAL LETTER C WITH CARON
0xC9	0x00C9	#LATIN CAPITAL LETTER E WITH ACUTE
0xCA	0x0118	#LATIN CAPITAL LETTER E WITH OGONEK
0xCB	0x00CB	#LATIN CAPITAL LETTER E WITH DIAERESIS
0xCC	0x011A	#LATIN CAPITAL LETTER E WITH CARON
0xCD	0x00CD	#LATIN CAPITAL LETTER I WITH ACUTE
0xCE	0x00CE	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xCF	0x010E	#LATIN CAPITAL LETTER D WITH CARON
0xD0	0x0110	#LATIN CAPITAL LETTER D WITH STROKE
0xD1	0x0143	#LATIN CAPITAL LETTER N WITH ACUTE
0xD2	0x0147	#LATIN CAPITAL LETTER N WITH CARON
0xD3	0x00D3	#LATIN CAPITAL LETTER O WITH ACUTE
0xD4	0x00D4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xD5	0x0150	#LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
0xD6	0x00D6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0xD7	0x00D7	#MULTIPLICATION SIGN
0xD8	0x0158	#LATIN CAPITAL LETTER R WITH CARON
0xD9	0x016E	#LATIN CAPITAL LETTER U WITH RING ABOVE
0xDA	0x00DA	#LATIN CAPITAL LETTER U WITH ACUTE
0xDB	0x0170	#LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
0xDC	0x00DC	#LATIN CAPITAL LETTER U WITH DIAERESIS
0xDD	0x00DD	#LATIN CAPITAL LETTER Y WITH ACUTE
0xDE	0x0162	#LATIN CAPITAL LETTER T WITH CEDILLA
0xDF	0x00DF	#LATIN SMALL LETTER SHARP S
0xE0	0x0155	#LATIN SMALL LETTER R WITH ACUTE
0xE1	0x00E1	#LATIN SMALL LETTER A WITH ACUTE
0xE2	0x00E2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0xE3	0x0103	#LATIN SMALL LETTER A WITH BREVE
0xE4	0x00E4	#LATIN SMALL LETTER A WITH DIAERESIS
0xE5	0x013A	#LATIN SMALL LETTER L WITH ACUTE
0xE6	0x0107	#LATIN SMALL LETTER C WITH ACUTE
0xE7	0x00E7	#LATIN SMALL LETTER C WITH CEDILLA
0xE8	0x010D	#LATIN SMALL LETTER C WITH CARON
0xE9	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
0xEA	0x0119	#LATIN SMALL LETTER E WITH OGONEK
0xEB	0x00EB	#LATIN SMALL LETTER E WITH DIAERESIS
0xEC	0x011B	#LATIN SMALL LETTER E WITH CARON
0xED	0x00ED	#LATIN SMALL LETTER I WITH ACUTE
0xEE	0x00EE	#LATIN SMALL LETTER I WITH CIRCUMFLEX
0xEF	0x010F	#LATIN SMALL LETTER D WITH CARON
0xF0	0x0111	#LATIN SMALL LETTER D WITH STROKE
0xF1	0x0144	#LATIN SMALL LETTER N WITH ACUTE
0xF2	0x0148	#LATIN SMALL LETTER N WITH CARON
0xF3	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
0xF4	0x00F4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0xF5	0x0151	#LATIN SMALL LETTER O WITH DOUBLE ACUTE
0xF6	0x00F6	#LATIN SMALL LETTER O WITH DIAERESIS
0xF7	0x00F7	#DIVISION SIGN
0xF8	0x0159	#LATIN SMALL LETTER R WITH CARON
0xF9	0x016F	#LATIN SMALL LETTER U WITH RING ABOVE
0xFA	0x00FA	#LATIN SMALL LETTER U WITH ACUTE
0xFB	0x0171	#LATIN SMALL LETTER U WITH DOUBLE ACUTE
0xFC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
0xFD	0x00FD	#LATIN SMALL LETTER Y WITH ACUTE
0xFE	0x0163	#LATIN SMALL LETTER T WITH CEDILLA
0xFF	0x02D9	#DOT ABOVE



Added tools/encoding/cp1251.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
269
270
271
272
273
274
275
#
#    Name:     cp1251_WinCyrillic to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp1251_WinCyrillic code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp1251_WinCyrillic 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	0x0402	#CYRILLIC CAPITAL LETTER DJE
0x81	0x0403	#CYRILLIC CAPITAL LETTER GJE
0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
0x83	0x0453	#CYRILLIC SMALL LETTER GJE
0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
0x85	0x2026	#HORIZONTAL ELLIPSIS
0x86	0x2020	#DAGGER
0x87	0x2021	#DOUBLE DAGGER
0x88		#UNDEFINED
0x89	0x2030	#PER MILLE SIGN
0x8A	0x0409	#CYRILLIC CAPITAL LETTER LJE
0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
0x8C	0x040A	#CYRILLIC CAPITAL LETTER NJE
0x8D	0x040C	#CYRILLIC CAPITAL LETTER KJE
0x8E	0x040B	#CYRILLIC CAPITAL LETTER TSHE
0x8F	0x040F	#CYRILLIC CAPITAL LETTER DZHE
0x90	0x0452	#CYRILLIC SMALL LETTER DJE
0x91	0x2018	#LEFT SINGLE QUOTATION MARK
0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
0x95	0x2022	#BULLET
0x96	0x2013	#EN DASH
0x97	0x2014	#EM DASH
0x98		#UNDEFINED
0x99	0x2122	#TRADE MARK SIGN
0x9A	0x0459	#CYRILLIC SMALL LETTER LJE
0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
0x9C	0x045A	#CYRILLIC SMALL LETTER NJE
0x9D	0x045C	#CYRILLIC SMALL LETTER KJE
0x9E	0x045B	#CYRILLIC SMALL LETTER TSHE
0x9F	0x045F	#CYRILLIC SMALL LETTER DZHE
0xA0	0x00A0	#NO-BREAK SPACE
0xA1	0x040E	#CYRILLIC CAPITAL LETTER SHORT U
0xA2	0x045E	#CYRILLIC SMALL LETTER SHORT U
0xA3	0x0408	#CYRILLIC CAPITAL LETTER JE
0xA4	0x00A4	#CURRENCY SIGN
0xA5	0x0490	#CYRILLIC CAPITAL LETTER GHE WITH UPTURN
0xA6	0x00A6	#BROKEN BAR
0xA7	0x00A7	#SECTION SIGN
0xA8	0x0401	#CYRILLIC CAPITAL LETTER IO
0xA9	0x00A9	#COPYRIGHT SIGN
0xAA	0x0404	#CYRILLIC CAPITAL LETTER UKRAINIAN IE
0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xAC	0x00AC	#NOT SIGN
0xAD	0x00AD	#SOFT HYPHEN
0xAE	0x00AE	#REGISTERED SIGN
0xAF	0x0407	#CYRILLIC CAPITAL LETTER YI
0xB0	0x00B0	#DEGREE SIGN
0xB1	0x00B1	#PLUS-MINUS SIGN
0xB2	0x0406	#CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
0xB3	0x0456	#CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
0xB4	0x0491	#CYRILLIC SMALL LETTER GHE WITH UPTURN
0xB5	0x00B5	#MICRO SIGN
0xB6	0x00B6	#PILCROW SIGN
0xB7	0x00B7	#MIDDLE DOT
0xB8	0x0451	#CYRILLIC SMALL LETTER IO
0xB9	0x2116	#NUMERO SIGN
0xBA	0x0454	#CYRILLIC SMALL LETTER UKRAINIAN IE
0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xBC	0x0458	#CYRILLIC SMALL LETTER JE
0xBD	0x0405	#CYRILLIC CAPITAL LETTER DZE
0xBE	0x0455	#CYRILLIC SMALL LETTER DZE
0xBF	0x0457	#CYRILLIC SMALL LETTER YI
0xC0	0x0410	#CYRILLIC CAPITAL LETTER A
0xC1	0x0411	#CYRILLIC CAPITAL LETTER BE
0xC2	0x0412	#CYRILLIC CAPITAL LETTER VE
0xC3	0x0413	#CYRILLIC CAPITAL LETTER GHE
0xC4	0x0414	#CYRILLIC CAPITAL LETTER DE
0xC5	0x0415	#CYRILLIC CAPITAL LETTER IE
0xC6	0x0416	#CYRILLIC CAPITAL LETTER ZHE
0xC7	0x0417	#CYRILLIC CAPITAL LETTER ZE
0xC8	0x0418	#CYRILLIC CAPITAL LETTER I
0xC9	0x0419	#CYRILLIC CAPITAL LETTER SHORT I
0xCA	0x041A	#CYRILLIC CAPITAL LETTER KA
0xCB	0x041B	#CYRILLIC CAPITAL LETTER EL
0xCC	0x041C	#CYRILLIC CAPITAL LETTER EM
0xCD	0x041D	#CYRILLIC CAPITAL LETTER EN
0xCE	0x041E	#CYRILLIC CAPITAL LETTER O
0xCF	0x041F	#CYRILLIC CAPITAL LETTER PE
0xD0	0x0420	#CYRILLIC CAPITAL LETTER ER
0xD1	0x0421	#CYRILLIC CAPITAL LETTER ES
0xD2	0x0422	#CYRILLIC CAPITAL LETTER TE
0xD3	0x0423	#CYRILLIC CAPITAL LETTER U
0xD4	0x0424	#CYRILLIC CAPITAL LETTER EF
0xD5	0x0425	#CYRILLIC CAPITAL LETTER HA
0xD6	0x0426	#CYRILLIC CAPITAL LETTER TSE
0xD7	0x0427	#CYRILLIC CAPITAL LETTER CHE
0xD8	0x0428	#CYRILLIC CAPITAL LETTER SHA
0xD9	0x0429	#CYRILLIC CAPITAL LETTER SHCHA
0xDA	0x042A	#CYRILLIC CAPITAL LETTER HARD SIGN
0xDB	0x042B	#CYRILLIC CAPITAL LETTER YERU
0xDC	0x042C	#CYRILLIC CAPITAL LETTER SOFT SIGN
0xDD	0x042D	#CYRILLIC CAPITAL LETTER E
0xDE	0x042E	#CYRILLIC CAPITAL LETTER YU
0xDF	0x042F	#CYRILLIC CAPITAL LETTER YA
0xE0	0x0430	#CYRILLIC SMALL LETTER A
0xE1	0x0431	#CYRILLIC SMALL LETTER BE
0xE2	0x0432	#CYRILLIC SMALL LETTER VE
0xE3	0x0433	#CYRILLIC SMALL LETTER GHE
0xE4	0x0434	#CYRILLIC SMALL LETTER DE
0xE5	0x0435	#CYRILLIC SMALL LETTER IE
0xE6	0x0436	#CYRILLIC SMALL LETTER ZHE
0xE7	0x0437	#CYRILLIC SMALL LETTER ZE
0xE8	0x0438	#CYRILLIC SMALL LETTER I
0xE9	0x0439	#CYRILLIC SMALL LETTER SHORT I
0xEA	0x043A	#CYRILLIC SMALL LETTER KA
0xEB	0x043B	#CYRILLIC SMALL LETTER EL
0xEC	0x043C	#CYRILLIC SMALL LETTER EM
0xED	0x043D	#CYRILLIC SMALL LETTER EN
0xEE	0x043E	#CYRILLIC SMALL LETTER O
0xEF	0x043F	#CYRILLIC SMALL LETTER PE
0xF0	0x0440	#CYRILLIC SMALL LETTER ER
0xF1	0x0441	#CYRILLIC SMALL LETTER ES
0xF2	0x0442	#CYRILLIC SMALL LETTER TE
0xF3	0x0443	#CYRILLIC SMALL LETTER U
0xF4	0x0444	#CYRILLIC SMALL LETTER EF
0xF5	0x0445	#CYRILLIC SMALL LETTER HA
0xF6	0x0446	#CYRILLIC SMALL LETTER TSE
0xF7	0x0447	#CYRILLIC SMALL LETTER CHE
0xF8	0x0448	#CYRILLIC SMALL LETTER SHA
0xF9	0x0449	#CYRILLIC SMALL LETTER SHCHA
0xFA	0x044A	#CYRILLIC SMALL LETTER HARD SIGN
0xFB	0x044B	#CYRILLIC SMALL LETTER YERU
0xFC	0x044C	#CYRILLIC SMALL LETTER SOFT SIGN
0xFD	0x044D	#CYRILLIC SMALL LETTER E
0xFE	0x044E	#CYRILLIC SMALL LETTER YU
0xFF	0x044F	#CYRILLIC SMALL LETTER YA



Added tools/encoding/cp1252.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
269
270
271
272
273
274
275
#
#    Name:     cp1252_WinLatin1 to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp1252_WinLatin1 code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp1252_WinLatin1 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		#UNDEFINED
0x81		#UNDEFINED
0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
0x83	0x0192	#LATIN SMALL LETTER F WITH HOOK
0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
0x85	0x2026	#HORIZONTAL ELLIPSIS
0x86	0x2020	#DAGGER
0x87	0x2021	#DOUBLE DAGGER
0x88	0x02C6	#MODIFIER LETTER CIRCUMFLEX ACCENT
0x89	0x2030	#PER MILLE SIGN
0x8A	0x0160	#LATIN CAPITAL LETTER S WITH CARON
0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
0x8C	0x0152	#LATIN CAPITAL LIGATURE OE
0x8D		#UNDEFINED
0x8E		#UNDEFINED
0x8F		#UNDEFINED
0x90		#UNDEFINED
0x91	0x2018	#LEFT SINGLE QUOTATION MARK
0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
0x95	0x2022	#BULLET
0x96	0x2013	#EN DASH
0x97	0x2014	#EM DASH
0x98	0x02DC	#SMALL TILDE
0x99	0x2122	#TRADE MARK SIGN
0x9A	0x0161	#LATIN SMALL LETTER S WITH CARON
0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
0x9C	0x0153	#LATIN SMALL LIGATURE OE
0x9D		#UNDEFINED
0x9E		#UNDEFINED
0x9F	0x0178	#LATIN CAPITAL LETTER Y WITH DIAERESIS
0xA0	0x00A0	#NO-BREAK SPACE
0xA1	0x00A1	#INVERTED EXCLAMATION MARK
0xA2	0x00A2	#CENT SIGN
0xA3	0x00A3	#POUND SIGN
0xA4	0x00A4	#CURRENCY SIGN
0xA5	0x00A5	#YEN SIGN
0xA6	0x00A6	#BROKEN BAR
0xA7	0x00A7	#SECTION SIGN
0xA8	0x00A8	#DIAERESIS
0xA9	0x00A9	#COPYRIGHT SIGN
0xAA	0x00AA	#FEMININE ORDINAL INDICATOR
0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xAC	0x00AC	#NOT SIGN
0xAD	0x00AD	#SOFT HYPHEN
0xAE	0x00AE	#REGISTERED SIGN
0xAF	0x00AF	#MACRON
0xB0	0x00B0	#DEGREE SIGN
0xB1	0x00B1	#PLUS-MINUS SIGN
0xB2	0x00B2	#SUPERSCRIPT TWO
0xB3	0x00B3	#SUPERSCRIPT THREE
0xB4	0x00B4	#ACUTE ACCENT
0xB5	0x00B5	#MICRO SIGN
0xB6	0x00B6	#PILCROW SIGN
0xB7	0x00B7	#MIDDLE DOT
0xB8	0x00B8	#CEDILLA
0xB9	0x00B9	#SUPERSCRIPT ONE
0xBA	0x00BA	#MASCULINE ORDINAL INDICATOR
0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xBC	0x00BC	#VULGAR FRACTION ONE QUARTER
0xBD	0x00BD	#VULGAR FRACTION ONE HALF
0xBE	0x00BE	#VULGAR FRACTION THREE QUARTERS
0xBF	0x00BF	#INVERTED QUESTION MARK
0xC0	0x00C0	#LATIN CAPITAL LETTER A WITH GRAVE
0xC1	0x00C1	#LATIN CAPITAL LETTER A WITH ACUTE
0xC2	0x00C2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xC3	0x00C3	#LATIN CAPITAL LETTER A WITH TILDE
0xC4	0x00C4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0xC5	0x00C5	#LATIN CAPITAL LETTER A WITH RING ABOVE
0xC6	0x00C6	#LATIN CAPITAL LIGATURE AE
0xC7	0x00C7	#LATIN CAPITAL LETTER C WITH CEDILLA
0xC8	0x00C8	#LATIN CAPITAL LETTER E WITH GRAVE
0xC9	0x00C9	#LATIN CAPITAL LETTER E WITH ACUTE
0xCA	0x00CA	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xCB	0x00CB	#LATIN CAPITAL LETTER E WITH DIAERESIS
0xCC	0x00CC	#LATIN CAPITAL LETTER I WITH GRAVE
0xCD	0x00CD	#LATIN CAPITAL LETTER I WITH ACUTE
0xCE	0x00CE	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xCF	0x00CF	#LATIN CAPITAL LETTER I WITH DIAERESIS
0xD0	0x00D0	#LATIN CAPITAL LETTER ETH
0xD1	0x00D1	#LATIN CAPITAL LETTER N WITH TILDE
0xD2	0x00D2	#LATIN CAPITAL LETTER O WITH GRAVE
0xD3	0x00D3	#LATIN CAPITAL LETTER O WITH ACUTE
0xD4	0x00D4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xD5	0x00D5	#LATIN CAPITAL LETTER O WITH TILDE
0xD6	0x00D6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0xD7	0x00D7	#MULTIPLICATION SIGN
0xD8	0x00D8	#LATIN CAPITAL LETTER O WITH STROKE
0xD9	0x00D9	#LATIN CAPITAL LETTER U WITH GRAVE
0xDA	0x00DA	#LATIN CAPITAL LETTER U WITH ACUTE
0xDB	0x00DB	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xDC	0x00DC	#LATIN CAPITAL LETTER U WITH DIAERESIS
0xDD	0x00DD	#LATIN CAPITAL LETTER Y WITH ACUTE
0xDE	0x00DE	#LATIN CAPITAL LETTER THORN
0xDF	0x00DF	#LATIN SMALL LETTER SHARP S
0xE0	0x00E0	#LATIN SMALL LETTER A WITH GRAVE
0xE1	0x00E1	#LATIN SMALL LETTER A WITH ACUTE
0xE2	0x00E2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0xE3	0x00E3	#LATIN SMALL LETTER A WITH TILDE
0xE4	0x00E4	#LATIN SMALL LETTER A WITH DIAERESIS
0xE5	0x00E5	#LATIN SMALL LETTER A WITH RING ABOVE
0xE6	0x00E6	#LATIN SMALL LIGATURE AE
0xE7	0x00E7	#LATIN SMALL LETTER C WITH CEDILLA
0xE8	0x00E8	#LATIN SMALL LETTER E WITH GRAVE
0xE9	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
0xEA	0x00EA	#LATIN SMALL LETTER E WITH CIRCUMFLEX
0xEB	0x00EB	#LATIN SMALL LETTER E WITH DIAERESIS
0xEC	0x00EC	#LATIN SMALL LETTER I WITH GRAVE
0xED	0x00ED	#LATIN SMALL LETTER I WITH ACUTE
0xEE	0x00EE	#LATIN SMALL LETTER I WITH CIRCUMFLEX
0xEF	0x00EF	#LATIN SMALL LETTER I WITH DIAERESIS
0xF0	0x00F0	#LATIN SMALL LETTER ETH
0xF1	0x00F1	#LATIN SMALL LETTER N WITH TILDE
0xF2	0x00F2	#LATIN SMALL LETTER O WITH GRAVE
0xF3	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
0xF4	0x00F4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0xF5	0x00F5	#LATIN SMALL LETTER O WITH TILDE
0xF6	0x00F6	#LATIN SMALL LETTER O WITH DIAERESIS
0xF7	0x00F7	#DIVISION SIGN
0xF8	0x00F8	#LATIN SMALL LETTER O WITH STROKE
0xF9	0x00F9	#LATIN SMALL LETTER U WITH GRAVE
0xFA	0x00FA	#LATIN SMALL LETTER U WITH ACUTE
0xFB	0x00FB	#LATIN SMALL LETTER U WITH CIRCUMFLEX
0xFC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
0xFD	0x00FD	#LATIN SMALL LETTER Y WITH ACUTE
0xFE	0x00FE	#LATIN SMALL LETTER THORN
0xFF	0x00FF	#LATIN SMALL LETTER Y WITH DIAERESIS



Added tools/encoding/cp1253.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
269
270
271
272
273
274
275
#
#    Name:     cp1253_WinGreek to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp1253_WinGreek code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp1253_WinGreek 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		#UNDEFINED
0x81		#UNDEFINED
0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
0x83	0x0192	#LATIN SMALL LETTER F WITH HOOK
0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
0x85	0x2026	#HORIZONTAL ELLIPSIS
0x86	0x2020	#DAGGER
0x87	0x2021	#DOUBLE DAGGER
0x88		#UNDEFINED
0x89	0x2030	#PER MILLE SIGN
0x8A		#UNDEFINED
0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
0x8C		#UNDEFINED
0x8D		#UNDEFINED
0x8E		#UNDEFINED
0x8F		#UNDEFINED
0x90		#UNDEFINED
0x91	0x2018	#LEFT SINGLE QUOTATION MARK
0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
0x95	0x2022	#BULLET
0x96	0x2013	#EN DASH
0x97	0x2014	#EM DASH
0x98		#UNDEFINED
0x99	0x2122	#TRADE MARK SIGN
0x9A		#UNDEFINED
0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
0x9C		#UNDEFINED
0x9D		#UNDEFINED
0x9E		#UNDEFINED
0x9F		#UNDEFINED
0xA0	0x00A0	#NO-BREAK SPACE
0xA1	0x0385	#GREEK DIALYTIKA TONOS
0xA2	0x0386	#GREEK CAPITAL LETTER ALPHA WITH TONOS
0xA3	0x00A3	#POUND SIGN
0xA4	0x00A4	#CURRENCY SIGN
0xA5	0x00A5	#YEN SIGN
0xA6	0x00A6	#BROKEN BAR
0xA7	0x00A7	#SECTION SIGN
0xA8	0x00A8	#DIAERESIS
0xA9	0x00A9	#COPYRIGHT SIGN
0xAA		#UNDEFINED
0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xAC	0x00AC	#NOT SIGN
0xAD	0x00AD	#SOFT HYPHEN
0xAE	0x00AE	#REGISTERED SIGN
0xAF	0x2015	#HORIZONTAL BAR
0xB0	0x00B0	#DEGREE SIGN
0xB1	0x00B1	#PLUS-MINUS SIGN
0xB2	0x00B2	#SUPERSCRIPT TWO
0xB3	0x00B3	#SUPERSCRIPT THREE
0xB4	0x0384	#GREEK TONOS
0xB5	0x00B5	#MICRO SIGN
0xB6	0x00B6	#PILCROW SIGN
0xB7	0x00B7	#MIDDLE DOT
0xB8	0x0388	#GREEK CAPITAL LETTER EPSILON WITH TONOS
0xB9	0x0389	#GREEK CAPITAL LETTER ETA WITH TONOS
0xBA	0x038A	#GREEK CAPITAL LETTER IOTA WITH TONOS
0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xBC	0x038C	#GREEK CAPITAL LETTER OMICRON WITH TONOS
0xBD	0x00BD	#VULGAR FRACTION ONE HALF
0xBE	0x038E	#GREEK CAPITAL LETTER UPSILON WITH TONOS
0xBF	0x038F	#GREEK CAPITAL LETTER OMEGA WITH TONOS
0xC0	0x0390	#GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
0xC1	0x0391	#GREEK CAPITAL LETTER ALPHA
0xC2	0x0392	#GREEK CAPITAL LETTER BETA
0xC3	0x0393	#GREEK CAPITAL LETTER GAMMA
0xC4	0x0394	#GREEK CAPITAL LETTER DELTA
0xC5	0x0395	#GREEK CAPITAL LETTER EPSILON
0xC6	0x0396	#GREEK CAPITAL LETTER ZETA
0xC7	0x0397	#GREEK CAPITAL LETTER ETA
0xC8	0x0398	#GREEK CAPITAL LETTER THETA
0xC9	0x0399	#GREEK CAPITAL LETTER IOTA
0xCA	0x039A	#GREEK CAPITAL LETTER KAPPA
0xCB	0x039B	#GREEK CAPITAL LETTER LAMDA
0xCC	0x039C	#GREEK CAPITAL LETTER MU
0xCD	0x039D	#GREEK CAPITAL LETTER NU
0xCE	0x039E	#GREEK CAPITAL LETTER XI
0xCF	0x039F	#GREEK CAPITAL LETTER OMICRON
0xD0	0x03A0	#GREEK CAPITAL LETTER PI
0xD1	0x03A1	#GREEK CAPITAL LETTER RHO
0xD2		#UNDEFINED
0xD3	0x03A3	#GREEK CAPITAL LETTER SIGMA
0xD4	0x03A4	#GREEK CAPITAL LETTER TAU
0xD5	0x03A5	#GREEK CAPITAL LETTER UPSILON
0xD6	0x03A6	#GREEK CAPITAL LETTER PHI
0xD7	0x03A7	#GREEK CAPITAL LETTER CHI
0xD8	0x03A8	#GREEK CAPITAL LETTER PSI
0xD9	0x03A9	#GREEK CAPITAL LETTER OMEGA
0xDA	0x03AA	#GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
0xDB	0x03AB	#GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
0xDC	0x03AC	#GREEK SMALL LETTER ALPHA WITH TONOS
0xDD	0x03AD	#GREEK SMALL LETTER EPSILON WITH TONOS
0xDE	0x03AE	#GREEK SMALL LETTER ETA WITH TONOS
0xDF	0x03AF	#GREEK SMALL LETTER IOTA WITH TONOS
0xE0	0x03B0	#GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
0xE1	0x03B1	#GREEK SMALL LETTER ALPHA
0xE2	0x03B2	#GREEK SMALL LETTER BETA
0xE3	0x03B3	#GREEK SMALL LETTER GAMMA
0xE4	0x03B4	#GREEK SMALL LETTER DELTA
0xE5	0x03B5	#GREEK SMALL LETTER EPSILON
0xE6	0x03B6	#GREEK SMALL LETTER ZETA
0xE7	0x03B7	#GREEK SMALL LETTER ETA
0xE8	0x03B8	#GREEK SMALL LETTER THETA
0xE9	0x03B9	#GREEK SMALL LETTER IOTA
0xEA	0x03BA	#GREEK SMALL LETTER KAPPA
0xEB	0x03BB	#GREEK SMALL LETTER LAMDA
0xEC	0x03BC	#GREEK SMALL LETTER MU
0xED	0x03BD	#GREEK SMALL LETTER NU
0xEE	0x03BE	#GREEK SMALL LETTER XI
0xEF	0x03BF	#GREEK SMALL LETTER OMICRON
0xF0	0x03C0	#GREEK SMALL LETTER PI
0xF1	0x03C1	#GREEK SMALL LETTER RHO
0xF2	0x03C2	#GREEK SMALL LETTER FINAL SIGMA
0xF3	0x03C3	#GREEK SMALL LETTER SIGMA
0xF4	0x03C4	#GREEK SMALL LETTER TAU
0xF5	0x03C5	#GREEK SMALL LETTER UPSILON
0xF6	0x03C6	#GREEK SMALL LETTER PHI
0xF7	0x03C7	#GREEK SMALL LETTER CHI
0xF8	0x03C8	#GREEK SMALL LETTER PSI
0xF9	0x03C9	#GREEK SMALL LETTER OMEGA
0xFA	0x03CA	#GREEK SMALL LETTER IOTA WITH DIALYTIKA
0xFB	0x03CB	#GREEK SMALL LETTER UPSILON WITH DIALYTIKA
0xFC	0x03CC	#GREEK SMALL LETTER OMICRON WITH TONOS
0xFD	0x03CD	#GREEK SMALL LETTER UPSILON WITH TONOS
0xFE	0x03CE	#GREEK SMALL LETTER OMEGA WITH TONOS
0xFF		#UNDEFINED



Added tools/encoding/cp1254.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
269
270
271
272
273
274
275
#
#    Name:     cp1254_WinTurkish to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp1254_WinTurkish code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp1254_WinTurkish 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		#UNDEFINED
0x81		#UNDEFINED
0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
0x83	0x0192	#LATIN SMALL LETTER F WITH HOOK
0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
0x85	0x2026	#HORIZONTAL ELLIPSIS
0x86	0x2020	#DAGGER
0x87	0x2021	#DOUBLE DAGGER
0x88	0x02C6	#MODIFIER LETTER CIRCUMFLEX ACCENT
0x89	0x2030	#PER MILLE SIGN
0x8A	0x0160	#LATIN CAPITAL LETTER S WITH CARON
0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
0x8C	0x0152	#LATIN CAPITAL LIGATURE OE
0x8D		#UNDEFINED
0x8E		#UNDEFINED
0x8F		#UNDEFINED
0x90		#UNDEFINED
0x91	0x2018	#LEFT SINGLE QUOTATION MARK
0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
0x95	0x2022	#BULLET
0x96	0x2013	#EN DASH
0x97	0x2014	#EM DASH
0x98	0x02DC	#SMALL TILDE
0x99	0x2122	#TRADE MARK SIGN
0x9A	0x0161	#LATIN SMALL LETTER S WITH CARON
0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
0x9C	0x0153	#LATIN SMALL LIGATURE OE
0x9D		#UNDEFINED
0x9E		#UNDEFINED
0x9F	0x0178	#LATIN CAPITAL LETTER Y WITH DIAERESIS
0xA0	0x00A0	#NO-BREAK SPACE
0xA1	0x00A1	#INVERTED EXCLAMATION MARK
0xA2	0x00A2	#CENT SIGN
0xA3	0x00A3	#POUND SIGN
0xA4	0x00A4	#CURRENCY SIGN
0xA5	0x00A5	#YEN SIGN
0xA6	0x00A6	#BROKEN BAR
0xA7	0x00A7	#SECTION SIGN
0xA8	0x00A8	#DIAERESIS
0xA9	0x00A9	#COPYRIGHT SIGN
0xAA	0x00AA	#FEMININE ORDINAL INDICATOR
0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xAC	0x00AC	#NOT SIGN
0xAD	0x00AD	#SOFT HYPHEN
0xAE	0x00AE	#REGISTERED SIGN
0xAF	0x00AF	#MACRON
0xB0	0x00B0	#DEGREE SIGN
0xB1	0x00B1	#PLUS-MINUS SIGN
0xB2	0x00B2	#SUPERSCRIPT TWO
0xB3	0x00B3	#SUPERSCRIPT THREE
0xB4	0x00B4	#ACUTE ACCENT
0xB5	0x00B5	#MICRO SIGN
0xB6	0x00B6	#PILCROW SIGN
0xB7	0x00B7	#MIDDLE DOT
0xB8	0x00B8	#CEDILLA
0xB9	0x00B9	#SUPERSCRIPT ONE
0xBA	0x00BA	#MASCULINE ORDINAL INDICATOR
0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xBC	0x00BC	#VULGAR FRACTION ONE QUARTER
0xBD	0x00BD	#VULGAR FRACTION ONE HALF
0xBE	0x00BE	#VULGAR FRACTION THREE QUARTERS
0xBF	0x00BF	#INVERTED QUESTION MARK
0xC0	0x00C0	#LATIN CAPITAL LETTER A WITH GRAVE
0xC1	0x00C1	#LATIN CAPITAL LETTER A WITH ACUTE
0xC2	0x00C2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xC3	0x00C3	#LATIN CAPITAL LETTER A WITH TILDE
0xC4	0x00C4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0xC5	0x00C5	#LATIN CAPITAL LETTER A WITH RING ABOVE
0xC6	0x00C6	#LATIN CAPITAL LIGATURE AE
0xC7	0x00C7	#LATIN CAPITAL LETTER C WITH CEDILLA
0xC8	0x00C8	#LATIN CAPITAL LETTER E WITH GRAVE
0xC9	0x00C9	#LATIN CAPITAL LETTER E WITH ACUTE
0xCA	0x00CA	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xCB	0x00CB	#LATIN CAPITAL LETTER E WITH DIAERESIS
0xCC	0x00CC	#LATIN CAPITAL LETTER I WITH GRAVE
0xCD	0x00CD	#LATIN CAPITAL LETTER I WITH ACUTE
0xCE	0x00CE	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xCF	0x00CF	#LATIN CAPITAL LETTER I WITH DIAERESIS
0xD0	0x011E	#LATIN CAPITAL LETTER G WITH BREVE
0xD1	0x00D1	#LATIN CAPITAL LETTER N WITH TILDE
0xD2	0x00D2	#LATIN CAPITAL LETTER O WITH GRAVE
0xD3	0x00D3	#LATIN CAPITAL LETTER O WITH ACUTE
0xD4	0x00D4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xD5	0x00D5	#LATIN CAPITAL LETTER O WITH TILDE
0xD6	0x00D6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0xD7	0x00D7	#MULTIPLICATION SIGN
0xD8	0x00D8	#LATIN CAPITAL LETTER O WITH STROKE
0xD9	0x00D9	#LATIN CAPITAL LETTER U WITH GRAVE
0xDA	0x00DA	#LATIN CAPITAL LETTER U WITH ACUTE
0xDB	0x00DB	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xDC	0x00DC	#LATIN CAPITAL LETTER U WITH DIAERESIS
0xDD	0x0130	#LATIN CAPITAL LETTER I WITH DOT ABOVE
0xDE	0x015E	#LATIN CAPITAL LETTER S WITH CEDILLA
0xDF	0x00DF	#LATIN SMALL LETTER SHARP S
0xE0	0x00E0	#LATIN SMALL LETTER A WITH GRAVE
0xE1	0x00E1	#LATIN SMALL LETTER A WITH ACUTE
0xE2	0x00E2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0xE3	0x00E3	#LATIN SMALL LETTER A WITH TILDE
0xE4	0x00E4	#LATIN SMALL LETTER A WITH DIAERESIS
0xE5	0x00E5	#LATIN SMALL LETTER A WITH RING ABOVE
0xE6	0x00E6	#LATIN SMALL LIGATURE AE
0xE7	0x00E7	#LATIN SMALL LETTER C WITH CEDILLA
0xE8	0x00E8	#LATIN SMALL LETTER E WITH GRAVE
0xE9	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
0xEA	0x00EA	#LATIN SMALL LETTER E WITH CIRCUMFLEX
0xEB	0x00EB	#LATIN SMALL LETTER E WITH DIAERESIS
0xEC	0x00EC	#LATIN SMALL LETTER I WITH GRAVE
0xED	0x00ED	#LATIN SMALL LETTER I WITH ACUTE
0xEE	0x00EE	#LATIN SMALL LETTER I WITH CIRCUMFLEX
0xEF	0x00EF	#LATIN SMALL LETTER I WITH DIAERESIS
0xF0	0x011F	#LATIN SMALL LETTER G WITH BREVE
0xF1	0x00F1	#LATIN SMALL LETTER N WITH TILDE
0xF2	0x00F2	#LATIN SMALL LETTER O WITH GRAVE
0xF3	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
0xF4	0x00F4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0xF5	0x00F5	#LATIN SMALL LETTER O WITH TILDE
0xF6	0x00F6	#LATIN SMALL LETTER O WITH DIAERESIS
0xF7	0x00F7	#DIVISION SIGN
0xF8	0x00F8	#LATIN SMALL LETTER O WITH STROKE
0xF9	0x00F9	#LATIN SMALL LETTER U WITH GRAVE
0xFA	0x00FA	#LATIN SMALL LETTER U WITH ACUTE
0xFB	0x00FB	#LATIN SMALL LETTER U WITH CIRCUMFLEX
0xFC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
0xFD	0x0131	#LATIN SMALL LETTER DOTLESS I
0xFE	0x015F	#LATIN SMALL LETTER S WITH CEDILLA
0xFF	0x00FF	#LATIN SMALL LETTER Y WITH DIAERESIS



Added tools/encoding/cp1255.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
269
270
271
272
273
274
275
#
#    Name:     cp1255_WinHebrew to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp1255_WinHebrew code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp1255_WinHebrew 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-QUOTE
0x28	0x0028	#OPENING PARENTHESIS
0x29	0x0029	#CLOSING PARENTHESIS
0x2A	0x002A	#ASTERISK
0x2B	0x002B	#PLUS SIGN
0x2C	0x002C	#COMMA
0x2D	0x002D	#HYPHEN-MINUS
0x2E	0x002E	#PERIOD
0x2F	0x002F	#SLASH
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	#OPENING SQUARE BRACKET
0x5C	0x005C	#BACKSLASH
0x5D	0x005D	#CLOSING SQUARE BRACKET
0x5E	0x005E	#SPACING CIRCUMFLEX
0x5F	0x005F	#SPACING UNDERSCORE
0x60	0x0060	#SPACING GRAVE
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	#OPENING CURLY BRACKET
0x7C	0x007C	#VERTICAL BAR
0x7D	0x007D	#CLOSING CURLY BRACKET
0x7E	0x007E	#TILDE
0x7F	0x007F	#DELETE
0x80		#UNDEFINED
0x81		#UNDEFINED
0x82	0x201A	#LOW SINGLE COMMA QUOTATION MARK
0x83	0x0192	#LATIN SMALL LETTER SCRIPT F
0x84	0x201E	#LOW DOUBLE COMMA QUOTATION MARK
0x85	0x2026	#HORIZONTAL ELLIPSIS
0x86	0x2020	#DAGGER
0x87	0x2021	#DOUBLE DAGGER
0x88	0x02C6	#MODIFIER LETTER CIRCUMFLEX
0x89	0x2030	#PER MILLE SIGN
0x8A		#UNDEFINED
0x8B	0x2039	#LEFT POINTING SINGLE GUILLEMET
0x8C		#UNDEFINED
0x8D		#UNDEFINED
0x8E		#UNDEFINED
0x8F		#UNDEFINED
0x90		#UNDEFINED
0x91	0x2018	#SINGLE TURNED COMMA QUOTATION MARK
0x92	0x2019	#SINGLE COMMA QUOTATION MARK
0x93	0x201C	#DOUBLE TURNED COMMA QUOTATION MARK
0x94	0x201D	#DOUBLE COMMA QUOTATION MARK
0x95	0x2022	#BULLET
0x96	0x2013	#EN DASH
0x97	0x2014	#EM DASH
0x98	0x02DC	#SPACING TILDE
0x99	0x2122	#TRADEMARK
0x9A		#UNDEFINED
0x9B	0x203A	#RIGHT POINTING SINGLE GUILLEMET
0x9C		#UNDEFINED
0x9D		#UNDEFINED
0x9E		#UNDEFINED
0x9F		#UNDEFINED
0xA0	0x00A0	#NON-BREAKING SPACE
0xA1		#UNDEFINED
0xA2	0x00A2	#CENT SIGN
0xA3	0x00A3	#POUND SIGN
0xA4	0x20AA	#NEW SHEQEL SIGN
0xA5	0x00A5	#YEN SIGN
0xA6	0x00A6	#BROKEN VERTICAL BAR
0xA7	0x00A7	#SECTION SIGN
0xA8	0x00A8	#SPACING DIAERESIS
0xA9	0x00A9	#COPYRIGHT SIGN
0xAA		#UNDEFINED
0xAB	0x00AB	#LEFT POINTING GUILLEMET
0xAC	0x00AC	#NOT SIGN
0xAD	0x00AD	#SOFT HYPHEN
0xAE	0x00AE	#REGISTERED TRADE MARK SIGN
0xAF	0x00AF	#SPACING MACRON
0xB0	0x00B0	#DEGREE SIGN
0xB1	0x00B1	#PLUS-OR-MINUS SIGN
0xB2	0x00B2	#SUPERSCRIPT DIGIT TWO
0xB3	0x00B3	#SUPERSCRIPT DIGIT THREE
0xB4	0x00B4	#SPACING ACUTE
0xB5	0x00B5	#MICRO SIGN
0xB6	0x00B6	#PARAGRAPH SIGN
0xB7	0x00B7	#MIDDLE DOT
0xB8		#UNDEFINED
0xB9	0x00B9	#SUPERSCRIPT DIGIT ONE
0xBA		#UNDEFINED
0xBB	0x00BB	#RIGHT POINTING GUILLEMET
0xBC	0x00BC	#FRACTION ONE QUARTER
0xBD	0x00BD	#FRACTION ONE HALF
0xBE	0x00BE	#FRACTION THREE QUARTERS
0xBF		#UNDEFINED
0xC0	0x05B0	#HEBREW POINT SHEVA
0xC1	0x05B1	#HEBREW POINT HATAF SEGOL
0xC2	0x05B2	#HEBREW POINT HATAF PATAH
0xC3	0x05B3	#HEBREW POINT HATAF QAMATS
0xC4	0x05B4	#HEBREW POINT HIRIQ
0xC5	0x05B5	#HEBREW POINT TSERE
0xC6	0x05B6	#HEBREW POINT SEGOL
0xC7	0x05B7	#HEBREW POINT PATAH
0xC8	0x05B8	#HEBREW POINT QAMATS
0xC9	0x05B9	#HEBREW POINT HOLAM
0xCA	0x05BA	#HEBREW POINT
0xCB	0x05BB	#HEBREW POINT QUBUTS
0xCC	0x05BC	#HEBREW POINT DAGESH
0xCD	0x05BD	#HEBREW POINT METEG
0xCE	0x05BE	#HEBREW PUNCTUATION MAQAF
0xCF	0x05BF	#HEBREW POINT RAFE
0xD0	0x05C0	#HEBREW POINT PASEQ
0xD1	0x05C1	#HEBREW POINT SHIN DOT
0xD2	0x05C2	#HEBREW POINT SIN DOT
0xD3	0x05C3	#HEBREW PUNCTUATION SOF PASUQ
0xD4	0x05F0	#HEBREW LETTER DOUBLE VAV
0xD5	0x05F1	#HEBREW LETTER VAV YOD
0xD6	0x05F2	#HEBREW LETTER DOUBLE YOD
0xD7		#UNDEFINED
0xD8		#UNDEFINED
0xD9		#UNDEFINED
0xDA		#UNDEFINED
0xDB		#UNDEFINED
0xDC		#UNDEFINED
0xDD		#UNDEFINED
0xDE		#UNDEFINED
0xDF		#UNDEFINED
0xE0	0x05D0	#HEBREW LETTER ALEF
0xE1	0x05D1	#HEBREW LETTER BET
0xE2	0x05D2	#HEBREW LETTER GIMEL
0xE3	0x05D3	#HEBREW LETTER DALET
0xE4	0x05D4	#HEBREW LETTER HE
0xE5	0x05D5	#HEBREW LETTER VAV
0xE6	0x05D6	#HEBREW LETTER ZAYIN
0xE7	0x05D7	#HEBREW LETTER HET
0xE8	0x05D8	#HEBREW LETTER TET
0xE9	0x05D9	#HEBREW LETTER YOD
0xEA	0x05DA	#HEBREW LETTER FINAL KAF
0xEB	0x05DB	#HEBREW LETTER KAF
0xEC	0x05DC	#HEBREW LETTER LAMED
0xED	0x05DD	#HEBREW LETTER FINAL MEM
0xEE	0x05DE	#HEBREW LETTER MEM
0xEF	0x05DF	#HEBREW LETTER FINAL NUN
0xF0	0x05E0	#HEBREW LETTER NUN
0xF1	0x05E1	#HEBREW LETTER SAMEKH
0xF2	0x05E2	#HEBREW LETTER AYIN
0xF3	0x05E3	#HEBREW LETTER FINAL PE
0xF4	0x05E4	#HEBREW LETTER PE
0xF5	0x05E5	#HEBREW LETTER FINAL TSADI
0xF6	0x05E6	#HEBREW LETTER TSADI
0xF7	0x05E7	#HEBREW LETTER QOF
0xF8	0x05E8	#HEBREW LETTER RESH
0xF9	0x05E9	#HEBREW LETTER SHIN
0xFA	0x05EA	#HEBREW LETTER TAV
0xFB		#UNDEFINED
0xFC		#UNDEFINED
0xFD	0x200E	#LEFT-TO-RIGHT MARK
0xFE	0x200F	#RIGHT-TO-LEFT MARK
0xFF		#UNDEFINED



Added tools/encoding/cp1256.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
269
270
271
272
273
274
275
#
#    Name:     cp1256_WinArabic to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp1256_WinArabic code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp1256_WinArabic 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-QUOTE
0x28	0x0028	#OPENING PARENTHESIS
0x29	0x0029	#CLOSING PARENTHESIS
0x2A	0x002A	#ASTERISK
0x2B	0x002B	#PLUS SIGN
0x2C	0x002C	#COMMA
0x2D	0x002D	#HYPHEN-MINUS
0x2E	0x002E	#PERIOD
0x2F	0x002F	#SLASH
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	#OPENING SQUARE BRACKET
0x5C	0x005C	#BACKSLASH
0x5D	0x005D	#CLOSING SQUARE BRACKET
0x5E	0x005E	#SPACING CIRCUMFLEX
0x5F	0x005F	#SPACING UNDERSCORE
0x60	0x0060	#SPACING GRAVE
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	#OPENING CURLY BRACKET
0x7C	0x007C	#VERTICAL BAR
0x7D	0x007D	#CLOSING CURLY BRACKET
0x7E	0x007E	#TILDE
0x7F	0x007F	#DELETE
0x80		#UNDEFINED
0x81	0x067E	#ARABIC TAA WITH THREE DOTS BELOW
0x82	0x201A	#LOW SINGLE COMMA QUOTATION MARK
0x83	0x0192	#LATIN SMALL LETTER SCRIPT F
0x84	0x201E	#LOW DOUBLE COMMA QUOTATION MARK
0x85	0x2026	#HORIZONTAL ELLIPSIS
0x86	0x2020	#DAGGER
0x87	0x2021	#DOUBLE DAGGER
0x88	0x02C6	#MODIFIER LETTER CIRCUMFLEX
0x89	0x2030	#PER MILLE SIGN
0x8A		#UNDEFINED
0x8B	0x2039	#LEFT POINTING SINGLE GUILLEMET
0x8C	0x0152	#LATIN CAPITAL LETTER O E
0x8D	0x0686	#ARABIC HAA WITH MIDDLE THREE DOTS DOWNWARD
0x8E	0x0698	#ARABIC RA WITH THREE DOTS ABOVE
0x8F		#UNDEFINED
0x90	0x06AF	#ARABIC GAF
0x91	0x2018	#SINGLE TURNED COMMA QUOTATION MARK
0x92	0x2019	#SINGLE COMMA QUOTATION MARK
0x93	0x201C	#DOUBLE TURNED COMMA QUOTATION MARK
0x94	0x201D	#DOUBLE COMMA QUOTATION MARK
0x95	0x2022	#BULLET
0x96	0x2013	#EN DASH
0x97	0x2014	#EM DASH
0x98		#UNDEFINED
0x99	0x2122	#TRADEMARK
0x9A		#UNDEFINED
0x9B	0x203A	#RIGHT POINTING SINGLE GUILLEMET
0x9C	0x0153	#LATIN SMALL LETTER O E
0x9D	0x200C	#ZERO WIDTH NON-JOINER
0x9E	0x200D	#ZERO WIDTH JOINER
0x9F		#UNDEFINED
0xA0	0x00A0	#NON-BREAKING SPACE
0xA1	0x060C	#ARABIC COMMA
0xA2	0x00A2	#CENT SIGN
0xA3	0x00A3	#POUND SIGN
0xA4	0x00A4	#CURRENCY SIGN
0xA5	0x00A5	#YEN SIGN
0xA6	0x00A6	#BROKEN VERTICAL BAR
0xA7	0x00A7	#SECTION SIGN
0xA8	0x00A8	#SPACING DIAERESIS
0xA9	0x00A9	#COPYRIGHT SIGN
0xAA		#UNDEFINED
0xAB	0x00AB	#LEFT POINTING GUILLEMET
0xAC	0x00AC	#NOT SIGN
0xAD	0x00AD	#SOFT HYPHEN
0xAE	0x00AE	#REGISTERED TRADE MARK SIGN
0xAF	0x00AF	#SPACING MACRON
0xB0	0x00B0	#DEGREE SIGN
0xB1	0x00B1	#PLUS-OR-MINUS SIGN
0xB2	0x00B2	#SUPERSCRIPT DIGIT TWO
0xB3	0x00B3	#SUPERSCRIPT DIGIT THREE
0xB4	0x00B4	#SPACING ACUTE
0xB5	0x00B5	#MICRO SIGN
0xB6	0x00B6	#PARAGRAPH SIGN
0xB7	0x00B7	#MIDDLE DOT
0xB8	0x00B8	#SPACING CEDILLA
0xB9	0x00B9	#SUPERSCRIPT DIGIT ONE
0xBA	0x061B	#ARABIC SEMICOLON
0xBB	0x00BB	#RIGHT POINTING GUILLEMET
0xBC	0x00BC	#FRACTION ONE QUARTER
0xBD	0x00BD	#FRACTION ONE HALF
0xBE	0x00BE	#FRACTION THREE QUARTERS
0xBF	0x061F	#ARABIC QUESTION MARK
0xC0		#UNDEFINED
0xC1	0x0621	#ARABIC LETTER HAMZAH
0xC2	0x0622	#ARABIC LETTER MADDAH ON ALEF
0xC3	0x0623	#ARABIC LETTER HAMZAH ON ALEF
0xC4	0x0624	#ARABIC LETTER HAMZAH ON WAW
0xC5	0x0625	#ARABIC LETTER HAMZAH UNDER ALEF
0xC6	0x0626	#ARABIC LETTER HAMZAH ON YA
0xC7	0x0627	#ARABIC LETTER ALEF
0xC8	0x0628	#ARABIC LETTER BAA
0xC9	0x0629	#ARABIC LETTER TAA MARBUTAH
0xCA	0x062A	#ARABIC LETTER TAA
0xCB	0x062B	#ARABIC LETTER THAA
0xCC	0x062C	#ARABIC LETTER JEEM
0xCD	0x062D	#ARABIC LETTER HAA
0xCE	0x062E	#ARABIC LETTER KHAA
0xCF	0x062F	#ARABIC LETTER DAL
0xD0	0x0630	#ARABIC LETTER THAL
0xD1	0x0631	#ARABIC LETTER RA
0xD2	0x0632	#ARABIC LETTER ZAIN
0xD3	0x0633	#ARABIC LETTER SEEN
0xD4	0x0634	#ARABIC LETTER SHEEN
0xD5	0x0635	#ARABIC LETTER SAD
0xD6	0x0636	#ARABIC LETTER DAD
0xD7	0x00D7	#MULTIPLICATION SIGN
0xD8	0x0637	#ARABIC LETTER TAH
0xD9	0x0638	#ARABIC LETTER DHAH
0xDA	0x0639	#ARABIC LETTER AIN
0xDB	0x063A	#ARABIC LETTER GHAIN
0xDC	0x0640	#ARABIC TATWEEL
0xDD	0x0641	#ARABIC LETTER FA
0xDE	0x0642	#ARABIC LETTER QAF
0xDF	0x0643	#ARABIC LETTER CAF
0xE0	0x00E0	#LATIN SMALL LETTER A GRAVE
0xE1	0x0644	#ARABIC LETTER LAM
0xE2	0x00E2	#LATIN SMALL LETTER A CIRCUMFLEX
0xE3	0x0645	#ARABIC LETTER MEEM
0xE4	0x0646	#ARABIC LETTER NOON
0xE5	0x0647	#ARABIC LETTER HA
0xE6	0x0648	#ARABIC LETTER WAW
0xE7	0x00E7	#LATIN SMALL LETTER C CEDILLA
0xE8	0x00E8	#LATIN SMALL LETTER E GRAVE
0xE9	0x00E9	#LATIN SMALL LETTER E ACUTE
0xEA	0x00EA	#LATIN SMALL LETTER E CIRCUMFLEX
0xEB	0x00EB	#LATIN SMALL LETTER E DIAERESIS
0xEC	0x0649	#ARABIC LETTER ALEF MAQSURAH
0xED	0x064A	#ARABIC LETTER YA
0xEE	0x00EE	#LATIN SMALL LETTER I CIRCUMFLEX
0xEF	0x00EF	#LATIN SMALL LETTER I DIAERESIS
0xF0	0x064B	#ARABIC FATHATAN
0xF1	0x064C	#ARABIC DAMMATAN
0xF2	0x064D	#ARABIC KASRATAN
0xF3	0x064E	#ARABIC FATHAH
0xF4	0x00F4	#LATIN SMALL LETTER O CIRCUMFLEX
0xF5	0x064F	#ARABIC DAMMAH
0xF6	0x0650	#ARABIC KASRAH
0xF7	0x00F7	#DIVISION SIGN
0xF8	0x0651	#ARABIC SHADDAH
0xF9	0x00F9	#LATIN SMALL LETTER U GRAVE
0xFA	0x0652	#ARABIC SUKUN
0xFB	0x00FB	#LATIN SMALL LETTER U CIRCUMFLEX
0xFC	0x00FC	#LATIN SMALL LETTER U DIAERESIS
0xFD	0x200E	#LEFT-TO-RIGHT MARK
0xFE	0x200F	#RIGHT-TO-LEFT MARK
0xFF		#UNDEFINED



Added tools/encoding/cp1257.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
269
270
271
272
273
274
275
#
#    Name:     cp1257_WinBaltic to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp1257_WinBaltic code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp1257_WinBaltic 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 0
0x31	0x0031	#DIGIT 1
0x32	0x0032	#DIGIT 2
0x33	0x0033	#DIGIT 3
0x34	0x0034	#DIGIT 4
0x35	0x0035	#DIGIT 5
0x36	0x0036	#DIGIT 6
0x37	0x0037	#DIGIT 7
0x38	0x0038	#DIGIT 8
0x39	0x0039	#DIGIT 9
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 A
0x42	0x0042	#LATIN CAPITAL B
0x43	0x0043	#LATIN CAPITAL C
0x44	0x0044	#LATIN CAPITAL D
0x45	0x0045	#LATIN CAPITAL E
0x46	0x0046	#LATIN CAPITAL F
0x47	0x0047	#LATIN CAPITAL G
0x48	0x0048	#LATIN CAPITAL H
0x49	0x0049	#LATIN CAPITAL I
0x4A	0x004A	#LATIN CAPITAL J
0x4B	0x004B	#LATIN CAPITAL K
0x4C	0x004C	#LATIN CAPITAL L
0x4D	0x004D	#LATIN CAPITAL M
0x4E	0x004E	#LATIN CAPITAL N
0x4F	0x004F	#LATIN CAPITAL O
0x50	0x0050	#LATIN CAPITAL P
0x51	0x0051	#LATIN CAPITAL Q
0x52	0x0052	#LATIN CAPITAL R
0x53	0x0053	#LATIN CAPITAL S
0x54	0x0054	#LATIN CAPITAL T
0x55	0x0055	#LATIN CAPITAL U
0x56	0x0056	#LATIN CAPITAL V
0x57	0x0057	#LATIN CAPITAL W
0x58	0x0058	#LATIN CAPITAL X
0x59	0x0059	#LATIN CAPITAL Y
0x5A	0x005A	#LATIN CAPITAL Z
0x5B	0x005B	#LEFT SQUARE BRACKET
0x5C	0x005C	#BACKSLASH
0x5D	0x005D	#RIGHT SQUARE BRACKET
0x5E	0x005E	#CIRCUMFLEX
0x5F	0x005F	#LOW LINE
0x60	0x0060	#GRAVE
0x61	0x0061	#LATIN SMALL A
0x62	0x0062	#LATIN SMALL B
0x63	0x0063	#LATIN SMALL C
0x64	0x0064	#LATIN SMALL D
0x65	0x0065	#LATIN SMALL E
0x66	0x0066	#LATIN SMALL F
0x67	0x0067	#LATIN SMALL G
0x68	0x0068	#LATIN SMALL H
0x69	0x0069	#LATIN SMALL I
0x6A	0x006A	#LATIN SMALL J
0x6B	0x006B	#LATIN SMALL K
0x6C	0x006C	#LATIN SMALL L
0x6D	0x006D	#LATIN SMALL M
0x6E	0x006E	#LATIN SMALL N
0x6F	0x006F	#LATIN SMALL O
0x70	0x0070	#LATIN SMALL P
0x71	0x0071	#LATIN SMALL Q
0x72	0x0072	#LATIN SMALL R
0x73	0x0073	#LATIN SMALL S
0x74	0x0074	#LATIN SMALL T
0x75	0x0075	#LATIN SMALL U
0x76	0x0076	#LATIN SMALL V
0x77	0x0077	#LATIN SMALL W
0x78	0x0078	#LATIN SMALL X
0x79	0x0079	#LATIN SMALL Y
0x7A	0x007A	#LATIN SMALL Z
0x7B	0x007B	#LEFT CURLY BRACKET
0x7C	0x007C	#VERTICAL LINE
0x7D	0x007D	#RIGHT CURLY BRACKET
0x7E	0x007E	#TILDE
0x7F	0x007F	#DELETE
0x80		#UNDEFINED
0x81		#UNDEFINED
0x82	0x201A	#LOW SINGLE COMMA QUOTATION MARK
0x83		#UNDEFINED
0x84	0x201E	#LOW DOUBLE COMMA QUOTATION MARK
0x85	0x2026	#HORIZONTAL ELLIPSIS
0x86	0x2020	#DAGGER
0x87	0x2021	#DOUBLE DAGGER
0x88		#UNDEFINED
0x89	0x2030	#PER MILLE SIGN
0x8A		#UNDEFINED
0x8B	0x2039	#LEFT POINTING SINGLE GUILLEMENT
0x8C		#UNDEFINED
0x8D	0x00A8	#DIAERESIS
0x8E	0x02C7	#HACEK
0x8F	0x00B8	#CEDILLA
0x90		#UNDEFINED
0x91	0x2018	#LEFT SINGLE QUOTATION MARK
0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
0x95	0x2022	#BULLET
0x96	0x2013	#EN DASH
0x97	0x2014	#EM DASH
0x98		#UNDEFINED
0x99	0x2122	#TRADE MARK SIGN
0x9A		#UNDEFINED
0x9B	0x203A	#RIGHT POINTING SINGLE GUILLEMENT
0x9C		#UNDEFINED
0x9D	0x00AF	#MACRON
0x9E	0x02DB	#OGONEK
0x9F		#UNDEFINED
0xA0	0x00A0	#NO-BREAK SPACE
0xA1		#UNDEFINED
0xA2	0x00A2	#CENT SIGN
0xA3	0x00A3	#POUND SIGN
0xA4	0x00A4	#CURRENCY SIGN
0xA5		#UNDEFINED
0xA6	0x00A6	#BROKEN BAR
0xA7	0x00A7	#SECTION SIGN
0xA8	0x00D8	#LATIN CAPITAL O STROKE
0xA9	0x00A9	#COPYRIGHT SIGN
0xAA	0x0156	#LATIN CAPITAL R CEDILLA
0xAB	0x00AB	#LEFT POINTING GUILLEMENT
0xAC	0x00AC	#NOT SIGN
0xAD	0x00AD	#SOFT HYPHEN
0xAE	0x00AE	#REGISTERED SIGN
0xAF	0x00C6	#LATIN CAPITAL AE LIGATURE
0xB0	0x00B0	#DEGREE SIGN
0xB1	0x00B1	#PLUS-MINUS SIGN
0xB2	0x00B2	#SUPERSCRIPT 2
0xB3	0x00B3	#SUPERSCRIPT 3
0xB4	0x00B4	#ACUTE
0xB5	0x00B5	#MICRO SIGN
0xB6	0x00B6	#PILCROW SIGN
0xB7	0x00B7	#MIDDLE DOT
0xB8	0x00F8	#LATIN SAMLL O STROKE
0xB9	0x00B9	#SUPERSCRIPT ONE
0xBA	0x0157	#LATIN SMALL R CEDILLA
0xBB	0x00BB	#RIGHT POINTING GUILLEMENT
0xBC	0x00BC	#FRACTION 1/4
0xBD	0x00BD	#FRACTION 1/2
0xBE	0x00BE	#FRACTION 3/4
0xBF	0x00E6	#LATIN SMALL AE LIGATURE
0xC0	0x0104	#LATIN CAPITAL A OGONEK
0xC1	0x012E	#LATIN CAPITAL I OGONEK
0xC2	0x0100	#LATIN CAPITAL A MACRON
0xC3	0x0106	#LATIN CAPITAL C ACUTE
0xC4	0x00C4	#LATIN CAPITAL A DIAERESIS
0xC5	0x00C5	#LATIN CAPITAL A RING ABOVE
0xC6	0x0118	#LATIN CAPITAL E OGONEK
0xC7	0x0112	#LATIN CAPITAL E MACRON
0xC8	0x010C	#LATIN CAPITAL C HACEK
0xC9	0x00C9	#LATIN CAPITAL E ACUTE
0xCA	0x0179	#LATIN CAPITAL Z ACUTE
0xCB	0x0116	#LATIN CAPITAL E DOT ABOVE
0xCC	0x0122	#LATIN CAPITAL G CEDILLA
0xCD	0x0136	#LATIN CAPITAL K CEDILLA
0xCE	0x012A	#LATIN CAPITAL I MACRON
0xCF	0x013B	#LATIN CAPITAL L CEDILLA
0xD0	0x0160	#LATIN CAPITAL S HACEK
0xD1	0x0143	#LATIN CAPITAL N ACUTE
0xD2	0x0145	#LATIN CAPITAL N CEDILLA
0xD3	0x00D3	#LATIN CAPITAL O ACUTE
0xD4	0x014C	#LATIN CAPITAL O MACRON
0xD5	0x00D5	#LATIN CAPITAL O TILDE
0xD6	0x00D6	#LATIN CAPITAL O DIAERESIS
0xD7	0x00D7	#MULTIPLICATION SIGN
0xD8	0x0172	#LATIN CAPITAL U OGONEK
0xD9	0x0141	#LATIN CAPITAL L STROKE
0xDA	0x015A	#LATIN CAPITAL S ACUTE
0xDB	0x016A	#LATIN CAPITAL U MACRON
0xDC	0x00DC	#LATIN CAPITAL U DIAERESIS
0xDD	0x017B	#LATIN CAPITAL Z DOT ABOVE
0xDE	0x017D	#LATIN CAPITAL Z HACEK
0xDF	0x00DF	#LATIN SMALL SHARP SS
0xE0	0x0105	#LATIN SMALL A OGONEK
0xE1	0x012F	#LATIN SMALL I OGONEK
0xE2	0x0101	#LATIN SMALL A MACRON
0xE3	0x0107	#LATIN SMALL C ACUTE
0xE4	0x00E4	#LATIN SMALL A DIAERESIS
0xE5	0x00E5	#LATIN SMALL A RING ABOVE
0xE6	0x0119	#LATIN SMALL E OGONEK
0xE7	0x0113	#LATIN SMALL E MACRON
0xE8	0x010D	#LATIN SMALL C HACEK
0xE9	0x00E9	#LATIN SMALL E ACUTE
0xEA	0x017A	#LATIN SMALL Z ACUTE
0xEB	0x0117	#LATIN SMALL E DOT ABOVE
0xEC	0x0123	#LATIN SMALL G CEDILLA
0xED	0x0137	#LATIN SMALL K CEDILLA
0xEE	0x012B	#LATIN SMALL I MACRON
0xEF	0x013C	#LATIN SMALL L CEDILLA
0xF0	0x0161	#LATIN SMALL S HACEK
0xF1	0x0144	#LATIN SMALL N ACUTE
0xF2	0x0146	#LATIN SMALL N CEDILLA
0xF3	0x00F3	#LATIN SMALL O ACUTE
0xF4	0x014D	#LATIN SMALL O MACRON
0xF5	0x00F5	#LATIN SMALL O TILDE
0xF6	0x00F6	#LATIN SMALL O DIAERESIS
0xF7	0x00F7	#DIVISION SIGN
0xF8	0x0173	#LATIN SMALL U OGONEK
0xF9	0x0142	#LATIN SMALL L STROKE
0xFA	0x015B	#LATIN SMALL S ACUTE
0xFB	0x016B	#LATIN SMALL U MACRON
0xFC	0x00FC	#LATIN SMALL U DIAERESIS
0xFD	0x017C	#LATIN SMALL Z DOT ABOVE
0xFE	0x017E	#LATIN SMALL Z HACEK
0xFF	0x02D9	#DOT ABOVE



Added tools/encoding/cp1258.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
269
270
271
272
273
274
275
#
#    Name:     cp1258_WinVietnamese to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp1258_WinVietnamese code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp1258_WinVietnamese 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		#UNDEFINED
0x81		#UNDEFINED
0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
0x83	0x0192	#LATIN SMALL LETTER F WITH HOOK
0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
0x85	0x2026	#HORIZONTAL ELLIPSIS
0x86	0x2020	#DAGGER
0x87	0x2021	#DOUBLE DAGGER
0x88	0x02C6	#MODIFIER LETTER CIRCUMFLEX ACCENT
0x89	0x2030	#PER MILLE SIGN
0x8A		#UNDEFINED
0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
0x8C	0x0152	#LATIN CAPITAL LIGATURE OE
0x8D		#UNDEFINED
0x8E		#UNDEFINED
0x8F		#UNDEFINED
0x90		#UNDEFINED
0x91	0x2018	#LEFT SINGLE QUOTATION MARK
0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
0x95	0x2022	#BULLET
0x96	0x2013	#EN DASH
0x97	0x2014	#EM DASH
0x98	0x02DC	#SMALL TILDE
0x99	0x2122	#TRADE MARK SIGN
0x9A		#UNDEFINED
0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
0x9C	0x0153	#LATIN SMALL LIGATURE OE
0x9D		#UNDEFINED
0x9E		#UNDEFINED
0x9F	0x0178	#LATIN CAPITAL LETTER Y WITH DIAERESIS
0xA0	0x00A0	#NO-BREAK SPACE
0xA1	0x00A1	#INVERTED EXCLAMATION MARK
0xA2	0x00A2	#CENT SIGN
0xA3	0x00A3	#POUND SIGN
0xA4	0x00A4	#CURRENCY SIGN
0xA5	0x00A5	#YEN SIGN
0xA6	0x00A6	#BROKEN BAR
0xA7	0x00A7	#SECTION SIGN
0xA8	0x00A8	#DIAERESIS
0xA9	0x00A9	#COPYRIGHT SIGN
0xAA	0x00AA	#FEMININE ORDINAL INDICATOR
0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xAC	0x00AC	#NOT SIGN
0xAD	0x00AD	#SOFT HYPHEN
0xAE	0x00AE	#REGISTERED SIGN
0xAF	0x00AF	#MACRON
0xB0	0x00B0	#DEGREE SIGN
0xB1	0x00B1	#PLUS-MINUS SIGN
0xB2	0x00B2	#SUPERSCRIPT TWO
0xB3	0x00B3	#SUPERSCRIPT THREE
0xB4	0x00B4	#ACUTE ACCENT
0xB5	0x00B5	#MICRO SIGN
0xB6	0x00B6	#PILCROW SIGN
0xB7	0x00B7	#MIDDLE DOT
0xB8	0x00B8	#CEDILLA
0xB9	0x00B9	#SUPERSCRIPT ONE
0xBA	0x00BA	#MASCULINE ORDINAL INDICATOR
0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xBC	0x00BC	#VULGAR FRACTION ONE QUARTER
0xBD	0x00BD	#VULGAR FRACTION ONE HALF
0xBE	0x00BE	#VULGAR FRACTION THREE QUARTERS
0xBF	0x00BF	#INVERTED QUESTION MARK
0xC0	0x00C0	#LATIN CAPITAL LETTER A WITH GRAVE
0xC1	0x00C1	#LATIN CAPITAL LETTER A WITH ACUTE
0xC2	0x00C2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xC3	0x0102	#LATIN CAPITAL LETTER A WITH BREVE
0xC4	0x00C4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0xC5	0x00C5	#LATIN CAPITAL LETTER A WITH RING ABOVE
0xC6	0x00C6	#LATIN CAPITAL LIGATURE AE
0xC7	0x00C7	#LATIN CAPITAL LETTER C WITH CEDILLA
0xC8	0x00C8	#LATIN CAPITAL LETTER E WITH GRAVE
0xC9	0x00C9	#LATIN CAPITAL LETTER E WITH ACUTE
0xCA	0x00CA	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xCB	0x00CB	#LATIN CAPITAL LETTER E WITH DIAERESIS
0xCC	0x0340	#NON-SPACING GRAVE TONE MARK
0xCD	0x00CD	#LATIN CAPITAL LETTER I WITH ACUTE
0xCE	0x00CE	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xCF	0x00CF	#LATIN CAPITAL LETTER I WITH DIAERESIS
0xD0	0x0110	#LATIN CAPITAL LETTER D BAR
0xD1	0x00D1	#LATIN CAPITAL LETTER N WITH TILDE
0xD2	0x0309	#COMBINING HOOK ABOVE
0xD3	0x00D3	#LATIN CAPITAL LETTER O WITH ACUTE
0xD4	0x00D4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xD5	0x01A0	#LATIN CAPITAL LETTER O WITH HORN
0xD6	0x00D6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0xD7	0x00D7	#MULTIPLICATION SIGN
0xD8	0x00D8	#LATIN CAPITAL LETTER O WITH STROKE
0xD9	0x00D9	#LATIN CAPITAL LETTER U WITH GRAVE
0xDA	0x00DA	#LATIN CAPITAL LETTER U WITH ACUTE
0xDB	0x00DB	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xDC	0x00DC	#LATIN CAPITAL LETTER U WITH DIAERESIS
0xDD	0x01AF	#LATIN CAPITAL LETTER U WITH HORN
0xDE	0x0303	#COMBINING TILDE
0xDF	0x00DF	#LATIN SMALL LETTER SHARP S
0xE0	0x00E0	#LATIN SMALL LETTER A WITH GRAVE
0xE1	0x00E1	#LATIN SMALL LETTER A WITH ACUTE
0xE2	0x00E2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0xE3	0x0103	#LATIN SMALL LETTER A WITH BREVE
0xE4	0x00E4	#LATIN SMALL LETTER A WITH DIAERESIS
0xE5	0x00E5	#LATIN SMALL LETTER A WITH RING ABOVE
0xE6	0x00E6	#LATIN SMALL LIGATURE AE
0xE7	0x00E7	#LATIN SMALL LETTER C WITH CEDILLA
0xE8	0x00E8	#LATIN SMALL LETTER E WITH GRAVE
0xE9	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
0xEA	0x00EA	#LATIN SMALL LETTER E WITH CIRCUMFLEX
0xEB	0x00EB	#LATIN SMALL LETTER E WITH DIAERESIS
0xEC	0x0341	#NON-SPACING ACUTE TONE MARK
0xED	0x00ED	#LATIN SMALL LETTER I WITH ACUTE
0xEE	0x00EE	#LATIN SMALL LETTER I WITH CIRCUMFLEX
0xEF	0x00EF	#LATIN SMALL LETTER I WITH DIAERESIS
0xF0	0x0111	#LATIN SMALL LETTER D BAR
0xF1	0x00F1	#LATIN SMALL LETTER N WITH TILDE
0xF2	0x0323	#COMBINING DOT BELOW
0xF3	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
0xF4	0x00F4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0xF5	0x01A1	#LATIN SMALL LETTER O WITH HORN
0xF6	0x00F6	#LATIN SMALL LETTER O WITH DIAERESIS
0xF7	0x00F7	#DIVISION SIGN
0xF8	0x00F8	#LATIN SMALL LETTER O WITH STROKE
0xF9	0x00F9	#LATIN SMALL LETTER U WITH GRAVE
0xFA	0x00FA	#LATIN SMALL LETTER U WITH ACUTE
0xFB	0x00FB	#LATIN SMALL LETTER U WITH CIRCUMFLEX
0xFC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
0xFD	0x01B0	#LATIN SMALL LETTER U WITH HORN
0xFE	0x20AB	#DONG SIGN
0xFF	0x00FF	#LATIN SMALL LETTER Y WITH DIAERESIS



Added tools/encoding/cp437.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
269
270
271
272
273
274
#
#    Name:     cp437_DOSLatinUS to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp437_DOSLatinUS code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp437_DOSLatinUS 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	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
0x8b	0x00ef	#LATIN SMALL LETTER I WITH DIAERESIS
0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
0x8d	0x00ec	#LATIN SMALL LETTER I WITH GRAVE
0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
0x91	0x00e6	#LATIN SMALL LIGATURE AE
0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
0x95	0x00f2	#LATIN SMALL LETTER O WITH GRAVE
0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
0x98	0x00ff	#LATIN SMALL LETTER Y WITH DIAERESIS
0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
0x9b	0x00a2	#CENT SIGN
0x9c	0x00a3	#POUND SIGN
0x9d	0x00a5	#YEN SIGN
0x9e	0x20a7	#PESETA SIGN
0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
0xa6	0x00aa	#FEMININE ORDINAL INDICATOR
0xa7	0x00ba	#MASCULINE ORDINAL INDICATOR
0xa8	0x00bf	#INVERTED QUESTION MARK
0xa9	0x2310	#REVERSED NOT SIGN
0xaa	0x00ac	#NOT SIGN
0xab	0x00bd	#VULGAR FRACTION ONE HALF
0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
0xad	0x00a1	#INVERTED EXCLAMATION MARK
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x258c	#LEFT HALF BLOCK
0xde	0x2590	#RIGHT HALF BLOCK
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
0xe1	0x00df	#LATIN SMALL LETTER SHARP S
0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
0xe3	0x03c0	#GREEK SMALL LETTER PI
0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
0xe6	0x00b5	#MICRO SIGN
0xe7	0x03c4	#GREEK SMALL LETTER TAU
0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
0xe9	0x0398	#GREEK CAPITAL LETTER THETA
0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
0xeb	0x03b4	#GREEK SMALL LETTER DELTA
0xec	0x221e	#INFINITY
0xed	0x03c6	#GREEK SMALL LETTER PHI
0xee	0x03b5	#GREEK SMALL LETTER EPSILON
0xef	0x2229	#INTERSECTION
0xf0	0x2261	#IDENTICAL TO
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2	0x2265	#GREATER-THAN OR EQUAL TO
0xf3	0x2264	#LESS-THAN OR EQUAL TO
0xf4	0x2320	#TOP HALF INTEGRAL
0xf5	0x2321	#BOTTOM HALF INTEGRAL
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x2248	#ALMOST EQUAL TO
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x2219	#BULLET OPERATOR
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x221a	#SQUARE ROOT
0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
0xfd	0x00b2	#SUPERSCRIPT TWO
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE


Added tools/encoding/cp737.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
269
270
271
272
273
274
#
#    Name:     cp737_DOSGreek to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp737_DOSGreek code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp737_DOSGreek 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	0x0391	#GREEK CAPITAL LETTER ALPHA
0x81	0x0392	#GREEK CAPITAL LETTER BETA
0x82	0x0393	#GREEK CAPITAL LETTER GAMMA
0x83	0x0394	#GREEK CAPITAL LETTER DELTA
0x84	0x0395	#GREEK CAPITAL LETTER EPSILON
0x85	0x0396	#GREEK CAPITAL LETTER ZETA
0x86	0x0397	#GREEK CAPITAL LETTER ETA
0x87	0x0398	#GREEK CAPITAL LETTER THETA
0x88	0x0399	#GREEK CAPITAL LETTER IOTA
0x89	0x039a	#GREEK CAPITAL LETTER KAPPA
0x8a	0x039b	#GREEK CAPITAL LETTER LAMDA
0x8b	0x039c	#GREEK CAPITAL LETTER MU
0x8c	0x039d	#GREEK CAPITAL LETTER NU
0x8d	0x039e	#GREEK CAPITAL LETTER XI
0x8e	0x039f	#GREEK CAPITAL LETTER OMICRON
0x8f	0x03a0	#GREEK CAPITAL LETTER PI
0x90	0x03a1	#GREEK CAPITAL LETTER RHO
0x91	0x03a3	#GREEK CAPITAL LETTER SIGMA
0x92	0x03a4	#GREEK CAPITAL LETTER TAU
0x93	0x03a5	#GREEK CAPITAL LETTER UPSILON
0x94	0x03a6	#GREEK CAPITAL LETTER PHI
0x95	0x03a7	#GREEK CAPITAL LETTER CHI
0x96	0x03a8	#GREEK CAPITAL LETTER PSI
0x97	0x03a9	#GREEK CAPITAL LETTER OMEGA
0x98	0x03b1	#GREEK SMALL LETTER ALPHA
0x99	0x03b2	#GREEK SMALL LETTER BETA
0x9a	0x03b3	#GREEK SMALL LETTER GAMMA
0x9b	0x03b4	#GREEK SMALL LETTER DELTA
0x9c	0x03b5	#GREEK SMALL LETTER EPSILON
0x9d	0x03b6	#GREEK SMALL LETTER ZETA
0x9e	0x03b7	#GREEK SMALL LETTER ETA
0x9f	0x03b8	#GREEK SMALL LETTER THETA
0xa0	0x03b9	#GREEK SMALL LETTER IOTA
0xa1	0x03ba	#GREEK SMALL LETTER KAPPA
0xa2	0x03bb	#GREEK SMALL LETTER LAMDA
0xa3	0x03bc	#GREEK SMALL LETTER MU
0xa4	0x03bd	#GREEK SMALL LETTER NU
0xa5	0x03be	#GREEK SMALL LETTER XI
0xa6	0x03bf	#GREEK SMALL LETTER OMICRON
0xa7	0x03c0	#GREEK SMALL LETTER PI
0xa8	0x03c1	#GREEK SMALL LETTER RHO
0xa9	0x03c3	#GREEK SMALL LETTER SIGMA
0xaa	0x03c2	#GREEK SMALL LETTER FINAL SIGMA
0xab	0x03c4	#GREEK SMALL LETTER TAU
0xac	0x03c5	#GREEK SMALL LETTER UPSILON
0xad	0x03c6	#GREEK SMALL LETTER PHI
0xae	0x03c7	#GREEK SMALL LETTER CHI
0xaf	0x03c8	#GREEK SMALL LETTER PSI
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x258c	#LEFT HALF BLOCK
0xde	0x2590	#RIGHT HALF BLOCK
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x03c9	#GREEK SMALL LETTER OMEGA
0xe1	0x03ac	#GREEK SMALL LETTER ALPHA WITH TONOS
0xe2	0x03ad	#GREEK SMALL LETTER EPSILON WITH TONOS
0xe3	0x03ae	#GREEK SMALL LETTER ETA WITH TONOS
0xe4	0x03ca	#GREEK SMALL LETTER IOTA WITH DIALYTIKA
0xe5	0x03af	#GREEK SMALL LETTER IOTA WITH TONOS
0xe6	0x03cc	#GREEK SMALL LETTER OMICRON WITH TONOS
0xe7	0x03cd	#GREEK SMALL LETTER UPSILON WITH TONOS
0xe8	0x03cb	#GREEK SMALL LETTER UPSILON WITH DIALYTIKA
0xe9	0x03ce	#GREEK SMALL LETTER OMEGA WITH TONOS
0xea	0x0386	#GREEK CAPITAL LETTER ALPHA WITH TONOS
0xeb	0x0388	#GREEK CAPITAL LETTER EPSILON WITH TONOS
0xec	0x0389	#GREEK CAPITAL LETTER ETA WITH TONOS
0xed	0x038a	#GREEK CAPITAL LETTER IOTA WITH TONOS
0xee	0x038c	#GREEK CAPITAL LETTER OMICRON WITH TONOS
0xef	0x038e	#GREEK CAPITAL LETTER UPSILON WITH TONOS
0xf0	0x038f	#GREEK CAPITAL LETTER OMEGA WITH TONOS
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2	0x2265	#GREATER-THAN OR EQUAL TO
0xf3	0x2264	#LESS-THAN OR EQUAL TO
0xf4	0x03aa	#GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
0xf5	0x03ab	#GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x2248	#ALMOST EQUAL TO
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x2219	#BULLET OPERATOR
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x221a	#SQUARE ROOT
0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
0xfd	0x00b2	#SUPERSCRIPT TWO
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE


Added tools/encoding/cp775.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
269
270
271
272
273
274
275
#
#    Name:     cp775_DOSBaltRim to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp775_DOSBaltRim code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp775_DOSBaltRim 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	0x0106	#LATIN CAPITAL LETTER C WITH ACUTE
0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
0x83	0x0101	#LATIN SMALL LETTER A WITH MACRON
0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
0x85	0x0123	#LATIN SMALL LETTER G WITH CEDILLA
0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
0x87	0x0107	#LATIN SMALL LETTER C WITH ACUTE
0x88	0x0142	#LATIN SMALL LETTER L WITH STROKE
0x89	0x0113	#LATIN SMALL LETTER E WITH MACRON
0x8a	0x0156	#LATIN CAPITAL LETTER R WITH CEDILLA
0x8b	0x0157	#LATIN SMALL LETTER R WITH CEDILLA
0x8c	0x012b	#LATIN SMALL LETTER I WITH MACRON
0x8d	0x0179	#LATIN CAPITAL LETTER Z WITH ACUTE
0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
0x91	0x00e6	#LATIN SMALL LIGATURE AE
0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
0x93	0x014d	#LATIN SMALL LETTER O WITH MACRON
0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
0x95	0x0122	#LATIN CAPITAL LETTER G WITH CEDILLA
0x96	0x00a2	#CENT SIGN
0x97	0x015a	#LATIN CAPITAL LETTER S WITH ACUTE
0x98	0x015b	#LATIN SMALL LETTER S WITH ACUTE
0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
0x9b	0x00f8	#LATIN SMALL LETTER O WITH STROKE
0x9c	0x00a3	#POUND SIGN
0x9d	0x00d8	#LATIN CAPITAL LETTER O WITH STROKE
0x9e	0x00d7	#MULTIPLICATION SIGN
0x9f	0x00a4	#CURRENCY SIGN
0xa0	0x0100	#LATIN CAPITAL LETTER A WITH MACRON
0xa1	0x012a	#LATIN CAPITAL LETTER I WITH MACRON
0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
0xa3	0x017b	#LATIN CAPITAL LETTER Z WITH DOT ABOVE
0xa4	0x017c	#LATIN SMALL LETTER Z WITH DOT ABOVE
0xa5	0x017a	#LATIN SMALL LETTER Z WITH ACUTE
0xa6	0x201d	#RIGHT DOUBLE QUOTATION MARK
0xa7	0x00a6	#BROKEN BAR
0xa8	0x00a9	#COPYRIGHT SIGN
0xa9	0x00ae	#REGISTERED SIGN
0xaa	0x00ac	#NOT SIGN
0xab	0x00bd	#VULGAR FRACTION ONE HALF
0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
0xad	0x0141	#LATIN CAPITAL LETTER L WITH STROKE
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x0104	#LATIN CAPITAL LETTER A WITH OGONEK
0xb6	0x010c	#LATIN CAPITAL LETTER C WITH CARON
0xb7	0x0118	#LATIN CAPITAL LETTER E WITH OGONEK
0xb8	0x0116	#LATIN CAPITAL LETTER E WITH DOT ABOVE
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x012e	#LATIN CAPITAL LETTER I WITH OGONEK
0xbe	0x0160	#LATIN CAPITAL LETTER S WITH CARON
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x0172	#LATIN CAPITAL LETTER U WITH OGONEK
0xc7	0x016a	#LATIN CAPITAL LETTER U WITH MACRON
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x017d	#LATIN CAPITAL LETTER Z WITH CARON
0xd0	0x0105	#LATIN SMALL LETTER A WITH OGONEK
0xd1	0x010d	#LATIN SMALL LETTER C WITH CARON
0xd2	0x0119	#LATIN SMALL LETTER E WITH OGONEK
0xd3	0x0117	#LATIN SMALL LETTER E WITH DOT ABOVE
0xd4	0x012f	#LATIN SMALL LETTER I WITH OGONEK
0xd5	0x0161	#LATIN SMALL LETTER S WITH CARON
0xd6	0x0173	#LATIN SMALL LETTER U WITH OGONEK
0xd7	0x016b	#LATIN SMALL LETTER U WITH MACRON
0xd8	0x017e	#LATIN SMALL LETTER Z WITH CARON
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x258c	#LEFT HALF BLOCK
0xde	0x2590	#RIGHT HALF BLOCK
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
0xe1	0x00df	#LATIN SMALL LETTER SHARP S (GERMAN)
0xe2	0x014c	#LATIN CAPITAL LETTER O WITH MACRON
0xe3	0x0143	#LATIN CAPITAL LETTER N WITH ACUTE
0xe4	0x00f5	#LATIN SMALL LETTER O WITH TILDE
0xe5	0x00d5	#LATIN CAPITAL LETTER O WITH TILDE
0xe6	0x00b5	#MICRO SIGN
0xe7	0x0144	#LATIN SMALL LETTER N WITH ACUTE
0xe8	0x0136	#LATIN CAPITAL LETTER K WITH CEDILLA
0xe9	0x0137	#LATIN SMALL LETTER K WITH CEDILLA
0xea	0x013b	#LATIN CAPITAL LETTER L WITH CEDILLA
0xeb	0x013c	#LATIN SMALL LETTER L WITH CEDILLA
0xec	0x0146	#LATIN SMALL LETTER N WITH CEDILLA
0xed	0x0112	#LATIN CAPITAL LETTER E WITH MACRON
0xee	0x0145	#LATIN CAPITAL LETTER N WITH CEDILLA
0xef	0x2019	#RIGHT SINGLE QUOTATION MARK
0xf0	0x00ad	#SOFT HYPHEN
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2	0x201c	#LEFT DOUBLE QUOTATION MARK
0xf3	0x00be	#VULGAR FRACTION THREE QUARTERS
0xf4	0x00b6	#PILCROW SIGN
0xf5	0x00a7	#SECTION SIGN
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x201e	#DOUBLE LOW-9 QUOTATION MARK
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x2219	#BULLET OPERATOR
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x00b9	#SUPERSCRIPT ONE
0xfc	0x00b3	#SUPERSCRIPT THREE
0xfd	0x00b2	#SUPERSCRIPT TWO
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE



Added tools/encoding/cp850.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
269
270
271
272
273
274
#
#    Name:     cp850_DOSLatin1 to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp850_DOSLatin1 code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp850_DOSLatin1 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	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
0x8b	0x00ef	#LATIN SMALL LETTER I WITH DIAERESIS
0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
0x8d	0x00ec	#LATIN SMALL LETTER I WITH GRAVE
0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
0x91	0x00e6	#LATIN SMALL LIGATURE AE
0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
0x95	0x00f2	#LATIN SMALL LETTER O WITH GRAVE
0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
0x98	0x00ff	#LATIN SMALL LETTER Y WITH DIAERESIS
0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
0x9b	0x00f8	#LATIN SMALL LETTER O WITH STROKE
0x9c	0x00a3	#POUND SIGN
0x9d	0x00d8	#LATIN CAPITAL LETTER O WITH STROKE
0x9e	0x00d7	#MULTIPLICATION SIGN
0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
0xa6	0x00aa	#FEMININE ORDINAL INDICATOR
0xa7	0x00ba	#MASCULINE ORDINAL INDICATOR
0xa8	0x00bf	#INVERTED QUESTION MARK
0xa9	0x00ae	#REGISTERED SIGN
0xaa	0x00ac	#NOT SIGN
0xab	0x00bd	#VULGAR FRACTION ONE HALF
0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
0xad	0x00a1	#INVERTED EXCLAMATION MARK
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x00c1	#LATIN CAPITAL LETTER A WITH ACUTE
0xb6	0x00c2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xb7	0x00c0	#LATIN CAPITAL LETTER A WITH GRAVE
0xb8	0x00a9	#COPYRIGHT SIGN
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x00a2	#CENT SIGN
0xbe	0x00a5	#YEN SIGN
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x00e3	#LATIN SMALL LETTER A WITH TILDE
0xc7	0x00c3	#LATIN CAPITAL LETTER A WITH TILDE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x00a4	#CURRENCY SIGN
0xd0	0x00f0	#LATIN SMALL LETTER ETH
0xd1	0x00d0	#LATIN CAPITAL LETTER ETH
0xd2	0x00ca	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xd3	0x00cb	#LATIN CAPITAL LETTER E WITH DIAERESIS
0xd4	0x00c8	#LATIN CAPITAL LETTER E WITH GRAVE
0xd5	0x0131	#LATIN SMALL LETTER DOTLESS I
0xd6	0x00cd	#LATIN CAPITAL LETTER I WITH ACUTE
0xd7	0x00ce	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xd8	0x00cf	#LATIN CAPITAL LETTER I WITH DIAERESIS
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x00a6	#BROKEN BAR
0xde	0x00cc	#LATIN CAPITAL LETTER I WITH GRAVE
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
0xe1	0x00df	#LATIN SMALL LETTER SHARP S
0xe2	0x00d4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xe3	0x00d2	#LATIN CAPITAL LETTER O WITH GRAVE
0xe4	0x00f5	#LATIN SMALL LETTER O WITH TILDE
0xe5	0x00d5	#LATIN CAPITAL LETTER O WITH TILDE
0xe6	0x00b5	#MICRO SIGN
0xe7	0x00fe	#LATIN SMALL LETTER THORN
0xe8	0x00de	#LATIN CAPITAL LETTER THORN
0xe9	0x00da	#LATIN CAPITAL LETTER U WITH ACUTE
0xea	0x00db	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xeb	0x00d9	#LATIN CAPITAL LETTER U WITH GRAVE
0xec	0x00fd	#LATIN SMALL LETTER Y WITH ACUTE
0xed	0x00dd	#LATIN CAPITAL LETTER Y WITH ACUTE
0xee	0x00af	#MACRON
0xef	0x00b4	#ACUTE ACCENT
0xf0	0x00ad	#SOFT HYPHEN
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2	0x2017	#DOUBLE LOW LINE
0xf3	0x00be	#VULGAR FRACTION THREE QUARTERS
0xf4	0x00b6	#PILCROW SIGN
0xf5	0x00a7	#SECTION SIGN
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x00b8	#CEDILLA
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x00a8	#DIAERESIS
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x00b9	#SUPERSCRIPT ONE
0xfc	0x00b3	#SUPERSCRIPT THREE
0xfd	0x00b2	#SUPERSCRIPT TWO
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE


Added tools/encoding/cp852.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
269
270
271
272
273
274
#
#    Name:     cp852_DOSLatin2 to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp852_DOSLatin2 code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp852_DOSLatin2 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	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
0x85	0x016f	#LATIN SMALL LETTER U WITH RING ABOVE
0x86	0x0107	#LATIN SMALL LETTER C WITH ACUTE
0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
0x88	0x0142	#LATIN SMALL LETTER L WITH STROKE
0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
0x8a	0x0150	#LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
0x8b	0x0151	#LATIN SMALL LETTER O WITH DOUBLE ACUTE
0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
0x8d	0x0179	#LATIN CAPITAL LETTER Z WITH ACUTE
0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0x8f	0x0106	#LATIN CAPITAL LETTER C WITH ACUTE
0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
0x91	0x0139	#LATIN CAPITAL LETTER L WITH ACUTE
0x92	0x013a	#LATIN SMALL LETTER L WITH ACUTE
0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
0x95	0x013d	#LATIN CAPITAL LETTER L WITH CARON
0x96	0x013e	#LATIN SMALL LETTER L WITH CARON
0x97	0x015a	#LATIN CAPITAL LETTER S WITH ACUTE
0x98	0x015b	#LATIN SMALL LETTER S WITH ACUTE
0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
0x9b	0x0164	#LATIN CAPITAL LETTER T WITH CARON
0x9c	0x0165	#LATIN SMALL LETTER T WITH CARON
0x9d	0x0141	#LATIN CAPITAL LETTER L WITH STROKE
0x9e	0x00d7	#MULTIPLICATION SIGN
0x9f	0x010d	#LATIN SMALL LETTER C WITH CARON
0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
0xa4	0x0104	#LATIN CAPITAL LETTER A WITH OGONEK
0xa5	0x0105	#LATIN SMALL LETTER A WITH OGONEK
0xa6	0x017d	#LATIN CAPITAL LETTER Z WITH CARON
0xa7	0x017e	#LATIN SMALL LETTER Z WITH CARON
0xa8	0x0118	#LATIN CAPITAL LETTER E WITH OGONEK
0xa9	0x0119	#LATIN SMALL LETTER E WITH OGONEK
0xaa	0x00ac	#NOT SIGN
0xab	0x017a	#LATIN SMALL LETTER Z WITH ACUTE
0xac	0x010c	#LATIN CAPITAL LETTER C WITH CARON
0xad	0x015f	#LATIN SMALL LETTER S WITH CEDILLA
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x00c1	#LATIN CAPITAL LETTER A WITH ACUTE
0xb6	0x00c2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xb7	0x011a	#LATIN CAPITAL LETTER E WITH CARON
0xb8	0x015e	#LATIN CAPITAL LETTER S WITH CEDILLA
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x017b	#LATIN CAPITAL LETTER Z WITH DOT ABOVE
0xbe	0x017c	#LATIN SMALL LETTER Z WITH DOT ABOVE
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x0102	#LATIN CAPITAL LETTER A WITH BREVE
0xc7	0x0103	#LATIN SMALL LETTER A WITH BREVE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x00a4	#CURRENCY SIGN
0xd0	0x0111	#LATIN SMALL LETTER D WITH STROKE
0xd1	0x0110	#LATIN CAPITAL LETTER D WITH STROKE
0xd2	0x010e	#LATIN CAPITAL LETTER D WITH CARON
0xd3	0x00cb	#LATIN CAPITAL LETTER E WITH DIAERESIS
0xd4	0x010f	#LATIN SMALL LETTER D WITH CARON
0xd5	0x0147	#LATIN CAPITAL LETTER N WITH CARON
0xd6	0x00cd	#LATIN CAPITAL LETTER I WITH ACUTE
0xd7	0x00ce	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xd8	0x011b	#LATIN SMALL LETTER E WITH CARON
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x0162	#LATIN CAPITAL LETTER T WITH CEDILLA
0xde	0x016e	#LATIN CAPITAL LETTER U WITH RING ABOVE
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
0xe1	0x00df	#LATIN SMALL LETTER SHARP S
0xe2	0x00d4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xe3	0x0143	#LATIN CAPITAL LETTER N WITH ACUTE
0xe4	0x0144	#LATIN SMALL LETTER N WITH ACUTE
0xe5	0x0148	#LATIN SMALL LETTER N WITH CARON
0xe6	0x0160	#LATIN CAPITAL LETTER S WITH CARON
0xe7	0x0161	#LATIN SMALL LETTER S WITH CARON
0xe8	0x0154	#LATIN CAPITAL LETTER R WITH ACUTE
0xe9	0x00da	#LATIN CAPITAL LETTER U WITH ACUTE
0xea	0x0155	#LATIN SMALL LETTER R WITH ACUTE
0xeb	0x0170	#LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
0xec	0x00fd	#LATIN SMALL LETTER Y WITH ACUTE
0xed	0x00dd	#LATIN CAPITAL LETTER Y WITH ACUTE
0xee	0x0163	#LATIN SMALL LETTER T WITH CEDILLA
0xef	0x00b4	#ACUTE ACCENT
0xf0	0x00ad	#SOFT HYPHEN
0xf1	0x02dd	#DOUBLE ACUTE ACCENT
0xf2	0x02db	#OGONEK
0xf3	0x02c7	#CARON
0xf4	0x02d8	#BREVE
0xf5	0x00a7	#SECTION SIGN
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x00b8	#CEDILLA
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x00a8	#DIAERESIS
0xfa	0x02d9	#DOT ABOVE
0xfb	0x0171	#LATIN SMALL LETTER U WITH DOUBLE ACUTE
0xfc	0x0158	#LATIN CAPITAL LETTER R WITH CARON
0xfd	0x0159	#LATIN SMALL LETTER R WITH CARON
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE


Added tools/encoding/cp855.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
269
270
271
272
273
274
275
#
#    Name:     cp855_DOSCyrillic to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp855_DOSCyrillic code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp855_DOSCyrillic 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	0x0452	#CYRILLIC SMALL LETTER DJE
0x81	0x0402	#CYRILLIC CAPITAL LETTER DJE
0x82	0x0453	#CYRILLIC SMALL LETTER GJE
0x83	0x0403	#CYRILLIC CAPITAL LETTER GJE
0x84	0x0451	#CYRILLIC SMALL LETTER IO
0x85	0x0401	#CYRILLIC CAPITAL LETTER IO
0x86	0x0454	#CYRILLIC SMALL LETTER UKRAINIAN IE
0x87	0x0404	#CYRILLIC CAPITAL LETTER UKRAINIAN IE
0x88	0x0455	#CYRILLIC SMALL LETTER DZE
0x89	0x0405	#CYRILLIC CAPITAL LETTER DZE
0x8a	0x0456	#CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
0x8b	0x0406	#CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
0x8c	0x0457	#CYRILLIC SMALL LETTER YI
0x8d	0x0407	#CYRILLIC CAPITAL LETTER YI
0x8e	0x0458	#CYRILLIC SMALL LETTER JE
0x8f	0x0408	#CYRILLIC CAPITAL LETTER JE
0x90	0x0459	#CYRILLIC SMALL LETTER LJE
0x91	0x0409	#CYRILLIC CAPITAL LETTER LJE
0x92	0x045a	#CYRILLIC SMALL LETTER NJE
0x93	0x040a	#CYRILLIC CAPITAL LETTER NJE
0x94	0x045b	#CYRILLIC SMALL LETTER TSHE
0x95	0x040b	#CYRILLIC CAPITAL LETTER TSHE
0x96	0x045c	#CYRILLIC SMALL LETTER KJE
0x97	0x040c	#CYRILLIC CAPITAL LETTER KJE
0x98	0x045e	#CYRILLIC SMALL LETTER SHORT U
0x99	0x040e	#CYRILLIC CAPITAL LETTER SHORT U
0x9a	0x045f	#CYRILLIC SMALL LETTER DZHE
0x9b	0x040f	#CYRILLIC CAPITAL LETTER DZHE
0x9c	0x044e	#CYRILLIC SMALL LETTER YU
0x9d	0x042e	#CYRILLIC CAPITAL LETTER YU
0x9e	0x044a	#CYRILLIC SMALL LETTER HARD SIGN
0x9f	0x042a	#CYRILLIC CAPITAL LETTER HARD SIGN
0xa0	0x0430	#CYRILLIC SMALL LETTER A
0xa1	0x0410	#CYRILLIC CAPITAL LETTER A
0xa2	0x0431	#CYRILLIC SMALL LETTER BE
0xa3	0x0411	#CYRILLIC CAPITAL LETTER BE
0xa4	0x0446	#CYRILLIC SMALL LETTER TSE
0xa5	0x0426	#CYRILLIC CAPITAL LETTER TSE
0xa6	0x0434	#CYRILLIC SMALL LETTER DE
0xa7	0x0414	#CYRILLIC CAPITAL LETTER DE
0xa8	0x0435	#CYRILLIC SMALL LETTER IE
0xa9	0x0415	#CYRILLIC CAPITAL LETTER IE
0xaa	0x0444	#CYRILLIC SMALL LETTER EF
0xab	0x0424	#CYRILLIC CAPITAL LETTER EF
0xac	0x0433	#CYRILLIC SMALL LETTER GHE
0xad	0x0413	#CYRILLIC CAPITAL LETTER GHE
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x0445	#CYRILLIC SMALL LETTER HA
0xb6	0x0425	#CYRILLIC CAPITAL LETTER HA
0xb7	0x0438	#CYRILLIC SMALL LETTER I
0xb8	0x0418	#CYRILLIC CAPITAL LETTER I
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x0439	#CYRILLIC SMALL LETTER SHORT I
0xbe	0x0419	#CYRILLIC CAPITAL LETTER SHORT I
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x043a	#CYRILLIC SMALL LETTER KA
0xc7	0x041a	#CYRILLIC CAPITAL LETTER KA
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x00a4	#CURRENCY SIGN
0xd0	0x043b	#CYRILLIC SMALL LETTER EL
0xd1	0x041b	#CYRILLIC CAPITAL LETTER EL
0xd2	0x043c	#CYRILLIC SMALL LETTER EM
0xd3	0x041c	#CYRILLIC CAPITAL LETTER EM
0xd4	0x043d	#CYRILLIC SMALL LETTER EN
0xd5	0x041d	#CYRILLIC CAPITAL LETTER EN
0xd6	0x043e	#CYRILLIC SMALL LETTER O
0xd7	0x041e	#CYRILLIC CAPITAL LETTER O
0xd8	0x043f	#CYRILLIC SMALL LETTER PE
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x041f	#CYRILLIC CAPITAL LETTER PE
0xde	0x044f	#CYRILLIC SMALL LETTER YA
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x042f	#CYRILLIC CAPITAL LETTER YA
0xe1	0x0440	#CYRILLIC SMALL LETTER ER
0xe2	0x0420	#CYRILLIC CAPITAL LETTER ER
0xe3	0x0441	#CYRILLIC SMALL LETTER ES
0xe4	0x0421	#CYRILLIC CAPITAL LETTER ES
0xe5	0x0442	#CYRILLIC SMALL LETTER TE
0xe6	0x0422	#CYRILLIC CAPITAL LETTER TE
0xe7	0x0443	#CYRILLIC SMALL LETTER U
0xe8	0x0423	#CYRILLIC CAPITAL LETTER U
0xe9	0x0436	#CYRILLIC SMALL LETTER ZHE
0xea	0x0416	#CYRILLIC CAPITAL LETTER ZHE
0xeb	0x0432	#CYRILLIC SMALL LETTER VE
0xec	0x0412	#CYRILLIC CAPITAL LETTER VE
0xed	0x044c	#CYRILLIC SMALL LETTER SOFT SIGN
0xee	0x042c	#CYRILLIC CAPITAL LETTER SOFT SIGN
0xef	0x2116	#NUMERO SIGN
0xf0	0x00ad	#SOFT HYPHEN
0xf1	0x044b	#CYRILLIC SMALL LETTER YERU
0xf2	0x042b	#CYRILLIC CAPITAL LETTER YERU
0xf3	0x0437	#CYRILLIC SMALL LETTER ZE
0xf4	0x0417	#CYRILLIC CAPITAL LETTER ZE
0xf5	0x0448	#CYRILLIC SMALL LETTER SHA
0xf6	0x0428	#CYRILLIC CAPITAL LETTER SHA
0xf7	0x044d	#CYRILLIC SMALL LETTER E
0xf8	0x042d	#CYRILLIC CAPITAL LETTER E
0xf9	0x0449	#CYRILLIC SMALL LETTER SHCHA
0xfa	0x0429	#CYRILLIC CAPITAL LETTER SHCHA
0xfb	0x0447	#CYRILLIC SMALL LETTER CHE
0xfc	0x0427	#CYRILLIC CAPITAL LETTER CHE
0xfd	0x00a7	#SECTION SIGN
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE



Added tools/encoding/cp857.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
269
270
271
272
273
274
275
#
#    Name:     cp857_DOSTurkish to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp857_DOSTurkish code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp857_DOSTurkish 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	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
0x8b	0x00ef	#LATIN SMALL LETTER I WITH DIAERESIS
0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
0x8d	0x0131	#LATIN SMALL LETTER DOTLESS I
0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
0x91	0x00e6	#LATIN SMALL LIGATURE AE
0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
0x95	0x00f2	#LATIN SMALL LETTER O WITH GRAVE
0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
0x98	0x0130	#LATIN CAPITAL LETTER I WITH DOT ABOVE
0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
0x9b	0x00f8	#LATIN SMALL LETTER O WITH STROKE
0x9c	0x00a3	#POUND SIGN
0x9d	0x00d8	#LATIN CAPITAL LETTER O WITH STROKE
0x9e	0x015e	#LATIN CAPITAL LETTER S WITH CEDILLA
0x9f	0x015f	#LATIN SMALL LETTER S WITH CEDILLA
0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
0xa6	0x011e	#LATIN CAPITAL LETTER G WITH BREVE
0xa7	0x011f	#LATIN SMALL LETTER G WITH BREVE
0xa8	0x00bf	#INVERTED QUESTION MARK
0xa9	0x00ae	#REGISTERED SIGN
0xaa	0x00ac	#NOT SIGN
0xab	0x00bd	#VULGAR FRACTION ONE HALF
0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
0xad	0x00a1	#INVERTED EXCLAMATION MARK
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x00c1	#LATIN CAPITAL LETTER A WITH ACUTE
0xb6	0x00c2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xb7	0x00c0	#LATIN CAPITAL LETTER A WITH GRAVE
0xb8	0x00a9	#COPYRIGHT SIGN
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x00a2	#CENT SIGN
0xbe	0x00a5	#YEN SIGN
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x00e3	#LATIN SMALL LETTER A WITH TILDE
0xc7	0x00c3	#LATIN CAPITAL LETTER A WITH TILDE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x00a4	#CURRENCY SIGN
0xd0	0x00ba	#MASCULINE ORDINAL INDICATOR
0xd1	0x00aa	#FEMININE ORDINAL INDICATOR
0xd2	0x00ca	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xd3	0x00cb	#LATIN CAPITAL LETTER E WITH DIAERESIS
0xd4	0x00c8	#LATIN CAPITAL LETTER E WITH GRAVE
0xd5		#UNDEFINED
0xd6	0x00cd	#LATIN CAPITAL LETTER I WITH ACUTE
0xd7	0x00ce	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xd8	0x00cf	#LATIN CAPITAL LETTER I WITH DIAERESIS
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x00a6	#BROKEN BAR
0xde	0x00cc	#LATIN CAPITAL LETTER I WITH GRAVE
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
0xe1	0x00df	#LATIN SMALL LETTER SHARP S
0xe2	0x00d4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xe3	0x00d2	#LATIN CAPITAL LETTER O WITH GRAVE
0xe4	0x00f5	#LATIN SMALL LETTER O WITH TILDE
0xe5	0x00d5	#LATIN CAPITAL LETTER O WITH TILDE
0xe6	0x00b5	#MICRO SIGN
0xe7		#UNDEFINED
0xe8	0x00d7	#MULTIPLICATION SIGN
0xe9	0x00da	#LATIN CAPITAL LETTER U WITH ACUTE
0xea	0x00db	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xeb	0x00d9	#LATIN CAPITAL LETTER U WITH GRAVE
0xec	0x00ec	#LATIN SMALL LETTER I WITH GRAVE
0xed	0x00ff	#LATIN SMALL LETTER Y WITH DIAERESIS
0xee	0x00af	#MACRON
0xef	0x00b4	#ACUTE ACCENT
0xf0	0x00ad	#SOFT HYPHEN
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2		#UNDEFINED
0xf3	0x00be	#VULGAR FRACTION THREE QUARTERS
0xf4	0x00b6	#PILCROW SIGN
0xf5	0x00a7	#SECTION SIGN
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x00b8	#CEDILLA
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x00a8	#DIAERESIS
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x00b9	#SUPERSCRIPT ONE
0xfc	0x00b3	#SUPERSCRIPT THREE
0xfd	0x00b2	#SUPERSCRIPT TWO
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE



Added tools/encoding/cp860.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
269
270
271
272
273
274
275
#
#    Name:     cp860_DOSPortuguese to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp860_DOSPortuguese code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp860_DOSPortuguese 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	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0x84	0x00e3	#LATIN SMALL LETTER A WITH TILDE
0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
0x86	0x00c1	#LATIN CAPITAL LETTER A WITH ACUTE
0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
0x89	0x00ca	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
0x8b	0x00cd	#LATIN CAPITAL LETTER I WITH ACUTE
0x8c	0x00d4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0x8d	0x00ec	#LATIN SMALL LETTER I WITH GRAVE
0x8e	0x00c3	#LATIN CAPITAL LETTER A WITH TILDE
0x8f	0x00c2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
0x91	0x00c0	#LATIN CAPITAL LETTER A WITH GRAVE
0x92	0x00c8	#LATIN CAPITAL LETTER E WITH GRAVE
0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0x94	0x00f5	#LATIN SMALL LETTER O WITH TILDE
0x95	0x00f2	#LATIN SMALL LETTER O WITH GRAVE
0x96	0x00da	#LATIN CAPITAL LETTER U WITH ACUTE
0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
0x98	0x00cc	#LATIN CAPITAL LETTER I WITH GRAVE
0x99	0x00d5	#LATIN CAPITAL LETTER O WITH TILDE
0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
0x9b	0x00a2	#CENT SIGN
0x9c	0x00a3	#POUND SIGN
0x9d	0x00d9	#LATIN CAPITAL LETTER U WITH GRAVE
0x9e	0x20a7	#PESETA SIGN
0x9f	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
0xa6	0x00aa	#FEMININE ORDINAL INDICATOR
0xa7	0x00ba	#MASCULINE ORDINAL INDICATOR
0xa8	0x00bf	#INVERTED QUESTION MARK
0xa9	0x00d2	#LATIN CAPITAL LETTER O WITH GRAVE
0xaa	0x00ac	#NOT SIGN
0xab	0x00bd	#VULGAR FRACTION ONE HALF
0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
0xad	0x00a1	#INVERTED EXCLAMATION MARK
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x258c	#LEFT HALF BLOCK
0xde	0x2590	#RIGHT HALF BLOCK
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
0xe1	0x00df	#LATIN SMALL LETTER SHARP S
0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
0xe3	0x03c0	#GREEK SMALL LETTER PI
0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
0xe6	0x00b5	#MICRO SIGN
0xe7	0x03c4	#GREEK SMALL LETTER TAU
0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
0xe9	0x0398	#GREEK CAPITAL LETTER THETA
0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
0xeb	0x03b4	#GREEK SMALL LETTER DELTA
0xec	0x221e	#INFINITY
0xed	0x03c6	#GREEK SMALL LETTER PHI
0xee	0x03b5	#GREEK SMALL LETTER EPSILON
0xef	0x2229	#INTERSECTION
0xf0	0x2261	#IDENTICAL TO
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2	0x2265	#GREATER-THAN OR EQUAL TO
0xf3	0x2264	#LESS-THAN OR EQUAL TO
0xf4	0x2320	#TOP HALF INTEGRAL
0xf5	0x2321	#BOTTOM HALF INTEGRAL
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x2248	#ALMOST EQUAL TO
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x2219	#BULLET OPERATOR
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x221a	#SQUARE ROOT
0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
0xfd	0x00b2	#SUPERSCRIPT TWO
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE



Added tools/encoding/cp861.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
269
270
271
272
273
274
275
#
#    Name:     cp861_DOSIcelandic to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp861_DOSIcelandic code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp861_DOSIcelandic 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	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
0x8b	0x00d0	#LATIN CAPITAL LETTER ETH
0x8c	0x00f0	#LATIN SMALL LETTER ETH
0x8d	0x00de	#LATIN CAPITAL LETTER THORN
0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
0x91	0x00e6	#LATIN SMALL LIGATURE AE
0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
0x95	0x00fe	#LATIN SMALL LETTER THORN
0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
0x97	0x00dd	#LATIN CAPITAL LETTER Y WITH ACUTE
0x98	0x00fd	#LATIN SMALL LETTER Y WITH ACUTE
0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
0x9b	0x00f8	#LATIN SMALL LETTER O WITH STROKE
0x9c	0x00a3	#POUND SIGN
0x9d	0x00d8	#LATIN CAPITAL LETTER O WITH STROKE
0x9e	0x20a7	#PESETA SIGN
0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
0xa4	0x00c1	#LATIN CAPITAL LETTER A WITH ACUTE
0xa5	0x00cd	#LATIN CAPITAL LETTER I WITH ACUTE
0xa6	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
0xa7	0x00da	#LATIN CAPITAL LETTER U WITH ACUTE
0xa8	0x00bf	#INVERTED QUESTION MARK
0xa9	0x2310	#REVERSED NOT SIGN
0xaa	0x00ac	#NOT SIGN
0xab	0x00bd	#VULGAR FRACTION ONE HALF
0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
0xad	0x00a1	#INVERTED EXCLAMATION MARK
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x258c	#LEFT HALF BLOCK
0xde	0x2590	#RIGHT HALF BLOCK
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
0xe1	0x00df	#LATIN SMALL LETTER SHARP S
0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
0xe3	0x03c0	#GREEK SMALL LETTER PI
0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
0xe6	0x00b5	#MICRO SIGN
0xe7	0x03c4	#GREEK SMALL LETTER TAU
0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
0xe9	0x0398	#GREEK CAPITAL LETTER THETA
0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
0xeb	0x03b4	#GREEK SMALL LETTER DELTA
0xec	0x221e	#INFINITY
0xed	0x03c6	#GREEK SMALL LETTER PHI
0xee	0x03b5	#GREEK SMALL LETTER EPSILON
0xef	0x2229	#INTERSECTION
0xf0	0x2261	#IDENTICAL TO
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2	0x2265	#GREATER-THAN OR EQUAL TO
0xf3	0x2264	#LESS-THAN OR EQUAL TO
0xf4	0x2320	#TOP HALF INTEGRAL
0xf5	0x2321	#BOTTOM HALF INTEGRAL
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x2248	#ALMOST EQUAL TO
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x2219	#BULLET OPERATOR
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x221a	#SQUARE ROOT
0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
0xfd	0x00b2	#SUPERSCRIPT TWO
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE



Added tools/encoding/cp862.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
269
270
271
272
273
274
275
#
#    Name:     cp862_DOSHebrew to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp862_DOSHebrew code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp862_DOSHebrew 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	0x05d0	#HEBREW LETTER ALEF
0x81	0x05d1	#HEBREW LETTER BET
0x82	0x05d2	#HEBREW LETTER GIMEL
0x83	0x05d3	#HEBREW LETTER DALET
0x84	0x05d4	#HEBREW LETTER HE
0x85	0x05d5	#HEBREW LETTER VAV
0x86	0x05d6	#HEBREW LETTER ZAYIN
0x87	0x05d7	#HEBREW LETTER HET
0x88	0x05d8	#HEBREW LETTER TET
0x89	0x05d9	#HEBREW LETTER YOD
0x8a	0x05da	#HEBREW LETTER FINAL KAF
0x8b	0x05db	#HEBREW LETTER KAF
0x8c	0x05dc	#HEBREW LETTER LAMED
0x8d	0x05dd	#HEBREW LETTER FINAL MEM
0x8e	0x05de	#HEBREW LETTER MEM
0x8f	0x05df	#HEBREW LETTER FINAL NUN
0x90	0x05e0	#HEBREW LETTER NUN
0x91	0x05e1	#HEBREW LETTER SAMEKH
0x92	0x05e2	#HEBREW LETTER AYIN
0x93	0x05e3	#HEBREW LETTER FINAL PE
0x94	0x05e4	#HEBREW LETTER PE
0x95	0x05e5	#HEBREW LETTER FINAL TSADI
0x96	0x05e6	#HEBREW LETTER TSADI
0x97	0x05e7	#HEBREW LETTER QOF
0x98	0x05e8	#HEBREW LETTER RESH
0x99	0x05e9	#HEBREW LETTER SHIN
0x9a	0x05ea	#HEBREW LETTER TAV
0x9b	0x00a2	#CENT SIGN
0x9c	0x00a3	#POUND SIGN
0x9d	0x00a5	#YEN SIGN
0x9e	0x20a7	#PESETA SIGN
0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
0xa6	0x00aa	#FEMININE ORDINAL INDICATOR
0xa7	0x00ba	#MASCULINE ORDINAL INDICATOR
0xa8	0x00bf	#INVERTED QUESTION MARK
0xa9	0x2310	#REVERSED NOT SIGN
0xaa	0x00ac	#NOT SIGN
0xab	0x00bd	#VULGAR FRACTION ONE HALF
0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
0xad	0x00a1	#INVERTED EXCLAMATION MARK
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x258c	#LEFT HALF BLOCK
0xde	0x2590	#RIGHT HALF BLOCK
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
0xe1	0x00df	#LATIN SMALL LETTER SHARP S (GERMAN)
0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
0xe3	0x03c0	#GREEK SMALL LETTER PI
0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
0xe6	0x00b5	#MICRO SIGN
0xe7	0x03c4	#GREEK SMALL LETTER TAU
0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
0xe9	0x0398	#GREEK CAPITAL LETTER THETA
0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
0xeb	0x03b4	#GREEK SMALL LETTER DELTA
0xec	0x221e	#INFINITY
0xed	0x03c6	#GREEK SMALL LETTER PHI
0xee	0x03b5	#GREEK SMALL LETTER EPSILON
0xef	0x2229	#INTERSECTION
0xf0	0x2261	#IDENTICAL TO
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2	0x2265	#GREATER-THAN OR EQUAL TO
0xf3	0x2264	#LESS-THAN OR EQUAL TO
0xf4	0x2320	#TOP HALF INTEGRAL
0xf5	0x2321	#BOTTOM HALF INTEGRAL
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x2248	#ALMOST EQUAL TO
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x2219	#BULLET OPERATOR
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x221a	#SQUARE ROOT
0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
0xfd	0x00b2	#SUPERSCRIPT TWO
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE



Added tools/encoding/cp863.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
269
270
271
272
273
274
275
#
#    Name:     cp863_DOSCanadaF to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp863_DOSCanadaF code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp863_DOSCanadaF 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	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0x84	0x00c2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
0x86	0x00b6	#PILCROW SIGN
0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
0x8b	0x00ef	#LATIN SMALL LETTER I WITH DIAERESIS
0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
0x8d	0x2017	#DOUBLE LOW LINE
0x8e	0x00c0	#LATIN CAPITAL LETTER A WITH GRAVE
0x8f	0x00a7	#SECTION SIGN
0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
0x91	0x00c8	#LATIN CAPITAL LETTER E WITH GRAVE
0x92	0x00ca	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0x94	0x00cb	#LATIN CAPITAL LETTER E WITH DIAERESIS
0x95	0x00cf	#LATIN CAPITAL LETTER I WITH DIAERESIS
0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
0x98	0x00a4	#CURRENCY SIGN
0x99	0x00d4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
0x9b	0x00a2	#CENT SIGN
0x9c	0x00a3	#POUND SIGN
0x9d	0x00d9	#LATIN CAPITAL LETTER U WITH GRAVE
0x9e	0x00db	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
0xa0	0x00a6	#BROKEN BAR
0xa1	0x00b4	#ACUTE ACCENT
0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
0xa4	0x00a8	#DIAERESIS
0xa5	0x00b8	#CEDILLA
0xa6	0x00b3	#SUPERSCRIPT THREE
0xa7	0x00af	#MACRON
0xa8	0x00ce	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xa9	0x2310	#REVERSED NOT SIGN
0xaa	0x00ac	#NOT SIGN
0xab	0x00bd	#VULGAR FRACTION ONE HALF
0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
0xad	0x00be	#VULGAR FRACTION THREE QUARTERS
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x258c	#LEFT HALF BLOCK
0xde	0x2590	#RIGHT HALF BLOCK
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
0xe1	0x00df	#LATIN SMALL LETTER SHARP S
0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
0xe3	0x03c0	#GREEK SMALL LETTER PI
0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
0xe6	0x00b5	#MICRO SIGN
0xe7	0x03c4	#GREEK SMALL LETTER TAU
0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
0xe9	0x0398	#GREEK CAPITAL LETTER THETA
0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
0xeb	0x03b4	#GREEK SMALL LETTER DELTA
0xec	0x221e	#INFINITY
0xed	0x03c6	#GREEK SMALL LETTER PHI
0xee	0x03b5	#GREEK SMALL LETTER EPSILON
0xef	0x2229	#INTERSECTION
0xf0	0x2261	#IDENTICAL TO
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2	0x2265	#GREATER-THAN OR EQUAL TO
0xf3	0x2264	#LESS-THAN OR EQUAL TO
0xf4	0x2320	#TOP HALF INTEGRAL
0xf5	0x2321	#BOTTOM HALF INTEGRAL
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x2248	#ALMOST EQUAL TO
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x2219	#BULLET OPERATOR
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x221a	#SQUARE ROOT
0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
0xfd	0x00b2	#SUPERSCRIPT TWO
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE



Added tools/encoding/cp864.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
269
270
271
272
273
274
275
#
#    Name:     cp864_DOSArabic to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp864_DOSArabic code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp864_DOSArabic 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	0x066a	#ARABIC 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	0x00b0	#DEGREE SIGN
0x81	0x00b7	#MIDDLE DOT
0x82	0x2219	#BULLET OPERATOR
0x83	0x221a	#SQUARE ROOT
0x84	0x2592	#MEDIUM SHADE
0x85	0x2500	#FORMS LIGHT HORIZONTAL
0x86	0x2502	#FORMS LIGHT VERTICAL
0x87	0x253c	#FORMS LIGHT VERTICAL AND HORIZONTAL
0x88	0x2524	#FORMS LIGHT VERTICAL AND LEFT
0x89	0x252c	#FORMS LIGHT DOWN AND HORIZONTAL
0x8a	0x251c	#FORMS LIGHT VERTICAL AND RIGHT
0x8b	0x2534	#FORMS LIGHT UP AND HORIZONTAL
0x8c	0x2510	#FORMS LIGHT DOWN AND LEFT
0x8d	0x250c	#FORMS LIGHT DOWN AND RIGHT
0x8e	0x2514	#FORMS LIGHT UP AND RIGHT
0x8f	0x2518	#FORMS LIGHT UP AND LEFT
0x90	0x03b2	#GREEK SMALL BETA
0x91	0x221e	#INFINITY
0x92	0x03c6	#GREEK SMALL PHI
0x93	0x00b1	#PLUS-OR-MINUS SIGN
0x94	0x00bd	#FRACTION 1/2
0x95	0x00bc	#FRACTION 1/4
0x96	0x2248	#ALMOST EQUAL TO
0x97	0x00ab	#LEFT POINTING GUILLEMET
0x98	0x00bb	#RIGHT POINTING GUILLEMET
0x99	0xfef7	#ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
0x9a	0xfef8	#ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
0x9b		#UNDEFINED
0x9c		#UNDEFINED
0x9d	0xfefb	#ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
0x9e	0xfefc	#ARABIC LIGATURE LAM WITH ALEF FINAL FORM
0x9f		#UNDEFINED
0xa0	0x00a0	#NON-BREAKING SPACE
0xa1	0x00ad	#SOFT HYPHEN
0xa2	0xfe82	#ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
0xa3	0x00a3	#POUND SIGN
0xa4	0x00a4	#CURRENCY SIGN
0xa5	0xfe84	#ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
0xa6		#UNDEFINED
0xa7		#UNDEFINED
0xa8	0xfe8e	#ARABIC LETTER ALEF FINAL FORM
0xa9	0xfe8f	#ARABIC LETTER BEH ISOLATED FORM
0xaa	0xfe95	#ARABIC LETTER TEH ISOLATED FORM
0xab	0xfe99	#ARABIC LETTER THEH ISOLATED FORM
0xac	0x060c	#ARABIC COMMA
0xad	0xfe9d	#ARABIC LETTER JEEM ISOLATED FORM
0xae	0xfea1	#ARABIC LETTER HAH ISOLATED FORM
0xaf	0xfea5	#ARABIC LETTER KHAH ISOLATED FORM
0xb0	0x0660	#ARABIC-INDIC DIGIT ZERO
0xb1	0x0661	#ARABIC-INDIC DIGIT ONE
0xb2	0x0662	#ARABIC-INDIC DIGIT TWO
0xb3	0x0663	#ARABIC-INDIC DIGIT THREE
0xb4	0x0664	#ARABIC-INDIC DIGIT FOUR
0xb5	0x0665	#ARABIC-INDIC DIGIT FIVE
0xb6	0x0666	#ARABIC-INDIC DIGIT SIX
0xb7	0x0667	#ARABIC-INDIC DIGIT SEVEN
0xb8	0x0668	#ARABIC-INDIC DIGIT EIGHT
0xb9	0x0669	#ARABIC-INDIC DIGIT NINE
0xba	0xfed1	#ARABIC LETTER FEH ISOLATED FORM
0xbb	0x061b	#ARABIC SEMICOLON
0xbc	0xfeb1	#ARABIC LETTER SEEN ISOLATED FORM
0xbd	0xfeb5	#ARABIC LETTER SHEEN ISOLATED FORM
0xbe	0xfeb9	#ARABIC LETTER SAD ISOLATED FORM
0xbf	0x061f	#ARABIC QUESTION MARK
0xc0	0x00a2	#CENT SIGN
0xc1	0xfe80	#ARABIC LETTER HAMZA ISOLATED FORM
0xc2	0xfe81	#ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
0xc3	0xfe83	#ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
0xc4	0xfe85	#ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
0xc5	0xfeca	#ARABIC LETTER AIN FINAL FORM
0xc6	0xfe8b	#ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
0xc7	0xfe8d	#ARABIC LETTER ALEF ISOLATED FORM
0xc8	0xfe91	#ARABIC LETTER BEH INITIAL FORM
0xc9	0xfe93	#ARABIC LETTER TEH MARBUTA ISOLATED FORM
0xca	0xfe97	#ARABIC LETTER TEH INITIAL FORM
0xcb	0xfe9b	#ARABIC LETTER THEH INITIAL FORM
0xcc	0xfe9f	#ARABIC LETTER JEEM INITIAL FORM
0xcd	0xfea3	#ARABIC LETTER HAH INITIAL FORM
0xce	0xfea7	#ARABIC LETTER KHAH INITIAL FORM
0xcf	0xfea9	#ARABIC LETTER DAL ISOLATED FORM
0xd0	0xfeab	#ARABIC LETTER THAL ISOLATED FORM
0xd1	0xfead	#ARABIC LETTER REH ISOLATED FORM
0xd2	0xfeaf	#ARABIC LETTER ZAIN ISOLATED FORM
0xd3	0xfeb3	#ARABIC LETTER SEEN INITIAL FORM
0xd4	0xfeb7	#ARABIC LETTER SHEEN INITIAL FORM
0xd5	0xfebb	#ARABIC LETTER SAD INITIAL FORM
0xd6	0xfebf	#ARABIC LETTER DAD INITIAL FORM
0xd7	0xfec1	#ARABIC LETTER TAH ISOLATED FORM
0xd8	0xfec5	#ARABIC LETTER ZAH ISOLATED FORM
0xd9	0xfecb	#ARABIC LETTER AIN INITIAL FORM
0xda	0xfecf	#ARABIC LETTER GHAIN INITIAL FORM
0xdb	0x00a6	#BROKEN VERTICAL BAR
0xdc	0x00ac	#NOT SIGN
0xdd	0x00f7	#DIVISION SIGN
0xde	0x00d7	#MULTIPLICATION SIGN
0xdf	0xfec9	#ARABIC LETTER AIN ISOLATED FORM
0xe0	0x0640	#ARABIC TATWEEL
0xe1	0xfed3	#ARABIC LETTER FEH INITIAL FORM
0xe2	0xfed7	#ARABIC LETTER QAF INITIAL FORM
0xe3	0xfedb	#ARABIC LETTER KAF INITIAL FORM
0xe4	0xfedf	#ARABIC LETTER LAM INITIAL FORM
0xe5	0xfee3	#ARABIC LETTER MEEM INITIAL FORM
0xe6	0xfee7	#ARABIC LETTER NOON INITIAL FORM
0xe7	0xfeeb	#ARABIC LETTER HEH INITIAL FORM
0xe8	0xfeed	#ARABIC LETTER WAW ISOLATED FORM
0xe9	0xfeef	#ARABIC LETTER ALEF MAKSURA ISOLATED FORM
0xea	0xfef3	#ARABIC LETTER YEH INITIAL FORM
0xeb	0xfebd	#ARABIC LETTER DAD ISOLATED FORM
0xec	0xfecc	#ARABIC LETTER AIN MEDIAL FORM
0xed	0xfece	#ARABIC LETTER GHAIN FINAL FORM
0xee	0xfecd	#ARABIC LETTER GHAIN ISOLATED FORM
0xef	0xfee1	#ARABIC LETTER MEEM ISOLATED FORM
0xf0	0xfe7d	#ARABIC SHADDA MEDIAL FORM
0xf1	0x0651	#ARABIC SHADDAH
0xf2	0xfee5	#ARABIC LETTER NOON ISOLATED FORM
0xf3	0xfee9	#ARABIC LETTER HEH ISOLATED FORM
0xf4	0xfeec	#ARABIC LETTER HEH MEDIAL FORM
0xf5	0xfef0	#ARABIC LETTER ALEF MAKSURA FINAL FORM
0xf6	0xfef2	#ARABIC LETTER YEH FINAL FORM
0xf7	0xfed0	#ARABIC LETTER GHAIN MEDIAL FORM
0xf8	0xfed5	#ARABIC LETTER QAF ISOLATED FORM
0xf9	0xfef5	#ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
0xfa	0xfef6	#ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
0xfb	0xfedd	#ARABIC LETTER LAM ISOLATED FORM
0xfc	0xfed9	#ARABIC LETTER KAF ISOLATED FORM
0xfd	0xfef1	#ARABIC LETTER YEH ISOLATED FORM
0xfe	0x25a0	#BLACK SQUARE
0xff		#UNDEFINED



Added tools/encoding/cp865.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
269
270
271
272
273
274
275
#
#    Name:     cp865_DOSNordic to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp865_DOSNordic code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp865_DOSNordic 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	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
0x8b	0x00ef	#LATIN SMALL LETTER I WITH DIAERESIS
0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
0x8d	0x00ec	#LATIN SMALL LETTER I WITH GRAVE
0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
0x91	0x00e6	#LATIN SMALL LIGATURE AE
0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
0x95	0x00f2	#LATIN SMALL LETTER O WITH GRAVE
0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
0x98	0x00ff	#LATIN SMALL LETTER Y WITH DIAERESIS
0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
0x9b	0x00f8	#LATIN SMALL LETTER O WITH STROKE
0x9c	0x00a3	#POUND SIGN
0x9d	0x00d8	#LATIN CAPITAL LETTER O WITH STROKE
0x9e	0x20a7	#PESETA SIGN
0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
0xa6	0x00aa	#FEMININE ORDINAL INDICATOR
0xa7	0x00ba	#MASCULINE ORDINAL INDICATOR
0xa8	0x00bf	#INVERTED QUESTION MARK
0xa9	0x2310	#REVERSED NOT SIGN
0xaa	0x00ac	#NOT SIGN
0xab	0x00bd	#VULGAR FRACTION ONE HALF
0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
0xad	0x00a1	#INVERTED EXCLAMATION MARK
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00a4	#CURRENCY SIGN
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x258c	#LEFT HALF BLOCK
0xde	0x2590	#RIGHT HALF BLOCK
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
0xe1	0x00df	#LATIN SMALL LETTER SHARP S
0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
0xe3	0x03c0	#GREEK SMALL LETTER PI
0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
0xe6	0x00b5	#MICRO SIGN
0xe7	0x03c4	#GREEK SMALL LETTER TAU
0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
0xe9	0x0398	#GREEK CAPITAL LETTER THETA
0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
0xeb	0x03b4	#GREEK SMALL LETTER DELTA
0xec	0x221e	#INFINITY
0xed	0x03c6	#GREEK SMALL LETTER PHI
0xee	0x03b5	#GREEK SMALL LETTER EPSILON
0xef	0x2229	#INTERSECTION
0xf0	0x2261	#IDENTICAL TO
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2	0x2265	#GREATER-THAN OR EQUAL TO
0xf3	0x2264	#LESS-THAN OR EQUAL TO
0xf4	0x2320	#TOP HALF INTEGRAL
0xf5	0x2321	#BOTTOM HALF INTEGRAL
0xf6	0x00f7	#DIVISION SIGN
0xf7	0x2248	#ALMOST EQUAL TO
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x2219	#BULLET OPERATOR
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x221a	#SQUARE ROOT
0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
0xfd	0x00b2	#SUPERSCRIPT TWO
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE



Added tools/encoding/cp866.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
269
270
271
272
273
274
275
#
#    Name:     cp866_DOSCyrillicRussian to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp866_DOSCyrillicRussian code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp866_DOSCyrillicRussian 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	0x0410	#CYRILLIC CAPITAL LETTER A
0x81	0x0411	#CYRILLIC CAPITAL LETTER BE
0x82	0x0412	#CYRILLIC CAPITAL LETTER VE
0x83	0x0413	#CYRILLIC CAPITAL LETTER GHE
0x84	0x0414	#CYRILLIC CAPITAL LETTER DE
0x85	0x0415	#CYRILLIC CAPITAL LETTER IE
0x86	0x0416	#CYRILLIC CAPITAL LETTER ZHE
0x87	0x0417	#CYRILLIC CAPITAL LETTER ZE
0x88	0x0418	#CYRILLIC CAPITAL LETTER I
0x89	0x0419	#CYRILLIC CAPITAL LETTER SHORT I
0x8a	0x041a	#CYRILLIC CAPITAL LETTER KA
0x8b	0x041b	#CYRILLIC CAPITAL LETTER EL
0x8c	0x041c	#CYRILLIC CAPITAL LETTER EM
0x8d	0x041d	#CYRILLIC CAPITAL LETTER EN
0x8e	0x041e	#CYRILLIC CAPITAL LETTER O
0x8f	0x041f	#CYRILLIC CAPITAL LETTER PE
0x90	0x0420	#CYRILLIC CAPITAL LETTER ER
0x91	0x0421	#CYRILLIC CAPITAL LETTER ES
0x92	0x0422	#CYRILLIC CAPITAL LETTER TE
0x93	0x0423	#CYRILLIC CAPITAL LETTER U
0x94	0x0424	#CYRILLIC CAPITAL LETTER EF
0x95	0x0425	#CYRILLIC CAPITAL LETTER HA
0x96	0x0426	#CYRILLIC CAPITAL LETTER TSE
0x97	0x0427	#CYRILLIC CAPITAL LETTER CHE
0x98	0x0428	#CYRILLIC CAPITAL LETTER SHA
0x99	0x0429	#CYRILLIC CAPITAL LETTER SHCHA
0x9a	0x042a	#CYRILLIC CAPITAL LETTER HARD SIGN
0x9b	0x042b	#CYRILLIC CAPITAL LETTER YERU
0x9c	0x042c	#CYRILLIC CAPITAL LETTER SOFT SIGN
0x9d	0x042d	#CYRILLIC CAPITAL LETTER E
0x9e	0x042e	#CYRILLIC CAPITAL LETTER YU
0x9f	0x042f	#CYRILLIC CAPITAL LETTER YA
0xa0	0x0430	#CYRILLIC SMALL LETTER A
0xa1	0x0431	#CYRILLIC SMALL LETTER BE
0xa2	0x0432	#CYRILLIC SMALL LETTER VE
0xa3	0x0433	#CYRILLIC SMALL LETTER GHE
0xa4	0x0434	#CYRILLIC SMALL LETTER DE
0xa5	0x0435	#CYRILLIC SMALL LETTER IE
0xa6	0x0436	#CYRILLIC SMALL LETTER ZHE
0xa7	0x0437	#CYRILLIC SMALL LETTER ZE
0xa8	0x0438	#CYRILLIC SMALL LETTER I
0xa9	0x0439	#CYRILLIC SMALL LETTER SHORT I
0xaa	0x043a	#CYRILLIC SMALL LETTER KA
0xab	0x043b	#CYRILLIC SMALL LETTER EL
0xac	0x043c	#CYRILLIC SMALL LETTER EM
0xad	0x043d	#CYRILLIC SMALL LETTER EN
0xae	0x043e	#CYRILLIC SMALL LETTER O
0xaf	0x043f	#CYRILLIC SMALL LETTER PE
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x258c	#LEFT HALF BLOCK
0xde	0x2590	#RIGHT HALF BLOCK
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x0440	#CYRILLIC SMALL LETTER ER
0xe1	0x0441	#CYRILLIC SMALL LETTER ES
0xe2	0x0442	#CYRILLIC SMALL LETTER TE
0xe3	0x0443	#CYRILLIC SMALL LETTER U
0xe4	0x0444	#CYRILLIC SMALL LETTER EF
0xe5	0x0445	#CYRILLIC SMALL LETTER HA
0xe6	0x0446	#CYRILLIC SMALL LETTER TSE
0xe7	0x0447	#CYRILLIC SMALL LETTER CHE
0xe8	0x0448	#CYRILLIC SMALL LETTER SHA
0xe9	0x0449	#CYRILLIC SMALL LETTER SHCHA
0xea	0x044a	#CYRILLIC SMALL LETTER HARD SIGN
0xeb	0x044b	#CYRILLIC SMALL LETTER YERU
0xec	0x044c	#CYRILLIC SMALL LETTER SOFT SIGN
0xed	0x044d	#CYRILLIC SMALL LETTER E
0xee	0x044e	#CYRILLIC SMALL LETTER YU
0xef	0x044f	#CYRILLIC SMALL LETTER YA
0xf0	0x0401	#CYRILLIC CAPITAL LETTER IO
0xf1	0x0451	#CYRILLIC SMALL LETTER IO
0xf2	0x0404	#CYRILLIC CAPITAL LETTER UKRAINIAN IE
0xf3	0x0454	#CYRILLIC SMALL LETTER UKRAINIAN IE
0xf4	0x0407	#CYRILLIC CAPITAL LETTER YI
0xf5	0x0457	#CYRILLIC SMALL LETTER YI
0xf6	0x040e	#CYRILLIC CAPITAL LETTER SHORT U
0xf7	0x045e	#CYRILLIC SMALL LETTER SHORT U
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x2219	#BULLET OPERATOR
0xfa	0x00b7	#MIDDLE DOT
0xfb	0x221a	#SQUARE ROOT
0xfc	0x2116	#NUMERO SIGN
0xfd	0x00a4	#CURRENCY SIGN
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE



Added tools/encoding/cp869.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
269
270
271
272
273
274
275
#
#    Name:     cp869_DOSGreek2 to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp869_DOSGreek2 code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp869_DOSGreek2 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		#UNDEFINED
0x81		#UNDEFINED
0x82		#UNDEFINED
0x83		#UNDEFINED
0x84		#UNDEFINED
0x85		#UNDEFINED
0x86	0x0386	#GREEK CAPITAL LETTER ALPHA WITH TONOS
0x87		#UNDEFINED
0x88	0x00b7	#MIDDLE DOT
0x89	0x00ac	#NOT SIGN
0x8a	0x00a6	#BROKEN BAR
0x8b	0x2018	#LEFT SINGLE QUOTATION MARK
0x8c	0x2019	#RIGHT SINGLE QUOTATION MARK
0x8d	0x0388	#GREEK CAPITAL LETTER EPSILON WITH TONOS
0x8e	0x2015	#HORIZONTAL BAR
0x8f	0x0389	#GREEK CAPITAL LETTER ETA WITH TONOS
0x90	0x038a	#GREEK CAPITAL LETTER IOTA WITH TONOS
0x91	0x03aa	#GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
0x92	0x038c	#GREEK CAPITAL LETTER OMICRON WITH TONOS
0x93		#UNDEFINED
0x94		#UNDEFINED
0x95	0x038e	#GREEK CAPITAL LETTER UPSILON WITH TONOS
0x96	0x03ab	#GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
0x97	0x00a9	#COPYRIGHT SIGN
0x98	0x038f	#GREEK CAPITAL LETTER OMEGA WITH TONOS
0x99	0x00b2	#SUPERSCRIPT TWO
0x9a	0x00b3	#SUPERSCRIPT THREE
0x9b	0x03ac	#GREEK SMALL LETTER ALPHA WITH TONOS
0x9c	0x00a3	#POUND SIGN
0x9d	0x03ad	#GREEK SMALL LETTER EPSILON WITH TONOS
0x9e	0x03ae	#GREEK SMALL LETTER ETA WITH TONOS
0x9f	0x03af	#GREEK SMALL LETTER IOTA WITH TONOS
0xa0	0x03ca	#GREEK SMALL LETTER IOTA WITH DIALYTIKA
0xa1	0x0390	#GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
0xa2	0x03cc	#GREEK SMALL LETTER OMICRON WITH TONOS
0xa3	0x03cd	#GREEK SMALL LETTER UPSILON WITH TONOS
0xa4	0x0391	#GREEK CAPITAL LETTER ALPHA
0xa5	0x0392	#GREEK CAPITAL LETTER BETA
0xa6	0x0393	#GREEK CAPITAL LETTER GAMMA
0xa7	0x0394	#GREEK CAPITAL LETTER DELTA
0xa8	0x0395	#GREEK CAPITAL LETTER EPSILON
0xa9	0x0396	#GREEK CAPITAL LETTER ZETA
0xaa	0x0397	#GREEK CAPITAL LETTER ETA
0xab	0x00bd	#VULGAR FRACTION ONE HALF
0xac	0x0398	#GREEK CAPITAL LETTER THETA
0xad	0x0399	#GREEK CAPITAL LETTER IOTA
0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xb0	0x2591	#LIGHT SHADE
0xb1	0x2592	#MEDIUM SHADE
0xb2	0x2593	#DARK SHADE
0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0xb5	0x039a	#GREEK CAPITAL LETTER KAPPA
0xb6	0x039b	#GREEK CAPITAL LETTER LAMDA
0xb7	0x039c	#GREEK CAPITAL LETTER MU
0xb8	0x039d	#GREEK CAPITAL LETTER NU
0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
0xbd	0x039e	#GREEK CAPITAL LETTER XI
0xbe	0x039f	#GREEK CAPITAL LETTER OMICRON
0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0xc6	0x03a0	#GREEK CAPITAL LETTER PI
0xc7	0x03a1	#GREEK CAPITAL LETTER RHO
0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xcf	0x03a3	#GREEK CAPITAL LETTER SIGMA
0xd0	0x03a4	#GREEK CAPITAL LETTER TAU
0xd1	0x03a5	#GREEK CAPITAL LETTER UPSILON
0xd2	0x03a6	#GREEK CAPITAL LETTER PHI
0xd3	0x03a7	#GREEK CAPITAL LETTER CHI
0xd4	0x03a8	#GREEK CAPITAL LETTER PSI
0xd5	0x03a9	#GREEK CAPITAL LETTER OMEGA
0xd6	0x03b1	#GREEK SMALL LETTER ALPHA
0xd7	0x03b2	#GREEK SMALL LETTER BETA
0xd8	0x03b3	#GREEK SMALL LETTER GAMMA
0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0xdb	0x2588	#FULL BLOCK
0xdc	0x2584	#LOWER HALF BLOCK
0xdd	0x03b4	#GREEK SMALL LETTER DELTA
0xde	0x03b5	#GREEK SMALL LETTER EPSILON
0xdf	0x2580	#UPPER HALF BLOCK
0xe0	0x03b6	#GREEK SMALL LETTER ZETA
0xe1	0x03b7	#GREEK SMALL LETTER ETA
0xe2	0x03b8	#GREEK SMALL LETTER THETA
0xe3	0x03b9	#GREEK SMALL LETTER IOTA
0xe4	0x03ba	#GREEK SMALL LETTER KAPPA
0xe5	0x03bb	#GREEK SMALL LETTER LAMDA
0xe6	0x03bc	#GREEK SMALL LETTER MU
0xe7	0x03bd	#GREEK SMALL LETTER NU
0xe8	0x03be	#GREEK SMALL LETTER XI
0xe9	0x03bf	#GREEK SMALL LETTER OMICRON
0xea	0x03c0	#GREEK SMALL LETTER PI
0xeb	0x03c1	#GREEK SMALL LETTER RHO
0xec	0x03c3	#GREEK SMALL LETTER SIGMA
0xed	0x03c2	#GREEK SMALL LETTER FINAL SIGMA
0xee	0x03c4	#GREEK SMALL LETTER TAU
0xef	0x0384	#GREEK TONOS
0xf0	0x00ad	#SOFT HYPHEN
0xf1	0x00b1	#PLUS-MINUS SIGN
0xf2	0x03c5	#GREEK SMALL LETTER UPSILON
0xf3	0x03c6	#GREEK SMALL LETTER PHI
0xf4	0x03c7	#GREEK SMALL LETTER CHI
0xf5	0x00a7	#SECTION SIGN
0xf6	0x03c8	#GREEK SMALL LETTER PSI
0xf7	0x0385	#GREEK DIALYTIKA TONOS
0xf8	0x00b0	#DEGREE SIGN
0xf9	0x00a8	#DIAERESIS
0xfa	0x03c9	#GREEK SMALL LETTER OMEGA
0xfb	0x03cb	#GREEK SMALL LETTER UPSILON WITH DIALYTIKA
0xfc	0x03b0	#GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
0xfd	0x03ce	#GREEK SMALL LETTER OMEGA WITH TONOS
0xfe	0x25a0	#BLACK SQUARE
0xff	0x00a0	#NO-BREAK SPACE



Added tools/encoding/cp874.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
269
270
271
272
273
274
275
#
#    Name:     cp874_DOSThai to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the cp874_DOSThai code (in hex)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in cp874_DOSThai 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		#UNDEFINED
0x81		#UNDEFINED
0x82		#UNDEFINED
0x83		#UNDEFINED
0x84		#UNDEFINED
0x85	0x2026	#HORIZONTAL ELLIPSIS
0x86		#UNDEFINED
0x87		#UNDEFINED
0x88		#UNDEFINED
0x89		#UNDEFINED
0x8a		#UNDEFINED
0x8b		#UNDEFINED
0x8c		#UNDEFINED
0x8d		#UNDEFINED
0x8e		#UNDEFINED
0x8f		#UNDEFINED
0x90		#UNDEFINED
0x91	0x2018	#SINGLE TURNED COMMA QUOTATION MARK
0x92	0x2019	#SINGLE COMMA QUOTATION MARK
0x93	0x201c	#DOUBLE TURNED COMMA QUOTATION MARK
0x94	0x201d	#DOUBLE COMMA QUOTATION MARK
0x95	0x2022	#BULLET
0x96	0x2013	#EN DASH
0x97	0x2014	#EM DASH
0x98		#UNDEFINED
0x99		#UNDEFINED
0x9a		#UNDEFINED
0x9b		#UNDEFINED
0x9c		#UNDEFINED
0x9d		#UNDEFINED
0x9e		#UNDEFINED
0x9f		#UNDEFINED
0xa0	0x00a0	#NON-BREAKING SPACE
0xa1	0x0e01	#THAI LETTER KO KAI
0xa2	0x0e02	#THAI LETTER KHO KHAI
0xa3	0x0e03	#THAI LETTER KHO KHUAT
0xa4	0x0e04	#THAI LETTER KHO KHWAI
0xa5	0x0e05	#THAI LETTER KHO KHON
0xa6	0x0e06	#THAI LETTER KHO RAKHANG
0xa7	0x0e07	#THAI LETTER NGO NGU
0xa8	0x0e08	#THAI LETTER CHO CHAN
0xa9	0x0e09	#THAI LETTER CHO CHING
0xaa	0x0e0a	#THAI LETTER CHO CHANG
0xab	0x0e0b	#THAI LETTER SO SO
0xac	0x0e0c	#THAI LETTER CHO CHOE
0xad	0x0e0d	#THAI LETTER YO YING
0xae	0x0e0e	#THAI LETTER DO CHADA
0xaf	0x0e0f	#THAI LETTER TO PATAK
0xb0	0x0e10	#THAI LETTER THO THAN
0xb1	0x0e11	#THAI LETTER THO NANGMONTHO
0xb2	0x0e12	#THAI LETTER THO PHUTHAO
0xb3	0x0e13	#THAI LETTER NO NEN
0xb4	0x0e14	#THAI LETTER DO DEK
0xb5	0x0e15	#THAI LETTER TO TAO
0xb6	0x0e16	#THAI LETTER THO THUNG
0xb7	0x0e17	#THAI LETTER THO THAHAN
0xb8	0x0e18	#THAI LETTER THO THONG
0xb9	0x0e19	#THAI LETTER NO NU
0xba	0x0e1a	#THAI LETTER BO BAIMAI
0xbb	0x0e1b	#THAI LETTER PO PLA
0xbc	0x0e1c	#THAI LETTER PHO PHUNG
0xbd	0x0e1d	#THAI LETTER FO FA
0xbe	0x0e1e	#THAI LETTER PHO PHAN
0xbf	0x0e1f	#THAI LETTER FO FAN
0xc0	0x0e20	#THAI LETTER PHO SAMPHAO
0xc1	0x0e21	#THAI LETTER MO MA
0xc2	0x0e22	#THAI LETTER YO YAK
0xc3	0x0e23	#THAI LETTER RO RUA
0xc4	0x0e24	#THAI LETTER RU
0xc5	0x0e25	#THAI LETTER LO LING
0xc6	0x0e26	#THAI LETTER LU
0xc7	0x0e27	#THAI LETTER WO WAEN
0xc8	0x0e28	#THAI LETTER SO SALA
0xc9	0x0e29	#THAI LETTER SO RUSI
0xca	0x0e2a	#THAI LETTER SO SUA
0xcb	0x0e2b	#THAI LETTER HO HIP
0xcc	0x0e2c	#THAI LETTER LO CHULA
0xcd	0x0e2d	#THAI LETTER O ANG
0xce	0x0e2e	#THAI LETTER HO NOK HUK
0xcf	0x0e2f	#THAI PAI YAN NOI
0xd0	0x0e30	#THAI VOWEL SIGN SARA A
0xd1	0x0e31	#THAI VOWEL SIGN MAI HAN-AKAT
0xd2	0x0e32	#THAI VOWEL SIGN SARA AA
0xd3	0x0e33	#THAI VOWEL SIGN SARA AM
0xd4	0x0e34	#THAI VOWEL SIGN SARA I
0xd5	0x0e35	#THAI VOWEL SIGN SARA II
0xd6	0x0e36	#THAI VOWEL SIGN SARA UE
0xd7	0x0e37	#THAI VOWEL SIGN SARA UEE
0xd8	0x0e38	#THAI VOWEL SIGN SARA U
0xd9	0x0e39	#THAI VOWEL SIGN SARA UU
0xda	0x0e3a	#THAI VOWEL SIGN PHINTHU
0xdb		#UNDEFINED
0xdc		#UNDEFINED
0xdd		#UNDEFINED
0xde		#UNDEFINED
0xdf	0x0e3f	#THAI BAHT SIGN
0xe0	0x0e40	#THAI VOWEL SIGN SARA E
0xe1	0x0e41	#THAI VOWEL SIGN SARA AE
0xe2	0x0e42	#THAI VOWEL SIGN SARA O
0xe3	0x0e43	#THAI VOWEL SIGN SARA MAI MUAN
0xe4	0x0e44	#THAI VOWEL SIGN SARA MAI MALAI
0xe5	0x0e45	#THAI LAK KHANG YAO
0xe6	0x0e46	#THAI MAI YAMOK
0xe7	0x0e47	#THAI VOWEL SIGN MAI TAI KHU
0xe8	0x0e48	#THAI TONE MAI EK
0xe9	0x0e49	#THAI TONE MAI THO
0xea	0x0e4a	#THAI TONE MAI TRI
0xeb	0x0e4b	#THAI TONE MAI CHATTAWA
0xec	0x0e4c	#THAI THANTHAKHAT
0xed	0x0e4d	#THAI NIKKHAHIT
0xee	0x0e4e	#THAI YAMAKKAN
0xef	0x0e4f	#THAI FONGMAN
0xf0	0x0e50	#THAI DIGIT 0
0xf1	0x0e51	#THAI DIGIT 1
0xf2	0x0e52	#THAI DIGIT 2
0xf3	0x0e53	#THAI DIGIT 3
0xf4	0x0e54	#THAI DIGIT 4
0xf5	0x0e55	#THAI DIGIT 5
0xf6	0x0e56	#THAI DIGIT 6
0xf7	0x0e57	#THAI DIGIT 7
0xf8	0x0e58	#THAI DIGIT 8
0xf9	0x0e59	#THAI DIGIT 9
0xfa	0x0e5a	#THAI ANGKHANKHU
0xfb	0x0e5b	#THAI KHOMUT
0xfc		#UNDEFINED
0xfd		#UNDEFINED
0xfe		#UNDEFINED
0xff		#UNDEFINED



Added tools/encoding/cp932.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
#
#    Name:  cp932_ShiftJIS to Unicode table
#    Unicode version: 2.0
#    Table version: 2.00
#    Table format:  Format A
#    Date:          04/24/96
#    Authors:       Lori Brownell <[email protected]>
#                   K.D. Chang    <[email protected]>
#    General notes: none
#
#    Format: Three tab-separated columns
#        Column #1 is the Shift JIS code (in hex as 0xXXXX)
#        Column #2 is the Unicode (in hex as 0xXXXX)
#        Column #3 is the Unicode name (follows a comment sign, '#')
#
#    The entries are in Shift JIS 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 (rendered as Halfwidth Yen Sign)
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		#UNDEFINED
0x81		#DBCS LEAD BYTE
0x82		#DBCS LEAD BYTE
0x83		#DBCS LEAD BYTE
0x84		#DBCS LEAD BYTE
0x85		#DBCS LEAD BYTE
0x86		#DBCS LEAD BYTE
0x87		#DBCS LEAD BYTE
0x88		#DBCS LEAD BYTE
0x89		#DBCS LEAD BYTE
0x8A		#DBCS LEAD BYTE
0x8B		#DBCS LEAD BYTE
0x8C		#DBCS LEAD BYTE
0x8D		#DBCS LEAD BYTE
0x8E		#DBCS LEAD BYTE
0x8F		#DBCS LEAD BYTE
0x90		#DBCS LEAD BYTE
0x91		#DBCS LEAD BYTE
0x92		#DBCS LEAD BYTE
0x93		#DBCS LEAD BYTE
0x94		#DBCS LEAD BYTE
0x95		#DBCS LEAD BYTE
0x96		#DBCS LEAD BYTE
0x97		#DBCS LEAD BYTE
0x98		#DBCS LEAD BYTE
0x99		#DBCS LEAD BYTE
0x9A		#DBCS LEAD BYTE
0x9B		#DBCS LEAD BYTE
0x9C		#DBCS LEAD BYTE
0x9D		#DBCS LEAD BYTE
0x9E		#DBCS LEAD BYTE
0x9F		#DBCS LEAD BYTE
0xA0		#UNDEFINED
0xA1	0xFF61	#HALFWIDTH IDEOGRAPHIC FULL STOP
0xA2	0xFF62	#HALFWIDTH LEFT CORNER BRACKET
0xA3	0xFF63	#HALFWIDTH RIGHT CORNER BRACKET
0xA4	0xFF64	#HALFWIDTH IDEOGRAPHIC COMMA
0xA5	0xFF65	#HALFWIDTH KATAKANA MIDDLE DOT
0xA6	0xFF66	#HALFWIDTH KATAKANA LETTER WO
0xA7	0xFF67	#HALFWIDTH KATAKANA LETTER SMALL A
0xA8	0xFF68	#HALFWIDTH KATAKANA LETTER SMALL I
0xA9	0xFF69	#HALFWIDTH KATAKANA LETTER SMALL U
0xAA	0xFF6A	#HALFWIDTH KATAKANA LETTER SMALL E
0xAB	0xFF6B	#HALFWIDTH KATAKANA LETTER SMALL O
0xAC	0xFF6C	#HALFWIDTH KATAKANA LETTER SMALL YA
0xAD	0xFF6D	#HALFWIDTH KATAKANA LETTER SMALL YU
0xAE	0xFF6E	#HALFWIDTH KATAKANA LETTER SMALL YO
0xAF	0xFF6F	#HALFWIDTH KATAKANA LETTER SMALL TU
0xB0	0xFF70	#HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
0xB1	0xFF71	#HALFWIDTH KATAKANA LETTER A
0xB2	0xFF72	#HALFWIDTH KATAKANA LETTER I
0xB3	0xFF73	#HALFWIDTH KATAKANA LETTER U
0xB4	0xFF74	#HALFWIDTH KATAKANA LETTER E
0xB5	0xFF75	#HALFWIDTH KATAKANA LETTER O
0xB6	0xFF76	#HALFWIDTH KATAKANA LETTER KA
0xB7	0xFF77	#HALFWIDTH KATAKANA LETTER KI
0xB8	0xFF78	#HALFWIDTH KATAKANA LETTER KU
0xB9	0xFF79	#HALFWIDTH KATAKANA LETTER KE
0xBA	0xFF7A	#HALFWIDTH KATAKANA LETTER KO
0xBB	0xFF7B	#HALFWIDTH KATAKANA LETTER SA
0xBC	0xFF7C	#HALFWIDTH KATAKANA LETTER SI
0xBD	0xFF7D	#HALFWIDTH KATAKANA LETTER SU
0xBE	0xFF7E	#HALFWIDTH KATAKANA LETTER SE
0xBF	0xFF7F	#HALFWIDTH KATAKANA LETTER SO
0xC0	0xFF80	#HALFWIDTH KATAKANA LETTER TA
0xC1	0xFF81	#HALFWIDTH KATAKANA LETTER TI
0xC2	0xFF82	#HALFWIDTH KATAKANA LETTER TU
0xC3	0xFF83	#HALFWIDTH KATAKANA LETTER TE
0xC4	0xFF84	#HALFWIDTH KATAKANA LETTER TO
0xC5	0xFF85	#HALFWIDTH KATAKANA LETTER NA
0xC6	0xFF86	#HALFWIDTH KATAKANA LETTER NI
0xC7	0xFF87	#HALFWIDTH KATAKANA LETTER NU
0xC8	0xFF88	#HALFWIDTH KATAKANA LETTER NE
0xC9	0xFF89	#HALFWIDTH KATAKANA LETTER NO
0xCA	0xFF8A	#HALFWIDTH KATAKANA LETTER HA
0xCB	0xFF8B	#HALFWIDTH KATAKANA LETTER HI
0xCC	0xFF8C	#HALFWIDTH KATAKANA LETTER HU
0xCD	0xFF8D	#HALFWIDTH KATAKANA LETTER HE
0xCE	0xFF8E	#HALFWIDTH KATAKANA LETTER HO
0xCF	0xFF8F	#HALFWIDTH KATAKANA LETTER MA
0xD0	0xFF90	#HALFWIDTH KATAKANA LETTER MI
0xD1	0xFF91	#HALFWIDTH KATAKANA LETTER MU
0xD2	0xFF92	#HALFWIDTH KATAKANA LETTER ME
0xD3	0xFF93	#HALFWIDTH KATAKANA LETTER MO
0xD4	0xFF94	#HALFWIDTH KATAKANA LETTER YA
0xD5	0xFF95	#HALFWIDTH KATAKANA LETTER YU
0xD6	0xFF96	#HALFWIDTH KATAKANA LETTER YO
0xD7	0xFF97	#HALFWIDTH KATAKANA LETTER RA
0xD8	0xFF98	#HALFWIDTH KATAKANA LETTER RI
0xD9	0xFF99	#HALFWIDTH KATAKANA LETTER RU
0xDA	0xFF9A	#HALFWIDTH KATAKANA LETTER RE
0xDB	0xFF9B	#HALFWIDTH KATAKANA LETTER RO
0xDC	0xFF9C	#HALFWIDTH KATAKANA LETTER WA
0xDD	0xFF9D	#HALFWIDTH KATAKANA LETTER N
0xDE	0xFF9E	#HALFWIDTH KATAKANA VOICED SOUND MARK
0xDF	0xFF9F	#HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
0xE0		#DBCS LEAD BYTE
0xE1		#DBCS LEAD BYTE
0xE2		#DBCS LEAD BYTE
0xE3		#DBCS LEAD BYTE
0xE4		#DBCS LEAD BYTE
0xE5		#DBCS LEAD BYTE
0xE6		#DBCS LEAD BYTE
0xE7		#DBCS LEAD BYTE
0xE8		#DBCS LEAD BYTE
0xE9		#DBCS LEAD BYTE
0xEA		#DBCS LEAD BYTE
0xEB		#DBCS LEAD BYTE
0xEC		#DBCS LEAD BYTE
0xED		#DBCS LEAD BYTE
0xEE		#DBCS LEAD BYTE
0xEF		#DBCS LEAD BYTE
0xF0		#DBCS LEAD BYTE
0xF1		#DBCS LEAD BYTE
0xF2		#DBCS LEAD BYTE
0xF3		#DBCS LEAD BYTE
0xF4		#DBCS LEAD BYTE
0xF5		#DBCS LEAD BYTE
0xF6		#DBCS LEAD BYTE
0xF7		#DBCS LEAD BYTE
0xF8		#DBCS LEAD BYTE
0xF9		#DBCS LEAD BYTE
0xFA		#DBCS LEAD BYTE
0xFB		#DBCS LEAD BYTE
0xFC		#DBCS LEAD BYTE
0xFD		#UNDEFINED
0xFE		#UNDEFINED
0xFF		#UNDEFINED
0x8140	0x3000	#IDEOGRAPHIC SPACE
0x8141	0x3001	#IDEOGRAPHIC COMMA
0x8142	0x3002	#IDEOGRAPHIC FULL STOP
0x8143	0xFF0C	#FULLWIDTH COMMA
0x8144	0xFF0E	#FULLWIDTH FULL STOP
0x8145	0x30FB	#KATAKANA MIDDLE DOT
0x8146	0xFF1A	#FULLWIDTH COLON
0x8147	0xFF1B	#FULLWIDTH SEMICOLON
0x8148	0xFF1F	#FULLWIDTH QUESTION MARK
0x8149	0xFF01	#FULLWIDTH EXCLAMATION MARK
0x814A	0x309B	#KATAKANA-HIRAGANA VOICED SOUND MARK
0x814B	0x309C	#KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
0x814C	0x00B4	#ACUTE ACCENT
0x814D	0xFF40	#FULLWIDTH GRAVE ACCENT
0x814E	0x00A8	#DIAERESIS
0x814F	0xFF3E	#FULLWIDTH CIRCUMFLEX ACCENT
0x8150	0xFFE3	#FULLWIDTH MACRON
0x8151	0xFF3F	#FULLWIDTH LOW LINE
0x8152	0x30FD	#KATAKANA ITERATION MARK
0x8153	0x30FE	#KATAKANA VOICED ITERATION MARK
0x8154	0x309D	#HIRAGANA ITERATION MARK
0x8155	0x309E	#HIRAGANA VOICED ITERATION MARK
0x8156	0x3003	#DITTO MARK
0x8157	0x4EDD	#<CJK>
0x8158	0x3005	#IDEOGRAPHIC ITERATION MARK
0x8159	0x3006	#IDEOGRAPHIC CLOSING MARK
0x815A	0x3007	#IDEOGRAPHIC NUMBER ZERO
0x815B	0x30FC	#KATAKANA-HIRAGANA PROLONGED SOUND MARK
0x815C	0x2015	#HORIZONTAL BAR
0x815D	0x2010	#HYPHEN
0x815E	0xFF0F	#FULLWIDTH SOLIDUS
0x815F	0xFF3C	#FULLWIDTH REVERSE SOLIDUS
0x8160	0xFF5E	#FULLWIDTH TILDE
0x8161	0x2225	#PARALLEL TO
0x8162	0xFF5C	#FULLWIDTH VERTICAL LINE
0x8163	0x2026	#HORIZONTAL ELLIPSIS
0x8164	0x2025	#TWO DOT LEADER
0x8165	0x2018	#LEFT SINGLE QUOTATION MARK
0x8166	0x2019	#RIGHT SINGLE QUOTATION MARK
0x8167	0x201C	#LEFT DOUBLE QUOTATION MARK
0x8168	0x201D	#RIGHT DOUBLE QUOTATION MARK
0x8169	0xFF08	#FULLWIDTH LEFT PARENTHESIS
0x816A	0xFF09	#FULLWIDTH RIGHT PARENTHESIS
0x816B	0x3014	#LEFT TORTOISE SHELL BRACKET
0x816C	0x3015	#RIGHT TORTOISE SHELL BRACKET
0x816D	0xFF3B	#FULLWIDTH LEFT SQUARE BRACKET
0x816E	0xFF3D	#FULLWIDTH RIGHT SQUARE BRACKET
0x816F	0xFF5B	#FULLWIDTH LEFT CURLY BRACKET
0x8170	0xFF5D	#FULLWIDTH RIGHT CURLY BRACKET
0x8171	0x3008	#LEFT ANGLE BRACKET
0x8172	0x3009	#RIGHT ANGLE BRACKET
0x8173	0x300A	#LEFT DOUBLE ANGLE BRACKET
0x8174	0x300B	#RIGHT DOUBLE ANGLE BRACKET
0x8175	0x300C	#LEFT CORNER BRACKET
0x8176	0x300D	#RIGHT CORNER BRACKET
0x8177	0x300E	#LEFT WHITE CORNER BRACKET
0x8178	0x300F	#RIGHT WHITE CORNER BRACKET
0x8179	0x3010	#LEFT BLACK LENTICULAR BRACKET
0x817A	0x3011	#RIGHT BLACK LENTICULAR BRACKET
0x817B	0xFF0B	#FULLWIDTH PLUS SIGN
0x817C	0xFF0D	#FULLWIDTH HYPHEN-MINUS
0x817D	0x00B1	#PLUS-MINUS SIGN
0x817E	0x00D7	#MULTIPLICATION SIGN
0x8180	0x00F7	#DIVISION SIGN
0x8181	0xFF1D	#FULLWIDTH EQUALS SIGN
0x8182	0x2260	#NOT EQUAL TO
0x8183	0xFF1C	#FULLWIDTH LESS-THAN SIGN
0x8184	0xFF1E	#FULLWIDTH GREATER-THAN SIGN
0x8185	0x2266	#LESS-THAN OVER EQUAL TO
0x8186	0x2267	#GREATER-THAN OVER EQUAL TO
0x8187	0x221E	#INFINITY
0x8188	0x2234	#THEREFORE
0x8189	0x2642	#MALE SIGN
0x818A	0x2640	#FEMALE SIGN
0x818B	0x00B0	#DEGREE SIGN
0x818C	0x2032	#PRIME
0x818D	0x2033	#DOUBLE PRIME
0x818E	0x2103	#DEGREE CELSIUS
0x818F	0xFFE5	#FULLWIDTH YEN SIGN
0x8190	0xFF04	#FULLWIDTH DOLLAR SIGN
0x8191	0xFFE0	#FULLWIDTH CENT SIGN
0x8192	0xFFE1	#FULLWIDTH POUND SIGN
0x8193	0xFF05	#FULLWIDTH PERCENT SIGN
0x8194	0xFF03	#FULLWIDTH NUMBER SIGN
0x8195	0xFF06	#FULLWIDTH AMPERSAND
0x8196	0xFF0A	#FULLWIDTH ASTERISK
0x8197	0xFF20	#FULLWIDTH COMMERCIAL AT
0x8198	0x00A7	#SECTION SIGN
0x8199	0x2606	#WHITE STAR
0x819A	0x2605	#BLACK STAR
0x819B	0x25CB	#WHITE CIRCLE
0x819C	0x25CF	#BLACK CIRCLE
0x819D	0x25CE	#BULLSEYE
0x819E	0x25C7	#WHITE DIAMOND
0x819F	0x25C6	#BLACK DIAMOND
0x81A0	0x25A1	#WHITE SQUARE
0x81A1	0x25A0	#BLACK SQUARE
0x81A2	0x25B3	#WHITE UP-POINTING TRIANGLE
0x81A3	0x25B2	#BLACK UP-POINTING TRIANGLE
0x81A4	0x25BD	#WHITE DOWN-POINTING TRIANGLE
0x81A5	0x25BC	#BLACK DOWN-POINTING TRIANGLE
0x81A6	0x203B	#REFERENCE MARK
0x81A7	0x3012	#POSTAL MARK
0x81A8	0x2192	#RIGHTWARDS ARROW
0x81A9	0x2190	#LEFTWARDS ARROW
0x81AA	0x2191	#UPWARDS ARROW
0x81AB	0x2193	#DOWNWARDS ARROW
0x81AC	0x3013	#GETA MARK
0x81B8	0x2208	#ELEMENT OF
0x81B9	0x220B	#CONTAINS AS MEMBER
0x81BA	0x2286	#SUBSET OF OR EQUAL TO
0x81BB	0x2287	#SUPERSET OF OR EQUAL TO
0x81BC	0x2282	#SUBSET OF
0x81BD	0x2283	#SUPERSET OF
0x81BE	0x222A	#UNION
0x81BF	0x2229	#INTERSECTION
0x81C8	0x2227	#LOGICAL AND
0x81C9	0x2228	#LOGICAL OR
0x81CA	0xFFE2	#FULLWIDTH NOT SIGN
0x81CB	0x21D2	#RIGHTWARDS DOUBLE ARROW
0x81CC	0x21D4	#LEFT RIGHT DOUBLE ARROW
0x81CD	0x2200	#FOR ALL
0x81CE	0x2203	#THERE EXISTS
0x81DA	0x2220	#ANGLE
0x81DB	0x22A5	#UP TACK
0x81DC	0x2312	#ARC
0x81DD	0x2202	#PARTIAL DIFFERENTIAL
0x81DE	0x2207	#NABLA
0x81DF	0x2261	#IDENTICAL TO
0x81E0	0x2252	#APPROXIMATELY EQUAL TO OR THE IMAGE OF
0x81E1	0x226A	#MUCH LESS-THAN
0x81E2	0x226B	#MUCH GREATER-THAN
0x81E3	0x221A	#SQUARE ROOT
0x81E4	0x223D	#REVERSED TILDE
0x81E5	0x221D	#PROPORTIONAL TO
0x81E6	0x2235	#BECAUSE
0x81E7	0x222B	#INTEGRAL
0x81E8	0x222C	#DOUBLE INTEGRAL
0x81F0	0x212B	#ANGSTROM SIGN
0x81F1	0x2030	#PER MILLE SIGN
0x81F2	0x266F	#MUSIC SHARP SIGN
0x81F3	0x266D	#MUSIC FLAT SIGN
0x81F4	0x266A	#EIGHTH NOTE
0x81F5	0x2020	#DAGGER
0x81F6	0x2021	#DOUBLE DAGGER
0x81F7	0x00B6	#PILCROW SIGN
0x81FC	0x25EF	#LARGE CIRCLE
0x824F	0xFF10	#FULLWIDTH DIGIT ZERO
0x8250	0xFF11	#FULLWIDTH DIGIT ONE
0x8251	0xFF12	#FULLWIDTH DIGIT TWO
0x8252	0xFF13	#FULLWIDTH DIGIT THREE
0x8253	0xFF14	#FULLWIDTH DIGIT FOUR
0x8254	0xFF15	#FULLWIDTH DIGIT FIVE
0x8255	0xFF16	#FULLWIDTH DIGIT SIX
0x8256	0xFF17	#FULLWIDTH DIGIT SEVEN
0x8257	0xFF18	#FULLWIDTH DIGIT EIGHT
0x8258	0xFF19	#FULLWIDTH DIGIT NINE
0x8260	0xFF21	#FULLWIDTH LATIN CAPITAL LETTER A
0x8261	0xFF22	#FULLWIDTH LATIN CAPITAL LETTER B
0x8262	0xFF23	#FULLWIDTH LATIN CAPITAL LETTER C
0x8263	0xFF24	#FULLWIDTH LATIN CAPITAL LETTER D
0x8264	0xFF25	#FULLWIDTH LATIN CAPITAL LETTER E
0x8265	0xFF26	#FULLWIDTH LATIN CAPITAL LETTER F
0x8266	0xFF27	#FULLWIDTH LATIN CAPITAL LETTER G
0x8267	0xFF28	#FULLWIDTH LATIN CAPITAL LETTER H
0x8268	0xFF29	#FULLWIDTH LATIN CAPITAL LETTER I
0x8269	0xFF2A	#FULLWIDTH LATIN CAPITAL LETTER J
0x826A	0xFF2B	#FULLWIDTH LATIN CAPITAL LETTER K
0x826B	0xFF2C	#FULLWIDTH LATIN CAPITAL LETTER L
0x826C	0xFF2D	#FULLWIDTH LATIN CAPITAL LETTER M
0x826D	0xFF2E	#FULLWIDTH LATIN CAPITAL LETTER N
0x826E	0xFF2F	#FULLWIDTH LATIN CAPITAL LETTER O
0x826F	0xFF30	#FULLWIDTH LATIN CAPITAL LETTER P
0x8270	0xFF31	#FULLWIDTH LATIN CAPITAL LETTER Q
0x8271	0xFF32	#FULLWIDTH LATIN CAPITAL LETTER R
0x8272	0xFF33	#FULLWIDTH LATIN CAPITAL LETTER S
0x8273	0xFF34	#FULLWIDTH LATIN CAPITAL LETTER T
0x8274	0xFF35	#FULLWIDTH LATIN CAPITAL LETTER U
0x8275	0xFF36	#FULLWIDTH LATIN CAPITAL LETTER V
0x8276	0xFF37	#FULLWIDTH LATIN CAPITAL LETTER W
0x8277	0xFF38	#FULLWIDTH LATIN CAPITAL LETTER X
0x8278	0xFF39	#FULLWIDTH LATIN CAPITAL LETTER Y
0x8279	0xFF3A	#FULLWIDTH LATIN CAPITAL LETTER Z
0x8281	0xFF41	#FULLWIDTH LATIN SMALL LETTER A
0x8282	0xFF42	#FULLWIDTH LATIN SMALL LETTER B
0x8283	0xFF43	#FULLWIDTH LATIN SMALL LETTER C
0x8284	0xFF44	#FULLWIDTH LATIN SMALL LETTER D
0x8285	0xFF45	#FULLWIDTH LATIN SMALL LETTER E
0x8286	0xFF46	#FULLWIDTH LATIN SMALL LETTER F
0x8287	0xFF47	#FULLWIDTH LATIN SMALL LETTER G
0x8288	0xFF48	#FULLWIDTH LATIN SMALL LETTER H
0x8289	0xFF49	#FULLWIDTH LATIN SMALL LETTER I
0x828A	0xFF4A	#FULLWIDTH LATIN SMALL LETTER J
0x828B	0xFF4B	#FULLWIDTH LATIN SMALL LETTER K
0x828C	0xFF4C	#FULLWIDTH LATIN SMALL LETTER L
0x828D	0xFF4D	#FULLWIDTH LATIN SMALL LETTER M
0x828E	0xFF4E	#FULLWIDTH LATIN SMALL LETTER N
0x828F	0xFF4F	#FULLWIDTH LATIN SMALL LETTER O
0x8290	0xFF50	#FULLWIDTH LATIN SMALL LETTER P
0x8291	0xFF51	#FULLWIDTH LATIN SMALL LETTER Q
0x8292	0xFF52	#FULLWIDTH LATIN SMALL LETTER R
0x8293	0xFF53	#FULLWIDTH LATIN SMALL LETTER S
0x8294	0xFF54	#FULLWIDTH LATIN SMALL LETTER T
0x8295	0xFF55	#FULLWIDTH LATIN SMALL LETTER U
0x8296	0xFF56	#FULLWIDTH LATIN SMALL LETTER V
0x8297	0xFF57	#FULLWIDTH LATIN SMALL LETTER W
0x8298	0xFF58	#FULLWIDTH LATIN SMALL LETTER X
0x8299	0xFF59	#FULLWIDTH LATIN SMALL LETTER Y
0x829A	0xFF5A	#FULLWIDTH LATIN SMALL LETTER Z
0x829F	0x3041	#HIRAGANA LETTER SMALL A
0x82A0	0x3042	#HIRAGANA LETTER A
0x82A1	0x3043	#HIRAGANA LETTER SMALL I
0x82A2	0x3044	#HIRAGANA LETTER I
0x82A3	0x3045	#HIRAGANA LETTER SMALL U
0x82A4	0x3046	#HIRAGANA LETTER U
0x82A5	0x3047	#HIRAGANA LETTER SMALL E
0x82A6	0x3048	#HIRAGANA LETTER E
0x82A7	0x3049	#HIRAGANA LETTER SMALL O
0x82A8	0x304A	#HIRAGANA LETTER O
0x82A9	0x304B	#HIRAGANA LETTER KA
0x82AA	0x304C	#HIRAGANA LETTER GA
0x82AB	0x304D	#HIRAGANA LETTER KI
0x82AC	0x304E	#HIRAGANA LETTER GI
0x82AD	0x304F	#HIRAGANA LETTER KU
0x82AE	0x3050	#HIRAGANA LETTER GU
0x82AF	0x3051	#HIRAGANA LETTER KE
0x82B0	0x3052	#HIRAGANA LETTER GE
0x82B1	0x3053	#HIRAGANA LETTER KO
0x82B2	0x3054	#HIRAGANA LETTER GO
0x82B3	0x3055	#HIRAGANA LETTER SA
0x82B4	0x3056	#HIRAGANA LETTER ZA
0x82B5	0x3057	#HIRAGANA LETTER SI
0x82B6	0x3058	#HIRAGANA LETTER ZI
0x82B7	0x3059	#HIRAGANA LETTER SU
0x82B8	0x305A	#HIRAGANA LETTER ZU
0x82B9	0x305B	#HIRAGANA LETTER SE
0x82BA	0x305C	#HIRAGANA LETTER ZE
0x82BB	0x305D	#HIRAGANA LETTER SO
0x82BC	0x305E	#HIRAGANA LETTER ZO
0x82BD	0x305F	#HIRAGANA LETTER TA
0x82BE	0x3060	#HIRAGANA LETTER DA
0x82BF	0x3061	#HIRAGANA LETTER TI
0x82C0	0x3062	#HIRAGANA LETTER DI
0x82C1	0x3063	#HIRAGANA LETTER SMALL TU
0x82C2	0x3064	#HIRAGANA LETTER TU
0x82C3	0x3065	#HIRAGANA LETTER DU
0x82C4	0x3066	#HIRAGANA LETTER TE
0x82C5	0x3067	#HIRAGANA LETTER DE
0x82C6	0x3068	#HIRAGANA LETTER TO
0x82C7	0x3069	#HIRAGANA LETTER DO
0x82C8	0x306A	#HIRAGANA LETTER NA
0x82C9	0x306B	#HIRAGANA LETTER NI
0x82CA	0x306C	#HIRAGANA LETTER NU
0x82CB	0x306D	#HIRAGANA LETTER NE
0x82CC	0x306E	#HIRAGANA LETTER NO
0x82CD	0x306F	#HIRAGANA LETTER HA
0x82CE	0x3070	#HIRAGANA LETTER BA
0x82CF	0x3071	#HIRAGANA LETTER PA
0x82D0	0x3072	#HIRAGANA LETTER HI
0x82D1	0x3073	#HIRAGANA LETTER BI
0x82D2	0x3074	#HIRAGANA LETTER PI
0x82D3	0x3075	#HIRAGANA LETTER HU
0x82D4	0x3076	#HIRAGANA LETTER BU
0x82D5	0x3077	#HIRAGANA LETTER PU
0x82D6	0x3078	#HIRAGANA LETTER HE
0x82D7	0x3079	#HIRAGANA LETTER BE
0x82D8	0x307A	#HIRAGANA LETTER PE
0x82D9	0x307B	#HIRAGANA LETTER HO
0x82DA	0x307C	#HIRAGANA LETTER BO
0x82DB	0x307D	#HIRAGANA LETTER PO
0x82DC	0x307E	#HIRAGANA LETTER MA
0x82DD	0x307F	#HIRAGANA LETTER MI
0x82DE	0x3080	#HIRAGANA LETTER MU
0x82DF	0x3081	#HIRAGANA LETTER ME
0x82E0	0x3082	#HIRAGANA LETTER MO
0x82E1	0x3083	#HIRAGANA LETTER SMALL YA
0x82E2	0x3084	#HIRAGANA LETTER YA
0x82E3	0x3085	#HIRAGANA LETTER SMALL YU
0x82E4	0x3086	#HIRAGANA LETTER YU
0x82E5	0x3087	#HIRAGANA LETTER SMALL YO
0x82E6	0x3088	#HIRAGANA LETTER YO
0x82E7	0x3089	#HIRAGANA LETTER RA
0x82E8	0x308A	#HIRAGANA LETTER RI
0x82E9	0x308B	#HIRAGANA LETTER RU
0x82EA	0x308C	#HIRAGANA LETTER RE
0x82EB	0x308D	#HIRAGANA LETTER RO
0x82EC	0x308E	#HIRAGANA LETTER SMALL WA
0x82ED	0x308F	#HIRAGANA LETTER WA
0x82EE	0x3090	#HIRAGANA LETTER WI
0x82EF	0x3091	#HIRAGANA LETTER WE
0x82F0	0x3092	#HIRAGANA LETTER WO
0x82F1	0x3093	#HIRAGANA LETTER N
0x8340	0x30A1	#KATAKANA LETTER SMALL A
0x8341	0x30A2	#KATAKANA LETTER A
0x8342	0x30A3	#KATAKANA LETTER SMALL I
0x8343	0x30A4	#KATAKANA LETTER I
0x8344	0x30A5	#KATAKANA LETTER SMALL U
0x8345	0x30A6	#KATAKANA LETTER U
0x8346	0x30A7	#KATAKANA LETTER SMALL E
0x8347	0x30A8	#KATAKANA LETTER E
0x8348	0x30A9	#KATAKANA LETTER SMALL O
0x8349	0x30AA	#KATAKANA LETTER O
0x834A	0x30AB	#KATAKANA LETTER KA
0x834B	0x30AC	#KATAKANA LETTER GA
0x834C	0x30AD	#KATAKANA LETTER KI
0x834D	0x30AE	#KATAKANA LETTER GI
0x834E	0x30AF	#KATAKANA LETTER KU
0x834F	0x30B0	#KATAKANA LETTER GU
0x8350	0x30B1	#KATAKANA LETTER KE
0x8351	0x30B2	#KATAKANA LETTER GE
0x8352	0x30B3	#KATAKANA LETTER KO
0x8353	0x30B4	#KATAKANA LETTER GO
0x8354	0x30B5	#KATAKANA LETTER SA
0x8355	0x30B6	#KATAKANA LETTER ZA
0x8356	0x30B7	#KATAKANA LETTER SI
0x8357	0x30B8	#KATAKANA LETTER ZI
0x8358	0x30B9	#KATAKANA LETTER SU
0x8359	0x30BA	#KATAKANA LETTER ZU
0x835A	0x30BB	#KATAKANA LETTER SE
0x835B	0x30BC	#KATAKANA LETTER ZE
0x835C	0x30BD	#KATAKANA LETTER SO
0x835D	0x30BE	#KATAKANA LETTER ZO
0x835E	0x30BF	#KATAKANA LETTER TA
0x835F	0x30C0	#KATAKANA LETTER DA
0x8360	0x30C1	#KATAKANA LETTER TI
0x8361	0x30C2	#KATAKANA LETTER DI
0x8362	0x30C3	#KATAKANA LETTER SMALL TU
0x8363	0x30C4	#KATAKANA LETTER TU
0x8364	0x30C5	#KATAKANA LETTER DU
0x8365	0x30C6	#KATAKANA LETTER TE
0x8366	0x30C7	#KATAKANA LETTER DE
0x8367	0x30C8	#KATAKANA LETTER TO
0x8368	0x30C9	#KATAKANA LETTER DO
0x8369	0x30CA	#KATAKANA LETTER NA
0x836A	0x30CB	#KATAKANA LETTER NI
0x836B	0x30CC	#KATAKANA LETTER NU
0x836C	0x30CD	#KATAKANA LETTER NE
0x836D	0x30CE	#KATAKANA LETTER NO
0x836E	0x30CF	#KATAKANA LETTER HA
0x836F	0x30D0	#KATAKANA LETTER BA
0x8370	0x30D1	#KATAKANA LETTER PA
0x8371	0x30D2	#KATAKANA LETTER HI
0x8372	0x30D3	#KATAKANA LETTER BI
0x8373	0x30D4	#KATAKANA LETTER PI
0x8374	0x30D5	#KATAKANA LETTER HU
0x8375	0x30D6	#KATAKANA LETTER BU
0x8376	0x30D7	#KATAKANA LETTER PU
0x8377	0x30D8	#KATAKANA LETTER HE
0x8378	0x30D9	#KATAKANA LETTER BE
0x8379	0x30DA	#KATAKANA LETTER PE
0x837A	0x30DB	#KATAKANA LETTER HO
0x837B	0x30DC	#KATAKANA LETTER BO
0x837C	0x30DD	#KATAKANA LETTER PO
0x837D	0x30DE	#KATAKANA LETTER MA
0x837E	0x30DF	#KATAKANA LETTER MI
0x8380	0x30E0	#KATAKANA LETTER MU
0x8381	0x30E1	#KATAKANA LETTER ME
0x8382	0x30E2	#KATAKANA LETTER MO
0x8383	0x30E3	#KATAKANA LETTER SMALL YA
0x8384	0x30E4	#KATAKANA LETTER YA
0x8385	0x30E5	#KATAKANA LETTER SMALL YU
0x8386	0x30E6	#KATAKANA LETTER YU
0x8387	0x30E7	#KATAKANA LETTER SMALL YO
0x8388	0x30E8	#KATAKANA LETTER YO
0x8389	0x30E9	#KATAKANA LETTER RA
0x838A	0x30EA	#KATAKANA LETTER RI
0x838B	0x30EB	#KATAKANA LETTER RU
0x838C	0x30EC	#KATAKANA LETTER RE
0x838D	0x30ED	#KATAKANA LETTER RO
0x838E	0x30EE	#KATAKANA LETTER SMALL WA
0x838F	0x30EF	#KATAKANA LETTER WA
0x8390	0x30F0	#KATAKANA LETTER WI
0x8391	0x30F1	#KATAKANA LETTER WE
0x8392	0x30F2	#KATAKANA LETTER WO
0x8393	0x30F3	#KATAKANA LETTER N
0x8394	0x30F4	#KATAKANA LETTER VU
0x8395	0x30F5	#KATAKANA LETTER SMALL KA
0x8396	0x30F6	#KATAKANA LETTER SMALL KE
0x839F	0x0391	#GREEK CAPITAL LETTER ALPHA
0x83A0	0x0392	#GREEK CAPITAL LETTER BETA
0x83A1	0x0393	#GREEK CAPITAL LETTER GAMMA
0x83A2	0x0394	#GREEK CAPITAL LETTER DELTA
0x83A3	0x0395	#GREEK CAPITAL LETTER EPSILON
0x83A4	0x0396	#GREEK CAPITAL LETTER ZETA
0x83A5	0x0397	#GREEK CAPITAL LETTER ETA
0x83A6	0x0398	#GREEK CAPITAL LETTER THETA
0x83A7	0x0399	#GREEK CAPITAL LETTER IOTA
0x83A8	0x039A	#GREEK CAPITAL LETTER KAPPA
0x83A9	0x039B	#GREEK CAPITAL LETTER LAMDA
0x83AA	0x039C	#GREEK CAPITAL LETTER MU
0x83AB	0x039D	#GREEK CAPITAL LETTER NU
0x83AC	0x039E	#GREEK CAPITAL LETTER XI
0x83AD	0x039F	#GREEK CAPITAL LETTER OMICRON
0x83AE	0x03A0	#GREEK CAPITAL LETTER PI
0x83AF	0x03A1	#GREEK CAPITAL LETTER RHO
0x83B0	0x03A3	#GREEK CAPITAL LETTER SIGMA
0x83B1	0x03A4	#GREEK CAPITAL LETTER TAU
0x83B2	0x03A5	#GREEK CAPITAL LETTER UPSILON
0x83B3	0x03A6	#GREEK CAPITAL LETTER PHI
0x83B4	0x03A7	#GREEK CAPITAL LETTER CHI
0x83B5	0x03A8	#GREEK CAPITAL LETTER PSI
0x83B6	0x03A9	#GREEK CAPITAL LETTER OMEGA
0x83BF	0x03B1	#GREEK SMALL LETTER ALPHA
0x83C0	0x03B2	#GREEK SMALL LETTER BETA
0x83C1	0x03B3	#GREEK SMALL LETTER GAMMA
0x83C2	0x03B4	#GREEK SMALL LETTER DELTA
0x83C3	0x03B5	#GREEK SMALL LETTER EPSILON
0x83C4	0x03B6	#GREEK SMALL LETTER ZETA
0x83C5	0x03B7	#GREEK SMALL LETTER ETA
0x83C6	0x03B8	#GREEK SMALL LETTER THETA
0x83C7	0x03B9	#GREEK SMALL LETTER IOTA
0x83C8	0x03BA	#GREEK SMALL LETTER KAPPA
0x83C9	0x03BB	#GREEK SMALL LETTER LAMDA
0x83CA	0x03BC	#GREEK SMALL LETTER MU
0x83CB	0x03BD	#GREEK SMALL LETTER NU
0x83CC	0x03BE	#GREEK SMALL LETTER XI
0x83CD	0x03BF	#GREEK SMALL LETTER OMICRON
0x83CE	0x03C0	#GREEK SMALL LETTER PI
0x83CF	0x03C1	#GREEK SMALL LETTER RHO
0x83D0	0x03C3	#GREEK SMALL LETTER SIGMA
0x83D1	0x03C4	#GREEK SMALL LETTER TAU
0x83D2	0x03C5	#GREEK SMALL LETTER UPSILON
0x83D3	0x03C6	#GREEK SMALL LETTER PHI
0x83D4	0x03C7	#GREEK SMALL LETTER CHI
0x83D5	0x03C8	#GREEK SMALL LETTER PSI
0x83D6	0x03C9	#GREEK SMALL LETTER OMEGA
0x8440	0x0410	#CYRILLIC CAPITAL LETTER A
0x8441	0x0411	#CYRILLIC CAPITAL LETTER BE
0x8442	0x0412	#CYRILLIC CAPITAL LETTER VE
0x8443	0x0413	#CYRILLIC CAPITAL LETTER GHE
0x8444	0x0414	#CYRILLIC CAPITAL LETTER DE
0x8445	0x0415	#CYRILLIC CAPITAL LETTER IE
0x8446	0x0401	#CYRILLIC CAPITAL LETTER IO
0x8447	0x0416	#CYRILLIC CAPITAL LETTER ZHE
0x8448	0x0417	#CYRILLIC CAPITAL LETTER ZE
0x8449	0x0418	#CYRILLIC CAPITAL LETTER I
0x844A	0x0419	#CYRILLIC CAPITAL LETTER SHORT I
0x844B	0x041A	#CYRILLIC CAPITAL LETTER KA
0x844C	0x041B	#CYRILLIC CAPITAL LETTER EL
0x844D	0x041C	#CYRILLIC CAPITAL LETTER EM
0x844E	0x041D	#CYRILLIC CAPITAL LETTER EN
0x844F	0x041E	#CYRILLIC CAPITAL LETTER O
0x8450	0x041F	#CYRILLIC CAPITAL LETTER PE
0x8451	0x0420	#CYRILLIC CAPITAL LETTER ER
0x8452	0x0421	#CYRILLIC CAPITAL LETTER ES
0x8453	0x0422	#CYRILLIC CAPITAL LETTER TE
0x8454	0x0423	#CYRILLIC CAPITAL LETTER U
0x8455	0x0424	#CYRILLIC CAPITAL LETTER EF
0x8456	0x0425	#CYRILLIC CAPITAL LETTER HA
0x8457	0x0426	#CYRILLIC CAPITAL LETTER TSE
0x8458	0x0427	#CYRILLIC CAPITAL LETTER CHE
0x8459	0x0428	#CYRILLIC CAPITAL LETTER SHA
0x845A	0x0429	#CYRILLIC CAPITAL LETTER SHCHA
0x845B	0x042A	#CYRILLIC CAPITAL LETTER HARD SIGN
0x845C	0x042B	#CYRILLIC CAPITAL LETTER YERU
0x845D	0x042C	#CYRILLIC CAPITAL LETTER SOFT SIGN
0x845E	0x042D	#CYRILLIC CAPITAL LETTER E
0x845F	0x042E	#CYRILLIC CAPITAL LETTER YU
0x8460	0x042F	#CYRILLIC CAPITAL LETTER YA
0x8470	0x0430	#CYRILLIC SMALL LETTER A
0x8471	0x0431	#CYRILLIC SMALL LETTER BE
0x8472	0x0432	#CYRILLIC SMALL LETTER VE
0x8473	0x0433	#CYRILLIC SMALL LETTER GHE
0x8474	0x0434	#CYRILLIC SMALL LETTER DE
0x8475	0x0435	#CYRILLIC SMALL LETTER IE
0x8476	0x0451	#CYRILLIC SMALL LETTER IO
0x8477	0x0436	#CYRILLIC SMALL LETTER ZHE
0x8478	0x0437	#CYRILLIC SMALL LETTER ZE
0x8479	0x0438	#CYRILLIC SMALL LETTER I
0x847A	0x0439	#CYRILLIC SMALL LETTER SHORT I
0x847B	0x043A	#CYRILLIC SMALL LETTER KA
0x847C	0x043B	#CYRILLIC SMALL LETTER EL
0x847D	0x043C	#CYRILLIC SMALL LETTER EM
0x847E	0x043D	#CYRILLIC SMALL LETTER EN
0x8480	0x043E	#CYRILLIC SMALL LETTER O
0x8481	0x043F	#CYRILLIC SMALL LETTER PE
0x8482	0x0440	#CYRILLIC SMALL LETTER ER
0x8483	0x0441	#CYRILLIC SMALL LETTER ES
0x8484	0x0442	#CYRILLIC SMALL LETTER TE
0x8485	0x0443	#CYRILLIC SMALL LETTER U
0x8486	0x0444	#CYRILLIC SMALL LETTER EF
0x8487	0x0445	#CYRILLIC SMALL LETTER HA
0x8488	0x0446	#CYRILLIC SMALL LETTER TSE
0x8489	0x0447	#CYRILLIC SMALL LETTER CHE
0x848A	0x0448	#CYRILLIC SMALL LETTER SHA
0x848B	0x0449	#CYRILLIC SMALL LETTER SHCHA
0x848C	0x044A	#CYRILLIC SMALL LETTER HARD SIGN
0x848D	0x044B	#CYRILLIC SMALL LETTER YERU
0x848E	0x044C	#CYRILLIC SMALL LETTER SOFT SIGN
0x848F	0x044D	#CYRILLIC SMALL LETTER E
0x8490	0x044E	#CYRILLIC SMALL LETTER YU
0x8491	0x044F	#CYRILLIC SMALL LETTER YA
0x849F	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
0x84A0	0x2502	#BOX DRAWINGS LIGHT VERTICAL
0x84A1	0x250C	#BOX DRAWINGS LIGHT DOWN AND RIGHT
0x84A2	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
0x84A3	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
0x84A4	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
0x84A5	0x251C	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0x84A6	0x252C	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0x84A7	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
0x84A8	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
0x84A9	0x253C	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0x84AA	0x2501	#BOX DRAWINGS HEAVY HORIZONTAL
0x84AB	0x2503	#BOX DRAWINGS HEAVY VERTICAL
0x84AC	0x250F	#BOX DRAWINGS HEAVY DOWN AND RIGHT
0x84AD	0x2513	#BOX DRAWINGS HEAVY DOWN AND LEFT
0x84AE	0x251B	#BOX DRAWINGS HEAVY UP AND LEFT
0x84AF	0x2517	#BOX DRAWINGS HEAVY UP AND RIGHT
0x84B0	0x2523	#BOX DRAWINGS HEAVY VERTICAL AND RIGHT
0x84B1	0x2533	#BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
0x84B2	0x252B	#BOX DRAWINGS HEAVY VERTICAL AND LEFT
0x84B3	0x253B	#BOX DRAWINGS HEAVY UP AND HORIZONTAL
0x84B4	0x254B	#BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
0x84B5	0x2520	#BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
0x84B6	0x252F	#BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
0x84B7	0x2528	#BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
0x84B8	0x2537	#BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
0x84B9	0x253F	#BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
0x84BA	0x251D	#BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
0x84BB	0x2530	#BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
0x84BC	0x2525	#BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
0x84BD	0x2538	#BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
0x84BE	0x2542	#BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
0x8740	0x2460	#CIRCLED DIGIT ONE
0x8741	0x2461	#CIRCLED DIGIT TWO
0x8742	0x2462	#CIRCLED DIGIT THREE
0x8743	0x2463	#CIRCLED DIGIT FOUR
0x8744	0x2464	#CIRCLED DIGIT FIVE
0x8745	0x2465	#CIRCLED DIGIT SIX
0x8746	0x2466	#CIRCLED DIGIT SEVEN
0x8747	0x2467	#CIRCLED DIGIT EIGHT
0x8748	0x2468	#CIRCLED DIGIT NINE
0x8749	0x2469	#CIRCLED NUMBER TEN
0x874A	0x246A	#CIRCLED NUMBER ELEVEN
0x874B	0x246B	#CIRCLED NUMBER TWELVE
0x874C	0x246C	#CIRCLED NUMBER THIRTEEN
0x874D	0x246D	#CIRCLED NUMBER FOURTEEN
0x874E	0x246E	#CIRCLED NUMBER FIFTEEN
0x874F	0x246F	#CIRCLED NUMBER SIXTEEN
0x8750	0x2470	#CIRCLED NUMBER SEVENTEEN
0x8751	0x2471	#CIRCLED NUMBER EIGHTEEN
0x8752	0x2472	#CIRCLED NUMBER NINETEEN
0x8753	0x2473	#CIRCLED NUMBER TWENTY
0x8754	0x2160	#ROMAN NUMERAL ONE
0x8755	0x2161	#ROMAN NUMERAL TWO
0x8756	0x2162	#ROMAN NUMERAL THREE
0x8757	0x2163	#ROMAN NUMERAL FOUR
0x8758	0x2164	#ROMAN NUMERAL FIVE
0x8759	0x2165	#ROMAN NUMERAL SIX
0x875A	0x2166	#ROMAN NUMERAL SEVEN
0x875B	0x2167	#ROMAN NUMERAL EIGHT
0x875C	0x2168	#ROMAN NUMERAL NINE
0x875D	0x2169	#ROMAN NUMERAL TEN
0x875F	0x3349	#SQUARE MIRI
0x8760	0x3314	#SQUARE KIRO
0x8761	0x3322	#SQUARE SENTI
0x8762	0x334D	#SQUARE MEETORU
0x8763	0x3318	#SQUARE GURAMU
0x8764	0x3327	#SQUARE TON
0x8765	0x3303	#SQUARE AARU
0x8766	0x3336	#SQUARE HEKUTAARU
0x8767	0x3351	#SQUARE RITTORU
0x8768	0x3357	#SQUARE WATTO
0x8769	0x330D	#SQUARE KARORII
0x876A	0x3326	#SQUARE DORU
0x876B	0x3323	#SQUARE SENTO
0x876C	0x332B	#SQUARE PAASENTO
0x876D	0x334A	#SQUARE MIRIBAARU
0x876E	0x333B	#SQUARE PEEZI
0x876F	0x339C	#SQUARE MM
0x8770	0x339D	#SQUARE CM
0x8771	0x339E	#SQUARE KM
0x8772	0x338E	#SQUARE MG
0x8773	0x338F	#SQUARE KG
0x8774	0x33C4	#SQUARE CC
0x8775	0x33A1	#SQUARE M SQUARED
0x877E	0x337B	#SQUARE ERA NAME HEISEI
0x8780	0x301D	#REVERSED DOUBLE PRIME QUOTATION MARK
0x8781	0x301F	#LOW DOUBLE PRIME QUOTATION MARK
0x8782	0x2116	#NUMERO SIGN
0x8783	0x33CD	#SQUARE KK
0x8784	0x2121	#TELEPHONE SIGN
0x8785	0x32A4	#CIRCLED IDEOGRAPH HIGH
0x8786	0x32A5	#CIRCLED IDEOGRAPH CENTRE
0x8787	0x32A6	#CIRCLED IDEOGRAPH LOW
0x8788	0x32A7	#CIRCLED IDEOGRAPH LEFT
0x8789	0x32A8	#CIRCLED IDEOGRAPH RIGHT
0x878A	0x3231	#PARENTHESIZED IDEOGRAPH STOCK
0x878B	0x3232	#PARENTHESIZED IDEOGRAPH HAVE
0x878C	0x3239	#PARENTHESIZED IDEOGRAPH REPRESENT
0x878D	0x337E	#SQUARE ERA NAME MEIZI
0x878E	0x337D	#SQUARE ERA NAME TAISYOU
0x878F	0x337C	#SQUARE ERA NAME SYOUWA
0x8790	0x2252	#APPROXIMATELY EQUAL TO OR THE IMAGE OF
0x8791	0x2261	#IDENTICAL TO
0x8792	0x222B	#INTEGRAL
0x8793	0x222E	#CONTOUR INTEGRAL
0x8794	0x2211	#N-ARY SUMMATION
0x8795	0x221A	#SQUARE ROOT
0x8796	0x22A5	#UP TACK
0x8797	0x2220	#ANGLE
0x8798	0x221F	#RIGHT ANGLE
0x8799	0x22BF	#RIGHT TRIANGLE
0x879A	0x2235	#BECAUSE
0x879B	0x2229	#INTERSECTION
0x879C	0x222A	#UNION
0x889F	0x4E9C	#<CJK>
0x88A0	0x5516	#<CJK>
0x88A1	0x5A03	#<CJK>
0x88A2	0x963F	#<CJK>
0x88A3	0x54C0	#<CJK>
0x88A4	0x611B	#<CJK>
0x88A5	0x6328	#<CJK>
0x88A6	0x59F6	#<CJK>
0x88A7	0x9022	#<CJK>
0x88A8	0x8475	#<CJK>
0x88A9	0x831C	#<CJK>
0x88AA	0x7A50	#<CJK>
0x88AB	0x60AA	#<CJK>
0x88AC	0x63E1	#<CJK>
0x88AD	0x6E25	#<CJK>
0x88AE	0x65ED	#<CJK>
0x88AF	0x8466	#<CJK>
0x88B0	0x82A6	#<CJK>
0x88B1	0x9BF5	#<CJK>
0x88B2	0x6893	#<CJK>
0x88B3	0x5727	#<CJK>
0x88B4	0x65A1	#<CJK>
0x88B5	0x6271	#<CJK>
0x88B6	0x5B9B	#<CJK>
0x88B7	0x59D0	#<CJK>
0x88B8	0x867B	#<CJK>
0x88B9	0x98F4	#<CJK>
0x88BA	0x7D62	#<CJK>
0x88BB	0x7DBE	#<CJK>
0x88BC	0x9B8E	#<CJK>
0x88BD	0x6216	#<CJK>
0x88BE	0x7C9F	#<CJK>
0x88BF	0x88B7	#<CJK>
0x88C0	0x5B89	#<CJK>
0x88C1	0x5EB5	#<CJK>
0x88C2	0x6309	#<CJK>
0x88C3	0x6697	#<CJK>
0x88C4	0x6848	#<CJK>
0x88C5	0x95C7	#<CJK>
0x88C6	0x978D	#<CJK>
0x88C7	0x674F	#<CJK>
0x88C8	0x4EE5	#<CJK>
0x88C9	0x4F0A	#<CJK>
0x88CA	0x4F4D	#<CJK>
0x88CB	0x4F9D	#<CJK>
0x88CC	0x5049	#<CJK>
0x88CD	0x56F2	#<CJK>
0x88CE	0x5937	#<CJK>
0x88CF	0x59D4	#<CJK>
0x88D0	0x5A01	#<CJK>
0x88D1	0x5C09	#<CJK>
0x88D2	0x60DF	#<CJK>
0x88D3	0x610F	#<CJK>
0x88D4	0x6170	#<CJK>
0x88D5	0x6613	#<CJK>
0x88D6	0x6905	#<CJK>
0x88D7	0x70BA	#<CJK>
0x88D8	0x754F	#<CJK>
0x88D9	0x7570	#<CJK>
0x88DA	0x79FB	#<CJK>
0x88DB	0x7DAD	#<CJK>
0x88DC	0x7DEF	#<CJK>
0x88DD	0x80C3	#<CJK>
0x88DE	0x840E	#<CJK>
0x88DF	0x8863	#<CJK>
0x88E0	0x8B02	#<CJK>
0x88E1	0x9055	#<CJK>
0x88E2	0x907A	#<CJK>
0x88E3	0x533B	#<CJK>
0x88E4	0x4E95	#<CJK>
0x88E5	0x4EA5	#<CJK>
0x88E6	0x57DF	#<CJK>
0x88E7	0x80B2	#<CJK>
0x88E8	0x90C1	#<CJK>
0x88E9	0x78EF	#<CJK>
0x88EA	0x4E00	#<CJK>
0x88EB	0x58F1	#<CJK>
0x88EC	0x6EA2	#<CJK>
0x88ED	0x9038	#<CJK>
0x88EE	0x7A32	#<CJK>
0x88EF	0x8328	#<CJK>
0x88F0	0x828B	#<CJK>
0x88F1	0x9C2F	#<CJK>
0x88F2	0x5141	#<CJK>
0x88F3	0x5370	#<CJK>
0x88F4	0x54BD	#<CJK>
0x88F5	0x54E1	#<CJK>
0x88F6	0x56E0	#<CJK>
0x88F7	0x59FB	#<CJK>
0x88F8	0x5F15	#<CJK>
0x88F9	0x98F2	#<CJK>
0x88FA	0x6DEB	#<CJK>
0x88FB	0x80E4	#<CJK>
0x88FC	0x852D	#<CJK>
0x8940	0x9662	#<CJK>
0x8941	0x9670	#<CJK>
0x8942	0x96A0	#<CJK>
0x8943	0x97FB	#<CJK>
0x8944	0x540B	#<CJK>
0x8945	0x53F3	#<CJK>
0x8946	0x5B87	#<CJK>
0x8947	0x70CF	#<CJK>
0x8948	0x7FBD	#<CJK>
0x8949	0x8FC2	#<CJK>
0x894A	0x96E8	#<CJK>
0x894B	0x536F	#<CJK>
0x894C	0x9D5C	#<CJK>
0x894D	0x7ABA	#<CJK>
0x894E	0x4E11	#<CJK>
0x894F	0x7893	#<CJK>
0x8950	0x81FC	#<CJK>
0x8951	0x6E26	#<CJK>
0x8952	0x5618	#<CJK>
0x8953	0x5504	#<CJK>
0x8954	0x6B1D	#<CJK>
0x8955	0x851A	#<CJK>
0x8956	0x9C3B	#<CJK>
0x8957	0x59E5	#<CJK>
0x8958	0x53A9	#<CJK>
0x8959	0x6D66	#<CJK>
0x895A	0x74DC	#<CJK>
0x895B	0x958F	#<CJK>
0x895C	0x5642	#<CJK>
0x895D	0x4E91	#<CJK>
0x895E	0x904B	#<CJK>
0x895F	0x96F2	#<CJK>
0x8960	0x834F	#<CJK>
0x8961	0x990C	#<CJK>
0x8962	0x53E1	#<CJK>
0x8963	0x55B6	#<CJK>
0x8964	0x5B30	#<CJK>
0x8965	0x5F71	#<CJK>
0x8966	0x6620	#<CJK>
0x8967	0x66F3	#<CJK>
0x8968	0x6804	#<CJK>
0x8969	0x6C38	#<CJK>
0x896A	0x6CF3	#<CJK>
0x896B	0x6D29	#<CJK>
0x896C	0x745B	#<CJK>
0x896D	0x76C8	#<CJK>
0x896E	0x7A4E	#<CJK>
0x896F	0x9834	#<CJK>
0x8970	0x82F1	#<CJK>
0x8971	0x885B	#<CJK>
0x8972	0x8A60	#<CJK>
0x8973	0x92ED	#<CJK>
0x8974	0x6DB2	#<CJK>
0x8975	0x75AB	#<CJK>
0x8976	0x76CA	#<CJK>
0x8977	0x99C5	#<CJK>
0x8978	0x60A6	#<CJK>
0x8979	0x8B01	#<CJK>
0x897A	0x8D8A	#<CJK>
0x897B	0x95B2	#<CJK>
0x897C	0x698E	#<CJK>
0x897D	0x53AD	#<CJK>
0x897E	0x5186	#<CJK>
0x8980	0x5712	#<CJK>
0x8981	0x5830	#<CJK>
0x8982	0x5944	#<CJK>
0x8983	0x5BB4	#<CJK>
0x8984	0x5EF6	#<CJK>
0x8985	0x6028	#<CJK>
0x8986	0x63A9	#<CJK>
0x8987	0x63F4	#<CJK>
0x8988	0x6CBF	#<CJK>
0x8989	0x6F14	#<CJK>
0x898A	0x708E	#<CJK>
0x898B	0x7114	#<CJK>
0x898C	0x7159	#<CJK>
0x898D	0x71D5	#<CJK>
0x898E	0x733F	#<CJK>
0x898F	0x7E01	#<CJK>
0x8990	0x8276	#<CJK>
0x8991	0x82D1	#<CJK>
0x8992	0x8597	#<CJK>
0x8993	0x9060	#<CJK>
0x8994	0x925B	#<CJK>
0x8995	0x9D1B	#<CJK>
0x8996	0x5869	#<CJK>
0x8997	0x65BC	#<CJK>
0x8998	0x6C5A	#<CJK>
0x8999	0x7525	#<CJK>
0x899A	0x51F9	#<CJK>
0x899B	0x592E	#<CJK>
0x899C	0x5965	#<CJK>
0x899D	0x5F80	#<CJK>
0x899E	0x5FDC	#<CJK>
0x899F	0x62BC	#<CJK>
0x89A0	0x65FA	#<CJK>
0x89A1	0x6A2A	#<CJK>
0x89A2	0x6B27	#<CJK>
0x89A3	0x6BB4	#<CJK>
0x89A4	0x738B	#<CJK>
0x89A5	0x7FC1	#<CJK>
0x89A6	0x8956	#<CJK>
0x89A7	0x9D2C	#<CJK>
0x89A8	0x9D0E	#<CJK>
0x89A9	0x9EC4	#<CJK>
0x89AA	0x5CA1	#<CJK>
0x89AB	0x6C96	#<CJK>
0x89AC	0x837B	#<CJK>
0x89AD	0x5104	#<CJK>
0x89AE	0x5C4B	#<CJK>
0x89AF	0x61B6	#<CJK>
0x89B0	0x81C6	#<CJK>
0x89B1	0x6876	#<CJK>
0x89B2	0x7261	#<CJK>
0x89B3	0x4E59	#<CJK>
0x89B4	0x4FFA	#<CJK>
0x89B5	0x5378	#<CJK>
0x89B6	0x6069	#<CJK>
0x89B7	0x6E29	#<CJK>
0x89B8	0x7A4F	#<CJK>
0x89B9	0x97F3	#<CJK>
0x89BA	0x4E0B	#<CJK>
0x89BB	0x5316	#<CJK>
0x89BC	0x4EEE	#<CJK>
0x89BD	0x4F55	#<CJK>
0x89BE	0x4F3D	#<CJK>
0x89BF	0x4FA1	#<CJK>
0x89C0	0x4F73	#<CJK>
0x89C1	0x52A0	#<CJK>
0x89C2	0x53EF	#<CJK>
0x89C3	0x5609	#<CJK>
0x89C4	0x590F	#<CJK>
0x89C5	0x5AC1	#<CJK>
0x89C6	0x5BB6	#<CJK>
0x89C7	0x5BE1	#<CJK>
0x89C8	0x79D1	#<CJK>
0x89C9	0x6687	#<CJK>
0x89CA	0x679C	#<CJK>
0x89CB	0x67B6	#<CJK>
0x89CC	0x6B4C	#<CJK>
0x89CD	0x6CB3	#<CJK>
0x89CE	0x706B	#<CJK>
0x89CF	0x73C2	#<CJK>
0x89D0	0x798D	#<CJK>
0x89D1	0x79BE	#<CJK>
0x89D2	0x7A3C	#<CJK>
0x89D3	0x7B87	#<CJK>
0x89D4	0x82B1	#<CJK>
0x89D5	0x82DB	#<CJK>
0x89D6	0x8304	#<CJK>
0x89D7	0x8377	#<CJK>
0x89D8	0x83EF	#<CJK>
0x89D9	0x83D3	#<CJK>
0x89DA	0x8766	#<CJK>
0x89DB	0x8AB2	#<CJK>
0x89DC	0x5629	#<CJK>
0x89DD	0x8CA8	#<CJK>
0x89DE	0x8FE6	#<CJK>
0x89DF	0x904E	#<CJK>
0x89E0	0x971E	#<CJK>
0x89E1	0x868A	#<CJK>
0x89E2	0x4FC4	#<CJK>
0x89E3	0x5CE8	#<CJK>
0x89E4	0x6211	#<CJK>
0x89E5	0x7259	#<CJK>
0x89E6	0x753B	#<CJK>
0x89E7	0x81E5	#<CJK>
0x89E8	0x82BD	#<CJK>
0x89E9	0x86FE	#<CJK>
0x89EA	0x8CC0	#<CJK>
0x89EB	0x96C5	#<CJK>
0x89EC	0x9913	#<CJK>
0x89ED	0x99D5	#<CJK>
0x89EE	0x4ECB	#<CJK>
0x89EF	0x4F1A	#<CJK>
0x89F0	0x89E3	#<CJK>
0x89F1	0x56DE	#<CJK>
0x89F2	0x584A	#<CJK>
0x89F3	0x58CA	#<CJK>
0x89F4	0x5EFB	#<CJK>
0x89F5	0x5FEB	#<CJK>
0x89F6	0x602A	#<CJK>
0x89F7	0x6094	#<CJK>
0x89F8	0x6062	#<CJK>
0x89F9	0x61D0	#<CJK>
0x89FA	0x6212	#<CJK>
0x89FB	0x62D0	#<CJK>
0x89FC	0x6539	#<CJK>
0x8A40	0x9B41	#<CJK>
0x8A41	0x6666	#<CJK>
0x8A42	0x68B0	#<CJK>
0x8A43	0x6D77	#<CJK>
0x8A44	0x7070	#<CJK>
0x8A45	0x754C	#<CJK>
0x8A46	0x7686	#<CJK>
0x8A47	0x7D75	#<CJK>
0x8A48	0x82A5	#<CJK>
0x8A49	0x87F9	#<CJK>
0x8A4A	0x958B	#<CJK>
0x8A4B	0x968E	#<CJK>
0x8A4C	0x8C9D	#<CJK>
0x8A4D	0x51F1	#<CJK>
0x8A4E	0x52BE	#<CJK>
0x8A4F	0x5916	#<CJK>
0x8A50	0x54B3	#<CJK>
0x8A51	0x5BB3	#<CJK>
0x8A52	0x5D16	#<CJK>
0x8A53	0x6168	#<CJK>
0x8A54	0x6982	#<CJK>
0x8A55	0x6DAF	#<CJK>
0x8A56	0x788D	#<CJK>
0x8A57	0x84CB	#<CJK>
0x8A58	0x8857	#<CJK>
0x8A59	0x8A72	#<CJK>
0x8A5A	0x93A7	#<CJK>
0x8A5B	0x9AB8	#<CJK>
0x8A5C	0x6D6C	#<CJK>
0x8A5D	0x99A8	#<CJK>
0x8A5E	0x86D9	#<CJK>
0x8A5F	0x57A3	#<CJK>
0x8A60	0x67FF	#<CJK>
0x8A61	0x86CE	#<CJK>
0x8A62	0x920E	#<CJK>
0x8A63	0x5283	#<CJK>
0x8A64	0x5687	#<CJK>
0x8A65	0x5404	#<CJK>
0x8A66	0x5ED3	#<CJK>
0x8A67	0x62E1	#<CJK>
0x8A68	0x64B9	#<CJK>
0x8A69	0x683C	#<CJK>
0x8A6A	0x6838	#<CJK>
0x8A6B	0x6BBB	#<CJK>
0x8A6C	0x7372	#<CJK>
0x8A6D	0x78BA	#<CJK>
0x8A6E	0x7A6B	#<CJK>
0x8A6F	0x899A	#<CJK>
0x8A70	0x89D2	#<CJK>
0x8A71	0x8D6B	#<CJK>
0x8A72	0x8F03	#<CJK>
0x8A73	0x90ED	#<CJK>
0x8A74	0x95A3	#<CJK>
0x8A75	0x9694	#<CJK>
0x8A76	0x9769	#<CJK>
0x8A77	0x5B66	#<CJK>
0x8A78	0x5CB3	#<CJK>
0x8A79	0x697D	#<CJK>
0x8A7A	0x984D	#<CJK>
0x8A7B	0x984E	#<CJK>
0x8A7C	0x639B	#<CJK>
0x8A7D	0x7B20	#<CJK>
0x8A7E	0x6A2B	#<CJK>
0x8A80	0x6A7F	#<CJK>
0x8A81	0x68B6	#<CJK>
0x8A82	0x9C0D	#<CJK>
0x8A83	0x6F5F	#<CJK>
0x8A84	0x5272	#<CJK>
0x8A85	0x559D	#<CJK>
0x8A86	0x6070	#<CJK>
0x8A87	0x62EC	#<CJK>
0x8A88	0x6D3B	#<CJK>
0x8A89	0x6E07	#<CJK>
0x8A8A	0x6ED1	#<CJK>
0x8A8B	0x845B	#<CJK>
0x8A8C	0x8910	#<CJK>
0x8A8D	0x8F44	#<CJK>
0x8A8E	0x4E14	#<CJK>
0x8A8F	0x9C39	#<CJK>
0x8A90	0x53F6	#<CJK>
0x8A91	0x691B	#<CJK>
0x8A92	0x6A3A	#<CJK>
0x8A93	0x9784	#<CJK>
0x8A94	0x682A	#<CJK>
0x8A95	0x515C	#<CJK>
0x8A96	0x7AC3	#<CJK>
0x8A97	0x84B2	#<CJK>
0x8A98	0x91DC	#<CJK>
0x8A99	0x938C	#<CJK>
0x8A9A	0x565B	#<CJK>
0x8A9B	0x9D28	#<CJK>
0x8A9C	0x6822	#<CJK>
0x8A9D	0x8305	#<CJK>
0x8A9E	0x8431	#<CJK>
0x8A9F	0x7CA5	#<CJK>
0x8AA0	0x5208	#<CJK>
0x8AA1	0x82C5	#<CJK>
0x8AA2	0x74E6	#<CJK>
0x8AA3	0x4E7E	#<CJK>
0x8AA4	0x4F83	#<CJK>
0x8AA5	0x51A0	#<CJK>
0x8AA6	0x5BD2	#<CJK>
0x8AA7	0x520A	#<CJK>
0x8AA8	0x52D8	#<CJK>
0x8AA9	0x52E7	#<CJK>
0x8AAA	0x5DFB	#<CJK>
0x8AAB	0x559A	#<CJK>
0x8AAC	0x582A	#<CJK>
0x8AAD	0x59E6	#<CJK>
0x8AAE	0x5B8C	#<CJK>
0x8AAF	0x5B98	#<CJK>
0x8AB0	0x5BDB	#<CJK>
0x8AB1	0x5E72	#<CJK>
0x8AB2	0x5E79	#<CJK>
0x8AB3	0x60A3	#<CJK>
0x8AB4	0x611F	#<CJK>
0x8AB5	0x6163	#<CJK>
0x8AB6	0x61BE	#<CJK>
0x8AB7	0x63DB	#<CJK>
0x8AB8	0x6562	#<CJK>
0x8AB9	0x67D1	#<CJK>
0x8ABA	0x6853	#<CJK>
0x8ABB	0x68FA	#<CJK>
0x8ABC	0x6B3E	#<CJK>
0x8ABD	0x6B53	#<CJK>
0x8ABE	0x6C57	#<CJK>
0x8ABF	0x6F22	#<CJK>
0x8AC0	0x6F97	#<CJK>
0x8AC1	0x6F45	#<CJK>
0x8AC2	0x74B0	#<CJK>
0x8AC3	0x7518	#<CJK>
0x8AC4	0x76E3	#<CJK>
0x8AC5	0x770B	#<CJK>
0x8AC6	0x7AFF	#<CJK>
0x8AC7	0x7BA1	#<CJK>
0x8AC8	0x7C21	#<CJK>
0x8AC9	0x7DE9	#<CJK>
0x8ACA	0x7F36	#<CJK>
0x8ACB	0x7FF0	#<CJK>
0x8ACC	0x809D	#<CJK>
0x8ACD	0x8266	#<CJK>
0x8ACE	0x839E	#<CJK>
0x8ACF	0x89B3	#<CJK>
0x8AD0	0x8ACC	#<CJK>
0x8AD1	0x8CAB	#<CJK>
0x8AD2	0x9084	#<CJK>
0x8AD3	0x9451	#<CJK>
0x8AD4	0x9593	#<CJK>
0x8AD5	0x9591	#<CJK>
0x8AD6	0x95A2	#<CJK>
0x8AD7	0x9665	#<CJK>
0x8AD8	0x97D3	#<CJK>
0x8AD9	0x9928	#<CJK>
0x8ADA	0x8218	#<CJK>
0x8ADB	0x4E38	#<CJK>
0x8ADC	0x542B	#<CJK>
0x8ADD	0x5CB8	#<CJK>
0x8ADE	0x5DCC	#<CJK>
0x8ADF	0x73A9	#<CJK>
0x8AE0	0x764C	#<CJK>
0x8AE1	0x773C	#<CJK>
0x8AE2	0x5CA9	#<CJK>
0x8AE3	0x7FEB	#<CJK>
0x8AE4	0x8D0B	#<CJK>
0x8AE5	0x96C1	#<CJK>
0x8AE6	0x9811	#<CJK>
0x8AE7	0x9854	#<CJK>
0x8AE8	0x9858	#<CJK>
0x8AE9	0x4F01	#<CJK>
0x8AEA	0x4F0E	#<CJK>
0x8AEB	0x5371	#<CJK>
0x8AEC	0x559C	#<CJK>
0x8AED	0x5668	#<CJK>
0x8AEE	0x57FA	#<CJK>
0x8AEF	0x5947	#<CJK>
0x8AF0	0x5B09	#<CJK>
0x8AF1	0x5BC4	#<CJK>
0x8AF2	0x5C90	#<CJK>
0x8AF3	0x5E0C	#<CJK>
0x8AF4	0x5E7E	#<CJK>
0x8AF5	0x5FCC	#<CJK>
0x8AF6	0x63EE	#<CJK>
0x8AF7	0x673A	#<CJK>
0x8AF8	0x65D7	#<CJK>
0x8AF9	0x65E2	#<CJK>
0x8AFA	0x671F	#<CJK>
0x8AFB	0x68CB	#<CJK>
0x8AFC	0x68C4	#<CJK>
0x8B40	0x6A5F	#<CJK>
0x8B41	0x5E30	#<CJK>
0x8B42	0x6BC5	#<CJK>
0x8B43	0x6C17	#<CJK>
0x8B44	0x6C7D	#<CJK>
0x8B45	0x757F	#<CJK>
0x8B46	0x7948	#<CJK>
0x8B47	0x5B63	#<CJK>
0x8B48	0x7A00	#<CJK>
0x8B49	0x7D00	#<CJK>
0x8B4A	0x5FBD	#<CJK>
0x8B4B	0x898F	#<CJK>
0x8B4C	0x8A18	#<CJK>
0x8B4D	0x8CB4	#<CJK>
0x8B4E	0x8D77	#<CJK>
0x8B4F	0x8ECC	#<CJK>
0x8B50	0x8F1D	#<CJK>
0x8B51	0x98E2	#<CJK>
0x8B52	0x9A0E	#<CJK>
0x8B53	0x9B3C	#<CJK>
0x8B54	0x4E80	#<CJK>
0x8B55	0x507D	#<CJK>
0x8B56	0x5100	#<CJK>
0x8B57	0x5993	#<CJK>
0x8B58	0x5B9C	#<CJK>
0x8B59	0x622F	#<CJK>
0x8B5A	0x6280	#<CJK>
0x8B5B	0x64EC	#<CJK>
0x8B5C	0x6B3A	#<CJK>
0x8B5D	0x72A0	#<CJK>
0x8B5E	0x7591	#<CJK>
0x8B5F	0x7947	#<CJK>
0x8B60	0x7FA9	#<CJK>
0x8B61	0x87FB	#<CJK>
0x8B62	0x8ABC	#<CJK>
0x8B63	0x8B70	#<CJK>
0x8B64	0x63AC	#<CJK>
0x8B65	0x83CA	#<CJK>
0x8B66	0x97A0	#<CJK>
0x8B67	0x5409	#<CJK>
0x8B68	0x5403	#<CJK>
0x8B69	0x55AB	#<CJK>
0x8B6A	0x6854	#<CJK>
0x8B6B	0x6A58	#<CJK>
0x8B6C	0x8A70	#<CJK>
0x8B6D	0x7827	#<CJK>
0x8B6E	0x6775	#<CJK>
0x8B6F	0x9ECD	#<CJK>
0x8B70	0x5374	#<CJK>
0x8B71	0x5BA2	#<CJK>
0x8B72	0x811A	#<CJK>
0x8B73	0x8650	#<CJK>
0x8B74	0x9006	#<CJK>
0x8B75	0x4E18	#<CJK>
0x8B76	0x4E45	#<CJK>
0x8B77	0x4EC7	#<CJK>
0x8B78	0x4F11	#<CJK>
0x8B79	0x53CA	#<CJK>
0x8B7A	0x5438	#<CJK>
0x8B7B	0x5BAE	#<CJK>
0x8B7C	0x5F13	#<CJK>
0x8B7D	0x6025	#<CJK>
0x8B7E	0x6551	#<CJK>
0x8B80	0x673D	#<CJK>
0x8B81	0x6C42	#<CJK>
0x8B82	0x6C72	#<CJK>
0x8B83	0x6CE3	#<CJK>
0x8B84	0x7078	#<CJK>
0x8B85	0x7403	#<CJK>
0x8B86	0x7A76	#<CJK>
0x8B87	0x7AAE	#<CJK>
0x8B88	0x7B08	#<CJK>
0x8B89	0x7D1A	#<CJK>
0x8B8A	0x7CFE	#<CJK>
0x8B8B	0x7D66	#<CJK>
0x8B8C	0x65E7	#<CJK>
0x8B8D	0x725B	#<CJK>
0x8B8E	0x53BB	#<CJK>
0x8B8F	0x5C45	#<CJK>
0x8B90	0x5DE8	#<CJK>
0x8B91	0x62D2	#<CJK>
0x8B92	0x62E0	#<CJK>
0x8B93	0x6319	#<CJK>
0x8B94	0x6E20	#<CJK>
0x8B95	0x865A	#<CJK>
0x8B96	0x8A31	#<CJK>
0x8B97	0x8DDD	#<CJK>
0x8B98	0x92F8	#<CJK>
0x8B99	0x6F01	#<CJK>
0x8B9A	0x79A6	#<CJK>
0x8B9B	0x9B5A	#<CJK>
0x8B9C	0x4EA8	#<CJK>
0x8B9D	0x4EAB	#<CJK>
0x8B9E	0x4EAC	#<CJK>
0x8B9F	0x4F9B	#<CJK>
0x8BA0	0x4FA0	#<CJK>
0x8BA1	0x50D1	#<CJK>
0x8BA2	0x5147	#<CJK>
0x8BA3	0x7AF6	#<CJK>
0x8BA4	0x5171	#<CJK>
0x8BA5	0x51F6	#<CJK>
0x8BA6	0x5354	#<CJK>
0x8BA7	0x5321	#<CJK>
0x8BA8	0x537F	#<CJK>
0x8BA9	0x53EB	#<CJK>
0x8BAA	0x55AC	#<CJK>
0x8BAB	0x5883	#<CJK>
0x8BAC	0x5CE1	#<CJK>
0x8BAD	0x5F37	#<CJK>
0x8BAE	0x5F4A	#<CJK>
0x8BAF	0x602F	#<CJK>
0x8BB0	0x6050	#<CJK>
0x8BB1	0x606D	#<CJK>
0x8BB2	0x631F	#<CJK>
0x8BB3	0x6559	#<CJK>
0x8BB4	0x6A4B	#<CJK>
0x8BB5	0x6CC1	#<CJK>
0x8BB6	0x72C2	#<CJK>
0x8BB7	0x72ED	#<CJK>
0x8BB8	0x77EF	#<CJK>
0x8BB9	0x80F8	#<CJK>
0x8BBA	0x8105	#<CJK>
0x8BBB	0x8208	#<CJK>
0x8BBC	0x854E	#<CJK>
0x8BBD	0x90F7	#<CJK>
0x8BBE	0x93E1	#<CJK>
0x8BBF	0x97FF	#<CJK>
0x8BC0	0x9957	#<CJK>
0x8BC1	0x9A5A	#<CJK>
0x8BC2	0x4EF0	#<CJK>
0x8BC3	0x51DD	#<CJK>
0x8BC4	0x5C2D	#<CJK>
0x8BC5	0x6681	#<CJK>
0x8BC6	0x696D	#<CJK>
0x8BC7	0x5C40	#<CJK>
0x8BC8	0x66F2	#<CJK>
0x8BC9	0x6975	#<CJK>
0x8BCA	0x7389	#<CJK>
0x8BCB	0x6850	#<CJK>
0x8BCC	0x7C81	#<CJK>
0x8BCD	0x50C5	#<CJK>
0x8BCE	0x52E4	#<CJK>
0x8BCF	0x5747	#<CJK>
0x8BD0	0x5DFE	#<CJK>
0x8BD1	0x9326	#<CJK>
0x8BD2	0x65A4	#<CJK>
0x8BD3	0x6B23	#<CJK>
0x8BD4	0x6B3D	#<CJK>
0x8BD5	0x7434	#<CJK>
0x8BD6	0x7981	#<CJK>
0x8BD7	0x79BD	#<CJK>
0x8BD8	0x7B4B	#<CJK>
0x8BD9	0x7DCA	#<CJK>
0x8BDA	0x82B9	#<CJK>
0x8BDB	0x83CC	#<CJK>
0x8BDC	0x887F	#<CJK>
0x8BDD	0x895F	#<CJK>
0x8BDE	0x8B39	#<CJK>
0x8BDF	0x8FD1	#<CJK>
0x8BE0	0x91D1	#<CJK>
0x8BE1	0x541F	#<CJK>
0x8BE2	0x9280	#<CJK>
0x8BE3	0x4E5D	#<CJK>
0x8BE4	0x5036	#<CJK>
0x8BE5	0x53E5	#<CJK>
0x8BE6	0x533A	#<CJK>
0x8BE7	0x72D7	#<CJK>
0x8BE8	0x7396	#<CJK>
0x8BE9	0x77E9	#<CJK>
0x8BEA	0x82E6	#<CJK>
0x8BEB	0x8EAF	#<CJK>
0x8BEC	0x99C6	#<CJK>
0x8BED	0x99C8	#<CJK>
0x8BEE	0x99D2	#<CJK>
0x8BEF	0x5177	#<CJK>
0x8BF0	0x611A	#<CJK>
0x8BF1	0x865E	#<CJK>
0x8BF2	0x55B0	#<CJK>
0x8BF3	0x7A7A	#<CJK>
0x8BF4	0x5076	#<CJK>
0x8BF5	0x5BD3	#<CJK>
0x8BF6	0x9047	#<CJK>
0x8BF7	0x9685	#<CJK>
0x8BF8	0x4E32	#<CJK>
0x8BF9	0x6ADB	#<CJK>
0x8BFA	0x91E7	#<CJK>
0x8BFB	0x5C51	#<CJK>
0x8BFC	0x5C48	#<CJK>
0x8C40	0x6398	#<CJK>
0x8C41	0x7A9F	#<CJK>
0x8C42	0x6C93	#<CJK>
0x8C43	0x9774	#<CJK>
0x8C44	0x8F61	#<CJK>
0x8C45	0x7AAA	#<CJK>
0x8C46	0x718A	#<CJK>
0x8C47	0x9688	#<CJK>
0x8C48	0x7C82	#<CJK>
0x8C49	0x6817	#<CJK>
0x8C4A	0x7E70	#<CJK>
0x8C4B	0x6851	#<CJK>
0x8C4C	0x936C	#<CJK>
0x8C4D	0x52F2	#<CJK>
0x8C4E	0x541B	#<CJK>
0x8C4F	0x85AB	#<CJK>
0x8C50	0x8A13	#<CJK>
0x8C51	0x7FA4	#<CJK>
0x8C52	0x8ECD	#<CJK>
0x8C53	0x90E1	#<CJK>
0x8C54	0x5366	#<CJK>
0x8C55	0x8888	#<CJK>
0x8C56	0x7941	#<CJK>
0x8C57	0x4FC2	#<CJK>
0x8C58	0x50BE	#<CJK>
0x8C59	0x5211	#<CJK>
0x8C5A	0x5144	#<CJK>
0x8C5B	0x5553	#<CJK>
0x8C5C	0x572D	#<CJK>
0x8C5D	0x73EA	#<CJK>
0x8C5E	0x578B	#<CJK>
0x8C5F	0x5951	#<CJK>
0x8C60	0x5F62	#<CJK>
0x8C61	0x5F84	#<CJK>
0x8C62	0x6075	#<CJK>
0x8C63	0x6176	#<CJK>
0x8C64	0x6167	#<CJK>
0x8C65	0x61A9	#<CJK>
0x8C66	0x63B2	#<CJK>
0x8C67	0x643A	#<CJK>
0x8C68	0x656C	#<CJK>
0x8C69	0x666F	#<CJK>
0x8C6A	0x6842	#<CJK>
0x8C6B	0x6E13	#<CJK>
0x8C6C	0x7566	#<CJK>
0x8C6D	0x7A3D	#<CJK>
0x8C6E	0x7CFB	#<CJK>
0x8C6F	0x7D4C	#<CJK>
0x8C70	0x7D99	#<CJK>
0x8C71	0x7E4B	#<CJK>
0x8C72	0x7F6B	#<CJK>
0x8C73	0x830E	#<CJK>
0x8C74	0x834A	#<CJK>
0x8C75	0x86CD	#<CJK>
0x8C76	0x8A08	#<CJK>
0x8C77	0x8A63	#<CJK>
0x8C78	0x8B66	#<CJK>
0x8C79	0x8EFD	#<CJK>
0x8C7A	0x981A	#<CJK>
0x8C7B	0x9D8F	#<CJK>
0x8C7C	0x82B8	#<CJK>
0x8C7D	0x8FCE	#<CJK>
0x8C7E	0x9BE8	#<CJK>
0x8C80	0x5287	#<CJK>
0x8C81	0x621F	#<CJK>
0x8C82	0x6483	#<CJK>
0x8C83	0x6FC0	#<CJK>
0x8C84	0x9699	#<CJK>
0x8C85	0x6841	#<CJK>
0x8C86	0x5091	#<CJK>
0x8C87	0x6B20	#<CJK>
0x8C88	0x6C7A	#<CJK>
0x8C89	0x6F54	#<CJK>
0x8C8A	0x7A74	#<CJK>
0x8C8B	0x7D50	#<CJK>
0x8C8C	0x8840	#<CJK>
0x8C8D	0x8A23	#<CJK>
0x8C8E	0x6708	#<CJK>
0x8C8F	0x4EF6	#<CJK>
0x8C90	0x5039	#<CJK>
0x8C91	0x5026	#<CJK>
0x8C92	0x5065	#<CJK>
0x8C93	0x517C	#<CJK>
0x8C94	0x5238	#<CJK>
0x8C95	0x5263	#<CJK>
0x8C96	0x55A7	#<CJK>
0x8C97	0x570F	#<CJK>
0x8C98	0x5805	#<CJK>
0x8C99	0x5ACC	#<CJK>
0x8C9A	0x5EFA	#<CJK>
0x8C9B	0x61B2	#<CJK>
0x8C9C	0x61F8	#<CJK>
0x8C9D	0x62F3	#<CJK>
0x8C9E	0x6372	#<CJK>
0x8C9F	0x691C	#<CJK>
0x8CA0	0x6A29	#<CJK>
0x8CA1	0x727D	#<CJK>
0x8CA2	0x72AC	#<CJK>
0x8CA3	0x732E	#<CJK>
0x8CA4	0x7814	#<CJK>
0x8CA5	0x786F	#<CJK>
0x8CA6	0x7D79	#<CJK>
0x8CA7	0x770C	#<CJK>
0x8CA8	0x80A9	#<CJK>
0x8CA9	0x898B	#<CJK>
0x8CAA	0x8B19	#<CJK>
0x8CAB	0x8CE2	#<CJK>
0x8CAC	0x8ED2	#<CJK>
0x8CAD	0x9063	#<CJK>
0x8CAE	0x9375	#<CJK>
0x8CAF	0x967A	#<CJK>
0x8CB0	0x9855	#<CJK>
0x8CB1	0x9A13	#<CJK>
0x8CB2	0x9E78	#<CJK>
0x8CB3	0x5143	#<CJK>
0x8CB4	0x539F	#<CJK>
0x8CB5	0x53B3	#<CJK>
0x8CB6	0x5E7B	#<CJK>
0x8CB7	0x5F26	#<CJK>
0x8CB8	0x6E1B	#<CJK>
0x8CB9	0x6E90	#<CJK>
0x8CBA	0x7384	#<CJK>
0x8CBB	0x73FE	#<CJK>
0x8CBC	0x7D43	#<CJK>
0x8CBD	0x8237	#<CJK>
0x8CBE	0x8A00	#<CJK>
0x8CBF	0x8AFA	#<CJK>
0x8CC0	0x9650	#<CJK>
0x8CC1	0x4E4E	#<CJK>
0x8CC2	0x500B	#<CJK>
0x8CC3	0x53E4	#<CJK>
0x8CC4	0x547C	#<CJK>
0x8CC5	0x56FA	#<CJK>
0x8CC6	0x59D1	#<CJK>
0x8CC7	0x5B64	#<CJK>
0x8CC8	0x5DF1	#<CJK>
0x8CC9	0x5EAB	#<CJK>
0x8CCA	0x5F27	#<CJK>
0x8CCB	0x6238	#<CJK>
0x8CCC	0x6545	#<CJK>
0x8CCD	0x67AF	#<CJK>
0x8CCE	0x6E56	#<CJK>
0x8CCF	0x72D0	#<CJK>
0x8CD0	0x7CCA	#<CJK>
0x8CD1	0x88B4	#<CJK>
0x8CD2	0x80A1	#<CJK>
0x8CD3	0x80E1	#<CJK>
0x8CD4	0x83F0	#<CJK>
0x8CD5	0x864E	#<CJK>
0x8CD6	0x8A87	#<CJK>
0x8CD7	0x8DE8	#<CJK>
0x8CD8	0x9237	#<CJK>
0x8CD9	0x96C7	#<CJK>
0x8CDA	0x9867	#<CJK>
0x8CDB	0x9F13	#<CJK>
0x8CDC	0x4E94	#<CJK>
0x8CDD	0x4E92	#<CJK>
0x8CDE	0x4F0D	#<CJK>
0x8CDF	0x5348	#<CJK>
0x8CE0	0x5449	#<CJK>
0x8CE1	0x543E	#<CJK>
0x8CE2	0x5A2F	#<CJK>
0x8CE3	0x5F8C	#<CJK>
0x8CE4	0x5FA1	#<CJK>
0x8CE5	0x609F	#<CJK>
0x8CE6	0x68A7	#<CJK>
0x8CE7	0x6A8E	#<CJK>
0x8CE8	0x745A	#<CJK>
0x8CE9	0x7881	#<CJK>
0x8CEA	0x8A9E	#<CJK>
0x8CEB	0x8AA4	#<CJK>
0x8CEC	0x8B77	#<CJK>
0x8CED	0x9190	#<CJK>
0x8CEE	0x4E5E	#<CJK>
0x8CEF	0x9BC9	#<CJK>
0x8CF0	0x4EA4	#<CJK>
0x8CF1	0x4F7C	#<CJK>
0x8CF2	0x4FAF	#<CJK>
0x8CF3	0x5019	#<CJK>
0x8CF4	0x5016	#<CJK>
0x8CF5	0x5149	#<CJK>
0x8CF6	0x516C	#<CJK>
0x8CF7	0x529F	#<CJK>
0x8CF8	0x52B9	#<CJK>
0x8CF9	0x52FE	#<CJK>
0x8CFA	0x539A	#<CJK>
0x8CFB	0x53E3	#<CJK>
0x8CFC	0x5411	#<CJK>
0x8D40	0x540E	#<CJK>
0x8D41	0x5589	#<CJK>
0x8D42	0x5751	#<CJK>
0x8D43	0x57A2	#<CJK>
0x8D44	0x597D	#<CJK>
0x8D45	0x5B54	#<CJK>
0x8D46	0x5B5D	#<CJK>
0x8D47	0x5B8F	#<CJK>
0x8D48	0x5DE5	#<CJK>
0x8D49	0x5DE7	#<CJK>
0x8D4A	0x5DF7	#<CJK>
0x8D4B	0x5E78	#<CJK>
0x8D4C	0x5E83	#<CJK>
0x8D4D	0x5E9A	#<CJK>
0x8D4E	0x5EB7	#<CJK>
0x8D4F	0x5F18	#<CJK>
0x8D50	0x6052	#<CJK>
0x8D51	0x614C	#<CJK>
0x8D52	0x6297	#<CJK>
0x8D53	0x62D8	#<CJK>
0x8D54	0x63A7	#<CJK>
0x8D55	0x653B	#<CJK>
0x8D56	0x6602	#<CJK>
0x8D57	0x6643	#<CJK>
0x8D58	0x66F4	#<CJK>
0x8D59	0x676D	#<CJK>
0x8D5A	0x6821	#<CJK>
0x8D5B	0x6897	#<CJK>
0x8D5C	0x69CB	#<CJK>
0x8D5D	0x6C5F	#<CJK>
0x8D5E	0x6D2A	#<CJK>
0x8D5F	0x6D69	#<CJK>
0x8D60	0x6E2F	#<CJK>
0x8D61	0x6E9D	#<CJK>
0x8D62	0x7532	#<CJK>
0x8D63	0x7687	#<CJK>
0x8D64	0x786C	#<CJK>
0x8D65	0x7A3F	#<CJK>
0x8D66	0x7CE0	#<CJK>
0x8D67	0x7D05	#<CJK>
0x8D68	0x7D18	#<CJK>
0x8D69	0x7D5E	#<CJK>
0x8D6A	0x7DB1	#<CJK>
0x8D6B	0x8015	#<CJK>
0x8D6C	0x8003	#<CJK>
0x8D6D	0x80AF	#<CJK>
0x8D6E	0x80B1	#<CJK>
0x8D6F	0x8154	#<CJK>
0x8D70	0x818F	#<CJK>
0x8D71	0x822A	#<CJK>
0x8D72	0x8352	#<CJK>
0x8D73	0x884C	#<CJK>
0x8D74	0x8861	#<CJK>
0x8D75	0x8B1B	#<CJK>
0x8D76	0x8CA2	#<CJK>
0x8D77	0x8CFC	#<CJK>
0x8D78	0x90CA	#<CJK>
0x8D79	0x9175	#<CJK>
0x8D7A	0x9271	#<CJK>
0x8D7B	0x783F	#<CJK>
0x8D7C	0x92FC	#<CJK>
0x8D7D	0x95A4	#<CJK>
0x8D7E	0x964D	#<CJK>
0x8D80	0x9805	#<CJK>
0x8D81	0x9999	#<CJK>
0x8D82	0x9AD8	#<CJK>
0x8D83	0x9D3B	#<CJK>
0x8D84	0x525B	#<CJK>
0x8D85	0x52AB	#<CJK>
0x8D86	0x53F7	#<CJK>
0x8D87	0x5408	#<CJK>
0x8D88	0x58D5	#<CJK>
0x8D89	0x62F7	#<CJK>
0x8D8A	0x6FE0	#<CJK>
0x8D8B	0x8C6A	#<CJK>
0x8D8C	0x8F5F	#<CJK>
0x8D8D	0x9EB9	#<CJK>
0x8D8E	0x514B	#<CJK>
0x8D8F	0x523B	#<CJK>
0x8D90	0x544A	#<CJK>
0x8D91	0x56FD	#<CJK>
0x8D92	0x7A40	#<CJK>
0x8D93	0x9177	#<CJK>
0x8D94	0x9D60	#<CJK>
0x8D95	0x9ED2	#<CJK>
0x8D96	0x7344	#<CJK>
0x8D97	0x6F09	#<CJK>
0x8D98	0x8170	#<CJK>
0x8D99	0x7511	#<CJK>
0x8D9A	0x5FFD	#<CJK>
0x8D9B	0x60DA	#<CJK>
0x8D9C	0x9AA8	#<CJK>
0x8D9D	0x72DB	#<CJK>
0x8D9E	0x8FBC	#<CJK>
0x8D9F	0x6B64	#<CJK>
0x8DA0	0x9803	#<CJK>
0x8DA1	0x4ECA	#<CJK>
0x8DA2	0x56F0	#<CJK>
0x8DA3	0x5764	#<CJK>
0x8DA4	0x58BE	#<CJK>
0x8DA5	0x5A5A	#<CJK>
0x8DA6	0x6068	#<CJK>
0x8DA7	0x61C7	#<CJK>
0x8DA8	0x660F	#<CJK>
0x8DA9	0x6606	#<CJK>
0x8DAA	0x6839	#<CJK>
0x8DAB	0x68B1	#<CJK>
0x8DAC	0x6DF7	#<CJK>
0x8DAD	0x75D5	#<CJK>
0x8DAE	0x7D3A	#<CJK>
0x8DAF	0x826E	#<CJK>
0x8DB0	0x9B42	#<CJK>
0x8DB1	0x4E9B	#<CJK>
0x8DB2	0x4F50	#<CJK>
0x8DB3	0x53C9	#<CJK>
0x8DB4	0x5506	#<CJK>
0x8DB5	0x5D6F	#<CJK>
0x8DB6	0x5DE6	#<CJK>
0x8DB7	0x5DEE	#<CJK>
0x8DB8	0x67FB	#<CJK>
0x8DB9	0x6C99	#<CJK>
0x8DBA	0x7473	#<CJK>
0x8DBB	0x7802	#<CJK>
0x8DBC	0x8A50	#<CJK>
0x8DBD	0x9396	#<CJK>
0x8DBE	0x88DF	#<CJK>
0x8DBF	0x5750	#<CJK>
0x8DC0	0x5EA7	#<CJK>
0x8DC1	0x632B	#<CJK>
0x8DC2	0x50B5	#<CJK>
0x8DC3	0x50AC	#<CJK>
0x8DC4	0x518D	#<CJK>
0x8DC5	0x6700	#<CJK>
0x8DC6	0x54C9	#<CJK>
0x8DC7	0x585E	#<CJK>
0x8DC8	0x59BB	#<CJK>
0x8DC9	0x5BB0	#<CJK>
0x8DCA	0x5F69	#<CJK>
0x8DCB	0x624D	#<CJK>
0x8DCC	0x63A1	#<CJK>
0x8DCD	0x683D	#<CJK>
0x8DCE	0x6B73	#<CJK>
0x8DCF	0x6E08	#<CJK>
0x8DD0	0x707D	#<CJK>
0x8DD1	0x91C7	#<CJK>
0x8DD2	0x7280	#<CJK>
0x8DD3	0x7815	#<CJK>
0x8DD4	0x7826	#<CJK>
0x8DD5	0x796D	#<CJK>
0x8DD6	0x658E	#<CJK>
0x8DD7	0x7D30	#<CJK>
0x8DD8	0x83DC	#<CJK>
0x8DD9	0x88C1	#<CJK>
0x8DDA	0x8F09	#<CJK>
0x8DDB	0x969B	#<CJK>
0x8DDC	0x5264	#<CJK>
0x8DDD	0x5728	#<CJK>
0x8DDE	0x6750	#<CJK>
0x8DDF	0x7F6A	#<CJK>
0x8DE0	0x8CA1	#<CJK>
0x8DE1	0x51B4	#<CJK>
0x8DE2	0x5742	#<CJK>
0x8DE3	0x962A	#<CJK>
0x8DE4	0x583A	#<CJK>
0x8DE5	0x698A	#<CJK>
0x8DE6	0x80B4	#<CJK>
0x8DE7	0x54B2	#<CJK>
0x8DE8	0x5D0E	#<CJK>
0x8DE9	0x57FC	#<CJK>
0x8DEA	0x7895	#<CJK>
0x8DEB	0x9DFA	#<CJK>
0x8DEC	0x4F5C	#<CJK>
0x8DED	0x524A	#<CJK>
0x8DEE	0x548B	#<CJK>
0x8DEF	0x643E	#<CJK>
0x8DF0	0x6628	#<CJK>
0x8DF1	0x6714	#<CJK>
0x8DF2	0x67F5	#<CJK>
0x8DF3	0x7A84	#<CJK>
0x8DF4	0x7B56	#<CJK>
0x8DF5	0x7D22	#<CJK>
0x8DF6	0x932F	#<CJK>
0x8DF7	0x685C	#<CJK>
0x8DF8	0x9BAD	#<CJK>
0x8DF9	0x7B39	#<CJK>
0x8DFA	0x5319	#<CJK>
0x8DFB	0x518A	#<CJK>
0x8DFC	0x5237	#<CJK>
0x8E40	0x5BDF	#<CJK>
0x8E41	0x62F6	#<CJK>
0x8E42	0x64AE	#<CJK>
0x8E43	0x64E6	#<CJK>
0x8E44	0x672D	#<CJK>
0x8E45	0x6BBA	#<CJK>
0x8E46	0x85A9	#<CJK>
0x8E47	0x96D1	#<CJK>
0x8E48	0x7690	#<CJK>
0x8E49	0x9BD6	#<CJK>
0x8E4A	0x634C	#<CJK>
0x8E4B	0x9306	#<CJK>
0x8E4C	0x9BAB	#<CJK>
0x8E4D	0x76BF	#<CJK>
0x8E4E	0x6652	#<CJK>
0x8E4F	0x4E09	#<CJK>
0x8E50	0x5098	#<CJK>
0x8E51	0x53C2	#<CJK>
0x8E52	0x5C71	#<CJK>
0x8E53	0x60E8	#<CJK>
0x8E54	0x6492	#<CJK>
0x8E55	0x6563	#<CJK>
0x8E56	0x685F	#<CJK>
0x8E57	0x71E6	#<CJK>
0x8E58	0x73CA	#<CJK>
0x8E59	0x7523	#<CJK>
0x8E5A	0x7B97	#<CJK>
0x8E5B	0x7E82	#<CJK>
0x8E5C	0x8695	#<CJK>
0x8E5D	0x8B83	#<CJK>
0x8E5E	0x8CDB	#<CJK>
0x8E5F	0x9178	#<CJK>
0x8E60	0x9910	#<CJK>
0x8E61	0x65AC	#<CJK>
0x8E62	0x66AB	#<CJK>
0x8E63	0x6B8B	#<CJK>
0x8E64	0x4ED5	#<CJK>
0x8E65	0x4ED4	#<CJK>
0x8E66	0x4F3A	#<CJK>
0x8E67	0x4F7F	#<CJK>
0x8E68	0x523A	#<CJK>
0x8E69	0x53F8	#<CJK>
0x8E6A	0x53F2	#<CJK>
0x8E6B	0x55E3	#<CJK>
0x8E6C	0x56DB	#<CJK>
0x8E6D	0x58EB	#<CJK>
0x8E6E	0x59CB	#<CJK>
0x8E6F	0x59C9	#<CJK>
0x8E70	0x59FF	#<CJK>
0x8E71	0x5B50	#<CJK>
0x8E72	0x5C4D	#<CJK>
0x8E73	0x5E02	#<CJK>
0x8E74	0x5E2B	#<CJK>
0x8E75	0x5FD7	#<CJK>
0x8E76	0x601D	#<CJK>
0x8E77	0x6307	#<CJK>
0x8E78	0x652F	#<CJK>
0x8E79	0x5B5C	#<CJK>
0x8E7A	0x65AF	#<CJK>
0x8E7B	0x65BD	#<CJK>
0x8E7C	0x65E8	#<CJK>
0x8E7D	0x679D	#<CJK>
0x8E7E	0x6B62	#<CJK>
0x8E80	0x6B7B	#<CJK>
0x8E81	0x6C0F	#<CJK>
0x8E82	0x7345	#<CJK>
0x8E83	0x7949	#<CJK>
0x8E84	0x79C1	#<CJK>
0x8E85	0x7CF8	#<CJK>
0x8E86	0x7D19	#<CJK>
0x8E87	0x7D2B	#<CJK>
0x8E88	0x80A2	#<CJK>
0x8E89	0x8102	#<CJK>
0x8E8A	0x81F3	#<CJK>
0x8E8B	0x8996	#<CJK>
0x8E8C	0x8A5E	#<CJK>
0x8E8D	0x8A69	#<CJK>
0x8E8E	0x8A66	#<CJK>
0x8E8F	0x8A8C	#<CJK>
0x8E90	0x8AEE	#<CJK>
0x8E91	0x8CC7	#<CJK>
0x8E92	0x8CDC	#<CJK>
0x8E93	0x96CC	#<CJK>
0x8E94	0x98FC	#<CJK>
0x8E95	0x6B6F	#<CJK>
0x8E96	0x4E8B	#<CJK>
0x8E97	0x4F3C	#<CJK>
0x8E98	0x4F8D	#<CJK>
0x8E99	0x5150	#<CJK>
0x8E9A	0x5B57	#<CJK>
0x8E9B	0x5BFA	#<CJK>
0x8E9C	0x6148	#<CJK>
0x8E9D	0x6301	#<CJK>
0x8E9E	0x6642	#<CJK>
0x8E9F	0x6B21	#<CJK>
0x8EA0	0x6ECB	#<CJK>
0x8EA1	0x6CBB	#<CJK>
0x8EA2	0x723E	#<CJK>
0x8EA3	0x74BD	#<CJK>
0x8EA4	0x75D4	#<CJK>
0x8EA5	0x78C1	#<CJK>
0x8EA6	0x793A	#<CJK>
0x8EA7	0x800C	#<CJK>
0x8EA8	0x8033	#<CJK>
0x8EA9	0x81EA	#<CJK>
0x8EAA	0x8494	#<CJK>
0x8EAB	0x8F9E	#<CJK>
0x8EAC	0x6C50	#<CJK>
0x8EAD	0x9E7F	#<CJK>
0x8EAE	0x5F0F	#<CJK>
0x8EAF	0x8B58	#<CJK>
0x8EB0	0x9D2B	#<CJK>
0x8EB1	0x7AFA	#<CJK>
0x8EB2	0x8EF8	#<CJK>
0x8EB3	0x5B8D	#<CJK>
0x8EB4	0x96EB	#<CJK>
0x8EB5	0x4E03	#<CJK>
0x8EB6	0x53F1	#<CJK>
0x8EB7	0x57F7	#<CJK>
0x8EB8	0x5931	#<CJK>
0x8EB9	0x5AC9	#<CJK>
0x8EBA	0x5BA4	#<CJK>
0x8EBB	0x6089	#<CJK>
0x8EBC	0x6E7F	#<CJK>
0x8EBD	0x6F06	#<CJK>
0x8EBE	0x75BE	#<CJK>
0x8EBF	0x8CEA	#<CJK>
0x8EC0	0x5B9F	#<CJK>
0x8EC1	0x8500	#<CJK>
0x8EC2	0x7BE0	#<CJK>
0x8EC3	0x5072	#<CJK>
0x8EC4	0x67F4	#<CJK>
0x8EC5	0x829D	#<CJK>
0x8EC6	0x5C61	#<CJK>
0x8EC7	0x854A	#<CJK>
0x8EC8	0x7E1E	#<CJK>
0x8EC9	0x820E	#<CJK>
0x8ECA	0x5199	#<CJK>
0x8ECB	0x5C04	#<CJK>
0x8ECC	0x6368	#<CJK>
0x8ECD	0x8D66	#<CJK>
0x8ECE	0x659C	#<CJK>
0x8ECF	0x716E	#<CJK>
0x8ED0	0x793E	#<CJK>
0x8ED1	0x7D17	#<CJK>
0x8ED2	0x8005	#<CJK>
0x8ED3	0x8B1D	#<CJK>
0x8ED4	0x8ECA	#<CJK>
0x8ED5	0x906E	#<CJK>
0x8ED6	0x86C7	#<CJK>
0x8ED7	0x90AA	#<CJK>
0x8ED8	0x501F	#<CJK>
0x8ED9	0x52FA	#<CJK>
0x8EDA	0x5C3A	#<CJK>
0x8EDB	0x6753	#<CJK>
0x8EDC	0x707C	#<CJK>
0x8EDD	0x7235	#<CJK>
0x8EDE	0x914C	#<CJK>
0x8EDF	0x91C8	#<CJK>
0x8EE0	0x932B	#<CJK>
0x8EE1	0x82E5	#<CJK>
0x8EE2	0x5BC2	#<CJK>
0x8EE3	0x5F31	#<CJK>
0x8EE4	0x60F9	#<CJK>
0x8EE5	0x4E3B	#<CJK>
0x8EE6	0x53D6	#<CJK>
0x8EE7	0x5B88	#<CJK>
0x8EE8	0x624B	#<CJK>
0x8EE9	0x6731	#<CJK>
0x8EEA	0x6B8A	#<CJK>
0x8EEB	0x72E9	#<CJK>
0x8EEC	0x73E0	#<CJK>
0x8EED	0x7A2E	#<CJK>
0x8EEE	0x816B	#<CJK>
0x8EEF	0x8DA3	#<CJK>
0x8EF0	0x9152	#<CJK>
0x8EF1	0x9996	#<CJK>
0x8EF2	0x5112	#<CJK>
0x8EF3	0x53D7	#<CJK>
0x8EF4	0x546A	#<CJK>
0x8EF5	0x5BFF	#<CJK>
0x8EF6	0x6388	#<CJK>
0x8EF7	0x6A39	#<CJK>
0x8EF8	0x7DAC	#<CJK>
0x8EF9	0x9700	#<CJK>
0x8EFA	0x56DA	#<CJK>
0x8EFB	0x53CE	#<CJK>
0x8EFC	0x5468	#<CJK>
0x8F40	0x5B97	#<CJK>
0x8F41	0x5C31	#<CJK>
0x8F42	0x5DDE	#<CJK>
0x8F43	0x4FEE	#<CJK>
0x8F44	0x6101	#<CJK>
0x8F45	0x62FE	#<CJK>
0x8F46	0x6D32	#<CJK>
0x8F47	0x79C0	#<CJK>
0x8F48	0x79CB	#<CJK>
0x8F49	0x7D42	#<CJK>
0x8F4A	0x7E4D	#<CJK>
0x8F4B	0x7FD2	#<CJK>
0x8F4C	0x81ED	#<CJK>
0x8F4D	0x821F	#<CJK>
0x8F4E	0x8490	#<CJK>
0x8F4F	0x8846	#<CJK>
0x8F50	0x8972	#<CJK>
0x8F51	0x8B90	#<CJK>
0x8F52	0x8E74	#<CJK>
0x8F53	0x8F2F	#<CJK>
0x8F54	0x9031	#<CJK>
0x8F55	0x914B	#<CJK>
0x8F56	0x916C	#<CJK>
0x8F57	0x96C6	#<CJK>
0x8F58	0x919C	#<CJK>
0x8F59	0x4EC0	#<CJK>
0x8F5A	0x4F4F	#<CJK>
0x8F5B	0x5145	#<CJK>
0x8F5C	0x5341	#<CJK>
0x8F5D	0x5F93	#<CJK>
0x8F5E	0x620E	#<CJK>
0x8F5F	0x67D4	#<CJK>
0x8F60	0x6C41	#<CJK>
0x8F61	0x6E0B	#<CJK>
0x8F62	0x7363	#<CJK>
0x8F63	0x7E26	#<CJK>
0x8F64	0x91CD	#<CJK>
0x8F65	0x9283	#<CJK>
0x8F66	0x53D4	#<CJK>
0x8F67	0x5919	#<CJK>
0x8F68	0x5BBF	#<CJK>
0x8F69	0x6DD1	#<CJK>
0x8F6A	0x795D	#<CJK>
0x8F6B	0x7E2E	#<CJK>
0x8F6C	0x7C9B	#<CJK>
0x8F6D	0x587E	#<CJK>
0x8F6E	0x719F	#<CJK>
0x8F6F	0x51FA	#<CJK>
0x8F70	0x8853	#<CJK>
0x8F71	0x8FF0	#<CJK>
0x8F72	0x4FCA	#<CJK>
0x8F73	0x5CFB	#<CJK>
0x8F74	0x6625	#<CJK>
0x8F75	0x77AC	#<CJK>
0x8F76	0x7AE3	#<CJK>
0x8F77	0x821C	#<CJK>
0x8F78	0x99FF	#<CJK>
0x8F79	0x51C6	#<CJK>
0x8F7A	0x5FAA	#<CJK>
0x8F7B	0x65EC	#<CJK>
0x8F7C	0x696F	#<CJK>
0x8F7D	0x6B89	#<CJK>
0x8F7E	0x6DF3	#<CJK>
0x8F80	0x6E96	#<CJK>
0x8F81	0x6F64	#<CJK>
0x8F82	0x76FE	#<CJK>
0x8F83	0x7D14	#<CJK>
0x8F84	0x5DE1	#<CJK>
0x8F85	0x9075	#<CJK>
0x8F86	0x9187	#<CJK>
0x8F87	0x9806	#<CJK>
0x8F88	0x51E6	#<CJK>
0x8F89	0x521D	#<CJK>
0x8F8A	0x6240	#<CJK>
0x8F8B	0x6691	#<CJK>
0x8F8C	0x66D9	#<CJK>
0x8F8D	0x6E1A	#<CJK>
0x8F8E	0x5EB6	#<CJK>
0x8F8F	0x7DD2	#<CJK>
0x8F90	0x7F72	#<CJK>
0x8F91	0x66F8	#<CJK>
0x8F92	0x85AF	#<CJK>
0x8F93	0x85F7	#<CJK>
0x8F94	0x8AF8	#<CJK>
0x8F95	0x52A9	#<CJK>
0x8F96	0x53D9	#<CJK>
0x8F97	0x5973	#<CJK>
0x8F98	0x5E8F	#<CJK>
0x8F99	0x5F90	#<CJK>
0x8F9A	0x6055	#<CJK>
0x8F9B	0x92E4	#<CJK>
0x8F9C	0x9664	#<CJK>
0x8F9D	0x50B7	#<CJK>
0x8F9E	0x511F	#<CJK>
0x8F9F	0x52DD	#<CJK>
0x8FA0	0x5320	#<CJK>
0x8FA1	0x5347	#<CJK>
0x8FA2	0x53EC	#<CJK>
0x8FA3	0x54E8	#<CJK>
0x8FA4	0x5546	#<CJK>
0x8FA5	0x5531	#<CJK>
0x8FA6	0x5617	#<CJK>
0x8FA7	0x5968	#<CJK>
0x8FA8	0x59BE	#<CJK>
0x8FA9	0x5A3C	#<CJK>
0x8FAA	0x5BB5	#<CJK>
0x8FAB	0x5C06	#<CJK>
0x8FAC	0x5C0F	#<CJK>
0x8FAD	0x5C11	#<CJK>
0x8FAE	0x5C1A	#<CJK>
0x8FAF	0x5E84	#<CJK>
0x8FB0	0x5E8A	#<CJK>
0x8FB1	0x5EE0	#<CJK>
0x8FB2	0x5F70	#<CJK>
0x8FB3	0x627F	#<CJK>
0x8FB4	0x6284	#<CJK>
0x8FB5	0x62DB	#<CJK>
0x8FB6	0x638C	#<CJK>
0x8FB7	0x6377	#<CJK>
0x8FB8	0x6607	#<CJK>
0x8FB9	0x660C	#<CJK>
0x8FBA	0x662D	#<CJK>
0x8FBB	0x6676	#<CJK>
0x8FBC	0x677E	#<CJK>
0x8FBD	0x68A2	#<CJK>
0x8FBE	0x6A1F	#<CJK>
0x8FBF	0x6A35	#<CJK>
0x8FC0	0x6CBC	#<CJK>
0x8FC1	0x6D88	#<CJK>
0x8FC2	0x6E09	#<CJK>
0x8FC3	0x6E58	#<CJK>
0x8FC4	0x713C	#<CJK>
0x8FC5	0x7126	#<CJK>
0x8FC6	0x7167	#<CJK>
0x8FC7	0x75C7	#<CJK>
0x8FC8	0x7701	#<CJK>
0x8FC9	0x785D	#<CJK>
0x8FCA	0x7901	#<CJK>
0x8FCB	0x7965	#<CJK>
0x8FCC	0x79F0	#<CJK>
0x8FCD	0x7AE0	#<CJK>
0x8FCE	0x7B11	#<CJK>
0x8FCF	0x7CA7	#<CJK>
0x8FD0	0x7D39	#<CJK>
0x8FD1	0x8096	#<CJK>
0x8FD2	0x83D6	#<CJK>
0x8FD3	0x848B	#<CJK>
0x8FD4	0x8549	#<CJK>
0x8FD5	0x885D	#<CJK>
0x8FD6	0x88F3	#<CJK>
0x8FD7	0x8A1F	#<CJK>
0x8FD8	0x8A3C	#<CJK>
0x8FD9	0x8A54	#<CJK>
0x8FDA	0x8A73	#<CJK>
0x8FDB	0x8C61	#<CJK>
0x8FDC	0x8CDE	#<CJK>
0x8FDD	0x91A4	#<CJK>
0x8FDE	0x9266	#<CJK>
0x8FDF	0x937E	#<CJK>
0x8FE0	0x9418	#<CJK>
0x8FE1	0x969C	#<CJK>
0x8FE2	0x9798	#<CJK>
0x8FE3	0x4E0A	#<CJK>
0x8FE4	0x4E08	#<CJK>
0x8FE5	0x4E1E	#<CJK>
0x8FE6	0x4E57	#<CJK>
0x8FE7	0x5197	#<CJK>
0x8FE8	0x5270	#<CJK>
0x8FE9	0x57CE	#<CJK>
0x8FEA	0x5834	#<CJK>
0x8FEB	0x58CC	#<CJK>
0x8FEC	0x5B22	#<CJK>
0x8FED	0x5E38	#<CJK>
0x8FEE	0x60C5	#<CJK>
0x8FEF	0x64FE	#<CJK>
0x8FF0	0x6761	#<CJK>
0x8FF1	0x6756	#<CJK>
0x8FF2	0x6D44	#<CJK>
0x8FF3	0x72B6	#<CJK>
0x8FF4	0x7573	#<CJK>
0x8FF5	0x7A63	#<CJK>
0x8FF6	0x84B8	#<CJK>
0x8FF7	0x8B72	#<CJK>
0x8FF8	0x91B8	#<CJK>
0x8FF9	0x9320	#<CJK>
0x8FFA	0x5631	#<CJK>
0x8FFB	0x57F4	#<CJK>
0x8FFC	0x98FE	#<CJK>
0x9040	0x62ED	#<CJK>
0x9041	0x690D	#<CJK>
0x9042	0x6B96	#<CJK>
0x9043	0x71ED	#<CJK>
0x9044	0x7E54	#<CJK>
0x9045	0x8077	#<CJK>
0x9046	0x8272	#<CJK>
0x9047	0x89E6	#<CJK>
0x9048	0x98DF	#<CJK>
0x9049	0x8755	#<CJK>
0x904A	0x8FB1	#<CJK>
0x904B	0x5C3B	#<CJK>
0x904C	0x4F38	#<CJK>
0x904D	0x4FE1	#<CJK>
0x904E	0x4FB5	#<CJK>
0x904F	0x5507	#<CJK>
0x9050	0x5A20	#<CJK>
0x9051	0x5BDD	#<CJK>
0x9052	0x5BE9	#<CJK>
0x9053	0x5FC3	#<CJK>
0x9054	0x614E	#<CJK>
0x9055	0x632F	#<CJK>
0x9056	0x65B0	#<CJK>
0x9057	0x664B	#<CJK>
0x9058	0x68EE	#<CJK>
0x9059	0x699B	#<CJK>
0x905A	0x6D78	#<CJK>
0x905B	0x6DF1	#<CJK>
0x905C	0x7533	#<CJK>
0x905D	0x75B9	#<CJK>
0x905E	0x771F	#<CJK>
0x905F	0x795E	#<CJK>
0x9060	0x79E6	#<CJK>
0x9061	0x7D33	#<CJK>
0x9062	0x81E3	#<CJK>
0x9063	0x82AF	#<CJK>
0x9064	0x85AA	#<CJK>
0x9065	0x89AA	#<CJK>
0x9066	0x8A3A	#<CJK>
0x9067	0x8EAB	#<CJK>
0x9068	0x8F9B	#<CJK>
0x9069	0x9032	#<CJK>
0x906A	0x91DD	#<CJK>
0x906B	0x9707	#<CJK>
0x906C	0x4EBA	#<CJK>
0x906D	0x4EC1	#<CJK>
0x906E	0x5203	#<CJK>
0x906F	0x5875	#<CJK>
0x9070	0x58EC	#<CJK>
0x9071	0x5C0B	#<CJK>
0x9072	0x751A	#<CJK>
0x9073	0x5C3D	#<CJK>
0x9074	0x814E	#<CJK>
0x9075	0x8A0A	#<CJK>
0x9076	0x8FC5	#<CJK>
0x9077	0x9663	#<CJK>
0x9078	0x976D	#<CJK>
0x9079	0x7B25	#<CJK>
0x907A	0x8ACF	#<CJK>
0x907B	0x9808	#<CJK>
0x907C	0x9162	#<CJK>
0x907D	0x56F3	#<CJK>
0x907E	0x53A8	#<CJK>
0x9080	0x9017	#<CJK>
0x9081	0x5439	#<CJK>
0x9082	0x5782	#<CJK>
0x9083	0x5E25	#<CJK>
0x9084	0x63A8	#<CJK>
0x9085	0x6C34	#<CJK>
0x9086	0x708A	#<CJK>
0x9087	0x7761	#<CJK>
0x9088	0x7C8B	#<CJK>
0x9089	0x7FE0	#<CJK>
0x908A	0x8870	#<CJK>
0x908B	0x9042	#<CJK>
0x908C	0x9154	#<CJK>
0x908D	0x9310	#<CJK>
0x908E	0x9318	#<CJK>
0x908F	0x968F	#<CJK>
0x9090	0x745E	#<CJK>
0x9091	0x9AC4	#<CJK>
0x9092	0x5D07	#<CJK>
0x9093	0x5D69	#<CJK>
0x9094	0x6570	#<CJK>
0x9095	0x67A2	#<CJK>
0x9096	0x8DA8	#<CJK>
0x9097	0x96DB	#<CJK>
0x9098	0x636E	#<CJK>
0x9099	0x6749	#<CJK>
0x909A	0x6919	#<CJK>
0x909B	0x83C5	#<CJK>
0x909C	0x9817	#<CJK>
0x909D	0x96C0	#<CJK>
0x909E	0x88FE	#<CJK>
0x909F	0x6F84	#<CJK>
0x90A0	0x647A	#<CJK>
0x90A1	0x5BF8	#<CJK>
0x90A2	0x4E16	#<CJK>
0x90A3	0x702C	#<CJK>
0x90A4	0x755D	#<CJK>
0x90A5	0x662F	#<CJK>
0x90A6	0x51C4	#<CJK>
0x90A7	0x5236	#<CJK>
0x90A8	0x52E2	#<CJK>
0x90A9	0x59D3	#<CJK>
0x90AA	0x5F81	#<CJK>
0x90AB	0x6027	#<CJK>
0x90AC	0x6210	#<CJK>
0x90AD	0x653F	#<CJK>
0x90AE	0x6574	#<CJK>
0x90AF	0x661F	#<CJK>
0x90B0	0x6674	#<CJK>
0x90B1	0x68F2	#<CJK>
0x90B2	0x6816	#<CJK>
0x90B3	0x6B63	#<CJK>
0x90B4	0x6E05	#<CJK>
0x90B5	0x7272	#<CJK>
0x90B6	0x751F	#<CJK>
0x90B7	0x76DB	#<CJK>
0x90B8	0x7CBE	#<CJK>
0x90B9	0x8056	#<CJK>
0x90BA	0x58F0	#<CJK>
0x90BB	0x88FD	#<CJK>
0x90BC	0x897F	#<CJK>
0x90BD	0x8AA0	#<CJK>
0x90BE	0x8A93	#<CJK>
0x90BF	0x8ACB	#<CJK>
0x90C0	0x901D	#<CJK>
0x90C1	0x9192	#<CJK>
0x90C2	0x9752	#<CJK>
0x90C3	0x9759	#<CJK>
0x90C4	0x6589	#<CJK>
0x90C5	0x7A0E	#<CJK>
0x90C6	0x8106	#<CJK>
0x90C7	0x96BB	#<CJK>
0x90C8	0x5E2D	#<CJK>
0x90C9	0x60DC	#<CJK>
0x90CA	0x621A	#<CJK>
0x90CB	0x65A5	#<CJK>
0x90CC	0x6614	#<CJK>
0x90CD	0x6790	#<CJK>
0x90CE	0x77F3	#<CJK>
0x90CF	0x7A4D	#<CJK>
0x90D0	0x7C4D	#<CJK>
0x90D1	0x7E3E	#<CJK>
0x90D2	0x810A	#<CJK>
0x90D3	0x8CAC	#<CJK>
0x90D4	0x8D64	#<CJK>
0x90D5	0x8DE1	#<CJK>
0x90D6	0x8E5F	#<CJK>
0x90D7	0x78A9	#<CJK>
0x90D8	0x5207	#<CJK>
0x90D9	0x62D9	#<CJK>
0x90DA	0x63A5	#<CJK>
0x90DB	0x6442	#<CJK>
0x90DC	0x6298	#<CJK>
0x90DD	0x8A2D	#<CJK>
0x90DE	0x7A83	#<CJK>
0x90DF	0x7BC0	#<CJK>
0x90E0	0x8AAC	#<CJK>
0x90E1	0x96EA	#<CJK>
0x90E2	0x7D76	#<CJK>
0x90E3	0x820C	#<CJK>
0x90E4	0x8749	#<CJK>
0x90E5	0x4ED9	#<CJK>
0x90E6	0x5148	#<CJK>
0x90E7	0x5343	#<CJK>
0x90E8	0x5360	#<CJK>
0x90E9	0x5BA3	#<CJK>
0x90EA	0x5C02	#<CJK>
0x90EB	0x5C16	#<CJK>
0x90EC	0x5DDD	#<CJK>
0x90ED	0x6226	#<CJK>
0x90EE	0x6247	#<CJK>
0x90EF	0x64B0	#<CJK>
0x90F0	0x6813	#<CJK>
0x90F1	0x6834	#<CJK>
0x90F2	0x6CC9	#<CJK>
0x90F3	0x6D45	#<CJK>
0x90F4	0x6D17	#<CJK>
0x90F5	0x67D3	#<CJK>
0x90F6	0x6F5C	#<CJK>
0x90F7	0x714E	#<CJK>
0x90F8	0x717D	#<CJK>
0x90F9	0x65CB	#<CJK>
0x90FA	0x7A7F	#<CJK>
0x90FB	0x7BAD	#<CJK>
0x90FC	0x7DDA	#<CJK>
0x9140	0x7E4A	#<CJK>
0x9141	0x7FA8	#<CJK>
0x9142	0x817A	#<CJK>
0x9143	0x821B	#<CJK>
0x9144	0x8239	#<CJK>
0x9145	0x85A6	#<CJK>
0x9146	0x8A6E	#<CJK>
0x9147	0x8CCE	#<CJK>
0x9148	0x8DF5	#<CJK>
0x9149	0x9078	#<CJK>
0x914A	0x9077	#<CJK>
0x914B	0x92AD	#<CJK>
0x914C	0x9291	#<CJK>
0x914D	0x9583	#<CJK>
0x914E	0x9BAE	#<CJK>
0x914F	0x524D	#<CJK>
0x9150	0x5584	#<CJK>
0x9151	0x6F38	#<CJK>
0x9152	0x7136	#<CJK>
0x9153	0x5168	#<CJK>
0x9154	0x7985	#<CJK>
0x9155	0x7E55	#<CJK>
0x9156	0x81B3	#<CJK>
0x9157	0x7CCE	#<CJK>
0x9158	0x564C	#<CJK>
0x9159	0x5851	#<CJK>
0x915A	0x5CA8	#<CJK>
0x915B	0x63AA	#<CJK>
0x915C	0x66FE	#<CJK>
0x915D	0x66FD	#<CJK>
0x915E	0x695A	#<CJK>
0x915F	0x72D9	#<CJK>
0x9160	0x758F	#<CJK>
0x9161	0x758E	#<CJK>
0x9162	0x790E	#<CJK>
0x9163	0x7956	#<CJK>
0x9164	0x79DF	#<CJK>
0x9165	0x7C97	#<CJK>
0x9166	0x7D20	#<CJK>
0x9167	0x7D44	#<CJK>
0x9168	0x8607	#<CJK>
0x9169	0x8A34	#<CJK>
0x916A	0x963B	#<CJK>
0x916B	0x9061	#<CJK>
0x916C	0x9F20	#<CJK>
0x916D	0x50E7	#<CJK>
0x916E	0x5275	#<CJK>
0x916F	0x53CC	#<CJK>
0x9170	0x53E2	#<CJK>
0x9171	0x5009	#<CJK>
0x9172	0x55AA	#<CJK>
0x9173	0x58EE	#<CJK>
0x9174	0x594F	#<CJK>
0x9175	0x723D	#<CJK>
0x9176	0x5B8B	#<CJK>
0x9177	0x5C64	#<CJK>
0x9178	0x531D	#<CJK>
0x9179	0x60E3	#<CJK>
0x917A	0x60F3	#<CJK>
0x917B	0x635C	#<CJK>
0x917C	0x6383	#<CJK>
0x917D	0x633F	#<CJK>
0x917E	0x63BB	#<CJK>
0x9180	0x64CD	#<CJK>
0x9181	0x65E9	#<CJK>
0x9182	0x66F9	#<CJK>
0x9183	0x5DE3	#<CJK>
0x9184	0x69CD	#<CJK>
0x9185	0x69FD	#<CJK>
0x9186	0x6F15	#<CJK>
0x9187	0x71E5	#<CJK>
0x9188	0x4E89	#<CJK>
0x9189	0x75E9	#<CJK>
0x918A	0x76F8	#<CJK>
0x918B	0x7A93	#<CJK>
0x918C	0x7CDF	#<CJK>
0x918D	0x7DCF	#<CJK>
0x918E	0x7D9C	#<CJK>
0x918F	0x8061	#<CJK>
0x9190	0x8349	#<CJK>
0x9191	0x8358	#<CJK>
0x9192	0x846C	#<CJK>
0x9193	0x84BC	#<CJK>
0x9194	0x85FB	#<CJK>
0x9195	0x88C5	#<CJK>
0x9196	0x8D70	#<CJK>
0x9197	0x9001	#<CJK>
0x9198	0x906D	#<CJK>
0x9199	0x9397	#<CJK>
0x919A	0x971C	#<CJK>
0x919B	0x9A12	#<CJK>
0x919C	0x50CF	#<CJK>
0x919D	0x5897	#<CJK>
0x919E	0x618E	#<CJK>
0x919F	0x81D3	#<CJK>
0x91A0	0x8535	#<CJK>
0x91A1	0x8D08	#<CJK>
0x91A2	0x9020	#<CJK>
0x91A3	0x4FC3	#<CJK>
0x91A4	0x5074	#<CJK>
0x91A5	0x5247	#<CJK>
0x91A6	0x5373	#<CJK>
0x91A7	0x606F	#<CJK>
0x91A8	0x6349	#<CJK>
0x91A9	0x675F	#<CJK>
0x91AA	0x6E2C	#<CJK>
0x91AB	0x8DB3	#<CJK>
0x91AC	0x901F	#<CJK>
0x91AD	0x4FD7	#<CJK>
0x91AE	0x5C5E	#<CJK>
0x91AF	0x8CCA	#<CJK>
0x91B0	0x65CF	#<CJK>
0x91B1	0x7D9A	#<CJK>
0x91B2	0x5352	#<CJK>
0x91B3	0x8896	#<CJK>
0x91B4	0x5176	#<CJK>
0x91B5	0x63C3	#<CJK>
0x91B6	0x5B58	#<CJK>
0x91B7	0x5B6B	#<CJK>
0x91B8	0x5C0A	#<CJK>
0x91B9	0x640D	#<CJK>
0x91BA	0x6751	#<CJK>
0x91BB	0x905C	#<CJK>
0x91BC	0x4ED6	#<CJK>
0x91BD	0x591A	#<CJK>
0x91BE	0x592A	#<CJK>
0x91BF	0x6C70	#<CJK>
0x91C0	0x8A51	#<CJK>
0x91C1	0x553E	#<CJK>
0x91C2	0x5815	#<CJK>
0x91C3	0x59A5	#<CJK>
0x91C4	0x60F0	#<CJK>
0x91C5	0x6253	#<CJK>
0x91C6	0x67C1	#<CJK>
0x91C7	0x8235	#<CJK>
0x91C8	0x6955	#<CJK>
0x91C9	0x9640	#<CJK>
0x91CA	0x99C4	#<CJK>
0x91CB	0x9A28	#<CJK>
0x91CC	0x4F53	#<CJK>
0x91CD	0x5806	#<CJK>
0x91CE	0x5BFE	#<CJK>
0x91CF	0x8010	#<CJK>
0x91D0	0x5CB1	#<CJK>
0x91D1	0x5E2F	#<CJK>
0x91D2	0x5F85	#<CJK>
0x91D3	0x6020	#<CJK>
0x91D4	0x614B	#<CJK>
0x91D5	0x6234	#<CJK>
0x91D6	0x66FF	#<CJK>
0x91D7	0x6CF0	#<CJK>
0x91D8	0x6EDE	#<CJK>
0x91D9	0x80CE	#<CJK>
0x91DA	0x817F	#<CJK>
0x91DB	0x82D4	#<CJK>
0x91DC	0x888B	#<CJK>
0x91DD	0x8CB8	#<CJK>
0x91DE	0x9000	#<CJK>
0x91DF	0x902E	#<CJK>
0x91E0	0x968A	#<CJK>
0x91E1	0x9EDB	#<CJK>
0x91E2	0x9BDB	#<CJK>
0x91E3	0x4EE3	#<CJK>
0x91E4	0x53F0	#<CJK>
0x91E5	0x5927	#<CJK>
0x91E6	0x7B2C	#<CJK>
0x91E7	0x918D	#<CJK>
0x91E8	0x984C	#<CJK>
0x91E9	0x9DF9	#<CJK>
0x91EA	0x6EDD	#<CJK>
0x91EB	0x7027	#<CJK>
0x91EC	0x5353	#<CJK>
0x91ED	0x5544	#<CJK>
0x91EE	0x5B85	#<CJK>
0x91EF	0x6258	#<CJK>
0x91F0	0x629E	#<CJK>
0x91F1	0x62D3	#<CJK>
0x91F2	0x6CA2	#<CJK>
0x91F3	0x6FEF	#<CJK>
0x91F4	0x7422	#<CJK>
0x91F5	0x8A17	#<CJK>
0x91F6	0x9438	#<CJK>
0x91F7	0x6FC1	#<CJK>
0x91F8	0x8AFE	#<CJK>
0x91F9	0x8338	#<CJK>
0x91FA	0x51E7	#<CJK>
0x91FB	0x86F8	#<CJK>
0x91FC	0x53EA	#<CJK>
0x9240	0x53E9	#<CJK>
0x9241	0x4F46	#<CJK>
0x9242	0x9054	#<CJK>
0x9243	0x8FB0	#<CJK>
0x9244	0x596A	#<CJK>
0x9245	0x8131	#<CJK>
0x9246	0x5DFD	#<CJK>
0x9247	0x7AEA	#<CJK>
0x9248	0x8FBF	#<CJK>
0x9249	0x68DA	#<CJK>
0x924A	0x8C37	#<CJK>
0x924B	0x72F8	#<CJK>
0x924C	0x9C48	#<CJK>
0x924D	0x6A3D	#<CJK>
0x924E	0x8AB0	#<CJK>
0x924F	0x4E39	#<CJK>
0x9250	0x5358	#<CJK>
0x9251	0x5606	#<CJK>
0x9252	0x5766	#<CJK>
0x9253	0x62C5	#<CJK>
0x9254	0x63A2	#<CJK>
0x9255	0x65E6	#<CJK>
0x9256	0x6B4E	#<CJK>
0x9257	0x6DE1	#<CJK>
0x9258	0x6E5B	#<CJK>
0x9259	0x70AD	#<CJK>
0x925A	0x77ED	#<CJK>
0x925B	0x7AEF	#<CJK>
0x925C	0x7BAA	#<CJK>
0x925D	0x7DBB	#<CJK>
0x925E	0x803D	#<CJK>
0x925F	0x80C6	#<CJK>
0x9260	0x86CB	#<CJK>
0x9261	0x8A95	#<CJK>
0x9262	0x935B	#<CJK>
0x9263	0x56E3	#<CJK>
0x9264	0x58C7	#<CJK>
0x9265	0x5F3E	#<CJK>
0x9266	0x65AD	#<CJK>
0x9267	0x6696	#<CJK>
0x9268	0x6A80	#<CJK>
0x9269	0x6BB5	#<CJK>
0x926A	0x7537	#<CJK>
0x926B	0x8AC7	#<CJK>
0x926C	0x5024	#<CJK>
0x926D	0x77E5	#<CJK>
0x926E	0x5730	#<CJK>
0x926F	0x5F1B	#<CJK>
0x9270	0x6065	#<CJK>
0x9271	0x667A	#<CJK>
0x9272	0x6C60	#<CJK>
0x9273	0x75F4	#<CJK>
0x9274	0x7A1A	#<CJK>
0x9275	0x7F6E	#<CJK>
0x9276	0x81F4	#<CJK>
0x9277	0x8718	#<CJK>
0x9278	0x9045	#<CJK>
0x9279	0x99B3	#<CJK>
0x927A	0x7BC9	#<CJK>
0x927B	0x755C	#<CJK>
0x927C	0x7AF9	#<CJK>
0x927D	0x7B51	#<CJK>
0x927E	0x84C4	#<CJK>
0x9280	0x9010	#<CJK>
0x9281	0x79E9	#<CJK>
0x9282	0x7A92	#<CJK>
0x9283	0x8336	#<CJK>
0x9284	0x5AE1	#<CJK>
0x9285	0x7740	#<CJK>
0x9286	0x4E2D	#<CJK>
0x9287	0x4EF2	#<CJK>
0x9288	0x5B99	#<CJK>
0x9289	0x5FE0	#<CJK>
0x928A	0x62BD	#<CJK>
0x928B	0x663C	#<CJK>
0x928C	0x67F1	#<CJK>
0x928D	0x6CE8	#<CJK>
0x928E	0x866B	#<CJK>
0x928F	0x8877	#<CJK>
0x9290	0x8A3B	#<CJK>
0x9291	0x914E	#<CJK>
0x9292	0x92F3	#<CJK>
0x9293	0x99D0	#<CJK>
0x9294	0x6A17	#<CJK>
0x9295	0x7026	#<CJK>
0x9296	0x732A	#<CJK>
0x9297	0x82E7	#<CJK>
0x9298	0x8457	#<CJK>
0x9299	0x8CAF	#<CJK>
0x929A	0x4E01	#<CJK>
0x929B	0x5146	#<CJK>
0x929C	0x51CB	#<CJK>
0x929D	0x558B	#<CJK>
0x929E	0x5BF5	#<CJK>
0x929F	0x5E16	#<CJK>
0x92A0	0x5E33	#<CJK>
0x92A1	0x5E81	#<CJK>
0x92A2	0x5F14	#<CJK>
0x92A3	0x5F35	#<CJK>
0x92A4	0x5F6B	#<CJK>
0x92A5	0x5FB4	#<CJK>
0x92A6	0x61F2	#<CJK>
0x92A7	0x6311	#<CJK>
0x92A8	0x66A2	#<CJK>
0x92A9	0x671D	#<CJK>
0x92AA	0x6F6E	#<CJK>
0x92AB	0x7252	#<CJK>
0x92AC	0x753A	#<CJK>
0x92AD	0x773A	#<CJK>
0x92AE	0x8074	#<CJK>
0x92AF	0x8139	#<CJK>
0x92B0	0x8178	#<CJK>
0x92B1	0x8776	#<CJK>
0x92B2	0x8ABF	#<CJK>
0x92B3	0x8ADC	#<CJK>
0x92B4	0x8D85	#<CJK>
0x92B5	0x8DF3	#<CJK>
0x92B6	0x929A	#<CJK>
0x92B7	0x9577	#<CJK>
0x92B8	0x9802	#<CJK>
0x92B9	0x9CE5	#<CJK>
0x92BA	0x52C5	#<CJK>
0x92BB	0x6357	#<CJK>
0x92BC	0x76F4	#<CJK>
0x92BD	0x6715	#<CJK>
0x92BE	0x6C88	#<CJK>
0x92BF	0x73CD	#<CJK>
0x92C0	0x8CC3	#<CJK>
0x92C1	0x93AE	#<CJK>
0x92C2	0x9673	#<CJK>
0x92C3	0x6D25	#<CJK>
0x92C4	0x589C	#<CJK>
0x92C5	0x690E	#<CJK>
0x92C6	0x69CC	#<CJK>
0x92C7	0x8FFD	#<CJK>
0x92C8	0x939A	#<CJK>
0x92C9	0x75DB	#<CJK>
0x92CA	0x901A	#<CJK>
0x92CB	0x585A	#<CJK>
0x92CC	0x6802	#<CJK>
0x92CD	0x63B4	#<CJK>
0x92CE	0x69FB	#<CJK>
0x92CF	0x4F43	#<CJK>
0x92D0	0x6F2C	#<CJK>
0x92D1	0x67D8	#<CJK>
0x92D2	0x8FBB	#<CJK>
0x92D3	0x8526	#<CJK>
0x92D4	0x7DB4	#<CJK>
0x92D5	0x9354	#<CJK>
0x92D6	0x693F	#<CJK>
0x92D7	0x6F70	#<CJK>
0x92D8	0x576A	#<CJK>
0x92D9	0x58F7	#<CJK>
0x92DA	0x5B2C	#<CJK>
0x92DB	0x7D2C	#<CJK>
0x92DC	0x722A	#<CJK>
0x92DD	0x540A	#<CJK>
0x92DE	0x91E3	#<CJK>
0x92DF	0x9DB4	#<CJK>
0x92E0	0x4EAD	#<CJK>
0x92E1	0x4F4E	#<CJK>
0x92E2	0x505C	#<CJK>
0x92E3	0x5075	#<CJK>
0x92E4	0x5243	#<CJK>
0x92E5	0x8C9E	#<CJK>
0x92E6	0x5448	#<CJK>
0x92E7	0x5824	#<CJK>
0x92E8	0x5B9A	#<CJK>
0x92E9	0x5E1D	#<CJK>
0x92EA	0x5E95	#<CJK>
0x92EB	0x5EAD	#<CJK>
0x92EC	0x5EF7	#<CJK>
0x92ED	0x5F1F	#<CJK>
0x92EE	0x608C	#<CJK>
0x92EF	0x62B5	#<CJK>
0x92F0	0x633A	#<CJK>
0x92F1	0x63D0	#<CJK>
0x92F2	0x68AF	#<CJK>
0x92F3	0x6C40	#<CJK>
0x92F4	0x7887	#<CJK>
0x92F5	0x798E	#<CJK>
0x92F6	0x7A0B	#<CJK>
0x92F7	0x7DE0	#<CJK>
0x92F8	0x8247	#<CJK>
0x92F9	0x8A02	#<CJK>
0x92FA	0x8AE6	#<CJK>
0x92FB	0x8E44	#<CJK>
0x92FC	0x9013	#<CJK>
0x9340	0x90B8	#<CJK>
0x9341	0x912D	#<CJK>
0x9342	0x91D8	#<CJK>
0x9343	0x9F0E	#<CJK>
0x9344	0x6CE5	#<CJK>
0x9345	0x6458	#<CJK>
0x9346	0x64E2	#<CJK>
0x9347	0x6575	#<CJK>
0x9348	0x6EF4	#<CJK>
0x9349	0x7684	#<CJK>
0x934A	0x7B1B	#<CJK>
0x934B	0x9069	#<CJK>
0x934C	0x93D1	#<CJK>
0x934D	0x6EBA	#<CJK>
0x934E	0x54F2	#<CJK>
0x934F	0x5FB9	#<CJK>
0x9350	0x64A4	#<CJK>
0x9351	0x8F4D	#<CJK>
0x9352	0x8FED	#<CJK>
0x9353	0x9244	#<CJK>
0x9354	0x5178	#<CJK>
0x9355	0x586B	#<CJK>
0x9356	0x5929	#<CJK>
0x9357	0x5C55	#<CJK>
0x9358	0x5E97	#<CJK>
0x9359	0x6DFB	#<CJK>
0x935A	0x7E8F	#<CJK>
0x935B	0x751C	#<CJK>
0x935C	0x8CBC	#<CJK>
0x935D	0x8EE2	#<CJK>
0x935E	0x985B	#<CJK>
0x935F	0x70B9	#<CJK>
0x9360	0x4F1D	#<CJK>
0x9361	0x6BBF	#<CJK>
0x9362	0x6FB1	#<CJK>
0x9363	0x7530	#<CJK>
0x9364	0x96FB	#<CJK>
0x9365	0x514E	#<CJK>
0x9366	0x5410	#<CJK>
0x9367	0x5835	#<CJK>
0x9368	0x5857	#<CJK>
0x9369	0x59AC	#<CJK>
0x936A	0x5C60	#<CJK>
0x936B	0x5F92	#<CJK>
0x936C	0x6597	#<CJK>
0x936D	0x675C	#<CJK>
0x936E	0x6E21	#<CJK>
0x936F	0x767B	#<CJK>
0x9370	0x83DF	#<CJK>
0x9371	0x8CED	#<CJK>
0x9372	0x9014	#<CJK>
0x9373	0x90FD	#<CJK>
0x9374	0x934D	#<CJK>
0x9375	0x7825	#<CJK>
0x9376	0x783A	#<CJK>
0x9377	0x52AA	#<CJK>
0x9378	0x5EA6	#<CJK>
0x9379	0x571F	#<CJK>
0x937A	0x5974	#<CJK>
0x937B	0x6012	#<CJK>
0x937C	0x5012	#<CJK>
0x937D	0x515A	#<CJK>
0x937E	0x51AC	#<CJK>
0x9380	0x51CD	#<CJK>
0x9381	0x5200	#<CJK>
0x9382	0x5510	#<CJK>
0x9383	0x5854	#<CJK>
0x9384	0x5858	#<CJK>
0x9385	0x5957	#<CJK>
0x9386	0x5B95	#<CJK>
0x9387	0x5CF6	#<CJK>
0x9388	0x5D8B	#<CJK>
0x9389	0x60BC	#<CJK>
0x938A	0x6295	#<CJK>
0x938B	0x642D	#<CJK>
0x938C	0x6771	#<CJK>
0x938D	0x6843	#<CJK>
0x938E	0x68BC	#<CJK>
0x938F	0x68DF	#<CJK>
0x9390	0x76D7	#<CJK>
0x9391	0x6DD8	#<CJK>
0x9392	0x6E6F	#<CJK>
0x9393	0x6D9B	#<CJK>
0x9394	0x706F	#<CJK>
0x9395	0x71C8	#<CJK>
0x9396	0x5F53	#<CJK>
0x9397	0x75D8	#<CJK>
0x9398	0x7977	#<CJK>
0x9399	0x7B49	#<CJK>
0x939A	0x7B54	#<CJK>
0x939B	0x7B52	#<CJK>
0x939C	0x7CD6	#<CJK>
0x939D	0x7D71	#<CJK>
0x939E	0x5230	#<CJK>
0x939F	0x8463	#<CJK>
0x93A0	0x8569	#<CJK>
0x93A1	0x85E4	#<CJK>
0x93A2	0x8A0E	#<CJK>
0x93A3	0x8B04	#<CJK>
0x93A4	0x8C46	#<CJK>
0x93A5	0x8E0F	#<CJK>
0x93A6	0x9003	#<CJK>
0x93A7	0x900F	#<CJK>
0x93A8	0x9419	#<CJK>
0x93A9	0x9676	#<CJK>
0x93AA	0x982D	#<CJK>
0x93AB	0x9A30	#<CJK>
0x93AC	0x95D8	#<CJK>
0x93AD	0x50CD	#<CJK>
0x93AE	0x52D5	#<CJK>
0x93AF	0x540C	#<CJK>
0x93B0	0x5802	#<CJK>
0x93B1	0x5C0E	#<CJK>
0x93B2	0x61A7	#<CJK>
0x93B3	0x649E	#<CJK>
0x93B4	0x6D1E	#<CJK>
0x93B5	0x77B3	#<CJK>
0x93B6	0x7AE5	#<CJK>
0x93B7	0x80F4	#<CJK>
0x93B8	0x8404	#<CJK>
0x93B9	0x9053	#<CJK>
0x93BA	0x9285	#<CJK>
0x93BB	0x5CE0	#<CJK>
0x93BC	0x9D07	#<CJK>
0x93BD	0x533F	#<CJK>
0x93BE	0x5F97	#<CJK>
0x93BF	0x5FB3	#<CJK>
0x93C0	0x6D9C	#<CJK>
0x93C1	0x7279	#<CJK>
0x93C2	0x7763	#<CJK>
0x93C3	0x79BF	#<CJK>
0x93C4	0x7BE4	#<CJK>
0x93C5	0x6BD2	#<CJK>
0x93C6	0x72EC	#<CJK>
0x93C7	0x8AAD	#<CJK>
0x93C8	0x6803	#<CJK>
0x93C9	0x6A61	#<CJK>
0x93CA	0x51F8	#<CJK>
0x93CB	0x7A81	#<CJK>
0x93CC	0x6934	#<CJK>
0x93CD	0x5C4A	#<CJK>
0x93CE	0x9CF6	#<CJK>
0x93CF	0x82EB	#<CJK>
0x93D0	0x5BC5	#<CJK>
0x93D1	0x9149	#<CJK>
0x93D2	0x701E	#<CJK>
0x93D3	0x5678	#<CJK>
0x93D4	0x5C6F	#<CJK>
0x93D5	0x60C7	#<CJK>
0x93D6	0x6566	#<CJK>
0x93D7	0x6C8C	#<CJK>
0x93D8	0x8C5A	#<CJK>
0x93D9	0x9041	#<CJK>
0x93DA	0x9813	#<CJK>
0x93DB	0x5451	#<CJK>
0x93DC	0x66C7	#<CJK>
0x93DD	0x920D	#<CJK>
0x93DE	0x5948	#<CJK>
0x93DF	0x90A3	#<CJK>
0x93E0	0x5185	#<CJK>
0x93E1	0x4E4D	#<CJK>
0x93E2	0x51EA	#<CJK>
0x93E3	0x8599	#<CJK>
0x93E4	0x8B0E	#<CJK>
0x93E5	0x7058	#<CJK>
0x93E6	0x637A	#<CJK>
0x93E7	0x934B	#<CJK>
0x93E8	0x6962	#<CJK>
0x93E9	0x99B4	#<CJK>
0x93EA	0x7E04	#<CJK>
0x93EB	0x7577	#<CJK>
0x93EC	0x5357	#<CJK>
0x93ED	0x6960	#<CJK>
0x93EE	0x8EDF	#<CJK>
0x93EF	0x96E3	#<CJK>
0x93F0	0x6C5D	#<CJK>
0x93F1	0x4E8C	#<CJK>
0x93F2	0x5C3C	#<CJK>
0x93F3	0x5F10	#<CJK>
0x93F4	0x8FE9	#<CJK>
0x93F5	0x5302	#<CJK>
0x93F6	0x8CD1	#<CJK>
0x93F7	0x8089	#<CJK>
0x93F8	0x8679	#<CJK>
0x93F9	0x5EFF	#<CJK>
0x93FA	0x65E5	#<CJK>
0x93FB	0x4E73	#<CJK>
0x93FC	0x5165	#<CJK>
0x9440	0x5982	#<CJK>
0x9441	0x5C3F	#<CJK>
0x9442	0x97EE	#<CJK>
0x9443	0x4EFB	#<CJK>
0x9444	0x598A	#<CJK>
0x9445	0x5FCD	#<CJK>
0x9446	0x8A8D	#<CJK>
0x9447	0x6FE1	#<CJK>
0x9448	0x79B0	#<CJK>
0x9449	0x7962	#<CJK>
0x944A	0x5BE7	#<CJK>
0x944B	0x8471	#<CJK>
0x944C	0x732B	#<CJK>
0x944D	0x71B1	#<CJK>
0x944E	0x5E74	#<CJK>
0x944F	0x5FF5	#<CJK>
0x9450	0x637B	#<CJK>
0x9451	0x649A	#<CJK>
0x9452	0x71C3	#<CJK>
0x9453	0x7C98	#<CJK>
0x9454	0x4E43	#<CJK>
0x9455	0x5EFC	#<CJK>
0x9456	0x4E4B	#<CJK>
0x9457	0x57DC	#<CJK>
0x9458	0x56A2	#<CJK>
0x9459	0x60A9	#<CJK>
0x945A	0x6FC3	#<CJK>
0x945B	0x7D0D	#<CJK>
0x945C	0x80FD	#<CJK>
0x945D	0x8133	#<CJK>
0x945E	0x81BF	#<CJK>
0x945F	0x8FB2	#<CJK>
0x9460	0x8997	#<CJK>
0x9461	0x86A4	#<CJK>
0x9462	0x5DF4	#<CJK>
0x9463	0x628A	#<CJK>
0x9464	0x64AD	#<CJK>
0x9465	0x8987	#<CJK>
0x9466	0x6777	#<CJK>
0x9467	0x6CE2	#<CJK>
0x9468	0x6D3E	#<CJK>
0x9469	0x7436	#<CJK>
0x946A	0x7834	#<CJK>
0x946B	0x5A46	#<CJK>
0x946C	0x7F75	#<CJK>
0x946D	0x82AD	#<CJK>
0x946E	0x99AC	#<CJK>
0x946F	0x4FF3	#<CJK>
0x9470	0x5EC3	#<CJK>
0x9471	0x62DD	#<CJK>
0x9472	0x6392	#<CJK>
0x9473	0x6557	#<CJK>
0x9474	0x676F	#<CJK>
0x9475	0x76C3	#<CJK>
0x9476	0x724C	#<CJK>
0x9477	0x80CC	#<CJK>
0x9478	0x80BA	#<CJK>
0x9479	0x8F29	#<CJK>
0x947A	0x914D	#<CJK>
0x947B	0x500D	#<CJK>
0x947C	0x57F9	#<CJK>
0x947D	0x5A92	#<CJK>
0x947E	0x6885	#<CJK>
0x9480	0x6973	#<CJK>
0x9481	0x7164	#<CJK>
0x9482	0x72FD	#<CJK>
0x9483	0x8CB7	#<CJK>
0x9484	0x58F2	#<CJK>
0x9485	0x8CE0	#<CJK>
0x9486	0x966A	#<CJK>
0x9487	0x9019	#<CJK>
0x9488	0x877F	#<CJK>
0x9489	0x79E4	#<CJK>
0x948A	0x77E7	#<CJK>
0x948B	0x8429	#<CJK>
0x948C	0x4F2F	#<CJK>
0x948D	0x5265	#<CJK>
0x948E	0x535A	#<CJK>
0x948F	0x62CD	#<CJK>
0x9490	0x67CF	#<CJK>
0x9491	0x6CCA	#<CJK>
0x9492	0x767D	#<CJK>
0x9493	0x7B94	#<CJK>
0x9494	0x7C95	#<CJK>
0x9495	0x8236	#<CJK>
0x9496	0x8584	#<CJK>
0x9497	0x8FEB	#<CJK>
0x9498	0x66DD	#<CJK>
0x9499	0x6F20	#<CJK>
0x949A	0x7206	#<CJK>
0x949B	0x7E1B	#<CJK>
0x949C	0x83AB	#<CJK>
0x949D	0x99C1	#<CJK>
0x949E	0x9EA6	#<CJK>
0x949F	0x51FD	#<CJK>
0x94A0	0x7BB1	#<CJK>
0x94A1	0x7872	#<CJK>
0x94A2	0x7BB8	#<CJK>
0x94A3	0x8087	#<CJK>
0x94A4	0x7B48	#<CJK>
0x94A5	0x6AE8	#<CJK>
0x94A6	0x5E61	#<CJK>
0x94A7	0x808C	#<CJK>
0x94A8	0x7551	#<CJK>
0x94A9	0x7560	#<CJK>
0x94AA	0x516B	#<CJK>
0x94AB	0x9262	#<CJK>
0x94AC	0x6E8C	#<CJK>
0x94AD	0x767A	#<CJK>
0x94AE	0x9197	#<CJK>
0x94AF	0x9AEA	#<CJK>
0x94B0	0x4F10	#<CJK>
0x94B1	0x7F70	#<CJK>
0x94B2	0x629C	#<CJK>
0x94B3	0x7B4F	#<CJK>
0x94B4	0x95A5	#<CJK>
0x94B5	0x9CE9	#<CJK>
0x94B6	0x567A	#<CJK>
0x94B7	0x5859	#<CJK>
0x94B8	0x86E4	#<CJK>
0x94B9	0x96BC	#<CJK>
0x94BA	0x4F34	#<CJK>
0x94BB	0x5224	#<CJK>
0x94BC	0x534A	#<CJK>
0x94BD	0x53CD	#<CJK>
0x94BE	0x53DB	#<CJK>
0x94BF	0x5E06	#<CJK>
0x94C0	0x642C	#<CJK>
0x94C1	0x6591	#<CJK>
0x94C2	0x677F	#<CJK>
0x94C3	0x6C3E	#<CJK>
0x94C4	0x6C4E	#<CJK>
0x94C5	0x7248	#<CJK>
0x94C6	0x72AF	#<CJK>
0x94C7	0x73ED	#<CJK>
0x94C8	0x7554	#<CJK>
0x94C9	0x7E41	#<CJK>
0x94CA	0x822C	#<CJK>
0x94CB	0x85E9	#<CJK>
0x94CC	0x8CA9	#<CJK>
0x94CD	0x7BC4	#<CJK>
0x94CE	0x91C6	#<CJK>
0x94CF	0x7169	#<CJK>
0x94D0	0x9812	#<CJK>
0x94D1	0x98EF	#<CJK>
0x94D2	0x633D	#<CJK>
0x94D3	0x6669	#<CJK>
0x94D4	0x756A	#<CJK>
0x94D5	0x76E4	#<CJK>
0x94D6	0x78D0	#<CJK>
0x94D7	0x8543	#<CJK>
0x94D8	0x86EE	#<CJK>
0x94D9	0x532A	#<CJK>
0x94DA	0x5351	#<CJK>
0x94DB	0x5426	#<CJK>
0x94DC	0x5983	#<CJK>
0x94DD	0x5E87	#<CJK>
0x94DE	0x5F7C	#<CJK>
0x94DF	0x60B2	#<CJK>
0x94E0	0x6249	#<CJK>
0x94E1	0x6279	#<CJK>
0x94E2	0x62AB	#<CJK>
0x94E3	0x6590	#<CJK>
0x94E4	0x6BD4	#<CJK>
0x94E5	0x6CCC	#<CJK>
0x94E6	0x75B2	#<CJK>
0x94E7	0x76AE	#<CJK>
0x94E8	0x7891	#<CJK>
0x94E9	0x79D8	#<CJK>
0x94EA	0x7DCB	#<CJK>
0x94EB	0x7F77	#<CJK>
0x94EC	0x80A5	#<CJK>
0x94ED	0x88AB	#<CJK>
0x94EE	0x8AB9	#<CJK>
0x94EF	0x8CBB	#<CJK>
0x94F0	0x907F	#<CJK>
0x94F1	0x975E	#<CJK>
0x94F2	0x98DB	#<CJK>
0x94F3	0x6A0B	#<CJK>
0x94F4	0x7C38	#<CJK>
0x94F5	0x5099	#<CJK>
0x94F6	0x5C3E	#<CJK>
0x94F7	0x5FAE	#<CJK>
0x94F8	0x6787	#<CJK>
0x94F9	0x6BD8	#<CJK>
0x94FA	0x7435	#<CJK>
0x94FB	0x7709	#<CJK>
0x94FC	0x7F8E	#<CJK>
0x9540	0x9F3B	#<CJK>
0x9541	0x67CA	#<CJK>
0x9542	0x7A17	#<CJK>
0x9543	0x5339	#<CJK>
0x9544	0x758B	#<CJK>
0x9545	0x9AED	#<CJK>
0x9546	0x5F66	#<CJK>
0x9547	0x819D	#<CJK>
0x9548	0x83F1	#<CJK>
0x9549	0x8098	#<CJK>
0x954A	0x5F3C	#<CJK>
0x954B	0x5FC5	#<CJK>
0x954C	0x7562	#<CJK>
0x954D	0x7B46	#<CJK>
0x954E	0x903C	#<CJK>
0x954F	0x6867	#<CJK>
0x9550	0x59EB	#<CJK>
0x9551	0x5A9B	#<CJK>
0x9552	0x7D10	#<CJK>
0x9553	0x767E	#<CJK>
0x9554	0x8B2C	#<CJK>
0x9555	0x4FF5	#<CJK>
0x9556	0x5F6A	#<CJK>
0x9557	0x6A19	#<CJK>
0x9558	0x6C37	#<CJK>
0x9559	0x6F02	#<CJK>
0x955A	0x74E2	#<CJK>
0x955B	0x7968	#<CJK>
0x955C	0x8868	#<CJK>
0x955D	0x8A55	#<CJK>
0x955E	0x8C79	#<CJK>
0x955F	0x5EDF	#<CJK>
0x9560	0x63CF	#<CJK>
0x9561	0x75C5	#<CJK>
0x9562	0x79D2	#<CJK>
0x9563	0x82D7	#<CJK>
0x9564	0x9328	#<CJK>
0x9565	0x92F2	#<CJK>
0x9566	0x849C	#<CJK>
0x9567	0x86ED	#<CJK>
0x9568	0x9C2D	#<CJK>
0x9569	0x54C1	#<CJK>
0x956A	0x5F6C	#<CJK>
0x956B	0x658C	#<CJK>
0x956C	0x6D5C	#<CJK>
0x956D	0x7015	#<CJK>
0x956E	0x8CA7	#<CJK>
0x956F	0x8CD3	#<CJK>
0x9570	0x983B	#<CJK>
0x9571	0x654F	#<CJK>
0x9572	0x74F6	#<CJK>
0x9573	0x4E0D	#<CJK>
0x9574	0x4ED8	#<CJK>
0x9575	0x57E0	#<CJK>
0x9576	0x592B	#<CJK>
0x9577	0x5A66	#<CJK>
0x9578	0x5BCC	#<CJK>
0x9579	0x51A8	#<CJK>
0x957A	0x5E03	#<CJK>
0x957B	0x5E9C	#<CJK>
0x957C	0x6016	#<CJK>
0x957D	0x6276	#<CJK>
0x957E	0x6577	#<CJK>
0x9580	0x65A7	#<CJK>
0x9581	0x666E	#<CJK>
0x9582	0x6D6E	#<CJK>
0x9583	0x7236	#<CJK>
0x9584	0x7B26	#<CJK>
0x9585	0x8150	#<CJK>
0x9586	0x819A	#<CJK>
0x9587	0x8299	#<CJK>
0x9588	0x8B5C	#<CJK>
0x9589	0x8CA0	#<CJK>
0x958A	0x8CE6	#<CJK>
0x958B	0x8D74	#<CJK>
0x958C	0x961C	#<CJK>
0x958D	0x9644	#<CJK>
0x958E	0x4FAE	#<CJK>
0x958F	0x64AB	#<CJK>
0x9590	0x6B66	#<CJK>
0x9591	0x821E	#<CJK>
0x9592	0x8461	#<CJK>
0x9593	0x856A	#<CJK>
0x9594	0x90E8	#<CJK>
0x9595	0x5C01	#<CJK>
0x9596	0x6953	#<CJK>
0x9597	0x98A8	#<CJK>
0x9598	0x847A	#<CJK>
0x9599	0x8557	#<CJK>
0x959A	0x4F0F	#<CJK>
0x959B	0x526F	#<CJK>
0x959C	0x5FA9	#<CJK>
0x959D	0x5E45	#<CJK>
0x959E	0x670D	#<CJK>
0x959F	0x798F	#<CJK>
0x95A0	0x8179	#<CJK>
0x95A1	0x8907	#<CJK>
0x95A2	0x8986	#<CJK>
0x95A3	0x6DF5	#<CJK>
0x95A4	0x5F17	#<CJK>
0x95A5	0x6255	#<CJK>
0x95A6	0x6CB8	#<CJK>
0x95A7	0x4ECF	#<CJK>
0x95A8	0x7269	#<CJK>
0x95A9	0x9B92	#<CJK>
0x95AA	0x5206	#<CJK>
0x95AB	0x543B	#<CJK>
0x95AC	0x5674	#<CJK>
0x95AD	0x58B3	#<CJK>
0x95AE	0x61A4	#<CJK>
0x95AF	0x626E	#<CJK>
0x95B0	0x711A	#<CJK>
0x95B1	0x596E	#<CJK>
0x95B2	0x7C89	#<CJK>
0x95B3	0x7CDE	#<CJK>
0x95B4	0x7D1B	#<CJK>
0x95B5	0x96F0	#<CJK>
0x95B6	0x6587	#<CJK>
0x95B7	0x805E	#<CJK>
0x95B8	0x4E19	#<CJK>
0x95B9	0x4F75	#<CJK>
0x95BA	0x5175	#<CJK>
0x95BB	0x5840	#<CJK>
0x95BC	0x5E63	#<CJK>
0x95BD	0x5E73	#<CJK>
0x95BE	0x5F0A	#<CJK>
0x95BF	0x67C4	#<CJK>
0x95C0	0x4E26	#<CJK>
0x95C1	0x853D	#<CJK>
0x95C2	0x9589	#<CJK>
0x95C3	0x965B	#<CJK>
0x95C4	0x7C73	#<CJK>
0x95C5	0x9801	#<CJK>
0x95C6	0x50FB	#<CJK>
0x95C7	0x58C1	#<CJK>
0x95C8	0x7656	#<CJK>
0x95C9	0x78A7	#<CJK>
0x95CA	0x5225	#<CJK>
0x95CB	0x77A5	#<CJK>
0x95CC	0x8511	#<CJK>
0x95CD	0x7B86	#<CJK>
0x95CE	0x504F	#<CJK>
0x95CF	0x5909	#<CJK>
0x95D0	0x7247	#<CJK>
0x95D1	0x7BC7	#<CJK>
0x95D2	0x7DE8	#<CJK>
0x95D3	0x8FBA	#<CJK>
0x95D4	0x8FD4	#<CJK>
0x95D5	0x904D	#<CJK>
0x95D6	0x4FBF	#<CJK>
0x95D7	0x52C9	#<CJK>
0x95D8	0x5A29	#<CJK>
0x95D9	0x5F01	#<CJK>
0x95DA	0x97AD	#<CJK>
0x95DB	0x4FDD	#<CJK>
0x95DC	0x8217	#<CJK>
0x95DD	0x92EA	#<CJK>
0x95DE	0x5703	#<CJK>
0x95DF	0x6355	#<CJK>
0x95E0	0x6B69	#<CJK>
0x95E1	0x752B	#<CJK>
0x95E2	0x88DC	#<CJK>
0x95E3	0x8F14	#<CJK>
0x95E4	0x7A42	#<CJK>
0x95E5	0x52DF	#<CJK>
0x95E6	0x5893	#<CJK>
0x95E7	0x6155	#<CJK>
0x95E8	0x620A	#<CJK>
0x95E9	0x66AE	#<CJK>
0x95EA	0x6BCD	#<CJK>
0x95EB	0x7C3F	#<CJK>
0x95EC	0x83E9	#<CJK>
0x95ED	0x5023	#<CJK>
0x95EE	0x4FF8	#<CJK>
0x95EF	0x5305	#<CJK>
0x95F0	0x5446	#<CJK>
0x95F1	0x5831	#<CJK>
0x95F2	0x5949	#<CJK>
0x95F3	0x5B9D	#<CJK>
0x95F4	0x5CF0	#<CJK>
0x95F5	0x5CEF	#<CJK>
0x95F6	0x5D29	#<CJK>
0x95F7	0x5E96	#<CJK>
0x95F8	0x62B1	#<CJK>
0x95F9	0x6367	#<CJK>
0x95FA	0x653E	#<CJK>
0x95FB	0x65B9	#<CJK>
0x95FC	0x670B	#<CJK>
0x9640	0x6CD5	#<CJK>
0x9641	0x6CE1	#<CJK>
0x9642	0x70F9	#<CJK>
0x9643	0x7832	#<CJK>
0x9644	0x7E2B	#<CJK>
0x9645	0x80DE	#<CJK>
0x9646	0x82B3	#<CJK>
0x9647	0x840C	#<CJK>
0x9648	0x84EC	#<CJK>
0x9649	0x8702	#<CJK>
0x964A	0x8912	#<CJK>
0x964B	0x8A2A	#<CJK>
0x964C	0x8C4A	#<CJK>
0x964D	0x90A6	#<CJK>
0x964E	0x92D2	#<CJK>
0x964F	0x98FD	#<CJK>
0x9650	0x9CF3	#<CJK>
0x9651	0x9D6C	#<CJK>
0x9652	0x4E4F	#<CJK>
0x9653	0x4EA1	#<CJK>
0x9654	0x508D	#<CJK>
0x9655	0x5256	#<CJK>
0x9656	0x574A	#<CJK>
0x9657	0x59A8	#<CJK>
0x9658	0x5E3D	#<CJK>
0x9659	0x5FD8	#<CJK>
0x965A	0x5FD9	#<CJK>
0x965B	0x623F	#<CJK>
0x965C	0x66B4	#<CJK>
0x965D	0x671B	#<CJK>
0x965E	0x67D0	#<CJK>
0x965F	0x68D2	#<CJK>
0x9660	0x5192	#<CJK>
0x9661	0x7D21	#<CJK>
0x9662	0x80AA	#<CJK>
0x9663	0x81A8	#<CJK>
0x9664	0x8B00	#<CJK>
0x9665	0x8C8C	#<CJK>
0x9666	0x8CBF	#<CJK>
0x9667	0x927E	#<CJK>
0x9668	0x9632	#<CJK>
0x9669	0x5420	#<CJK>
0x966A	0x982C	#<CJK>
0x966B	0x5317	#<CJK>
0x966C	0x50D5	#<CJK>
0x966D	0x535C	#<CJK>
0x966E	0x58A8	#<CJK>
0x966F	0x64B2	#<CJK>
0x9670	0x6734	#<CJK>
0x9671	0x7267	#<CJK>
0x9672	0x7766	#<CJK>
0x9673	0x7A46	#<CJK>
0x9674	0x91E6	#<CJK>
0x9675	0x52C3	#<CJK>
0x9676	0x6CA1	#<CJK>
0x9677	0x6B86	#<CJK>
0x9678	0x5800	#<CJK>
0x9679	0x5E4C	#<CJK>
0x967A	0x5954	#<CJK>
0x967B	0x672C	#<CJK>
0x967C	0x7FFB	#<CJK>
0x967D	0x51E1	#<CJK>
0x967E	0x76C6	#<CJK>
0x9680	0x6469	#<CJK>
0x9681	0x78E8	#<CJK>
0x9682	0x9B54	#<CJK>
0x9683	0x9EBB	#<CJK>
0x9684	0x57CB	#<CJK>
0x9685	0x59B9	#<CJK>
0x9686	0x6627	#<CJK>
0x9687	0x679A	#<CJK>
0x9688	0x6BCE	#<CJK>
0x9689	0x54E9	#<CJK>
0x968A	0x69D9	#<CJK>
0x968B	0x5E55	#<CJK>
0x968C	0x819C	#<CJK>
0x968D	0x6795	#<CJK>
0x968E	0x9BAA	#<CJK>
0x968F	0x67FE	#<CJK>
0x9690	0x9C52	#<CJK>
0x9691	0x685D	#<CJK>
0x9692	0x4EA6	#<CJK>
0x9693	0x4FE3	#<CJK>
0x9694	0x53C8	#<CJK>
0x9695	0x62B9	#<CJK>
0x9696	0x672B	#<CJK>
0x9697	0x6CAB	#<CJK>
0x9698	0x8FC4	#<CJK>
0x9699	0x4FAD	#<CJK>
0x969A	0x7E6D	#<CJK>
0x969B	0x9EBF	#<CJK>
0x969C	0x4E07	#<CJK>
0x969D	0x6162	#<CJK>
0x969E	0x6E80	#<CJK>
0x969F	0x6F2B	#<CJK>
0x96A0	0x8513	#<CJK>
0x96A1	0x5473	#<CJK>
0x96A2	0x672A	#<CJK>
0x96A3	0x9B45	#<CJK>
0x96A4	0x5DF3	#<CJK>
0x96A5	0x7B95	#<CJK>
0x96A6	0x5CAC	#<CJK>
0x96A7	0x5BC6	#<CJK>
0x96A8	0x871C	#<CJK>
0x96A9	0x6E4A	#<CJK>
0x96AA	0x84D1	#<CJK>
0x96AB	0x7A14	#<CJK>
0x96AC	0x8108	#<CJK>
0x96AD	0x5999	#<CJK>
0x96AE	0x7C8D	#<CJK>
0x96AF	0x6C11	#<CJK>
0x96B0	0x7720	#<CJK>
0x96B1	0x52D9	#<CJK>
0x96B2	0x5922	#<CJK>
0x96B3	0x7121	#<CJK>
0x96B4	0x725F	#<CJK>
0x96B5	0x77DB	#<CJK>
0x96B6	0x9727	#<CJK>
0x96B7	0x9D61	#<CJK>
0x96B8	0x690B	#<CJK>
0x96B9	0x5A7F	#<CJK>
0x96BA	0x5A18	#<CJK>
0x96BB	0x51A5	#<CJK>
0x96BC	0x540D	#<CJK>
0x96BD	0x547D	#<CJK>
0x96BE	0x660E	#<CJK>
0x96BF	0x76DF	#<CJK>
0x96C0	0x8FF7	#<CJK>
0x96C1	0x9298	#<CJK>
0x96C2	0x9CF4	#<CJK>
0x96C3	0x59EA	#<CJK>
0x96C4	0x725D	#<CJK>
0x96C5	0x6EC5	#<CJK>
0x96C6	0x514D	#<CJK>
0x96C7	0x68C9	#<CJK>
0x96C8	0x7DBF	#<CJK>
0x96C9	0x7DEC	#<CJK>
0x96CA	0x9762	#<CJK>
0x96CB	0x9EBA	#<CJK>
0x96CC	0x6478	#<CJK>
0x96CD	0x6A21	#<CJK>
0x96CE	0x8302	#<CJK>
0x96CF	0x5984	#<CJK>
0x96D0	0x5B5F	#<CJK>
0x96D1	0x6BDB	#<CJK>
0x96D2	0x731B	#<CJK>
0x96D3	0x76F2	#<CJK>
0x96D4	0x7DB2	#<CJK>
0x96D5	0x8017	#<CJK>
0x96D6	0x8499	#<CJK>
0x96D7	0x5132	#<CJK>
0x96D8	0x6728	#<CJK>
0x96D9	0x9ED9	#<CJK>
0x96DA	0x76EE	#<CJK>
0x96DB	0x6762	#<CJK>
0x96DC	0x52FF	#<CJK>
0x96DD	0x9905	#<CJK>
0x96DE	0x5C24	#<CJK>
0x96DF	0x623B	#<CJK>
0x96E0	0x7C7E	#<CJK>
0x96E1	0x8CB0	#<CJK>
0x96E2	0x554F	#<CJK>
0x96E3	0x60B6	#<CJK>
0x96E4	0x7D0B	#<CJK>
0x96E5	0x9580	#<CJK>
0x96E6	0x5301	#<CJK>
0x96E7	0x4E5F	#<CJK>
0x96E8	0x51B6	#<CJK>
0x96E9	0x591C	#<CJK>
0x96EA	0x723A	#<CJK>
0x96EB	0x8036	#<CJK>
0x96EC	0x91CE	#<CJK>
0x96ED	0x5F25	#<CJK>
0x96EE	0x77E2	#<CJK>
0x96EF	0x5384	#<CJK>
0x96F0	0x5F79	#<CJK>
0x96F1	0x7D04	#<CJK>
0x96F2	0x85AC	#<CJK>
0x96F3	0x8A33	#<CJK>
0x96F4	0x8E8D	#<CJK>
0x96F5	0x9756	#<CJK>
0x96F6	0x67F3	#<CJK>
0x96F7	0x85AE	#<CJK>
0x96F8	0x9453	#<CJK>
0x96F9	0x6109	#<CJK>
0x96FA	0x6108	#<CJK>
0x96FB	0x6CB9	#<CJK>
0x96FC	0x7652	#<CJK>
0x9740	0x8AED	#<CJK>
0x9741	0x8F38	#<CJK>
0x9742	0x552F	#<CJK>
0x9743	0x4F51	#<CJK>
0x9744	0x512A	#<CJK>
0x9745	0x52C7	#<CJK>
0x9746	0x53CB	#<CJK>
0x9747	0x5BA5	#<CJK>
0x9748	0x5E7D	#<CJK>
0x9749	0x60A0	#<CJK>
0x974A	0x6182	#<CJK>
0x974B	0x63D6	#<CJK>
0x974C	0x6709	#<CJK>
0x974D	0x67DA	#<CJK>
0x974E	0x6E67	#<CJK>
0x974F	0x6D8C	#<CJK>
0x9750	0x7336	#<CJK>
0x9751	0x7337	#<CJK>
0x9752	0x7531	#<CJK>
0x9753	0x7950	#<CJK>
0x9754	0x88D5	#<CJK>
0x9755	0x8A98	#<CJK>
0x9756	0x904A	#<CJK>
0x9757	0x9091	#<CJK>
0x9758	0x90F5	#<CJK>
0x9759	0x96C4	#<CJK>
0x975A	0x878D	#<CJK>
0x975B	0x5915	#<CJK>
0x975C	0x4E88	#<CJK>
0x975D	0x4F59	#<CJK>
0x975E	0x4E0E	#<CJK>
0x975F	0x8A89	#<CJK>
0x9760	0x8F3F	#<CJK>
0x9761	0x9810	#<CJK>
0x9762	0x50AD	#<CJK>
0x9763	0x5E7C	#<CJK>
0x9764	0x5996	#<CJK>
0x9765	0x5BB9	#<CJK>
0x9766	0x5EB8	#<CJK>
0x9767	0x63DA	#<CJK>
0x9768	0x63FA	#<CJK>
0x9769	0x64C1	#<CJK>
0x976A	0x66DC	#<CJK>
0x976B	0x694A	#<CJK>
0x976C	0x69D8	#<CJK>
0x976D	0x6D0B	#<CJK>
0x976E	0x6EB6	#<CJK>
0x976F	0x7194	#<CJK>
0x9770	0x7528	#<CJK>
0x9771	0x7AAF	#<CJK>
0x9772	0x7F8A	#<CJK>
0x9773	0x8000	#<CJK>
0x9774	0x8449	#<CJK>
0x9775	0x84C9	#<CJK>
0x9776	0x8981	#<CJK>
0x9777	0x8B21	#<CJK>
0x9778	0x8E0A	#<CJK>
0x9779	0x9065	#<CJK>
0x977A	0x967D	#<CJK>
0x977B	0x990A	#<CJK>
0x977C	0x617E	#<CJK>
0x977D	0x6291	#<CJK>
0x977E	0x6B32	#<CJK>
0x9780	0x6C83	#<CJK>
0x9781	0x6D74	#<CJK>
0x9782	0x7FCC	#<CJK>
0x9783	0x7FFC	#<CJK>
0x9784	0x6DC0	#<CJK>
0x9785	0x7F85	#<CJK>
0x9786	0x87BA	#<CJK>
0x9787	0x88F8	#<CJK>
0x9788	0x6765	#<CJK>
0x9789	0x83B1	#<CJK>
0x978A	0x983C	#<CJK>
0x978B	0x96F7	#<CJK>
0x978C	0x6D1B	#<CJK>
0x978D	0x7D61	#<CJK>
0x978E	0x843D	#<CJK>
0x978F	0x916A	#<CJK>
0x9790	0x4E71	#<CJK>
0x9791	0x5375	#<CJK>
0x9792	0x5D50	#<CJK>
0x9793	0x6B04	#<CJK>
0x9794	0x6FEB	#<CJK>
0x9795	0x85CD	#<CJK>
0x9796	0x862D	#<CJK>
0x9797	0x89A7	#<CJK>
0x9798	0x5229	#<CJK>
0x9799	0x540F	#<CJK>
0x979A	0x5C65	#<CJK>
0x979B	0x674E	#<CJK>
0x979C	0x68A8	#<CJK>
0x979D	0x7406	#<CJK>
0x979E	0x7483	#<CJK>
0x979F	0x75E2	#<CJK>
0x97A0	0x88CF	#<CJK>
0x97A1	0x88E1	#<CJK>
0x97A2	0x91CC	#<CJK>
0x97A3	0x96E2	#<CJK>
0x97A4	0x9678	#<CJK>
0x97A5	0x5F8B	#<CJK>
0x97A6	0x7387	#<CJK>
0x97A7	0x7ACB	#<CJK>
0x97A8	0x844E	#<CJK>
0x97A9	0x63A0	#<CJK>
0x97AA	0x7565	#<CJK>
0x97AB	0x5289	#<CJK>
0x97AC	0x6D41	#<CJK>
0x97AD	0x6E9C	#<CJK>
0x97AE	0x7409	#<CJK>
0x97AF	0x7559	#<CJK>
0x97B0	0x786B	#<CJK>
0x97B1	0x7C92	#<CJK>
0x97B2	0x9686	#<CJK>
0x97B3	0x7ADC	#<CJK>
0x97B4	0x9F8D	#<CJK>
0x97B5	0x4FB6	#<CJK>
0x97B6	0x616E	#<CJK>
0x97B7	0x65C5	#<CJK>
0x97B8	0x865C	#<CJK>
0x97B9	0x4E86	#<CJK>
0x97BA	0x4EAE	#<CJK>
0x97BB	0x50DA	#<CJK>
0x97BC	0x4E21	#<CJK>
0x97BD	0x51CC	#<CJK>
0x97BE	0x5BEE	#<CJK>
0x97BF	0x6599	#<CJK>
0x97C0	0x6881	#<CJK>
0x97C1	0x6DBC	#<CJK>
0x97C2	0x731F	#<CJK>
0x97C3	0x7642	#<CJK>
0x97C4	0x77AD	#<CJK>
0x97C5	0x7A1C	#<CJK>
0x97C6	0x7CE7	#<CJK>
0x97C7	0x826F	#<CJK>
0x97C8	0x8AD2	#<CJK>
0x97C9	0x907C	#<CJK>
0x97CA	0x91CF	#<CJK>
0x97CB	0x9675	#<CJK>
0x97CC	0x9818	#<CJK>
0x97CD	0x529B	#<CJK>
0x97CE	0x7DD1	#<CJK>
0x97CF	0x502B	#<CJK>
0x97D0	0x5398	#<CJK>
0x97D1	0x6797	#<CJK>
0x97D2	0x6DCB	#<CJK>
0x97D3	0x71D0	#<CJK>
0x97D4	0x7433	#<CJK>
0x97D5	0x81E8	#<CJK>
0x97D6	0x8F2A	#<CJK>
0x97D7	0x96A3	#<CJK>
0x97D8	0x9C57	#<CJK>
0x97D9	0x9E9F	#<CJK>
0x97DA	0x7460	#<CJK>
0x97DB	0x5841	#<CJK>
0x97DC	0x6D99	#<CJK>
0x97DD	0x7D2F	#<CJK>
0x97DE	0x985E	#<CJK>
0x97DF	0x4EE4	#<CJK>
0x97E0	0x4F36	#<CJK>
0x97E1	0x4F8B	#<CJK>
0x97E2	0x51B7	#<CJK>
0x97E3	0x52B1	#<CJK>
0x97E4	0x5DBA	#<CJK>
0x97E5	0x601C	#<CJK>
0x97E6	0x73B2	#<CJK>
0x97E7	0x793C	#<CJK>
0x97E8	0x82D3	#<CJK>
0x97E9	0x9234	#<CJK>
0x97EA	0x96B7	#<CJK>
0x97EB	0x96F6	#<CJK>
0x97EC	0x970A	#<CJK>
0x97ED	0x9E97	#<CJK>
0x97EE	0x9F62	#<CJK>
0x97EF	0x66A6	#<CJK>
0x97F0	0x6B74	#<CJK>
0x97F1	0x5217	#<CJK>
0x97F2	0x52A3	#<CJK>
0x97F3	0x70C8	#<CJK>
0x97F4	0x88C2	#<CJK>
0x97F5	0x5EC9	#<CJK>
0x97F6	0x604B	#<CJK>
0x97F7	0x6190	#<CJK>
0x97F8	0x6F23	#<CJK>
0x97F9	0x7149	#<CJK>
0x97FA	0x7C3E	#<CJK>
0x97FB	0x7DF4	#<CJK>
0x97FC	0x806F	#<CJK>
0x9840	0x84EE	#<CJK>
0x9841	0x9023	#<CJK>
0x9842	0x932C	#<CJK>
0x9843	0x5442	#<CJK>
0x9844	0x9B6F	#<CJK>
0x9845	0x6AD3	#<CJK>
0x9846	0x7089	#<CJK>
0x9847	0x8CC2	#<CJK>
0x9848	0x8DEF	#<CJK>
0x9849	0x9732	#<CJK>
0x984A	0x52B4	#<CJK>
0x984B	0x5A41	#<CJK>
0x984C	0x5ECA	#<CJK>
0x984D	0x5F04	#<CJK>
0x984E	0x6717	#<CJK>
0x984F	0x697C	#<CJK>
0x9850	0x6994	#<CJK>
0x9851	0x6D6A	#<CJK>
0x9852	0x6F0F	#<CJK>
0x9853	0x7262	#<CJK>
0x9854	0x72FC	#<CJK>
0x9855	0x7BED	#<CJK>
0x9856	0x8001	#<CJK>
0x9857	0x807E	#<CJK>
0x9858	0x874B	#<CJK>
0x9859	0x90CE	#<CJK>
0x985A	0x516D	#<CJK>
0x985B	0x9E93	#<CJK>
0x985C	0x7984	#<CJK>
0x985D	0x808B	#<CJK>
0x985E	0x9332	#<CJK>
0x985F	0x8AD6	#<CJK>
0x9860	0x502D	#<CJK>
0x9861	0x548C	#<CJK>
0x9862	0x8A71	#<CJK>
0x9863	0x6B6A	#<CJK>
0x9864	0x8CC4	#<CJK>
0x9865	0x8107	#<CJK>
0x9866	0x60D1	#<CJK>
0x9867	0x67A0	#<CJK>
0x9868	0x9DF2	#<CJK>
0x9869	0x4E99	#<CJK>
0x986A	0x4E98	#<CJK>
0x986B	0x9C10	#<CJK>
0x986C	0x8A6B	#<CJK>
0x986D	0x85C1	#<CJK>
0x986E	0x8568	#<CJK>
0x986F	0x6900	#<CJK>
0x9870	0x6E7E	#<CJK>
0x9871	0x7897	#<CJK>
0x9872	0x8155	#<CJK>
0x989F	0x5F0C	#<CJK>
0x98A0	0x4E10	#<CJK>
0x98A1	0x4E15	#<CJK>
0x98A2	0x4E2A	#<CJK>
0x98A3	0x4E31	#<CJK>
0x98A4	0x4E36	#<CJK>
0x98A5	0x4E3C	#<CJK>
0x98A6	0x4E3F	#<CJK>
0x98A7	0x4E42	#<CJK>
0x98A8	0x4E56	#<CJK>
0x98A9	0x4E58	#<CJK>
0x98AA	0x4E82	#<CJK>
0x98AB	0x4E85	#<CJK>
0x98AC	0x8C6B	#<CJK>
0x98AD	0x4E8A	#<CJK>
0x98AE	0x8212	#<CJK>
0x98AF	0x5F0D	#<CJK>
0x98B0	0x4E8E	#<CJK>
0x98B1	0x4E9E	#<CJK>
0x98B2	0x4E9F	#<CJK>
0x98B3	0x4EA0	#<CJK>
0x98B4	0x4EA2	#<CJK>
0x98B5	0x4EB0	#<CJK>
0x98B6	0x4EB3	#<CJK>
0x98B7	0x4EB6	#<CJK>
0x98B8	0x4ECE	#<CJK>
0x98B9	0x4ECD	#<CJK>
0x98BA	0x4EC4	#<CJK>
0x98BB	0x4EC6	#<CJK>
0x98BC	0x4EC2	#<CJK>
0x98BD	0x4ED7	#<CJK>
0x98BE	0x4EDE	#<CJK>
0x98BF	0x4EED	#<CJK>
0x98C0	0x4EDF	#<CJK>
0x98C1	0x4EF7	#<CJK>
0x98C2	0x4F09	#<CJK>
0x98C3	0x4F5A	#<CJK>
0x98C4	0x4F30	#<CJK>
0x98C5	0x4F5B	#<CJK>
0x98C6	0x4F5D	#<CJK>
0x98C7	0x4F57	#<CJK>
0x98C8	0x4F47	#<CJK>
0x98C9	0x4F76	#<CJK>
0x98CA	0x4F88	#<CJK>
0x98CB	0x4F8F	#<CJK>
0x98CC	0x4F98	#<CJK>
0x98CD	0x4F7B	#<CJK>
0x98CE	0x4F69	#<CJK>
0x98CF	0x4F70	#<CJK>
0x98D0	0x4F91	#<CJK>
0x98D1	0x4F6F	#<CJK>
0x98D2	0x4F86	#<CJK>
0x98D3	0x4F96	#<CJK>
0x98D4	0x5118	#<CJK>
0x98D5	0x4FD4	#<CJK>
0x98D6	0x4FDF	#<CJK>
0x98D7	0x4FCE	#<CJK>
0x98D8	0x4FD8	#<CJK>
0x98D9	0x4FDB	#<CJK>
0x98DA	0x4FD1	#<CJK>
0x98DB	0x4FDA	#<CJK>
0x98DC	0x4FD0	#<CJK>
0x98DD	0x4FE4	#<CJK>
0x98DE	0x4FE5	#<CJK>
0x98DF	0x501A	#<CJK>
0x98E0	0x5028	#<CJK>
0x98E1	0x5014	#<CJK>
0x98E2	0x502A	#<CJK>
0x98E3	0x5025	#<CJK>
0x98E4	0x5005	#<CJK>
0x98E5	0x4F1C	#<CJK>
0x98E6	0x4FF6	#<CJK>
0x98E7	0x5021	#<CJK>
0x98E8	0x5029	#<CJK>
0x98E9	0x502C	#<CJK>
0x98EA	0x4FFE	#<CJK>
0x98EB	0x4FEF	#<CJK>
0x98EC	0x5011	#<CJK>
0x98ED	0x5006	#<CJK>
0x98EE	0x5043	#<CJK>
0x98EF	0x5047	#<CJK>
0x98F0	0x6703	#<CJK>
0x98F1	0x5055	#<CJK>
0x98F2	0x5050	#<CJK>
0x98F3	0x5048	#<CJK>
0x98F4	0x505A	#<CJK>
0x98F5	0x5056	#<CJK>
0x98F6	0x506C	#<CJK>
0x98F7	0x5078	#<CJK>
0x98F8	0x5080	#<CJK>
0x98F9	0x509A	#<CJK>
0x98FA	0x5085	#<CJK>
0x98FB	0x50B4	#<CJK>
0x98FC	0x50B2	#<CJK>
0x9940	0x50C9	#<CJK>
0x9941	0x50CA	#<CJK>
0x9942	0x50B3	#<CJK>
0x9943	0x50C2	#<CJK>
0x9944	0x50D6	#<CJK>
0x9945	0x50DE	#<CJK>
0x9946	0x50E5	#<CJK>
0x9947	0x50ED	#<CJK>
0x9948	0x50E3	#<CJK>
0x9949	0x50EE	#<CJK>
0x994A	0x50F9	#<CJK>
0x994B	0x50F5	#<CJK>
0x994C	0x5109	#<CJK>
0x994D	0x5101	#<CJK>
0x994E	0x5102	#<CJK>
0x994F	0x5116	#<CJK>
0x9950	0x5115	#<CJK>
0x9951	0x5114	#<CJK>
0x9952	0x511A	#<CJK>
0x9953	0x5121	#<CJK>
0x9954	0x513A	#<CJK>
0x9955	0x5137	#<CJK>
0x9956	0x513C	#<CJK>
0x9957	0x513B	#<CJK>
0x9958	0x513F	#<CJK>
0x9959	0x5140	#<CJK>
0x995A	0x5152	#<CJK>
0x995B	0x514C	#<CJK>
0x995C	0x5154	#<CJK>
0x995D	0x5162	#<CJK>
0x995E	0x7AF8	#<CJK>
0x995F	0x5169	#<CJK>
0x9960	0x516A	#<CJK>
0x9961	0x516E	#<CJK>
0x9962	0x5180	#<CJK>
0x9963	0x5182	#<CJK>
0x9964	0x56D8	#<CJK>
0x9965	0x518C	#<CJK>
0x9966	0x5189	#<CJK>
0x9967	0x518F	#<CJK>
0x9968	0x5191	#<CJK>
0x9969	0x5193	#<CJK>
0x996A	0x5195	#<CJK>
0x996B	0x5196	#<CJK>
0x996C	0x51A4	#<CJK>
0x996D	0x51A6	#<CJK>
0x996E	0x51A2	#<CJK>
0x996F	0x51A9	#<CJK>
0x9970	0x51AA	#<CJK>
0x9971	0x51AB	#<CJK>
0x9972	0x51B3	#<CJK>
0x9973	0x51B1	#<CJK>
0x9974	0x51B2	#<CJK>
0x9975	0x51B0	#<CJK>
0x9976	0x51B5	#<CJK>
0x9977	0x51BD	#<CJK>
0x9978	0x51C5	#<CJK>
0x9979	0x51C9	#<CJK>
0x997A	0x51DB	#<CJK>
0x997B	0x51E0	#<CJK>
0x997C	0x8655	#<CJK>
0x997D	0x51E9	#<CJK>
0x997E	0x51ED	#<CJK>
0x9980	0x51F0	#<CJK>
0x9981	0x51F5	#<CJK>
0x9982	0x51FE	#<CJK>
0x9983	0x5204	#<CJK>
0x9984	0x520B	#<CJK>
0x9985	0x5214	#<CJK>
0x9986	0x520E	#<CJK>
0x9987	0x5227	#<CJK>
0x9988	0x522A	#<CJK>
0x9989	0x522E	#<CJK>
0x998A	0x5233	#<CJK>
0x998B	0x5239	#<CJK>
0x998C	0x524F	#<CJK>
0x998D	0x5244	#<CJK>
0x998E	0x524B	#<CJK>
0x998F	0x524C	#<CJK>
0x9990	0x525E	#<CJK>
0x9991	0x5254	#<CJK>
0x9992	0x526A	#<CJK>
0x9993	0x5274	#<CJK>
0x9994	0x5269	#<CJK>
0x9995	0x5273	#<CJK>
0x9996	0x527F	#<CJK>
0x9997	0x527D	#<CJK>
0x9998	0x528D	#<CJK>
0x9999	0x5294	#<CJK>
0x999A	0x5292	#<CJK>
0x999B	0x5271	#<CJK>
0x999C	0x5288	#<CJK>
0x999D	0x5291	#<CJK>
0x999E	0x8FA8	#<CJK>
0x999F	0x8FA7	#<CJK>
0x99A0	0x52AC	#<CJK>
0x99A1	0x52AD	#<CJK>
0x99A2	0x52BC	#<CJK>
0x99A3	0x52B5	#<CJK>
0x99A4	0x52C1	#<CJK>
0x99A5	0x52CD	#<CJK>
0x99A6	0x52D7	#<CJK>
0x99A7	0x52DE	#<CJK>
0x99A8	0x52E3	#<CJK>
0x99A9	0x52E6	#<CJK>
0x99AA	0x98ED	#<CJK>
0x99AB	0x52E0	#<CJK>
0x99AC	0x52F3	#<CJK>
0x99AD	0x52F5	#<CJK>
0x99AE	0x52F8	#<CJK>
0x99AF	0x52F9	#<CJK>
0x99B0	0x5306	#<CJK>
0x99B1	0x5308	#<CJK>
0x99B2	0x7538	#<CJK>
0x99B3	0x530D	#<CJK>
0x99B4	0x5310	#<CJK>
0x99B5	0x530F	#<CJK>
0x99B6	0x5315	#<CJK>
0x99B7	0x531A	#<CJK>
0x99B8	0x5323	#<CJK>
0x99B9	0x532F	#<CJK>
0x99BA	0x5331	#<CJK>
0x99BB	0x5333	#<CJK>
0x99BC	0x5338	#<CJK>
0x99BD	0x5340	#<CJK>
0x99BE	0x5346	#<CJK>
0x99BF	0x5345	#<CJK>
0x99C0	0x4E17	#<CJK>
0x99C1	0x5349	#<CJK>
0x99C2	0x534D	#<CJK>
0x99C3	0x51D6	#<CJK>
0x99C4	0x535E	#<CJK>
0x99C5	0x5369	#<CJK>
0x99C6	0x536E	#<CJK>
0x99C7	0x5918	#<CJK>
0x99C8	0x537B	#<CJK>
0x99C9	0x5377	#<CJK>
0x99CA	0x5382	#<CJK>
0x99CB	0x5396	#<CJK>
0x99CC	0x53A0	#<CJK>
0x99CD	0x53A6	#<CJK>
0x99CE	0x53A5	#<CJK>
0x99CF	0x53AE	#<CJK>
0x99D0	0x53B0	#<CJK>
0x99D1	0x53B6	#<CJK>
0x99D2	0x53C3	#<CJK>
0x99D3	0x7C12	#<CJK>
0x99D4	0x96D9	#<CJK>
0x99D5	0x53DF	#<CJK>
0x99D6	0x66FC	#<CJK>
0x99D7	0x71EE	#<CJK>
0x99D8	0x53EE	#<CJK>
0x99D9	0x53E8	#<CJK>
0x99DA	0x53ED	#<CJK>
0x99DB	0x53FA	#<CJK>
0x99DC	0x5401	#<CJK>
0x99DD	0x543D	#<CJK>
0x99DE	0x5440	#<CJK>
0x99DF	0x542C	#<CJK>
0x99E0	0x542D	#<CJK>
0x99E1	0x543C	#<CJK>
0x99E2	0x542E	#<CJK>
0x99E3	0x5436	#<CJK>
0x99E4	0x5429	#<CJK>
0x99E5	0x541D	#<CJK>
0x99E6	0x544E	#<CJK>
0x99E7	0x548F	#<CJK>
0x99E8	0x5475	#<CJK>
0x99E9	0x548E	#<CJK>
0x99EA	0x545F	#<CJK>
0x99EB	0x5471	#<CJK>
0x99EC	0x5477	#<CJK>
0x99ED	0x5470	#<CJK>
0x99EE	0x5492	#<CJK>
0x99EF	0x547B	#<CJK>
0x99F0	0x5480	#<CJK>
0x99F1	0x5476	#<CJK>
0x99F2	0x5484	#<CJK>
0x99F3	0x5490	#<CJK>
0x99F4	0x5486	#<CJK>
0x99F5	0x54C7	#<CJK>
0x99F6	0x54A2	#<CJK>
0x99F7	0x54B8	#<CJK>
0x99F8	0x54A5	#<CJK>
0x99F9	0x54AC	#<CJK>
0x99FA	0x54C4	#<CJK>
0x99FB	0x54C8	#<CJK>
0x99FC	0x54A8	#<CJK>
0x9A40	0x54AB	#<CJK>
0x9A41	0x54C2	#<CJK>
0x9A42	0x54A4	#<CJK>
0x9A43	0x54BE	#<CJK>
0x9A44	0x54BC	#<CJK>
0x9A45	0x54D8	#<CJK>
0x9A46	0x54E5	#<CJK>
0x9A47	0x54E6	#<CJK>
0x9A48	0x550F	#<CJK>
0x9A49	0x5514	#<CJK>
0x9A4A	0x54FD	#<CJK>
0x9A4B	0x54EE	#<CJK>
0x9A4C	0x54ED	#<CJK>
0x9A4D	0x54FA	#<CJK>
0x9A4E	0x54E2	#<CJK>
0x9A4F	0x5539	#<CJK>
0x9A50	0x5540	#<CJK>
0x9A51	0x5563	#<CJK>
0x9A52	0x554C	#<CJK>
0x9A53	0x552E	#<CJK>
0x9A54	0x555C	#<CJK>
0x9A55	0x5545	#<CJK>
0x9A56	0x5556	#<CJK>
0x9A57	0x5557	#<CJK>
0x9A58	0x5538	#<CJK>
0x9A59	0x5533	#<CJK>
0x9A5A	0x555D	#<CJK>
0x9A5B	0x5599	#<CJK>
0x9A5C	0x5580	#<CJK>
0x9A5D	0x54AF	#<CJK>
0x9A5E	0x558A	#<CJK>
0x9A5F	0x559F	#<CJK>
0x9A60	0x557B	#<CJK>
0x9A61	0x557E	#<CJK>
0x9A62	0x5598	#<CJK>
0x9A63	0x559E	#<CJK>
0x9A64	0x55AE	#<CJK>
0x9A65	0x557C	#<CJK>
0x9A66	0x5583	#<CJK>
0x9A67	0x55A9	#<CJK>
0x9A68	0x5587	#<CJK>
0x9A69	0x55A8	#<CJK>
0x9A6A	0x55DA	#<CJK>
0x9A6B	0x55C5	#<CJK>
0x9A6C	0x55DF	#<CJK>
0x9A6D	0x55C4	#<CJK>
0x9A6E	0x55DC	#<CJK>
0x9A6F	0x55E4	#<CJK>
0x9A70	0x55D4	#<CJK>
0x9A71	0x5614	#<CJK>
0x9A72	0x55F7	#<CJK>
0x9A73	0x5616	#<CJK>
0x9A74	0x55FE	#<CJK>
0x9A75	0x55FD	#<CJK>
0x9A76	0x561B	#<CJK>
0x9A77	0x55F9	#<CJK>
0x9A78	0x564E	#<CJK>
0x9A79	0x5650	#<CJK>
0x9A7A	0x71DF	#<CJK>
0x9A7B	0x5634	#<CJK>
0x9A7C	0x5636	#<CJK>
0x9A7D	0x5632	#<CJK>
0x9A7E	0x5638	#<CJK>
0x9A80	0x566B	#<CJK>
0x9A81	0x5664	#<CJK>
0x9A82	0x562F	#<CJK>
0x9A83	0x566C	#<CJK>
0x9A84	0x566A	#<CJK>
0x9A85	0x5686	#<CJK>
0x9A86	0x5680	#<CJK>
0x9A87	0x568A	#<CJK>
0x9A88	0x56A0	#<CJK>
0x9A89	0x5694	#<CJK>
0x9A8A	0x568F	#<CJK>
0x9A8B	0x56A5	#<CJK>
0x9A8C	0x56AE	#<CJK>
0x9A8D	0x56B6	#<CJK>
0x9A8E	0x56B4	#<CJK>
0x9A8F	0x56C2	#<CJK>
0x9A90	0x56BC	#<CJK>
0x9A91	0x56C1	#<CJK>
0x9A92	0x56C3	#<CJK>
0x9A93	0x56C0	#<CJK>
0x9A94	0x56C8	#<CJK>
0x9A95	0x56CE	#<CJK>
0x9A96	0x56D1	#<CJK>
0x9A97	0x56D3	#<CJK>
0x9A98	0x56D7	#<CJK>
0x9A99	0x56EE	#<CJK>
0x9A9A	0x56F9	#<CJK>
0x9A9B	0x5700	#<CJK>
0x9A9C	0x56FF	#<CJK>
0x9A9D	0x5704	#<CJK>
0x9A9E	0x5709	#<CJK>
0x9A9F	0x5708	#<CJK>
0x9AA0	0x570B	#<CJK>
0x9AA1	0x570D	#<CJK>
0x9AA2	0x5713	#<CJK>
0x9AA3	0x5718	#<CJK>
0x9AA4	0x5716	#<CJK>
0x9AA5	0x55C7	#<CJK>
0x9AA6	0x571C	#<CJK>
0x9AA7	0x5726	#<CJK>
0x9AA8	0x5737	#<CJK>
0x9AA9	0x5738	#<CJK>
0x9AAA	0x574E	#<CJK>
0x9AAB	0x573B	#<CJK>
0x9AAC	0x5740	#<CJK>
0x9AAD	0x574F	#<CJK>
0x9AAE	0x5769	#<CJK>
0x9AAF	0x57C0	#<CJK>
0x9AB0	0x5788	#<CJK>
0x9AB1	0x5761	#<CJK>
0x9AB2	0x577F	#<CJK>
0x9AB3	0x5789	#<CJK>
0x9AB4	0x5793	#<CJK>
0x9AB5	0x57A0	#<CJK>
0x9AB6	0x57B3	#<CJK>
0x9AB7	0x57A4	#<CJK>
0x9AB8	0x57AA	#<CJK>
0x9AB9	0x57B0	#<CJK>
0x9ABA	0x57C3	#<CJK>
0x9ABB	0x57C6	#<CJK>
0x9ABC	0x57D4	#<CJK>
0x9ABD	0x57D2	#<CJK>
0x9ABE	0x57D3	#<CJK>
0x9ABF	0x580A	#<CJK>
0x9AC0	0x57D6	#<CJK>
0x9AC1	0x57E3	#<CJK>
0x9AC2	0x580B	#<CJK>
0x9AC3	0x5819	#<CJK>
0x9AC4	0x581D	#<CJK>
0x9AC5	0x5872	#<CJK>
0x9AC6	0x5821	#<CJK>
0x9AC7	0x5862	#<CJK>
0x9AC8	0x584B	#<CJK>
0x9AC9	0x5870	#<CJK>
0x9ACA	0x6BC0	#<CJK>
0x9ACB	0x5852	#<CJK>
0x9ACC	0x583D	#<CJK>
0x9ACD	0x5879	#<CJK>
0x9ACE	0x5885	#<CJK>
0x9ACF	0x58B9	#<CJK>
0x9AD0	0x589F	#<CJK>
0x9AD1	0x58AB	#<CJK>
0x9AD2	0x58BA	#<CJK>
0x9AD3	0x58DE	#<CJK>
0x9AD4	0x58BB	#<CJK>
0x9AD5	0x58B8	#<CJK>
0x9AD6	0x58AE	#<CJK>
0x9AD7	0x58C5	#<CJK>
0x9AD8	0x58D3	#<CJK>
0x9AD9	0x58D1	#<CJK>
0x9ADA	0x58D7	#<CJK>
0x9ADB	0x58D9	#<CJK>
0x9ADC	0x58D8	#<CJK>
0x9ADD	0x58E5	#<CJK>
0x9ADE	0x58DC	#<CJK>
0x9ADF	0x58E4	#<CJK>
0x9AE0	0x58DF	#<CJK>
0x9AE1	0x58EF	#<CJK>
0x9AE2	0x58FA	#<CJK>
0x9AE3	0x58F9	#<CJK>
0x9AE4	0x58FB	#<CJK>
0x9AE5	0x58FC	#<CJK>
0x9AE6	0x58FD	#<CJK>
0x9AE7	0x5902	#<CJK>
0x9AE8	0x590A	#<CJK>
0x9AE9	0x5910	#<CJK>
0x9AEA	0x591B	#<CJK>
0x9AEB	0x68A6	#<CJK>
0x9AEC	0x5925	#<CJK>
0x9AED	0x592C	#<CJK>
0x9AEE	0x592D	#<CJK>
0x9AEF	0x5932	#<CJK>
0x9AF0	0x5938	#<CJK>
0x9AF1	0x593E	#<CJK>
0x9AF2	0x7AD2	#<CJK>
0x9AF3	0x5955	#<CJK>
0x9AF4	0x5950	#<CJK>
0x9AF5	0x594E	#<CJK>
0x9AF6	0x595A	#<CJK>
0x9AF7	0x5958	#<CJK>
0x9AF8	0x5962	#<CJK>
0x9AF9	0x5960	#<CJK>
0x9AFA	0x5967	#<CJK>
0x9AFB	0x596C	#<CJK>
0x9AFC	0x5969	#<CJK>
0x9B40	0x5978	#<CJK>
0x9B41	0x5981	#<CJK>
0x9B42	0x599D	#<CJK>
0x9B43	0x4F5E	#<CJK>
0x9B44	0x4FAB	#<CJK>
0x9B45	0x59A3	#<CJK>
0x9B46	0x59B2	#<CJK>
0x9B47	0x59C6	#<CJK>
0x9B48	0x59E8	#<CJK>
0x9B49	0x59DC	#<CJK>
0x9B4A	0x598D	#<CJK>
0x9B4B	0x59D9	#<CJK>
0x9B4C	0x59DA	#<CJK>
0x9B4D	0x5A25	#<CJK>
0x9B4E	0x5A1F	#<CJK>
0x9B4F	0x5A11	#<CJK>
0x9B50	0x5A1C	#<CJK>
0x9B51	0x5A09	#<CJK>
0x9B52	0x5A1A	#<CJK>
0x9B53	0x5A40	#<CJK>
0x9B54	0x5A6C	#<CJK>
0x9B55	0x5A49	#<CJK>
0x9B56	0x5A35	#<CJK>
0x9B57	0x5A36	#<CJK>
0x9B58	0x5A62	#<CJK>
0x9B59	0x5A6A	#<CJK>
0x9B5A	0x5A9A	#<CJK>
0x9B5B	0x5ABC	#<CJK>
0x9B5C	0x5ABE	#<CJK>
0x9B5D	0x5ACB	#<CJK>
0x9B5E	0x5AC2	#<CJK>
0x9B5F	0x5ABD	#<CJK>
0x9B60	0x5AE3	#<CJK>
0x9B61	0x5AD7	#<CJK>
0x9B62	0x5AE6	#<CJK>
0x9B63	0x5AE9	#<CJK>
0x9B64	0x5AD6	#<CJK>
0x9B65	0x5AFA	#<CJK>
0x9B66	0x5AFB	#<CJK>
0x9B67	0x5B0C	#<CJK>
0x9B68	0x5B0B	#<CJK>
0x9B69	0x5B16	#<CJK>
0x9B6A	0x5B32	#<CJK>
0x9B6B	0x5AD0	#<CJK>
0x9B6C	0x5B2A	#<CJK>
0x9B6D	0x5B36	#<CJK>
0x9B6E	0x5B3E	#<CJK>
0x9B6F	0x5B43	#<CJK>
0x9B70	0x5B45	#<CJK>
0x9B71	0x5B40	#<CJK>
0x9B72	0x5B51	#<CJK>
0x9B73	0x5B55	#<CJK>
0x9B74	0x5B5A	#<CJK>
0x9B75	0x5B5B	#<CJK>
0x9B76	0x5B65	#<CJK>
0x9B77	0x5B69	#<CJK>
0x9B78	0x5B70	#<CJK>
0x9B79	0x5B73	#<CJK>
0x9B7A	0x5B75	#<CJK>
0x9B7B	0x5B78	#<CJK>
0x9B7C	0x6588	#<CJK>
0x9B7D	0x5B7A	#<CJK>
0x9B7E	0x5B80	#<CJK>
0x9B80	0x5B83	#<CJK>
0x9B81	0x5BA6	#<CJK>
0x9B82	0x5BB8	#<CJK>
0x9B83	0x5BC3	#<CJK>
0x9B84	0x5BC7	#<CJK>
0x9B85	0x5BC9	#<CJK>
0x9B86	0x5BD4	#<CJK>
0x9B87	0x5BD0	#<CJK>
0x9B88	0x5BE4	#<CJK>
0x9B89	0x5BE6	#<CJK>
0x9B8A	0x5BE2	#<CJK>
0x9B8B	0x5BDE	#<CJK>
0x9B8C	0x5BE5	#<CJK>
0x9B8D	0x5BEB	#<CJK>
0x9B8E	0x5BF0	#<CJK>
0x9B8F	0x5BF6	#<CJK>
0x9B90	0x5BF3	#<CJK>
0x9B91	0x5C05	#<CJK>
0x9B92	0x5C07	#<CJK>
0x9B93	0x5C08	#<CJK>
0x9B94	0x5C0D	#<CJK>
0x9B95	0x5C13	#<CJK>
0x9B96	0x5C20	#<CJK>
0x9B97	0x5C22	#<CJK>
0x9B98	0x5C28	#<CJK>
0x9B99	0x5C38	#<CJK>
0x9B9A	0x5C39	#<CJK>
0x9B9B	0x5C41	#<CJK>
0x9B9C	0x5C46	#<CJK>
0x9B9D	0x5C4E	#<CJK>
0x9B9E	0x5C53	#<CJK>
0x9B9F	0x5C50	#<CJK>
0x9BA0	0x5C4F	#<CJK>
0x9BA1	0x5B71	#<CJK>
0x9BA2	0x5C6C	#<CJK>
0x9BA3	0x5C6E	#<CJK>
0x9BA4	0x4E62	#<CJK>
0x9BA5	0x5C76	#<CJK>
0x9BA6	0x5C79	#<CJK>
0x9BA7	0x5C8C	#<CJK>
0x9BA8	0x5C91	#<CJK>
0x9BA9	0x5C94	#<CJK>
0x9BAA	0x599B	#<CJK>
0x9BAB	0x5CAB	#<CJK>
0x9BAC	0x5CBB	#<CJK>
0x9BAD	0x5CB6	#<CJK>
0x9BAE	0x5CBC	#<CJK>
0x9BAF	0x5CB7	#<CJK>
0x9BB0	0x5CC5	#<CJK>
0x9BB1	0x5CBE	#<CJK>
0x9BB2	0x5CC7	#<CJK>
0x9BB3	0x5CD9	#<CJK>
0x9BB4	0x5CE9	#<CJK>
0x9BB5	0x5CFD	#<CJK>
0x9BB6	0x5CFA	#<CJK>
0x9BB7	0x5CED	#<CJK>
0x9BB8	0x5D8C	#<CJK>
0x9BB9	0x5CEA	#<CJK>
0x9BBA	0x5D0B	#<CJK>
0x9BBB	0x5D15	#<CJK>
0x9BBC	0x5D17	#<CJK>
0x9BBD	0x5D5C	#<CJK>
0x9BBE	0x5D1F	#<CJK>
0x9BBF	0x5D1B	#<CJK>
0x9BC0	0x5D11	#<CJK>
0x9BC1	0x5D14	#<CJK>
0x9BC2	0x5D22	#<CJK>
0x9BC3	0x5D1A	#<CJK>
0x9BC4	0x5D19	#<CJK>
0x9BC5	0x5D18	#<CJK>
0x9BC6	0x5D4C	#<CJK>
0x9BC7	0x5D52	#<CJK>
0x9BC8	0x5D4E	#<CJK>
0x9BC9	0x5D4B	#<CJK>
0x9BCA	0x5D6C	#<CJK>
0x9BCB	0x5D73	#<CJK>
0x9BCC	0x5D76	#<CJK>
0x9BCD	0x5D87	#<CJK>
0x9BCE	0x5D84	#<CJK>
0x9BCF	0x5D82	#<CJK>
0x9BD0	0x5DA2	#<CJK>
0x9BD1	0x5D9D	#<CJK>
0x9BD2	0x5DAC	#<CJK>
0x9BD3	0x5DAE	#<CJK>
0x9BD4	0x5DBD	#<CJK>
0x9BD5	0x5D90	#<CJK>
0x9BD6	0x5DB7	#<CJK>
0x9BD7	0x5DBC	#<CJK>
0x9BD8	0x5DC9	#<CJK>
0x9BD9	0x5DCD	#<CJK>
0x9BDA	0x5DD3	#<CJK>
0x9BDB	0x5DD2	#<CJK>
0x9BDC	0x5DD6	#<CJK>
0x9BDD	0x5DDB	#<CJK>
0x9BDE	0x5DEB	#<CJK>
0x9BDF	0x5DF2	#<CJK>
0x9BE0	0x5DF5	#<CJK>
0x9BE1	0x5E0B	#<CJK>
0x9BE2	0x5E1A	#<CJK>
0x9BE3	0x5E19	#<CJK>
0x9BE4	0x5E11	#<CJK>
0x9BE5	0x5E1B	#<CJK>
0x9BE6	0x5E36	#<CJK>
0x9BE7	0x5E37	#<CJK>
0x9BE8	0x5E44	#<CJK>
0x9BE9	0x5E43	#<CJK>
0x9BEA	0x5E40	#<CJK>
0x9BEB	0x5E4E	#<CJK>
0x9BEC	0x5E57	#<CJK>
0x9BED	0x5E54	#<CJK>
0x9BEE	0x5E5F	#<CJK>
0x9BEF	0x5E62	#<CJK>
0x9BF0	0x5E64	#<CJK>
0x9BF1	0x5E47	#<CJK>
0x9BF2	0x5E75	#<CJK>
0x9BF3	0x5E76	#<CJK>
0x9BF4	0x5E7A	#<CJK>
0x9BF5	0x9EBC	#<CJK>
0x9BF6	0x5E7F	#<CJK>
0x9BF7	0x5EA0	#<CJK>
0x9BF8	0x5EC1	#<CJK>
0x9BF9	0x5EC2	#<CJK>
0x9BFA	0x5EC8	#<CJK>
0x9BFB	0x5ED0	#<CJK>
0x9BFC	0x5ECF	#<CJK>
0x9C40	0x5ED6	#<CJK>
0x9C41	0x5EE3	#<CJK>
0x9C42	0x5EDD	#<CJK>
0x9C43	0x5EDA	#<CJK>
0x9C44	0x5EDB	#<CJK>
0x9C45	0x5EE2	#<CJK>
0x9C46	0x5EE1	#<CJK>
0x9C47	0x5EE8	#<CJK>
0x9C48	0x5EE9	#<CJK>
0x9C49	0x5EEC	#<CJK>
0x9C4A	0x5EF1	#<CJK>
0x9C4B	0x5EF3	#<CJK>
0x9C4C	0x5EF0	#<CJK>
0x9C4D	0x5EF4	#<CJK>
0x9C4E	0x5EF8	#<CJK>
0x9C4F	0x5EFE	#<CJK>
0x9C50	0x5F03	#<CJK>
0x9C51	0x5F09	#<CJK>
0x9C52	0x5F5D	#<CJK>
0x9C53	0x5F5C	#<CJK>
0x9C54	0x5F0B	#<CJK>
0x9C55	0x5F11	#<CJK>
0x9C56	0x5F16	#<CJK>
0x9C57	0x5F29	#<CJK>
0x9C58	0x5F2D	#<CJK>
0x9C59	0x5F38	#<CJK>
0x9C5A	0x5F41	#<CJK>
0x9C5B	0x5F48	#<CJK>
0x9C5C	0x5F4C	#<CJK>
0x9C5D	0x5F4E	#<CJK>
0x9C5E	0x5F2F	#<CJK>
0x9C5F	0x5F51	#<CJK>
0x9C60	0x5F56	#<CJK>
0x9C61	0x5F57	#<CJK>
0x9C62	0x5F59	#<CJK>
0x9C63	0x5F61	#<CJK>
0x9C64	0x5F6D	#<CJK>
0x9C65	0x5F73	#<CJK>
0x9C66	0x5F77	#<CJK>
0x9C67	0x5F83	#<CJK>
0x9C68	0x5F82	#<CJK>
0x9C69	0x5F7F	#<CJK>
0x9C6A	0x5F8A	#<CJK>
0x9C6B	0x5F88	#<CJK>
0x9C6C	0x5F91	#<CJK>
0x9C6D	0x5F87	#<CJK>
0x9C6E	0x5F9E	#<CJK>
0x9C6F	0x5F99	#<CJK>
0x9C70	0x5F98	#<CJK>
0x9C71	0x5FA0	#<CJK>
0x9C72	0x5FA8	#<CJK>
0x9C73	0x5FAD	#<CJK>
0x9C74	0x5FBC	#<CJK>
0x9C75	0x5FD6	#<CJK>
0x9C76	0x5FFB	#<CJK>
0x9C77	0x5FE4	#<CJK>
0x9C78	0x5FF8	#<CJK>
0x9C79	0x5FF1	#<CJK>
0x9C7A	0x5FDD	#<CJK>
0x9C7B	0x60B3	#<CJK>
0x9C7C	0x5FFF	#<CJK>
0x9C7D	0x6021	#<CJK>
0x9C7E	0x6060	#<CJK>
0x9C80	0x6019	#<CJK>
0x9C81	0x6010	#<CJK>
0x9C82	0x6029	#<CJK>
0x9C83	0x600E	#<CJK>
0x9C84	0x6031	#<CJK>
0x9C85	0x601B	#<CJK>
0x9C86	0x6015	#<CJK>
0x9C87	0x602B	#<CJK>
0x9C88	0x6026	#<CJK>
0x9C89	0x600F	#<CJK>
0x9C8A	0x603A	#<CJK>
0x9C8B	0x605A	#<CJK>
0x9C8C	0x6041	#<CJK>
0x9C8D	0x606A	#<CJK>
0x9C8E	0x6077	#<CJK>
0x9C8F	0x605F	#<CJK>
0x9C90	0x604A	#<CJK>
0x9C91	0x6046	#<CJK>
0x9C92	0x604D	#<CJK>
0x9C93	0x6063	#<CJK>
0x9C94	0x6043	#<CJK>
0x9C95	0x6064	#<CJK>
0x9C96	0x6042	#<CJK>
0x9C97	0x606C	#<CJK>
0x9C98	0x606B	#<CJK>
0x9C99	0x6059	#<CJK>
0x9C9A	0x6081	#<CJK>
0x9C9B	0x608D	#<CJK>
0x9C9C	0x60E7	#<CJK>
0x9C9D	0x6083	#<CJK>
0x9C9E	0x609A	#<CJK>
0x9C9F	0x6084	#<CJK>
0x9CA0	0x609B	#<CJK>
0x9CA1	0x6096	#<CJK>
0x9CA2	0x6097	#<CJK>
0x9CA3	0x6092	#<CJK>
0x9CA4	0x60A7	#<CJK>
0x9CA5	0x608B	#<CJK>
0x9CA6	0x60E1	#<CJK>
0x9CA7	0x60B8	#<CJK>
0x9CA8	0x60E0	#<CJK>
0x9CA9	0x60D3	#<CJK>
0x9CAA	0x60B4	#<CJK>
0x9CAB	0x5FF0	#<CJK>
0x9CAC	0x60BD	#<CJK>
0x9CAD	0x60C6	#<CJK>
0x9CAE	0x60B5	#<CJK>
0x9CAF	0x60D8	#<CJK>
0x9CB0	0x614D	#<CJK>
0x9CB1	0x6115	#<CJK>
0x9CB2	0x6106	#<CJK>
0x9CB3	0x60F6	#<CJK>
0x9CB4	0x60F7	#<CJK>
0x9CB5	0x6100	#<CJK>
0x9CB6	0x60F4	#<CJK>
0x9CB7	0x60FA	#<CJK>
0x9CB8	0x6103	#<CJK>
0x9CB9	0x6121	#<CJK>
0x9CBA	0x60FB	#<CJK>
0x9CBB	0x60F1	#<CJK>
0x9CBC	0x610D	#<CJK>
0x9CBD	0x610E	#<CJK>
0x9CBE	0x6147	#<CJK>
0x9CBF	0x613E	#<CJK>
0x9CC0	0x6128	#<CJK>
0x9CC1	0x6127	#<CJK>
0x9CC2	0x614A	#<CJK>
0x9CC3	0x613F	#<CJK>
0x9CC4	0x613C	#<CJK>
0x9CC5	0x612C	#<CJK>
0x9CC6	0x6134	#<CJK>
0x9CC7	0x613D	#<CJK>
0x9CC8	0x6142	#<CJK>
0x9CC9	0x6144	#<CJK>
0x9CCA	0x6173	#<CJK>
0x9CCB	0x6177	#<CJK>
0x9CCC	0x6158	#<CJK>
0x9CCD	0x6159	#<CJK>
0x9CCE	0x615A	#<CJK>
0x9CCF	0x616B	#<CJK>
0x9CD0	0x6174	#<CJK>
0x9CD1	0x616F	#<CJK>
0x9CD2	0x6165	#<CJK>
0x9CD3	0x6171	#<CJK>
0x9CD4	0x615F	#<CJK>
0x9CD5	0x615D	#<CJK>
0x9CD6	0x6153	#<CJK>
0x9CD7	0x6175	#<CJK>
0x9CD8	0x6199	#<CJK>
0x9CD9	0x6196	#<CJK>
0x9CDA	0x6187	#<CJK>
0x9CDB	0x61AC	#<CJK>
0x9CDC	0x6194	#<CJK>
0x9CDD	0x619A	#<CJK>
0x9CDE	0x618A	#<CJK>
0x9CDF	0x6191	#<CJK>
0x9CE0	0x61AB	#<CJK>
0x9CE1	0x61AE	#<CJK>
0x9CE2	0x61CC	#<CJK>
0x9CE3	0x61CA	#<CJK>
0x9CE4	0x61C9	#<CJK>
0x9CE5	0x61F7	#<CJK>
0x9CE6	0x61C8	#<CJK>
0x9CE7	0x61C3	#<CJK>
0x9CE8	0x61C6	#<CJK>
0x9CE9	0x61BA	#<CJK>
0x9CEA	0x61CB	#<CJK>
0x9CEB	0x7F79	#<CJK>
0x9CEC	0x61CD	#<CJK>
0x9CED	0x61E6	#<CJK>
0x9CEE	0x61E3	#<CJK>
0x9CEF	0x61F6	#<CJK>
0x9CF0	0x61FA	#<CJK>
0x9CF1	0x61F4	#<CJK>
0x9CF2	0x61FF	#<CJK>
0x9CF3	0x61FD	#<CJK>
0x9CF4	0x61FC	#<CJK>
0x9CF5	0x61FE	#<CJK>
0x9CF6	0x6200	#<CJK>
0x9CF7	0x6208	#<CJK>
0x9CF8	0x6209	#<CJK>
0x9CF9	0x620D	#<CJK>
0x9CFA	0x620C	#<CJK>
0x9CFB	0x6214	#<CJK>
0x9CFC	0x621B	#<CJK>
0x9D40	0x621E	#<CJK>
0x9D41	0x6221	#<CJK>
0x9D42	0x622A	#<CJK>
0x9D43	0x622E	#<CJK>
0x9D44	0x6230	#<CJK>
0x9D45	0x6232	#<CJK>
0x9D46	0x6233	#<CJK>
0x9D47	0x6241	#<CJK>
0x9D48	0x624E	#<CJK>
0x9D49	0x625E	#<CJK>
0x9D4A	0x6263	#<CJK>
0x9D4B	0x625B	#<CJK>
0x9D4C	0x6260	#<CJK>
0x9D4D	0x6268	#<CJK>
0x9D4E	0x627C	#<CJK>
0x9D4F	0x6282	#<CJK>
0x9D50	0x6289	#<CJK>
0x9D51	0x627E	#<CJK>
0x9D52	0x6292	#<CJK>
0x9D53	0x6293	#<CJK>
0x9D54	0x6296	#<CJK>
0x9D55	0x62D4	#<CJK>
0x9D56	0x6283	#<CJK>
0x9D57	0x6294	#<CJK>
0x9D58	0x62D7	#<CJK>
0x9D59	0x62D1	#<CJK>
0x9D5A	0x62BB	#<CJK>
0x9D5B	0x62CF	#<CJK>
0x9D5C	0x62FF	#<CJK>
0x9D5D	0x62C6	#<CJK>
0x9D5E	0x64D4	#<CJK>
0x9D5F	0x62C8	#<CJK>
0x9D60	0x62DC	#<CJK>
0x9D61	0x62CC	#<CJK>
0x9D62	0x62CA	#<CJK>
0x9D63	0x62C2	#<CJK>
0x9D64	0x62C7	#<CJK>
0x9D65	0x629B	#<CJK>
0x9D66	0x62C9	#<CJK>
0x9D67	0x630C	#<CJK>
0x9D68	0x62EE	#<CJK>
0x9D69	0x62F1	#<CJK>
0x9D6A	0x6327	#<CJK>
0x9D6B	0x6302	#<CJK>
0x9D6C	0x6308	#<CJK>
0x9D6D	0x62EF	#<CJK>
0x9D6E	0x62F5	#<CJK>
0x9D6F	0x6350	#<CJK>
0x9D70	0x633E	#<CJK>
0x9D71	0x634D	#<CJK>
0x9D72	0x641C	#<CJK>
0x9D73	0x634F	#<CJK>
0x9D74	0x6396	#<CJK>
0x9D75	0x638E	#<CJK>
0x9D76	0x6380	#<CJK>
0x9D77	0x63AB	#<CJK>
0x9D78	0x6376	#<CJK>
0x9D79	0x63A3	#<CJK>
0x9D7A	0x638F	#<CJK>
0x9D7B	0x6389	#<CJK>
0x9D7C	0x639F	#<CJK>
0x9D7D	0x63B5	#<CJK>
0x9D7E	0x636B	#<CJK>
0x9D80	0x6369	#<CJK>
0x9D81	0x63BE	#<CJK>
0x9D82	0x63E9	#<CJK>
0x9D83	0x63C0	#<CJK>
0x9D84	0x63C6	#<CJK>
0x9D85	0x63E3	#<CJK>
0x9D86	0x63C9	#<CJK>
0x9D87	0x63D2	#<CJK>
0x9D88	0x63F6	#<CJK>
0x9D89	0x63C4	#<CJK>
0x9D8A	0x6416	#<CJK>
0x9D8B	0x6434	#<CJK>
0x9D8C	0x6406	#<CJK>
0x9D8D	0x6413	#<CJK>
0x9D8E	0x6426	#<CJK>
0x9D8F	0x6436	#<CJK>
0x9D90	0x651D	#<CJK>
0x9D91	0x6417	#<CJK>
0x9D92	0x6428	#<CJK>
0x9D93	0x640F	#<CJK>
0x9D94	0x6467	#<CJK>
0x9D95	0x646F	#<CJK>
0x9D96	0x6476	#<CJK>
0x9D97	0x644E	#<CJK>
0x9D98	0x652A	#<CJK>
0x9D99	0x6495	#<CJK>
0x9D9A	0x6493	#<CJK>
0x9D9B	0x64A5	#<CJK>
0x9D9C	0x64A9	#<CJK>
0x9D9D	0x6488	#<CJK>
0x9D9E	0x64BC	#<CJK>
0x9D9F	0x64DA	#<CJK>
0x9DA0	0x64D2	#<CJK>
0x9DA1	0x64C5	#<CJK>
0x9DA2	0x64C7	#<CJK>
0x9DA3	0x64BB	#<CJK>
0x9DA4	0x64D8	#<CJK>
0x9DA5	0x64C2	#<CJK>
0x9DA6	0x64F1	#<CJK>
0x9DA7	0x64E7	#<CJK>
0x9DA8	0x8209	#<CJK>
0x9DA9	0x64E0	#<CJK>
0x9DAA	0x64E1	#<CJK>
0x9DAB	0x62AC	#<CJK>
0x9DAC	0x64E3	#<CJK>
0x9DAD	0x64EF	#<CJK>
0x9DAE	0x652C	#<CJK>
0x9DAF	0x64F6	#<CJK>
0x9DB0	0x64F4	#<CJK>
0x9DB1	0x64F2	#<CJK>
0x9DB2	0x64FA	#<CJK>
0x9DB3	0x6500	#<CJK>
0x9DB4	0x64FD	#<CJK>
0x9DB5	0x6518	#<CJK>
0x9DB6	0x651C	#<CJK>
0x9DB7	0x6505	#<CJK>
0x9DB8	0x6524	#<CJK>
0x9DB9	0x6523	#<CJK>
0x9DBA	0x652B	#<CJK>
0x9DBB	0x6534	#<CJK>
0x9DBC	0x6535	#<CJK>
0x9DBD	0x6537	#<CJK>
0x9DBE	0x6536	#<CJK>
0x9DBF	0x6538	#<CJK>
0x9DC0	0x754B	#<CJK>
0x9DC1	0x6548	#<CJK>
0x9DC2	0x6556	#<CJK>
0x9DC3	0x6555	#<CJK>
0x9DC4	0x654D	#<CJK>
0x9DC5	0x6558	#<CJK>
0x9DC6	0x655E	#<CJK>
0x9DC7	0x655D	#<CJK>
0x9DC8	0x6572	#<CJK>
0x9DC9	0x6578	#<CJK>
0x9DCA	0x6582	#<CJK>
0x9DCB	0x6583	#<CJK>
0x9DCC	0x8B8A	#<CJK>
0x9DCD	0x659B	#<CJK>
0x9DCE	0x659F	#<CJK>
0x9DCF	0x65AB	#<CJK>
0x9DD0	0x65B7	#<CJK>
0x9DD1	0x65C3	#<CJK>
0x9DD2	0x65C6	#<CJK>
0x9DD3	0x65C1	#<CJK>
0x9DD4	0x65C4	#<CJK>
0x9DD5	0x65CC	#<CJK>
0x9DD6	0x65D2	#<CJK>
0x9DD7	0x65DB	#<CJK>
0x9DD8	0x65D9	#<CJK>
0x9DD9	0x65E0	#<CJK>
0x9DDA	0x65E1	#<CJK>
0x9DDB	0x65F1	#<CJK>
0x9DDC	0x6772	#<CJK>
0x9DDD	0x660A	#<CJK>
0x9DDE	0x6603	#<CJK>
0x9DDF	0x65FB	#<CJK>
0x9DE0	0x6773	#<CJK>
0x9DE1	0x6635	#<CJK>
0x9DE2	0x6636	#<CJK>
0x9DE3	0x6634	#<CJK>
0x9DE4	0x661C	#<CJK>
0x9DE5	0x664F	#<CJK>
0x9DE6	0x6644	#<CJK>
0x9DE7	0x6649	#<CJK>
0x9DE8	0x6641	#<CJK>
0x9DE9	0x665E	#<CJK>
0x9DEA	0x665D	#<CJK>
0x9DEB	0x6664	#<CJK>
0x9DEC	0x6667	#<CJK>
0x9DED	0x6668	#<CJK>
0x9DEE	0x665F	#<CJK>
0x9DEF	0x6662	#<CJK>
0x9DF0	0x6670	#<CJK>
0x9DF1	0x6683	#<CJK>
0x9DF2	0x6688	#<CJK>
0x9DF3	0x668E	#<CJK>
0x9DF4	0x6689	#<CJK>
0x9DF5	0x6684	#<CJK>
0x9DF6	0x6698	#<CJK>
0x9DF7	0x669D	#<CJK>
0x9DF8	0x66C1	#<CJK>
0x9DF9	0x66B9	#<CJK>
0x9DFA	0x66C9	#<CJK>
0x9DFB	0x66BE	#<CJK>
0x9DFC	0x66BC	#<CJK>
0x9E40	0x66C4	#<CJK>
0x9E41	0x66B8	#<CJK>
0x9E42	0x66D6	#<CJK>
0x9E43	0x66DA	#<CJK>
0x9E44	0x66E0	#<CJK>
0x9E45	0x663F	#<CJK>
0x9E46	0x66E6	#<CJK>
0x9E47	0x66E9	#<CJK>
0x9E48	0x66F0	#<CJK>
0x9E49	0x66F5	#<CJK>
0x9E4A	0x66F7	#<CJK>
0x9E4B	0x670F	#<CJK>
0x9E4C	0x6716	#<CJK>
0x9E4D	0x671E	#<CJK>
0x9E4E	0x6726	#<CJK>
0x9E4F	0x6727	#<CJK>
0x9E50	0x9738	#<CJK>
0x9E51	0x672E	#<CJK>
0x9E52	0x673F	#<CJK>
0x9E53	0x6736	#<CJK>
0x9E54	0x6741	#<CJK>
0x9E55	0x6738	#<CJK>
0x9E56	0x6737	#<CJK>
0x9E57	0x6746	#<CJK>
0x9E58	0x675E	#<CJK>
0x9E59	0x6760	#<CJK>
0x9E5A	0x6759	#<CJK>
0x9E5B	0x6763	#<CJK>
0x9E5C	0x6764	#<CJK>
0x9E5D	0x6789	#<CJK>
0x9E5E	0x6770	#<CJK>
0x9E5F	0x67A9	#<CJK>
0x9E60	0x677C	#<CJK>
0x9E61	0x676A	#<CJK>
0x9E62	0x678C	#<CJK>
0x9E63	0x678B	#<CJK>
0x9E64	0x67A6	#<CJK>
0x9E65	0x67A1	#<CJK>
0x9E66	0x6785	#<CJK>
0x9E67	0x67B7	#<CJK>
0x9E68	0x67EF	#<CJK>
0x9E69	0x67B4	#<CJK>
0x9E6A	0x67EC	#<CJK>
0x9E6B	0x67B3	#<CJK>
0x9E6C	0x67E9	#<CJK>
0x9E6D	0x67B8	#<CJK>
0x9E6E	0x67E4	#<CJK>
0x9E6F	0x67DE	#<CJK>
0x9E70	0x67DD	#<CJK>
0x9E71	0x67E2	#<CJK>
0x9E72	0x67EE	#<CJK>
0x9E73	0x67B9	#<CJK>
0x9E74	0x67CE	#<CJK>
0x9E75	0x67C6	#<CJK>
0x9E76	0x67E7	#<CJK>
0x9E77	0x6A9C	#<CJK>
0x9E78	0x681E	#<CJK>
0x9E79	0x6846	#<CJK>
0x9E7A	0x6829	#<CJK>
0x9E7B	0x6840	#<CJK>
0x9E7C	0x684D	#<CJK>
0x9E7D	0x6832	#<CJK>
0x9E7E	0x684E	#<CJK>
0x9E80	0x68B3	#<CJK>
0x9E81	0x682B	#<CJK>
0x9E82	0x6859	#<CJK>
0x9E83	0x6863	#<CJK>
0x9E84	0x6877	#<CJK>
0x9E85	0x687F	#<CJK>
0x9E86	0x689F	#<CJK>
0x9E87	0x688F	#<CJK>
0x9E88	0x68AD	#<CJK>
0x9E89	0x6894	#<CJK>
0x9E8A	0x689D	#<CJK>
0x9E8B	0x689B	#<CJK>
0x9E8C	0x6883	#<CJK>
0x9E8D	0x6AAE	#<CJK>
0x9E8E	0x68B9	#<CJK>
0x9E8F	0x6874	#<CJK>
0x9E90	0x68B5	#<CJK>
0x9E91	0x68A0	#<CJK>
0x9E92	0x68BA	#<CJK>
0x9E93	0x690F	#<CJK>
0x9E94	0x688D	#<CJK>
0x9E95	0x687E	#<CJK>
0x9E96	0x6901	#<CJK>
0x9E97	0x68CA	#<CJK>
0x9E98	0x6908	#<CJK>
0x9E99	0x68D8	#<CJK>
0x9E9A	0x6922	#<CJK>
0x9E9B	0x6926	#<CJK>
0x9E9C	0x68E1	#<CJK>
0x9E9D	0x690C	#<CJK>
0x9E9E	0x68CD	#<CJK>
0x9E9F	0x68D4	#<CJK>
0x9EA0	0x68E7	#<CJK>
0x9EA1	0x68D5	#<CJK>
0x9EA2	0x6936	#<CJK>
0x9EA3	0x6912	#<CJK>
0x9EA4	0x6904	#<CJK>
0x9EA5	0x68D7	#<CJK>
0x9EA6	0x68E3	#<CJK>
0x9EA7	0x6925	#<CJK>
0x9EA8	0x68F9	#<CJK>
0x9EA9	0x68E0	#<CJK>
0x9EAA	0x68EF	#<CJK>
0x9EAB	0x6928	#<CJK>
0x9EAC	0x692A	#<CJK>
0x9EAD	0x691A	#<CJK>
0x9EAE	0x6923	#<CJK>
0x9EAF	0x6921	#<CJK>
0x9EB0	0x68C6	#<CJK>
0x9EB1	0x6979	#<CJK>
0x9EB2	0x6977	#<CJK>
0x9EB3	0x695C	#<CJK>
0x9EB4	0x6978	#<CJK>
0x9EB5	0x696B	#<CJK>
0x9EB6	0x6954	#<CJK>
0x9EB7	0x697E	#<CJK>
0x9EB8	0x696E	#<CJK>
0x9EB9	0x6939	#<CJK>
0x9EBA	0x6974	#<CJK>
0x9EBB	0x693D	#<CJK>
0x9EBC	0x6959	#<CJK>
0x9EBD	0x6930	#<CJK>
0x9EBE	0x6961	#<CJK>
0x9EBF	0x695E	#<CJK>
0x9EC0	0x695D	#<CJK>
0x9EC1	0x6981	#<CJK>
0x9EC2	0x696A	#<CJK>
0x9EC3	0x69B2	#<CJK>
0x9EC4	0x69AE	#<CJK>
0x9EC5	0x69D0	#<CJK>
0x9EC6	0x69BF	#<CJK>
0x9EC7	0x69C1	#<CJK>
0x9EC8	0x69D3	#<CJK>
0x9EC9	0x69BE	#<CJK>
0x9ECA	0x69CE	#<CJK>
0x9ECB	0x5BE8	#<CJK>
0x9ECC	0x69CA	#<CJK>
0x9ECD	0x69DD	#<CJK>
0x9ECE	0x69BB	#<CJK>
0x9ECF	0x69C3	#<CJK>
0x9ED0	0x69A7	#<CJK>
0x9ED1	0x6A2E	#<CJK>
0x9ED2	0x6991	#<CJK>
0x9ED3	0x69A0	#<CJK>
0x9ED4	0x699C	#<CJK>
0x9ED5	0x6995	#<CJK>
0x9ED6	0x69B4	#<CJK>
0x9ED7	0x69DE	#<CJK>
0x9ED8	0x69E8	#<CJK>
0x9ED9	0x6A02	#<CJK>
0x9EDA	0x6A1B	#<CJK>
0x9EDB	0x69FF	#<CJK>
0x9EDC	0x6B0A	#<CJK>
0x9EDD	0x69F9	#<CJK>
0x9EDE	0x69F2	#<CJK>
0x9EDF	0x69E7	#<CJK>
0x9EE0	0x6A05	#<CJK>
0x9EE1	0x69B1	#<CJK>
0x9EE2	0x6A1E	#<CJK>
0x9EE3	0x69ED	#<CJK>
0x9EE4	0x6A14	#<CJK>
0x9EE5	0x69EB	#<CJK>
0x9EE6	0x6A0A	#<CJK>
0x9EE7	0x6A12	#<CJK>
0x9EE8	0x6AC1	#<CJK>
0x9EE9	0x6A23	#<CJK>
0x9EEA	0x6A13	#<CJK>
0x9EEB	0x6A44	#<CJK>
0x9EEC	0x6A0C	#<CJK>
0x9EED	0x6A72	#<CJK>
0x9EEE	0x6A36	#<CJK>
0x9EEF	0x6A78	#<CJK>
0x9EF0	0x6A47	#<CJK>
0x9EF1	0x6A62	#<CJK>
0x9EF2	0x6A59	#<CJK>
0x9EF3	0x6A66	#<CJK>
0x9EF4	0x6A48	#<CJK>
0x9EF5	0x6A38	#<CJK>
0x9EF6	0x6A22	#<CJK>
0x9EF7	0x6A90	#<CJK>
0x9EF8	0x6A8D	#<CJK>
0x9EF9	0x6AA0	#<CJK>
0x9EFA	0x6A84	#<CJK>
0x9EFB	0x6AA2	#<CJK>
0x9EFC	0x6AA3	#<CJK>
0x9F40	0x6A97	#<CJK>
0x9F41	0x8617	#<CJK>
0x9F42	0x6ABB	#<CJK>
0x9F43	0x6AC3	#<CJK>
0x9F44	0x6AC2	#<CJK>
0x9F45	0x6AB8	#<CJK>
0x9F46	0x6AB3	#<CJK>
0x9F47	0x6AAC	#<CJK>
0x9F48	0x6ADE	#<CJK>
0x9F49	0x6AD1	#<CJK>
0x9F4A	0x6ADF	#<CJK>
0x9F4B	0x6AAA	#<CJK>
0x9F4C	0x6ADA	#<CJK>
0x9F4D	0x6AEA	#<CJK>
0x9F4E	0x6AFB	#<CJK>
0x9F4F	0x6B05	#<CJK>
0x9F50	0x8616	#<CJK>
0x9F51	0x6AFA	#<CJK>
0x9F52	0x6B12	#<CJK>
0x9F53	0x6B16	#<CJK>
0x9F54	0x9B31	#<CJK>
0x9F55	0x6B1F	#<CJK>
0x9F56	0x6B38	#<CJK>
0x9F57	0x6B37	#<CJK>
0x9F58	0x76DC	#<CJK>
0x9F59	0x6B39	#<CJK>
0x9F5A	0x98EE	#<CJK>
0x9F5B	0x6B47	#<CJK>
0x9F5C	0x6B43	#<CJK>
0x9F5D	0x6B49	#<CJK>
0x9F5E	0x6B50	#<CJK>
0x9F5F	0x6B59	#<CJK>
0x9F60	0x6B54	#<CJK>
0x9F61	0x6B5B	#<CJK>
0x9F62	0x6B5F	#<CJK>
0x9F63	0x6B61	#<CJK>
0x9F64	0x6B78	#<CJK>
0x9F65	0x6B79	#<CJK>
0x9F66	0x6B7F	#<CJK>
0x9F67	0x6B80	#<CJK>
0x9F68	0x6B84	#<CJK>
0x9F69	0x6B83	#<CJK>
0x9F6A	0x6B8D	#<CJK>
0x9F6B	0x6B98	#<CJK>
0x9F6C	0x6B95	#<CJK>
0x9F6D	0x6B9E	#<CJK>
0x9F6E	0x6BA4	#<CJK>
0x9F6F	0x6BAA	#<CJK>
0x9F70	0x6BAB	#<CJK>
0x9F71	0x6BAF	#<CJK>
0x9F72	0x6BB2	#<CJK>
0x9F73	0x6BB1	#<CJK>
0x9F74	0x6BB3	#<CJK>
0x9F75	0x6BB7	#<CJK>
0x9F76	0x6BBC	#<CJK>
0x9F77	0x6BC6	#<CJK>
0x9F78	0x6BCB	#<CJK>
0x9F79	0x6BD3	#<CJK>
0x9F7A	0x6BDF	#<CJK>
0x9F7B	0x6BEC	#<CJK>
0x9F7C	0x6BEB	#<CJK>
0x9F7D	0x6BF3	#<CJK>
0x9F7E	0x6BEF	#<CJK>
0x9F80	0x9EBE	#<CJK>
0x9F81	0x6C08	#<CJK>
0x9F82	0x6C13	#<CJK>
0x9F83	0x6C14	#<CJK>
0x9F84	0x6C1B	#<CJK>
0x9F85	0x6C24	#<CJK>
0x9F86	0x6C23	#<CJK>
0x9F87	0x6C5E	#<CJK>
0x9F88	0x6C55	#<CJK>
0x9F89	0x6C62	#<CJK>
0x9F8A	0x6C6A	#<CJK>
0x9F8B	0x6C82	#<CJK>
0x9F8C	0x6C8D	#<CJK>
0x9F8D	0x6C9A	#<CJK>
0x9F8E	0x6C81	#<CJK>
0x9F8F	0x6C9B	#<CJK>
0x9F90	0x6C7E	#<CJK>
0x9F91	0x6C68	#<CJK>
0x9F92	0x6C73	#<CJK>
0x9F93	0x6C92	#<CJK>
0x9F94	0x6C90	#<CJK>
0x9F95	0x6CC4	#<CJK>
0x9F96	0x6CF1	#<CJK>
0x9F97	0x6CD3	#<CJK>
0x9F98	0x6CBD	#<CJK>
0x9F99	0x6CD7	#<CJK>
0x9F9A	0x6CC5	#<CJK>
0x9F9B	0x6CDD	#<CJK>
0x9F9C	0x6CAE	#<CJK>
0x9F9D	0x6CB1	#<CJK>
0x9F9E	0x6CBE	#<CJK>
0x9F9F	0x6CBA	#<CJK>
0x9FA0	0x6CDB	#<CJK>
0x9FA1	0x6CEF	#<CJK>
0x9FA2	0x6CD9	#<CJK>
0x9FA3	0x6CEA	#<CJK>
0x9FA4	0x6D1F	#<CJK>
0x9FA5	0x884D	#<CJK>
0x9FA6	0x6D36	#<CJK>
0x9FA7	0x6D2B	#<CJK>
0x9FA8	0x6D3D	#<CJK>
0x9FA9	0x6D38	#<CJK>
0x9FAA	0x6D19	#<CJK>
0x9FAB	0x6D35	#<CJK>
0x9FAC	0x6D33	#<CJK>
0x9FAD	0x6D12	#<CJK>
0x9FAE	0x6D0C	#<CJK>
0x9FAF	0x6D63	#<CJK>
0x9FB0	0x6D93	#<CJK>
0x9FB1	0x6D64	#<CJK>
0x9FB2	0x6D5A	#<CJK>
0x9FB3	0x6D79	#<CJK>
0x9FB4	0x6D59	#<CJK>
0x9FB5	0x6D8E	#<CJK>
0x9FB6	0x6D95	#<CJK>
0x9FB7	0x6FE4	#<CJK>
0x9FB8	0x6D85	#<CJK>
0x9FB9	0x6DF9	#<CJK>
0x9FBA	0x6E15	#<CJK>
0x9FBB	0x6E0A	#<CJK>
0x9FBC	0x6DB5	#<CJK>
0x9FBD	0x6DC7	#<CJK>
0x9FBE	0x6DE6	#<CJK>
0x9FBF	0x6DB8	#<CJK>
0x9FC0	0x6DC6	#<CJK>
0x9FC1	0x6DEC	#<CJK>
0x9FC2	0x6DDE	#<CJK>
0x9FC3	0x6DCC	#<CJK>
0x9FC4	0x6DE8	#<CJK>
0x9FC5	0x6DD2	#<CJK>
0x9FC6	0x6DC5	#<CJK>
0x9FC7	0x6DFA	#<CJK>
0x9FC8	0x6DD9	#<CJK>
0x9FC9	0x6DE4	#<CJK>
0x9FCA	0x6DD5	#<CJK>
0x9FCB	0x6DEA	#<CJK>
0x9FCC	0x6DEE	#<CJK>
0x9FCD	0x6E2D	#<CJK>
0x9FCE	0x6E6E	#<CJK>
0x9FCF	0x6E2E	#<CJK>
0x9FD0	0x6E19	#<CJK>
0x9FD1	0x6E72	#<CJK>
0x9FD2	0x6E5F	#<CJK>
0x9FD3	0x6E3E	#<CJK>
0x9FD4	0x6E23	#<CJK>
0x9FD5	0x6E6B	#<CJK>
0x9FD6	0x6E2B	#<CJK>
0x9FD7	0x6E76	#<CJK>
0x9FD8	0x6E4D	#<CJK>
0x9FD9	0x6E1F	#<CJK>
0x9FDA	0x6E43	#<CJK>
0x9FDB	0x6E3A	#<CJK>
0x9FDC	0x6E4E	#<CJK>
0x9FDD	0x6E24	#<CJK>
0x9FDE	0x6EFF	#<CJK>
0x9FDF	0x6E1D	#<CJK>
0x9FE0	0x6E38	#<CJK>
0x9FE1	0x6E82	#<CJK>
0x9FE2	0x6EAA	#<CJK>
0x9FE3	0x6E98	#<CJK>
0x9FE4	0x6EC9	#<CJK>
0x9FE5	0x6EB7	#<CJK>
0x9FE6	0x6ED3	#<CJK>
0x9FE7	0x6EBD	#<CJK>
0x9FE8	0x6EAF	#<CJK>
0x9FE9	0x6EC4	#<CJK>
0x9FEA	0x6EB2	#<CJK>
0x9FEB	0x6ED4	#<CJK>
0x9FEC	0x6ED5	#<CJK>
0x9FED	0x6E8F	#<CJK>
0x9FEE	0x6EA5	#<CJK>
0x9FEF	0x6EC2	#<CJK>
0x9FF0	0x6E9F	#<CJK>
0x9FF1	0x6F41	#<CJK>
0x9FF2	0x6F11	#<CJK>
0x9FF3	0x704C	#<CJK>
0x9FF4	0x6EEC	#<CJK>
0x9FF5	0x6EF8	#<CJK>
0x9FF6	0x6EFE	#<CJK>
0x9FF7	0x6F3F	#<CJK>
0x9FF8	0x6EF2	#<CJK>
0x9FF9	0x6F31	#<CJK>
0x9FFA	0x6EEF	#<CJK>
0x9FFB	0x6F32	#<CJK>
0x9FFC	0x6ECC	#<CJK>
0xE040	0x6F3E	#<CJK>
0xE041	0x6F13	#<CJK>
0xE042	0x6EF7	#<CJK>
0xE043	0x6F86	#<CJK>
0xE044	0x6F7A	#<CJK>
0xE045	0x6F78	#<CJK>
0xE046	0x6F81	#<CJK>
0xE047	0x6F80	#<CJK>
0xE048	0x6F6F	#<CJK>
0xE049	0x6F5B	#<CJK>
0xE04A	0x6FF3	#<CJK>
0xE04B	0x6F6D	#<CJK>
0xE04C	0x6F82	#<CJK>
0xE04D	0x6F7C	#<CJK>
0xE04E	0x6F58	#<CJK>
0xE04F	0x6F8E	#<CJK>
0xE050	0x6F91	#<CJK>
0xE051	0x6FC2	#<CJK>
0xE052	0x6F66	#<CJK>
0xE053	0x6FB3	#<CJK>
0xE054	0x6FA3	#<CJK>
0xE055	0x6FA1	#<CJK>
0xE056	0x6FA4	#<CJK>
0xE057	0x6FB9	#<CJK>
0xE058	0x6FC6	#<CJK>
0xE059	0x6FAA	#<CJK>
0xE05A	0x6FDF	#<CJK>
0xE05B	0x6FD5	#<CJK>
0xE05C	0x6FEC	#<CJK>
0xE05D	0x6FD4	#<CJK>
0xE05E	0x6FD8	#<CJK>
0xE05F	0x6FF1	#<CJK>
0xE060	0x6FEE	#<CJK>
0xE061	0x6FDB	#<CJK>
0xE062	0x7009	#<CJK>
0xE063	0x700B	#<CJK>
0xE064	0x6FFA	#<CJK>
0xE065	0x7011	#<CJK>
0xE066	0x7001	#<CJK>
0xE067	0x700F	#<CJK>
0xE068	0x6FFE	#<CJK>
0xE069	0x701B	#<CJK>
0xE06A	0x701A	#<CJK>
0xE06B	0x6F74	#<CJK>
0xE06C	0x701D	#<CJK>
0xE06D	0x7018	#<CJK>
0xE06E	0x701F	#<CJK>
0xE06F	0x7030	#<CJK>
0xE070	0x703E	#<CJK>
0xE071	0x7032	#<CJK>
0xE072	0x7051	#<CJK>
0xE073	0x7063	#<CJK>
0xE074	0x7099	#<CJK>
0xE075	0x7092	#<CJK>
0xE076	0x70AF	#<CJK>
0xE077	0x70F1	#<CJK>
0xE078	0x70AC	#<CJK>
0xE079	0x70B8	#<CJK>
0xE07A	0x70B3	#<CJK>
0xE07B	0x70AE	#<CJK>
0xE07C	0x70DF	#<CJK>
0xE07D	0x70CB	#<CJK>
0xE07E	0x70DD	#<CJK>
0xE080	0x70D9	#<CJK>
0xE081	0x7109	#<CJK>
0xE082	0x70FD	#<CJK>
0xE083	0x711C	#<CJK>
0xE084	0x7119	#<CJK>
0xE085	0x7165	#<CJK>
0xE086	0x7155	#<CJK>
0xE087	0x7188	#<CJK>
0xE088	0x7166	#<CJK>
0xE089	0x7162	#<CJK>
0xE08A	0x714C	#<CJK>
0xE08B	0x7156	#<CJK>
0xE08C	0x716C	#<CJK>
0xE08D	0x718F	#<CJK>
0xE08E	0x71FB	#<CJK>
0xE08F	0x7184	#<CJK>
0xE090	0x7195	#<CJK>
0xE091	0x71A8	#<CJK>
0xE092	0x71AC	#<CJK>
0xE093	0x71D7	#<CJK>
0xE094	0x71B9	#<CJK>
0xE095	0x71BE	#<CJK>
0xE096	0x71D2	#<CJK>
0xE097	0x71C9	#<CJK>
0xE098	0x71D4	#<CJK>
0xE099	0x71CE	#<CJK>
0xE09A	0x71E0	#<CJK>
0xE09B	0x71EC	#<CJK>
0xE09C	0x71E7	#<CJK>
0xE09D	0x71F5	#<CJK>
0xE09E	0x71FC	#<CJK>
0xE09F	0x71F9	#<CJK>
0xE0A0	0x71FF	#<CJK>
0xE0A1	0x720D	#<CJK>
0xE0A2	0x7210	#<CJK>
0xE0A3	0x721B	#<CJK>
0xE0A4	0x7228	#<CJK>
0xE0A5	0x722D	#<CJK>
0xE0A6	0x722C	#<CJK>
0xE0A7	0x7230	#<CJK>
0xE0A8	0x7232	#<CJK>
0xE0A9	0x723B	#<CJK>
0xE0AA	0x723C	#<CJK>
0xE0AB	0x723F	#<CJK>
0xE0AC	0x7240	#<CJK>
0xE0AD	0x7246	#<CJK>
0xE0AE	0x724B	#<CJK>
0xE0AF	0x7258	#<CJK>
0xE0B0	0x7274	#<CJK>
0xE0B1	0x727E	#<CJK>
0xE0B2	0x7282	#<CJK>
0xE0B3	0x7281	#<CJK>
0xE0B4	0x7287	#<CJK>
0xE0B5	0x7292	#<CJK>
0xE0B6	0x7296	#<CJK>
0xE0B7	0x72A2	#<CJK>
0xE0B8	0x72A7	#<CJK>
0xE0B9	0x72B9	#<CJK>
0xE0BA	0x72B2	#<CJK>
0xE0BB	0x72C3	#<CJK>
0xE0BC	0x72C6	#<CJK>
0xE0BD	0x72C4	#<CJK>
0xE0BE	0x72CE	#<CJK>
0xE0BF	0x72D2	#<CJK>
0xE0C0	0x72E2	#<CJK>
0xE0C1	0x72E0	#<CJK>
0xE0C2	0x72E1	#<CJK>
0xE0C3	0x72F9	#<CJK>
0xE0C4	0x72F7	#<CJK>
0xE0C5	0x500F	#<CJK>
0xE0C6	0x7317	#<CJK>
0xE0C7	0x730A	#<CJK>
0xE0C8	0x731C	#<CJK>
0xE0C9	0x7316	#<CJK>
0xE0CA	0x731D	#<CJK>
0xE0CB	0x7334	#<CJK>
0xE0CC	0x732F	#<CJK>
0xE0CD	0x7329	#<CJK>
0xE0CE	0x7325	#<CJK>
0xE0CF	0x733E	#<CJK>
0xE0D0	0x734E	#<CJK>
0xE0D1	0x734F	#<CJK>
0xE0D2	0x9ED8	#<CJK>
0xE0D3	0x7357	#<CJK>
0xE0D4	0x736A	#<CJK>
0xE0D5	0x7368	#<CJK>
0xE0D6	0x7370	#<CJK>
0xE0D7	0x7378	#<CJK>
0xE0D8	0x7375	#<CJK>
0xE0D9	0x737B	#<CJK>
0xE0DA	0x737A	#<CJK>
0xE0DB	0x73C8	#<CJK>
0xE0DC	0x73B3	#<CJK>
0xE0DD	0x73CE	#<CJK>
0xE0DE	0x73BB	#<CJK>
0xE0DF	0x73C0	#<CJK>
0xE0E0	0x73E5	#<CJK>
0xE0E1	0x73EE	#<CJK>
0xE0E2	0x73DE	#<CJK>
0xE0E3	0x74A2	#<CJK>
0xE0E4	0x7405	#<CJK>
0xE0E5	0x746F	#<CJK>
0xE0E6	0x7425	#<CJK>
0xE0E7	0x73F8	#<CJK>
0xE0E8	0x7432	#<CJK>
0xE0E9	0x743A	#<CJK>
0xE0EA	0x7455	#<CJK>
0xE0EB	0x743F	#<CJK>
0xE0EC	0x745F	#<CJK>
0xE0ED	0x7459	#<CJK>
0xE0EE	0x7441	#<CJK>
0xE0EF	0x745C	#<CJK>
0xE0F0	0x7469	#<CJK>
0xE0F1	0x7470	#<CJK>
0xE0F2	0x7463	#<CJK>
0xE0F3	0x746A	#<CJK>
0xE0F4	0x7476	#<CJK>
0xE0F5	0x747E	#<CJK>
0xE0F6	0x748B	#<CJK>
0xE0F7	0x749E	#<CJK>
0xE0F8	0x74A7	#<CJK>
0xE0F9	0x74CA	#<CJK>
0xE0FA	0x74CF	#<CJK>
0xE0FB	0x74D4	#<CJK>
0xE0FC	0x73F1	#<CJK>
0xE140	0x74E0	#<CJK>
0xE141	0x74E3	#<CJK>
0xE142	0x74E7	#<CJK>
0xE143	0x74E9	#<CJK>
0xE144	0x74EE	#<CJK>
0xE145	0x74F2	#<CJK>
0xE146	0x74F0	#<CJK>
0xE147	0x74F1	#<CJK>
0xE148	0x74F8	#<CJK>
0xE149	0x74F7	#<CJK>
0xE14A	0x7504	#<CJK>
0xE14B	0x7503	#<CJK>
0xE14C	0x7505	#<CJK>
0xE14D	0x750C	#<CJK>
0xE14E	0x750E	#<CJK>
0xE14F	0x750D	#<CJK>
0xE150	0x7515	#<CJK>
0xE151	0x7513	#<CJK>
0xE152	0x751E	#<CJK>
0xE153	0x7526	#<CJK>
0xE154	0x752C	#<CJK>
0xE155	0x753C	#<CJK>
0xE156	0x7544	#<CJK>
0xE157	0x754D	#<CJK>
0xE158	0x754A	#<CJK>
0xE159	0x7549	#<CJK>
0xE15A	0x755B	#<CJK>
0xE15B	0x7546	#<CJK>
0xE15C	0x755A	#<CJK>
0xE15D	0x7569	#<CJK>
0xE15E	0x7564	#<CJK>
0xE15F	0x7567	#<CJK>
0xE160	0x756B	#<CJK>
0xE161	0x756D	#<CJK>
0xE162	0x7578	#<CJK>
0xE163	0x7576	#<CJK>
0xE164	0x7586	#<CJK>
0xE165	0x7587	#<CJK>
0xE166	0x7574	#<CJK>
0xE167	0x758A	#<CJK>
0xE168	0x7589	#<CJK>
0xE169	0x7582	#<CJK>
0xE16A	0x7594	#<CJK>
0xE16B	0x759A	#<CJK>
0xE16C	0x759D	#<CJK>
0xE16D	0x75A5	#<CJK>
0xE16E	0x75A3	#<CJK>
0xE16F	0x75C2	#<CJK>
0xE170	0x75B3	#<CJK>
0xE171	0x75C3	#<CJK>
0xE172	0x75B5	#<CJK>
0xE173	0x75BD	#<CJK>
0xE174	0x75B8	#<CJK>
0xE175	0x75BC	#<CJK>
0xE176	0x75B1	#<CJK>
0xE177	0x75CD	#<CJK>
0xE178	0x75CA	#<CJK>
0xE179	0x75D2	#<CJK>
0xE17A	0x75D9	#<CJK>
0xE17B	0x75E3	#<CJK>
0xE17C	0x75DE	#<CJK>
0xE17D	0x75FE	#<CJK>
0xE17E	0x75FF	#<CJK>
0xE180	0x75FC	#<CJK>
0xE181	0x7601	#<CJK>
0xE182	0x75F0	#<CJK>
0xE183	0x75FA	#<CJK>
0xE184	0x75F2	#<CJK>
0xE185	0x75F3	#<CJK>
0xE186	0x760B	#<CJK>
0xE187	0x760D	#<CJK>
0xE188	0x7609	#<CJK>
0xE189	0x761F	#<CJK>
0xE18A	0x7627	#<CJK>
0xE18B	0x7620	#<CJK>
0xE18C	0x7621	#<CJK>
0xE18D	0x7622	#<CJK>
0xE18E	0x7624	#<CJK>
0xE18F	0x7634	#<CJK>
0xE190	0x7630	#<CJK>
0xE191	0x763B	#<CJK>
0xE192	0x7647	#<CJK>
0xE193	0x7648	#<CJK>
0xE194	0x7646	#<CJK>
0xE195	0x765C	#<CJK>
0xE196	0x7658	#<CJK>
0xE197	0x7661	#<CJK>
0xE198	0x7662	#<CJK>
0xE199	0x7668	#<CJK>
0xE19A	0x7669	#<CJK>
0xE19B	0x766A	#<CJK>
0xE19C	0x7667	#<CJK>
0xE19D	0x766C	#<CJK>
0xE19E	0x7670	#<CJK>
0xE19F	0x7672	#<CJK>
0xE1A0	0x7676	#<CJK>
0xE1A1	0x7678	#<CJK>
0xE1A2	0x767C	#<CJK>
0xE1A3	0x7680	#<CJK>
0xE1A4	0x7683	#<CJK>
0xE1A5	0x7688	#<CJK>
0xE1A6	0x768B	#<CJK>
0xE1A7	0x768E	#<CJK>
0xE1A8	0x7696	#<CJK>
0xE1A9	0x7693	#<CJK>
0xE1AA	0x7699	#<CJK>
0xE1AB	0x769A	#<CJK>
0xE1AC	0x76B0	#<CJK>
0xE1AD	0x76B4	#<CJK>
0xE1AE	0x76B8	#<CJK>
0xE1AF	0x76B9	#<CJK>
0xE1B0	0x76BA	#<CJK>
0xE1B1	0x76C2	#<CJK>
0xE1B2	0x76CD	#<CJK>
0xE1B3	0x76D6	#<CJK>
0xE1B4	0x76D2	#<CJK>
0xE1B5	0x76DE	#<CJK>
0xE1B6	0x76E1	#<CJK>
0xE1B7	0x76E5	#<CJK>
0xE1B8	0x76E7	#<CJK>
0xE1B9	0x76EA	#<CJK>
0xE1BA	0x862F	#<CJK>
0xE1BB	0x76FB	#<CJK>
0xE1BC	0x7708	#<CJK>
0xE1BD	0x7707	#<CJK>
0xE1BE	0x7704	#<CJK>
0xE1BF	0x7729	#<CJK>
0xE1C0	0x7724	#<CJK>
0xE1C1	0x771E	#<CJK>
0xE1C2	0x7725	#<CJK>
0xE1C3	0x7726	#<CJK>
0xE1C4	0x771B	#<CJK>
0xE1C5	0x7737	#<CJK>
0xE1C6	0x7738	#<CJK>
0xE1C7	0x7747	#<CJK>
0xE1C8	0x775A	#<CJK>
0xE1C9	0x7768	#<CJK>
0xE1CA	0x776B	#<CJK>
0xE1CB	0x775B	#<CJK>
0xE1CC	0x7765	#<CJK>
0xE1CD	0x777F	#<CJK>
0xE1CE	0x777E	#<CJK>
0xE1CF	0x7779	#<CJK>
0xE1D0	0x778E	#<CJK>
0xE1D1	0x778B	#<CJK>
0xE1D2	0x7791	#<CJK>
0xE1D3	0x77A0	#<CJK>
0xE1D4	0x779E	#<CJK>
0xE1D5	0x77B0	#<CJK>
0xE1D6	0x77B6	#<CJK>
0xE1D7	0x77B9	#<CJK>
0xE1D8	0x77BF	#<CJK>
0xE1D9	0x77BC	#<CJK>
0xE1DA	0x77BD	#<CJK>
0xE1DB	0x77BB	#<CJK>
0xE1DC	0x77C7	#<CJK>
0xE1DD	0x77CD	#<CJK>
0xE1DE	0x77D7	#<CJK>
0xE1DF	0x77DA	#<CJK>
0xE1E0	0x77DC	#<CJK>
0xE1E1	0x77E3	#<CJK>
0xE1E2	0x77EE	#<CJK>
0xE1E3	0x77FC	#<CJK>
0xE1E4	0x780C	#<CJK>
0xE1E5	0x7812	#<CJK>
0xE1E6	0x7926	#<CJK>
0xE1E7	0x7820	#<CJK>
0xE1E8	0x792A	#<CJK>
0xE1E9	0x7845	#<CJK>
0xE1EA	0x788E	#<CJK>
0xE1EB	0x7874	#<CJK>
0xE1EC	0x7886	#<CJK>
0xE1ED	0x787C	#<CJK>
0xE1EE	0x789A	#<CJK>
0xE1EF	0x788C	#<CJK>
0xE1F0	0x78A3	#<CJK>
0xE1F1	0x78B5	#<CJK>
0xE1F2	0x78AA	#<CJK>
0xE1F3	0x78AF	#<CJK>
0xE1F4	0x78D1	#<CJK>
0xE1F5	0x78C6	#<CJK>
0xE1F6	0x78CB	#<CJK>
0xE1F7	0x78D4	#<CJK>
0xE1F8	0x78BE	#<CJK>
0xE1F9	0x78BC	#<CJK>
0xE1FA	0x78C5	#<CJK>
0xE1FB	0x78CA	#<CJK>
0xE1FC	0x78EC	#<CJK>
0xE240	0x78E7	#<CJK>
0xE241	0x78DA	#<CJK>
0xE242	0x78FD	#<CJK>
0xE243	0x78F4	#<CJK>
0xE244	0x7907	#<CJK>
0xE245	0x7912	#<CJK>
0xE246	0x7911	#<CJK>
0xE247	0x7919	#<CJK>
0xE248	0x792C	#<CJK>
0xE249	0x792B	#<CJK>
0xE24A	0x7940	#<CJK>
0xE24B	0x7960	#<CJK>
0xE24C	0x7957	#<CJK>
0xE24D	0x795F	#<CJK>
0xE24E	0x795A	#<CJK>
0xE24F	0x7955	#<CJK>
0xE250	0x7953	#<CJK>
0xE251	0x797A	#<CJK>
0xE252	0x797F	#<CJK>
0xE253	0x798A	#<CJK>
0xE254	0x799D	#<CJK>
0xE255	0x79A7	#<CJK>
0xE256	0x9F4B	#<CJK>
0xE257	0x79AA	#<CJK>
0xE258	0x79AE	#<CJK>
0xE259	0x79B3	#<CJK>
0xE25A	0x79B9	#<CJK>
0xE25B	0x79BA	#<CJK>
0xE25C	0x79C9	#<CJK>
0xE25D	0x79D5	#<CJK>
0xE25E	0x79E7	#<CJK>
0xE25F	0x79EC	#<CJK>
0xE260	0x79E1	#<CJK>
0xE261	0x79E3	#<CJK>
0xE262	0x7A08	#<CJK>
0xE263	0x7A0D	#<CJK>
0xE264	0x7A18	#<CJK>
0xE265	0x7A19	#<CJK>
0xE266	0x7A20	#<CJK>
0xE267	0x7A1F	#<CJK>
0xE268	0x7980	#<CJK>
0xE269	0x7A31	#<CJK>
0xE26A	0x7A3B	#<CJK>
0xE26B	0x7A3E	#<CJK>
0xE26C	0x7A37	#<CJK>
0xE26D	0x7A43	#<CJK>
0xE26E	0x7A57	#<CJK>
0xE26F	0x7A49	#<CJK>
0xE270	0x7A61	#<CJK>
0xE271	0x7A62	#<CJK>
0xE272	0x7A69	#<CJK>
0xE273	0x9F9D	#<CJK>
0xE274	0x7A70	#<CJK>
0xE275	0x7A79	#<CJK>
0xE276	0x7A7D	#<CJK>
0xE277	0x7A88	#<CJK>
0xE278	0x7A97	#<CJK>
0xE279	0x7A95	#<CJK>
0xE27A	0x7A98	#<CJK>
0xE27B	0x7A96	#<CJK>
0xE27C	0x7AA9	#<CJK>
0xE27D	0x7AC8	#<CJK>
0xE27E	0x7AB0	#<CJK>
0xE280	0x7AB6	#<CJK>
0xE281	0x7AC5	#<CJK>
0xE282	0x7AC4	#<CJK>
0xE283	0x7ABF	#<CJK>
0xE284	0x9083	#<CJK>
0xE285	0x7AC7	#<CJK>
0xE286	0x7ACA	#<CJK>
0xE287	0x7ACD	#<CJK>
0xE288	0x7ACF	#<CJK>
0xE289	0x7AD5	#<CJK>
0xE28A	0x7AD3	#<CJK>
0xE28B	0x7AD9	#<CJK>
0xE28C	0x7ADA	#<CJK>
0xE28D	0x7ADD	#<CJK>
0xE28E	0x7AE1	#<CJK>
0xE28F	0x7AE2	#<CJK>
0xE290	0x7AE6	#<CJK>
0xE291	0x7AED	#<CJK>
0xE292	0x7AF0	#<CJK>
0xE293	0x7B02	#<CJK>
0xE294	0x7B0F	#<CJK>
0xE295	0x7B0A	#<CJK>
0xE296	0x7B06	#<CJK>
0xE297	0x7B33	#<CJK>
0xE298	0x7B18	#<CJK>
0xE299	0x7B19	#<CJK>
0xE29A	0x7B1E	#<CJK>
0xE29B	0x7B35	#<CJK>
0xE29C	0x7B28	#<CJK>
0xE29D	0x7B36	#<CJK>
0xE29E	0x7B50	#<CJK>
0xE29F	0x7B7A	#<CJK>
0xE2A0	0x7B04	#<CJK>
0xE2A1	0x7B4D	#<CJK>
0xE2A2	0x7B0B	#<CJK>
0xE2A3	0x7B4C	#<CJK>
0xE2A4	0x7B45	#<CJK>
0xE2A5	0x7B75	#<CJK>
0xE2A6	0x7B65	#<CJK>
0xE2A7	0x7B74	#<CJK>
0xE2A8	0x7B67	#<CJK>
0xE2A9	0x7B70	#<CJK>
0xE2AA	0x7B71	#<CJK>
0xE2AB	0x7B6C	#<CJK>
0xE2AC	0x7B6E	#<CJK>
0xE2AD	0x7B9D	#<CJK>
0xE2AE	0x7B98	#<CJK>
0xE2AF	0x7B9F	#<CJK>
0xE2B0	0x7B8D	#<CJK>
0xE2B1	0x7B9C	#<CJK>
0xE2B2	0x7B9A	#<CJK>
0xE2B3	0x7B8B	#<CJK>
0xE2B4	0x7B92	#<CJK>
0xE2B5	0x7B8F	#<CJK>
0xE2B6	0x7B5D	#<CJK>
0xE2B7	0x7B99	#<CJK>
0xE2B8	0x7BCB	#<CJK>
0xE2B9	0x7BC1	#<CJK>
0xE2BA	0x7BCC	#<CJK>
0xE2BB	0x7BCF	#<CJK>
0xE2BC	0x7BB4	#<CJK>
0xE2BD	0x7BC6	#<CJK>
0xE2BE	0x7BDD	#<CJK>
0xE2BF	0x7BE9	#<CJK>
0xE2C0	0x7C11	#<CJK>
0xE2C1	0x7C14	#<CJK>
0xE2C2	0x7BE6	#<CJK>
0xE2C3	0x7BE5	#<CJK>
0xE2C4	0x7C60	#<CJK>
0xE2C5	0x7C00	#<CJK>
0xE2C6	0x7C07	#<CJK>
0xE2C7	0x7C13	#<CJK>
0xE2C8	0x7BF3	#<CJK>
0xE2C9	0x7BF7	#<CJK>
0xE2CA	0x7C17	#<CJK>
0xE2CB	0x7C0D	#<CJK>
0xE2CC	0x7BF6	#<CJK>
0xE2CD	0x7C23	#<CJK>
0xE2CE	0x7C27	#<CJK>
0xE2CF	0x7C2A	#<CJK>
0xE2D0	0x7C1F	#<CJK>
0xE2D1	0x7C37	#<CJK>
0xE2D2	0x7C2B	#<CJK>
0xE2D3	0x7C3D	#<CJK>
0xE2D4	0x7C4C	#<CJK>
0xE2D5	0x7C43	#<CJK>
0xE2D6	0x7C54	#<CJK>
0xE2D7	0x7C4F	#<CJK>
0xE2D8	0x7C40	#<CJK>
0xE2D9	0x7C50	#<CJK>
0xE2DA	0x7C58	#<CJK>
0xE2DB	0x7C5F	#<CJK>
0xE2DC	0x7C64	#<CJK>
0xE2DD	0x7C56	#<CJK>
0xE2DE	0x7C65	#<CJK>
0xE2DF	0x7C6C	#<CJK>
0xE2E0	0x7C75	#<CJK>
0xE2E1	0x7C83	#<CJK>
0xE2E2	0x7C90	#<CJK>
0xE2E3	0x7CA4	#<CJK>
0xE2E4	0x7CAD	#<CJK>
0xE2E5	0x7CA2	#<CJK>
0xE2E6	0x7CAB	#<CJK>
0xE2E7	0x7CA1	#<CJK>
0xE2E8	0x7CA8	#<CJK>
0xE2E9	0x7CB3	#<CJK>
0xE2EA	0x7CB2	#<CJK>
0xE2EB	0x7CB1	#<CJK>
0xE2EC	0x7CAE	#<CJK>
0xE2ED	0x7CB9	#<CJK>
0xE2EE	0x7CBD	#<CJK>
0xE2EF	0x7CC0	#<CJK>
0xE2F0	0x7CC5	#<CJK>
0xE2F1	0x7CC2	#<CJK>
0xE2F2	0x7CD8	#<CJK>
0xE2F3	0x7CD2	#<CJK>
0xE2F4	0x7CDC	#<CJK>
0xE2F5	0x7CE2	#<CJK>
0xE2F6	0x9B3B	#<CJK>
0xE2F7	0x7CEF	#<CJK>
0xE2F8	0x7CF2	#<CJK>
0xE2F9	0x7CF4	#<CJK>
0xE2FA	0x7CF6	#<CJK>
0xE2FB	0x7CFA	#<CJK>
0xE2FC	0x7D06	#<CJK>
0xE340	0x7D02	#<CJK>
0xE341	0x7D1C	#<CJK>
0xE342	0x7D15	#<CJK>
0xE343	0x7D0A	#<CJK>
0xE344	0x7D45	#<CJK>
0xE345	0x7D4B	#<CJK>
0xE346	0x7D2E	#<CJK>
0xE347	0x7D32	#<CJK>
0xE348	0x7D3F	#<CJK>
0xE349	0x7D35	#<CJK>
0xE34A	0x7D46	#<CJK>
0xE34B	0x7D73	#<CJK>
0xE34C	0x7D56	#<CJK>
0xE34D	0x7D4E	#<CJK>
0xE34E	0x7D72	#<CJK>
0xE34F	0x7D68	#<CJK>
0xE350	0x7D6E	#<CJK>
0xE351	0x7D4F	#<CJK>
0xE352	0x7D63	#<CJK>
0xE353	0x7D93	#<CJK>
0xE354	0x7D89	#<CJK>
0xE355	0x7D5B	#<CJK>
0xE356	0x7D8F	#<CJK>
0xE357	0x7D7D	#<CJK>
0xE358	0x7D9B	#<CJK>
0xE359	0x7DBA	#<CJK>
0xE35A	0x7DAE	#<CJK>
0xE35B	0x7DA3	#<CJK>
0xE35C	0x7DB5	#<CJK>
0xE35D	0x7DC7	#<CJK>
0xE35E	0x7DBD	#<CJK>
0xE35F	0x7DAB	#<CJK>
0xE360	0x7E3D	#<CJK>
0xE361	0x7DA2	#<CJK>
0xE362	0x7DAF	#<CJK>
0xE363	0x7DDC	#<CJK>
0xE364	0x7DB8	#<CJK>
0xE365	0x7D9F	#<CJK>
0xE366	0x7DB0	#<CJK>
0xE367	0x7DD8	#<CJK>
0xE368	0x7DDD	#<CJK>
0xE369	0x7DE4	#<CJK>
0xE36A	0x7DDE	#<CJK>
0xE36B	0x7DFB	#<CJK>
0xE36C	0x7DF2	#<CJK>
0xE36D	0x7DE1	#<CJK>
0xE36E	0x7E05	#<CJK>
0xE36F	0x7E0A	#<CJK>
0xE370	0x7E23	#<CJK>
0xE371	0x7E21	#<CJK>
0xE372	0x7E12	#<CJK>
0xE373	0x7E31	#<CJK>
0xE374	0x7E1F	#<CJK>
0xE375	0x7E09	#<CJK>
0xE376	0x7E0B	#<CJK>
0xE377	0x7E22	#<CJK>
0xE378	0x7E46	#<CJK>
0xE379	0x7E66	#<CJK>
0xE37A	0x7E3B	#<CJK>
0xE37B	0x7E35	#<CJK>
0xE37C	0x7E39	#<CJK>
0xE37D	0x7E43	#<CJK>
0xE37E	0x7E37	#<CJK>
0xE380	0x7E32	#<CJK>
0xE381	0x7E3A	#<CJK>
0xE382	0x7E67	#<CJK>
0xE383	0x7E5D	#<CJK>
0xE384	0x7E56	#<CJK>
0xE385	0x7E5E	#<CJK>
0xE386	0x7E59	#<CJK>
0xE387	0x7E5A	#<CJK>
0xE388	0x7E79	#<CJK>
0xE389	0x7E6A	#<CJK>
0xE38A	0x7E69	#<CJK>
0xE38B	0x7E7C	#<CJK>
0xE38C	0x7E7B	#<CJK>
0xE38D	0x7E83	#<CJK>
0xE38E	0x7DD5	#<CJK>
0xE38F	0x7E7D	#<CJK>
0xE390	0x8FAE	#<CJK>
0xE391	0x7E7F	#<CJK>
0xE392	0x7E88	#<CJK>
0xE393	0x7E89	#<CJK>
0xE394	0x7E8C	#<CJK>
0xE395	0x7E92	#<CJK>
0xE396	0x7E90	#<CJK>
0xE397	0x7E93	#<CJK>
0xE398	0x7E94	#<CJK>
0xE399	0x7E96	#<CJK>
0xE39A	0x7E8E	#<CJK>
0xE39B	0x7E9B	#<CJK>
0xE39C	0x7E9C	#<CJK>
0xE39D	0x7F38	#<CJK>
0xE39E	0x7F3A	#<CJK>
0xE39F	0x7F45	#<CJK>
0xE3A0	0x7F4C	#<CJK>
0xE3A1	0x7F4D	#<CJK>
0xE3A2	0x7F4E	#<CJK>
0xE3A3	0x7F50	#<CJK>
0xE3A4	0x7F51	#<CJK>
0xE3A5	0x7F55	#<CJK>
0xE3A6	0x7F54	#<CJK>
0xE3A7	0x7F58	#<CJK>
0xE3A8	0x7F5F	#<CJK>
0xE3A9	0x7F60	#<CJK>
0xE3AA	0x7F68	#<CJK>
0xE3AB	0x7F69	#<CJK>
0xE3AC	0x7F67	#<CJK>
0xE3AD	0x7F78	#<CJK>
0xE3AE	0x7F82	#<CJK>
0xE3AF	0x7F86	#<CJK>
0xE3B0	0x7F83	#<CJK>
0xE3B1	0x7F88	#<CJK>
0xE3B2	0x7F87	#<CJK>
0xE3B3	0x7F8C	#<CJK>
0xE3B4	0x7F94	#<CJK>
0xE3B5	0x7F9E	#<CJK>
0xE3B6	0x7F9D	#<CJK>
0xE3B7	0x7F9A	#<CJK>
0xE3B8	0x7FA3	#<CJK>
0xE3B9	0x7FAF	#<CJK>
0xE3BA	0x7FB2	#<CJK>
0xE3BB	0x7FB9	#<CJK>
0xE3BC	0x7FAE	#<CJK>
0xE3BD	0x7FB6	#<CJK>
0xE3BE	0x7FB8	#<CJK>
0xE3BF	0x8B71	#<CJK>
0xE3C0	0x7FC5	#<CJK>
0xE3C1	0x7FC6	#<CJK>
0xE3C2	0x7FCA	#<CJK>
0xE3C3	0x7FD5	#<CJK>
0xE3C4	0x7FD4	#<CJK>
0xE3C5	0x7FE1	#<CJK>
0xE3C6	0x7FE6	#<CJK>
0xE3C7	0x7FE9	#<CJK>
0xE3C8	0x7FF3	#<CJK>
0xE3C9	0x7FF9	#<CJK>
0xE3CA	0x98DC	#<CJK>
0xE3CB	0x8006	#<CJK>
0xE3CC	0x8004	#<CJK>
0xE3CD	0x800B	#<CJK>
0xE3CE	0x8012	#<CJK>
0xE3CF	0x8018	#<CJK>
0xE3D0	0x8019	#<CJK>
0xE3D1	0x801C	#<CJK>
0xE3D2	0x8021	#<CJK>
0xE3D3	0x8028	#<CJK>
0xE3D4	0x803F	#<CJK>
0xE3D5	0x803B	#<CJK>
0xE3D6	0x804A	#<CJK>
0xE3D7	0x8046	#<CJK>
0xE3D8	0x8052	#<CJK>
0xE3D9	0x8058	#<CJK>
0xE3DA	0x805A	#<CJK>
0xE3DB	0x805F	#<CJK>
0xE3DC	0x8062	#<CJK>
0xE3DD	0x8068	#<CJK>
0xE3DE	0x8073	#<CJK>
0xE3DF	0x8072	#<CJK>
0xE3E0	0x8070	#<CJK>
0xE3E1	0x8076	#<CJK>
0xE3E2	0x8079	#<CJK>
0xE3E3	0x807D	#<CJK>
0xE3E4	0x807F	#<CJK>
0xE3E5	0x8084	#<CJK>
0xE3E6	0x8086	#<CJK>
0xE3E7	0x8085	#<CJK>
0xE3E8	0x809B	#<CJK>
0xE3E9	0x8093	#<CJK>
0xE3EA	0x809A	#<CJK>
0xE3EB	0x80AD	#<CJK>
0xE3EC	0x5190	#<CJK>
0xE3ED	0x80AC	#<CJK>
0xE3EE	0x80DB	#<CJK>
0xE3EF	0x80E5	#<CJK>
0xE3F0	0x80D9	#<CJK>
0xE3F1	0x80DD	#<CJK>
0xE3F2	0x80C4	#<CJK>
0xE3F3	0x80DA	#<CJK>
0xE3F4	0x80D6	#<CJK>
0xE3F5	0x8109	#<CJK>
0xE3F6	0x80EF	#<CJK>
0xE3F7	0x80F1	#<CJK>
0xE3F8	0x811B	#<CJK>
0xE3F9	0x8129	#<CJK>
0xE3FA	0x8123	#<CJK>
0xE3FB	0x812F	#<CJK>
0xE3FC	0x814B	#<CJK>
0xE440	0x968B	#<CJK>
0xE441	0x8146	#<CJK>
0xE442	0x813E	#<CJK>
0xE443	0x8153	#<CJK>
0xE444	0x8151	#<CJK>
0xE445	0x80FC	#<CJK>
0xE446	0x8171	#<CJK>
0xE447	0x816E	#<CJK>
0xE448	0x8165	#<CJK>
0xE449	0x8166	#<CJK>
0xE44A	0x8174	#<CJK>
0xE44B	0x8183	#<CJK>
0xE44C	0x8188	#<CJK>
0xE44D	0x818A	#<CJK>
0xE44E	0x8180	#<CJK>
0xE44F	0x8182	#<CJK>
0xE450	0x81A0	#<CJK>
0xE451	0x8195	#<CJK>
0xE452	0x81A4	#<CJK>
0xE453	0x81A3	#<CJK>
0xE454	0x815F	#<CJK>
0xE455	0x8193	#<CJK>
0xE456	0x81A9	#<CJK>
0xE457	0x81B0	#<CJK>
0xE458	0x81B5	#<CJK>
0xE459	0x81BE	#<CJK>
0xE45A	0x81B8	#<CJK>
0xE45B	0x81BD	#<CJK>
0xE45C	0x81C0	#<CJK>
0xE45D	0x81C2	#<CJK>
0xE45E	0x81BA	#<CJK>
0xE45F	0x81C9	#<CJK>
0xE460	0x81CD	#<CJK>
0xE461	0x81D1	#<CJK>
0xE462	0x81D9	#<CJK>
0xE463	0x81D8	#<CJK>
0xE464	0x81C8	#<CJK>
0xE465	0x81DA	#<CJK>
0xE466	0x81DF	#<CJK>
0xE467	0x81E0	#<CJK>
0xE468	0x81E7	#<CJK>
0xE469	0x81FA	#<CJK>
0xE46A	0x81FB	#<CJK>
0xE46B	0x81FE	#<CJK>
0xE46C	0x8201	#<CJK>
0xE46D	0x8202	#<CJK>
0xE46E	0x8205	#<CJK>
0xE46F	0x8207	#<CJK>
0xE470	0x820A	#<CJK>
0xE471	0x820D	#<CJK>
0xE472	0x8210	#<CJK>
0xE473	0x8216	#<CJK>
0xE474	0x8229	#<CJK>
0xE475	0x822B	#<CJK>
0xE476	0x8238	#<CJK>
0xE477	0x8233	#<CJK>
0xE478	0x8240	#<CJK>
0xE479	0x8259	#<CJK>
0xE47A	0x8258	#<CJK>
0xE47B	0x825D	#<CJK>
0xE47C	0x825A	#<CJK>
0xE47D	0x825F	#<CJK>
0xE47E	0x8264	#<CJK>
0xE480	0x8262	#<CJK>
0xE481	0x8268	#<CJK>
0xE482	0x826A	#<CJK>
0xE483	0x826B	#<CJK>
0xE484	0x822E	#<CJK>
0xE485	0x8271	#<CJK>
0xE486	0x8277	#<CJK>
0xE487	0x8278	#<CJK>
0xE488	0x827E	#<CJK>
0xE489	0x828D	#<CJK>
0xE48A	0x8292	#<CJK>
0xE48B	0x82AB	#<CJK>
0xE48C	0x829F	#<CJK>
0xE48D	0x82BB	#<CJK>
0xE48E	0x82AC	#<CJK>
0xE48F	0x82E1	#<CJK>
0xE490	0x82E3	#<CJK>
0xE491	0x82DF	#<CJK>
0xE492	0x82D2	#<CJK>
0xE493	0x82F4	#<CJK>
0xE494	0x82F3	#<CJK>
0xE495	0x82FA	#<CJK>
0xE496	0x8393	#<CJK>
0xE497	0x8303	#<CJK>
0xE498	0x82FB	#<CJK>
0xE499	0x82F9	#<CJK>
0xE49A	0x82DE	#<CJK>
0xE49B	0x8306	#<CJK>
0xE49C	0x82DC	#<CJK>
0xE49D	0x8309	#<CJK>
0xE49E	0x82D9	#<CJK>
0xE49F	0x8335	#<CJK>
0xE4A0	0x8334	#<CJK>
0xE4A1	0x8316	#<CJK>
0xE4A2	0x8332	#<CJK>
0xE4A3	0x8331	#<CJK>
0xE4A4	0x8340	#<CJK>
0xE4A5	0x8339	#<CJK>
0xE4A6	0x8350	#<CJK>
0xE4A7	0x8345	#<CJK>
0xE4A8	0x832F	#<CJK>
0xE4A9	0x832B	#<CJK>
0xE4AA	0x8317	#<CJK>
0xE4AB	0x8318	#<CJK>
0xE4AC	0x8385	#<CJK>
0xE4AD	0x839A	#<CJK>
0xE4AE	0x83AA	#<CJK>
0xE4AF	0x839F	#<CJK>
0xE4B0	0x83A2	#<CJK>
0xE4B1	0x8396	#<CJK>
0xE4B2	0x8323	#<CJK>
0xE4B3	0x838E	#<CJK>
0xE4B4	0x8387	#<CJK>
0xE4B5	0x838A	#<CJK>
0xE4B6	0x837C	#<CJK>
0xE4B7	0x83B5	#<CJK>
0xE4B8	0x8373	#<CJK>
0xE4B9	0x8375	#<CJK>
0xE4BA	0x83A0	#<CJK>
0xE4BB	0x8389	#<CJK>
0xE4BC	0x83A8	#<CJK>
0xE4BD	0x83F4	#<CJK>
0xE4BE	0x8413	#<CJK>
0xE4BF	0x83EB	#<CJK>
0xE4C0	0x83CE	#<CJK>
0xE4C1	0x83FD	#<CJK>
0xE4C2	0x8403	#<CJK>
0xE4C3	0x83D8	#<CJK>
0xE4C4	0x840B	#<CJK>
0xE4C5	0x83C1	#<CJK>
0xE4C6	0x83F7	#<CJK>
0xE4C7	0x8407	#<CJK>
0xE4C8	0x83E0	#<CJK>
0xE4C9	0x83F2	#<CJK>
0xE4CA	0x840D	#<CJK>
0xE4CB	0x8422	#<CJK>
0xE4CC	0x8420	#<CJK>
0xE4CD	0x83BD	#<CJK>
0xE4CE	0x8438	#<CJK>
0xE4CF	0x8506	#<CJK>
0xE4D0	0x83FB	#<CJK>
0xE4D1	0x846D	#<CJK>
0xE4D2	0x842A	#<CJK>
0xE4D3	0x843C	#<CJK>
0xE4D4	0x855A	#<CJK>
0xE4D5	0x8484	#<CJK>
0xE4D6	0x8477	#<CJK>
0xE4D7	0x846B	#<CJK>
0xE4D8	0x84AD	#<CJK>
0xE4D9	0x846E	#<CJK>
0xE4DA	0x8482	#<CJK>
0xE4DB	0x8469	#<CJK>
0xE4DC	0x8446	#<CJK>
0xE4DD	0x842C	#<CJK>
0xE4DE	0x846F	#<CJK>
0xE4DF	0x8479	#<CJK>
0xE4E0	0x8435	#<CJK>
0xE4E1	0x84CA	#<CJK>
0xE4E2	0x8462	#<CJK>
0xE4E3	0x84B9	#<CJK>
0xE4E4	0x84BF	#<CJK>
0xE4E5	0x849F	#<CJK>
0xE4E6	0x84D9	#<CJK>
0xE4E7	0x84CD	#<CJK>
0xE4E8	0x84BB	#<CJK>
0xE4E9	0x84DA	#<CJK>
0xE4EA	0x84D0	#<CJK>
0xE4EB	0x84C1	#<CJK>
0xE4EC	0x84C6	#<CJK>
0xE4ED	0x84D6	#<CJK>
0xE4EE	0x84A1	#<CJK>
0xE4EF	0x8521	#<CJK>
0xE4F0	0x84FF	#<CJK>
0xE4F1	0x84F4	#<CJK>
0xE4F2	0x8517	#<CJK>
0xE4F3	0x8518	#<CJK>
0xE4F4	0x852C	#<CJK>
0xE4F5	0x851F	#<CJK>
0xE4F6	0x8515	#<CJK>
0xE4F7	0x8514	#<CJK>
0xE4F8	0x84FC	#<CJK>
0xE4F9	0x8540	#<CJK>
0xE4FA	0x8563	#<CJK>
0xE4FB	0x8558	#<CJK>
0xE4FC	0x8548	#<CJK>
0xE540	0x8541	#<CJK>
0xE541	0x8602	#<CJK>
0xE542	0x854B	#<CJK>
0xE543	0x8555	#<CJK>
0xE544	0x8580	#<CJK>
0xE545	0x85A4	#<CJK>
0xE546	0x8588	#<CJK>
0xE547	0x8591	#<CJK>
0xE548	0x858A	#<CJK>
0xE549	0x85A8	#<CJK>
0xE54A	0x856D	#<CJK>
0xE54B	0x8594	#<CJK>
0xE54C	0x859B	#<CJK>
0xE54D	0x85EA	#<CJK>
0xE54E	0x8587	#<CJK>
0xE54F	0x859C	#<CJK>
0xE550	0x8577	#<CJK>
0xE551	0x857E	#<CJK>
0xE552	0x8590	#<CJK>
0xE553	0x85C9	#<CJK>
0xE554	0x85BA	#<CJK>
0xE555	0x85CF	#<CJK>
0xE556	0x85B9	#<CJK>
0xE557	0x85D0	#<CJK>
0xE558	0x85D5	#<CJK>
0xE559	0x85DD	#<CJK>
0xE55A	0x85E5	#<CJK>
0xE55B	0x85DC	#<CJK>
0xE55C	0x85F9	#<CJK>
0xE55D	0x860A	#<CJK>
0xE55E	0x8613	#<CJK>
0xE55F	0x860B	#<CJK>
0xE560	0x85FE	#<CJK>
0xE561	0x85FA	#<CJK>
0xE562	0x8606	#<CJK>
0xE563	0x8622	#<CJK>
0xE564	0x861A	#<CJK>
0xE565	0x8630	#<CJK>
0xE566	0x863F	#<CJK>
0xE567	0x864D	#<CJK>
0xE568	0x4E55	#<CJK>
0xE569	0x8654	#<CJK>
0xE56A	0x865F	#<CJK>
0xE56B	0x8667	#<CJK>
0xE56C	0x8671	#<CJK>
0xE56D	0x8693	#<CJK>
0xE56E	0x86A3	#<CJK>
0xE56F	0x86A9	#<CJK>
0xE570	0x86AA	#<CJK>
0xE571	0x868B	#<CJK>
0xE572	0x868C	#<CJK>
0xE573	0x86B6	#<CJK>
0xE574	0x86AF	#<CJK>
0xE575	0x86C4	#<CJK>
0xE576	0x86C6	#<CJK>
0xE577	0x86B0	#<CJK>
0xE578	0x86C9	#<CJK>
0xE579	0x8823	#<CJK>
0xE57A	0x86AB	#<CJK>
0xE57B	0x86D4	#<CJK>
0xE57C	0x86DE	#<CJK>
0xE57D	0x86E9	#<CJK>
0xE57E	0x86EC	#<CJK>
0xE580	0x86DF	#<CJK>
0xE581	0x86DB	#<CJK>
0xE582	0x86EF	#<CJK>
0xE583	0x8712	#<CJK>
0xE584	0x8706	#<CJK>
0xE585	0x8708	#<CJK>
0xE586	0x8700	#<CJK>
0xE587	0x8703	#<CJK>
0xE588	0x86FB	#<CJK>
0xE589	0x8711	#<CJK>
0xE58A	0x8709	#<CJK>
0xE58B	0x870D	#<CJK>
0xE58C	0x86F9	#<CJK>
0xE58D	0x870A	#<CJK>
0xE58E	0x8734	#<CJK>
0xE58F	0x873F	#<CJK>
0xE590	0x8737	#<CJK>
0xE591	0x873B	#<CJK>
0xE592	0x8725	#<CJK>
0xE593	0x8729	#<CJK>
0xE594	0x871A	#<CJK>
0xE595	0x8760	#<CJK>
0xE596	0x875F	#<CJK>
0xE597	0x8778	#<CJK>
0xE598	0x874C	#<CJK>
0xE599	0x874E	#<CJK>
0xE59A	0x8774	#<CJK>
0xE59B	0x8757	#<CJK>
0xE59C	0x8768	#<CJK>
0xE59D	0x876E	#<CJK>
0xE59E	0x8759	#<CJK>
0xE59F	0x8753	#<CJK>
0xE5A0	0x8763	#<CJK>
0xE5A1	0x876A	#<CJK>
0xE5A2	0x8805	#<CJK>
0xE5A3	0x87A2	#<CJK>
0xE5A4	0x879F	#<CJK>
0xE5A5	0x8782	#<CJK>
0xE5A6	0x87AF	#<CJK>
0xE5A7	0x87CB	#<CJK>
0xE5A8	0x87BD	#<CJK>
0xE5A9	0x87C0	#<CJK>
0xE5AA	0x87D0	#<CJK>
0xE5AB	0x96D6	#<CJK>
0xE5AC	0x87AB	#<CJK>
0xE5AD	0x87C4	#<CJK>
0xE5AE	0x87B3	#<CJK>
0xE5AF	0x87C7	#<CJK>
0xE5B0	0x87C6	#<CJK>
0xE5B1	0x87BB	#<CJK>
0xE5B2	0x87EF	#<CJK>
0xE5B3	0x87F2	#<CJK>
0xE5B4	0x87E0	#<CJK>
0xE5B5	0x880F	#<CJK>
0xE5B6	0x880D	#<CJK>
0xE5B7	0x87FE	#<CJK>
0xE5B8	0x87F6	#<CJK>
0xE5B9	0x87F7	#<CJK>
0xE5BA	0x880E	#<CJK>
0xE5BB	0x87D2	#<CJK>
0xE5BC	0x8811	#<CJK>
0xE5BD	0x8816	#<CJK>
0xE5BE	0x8815	#<CJK>
0xE5BF	0x8822	#<CJK>
0xE5C0	0x8821	#<CJK>
0xE5C1	0x8831	#<CJK>
0xE5C2	0x8836	#<CJK>
0xE5C3	0x8839	#<CJK>
0xE5C4	0x8827	#<CJK>
0xE5C5	0x883B	#<CJK>
0xE5C6	0x8844	#<CJK>
0xE5C7	0x8842	#<CJK>
0xE5C8	0x8852	#<CJK>
0xE5C9	0x8859	#<CJK>
0xE5CA	0x885E	#<CJK>
0xE5CB	0x8862	#<CJK>
0xE5CC	0x886B	#<CJK>
0xE5CD	0x8881	#<CJK>
0xE5CE	0x887E	#<CJK>
0xE5CF	0x889E	#<CJK>
0xE5D0	0x8875	#<CJK>
0xE5D1	0x887D	#<CJK>
0xE5D2	0x88B5	#<CJK>
0xE5D3	0x8872	#<CJK>
0xE5D4	0x8882	#<CJK>
0xE5D5	0x8897	#<CJK>
0xE5D6	0x8892	#<CJK>
0xE5D7	0x88AE	#<CJK>
0xE5D8	0x8899	#<CJK>
0xE5D9	0x88A2	#<CJK>
0xE5DA	0x888D	#<CJK>
0xE5DB	0x88A4	#<CJK>
0xE5DC	0x88B0	#<CJK>
0xE5DD	0x88BF	#<CJK>
0xE5DE	0x88B1	#<CJK>
0xE5DF	0x88C3	#<CJK>
0xE5E0	0x88C4	#<CJK>
0xE5E1	0x88D4	#<CJK>
0xE5E2	0x88D8	#<CJK>
0xE5E3	0x88D9	#<CJK>
0xE5E4	0x88DD	#<CJK>
0xE5E5	0x88F9	#<CJK>
0xE5E6	0x8902	#<CJK>
0xE5E7	0x88FC	#<CJK>
0xE5E8	0x88F4	#<CJK>
0xE5E9	0x88E8	#<CJK>
0xE5EA	0x88F2	#<CJK>
0xE5EB	0x8904	#<CJK>
0xE5EC	0x890C	#<CJK>
0xE5ED	0x890A	#<CJK>
0xE5EE	0x8913	#<CJK>
0xE5EF	0x8943	#<CJK>
0xE5F0	0x891E	#<CJK>
0xE5F1	0x8925	#<CJK>
0xE5F2	0x892A	#<CJK>
0xE5F3	0x892B	#<CJK>
0xE5F4	0x8941	#<CJK>
0xE5F5	0x8944	#<CJK>
0xE5F6	0x893B	#<CJK>
0xE5F7	0x8936	#<CJK>
0xE5F8	0x8938	#<CJK>
0xE5F9	0x894C	#<CJK>
0xE5FA	0x891D	#<CJK>
0xE5FB	0x8960	#<CJK>
0xE5FC	0x895E	#<CJK>
0xE640	0x8966	#<CJK>
0xE641	0x8964	#<CJK>
0xE642	0x896D	#<CJK>
0xE643	0x896A	#<CJK>
0xE644	0x896F	#<CJK>
0xE645	0x8974	#<CJK>
0xE646	0x8977	#<CJK>
0xE647	0x897E	#<CJK>
0xE648	0x8983	#<CJK>
0xE649	0x8988	#<CJK>
0xE64A	0x898A	#<CJK>
0xE64B	0x8993	#<CJK>
0xE64C	0x8998	#<CJK>
0xE64D	0x89A1	#<CJK>
0xE64E	0x89A9	#<CJK>
0xE64F	0x89A6	#<CJK>
0xE650	0x89AC	#<CJK>
0xE651	0x89AF	#<CJK>
0xE652	0x89B2	#<CJK>
0xE653	0x89BA	#<CJK>
0xE654	0x89BD	#<CJK>
0xE655	0x89BF	#<CJK>
0xE656	0x89C0	#<CJK>
0xE657	0x89DA	#<CJK>
0xE658	0x89DC	#<CJK>
0xE659	0x89DD	#<CJK>
0xE65A	0x89E7	#<CJK>
0xE65B	0x89F4	#<CJK>
0xE65C	0x89F8	#<CJK>
0xE65D	0x8A03	#<CJK>
0xE65E	0x8A16	#<CJK>
0xE65F	0x8A10	#<CJK>
0xE660	0x8A0C	#<CJK>
0xE661	0x8A1B	#<CJK>
0xE662	0x8A1D	#<CJK>
0xE663	0x8A25	#<CJK>
0xE664	0x8A36	#<CJK>
0xE665	0x8A41	#<CJK>
0xE666	0x8A5B	#<CJK>
0xE667	0x8A52	#<CJK>
0xE668	0x8A46	#<CJK>
0xE669	0x8A48	#<CJK>
0xE66A	0x8A7C	#<CJK>
0xE66B	0x8A6D	#<CJK>
0xE66C	0x8A6C	#<CJK>
0xE66D	0x8A62	#<CJK>
0xE66E	0x8A85	#<CJK>
0xE66F	0x8A82	#<CJK>
0xE670	0x8A84	#<CJK>
0xE671	0x8AA8	#<CJK>
0xE672	0x8AA1	#<CJK>
0xE673	0x8A91	#<CJK>
0xE674	0x8AA5	#<CJK>
0xE675	0x8AA6	#<CJK>
0xE676	0x8A9A	#<CJK>
0xE677	0x8AA3	#<CJK>
0xE678	0x8AC4	#<CJK>
0xE679	0x8ACD	#<CJK>
0xE67A	0x8AC2	#<CJK>
0xE67B	0x8ADA	#<CJK>
0xE67C	0x8AEB	#<CJK>
0xE67D	0x8AF3	#<CJK>
0xE67E	0x8AE7	#<CJK>
0xE680	0x8AE4	#<CJK>
0xE681	0x8AF1	#<CJK>
0xE682	0x8B14	#<CJK>
0xE683	0x8AE0	#<CJK>
0xE684	0x8AE2	#<CJK>
0xE685	0x8AF7	#<CJK>
0xE686	0x8ADE	#<CJK>
0xE687	0x8ADB	#<CJK>
0xE688	0x8B0C	#<CJK>
0xE689	0x8B07	#<CJK>
0xE68A	0x8B1A	#<CJK>
0xE68B	0x8AE1	#<CJK>
0xE68C	0x8B16	#<CJK>
0xE68D	0x8B10	#<CJK>
0xE68E	0x8B17	#<CJK>
0xE68F	0x8B20	#<CJK>
0xE690	0x8B33	#<CJK>
0xE691	0x97AB	#<CJK>
0xE692	0x8B26	#<CJK>
0xE693	0x8B2B	#<CJK>
0xE694	0x8B3E	#<CJK>
0xE695	0x8B28	#<CJK>
0xE696	0x8B41	#<CJK>
0xE697	0x8B4C	#<CJK>
0xE698	0x8B4F	#<CJK>
0xE699	0x8B4E	#<CJK>
0xE69A	0x8B49	#<CJK>
0xE69B	0x8B56	#<CJK>
0xE69C	0x8B5B	#<CJK>
0xE69D	0x8B5A	#<CJK>
0xE69E	0x8B6B	#<CJK>
0xE69F	0x8B5F	#<CJK>
0xE6A0	0x8B6C	#<CJK>
0xE6A1	0x8B6F	#<CJK>
0xE6A2	0x8B74	#<CJK>
0xE6A3	0x8B7D	#<CJK>
0xE6A4	0x8B80	#<CJK>
0xE6A5	0x8B8C	#<CJK>
0xE6A6	0x8B8E	#<CJK>
0xE6A7	0x8B92	#<CJK>
0xE6A8	0x8B93	#<CJK>
0xE6A9	0x8B96	#<CJK>
0xE6AA	0x8B99	#<CJK>
0xE6AB	0x8B9A	#<CJK>
0xE6AC	0x8C3A	#<CJK>
0xE6AD	0x8C41	#<CJK>
0xE6AE	0x8C3F	#<CJK>
0xE6AF	0x8C48	#<CJK>
0xE6B0	0x8C4C	#<CJK>
0xE6B1	0x8C4E	#<CJK>
0xE6B2	0x8C50	#<CJK>
0xE6B3	0x8C55	#<CJK>
0xE6B4	0x8C62	#<CJK>
0xE6B5	0x8C6C	#<CJK>
0xE6B6	0x8C78	#<CJK>
0xE6B7	0x8C7A	#<CJK>
0xE6B8	0x8C82	#<CJK>
0xE6B9	0x8C89	#<CJK>
0xE6BA	0x8C85	#<CJK>
0xE6BB	0x8C8A	#<CJK>
0xE6BC	0x8C8D	#<CJK>
0xE6BD	0x8C8E	#<CJK>
0xE6BE	0x8C94	#<CJK>
0xE6BF	0x8C7C	#<CJK>
0xE6C0	0x8C98	#<CJK>
0xE6C1	0x621D	#<CJK>
0xE6C2	0x8CAD	#<CJK>
0xE6C3	0x8CAA	#<CJK>
0xE6C4	0x8CBD	#<CJK>
0xE6C5	0x8CB2	#<CJK>
0xE6C6	0x8CB3	#<CJK>
0xE6C7	0x8CAE	#<CJK>
0xE6C8	0x8CB6	#<CJK>
0xE6C9	0x8CC8	#<CJK>
0xE6CA	0x8CC1	#<CJK>
0xE6CB	0x8CE4	#<CJK>
0xE6CC	0x8CE3	#<CJK>
0xE6CD	0x8CDA	#<CJK>
0xE6CE	0x8CFD	#<CJK>
0xE6CF	0x8CFA	#<CJK>
0xE6D0	0x8CFB	#<CJK>
0xE6D1	0x8D04	#<CJK>
0xE6D2	0x8D05	#<CJK>
0xE6D3	0x8D0A	#<CJK>
0xE6D4	0x8D07	#<CJK>
0xE6D5	0x8D0F	#<CJK>
0xE6D6	0x8D0D	#<CJK>
0xE6D7	0x8D10	#<CJK>
0xE6D8	0x9F4E	#<CJK>
0xE6D9	0x8D13	#<CJK>
0xE6DA	0x8CCD	#<CJK>
0xE6DB	0x8D14	#<CJK>
0xE6DC	0x8D16	#<CJK>
0xE6DD	0x8D67	#<CJK>
0xE6DE	0x8D6D	#<CJK>
0xE6DF	0x8D71	#<CJK>
0xE6E0	0x8D73	#<CJK>
0xE6E1	0x8D81	#<CJK>
0xE6E2	0x8D99	#<CJK>
0xE6E3	0x8DC2	#<CJK>
0xE6E4	0x8DBE	#<CJK>
0xE6E5	0x8DBA	#<CJK>
0xE6E6	0x8DCF	#<CJK>
0xE6E7	0x8DDA	#<CJK>
0xE6E8	0x8DD6	#<CJK>
0xE6E9	0x8DCC	#<CJK>
0xE6EA	0x8DDB	#<CJK>
0xE6EB	0x8DCB	#<CJK>
0xE6EC	0x8DEA	#<CJK>
0xE6ED	0x8DEB	#<CJK>
0xE6EE	0x8DDF	#<CJK>
0xE6EF	0x8DE3	#<CJK>
0xE6F0	0x8DFC	#<CJK>
0xE6F1	0x8E08	#<CJK>
0xE6F2	0x8E09	#<CJK>
0xE6F3	0x8DFF	#<CJK>
0xE6F4	0x8E1D	#<CJK>
0xE6F5	0x8E1E	#<CJK>
0xE6F6	0x8E10	#<CJK>
0xE6F7	0x8E1F	#<CJK>
0xE6F8	0x8E42	#<CJK>
0xE6F9	0x8E35	#<CJK>
0xE6FA	0x8E30	#<CJK>
0xE6FB	0x8E34	#<CJK>
0xE6FC	0x8E4A	#<CJK>
0xE740	0x8E47	#<CJK>
0xE741	0x8E49	#<CJK>
0xE742	0x8E4C	#<CJK>
0xE743	0x8E50	#<CJK>
0xE744	0x8E48	#<CJK>
0xE745	0x8E59	#<CJK>
0xE746	0x8E64	#<CJK>
0xE747	0x8E60	#<CJK>
0xE748	0x8E2A	#<CJK>
0xE749	0x8E63	#<CJK>
0xE74A	0x8E55	#<CJK>
0xE74B	0x8E76	#<CJK>
0xE74C	0x8E72	#<CJK>
0xE74D	0x8E7C	#<CJK>
0xE74E	0x8E81	#<CJK>
0xE74F	0x8E87	#<CJK>
0xE750	0x8E85	#<CJK>
0xE751	0x8E84	#<CJK>
0xE752	0x8E8B	#<CJK>
0xE753	0x8E8A	#<CJK>
0xE754	0x8E93	#<CJK>
0xE755	0x8E91	#<CJK>
0xE756	0x8E94	#<CJK>
0xE757	0x8E99	#<CJK>
0xE758	0x8EAA	#<CJK>
0xE759	0x8EA1	#<CJK>
0xE75A	0x8EAC	#<CJK>
0xE75B	0x8EB0	#<CJK>
0xE75C	0x8EC6	#<CJK>
0xE75D	0x8EB1	#<CJK>
0xE75E	0x8EBE	#<CJK>
0xE75F	0x8EC5	#<CJK>
0xE760	0x8EC8	#<CJK>
0xE761	0x8ECB	#<CJK>
0xE762	0x8EDB	#<CJK>
0xE763	0x8EE3	#<CJK>
0xE764	0x8EFC	#<CJK>
0xE765	0x8EFB	#<CJK>
0xE766	0x8EEB	#<CJK>
0xE767	0x8EFE	#<CJK>
0xE768	0x8F0A	#<CJK>
0xE769	0x8F05	#<CJK>
0xE76A	0x8F15	#<CJK>
0xE76B	0x8F12	#<CJK>
0xE76C	0x8F19	#<CJK>
0xE76D	0x8F13	#<CJK>
0xE76E	0x8F1C	#<CJK>
0xE76F	0x8F1F	#<CJK>
0xE770	0x8F1B	#<CJK>
0xE771	0x8F0C	#<CJK>
0xE772	0x8F26	#<CJK>
0xE773	0x8F33	#<CJK>
0xE774	0x8F3B	#<CJK>
0xE775	0x8F39	#<CJK>
0xE776	0x8F45	#<CJK>
0xE777	0x8F42	#<CJK>
0xE778	0x8F3E	#<CJK>
0xE779	0x8F4C	#<CJK>
0xE77A	0x8F49	#<CJK>
0xE77B	0x8F46	#<CJK>
0xE77C	0x8F4E	#<CJK>
0xE77D	0x8F57	#<CJK>
0xE77E	0x8F5C	#<CJK>
0xE780	0x8F62	#<CJK>
0xE781	0x8F63	#<CJK>
0xE782	0x8F64	#<CJK>
0xE783	0x8F9C	#<CJK>
0xE784	0x8F9F	#<CJK>
0xE785	0x8FA3	#<CJK>
0xE786	0x8FAD	#<CJK>
0xE787	0x8FAF	#<CJK>
0xE788	0x8FB7	#<CJK>
0xE789	0x8FDA	#<CJK>
0xE78A	0x8FE5	#<CJK>
0xE78B	0x8FE2	#<CJK>
0xE78C	0x8FEA	#<CJK>
0xE78D	0x8FEF	#<CJK>
0xE78E	0x9087	#<CJK>
0xE78F	0x8FF4	#<CJK>
0xE790	0x9005	#<CJK>
0xE791	0x8FF9	#<CJK>
0xE792	0x8FFA	#<CJK>
0xE793	0x9011	#<CJK>
0xE794	0x9015	#<CJK>
0xE795	0x9021	#<CJK>
0xE796	0x900D	#<CJK>
0xE797	0x901E	#<CJK>
0xE798	0x9016	#<CJK>
0xE799	0x900B	#<CJK>
0xE79A	0x9027	#<CJK>
0xE79B	0x9036	#<CJK>
0xE79C	0x9035	#<CJK>
0xE79D	0x9039	#<CJK>
0xE79E	0x8FF8	#<CJK>
0xE79F	0x904F	#<CJK>
0xE7A0	0x9050	#<CJK>
0xE7A1	0x9051	#<CJK>
0xE7A2	0x9052	#<CJK>
0xE7A3	0x900E	#<CJK>
0xE7A4	0x9049	#<CJK>
0xE7A5	0x903E	#<CJK>
0xE7A6	0x9056	#<CJK>
0xE7A7	0x9058	#<CJK>
0xE7A8	0x905E	#<CJK>
0xE7A9	0x9068	#<CJK>
0xE7AA	0x906F	#<CJK>
0xE7AB	0x9076	#<CJK>
0xE7AC	0x96A8	#<CJK>
0xE7AD	0x9072	#<CJK>
0xE7AE	0x9082	#<CJK>
0xE7AF	0x907D	#<CJK>
0xE7B0	0x9081	#<CJK>
0xE7B1	0x9080	#<CJK>
0xE7B2	0x908A	#<CJK>
0xE7B3	0x9089	#<CJK>
0xE7B4	0x908F	#<CJK>
0xE7B5	0x90A8	#<CJK>
0xE7B6	0x90AF	#<CJK>
0xE7B7	0x90B1	#<CJK>
0xE7B8	0x90B5	#<CJK>
0xE7B9	0x90E2	#<CJK>
0xE7BA	0x90E4	#<CJK>
0xE7BB	0x6248	#<CJK>
0xE7BC	0x90DB	#<CJK>
0xE7BD	0x9102	#<CJK>
0xE7BE	0x9112	#<CJK>
0xE7BF	0x9119	#<CJK>
0xE7C0	0x9132	#<CJK>
0xE7C1	0x9130	#<CJK>
0xE7C2	0x914A	#<CJK>
0xE7C3	0x9156	#<CJK>
0xE7C4	0x9158	#<CJK>
0xE7C5	0x9163	#<CJK>
0xE7C6	0x9165	#<CJK>
0xE7C7	0x9169	#<CJK>
0xE7C8	0x9173	#<CJK>
0xE7C9	0x9172	#<CJK>
0xE7CA	0x918B	#<CJK>
0xE7CB	0x9189	#<CJK>
0xE7CC	0x9182	#<CJK>
0xE7CD	0x91A2	#<CJK>
0xE7CE	0x91AB	#<CJK>
0xE7CF	0x91AF	#<CJK>
0xE7D0	0x91AA	#<CJK>
0xE7D1	0x91B5	#<CJK>
0xE7D2	0x91B4	#<CJK>
0xE7D3	0x91BA	#<CJK>
0xE7D4	0x91C0	#<CJK>
0xE7D5	0x91C1	#<CJK>
0xE7D6	0x91C9	#<CJK>
0xE7D7	0x91CB	#<CJK>
0xE7D8	0x91D0	#<CJK>
0xE7D9	0x91D6	#<CJK>
0xE7DA	0x91DF	#<CJK>
0xE7DB	0x91E1	#<CJK>
0xE7DC	0x91DB	#<CJK>
0xE7DD	0x91FC	#<CJK>
0xE7DE	0x91F5	#<CJK>
0xE7DF	0x91F6	#<CJK>
0xE7E0	0x921E	#<CJK>
0xE7E1	0x91FF	#<CJK>
0xE7E2	0x9214	#<CJK>
0xE7E3	0x922C	#<CJK>
0xE7E4	0x9215	#<CJK>
0xE7E5	0x9211	#<CJK>
0xE7E6	0x925E	#<CJK>
0xE7E7	0x9257	#<CJK>
0xE7E8	0x9245	#<CJK>
0xE7E9	0x9249	#<CJK>
0xE7EA	0x9264	#<CJK>
0xE7EB	0x9248	#<CJK>
0xE7EC	0x9295	#<CJK>
0xE7ED	0x923F	#<CJK>
0xE7EE	0x924B	#<CJK>
0xE7EF	0x9250	#<CJK>
0xE7F0	0x929C	#<CJK>
0xE7F1	0x9296	#<CJK>
0xE7F2	0x9293	#<CJK>
0xE7F3	0x929B	#<CJK>
0xE7F4	0x925A	#<CJK>
0xE7F5	0x92CF	#<CJK>
0xE7F6	0x92B9	#<CJK>
0xE7F7	0x92B7	#<CJK>
0xE7F8	0x92E9	#<CJK>
0xE7F9	0x930F	#<CJK>
0xE7FA	0x92FA	#<CJK>
0xE7FB	0x9344	#<CJK>
0xE7FC	0x932E	#<CJK>
0xE840	0x9319	#<CJK>
0xE841	0x9322	#<CJK>
0xE842	0x931A	#<CJK>
0xE843	0x9323	#<CJK>
0xE844	0x933A	#<CJK>
0xE845	0x9335	#<CJK>
0xE846	0x933B	#<CJK>
0xE847	0x935C	#<CJK>
0xE848	0x9360	#<CJK>
0xE849	0x937C	#<CJK>
0xE84A	0x936E	#<CJK>
0xE84B	0x9356	#<CJK>
0xE84C	0x93B0	#<CJK>
0xE84D	0x93AC	#<CJK>
0xE84E	0x93AD	#<CJK>
0xE84F	0x9394	#<CJK>
0xE850	0x93B9	#<CJK>
0xE851	0x93D6	#<CJK>
0xE852	0x93D7	#<CJK>
0xE853	0x93E8	#<CJK>
0xE854	0x93E5	#<CJK>
0xE855	0x93D8	#<CJK>
0xE856	0x93C3	#<CJK>
0xE857	0x93DD	#<CJK>
0xE858	0x93D0	#<CJK>
0xE859	0x93C8	#<CJK>
0xE85A	0x93E4	#<CJK>
0xE85B	0x941A	#<CJK>
0xE85C	0x9414	#<CJK>
0xE85D	0x9413	#<CJK>
0xE85E	0x9403	#<CJK>
0xE85F	0x9407	#<CJK>
0xE860	0x9410	#<CJK>
0xE861	0x9436	#<CJK>
0xE862	0x942B	#<CJK>
0xE863	0x9435	#<CJK>
0xE864	0x9421	#<CJK>
0xE865	0x943A	#<CJK>
0xE866	0x9441	#<CJK>
0xE867	0x9452	#<CJK>
0xE868	0x9444	#<CJK>
0xE869	0x945B	#<CJK>
0xE86A	0x9460	#<CJK>
0xE86B	0x9462	#<CJK>
0xE86C	0x945E	#<CJK>
0xE86D	0x946A	#<CJK>
0xE86E	0x9229	#<CJK>
0xE86F	0x9470	#<CJK>
0xE870	0x9475	#<CJK>
0xE871	0x9477	#<CJK>
0xE872	0x947D	#<CJK>
0xE873	0x945A	#<CJK>
0xE874	0x947C	#<CJK>
0xE875	0x947E	#<CJK>
0xE876	0x9481	#<CJK>
0xE877	0x947F	#<CJK>
0xE878	0x9582	#<CJK>
0xE879	0x9587	#<CJK>
0xE87A	0x958A	#<CJK>
0xE87B	0x9594	#<CJK>
0xE87C	0x9596	#<CJK>
0xE87D	0x9598	#<CJK>
0xE87E	0x9599	#<CJK>
0xE880	0x95A0	#<CJK>
0xE881	0x95A8	#<CJK>
0xE882	0x95A7	#<CJK>
0xE883	0x95AD	#<CJK>
0xE884	0x95BC	#<CJK>
0xE885	0x95BB	#<CJK>
0xE886	0x95B9	#<CJK>
0xE887	0x95BE	#<CJK>
0xE888	0x95CA	#<CJK>
0xE889	0x6FF6	#<CJK>
0xE88A	0x95C3	#<CJK>
0xE88B	0x95CD	#<CJK>
0xE88C	0x95CC	#<CJK>
0xE88D	0x95D5	#<CJK>
0xE88E	0x95D4	#<CJK>
0xE88F	0x95D6	#<CJK>
0xE890	0x95DC	#<CJK>
0xE891	0x95E1	#<CJK>
0xE892	0x95E5	#<CJK>
0xE893	0x95E2	#<CJK>
0xE894	0x9621	#<CJK>
0xE895	0x9628	#<CJK>
0xE896	0x962E	#<CJK>
0xE897	0x962F	#<CJK>
0xE898	0x9642	#<CJK>
0xE899	0x964C	#<CJK>
0xE89A	0x964F	#<CJK>
0xE89B	0x964B	#<CJK>
0xE89C	0x9677	#<CJK>
0xE89D	0x965C	#<CJK>
0xE89E	0x965E	#<CJK>
0xE89F	0x965D	#<CJK>
0xE8A0	0x965F	#<CJK>
0xE8A1	0x9666	#<CJK>
0xE8A2	0x9672	#<CJK>
0xE8A3	0x966C	#<CJK>
0xE8A4	0x968D	#<CJK>
0xE8A5	0x9698	#<CJK>
0xE8A6	0x9695	#<CJK>
0xE8A7	0x9697	#<CJK>
0xE8A8	0x96AA	#<CJK>
0xE8A9	0x96A7	#<CJK>
0xE8AA	0x96B1	#<CJK>
0xE8AB	0x96B2	#<CJK>
0xE8AC	0x96B0	#<CJK>
0xE8AD	0x96B4	#<CJK>
0xE8AE	0x96B6	#<CJK>
0xE8AF	0x96B8	#<CJK>
0xE8B0	0x96B9	#<CJK>
0xE8B1	0x96CE	#<CJK>
0xE8B2	0x96CB	#<CJK>
0xE8B3	0x96C9	#<CJK>
0xE8B4	0x96CD	#<CJK>
0xE8B5	0x894D	#<CJK>
0xE8B6	0x96DC	#<CJK>
0xE8B7	0x970D	#<CJK>
0xE8B8	0x96D5	#<CJK>
0xE8B9	0x96F9	#<CJK>
0xE8BA	0x9704	#<CJK>
0xE8BB	0x9706	#<CJK>
0xE8BC	0x9708	#<CJK>
0xE8BD	0x9713	#<CJK>
0xE8BE	0x970E	#<CJK>
0xE8BF	0x9711	#<CJK>
0xE8C0	0x970F	#<CJK>
0xE8C1	0x9716	#<CJK>
0xE8C2	0x9719	#<CJK>
0xE8C3	0x9724	#<CJK>
0xE8C4	0x972A	#<CJK>
0xE8C5	0x9730	#<CJK>
0xE8C6	0x9739	#<CJK>
0xE8C7	0x973D	#<CJK>
0xE8C8	0x973E	#<CJK>
0xE8C9	0x9744	#<CJK>
0xE8CA	0x9746	#<CJK>
0xE8CB	0x9748	#<CJK>
0xE8CC	0x9742	#<CJK>
0xE8CD	0x9749	#<CJK>
0xE8CE	0x975C	#<CJK>
0xE8CF	0x9760	#<CJK>
0xE8D0	0x9764	#<CJK>
0xE8D1	0x9766	#<CJK>
0xE8D2	0x9768	#<CJK>
0xE8D3	0x52D2	#<CJK>
0xE8D4	0x976B	#<CJK>
0xE8D5	0x9771	#<CJK>
0xE8D6	0x9779	#<CJK>
0xE8D7	0x9785	#<CJK>
0xE8D8	0x977C	#<CJK>
0xE8D9	0x9781	#<CJK>
0xE8DA	0x977A	#<CJK>
0xE8DB	0x9786	#<CJK>
0xE8DC	0x978B	#<CJK>
0xE8DD	0x978F	#<CJK>
0xE8DE	0x9790	#<CJK>
0xE8DF	0x979C	#<CJK>
0xE8E0	0x97A8	#<CJK>
0xE8E1	0x97A6	#<CJK>
0xE8E2	0x97A3	#<CJK>
0xE8E3	0x97B3	#<CJK>
0xE8E4	0x97B4	#<CJK>
0xE8E5	0x97C3	#<CJK>
0xE8E6	0x97C6	#<CJK>
0xE8E7	0x97C8	#<CJK>
0xE8E8	0x97CB	#<CJK>
0xE8E9	0x97DC	#<CJK>
0xE8EA	0x97ED	#<CJK>
0xE8EB	0x9F4F	#<CJK>
0xE8EC	0x97F2	#<CJK>
0xE8ED	0x7ADF	#<CJK>
0xE8EE	0x97F6	#<CJK>
0xE8EF	0x97F5	#<CJK>
0xE8F0	0x980F	#<CJK>
0xE8F1	0x980C	#<CJK>
0xE8F2	0x9838	#<CJK>
0xE8F3	0x9824	#<CJK>
0xE8F4	0x9821	#<CJK>
0xE8F5	0x9837	#<CJK>
0xE8F6	0x983D	#<CJK>
0xE8F7	0x9846	#<CJK>
0xE8F8	0x984F	#<CJK>
0xE8F9	0x984B	#<CJK>
0xE8FA	0x986B	#<CJK>
0xE8FB	0x986F	#<CJK>
0xE8FC	0x9870	#<CJK>
0xE940	0x9871	#<CJK>
0xE941	0x9874	#<CJK>
0xE942	0x9873	#<CJK>
0xE943	0x98AA	#<CJK>
0xE944	0x98AF	#<CJK>
0xE945	0x98B1	#<CJK>
0xE946	0x98B6	#<CJK>
0xE947	0x98C4	#<CJK>
0xE948	0x98C3	#<CJK>
0xE949	0x98C6	#<CJK>
0xE94A	0x98E9	#<CJK>
0xE94B	0x98EB	#<CJK>
0xE94C	0x9903	#<CJK>
0xE94D	0x9909	#<CJK>
0xE94E	0x9912	#<CJK>
0xE94F	0x9914	#<CJK>
0xE950	0x9918	#<CJK>
0xE951	0x9921	#<CJK>
0xE952	0x991D	#<CJK>
0xE953	0x991E	#<CJK>
0xE954	0x9924	#<CJK>
0xE955	0x9920	#<CJK>
0xE956	0x992C	#<CJK>
0xE957	0x992E	#<CJK>
0xE958	0x993D	#<CJK>
0xE959	0x993E	#<CJK>
0xE95A	0x9942	#<CJK>
0xE95B	0x9949	#<CJK>
0xE95C	0x9945	#<CJK>
0xE95D	0x9950	#<CJK>
0xE95E	0x994B	#<CJK>
0xE95F	0x9951	#<CJK>
0xE960	0x9952	#<CJK>
0xE961	0x994C	#<CJK>
0xE962	0x9955	#<CJK>
0xE963	0x9997	#<CJK>
0xE964	0x9998	#<CJK>
0xE965	0x99A5	#<CJK>
0xE966	0x99AD	#<CJK>
0xE967	0x99AE	#<CJK>
0xE968	0x99BC	#<CJK>
0xE969	0x99DF	#<CJK>
0xE96A	0x99DB	#<CJK>
0xE96B	0x99DD	#<CJK>
0xE96C	0x99D8	#<CJK>
0xE96D	0x99D1	#<CJK>
0xE96E	0x99ED	#<CJK>
0xE96F	0x99EE	#<CJK>
0xE970	0x99F1	#<CJK>
0xE971	0x99F2	#<CJK>
0xE972	0x99FB	#<CJK>
0xE973	0x99F8	#<CJK>
0xE974	0x9A01	#<CJK>
0xE975	0x9A0F	#<CJK>
0xE976	0x9A05	#<CJK>
0xE977	0x99E2	#<CJK>
0xE978	0x9A19	#<CJK>
0xE979	0x9A2B	#<CJK>
0xE97A	0x9A37	#<CJK>
0xE97B	0x9A45	#<CJK>
0xE97C	0x9A42	#<CJK>
0xE97D	0x9A40	#<CJK>
0xE97E	0x9A43	#<CJK>
0xE980	0x9A3E	#<CJK>
0xE981	0x9A55	#<CJK>
0xE982	0x9A4D	#<CJK>
0xE983	0x9A5B	#<CJK>
0xE984	0x9A57	#<CJK>
0xE985	0x9A5F	#<CJK>
0xE986	0x9A62	#<CJK>
0xE987	0x9A65	#<CJK>
0xE988	0x9A64	#<CJK>
0xE989	0x9A69	#<CJK>
0xE98A	0x9A6B	#<CJK>
0xE98B	0x9A6A	#<CJK>
0xE98C	0x9AAD	#<CJK>
0xE98D	0x9AB0	#<CJK>
0xE98E	0x9ABC	#<CJK>
0xE98F	0x9AC0	#<CJK>
0xE990	0x9ACF	#<CJK>
0xE991	0x9AD1	#<CJK>
0xE992	0x9AD3	#<CJK>
0xE993	0x9AD4	#<CJK>
0xE994	0x9ADE	#<CJK>
0xE995	0x9ADF	#<CJK>
0xE996	0x9AE2	#<CJK>
0xE997	0x9AE3	#<CJK>
0xE998	0x9AE6	#<CJK>
0xE999	0x9AEF	#<CJK>
0xE99A	0x9AEB	#<CJK>
0xE99B	0x9AEE	#<CJK>
0xE99C	0x9AF4	#<CJK>
0xE99D	0x9AF1	#<CJK>
0xE99E	0x9AF7	#<CJK>
0xE99F	0x9AFB	#<CJK>
0xE9A0	0x9B06	#<CJK>
0xE9A1	0x9B18	#<CJK>
0xE9A2	0x9B1A	#<CJK>
0xE9A3	0x9B1F	#<CJK>
0xE9A4	0x9B22	#<CJK>
0xE9A5	0x9B23	#<CJK>
0xE9A6	0x9B25	#<CJK>
0xE9A7	0x9B27	#<CJK>
0xE9A8	0x9B28	#<CJK>
0xE9A9	0x9B29	#<CJK>
0xE9AA	0x9B2A	#<CJK>
0xE9AB	0x9B2E	#<CJK>
0xE9AC	0x9B2F	#<CJK>
0xE9AD	0x9B32	#<CJK>
0xE9AE	0x9B44	#<CJK>
0xE9AF	0x9B43	#<CJK>
0xE9B0	0x9B4F	#<CJK>
0xE9B1	0x9B4D	#<CJK>
0xE9B2	0x9B4E	#<CJK>
0xE9B3	0x9B51	#<CJK>
0xE9B4	0x9B58	#<CJK>
0xE9B5	0x9B74	#<CJK>
0xE9B6	0x9B93	#<CJK>
0xE9B7	0x9B83	#<CJK>
0xE9B8	0x9B91	#<CJK>
0xE9B9	0x9B96	#<CJK>
0xE9BA	0x9B97	#<CJK>
0xE9BB	0x9B9F	#<CJK>
0xE9BC	0x9BA0	#<CJK>
0xE9BD	0x9BA8	#<CJK>
0xE9BE	0x9BB4	#<CJK>
0xE9BF	0x9BC0	#<CJK>
0xE9C0	0x9BCA	#<CJK>
0xE9C1	0x9BB9	#<CJK>
0xE9C2	0x9BC6	#<CJK>
0xE9C3	0x9BCF	#<CJK>
0xE9C4	0x9BD1	#<CJK>
0xE9C5	0x9BD2	#<CJK>
0xE9C6	0x9BE3	#<CJK>
0xE9C7	0x9BE2	#<CJK>
0xE9C8	0x9BE4	#<CJK>
0xE9C9	0x9BD4	#<CJK>
0xE9CA	0x9BE1	#<CJK>
0xE9CB	0x9C3A	#<CJK>
0xE9CC	0x9BF2	#<CJK>
0xE9CD	0x9BF1	#<CJK>
0xE9CE	0x9BF0	#<CJK>
0xE9CF	0x9C15	#<CJK>
0xE9D0	0x9C14	#<CJK>
0xE9D1	0x9C09	#<CJK>
0xE9D2	0x9C13	#<CJK>
0xE9D3	0x9C0C	#<CJK>
0xE9D4	0x9C06	#<CJK>
0xE9D5	0x9C08	#<CJK>
0xE9D6	0x9C12	#<CJK>
0xE9D7	0x9C0A	#<CJK>
0xE9D8	0x9C04	#<CJK>
0xE9D9	0x9C2E	#<CJK>
0xE9DA	0x9C1B	#<CJK>
0xE9DB	0x9C25	#<CJK>
0xE9DC	0x9C24	#<CJK>
0xE9DD	0x9C21	#<CJK>
0xE9DE	0x9C30	#<CJK>
0xE9DF	0x9C47	#<CJK>
0xE9E0	0x9C32	#<CJK>
0xE9E1	0x9C46	#<CJK>
0xE9E2	0x9C3E	#<CJK>
0xE9E3	0x9C5A	#<CJK>
0xE9E4	0x9C60	#<CJK>
0xE9E5	0x9C67	#<CJK>
0xE9E6	0x9C76	#<CJK>
0xE9E7	0x9C78	#<CJK>
0xE9E8	0x9CE7	#<CJK>
0xE9E9	0x9CEC	#<CJK>
0xE9EA	0x9CF0	#<CJK>
0xE9EB	0x9D09	#<CJK>
0xE9EC	0x9D08	#<CJK>
0xE9ED	0x9CEB	#<CJK>
0xE9EE	0x9D03	#<CJK>
0xE9EF	0x9D06	#<CJK>
0xE9F0	0x9D2A	#<CJK>
0xE9F1	0x9D26	#<CJK>
0xE9F2	0x9DAF	#<CJK>
0xE9F3	0x9D23	#<CJK>
0xE9F4	0x9D1F	#<CJK>
0xE9F5	0x9D44	#<CJK>
0xE9F6	0x9D15	#<CJK>
0xE9F7	0x9D12	#<CJK>
0xE9F8	0x9D41	#<CJK>
0xE9F9	0x9D3F	#<CJK>
0xE9FA	0x9D3E	#<CJK>
0xE9FB	0x9D46	#<CJK>
0xE9FC	0x9D48	#<CJK>
0xEA40	0x9D5D	#<CJK>
0xEA41	0x9D5E	#<CJK>
0xEA42	0x9D64	#<CJK>
0xEA43	0x9D51	#<CJK>
0xEA44	0x9D50	#<CJK>
0xEA45	0x9D59	#<CJK>
0xEA46	0x9D72	#<CJK>
0xEA47	0x9D89	#<CJK>
0xEA48	0x9D87	#<CJK>
0xEA49	0x9DAB	#<CJK>
0xEA4A	0x9D6F	#<CJK>
0xEA4B	0x9D7A	#<CJK>
0xEA4C	0x9D9A	#<CJK>
0xEA4D	0x9DA4	#<CJK>
0xEA4E	0x9DA9	#<CJK>
0xEA4F	0x9DB2	#<CJK>
0xEA50	0x9DC4	#<CJK>
0xEA51	0x9DC1	#<CJK>
0xEA52	0x9DBB	#<CJK>
0xEA53	0x9DB8	#<CJK>
0xEA54	0x9DBA	#<CJK>
0xEA55	0x9DC6	#<CJK>
0xEA56	0x9DCF	#<CJK>
0xEA57	0x9DC2	#<CJK>
0xEA58	0x9DD9	#<CJK>
0xEA59	0x9DD3	#<CJK>
0xEA5A	0x9DF8	#<CJK>
0xEA5B	0x9DE6	#<CJK>
0xEA5C	0x9DED	#<CJK>
0xEA5D	0x9DEF	#<CJK>
0xEA5E	0x9DFD	#<CJK>
0xEA5F	0x9E1A	#<CJK>
0xEA60	0x9E1B	#<CJK>
0xEA61	0x9E1E	#<CJK>
0xEA62	0x9E75	#<CJK>
0xEA63	0x9E79	#<CJK>
0xEA64	0x9E7D	#<CJK>
0xEA65	0x9E81	#<CJK>
0xEA66	0x9E88	#<CJK>
0xEA67	0x9E8B	#<CJK>
0xEA68	0x9E8C	#<CJK>
0xEA69	0x9E92	#<CJK>
0xEA6A	0x9E95	#<CJK>
0xEA6B	0x9E91	#<CJK>
0xEA6C	0x9E9D	#<CJK>
0xEA6D	0x9EA5	#<CJK>
0xEA6E	0x9EA9	#<CJK>
0xEA6F	0x9EB8	#<CJK>
0xEA70	0x9EAA	#<CJK>
0xEA71	0x9EAD	#<CJK>
0xEA72	0x9761	#<CJK>
0xEA73	0x9ECC	#<CJK>
0xEA74	0x9ECE	#<CJK>
0xEA75	0x9ECF	#<CJK>
0xEA76	0x9ED0	#<CJK>
0xEA77	0x9ED4	#<CJK>
0xEA78	0x9EDC	#<CJK>
0xEA79	0x9EDE	#<CJK>
0xEA7A	0x9EDD	#<CJK>
0xEA7B	0x9EE0	#<CJK>
0xEA7C	0x9EE5	#<CJK>
0xEA7D	0x9EE8	#<CJK>
0xEA7E	0x9EEF	#<CJK>
0xEA80	0x9EF4	#<CJK>
0xEA81	0x9EF6	#<CJK>
0xEA82	0x9EF7	#<CJK>
0xEA83	0x9EF9	#<CJK>
0xEA84	0x9EFB	#<CJK>
0xEA85	0x9EFC	#<CJK>
0xEA86	0x9EFD	#<CJK>
0xEA87	0x9F07	#<CJK>
0xEA88	0x9F08	#<CJK>
0xEA89	0x76B7	#<CJK>
0xEA8A	0x9F15	#<CJK>
0xEA8B	0x9F21	#<CJK>
0xEA8C	0x9F2C	#<CJK>
0xEA8D	0x9F3E	#<CJK>
0xEA8E	0x9F4A	#<CJK>
0xEA8F	0x9F52	#<CJK>
0xEA90	0x9F54	#<CJK>
0xEA91	0x9F63	#<CJK>
0xEA92	0x9F5F	#<CJK>
0xEA93	0x9F60	#<CJK>
0xEA94	0x9F61	#<CJK>
0xEA95	0x9F66	#<CJK>
0xEA96	0x9F67	#<CJK>
0xEA97	0x9F6C	#<CJK>
0xEA98	0x9F6A	#<CJK>
0xEA99	0x9F77	#<CJK>
0xEA9A	0x9F72	#<CJK>
0xEA9B	0x9F76	#<CJK>
0xEA9C	0x9F95	#<CJK>
0xEA9D	0x9F9C	#<CJK>
0xEA9E	0x9FA0	#<CJK>
0xEA9F	0x582F	#<CJK>
0xEAA0	0x69C7	#<CJK>
0xEAA1	0x9059	#<CJK>
0xEAA2	0x7464	#<CJK>
0xEAA3	0x51DC	#<CJK>
0xEAA4	0x7199	#<CJK>
0xED40	0x7E8A	#<CJK>
0xED41	0x891C	#<CJK>
0xED42	0x9348	#<CJK>
0xED43	0x9288	#<CJK>
0xED44	0x84DC	#<CJK>
0xED45	0x4FC9	#<CJK>
0xED46	0x70BB	#<CJK>
0xED47	0x6631	#<CJK>
0xED48	0x68C8	#<CJK>
0xED49	0x92F9	#<CJK>
0xED4A	0x66FB	#<CJK>
0xED4B	0x5F45	#<CJK>
0xED4C	0x4E28	#<CJK>
0xED4D	0x4EE1	#<CJK>
0xED4E	0x4EFC	#<CJK>
0xED4F	0x4F00	#<CJK>
0xED50	0x4F03	#<CJK>
0xED51	0x4F39	#<CJK>
0xED52	0x4F56	#<CJK>
0xED53	0x4F92	#<CJK>
0xED54	0x4F8A	#<CJK>
0xED55	0x4F9A	#<CJK>
0xED56	0x4F94	#<CJK>
0xED57	0x4FCD	#<CJK>
0xED58	0x5040	#<CJK>
0xED59	0x5022	#<CJK>
0xED5A	0x4FFF	#<CJK>
0xED5B	0x501E	#<CJK>
0xED5C	0x5046	#<CJK>
0xED5D	0x5070	#<CJK>
0xED5E	0x5042	#<CJK>
0xED5F	0x5094	#<CJK>
0xED60	0x50F4	#<CJK>
0xED61	0x50D8	#<CJK>
0xED62	0x514A	#<CJK>
0xED63	0x5164	#<CJK>
0xED64	0x519D	#<CJK>
0xED65	0x51BE	#<CJK>
0xED66	0x51EC	#<CJK>
0xED67	0x5215	#<CJK>
0xED68	0x529C	#<CJK>
0xED69	0x52A6	#<CJK>
0xED6A	0x52C0	#<CJK>
0xED6B	0x52DB	#<CJK>
0xED6C	0x5300	#<CJK>
0xED6D	0x5307	#<CJK>
0xED6E	0x5324	#<CJK>
0xED6F	0x5372	#<CJK>
0xED70	0x5393	#<CJK>
0xED71	0x53B2	#<CJK>
0xED72	0x53DD	#<CJK>
0xED73	0xFA0E	#<CJK>
0xED74	0x549C	#<CJK>
0xED75	0x548A	#<CJK>
0xED76	0x54A9	#<CJK>
0xED77	0x54FF	#<CJK>
0xED78	0x5586	#<CJK>
0xED79	0x5759	#<CJK>
0xED7A	0x5765	#<CJK>
0xED7B	0x57AC	#<CJK>
0xED7C	0x57C8	#<CJK>
0xED7D	0x57C7	#<CJK>
0xED7E	0xFA0F	#<CJK>
0xED80	0xFA10	#<CJK>
0xED81	0x589E	#<CJK>
0xED82	0x58B2	#<CJK>
0xED83	0x590B	#<CJK>
0xED84	0x5953	#<CJK>
0xED85	0x595B	#<CJK>
0xED86	0x595D	#<CJK>
0xED87	0x5963	#<CJK>
0xED88	0x59A4	#<CJK>
0xED89	0x59BA	#<CJK>
0xED8A	0x5B56	#<CJK>
0xED8B	0x5BC0	#<CJK>
0xED8C	0x752F	#<CJK>
0xED8D	0x5BD8	#<CJK>
0xED8E	0x5BEC	#<CJK>
0xED8F	0x5C1E	#<CJK>
0xED90	0x5CA6	#<CJK>
0xED91	0x5CBA	#<CJK>
0xED92	0x5CF5	#<CJK>
0xED93	0x5D27	#<CJK>
0xED94	0x5D53	#<CJK>
0xED95	0xFA11	#<CJK>
0xED96	0x5D42	#<CJK>
0xED97	0x5D6D	#<CJK>
0xED98	0x5DB8	#<CJK>
0xED99	0x5DB9	#<CJK>
0xED9A	0x5DD0	#<CJK>
0xED9B	0x5F21	#<CJK>
0xED9C	0x5F34	#<CJK>
0xED9D	0x5F67	#<CJK>
0xED9E	0x5FB7	#<CJK>
0xED9F	0x5FDE	#<CJK>
0xEDA0	0x605D	#<CJK>
0xEDA1	0x6085	#<CJK>
0xEDA2	0x608A	#<CJK>
0xEDA3	0x60DE	#<CJK>
0xEDA4	0x60D5	#<CJK>
0xEDA5	0x6120	#<CJK>
0xEDA6	0x60F2	#<CJK>
0xEDA7	0x6111	#<CJK>
0xEDA8	0x6137	#<CJK>
0xEDA9	0x6130	#<CJK>
0xEDAA	0x6198	#<CJK>
0xEDAB	0x6213	#<CJK>
0xEDAC	0x62A6	#<CJK>
0xEDAD	0x63F5	#<CJK>
0xEDAE	0x6460	#<CJK>
0xEDAF	0x649D	#<CJK>
0xEDB0	0x64CE	#<CJK>
0xEDB1	0x654E	#<CJK>
0xEDB2	0x6600	#<CJK>
0xEDB3	0x6615	#<CJK>
0xEDB4	0x663B	#<CJK>
0xEDB5	0x6609	#<CJK>
0xEDB6	0x662E	#<CJK>
0xEDB7	0x661E	#<CJK>
0xEDB8	0x6624	#<CJK>
0xEDB9	0x6665	#<CJK>
0xEDBA	0x6657	#<CJK>
0xEDBB	0x6659	#<CJK>
0xEDBC	0xFA12	#<CJK>
0xEDBD	0x6673	#<CJK>
0xEDBE	0x6699	#<CJK>
0xEDBF	0x66A0	#<CJK>
0xEDC0	0x66B2	#<CJK>
0xEDC1	0x66BF	#<CJK>
0xEDC2	0x66FA	#<CJK>
0xEDC3	0x670E	#<CJK>
0xEDC4	0xF929	#<CJK>
0xEDC5	0x6766	#<CJK>
0xEDC6	0x67BB	#<CJK>
0xEDC7	0x6852	#<CJK>
0xEDC8	0x67C0	#<CJK>
0xEDC9	0x6801	#<CJK>
0xEDCA	0x6844	#<CJK>
0xEDCB	0x68CF	#<CJK>
0xEDCC	0xFA13	#<CJK>
0xEDCD	0x6968	#<CJK>
0xEDCE	0xFA14	#<CJK>
0xEDCF	0x6998	#<CJK>
0xEDD0	0x69E2	#<CJK>
0xEDD1	0x6A30	#<CJK>
0xEDD2	0x6A6B	#<CJK>
0xEDD3	0x6A46	#<CJK>
0xEDD4	0x6A73	#<CJK>
0xEDD5	0x6A7E	#<CJK>
0xEDD6	0x6AE2	#<CJK>
0xEDD7	0x6AE4	#<CJK>
0xEDD8	0x6BD6	#<CJK>
0xEDD9	0x6C3F	#<CJK>
0xEDDA	0x6C5C	#<CJK>
0xEDDB	0x6C86	#<CJK>
0xEDDC	0x6C6F	#<CJK>
0xEDDD	0x6CDA	#<CJK>
0xEDDE	0x6D04	#<CJK>
0xEDDF	0x6D87	#<CJK>
0xEDE0	0x6D6F	#<CJK>
0xEDE1	0x6D96	#<CJK>
0xEDE2	0x6DAC	#<CJK>
0xEDE3	0x6DCF	#<CJK>
0xEDE4	0x6DF8	#<CJK>
0xEDE5	0x6DF2	#<CJK>
0xEDE6	0x6DFC	#<CJK>
0xEDE7	0x6E39	#<CJK>
0xEDE8	0x6E5C	#<CJK>
0xEDE9	0x6E27	#<CJK>
0xEDEA	0x6E3C	#<CJK>
0xEDEB	0x6EBF	#<CJK>
0xEDEC	0x6F88	#<CJK>
0xEDED	0x6FB5	#<CJK>
0xEDEE	0x6FF5	#<CJK>
0xEDEF	0x7005	#<CJK>
0xEDF0	0x7007	#<CJK>
0xEDF1	0x7028	#<CJK>
0xEDF2	0x7085	#<CJK>
0xEDF3	0x70AB	#<CJK>
0xEDF4	0x710F	#<CJK>
0xEDF5	0x7104	#<CJK>
0xEDF6	0x715C	#<CJK>
0xEDF7	0x7146	#<CJK>
0xEDF8	0x7147	#<CJK>
0xEDF9	0xFA15	#<CJK>
0xEDFA	0x71C1	#<CJK>
0xEDFB	0x71FE	#<CJK>
0xEDFC	0x72B1	#<CJK>
0xEE40	0x72BE	#<CJK>
0xEE41	0x7324	#<CJK>
0xEE42	0xFA16	#<CJK>
0xEE43	0x7377	#<CJK>
0xEE44	0x73BD	#<CJK>
0xEE45	0x73C9	#<CJK>
0xEE46	0x73D6	#<CJK>
0xEE47	0x73E3	#<CJK>
0xEE48	0x73D2	#<CJK>
0xEE49	0x7407	#<CJK>
0xEE4A	0x73F5	#<CJK>
0xEE4B	0x7426	#<CJK>
0xEE4C	0x742A	#<CJK>
0xEE4D	0x7429	#<CJK>
0xEE4E	0x742E	#<CJK>
0xEE4F	0x7462	#<CJK>
0xEE50	0x7489	#<CJK>
0xEE51	0x749F	#<CJK>
0xEE52	0x7501	#<CJK>
0xEE53	0x756F	#<CJK>
0xEE54	0x7682	#<CJK>
0xEE55	0x769C	#<CJK>
0xEE56	0x769E	#<CJK>
0xEE57	0x769B	#<CJK>
0xEE58	0x76A6	#<CJK>
0xEE59	0xFA17	#<CJK>
0xEE5A	0x7746	#<CJK>
0xEE5B	0x52AF	#<CJK>
0xEE5C	0x7821	#<CJK>
0xEE5D	0x784E	#<CJK>
0xEE5E	0x7864	#<CJK>
0xEE5F	0x787A	#<CJK>
0xEE60	0x7930	#<CJK>
0xEE61	0xFA18	#<CJK>
0xEE62	0xFA19	#<CJK>
0xEE63	0xFA1A	#<CJK>
0xEE64	0x7994	#<CJK>
0xEE65	0xFA1B	#<CJK>
0xEE66	0x799B	#<CJK>
0xEE67	0x7AD1	#<CJK>
0xEE68	0x7AE7	#<CJK>
0xEE69	0xFA1C	#<CJK>
0xEE6A	0x7AEB	#<CJK>
0xEE6B	0x7B9E	#<CJK>
0xEE6C	0xFA1D	#<CJK>
0xEE6D	0x7D48	#<CJK>
0xEE6E	0x7D5C	#<CJK>
0xEE6F	0x7DB7	#<CJK>
0xEE70	0x7DA0	#<CJK>
0xEE71	0x7DD6	#<CJK>
0xEE72	0x7E52	#<CJK>
0xEE73	0x7F47	#<CJK>
0xEE74	0x7FA1	#<CJK>
0xEE75	0xFA1E	#<CJK>
0xEE76	0x8301	#<CJK>
0xEE77	0x8362	#<CJK>
0xEE78	0x837F	#<CJK>
0xEE79	0x83C7	#<CJK>
0xEE7A	0x83F6	#<CJK>
0xEE7B	0x8448	#<CJK>
0xEE7C	0x84B4	#<CJK>
0xEE7D	0x8553	#<CJK>
0xEE7E	0x8559	#<CJK>
0xEE80	0x856B	#<CJK>
0xEE81	0xFA1F	#<CJK>
0xEE82	0x85B0	#<CJK>
0xEE83	0xFA20	#<CJK>
0xEE84	0xFA21	#<CJK>
0xEE85	0x8807	#<CJK>
0xEE86	0x88F5	#<CJK>
0xEE87	0x8A12	#<CJK>
0xEE88	0x8A37	#<CJK>
0xEE89	0x8A79	#<CJK>
0xEE8A	0x8AA7	#<CJK>
0xEE8B	0x8ABE	#<CJK>
0xEE8C	0x8ADF	#<CJK>
0xEE8D	0xFA22	#<CJK>
0xEE8E	0x8AF6	#<CJK>
0xEE8F	0x8B53	#<CJK>
0xEE90	0x8B7F	#<CJK>
0xEE91	0x8CF0	#<CJK>
0xEE92	0x8CF4	#<CJK>
0xEE93	0x8D12	#<CJK>
0xEE94	0x8D76	#<CJK>
0xEE95	0xFA23	#<CJK>
0xEE96	0x8ECF	#<CJK>
0xEE97	0xFA24	#<CJK>
0xEE98	0xFA25	#<CJK>
0xEE99	0x9067	#<CJK>
0xEE9A	0x90DE	#<CJK>
0xEE9B	0xFA26	#<CJK>
0xEE9C	0x9115	#<CJK>
0xEE9D	0x9127	#<CJK>
0xEE9E	0x91DA	#<CJK>
0xEE9F	0x91D7	#<CJK>
0xEEA0	0x91DE	#<CJK>
0xEEA1	0x91ED	#<CJK>
0xEEA2	0x91EE	#<CJK>
0xEEA3	0x91E4	#<CJK>
0xEEA4	0x91E5	#<CJK>
0xEEA5	0x9206	#<CJK>
0xEEA6	0x9210	#<CJK>
0xEEA7	0x920A	#<CJK>
0xEEA8	0x923A	#<CJK>
0xEEA9	0x9240	#<CJK>
0xEEAA	0x923C	#<CJK>
0xEEAB	0x924E	#<CJK>
0xEEAC	0x9259	#<CJK>
0xEEAD	0x9251	#<CJK>
0xEEAE	0x9239	#<CJK>
0xEEAF	0x9267	#<CJK>
0xEEB0	0x92A7	#<CJK>
0xEEB1	0x9277	#<CJK>
0xEEB2	0x9278	#<CJK>
0xEEB3	0x92E7	#<CJK>
0xEEB4	0x92D7	#<CJK>
0xEEB5	0x92D9	#<CJK>
0xEEB6	0x92D0	#<CJK>
0xEEB7	0xFA27	#<CJK>
0xEEB8	0x92D5	#<CJK>
0xEEB9	0x92E0	#<CJK>
0xEEBA	0x92D3	#<CJK>
0xEEBB	0x9325	#<CJK>
0xEEBC	0x9321	#<CJK>
0xEEBD	0x92FB	#<CJK>
0xEEBE	0xFA28	#<CJK>
0xEEBF	0x931E	#<CJK>
0xEEC0	0x92FF	#<CJK>
0xEEC1	0x931D	#<CJK>
0xEEC2	0x9302	#<CJK>
0xEEC3	0x9370	#<CJK>
0xEEC4	0x9357	#<CJK>
0xEEC5	0x93A4	#<CJK>
0xEEC6	0x93C6	#<CJK>
0xEEC7	0x93DE	#<CJK>
0xEEC8	0x93F8	#<CJK>
0xEEC9	0x9431	#<CJK>
0xEECA	0x9445	#<CJK>
0xEECB	0x9448	#<CJK>
0xEECC	0x9592	#<CJK>
0xEECD	0xF9DC	#<CJK>
0xEECE	0xFA29	#<CJK>
0xEECF	0x969D	#<CJK>
0xEED0	0x96AF	#<CJK>
0xEED1	0x9733	#<CJK>
0xEED2	0x973B	#<CJK>
0xEED3	0x9743	#<CJK>
0xEED4	0x974D	#<CJK>
0xEED5	0x974F	#<CJK>
0xEED6	0x9751	#<CJK>
0xEED7	0x9755	#<CJK>
0xEED8	0x9857	#<CJK>
0xEED9	0x9865	#<CJK>
0xEEDA	0xFA2A	#<CJK>
0xEEDB	0xFA2B	#<CJK>
0xEEDC	0x9927	#<CJK>
0xEEDD	0xFA2C	#<CJK>
0xEEDE	0x999E	#<CJK>
0xEEDF	0x9A4E	#<CJK>
0xEEE0	0x9AD9	#<CJK>
0xEEE1	0x9ADC	#<CJK>
0xEEE2	0x9B75	#<CJK>
0xEEE3	0x9B72	#<CJK>
0xEEE4	0x9B8F	#<CJK>
0xEEE5	0x9BB1	#<CJK>
0xEEE6	0x9BBB	#<CJK>
0xEEE7	0x9C00	#<CJK>
0xEEE8	0x9D70	#<CJK>
0xEEE9	0x9D6B	#<CJK>
0xEEEA	0xFA2D	#<CJK>
0xEEEB	0x9E19	#<CJK>
0xEEEC	0x9ED1	#<CJK>
0xEEEF	0x2170	#SMALL ROMAN NUMERAL ONE
0xEEF0	0x2171	#SMALL ROMAN NUMERAL TWO
0xEEF1	0x2172	#SMALL ROMAN NUMERAL THREE
0xEEF2	0x2173	#SMALL ROMAN NUMERAL FOUR
0xEEF3	0x2174	#SMALL ROMAN NUMERAL FIVE
0xEEF4	0x2175	#SMALL ROMAN NUMERAL SIX
0xEEF5	0x2176	#SMALL ROMAN NUMERAL SEVEN
0xEEF6	0x2177	#SMALL ROMAN NUMERAL EIGHT
0xEEF7	0x2178	#SMALL ROMAN NUMERAL NINE
0xEEF8	0x2179	#SMALL ROMAN NUMERAL TEN
0xEEF9	0xFFE2	#FULLWIDTH NOT SIGN
0xEEFA	0xFFE4	#FULLWIDTH BROKEN BAR
0xEEFB	0xFF07	#FULLWIDTH APOSTROPHE
0xEEFC	0xFF02	#FULLWIDTH QUOTATION MARK
0xFA40	0x2170	#SMALL ROMAN NUMERAL ONE
0xFA41	0x2171	#SMALL ROMAN NUMERAL TWO
0xFA42	0x2172	#SMALL ROMAN NUMERAL THREE
0xFA43	0x2173	#SMALL ROMAN NUMERAL FOUR
0xFA44	0x2174	#SMALL ROMAN NUMERAL FIVE
0xFA45	0x2175	#SMALL ROMAN NUMERAL SIX
0xFA46	0x2176	#SMALL ROMAN NUMERAL SEVEN
0xFA47	0x2177	#SMALL ROMAN NUMERAL EIGHT
0xFA48	0x2178	#SMALL ROMAN NUMERAL NINE
0xFA49	0x2179	#SMALL ROMAN NUMERAL TEN
0xFA4A	0x2160	#ROMAN NUMERAL ONE
0xFA4B	0x2161	#ROMAN NUMERAL TWO
0xFA4C	0x2162	#ROMAN NUMERAL THREE
0xFA4D	0x2163	#ROMAN NUMERAL FOUR
0xFA4E	0x2164	#ROMAN NUMERAL FIVE
0xFA4F	0x2165	#ROMAN NUMERAL SIX
0xFA50	0x2166	#ROMAN NUMERAL SEVEN
0xFA51	0x2167	#ROMAN NUMERAL EIGHT
0xFA52	0x2168	#ROMAN NUMERAL NINE
0xFA53	0x2169	#ROMAN NUMERAL TEN
0xFA54	0xFFE2	#FULLWIDTH NOT SIGN
0xFA55	0xFFE4	#FULLWIDTH BROKEN BAR
0xFA56	0xFF07	#FULLWIDTH APOSTROPHE
0xFA57	0xFF02	#FULLWIDTH QUOTATION MARK
0xFA58	0x3231	#PARENTHESIZED IDEOGRAPH STOCK
0xFA59	0x2116	#NUMERO SIGN
0xFA5A	0x2121	#TELEPHONE SIGN
0xFA5B	0x2235	#BECAUSE
0xFA5C	0x7E8A	#<CJK>
0xFA5D	0x891C	#<CJK>
0xFA5E	0x9348	#<CJK>
0xFA5F	0x9288	#<CJK>
0xFA60	0x84DC	#<CJK>
0xFA61	0x4FC9	#<CJK>
0xFA62	0x70BB	#<CJK>
0xFA63	0x6631	#<CJK>
0xFA64	0x68C8	#<CJK>
0xFA65	0x92F9	#<CJK>
0xFA66	0x66FB	#<CJK>
0xFA67	0x5F45	#<CJK>
0xFA68	0x4E28	#<CJK>
0xFA69	0x4EE1	#<CJK>
0xFA6A	0x4EFC	#<CJK>
0xFA6B	0x4F00	#<CJK>
0xFA6C	0x4F03	#<CJK>
0xFA6D	0x4F39	#<CJK>
0xFA6E	0x4F56	#<CJK>
0xFA6F	0x4F92	#<CJK>
0xFA70	0x4F8A	#<CJK>
0xFA71	0x4F9A	#<CJK>
0xFA72	0x4F94	#<CJK>
0xFA73	0x4FCD	#<CJK>
0xFA74	0x5040	#<CJK>
0xFA75	0x5022	#<CJK>
0xFA76	0x4FFF	#<CJK>
0xFA77	0x501E	#<CJK>
0xFA78	0x5046	#<CJK>
0xFA79	0x5070	#<CJK>
0xFA7A	0x5042	#<CJK>
0xFA7B	0x5094	#<CJK>
0xFA7C	0x50F4	#<CJK>
0xFA7D	0x50D8	#<CJK>
0xFA7E	0x514A	#<CJK>
0xFA80	0x5164	#<CJK>
0xFA81	0x519D	#<CJK>
0xFA82	0x51BE	#<CJK>
0xFA83	0x51EC	#<CJK>
0xFA84	0x5215	#<CJK>
0xFA85	0x529C	#<CJK>
0xFA86	0x52A6	#<CJK>
0xFA87	0x52C0	#<CJK>
0xFA88	0x52DB	#<CJK>
0xFA89	0x5300	#<CJK>
0xFA8A	0x5307	#<CJK>
0xFA8B	0x5324	#<CJK>
0xFA8C	0x5372	#<CJK>
0xFA8D	0x5393	#<CJK>
0xFA8E	0x53B2	#<CJK>
0xFA8F	0x53DD	#<CJK>
0xFA90	0xFA0E	#<CJK>
0xFA91	0x549C	#<CJK>
0xFA92	0x548A	#<CJK>
0xFA93	0x54A9	#<CJK>
0xFA94	0x54FF	#<CJK>
0xFA95	0x5586	#<CJK>
0xFA96	0x5759	#<CJK>
0xFA97	0x5765	#<CJK>
0xFA98	0x57AC	#<CJK>
0xFA99	0x57C8	#<CJK>
0xFA9A	0x57C7	#<CJK>
0xFA9B	0xFA0F	#<CJK>
0xFA9C	0xFA10	#<CJK>
0xFA9D	0x589E	#<CJK>
0xFA9E	0x58B2	#<CJK>
0xFA9F	0x590B	#<CJK>
0xFAA0	0x5953	#<CJK>
0xFAA1	0x595B	#<CJK>
0xFAA2	0x595D	#<CJK>
0xFAA3	0x5963	#<CJK>
0xFAA4	0x59A4	#<CJK>
0xFAA5	0x59BA	#<CJK>
0xFAA6	0x5B56	#<CJK>
0xFAA7	0x5BC0	#<CJK>
0xFAA8	0x752F	#<CJK>
0xFAA9	0x5BD8	#<CJK>
0xFAAA	0x5BEC	#<CJK>
0xFAAB	0x5C1E	#<CJK>
0xFAAC	0x5CA6	#<CJK>
0xFAAD	0x5CBA	#<CJK>
0xFAAE	0x5CF5	#<CJK>
0xFAAF	0x5D27	#<CJK>
0xFAB0	0x5D53	#<CJK>
0xFAB1	0xFA11	#<CJK>
0xFAB2	0x5D42	#<CJK>
0xFAB3	0x5D6D	#<CJK>
0xFAB4	0x5DB8	#<CJK>
0xFAB5	0x5DB9	#<CJK>
0xFAB6	0x5DD0	#<CJK>
0xFAB7	0x5F21	#<CJK>
0xFAB8	0x5F34	#<CJK>
0xFAB9	0x5F67	#<CJK>
0xFABA	0x5FB7	#<CJK>
0xFABB	0x5FDE	#<CJK>
0xFABC	0x605D	#<CJK>
0xFABD	0x6085	#<CJK>
0xFABE	0x608A	#<CJK>
0xFABF	0x60DE	#<CJK>
0xFAC0	0x60D5	#<CJK>
0xFAC1	0x6120	#<CJK>
0xFAC2	0x60F2	#<CJK>
0xFAC3	0x6111	#<CJK>
0xFAC4	0x6137	#<CJK>
0xFAC5	0x6130	#<CJK>
0xFAC6	0x6198	#<CJK>
0xFAC7	0x6213	#<CJK>
0xFAC8	0x62A6	#<CJK>
0xFAC9	0x63F5	#<CJK>
0xFACA	0x6460	#<CJK>
0xFACB	0x649D	#<CJK>
0xFACC	0x64CE	#<CJK>
0xFACD	0x654E	#<CJK>
0xFACE	0x6600	#<CJK>
0xFACF	0x6615	#<CJK>
0xFAD0	0x663B	#<CJK>
0xFAD1	0x6609	#<CJK>
0xFAD2	0x662E	#<CJK>
0xFAD3	0x661E	#<CJK>
0xFAD4	0x6624	#<CJK>
0xFAD5	0x6665	#<CJK>
0xFAD6	0x6657	#<CJK>
0xFAD7	0x6659	#<CJK>
0xFAD8	0xFA12	#<CJK>
0xFAD9	0x6673	#<CJK>
0xFADA	0x6699	#<CJK>
0xFADB	0x66A0	#<CJK>
0xFADC	0x66B2	#<CJK>
0xFADD	0x66BF	#<CJK>
0xFADE	0x66FA	#<CJK>
0xFADF	0x670E	#<CJK>
0xFAE0	0xF929	#<CJK>
0xFAE1	0x6766	#<CJK>
0xFAE2	0x67BB	#<CJK>
0xFAE3	0x6852	#<CJK>
0xFAE4	0x67C0	#<CJK>
0xFAE5	0x6801	#<CJK>
0xFAE6	0x6844	#<CJK>
0xFAE7	0x68CF	#<CJK>
0xFAE8	0xFA13	#<CJK>
0xFAE9	0x6968	#<CJK>
0xFAEA	0xFA14	#<CJK>
0xFAEB	0x6998	#<CJK>
0xFAEC	0x69E2	#<CJK>
0xFAED	0x6A30	#<CJK>
0xFAEE	0x6A6B	#<CJK>
0xFAEF	0x6A46	#<CJK>
0xFAF0	0x6A73	#<CJK>
0xFAF1	0x6A7E	#<CJK>
0xFAF2	0x6AE2	#<CJK>
0xFAF3	0x6AE4	#<CJK>
0xFAF4	0x6BD6	#<CJK>
0xFAF5	0x6C3F	#<CJK>
0xFAF6	0x6C5C	#<CJK>
0xFAF7	0x6C86	#<CJK>
0xFAF8	0x6C6F	#<CJK>
0xFAF9	0x6CDA	#<CJK>
0xFAFA	0x6D04	#<CJK>
0xFAFB	0x6D87	#<CJK>
0xFAFC	0x6D6F	#<CJK>
0xFB40	0x6D96	#<CJK>
0xFB41	0x6DAC	#<CJK>
0xFB42	0x6DCF	#<CJK>
0xFB43	0x6DF8	#<CJK>
0xFB44	0x6DF2	#<CJK>
0xFB45	0x6DFC	#<CJK>
0xFB46	0x6E39	#<CJK>
0xFB47	0x6E5C	#<CJK>
0xFB48	0x6E27	#<CJK>
0xFB49	0x6E3C	#<CJK>
0xFB4A	0x6EBF	#<CJK>
0xFB4B	0x6F88	#<CJK>
0xFB4C	0x6FB5	#<CJK>
0xFB4D	0x6FF5	#<CJK>
0xFB4E	0x7005	#<CJK>
0xFB4F	0x7007	#<CJK>
0xFB50	0x7028	#<CJK>
0xFB51	0x7085	#<CJK>
0xFB52	0x70AB	#<CJK>
0xFB53	0x710F	#<CJK>
0xFB54	0x7104	#<CJK>
0xFB55	0x715C	#<CJK>
0xFB56	0x7146	#<CJK>
0xFB57	0x7147	#<CJK>
0xFB58	0xFA15	#<CJK>
0xFB59	0x71C1	#<CJK>
0xFB5A	0x71FE	#<CJK>
0xFB5B	0x72B1	#<CJK>
0xFB5C	0x72BE	#<CJK>
0xFB5D	0x7324	#<CJK>
0xFB5E	0xFA16	#<CJK>
0xFB5F	0x7377	#<CJK>
0xFB60	0x73BD	#<CJK>
0xFB61	0x73C9	#<CJK>
0xFB62	0x73D6	#<CJK>
0xFB63	0x73E3	#<CJK>
0xFB64	0x73D2	#<CJK>
0xFB65	0x7407	#<CJK>
0xFB66	0x73F5	#<CJK>
0xFB67	0x7426	#<CJK>
0xFB68	0x742A	#<CJK>
0xFB69	0x7429	#<CJK>
0xFB6A	0x742E	#<CJK>
0xFB6B	0x7462	#<CJK>
0xFB6C	0x7489	#<CJK>
0xFB6D	0x749F	#<CJK>
0xFB6E	0x7501	#<CJK>
0xFB6F	0x756F	#<CJK>
0xFB70	0x7682	#<CJK>
0xFB71	0x769C	#<CJK>
0xFB72	0x769E	#<CJK>
0xFB73	0x769B	#<CJK>
0xFB74	0x76A6	#<CJK>
0xFB75	0xFA17	#<CJK>
0xFB76	0x7746	#<CJK>
0xFB77	0x52AF	#<CJK>
0xFB78	0x7821	#<CJK>
0xFB79	0x784E	#<CJK>
0xFB7A	0x7864	#<CJK>
0xFB7B	0x787A	#<CJK>
0xFB7C	0x7930	#<CJK>
0xFB7D	0xFA18	#<CJK>
0xFB7E	0xFA19	#<CJK>
0xFB80	0xFA1A	#<CJK>
0xFB81	0x7994	#<CJK>
0xFB82	0xFA1B	#<CJK>
0xFB83	0x799B	#<CJK>
0xFB84	0x7AD1	#<CJK>
0xFB85	0x7AE7	#<CJK>
0xFB86	0xFA1C	#<CJK>
0xFB87	0x7AEB	#<CJK>
0xFB88	0x7B9E	#<CJK>
0xFB89	0xFA1D	#<CJK>
0xFB8A	0x7D48	#<CJK>
0xFB8B	0x7D5C	#<CJK>
0xFB8C	0x7DB7	#<CJK>
0xFB8D	0x7DA0	#<CJK>
0xFB8E	0x7DD6	#<CJK>
0xFB8F	0x7E52	#<CJK>
0xFB90	0x7F47	#<CJK>
0xFB91	0x7FA1	#<CJK>
0xFB92	0xFA1E	#<CJK>
0xFB93	0x8301	#<CJK>
0xFB94	0x8362	#<CJK>
0xFB95	0x837F	#<CJK>
0xFB96	0x83C7	#<CJK>
0xFB97	0x83F6	#<CJK>
0xFB98	0x8448	#<CJK>
0xFB99	0x84B4	#<CJK>
0xFB9A	0x8553	#<CJK>
0xFB9B	0x8559	#<CJK>
0xFB9C	0x856B	#<CJK>
0xFB9D	0xFA1F	#<CJK>
0xFB9E	0x85B0	#<CJK>
0xFB9F	0xFA20	#<CJK>
0xFBA0	0xFA21	#<CJK>
0xFBA1	0x8807	#<CJK>
0xFBA2	0x88F5	#<CJK>
0xFBA3	0x8A12	#<CJK>
0xFBA4	0x8A37	#<CJK>
0xFBA5	0x8A79	#<CJK>
0xFBA6	0x8AA7	#<CJK>
0xFBA7	0x8ABE	#<CJK>
0xFBA8	0x8ADF	#<CJK>
0xFBA9	0xFA22	#<CJK>
0xFBAA	0x8AF6	#<CJK>
0xFBAB	0x8B53	#<CJK>
0xFBAC	0x8B7F	#<CJK>
0xFBAD	0x8CF0	#<CJK>
0xFBAE	0x8CF4	#<CJK>
0xFBAF	0x8D12	#<CJK>
0xFBB0	0x8D76	#<CJK>
0xFBB1	0xFA23	#<CJK>
0xFBB2	0x8ECF	#<CJK>
0xFBB3	0xFA24	#<CJK>
0xFBB4	0xFA25	#<CJK>
0xFBB5	0x9067	#<CJK>
0xFBB6	0x90DE	#<CJK>
0xFBB7	0xFA26	#<CJK>
0xFBB8	0x9115	#<CJK>
0xFBB9	0x9127	#<CJK>
0xFBBA	0x91DA	#<CJK>
0xFBBB	0x91D7	#<CJK>
0xFBBC	0x91DE	#<CJK>
0xFBBD	0x91ED	#<CJK>
0xFBBE	0x91EE	#<CJK>
0xFBBF	0x91E4	#<CJK>
0xFBC0	0x91E5	#<CJK>
0xFBC1	0x9206	#<CJK>
0xFBC2	0x9210	#<CJK>
0xFBC3	0x920A	#<CJK>
0xFBC4	0x923A	#<CJK>
0xFBC5	0x9240	#<CJK>
0xFBC6	0x923C	#<CJK>
0xFBC7	0x924E	#<CJK>
0xFBC8	0x9259	#<CJK>
0xFBC9	0x9251	#<CJK>
0xFBCA	0x9239	#<CJK>
0xFBCB	0x9267	#<CJK>
0xFBCC	0x92A7	#<CJK>
0xFBCD	0x9277	#<CJK>
0xFBCE	0x9278	#<CJK>
0xFBCF	0x92E7	#<CJK>
0xFBD0	0x92D7	#<CJK>
0xFBD1	0x92D9	#<CJK>
0xFBD2	0x92D0	#<CJK>
0xFBD3	0xFA27	#<CJK>
0xFBD4	0x92D5	#<CJK>
0xFBD5	0x92E0	#<CJK>
0xFBD6	0x92D3	#<CJK>
0xFBD7	0x9325	#<CJK>
0xFBD8	0x9321	#<CJK>
0xFBD9	0x92FB	#<CJK>
0xFBDA	0xFA28	#<CJK>
0xFBDB	0x931E	#<CJK>
0xFBDC	0x92FF	#<CJK>
0xFBDD	0x931D	#<CJK>
0xFBDE	0x9302	#<CJK>
0xFBDF	0x9370	#<CJK>
0xFBE0	0x9357	#<CJK>
0xFBE1	0x93A4	#<CJK>
0xFBE2	0x93C6	#<CJK>
0xFBE3	0x93DE	#<CJK>
0xFBE4	0x93F8	#<CJK>
0xFBE5	0x9431	#<CJK>
0xFBE6	0x9445	#<CJK>
0xFBE7	0x9448	#<CJK>
0xFBE8	0x9592	#<CJK>
0xFBE9	0xF9DC	#<CJK>
0xFBEA	0xFA29	#<CJK>
0xFBEB	0x969D	#<CJK>
0xFBEC	0x96AF	#<CJK>
0xFBED	0x9733	#<CJK>
0xFBEE	0x973B	#<CJK>
0xFBEF	0x9743	#<CJK>
0xFBF0	0x974D	#<CJK>
0xFBF1	0x974F	#<CJK>
0xFBF2	0x9751	#<CJK>
0xFBF3	0x9755	#<CJK>
0xFBF4	0x9857	#<CJK>
0xFBF5	0x9865	#<CJK>
0xFBF6	0xFA2A	#<CJK>
0xFBF7	0xFA2B	#<CJK>
0xFBF8	0x9927	#<CJK>
0xFBF9	0xFA2C	#<CJK>
0xFBFA	0x999E	#<CJK>
0xFBFB	0x9A4E	#<CJK>
0xFBFC	0x9AD9	#<CJK>
0xFC40	0x9ADC	#<CJK>
0xFC41	0x9B75	#<CJK>
0xFC42	0x9B72	#<CJK>
0xFC43	0x9B8F	#<CJK>
0xFC44	0x9BB1	#<CJK>
0xFC45	0x9BBB	#<CJK>
0xFC46	0x9C00	#<CJK>
0xFC47	0x9D70	#<CJK>
0xFC48	0x9D6B	#<CJK>
0xFC49	0xFA2D	#<CJK>
0xFC4A	0x9E19	#<CJK>
0xFC4B	0x9ED1	#<CJK>



Added tools/encoding/cp936.txt.

more than 10,000 changes

Added tools/encoding/cp949.txt.

more than 10,000 changes

Added tools/encoding/cp950.txt.

more than 10,000 changes

Added tools/encoding/dingbats.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
#
# ITC Dingbats, for use on X.  Doesn't have Mac dingbats extensions.
#
# This file is derived from:
#
#   Name:             MacOS_Dingbats [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <4>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Dingbats code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Dingbats code order.
#
#   Several of these mappings require the use of corporate
#   characters. See the file "MacOS-CorpCharList".
#
#   Notes on MacOS Dingbats:
#   ------------------------
#
#   The MacOS Dingbats encoding shares the script code smRoman
#   (0) with the standard MacOS Roman encoding. To determine if
#   the Dingbats encoding is being used, you must check if the
#   font name is "Zapf Dingbats".
#
#   The layout of the Dingbats character set is identical to or
#   a superset of the layout of the Adobe Zapf Dingbats encoding
#   vector.
#
##################

0x20	0x0020	# SPACE
0x21	0x2701	# UPPER BLADE SCISSORS
0x22	0x2702	# BLACK SCISSORS
0x23	0x2703	# LOWER BLADE SCISSORS
0x24	0x2704	# WHITE SCISSORS
0x25	0x260E	# BLACK TELEPHONE
0x26	0x2706	# TELEPHONE LOCATION SIGN
0x27	0x2707	# TAPE DRIVE
0x28	0x2708	# AIRPLANE
0x29	0x2709	# ENVELOPE
0x2A	0x261B	# BLACK RIGHT POINTING INDEX
0x2B	0x261E	# WHITE RIGHT POINTING INDEX
0x2C	0x270C	# VICTORY HAND
0x2D	0x270D	# WRITING HAND
0x2E	0x270E	# LOWER RIGHT PENCIL
0x2F	0x270F	# PENCIL
0x30	0x2710	# UPPER RIGHT PENCIL
0x31	0x2711	# WHITE NIB
0x32	0x2712	# BLACK NIB
0x33	0x2713	# CHECK MARK
0x34	0x2714	# HEAVY CHECK MARK
0x35	0x2715	# MULTIPLICATION X
0x36	0x2716	# HEAVY MULTIPLICATION X
0x37	0x2717	# BALLOT X
0x38	0x2718	# HEAVY BALLOT X
0x39	0x2719	# OUTLINED GREEK CROSS
0x3A	0x271A	# HEAVY GREEK CROSS
0x3B	0x271B	# OPEN CENTRE CROSS
0x3C	0x271C	# HEAVY OPEN CENTRE CROSS
0x3D	0x271D	# LATIN CROSS
0x3E	0x271E	# SHADOWED WHITE LATIN CROSS
0x3F	0x271F	# OUTLINED LATIN CROSS
0x40	0x2720	# MALTESE CROSS
0x41	0x2721	# STAR OF DAVID
0x42	0x2722	# FOUR TEARDROP-SPOKED ASTERISK
0x43	0x2723	# FOUR BALLOON-SPOKED ASTERISK
0x44	0x2724	# HEAVY FOUR BALLOON-SPOKED ASTERISK
0x45	0x2725	# FOUR CLUB-SPOKED ASTERISK
0x46	0x2726	# BLACK FOUR POINTED STAR
0x47	0x2727	# WHITE FOUR POINTED STAR
0x48	0x2605	# BLACK STAR
0x49	0x2729	# STRESS OUTLINED WHITE STAR
0x4A	0x272A	# CIRCLED WHITE STAR
0x4B	0x272B	# OPEN CENTRE BLACK STAR
0x4C	0x272C	# BLACK CENTRE WHITE STAR
0x4D	0x272D	# OUTLINED BLACK STAR
0x4E	0x272E	# HEAVY OUTLINED BLACK STAR
0x4F	0x272F	# PINWHEEL STAR
0x50	0x2730	# SHADOWED WHITE STAR
0x51	0x2731	# HEAVY ASTERISK
0x52	0x2732	# OPEN CENTRE ASTERISK
0x53	0x2733	# EIGHT SPOKED ASTERISK
0x54	0x2734	# EIGHT POINTED BLACK STAR
0x55	0x2735	# EIGHT POINTED PINWHEEL STAR
0x56	0x2736	# SIX POINTED BLACK STAR
0x57	0x2737	# EIGHT POINTED RECTILINEAR BLACK STAR
0x58	0x2738	# HEAVY EIGHT POINTED RECTILINEAR BLACK STAR
0x59	0x2739	# TWELVE POINTED BLACK STAR
0x5A	0x273A	# SIXTEEN POINTED ASTERISK
0x5B	0x273B	# TEARDROP-SPOKED ASTERISK
0x5C	0x273C	# OPEN CENTRE TEARDROP-SPOKED ASTERISK
0x5D	0x273D	# HEAVY TEARDROP-SPOKED ASTERISK
0x5E	0x273E	# SIX PETALLED BLACK AND WHITE FLORETTE
0x5F	0x273F	# BLACK FLORETTE
0x60	0x2740	# WHITE FLORETTE
0x61	0x2741	# EIGHT PETALLED OUTLINED BLACK FLORETTE
0x62	0x2742	# CIRCLED OPEN CENTRE EIGHT POINTED STAR
0x63	0x2743	# HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK
0x64	0x2744	# SNOWFLAKE
0x65	0x2745	# TIGHT TRIFOLIATE SNOWFLAKE
0x66	0x2746	# HEAVY CHEVRON SNOWFLAKE
0x67	0x2747	# SPARKLE
0x68	0x2748	# HEAVY SPARKLE
0x69	0x2749	# BALLOON-SPOKED ASTERISK
0x6A	0x274A	# EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
0x6B	0x274B	# HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
0x6C	0x25CF	# BLACK CIRCLE
0x6D	0x274D	# SHADOWED WHITE CIRCLE
0x6E	0x25A0	# BLACK SQUARE
0x6F	0x274F	# LOWER RIGHT DROP-SHADOWED WHITE SQUARE
0x70	0x2750	# UPPER RIGHT DROP-SHADOWED WHITE SQUARE
0x71	0x2751	# LOWER RIGHT SHADOWED WHITE SQUARE
0x72	0x2752	# UPPER RIGHT SHADOWED WHITE SQUARE
0x73	0x25B2	# BLACK UP-POINTING TRIANGLE
0x74	0x25BC	# BLACK DOWN-POINTING TRIANGLE
0x75	0x25C6	# BLACK DIAMOND
0x76	0x2756	# BLACK DIAMOND MINUS WHITE X
0x77	0x25D7	# RIGHT HALF BLACK CIRCLE
0x78	0x2758	# LIGHT VERTICAL BAR
0x79	0x2759	# MEDIUM VERTICAL BAR
0x7A	0x275A	# HEAVY VERTICAL BAR
0x7B	0x275B	# HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT
0x7C	0x275C	# HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT
0x7D	0x275D	# HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT
0x7E	0x275E	# HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT
0xA1	0x2761	# CURVED STEM PARAGRAPH SIGN ORNAMENT
0xA2	0x2762	# HEAVY EXCLAMATION MARK ORNAMENT
0xA3	0x2763	# HEAVY HEART EXCLAMATION MARK ORNAMENT
0xA4	0x2764	# HEAVY BLACK HEART
0xA5	0x2765	# ROTATED HEAVY BLACK HEART BULLET
0xA6	0x2766	# FLORAL HEART
0xA7	0x2767	# ROTATED FLORAL HEART BULLET
0xA8	0x2663	# BLACK CLUB SUIT
0xA9	0x2666	# BLACK DIAMOND SUIT
0xAA	0x2665	# BLACK HEART SUIT
0xAB	0x2660	# BLACK SPADE SUIT
0xAC	0x2460	# CIRCLED DIGIT ONE
0xAD	0x2461	# CIRCLED DIGIT TWO
0xAE	0x2462	# CIRCLED DIGIT THREE
0xAF	0x2463	# CIRCLED DIGIT FOUR
0xB0	0x2464	# CIRCLED DIGIT FIVE
0xB1	0x2465	# CIRCLED DIGIT SIX
0xB2	0x2466	# CIRCLED DIGIT SEVEN
0xB3	0x2467	# CIRCLED DIGIT EIGHT
0xB4	0x2468	# CIRCLED DIGIT NINE
0xB5	0x2469	# CIRCLED NUMBER TEN
0xB6	0x2776	# DINGBAT NEGATIVE CIRCLED DIGIT ONE
0xB7	0x2777	# DINGBAT NEGATIVE CIRCLED DIGIT TWO
0xB8	0x2778	# DINGBAT NEGATIVE CIRCLED DIGIT THREE
0xB9	0x2779	# DINGBAT NEGATIVE CIRCLED DIGIT FOUR
0xBA	0x277A	# DINGBAT NEGATIVE CIRCLED DIGIT FIVE
0xBB	0x277B	# DINGBAT NEGATIVE CIRCLED DIGIT SIX
0xBC	0x277C	# DINGBAT NEGATIVE CIRCLED DIGIT SEVEN
0xBD	0x277D	# DINGBAT NEGATIVE CIRCLED DIGIT EIGHT
0xBE	0x277E	# DINGBAT NEGATIVE CIRCLED DIGIT NINE
0xBF	0x277F	# DINGBAT NEGATIVE CIRCLED NUMBER TEN
0xC0	0x2780	# DINGBAT CIRCLED SANS-SERIF DIGIT ONE
0xC1	0x2781	# DINGBAT CIRCLED SANS-SERIF DIGIT TWO
0xC2	0x2782	# DINGBAT CIRCLED SANS-SERIF DIGIT THREE
0xC3	0x2783	# DINGBAT CIRCLED SANS-SERIF DIGIT FOUR
0xC4	0x2784	# DINGBAT CIRCLED SANS-SERIF DIGIT FIVE
0xC5	0x2785	# DINGBAT CIRCLED SANS-SERIF DIGIT SIX
0xC6	0x2786	# DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN
0xC7	0x2787	# DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT
0xC8	0x2788	# DINGBAT CIRCLED SANS-SERIF DIGIT NINE
0xC9	0x2789	# DINGBAT CIRCLED SANS-SERIF NUMBER TEN
0xCA	0x278A	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE
0xCB	0x278B	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO
0xCC	0x278C	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE
0xCD	0x278D	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR
0xCE	0x278E	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE
0xCF	0x278F	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX
0xD0	0x2790	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN
0xD1	0x2791	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT
0xD2	0x2792	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE
0xD3	0x2793	# DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN
0xD4	0x2794	# HEAVY WIDE-HEADED RIGHTWARDS ARROW
0xD5	0x2192	# RIGHTWARDS ARROW
0xD6	0x2194	# LEFT RIGHT ARROW
0xD7	0x2195	# UP DOWN ARROW
0xD8	0x2798	# HEAVY SOUTH EAST ARROW
0xD9	0x2799	# HEAVY RIGHTWARDS ARROW
0xDA	0x279A	# HEAVY NORTH EAST ARROW
0xDB	0x279B	# DRAFTING POINT RIGHTWARDS ARROW
0xDC	0x279C	# HEAVY ROUND-TIPPED RIGHTWARDS ARROW
0xDD	0x279D	# TRIANGLE-HEADED RIGHTWARDS ARROW
0xDE	0x279E	# HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW
0xDF	0x279F	# DASHED TRIANGLE-HEADED RIGHTWARDS ARROW
0xE0	0x27A0	# HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW
0xE1	0x27A1	# BLACK RIGHTWARDS ARROW
0xE2	0x27A2	# THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD
0xE3	0x27A3	# THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD
0xE4	0x27A4	# BLACK RIGHTWARDS ARROWHEAD
0xE5	0x27A5	# HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW
0xE6	0x27A6	# HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW
0xE7	0x27A7	# SQUAT BLACK RIGHTWARDS ARROW
0xE8	0x27A8	# HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW
0xE9	0x27A9	# RIGHT-SHADED WHITE RIGHTWARDS ARROW
0xEA	0x27AA	# LEFT-SHADED WHITE RIGHTWARDS ARROW
0xEB	0x27AB	# BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW
0xEC	0x27AC	# FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW
0xED	0x27AD	# HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
0xEE	0x27AE	# HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
0xEF	0x27AF	# NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
0xF1	0x27B1	# NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
0xF2	0x27B2	# CIRCLED HEAVY WHITE RIGHTWARDS ARROW
0xF3	0x27B3	# WHITE-FEATHERED RIGHTWARDS ARROW
0xF4	0x27B4	# BLACK-FEATHERED SOUTH EAST ARROW
0xF5	0x27B5	# BLACK-FEATHERED RIGHTWARDS ARROW
0xF6	0x27B6	# BLACK-FEATHERED NORTH EAST ARROW
0xF7	0x27B7	# HEAVY BLACK-FEATHERED SOUTH EAST ARROW
0xF8	0x27B8	# HEAVY BLACK-FEATHERED RIGHTWARDS ARROW
0xF9	0x27B9	# HEAVY BLACK-FEATHERED NORTH EAST ARROW
0xFA	0x27BA	# TEARDROP-BARBED RIGHTWARDS ARROW
0xFB	0x27BB	# HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW
0xFC	0x27BC	# WEDGE-TAILED RIGHTWARDS ARROW
0xFD	0x27BD	# HEAVY WEDGE-TAILED RIGHTWARDS ARROW
0xFE	0x27BE	# OPEN OUTLINED RIGHTWARDS ARROW

Added tools/encoding/gb12345.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
#
#	Name:             GB12345-80 to Unicode table (complete, hex format)
#	Unicode version:  1.1
#	Table version:    0.0d1
#	Table format:     Format A
#	Date:             6 December 1993
#	Author:           Glenn Adams <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data Metis and Taligent currently have on how
#       GB12345-90 characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the GB12345 code (in hex as 0xXXXX)
#		 Column #2 is the Unicode (in hex as 0xXXXX)
#		 Column #3 the Unicode name (follows a comment sign, '#')
#					The official names for Unicode characters U+4E00
#					to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
#					where XXXX is the code point.  Including all these
#					names in this file increases its size substantially
#					and needlessly.  The token "<CJK>" is used for the
#					name of these characters.  If necessary, it can be
#					expanded algorithmically by a parser or editor.
#
#	The entries are in GB12345 order
#
#	The following algorithms can be used to change the hex form
#		of GB12345 to other standard forms:
#
#		To change hex to EUC form, add 0x8080
#		To change hex to kuten form, first subtract 0x2020.  Then
#			the high and low bytes correspond to the ku and ten of
#			the kuten form.  For example, 0x2121 -> 0x0101 -> 0101;
#			0x777E -> 0x575E -> 8794
#
#	Any comments or problems, contact <[email protected]>
#
#
0x2121	0x3000	# IDEOGRAPHIC SPACE
0x2122	0x3001	# IDEOGRAPHIC COMMA
0x2123	0x3002	# IDEOGRAPHIC FULL STOP
0x2124	0x30FB	# KATAKANA MIDDLE DOT
0x2125	0x02C9	# MODIFIER LETTER MACRON (Mandarin Chinese first tone)
0x2126	0x02C7	# CARON (Mandarin Chinese third tone)
0x2127	0x00A8	# DIAERESIS
0x2128	0x3003	# DITTO MARK
0x2129	0x3005	# IDEOGRAPHIC ITERATION MARK
0x212A	0x2015	# HORIZONTAL BAR
0x212B	0xFF5E	# FULLWIDTH TILDE
0x212C	0x2225	# PARALLEL TO
0x212D	0x2026	# HORIZONTAL ELLIPSIS
0x212E	0x2018	# LEFT SINGLE QUOTATION MARK
0x212F	0x2019	# RIGHT SINGLE QUOTATION MARK
0x2130	0x201C	# LEFT DOUBLE QUOTATION MARK
0x2131	0x201D	# RIGHT DOUBLE QUOTATION MARK
0x2132	0x3014	# LEFT TORTOISE SHELL BRACKET
0x2133	0x3015	# RIGHT TORTOISE SHELL BRACKET
0x2134	0x3008	# LEFT ANGLE BRACKET
0x2135	0x3009	# RIGHT ANGLE BRACKET
0x2136	0x300A	# LEFT DOUBLE ANGLE BRACKET
0x2137	0x300B	# RIGHT DOUBLE ANGLE BRACKET
0x2138	0x300C	# LEFT CORNER BRACKET
0x2139	0x300D	# RIGHT CORNER BRACKET
0x213A	0x300E	# LEFT WHITE CORNER BRACKET
0x213B	0x300F	# RIGHT WHITE CORNER BRACKET
0x213C	0x3016	# LEFT WHITE LENTICULAR BRACKET
0x213D	0x3017	# RIGHT WHITE LENTICULAR BRACKET
0x213E	0x3010	# LEFT BLACK LENTICULAR BRACKET
0x213F	0x3011	# RIGHT BLACK LENTICULAR BRACKET
0x2140	0x00B1	# PLUS-MINUS SIGN
0x2141	0x00D7	# MULTIPLICATION SIGN
0x2142	0x00F7	# DIVISION SIGN
0x2143	0x2236	# RATIO
0x2144	0x2227	# LOGICAL AND
0x2145	0x2228	# LOGICAL OR
0x2146	0x2211	# N-ARY SUMMATION
0x2147	0x220F	# N-ARY PRODUCT
0x2148	0x222A	# UNION
0x2149	0x2229	# INTERSECTION
0x214A	0x2208	# ELEMENT OF
0x214B	0x2237	# PROPORTION
0x214C	0x221A	# SQUARE ROOT
0x214D	0x22A5	# UP TACK
0x214E	0x2225	# PARALLEL TO
0x214F	0x2220	# ANGLE
0x2150	0x2312	# ARC
0x2151	0x2299	# CIRCLED DOT OPERATOR
0x2152	0x222B	# INTEGRAL
0x2153	0x222E	# CONTOUR INTEGRAL
0x2154	0x2261	# IDENTICAL TO
0x2155	0x224C	# ALL EQUAL TO
0x2156	0x2248	# ALMOST EQUAL TO
0x2157	0x223D	# REVERSED TILDE
0x2158	0x221D	# PROPORTIONAL TO
0x2159	0x2260	# NOT EQUAL TO
0x215A	0x226E	# NOT LESS-THAN
0x215B	0x226F	# NOT GREATER-THAN
0x215C	0x2264	# LESS-THAN OR EQUAL TO
0x215D	0x2265	# GREATER-THAN OR EQUAL TO
0x215E	0x221E	# INFINITY
0x215F	0x2235	# BECAUSE
0x2160	0x2234	# THEREFORE
0x2161	0x2642	# MALE SIGN
0x2162	0x2640	# FEMALE SIGN
0x2163	0x00B0	# DEGREE SIGN
0x2164	0x2032	# PRIME
0x2165	0x2033	# DOUBLE PRIME
0x2166	0x2103	# DEGREE CELSIUS
0x2167	0xFF04	# FULLWIDTH DOLLAR SIGN
0x2168	0x00A4	# CURRENCY SIGN
0x2169	0xFFE0	# FULLWIDTH CENT SIGN
0x216A	0xFFE1	# FULLWIDTH POUND SIGN
0x216B	0x2030	# PER MILLE SIGN
0x216C	0x00A7	# SECTION SIGN
0x216D	0x2116	# NUMERO SIGN
0x216E	0x2606	# WHITE STAR
0x216F	0x2605	# BLACK STAR
0x2170	0x25CB	# WHITE CIRCLE
0x2171	0x25CF	# BLACK CIRCLE
0x2172	0x25CE	# BULLSEYE
0x2173	0x25C7	# WHITE DIAMOND
0x2174	0x25C6	# BLACK DIAMOND
0x2175	0x25A1	# WHITE SQUARE
0x2176	0x25A0	# BLACK SQUARE
0x2177	0x25B3	# WHITE UP-POINTING TRIANGLE
0x2178	0x25B2	# BLACK UP-POINTING TRIANGLE
0x2179	0x203B	# REFERENCE MARK
0x217A	0x2192	# RIGHTWARDS ARROW
0x217B	0x2190	# LEFTWARDS ARROW
0x217C	0x2191	# UPWARDS ARROW
0x217D	0x2193	# DOWNWARDS ARROW
0x217E	0x3013	# GETA MARK
0x2231	0x2488	# DIGIT ONE FULL STOP
0x2232	0x2489	# DIGIT TWO FULL STOP
0x2233	0x248A	# DIGIT THREE FULL STOP
0x2234	0x248B	# DIGIT FOUR FULL STOP
0x2235	0x248C	# DIGIT FIVE FULL STOP
0x2236	0x248D	# DIGIT SIX FULL STOP
0x2237	0x248E	# DIGIT SEVEN FULL STOP
0x2238	0x248F	# DIGIT EIGHT FULL STOP
0x2239	0x2490	# DIGIT NINE FULL STOP
0x223A	0x2491	# NUMBER TEN FULL STOP
0x223B	0x2492	# NUMBER ELEVEN FULL STOP
0x223C	0x2493	# NUMBER TWELVE FULL STOP
0x223D	0x2494	# NUMBER THIRTEEN FULL STOP
0x223E	0x2495	# NUMBER FOURTEEN FULL STOP
0x223F	0x2496	# NUMBER FIFTEEN FULL STOP
0x2240	0x2497	# NUMBER SIXTEEN FULL STOP
0x2241	0x2498	# NUMBER SEVENTEEN FULL STOP
0x2242	0x2499	# NUMBER EIGHTEEN FULL STOP
0x2243	0x249A	# NUMBER NINETEEN FULL STOP
0x2244	0x249B	# NUMBER TWENTY FULL STOP
0x2245	0x2474	# PARENTHESIZED DIGIT ONE
0x2246	0x2475	# PARENTHESIZED DIGIT TWO
0x2247	0x2476	# PARENTHESIZED DIGIT THREE
0x2248	0x2477	# PARENTHESIZED DIGIT FOUR
0x2249	0x2478	# PARENTHESIZED DIGIT FIVE
0x224A	0x2479	# PARENTHESIZED DIGIT SIX
0x224B	0x247A	# PARENTHESIZED DIGIT SEVEN
0x224C	0x247B	# PARENTHESIZED DIGIT EIGHT
0x224D	0x247C	# PARENTHESIZED DIGIT NINE
0x224E	0x247D	# PARENTHESIZED NUMBER TEN
0x224F	0x247E	# PARENTHESIZED NUMBER ELEVEN
0x2250	0x247F	# PARENTHESIZED NUMBER TWELVE
0x2251	0x2480	# PARENTHESIZED NUMBER THIRTEEN
0x2252	0x2481	# PARENTHESIZED NUMBER FOURTEEN
0x2253	0x2482	# PARENTHESIZED NUMBER FIFTEEN
0x2254	0x2483	# PARENTHESIZED NUMBER SIXTEEN
0x2255	0x2484	# PARENTHESIZED NUMBER SEVENTEEN
0x2256	0x2485	# PARENTHESIZED NUMBER EIGHTEEN
0x2257	0x2486	# PARENTHESIZED NUMBER NINETEEN
0x2258	0x2487	# PARENTHESIZED NUMBER TWENTY
0x2259	0x2460	# CIRCLED DIGIT ONE
0x225A	0x2461	# CIRCLED DIGIT TWO
0x225B	0x2462	# CIRCLED DIGIT THREE
0x225C	0x2463	# CIRCLED DIGIT FOUR
0x225D	0x2464	# CIRCLED DIGIT FIVE
0x225E	0x2465	# CIRCLED DIGIT SIX
0x225F	0x2466	# CIRCLED DIGIT SEVEN
0x2260	0x2467	# CIRCLED DIGIT EIGHT
0x2261	0x2468	# CIRCLED DIGIT NINE
0x2262	0x2469	# CIRCLED NUMBER TEN
0x2265	0x3220	# PARENTHESIZED IDEOGRAPH ONE
0x2266	0x3221	# PARENTHESIZED IDEOGRAPH TWO
0x2267	0x3222	# PARENTHESIZED IDEOGRAPH THREE
0x2268	0x3223	# PARENTHESIZED IDEOGRAPH FOUR
0x2269	0x3224	# PARENTHESIZED IDEOGRAPH FIVE
0x226A	0x3225	# PARENTHESIZED IDEOGRAPH SIX
0x226B	0x3226	# PARENTHESIZED IDEOGRAPH SEVEN
0x226C	0x3227	# PARENTHESIZED IDEOGRAPH EIGHT
0x226D	0x3228	# PARENTHESIZED IDEOGRAPH NINE
0x226E	0x3229	# PARENTHESIZED IDEOGRAPH TEN
0x2271	0x2160	# ROMAN NUMERAL ONE
0x2272	0x2161	# ROMAN NUMERAL TWO
0x2273	0x2162	# ROMAN NUMERAL THREE
0x2274	0x2163	# ROMAN NUMERAL FOUR
0x2275	0x2164	# ROMAN NUMERAL FIVE
0x2276	0x2165	# ROMAN NUMERAL SIX
0x2277	0x2166	# ROMAN NUMERAL SEVEN
0x2278	0x2167	# ROMAN NUMERAL EIGHT
0x2279	0x2168	# ROMAN NUMERAL NINE
0x227A	0x2169	# ROMAN NUMERAL TEN
0x227B	0x216A	# ROMAN NUMERAL ELEVEN
0x227C	0x216B	# ROMAN NUMERAL TWELVE
0x2321	0xFF01	# FULLWIDTH EXCLAMATION MARK
0x2322	0xFF02	# FULLWIDTH QUOTATION MARK
0x2323	0xFF03	# FULLWIDTH NUMBER SIGN
0x2324	0xFFE5	# FULLWIDTH YEN SIGN
0x2325	0xFF05	# FULLWIDTH PERCENT SIGN
0x2326	0xFF06	# FULLWIDTH AMPERSAND
0x2327	0xFF07	# FULLWIDTH APOSTROPHE
0x2328	0xFF08	# FULLWIDTH LEFT PARENTHESIS
0x2329	0xFF09	# FULLWIDTH RIGHT PARENTHESIS
0x232A	0xFF0A	# FULLWIDTH ASTERISK
0x232B	0xFF0B	# FULLWIDTH PLUS SIGN
0x232C	0xFF0C	# FULLWIDTH COMMA
0x232D	0xFF0D	# FULLWIDTH HYPHEN-MINUS
0x232E	0xFF0E	# FULLWIDTH FULL STOP
0x232F	0xFF0F	# FULLWIDTH SOLIDUS
0x2330	0xFF10	# FULLWIDTH DIGIT ZERO
0x2331	0xFF11	# FULLWIDTH DIGIT ONE
0x2332	0xFF12	# FULLWIDTH DIGIT TWO
0x2333	0xFF13	# FULLWIDTH DIGIT THREE
0x2334	0xFF14	# FULLWIDTH DIGIT FOUR
0x2335	0xFF15	# FULLWIDTH DIGIT FIVE
0x2336	0xFF16	# FULLWIDTH DIGIT SIX
0x2337	0xFF17	# FULLWIDTH DIGIT SEVEN
0x2338	0xFF18	# FULLWIDTH DIGIT EIGHT
0x2339	0xFF19	# FULLWIDTH DIGIT NINE
0x233A	0xFF1A	# FULLWIDTH COLON
0x233B	0xFF1B	# FULLWIDTH SEMICOLON
0x233C	0xFF1C	# FULLWIDTH LESS-THAN SIGN
0x233D	0xFF1D	# FULLWIDTH EQUALS SIGN
0x233E	0xFF1E	# FULLWIDTH GREATER-THAN SIGN
0x233F	0xFF1F	# FULLWIDTH QUESTION MARK
0x2340	0xFF20	# FULLWIDTH COMMERCIAL AT
0x2341	0xFF21	# FULLWIDTH LATIN CAPITAL LETTER A
0x2342	0xFF22	# FULLWIDTH LATIN CAPITAL LETTER B
0x2343	0xFF23	# FULLWIDTH LATIN CAPITAL LETTER C
0x2344	0xFF24	# FULLWIDTH LATIN CAPITAL LETTER D
0x2345	0xFF25	# FULLWIDTH LATIN CAPITAL LETTER E
0x2346	0xFF26	# FULLWIDTH LATIN CAPITAL LETTER F
0x2347	0xFF27	# FULLWIDTH LATIN CAPITAL LETTER G
0x2348	0xFF28	# FULLWIDTH LATIN CAPITAL LETTER H
0x2349	0xFF29	# FULLWIDTH LATIN CAPITAL LETTER I
0x234A	0xFF2A	# FULLWIDTH LATIN CAPITAL LETTER J
0x234B	0xFF2B	# FULLWIDTH LATIN CAPITAL LETTER K
0x234C	0xFF2C	# FULLWIDTH LATIN CAPITAL LETTER L
0x234D	0xFF2D	# FULLWIDTH LATIN CAPITAL LETTER M
0x234E	0xFF2E	# FULLWIDTH LATIN CAPITAL LETTER N
0x234F	0xFF2F	# FULLWIDTH LATIN CAPITAL LETTER O
0x2350	0xFF30	# FULLWIDTH LATIN CAPITAL LETTER P
0x2351	0xFF31	# FULLWIDTH LATIN CAPITAL LETTER Q
0x2352	0xFF32	# FULLWIDTH LATIN CAPITAL LETTER R
0x2353	0xFF33	# FULLWIDTH LATIN CAPITAL LETTER S
0x2354	0xFF34	# FULLWIDTH LATIN CAPITAL LETTER T
0x2355	0xFF35	# FULLWIDTH LATIN CAPITAL LETTER U
0x2356	0xFF36	# FULLWIDTH LATIN CAPITAL LETTER V
0x2357	0xFF37	# FULLWIDTH LATIN CAPITAL LETTER W
0x2358	0xFF38	# FULLWIDTH LATIN CAPITAL LETTER X
0x2359	0xFF39	# FULLWIDTH LATIN CAPITAL LETTER Y
0x235A	0xFF3A	# FULLWIDTH LATIN CAPITAL LETTER Z
0x235B	0xFF3B	# FULLWIDTH LEFT SQUARE BRACKET
0x235C	0xFF3C	# FULLWIDTH REVERSE SOLIDUS
0x235D	0xFF3D	# FULLWIDTH RIGHT SQUARE BRACKET
0x235E	0xFF3E	# FULLWIDTH CIRCUMFLEX ACCENT
0x235F	0xFF3F	# FULLWIDTH LOW LINE
0x2360	0xFF40	# FULLWIDTH GRAVE ACCENT
0x2361	0xFF41	# FULLWIDTH LATIN SMALL LETTER A
0x2362	0xFF42	# FULLWIDTH LATIN SMALL LETTER B
0x2363	0xFF43	# FULLWIDTH LATIN SMALL LETTER C
0x2364	0xFF44	# FULLWIDTH LATIN SMALL LETTER D
0x2365	0xFF45	# FULLWIDTH LATIN SMALL LETTER E
0x2366	0xFF46	# FULLWIDTH LATIN SMALL LETTER F
0x2367	0xFF47	# FULLWIDTH LATIN SMALL LETTER G
0x2368	0xFF48	# FULLWIDTH LATIN SMALL LETTER H
0x2369	0xFF49	# FULLWIDTH LATIN SMALL LETTER I
0x236A	0xFF4A	# FULLWIDTH LATIN SMALL LETTER J
0x236B	0xFF4B	# FULLWIDTH LATIN SMALL LETTER K
0x236C	0xFF4C	# FULLWIDTH LATIN SMALL LETTER L
0x236D	0xFF4D	# FULLWIDTH LATIN SMALL LETTER M
0x236E	0xFF4E	# FULLWIDTH LATIN SMALL LETTER N
0x236F	0xFF4F	# FULLWIDTH LATIN SMALL LETTER O
0x2370	0xFF50	# FULLWIDTH LATIN SMALL LETTER P
0x2371	0xFF51	# FULLWIDTH LATIN SMALL LETTER Q
0x2372	0xFF52	# FULLWIDTH LATIN SMALL LETTER R
0x2373	0xFF53	# FULLWIDTH LATIN SMALL LETTER S
0x2374	0xFF54	# FULLWIDTH LATIN SMALL LETTER T
0x2375	0xFF55	# FULLWIDTH LATIN SMALL LETTER U
0x2376	0xFF56	# FULLWIDTH LATIN SMALL LETTER V
0x2377	0xFF57	# FULLWIDTH LATIN SMALL LETTER W
0x2378	0xFF58	# FULLWIDTH LATIN SMALL LETTER X
0x2379	0xFF59	# FULLWIDTH LATIN SMALL LETTER Y
0x237A	0xFF5A	# FULLWIDTH LATIN SMALL LETTER Z
0x237B	0xFF5B	# FULLWIDTH LEFT CURLY BRACKET
0x237C	0xFF5C	# FULLWIDTH VERTICAL LINE
0x237D	0xFF5D	# FULLWIDTH RIGHT CURLY BRACKET
0x237E	0xFFE3	# FULLWIDTH MACRON
0x2421	0x3041	# HIRAGANA LETTER SMALL A
0x2422	0x3042	# HIRAGANA LETTER A
0x2423	0x3043	# HIRAGANA LETTER SMALL I
0x2424	0x3044	# HIRAGANA LETTER I
0x2425	0x3045	# HIRAGANA LETTER SMALL U
0x2426	0x3046	# HIRAGANA LETTER U
0x2427	0x3047	# HIRAGANA LETTER SMALL E
0x2428	0x3048	# HIRAGANA LETTER E
0x2429	0x3049	# HIRAGANA LETTER SMALL O
0x242A	0x304A	# HIRAGANA LETTER O
0x242B	0x304B	# HIRAGANA LETTER KA
0x242C	0x304C	# HIRAGANA LETTER GA
0x242D	0x304D	# HIRAGANA LETTER KI
0x242E	0x304E	# HIRAGANA LETTER GI
0x242F	0x304F	# HIRAGANA LETTER KU
0x2430	0x3050	# HIRAGANA LETTER GU
0x2431	0x3051	# HIRAGANA LETTER KE
0x2432	0x3052	# HIRAGANA LETTER GE
0x2433	0x3053	# HIRAGANA LETTER KO
0x2434	0x3054	# HIRAGANA LETTER GO
0x2435	0x3055	# HIRAGANA LETTER SA
0x2436	0x3056	# HIRAGANA LETTER ZA
0x2437	0x3057	# HIRAGANA LETTER SI
0x2438	0x3058	# HIRAGANA LETTER ZI
0x2439	0x3059	# HIRAGANA LETTER SU
0x243A	0x305A	# HIRAGANA LETTER ZU
0x243B	0x305B	# HIRAGANA LETTER SE
0x243C	0x305C	# HIRAGANA LETTER ZE
0x243D	0x305D	# HIRAGANA LETTER SO
0x243E	0x305E	# HIRAGANA LETTER ZO
0x243F	0x305F	# HIRAGANA LETTER TA
0x2440	0x3060	# HIRAGANA LETTER DA
0x2441	0x3061	# HIRAGANA LETTER TI
0x2442	0x3062	# HIRAGANA LETTER DI
0x2443	0x3063	# HIRAGANA LETTER SMALL TU
0x2444	0x3064	# HIRAGANA LETTER TU
0x2445	0x3065	# HIRAGANA LETTER DU
0x2446	0x3066	# HIRAGANA LETTER TE
0x2447	0x3067	# HIRAGANA LETTER DE
0x2448	0x3068	# HIRAGANA LETTER TO
0x2449	0x3069	# HIRAGANA LETTER DO
0x244A	0x306A	# HIRAGANA LETTER NA
0x244B	0x306B	# HIRAGANA LETTER NI
0x244C	0x306C	# HIRAGANA LETTER NU
0x244D	0x306D	# HIRAGANA LETTER NE
0x244E	0x306E	# HIRAGANA LETTER NO
0x244F	0x306F	# HIRAGANA LETTER HA
0x2450	0x3070	# HIRAGANA LETTER BA
0x2451	0x3071	# HIRAGANA LETTER PA
0x2452	0x3072	# HIRAGANA LETTER HI
0x2453	0x3073	# HIRAGANA LETTER BI
0x2454	0x3074	# HIRAGANA LETTER PI
0x2455	0x3075	# HIRAGANA LETTER HU
0x2456	0x3076	# HIRAGANA LETTER BU
0x2457	0x3077	# HIRAGANA LETTER PU
0x2458	0x3078	# HIRAGANA LETTER HE
0x2459	0x3079	# HIRAGANA LETTER BE
0x245A	0x307A	# HIRAGANA LETTER PE
0x245B	0x307B	# HIRAGANA LETTER HO
0x245C	0x307C	# HIRAGANA LETTER BO
0x245D	0x307D	# HIRAGANA LETTER PO
0x245E	0x307E	# HIRAGANA LETTER MA
0x245F	0x307F	# HIRAGANA LETTER MI
0x2460	0x3080	# HIRAGANA LETTER MU
0x2461	0x3081	# HIRAGANA LETTER ME
0x2462	0x3082	# HIRAGANA LETTER MO
0x2463	0x3083	# HIRAGANA LETTER SMALL YA
0x2464	0x3084	# HIRAGANA LETTER YA
0x2465	0x3085	# HIRAGANA LETTER SMALL YU
0x2466	0x3086	# HIRAGANA LETTER YU
0x2467	0x3087	# HIRAGANA LETTER SMALL YO
0x2468	0x3088	# HIRAGANA LETTER YO
0x2469	0x3089	# HIRAGANA LETTER RA
0x246A	0x308A	# HIRAGANA LETTER RI
0x246B	0x308B	# HIRAGANA LETTER RU
0x246C	0x308C	# HIRAGANA LETTER RE
0x246D	0x308D	# HIRAGANA LETTER RO
0x246E	0x308E	# HIRAGANA LETTER SMALL WA
0x246F	0x308F	# HIRAGANA LETTER WA
0x2470	0x3090	# HIRAGANA LETTER WI
0x2471	0x3091	# HIRAGANA LETTER WE
0x2472	0x3092	# HIRAGANA LETTER WO
0x2473	0x3093	# HIRAGANA LETTER N
0x2521	0x30A1	# KATAKANA LETTER SMALL A
0x2522	0x30A2	# KATAKANA LETTER A
0x2523	0x30A3	# KATAKANA LETTER SMALL I
0x2524	0x30A4	# KATAKANA LETTER I
0x2525	0x30A5	# KATAKANA LETTER SMALL U
0x2526	0x30A6	# KATAKANA LETTER U
0x2527	0x30A7	# KATAKANA LETTER SMALL E
0x2528	0x30A8	# KATAKANA LETTER E
0x2529	0x30A9	# KATAKANA LETTER SMALL O
0x252A	0x30AA	# KATAKANA LETTER O
0x252B	0x30AB	# KATAKANA LETTER KA
0x252C	0x30AC	# KATAKANA LETTER GA
0x252D	0x30AD	# KATAKANA LETTER KI
0x252E	0x30AE	# KATAKANA LETTER GI
0x252F	0x30AF	# KATAKANA LETTER KU
0x2530	0x30B0	# KATAKANA LETTER GU
0x2531	0x30B1	# KATAKANA LETTER KE
0x2532	0x30B2	# KATAKANA LETTER GE
0x2533	0x30B3	# KATAKANA LETTER KO
0x2534	0x30B4	# KATAKANA LETTER GO
0x2535	0x30B5	# KATAKANA LETTER SA
0x2536	0x30B6	# KATAKANA LETTER ZA
0x2537	0x30B7	# KATAKANA LETTER SI
0x2538	0x30B8	# KATAKANA LETTER ZI
0x2539	0x30B9	# KATAKANA LETTER SU
0x253A	0x30BA	# KATAKANA LETTER ZU
0x253B	0x30BB	# KATAKANA LETTER SE
0x253C	0x30BC	# KATAKANA LETTER ZE
0x253D	0x30BD	# KATAKANA LETTER SO
0x253E	0x30BE	# KATAKANA LETTER ZO
0x253F	0x30BF	# KATAKANA LETTER TA
0x2540	0x30C0	# KATAKANA LETTER DA
0x2541	0x30C1	# KATAKANA LETTER TI
0x2542	0x30C2	# KATAKANA LETTER DI
0x2543	0x30C3	# KATAKANA LETTER SMALL TU
0x2544	0x30C4	# KATAKANA LETTER TU
0x2545	0x30C5	# KATAKANA LETTER DU
0x2546	0x30C6	# KATAKANA LETTER TE
0x2547	0x30C7	# KATAKANA LETTER DE
0x2548	0x30C8	# KATAKANA LETTER TO
0x2549	0x30C9	# KATAKANA LETTER DO
0x254A	0x30CA	# KATAKANA LETTER NA
0x254B	0x30CB	# KATAKANA LETTER NI
0x254C	0x30CC	# KATAKANA LETTER NU
0x254D	0x30CD	# KATAKANA LETTER NE
0x254E	0x30CE	# KATAKANA LETTER NO
0x254F	0x30CF	# KATAKANA LETTER HA
0x2550	0x30D0	# KATAKANA LETTER BA
0x2551	0x30D1	# KATAKANA LETTER PA
0x2552	0x30D2	# KATAKANA LETTER HI
0x2553	0x30D3	# KATAKANA LETTER BI
0x2554	0x30D4	# KATAKANA LETTER PI
0x2555	0x30D5	# KATAKANA LETTER HU
0x2556	0x30D6	# KATAKANA LETTER BU
0x2557	0x30D7	# KATAKANA LETTER PU
0x2558	0x30D8	# KATAKANA LETTER HE
0x2559	0x30D9	# KATAKANA LETTER BE
0x255A	0x30DA	# KATAKANA LETTER PE
0x255B	0x30DB	# KATAKANA LETTER HO
0x255C	0x30DC	# KATAKANA LETTER BO
0x255D	0x30DD	# KATAKANA LETTER PO
0x255E	0x30DE	# KATAKANA LETTER MA
0x255F	0x30DF	# KATAKANA LETTER MI
0x2560	0x30E0	# KATAKANA LETTER MU
0x2561	0x30E1	# KATAKANA LETTER ME
0x2562	0x30E2	# KATAKANA LETTER MO
0x2563	0x30E3	# KATAKANA LETTER SMALL YA
0x2564	0x30E4	# KATAKANA LETTER YA
0x2565	0x30E5	# KATAKANA LETTER SMALL YU
0x2566	0x30E6	# KATAKANA LETTER YU
0x2567	0x30E7	# KATAKANA LETTER SMALL YO
0x2568	0x30E8	# KATAKANA LETTER YO
0x2569	0x30E9	# KATAKANA LETTER RA
0x256A	0x30EA	# KATAKANA LETTER RI
0x256B	0x30EB	# KATAKANA LETTER RU
0x256C	0x30EC	# KATAKANA LETTER RE
0x256D	0x30ED	# KATAKANA LETTER RO
0x256E	0x30EE	# KATAKANA LETTER SMALL WA
0x256F	0x30EF	# KATAKANA LETTER WA
0x2570	0x30F0	# KATAKANA LETTER WI
0x2571	0x30F1	# KATAKANA LETTER WE
0x2572	0x30F2	# KATAKANA LETTER WO
0x2573	0x30F3	# KATAKANA LETTER N
0x2574	0x30F4	# KATAKANA LETTER VU
0x2575	0x30F5	# KATAKANA LETTER SMALL KA
0x2576	0x30F6	# KATAKANA LETTER SMALL KE
0x2621	0x0391	# GREEK CAPITAL LETTER ALPHA
0x2622	0x0392	# GREEK CAPITAL LETTER BETA
0x2623	0x0393	# GREEK CAPITAL LETTER GAMMA
0x2624	0x0394	# GREEK CAPITAL LETTER DELTA
0x2625	0x0395	# GREEK CAPITAL LETTER EPSILON
0x2626	0x0396	# GREEK CAPITAL LETTER ZETA
0x2627	0x0397	# GREEK CAPITAL LETTER ETA
0x2628	0x0398	# GREEK CAPITAL LETTER THETA
0x2629	0x0399	# GREEK CAPITAL LETTER IOTA
0x262A	0x039A	# GREEK CAPITAL LETTER KAPPA
0x262B	0x039B	# GREEK CAPITAL LETTER LAMDA
0x262C	0x039C	# GREEK CAPITAL LETTER MU
0x262D	0x039D	# GREEK CAPITAL LETTER NU
0x262E	0x039E	# GREEK CAPITAL LETTER XI
0x262F	0x039F	# GREEK CAPITAL LETTER OMICRON
0x2630	0x03A0	# GREEK CAPITAL LETTER PI
0x2631	0x03A1	# GREEK CAPITAL LETTER RHO
0x2632	0x03A3	# GREEK CAPITAL LETTER SIGMA
0x2633	0x03A4	# GREEK CAPITAL LETTER TAU
0x2634	0x03A5	# GREEK CAPITAL LETTER UPSILON
0x2635	0x03A6	# GREEK CAPITAL LETTER PHI
0x2636	0x03A7	# GREEK CAPITAL LETTER CHI
0x2637	0x03A8	# GREEK CAPITAL LETTER PSI
0x2638	0x03A9	# GREEK CAPITAL LETTER OMEGA
0x2641	0x03B1	# GREEK SMALL LETTER ALPHA
0x2642	0x03B2	# GREEK SMALL LETTER BETA
0x2643	0x03B3	# GREEK SMALL LETTER GAMMA
0x2644	0x03B4	# GREEK SMALL LETTER DELTA
0x2645	0x03B5	# GREEK SMALL LETTER EPSILON
0x2646	0x03B6	# GREEK SMALL LETTER ZETA
0x2647	0x03B7	# GREEK SMALL LETTER ETA
0x2648	0x03B8	# GREEK SMALL LETTER THETA
0x2649	0x03B9	# GREEK SMALL LETTER IOTA
0x264A	0x03BA	# GREEK SMALL LETTER KAPPA
0x264B	0x03BB	# GREEK SMALL LETTER LAMDA
0x264C	0x03BC	# GREEK SMALL LETTER MU
0x264D	0x03BD	# GREEK SMALL LETTER NU
0x264E	0x03BE	# GREEK SMALL LETTER XI
0x264F	0x03BF	# GREEK SMALL LETTER OMICRON
0x2650	0x03C0	# GREEK SMALL LETTER PI
0x2651	0x03C1	# GREEK SMALL LETTER RHO
0x2652	0x03C3	# GREEK SMALL LETTER SIGMA
0x2653	0x03C4	# GREEK SMALL LETTER TAU
0x2654	0x03C5	# GREEK SMALL LETTER UPSILON
0x2655	0x03C6	# GREEK SMALL LETTER PHI
0x2656	0x03C7	# GREEK SMALL LETTER CHI
0x2657	0x03C8	# GREEK SMALL LETTER PSI
0x2658	0x03C9	# GREEK SMALL LETTER OMEGA
0x2721	0x0410	# CYRILLIC CAPITAL LETTER A
0x2722	0x0411	# CYRILLIC CAPITAL LETTER BE
0x2723	0x0412	# CYRILLIC CAPITAL LETTER VE
0x2724	0x0413	# CYRILLIC CAPITAL LETTER GHE
0x2725	0x0414	# CYRILLIC CAPITAL LETTER DE
0x2726	0x0415	# CYRILLIC CAPITAL LETTER IE
0x2727	0x0401	# CYRILLIC CAPITAL LETTER IO
0x2728	0x0416	# CYRILLIC CAPITAL LETTER ZHE
0x2729	0x0417	# CYRILLIC CAPITAL LETTER ZE
0x272A	0x0418	# CYRILLIC CAPITAL LETTER I
0x272B	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
0x272C	0x041A	# CYRILLIC CAPITAL LETTER KA
0x272D	0x041B	# CYRILLIC CAPITAL LETTER EL
0x272E	0x041C	# CYRILLIC CAPITAL LETTER EM
0x272F	0x041D	# CYRILLIC CAPITAL LETTER EN
0x2730	0x041E	# CYRILLIC CAPITAL LETTER O
0x2731	0x041F	# CYRILLIC CAPITAL LETTER PE
0x2732	0x0420	# CYRILLIC CAPITAL LETTER ER
0x2733	0x0421	# CYRILLIC CAPITAL LETTER ES
0x2734	0x0422	# CYRILLIC CAPITAL LETTER TE
0x2735	0x0423	# CYRILLIC CAPITAL LETTER U
0x2736	0x0424	# CYRILLIC CAPITAL LETTER EF
0x2737	0x0425	# CYRILLIC CAPITAL LETTER HA
0x2738	0x0426	# CYRILLIC CAPITAL LETTER TSE
0x2739	0x0427	# CYRILLIC CAPITAL LETTER CHE
0x273A	0x0428	# CYRILLIC CAPITAL LETTER SHA
0x273B	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
0x273C	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
0x273D	0x042B	# CYRILLIC CAPITAL LETTER YERU
0x273E	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
0x273F	0x042D	# CYRILLIC CAPITAL LETTER E
0x2740	0x042E	# CYRILLIC CAPITAL LETTER YU
0x2741	0x042F	# CYRILLIC CAPITAL LETTER YA
0x2751	0x0430	# CYRILLIC SMALL LETTER A
0x2752	0x0431	# CYRILLIC SMALL LETTER BE
0x2753	0x0432	# CYRILLIC SMALL LETTER VE
0x2754	0x0433	# CYRILLIC SMALL LETTER GHE
0x2755	0x0434	# CYRILLIC SMALL LETTER DE
0x2756	0x0435	# CYRILLIC SMALL LETTER IE
0x2757	0x0451	# CYRILLIC SMALL LETTER IO
0x2758	0x0436	# CYRILLIC SMALL LETTER ZHE
0x2759	0x0437	# CYRILLIC SMALL LETTER ZE
0x275A	0x0438	# CYRILLIC SMALL LETTER I
0x275B	0x0439	# CYRILLIC SMALL LETTER SHORT I
0x275C	0x043A	# CYRILLIC SMALL LETTER KA
0x275D	0x043B	# CYRILLIC SMALL LETTER EL
0x275E	0x043C	# CYRILLIC SMALL LETTER EM
0x275F	0x043D	# CYRILLIC SMALL LETTER EN
0x2760	0x043E	# CYRILLIC SMALL LETTER O
0x2761	0x043F	# CYRILLIC SMALL LETTER PE
0x2762	0x0440	# CYRILLIC SMALL LETTER ER
0x2763	0x0441	# CYRILLIC SMALL LETTER ES
0x2764	0x0442	# CYRILLIC SMALL LETTER TE
0x2765	0x0443	# CYRILLIC SMALL LETTER U
0x2766	0x0444	# CYRILLIC SMALL LETTER EF
0x2767	0x0445	# CYRILLIC SMALL LETTER HA
0x2768	0x0446	# CYRILLIC SMALL LETTER TSE
0x2769	0x0447	# CYRILLIC SMALL LETTER CHE
0x276A	0x0448	# CYRILLIC SMALL LETTER SHA
0x276B	0x0449	# CYRILLIC SMALL LETTER SHCHA
0x276C	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
0x276D	0x044B	# CYRILLIC SMALL LETTER YERU
0x276E	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
0x276F	0x044D	# CYRILLIC SMALL LETTER E
0x2770	0x044E	# CYRILLIC SMALL LETTER YU
0x2771	0x044F	# CYRILLIC SMALL LETTER YA
0x2821	0x0101	# LATIN SMALL LETTER A WITH MACRON
0x2822	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
0x2823	0x01CE	# LATIN SMALL LETTER A WITH CARON
0x2824	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
0x2825	0x0113	# LATIN SMALL LETTER E WITH MACRON
0x2826	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
0x2827	0x011B	# LATIN SMALL LETTER E WITH CARON
0x2828	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
0x2829	0x012B	# LATIN SMALL LETTER I WITH MACRON
0x282A	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
0x282B	0x01D0	# LATIN SMALL LETTER I WITH CARON
0x282C	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
0x282D	0x014D	# LATIN SMALL LETTER O WITH MACRON
0x282E	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
0x282F	0x01D2	# LATIN SMALL LETTER O WITH CARON
0x2830	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
0x2831	0x016B	# LATIN SMALL LETTER U WITH MACRON
0x2832	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
0x2833	0x01D4	# LATIN SMALL LETTER U WITH CARON
0x2834	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
0x2835	0x01D6	# LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
0x2836	0x01D8	# LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
0x2837	0x01DA	# LATIN SMALL LETTER U WITH DIAERESIS AND CARON
0x2838	0x01DC	# LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
0x2839	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
0x283A	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
0x2845	0x3105	# BOPOMOFO LETTER B
0x2846	0x3106	# BOPOMOFO LETTER P
0x2847	0x3107	# BOPOMOFO LETTER M
0x2848	0x3108	# BOPOMOFO LETTER F
0x2849	0x3109	# BOPOMOFO LETTER D
0x284A	0x310A	# BOPOMOFO LETTER T
0x284B	0x310B	# BOPOMOFO LETTER N
0x284C	0x310C	# BOPOMOFO LETTER L
0x284D	0x310D	# BOPOMOFO LETTER G
0x284E	0x310E	# BOPOMOFO LETTER K
0x284F	0x310F	# BOPOMOFO LETTER H
0x2850	0x3110	# BOPOMOFO LETTER J
0x2851	0x3111	# BOPOMOFO LETTER Q
0x2852	0x3112	# BOPOMOFO LETTER X
0x2853	0x3113	# BOPOMOFO LETTER ZH
0x2854	0x3114	# BOPOMOFO LETTER CH
0x2855	0x3115	# BOPOMOFO LETTER SH
0x2856	0x3116	# BOPOMOFO LETTER R
0x2857	0x3117	# BOPOMOFO LETTER Z
0x2858	0x3118	# BOPOMOFO LETTER C
0x2859	0x3119	# BOPOMOFO LETTER S
0x285A	0x311A	# BOPOMOFO LETTER A
0x285B	0x311B	# BOPOMOFO LETTER O
0x285C	0x311C	# BOPOMOFO LETTER E
0x285D	0x311D	# BOPOMOFO LETTER EH
0x285E	0x311E	# BOPOMOFO LETTER AI
0x285F	0x311F	# BOPOMOFO LETTER EI
0x2860	0x3120	# BOPOMOFO LETTER AU
0x2861	0x3121	# BOPOMOFO LETTER OU
0x2862	0x3122	# BOPOMOFO LETTER AN
0x2863	0x3123	# BOPOMOFO LETTER EN
0x2864	0x3124	# BOPOMOFO LETTER ANG
0x2865	0x3125	# BOPOMOFO LETTER ENG
0x2866	0x3126	# BOPOMOFO LETTER ER
0x2867	0x3127	# BOPOMOFO LETTER I
0x2868	0x3128	# BOPOMOFO LETTER U
0x2869	0x3129	# BOPOMOFO LETTER IU
0x2924	0x2500	# BOX DRAWINGS LIGHT HORIZONTAL
0x2925	0x2501	# BOX DRAWINGS HEAVY HORIZONTAL
0x2926	0x2502	# BOX DRAWINGS LIGHT VERTICAL
0x2927	0x2503	# BOX DRAWINGS HEAVY VERTICAL
0x2928	0x2504	# BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL
0x2929	0x2505	# BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL
0x292A	0x2506	# BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL
0x292B	0x2507	# BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL
0x292C	0x2508	# BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL
0x292D	0x2509	# BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL
0x292E	0x250A	# BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL
0x292F	0x250B	# BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL
0x2930	0x250C	# BOX DRAWINGS LIGHT DOWN AND RIGHT
0x2931	0x250D	# BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
0x2932	0x250E	# BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
0x2933	0x250F	# BOX DRAWINGS HEAVY DOWN AND RIGHT
0x2934	0x2510	# BOX DRAWINGS LIGHT DOWN AND LEFT
0x2935	0x2511	# BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
0x2936	0x2512	# BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
0x2937	0x2513	# BOX DRAWINGS HEAVY DOWN AND LEFT
0x2938	0x2514	# BOX DRAWINGS LIGHT UP AND RIGHT
0x2939	0x2515	# BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
0x293A	0x2516	# BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
0x293B	0x2517	# BOX DRAWINGS HEAVY UP AND RIGHT
0x293C	0x2518	# BOX DRAWINGS LIGHT UP AND LEFT
0x293D	0x2519	# BOX DRAWINGS UP LIGHT AND LEFT HEAVY
0x293E	0x251A	# BOX DRAWINGS UP HEAVY AND LEFT LIGHT
0x293F	0x251B	# BOX DRAWINGS HEAVY UP AND LEFT
0x2940	0x251C	# BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0x2941	0x251D	# BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
0x2942	0x251E	# BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
0x2943	0x251F	# BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
0x2944	0x2520	# BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
0x2945	0x2521	# BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
0x2946	0x2522	# BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
0x2947	0x2523	# BOX DRAWINGS HEAVY VERTICAL AND RIGHT
0x2948	0x2524	# BOX DRAWINGS LIGHT VERTICAL AND LEFT
0x2949	0x2525	# BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
0x294A	0x2526	# BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
0x294B	0x2527	# BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
0x294C	0x2528	# BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
0x294D	0x2529	# BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
0x294E	0x252A	# BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
0x294F	0x252B	# BOX DRAWINGS HEAVY VERTICAL AND LEFT
0x2950	0x252C	# BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0x2951	0x252D	# BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
0x2952	0x252E	# BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
0x2953	0x252F	# BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
0x2954	0x2530	# BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
0x2955	0x2531	# BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
0x2956	0x2532	# BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
0x2957	0x2533	# BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
0x2958	0x2534	# BOX DRAWINGS LIGHT UP AND HORIZONTAL
0x2959	0x2535	# BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
0x295A	0x2536	# BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
0x295B	0x2537	# BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
0x295C	0x2538	# BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
0x295D	0x2539	# BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
0x295E	0x253A	# BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
0x295F	0x253B	# BOX DRAWINGS HEAVY UP AND HORIZONTAL
0x2960	0x253C	# BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0x2961	0x253D	# BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
0x2962	0x253E	# BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
0x2963	0x253F	# BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
0x2964	0x2540	# BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
0x2965	0x2541	# BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
0x2966	0x2542	# BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
0x2967	0x2543	# BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
0x2968	0x2544	# BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
0x2969	0x2545	# BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
0x296A	0x2546	# BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
0x296B	0x2547	# BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
0x296C	0x2548	# BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
0x296D	0x2549	# BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
0x296E	0x254A	# BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
0x296F	0x254B	# BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
0x3021	0x554A	# <CJK>
0x3022	0x963F	# <CJK>
0x3023	0x57C3	# <CJK>
0x3024	0x6328	# <CJK>
0x3025	0x54CE	# <CJK>
0x3026	0x5509	# <CJK>
0x3027	0x54C0	# <CJK>
0x3028	0x769A	# <CJK>
0x3029	0x764C	# <CJK>
0x302A	0x85F9	# <CJK>
0x302B	0x77EE	# <CJK>
0x302C	0x827E	# <CJK>
0x302D	0x7919	# <CJK>
0x302E	0x611B	# <CJK>
0x302F	0x9698	# <CJK>
0x3030	0x978D	# <CJK>
0x3031	0x6C28	# <CJK>
0x3032	0x5B89	# <CJK>
0x3033	0x4FFA	# <CJK>
0x3034	0x6309	# <CJK>
0x3035	0x6697	# <CJK>
0x3036	0x5CB8	# <CJK>
0x3037	0x80FA	# <CJK>
0x3038	0x6848	# <CJK>
0x3039	0x9AAF	# <CJK>
0x303A	0x6602	# <CJK>
0x303B	0x76CE	# <CJK>
0x303C	0x51F9	# <CJK>
0x303D	0x6556	# <CJK>
0x303E	0x71AC	# <CJK>
0x303F	0x7FF1	# <CJK>
0x3040	0x8956	# <CJK>
0x3041	0x50B2	# <CJK>
0x3042	0x5965	# <CJK>
0x3043	0x61CA	# <CJK>
0x3044	0x6FB3	# <CJK>
0x3045	0x82AD	# <CJK>
0x3046	0x634C	# <CJK>
0x3047	0x6252	# <CJK>
0x3048	0x53ED	# <CJK>
0x3049	0x5427	# <CJK>
0x304A	0x7B06	# <CJK>
0x304B	0x516B	# <CJK>
0x304C	0x75A4	# <CJK>
0x304D	0x5DF4	# <CJK>
0x304E	0x62D4	# <CJK>
0x304F	0x8DCB	# <CJK>
0x3050	0x9776	# <CJK>
0x3051	0x628A	# <CJK>
0x3052	0x8019	# <CJK>
0x3053	0x58E9	# <CJK>
0x3054	0x9738	# <CJK>
0x3055	0x7F77	# <CJK>
0x3056	0x7238	# <CJK>
0x3057	0x767D	# <CJK>
0x3058	0x67CF	# <CJK>
0x3059	0x767E	# <CJK>
0x305A	0x64FA	# <CJK>
0x305B	0x4F70	# <CJK>
0x305C	0x6557	# <CJK>
0x305D	0x62DC	# <CJK>
0x305E	0x7A17	# <CJK>
0x305F	0x6591	# <CJK>
0x3060	0x73ED	# <CJK>
0x3061	0x642C	# <CJK>
0x3062	0x6273	# <CJK>
0x3063	0x822C	# <CJK>
0x3064	0x9812	# <CJK>
0x3065	0x677F	# <CJK>
0x3066	0x7248	# <CJK>
0x3067	0x626E	# <CJK>
0x3068	0x62CC	# <CJK>
0x3069	0x4F34	# <CJK>
0x306A	0x74E3	# <CJK>
0x306B	0x534A	# <CJK>
0x306C	0x8FA6	# <CJK>
0x306D	0x7D46	# <CJK>
0x306E	0x90A6	# <CJK>
0x306F	0x5E6B	# <CJK>
0x3070	0x6886	# <CJK>
0x3071	0x699C	# <CJK>
0x3072	0x8180	# <CJK>
0x3073	0x7D81	# <CJK>
0x3074	0x68D2	# <CJK>
0x3075	0x78C5	# <CJK>
0x3076	0x868C	# <CJK>
0x3077	0x938A	# <CJK>
0x3078	0x508D	# <CJK>
0x3079	0x8B17	# <CJK>
0x307A	0x82DE	# <CJK>
0x307B	0x80DE	# <CJK>
0x307C	0x5305	# <CJK>
0x307D	0x8912	# <CJK>
0x307E	0x5265	# <CJK>
0x3121	0x8584	# <CJK>
0x3122	0x96F9	# <CJK>
0x3123	0x4FDD	# <CJK>
0x3124	0x5821	# <CJK>
0x3125	0x98FD	# <CJK>
0x3126	0x5BF6	# <CJK>
0x3127	0x62B1	# <CJK>
0x3128	0x5831	# <CJK>
0x3129	0x66B4	# <CJK>
0x312A	0x8C79	# <CJK>
0x312B	0x9B91	# <CJK>
0x312C	0x7206	# <CJK>
0x312D	0x676F	# <CJK>
0x312E	0x7891	# <CJK>
0x312F	0x60B2	# <CJK>
0x3130	0x5351	# <CJK>
0x3131	0x5317	# <CJK>
0x3132	0x8F29	# <CJK>
0x3133	0x80CC	# <CJK>
0x3134	0x8C9D	# <CJK>
0x3135	0x92C7	# <CJK>
0x3136	0x500D	# <CJK>
0x3137	0x72FD	# <CJK>
0x3138	0x5099	# <CJK>
0x3139	0x618A	# <CJK>
0x313A	0x7119	# <CJK>
0x313B	0x88AB	# <CJK>
0x313C	0x5954	# <CJK>
0x313D	0x82EF	# <CJK>
0x313E	0x672C	# <CJK>
0x313F	0x7B28	# <CJK>
0x3140	0x5D29	# <CJK>
0x3141	0x7DB3	# <CJK>
0x3142	0x752D	# <CJK>
0x3143	0x6CF5	# <CJK>
0x3144	0x8E66	# <CJK>
0x3145	0x8FF8	# <CJK>
0x3146	0x903C	# <CJK>
0x3147	0x9F3B	# <CJK>
0x3148	0x6BD4	# <CJK>
0x3149	0x9119	# <CJK>
0x314A	0x7B46	# <CJK>
0x314B	0x5F7C	# <CJK>
0x314C	0x78A7	# <CJK>
0x314D	0x84D6	# <CJK>
0x314E	0x853D	# <CJK>
0x314F	0x7562	# <CJK>
0x3150	0x6583	# <CJK>
0x3151	0x6BD6	# <CJK>
0x3152	0x5E63	# <CJK>
0x3153	0x5E87	# <CJK>
0x3154	0x75F9	# <CJK>
0x3155	0x9589	# <CJK>
0x3156	0x655D	# <CJK>
0x3157	0x5F0A	# <CJK>
0x3158	0x5FC5	# <CJK>
0x3159	0x8F9F	# <CJK>
0x315A	0x58C1	# <CJK>
0x315B	0x81C2	# <CJK>
0x315C	0x907F	# <CJK>
0x315D	0x965B	# <CJK>
0x315E	0x97AD	# <CJK>
0x315F	0x908A	# <CJK>
0x3160	0x7DE8	# <CJK>
0x3161	0x8CB6	# <CJK>
0x3162	0x6241	# <CJK>
0x3163	0x4FBF	# <CJK>
0x3164	0x8B8A	# <CJK>
0x3165	0x535E	# <CJK>
0x3166	0x8FA8	# <CJK>
0x3167	0x8FAF	# <CJK>
0x3168	0x8FAE	# <CJK>
0x3169	0x904D	# <CJK>
0x316A	0x6A19	# <CJK>
0x316B	0x5F6A	# <CJK>
0x316C	0x8198	# <CJK>
0x316D	0x8868	# <CJK>
0x316E	0x9C49	# <CJK>
0x316F	0x618B	# <CJK>
0x3170	0x522B	# <CJK>
0x3171	0x765F	# <CJK>
0x3172	0x5F6C	# <CJK>
0x3173	0x658C	# <CJK>
0x3174	0x7015	# <CJK>
0x3175	0x6FF1	# <CJK>
0x3176	0x8CD3	# <CJK>
0x3177	0x64EF	# <CJK>
0x3178	0x5175	# <CJK>
0x3179	0x51B0	# <CJK>
0x317A	0x67C4	# <CJK>
0x317B	0x4E19	# <CJK>
0x317C	0x79C9	# <CJK>
0x317D	0x9905	# <CJK>
0x317E	0x70B3	# <CJK>
0x3221	0x75C5	# <CJK>
0x3222	0x5E76	# <CJK>
0x3223	0x73BB	# <CJK>
0x3224	0x83E0	# <CJK>
0x3225	0x64AD	# <CJK>
0x3226	0x64A5	# <CJK>
0x3227	0x9262	# <CJK>
0x3228	0x6CE2	# <CJK>
0x3229	0x535A	# <CJK>
0x322A	0x52C3	# <CJK>
0x322B	0x640F	# <CJK>
0x322C	0x9251	# <CJK>
0x322D	0x7B94	# <CJK>
0x322E	0x4F2F	# <CJK>
0x322F	0x5E1B	# <CJK>
0x3230	0x8236	# <CJK>
0x3231	0x8116	# <CJK>
0x3232	0x818A	# <CJK>
0x3233	0x6E24	# <CJK>
0x3234	0x6CCA	# <CJK>
0x3235	0x99C1	# <CJK>
0x3236	0x6355	# <CJK>
0x3237	0x535C	# <CJK>
0x3238	0x54FA	# <CJK>
0x3239	0x88DC	# <CJK>
0x323A	0x57E0	# <CJK>
0x323B	0x4E0D	# <CJK>
0x323C	0x5E03	# <CJK>
0x323D	0x6B65	# <CJK>
0x323E	0x7C3F	# <CJK>
0x323F	0x90E8	# <CJK>
0x3240	0x6016	# <CJK>
0x3241	0x64E6	# <CJK>
0x3242	0x731C	# <CJK>
0x3243	0x88C1	# <CJK>
0x3244	0x6750	# <CJK>
0x3245	0x624D	# <CJK>
0x3246	0x8CA1	# <CJK>
0x3247	0x776C	# <CJK>
0x3248	0x8E29	# <CJK>
0x3249	0x91C7	# <CJK>
0x324A	0x5F69	# <CJK>
0x324B	0x83DC	# <CJK>
0x324C	0x8521	# <CJK>
0x324D	0x9910	# <CJK>
0x324E	0x53C3	# <CJK>
0x324F	0x8836	# <CJK>
0x3250	0x6B98	# <CJK>
0x3251	0x615A	# <CJK>
0x3252	0x6158	# <CJK>
0x3253	0x71E6	# <CJK>
0x3254	0x84BC	# <CJK>
0x3255	0x8259	# <CJK>
0x3256	0x5009	# <CJK>
0x3257	0x6EC4	# <CJK>
0x3258	0x85CF	# <CJK>
0x3259	0x64CD	# <CJK>
0x325A	0x7CD9	# <CJK>
0x325B	0x69FD	# <CJK>
0x325C	0x66F9	# <CJK>
0x325D	0x8349	# <CJK>
0x325E	0x53A0	# <CJK>
0x325F	0x7B56	# <CJK>
0x3260	0x5074	# <CJK>
0x3261	0x518C	# <CJK>
0x3262	0x6E2C	# <CJK>
0x3263	0x5C64	# <CJK>
0x3264	0x8E6D	# <CJK>
0x3265	0x63D2	# <CJK>
0x3266	0x53C9	# <CJK>
0x3267	0x832C	# <CJK>
0x3268	0x8336	# <CJK>
0x3269	0x67E5	# <CJK>
0x326A	0x78B4	# <CJK>
0x326B	0x643D	# <CJK>
0x326C	0x5BDF	# <CJK>
0x326D	0x5C94	# <CJK>
0x326E	0x5DEE	# <CJK>
0x326F	0x8A6B	# <CJK>
0x3270	0x62C6	# <CJK>
0x3271	0x67F4	# <CJK>
0x3272	0x8C7A	# <CJK>
0x3273	0x6519	# <CJK>
0x3274	0x647B	# <CJK>
0x3275	0x87EC	# <CJK>
0x3276	0x995E	# <CJK>
0x3277	0x8B92	# <CJK>
0x3278	0x7E8F	# <CJK>
0x3279	0x93DF	# <CJK>
0x327A	0x7523	# <CJK>
0x327B	0x95E1	# <CJK>
0x327C	0x986B	# <CJK>
0x327D	0x660C	# <CJK>
0x327E	0x7316	# <CJK>
0x3321	0x5834	# <CJK>
0x3322	0x5617	# <CJK>
0x3323	0x5E38	# <CJK>
0x3324	0x9577	# <CJK>
0x3325	0x511F	# <CJK>
0x3326	0x8178	# <CJK>
0x3327	0x5EE0	# <CJK>
0x3328	0x655E	# <CJK>
0x3329	0x66A2	# <CJK>
0x332A	0x5531	# <CJK>
0x332B	0x5021	# <CJK>
0x332C	0x8D85	# <CJK>
0x332D	0x6284	# <CJK>
0x332E	0x9214	# <CJK>
0x332F	0x671D	# <CJK>
0x3330	0x5632	# <CJK>
0x3331	0x6F6E	# <CJK>
0x3332	0x5DE2	# <CJK>
0x3333	0x5435	# <CJK>
0x3334	0x7092	# <CJK>
0x3335	0x8ECA	# <CJK>
0x3336	0x626F	# <CJK>
0x3337	0x64A4	# <CJK>
0x3338	0x63A3	# <CJK>
0x3339	0x5FB9	# <CJK>
0x333A	0x6F88	# <CJK>
0x333B	0x90F4	# <CJK>
0x333C	0x81E3	# <CJK>
0x333D	0x8FB0	# <CJK>
0x333E	0x5875	# <CJK>
0x333F	0x6668	# <CJK>
0x3340	0x5FF1	# <CJK>
0x3341	0x6C89	# <CJK>
0x3342	0x9673	# <CJK>
0x3343	0x8D81	# <CJK>
0x3344	0x896F	# <CJK>
0x3345	0x6491	# <CJK>
0x3346	0x7A31	# <CJK>
0x3347	0x57CE	# <CJK>
0x3348	0x6A59	# <CJK>
0x3349	0x6210	# <CJK>
0x334A	0x5448	# <CJK>
0x334B	0x4E58	# <CJK>
0x334C	0x7A0B	# <CJK>
0x334D	0x61F2	# <CJK>
0x334E	0x6F84	# <CJK>
0x334F	0x8AA0	# <CJK>
0x3350	0x627F	# <CJK>
0x3351	0x901E	# <CJK>
0x3352	0x9A01	# <CJK>
0x3353	0x79E4	# <CJK>
0x3354	0x5403	# <CJK>
0x3355	0x75F4	# <CJK>
0x3356	0x6301	# <CJK>
0x3357	0x5319	# <CJK>
0x3358	0x6C60	# <CJK>
0x3359	0x9072	# <CJK>
0x335A	0x5F1B	# <CJK>
0x335B	0x99B3	# <CJK>
0x335C	0x803B	# <CJK>
0x335D	0x9F52	# <CJK>
0x335E	0x4F88	# <CJK>
0x335F	0x5C3A	# <CJK>
0x3360	0x8D64	# <CJK>
0x3361	0x7FC5	# <CJK>
0x3362	0x65A5	# <CJK>
0x3363	0x71BE	# <CJK>
0x3364	0x5145	# <CJK>
0x3365	0x885D	# <CJK>
0x3366	0x87F2	# <CJK>
0x3367	0x5D07	# <CJK>
0x3368	0x5BF5	# <CJK>
0x3369	0x62BD	# <CJK>
0x336A	0x916C	# <CJK>
0x336B	0x7587	# <CJK>
0x336C	0x8E8A	# <CJK>
0x336D	0x7A20	# <CJK>
0x336E	0x6101	# <CJK>
0x336F	0x7C4C	# <CJK>
0x3370	0x4EC7	# <CJK>
0x3371	0x7DA2	# <CJK>
0x3372	0x7785	# <CJK>
0x3373	0x919C	# <CJK>
0x3374	0x81ED	# <CJK>
0x3375	0x521D	# <CJK>
0x3376	0x51FA	# <CJK>
0x3377	0x6A71	# <CJK>
0x3378	0x53A8	# <CJK>
0x3379	0x8E87	# <CJK>
0x337A	0x92E4	# <CJK>
0x337B	0x96DB	# <CJK>
0x337C	0x6EC1	# <CJK>
0x337D	0x9664	# <CJK>
0x337E	0x695A	# <CJK>
0x3421	0x790E	# <CJK>
0x3422	0x5132	# <CJK>
0x3423	0x77D7	# <CJK>
0x3424	0x6410	# <CJK>
0x3425	0x89F8	# <CJK>
0x3426	0x8655	# <CJK>
0x3427	0x63E3	# <CJK>
0x3428	0x5DDD	# <CJK>
0x3429	0x7A7F	# <CJK>
0x342A	0x693D	# <CJK>
0x342B	0x50B3	# <CJK>
0x342C	0x8239	# <CJK>
0x342D	0x5598	# <CJK>
0x342E	0x4E32	# <CJK>
0x342F	0x7621	# <CJK>
0x3430	0x7A97	# <CJK>
0x3431	0x5E62	# <CJK>
0x3432	0x5E8A	# <CJK>
0x3433	0x95D6	# <CJK>
0x3434	0x5275	# <CJK>
0x3435	0x5439	# <CJK>
0x3436	0x708A	# <CJK>
0x3437	0x6376	# <CJK>
0x3438	0x9318	# <CJK>
0x3439	0x5782	# <CJK>
0x343A	0x6625	# <CJK>
0x343B	0x693F	# <CJK>
0x343C	0x9187	# <CJK>
0x343D	0x5507	# <CJK>
0x343E	0x6DF3	# <CJK>
0x343F	0x7D14	# <CJK>
0x3440	0x8822	# <CJK>
0x3441	0x6233	# <CJK>
0x3442	0x7DBD	# <CJK>
0x3443	0x75B5	# <CJK>
0x3444	0x8328	# <CJK>
0x3445	0x78C1	# <CJK>
0x3446	0x96CC	# <CJK>
0x3447	0x8FAD	# <CJK>
0x3448	0x6148	# <CJK>
0x3449	0x74F7	# <CJK>
0x344A	0x8A5E	# <CJK>
0x344B	0x6B64	# <CJK>
0x344C	0x523A	# <CJK>
0x344D	0x8CDC	# <CJK>
0x344E	0x6B21	# <CJK>
0x344F	0x8070	# <CJK>
0x3450	0x8471	# <CJK>
0x3451	0x56F1	# <CJK>
0x3452	0x5306	# <CJK>
0x3453	0x5F9E	# <CJK>
0x3454	0x53E2	# <CJK>
0x3455	0x51D1	# <CJK>
0x3456	0x7C97	# <CJK>
0x3457	0x918B	# <CJK>
0x3458	0x7C07	# <CJK>
0x3459	0x4FC3	# <CJK>
0x345A	0x8EA5	# <CJK>
0x345B	0x7BE1	# <CJK>
0x345C	0x7AC4	# <CJK>
0x345D	0x6467	# <CJK>
0x345E	0x5D14	# <CJK>
0x345F	0x50AC	# <CJK>
0x3460	0x8106	# <CJK>
0x3461	0x7601	# <CJK>
0x3462	0x7CB9	# <CJK>
0x3463	0x6DEC	# <CJK>
0x3464	0x7FE0	# <CJK>
0x3465	0x6751	# <CJK>
0x3466	0x5B58	# <CJK>
0x3467	0x5BF8	# <CJK>
0x3468	0x78CB	# <CJK>
0x3469	0x64AE	# <CJK>
0x346A	0x6413	# <CJK>
0x346B	0x63AA	# <CJK>
0x346C	0x632B	# <CJK>
0x346D	0x932F	# <CJK>
0x346E	0x642D	# <CJK>
0x346F	0x9054	# <CJK>
0x3470	0x7B54	# <CJK>
0x3471	0x7629	# <CJK>
0x3472	0x6253	# <CJK>
0x3473	0x5927	# <CJK>
0x3474	0x5446	# <CJK>
0x3475	0x6B79	# <CJK>
0x3476	0x50A3	# <CJK>
0x3477	0x6234	# <CJK>
0x3478	0x5E36	# <CJK>
0x3479	0x6B86	# <CJK>
0x347A	0x4EE3	# <CJK>
0x347B	0x8CB8	# <CJK>
0x347C	0x888B	# <CJK>
0x347D	0x5F85	# <CJK>
0x347E	0x902E	# <CJK>
0x3521	0x6020	# <CJK>
0x3522	0x803D	# <CJK>
0x3523	0x64D4	# <CJK>
0x3524	0x4E39	# <CJK>
0x3525	0x55AE	# <CJK>
0x3526	0x9132	# <CJK>
0x3527	0x64A3	# <CJK>
0x3528	0x81BD	# <CJK>
0x3529	0x65E6	# <CJK>
0x352A	0x6C2E	# <CJK>
0x352B	0x4F46	# <CJK>
0x352C	0x619A	# <CJK>
0x352D	0x6DE1	# <CJK>
0x352E	0x8A95	# <CJK>
0x352F	0x5F48	# <CJK>
0x3530	0x86CB	# <CJK>
0x3531	0x7576	# <CJK>
0x3532	0x64CB	# <CJK>
0x3533	0x9EE8	# <CJK>
0x3534	0x8569	# <CJK>
0x3535	0x6A94	# <CJK>
0x3536	0x5200	# <CJK>
0x3537	0x6417	# <CJK>
0x3538	0x8E48	# <CJK>
0x3539	0x5012	# <CJK>
0x353A	0x5CF6	# <CJK>
0x353B	0x79B1	# <CJK>
0x353C	0x5C0E	# <CJK>
0x353D	0x5230	# <CJK>
0x353E	0x7A3B	# <CJK>
0x353F	0x60BC	# <CJK>
0x3540	0x9053	# <CJK>
0x3541	0x76D7	# <CJK>
0x3542	0x5FB7	# <CJK>
0x3543	0x5F97	# <CJK>
0x3544	0x7684	# <CJK>
0x3545	0x8E6C	# <CJK>
0x3546	0x71C8	# <CJK>
0x3547	0x767B	# <CJK>
0x3548	0x7B49	# <CJK>
0x3549	0x77AA	# <CJK>
0x354A	0x51F3	# <CJK>
0x354B	0x9127	# <CJK>
0x354C	0x5824	# <CJK>
0x354D	0x4F4E	# <CJK>
0x354E	0x6EF4	# <CJK>
0x354F	0x8FEA	# <CJK>
0x3550	0x6575	# <CJK>
0x3551	0x7B1B	# <CJK>
0x3552	0x72C4	# <CJK>
0x3553	0x6ECC	# <CJK>
0x3554	0x7FDF	# <CJK>
0x3555	0x5AE1	# <CJK>
0x3556	0x62B5	# <CJK>
0x3557	0x5E95	# <CJK>
0x3558	0x5730	# <CJK>
0x3559	0x8482	# <CJK>
0x355A	0x7B2C	# <CJK>
0x355B	0x5E1D	# <CJK>
0x355C	0x5F1F	# <CJK>
0x355D	0x905E	# <CJK>
0x355E	0x7DE0	# <CJK>
0x355F	0x985B	# <CJK>
0x3560	0x6382	# <CJK>
0x3561	0x6EC7	# <CJK>
0x3562	0x7898	# <CJK>
0x3563	0x9EDE	# <CJK>
0x3564	0x5178	# <CJK>
0x3565	0x975B	# <CJK>
0x3566	0x588A	# <CJK>
0x3567	0x96FB	# <CJK>
0x3568	0x4F43	# <CJK>
0x3569	0x7538	# <CJK>
0x356A	0x5E97	# <CJK>
0x356B	0x60E6	# <CJK>
0x356C	0x5960	# <CJK>
0x356D	0x6FB1	# <CJK>
0x356E	0x6BBF	# <CJK>
0x356F	0x7889	# <CJK>
0x3570	0x53FC	# <CJK>
0x3571	0x96D5	# <CJK>
0x3572	0x51CB	# <CJK>
0x3573	0x5201	# <CJK>
0x3574	0x6389	# <CJK>
0x3575	0x540A	# <CJK>
0x3576	0x91E3	# <CJK>
0x3577	0x8ABF	# <CJK>
0x3578	0x8DCC	# <CJK>
0x3579	0x7239	# <CJK>
0x357A	0x789F	# <CJK>
0x357B	0x8776	# <CJK>
0x357C	0x8FED	# <CJK>
0x357D	0x8ADC	# <CJK>
0x357E	0x758A	# <CJK>
0x3621	0x4E01	# <CJK>
0x3622	0x76EF	# <CJK>
0x3623	0x53EE	# <CJK>
0x3624	0x91D8	# <CJK>
0x3625	0x9802	# <CJK>
0x3626	0x9F0E	# <CJK>
0x3627	0x9320	# <CJK>
0x3628	0x5B9A	# <CJK>
0x3629	0x8A02	# <CJK>
0x362A	0x4E22	# <CJK>
0x362B	0x6771	# <CJK>
0x362C	0x51AC	# <CJK>
0x362D	0x8463	# <CJK>
0x362E	0x61C2	# <CJK>
0x362F	0x52D5	# <CJK>
0x3630	0x68DF	# <CJK>
0x3631	0x4F97	# <CJK>
0x3632	0x606B	# <CJK>
0x3633	0x51CD	# <CJK>
0x3634	0x6D1E	# <CJK>
0x3635	0x515C	# <CJK>
0x3636	0x6296	# <CJK>
0x3637	0x9B25	# <CJK>
0x3638	0x9661	# <CJK>
0x3639	0x8C46	# <CJK>
0x363A	0x9017	# <CJK>
0x363B	0x75D8	# <CJK>
0x363C	0x90FD	# <CJK>
0x363D	0x7763	# <CJK>
0x363E	0x6BD2	# <CJK>
0x363F	0x72A2	# <CJK>
0x3640	0x7368	# <CJK>
0x3641	0x8B80	# <CJK>
0x3642	0x5835	# <CJK>
0x3643	0x7779	# <CJK>
0x3644	0x8CED	# <CJK>
0x3645	0x675C	# <CJK>
0x3646	0x934D	# <CJK>
0x3647	0x809A	# <CJK>
0x3648	0x5EA6	# <CJK>
0x3649	0x6E21	# <CJK>
0x364A	0x5992	# <CJK>
0x364B	0x7AEF	# <CJK>
0x364C	0x77ED	# <CJK>
0x364D	0x935B	# <CJK>
0x364E	0x6BB5	# <CJK>
0x364F	0x65B7	# <CJK>
0x3650	0x7DDE	# <CJK>
0x3651	0x5806	# <CJK>
0x3652	0x5151	# <CJK>
0x3653	0x968A	# <CJK>
0x3654	0x5C0D	# <CJK>
0x3655	0x58A9	# <CJK>
0x3656	0x5678	# <CJK>
0x3657	0x8E72	# <CJK>
0x3658	0x6566	# <CJK>
0x3659	0x9813	# <CJK>
0x365A	0x56E4	# <CJK>
0x365B	0x920D	# <CJK>
0x365C	0x76FE	# <CJK>
0x365D	0x9041	# <CJK>
0x365E	0x6387	# <CJK>
0x365F	0x54C6	# <CJK>
0x3660	0x591A	# <CJK>
0x3661	0x596A	# <CJK>
0x3662	0x579B	# <CJK>
0x3663	0x8EB2	# <CJK>
0x3664	0x6735	# <CJK>
0x3665	0x8DFA	# <CJK>
0x3666	0x8235	# <CJK>
0x3667	0x5241	# <CJK>
0x3668	0x60F0	# <CJK>
0x3669	0x58AE	# <CJK>
0x366A	0x86FE	# <CJK>
0x366B	0x5CE8	# <CJK>
0x366C	0x9D5D	# <CJK>
0x366D	0x4FC4	# <CJK>
0x366E	0x984D	# <CJK>
0x366F	0x8A1B	# <CJK>
0x3670	0x5A25	# <CJK>
0x3671	0x60E1	# <CJK>
0x3672	0x5384	# <CJK>
0x3673	0x627C	# <CJK>
0x3674	0x904F	# <CJK>
0x3675	0x9102	# <CJK>
0x3676	0x9913	# <CJK>
0x3677	0x6069	# <CJK>
0x3678	0x800C	# <CJK>
0x3679	0x5152	# <CJK>
0x367A	0x8033	# <CJK>
0x367B	0x723E	# <CJK>
0x367C	0x990C	# <CJK>
0x367D	0x6D31	# <CJK>
0x367E	0x4E8C	# <CJK>
0x3721	0x8CB3	# <CJK>
0x3722	0x767C	# <CJK>
0x3723	0x7F70	# <CJK>
0x3724	0x7B4F	# <CJK>
0x3725	0x4F10	# <CJK>
0x3726	0x4E4F	# <CJK>
0x3727	0x95A5	# <CJK>
0x3728	0x6CD5	# <CJK>
0x3729	0x73D0	# <CJK>
0x372A	0x85E9	# <CJK>
0x372B	0x5E06	# <CJK>
0x372C	0x756A	# <CJK>
0x372D	0x7FFB	# <CJK>
0x372E	0x6A0A	# <CJK>
0x372F	0x792C	# <CJK>
0x3730	0x91E9	# <CJK>
0x3731	0x7E41	# <CJK>
0x3732	0x51E1	# <CJK>
0x3733	0x7169	# <CJK>
0x3734	0x53CD	# <CJK>
0x3735	0x8FD4	# <CJK>
0x3736	0x7BC4	# <CJK>
0x3737	0x8CA9	# <CJK>
0x3738	0x72AF	# <CJK>
0x3739	0x98EF	# <CJK>
0x373A	0x6CDB	# <CJK>
0x373B	0x574A	# <CJK>
0x373C	0x82B3	# <CJK>
0x373D	0x65B9	# <CJK>
0x373E	0x80AA	# <CJK>
0x373F	0x623F	# <CJK>
0x3740	0x9632	# <CJK>
0x3741	0x59A8	# <CJK>
0x3742	0x4EFF	# <CJK>
0x3743	0x8A2A	# <CJK>
0x3744	0x7D21	# <CJK>
0x3745	0x653E	# <CJK>
0x3746	0x83F2	# <CJK>
0x3747	0x975E	# <CJK>
0x3748	0x5561	# <CJK>
0x3749	0x98DB	# <CJK>
0x374A	0x80A5	# <CJK>
0x374B	0x532A	# <CJK>
0x374C	0x8AB9	# <CJK>
0x374D	0x5420	# <CJK>
0x374E	0x80BA	# <CJK>
0x374F	0x5EE2	# <CJK>
0x3750	0x6CB8	# <CJK>
0x3751	0x8CBB	# <CJK>
0x3752	0x82AC	# <CJK>
0x3753	0x915A	# <CJK>
0x3754	0x5429	# <CJK>
0x3755	0x6C1B	# <CJK>
0x3756	0x5206	# <CJK>
0x3757	0x7D1B	# <CJK>
0x3758	0x58B3	# <CJK>
0x3759	0x711A	# <CJK>
0x375A	0x6C7E	# <CJK>
0x375B	0x7C89	# <CJK>
0x375C	0x596E	# <CJK>
0x375D	0x4EFD	# <CJK>
0x375E	0x5FFF	# <CJK>
0x375F	0x61A4	# <CJK>
0x3760	0x7CDE	# <CJK>
0x3761	0x8C50	# <CJK>
0x3762	0x5C01	# <CJK>
0x3763	0x6953	# <CJK>
0x3764	0x8702	# <CJK>
0x3765	0x5CF0	# <CJK>
0x3766	0x92D2	# <CJK>
0x3767	0x98A8	# <CJK>
0x3768	0x760B	# <CJK>
0x3769	0x70FD	# <CJK>
0x376A	0x9022	# <CJK>
0x376B	0x99AE	# <CJK>
0x376C	0x7E2B	# <CJK>
0x376D	0x8AF7	# <CJK>
0x376E	0x5949	# <CJK>
0x376F	0x9CF3	# <CJK>
0x3770	0x4F5B	# <CJK>
0x3771	0x5426	# <CJK>
0x3772	0x592B	# <CJK>
0x3773	0x6577	# <CJK>
0x3774	0x819A	# <CJK>
0x3775	0x5B75	# <CJK>
0x3776	0x6276	# <CJK>
0x3777	0x62C2	# <CJK>
0x3778	0x8F3B	# <CJK>
0x3779	0x5E45	# <CJK>
0x377A	0x6C1F	# <CJK>
0x377B	0x7B26	# <CJK>
0x377C	0x4F0F	# <CJK>
0x377D	0x4FD8	# <CJK>
0x377E	0x670D	# <CJK>
0x3821	0x6D6E	# <CJK>
0x3822	0x6DAA	# <CJK>
0x3823	0x798F	# <CJK>
0x3824	0x88B1	# <CJK>
0x3825	0x5F17	# <CJK>
0x3826	0x752B	# <CJK>
0x3827	0x64AB	# <CJK>
0x3828	0x8F14	# <CJK>
0x3829	0x4FEF	# <CJK>
0x382A	0x91DC	# <CJK>
0x382B	0x65A7	# <CJK>
0x382C	0x812F	# <CJK>
0x382D	0x8151	# <CJK>
0x382E	0x5E9C	# <CJK>
0x382F	0x8150	# <CJK>
0x3830	0x8D74	# <CJK>
0x3831	0x526F	# <CJK>
0x3832	0x8986	# <CJK>
0x3833	0x8CE6	# <CJK>
0x3834	0x5FA9	# <CJK>
0x3835	0x5085	# <CJK>
0x3836	0x4ED8	# <CJK>
0x3837	0x961C	# <CJK>
0x3838	0x7236	# <CJK>
0x3839	0x8179	# <CJK>
0x383A	0x8CA0	# <CJK>
0x383B	0x5BCC	# <CJK>
0x383C	0x8A03	# <CJK>
0x383D	0x9644	# <CJK>
0x383E	0x5A66	# <CJK>
0x383F	0x7E1B	# <CJK>
0x3840	0x5490	# <CJK>
0x3841	0x5676	# <CJK>
0x3842	0x560E	# <CJK>
0x3843	0x8A72	# <CJK>
0x3844	0x6539	# <CJK>
0x3845	0x6982	# <CJK>
0x3846	0x9223	# <CJK>
0x3847	0x84CB	# <CJK>
0x3848	0x6E89	# <CJK>
0x3849	0x5E79	# <CJK>
0x384A	0x7518	# <CJK>
0x384B	0x6746	# <CJK>
0x384C	0x67D1	# <CJK>
0x384D	0x7AFF	# <CJK>
0x384E	0x809D	# <CJK>
0x384F	0x8D95	# <CJK>
0x3850	0x611F	# <CJK>
0x3851	0x79C6	# <CJK>
0x3852	0x6562	# <CJK>
0x3853	0x8D1B	# <CJK>
0x3854	0x5CA1	# <CJK>
0x3855	0x525B	# <CJK>
0x3856	0x92FC	# <CJK>
0x3857	0x7F38	# <CJK>
0x3858	0x809B	# <CJK>
0x3859	0x7DB1	# <CJK>
0x385A	0x5D17	# <CJK>
0x385B	0x6E2F	# <CJK>
0x385C	0x6760	# <CJK>
0x385D	0x7BD9	# <CJK>
0x385E	0x768B	# <CJK>
0x385F	0x9AD8	# <CJK>
0x3860	0x818F	# <CJK>
0x3861	0x7F94	# <CJK>
0x3862	0x7CD5	# <CJK>
0x3863	0x641E	# <CJK>
0x3864	0x93AC	# <CJK>
0x3865	0x7A3F	# <CJK>
0x3866	0x544A	# <CJK>
0x3867	0x54E5	# <CJK>
0x3868	0x6B4C	# <CJK>
0x3869	0x64F1	# <CJK>
0x386A	0x6208	# <CJK>
0x386B	0x9D3F	# <CJK>
0x386C	0x80F3	# <CJK>
0x386D	0x7599	# <CJK>
0x386E	0x5272	# <CJK>
0x386F	0x9769	# <CJK>
0x3870	0x845B	# <CJK>
0x3871	0x683C	# <CJK>
0x3872	0x86E4	# <CJK>
0x3873	0x95A3	# <CJK>
0x3874	0x9694	# <CJK>
0x3875	0x927B	# <CJK>
0x3876	0x500B	# <CJK>
0x3877	0x5404	# <CJK>
0x3878	0x7D66	# <CJK>
0x3879	0x6839	# <CJK>
0x387A	0x8DDF	# <CJK>
0x387B	0x8015	# <CJK>
0x387C	0x66F4	# <CJK>
0x387D	0x5E9A	# <CJK>
0x387E	0x7FB9	# <CJK>
0x3921	0x57C2	# <CJK>
0x3922	0x803F	# <CJK>
0x3923	0x6897	# <CJK>
0x3924	0x5DE5	# <CJK>
0x3925	0x653B	# <CJK>
0x3926	0x529F	# <CJK>
0x3927	0x606D	# <CJK>
0x3928	0x9F94	# <CJK>
0x3929	0x4F9B	# <CJK>
0x392A	0x8EAC	# <CJK>
0x392B	0x516C	# <CJK>
0x392C	0x5BAB	# <CJK>
0x392D	0x5F13	# <CJK>
0x392E	0x978F	# <CJK>
0x392F	0x6C5E	# <CJK>
0x3930	0x62F1	# <CJK>
0x3931	0x8CA2	# <CJK>
0x3932	0x5171	# <CJK>
0x3933	0x920E	# <CJK>
0x3934	0x52FE	# <CJK>
0x3935	0x6E9D	# <CJK>
0x3936	0x82DF	# <CJK>
0x3937	0x72D7	# <CJK>
0x3938	0x57A2	# <CJK>
0x3939	0x69CB	# <CJK>
0x393A	0x8CFC	# <CJK>
0x393B	0x591F	# <CJK>
0x393C	0x8F9C	# <CJK>
0x393D	0x83C7	# <CJK>
0x393E	0x5495	# <CJK>
0x393F	0x7B8D	# <CJK>
0x3940	0x4F30	# <CJK>
0x3941	0x6CBD	# <CJK>
0x3942	0x5B64	# <CJK>
0x3943	0x59D1	# <CJK>
0x3944	0x9F13	# <CJK>
0x3945	0x53E4	# <CJK>
0x3946	0x8831	# <CJK>
0x3947	0x9AA8	# <CJK>
0x3948	0x8C37	# <CJK>
0x3949	0x80A1	# <CJK>
0x394A	0x6545	# <CJK>
0x394B	0x9867	# <CJK>
0x394C	0x56FA	# <CJK>
0x394D	0x96C7	# <CJK>
0x394E	0x522E	# <CJK>
0x394F	0x74DC	# <CJK>
0x3950	0x526E	# <CJK>
0x3951	0x5BE1	# <CJK>
0x3952	0x6302	# <CJK>
0x3953	0x8902	# <CJK>
0x3954	0x4E56	# <CJK>
0x3955	0x62D0	# <CJK>
0x3956	0x602A	# <CJK>
0x3957	0x68FA	# <CJK>
0x3958	0x95DC	# <CJK>
0x3959	0x5B98	# <CJK>
0x395A	0x51A0	# <CJK>
0x395B	0x89C0	# <CJK>
0x395C	0x7BA1	# <CJK>
0x395D	0x9928	# <CJK>
0x395E	0x7F50	# <CJK>
0x395F	0x6163	# <CJK>
0x3960	0x704C	# <CJK>
0x3961	0x8CAB	# <CJK>
0x3962	0x5149	# <CJK>
0x3963	0x5EE3	# <CJK>
0x3964	0x901B	# <CJK>
0x3965	0x7470	# <CJK>
0x3966	0x898F	# <CJK>
0x3967	0x572D	# <CJK>
0x3968	0x7845	# <CJK>
0x3969	0x6B78	# <CJK>
0x396A	0x9F9C	# <CJK>
0x396B	0x95A8	# <CJK>
0x396C	0x8ECC	# <CJK>
0x396D	0x9B3C	# <CJK>
0x396E	0x8A6D	# <CJK>
0x396F	0x7678	# <CJK>
0x3970	0x6842	# <CJK>
0x3971	0x6AC3	# <CJK>
0x3972	0x8DEA	# <CJK>
0x3973	0x8CB4	# <CJK>
0x3974	0x528A	# <CJK>
0x3975	0x8F25	# <CJK>
0x3976	0x6EDA	# <CJK>
0x3977	0x68CD	# <CJK>
0x3978	0x934B	# <CJK>
0x3979	0x90ED	# <CJK>
0x397A	0x570B	# <CJK>
0x397B	0x679C	# <CJK>
0x397C	0x88F9	# <CJK>
0x397D	0x904E	# <CJK>
0x397E	0x54C8	# <CJK>
0x3A21	0x9AB8	# <CJK>
0x3A22	0x5B69	# <CJK>
0x3A23	0x6D77	# <CJK>
0x3A24	0x6C26	# <CJK>
0x3A25	0x4EA5	# <CJK>
0x3A26	0x5BB3	# <CJK>
0x3A27	0x99ED	# <CJK>
0x3A28	0x9163	# <CJK>
0x3A29	0x61A8	# <CJK>
0x3A2A	0x90AF	# <CJK>
0x3A2B	0x97D3	# <CJK>
0x3A2C	0x542B	# <CJK>
0x3A2D	0x6DB5	# <CJK>
0x3A2E	0x5BD2	# <CJK>
0x3A2F	0x51FD	# <CJK>
0x3A30	0x558A	# <CJK>
0x3A31	0x7F55	# <CJK>
0x3A32	0x7FF0	# <CJK>
0x3A33	0x64BC	# <CJK>
0x3A34	0x634D	# <CJK>
0x3A35	0x65F1	# <CJK>
0x3A36	0x61BE	# <CJK>
0x3A37	0x608D	# <CJK>
0x3A38	0x710A	# <CJK>
0x3A39	0x6C57	# <CJK>
0x3A3A	0x6F22	# <CJK>
0x3A3B	0x592F	# <CJK>
0x3A3C	0x676D	# <CJK>
0x3A3D	0x822A	# <CJK>
0x3A3E	0x58D5	# <CJK>
0x3A3F	0x568E	# <CJK>
0x3A40	0x8C6A	# <CJK>
0x3A41	0x6BEB	# <CJK>
0x3A42	0x90DD	# <CJK>
0x3A43	0x597D	# <CJK>
0x3A44	0x8017	# <CJK>
0x3A45	0x865F	# <CJK>
0x3A46	0x6D69	# <CJK>
0x3A47	0x5475	# <CJK>
0x3A48	0x559D	# <CJK>
0x3A49	0x8377	# <CJK>
0x3A4A	0x83CF	# <CJK>
0x3A4B	0x6838	# <CJK>
0x3A4C	0x79BE	# <CJK>
0x3A4D	0x548C	# <CJK>
0x3A4E	0x4F55	# <CJK>
0x3A4F	0x5408	# <CJK>
0x3A50	0x76D2	# <CJK>
0x3A51	0x8C89	# <CJK>
0x3A52	0x95A1	# <CJK>
0x3A53	0x6CB3	# <CJK>
0x3A54	0x6DB8	# <CJK>
0x3A55	0x8D6B	# <CJK>
0x3A56	0x8910	# <CJK>
0x3A57	0x9DB4	# <CJK>
0x3A58	0x8CC0	# <CJK>
0x3A59	0x563F	# <CJK>
0x3A5A	0x9ED1	# <CJK>
0x3A5B	0x75D5	# <CJK>
0x3A5C	0x5F88	# <CJK>
0x3A5D	0x72E0	# <CJK>
0x3A5E	0x6068	# <CJK>
0x3A5F	0x54FC	# <CJK>
0x3A60	0x4EA8	# <CJK>
0x3A61	0x6A2A	# <CJK>
0x3A62	0x8861	# <CJK>
0x3A63	0x6052	# <CJK>
0x3A64	0x8F5F	# <CJK>
0x3A65	0x54C4	# <CJK>
0x3A66	0x70D8	# <CJK>
0x3A67	0x8679	# <CJK>
0x3A68	0x9D3B	# <CJK>
0x3A69	0x6D2A	# <CJK>
0x3A6A	0x5B8F	# <CJK>
0x3A6B	0x5F18	# <CJK>
0x3A6C	0x7D05	# <CJK>
0x3A6D	0x5589	# <CJK>
0x3A6E	0x4FAF	# <CJK>
0x3A6F	0x7334	# <CJK>
0x3A70	0x543C	# <CJK>
0x3A71	0x539A	# <CJK>
0x3A72	0x5019	# <CJK>
0x3A73	0x5F8C	# <CJK>
0x3A74	0x547C	# <CJK>
0x3A75	0x4E4E	# <CJK>
0x3A76	0x5FFD	# <CJK>
0x3A77	0x745A	# <CJK>
0x3A78	0x58FA	# <CJK>
0x3A79	0x846B	# <CJK>
0x3A7A	0x80E1	# <CJK>
0x3A7B	0x8774	# <CJK>
0x3A7C	0x72D0	# <CJK>
0x3A7D	0x7CCA	# <CJK>
0x3A7E	0x6E56	# <CJK>
0x3B21	0x5F27	# <CJK>
0x3B22	0x864E	# <CJK>
0x3B23	0x552C	# <CJK>
0x3B24	0x8B77	# <CJK>
0x3B25	0x4E92	# <CJK>
0x3B26	0x6EEC	# <CJK>
0x3B27	0x6237	# <CJK>
0x3B28	0x82B1	# <CJK>
0x3B29	0x5629	# <CJK>
0x3B2A	0x83EF	# <CJK>
0x3B2B	0x733E	# <CJK>
0x3B2C	0x6ED1	# <CJK>
0x3B2D	0x756B	# <CJK>
0x3B2E	0x5283	# <CJK>
0x3B2F	0x5316	# <CJK>
0x3B30	0x8A71	# <CJK>
0x3B31	0x69D0	# <CJK>
0x3B32	0x5F8A	# <CJK>
0x3B33	0x61F7	# <CJK>
0x3B34	0x6DEE	# <CJK>
0x3B35	0x58DE	# <CJK>
0x3B36	0x6B61	# <CJK>
0x3B37	0x74B0	# <CJK>
0x3B38	0x6853	# <CJK>
0x3B39	0x9084	# <CJK>
0x3B3A	0x7DE9	# <CJK>
0x3B3B	0x63DB	# <CJK>
0x3B3C	0x60A3	# <CJK>
0x3B3D	0x559A	# <CJK>
0x3B3E	0x7613	# <CJK>
0x3B3F	0x8C62	# <CJK>
0x3B40	0x7165	# <CJK>
0x3B41	0x6E19	# <CJK>
0x3B42	0x5BA6	# <CJK>
0x3B43	0x5E7B	# <CJK>
0x3B44	0x8352	# <CJK>
0x3B45	0x614C	# <CJK>
0x3B46	0x9EC4	# <CJK>
0x3B47	0x78FA	# <CJK>
0x3B48	0x8757	# <CJK>
0x3B49	0x7C27	# <CJK>
0x3B4A	0x7687	# <CJK>
0x3B4B	0x51F0	# <CJK>
0x3B4C	0x60F6	# <CJK>
0x3B4D	0x714C	# <CJK>
0x3B4E	0x6643	# <CJK>
0x3B4F	0x5E4C	# <CJK>
0x3B50	0x604D	# <CJK>
0x3B51	0x8B0A	# <CJK>
0x3B52	0x7070	# <CJK>
0x3B53	0x63EE	# <CJK>
0x3B54	0x8F1D	# <CJK>
0x3B55	0x5FBD	# <CJK>
0x3B56	0x6062	# <CJK>
0x3B57	0x86D4	# <CJK>
0x3B58	0x56DE	# <CJK>
0x3B59	0x6BC1	# <CJK>
0x3B5A	0x6094	# <CJK>
0x3B5B	0x6167	# <CJK>
0x3B5C	0x5349	# <CJK>
0x3B5D	0x60E0	# <CJK>
0x3B5E	0x6666	# <CJK>
0x3B5F	0x8CC4	# <CJK>
0x3B60	0x7A62	# <CJK>
0x3B61	0x6703	# <CJK>
0x3B62	0x71F4	# <CJK>
0x3B63	0x532F	# <CJK>
0x3B64	0x8AF1	# <CJK>
0x3B65	0x8AA8	# <CJK>
0x3B66	0x7E6A	# <CJK>
0x3B67	0x8477	# <CJK>
0x3B68	0x660F	# <CJK>
0x3B69	0x5A5A	# <CJK>
0x3B6A	0x9B42	# <CJK>
0x3B6B	0x6E3E	# <CJK>
0x3B6C	0x6DF7	# <CJK>
0x3B6D	0x8C41	# <CJK>
0x3B6E	0x6D3B	# <CJK>
0x3B6F	0x4F19	# <CJK>
0x3B70	0x706B	# <CJK>
0x3B71	0x7372	# <CJK>
0x3B72	0x6216	# <CJK>
0x3B73	0x60D1	# <CJK>
0x3B74	0x970D	# <CJK>
0x3B75	0x8CA8	# <CJK>
0x3B76	0x798D	# <CJK>
0x3B77	0x64CA	# <CJK>
0x3B78	0x573E	# <CJK>
0x3B79	0x57FA	# <CJK>
0x3B7A	0x6A5F	# <CJK>
0x3B7B	0x7578	# <CJK>
0x3B7C	0x7A3D	# <CJK>
0x3B7D	0x7A4D	# <CJK>
0x3B7E	0x7B95	# <CJK>
0x3C21	0x808C	# <CJK>
0x3C22	0x9951	# <CJK>
0x3C23	0x8FF9	# <CJK>
0x3C24	0x6FC0	# <CJK>
0x3C25	0x8B4F	# <CJK>
0x3C26	0x9DC4	# <CJK>
0x3C27	0x59EC	# <CJK>
0x3C28	0x7E3E	# <CJK>
0x3C29	0x7DDD	# <CJK>
0x3C2A	0x5409	# <CJK>
0x3C2B	0x6975	# <CJK>
0x3C2C	0x68D8	# <CJK>
0x3C2D	0x8F2F	# <CJK>
0x3C2E	0x7C4D	# <CJK>
0x3C2F	0x96C6	# <CJK>
0x3C30	0x53CA	# <CJK>
0x3C31	0x6025	# <CJK>
0x3C32	0x75BE	# <CJK>
0x3C33	0x6C72	# <CJK>
0x3C34	0x5373	# <CJK>
0x3C35	0x5AC9	# <CJK>
0x3C36	0x7D1A	# <CJK>
0x3C37	0x64E0	# <CJK>
0x3C38	0x5E7E	# <CJK>
0x3C39	0x810A	# <CJK>
0x3C3A	0x5DF1	# <CJK>
0x3C3B	0x858A	# <CJK>
0x3C3C	0x6280	# <CJK>
0x3C3D	0x5180	# <CJK>
0x3C3E	0x5B63	# <CJK>
0x3C3F	0x4F0E	# <CJK>
0x3C40	0x796D	# <CJK>
0x3C41	0x5291	# <CJK>
0x3C42	0x60B8	# <CJK>
0x3C43	0x6FDF	# <CJK>
0x3C44	0x5BC4	# <CJK>
0x3C45	0x5BC2	# <CJK>
0x3C46	0x8A08	# <CJK>
0x3C47	0x8A18	# <CJK>
0x3C48	0x65E2	# <CJK>
0x3C49	0x5FCC	# <CJK>
0x3C4A	0x969B	# <CJK>
0x3C4B	0x5993	# <CJK>
0x3C4C	0x7E7C	# <CJK>
0x3C4D	0x7D00	# <CJK>
0x3C4E	0x5609	# <CJK>
0x3C4F	0x67B7	# <CJK>
0x3C50	0x593E	# <CJK>
0x3C51	0x4F73	# <CJK>
0x3C52	0x5BB6	# <CJK>
0x3C53	0x52A0	# <CJK>
0x3C54	0x83A2	# <CJK>
0x3C55	0x9830	# <CJK>
0x3C56	0x8CC8	# <CJK>
0x3C57	0x7532	# <CJK>
0x3C58	0x9240	# <CJK>
0x3C59	0x5047	# <CJK>
0x3C5A	0x7A3C	# <CJK>
0x3C5B	0x50F9	# <CJK>
0x3C5C	0x67B6	# <CJK>
0x3C5D	0x99D5	# <CJK>
0x3C5E	0x5AC1	# <CJK>
0x3C5F	0x6BB2	# <CJK>
0x3C60	0x76E3	# <CJK>
0x3C61	0x5805	# <CJK>
0x3C62	0x5C16	# <CJK>
0x3C63	0x7B8B	# <CJK>
0x3C64	0x9593	# <CJK>
0x3C65	0x714E	# <CJK>
0x3C66	0x517C	# <CJK>
0x3C67	0x80A9	# <CJK>
0x3C68	0x8271	# <CJK>
0x3C69	0x5978	# <CJK>
0x3C6A	0x7DD8	# <CJK>
0x3C6B	0x7E6D	# <CJK>
0x3C6C	0x6AA2	# <CJK>
0x3C6D	0x67EC	# <CJK>
0x3C6E	0x78B1	# <CJK>
0x3C6F	0x9E7C	# <CJK>
0x3C70	0x63C0	# <CJK>
0x3C71	0x64BF	# <CJK>
0x3C72	0x7C21	# <CJK>
0x3C73	0x5109	# <CJK>
0x3C74	0x526A	# <CJK>
0x3C75	0x51CF	# <CJK>
0x3C76	0x85A6	# <CJK>
0x3C77	0x6ABB	# <CJK>
0x3C78	0x9452	# <CJK>
0x3C79	0x8E10	# <CJK>
0x3C7A	0x8CE4	# <CJK>
0x3C7B	0x898B	# <CJK>
0x3C7C	0x9375	# <CJK>
0x3C7D	0x7BAD	# <CJK>
0x3C7E	0x4EF6	# <CJK>
0x3D21	0x5065	# <CJK>
0x3D22	0x8266	# <CJK>
0x3D23	0x528D	# <CJK>
0x3D24	0x991E	# <CJK>
0x3D25	0x6F38	# <CJK>
0x3D26	0x6FFA	# <CJK>
0x3D27	0x6F97	# <CJK>
0x3D28	0x5EFA	# <CJK>
0x3D29	0x50F5	# <CJK>
0x3D2A	0x59DC	# <CJK>
0x3D2B	0x5C07	# <CJK>
0x3D2C	0x6F3F	# <CJK>
0x3D2D	0x6C5F	# <CJK>
0x3D2E	0x7586	# <CJK>
0x3D2F	0x8523	# <CJK>
0x3D30	0x69F3	# <CJK>
0x3D31	0x596C	# <CJK>
0x3D32	0x8B1B	# <CJK>
0x3D33	0x5320	# <CJK>
0x3D34	0x91AC	# <CJK>
0x3D35	0x964D	# <CJK>
0x3D36	0x8549	# <CJK>
0x3D37	0x6912	# <CJK>
0x3D38	0x7901	# <CJK>
0x3D39	0x7126	# <CJK>
0x3D3A	0x81A0	# <CJK>
0x3D3B	0x4EA4	# <CJK>
0x3D3C	0x90CA	# <CJK>
0x3D3D	0x6F86	# <CJK>
0x3D3E	0x9A55	# <CJK>
0x3D3F	0x5B0C	# <CJK>
0x3D40	0x56BC	# <CJK>
0x3D41	0x652A	# <CJK>
0x3D42	0x9278	# <CJK>
0x3D43	0x77EF	# <CJK>
0x3D44	0x50E5	# <CJK>
0x3D45	0x811A	# <CJK>
0x3D46	0x72E1	# <CJK>
0x3D47	0x89D2	# <CJK>
0x3D48	0x9903	# <CJK>
0x3D49	0x7E73	# <CJK>
0x3D4A	0x7D5E	# <CJK>
0x3D4B	0x527F	# <CJK>
0x3D4C	0x6559	# <CJK>
0x3D4D	0x9175	# <CJK>
0x3D4E	0x8F4E	# <CJK>
0x3D4F	0x8F03	# <CJK>
0x3D50	0x53EB	# <CJK>
0x3D51	0x7A96	# <CJK>
0x3D52	0x63ED	# <CJK>
0x3D53	0x63A5	# <CJK>
0x3D54	0x7686	# <CJK>
0x3D55	0x79F8	# <CJK>
0x3D56	0x8857	# <CJK>
0x3D57	0x968E	# <CJK>
0x3D58	0x622A	# <CJK>
0x3D59	0x52AB	# <CJK>
0x3D5A	0x7BC0	# <CJK>
0x3D5B	0x6854	# <CJK>
0x3D5C	0x6770	# <CJK>
0x3D5D	0x6377	# <CJK>
0x3D5E	0x776B	# <CJK>
0x3D5F	0x7AED	# <CJK>
0x3D60	0x6F54	# <CJK>
0x3D61	0x7D50	# <CJK>
0x3D62	0x89E3	# <CJK>
0x3D63	0x59D0	# <CJK>
0x3D64	0x6212	# <CJK>
0x3D65	0x85C9	# <CJK>
0x3D66	0x82A5	# <CJK>
0x3D67	0x754C	# <CJK>
0x3D68	0x501F	# <CJK>
0x3D69	0x4ECB	# <CJK>
0x3D6A	0x75A5	# <CJK>
0x3D6B	0x8AA1	# <CJK>
0x3D6C	0x5C4A	# <CJK>
0x3D6D	0x5DFE	# <CJK>
0x3D6E	0x7B4B	# <CJK>
0x3D6F	0x65A4	# <CJK>
0x3D70	0x91D1	# <CJK>
0x3D71	0x4ECA	# <CJK>
0x3D72	0x6D25	# <CJK>
0x3D73	0x895F	# <CJK>
0x3D74	0x7DCA	# <CJK>
0x3D75	0x9326	# <CJK>
0x3D76	0x50C5	# <CJK>
0x3D77	0x8B39	# <CJK>
0x3D78	0x9032	# <CJK>
0x3D79	0x9773	# <CJK>
0x3D7A	0x6649	# <CJK>
0x3D7B	0x7981	# <CJK>
0x3D7C	0x8FD1	# <CJK>
0x3D7D	0x71FC	# <CJK>
0x3D7E	0x6D78	# <CJK>
0x3E21	0x76E1	# <CJK>
0x3E22	0x52C1	# <CJK>
0x3E23	0x8346	# <CJK>
0x3E24	0x5162	# <CJK>
0x3E25	0x8396	# <CJK>
0x3E26	0x775B	# <CJK>
0x3E27	0x6676	# <CJK>
0x3E28	0x9BE8	# <CJK>
0x3E29	0x4EAC	# <CJK>
0x3E2A	0x9A5A	# <CJK>
0x3E2B	0x7CBE	# <CJK>
0x3E2C	0x7CB3	# <CJK>
0x3E2D	0x7D93	# <CJK>
0x3E2E	0x4E95	# <CJK>
0x3E2F	0x8B66	# <CJK>
0x3E30	0x666F	# <CJK>
0x3E31	0x9838	# <CJK>
0x3E32	0x975C	# <CJK>
0x3E33	0x5883	# <CJK>
0x3E34	0x656C	# <CJK>
0x3E35	0x93E1	# <CJK>
0x3E36	0x5F91	# <CJK>
0x3E37	0x75D9	# <CJK>
0x3E38	0x9756	# <CJK>
0x3E39	0x7ADF	# <CJK>
0x3E3A	0x7AF6	# <CJK>
0x3E3B	0x51C8	# <CJK>
0x3E3C	0x70AF	# <CJK>
0x3E3D	0x7A98	# <CJK>
0x3E3E	0x63EA	# <CJK>
0x3E3F	0x7A76	# <CJK>
0x3E40	0x7CFE	# <CJK>
0x3E41	0x7396	# <CJK>
0x3E42	0x97ED	# <CJK>
0x3E43	0x4E45	# <CJK>
0x3E44	0x7078	# <CJK>
0x3E45	0x4E5D	# <CJK>
0x3E46	0x9152	# <CJK>
0x3E47	0x53A9	# <CJK>
0x3E48	0x6551	# <CJK>
0x3E49	0x820A	# <CJK>
0x3E4A	0x81FC	# <CJK>
0x3E4B	0x8205	# <CJK>
0x3E4C	0x548E	# <CJK>
0x3E4D	0x5C31	# <CJK>
0x3E4E	0x759A	# <CJK>
0x3E4F	0x97A0	# <CJK>
0x3E50	0x62D8	# <CJK>
0x3E51	0x72D9	# <CJK>
0x3E52	0x75BD	# <CJK>
0x3E53	0x5C45	# <CJK>
0x3E54	0x99D2	# <CJK>
0x3E55	0x83CA	# <CJK>
0x3E56	0x5C40	# <CJK>
0x3E57	0x5480	# <CJK>
0x3E58	0x77E9	# <CJK>
0x3E59	0x8209	# <CJK>
0x3E5A	0x6CAE	# <CJK>
0x3E5B	0x805A	# <CJK>
0x3E5C	0x62D2	# <CJK>
0x3E5D	0x64DA	# <CJK>
0x3E5E	0x5DE8	# <CJK>
0x3E5F	0x5177	# <CJK>
0x3E60	0x8DDD	# <CJK>
0x3E61	0x8E1E	# <CJK>
0x3E62	0x92F8	# <CJK>
0x3E63	0x4FF1	# <CJK>
0x3E64	0x53E5	# <CJK>
0x3E65	0x61FC	# <CJK>
0x3E66	0x70AC	# <CJK>
0x3E67	0x5287	# <CJK>
0x3E68	0x6350	# <CJK>
0x3E69	0x9D51	# <CJK>
0x3E6A	0x5A1F	# <CJK>
0x3E6B	0x5026	# <CJK>
0x3E6C	0x7737	# <CJK>
0x3E6D	0x5377	# <CJK>
0x3E6E	0x7D79	# <CJK>
0x3E6F	0x6485	# <CJK>
0x3E70	0x652B	# <CJK>
0x3E71	0x6289	# <CJK>
0x3E72	0x6398	# <CJK>
0x3E73	0x5014	# <CJK>
0x3E74	0x7235	# <CJK>
0x3E75	0x89BA	# <CJK>
0x3E76	0x51B3	# <CJK>
0x3E77	0x8A23	# <CJK>
0x3E78	0x7D76	# <CJK>
0x3E79	0x5747	# <CJK>
0x3E7A	0x83CC	# <CJK>
0x3E7B	0x921E	# <CJK>
0x3E7C	0x8ECD	# <CJK>
0x3E7D	0x541B	# <CJK>
0x3E7E	0x5CFB	# <CJK>
0x3F21	0x4FCA	# <CJK>
0x3F22	0x7AE3	# <CJK>
0x3F23	0x6D5A	# <CJK>
0x3F24	0x90E1	# <CJK>
0x3F25	0x99FF	# <CJK>
0x3F26	0x5580	# <CJK>
0x3F27	0x5496	# <CJK>
0x3F28	0x5361	# <CJK>
0x3F29	0x54AF	# <CJK>
0x3F2A	0x958B	# <CJK>
0x3F2B	0x63E9	# <CJK>
0x3F2C	0x6977	# <CJK>
0x3F2D	0x51F1	# <CJK>
0x3F2E	0x6168	# <CJK>
0x3F2F	0x520A	# <CJK>
0x3F30	0x582A	# <CJK>
0x3F31	0x52D8	# <CJK>
0x3F32	0x574E	# <CJK>
0x3F33	0x780D	# <CJK>
0x3F34	0x770B	# <CJK>
0x3F35	0x5EB7	# <CJK>
0x3F36	0x6177	# <CJK>
0x3F37	0x7CE0	# <CJK>
0x3F38	0x625B	# <CJK>
0x3F39	0x6297	# <CJK>
0x3F3A	0x4EA2	# <CJK>
0x3F3B	0x7095	# <CJK>
0x3F3C	0x8003	# <CJK>
0x3F3D	0x62F7	# <CJK>
0x3F3E	0x70E4	# <CJK>
0x3F3F	0x9760	# <CJK>
0x3F40	0x5777	# <CJK>
0x3F41	0x82DB	# <CJK>
0x3F42	0x67EF	# <CJK>
0x3F43	0x68F5	# <CJK>
0x3F44	0x78D5	# <CJK>
0x3F45	0x9846	# <CJK>
0x3F46	0x79D1	# <CJK>
0x3F47	0x6BBB	# <CJK>
0x3F48	0x54B3	# <CJK>
0x3F49	0x53EF	# <CJK>
0x3F4A	0x6E34	# <CJK>
0x3F4B	0x514B	# <CJK>
0x3F4C	0x523B	# <CJK>
0x3F4D	0x5BA2	# <CJK>
0x3F4E	0x8AB2	# <CJK>
0x3F4F	0x80AF	# <CJK>
0x3F50	0x5543	# <CJK>
0x3F51	0x58BE	# <CJK>
0x3F52	0x61C7	# <CJK>
0x3F53	0x5751	# <CJK>
0x3F54	0x542D	# <CJK>
0x3F55	0x7A7A	# <CJK>
0x3F56	0x6050	# <CJK>
0x3F57	0x5B54	# <CJK>
0x3F58	0x63A7	# <CJK>
0x3F59	0x6473	# <CJK>
0x3F5A	0x53E3	# <CJK>
0x3F5B	0x6263	# <CJK>
0x3F5C	0x5BC7	# <CJK>
0x3F5D	0x67AF	# <CJK>
0x3F5E	0x54ED	# <CJK>
0x3F5F	0x7A9F	# <CJK>
0x3F60	0x82E6	# <CJK>
0x3F61	0x9177	# <CJK>
0x3F62	0x5EAB	# <CJK>
0x3F63	0x8932	# <CJK>
0x3F64	0x8A87	# <CJK>
0x3F65	0x57AE	# <CJK>
0x3F66	0x630E	# <CJK>
0x3F67	0x8DE8	# <CJK>
0x3F68	0x80EF	# <CJK>
0x3F69	0x584A	# <CJK>
0x3F6A	0x7B77	# <CJK>
0x3F6B	0x5108	# <CJK>
0x3F6C	0x5FEB	# <CJK>
0x3F6D	0x5BEC	# <CJK>
0x3F6E	0x6B3E	# <CJK>
0x3F6F	0x5321	# <CJK>
0x3F70	0x7B50	# <CJK>
0x3F71	0x72C2	# <CJK>
0x3F72	0x6846	# <CJK>
0x3F73	0x7926	# <CJK>
0x3F74	0x7736	# <CJK>
0x3F75	0x66E0	# <CJK>
0x3F76	0x51B5	# <CJK>
0x3F77	0x8667	# <CJK>
0x3F78	0x76D4	# <CJK>
0x3F79	0x5DCB	# <CJK>
0x3F7A	0x7ABA	# <CJK>
0x3F7B	0x8475	# <CJK>
0x3F7C	0x594E	# <CJK>
0x3F7D	0x9B41	# <CJK>
0x3F7E	0x5080	# <CJK>
0x4021	0x994B	# <CJK>
0x4022	0x6127	# <CJK>
0x4023	0x6F70	# <CJK>
0x4024	0x5764	# <CJK>
0x4025	0x6606	# <CJK>
0x4026	0x6346	# <CJK>
0x4027	0x56F0	# <CJK>
0x4028	0x62EC	# <CJK>
0x4029	0x64F4	# <CJK>
0x402A	0x5ED3	# <CJK>
0x402B	0x95CA	# <CJK>
0x402C	0x5783	# <CJK>
0x402D	0x62C9	# <CJK>
0x402E	0x5587	# <CJK>
0x402F	0x881F	# <CJK>
0x4030	0x81D8	# <CJK>
0x4031	0x8FA3	# <CJK>
0x4032	0x5566	# <CJK>
0x4033	0x840A	# <CJK>
0x4034	0x4F86	# <CJK>
0x4035	0x8CF4	# <CJK>
0x4036	0x85CD	# <CJK>
0x4037	0x5A6A	# <CJK>
0x4038	0x6B04	# <CJK>
0x4039	0x6514	# <CJK>
0x403A	0x7C43	# <CJK>
0x403B	0x95CC	# <CJK>
0x403C	0x862D	# <CJK>
0x403D	0x703E	# <CJK>
0x403E	0x8B95	# <CJK>
0x403F	0x652C	# <CJK>
0x4040	0x89BD	# <CJK>
0x4041	0x61F6	# <CJK>
0x4042	0x7E9C	# <CJK>
0x4043	0x721B	# <CJK>
0x4044	0x6FEB	# <CJK>
0x4045	0x7405	# <CJK>
0x4046	0x6994	# <CJK>
0x4047	0x72FC	# <CJK>
0x4048	0x5ECA	# <CJK>
0x4049	0x90CE	# <CJK>
0x404A	0x6717	# <CJK>
0x404B	0x6D6A	# <CJK>
0x404C	0x6488	# <CJK>
0x404D	0x52DE	# <CJK>
0x404E	0x7262	# <CJK>
0x404F	0x8001	# <CJK>
0x4050	0x4F6C	# <CJK>
0x4051	0x59E5	# <CJK>
0x4052	0x916A	# <CJK>
0x4053	0x70D9	# <CJK>
0x4054	0x6F87	# <CJK>
0x4055	0x52D2	# <CJK>
0x4056	0x6A02	# <CJK>
0x4057	0x96F7	# <CJK>
0x4058	0x9433	# <CJK>
0x4059	0x857E	# <CJK>
0x405A	0x78CA	# <CJK>
0x405B	0x7D2F	# <CJK>
0x405C	0x5121	# <CJK>
0x405D	0x58D8	# <CJK>
0x405E	0x64C2	# <CJK>
0x405F	0x808B	# <CJK>
0x4060	0x985E	# <CJK>
0x4061	0x6CEA	# <CJK>
0x4062	0x68F1	# <CJK>
0x4063	0x695E	# <CJK>
0x4064	0x51B7	# <CJK>
0x4065	0x5398	# <CJK>
0x4066	0x68A8	# <CJK>
0x4067	0x7281	# <CJK>
0x4068	0x9ECE	# <CJK>
0x4069	0x7C6C	# <CJK>
0x406A	0x72F8	# <CJK>
0x406B	0x96E2	# <CJK>
0x406C	0x7055	# <CJK>
0x406D	0x7406	# <CJK>
0x406E	0x674E	# <CJK>
0x406F	0x88CF	# <CJK>
0x4070	0x9BC9	# <CJK>
0x4071	0x79AE	# <CJK>
0x4072	0x8389	# <CJK>
0x4073	0x8354	# <CJK>
0x4074	0x540F	# <CJK>
0x4075	0x6817	# <CJK>
0x4076	0x9E97	# <CJK>
0x4077	0x53B2	# <CJK>
0x4078	0x52F5	# <CJK>
0x4079	0x792B	# <CJK>
0x407A	0x6B77	# <CJK>
0x407B	0x5229	# <CJK>
0x407C	0x5088	# <CJK>
0x407D	0x4F8B	# <CJK>
0x407E	0x4FD0	# <CJK>
0x4121	0x75E2	# <CJK>
0x4122	0x7ACB	# <CJK>
0x4123	0x7C92	# <CJK>
0x4124	0x701D	# <CJK>
0x4125	0x96B8	# <CJK>
0x4126	0x529B	# <CJK>
0x4127	0x7483	# <CJK>
0x4128	0x54E9	# <CJK>
0x4129	0x5006	# <CJK>
0x412A	0x806F	# <CJK>
0x412B	0x84EE	# <CJK>
0x412C	0x9023	# <CJK>
0x412D	0x942E	# <CJK>
0x412E	0x5EC9	# <CJK>
0x412F	0x6190	# <CJK>
0x4130	0x6F23	# <CJK>
0x4131	0x7C3E	# <CJK>
0x4132	0x6582	# <CJK>
0x4133	0x81C9	# <CJK>
0x4134	0x93C8	# <CJK>
0x4135	0x6200	# <CJK>
0x4136	0x7149	# <CJK>
0x4137	0x7DF4	# <CJK>
0x4138	0x7CE7	# <CJK>
0x4139	0x51C9	# <CJK>
0x413A	0x6881	# <CJK>
0x413B	0x7CB1	# <CJK>
0x413C	0x826F	# <CJK>
0x413D	0x5169	# <CJK>
0x413E	0x8F1B	# <CJK>
0x413F	0x91CF	# <CJK>
0x4140	0x667E	# <CJK>
0x4141	0x4EAE	# <CJK>
0x4142	0x8AD2	# <CJK>
0x4143	0x64A9	# <CJK>
0x4144	0x804A	# <CJK>
0x4145	0x50DA	# <CJK>
0x4146	0x7642	# <CJK>
0x4147	0x71CE	# <CJK>
0x4148	0x5BE5	# <CJK>
0x4149	0x907C	# <CJK>
0x414A	0x6F66	# <CJK>
0x414B	0x4E86	# <CJK>
0x414C	0x6482	# <CJK>
0x414D	0x9410	# <CJK>
0x414E	0x5ED6	# <CJK>
0x414F	0x6599	# <CJK>
0x4150	0x5217	# <CJK>
0x4151	0x88C2	# <CJK>
0x4152	0x70C8	# <CJK>
0x4153	0x52A3	# <CJK>
0x4154	0x7375	# <CJK>
0x4155	0x7433	# <CJK>
0x4156	0x6797	# <CJK>
0x4157	0x78F7	# <CJK>
0x4158	0x9716	# <CJK>
0x4159	0x81E8	# <CJK>
0x415A	0x9130	# <CJK>
0x415B	0x9C57	# <CJK>
0x415C	0x6DCB	# <CJK>
0x415D	0x51DB	# <CJK>
0x415E	0x8CC3	# <CJK>
0x415F	0x541D	# <CJK>
0x4160	0x62CE	# <CJK>
0x4161	0x73B2	# <CJK>
0x4162	0x83F1	# <CJK>
0x4163	0x96F6	# <CJK>
0x4164	0x9F61	# <CJK>
0x4165	0x9234	# <CJK>
0x4166	0x4F36	# <CJK>
0x4167	0x7F9A	# <CJK>
0x4168	0x51CC	# <CJK>
0x4169	0x9748	# <CJK>
0x416A	0x9675	# <CJK>
0x416B	0x5DBA	# <CJK>
0x416C	0x9818	# <CJK>
0x416D	0x53E6	# <CJK>
0x416E	0x4EE4	# <CJK>
0x416F	0x6E9C	# <CJK>
0x4170	0x7409	# <CJK>
0x4171	0x69B4	# <CJK>
0x4172	0x786B	# <CJK>
0x4173	0x993E	# <CJK>
0x4174	0x7559	# <CJK>
0x4175	0x5289	# <CJK>
0x4176	0x7624	# <CJK>
0x4177	0x6D41	# <CJK>
0x4178	0x67F3	# <CJK>
0x4179	0x516D	# <CJK>
0x417A	0x9F8D	# <CJK>
0x417B	0x807E	# <CJK>
0x417C	0x56A8	# <CJK>
0x417D	0x7C60	# <CJK>
0x417E	0x7ABF	# <CJK>
0x4221	0x9686	# <CJK>
0x4222	0x58DF	# <CJK>
0x4223	0x650F	# <CJK>
0x4224	0x96B4	# <CJK>
0x4225	0x6A13	# <CJK>
0x4226	0x5A41	# <CJK>
0x4227	0x645F	# <CJK>
0x4228	0x7C0D	# <CJK>
0x4229	0x6F0F	# <CJK>
0x422A	0x964B	# <CJK>
0x422B	0x8606	# <CJK>
0x422C	0x76E7	# <CJK>
0x422D	0x9871	# <CJK>
0x422E	0x5EEC	# <CJK>
0x422F	0x7210	# <CJK>
0x4230	0x64C4	# <CJK>
0x4231	0x6EF7	# <CJK>
0x4232	0x865C	# <CJK>
0x4233	0x9B6F	# <CJK>
0x4234	0x9E93	# <CJK>
0x4235	0x788C	# <CJK>
0x4236	0x9732	# <CJK>
0x4237	0x8DEF	# <CJK>
0x4238	0x8CC2	# <CJK>
0x4239	0x9E7F	# <CJK>
0x423A	0x6F5E	# <CJK>
0x423B	0x7984	# <CJK>
0x423C	0x9332	# <CJK>
0x423D	0x9678	# <CJK>
0x423E	0x622E	# <CJK>
0x423F	0x9A62	# <CJK>
0x4240	0x5415	# <CJK>
0x4241	0x92C1	# <CJK>
0x4242	0x4FA3	# <CJK>
0x4243	0x65C5	# <CJK>
0x4244	0x5C65	# <CJK>
0x4245	0x5C62	# <CJK>
0x4246	0x7E37	# <CJK>
0x4247	0x616E	# <CJK>
0x4248	0x6C2F	# <CJK>
0x4249	0x5F8B	# <CJK>
0x424A	0x7387	# <CJK>
0x424B	0x6FFE	# <CJK>
0x424C	0x7DD1	# <CJK>
0x424D	0x5DD2	# <CJK>
0x424E	0x6523	# <CJK>
0x424F	0x5B7F	# <CJK>
0x4250	0x7064	# <CJK>
0x4251	0x5375	# <CJK>
0x4252	0x4E82	# <CJK>
0x4253	0x63A0	# <CJK>
0x4254	0x7565	# <CJK>
0x4255	0x6384	# <CJK>
0x4256	0x8F2A	# <CJK>
0x4257	0x502B	# <CJK>
0x4258	0x4F96	# <CJK>
0x4259	0x6DEA	# <CJK>
0x425A	0x7DB8	# <CJK>
0x425B	0x8AD6	# <CJK>
0x425C	0x863F	# <CJK>
0x425D	0x87BA	# <CJK>
0x425E	0x7F85	# <CJK>
0x425F	0x908F	# <CJK>
0x4260	0x947C	# <CJK>
0x4261	0x7C6E	# <CJK>
0x4262	0x9A3E	# <CJK>
0x4263	0x88F8	# <CJK>
0x4264	0x843D	# <CJK>
0x4265	0x6D1B	# <CJK>
0x4266	0x99F1	# <CJK>
0x4267	0x7D61	# <CJK>
0x4268	0x5ABD	# <CJK>
0x4269	0x9EBB	# <CJK>
0x426A	0x746A	# <CJK>
0x426B	0x78BC	# <CJK>
0x426C	0x879E	# <CJK>
0x426D	0x99AC	# <CJK>
0x426E	0x99E1	# <CJK>
0x426F	0x561B	# <CJK>
0x4270	0x55CE	# <CJK>
0x4271	0x57CB	# <CJK>
0x4272	0x8CB7	# <CJK>
0x4273	0x9EA5	# <CJK>
0x4274	0x8CE3	# <CJK>
0x4275	0x9081	# <CJK>
0x4276	0x8109	# <CJK>
0x4277	0x779E	# <CJK>
0x4278	0x9945	# <CJK>
0x4279	0x883B	# <CJK>
0x427A	0x6EFF	# <CJK>
0x427B	0x8513	# <CJK>
0x427C	0x66FC	# <CJK>
0x427D	0x6162	# <CJK>
0x427E	0x6F2B	# <CJK>
0x4321	0x8B3E	# <CJK>
0x4322	0x8292	# <CJK>
0x4323	0x832B	# <CJK>
0x4324	0x76F2	# <CJK>
0x4325	0x6C13	# <CJK>
0x4326	0x5FD9	# <CJK>
0x4327	0x83BD	# <CJK>
0x4328	0x732B	# <CJK>
0x4329	0x8305	# <CJK>
0x432A	0x9328	# <CJK>
0x432B	0x6BDB	# <CJK>
0x432C	0x77DB	# <CJK>
0x432D	0x925A	# <CJK>
0x432E	0x536F	# <CJK>
0x432F	0x8302	# <CJK>
0x4330	0x5192	# <CJK>
0x4331	0x5E3D	# <CJK>
0x4332	0x8C8C	# <CJK>
0x4333	0x8CBF	# <CJK>
0x4334	0x9EBD	# <CJK>
0x4335	0x73AB	# <CJK>
0x4336	0x679A	# <CJK>
0x4337	0x6885	# <CJK>
0x4338	0x9176	# <CJK>
0x4339	0x9709	# <CJK>
0x433A	0x7164	# <CJK>
0x433B	0x6CA1	# <CJK>
0x433C	0x7709	# <CJK>
0x433D	0x5A92	# <CJK>
0x433E	0x9382	# <CJK>
0x433F	0x6BCF	# <CJK>
0x4340	0x7F8E	# <CJK>
0x4341	0x6627	# <CJK>
0x4342	0x5BD0	# <CJK>
0x4343	0x59B9	# <CJK>
0x4344	0x5A9A	# <CJK>
0x4345	0x9580	# <CJK>
0x4346	0x60B6	# <CJK>
0x4347	0x5011	# <CJK>
0x4348	0x840C	# <CJK>
0x4349	0x8499	# <CJK>
0x434A	0x6AAC	# <CJK>
0x434B	0x76DF	# <CJK>
0x434C	0x9333	# <CJK>
0x434D	0x731B	# <CJK>
0x434E	0x5922	# <CJK>
0x434F	0x5B5F	# <CJK>
0x4350	0x772F	# <CJK>
0x4351	0x919A	# <CJK>
0x4352	0x9761	# <CJK>
0x4353	0x7CDC	# <CJK>
0x4354	0x8FF7	# <CJK>
0x4355	0x8B0E	# <CJK>
0x4356	0x5F4C	# <CJK>
0x4357	0x7C73	# <CJK>
0x4358	0x79D8	# <CJK>
0x4359	0x8993	# <CJK>
0x435A	0x6CCC	# <CJK>
0x435B	0x871C	# <CJK>
0x435C	0x5BC6	# <CJK>
0x435D	0x5E42	# <CJK>
0x435E	0x68C9	# <CJK>
0x435F	0x7720	# <CJK>
0x4360	0x7DBF	# <CJK>
0x4361	0x5195	# <CJK>
0x4362	0x514D	# <CJK>
0x4363	0x52C9	# <CJK>
0x4364	0x5A29	# <CJK>
0x4365	0x7DEC	# <CJK>
0x4366	0x9762	# <CJK>
0x4367	0x82D7	# <CJK>
0x4368	0x63CF	# <CJK>
0x4369	0x7784	# <CJK>
0x436A	0x85D0	# <CJK>
0x436B	0x79D2	# <CJK>
0x436C	0x6E3A	# <CJK>
0x436D	0x5EDF	# <CJK>
0x436E	0x5999	# <CJK>
0x436F	0x8511	# <CJK>
0x4370	0x6EC5	# <CJK>
0x4371	0x6C11	# <CJK>
0x4372	0x62BF	# <CJK>
0x4373	0x76BF	# <CJK>
0x4374	0x654F	# <CJK>
0x4375	0x61AB	# <CJK>
0x4376	0x95A9	# <CJK>
0x4377	0x660E	# <CJK>
0x4378	0x879F	# <CJK>
0x4379	0x9CF4	# <CJK>
0x437A	0x9298	# <CJK>
0x437B	0x540D	# <CJK>
0x437C	0x547D	# <CJK>
0x437D	0x8B2C	# <CJK>
0x437E	0x6478	# <CJK>
0x4421	0x6479	# <CJK>
0x4422	0x8611	# <CJK>
0x4423	0x6A21	# <CJK>
0x4424	0x819C	# <CJK>
0x4425	0x78E8	# <CJK>
0x4426	0x6469	# <CJK>
0x4427	0x9B54	# <CJK>
0x4428	0x62B9	# <CJK>
0x4429	0x672B	# <CJK>
0x442A	0x83AB	# <CJK>
0x442B	0x58A8	# <CJK>
0x442C	0x9ED8	# <CJK>
0x442D	0x6CAB	# <CJK>
0x442E	0x6F20	# <CJK>
0x442F	0x5BDE	# <CJK>
0x4430	0x964C	# <CJK>
0x4431	0x8B00	# <CJK>
0x4432	0x725F	# <CJK>
0x4433	0x67D0	# <CJK>
0x4434	0x62C7	# <CJK>
0x4435	0x7261	# <CJK>
0x4436	0x755D	# <CJK>
0x4437	0x59C6	# <CJK>
0x4438	0x6BCD	# <CJK>
0x4439	0x5893	# <CJK>
0x443A	0x66AE	# <CJK>
0x443B	0x5E55	# <CJK>
0x443C	0x52DF	# <CJK>
0x443D	0x6155	# <CJK>
0x443E	0x6728	# <CJK>
0x443F	0x76EE	# <CJK>
0x4440	0x7766	# <CJK>
0x4441	0x7267	# <CJK>
0x4442	0x7A46	# <CJK>
0x4443	0x62FF	# <CJK>
0x4444	0x54EA	# <CJK>
0x4445	0x5450	# <CJK>
0x4446	0x9209	# <CJK>
0x4447	0x90A3	# <CJK>
0x4448	0x5A1C	# <CJK>
0x4449	0x7D0D	# <CJK>
0x444A	0x6C16	# <CJK>
0x444B	0x4E43	# <CJK>
0x444C	0x5976	# <CJK>
0x444D	0x8010	# <CJK>
0x444E	0x5948	# <CJK>
0x444F	0x5357	# <CJK>
0x4450	0x7537	# <CJK>
0x4451	0x96E3	# <CJK>
0x4452	0x56CA	# <CJK>
0x4453	0x6493	# <CJK>
0x4454	0x8166	# <CJK>
0x4455	0x60F1	# <CJK>
0x4456	0x9B27	# <CJK>
0x4457	0x6DD6	# <CJK>
0x4458	0x5462	# <CJK>
0x4459	0x9912	# <CJK>
0x445A	0x5185	# <CJK>
0x445B	0x5AE9	# <CJK>
0x445C	0x80FD	# <CJK>
0x445D	0x59AE	# <CJK>
0x445E	0x9713	# <CJK>
0x445F	0x502A	# <CJK>
0x4460	0x6CE5	# <CJK>
0x4461	0x5C3C	# <CJK>
0x4462	0x64EC	# <CJK>
0x4463	0x4F60	# <CJK>
0x4464	0x533F	# <CJK>
0x4465	0x81A9	# <CJK>
0x4466	0x9006	# <CJK>
0x4467	0x6EBA	# <CJK>
0x4468	0x852B	# <CJK>
0x4469	0x62C8	# <CJK>
0x446A	0x5E74	# <CJK>
0x446B	0x78BE	# <CJK>
0x446C	0x6506	# <CJK>
0x446D	0x637B	# <CJK>
0x446E	0x5FF5	# <CJK>
0x446F	0x5A18	# <CJK>
0x4470	0x91C0	# <CJK>
0x4471	0x9CE5	# <CJK>
0x4472	0x5C3F	# <CJK>
0x4473	0x634F	# <CJK>
0x4474	0x8076	# <CJK>
0x4475	0x5B7D	# <CJK>
0x4476	0x5699	# <CJK>
0x4477	0x9477	# <CJK>
0x4478	0x93B3	# <CJK>
0x4479	0x6D85	# <CJK>
0x447A	0x60A8	# <CJK>
0x447B	0x6AB8	# <CJK>
0x447C	0x7370	# <CJK>
0x447D	0x51DD	# <CJK>
0x447E	0x5BE7	# <CJK>
0x4521	0x64F0	# <CJK>
0x4522	0x6FD8	# <CJK>
0x4523	0x725B	# <CJK>
0x4524	0x626D	# <CJK>
0x4525	0x9215	# <CJK>
0x4526	0x7D10	# <CJK>
0x4527	0x81BF	# <CJK>
0x4528	0x6FC3	# <CJK>
0x4529	0x8FB2	# <CJK>
0x452A	0x5F04	# <CJK>
0x452B	0x5974	# <CJK>
0x452C	0x52AA	# <CJK>
0x452D	0x6012	# <CJK>
0x452E	0x5973	# <CJK>
0x452F	0x6696	# <CJK>
0x4530	0x8650	# <CJK>
0x4531	0x7627	# <CJK>
0x4532	0x632A	# <CJK>
0x4533	0x61E6	# <CJK>
0x4534	0x7CEF	# <CJK>
0x4535	0x8AFE	# <CJK>
0x4536	0x54E6	# <CJK>
0x4537	0x6B50	# <CJK>
0x4538	0x9DD7	# <CJK>
0x4539	0x6BC6	# <CJK>
0x453A	0x85D5	# <CJK>
0x453B	0x5614	# <CJK>
0x453C	0x5076	# <CJK>
0x453D	0x6F1A	# <CJK>
0x453E	0x556A	# <CJK>
0x453F	0x8DB4	# <CJK>
0x4540	0x722C	# <CJK>
0x4541	0x5E15	# <CJK>
0x4542	0x6015	# <CJK>
0x4543	0x7436	# <CJK>
0x4544	0x62CD	# <CJK>
0x4545	0x6392	# <CJK>
0x4546	0x724C	# <CJK>
0x4547	0x5F98	# <CJK>
0x4548	0x6E43	# <CJK>
0x4549	0x6D3E	# <CJK>
0x454A	0x6500	# <CJK>
0x454B	0x6F58	# <CJK>
0x454C	0x76E4	# <CJK>
0x454D	0x78D0	# <CJK>
0x454E	0x76FC	# <CJK>
0x454F	0x7554	# <CJK>
0x4550	0x5224	# <CJK>
0x4551	0x53DB	# <CJK>
0x4552	0x4E53	# <CJK>
0x4553	0x9F90	# <CJK>
0x4554	0x65C1	# <CJK>
0x4555	0x802A	# <CJK>
0x4556	0x80D6	# <CJK>
0x4557	0x629B	# <CJK>
0x4558	0x5486	# <CJK>
0x4559	0x5228	# <CJK>
0x455A	0x70AE	# <CJK>
0x455B	0x888D	# <CJK>
0x455C	0x8DD1	# <CJK>
0x455D	0x6CE1	# <CJK>
0x455E	0x5478	# <CJK>
0x455F	0x80DA	# <CJK>
0x4560	0x57F9	# <CJK>
0x4561	0x88F4	# <CJK>
0x4562	0x8CE0	# <CJK>
0x4563	0x966A	# <CJK>
0x4564	0x914D	# <CJK>
0x4565	0x4F69	# <CJK>
0x4566	0x6C9B	# <CJK>
0x4567	0x5674	# <CJK>
0x4568	0x76C6	# <CJK>
0x4569	0x7830	# <CJK>
0x456A	0x62A8	# <CJK>
0x456B	0x70F9	# <CJK>
0x456C	0x6F8E	# <CJK>
0x456D	0x5F6D	# <CJK>
0x456E	0x84EC	# <CJK>
0x456F	0x68DA	# <CJK>
0x4570	0x787C	# <CJK>
0x4571	0x7BF7	# <CJK>
0x4572	0x81A8	# <CJK>
0x4573	0x670B	# <CJK>
0x4574	0x9D6C	# <CJK>
0x4575	0x6367	# <CJK>
0x4576	0x78B0	# <CJK>
0x4577	0x576F	# <CJK>
0x4578	0x7812	# <CJK>
0x4579	0x9739	# <CJK>
0x457A	0x6279	# <CJK>
0x457B	0x62AB	# <CJK>
0x457C	0x5288	# <CJK>
0x457D	0x7435	# <CJK>
0x457E	0x6BD7	# <CJK>
0x4621	0x5564	# <CJK>
0x4622	0x813E	# <CJK>
0x4623	0x75B2	# <CJK>
0x4624	0x76AE	# <CJK>
0x4625	0x5339	# <CJK>
0x4626	0x75DE	# <CJK>
0x4627	0x50FB	# <CJK>
0x4628	0x5C41	# <CJK>
0x4629	0x8B6C	# <CJK>
0x462A	0x7BC7	# <CJK>
0x462B	0x504F	# <CJK>
0x462C	0x7247	# <CJK>
0x462D	0x9A19	# <CJK>
0x462E	0x98C4	# <CJK>
0x462F	0x6F02	# <CJK>
0x4630	0x74E2	# <CJK>
0x4631	0x7968	# <CJK>
0x4632	0x6487	# <CJK>
0x4633	0x77A5	# <CJK>
0x4634	0x62FC	# <CJK>
0x4635	0x983B	# <CJK>
0x4636	0x8CA7	# <CJK>
0x4637	0x54C1	# <CJK>
0x4638	0x8058	# <CJK>
0x4639	0x4E52	# <CJK>
0x463A	0x576A	# <CJK>
0x463B	0x860B	# <CJK>
0x463C	0x840D	# <CJK>
0x463D	0x5E73	# <CJK>
0x463E	0x6191	# <CJK>
0x463F	0x74F6	# <CJK>
0x4640	0x8A55	# <CJK>
0x4641	0x5C4F	# <CJK>
0x4642	0x5761	# <CJK>
0x4643	0x6F51	# <CJK>
0x4644	0x9817	# <CJK>
0x4645	0x5A46	# <CJK>
0x4646	0x7834	# <CJK>
0x4647	0x9B44	# <CJK>
0x4648	0x8FEB	# <CJK>
0x4649	0x7C95	# <CJK>
0x464A	0x5256	# <CJK>
0x464B	0x64B2	# <CJK>
0x464C	0x92EA	# <CJK>
0x464D	0x50D5	# <CJK>
0x464E	0x8386	# <CJK>
0x464F	0x8461	# <CJK>
0x4650	0x83E9	# <CJK>
0x4651	0x84B2	# <CJK>
0x4652	0x57D4	# <CJK>
0x4653	0x6A38	# <CJK>
0x4654	0x5703	# <CJK>
0x4655	0x666E	# <CJK>
0x4656	0x6D66	# <CJK>
0x4657	0x8B5C	# <CJK>
0x4658	0x66DD	# <CJK>
0x4659	0x7011	# <CJK>
0x465A	0x671F	# <CJK>
0x465B	0x6B3A	# <CJK>
0x465C	0x68F2	# <CJK>
0x465D	0x621A	# <CJK>
0x465E	0x59BB	# <CJK>
0x465F	0x4E03	# <CJK>
0x4660	0x51C4	# <CJK>
0x4661	0x6F06	# <CJK>
0x4662	0x67D2	# <CJK>
0x4663	0x6C8F	# <CJK>
0x4664	0x5176	# <CJK>
0x4665	0x68CB	# <CJK>
0x4666	0x5947	# <CJK>
0x4667	0x6B67	# <CJK>
0x4668	0x7566	# <CJK>
0x4669	0x5D0E	# <CJK>
0x466A	0x81CD	# <CJK>
0x466B	0x9F4A	# <CJK>
0x466C	0x65D7	# <CJK>
0x466D	0x7948	# <CJK>
0x466E	0x7941	# <CJK>
0x466F	0x9A0E	# <CJK>
0x4670	0x8D77	# <CJK>
0x4671	0x8C48	# <CJK>
0x4672	0x4E5E	# <CJK>
0x4673	0x4F01	# <CJK>
0x4674	0x5553	# <CJK>
0x4675	0x5951	# <CJK>
0x4676	0x780C	# <CJK>
0x4677	0x5668	# <CJK>
0x4678	0x6C23	# <CJK>
0x4679	0x8FC4	# <CJK>
0x467A	0x68C4	# <CJK>
0x467B	0x6C7D	# <CJK>
0x467C	0x6CE3	# <CJK>
0x467D	0x8A16	# <CJK>
0x467E	0x6390	# <CJK>
0x4721	0x6070	# <CJK>
0x4722	0x6D3D	# <CJK>
0x4723	0x727D	# <CJK>
0x4724	0x6266	# <CJK>
0x4725	0x91FA	# <CJK>
0x4726	0x925B	# <CJK>
0x4727	0x5343	# <CJK>
0x4728	0x9077	# <CJK>
0x4729	0x7C3D	# <CJK>
0x472A	0x4EDF	# <CJK>
0x472B	0x8B19	# <CJK>
0x472C	0x4E7E	# <CJK>
0x472D	0x9ED4	# <CJK>
0x472E	0x9322	# <CJK>
0x472F	0x9257	# <CJK>
0x4730	0x524D	# <CJK>
0x4731	0x6F5B	# <CJK>
0x4732	0x9063	# <CJK>
0x4733	0x6DFA	# <CJK>
0x4734	0x8B74	# <CJK>
0x4735	0x5879	# <CJK>
0x4736	0x5D4C	# <CJK>
0x4737	0x6B20	# <CJK>
0x4738	0x6B49	# <CJK>
0x4739	0x69CD	# <CJK>
0x473A	0x55C6	# <CJK>
0x473B	0x8154	# <CJK>
0x473C	0x7F8C	# <CJK>
0x473D	0x58BB	# <CJK>
0x473E	0x8594	# <CJK>
0x473F	0x5F3A	# <CJK>
0x4740	0x6436	# <CJK>
0x4741	0x6A47	# <CJK>
0x4742	0x936C	# <CJK>
0x4743	0x6572	# <CJK>
0x4744	0x6084	# <CJK>
0x4745	0x6A4B	# <CJK>
0x4746	0x77A7	# <CJK>
0x4747	0x55AC	# <CJK>
0x4748	0x50D1	# <CJK>
0x4749	0x5DE7	# <CJK>
0x474A	0x9798	# <CJK>
0x474B	0x64AC	# <CJK>
0x474C	0x7FF9	# <CJK>
0x474D	0x5CED	# <CJK>
0x474E	0x4FCF	# <CJK>
0x474F	0x7AC5	# <CJK>
0x4750	0x5207	# <CJK>
0x4751	0x8304	# <CJK>
0x4752	0x4E14	# <CJK>
0x4753	0x602F	# <CJK>
0x4754	0x7ACA	# <CJK>
0x4755	0x6B3D	# <CJK>
0x4756	0x4FB5	# <CJK>
0x4757	0x89AA	# <CJK>
0x4758	0x79E6	# <CJK>
0x4759	0x7434	# <CJK>
0x475A	0x52E4	# <CJK>
0x475B	0x82B9	# <CJK>
0x475C	0x64D2	# <CJK>
0x475D	0x79BD	# <CJK>
0x475E	0x5BE2	# <CJK>
0x475F	0x6C81	# <CJK>
0x4760	0x9752	# <CJK>
0x4761	0x8F15	# <CJK>
0x4762	0x6C2B	# <CJK>
0x4763	0x50BE	# <CJK>
0x4764	0x537F	# <CJK>
0x4765	0x6E05	# <CJK>
0x4766	0x64CE	# <CJK>
0x4767	0x6674	# <CJK>
0x4768	0x6C30	# <CJK>
0x4769	0x60C5	# <CJK>
0x476A	0x9803	# <CJK>
0x476B	0x8ACB	# <CJK>
0x476C	0x6176	# <CJK>
0x476D	0x74CA	# <CJK>
0x476E	0x7AAE	# <CJK>
0x476F	0x79CB	# <CJK>
0x4770	0x4E18	# <CJK>
0x4771	0x90B1	# <CJK>
0x4772	0x7403	# <CJK>
0x4773	0x6C42	# <CJK>
0x4774	0x56DA	# <CJK>
0x4775	0x914B	# <CJK>
0x4776	0x6CC5	# <CJK>
0x4777	0x8DA8	# <CJK>
0x4778	0x5340	# <CJK>
0x4779	0x86C6	# <CJK>
0x477A	0x66F2	# <CJK>
0x477B	0x8EC0	# <CJK>
0x477C	0x5C48	# <CJK>
0x477D	0x9A45	# <CJK>
0x477E	0x6E20	# <CJK>
0x4821	0x53D6	# <CJK>
0x4822	0x5A36	# <CJK>
0x4823	0x9F72	# <CJK>
0x4824	0x8DA3	# <CJK>
0x4825	0x53BB	# <CJK>
0x4826	0x5708	# <CJK>
0x4827	0x9874	# <CJK>
0x4828	0x6B0A	# <CJK>
0x4829	0x919B	# <CJK>
0x482A	0x6CC9	# <CJK>
0x482B	0x5168	# <CJK>
0x482C	0x75CA	# <CJK>
0x482D	0x62F3	# <CJK>
0x482E	0x72AC	# <CJK>
0x482F	0x5238	# <CJK>
0x4830	0x52F8	# <CJK>
0x4831	0x7F3A	# <CJK>
0x4832	0x7094	# <CJK>
0x4833	0x7638	# <CJK>
0x4834	0x5374	# <CJK>
0x4835	0x9D72	# <CJK>
0x4836	0x69B7	# <CJK>
0x4837	0x78BA	# <CJK>
0x4838	0x96C0	# <CJK>
0x4839	0x88D9	# <CJK>
0x483A	0x7FA4	# <CJK>
0x483B	0x7136	# <CJK>
0x483C	0x71C3	# <CJK>
0x483D	0x5189	# <CJK>
0x483E	0x67D3	# <CJK>
0x483F	0x74E4	# <CJK>
0x4840	0x58E4	# <CJK>
0x4841	0x6518	# <CJK>
0x4842	0x56B7	# <CJK>
0x4843	0x8B93	# <CJK>
0x4844	0x9952	# <CJK>
0x4845	0x64FE	# <CJK>
0x4846	0x7E5E	# <CJK>
0x4847	0x60F9	# <CJK>
0x4848	0x71B1	# <CJK>
0x4849	0x58EC	# <CJK>
0x484A	0x4EC1	# <CJK>
0x484B	0x4EBA	# <CJK>
0x484C	0x5FCD	# <CJK>
0x484D	0x97CC	# <CJK>
0x484E	0x4EFB	# <CJK>
0x484F	0x8A8D	# <CJK>
0x4850	0x5203	# <CJK>
0x4851	0x598A	# <CJK>
0x4852	0x7D09	# <CJK>
0x4853	0x6254	# <CJK>
0x4854	0x4ECD	# <CJK>
0x4855	0x65E5	# <CJK>
0x4856	0x620E	# <CJK>
0x4857	0x8338	# <CJK>
0x4858	0x84C9	# <CJK>
0x4859	0x69AE	# <CJK>
0x485A	0x878D	# <CJK>
0x485B	0x7194	# <CJK>
0x485C	0x6EB6	# <CJK>
0x485D	0x5BB9	# <CJK>
0x485E	0x7D68	# <CJK>
0x485F	0x5197	# <CJK>
0x4860	0x63C9	# <CJK>
0x4861	0x67D4	# <CJK>
0x4862	0x8089	# <CJK>
0x4863	0x8339	# <CJK>
0x4864	0x8815	# <CJK>
0x4865	0x5112	# <CJK>
0x4866	0x5B7A	# <CJK>
0x4867	0x5982	# <CJK>
0x4868	0x8FB1	# <CJK>
0x4869	0x4E73	# <CJK>
0x486A	0x6C5D	# <CJK>
0x486B	0x5165	# <CJK>
0x486C	0x8925	# <CJK>
0x486D	0x8EDF	# <CJK>
0x486E	0x962E	# <CJK>
0x486F	0x854A	# <CJK>
0x4870	0x745E	# <CJK>
0x4871	0x92ED	# <CJK>
0x4872	0x958F	# <CJK>
0x4873	0x6F64	# <CJK>
0x4874	0x82E5	# <CJK>
0x4875	0x5F31	# <CJK>
0x4876	0x6492	# <CJK>
0x4877	0x7051	# <CJK>
0x4878	0x85A9	# <CJK>
0x4879	0x816E	# <CJK>
0x487A	0x9C13	# <CJK>
0x487B	0x585E	# <CJK>
0x487C	0x8CFD	# <CJK>
0x487D	0x4E09	# <CJK>
0x487E	0x53C1	# <CJK>
0x4921	0x5098	# <CJK>
0x4922	0x6563	# <CJK>
0x4923	0x6851	# <CJK>
0x4924	0x55D3	# <CJK>
0x4925	0x55AA	# <CJK>
0x4926	0x6414	# <CJK>
0x4927	0x9A37	# <CJK>
0x4928	0x6383	# <CJK>
0x4929	0x5AC2	# <CJK>
0x492A	0x745F	# <CJK>
0x492B	0x8272	# <CJK>
0x492C	0x6F80	# <CJK>
0x492D	0x68EE	# <CJK>
0x492E	0x50E7	# <CJK>
0x492F	0x838E	# <CJK>
0x4930	0x7802	# <CJK>
0x4931	0x6BBA	# <CJK>
0x4932	0x5239	# <CJK>
0x4933	0x6C99	# <CJK>
0x4934	0x7D17	# <CJK>
0x4935	0x50BB	# <CJK>
0x4936	0x5565	# <CJK>
0x4937	0x715E	# <CJK>
0x4938	0x7BE9	# <CJK>
0x4939	0x66EC	# <CJK>
0x493A	0x73CA	# <CJK>
0x493B	0x82EB	# <CJK>
0x493C	0x6749	# <CJK>
0x493D	0x5C71	# <CJK>
0x493E	0x5220	# <CJK>
0x493F	0x717D	# <CJK>
0x4940	0x886B	# <CJK>
0x4941	0x9583	# <CJK>
0x4942	0x965D	# <CJK>
0x4943	0x64C5	# <CJK>
0x4944	0x8D0D	# <CJK>
0x4945	0x81B3	# <CJK>
0x4946	0x5584	# <CJK>
0x4947	0x6C55	# <CJK>
0x4948	0x6247	# <CJK>
0x4949	0x7E55	# <CJK>
0x494A	0x5892	# <CJK>
0x494B	0x50B7	# <CJK>
0x494C	0x5546	# <CJK>
0x494D	0x8CDE	# <CJK>
0x494E	0x664C	# <CJK>
0x494F	0x4E0A	# <CJK>
0x4950	0x5C1A	# <CJK>
0x4951	0x88F3	# <CJK>
0x4952	0x68A2	# <CJK>
0x4953	0x634E	# <CJK>
0x4954	0x7A0D	# <CJK>
0x4955	0x71D2	# <CJK>
0x4956	0x828D	# <CJK>
0x4957	0x52FA	# <CJK>
0x4958	0x97F6	# <CJK>
0x4959	0x5C11	# <CJK>
0x495A	0x54E8	# <CJK>
0x495B	0x90B5	# <CJK>
0x495C	0x7D39	# <CJK>
0x495D	0x5962	# <CJK>
0x495E	0x8CD2	# <CJK>
0x495F	0x86C7	# <CJK>
0x4960	0x820C	# <CJK>
0x4961	0x6368	# <CJK>
0x4962	0x8D66	# <CJK>
0x4963	0x651D	# <CJK>
0x4964	0x5C04	# <CJK>
0x4965	0x61FE	# <CJK>
0x4966	0x6D89	# <CJK>
0x4967	0x793E	# <CJK>
0x4968	0x8A2D	# <CJK>
0x4969	0x7837	# <CJK>
0x496A	0x7533	# <CJK>
0x496B	0x547B	# <CJK>
0x496C	0x4F38	# <CJK>
0x496D	0x8EAB	# <CJK>
0x496E	0x6DF1	# <CJK>
0x496F	0x5A20	# <CJK>
0x4970	0x7D33	# <CJK>
0x4971	0x795E	# <CJK>
0x4972	0x6C88	# <CJK>
0x4973	0x5BE9	# <CJK>
0x4974	0x5B38	# <CJK>
0x4975	0x751A	# <CJK>
0x4976	0x814E	# <CJK>
0x4977	0x614E	# <CJK>
0x4978	0x6EF2	# <CJK>
0x4979	0x8072	# <CJK>
0x497A	0x751F	# <CJK>
0x497B	0x7525	# <CJK>
0x497C	0x7272	# <CJK>
0x497D	0x5347	# <CJK>
0x497E	0x7E69	# <CJK>
0x4A21	0x7701	# <CJK>
0x4A22	0x76DB	# <CJK>
0x4A23	0x5269	# <CJK>
0x4A24	0x52DD	# <CJK>
0x4A25	0x8056	# <CJK>
0x4A26	0x5E2B	# <CJK>
0x4A27	0x5931	# <CJK>
0x4A28	0x7345	# <CJK>
0x4A29	0x65BD	# <CJK>
0x4A2A	0x6FD5	# <CJK>
0x4A2B	0x8A69	# <CJK>
0x4A2C	0x5C38	# <CJK>
0x4A2D	0x8671	# <CJK>
0x4A2E	0x5341	# <CJK>
0x4A2F	0x77F3	# <CJK>
0x4A30	0x62FE	# <CJK>
0x4A31	0x6642	# <CJK>
0x4A32	0x4EC0	# <CJK>
0x4A33	0x98DF	# <CJK>
0x4A34	0x8755	# <CJK>
0x4A35	0x5BE6	# <CJK>
0x4A36	0x8B58	# <CJK>
0x4A37	0x53F2	# <CJK>
0x4A38	0x77E2	# <CJK>
0x4A39	0x4F7F	# <CJK>
0x4A3A	0x5C4E	# <CJK>
0x4A3B	0x99DB	# <CJK>
0x4A3C	0x59CB	# <CJK>
0x4A3D	0x5F0F	# <CJK>
0x4A3E	0x793A	# <CJK>
0x4A3F	0x58EB	# <CJK>
0x4A40	0x4E16	# <CJK>
0x4A41	0x67FF	# <CJK>
0x4A42	0x4E8B	# <CJK>
0x4A43	0x62ED	# <CJK>
0x4A44	0x8A93	# <CJK>
0x4A45	0x901D	# <CJK>
0x4A46	0x52E2	# <CJK>
0x4A47	0x662F	# <CJK>
0x4A48	0x55DC	# <CJK>
0x4A49	0x566C	# <CJK>
0x4A4A	0x9069	# <CJK>
0x4A4B	0x4ED5	# <CJK>
0x4A4C	0x4F8D	# <CJK>
0x4A4D	0x91CB	# <CJK>
0x4A4E	0x98FE	# <CJK>
0x4A4F	0x6C0F	# <CJK>
0x4A50	0x5E02	# <CJK>
0x4A51	0x6043	# <CJK>
0x4A52	0x5BA4	# <CJK>
0x4A53	0x8996	# <CJK>
0x4A54	0x8A66	# <CJK>
0x4A55	0x6536	# <CJK>
0x4A56	0x624B	# <CJK>
0x4A57	0x9996	# <CJK>
0x4A58	0x5B88	# <CJK>
0x4A59	0x58FD	# <CJK>
0x4A5A	0x6388	# <CJK>
0x4A5B	0x552E	# <CJK>
0x4A5C	0x53D7	# <CJK>
0x4A5D	0x7626	# <CJK>
0x4A5E	0x7378	# <CJK>
0x4A5F	0x852C	# <CJK>
0x4A60	0x6A1E	# <CJK>
0x4A61	0x68B3	# <CJK>
0x4A62	0x6B8A	# <CJK>
0x4A63	0x6292	# <CJK>
0x4A64	0x8F38	# <CJK>
0x4A65	0x53D4	# <CJK>
0x4A66	0x8212	# <CJK>
0x4A67	0x6DD1	# <CJK>
0x4A68	0x758F	# <CJK>
0x4A69	0x66F8	# <CJK>
0x4A6A	0x8D16	# <CJK>
0x4A6B	0x5B70	# <CJK>
0x4A6C	0x719F	# <CJK>
0x4A6D	0x85AF	# <CJK>
0x4A6E	0x6691	# <CJK>
0x4A6F	0x66D9	# <CJK>
0x4A70	0x7F72	# <CJK>
0x4A71	0x8700	# <CJK>
0x4A72	0x9ECD	# <CJK>
0x4A73	0x9F20	# <CJK>
0x4A74	0x5C6C	# <CJK>
0x4A75	0x8853	# <CJK>
0x4A76	0x8FF0	# <CJK>
0x4A77	0x6A39	# <CJK>
0x4A78	0x675F	# <CJK>
0x4A79	0x620D	# <CJK>
0x4A7A	0x7AEA	# <CJK>
0x4A7B	0x5885	# <CJK>
0x4A7C	0x5EB6	# <CJK>
0x4A7D	0x6578	# <CJK>
0x4A7E	0x6F31	# <CJK>
0x4B21	0x6055	# <CJK>
0x4B22	0x5237	# <CJK>
0x4B23	0x800D	# <CJK>
0x4B24	0x6454	# <CJK>
0x4B25	0x8870	# <CJK>
0x4B26	0x7529	# <CJK>
0x4B27	0x5E25	# <CJK>
0x4B28	0x6813	# <CJK>
0x4B29	0x62F4	# <CJK>
0x4B2A	0x971C	# <CJK>
0x4B2B	0x96D9	# <CJK>
0x4B2C	0x723D	# <CJK>
0x4B2D	0x8AB0	# <CJK>
0x4B2E	0x6C34	# <CJK>
0x4B2F	0x7761	# <CJK>
0x4B30	0x7A0E	# <CJK>
0x4B31	0x542E	# <CJK>
0x4B32	0x77AC	# <CJK>
0x4B33	0x9806	# <CJK>
0x4B34	0x821C	# <CJK>
0x4B35	0x8AAC	# <CJK>
0x4B36	0x78A9	# <CJK>
0x4B37	0x6714	# <CJK>
0x4B38	0x720D	# <CJK>
0x4B39	0x65AF	# <CJK>
0x4B3A	0x6495	# <CJK>
0x4B3B	0x5636	# <CJK>
0x4B3C	0x601D	# <CJK>
0x4B3D	0x79C1	# <CJK>
0x4B3E	0x53F8	# <CJK>
0x4B3F	0x7D72	# <CJK>
0x4B40	0x6B7B	# <CJK>
0x4B41	0x8086	# <CJK>
0x4B42	0x5BFA	# <CJK>
0x4B43	0x55E3	# <CJK>
0x4B44	0x56DB	# <CJK>
0x4B45	0x4F3A	# <CJK>
0x4B46	0x4F3C	# <CJK>
0x4B47	0x98FC	# <CJK>
0x4B48	0x5DF3	# <CJK>
0x4B49	0x9B06	# <CJK>
0x4B4A	0x8073	# <CJK>
0x4B4B	0x616B	# <CJK>
0x4B4C	0x980C	# <CJK>
0x4B4D	0x9001	# <CJK>
0x4B4E	0x5B8B	# <CJK>
0x4B4F	0x8A1F	# <CJK>
0x4B50	0x8AA6	# <CJK>
0x4B51	0x641C	# <CJK>
0x4B52	0x8258	# <CJK>
0x4B53	0x64FB	# <CJK>
0x4B54	0x55FD	# <CJK>
0x4B55	0x8607	# <CJK>
0x4B56	0x9165	# <CJK>
0x4B57	0x4FD7	# <CJK>
0x4B58	0x7D20	# <CJK>
0x4B59	0x901F	# <CJK>
0x4B5A	0x7C9F	# <CJK>
0x4B5B	0x50F3	# <CJK>
0x4B5C	0x5851	# <CJK>
0x4B5D	0x6EAF	# <CJK>
0x4B5E	0x5BBF	# <CJK>
0x4B5F	0x8A34	# <CJK>
0x4B60	0x8085	# <CJK>
0x4B61	0x9178	# <CJK>
0x4B62	0x849C	# <CJK>
0x4B63	0x7B97	# <CJK>
0x4B64	0x96D6	# <CJK>
0x4B65	0x968B	# <CJK>
0x4B66	0x96A8	# <CJK>
0x4B67	0x7D8F	# <CJK>
0x4B68	0x9AD3	# <CJK>
0x4B69	0x788E	# <CJK>
0x4B6A	0x6B72	# <CJK>
0x4B6B	0x7A57	# <CJK>
0x4B6C	0x9042	# <CJK>
0x4B6D	0x96A7	# <CJK>
0x4B6E	0x795F	# <CJK>
0x4B6F	0x5B6B	# <CJK>
0x4B70	0x640D	# <CJK>
0x4B71	0x7B0B	# <CJK>
0x4B72	0x84D1	# <CJK>
0x4B73	0x68AD	# <CJK>
0x4B74	0x5506	# <CJK>
0x4B75	0x7E2E	# <CJK>
0x4B76	0x7463	# <CJK>
0x4B77	0x7D22	# <CJK>
0x4B78	0x9396	# <CJK>
0x4B79	0x6240	# <CJK>
0x4B7A	0x584C	# <CJK>
0x4B7B	0x4ED6	# <CJK>
0x4B7C	0x5B83	# <CJK>
0x4B7D	0x5979	# <CJK>
0x4B7E	0x5854	# <CJK>
0x4C21	0x737A	# <CJK>
0x4C22	0x64BB	# <CJK>
0x4C23	0x8E4B	# <CJK>
0x4C24	0x8E0F	# <CJK>
0x4C25	0x80CE	# <CJK>
0x4C26	0x82D4	# <CJK>
0x4C27	0x62AC	# <CJK>
0x4C28	0x81FA	# <CJK>
0x4C29	0x6CF0	# <CJK>
0x4C2A	0x915E	# <CJK>
0x4C2B	0x592A	# <CJK>
0x4C2C	0x614B	# <CJK>
0x4C2D	0x6C70	# <CJK>
0x4C2E	0x574D	# <CJK>
0x4C2F	0x6524	# <CJK>
0x4C30	0x8CAA	# <CJK>
0x4C31	0x7671	# <CJK>
0x4C32	0x7058	# <CJK>
0x4C33	0x58C7	# <CJK>
0x4C34	0x6A80	# <CJK>
0x4C35	0x75F0	# <CJK>
0x4C36	0x6F6D	# <CJK>
0x4C37	0x8B5A	# <CJK>
0x4C38	0x8AC7	# <CJK>
0x4C39	0x5766	# <CJK>
0x4C3A	0x6BEF	# <CJK>
0x4C3B	0x8892	# <CJK>
0x4C3C	0x78B3	# <CJK>
0x4C3D	0x63A2	# <CJK>
0x4C3E	0x5606	# <CJK>
0x4C3F	0x70AD	# <CJK>
0x4C40	0x6E6F	# <CJK>
0x4C41	0x5858	# <CJK>
0x4C42	0x642A	# <CJK>
0x4C43	0x5802	# <CJK>
0x4C44	0x68E0	# <CJK>
0x4C45	0x819B	# <CJK>
0x4C46	0x5510	# <CJK>
0x4C47	0x7CD6	# <CJK>
0x4C48	0x5018	# <CJK>
0x4C49	0x8EBA	# <CJK>
0x4C4A	0x6DCC	# <CJK>
0x4C4B	0x8D9F	# <CJK>
0x4C4C	0x71D9	# <CJK>
0x4C4D	0x638F	# <CJK>
0x4C4E	0x6FE4	# <CJK>
0x4C4F	0x6ED4	# <CJK>
0x4C50	0x7E27	# <CJK>
0x4C51	0x8404	# <CJK>
0x4C52	0x6843	# <CJK>
0x4C53	0x9003	# <CJK>
0x4C54	0x6DD8	# <CJK>
0x4C55	0x9676	# <CJK>
0x4C56	0x8A0E	# <CJK>
0x4C57	0x5957	# <CJK>
0x4C58	0x7279	# <CJK>
0x4C59	0x85E4	# <CJK>
0x4C5A	0x9A30	# <CJK>
0x4C5B	0x75BC	# <CJK>
0x4C5C	0x8B04	# <CJK>
0x4C5D	0x68AF	# <CJK>
0x4C5E	0x5254	# <CJK>
0x4C5F	0x8E22	# <CJK>
0x4C60	0x92BB	# <CJK>
0x4C61	0x63D0	# <CJK>
0x4C62	0x984C	# <CJK>
0x4C63	0x8E44	# <CJK>
0x4C64	0x557C	# <CJK>
0x4C65	0x9AD4	# <CJK>
0x4C66	0x66FF	# <CJK>
0x4C67	0x568F	# <CJK>
0x4C68	0x60D5	# <CJK>
0x4C69	0x6D95	# <CJK>
0x4C6A	0x5243	# <CJK>
0x4C6B	0x5C49	# <CJK>
0x4C6C	0x5929	# <CJK>
0x4C6D	0x6DFB	# <CJK>
0x4C6E	0x586B	# <CJK>
0x4C6F	0x7530	# <CJK>
0x4C70	0x751C	# <CJK>
0x4C71	0x606C	# <CJK>
0x4C72	0x8214	# <CJK>
0x4C73	0x8146	# <CJK>
0x4C74	0x6311	# <CJK>
0x4C75	0x689D	# <CJK>
0x4C76	0x8FE2	# <CJK>
0x4C77	0x773A	# <CJK>
0x4C78	0x8DF3	# <CJK>
0x4C79	0x8CBC	# <CJK>
0x4C7A	0x9435	# <CJK>
0x4C7B	0x5E16	# <CJK>
0x4C7C	0x5EF3	# <CJK>
0x4C7D	0x807D	# <CJK>
0x4C7E	0x70F4	# <CJK>
0x4D21	0x6C40	# <CJK>
0x4D22	0x5EF7	# <CJK>
0x4D23	0x505C	# <CJK>
0x4D24	0x4EAD	# <CJK>
0x4D25	0x5EAD	# <CJK>
0x4D26	0x633A	# <CJK>
0x4D27	0x8247	# <CJK>
0x4D28	0x901A	# <CJK>
0x4D29	0x6850	# <CJK>
0x4D2A	0x916E	# <CJK>
0x4D2B	0x77B3	# <CJK>
0x4D2C	0x540C	# <CJK>
0x4D2D	0x9285	# <CJK>
0x4D2E	0x5F64	# <CJK>
0x4D2F	0x7AE5	# <CJK>
0x4D30	0x6876	# <CJK>
0x4D31	0x6345	# <CJK>
0x4D32	0x7B52	# <CJK>
0x4D33	0x7D71	# <CJK>
0x4D34	0x75DB	# <CJK>
0x4D35	0x5077	# <CJK>
0x4D36	0x6295	# <CJK>
0x4D37	0x982D	# <CJK>
0x4D38	0x900F	# <CJK>
0x4D39	0x51F8	# <CJK>
0x4D3A	0x79C3	# <CJK>
0x4D3B	0x7A81	# <CJK>
0x4D3C	0x5716	# <CJK>
0x4D3D	0x5F92	# <CJK>
0x4D3E	0x9014	# <CJK>
0x4D3F	0x5857	# <CJK>
0x4D40	0x5C60	# <CJK>
0x4D41	0x571F	# <CJK>
0x4D42	0x5410	# <CJK>
0x4D43	0x5154	# <CJK>
0x4D44	0x6E4D	# <CJK>
0x4D45	0x5718	# <CJK>
0x4D46	0x63A8	# <CJK>
0x4D47	0x983D	# <CJK>
0x4D48	0x817F	# <CJK>
0x4D49	0x8715	# <CJK>
0x4D4A	0x892A	# <CJK>
0x4D4B	0x9000	# <CJK>
0x4D4C	0x541E	# <CJK>
0x4D4D	0x5C6F	# <CJK>
0x4D4E	0x81C0	# <CJK>
0x4D4F	0x62D6	# <CJK>
0x4D50	0x6258	# <CJK>
0x4D51	0x8131	# <CJK>
0x4D52	0x9D15	# <CJK>
0x4D53	0x9640	# <CJK>
0x4D54	0x99B1	# <CJK>
0x4D55	0x99DD	# <CJK>
0x4D56	0x6A62	# <CJK>
0x4D57	0x59A5	# <CJK>
0x4D58	0x62D3	# <CJK>
0x4D59	0x553E	# <CJK>
0x4D5A	0x6316	# <CJK>
0x4D5B	0x54C7	# <CJK>
0x4D5C	0x86D9	# <CJK>
0x4D5D	0x7AAA	# <CJK>
0x4D5E	0x5A03	# <CJK>
0x4D5F	0x74E6	# <CJK>
0x4D60	0x896A	# <CJK>
0x4D61	0x6B6A	# <CJK>
0x4D62	0x5916	# <CJK>
0x4D63	0x8C4C	# <CJK>
0x4D64	0x5F4E	# <CJK>
0x4D65	0x7063	# <CJK>
0x4D66	0x73A9	# <CJK>
0x4D67	0x9811	# <CJK>
0x4D68	0x4E38	# <CJK>
0x4D69	0x70F7	# <CJK>
0x4D6A	0x5B8C	# <CJK>
0x4D6B	0x7897	# <CJK>
0x4D6C	0x633D	# <CJK>
0x4D6D	0x665A	# <CJK>
0x4D6E	0x7696	# <CJK>
0x4D6F	0x60CB	# <CJK>
0x4D70	0x5B9B	# <CJK>
0x4D71	0x5A49	# <CJK>
0x4D72	0x842C	# <CJK>
0x4D73	0x8155	# <CJK>
0x4D74	0x6C6A	# <CJK>
0x4D75	0x738B	# <CJK>
0x4D76	0x4EA1	# <CJK>
0x4D77	0x6789	# <CJK>
0x4D78	0x7DB2	# <CJK>
0x4D79	0x5F80	# <CJK>
0x4D7A	0x65FA	# <CJK>
0x4D7B	0x671B	# <CJK>
0x4D7C	0x5FD8	# <CJK>
0x4D7D	0x5984	# <CJK>
0x4D7E	0x5A01	# <CJK>
0x4E21	0x5DCD	# <CJK>
0x4E22	0x5FAE	# <CJK>
0x4E23	0x5371	# <CJK>
0x4E24	0x97CB	# <CJK>
0x4E25	0x9055	# <CJK>
0x4E26	0x6845	# <CJK>
0x4E27	0x570D	# <CJK>
0x4E28	0x552F	# <CJK>
0x4E29	0x60DF	# <CJK>
0x4E2A	0x7232	# <CJK>
0x4E2B	0x6FF0	# <CJK>
0x4E2C	0x7DAD	# <CJK>
0x4E2D	0x8466	# <CJK>
0x4E2E	0x840E	# <CJK>
0x4E2F	0x59D4	# <CJK>
0x4E30	0x5049	# <CJK>
0x4E31	0x50DE	# <CJK>
0x4E32	0x5C3E	# <CJK>
0x4E33	0x7DEF	# <CJK>
0x4E34	0x672A	# <CJK>
0x4E35	0x851A	# <CJK>
0x4E36	0x5473	# <CJK>
0x4E37	0x754F	# <CJK>
0x4E38	0x80C3	# <CJK>
0x4E39	0x5582	# <CJK>
0x4E3A	0x9B4F	# <CJK>
0x4E3B	0x4F4D	# <CJK>
0x4E3C	0x6E2D	# <CJK>
0x4E3D	0x8B02	# <CJK>
0x4E3E	0x5C09	# <CJK>
0x4E3F	0x6170	# <CJK>
0x4E40	0x885B	# <CJK>
0x4E41	0x761F	# <CJK>
0x4E42	0x6E29	# <CJK>
0x4E43	0x868A	# <CJK>
0x4E44	0x6587	# <CJK>
0x4E45	0x805E	# <CJK>
0x4E46	0x7D0B	# <CJK>
0x4E47	0x543B	# <CJK>
0x4E48	0x7A69	# <CJK>
0x4E49	0x7D0A	# <CJK>
0x4E4A	0x554F	# <CJK>
0x4E4B	0x55E1	# <CJK>
0x4E4C	0x7FC1	# <CJK>
0x4E4D	0x74EE	# <CJK>
0x4E4E	0x64BE	# <CJK>
0x4E4F	0x8778	# <CJK>
0x4E50	0x6E26	# <CJK>
0x4E51	0x7AA9	# <CJK>
0x4E52	0x6211	# <CJK>
0x4E53	0x65A1	# <CJK>
0x4E54	0x5367	# <CJK>
0x4E55	0x63E1	# <CJK>
0x4E56	0x6C83	# <CJK>
0x4E57	0x5DEB	# <CJK>
0x4E58	0x55DA	# <CJK>
0x4E59	0x93A2	# <CJK>
0x4E5A	0x70CF	# <CJK>
0x4E5B	0x6C61	# <CJK>
0x4E5C	0x8AA3	# <CJK>
0x4E5D	0x5C4B	# <CJK>
0x4E5E	0x7121	# <CJK>
0x4E5F	0x856A	# <CJK>
0x4E60	0x68A7	# <CJK>
0x4E61	0x543E	# <CJK>
0x4E62	0x5434	# <CJK>
0x4E63	0x6BCB	# <CJK>
0x4E64	0x6B66	# <CJK>
0x4E65	0x4E94	# <CJK>
0x4E66	0x6342	# <CJK>
0x4E67	0x5348	# <CJK>
0x4E68	0x821E	# <CJK>
0x4E69	0x4F0D	# <CJK>
0x4E6A	0x4FAE	# <CJK>
0x4E6B	0x5862	# <CJK>
0x4E6C	0x620A	# <CJK>
0x4E6D	0x9727	# <CJK>
0x4E6E	0x6664	# <CJK>
0x4E6F	0x7269	# <CJK>
0x4E70	0x52FF	# <CJK>
0x4E71	0x52D9	# <CJK>
0x4E72	0x609F	# <CJK>
0x4E73	0x8AA4	# <CJK>
0x4E74	0x6614	# <CJK>
0x4E75	0x7199	# <CJK>
0x4E76	0x6790	# <CJK>
0x4E77	0x897F	# <CJK>
0x4E78	0x7852	# <CJK>
0x4E79	0x77FD	# <CJK>
0x4E7A	0x6670	# <CJK>
0x4E7B	0x563B	# <CJK>
0x4E7C	0x5438	# <CJK>
0x4E7D	0x932B	# <CJK>
0x4E7E	0x72A7	# <CJK>
0x4F21	0x7A00	# <CJK>
0x4F22	0x606F	# <CJK>
0x4F23	0x5E0C	# <CJK>
0x4F24	0x6089	# <CJK>
0x4F25	0x819D	# <CJK>
0x4F26	0x5915	# <CJK>
0x4F27	0x60DC	# <CJK>
0x4F28	0x7184	# <CJK>
0x4F29	0x70EF	# <CJK>
0x4F2A	0x6EAA	# <CJK>
0x4F2B	0x6C50	# <CJK>
0x4F2C	0x7280	# <CJK>
0x4F2D	0x6A84	# <CJK>
0x4F2E	0x8972	# <CJK>
0x4F2F	0x5E2D	# <CJK>
0x4F30	0x7FD2	# <CJK>
0x4F31	0x5AB3	# <CJK>
0x4F32	0x559C	# <CJK>
0x4F33	0x9291	# <CJK>
0x4F34	0x6D17	# <CJK>
0x4F35	0x7CFB	# <CJK>
0x4F36	0x9699	# <CJK>
0x4F37	0x6232	# <CJK>
0x4F38	0x7D30	# <CJK>
0x4F39	0x778E	# <CJK>
0x4F3A	0x8766	# <CJK>
0x4F3B	0x5323	# <CJK>
0x4F3C	0x971E	# <CJK>
0x4F3D	0x8F44	# <CJK>
0x4F3E	0x6687	# <CJK>
0x4F3F	0x5CFD	# <CJK>
0x4F40	0x4FE0	# <CJK>
0x4F41	0x72F9	# <CJK>
0x4F42	0x4E0B	# <CJK>
0x4F43	0x53A6	# <CJK>
0x4F44	0x590F	# <CJK>
0x4F45	0x5687	# <CJK>
0x4F46	0x6380	# <CJK>
0x4F47	0x9341	# <CJK>
0x4F48	0x5148	# <CJK>
0x4F49	0x4ED9	# <CJK>
0x4F4A	0x9BAE	# <CJK>
0x4F4B	0x7E96	# <CJK>
0x4F4C	0x54B8	# <CJK>
0x4F4D	0x8CE2	# <CJK>
0x4F4E	0x929C	# <CJK>
0x4F4F	0x8237	# <CJK>
0x4F50	0x9591	# <CJK>
0x4F51	0x6D8E	# <CJK>
0x4F52	0x5F26	# <CJK>
0x4F53	0x5ACC	# <CJK>
0x4F54	0x986F	# <CJK>
0x4F55	0x96AA	# <CJK>
0x4F56	0x73FE	# <CJK>
0x4F57	0x737B	# <CJK>
0x4F58	0x7E23	# <CJK>
0x4F59	0x817A	# <CJK>
0x4F5A	0x9921	# <CJK>
0x4F5B	0x7FA1	# <CJK>
0x4F5C	0x61B2	# <CJK>
0x4F5D	0x9677	# <CJK>
0x4F5E	0x9650	# <CJK>
0x4F5F	0x7DAB	# <CJK>
0x4F60	0x76F8	# <CJK>
0x4F61	0x53A2	# <CJK>
0x4F62	0x9472	# <CJK>
0x4F63	0x9999	# <CJK>
0x4F64	0x7BB1	# <CJK>
0x4F65	0x8944	# <CJK>
0x4F66	0x6E58	# <CJK>
0x4F67	0x9109	# <CJK>
0x4F68	0x7FD4	# <CJK>
0x4F69	0x7965	# <CJK>
0x4F6A	0x8A73	# <CJK>
0x4F6B	0x60F3	# <CJK>
0x4F6C	0x97FF	# <CJK>
0x4F6D	0x4EAB	# <CJK>
0x4F6E	0x9805	# <CJK>
0x4F6F	0x5DF7	# <CJK>
0x4F70	0x6A61	# <CJK>
0x4F71	0x50CF	# <CJK>
0x4F72	0x5411	# <CJK>
0x4F73	0x8C61	# <CJK>
0x4F74	0x856D	# <CJK>
0x4F75	0x785D	# <CJK>
0x4F76	0x9704	# <CJK>
0x4F77	0x524A	# <CJK>
0x4F78	0x54EE	# <CJK>
0x4F79	0x56C2	# <CJK>
0x4F7A	0x92B7	# <CJK>
0x4F7B	0x6D88	# <CJK>
0x4F7C	0x5BB5	# <CJK>
0x4F7D	0x6DC6	# <CJK>
0x4F7E	0x66C9	# <CJK>
0x5021	0x5C0F	# <CJK>
0x5022	0x5B5D	# <CJK>
0x5023	0x6821	# <CJK>
0x5024	0x8096	# <CJK>
0x5025	0x562F	# <CJK>
0x5026	0x7B11	# <CJK>
0x5027	0x6548	# <CJK>
0x5028	0x6954	# <CJK>
0x5029	0x4E9B	# <CJK>
0x502A	0x6B47	# <CJK>
0x502B	0x874E	# <CJK>
0x502C	0x978B	# <CJK>
0x502D	0x5354	# <CJK>
0x502E	0x633E	# <CJK>
0x502F	0x643A	# <CJK>
0x5030	0x90AA	# <CJK>
0x5031	0x659C	# <CJK>
0x5032	0x8105	# <CJK>
0x5033	0x8AE7	# <CJK>
0x5034	0x5BEB	# <CJK>
0x5035	0x68B0	# <CJK>
0x5036	0x5378	# <CJK>
0x5037	0x87F9	# <CJK>
0x5038	0x61C8	# <CJK>
0x5039	0x6CC4	# <CJK>
0x503A	0x7009	# <CJK>
0x503B	0x8B1D	# <CJK>
0x503C	0x5C51	# <CJK>
0x503D	0x85AA	# <CJK>
0x503E	0x82AF	# <CJK>
0x503F	0x92C5	# <CJK>
0x5040	0x6B23	# <CJK>
0x5041	0x8F9B	# <CJK>
0x5042	0x65B0	# <CJK>
0x5043	0x5FFB	# <CJK>
0x5044	0x5FC3	# <CJK>
0x5045	0x4FE1	# <CJK>
0x5046	0x91C1	# <CJK>
0x5047	0x661F	# <CJK>
0x5048	0x8165	# <CJK>
0x5049	0x7329	# <CJK>
0x504A	0x60FA	# <CJK>
0x504B	0x8208	# <CJK>
0x504C	0x5211	# <CJK>
0x504D	0x578B	# <CJK>
0x504E	0x5F62	# <CJK>
0x504F	0x90A2	# <CJK>
0x5050	0x884C	# <CJK>
0x5051	0x9192	# <CJK>
0x5052	0x5E78	# <CJK>
0x5053	0x674F	# <CJK>
0x5054	0x6027	# <CJK>
0x5055	0x59D3	# <CJK>
0x5056	0x5144	# <CJK>
0x5057	0x51F6	# <CJK>
0x5058	0x80F8	# <CJK>
0x5059	0x5308	# <CJK>
0x505A	0x6C79	# <CJK>
0x505B	0x96C4	# <CJK>
0x505C	0x718A	# <CJK>
0x505D	0x4F11	# <CJK>
0x505E	0x4FEE	# <CJK>
0x505F	0x7F9E	# <CJK>
0x5060	0x673D	# <CJK>
0x5061	0x55C5	# <CJK>
0x5062	0x92B9	# <CJK>
0x5063	0x79C0	# <CJK>
0x5064	0x8896	# <CJK>
0x5065	0x7D89	# <CJK>
0x5066	0x589F	# <CJK>
0x5067	0x620C	# <CJK>
0x5068	0x9700	# <CJK>
0x5069	0x865A	# <CJK>
0x506A	0x5618	# <CJK>
0x506B	0x9808	# <CJK>
0x506C	0x5F90	# <CJK>
0x506D	0x8A31	# <CJK>
0x506E	0x84C4	# <CJK>
0x506F	0x9157	# <CJK>
0x5070	0x53D9	# <CJK>
0x5071	0x65ED	# <CJK>
0x5072	0x5E8F	# <CJK>
0x5073	0x755C	# <CJK>
0x5074	0x6064	# <CJK>
0x5075	0x7D6E	# <CJK>
0x5076	0x5A7F	# <CJK>
0x5077	0x7DD2	# <CJK>
0x5078	0x7E8C	# <CJK>
0x5079	0x8ED2	# <CJK>
0x507A	0x55A7	# <CJK>
0x507B	0x5BA3	# <CJK>
0x507C	0x61F8	# <CJK>
0x507D	0x65CB	# <CJK>
0x507E	0x7384	# <CJK>
0x5121	0x9078	# <CJK>
0x5122	0x766C	# <CJK>
0x5123	0x7729	# <CJK>
0x5124	0x7D62	# <CJK>
0x5125	0x9774	# <CJK>
0x5126	0x859B	# <CJK>
0x5127	0x5B78	# <CJK>
0x5128	0x7A74	# <CJK>
0x5129	0x96EA	# <CJK>
0x512A	0x8840	# <CJK>
0x512B	0x52DB	# <CJK>
0x512C	0x718F	# <CJK>
0x512D	0x5FAA	# <CJK>
0x512E	0x65EC	# <CJK>
0x512F	0x8A62	# <CJK>
0x5130	0x5C0B	# <CJK>
0x5131	0x99B4	# <CJK>
0x5132	0x5DE1	# <CJK>
0x5133	0x6B89	# <CJK>
0x5134	0x6C5B	# <CJK>
0x5135	0x8A13	# <CJK>
0x5136	0x8A0A	# <CJK>
0x5137	0x905C	# <CJK>
0x5138	0x8FC5	# <CJK>
0x5139	0x58D3	# <CJK>
0x513A	0x62BC	# <CJK>
0x513B	0x9D09	# <CJK>
0x513C	0x9D28	# <CJK>
0x513D	0x5440	# <CJK>
0x513E	0x4E2B	# <CJK>
0x513F	0x82BD	# <CJK>
0x5140	0x7259	# <CJK>
0x5141	0x869C	# <CJK>
0x5142	0x5D16	# <CJK>
0x5143	0x8859	# <CJK>
0x5144	0x6DAF	# <CJK>
0x5145	0x96C5	# <CJK>
0x5146	0x555E	# <CJK>
0x5147	0x4E9E	# <CJK>
0x5148	0x8A1D	# <CJK>
0x5149	0x7109	# <CJK>
0x514A	0x54BD	# <CJK>
0x514B	0x95B9	# <CJK>
0x514C	0x70DF	# <CJK>
0x514D	0x6DF9	# <CJK>
0x514E	0x9E7D	# <CJK>
0x514F	0x56B4	# <CJK>
0x5150	0x7814	# <CJK>
0x5151	0x8712	# <CJK>
0x5152	0x5CA9	# <CJK>
0x5153	0x5EF6	# <CJK>
0x5154	0x8A00	# <CJK>
0x5155	0x9854	# <CJK>
0x5156	0x95BB	# <CJK>
0x5157	0x708E	# <CJK>
0x5158	0x6CBF	# <CJK>
0x5159	0x5944	# <CJK>
0x515A	0x63A9	# <CJK>
0x515B	0x773C	# <CJK>
0x515C	0x884D	# <CJK>
0x515D	0x6F14	# <CJK>
0x515E	0x8277	# <CJK>
0x515F	0x5830	# <CJK>
0x5160	0x71D5	# <CJK>
0x5161	0x53AD	# <CJK>
0x5162	0x786F	# <CJK>
0x5163	0x96C1	# <CJK>
0x5164	0x5501	# <CJK>
0x5165	0x5F66	# <CJK>
0x5166	0x7130	# <CJK>
0x5167	0x5BB4	# <CJK>
0x5168	0x8AFA	# <CJK>
0x5169	0x9A57	# <CJK>
0x516A	0x6B83	# <CJK>
0x516B	0x592E	# <CJK>
0x516C	0x9D26	# <CJK>
0x516D	0x79E7	# <CJK>
0x516E	0x694A	# <CJK>
0x516F	0x63DA	# <CJK>
0x5170	0x4F6F	# <CJK>
0x5171	0x760D	# <CJK>
0x5172	0x7F8A	# <CJK>
0x5173	0x6D0B	# <CJK>
0x5174	0x967D	# <CJK>
0x5175	0x6C27	# <CJK>
0x5176	0x4EF0	# <CJK>
0x5177	0x7662	# <CJK>
0x5178	0x990A	# <CJK>
0x5179	0x6A23	# <CJK>
0x517A	0x6F3E	# <CJK>
0x517B	0x9080	# <CJK>
0x517C	0x8170	# <CJK>
0x517D	0x5996	# <CJK>
0x517E	0x7476	# <CJK>
0x5221	0x6447	# <CJK>
0x5222	0x582F	# <CJK>
0x5223	0x9065	# <CJK>
0x5224	0x7A91	# <CJK>
0x5225	0x8B21	# <CJK>
0x5226	0x59DA	# <CJK>
0x5227	0x54AC	# <CJK>
0x5228	0x8200	# <CJK>
0x5229	0x85E5	# <CJK>
0x522A	0x8981	# <CJK>
0x522B	0x8000	# <CJK>
0x522C	0x6930	# <CJK>
0x522D	0x564E	# <CJK>
0x522E	0x8036	# <CJK>
0x522F	0x723A	# <CJK>
0x5230	0x91CE	# <CJK>
0x5231	0x51B6	# <CJK>
0x5232	0x4E5F	# <CJK>
0x5233	0x9801	# <CJK>
0x5234	0x6396	# <CJK>
0x5235	0x696D	# <CJK>
0x5236	0x8449	# <CJK>
0x5237	0x66F3	# <CJK>
0x5238	0x814B	# <CJK>
0x5239	0x591C	# <CJK>
0x523A	0x6DB2	# <CJK>
0x523B	0x4E00	# <CJK>
0x523C	0x58F9	# <CJK>
0x523D	0x91AB	# <CJK>
0x523E	0x63D6	# <CJK>
0x523F	0x92A5	# <CJK>
0x5240	0x4F9D	# <CJK>
0x5241	0x4F0A	# <CJK>
0x5242	0x8863	# <CJK>
0x5243	0x9824	# <CJK>
0x5244	0x5937	# <CJK>
0x5245	0x907A	# <CJK>
0x5246	0x79FB	# <CJK>
0x5247	0x5100	# <CJK>
0x5248	0x80F0	# <CJK>
0x5249	0x7591	# <CJK>
0x524A	0x6C82	# <CJK>
0x524B	0x5B9C	# <CJK>
0x524C	0x59E8	# <CJK>
0x524D	0x5F5D	# <CJK>
0x524E	0x6905	# <CJK>
0x524F	0x87FB	# <CJK>
0x5250	0x501A	# <CJK>
0x5251	0x5DF2	# <CJK>
0x5252	0x4E59	# <CJK>
0x5253	0x77E3	# <CJK>
0x5254	0x4EE5	# <CJK>
0x5255	0x85DD	# <CJK>
0x5256	0x6291	# <CJK>
0x5257	0x6613	# <CJK>
0x5258	0x9091	# <CJK>
0x5259	0x5C79	# <CJK>
0x525A	0x5104	# <CJK>
0x525B	0x5F79	# <CJK>
0x525C	0x81C6	# <CJK>
0x525D	0x9038	# <CJK>
0x525E	0x8084	# <CJK>
0x525F	0x75AB	# <CJK>
0x5260	0x4EA6	# <CJK>
0x5261	0x88D4	# <CJK>
0x5262	0x610F	# <CJK>
0x5263	0x6BC5	# <CJK>
0x5264	0x61B6	# <CJK>
0x5265	0x7FA9	# <CJK>
0x5266	0x76CA	# <CJK>
0x5267	0x6EA2	# <CJK>
0x5268	0x8A63	# <CJK>
0x5269	0x8B70	# <CJK>
0x526A	0x8ABC	# <CJK>
0x526B	0x8B6F	# <CJK>
0x526C	0x5F02	# <CJK>
0x526D	0x7FFC	# <CJK>
0x526E	0x7FCC	# <CJK>
0x526F	0x7E79	# <CJK>
0x5270	0x8335	# <CJK>
0x5271	0x852D	# <CJK>
0x5272	0x56E0	# <CJK>
0x5273	0x6BB7	# <CJK>
0x5274	0x97F3	# <CJK>
0x5275	0x9670	# <CJK>
0x5276	0x59FB	# <CJK>
0x5277	0x541F	# <CJK>
0x5278	0x9280	# <CJK>
0x5279	0x6DEB	# <CJK>
0x527A	0x5BC5	# <CJK>
0x527B	0x98F2	# <CJK>
0x527C	0x5C39	# <CJK>
0x527D	0x5F15	# <CJK>
0x527E	0x96B1	# <CJK>
0x5321	0x5370	# <CJK>
0x5322	0x82F1	# <CJK>
0x5323	0x6AFB	# <CJK>
0x5324	0x5B30	# <CJK>
0x5325	0x9DF9	# <CJK>
0x5326	0x61C9	# <CJK>
0x5327	0x7E93	# <CJK>
0x5328	0x7469	# <CJK>
0x5329	0x87A2	# <CJK>
0x532A	0x71DF	# <CJK>
0x532B	0x7192	# <CJK>
0x532C	0x8805	# <CJK>
0x532D	0x8FCE	# <CJK>
0x532E	0x8D0F	# <CJK>
0x532F	0x76C8	# <CJK>
0x5330	0x5F71	# <CJK>
0x5331	0x7A4E	# <CJK>
0x5332	0x786C	# <CJK>
0x5333	0x6620	# <CJK>
0x5334	0x55B2	# <CJK>
0x5335	0x64C1	# <CJK>
0x5336	0x50AD	# <CJK>
0x5337	0x81C3	# <CJK>
0x5338	0x7670	# <CJK>
0x5339	0x5EB8	# <CJK>
0x533A	0x96CD	# <CJK>
0x533B	0x8E34	# <CJK>
0x533C	0x86F9	# <CJK>
0x533D	0x548F	# <CJK>
0x533E	0x6CF3	# <CJK>
0x533F	0x6D8C	# <CJK>
0x5340	0x6C38	# <CJK>
0x5341	0x607F	# <CJK>
0x5342	0x52C7	# <CJK>
0x5343	0x7528	# <CJK>
0x5344	0x5E7D	# <CJK>
0x5345	0x512A	# <CJK>
0x5346	0x60A0	# <CJK>
0x5347	0x6182	# <CJK>
0x5348	0x5C24	# <CJK>
0x5349	0x7531	# <CJK>
0x534A	0x90F5	# <CJK>
0x534B	0x923E	# <CJK>
0x534C	0x7336	# <CJK>
0x534D	0x6CB9	# <CJK>
0x534E	0x6E38	# <CJK>
0x534F	0x9149	# <CJK>
0x5350	0x6709	# <CJK>
0x5351	0x53CB	# <CJK>
0x5352	0x53F3	# <CJK>
0x5353	0x4F51	# <CJK>
0x5354	0x91C9	# <CJK>
0x5355	0x8A98	# <CJK>
0x5356	0x53C8	# <CJK>
0x5357	0x5E7C	# <CJK>
0x5358	0x8FC2	# <CJK>
0x5359	0x6DE4	# <CJK>
0x535A	0x4E8E	# <CJK>
0x535B	0x76C2	# <CJK>
0x535C	0x6986	# <CJK>
0x535D	0x865E	# <CJK>
0x535E	0x611A	# <CJK>
0x535F	0x8F3F	# <CJK>
0x5360	0x9918	# <CJK>
0x5361	0x4FDE	# <CJK>
0x5362	0x903E	# <CJK>
0x5363	0x9B5A	# <CJK>
0x5364	0x6109	# <CJK>
0x5365	0x6E1D	# <CJK>
0x5366	0x6F01	# <CJK>
0x5367	0x9685	# <CJK>
0x5368	0x4E88	# <CJK>
0x5369	0x5A31	# <CJK>
0x536A	0x96E8	# <CJK>
0x536B	0x8207	# <CJK>
0x536C	0x5DBC	# <CJK>
0x536D	0x79B9	# <CJK>
0x536E	0x5B87	# <CJK>
0x536F	0x8A9E	# <CJK>
0x5370	0x7FBD	# <CJK>
0x5371	0x7389	# <CJK>
0x5372	0x57DF	# <CJK>
0x5373	0x828B	# <CJK>
0x5374	0x9B31	# <CJK>
0x5375	0x5401	# <CJK>
0x5376	0x9047	# <CJK>
0x5377	0x55BB	# <CJK>
0x5378	0x5CEA	# <CJK>
0x5379	0x5FA1	# <CJK>
0x537A	0x6108	# <CJK>
0x537B	0x6B32	# <CJK>
0x537C	0x7344	# <CJK>
0x537D	0x80B2	# <CJK>
0x537E	0x8B7D	# <CJK>
0x5421	0x6D74	# <CJK>
0x5422	0x5BD3	# <CJK>
0x5423	0x88D5	# <CJK>
0x5424	0x9810	# <CJK>
0x5425	0x8C6B	# <CJK>
0x5426	0x99AD	# <CJK>
0x5427	0x9D1B	# <CJK>
0x5428	0x6DF5	# <CJK>
0x5429	0x51A4	# <CJK>
0x542A	0x5143	# <CJK>
0x542B	0x57A3	# <CJK>
0x542C	0x8881	# <CJK>
0x542D	0x539F	# <CJK>
0x542E	0x63F4	# <CJK>
0x542F	0x8F45	# <CJK>
0x5430	0x5712	# <CJK>
0x5431	0x54E1	# <CJK>
0x5432	0x5713	# <CJK>
0x5433	0x733F	# <CJK>
0x5434	0x6E90	# <CJK>
0x5435	0x7DE3	# <CJK>
0x5436	0x9060	# <CJK>
0x5437	0x82D1	# <CJK>
0x5438	0x9858	# <CJK>
0x5439	0x6028	# <CJK>
0x543A	0x9662	# <CJK>
0x543B	0x66F0	# <CJK>
0x543C	0x7D04	# <CJK>
0x543D	0x8D8A	# <CJK>
0x543E	0x8E8D	# <CJK>
0x543F	0x9470	# <CJK>
0x5440	0x5CB3	# <CJK>
0x5441	0x7CA4	# <CJK>
0x5442	0x6708	# <CJK>
0x5443	0x60A6	# <CJK>
0x5444	0x95B2	# <CJK>
0x5445	0x8018	# <CJK>
0x5446	0x96F2	# <CJK>
0x5447	0x9116	# <CJK>
0x5448	0x5300	# <CJK>
0x5449	0x9695	# <CJK>
0x544A	0x5141	# <CJK>
0x544B	0x904B	# <CJK>
0x544C	0x85F4	# <CJK>
0x544D	0x9196	# <CJK>
0x544E	0x6688	# <CJK>
0x544F	0x97F5	# <CJK>
0x5450	0x5B55	# <CJK>
0x5451	0x531D	# <CJK>
0x5452	0x7838	# <CJK>
0x5453	0x96DC	# <CJK>
0x5454	0x683D	# <CJK>
0x5455	0x54C9	# <CJK>
0x5456	0x707E	# <CJK>
0x5457	0x5BB0	# <CJK>
0x5458	0x8F09	# <CJK>
0x5459	0x518D	# <CJK>
0x545A	0x5728	# <CJK>
0x545B	0x54B1	# <CJK>
0x545C	0x6522	# <CJK>
0x545D	0x66AB	# <CJK>
0x545E	0x8D0A	# <CJK>
0x545F	0x8D1C	# <CJK>
0x5460	0x81DF	# <CJK>
0x5461	0x846C	# <CJK>
0x5462	0x906D	# <CJK>
0x5463	0x7CDF	# <CJK>
0x5464	0x947F	# <CJK>
0x5465	0x85FB	# <CJK>
0x5466	0x68D7	# <CJK>
0x5467	0x65E9	# <CJK>
0x5468	0x6FA1	# <CJK>
0x5469	0x86A4	# <CJK>
0x546A	0x8E81	# <CJK>
0x546B	0x566A	# <CJK>
0x546C	0x9020	# <CJK>
0x546D	0x7682	# <CJK>
0x546E	0x7AC8	# <CJK>
0x546F	0x71E5	# <CJK>
0x5470	0x8CAC	# <CJK>
0x5471	0x64C7	# <CJK>
0x5472	0x5247	# <CJK>
0x5473	0x6FA4	# <CJK>
0x5474	0x8CCA	# <CJK>
0x5475	0x600E	# <CJK>
0x5476	0x589E	# <CJK>
0x5477	0x618E	# <CJK>
0x5478	0x66FE	# <CJK>
0x5479	0x8D08	# <CJK>
0x547A	0x624E	# <CJK>
0x547B	0x55B3	# <CJK>
0x547C	0x6E23	# <CJK>
0x547D	0x672D	# <CJK>
0x547E	0x8ECB	# <CJK>
0x5521	0x9358	# <CJK>
0x5522	0x9598	# <CJK>
0x5523	0x7728	# <CJK>
0x5524	0x6805	# <CJK>
0x5525	0x69A8	# <CJK>
0x5526	0x548B	# <CJK>
0x5527	0x4E4D	# <CJK>
0x5528	0x70B8	# <CJK>
0x5529	0x8A50	# <CJK>
0x552A	0x6458	# <CJK>
0x552B	0x9F4B	# <CJK>
0x552C	0x5B85	# <CJK>
0x552D	0x7A84	# <CJK>
0x552E	0x50B5	# <CJK>
0x552F	0x5BE8	# <CJK>
0x5530	0x77BB	# <CJK>
0x5531	0x6C08	# <CJK>
0x5532	0x8A79	# <CJK>
0x5533	0x7C98	# <CJK>
0x5534	0x6CBE	# <CJK>
0x5535	0x76DE	# <CJK>
0x5536	0x65AC	# <CJK>
0x5537	0x8F3E	# <CJK>
0x5538	0x5D84	# <CJK>
0x5539	0x5C55	# <CJK>
0x553A	0x8638	# <CJK>
0x553B	0x68E7	# <CJK>
0x553C	0x5360	# <CJK>
0x553D	0x6230	# <CJK>
0x553E	0x7AD9	# <CJK>
0x553F	0x6E5B	# <CJK>
0x5540	0x7DBB	# <CJK>
0x5541	0x6A1F	# <CJK>
0x5542	0x7AE0	# <CJK>
0x5543	0x5F70	# <CJK>
0x5544	0x6F33	# <CJK>
0x5545	0x5F35	# <CJK>
0x5546	0x638C	# <CJK>
0x5547	0x6F32	# <CJK>
0x5548	0x6756	# <CJK>
0x5549	0x4E08	# <CJK>
0x554A	0x5E33	# <CJK>
0x554B	0x8CEC	# <CJK>
0x554C	0x4ED7	# <CJK>
0x554D	0x8139	# <CJK>
0x554E	0x7634	# <CJK>
0x554F	0x969C	# <CJK>
0x5550	0x62DB	# <CJK>
0x5551	0x662D	# <CJK>
0x5552	0x627E	# <CJK>
0x5553	0x6CBC	# <CJK>
0x5554	0x8D99	# <CJK>
0x5555	0x7167	# <CJK>
0x5556	0x7F69	# <CJK>
0x5557	0x5146	# <CJK>
0x5558	0x8087	# <CJK>
0x5559	0x53EC	# <CJK>
0x555A	0x906E	# <CJK>
0x555B	0x6298	# <CJK>
0x555C	0x54F2	# <CJK>
0x555D	0x87C4	# <CJK>
0x555E	0x8F4D	# <CJK>
0x555F	0x8005	# <CJK>
0x5560	0x937A	# <CJK>
0x5561	0x8517	# <CJK>
0x5562	0x9019	# <CJK>
0x5563	0x6D59	# <CJK>
0x5564	0x73CD	# <CJK>
0x5565	0x659F	# <CJK>
0x5566	0x771F	# <CJK>
0x5567	0x7504	# <CJK>
0x5568	0x7827	# <CJK>
0x5569	0x81FB	# <CJK>
0x556A	0x8C9E	# <CJK>
0x556B	0x91DD	# <CJK>
0x556C	0x5075	# <CJK>
0x556D	0x6795	# <CJK>
0x556E	0x75B9	# <CJK>
0x556F	0x8A3A	# <CJK>
0x5570	0x9707	# <CJK>
0x5571	0x632F	# <CJK>
0x5572	0x93AE	# <CJK>
0x5573	0x9663	# <CJK>
0x5574	0x84B8	# <CJK>
0x5575	0x6399	# <CJK>
0x5576	0x775C	# <CJK>
0x5577	0x5F81	# <CJK>
0x5578	0x7319	# <CJK>
0x5579	0x722D	# <CJK>
0x557A	0x6014	# <CJK>
0x557B	0x6574	# <CJK>
0x557C	0x62EF	# <CJK>
0x557D	0x6B63	# <CJK>
0x557E	0x653F	# <CJK>
0x5621	0x5E40	# <CJK>
0x5622	0x7665	# <CJK>
0x5623	0x912D	# <CJK>
0x5624	0x8B49	# <CJK>
0x5625	0x829D	# <CJK>
0x5626	0x679D	# <CJK>
0x5627	0x652F	# <CJK>
0x5628	0x5431	# <CJK>
0x5629	0x8718	# <CJK>
0x562A	0x77E5	# <CJK>
0x562B	0x80A2	# <CJK>
0x562C	0x8102	# <CJK>
0x562D	0x6C41	# <CJK>
0x562E	0x4E4B	# <CJK>
0x562F	0x7E54	# <CJK>
0x5630	0x8077	# <CJK>
0x5631	0x76F4	# <CJK>
0x5632	0x690D	# <CJK>
0x5633	0x6B96	# <CJK>
0x5634	0x57F7	# <CJK>
0x5635	0x503C	# <CJK>
0x5636	0x4F84	# <CJK>
0x5637	0x5740	# <CJK>
0x5638	0x6307	# <CJK>
0x5639	0x6B62	# <CJK>
0x563A	0x8DBE	# <CJK>
0x563B	0x8879	# <CJK>
0x563C	0x65E8	# <CJK>
0x563D	0x7D19	# <CJK>
0x563E	0x5FD7	# <CJK>
0x563F	0x646F	# <CJK>
0x5640	0x64F2	# <CJK>
0x5641	0x81F3	# <CJK>
0x5642	0x81F4	# <CJK>
0x5643	0x7F6E	# <CJK>
0x5644	0x5E5F	# <CJK>
0x5645	0x5CD9	# <CJK>
0x5646	0x5236	# <CJK>
0x5647	0x667A	# <CJK>
0x5648	0x79E9	# <CJK>
0x5649	0x7A1A	# <CJK>
0x564A	0x8CEA	# <CJK>
0x564B	0x7099	# <CJK>
0x564C	0x75D4	# <CJK>
0x564D	0x6EEF	# <CJK>
0x564E	0x6CBB	# <CJK>
0x564F	0x7A92	# <CJK>
0x5650	0x4E2D	# <CJK>
0x5651	0x76C5	# <CJK>
0x5652	0x5FE0	# <CJK>
0x5653	0x9418	# <CJK>
0x5654	0x8877	# <CJK>
0x5655	0x7D42	# <CJK>
0x5656	0x7A2E	# <CJK>
0x5657	0x816B	# <CJK>
0x5658	0x91CD	# <CJK>
0x5659	0x4EF2	# <CJK>
0x565A	0x8846	# <CJK>
0x565B	0x821F	# <CJK>
0x565C	0x5468	# <CJK>
0x565D	0x5DDE	# <CJK>
0x565E	0x6D32	# <CJK>
0x565F	0x8B05	# <CJK>
0x5660	0x7CA5	# <CJK>
0x5661	0x8EF8	# <CJK>
0x5662	0x8098	# <CJK>
0x5663	0x5E1A	# <CJK>
0x5664	0x5492	# <CJK>
0x5665	0x76BA	# <CJK>
0x5666	0x5B99	# <CJK>
0x5667	0x665D	# <CJK>
0x5668	0x9A5F	# <CJK>
0x5669	0x73E0	# <CJK>
0x566A	0x682A	# <CJK>
0x566B	0x86DB	# <CJK>
0x566C	0x6731	# <CJK>
0x566D	0x732A	# <CJK>
0x566E	0x8AF8	# <CJK>
0x566F	0x8A85	# <CJK>
0x5670	0x9010	# <CJK>
0x5671	0x7AF9	# <CJK>
0x5672	0x71ED	# <CJK>
0x5673	0x716E	# <CJK>
0x5674	0x62C4	# <CJK>
0x5675	0x77DA	# <CJK>
0x5676	0x56D1	# <CJK>
0x5677	0x4E3B	# <CJK>
0x5678	0x8457	# <CJK>
0x5679	0x67F1	# <CJK>
0x567A	0x52A9	# <CJK>
0x567B	0x86C0	# <CJK>
0x567C	0x8CAF	# <CJK>
0x567D	0x9444	# <CJK>
0x567E	0x7BC9	# <CJK>
0x5721	0x4F4F	# <CJK>
0x5722	0x6CE8	# <CJK>
0x5723	0x795D	# <CJK>
0x5724	0x99D0	# <CJK>
0x5725	0x6293	# <CJK>
0x5726	0x722A	# <CJK>
0x5727	0x62FD	# <CJK>
0x5728	0x5C08	# <CJK>
0x5729	0x78DA	# <CJK>
0x572A	0x8F49	# <CJK>
0x572B	0x64B0	# <CJK>
0x572C	0x8CFA	# <CJK>
0x572D	0x7BC6	# <CJK>
0x572E	0x6A01	# <CJK>
0x572F	0x838A	# <CJK>
0x5730	0x88DD	# <CJK>
0x5731	0x599D	# <CJK>
0x5732	0x649E	# <CJK>
0x5733	0x58EF	# <CJK>
0x5734	0x72C0	# <CJK>
0x5735	0x690E	# <CJK>
0x5736	0x9310	# <CJK>
0x5737	0x8FFD	# <CJK>
0x5738	0x8D05	# <CJK>
0x5739	0x589C	# <CJK>
0x573A	0x7DB4	# <CJK>
0x573B	0x8AC4	# <CJK>
0x573C	0x6E96	# <CJK>
0x573D	0x6349	# <CJK>
0x573E	0x62D9	# <CJK>
0x573F	0x5353	# <CJK>
0x5740	0x684C	# <CJK>
0x5741	0x7422	# <CJK>
0x5742	0x8301	# <CJK>
0x5743	0x914C	# <CJK>
0x5744	0x5544	# <CJK>
0x5745	0x7740	# <CJK>
0x5746	0x707C	# <CJK>
0x5747	0x6FC1	# <CJK>
0x5748	0x5179	# <CJK>
0x5749	0x54A8	# <CJK>
0x574A	0x8CC7	# <CJK>
0x574B	0x59FF	# <CJK>
0x574C	0x6ECB	# <CJK>
0x574D	0x6DC4	# <CJK>
0x574E	0x5B5C	# <CJK>
0x574F	0x7D2B	# <CJK>
0x5750	0x4ED4	# <CJK>
0x5751	0x7C7D	# <CJK>
0x5752	0x6ED3	# <CJK>
0x5753	0x5B50	# <CJK>
0x5754	0x81EA	# <CJK>
0x5755	0x6F2C	# <CJK>
0x5756	0x5B57	# <CJK>
0x5757	0x9B03	# <CJK>
0x5758	0x68D5	# <CJK>
0x5759	0x8E2A	# <CJK>
0x575A	0x5B97	# <CJK>
0x575B	0x7D9C	# <CJK>
0x575C	0x7E3D	# <CJK>
0x575D	0x7E31	# <CJK>
0x575E	0x9112	# <CJK>
0x575F	0x8D70	# <CJK>
0x5760	0x594F	# <CJK>
0x5761	0x63CD	# <CJK>
0x5762	0x79DF	# <CJK>
0x5763	0x8DB3	# <CJK>
0x5764	0x5352	# <CJK>
0x5765	0x65CF	# <CJK>
0x5766	0x7956	# <CJK>
0x5767	0x8A5B	# <CJK>
0x5768	0x963B	# <CJK>
0x5769	0x7D44	# <CJK>
0x576A	0x947D	# <CJK>
0x576B	0x7E82	# <CJK>
0x576C	0x5634	# <CJK>
0x576D	0x9189	# <CJK>
0x576E	0x6700	# <CJK>
0x576F	0x7F6A	# <CJK>
0x5770	0x5C0A	# <CJK>
0x5771	0x9075	# <CJK>
0x5772	0x6628	# <CJK>
0x5773	0x5DE6	# <CJK>
0x5774	0x4F50	# <CJK>
0x5775	0x67DE	# <CJK>
0x5776	0x505A	# <CJK>
0x5777	0x4F5C	# <CJK>
0x5778	0x5750	# <CJK>
0x5779	0x5EA7	# <CJK>
0x5821	0x4E8D	# <CJK>
0x5822	0x4E0C	# <CJK>
0x5823	0x5140	# <CJK>
0x5824	0x4E10	# <CJK>
0x5825	0x5EFF	# <CJK>
0x5826	0x5345	# <CJK>
0x5827	0x4E15	# <CJK>
0x5828	0x4E98	# <CJK>
0x5829	0x4E1E	# <CJK>
0x582A	0x9B32	# <CJK>
0x582B	0x5B6C	# <CJK>
0x582C	0x5669	# <CJK>
0x582D	0x4E28	# <CJK>
0x582E	0x79BA	# <CJK>
0x582F	0x4E3F	# <CJK>
0x5830	0x5315	# <CJK>
0x5831	0x4E47	# <CJK>
0x5832	0x592D	# <CJK>
0x5833	0x723B	# <CJK>
0x5834	0x536E	# <CJK>
0x5835	0x6C10	# <CJK>
0x5836	0x56DF	# <CJK>
0x5837	0x80E4	# <CJK>
0x5838	0x9997	# <CJK>
0x5839	0x6BD3	# <CJK>
0x583A	0x777E	# <CJK>
0x583B	0x9F17	# <CJK>
0x583C	0x4E36	# <CJK>
0x583D	0x4E9F	# <CJK>
0x583E	0x9F10	# <CJK>
0x583F	0x4E5C	# <CJK>
0x5840	0x4E69	# <CJK>
0x5841	0x4E93	# <CJK>
0x5842	0x8288	# <CJK>
0x5843	0x5B5B	# <CJK>
0x5844	0x55C7	# <CJK>
0x5845	0x560F	# <CJK>
0x5846	0x4EC4	# <CJK>
0x5847	0x5399	# <CJK>
0x5848	0x539D	# <CJK>
0x5849	0x53B4	# <CJK>
0x584A	0x53A5	# <CJK>
0x584B	0x53AE	# <CJK>
0x584C	0x9768	# <CJK>
0x584D	0x8D0B	# <CJK>
0x584E	0x531A	# <CJK>
0x584F	0x53F5	# <CJK>
0x5850	0x532D	# <CJK>
0x5851	0x5331	# <CJK>
0x5852	0x533E	# <CJK>
0x5853	0x8CFE	# <CJK>
0x5854	0x5366	# <CJK>
0x5855	0x5363	# <CJK>
0x5856	0x5202	# <CJK>
0x5857	0x5208	# <CJK>
0x5858	0x520E	# <CJK>
0x5859	0x5244	# <CJK>
0x585A	0x5233	# <CJK>
0x585B	0x528C	# <CJK>
0x585C	0x5274	# <CJK>
0x585D	0x524C	# <CJK>
0x585E	0x525E	# <CJK>
0x585F	0x5261	# <CJK>
0x5860	0x525C	# <CJK>
0x5861	0x84AF	# <CJK>
0x5862	0x527D	# <CJK>
0x5863	0x5282	# <CJK>
0x5864	0x5281	# <CJK>
0x5865	0x5290	# <CJK>
0x5866	0x5293	# <CJK>
0x5867	0x5182	# <CJK>
0x5868	0x7F54	# <CJK>
0x5869	0x4EBB	# <CJK>
0x586A	0x4EC3	# <CJK>
0x586B	0x4EC9	# <CJK>
0x586C	0x4EC2	# <CJK>
0x586D	0x4EE8	# <CJK>
0x586E	0x4EE1	# <CJK>
0x586F	0x4EEB	# <CJK>
0x5870	0x4EDE	# <CJK>
0x5871	0x50B4	# <CJK>
0x5872	0x4EF3	# <CJK>
0x5873	0x4F22	# <CJK>
0x5874	0x4F64	# <CJK>
0x5875	0x4EF5	# <CJK>
0x5876	0x5000	# <CJK>
0x5877	0x5096	# <CJK>
0x5878	0x4F09	# <CJK>
0x5879	0x4F47	# <CJK>
0x587A	0x4F5E	# <CJK>
0x587B	0x4F67	# <CJK>
0x587C	0x6538	# <CJK>
0x587D	0x4F5A	# <CJK>
0x587E	0x4F5D	# <CJK>
0x5921	0x4F5F	# <CJK>
0x5922	0x4F57	# <CJK>
0x5923	0x4F32	# <CJK>
0x5924	0x4F3D	# <CJK>
0x5925	0x4F76	# <CJK>
0x5926	0x4F74	# <CJK>
0x5927	0x4F91	# <CJK>
0x5928	0x4F89	# <CJK>
0x5929	0x4F83	# <CJK>
0x592A	0x4F8F	# <CJK>
0x592B	0x4F7E	# <CJK>
0x592C	0x4F7B	# <CJK>
0x592D	0x5115	# <CJK>
0x592E	0x4F7C	# <CJK>
0x592F	0x5102	# <CJK>
0x5930	0x4F94	# <CJK>
0x5931	0x5114	# <CJK>
0x5932	0x513C	# <CJK>
0x5933	0x5137	# <CJK>
0x5934	0x4FC5	# <CJK>
0x5935	0x4FDA	# <CJK>
0x5936	0x4FE3	# <CJK>
0x5937	0x4FDC	# <CJK>
0x5938	0x4FD1	# <CJK>
0x5939	0x4FDF	# <CJK>
0x593A	0x4FF8	# <CJK>
0x593B	0x5029	# <CJK>
0x593C	0x504C	# <CJK>
0x593D	0x4FF3	# <CJK>
0x593E	0x502C	# <CJK>
0x593F	0x500F	# <CJK>
0x5940	0x502E	# <CJK>
0x5941	0x502D	# <CJK>
0x5942	0x4FFE	# <CJK>
0x5943	0x501C	# <CJK>
0x5944	0x500C	# <CJK>
0x5945	0x5025	# <CJK>
0x5946	0x5028	# <CJK>
0x5947	0x50E8	# <CJK>
0x5948	0x5043	# <CJK>
0x5949	0x5055	# <CJK>
0x594A	0x5048	# <CJK>
0x594B	0x504E	# <CJK>
0x594C	0x506C	# <CJK>
0x594D	0x50C2	# <CJK>
0x594E	0x513B	# <CJK>
0x594F	0x5110	# <CJK>
0x5950	0x513A	# <CJK>
0x5951	0x50BA	# <CJK>
0x5952	0x50D6	# <CJK>
0x5953	0x5106	# <CJK>
0x5954	0x50ED	# <CJK>
0x5955	0x50EC	# <CJK>
0x5956	0x50E6	# <CJK>
0x5957	0x50EE	# <CJK>
0x5958	0x5107	# <CJK>
0x5959	0x510B	# <CJK>
0x595A	0x4EDD	# <CJK>
0x595B	0x6C3D	# <CJK>
0x595C	0x4F58	# <CJK>
0x595D	0x50C9	# <CJK>
0x595E	0x4FCE	# <CJK>
0x595F	0x9FA0	# <CJK>
0x5960	0x6C46	# <CJK>
0x5961	0x7CF4	# <CJK>
0x5962	0x516E	# <CJK>
0x5963	0x5DFD	# <CJK>
0x5964	0x9ECC	# <CJK>
0x5965	0x9998	# <CJK>
0x5966	0x56C5	# <CJK>
0x5967	0x5914	# <CJK>
0x5968	0x52F9	# <CJK>
0x5969	0x530D	# <CJK>
0x596A	0x8A07	# <CJK>
0x596B	0x5310	# <CJK>
0x596C	0x9CEC	# <CJK>
0x596D	0x5919	# <CJK>
0x596E	0x5155	# <CJK>
0x596F	0x4EA0	# <CJK>
0x5970	0x5156	# <CJK>
0x5971	0x4EB3	# <CJK>
0x5972	0x886E	# <CJK>
0x5973	0x88A4	# <CJK>
0x5974	0x893B	# <CJK>
0x5975	0x81E0	# <CJK>
0x5976	0x88D2	# <CJK>
0x5977	0x7980	# <CJK>
0x5978	0x5B34	# <CJK>
0x5979	0x8803	# <CJK>
0x597A	0x7FB8	# <CJK>
0x597B	0x51AB	# <CJK>
0x597C	0x51B1	# <CJK>
0x597D	0x51BD	# <CJK>
0x597E	0x51BC	# <CJK>
0x5A21	0x51C7	# <CJK>
0x5A22	0x5196	# <CJK>
0x5A23	0x51A2	# <CJK>
0x5A24	0x51A5	# <CJK>
0x5A25	0x8A01	# <CJK>
0x5A26	0x8A10	# <CJK>
0x5A27	0x8A0C	# <CJK>
0x5A28	0x8A15	# <CJK>
0x5A29	0x8B33	# <CJK>
0x5A2A	0x8A4E	# <CJK>
0x5A2B	0x8A25	# <CJK>
0x5A2C	0x8A41	# <CJK>
0x5A2D	0x8A36	# <CJK>
0x5A2E	0x8A46	# <CJK>
0x5A2F	0x8A54	# <CJK>
0x5A30	0x8A58	# <CJK>
0x5A31	0x8A52	# <CJK>
0x5A32	0x8A86	# <CJK>
0x5A33	0x8A84	# <CJK>
0x5A34	0x8A7F	# <CJK>
0x5A35	0x8A70	# <CJK>
0x5A36	0x8A7C	# <CJK>
0x5A37	0x8A75	# <CJK>
0x5A38	0x8A6C	# <CJK>
0x5A39	0x8A6E	# <CJK>
0x5A3A	0x8ACD	# <CJK>
0x5A3B	0x8AE2	# <CJK>
0x5A3C	0x8A61	# <CJK>
0x5A3D	0x8A9A	# <CJK>
0x5A3E	0x8AA5	# <CJK>
0x5A3F	0x8A91	# <CJK>
0x5A40	0x8A92	# <CJK>
0x5A41	0x8ACF	# <CJK>
0x5A42	0x8AD1	# <CJK>
0x5A43	0x8AC9	# <CJK>
0x5A44	0x8ADB	# <CJK>
0x5A45	0x8AD7	# <CJK>
0x5A46	0x8AC2	# <CJK>
0x5A47	0x8AB6	# <CJK>
0x5A48	0x8AF6	# <CJK>
0x5A49	0x8AEB	# <CJK>
0x5A4A	0x8B14	# <CJK>
0x5A4B	0x8B01	# <CJK>
0x5A4C	0x8AE4	# <CJK>
0x5A4D	0x8AED	# <CJK>
0x5A4E	0x8AFC	# <CJK>
0x5A4F	0x8AF3	# <CJK>
0x5A50	0x8AE6	# <CJK>
0x5A51	0x8AEE	# <CJK>
0x5A52	0x8ADE	# <CJK>
0x5A53	0x8B28	# <CJK>
0x5A54	0x8B9C	# <CJK>
0x5A55	0x8B16	# <CJK>
0x5A56	0x8B1A	# <CJK>
0x5A57	0x8B10	# <CJK>
0x5A58	0x8B2B	# <CJK>
0x5A59	0x8B2D	# <CJK>
0x5A5A	0x8B56	# <CJK>
0x5A5B	0x8B59	# <CJK>
0x5A5C	0x8B4E	# <CJK>
0x5A5D	0x8B9E	# <CJK>
0x5A5E	0x8B6B	# <CJK>
0x5A5F	0x8B96	# <CJK>
0x5A60	0x5369	# <CJK>
0x5A61	0x537A	# <CJK>
0x5A62	0x961D	# <CJK>
0x5A63	0x9622	# <CJK>
0x5A64	0x9621	# <CJK>
0x5A65	0x9631	# <CJK>
0x5A66	0x962A	# <CJK>
0x5A67	0x963D	# <CJK>
0x5A68	0x963C	# <CJK>
0x5A69	0x9642	# <CJK>
0x5A6A	0x9658	# <CJK>
0x5A6B	0x9654	# <CJK>
0x5A6C	0x965F	# <CJK>
0x5A6D	0x9689	# <CJK>
0x5A6E	0x966C	# <CJK>
0x5A6F	0x9672	# <CJK>
0x5A70	0x9674	# <CJK>
0x5A71	0x9688	# <CJK>
0x5A72	0x968D	# <CJK>
0x5A73	0x9697	# <CJK>
0x5A74	0x96B0	# <CJK>
0x5A75	0x9097	# <CJK>
0x5A76	0x909B	# <CJK>
0x5A77	0x913A	# <CJK>
0x5A78	0x9099	# <CJK>
0x5A79	0x9114	# <CJK>
0x5A7A	0x90A1	# <CJK>
0x5A7B	0x90B4	# <CJK>
0x5A7C	0x90B3	# <CJK>
0x5A7D	0x90B6	# <CJK>
0x5A7E	0x9134	# <CJK>
0x5B21	0x90B8	# <CJK>
0x5B22	0x90B0	# <CJK>
0x5B23	0x90DF	# <CJK>
0x5B24	0x90C5	# <CJK>
0x5B25	0x90BE	# <CJK>
0x5B26	0x9136	# <CJK>
0x5B27	0x90C4	# <CJK>
0x5B28	0x90C7	# <CJK>
0x5B29	0x9106	# <CJK>
0x5B2A	0x9148	# <CJK>
0x5B2B	0x90E2	# <CJK>
0x5B2C	0x90DC	# <CJK>
0x5B2D	0x90D7	# <CJK>
0x5B2E	0x90DB	# <CJK>
0x5B2F	0x90EB	# <CJK>
0x5B30	0x90EF	# <CJK>
0x5B31	0x90FE	# <CJK>
0x5B32	0x9104	# <CJK>
0x5B33	0x9122	# <CJK>
0x5B34	0x911E	# <CJK>
0x5B35	0x9123	# <CJK>
0x5B36	0x9131	# <CJK>
0x5B37	0x912F	# <CJK>
0x5B38	0x9139	# <CJK>
0x5B39	0x9143	# <CJK>
0x5B3A	0x9146	# <CJK>
0x5B3B	0x82BB	# <CJK>
0x5B3C	0x5950	# <CJK>
0x5B3D	0x52F1	# <CJK>
0x5B3E	0x52AC	# <CJK>
0x5B3F	0x52AD	# <CJK>
0x5B40	0x52BE	# <CJK>
0x5B41	0x54FF	# <CJK>
0x5B42	0x52D0	# <CJK>
0x5B43	0x52D6	# <CJK>
0x5B44	0x52F0	# <CJK>
0x5B45	0x53DF	# <CJK>
0x5B46	0x71EE	# <CJK>
0x5B47	0x77CD	# <CJK>
0x5B48	0x5EF4	# <CJK>
0x5B49	0x51F5	# <CJK>
0x5B4A	0x51FC	# <CJK>
0x5B4B	0x9B2F	# <CJK>
0x5B4C	0x53B6	# <CJK>
0x5B4D	0x5F01	# <CJK>
0x5B4E	0x755A	# <CJK>
0x5B4F	0x5DF0	# <CJK>
0x5B50	0x574C	# <CJK>
0x5B51	0x580A	# <CJK>
0x5B52	0x57A1	# <CJK>
0x5B53	0x587E	# <CJK>
0x5B54	0x58BC	# <CJK>
0x5B55	0x58C5	# <CJK>
0x5B56	0x58D1	# <CJK>
0x5B57	0x5729	# <CJK>
0x5B58	0x572C	# <CJK>
0x5B59	0x572A	# <CJK>
0x5B5A	0x5733	# <CJK>
0x5B5B	0x58D9	# <CJK>
0x5B5C	0x572E	# <CJK>
0x5B5D	0x572F	# <CJK>
0x5B5E	0x58E2	# <CJK>
0x5B5F	0x573B	# <CJK>
0x5B60	0x5742	# <CJK>
0x5B61	0x5769	# <CJK>
0x5B62	0x58E0	# <CJK>
0x5B63	0x576B	# <CJK>
0x5B64	0x58DA	# <CJK>
0x5B65	0x577C	# <CJK>
0x5B66	0x577B	# <CJK>
0x5B67	0x5768	# <CJK>
0x5B68	0x576D	# <CJK>
0x5B69	0x5776	# <CJK>
0x5B6A	0x5773	# <CJK>
0x5B6B	0x57E1	# <CJK>
0x5B6C	0x57A4	# <CJK>
0x5B6D	0x578C	# <CJK>
0x5B6E	0x584F	# <CJK>
0x5B6F	0x57CF	# <CJK>
0x5B70	0x57A7	# <CJK>
0x5B71	0x5816	# <CJK>
0x5B72	0x5793	# <CJK>
0x5B73	0x57A0	# <CJK>
0x5B74	0x57D5	# <CJK>
0x5B75	0x5852	# <CJK>
0x5B76	0x581D	# <CJK>
0x5B77	0x5864	# <CJK>
0x5B78	0x57D2	# <CJK>
0x5B79	0x57B8	# <CJK>
0x5B7A	0x57F4	# <CJK>
0x5B7B	0x57EF	# <CJK>
0x5B7C	0x57F8	# <CJK>
0x5B7D	0x57E4	# <CJK>
0x5B7E	0x57DD	# <CJK>
0x5C21	0x580B	# <CJK>
0x5C22	0x580D	# <CJK>
0x5C23	0x57FD	# <CJK>
0x5C24	0x57ED	# <CJK>
0x5C25	0x5800	# <CJK>
0x5C26	0x581E	# <CJK>
0x5C27	0x5819	# <CJK>
0x5C28	0x5844	# <CJK>
0x5C29	0x5820	# <CJK>
0x5C2A	0x5865	# <CJK>
0x5C2B	0x586C	# <CJK>
0x5C2C	0x5881	# <CJK>
0x5C2D	0x5889	# <CJK>
0x5C2E	0x589A	# <CJK>
0x5C2F	0x5880	# <CJK>
0x5C30	0x99A8	# <CJK>
0x5C31	0x9F19	# <CJK>
0x5C32	0x61FF	# <CJK>
0x5C33	0x8279	# <CJK>
0x5C34	0x827D	# <CJK>
0x5C35	0x827F	# <CJK>
0x5C36	0x828F	# <CJK>
0x5C37	0x828A	# <CJK>
0x5C38	0x82A8	# <CJK>
0x5C39	0x8284	# <CJK>
0x5C3A	0x828E	# <CJK>
0x5C3B	0x8291	# <CJK>
0x5C3C	0x858C	# <CJK>
0x5C3D	0x8299	# <CJK>
0x5C3E	0x82AB	# <CJK>
0x5C3F	0x8553	# <CJK>
0x5C40	0x82BE	# <CJK>
0x5C41	0x82B0	# <CJK>
0x5C42	0x85F6	# <CJK>
0x5C43	0x82CA	# <CJK>
0x5C44	0x82E3	# <CJK>
0x5C45	0x8298	# <CJK>
0x5C46	0x82B7	# <CJK>
0x5C47	0x82AE	# <CJK>
0x5C48	0x83A7	# <CJK>
0x5C49	0x8407	# <CJK>
0x5C4A	0x84EF	# <CJK>
0x5C4B	0x82A9	# <CJK>
0x5C4C	0x82B4	# <CJK>
0x5C4D	0x82A1	# <CJK>
0x5C4E	0x82AA	# <CJK>
0x5C4F	0x829F	# <CJK>
0x5C50	0x82C4	# <CJK>
0x5C51	0x82E7	# <CJK>
0x5C52	0x82A4	# <CJK>
0x5C53	0x82E1	# <CJK>
0x5C54	0x8309	# <CJK>
0x5C55	0x82F7	# <CJK>
0x5C56	0x82E4	# <CJK>
0x5C57	0x8622	# <CJK>
0x5C58	0x8307	# <CJK>
0x5C59	0x82DC	# <CJK>
0x5C5A	0x82F4	# <CJK>
0x5C5B	0x82D2	# <CJK>
0x5C5C	0x82D8	# <CJK>
0x5C5D	0x830C	# <CJK>
0x5C5E	0x82FB	# <CJK>
0x5C5F	0x82D3	# <CJK>
0x5C60	0x8526	# <CJK>
0x5C61	0x831A	# <CJK>
0x5C62	0x8306	# <CJK>
0x5C63	0x584B	# <CJK>
0x5C64	0x7162	# <CJK>
0x5C65	0x82E0	# <CJK>
0x5C66	0x82D5	# <CJK>
0x5C67	0x831C	# <CJK>
0x5C68	0x8351	# <CJK>
0x5C69	0x8558	# <CJK>
0x5C6A	0x84FD	# <CJK>
0x5C6B	0x8308	# <CJK>
0x5C6C	0x8392	# <CJK>
0x5C6D	0x833C	# <CJK>
0x5C6E	0x8334	# <CJK>
0x5C6F	0x8331	# <CJK>
0x5C70	0x839B	# <CJK>
0x5C71	0x854E	# <CJK>
0x5C72	0x832F	# <CJK>
0x5C73	0x834F	# <CJK>
0x5C74	0x8347	# <CJK>
0x5C75	0x8343	# <CJK>
0x5C76	0x8588	# <CJK>
0x5C77	0x8340	# <CJK>
0x5C78	0x8317	# <CJK>
0x5C79	0x85BA	# <CJK>
0x5C7A	0x832D	# <CJK>
0x5C7B	0x833A	# <CJK>
0x5C7C	0x8333	# <CJK>
0x5C7D	0x7296	# <CJK>
0x5C7E	0x6ECE	# <CJK>
0x5D21	0x8541	# <CJK>
0x5D22	0x831B	# <CJK>
0x5D23	0x85CE	# <CJK>
0x5D24	0x8552	# <CJK>
0x5D25	0x84C0	# <CJK>
0x5D26	0x8452	# <CJK>
0x5D27	0x8464	# <CJK>
0x5D28	0x83B0	# <CJK>
0x5D29	0x8378	# <CJK>
0x5D2A	0x8494	# <CJK>
0x5D2B	0x8435	# <CJK>
0x5D2C	0x83A0	# <CJK>
0x5D2D	0x83AA	# <CJK>
0x5D2E	0x8393	# <CJK>
0x5D2F	0x839C	# <CJK>
0x5D30	0x8385	# <CJK>
0x5D31	0x837C	# <CJK>
0x5D32	0x859F	# <CJK>
0x5D33	0x83A9	# <CJK>
0x5D34	0x837D	# <CJK>
0x5D35	0x8555	# <CJK>
0x5D36	0x837B	# <CJK>
0x5D37	0x8398	# <CJK>
0x5D38	0x839E	# <CJK>
0x5D39	0x83A8	# <CJK>
0x5D3A	0x9DAF	# <CJK>
0x5D3B	0x8493	# <CJK>
0x5D3C	0x83C1	# <CJK>
0x5D3D	0x8401	# <CJK>
0x5D3E	0x83E5	# <CJK>
0x5D3F	0x83D8	# <CJK>
0x5D40	0x5807	# <CJK>
0x5D41	0x8418	# <CJK>
0x5D42	0x840B	# <CJK>
0x5D43	0x83DD	# <CJK>
0x5D44	0x83FD	# <CJK>
0x5D45	0x83D6	# <CJK>
0x5D46	0x841C	# <CJK>
0x5D47	0x8438	# <CJK>
0x5D48	0x8411	# <CJK>
0x5D49	0x8406	# <CJK>
0x5D4A	0x83D4	# <CJK>
0x5D4B	0x83DF	# <CJK>
0x5D4C	0x840F	# <CJK>
0x5D4D	0x8403	# <CJK>
0x5D4E	0x83F8	# <CJK>
0x5D4F	0x83F9	# <CJK>
0x5D50	0x83EA	# <CJK>
0x5D51	0x83C5	# <CJK>
0x5D52	0x83C0	# <CJK>
0x5D53	0x7E08	# <CJK>
0x5D54	0x83F0	# <CJK>
0x5D55	0x83E1	# <CJK>
0x5D56	0x845C	# <CJK>
0x5D57	0x8451	# <CJK>
0x5D58	0x845A	# <CJK>
0x5D59	0x8459	# <CJK>
0x5D5A	0x8473	# <CJK>
0x5D5B	0x8546	# <CJK>
0x5D5C	0x8488	# <CJK>
0x5D5D	0x847A	# <CJK>
0x5D5E	0x8562	# <CJK>
0x5D5F	0x8478	# <CJK>
0x5D60	0x843C	# <CJK>
0x5D61	0x8446	# <CJK>
0x5D62	0x8469	# <CJK>
0x5D63	0x8476	# <CJK>
0x5D64	0x851E	# <CJK>
0x5D65	0x848E	# <CJK>
0x5D66	0x8431	# <CJK>
0x5D67	0x846D	# <CJK>
0x5D68	0x84C1	# <CJK>
0x5D69	0x84CD	# <CJK>
0x5D6A	0x84D0	# <CJK>
0x5D6B	0x9A40	# <CJK>
0x5D6C	0x84BD	# <CJK>
0x5D6D	0x84D3	# <CJK>
0x5D6E	0x84CA	# <CJK>
0x5D6F	0x84BF	# <CJK>
0x5D70	0x84BA	# <CJK>
0x5D71	0x863A	# <CJK>
0x5D72	0x84A1	# <CJK>
0x5D73	0x84B9	# <CJK>
0x5D74	0x84B4	# <CJK>
0x5D75	0x8497	# <CJK>
0x5D76	0x93A3	# <CJK>
0x5D77	0x8577	# <CJK>
0x5D78	0x850C	# <CJK>
0x5D79	0x750D	# <CJK>
0x5D7A	0x8538	# <CJK>
0x5D7B	0x84F0	# <CJK>
0x5D7C	0x861E	# <CJK>
0x5D7D	0x851F	# <CJK>
0x5D7E	0x85FA	# <CJK>
0x5E21	0x8556	# <CJK>
0x5E22	0x853B	# <CJK>
0x5E23	0x84FF	# <CJK>
0x5E24	0x84FC	# <CJK>
0x5E25	0x8559	# <CJK>
0x5E26	0x8548	# <CJK>
0x5E27	0x8568	# <CJK>
0x5E28	0x8564	# <CJK>
0x5E29	0x855E	# <CJK>
0x5E2A	0x857A	# <CJK>
0x5E2B	0x77A2	# <CJK>
0x5E2C	0x8543	# <CJK>
0x5E2D	0x8604	# <CJK>
0x5E2E	0x857B	# <CJK>
0x5E2F	0x85A4	# <CJK>
0x5E30	0x85A8	# <CJK>
0x5E31	0x8587	# <CJK>
0x5E32	0x858F	# <CJK>
0x5E33	0x8579	# <CJK>
0x5E34	0x85EA	# <CJK>
0x5E35	0x859C	# <CJK>
0x5E36	0x8585	# <CJK>
0x5E37	0x85B9	# <CJK>
0x5E38	0x85B7	# <CJK>
0x5E39	0x85B0	# <CJK>
0x5E3A	0x861A	# <CJK>
0x5E3B	0x85C1	# <CJK>
0x5E3C	0x85DC	# <CJK>
0x5E3D	0x85FF	# <CJK>
0x5E3E	0x8627	# <CJK>
0x5E3F	0x8605	# <CJK>
0x5E40	0x8629	# <CJK>
0x5E41	0x8616	# <CJK>
0x5E42	0x863C	# <CJK>
0x5E43	0x5EFE	# <CJK>
0x5E44	0x5F08	# <CJK>
0x5E45	0x593C	# <CJK>
0x5E46	0x5969	# <CJK>
0x5E47	0x8037	# <CJK>
0x5E48	0x5955	# <CJK>
0x5E49	0x595A	# <CJK>
0x5E4A	0x5958	# <CJK>
0x5E4B	0x530F	# <CJK>
0x5E4C	0x5C22	# <CJK>
0x5E4D	0x5C25	# <CJK>
0x5E4E	0x5C2C	# <CJK>
0x5E4F	0x5C37	# <CJK>
0x5E50	0x624C	# <CJK>
0x5E51	0x636B	# <CJK>
0x5E52	0x6476	# <CJK>
0x5E53	0x62BB	# <CJK>
0x5E54	0x62CA	# <CJK>
0x5E55	0x62DA	# <CJK>
0x5E56	0x62D7	# <CJK>
0x5E57	0x62EE	# <CJK>
0x5E58	0x649F	# <CJK>
0x5E59	0x62F6	# <CJK>
0x5E5A	0x6339	# <CJK>
0x5E5B	0x634B	# <CJK>
0x5E5C	0x6343	# <CJK>
0x5E5D	0x63AD	# <CJK>
0x5E5E	0x63F6	# <CJK>
0x5E5F	0x6371	# <CJK>
0x5E60	0x637A	# <CJK>
0x5E61	0x638E	# <CJK>
0x5E62	0x6451	# <CJK>
0x5E63	0x636D	# <CJK>
0x5E64	0x63AC	# <CJK>
0x5E65	0x638A	# <CJK>
0x5E66	0x6369	# <CJK>
0x5E67	0x63AE	# <CJK>
0x5E68	0x645C	# <CJK>
0x5E69	0x63F2	# <CJK>
0x5E6A	0x63F8	# <CJK>
0x5E6B	0x63E0	# <CJK>
0x5E6C	0x64B3	# <CJK>
0x5E6D	0x63C4	# <CJK>
0x5E6E	0x63DE	# <CJK>
0x5E6F	0x63CE	# <CJK>
0x5E70	0x6452	# <CJK>
0x5E71	0x63C6	# <CJK>
0x5E72	0x63BE	# <CJK>
0x5E73	0x6504	# <CJK>
0x5E74	0x6441	# <CJK>
0x5E75	0x640B	# <CJK>
0x5E76	0x641B	# <CJK>
0x5E77	0x6420	# <CJK>
0x5E78	0x640C	# <CJK>
0x5E79	0x6426	# <CJK>
0x5E7A	0x6421	# <CJK>
0x5E7B	0x645E	# <CJK>
0x5E7C	0x6516	# <CJK>
0x5E7D	0x646D	# <CJK>
0x5E7E	0x6496	# <CJK>
0x5F21	0x647A	# <CJK>
0x5F22	0x64F7	# <CJK>
0x5F23	0x64FC	# <CJK>
0x5F24	0x6499	# <CJK>
0x5F25	0x651B	# <CJK>
0x5F26	0x64C0	# <CJK>
0x5F27	0x64D0	# <CJK>
0x5F28	0x64D7	# <CJK>
0x5F29	0x64E4	# <CJK>
0x5F2A	0x64E2	# <CJK>
0x5F2B	0x6509	# <CJK>
0x5F2C	0x6525	# <CJK>
0x5F2D	0x652E	# <CJK>
0x5F2E	0x5F0B	# <CJK>
0x5F2F	0x5FD2	# <CJK>
0x5F30	0x7519	# <CJK>
0x5F31	0x5F11	# <CJK>
0x5F32	0x535F	# <CJK>
0x5F33	0x53F1	# <CJK>
0x5F34	0x5630	# <CJK>
0x5F35	0x53E9	# <CJK>
0x5F36	0x53E8	# <CJK>
0x5F37	0x53FB	# <CJK>
0x5F38	0x5412	# <CJK>
0x5F39	0x5416	# <CJK>
0x5F3A	0x5406	# <CJK>
0x5F3B	0x544B	# <CJK>
0x5F3C	0x5638	# <CJK>
0x5F3D	0x56C8	# <CJK>
0x5F3E	0x5454	# <CJK>
0x5F3F	0x56A6	# <CJK>
0x5F40	0x5443	# <CJK>
0x5F41	0x5421	# <CJK>
0x5F42	0x5504	# <CJK>
0x5F43	0x54BC	# <CJK>
0x5F44	0x5423	# <CJK>
0x5F45	0x5432	# <CJK>
0x5F46	0x5482	# <CJK>
0x5F47	0x5494	# <CJK>
0x5F48	0x5477	# <CJK>
0x5F49	0x5471	# <CJK>
0x5F4A	0x5464	# <CJK>
0x5F4B	0x549A	# <CJK>
0x5F4C	0x5680	# <CJK>
0x5F4D	0x5484	# <CJK>
0x5F4E	0x5476	# <CJK>
0x5F4F	0x5466	# <CJK>
0x5F50	0x565D	# <CJK>
0x5F51	0x54D0	# <CJK>
0x5F52	0x54AD	# <CJK>
0x5F53	0x54C2	# <CJK>
0x5F54	0x54B4	# <CJK>
0x5F55	0x5660	# <CJK>
0x5F56	0x54A7	# <CJK>
0x5F57	0x54A6	# <CJK>
0x5F58	0x5635	# <CJK>
0x5F59	0x55F6	# <CJK>
0x5F5A	0x5472	# <CJK>
0x5F5B	0x54A3	# <CJK>
0x5F5C	0x5666	# <CJK>
0x5F5D	0x54BB	# <CJK>
0x5F5E	0x54BF	# <CJK>
0x5F5F	0x54CC	# <CJK>
0x5F60	0x5672	# <CJK>
0x5F61	0x54DA	# <CJK>
0x5F62	0x568C	# <CJK>
0x5F63	0x54A9	# <CJK>
0x5F64	0x54AA	# <CJK>
0x5F65	0x54A4	# <CJK>
0x5F66	0x5665	# <CJK>
0x5F67	0x54CF	# <CJK>
0x5F68	0x54DE	# <CJK>
0x5F69	0x561C	# <CJK>
0x5F6A	0x54E7	# <CJK>
0x5F6B	0x562E	# <CJK>
0x5F6C	0x54FD	# <CJK>
0x5F6D	0x5514	# <CJK>
0x5F6E	0x54F3	# <CJK>
0x5F6F	0x55E9	# <CJK>
0x5F70	0x5523	# <CJK>
0x5F71	0x550F	# <CJK>
0x5F72	0x5511	# <CJK>
0x5F73	0x5527	# <CJK>
0x5F74	0x552A	# <CJK>
0x5F75	0x5616	# <CJK>
0x5F76	0x558F	# <CJK>
0x5F77	0x55B5	# <CJK>
0x5F78	0x5549	# <CJK>
0x5F79	0x56C0	# <CJK>
0x5F7A	0x5541	# <CJK>
0x5F7B	0x5555	# <CJK>
0x5F7C	0x553F	# <CJK>
0x5F7D	0x5550	# <CJK>
0x5F7E	0x553C	# <CJK>
0x6021	0x5537	# <CJK>
0x6022	0x5556	# <CJK>
0x6023	0x5575	# <CJK>
0x6024	0x5576	# <CJK>
0x6025	0x5577	# <CJK>
0x6026	0x5533	# <CJK>
0x6027	0x5530	# <CJK>
0x6028	0x555C	# <CJK>
0x6029	0x558B	# <CJK>
0x602A	0x55D2	# <CJK>
0x602B	0x5583	# <CJK>
0x602C	0x55B1	# <CJK>
0x602D	0x55B9	# <CJK>
0x602E	0x5588	# <CJK>
0x602F	0x5581	# <CJK>
0x6030	0x559F	# <CJK>
0x6031	0x557E	# <CJK>
0x6032	0x55D6	# <CJK>
0x6033	0x5591	# <CJK>
0x6034	0x557B	# <CJK>
0x6035	0x55DF	# <CJK>
0x6036	0x560D	# <CJK>
0x6037	0x56B3	# <CJK>
0x6038	0x5594	# <CJK>
0x6039	0x5599	# <CJK>
0x603A	0x55EA	# <CJK>
0x603B	0x55F7	# <CJK>
0x603C	0x55C9	# <CJK>
0x603D	0x561F	# <CJK>
0x603E	0x55D1	# <CJK>
0x603F	0x56C1	# <CJK>
0x6040	0x55EC	# <CJK>
0x6041	0x55D4	# <CJK>
0x6042	0x55E6	# <CJK>
0x6043	0x55DD	# <CJK>
0x6044	0x55C4	# <CJK>
0x6045	0x55EF	# <CJK>
0x6046	0x55E5	# <CJK>
0x6047	0x55F2	# <CJK>
0x6048	0x566F	# <CJK>
0x6049	0x55CC	# <CJK>
0x604A	0x55CD	# <CJK>
0x604B	0x55E8	# <CJK>
0x604C	0x55F5	# <CJK>
0x604D	0x55E4	# <CJK>
0x604E	0x8F61	# <CJK>
0x604F	0x561E	# <CJK>
0x6050	0x5608	# <CJK>
0x6051	0x560C	# <CJK>
0x6052	0x5601	# <CJK>
0x6053	0x56B6	# <CJK>
0x6054	0x5623	# <CJK>
0x6055	0x55FE	# <CJK>
0x6056	0x5600	# <CJK>
0x6057	0x5627	# <CJK>
0x6058	0x562D	# <CJK>
0x6059	0x5658	# <CJK>
0x605A	0x5639	# <CJK>
0x605B	0x5657	# <CJK>
0x605C	0x562C	# <CJK>
0x605D	0x564D	# <CJK>
0x605E	0x5662	# <CJK>
0x605F	0x5659	# <CJK>
0x6060	0x5695	# <CJK>
0x6061	0x564C	# <CJK>
0x6062	0x5654	# <CJK>
0x6063	0x5686	# <CJK>
0x6064	0x5664	# <CJK>
0x6065	0x5671	# <CJK>
0x6066	0x566B	# <CJK>
0x6067	0x567B	# <CJK>
0x6068	0x567C	# <CJK>
0x6069	0x5685	# <CJK>
0x606A	0x5693	# <CJK>
0x606B	0x56AF	# <CJK>
0x606C	0x56D4	# <CJK>
0x606D	0x56D7	# <CJK>
0x606E	0x56DD	# <CJK>
0x606F	0x56E1	# <CJK>
0x6070	0x5707	# <CJK>
0x6071	0x56EB	# <CJK>
0x6072	0x56F9	# <CJK>
0x6073	0x56FF	# <CJK>
0x6074	0x5704	# <CJK>
0x6075	0x570A	# <CJK>
0x6076	0x5709	# <CJK>
0x6077	0x571C	# <CJK>
0x6078	0x5E43	# <CJK>
0x6079	0x5E19	# <CJK>
0x607A	0x5E14	# <CJK>
0x607B	0x5E11	# <CJK>
0x607C	0x5E6C	# <CJK>
0x607D	0x5E58	# <CJK>
0x607E	0x5E57	# <CJK>
0x6121	0x5E37	# <CJK>
0x6122	0x5E44	# <CJK>
0x6123	0x5E54	# <CJK>
0x6124	0x5E5B	# <CJK>
0x6125	0x5E5E	# <CJK>
0x6126	0x5E61	# <CJK>
0x6127	0x5C8C	# <CJK>
0x6128	0x5C7A	# <CJK>
0x6129	0x5C8D	# <CJK>
0x612A	0x5C90	# <CJK>
0x612B	0x5D87	# <CJK>
0x612C	0x5C88	# <CJK>
0x612D	0x5CF4	# <CJK>
0x612E	0x5C99	# <CJK>
0x612F	0x5C91	# <CJK>
0x6130	0x5D50	# <CJK>
0x6131	0x5C9C	# <CJK>
0x6132	0x5CB5	# <CJK>
0x6133	0x5CA2	# <CJK>
0x6134	0x5D2C	# <CJK>
0x6135	0x5CAC	# <CJK>
0x6136	0x5CAB	# <CJK>
0x6137	0x5CB1	# <CJK>
0x6138	0x5CA3	# <CJK>
0x6139	0x5CC1	# <CJK>
0x613A	0x5CB7	# <CJK>
0x613B	0x5DA7	# <CJK>
0x613C	0x5CD2	# <CJK>
0x613D	0x5DA0	# <CJK>
0x613E	0x5CCB	# <CJK>
0x613F	0x5D22	# <CJK>
0x6140	0x5D97	# <CJK>
0x6141	0x5D0D	# <CJK>
0x6142	0x5D27	# <CJK>
0x6143	0x5D26	# <CJK>
0x6144	0x5D2E	# <CJK>
0x6145	0x5D24	# <CJK>
0x6146	0x5D1E	# <CJK>
0x6147	0x5D06	# <CJK>
0x6148	0x5D1B	# <CJK>
0x6149	0x5DB8	# <CJK>
0x614A	0x5D3E	# <CJK>
0x614B	0x5D34	# <CJK>
0x614C	0x5D3D	# <CJK>
0x614D	0x5D6C	# <CJK>
0x614E	0x5D5B	# <CJK>
0x614F	0x5D6F	# <CJK>
0x6150	0x5D81	# <CJK>
0x6151	0x5D6B	# <CJK>
0x6152	0x5D4B	# <CJK>
0x6153	0x5D4A	# <CJK>
0x6154	0x5D69	# <CJK>
0x6155	0x5D74	# <CJK>
0x6156	0x5D82	# <CJK>
0x6157	0x5D99	# <CJK>
0x6158	0x5D9D	# <CJK>
0x6159	0x8C73	# <CJK>
0x615A	0x5DB7	# <CJK>
0x615B	0x5DD4	# <CJK>
0x615C	0x5F73	# <CJK>
0x615D	0x5F77	# <CJK>
0x615E	0x5F82	# <CJK>
0x615F	0x5F87	# <CJK>
0x6160	0x5F89	# <CJK>
0x6161	0x540E	# <CJK>
0x6162	0x5FA0	# <CJK>
0x6163	0x5F99	# <CJK>
0x6164	0x5F9C	# <CJK>
0x6165	0x5FA8	# <CJK>
0x6166	0x5FAD	# <CJK>
0x6167	0x5FB5	# <CJK>
0x6168	0x5FBC	# <CJK>
0x6169	0x8862	# <CJK>
0x616A	0x5F61	# <CJK>
0x616B	0x72AD	# <CJK>
0x616C	0x72B0	# <CJK>
0x616D	0x72B4	# <CJK>
0x616E	0x7377	# <CJK>
0x616F	0x7341	# <CJK>
0x6170	0x72C3	# <CJK>
0x6171	0x72C1	# <CJK>
0x6172	0x72CE	# <CJK>
0x6173	0x72CD	# <CJK>
0x6174	0x72D2	# <CJK>
0x6175	0x72E8	# <CJK>
0x6176	0x736A	# <CJK>
0x6177	0x72E9	# <CJK>
0x6178	0x733B	# <CJK>
0x6179	0x72F4	# <CJK>
0x617A	0x72F7	# <CJK>
0x617B	0x7301	# <CJK>
0x617C	0x72F3	# <CJK>
0x617D	0x736B	# <CJK>
0x617E	0x72FA	# <CJK>
0x6221	0x72FB	# <CJK>
0x6222	0x7317	# <CJK>
0x6223	0x7313	# <CJK>
0x6224	0x7380	# <CJK>
0x6225	0x730A	# <CJK>
0x6226	0x731E	# <CJK>
0x6227	0x731D	# <CJK>
0x6228	0x737C	# <CJK>
0x6229	0x7322	# <CJK>
0x622A	0x7339	# <CJK>
0x622B	0x7325	# <CJK>
0x622C	0x732C	# <CJK>
0x622D	0x7338	# <CJK>
0x622E	0x7331	# <CJK>
0x622F	0x7350	# <CJK>
0x6230	0x734D	# <CJK>
0x6231	0x7357	# <CJK>
0x6232	0x7360	# <CJK>
0x6233	0x736C	# <CJK>
0x6234	0x736F	# <CJK>
0x6235	0x737E	# <CJK>
0x6236	0x821B	# <CJK>
0x6237	0x5925	# <CJK>
0x6238	0x98E7	# <CJK>
0x6239	0x5924	# <CJK>
0x623A	0x5902	# <CJK>
0x623B	0x98E0	# <CJK>
0x623C	0x9933	# <CJK>
0x623D	0x98E9	# <CJK>
0x623E	0x993C	# <CJK>
0x623F	0x98EA	# <CJK>
0x6240	0x98EB	# <CJK>
0x6241	0x98ED	# <CJK>
0x6242	0x98F4	# <CJK>
0x6243	0x9909	# <CJK>
0x6244	0x9911	# <CJK>
0x6245	0x4F59	# <CJK>
0x6246	0x991B	# <CJK>
0x6247	0x9937	# <CJK>
0x6248	0x993F	# <CJK>
0x6249	0x9943	# <CJK>
0x624A	0x9948	# <CJK>
0x624B	0x9949	# <CJK>
0x624C	0x994A	# <CJK>
0x624D	0x994C	# <CJK>
0x624E	0x9962	# <CJK>
0x624F	0x5E80	# <CJK>
0x6250	0x5EE1	# <CJK>
0x6251	0x5E8B	# <CJK>
0x6252	0x5E96	# <CJK>
0x6253	0x5EA5	# <CJK>
0x6254	0x5EA0	# <CJK>
0x6255	0x5EB9	# <CJK>
0x6256	0x5EB5	# <CJK>
0x6257	0x5EBE	# <CJK>
0x6258	0x5EB3	# <CJK>
0x6259	0x8CE1	# <CJK>
0x625A	0x5ED2	# <CJK>
0x625B	0x5ED1	# <CJK>
0x625C	0x5EDB	# <CJK>
0x625D	0x5EE8	# <CJK>
0x625E	0x5EEA	# <CJK>
0x625F	0x81BA	# <CJK>
0x6260	0x5FC4	# <CJK>
0x6261	0x5FC9	# <CJK>
0x6262	0x5FD6	# <CJK>
0x6263	0x61FA	# <CJK>
0x6264	0x61AE	# <CJK>
0x6265	0x5FEE	# <CJK>
0x6266	0x616A	# <CJK>
0x6267	0x5FE1	# <CJK>
0x6268	0x5FE4	# <CJK>
0x6269	0x613E	# <CJK>
0x626A	0x60B5	# <CJK>
0x626B	0x6134	# <CJK>
0x626C	0x5FEA	# <CJK>
0x626D	0x5FED	# <CJK>
0x626E	0x5FF8	# <CJK>
0x626F	0x6019	# <CJK>
0x6270	0x6035	# <CJK>
0x6271	0x6026	# <CJK>
0x6272	0x601B	# <CJK>
0x6273	0x600F	# <CJK>
0x6274	0x600D	# <CJK>
0x6275	0x6029	# <CJK>
0x6276	0x602B	# <CJK>
0x6277	0x600A	# <CJK>
0x6278	0x61CC	# <CJK>
0x6279	0x6021	# <CJK>
0x627A	0x615F	# <CJK>
0x627B	0x61E8	# <CJK>
0x627C	0x60FB	# <CJK>
0x627D	0x6137	# <CJK>
0x627E	0x6042	# <CJK>
0x6321	0x606A	# <CJK>
0x6322	0x60F2	# <CJK>
0x6323	0x6096	# <CJK>
0x6324	0x609A	# <CJK>
0x6325	0x6173	# <CJK>
0x6326	0x609D	# <CJK>
0x6327	0x6083	# <CJK>
0x6328	0x6092	# <CJK>
0x6329	0x608C	# <CJK>
0x632A	0x609B	# <CJK>
0x632B	0x611C	# <CJK>
0x632C	0x60BB	# <CJK>
0x632D	0x60B1	# <CJK>
0x632E	0x60DD	# <CJK>
0x632F	0x60D8	# <CJK>
0x6330	0x60C6	# <CJK>
0x6331	0x60DA	# <CJK>
0x6332	0x60B4	# <CJK>
0x6333	0x6120	# <CJK>
0x6334	0x6192	# <CJK>
0x6335	0x6115	# <CJK>
0x6336	0x6123	# <CJK>
0x6337	0x60F4	# <CJK>
0x6338	0x6100	# <CJK>
0x6339	0x610E	# <CJK>
0x633A	0x612B	# <CJK>
0x633B	0x614A	# <CJK>
0x633C	0x6175	# <CJK>
0x633D	0x61AC	# <CJK>
0x633E	0x6194	# <CJK>
0x633F	0x61A7	# <CJK>
0x6340	0x61B7	# <CJK>
0x6341	0x61D4	# <CJK>
0x6342	0x61F5	# <CJK>
0x6343	0x5FDD	# <CJK>
0x6344	0x96B3	# <CJK>
0x6345	0x9582	# <CJK>
0x6346	0x9586	# <CJK>
0x6347	0x95C8	# <CJK>
0x6348	0x958E	# <CJK>
0x6349	0x9594	# <CJK>
0x634A	0x958C	# <CJK>
0x634B	0x95E5	# <CJK>
0x634C	0x95AD	# <CJK>
0x634D	0x95AB	# <CJK>
0x634E	0x9B2E	# <CJK>
0x634F	0x95AC	# <CJK>
0x6350	0x95BE	# <CJK>
0x6351	0x95B6	# <CJK>
0x6352	0x9B29	# <CJK>
0x6353	0x95BF	# <CJK>
0x6354	0x95BD	# <CJK>
0x6355	0x95BC	# <CJK>
0x6356	0x95C3	# <CJK>
0x6357	0x95CB	# <CJK>
0x6358	0x95D4	# <CJK>
0x6359	0x95D0	# <CJK>
0x635A	0x95D5	# <CJK>
0x635B	0x95DE	# <CJK>
0x635C	0x4E2C	# <CJK>
0x635D	0x723F	# <CJK>
0x635E	0x6215	# <CJK>
0x635F	0x6C35	# <CJK>
0x6360	0x6C54	# <CJK>
0x6361	0x6C5C	# <CJK>
0x6362	0x6C4A	# <CJK>
0x6363	0x7043	# <CJK>
0x6364	0x6C85	# <CJK>
0x6365	0x6C90	# <CJK>
0x6366	0x6C94	# <CJK>
0x6367	0x6C8C	# <CJK>
0x6368	0x6C68	# <CJK>
0x6369	0x6C69	# <CJK>
0x636A	0x6C74	# <CJK>
0x636B	0x6C76	# <CJK>
0x636C	0x6C86	# <CJK>
0x636D	0x6F59	# <CJK>
0x636E	0x6CD0	# <CJK>
0x636F	0x6CD4	# <CJK>
0x6370	0x6CAD	# <CJK>
0x6371	0x7027	# <CJK>
0x6372	0x7018	# <CJK>
0x6373	0x6CF1	# <CJK>
0x6374	0x6CD7	# <CJK>
0x6375	0x6CB2	# <CJK>
0x6376	0x6CE0	# <CJK>
0x6377	0x6CD6	# <CJK>
0x6378	0x6FFC	# <CJK>
0x6379	0x6CEB	# <CJK>
0x637A	0x6CEE	# <CJK>
0x637B	0x6CB1	# <CJK>
0x637C	0x6CD3	# <CJK>
0x637D	0x6CEF	# <CJK>
0x637E	0x6D87	# <CJK>
0x6421	0x6D39	# <CJK>
0x6422	0x6D27	# <CJK>
0x6423	0x6D0C	# <CJK>
0x6424	0x6D79	# <CJK>
0x6425	0x6E5E	# <CJK>
0x6426	0x6D07	# <CJK>
0x6427	0x6D04	# <CJK>
0x6428	0x6D19	# <CJK>
0x6429	0x6D0E	# <CJK>
0x642A	0x6D2B	# <CJK>
0x642B	0x6FAE	# <CJK>
0x642C	0x6D2E	# <CJK>
0x642D	0x6D35	# <CJK>
0x642E	0x6D1A	# <CJK>
0x642F	0x700F	# <CJK>
0x6430	0x6EF8	# <CJK>
0x6431	0x6F6F	# <CJK>
0x6432	0x6D33	# <CJK>
0x6433	0x6D91	# <CJK>
0x6434	0x6D6F	# <CJK>
0x6435	0x6DF6	# <CJK>
0x6436	0x6F7F	# <CJK>
0x6437	0x6D5E	# <CJK>
0x6438	0x6D93	# <CJK>
0x6439	0x6D94	# <CJK>
0x643A	0x6D5C	# <CJK>
0x643B	0x6D60	# <CJK>
0x643C	0x6D7C	# <CJK>
0x643D	0x6D63	# <CJK>
0x643E	0x6E1A	# <CJK>
0x643F	0x6DC7	# <CJK>
0x6440	0x6DC5	# <CJK>
0x6441	0x6DDE	# <CJK>
0x6442	0x7006	# <CJK>
0x6443	0x6DBF	# <CJK>
0x6444	0x6DE0	# <CJK>
0x6445	0x6FA0	# <CJK>
0x6446	0x6DE6	# <CJK>
0x6447	0x6DDD	# <CJK>
0x6448	0x6DD9	# <CJK>
0x6449	0x700B	# <CJK>
0x644A	0x6DAB	# <CJK>
0x644B	0x6E0C	# <CJK>
0x644C	0x6DAE	# <CJK>
0x644D	0x6E2B	# <CJK>
0x644E	0x6E6E	# <CJK>
0x644F	0x6E4E	# <CJK>
0x6450	0x6E6B	# <CJK>
0x6451	0x6EB2	# <CJK>
0x6452	0x6E5F	# <CJK>
0x6453	0x6E86	# <CJK>
0x6454	0x6E53	# <CJK>
0x6455	0x6E54	# <CJK>
0x6456	0x6E32	# <CJK>
0x6457	0x6E25	# <CJK>
0x6458	0x6E44	# <CJK>
0x6459	0x7067	# <CJK>
0x645A	0x6EB1	# <CJK>
0x645B	0x6E98	# <CJK>
0x645C	0x7044	# <CJK>
0x645D	0x6F2D	# <CJK>
0x645E	0x7005	# <CJK>
0x645F	0x6EA5	# <CJK>
0x6460	0x6EA7	# <CJK>
0x6461	0x6EBD	# <CJK>
0x6462	0x6EBB	# <CJK>
0x6463	0x6EB7	# <CJK>
0x6464	0x6F77	# <CJK>
0x6465	0x6EB4	# <CJK>
0x6466	0x6ECF	# <CJK>
0x6467	0x6E8F	# <CJK>
0x6468	0x6EC2	# <CJK>
0x6469	0x6E9F	# <CJK>
0x646A	0x6F62	# <CJK>
0x646B	0x7020	# <CJK>
0x646C	0x701F	# <CJK>
0x646D	0x6F24	# <CJK>
0x646E	0x6F15	# <CJK>
0x646F	0x6EF9	# <CJK>
0x6470	0x6F2F	# <CJK>
0x6471	0x6F36	# <CJK>
0x6472	0x7032	# <CJK>
0x6473	0x6F74	# <CJK>
0x6474	0x6F2A	# <CJK>
0x6475	0x6F09	# <CJK>
0x6476	0x6F29	# <CJK>
0x6477	0x6F89	# <CJK>
0x6478	0x6F8D	# <CJK>
0x6479	0x6F8C	# <CJK>
0x647A	0x6F78	# <CJK>
0x647B	0x6F72	# <CJK>
0x647C	0x6F7C	# <CJK>
0x647D	0x6F7A	# <CJK>
0x647E	0x7028	# <CJK>
0x6521	0x6FC9	# <CJK>
0x6522	0x6FA7	# <CJK>
0x6523	0x6FB9	# <CJK>
0x6524	0x6FB6	# <CJK>
0x6525	0x6FC2	# <CJK>
0x6526	0x6FE1	# <CJK>
0x6527	0x6FEE	# <CJK>
0x6528	0x6FDE	# <CJK>
0x6529	0x6FE0	# <CJK>
0x652A	0x6FEF	# <CJK>
0x652B	0x701A	# <CJK>
0x652C	0x7023	# <CJK>
0x652D	0x701B	# <CJK>
0x652E	0x7039	# <CJK>
0x652F	0x7035	# <CJK>
0x6530	0x705D	# <CJK>
0x6531	0x705E	# <CJK>
0x6532	0x5B80	# <CJK>
0x6533	0x5B84	# <CJK>
0x6534	0x5B95	# <CJK>
0x6535	0x5B93	# <CJK>
0x6536	0x5BA5	# <CJK>
0x6537	0x5BB8	# <CJK>
0x6538	0x752F	# <CJK>
0x6539	0x9A2B	# <CJK>
0x653A	0x6434	# <CJK>
0x653B	0x5BE4	# <CJK>
0x653C	0x5BEE	# <CJK>
0x653D	0x8930	# <CJK>
0x653E	0x5BF0	# <CJK>
0x653F	0x8E47	# <CJK>
0x6540	0x8B07	# <CJK>
0x6541	0x8FB6	# <CJK>
0x6542	0x8FD3	# <CJK>
0x6543	0x8FD5	# <CJK>
0x6544	0x8FE5	# <CJK>
0x6545	0x8FEE	# <CJK>
0x6546	0x8FE4	# <CJK>
0x6547	0x9087	# <CJK>
0x6548	0x8FE6	# <CJK>
0x6549	0x9015	# <CJK>
0x654A	0x8FE8	# <CJK>
0x654B	0x9005	# <CJK>
0x654C	0x9004	# <CJK>
0x654D	0x900B	# <CJK>
0x654E	0x9090	# <CJK>
0x654F	0x9011	# <CJK>
0x6550	0x900D	# <CJK>
0x6551	0x9016	# <CJK>
0x6552	0x9021	# <CJK>
0x6553	0x9035	# <CJK>
0x6554	0x9036	# <CJK>
0x6555	0x902D	# <CJK>
0x6556	0x902F	# <CJK>
0x6557	0x9044	# <CJK>
0x6558	0x9051	# <CJK>
0x6559	0x9052	# <CJK>
0x655A	0x9050	# <CJK>
0x655B	0x9068	# <CJK>
0x655C	0x9058	# <CJK>
0x655D	0x9062	# <CJK>
0x655E	0x905B	# <CJK>
0x655F	0x66B9	# <CJK>
0x6560	0x9074	# <CJK>
0x6561	0x907D	# <CJK>
0x6562	0x9082	# <CJK>
0x6563	0x9088	# <CJK>
0x6564	0x9083	# <CJK>
0x6565	0x908B	# <CJK>
0x6566	0x5F50	# <CJK>
0x6567	0x5F57	# <CJK>
0x6568	0x5F56	# <CJK>
0x6569	0x5F58	# <CJK>
0x656A	0x5C3B	# <CJK>
0x656B	0x54AB	# <CJK>
0x656C	0x5C50	# <CJK>
0x656D	0x5C59	# <CJK>
0x656E	0x5B71	# <CJK>
0x656F	0x5C63	# <CJK>
0x6570	0x5C68	# <CJK>
0x6571	0x7FBC	# <CJK>
0x6572	0x5F33	# <CJK>
0x6573	0x5F29	# <CJK>
0x6574	0x5F2D	# <CJK>
0x6575	0x8274	# <CJK>
0x6576	0x5F3C	# <CJK>
0x6577	0x9B3B	# <CJK>
0x6578	0x5C6E	# <CJK>
0x6579	0x5981	# <CJK>
0x657A	0x5983	# <CJK>
0x657B	0x598D	# <CJK>
0x657C	0x5AF5	# <CJK>
0x657D	0x5AD7	# <CJK>
0x657E	0x59A3	# <CJK>
0x6621	0x5997	# <CJK>
0x6622	0x59CA	# <CJK>
0x6623	0x5B00	# <CJK>
0x6624	0x599E	# <CJK>
0x6625	0x59A4	# <CJK>
0x6626	0x59D2	# <CJK>
0x6627	0x59B2	# <CJK>
0x6628	0x59AF	# <CJK>
0x6629	0x59D7	# <CJK>
0x662A	0x59BE	# <CJK>
0x662B	0x5A6D	# <CJK>
0x662C	0x5B08	# <CJK>
0x662D	0x59DD	# <CJK>
0x662E	0x5B4C	# <CJK>
0x662F	0x59E3	# <CJK>
0x6630	0x59D8	# <CJK>
0x6631	0x59F9	# <CJK>
0x6632	0x5A0C	# <CJK>
0x6633	0x5A09	# <CJK>
0x6634	0x5AA7	# <CJK>
0x6635	0x5AFB	# <CJK>
0x6636	0x5A11	# <CJK>
0x6637	0x5A23	# <CJK>
0x6638	0x5A13	# <CJK>
0x6639	0x5A40	# <CJK>
0x663A	0x5A67	# <CJK>
0x663B	0x5A4A	# <CJK>
0x663C	0x5A55	# <CJK>
0x663D	0x5A3C	# <CJK>
0x663E	0x5A62	# <CJK>
0x663F	0x5B0B	# <CJK>
0x6640	0x80EC	# <CJK>
0x6641	0x5AAA	# <CJK>
0x6642	0x5A9B	# <CJK>
0x6643	0x5A77	# <CJK>
0x6644	0x5A7A	# <CJK>
0x6645	0x5ABE	# <CJK>
0x6646	0x5AEB	# <CJK>
0x6647	0x5AB2	# <CJK>
0x6648	0x5B21	# <CJK>
0x6649	0x5B2A	# <CJK>
0x664A	0x5AB8	# <CJK>
0x664B	0x5AE0	# <CJK>
0x664C	0x5AE3	# <CJK>
0x664D	0x5B19	# <CJK>
0x664E	0x5AD6	# <CJK>
0x664F	0x5AE6	# <CJK>
0x6650	0x5AD8	# <CJK>
0x6651	0x5ADC	# <CJK>
0x6652	0x5B09	# <CJK>
0x6653	0x5B17	# <CJK>
0x6654	0x5B16	# <CJK>
0x6655	0x5B32	# <CJK>
0x6656	0x5B37	# <CJK>
0x6657	0x5B40	# <CJK>
0x6658	0x5C15	# <CJK>
0x6659	0x5C1C	# <CJK>
0x665A	0x5B5A	# <CJK>
0x665B	0x5B65	# <CJK>
0x665C	0x5B73	# <CJK>
0x665D	0x5B51	# <CJK>
0x665E	0x5B53	# <CJK>
0x665F	0x5B62	# <CJK>
0x6660	0x99D4	# <CJK>
0x6661	0x99DF	# <CJK>
0x6662	0x99D9	# <CJK>
0x6663	0x9A36	# <CJK>
0x6664	0x9A5B	# <CJK>
0x6665	0x99D1	# <CJK>
0x6666	0x99D8	# <CJK>
0x6667	0x9A4D	# <CJK>
0x6668	0x9A4A	# <CJK>
0x6669	0x99E2	# <CJK>
0x666A	0x9A6A	# <CJK>
0x666B	0x9A0F	# <CJK>
0x666C	0x9A0D	# <CJK>
0x666D	0x9A05	# <CJK>
0x666E	0x9A42	# <CJK>
0x666F	0x9A2D	# <CJK>
0x6670	0x9A16	# <CJK>
0x6671	0x9A41	# <CJK>
0x6672	0x9A2E	# <CJK>
0x6673	0x9A38	# <CJK>
0x6674	0x9A43	# <CJK>
0x6675	0x9A44	# <CJK>
0x6676	0x9A4F	# <CJK>
0x6677	0x9A65	# <CJK>
0x6678	0x9A64	# <CJK>
0x6679	0x7CF9	# <CJK>
0x667A	0x7D06	# <CJK>
0x667B	0x7D02	# <CJK>
0x667C	0x7D07	# <CJK>
0x667D	0x7D08	# <CJK>
0x667E	0x7E8A	# <CJK>
0x6721	0x7D1C	# <CJK>
0x6722	0x7D15	# <CJK>
0x6723	0x7D13	# <CJK>
0x6724	0x7D3A	# <CJK>
0x6725	0x7D32	# <CJK>
0x6726	0x7D31	# <CJK>
0x6727	0x7E10	# <CJK>
0x6728	0x7D3C	# <CJK>
0x6729	0x7D40	# <CJK>
0x672A	0x7D3F	# <CJK>
0x672B	0x7D5D	# <CJK>
0x672C	0x7D4E	# <CJK>
0x672D	0x7D73	# <CJK>
0x672E	0x7D86	# <CJK>
0x672F	0x7D83	# <CJK>
0x6730	0x7D88	# <CJK>
0x6731	0x7DBE	# <CJK>
0x6732	0x7DBA	# <CJK>
0x6733	0x7DCB	# <CJK>
0x6734	0x7DD4	# <CJK>
0x6735	0x7DC4	# <CJK>
0x6736	0x7D9E	# <CJK>
0x6737	0x7DAC	# <CJK>
0x6738	0x7DB9	# <CJK>
0x6739	0x7DA3	# <CJK>
0x673A	0x7DB0	# <CJK>
0x673B	0x7DC7	# <CJK>
0x673C	0x7DD9	# <CJK>
0x673D	0x7DD7	# <CJK>
0x673E	0x7DF9	# <CJK>
0x673F	0x7DF2	# <CJK>
0x6740	0x7E62	# <CJK>
0x6741	0x7DE6	# <CJK>
0x6742	0x7DF6	# <CJK>
0x6743	0x7DF1	# <CJK>
0x6744	0x7E0B	# <CJK>
0x6745	0x7DE1	# <CJK>
0x6746	0x7E09	# <CJK>
0x6747	0x7E1D	# <CJK>
0x6748	0x7E1F	# <CJK>
0x6749	0x7E1E	# <CJK>
0x674A	0x7E2D	# <CJK>
0x674B	0x7E0A	# <CJK>
0x674C	0x7E11	# <CJK>
0x674D	0x7E7D	# <CJK>
0x674E	0x7E39	# <CJK>
0x674F	0x7E35	# <CJK>
0x6750	0x7E32	# <CJK>
0x6751	0x7E46	# <CJK>
0x6752	0x7E45	# <CJK>
0x6753	0x7E88	# <CJK>
0x6754	0x7E5A	# <CJK>
0x6755	0x7E52	# <CJK>
0x6756	0x7E6E	# <CJK>
0x6757	0x7E7E	# <CJK>
0x6758	0x7E70	# <CJK>
0x6759	0x7E6F	# <CJK>
0x675A	0x7E98	# <CJK>
0x675B	0x5E7A	# <CJK>
0x675C	0x757F	# <CJK>
0x675D	0x5DDB	# <CJK>
0x675E	0x753E	# <CJK>
0x675F	0x9095	# <CJK>
0x6760	0x738E	# <CJK>
0x6761	0x74A3	# <CJK>
0x6762	0x744B	# <CJK>
0x6763	0x73A2	# <CJK>
0x6764	0x739F	# <CJK>
0x6765	0x73CF	# <CJK>
0x6766	0x73C2	# <CJK>
0x6767	0x74CF	# <CJK>
0x6768	0x73B7	# <CJK>
0x6769	0x73B3	# <CJK>
0x676A	0x73C0	# <CJK>
0x676B	0x73C9	# <CJK>
0x676C	0x73C8	# <CJK>
0x676D	0x73E5	# <CJK>
0x676E	0x73D9	# <CJK>
0x676F	0x980A	# <CJK>
0x6770	0x740A	# <CJK>
0x6771	0x73E9	# <CJK>
0x6772	0x73E7	# <CJK>
0x6773	0x73DE	# <CJK>
0x6774	0x74BD	# <CJK>
0x6775	0x743F	# <CJK>
0x6776	0x7489	# <CJK>
0x6777	0x742A	# <CJK>
0x6778	0x745B	# <CJK>
0x6779	0x7426	# <CJK>
0x677A	0x7425	# <CJK>
0x677B	0x7428	# <CJK>
0x677C	0x7430	# <CJK>
0x677D	0x742E	# <CJK>
0x677E	0x742C	# <CJK>
0x6821	0x741B	# <CJK>
0x6822	0x741A	# <CJK>
0x6823	0x7441	# <CJK>
0x6824	0x745C	# <CJK>
0x6825	0x7457	# <CJK>
0x6826	0x7455	# <CJK>
0x6827	0x7459	# <CJK>
0x6828	0x74A6	# <CJK>
0x6829	0x746D	# <CJK>
0x682A	0x747E	# <CJK>
0x682B	0x749C	# <CJK>
0x682C	0x74D4	# <CJK>
0x682D	0x7480	# <CJK>
0x682E	0x7481	# <CJK>
0x682F	0x7487	# <CJK>
0x6830	0x748B	# <CJK>
0x6831	0x749E	# <CJK>
0x6832	0x74A8	# <CJK>
0x6833	0x74A9	# <CJK>
0x6834	0x7490	# <CJK>
0x6835	0x74A7	# <CJK>
0x6836	0x74DA	# <CJK>
0x6837	0x74BA	# <CJK>
0x6838	0x97D9	# <CJK>
0x6839	0x97DE	# <CJK>
0x683A	0x97DC	# <CJK>
0x683B	0x674C	# <CJK>
0x683C	0x6753	# <CJK>
0x683D	0x675E	# <CJK>
0x683E	0x6748	# <CJK>
0x683F	0x69AA	# <CJK>
0x6840	0x6AEA	# <CJK>
0x6841	0x6787	# <CJK>
0x6842	0x676A	# <CJK>
0x6843	0x6773	# <CJK>
0x6844	0x6798	# <CJK>
0x6845	0x6898	# <CJK>
0x6846	0x6775	# <CJK>
0x6847	0x68D6	# <CJK>
0x6848	0x6A05	# <CJK>
0x6849	0x689F	# <CJK>
0x684A	0x678B	# <CJK>
0x684B	0x6777	# <CJK>
0x684C	0x677C	# <CJK>
0x684D	0x67F0	# <CJK>
0x684E	0x6ADB	# <CJK>
0x684F	0x67D8	# <CJK>
0x6850	0x6AF3	# <CJK>
0x6851	0x67E9	# <CJK>
0x6852	0x67B0	# <CJK>
0x6853	0x6AE8	# <CJK>
0x6854	0x67D9	# <CJK>
0x6855	0x67B5	# <CJK>
0x6856	0x67DA	# <CJK>
0x6857	0x67B3	# <CJK>
0x6858	0x67DD	# <CJK>
0x6859	0x6800	# <CJK>
0x685A	0x67C3	# <CJK>
0x685B	0x67B8	# <CJK>
0x685C	0x67E2	# <CJK>
0x685D	0x6ADF	# <CJK>
0x685E	0x67C1	# <CJK>
0x685F	0x6A89	# <CJK>
0x6860	0x6832	# <CJK>
0x6861	0x6833	# <CJK>
0x6862	0x690F	# <CJK>
0x6863	0x6A48	# <CJK>
0x6864	0x684E	# <CJK>
0x6865	0x6968	# <CJK>
0x6866	0x6844	# <CJK>
0x6867	0x69BF	# <CJK>
0x6868	0x6883	# <CJK>
0x6869	0x681D	# <CJK>
0x686A	0x6855	# <CJK>
0x686B	0x6A3A	# <CJK>
0x686C	0x6841	# <CJK>
0x686D	0x6A9C	# <CJK>
0x686E	0x6840	# <CJK>
0x686F	0x6B12	# <CJK>
0x6870	0x684A	# <CJK>
0x6871	0x6849	# <CJK>
0x6872	0x6829	# <CJK>
0x6873	0x68B5	# <CJK>
0x6874	0x688F	# <CJK>
0x6875	0x6874	# <CJK>
0x6876	0x6877	# <CJK>
0x6877	0x6893	# <CJK>
0x6878	0x686B	# <CJK>
0x6879	0x6B1E	# <CJK>
0x687A	0x696E	# <CJK>
0x687B	0x68FC	# <CJK>
0x687C	0x6ADD	# <CJK>
0x687D	0x69E7	# <CJK>
0x687E	0x68F9	# <CJK>
0x6921	0x6B0F	# <CJK>
0x6922	0x68F0	# <CJK>
0x6923	0x690B	# <CJK>
0x6924	0x6901	# <CJK>
0x6925	0x6957	# <CJK>
0x6926	0x68E3	# <CJK>
0x6927	0x6910	# <CJK>
0x6928	0x6971	# <CJK>
0x6929	0x6939	# <CJK>
0x692A	0x6960	# <CJK>
0x692B	0x6942	# <CJK>
0x692C	0x695D	# <CJK>
0x692D	0x6B16	# <CJK>
0x692E	0x696B	# <CJK>
0x692F	0x6980	# <CJK>
0x6930	0x6998	# <CJK>
0x6931	0x6978	# <CJK>
0x6932	0x6934	# <CJK>
0x6933	0x69CC	# <CJK>
0x6934	0x6AEC	# <CJK>
0x6935	0x6ADA	# <CJK>
0x6936	0x69CE	# <CJK>
0x6937	0x6AF8	# <CJK>
0x6938	0x6966	# <CJK>
0x6939	0x6963	# <CJK>
0x693A	0x6979	# <CJK>
0x693B	0x699B	# <CJK>
0x693C	0x69A7	# <CJK>
0x693D	0x69BB	# <CJK>
0x693E	0x69AB	# <CJK>
0x693F	0x69AD	# <CJK>
0x6940	0x69D4	# <CJK>
0x6941	0x69B1	# <CJK>
0x6942	0x69C1	# <CJK>
0x6943	0x69CA	# <CJK>
0x6944	0x6AB3	# <CJK>
0x6945	0x6995	# <CJK>
0x6946	0x6AE7	# <CJK>
0x6947	0x698D	# <CJK>
0x6948	0x69FF	# <CJK>
0x6949	0x6AA3	# <CJK>
0x694A	0x69ED	# <CJK>
0x694B	0x6A17	# <CJK>
0x694C	0x6A18	# <CJK>
0x694D	0x6A65	# <CJK>
0x694E	0x69F2	# <CJK>
0x694F	0x6A44	# <CJK>
0x6950	0x6A3E	# <CJK>
0x6951	0x6AA0	# <CJK>
0x6952	0x6A50	# <CJK>
0x6953	0x6A5B	# <CJK>
0x6954	0x6A35	# <CJK>
0x6955	0x6A8E	# <CJK>
0x6956	0x6AD3	# <CJK>
0x6957	0x6A3D	# <CJK>
0x6958	0x6A28	# <CJK>
0x6959	0x6A58	# <CJK>
0x695A	0x6ADE	# <CJK>
0x695B	0x6A91	# <CJK>
0x695C	0x6A90	# <CJK>
0x695D	0x6AA9	# <CJK>
0x695E	0x6A97	# <CJK>
0x695F	0x6AAB	# <CJK>
0x6960	0x7337	# <CJK>
0x6961	0x7352	# <CJK>
0x6962	0x6B81	# <CJK>
0x6963	0x6B82	# <CJK>
0x6964	0x6BA4	# <CJK>
0x6965	0x6B84	# <CJK>
0x6966	0x6B9E	# <CJK>
0x6967	0x6BAE	# <CJK>
0x6968	0x6B8D	# <CJK>
0x6969	0x6BAB	# <CJK>
0x696A	0x6B9B	# <CJK>
0x696B	0x6BAF	# <CJK>
0x696C	0x6BAA	# <CJK>
0x696D	0x8ED4	# <CJK>
0x696E	0x8EDB	# <CJK>
0x696F	0x8EF2	# <CJK>
0x6970	0x8EFB	# <CJK>
0x6971	0x8F64	# <CJK>
0x6972	0x8EF9	# <CJK>
0x6973	0x8EFC	# <CJK>
0x6974	0x8EEB	# <CJK>
0x6975	0x8EE4	# <CJK>
0x6976	0x8F62	# <CJK>
0x6977	0x8EFA	# <CJK>
0x6978	0x8EFE	# <CJK>
0x6979	0x8F0A	# <CJK>
0x697A	0x8F07	# <CJK>
0x697B	0x8F05	# <CJK>
0x697C	0x8F12	# <CJK>
0x697D	0x8F26	# <CJK>
0x697E	0x8F1E	# <CJK>
0x6A21	0x8F1F	# <CJK>
0x6A22	0x8F1C	# <CJK>
0x6A23	0x8F33	# <CJK>
0x6A24	0x8F46	# <CJK>
0x6A25	0x8F54	# <CJK>
0x6A26	0x8ECE	# <CJK>
0x6A27	0x6214	# <CJK>
0x6A28	0x6227	# <CJK>
0x6A29	0x621B	# <CJK>
0x6A2A	0x621F	# <CJK>
0x6A2B	0x6222	# <CJK>
0x6A2C	0x6221	# <CJK>
0x6A2D	0x6225	# <CJK>
0x6A2E	0x6224	# <CJK>
0x6A2F	0x6229	# <CJK>
0x6A30	0x81E7	# <CJK>
0x6A31	0x750C	# <CJK>
0x6A32	0x74F4	# <CJK>
0x6A33	0x74FF	# <CJK>
0x6A34	0x750F	# <CJK>
0x6A35	0x7511	# <CJK>
0x6A36	0x7513	# <CJK>
0x6A37	0x6534	# <CJK>
0x6A38	0x65EE	# <CJK>
0x6A39	0x65EF	# <CJK>
0x6A3A	0x65F0	# <CJK>
0x6A3B	0x660A	# <CJK>
0x6A3C	0x66C7	# <CJK>
0x6A3D	0x6772	# <CJK>
0x6A3E	0x6603	# <CJK>
0x6A3F	0x6615	# <CJK>
0x6A40	0x6600	# <CJK>
0x6A41	0x7085	# <CJK>
0x6A42	0x66F7	# <CJK>
0x6A43	0x661D	# <CJK>
0x6A44	0x6634	# <CJK>
0x6A45	0x6631	# <CJK>
0x6A46	0x6636	# <CJK>
0x6A47	0x6635	# <CJK>
0x6A48	0x8006	# <CJK>
0x6A49	0x665F	# <CJK>
0x6A4A	0x66C4	# <CJK>
0x6A4B	0x6641	# <CJK>
0x6A4C	0x664F	# <CJK>
0x6A4D	0x6689	# <CJK>
0x6A4E	0x6661	# <CJK>
0x6A4F	0x6657	# <CJK>
0x6A50	0x6677	# <CJK>
0x6A51	0x6684	# <CJK>
0x6A52	0x668C	# <CJK>
0x6A53	0x66D6	# <CJK>
0x6A54	0x669D	# <CJK>
0x6A55	0x66BE	# <CJK>
0x6A56	0x66DB	# <CJK>
0x6A57	0x66DC	# <CJK>
0x6A58	0x66E6	# <CJK>
0x6A59	0x66E9	# <CJK>
0x6A5A	0x8CC1	# <CJK>
0x6A5B	0x8CB0	# <CJK>
0x6A5C	0x8CBA	# <CJK>
0x6A5D	0x8CBD	# <CJK>
0x6A5E	0x8D04	# <CJK>
0x6A5F	0x8CB2	# <CJK>
0x6A60	0x8CC5	# <CJK>
0x6A61	0x8D10	# <CJK>
0x6A62	0x8CD1	# <CJK>
0x6A63	0x8CDA	# <CJK>
0x6A64	0x8CD5	# <CJK>
0x6A65	0x8CEB	# <CJK>
0x6A66	0x8CE7	# <CJK>
0x6A67	0x8CFB	# <CJK>
0x6A68	0x8998	# <CJK>
0x6A69	0x89AC	# <CJK>
0x6A6A	0x89A1	# <CJK>
0x6A6B	0x89BF	# <CJK>
0x6A6C	0x89A6	# <CJK>
0x6A6D	0x89AF	# <CJK>
0x6A6E	0x89B2	# <CJK>
0x6A6F	0x89B7	# <CJK>
0x6A70	0x726E	# <CJK>
0x6A71	0x729F	# <CJK>
0x6A72	0x725D	# <CJK>
0x6A73	0x7266	# <CJK>
0x6A74	0x726F	# <CJK>
0x6A75	0x727E	# <CJK>
0x6A76	0x727F	# <CJK>
0x6A77	0x7284	# <CJK>
0x6A78	0x728B	# <CJK>
0x6A79	0x728D	# <CJK>
0x6A7A	0x728F	# <CJK>
0x6A7B	0x7292	# <CJK>
0x6A7C	0x6308	# <CJK>
0x6A7D	0x6332	# <CJK>
0x6A7E	0x63B0	# <CJK>
0x6B21	0x643F	# <CJK>
0x6B22	0x64D8	# <CJK>
0x6B23	0x8004	# <CJK>
0x6B24	0x6BEA	# <CJK>
0x6B25	0x6BF3	# <CJK>
0x6B26	0x6BFD	# <CJK>
0x6B27	0x6BFF	# <CJK>
0x6B28	0x6BF9	# <CJK>
0x6B29	0x6C05	# <CJK>
0x6B2A	0x6C0C	# <CJK>
0x6B2B	0x6C06	# <CJK>
0x6B2C	0x6C0D	# <CJK>
0x6B2D	0x6C15	# <CJK>
0x6B2E	0x6C18	# <CJK>
0x6B2F	0x6C19	# <CJK>
0x6B30	0x6C1A	# <CJK>
0x6B31	0x6C21	# <CJK>
0x6B32	0x6C2C	# <CJK>
0x6B33	0x6C24	# <CJK>
0x6B34	0x6C2A	# <CJK>
0x6B35	0x6C32	# <CJK>
0x6B36	0x6535	# <CJK>
0x6B37	0x6555	# <CJK>
0x6B38	0x656B	# <CJK>
0x6B39	0x7258	# <CJK>
0x6B3A	0x7252	# <CJK>
0x6B3B	0x7256	# <CJK>
0x6B3C	0x7230	# <CJK>
0x6B3D	0x8662	# <CJK>
0x6B3E	0x5216	# <CJK>
0x6B3F	0x809F	# <CJK>
0x6B40	0x809C	# <CJK>
0x6B41	0x8093	# <CJK>
0x6B42	0x80BC	# <CJK>
0x6B43	0x670A	# <CJK>
0x6B44	0x80BD	# <CJK>
0x6B45	0x80B1	# <CJK>
0x6B46	0x80AB	# <CJK>
0x6B47	0x80AD	# <CJK>
0x6B48	0x80B4	# <CJK>
0x6B49	0x80B7	# <CJK>
0x6B4A	0x6727	# <CJK>
0x6B4B	0x8156	# <CJK>
0x6B4C	0x80E9	# <CJK>
0x6B4D	0x81DA	# <CJK>
0x6B4E	0x80DB	# <CJK>
0x6B4F	0x80C2	# <CJK>
0x6B50	0x80C4	# <CJK>
0x6B51	0x80D9	# <CJK>
0x6B52	0x80CD	# <CJK>
0x6B53	0x80D7	# <CJK>
0x6B54	0x6710	# <CJK>
0x6B55	0x80DD	# <CJK>
0x6B56	0x811B	# <CJK>
0x6B57	0x80F1	# <CJK>
0x6B58	0x80F4	# <CJK>
0x6B59	0x80ED	# <CJK>
0x6B5A	0x81BE	# <CJK>
0x6B5B	0x810E	# <CJK>
0x6B5C	0x80F2	# <CJK>
0x6B5D	0x80FC	# <CJK>
0x6B5E	0x6715	# <CJK>
0x6B5F	0x8112	# <CJK>
0x6B60	0x8C5A	# <CJK>
0x6B61	0x8161	# <CJK>
0x6B62	0x811E	# <CJK>
0x6B63	0x812C	# <CJK>
0x6B64	0x8118	# <CJK>
0x6B65	0x8132	# <CJK>
0x6B66	0x8148	# <CJK>
0x6B67	0x814C	# <CJK>
0x6B68	0x8153	# <CJK>
0x6B69	0x8174	# <CJK>
0x6B6A	0x8159	# <CJK>
0x6B6B	0x815A	# <CJK>
0x6B6C	0x8171	# <CJK>
0x6B6D	0x8160	# <CJK>
0x6B6E	0x8169	# <CJK>
0x6B6F	0x817C	# <CJK>
0x6B70	0x817D	# <CJK>
0x6B71	0x816D	# <CJK>
0x6B72	0x8167	# <CJK>
0x6B73	0x584D	# <CJK>
0x6B74	0x5AB5	# <CJK>
0x6B75	0x8188	# <CJK>
0x6B76	0x8182	# <CJK>
0x6B77	0x81CF	# <CJK>
0x6B78	0x6ED5	# <CJK>
0x6B79	0x81A3	# <CJK>
0x6B7A	0x81AA	# <CJK>
0x6B7B	0x81CC	# <CJK>
0x6B7C	0x6726	# <CJK>
0x6B7D	0x81CA	# <CJK>
0x6B7E	0x81BB	# <CJK>
0x6C21	0x81C1	# <CJK>
0x6C22	0x81A6	# <CJK>
0x6C23	0x6B5F	# <CJK>
0x6C24	0x6B37	# <CJK>
0x6C25	0x6B39	# <CJK>
0x6C26	0x6B43	# <CJK>
0x6C27	0x6B46	# <CJK>
0x6C28	0x6B59	# <CJK>
0x6C29	0x98AE	# <CJK>
0x6C2A	0x98AF	# <CJK>
0x6C2B	0x98B6	# <CJK>
0x6C2C	0x98BC	# <CJK>
0x6C2D	0x98C6	# <CJK>
0x6C2E	0x98C8	# <CJK>
0x6C2F	0x6BB3	# <CJK>
0x6C30	0x5F40	# <CJK>
0x6C31	0x8F42	# <CJK>
0x6C32	0x89F3	# <CJK>
0x6C33	0x6590	# <CJK>
0x6C34	0x9F4F	# <CJK>
0x6C35	0x6595	# <CJK>
0x6C36	0x65BC	# <CJK>
0x6C37	0x65C6	# <CJK>
0x6C38	0x65C4	# <CJK>
0x6C39	0x65C3	# <CJK>
0x6C3A	0x65CC	# <CJK>
0x6C3B	0x65CE	# <CJK>
0x6C3C	0x65D2	# <CJK>
0x6C3D	0x65D6	# <CJK>
0x6C3E	0x716C	# <CJK>
0x6C3F	0x7152	# <CJK>
0x6C40	0x7096	# <CJK>
0x6C41	0x7197	# <CJK>
0x6C42	0x70BB	# <CJK>
0x6C43	0x70C0	# <CJK>
0x6C44	0x70B7	# <CJK>
0x6C45	0x70AB	# <CJK>
0x6C46	0x70B1	# <CJK>
0x6C47	0x71C1	# <CJK>
0x6C48	0x70CA	# <CJK>
0x6C49	0x7110	# <CJK>
0x6C4A	0x7113	# <CJK>
0x6C4B	0x71DC	# <CJK>
0x6C4C	0x712F	# <CJK>
0x6C4D	0x7131	# <CJK>
0x6C4E	0x7173	# <CJK>
0x6C4F	0x715C	# <CJK>
0x6C50	0x7168	# <CJK>
0x6C51	0x7145	# <CJK>
0x6C52	0x7172	# <CJK>
0x6C53	0x714A	# <CJK>
0x6C54	0x7178	# <CJK>
0x6C55	0x717A	# <CJK>
0x6C56	0x7198	# <CJK>
0x6C57	0x71B3	# <CJK>
0x6C58	0x71B5	# <CJK>
0x6C59	0x71A8	# <CJK>
0x6C5A	0x71A0	# <CJK>
0x6C5B	0x71E0	# <CJK>
0x6C5C	0x71D4	# <CJK>
0x6C5D	0x71E7	# <CJK>
0x6C5E	0x71F9	# <CJK>
0x6C5F	0x721D	# <CJK>
0x6C60	0x7228	# <CJK>
0x6C61	0x706C	# <CJK>
0x6C62	0x71FE	# <CJK>
0x6C63	0x7166	# <CJK>
0x6C64	0x71B9	# <CJK>
0x6C65	0x623E	# <CJK>
0x6C66	0x623D	# <CJK>
0x6C67	0x6243	# <CJK>
0x6C68	0x6248	# <CJK>
0x6C69	0x6249	# <CJK>
0x6C6A	0x793B	# <CJK>
0x6C6B	0x7940	# <CJK>
0x6C6C	0x7946	# <CJK>
0x6C6D	0x7949	# <CJK>
0x6C6E	0x795B	# <CJK>
0x6C6F	0x795C	# <CJK>
0x6C70	0x7953	# <CJK>
0x6C71	0x795A	# <CJK>
0x6C72	0x79B0	# <CJK>
0x6C73	0x7957	# <CJK>
0x6C74	0x7960	# <CJK>
0x6C75	0x798E	# <CJK>
0x6C76	0x7967	# <CJK>
0x6C77	0x797A	# <CJK>
0x6C78	0x79AA	# <CJK>
0x6C79	0x798A	# <CJK>
0x6C7A	0x799A	# <CJK>
0x6C7B	0x79A7	# <CJK>
0x6C7C	0x79B3	# <CJK>
0x6C7D	0x5FD1	# <CJK>
0x6C7E	0x5FD0	# <CJK>
0x6D21	0x61DF	# <CJK>
0x6D22	0x605D	# <CJK>
0x6D23	0x605A	# <CJK>
0x6D24	0x6067	# <CJK>
0x6D25	0x6041	# <CJK>
0x6D26	0x6059	# <CJK>
0x6D27	0x6063	# <CJK>
0x6D28	0x6164	# <CJK>
0x6D29	0x6106	# <CJK>
0x6D2A	0x610D	# <CJK>
0x6D2B	0x615D	# <CJK>
0x6D2C	0x61A9	# <CJK>
0x6D2D	0x619D	# <CJK>
0x6D2E	0x61CB	# <CJK>
0x6D2F	0x61E3	# <CJK>
0x6D30	0x6207	# <CJK>
0x6D31	0x8080	# <CJK>
0x6D32	0x807F	# <CJK>
0x6D33	0x6C93	# <CJK>
0x6D34	0x6FA9	# <CJK>
0x6D35	0x6DFC	# <CJK>
0x6D36	0x78EF	# <CJK>
0x6D37	0x77F8	# <CJK>
0x6D38	0x78AD	# <CJK>
0x6D39	0x7809	# <CJK>
0x6D3A	0x7868	# <CJK>
0x6D3B	0x7818	# <CJK>
0x6D3C	0x7811	# <CJK>
0x6D3D	0x65AB	# <CJK>
0x6D3E	0x782D	# <CJK>
0x6D3F	0x78B8	# <CJK>
0x6D40	0x781D	# <CJK>
0x6D41	0x7839	# <CJK>
0x6D42	0x792A	# <CJK>
0x6D43	0x7931	# <CJK>
0x6D44	0x781F	# <CJK>
0x6D45	0x783C	# <CJK>
0x6D46	0x7825	# <CJK>
0x6D47	0x782C	# <CJK>
0x6D48	0x7823	# <CJK>
0x6D49	0x7829	# <CJK>
0x6D4A	0x784E	# <CJK>
0x6D4B	0x786D	# <CJK>
0x6D4C	0x7864	# <CJK>
0x6D4D	0x78FD	# <CJK>
0x6D4E	0x7826	# <CJK>
0x6D4F	0x7850	# <CJK>
0x6D50	0x7847	# <CJK>
0x6D51	0x784C	# <CJK>
0x6D52	0x786A	# <CJK>
0x6D53	0x78E7	# <CJK>
0x6D54	0x7893	# <CJK>
0x6D55	0x789A	# <CJK>
0x6D56	0x7887	# <CJK>
0x6D57	0x78E3	# <CJK>
0x6D58	0x78A1	# <CJK>
0x6D59	0x78A3	# <CJK>
0x6D5A	0x78B2	# <CJK>
0x6D5B	0x78B9	# <CJK>
0x6D5C	0x78A5	# <CJK>
0x6D5D	0x78D4	# <CJK>
0x6D5E	0x78D9	# <CJK>
0x6D5F	0x78C9	# <CJK>
0x6D60	0x78EC	# <CJK>
0x6D61	0x78F2	# <CJK>
0x6D62	0x7905	# <CJK>
0x6D63	0x78F4	# <CJK>
0x6D64	0x7913	# <CJK>
0x6D65	0x7924	# <CJK>
0x6D66	0x791E	# <CJK>
0x6D67	0x7934	# <CJK>
0x6D68	0x9F95	# <CJK>
0x6D69	0x9EF9	# <CJK>
0x6D6A	0x9EFB	# <CJK>
0x6D6B	0x9EFC	# <CJK>
0x6D6C	0x76F1	# <CJK>
0x6D6D	0x7704	# <CJK>
0x6D6E	0x7798	# <CJK>
0x6D6F	0x76F9	# <CJK>
0x6D70	0x7707	# <CJK>
0x6D71	0x7708	# <CJK>
0x6D72	0x771A	# <CJK>
0x6D73	0x7722	# <CJK>
0x6D74	0x7719	# <CJK>
0x6D75	0x772D	# <CJK>
0x6D76	0x7726	# <CJK>
0x6D77	0x7735	# <CJK>
0x6D78	0x7738	# <CJK>
0x6D79	0x775E	# <CJK>
0x6D7A	0x77BC	# <CJK>
0x6D7B	0x7747	# <CJK>
0x6D7C	0x7743	# <CJK>
0x6D7D	0x775A	# <CJK>
0x6D7E	0x7768	# <CJK>
0x6E21	0x7762	# <CJK>
0x6E22	0x7765	# <CJK>
0x6E23	0x777F	# <CJK>
0x6E24	0x778D	# <CJK>
0x6E25	0x777D	# <CJK>
0x6E26	0x7780	# <CJK>
0x6E27	0x778C	# <CJK>
0x6E28	0x7791	# <CJK>
0x6E29	0x779F	# <CJK>
0x6E2A	0x77A0	# <CJK>
0x6E2B	0x77B0	# <CJK>
0x6E2C	0x77B5	# <CJK>
0x6E2D	0x77BD	# <CJK>
0x6E2E	0x753A	# <CJK>
0x6E2F	0x7540	# <CJK>
0x6E30	0x754E	# <CJK>
0x6E31	0x754B	# <CJK>
0x6E32	0x7548	# <CJK>
0x6E33	0x755B	# <CJK>
0x6E34	0x7572	# <CJK>
0x6E35	0x7579	# <CJK>
0x6E36	0x7583	# <CJK>
0x6E37	0x7F58	# <CJK>
0x6E38	0x7F61	# <CJK>
0x6E39	0x7F5F	# <CJK>
0x6E3A	0x8A48	# <CJK>
0x6E3B	0x7F68	# <CJK>
0x6E3C	0x7F86	# <CJK>
0x6E3D	0x7F71	# <CJK>
0x6E3E	0x7F79	# <CJK>
0x6E3F	0x7F88	# <CJK>
0x6E40	0x7F7E	# <CJK>
0x6E41	0x76CD	# <CJK>
0x6E42	0x76E5	# <CJK>
0x6E43	0x8832	# <CJK>
0x6E44	0x91D2	# <CJK>
0x6E45	0x91D3	# <CJK>
0x6E46	0x91D4	# <CJK>
0x6E47	0x91D9	# <CJK>
0x6E48	0x91D7	# <CJK>
0x6E49	0x91D5	# <CJK>
0x6E4A	0x91F7	# <CJK>
0x6E4B	0x91E7	# <CJK>
0x6E4C	0x91E4	# <CJK>
0x6E4D	0x9346	# <CJK>
0x6E4E	0x91F5	# <CJK>
0x6E4F	0x91F9	# <CJK>
0x6E50	0x9208	# <CJK>
0x6E51	0x9226	# <CJK>
0x6E52	0x9245	# <CJK>
0x6E53	0x9211	# <CJK>
0x6E54	0x9210	# <CJK>
0x6E55	0x9201	# <CJK>
0x6E56	0x9227	# <CJK>
0x6E57	0x9204	# <CJK>
0x6E58	0x9225	# <CJK>
0x6E59	0x9200	# <CJK>
0x6E5A	0x923A	# <CJK>
0x6E5B	0x9266	# <CJK>
0x6E5C	0x9237	# <CJK>
0x6E5D	0x9233	# <CJK>
0x6E5E	0x9255	# <CJK>
0x6E5F	0x923D	# <CJK>
0x6E60	0x9238	# <CJK>
0x6E61	0x925E	# <CJK>
0x6E62	0x926C	# <CJK>
0x6E63	0x926D	# <CJK>
0x6E64	0x923F	# <CJK>
0x6E65	0x9460	# <CJK>
0x6E66	0x9230	# <CJK>
0x6E67	0x9249	# <CJK>
0x6E68	0x9248	# <CJK>
0x6E69	0x924D	# <CJK>
0x6E6A	0x922E	# <CJK>
0x6E6B	0x9239	# <CJK>
0x6E6C	0x9438	# <CJK>
0x6E6D	0x92AC	# <CJK>
0x6E6E	0x92A0	# <CJK>
0x6E6F	0x927A	# <CJK>
0x6E70	0x92AA	# <CJK>
0x6E71	0x92EE	# <CJK>
0x6E72	0x92CF	# <CJK>
0x6E73	0x9403	# <CJK>
0x6E74	0x92E3	# <CJK>
0x6E75	0x943A	# <CJK>
0x6E76	0x92B1	# <CJK>
0x6E77	0x92A6	# <CJK>
0x6E78	0x93A7	# <CJK>
0x6E79	0x9296	# <CJK>
0x6E7A	0x92CC	# <CJK>
0x6E7B	0x92A9	# <CJK>
0x6E7C	0x93F5	# <CJK>
0x6E7D	0x9293	# <CJK>
0x6E7E	0x927F	# <CJK>
0x6F21	0x93A9	# <CJK>
0x6F22	0x929A	# <CJK>
0x6F23	0x931A	# <CJK>
0x6F24	0x92AB	# <CJK>
0x6F25	0x9283	# <CJK>
0x6F26	0x940B	# <CJK>
0x6F27	0x92A8	# <CJK>
0x6F28	0x92A3	# <CJK>
0x6F29	0x9412	# <CJK>
0x6F2A	0x9338	# <CJK>
0x6F2B	0x92F1	# <CJK>
0x6F2C	0x93D7	# <CJK>
0x6F2D	0x92E5	# <CJK>
0x6F2E	0x92F0	# <CJK>
0x6F2F	0x92EF	# <CJK>
0x6F30	0x92E8	# <CJK>
0x6F31	0x92BC	# <CJK>
0x6F32	0x92DD	# <CJK>
0x6F33	0x92F6	# <CJK>
0x6F34	0x9426	# <CJK>
0x6F35	0x9427	# <CJK>
0x6F36	0x92C3	# <CJK>
0x6F37	0x92DF	# <CJK>
0x6F38	0x92E6	# <CJK>
0x6F39	0x9312	# <CJK>
0x6F3A	0x9306	# <CJK>
0x6F3B	0x9369	# <CJK>
0x6F3C	0x931B	# <CJK>
0x6F3D	0x9340	# <CJK>
0x6F3E	0x9301	# <CJK>
0x6F3F	0x9315	# <CJK>
0x6F40	0x932E	# <CJK>
0x6F41	0x9343	# <CJK>
0x6F42	0x9307	# <CJK>
0x6F43	0x9308	# <CJK>
0x6F44	0x931F	# <CJK>
0x6F45	0x9319	# <CJK>
0x6F46	0x9365	# <CJK>
0x6F47	0x9347	# <CJK>
0x6F48	0x9376	# <CJK>
0x6F49	0x9354	# <CJK>
0x6F4A	0x9364	# <CJK>
0x6F4B	0x93AA	# <CJK>
0x6F4C	0x9370	# <CJK>
0x6F4D	0x9384	# <CJK>
0x6F4E	0x93E4	# <CJK>
0x6F4F	0x93D8	# <CJK>
0x6F50	0x9428	# <CJK>
0x6F51	0x9387	# <CJK>
0x6F52	0x93CC	# <CJK>
0x6F53	0x9398	# <CJK>
0x6F54	0x93B8	# <CJK>
0x6F55	0x93BF	# <CJK>
0x6F56	0x93A6	# <CJK>
0x6F57	0x93B0	# <CJK>
0x6F58	0x93B5	# <CJK>
0x6F59	0x944C	# <CJK>
0x6F5A	0x93E2	# <CJK>
0x6F5B	0x93DC	# <CJK>
0x6F5C	0x93DD	# <CJK>
0x6F5D	0x93CD	# <CJK>
0x6F5E	0x93DE	# <CJK>
0x6F5F	0x93C3	# <CJK>
0x6F60	0x93C7	# <CJK>
0x6F61	0x93D1	# <CJK>
0x6F62	0x9414	# <CJK>
0x6F63	0x941D	# <CJK>
0x6F64	0x93F7	# <CJK>
0x6F65	0x9465	# <CJK>
0x6F66	0x9413	# <CJK>
0x6F67	0x946D	# <CJK>
0x6F68	0x9420	# <CJK>
0x6F69	0x9479	# <CJK>
0x6F6A	0x93F9	# <CJK>
0x6F6B	0x9419	# <CJK>
0x6F6C	0x944A	# <CJK>
0x6F6D	0x9432	# <CJK>
0x6F6E	0x943F	# <CJK>
0x6F6F	0x9454	# <CJK>
0x6F70	0x9463	# <CJK>
0x6F71	0x937E	# <CJK>
0x6F72	0x77E7	# <CJK>
0x6F73	0x77EC	# <CJK>
0x6F74	0x96C9	# <CJK>
0x6F75	0x79D5	# <CJK>
0x6F76	0x79ED	# <CJK>
0x6F77	0x79E3	# <CJK>
0x6F78	0x79EB	# <CJK>
0x6F79	0x7A06	# <CJK>
0x6F7A	0x5D47	# <CJK>
0x6F7B	0x7A03	# <CJK>
0x6F7C	0x7A02	# <CJK>
0x6F7D	0x7A1E	# <CJK>
0x6F7E	0x7A14	# <CJK>
0x7021	0x7A39	# <CJK>
0x7022	0x7A37	# <CJK>
0x7023	0x7A61	# <CJK>
0x7024	0x9ECF	# <CJK>
0x7025	0x99A5	# <CJK>
0x7026	0x7A70	# <CJK>
0x7027	0x7688	# <CJK>
0x7028	0x768E	# <CJK>
0x7029	0x7693	# <CJK>
0x702A	0x7699	# <CJK>
0x702B	0x76A4	# <CJK>
0x702C	0x74DE	# <CJK>
0x702D	0x74E0	# <CJK>
0x702E	0x752C	# <CJK>
0x702F	0x9CE9	# <CJK>
0x7030	0x9CF6	# <CJK>
0x7031	0x9D07	# <CJK>
0x7032	0x9D06	# <CJK>
0x7033	0x9D23	# <CJK>
0x7034	0x9D87	# <CJK>
0x7035	0x9E15	# <CJK>
0x7036	0x9D1D	# <CJK>
0x7037	0x9D1F	# <CJK>
0x7038	0x9DE5	# <CJK>
0x7039	0x9D2F	# <CJK>
0x703A	0x9DD9	# <CJK>
0x703B	0x9D30	# <CJK>
0x703C	0x9D42	# <CJK>
0x703D	0x9E1E	# <CJK>
0x703E	0x9D53	# <CJK>
0x703F	0x9E1D	# <CJK>
0x7040	0x9D60	# <CJK>
0x7041	0x9D52	# <CJK>
0x7042	0x9DF3	# <CJK>
0x7043	0x9D5C	# <CJK>
0x7044	0x9D61	# <CJK>
0x7045	0x9D93	# <CJK>
0x7046	0x9D6A	# <CJK>
0x7047	0x9D6F	# <CJK>
0x7048	0x9D89	# <CJK>
0x7049	0x9D98	# <CJK>
0x704A	0x9D9A	# <CJK>
0x704B	0x9DC0	# <CJK>
0x704C	0x9DA5	# <CJK>
0x704D	0x9DA9	# <CJK>
0x704E	0x9DC2	# <CJK>
0x704F	0x9DBC	# <CJK>
0x7050	0x9E1A	# <CJK>
0x7051	0x9DD3	# <CJK>
0x7052	0x9DDA	# <CJK>
0x7053	0x9DEF	# <CJK>
0x7054	0x9DE6	# <CJK>
0x7055	0x9DF2	# <CJK>
0x7056	0x9DF8	# <CJK>
0x7057	0x9E0C	# <CJK>
0x7058	0x9DFA	# <CJK>
0x7059	0x9E1B	# <CJK>
0x705A	0x7592	# <CJK>
0x705B	0x7594	# <CJK>
0x705C	0x7664	# <CJK>
0x705D	0x7658	# <CJK>
0x705E	0x759D	# <CJK>
0x705F	0x7667	# <CJK>
0x7060	0x75A3	# <CJK>
0x7061	0x75B3	# <CJK>
0x7062	0x75B4	# <CJK>
0x7063	0x75B8	# <CJK>
0x7064	0x75C4	# <CJK>
0x7065	0x75B1	# <CJK>
0x7066	0x75B0	# <CJK>
0x7067	0x75C3	# <CJK>
0x7068	0x75C2	# <CJK>
0x7069	0x7602	# <CJK>
0x706A	0x75CD	# <CJK>
0x706B	0x75E3	# <CJK>
0x706C	0x7646	# <CJK>
0x706D	0x75E6	# <CJK>
0x706E	0x75E4	# <CJK>
0x706F	0x7647	# <CJK>
0x7070	0x75E7	# <CJK>
0x7071	0x7603	# <CJK>
0x7072	0x75F1	# <CJK>
0x7073	0x75FC	# <CJK>
0x7074	0x75FF	# <CJK>
0x7075	0x7610	# <CJK>
0x7076	0x7600	# <CJK>
0x7077	0x7649	# <CJK>
0x7078	0x760C	# <CJK>
0x7079	0x761E	# <CJK>
0x707A	0x760A	# <CJK>
0x707B	0x7625	# <CJK>
0x707C	0x763B	# <CJK>
0x707D	0x7615	# <CJK>
0x707E	0x7619	# <CJK>
0x7121	0x761B	# <CJK>
0x7122	0x763C	# <CJK>
0x7123	0x7622	# <CJK>
0x7124	0x7620	# <CJK>
0x7125	0x7640	# <CJK>
0x7126	0x762D	# <CJK>
0x7127	0x7630	# <CJK>
0x7128	0x766D	# <CJK>
0x7129	0x7635	# <CJK>
0x712A	0x7643	# <CJK>
0x712B	0x766E	# <CJK>
0x712C	0x7633	# <CJK>
0x712D	0x764D	# <CJK>
0x712E	0x7669	# <CJK>
0x712F	0x7654	# <CJK>
0x7130	0x765C	# <CJK>
0x7131	0x7656	# <CJK>
0x7132	0x7672	# <CJK>
0x7133	0x766F	# <CJK>
0x7134	0x7FCA	# <CJK>
0x7135	0x7AE6	# <CJK>
0x7136	0x7A78	# <CJK>
0x7137	0x7A79	# <CJK>
0x7138	0x7A80	# <CJK>
0x7139	0x7A86	# <CJK>
0x713A	0x7A88	# <CJK>
0x713B	0x7A95	# <CJK>
0x713C	0x7AC7	# <CJK>
0x713D	0x7AA0	# <CJK>
0x713E	0x7AAC	# <CJK>
0x713F	0x7AA8	# <CJK>
0x7140	0x7AB6	# <CJK>
0x7141	0x7AB3	# <CJK>
0x7142	0x8864	# <CJK>
0x7143	0x8869	# <CJK>
0x7144	0x8872	# <CJK>
0x7145	0x887D	# <CJK>
0x7146	0x887F	# <CJK>
0x7147	0x8882	# <CJK>
0x7148	0x88A2	# <CJK>
0x7149	0x8960	# <CJK>
0x714A	0x88B7	# <CJK>
0x714B	0x88BC	# <CJK>
0x714C	0x88C9	# <CJK>
0x714D	0x8933	# <CJK>
0x714E	0x88CE	# <CJK>
0x714F	0x895D	# <CJK>
0x7150	0x8947	# <CJK>
0x7151	0x88F1	# <CJK>
0x7152	0x891A	# <CJK>
0x7153	0x88FC	# <CJK>
0x7154	0x88E8	# <CJK>
0x7155	0x88FE	# <CJK>
0x7156	0x88F0	# <CJK>
0x7157	0x8921	# <CJK>
0x7158	0x8919	# <CJK>
0x7159	0x8913	# <CJK>
0x715A	0x8938	# <CJK>
0x715B	0x890A	# <CJK>
0x715C	0x8964	# <CJK>
0x715D	0x892B	# <CJK>
0x715E	0x8936	# <CJK>
0x715F	0x8941	# <CJK>
0x7160	0x8966	# <CJK>
0x7161	0x897B	# <CJK>
0x7162	0x758B	# <CJK>
0x7163	0x80E5	# <CJK>
0x7164	0x76B8	# <CJK>
0x7165	0x76B4	# <CJK>
0x7166	0x77DC	# <CJK>
0x7167	0x8012	# <CJK>
0x7168	0x8014	# <CJK>
0x7169	0x8016	# <CJK>
0x716A	0x801C	# <CJK>
0x716B	0x8020	# <CJK>
0x716C	0x802E	# <CJK>
0x716D	0x8025	# <CJK>
0x716E	0x8026	# <CJK>
0x716F	0x802C	# <CJK>
0x7170	0x8029	# <CJK>
0x7171	0x8028	# <CJK>
0x7172	0x8031	# <CJK>
0x7173	0x800B	# <CJK>
0x7174	0x8035	# <CJK>
0x7175	0x8043	# <CJK>
0x7176	0x8046	# <CJK>
0x7177	0x8079	# <CJK>
0x7178	0x8052	# <CJK>
0x7179	0x8075	# <CJK>
0x717A	0x8071	# <CJK>
0x717B	0x8983	# <CJK>
0x717C	0x9807	# <CJK>
0x717D	0x980E	# <CJK>
0x717E	0x980F	# <CJK>
0x7221	0x9821	# <CJK>
0x7222	0x981C	# <CJK>
0x7223	0x6F41	# <CJK>
0x7224	0x9826	# <CJK>
0x7225	0x9837	# <CJK>
0x7226	0x984E	# <CJK>
0x7227	0x9853	# <CJK>
0x7228	0x9873	# <CJK>
0x7229	0x9862	# <CJK>
0x722A	0x9859	# <CJK>
0x722B	0x9865	# <CJK>
0x722C	0x986C	# <CJK>
0x722D	0x9870	# <CJK>
0x722E	0x864D	# <CJK>
0x722F	0x8654	# <CJK>
0x7230	0x866C	# <CJK>
0x7231	0x87E3	# <CJK>
0x7232	0x8806	# <CJK>
0x7233	0x867A	# <CJK>
0x7234	0x867C	# <CJK>
0x7235	0x867B	# <CJK>
0x7236	0x86A8	# <CJK>
0x7237	0x868D	# <CJK>
0x7238	0x868B	# <CJK>
0x7239	0x8706	# <CJK>
0x723A	0x869D	# <CJK>
0x723B	0x86A7	# <CJK>
0x723C	0x86A3	# <CJK>
0x723D	0x86AA	# <CJK>
0x723E	0x8693	# <CJK>
0x723F	0x86A9	# <CJK>
0x7240	0x86B6	# <CJK>
0x7241	0x86C4	# <CJK>
0x7242	0x86B5	# <CJK>
0x7243	0x8823	# <CJK>
0x7244	0x86B0	# <CJK>
0x7245	0x86BA	# <CJK>
0x7246	0x86B1	# <CJK>
0x7247	0x86AF	# <CJK>
0x7248	0x86C9	# <CJK>
0x7249	0x87F6	# <CJK>
0x724A	0x86B4	# <CJK>
0x724B	0x86E9	# <CJK>
0x724C	0x86FA	# <CJK>
0x724D	0x87EF	# <CJK>
0x724E	0x86ED	# <CJK>
0x724F	0x8784	# <CJK>
0x7250	0x86D0	# <CJK>
0x7251	0x8713	# <CJK>
0x7252	0x86DE	# <CJK>
0x7253	0x8810	# <CJK>
0x7254	0x86DF	# <CJK>
0x7255	0x86D8	# <CJK>
0x7256	0x86D1	# <CJK>
0x7257	0x8703	# <CJK>
0x7258	0x8707	# <CJK>
0x7259	0x86F8	# <CJK>
0x725A	0x8708	# <CJK>
0x725B	0x870A	# <CJK>
0x725C	0x870D	# <CJK>
0x725D	0x8709	# <CJK>
0x725E	0x8723	# <CJK>
0x725F	0x873B	# <CJK>
0x7260	0x871E	# <CJK>
0x7261	0x8725	# <CJK>
0x7262	0x872E	# <CJK>
0x7263	0x871A	# <CJK>
0x7264	0x873E	# <CJK>
0x7265	0x87C8	# <CJK>
0x7266	0x8734	# <CJK>
0x7267	0x8731	# <CJK>
0x7268	0x8729	# <CJK>
0x7269	0x8737	# <CJK>
0x726A	0x873F	# <CJK>
0x726B	0x8782	# <CJK>
0x726C	0x8722	# <CJK>
0x726D	0x877D	# <CJK>
0x726E	0x8811	# <CJK>
0x726F	0x877B	# <CJK>
0x7270	0x8760	# <CJK>
0x7271	0x8770	# <CJK>
0x7272	0x874C	# <CJK>
0x7273	0x876E	# <CJK>
0x7274	0x878B	# <CJK>
0x7275	0x8753	# <CJK>
0x7276	0x8763	# <CJK>
0x7277	0x87BB	# <CJK>
0x7278	0x8764	# <CJK>
0x7279	0x8759	# <CJK>
0x727A	0x8765	# <CJK>
0x727B	0x8793	# <CJK>
0x727C	0x87AF	# <CJK>
0x727D	0x87CE	# <CJK>
0x727E	0x87D2	# <CJK>
0x7321	0x87C6	# <CJK>
0x7322	0x8788	# <CJK>
0x7323	0x8785	# <CJK>
0x7324	0x87AD	# <CJK>
0x7325	0x8797	# <CJK>
0x7326	0x8783	# <CJK>
0x7327	0x87AB	# <CJK>
0x7328	0x87E5	# <CJK>
0x7329	0x87AC	# <CJK>
0x732A	0x87B5	# <CJK>
0x732B	0x87B3	# <CJK>
0x732C	0x87CB	# <CJK>
0x732D	0x87D3	# <CJK>
0x732E	0x87BD	# <CJK>
0x732F	0x87D1	# <CJK>
0x7330	0x87C0	# <CJK>
0x7331	0x87CA	# <CJK>
0x7332	0x87DB	# <CJK>
0x7333	0x87EA	# <CJK>
0x7334	0x87E0	# <CJK>
0x7335	0x87EE	# <CJK>
0x7336	0x8816	# <CJK>
0x7337	0x8813	# <CJK>
0x7338	0x87FE	# <CJK>
0x7339	0x880A	# <CJK>
0x733A	0x881B	# <CJK>
0x733B	0x8821	# <CJK>
0x733C	0x8839	# <CJK>
0x733D	0x883C	# <CJK>
0x733E	0x7F36	# <CJK>
0x733F	0x7F4C	# <CJK>
0x7340	0x7F44	# <CJK>
0x7341	0x7F45	# <CJK>
0x7342	0x8210	# <CJK>
0x7343	0x7AFA	# <CJK>
0x7344	0x7AFD	# <CJK>
0x7345	0x7B08	# <CJK>
0x7346	0x7BE4	# <CJK>
0x7347	0x7B04	# <CJK>
0x7348	0x7B67	# <CJK>
0x7349	0x7B0A	# <CJK>
0x734A	0x7B2B	# <CJK>
0x734B	0x7B0F	# <CJK>
0x734C	0x7B47	# <CJK>
0x734D	0x7B38	# <CJK>
0x734E	0x7B2A	# <CJK>
0x734F	0x7B19	# <CJK>
0x7350	0x7B2E	# <CJK>
0x7351	0x7B31	# <CJK>
0x7352	0x7B20	# <CJK>
0x7353	0x7B25	# <CJK>
0x7354	0x7B24	# <CJK>
0x7355	0x7B33	# <CJK>
0x7356	0x7C69	# <CJK>
0x7357	0x7B1E	# <CJK>
0x7358	0x7B58	# <CJK>
0x7359	0x7BF3	# <CJK>
0x735A	0x7B45	# <CJK>
0x735B	0x7B75	# <CJK>
0x735C	0x7B4C	# <CJK>
0x735D	0x7B8F	# <CJK>
0x735E	0x7B60	# <CJK>
0x735F	0x7B6E	# <CJK>
0x7360	0x7B7B	# <CJK>
0x7361	0x7B62	# <CJK>
0x7362	0x7B72	# <CJK>
0x7363	0x7B71	# <CJK>
0x7364	0x7B90	# <CJK>
0x7365	0x7C00	# <CJK>
0x7366	0x7BCB	# <CJK>
0x7367	0x7BB8	# <CJK>
0x7368	0x7BAC	# <CJK>
0x7369	0x7B9D	# <CJK>
0x736A	0x7C5C	# <CJK>
0x736B	0x7B85	# <CJK>
0x736C	0x7C1E	# <CJK>
0x736D	0x7B9C	# <CJK>
0x736E	0x7BA2	# <CJK>
0x736F	0x7C2B	# <CJK>
0x7370	0x7BB4	# <CJK>
0x7371	0x7C23	# <CJK>
0x7372	0x7BC1	# <CJK>
0x7373	0x7BCC	# <CJK>
0x7374	0x7BDD	# <CJK>
0x7375	0x7BDA	# <CJK>
0x7376	0x7BE5	# <CJK>
0x7377	0x7BE6	# <CJK>
0x7378	0x7BEA	# <CJK>
0x7379	0x7C0C	# <CJK>
0x737A	0x7BFE	# <CJK>
0x737B	0x7BFC	# <CJK>
0x737C	0x7C0F	# <CJK>
0x737D	0x7C6A	# <CJK>
0x737E	0x7C0B	# <CJK>
0x7421	0x7C1F	# <CJK>
0x7422	0x7C2A	# <CJK>
0x7423	0x7C26	# <CJK>
0x7424	0x7C38	# <CJK>
0x7425	0x7C5F	# <CJK>
0x7426	0x7C40	# <CJK>
0x7427	0x81FE	# <CJK>
0x7428	0x8201	# <CJK>
0x7429	0x8202	# <CJK>
0x742A	0x8204	# <CJK>
0x742B	0x81EC	# <CJK>
0x742C	0x8844	# <CJK>
0x742D	0x8221	# <CJK>
0x742E	0x8222	# <CJK>
0x742F	0x8264	# <CJK>
0x7430	0x822D	# <CJK>
0x7431	0x822F	# <CJK>
0x7432	0x8228	# <CJK>
0x7433	0x822B	# <CJK>
0x7434	0x8238	# <CJK>
0x7435	0x826B	# <CJK>
0x7436	0x8233	# <CJK>
0x7437	0x8234	# <CJK>
0x7438	0x823E	# <CJK>
0x7439	0x8244	# <CJK>
0x743A	0x8249	# <CJK>
0x743B	0x824B	# <CJK>
0x743C	0x824F	# <CJK>
0x743D	0x825A	# <CJK>
0x743E	0x825F	# <CJK>
0x743F	0x8268	# <CJK>
0x7440	0x887E	# <CJK>
0x7441	0x88CA	# <CJK>
0x7442	0x8888	# <CJK>
0x7443	0x88D8	# <CJK>
0x7444	0x88DF	# <CJK>
0x7445	0x895E	# <CJK>
0x7446	0x7F9D	# <CJK>
0x7447	0x7FA5	# <CJK>
0x7448	0x7FA7	# <CJK>
0x7449	0x7FAF	# <CJK>
0x744A	0x7FB0	# <CJK>
0x744B	0x7FB2	# <CJK>
0x744C	0x7C7C	# <CJK>
0x744D	0x6549	# <CJK>
0x744E	0x7C91	# <CJK>
0x744F	0x7CF2	# <CJK>
0x7450	0x7CF6	# <CJK>
0x7451	0x7C9E	# <CJK>
0x7452	0x7CA2	# <CJK>
0x7453	0x7CB2	# <CJK>
0x7454	0x7CBC	# <CJK>
0x7455	0x7CBD	# <CJK>
0x7456	0x7CDD	# <CJK>
0x7457	0x7CC7	# <CJK>
0x7458	0x7CCC	# <CJK>
0x7459	0x7CCD	# <CJK>
0x745A	0x7CC8	# <CJK>
0x745B	0x7CC5	# <CJK>
0x745C	0x7CD7	# <CJK>
0x745D	0x7CE8	# <CJK>
0x745E	0x826E	# <CJK>
0x745F	0x66A8	# <CJK>
0x7460	0x7FBF	# <CJK>
0x7461	0x7FCE	# <CJK>
0x7462	0x7FD5	# <CJK>
0x7463	0x7FE5	# <CJK>
0x7464	0x7FE1	# <CJK>
0x7465	0x7FE6	# <CJK>
0x7466	0x7FE9	# <CJK>
0x7467	0x7FEE	# <CJK>
0x7468	0x7FF3	# <CJK>
0x7469	0x7CF8	# <CJK>
0x746A	0x7E36	# <CJK>
0x746B	0x7DA6	# <CJK>
0x746C	0x7DAE	# <CJK>
0x746D	0x7E47	# <CJK>
0x746E	0x7E9B	# <CJK>
0x746F	0x9EA9	# <CJK>
0x7470	0x9EB4	# <CJK>
0x7471	0x8D73	# <CJK>
0x7472	0x8D84	# <CJK>
0x7473	0x8D94	# <CJK>
0x7474	0x8D91	# <CJK>
0x7475	0x8DB2	# <CJK>
0x7476	0x8D67	# <CJK>
0x7477	0x8D6D	# <CJK>
0x7478	0x8C47	# <CJK>
0x7479	0x8C49	# <CJK>
0x747A	0x914A	# <CJK>
0x747B	0x9150	# <CJK>
0x747C	0x914E	# <CJK>
0x747D	0x914F	# <CJK>
0x747E	0x9164	# <CJK>
0x7521	0x9162	# <CJK>
0x7522	0x9161	# <CJK>
0x7523	0x9170	# <CJK>
0x7524	0x9169	# <CJK>
0x7525	0x916F	# <CJK>
0x7526	0x91C5	# <CJK>
0x7527	0x91C3	# <CJK>
0x7528	0x9172	# <CJK>
0x7529	0x9174	# <CJK>
0x752A	0x9179	# <CJK>
0x752B	0x918C	# <CJK>
0x752C	0x9185	# <CJK>
0x752D	0x9190	# <CJK>
0x752E	0x918D	# <CJK>
0x752F	0x9191	# <CJK>
0x7530	0x91A2	# <CJK>
0x7531	0x91A3	# <CJK>
0x7532	0x91AA	# <CJK>
0x7533	0x91AD	# <CJK>
0x7534	0x91AE	# <CJK>
0x7535	0x91AF	# <CJK>
0x7536	0x91B5	# <CJK>
0x7537	0x91B4	# <CJK>
0x7538	0x91BA	# <CJK>
0x7539	0x8C55	# <CJK>
0x753A	0x9E7A	# <CJK>
0x753B	0x8E89	# <CJK>
0x753C	0x8DEB	# <CJK>
0x753D	0x8E05	# <CJK>
0x753E	0x8E59	# <CJK>
0x753F	0x8E69	# <CJK>
0x7540	0x8DB5	# <CJK>
0x7541	0x8DBF	# <CJK>
0x7542	0x8DBC	# <CJK>
0x7543	0x8DBA	# <CJK>
0x7544	0x8E4C	# <CJK>
0x7545	0x8DD6	# <CJK>
0x7546	0x8DD7	# <CJK>
0x7547	0x8DDA	# <CJK>
0x7548	0x8E92	# <CJK>
0x7549	0x8DCE	# <CJK>
0x754A	0x8DCF	# <CJK>
0x754B	0x8DDB	# <CJK>
0x754C	0x8DC6	# <CJK>
0x754D	0x8DEC	# <CJK>
0x754E	0x8E7A	# <CJK>
0x754F	0x8E55	# <CJK>
0x7550	0x8DE3	# <CJK>
0x7551	0x8E9A	# <CJK>
0x7552	0x8E8B	# <CJK>
0x7553	0x8DE4	# <CJK>
0x7554	0x8E09	# <CJK>
0x7555	0x8DFD	# <CJK>
0x7556	0x8E14	# <CJK>
0x7557	0x8E1D	# <CJK>
0x7558	0x8E1F	# <CJK>
0x7559	0x8E93	# <CJK>
0x755A	0x8E2E	# <CJK>
0x755B	0x8E23	# <CJK>
0x755C	0x8E91	# <CJK>
0x755D	0x8E3A	# <CJK>
0x755E	0x8E40	# <CJK>
0x755F	0x8E39	# <CJK>
0x7560	0x8E35	# <CJK>
0x7561	0x8E3D	# <CJK>
0x7562	0x8E31	# <CJK>
0x7563	0x8E49	# <CJK>
0x7564	0x8E41	# <CJK>
0x7565	0x8E42	# <CJK>
0x7566	0x8EA1	# <CJK>
0x7567	0x8E63	# <CJK>
0x7568	0x8E4A	# <CJK>
0x7569	0x8E70	# <CJK>
0x756A	0x8E76	# <CJK>
0x756B	0x8E7C	# <CJK>
0x756C	0x8E6F	# <CJK>
0x756D	0x8E74	# <CJK>
0x756E	0x8E85	# <CJK>
0x756F	0x8EAA	# <CJK>
0x7570	0x8E94	# <CJK>
0x7571	0x8E90	# <CJK>
0x7572	0x8EA6	# <CJK>
0x7573	0x8E9E	# <CJK>
0x7574	0x8C78	# <CJK>
0x7575	0x8C82	# <CJK>
0x7576	0x8C8A	# <CJK>
0x7577	0x8C85	# <CJK>
0x7578	0x8C98	# <CJK>
0x7579	0x8C94	# <CJK>
0x757A	0x659B	# <CJK>
0x757B	0x89D6	# <CJK>
0x757C	0x89F4	# <CJK>
0x757D	0x89DA	# <CJK>
0x757E	0x89DC	# <CJK>
0x7621	0x89E5	# <CJK>
0x7622	0x89EB	# <CJK>
0x7623	0x89F6	# <CJK>
0x7624	0x8A3E	# <CJK>
0x7625	0x8B26	# <CJK>
0x7626	0x975A	# <CJK>
0x7627	0x96E9	# <CJK>
0x7628	0x9742	# <CJK>
0x7629	0x96EF	# <CJK>
0x762A	0x9706	# <CJK>
0x762B	0x973D	# <CJK>
0x762C	0x9708	# <CJK>
0x762D	0x970F	# <CJK>
0x762E	0x970E	# <CJK>
0x762F	0x972A	# <CJK>
0x7630	0x9744	# <CJK>
0x7631	0x9730	# <CJK>
0x7632	0x973E	# <CJK>
0x7633	0x9F54	# <CJK>
0x7634	0x9F5F	# <CJK>
0x7635	0x9F59	# <CJK>
0x7636	0x9F60	# <CJK>
0x7637	0x9F5C	# <CJK>
0x7638	0x9F66	# <CJK>
0x7639	0x9F6C	# <CJK>
0x763A	0x9F6A	# <CJK>
0x763B	0x9F77	# <CJK>
0x763C	0x9EFD	# <CJK>
0x763D	0x9EFF	# <CJK>
0x763E	0x9F09	# <CJK>
0x763F	0x96B9	# <CJK>
0x7640	0x96BC	# <CJK>
0x7641	0x96BD	# <CJK>
0x7642	0x96CE	# <CJK>
0x7643	0x96D2	# <CJK>
0x7644	0x77BF	# <CJK>
0x7645	0x8B8E	# <CJK>
0x7646	0x928E	# <CJK>
0x7647	0x947E	# <CJK>
0x7648	0x92C8	# <CJK>
0x7649	0x93E8	# <CJK>
0x764A	0x936A	# <CJK>
0x764B	0x93CA	# <CJK>
0x764C	0x938F	# <CJK>
0x764D	0x943E	# <CJK>
0x764E	0x946B	# <CJK>
0x764F	0x9B77	# <CJK>
0x7650	0x9B74	# <CJK>
0x7651	0x9B81	# <CJK>
0x7652	0x9B83	# <CJK>
0x7653	0x9B8E	# <CJK>
0x7654	0x9C78	# <CJK>
0x7655	0x7A4C	# <CJK>
0x7656	0x9B92	# <CJK>
0x7657	0x9C5F	# <CJK>
0x7658	0x9B90	# <CJK>
0x7659	0x9BAD	# <CJK>
0x765A	0x9B9A	# <CJK>
0x765B	0x9BAA	# <CJK>
0x765C	0x9B9E	# <CJK>
0x765D	0x9C6D	# <CJK>
0x765E	0x9BAB	# <CJK>
0x765F	0x9B9D	# <CJK>
0x7660	0x9C58	# <CJK>
0x7661	0x9BC1	# <CJK>
0x7662	0x9C7A	# <CJK>
0x7663	0x9C31	# <CJK>
0x7664	0x9C39	# <CJK>
0x7665	0x9C23	# <CJK>
0x7666	0x9C37	# <CJK>
0x7667	0x9BC0	# <CJK>
0x7668	0x9BCA	# <CJK>
0x7669	0x9BC7	# <CJK>
0x766A	0x9BFD	# <CJK>
0x766B	0x9BD6	# <CJK>
0x766C	0x9BEA	# <CJK>
0x766D	0x9BEB	# <CJK>
0x766E	0x9BE1	# <CJK>
0x766F	0x9BE4	# <CJK>
0x7670	0x9BE7	# <CJK>
0x7671	0x9BDD	# <CJK>
0x7672	0x9BE2	# <CJK>
0x7673	0x9BF0	# <CJK>
0x7674	0x9BDB	# <CJK>
0x7675	0x9BF4	# <CJK>
0x7676	0x9BD4	# <CJK>
0x7677	0x9C5D	# <CJK>
0x7678	0x9C08	# <CJK>
0x7679	0x9C10	# <CJK>
0x767A	0x9C0D	# <CJK>
0x767B	0x9C12	# <CJK>
0x767C	0x9C09	# <CJK>
0x767D	0x9BFF	# <CJK>
0x767E	0x9C20	# <CJK>
0x7721	0x9C32	# <CJK>
0x7722	0x9C2D	# <CJK>
0x7723	0x9C28	# <CJK>
0x7724	0x9C25	# <CJK>
0x7725	0x9C29	# <CJK>
0x7726	0x9C33	# <CJK>
0x7727	0x9C3E	# <CJK>
0x7728	0x9C48	# <CJK>
0x7729	0x9C3B	# <CJK>
0x772A	0x9C35	# <CJK>
0x772B	0x9C45	# <CJK>
0x772C	0x9C56	# <CJK>
0x772D	0x9C54	# <CJK>
0x772E	0x9C52	# <CJK>
0x772F	0x9C67	# <CJK>
0x7730	0x977C	# <CJK>
0x7731	0x9785	# <CJK>
0x7732	0x97C3	# <CJK>
0x7733	0x97BD	# <CJK>
0x7734	0x9794	# <CJK>
0x7735	0x97C9	# <CJK>
0x7736	0x97AB	# <CJK>
0x7737	0x97A3	# <CJK>
0x7738	0x97B2	# <CJK>
0x7739	0x97B4	# <CJK>
0x773A	0x9AB1	# <CJK>
0x773B	0x9AB0	# <CJK>
0x773C	0x9AB7	# <CJK>
0x773D	0x9DBB	# <CJK>
0x773E	0x9AB6	# <CJK>
0x773F	0x9ABA	# <CJK>
0x7740	0x9ABC	# <CJK>
0x7741	0x9AC1	# <CJK>
0x7742	0x9AC0	# <CJK>
0x7743	0x9ACF	# <CJK>
0x7744	0x9AC2	# <CJK>
0x7745	0x9AD6	# <CJK>
0x7746	0x9AD5	# <CJK>
0x7747	0x9AD1	# <CJK>
0x7748	0x9B45	# <CJK>
0x7749	0x9B43	# <CJK>
0x774A	0x9B58	# <CJK>
0x774B	0x9B4E	# <CJK>
0x774C	0x9B48	# <CJK>
0x774D	0x9B4D	# <CJK>
0x774E	0x9B51	# <CJK>
0x774F	0x9957	# <CJK>
0x7750	0x995C	# <CJK>
0x7751	0x992E	# <CJK>
0x7752	0x9955	# <CJK>
0x7753	0x9954	# <CJK>
0x7754	0x9ADF	# <CJK>
0x7755	0x9AE1	# <CJK>
0x7756	0x9AE6	# <CJK>
0x7757	0x9AEF	# <CJK>
0x7758	0x9AEB	# <CJK>
0x7759	0x9AFB	# <CJK>
0x775A	0x9AED	# <CJK>
0x775B	0x9AF9	# <CJK>
0x775C	0x9B08	# <CJK>
0x775D	0x9B0F	# <CJK>
0x775E	0x9B22	# <CJK>
0x775F	0x9B1F	# <CJK>
0x7760	0x9B23	# <CJK>
0x7761	0x4E48	# <CJK>
0x7762	0x9EBE	# <CJK>
0x7763	0x7E3B	# <CJK>
0x7764	0x9E82	# <CJK>
0x7765	0x9E87	# <CJK>
0x7766	0x9E88	# <CJK>
0x7767	0x9E8B	# <CJK>
0x7768	0x9E92	# <CJK>
0x7769	0x93D6	# <CJK>
0x776A	0x9E9D	# <CJK>
0x776B	0x9E9F	# <CJK>
0x776C	0x9EDB	# <CJK>
0x776D	0x9EDC	# <CJK>
0x776E	0x9EDD	# <CJK>
0x776F	0x9EE0	# <CJK>
0x7770	0x9EDF	# <CJK>
0x7771	0x9EE2	# <CJK>
0x7772	0x9EF7	# <CJK>
0x7773	0x9EE7	# <CJK>
0x7774	0x9EE5	# <CJK>
0x7775	0x9EF2	# <CJK>
0x7776	0x9EEF	# <CJK>
0x7777	0x9F22	# <CJK>
0x7778	0x9F2C	# <CJK>
0x7779	0x9F2F	# <CJK>
0x777A	0x9F39	# <CJK>
0x777B	0x9F37	# <CJK>
0x777C	0x9F3D	# <CJK>
0x777D	0x9F3E	# <CJK>
0x777E	0x9F44	# <CJK>
0x7821	0x896C	# <CJK>
0x7822	0x95C6	# <CJK>
0x7823	0x9336	# <CJK>
0x7824	0x5F46	# <CJK>
0x7825	0x8514	# <CJK>
0x7826	0x7E94	# <CJK>
0x7827	0x5382	# <CJK>
0x7828	0x51B2	# <CJK>
0x7829	0x4E11	# <CJK>
0x782A	0x9F63	# <CJK>
0x782B	0x5679	# <CJK>
0x782C	0x515A	# <CJK>
0x782D	0x6DC0	# <CJK>
0x782E	0x9F15	# <CJK>
0x782F	0x6597	# <CJK>
0x7830	0x5641	# <CJK>
0x7831	0x9AEE	# <CJK>
0x7832	0x8303	# <CJK>
0x7833	0x4E30	# <CJK>
0x7834	0x8907	# <CJK>
0x7835	0x5E72	# <CJK>
0x7836	0x7A40	# <CJK>
0x7837	0x98B3	# <CJK>
0x7838	0x5E7F	# <CJK>
0x7839	0x95A4	# <CJK>
0x783A	0x9B0D	# <CJK>
0x783B	0x5212	# <CJK>
0x783C	0x8FF4	# <CJK>
0x783D	0x5F59	# <CJK>
0x783E	0x7A6B	# <CJK>
0x783F	0x98E2	# <CJK>
0x7840	0x51E0	# <CJK>
0x7841	0x50A2	# <CJK>
0x7842	0x4EF7	# <CJK>
0x7843	0x8350	# <CJK>
0x7844	0x8591	# <CJK>
0x7845	0x5118	# <CJK>
0x7846	0x636E	# <CJK>
0x7847	0x6372	# <CJK>
0x7848	0x524B	# <CJK>
0x7849	0x5938	# <CJK>
0x784A	0x774F	# <CJK>
0x784B	0x8721	# <CJK>
0x784C	0x814A	# <CJK>
0x784D	0x7E8D	# <CJK>
0x784E	0x91CC	# <CJK>
0x784F	0x66C6	# <CJK>
0x7850	0x5E18	# <CJK>
0x7851	0x77AD	# <CJK>
0x7852	0x9E75	# <CJK>
0x7853	0x56C9	# <CJK>
0x7854	0x9EF4	# <CJK>
0x7855	0x6FDB	# <CJK>
0x7856	0x61DE	# <CJK>
0x7857	0x77C7	# <CJK>
0x7858	0x7030	# <CJK>
0x7859	0x9EB5	# <CJK>
0x785A	0x884A	# <CJK>
0x785B	0x95E2	# <CJK>
0x785C	0x82F9	# <CJK>
0x785D	0x51ED	# <CJK>
0x785E	0x6251	# <CJK>
0x785F	0x4EC6	# <CJK>
0x7860	0x6734	# <CJK>
0x7861	0x97C6	# <CJK>
0x7862	0x7C64	# <CJK>
0x7863	0x7E34	# <CJK>
0x7864	0x97A6	# <CJK>
0x7865	0x9EAF	# <CJK>
0x7866	0x786E	# <CJK>
0x7867	0x820D	# <CJK>
0x7868	0x672F	# <CJK>
0x7869	0x677E	# <CJK>
0x786A	0x56CC	# <CJK>
0x786B	0x53F0	# <CJK>
0x786C	0x98B1	# <CJK>
0x786D	0x6AAF	# <CJK>
0x786E	0x7F4E	# <CJK>
0x786F	0x6D82	# <CJK>
0x7870	0x7CF0	# <CJK>
0x7871	0x4E07	# <CJK>
0x7872	0x4FC2	# <CJK>
0x7873	0x7E6B	# <CJK>
0x7874	0x9E79	# <CJK>
0x7875	0x56AE	# <CJK>
0x7876	0x9B1A	# <CJK>
0x7877	0x846F	# <CJK>
0x7878	0x53F6	# <CJK>
0x7879	0x90C1	# <CJK>
0x787A	0x79A6	# <CJK>
0x787B	0x7C72	# <CJK>
0x787C	0x613F	# <CJK>
0x787D	0x4E91	# <CJK>
0x787E	0x9AD2	# <CJK>
0x7921	0x75C7	# <CJK>
0x7922	0x96BB	# <CJK>
0x7923	0x53EA	# <CJK>
0x7924	0x7DFB	# <CJK>
0x7925	0x88FD	# <CJK>
0x7926	0x79CD	# <CJK>
0x7927	0x7843	# <CJK>
0x7928	0x7B51	# <CJK>
0x7929	0x51C6	# <CJK>

Added tools/encoding/gb1988.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
0x20	0x0020	# SPACE
0x21	0x0021	# EXCLAMATION MARK
0x22	0x0022	# QUOTATION MARK
0x23	0x0023	# NUMBER SIGN
0x24	0x00A5	# YUAN 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 (rendered as Halfwidth Yen Sign)
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	0x203E	# OVERLINE
0xA1	0xFF61	# HALFWIDTH IDEOGRAPHIC FULL STOP
0xA2	0xFF62	# HALFWIDTH LEFT CORNER BRACKET
0xA3	0xFF63	# HALFWIDTH RIGHT CORNER BRACKET
0xA4	0xFF64	# HALFWIDTH IDEOGRAPHIC COMMA
0xA5	0xFF65	# HALFWIDTH KATAKANA MIDDLE DOT
0xA6	0xFF66	# HALFWIDTH KATAKANA LETTER WO
0xA7	0xFF67	# HALFWIDTH KATAKANA LETTER SMALL A
0xA8	0xFF68	# HALFWIDTH KATAKANA LETTER SMALL I
0xA9	0xFF69	# HALFWIDTH KATAKANA LETTER SMALL U
0xAA	0xFF6A	# HALFWIDTH KATAKANA LETTER SMALL E
0xAB	0xFF6B	# HALFWIDTH KATAKANA LETTER SMALL O
0xAC	0xFF6C	# HALFWIDTH KATAKANA LETTER SMALL YA
0xAD	0xFF6D	# HALFWIDTH KATAKANA LETTER SMALL YU
0xAE	0xFF6E	# HALFWIDTH KATAKANA LETTER SMALL YO
0xAF	0xFF6F	# HALFWIDTH KATAKANA LETTER SMALL TU
0xB0	0xFF70	# HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
0xB1	0xFF71	# HALFWIDTH KATAKANA LETTER A
0xB2	0xFF72	# HALFWIDTH KATAKANA LETTER I
0xB3	0xFF73	# HALFWIDTH KATAKANA LETTER U
0xB4	0xFF74	# HALFWIDTH KATAKANA LETTER E
0xB5	0xFF75	# HALFWIDTH KATAKANA LETTER O
0xB6	0xFF76	# HALFWIDTH KATAKANA LETTER KA
0xB7	0xFF77	# HALFWIDTH KATAKANA LETTER KI
0xB8	0xFF78	# HALFWIDTH KATAKANA LETTER KU
0xB9	0xFF79	# HALFWIDTH KATAKANA LETTER KE
0xBA	0xFF7A	# HALFWIDTH KATAKANA LETTER KO
0xBB	0xFF7B	# HALFWIDTH KATAKANA LETTER SA
0xBC	0xFF7C	# HALFWIDTH KATAKANA LETTER SI
0xBD	0xFF7D	# HALFWIDTH KATAKANA LETTER SU
0xBE	0xFF7E	# HALFWIDTH KATAKANA LETTER SE
0xBF	0xFF7F	# HALFWIDTH KATAKANA LETTER SO
0xC0	0xFF80	# HALFWIDTH KATAKANA LETTER TA
0xC1	0xFF81	# HALFWIDTH KATAKANA LETTER TI
0xC2	0xFF82	# HALFWIDTH KATAKANA LETTER TU
0xC3	0xFF83	# HALFWIDTH KATAKANA LETTER TE
0xC4	0xFF84	# HALFWIDTH KATAKANA LETTER TO
0xC5	0xFF85	# HALFWIDTH KATAKANA LETTER NA
0xC6	0xFF86	# HALFWIDTH KATAKANA LETTER NI
0xC7	0xFF87	# HALFWIDTH KATAKANA LETTER NU
0xC8	0xFF88	# HALFWIDTH KATAKANA LETTER NE
0xC9	0xFF89	# HALFWIDTH KATAKANA LETTER NO
0xCA	0xFF8A	# HALFWIDTH KATAKANA LETTER HA
0xCB	0xFF8B	# HALFWIDTH KATAKANA LETTER HI
0xCC	0xFF8C	# HALFWIDTH KATAKANA LETTER HU
0xCD	0xFF8D	# HALFWIDTH KATAKANA LETTER HE
0xCE	0xFF8E	# HALFWIDTH KATAKANA LETTER HO
0xCF	0xFF8F	# HALFWIDTH KATAKANA LETTER MA
0xD0	0xFF90	# HALFWIDTH KATAKANA LETTER MI
0xD1	0xFF91	# HALFWIDTH KATAKANA LETTER MU
0xD2	0xFF92	# HALFWIDTH KATAKANA LETTER ME
0xD3	0xFF93	# HALFWIDTH KATAKANA LETTER MO
0xD4	0xFF94	# HALFWIDTH KATAKANA LETTER YA
0xD5	0xFF95	# HALFWIDTH KATAKANA LETTER YU
0xD6	0xFF96	# HALFWIDTH KATAKANA LETTER YO
0xD7	0xFF97	# HALFWIDTH KATAKANA LETTER RA
0xD8	0xFF98	# HALFWIDTH KATAKANA LETTER RI
0xD9	0xFF99	# HALFWIDTH KATAKANA LETTER RU
0xDA	0xFF9A	# HALFWIDTH KATAKANA LETTER RE
0xDB	0xFF9B	# HALFWIDTH KATAKANA LETTER RO
0xDC	0xFF9C	# HALFWIDTH KATAKANA LETTER WA
0xDD	0xFF9D	# HALFWIDTH KATAKANA LETTER N
0xDE	0xFF9E	# HALFWIDTH KATAKANA VOICED SOUND MARK
0xDF	0xFF9F	# HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK

Added tools/encoding/gb2312.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
# gb2312.txt --
#
#	GB2312 to Unicode table (modified)
#
# 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: gb2312.txt,v 1.1.2.3 1999/04/13 18:29:06 stanton Exp $
#
# NOTE: this table has been modified to include the 7-bit ASCII
# characters that are allowed in GB2312 files.
#
#
#	Name:             GB2312-80 to Unicode table (complete, hex format)
#	Unicode version:  1.1
#	Table version:    0.0d2
#	Table format:     Format A
#	Date:             6 December 1993
#	Author:           Glenn Adams <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data Metis and Taligent currently have on how
#       GB2312-80 characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the GB2312 code (in hex as 0xXXXX)
#		 Column #2 is the Unicode (in hex as 0xXXXX)
#		 Column #3 the Unicode name (follows a comment sign, '#')
#					The official names for Unicode characters U+4E00
#					to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
#					where XXXX is the code point.  Including all these
#					names in this file increases its size substantially
#					and needlessly.  The token "<CJK>" is used for the
#					name of these characters.  If necessary, it can be
#					expanded algorithmically by a parser or editor.
#
#	The entries are in GB2312 order
#
#	The following algorithms can be used to change the hex form
#		of GB2312 to other standard forms:
#
#		To change hex to EUC form, add 0x8080
#		To change hex to kuten form, first subtract 0x2020.  Then
#			the high and low bytes correspond to the ku and ten of
#			the kuten form.  For example, 0x2121 -> 0x0101 -> 0101;
#			0x777E -> 0x575E -> 8794
#
#	Any comments or problems, contact <[email protected]>
#
#
0x2121	0x3000	# IDEOGRAPHIC SPACE
0x2122	0x3001	# IDEOGRAPHIC COMMA
0x2123	0x3002	# IDEOGRAPHIC FULL STOP
0x2124	0x30FB	# KATAKANA MIDDLE DOT
0x2125	0x02C9	# MODIFIER LETTER MACRON (Mandarin Chinese first tone)
0x2126	0x02C7	# CARON (Mandarin Chinese third tone)
0x2127	0x00A8	# DIAERESIS
0x2128	0x3003	# DITTO MARK
0x2129	0x3005	# IDEOGRAPHIC ITERATION MARK
0x212A	0x2015	# HORIZONTAL BAR
0x212B	0xFF5E	# FULLWIDTH TILDE
0x212C	0x2225	# PARALLEL TO
0x212D	0x2026	# HORIZONTAL ELLIPSIS
0x212E	0x2018	# LEFT SINGLE QUOTATION MARK
0x212F	0x2019	# RIGHT SINGLE QUOTATION MARK
0x2130	0x201C	# LEFT DOUBLE QUOTATION MARK
0x2131	0x201D	# RIGHT DOUBLE QUOTATION MARK
0x2132	0x3014	# LEFT TORTOISE SHELL BRACKET
0x2133	0x3015	# RIGHT TORTOISE SHELL BRACKET
0x2134	0x3008	# LEFT ANGLE BRACKET
0x2135	0x3009	# RIGHT ANGLE BRACKET
0x2136	0x300A	# LEFT DOUBLE ANGLE BRACKET
0x2137	0x300B	# RIGHT DOUBLE ANGLE BRACKET
0x2138	0x300C	# LEFT CORNER BRACKET
0x2139	0x300D	# RIGHT CORNER BRACKET
0x213A	0x300E	# LEFT WHITE CORNER BRACKET
0x213B	0x300F	# RIGHT WHITE CORNER BRACKET
0x213C	0x3016	# LEFT WHITE LENTICULAR BRACKET
0x213D	0x3017	# RIGHT WHITE LENTICULAR BRACKET
0x213E	0x3010	# LEFT BLACK LENTICULAR BRACKET
0x213F	0x3011	# RIGHT BLACK LENTICULAR BRACKET
0x2140	0x00B1	# PLUS-MINUS SIGN
0x2141	0x00D7	# MULTIPLICATION SIGN
0x2142	0x00F7	# DIVISION SIGN
0x2143	0x2236	# RATIO
0x2144	0x2227	# LOGICAL AND
0x2145	0x2228	# LOGICAL OR
0x2146	0x2211	# N-ARY SUMMATION
0x2147	0x220F	# N-ARY PRODUCT
0x2148	0x222A	# UNION
0x2149	0x2229	# INTERSECTION
0x214A	0x2208	# ELEMENT OF
0x214B	0x2237	# PROPORTION
0x214C	0x221A	# SQUARE ROOT
0x214D	0x22A5	# UP TACK
0x214E	0x2225	# PARALLEL TO
0x214F	0x2220	# ANGLE
0x2150	0x2312	# ARC
0x2151	0x2299	# CIRCLED DOT OPERATOR
0x2152	0x222B	# INTEGRAL
0x2153	0x222E	# CONTOUR INTEGRAL
0x2154	0x2261	# IDENTICAL TO
0x2155	0x224C	# ALL EQUAL TO
0x2156	0x2248	# ALMOST EQUAL TO
0x2157	0x223D	# REVERSED TILDE
0x2158	0x221D	# PROPORTIONAL TO
0x2159	0x2260	# NOT EQUAL TO
0x215A	0x226E	# NOT LESS-THAN
0x215B	0x226F	# NOT GREATER-THAN
0x215C	0x2264	# LESS-THAN OR EQUAL TO
0x215D	0x2265	# GREATER-THAN OR EQUAL TO
0x215E	0x221E	# INFINITY
0x215F	0x2235	# BECAUSE
0x2160	0x2234	# THEREFORE
0x2161	0x2642	# MALE SIGN
0x2162	0x2640	# FEMALE SIGN
0x2163	0x00B0	# DEGREE SIGN
0x2164	0x2032	# PRIME
0x2165	0x2033	# DOUBLE PRIME
0x2166	0x2103	# DEGREE CELSIUS
0x2167	0xFF04	# FULLWIDTH DOLLAR SIGN
0x2168	0x00A4	# CURRENCY SIGN
0x2169	0xFFE0	# FULLWIDTH CENT SIGN
0x216A	0xFFE1	# FULLWIDTH POUND SIGN
0x216B	0x2030	# PER MILLE SIGN
0x216C	0x00A7	# SECTION SIGN
0x216D	0x2116	# NUMERO SIGN
0x216E	0x2606	# WHITE STAR
0x216F	0x2605	# BLACK STAR
0x2170	0x25CB	# WHITE CIRCLE
0x2171	0x25CF	# BLACK CIRCLE
0x2172	0x25CE	# BULLSEYE
0x2173	0x25C7	# WHITE DIAMOND
0x2174	0x25C6	# BLACK DIAMOND
0x2175	0x25A1	# WHITE SQUARE
0x2176	0x25A0	# BLACK SQUARE
0x2177	0x25B3	# WHITE UP-POINTING TRIANGLE
0x2178	0x25B2	# BLACK UP-POINTING TRIANGLE
0x2179	0x203B	# REFERENCE MARK
0x217A	0x2192	# RIGHTWARDS ARROW
0x217B	0x2190	# LEFTWARDS ARROW
0x217C	0x2191	# UPWARDS ARROW
0x217D	0x2193	# DOWNWARDS ARROW
0x217E	0x3013	# GETA MARK
0x2231	0x2488	# DIGIT ONE FULL STOP
0x2232	0x2489	# DIGIT TWO FULL STOP
0x2233	0x248A	# DIGIT THREE FULL STOP
0x2234	0x248B	# DIGIT FOUR FULL STOP
0x2235	0x248C	# DIGIT FIVE FULL STOP
0x2236	0x248D	# DIGIT SIX FULL STOP
0x2237	0x248E	# DIGIT SEVEN FULL STOP
0x2238	0x248F	# DIGIT EIGHT FULL STOP
0x2239	0x2490	# DIGIT NINE FULL STOP
0x223A	0x2491	# NUMBER TEN FULL STOP
0x223B	0x2492	# NUMBER ELEVEN FULL STOP
0x223C	0x2493	# NUMBER TWELVE FULL STOP
0x223D	0x2494	# NUMBER THIRTEEN FULL STOP
0x223E	0x2495	# NUMBER FOURTEEN FULL STOP
0x223F	0x2496	# NUMBER FIFTEEN FULL STOP
0x2240	0x2497	# NUMBER SIXTEEN FULL STOP
0x2241	0x2498	# NUMBER SEVENTEEN FULL STOP
0x2242	0x2499	# NUMBER EIGHTEEN FULL STOP
0x2243	0x249A	# NUMBER NINETEEN FULL STOP
0x2244	0x249B	# NUMBER TWENTY FULL STOP
0x2245	0x2474	# PARENTHESIZED DIGIT ONE
0x2246	0x2475	# PARENTHESIZED DIGIT TWO
0x2247	0x2476	# PARENTHESIZED DIGIT THREE
0x2248	0x2477	# PARENTHESIZED DIGIT FOUR
0x2249	0x2478	# PARENTHESIZED DIGIT FIVE
0x224A	0x2479	# PARENTHESIZED DIGIT SIX
0x224B	0x247A	# PARENTHESIZED DIGIT SEVEN
0x224C	0x247B	# PARENTHESIZED DIGIT EIGHT
0x224D	0x247C	# PARENTHESIZED DIGIT NINE
0x224E	0x247D	# PARENTHESIZED NUMBER TEN
0x224F	0x247E	# PARENTHESIZED NUMBER ELEVEN
0x2250	0x247F	# PARENTHESIZED NUMBER TWELVE
0x2251	0x2480	# PARENTHESIZED NUMBER THIRTEEN
0x2252	0x2481	# PARENTHESIZED NUMBER FOURTEEN
0x2253	0x2482	# PARENTHESIZED NUMBER FIFTEEN
0x2254	0x2483	# PARENTHESIZED NUMBER SIXTEEN
0x2255	0x2484	# PARENTHESIZED NUMBER SEVENTEEN
0x2256	0x2485	# PARENTHESIZED NUMBER EIGHTEEN
0x2257	0x2486	# PARENTHESIZED NUMBER NINETEEN
0x2258	0x2487	# PARENTHESIZED NUMBER TWENTY
0x2259	0x2460	# CIRCLED DIGIT ONE
0x225A	0x2461	# CIRCLED DIGIT TWO
0x225B	0x2462	# CIRCLED DIGIT THREE
0x225C	0x2463	# CIRCLED DIGIT FOUR
0x225D	0x2464	# CIRCLED DIGIT FIVE
0x225E	0x2465	# CIRCLED DIGIT SIX
0x225F	0x2466	# CIRCLED DIGIT SEVEN
0x2260	0x2467	# CIRCLED DIGIT EIGHT
0x2261	0x2468	# CIRCLED DIGIT NINE
0x2262	0x2469	# CIRCLED NUMBER TEN
0x2265	0x3220	# PARENTHESIZED IDEOGRAPH ONE
0x2266	0x3221	# PARENTHESIZED IDEOGRAPH TWO
0x2267	0x3222	# PARENTHESIZED IDEOGRAPH THREE
0x2268	0x3223	# PARENTHESIZED IDEOGRAPH FOUR
0x2269	0x3224	# PARENTHESIZED IDEOGRAPH FIVE
0x226A	0x3225	# PARENTHESIZED IDEOGRAPH SIX
0x226B	0x3226	# PARENTHESIZED IDEOGRAPH SEVEN
0x226C	0x3227	# PARENTHESIZED IDEOGRAPH EIGHT
0x226D	0x3228	# PARENTHESIZED IDEOGRAPH NINE
0x226E	0x3229	# PARENTHESIZED IDEOGRAPH TEN
0x2271	0x2160	# ROMAN NUMERAL ONE
0x2272	0x2161	# ROMAN NUMERAL TWO
0x2273	0x2162	# ROMAN NUMERAL THREE
0x2274	0x2163	# ROMAN NUMERAL FOUR
0x2275	0x2164	# ROMAN NUMERAL FIVE
0x2276	0x2165	# ROMAN NUMERAL SIX
0x2277	0x2166	# ROMAN NUMERAL SEVEN
0x2278	0x2167	# ROMAN NUMERAL EIGHT
0x2279	0x2168	# ROMAN NUMERAL NINE
0x227A	0x2169	# ROMAN NUMERAL TEN
0x227B	0x216A	# ROMAN NUMERAL ELEVEN
0x227C	0x216B	# ROMAN NUMERAL TWELVE
0x2321	0xFF01	# FULLWIDTH EXCLAMATION MARK
0x2322	0xFF02	# FULLWIDTH QUOTATION MARK
0x2323	0xFF03	# FULLWIDTH NUMBER SIGN
0x2324	0xFFE5	# FULLWIDTH YEN SIGN
0x2325	0xFF05	# FULLWIDTH PERCENT SIGN
0x2326	0xFF06	# FULLWIDTH AMPERSAND
0x2327	0xFF07	# FULLWIDTH APOSTROPHE
0x2328	0xFF08	# FULLWIDTH LEFT PARENTHESIS
0x2329	0xFF09	# FULLWIDTH RIGHT PARENTHESIS
0x232A	0xFF0A	# FULLWIDTH ASTERISK
0x232B	0xFF0B	# FULLWIDTH PLUS SIGN
0x232C	0xFF0C	# FULLWIDTH COMMA
0x232D	0xFF0D	# FULLWIDTH HYPHEN-MINUS
0x232E	0xFF0E	# FULLWIDTH FULL STOP
0x232F	0xFF0F	# FULLWIDTH SOLIDUS
0x2330	0xFF10	# FULLWIDTH DIGIT ZERO
0x2331	0xFF11	# FULLWIDTH DIGIT ONE
0x2332	0xFF12	# FULLWIDTH DIGIT TWO
0x2333	0xFF13	# FULLWIDTH DIGIT THREE
0x2334	0xFF14	# FULLWIDTH DIGIT FOUR
0x2335	0xFF15	# FULLWIDTH DIGIT FIVE
0x2336	0xFF16	# FULLWIDTH DIGIT SIX
0x2337	0xFF17	# FULLWIDTH DIGIT SEVEN
0x2338	0xFF18	# FULLWIDTH DIGIT EIGHT
0x2339	0xFF19	# FULLWIDTH DIGIT NINE
0x233A	0xFF1A	# FULLWIDTH COLON
0x233B	0xFF1B	# FULLWIDTH SEMICOLON
0x233C	0xFF1C	# FULLWIDTH LESS-THAN SIGN
0x233D	0xFF1D	# FULLWIDTH EQUALS SIGN
0x233E	0xFF1E	# FULLWIDTH GREATER-THAN SIGN
0x233F	0xFF1F	# FULLWIDTH QUESTION MARK
0x2340	0xFF20	# FULLWIDTH COMMERCIAL AT
0x2341	0xFF21	# FULLWIDTH LATIN CAPITAL LETTER A
0x2342	0xFF22	# FULLWIDTH LATIN CAPITAL LETTER B
0x2343	0xFF23	# FULLWIDTH LATIN CAPITAL LETTER C
0x2344	0xFF24	# FULLWIDTH LATIN CAPITAL LETTER D
0x2345	0xFF25	# FULLWIDTH LATIN CAPITAL LETTER E
0x2346	0xFF26	# FULLWIDTH LATIN CAPITAL LETTER F
0x2347	0xFF27	# FULLWIDTH LATIN CAPITAL LETTER G
0x2348	0xFF28	# FULLWIDTH LATIN CAPITAL LETTER H
0x2349	0xFF29	# FULLWIDTH LATIN CAPITAL LETTER I
0x234A	0xFF2A	# FULLWIDTH LATIN CAPITAL LETTER J
0x234B	0xFF2B	# FULLWIDTH LATIN CAPITAL LETTER K
0x234C	0xFF2C	# FULLWIDTH LATIN CAPITAL LETTER L
0x234D	0xFF2D	# FULLWIDTH LATIN CAPITAL LETTER M
0x234E	0xFF2E	# FULLWIDTH LATIN CAPITAL LETTER N
0x234F	0xFF2F	# FULLWIDTH LATIN CAPITAL LETTER O
0x2350	0xFF30	# FULLWIDTH LATIN CAPITAL LETTER P
0x2351	0xFF31	# FULLWIDTH LATIN CAPITAL LETTER Q
0x2352	0xFF32	# FULLWIDTH LATIN CAPITAL LETTER R
0x2353	0xFF33	# FULLWIDTH LATIN CAPITAL LETTER S
0x2354	0xFF34	# FULLWIDTH LATIN CAPITAL LETTER T
0x2355	0xFF35	# FULLWIDTH LATIN CAPITAL LETTER U
0x2356	0xFF36	# FULLWIDTH LATIN CAPITAL LETTER V
0x2357	0xFF37	# FULLWIDTH LATIN CAPITAL LETTER W
0x2358	0xFF38	# FULLWIDTH LATIN CAPITAL LETTER X
0x2359	0xFF39	# FULLWIDTH LATIN CAPITAL LETTER Y
0x235A	0xFF3A	# FULLWIDTH LATIN CAPITAL LETTER Z
0x235B	0xFF3B	# FULLWIDTH LEFT SQUARE BRACKET
0x235C	0xFF3C	# FULLWIDTH REVERSE SOLIDUS
0x235D	0xFF3D	# FULLWIDTH RIGHT SQUARE BRACKET
0x235E	0xFF3E	# FULLWIDTH CIRCUMFLEX ACCENT
0x235F	0xFF3F	# FULLWIDTH LOW LINE
0x2360	0xFF40	# FULLWIDTH GRAVE ACCENT
0x2361	0xFF41	# FULLWIDTH LATIN SMALL LETTER A
0x2362	0xFF42	# FULLWIDTH LATIN SMALL LETTER B
0x2363	0xFF43	# FULLWIDTH LATIN SMALL LETTER C
0x2364	0xFF44	# FULLWIDTH LATIN SMALL LETTER D
0x2365	0xFF45	# FULLWIDTH LATIN SMALL LETTER E
0x2366	0xFF46	# FULLWIDTH LATIN SMALL LETTER F
0x2367	0xFF47	# FULLWIDTH LATIN SMALL LETTER G
0x2368	0xFF48	# FULLWIDTH LATIN SMALL LETTER H
0x2369	0xFF49	# FULLWIDTH LATIN SMALL LETTER I
0x236A	0xFF4A	# FULLWIDTH LATIN SMALL LETTER J
0x236B	0xFF4B	# FULLWIDTH LATIN SMALL LETTER K
0x236C	0xFF4C	# FULLWIDTH LATIN SMALL LETTER L
0x236D	0xFF4D	# FULLWIDTH LATIN SMALL LETTER M
0x236E	0xFF4E	# FULLWIDTH LATIN SMALL LETTER N
0x236F	0xFF4F	# FULLWIDTH LATIN SMALL LETTER O
0x2370	0xFF50	# FULLWIDTH LATIN SMALL LETTER P
0x2371	0xFF51	# FULLWIDTH LATIN SMALL LETTER Q
0x2372	0xFF52	# FULLWIDTH LATIN SMALL LETTER R
0x2373	0xFF53	# FULLWIDTH LATIN SMALL LETTER S
0x2374	0xFF54	# FULLWIDTH LATIN SMALL LETTER T
0x2375	0xFF55	# FULLWIDTH LATIN SMALL LETTER U
0x2376	0xFF56	# FULLWIDTH LATIN SMALL LETTER V
0x2377	0xFF57	# FULLWIDTH LATIN SMALL LETTER W
0x2378	0xFF58	# FULLWIDTH LATIN SMALL LETTER X
0x2379	0xFF59	# FULLWIDTH LATIN SMALL LETTER Y
0x237A	0xFF5A	# FULLWIDTH LATIN SMALL LETTER Z
0x237B	0xFF5B	# FULLWIDTH LEFT CURLY BRACKET
0x237C	0xFF5C	# FULLWIDTH VERTICAL LINE
0x237D	0xFF5D	# FULLWIDTH RIGHT CURLY BRACKET
0x237E	0xFFE3	# FULLWIDTH MACRON
0x2421	0x3041	# HIRAGANA LETTER SMALL A
0x2422	0x3042	# HIRAGANA LETTER A
0x2423	0x3043	# HIRAGANA LETTER SMALL I
0x2424	0x3044	# HIRAGANA LETTER I
0x2425	0x3045	# HIRAGANA LETTER SMALL U
0x2426	0x3046	# HIRAGANA LETTER U
0x2427	0x3047	# HIRAGANA LETTER SMALL E
0x2428	0x3048	# HIRAGANA LETTER E
0x2429	0x3049	# HIRAGANA LETTER SMALL O
0x242A	0x304A	# HIRAGANA LETTER O
0x242B	0x304B	# HIRAGANA LETTER KA
0x242C	0x304C	# HIRAGANA LETTER GA
0x242D	0x304D	# HIRAGANA LETTER KI
0x242E	0x304E	# HIRAGANA LETTER GI
0x242F	0x304F	# HIRAGANA LETTER KU
0x2430	0x3050	# HIRAGANA LETTER GU
0x2431	0x3051	# HIRAGANA LETTER KE
0x2432	0x3052	# HIRAGANA LETTER GE
0x2433	0x3053	# HIRAGANA LETTER KO
0x2434	0x3054	# HIRAGANA LETTER GO
0x2435	0x3055	# HIRAGANA LETTER SA
0x2436	0x3056	# HIRAGANA LETTER ZA
0x2437	0x3057	# HIRAGANA LETTER SI
0x2438	0x3058	# HIRAGANA LETTER ZI
0x2439	0x3059	# HIRAGANA LETTER SU
0x243A	0x305A	# HIRAGANA LETTER ZU
0x243B	0x305B	# HIRAGANA LETTER SE
0x243C	0x305C	# HIRAGANA LETTER ZE
0x243D	0x305D	# HIRAGANA LETTER SO
0x243E	0x305E	# HIRAGANA LETTER ZO
0x243F	0x305F	# HIRAGANA LETTER TA
0x2440	0x3060	# HIRAGANA LETTER DA
0x2441	0x3061	# HIRAGANA LETTER TI
0x2442	0x3062	# HIRAGANA LETTER DI
0x2443	0x3063	# HIRAGANA LETTER SMALL TU
0x2444	0x3064	# HIRAGANA LETTER TU
0x2445	0x3065	# HIRAGANA LETTER DU
0x2446	0x3066	# HIRAGANA LETTER TE
0x2447	0x3067	# HIRAGANA LETTER DE
0x2448	0x3068	# HIRAGANA LETTER TO
0x2449	0x3069	# HIRAGANA LETTER DO
0x244A	0x306A	# HIRAGANA LETTER NA
0x244B	0x306B	# HIRAGANA LETTER NI
0x244C	0x306C	# HIRAGANA LETTER NU
0x244D	0x306D	# HIRAGANA LETTER NE
0x244E	0x306E	# HIRAGANA LETTER NO
0x244F	0x306F	# HIRAGANA LETTER HA
0x2450	0x3070	# HIRAGANA LETTER BA
0x2451	0x3071	# HIRAGANA LETTER PA
0x2452	0x3072	# HIRAGANA LETTER HI
0x2453	0x3073	# HIRAGANA LETTER BI
0x2454	0x3074	# HIRAGANA LETTER PI
0x2455	0x3075	# HIRAGANA LETTER HU
0x2456	0x3076	# HIRAGANA LETTER BU
0x2457	0x3077	# HIRAGANA LETTER PU
0x2458	0x3078	# HIRAGANA LETTER HE
0x2459	0x3079	# HIRAGANA LETTER BE
0x245A	0x307A	# HIRAGANA LETTER PE
0x245B	0x307B	# HIRAGANA LETTER HO
0x245C	0x307C	# HIRAGANA LETTER BO
0x245D	0x307D	# HIRAGANA LETTER PO
0x245E	0x307E	# HIRAGANA LETTER MA
0x245F	0x307F	# HIRAGANA LETTER MI
0x2460	0x3080	# HIRAGANA LETTER MU
0x2461	0x3081	# HIRAGANA LETTER ME
0x2462	0x3082	# HIRAGANA LETTER MO
0x2463	0x3083	# HIRAGANA LETTER SMALL YA
0x2464	0x3084	# HIRAGANA LETTER YA
0x2465	0x3085	# HIRAGANA LETTER SMALL YU
0x2466	0x3086	# HIRAGANA LETTER YU
0x2467	0x3087	# HIRAGANA LETTER SMALL YO
0x2468	0x3088	# HIRAGANA LETTER YO
0x2469	0x3089	# HIRAGANA LETTER RA
0x246A	0x308A	# HIRAGANA LETTER RI
0x246B	0x308B	# HIRAGANA LETTER RU
0x246C	0x308C	# HIRAGANA LETTER RE
0x246D	0x308D	# HIRAGANA LETTER RO
0x246E	0x308E	# HIRAGANA LETTER SMALL WA
0x246F	0x308F	# HIRAGANA LETTER WA
0x2470	0x3090	# HIRAGANA LETTER WI
0x2471	0x3091	# HIRAGANA LETTER WE
0x2472	0x3092	# HIRAGANA LETTER WO
0x2473	0x3093	# HIRAGANA LETTER N
0x2521	0x30A1	# KATAKANA LETTER SMALL A
0x2522	0x30A2	# KATAKANA LETTER A
0x2523	0x30A3	# KATAKANA LETTER SMALL I
0x2524	0x30A4	# KATAKANA LETTER I
0x2525	0x30A5	# KATAKANA LETTER SMALL U
0x2526	0x30A6	# KATAKANA LETTER U
0x2527	0x30A7	# KATAKANA LETTER SMALL E
0x2528	0x30A8	# KATAKANA LETTER E
0x2529	0x30A9	# KATAKANA LETTER SMALL O
0x252A	0x30AA	# KATAKANA LETTER O
0x252B	0x30AB	# KATAKANA LETTER KA
0x252C	0x30AC	# KATAKANA LETTER GA
0x252D	0x30AD	# KATAKANA LETTER KI
0x252E	0x30AE	# KATAKANA LETTER GI
0x252F	0x30AF	# KATAKANA LETTER KU
0x2530	0x30B0	# KATAKANA LETTER GU
0x2531	0x30B1	# KATAKANA LETTER KE
0x2532	0x30B2	# KATAKANA LETTER GE
0x2533	0x30B3	# KATAKANA LETTER KO
0x2534	0x30B4	# KATAKANA LETTER GO
0x2535	0x30B5	# KATAKANA LETTER SA
0x2536	0x30B6	# KATAKANA LETTER ZA
0x2537	0x30B7	# KATAKANA LETTER SI
0x2538	0x30B8	# KATAKANA LETTER ZI
0x2539	0x30B9	# KATAKANA LETTER SU
0x253A	0x30BA	# KATAKANA LETTER ZU
0x253B	0x30BB	# KATAKANA LETTER SE
0x253C	0x30BC	# KATAKANA LETTER ZE
0x253D	0x30BD	# KATAKANA LETTER SO
0x253E	0x30BE	# KATAKANA LETTER ZO
0x253F	0x30BF	# KATAKANA LETTER TA
0x2540	0x30C0	# KATAKANA LETTER DA
0x2541	0x30C1	# KATAKANA LETTER TI
0x2542	0x30C2	# KATAKANA LETTER DI
0x2543	0x30C3	# KATAKANA LETTER SMALL TU
0x2544	0x30C4	# KATAKANA LETTER TU
0x2545	0x30C5	# KATAKANA LETTER DU
0x2546	0x30C6	# KATAKANA LETTER TE
0x2547	0x30C7	# KATAKANA LETTER DE
0x2548	0x30C8	# KATAKANA LETTER TO
0x2549	0x30C9	# KATAKANA LETTER DO
0x254A	0x30CA	# KATAKANA LETTER NA
0x254B	0x30CB	# KATAKANA LETTER NI
0x254C	0x30CC	# KATAKANA LETTER NU
0x254D	0x30CD	# KATAKANA LETTER NE
0x254E	0x30CE	# KATAKANA LETTER NO
0x254F	0x30CF	# KATAKANA LETTER HA
0x2550	0x30D0	# KATAKANA LETTER BA
0x2551	0x30D1	# KATAKANA LETTER PA
0x2552	0x30D2	# KATAKANA LETTER HI
0x2553	0x30D3	# KATAKANA LETTER BI
0x2554	0x30D4	# KATAKANA LETTER PI
0x2555	0x30D5	# KATAKANA LETTER HU
0x2556	0x30D6	# KATAKANA LETTER BU
0x2557	0x30D7	# KATAKANA LETTER PU
0x2558	0x30D8	# KATAKANA LETTER HE
0x2559	0x30D9	# KATAKANA LETTER BE
0x255A	0x30DA	# KATAKANA LETTER PE
0x255B	0x30DB	# KATAKANA LETTER HO
0x255C	0x30DC	# KATAKANA LETTER BO
0x255D	0x30DD	# KATAKANA LETTER PO
0x255E	0x30DE	# KATAKANA LETTER MA
0x255F	0x30DF	# KATAKANA LETTER MI
0x2560	0x30E0	# KATAKANA LETTER MU
0x2561	0x30E1	# KATAKANA LETTER ME
0x2562	0x30E2	# KATAKANA LETTER MO
0x2563	0x30E3	# KATAKANA LETTER SMALL YA
0x2564	0x30E4	# KATAKANA LETTER YA
0x2565	0x30E5	# KATAKANA LETTER SMALL YU
0x2566	0x30E6	# KATAKANA LETTER YU
0x2567	0x30E7	# KATAKANA LETTER SMALL YO
0x2568	0x30E8	# KATAKANA LETTER YO
0x2569	0x30E9	# KATAKANA LETTER RA
0x256A	0x30EA	# KATAKANA LETTER RI
0x256B	0x30EB	# KATAKANA LETTER RU
0x256C	0x30EC	# KATAKANA LETTER RE
0x256D	0x30ED	# KATAKANA LETTER RO
0x256E	0x30EE	# KATAKANA LETTER SMALL WA
0x256F	0x30EF	# KATAKANA LETTER WA
0x2570	0x30F0	# KATAKANA LETTER WI
0x2571	0x30F1	# KATAKANA LETTER WE
0x2572	0x30F2	# KATAKANA LETTER WO
0x2573	0x30F3	# KATAKANA LETTER N
0x2574	0x30F4	# KATAKANA LETTER VU
0x2575	0x30F5	# KATAKANA LETTER SMALL KA
0x2576	0x30F6	# KATAKANA LETTER SMALL KE
0x2621	0x0391	# GREEK CAPITAL LETTER ALPHA
0x2622	0x0392	# GREEK CAPITAL LETTER BETA
0x2623	0x0393	# GREEK CAPITAL LETTER GAMMA
0x2624	0x0394	# GREEK CAPITAL LETTER DELTA
0x2625	0x0395	# GREEK CAPITAL LETTER EPSILON
0x2626	0x0396	# GREEK CAPITAL LETTER ZETA
0x2627	0x0397	# GREEK CAPITAL LETTER ETA
0x2628	0x0398	# GREEK CAPITAL LETTER THETA
0x2629	0x0399	# GREEK CAPITAL LETTER IOTA
0x262A	0x039A	# GREEK CAPITAL LETTER KAPPA
0x262B	0x039B	# GREEK CAPITAL LETTER LAMDA
0x262C	0x039C	# GREEK CAPITAL LETTER MU
0x262D	0x039D	# GREEK CAPITAL LETTER NU
0x262E	0x039E	# GREEK CAPITAL LETTER XI
0x262F	0x039F	# GREEK CAPITAL LETTER OMICRON
0x2630	0x03A0	# GREEK CAPITAL LETTER PI
0x2631	0x03A1	# GREEK CAPITAL LETTER RHO
0x2632	0x03A3	# GREEK CAPITAL LETTER SIGMA
0x2633	0x03A4	# GREEK CAPITAL LETTER TAU
0x2634	0x03A5	# GREEK CAPITAL LETTER UPSILON
0x2635	0x03A6	# GREEK CAPITAL LETTER PHI
0x2636	0x03A7	# GREEK CAPITAL LETTER CHI
0x2637	0x03A8	# GREEK CAPITAL LETTER PSI
0x2638	0x03A9	# GREEK CAPITAL LETTER OMEGA
0x2641	0x03B1	# GREEK SMALL LETTER ALPHA
0x2642	0x03B2	# GREEK SMALL LETTER BETA
0x2643	0x03B3	# GREEK SMALL LETTER GAMMA
0x2644	0x03B4	# GREEK SMALL LETTER DELTA
0x2645	0x03B5	# GREEK SMALL LETTER EPSILON
0x2646	0x03B6	# GREEK SMALL LETTER ZETA
0x2647	0x03B7	# GREEK SMALL LETTER ETA
0x2648	0x03B8	# GREEK SMALL LETTER THETA
0x2649	0x03B9	# GREEK SMALL LETTER IOTA
0x264A	0x03BA	# GREEK SMALL LETTER KAPPA
0x264B	0x03BB	# GREEK SMALL LETTER LAMDA
0x264C	0x03BC	# GREEK SMALL LETTER MU
0x264D	0x03BD	# GREEK SMALL LETTER NU
0x264E	0x03BE	# GREEK SMALL LETTER XI
0x264F	0x03BF	# GREEK SMALL LETTER OMICRON
0x2650	0x03C0	# GREEK SMALL LETTER PI
0x2651	0x03C1	# GREEK SMALL LETTER RHO
0x2652	0x03C3	# GREEK SMALL LETTER SIGMA
0x2653	0x03C4	# GREEK SMALL LETTER TAU
0x2654	0x03C5	# GREEK SMALL LETTER UPSILON
0x2655	0x03C6	# GREEK SMALL LETTER PHI
0x2656	0x03C7	# GREEK SMALL LETTER CHI
0x2657	0x03C8	# GREEK SMALL LETTER PSI
0x2658	0x03C9	# GREEK SMALL LETTER OMEGA
0x2721	0x0410	# CYRILLIC CAPITAL LETTER A
0x2722	0x0411	# CYRILLIC CAPITAL LETTER BE
0x2723	0x0412	# CYRILLIC CAPITAL LETTER VE
0x2724	0x0413	# CYRILLIC CAPITAL LETTER GHE
0x2725	0x0414	# CYRILLIC CAPITAL LETTER DE
0x2726	0x0415	# CYRILLIC CAPITAL LETTER IE
0x2727	0x0401	# CYRILLIC CAPITAL LETTER IO
0x2728	0x0416	# CYRILLIC CAPITAL LETTER ZHE
0x2729	0x0417	# CYRILLIC CAPITAL LETTER ZE
0x272A	0x0418	# CYRILLIC CAPITAL LETTER I
0x272B	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
0x272C	0x041A	# CYRILLIC CAPITAL LETTER KA
0x272D	0x041B	# CYRILLIC CAPITAL LETTER EL
0x272E	0x041C	# CYRILLIC CAPITAL LETTER EM
0x272F	0x041D	# CYRILLIC CAPITAL LETTER EN
0x2730	0x041E	# CYRILLIC CAPITAL LETTER O
0x2731	0x041F	# CYRILLIC CAPITAL LETTER PE
0x2732	0x0420	# CYRILLIC CAPITAL LETTER ER
0x2733	0x0421	# CYRILLIC CAPITAL LETTER ES
0x2734	0x0422	# CYRILLIC CAPITAL LETTER TE
0x2735	0x0423	# CYRILLIC CAPITAL LETTER U
0x2736	0x0424	# CYRILLIC CAPITAL LETTER EF
0x2737	0x0425	# CYRILLIC CAPITAL LETTER HA
0x2738	0x0426	# CYRILLIC CAPITAL LETTER TSE
0x2739	0x0427	# CYRILLIC CAPITAL LETTER CHE
0x273A	0x0428	# CYRILLIC CAPITAL LETTER SHA
0x273B	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
0x273C	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
0x273D	0x042B	# CYRILLIC CAPITAL LETTER YERU
0x273E	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
0x273F	0x042D	# CYRILLIC CAPITAL LETTER E
0x2740	0x042E	# CYRILLIC CAPITAL LETTER YU
0x2741	0x042F	# CYRILLIC CAPITAL LETTER YA
0x2751	0x0430	# CYRILLIC SMALL LETTER A
0x2752	0x0431	# CYRILLIC SMALL LETTER BE
0x2753	0x0432	# CYRILLIC SMALL LETTER VE
0x2754	0x0433	# CYRILLIC SMALL LETTER GHE
0x2755	0x0434	# CYRILLIC SMALL LETTER DE
0x2756	0x0435	# CYRILLIC SMALL LETTER IE
0x2757	0x0451	# CYRILLIC SMALL LETTER IO
0x2758	0x0436	# CYRILLIC SMALL LETTER ZHE
0x2759	0x0437	# CYRILLIC SMALL LETTER ZE
0x275A	0x0438	# CYRILLIC SMALL LETTER I
0x275B	0x0439	# CYRILLIC SMALL LETTER SHORT I
0x275C	0x043A	# CYRILLIC SMALL LETTER KA
0x275D	0x043B	# CYRILLIC SMALL LETTER EL
0x275E	0x043C	# CYRILLIC SMALL LETTER EM
0x275F	0x043D	# CYRILLIC SMALL LETTER EN
0x2760	0x043E	# CYRILLIC SMALL LETTER O
0x2761	0x043F	# CYRILLIC SMALL LETTER PE
0x2762	0x0440	# CYRILLIC SMALL LETTER ER
0x2763	0x0441	# CYRILLIC SMALL LETTER ES
0x2764	0x0442	# CYRILLIC SMALL LETTER TE
0x2765	0x0443	# CYRILLIC SMALL LETTER U
0x2766	0x0444	# CYRILLIC SMALL LETTER EF
0x2767	0x0445	# CYRILLIC SMALL LETTER HA
0x2768	0x0446	# CYRILLIC SMALL LETTER TSE
0x2769	0x0447	# CYRILLIC SMALL LETTER CHE
0x276A	0x0448	# CYRILLIC SMALL LETTER SHA
0x276B	0x0449	# CYRILLIC SMALL LETTER SHCHA
0x276C	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
0x276D	0x044B	# CYRILLIC SMALL LETTER YERU
0x276E	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
0x276F	0x044D	# CYRILLIC SMALL LETTER E
0x2770	0x044E	# CYRILLIC SMALL LETTER YU
0x2771	0x044F	# CYRILLIC SMALL LETTER YA
0x2821	0x0101	# LATIN SMALL LETTER A WITH MACRON
0x2822	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
0x2823	0x01CE	# LATIN SMALL LETTER A WITH CARON
0x2824	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
0x2825	0x0113	# LATIN SMALL LETTER E WITH MACRON
0x2826	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
0x2827	0x011B	# LATIN SMALL LETTER E WITH CARON
0x2828	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
0x2829	0x012B	# LATIN SMALL LETTER I WITH MACRON
0x282A	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
0x282B	0x01D0	# LATIN SMALL LETTER I WITH CARON
0x282C	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
0x282D	0x014D	# LATIN SMALL LETTER O WITH MACRON
0x282E	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
0x282F	0x01D2	# LATIN SMALL LETTER O WITH CARON
0x2830	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
0x2831	0x016B	# LATIN SMALL LETTER U WITH MACRON
0x2832	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
0x2833	0x01D4	# LATIN SMALL LETTER U WITH CARON
0x2834	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
0x2835	0x01D6	# LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
0x2836	0x01D8	# LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
0x2837	0x01DA	# LATIN SMALL LETTER U WITH DIAERESIS AND CARON
0x2838	0x01DC	# LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
0x2839	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
0x283A	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
0x2845	0x3105	# BOPOMOFO LETTER B
0x2846	0x3106	# BOPOMOFO LETTER P
0x2847	0x3107	# BOPOMOFO LETTER M
0x2848	0x3108	# BOPOMOFO LETTER F
0x2849	0x3109	# BOPOMOFO LETTER D
0x284A	0x310A	# BOPOMOFO LETTER T
0x284B	0x310B	# BOPOMOFO LETTER N
0x284C	0x310C	# BOPOMOFO LETTER L
0x284D	0x310D	# BOPOMOFO LETTER G
0x284E	0x310E	# BOPOMOFO LETTER K
0x284F	0x310F	# BOPOMOFO LETTER H
0x2850	0x3110	# BOPOMOFO LETTER J
0x2851	0x3111	# BOPOMOFO LETTER Q
0x2852	0x3112	# BOPOMOFO LETTER X
0x2853	0x3113	# BOPOMOFO LETTER ZH
0x2854	0x3114	# BOPOMOFO LETTER CH
0x2855	0x3115	# BOPOMOFO LETTER SH
0x2856	0x3116	# BOPOMOFO LETTER R
0x2857	0x3117	# BOPOMOFO LETTER Z
0x2858	0x3118	# BOPOMOFO LETTER C
0x2859	0x3119	# BOPOMOFO LETTER S
0x285A	0x311A	# BOPOMOFO LETTER A
0x285B	0x311B	# BOPOMOFO LETTER O
0x285C	0x311C	# BOPOMOFO LETTER E
0x285D	0x311D	# BOPOMOFO LETTER EH
0x285E	0x311E	# BOPOMOFO LETTER AI
0x285F	0x311F	# BOPOMOFO LETTER EI
0x2860	0x3120	# BOPOMOFO LETTER AU
0x2861	0x3121	# BOPOMOFO LETTER OU
0x2862	0x3122	# BOPOMOFO LETTER AN
0x2863	0x3123	# BOPOMOFO LETTER EN
0x2864	0x3124	# BOPOMOFO LETTER ANG
0x2865	0x3125	# BOPOMOFO LETTER ENG
0x2866	0x3126	# BOPOMOFO LETTER ER
0x2867	0x3127	# BOPOMOFO LETTER I
0x2868	0x3128	# BOPOMOFO LETTER U
0x2869	0x3129	# BOPOMOFO LETTER IU
0x2924	0x2500	# BOX DRAWINGS LIGHT HORIZONTAL
0x2925	0x2501	# BOX DRAWINGS HEAVY HORIZONTAL
0x2926	0x2502	# BOX DRAWINGS LIGHT VERTICAL
0x2927	0x2503	# BOX DRAWINGS HEAVY VERTICAL
0x2928	0x2504	# BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL
0x2929	0x2505	# BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL
0x292A	0x2506	# BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL
0x292B	0x2507	# BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL
0x292C	0x2508	# BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL
0x292D	0x2509	# BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL
0x292E	0x250A	# BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL
0x292F	0x250B	# BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL
0x2930	0x250C	# BOX DRAWINGS LIGHT DOWN AND RIGHT
0x2931	0x250D	# BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
0x2932	0x250E	# BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
0x2933	0x250F	# BOX DRAWINGS HEAVY DOWN AND RIGHT
0x2934	0x2510	# BOX DRAWINGS LIGHT DOWN AND LEFT
0x2935	0x2511	# BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
0x2936	0x2512	# BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
0x2937	0x2513	# BOX DRAWINGS HEAVY DOWN AND LEFT
0x2938	0x2514	# BOX DRAWINGS LIGHT UP AND RIGHT
0x2939	0x2515	# BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
0x293A	0x2516	# BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
0x293B	0x2517	# BOX DRAWINGS HEAVY UP AND RIGHT
0x293C	0x2518	# BOX DRAWINGS LIGHT UP AND LEFT
0x293D	0x2519	# BOX DRAWINGS UP LIGHT AND LEFT HEAVY
0x293E	0x251A	# BOX DRAWINGS UP HEAVY AND LEFT LIGHT
0x293F	0x251B	# BOX DRAWINGS HEAVY UP AND LEFT
0x2940	0x251C	# BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0x2941	0x251D	# BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
0x2942	0x251E	# BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
0x2943	0x251F	# BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
0x2944	0x2520	# BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
0x2945	0x2521	# BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
0x2946	0x2522	# BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
0x2947	0x2523	# BOX DRAWINGS HEAVY VERTICAL AND RIGHT
0x2948	0x2524	# BOX DRAWINGS LIGHT VERTICAL AND LEFT
0x2949	0x2525	# BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
0x294A	0x2526	# BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
0x294B	0x2527	# BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
0x294C	0x2528	# BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
0x294D	0x2529	# BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
0x294E	0x252A	# BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
0x294F	0x252B	# BOX DRAWINGS HEAVY VERTICAL AND LEFT
0x2950	0x252C	# BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0x2951	0x252D	# BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
0x2952	0x252E	# BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
0x2953	0x252F	# BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
0x2954	0x2530	# BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
0x2955	0x2531	# BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
0x2956	0x2532	# BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
0x2957	0x2533	# BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
0x2958	0x2534	# BOX DRAWINGS LIGHT UP AND HORIZONTAL
0x2959	0x2535	# BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
0x295A	0x2536	# BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
0x295B	0x2537	# BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
0x295C	0x2538	# BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
0x295D	0x2539	# BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
0x295E	0x253A	# BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
0x295F	0x253B	# BOX DRAWINGS HEAVY UP AND HORIZONTAL
0x2960	0x253C	# BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0x2961	0x253D	# BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
0x2962	0x253E	# BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
0x2963	0x253F	# BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
0x2964	0x2540	# BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
0x2965	0x2541	# BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
0x2966	0x2542	# BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
0x2967	0x2543	# BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
0x2968	0x2544	# BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
0x2969	0x2545	# BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
0x296A	0x2546	# BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
0x296B	0x2547	# BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
0x296C	0x2548	# BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
0x296D	0x2549	# BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
0x296E	0x254A	# BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
0x296F	0x254B	# BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
0x3021	0x554A	# <CJK>
0x3022	0x963F	# <CJK>
0x3023	0x57C3	# <CJK>
0x3024	0x6328	# <CJK>
0x3025	0x54CE	# <CJK>
0x3026	0x5509	# <CJK>
0x3027	0x54C0	# <CJK>
0x3028	0x7691	# <CJK>
0x3029	0x764C	# <CJK>
0x302A	0x853C	# <CJK>
0x302B	0x77EE	# <CJK>
0x302C	0x827E	# <CJK>
0x302D	0x788D	# <CJK>
0x302E	0x7231	# <CJK>
0x302F	0x9698	# <CJK>
0x3030	0x978D	# <CJK>
0x3031	0x6C28	# <CJK>
0x3032	0x5B89	# <CJK>
0x3033	0x4FFA	# <CJK>
0x3034	0x6309	# <CJK>
0x3035	0x6697	# <CJK>
0x3036	0x5CB8	# <CJK>
0x3037	0x80FA	# <CJK>
0x3038	0x6848	# <CJK>
0x3039	0x80AE	# <CJK>
0x303A	0x6602	# <CJK>
0x303B	0x76CE	# <CJK>
0x303C	0x51F9	# <CJK>
0x303D	0x6556	# <CJK>
0x303E	0x71AC	# <CJK>
0x303F	0x7FF1	# <CJK>
0x3040	0x8884	# <CJK>
0x3041	0x50B2	# <CJK>
0x3042	0x5965	# <CJK>
0x3043	0x61CA	# <CJK>
0x3044	0x6FB3	# <CJK>
0x3045	0x82AD	# <CJK>
0x3046	0x634C	# <CJK>
0x3047	0x6252	# <CJK>
0x3048	0x53ED	# <CJK>
0x3049	0x5427	# <CJK>
0x304A	0x7B06	# <CJK>
0x304B	0x516B	# <CJK>
0x304C	0x75A4	# <CJK>
0x304D	0x5DF4	# <CJK>
0x304E	0x62D4	# <CJK>
0x304F	0x8DCB	# <CJK>
0x3050	0x9776	# <CJK>
0x3051	0x628A	# <CJK>
0x3052	0x8019	# <CJK>
0x3053	0x575D	# <CJK>
0x3054	0x9738	# <CJK>
0x3055	0x7F62	# <CJK>
0x3056	0x7238	# <CJK>
0x3057	0x767D	# <CJK>
0x3058	0x67CF	# <CJK>
0x3059	0x767E	# <CJK>
0x305A	0x6446	# <CJK>
0x305B	0x4F70	# <CJK>
0x305C	0x8D25	# <CJK>
0x305D	0x62DC	# <CJK>
0x305E	0x7A17	# <CJK>
0x305F	0x6591	# <CJK>
0x3060	0x73ED	# <CJK>
0x3061	0x642C	# <CJK>
0x3062	0x6273	# <CJK>
0x3063	0x822C	# <CJK>
0x3064	0x9881	# <CJK>
0x3065	0x677F	# <CJK>
0x3066	0x7248	# <CJK>
0x3067	0x626E	# <CJK>
0x3068	0x62CC	# <CJK>
0x3069	0x4F34	# <CJK>
0x306A	0x74E3	# <CJK>
0x306B	0x534A	# <CJK>
0x306C	0x529E	# <CJK>
0x306D	0x7ECA	# <CJK>
0x306E	0x90A6	# <CJK>
0x306F	0x5E2E	# <CJK>
0x3070	0x6886	# <CJK>
0x3071	0x699C	# <CJK>
0x3072	0x8180	# <CJK>
0x3073	0x7ED1	# <CJK>
0x3074	0x68D2	# <CJK>
0x3075	0x78C5	# <CJK>
0x3076	0x868C	# <CJK>
0x3077	0x9551	# <CJK>
0x3078	0x508D	# <CJK>
0x3079	0x8C24	# <CJK>
0x307A	0x82DE	# <CJK>
0x307B	0x80DE	# <CJK>
0x307C	0x5305	# <CJK>
0x307D	0x8912	# <CJK>
0x307E	0x5265	# <CJK>
0x3121	0x8584	# <CJK>
0x3122	0x96F9	# <CJK>
0x3123	0x4FDD	# <CJK>
0x3124	0x5821	# <CJK>
0x3125	0x9971	# <CJK>
0x3126	0x5B9D	# <CJK>
0x3127	0x62B1	# <CJK>
0x3128	0x62A5	# <CJK>
0x3129	0x66B4	# <CJK>
0x312A	0x8C79	# <CJK>
0x312B	0x9C8D	# <CJK>
0x312C	0x7206	# <CJK>
0x312D	0x676F	# <CJK>
0x312E	0x7891	# <CJK>
0x312F	0x60B2	# <CJK>
0x3130	0x5351	# <CJK>
0x3131	0x5317	# <CJK>
0x3132	0x8F88	# <CJK>
0x3133	0x80CC	# <CJK>
0x3134	0x8D1D	# <CJK>
0x3135	0x94A1	# <CJK>
0x3136	0x500D	# <CJK>
0x3137	0x72C8	# <CJK>
0x3138	0x5907	# <CJK>
0x3139	0x60EB	# <CJK>
0x313A	0x7119	# <CJK>
0x313B	0x88AB	# <CJK>
0x313C	0x5954	# <CJK>
0x313D	0x82EF	# <CJK>
0x313E	0x672C	# <CJK>
0x313F	0x7B28	# <CJK>
0x3140	0x5D29	# <CJK>
0x3141	0x7EF7	# <CJK>
0x3142	0x752D	# <CJK>
0x3143	0x6CF5	# <CJK>
0x3144	0x8E66	# <CJK>
0x3145	0x8FF8	# <CJK>
0x3146	0x903C	# <CJK>
0x3147	0x9F3B	# <CJK>
0x3148	0x6BD4	# <CJK>
0x3149	0x9119	# <CJK>
0x314A	0x7B14	# <CJK>
0x314B	0x5F7C	# <CJK>
0x314C	0x78A7	# <CJK>
0x314D	0x84D6	# <CJK>
0x314E	0x853D	# <CJK>
0x314F	0x6BD5	# <CJK>
0x3150	0x6BD9	# <CJK>
0x3151	0x6BD6	# <CJK>
0x3152	0x5E01	# <CJK>
0x3153	0x5E87	# <CJK>
0x3154	0x75F9	# <CJK>
0x3155	0x95ED	# <CJK>
0x3156	0x655D	# <CJK>
0x3157	0x5F0A	# <CJK>
0x3158	0x5FC5	# <CJK>
0x3159	0x8F9F	# <CJK>
0x315A	0x58C1	# <CJK>
0x315B	0x81C2	# <CJK>
0x315C	0x907F	# <CJK>
0x315D	0x965B	# <CJK>
0x315E	0x97AD	# <CJK>
0x315F	0x8FB9	# <CJK>
0x3160	0x7F16	# <CJK>
0x3161	0x8D2C	# <CJK>
0x3162	0x6241	# <CJK>
0x3163	0x4FBF	# <CJK>
0x3164	0x53D8	# <CJK>
0x3165	0x535E	# <CJK>
0x3166	0x8FA8	# <CJK>
0x3167	0x8FA9	# <CJK>
0x3168	0x8FAB	# <CJK>
0x3169	0x904D	# <CJK>
0x316A	0x6807	# <CJK>
0x316B	0x5F6A	# <CJK>
0x316C	0x8198	# <CJK>
0x316D	0x8868	# <CJK>
0x316E	0x9CD6	# <CJK>
0x316F	0x618B	# <CJK>
0x3170	0x522B	# <CJK>
0x3171	0x762A	# <CJK>
0x3172	0x5F6C	# <CJK>
0x3173	0x658C	# <CJK>
0x3174	0x6FD2	# <CJK>
0x3175	0x6EE8	# <CJK>
0x3176	0x5BBE	# <CJK>
0x3177	0x6448	# <CJK>
0x3178	0x5175	# <CJK>
0x3179	0x51B0	# <CJK>
0x317A	0x67C4	# <CJK>
0x317B	0x4E19	# <CJK>
0x317C	0x79C9	# <CJK>
0x317D	0x997C	# <CJK>
0x317E	0x70B3	# <CJK>
0x3221	0x75C5	# <CJK>
0x3222	0x5E76	# <CJK>
0x3223	0x73BB	# <CJK>
0x3224	0x83E0	# <CJK>
0x3225	0x64AD	# <CJK>
0x3226	0x62E8	# <CJK>
0x3227	0x94B5	# <CJK>
0x3228	0x6CE2	# <CJK>
0x3229	0x535A	# <CJK>
0x322A	0x52C3	# <CJK>
0x322B	0x640F	# <CJK>
0x322C	0x94C2	# <CJK>
0x322D	0x7B94	# <CJK>
0x322E	0x4F2F	# <CJK>
0x322F	0x5E1B	# <CJK>
0x3230	0x8236	# <CJK>
0x3231	0x8116	# <CJK>
0x3232	0x818A	# <CJK>
0x3233	0x6E24	# <CJK>
0x3234	0x6CCA	# <CJK>
0x3235	0x9A73	# <CJK>
0x3236	0x6355	# <CJK>
0x3237	0x535C	# <CJK>
0x3238	0x54FA	# <CJK>
0x3239	0x8865	# <CJK>
0x323A	0x57E0	# <CJK>
0x323B	0x4E0D	# <CJK>
0x323C	0x5E03	# <CJK>
0x323D	0x6B65	# <CJK>
0x323E	0x7C3F	# <CJK>
0x323F	0x90E8	# <CJK>
0x3240	0x6016	# <CJK>
0x3241	0x64E6	# <CJK>
0x3242	0x731C	# <CJK>
0x3243	0x88C1	# <CJK>
0x3244	0x6750	# <CJK>
0x3245	0x624D	# <CJK>
0x3246	0x8D22	# <CJK>
0x3247	0x776C	# <CJK>
0x3248	0x8E29	# <CJK>
0x3249	0x91C7	# <CJK>
0x324A	0x5F69	# <CJK>
0x324B	0x83DC	# <CJK>
0x324C	0x8521	# <CJK>
0x324D	0x9910	# <CJK>
0x324E	0x53C2	# <CJK>
0x324F	0x8695	# <CJK>
0x3250	0x6B8B	# <CJK>
0x3251	0x60ED	# <CJK>
0x3252	0x60E8	# <CJK>
0x3253	0x707F	# <CJK>
0x3254	0x82CD	# <CJK>
0x3255	0x8231	# <CJK>
0x3256	0x4ED3	# <CJK>
0x3257	0x6CA7	# <CJK>
0x3258	0x85CF	# <CJK>
0x3259	0x64CD	# <CJK>
0x325A	0x7CD9	# <CJK>
0x325B	0x69FD	# <CJK>
0x325C	0x66F9	# <CJK>
0x325D	0x8349	# <CJK>
0x325E	0x5395	# <CJK>
0x325F	0x7B56	# <CJK>
0x3260	0x4FA7	# <CJK>
0x3261	0x518C	# <CJK>
0x3262	0x6D4B	# <CJK>
0x3263	0x5C42	# <CJK>
0x3264	0x8E6D	# <CJK>
0x3265	0x63D2	# <CJK>
0x3266	0x53C9	# <CJK>
0x3267	0x832C	# <CJK>
0x3268	0x8336	# <CJK>
0x3269	0x67E5	# <CJK>
0x326A	0x78B4	# <CJK>
0x326B	0x643D	# <CJK>
0x326C	0x5BDF	# <CJK>
0x326D	0x5C94	# <CJK>
0x326E	0x5DEE	# <CJK>
0x326F	0x8BE7	# <CJK>
0x3270	0x62C6	# <CJK>
0x3271	0x67F4	# <CJK>
0x3272	0x8C7A	# <CJK>
0x3273	0x6400	# <CJK>
0x3274	0x63BA	# <CJK>
0x3275	0x8749	# <CJK>
0x3276	0x998B	# <CJK>
0x3277	0x8C17	# <CJK>
0x3278	0x7F20	# <CJK>
0x3279	0x94F2	# <CJK>
0x327A	0x4EA7	# <CJK>
0x327B	0x9610	# <CJK>
0x327C	0x98A4	# <CJK>
0x327D	0x660C	# <CJK>
0x327E	0x7316	# <CJK>
0x3321	0x573A	# <CJK>
0x3322	0x5C1D	# <CJK>
0x3323	0x5E38	# <CJK>
0x3324	0x957F	# <CJK>
0x3325	0x507F	# <CJK>
0x3326	0x80A0	# <CJK>
0x3327	0x5382	# <CJK>
0x3328	0x655E	# <CJK>
0x3329	0x7545	# <CJK>
0x332A	0x5531	# <CJK>
0x332B	0x5021	# <CJK>
0x332C	0x8D85	# <CJK>
0x332D	0x6284	# <CJK>
0x332E	0x949E	# <CJK>
0x332F	0x671D	# <CJK>
0x3330	0x5632	# <CJK>
0x3331	0x6F6E	# <CJK>
0x3332	0x5DE2	# <CJK>
0x3333	0x5435	# <CJK>
0x3334	0x7092	# <CJK>
0x3335	0x8F66	# <CJK>
0x3336	0x626F	# <CJK>
0x3337	0x64A4	# <CJK>
0x3338	0x63A3	# <CJK>
0x3339	0x5F7B	# <CJK>
0x333A	0x6F88	# <CJK>
0x333B	0x90F4	# <CJK>
0x333C	0x81E3	# <CJK>
0x333D	0x8FB0	# <CJK>
0x333E	0x5C18	# <CJK>
0x333F	0x6668	# <CJK>
0x3340	0x5FF1	# <CJK>
0x3341	0x6C89	# <CJK>
0x3342	0x9648	# <CJK>
0x3343	0x8D81	# <CJK>
0x3344	0x886C	# <CJK>
0x3345	0x6491	# <CJK>
0x3346	0x79F0	# <CJK>
0x3347	0x57CE	# <CJK>
0x3348	0x6A59	# <CJK>
0x3349	0x6210	# <CJK>
0x334A	0x5448	# <CJK>
0x334B	0x4E58	# <CJK>
0x334C	0x7A0B	# <CJK>
0x334D	0x60E9	# <CJK>
0x334E	0x6F84	# <CJK>
0x334F	0x8BDA	# <CJK>
0x3350	0x627F	# <CJK>
0x3351	0x901E	# <CJK>
0x3352	0x9A8B	# <CJK>
0x3353	0x79E4	# <CJK>
0x3354	0x5403	# <CJK>
0x3355	0x75F4	# <CJK>
0x3356	0x6301	# <CJK>
0x3357	0x5319	# <CJK>
0x3358	0x6C60	# <CJK>
0x3359	0x8FDF	# <CJK>
0x335A	0x5F1B	# <CJK>
0x335B	0x9A70	# <CJK>
0x335C	0x803B	# <CJK>
0x335D	0x9F7F	# <CJK>
0x335E	0x4F88	# <CJK>
0x335F	0x5C3A	# <CJK>
0x3360	0x8D64	# <CJK>
0x3361	0x7FC5	# <CJK>
0x3362	0x65A5	# <CJK>
0x3363	0x70BD	# <CJK>
0x3364	0x5145	# <CJK>
0x3365	0x51B2	# <CJK>
0x3366	0x866B	# <CJK>
0x3367	0x5D07	# <CJK>
0x3368	0x5BA0	# <CJK>
0x3369	0x62BD	# <CJK>
0x336A	0x916C	# <CJK>
0x336B	0x7574	# <CJK>
0x336C	0x8E0C	# <CJK>
0x336D	0x7A20	# <CJK>
0x336E	0x6101	# <CJK>
0x336F	0x7B79	# <CJK>
0x3370	0x4EC7	# <CJK>
0x3371	0x7EF8	# <CJK>
0x3372	0x7785	# <CJK>
0x3373	0x4E11	# <CJK>
0x3374	0x81ED	# <CJK>
0x3375	0x521D	# <CJK>
0x3376	0x51FA	# <CJK>
0x3377	0x6A71	# <CJK>
0x3378	0x53A8	# <CJK>
0x3379	0x8E87	# <CJK>
0x337A	0x9504	# <CJK>
0x337B	0x96CF	# <CJK>
0x337C	0x6EC1	# <CJK>
0x337D	0x9664	# <CJK>
0x337E	0x695A	# <CJK>
0x3421	0x7840	# <CJK>
0x3422	0x50A8	# <CJK>
0x3423	0x77D7	# <CJK>
0x3424	0x6410	# <CJK>
0x3425	0x89E6	# <CJK>
0x3426	0x5904	# <CJK>
0x3427	0x63E3	# <CJK>
0x3428	0x5DDD	# <CJK>
0x3429	0x7A7F	# <CJK>
0x342A	0x693D	# <CJK>
0x342B	0x4F20	# <CJK>
0x342C	0x8239	# <CJK>
0x342D	0x5598	# <CJK>
0x342E	0x4E32	# <CJK>
0x342F	0x75AE	# <CJK>
0x3430	0x7A97	# <CJK>
0x3431	0x5E62	# <CJK>
0x3432	0x5E8A	# <CJK>
0x3433	0x95EF	# <CJK>
0x3434	0x521B	# <CJK>
0x3435	0x5439	# <CJK>
0x3436	0x708A	# <CJK>
0x3437	0x6376	# <CJK>
0x3438	0x9524	# <CJK>
0x3439	0x5782	# <CJK>
0x343A	0x6625	# <CJK>
0x343B	0x693F	# <CJK>
0x343C	0x9187	# <CJK>
0x343D	0x5507	# <CJK>
0x343E	0x6DF3	# <CJK>
0x343F	0x7EAF	# <CJK>
0x3440	0x8822	# <CJK>
0x3441	0x6233	# <CJK>
0x3442	0x7EF0	# <CJK>
0x3443	0x75B5	# <CJK>
0x3444	0x8328	# <CJK>
0x3445	0x78C1	# <CJK>
0x3446	0x96CC	# <CJK>
0x3447	0x8F9E	# <CJK>
0x3448	0x6148	# <CJK>
0x3449	0x74F7	# <CJK>
0x344A	0x8BCD	# <CJK>
0x344B	0x6B64	# <CJK>
0x344C	0x523A	# <CJK>
0x344D	0x8D50	# <CJK>
0x344E	0x6B21	# <CJK>
0x344F	0x806A	# <CJK>
0x3450	0x8471	# <CJK>
0x3451	0x56F1	# <CJK>
0x3452	0x5306	# <CJK>
0x3453	0x4ECE	# <CJK>
0x3454	0x4E1B	# <CJK>
0x3455	0x51D1	# <CJK>
0x3456	0x7C97	# <CJK>
0x3457	0x918B	# <CJK>
0x3458	0x7C07	# <CJK>
0x3459	0x4FC3	# <CJK>
0x345A	0x8E7F	# <CJK>
0x345B	0x7BE1	# <CJK>
0x345C	0x7A9C	# <CJK>
0x345D	0x6467	# <CJK>
0x345E	0x5D14	# <CJK>
0x345F	0x50AC	# <CJK>
0x3460	0x8106	# <CJK>
0x3461	0x7601	# <CJK>
0x3462	0x7CB9	# <CJK>
0x3463	0x6DEC	# <CJK>
0x3464	0x7FE0	# <CJK>
0x3465	0x6751	# <CJK>
0x3466	0x5B58	# <CJK>
0x3467	0x5BF8	# <CJK>
0x3468	0x78CB	# <CJK>
0x3469	0x64AE	# <CJK>
0x346A	0x6413	# <CJK>
0x346B	0x63AA	# <CJK>
0x346C	0x632B	# <CJK>
0x346D	0x9519	# <CJK>
0x346E	0x642D	# <CJK>
0x346F	0x8FBE	# <CJK>
0x3470	0x7B54	# <CJK>
0x3471	0x7629	# <CJK>
0x3472	0x6253	# <CJK>
0x3473	0x5927	# <CJK>
0x3474	0x5446	# <CJK>
0x3475	0x6B79	# <CJK>
0x3476	0x50A3	# <CJK>
0x3477	0x6234	# <CJK>
0x3478	0x5E26	# <CJK>
0x3479	0x6B86	# <CJK>
0x347A	0x4EE3	# <CJK>
0x347B	0x8D37	# <CJK>
0x347C	0x888B	# <CJK>
0x347D	0x5F85	# <CJK>
0x347E	0x902E	# <CJK>
0x3521	0x6020	# <CJK>
0x3522	0x803D	# <CJK>
0x3523	0x62C5	# <CJK>
0x3524	0x4E39	# <CJK>
0x3525	0x5355	# <CJK>
0x3526	0x90F8	# <CJK>
0x3527	0x63B8	# <CJK>
0x3528	0x80C6	# <CJK>
0x3529	0x65E6	# <CJK>
0x352A	0x6C2E	# <CJK>
0x352B	0x4F46	# <CJK>
0x352C	0x60EE	# <CJK>
0x352D	0x6DE1	# <CJK>
0x352E	0x8BDE	# <CJK>
0x352F	0x5F39	# <CJK>
0x3530	0x86CB	# <CJK>
0x3531	0x5F53	# <CJK>
0x3532	0x6321	# <CJK>
0x3533	0x515A	# <CJK>
0x3534	0x8361	# <CJK>
0x3535	0x6863	# <CJK>
0x3536	0x5200	# <CJK>
0x3537	0x6363	# <CJK>
0x3538	0x8E48	# <CJK>
0x3539	0x5012	# <CJK>
0x353A	0x5C9B	# <CJK>
0x353B	0x7977	# <CJK>
0x353C	0x5BFC	# <CJK>
0x353D	0x5230	# <CJK>
0x353E	0x7A3B	# <CJK>
0x353F	0x60BC	# <CJK>
0x3540	0x9053	# <CJK>
0x3541	0x76D7	# <CJK>
0x3542	0x5FB7	# <CJK>
0x3543	0x5F97	# <CJK>
0x3544	0x7684	# <CJK>
0x3545	0x8E6C	# <CJK>
0x3546	0x706F	# <CJK>
0x3547	0x767B	# <CJK>
0x3548	0x7B49	# <CJK>
0x3549	0x77AA	# <CJK>
0x354A	0x51F3	# <CJK>
0x354B	0x9093	# <CJK>
0x354C	0x5824	# <CJK>
0x354D	0x4F4E	# <CJK>
0x354E	0x6EF4	# <CJK>
0x354F	0x8FEA	# <CJK>
0x3550	0x654C	# <CJK>
0x3551	0x7B1B	# <CJK>
0x3552	0x72C4	# <CJK>
0x3553	0x6DA4	# <CJK>
0x3554	0x7FDF	# <CJK>
0x3555	0x5AE1	# <CJK>
0x3556	0x62B5	# <CJK>
0x3557	0x5E95	# <CJK>
0x3558	0x5730	# <CJK>
0x3559	0x8482	# <CJK>
0x355A	0x7B2C	# <CJK>
0x355B	0x5E1D	# <CJK>
0x355C	0x5F1F	# <CJK>
0x355D	0x9012	# <CJK>
0x355E	0x7F14	# <CJK>
0x355F	0x98A0	# <CJK>
0x3560	0x6382	# <CJK>
0x3561	0x6EC7	# <CJK>
0x3562	0x7898	# <CJK>
0x3563	0x70B9	# <CJK>
0x3564	0x5178	# <CJK>
0x3565	0x975B	# <CJK>
0x3566	0x57AB	# <CJK>
0x3567	0x7535	# <CJK>
0x3568	0x4F43	# <CJK>
0x3569	0x7538	# <CJK>
0x356A	0x5E97	# <CJK>
0x356B	0x60E6	# <CJK>
0x356C	0x5960	# <CJK>
0x356D	0x6DC0	# <CJK>
0x356E	0x6BBF	# <CJK>
0x356F	0x7889	# <CJK>
0x3570	0x53FC	# <CJK>
0x3571	0x96D5	# <CJK>
0x3572	0x51CB	# <CJK>
0x3573	0x5201	# <CJK>
0x3574	0x6389	# <CJK>
0x3575	0x540A	# <CJK>
0x3576	0x9493	# <CJK>
0x3577	0x8C03	# <CJK>
0x3578	0x8DCC	# <CJK>
0x3579	0x7239	# <CJK>
0x357A	0x789F	# <CJK>
0x357B	0x8776	# <CJK>
0x357C	0x8FED	# <CJK>
0x357D	0x8C0D	# <CJK>
0x357E	0x53E0	# <CJK>
0x3621	0x4E01	# <CJK>
0x3622	0x76EF	# <CJK>
0x3623	0x53EE	# <CJK>
0x3624	0x9489	# <CJK>
0x3625	0x9876	# <CJK>
0x3626	0x9F0E	# <CJK>
0x3627	0x952D	# <CJK>
0x3628	0x5B9A	# <CJK>
0x3629	0x8BA2	# <CJK>
0x362A	0x4E22	# <CJK>
0x362B	0x4E1C	# <CJK>
0x362C	0x51AC	# <CJK>
0x362D	0x8463	# <CJK>
0x362E	0x61C2	# <CJK>
0x362F	0x52A8	# <CJK>
0x3630	0x680B	# <CJK>
0x3631	0x4F97	# <CJK>
0x3632	0x606B	# <CJK>
0x3633	0x51BB	# <CJK>
0x3634	0x6D1E	# <CJK>
0x3635	0x515C	# <CJK>
0x3636	0x6296	# <CJK>
0x3637	0x6597	# <CJK>
0x3638	0x9661	# <CJK>
0x3639	0x8C46	# <CJK>
0x363A	0x9017	# <CJK>
0x363B	0x75D8	# <CJK>
0x363C	0x90FD	# <CJK>
0x363D	0x7763	# <CJK>
0x363E	0x6BD2	# <CJK>
0x363F	0x728A	# <CJK>
0x3640	0x72EC	# <CJK>
0x3641	0x8BFB	# <CJK>
0x3642	0x5835	# <CJK>
0x3643	0x7779	# <CJK>
0x3644	0x8D4C	# <CJK>
0x3645	0x675C	# <CJK>
0x3646	0x9540	# <CJK>
0x3647	0x809A	# <CJK>
0x3648	0x5EA6	# <CJK>
0x3649	0x6E21	# <CJK>
0x364A	0x5992	# <CJK>
0x364B	0x7AEF	# <CJK>
0x364C	0x77ED	# <CJK>
0x364D	0x953B	# <CJK>
0x364E	0x6BB5	# <CJK>
0x364F	0x65AD	# <CJK>
0x3650	0x7F0E	# <CJK>
0x3651	0x5806	# <CJK>
0x3652	0x5151	# <CJK>
0x3653	0x961F	# <CJK>
0x3654	0x5BF9	# <CJK>
0x3655	0x58A9	# <CJK>
0x3656	0x5428	# <CJK>
0x3657	0x8E72	# <CJK>
0x3658	0x6566	# <CJK>
0x3659	0x987F	# <CJK>
0x365A	0x56E4	# <CJK>
0x365B	0x949D	# <CJK>
0x365C	0x76FE	# <CJK>
0x365D	0x9041	# <CJK>
0x365E	0x6387	# <CJK>
0x365F	0x54C6	# <CJK>
0x3660	0x591A	# <CJK>
0x3661	0x593A	# <CJK>
0x3662	0x579B	# <CJK>
0x3663	0x8EB2	# <CJK>
0x3664	0x6735	# <CJK>
0x3665	0x8DFA	# <CJK>
0x3666	0x8235	# <CJK>
0x3667	0x5241	# <CJK>
0x3668	0x60F0	# <CJK>
0x3669	0x5815	# <CJK>
0x366A	0x86FE	# <CJK>
0x366B	0x5CE8	# <CJK>
0x366C	0x9E45	# <CJK>
0x366D	0x4FC4	# <CJK>
0x366E	0x989D	# <CJK>
0x366F	0x8BB9	# <CJK>
0x3670	0x5A25	# <CJK>
0x3671	0x6076	# <CJK>
0x3672	0x5384	# <CJK>
0x3673	0x627C	# <CJK>
0x3674	0x904F	# <CJK>
0x3675	0x9102	# <CJK>
0x3676	0x997F	# <CJK>
0x3677	0x6069	# <CJK>
0x3678	0x800C	# <CJK>
0x3679	0x513F	# <CJK>
0x367A	0x8033	# <CJK>
0x367B	0x5C14	# <CJK>
0x367C	0x9975	# <CJK>
0x367D	0x6D31	# <CJK>
0x367E	0x4E8C	# <CJK>
0x3721	0x8D30	# <CJK>
0x3722	0x53D1	# <CJK>
0x3723	0x7F5A	# <CJK>
0x3724	0x7B4F	# <CJK>
0x3725	0x4F10	# <CJK>
0x3726	0x4E4F	# <CJK>
0x3727	0x9600	# <CJK>
0x3728	0x6CD5	# <CJK>
0x3729	0x73D0	# <CJK>
0x372A	0x85E9	# <CJK>
0x372B	0x5E06	# <CJK>
0x372C	0x756A	# <CJK>
0x372D	0x7FFB	# <CJK>
0x372E	0x6A0A	# <CJK>
0x372F	0x77FE	# <CJK>
0x3730	0x9492	# <CJK>
0x3731	0x7E41	# <CJK>
0x3732	0x51E1	# <CJK>
0x3733	0x70E6	# <CJK>
0x3734	0x53CD	# <CJK>
0x3735	0x8FD4	# <CJK>
0x3736	0x8303	# <CJK>
0x3737	0x8D29	# <CJK>
0x3738	0x72AF	# <CJK>
0x3739	0x996D	# <CJK>
0x373A	0x6CDB	# <CJK>
0x373B	0x574A	# <CJK>
0x373C	0x82B3	# <CJK>
0x373D	0x65B9	# <CJK>
0x373E	0x80AA	# <CJK>
0x373F	0x623F	# <CJK>
0x3740	0x9632	# <CJK>
0x3741	0x59A8	# <CJK>
0x3742	0x4EFF	# <CJK>
0x3743	0x8BBF	# <CJK>
0x3744	0x7EBA	# <CJK>
0x3745	0x653E	# <CJK>
0x3746	0x83F2	# <CJK>
0x3747	0x975E	# <CJK>
0x3748	0x5561	# <CJK>
0x3749	0x98DE	# <CJK>
0x374A	0x80A5	# <CJK>
0x374B	0x532A	# <CJK>
0x374C	0x8BFD	# <CJK>
0x374D	0x5420	# <CJK>
0x374E	0x80BA	# <CJK>
0x374F	0x5E9F	# <CJK>
0x3750	0x6CB8	# <CJK>
0x3751	0x8D39	# <CJK>
0x3752	0x82AC	# <CJK>
0x3753	0x915A	# <CJK>
0x3754	0x5429	# <CJK>
0x3755	0x6C1B	# <CJK>
0x3756	0x5206	# <CJK>
0x3757	0x7EB7	# <CJK>
0x3758	0x575F	# <CJK>
0x3759	0x711A	# <CJK>
0x375A	0x6C7E	# <CJK>
0x375B	0x7C89	# <CJK>
0x375C	0x594B	# <CJK>
0x375D	0x4EFD	# <CJK>
0x375E	0x5FFF	# <CJK>
0x375F	0x6124	# <CJK>
0x3760	0x7CAA	# <CJK>
0x3761	0x4E30	# <CJK>
0x3762	0x5C01	# <CJK>
0x3763	0x67AB	# <CJK>
0x3764	0x8702	# <CJK>
0x3765	0x5CF0	# <CJK>
0x3766	0x950B	# <CJK>
0x3767	0x98CE	# <CJK>
0x3768	0x75AF	# <CJK>
0x3769	0x70FD	# <CJK>
0x376A	0x9022	# <CJK>
0x376B	0x51AF	# <CJK>
0x376C	0x7F1D	# <CJK>
0x376D	0x8BBD	# <CJK>
0x376E	0x5949	# <CJK>
0x376F	0x51E4	# <CJK>
0x3770	0x4F5B	# <CJK>
0x3771	0x5426	# <CJK>
0x3772	0x592B	# <CJK>
0x3773	0x6577	# <CJK>
0x3774	0x80A4	# <CJK>
0x3775	0x5B75	# <CJK>
0x3776	0x6276	# <CJK>
0x3777	0x62C2	# <CJK>
0x3778	0x8F90	# <CJK>
0x3779	0x5E45	# <CJK>
0x377A	0x6C1F	# <CJK>
0x377B	0x7B26	# <CJK>
0x377C	0x4F0F	# <CJK>
0x377D	0x4FD8	# <CJK>
0x377E	0x670D	# <CJK>
0x3821	0x6D6E	# <CJK>
0x3822	0x6DAA	# <CJK>
0x3823	0x798F	# <CJK>
0x3824	0x88B1	# <CJK>
0x3825	0x5F17	# <CJK>
0x3826	0x752B	# <CJK>
0x3827	0x629A	# <CJK>
0x3828	0x8F85	# <CJK>
0x3829	0x4FEF	# <CJK>
0x382A	0x91DC	# <CJK>
0x382B	0x65A7	# <CJK>
0x382C	0x812F	# <CJK>
0x382D	0x8151	# <CJK>
0x382E	0x5E9C	# <CJK>
0x382F	0x8150	# <CJK>
0x3830	0x8D74	# <CJK>
0x3831	0x526F	# <CJK>
0x3832	0x8986	# <CJK>
0x3833	0x8D4B	# <CJK>
0x3834	0x590D	# <CJK>
0x3835	0x5085	# <CJK>
0x3836	0x4ED8	# <CJK>
0x3837	0x961C	# <CJK>
0x3838	0x7236	# <CJK>
0x3839	0x8179	# <CJK>
0x383A	0x8D1F	# <CJK>
0x383B	0x5BCC	# <CJK>
0x383C	0x8BA3	# <CJK>
0x383D	0x9644	# <CJK>
0x383E	0x5987	# <CJK>
0x383F	0x7F1A	# <CJK>
0x3840	0x5490	# <CJK>
0x3841	0x5676	# <CJK>
0x3842	0x560E	# <CJK>
0x3843	0x8BE5	# <CJK>
0x3844	0x6539	# <CJK>
0x3845	0x6982	# <CJK>
0x3846	0x9499	# <CJK>
0x3847	0x76D6	# <CJK>
0x3848	0x6E89	# <CJK>
0x3849	0x5E72	# <CJK>
0x384A	0x7518	# <CJK>
0x384B	0x6746	# <CJK>
0x384C	0x67D1	# <CJK>
0x384D	0x7AFF	# <CJK>
0x384E	0x809D	# <CJK>
0x384F	0x8D76	# <CJK>
0x3850	0x611F	# <CJK>
0x3851	0x79C6	# <CJK>
0x3852	0x6562	# <CJK>
0x3853	0x8D63	# <CJK>
0x3854	0x5188	# <CJK>
0x3855	0x521A	# <CJK>
0x3856	0x94A2	# <CJK>
0x3857	0x7F38	# <CJK>
0x3858	0x809B	# <CJK>
0x3859	0x7EB2	# <CJK>
0x385A	0x5C97	# <CJK>
0x385B	0x6E2F	# <CJK>
0x385C	0x6760	# <CJK>
0x385D	0x7BD9	# <CJK>
0x385E	0x768B	# <CJK>
0x385F	0x9AD8	# <CJK>
0x3860	0x818F	# <CJK>
0x3861	0x7F94	# <CJK>
0x3862	0x7CD5	# <CJK>
0x3863	0x641E	# <CJK>
0x3864	0x9550	# <CJK>
0x3865	0x7A3F	# <CJK>
0x3866	0x544A	# <CJK>
0x3867	0x54E5	# <CJK>
0x3868	0x6B4C	# <CJK>
0x3869	0x6401	# <CJK>
0x386A	0x6208	# <CJK>
0x386B	0x9E3D	# <CJK>
0x386C	0x80F3	# <CJK>
0x386D	0x7599	# <CJK>
0x386E	0x5272	# <CJK>
0x386F	0x9769	# <CJK>
0x3870	0x845B	# <CJK>
0x3871	0x683C	# <CJK>
0x3872	0x86E4	# <CJK>
0x3873	0x9601	# <CJK>
0x3874	0x9694	# <CJK>
0x3875	0x94EC	# <CJK>
0x3876	0x4E2A	# <CJK>
0x3877	0x5404	# <CJK>
0x3878	0x7ED9	# <CJK>
0x3879	0x6839	# <CJK>
0x387A	0x8DDF	# <CJK>
0x387B	0x8015	# <CJK>
0x387C	0x66F4	# <CJK>
0x387D	0x5E9A	# <CJK>
0x387E	0x7FB9	# <CJK>
0x3921	0x57C2	# <CJK>
0x3922	0x803F	# <CJK>
0x3923	0x6897	# <CJK>
0x3924	0x5DE5	# <CJK>
0x3925	0x653B	# <CJK>
0x3926	0x529F	# <CJK>
0x3927	0x606D	# <CJK>
0x3928	0x9F9A	# <CJK>
0x3929	0x4F9B	# <CJK>
0x392A	0x8EAC	# <CJK>
0x392B	0x516C	# <CJK>
0x392C	0x5BAB	# <CJK>
0x392D	0x5F13	# <CJK>
0x392E	0x5DE9	# <CJK>
0x392F	0x6C5E	# <CJK>
0x3930	0x62F1	# <CJK>
0x3931	0x8D21	# <CJK>
0x3932	0x5171	# <CJK>
0x3933	0x94A9	# <CJK>
0x3934	0x52FE	# <CJK>
0x3935	0x6C9F	# <CJK>
0x3936	0x82DF	# <CJK>
0x3937	0x72D7	# <CJK>
0x3938	0x57A2	# <CJK>
0x3939	0x6784	# <CJK>
0x393A	0x8D2D	# <CJK>
0x393B	0x591F	# <CJK>
0x393C	0x8F9C	# <CJK>
0x393D	0x83C7	# <CJK>
0x393E	0x5495	# <CJK>
0x393F	0x7B8D	# <CJK>
0x3940	0x4F30	# <CJK>
0x3941	0x6CBD	# <CJK>
0x3942	0x5B64	# <CJK>
0x3943	0x59D1	# <CJK>
0x3944	0x9F13	# <CJK>
0x3945	0x53E4	# <CJK>
0x3946	0x86CA	# <CJK>
0x3947	0x9AA8	# <CJK>
0x3948	0x8C37	# <CJK>
0x3949	0x80A1	# <CJK>
0x394A	0x6545	# <CJK>
0x394B	0x987E	# <CJK>
0x394C	0x56FA	# <CJK>
0x394D	0x96C7	# <CJK>
0x394E	0x522E	# <CJK>
0x394F	0x74DC	# <CJK>
0x3950	0x5250	# <CJK>
0x3951	0x5BE1	# <CJK>
0x3952	0x6302	# <CJK>
0x3953	0x8902	# <CJK>
0x3954	0x4E56	# <CJK>
0x3955	0x62D0	# <CJK>
0x3956	0x602A	# <CJK>
0x3957	0x68FA	# <CJK>
0x3958	0x5173	# <CJK>
0x3959	0x5B98	# <CJK>
0x395A	0x51A0	# <CJK>
0x395B	0x89C2	# <CJK>
0x395C	0x7BA1	# <CJK>
0x395D	0x9986	# <CJK>
0x395E	0x7F50	# <CJK>
0x395F	0x60EF	# <CJK>
0x3960	0x704C	# <CJK>
0x3961	0x8D2F	# <CJK>
0x3962	0x5149	# <CJK>
0x3963	0x5E7F	# <CJK>
0x3964	0x901B	# <CJK>
0x3965	0x7470	# <CJK>
0x3966	0x89C4	# <CJK>
0x3967	0x572D	# <CJK>
0x3968	0x7845	# <CJK>
0x3969	0x5F52	# <CJK>
0x396A	0x9F9F	# <CJK>
0x396B	0x95FA	# <CJK>
0x396C	0x8F68	# <CJK>
0x396D	0x9B3C	# <CJK>
0x396E	0x8BE1	# <CJK>
0x396F	0x7678	# <CJK>
0x3970	0x6842	# <CJK>
0x3971	0x67DC	# <CJK>
0x3972	0x8DEA	# <CJK>
0x3973	0x8D35	# <CJK>
0x3974	0x523D	# <CJK>
0x3975	0x8F8A	# <CJK>
0x3976	0x6EDA	# <CJK>
0x3977	0x68CD	# <CJK>
0x3978	0x9505	# <CJK>
0x3979	0x90ED	# <CJK>
0x397A	0x56FD	# <CJK>
0x397B	0x679C	# <CJK>
0x397C	0x88F9	# <CJK>
0x397D	0x8FC7	# <CJK>
0x397E	0x54C8	# <CJK>
0x3A21	0x9AB8	# <CJK>
0x3A22	0x5B69	# <CJK>
0x3A23	0x6D77	# <CJK>
0x3A24	0x6C26	# <CJK>
0x3A25	0x4EA5	# <CJK>
0x3A26	0x5BB3	# <CJK>
0x3A27	0x9A87	# <CJK>
0x3A28	0x9163	# <CJK>
0x3A29	0x61A8	# <CJK>
0x3A2A	0x90AF	# <CJK>
0x3A2B	0x97E9	# <CJK>
0x3A2C	0x542B	# <CJK>
0x3A2D	0x6DB5	# <CJK>
0x3A2E	0x5BD2	# <CJK>
0x3A2F	0x51FD	# <CJK>
0x3A30	0x558A	# <CJK>
0x3A31	0x7F55	# <CJK>
0x3A32	0x7FF0	# <CJK>
0x3A33	0x64BC	# <CJK>
0x3A34	0x634D	# <CJK>
0x3A35	0x65F1	# <CJK>
0x3A36	0x61BE	# <CJK>
0x3A37	0x608D	# <CJK>
0x3A38	0x710A	# <CJK>
0x3A39	0x6C57	# <CJK>
0x3A3A	0x6C49	# <CJK>
0x3A3B	0x592F	# <CJK>
0x3A3C	0x676D	# <CJK>
0x3A3D	0x822A	# <CJK>
0x3A3E	0x58D5	# <CJK>
0x3A3F	0x568E	# <CJK>
0x3A40	0x8C6A	# <CJK>
0x3A41	0x6BEB	# <CJK>
0x3A42	0x90DD	# <CJK>
0x3A43	0x597D	# <CJK>
0x3A44	0x8017	# <CJK>
0x3A45	0x53F7	# <CJK>
0x3A46	0x6D69	# <CJK>
0x3A47	0x5475	# <CJK>
0x3A48	0x559D	# <CJK>
0x3A49	0x8377	# <CJK>
0x3A4A	0x83CF	# <CJK>
0x3A4B	0x6838	# <CJK>
0x3A4C	0x79BE	# <CJK>
0x3A4D	0x548C	# <CJK>
0x3A4E	0x4F55	# <CJK>
0x3A4F	0x5408	# <CJK>
0x3A50	0x76D2	# <CJK>
0x3A51	0x8C89	# <CJK>
0x3A52	0x9602	# <CJK>
0x3A53	0x6CB3	# <CJK>
0x3A54	0x6DB8	# <CJK>
0x3A55	0x8D6B	# <CJK>
0x3A56	0x8910	# <CJK>
0x3A57	0x9E64	# <CJK>
0x3A58	0x8D3A	# <CJK>
0x3A59	0x563F	# <CJK>
0x3A5A	0x9ED1	# <CJK>
0x3A5B	0x75D5	# <CJK>
0x3A5C	0x5F88	# <CJK>
0x3A5D	0x72E0	# <CJK>
0x3A5E	0x6068	# <CJK>
0x3A5F	0x54FC	# <CJK>
0x3A60	0x4EA8	# <CJK>
0x3A61	0x6A2A	# <CJK>
0x3A62	0x8861	# <CJK>
0x3A63	0x6052	# <CJK>
0x3A64	0x8F70	# <CJK>
0x3A65	0x54C4	# <CJK>
0x3A66	0x70D8	# <CJK>
0x3A67	0x8679	# <CJK>
0x3A68	0x9E3F	# <CJK>
0x3A69	0x6D2A	# <CJK>
0x3A6A	0x5B8F	# <CJK>
0x3A6B	0x5F18	# <CJK>
0x3A6C	0x7EA2	# <CJK>
0x3A6D	0x5589	# <CJK>
0x3A6E	0x4FAF	# <CJK>
0x3A6F	0x7334	# <CJK>
0x3A70	0x543C	# <CJK>
0x3A71	0x539A	# <CJK>
0x3A72	0x5019	# <CJK>
0x3A73	0x540E	# <CJK>
0x3A74	0x547C	# <CJK>
0x3A75	0x4E4E	# <CJK>
0x3A76	0x5FFD	# <CJK>
0x3A77	0x745A	# <CJK>
0x3A78	0x58F6	# <CJK>
0x3A79	0x846B	# <CJK>
0x3A7A	0x80E1	# <CJK>
0x3A7B	0x8774	# <CJK>
0x3A7C	0x72D0	# <CJK>
0x3A7D	0x7CCA	# <CJK>
0x3A7E	0x6E56	# <CJK>
0x3B21	0x5F27	# <CJK>
0x3B22	0x864E	# <CJK>
0x3B23	0x552C	# <CJK>
0x3B24	0x62A4	# <CJK>
0x3B25	0x4E92	# <CJK>
0x3B26	0x6CAA	# <CJK>
0x3B27	0x6237	# <CJK>
0x3B28	0x82B1	# <CJK>
0x3B29	0x54D7	# <CJK>
0x3B2A	0x534E	# <CJK>
0x3B2B	0x733E	# <CJK>
0x3B2C	0x6ED1	# <CJK>
0x3B2D	0x753B	# <CJK>
0x3B2E	0x5212	# <CJK>
0x3B2F	0x5316	# <CJK>
0x3B30	0x8BDD	# <CJK>
0x3B31	0x69D0	# <CJK>
0x3B32	0x5F8A	# <CJK>
0x3B33	0x6000	# <CJK>
0x3B34	0x6DEE	# <CJK>
0x3B35	0x574F	# <CJK>
0x3B36	0x6B22	# <CJK>
0x3B37	0x73AF	# <CJK>
0x3B38	0x6853	# <CJK>
0x3B39	0x8FD8	# <CJK>
0x3B3A	0x7F13	# <CJK>
0x3B3B	0x6362	# <CJK>
0x3B3C	0x60A3	# <CJK>
0x3B3D	0x5524	# <CJK>
0x3B3E	0x75EA	# <CJK>
0x3B3F	0x8C62	# <CJK>
0x3B40	0x7115	# <CJK>
0x3B41	0x6DA3	# <CJK>
0x3B42	0x5BA6	# <CJK>
0x3B43	0x5E7B	# <CJK>
0x3B44	0x8352	# <CJK>
0x3B45	0x614C	# <CJK>
0x3B46	0x9EC4	# <CJK>
0x3B47	0x78FA	# <CJK>
0x3B48	0x8757	# <CJK>
0x3B49	0x7C27	# <CJK>
0x3B4A	0x7687	# <CJK>
0x3B4B	0x51F0	# <CJK>
0x3B4C	0x60F6	# <CJK>
0x3B4D	0x714C	# <CJK>
0x3B4E	0x6643	# <CJK>
0x3B4F	0x5E4C	# <CJK>
0x3B50	0x604D	# <CJK>
0x3B51	0x8C0E	# <CJK>
0x3B52	0x7070	# <CJK>
0x3B53	0x6325	# <CJK>
0x3B54	0x8F89	# <CJK>
0x3B55	0x5FBD	# <CJK>
0x3B56	0x6062	# <CJK>
0x3B57	0x86D4	# <CJK>
0x3B58	0x56DE	# <CJK>
0x3B59	0x6BC1	# <CJK>
0x3B5A	0x6094	# <CJK>
0x3B5B	0x6167	# <CJK>
0x3B5C	0x5349	# <CJK>
0x3B5D	0x60E0	# <CJK>
0x3B5E	0x6666	# <CJK>
0x3B5F	0x8D3F	# <CJK>
0x3B60	0x79FD	# <CJK>
0x3B61	0x4F1A	# <CJK>
0x3B62	0x70E9	# <CJK>
0x3B63	0x6C47	# <CJK>
0x3B64	0x8BB3	# <CJK>
0x3B65	0x8BF2	# <CJK>
0x3B66	0x7ED8	# <CJK>
0x3B67	0x8364	# <CJK>
0x3B68	0x660F	# <CJK>
0x3B69	0x5A5A	# <CJK>
0x3B6A	0x9B42	# <CJK>
0x3B6B	0x6D51	# <CJK>
0x3B6C	0x6DF7	# <CJK>
0x3B6D	0x8C41	# <CJK>
0x3B6E	0x6D3B	# <CJK>
0x3B6F	0x4F19	# <CJK>
0x3B70	0x706B	# <CJK>
0x3B71	0x83B7	# <CJK>
0x3B72	0x6216	# <CJK>
0x3B73	0x60D1	# <CJK>
0x3B74	0x970D	# <CJK>
0x3B75	0x8D27	# <CJK>
0x3B76	0x7978	# <CJK>
0x3B77	0x51FB	# <CJK>
0x3B78	0x573E	# <CJK>
0x3B79	0x57FA	# <CJK>
0x3B7A	0x673A	# <CJK>
0x3B7B	0x7578	# <CJK>
0x3B7C	0x7A3D	# <CJK>
0x3B7D	0x79EF	# <CJK>
0x3B7E	0x7B95	# <CJK>
0x3C21	0x808C	# <CJK>
0x3C22	0x9965	# <CJK>
0x3C23	0x8FF9	# <CJK>
0x3C24	0x6FC0	# <CJK>
0x3C25	0x8BA5	# <CJK>
0x3C26	0x9E21	# <CJK>
0x3C27	0x59EC	# <CJK>
0x3C28	0x7EE9	# <CJK>
0x3C29	0x7F09	# <CJK>
0x3C2A	0x5409	# <CJK>
0x3C2B	0x6781	# <CJK>
0x3C2C	0x68D8	# <CJK>
0x3C2D	0x8F91	# <CJK>
0x3C2E	0x7C4D	# <CJK>
0x3C2F	0x96C6	# <CJK>
0x3C30	0x53CA	# <CJK>
0x3C31	0x6025	# <CJK>
0x3C32	0x75BE	# <CJK>
0x3C33	0x6C72	# <CJK>
0x3C34	0x5373	# <CJK>
0x3C35	0x5AC9	# <CJK>
0x3C36	0x7EA7	# <CJK>
0x3C37	0x6324	# <CJK>
0x3C38	0x51E0	# <CJK>
0x3C39	0x810A	# <CJK>
0x3C3A	0x5DF1	# <CJK>
0x3C3B	0x84DF	# <CJK>
0x3C3C	0x6280	# <CJK>
0x3C3D	0x5180	# <CJK>
0x3C3E	0x5B63	# <CJK>
0x3C3F	0x4F0E	# <CJK>
0x3C40	0x796D	# <CJK>
0x3C41	0x5242	# <CJK>
0x3C42	0x60B8	# <CJK>
0x3C43	0x6D4E	# <CJK>
0x3C44	0x5BC4	# <CJK>
0x3C45	0x5BC2	# <CJK>
0x3C46	0x8BA1	# <CJK>
0x3C47	0x8BB0	# <CJK>
0x3C48	0x65E2	# <CJK>
0x3C49	0x5FCC	# <CJK>
0x3C4A	0x9645	# <CJK>
0x3C4B	0x5993	# <CJK>
0x3C4C	0x7EE7	# <CJK>
0x3C4D	0x7EAA	# <CJK>
0x3C4E	0x5609	# <CJK>
0x3C4F	0x67B7	# <CJK>
0x3C50	0x5939	# <CJK>
0x3C51	0x4F73	# <CJK>
0x3C52	0x5BB6	# <CJK>
0x3C53	0x52A0	# <CJK>
0x3C54	0x835A	# <CJK>
0x3C55	0x988A	# <CJK>
0x3C56	0x8D3E	# <CJK>
0x3C57	0x7532	# <CJK>
0x3C58	0x94BE	# <CJK>
0x3C59	0x5047	# <CJK>
0x3C5A	0x7A3C	# <CJK>
0x3C5B	0x4EF7	# <CJK>
0x3C5C	0x67B6	# <CJK>
0x3C5D	0x9A7E	# <CJK>
0x3C5E	0x5AC1	# <CJK>
0x3C5F	0x6B7C	# <CJK>
0x3C60	0x76D1	# <CJK>
0x3C61	0x575A	# <CJK>
0x3C62	0x5C16	# <CJK>
0x3C63	0x7B3A	# <CJK>
0x3C64	0x95F4	# <CJK>
0x3C65	0x714E	# <CJK>
0x3C66	0x517C	# <CJK>
0x3C67	0x80A9	# <CJK>
0x3C68	0x8270	# <CJK>
0x3C69	0x5978	# <CJK>
0x3C6A	0x7F04	# <CJK>
0x3C6B	0x8327	# <CJK>
0x3C6C	0x68C0	# <CJK>
0x3C6D	0x67EC	# <CJK>
0x3C6E	0x78B1	# <CJK>
0x3C6F	0x7877	# <CJK>
0x3C70	0x62E3	# <CJK>
0x3C71	0x6361	# <CJK>
0x3C72	0x7B80	# <CJK>
0x3C73	0x4FED	# <CJK>
0x3C74	0x526A	# <CJK>
0x3C75	0x51CF	# <CJK>
0x3C76	0x8350	# <CJK>
0x3C77	0x69DB	# <CJK>
0x3C78	0x9274	# <CJK>
0x3C79	0x8DF5	# <CJK>
0x3C7A	0x8D31	# <CJK>
0x3C7B	0x89C1	# <CJK>
0x3C7C	0x952E	# <CJK>
0x3C7D	0x7BAD	# <CJK>
0x3C7E	0x4EF6	# <CJK>
0x3D21	0x5065	# <CJK>
0x3D22	0x8230	# <CJK>
0x3D23	0x5251	# <CJK>
0x3D24	0x996F	# <CJK>
0x3D25	0x6E10	# <CJK>
0x3D26	0x6E85	# <CJK>
0x3D27	0x6DA7	# <CJK>
0x3D28	0x5EFA	# <CJK>
0x3D29	0x50F5	# <CJK>
0x3D2A	0x59DC	# <CJK>
0x3D2B	0x5C06	# <CJK>
0x3D2C	0x6D46	# <CJK>
0x3D2D	0x6C5F	# <CJK>
0x3D2E	0x7586	# <CJK>
0x3D2F	0x848B	# <CJK>
0x3D30	0x6868	# <CJK>
0x3D31	0x5956	# <CJK>
0x3D32	0x8BB2	# <CJK>
0x3D33	0x5320	# <CJK>
0x3D34	0x9171	# <CJK>
0x3D35	0x964D	# <CJK>
0x3D36	0x8549	# <CJK>
0x3D37	0x6912	# <CJK>
0x3D38	0x7901	# <CJK>
0x3D39	0x7126	# <CJK>
0x3D3A	0x80F6	# <CJK>
0x3D3B	0x4EA4	# <CJK>
0x3D3C	0x90CA	# <CJK>
0x3D3D	0x6D47	# <CJK>
0x3D3E	0x9A84	# <CJK>
0x3D3F	0x5A07	# <CJK>
0x3D40	0x56BC	# <CJK>
0x3D41	0x6405	# <CJK>
0x3D42	0x94F0	# <CJK>
0x3D43	0x77EB	# <CJK>
0x3D44	0x4FA5	# <CJK>
0x3D45	0x811A	# <CJK>
0x3D46	0x72E1	# <CJK>
0x3D47	0x89D2	# <CJK>
0x3D48	0x997A	# <CJK>
0x3D49	0x7F34	# <CJK>
0x3D4A	0x7EDE	# <CJK>
0x3D4B	0x527F	# <CJK>
0x3D4C	0x6559	# <CJK>
0x3D4D	0x9175	# <CJK>
0x3D4E	0x8F7F	# <CJK>
0x3D4F	0x8F83	# <CJK>
0x3D50	0x53EB	# <CJK>
0x3D51	0x7A96	# <CJK>
0x3D52	0x63ED	# <CJK>
0x3D53	0x63A5	# <CJK>
0x3D54	0x7686	# <CJK>
0x3D55	0x79F8	# <CJK>
0x3D56	0x8857	# <CJK>
0x3D57	0x9636	# <CJK>
0x3D58	0x622A	# <CJK>
0x3D59	0x52AB	# <CJK>
0x3D5A	0x8282	# <CJK>
0x3D5B	0x6854	# <CJK>
0x3D5C	0x6770	# <CJK>
0x3D5D	0x6377	# <CJK>
0x3D5E	0x776B	# <CJK>
0x3D5F	0x7AED	# <CJK>
0x3D60	0x6D01	# <CJK>
0x3D61	0x7ED3	# <CJK>
0x3D62	0x89E3	# <CJK>
0x3D63	0x59D0	# <CJK>
0x3D64	0x6212	# <CJK>
0x3D65	0x85C9	# <CJK>
0x3D66	0x82A5	# <CJK>
0x3D67	0x754C	# <CJK>
0x3D68	0x501F	# <CJK>
0x3D69	0x4ECB	# <CJK>
0x3D6A	0x75A5	# <CJK>
0x3D6B	0x8BEB	# <CJK>
0x3D6C	0x5C4A	# <CJK>
0x3D6D	0x5DFE	# <CJK>
0x3D6E	0x7B4B	# <CJK>
0x3D6F	0x65A4	# <CJK>
0x3D70	0x91D1	# <CJK>
0x3D71	0x4ECA	# <CJK>
0x3D72	0x6D25	# <CJK>
0x3D73	0x895F	# <CJK>
0x3D74	0x7D27	# <CJK>
0x3D75	0x9526	# <CJK>
0x3D76	0x4EC5	# <CJK>
0x3D77	0x8C28	# <CJK>
0x3D78	0x8FDB	# <CJK>
0x3D79	0x9773	# <CJK>
0x3D7A	0x664B	# <CJK>
0x3D7B	0x7981	# <CJK>
0x3D7C	0x8FD1	# <CJK>
0x3D7D	0x70EC	# <CJK>
0x3D7E	0x6D78	# <CJK>
0x3E21	0x5C3D	# <CJK>
0x3E22	0x52B2	# <CJK>
0x3E23	0x8346	# <CJK>
0x3E24	0x5162	# <CJK>
0x3E25	0x830E	# <CJK>
0x3E26	0x775B	# <CJK>
0x3E27	0x6676	# <CJK>
0x3E28	0x9CB8	# <CJK>
0x3E29	0x4EAC	# <CJK>
0x3E2A	0x60CA	# <CJK>
0x3E2B	0x7CBE	# <CJK>
0x3E2C	0x7CB3	# <CJK>
0x3E2D	0x7ECF	# <CJK>
0x3E2E	0x4E95	# <CJK>
0x3E2F	0x8B66	# <CJK>
0x3E30	0x666F	# <CJK>
0x3E31	0x9888	# <CJK>
0x3E32	0x9759	# <CJK>
0x3E33	0x5883	# <CJK>
0x3E34	0x656C	# <CJK>
0x3E35	0x955C	# <CJK>
0x3E36	0x5F84	# <CJK>
0x3E37	0x75C9	# <CJK>
0x3E38	0x9756	# <CJK>
0x3E39	0x7ADF	# <CJK>
0x3E3A	0x7ADE	# <CJK>
0x3E3B	0x51C0	# <CJK>
0x3E3C	0x70AF	# <CJK>
0x3E3D	0x7A98	# <CJK>
0x3E3E	0x63EA	# <CJK>
0x3E3F	0x7A76	# <CJK>
0x3E40	0x7EA0	# <CJK>
0x3E41	0x7396	# <CJK>
0x3E42	0x97ED	# <CJK>
0x3E43	0x4E45	# <CJK>
0x3E44	0x7078	# <CJK>
0x3E45	0x4E5D	# <CJK>
0x3E46	0x9152	# <CJK>
0x3E47	0x53A9	# <CJK>
0x3E48	0x6551	# <CJK>
0x3E49	0x65E7	# <CJK>
0x3E4A	0x81FC	# <CJK>
0x3E4B	0x8205	# <CJK>
0x3E4C	0x548E	# <CJK>
0x3E4D	0x5C31	# <CJK>
0x3E4E	0x759A	# <CJK>
0x3E4F	0x97A0	# <CJK>
0x3E50	0x62D8	# <CJK>
0x3E51	0x72D9	# <CJK>
0x3E52	0x75BD	# <CJK>
0x3E53	0x5C45	# <CJK>
0x3E54	0x9A79	# <CJK>
0x3E55	0x83CA	# <CJK>
0x3E56	0x5C40	# <CJK>
0x3E57	0x5480	# <CJK>
0x3E58	0x77E9	# <CJK>
0x3E59	0x4E3E	# <CJK>
0x3E5A	0x6CAE	# <CJK>
0x3E5B	0x805A	# <CJK>
0x3E5C	0x62D2	# <CJK>
0x3E5D	0x636E	# <CJK>
0x3E5E	0x5DE8	# <CJK>
0x3E5F	0x5177	# <CJK>
0x3E60	0x8DDD	# <CJK>
0x3E61	0x8E1E	# <CJK>
0x3E62	0x952F	# <CJK>
0x3E63	0x4FF1	# <CJK>
0x3E64	0x53E5	# <CJK>
0x3E65	0x60E7	# <CJK>
0x3E66	0x70AC	# <CJK>
0x3E67	0x5267	# <CJK>
0x3E68	0x6350	# <CJK>
0x3E69	0x9E43	# <CJK>
0x3E6A	0x5A1F	# <CJK>
0x3E6B	0x5026	# <CJK>
0x3E6C	0x7737	# <CJK>
0x3E6D	0x5377	# <CJK>
0x3E6E	0x7EE2	# <CJK>
0x3E6F	0x6485	# <CJK>
0x3E70	0x652B	# <CJK>
0x3E71	0x6289	# <CJK>
0x3E72	0x6398	# <CJK>
0x3E73	0x5014	# <CJK>
0x3E74	0x7235	# <CJK>
0x3E75	0x89C9	# <CJK>
0x3E76	0x51B3	# <CJK>
0x3E77	0x8BC0	# <CJK>
0x3E78	0x7EDD	# <CJK>
0x3E79	0x5747	# <CJK>
0x3E7A	0x83CC	# <CJK>
0x3E7B	0x94A7	# <CJK>
0x3E7C	0x519B	# <CJK>
0x3E7D	0x541B	# <CJK>
0x3E7E	0x5CFB	# <CJK>
0x3F21	0x4FCA	# <CJK>
0x3F22	0x7AE3	# <CJK>
0x3F23	0x6D5A	# <CJK>
0x3F24	0x90E1	# <CJK>
0x3F25	0x9A8F	# <CJK>
0x3F26	0x5580	# <CJK>
0x3F27	0x5496	# <CJK>
0x3F28	0x5361	# <CJK>
0x3F29	0x54AF	# <CJK>
0x3F2A	0x5F00	# <CJK>
0x3F2B	0x63E9	# <CJK>
0x3F2C	0x6977	# <CJK>
0x3F2D	0x51EF	# <CJK>
0x3F2E	0x6168	# <CJK>
0x3F2F	0x520A	# <CJK>
0x3F30	0x582A	# <CJK>
0x3F31	0x52D8	# <CJK>
0x3F32	0x574E	# <CJK>
0x3F33	0x780D	# <CJK>
0x3F34	0x770B	# <CJK>
0x3F35	0x5EB7	# <CJK>
0x3F36	0x6177	# <CJK>
0x3F37	0x7CE0	# <CJK>
0x3F38	0x625B	# <CJK>
0x3F39	0x6297	# <CJK>
0x3F3A	0x4EA2	# <CJK>
0x3F3B	0x7095	# <CJK>
0x3F3C	0x8003	# <CJK>
0x3F3D	0x62F7	# <CJK>
0x3F3E	0x70E4	# <CJK>
0x3F3F	0x9760	# <CJK>
0x3F40	0x5777	# <CJK>
0x3F41	0x82DB	# <CJK>
0x3F42	0x67EF	# <CJK>
0x3F43	0x68F5	# <CJK>
0x3F44	0x78D5	# <CJK>
0x3F45	0x9897	# <CJK>
0x3F46	0x79D1	# <CJK>
0x3F47	0x58F3	# <CJK>
0x3F48	0x54B3	# <CJK>
0x3F49	0x53EF	# <CJK>
0x3F4A	0x6E34	# <CJK>
0x3F4B	0x514B	# <CJK>
0x3F4C	0x523B	# <CJK>
0x3F4D	0x5BA2	# <CJK>
0x3F4E	0x8BFE	# <CJK>
0x3F4F	0x80AF	# <CJK>
0x3F50	0x5543	# <CJK>
0x3F51	0x57A6	# <CJK>
0x3F52	0x6073	# <CJK>
0x3F53	0x5751	# <CJK>
0x3F54	0x542D	# <CJK>
0x3F55	0x7A7A	# <CJK>
0x3F56	0x6050	# <CJK>
0x3F57	0x5B54	# <CJK>
0x3F58	0x63A7	# <CJK>
0x3F59	0x62A0	# <CJK>
0x3F5A	0x53E3	# <CJK>
0x3F5B	0x6263	# <CJK>
0x3F5C	0x5BC7	# <CJK>
0x3F5D	0x67AF	# <CJK>
0x3F5E	0x54ED	# <CJK>
0x3F5F	0x7A9F	# <CJK>
0x3F60	0x82E6	# <CJK>
0x3F61	0x9177	# <CJK>
0x3F62	0x5E93	# <CJK>
0x3F63	0x88E4	# <CJK>
0x3F64	0x5938	# <CJK>
0x3F65	0x57AE	# <CJK>
0x3F66	0x630E	# <CJK>
0x3F67	0x8DE8	# <CJK>
0x3F68	0x80EF	# <CJK>
0x3F69	0x5757	# <CJK>
0x3F6A	0x7B77	# <CJK>
0x3F6B	0x4FA9	# <CJK>
0x3F6C	0x5FEB	# <CJK>
0x3F6D	0x5BBD	# <CJK>
0x3F6E	0x6B3E	# <CJK>
0x3F6F	0x5321	# <CJK>
0x3F70	0x7B50	# <CJK>
0x3F71	0x72C2	# <CJK>
0x3F72	0x6846	# <CJK>
0x3F73	0x77FF	# <CJK>
0x3F74	0x7736	# <CJK>
0x3F75	0x65F7	# <CJK>
0x3F76	0x51B5	# <CJK>
0x3F77	0x4E8F	# <CJK>
0x3F78	0x76D4	# <CJK>
0x3F79	0x5CBF	# <CJK>
0x3F7A	0x7AA5	# <CJK>
0x3F7B	0x8475	# <CJK>
0x3F7C	0x594E	# <CJK>
0x3F7D	0x9B41	# <CJK>
0x3F7E	0x5080	# <CJK>
0x4021	0x9988	# <CJK>
0x4022	0x6127	# <CJK>
0x4023	0x6E83	# <CJK>
0x4024	0x5764	# <CJK>
0x4025	0x6606	# <CJK>
0x4026	0x6346	# <CJK>
0x4027	0x56F0	# <CJK>
0x4028	0x62EC	# <CJK>
0x4029	0x6269	# <CJK>
0x402A	0x5ED3	# <CJK>
0x402B	0x9614	# <CJK>
0x402C	0x5783	# <CJK>
0x402D	0x62C9	# <CJK>
0x402E	0x5587	# <CJK>
0x402F	0x8721	# <CJK>
0x4030	0x814A	# <CJK>
0x4031	0x8FA3	# <CJK>
0x4032	0x5566	# <CJK>
0x4033	0x83B1	# <CJK>
0x4034	0x6765	# <CJK>
0x4035	0x8D56	# <CJK>
0x4036	0x84DD	# <CJK>
0x4037	0x5A6A	# <CJK>
0x4038	0x680F	# <CJK>
0x4039	0x62E6	# <CJK>
0x403A	0x7BEE	# <CJK>
0x403B	0x9611	# <CJK>
0x403C	0x5170	# <CJK>
0x403D	0x6F9C	# <CJK>
0x403E	0x8C30	# <CJK>
0x403F	0x63FD	# <CJK>
0x4040	0x89C8	# <CJK>
0x4041	0x61D2	# <CJK>
0x4042	0x7F06	# <CJK>
0x4043	0x70C2	# <CJK>
0x4044	0x6EE5	# <CJK>
0x4045	0x7405	# <CJK>
0x4046	0x6994	# <CJK>
0x4047	0x72FC	# <CJK>
0x4048	0x5ECA	# <CJK>
0x4049	0x90CE	# <CJK>
0x404A	0x6717	# <CJK>
0x404B	0x6D6A	# <CJK>
0x404C	0x635E	# <CJK>
0x404D	0x52B3	# <CJK>
0x404E	0x7262	# <CJK>
0x404F	0x8001	# <CJK>
0x4050	0x4F6C	# <CJK>
0x4051	0x59E5	# <CJK>
0x4052	0x916A	# <CJK>
0x4053	0x70D9	# <CJK>
0x4054	0x6D9D	# <CJK>
0x4055	0x52D2	# <CJK>
0x4056	0x4E50	# <CJK>
0x4057	0x96F7	# <CJK>
0x4058	0x956D	# <CJK>
0x4059	0x857E	# <CJK>
0x405A	0x78CA	# <CJK>
0x405B	0x7D2F	# <CJK>
0x405C	0x5121	# <CJK>
0x405D	0x5792	# <CJK>
0x405E	0x64C2	# <CJK>
0x405F	0x808B	# <CJK>
0x4060	0x7C7B	# <CJK>
0x4061	0x6CEA	# <CJK>
0x4062	0x68F1	# <CJK>
0x4063	0x695E	# <CJK>
0x4064	0x51B7	# <CJK>
0x4065	0x5398	# <CJK>
0x4066	0x68A8	# <CJK>
0x4067	0x7281	# <CJK>
0x4068	0x9ECE	# <CJK>
0x4069	0x7BF1	# <CJK>
0x406A	0x72F8	# <CJK>
0x406B	0x79BB	# <CJK>
0x406C	0x6F13	# <CJK>
0x406D	0x7406	# <CJK>
0x406E	0x674E	# <CJK>
0x406F	0x91CC	# <CJK>
0x4070	0x9CA4	# <CJK>
0x4071	0x793C	# <CJK>
0x4072	0x8389	# <CJK>
0x4073	0x8354	# <CJK>
0x4074	0x540F	# <CJK>
0x4075	0x6817	# <CJK>
0x4076	0x4E3D	# <CJK>
0x4077	0x5389	# <CJK>
0x4078	0x52B1	# <CJK>
0x4079	0x783E	# <CJK>
0x407A	0x5386	# <CJK>
0x407B	0x5229	# <CJK>
0x407C	0x5088	# <CJK>
0x407D	0x4F8B	# <CJK>
0x407E	0x4FD0	# <CJK>
0x4121	0x75E2	# <CJK>
0x4122	0x7ACB	# <CJK>
0x4123	0x7C92	# <CJK>
0x4124	0x6CA5	# <CJK>
0x4125	0x96B6	# <CJK>
0x4126	0x529B	# <CJK>
0x4127	0x7483	# <CJK>
0x4128	0x54E9	# <CJK>
0x4129	0x4FE9	# <CJK>
0x412A	0x8054	# <CJK>
0x412B	0x83B2	# <CJK>
0x412C	0x8FDE	# <CJK>
0x412D	0x9570	# <CJK>
0x412E	0x5EC9	# <CJK>
0x412F	0x601C	# <CJK>
0x4130	0x6D9F	# <CJK>
0x4131	0x5E18	# <CJK>
0x4132	0x655B	# <CJK>
0x4133	0x8138	# <CJK>
0x4134	0x94FE	# <CJK>
0x4135	0x604B	# <CJK>
0x4136	0x70BC	# <CJK>
0x4137	0x7EC3	# <CJK>
0x4138	0x7CAE	# <CJK>
0x4139	0x51C9	# <CJK>
0x413A	0x6881	# <CJK>
0x413B	0x7CB1	# <CJK>
0x413C	0x826F	# <CJK>
0x413D	0x4E24	# <CJK>
0x413E	0x8F86	# <CJK>
0x413F	0x91CF	# <CJK>
0x4140	0x667E	# <CJK>
0x4141	0x4EAE	# <CJK>
0x4142	0x8C05	# <CJK>
0x4143	0x64A9	# <CJK>
0x4144	0x804A	# <CJK>
0x4145	0x50DA	# <CJK>
0x4146	0x7597	# <CJK>
0x4147	0x71CE	# <CJK>
0x4148	0x5BE5	# <CJK>
0x4149	0x8FBD	# <CJK>
0x414A	0x6F66	# <CJK>
0x414B	0x4E86	# <CJK>
0x414C	0x6482	# <CJK>
0x414D	0x9563	# <CJK>
0x414E	0x5ED6	# <CJK>
0x414F	0x6599	# <CJK>
0x4150	0x5217	# <CJK>
0x4151	0x88C2	# <CJK>
0x4152	0x70C8	# <CJK>
0x4153	0x52A3	# <CJK>
0x4154	0x730E	# <CJK>
0x4155	0x7433	# <CJK>
0x4156	0x6797	# <CJK>
0x4157	0x78F7	# <CJK>
0x4158	0x9716	# <CJK>
0x4159	0x4E34	# <CJK>
0x415A	0x90BB	# <CJK>
0x415B	0x9CDE	# <CJK>
0x415C	0x6DCB	# <CJK>
0x415D	0x51DB	# <CJK>
0x415E	0x8D41	# <CJK>
0x415F	0x541D	# <CJK>
0x4160	0x62CE	# <CJK>
0x4161	0x73B2	# <CJK>
0x4162	0x83F1	# <CJK>
0x4163	0x96F6	# <CJK>
0x4164	0x9F84	# <CJK>
0x4165	0x94C3	# <CJK>
0x4166	0x4F36	# <CJK>
0x4167	0x7F9A	# <CJK>
0x4168	0x51CC	# <CJK>
0x4169	0x7075	# <CJK>
0x416A	0x9675	# <CJK>
0x416B	0x5CAD	# <CJK>
0x416C	0x9886	# <CJK>
0x416D	0x53E6	# <CJK>
0x416E	0x4EE4	# <CJK>
0x416F	0x6E9C	# <CJK>
0x4170	0x7409	# <CJK>
0x4171	0x69B4	# <CJK>
0x4172	0x786B	# <CJK>
0x4173	0x998F	# <CJK>
0x4174	0x7559	# <CJK>
0x4175	0x5218	# <CJK>
0x4176	0x7624	# <CJK>
0x4177	0x6D41	# <CJK>
0x4178	0x67F3	# <CJK>
0x4179	0x516D	# <CJK>
0x417A	0x9F99	# <CJK>
0x417B	0x804B	# <CJK>
0x417C	0x5499	# <CJK>
0x417D	0x7B3C	# <CJK>
0x417E	0x7ABF	# <CJK>
0x4221	0x9686	# <CJK>
0x4222	0x5784	# <CJK>
0x4223	0x62E2	# <CJK>
0x4224	0x9647	# <CJK>
0x4225	0x697C	# <CJK>
0x4226	0x5A04	# <CJK>
0x4227	0x6402	# <CJK>
0x4228	0x7BD3	# <CJK>
0x4229	0x6F0F	# <CJK>
0x422A	0x964B	# <CJK>
0x422B	0x82A6	# <CJK>
0x422C	0x5362	# <CJK>
0x422D	0x9885	# <CJK>
0x422E	0x5E90	# <CJK>
0x422F	0x7089	# <CJK>
0x4230	0x63B3	# <CJK>
0x4231	0x5364	# <CJK>
0x4232	0x864F	# <CJK>
0x4233	0x9C81	# <CJK>
0x4234	0x9E93	# <CJK>
0x4235	0x788C	# <CJK>
0x4236	0x9732	# <CJK>
0x4237	0x8DEF	# <CJK>
0x4238	0x8D42	# <CJK>
0x4239	0x9E7F	# <CJK>
0x423A	0x6F5E	# <CJK>
0x423B	0x7984	# <CJK>
0x423C	0x5F55	# <CJK>
0x423D	0x9646	# <CJK>
0x423E	0x622E	# <CJK>
0x423F	0x9A74	# <CJK>
0x4240	0x5415	# <CJK>
0x4241	0x94DD	# <CJK>
0x4242	0x4FA3	# <CJK>
0x4243	0x65C5	# <CJK>
0x4244	0x5C65	# <CJK>
0x4245	0x5C61	# <CJK>
0x4246	0x7F15	# <CJK>
0x4247	0x8651	# <CJK>
0x4248	0x6C2F	# <CJK>
0x4249	0x5F8B	# <CJK>
0x424A	0x7387	# <CJK>
0x424B	0x6EE4	# <CJK>
0x424C	0x7EFF	# <CJK>
0x424D	0x5CE6	# <CJK>
0x424E	0x631B	# <CJK>
0x424F	0x5B6A	# <CJK>
0x4250	0x6EE6	# <CJK>
0x4251	0x5375	# <CJK>
0x4252	0x4E71	# <CJK>
0x4253	0x63A0	# <CJK>
0x4254	0x7565	# <CJK>
0x4255	0x62A1	# <CJK>
0x4256	0x8F6E	# <CJK>
0x4257	0x4F26	# <CJK>
0x4258	0x4ED1	# <CJK>
0x4259	0x6CA6	# <CJK>
0x425A	0x7EB6	# <CJK>
0x425B	0x8BBA	# <CJK>
0x425C	0x841D	# <CJK>
0x425D	0x87BA	# <CJK>
0x425E	0x7F57	# <CJK>
0x425F	0x903B	# <CJK>
0x4260	0x9523	# <CJK>
0x4261	0x7BA9	# <CJK>
0x4262	0x9AA1	# <CJK>
0x4263	0x88F8	# <CJK>
0x4264	0x843D	# <CJK>
0x4265	0x6D1B	# <CJK>
0x4266	0x9A86	# <CJK>
0x4267	0x7EDC	# <CJK>
0x4268	0x5988	# <CJK>
0x4269	0x9EBB	# <CJK>
0x426A	0x739B	# <CJK>
0x426B	0x7801	# <CJK>
0x426C	0x8682	# <CJK>
0x426D	0x9A6C	# <CJK>
0x426E	0x9A82	# <CJK>
0x426F	0x561B	# <CJK>
0x4270	0x5417	# <CJK>
0x4271	0x57CB	# <CJK>
0x4272	0x4E70	# <CJK>
0x4273	0x9EA6	# <CJK>
0x4274	0x5356	# <CJK>
0x4275	0x8FC8	# <CJK>
0x4276	0x8109	# <CJK>
0x4277	0x7792	# <CJK>
0x4278	0x9992	# <CJK>
0x4279	0x86EE	# <CJK>
0x427A	0x6EE1	# <CJK>
0x427B	0x8513	# <CJK>
0x427C	0x66FC	# <CJK>
0x427D	0x6162	# <CJK>
0x427E	0x6F2B	# <CJK>
0x4321	0x8C29	# <CJK>
0x4322	0x8292	# <CJK>
0x4323	0x832B	# <CJK>
0x4324	0x76F2	# <CJK>
0x4325	0x6C13	# <CJK>
0x4326	0x5FD9	# <CJK>
0x4327	0x83BD	# <CJK>
0x4328	0x732B	# <CJK>
0x4329	0x8305	# <CJK>
0x432A	0x951A	# <CJK>
0x432B	0x6BDB	# <CJK>
0x432C	0x77DB	# <CJK>
0x432D	0x94C6	# <CJK>
0x432E	0x536F	# <CJK>
0x432F	0x8302	# <CJK>
0x4330	0x5192	# <CJK>
0x4331	0x5E3D	# <CJK>
0x4332	0x8C8C	# <CJK>
0x4333	0x8D38	# <CJK>
0x4334	0x4E48	# <CJK>
0x4335	0x73AB	# <CJK>
0x4336	0x679A	# <CJK>
0x4337	0x6885	# <CJK>
0x4338	0x9176	# <CJK>
0x4339	0x9709	# <CJK>
0x433A	0x7164	# <CJK>
0x433B	0x6CA1	# <CJK>
0x433C	0x7709	# <CJK>
0x433D	0x5A92	# <CJK>
0x433E	0x9541	# <CJK>
0x433F	0x6BCF	# <CJK>
0x4340	0x7F8E	# <CJK>
0x4341	0x6627	# <CJK>
0x4342	0x5BD0	# <CJK>
0x4343	0x59B9	# <CJK>
0x4344	0x5A9A	# <CJK>
0x4345	0x95E8	# <CJK>
0x4346	0x95F7	# <CJK>
0x4347	0x4EEC	# <CJK>
0x4348	0x840C	# <CJK>
0x4349	0x8499	# <CJK>
0x434A	0x6AAC	# <CJK>
0x434B	0x76DF	# <CJK>
0x434C	0x9530	# <CJK>
0x434D	0x731B	# <CJK>
0x434E	0x68A6	# <CJK>
0x434F	0x5B5F	# <CJK>
0x4350	0x772F	# <CJK>
0x4351	0x919A	# <CJK>
0x4352	0x9761	# <CJK>
0x4353	0x7CDC	# <CJK>
0x4354	0x8FF7	# <CJK>
0x4355	0x8C1C	# <CJK>
0x4356	0x5F25	# <CJK>
0x4357	0x7C73	# <CJK>
0x4358	0x79D8	# <CJK>
0x4359	0x89C5	# <CJK>
0x435A	0x6CCC	# <CJK>
0x435B	0x871C	# <CJK>
0x435C	0x5BC6	# <CJK>
0x435D	0x5E42	# <CJK>
0x435E	0x68C9	# <CJK>
0x435F	0x7720	# <CJK>
0x4360	0x7EF5	# <CJK>
0x4361	0x5195	# <CJK>
0x4362	0x514D	# <CJK>
0x4363	0x52C9	# <CJK>
0x4364	0x5A29	# <CJK>
0x4365	0x7F05	# <CJK>
0x4366	0x9762	# <CJK>
0x4367	0x82D7	# <CJK>
0x4368	0x63CF	# <CJK>
0x4369	0x7784	# <CJK>
0x436A	0x85D0	# <CJK>
0x436B	0x79D2	# <CJK>
0x436C	0x6E3A	# <CJK>
0x436D	0x5E99	# <CJK>
0x436E	0x5999	# <CJK>
0x436F	0x8511	# <CJK>
0x4370	0x706D	# <CJK>
0x4371	0x6C11	# <CJK>
0x4372	0x62BF	# <CJK>
0x4373	0x76BF	# <CJK>
0x4374	0x654F	# <CJK>
0x4375	0x60AF	# <CJK>
0x4376	0x95FD	# <CJK>
0x4377	0x660E	# <CJK>
0x4378	0x879F	# <CJK>
0x4379	0x9E23	# <CJK>
0x437A	0x94ED	# <CJK>
0x437B	0x540D	# <CJK>
0x437C	0x547D	# <CJK>
0x437D	0x8C2C	# <CJK>
0x437E	0x6478	# <CJK>
0x4421	0x6479	# <CJK>
0x4422	0x8611	# <CJK>
0x4423	0x6A21	# <CJK>
0x4424	0x819C	# <CJK>
0x4425	0x78E8	# <CJK>
0x4426	0x6469	# <CJK>
0x4427	0x9B54	# <CJK>
0x4428	0x62B9	# <CJK>
0x4429	0x672B	# <CJK>
0x442A	0x83AB	# <CJK>
0x442B	0x58A8	# <CJK>
0x442C	0x9ED8	# <CJK>
0x442D	0x6CAB	# <CJK>
0x442E	0x6F20	# <CJK>
0x442F	0x5BDE	# <CJK>
0x4430	0x964C	# <CJK>
0x4431	0x8C0B	# <CJK>
0x4432	0x725F	# <CJK>
0x4433	0x67D0	# <CJK>
0x4434	0x62C7	# <CJK>
0x4435	0x7261	# <CJK>
0x4436	0x4EA9	# <CJK>
0x4437	0x59C6	# <CJK>
0x4438	0x6BCD	# <CJK>
0x4439	0x5893	# <CJK>
0x443A	0x66AE	# <CJK>
0x443B	0x5E55	# <CJK>
0x443C	0x52DF	# <CJK>
0x443D	0x6155	# <CJK>
0x443E	0x6728	# <CJK>
0x443F	0x76EE	# <CJK>
0x4440	0x7766	# <CJK>
0x4441	0x7267	# <CJK>
0x4442	0x7A46	# <CJK>
0x4443	0x62FF	# <CJK>
0x4444	0x54EA	# <CJK>
0x4445	0x5450	# <CJK>
0x4446	0x94A0	# <CJK>
0x4447	0x90A3	# <CJK>
0x4448	0x5A1C	# <CJK>
0x4449	0x7EB3	# <CJK>
0x444A	0x6C16	# <CJK>
0x444B	0x4E43	# <CJK>
0x444C	0x5976	# <CJK>
0x444D	0x8010	# <CJK>
0x444E	0x5948	# <CJK>
0x444F	0x5357	# <CJK>
0x4450	0x7537	# <CJK>
0x4451	0x96BE	# <CJK>
0x4452	0x56CA	# <CJK>
0x4453	0x6320	# <CJK>
0x4454	0x8111	# <CJK>
0x4455	0x607C	# <CJK>
0x4456	0x95F9	# <CJK>
0x4457	0x6DD6	# <CJK>
0x4458	0x5462	# <CJK>
0x4459	0x9981	# <CJK>
0x445A	0x5185	# <CJK>
0x445B	0x5AE9	# <CJK>
0x445C	0x80FD	# <CJK>
0x445D	0x59AE	# <CJK>
0x445E	0x9713	# <CJK>
0x445F	0x502A	# <CJK>
0x4460	0x6CE5	# <CJK>
0x4461	0x5C3C	# <CJK>
0x4462	0x62DF	# <CJK>
0x4463	0x4F60	# <CJK>
0x4464	0x533F	# <CJK>
0x4465	0x817B	# <CJK>
0x4466	0x9006	# <CJK>
0x4467	0x6EBA	# <CJK>
0x4468	0x852B	# <CJK>
0x4469	0x62C8	# <CJK>
0x446A	0x5E74	# <CJK>
0x446B	0x78BE	# <CJK>
0x446C	0x64B5	# <CJK>
0x446D	0x637B	# <CJK>
0x446E	0x5FF5	# <CJK>
0x446F	0x5A18	# <CJK>
0x4470	0x917F	# <CJK>
0x4471	0x9E1F	# <CJK>
0x4472	0x5C3F	# <CJK>
0x4473	0x634F	# <CJK>
0x4474	0x8042	# <CJK>
0x4475	0x5B7D	# <CJK>
0x4476	0x556E	# <CJK>
0x4477	0x954A	# <CJK>
0x4478	0x954D	# <CJK>
0x4479	0x6D85	# <CJK>
0x447A	0x60A8	# <CJK>
0x447B	0x67E0	# <CJK>
0x447C	0x72DE	# <CJK>
0x447D	0x51DD	# <CJK>
0x447E	0x5B81	# <CJK>
0x4521	0x62E7	# <CJK>
0x4522	0x6CDE	# <CJK>
0x4523	0x725B	# <CJK>
0x4524	0x626D	# <CJK>
0x4525	0x94AE	# <CJK>
0x4526	0x7EBD	# <CJK>
0x4527	0x8113	# <CJK>
0x4528	0x6D53	# <CJK>
0x4529	0x519C	# <CJK>
0x452A	0x5F04	# <CJK>
0x452B	0x5974	# <CJK>
0x452C	0x52AA	# <CJK>
0x452D	0x6012	# <CJK>
0x452E	0x5973	# <CJK>
0x452F	0x6696	# <CJK>
0x4530	0x8650	# <CJK>
0x4531	0x759F	# <CJK>
0x4532	0x632A	# <CJK>
0x4533	0x61E6	# <CJK>
0x4534	0x7CEF	# <CJK>
0x4535	0x8BFA	# <CJK>
0x4536	0x54E6	# <CJK>
0x4537	0x6B27	# <CJK>
0x4538	0x9E25	# <CJK>
0x4539	0x6BB4	# <CJK>
0x453A	0x85D5	# <CJK>
0x453B	0x5455	# <CJK>
0x453C	0x5076	# <CJK>
0x453D	0x6CA4	# <CJK>
0x453E	0x556A	# <CJK>
0x453F	0x8DB4	# <CJK>
0x4540	0x722C	# <CJK>
0x4541	0x5E15	# <CJK>
0x4542	0x6015	# <CJK>
0x4543	0x7436	# <CJK>
0x4544	0x62CD	# <CJK>
0x4545	0x6392	# <CJK>
0x4546	0x724C	# <CJK>
0x4547	0x5F98	# <CJK>
0x4548	0x6E43	# <CJK>
0x4549	0x6D3E	# <CJK>
0x454A	0x6500	# <CJK>
0x454B	0x6F58	# <CJK>
0x454C	0x76D8	# <CJK>
0x454D	0x78D0	# <CJK>
0x454E	0x76FC	# <CJK>
0x454F	0x7554	# <CJK>
0x4550	0x5224	# <CJK>
0x4551	0x53DB	# <CJK>
0x4552	0x4E53	# <CJK>
0x4553	0x5E9E	# <CJK>
0x4554	0x65C1	# <CJK>
0x4555	0x802A	# <CJK>
0x4556	0x80D6	# <CJK>
0x4557	0x629B	# <CJK>
0x4558	0x5486	# <CJK>
0x4559	0x5228	# <CJK>
0x455A	0x70AE	# <CJK>
0x455B	0x888D	# <CJK>
0x455C	0x8DD1	# <CJK>
0x455D	0x6CE1	# <CJK>
0x455E	0x5478	# <CJK>
0x455F	0x80DA	# <CJK>
0x4560	0x57F9	# <CJK>
0x4561	0x88F4	# <CJK>
0x4562	0x8D54	# <CJK>
0x4563	0x966A	# <CJK>
0x4564	0x914D	# <CJK>
0x4565	0x4F69	# <CJK>
0x4566	0x6C9B	# <CJK>
0x4567	0x55B7	# <CJK>
0x4568	0x76C6	# <CJK>
0x4569	0x7830	# <CJK>
0x456A	0x62A8	# <CJK>
0x456B	0x70F9	# <CJK>
0x456C	0x6F8E	# <CJK>
0x456D	0x5F6D	# <CJK>
0x456E	0x84EC	# <CJK>
0x456F	0x68DA	# <CJK>
0x4570	0x787C	# <CJK>
0x4571	0x7BF7	# <CJK>
0x4572	0x81A8	# <CJK>
0x4573	0x670B	# <CJK>
0x4574	0x9E4F	# <CJK>
0x4575	0x6367	# <CJK>
0x4576	0x78B0	# <CJK>
0x4577	0x576F	# <CJK>
0x4578	0x7812	# <CJK>
0x4579	0x9739	# <CJK>
0x457A	0x6279	# <CJK>
0x457B	0x62AB	# <CJK>
0x457C	0x5288	# <CJK>
0x457D	0x7435	# <CJK>
0x457E	0x6BD7	# <CJK>
0x4621	0x5564	# <CJK>
0x4622	0x813E	# <CJK>
0x4623	0x75B2	# <CJK>
0x4624	0x76AE	# <CJK>
0x4625	0x5339	# <CJK>
0x4626	0x75DE	# <CJK>
0x4627	0x50FB	# <CJK>
0x4628	0x5C41	# <CJK>
0x4629	0x8B6C	# <CJK>
0x462A	0x7BC7	# <CJK>
0x462B	0x504F	# <CJK>
0x462C	0x7247	# <CJK>
0x462D	0x9A97	# <CJK>
0x462E	0x98D8	# <CJK>
0x462F	0x6F02	# <CJK>
0x4630	0x74E2	# <CJK>
0x4631	0x7968	# <CJK>
0x4632	0x6487	# <CJK>
0x4633	0x77A5	# <CJK>
0x4634	0x62FC	# <CJK>
0x4635	0x9891	# <CJK>
0x4636	0x8D2B	# <CJK>
0x4637	0x54C1	# <CJK>
0x4638	0x8058	# <CJK>
0x4639	0x4E52	# <CJK>
0x463A	0x576A	# <CJK>
0x463B	0x82F9	# <CJK>
0x463C	0x840D	# <CJK>
0x463D	0x5E73	# <CJK>
0x463E	0x51ED	# <CJK>
0x463F	0x74F6	# <CJK>
0x4640	0x8BC4	# <CJK>
0x4641	0x5C4F	# <CJK>
0x4642	0x5761	# <CJK>
0x4643	0x6CFC	# <CJK>
0x4644	0x9887	# <CJK>
0x4645	0x5A46	# <CJK>
0x4646	0x7834	# <CJK>
0x4647	0x9B44	# <CJK>
0x4648	0x8FEB	# <CJK>
0x4649	0x7C95	# <CJK>
0x464A	0x5256	# <CJK>
0x464B	0x6251	# <CJK>
0x464C	0x94FA	# <CJK>
0x464D	0x4EC6	# <CJK>
0x464E	0x8386	# <CJK>
0x464F	0x8461	# <CJK>
0x4650	0x83E9	# <CJK>
0x4651	0x84B2	# <CJK>
0x4652	0x57D4	# <CJK>
0x4653	0x6734	# <CJK>
0x4654	0x5703	# <CJK>
0x4655	0x666E	# <CJK>
0x4656	0x6D66	# <CJK>
0x4657	0x8C31	# <CJK>
0x4658	0x66DD	# <CJK>
0x4659	0x7011	# <CJK>
0x465A	0x671F	# <CJK>
0x465B	0x6B3A	# <CJK>
0x465C	0x6816	# <CJK>
0x465D	0x621A	# <CJK>
0x465E	0x59BB	# <CJK>
0x465F	0x4E03	# <CJK>
0x4660	0x51C4	# <CJK>
0x4661	0x6F06	# <CJK>
0x4662	0x67D2	# <CJK>
0x4663	0x6C8F	# <CJK>
0x4664	0x5176	# <CJK>
0x4665	0x68CB	# <CJK>
0x4666	0x5947	# <CJK>
0x4667	0x6B67	# <CJK>
0x4668	0x7566	# <CJK>
0x4669	0x5D0E	# <CJK>
0x466A	0x8110	# <CJK>
0x466B	0x9F50	# <CJK>
0x466C	0x65D7	# <CJK>
0x466D	0x7948	# <CJK>
0x466E	0x7941	# <CJK>
0x466F	0x9A91	# <CJK>
0x4670	0x8D77	# <CJK>
0x4671	0x5C82	# <CJK>
0x4672	0x4E5E	# <CJK>
0x4673	0x4F01	# <CJK>
0x4674	0x542F	# <CJK>
0x4675	0x5951	# <CJK>
0x4676	0x780C	# <CJK>
0x4677	0x5668	# <CJK>
0x4678	0x6C14	# <CJK>
0x4679	0x8FC4	# <CJK>
0x467A	0x5F03	# <CJK>
0x467B	0x6C7D	# <CJK>
0x467C	0x6CE3	# <CJK>
0x467D	0x8BAB	# <CJK>
0x467E	0x6390	# <CJK>
0x4721	0x6070	# <CJK>
0x4722	0x6D3D	# <CJK>
0x4723	0x7275	# <CJK>
0x4724	0x6266	# <CJK>
0x4725	0x948E	# <CJK>
0x4726	0x94C5	# <CJK>
0x4727	0x5343	# <CJK>
0x4728	0x8FC1	# <CJK>
0x4729	0x7B7E	# <CJK>
0x472A	0x4EDF	# <CJK>
0x472B	0x8C26	# <CJK>
0x472C	0x4E7E	# <CJK>
0x472D	0x9ED4	# <CJK>
0x472E	0x94B1	# <CJK>
0x472F	0x94B3	# <CJK>
0x4730	0x524D	# <CJK>
0x4731	0x6F5C	# <CJK>
0x4732	0x9063	# <CJK>
0x4733	0x6D45	# <CJK>
0x4734	0x8C34	# <CJK>
0x4735	0x5811	# <CJK>
0x4736	0x5D4C	# <CJK>
0x4737	0x6B20	# <CJK>
0x4738	0x6B49	# <CJK>
0x4739	0x67AA	# <CJK>
0x473A	0x545B	# <CJK>
0x473B	0x8154	# <CJK>
0x473C	0x7F8C	# <CJK>
0x473D	0x5899	# <CJK>
0x473E	0x8537	# <CJK>
0x473F	0x5F3A	# <CJK>
0x4740	0x62A2	# <CJK>
0x4741	0x6A47	# <CJK>
0x4742	0x9539	# <CJK>
0x4743	0x6572	# <CJK>
0x4744	0x6084	# <CJK>
0x4745	0x6865	# <CJK>
0x4746	0x77A7	# <CJK>
0x4747	0x4E54	# <CJK>
0x4748	0x4FA8	# <CJK>
0x4749	0x5DE7	# <CJK>
0x474A	0x9798	# <CJK>
0x474B	0x64AC	# <CJK>
0x474C	0x7FD8	# <CJK>
0x474D	0x5CED	# <CJK>
0x474E	0x4FCF	# <CJK>
0x474F	0x7A8D	# <CJK>
0x4750	0x5207	# <CJK>
0x4751	0x8304	# <CJK>
0x4752	0x4E14	# <CJK>
0x4753	0x602F	# <CJK>
0x4754	0x7A83	# <CJK>
0x4755	0x94A6	# <CJK>
0x4756	0x4FB5	# <CJK>
0x4757	0x4EB2	# <CJK>
0x4758	0x79E6	# <CJK>
0x4759	0x7434	# <CJK>
0x475A	0x52E4	# <CJK>
0x475B	0x82B9	# <CJK>
0x475C	0x64D2	# <CJK>
0x475D	0x79BD	# <CJK>
0x475E	0x5BDD	# <CJK>
0x475F	0x6C81	# <CJK>
0x4760	0x9752	# <CJK>
0x4761	0x8F7B	# <CJK>
0x4762	0x6C22	# <CJK>
0x4763	0x503E	# <CJK>
0x4764	0x537F	# <CJK>
0x4765	0x6E05	# <CJK>
0x4766	0x64CE	# <CJK>
0x4767	0x6674	# <CJK>
0x4768	0x6C30	# <CJK>
0x4769	0x60C5	# <CJK>
0x476A	0x9877	# <CJK>
0x476B	0x8BF7	# <CJK>
0x476C	0x5E86	# <CJK>
0x476D	0x743C	# <CJK>
0x476E	0x7A77	# <CJK>
0x476F	0x79CB	# <CJK>
0x4770	0x4E18	# <CJK>
0x4771	0x90B1	# <CJK>
0x4772	0x7403	# <CJK>
0x4773	0x6C42	# <CJK>
0x4774	0x56DA	# <CJK>
0x4775	0x914B	# <CJK>
0x4776	0x6CC5	# <CJK>
0x4777	0x8D8B	# <CJK>
0x4778	0x533A	# <CJK>
0x4779	0x86C6	# <CJK>
0x477A	0x66F2	# <CJK>
0x477B	0x8EAF	# <CJK>
0x477C	0x5C48	# <CJK>
0x477D	0x9A71	# <CJK>
0x477E	0x6E20	# <CJK>
0x4821	0x53D6	# <CJK>
0x4822	0x5A36	# <CJK>
0x4823	0x9F8B	# <CJK>
0x4824	0x8DA3	# <CJK>
0x4825	0x53BB	# <CJK>
0x4826	0x5708	# <CJK>
0x4827	0x98A7	# <CJK>
0x4828	0x6743	# <CJK>
0x4829	0x919B	# <CJK>
0x482A	0x6CC9	# <CJK>
0x482B	0x5168	# <CJK>
0x482C	0x75CA	# <CJK>
0x482D	0x62F3	# <CJK>
0x482E	0x72AC	# <CJK>
0x482F	0x5238	# <CJK>
0x4830	0x529D	# <CJK>
0x4831	0x7F3A	# <CJK>
0x4832	0x7094	# <CJK>
0x4833	0x7638	# <CJK>
0x4834	0x5374	# <CJK>
0x4835	0x9E4A	# <CJK>
0x4836	0x69B7	# <CJK>
0x4837	0x786E	# <CJK>
0x4838	0x96C0	# <CJK>
0x4839	0x88D9	# <CJK>
0x483A	0x7FA4	# <CJK>
0x483B	0x7136	# <CJK>
0x483C	0x71C3	# <CJK>
0x483D	0x5189	# <CJK>
0x483E	0x67D3	# <CJK>
0x483F	0x74E4	# <CJK>
0x4840	0x58E4	# <CJK>
0x4841	0x6518	# <CJK>
0x4842	0x56B7	# <CJK>
0x4843	0x8BA9	# <CJK>
0x4844	0x9976	# <CJK>
0x4845	0x6270	# <CJK>
0x4846	0x7ED5	# <CJK>
0x4847	0x60F9	# <CJK>
0x4848	0x70ED	# <CJK>
0x4849	0x58EC	# <CJK>
0x484A	0x4EC1	# <CJK>
0x484B	0x4EBA	# <CJK>
0x484C	0x5FCD	# <CJK>
0x484D	0x97E7	# <CJK>
0x484E	0x4EFB	# <CJK>
0x484F	0x8BA4	# <CJK>
0x4850	0x5203	# <CJK>
0x4851	0x598A	# <CJK>
0x4852	0x7EAB	# <CJK>
0x4853	0x6254	# <CJK>
0x4854	0x4ECD	# <CJK>
0x4855	0x65E5	# <CJK>
0x4856	0x620E	# <CJK>
0x4857	0x8338	# <CJK>
0x4858	0x84C9	# <CJK>
0x4859	0x8363	# <CJK>
0x485A	0x878D	# <CJK>
0x485B	0x7194	# <CJK>
0x485C	0x6EB6	# <CJK>
0x485D	0x5BB9	# <CJK>
0x485E	0x7ED2	# <CJK>
0x485F	0x5197	# <CJK>
0x4860	0x63C9	# <CJK>
0x4861	0x67D4	# <CJK>
0x4862	0x8089	# <CJK>
0x4863	0x8339	# <CJK>
0x4864	0x8815	# <CJK>
0x4865	0x5112	# <CJK>
0x4866	0x5B7A	# <CJK>
0x4867	0x5982	# <CJK>
0x4868	0x8FB1	# <CJK>
0x4869	0x4E73	# <CJK>
0x486A	0x6C5D	# <CJK>
0x486B	0x5165	# <CJK>
0x486C	0x8925	# <CJK>
0x486D	0x8F6F	# <CJK>
0x486E	0x962E	# <CJK>
0x486F	0x854A	# <CJK>
0x4870	0x745E	# <CJK>
0x4871	0x9510	# <CJK>
0x4872	0x95F0	# <CJK>
0x4873	0x6DA6	# <CJK>
0x4874	0x82E5	# <CJK>
0x4875	0x5F31	# <CJK>
0x4876	0x6492	# <CJK>
0x4877	0x6D12	# <CJK>
0x4878	0x8428	# <CJK>
0x4879	0x816E	# <CJK>
0x487A	0x9CC3	# <CJK>
0x487B	0x585E	# <CJK>
0x487C	0x8D5B	# <CJK>
0x487D	0x4E09	# <CJK>
0x487E	0x53C1	# <CJK>
0x4921	0x4F1E	# <CJK>
0x4922	0x6563	# <CJK>
0x4923	0x6851	# <CJK>
0x4924	0x55D3	# <CJK>
0x4925	0x4E27	# <CJK>
0x4926	0x6414	# <CJK>
0x4927	0x9A9A	# <CJK>
0x4928	0x626B	# <CJK>
0x4929	0x5AC2	# <CJK>
0x492A	0x745F	# <CJK>
0x492B	0x8272	# <CJK>
0x492C	0x6DA9	# <CJK>
0x492D	0x68EE	# <CJK>
0x492E	0x50E7	# <CJK>
0x492F	0x838E	# <CJK>
0x4930	0x7802	# <CJK>
0x4931	0x6740	# <CJK>
0x4932	0x5239	# <CJK>
0x4933	0x6C99	# <CJK>
0x4934	0x7EB1	# <CJK>
0x4935	0x50BB	# <CJK>
0x4936	0x5565	# <CJK>
0x4937	0x715E	# <CJK>
0x4938	0x7B5B	# <CJK>
0x4939	0x6652	# <CJK>
0x493A	0x73CA	# <CJK>
0x493B	0x82EB	# <CJK>
0x493C	0x6749	# <CJK>
0x493D	0x5C71	# <CJK>
0x493E	0x5220	# <CJK>
0x493F	0x717D	# <CJK>
0x4940	0x886B	# <CJK>
0x4941	0x95EA	# <CJK>
0x4942	0x9655	# <CJK>
0x4943	0x64C5	# <CJK>
0x4944	0x8D61	# <CJK>
0x4945	0x81B3	# <CJK>
0x4946	0x5584	# <CJK>
0x4947	0x6C55	# <CJK>
0x4948	0x6247	# <CJK>
0x4949	0x7F2E	# <CJK>
0x494A	0x5892	# <CJK>
0x494B	0x4F24	# <CJK>
0x494C	0x5546	# <CJK>
0x494D	0x8D4F	# <CJK>
0x494E	0x664C	# <CJK>
0x494F	0x4E0A	# <CJK>
0x4950	0x5C1A	# <CJK>
0x4951	0x88F3	# <CJK>
0x4952	0x68A2	# <CJK>
0x4953	0x634E	# <CJK>
0x4954	0x7A0D	# <CJK>
0x4955	0x70E7	# <CJK>
0x4956	0x828D	# <CJK>
0x4957	0x52FA	# <CJK>
0x4958	0x97F6	# <CJK>
0x4959	0x5C11	# <CJK>
0x495A	0x54E8	# <CJK>
0x495B	0x90B5	# <CJK>
0x495C	0x7ECD	# <CJK>
0x495D	0x5962	# <CJK>
0x495E	0x8D4A	# <CJK>
0x495F	0x86C7	# <CJK>
0x4960	0x820C	# <CJK>
0x4961	0x820D	# <CJK>
0x4962	0x8D66	# <CJK>
0x4963	0x6444	# <CJK>
0x4964	0x5C04	# <CJK>
0x4965	0x6151	# <CJK>
0x4966	0x6D89	# <CJK>
0x4967	0x793E	# <CJK>
0x4968	0x8BBE	# <CJK>
0x4969	0x7837	# <CJK>
0x496A	0x7533	# <CJK>
0x496B	0x547B	# <CJK>
0x496C	0x4F38	# <CJK>
0x496D	0x8EAB	# <CJK>
0x496E	0x6DF1	# <CJK>
0x496F	0x5A20	# <CJK>
0x4970	0x7EC5	# <CJK>
0x4971	0x795E	# <CJK>
0x4972	0x6C88	# <CJK>
0x4973	0x5BA1	# <CJK>
0x4974	0x5A76	# <CJK>
0x4975	0x751A	# <CJK>
0x4976	0x80BE	# <CJK>
0x4977	0x614E	# <CJK>
0x4978	0x6E17	# <CJK>
0x4979	0x58F0	# <CJK>
0x497A	0x751F	# <CJK>
0x497B	0x7525	# <CJK>
0x497C	0x7272	# <CJK>
0x497D	0x5347	# <CJK>
0x497E	0x7EF3	# <CJK>
0x4A21	0x7701	# <CJK>
0x4A22	0x76DB	# <CJK>
0x4A23	0x5269	# <CJK>
0x4A24	0x80DC	# <CJK>
0x4A25	0x5723	# <CJK>
0x4A26	0x5E08	# <CJK>
0x4A27	0x5931	# <CJK>
0x4A28	0x72EE	# <CJK>
0x4A29	0x65BD	# <CJK>
0x4A2A	0x6E7F	# <CJK>
0x4A2B	0x8BD7	# <CJK>
0x4A2C	0x5C38	# <CJK>
0x4A2D	0x8671	# <CJK>
0x4A2E	0x5341	# <CJK>
0x4A2F	0x77F3	# <CJK>
0x4A30	0x62FE	# <CJK>
0x4A31	0x65F6	# <CJK>
0x4A32	0x4EC0	# <CJK>
0x4A33	0x98DF	# <CJK>
0x4A34	0x8680	# <CJK>
0x4A35	0x5B9E	# <CJK>
0x4A36	0x8BC6	# <CJK>
0x4A37	0x53F2	# <CJK>
0x4A38	0x77E2	# <CJK>
0x4A39	0x4F7F	# <CJK>
0x4A3A	0x5C4E	# <CJK>
0x4A3B	0x9A76	# <CJK>
0x4A3C	0x59CB	# <CJK>
0x4A3D	0x5F0F	# <CJK>
0x4A3E	0x793A	# <CJK>
0x4A3F	0x58EB	# <CJK>
0x4A40	0x4E16	# <CJK>
0x4A41	0x67FF	# <CJK>
0x4A42	0x4E8B	# <CJK>
0x4A43	0x62ED	# <CJK>
0x4A44	0x8A93	# <CJK>
0x4A45	0x901D	# <CJK>
0x4A46	0x52BF	# <CJK>
0x4A47	0x662F	# <CJK>
0x4A48	0x55DC	# <CJK>
0x4A49	0x566C	# <CJK>
0x4A4A	0x9002	# <CJK>
0x4A4B	0x4ED5	# <CJK>
0x4A4C	0x4F8D	# <CJK>
0x4A4D	0x91CA	# <CJK>
0x4A4E	0x9970	# <CJK>
0x4A4F	0x6C0F	# <CJK>
0x4A50	0x5E02	# <CJK>
0x4A51	0x6043	# <CJK>
0x4A52	0x5BA4	# <CJK>
0x4A53	0x89C6	# <CJK>
0x4A54	0x8BD5	# <CJK>
0x4A55	0x6536	# <CJK>
0x4A56	0x624B	# <CJK>
0x4A57	0x9996	# <CJK>
0x4A58	0x5B88	# <CJK>
0x4A59	0x5BFF	# <CJK>
0x4A5A	0x6388	# <CJK>
0x4A5B	0x552E	# <CJK>
0x4A5C	0x53D7	# <CJK>
0x4A5D	0x7626	# <CJK>
0x4A5E	0x517D	# <CJK>
0x4A5F	0x852C	# <CJK>
0x4A60	0x67A2	# <CJK>
0x4A61	0x68B3	# <CJK>
0x4A62	0x6B8A	# <CJK>
0x4A63	0x6292	# <CJK>
0x4A64	0x8F93	# <CJK>
0x4A65	0x53D4	# <CJK>
0x4A66	0x8212	# <CJK>
0x4A67	0x6DD1	# <CJK>
0x4A68	0x758F	# <CJK>
0x4A69	0x4E66	# <CJK>
0x4A6A	0x8D4E	# <CJK>
0x4A6B	0x5B70	# <CJK>
0x4A6C	0x719F	# <CJK>
0x4A6D	0x85AF	# <CJK>
0x4A6E	0x6691	# <CJK>
0x4A6F	0x66D9	# <CJK>
0x4A70	0x7F72	# <CJK>
0x4A71	0x8700	# <CJK>
0x4A72	0x9ECD	# <CJK>
0x4A73	0x9F20	# <CJK>
0x4A74	0x5C5E	# <CJK>
0x4A75	0x672F	# <CJK>
0x4A76	0x8FF0	# <CJK>
0x4A77	0x6811	# <CJK>
0x4A78	0x675F	# <CJK>
0x4A79	0x620D	# <CJK>
0x4A7A	0x7AD6	# <CJK>
0x4A7B	0x5885	# <CJK>
0x4A7C	0x5EB6	# <CJK>
0x4A7D	0x6570	# <CJK>
0x4A7E	0x6F31	# <CJK>
0x4B21	0x6055	# <CJK>
0x4B22	0x5237	# <CJK>
0x4B23	0x800D	# <CJK>
0x4B24	0x6454	# <CJK>
0x4B25	0x8870	# <CJK>
0x4B26	0x7529	# <CJK>
0x4B27	0x5E05	# <CJK>
0x4B28	0x6813	# <CJK>
0x4B29	0x62F4	# <CJK>
0x4B2A	0x971C	# <CJK>
0x4B2B	0x53CC	# <CJK>
0x4B2C	0x723D	# <CJK>
0x4B2D	0x8C01	# <CJK>
0x4B2E	0x6C34	# <CJK>
0x4B2F	0x7761	# <CJK>
0x4B30	0x7A0E	# <CJK>
0x4B31	0x542E	# <CJK>
0x4B32	0x77AC	# <CJK>
0x4B33	0x987A	# <CJK>
0x4B34	0x821C	# <CJK>
0x4B35	0x8BF4	# <CJK>
0x4B36	0x7855	# <CJK>
0x4B37	0x6714	# <CJK>
0x4B38	0x70C1	# <CJK>
0x4B39	0x65AF	# <CJK>
0x4B3A	0x6495	# <CJK>
0x4B3B	0x5636	# <CJK>
0x4B3C	0x601D	# <CJK>
0x4B3D	0x79C1	# <CJK>
0x4B3E	0x53F8	# <CJK>
0x4B3F	0x4E1D	# <CJK>
0x4B40	0x6B7B	# <CJK>
0x4B41	0x8086	# <CJK>
0x4B42	0x5BFA	# <CJK>
0x4B43	0x55E3	# <CJK>
0x4B44	0x56DB	# <CJK>
0x4B45	0x4F3A	# <CJK>
0x4B46	0x4F3C	# <CJK>
0x4B47	0x9972	# <CJK>
0x4B48	0x5DF3	# <CJK>
0x4B49	0x677E	# <CJK>
0x4B4A	0x8038	# <CJK>
0x4B4B	0x6002	# <CJK>
0x4B4C	0x9882	# <CJK>
0x4B4D	0x9001	# <CJK>
0x4B4E	0x5B8B	# <CJK>
0x4B4F	0x8BBC	# <CJK>
0x4B50	0x8BF5	# <CJK>
0x4B51	0x641C	# <CJK>
0x4B52	0x8258	# <CJK>
0x4B53	0x64DE	# <CJK>
0x4B54	0x55FD	# <CJK>
0x4B55	0x82CF	# <CJK>
0x4B56	0x9165	# <CJK>
0x4B57	0x4FD7	# <CJK>
0x4B58	0x7D20	# <CJK>
0x4B59	0x901F	# <CJK>
0x4B5A	0x7C9F	# <CJK>
0x4B5B	0x50F3	# <CJK>
0x4B5C	0x5851	# <CJK>
0x4B5D	0x6EAF	# <CJK>
0x4B5E	0x5BBF	# <CJK>
0x4B5F	0x8BC9	# <CJK>
0x4B60	0x8083	# <CJK>
0x4B61	0x9178	# <CJK>
0x4B62	0x849C	# <CJK>
0x4B63	0x7B97	# <CJK>
0x4B64	0x867D	# <CJK>
0x4B65	0x968B	# <CJK>
0x4B66	0x968F	# <CJK>
0x4B67	0x7EE5	# <CJK>
0x4B68	0x9AD3	# <CJK>
0x4B69	0x788E	# <CJK>
0x4B6A	0x5C81	# <CJK>
0x4B6B	0x7A57	# <CJK>
0x4B6C	0x9042	# <CJK>
0x4B6D	0x96A7	# <CJK>
0x4B6E	0x795F	# <CJK>
0x4B6F	0x5B59	# <CJK>
0x4B70	0x635F	# <CJK>
0x4B71	0x7B0B	# <CJK>
0x4B72	0x84D1	# <CJK>
0x4B73	0x68AD	# <CJK>
0x4B74	0x5506	# <CJK>
0x4B75	0x7F29	# <CJK>
0x4B76	0x7410	# <CJK>
0x4B77	0x7D22	# <CJK>
0x4B78	0x9501	# <CJK>
0x4B79	0x6240	# <CJK>
0x4B7A	0x584C	# <CJK>
0x4B7B	0x4ED6	# <CJK>
0x4B7C	0x5B83	# <CJK>
0x4B7D	0x5979	# <CJK>
0x4B7E	0x5854	# <CJK>
0x4C21	0x736D	# <CJK>
0x4C22	0x631E	# <CJK>
0x4C23	0x8E4B	# <CJK>
0x4C24	0x8E0F	# <CJK>
0x4C25	0x80CE	# <CJK>
0x4C26	0x82D4	# <CJK>
0x4C27	0x62AC	# <CJK>
0x4C28	0x53F0	# <CJK>
0x4C29	0x6CF0	# <CJK>
0x4C2A	0x915E	# <CJK>
0x4C2B	0x592A	# <CJK>
0x4C2C	0x6001	# <CJK>
0x4C2D	0x6C70	# <CJK>
0x4C2E	0x574D	# <CJK>
0x4C2F	0x644A	# <CJK>
0x4C30	0x8D2A	# <CJK>
0x4C31	0x762B	# <CJK>
0x4C32	0x6EE9	# <CJK>
0x4C33	0x575B	# <CJK>
0x4C34	0x6A80	# <CJK>
0x4C35	0x75F0	# <CJK>
0x4C36	0x6F6D	# <CJK>
0x4C37	0x8C2D	# <CJK>
0x4C38	0x8C08	# <CJK>
0x4C39	0x5766	# <CJK>
0x4C3A	0x6BEF	# <CJK>
0x4C3B	0x8892	# <CJK>
0x4C3C	0x78B3	# <CJK>
0x4C3D	0x63A2	# <CJK>
0x4C3E	0x53F9	# <CJK>
0x4C3F	0x70AD	# <CJK>
0x4C40	0x6C64	# <CJK>
0x4C41	0x5858	# <CJK>
0x4C42	0x642A	# <CJK>
0x4C43	0x5802	# <CJK>
0x4C44	0x68E0	# <CJK>
0x4C45	0x819B	# <CJK>
0x4C46	0x5510	# <CJK>
0x4C47	0x7CD6	# <CJK>
0x4C48	0x5018	# <CJK>
0x4C49	0x8EBA	# <CJK>
0x4C4A	0x6DCC	# <CJK>
0x4C4B	0x8D9F	# <CJK>
0x4C4C	0x70EB	# <CJK>
0x4C4D	0x638F	# <CJK>
0x4C4E	0x6D9B	# <CJK>
0x4C4F	0x6ED4	# <CJK>
0x4C50	0x7EE6	# <CJK>
0x4C51	0x8404	# <CJK>
0x4C52	0x6843	# <CJK>
0x4C53	0x9003	# <CJK>
0x4C54	0x6DD8	# <CJK>
0x4C55	0x9676	# <CJK>
0x4C56	0x8BA8	# <CJK>
0x4C57	0x5957	# <CJK>
0x4C58	0x7279	# <CJK>
0x4C59	0x85E4	# <CJK>
0x4C5A	0x817E	# <CJK>
0x4C5B	0x75BC	# <CJK>
0x4C5C	0x8A8A	# <CJK>
0x4C5D	0x68AF	# <CJK>
0x4C5E	0x5254	# <CJK>
0x4C5F	0x8E22	# <CJK>
0x4C60	0x9511	# <CJK>
0x4C61	0x63D0	# <CJK>
0x4C62	0x9898	# <CJK>
0x4C63	0x8E44	# <CJK>
0x4C64	0x557C	# <CJK>
0x4C65	0x4F53	# <CJK>
0x4C66	0x66FF	# <CJK>
0x4C67	0x568F	# <CJK>
0x4C68	0x60D5	# <CJK>
0x4C69	0x6D95	# <CJK>
0x4C6A	0x5243	# <CJK>
0x4C6B	0x5C49	# <CJK>
0x4C6C	0x5929	# <CJK>
0x4C6D	0x6DFB	# <CJK>
0x4C6E	0x586B	# <CJK>
0x4C6F	0x7530	# <CJK>
0x4C70	0x751C	# <CJK>
0x4C71	0x606C	# <CJK>
0x4C72	0x8214	# <CJK>
0x4C73	0x8146	# <CJK>
0x4C74	0x6311	# <CJK>
0x4C75	0x6761	# <CJK>
0x4C76	0x8FE2	# <CJK>
0x4C77	0x773A	# <CJK>
0x4C78	0x8DF3	# <CJK>
0x4C79	0x8D34	# <CJK>
0x4C7A	0x94C1	# <CJK>
0x4C7B	0x5E16	# <CJK>
0x4C7C	0x5385	# <CJK>
0x4C7D	0x542C	# <CJK>
0x4C7E	0x70C3	# <CJK>
0x4D21	0x6C40	# <CJK>
0x4D22	0x5EF7	# <CJK>
0x4D23	0x505C	# <CJK>
0x4D24	0x4EAD	# <CJK>
0x4D25	0x5EAD	# <CJK>
0x4D26	0x633A	# <CJK>
0x4D27	0x8247	# <CJK>
0x4D28	0x901A	# <CJK>
0x4D29	0x6850	# <CJK>
0x4D2A	0x916E	# <CJK>
0x4D2B	0x77B3	# <CJK>
0x4D2C	0x540C	# <CJK>
0x4D2D	0x94DC	# <CJK>
0x4D2E	0x5F64	# <CJK>
0x4D2F	0x7AE5	# <CJK>
0x4D30	0x6876	# <CJK>
0x4D31	0x6345	# <CJK>
0x4D32	0x7B52	# <CJK>
0x4D33	0x7EDF	# <CJK>
0x4D34	0x75DB	# <CJK>
0x4D35	0x5077	# <CJK>
0x4D36	0x6295	# <CJK>
0x4D37	0x5934	# <CJK>
0x4D38	0x900F	# <CJK>
0x4D39	0x51F8	# <CJK>
0x4D3A	0x79C3	# <CJK>
0x4D3B	0x7A81	# <CJK>
0x4D3C	0x56FE	# <CJK>
0x4D3D	0x5F92	# <CJK>
0x4D3E	0x9014	# <CJK>
0x4D3F	0x6D82	# <CJK>
0x4D40	0x5C60	# <CJK>
0x4D41	0x571F	# <CJK>
0x4D42	0x5410	# <CJK>
0x4D43	0x5154	# <CJK>
0x4D44	0x6E4D	# <CJK>
0x4D45	0x56E2	# <CJK>
0x4D46	0x63A8	# <CJK>
0x4D47	0x9893	# <CJK>
0x4D48	0x817F	# <CJK>
0x4D49	0x8715	# <CJK>
0x4D4A	0x892A	# <CJK>
0x4D4B	0x9000	# <CJK>
0x4D4C	0x541E	# <CJK>
0x4D4D	0x5C6F	# <CJK>
0x4D4E	0x81C0	# <CJK>
0x4D4F	0x62D6	# <CJK>
0x4D50	0x6258	# <CJK>
0x4D51	0x8131	# <CJK>
0x4D52	0x9E35	# <CJK>
0x4D53	0x9640	# <CJK>
0x4D54	0x9A6E	# <CJK>
0x4D55	0x9A7C	# <CJK>
0x4D56	0x692D	# <CJK>
0x4D57	0x59A5	# <CJK>
0x4D58	0x62D3	# <CJK>
0x4D59	0x553E	# <CJK>
0x4D5A	0x6316	# <CJK>
0x4D5B	0x54C7	# <CJK>
0x4D5C	0x86D9	# <CJK>
0x4D5D	0x6D3C	# <CJK>
0x4D5E	0x5A03	# <CJK>
0x4D5F	0x74E6	# <CJK>
0x4D60	0x889C	# <CJK>
0x4D61	0x6B6A	# <CJK>
0x4D62	0x5916	# <CJK>
0x4D63	0x8C4C	# <CJK>
0x4D64	0x5F2F	# <CJK>
0x4D65	0x6E7E	# <CJK>
0x4D66	0x73A9	# <CJK>
0x4D67	0x987D	# <CJK>
0x4D68	0x4E38	# <CJK>
0x4D69	0x70F7	# <CJK>
0x4D6A	0x5B8C	# <CJK>
0x4D6B	0x7897	# <CJK>
0x4D6C	0x633D	# <CJK>
0x4D6D	0x665A	# <CJK>
0x4D6E	0x7696	# <CJK>
0x4D6F	0x60CB	# <CJK>
0x4D70	0x5B9B	# <CJK>
0x4D71	0x5A49	# <CJK>
0x4D72	0x4E07	# <CJK>
0x4D73	0x8155	# <CJK>
0x4D74	0x6C6A	# <CJK>
0x4D75	0x738B	# <CJK>
0x4D76	0x4EA1	# <CJK>
0x4D77	0x6789	# <CJK>
0x4D78	0x7F51	# <CJK>
0x4D79	0x5F80	# <CJK>
0x4D7A	0x65FA	# <CJK>
0x4D7B	0x671B	# <CJK>
0x4D7C	0x5FD8	# <CJK>
0x4D7D	0x5984	# <CJK>
0x4D7E	0x5A01	# <CJK>
0x4E21	0x5DCD	# <CJK>
0x4E22	0x5FAE	# <CJK>
0x4E23	0x5371	# <CJK>
0x4E24	0x97E6	# <CJK>
0x4E25	0x8FDD	# <CJK>
0x4E26	0x6845	# <CJK>
0x4E27	0x56F4	# <CJK>
0x4E28	0x552F	# <CJK>
0x4E29	0x60DF	# <CJK>
0x4E2A	0x4E3A	# <CJK>
0x4E2B	0x6F4D	# <CJK>
0x4E2C	0x7EF4	# <CJK>
0x4E2D	0x82C7	# <CJK>
0x4E2E	0x840E	# <CJK>
0x4E2F	0x59D4	# <CJK>
0x4E30	0x4F1F	# <CJK>
0x4E31	0x4F2A	# <CJK>
0x4E32	0x5C3E	# <CJK>
0x4E33	0x7EAC	# <CJK>
0x4E34	0x672A	# <CJK>
0x4E35	0x851A	# <CJK>
0x4E36	0x5473	# <CJK>
0x4E37	0x754F	# <CJK>
0x4E38	0x80C3	# <CJK>
0x4E39	0x5582	# <CJK>
0x4E3A	0x9B4F	# <CJK>
0x4E3B	0x4F4D	# <CJK>
0x4E3C	0x6E2D	# <CJK>
0x4E3D	0x8C13	# <CJK>
0x4E3E	0x5C09	# <CJK>
0x4E3F	0x6170	# <CJK>
0x4E40	0x536B	# <CJK>
0x4E41	0x761F	# <CJK>
0x4E42	0x6E29	# <CJK>
0x4E43	0x868A	# <CJK>
0x4E44	0x6587	# <CJK>
0x4E45	0x95FB	# <CJK>
0x4E46	0x7EB9	# <CJK>
0x4E47	0x543B	# <CJK>
0x4E48	0x7A33	# <CJK>
0x4E49	0x7D0A	# <CJK>
0x4E4A	0x95EE	# <CJK>
0x4E4B	0x55E1	# <CJK>
0x4E4C	0x7FC1	# <CJK>
0x4E4D	0x74EE	# <CJK>
0x4E4E	0x631D	# <CJK>
0x4E4F	0x8717	# <CJK>
0x4E50	0x6DA1	# <CJK>
0x4E51	0x7A9D	# <CJK>
0x4E52	0x6211	# <CJK>
0x4E53	0x65A1	# <CJK>
0x4E54	0x5367	# <CJK>
0x4E55	0x63E1	# <CJK>
0x4E56	0x6C83	# <CJK>
0x4E57	0x5DEB	# <CJK>
0x4E58	0x545C	# <CJK>
0x4E59	0x94A8	# <CJK>
0x4E5A	0x4E4C	# <CJK>
0x4E5B	0x6C61	# <CJK>
0x4E5C	0x8BEC	# <CJK>
0x4E5D	0x5C4B	# <CJK>
0x4E5E	0x65E0	# <CJK>
0x4E5F	0x829C	# <CJK>
0x4E60	0x68A7	# <CJK>
0x4E61	0x543E	# <CJK>
0x4E62	0x5434	# <CJK>
0x4E63	0x6BCB	# <CJK>
0x4E64	0x6B66	# <CJK>
0x4E65	0x4E94	# <CJK>
0x4E66	0x6342	# <CJK>
0x4E67	0x5348	# <CJK>
0x4E68	0x821E	# <CJK>
0x4E69	0x4F0D	# <CJK>
0x4E6A	0x4FAE	# <CJK>
0x4E6B	0x575E	# <CJK>
0x4E6C	0x620A	# <CJK>
0x4E6D	0x96FE	# <CJK>
0x4E6E	0x6664	# <CJK>
0x4E6F	0x7269	# <CJK>
0x4E70	0x52FF	# <CJK>
0x4E71	0x52A1	# <CJK>
0x4E72	0x609F	# <CJK>
0x4E73	0x8BEF	# <CJK>
0x4E74	0x6614	# <CJK>
0x4E75	0x7199	# <CJK>
0x4E76	0x6790	# <CJK>
0x4E77	0x897F	# <CJK>
0x4E78	0x7852	# <CJK>
0x4E79	0x77FD	# <CJK>
0x4E7A	0x6670	# <CJK>
0x4E7B	0x563B	# <CJK>
0x4E7C	0x5438	# <CJK>
0x4E7D	0x9521	# <CJK>
0x4E7E	0x727A	# <CJK>
0x4F21	0x7A00	# <CJK>
0x4F22	0x606F	# <CJK>
0x4F23	0x5E0C	# <CJK>
0x4F24	0x6089	# <CJK>
0x4F25	0x819D	# <CJK>
0x4F26	0x5915	# <CJK>
0x4F27	0x60DC	# <CJK>
0x4F28	0x7184	# <CJK>
0x4F29	0x70EF	# <CJK>
0x4F2A	0x6EAA	# <CJK>
0x4F2B	0x6C50	# <CJK>
0x4F2C	0x7280	# <CJK>
0x4F2D	0x6A84	# <CJK>
0x4F2E	0x88AD	# <CJK>
0x4F2F	0x5E2D	# <CJK>
0x4F30	0x4E60	# <CJK>
0x4F31	0x5AB3	# <CJK>
0x4F32	0x559C	# <CJK>
0x4F33	0x94E3	# <CJK>
0x4F34	0x6D17	# <CJK>
0x4F35	0x7CFB	# <CJK>
0x4F36	0x9699	# <CJK>
0x4F37	0x620F	# <CJK>
0x4F38	0x7EC6	# <CJK>
0x4F39	0x778E	# <CJK>
0x4F3A	0x867E	# <CJK>
0x4F3B	0x5323	# <CJK>
0x4F3C	0x971E	# <CJK>
0x4F3D	0x8F96	# <CJK>
0x4F3E	0x6687	# <CJK>
0x4F3F	0x5CE1	# <CJK>
0x4F40	0x4FA0	# <CJK>
0x4F41	0x72ED	# <CJK>
0x4F42	0x4E0B	# <CJK>
0x4F43	0x53A6	# <CJK>
0x4F44	0x590F	# <CJK>
0x4F45	0x5413	# <CJK>
0x4F46	0x6380	# <CJK>
0x4F47	0x9528	# <CJK>
0x4F48	0x5148	# <CJK>
0x4F49	0x4ED9	# <CJK>
0x4F4A	0x9C9C	# <CJK>
0x4F4B	0x7EA4	# <CJK>
0x4F4C	0x54B8	# <CJK>
0x4F4D	0x8D24	# <CJK>
0x4F4E	0x8854	# <CJK>
0x4F4F	0x8237	# <CJK>
0x4F50	0x95F2	# <CJK>
0x4F51	0x6D8E	# <CJK>
0x4F52	0x5F26	# <CJK>
0x4F53	0x5ACC	# <CJK>
0x4F54	0x663E	# <CJK>
0x4F55	0x9669	# <CJK>
0x4F56	0x73B0	# <CJK>
0x4F57	0x732E	# <CJK>
0x4F58	0x53BF	# <CJK>
0x4F59	0x817A	# <CJK>
0x4F5A	0x9985	# <CJK>
0x4F5B	0x7FA1	# <CJK>
0x4F5C	0x5BAA	# <CJK>
0x4F5D	0x9677	# <CJK>
0x4F5E	0x9650	# <CJK>
0x4F5F	0x7EBF	# <CJK>
0x4F60	0x76F8	# <CJK>
0x4F61	0x53A2	# <CJK>
0x4F62	0x9576	# <CJK>
0x4F63	0x9999	# <CJK>
0x4F64	0x7BB1	# <CJK>
0x4F65	0x8944	# <CJK>
0x4F66	0x6E58	# <CJK>
0x4F67	0x4E61	# <CJK>
0x4F68	0x7FD4	# <CJK>
0x4F69	0x7965	# <CJK>
0x4F6A	0x8BE6	# <CJK>
0x4F6B	0x60F3	# <CJK>
0x4F6C	0x54CD	# <CJK>
0x4F6D	0x4EAB	# <CJK>
0x4F6E	0x9879	# <CJK>
0x4F6F	0x5DF7	# <CJK>
0x4F70	0x6A61	# <CJK>
0x4F71	0x50CF	# <CJK>
0x4F72	0x5411	# <CJK>
0x4F73	0x8C61	# <CJK>
0x4F74	0x8427	# <CJK>
0x4F75	0x785D	# <CJK>
0x4F76	0x9704	# <CJK>
0x4F77	0x524A	# <CJK>
0x4F78	0x54EE	# <CJK>
0x4F79	0x56A3	# <CJK>
0x4F7A	0x9500	# <CJK>
0x4F7B	0x6D88	# <CJK>
0x4F7C	0x5BB5	# <CJK>
0x4F7D	0x6DC6	# <CJK>
0x4F7E	0x6653	# <CJK>
0x5021	0x5C0F	# <CJK>
0x5022	0x5B5D	# <CJK>
0x5023	0x6821	# <CJK>
0x5024	0x8096	# <CJK>
0x5025	0x5578	# <CJK>
0x5026	0x7B11	# <CJK>
0x5027	0x6548	# <CJK>
0x5028	0x6954	# <CJK>
0x5029	0x4E9B	# <CJK>
0x502A	0x6B47	# <CJK>
0x502B	0x874E	# <CJK>
0x502C	0x978B	# <CJK>
0x502D	0x534F	# <CJK>
0x502E	0x631F	# <CJK>
0x502F	0x643A	# <CJK>
0x5030	0x90AA	# <CJK>
0x5031	0x659C	# <CJK>
0x5032	0x80C1	# <CJK>
0x5033	0x8C10	# <CJK>
0x5034	0x5199	# <CJK>
0x5035	0x68B0	# <CJK>
0x5036	0x5378	# <CJK>
0x5037	0x87F9	# <CJK>
0x5038	0x61C8	# <CJK>
0x5039	0x6CC4	# <CJK>
0x503A	0x6CFB	# <CJK>
0x503B	0x8C22	# <CJK>
0x503C	0x5C51	# <CJK>
0x503D	0x85AA	# <CJK>
0x503E	0x82AF	# <CJK>
0x503F	0x950C	# <CJK>
0x5040	0x6B23	# <CJK>
0x5041	0x8F9B	# <CJK>
0x5042	0x65B0	# <CJK>
0x5043	0x5FFB	# <CJK>
0x5044	0x5FC3	# <CJK>
0x5045	0x4FE1	# <CJK>
0x5046	0x8845	# <CJK>
0x5047	0x661F	# <CJK>
0x5048	0x8165	# <CJK>
0x5049	0x7329	# <CJK>
0x504A	0x60FA	# <CJK>
0x504B	0x5174	# <CJK>
0x504C	0x5211	# <CJK>
0x504D	0x578B	# <CJK>
0x504E	0x5F62	# <CJK>
0x504F	0x90A2	# <CJK>
0x5050	0x884C	# <CJK>
0x5051	0x9192	# <CJK>
0x5052	0x5E78	# <CJK>
0x5053	0x674F	# <CJK>
0x5054	0x6027	# <CJK>
0x5055	0x59D3	# <CJK>
0x5056	0x5144	# <CJK>
0x5057	0x51F6	# <CJK>
0x5058	0x80F8	# <CJK>
0x5059	0x5308	# <CJK>
0x505A	0x6C79	# <CJK>
0x505B	0x96C4	# <CJK>
0x505C	0x718A	# <CJK>
0x505D	0x4F11	# <CJK>
0x505E	0x4FEE	# <CJK>
0x505F	0x7F9E	# <CJK>
0x5060	0x673D	# <CJK>
0x5061	0x55C5	# <CJK>
0x5062	0x9508	# <CJK>
0x5063	0x79C0	# <CJK>
0x5064	0x8896	# <CJK>
0x5065	0x7EE3	# <CJK>
0x5066	0x589F	# <CJK>
0x5067	0x620C	# <CJK>
0x5068	0x9700	# <CJK>
0x5069	0x865A	# <CJK>
0x506A	0x5618	# <CJK>
0x506B	0x987B	# <CJK>
0x506C	0x5F90	# <CJK>
0x506D	0x8BB8	# <CJK>
0x506E	0x84C4	# <CJK>
0x506F	0x9157	# <CJK>
0x5070	0x53D9	# <CJK>
0x5071	0x65ED	# <CJK>
0x5072	0x5E8F	# <CJK>
0x5073	0x755C	# <CJK>
0x5074	0x6064	# <CJK>
0x5075	0x7D6E	# <CJK>
0x5076	0x5A7F	# <CJK>
0x5077	0x7EEA	# <CJK>
0x5078	0x7EED	# <CJK>
0x5079	0x8F69	# <CJK>
0x507A	0x55A7	# <CJK>
0x507B	0x5BA3	# <CJK>
0x507C	0x60AC	# <CJK>
0x507D	0x65CB	# <CJK>
0x507E	0x7384	# <CJK>
0x5121	0x9009	# <CJK>
0x5122	0x7663	# <CJK>
0x5123	0x7729	# <CJK>
0x5124	0x7EDA	# <CJK>
0x5125	0x9774	# <CJK>
0x5126	0x859B	# <CJK>
0x5127	0x5B66	# <CJK>
0x5128	0x7A74	# <CJK>
0x5129	0x96EA	# <CJK>
0x512A	0x8840	# <CJK>
0x512B	0x52CB	# <CJK>
0x512C	0x718F	# <CJK>
0x512D	0x5FAA	# <CJK>
0x512E	0x65EC	# <CJK>
0x512F	0x8BE2	# <CJK>
0x5130	0x5BFB	# <CJK>
0x5131	0x9A6F	# <CJK>
0x5132	0x5DE1	# <CJK>
0x5133	0x6B89	# <CJK>
0x5134	0x6C5B	# <CJK>
0x5135	0x8BAD	# <CJK>
0x5136	0x8BAF	# <CJK>
0x5137	0x900A	# <CJK>
0x5138	0x8FC5	# <CJK>
0x5139	0x538B	# <CJK>
0x513A	0x62BC	# <CJK>
0x513B	0x9E26	# <CJK>
0x513C	0x9E2D	# <CJK>
0x513D	0x5440	# <CJK>
0x513E	0x4E2B	# <CJK>
0x513F	0x82BD	# <CJK>
0x5140	0x7259	# <CJK>
0x5141	0x869C	# <CJK>
0x5142	0x5D16	# <CJK>
0x5143	0x8859	# <CJK>
0x5144	0x6DAF	# <CJK>
0x5145	0x96C5	# <CJK>
0x5146	0x54D1	# <CJK>
0x5147	0x4E9A	# <CJK>
0x5148	0x8BB6	# <CJK>
0x5149	0x7109	# <CJK>
0x514A	0x54BD	# <CJK>
0x514B	0x9609	# <CJK>
0x514C	0x70DF	# <CJK>
0x514D	0x6DF9	# <CJK>
0x514E	0x76D0	# <CJK>
0x514F	0x4E25	# <CJK>
0x5150	0x7814	# <CJK>
0x5151	0x8712	# <CJK>
0x5152	0x5CA9	# <CJK>
0x5153	0x5EF6	# <CJK>
0x5154	0x8A00	# <CJK>
0x5155	0x989C	# <CJK>
0x5156	0x960E	# <CJK>
0x5157	0x708E	# <CJK>
0x5158	0x6CBF	# <CJK>
0x5159	0x5944	# <CJK>
0x515A	0x63A9	# <CJK>
0x515B	0x773C	# <CJK>
0x515C	0x884D	# <CJK>
0x515D	0x6F14	# <CJK>
0x515E	0x8273	# <CJK>
0x515F	0x5830	# <CJK>
0x5160	0x71D5	# <CJK>
0x5161	0x538C	# <CJK>
0x5162	0x781A	# <CJK>
0x5163	0x96C1	# <CJK>
0x5164	0x5501	# <CJK>
0x5165	0x5F66	# <CJK>
0x5166	0x7130	# <CJK>
0x5167	0x5BB4	# <CJK>
0x5168	0x8C1A	# <CJK>
0x5169	0x9A8C	# <CJK>
0x516A	0x6B83	# <CJK>
0x516B	0x592E	# <CJK>
0x516C	0x9E2F	# <CJK>
0x516D	0x79E7	# <CJK>
0x516E	0x6768	# <CJK>
0x516F	0x626C	# <CJK>
0x5170	0x4F6F	# <CJK>
0x5171	0x75A1	# <CJK>
0x5172	0x7F8A	# <CJK>
0x5173	0x6D0B	# <CJK>
0x5174	0x9633	# <CJK>
0x5175	0x6C27	# <CJK>
0x5176	0x4EF0	# <CJK>
0x5177	0x75D2	# <CJK>
0x5178	0x517B	# <CJK>
0x5179	0x6837	# <CJK>
0x517A	0x6F3E	# <CJK>
0x517B	0x9080	# <CJK>
0x517C	0x8170	# <CJK>
0x517D	0x5996	# <CJK>
0x517E	0x7476	# <CJK>
0x5221	0x6447	# <CJK>
0x5222	0x5C27	# <CJK>
0x5223	0x9065	# <CJK>
0x5224	0x7A91	# <CJK>
0x5225	0x8C23	# <CJK>
0x5226	0x59DA	# <CJK>
0x5227	0x54AC	# <CJK>
0x5228	0x8200	# <CJK>
0x5229	0x836F	# <CJK>
0x522A	0x8981	# <CJK>
0x522B	0x8000	# <CJK>
0x522C	0x6930	# <CJK>
0x522D	0x564E	# <CJK>
0x522E	0x8036	# <CJK>
0x522F	0x7237	# <CJK>
0x5230	0x91CE	# <CJK>
0x5231	0x51B6	# <CJK>
0x5232	0x4E5F	# <CJK>
0x5233	0x9875	# <CJK>
0x5234	0x6396	# <CJK>
0x5235	0x4E1A	# <CJK>
0x5236	0x53F6	# <CJK>
0x5237	0x66F3	# <CJK>
0x5238	0x814B	# <CJK>
0x5239	0x591C	# <CJK>
0x523A	0x6DB2	# <CJK>
0x523B	0x4E00	# <CJK>
0x523C	0x58F9	# <CJK>
0x523D	0x533B	# <CJK>
0x523E	0x63D6	# <CJK>
0x523F	0x94F1	# <CJK>
0x5240	0x4F9D	# <CJK>
0x5241	0x4F0A	# <CJK>
0x5242	0x8863	# <CJK>
0x5243	0x9890	# <CJK>
0x5244	0x5937	# <CJK>
0x5245	0x9057	# <CJK>
0x5246	0x79FB	# <CJK>
0x5247	0x4EEA	# <CJK>
0x5248	0x80F0	# <CJK>
0x5249	0x7591	# <CJK>
0x524A	0x6C82	# <CJK>
0x524B	0x5B9C	# <CJK>
0x524C	0x59E8	# <CJK>
0x524D	0x5F5D	# <CJK>
0x524E	0x6905	# <CJK>
0x524F	0x8681	# <CJK>
0x5250	0x501A	# <CJK>
0x5251	0x5DF2	# <CJK>
0x5252	0x4E59	# <CJK>
0x5253	0x77E3	# <CJK>
0x5254	0x4EE5	# <CJK>
0x5255	0x827A	# <CJK>
0x5256	0x6291	# <CJK>
0x5257	0x6613	# <CJK>
0x5258	0x9091	# <CJK>
0x5259	0x5C79	# <CJK>
0x525A	0x4EBF	# <CJK>
0x525B	0x5F79	# <CJK>
0x525C	0x81C6	# <CJK>
0x525D	0x9038	# <CJK>
0x525E	0x8084	# <CJK>
0x525F	0x75AB	# <CJK>
0x5260	0x4EA6	# <CJK>
0x5261	0x88D4	# <CJK>
0x5262	0x610F	# <CJK>
0x5263	0x6BC5	# <CJK>
0x5264	0x5FC6	# <CJK>
0x5265	0x4E49	# <CJK>
0x5266	0x76CA	# <CJK>
0x5267	0x6EA2	# <CJK>
0x5268	0x8BE3	# <CJK>
0x5269	0x8BAE	# <CJK>
0x526A	0x8C0A	# <CJK>
0x526B	0x8BD1	# <CJK>
0x526C	0x5F02	# <CJK>
0x526D	0x7FFC	# <CJK>
0x526E	0x7FCC	# <CJK>
0x526F	0x7ECE	# <CJK>
0x5270	0x8335	# <CJK>
0x5271	0x836B	# <CJK>
0x5272	0x56E0	# <CJK>
0x5273	0x6BB7	# <CJK>
0x5274	0x97F3	# <CJK>
0x5275	0x9634	# <CJK>
0x5276	0x59FB	# <CJK>
0x5277	0x541F	# <CJK>
0x5278	0x94F6	# <CJK>
0x5279	0x6DEB	# <CJK>
0x527A	0x5BC5	# <CJK>
0x527B	0x996E	# <CJK>
0x527C	0x5C39	# <CJK>
0x527D	0x5F15	# <CJK>
0x527E	0x9690	# <CJK>
0x5321	0x5370	# <CJK>
0x5322	0x82F1	# <CJK>
0x5323	0x6A31	# <CJK>
0x5324	0x5A74	# <CJK>
0x5325	0x9E70	# <CJK>
0x5326	0x5E94	# <CJK>
0x5327	0x7F28	# <CJK>
0x5328	0x83B9	# <CJK>
0x5329	0x8424	# <CJK>
0x532A	0x8425	# <CJK>
0x532B	0x8367	# <CJK>
0x532C	0x8747	# <CJK>
0x532D	0x8FCE	# <CJK>
0x532E	0x8D62	# <CJK>
0x532F	0x76C8	# <CJK>
0x5330	0x5F71	# <CJK>
0x5331	0x9896	# <CJK>
0x5332	0x786C	# <CJK>
0x5333	0x6620	# <CJK>
0x5334	0x54DF	# <CJK>
0x5335	0x62E5	# <CJK>
0x5336	0x4F63	# <CJK>
0x5337	0x81C3	# <CJK>
0x5338	0x75C8	# <CJK>
0x5339	0x5EB8	# <CJK>
0x533A	0x96CD	# <CJK>
0x533B	0x8E0A	# <CJK>
0x533C	0x86F9	# <CJK>
0x533D	0x548F	# <CJK>
0x533E	0x6CF3	# <CJK>
0x533F	0x6D8C	# <CJK>
0x5340	0x6C38	# <CJK>
0x5341	0x607F	# <CJK>
0x5342	0x52C7	# <CJK>
0x5343	0x7528	# <CJK>
0x5344	0x5E7D	# <CJK>
0x5345	0x4F18	# <CJK>
0x5346	0x60A0	# <CJK>
0x5347	0x5FE7	# <CJK>
0x5348	0x5C24	# <CJK>
0x5349	0x7531	# <CJK>
0x534A	0x90AE	# <CJK>
0x534B	0x94C0	# <CJK>
0x534C	0x72B9	# <CJK>
0x534D	0x6CB9	# <CJK>
0x534E	0x6E38	# <CJK>
0x534F	0x9149	# <CJK>
0x5350	0x6709	# <CJK>
0x5351	0x53CB	# <CJK>
0x5352	0x53F3	# <CJK>
0x5353	0x4F51	# <CJK>
0x5354	0x91C9	# <CJK>
0x5355	0x8BF1	# <CJK>
0x5356	0x53C8	# <CJK>
0x5357	0x5E7C	# <CJK>
0x5358	0x8FC2	# <CJK>
0x5359	0x6DE4	# <CJK>
0x535A	0x4E8E	# <CJK>
0x535B	0x76C2	# <CJK>
0x535C	0x6986	# <CJK>
0x535D	0x865E	# <CJK>
0x535E	0x611A	# <CJK>
0x535F	0x8206	# <CJK>
0x5360	0x4F59	# <CJK>
0x5361	0x4FDE	# <CJK>
0x5362	0x903E	# <CJK>
0x5363	0x9C7C	# <CJK>
0x5364	0x6109	# <CJK>
0x5365	0x6E1D	# <CJK>
0x5366	0x6E14	# <CJK>
0x5367	0x9685	# <CJK>
0x5368	0x4E88	# <CJK>
0x5369	0x5A31	# <CJK>
0x536A	0x96E8	# <CJK>
0x536B	0x4E0E	# <CJK>
0x536C	0x5C7F	# <CJK>
0x536D	0x79B9	# <CJK>
0x536E	0x5B87	# <CJK>
0x536F	0x8BED	# <CJK>
0x5370	0x7FBD	# <CJK>
0x5371	0x7389	# <CJK>
0x5372	0x57DF	# <CJK>
0x5373	0x828B	# <CJK>
0x5374	0x90C1	# <CJK>
0x5375	0x5401	# <CJK>
0x5376	0x9047	# <CJK>
0x5377	0x55BB	# <CJK>
0x5378	0x5CEA	# <CJK>
0x5379	0x5FA1	# <CJK>
0x537A	0x6108	# <CJK>
0x537B	0x6B32	# <CJK>
0x537C	0x72F1	# <CJK>
0x537D	0x80B2	# <CJK>
0x537E	0x8A89	# <CJK>
0x5421	0x6D74	# <CJK>
0x5422	0x5BD3	# <CJK>
0x5423	0x88D5	# <CJK>
0x5424	0x9884	# <CJK>
0x5425	0x8C6B	# <CJK>
0x5426	0x9A6D	# <CJK>
0x5427	0x9E33	# <CJK>
0x5428	0x6E0A	# <CJK>
0x5429	0x51A4	# <CJK>
0x542A	0x5143	# <CJK>
0x542B	0x57A3	# <CJK>
0x542C	0x8881	# <CJK>
0x542D	0x539F	# <CJK>
0x542E	0x63F4	# <CJK>
0x542F	0x8F95	# <CJK>
0x5430	0x56ED	# <CJK>
0x5431	0x5458	# <CJK>
0x5432	0x5706	# <CJK>
0x5433	0x733F	# <CJK>
0x5434	0x6E90	# <CJK>
0x5435	0x7F18	# <CJK>
0x5436	0x8FDC	# <CJK>
0x5437	0x82D1	# <CJK>
0x5438	0x613F	# <CJK>
0x5439	0x6028	# <CJK>
0x543A	0x9662	# <CJK>
0x543B	0x66F0	# <CJK>
0x543C	0x7EA6	# <CJK>
0x543D	0x8D8A	# <CJK>
0x543E	0x8DC3	# <CJK>
0x543F	0x94A5	# <CJK>
0x5440	0x5CB3	# <CJK>
0x5441	0x7CA4	# <CJK>
0x5442	0x6708	# <CJK>
0x5443	0x60A6	# <CJK>
0x5444	0x9605	# <CJK>
0x5445	0x8018	# <CJK>
0x5446	0x4E91	# <CJK>
0x5447	0x90E7	# <CJK>
0x5448	0x5300	# <CJK>
0x5449	0x9668	# <CJK>
0x544A	0x5141	# <CJK>
0x544B	0x8FD0	# <CJK>
0x544C	0x8574	# <CJK>
0x544D	0x915D	# <CJK>
0x544E	0x6655	# <CJK>
0x544F	0x97F5	# <CJK>
0x5450	0x5B55	# <CJK>
0x5451	0x531D	# <CJK>
0x5452	0x7838	# <CJK>
0x5453	0x6742	# <CJK>
0x5454	0x683D	# <CJK>
0x5455	0x54C9	# <CJK>
0x5456	0x707E	# <CJK>
0x5457	0x5BB0	# <CJK>
0x5458	0x8F7D	# <CJK>
0x5459	0x518D	# <CJK>
0x545A	0x5728	# <CJK>
0x545B	0x54B1	# <CJK>
0x545C	0x6512	# <CJK>
0x545D	0x6682	# <CJK>
0x545E	0x8D5E	# <CJK>
0x545F	0x8D43	# <CJK>
0x5460	0x810F	# <CJK>
0x5461	0x846C	# <CJK>
0x5462	0x906D	# <CJK>
0x5463	0x7CDF	# <CJK>
0x5464	0x51FF	# <CJK>
0x5465	0x85FB	# <CJK>
0x5466	0x67A3	# <CJK>
0x5467	0x65E9	# <CJK>
0x5468	0x6FA1	# <CJK>
0x5469	0x86A4	# <CJK>
0x546A	0x8E81	# <CJK>
0x546B	0x566A	# <CJK>
0x546C	0x9020	# <CJK>
0x546D	0x7682	# <CJK>
0x546E	0x7076	# <CJK>
0x546F	0x71E5	# <CJK>
0x5470	0x8D23	# <CJK>
0x5471	0x62E9	# <CJK>
0x5472	0x5219	# <CJK>
0x5473	0x6CFD	# <CJK>
0x5474	0x8D3C	# <CJK>
0x5475	0x600E	# <CJK>
0x5476	0x589E	# <CJK>
0x5477	0x618E	# <CJK>
0x5478	0x66FE	# <CJK>
0x5479	0x8D60	# <CJK>
0x547A	0x624E	# <CJK>
0x547B	0x55B3	# <CJK>
0x547C	0x6E23	# <CJK>
0x547D	0x672D	# <CJK>
0x547E	0x8F67	# <CJK>
0x5521	0x94E1	# <CJK>
0x5522	0x95F8	# <CJK>
0x5523	0x7728	# <CJK>
0x5524	0x6805	# <CJK>
0x5525	0x69A8	# <CJK>
0x5526	0x548B	# <CJK>
0x5527	0x4E4D	# <CJK>
0x5528	0x70B8	# <CJK>
0x5529	0x8BC8	# <CJK>
0x552A	0x6458	# <CJK>
0x552B	0x658B	# <CJK>
0x552C	0x5B85	# <CJK>
0x552D	0x7A84	# <CJK>
0x552E	0x503A	# <CJK>
0x552F	0x5BE8	# <CJK>
0x5530	0x77BB	# <CJK>
0x5531	0x6BE1	# <CJK>
0x5532	0x8A79	# <CJK>
0x5533	0x7C98	# <CJK>
0x5534	0x6CBE	# <CJK>
0x5535	0x76CF	# <CJK>
0x5536	0x65A9	# <CJK>
0x5537	0x8F97	# <CJK>
0x5538	0x5D2D	# <CJK>
0x5539	0x5C55	# <CJK>
0x553A	0x8638	# <CJK>
0x553B	0x6808	# <CJK>
0x553C	0x5360	# <CJK>
0x553D	0x6218	# <CJK>
0x553E	0x7AD9	# <CJK>
0x553F	0x6E5B	# <CJK>
0x5540	0x7EFD	# <CJK>
0x5541	0x6A1F	# <CJK>
0x5542	0x7AE0	# <CJK>
0x5543	0x5F70	# <CJK>
0x5544	0x6F33	# <CJK>
0x5545	0x5F20	# <CJK>
0x5546	0x638C	# <CJK>
0x5547	0x6DA8	# <CJK>
0x5548	0x6756	# <CJK>
0x5549	0x4E08	# <CJK>
0x554A	0x5E10	# <CJK>
0x554B	0x8D26	# <CJK>
0x554C	0x4ED7	# <CJK>
0x554D	0x80C0	# <CJK>
0x554E	0x7634	# <CJK>
0x554F	0x969C	# <CJK>
0x5550	0x62DB	# <CJK>
0x5551	0x662D	# <CJK>
0x5552	0x627E	# <CJK>
0x5553	0x6CBC	# <CJK>
0x5554	0x8D75	# <CJK>
0x5555	0x7167	# <CJK>
0x5556	0x7F69	# <CJK>
0x5557	0x5146	# <CJK>
0x5558	0x8087	# <CJK>
0x5559	0x53EC	# <CJK>
0x555A	0x906E	# <CJK>
0x555B	0x6298	# <CJK>
0x555C	0x54F2	# <CJK>
0x555D	0x86F0	# <CJK>
0x555E	0x8F99	# <CJK>
0x555F	0x8005	# <CJK>
0x5560	0x9517	# <CJK>
0x5561	0x8517	# <CJK>
0x5562	0x8FD9	# <CJK>
0x5563	0x6D59	# <CJK>
0x5564	0x73CD	# <CJK>
0x5565	0x659F	# <CJK>
0x5566	0x771F	# <CJK>
0x5567	0x7504	# <CJK>
0x5568	0x7827	# <CJK>
0x5569	0x81FB	# <CJK>
0x556A	0x8D1E	# <CJK>
0x556B	0x9488	# <CJK>
0x556C	0x4FA6	# <CJK>
0x556D	0x6795	# <CJK>
0x556E	0x75B9	# <CJK>
0x556F	0x8BCA	# <CJK>
0x5570	0x9707	# <CJK>
0x5571	0x632F	# <CJK>
0x5572	0x9547	# <CJK>
0x5573	0x9635	# <CJK>
0x5574	0x84B8	# <CJK>
0x5575	0x6323	# <CJK>
0x5576	0x7741	# <CJK>
0x5577	0x5F81	# <CJK>
0x5578	0x72F0	# <CJK>
0x5579	0x4E89	# <CJK>
0x557A	0x6014	# <CJK>
0x557B	0x6574	# <CJK>
0x557C	0x62EF	# <CJK>
0x557D	0x6B63	# <CJK>
0x557E	0x653F	# <CJK>
0x5621	0x5E27	# <CJK>
0x5622	0x75C7	# <CJK>
0x5623	0x90D1	# <CJK>
0x5624	0x8BC1	# <CJK>
0x5625	0x829D	# <CJK>
0x5626	0x679D	# <CJK>
0x5627	0x652F	# <CJK>
0x5628	0x5431	# <CJK>
0x5629	0x8718	# <CJK>
0x562A	0x77E5	# <CJK>
0x562B	0x80A2	# <CJK>
0x562C	0x8102	# <CJK>
0x562D	0x6C41	# <CJK>
0x562E	0x4E4B	# <CJK>
0x562F	0x7EC7	# <CJK>
0x5630	0x804C	# <CJK>
0x5631	0x76F4	# <CJK>
0x5632	0x690D	# <CJK>
0x5633	0x6B96	# <CJK>
0x5634	0x6267	# <CJK>
0x5635	0x503C	# <CJK>
0x5636	0x4F84	# <CJK>
0x5637	0x5740	# <CJK>
0x5638	0x6307	# <CJK>
0x5639	0x6B62	# <CJK>
0x563A	0x8DBE	# <CJK>
0x563B	0x53EA	# <CJK>
0x563C	0x65E8	# <CJK>
0x563D	0x7EB8	# <CJK>
0x563E	0x5FD7	# <CJK>
0x563F	0x631A	# <CJK>
0x5640	0x63B7	# <CJK>
0x5641	0x81F3	# <CJK>
0x5642	0x81F4	# <CJK>
0x5643	0x7F6E	# <CJK>
0x5644	0x5E1C	# <CJK>
0x5645	0x5CD9	# <CJK>
0x5646	0x5236	# <CJK>
0x5647	0x667A	# <CJK>
0x5648	0x79E9	# <CJK>
0x5649	0x7A1A	# <CJK>
0x564A	0x8D28	# <CJK>
0x564B	0x7099	# <CJK>
0x564C	0x75D4	# <CJK>
0x564D	0x6EDE	# <CJK>
0x564E	0x6CBB	# <CJK>
0x564F	0x7A92	# <CJK>
0x5650	0x4E2D	# <CJK>
0x5651	0x76C5	# <CJK>
0x5652	0x5FE0	# <CJK>
0x5653	0x949F	# <CJK>
0x5654	0x8877	# <CJK>
0x5655	0x7EC8	# <CJK>
0x5656	0x79CD	# <CJK>
0x5657	0x80BF	# <CJK>
0x5658	0x91CD	# <CJK>
0x5659	0x4EF2	# <CJK>
0x565A	0x4F17	# <CJK>
0x565B	0x821F	# <CJK>
0x565C	0x5468	# <CJK>
0x565D	0x5DDE	# <CJK>
0x565E	0x6D32	# <CJK>
0x565F	0x8BCC	# <CJK>
0x5660	0x7CA5	# <CJK>
0x5661	0x8F74	# <CJK>
0x5662	0x8098	# <CJK>
0x5663	0x5E1A	# <CJK>
0x5664	0x5492	# <CJK>
0x5665	0x76B1	# <CJK>
0x5666	0x5B99	# <CJK>
0x5667	0x663C	# <CJK>
0x5668	0x9AA4	# <CJK>
0x5669	0x73E0	# <CJK>
0x566A	0x682A	# <CJK>
0x566B	0x86DB	# <CJK>
0x566C	0x6731	# <CJK>
0x566D	0x732A	# <CJK>
0x566E	0x8BF8	# <CJK>
0x566F	0x8BDB	# <CJK>
0x5670	0x9010	# <CJK>
0x5671	0x7AF9	# <CJK>
0x5672	0x70DB	# <CJK>
0x5673	0x716E	# <CJK>
0x5674	0x62C4	# <CJK>
0x5675	0x77A9	# <CJK>
0x5676	0x5631	# <CJK>
0x5677	0x4E3B	# <CJK>
0x5678	0x8457	# <CJK>
0x5679	0x67F1	# <CJK>
0x567A	0x52A9	# <CJK>
0x567B	0x86C0	# <CJK>
0x567C	0x8D2E	# <CJK>
0x567D	0x94F8	# <CJK>
0x567E	0x7B51	# <CJK>
0x5721	0x4F4F	# <CJK>
0x5722	0x6CE8	# <CJK>
0x5723	0x795D	# <CJK>
0x5724	0x9A7B	# <CJK>
0x5725	0x6293	# <CJK>
0x5726	0x722A	# <CJK>
0x5727	0x62FD	# <CJK>
0x5728	0x4E13	# <CJK>
0x5729	0x7816	# <CJK>
0x572A	0x8F6C	# <CJK>
0x572B	0x64B0	# <CJK>
0x572C	0x8D5A	# <CJK>
0x572D	0x7BC6	# <CJK>
0x572E	0x6869	# <CJK>
0x572F	0x5E84	# <CJK>
0x5730	0x88C5	# <CJK>
0x5731	0x5986	# <CJK>
0x5732	0x649E	# <CJK>
0x5733	0x58EE	# <CJK>
0x5734	0x72B6	# <CJK>
0x5735	0x690E	# <CJK>
0x5736	0x9525	# <CJK>
0x5737	0x8FFD	# <CJK>
0x5738	0x8D58	# <CJK>
0x5739	0x5760	# <CJK>
0x573A	0x7F00	# <CJK>
0x573B	0x8C06	# <CJK>
0x573C	0x51C6	# <CJK>
0x573D	0x6349	# <CJK>
0x573E	0x62D9	# <CJK>
0x573F	0x5353	# <CJK>
0x5740	0x684C	# <CJK>
0x5741	0x7422	# <CJK>
0x5742	0x8301	# <CJK>
0x5743	0x914C	# <CJK>
0x5744	0x5544	# <CJK>
0x5745	0x7740	# <CJK>
0x5746	0x707C	# <CJK>
0x5747	0x6D4A	# <CJK>
0x5748	0x5179	# <CJK>
0x5749	0x54A8	# <CJK>
0x574A	0x8D44	# <CJK>
0x574B	0x59FF	# <CJK>
0x574C	0x6ECB	# <CJK>
0x574D	0x6DC4	# <CJK>
0x574E	0x5B5C	# <CJK>
0x574F	0x7D2B	# <CJK>
0x5750	0x4ED4	# <CJK>
0x5751	0x7C7D	# <CJK>
0x5752	0x6ED3	# <CJK>
0x5753	0x5B50	# <CJK>
0x5754	0x81EA	# <CJK>
0x5755	0x6E0D	# <CJK>
0x5756	0x5B57	# <CJK>
0x5757	0x9B03	# <CJK>
0x5758	0x68D5	# <CJK>
0x5759	0x8E2A	# <CJK>
0x575A	0x5B97	# <CJK>
0x575B	0x7EFC	# <CJK>
0x575C	0x603B	# <CJK>
0x575D	0x7EB5	# <CJK>
0x575E	0x90B9	# <CJK>
0x575F	0x8D70	# <CJK>
0x5760	0x594F	# <CJK>
0x5761	0x63CD	# <CJK>
0x5762	0x79DF	# <CJK>
0x5763	0x8DB3	# <CJK>
0x5764	0x5352	# <CJK>
0x5765	0x65CF	# <CJK>
0x5766	0x7956	# <CJK>
0x5767	0x8BC5	# <CJK>
0x5768	0x963B	# <CJK>
0x5769	0x7EC4	# <CJK>
0x576A	0x94BB	# <CJK>
0x576B	0x7E82	# <CJK>
0x576C	0x5634	# <CJK>
0x576D	0x9189	# <CJK>
0x576E	0x6700	# <CJK>
0x576F	0x7F6A	# <CJK>
0x5770	0x5C0A	# <CJK>
0x5771	0x9075	# <CJK>
0x5772	0x6628	# <CJK>
0x5773	0x5DE6	# <CJK>
0x5774	0x4F50	# <CJK>
0x5775	0x67DE	# <CJK>
0x5776	0x505A	# <CJK>
0x5777	0x4F5C	# <CJK>
0x5778	0x5750	# <CJK>
0x5779	0x5EA7	# <CJK>
0x5821	0x4E8D	# <CJK>
0x5822	0x4E0C	# <CJK>
0x5823	0x5140	# <CJK>
0x5824	0x4E10	# <CJK>
0x5825	0x5EFF	# <CJK>
0x5826	0x5345	# <CJK>
0x5827	0x4E15	# <CJK>
0x5828	0x4E98	# <CJK>
0x5829	0x4E1E	# <CJK>
0x582A	0x9B32	# <CJK>
0x582B	0x5B6C	# <CJK>
0x582C	0x5669	# <CJK>
0x582D	0x4E28	# <CJK>
0x582E	0x79BA	# <CJK>
0x582F	0x4E3F	# <CJK>
0x5830	0x5315	# <CJK>
0x5831	0x4E47	# <CJK>
0x5832	0x592D	# <CJK>
0x5833	0x723B	# <CJK>
0x5834	0x536E	# <CJK>
0x5835	0x6C10	# <CJK>
0x5836	0x56DF	# <CJK>
0x5837	0x80E4	# <CJK>
0x5838	0x9997	# <CJK>
0x5839	0x6BD3	# <CJK>
0x583A	0x777E	# <CJK>
0x583B	0x9F17	# <CJK>
0x583C	0x4E36	# <CJK>
0x583D	0x4E9F	# <CJK>
0x583E	0x9F10	# <CJK>
0x583F	0x4E5C	# <CJK>
0x5840	0x4E69	# <CJK>
0x5841	0x4E93	# <CJK>
0x5842	0x8288	# <CJK>
0x5843	0x5B5B	# <CJK>
0x5844	0x556C	# <CJK>
0x5845	0x560F	# <CJK>
0x5846	0x4EC4	# <CJK>
0x5847	0x538D	# <CJK>
0x5848	0x539D	# <CJK>
0x5849	0x53A3	# <CJK>
0x584A	0x53A5	# <CJK>
0x584B	0x53AE	# <CJK>
0x584C	0x9765	# <CJK>
0x584D	0x8D5D	# <CJK>
0x584E	0x531A	# <CJK>
0x584F	0x53F5	# <CJK>
0x5850	0x5326	# <CJK>
0x5851	0x532E	# <CJK>
0x5852	0x533E	# <CJK>
0x5853	0x8D5C	# <CJK>
0x5854	0x5366	# <CJK>
0x5855	0x5363	# <CJK>
0x5856	0x5202	# <CJK>
0x5857	0x5208	# <CJK>
0x5858	0x520E	# <CJK>
0x5859	0x522D	# <CJK>
0x585A	0x5233	# <CJK>
0x585B	0x523F	# <CJK>
0x585C	0x5240	# <CJK>
0x585D	0x524C	# <CJK>
0x585E	0x525E	# <CJK>
0x585F	0x5261	# <CJK>
0x5860	0x525C	# <CJK>
0x5861	0x84AF	# <CJK>
0x5862	0x527D	# <CJK>
0x5863	0x5282	# <CJK>
0x5864	0x5281	# <CJK>
0x5865	0x5290	# <CJK>
0x5866	0x5293	# <CJK>
0x5867	0x5182	# <CJK>
0x5868	0x7F54	# <CJK>
0x5869	0x4EBB	# <CJK>
0x586A	0x4EC3	# <CJK>
0x586B	0x4EC9	# <CJK>
0x586C	0x4EC2	# <CJK>
0x586D	0x4EE8	# <CJK>
0x586E	0x4EE1	# <CJK>
0x586F	0x4EEB	# <CJK>
0x5870	0x4EDE	# <CJK>
0x5871	0x4F1B	# <CJK>
0x5872	0x4EF3	# <CJK>
0x5873	0x4F22	# <CJK>
0x5874	0x4F64	# <CJK>
0x5875	0x4EF5	# <CJK>
0x5876	0x4F25	# <CJK>
0x5877	0x4F27	# <CJK>
0x5878	0x4F09	# <CJK>
0x5879	0x4F2B	# <CJK>
0x587A	0x4F5E	# <CJK>
0x587B	0x4F67	# <CJK>
0x587C	0x6538	# <CJK>
0x587D	0x4F5A	# <CJK>
0x587E	0x4F5D	# <CJK>
0x5921	0x4F5F	# <CJK>
0x5922	0x4F57	# <CJK>
0x5923	0x4F32	# <CJK>
0x5924	0x4F3D	# <CJK>
0x5925	0x4F76	# <CJK>
0x5926	0x4F74	# <CJK>
0x5927	0x4F91	# <CJK>
0x5928	0x4F89	# <CJK>
0x5929	0x4F83	# <CJK>
0x592A	0x4F8F	# <CJK>
0x592B	0x4F7E	# <CJK>
0x592C	0x4F7B	# <CJK>
0x592D	0x4FAA	# <CJK>
0x592E	0x4F7C	# <CJK>
0x592F	0x4FAC	# <CJK>
0x5930	0x4F94	# <CJK>
0x5931	0x4FE6	# <CJK>
0x5932	0x4FE8	# <CJK>
0x5933	0x4FEA	# <CJK>
0x5934	0x4FC5	# <CJK>
0x5935	0x4FDA	# <CJK>
0x5936	0x4FE3	# <CJK>
0x5937	0x4FDC	# <CJK>
0x5938	0x4FD1	# <CJK>
0x5939	0x4FDF	# <CJK>
0x593A	0x4FF8	# <CJK>
0x593B	0x5029	# <CJK>
0x593C	0x504C	# <CJK>
0x593D	0x4FF3	# <CJK>
0x593E	0x502C	# <CJK>
0x593F	0x500F	# <CJK>
0x5940	0x502E	# <CJK>
0x5941	0x502D	# <CJK>
0x5942	0x4FFE	# <CJK>
0x5943	0x501C	# <CJK>
0x5944	0x500C	# <CJK>
0x5945	0x5025	# <CJK>
0x5946	0x5028	# <CJK>
0x5947	0x507E	# <CJK>
0x5948	0x5043	# <CJK>
0x5949	0x5055	# <CJK>
0x594A	0x5048	# <CJK>
0x594B	0x504E	# <CJK>
0x594C	0x506C	# <CJK>
0x594D	0x507B	# <CJK>
0x594E	0x50A5	# <CJK>
0x594F	0x50A7	# <CJK>
0x5950	0x50A9	# <CJK>
0x5951	0x50BA	# <CJK>
0x5952	0x50D6	# <CJK>
0x5953	0x5106	# <CJK>
0x5954	0x50ED	# <CJK>
0x5955	0x50EC	# <CJK>
0x5956	0x50E6	# <CJK>
0x5957	0x50EE	# <CJK>
0x5958	0x5107	# <CJK>
0x5959	0x510B	# <CJK>
0x595A	0x4EDD	# <CJK>
0x595B	0x6C3D	# <CJK>
0x595C	0x4F58	# <CJK>
0x595D	0x4F65	# <CJK>
0x595E	0x4FCE	# <CJK>
0x595F	0x9FA0	# <CJK>
0x5960	0x6C46	# <CJK>
0x5961	0x7C74	# <CJK>
0x5962	0x516E	# <CJK>
0x5963	0x5DFD	# <CJK>
0x5964	0x9EC9	# <CJK>
0x5965	0x9998	# <CJK>
0x5966	0x5181	# <CJK>
0x5967	0x5914	# <CJK>
0x5968	0x52F9	# <CJK>
0x5969	0x530D	# <CJK>
0x596A	0x8A07	# <CJK>
0x596B	0x5310	# <CJK>
0x596C	0x51EB	# <CJK>
0x596D	0x5919	# <CJK>
0x596E	0x5155	# <CJK>
0x596F	0x4EA0	# <CJK>
0x5970	0x5156	# <CJK>
0x5971	0x4EB3	# <CJK>
0x5972	0x886E	# <CJK>
0x5973	0x88A4	# <CJK>
0x5974	0x4EB5	# <CJK>
0x5975	0x8114	# <CJK>
0x5976	0x88D2	# <CJK>
0x5977	0x7980	# <CJK>
0x5978	0x5B34	# <CJK>
0x5979	0x8803	# <CJK>
0x597A	0x7FB8	# <CJK>
0x597B	0x51AB	# <CJK>
0x597C	0x51B1	# <CJK>
0x597D	0x51BD	# <CJK>
0x597E	0x51BC	# <CJK>
0x5A21	0x51C7	# <CJK>
0x5A22	0x5196	# <CJK>
0x5A23	0x51A2	# <CJK>
0x5A24	0x51A5	# <CJK>
0x5A25	0x8BA0	# <CJK>
0x5A26	0x8BA6	# <CJK>
0x5A27	0x8BA7	# <CJK>
0x5A28	0x8BAA	# <CJK>
0x5A29	0x8BB4	# <CJK>
0x5A2A	0x8BB5	# <CJK>
0x5A2B	0x8BB7	# <CJK>
0x5A2C	0x8BC2	# <CJK>
0x5A2D	0x8BC3	# <CJK>
0x5A2E	0x8BCB	# <CJK>
0x5A2F	0x8BCF	# <CJK>
0x5A30	0x8BCE	# <CJK>
0x5A31	0x8BD2	# <CJK>
0x5A32	0x8BD3	# <CJK>
0x5A33	0x8BD4	# <CJK>
0x5A34	0x8BD6	# <CJK>
0x5A35	0x8BD8	# <CJK>
0x5A36	0x8BD9	# <CJK>
0x5A37	0x8BDC	# <CJK>
0x5A38	0x8BDF	# <CJK>
0x5A39	0x8BE0	# <CJK>
0x5A3A	0x8BE4	# <CJK>
0x5A3B	0x8BE8	# <CJK>
0x5A3C	0x8BE9	# <CJK>
0x5A3D	0x8BEE	# <CJK>
0x5A3E	0x8BF0	# <CJK>
0x5A3F	0x8BF3	# <CJK>
0x5A40	0x8BF6	# <CJK>
0x5A41	0x8BF9	# <CJK>
0x5A42	0x8BFC	# <CJK>
0x5A43	0x8BFF	# <CJK>
0x5A44	0x8C00	# <CJK>
0x5A45	0x8C02	# <CJK>
0x5A46	0x8C04	# <CJK>
0x5A47	0x8C07	# <CJK>
0x5A48	0x8C0C	# <CJK>
0x5A49	0x8C0F	# <CJK>
0x5A4A	0x8C11	# <CJK>
0x5A4B	0x8C12	# <CJK>
0x5A4C	0x8C14	# <CJK>
0x5A4D	0x8C15	# <CJK>
0x5A4E	0x8C16	# <CJK>
0x5A4F	0x8C19	# <CJK>
0x5A50	0x8C1B	# <CJK>
0x5A51	0x8C18	# <CJK>
0x5A52	0x8C1D	# <CJK>
0x5A53	0x8C1F	# <CJK>
0x5A54	0x8C20	# <CJK>
0x5A55	0x8C21	# <CJK>
0x5A56	0x8C25	# <CJK>
0x5A57	0x8C27	# <CJK>
0x5A58	0x8C2A	# <CJK>
0x5A59	0x8C2B	# <CJK>
0x5A5A	0x8C2E	# <CJK>
0x5A5B	0x8C2F	# <CJK>
0x5A5C	0x8C32	# <CJK>
0x5A5D	0x8C33	# <CJK>
0x5A5E	0x8C35	# <CJK>
0x5A5F	0x8C36	# <CJK>
0x5A60	0x5369	# <CJK>
0x5A61	0x537A	# <CJK>
0x5A62	0x961D	# <CJK>
0x5A63	0x9622	# <CJK>
0x5A64	0x9621	# <CJK>
0x5A65	0x9631	# <CJK>
0x5A66	0x962A	# <CJK>
0x5A67	0x963D	# <CJK>
0x5A68	0x963C	# <CJK>
0x5A69	0x9642	# <CJK>
0x5A6A	0x9649	# <CJK>
0x5A6B	0x9654	# <CJK>
0x5A6C	0x965F	# <CJK>
0x5A6D	0x9667	# <CJK>
0x5A6E	0x966C	# <CJK>
0x5A6F	0x9672	# <CJK>
0x5A70	0x9674	# <CJK>
0x5A71	0x9688	# <CJK>
0x5A72	0x968D	# <CJK>
0x5A73	0x9697	# <CJK>
0x5A74	0x96B0	# <CJK>
0x5A75	0x9097	# <CJK>
0x5A76	0x909B	# <CJK>
0x5A77	0x909D	# <CJK>
0x5A78	0x9099	# <CJK>
0x5A79	0x90AC	# <CJK>
0x5A7A	0x90A1	# <CJK>
0x5A7B	0x90B4	# <CJK>
0x5A7C	0x90B3	# <CJK>
0x5A7D	0x90B6	# <CJK>
0x5A7E	0x90BA	# <CJK>
0x5B21	0x90B8	# <CJK>
0x5B22	0x90B0	# <CJK>
0x5B23	0x90CF	# <CJK>
0x5B24	0x90C5	# <CJK>
0x5B25	0x90BE	# <CJK>
0x5B26	0x90D0	# <CJK>
0x5B27	0x90C4	# <CJK>
0x5B28	0x90C7	# <CJK>
0x5B29	0x90D3	# <CJK>
0x5B2A	0x90E6	# <CJK>
0x5B2B	0x90E2	# <CJK>
0x5B2C	0x90DC	# <CJK>
0x5B2D	0x90D7	# <CJK>
0x5B2E	0x90DB	# <CJK>
0x5B2F	0x90EB	# <CJK>
0x5B30	0x90EF	# <CJK>
0x5B31	0x90FE	# <CJK>
0x5B32	0x9104	# <CJK>
0x5B33	0x9122	# <CJK>
0x5B34	0x911E	# <CJK>
0x5B35	0x9123	# <CJK>
0x5B36	0x9131	# <CJK>
0x5B37	0x912F	# <CJK>
0x5B38	0x9139	# <CJK>
0x5B39	0x9143	# <CJK>
0x5B3A	0x9146	# <CJK>
0x5B3B	0x520D	# <CJK>
0x5B3C	0x5942	# <CJK>
0x5B3D	0x52A2	# <CJK>
0x5B3E	0x52AC	# <CJK>
0x5B3F	0x52AD	# <CJK>
0x5B40	0x52BE	# <CJK>
0x5B41	0x54FF	# <CJK>
0x5B42	0x52D0	# <CJK>
0x5B43	0x52D6	# <CJK>
0x5B44	0x52F0	# <CJK>
0x5B45	0x53DF	# <CJK>
0x5B46	0x71EE	# <CJK>
0x5B47	0x77CD	# <CJK>
0x5B48	0x5EF4	# <CJK>
0x5B49	0x51F5	# <CJK>
0x5B4A	0x51FC	# <CJK>
0x5B4B	0x9B2F	# <CJK>
0x5B4C	0x53B6	# <CJK>
0x5B4D	0x5F01	# <CJK>
0x5B4E	0x755A	# <CJK>
0x5B4F	0x5DEF	# <CJK>
0x5B50	0x574C	# <CJK>
0x5B51	0x57A9	# <CJK>
0x5B52	0x57A1	# <CJK>
0x5B53	0x587E	# <CJK>
0x5B54	0x58BC	# <CJK>
0x5B55	0x58C5	# <CJK>
0x5B56	0x58D1	# <CJK>
0x5B57	0x5729	# <CJK>
0x5B58	0x572C	# <CJK>
0x5B59	0x572A	# <CJK>
0x5B5A	0x5733	# <CJK>
0x5B5B	0x5739	# <CJK>
0x5B5C	0x572E	# <CJK>
0x5B5D	0x572F	# <CJK>
0x5B5E	0x575C	# <CJK>
0x5B5F	0x573B	# <CJK>
0x5B60	0x5742	# <CJK>
0x5B61	0x5769	# <CJK>
0x5B62	0x5785	# <CJK>
0x5B63	0x576B	# <CJK>
0x5B64	0x5786	# <CJK>
0x5B65	0x577C	# <CJK>
0x5B66	0x577B	# <CJK>
0x5B67	0x5768	# <CJK>
0x5B68	0x576D	# <CJK>
0x5B69	0x5776	# <CJK>
0x5B6A	0x5773	# <CJK>
0x5B6B	0x57AD	# <CJK>
0x5B6C	0x57A4	# <CJK>
0x5B6D	0x578C	# <CJK>
0x5B6E	0x57B2	# <CJK>
0x5B6F	0x57CF	# <CJK>
0x5B70	0x57A7	# <CJK>
0x5B71	0x57B4	# <CJK>
0x5B72	0x5793	# <CJK>
0x5B73	0x57A0	# <CJK>
0x5B74	0x57D5	# <CJK>
0x5B75	0x57D8	# <CJK>
0x5B76	0x57DA	# <CJK>
0x5B77	0x57D9	# <CJK>
0x5B78	0x57D2	# <CJK>
0x5B79	0x57B8	# <CJK>
0x5B7A	0x57F4	# <CJK>
0x5B7B	0x57EF	# <CJK>
0x5B7C	0x57F8	# <CJK>
0x5B7D	0x57E4	# <CJK>
0x5B7E	0x57DD	# <CJK>
0x5C21	0x580B	# <CJK>
0x5C22	0x580D	# <CJK>
0x5C23	0x57FD	# <CJK>
0x5C24	0x57ED	# <CJK>
0x5C25	0x5800	# <CJK>
0x5C26	0x581E	# <CJK>
0x5C27	0x5819	# <CJK>
0x5C28	0x5844	# <CJK>
0x5C29	0x5820	# <CJK>
0x5C2A	0x5865	# <CJK>
0x5C2B	0x586C	# <CJK>
0x5C2C	0x5881	# <CJK>
0x5C2D	0x5889	# <CJK>
0x5C2E	0x589A	# <CJK>
0x5C2F	0x5880	# <CJK>
0x5C30	0x99A8	# <CJK>
0x5C31	0x9F19	# <CJK>
0x5C32	0x61FF	# <CJK>
0x5C33	0x8279	# <CJK>
0x5C34	0x827D	# <CJK>
0x5C35	0x827F	# <CJK>
0x5C36	0x828F	# <CJK>
0x5C37	0x828A	# <CJK>
0x5C38	0x82A8	# <CJK>
0x5C39	0x8284	# <CJK>
0x5C3A	0x828E	# <CJK>
0x5C3B	0x8291	# <CJK>
0x5C3C	0x8297	# <CJK>
0x5C3D	0x8299	# <CJK>
0x5C3E	0x82AB	# <CJK>
0x5C3F	0x82B8	# <CJK>
0x5C40	0x82BE	# <CJK>
0x5C41	0x82B0	# <CJK>
0x5C42	0x82C8	# <CJK>
0x5C43	0x82CA	# <CJK>
0x5C44	0x82E3	# <CJK>
0x5C45	0x8298	# <CJK>
0x5C46	0x82B7	# <CJK>
0x5C47	0x82AE	# <CJK>
0x5C48	0x82CB	# <CJK>
0x5C49	0x82CC	# <CJK>
0x5C4A	0x82C1	# <CJK>
0x5C4B	0x82A9	# <CJK>
0x5C4C	0x82B4	# <CJK>
0x5C4D	0x82A1	# <CJK>
0x5C4E	0x82AA	# <CJK>
0x5C4F	0x829F	# <CJK>
0x5C50	0x82C4	# <CJK>
0x5C51	0x82CE	# <CJK>
0x5C52	0x82A4	# <CJK>
0x5C53	0x82E1	# <CJK>
0x5C54	0x8309	# <CJK>
0x5C55	0x82F7	# <CJK>
0x5C56	0x82E4	# <CJK>
0x5C57	0x830F	# <CJK>
0x5C58	0x8307	# <CJK>
0x5C59	0x82DC	# <CJK>
0x5C5A	0x82F4	# <CJK>
0x5C5B	0x82D2	# <CJK>
0x5C5C	0x82D8	# <CJK>
0x5C5D	0x830C	# <CJK>
0x5C5E	0x82FB	# <CJK>
0x5C5F	0x82D3	# <CJK>
0x5C60	0x8311	# <CJK>
0x5C61	0x831A	# <CJK>
0x5C62	0x8306	# <CJK>
0x5C63	0x8314	# <CJK>
0x5C64	0x8315	# <CJK>
0x5C65	0x82E0	# <CJK>
0x5C66	0x82D5	# <CJK>
0x5C67	0x831C	# <CJK>
0x5C68	0x8351	# <CJK>
0x5C69	0x835B	# <CJK>
0x5C6A	0x835C	# <CJK>
0x5C6B	0x8308	# <CJK>
0x5C6C	0x8392	# <CJK>
0x5C6D	0x833C	# <CJK>
0x5C6E	0x8334	# <CJK>
0x5C6F	0x8331	# <CJK>
0x5C70	0x839B	# <CJK>
0x5C71	0x835E	# <CJK>
0x5C72	0x832F	# <CJK>
0x5C73	0x834F	# <CJK>
0x5C74	0x8347	# <CJK>
0x5C75	0x8343	# <CJK>
0x5C76	0x835F	# <CJK>
0x5C77	0x8340	# <CJK>
0x5C78	0x8317	# <CJK>
0x5C79	0x8360	# <CJK>
0x5C7A	0x832D	# <CJK>
0x5C7B	0x833A	# <CJK>
0x5C7C	0x8333	# <CJK>
0x5C7D	0x8366	# <CJK>
0x5C7E	0x8365	# <CJK>
0x5D21	0x8368	# <CJK>
0x5D22	0x831B	# <CJK>
0x5D23	0x8369	# <CJK>
0x5D24	0x836C	# <CJK>
0x5D25	0x836A	# <CJK>
0x5D26	0x836D	# <CJK>
0x5D27	0x836E	# <CJK>
0x5D28	0x83B0	# <CJK>
0x5D29	0x8378	# <CJK>
0x5D2A	0x83B3	# <CJK>
0x5D2B	0x83B4	# <CJK>
0x5D2C	0x83A0	# <CJK>
0x5D2D	0x83AA	# <CJK>
0x5D2E	0x8393	# <CJK>
0x5D2F	0x839C	# <CJK>
0x5D30	0x8385	# <CJK>
0x5D31	0x837C	# <CJK>
0x5D32	0x83B6	# <CJK>
0x5D33	0x83A9	# <CJK>
0x5D34	0x837D	# <CJK>
0x5D35	0x83B8	# <CJK>
0x5D36	0x837B	# <CJK>
0x5D37	0x8398	# <CJK>
0x5D38	0x839E	# <CJK>
0x5D39	0x83A8	# <CJK>
0x5D3A	0x83BA	# <CJK>
0x5D3B	0x83BC	# <CJK>
0x5D3C	0x83C1	# <CJK>
0x5D3D	0x8401	# <CJK>
0x5D3E	0x83E5	# <CJK>
0x5D3F	0x83D8	# <CJK>
0x5D40	0x5807	# <CJK>
0x5D41	0x8418	# <CJK>
0x5D42	0x840B	# <CJK>
0x5D43	0x83DD	# <CJK>
0x5D44	0x83FD	# <CJK>
0x5D45	0x83D6	# <CJK>
0x5D46	0x841C	# <CJK>
0x5D47	0x8438	# <CJK>
0x5D48	0x8411	# <CJK>
0x5D49	0x8406	# <CJK>
0x5D4A	0x83D4	# <CJK>
0x5D4B	0x83DF	# <CJK>
0x5D4C	0x840F	# <CJK>
0x5D4D	0x8403	# <CJK>
0x5D4E	0x83F8	# <CJK>
0x5D4F	0x83F9	# <CJK>
0x5D50	0x83EA	# <CJK>
0x5D51	0x83C5	# <CJK>
0x5D52	0x83C0	# <CJK>
0x5D53	0x8426	# <CJK>
0x5D54	0x83F0	# <CJK>
0x5D55	0x83E1	# <CJK>
0x5D56	0x845C	# <CJK>
0x5D57	0x8451	# <CJK>
0x5D58	0x845A	# <CJK>
0x5D59	0x8459	# <CJK>
0x5D5A	0x8473	# <CJK>
0x5D5B	0x8487	# <CJK>
0x5D5C	0x8488	# <CJK>
0x5D5D	0x847A	# <CJK>
0x5D5E	0x8489	# <CJK>
0x5D5F	0x8478	# <CJK>
0x5D60	0x843C	# <CJK>
0x5D61	0x8446	# <CJK>
0x5D62	0x8469	# <CJK>
0x5D63	0x8476	# <CJK>
0x5D64	0x848C	# <CJK>
0x5D65	0x848E	# <CJK>
0x5D66	0x8431	# <CJK>
0x5D67	0x846D	# <CJK>
0x5D68	0x84C1	# <CJK>
0x5D69	0x84CD	# <CJK>
0x5D6A	0x84D0	# <CJK>
0x5D6B	0x84E6	# <CJK>
0x5D6C	0x84BD	# <CJK>
0x5D6D	0x84D3	# <CJK>
0x5D6E	0x84CA	# <CJK>
0x5D6F	0x84BF	# <CJK>
0x5D70	0x84BA	# <CJK>
0x5D71	0x84E0	# <CJK>
0x5D72	0x84A1	# <CJK>
0x5D73	0x84B9	# <CJK>
0x5D74	0x84B4	# <CJK>
0x5D75	0x8497	# <CJK>
0x5D76	0x84E5	# <CJK>
0x5D77	0x84E3	# <CJK>
0x5D78	0x850C	# <CJK>
0x5D79	0x750D	# <CJK>
0x5D7A	0x8538	# <CJK>
0x5D7B	0x84F0	# <CJK>
0x5D7C	0x8539	# <CJK>
0x5D7D	0x851F	# <CJK>
0x5D7E	0x853A	# <CJK>
0x5E21	0x8556	# <CJK>
0x5E22	0x853B	# <CJK>
0x5E23	0x84FF	# <CJK>
0x5E24	0x84FC	# <CJK>
0x5E25	0x8559	# <CJK>
0x5E26	0x8548	# <CJK>
0x5E27	0x8568	# <CJK>
0x5E28	0x8564	# <CJK>
0x5E29	0x855E	# <CJK>
0x5E2A	0x857A	# <CJK>
0x5E2B	0x77A2	# <CJK>
0x5E2C	0x8543	# <CJK>
0x5E2D	0x8572	# <CJK>
0x5E2E	0x857B	# <CJK>
0x5E2F	0x85A4	# <CJK>
0x5E30	0x85A8	# <CJK>
0x5E31	0x8587	# <CJK>
0x5E32	0x858F	# <CJK>
0x5E33	0x8579	# <CJK>
0x5E34	0x85AE	# <CJK>
0x5E35	0x859C	# <CJK>
0x5E36	0x8585	# <CJK>
0x5E37	0x85B9	# <CJK>
0x5E38	0x85B7	# <CJK>
0x5E39	0x85B0	# <CJK>
0x5E3A	0x85D3	# <CJK>
0x5E3B	0x85C1	# <CJK>
0x5E3C	0x85DC	# <CJK>
0x5E3D	0x85FF	# <CJK>
0x5E3E	0x8627	# <CJK>
0x5E3F	0x8605	# <CJK>
0x5E40	0x8629	# <CJK>
0x5E41	0x8616	# <CJK>
0x5E42	0x863C	# <CJK>
0x5E43	0x5EFE	# <CJK>
0x5E44	0x5F08	# <CJK>
0x5E45	0x593C	# <CJK>
0x5E46	0x5941	# <CJK>
0x5E47	0x8037	# <CJK>
0x5E48	0x5955	# <CJK>
0x5E49	0x595A	# <CJK>
0x5E4A	0x5958	# <CJK>
0x5E4B	0x530F	# <CJK>
0x5E4C	0x5C22	# <CJK>
0x5E4D	0x5C25	# <CJK>
0x5E4E	0x5C2C	# <CJK>
0x5E4F	0x5C34	# <CJK>
0x5E50	0x624C	# <CJK>
0x5E51	0x626A	# <CJK>
0x5E52	0x629F	# <CJK>
0x5E53	0x62BB	# <CJK>
0x5E54	0x62CA	# <CJK>
0x5E55	0x62DA	# <CJK>
0x5E56	0x62D7	# <CJK>
0x5E57	0x62EE	# <CJK>
0x5E58	0x6322	# <CJK>
0x5E59	0x62F6	# <CJK>
0x5E5A	0x6339	# <CJK>
0x5E5B	0x634B	# <CJK>
0x5E5C	0x6343	# <CJK>
0x5E5D	0x63AD	# <CJK>
0x5E5E	0x63F6	# <CJK>
0x5E5F	0x6371	# <CJK>
0x5E60	0x637A	# <CJK>
0x5E61	0x638E	# <CJK>
0x5E62	0x63B4	# <CJK>
0x5E63	0x636D	# <CJK>
0x5E64	0x63AC	# <CJK>
0x5E65	0x638A	# <CJK>
0x5E66	0x6369	# <CJK>
0x5E67	0x63AE	# <CJK>
0x5E68	0x63BC	# <CJK>
0x5E69	0x63F2	# <CJK>
0x5E6A	0x63F8	# <CJK>
0x5E6B	0x63E0	# <CJK>
0x5E6C	0x63FF	# <CJK>
0x5E6D	0x63C4	# <CJK>
0x5E6E	0x63DE	# <CJK>
0x5E6F	0x63CE	# <CJK>
0x5E70	0x6452	# <CJK>
0x5E71	0x63C6	# <CJK>
0x5E72	0x63BE	# <CJK>
0x5E73	0x6445	# <CJK>
0x5E74	0x6441	# <CJK>
0x5E75	0x640B	# <CJK>
0x5E76	0x641B	# <CJK>
0x5E77	0x6420	# <CJK>
0x5E78	0x640C	# <CJK>
0x5E79	0x6426	# <CJK>
0x5E7A	0x6421	# <CJK>
0x5E7B	0x645E	# <CJK>
0x5E7C	0x6484	# <CJK>
0x5E7D	0x646D	# <CJK>
0x5E7E	0x6496	# <CJK>
0x5F21	0x647A	# <CJK>
0x5F22	0x64B7	# <CJK>
0x5F23	0x64B8	# <CJK>
0x5F24	0x6499	# <CJK>
0x5F25	0x64BA	# <CJK>
0x5F26	0x64C0	# <CJK>
0x5F27	0x64D0	# <CJK>
0x5F28	0x64D7	# <CJK>
0x5F29	0x64E4	# <CJK>
0x5F2A	0x64E2	# <CJK>
0x5F2B	0x6509	# <CJK>
0x5F2C	0x6525	# <CJK>
0x5F2D	0x652E	# <CJK>
0x5F2E	0x5F0B	# <CJK>
0x5F2F	0x5FD2	# <CJK>
0x5F30	0x7519	# <CJK>
0x5F31	0x5F11	# <CJK>
0x5F32	0x535F	# <CJK>
0x5F33	0x53F1	# <CJK>
0x5F34	0x53FD	# <CJK>
0x5F35	0x53E9	# <CJK>
0x5F36	0x53E8	# <CJK>
0x5F37	0x53FB	# <CJK>
0x5F38	0x5412	# <CJK>
0x5F39	0x5416	# <CJK>
0x5F3A	0x5406	# <CJK>
0x5F3B	0x544B	# <CJK>
0x5F3C	0x5452	# <CJK>
0x5F3D	0x5453	# <CJK>
0x5F3E	0x5454	# <CJK>
0x5F3F	0x5456	# <CJK>
0x5F40	0x5443	# <CJK>
0x5F41	0x5421	# <CJK>
0x5F42	0x5457	# <CJK>
0x5F43	0x5459	# <CJK>
0x5F44	0x5423	# <CJK>
0x5F45	0x5432	# <CJK>
0x5F46	0x5482	# <CJK>
0x5F47	0x5494	# <CJK>
0x5F48	0x5477	# <CJK>
0x5F49	0x5471	# <CJK>
0x5F4A	0x5464	# <CJK>
0x5F4B	0x549A	# <CJK>
0x5F4C	0x549B	# <CJK>
0x5F4D	0x5484	# <CJK>
0x5F4E	0x5476	# <CJK>
0x5F4F	0x5466	# <CJK>
0x5F50	0x549D	# <CJK>
0x5F51	0x54D0	# <CJK>
0x5F52	0x54AD	# <CJK>
0x5F53	0x54C2	# <CJK>
0x5F54	0x54B4	# <CJK>
0x5F55	0x54D2	# <CJK>
0x5F56	0x54A7	# <CJK>
0x5F57	0x54A6	# <CJK>
0x5F58	0x54D3	# <CJK>
0x5F59	0x54D4	# <CJK>
0x5F5A	0x5472	# <CJK>
0x5F5B	0x54A3	# <CJK>
0x5F5C	0x54D5	# <CJK>
0x5F5D	0x54BB	# <CJK>
0x5F5E	0x54BF	# <CJK>
0x5F5F	0x54CC	# <CJK>
0x5F60	0x54D9	# <CJK>
0x5F61	0x54DA	# <CJK>
0x5F62	0x54DC	# <CJK>
0x5F63	0x54A9	# <CJK>
0x5F64	0x54AA	# <CJK>
0x5F65	0x54A4	# <CJK>
0x5F66	0x54DD	# <CJK>
0x5F67	0x54CF	# <CJK>
0x5F68	0x54DE	# <CJK>
0x5F69	0x551B	# <CJK>
0x5F6A	0x54E7	# <CJK>
0x5F6B	0x5520	# <CJK>
0x5F6C	0x54FD	# <CJK>
0x5F6D	0x5514	# <CJK>
0x5F6E	0x54F3	# <CJK>
0x5F6F	0x5522	# <CJK>
0x5F70	0x5523	# <CJK>
0x5F71	0x550F	# <CJK>
0x5F72	0x5511	# <CJK>
0x5F73	0x5527	# <CJK>
0x5F74	0x552A	# <CJK>
0x5F75	0x5567	# <CJK>
0x5F76	0x558F	# <CJK>
0x5F77	0x55B5	# <CJK>
0x5F78	0x5549	# <CJK>
0x5F79	0x556D	# <CJK>
0x5F7A	0x5541	# <CJK>
0x5F7B	0x5555	# <CJK>
0x5F7C	0x553F	# <CJK>
0x5F7D	0x5550	# <CJK>
0x5F7E	0x553C	# <CJK>
0x6021	0x5537	# <CJK>
0x6022	0x5556	# <CJK>
0x6023	0x5575	# <CJK>
0x6024	0x5576	# <CJK>
0x6025	0x5577	# <CJK>
0x6026	0x5533	# <CJK>
0x6027	0x5530	# <CJK>
0x6028	0x555C	# <CJK>
0x6029	0x558B	# <CJK>
0x602A	0x55D2	# <CJK>
0x602B	0x5583	# <CJK>
0x602C	0x55B1	# <CJK>
0x602D	0x55B9	# <CJK>
0x602E	0x5588	# <CJK>
0x602F	0x5581	# <CJK>
0x6030	0x559F	# <CJK>
0x6031	0x557E	# <CJK>
0x6032	0x55D6	# <CJK>
0x6033	0x5591	# <CJK>
0x6034	0x557B	# <CJK>
0x6035	0x55DF	# <CJK>
0x6036	0x55BD	# <CJK>
0x6037	0x55BE	# <CJK>
0x6038	0x5594	# <CJK>
0x6039	0x5599	# <CJK>
0x603A	0x55EA	# <CJK>
0x603B	0x55F7	# <CJK>
0x603C	0x55C9	# <CJK>
0x603D	0x561F	# <CJK>
0x603E	0x55D1	# <CJK>
0x603F	0x55EB	# <CJK>
0x6040	0x55EC	# <CJK>
0x6041	0x55D4	# <CJK>
0x6042	0x55E6	# <CJK>
0x6043	0x55DD	# <CJK>
0x6044	0x55C4	# <CJK>
0x6045	0x55EF	# <CJK>
0x6046	0x55E5	# <CJK>
0x6047	0x55F2	# <CJK>
0x6048	0x55F3	# <CJK>
0x6049	0x55CC	# <CJK>
0x604A	0x55CD	# <CJK>
0x604B	0x55E8	# <CJK>
0x604C	0x55F5	# <CJK>
0x604D	0x55E4	# <CJK>
0x604E	0x8F94	# <CJK>
0x604F	0x561E	# <CJK>
0x6050	0x5608	# <CJK>
0x6051	0x560C	# <CJK>
0x6052	0x5601	# <CJK>
0x6053	0x5624	# <CJK>
0x6054	0x5623	# <CJK>
0x6055	0x55FE	# <CJK>
0x6056	0x5600	# <CJK>
0x6057	0x5627	# <CJK>
0x6058	0x562D	# <CJK>
0x6059	0x5658	# <CJK>
0x605A	0x5639	# <CJK>
0x605B	0x5657	# <CJK>
0x605C	0x562C	# <CJK>
0x605D	0x564D	# <CJK>
0x605E	0x5662	# <CJK>
0x605F	0x5659	# <CJK>
0x6060	0x565C	# <CJK>
0x6061	0x564C	# <CJK>
0x6062	0x5654	# <CJK>
0x6063	0x5686	# <CJK>
0x6064	0x5664	# <CJK>
0x6065	0x5671	# <CJK>
0x6066	0x566B	# <CJK>
0x6067	0x567B	# <CJK>
0x6068	0x567C	# <CJK>
0x6069	0x5685	# <CJK>
0x606A	0x5693	# <CJK>
0x606B	0x56AF	# <CJK>
0x606C	0x56D4	# <CJK>
0x606D	0x56D7	# <CJK>
0x606E	0x56DD	# <CJK>
0x606F	0x56E1	# <CJK>
0x6070	0x56F5	# <CJK>
0x6071	0x56EB	# <CJK>
0x6072	0x56F9	# <CJK>
0x6073	0x56FF	# <CJK>
0x6074	0x5704	# <CJK>
0x6075	0x570A	# <CJK>
0x6076	0x5709	# <CJK>
0x6077	0x571C	# <CJK>
0x6078	0x5E0F	# <CJK>
0x6079	0x5E19	# <CJK>
0x607A	0x5E14	# <CJK>
0x607B	0x5E11	# <CJK>
0x607C	0x5E31	# <CJK>
0x607D	0x5E3B	# <CJK>
0x607E	0x5E3C	# <CJK>
0x6121	0x5E37	# <CJK>
0x6122	0x5E44	# <CJK>
0x6123	0x5E54	# <CJK>
0x6124	0x5E5B	# <CJK>
0x6125	0x5E5E	# <CJK>
0x6126	0x5E61	# <CJK>
0x6127	0x5C8C	# <CJK>
0x6128	0x5C7A	# <CJK>
0x6129	0x5C8D	# <CJK>
0x612A	0x5C90	# <CJK>
0x612B	0x5C96	# <CJK>
0x612C	0x5C88	# <CJK>
0x612D	0x5C98	# <CJK>
0x612E	0x5C99	# <CJK>
0x612F	0x5C91	# <CJK>
0x6130	0x5C9A	# <CJK>
0x6131	0x5C9C	# <CJK>
0x6132	0x5CB5	# <CJK>
0x6133	0x5CA2	# <CJK>
0x6134	0x5CBD	# <CJK>
0x6135	0x5CAC	# <CJK>
0x6136	0x5CAB	# <CJK>
0x6137	0x5CB1	# <CJK>
0x6138	0x5CA3	# <CJK>
0x6139	0x5CC1	# <CJK>
0x613A	0x5CB7	# <CJK>
0x613B	0x5CC4	# <CJK>
0x613C	0x5CD2	# <CJK>
0x613D	0x5CE4	# <CJK>
0x613E	0x5CCB	# <CJK>
0x613F	0x5CE5	# <CJK>
0x6140	0x5D02	# <CJK>
0x6141	0x5D03	# <CJK>
0x6142	0x5D27	# <CJK>
0x6143	0x5D26	# <CJK>
0x6144	0x5D2E	# <CJK>
0x6145	0x5D24	# <CJK>
0x6146	0x5D1E	# <CJK>
0x6147	0x5D06	# <CJK>
0x6148	0x5D1B	# <CJK>
0x6149	0x5D58	# <CJK>
0x614A	0x5D3E	# <CJK>
0x614B	0x5D34	# <CJK>
0x614C	0x5D3D	# <CJK>
0x614D	0x5D6C	# <CJK>
0x614E	0x5D5B	# <CJK>
0x614F	0x5D6F	# <CJK>
0x6150	0x5D5D	# <CJK>
0x6151	0x5D6B	# <CJK>
0x6152	0x5D4B	# <CJK>
0x6153	0x5D4A	# <CJK>
0x6154	0x5D69	# <CJK>
0x6155	0x5D74	# <CJK>
0x6156	0x5D82	# <CJK>
0x6157	0x5D99	# <CJK>
0x6158	0x5D9D	# <CJK>
0x6159	0x8C73	# <CJK>
0x615A	0x5DB7	# <CJK>
0x615B	0x5DC5	# <CJK>
0x615C	0x5F73	# <CJK>
0x615D	0x5F77	# <CJK>
0x615E	0x5F82	# <CJK>
0x615F	0x5F87	# <CJK>
0x6160	0x5F89	# <CJK>
0x6161	0x5F8C	# <CJK>
0x6162	0x5F95	# <CJK>
0x6163	0x5F99	# <CJK>
0x6164	0x5F9C	# <CJK>
0x6165	0x5FA8	# <CJK>
0x6166	0x5FAD	# <CJK>
0x6167	0x5FB5	# <CJK>
0x6168	0x5FBC	# <CJK>
0x6169	0x8862	# <CJK>
0x616A	0x5F61	# <CJK>
0x616B	0x72AD	# <CJK>
0x616C	0x72B0	# <CJK>
0x616D	0x72B4	# <CJK>
0x616E	0x72B7	# <CJK>
0x616F	0x72B8	# <CJK>
0x6170	0x72C3	# <CJK>
0x6171	0x72C1	# <CJK>
0x6172	0x72CE	# <CJK>
0x6173	0x72CD	# <CJK>
0x6174	0x72D2	# <CJK>
0x6175	0x72E8	# <CJK>
0x6176	0x72EF	# <CJK>
0x6177	0x72E9	# <CJK>
0x6178	0x72F2	# <CJK>
0x6179	0x72F4	# <CJK>
0x617A	0x72F7	# <CJK>
0x617B	0x7301	# <CJK>
0x617C	0x72F3	# <CJK>
0x617D	0x7303	# <CJK>
0x617E	0x72FA	# <CJK>
0x6221	0x72FB	# <CJK>
0x6222	0x7317	# <CJK>
0x6223	0x7313	# <CJK>
0x6224	0x7321	# <CJK>
0x6225	0x730A	# <CJK>
0x6226	0x731E	# <CJK>
0x6227	0x731D	# <CJK>
0x6228	0x7315	# <CJK>
0x6229	0x7322	# <CJK>
0x622A	0x7339	# <CJK>
0x622B	0x7325	# <CJK>
0x622C	0x732C	# <CJK>
0x622D	0x7338	# <CJK>
0x622E	0x7331	# <CJK>
0x622F	0x7350	# <CJK>
0x6230	0x734D	# <CJK>
0x6231	0x7357	# <CJK>
0x6232	0x7360	# <CJK>
0x6233	0x736C	# <CJK>
0x6234	0x736F	# <CJK>
0x6235	0x737E	# <CJK>
0x6236	0x821B	# <CJK>
0x6237	0x5925	# <CJK>
0x6238	0x98E7	# <CJK>
0x6239	0x5924	# <CJK>
0x623A	0x5902	# <CJK>
0x623B	0x9963	# <CJK>
0x623C	0x9967	# <CJK>
0x623D	0x9968	# <CJK>
0x623E	0x9969	# <CJK>
0x623F	0x996A	# <CJK>
0x6240	0x996B	# <CJK>
0x6241	0x996C	# <CJK>
0x6242	0x9974	# <CJK>
0x6243	0x9977	# <CJK>
0x6244	0x997D	# <CJK>
0x6245	0x9980	# <CJK>
0x6246	0x9984	# <CJK>
0x6247	0x9987	# <CJK>
0x6248	0x998A	# <CJK>
0x6249	0x998D	# <CJK>
0x624A	0x9990	# <CJK>
0x624B	0x9991	# <CJK>
0x624C	0x9993	# <CJK>
0x624D	0x9994	# <CJK>
0x624E	0x9995	# <CJK>
0x624F	0x5E80	# <CJK>
0x6250	0x5E91	# <CJK>
0x6251	0x5E8B	# <CJK>
0x6252	0x5E96	# <CJK>
0x6253	0x5EA5	# <CJK>
0x6254	0x5EA0	# <CJK>
0x6255	0x5EB9	# <CJK>
0x6256	0x5EB5	# <CJK>
0x6257	0x5EBE	# <CJK>
0x6258	0x5EB3	# <CJK>
0x6259	0x8D53	# <CJK>
0x625A	0x5ED2	# <CJK>
0x625B	0x5ED1	# <CJK>
0x625C	0x5EDB	# <CJK>
0x625D	0x5EE8	# <CJK>
0x625E	0x5EEA	# <CJK>
0x625F	0x81BA	# <CJK>
0x6260	0x5FC4	# <CJK>
0x6261	0x5FC9	# <CJK>
0x6262	0x5FD6	# <CJK>
0x6263	0x5FCF	# <CJK>
0x6264	0x6003	# <CJK>
0x6265	0x5FEE	# <CJK>
0x6266	0x6004	# <CJK>
0x6267	0x5FE1	# <CJK>
0x6268	0x5FE4	# <CJK>
0x6269	0x5FFE	# <CJK>
0x626A	0x6005	# <CJK>
0x626B	0x6006	# <CJK>
0x626C	0x5FEA	# <CJK>
0x626D	0x5FED	# <CJK>
0x626E	0x5FF8	# <CJK>
0x626F	0x6019	# <CJK>
0x6270	0x6035	# <CJK>
0x6271	0x6026	# <CJK>
0x6272	0x601B	# <CJK>
0x6273	0x600F	# <CJK>
0x6274	0x600D	# <CJK>
0x6275	0x6029	# <CJK>
0x6276	0x602B	# <CJK>
0x6277	0x600A	# <CJK>
0x6278	0x603F	# <CJK>
0x6279	0x6021	# <CJK>
0x627A	0x6078	# <CJK>
0x627B	0x6079	# <CJK>
0x627C	0x607B	# <CJK>
0x627D	0x607A	# <CJK>
0x627E	0x6042	# <CJK>
0x6321	0x606A	# <CJK>
0x6322	0x607D	# <CJK>
0x6323	0x6096	# <CJK>
0x6324	0x609A	# <CJK>
0x6325	0x60AD	# <CJK>
0x6326	0x609D	# <CJK>
0x6327	0x6083	# <CJK>
0x6328	0x6092	# <CJK>
0x6329	0x608C	# <CJK>
0x632A	0x609B	# <CJK>
0x632B	0x60EC	# <CJK>
0x632C	0x60BB	# <CJK>
0x632D	0x60B1	# <CJK>
0x632E	0x60DD	# <CJK>
0x632F	0x60D8	# <CJK>
0x6330	0x60C6	# <CJK>
0x6331	0x60DA	# <CJK>
0x6332	0x60B4	# <CJK>
0x6333	0x6120	# <CJK>
0x6334	0x6126	# <CJK>
0x6335	0x6115	# <CJK>
0x6336	0x6123	# <CJK>
0x6337	0x60F4	# <CJK>
0x6338	0x6100	# <CJK>
0x6339	0x610E	# <CJK>
0x633A	0x612B	# <CJK>
0x633B	0x614A	# <CJK>
0x633C	0x6175	# <CJK>
0x633D	0x61AC	# <CJK>
0x633E	0x6194	# <CJK>
0x633F	0x61A7	# <CJK>
0x6340	0x61B7	# <CJK>
0x6341	0x61D4	# <CJK>
0x6342	0x61F5	# <CJK>
0x6343	0x5FDD	# <CJK>
0x6344	0x96B3	# <CJK>
0x6345	0x95E9	# <CJK>
0x6346	0x95EB	# <CJK>
0x6347	0x95F1	# <CJK>
0x6348	0x95F3	# <CJK>
0x6349	0x95F5	# <CJK>
0x634A	0x95F6	# <CJK>
0x634B	0x95FC	# <CJK>
0x634C	0x95FE	# <CJK>
0x634D	0x9603	# <CJK>
0x634E	0x9604	# <CJK>
0x634F	0x9606	# <CJK>
0x6350	0x9608	# <CJK>
0x6351	0x960A	# <CJK>
0x6352	0x960B	# <CJK>
0x6353	0x960C	# <CJK>
0x6354	0x960D	# <CJK>
0x6355	0x960F	# <CJK>
0x6356	0x9612	# <CJK>
0x6357	0x9615	# <CJK>
0x6358	0x9616	# <CJK>
0x6359	0x9617	# <CJK>
0x635A	0x9619	# <CJK>
0x635B	0x961A	# <CJK>
0x635C	0x4E2C	# <CJK>
0x635D	0x723F	# <CJK>
0x635E	0x6215	# <CJK>
0x635F	0x6C35	# <CJK>
0x6360	0x6C54	# <CJK>
0x6361	0x6C5C	# <CJK>
0x6362	0x6C4A	# <CJK>
0x6363	0x6CA3	# <CJK>
0x6364	0x6C85	# <CJK>
0x6365	0x6C90	# <CJK>
0x6366	0x6C94	# <CJK>
0x6367	0x6C8C	# <CJK>
0x6368	0x6C68	# <CJK>
0x6369	0x6C69	# <CJK>
0x636A	0x6C74	# <CJK>
0x636B	0x6C76	# <CJK>
0x636C	0x6C86	# <CJK>
0x636D	0x6CA9	# <CJK>
0x636E	0x6CD0	# <CJK>
0x636F	0x6CD4	# <CJK>
0x6370	0x6CAD	# <CJK>
0x6371	0x6CF7	# <CJK>
0x6372	0x6CF8	# <CJK>
0x6373	0x6CF1	# <CJK>
0x6374	0x6CD7	# <CJK>
0x6375	0x6CB2	# <CJK>
0x6376	0x6CE0	# <CJK>
0x6377	0x6CD6	# <CJK>
0x6378	0x6CFA	# <CJK>
0x6379	0x6CEB	# <CJK>
0x637A	0x6CEE	# <CJK>
0x637B	0x6CB1	# <CJK>
0x637C	0x6CD3	# <CJK>
0x637D	0x6CEF	# <CJK>
0x637E	0x6CFE	# <CJK>
0x6421	0x6D39	# <CJK>
0x6422	0x6D27	# <CJK>
0x6423	0x6D0C	# <CJK>
0x6424	0x6D43	# <CJK>
0x6425	0x6D48	# <CJK>
0x6426	0x6D07	# <CJK>
0x6427	0x6D04	# <CJK>
0x6428	0x6D19	# <CJK>
0x6429	0x6D0E	# <CJK>
0x642A	0x6D2B	# <CJK>
0x642B	0x6D4D	# <CJK>
0x642C	0x6D2E	# <CJK>
0x642D	0x6D35	# <CJK>
0x642E	0x6D1A	# <CJK>
0x642F	0x6D4F	# <CJK>
0x6430	0x6D52	# <CJK>
0x6431	0x6D54	# <CJK>
0x6432	0x6D33	# <CJK>
0x6433	0x6D91	# <CJK>
0x6434	0x6D6F	# <CJK>
0x6435	0x6D9E	# <CJK>
0x6436	0x6DA0	# <CJK>
0x6437	0x6D5E	# <CJK>
0x6438	0x6D93	# <CJK>
0x6439	0x6D94	# <CJK>
0x643A	0x6D5C	# <CJK>
0x643B	0x6D60	# <CJK>
0x643C	0x6D7C	# <CJK>
0x643D	0x6D63	# <CJK>
0x643E	0x6E1A	# <CJK>
0x643F	0x6DC7	# <CJK>
0x6440	0x6DC5	# <CJK>
0x6441	0x6DDE	# <CJK>
0x6442	0x6E0E	# <CJK>
0x6443	0x6DBF	# <CJK>
0x6444	0x6DE0	# <CJK>
0x6445	0x6E11	# <CJK>
0x6446	0x6DE6	# <CJK>
0x6447	0x6DDD	# <CJK>
0x6448	0x6DD9	# <CJK>
0x6449	0x6E16	# <CJK>
0x644A	0x6DAB	# <CJK>
0x644B	0x6E0C	# <CJK>
0x644C	0x6DAE	# <CJK>
0x644D	0x6E2B	# <CJK>
0x644E	0x6E6E	# <CJK>
0x644F	0x6E4E	# <CJK>
0x6450	0x6E6B	# <CJK>
0x6451	0x6EB2	# <CJK>
0x6452	0x6E5F	# <CJK>
0x6453	0x6E86	# <CJK>
0x6454	0x6E53	# <CJK>
0x6455	0x6E54	# <CJK>
0x6456	0x6E32	# <CJK>
0x6457	0x6E25	# <CJK>
0x6458	0x6E44	# <CJK>
0x6459	0x6EDF	# <CJK>
0x645A	0x6EB1	# <CJK>
0x645B	0x6E98	# <CJK>
0x645C	0x6EE0	# <CJK>
0x645D	0x6F2D	# <CJK>
0x645E	0x6EE2	# <CJK>
0x645F	0x6EA5	# <CJK>
0x6460	0x6EA7	# <CJK>
0x6461	0x6EBD	# <CJK>
0x6462	0x6EBB	# <CJK>
0x6463	0x6EB7	# <CJK>
0x6464	0x6ED7	# <CJK>
0x6465	0x6EB4	# <CJK>
0x6466	0x6ECF	# <CJK>
0x6467	0x6E8F	# <CJK>
0x6468	0x6EC2	# <CJK>
0x6469	0x6E9F	# <CJK>
0x646A	0x6F62	# <CJK>
0x646B	0x6F46	# <CJK>
0x646C	0x6F47	# <CJK>
0x646D	0x6F24	# <CJK>
0x646E	0x6F15	# <CJK>
0x646F	0x6EF9	# <CJK>
0x6470	0x6F2F	# <CJK>
0x6471	0x6F36	# <CJK>
0x6472	0x6F4B	# <CJK>
0x6473	0x6F74	# <CJK>
0x6474	0x6F2A	# <CJK>
0x6475	0x6F09	# <CJK>
0x6476	0x6F29	# <CJK>
0x6477	0x6F89	# <CJK>
0x6478	0x6F8D	# <CJK>
0x6479	0x6F8C	# <CJK>
0x647A	0x6F78	# <CJK>
0x647B	0x6F72	# <CJK>
0x647C	0x6F7C	# <CJK>
0x647D	0x6F7A	# <CJK>
0x647E	0x6FD1	# <CJK>
0x6521	0x6FC9	# <CJK>
0x6522	0x6FA7	# <CJK>
0x6523	0x6FB9	# <CJK>
0x6524	0x6FB6	# <CJK>
0x6525	0x6FC2	# <CJK>
0x6526	0x6FE1	# <CJK>
0x6527	0x6FEE	# <CJK>
0x6528	0x6FDE	# <CJK>
0x6529	0x6FE0	# <CJK>
0x652A	0x6FEF	# <CJK>
0x652B	0x701A	# <CJK>
0x652C	0x7023	# <CJK>
0x652D	0x701B	# <CJK>
0x652E	0x7039	# <CJK>
0x652F	0x7035	# <CJK>
0x6530	0x704F	# <CJK>
0x6531	0x705E	# <CJK>
0x6532	0x5B80	# <CJK>
0x6533	0x5B84	# <CJK>
0x6534	0x5B95	# <CJK>
0x6535	0x5B93	# <CJK>
0x6536	0x5BA5	# <CJK>
0x6537	0x5BB8	# <CJK>
0x6538	0x752F	# <CJK>
0x6539	0x9A9E	# <CJK>
0x653A	0x6434	# <CJK>
0x653B	0x5BE4	# <CJK>
0x653C	0x5BEE	# <CJK>
0x653D	0x8930	# <CJK>
0x653E	0x5BF0	# <CJK>
0x653F	0x8E47	# <CJK>
0x6540	0x8B07	# <CJK>
0x6541	0x8FB6	# <CJK>
0x6542	0x8FD3	# <CJK>
0x6543	0x8FD5	# <CJK>
0x6544	0x8FE5	# <CJK>
0x6545	0x8FEE	# <CJK>
0x6546	0x8FE4	# <CJK>
0x6547	0x8FE9	# <CJK>
0x6548	0x8FE6	# <CJK>
0x6549	0x8FF3	# <CJK>
0x654A	0x8FE8	# <CJK>
0x654B	0x9005	# <CJK>
0x654C	0x9004	# <CJK>
0x654D	0x900B	# <CJK>
0x654E	0x9026	# <CJK>
0x654F	0x9011	# <CJK>
0x6550	0x900D	# <CJK>
0x6551	0x9016	# <CJK>
0x6552	0x9021	# <CJK>
0x6553	0x9035	# <CJK>
0x6554	0x9036	# <CJK>
0x6555	0x902D	# <CJK>
0x6556	0x902F	# <CJK>
0x6557	0x9044	# <CJK>
0x6558	0x9051	# <CJK>
0x6559	0x9052	# <CJK>
0x655A	0x9050	# <CJK>
0x655B	0x9068	# <CJK>
0x655C	0x9058	# <CJK>
0x655D	0x9062	# <CJK>
0x655E	0x905B	# <CJK>
0x655F	0x66B9	# <CJK>
0x6560	0x9074	# <CJK>
0x6561	0x907D	# <CJK>
0x6562	0x9082	# <CJK>
0x6563	0x9088	# <CJK>
0x6564	0x9083	# <CJK>
0x6565	0x908B	# <CJK>
0x6566	0x5F50	# <CJK>
0x6567	0x5F57	# <CJK>
0x6568	0x5F56	# <CJK>
0x6569	0x5F58	# <CJK>
0x656A	0x5C3B	# <CJK>
0x656B	0x54AB	# <CJK>
0x656C	0x5C50	# <CJK>
0x656D	0x5C59	# <CJK>
0x656E	0x5B71	# <CJK>
0x656F	0x5C63	# <CJK>
0x6570	0x5C66	# <CJK>
0x6571	0x7FBC	# <CJK>
0x6572	0x5F2A	# <CJK>
0x6573	0x5F29	# <CJK>
0x6574	0x5F2D	# <CJK>
0x6575	0x8274	# <CJK>
0x6576	0x5F3C	# <CJK>
0x6577	0x9B3B	# <CJK>
0x6578	0x5C6E	# <CJK>
0x6579	0x5981	# <CJK>
0x657A	0x5983	# <CJK>
0x657B	0x598D	# <CJK>
0x657C	0x59A9	# <CJK>
0x657D	0x59AA	# <CJK>
0x657E	0x59A3	# <CJK>
0x6621	0x5997	# <CJK>
0x6622	0x59CA	# <CJK>
0x6623	0x59AB	# <CJK>
0x6624	0x599E	# <CJK>
0x6625	0x59A4	# <CJK>
0x6626	0x59D2	# <CJK>
0x6627	0x59B2	# <CJK>
0x6628	0x59AF	# <CJK>
0x6629	0x59D7	# <CJK>
0x662A	0x59BE	# <CJK>
0x662B	0x5A05	# <CJK>
0x662C	0x5A06	# <CJK>
0x662D	0x59DD	# <CJK>
0x662E	0x5A08	# <CJK>
0x662F	0x59E3	# <CJK>
0x6630	0x59D8	# <CJK>
0x6631	0x59F9	# <CJK>
0x6632	0x5A0C	# <CJK>
0x6633	0x5A09	# <CJK>
0x6634	0x5A32	# <CJK>
0x6635	0x5A34	# <CJK>
0x6636	0x5A11	# <CJK>
0x6637	0x5A23	# <CJK>
0x6638	0x5A13	# <CJK>
0x6639	0x5A40	# <CJK>
0x663A	0x5A67	# <CJK>
0x663B	0x5A4A	# <CJK>
0x663C	0x5A55	# <CJK>
0x663D	0x5A3C	# <CJK>
0x663E	0x5A62	# <CJK>
0x663F	0x5A75	# <CJK>
0x6640	0x80EC	# <CJK>
0x6641	0x5AAA	# <CJK>
0x6642	0x5A9B	# <CJK>
0x6643	0x5A77	# <CJK>
0x6644	0x5A7A	# <CJK>
0x6645	0x5ABE	# <CJK>
0x6646	0x5AEB	# <CJK>
0x6647	0x5AB2	# <CJK>
0x6648	0x5AD2	# <CJK>
0x6649	0x5AD4	# <CJK>
0x664A	0x5AB8	# <CJK>
0x664B	0x5AE0	# <CJK>
0x664C	0x5AE3	# <CJK>
0x664D	0x5AF1	# <CJK>
0x664E	0x5AD6	# <CJK>
0x664F	0x5AE6	# <CJK>
0x6650	0x5AD8	# <CJK>
0x6651	0x5ADC	# <CJK>
0x6652	0x5B09	# <CJK>
0x6653	0x5B17	# <CJK>
0x6654	0x5B16	# <CJK>
0x6655	0x5B32	# <CJK>
0x6656	0x5B37	# <CJK>
0x6657	0x5B40	# <CJK>
0x6658	0x5C15	# <CJK>
0x6659	0x5C1C	# <CJK>
0x665A	0x5B5A	# <CJK>
0x665B	0x5B65	# <CJK>
0x665C	0x5B73	# <CJK>
0x665D	0x5B51	# <CJK>
0x665E	0x5B53	# <CJK>
0x665F	0x5B62	# <CJK>
0x6660	0x9A75	# <CJK>
0x6661	0x9A77	# <CJK>
0x6662	0x9A78	# <CJK>
0x6663	0x9A7A	# <CJK>
0x6664	0x9A7F	# <CJK>
0x6665	0x9A7D	# <CJK>
0x6666	0x9A80	# <CJK>
0x6667	0x9A81	# <CJK>
0x6668	0x9A85	# <CJK>
0x6669	0x9A88	# <CJK>
0x666A	0x9A8A	# <CJK>
0x666B	0x9A90	# <CJK>
0x666C	0x9A92	# <CJK>
0x666D	0x9A93	# <CJK>
0x666E	0x9A96	# <CJK>
0x666F	0x9A98	# <CJK>
0x6670	0x9A9B	# <CJK>
0x6671	0x9A9C	# <CJK>
0x6672	0x9A9D	# <CJK>
0x6673	0x9A9F	# <CJK>
0x6674	0x9AA0	# <CJK>
0x6675	0x9AA2	# <CJK>
0x6676	0x9AA3	# <CJK>
0x6677	0x9AA5	# <CJK>
0x6678	0x9AA7	# <CJK>
0x6679	0x7E9F	# <CJK>
0x667A	0x7EA1	# <CJK>
0x667B	0x7EA3	# <CJK>
0x667C	0x7EA5	# <CJK>
0x667D	0x7EA8	# <CJK>
0x667E	0x7EA9	# <CJK>
0x6721	0x7EAD	# <CJK>
0x6722	0x7EB0	# <CJK>
0x6723	0x7EBE	# <CJK>
0x6724	0x7EC0	# <CJK>
0x6725	0x7EC1	# <CJK>
0x6726	0x7EC2	# <CJK>
0x6727	0x7EC9	# <CJK>
0x6728	0x7ECB	# <CJK>
0x6729	0x7ECC	# <CJK>
0x672A	0x7ED0	# <CJK>
0x672B	0x7ED4	# <CJK>
0x672C	0x7ED7	# <CJK>
0x672D	0x7EDB	# <CJK>
0x672E	0x7EE0	# <CJK>
0x672F	0x7EE1	# <CJK>
0x6730	0x7EE8	# <CJK>
0x6731	0x7EEB	# <CJK>
0x6732	0x7EEE	# <CJK>
0x6733	0x7EEF	# <CJK>
0x6734	0x7EF1	# <CJK>
0x6735	0x7EF2	# <CJK>
0x6736	0x7F0D	# <CJK>
0x6737	0x7EF6	# <CJK>
0x6738	0x7EFA	# <CJK>
0x6739	0x7EFB	# <CJK>
0x673A	0x7EFE	# <CJK>
0x673B	0x7F01	# <CJK>
0x673C	0x7F02	# <CJK>
0x673D	0x7F03	# <CJK>
0x673E	0x7F07	# <CJK>
0x673F	0x7F08	# <CJK>
0x6740	0x7F0B	# <CJK>
0x6741	0x7F0C	# <CJK>
0x6742	0x7F0F	# <CJK>
0x6743	0x7F11	# <CJK>
0x6744	0x7F12	# <CJK>
0x6745	0x7F17	# <CJK>
0x6746	0x7F19	# <CJK>
0x6747	0x7F1C	# <CJK>
0x6748	0x7F1B	# <CJK>
0x6749	0x7F1F	# <CJK>
0x674A	0x7F21	# <CJK>
0x674B	0x7F22	# <CJK>
0x674C	0x7F23	# <CJK>
0x674D	0x7F24	# <CJK>
0x674E	0x7F25	# <CJK>
0x674F	0x7F26	# <CJK>
0x6750	0x7F27	# <CJK>
0x6751	0x7F2A	# <CJK>
0x6752	0x7F2B	# <CJK>
0x6753	0x7F2C	# <CJK>
0x6754	0x7F2D	# <CJK>
0x6755	0x7F2F	# <CJK>
0x6756	0x7F30	# <CJK>
0x6757	0x7F31	# <CJK>
0x6758	0x7F32	# <CJK>
0x6759	0x7F33	# <CJK>
0x675A	0x7F35	# <CJK>
0x675B	0x5E7A	# <CJK>
0x675C	0x757F	# <CJK>
0x675D	0x5DDB	# <CJK>
0x675E	0x753E	# <CJK>
0x675F	0x9095	# <CJK>
0x6760	0x738E	# <CJK>
0x6761	0x7391	# <CJK>
0x6762	0x73AE	# <CJK>
0x6763	0x73A2	# <CJK>
0x6764	0x739F	# <CJK>
0x6765	0x73CF	# <CJK>
0x6766	0x73C2	# <CJK>
0x6767	0x73D1	# <CJK>
0x6768	0x73B7	# <CJK>
0x6769	0x73B3	# <CJK>
0x676A	0x73C0	# <CJK>
0x676B	0x73C9	# <CJK>
0x676C	0x73C8	# <CJK>
0x676D	0x73E5	# <CJK>
0x676E	0x73D9	# <CJK>
0x676F	0x987C	# <CJK>
0x6770	0x740A	# <CJK>
0x6771	0x73E9	# <CJK>
0x6772	0x73E7	# <CJK>
0x6773	0x73DE	# <CJK>
0x6774	0x73BA	# <CJK>
0x6775	0x73F2	# <CJK>
0x6776	0x740F	# <CJK>
0x6777	0x742A	# <CJK>
0x6778	0x745B	# <CJK>
0x6779	0x7426	# <CJK>
0x677A	0x7425	# <CJK>
0x677B	0x7428	# <CJK>
0x677C	0x7430	# <CJK>
0x677D	0x742E	# <CJK>
0x677E	0x742C	# <CJK>
0x6821	0x741B	# <CJK>
0x6822	0x741A	# <CJK>
0x6823	0x7441	# <CJK>
0x6824	0x745C	# <CJK>
0x6825	0x7457	# <CJK>
0x6826	0x7455	# <CJK>
0x6827	0x7459	# <CJK>
0x6828	0x7477	# <CJK>
0x6829	0x746D	# <CJK>
0x682A	0x747E	# <CJK>
0x682B	0x749C	# <CJK>
0x682C	0x748E	# <CJK>
0x682D	0x7480	# <CJK>
0x682E	0x7481	# <CJK>
0x682F	0x7487	# <CJK>
0x6830	0x748B	# <CJK>
0x6831	0x749E	# <CJK>
0x6832	0x74A8	# <CJK>
0x6833	0x74A9	# <CJK>
0x6834	0x7490	# <CJK>
0x6835	0x74A7	# <CJK>
0x6836	0x74D2	# <CJK>
0x6837	0x74BA	# <CJK>
0x6838	0x97EA	# <CJK>
0x6839	0x97EB	# <CJK>
0x683A	0x97EC	# <CJK>
0x683B	0x674C	# <CJK>
0x683C	0x6753	# <CJK>
0x683D	0x675E	# <CJK>
0x683E	0x6748	# <CJK>
0x683F	0x6769	# <CJK>
0x6840	0x67A5	# <CJK>
0x6841	0x6787	# <CJK>
0x6842	0x676A	# <CJK>
0x6843	0x6773	# <CJK>
0x6844	0x6798	# <CJK>
0x6845	0x67A7	# <CJK>
0x6846	0x6775	# <CJK>
0x6847	0x67A8	# <CJK>
0x6848	0x679E	# <CJK>
0x6849	0x67AD	# <CJK>
0x684A	0x678B	# <CJK>
0x684B	0x6777	# <CJK>
0x684C	0x677C	# <CJK>
0x684D	0x67F0	# <CJK>
0x684E	0x6809	# <CJK>
0x684F	0x67D8	# <CJK>
0x6850	0x680A	# <CJK>
0x6851	0x67E9	# <CJK>
0x6852	0x67B0	# <CJK>
0x6853	0x680C	# <CJK>
0x6854	0x67D9	# <CJK>
0x6855	0x67B5	# <CJK>
0x6856	0x67DA	# <CJK>
0x6857	0x67B3	# <CJK>
0x6858	0x67DD	# <CJK>
0x6859	0x6800	# <CJK>
0x685A	0x67C3	# <CJK>
0x685B	0x67B8	# <CJK>
0x685C	0x67E2	# <CJK>
0x685D	0x680E	# <CJK>
0x685E	0x67C1	# <CJK>
0x685F	0x67FD	# <CJK>
0x6860	0x6832	# <CJK>
0x6861	0x6833	# <CJK>
0x6862	0x6860	# <CJK>
0x6863	0x6861	# <CJK>
0x6864	0x684E	# <CJK>
0x6865	0x6862	# <CJK>
0x6866	0x6844	# <CJK>
0x6867	0x6864	# <CJK>
0x6868	0x6883	# <CJK>
0x6869	0x681D	# <CJK>
0x686A	0x6855	# <CJK>
0x686B	0x6866	# <CJK>
0x686C	0x6841	# <CJK>
0x686D	0x6867	# <CJK>
0x686E	0x6840	# <CJK>
0x686F	0x683E	# <CJK>
0x6870	0x684A	# <CJK>
0x6871	0x6849	# <CJK>
0x6872	0x6829	# <CJK>
0x6873	0x68B5	# <CJK>
0x6874	0x688F	# <CJK>
0x6875	0x6874	# <CJK>
0x6876	0x6877	# <CJK>
0x6877	0x6893	# <CJK>
0x6878	0x686B	# <CJK>
0x6879	0x68C2	# <CJK>
0x687A	0x696E	# <CJK>
0x687B	0x68FC	# <CJK>
0x687C	0x691F	# <CJK>
0x687D	0x6920	# <CJK>
0x687E	0x68F9	# <CJK>
0x6921	0x6924	# <CJK>
0x6922	0x68F0	# <CJK>
0x6923	0x690B	# <CJK>
0x6924	0x6901	# <CJK>
0x6925	0x6957	# <CJK>
0x6926	0x68E3	# <CJK>
0x6927	0x6910	# <CJK>
0x6928	0x6971	# <CJK>
0x6929	0x6939	# <CJK>
0x692A	0x6960	# <CJK>
0x692B	0x6942	# <CJK>
0x692C	0x695D	# <CJK>
0x692D	0x6984	# <CJK>
0x692E	0x696B	# <CJK>
0x692F	0x6980	# <CJK>
0x6930	0x6998	# <CJK>
0x6931	0x6978	# <CJK>
0x6932	0x6934	# <CJK>
0x6933	0x69CC	# <CJK>
0x6934	0x6987	# <CJK>
0x6935	0x6988	# <CJK>
0x6936	0x69CE	# <CJK>
0x6937	0x6989	# <CJK>
0x6938	0x6966	# <CJK>
0x6939	0x6963	# <CJK>
0x693A	0x6979	# <CJK>
0x693B	0x699B	# <CJK>
0x693C	0x69A7	# <CJK>
0x693D	0x69BB	# <CJK>
0x693E	0x69AB	# <CJK>
0x693F	0x69AD	# <CJK>
0x6940	0x69D4	# <CJK>
0x6941	0x69B1	# <CJK>
0x6942	0x69C1	# <CJK>
0x6943	0x69CA	# <CJK>
0x6944	0x69DF	# <CJK>
0x6945	0x6995	# <CJK>
0x6946	0x69E0	# <CJK>
0x6947	0x698D	# <CJK>
0x6948	0x69FF	# <CJK>
0x6949	0x6A2F	# <CJK>
0x694A	0x69ED	# <CJK>
0x694B	0x6A17	# <CJK>
0x694C	0x6A18	# <CJK>
0x694D	0x6A65	# <CJK>
0x694E	0x69F2	# <CJK>
0x694F	0x6A44	# <CJK>
0x6950	0x6A3E	# <CJK>
0x6951	0x6AA0	# <CJK>
0x6952	0x6A50	# <CJK>
0x6953	0x6A5B	# <CJK>
0x6954	0x6A35	# <CJK>
0x6955	0x6A8E	# <CJK>
0x6956	0x6A79	# <CJK>
0x6957	0x6A3D	# <CJK>
0x6958	0x6A28	# <CJK>
0x6959	0x6A58	# <CJK>
0x695A	0x6A7C	# <CJK>
0x695B	0x6A91	# <CJK>
0x695C	0x6A90	# <CJK>
0x695D	0x6AA9	# <CJK>
0x695E	0x6A97	# <CJK>
0x695F	0x6AAB	# <CJK>
0x6960	0x7337	# <CJK>
0x6961	0x7352	# <CJK>
0x6962	0x6B81	# <CJK>
0x6963	0x6B82	# <CJK>
0x6964	0x6B87	# <CJK>
0x6965	0x6B84	# <CJK>
0x6966	0x6B92	# <CJK>
0x6967	0x6B93	# <CJK>
0x6968	0x6B8D	# <CJK>
0x6969	0x6B9A	# <CJK>
0x696A	0x6B9B	# <CJK>
0x696B	0x6BA1	# <CJK>
0x696C	0x6BAA	# <CJK>
0x696D	0x8F6B	# <CJK>
0x696E	0x8F6D	# <CJK>
0x696F	0x8F71	# <CJK>
0x6970	0x8F72	# <CJK>
0x6971	0x8F73	# <CJK>
0x6972	0x8F75	# <CJK>
0x6973	0x8F76	# <CJK>
0x6974	0x8F78	# <CJK>
0x6975	0x8F77	# <CJK>
0x6976	0x8F79	# <CJK>
0x6977	0x8F7A	# <CJK>
0x6978	0x8F7C	# <CJK>
0x6979	0x8F7E	# <CJK>
0x697A	0x8F81	# <CJK>
0x697B	0x8F82	# <CJK>
0x697C	0x8F84	# <CJK>
0x697D	0x8F87	# <CJK>
0x697E	0x8F8B	# <CJK>
0x6A21	0x8F8D	# <CJK>
0x6A22	0x8F8E	# <CJK>
0x6A23	0x8F8F	# <CJK>
0x6A24	0x8F98	# <CJK>
0x6A25	0x8F9A	# <CJK>
0x6A26	0x8ECE	# <CJK>
0x6A27	0x620B	# <CJK>
0x6A28	0x6217	# <CJK>
0x6A29	0x621B	# <CJK>
0x6A2A	0x621F	# <CJK>
0x6A2B	0x6222	# <CJK>
0x6A2C	0x6221	# <CJK>
0x6A2D	0x6225	# <CJK>
0x6A2E	0x6224	# <CJK>
0x6A2F	0x622C	# <CJK>
0x6A30	0x81E7	# <CJK>
0x6A31	0x74EF	# <CJK>
0x6A32	0x74F4	# <CJK>
0x6A33	0x74FF	# <CJK>
0x6A34	0x750F	# <CJK>
0x6A35	0x7511	# <CJK>
0x6A36	0x7513	# <CJK>
0x6A37	0x6534	# <CJK>
0x6A38	0x65EE	# <CJK>
0x6A39	0x65EF	# <CJK>
0x6A3A	0x65F0	# <CJK>
0x6A3B	0x660A	# <CJK>
0x6A3C	0x6619	# <CJK>
0x6A3D	0x6772	# <CJK>
0x6A3E	0x6603	# <CJK>
0x6A3F	0x6615	# <CJK>
0x6A40	0x6600	# <CJK>
0x6A41	0x7085	# <CJK>
0x6A42	0x66F7	# <CJK>
0x6A43	0x661D	# <CJK>
0x6A44	0x6634	# <CJK>
0x6A45	0x6631	# <CJK>
0x6A46	0x6636	# <CJK>
0x6A47	0x6635	# <CJK>
0x6A48	0x8006	# <CJK>
0x6A49	0x665F	# <CJK>
0x6A4A	0x6654	# <CJK>
0x6A4B	0x6641	# <CJK>
0x6A4C	0x664F	# <CJK>
0x6A4D	0x6656	# <CJK>
0x6A4E	0x6661	# <CJK>
0x6A4F	0x6657	# <CJK>
0x6A50	0x6677	# <CJK>
0x6A51	0x6684	# <CJK>
0x6A52	0x668C	# <CJK>
0x6A53	0x66A7	# <CJK>
0x6A54	0x669D	# <CJK>
0x6A55	0x66BE	# <CJK>
0x6A56	0x66DB	# <CJK>
0x6A57	0x66DC	# <CJK>
0x6A58	0x66E6	# <CJK>
0x6A59	0x66E9	# <CJK>
0x6A5A	0x8D32	# <CJK>
0x6A5B	0x8D33	# <CJK>
0x6A5C	0x8D36	# <CJK>
0x6A5D	0x8D3B	# <CJK>
0x6A5E	0x8D3D	# <CJK>
0x6A5F	0x8D40	# <CJK>
0x6A60	0x8D45	# <CJK>
0x6A61	0x8D46	# <CJK>
0x6A62	0x8D48	# <CJK>
0x6A63	0x8D49	# <CJK>
0x6A64	0x8D47	# <CJK>
0x6A65	0x8D4D	# <CJK>
0x6A66	0x8D55	# <CJK>
0x6A67	0x8D59	# <CJK>
0x6A68	0x89C7	# <CJK>
0x6A69	0x89CA	# <CJK>
0x6A6A	0x89CB	# <CJK>
0x6A6B	0x89CC	# <CJK>
0x6A6C	0x89CE	# <CJK>
0x6A6D	0x89CF	# <CJK>
0x6A6E	0x89D0	# <CJK>
0x6A6F	0x89D1	# <CJK>
0x6A70	0x726E	# <CJK>
0x6A71	0x729F	# <CJK>
0x6A72	0x725D	# <CJK>
0x6A73	0x7266	# <CJK>
0x6A74	0x726F	# <CJK>
0x6A75	0x727E	# <CJK>
0x6A76	0x727F	# <CJK>
0x6A77	0x7284	# <CJK>
0x6A78	0x728B	# <CJK>
0x6A79	0x728D	# <CJK>
0x6A7A	0x728F	# <CJK>
0x6A7B	0x7292	# <CJK>
0x6A7C	0x6308	# <CJK>
0x6A7D	0x6332	# <CJK>
0x6A7E	0x63B0	# <CJK>
0x6B21	0x643F	# <CJK>
0x6B22	0x64D8	# <CJK>
0x6B23	0x8004	# <CJK>
0x6B24	0x6BEA	# <CJK>
0x6B25	0x6BF3	# <CJK>
0x6B26	0x6BFD	# <CJK>
0x6B27	0x6BF5	# <CJK>
0x6B28	0x6BF9	# <CJK>
0x6B29	0x6C05	# <CJK>
0x6B2A	0x6C07	# <CJK>
0x6B2B	0x6C06	# <CJK>
0x6B2C	0x6C0D	# <CJK>
0x6B2D	0x6C15	# <CJK>
0x6B2E	0x6C18	# <CJK>
0x6B2F	0x6C19	# <CJK>
0x6B30	0x6C1A	# <CJK>
0x6B31	0x6C21	# <CJK>
0x6B32	0x6C29	# <CJK>
0x6B33	0x6C24	# <CJK>
0x6B34	0x6C2A	# <CJK>
0x6B35	0x6C32	# <CJK>
0x6B36	0x6535	# <CJK>
0x6B37	0x6555	# <CJK>
0x6B38	0x656B	# <CJK>
0x6B39	0x724D	# <CJK>
0x6B3A	0x7252	# <CJK>
0x6B3B	0x7256	# <CJK>
0x6B3C	0x7230	# <CJK>
0x6B3D	0x8662	# <CJK>
0x6B3E	0x5216	# <CJK>
0x6B3F	0x809F	# <CJK>
0x6B40	0x809C	# <CJK>
0x6B41	0x8093	# <CJK>
0x6B42	0x80BC	# <CJK>
0x6B43	0x670A	# <CJK>
0x6B44	0x80BD	# <CJK>
0x6B45	0x80B1	# <CJK>
0x6B46	0x80AB	# <CJK>
0x6B47	0x80AD	# <CJK>
0x6B48	0x80B4	# <CJK>
0x6B49	0x80B7	# <CJK>
0x6B4A	0x80E7	# <CJK>
0x6B4B	0x80E8	# <CJK>
0x6B4C	0x80E9	# <CJK>
0x6B4D	0x80EA	# <CJK>
0x6B4E	0x80DB	# <CJK>
0x6B4F	0x80C2	# <CJK>
0x6B50	0x80C4	# <CJK>
0x6B51	0x80D9	# <CJK>
0x6B52	0x80CD	# <CJK>
0x6B53	0x80D7	# <CJK>
0x6B54	0x6710	# <CJK>
0x6B55	0x80DD	# <CJK>
0x6B56	0x80EB	# <CJK>
0x6B57	0x80F1	# <CJK>
0x6B58	0x80F4	# <CJK>
0x6B59	0x80ED	# <CJK>
0x6B5A	0x810D	# <CJK>
0x6B5B	0x810E	# <CJK>
0x6B5C	0x80F2	# <CJK>
0x6B5D	0x80FC	# <CJK>
0x6B5E	0x6715	# <CJK>
0x6B5F	0x8112	# <CJK>
0x6B60	0x8C5A	# <CJK>
0x6B61	0x8136	# <CJK>
0x6B62	0x811E	# <CJK>
0x6B63	0x812C	# <CJK>
0x6B64	0x8118	# <CJK>
0x6B65	0x8132	# <CJK>
0x6B66	0x8148	# <CJK>
0x6B67	0x814C	# <CJK>
0x6B68	0x8153	# <CJK>
0x6B69	0x8174	# <CJK>
0x6B6A	0x8159	# <CJK>
0x6B6B	0x815A	# <CJK>
0x6B6C	0x8171	# <CJK>
0x6B6D	0x8160	# <CJK>
0x6B6E	0x8169	# <CJK>
0x6B6F	0x817C	# <CJK>
0x6B70	0x817D	# <CJK>
0x6B71	0x816D	# <CJK>
0x6B72	0x8167	# <CJK>
0x6B73	0x584D	# <CJK>
0x6B74	0x5AB5	# <CJK>
0x6B75	0x8188	# <CJK>
0x6B76	0x8182	# <CJK>
0x6B77	0x8191	# <CJK>
0x6B78	0x6ED5	# <CJK>
0x6B79	0x81A3	# <CJK>
0x6B7A	0x81AA	# <CJK>
0x6B7B	0x81CC	# <CJK>
0x6B7C	0x6726	# <CJK>
0x6B7D	0x81CA	# <CJK>
0x6B7E	0x81BB	# <CJK>
0x6C21	0x81C1	# <CJK>
0x6C22	0x81A6	# <CJK>
0x6C23	0x6B24	# <CJK>
0x6C24	0x6B37	# <CJK>
0x6C25	0x6B39	# <CJK>
0x6C26	0x6B43	# <CJK>
0x6C27	0x6B46	# <CJK>
0x6C28	0x6B59	# <CJK>
0x6C29	0x98D1	# <CJK>
0x6C2A	0x98D2	# <CJK>
0x6C2B	0x98D3	# <CJK>
0x6C2C	0x98D5	# <CJK>
0x6C2D	0x98D9	# <CJK>
0x6C2E	0x98DA	# <CJK>
0x6C2F	0x6BB3	# <CJK>
0x6C30	0x5F40	# <CJK>
0x6C31	0x6BC2	# <CJK>
0x6C32	0x89F3	# <CJK>
0x6C33	0x6590	# <CJK>
0x6C34	0x9F51	# <CJK>
0x6C35	0x6593	# <CJK>
0x6C36	0x65BC	# <CJK>
0x6C37	0x65C6	# <CJK>
0x6C38	0x65C4	# <CJK>
0x6C39	0x65C3	# <CJK>
0x6C3A	0x65CC	# <CJK>
0x6C3B	0x65CE	# <CJK>
0x6C3C	0x65D2	# <CJK>
0x6C3D	0x65D6	# <CJK>
0x6C3E	0x7080	# <CJK>
0x6C3F	0x709C	# <CJK>
0x6C40	0x7096	# <CJK>
0x6C41	0x709D	# <CJK>
0x6C42	0x70BB	# <CJK>
0x6C43	0x70C0	# <CJK>
0x6C44	0x70B7	# <CJK>
0x6C45	0x70AB	# <CJK>
0x6C46	0x70B1	# <CJK>
0x6C47	0x70E8	# <CJK>
0x6C48	0x70CA	# <CJK>
0x6C49	0x7110	# <CJK>
0x6C4A	0x7113	# <CJK>
0x6C4B	0x7116	# <CJK>
0x6C4C	0x712F	# <CJK>
0x6C4D	0x7131	# <CJK>
0x6C4E	0x7173	# <CJK>
0x6C4F	0x715C	# <CJK>
0x6C50	0x7168	# <CJK>
0x6C51	0x7145	# <CJK>
0x6C52	0x7172	# <CJK>
0x6C53	0x714A	# <CJK>
0x6C54	0x7178	# <CJK>
0x6C55	0x717A	# <CJK>
0x6C56	0x7198	# <CJK>
0x6C57	0x71B3	# <CJK>
0x6C58	0x71B5	# <CJK>
0x6C59	0x71A8	# <CJK>
0x6C5A	0x71A0	# <CJK>
0x6C5B	0x71E0	# <CJK>
0x6C5C	0x71D4	# <CJK>
0x6C5D	0x71E7	# <CJK>
0x6C5E	0x71F9	# <CJK>
0x6C5F	0x721D	# <CJK>
0x6C60	0x7228	# <CJK>
0x6C61	0x706C	# <CJK>
0x6C62	0x7118	# <CJK>
0x6C63	0x7166	# <CJK>
0x6C64	0x71B9	# <CJK>
0x6C65	0x623E	# <CJK>
0x6C66	0x623D	# <CJK>
0x6C67	0x6243	# <CJK>
0x6C68	0x6248	# <CJK>
0x6C69	0x6249	# <CJK>
0x6C6A	0x793B	# <CJK>
0x6C6B	0x7940	# <CJK>
0x6C6C	0x7946	# <CJK>
0x6C6D	0x7949	# <CJK>
0x6C6E	0x795B	# <CJK>
0x6C6F	0x795C	# <CJK>
0x6C70	0x7953	# <CJK>
0x6C71	0x795A	# <CJK>
0x6C72	0x7962	# <CJK>
0x6C73	0x7957	# <CJK>
0x6C74	0x7960	# <CJK>
0x6C75	0x796F	# <CJK>
0x6C76	0x7967	# <CJK>
0x6C77	0x797A	# <CJK>
0x6C78	0x7985	# <CJK>
0x6C79	0x798A	# <CJK>
0x6C7A	0x799A	# <CJK>
0x6C7B	0x79A7	# <CJK>
0x6C7C	0x79B3	# <CJK>
0x6C7D	0x5FD1	# <CJK>
0x6C7E	0x5FD0	# <CJK>
0x6D21	0x603C	# <CJK>
0x6D22	0x605D	# <CJK>
0x6D23	0x605A	# <CJK>
0x6D24	0x6067	# <CJK>
0x6D25	0x6041	# <CJK>
0x6D26	0x6059	# <CJK>
0x6D27	0x6063	# <CJK>
0x6D28	0x60AB	# <CJK>
0x6D29	0x6106	# <CJK>
0x6D2A	0x610D	# <CJK>
0x6D2B	0x615D	# <CJK>
0x6D2C	0x61A9	# <CJK>
0x6D2D	0x619D	# <CJK>
0x6D2E	0x61CB	# <CJK>
0x6D2F	0x61D1	# <CJK>
0x6D30	0x6206	# <CJK>
0x6D31	0x8080	# <CJK>
0x6D32	0x807F	# <CJK>
0x6D33	0x6C93	# <CJK>
0x6D34	0x6CF6	# <CJK>
0x6D35	0x6DFC	# <CJK>
0x6D36	0x77F6	# <CJK>
0x6D37	0x77F8	# <CJK>
0x6D38	0x7800	# <CJK>
0x6D39	0x7809	# <CJK>
0x6D3A	0x7817	# <CJK>
0x6D3B	0x7818	# <CJK>
0x6D3C	0x7811	# <CJK>
0x6D3D	0x65AB	# <CJK>
0x6D3E	0x782D	# <CJK>
0x6D3F	0x781C	# <CJK>
0x6D40	0x781D	# <CJK>
0x6D41	0x7839	# <CJK>
0x6D42	0x783A	# <CJK>
0x6D43	0x783B	# <CJK>
0x6D44	0x781F	# <CJK>
0x6D45	0x783C	# <CJK>
0x6D46	0x7825	# <CJK>
0x6D47	0x782C	# <CJK>
0x6D48	0x7823	# <CJK>
0x6D49	0x7829	# <CJK>
0x6D4A	0x784E	# <CJK>
0x6D4B	0x786D	# <CJK>
0x6D4C	0x7856	# <CJK>
0x6D4D	0x7857	# <CJK>
0x6D4E	0x7826	# <CJK>
0x6D4F	0x7850	# <CJK>
0x6D50	0x7847	# <CJK>
0x6D51	0x784C	# <CJK>
0x6D52	0x786A	# <CJK>
0x6D53	0x789B	# <CJK>
0x6D54	0x7893	# <CJK>
0x6D55	0x789A	# <CJK>
0x6D56	0x7887	# <CJK>
0x6D57	0x789C	# <CJK>
0x6D58	0x78A1	# <CJK>
0x6D59	0x78A3	# <CJK>
0x6D5A	0x78B2	# <CJK>
0x6D5B	0x78B9	# <CJK>
0x6D5C	0x78A5	# <CJK>
0x6D5D	0x78D4	# <CJK>
0x6D5E	0x78D9	# <CJK>
0x6D5F	0x78C9	# <CJK>
0x6D60	0x78EC	# <CJK>
0x6D61	0x78F2	# <CJK>
0x6D62	0x7905	# <CJK>
0x6D63	0x78F4	# <CJK>
0x6D64	0x7913	# <CJK>
0x6D65	0x7924	# <CJK>
0x6D66	0x791E	# <CJK>
0x6D67	0x7934	# <CJK>
0x6D68	0x9F9B	# <CJK>
0x6D69	0x9EF9	# <CJK>
0x6D6A	0x9EFB	# <CJK>
0x6D6B	0x9EFC	# <CJK>
0x6D6C	0x76F1	# <CJK>
0x6D6D	0x7704	# <CJK>
0x6D6E	0x770D	# <CJK>
0x6D6F	0x76F9	# <CJK>
0x6D70	0x7707	# <CJK>
0x6D71	0x7708	# <CJK>
0x6D72	0x771A	# <CJK>
0x6D73	0x7722	# <CJK>
0x6D74	0x7719	# <CJK>
0x6D75	0x772D	# <CJK>
0x6D76	0x7726	# <CJK>
0x6D77	0x7735	# <CJK>
0x6D78	0x7738	# <CJK>
0x6D79	0x7750	# <CJK>
0x6D7A	0x7751	# <CJK>
0x6D7B	0x7747	# <CJK>
0x6D7C	0x7743	# <CJK>
0x6D7D	0x775A	# <CJK>
0x6D7E	0x7768	# <CJK>
0x6E21	0x7762	# <CJK>
0x6E22	0x7765	# <CJK>
0x6E23	0x777F	# <CJK>
0x6E24	0x778D	# <CJK>
0x6E25	0x777D	# <CJK>
0x6E26	0x7780	# <CJK>
0x6E27	0x778C	# <CJK>
0x6E28	0x7791	# <CJK>
0x6E29	0x779F	# <CJK>
0x6E2A	0x77A0	# <CJK>
0x6E2B	0x77B0	# <CJK>
0x6E2C	0x77B5	# <CJK>
0x6E2D	0x77BD	# <CJK>
0x6E2E	0x753A	# <CJK>
0x6E2F	0x7540	# <CJK>
0x6E30	0x754E	# <CJK>
0x6E31	0x754B	# <CJK>
0x6E32	0x7548	# <CJK>
0x6E33	0x755B	# <CJK>
0x6E34	0x7572	# <CJK>
0x6E35	0x7579	# <CJK>
0x6E36	0x7583	# <CJK>
0x6E37	0x7F58	# <CJK>
0x6E38	0x7F61	# <CJK>
0x6E39	0x7F5F	# <CJK>
0x6E3A	0x8A48	# <CJK>
0x6E3B	0x7F68	# <CJK>
0x6E3C	0x7F74	# <CJK>
0x6E3D	0x7F71	# <CJK>
0x6E3E	0x7F79	# <CJK>
0x6E3F	0x7F81	# <CJK>
0x6E40	0x7F7E	# <CJK>
0x6E41	0x76CD	# <CJK>
0x6E42	0x76E5	# <CJK>
0x6E43	0x8832	# <CJK>
0x6E44	0x9485	# <CJK>
0x6E45	0x9486	# <CJK>
0x6E46	0x9487	# <CJK>
0x6E47	0x948B	# <CJK>
0x6E48	0x948A	# <CJK>
0x6E49	0x948C	# <CJK>
0x6E4A	0x948D	# <CJK>
0x6E4B	0x948F	# <CJK>
0x6E4C	0x9490	# <CJK>
0x6E4D	0x9494	# <CJK>
0x6E4E	0x9497	# <CJK>
0x6E4F	0x9495	# <CJK>
0x6E50	0x949A	# <CJK>
0x6E51	0x949B	# <CJK>
0x6E52	0x949C	# <CJK>
0x6E53	0x94A3	# <CJK>
0x6E54	0x94A4	# <CJK>
0x6E55	0x94AB	# <CJK>
0x6E56	0x94AA	# <CJK>
0x6E57	0x94AD	# <CJK>
0x6E58	0x94AC	# <CJK>
0x6E59	0x94AF	# <CJK>
0x6E5A	0x94B0	# <CJK>
0x6E5B	0x94B2	# <CJK>
0x6E5C	0x94B4	# <CJK>
0x6E5D	0x94B6	# <CJK>
0x6E5E	0x94B7	# <CJK>
0x6E5F	0x94B8	# <CJK>
0x6E60	0x94B9	# <CJK>
0x6E61	0x94BA	# <CJK>
0x6E62	0x94BC	# <CJK>
0x6E63	0x94BD	# <CJK>
0x6E64	0x94BF	# <CJK>
0x6E65	0x94C4	# <CJK>
0x6E66	0x94C8	# <CJK>
0x6E67	0x94C9	# <CJK>
0x6E68	0x94CA	# <CJK>
0x6E69	0x94CB	# <CJK>
0x6E6A	0x94CC	# <CJK>
0x6E6B	0x94CD	# <CJK>
0x6E6C	0x94CE	# <CJK>
0x6E6D	0x94D0	# <CJK>
0x6E6E	0x94D1	# <CJK>
0x6E6F	0x94D2	# <CJK>
0x6E70	0x94D5	# <CJK>
0x6E71	0x94D6	# <CJK>
0x6E72	0x94D7	# <CJK>
0x6E73	0x94D9	# <CJK>
0x6E74	0x94D8	# <CJK>
0x6E75	0x94DB	# <CJK>
0x6E76	0x94DE	# <CJK>
0x6E77	0x94DF	# <CJK>
0x6E78	0x94E0	# <CJK>
0x6E79	0x94E2	# <CJK>
0x6E7A	0x94E4	# <CJK>
0x6E7B	0x94E5	# <CJK>
0x6E7C	0x94E7	# <CJK>
0x6E7D	0x94E8	# <CJK>
0x6E7E	0x94EA	# <CJK>
0x6F21	0x94E9	# <CJK>
0x6F22	0x94EB	# <CJK>
0x6F23	0x94EE	# <CJK>
0x6F24	0x94EF	# <CJK>
0x6F25	0x94F3	# <CJK>
0x6F26	0x94F4	# <CJK>
0x6F27	0x94F5	# <CJK>
0x6F28	0x94F7	# <CJK>
0x6F29	0x94F9	# <CJK>
0x6F2A	0x94FC	# <CJK>
0x6F2B	0x94FD	# <CJK>
0x6F2C	0x94FF	# <CJK>
0x6F2D	0x9503	# <CJK>
0x6F2E	0x9502	# <CJK>
0x6F2F	0x9506	# <CJK>
0x6F30	0x9507	# <CJK>
0x6F31	0x9509	# <CJK>
0x6F32	0x950A	# <CJK>
0x6F33	0x950D	# <CJK>
0x6F34	0x950E	# <CJK>
0x6F35	0x950F	# <CJK>
0x6F36	0x9512	# <CJK>
0x6F37	0x9513	# <CJK>
0x6F38	0x9514	# <CJK>
0x6F39	0x9515	# <CJK>
0x6F3A	0x9516	# <CJK>
0x6F3B	0x9518	# <CJK>
0x6F3C	0x951B	# <CJK>
0x6F3D	0x951D	# <CJK>
0x6F3E	0x951E	# <CJK>
0x6F3F	0x951F	# <CJK>
0x6F40	0x9522	# <CJK>
0x6F41	0x952A	# <CJK>
0x6F42	0x952B	# <CJK>
0x6F43	0x9529	# <CJK>
0x6F44	0x952C	# <CJK>
0x6F45	0x9531	# <CJK>
0x6F46	0x9532	# <CJK>
0x6F47	0x9534	# <CJK>
0x6F48	0x9536	# <CJK>
0x6F49	0x9537	# <CJK>
0x6F4A	0x9538	# <CJK>
0x6F4B	0x953C	# <CJK>
0x6F4C	0x953E	# <CJK>
0x6F4D	0x953F	# <CJK>
0x6F4E	0x9542	# <CJK>
0x6F4F	0x9535	# <CJK>
0x6F50	0x9544	# <CJK>
0x6F51	0x9545	# <CJK>
0x6F52	0x9546	# <CJK>
0x6F53	0x9549	# <CJK>
0x6F54	0x954C	# <CJK>
0x6F55	0x954E	# <CJK>
0x6F56	0x954F	# <CJK>
0x6F57	0x9552	# <CJK>
0x6F58	0x9553	# <CJK>
0x6F59	0x9554	# <CJK>
0x6F5A	0x9556	# <CJK>
0x6F5B	0x9557	# <CJK>
0x6F5C	0x9558	# <CJK>
0x6F5D	0x9559	# <CJK>
0x6F5E	0x955B	# <CJK>
0x6F5F	0x955E	# <CJK>
0x6F60	0x955F	# <CJK>
0x6F61	0x955D	# <CJK>
0x6F62	0x9561	# <CJK>
0x6F63	0x9562	# <CJK>
0x6F64	0x9564	# <CJK>
0x6F65	0x9565	# <CJK>
0x6F66	0x9566	# <CJK>
0x6F67	0x9567	# <CJK>
0x6F68	0x9568	# <CJK>
0x6F69	0x9569	# <CJK>
0x6F6A	0x956A	# <CJK>
0x6F6B	0x956B	# <CJK>
0x6F6C	0x956C	# <CJK>
0x6F6D	0x956F	# <CJK>
0x6F6E	0x9571	# <CJK>
0x6F6F	0x9572	# <CJK>
0x6F70	0x9573	# <CJK>
0x6F71	0x953A	# <CJK>
0x6F72	0x77E7	# <CJK>
0x6F73	0x77EC	# <CJK>
0x6F74	0x96C9	# <CJK>
0x6F75	0x79D5	# <CJK>
0x6F76	0x79ED	# <CJK>
0x6F77	0x79E3	# <CJK>
0x6F78	0x79EB	# <CJK>
0x6F79	0x7A06	# <CJK>
0x6F7A	0x5D47	# <CJK>
0x6F7B	0x7A03	# <CJK>
0x6F7C	0x7A02	# <CJK>
0x6F7D	0x7A1E	# <CJK>
0x6F7E	0x7A14	# <CJK>
0x7021	0x7A39	# <CJK>
0x7022	0x7A37	# <CJK>
0x7023	0x7A51	# <CJK>
0x7024	0x9ECF	# <CJK>
0x7025	0x99A5	# <CJK>
0x7026	0x7A70	# <CJK>
0x7027	0x7688	# <CJK>
0x7028	0x768E	# <CJK>
0x7029	0x7693	# <CJK>
0x702A	0x7699	# <CJK>
0x702B	0x76A4	# <CJK>
0x702C	0x74DE	# <CJK>
0x702D	0x74E0	# <CJK>
0x702E	0x752C	# <CJK>
0x702F	0x9E20	# <CJK>
0x7030	0x9E22	# <CJK>
0x7031	0x9E28	# <CJK>
0x7032	0x9E29	# <CJK>
0x7033	0x9E2A	# <CJK>
0x7034	0x9E2B	# <CJK>
0x7035	0x9E2C	# <CJK>
0x7036	0x9E32	# <CJK>
0x7037	0x9E31	# <CJK>
0x7038	0x9E36	# <CJK>
0x7039	0x9E38	# <CJK>
0x703A	0x9E37	# <CJK>
0x703B	0x9E39	# <CJK>
0x703C	0x9E3A	# <CJK>
0x703D	0x9E3E	# <CJK>
0x703E	0x9E41	# <CJK>
0x703F	0x9E42	# <CJK>
0x7040	0x9E44	# <CJK>
0x7041	0x9E46	# <CJK>
0x7042	0x9E47	# <CJK>
0x7043	0x9E48	# <CJK>
0x7044	0x9E49	# <CJK>
0x7045	0x9E4B	# <CJK>
0x7046	0x9E4C	# <CJK>
0x7047	0x9E4E	# <CJK>
0x7048	0x9E51	# <CJK>
0x7049	0x9E55	# <CJK>
0x704A	0x9E57	# <CJK>
0x704B	0x9E5A	# <CJK>
0x704C	0x9E5B	# <CJK>
0x704D	0x9E5C	# <CJK>
0x704E	0x9E5E	# <CJK>
0x704F	0x9E63	# <CJK>
0x7050	0x9E66	# <CJK>
0x7051	0x9E67	# <CJK>
0x7052	0x9E68	# <CJK>
0x7053	0x9E69	# <CJK>
0x7054	0x9E6A	# <CJK>
0x7055	0x9E6B	# <CJK>
0x7056	0x9E6C	# <CJK>
0x7057	0x9E71	# <CJK>
0x7058	0x9E6D	# <CJK>
0x7059	0x9E73	# <CJK>
0x705A	0x7592	# <CJK>
0x705B	0x7594	# <CJK>
0x705C	0x7596	# <CJK>
0x705D	0x75A0	# <CJK>
0x705E	0x759D	# <CJK>
0x705F	0x75AC	# <CJK>
0x7060	0x75A3	# <CJK>
0x7061	0x75B3	# <CJK>
0x7062	0x75B4	# <CJK>
0x7063	0x75B8	# <CJK>
0x7064	0x75C4	# <CJK>
0x7065	0x75B1	# <CJK>
0x7066	0x75B0	# <CJK>
0x7067	0x75C3	# <CJK>
0x7068	0x75C2	# <CJK>
0x7069	0x75D6	# <CJK>
0x706A	0x75CD	# <CJK>
0x706B	0x75E3	# <CJK>
0x706C	0x75E8	# <CJK>
0x706D	0x75E6	# <CJK>
0x706E	0x75E4	# <CJK>
0x706F	0x75EB	# <CJK>
0x7070	0x75E7	# <CJK>
0x7071	0x7603	# <CJK>
0x7072	0x75F1	# <CJK>
0x7073	0x75FC	# <CJK>
0x7074	0x75FF	# <CJK>
0x7075	0x7610	# <CJK>
0x7076	0x7600	# <CJK>
0x7077	0x7605	# <CJK>
0x7078	0x760C	# <CJK>
0x7079	0x7617	# <CJK>
0x707A	0x760A	# <CJK>
0x707B	0x7625	# <CJK>
0x707C	0x7618	# <CJK>
0x707D	0x7615	# <CJK>
0x707E	0x7619	# <CJK>
0x7121	0x761B	# <CJK>
0x7122	0x763C	# <CJK>
0x7123	0x7622	# <CJK>
0x7124	0x7620	# <CJK>
0x7125	0x7640	# <CJK>
0x7126	0x762D	# <CJK>
0x7127	0x7630	# <CJK>
0x7128	0x763F	# <CJK>
0x7129	0x7635	# <CJK>
0x712A	0x7643	# <CJK>
0x712B	0x763E	# <CJK>
0x712C	0x7633	# <CJK>
0x712D	0x764D	# <CJK>
0x712E	0x765E	# <CJK>
0x712F	0x7654	# <CJK>
0x7130	0x765C	# <CJK>
0x7131	0x7656	# <CJK>
0x7132	0x766B	# <CJK>
0x7133	0x766F	# <CJK>
0x7134	0x7FCA	# <CJK>
0x7135	0x7AE6	# <CJK>
0x7136	0x7A78	# <CJK>
0x7137	0x7A79	# <CJK>
0x7138	0x7A80	# <CJK>
0x7139	0x7A86	# <CJK>
0x713A	0x7A88	# <CJK>
0x713B	0x7A95	# <CJK>
0x713C	0x7AA6	# <CJK>
0x713D	0x7AA0	# <CJK>
0x713E	0x7AAC	# <CJK>
0x713F	0x7AA8	# <CJK>
0x7140	0x7AAD	# <CJK>
0x7141	0x7AB3	# <CJK>
0x7142	0x8864	# <CJK>
0x7143	0x8869	# <CJK>
0x7144	0x8872	# <CJK>
0x7145	0x887D	# <CJK>
0x7146	0x887F	# <CJK>
0x7147	0x8882	# <CJK>
0x7148	0x88A2	# <CJK>
0x7149	0x88C6	# <CJK>
0x714A	0x88B7	# <CJK>
0x714B	0x88BC	# <CJK>
0x714C	0x88C9	# <CJK>
0x714D	0x88E2	# <CJK>
0x714E	0x88CE	# <CJK>
0x714F	0x88E3	# <CJK>
0x7150	0x88E5	# <CJK>
0x7151	0x88F1	# <CJK>
0x7152	0x891A	# <CJK>
0x7153	0x88FC	# <CJK>
0x7154	0x88E8	# <CJK>
0x7155	0x88FE	# <CJK>
0x7156	0x88F0	# <CJK>
0x7157	0x8921	# <CJK>
0x7158	0x8919	# <CJK>
0x7159	0x8913	# <CJK>
0x715A	0x891B	# <CJK>
0x715B	0x890A	# <CJK>
0x715C	0x8934	# <CJK>
0x715D	0x892B	# <CJK>
0x715E	0x8936	# <CJK>
0x715F	0x8941	# <CJK>
0x7160	0x8966	# <CJK>
0x7161	0x897B	# <CJK>
0x7162	0x758B	# <CJK>
0x7163	0x80E5	# <CJK>
0x7164	0x76B2	# <CJK>
0x7165	0x76B4	# <CJK>
0x7166	0x77DC	# <CJK>
0x7167	0x8012	# <CJK>
0x7168	0x8014	# <CJK>
0x7169	0x8016	# <CJK>
0x716A	0x801C	# <CJK>
0x716B	0x8020	# <CJK>
0x716C	0x8022	# <CJK>
0x716D	0x8025	# <CJK>
0x716E	0x8026	# <CJK>
0x716F	0x8027	# <CJK>
0x7170	0x8029	# <CJK>
0x7171	0x8028	# <CJK>
0x7172	0x8031	# <CJK>
0x7173	0x800B	# <CJK>
0x7174	0x8035	# <CJK>
0x7175	0x8043	# <CJK>
0x7176	0x8046	# <CJK>
0x7177	0x804D	# <CJK>
0x7178	0x8052	# <CJK>
0x7179	0x8069	# <CJK>
0x717A	0x8071	# <CJK>
0x717B	0x8983	# <CJK>
0x717C	0x9878	# <CJK>
0x717D	0x9880	# <CJK>
0x717E	0x9883	# <CJK>
0x7221	0x9889	# <CJK>
0x7222	0x988C	# <CJK>
0x7223	0x988D	# <CJK>
0x7224	0x988F	# <CJK>
0x7225	0x9894	# <CJK>
0x7226	0x989A	# <CJK>
0x7227	0x989B	# <CJK>
0x7228	0x989E	# <CJK>
0x7229	0x989F	# <CJK>
0x722A	0x98A1	# <CJK>
0x722B	0x98A2	# <CJK>
0x722C	0x98A5	# <CJK>
0x722D	0x98A6	# <CJK>
0x722E	0x864D	# <CJK>
0x722F	0x8654	# <CJK>
0x7230	0x866C	# <CJK>
0x7231	0x866E	# <CJK>
0x7232	0x867F	# <CJK>
0x7233	0x867A	# <CJK>
0x7234	0x867C	# <CJK>
0x7235	0x867B	# <CJK>
0x7236	0x86A8	# <CJK>
0x7237	0x868D	# <CJK>
0x7238	0x868B	# <CJK>
0x7239	0x86AC	# <CJK>
0x723A	0x869D	# <CJK>
0x723B	0x86A7	# <CJK>
0x723C	0x86A3	# <CJK>
0x723D	0x86AA	# <CJK>
0x723E	0x8693	# <CJK>
0x723F	0x86A9	# <CJK>
0x7240	0x86B6	# <CJK>
0x7241	0x86C4	# <CJK>
0x7242	0x86B5	# <CJK>
0x7243	0x86CE	# <CJK>
0x7244	0x86B0	# <CJK>
0x7245	0x86BA	# <CJK>
0x7246	0x86B1	# <CJK>
0x7247	0x86AF	# <CJK>
0x7248	0x86C9	# <CJK>
0x7249	0x86CF	# <CJK>
0x724A	0x86B4	# <CJK>
0x724B	0x86E9	# <CJK>
0x724C	0x86F1	# <CJK>
0x724D	0x86F2	# <CJK>
0x724E	0x86ED	# <CJK>
0x724F	0x86F3	# <CJK>
0x7250	0x86D0	# <CJK>
0x7251	0x8713	# <CJK>
0x7252	0x86DE	# <CJK>
0x7253	0x86F4	# <CJK>
0x7254	0x86DF	# <CJK>
0x7255	0x86D8	# <CJK>
0x7256	0x86D1	# <CJK>
0x7257	0x8703	# <CJK>
0x7258	0x8707	# <CJK>
0x7259	0x86F8	# <CJK>
0x725A	0x8708	# <CJK>
0x725B	0x870A	# <CJK>
0x725C	0x870D	# <CJK>
0x725D	0x8709	# <CJK>
0x725E	0x8723	# <CJK>
0x725F	0x873B	# <CJK>
0x7260	0x871E	# <CJK>
0x7261	0x8725	# <CJK>
0x7262	0x872E	# <CJK>
0x7263	0x871A	# <CJK>
0x7264	0x873E	# <CJK>
0x7265	0x8748	# <CJK>
0x7266	0x8734	# <CJK>
0x7267	0x8731	# <CJK>
0x7268	0x8729	# <CJK>
0x7269	0x8737	# <CJK>
0x726A	0x873F	# <CJK>
0x726B	0x8782	# <CJK>
0x726C	0x8722	# <CJK>
0x726D	0x877D	# <CJK>
0x726E	0x877E	# <CJK>
0x726F	0x877B	# <CJK>
0x7270	0x8760	# <CJK>
0x7271	0x8770	# <CJK>
0x7272	0x874C	# <CJK>
0x7273	0x876E	# <CJK>
0x7274	0x878B	# <CJK>
0x7275	0x8753	# <CJK>
0x7276	0x8763	# <CJK>
0x7277	0x877C	# <CJK>
0x7278	0x8764	# <CJK>
0x7279	0x8759	# <CJK>
0x727A	0x8765	# <CJK>
0x727B	0x8793	# <CJK>
0x727C	0x87AF	# <CJK>
0x727D	0x87A8	# <CJK>
0x727E	0x87D2	# <CJK>
0x7321	0x87C6	# <CJK>
0x7322	0x8788	# <CJK>
0x7323	0x8785	# <CJK>
0x7324	0x87AD	# <CJK>
0x7325	0x8797	# <CJK>
0x7326	0x8783	# <CJK>
0x7327	0x87AB	# <CJK>
0x7328	0x87E5	# <CJK>
0x7329	0x87AC	# <CJK>
0x732A	0x87B5	# <CJK>
0x732B	0x87B3	# <CJK>
0x732C	0x87CB	# <CJK>
0x732D	0x87D3	# <CJK>
0x732E	0x87BD	# <CJK>
0x732F	0x87D1	# <CJK>
0x7330	0x87C0	# <CJK>
0x7331	0x87CA	# <CJK>
0x7332	0x87DB	# <CJK>
0x7333	0x87EA	# <CJK>
0x7334	0x87E0	# <CJK>
0x7335	0x87EE	# <CJK>
0x7336	0x8816	# <CJK>
0x7337	0x8813	# <CJK>
0x7338	0x87FE	# <CJK>
0x7339	0x880A	# <CJK>
0x733A	0x881B	# <CJK>
0x733B	0x8821	# <CJK>
0x733C	0x8839	# <CJK>
0x733D	0x883C	# <CJK>
0x733E	0x7F36	# <CJK>
0x733F	0x7F42	# <CJK>
0x7340	0x7F44	# <CJK>
0x7341	0x7F45	# <CJK>
0x7342	0x8210	# <CJK>
0x7343	0x7AFA	# <CJK>
0x7344	0x7AFD	# <CJK>
0x7345	0x7B08	# <CJK>
0x7346	0x7B03	# <CJK>
0x7347	0x7B04	# <CJK>
0x7348	0x7B15	# <CJK>
0x7349	0x7B0A	# <CJK>
0x734A	0x7B2B	# <CJK>
0x734B	0x7B0F	# <CJK>
0x734C	0x7B47	# <CJK>
0x734D	0x7B38	# <CJK>
0x734E	0x7B2A	# <CJK>
0x734F	0x7B19	# <CJK>
0x7350	0x7B2E	# <CJK>
0x7351	0x7B31	# <CJK>
0x7352	0x7B20	# <CJK>
0x7353	0x7B25	# <CJK>
0x7354	0x7B24	# <CJK>
0x7355	0x7B33	# <CJK>
0x7356	0x7B3E	# <CJK>
0x7357	0x7B1E	# <CJK>
0x7358	0x7B58	# <CJK>
0x7359	0x7B5A	# <CJK>
0x735A	0x7B45	# <CJK>
0x735B	0x7B75	# <CJK>
0x735C	0x7B4C	# <CJK>
0x735D	0x7B5D	# <CJK>
0x735E	0x7B60	# <CJK>
0x735F	0x7B6E	# <CJK>
0x7360	0x7B7B	# <CJK>
0x7361	0x7B62	# <CJK>
0x7362	0x7B72	# <CJK>
0x7363	0x7B71	# <CJK>
0x7364	0x7B90	# <CJK>
0x7365	0x7BA6	# <CJK>
0x7366	0x7BA7	# <CJK>
0x7367	0x7BB8	# <CJK>
0x7368	0x7BAC	# <CJK>
0x7369	0x7B9D	# <CJK>
0x736A	0x7BA8	# <CJK>
0x736B	0x7B85	# <CJK>
0x736C	0x7BAA	# <CJK>
0x736D	0x7B9C	# <CJK>
0x736E	0x7BA2	# <CJK>
0x736F	0x7BAB	# <CJK>
0x7370	0x7BB4	# <CJK>
0x7371	0x7BD1	# <CJK>
0x7372	0x7BC1	# <CJK>
0x7373	0x7BCC	# <CJK>
0x7374	0x7BDD	# <CJK>
0x7375	0x7BDA	# <CJK>
0x7376	0x7BE5	# <CJK>
0x7377	0x7BE6	# <CJK>
0x7378	0x7BEA	# <CJK>
0x7379	0x7C0C	# <CJK>
0x737A	0x7BFE	# <CJK>
0x737B	0x7BFC	# <CJK>
0x737C	0x7C0F	# <CJK>
0x737D	0x7C16	# <CJK>
0x737E	0x7C0B	# <CJK>
0x7421	0x7C1F	# <CJK>
0x7422	0x7C2A	# <CJK>
0x7423	0x7C26	# <CJK>
0x7424	0x7C38	# <CJK>
0x7425	0x7C41	# <CJK>
0x7426	0x7C40	# <CJK>
0x7427	0x81FE	# <CJK>
0x7428	0x8201	# <CJK>
0x7429	0x8202	# <CJK>
0x742A	0x8204	# <CJK>
0x742B	0x81EC	# <CJK>
0x742C	0x8844	# <CJK>
0x742D	0x8221	# <CJK>
0x742E	0x8222	# <CJK>
0x742F	0x8223	# <CJK>
0x7430	0x822D	# <CJK>
0x7431	0x822F	# <CJK>
0x7432	0x8228	# <CJK>
0x7433	0x822B	# <CJK>
0x7434	0x8238	# <CJK>
0x7435	0x823B	# <CJK>
0x7436	0x8233	# <CJK>
0x7437	0x8234	# <CJK>
0x7438	0x823E	# <CJK>
0x7439	0x8244	# <CJK>
0x743A	0x8249	# <CJK>
0x743B	0x824B	# <CJK>
0x743C	0x824F	# <CJK>
0x743D	0x825A	# <CJK>
0x743E	0x825F	# <CJK>
0x743F	0x8268	# <CJK>
0x7440	0x887E	# <CJK>
0x7441	0x8885	# <CJK>
0x7442	0x8888	# <CJK>
0x7443	0x88D8	# <CJK>
0x7444	0x88DF	# <CJK>
0x7445	0x895E	# <CJK>
0x7446	0x7F9D	# <CJK>
0x7447	0x7F9F	# <CJK>
0x7448	0x7FA7	# <CJK>
0x7449	0x7FAF	# <CJK>
0x744A	0x7FB0	# <CJK>
0x744B	0x7FB2	# <CJK>
0x744C	0x7C7C	# <CJK>
0x744D	0x6549	# <CJK>
0x744E	0x7C91	# <CJK>
0x744F	0x7C9D	# <CJK>
0x7450	0x7C9C	# <CJK>
0x7451	0x7C9E	# <CJK>
0x7452	0x7CA2	# <CJK>
0x7453	0x7CB2	# <CJK>
0x7454	0x7CBC	# <CJK>
0x7455	0x7CBD	# <CJK>
0x7456	0x7CC1	# <CJK>
0x7457	0x7CC7	# <CJK>
0x7458	0x7CCC	# <CJK>
0x7459	0x7CCD	# <CJK>
0x745A	0x7CC8	# <CJK>
0x745B	0x7CC5	# <CJK>
0x745C	0x7CD7	# <CJK>
0x745D	0x7CE8	# <CJK>
0x745E	0x826E	# <CJK>
0x745F	0x66A8	# <CJK>
0x7460	0x7FBF	# <CJK>
0x7461	0x7FCE	# <CJK>
0x7462	0x7FD5	# <CJK>
0x7463	0x7FE5	# <CJK>
0x7464	0x7FE1	# <CJK>
0x7465	0x7FE6	# <CJK>
0x7466	0x7FE9	# <CJK>
0x7467	0x7FEE	# <CJK>
0x7468	0x7FF3	# <CJK>
0x7469	0x7CF8	# <CJK>
0x746A	0x7D77	# <CJK>
0x746B	0x7DA6	# <CJK>
0x746C	0x7DAE	# <CJK>
0x746D	0x7E47	# <CJK>
0x746E	0x7E9B	# <CJK>
0x746F	0x9EB8	# <CJK>
0x7470	0x9EB4	# <CJK>
0x7471	0x8D73	# <CJK>
0x7472	0x8D84	# <CJK>
0x7473	0x8D94	# <CJK>
0x7474	0x8D91	# <CJK>
0x7475	0x8DB1	# <CJK>
0x7476	0x8D67	# <CJK>
0x7477	0x8D6D	# <CJK>
0x7478	0x8C47	# <CJK>
0x7479	0x8C49	# <CJK>
0x747A	0x914A	# <CJK>
0x747B	0x9150	# <CJK>
0x747C	0x914E	# <CJK>
0x747D	0x914F	# <CJK>
0x747E	0x9164	# <CJK>
0x7521	0x9162	# <CJK>
0x7522	0x9161	# <CJK>
0x7523	0x9170	# <CJK>
0x7524	0x9169	# <CJK>
0x7525	0x916F	# <CJK>
0x7526	0x917D	# <CJK>
0x7527	0x917E	# <CJK>
0x7528	0x9172	# <CJK>
0x7529	0x9174	# <CJK>
0x752A	0x9179	# <CJK>
0x752B	0x918C	# <CJK>
0x752C	0x9185	# <CJK>
0x752D	0x9190	# <CJK>
0x752E	0x918D	# <CJK>
0x752F	0x9191	# <CJK>
0x7530	0x91A2	# <CJK>
0x7531	0x91A3	# <CJK>
0x7532	0x91AA	# <CJK>
0x7533	0x91AD	# <CJK>
0x7534	0x91AE	# <CJK>
0x7535	0x91AF	# <CJK>
0x7536	0x91B5	# <CJK>
0x7537	0x91B4	# <CJK>
0x7538	0x91BA	# <CJK>
0x7539	0x8C55	# <CJK>
0x753A	0x9E7E	# <CJK>
0x753B	0x8DB8	# <CJK>
0x753C	0x8DEB	# <CJK>
0x753D	0x8E05	# <CJK>
0x753E	0x8E59	# <CJK>
0x753F	0x8E69	# <CJK>
0x7540	0x8DB5	# <CJK>
0x7541	0x8DBF	# <CJK>
0x7542	0x8DBC	# <CJK>
0x7543	0x8DBA	# <CJK>
0x7544	0x8DC4	# <CJK>
0x7545	0x8DD6	# <CJK>
0x7546	0x8DD7	# <CJK>
0x7547	0x8DDA	# <CJK>
0x7548	0x8DDE	# <CJK>
0x7549	0x8DCE	# <CJK>
0x754A	0x8DCF	# <CJK>
0x754B	0x8DDB	# <CJK>
0x754C	0x8DC6	# <CJK>
0x754D	0x8DEC	# <CJK>
0x754E	0x8DF7	# <CJK>
0x754F	0x8DF8	# <CJK>
0x7550	0x8DE3	# <CJK>
0x7551	0x8DF9	# <CJK>
0x7552	0x8DFB	# <CJK>
0x7553	0x8DE4	# <CJK>
0x7554	0x8E09	# <CJK>
0x7555	0x8DFD	# <CJK>
0x7556	0x8E14	# <CJK>
0x7557	0x8E1D	# <CJK>
0x7558	0x8E1F	# <CJK>
0x7559	0x8E2C	# <CJK>
0x755A	0x8E2E	# <CJK>
0x755B	0x8E23	# <CJK>
0x755C	0x8E2F	# <CJK>
0x755D	0x8E3A	# <CJK>
0x755E	0x8E40	# <CJK>
0x755F	0x8E39	# <CJK>
0x7560	0x8E35	# <CJK>
0x7561	0x8E3D	# <CJK>
0x7562	0x8E31	# <CJK>
0x7563	0x8E49	# <CJK>
0x7564	0x8E41	# <CJK>
0x7565	0x8E42	# <CJK>
0x7566	0x8E51	# <CJK>
0x7567	0x8E52	# <CJK>
0x7568	0x8E4A	# <CJK>
0x7569	0x8E70	# <CJK>
0x756A	0x8E76	# <CJK>
0x756B	0x8E7C	# <CJK>
0x756C	0x8E6F	# <CJK>
0x756D	0x8E74	# <CJK>
0x756E	0x8E85	# <CJK>
0x756F	0x8E8F	# <CJK>
0x7570	0x8E94	# <CJK>
0x7571	0x8E90	# <CJK>
0x7572	0x8E9C	# <CJK>
0x7573	0x8E9E	# <CJK>
0x7574	0x8C78	# <CJK>
0x7575	0x8C82	# <CJK>
0x7576	0x8C8A	# <CJK>
0x7577	0x8C85	# <CJK>
0x7578	0x8C98	# <CJK>
0x7579	0x8C94	# <CJK>
0x757A	0x659B	# <CJK>
0x757B	0x89D6	# <CJK>
0x757C	0x89DE	# <CJK>
0x757D	0x89DA	# <CJK>
0x757E	0x89DC	# <CJK>
0x7621	0x89E5	# <CJK>
0x7622	0x89EB	# <CJK>
0x7623	0x89EF	# <CJK>
0x7624	0x8A3E	# <CJK>
0x7625	0x8B26	# <CJK>
0x7626	0x9753	# <CJK>
0x7627	0x96E9	# <CJK>
0x7628	0x96F3	# <CJK>
0x7629	0x96EF	# <CJK>
0x762A	0x9706	# <CJK>
0x762B	0x9701	# <CJK>
0x762C	0x9708	# <CJK>
0x762D	0x970F	# <CJK>
0x762E	0x970E	# <CJK>
0x762F	0x972A	# <CJK>
0x7630	0x972D	# <CJK>
0x7631	0x9730	# <CJK>
0x7632	0x973E	# <CJK>
0x7633	0x9F80	# <CJK>
0x7634	0x9F83	# <CJK>
0x7635	0x9F85	# <CJK>
0x7636	0x9F86	# <CJK>
0x7637	0x9F87	# <CJK>
0x7638	0x9F88	# <CJK>
0x7639	0x9F89	# <CJK>
0x763A	0x9F8A	# <CJK>
0x763B	0x9F8C	# <CJK>
0x763C	0x9EFE	# <CJK>
0x763D	0x9F0B	# <CJK>
0x763E	0x9F0D	# <CJK>
0x763F	0x96B9	# <CJK>
0x7640	0x96BC	# <CJK>
0x7641	0x96BD	# <CJK>
0x7642	0x96CE	# <CJK>
0x7643	0x96D2	# <CJK>
0x7644	0x77BF	# <CJK>
0x7645	0x96E0	# <CJK>
0x7646	0x928E	# <CJK>
0x7647	0x92AE	# <CJK>
0x7648	0x92C8	# <CJK>
0x7649	0x933E	# <CJK>
0x764A	0x936A	# <CJK>
0x764B	0x93CA	# <CJK>
0x764C	0x938F	# <CJK>
0x764D	0x943E	# <CJK>
0x764E	0x946B	# <CJK>
0x764F	0x9C7F	# <CJK>
0x7650	0x9C82	# <CJK>
0x7651	0x9C85	# <CJK>
0x7652	0x9C86	# <CJK>
0x7653	0x9C87	# <CJK>
0x7654	0x9C88	# <CJK>
0x7655	0x7A23	# <CJK>
0x7656	0x9C8B	# <CJK>
0x7657	0x9C8E	# <CJK>
0x7658	0x9C90	# <CJK>
0x7659	0x9C91	# <CJK>
0x765A	0x9C92	# <CJK>
0x765B	0x9C94	# <CJK>
0x765C	0x9C95	# <CJK>
0x765D	0x9C9A	# <CJK>
0x765E	0x9C9B	# <CJK>
0x765F	0x9C9E	# <CJK>
0x7660	0x9C9F	# <CJK>
0x7661	0x9CA0	# <CJK>
0x7662	0x9CA1	# <CJK>
0x7663	0x9CA2	# <CJK>
0x7664	0x9CA3	# <CJK>
0x7665	0x9CA5	# <CJK>
0x7666	0x9CA6	# <CJK>
0x7667	0x9CA7	# <CJK>
0x7668	0x9CA8	# <CJK>
0x7669	0x9CA9	# <CJK>
0x766A	0x9CAB	# <CJK>
0x766B	0x9CAD	# <CJK>
0x766C	0x9CAE	# <CJK>
0x766D	0x9CB0	# <CJK>
0x766E	0x9CB1	# <CJK>
0x766F	0x9CB2	# <CJK>
0x7670	0x9CB3	# <CJK>
0x7671	0x9CB4	# <CJK>
0x7672	0x9CB5	# <CJK>
0x7673	0x9CB6	# <CJK>
0x7674	0x9CB7	# <CJK>
0x7675	0x9CBA	# <CJK>
0x7676	0x9CBB	# <CJK>
0x7677	0x9CBC	# <CJK>
0x7678	0x9CBD	# <CJK>
0x7679	0x9CC4	# <CJK>
0x767A	0x9CC5	# <CJK>
0x767B	0x9CC6	# <CJK>
0x767C	0x9CC7	# <CJK>
0x767D	0x9CCA	# <CJK>
0x767E	0x9CCB	# <CJK>
0x7721	0x9CCC	# <CJK>
0x7722	0x9CCD	# <CJK>
0x7723	0x9CCE	# <CJK>
0x7724	0x9CCF	# <CJK>
0x7725	0x9CD0	# <CJK>
0x7726	0x9CD3	# <CJK>
0x7727	0x9CD4	# <CJK>
0x7728	0x9CD5	# <CJK>
0x7729	0x9CD7	# <CJK>
0x772A	0x9CD8	# <CJK>
0x772B	0x9CD9	# <CJK>
0x772C	0x9CDC	# <CJK>
0x772D	0x9CDD	# <CJK>
0x772E	0x9CDF	# <CJK>
0x772F	0x9CE2	# <CJK>
0x7730	0x977C	# <CJK>
0x7731	0x9785	# <CJK>
0x7732	0x9791	# <CJK>
0x7733	0x9792	# <CJK>
0x7734	0x9794	# <CJK>
0x7735	0x97AF	# <CJK>
0x7736	0x97AB	# <CJK>
0x7737	0x97A3	# <CJK>
0x7738	0x97B2	# <CJK>
0x7739	0x97B4	# <CJK>
0x773A	0x9AB1	# <CJK>
0x773B	0x9AB0	# <CJK>
0x773C	0x9AB7	# <CJK>
0x773D	0x9E58	# <CJK>
0x773E	0x9AB6	# <CJK>
0x773F	0x9ABA	# <CJK>
0x7740	0x9ABC	# <CJK>
0x7741	0x9AC1	# <CJK>
0x7742	0x9AC0	# <CJK>
0x7743	0x9AC5	# <CJK>
0x7744	0x9AC2	# <CJK>
0x7745	0x9ACB	# <CJK>
0x7746	0x9ACC	# <CJK>
0x7747	0x9AD1	# <CJK>
0x7748	0x9B45	# <CJK>
0x7749	0x9B43	# <CJK>
0x774A	0x9B47	# <CJK>
0x774B	0x9B49	# <CJK>
0x774C	0x9B48	# <CJK>
0x774D	0x9B4D	# <CJK>
0x774E	0x9B51	# <CJK>
0x774F	0x98E8	# <CJK>
0x7750	0x990D	# <CJK>
0x7751	0x992E	# <CJK>
0x7752	0x9955	# <CJK>
0x7753	0x9954	# <CJK>
0x7754	0x9ADF	# <CJK>
0x7755	0x9AE1	# <CJK>
0x7756	0x9AE6	# <CJK>
0x7757	0x9AEF	# <CJK>
0x7758	0x9AEB	# <CJK>
0x7759	0x9AFB	# <CJK>
0x775A	0x9AED	# <CJK>
0x775B	0x9AF9	# <CJK>
0x775C	0x9B08	# <CJK>
0x775D	0x9B0F	# <CJK>
0x775E	0x9B13	# <CJK>
0x775F	0x9B1F	# <CJK>
0x7760	0x9B23	# <CJK>
0x7761	0x9EBD	# <CJK>
0x7762	0x9EBE	# <CJK>
0x7763	0x7E3B	# <CJK>
0x7764	0x9E82	# <CJK>
0x7765	0x9E87	# <CJK>
0x7766	0x9E88	# <CJK>
0x7767	0x9E8B	# <CJK>
0x7768	0x9E92	# <CJK>
0x7769	0x93D6	# <CJK>
0x776A	0x9E9D	# <CJK>
0x776B	0x9E9F	# <CJK>
0x776C	0x9EDB	# <CJK>
0x776D	0x9EDC	# <CJK>
0x776E	0x9EDD	# <CJK>
0x776F	0x9EE0	# <CJK>
0x7770	0x9EDF	# <CJK>
0x7771	0x9EE2	# <CJK>
0x7772	0x9EE9	# <CJK>
0x7773	0x9EE7	# <CJK>
0x7774	0x9EE5	# <CJK>
0x7775	0x9EEA	# <CJK>
0x7776	0x9EEF	# <CJK>
0x7777	0x9F22	# <CJK>
0x7778	0x9F2C	# <CJK>
0x7779	0x9F2F	# <CJK>
0x777A	0x9F39	# <CJK>
0x777B	0x9F37	# <CJK>
0x777C	0x9F3D	# <CJK>
0x777D	0x9F3E	# <CJK>
0x777E	0x9F44	# <CJK>

Added tools/encoding/iso2022-jp.esc.





















>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
name		iso2022-jp
init		{}
final		{}
iso8859-1	\x1b(B
jis0201		\x1b(J
jis0208		\x1b$@
jis0208		\x1b$B
jis0212		\x1b$(D
gb2312		\x1b$A
ksc5601		\x1b$(C

Added tools/encoding/iso2022-kr.esc.











>
>
>
>
>
1
2
3
4
5
name		iso2022-kr
init		\x1b$)C
final		{}
iso8859-1	\x0f
ksc5601		\x0e

Added tools/encoding/iso2022.esc.





























>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
name		iso2022
init		{}
final		{}
iso8859-1	\x1b(B
jis0201		\x1b(J
gb1988		\x1b(T
jis0208		\x1b$@
jis0208		\x1b$B
jis0212		\x1b$(D
gb2312		\x1b$A
ksc5601		\x1b$(C
jis0208		\x1b&@\x1b$B


Added tools/encoding/iso8859-1.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
#
#	Name:             ISO 8859-1 (1987) to Unicode
#	Unicode version:  1.1
#	Table version:    0.1
#	Table format:     Format A
#	Date:             16 January 1995
#	Authors:          Tim Greenwood <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1995 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       ISO 8859-1 (1987) characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the ISO 8859-1 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 ISO 8859-1 order
#
#	Any comments or problems, contact <[email protected]>
#
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
0xA0	0x00A0	#	NO-BREAK SPACE
0xA1	0x00A1	#	INVERTED EXCLAMATION MARK
0xA2	0x00A2	#	CENT SIGN
0xA3	0x00A3	#	POUND SIGN
0xA4	0x00A4	#	CURRENCY SIGN
0xA5	0x00A5	#	YEN SIGN
0xA6	0x00A6	#	BROKEN BAR
0xA7	0x00A7	#	SECTION SIGN
0xA8	0x00A8	#	DIAERESIS
0xA9	0x00A9	#	COPYRIGHT SIGN
0xAA	0x00AA	#	FEMININE ORDINAL INDICATOR
0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xAC	0x00AC	#	NOT SIGN
0xAD	0x00AD	#	SOFT HYPHEN
0xAE	0x00AE	#	REGISTERED SIGN
0xAF	0x00AF	#	MACRON
0xB0	0x00B0	#	DEGREE SIGN
0xB1	0x00B1	#	PLUS-MINUS SIGN
0xB2	0x00B2	#	SUPERSCRIPT TWO
0xB3	0x00B3	#	SUPERSCRIPT THREE
0xB4	0x00B4	#	ACUTE ACCENT
0xB5	0x00B5	#	MICRO SIGN
0xB6	0x00B6	#	PILCROW SIGN
0xB7	0x00B7	#	MIDDLE DOT
0xB8	0x00B8	#	CEDILLA
0xB9	0x00B9	#	SUPERSCRIPT ONE
0xBA	0x00BA	#	MASCULINE ORDINAL INDICATOR
0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xBC	0x00BC	#	VULGAR FRACTION ONE QUARTER
0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
0xBE	0x00BE	#	VULGAR FRACTION THREE QUARTERS
0xBF	0x00BF	#	INVERTED QUESTION MARK
0xC0	0x00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xC3	0x00C3	#	LATIN CAPITAL LETTER A WITH TILDE
0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
0xC5	0x00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
0xC6	0x00C6	#	LATIN CAPITAL LETTER AE
0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
0xC8	0x00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
0xCA	0x00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
0xCC	0x00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
0xD0	0x00D0	#	LATIN CAPITAL LETTER ETH (Icelandic)
0xD1	0x00D1	#	LATIN CAPITAL LETTER N WITH TILDE
0xD2	0x00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xD5	0x00D5	#	LATIN CAPITAL LETTER O WITH TILDE
0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
0xD7	0x00D7	#	MULTIPLICATION SIGN
0xD8	0x00D8	#	LATIN CAPITAL LETTER O WITH STROKE
0xD9	0x00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
0xDD	0x00DD	#	LATIN CAPITAL LETTER Y WITH ACUTE
0xDE	0x00DE	#	LATIN CAPITAL LETTER THORN (Icelandic)
0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S (German)
0xE0	0x00E0	#	LATIN SMALL LETTER A WITH GRAVE
0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
0xE3	0x00E3	#	LATIN SMALL LETTER A WITH TILDE
0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
0xE5	0x00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
0xE6	0x00E6	#	LATIN SMALL LETTER AE
0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
0xE8	0x00E8	#	LATIN SMALL LETTER E WITH GRAVE
0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
0xEA	0x00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
0xEC	0x00EC	#	LATIN SMALL LETTER I WITH GRAVE
0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
0xF0	0x00F0	#	LATIN SMALL LETTER ETH (Icelandic)
0xF1	0x00F1	#	LATIN SMALL LETTER N WITH TILDE
0xF2	0x00F2	#	LATIN SMALL LETTER O WITH GRAVE
0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
0xF5	0x00F5	#	LATIN SMALL LETTER O WITH TILDE
0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
0xF7	0x00F7	#	DIVISION SIGN
0xF8	0x00F8	#	LATIN SMALL LETTER O WITH STROKE
0xF9	0x00F9	#	LATIN SMALL LETTER U WITH GRAVE
0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
0xFD	0x00FD	#	LATIN SMALL LETTER Y WITH ACUTE
0xFE	0x00FE	#	LATIN SMALL LETTER THORN (Icelandic)
0xFF	0x00FF	#	LATIN SMALL LETTER Y WITH DIAERESIS

Added tools/encoding/iso8859-2.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
#
#	Name:             ISO 8859-2 (1987) to Unicode
#	Unicode version:  1.1
#	Table version:    0.1
#	Table format:     Format A
#	Date:             16 January 1995
#	Authors:          Tim Greenwood <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1995 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       ISO 8859-2 (1987) characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the ISO 8859-2 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 ISO 8859-2 order
#
#	Any comments or problems, contact <[email protected]>
#
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
0xA0	0x00A0	#	NO-BREAK SPACE
0xA1	0x0104	#	LATIN CAPITAL LETTER A WITH OGONEK
0xA2	0x02D8	#	BREVE
0xA3	0x0141	#	LATIN CAPITAL LETTER L WITH STROKE
0xA4	0x00A4	#	CURRENCY SIGN
0xA5	0x013D	#	LATIN CAPITAL LETTER L WITH CARON
0xA6	0x015A	#	LATIN CAPITAL LETTER S WITH ACUTE
0xA7	0x00A7	#	SECTION SIGN
0xA8	0x00A8	#	DIAERESIS
0xA9	0x0160	#	LATIN CAPITAL LETTER S WITH CARON
0xAA	0x015E	#	LATIN CAPITAL LETTER S WITH CEDILLA
0xAB	0x0164	#	LATIN CAPITAL LETTER T WITH CARON
0xAC	0x0179	#	LATIN CAPITAL LETTER Z WITH ACUTE
0xAD	0x00AD	#	SOFT HYPHEN
0xAE	0x017D	#	LATIN CAPITAL LETTER Z WITH CARON
0xAF	0x017B	#	LATIN CAPITAL LETTER Z WITH DOT ABOVE
0xB0	0x00B0	#	DEGREE SIGN
0xB1	0x0105	#	LATIN SMALL LETTER A WITH OGONEK
0xB2	0x02DB	#	OGONEK
0xB3	0x0142	#	LATIN SMALL LETTER L WITH STROKE
0xB4	0x00B4	#	ACUTE ACCENT
0xB5	0x013E	#	LATIN SMALL LETTER L WITH CARON
0xB6	0x015B	#	LATIN SMALL LETTER S WITH ACUTE
0xB7	0x02C7	#	CARON
0xB8	0x00B8	#	CEDILLA
0xB9	0x0161	#	LATIN SMALL LETTER S WITH CARON
0xBA	0x015F	#	LATIN SMALL LETTER S WITH CEDILLA
0xBB	0x0165	#	LATIN SMALL LETTER T WITH CARON
0xBC	0x017A	#	LATIN SMALL LETTER Z WITH ACUTE
0xBD	0x02DD	#	DOUBLE ACUTE ACCENT
0xBE	0x017E	#	LATIN SMALL LETTER Z WITH CARON
0xBF	0x017C	#	LATIN SMALL LETTER Z WITH DOT ABOVE
0xC0	0x0154	#	LATIN CAPITAL LETTER R WITH ACUTE
0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xC3	0x0102	#	LATIN CAPITAL LETTER A WITH BREVE
0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
0xC5	0x0139	#	LATIN CAPITAL LETTER L WITH ACUTE
0xC6	0x0106	#	LATIN CAPITAL LETTER C WITH ACUTE
0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
0xC8	0x010C	#	LATIN CAPITAL LETTER C WITH CARON
0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
0xCA	0x0118	#	LATIN CAPITAL LETTER E WITH OGONEK
0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
0xCC	0x011A	#	LATIN CAPITAL LETTER E WITH CARON
0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xCF	0x010E	#	LATIN CAPITAL LETTER D WITH CARON
0xD0	0x0110	#	LATIN CAPITAL LETTER D WITH STROKE
0xD1	0x0143	#	LATIN CAPITAL LETTER N WITH ACUTE
0xD2	0x0147	#	LATIN CAPITAL LETTER N WITH CARON
0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xD5	0x0150	#	LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
0xD7	0x00D7	#	MULTIPLICATION SIGN
0xD8	0x0158	#	LATIN CAPITAL LETTER R WITH CARON
0xD9	0x016E	#	LATIN CAPITAL LETTER U WITH RING ABOVE
0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
0xDB	0x0170	#	LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
0xDD	0x00DD	#	LATIN CAPITAL LETTER Y WITH ACUTE
0xDE	0x0162	#	LATIN CAPITAL LETTER T WITH CEDILLA
0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
0xE0	0x0155	#	LATIN SMALL LETTER R WITH ACUTE
0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
0xE3	0x0103	#	LATIN SMALL LETTER A WITH BREVE
0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
0xE5	0x013A	#	LATIN SMALL LETTER L WITH ACUTE
0xE6	0x0107	#	LATIN SMALL LETTER C WITH ACUTE
0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
0xE8	0x010D	#	LATIN SMALL LETTER C WITH CARON
0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
0xEA	0x0119	#	LATIN SMALL LETTER E WITH OGONEK
0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
0xEC	0x011B	#	LATIN SMALL LETTER E WITH CARON
0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
0xEF	0x010F	#	LATIN SMALL LETTER D WITH CARON
0xF0	0x0111	#	LATIN SMALL LETTER D WITH STROKE
0xF1	0x0144	#	LATIN SMALL LETTER N WITH ACUTE
0xF2	0x0148	#	LATIN SMALL LETTER N WITH CARON
0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
0xF5	0x0151	#	LATIN SMALL LETTER O WITH DOUBLE ACUTE
0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
0xF7	0x00F7	#	DIVISION SIGN
0xF8	0x0159	#	LATIN SMALL LETTER R WITH CARON
0xF9	0x016F	#	LATIN SMALL LETTER U WITH RING ABOVE
0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
0xFB	0x0171	#	LATIN SMALL LETTER U WITH DOUBLE ACUTE
0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
0xFD	0x00FD	#	LATIN SMALL LETTER Y WITH ACUTE
0xFE	0x0163	#	LATIN SMALL LETTER T WITH CEDILLA
0xFF	0x02D9	#	DOT ABOVE

Added tools/encoding/iso8859-3.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
#
#	Name:             ISO 8859-3 (1988) to Unicode
#	Unicode version:  1.1
#	Table version:    0.1
#	Table format:     Format A
#	Date:             16 January 1995
#	Authors:          Tim Greenwood <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1995 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       ISO 8859-3 (1988) characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the ISO 8859-3 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 ISO 8859-3 order
#
#	Any comments or problems, contact <[email protected]>
#
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
0xA0	0x00A0	#	NO-BREAK SPACE
0xA1	0x0126	#	LATIN CAPITAL LETTER H WITH STROKE
0xA2	0x02D8	#	BREVE
0xA3	0x00A3	#	POUND SIGN
0xA4	0x00A4	#	CURRENCY SIGN
0xA6	0x0124	#	LATIN CAPITAL LETTER H WITH CIRCUMFLEX
0xA7	0x00A7	#	SECTION SIGN
0xA8	0x00A8	#	DIAERESIS
0xA9	0x0130	#	LATIN CAPITAL LETTER I WITH DOT ABOVE
0xAA	0x015E	#	LATIN CAPITAL LETTER S WITH CEDILLA
0xAB	0x011E	#	LATIN CAPITAL LETTER G WITH BREVE
0xAC	0x0134	#	LATIN CAPITAL LETTER J WITH CIRCUMFLEX
0xAD	0x00AD	#	SOFT HYPHEN
0xAF	0x017B	#	LATIN CAPITAL LETTER Z WITH DOT ABOVE
0xB0	0x00B0	#	DEGREE SIGN
0xB1	0x0127	#	LATIN SMALL LETTER H WITH STROKE
0xB2	0x00B2	#	SUPERSCRIPT TWO
0xB3	0x00B3	#	SUPERSCRIPT THREE
0xB4	0x00B4	#	ACUTE ACCENT
0xB5	0x00B5	#	MICRO SIGN
0xB6	0x0125	#	LATIN SMALL LETTER H WITH CIRCUMFLEX
0xB7	0x00B7	#	MIDDLE DOT
0xB8	0x00B8	#	CEDILLA
0xB9	0x0131	#	LATIN SMALL LETTER DOTLESS I
0xBA	0x015F	#	LATIN SMALL LETTER S WITH CEDILLA
0xBB	0x011F	#	LATIN SMALL LETTER G WITH BREVE
0xBC	0x0135	#	LATIN SMALL LETTER J WITH CIRCUMFLEX
0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
0xBF	0x017C	#	LATIN SMALL LETTER Z WITH DOT ABOVE
0xC0	0x00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
0xC5	0x010A	#	LATIN CAPITAL LETTER C WITH DOT ABOVE
0xC6	0x0108	#	LATIN CAPITAL LETTER C WITH CIRCUMFLEX
0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
0xC8	0x00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
0xCA	0x00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
0xCC	0x00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
0xD1	0x00D1	#	LATIN CAPITAL LETTER N WITH TILDE
0xD2	0x00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xD5	0x0120	#	LATIN CAPITAL LETTER G WITH DOT ABOVE
0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
0xD7	0x00D7	#	MULTIPLICATION SIGN
0xD8	0x011C	#	LATIN CAPITAL LETTER G WITH CIRCUMFLEX
0xD9	0x00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
0xDD	0x016C	#	LATIN CAPITAL LETTER U WITH BREVE
0xDE	0x015C	#	LATIN CAPITAL LETTER S WITH CIRCUMFLEX
0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
0xE0	0x00E0	#	LATIN SMALL LETTER A WITH GRAVE
0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
0xE5	0x010B	#	LATIN SMALL LETTER C WITH DOT ABOVE
0xE6	0x0109	#	LATIN SMALL LETTER C WITH CIRCUMFLEX
0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
0xE8	0x00E8	#	LATIN SMALL LETTER E WITH GRAVE
0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
0xEA	0x00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
0xEC	0x00EC	#	LATIN SMALL LETTER I WITH GRAVE
0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
0xF1	0x00F1	#	LATIN SMALL LETTER N WITH TILDE
0xF2	0x00F2	#	LATIN SMALL LETTER O WITH GRAVE
0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
0xF5	0x0121	#	LATIN SMALL LETTER G WITH DOT ABOVE
0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
0xF7	0x00F7	#	DIVISION SIGN
0xF8	0x011D	#	LATIN SMALL LETTER G WITH CIRCUMFLEX
0xF9	0x00F9	#	LATIN SMALL LETTER U WITH GRAVE
0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
0xFD	0x016D	#	LATIN SMALL LETTER U WITH BREVE
0xFE	0x015D	#	LATIN SMALL LETTER S WITH CIRCUMFLEX
0xFF	0x02D9	#	DOT ABOVE

Added tools/encoding/iso8859-4.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
#
#	Name:             ISO 8859-4 (1988) to Unicode
#	Unicode version:  1.1
#	Table version:    0.1
#	Table format:     Format A
#	Date:             16 January 1995
#	Authors:          Tim Greenwood <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1995 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       ISO 8859-4 (1988) characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the ISO 8859-4 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 ISO 8859-4 order
#
#	Any comments or problems, contact <[email protected]>
#
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
0xA0	0x00A0	#	NO-BREAK SPACE
0xA1	0x0104	#	LATIN CAPITAL LETTER A WITH OGONEK
0xA2	0x0138	#	LATIN SMALL LETTER KRA
0xA3	0x0156	#	LATIN CAPITAL LETTER R WITH CEDILLA
0xA4	0x00A4	#	CURRENCY SIGN
0xA5	0x0128	#	LATIN CAPITAL LETTER I WITH TILDE
0xA6	0x013B	#	LATIN CAPITAL LETTER L WITH CEDILLA
0xA7	0x00A7	#	SECTION SIGN
0xA8	0x00A8	#	DIAERESIS
0xA9	0x0160	#	LATIN CAPITAL LETTER S WITH CARON
0xAA	0x0112	#	LATIN CAPITAL LETTER E WITH MACRON
0xAB	0x0122	#	LATIN CAPITAL LETTER G WITH CEDILLA
0xAC	0x0166	#	LATIN CAPITAL LETTER T WITH STROKE
0xAD	0x00AD	#	SOFT HYPHEN
0xAE	0x017D	#	LATIN CAPITAL LETTER Z WITH CARON
0xAF	0x00AF	#	MACRON
0xB0	0x00B0	#	DEGREE SIGN
0xB1	0x0105	#	LATIN SMALL LETTER A WITH OGONEK
0xB2	0x02DB	#	OGONEK
0xB3	0x0157	#	LATIN SMALL LETTER R WITH CEDILLA
0xB4	0x00B4	#	ACUTE ACCENT
0xB5	0x0129	#	LATIN SMALL LETTER I WITH TILDE
0xB6	0x013C	#	LATIN SMALL LETTER L WITH CEDILLA
0xB7	0x02C7	#	CARON
0xB8	0x00B8	#	CEDILLA
0xB9	0x0161	#	LATIN SMALL LETTER S WITH CARON
0xBA	0x0113	#	LATIN SMALL LETTER E WITH MACRON
0xBB	0x0123	#	LATIN SMALL LETTER G WITH CEDILLA
0xBC	0x0167	#	LATIN SMALL LETTER T WITH STROKE
0xBD	0x014A	#	LATIN CAPITAL LETTER ENG
0xBE	0x017E	#	LATIN SMALL LETTER Z WITH CARON
0xBF	0x014B	#	LATIN SMALL LETTER ENG
0xC0	0x0100	#	LATIN CAPITAL LETTER A WITH MACRON
0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xC3	0x00C3	#	LATIN CAPITAL LETTER A WITH TILDE
0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
0xC5	0x00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
0xC6	0x00C6	#	LATIN CAPITAL LETTER AE
0xC7	0x012E	#	LATIN CAPITAL LETTER I WITH OGONEK
0xC8	0x010C	#	LATIN CAPITAL LETTER C WITH CARON
0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
0xCA	0x0118	#	LATIN CAPITAL LETTER E WITH OGONEK
0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
0xCC	0x0116	#	LATIN CAPITAL LETTER E WITH DOT ABOVE
0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xCF	0x012A	#	LATIN CAPITAL LETTER I WITH MACRON
0xD0	0x0110	#	LATIN CAPITAL LETTER D WITH STROKE
0xD1	0x0145	#	LATIN CAPITAL LETTER N WITH CEDILLA
0xD2	0x014C	#	LATIN CAPITAL LETTER O WITH MACRON
0xD3	0x0136	#	LATIN CAPITAL LETTER K WITH CEDILLA
0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xD5	0x00D5	#	LATIN CAPITAL LETTER O WITH TILDE
0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
0xD7	0x00D7	#	MULTIPLICATION SIGN
0xD8	0x00D8	#	LATIN CAPITAL LETTER O WITH STROKE
0xD9	0x0172	#	LATIN CAPITAL LETTER U WITH OGONEK
0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
0xDD	0x0168	#	LATIN CAPITAL LETTER U WITH TILDE
0xDE	0x016A	#	LATIN CAPITAL LETTER U WITH MACRON
0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
0xE0	0x0101	#	LATIN SMALL LETTER A WITH MACRON
0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
0xE3	0x00E3	#	LATIN SMALL LETTER A WITH TILDE
0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
0xE5	0x00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
0xE6	0x00E6	#	LATIN SMALL LETTER AE
0xE7	0x012F	#	LATIN SMALL LETTER I WITH OGONEK
0xE8	0x010D	#	LATIN SMALL LETTER C WITH CARON
0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
0xEA	0x0119	#	LATIN SMALL LETTER E WITH OGONEK
0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
0xEC	0x0117	#	LATIN SMALL LETTER E WITH DOT ABOVE
0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
0xEF	0x012B	#	LATIN SMALL LETTER I WITH MACRON
0xF0	0x0111	#	LATIN SMALL LETTER D WITH STROKE
0xF1	0x0146	#	LATIN SMALL LETTER N WITH CEDILLA
0xF2	0x014D	#	LATIN SMALL LETTER O WITH MACRON
0xF3	0x0137	#	LATIN SMALL LETTER K WITH CEDILLA
0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
0xF5	0x00F5	#	LATIN SMALL LETTER O WITH TILDE
0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
0xF7	0x00F7	#	DIVISION SIGN
0xF8	0x00F8	#	LATIN SMALL LETTER O WITH STROKE
0xF9	0x0173	#	LATIN SMALL LETTER U WITH OGONEK
0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
0xFD	0x0169	#	LATIN SMALL LETTER U WITH TILDE
0xFE	0x016B	#	LATIN SMALL LETTER U WITH MACRON
0xFF	0x02D9	#	DOT ABOVE

Added tools/encoding/iso8859-5.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
#
#	Name:             ISO 8859-5 (1988) to Unicode
#	Unicode version:  1.1
#	Table version:    0.1
#	Table format:     Format A
#	Date:             16 January 1995
#	Authors:          Tim Greenwood <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1995 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       ISO 8859-5 (1988) characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the ISO 8859-5 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 ISO 8859-5 order
#
#	Any comments or problems, contact <[email protected]>
#
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
0xA0	0x00A0	#	NO-BREAK SPACE
0xA1	0x0401	#	CYRILLIC CAPITAL LETTER IO
0xA2	0x0402	#	CYRILLIC CAPITAL LETTER DJE
0xA3	0x0403	#	CYRILLIC CAPITAL LETTER GJE
0xA4	0x0404	#	CYRILLIC CAPITAL LETTER UKRAINIAN IE
0xA5	0x0405	#	CYRILLIC CAPITAL LETTER DZE
0xA6	0x0406	#	CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
0xA7	0x0407	#	CYRILLIC CAPITAL LETTER YI
0xA8	0x0408	#	CYRILLIC CAPITAL LETTER JE
0xA9	0x0409	#	CYRILLIC CAPITAL LETTER LJE
0xAA	0x040A	#	CYRILLIC CAPITAL LETTER NJE
0xAB	0x040B	#	CYRILLIC CAPITAL LETTER TSHE
0xAC	0x040C	#	CYRILLIC CAPITAL LETTER KJE
0xAD	0x00AD	#	SOFT HYPHEN
0xAE	0x040E	#	CYRILLIC CAPITAL LETTER SHORT U
0xAF	0x040F	#	CYRILLIC CAPITAL LETTER DZHE
0xB0	0x0410	#	CYRILLIC CAPITAL LETTER A
0xB1	0x0411	#	CYRILLIC CAPITAL LETTER BE
0xB2	0x0412	#	CYRILLIC CAPITAL LETTER VE
0xB3	0x0413	#	CYRILLIC CAPITAL LETTER GHE
0xB4	0x0414	#	CYRILLIC CAPITAL LETTER DE
0xB5	0x0415	#	CYRILLIC CAPITAL LETTER IE
0xB6	0x0416	#	CYRILLIC CAPITAL LETTER ZHE
0xB7	0x0417	#	CYRILLIC CAPITAL LETTER ZE
0xB8	0x0418	#	CYRILLIC CAPITAL LETTER I
0xB9	0x0419	#	CYRILLIC CAPITAL LETTER SHORT I
0xBA	0x041A	#	CYRILLIC CAPITAL LETTER KA
0xBB	0x041B	#	CYRILLIC CAPITAL LETTER EL
0xBC	0x041C	#	CYRILLIC CAPITAL LETTER EM
0xBD	0x041D	#	CYRILLIC CAPITAL LETTER EN
0xBE	0x041E	#	CYRILLIC CAPITAL LETTER O
0xBF	0x041F	#	CYRILLIC CAPITAL LETTER PE
0xC0	0x0420	#	CYRILLIC CAPITAL LETTER ER
0xC1	0x0421	#	CYRILLIC CAPITAL LETTER ES
0xC2	0x0422	#	CYRILLIC CAPITAL LETTER TE
0xC3	0x0423	#	CYRILLIC CAPITAL LETTER U
0xC4	0x0424	#	CYRILLIC CAPITAL LETTER EF
0xC5	0x0425	#	CYRILLIC CAPITAL LETTER HA
0xC6	0x0426	#	CYRILLIC CAPITAL LETTER TSE
0xC7	0x0427	#	CYRILLIC CAPITAL LETTER CHE
0xC8	0x0428	#	CYRILLIC CAPITAL LETTER SHA
0xC9	0x0429	#	CYRILLIC CAPITAL LETTER SHCHA
0xCA	0x042A	#	CYRILLIC CAPITAL LETTER HARD SIGN
0xCB	0x042B	#	CYRILLIC CAPITAL LETTER YERU
0xCC	0x042C	#	CYRILLIC CAPITAL LETTER SOFT SIGN
0xCD	0x042D	#	CYRILLIC CAPITAL LETTER E
0xCE	0x042E	#	CYRILLIC CAPITAL LETTER YU
0xCF	0x042F	#	CYRILLIC CAPITAL LETTER YA
0xD0	0x0430	#	CYRILLIC SMALL LETTER A
0xD1	0x0431	#	CYRILLIC SMALL LETTER BE
0xD2	0x0432	#	CYRILLIC SMALL LETTER VE
0xD3	0x0433	#	CYRILLIC SMALL LETTER GHE
0xD4	0x0434	#	CYRILLIC SMALL LETTER DE
0xD5	0x0435	#	CYRILLIC SMALL LETTER IE
0xD6	0x0436	#	CYRILLIC SMALL LETTER ZHE
0xD7	0x0437	#	CYRILLIC SMALL LETTER ZE
0xD8	0x0438	#	CYRILLIC SMALL LETTER I
0xD9	0x0439	#	CYRILLIC SMALL LETTER SHORT I
0xDA	0x043A	#	CYRILLIC SMALL LETTER KA
0xDB	0x043B	#	CYRILLIC SMALL LETTER EL
0xDC	0x043C	#	CYRILLIC SMALL LETTER EM
0xDD	0x043D	#	CYRILLIC SMALL LETTER EN
0xDE	0x043E	#	CYRILLIC SMALL LETTER O
0xDF	0x043F	#	CYRILLIC SMALL LETTER PE
0xE0	0x0440	#	CYRILLIC SMALL LETTER ER
0xE1	0x0441	#	CYRILLIC SMALL LETTER ES
0xE2	0x0442	#	CYRILLIC SMALL LETTER TE
0xE3	0x0443	#	CYRILLIC SMALL LETTER U
0xE4	0x0444	#	CYRILLIC SMALL LETTER EF
0xE5	0x0445	#	CYRILLIC SMALL LETTER HA
0xE6	0x0446	#	CYRILLIC SMALL LETTER TSE
0xE7	0x0447	#	CYRILLIC SMALL LETTER CHE
0xE8	0x0448	#	CYRILLIC SMALL LETTER SHA
0xE9	0x0449	#	CYRILLIC SMALL LETTER SHCHA
0xEA	0x044A	#	CYRILLIC SMALL LETTER HARD SIGN
0xEB	0x044B	#	CYRILLIC SMALL LETTER YERU
0xEC	0x044C	#	CYRILLIC SMALL LETTER SOFT SIGN
0xED	0x044D	#	CYRILLIC SMALL LETTER E
0xEE	0x044E	#	CYRILLIC SMALL LETTER YU
0xEF	0x044F	#	CYRILLIC SMALL LETTER YA
0xF0	0x2116	#	NUMERO SIGN
0xF1	0x0451	#	CYRILLIC SMALL LETTER IO
0xF2	0x0452	#	CYRILLIC SMALL LETTER DJE
0xF3	0x0453	#	CYRILLIC SMALL LETTER GJE
0xF4	0x0454	#	CYRILLIC SMALL LETTER UKRAINIAN IE
0xF5	0x0455	#	CYRILLIC SMALL LETTER DZE
0xF6	0x0456	#	CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
0xF7	0x0457	#	CYRILLIC SMALL LETTER YI
0xF8	0x0458	#	CYRILLIC SMALL LETTER JE
0xF9	0x0459	#	CYRILLIC SMALL LETTER LJE
0xFA	0x045A	#	CYRILLIC SMALL LETTER NJE
0xFB	0x045B	#	CYRILLIC SMALL LETTER TSHE
0xFC	0x045C	#	CYRILLIC SMALL LETTER KJE
0xFD	0x00A7	#	SECTION SIGN
0xFE	0x045E	#	CYRILLIC SMALL LETTER SHORT U
0xFF	0x045F	#	CYRILLIC SMALL LETTER DZHE

Added tools/encoding/iso8859-6.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
#
#	Name:             ISO 8859-6 (1987) to Unicode
#	Unicode version:  1.1
#	Table version:    0.1
#	Table format:     Format A
#	Date:             16 January 1995
#	Authors:          Tim Greenwood <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1995 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       ISO 8859-6 (1987) characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the ISO 8859-6 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 ISO 8859-6 order
#
#	Any comments or problems, contact <[email protected]>
#
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	0x0660	#	ARABIC-INDIC DIGIT ZERO
0x31	0x0661	#	ARABIC-INDIC DIGIT ONE
0x32	0x0662	#	ARABIC-INDIC DIGIT TWO
0x33	0x0663	#	ARABIC-INDIC DIGIT THREE
0x34	0x0664	#	ARABIC-INDIC DIGIT FOUR
0x35	0x0665	#	ARABIC-INDIC DIGIT FIVE
0x36	0x0666	#	ARABIC-INDIC DIGIT SIX
0x37	0x0667	#	ARABIC-INDIC DIGIT SEVEN
0x38	0x0668	#	ARABIC-INDIC DIGIT EIGHT
0x39	0x0669	#	ARABIC-INDIC 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
0xA0	0x00A0	#	NO-BREAK SPACE
0xA4	0x00A4	#	CURRENCY SIGN
0xAC	0x060C	#	ARABIC COMMA
0xAD	0x00AD	#	SOFT HYPHEN
0xBB	0x061B	#	ARABIC SEMICOLON
0xBF	0x061F	#	ARABIC QUESTION MARK
0xC1	0x0621	#	ARABIC LETTER HAMZA
0xC2	0x0622	#	ARABIC LETTER ALEF WITH MADDA ABOVE
0xC3	0x0623	#	ARABIC LETTER ALEF WITH HAMZA ABOVE
0xC4	0x0624	#	ARABIC LETTER WAW WITH HAMZA ABOVE
0xC5	0x0625	#	ARABIC LETTER ALEF WITH HAMZA BELOW
0xC6	0x0626	#	ARABIC LETTER YEH WITH HAMZA ABOVE
0xC7	0x0627	#	ARABIC LETTER ALEF
0xC8	0x0628	#	ARABIC LETTER BEH
0xC9	0x0629	#	ARABIC LETTER TEH MARBUTA
0xCA	0x062A	#	ARABIC LETTER TEH
0xCB	0x062B	#	ARABIC LETTER THEH
0xCC	0x062C	#	ARABIC LETTER JEEM
0xCD	0x062D	#	ARABIC LETTER HAH
0xCE	0x062E	#	ARABIC LETTER KHAH
0xCF	0x062F	#	ARABIC LETTER DAL
0xD0	0x0630	#	ARABIC LETTER THAL
0xD1	0x0631	#	ARABIC LETTER REH
0xD2	0x0632	#	ARABIC LETTER ZAIN
0xD3	0x0633	#	ARABIC LETTER SEEN
0xD4	0x0634	#	ARABIC LETTER SHEEN
0xD5	0x0635	#	ARABIC LETTER SAD
0xD6	0x0636	#	ARABIC LETTER DAD
0xD7	0x0637	#	ARABIC LETTER TAH
0xD8	0x0638	#	ARABIC LETTER ZAH
0xD9	0x0639	#	ARABIC LETTER AIN
0xDA	0x063A	#	ARABIC LETTER GHAIN
0xE0	0x0640	#	ARABIC TATWEEL
0xE1	0x0641	#	ARABIC LETTER FEH
0xE2	0x0642	#	ARABIC LETTER QAF
0xE3	0x0643	#	ARABIC LETTER KAF
0xE4	0x0644	#	ARABIC LETTER LAM
0xE5	0x0645	#	ARABIC LETTER MEEM
0xE6	0x0646	#	ARABIC LETTER NOON
0xE7	0x0647	#	ARABIC LETTER HEH
0xE8	0x0648	#	ARABIC LETTER WAW
0xE9	0x0649	#	ARABIC LETTER ALEF MAKSURA
0xEA	0x064A	#	ARABIC LETTER YEH
0xEB	0x064B	#	ARABIC FATHATAN
0xEC	0x064C	#	ARABIC DAMMATAN
0xED	0x064D	#	ARABIC KASRATAN
0xEE	0x064E	#	ARABIC FATHA
0xEF	0x064F	#	ARABIC DAMMA
0xF0	0x0650	#	ARABIC KASRA
0xF1	0x0651	#	ARABIC SHADDA
0xF2	0x0652	#	ARABIC SUKUN

Added tools/encoding/iso8859-7.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
#
#	Name:             ISO 8859-7 (1987) to Unicode
#	Unicode version:  1.1
#	Table version:    0.1
#	Table format:     Format A
#	Date:             16 January 1995
#	Authors:          Tim Greenwood <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1995 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       ISO 8859-7 (1987) characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the ISO 8859-7 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 ISO 8859-7 order
#
#	Any comments or problems, contact <[email protected]>
#
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
0xA0	0x00A0	#	NO-BREAK SPACE
0xA1	0x02BD	#	MODIFIER LETTER REVERSED COMMA
0xA2	0x02BC	#	MODIFIER LETTER APOSTROPHE
0xA3	0x00A3	#	POUND SIGN
0xA6	0x00A6	#	BROKEN BAR
0xA7	0x00A7	#	SECTION SIGN
0xA8	0x00A8	#	DIAERESIS
0xA9	0x00A9	#	COPYRIGHT SIGN
0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xAC	0x00AC	#	NOT SIGN
0xAD	0x00AD	#	SOFT HYPHEN
0xAF	0x2015	#	HORIZONTAL BAR
0xB0	0x00B0	#	DEGREE SIGN
0xB1	0x00B1	#	PLUS-MINUS SIGN
0xB2	0x00B2	#	SUPERSCRIPT TWO
0xB3	0x00B3	#	SUPERSCRIPT THREE
0xB4	0x0384	#	GREEK TONOS
0xB5	0x0385	#	GREEK DIALYTIKA TONOS
0xB6	0x0386	#	GREEK CAPITAL LETTER ALPHA WITH TONOS
0xB7	0x00B7	#	MIDDLE DOT
0xB8	0x0388	#	GREEK CAPITAL LETTER EPSILON WITH TONOS
0xB9	0x0389	#	GREEK CAPITAL LETTER ETA WITH TONOS
0xBA	0x038A	#	GREEK CAPITAL LETTER IOTA WITH TONOS
0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xBC	0x038C	#	GREEK CAPITAL LETTER OMICRON WITH TONOS
0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
0xBE	0x038E	#	GREEK CAPITAL LETTER UPSILON WITH TONOS
0xBF	0x038F	#	GREEK CAPITAL LETTER OMEGA WITH TONOS
0xC0	0x0390	#	GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
0xC1	0x0391	#	GREEK CAPITAL LETTER ALPHA
0xC2	0x0392	#	GREEK CAPITAL LETTER BETA
0xC3	0x0393	#	GREEK CAPITAL LETTER GAMMA
0xC4	0x0394	#	GREEK CAPITAL LETTER DELTA
0xC5	0x0395	#	GREEK CAPITAL LETTER EPSILON
0xC6	0x0396	#	GREEK CAPITAL LETTER ZETA
0xC7	0x0397	#	GREEK CAPITAL LETTER ETA
0xC8	0x0398	#	GREEK CAPITAL LETTER THETA
0xC9	0x0399	#	GREEK CAPITAL LETTER IOTA
0xCA	0x039A	#	GREEK CAPITAL LETTER KAPPA
0xCB	0x039B	#	GREEK CAPITAL LETTER LAMDA
0xCC	0x039C	#	GREEK CAPITAL LETTER MU
0xCD	0x039D	#	GREEK CAPITAL LETTER NU
0xCE	0x039E	#	GREEK CAPITAL LETTER XI
0xCF	0x039F	#	GREEK CAPITAL LETTER OMICRON
0xD0	0x03A0	#	GREEK CAPITAL LETTER PI
0xD1	0x03A1	#	GREEK CAPITAL LETTER RHO
0xD3	0x03A3	#	GREEK CAPITAL LETTER SIGMA
0xD4	0x03A4	#	GREEK CAPITAL LETTER TAU
0xD5	0x03A5	#	GREEK CAPITAL LETTER UPSILON
0xD6	0x03A6	#	GREEK CAPITAL LETTER PHI
0xD7	0x03A7	#	GREEK CAPITAL LETTER CHI
0xD8	0x03A8	#	GREEK CAPITAL LETTER PSI
0xD9	0x03A9	#	GREEK CAPITAL LETTER OMEGA
0xDA	0x03AA	#	GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
0xDB	0x03AB	#	GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
0xDC	0x03AC	#	GREEK SMALL LETTER ALPHA WITH TONOS
0xDD	0x03AD	#	GREEK SMALL LETTER EPSILON WITH TONOS
0xDE	0x03AE	#	GREEK SMALL LETTER ETA WITH TONOS
0xDF	0x03AF	#	GREEK SMALL LETTER IOTA WITH TONOS
0xE0	0x03B0	#	GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
0xE1	0x03B1	#	GREEK SMALL LETTER ALPHA
0xE2	0x03B2	#	GREEK SMALL LETTER BETA
0xE3	0x03B3	#	GREEK SMALL LETTER GAMMA
0xE4	0x03B4	#	GREEK SMALL LETTER DELTA
0xE5	0x03B5	#	GREEK SMALL LETTER EPSILON
0xE6	0x03B6	#	GREEK SMALL LETTER ZETA
0xE7	0x03B7	#	GREEK SMALL LETTER ETA
0xE8	0x03B8	#	GREEK SMALL LETTER THETA
0xE9	0x03B9	#	GREEK SMALL LETTER IOTA
0xEA	0x03BA	#	GREEK SMALL LETTER KAPPA
0xEB	0x03BB	#	GREEK SMALL LETTER LAMDA
0xEC	0x03BC	#	GREEK SMALL LETTER MU
0xED	0x03BD	#	GREEK SMALL LETTER NU
0xEE	0x03BE	#	GREEK SMALL LETTER XI
0xEF	0x03BF	#	GREEK SMALL LETTER OMICRON
0xF0	0x03C0	#	GREEK SMALL LETTER PI
0xF1	0x03C1	#	GREEK SMALL LETTER RHO
0xF2	0x03C2	#	GREEK SMALL LETTER FINAL SIGMA
0xF3	0x03C3	#	GREEK SMALL LETTER SIGMA
0xF4	0x03C4	#	GREEK SMALL LETTER TAU
0xF5	0x03C5	#	GREEK SMALL LETTER UPSILON
0xF6	0x03C6	#	GREEK SMALL LETTER PHI
0xF7	0x03C7	#	GREEK SMALL LETTER CHI
0xF8	0x03C8	#	GREEK SMALL LETTER PSI
0xF9	0x03C9	#	GREEK SMALL LETTER OMEGA
0xFA	0x03CA	#	GREEK SMALL LETTER IOTA WITH DIALYTIKA
0xFB	0x03CB	#	GREEK SMALL LETTER UPSILON WITH DIALYTIKA
0xFC	0x03CC	#	GREEK SMALL LETTER OMICRON WITH TONOS
0xFD	0x03CD	#	GREEK SMALL LETTER UPSILON WITH TONOS
0xFE	0x03CE	#	GREEK SMALL LETTER OMEGA WITH TONOS

Added tools/encoding/iso8859-8.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
#
#	Name:             ISO 8859-8 (1988) to Unicode
#	Unicode version:  1.1
#	Table version:    0.1
#	Table format:     Format A
#	Date:             16 January 1995
#	Authors:          Tim Greenwood <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1995 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       ISO 8859-8 (1988) characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the ISO 8859-8 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 ISO 8859-8 order
#
#	Any comments or problems, contact <[email protected]>
#
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
0xA0	0x00A0	#	NO-BREAK SPACE
0xA2	0x00A2	#	CENT SIGN
0xA3	0x00A3	#	POUND SIGN
0xA4	0x00A4	#	CURRENCY SIGN
0xA5	0x00A5	#	YEN SIGN
0xA6	0x00A6	#	BROKEN BAR
0xA7	0x00A7	#	SECTION SIGN
0xA8	0x00A8	#	DIAERESIS
0xA9	0x00A9	#	COPYRIGHT SIGN
0xAA	0x00D7	#	MULTIPLICATION SIGN
0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xAC	0x00AC	#	NOT SIGN
0xAD	0x00AD	#	SOFT HYPHEN
0xAE	0x00AE	#	REGISTERED SIGN
0xAF	0x203E	#	OVERLINE
0xB0	0x00B0	#	DEGREE SIGN
0xB1	0x00B1	#	PLUS-MINUS SIGN
0xB2	0x00B2	#	SUPERSCRIPT TWO
0xB3	0x00B3	#	SUPERSCRIPT THREE
0xB4	0x00B4	#	ACUTE ACCENT
0xB5	0x00B5	#	MICRO SIGN
0xB6	0x00B6	#	PILCROW SIGN
0xB7	0x00B7	#	MIDDLE DOT
0xB8	0x00B8	#	CEDILLA
0xB9	0x00B9	#	SUPERSCRIPT ONE
0xBA	0x00F7	#	DIVISION SIGN
0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xBC	0x00BC	#	VULGAR FRACTION ONE QUARTER
0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
0xBE	0x00BE	#	VULGAR FRACTION THREE QUARTERS
0xDF	0x2017	#	DOUBLE LOW LINE
0xE0	0x05D0	#	HEBREW LETTER ALEF
0xE1	0x05D1	#	HEBREW LETTER BET
0xE2	0x05D2	#	HEBREW LETTER GIMEL
0xE3	0x05D3	#	HEBREW LETTER DALET
0xE4	0x05D4	#	HEBREW LETTER HE
0xE5	0x05D5	#	HEBREW LETTER VAV
0xE6	0x05D6	#	HEBREW LETTER ZAYIN
0xE7	0x05D7	#	HEBREW LETTER HET
0xE8	0x05D8	#	HEBREW LETTER TET
0xE9	0x05D9	#	HEBREW LETTER YOD
0xEA	0x05DA	#	HEBREW LETTER FINAL KAF
0xEB	0x05DB	#	HEBREW LETTER KAF
0xEC	0x05DC	#	HEBREW LETTER LAMED
0xED	0x05DD	#	HEBREW LETTER FINAL MEM
0xEE	0x05DE	#	HEBREW LETTER MEM
0xEF	0x05DF	#	HEBREW LETTER FINAL NUN
0xF0	0x05E0	#	HEBREW LETTER NUN
0xF1	0x05E1	#	HEBREW LETTER SAMEKH
0xF2	0x05E2	#	HEBREW LETTER AYIN
0xF3	0x05E3	#	HEBREW LETTER FINAL PE
0xF4	0x05E4	#	HEBREW LETTER PE
0xF5	0x05E5	#	HEBREW LETTER FINAL TSADI
0xF6	0x05E6	#	HEBREW LETTER TSADI
0xF7	0x05E7	#	HEBREW LETTER QOF
0xF8	0x05E8	#	HEBREW LETTER RESH
0xF9	0x05E9	#	HEBREW LETTER SHIN
0xFA	0x05EA	#	HEBREW LETTER TAV

Added tools/encoding/iso8859-9.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
#
#	Name:             ISO 8859-9 (1989) to Unicode
#	Unicode version:  1.1
#	Table version:    0.1
#	Table format:     Format A
#	Date:             16 January 1995
#	Authors:          Tim Greenwood <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1995 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       ISO 8859-9 (1989) characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the ISO 8859-9 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 ISO 8859-9 order
#
#	Any comments or problems, contact <[email protected]>
#
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
0xA0	0x00A0	#	NO-BREAK SPACE
0xA1	0x00A1	#	INVERTED EXCLAMATION MARK
0xA2	0x00A2	#	CENT SIGN
0xA3	0x00A3	#	POUND SIGN
0xA4	0x00A4	#	CURRENCY SIGN
0xA5	0x00A5	#	YEN SIGN
0xA6	0x00A6	#	BROKEN BAR
0xA7	0x00A7	#	SECTION SIGN
0xA8	0x00A8	#	DIAERESIS
0xA9	0x00A9	#	COPYRIGHT SIGN
0xAA	0x00AA	#	FEMININE ORDINAL INDICATOR
0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xAC	0x00AC	#	NOT SIGN
0xAD	0x00AD	#	SOFT HYPHEN
0xAE	0x00AE	#	REGISTERED SIGN
0xAF	0x00AF	#	MACRON
0xB0	0x00B0	#	DEGREE SIGN
0xB1	0x00B1	#	PLUS-MINUS SIGN
0xB2	0x00B2	#	SUPERSCRIPT TWO
0xB3	0x00B3	#	SUPERSCRIPT THREE
0xB4	0x00B4	#	ACUTE ACCENT
0xB5	0x00B5	#	MICRO SIGN
0xB6	0x00B6	#	PILCROW SIGN
0xB7	0x00B7	#	MIDDLE DOT
0xB8	0x00B8	#	CEDILLA
0xB9	0x00B9	#	SUPERSCRIPT ONE
0xBA	0x00BA	#	MASCULINE ORDINAL INDICATOR
0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xBC	0x00BC	#	VULGAR FRACTION ONE QUARTER
0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
0xBE	0x00BE	#	VULGAR FRACTION THREE QUARTERS
0xBF	0x00BF	#	INVERTED QUESTION MARK
0xC0	0x00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xC3	0x00C3	#	LATIN CAPITAL LETTER A WITH TILDE
0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
0xC5	0x00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
0xC6	0x00C6	#	LATIN CAPITAL LETTER AE
0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
0xC8	0x00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
0xCA	0x00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
0xCC	0x00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
0xD0	0x011E	#	LATIN CAPITAL LETTER G WITH BREVE
0xD1	0x00D1	#	LATIN CAPITAL LETTER N WITH TILDE
0xD2	0x00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xD5	0x00D5	#	LATIN CAPITAL LETTER O WITH TILDE
0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
0xD7	0x00D7	#	MULTIPLICATION SIGN
0xD8	0x00D8	#	LATIN CAPITAL LETTER O WITH STROKE
0xD9	0x00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
0xDD	0x0130	#	LATIN CAPITAL LETTER I WITH DOT ABOVE
0xDE	0x015E	#	LATIN CAPITAL LETTER S WITH CEDILLA
0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
0xE0	0x00E0	#	LATIN SMALL LETTER A WITH GRAVE
0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
0xE3	0x00E3	#	LATIN SMALL LETTER A WITH TILDE
0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
0xE5	0x00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
0xE6	0x00E6	#	LATIN SMALL LETTER AE
0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
0xE8	0x00E8	#	LATIN SMALL LETTER E WITH GRAVE
0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
0xEA	0x00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
0xEC	0x00EC	#	LATIN SMALL LETTER I WITH GRAVE
0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
0xF0	0x011F	#	LATIN SMALL LETTER G WITH BREVE
0xF1	0x00F1	#	LATIN SMALL LETTER N WITH TILDE
0xF2	0x00F2	#	LATIN SMALL LETTER O WITH GRAVE
0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
0xF5	0x00F5	#	LATIN SMALL LETTER O WITH TILDE
0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
0xF7	0x00F7	#	DIVISION SIGN
0xF8	0x00F8	#	LATIN SMALL LETTER O WITH STROKE
0xF9	0x00F9	#	LATIN SMALL LETTER U WITH GRAVE
0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
0xFD	0x0131	#	LATIN SMALL LETTER DOTLESS I
0xFE	0x015F	#	LATIN SMALL LETTER S WITH CEDILLA
0xFF	0x00FF	#	LATIN SMALL LETTER Y WITH DIAERESIS


Added tools/encoding/jis0201.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
#
#	Name:             JIS X 0201 (1976) to Unicode 1.1 Table
#	Unicode version:  1.1
#	Table version:    0.9
#	Table format:     Format A
#	Date:             8 March 1994
#	Authors:          Glenn Adams <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#	single-byte JIS X 0201 characters map into Unicode 1.1
#	(ISO/IEC 10646:1-1993 UCS-2).
#
#	Format:  Three tab-separated columns
#		Column #1 is the shift JIS code (in hex as 0xXX)
#		Column #2 is the Unicode (in hex as 0xXXXX)
#		Column #3 the Unicode (ISO 10646) name (follows a comment sign)
#
#	The entries are in JIS order
#
#   These mappings are provisional, pending definition of
#       official mappings by Japanese standards bodies.
#
#	Any comments or problems, contact <[email protected]>
#
#
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 (rendered as Halfwidth Yen Sign)
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	0x203E	# OVERLINE
0xA1	0xFF61	# HALFWIDTH IDEOGRAPHIC FULL STOP
0xA2	0xFF62	# HALFWIDTH LEFT CORNER BRACKET
0xA3	0xFF63	# HALFWIDTH RIGHT CORNER BRACKET
0xA4	0xFF64	# HALFWIDTH IDEOGRAPHIC COMMA
0xA5	0xFF65	# HALFWIDTH KATAKANA MIDDLE DOT
0xA6	0xFF66	# HALFWIDTH KATAKANA LETTER WO
0xA7	0xFF67	# HALFWIDTH KATAKANA LETTER SMALL A
0xA8	0xFF68	# HALFWIDTH KATAKANA LETTER SMALL I
0xA9	0xFF69	# HALFWIDTH KATAKANA LETTER SMALL U
0xAA	0xFF6A	# HALFWIDTH KATAKANA LETTER SMALL E
0xAB	0xFF6B	# HALFWIDTH KATAKANA LETTER SMALL O
0xAC	0xFF6C	# HALFWIDTH KATAKANA LETTER SMALL YA
0xAD	0xFF6D	# HALFWIDTH KATAKANA LETTER SMALL YU
0xAE	0xFF6E	# HALFWIDTH KATAKANA LETTER SMALL YO
0xAF	0xFF6F	# HALFWIDTH KATAKANA LETTER SMALL TU
0xB0	0xFF70	# HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
0xB1	0xFF71	# HALFWIDTH KATAKANA LETTER A
0xB2	0xFF72	# HALFWIDTH KATAKANA LETTER I
0xB3	0xFF73	# HALFWIDTH KATAKANA LETTER U
0xB4	0xFF74	# HALFWIDTH KATAKANA LETTER E
0xB5	0xFF75	# HALFWIDTH KATAKANA LETTER O
0xB6	0xFF76	# HALFWIDTH KATAKANA LETTER KA
0xB7	0xFF77	# HALFWIDTH KATAKANA LETTER KI
0xB8	0xFF78	# HALFWIDTH KATAKANA LETTER KU
0xB9	0xFF79	# HALFWIDTH KATAKANA LETTER KE
0xBA	0xFF7A	# HALFWIDTH KATAKANA LETTER KO
0xBB	0xFF7B	# HALFWIDTH KATAKANA LETTER SA
0xBC	0xFF7C	# HALFWIDTH KATAKANA LETTER SI
0xBD	0xFF7D	# HALFWIDTH KATAKANA LETTER SU
0xBE	0xFF7E	# HALFWIDTH KATAKANA LETTER SE
0xBF	0xFF7F	# HALFWIDTH KATAKANA LETTER SO
0xC0	0xFF80	# HALFWIDTH KATAKANA LETTER TA
0xC1	0xFF81	# HALFWIDTH KATAKANA LETTER TI
0xC2	0xFF82	# HALFWIDTH KATAKANA LETTER TU
0xC3	0xFF83	# HALFWIDTH KATAKANA LETTER TE
0xC4	0xFF84	# HALFWIDTH KATAKANA LETTER TO
0xC5	0xFF85	# HALFWIDTH KATAKANA LETTER NA
0xC6	0xFF86	# HALFWIDTH KATAKANA LETTER NI
0xC7	0xFF87	# HALFWIDTH KATAKANA LETTER NU
0xC8	0xFF88	# HALFWIDTH KATAKANA LETTER NE
0xC9	0xFF89	# HALFWIDTH KATAKANA LETTER NO
0xCA	0xFF8A	# HALFWIDTH KATAKANA LETTER HA
0xCB	0xFF8B	# HALFWIDTH KATAKANA LETTER HI
0xCC	0xFF8C	# HALFWIDTH KATAKANA LETTER HU
0xCD	0xFF8D	# HALFWIDTH KATAKANA LETTER HE
0xCE	0xFF8E	# HALFWIDTH KATAKANA LETTER HO
0xCF	0xFF8F	# HALFWIDTH KATAKANA LETTER MA
0xD0	0xFF90	# HALFWIDTH KATAKANA LETTER MI
0xD1	0xFF91	# HALFWIDTH KATAKANA LETTER MU
0xD2	0xFF92	# HALFWIDTH KATAKANA LETTER ME
0xD3	0xFF93	# HALFWIDTH KATAKANA LETTER MO
0xD4	0xFF94	# HALFWIDTH KATAKANA LETTER YA
0xD5	0xFF95	# HALFWIDTH KATAKANA LETTER YU
0xD6	0xFF96	# HALFWIDTH KATAKANA LETTER YO
0xD7	0xFF97	# HALFWIDTH KATAKANA LETTER RA
0xD8	0xFF98	# HALFWIDTH KATAKANA LETTER RI
0xD9	0xFF99	# HALFWIDTH KATAKANA LETTER RU
0xDA	0xFF9A	# HALFWIDTH KATAKANA LETTER RE
0xDB	0xFF9B	# HALFWIDTH KATAKANA LETTER RO
0xDC	0xFF9C	# HALFWIDTH KATAKANA LETTER WA
0xDD	0xFF9D	# HALFWIDTH KATAKANA LETTER N
0xDE	0xFF9E	# HALFWIDTH KATAKANA VOICED SOUND MARK
0xDF	0xFF9F	# HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK

Added tools/encoding/jis0208.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
#
#	Name:             JIS X 0208 (1990) to Unicode
#	Unicode version:  1.1
#	Table version:    0.9
#	Table format:     Format A
#	Date:             8 March 1994
#	Authors:          Glenn Adams <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       JIS X 0208 (1983) characters map into Unicode.
#
#	Format:  Four tab-separated columns
#		 Column #1 is the shift-JIS code (in hex)
#		 Column #2 is the JIS X 0208 code (in hex as 0xXXXX)
#		 Column #3 is the Unicode (in hex as 0xXXXX)
#		 Column #4 the Unicode name (follows a comment sign, '#')
#					The official names for Unicode characters U+4E00
#					to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
#					where XXXX is the code point.  Including all these
#					names in this file increases its size substantially
#					and needlessly.  The token "<CJK>" is used for the
#					name of these characters.  If necessary, it can be
#					expanded algorithmically by a parser or editor.
#
#	The entries are in JIS X 0208 order
#
#	The following algorithms can be used to change the hex form
#		of JIS 0208 to other standard forms:
#
#		To change hex to EUC form, add 0x8080
#		To change hex to kuten form, first subtract 0x2020.  Then
#			the high and low bytes correspond to the ku and ten of
#			the kuten form.  For example, 0x2121 -> 0x0101 -> 0101;
#			0x7426 -> 0x5406 -> 8406
#
#   The kanji mappings are a normative part of ISO/IEC 10646.  The
#       non-kanji mappings are provisional, pending definition of
#       official mappings by Japanese standards bodies
#
#	Any comments or problems, contact <[email protected]>
#
#
0x8140	0x2121	0x3000	# IDEOGRAPHIC SPACE
0x8141	0x2122	0x3001	# IDEOGRAPHIC COMMA
0x8142	0x2123	0x3002	# IDEOGRAPHIC FULL STOP
0x8143	0x2124	0xFF0C	# FULLWIDTH COMMA
0x8144	0x2125	0xFF0E	# FULLWIDTH FULL STOP
0x8145	0x2126	0x30FB	# KATAKANA MIDDLE DOT
0x8146	0x2127	0xFF1A	# FULLWIDTH COLON
0x8147	0x2128	0xFF1B	# FULLWIDTH SEMICOLON
0x8148	0x2129	0xFF1F	# FULLWIDTH QUESTION MARK
0x8149	0x212A	0xFF01	# FULLWIDTH EXCLAMATION MARK
0x814A	0x212B	0x309B	# KATAKANA-HIRAGANA VOICED SOUND MARK
0x814B	0x212C	0x309C	# KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
0x814C	0x212D	0x00B4	# ACUTE ACCENT
0x814D	0x212E	0xFF40	# FULLWIDTH GRAVE ACCENT
0x814E	0x212F	0x00A8	# DIAERESIS
0x814F	0x2130	0xFF3E	# FULLWIDTH CIRCUMFLEX ACCENT
0x8150	0x2131	0xFFE3	# FULLWIDTH MACRON
0x8151	0x2132	0xFF3F	# FULLWIDTH LOW LINE
0x8152	0x2133	0x30FD	# KATAKANA ITERATION MARK
0x8153	0x2134	0x30FE	# KATAKANA VOICED ITERATION MARK
0x8154	0x2135	0x309D	# HIRAGANA ITERATION MARK
0x8155	0x2136	0x309E	# HIRAGANA VOICED ITERATION MARK
0x8156	0x2137	0x3003	# DITTO MARK
0x8157	0x2138	0x4EDD	# <CJK>
0x8158	0x2139	0x3005	# IDEOGRAPHIC ITERATION MARK
0x8159	0x213A	0x3006	# IDEOGRAPHIC CLOSING MARK
0x815A	0x213B	0x3007	# IDEOGRAPHIC NUMBER ZERO
0x815B	0x213C	0x30FC	# KATAKANA-HIRAGANA PROLONGED SOUND MARK
0x815C	0x213D	0x2015	# HORIZONTAL BAR
0x815D	0x213E	0x2010	# HYPHEN
0x815E	0x213F	0xFF0F	# FULLWIDTH SOLIDUS
0x815F	0x2140	0xFF3C	# FULLWIDTH REVERSE SOLIDUS
0x8160	0x2141	0x301C	# WAVE DASH
0x8161	0x2142	0x2016	# DOUBLE VERTICAL LINE
0x8162	0x2143	0xFF5C	# FULLWIDTH VERTICAL LINE
0x8163	0x2144	0x2026	# HORIZONTAL ELLIPSIS
0x8164	0x2145	0x2025	# TWO DOT LEADER
0x8165	0x2146	0x2018	# LEFT SINGLE QUOTATION MARK
0x8166	0x2147	0x2019	# RIGHT SINGLE QUOTATION MARK
0x8167	0x2148	0x201C	# LEFT DOUBLE QUOTATION MARK
0x8168	0x2149	0x201D	# RIGHT DOUBLE QUOTATION MARK
0x8169	0x214A	0xFF08	# FULLWIDTH LEFT PARENTHESIS
0x816A	0x214B	0xFF09	# FULLWIDTH RIGHT PARENTHESIS
0x816B	0x214C	0x3014	# LEFT TORTOISE SHELL BRACKET
0x816C	0x214D	0x3015	# RIGHT TORTOISE SHELL BRACKET
0x816D	0x214E	0xFF3B	# FULLWIDTH LEFT SQUARE BRACKET
0x816E	0x214F	0xFF3D	# FULLWIDTH RIGHT SQUARE BRACKET
0x816F	0x2150	0xFF5B	# FULLWIDTH LEFT CURLY BRACKET
0x8170	0x2151	0xFF5D	# FULLWIDTH RIGHT CURLY BRACKET
0x8171	0x2152	0x3008	# LEFT ANGLE BRACKET
0x8172	0x2153	0x3009	# RIGHT ANGLE BRACKET
0x8173	0x2154	0x300A	# LEFT DOUBLE ANGLE BRACKET
0x8174	0x2155	0x300B	# RIGHT DOUBLE ANGLE BRACKET
0x8175	0x2156	0x300C	# LEFT CORNER BRACKET
0x8176	0x2157	0x300D	# RIGHT CORNER BRACKET
0x8177	0x2158	0x300E	# LEFT WHITE CORNER BRACKET
0x8178	0x2159	0x300F	# RIGHT WHITE CORNER BRACKET
0x8179	0x215A	0x3010	# LEFT BLACK LENTICULAR BRACKET
0x817A	0x215B	0x3011	# RIGHT BLACK LENTICULAR BRACKET
0x817B	0x215C	0xFF0B	# FULLWIDTH PLUS SIGN
0x817C	0x215D	0x2212	# MINUS SIGN
0x817D	0x215E	0x00B1	# PLUS-MINUS SIGN
0x817E	0x215F	0x00D7	# MULTIPLICATION SIGN
0x8180	0x2160	0x00F7	# DIVISION SIGN
0x8181	0x2161	0xFF1D	# FULLWIDTH EQUALS SIGN
0x8182	0x2162	0x2260	# NOT EQUAL TO
0x8183	0x2163	0xFF1C	# FULLWIDTH LESS-THAN SIGN
0x8184	0x2164	0xFF1E	# FULLWIDTH GREATER-THAN SIGN
0x8185	0x2165	0x2266	# LESS-THAN OVER EQUAL TO
0x8186	0x2166	0x2267	# GREATER-THAN OVER EQUAL TO
0x8187	0x2167	0x221E	# INFINITY
0x8188	0x2168	0x2234	# THEREFORE
0x8189	0x2169	0x2642	# MALE SIGN
0x818A	0x216A	0x2640	# FEMALE SIGN
0x818B	0x216B	0x00B0	# DEGREE SIGN
0x818C	0x216C	0x2032	# PRIME
0x818D	0x216D	0x2033	# DOUBLE PRIME
0x818E	0x216E	0x2103	# DEGREE CELSIUS
0x818F	0x216F	0xFFE5	# FULLWIDTH YEN SIGN
0x8190	0x2170	0xFF04	# FULLWIDTH DOLLAR SIGN
0x8191	0x2171	0x00A2	# CENT SIGN
0x8192	0x2172	0x00A3	# POUND SIGN
0x8193	0x2173	0xFF05	# FULLWIDTH PERCENT SIGN
0x8194	0x2174	0xFF03	# FULLWIDTH NUMBER SIGN
0x8195	0x2175	0xFF06	# FULLWIDTH AMPERSAND
0x8196	0x2176	0xFF0A	# FULLWIDTH ASTERISK
0x8197	0x2177	0xFF20	# FULLWIDTH COMMERCIAL AT
0x8198	0x2178	0x00A7	# SECTION SIGN
0x8199	0x2179	0x2606	# WHITE STAR
0x819A	0x217A	0x2605	# BLACK STAR
0x819B	0x217B	0x25CB	# WHITE CIRCLE
0x819C	0x217C	0x25CF	# BLACK CIRCLE
0x819D	0x217D	0x25CE	# BULLSEYE
0x819E	0x217E	0x25C7	# WHITE DIAMOND
0x819F	0x2221	0x25C6	# BLACK DIAMOND
0x81A0	0x2222	0x25A1	# WHITE SQUARE
0x81A1	0x2223	0x25A0	# BLACK SQUARE
0x81A2	0x2224	0x25B3	# WHITE UP-POINTING TRIANGLE
0x81A3	0x2225	0x25B2	# BLACK UP-POINTING TRIANGLE
0x81A4	0x2226	0x25BD	# WHITE DOWN-POINTING TRIANGLE
0x81A5	0x2227	0x25BC	# BLACK DOWN-POINTING TRIANGLE
0x81A6	0x2228	0x203B	# REFERENCE MARK
0x81A7	0x2229	0x3012	# POSTAL MARK
0x81A8	0x222A	0x2192	# RIGHTWARDS ARROW
0x81A9	0x222B	0x2190	# LEFTWARDS ARROW
0x81AA	0x222C	0x2191	# UPWARDS ARROW
0x81AB	0x222D	0x2193	# DOWNWARDS ARROW
0x81AC	0x222E	0x3013	# GETA MARK
0x81B8	0x223A	0x2208	# ELEMENT OF
0x81B9	0x223B	0x220B	# CONTAINS AS MEMBER
0x81BA	0x223C	0x2286	# SUBSET OF OR EQUAL TO
0x81BB	0x223D	0x2287	# SUPERSET OF OR EQUAL TO
0x81BC	0x223E	0x2282	# SUBSET OF
0x81BD	0x223F	0x2283	# SUPERSET OF
0x81BE	0x2240	0x222A	# UNION
0x81BF	0x2241	0x2229	# INTERSECTION
0x81C8	0x224A	0x2227	# LOGICAL AND
0x81C9	0x224B	0x2228	# LOGICAL OR
0x81CA	0x224C	0x00AC	# NOT SIGN
0x81CB	0x224D	0x21D2	# RIGHTWARDS DOUBLE ARROW
0x81CC	0x224E	0x21D4	# LEFT RIGHT DOUBLE ARROW
0x81CD	0x224F	0x2200	# FOR ALL
0x81CE	0x2250	0x2203	# THERE EXISTS
0x81DA	0x225C	0x2220	# ANGLE
0x81DB	0x225D	0x22A5	# UP TACK
0x81DC	0x225E	0x2312	# ARC
0x81DD	0x225F	0x2202	# PARTIAL DIFFERENTIAL
0x81DE	0x2260	0x2207	# NABLA
0x81DF	0x2261	0x2261	# IDENTICAL TO
0x81E0	0x2262	0x2252	# APPROXIMATELY EQUAL TO OR THE IMAGE OF
0x81E1	0x2263	0x226A	# MUCH LESS-THAN
0x81E2	0x2264	0x226B	# MUCH GREATER-THAN
0x81E3	0x2265	0x221A	# SQUARE ROOT
0x81E4	0x2266	0x223D	# REVERSED TILDE
0x81E5	0x2267	0x221D	# PROPORTIONAL TO
0x81E6	0x2268	0x2235	# BECAUSE
0x81E7	0x2269	0x222B	# INTEGRAL
0x81E8	0x226A	0x222C	# DOUBLE INTEGRAL
0x81F0	0x2272	0x212B	# ANGSTROM SIGN
0x81F1	0x2273	0x2030	# PER MILLE SIGN
0x81F2	0x2274	0x266F	# MUSIC SHARP SIGN
0x81F3	0x2275	0x266D	# MUSIC FLAT SIGN
0x81F4	0x2276	0x266A	# EIGHTH NOTE
0x81F5	0x2277	0x2020	# DAGGER
0x81F6	0x2278	0x2021	# DOUBLE DAGGER
0x81F7	0x2279	0x00B6	# PILCROW SIGN
0x81FC	0x227E	0x25EF	# LARGE CIRCLE
0x824F	0x2330	0xFF10	# FULLWIDTH DIGIT ZERO
0x8250	0x2331	0xFF11	# FULLWIDTH DIGIT ONE
0x8251	0x2332	0xFF12	# FULLWIDTH DIGIT TWO
0x8252	0x2333	0xFF13	# FULLWIDTH DIGIT THREE
0x8253	0x2334	0xFF14	# FULLWIDTH DIGIT FOUR
0x8254	0x2335	0xFF15	# FULLWIDTH DIGIT FIVE
0x8255	0x2336	0xFF16	# FULLWIDTH DIGIT SIX
0x8256	0x2337	0xFF17	# FULLWIDTH DIGIT SEVEN
0x8257	0x2338	0xFF18	# FULLWIDTH DIGIT EIGHT
0x8258	0x2339	0xFF19	# FULLWIDTH DIGIT NINE
0x8260	0x2341	0xFF21	# FULLWIDTH LATIN CAPITAL LETTER A
0x8261	0x2342	0xFF22	# FULLWIDTH LATIN CAPITAL LETTER B
0x8262	0x2343	0xFF23	# FULLWIDTH LATIN CAPITAL LETTER C
0x8263	0x2344	0xFF24	# FULLWIDTH LATIN CAPITAL LETTER D
0x8264	0x2345	0xFF25	# FULLWIDTH LATIN CAPITAL LETTER E
0x8265	0x2346	0xFF26	# FULLWIDTH LATIN CAPITAL LETTER F
0x8266	0x2347	0xFF27	# FULLWIDTH LATIN CAPITAL LETTER G
0x8267	0x2348	0xFF28	# FULLWIDTH LATIN CAPITAL LETTER H
0x8268	0x2349	0xFF29	# FULLWIDTH LATIN CAPITAL LETTER I
0x8269	0x234A	0xFF2A	# FULLWIDTH LATIN CAPITAL LETTER J
0x826A	0x234B	0xFF2B	# FULLWIDTH LATIN CAPITAL LETTER K
0x826B	0x234C	0xFF2C	# FULLWIDTH LATIN CAPITAL LETTER L
0x826C	0x234D	0xFF2D	# FULLWIDTH LATIN CAPITAL LETTER M
0x826D	0x234E	0xFF2E	# FULLWIDTH LATIN CAPITAL LETTER N
0x826E	0x234F	0xFF2F	# FULLWIDTH LATIN CAPITAL LETTER O
0x826F	0x2350	0xFF30	# FULLWIDTH LATIN CAPITAL LETTER P
0x8270	0x2351	0xFF31	# FULLWIDTH LATIN CAPITAL LETTER Q
0x8271	0x2352	0xFF32	# FULLWIDTH LATIN CAPITAL LETTER R
0x8272	0x2353	0xFF33	# FULLWIDTH LATIN CAPITAL LETTER S
0x8273	0x2354	0xFF34	# FULLWIDTH LATIN CAPITAL LETTER T
0x8274	0x2355	0xFF35	# FULLWIDTH LATIN CAPITAL LETTER U
0x8275	0x2356	0xFF36	# FULLWIDTH LATIN CAPITAL LETTER V
0x8276	0x2357	0xFF37	# FULLWIDTH LATIN CAPITAL LETTER W
0x8277	0x2358	0xFF38	# FULLWIDTH LATIN CAPITAL LETTER X
0x8278	0x2359	0xFF39	# FULLWIDTH LATIN CAPITAL LETTER Y
0x8279	0x235A	0xFF3A	# FULLWIDTH LATIN CAPITAL LETTER Z
0x8281	0x2361	0xFF41	# FULLWIDTH LATIN SMALL LETTER A
0x8282	0x2362	0xFF42	# FULLWIDTH LATIN SMALL LETTER B
0x8283	0x2363	0xFF43	# FULLWIDTH LATIN SMALL LETTER C
0x8284	0x2364	0xFF44	# FULLWIDTH LATIN SMALL LETTER D
0x8285	0x2365	0xFF45	# FULLWIDTH LATIN SMALL LETTER E
0x8286	0x2366	0xFF46	# FULLWIDTH LATIN SMALL LETTER F
0x8287	0x2367	0xFF47	# FULLWIDTH LATIN SMALL LETTER G
0x8288	0x2368	0xFF48	# FULLWIDTH LATIN SMALL LETTER H
0x8289	0x2369	0xFF49	# FULLWIDTH LATIN SMALL LETTER I
0x828A	0x236A	0xFF4A	# FULLWIDTH LATIN SMALL LETTER J
0x828B	0x236B	0xFF4B	# FULLWIDTH LATIN SMALL LETTER K
0x828C	0x236C	0xFF4C	# FULLWIDTH LATIN SMALL LETTER L
0x828D	0x236D	0xFF4D	# FULLWIDTH LATIN SMALL LETTER M
0x828E	0x236E	0xFF4E	# FULLWIDTH LATIN SMALL LETTER N
0x828F	0x236F	0xFF4F	# FULLWIDTH LATIN SMALL LETTER O
0x8290	0x2370	0xFF50	# FULLWIDTH LATIN SMALL LETTER P
0x8291	0x2371	0xFF51	# FULLWIDTH LATIN SMALL LETTER Q
0x8292	0x2372	0xFF52	# FULLWIDTH LATIN SMALL LETTER R
0x8293	0x2373	0xFF53	# FULLWIDTH LATIN SMALL LETTER S
0x8294	0x2374	0xFF54	# FULLWIDTH LATIN SMALL LETTER T
0x8295	0x2375	0xFF55	# FULLWIDTH LATIN SMALL LETTER U
0x8296	0x2376	0xFF56	# FULLWIDTH LATIN SMALL LETTER V
0x8297	0x2377	0xFF57	# FULLWIDTH LATIN SMALL LETTER W
0x8298	0x2378	0xFF58	# FULLWIDTH LATIN SMALL LETTER X
0x8299	0x2379	0xFF59	# FULLWIDTH LATIN SMALL LETTER Y
0x829A	0x237A	0xFF5A	# FULLWIDTH LATIN SMALL LETTER Z
0x829F	0x2421	0x3041	# HIRAGANA LETTER SMALL A
0x82A0	0x2422	0x3042	# HIRAGANA LETTER A
0x82A1	0x2423	0x3043	# HIRAGANA LETTER SMALL I
0x82A2	0x2424	0x3044	# HIRAGANA LETTER I
0x82A3	0x2425	0x3045	# HIRAGANA LETTER SMALL U
0x82A4	0x2426	0x3046	# HIRAGANA LETTER U
0x82A5	0x2427	0x3047	# HIRAGANA LETTER SMALL E
0x82A6	0x2428	0x3048	# HIRAGANA LETTER E
0x82A7	0x2429	0x3049	# HIRAGANA LETTER SMALL O
0x82A8	0x242A	0x304A	# HIRAGANA LETTER O
0x82A9	0x242B	0x304B	# HIRAGANA LETTER KA
0x82AA	0x242C	0x304C	# HIRAGANA LETTER GA
0x82AB	0x242D	0x304D	# HIRAGANA LETTER KI
0x82AC	0x242E	0x304E	# HIRAGANA LETTER GI
0x82AD	0x242F	0x304F	# HIRAGANA LETTER KU
0x82AE	0x2430	0x3050	# HIRAGANA LETTER GU
0x82AF	0x2431	0x3051	# HIRAGANA LETTER KE
0x82B0	0x2432	0x3052	# HIRAGANA LETTER GE
0x82B1	0x2433	0x3053	# HIRAGANA LETTER KO
0x82B2	0x2434	0x3054	# HIRAGANA LETTER GO
0x82B3	0x2435	0x3055	# HIRAGANA LETTER SA
0x82B4	0x2436	0x3056	# HIRAGANA LETTER ZA
0x82B5	0x2437	0x3057	# HIRAGANA LETTER SI
0x82B6	0x2438	0x3058	# HIRAGANA LETTER ZI
0x82B7	0x2439	0x3059	# HIRAGANA LETTER SU
0x82B8	0x243A	0x305A	# HIRAGANA LETTER ZU
0x82B9	0x243B	0x305B	# HIRAGANA LETTER SE
0x82BA	0x243C	0x305C	# HIRAGANA LETTER ZE
0x82BB	0x243D	0x305D	# HIRAGANA LETTER SO
0x82BC	0x243E	0x305E	# HIRAGANA LETTER ZO
0x82BD	0x243F	0x305F	# HIRAGANA LETTER TA
0x82BE	0x2440	0x3060	# HIRAGANA LETTER DA
0x82BF	0x2441	0x3061	# HIRAGANA LETTER TI
0x82C0	0x2442	0x3062	# HIRAGANA LETTER DI
0x82C1	0x2443	0x3063	# HIRAGANA LETTER SMALL TU
0x82C2	0x2444	0x3064	# HIRAGANA LETTER TU
0x82C3	0x2445	0x3065	# HIRAGANA LETTER DU
0x82C4	0x2446	0x3066	# HIRAGANA LETTER TE
0x82C5	0x2447	0x3067	# HIRAGANA LETTER DE
0x82C6	0x2448	0x3068	# HIRAGANA LETTER TO
0x82C7	0x2449	0x3069	# HIRAGANA LETTER DO
0x82C8	0x244A	0x306A	# HIRAGANA LETTER NA
0x82C9	0x244B	0x306B	# HIRAGANA LETTER NI
0x82CA	0x244C	0x306C	# HIRAGANA LETTER NU
0x82CB	0x244D	0x306D	# HIRAGANA LETTER NE
0x82CC	0x244E	0x306E	# HIRAGANA LETTER NO
0x82CD	0x244F	0x306F	# HIRAGANA LETTER HA
0x82CE	0x2450	0x3070	# HIRAGANA LETTER BA
0x82CF	0x2451	0x3071	# HIRAGANA LETTER PA
0x82D0	0x2452	0x3072	# HIRAGANA LETTER HI
0x82D1	0x2453	0x3073	# HIRAGANA LETTER BI
0x82D2	0x2454	0x3074	# HIRAGANA LETTER PI
0x82D3	0x2455	0x3075	# HIRAGANA LETTER HU
0x82D4	0x2456	0x3076	# HIRAGANA LETTER BU
0x82D5	0x2457	0x3077	# HIRAGANA LETTER PU
0x82D6	0x2458	0x3078	# HIRAGANA LETTER HE
0x82D7	0x2459	0x3079	# HIRAGANA LETTER BE
0x82D8	0x245A	0x307A	# HIRAGANA LETTER PE
0x82D9	0x245B	0x307B	# HIRAGANA LETTER HO
0x82DA	0x245C	0x307C	# HIRAGANA LETTER BO
0x82DB	0x245D	0x307D	# HIRAGANA LETTER PO
0x82DC	0x245E	0x307E	# HIRAGANA LETTER MA
0x82DD	0x245F	0x307F	# HIRAGANA LETTER MI
0x82DE	0x2460	0x3080	# HIRAGANA LETTER MU
0x82DF	0x2461	0x3081	# HIRAGANA LETTER ME
0x82E0	0x2462	0x3082	# HIRAGANA LETTER MO
0x82E1	0x2463	0x3083	# HIRAGANA LETTER SMALL YA
0x82E2	0x2464	0x3084	# HIRAGANA LETTER YA
0x82E3	0x2465	0x3085	# HIRAGANA LETTER SMALL YU
0x82E4	0x2466	0x3086	# HIRAGANA LETTER YU
0x82E5	0x2467	0x3087	# HIRAGANA LETTER SMALL YO
0x82E6	0x2468	0x3088	# HIRAGANA LETTER YO
0x82E7	0x2469	0x3089	# HIRAGANA LETTER RA
0x82E8	0x246A	0x308A	# HIRAGANA LETTER RI
0x82E9	0x246B	0x308B	# HIRAGANA LETTER RU
0x82EA	0x246C	0x308C	# HIRAGANA LETTER RE
0x82EB	0x246D	0x308D	# HIRAGANA LETTER RO
0x82EC	0x246E	0x308E	# HIRAGANA LETTER SMALL WA
0x82ED	0x246F	0x308F	# HIRAGANA LETTER WA
0x82EE	0x2470	0x3090	# HIRAGANA LETTER WI
0x82EF	0x2471	0x3091	# HIRAGANA LETTER WE
0x82F0	0x2472	0x3092	# HIRAGANA LETTER WO
0x82F1	0x2473	0x3093	# HIRAGANA LETTER N
0x8340	0x2521	0x30A1	# KATAKANA LETTER SMALL A
0x8341	0x2522	0x30A2	# KATAKANA LETTER A
0x8342	0x2523	0x30A3	# KATAKANA LETTER SMALL I
0x8343	0x2524	0x30A4	# KATAKANA LETTER I
0x8344	0x2525	0x30A5	# KATAKANA LETTER SMALL U
0x8345	0x2526	0x30A6	# KATAKANA LETTER U
0x8346	0x2527	0x30A7	# KATAKANA LETTER SMALL E
0x8347	0x2528	0x30A8	# KATAKANA LETTER E
0x8348	0x2529	0x30A9	# KATAKANA LETTER SMALL O
0x8349	0x252A	0x30AA	# KATAKANA LETTER O
0x834A	0x252B	0x30AB	# KATAKANA LETTER KA
0x834B	0x252C	0x30AC	# KATAKANA LETTER GA
0x834C	0x252D	0x30AD	# KATAKANA LETTER KI
0x834D	0x252E	0x30AE	# KATAKANA LETTER GI
0x834E	0x252F	0x30AF	# KATAKANA LETTER KU
0x834F	0x2530	0x30B0	# KATAKANA LETTER GU
0x8350	0x2531	0x30B1	# KATAKANA LETTER KE
0x8351	0x2532	0x30B2	# KATAKANA LETTER GE
0x8352	0x2533	0x30B3	# KATAKANA LETTER KO
0x8353	0x2534	0x30B4	# KATAKANA LETTER GO
0x8354	0x2535	0x30B5	# KATAKANA LETTER SA
0x8355	0x2536	0x30B6	# KATAKANA LETTER ZA
0x8356	0x2537	0x30B7	# KATAKANA LETTER SI
0x8357	0x2538	0x30B8	# KATAKANA LETTER ZI
0x8358	0x2539	0x30B9	# KATAKANA LETTER SU
0x8359	0x253A	0x30BA	# KATAKANA LETTER ZU
0x835A	0x253B	0x30BB	# KATAKANA LETTER SE
0x835B	0x253C	0x30BC	# KATAKANA LETTER ZE
0x835C	0x253D	0x30BD	# KATAKANA LETTER SO
0x835D	0x253E	0x30BE	# KATAKANA LETTER ZO
0x835E	0x253F	0x30BF	# KATAKANA LETTER TA
0x835F	0x2540	0x30C0	# KATAKANA LETTER DA
0x8360	0x2541	0x30C1	# KATAKANA LETTER TI
0x8361	0x2542	0x30C2	# KATAKANA LETTER DI
0x8362	0x2543	0x30C3	# KATAKANA LETTER SMALL TU
0x8363	0x2544	0x30C4	# KATAKANA LETTER TU
0x8364	0x2545	0x30C5	# KATAKANA LETTER DU
0x8365	0x2546	0x30C6	# KATAKANA LETTER TE
0x8366	0x2547	0x30C7	# KATAKANA LETTER DE
0x8367	0x2548	0x30C8	# KATAKANA LETTER TO
0x8368	0x2549	0x30C9	# KATAKANA LETTER DO
0x8369	0x254A	0x30CA	# KATAKANA LETTER NA
0x836A	0x254B	0x30CB	# KATAKANA LETTER NI
0x836B	0x254C	0x30CC	# KATAKANA LETTER NU
0x836C	0x254D	0x30CD	# KATAKANA LETTER NE
0x836D	0x254E	0x30CE	# KATAKANA LETTER NO
0x836E	0x254F	0x30CF	# KATAKANA LETTER HA
0x836F	0x2550	0x30D0	# KATAKANA LETTER BA
0x8370	0x2551	0x30D1	# KATAKANA LETTER PA
0x8371	0x2552	0x30D2	# KATAKANA LETTER HI
0x8372	0x2553	0x30D3	# KATAKANA LETTER BI
0x8373	0x2554	0x30D4	# KATAKANA LETTER PI
0x8374	0x2555	0x30D5	# KATAKANA LETTER HU
0x8375	0x2556	0x30D6	# KATAKANA LETTER BU
0x8376	0x2557	0x30D7	# KATAKANA LETTER PU
0x8377	0x2558	0x30D8	# KATAKANA LETTER HE
0x8378	0x2559	0x30D9	# KATAKANA LETTER BE
0x8379	0x255A	0x30DA	# KATAKANA LETTER PE
0x837A	0x255B	0x30DB	# KATAKANA LETTER HO
0x837B	0x255C	0x30DC	# KATAKANA LETTER BO
0x837C	0x255D	0x30DD	# KATAKANA LETTER PO
0x837D	0x255E	0x30DE	# KATAKANA LETTER MA
0x837E	0x255F	0x30DF	# KATAKANA LETTER MI
0x8380	0x2560	0x30E0	# KATAKANA LETTER MU
0x8381	0x2561	0x30E1	# KATAKANA LETTER ME
0x8382	0x2562	0x30E2	# KATAKANA LETTER MO
0x8383	0x2563	0x30E3	# KATAKANA LETTER SMALL YA
0x8384	0x2564	0x30E4	# KATAKANA LETTER YA
0x8385	0x2565	0x30E5	# KATAKANA LETTER SMALL YU
0x8386	0x2566	0x30E6	# KATAKANA LETTER YU
0x8387	0x2567	0x30E7	# KATAKANA LETTER SMALL YO
0x8388	0x2568	0x30E8	# KATAKANA LETTER YO
0x8389	0x2569	0x30E9	# KATAKANA LETTER RA
0x838A	0x256A	0x30EA	# KATAKANA LETTER RI
0x838B	0x256B	0x30EB	# KATAKANA LETTER RU
0x838C	0x256C	0x30EC	# KATAKANA LETTER RE
0x838D	0x256D	0x30ED	# KATAKANA LETTER RO
0x838E	0x256E	0x30EE	# KATAKANA LETTER SMALL WA
0x838F	0x256F	0x30EF	# KATAKANA LETTER WA
0x8390	0x2570	0x30F0	# KATAKANA LETTER WI
0x8391	0x2571	0x30F1	# KATAKANA LETTER WE
0x8392	0x2572	0x30F2	# KATAKANA LETTER WO
0x8393	0x2573	0x30F3	# KATAKANA LETTER N
0x8394	0x2574	0x30F4	# KATAKANA LETTER VU
0x8395	0x2575	0x30F5	# KATAKANA LETTER SMALL KA
0x8396	0x2576	0x30F6	# KATAKANA LETTER SMALL KE
0x839F	0x2621	0x0391	# GREEK CAPITAL LETTER ALPHA
0x83A0	0x2622	0x0392	# GREEK CAPITAL LETTER BETA
0x83A1	0x2623	0x0393	# GREEK CAPITAL LETTER GAMMA
0x83A2	0x2624	0x0394	# GREEK CAPITAL LETTER DELTA
0x83A3	0x2625	0x0395	# GREEK CAPITAL LETTER EPSILON
0x83A4	0x2626	0x0396	# GREEK CAPITAL LETTER ZETA
0x83A5	0x2627	0x0397	# GREEK CAPITAL LETTER ETA
0x83A6	0x2628	0x0398	# GREEK CAPITAL LETTER THETA
0x83A7	0x2629	0x0399	# GREEK CAPITAL LETTER IOTA
0x83A8	0x262A	0x039A	# GREEK CAPITAL LETTER KAPPA
0x83A9	0x262B	0x039B	# GREEK CAPITAL LETTER LAMDA
0x83AA	0x262C	0x039C	# GREEK CAPITAL LETTER MU
0x83AB	0x262D	0x039D	# GREEK CAPITAL LETTER NU
0x83AC	0x262E	0x039E	# GREEK CAPITAL LETTER XI
0x83AD	0x262F	0x039F	# GREEK CAPITAL LETTER OMICRON
0x83AE	0x2630	0x03A0	# GREEK CAPITAL LETTER PI
0x83AF	0x2631	0x03A1	# GREEK CAPITAL LETTER RHO
0x83B0	0x2632	0x03A3	# GREEK CAPITAL LETTER SIGMA
0x83B1	0x2633	0x03A4	# GREEK CAPITAL LETTER TAU
0x83B2	0x2634	0x03A5	# GREEK CAPITAL LETTER UPSILON
0x83B3	0x2635	0x03A6	# GREEK CAPITAL LETTER PHI
0x83B4	0x2636	0x03A7	# GREEK CAPITAL LETTER CHI
0x83B5	0x2637	0x03A8	# GREEK CAPITAL LETTER PSI
0x83B6	0x2638	0x03A9	# GREEK CAPITAL LETTER OMEGA
0x83BF	0x2641	0x03B1	# GREEK SMALL LETTER ALPHA
0x83C0	0x2642	0x03B2	# GREEK SMALL LETTER BETA
0x83C1	0x2643	0x03B3	# GREEK SMALL LETTER GAMMA
0x83C2	0x2644	0x03B4	# GREEK SMALL LETTER DELTA
0x83C3	0x2645	0x03B5	# GREEK SMALL LETTER EPSILON
0x83C4	0x2646	0x03B6	# GREEK SMALL LETTER ZETA
0x83C5	0x2647	0x03B7	# GREEK SMALL LETTER ETA
0x83C6	0x2648	0x03B8	# GREEK SMALL LETTER THETA
0x83C7	0x2649	0x03B9	# GREEK SMALL LETTER IOTA
0x83C8	0x264A	0x03BA	# GREEK SMALL LETTER KAPPA
0x83C9	0x264B	0x03BB	# GREEK SMALL LETTER LAMDA
0x83CA	0x264C	0x03BC	# GREEK SMALL LETTER MU
0x83CB	0x264D	0x03BD	# GREEK SMALL LETTER NU
0x83CC	0x264E	0x03BE	# GREEK SMALL LETTER XI
0x83CD	0x264F	0x03BF	# GREEK SMALL LETTER OMICRON
0x83CE	0x2650	0x03C0	# GREEK SMALL LETTER PI
0x83CF	0x2651	0x03C1	# GREEK SMALL LETTER RHO
0x83D0	0x2652	0x03C3	# GREEK SMALL LETTER SIGMA
0x83D1	0x2653	0x03C4	# GREEK SMALL LETTER TAU
0x83D2	0x2654	0x03C5	# GREEK SMALL LETTER UPSILON
0x83D3	0x2655	0x03C6	# GREEK SMALL LETTER PHI
0x83D4	0x2656	0x03C7	# GREEK SMALL LETTER CHI
0x83D5	0x2657	0x03C8	# GREEK SMALL LETTER PSI
0x83D6	0x2658	0x03C9	# GREEK SMALL LETTER OMEGA
0x8440	0x2721	0x0410	# CYRILLIC CAPITAL LETTER A
0x8441	0x2722	0x0411	# CYRILLIC CAPITAL LETTER BE
0x8442	0x2723	0x0412	# CYRILLIC CAPITAL LETTER VE
0x8443	0x2724	0x0413	# CYRILLIC CAPITAL LETTER GHE
0x8444	0x2725	0x0414	# CYRILLIC CAPITAL LETTER DE
0x8445	0x2726	0x0415	# CYRILLIC CAPITAL LETTER IE
0x8446	0x2727	0x0401	# CYRILLIC CAPITAL LETTER IO
0x8447	0x2728	0x0416	# CYRILLIC CAPITAL LETTER ZHE
0x8448	0x2729	0x0417	# CYRILLIC CAPITAL LETTER ZE
0x8449	0x272A	0x0418	# CYRILLIC CAPITAL LETTER I
0x844A	0x272B	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
0x844B	0x272C	0x041A	# CYRILLIC CAPITAL LETTER KA
0x844C	0x272D	0x041B	# CYRILLIC CAPITAL LETTER EL
0x844D	0x272E	0x041C	# CYRILLIC CAPITAL LETTER EM
0x844E	0x272F	0x041D	# CYRILLIC CAPITAL LETTER EN
0x844F	0x2730	0x041E	# CYRILLIC CAPITAL LETTER O
0x8450	0x2731	0x041F	# CYRILLIC CAPITAL LETTER PE
0x8451	0x2732	0x0420	# CYRILLIC CAPITAL LETTER ER
0x8452	0x2733	0x0421	# CYRILLIC CAPITAL LETTER ES
0x8453	0x2734	0x0422	# CYRILLIC CAPITAL LETTER TE
0x8454	0x2735	0x0423	# CYRILLIC CAPITAL LETTER U
0x8455	0x2736	0x0424	# CYRILLIC CAPITAL LETTER EF
0x8456	0x2737	0x0425	# CYRILLIC CAPITAL LETTER HA
0x8457	0x2738	0x0426	# CYRILLIC CAPITAL LETTER TSE
0x8458	0x2739	0x0427	# CYRILLIC CAPITAL LETTER CHE
0x8459	0x273A	0x0428	# CYRILLIC CAPITAL LETTER SHA
0x845A	0x273B	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
0x845B	0x273C	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
0x845C	0x273D	0x042B	# CYRILLIC CAPITAL LETTER YERU
0x845D	0x273E	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
0x845E	0x273F	0x042D	# CYRILLIC CAPITAL LETTER E
0x845F	0x2740	0x042E	# CYRILLIC CAPITAL LETTER YU
0x8460	0x2741	0x042F	# CYRILLIC CAPITAL LETTER YA
0x8470	0x2751	0x0430	# CYRILLIC SMALL LETTER A
0x8471	0x2752	0x0431	# CYRILLIC SMALL LETTER BE
0x8472	0x2753	0x0432	# CYRILLIC SMALL LETTER VE
0x8473	0x2754	0x0433	# CYRILLIC SMALL LETTER GHE
0x8474	0x2755	0x0434	# CYRILLIC SMALL LETTER DE
0x8475	0x2756	0x0435	# CYRILLIC SMALL LETTER IE
0x8476	0x2757	0x0451	# CYRILLIC SMALL LETTER IO
0x8477	0x2758	0x0436	# CYRILLIC SMALL LETTER ZHE
0x8478	0x2759	0x0437	# CYRILLIC SMALL LETTER ZE
0x8479	0x275A	0x0438	# CYRILLIC SMALL LETTER I
0x847A	0x275B	0x0439	# CYRILLIC SMALL LETTER SHORT I
0x847B	0x275C	0x043A	# CYRILLIC SMALL LETTER KA
0x847C	0x275D	0x043B	# CYRILLIC SMALL LETTER EL
0x847D	0x275E	0x043C	# CYRILLIC SMALL LETTER EM
0x847E	0x275F	0x043D	# CYRILLIC SMALL LETTER EN
0x8480	0x2760	0x043E	# CYRILLIC SMALL LETTER O
0x8481	0x2761	0x043F	# CYRILLIC SMALL LETTER PE
0x8482	0x2762	0x0440	# CYRILLIC SMALL LETTER ER
0x8483	0x2763	0x0441	# CYRILLIC SMALL LETTER ES
0x8484	0x2764	0x0442	# CYRILLIC SMALL LETTER TE
0x8485	0x2765	0x0443	# CYRILLIC SMALL LETTER U
0x8486	0x2766	0x0444	# CYRILLIC SMALL LETTER EF
0x8487	0x2767	0x0445	# CYRILLIC SMALL LETTER HA
0x8488	0x2768	0x0446	# CYRILLIC SMALL LETTER TSE
0x8489	0x2769	0x0447	# CYRILLIC SMALL LETTER CHE
0x848A	0x276A	0x0448	# CYRILLIC SMALL LETTER SHA
0x848B	0x276B	0x0449	# CYRILLIC SMALL LETTER SHCHA
0x848C	0x276C	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
0x848D	0x276D	0x044B	# CYRILLIC SMALL LETTER YERU
0x848E	0x276E	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
0x848F	0x276F	0x044D	# CYRILLIC SMALL LETTER E
0x8490	0x2770	0x044E	# CYRILLIC SMALL LETTER YU
0x8491	0x2771	0x044F	# CYRILLIC SMALL LETTER YA
0x849F	0x2821	0x2500	# BOX DRAWINGS LIGHT HORIZONTAL
0x84A0	0x2822	0x2502	# BOX DRAWINGS LIGHT VERTICAL
0x84A1	0x2823	0x250C	# BOX DRAWINGS LIGHT DOWN AND RIGHT
0x84A2	0x2824	0x2510	# BOX DRAWINGS LIGHT DOWN AND LEFT
0x84A3	0x2825	0x2518	# BOX DRAWINGS LIGHT UP AND LEFT
0x84A4	0x2826	0x2514	# BOX DRAWINGS LIGHT UP AND RIGHT
0x84A5	0x2827	0x251C	# BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0x84A6	0x2828	0x252C	# BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0x84A7	0x2829	0x2524	# BOX DRAWINGS LIGHT VERTICAL AND LEFT
0x84A8	0x282A	0x2534	# BOX DRAWINGS LIGHT UP AND HORIZONTAL
0x84A9	0x282B	0x253C	# BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0x84AA	0x282C	0x2501	# BOX DRAWINGS HEAVY HORIZONTAL
0x84AB	0x282D	0x2503	# BOX DRAWINGS HEAVY VERTICAL
0x84AC	0x282E	0x250F	# BOX DRAWINGS HEAVY DOWN AND RIGHT
0x84AD	0x282F	0x2513	# BOX DRAWINGS HEAVY DOWN AND LEFT
0x84AE	0x2830	0x251B	# BOX DRAWINGS HEAVY UP AND LEFT
0x84AF	0x2831	0x2517	# BOX DRAWINGS HEAVY UP AND RIGHT
0x84B0	0x2832	0x2523	# BOX DRAWINGS HEAVY VERTICAL AND RIGHT
0x84B1	0x2833	0x2533	# BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
0x84B2	0x2834	0x252B	# BOX DRAWINGS HEAVY VERTICAL AND LEFT
0x84B3	0x2835	0x253B	# BOX DRAWINGS HEAVY UP AND HORIZONTAL
0x84B4	0x2836	0x254B	# BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
0x84B5	0x2837	0x2520	# BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
0x84B6	0x2838	0x252F	# BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
0x84B7	0x2839	0x2528	# BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
0x84B8	0x283A	0x2537	# BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
0x84B9	0x283B	0x253F	# BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
0x84BA	0x283C	0x251D	# BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
0x84BB	0x283D	0x2530	# BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
0x84BC	0x283E	0x2525	# BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
0x84BD	0x283F	0x2538	# BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
0x84BE	0x2840	0x2542	# BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
0x889F	0x3021	0x4E9C	# <CJK>
0x88A0	0x3022	0x5516	# <CJK>
0x88A1	0x3023	0x5A03	# <CJK>
0x88A2	0x3024	0x963F	# <CJK>
0x88A3	0x3025	0x54C0	# <CJK>
0x88A4	0x3026	0x611B	# <CJK>
0x88A5	0x3027	0x6328	# <CJK>
0x88A6	0x3028	0x59F6	# <CJK>
0x88A7	0x3029	0x9022	# <CJK>
0x88A8	0x302A	0x8475	# <CJK>
0x88A9	0x302B	0x831C	# <CJK>
0x88AA	0x302C	0x7A50	# <CJK>
0x88AB	0x302D	0x60AA	# <CJK>
0x88AC	0x302E	0x63E1	# <CJK>
0x88AD	0x302F	0x6E25	# <CJK>
0x88AE	0x3030	0x65ED	# <CJK>
0x88AF	0x3031	0x8466	# <CJK>
0x88B0	0x3032	0x82A6	# <CJK>
0x88B1	0x3033	0x9BF5	# <CJK>
0x88B2	0x3034	0x6893	# <CJK>
0x88B3	0x3035	0x5727	# <CJK>
0x88B4	0x3036	0x65A1	# <CJK>
0x88B5	0x3037	0x6271	# <CJK>
0x88B6	0x3038	0x5B9B	# <CJK>
0x88B7	0x3039	0x59D0	# <CJK>
0x88B8	0x303A	0x867B	# <CJK>
0x88B9	0x303B	0x98F4	# <CJK>
0x88BA	0x303C	0x7D62	# <CJK>
0x88BB	0x303D	0x7DBE	# <CJK>
0x88BC	0x303E	0x9B8E	# <CJK>
0x88BD	0x303F	0x6216	# <CJK>
0x88BE	0x3040	0x7C9F	# <CJK>
0x88BF	0x3041	0x88B7	# <CJK>
0x88C0	0x3042	0x5B89	# <CJK>
0x88C1	0x3043	0x5EB5	# <CJK>
0x88C2	0x3044	0x6309	# <CJK>
0x88C3	0x3045	0x6697	# <CJK>
0x88C4	0x3046	0x6848	# <CJK>
0x88C5	0x3047	0x95C7	# <CJK>
0x88C6	0x3048	0x978D	# <CJK>
0x88C7	0x3049	0x674F	# <CJK>
0x88C8	0x304A	0x4EE5	# <CJK>
0x88C9	0x304B	0x4F0A	# <CJK>
0x88CA	0x304C	0x4F4D	# <CJK>
0x88CB	0x304D	0x4F9D	# <CJK>
0x88CC	0x304E	0x5049	# <CJK>
0x88CD	0x304F	0x56F2	# <CJK>
0x88CE	0x3050	0x5937	# <CJK>
0x88CF	0x3051	0x59D4	# <CJK>
0x88D0	0x3052	0x5A01	# <CJK>
0x88D1	0x3053	0x5C09	# <CJK>
0x88D2	0x3054	0x60DF	# <CJK>
0x88D3	0x3055	0x610F	# <CJK>
0x88D4	0x3056	0x6170	# <CJK>
0x88D5	0x3057	0x6613	# <CJK>
0x88D6	0x3058	0x6905	# <CJK>
0x88D7	0x3059	0x70BA	# <CJK>
0x88D8	0x305A	0x754F	# <CJK>
0x88D9	0x305B	0x7570	# <CJK>
0x88DA	0x305C	0x79FB	# <CJK>
0x88DB	0x305D	0x7DAD	# <CJK>
0x88DC	0x305E	0x7DEF	# <CJK>
0x88DD	0x305F	0x80C3	# <CJK>
0x88DE	0x3060	0x840E	# <CJK>
0x88DF	0x3061	0x8863	# <CJK>
0x88E0	0x3062	0x8B02	# <CJK>
0x88E1	0x3063	0x9055	# <CJK>
0x88E2	0x3064	0x907A	# <CJK>
0x88E3	0x3065	0x533B	# <CJK>
0x88E4	0x3066	0x4E95	# <CJK>
0x88E5	0x3067	0x4EA5	# <CJK>
0x88E6	0x3068	0x57DF	# <CJK>
0x88E7	0x3069	0x80B2	# <CJK>
0x88E8	0x306A	0x90C1	# <CJK>
0x88E9	0x306B	0x78EF	# <CJK>
0x88EA	0x306C	0x4E00	# <CJK>
0x88EB	0x306D	0x58F1	# <CJK>
0x88EC	0x306E	0x6EA2	# <CJK>
0x88ED	0x306F	0x9038	# <CJK>
0x88EE	0x3070	0x7A32	# <CJK>
0x88EF	0x3071	0x8328	# <CJK>
0x88F0	0x3072	0x828B	# <CJK>
0x88F1	0x3073	0x9C2F	# <CJK>
0x88F2	0x3074	0x5141	# <CJK>
0x88F3	0x3075	0x5370	# <CJK>
0x88F4	0x3076	0x54BD	# <CJK>
0x88F5	0x3077	0x54E1	# <CJK>
0x88F6	0x3078	0x56E0	# <CJK>
0x88F7	0x3079	0x59FB	# <CJK>
0x88F8	0x307A	0x5F15	# <CJK>
0x88F9	0x307B	0x98F2	# <CJK>
0x88FA	0x307C	0x6DEB	# <CJK>
0x88FB	0x307D	0x80E4	# <CJK>
0x88FC	0x307E	0x852D	# <CJK>
0x8940	0x3121	0x9662	# <CJK>
0x8941	0x3122	0x9670	# <CJK>
0x8942	0x3123	0x96A0	# <CJK>
0x8943	0x3124	0x97FB	# <CJK>
0x8944	0x3125	0x540B	# <CJK>
0x8945	0x3126	0x53F3	# <CJK>
0x8946	0x3127	0x5B87	# <CJK>
0x8947	0x3128	0x70CF	# <CJK>
0x8948	0x3129	0x7FBD	# <CJK>
0x8949	0x312A	0x8FC2	# <CJK>
0x894A	0x312B	0x96E8	# <CJK>
0x894B	0x312C	0x536F	# <CJK>
0x894C	0x312D	0x9D5C	# <CJK>
0x894D	0x312E	0x7ABA	# <CJK>
0x894E	0x312F	0x4E11	# <CJK>
0x894F	0x3130	0x7893	# <CJK>
0x8950	0x3131	0x81FC	# <CJK>
0x8951	0x3132	0x6E26	# <CJK>
0x8952	0x3133	0x5618	# <CJK>
0x8953	0x3134	0x5504	# <CJK>
0x8954	0x3135	0x6B1D	# <CJK>
0x8955	0x3136	0x851A	# <CJK>
0x8956	0x3137	0x9C3B	# <CJK>
0x8957	0x3138	0x59E5	# <CJK>
0x8958	0x3139	0x53A9	# <CJK>
0x8959	0x313A	0x6D66	# <CJK>
0x895A	0x313B	0x74DC	# <CJK>
0x895B	0x313C	0x958F	# <CJK>
0x895C	0x313D	0x5642	# <CJK>
0x895D	0x313E	0x4E91	# <CJK>
0x895E	0x313F	0x904B	# <CJK>
0x895F	0x3140	0x96F2	# <CJK>
0x8960	0x3141	0x834F	# <CJK>
0x8961	0x3142	0x990C	# <CJK>
0x8962	0x3143	0x53E1	# <CJK>
0x8963	0x3144	0x55B6	# <CJK>
0x8964	0x3145	0x5B30	# <CJK>
0x8965	0x3146	0x5F71	# <CJK>
0x8966	0x3147	0x6620	# <CJK>
0x8967	0x3148	0x66F3	# <CJK>
0x8968	0x3149	0x6804	# <CJK>
0x8969	0x314A	0x6C38	# <CJK>
0x896A	0x314B	0x6CF3	# <CJK>
0x896B	0x314C	0x6D29	# <CJK>
0x896C	0x314D	0x745B	# <CJK>
0x896D	0x314E	0x76C8	# <CJK>
0x896E	0x314F	0x7A4E	# <CJK>
0x896F	0x3150	0x9834	# <CJK>
0x8970	0x3151	0x82F1	# <CJK>
0x8971	0x3152	0x885B	# <CJK>
0x8972	0x3153	0x8A60	# <CJK>
0x8973	0x3154	0x92ED	# <CJK>
0x8974	0x3155	0x6DB2	# <CJK>
0x8975	0x3156	0x75AB	# <CJK>
0x8976	0x3157	0x76CA	# <CJK>
0x8977	0x3158	0x99C5	# <CJK>
0x8978	0x3159	0x60A6	# <CJK>
0x8979	0x315A	0x8B01	# <CJK>
0x897A	0x315B	0x8D8A	# <CJK>
0x897B	0x315C	0x95B2	# <CJK>
0x897C	0x315D	0x698E	# <CJK>
0x897D	0x315E	0x53AD	# <CJK>
0x897E	0x315F	0x5186	# <CJK>
0x8980	0x3160	0x5712	# <CJK>
0x8981	0x3161	0x5830	# <CJK>
0x8982	0x3162	0x5944	# <CJK>
0x8983	0x3163	0x5BB4	# <CJK>
0x8984	0x3164	0x5EF6	# <CJK>
0x8985	0x3165	0x6028	# <CJK>
0x8986	0x3166	0x63A9	# <CJK>
0x8987	0x3167	0x63F4	# <CJK>
0x8988	0x3168	0x6CBF	# <CJK>
0x8989	0x3169	0x6F14	# <CJK>
0x898A	0x316A	0x708E	# <CJK>
0x898B	0x316B	0x7114	# <CJK>
0x898C	0x316C	0x7159	# <CJK>
0x898D	0x316D	0x71D5	# <CJK>
0x898E	0x316E	0x733F	# <CJK>
0x898F	0x316F	0x7E01	# <CJK>
0x8990	0x3170	0x8276	# <CJK>
0x8991	0x3171	0x82D1	# <CJK>
0x8992	0x3172	0x8597	# <CJK>
0x8993	0x3173	0x9060	# <CJK>
0x8994	0x3174	0x925B	# <CJK>
0x8995	0x3175	0x9D1B	# <CJK>
0x8996	0x3176	0x5869	# <CJK>
0x8997	0x3177	0x65BC	# <CJK>
0x8998	0x3178	0x6C5A	# <CJK>
0x8999	0x3179	0x7525	# <CJK>
0x899A	0x317A	0x51F9	# <CJK>
0x899B	0x317B	0x592E	# <CJK>
0x899C	0x317C	0x5965	# <CJK>
0x899D	0x317D	0x5F80	# <CJK>
0x899E	0x317E	0x5FDC	# <CJK>
0x899F	0x3221	0x62BC	# <CJK>
0x89A0	0x3222	0x65FA	# <CJK>
0x89A1	0x3223	0x6A2A	# <CJK>
0x89A2	0x3224	0x6B27	# <CJK>
0x89A3	0x3225	0x6BB4	# <CJK>
0x89A4	0x3226	0x738B	# <CJK>
0x89A5	0x3227	0x7FC1	# <CJK>
0x89A6	0x3228	0x8956	# <CJK>
0x89A7	0x3229	0x9D2C	# <CJK>
0x89A8	0x322A	0x9D0E	# <CJK>
0x89A9	0x322B	0x9EC4	# <CJK>
0x89AA	0x322C	0x5CA1	# <CJK>
0x89AB	0x322D	0x6C96	# <CJK>
0x89AC	0x322E	0x837B	# <CJK>
0x89AD	0x322F	0x5104	# <CJK>
0x89AE	0x3230	0x5C4B	# <CJK>
0x89AF	0x3231	0x61B6	# <CJK>
0x89B0	0x3232	0x81C6	# <CJK>
0x89B1	0x3233	0x6876	# <CJK>
0x89B2	0x3234	0x7261	# <CJK>
0x89B3	0x3235	0x4E59	# <CJK>
0x89B4	0x3236	0x4FFA	# <CJK>
0x89B5	0x3237	0x5378	# <CJK>
0x89B6	0x3238	0x6069	# <CJK>
0x89B7	0x3239	0x6E29	# <CJK>
0x89B8	0x323A	0x7A4F	# <CJK>
0x89B9	0x323B	0x97F3	# <CJK>
0x89BA	0x323C	0x4E0B	# <CJK>
0x89BB	0x323D	0x5316	# <CJK>
0x89BC	0x323E	0x4EEE	# <CJK>
0x89BD	0x323F	0x4F55	# <CJK>
0x89BE	0x3240	0x4F3D	# <CJK>
0x89BF	0x3241	0x4FA1	# <CJK>
0x89C0	0x3242	0x4F73	# <CJK>
0x89C1	0x3243	0x52A0	# <CJK>
0x89C2	0x3244	0x53EF	# <CJK>
0x89C3	0x3245	0x5609	# <CJK>
0x89C4	0x3246	0x590F	# <CJK>
0x89C5	0x3247	0x5AC1	# <CJK>
0x89C6	0x3248	0x5BB6	# <CJK>
0x89C7	0x3249	0x5BE1	# <CJK>
0x89C8	0x324A	0x79D1	# <CJK>
0x89C9	0x324B	0x6687	# <CJK>
0x89CA	0x324C	0x679C	# <CJK>
0x89CB	0x324D	0x67B6	# <CJK>
0x89CC	0x324E	0x6B4C	# <CJK>
0x89CD	0x324F	0x6CB3	# <CJK>
0x89CE	0x3250	0x706B	# <CJK>
0x89CF	0x3251	0x73C2	# <CJK>
0x89D0	0x3252	0x798D	# <CJK>
0x89D1	0x3253	0x79BE	# <CJK>
0x89D2	0x3254	0x7A3C	# <CJK>
0x89D3	0x3255	0x7B87	# <CJK>
0x89D4	0x3256	0x82B1	# <CJK>
0x89D5	0x3257	0x82DB	# <CJK>
0x89D6	0x3258	0x8304	# <CJK>
0x89D7	0x3259	0x8377	# <CJK>
0x89D8	0x325A	0x83EF	# <CJK>
0x89D9	0x325B	0x83D3	# <CJK>
0x89DA	0x325C	0x8766	# <CJK>
0x89DB	0x325D	0x8AB2	# <CJK>
0x89DC	0x325E	0x5629	# <CJK>
0x89DD	0x325F	0x8CA8	# <CJK>
0x89DE	0x3260	0x8FE6	# <CJK>
0x89DF	0x3261	0x904E	# <CJK>
0x89E0	0x3262	0x971E	# <CJK>
0x89E1	0x3263	0x868A	# <CJK>
0x89E2	0x3264	0x4FC4	# <CJK>
0x89E3	0x3265	0x5CE8	# <CJK>
0x89E4	0x3266	0x6211	# <CJK>
0x89E5	0x3267	0x7259	# <CJK>
0x89E6	0x3268	0x753B	# <CJK>
0x89E7	0x3269	0x81E5	# <CJK>
0x89E8	0x326A	0x82BD	# <CJK>
0x89E9	0x326B	0x86FE	# <CJK>
0x89EA	0x326C	0x8CC0	# <CJK>
0x89EB	0x326D	0x96C5	# <CJK>
0x89EC	0x326E	0x9913	# <CJK>
0x89ED	0x326F	0x99D5	# <CJK>
0x89EE	0x3270	0x4ECB	# <CJK>
0x89EF	0x3271	0x4F1A	# <CJK>
0x89F0	0x3272	0x89E3	# <CJK>
0x89F1	0x3273	0x56DE	# <CJK>
0x89F2	0x3274	0x584A	# <CJK>
0x89F3	0x3275	0x58CA	# <CJK>
0x89F4	0x3276	0x5EFB	# <CJK>
0x89F5	0x3277	0x5FEB	# <CJK>
0x89F6	0x3278	0x602A	# <CJK>
0x89F7	0x3279	0x6094	# <CJK>
0x89F8	0x327A	0x6062	# <CJK>
0x89F9	0x327B	0x61D0	# <CJK>
0x89FA	0x327C	0x6212	# <CJK>
0x89FB	0x327D	0x62D0	# <CJK>
0x89FC	0x327E	0x6539	# <CJK>
0x8A40	0x3321	0x9B41	# <CJK>
0x8A41	0x3322	0x6666	# <CJK>
0x8A42	0x3323	0x68B0	# <CJK>
0x8A43	0x3324	0x6D77	# <CJK>
0x8A44	0x3325	0x7070	# <CJK>
0x8A45	0x3326	0x754C	# <CJK>
0x8A46	0x3327	0x7686	# <CJK>
0x8A47	0x3328	0x7D75	# <CJK>
0x8A48	0x3329	0x82A5	# <CJK>
0x8A49	0x332A	0x87F9	# <CJK>
0x8A4A	0x332B	0x958B	# <CJK>
0x8A4B	0x332C	0x968E	# <CJK>
0x8A4C	0x332D	0x8C9D	# <CJK>
0x8A4D	0x332E	0x51F1	# <CJK>
0x8A4E	0x332F	0x52BE	# <CJK>
0x8A4F	0x3330	0x5916	# <CJK>
0x8A50	0x3331	0x54B3	# <CJK>
0x8A51	0x3332	0x5BB3	# <CJK>
0x8A52	0x3333	0x5D16	# <CJK>
0x8A53	0x3334	0x6168	# <CJK>
0x8A54	0x3335	0x6982	# <CJK>
0x8A55	0x3336	0x6DAF	# <CJK>
0x8A56	0x3337	0x788D	# <CJK>
0x8A57	0x3338	0x84CB	# <CJK>
0x8A58	0x3339	0x8857	# <CJK>
0x8A59	0x333A	0x8A72	# <CJK>
0x8A5A	0x333B	0x93A7	# <CJK>
0x8A5B	0x333C	0x9AB8	# <CJK>
0x8A5C	0x333D	0x6D6C	# <CJK>
0x8A5D	0x333E	0x99A8	# <CJK>
0x8A5E	0x333F	0x86D9	# <CJK>
0x8A5F	0x3340	0x57A3	# <CJK>
0x8A60	0x3341	0x67FF	# <CJK>
0x8A61	0x3342	0x86CE	# <CJK>
0x8A62	0x3343	0x920E	# <CJK>
0x8A63	0x3344	0x5283	# <CJK>
0x8A64	0x3345	0x5687	# <CJK>
0x8A65	0x3346	0x5404	# <CJK>
0x8A66	0x3347	0x5ED3	# <CJK>
0x8A67	0x3348	0x62E1	# <CJK>
0x8A68	0x3349	0x64B9	# <CJK>
0x8A69	0x334A	0x683C	# <CJK>
0x8A6A	0x334B	0x6838	# <CJK>
0x8A6B	0x334C	0x6BBB	# <CJK>
0x8A6C	0x334D	0x7372	# <CJK>
0x8A6D	0x334E	0x78BA	# <CJK>
0x8A6E	0x334F	0x7A6B	# <CJK>
0x8A6F	0x3350	0x899A	# <CJK>
0x8A70	0x3351	0x89D2	# <CJK>
0x8A71	0x3352	0x8D6B	# <CJK>
0x8A72	0x3353	0x8F03	# <CJK>
0x8A73	0x3354	0x90ED	# <CJK>
0x8A74	0x3355	0x95A3	# <CJK>
0x8A75	0x3356	0x9694	# <CJK>
0x8A76	0x3357	0x9769	# <CJK>
0x8A77	0x3358	0x5B66	# <CJK>
0x8A78	0x3359	0x5CB3	# <CJK>
0x8A79	0x335A	0x697D	# <CJK>
0x8A7A	0x335B	0x984D	# <CJK>
0x8A7B	0x335C	0x984E	# <CJK>
0x8A7C	0x335D	0x639B	# <CJK>
0x8A7D	0x335E	0x7B20	# <CJK>
0x8A7E	0x335F	0x6A2B	# <CJK>
0x8A80	0x3360	0x6A7F	# <CJK>
0x8A81	0x3361	0x68B6	# <CJK>
0x8A82	0x3362	0x9C0D	# <CJK>
0x8A83	0x3363	0x6F5F	# <CJK>
0x8A84	0x3364	0x5272	# <CJK>
0x8A85	0x3365	0x559D	# <CJK>
0x8A86	0x3366	0x6070	# <CJK>
0x8A87	0x3367	0x62EC	# <CJK>
0x8A88	0x3368	0x6D3B	# <CJK>
0x8A89	0x3369	0x6E07	# <CJK>
0x8A8A	0x336A	0x6ED1	# <CJK>
0x8A8B	0x336B	0x845B	# <CJK>
0x8A8C	0x336C	0x8910	# <CJK>
0x8A8D	0x336D	0x8F44	# <CJK>
0x8A8E	0x336E	0x4E14	# <CJK>
0x8A8F	0x336F	0x9C39	# <CJK>
0x8A90	0x3370	0x53F6	# <CJK>
0x8A91	0x3371	0x691B	# <CJK>
0x8A92	0x3372	0x6A3A	# <CJK>
0x8A93	0x3373	0x9784	# <CJK>
0x8A94	0x3374	0x682A	# <CJK>
0x8A95	0x3375	0x515C	# <CJK>
0x8A96	0x3376	0x7AC3	# <CJK>
0x8A97	0x3377	0x84B2	# <CJK>
0x8A98	0x3378	0x91DC	# <CJK>
0x8A99	0x3379	0x938C	# <CJK>
0x8A9A	0x337A	0x565B	# <CJK>
0x8A9B	0x337B	0x9D28	# <CJK>
0x8A9C	0x337C	0x6822	# <CJK>
0x8A9D	0x337D	0x8305	# <CJK>
0x8A9E	0x337E	0x8431	# <CJK>
0x8A9F	0x3421	0x7CA5	# <CJK>
0x8AA0	0x3422	0x5208	# <CJK>
0x8AA1	0x3423	0x82C5	# <CJK>
0x8AA2	0x3424	0x74E6	# <CJK>
0x8AA3	0x3425	0x4E7E	# <CJK>
0x8AA4	0x3426	0x4F83	# <CJK>
0x8AA5	0x3427	0x51A0	# <CJK>
0x8AA6	0x3428	0x5BD2	# <CJK>
0x8AA7	0x3429	0x520A	# <CJK>
0x8AA8	0x342A	0x52D8	# <CJK>
0x8AA9	0x342B	0x52E7	# <CJK>
0x8AAA	0x342C	0x5DFB	# <CJK>
0x8AAB	0x342D	0x559A	# <CJK>
0x8AAC	0x342E	0x582A	# <CJK>
0x8AAD	0x342F	0x59E6	# <CJK>
0x8AAE	0x3430	0x5B8C	# <CJK>
0x8AAF	0x3431	0x5B98	# <CJK>
0x8AB0	0x3432	0x5BDB	# <CJK>
0x8AB1	0x3433	0x5E72	# <CJK>
0x8AB2	0x3434	0x5E79	# <CJK>
0x8AB3	0x3435	0x60A3	# <CJK>
0x8AB4	0x3436	0x611F	# <CJK>
0x8AB5	0x3437	0x6163	# <CJK>
0x8AB6	0x3438	0x61BE	# <CJK>
0x8AB7	0x3439	0x63DB	# <CJK>
0x8AB8	0x343A	0x6562	# <CJK>
0x8AB9	0x343B	0x67D1	# <CJK>
0x8ABA	0x343C	0x6853	# <CJK>
0x8ABB	0x343D	0x68FA	# <CJK>
0x8ABC	0x343E	0x6B3E	# <CJK>
0x8ABD	0x343F	0x6B53	# <CJK>
0x8ABE	0x3440	0x6C57	# <CJK>
0x8ABF	0x3441	0x6F22	# <CJK>
0x8AC0	0x3442	0x6F97	# <CJK>
0x8AC1	0x3443	0x6F45	# <CJK>
0x8AC2	0x3444	0x74B0	# <CJK>
0x8AC3	0x3445	0x7518	# <CJK>
0x8AC4	0x3446	0x76E3	# <CJK>
0x8AC5	0x3447	0x770B	# <CJK>
0x8AC6	0x3448	0x7AFF	# <CJK>
0x8AC7	0x3449	0x7BA1	# <CJK>
0x8AC8	0x344A	0x7C21	# <CJK>
0x8AC9	0x344B	0x7DE9	# <CJK>
0x8ACA	0x344C	0x7F36	# <CJK>
0x8ACB	0x344D	0x7FF0	# <CJK>
0x8ACC	0x344E	0x809D	# <CJK>
0x8ACD	0x344F	0x8266	# <CJK>
0x8ACE	0x3450	0x839E	# <CJK>
0x8ACF	0x3451	0x89B3	# <CJK>
0x8AD0	0x3452	0x8ACC	# <CJK>
0x8AD1	0x3453	0x8CAB	# <CJK>
0x8AD2	0x3454	0x9084	# <CJK>
0x8AD3	0x3455	0x9451	# <CJK>
0x8AD4	0x3456	0x9593	# <CJK>
0x8AD5	0x3457	0x9591	# <CJK>
0x8AD6	0x3458	0x95A2	# <CJK>
0x8AD7	0x3459	0x9665	# <CJK>
0x8AD8	0x345A	0x97D3	# <CJK>
0x8AD9	0x345B	0x9928	# <CJK>
0x8ADA	0x345C	0x8218	# <CJK>
0x8ADB	0x345D	0x4E38	# <CJK>
0x8ADC	0x345E	0x542B	# <CJK>
0x8ADD	0x345F	0x5CB8	# <CJK>
0x8ADE	0x3460	0x5DCC	# <CJK>
0x8ADF	0x3461	0x73A9	# <CJK>
0x8AE0	0x3462	0x764C	# <CJK>
0x8AE1	0x3463	0x773C	# <CJK>
0x8AE2	0x3464	0x5CA9	# <CJK>
0x8AE3	0x3465	0x7FEB	# <CJK>
0x8AE4	0x3466	0x8D0B	# <CJK>
0x8AE5	0x3467	0x96C1	# <CJK>
0x8AE6	0x3468	0x9811	# <CJK>
0x8AE7	0x3469	0x9854	# <CJK>
0x8AE8	0x346A	0x9858	# <CJK>
0x8AE9	0x346B	0x4F01	# <CJK>
0x8AEA	0x346C	0x4F0E	# <CJK>
0x8AEB	0x346D	0x5371	# <CJK>
0x8AEC	0x346E	0x559C	# <CJK>
0x8AED	0x346F	0x5668	# <CJK>
0x8AEE	0x3470	0x57FA	# <CJK>
0x8AEF	0x3471	0x5947	# <CJK>
0x8AF0	0x3472	0x5B09	# <CJK>
0x8AF1	0x3473	0x5BC4	# <CJK>
0x8AF2	0x3474	0x5C90	# <CJK>
0x8AF3	0x3475	0x5E0C	# <CJK>
0x8AF4	0x3476	0x5E7E	# <CJK>
0x8AF5	0x3477	0x5FCC	# <CJK>
0x8AF6	0x3478	0x63EE	# <CJK>
0x8AF7	0x3479	0x673A	# <CJK>
0x8AF8	0x347A	0x65D7	# <CJK>
0x8AF9	0x347B	0x65E2	# <CJK>
0x8AFA	0x347C	0x671F	# <CJK>
0x8AFB	0x347D	0x68CB	# <CJK>
0x8AFC	0x347E	0x68C4	# <CJK>
0x8B40	0x3521	0x6A5F	# <CJK>
0x8B41	0x3522	0x5E30	# <CJK>
0x8B42	0x3523	0x6BC5	# <CJK>
0x8B43	0x3524	0x6C17	# <CJK>
0x8B44	0x3525	0x6C7D	# <CJK>
0x8B45	0x3526	0x757F	# <CJK>
0x8B46	0x3527	0x7948	# <CJK>
0x8B47	0x3528	0x5B63	# <CJK>
0x8B48	0x3529	0x7A00	# <CJK>
0x8B49	0x352A	0x7D00	# <CJK>
0x8B4A	0x352B	0x5FBD	# <CJK>
0x8B4B	0x352C	0x898F	# <CJK>
0x8B4C	0x352D	0x8A18	# <CJK>
0x8B4D	0x352E	0x8CB4	# <CJK>
0x8B4E	0x352F	0x8D77	# <CJK>
0x8B4F	0x3530	0x8ECC	# <CJK>
0x8B50	0x3531	0x8F1D	# <CJK>
0x8B51	0x3532	0x98E2	# <CJK>
0x8B52	0x3533	0x9A0E	# <CJK>
0x8B53	0x3534	0x9B3C	# <CJK>
0x8B54	0x3535	0x4E80	# <CJK>
0x8B55	0x3536	0x507D	# <CJK>
0x8B56	0x3537	0x5100	# <CJK>
0x8B57	0x3538	0x5993	# <CJK>
0x8B58	0x3539	0x5B9C	# <CJK>
0x8B59	0x353A	0x622F	# <CJK>
0x8B5A	0x353B	0x6280	# <CJK>
0x8B5B	0x353C	0x64EC	# <CJK>
0x8B5C	0x353D	0x6B3A	# <CJK>
0x8B5D	0x353E	0x72A0	# <CJK>
0x8B5E	0x353F	0x7591	# <CJK>
0x8B5F	0x3540	0x7947	# <CJK>
0x8B60	0x3541	0x7FA9	# <CJK>
0x8B61	0x3542	0x87FB	# <CJK>
0x8B62	0x3543	0x8ABC	# <CJK>
0x8B63	0x3544	0x8B70	# <CJK>
0x8B64	0x3545	0x63AC	# <CJK>
0x8B65	0x3546	0x83CA	# <CJK>
0x8B66	0x3547	0x97A0	# <CJK>
0x8B67	0x3548	0x5409	# <CJK>
0x8B68	0x3549	0x5403	# <CJK>
0x8B69	0x354A	0x55AB	# <CJK>
0x8B6A	0x354B	0x6854	# <CJK>
0x8B6B	0x354C	0x6A58	# <CJK>
0x8B6C	0x354D	0x8A70	# <CJK>
0x8B6D	0x354E	0x7827	# <CJK>
0x8B6E	0x354F	0x6775	# <CJK>
0x8B6F	0x3550	0x9ECD	# <CJK>
0x8B70	0x3551	0x5374	# <CJK>
0x8B71	0x3552	0x5BA2	# <CJK>
0x8B72	0x3553	0x811A	# <CJK>
0x8B73	0x3554	0x8650	# <CJK>
0x8B74	0x3555	0x9006	# <CJK>
0x8B75	0x3556	0x4E18	# <CJK>
0x8B76	0x3557	0x4E45	# <CJK>
0x8B77	0x3558	0x4EC7	# <CJK>
0x8B78	0x3559	0x4F11	# <CJK>
0x8B79	0x355A	0x53CA	# <CJK>
0x8B7A	0x355B	0x5438	# <CJK>
0x8B7B	0x355C	0x5BAE	# <CJK>
0x8B7C	0x355D	0x5F13	# <CJK>
0x8B7D	0x355E	0x6025	# <CJK>
0x8B7E	0x355F	0x6551	# <CJK>
0x8B80	0x3560	0x673D	# <CJK>
0x8B81	0x3561	0x6C42	# <CJK>
0x8B82	0x3562	0x6C72	# <CJK>
0x8B83	0x3563	0x6CE3	# <CJK>
0x8B84	0x3564	0x7078	# <CJK>
0x8B85	0x3565	0x7403	# <CJK>
0x8B86	0x3566	0x7A76	# <CJK>
0x8B87	0x3567	0x7AAE	# <CJK>
0x8B88	0x3568	0x7B08	# <CJK>
0x8B89	0x3569	0x7D1A	# <CJK>
0x8B8A	0x356A	0x7CFE	# <CJK>
0x8B8B	0x356B	0x7D66	# <CJK>
0x8B8C	0x356C	0x65E7	# <CJK>
0x8B8D	0x356D	0x725B	# <CJK>
0x8B8E	0x356E	0x53BB	# <CJK>
0x8B8F	0x356F	0x5C45	# <CJK>
0x8B90	0x3570	0x5DE8	# <CJK>
0x8B91	0x3571	0x62D2	# <CJK>
0x8B92	0x3572	0x62E0	# <CJK>
0x8B93	0x3573	0x6319	# <CJK>
0x8B94	0x3574	0x6E20	# <CJK>
0x8B95	0x3575	0x865A	# <CJK>
0x8B96	0x3576	0x8A31	# <CJK>
0x8B97	0x3577	0x8DDD	# <CJK>
0x8B98	0x3578	0x92F8	# <CJK>
0x8B99	0x3579	0x6F01	# <CJK>
0x8B9A	0x357A	0x79A6	# <CJK>
0x8B9B	0x357B	0x9B5A	# <CJK>
0x8B9C	0x357C	0x4EA8	# <CJK>
0x8B9D	0x357D	0x4EAB	# <CJK>
0x8B9E	0x357E	0x4EAC	# <CJK>
0x8B9F	0x3621	0x4F9B	# <CJK>
0x8BA0	0x3622	0x4FA0	# <CJK>
0x8BA1	0x3623	0x50D1	# <CJK>
0x8BA2	0x3624	0x5147	# <CJK>
0x8BA3	0x3625	0x7AF6	# <CJK>
0x8BA4	0x3626	0x5171	# <CJK>
0x8BA5	0x3627	0x51F6	# <CJK>
0x8BA6	0x3628	0x5354	# <CJK>
0x8BA7	0x3629	0x5321	# <CJK>
0x8BA8	0x362A	0x537F	# <CJK>
0x8BA9	0x362B	0x53EB	# <CJK>
0x8BAA	0x362C	0x55AC	# <CJK>
0x8BAB	0x362D	0x5883	# <CJK>
0x8BAC	0x362E	0x5CE1	# <CJK>
0x8BAD	0x362F	0x5F37	# <CJK>
0x8BAE	0x3630	0x5F4A	# <CJK>
0x8BAF	0x3631	0x602F	# <CJK>
0x8BB0	0x3632	0x6050	# <CJK>
0x8BB1	0x3633	0x606D	# <CJK>
0x8BB2	0x3634	0x631F	# <CJK>
0x8BB3	0x3635	0x6559	# <CJK>
0x8BB4	0x3636	0x6A4B	# <CJK>
0x8BB5	0x3637	0x6CC1	# <CJK>
0x8BB6	0x3638	0x72C2	# <CJK>
0x8BB7	0x3639	0x72ED	# <CJK>
0x8BB8	0x363A	0x77EF	# <CJK>
0x8BB9	0x363B	0x80F8	# <CJK>
0x8BBA	0x363C	0x8105	# <CJK>
0x8BBB	0x363D	0x8208	# <CJK>
0x8BBC	0x363E	0x854E	# <CJK>
0x8BBD	0x363F	0x90F7	# <CJK>
0x8BBE	0x3640	0x93E1	# <CJK>
0x8BBF	0x3641	0x97FF	# <CJK>
0x8BC0	0x3642	0x9957	# <CJK>
0x8BC1	0x3643	0x9A5A	# <CJK>
0x8BC2	0x3644	0x4EF0	# <CJK>
0x8BC3	0x3645	0x51DD	# <CJK>
0x8BC4	0x3646	0x5C2D	# <CJK>
0x8BC5	0x3647	0x6681	# <CJK>
0x8BC6	0x3648	0x696D	# <CJK>
0x8BC7	0x3649	0x5C40	# <CJK>
0x8BC8	0x364A	0x66F2	# <CJK>
0x8BC9	0x364B	0x6975	# <CJK>
0x8BCA	0x364C	0x7389	# <CJK>
0x8BCB	0x364D	0x6850	# <CJK>
0x8BCC	0x364E	0x7C81	# <CJK>
0x8BCD	0x364F	0x50C5	# <CJK>
0x8BCE	0x3650	0x52E4	# <CJK>
0x8BCF	0x3651	0x5747	# <CJK>
0x8BD0	0x3652	0x5DFE	# <CJK>
0x8BD1	0x3653	0x9326	# <CJK>
0x8BD2	0x3654	0x65A4	# <CJK>
0x8BD3	0x3655	0x6B23	# <CJK>
0x8BD4	0x3656	0x6B3D	# <CJK>
0x8BD5	0x3657	0x7434	# <CJK>
0x8BD6	0x3658	0x7981	# <CJK>
0x8BD7	0x3659	0x79BD	# <CJK>
0x8BD8	0x365A	0x7B4B	# <CJK>
0x8BD9	0x365B	0x7DCA	# <CJK>
0x8BDA	0x365C	0x82B9	# <CJK>
0x8BDB	0x365D	0x83CC	# <CJK>
0x8BDC	0x365E	0x887F	# <CJK>
0x8BDD	0x365F	0x895F	# <CJK>
0x8BDE	0x3660	0x8B39	# <CJK>
0x8BDF	0x3661	0x8FD1	# <CJK>
0x8BE0	0x3662	0x91D1	# <CJK>
0x8BE1	0x3663	0x541F	# <CJK>
0x8BE2	0x3664	0x9280	# <CJK>
0x8BE3	0x3665	0x4E5D	# <CJK>
0x8BE4	0x3666	0x5036	# <CJK>
0x8BE5	0x3667	0x53E5	# <CJK>
0x8BE6	0x3668	0x533A	# <CJK>
0x8BE7	0x3669	0x72D7	# <CJK>
0x8BE8	0x366A	0x7396	# <CJK>
0x8BE9	0x366B	0x77E9	# <CJK>
0x8BEA	0x366C	0x82E6	# <CJK>
0x8BEB	0x366D	0x8EAF	# <CJK>
0x8BEC	0x366E	0x99C6	# <CJK>
0x8BED	0x366F	0x99C8	# <CJK>
0x8BEE	0x3670	0x99D2	# <CJK>
0x8BEF	0x3671	0x5177	# <CJK>
0x8BF0	0x3672	0x611A	# <CJK>
0x8BF1	0x3673	0x865E	# <CJK>
0x8BF2	0x3674	0x55B0	# <CJK>
0x8BF3	0x3675	0x7A7A	# <CJK>
0x8BF4	0x3676	0x5076	# <CJK>
0x8BF5	0x3677	0x5BD3	# <CJK>
0x8BF6	0x3678	0x9047	# <CJK>
0x8BF7	0x3679	0x9685	# <CJK>
0x8BF8	0x367A	0x4E32	# <CJK>
0x8BF9	0x367B	0x6ADB	# <CJK>
0x8BFA	0x367C	0x91E7	# <CJK>
0x8BFB	0x367D	0x5C51	# <CJK>
0x8BFC	0x367E	0x5C48	# <CJK>
0x8C40	0x3721	0x6398	# <CJK>
0x8C41	0x3722	0x7A9F	# <CJK>
0x8C42	0x3723	0x6C93	# <CJK>
0x8C43	0x3724	0x9774	# <CJK>
0x8C44	0x3725	0x8F61	# <CJK>
0x8C45	0x3726	0x7AAA	# <CJK>
0x8C46	0x3727	0x718A	# <CJK>
0x8C47	0x3728	0x9688	# <CJK>
0x8C48	0x3729	0x7C82	# <CJK>
0x8C49	0x372A	0x6817	# <CJK>
0x8C4A	0x372B	0x7E70	# <CJK>
0x8C4B	0x372C	0x6851	# <CJK>
0x8C4C	0x372D	0x936C	# <CJK>
0x8C4D	0x372E	0x52F2	# <CJK>
0x8C4E	0x372F	0x541B	# <CJK>
0x8C4F	0x3730	0x85AB	# <CJK>
0x8C50	0x3731	0x8A13	# <CJK>
0x8C51	0x3732	0x7FA4	# <CJK>
0x8C52	0x3733	0x8ECD	# <CJK>
0x8C53	0x3734	0x90E1	# <CJK>
0x8C54	0x3735	0x5366	# <CJK>
0x8C55	0x3736	0x8888	# <CJK>
0x8C56	0x3737	0x7941	# <CJK>
0x8C57	0x3738	0x4FC2	# <CJK>
0x8C58	0x3739	0x50BE	# <CJK>
0x8C59	0x373A	0x5211	# <CJK>
0x8C5A	0x373B	0x5144	# <CJK>
0x8C5B	0x373C	0x5553	# <CJK>
0x8C5C	0x373D	0x572D	# <CJK>
0x8C5D	0x373E	0x73EA	# <CJK>
0x8C5E	0x373F	0x578B	# <CJK>
0x8C5F	0x3740	0x5951	# <CJK>
0x8C60	0x3741	0x5F62	# <CJK>
0x8C61	0x3742	0x5F84	# <CJK>
0x8C62	0x3743	0x6075	# <CJK>
0x8C63	0x3744	0x6176	# <CJK>
0x8C64	0x3745	0x6167	# <CJK>
0x8C65	0x3746	0x61A9	# <CJK>
0x8C66	0x3747	0x63B2	# <CJK>
0x8C67	0x3748	0x643A	# <CJK>
0x8C68	0x3749	0x656C	# <CJK>
0x8C69	0x374A	0x666F	# <CJK>
0x8C6A	0x374B	0x6842	# <CJK>
0x8C6B	0x374C	0x6E13	# <CJK>
0x8C6C	0x374D	0x7566	# <CJK>
0x8C6D	0x374E	0x7A3D	# <CJK>
0x8C6E	0x374F	0x7CFB	# <CJK>
0x8C6F	0x3750	0x7D4C	# <CJK>
0x8C70	0x3751	0x7D99	# <CJK>
0x8C71	0x3752	0x7E4B	# <CJK>
0x8C72	0x3753	0x7F6B	# <CJK>
0x8C73	0x3754	0x830E	# <CJK>
0x8C74	0x3755	0x834A	# <CJK>
0x8C75	0x3756	0x86CD	# <CJK>
0x8C76	0x3757	0x8A08	# <CJK>
0x8C77	0x3758	0x8A63	# <CJK>
0x8C78	0x3759	0x8B66	# <CJK>
0x8C79	0x375A	0x8EFD	# <CJK>
0x8C7A	0x375B	0x981A	# <CJK>
0x8C7B	0x375C	0x9D8F	# <CJK>
0x8C7C	0x375D	0x82B8	# <CJK>
0x8C7D	0x375E	0x8FCE	# <CJK>
0x8C7E	0x375F	0x9BE8	# <CJK>
0x8C80	0x3760	0x5287	# <CJK>
0x8C81	0x3761	0x621F	# <CJK>
0x8C82	0x3762	0x6483	# <CJK>
0x8C83	0x3763	0x6FC0	# <CJK>
0x8C84	0x3764	0x9699	# <CJK>
0x8C85	0x3765	0x6841	# <CJK>
0x8C86	0x3766	0x5091	# <CJK>
0x8C87	0x3767	0x6B20	# <CJK>
0x8C88	0x3768	0x6C7A	# <CJK>
0x8C89	0x3769	0x6F54	# <CJK>
0x8C8A	0x376A	0x7A74	# <CJK>
0x8C8B	0x376B	0x7D50	# <CJK>
0x8C8C	0x376C	0x8840	# <CJK>
0x8C8D	0x376D	0x8A23	# <CJK>
0x8C8E	0x376E	0x6708	# <CJK>
0x8C8F	0x376F	0x4EF6	# <CJK>
0x8C90	0x3770	0x5039	# <CJK>
0x8C91	0x3771	0x5026	# <CJK>
0x8C92	0x3772	0x5065	# <CJK>
0x8C93	0x3773	0x517C	# <CJK>
0x8C94	0x3774	0x5238	# <CJK>
0x8C95	0x3775	0x5263	# <CJK>
0x8C96	0x3776	0x55A7	# <CJK>
0x8C97	0x3777	0x570F	# <CJK>
0x8C98	0x3778	0x5805	# <CJK>
0x8C99	0x3779	0x5ACC	# <CJK>
0x8C9A	0x377A	0x5EFA	# <CJK>
0x8C9B	0x377B	0x61B2	# <CJK>
0x8C9C	0x377C	0x61F8	# <CJK>
0x8C9D	0x377D	0x62F3	# <CJK>
0x8C9E	0x377E	0x6372	# <CJK>
0x8C9F	0x3821	0x691C	# <CJK>
0x8CA0	0x3822	0x6A29	# <CJK>
0x8CA1	0x3823	0x727D	# <CJK>
0x8CA2	0x3824	0x72AC	# <CJK>
0x8CA3	0x3825	0x732E	# <CJK>
0x8CA4	0x3826	0x7814	# <CJK>
0x8CA5	0x3827	0x786F	# <CJK>
0x8CA6	0x3828	0x7D79	# <CJK>
0x8CA7	0x3829	0x770C	# <CJK>
0x8CA8	0x382A	0x80A9	# <CJK>
0x8CA9	0x382B	0x898B	# <CJK>
0x8CAA	0x382C	0x8B19	# <CJK>
0x8CAB	0x382D	0x8CE2	# <CJK>
0x8CAC	0x382E	0x8ED2	# <CJK>
0x8CAD	0x382F	0x9063	# <CJK>
0x8CAE	0x3830	0x9375	# <CJK>
0x8CAF	0x3831	0x967A	# <CJK>
0x8CB0	0x3832	0x9855	# <CJK>
0x8CB1	0x3833	0x9A13	# <CJK>
0x8CB2	0x3834	0x9E78	# <CJK>
0x8CB3	0x3835	0x5143	# <CJK>
0x8CB4	0x3836	0x539F	# <CJK>
0x8CB5	0x3837	0x53B3	# <CJK>
0x8CB6	0x3838	0x5E7B	# <CJK>
0x8CB7	0x3839	0x5F26	# <CJK>
0x8CB8	0x383A	0x6E1B	# <CJK>
0x8CB9	0x383B	0x6E90	# <CJK>
0x8CBA	0x383C	0x7384	# <CJK>
0x8CBB	0x383D	0x73FE	# <CJK>
0x8CBC	0x383E	0x7D43	# <CJK>
0x8CBD	0x383F	0x8237	# <CJK>
0x8CBE	0x3840	0x8A00	# <CJK>
0x8CBF	0x3841	0x8AFA	# <CJK>
0x8CC0	0x3842	0x9650	# <CJK>
0x8CC1	0x3843	0x4E4E	# <CJK>
0x8CC2	0x3844	0x500B	# <CJK>
0x8CC3	0x3845	0x53E4	# <CJK>
0x8CC4	0x3846	0x547C	# <CJK>
0x8CC5	0x3847	0x56FA	# <CJK>
0x8CC6	0x3848	0x59D1	# <CJK>
0x8CC7	0x3849	0x5B64	# <CJK>
0x8CC8	0x384A	0x5DF1	# <CJK>
0x8CC9	0x384B	0x5EAB	# <CJK>
0x8CCA	0x384C	0x5F27	# <CJK>
0x8CCB	0x384D	0x6238	# <CJK>
0x8CCC	0x384E	0x6545	# <CJK>
0x8CCD	0x384F	0x67AF	# <CJK>
0x8CCE	0x3850	0x6E56	# <CJK>
0x8CCF	0x3851	0x72D0	# <CJK>
0x8CD0	0x3852	0x7CCA	# <CJK>
0x8CD1	0x3853	0x88B4	# <CJK>
0x8CD2	0x3854	0x80A1	# <CJK>
0x8CD3	0x3855	0x80E1	# <CJK>
0x8CD4	0x3856	0x83F0	# <CJK>
0x8CD5	0x3857	0x864E	# <CJK>
0x8CD6	0x3858	0x8A87	# <CJK>
0x8CD7	0x3859	0x8DE8	# <CJK>
0x8CD8	0x385A	0x9237	# <CJK>
0x8CD9	0x385B	0x96C7	# <CJK>
0x8CDA	0x385C	0x9867	# <CJK>
0x8CDB	0x385D	0x9F13	# <CJK>
0x8CDC	0x385E	0x4E94	# <CJK>
0x8CDD	0x385F	0x4E92	# <CJK>
0x8CDE	0x3860	0x4F0D	# <CJK>
0x8CDF	0x3861	0x5348	# <CJK>
0x8CE0	0x3862	0x5449	# <CJK>
0x8CE1	0x3863	0x543E	# <CJK>
0x8CE2	0x3864	0x5A2F	# <CJK>
0x8CE3	0x3865	0x5F8C	# <CJK>
0x8CE4	0x3866	0x5FA1	# <CJK>
0x8CE5	0x3867	0x609F	# <CJK>
0x8CE6	0x3868	0x68A7	# <CJK>
0x8CE7	0x3869	0x6A8E	# <CJK>
0x8CE8	0x386A	0x745A	# <CJK>
0x8CE9	0x386B	0x7881	# <CJK>
0x8CEA	0x386C	0x8A9E	# <CJK>
0x8CEB	0x386D	0x8AA4	# <CJK>
0x8CEC	0x386E	0x8B77	# <CJK>
0x8CED	0x386F	0x9190	# <CJK>
0x8CEE	0x3870	0x4E5E	# <CJK>
0x8CEF	0x3871	0x9BC9	# <CJK>
0x8CF0	0x3872	0x4EA4	# <CJK>
0x8CF1	0x3873	0x4F7C	# <CJK>
0x8CF2	0x3874	0x4FAF	# <CJK>
0x8CF3	0x3875	0x5019	# <CJK>
0x8CF4	0x3876	0x5016	# <CJK>
0x8CF5	0x3877	0x5149	# <CJK>
0x8CF6	0x3878	0x516C	# <CJK>
0x8CF7	0x3879	0x529F	# <CJK>
0x8CF8	0x387A	0x52B9	# <CJK>
0x8CF9	0x387B	0x52FE	# <CJK>
0x8CFA	0x387C	0x539A	# <CJK>
0x8CFB	0x387D	0x53E3	# <CJK>
0x8CFC	0x387E	0x5411	# <CJK>
0x8D40	0x3921	0x540E	# <CJK>
0x8D41	0x3922	0x5589	# <CJK>
0x8D42	0x3923	0x5751	# <CJK>
0x8D43	0x3924	0x57A2	# <CJK>
0x8D44	0x3925	0x597D	# <CJK>
0x8D45	0x3926	0x5B54	# <CJK>
0x8D46	0x3927	0x5B5D	# <CJK>
0x8D47	0x3928	0x5B8F	# <CJK>
0x8D48	0x3929	0x5DE5	# <CJK>
0x8D49	0x392A	0x5DE7	# <CJK>
0x8D4A	0x392B	0x5DF7	# <CJK>
0x8D4B	0x392C	0x5E78	# <CJK>
0x8D4C	0x392D	0x5E83	# <CJK>
0x8D4D	0x392E	0x5E9A	# <CJK>
0x8D4E	0x392F	0x5EB7	# <CJK>
0x8D4F	0x3930	0x5F18	# <CJK>
0x8D50	0x3931	0x6052	# <CJK>
0x8D51	0x3932	0x614C	# <CJK>
0x8D52	0x3933	0x6297	# <CJK>
0x8D53	0x3934	0x62D8	# <CJK>
0x8D54	0x3935	0x63A7	# <CJK>
0x8D55	0x3936	0x653B	# <CJK>
0x8D56	0x3937	0x6602	# <CJK>
0x8D57	0x3938	0x6643	# <CJK>
0x8D58	0x3939	0x66F4	# <CJK>
0x8D59	0x393A	0x676D	# <CJK>
0x8D5A	0x393B	0x6821	# <CJK>
0x8D5B	0x393C	0x6897	# <CJK>
0x8D5C	0x393D	0x69CB	# <CJK>
0x8D5D	0x393E	0x6C5F	# <CJK>
0x8D5E	0x393F	0x6D2A	# <CJK>
0x8D5F	0x3940	0x6D69	# <CJK>
0x8D60	0x3941	0x6E2F	# <CJK>
0x8D61	0x3942	0x6E9D	# <CJK>
0x8D62	0x3943	0x7532	# <CJK>
0x8D63	0x3944	0x7687	# <CJK>
0x8D64	0x3945	0x786C	# <CJK>
0x8D65	0x3946	0x7A3F	# <CJK>
0x8D66	0x3947	0x7CE0	# <CJK>
0x8D67	0x3948	0x7D05	# <CJK>
0x8D68	0x3949	0x7D18	# <CJK>
0x8D69	0x394A	0x7D5E	# <CJK>
0x8D6A	0x394B	0x7DB1	# <CJK>
0x8D6B	0x394C	0x8015	# <CJK>
0x8D6C	0x394D	0x8003	# <CJK>
0x8D6D	0x394E	0x80AF	# <CJK>
0x8D6E	0x394F	0x80B1	# <CJK>
0x8D6F	0x3950	0x8154	# <CJK>
0x8D70	0x3951	0x818F	# <CJK>
0x8D71	0x3952	0x822A	# <CJK>
0x8D72	0x3953	0x8352	# <CJK>
0x8D73	0x3954	0x884C	# <CJK>
0x8D74	0x3955	0x8861	# <CJK>
0x8D75	0x3956	0x8B1B	# <CJK>
0x8D76	0x3957	0x8CA2	# <CJK>
0x8D77	0x3958	0x8CFC	# <CJK>
0x8D78	0x3959	0x90CA	# <CJK>
0x8D79	0x395A	0x9175	# <CJK>
0x8D7A	0x395B	0x9271	# <CJK>
0x8D7B	0x395C	0x783F	# <CJK>
0x8D7C	0x395D	0x92FC	# <CJK>
0x8D7D	0x395E	0x95A4	# <CJK>
0x8D7E	0x395F	0x964D	# <CJK>
0x8D80	0x3960	0x9805	# <CJK>
0x8D81	0x3961	0x9999	# <CJK>
0x8D82	0x3962	0x9AD8	# <CJK>
0x8D83	0x3963	0x9D3B	# <CJK>
0x8D84	0x3964	0x525B	# <CJK>
0x8D85	0x3965	0x52AB	# <CJK>
0x8D86	0x3966	0x53F7	# <CJK>
0x8D87	0x3967	0x5408	# <CJK>
0x8D88	0x3968	0x58D5	# <CJK>
0x8D89	0x3969	0x62F7	# <CJK>
0x8D8A	0x396A	0x6FE0	# <CJK>
0x8D8B	0x396B	0x8C6A	# <CJK>
0x8D8C	0x396C	0x8F5F	# <CJK>
0x8D8D	0x396D	0x9EB9	# <CJK>
0x8D8E	0x396E	0x514B	# <CJK>
0x8D8F	0x396F	0x523B	# <CJK>
0x8D90	0x3970	0x544A	# <CJK>
0x8D91	0x3971	0x56FD	# <CJK>
0x8D92	0x3972	0x7A40	# <CJK>
0x8D93	0x3973	0x9177	# <CJK>
0x8D94	0x3974	0x9D60	# <CJK>
0x8D95	0x3975	0x9ED2	# <CJK>
0x8D96	0x3976	0x7344	# <CJK>
0x8D97	0x3977	0x6F09	# <CJK>
0x8D98	0x3978	0x8170	# <CJK>
0x8D99	0x3979	0x7511	# <CJK>
0x8D9A	0x397A	0x5FFD	# <CJK>
0x8D9B	0x397B	0x60DA	# <CJK>
0x8D9C	0x397C	0x9AA8	# <CJK>
0x8D9D	0x397D	0x72DB	# <CJK>
0x8D9E	0x397E	0x8FBC	# <CJK>
0x8D9F	0x3A21	0x6B64	# <CJK>
0x8DA0	0x3A22	0x9803	# <CJK>
0x8DA1	0x3A23	0x4ECA	# <CJK>
0x8DA2	0x3A24	0x56F0	# <CJK>
0x8DA3	0x3A25	0x5764	# <CJK>
0x8DA4	0x3A26	0x58BE	# <CJK>
0x8DA5	0x3A27	0x5A5A	# <CJK>
0x8DA6	0x3A28	0x6068	# <CJK>
0x8DA7	0x3A29	0x61C7	# <CJK>
0x8DA8	0x3A2A	0x660F	# <CJK>
0x8DA9	0x3A2B	0x6606	# <CJK>
0x8DAA	0x3A2C	0x6839	# <CJK>
0x8DAB	0x3A2D	0x68B1	# <CJK>
0x8DAC	0x3A2E	0x6DF7	# <CJK>
0x8DAD	0x3A2F	0x75D5	# <CJK>
0x8DAE	0x3A30	0x7D3A	# <CJK>
0x8DAF	0x3A31	0x826E	# <CJK>
0x8DB0	0x3A32	0x9B42	# <CJK>
0x8DB1	0x3A33	0x4E9B	# <CJK>
0x8DB2	0x3A34	0x4F50	# <CJK>
0x8DB3	0x3A35	0x53C9	# <CJK>
0x8DB4	0x3A36	0x5506	# <CJK>
0x8DB5	0x3A37	0x5D6F	# <CJK>
0x8DB6	0x3A38	0x5DE6	# <CJK>
0x8DB7	0x3A39	0x5DEE	# <CJK>
0x8DB8	0x3A3A	0x67FB	# <CJK>
0x8DB9	0x3A3B	0x6C99	# <CJK>
0x8DBA	0x3A3C	0x7473	# <CJK>
0x8DBB	0x3A3D	0x7802	# <CJK>
0x8DBC	0x3A3E	0x8A50	# <CJK>
0x8DBD	0x3A3F	0x9396	# <CJK>
0x8DBE	0x3A40	0x88DF	# <CJK>
0x8DBF	0x3A41	0x5750	# <CJK>
0x8DC0	0x3A42	0x5EA7	# <CJK>
0x8DC1	0x3A43	0x632B	# <CJK>
0x8DC2	0x3A44	0x50B5	# <CJK>
0x8DC3	0x3A45	0x50AC	# <CJK>
0x8DC4	0x3A46	0x518D	# <CJK>
0x8DC5	0x3A47	0x6700	# <CJK>
0x8DC6	0x3A48	0x54C9	# <CJK>
0x8DC7	0x3A49	0x585E	# <CJK>
0x8DC8	0x3A4A	0x59BB	# <CJK>
0x8DC9	0x3A4B	0x5BB0	# <CJK>
0x8DCA	0x3A4C	0x5F69	# <CJK>
0x8DCB	0x3A4D	0x624D	# <CJK>
0x8DCC	0x3A4E	0x63A1	# <CJK>
0x8DCD	0x3A4F	0x683D	# <CJK>
0x8DCE	0x3A50	0x6B73	# <CJK>
0x8DCF	0x3A51	0x6E08	# <CJK>
0x8DD0	0x3A52	0x707D	# <CJK>
0x8DD1	0x3A53	0x91C7	# <CJK>
0x8DD2	0x3A54	0x7280	# <CJK>
0x8DD3	0x3A55	0x7815	# <CJK>
0x8DD4	0x3A56	0x7826	# <CJK>
0x8DD5	0x3A57	0x796D	# <CJK>
0x8DD6	0x3A58	0x658E	# <CJK>
0x8DD7	0x3A59	0x7D30	# <CJK>
0x8DD8	0x3A5A	0x83DC	# <CJK>
0x8DD9	0x3A5B	0x88C1	# <CJK>
0x8DDA	0x3A5C	0x8F09	# <CJK>
0x8DDB	0x3A5D	0x969B	# <CJK>
0x8DDC	0x3A5E	0x5264	# <CJK>
0x8DDD	0x3A5F	0x5728	# <CJK>
0x8DDE	0x3A60	0x6750	# <CJK>
0x8DDF	0x3A61	0x7F6A	# <CJK>
0x8DE0	0x3A62	0x8CA1	# <CJK>
0x8DE1	0x3A63	0x51B4	# <CJK>
0x8DE2	0x3A64	0x5742	# <CJK>
0x8DE3	0x3A65	0x962A	# <CJK>
0x8DE4	0x3A66	0x583A	# <CJK>
0x8DE5	0x3A67	0x698A	# <CJK>
0x8DE6	0x3A68	0x80B4	# <CJK>
0x8DE7	0x3A69	0x54B2	# <CJK>
0x8DE8	0x3A6A	0x5D0E	# <CJK>
0x8DE9	0x3A6B	0x57FC	# <CJK>
0x8DEA	0x3A6C	0x7895	# <CJK>
0x8DEB	0x3A6D	0x9DFA	# <CJK>
0x8DEC	0x3A6E	0x4F5C	# <CJK>
0x8DED	0x3A6F	0x524A	# <CJK>
0x8DEE	0x3A70	0x548B	# <CJK>
0x8DEF	0x3A71	0x643E	# <CJK>
0x8DF0	0x3A72	0x6628	# <CJK>
0x8DF1	0x3A73	0x6714	# <CJK>
0x8DF2	0x3A74	0x67F5	# <CJK>
0x8DF3	0x3A75	0x7A84	# <CJK>
0x8DF4	0x3A76	0x7B56	# <CJK>
0x8DF5	0x3A77	0x7D22	# <CJK>
0x8DF6	0x3A78	0x932F	# <CJK>
0x8DF7	0x3A79	0x685C	# <CJK>
0x8DF8	0x3A7A	0x9BAD	# <CJK>
0x8DF9	0x3A7B	0x7B39	# <CJK>
0x8DFA	0x3A7C	0x5319	# <CJK>
0x8DFB	0x3A7D	0x518A	# <CJK>
0x8DFC	0x3A7E	0x5237	# <CJK>
0x8E40	0x3B21	0x5BDF	# <CJK>
0x8E41	0x3B22	0x62F6	# <CJK>
0x8E42	0x3B23	0x64AE	# <CJK>
0x8E43	0x3B24	0x64E6	# <CJK>
0x8E44	0x3B25	0x672D	# <CJK>
0x8E45	0x3B26	0x6BBA	# <CJK>
0x8E46	0x3B27	0x85A9	# <CJK>
0x8E47	0x3B28	0x96D1	# <CJK>
0x8E48	0x3B29	0x7690	# <CJK>
0x8E49	0x3B2A	0x9BD6	# <CJK>
0x8E4A	0x3B2B	0x634C	# <CJK>
0x8E4B	0x3B2C	0x9306	# <CJK>
0x8E4C	0x3B2D	0x9BAB	# <CJK>
0x8E4D	0x3B2E	0x76BF	# <CJK>
0x8E4E	0x3B2F	0x6652	# <CJK>
0x8E4F	0x3B30	0x4E09	# <CJK>
0x8E50	0x3B31	0x5098	# <CJK>
0x8E51	0x3B32	0x53C2	# <CJK>
0x8E52	0x3B33	0x5C71	# <CJK>
0x8E53	0x3B34	0x60E8	# <CJK>
0x8E54	0x3B35	0x6492	# <CJK>
0x8E55	0x3B36	0x6563	# <CJK>
0x8E56	0x3B37	0x685F	# <CJK>
0x8E57	0x3B38	0x71E6	# <CJK>
0x8E58	0x3B39	0x73CA	# <CJK>
0x8E59	0x3B3A	0x7523	# <CJK>
0x8E5A	0x3B3B	0x7B97	# <CJK>
0x8E5B	0x3B3C	0x7E82	# <CJK>
0x8E5C	0x3B3D	0x8695	# <CJK>
0x8E5D	0x3B3E	0x8B83	# <CJK>
0x8E5E	0x3B3F	0x8CDB	# <CJK>
0x8E5F	0x3B40	0x9178	# <CJK>
0x8E60	0x3B41	0x9910	# <CJK>
0x8E61	0x3B42	0x65AC	# <CJK>
0x8E62	0x3B43	0x66AB	# <CJK>
0x8E63	0x3B44	0x6B8B	# <CJK>
0x8E64	0x3B45	0x4ED5	# <CJK>
0x8E65	0x3B46	0x4ED4	# <CJK>
0x8E66	0x3B47	0x4F3A	# <CJK>
0x8E67	0x3B48	0x4F7F	# <CJK>
0x8E68	0x3B49	0x523A	# <CJK>
0x8E69	0x3B4A	0x53F8	# <CJK>
0x8E6A	0x3B4B	0x53F2	# <CJK>
0x8E6B	0x3B4C	0x55E3	# <CJK>
0x8E6C	0x3B4D	0x56DB	# <CJK>
0x8E6D	0x3B4E	0x58EB	# <CJK>
0x8E6E	0x3B4F	0x59CB	# <CJK>
0x8E6F	0x3B50	0x59C9	# <CJK>
0x8E70	0x3B51	0x59FF	# <CJK>
0x8E71	0x3B52	0x5B50	# <CJK>
0x8E72	0x3B53	0x5C4D	# <CJK>
0x8E73	0x3B54	0x5E02	# <CJK>
0x8E74	0x3B55	0x5E2B	# <CJK>
0x8E75	0x3B56	0x5FD7	# <CJK>
0x8E76	0x3B57	0x601D	# <CJK>
0x8E77	0x3B58	0x6307	# <CJK>
0x8E78	0x3B59	0x652F	# <CJK>
0x8E79	0x3B5A	0x5B5C	# <CJK>
0x8E7A	0x3B5B	0x65AF	# <CJK>
0x8E7B	0x3B5C	0x65BD	# <CJK>
0x8E7C	0x3B5D	0x65E8	# <CJK>
0x8E7D	0x3B5E	0x679D	# <CJK>
0x8E7E	0x3B5F	0x6B62	# <CJK>
0x8E80	0x3B60	0x6B7B	# <CJK>
0x8E81	0x3B61	0x6C0F	# <CJK>
0x8E82	0x3B62	0x7345	# <CJK>
0x8E83	0x3B63	0x7949	# <CJK>
0x8E84	0x3B64	0x79C1	# <CJK>
0x8E85	0x3B65	0x7CF8	# <CJK>
0x8E86	0x3B66	0x7D19	# <CJK>
0x8E87	0x3B67	0x7D2B	# <CJK>
0x8E88	0x3B68	0x80A2	# <CJK>
0x8E89	0x3B69	0x8102	# <CJK>
0x8E8A	0x3B6A	0x81F3	# <CJK>
0x8E8B	0x3B6B	0x8996	# <CJK>
0x8E8C	0x3B6C	0x8A5E	# <CJK>
0x8E8D	0x3B6D	0x8A69	# <CJK>
0x8E8E	0x3B6E	0x8A66	# <CJK>
0x8E8F	0x3B6F	0x8A8C	# <CJK>
0x8E90	0x3B70	0x8AEE	# <CJK>
0x8E91	0x3B71	0x8CC7	# <CJK>
0x8E92	0x3B72	0x8CDC	# <CJK>
0x8E93	0x3B73	0x96CC	# <CJK>
0x8E94	0x3B74	0x98FC	# <CJK>
0x8E95	0x3B75	0x6B6F	# <CJK>
0x8E96	0x3B76	0x4E8B	# <CJK>
0x8E97	0x3B77	0x4F3C	# <CJK>
0x8E98	0x3B78	0x4F8D	# <CJK>
0x8E99	0x3B79	0x5150	# <CJK>
0x8E9A	0x3B7A	0x5B57	# <CJK>
0x8E9B	0x3B7B	0x5BFA	# <CJK>
0x8E9C	0x3B7C	0x6148	# <CJK>
0x8E9D	0x3B7D	0x6301	# <CJK>
0x8E9E	0x3B7E	0x6642	# <CJK>
0x8E9F	0x3C21	0x6B21	# <CJK>
0x8EA0	0x3C22	0x6ECB	# <CJK>
0x8EA1	0x3C23	0x6CBB	# <CJK>
0x8EA2	0x3C24	0x723E	# <CJK>
0x8EA3	0x3C25	0x74BD	# <CJK>
0x8EA4	0x3C26	0x75D4	# <CJK>
0x8EA5	0x3C27	0x78C1	# <CJK>
0x8EA6	0x3C28	0x793A	# <CJK>
0x8EA7	0x3C29	0x800C	# <CJK>
0x8EA8	0x3C2A	0x8033	# <CJK>
0x8EA9	0x3C2B	0x81EA	# <CJK>
0x8EAA	0x3C2C	0x8494	# <CJK>
0x8EAB	0x3C2D	0x8F9E	# <CJK>
0x8EAC	0x3C2E	0x6C50	# <CJK>
0x8EAD	0x3C2F	0x9E7F	# <CJK>
0x8EAE	0x3C30	0x5F0F	# <CJK>
0x8EAF	0x3C31	0x8B58	# <CJK>
0x8EB0	0x3C32	0x9D2B	# <CJK>
0x8EB1	0x3C33	0x7AFA	# <CJK>
0x8EB2	0x3C34	0x8EF8	# <CJK>
0x8EB3	0x3C35	0x5B8D	# <CJK>
0x8EB4	0x3C36	0x96EB	# <CJK>
0x8EB5	0x3C37	0x4E03	# <CJK>
0x8EB6	0x3C38	0x53F1	# <CJK>
0x8EB7	0x3C39	0x57F7	# <CJK>
0x8EB8	0x3C3A	0x5931	# <CJK>
0x8EB9	0x3C3B	0x5AC9	# <CJK>
0x8EBA	0x3C3C	0x5BA4	# <CJK>
0x8EBB	0x3C3D	0x6089	# <CJK>
0x8EBC	0x3C3E	0x6E7F	# <CJK>
0x8EBD	0x3C3F	0x6F06	# <CJK>
0x8EBE	0x3C40	0x75BE	# <CJK>
0x8EBF	0x3C41	0x8CEA	# <CJK>
0x8EC0	0x3C42	0x5B9F	# <CJK>
0x8EC1	0x3C43	0x8500	# <CJK>
0x8EC2	0x3C44	0x7BE0	# <CJK>
0x8EC3	0x3C45	0x5072	# <CJK>
0x8EC4	0x3C46	0x67F4	# <CJK>
0x8EC5	0x3C47	0x829D	# <CJK>
0x8EC6	0x3C48	0x5C61	# <CJK>
0x8EC7	0x3C49	0x854A	# <CJK>
0x8EC8	0x3C4A	0x7E1E	# <CJK>
0x8EC9	0x3C4B	0x820E	# <CJK>
0x8ECA	0x3C4C	0x5199	# <CJK>
0x8ECB	0x3C4D	0x5C04	# <CJK>
0x8ECC	0x3C4E	0x6368	# <CJK>
0x8ECD	0x3C4F	0x8D66	# <CJK>
0x8ECE	0x3C50	0x659C	# <CJK>
0x8ECF	0x3C51	0x716E	# <CJK>
0x8ED0	0x3C52	0x793E	# <CJK>
0x8ED1	0x3C53	0x7D17	# <CJK>
0x8ED2	0x3C54	0x8005	# <CJK>
0x8ED3	0x3C55	0x8B1D	# <CJK>
0x8ED4	0x3C56	0x8ECA	# <CJK>
0x8ED5	0x3C57	0x906E	# <CJK>
0x8ED6	0x3C58	0x86C7	# <CJK>
0x8ED7	0x3C59	0x90AA	# <CJK>
0x8ED8	0x3C5A	0x501F	# <CJK>
0x8ED9	0x3C5B	0x52FA	# <CJK>
0x8EDA	0x3C5C	0x5C3A	# <CJK>
0x8EDB	0x3C5D	0x6753	# <CJK>
0x8EDC	0x3C5E	0x707C	# <CJK>
0x8EDD	0x3C5F	0x7235	# <CJK>
0x8EDE	0x3C60	0x914C	# <CJK>
0x8EDF	0x3C61	0x91C8	# <CJK>
0x8EE0	0x3C62	0x932B	# <CJK>
0x8EE1	0x3C63	0x82E5	# <CJK>
0x8EE2	0x3C64	0x5BC2	# <CJK>
0x8EE3	0x3C65	0x5F31	# <CJK>
0x8EE4	0x3C66	0x60F9	# <CJK>
0x8EE5	0x3C67	0x4E3B	# <CJK>
0x8EE6	0x3C68	0x53D6	# <CJK>
0x8EE7	0x3C69	0x5B88	# <CJK>
0x8EE8	0x3C6A	0x624B	# <CJK>
0x8EE9	0x3C6B	0x6731	# <CJK>
0x8EEA	0x3C6C	0x6B8A	# <CJK>
0x8EEB	0x3C6D	0x72E9	# <CJK>
0x8EEC	0x3C6E	0x73E0	# <CJK>
0x8EED	0x3C6F	0x7A2E	# <CJK>
0x8EEE	0x3C70	0x816B	# <CJK>
0x8EEF	0x3C71	0x8DA3	# <CJK>
0x8EF0	0x3C72	0x9152	# <CJK>
0x8EF1	0x3C73	0x9996	# <CJK>
0x8EF2	0x3C74	0x5112	# <CJK>
0x8EF3	0x3C75	0x53D7	# <CJK>
0x8EF4	0x3C76	0x546A	# <CJK>
0x8EF5	0x3C77	0x5BFF	# <CJK>
0x8EF6	0x3C78	0x6388	# <CJK>
0x8EF7	0x3C79	0x6A39	# <CJK>
0x8EF8	0x3C7A	0x7DAC	# <CJK>
0x8EF9	0x3C7B	0x9700	# <CJK>
0x8EFA	0x3C7C	0x56DA	# <CJK>
0x8EFB	0x3C7D	0x53CE	# <CJK>
0x8EFC	0x3C7E	0x5468	# <CJK>
0x8F40	0x3D21	0x5B97	# <CJK>
0x8F41	0x3D22	0x5C31	# <CJK>
0x8F42	0x3D23	0x5DDE	# <CJK>
0x8F43	0x3D24	0x4FEE	# <CJK>
0x8F44	0x3D25	0x6101	# <CJK>
0x8F45	0x3D26	0x62FE	# <CJK>
0x8F46	0x3D27	0x6D32	# <CJK>
0x8F47	0x3D28	0x79C0	# <CJK>
0x8F48	0x3D29	0x79CB	# <CJK>
0x8F49	0x3D2A	0x7D42	# <CJK>
0x8F4A	0x3D2B	0x7E4D	# <CJK>
0x8F4B	0x3D2C	0x7FD2	# <CJK>
0x8F4C	0x3D2D	0x81ED	# <CJK>
0x8F4D	0x3D2E	0x821F	# <CJK>
0x8F4E	0x3D2F	0x8490	# <CJK>
0x8F4F	0x3D30	0x8846	# <CJK>
0x8F50	0x3D31	0x8972	# <CJK>
0x8F51	0x3D32	0x8B90	# <CJK>
0x8F52	0x3D33	0x8E74	# <CJK>
0x8F53	0x3D34	0x8F2F	# <CJK>
0x8F54	0x3D35	0x9031	# <CJK>
0x8F55	0x3D36	0x914B	# <CJK>
0x8F56	0x3D37	0x916C	# <CJK>
0x8F57	0x3D38	0x96C6	# <CJK>
0x8F58	0x3D39	0x919C	# <CJK>
0x8F59	0x3D3A	0x4EC0	# <CJK>
0x8F5A	0x3D3B	0x4F4F	# <CJK>
0x8F5B	0x3D3C	0x5145	# <CJK>
0x8F5C	0x3D3D	0x5341	# <CJK>
0x8F5D	0x3D3E	0x5F93	# <CJK>
0x8F5E	0x3D3F	0x620E	# <CJK>
0x8F5F	0x3D40	0x67D4	# <CJK>
0x8F60	0x3D41	0x6C41	# <CJK>
0x8F61	0x3D42	0x6E0B	# <CJK>
0x8F62	0x3D43	0x7363	# <CJK>
0x8F63	0x3D44	0x7E26	# <CJK>
0x8F64	0x3D45	0x91CD	# <CJK>
0x8F65	0x3D46	0x9283	# <CJK>
0x8F66	0x3D47	0x53D4	# <CJK>
0x8F67	0x3D48	0x5919	# <CJK>
0x8F68	0x3D49	0x5BBF	# <CJK>
0x8F69	0x3D4A	0x6DD1	# <CJK>
0x8F6A	0x3D4B	0x795D	# <CJK>
0x8F6B	0x3D4C	0x7E2E	# <CJK>
0x8F6C	0x3D4D	0x7C9B	# <CJK>
0x8F6D	0x3D4E	0x587E	# <CJK>
0x8F6E	0x3D4F	0x719F	# <CJK>
0x8F6F	0x3D50	0x51FA	# <CJK>
0x8F70	0x3D51	0x8853	# <CJK>
0x8F71	0x3D52	0x8FF0	# <CJK>
0x8F72	0x3D53	0x4FCA	# <CJK>
0x8F73	0x3D54	0x5CFB	# <CJK>
0x8F74	0x3D55	0x6625	# <CJK>
0x8F75	0x3D56	0x77AC	# <CJK>
0x8F76	0x3D57	0x7AE3	# <CJK>
0x8F77	0x3D58	0x821C	# <CJK>
0x8F78	0x3D59	0x99FF	# <CJK>
0x8F79	0x3D5A	0x51C6	# <CJK>
0x8F7A	0x3D5B	0x5FAA	# <CJK>
0x8F7B	0x3D5C	0x65EC	# <CJK>
0x8F7C	0x3D5D	0x696F	# <CJK>
0x8F7D	0x3D5E	0x6B89	# <CJK>
0x8F7E	0x3D5F	0x6DF3	# <CJK>
0x8F80	0x3D60	0x6E96	# <CJK>
0x8F81	0x3D61	0x6F64	# <CJK>
0x8F82	0x3D62	0x76FE	# <CJK>
0x8F83	0x3D63	0x7D14	# <CJK>
0x8F84	0x3D64	0x5DE1	# <CJK>
0x8F85	0x3D65	0x9075	# <CJK>
0x8F86	0x3D66	0x9187	# <CJK>
0x8F87	0x3D67	0x9806	# <CJK>
0x8F88	0x3D68	0x51E6	# <CJK>
0x8F89	0x3D69	0x521D	# <CJK>
0x8F8A	0x3D6A	0x6240	# <CJK>
0x8F8B	0x3D6B	0x6691	# <CJK>
0x8F8C	0x3D6C	0x66D9	# <CJK>
0x8F8D	0x3D6D	0x6E1A	# <CJK>
0x8F8E	0x3D6E	0x5EB6	# <CJK>
0x8F8F	0x3D6F	0x7DD2	# <CJK>
0x8F90	0x3D70	0x7F72	# <CJK>
0x8F91	0x3D71	0x66F8	# <CJK>
0x8F92	0x3D72	0x85AF	# <CJK>
0x8F93	0x3D73	0x85F7	# <CJK>
0x8F94	0x3D74	0x8AF8	# <CJK>
0x8F95	0x3D75	0x52A9	# <CJK>
0x8F96	0x3D76	0x53D9	# <CJK>
0x8F97	0x3D77	0x5973	# <CJK>
0x8F98	0x3D78	0x5E8F	# <CJK>
0x8F99	0x3D79	0x5F90	# <CJK>
0x8F9A	0x3D7A	0x6055	# <CJK>
0x8F9B	0x3D7B	0x92E4	# <CJK>
0x8F9C	0x3D7C	0x9664	# <CJK>
0x8F9D	0x3D7D	0x50B7	# <CJK>
0x8F9E	0x3D7E	0x511F	# <CJK>
0x8F9F	0x3E21	0x52DD	# <CJK>
0x8FA0	0x3E22	0x5320	# <CJK>
0x8FA1	0x3E23	0x5347	# <CJK>
0x8FA2	0x3E24	0x53EC	# <CJK>
0x8FA3	0x3E25	0x54E8	# <CJK>
0x8FA4	0x3E26	0x5546	# <CJK>
0x8FA5	0x3E27	0x5531	# <CJK>
0x8FA6	0x3E28	0x5617	# <CJK>
0x8FA7	0x3E29	0x5968	# <CJK>
0x8FA8	0x3E2A	0x59BE	# <CJK>
0x8FA9	0x3E2B	0x5A3C	# <CJK>
0x8FAA	0x3E2C	0x5BB5	# <CJK>
0x8FAB	0x3E2D	0x5C06	# <CJK>
0x8FAC	0x3E2E	0x5C0F	# <CJK>
0x8FAD	0x3E2F	0x5C11	# <CJK>
0x8FAE	0x3E30	0x5C1A	# <CJK>
0x8FAF	0x3E31	0x5E84	# <CJK>
0x8FB0	0x3E32	0x5E8A	# <CJK>
0x8FB1	0x3E33	0x5EE0	# <CJK>
0x8FB2	0x3E34	0x5F70	# <CJK>
0x8FB3	0x3E35	0x627F	# <CJK>
0x8FB4	0x3E36	0x6284	# <CJK>
0x8FB5	0x3E37	0x62DB	# <CJK>
0x8FB6	0x3E38	0x638C	# <CJK>
0x8FB7	0x3E39	0x6377	# <CJK>
0x8FB8	0x3E3A	0x6607	# <CJK>
0x8FB9	0x3E3B	0x660C	# <CJK>
0x8FBA	0x3E3C	0x662D	# <CJK>
0x8FBB	0x3E3D	0x6676	# <CJK>
0x8FBC	0x3E3E	0x677E	# <CJK>
0x8FBD	0x3E3F	0x68A2	# <CJK>
0x8FBE	0x3E40	0x6A1F	# <CJK>
0x8FBF	0x3E41	0x6A35	# <CJK>
0x8FC0	0x3E42	0x6CBC	# <CJK>
0x8FC1	0x3E43	0x6D88	# <CJK>
0x8FC2	0x3E44	0x6E09	# <CJK>
0x8FC3	0x3E45	0x6E58	# <CJK>
0x8FC4	0x3E46	0x713C	# <CJK>
0x8FC5	0x3E47	0x7126	# <CJK>
0x8FC6	0x3E48	0x7167	# <CJK>
0x8FC7	0x3E49	0x75C7	# <CJK>
0x8FC8	0x3E4A	0x7701	# <CJK>
0x8FC9	0x3E4B	0x785D	# <CJK>
0x8FCA	0x3E4C	0x7901	# <CJK>
0x8FCB	0x3E4D	0x7965	# <CJK>
0x8FCC	0x3E4E	0x79F0	# <CJK>
0x8FCD	0x3E4F	0x7AE0	# <CJK>
0x8FCE	0x3E50	0x7B11	# <CJK>
0x8FCF	0x3E51	0x7CA7	# <CJK>
0x8FD0	0x3E52	0x7D39	# <CJK>
0x8FD1	0x3E53	0x8096	# <CJK>
0x8FD2	0x3E54	0x83D6	# <CJK>
0x8FD3	0x3E55	0x848B	# <CJK>
0x8FD4	0x3E56	0x8549	# <CJK>
0x8FD5	0x3E57	0x885D	# <CJK>
0x8FD6	0x3E58	0x88F3	# <CJK>
0x8FD7	0x3E59	0x8A1F	# <CJK>
0x8FD8	0x3E5A	0x8A3C	# <CJK>
0x8FD9	0x3E5B	0x8A54	# <CJK>
0x8FDA	0x3E5C	0x8A73	# <CJK>
0x8FDB	0x3E5D	0x8C61	# <CJK>
0x8FDC	0x3E5E	0x8CDE	# <CJK>
0x8FDD	0x3E5F	0x91A4	# <CJK>
0x8FDE	0x3E60	0x9266	# <CJK>
0x8FDF	0x3E61	0x937E	# <CJK>
0x8FE0	0x3E62	0x9418	# <CJK>
0x8FE1	0x3E63	0x969C	# <CJK>
0x8FE2	0x3E64	0x9798	# <CJK>
0x8FE3	0x3E65	0x4E0A	# <CJK>
0x8FE4	0x3E66	0x4E08	# <CJK>
0x8FE5	0x3E67	0x4E1E	# <CJK>
0x8FE6	0x3E68	0x4E57	# <CJK>
0x8FE7	0x3E69	0x5197	# <CJK>
0x8FE8	0x3E6A	0x5270	# <CJK>
0x8FE9	0x3E6B	0x57CE	# <CJK>
0x8FEA	0x3E6C	0x5834	# <CJK>
0x8FEB	0x3E6D	0x58CC	# <CJK>
0x8FEC	0x3E6E	0x5B22	# <CJK>
0x8FED	0x3E6F	0x5E38	# <CJK>
0x8FEE	0x3E70	0x60C5	# <CJK>
0x8FEF	0x3E71	0x64FE	# <CJK>
0x8FF0	0x3E72	0x6761	# <CJK>
0x8FF1	0x3E73	0x6756	# <CJK>
0x8FF2	0x3E74	0x6D44	# <CJK>
0x8FF3	0x3E75	0x72B6	# <CJK>
0x8FF4	0x3E76	0x7573	# <CJK>
0x8FF5	0x3E77	0x7A63	# <CJK>
0x8FF6	0x3E78	0x84B8	# <CJK>
0x8FF7	0x3E79	0x8B72	# <CJK>
0x8FF8	0x3E7A	0x91B8	# <CJK>
0x8FF9	0x3E7B	0x9320	# <CJK>
0x8FFA	0x3E7C	0x5631	# <CJK>
0x8FFB	0x3E7D	0x57F4	# <CJK>
0x8FFC	0x3E7E	0x98FE	# <CJK>
0x9040	0x3F21	0x62ED	# <CJK>
0x9041	0x3F22	0x690D	# <CJK>
0x9042	0x3F23	0x6B96	# <CJK>
0x9043	0x3F24	0x71ED	# <CJK>
0x9044	0x3F25	0x7E54	# <CJK>
0x9045	0x3F26	0x8077	# <CJK>
0x9046	0x3F27	0x8272	# <CJK>
0x9047	0x3F28	0x89E6	# <CJK>
0x9048	0x3F29	0x98DF	# <CJK>
0x9049	0x3F2A	0x8755	# <CJK>
0x904A	0x3F2B	0x8FB1	# <CJK>
0x904B	0x3F2C	0x5C3B	# <CJK>
0x904C	0x3F2D	0x4F38	# <CJK>
0x904D	0x3F2E	0x4FE1	# <CJK>
0x904E	0x3F2F	0x4FB5	# <CJK>
0x904F	0x3F30	0x5507	# <CJK>
0x9050	0x3F31	0x5A20	# <CJK>
0x9051	0x3F32	0x5BDD	# <CJK>
0x9052	0x3F33	0x5BE9	# <CJK>
0x9053	0x3F34	0x5FC3	# <CJK>
0x9054	0x3F35	0x614E	# <CJK>
0x9055	0x3F36	0x632F	# <CJK>
0x9056	0x3F37	0x65B0	# <CJK>
0x9057	0x3F38	0x664B	# <CJK>
0x9058	0x3F39	0x68EE	# <CJK>
0x9059	0x3F3A	0x699B	# <CJK>
0x905A	0x3F3B	0x6D78	# <CJK>
0x905B	0x3F3C	0x6DF1	# <CJK>
0x905C	0x3F3D	0x7533	# <CJK>
0x905D	0x3F3E	0x75B9	# <CJK>
0x905E	0x3F3F	0x771F	# <CJK>
0x905F	0x3F40	0x795E	# <CJK>
0x9060	0x3F41	0x79E6	# <CJK>
0x9061	0x3F42	0x7D33	# <CJK>
0x9062	0x3F43	0x81E3	# <CJK>
0x9063	0x3F44	0x82AF	# <CJK>
0x9064	0x3F45	0x85AA	# <CJK>
0x9065	0x3F46	0x89AA	# <CJK>
0x9066	0x3F47	0x8A3A	# <CJK>
0x9067	0x3F48	0x8EAB	# <CJK>
0x9068	0x3F49	0x8F9B	# <CJK>
0x9069	0x3F4A	0x9032	# <CJK>
0x906A	0x3F4B	0x91DD	# <CJK>
0x906B	0x3F4C	0x9707	# <CJK>
0x906C	0x3F4D	0x4EBA	# <CJK>
0x906D	0x3F4E	0x4EC1	# <CJK>
0x906E	0x3F4F	0x5203	# <CJK>
0x906F	0x3F50	0x5875	# <CJK>
0x9070	0x3F51	0x58EC	# <CJK>
0x9071	0x3F52	0x5C0B	# <CJK>
0x9072	0x3F53	0x751A	# <CJK>
0x9073	0x3F54	0x5C3D	# <CJK>
0x9074	0x3F55	0x814E	# <CJK>
0x9075	0x3F56	0x8A0A	# <CJK>
0x9076	0x3F57	0x8FC5	# <CJK>
0x9077	0x3F58	0x9663	# <CJK>
0x9078	0x3F59	0x976D	# <CJK>
0x9079	0x3F5A	0x7B25	# <CJK>
0x907A	0x3F5B	0x8ACF	# <CJK>
0x907B	0x3F5C	0x9808	# <CJK>
0x907C	0x3F5D	0x9162	# <CJK>
0x907D	0x3F5E	0x56F3	# <CJK>
0x907E	0x3F5F	0x53A8	# <CJK>
0x9080	0x3F60	0x9017	# <CJK>
0x9081	0x3F61	0x5439	# <CJK>
0x9082	0x3F62	0x5782	# <CJK>
0x9083	0x3F63	0x5E25	# <CJK>
0x9084	0x3F64	0x63A8	# <CJK>
0x9085	0x3F65	0x6C34	# <CJK>
0x9086	0x3F66	0x708A	# <CJK>
0x9087	0x3F67	0x7761	# <CJK>
0x9088	0x3F68	0x7C8B	# <CJK>
0x9089	0x3F69	0x7FE0	# <CJK>
0x908A	0x3F6A	0x8870	# <CJK>
0x908B	0x3F6B	0x9042	# <CJK>
0x908C	0x3F6C	0x9154	# <CJK>
0x908D	0x3F6D	0x9310	# <CJK>
0x908E	0x3F6E	0x9318	# <CJK>
0x908F	0x3F6F	0x968F	# <CJK>
0x9090	0x3F70	0x745E	# <CJK>
0x9091	0x3F71	0x9AC4	# <CJK>
0x9092	0x3F72	0x5D07	# <CJK>
0x9093	0x3F73	0x5D69	# <CJK>
0x9094	0x3F74	0x6570	# <CJK>
0x9095	0x3F75	0x67A2	# <CJK>
0x9096	0x3F76	0x8DA8	# <CJK>
0x9097	0x3F77	0x96DB	# <CJK>
0x9098	0x3F78	0x636E	# <CJK>
0x9099	0x3F79	0x6749	# <CJK>
0x909A	0x3F7A	0x6919	# <CJK>
0x909B	0x3F7B	0x83C5	# <CJK>
0x909C	0x3F7C	0x9817	# <CJK>
0x909D	0x3F7D	0x96C0	# <CJK>
0x909E	0x3F7E	0x88FE	# <CJK>
0x909F	0x4021	0x6F84	# <CJK>
0x90A0	0x4022	0x647A	# <CJK>
0x90A1	0x4023	0x5BF8	# <CJK>
0x90A2	0x4024	0x4E16	# <CJK>
0x90A3	0x4025	0x702C	# <CJK>
0x90A4	0x4026	0x755D	# <CJK>
0x90A5	0x4027	0x662F	# <CJK>
0x90A6	0x4028	0x51C4	# <CJK>
0x90A7	0x4029	0x5236	# <CJK>
0x90A8	0x402A	0x52E2	# <CJK>
0x90A9	0x402B	0x59D3	# <CJK>
0x90AA	0x402C	0x5F81	# <CJK>
0x90AB	0x402D	0x6027	# <CJK>
0x90AC	0x402E	0x6210	# <CJK>
0x90AD	0x402F	0x653F	# <CJK>
0x90AE	0x4030	0x6574	# <CJK>
0x90AF	0x4031	0x661F	# <CJK>
0x90B0	0x4032	0x6674	# <CJK>
0x90B1	0x4033	0x68F2	# <CJK>
0x90B2	0x4034	0x6816	# <CJK>
0x90B3	0x4035	0x6B63	# <CJK>
0x90B4	0x4036	0x6E05	# <CJK>
0x90B5	0x4037	0x7272	# <CJK>
0x90B6	0x4038	0x751F	# <CJK>
0x90B7	0x4039	0x76DB	# <CJK>
0x90B8	0x403A	0x7CBE	# <CJK>
0x90B9	0x403B	0x8056	# <CJK>
0x90BA	0x403C	0x58F0	# <CJK>
0x90BB	0x403D	0x88FD	# <CJK>
0x90BC	0x403E	0x897F	# <CJK>
0x90BD	0x403F	0x8AA0	# <CJK>
0x90BE	0x4040	0x8A93	# <CJK>
0x90BF	0x4041	0x8ACB	# <CJK>
0x90C0	0x4042	0x901D	# <CJK>
0x90C1	0x4043	0x9192	# <CJK>
0x90C2	0x4044	0x9752	# <CJK>
0x90C3	0x4045	0x9759	# <CJK>
0x90C4	0x4046	0x6589	# <CJK>
0x90C5	0x4047	0x7A0E	# <CJK>
0x90C6	0x4048	0x8106	# <CJK>
0x90C7	0x4049	0x96BB	# <CJK>
0x90C8	0x404A	0x5E2D	# <CJK>
0x90C9	0x404B	0x60DC	# <CJK>
0x90CA	0x404C	0x621A	# <CJK>
0x90CB	0x404D	0x65A5	# <CJK>
0x90CC	0x404E	0x6614	# <CJK>
0x90CD	0x404F	0x6790	# <CJK>
0x90CE	0x4050	0x77F3	# <CJK>
0x90CF	0x4051	0x7A4D	# <CJK>
0x90D0	0x4052	0x7C4D	# <CJK>
0x90D1	0x4053	0x7E3E	# <CJK>
0x90D2	0x4054	0x810A	# <CJK>
0x90D3	0x4055	0x8CAC	# <CJK>
0x90D4	0x4056	0x8D64	# <CJK>
0x90D5	0x4057	0x8DE1	# <CJK>
0x90D6	0x4058	0x8E5F	# <CJK>
0x90D7	0x4059	0x78A9	# <CJK>
0x90D8	0x405A	0x5207	# <CJK>
0x90D9	0x405B	0x62D9	# <CJK>
0x90DA	0x405C	0x63A5	# <CJK>
0x90DB	0x405D	0x6442	# <CJK>
0x90DC	0x405E	0x6298	# <CJK>
0x90DD	0x405F	0x8A2D	# <CJK>
0x90DE	0x4060	0x7A83	# <CJK>
0x90DF	0x4061	0x7BC0	# <CJK>
0x90E0	0x4062	0x8AAC	# <CJK>
0x90E1	0x4063	0x96EA	# <CJK>
0x90E2	0x4064	0x7D76	# <CJK>
0x90E3	0x4065	0x820C	# <CJK>
0x90E4	0x4066	0x8749	# <CJK>
0x90E5	0x4067	0x4ED9	# <CJK>
0x90E6	0x4068	0x5148	# <CJK>
0x90E7	0x4069	0x5343	# <CJK>
0x90E8	0x406A	0x5360	# <CJK>
0x90E9	0x406B	0x5BA3	# <CJK>
0x90EA	0x406C	0x5C02	# <CJK>
0x90EB	0x406D	0x5C16	# <CJK>
0x90EC	0x406E	0x5DDD	# <CJK>
0x90ED	0x406F	0x6226	# <CJK>
0x90EE	0x4070	0x6247	# <CJK>
0x90EF	0x4071	0x64B0	# <CJK>
0x90F0	0x4072	0x6813	# <CJK>
0x90F1	0x4073	0x6834	# <CJK>
0x90F2	0x4074	0x6CC9	# <CJK>
0x90F3	0x4075	0x6D45	# <CJK>
0x90F4	0x4076	0x6D17	# <CJK>
0x90F5	0x4077	0x67D3	# <CJK>
0x90F6	0x4078	0x6F5C	# <CJK>
0x90F7	0x4079	0x714E	# <CJK>
0x90F8	0x407A	0x717D	# <CJK>
0x90F9	0x407B	0x65CB	# <CJK>
0x90FA	0x407C	0x7A7F	# <CJK>
0x90FB	0x407D	0x7BAD	# <CJK>
0x90FC	0x407E	0x7DDA	# <CJK>
0x9140	0x4121	0x7E4A	# <CJK>
0x9141	0x4122	0x7FA8	# <CJK>
0x9142	0x4123	0x817A	# <CJK>
0x9143	0x4124	0x821B	# <CJK>
0x9144	0x4125	0x8239	# <CJK>
0x9145	0x4126	0x85A6	# <CJK>
0x9146	0x4127	0x8A6E	# <CJK>
0x9147	0x4128	0x8CCE	# <CJK>
0x9148	0x4129	0x8DF5	# <CJK>
0x9149	0x412A	0x9078	# <CJK>
0x914A	0x412B	0x9077	# <CJK>
0x914B	0x412C	0x92AD	# <CJK>
0x914C	0x412D	0x9291	# <CJK>
0x914D	0x412E	0x9583	# <CJK>
0x914E	0x412F	0x9BAE	# <CJK>
0x914F	0x4130	0x524D	# <CJK>
0x9150	0x4131	0x5584	# <CJK>
0x9151	0x4132	0x6F38	# <CJK>
0x9152	0x4133	0x7136	# <CJK>
0x9153	0x4134	0x5168	# <CJK>
0x9154	0x4135	0x7985	# <CJK>
0x9155	0x4136	0x7E55	# <CJK>
0x9156	0x4137	0x81B3	# <CJK>
0x9157	0x4138	0x7CCE	# <CJK>
0x9158	0x4139	0x564C	# <CJK>
0x9159	0x413A	0x5851	# <CJK>
0x915A	0x413B	0x5CA8	# <CJK>
0x915B	0x413C	0x63AA	# <CJK>
0x915C	0x413D	0x66FE	# <CJK>
0x915D	0x413E	0x66FD	# <CJK>
0x915E	0x413F	0x695A	# <CJK>
0x915F	0x4140	0x72D9	# <CJK>
0x9160	0x4141	0x758F	# <CJK>
0x9161	0x4142	0x758E	# <CJK>
0x9162	0x4143	0x790E	# <CJK>
0x9163	0x4144	0x7956	# <CJK>
0x9164	0x4145	0x79DF	# <CJK>
0x9165	0x4146	0x7C97	# <CJK>
0x9166	0x4147	0x7D20	# <CJK>
0x9167	0x4148	0x7D44	# <CJK>
0x9168	0x4149	0x8607	# <CJK>
0x9169	0x414A	0x8A34	# <CJK>
0x916A	0x414B	0x963B	# <CJK>
0x916B	0x414C	0x9061	# <CJK>
0x916C	0x414D	0x9F20	# <CJK>
0x916D	0x414E	0x50E7	# <CJK>
0x916E	0x414F	0x5275	# <CJK>
0x916F	0x4150	0x53CC	# <CJK>
0x9170	0x4151	0x53E2	# <CJK>
0x9171	0x4152	0x5009	# <CJK>
0x9172	0x4153	0x55AA	# <CJK>
0x9173	0x4154	0x58EE	# <CJK>
0x9174	0x4155	0x594F	# <CJK>
0x9175	0x4156	0x723D	# <CJK>
0x9176	0x4157	0x5B8B	# <CJK>
0x9177	0x4158	0x5C64	# <CJK>
0x9178	0x4159	0x531D	# <CJK>
0x9179	0x415A	0x60E3	# <CJK>
0x917A	0x415B	0x60F3	# <CJK>
0x917B	0x415C	0x635C	# <CJK>
0x917C	0x415D	0x6383	# <CJK>
0x917D	0x415E	0x633F	# <CJK>
0x917E	0x415F	0x63BB	# <CJK>
0x9180	0x4160	0x64CD	# <CJK>
0x9181	0x4161	0x65E9	# <CJK>
0x9182	0x4162	0x66F9	# <CJK>
0x9183	0x4163	0x5DE3	# <CJK>
0x9184	0x4164	0x69CD	# <CJK>
0x9185	0x4165	0x69FD	# <CJK>
0x9186	0x4166	0x6F15	# <CJK>
0x9187	0x4167	0x71E5	# <CJK>
0x9188	0x4168	0x4E89	# <CJK>
0x9189	0x4169	0x75E9	# <CJK>
0x918A	0x416A	0x76F8	# <CJK>
0x918B	0x416B	0x7A93	# <CJK>
0x918C	0x416C	0x7CDF	# <CJK>
0x918D	0x416D	0x7DCF	# <CJK>
0x918E	0x416E	0x7D9C	# <CJK>
0x918F	0x416F	0x8061	# <CJK>
0x9190	0x4170	0x8349	# <CJK>
0x9191	0x4171	0x8358	# <CJK>
0x9192	0x4172	0x846C	# <CJK>
0x9193	0x4173	0x84BC	# <CJK>
0x9194	0x4174	0x85FB	# <CJK>
0x9195	0x4175	0x88C5	# <CJK>
0x9196	0x4176	0x8D70	# <CJK>
0x9197	0x4177	0x9001	# <CJK>
0x9198	0x4178	0x906D	# <CJK>
0x9199	0x4179	0x9397	# <CJK>
0x919A	0x417A	0x971C	# <CJK>
0x919B	0x417B	0x9A12	# <CJK>
0x919C	0x417C	0x50CF	# <CJK>
0x919D	0x417D	0x5897	# <CJK>
0x919E	0x417E	0x618E	# <CJK>
0x919F	0x4221	0x81D3	# <CJK>
0x91A0	0x4222	0x8535	# <CJK>
0x91A1	0x4223	0x8D08	# <CJK>
0x91A2	0x4224	0x9020	# <CJK>
0x91A3	0x4225	0x4FC3	# <CJK>
0x91A4	0x4226	0x5074	# <CJK>
0x91A5	0x4227	0x5247	# <CJK>
0x91A6	0x4228	0x5373	# <CJK>
0x91A7	0x4229	0x606F	# <CJK>
0x91A8	0x422A	0x6349	# <CJK>
0x91A9	0x422B	0x675F	# <CJK>
0x91AA	0x422C	0x6E2C	# <CJK>
0x91AB	0x422D	0x8DB3	# <CJK>
0x91AC	0x422E	0x901F	# <CJK>
0x91AD	0x422F	0x4FD7	# <CJK>
0x91AE	0x4230	0x5C5E	# <CJK>
0x91AF	0x4231	0x8CCA	# <CJK>
0x91B0	0x4232	0x65CF	# <CJK>
0x91B1	0x4233	0x7D9A	# <CJK>
0x91B2	0x4234	0x5352	# <CJK>
0x91B3	0x4235	0x8896	# <CJK>
0x91B4	0x4236	0x5176	# <CJK>
0x91B5	0x4237	0x63C3	# <CJK>
0x91B6	0x4238	0x5B58	# <CJK>
0x91B7	0x4239	0x5B6B	# <CJK>
0x91B8	0x423A	0x5C0A	# <CJK>
0x91B9	0x423B	0x640D	# <CJK>
0x91BA	0x423C	0x6751	# <CJK>
0x91BB	0x423D	0x905C	# <CJK>
0x91BC	0x423E	0x4ED6	# <CJK>
0x91BD	0x423F	0x591A	# <CJK>
0x91BE	0x4240	0x592A	# <CJK>
0x91BF	0x4241	0x6C70	# <CJK>
0x91C0	0x4242	0x8A51	# <CJK>
0x91C1	0x4243	0x553E	# <CJK>
0x91C2	0x4244	0x5815	# <CJK>
0x91C3	0x4245	0x59A5	# <CJK>
0x91C4	0x4246	0x60F0	# <CJK>
0x91C5	0x4247	0x6253	# <CJK>
0x91C6	0x4248	0x67C1	# <CJK>
0x91C7	0x4249	0x8235	# <CJK>
0x91C8	0x424A	0x6955	# <CJK>
0x91C9	0x424B	0x9640	# <CJK>
0x91CA	0x424C	0x99C4	# <CJK>
0x91CB	0x424D	0x9A28	# <CJK>
0x91CC	0x424E	0x4F53	# <CJK>
0x91CD	0x424F	0x5806	# <CJK>
0x91CE	0x4250	0x5BFE	# <CJK>
0x91CF	0x4251	0x8010	# <CJK>
0x91D0	0x4252	0x5CB1	# <CJK>
0x91D1	0x4253	0x5E2F	# <CJK>
0x91D2	0x4254	0x5F85	# <CJK>
0x91D3	0x4255	0x6020	# <CJK>
0x91D4	0x4256	0x614B	# <CJK>
0x91D5	0x4257	0x6234	# <CJK>
0x91D6	0x4258	0x66FF	# <CJK>
0x91D7	0x4259	0x6CF0	# <CJK>
0x91D8	0x425A	0x6EDE	# <CJK>
0x91D9	0x425B	0x80CE	# <CJK>
0x91DA	0x425C	0x817F	# <CJK>
0x91DB	0x425D	0x82D4	# <CJK>
0x91DC	0x425E	0x888B	# <CJK>
0x91DD	0x425F	0x8CB8	# <CJK>
0x91DE	0x4260	0x9000	# <CJK>
0x91DF	0x4261	0x902E	# <CJK>
0x91E0	0x4262	0x968A	# <CJK>
0x91E1	0x4263	0x9EDB	# <CJK>
0x91E2	0x4264	0x9BDB	# <CJK>
0x91E3	0x4265	0x4EE3	# <CJK>
0x91E4	0x4266	0x53F0	# <CJK>
0x91E5	0x4267	0x5927	# <CJK>
0x91E6	0x4268	0x7B2C	# <CJK>
0x91E7	0x4269	0x918D	# <CJK>
0x91E8	0x426A	0x984C	# <CJK>
0x91E9	0x426B	0x9DF9	# <CJK>
0x91EA	0x426C	0x6EDD	# <CJK>
0x91EB	0x426D	0x7027	# <CJK>
0x91EC	0x426E	0x5353	# <CJK>
0x91ED	0x426F	0x5544	# <CJK>
0x91EE	0x4270	0x5B85	# <CJK>
0x91EF	0x4271	0x6258	# <CJK>
0x91F0	0x4272	0x629E	# <CJK>
0x91F1	0x4273	0x62D3	# <CJK>
0x91F2	0x4274	0x6CA2	# <CJK>
0x91F3	0x4275	0x6FEF	# <CJK>
0x91F4	0x4276	0x7422	# <CJK>
0x91F5	0x4277	0x8A17	# <CJK>
0x91F6	0x4278	0x9438	# <CJK>
0x91F7	0x4279	0x6FC1	# <CJK>
0x91F8	0x427A	0x8AFE	# <CJK>
0x91F9	0x427B	0x8338	# <CJK>
0x91FA	0x427C	0x51E7	# <CJK>
0x91FB	0x427D	0x86F8	# <CJK>
0x91FC	0x427E	0x53EA	# <CJK>
0x9240	0x4321	0x53E9	# <CJK>
0x9241	0x4322	0x4F46	# <CJK>
0x9242	0x4323	0x9054	# <CJK>
0x9243	0x4324	0x8FB0	# <CJK>
0x9244	0x4325	0x596A	# <CJK>
0x9245	0x4326	0x8131	# <CJK>
0x9246	0x4327	0x5DFD	# <CJK>
0x9247	0x4328	0x7AEA	# <CJK>
0x9248	0x4329	0x8FBF	# <CJK>
0x9249	0x432A	0x68DA	# <CJK>
0x924A	0x432B	0x8C37	# <CJK>
0x924B	0x432C	0x72F8	# <CJK>
0x924C	0x432D	0x9C48	# <CJK>
0x924D	0x432E	0x6A3D	# <CJK>
0x924E	0x432F	0x8AB0	# <CJK>
0x924F	0x4330	0x4E39	# <CJK>
0x9250	0x4331	0x5358	# <CJK>
0x9251	0x4332	0x5606	# <CJK>
0x9252	0x4333	0x5766	# <CJK>
0x9253	0x4334	0x62C5	# <CJK>
0x9254	0x4335	0x63A2	# <CJK>
0x9255	0x4336	0x65E6	# <CJK>
0x9256	0x4337	0x6B4E	# <CJK>
0x9257	0x4338	0x6DE1	# <CJK>
0x9258	0x4339	0x6E5B	# <CJK>
0x9259	0x433A	0x70AD	# <CJK>
0x925A	0x433B	0x77ED	# <CJK>
0x925B	0x433C	0x7AEF	# <CJK>
0x925C	0x433D	0x7BAA	# <CJK>
0x925D	0x433E	0x7DBB	# <CJK>
0x925E	0x433F	0x803D	# <CJK>
0x925F	0x4340	0x80C6	# <CJK>
0x9260	0x4341	0x86CB	# <CJK>
0x9261	0x4342	0x8A95	# <CJK>
0x9262	0x4343	0x935B	# <CJK>
0x9263	0x4344	0x56E3	# <CJK>
0x9264	0x4345	0x58C7	# <CJK>
0x9265	0x4346	0x5F3E	# <CJK>
0x9266	0x4347	0x65AD	# <CJK>
0x9267	0x4348	0x6696	# <CJK>
0x9268	0x4349	0x6A80	# <CJK>
0x9269	0x434A	0x6BB5	# <CJK>
0x926A	0x434B	0x7537	# <CJK>
0x926B	0x434C	0x8AC7	# <CJK>
0x926C	0x434D	0x5024	# <CJK>
0x926D	0x434E	0x77E5	# <CJK>
0x926E	0x434F	0x5730	# <CJK>
0x926F	0x4350	0x5F1B	# <CJK>
0x9270	0x4351	0x6065	# <CJK>
0x9271	0x4352	0x667A	# <CJK>
0x9272	0x4353	0x6C60	# <CJK>
0x9273	0x4354	0x75F4	# <CJK>
0x9274	0x4355	0x7A1A	# <CJK>
0x9275	0x4356	0x7F6E	# <CJK>
0x9276	0x4357	0x81F4	# <CJK>
0x9277	0x4358	0x8718	# <CJK>
0x9278	0x4359	0x9045	# <CJK>
0x9279	0x435A	0x99B3	# <CJK>
0x927A	0x435B	0x7BC9	# <CJK>
0x927B	0x435C	0x755C	# <CJK>
0x927C	0x435D	0x7AF9	# <CJK>
0x927D	0x435E	0x7B51	# <CJK>
0x927E	0x435F	0x84C4	# <CJK>
0x9280	0x4360	0x9010	# <CJK>
0x9281	0x4361	0x79E9	# <CJK>
0x9282	0x4362	0x7A92	# <CJK>
0x9283	0x4363	0x8336	# <CJK>
0x9284	0x4364	0x5AE1	# <CJK>
0x9285	0x4365	0x7740	# <CJK>
0x9286	0x4366	0x4E2D	# <CJK>
0x9287	0x4367	0x4EF2	# <CJK>
0x9288	0x4368	0x5B99	# <CJK>
0x9289	0x4369	0x5FE0	# <CJK>
0x928A	0x436A	0x62BD	# <CJK>
0x928B	0x436B	0x663C	# <CJK>
0x928C	0x436C	0x67F1	# <CJK>
0x928D	0x436D	0x6CE8	# <CJK>
0x928E	0x436E	0x866B	# <CJK>
0x928F	0x436F	0x8877	# <CJK>
0x9290	0x4370	0x8A3B	# <CJK>
0x9291	0x4371	0x914E	# <CJK>
0x9292	0x4372	0x92F3	# <CJK>
0x9293	0x4373	0x99D0	# <CJK>
0x9294	0x4374	0x6A17	# <CJK>
0x9295	0x4375	0x7026	# <CJK>
0x9296	0x4376	0x732A	# <CJK>
0x9297	0x4377	0x82E7	# <CJK>
0x9298	0x4378	0x8457	# <CJK>
0x9299	0x4379	0x8CAF	# <CJK>
0x929A	0x437A	0x4E01	# <CJK>
0x929B	0x437B	0x5146	# <CJK>
0x929C	0x437C	0x51CB	# <CJK>
0x929D	0x437D	0x558B	# <CJK>
0x929E	0x437E	0x5BF5	# <CJK>
0x929F	0x4421	0x5E16	# <CJK>
0x92A0	0x4422	0x5E33	# <CJK>
0x92A1	0x4423	0x5E81	# <CJK>
0x92A2	0x4424	0x5F14	# <CJK>
0x92A3	0x4425	0x5F35	# <CJK>
0x92A4	0x4426	0x5F6B	# <CJK>
0x92A5	0x4427	0x5FB4	# <CJK>
0x92A6	0x4428	0x61F2	# <CJK>
0x92A7	0x4429	0x6311	# <CJK>
0x92A8	0x442A	0x66A2	# <CJK>
0x92A9	0x442B	0x671D	# <CJK>
0x92AA	0x442C	0x6F6E	# <CJK>
0x92AB	0x442D	0x7252	# <CJK>
0x92AC	0x442E	0x753A	# <CJK>
0x92AD	0x442F	0x773A	# <CJK>
0x92AE	0x4430	0x8074	# <CJK>
0x92AF	0x4431	0x8139	# <CJK>
0x92B0	0x4432	0x8178	# <CJK>
0x92B1	0x4433	0x8776	# <CJK>
0x92B2	0x4434	0x8ABF	# <CJK>
0x92B3	0x4435	0x8ADC	# <CJK>
0x92B4	0x4436	0x8D85	# <CJK>
0x92B5	0x4437	0x8DF3	# <CJK>
0x92B6	0x4438	0x929A	# <CJK>
0x92B7	0x4439	0x9577	# <CJK>
0x92B8	0x443A	0x9802	# <CJK>
0x92B9	0x443B	0x9CE5	# <CJK>
0x92BA	0x443C	0x52C5	# <CJK>
0x92BB	0x443D	0x6357	# <CJK>
0x92BC	0x443E	0x76F4	# <CJK>
0x92BD	0x443F	0x6715	# <CJK>
0x92BE	0x4440	0x6C88	# <CJK>
0x92BF	0x4441	0x73CD	# <CJK>
0x92C0	0x4442	0x8CC3	# <CJK>
0x92C1	0x4443	0x93AE	# <CJK>
0x92C2	0x4444	0x9673	# <CJK>
0x92C3	0x4445	0x6D25	# <CJK>
0x92C4	0x4446	0x589C	# <CJK>
0x92C5	0x4447	0x690E	# <CJK>
0x92C6	0x4448	0x69CC	# <CJK>
0x92C7	0x4449	0x8FFD	# <CJK>
0x92C8	0x444A	0x939A	# <CJK>
0x92C9	0x444B	0x75DB	# <CJK>
0x92CA	0x444C	0x901A	# <CJK>
0x92CB	0x444D	0x585A	# <CJK>
0x92CC	0x444E	0x6802	# <CJK>
0x92CD	0x444F	0x63B4	# <CJK>
0x92CE	0x4450	0x69FB	# <CJK>
0x92CF	0x4451	0x4F43	# <CJK>
0x92D0	0x4452	0x6F2C	# <CJK>
0x92D1	0x4453	0x67D8	# <CJK>
0x92D2	0x4454	0x8FBB	# <CJK>
0x92D3	0x4455	0x8526	# <CJK>
0x92D4	0x4456	0x7DB4	# <CJK>
0x92D5	0x4457	0x9354	# <CJK>
0x92D6	0x4458	0x693F	# <CJK>
0x92D7	0x4459	0x6F70	# <CJK>
0x92D8	0x445A	0x576A	# <CJK>
0x92D9	0x445B	0x58F7	# <CJK>
0x92DA	0x445C	0x5B2C	# <CJK>
0x92DB	0x445D	0x7D2C	# <CJK>
0x92DC	0x445E	0x722A	# <CJK>
0x92DD	0x445F	0x540A	# <CJK>
0x92DE	0x4460	0x91E3	# <CJK>
0x92DF	0x4461	0x9DB4	# <CJK>
0x92E0	0x4462	0x4EAD	# <CJK>
0x92E1	0x4463	0x4F4E	# <CJK>
0x92E2	0x4464	0x505C	# <CJK>
0x92E3	0x4465	0x5075	# <CJK>
0x92E4	0x4466	0x5243	# <CJK>
0x92E5	0x4467	0x8C9E	# <CJK>
0x92E6	0x4468	0x5448	# <CJK>
0x92E7	0x4469	0x5824	# <CJK>
0x92E8	0x446A	0x5B9A	# <CJK>
0x92E9	0x446B	0x5E1D	# <CJK>
0x92EA	0x446C	0x5E95	# <CJK>
0x92EB	0x446D	0x5EAD	# <CJK>
0x92EC	0x446E	0x5EF7	# <CJK>
0x92ED	0x446F	0x5F1F	# <CJK>
0x92EE	0x4470	0x608C	# <CJK>
0x92EF	0x4471	0x62B5	# <CJK>
0x92F0	0x4472	0x633A	# <CJK>
0x92F1	0x4473	0x63D0	# <CJK>
0x92F2	0x4474	0x68AF	# <CJK>
0x92F3	0x4475	0x6C40	# <CJK>
0x92F4	0x4476	0x7887	# <CJK>
0x92F5	0x4477	0x798E	# <CJK>
0x92F6	0x4478	0x7A0B	# <CJK>
0x92F7	0x4479	0x7DE0	# <CJK>
0x92F8	0x447A	0x8247	# <CJK>
0x92F9	0x447B	0x8A02	# <CJK>
0x92FA	0x447C	0x8AE6	# <CJK>
0x92FB	0x447D	0x8E44	# <CJK>
0x92FC	0x447E	0x9013	# <CJK>
0x9340	0x4521	0x90B8	# <CJK>
0x9341	0x4522	0x912D	# <CJK>
0x9342	0x4523	0x91D8	# <CJK>
0x9343	0x4524	0x9F0E	# <CJK>
0x9344	0x4525	0x6CE5	# <CJK>
0x9345	0x4526	0x6458	# <CJK>
0x9346	0x4527	0x64E2	# <CJK>
0x9347	0x4528	0x6575	# <CJK>
0x9348	0x4529	0x6EF4	# <CJK>
0x9349	0x452A	0x7684	# <CJK>
0x934A	0x452B	0x7B1B	# <CJK>
0x934B	0x452C	0x9069	# <CJK>
0x934C	0x452D	0x93D1	# <CJK>
0x934D	0x452E	0x6EBA	# <CJK>
0x934E	0x452F	0x54F2	# <CJK>
0x934F	0x4530	0x5FB9	# <CJK>
0x9350	0x4531	0x64A4	# <CJK>
0x9351	0x4532	0x8F4D	# <CJK>
0x9352	0x4533	0x8FED	# <CJK>
0x9353	0x4534	0x9244	# <CJK>
0x9354	0x4535	0x5178	# <CJK>
0x9355	0x4536	0x586B	# <CJK>
0x9356	0x4537	0x5929	# <CJK>
0x9357	0x4538	0x5C55	# <CJK>
0x9358	0x4539	0x5E97	# <CJK>
0x9359	0x453A	0x6DFB	# <CJK>
0x935A	0x453B	0x7E8F	# <CJK>
0x935B	0x453C	0x751C	# <CJK>
0x935C	0x453D	0x8CBC	# <CJK>
0x935D	0x453E	0x8EE2	# <CJK>
0x935E	0x453F	0x985B	# <CJK>
0x935F	0x4540	0x70B9	# <CJK>
0x9360	0x4541	0x4F1D	# <CJK>
0x9361	0x4542	0x6BBF	# <CJK>
0x9362	0x4543	0x6FB1	# <CJK>
0x9363	0x4544	0x7530	# <CJK>
0x9364	0x4545	0x96FB	# <CJK>
0x9365	0x4546	0x514E	# <CJK>
0x9366	0x4547	0x5410	# <CJK>
0x9367	0x4548	0x5835	# <CJK>
0x9368	0x4549	0x5857	# <CJK>
0x9369	0x454A	0x59AC	# <CJK>
0x936A	0x454B	0x5C60	# <CJK>
0x936B	0x454C	0x5F92	# <CJK>
0x936C	0x454D	0x6597	# <CJK>
0x936D	0x454E	0x675C	# <CJK>
0x936E	0x454F	0x6E21	# <CJK>
0x936F	0x4550	0x767B	# <CJK>
0x9370	0x4551	0x83DF	# <CJK>
0x9371	0x4552	0x8CED	# <CJK>
0x9372	0x4553	0x9014	# <CJK>
0x9373	0x4554	0x90FD	# <CJK>
0x9374	0x4555	0x934D	# <CJK>
0x9375	0x4556	0x7825	# <CJK>
0x9376	0x4557	0x783A	# <CJK>
0x9377	0x4558	0x52AA	# <CJK>
0x9378	0x4559	0x5EA6	# <CJK>
0x9379	0x455A	0x571F	# <CJK>
0x937A	0x455B	0x5974	# <CJK>
0x937B	0x455C	0x6012	# <CJK>
0x937C	0x455D	0x5012	# <CJK>
0x937D	0x455E	0x515A	# <CJK>
0x937E	0x455F	0x51AC	# <CJK>
0x9380	0x4560	0x51CD	# <CJK>
0x9381	0x4561	0x5200	# <CJK>
0x9382	0x4562	0x5510	# <CJK>
0x9383	0x4563	0x5854	# <CJK>
0x9384	0x4564	0x5858	# <CJK>
0x9385	0x4565	0x5957	# <CJK>
0x9386	0x4566	0x5B95	# <CJK>
0x9387	0x4567	0x5CF6	# <CJK>
0x9388	0x4568	0x5D8B	# <CJK>
0x9389	0x4569	0x60BC	# <CJK>
0x938A	0x456A	0x6295	# <CJK>
0x938B	0x456B	0x642D	# <CJK>
0x938C	0x456C	0x6771	# <CJK>
0x938D	0x456D	0x6843	# <CJK>
0x938E	0x456E	0x68BC	# <CJK>
0x938F	0x456F	0x68DF	# <CJK>
0x9390	0x4570	0x76D7	# <CJK>
0x9391	0x4571	0x6DD8	# <CJK>
0x9392	0x4572	0x6E6F	# <CJK>
0x9393	0x4573	0x6D9B	# <CJK>
0x9394	0x4574	0x706F	# <CJK>
0x9395	0x4575	0x71C8	# <CJK>
0x9396	0x4576	0x5F53	# <CJK>
0x9397	0x4577	0x75D8	# <CJK>
0x9398	0x4578	0x7977	# <CJK>
0x9399	0x4579	0x7B49	# <CJK>
0x939A	0x457A	0x7B54	# <CJK>
0x939B	0x457B	0x7B52	# <CJK>
0x939C	0x457C	0x7CD6	# <CJK>
0x939D	0x457D	0x7D71	# <CJK>
0x939E	0x457E	0x5230	# <CJK>
0x939F	0x4621	0x8463	# <CJK>
0x93A0	0x4622	0x8569	# <CJK>
0x93A1	0x4623	0x85E4	# <CJK>
0x93A2	0x4624	0x8A0E	# <CJK>
0x93A3	0x4625	0x8B04	# <CJK>
0x93A4	0x4626	0x8C46	# <CJK>
0x93A5	0x4627	0x8E0F	# <CJK>
0x93A6	0x4628	0x9003	# <CJK>
0x93A7	0x4629	0x900F	# <CJK>
0x93A8	0x462A	0x9419	# <CJK>
0x93A9	0x462B	0x9676	# <CJK>
0x93AA	0x462C	0x982D	# <CJK>
0x93AB	0x462D	0x9A30	# <CJK>
0x93AC	0x462E	0x95D8	# <CJK>
0x93AD	0x462F	0x50CD	# <CJK>
0x93AE	0x4630	0x52D5	# <CJK>
0x93AF	0x4631	0x540C	# <CJK>
0x93B0	0x4632	0x5802	# <CJK>
0x93B1	0x4633	0x5C0E	# <CJK>
0x93B2	0x4634	0x61A7	# <CJK>
0x93B3	0x4635	0x649E	# <CJK>
0x93B4	0x4636	0x6D1E	# <CJK>
0x93B5	0x4637	0x77B3	# <CJK>
0x93B6	0x4638	0x7AE5	# <CJK>
0x93B7	0x4639	0x80F4	# <CJK>
0x93B8	0x463A	0x8404	# <CJK>
0x93B9	0x463B	0x9053	# <CJK>
0x93BA	0x463C	0x9285	# <CJK>
0x93BB	0x463D	0x5CE0	# <CJK>
0x93BC	0x463E	0x9D07	# <CJK>
0x93BD	0x463F	0x533F	# <CJK>
0x93BE	0x4640	0x5F97	# <CJK>
0x93BF	0x4641	0x5FB3	# <CJK>
0x93C0	0x4642	0x6D9C	# <CJK>
0x93C1	0x4643	0x7279	# <CJK>
0x93C2	0x4644	0x7763	# <CJK>
0x93C3	0x4645	0x79BF	# <CJK>
0x93C4	0x4646	0x7BE4	# <CJK>
0x93C5	0x4647	0x6BD2	# <CJK>
0x93C6	0x4648	0x72EC	# <CJK>
0x93C7	0x4649	0x8AAD	# <CJK>
0x93C8	0x464A	0x6803	# <CJK>
0x93C9	0x464B	0x6A61	# <CJK>
0x93CA	0x464C	0x51F8	# <CJK>
0x93CB	0x464D	0x7A81	# <CJK>
0x93CC	0x464E	0x6934	# <CJK>
0x93CD	0x464F	0x5C4A	# <CJK>
0x93CE	0x4650	0x9CF6	# <CJK>
0x93CF	0x4651	0x82EB	# <CJK>
0x93D0	0x4652	0x5BC5	# <CJK>
0x93D1	0x4653	0x9149	# <CJK>
0x93D2	0x4654	0x701E	# <CJK>
0x93D3	0x4655	0x5678	# <CJK>
0x93D4	0x4656	0x5C6F	# <CJK>
0x93D5	0x4657	0x60C7	# <CJK>
0x93D6	0x4658	0x6566	# <CJK>
0x93D7	0x4659	0x6C8C	# <CJK>
0x93D8	0x465A	0x8C5A	# <CJK>
0x93D9	0x465B	0x9041	# <CJK>
0x93DA	0x465C	0x9813	# <CJK>
0x93DB	0x465D	0x5451	# <CJK>
0x93DC	0x465E	0x66C7	# <CJK>
0x93DD	0x465F	0x920D	# <CJK>
0x93DE	0x4660	0x5948	# <CJK>
0x93DF	0x4661	0x90A3	# <CJK>
0x93E0	0x4662	0x5185	# <CJK>
0x93E1	0x4663	0x4E4D	# <CJK>
0x93E2	0x4664	0x51EA	# <CJK>
0x93E3	0x4665	0x8599	# <CJK>
0x93E4	0x4666	0x8B0E	# <CJK>
0x93E5	0x4667	0x7058	# <CJK>
0x93E6	0x4668	0x637A	# <CJK>
0x93E7	0x4669	0x934B	# <CJK>
0x93E8	0x466A	0x6962	# <CJK>
0x93E9	0x466B	0x99B4	# <CJK>
0x93EA	0x466C	0x7E04	# <CJK>
0x93EB	0x466D	0x7577	# <CJK>
0x93EC	0x466E	0x5357	# <CJK>
0x93ED	0x466F	0x6960	# <CJK>
0x93EE	0x4670	0x8EDF	# <CJK>
0x93EF	0x4671	0x96E3	# <CJK>
0x93F0	0x4672	0x6C5D	# <CJK>
0x93F1	0x4673	0x4E8C	# <CJK>
0x93F2	0x4674	0x5C3C	# <CJK>
0x93F3	0x4675	0x5F10	# <CJK>
0x93F4	0x4676	0x8FE9	# <CJK>
0x93F5	0x4677	0x5302	# <CJK>
0x93F6	0x4678	0x8CD1	# <CJK>
0x93F7	0x4679	0x8089	# <CJK>
0x93F8	0x467A	0x8679	# <CJK>
0x93F9	0x467B	0x5EFF	# <CJK>
0x93FA	0x467C	0x65E5	# <CJK>
0x93FB	0x467D	0x4E73	# <CJK>
0x93FC	0x467E	0x5165	# <CJK>
0x9440	0x4721	0x5982	# <CJK>
0x9441	0x4722	0x5C3F	# <CJK>
0x9442	0x4723	0x97EE	# <CJK>
0x9443	0x4724	0x4EFB	# <CJK>
0x9444	0x4725	0x598A	# <CJK>
0x9445	0x4726	0x5FCD	# <CJK>
0x9446	0x4727	0x8A8D	# <CJK>
0x9447	0x4728	0x6FE1	# <CJK>
0x9448	0x4729	0x79B0	# <CJK>
0x9449	0x472A	0x7962	# <CJK>
0x944A	0x472B	0x5BE7	# <CJK>
0x944B	0x472C	0x8471	# <CJK>
0x944C	0x472D	0x732B	# <CJK>
0x944D	0x472E	0x71B1	# <CJK>
0x944E	0x472F	0x5E74	# <CJK>
0x944F	0x4730	0x5FF5	# <CJK>
0x9450	0x4731	0x637B	# <CJK>
0x9451	0x4732	0x649A	# <CJK>
0x9452	0x4733	0x71C3	# <CJK>
0x9453	0x4734	0x7C98	# <CJK>
0x9454	0x4735	0x4E43	# <CJK>
0x9455	0x4736	0x5EFC	# <CJK>
0x9456	0x4737	0x4E4B	# <CJK>
0x9457	0x4738	0x57DC	# <CJK>
0x9458	0x4739	0x56A2	# <CJK>
0x9459	0x473A	0x60A9	# <CJK>
0x945A	0x473B	0x6FC3	# <CJK>
0x945B	0x473C	0x7D0D	# <CJK>
0x945C	0x473D	0x80FD	# <CJK>
0x945D	0x473E	0x8133	# <CJK>
0x945E	0x473F	0x81BF	# <CJK>
0x945F	0x4740	0x8FB2	# <CJK>
0x9460	0x4741	0x8997	# <CJK>
0x9461	0x4742	0x86A4	# <CJK>
0x9462	0x4743	0x5DF4	# <CJK>
0x9463	0x4744	0x628A	# <CJK>
0x9464	0x4745	0x64AD	# <CJK>
0x9465	0x4746	0x8987	# <CJK>
0x9466	0x4747	0x6777	# <CJK>
0x9467	0x4748	0x6CE2	# <CJK>
0x9468	0x4749	0x6D3E	# <CJK>
0x9469	0x474A	0x7436	# <CJK>
0x946A	0x474B	0x7834	# <CJK>
0x946B	0x474C	0x5A46	# <CJK>
0x946C	0x474D	0x7F75	# <CJK>
0x946D	0x474E	0x82AD	# <CJK>
0x946E	0x474F	0x99AC	# <CJK>
0x946F	0x4750	0x4FF3	# <CJK>
0x9470	0x4751	0x5EC3	# <CJK>
0x9471	0x4752	0x62DD	# <CJK>
0x9472	0x4753	0x6392	# <CJK>
0x9473	0x4754	0x6557	# <CJK>
0x9474	0x4755	0x676F	# <CJK>
0x9475	0x4756	0x76C3	# <CJK>
0x9476	0x4757	0x724C	# <CJK>
0x9477	0x4758	0x80CC	# <CJK>
0x9478	0x4759	0x80BA	# <CJK>
0x9479	0x475A	0x8F29	# <CJK>
0x947A	0x475B	0x914D	# <CJK>
0x947B	0x475C	0x500D	# <CJK>
0x947C	0x475D	0x57F9	# <CJK>
0x947D	0x475E	0x5A92	# <CJK>
0x947E	0x475F	0x6885	# <CJK>
0x9480	0x4760	0x6973	# <CJK>
0x9481	0x4761	0x7164	# <CJK>
0x9482	0x4762	0x72FD	# <CJK>
0x9483	0x4763	0x8CB7	# <CJK>
0x9484	0x4764	0x58F2	# <CJK>
0x9485	0x4765	0x8CE0	# <CJK>
0x9486	0x4766	0x966A	# <CJK>
0x9487	0x4767	0x9019	# <CJK>
0x9488	0x4768	0x877F	# <CJK>
0x9489	0x4769	0x79E4	# <CJK>
0x948A	0x476A	0x77E7	# <CJK>
0x948B	0x476B	0x8429	# <CJK>
0x948C	0x476C	0x4F2F	# <CJK>
0x948D	0x476D	0x5265	# <CJK>
0x948E	0x476E	0x535A	# <CJK>
0x948F	0x476F	0x62CD	# <CJK>
0x9490	0x4770	0x67CF	# <CJK>
0x9491	0x4771	0x6CCA	# <CJK>
0x9492	0x4772	0x767D	# <CJK>
0x9493	0x4773	0x7B94	# <CJK>
0x9494	0x4774	0x7C95	# <CJK>
0x9495	0x4775	0x8236	# <CJK>
0x9496	0x4776	0x8584	# <CJK>
0x9497	0x4777	0x8FEB	# <CJK>
0x9498	0x4778	0x66DD	# <CJK>
0x9499	0x4779	0x6F20	# <CJK>
0x949A	0x477A	0x7206	# <CJK>
0x949B	0x477B	0x7E1B	# <CJK>
0x949C	0x477C	0x83AB	# <CJK>
0x949D	0x477D	0x99C1	# <CJK>
0x949E	0x477E	0x9EA6	# <CJK>
0x949F	0x4821	0x51FD	# <CJK>
0x94A0	0x4822	0x7BB1	# <CJK>
0x94A1	0x4823	0x7872	# <CJK>
0x94A2	0x4824	0x7BB8	# <CJK>
0x94A3	0x4825	0x8087	# <CJK>
0x94A4	0x4826	0x7B48	# <CJK>
0x94A5	0x4827	0x6AE8	# <CJK>
0x94A6	0x4828	0x5E61	# <CJK>
0x94A7	0x4829	0x808C	# <CJK>
0x94A8	0x482A	0x7551	# <CJK>
0x94A9	0x482B	0x7560	# <CJK>
0x94AA	0x482C	0x516B	# <CJK>
0x94AB	0x482D	0x9262	# <CJK>
0x94AC	0x482E	0x6E8C	# <CJK>
0x94AD	0x482F	0x767A	# <CJK>
0x94AE	0x4830	0x9197	# <CJK>
0x94AF	0x4831	0x9AEA	# <CJK>
0x94B0	0x4832	0x4F10	# <CJK>
0x94B1	0x4833	0x7F70	# <CJK>
0x94B2	0x4834	0x629C	# <CJK>
0x94B3	0x4835	0x7B4F	# <CJK>
0x94B4	0x4836	0x95A5	# <CJK>
0x94B5	0x4837	0x9CE9	# <CJK>
0x94B6	0x4838	0x567A	# <CJK>
0x94B7	0x4839	0x5859	# <CJK>
0x94B8	0x483A	0x86E4	# <CJK>
0x94B9	0x483B	0x96BC	# <CJK>
0x94BA	0x483C	0x4F34	# <CJK>
0x94BB	0x483D	0x5224	# <CJK>
0x94BC	0x483E	0x534A	# <CJK>
0x94BD	0x483F	0x53CD	# <CJK>
0x94BE	0x4840	0x53DB	# <CJK>
0x94BF	0x4841	0x5E06	# <CJK>
0x94C0	0x4842	0x642C	# <CJK>
0x94C1	0x4843	0x6591	# <CJK>
0x94C2	0x4844	0x677F	# <CJK>
0x94C3	0x4845	0x6C3E	# <CJK>
0x94C4	0x4846	0x6C4E	# <CJK>
0x94C5	0x4847	0x7248	# <CJK>
0x94C6	0x4848	0x72AF	# <CJK>
0x94C7	0x4849	0x73ED	# <CJK>
0x94C8	0x484A	0x7554	# <CJK>
0x94C9	0x484B	0x7E41	# <CJK>
0x94CA	0x484C	0x822C	# <CJK>
0x94CB	0x484D	0x85E9	# <CJK>
0x94CC	0x484E	0x8CA9	# <CJK>
0x94CD	0x484F	0x7BC4	# <CJK>
0x94CE	0x4850	0x91C6	# <CJK>
0x94CF	0x4851	0x7169	# <CJK>
0x94D0	0x4852	0x9812	# <CJK>
0x94D1	0x4853	0x98EF	# <CJK>
0x94D2	0x4854	0x633D	# <CJK>
0x94D3	0x4855	0x6669	# <CJK>
0x94D4	0x4856	0x756A	# <CJK>
0x94D5	0x4857	0x76E4	# <CJK>
0x94D6	0x4858	0x78D0	# <CJK>
0x94D7	0x4859	0x8543	# <CJK>
0x94D8	0x485A	0x86EE	# <CJK>
0x94D9	0x485B	0x532A	# <CJK>
0x94DA	0x485C	0x5351	# <CJK>
0x94DB	0x485D	0x5426	# <CJK>
0x94DC	0x485E	0x5983	# <CJK>
0x94DD	0x485F	0x5E87	# <CJK>
0x94DE	0x4860	0x5F7C	# <CJK>
0x94DF	0x4861	0x60B2	# <CJK>
0x94E0	0x4862	0x6249	# <CJK>
0x94E1	0x4863	0x6279	# <CJK>
0x94E2	0x4864	0x62AB	# <CJK>
0x94E3	0x4865	0x6590	# <CJK>
0x94E4	0x4866	0x6BD4	# <CJK>
0x94E5	0x4867	0x6CCC	# <CJK>
0x94E6	0x4868	0x75B2	# <CJK>
0x94E7	0x4869	0x76AE	# <CJK>
0x94E8	0x486A	0x7891	# <CJK>
0x94E9	0x486B	0x79D8	# <CJK>
0x94EA	0x486C	0x7DCB	# <CJK>
0x94EB	0x486D	0x7F77	# <CJK>
0x94EC	0x486E	0x80A5	# <CJK>
0x94ED	0x486F	0x88AB	# <CJK>
0x94EE	0x4870	0x8AB9	# <CJK>
0x94EF	0x4871	0x8CBB	# <CJK>
0x94F0	0x4872	0x907F	# <CJK>
0x94F1	0x4873	0x975E	# <CJK>
0x94F2	0x4874	0x98DB	# <CJK>
0x94F3	0x4875	0x6A0B	# <CJK>
0x94F4	0x4876	0x7C38	# <CJK>
0x94F5	0x4877	0x5099	# <CJK>
0x94F6	0x4878	0x5C3E	# <CJK>
0x94F7	0x4879	0x5FAE	# <CJK>
0x94F8	0x487A	0x6787	# <CJK>
0x94F9	0x487B	0x6BD8	# <CJK>
0x94FA	0x487C	0x7435	# <CJK>
0x94FB	0x487D	0x7709	# <CJK>
0x94FC	0x487E	0x7F8E	# <CJK>
0x9540	0x4921	0x9F3B	# <CJK>
0x9541	0x4922	0x67CA	# <CJK>
0x9542	0x4923	0x7A17	# <CJK>
0x9543	0x4924	0x5339	# <CJK>
0x9544	0x4925	0x758B	# <CJK>
0x9545	0x4926	0x9AED	# <CJK>
0x9546	0x4927	0x5F66	# <CJK>
0x9547	0x4928	0x819D	# <CJK>
0x9548	0x4929	0x83F1	# <CJK>
0x9549	0x492A	0x8098	# <CJK>
0x954A	0x492B	0x5F3C	# <CJK>
0x954B	0x492C	0x5FC5	# <CJK>
0x954C	0x492D	0x7562	# <CJK>
0x954D	0x492E	0x7B46	# <CJK>
0x954E	0x492F	0x903C	# <CJK>
0x954F	0x4930	0x6867	# <CJK>
0x9550	0x4931	0x59EB	# <CJK>
0x9551	0x4932	0x5A9B	# <CJK>
0x9552	0x4933	0x7D10	# <CJK>
0x9553	0x4934	0x767E	# <CJK>
0x9554	0x4935	0x8B2C	# <CJK>
0x9555	0x4936	0x4FF5	# <CJK>
0x9556	0x4937	0x5F6A	# <CJK>
0x9557	0x4938	0x6A19	# <CJK>
0x9558	0x4939	0x6C37	# <CJK>
0x9559	0x493A	0x6F02	# <CJK>
0x955A	0x493B	0x74E2	# <CJK>
0x955B	0x493C	0x7968	# <CJK>
0x955C	0x493D	0x8868	# <CJK>
0x955D	0x493E	0x8A55	# <CJK>
0x955E	0x493F	0x8C79	# <CJK>
0x955F	0x4940	0x5EDF	# <CJK>
0x9560	0x4941	0x63CF	# <CJK>
0x9561	0x4942	0x75C5	# <CJK>
0x9562	0x4943	0x79D2	# <CJK>
0x9563	0x4944	0x82D7	# <CJK>
0x9564	0x4945	0x9328	# <CJK>
0x9565	0x4946	0x92F2	# <CJK>
0x9566	0x4947	0x849C	# <CJK>
0x9567	0x4948	0x86ED	# <CJK>
0x9568	0x4949	0x9C2D	# <CJK>
0x9569	0x494A	0x54C1	# <CJK>
0x956A	0x494B	0x5F6C	# <CJK>
0x956B	0x494C	0x658C	# <CJK>
0x956C	0x494D	0x6D5C	# <CJK>
0x956D	0x494E	0x7015	# <CJK>
0x956E	0x494F	0x8CA7	# <CJK>
0x956F	0x4950	0x8CD3	# <CJK>
0x9570	0x4951	0x983B	# <CJK>
0x9571	0x4952	0x654F	# <CJK>
0x9572	0x4953	0x74F6	# <CJK>
0x9573	0x4954	0x4E0D	# <CJK>
0x9574	0x4955	0x4ED8	# <CJK>
0x9575	0x4956	0x57E0	# <CJK>
0x9576	0x4957	0x592B	# <CJK>
0x9577	0x4958	0x5A66	# <CJK>
0x9578	0x4959	0x5BCC	# <CJK>
0x9579	0x495A	0x51A8	# <CJK>
0x957A	0x495B	0x5E03	# <CJK>
0x957B	0x495C	0x5E9C	# <CJK>
0x957C	0x495D	0x6016	# <CJK>
0x957D	0x495E	0x6276	# <CJK>
0x957E	0x495F	0x6577	# <CJK>
0x9580	0x4960	0x65A7	# <CJK>
0x9581	0x4961	0x666E	# <CJK>
0x9582	0x4962	0x6D6E	# <CJK>
0x9583	0x4963	0x7236	# <CJK>
0x9584	0x4964	0x7B26	# <CJK>
0x9585	0x4965	0x8150	# <CJK>
0x9586	0x4966	0x819A	# <CJK>
0x9587	0x4967	0x8299	# <CJK>
0x9588	0x4968	0x8B5C	# <CJK>
0x9589	0x4969	0x8CA0	# <CJK>
0x958A	0x496A	0x8CE6	# <CJK>
0x958B	0x496B	0x8D74	# <CJK>
0x958C	0x496C	0x961C	# <CJK>
0x958D	0x496D	0x9644	# <CJK>
0x958E	0x496E	0x4FAE	# <CJK>
0x958F	0x496F	0x64AB	# <CJK>
0x9590	0x4970	0x6B66	# <CJK>
0x9591	0x4971	0x821E	# <CJK>
0x9592	0x4972	0x8461	# <CJK>
0x9593	0x4973	0x856A	# <CJK>
0x9594	0x4974	0x90E8	# <CJK>
0x9595	0x4975	0x5C01	# <CJK>
0x9596	0x4976	0x6953	# <CJK>
0x9597	0x4977	0x98A8	# <CJK>
0x9598	0x4978	0x847A	# <CJK>
0x9599	0x4979	0x8557	# <CJK>
0x959A	0x497A	0x4F0F	# <CJK>
0x959B	0x497B	0x526F	# <CJK>
0x959C	0x497C	0x5FA9	# <CJK>
0x959D	0x497D	0x5E45	# <CJK>
0x959E	0x497E	0x670D	# <CJK>
0x959F	0x4A21	0x798F	# <CJK>
0x95A0	0x4A22	0x8179	# <CJK>
0x95A1	0x4A23	0x8907	# <CJK>
0x95A2	0x4A24	0x8986	# <CJK>
0x95A3	0x4A25	0x6DF5	# <CJK>
0x95A4	0x4A26	0x5F17	# <CJK>
0x95A5	0x4A27	0x6255	# <CJK>
0x95A6	0x4A28	0x6CB8	# <CJK>
0x95A7	0x4A29	0x4ECF	# <CJK>
0x95A8	0x4A2A	0x7269	# <CJK>
0x95A9	0x4A2B	0x9B92	# <CJK>
0x95AA	0x4A2C	0x5206	# <CJK>
0x95AB	0x4A2D	0x543B	# <CJK>
0x95AC	0x4A2E	0x5674	# <CJK>
0x95AD	0x4A2F	0x58B3	# <CJK>
0x95AE	0x4A30	0x61A4	# <CJK>
0x95AF	0x4A31	0x626E	# <CJK>
0x95B0	0x4A32	0x711A	# <CJK>
0x95B1	0x4A33	0x596E	# <CJK>
0x95B2	0x4A34	0x7C89	# <CJK>
0x95B3	0x4A35	0x7CDE	# <CJK>
0x95B4	0x4A36	0x7D1B	# <CJK>
0x95B5	0x4A37	0x96F0	# <CJK>
0x95B6	0x4A38	0x6587	# <CJK>
0x95B7	0x4A39	0x805E	# <CJK>
0x95B8	0x4A3A	0x4E19	# <CJK>
0x95B9	0x4A3B	0x4F75	# <CJK>
0x95BA	0x4A3C	0x5175	# <CJK>
0x95BB	0x4A3D	0x5840	# <CJK>
0x95BC	0x4A3E	0x5E63	# <CJK>
0x95BD	0x4A3F	0x5E73	# <CJK>
0x95BE	0x4A40	0x5F0A	# <CJK>
0x95BF	0x4A41	0x67C4	# <CJK>
0x95C0	0x4A42	0x4E26	# <CJK>
0x95C1	0x4A43	0x853D	# <CJK>
0x95C2	0x4A44	0x9589	# <CJK>
0x95C3	0x4A45	0x965B	# <CJK>
0x95C4	0x4A46	0x7C73	# <CJK>
0x95C5	0x4A47	0x9801	# <CJK>
0x95C6	0x4A48	0x50FB	# <CJK>
0x95C7	0x4A49	0x58C1	# <CJK>
0x95C8	0x4A4A	0x7656	# <CJK>
0x95C9	0x4A4B	0x78A7	# <CJK>
0x95CA	0x4A4C	0x5225	# <CJK>
0x95CB	0x4A4D	0x77A5	# <CJK>
0x95CC	0x4A4E	0x8511	# <CJK>
0x95CD	0x4A4F	0x7B86	# <CJK>
0x95CE	0x4A50	0x504F	# <CJK>
0x95CF	0x4A51	0x5909	# <CJK>
0x95D0	0x4A52	0x7247	# <CJK>
0x95D1	0x4A53	0x7BC7	# <CJK>
0x95D2	0x4A54	0x7DE8	# <CJK>
0x95D3	0x4A55	0x8FBA	# <CJK>
0x95D4	0x4A56	0x8FD4	# <CJK>
0x95D5	0x4A57	0x904D	# <CJK>
0x95D6	0x4A58	0x4FBF	# <CJK>
0x95D7	0x4A59	0x52C9	# <CJK>
0x95D8	0x4A5A	0x5A29	# <CJK>
0x95D9	0x4A5B	0x5F01	# <CJK>
0x95DA	0x4A5C	0x97AD	# <CJK>
0x95DB	0x4A5D	0x4FDD	# <CJK>
0x95DC	0x4A5E	0x8217	# <CJK>
0x95DD	0x4A5F	0x92EA	# <CJK>
0x95DE	0x4A60	0x5703	# <CJK>
0x95DF	0x4A61	0x6355	# <CJK>
0x95E0	0x4A62	0x6B69	# <CJK>
0x95E1	0x4A63	0x752B	# <CJK>
0x95E2	0x4A64	0x88DC	# <CJK>
0x95E3	0x4A65	0x8F14	# <CJK>
0x95E4	0x4A66	0x7A42	# <CJK>
0x95E5	0x4A67	0x52DF	# <CJK>
0x95E6	0x4A68	0x5893	# <CJK>
0x95E7	0x4A69	0x6155	# <CJK>
0x95E8	0x4A6A	0x620A	# <CJK>
0x95E9	0x4A6B	0x66AE	# <CJK>
0x95EA	0x4A6C	0x6BCD	# <CJK>
0x95EB	0x4A6D	0x7C3F	# <CJK>
0x95EC	0x4A6E	0x83E9	# <CJK>
0x95ED	0x4A6F	0x5023	# <CJK>
0x95EE	0x4A70	0x4FF8	# <CJK>
0x95EF	0x4A71	0x5305	# <CJK>
0x95F0	0x4A72	0x5446	# <CJK>
0x95F1	0x4A73	0x5831	# <CJK>
0x95F2	0x4A74	0x5949	# <CJK>
0x95F3	0x4A75	0x5B9D	# <CJK>
0x95F4	0x4A76	0x5CF0	# <CJK>
0x95F5	0x4A77	0x5CEF	# <CJK>
0x95F6	0x4A78	0x5D29	# <CJK>
0x95F7	0x4A79	0x5E96	# <CJK>
0x95F8	0x4A7A	0x62B1	# <CJK>
0x95F9	0x4A7B	0x6367	# <CJK>
0x95FA	0x4A7C	0x653E	# <CJK>
0x95FB	0x4A7D	0x65B9	# <CJK>
0x95FC	0x4A7E	0x670B	# <CJK>
0x9640	0x4B21	0x6CD5	# <CJK>
0x9641	0x4B22	0x6CE1	# <CJK>
0x9642	0x4B23	0x70F9	# <CJK>
0x9643	0x4B24	0x7832	# <CJK>
0x9644	0x4B25	0x7E2B	# <CJK>
0x9645	0x4B26	0x80DE	# <CJK>
0x9646	0x4B27	0x82B3	# <CJK>
0x9647	0x4B28	0x840C	# <CJK>
0x9648	0x4B29	0x84EC	# <CJK>
0x9649	0x4B2A	0x8702	# <CJK>
0x964A	0x4B2B	0x8912	# <CJK>
0x964B	0x4B2C	0x8A2A	# <CJK>
0x964C	0x4B2D	0x8C4A	# <CJK>
0x964D	0x4B2E	0x90A6	# <CJK>
0x964E	0x4B2F	0x92D2	# <CJK>
0x964F	0x4B30	0x98FD	# <CJK>
0x9650	0x4B31	0x9CF3	# <CJK>
0x9651	0x4B32	0x9D6C	# <CJK>
0x9652	0x4B33	0x4E4F	# <CJK>
0x9653	0x4B34	0x4EA1	# <CJK>
0x9654	0x4B35	0x508D	# <CJK>
0x9655	0x4B36	0x5256	# <CJK>
0x9656	0x4B37	0x574A	# <CJK>
0x9657	0x4B38	0x59A8	# <CJK>
0x9658	0x4B39	0x5E3D	# <CJK>
0x9659	0x4B3A	0x5FD8	# <CJK>
0x965A	0x4B3B	0x5FD9	# <CJK>
0x965B	0x4B3C	0x623F	# <CJK>
0x965C	0x4B3D	0x66B4	# <CJK>
0x965D	0x4B3E	0x671B	# <CJK>
0x965E	0x4B3F	0x67D0	# <CJK>
0x965F	0x4B40	0x68D2	# <CJK>
0x9660	0x4B41	0x5192	# <CJK>
0x9661	0x4B42	0x7D21	# <CJK>
0x9662	0x4B43	0x80AA	# <CJK>
0x9663	0x4B44	0x81A8	# <CJK>
0x9664	0x4B45	0x8B00	# <CJK>
0x9665	0x4B46	0x8C8C	# <CJK>
0x9666	0x4B47	0x8CBF	# <CJK>
0x9667	0x4B48	0x927E	# <CJK>
0x9668	0x4B49	0x9632	# <CJK>
0x9669	0x4B4A	0x5420	# <CJK>
0x966A	0x4B4B	0x982C	# <CJK>
0x966B	0x4B4C	0x5317	# <CJK>
0x966C	0x4B4D	0x50D5	# <CJK>
0x966D	0x4B4E	0x535C	# <CJK>
0x966E	0x4B4F	0x58A8	# <CJK>
0x966F	0x4B50	0x64B2	# <CJK>
0x9670	0x4B51	0x6734	# <CJK>
0x9671	0x4B52	0x7267	# <CJK>
0x9672	0x4B53	0x7766	# <CJK>
0x9673	0x4B54	0x7A46	# <CJK>
0x9674	0x4B55	0x91E6	# <CJK>
0x9675	0x4B56	0x52C3	# <CJK>
0x9676	0x4B57	0x6CA1	# <CJK>
0x9677	0x4B58	0x6B86	# <CJK>
0x9678	0x4B59	0x5800	# <CJK>
0x9679	0x4B5A	0x5E4C	# <CJK>
0x967A	0x4B5B	0x5954	# <CJK>
0x967B	0x4B5C	0x672C	# <CJK>
0x967C	0x4B5D	0x7FFB	# <CJK>
0x967D	0x4B5E	0x51E1	# <CJK>
0x967E	0x4B5F	0x76C6	# <CJK>
0x9680	0x4B60	0x6469	# <CJK>
0x9681	0x4B61	0x78E8	# <CJK>
0x9682	0x4B62	0x9B54	# <CJK>
0x9683	0x4B63	0x9EBB	# <CJK>
0x9684	0x4B64	0x57CB	# <CJK>
0x9685	0x4B65	0x59B9	# <CJK>
0x9686	0x4B66	0x6627	# <CJK>
0x9687	0x4B67	0x679A	# <CJK>
0x9688	0x4B68	0x6BCE	# <CJK>
0x9689	0x4B69	0x54E9	# <CJK>
0x968A	0x4B6A	0x69D9	# <CJK>
0x968B	0x4B6B	0x5E55	# <CJK>
0x968C	0x4B6C	0x819C	# <CJK>
0x968D	0x4B6D	0x6795	# <CJK>
0x968E	0x4B6E	0x9BAA	# <CJK>
0x968F	0x4B6F	0x67FE	# <CJK>
0x9690	0x4B70	0x9C52	# <CJK>
0x9691	0x4B71	0x685D	# <CJK>
0x9692	0x4B72	0x4EA6	# <CJK>
0x9693	0x4B73	0x4FE3	# <CJK>
0x9694	0x4B74	0x53C8	# <CJK>
0x9695	0x4B75	0x62B9	# <CJK>
0x9696	0x4B76	0x672B	# <CJK>
0x9697	0x4B77	0x6CAB	# <CJK>
0x9698	0x4B78	0x8FC4	# <CJK>
0x9699	0x4B79	0x4FAD	# <CJK>
0x969A	0x4B7A	0x7E6D	# <CJK>
0x969B	0x4B7B	0x9EBF	# <CJK>
0x969C	0x4B7C	0x4E07	# <CJK>
0x969D	0x4B7D	0x6162	# <CJK>
0x969E	0x4B7E	0x6E80	# <CJK>
0x969F	0x4C21	0x6F2B	# <CJK>
0x96A0	0x4C22	0x8513	# <CJK>
0x96A1	0x4C23	0x5473	# <CJK>
0x96A2	0x4C24	0x672A	# <CJK>
0x96A3	0x4C25	0x9B45	# <CJK>
0x96A4	0x4C26	0x5DF3	# <CJK>
0x96A5	0x4C27	0x7B95	# <CJK>
0x96A6	0x4C28	0x5CAC	# <CJK>
0x96A7	0x4C29	0x5BC6	# <CJK>
0x96A8	0x4C2A	0x871C	# <CJK>
0x96A9	0x4C2B	0x6E4A	# <CJK>
0x96AA	0x4C2C	0x84D1	# <CJK>
0x96AB	0x4C2D	0x7A14	# <CJK>
0x96AC	0x4C2E	0x8108	# <CJK>
0x96AD	0x4C2F	0x5999	# <CJK>
0x96AE	0x4C30	0x7C8D	# <CJK>
0x96AF	0x4C31	0x6C11	# <CJK>
0x96B0	0x4C32	0x7720	# <CJK>
0x96B1	0x4C33	0x52D9	# <CJK>
0x96B2	0x4C34	0x5922	# <CJK>
0x96B3	0x4C35	0x7121	# <CJK>
0x96B4	0x4C36	0x725F	# <CJK>
0x96B5	0x4C37	0x77DB	# <CJK>
0x96B6	0x4C38	0x9727	# <CJK>
0x96B7	0x4C39	0x9D61	# <CJK>
0x96B8	0x4C3A	0x690B	# <CJK>
0x96B9	0x4C3B	0x5A7F	# <CJK>
0x96BA	0x4C3C	0x5A18	# <CJK>
0x96BB	0x4C3D	0x51A5	# <CJK>
0x96BC	0x4C3E	0x540D	# <CJK>
0x96BD	0x4C3F	0x547D	# <CJK>
0x96BE	0x4C40	0x660E	# <CJK>
0x96BF	0x4C41	0x76DF	# <CJK>
0x96C0	0x4C42	0x8FF7	# <CJK>
0x96C1	0x4C43	0x9298	# <CJK>
0x96C2	0x4C44	0x9CF4	# <CJK>
0x96C3	0x4C45	0x59EA	# <CJK>
0x96C4	0x4C46	0x725D	# <CJK>
0x96C5	0x4C47	0x6EC5	# <CJK>
0x96C6	0x4C48	0x514D	# <CJK>
0x96C7	0x4C49	0x68C9	# <CJK>
0x96C8	0x4C4A	0x7DBF	# <CJK>
0x96C9	0x4C4B	0x7DEC	# <CJK>
0x96CA	0x4C4C	0x9762	# <CJK>
0x96CB	0x4C4D	0x9EBA	# <CJK>
0x96CC	0x4C4E	0x6478	# <CJK>
0x96CD	0x4C4F	0x6A21	# <CJK>
0x96CE	0x4C50	0x8302	# <CJK>
0x96CF	0x4C51	0x5984	# <CJK>
0x96D0	0x4C52	0x5B5F	# <CJK>
0x96D1	0x4C53	0x6BDB	# <CJK>
0x96D2	0x4C54	0x731B	# <CJK>
0x96D3	0x4C55	0x76F2	# <CJK>
0x96D4	0x4C56	0x7DB2	# <CJK>
0x96D5	0x4C57	0x8017	# <CJK>
0x96D6	0x4C58	0x8499	# <CJK>
0x96D7	0x4C59	0x5132	# <CJK>
0x96D8	0x4C5A	0x6728	# <CJK>
0x96D9	0x4C5B	0x9ED9	# <CJK>
0x96DA	0x4C5C	0x76EE	# <CJK>
0x96DB	0x4C5D	0x6762	# <CJK>
0x96DC	0x4C5E	0x52FF	# <CJK>
0x96DD	0x4C5F	0x9905	# <CJK>
0x96DE	0x4C60	0x5C24	# <CJK>
0x96DF	0x4C61	0x623B	# <CJK>
0x96E0	0x4C62	0x7C7E	# <CJK>
0x96E1	0x4C63	0x8CB0	# <CJK>
0x96E2	0x4C64	0x554F	# <CJK>
0x96E3	0x4C65	0x60B6	# <CJK>
0x96E4	0x4C66	0x7D0B	# <CJK>
0x96E5	0x4C67	0x9580	# <CJK>
0x96E6	0x4C68	0x5301	# <CJK>
0x96E7	0x4C69	0x4E5F	# <CJK>
0x96E8	0x4C6A	0x51B6	# <CJK>
0x96E9	0x4C6B	0x591C	# <CJK>
0x96EA	0x4C6C	0x723A	# <CJK>
0x96EB	0x4C6D	0x8036	# <CJK>
0x96EC	0x4C6E	0x91CE	# <CJK>
0x96ED	0x4C6F	0x5F25	# <CJK>
0x96EE	0x4C70	0x77E2	# <CJK>
0x96EF	0x4C71	0x5384	# <CJK>
0x96F0	0x4C72	0x5F79	# <CJK>
0x96F1	0x4C73	0x7D04	# <CJK>
0x96F2	0x4C74	0x85AC	# <CJK>
0x96F3	0x4C75	0x8A33	# <CJK>
0x96F4	0x4C76	0x8E8D	# <CJK>
0x96F5	0x4C77	0x9756	# <CJK>
0x96F6	0x4C78	0x67F3	# <CJK>
0x96F7	0x4C79	0x85AE	# <CJK>
0x96F8	0x4C7A	0x9453	# <CJK>
0x96F9	0x4C7B	0x6109	# <CJK>
0x96FA	0x4C7C	0x6108	# <CJK>
0x96FB	0x4C7D	0x6CB9	# <CJK>
0x96FC	0x4C7E	0x7652	# <CJK>
0x9740	0x4D21	0x8AED	# <CJK>
0x9741	0x4D22	0x8F38	# <CJK>
0x9742	0x4D23	0x552F	# <CJK>
0x9743	0x4D24	0x4F51	# <CJK>
0x9744	0x4D25	0x512A	# <CJK>
0x9745	0x4D26	0x52C7	# <CJK>
0x9746	0x4D27	0x53CB	# <CJK>
0x9747	0x4D28	0x5BA5	# <CJK>
0x9748	0x4D29	0x5E7D	# <CJK>
0x9749	0x4D2A	0x60A0	# <CJK>
0x974A	0x4D2B	0x6182	# <CJK>
0x974B	0x4D2C	0x63D6	# <CJK>
0x974C	0x4D2D	0x6709	# <CJK>
0x974D	0x4D2E	0x67DA	# <CJK>
0x974E	0x4D2F	0x6E67	# <CJK>
0x974F	0x4D30	0x6D8C	# <CJK>
0x9750	0x4D31	0x7336	# <CJK>
0x9751	0x4D32	0x7337	# <CJK>
0x9752	0x4D33	0x7531	# <CJK>
0x9753	0x4D34	0x7950	# <CJK>
0x9754	0x4D35	0x88D5	# <CJK>
0x9755	0x4D36	0x8A98	# <CJK>
0x9756	0x4D37	0x904A	# <CJK>
0x9757	0x4D38	0x9091	# <CJK>
0x9758	0x4D39	0x90F5	# <CJK>
0x9759	0x4D3A	0x96C4	# <CJK>
0x975A	0x4D3B	0x878D	# <CJK>
0x975B	0x4D3C	0x5915	# <CJK>
0x975C	0x4D3D	0x4E88	# <CJK>
0x975D	0x4D3E	0x4F59	# <CJK>
0x975E	0x4D3F	0x4E0E	# <CJK>
0x975F	0x4D40	0x8A89	# <CJK>
0x9760	0x4D41	0x8F3F	# <CJK>
0x9761	0x4D42	0x9810	# <CJK>
0x9762	0x4D43	0x50AD	# <CJK>
0x9763	0x4D44	0x5E7C	# <CJK>
0x9764	0x4D45	0x5996	# <CJK>
0x9765	0x4D46	0x5BB9	# <CJK>
0x9766	0x4D47	0x5EB8	# <CJK>
0x9767	0x4D48	0x63DA	# <CJK>
0x9768	0x4D49	0x63FA	# <CJK>
0x9769	0x4D4A	0x64C1	# <CJK>
0x976A	0x4D4B	0x66DC	# <CJK>
0x976B	0x4D4C	0x694A	# <CJK>
0x976C	0x4D4D	0x69D8	# <CJK>
0x976D	0x4D4E	0x6D0B	# <CJK>
0x976E	0x4D4F	0x6EB6	# <CJK>
0x976F	0x4D50	0x7194	# <CJK>
0x9770	0x4D51	0x7528	# <CJK>
0x9771	0x4D52	0x7AAF	# <CJK>
0x9772	0x4D53	0x7F8A	# <CJK>
0x9773	0x4D54	0x8000	# <CJK>
0x9774	0x4D55	0x8449	# <CJK>
0x9775	0x4D56	0x84C9	# <CJK>
0x9776	0x4D57	0x8981	# <CJK>
0x9777	0x4D58	0x8B21	# <CJK>
0x9778	0x4D59	0x8E0A	# <CJK>
0x9779	0x4D5A	0x9065	# <CJK>
0x977A	0x4D5B	0x967D	# <CJK>
0x977B	0x4D5C	0x990A	# <CJK>
0x977C	0x4D5D	0x617E	# <CJK>
0x977D	0x4D5E	0x6291	# <CJK>
0x977E	0x4D5F	0x6B32	# <CJK>
0x9780	0x4D60	0x6C83	# <CJK>
0x9781	0x4D61	0x6D74	# <CJK>
0x9782	0x4D62	0x7FCC	# <CJK>
0x9783	0x4D63	0x7FFC	# <CJK>
0x9784	0x4D64	0x6DC0	# <CJK>
0x9785	0x4D65	0x7F85	# <CJK>
0x9786	0x4D66	0x87BA	# <CJK>
0x9787	0x4D67	0x88F8	# <CJK>
0x9788	0x4D68	0x6765	# <CJK>
0x9789	0x4D69	0x83B1	# <CJK>
0x978A	0x4D6A	0x983C	# <CJK>
0x978B	0x4D6B	0x96F7	# <CJK>
0x978C	0x4D6C	0x6D1B	# <CJK>
0x978D	0x4D6D	0x7D61	# <CJK>
0x978E	0x4D6E	0x843D	# <CJK>
0x978F	0x4D6F	0x916A	# <CJK>
0x9790	0x4D70	0x4E71	# <CJK>
0x9791	0x4D71	0x5375	# <CJK>
0x9792	0x4D72	0x5D50	# <CJK>
0x9793	0x4D73	0x6B04	# <CJK>
0x9794	0x4D74	0x6FEB	# <CJK>
0x9795	0x4D75	0x85CD	# <CJK>
0x9796	0x4D76	0x862D	# <CJK>
0x9797	0x4D77	0x89A7	# <CJK>
0x9798	0x4D78	0x5229	# <CJK>
0x9799	0x4D79	0x540F	# <CJK>
0x979A	0x4D7A	0x5C65	# <CJK>
0x979B	0x4D7B	0x674E	# <CJK>
0x979C	0x4D7C	0x68A8	# <CJK>
0x979D	0x4D7D	0x7406	# <CJK>
0x979E	0x4D7E	0x7483	# <CJK>
0x979F	0x4E21	0x75E2	# <CJK>
0x97A0	0x4E22	0x88CF	# <CJK>
0x97A1	0x4E23	0x88E1	# <CJK>
0x97A2	0x4E24	0x91CC	# <CJK>
0x97A3	0x4E25	0x96E2	# <CJK>
0x97A4	0x4E26	0x9678	# <CJK>
0x97A5	0x4E27	0x5F8B	# <CJK>
0x97A6	0x4E28	0x7387	# <CJK>
0x97A7	0x4E29	0x7ACB	# <CJK>
0x97A8	0x4E2A	0x844E	# <CJK>
0x97A9	0x4E2B	0x63A0	# <CJK>
0x97AA	0x4E2C	0x7565	# <CJK>
0x97AB	0x4E2D	0x5289	# <CJK>
0x97AC	0x4E2E	0x6D41	# <CJK>
0x97AD	0x4E2F	0x6E9C	# <CJK>
0x97AE	0x4E30	0x7409	# <CJK>
0x97AF	0x4E31	0x7559	# <CJK>
0x97B0	0x4E32	0x786B	# <CJK>
0x97B1	0x4E33	0x7C92	# <CJK>
0x97B2	0x4E34	0x9686	# <CJK>
0x97B3	0x4E35	0x7ADC	# <CJK>
0x97B4	0x4E36	0x9F8D	# <CJK>
0x97B5	0x4E37	0x4FB6	# <CJK>
0x97B6	0x4E38	0x616E	# <CJK>
0x97B7	0x4E39	0x65C5	# <CJK>
0x97B8	0x4E3A	0x865C	# <CJK>
0x97B9	0x4E3B	0x4E86	# <CJK>
0x97BA	0x4E3C	0x4EAE	# <CJK>
0x97BB	0x4E3D	0x50DA	# <CJK>
0x97BC	0x4E3E	0x4E21	# <CJK>
0x97BD	0x4E3F	0x51CC	# <CJK>
0x97BE	0x4E40	0x5BEE	# <CJK>
0x97BF	0x4E41	0x6599	# <CJK>
0x97C0	0x4E42	0x6881	# <CJK>
0x97C1	0x4E43	0x6DBC	# <CJK>
0x97C2	0x4E44	0x731F	# <CJK>
0x97C3	0x4E45	0x7642	# <CJK>
0x97C4	0x4E46	0x77AD	# <CJK>
0x97C5	0x4E47	0x7A1C	# <CJK>
0x97C6	0x4E48	0x7CE7	# <CJK>
0x97C7	0x4E49	0x826F	# <CJK>
0x97C8	0x4E4A	0x8AD2	# <CJK>
0x97C9	0x4E4B	0x907C	# <CJK>
0x97CA	0x4E4C	0x91CF	# <CJK>
0x97CB	0x4E4D	0x9675	# <CJK>
0x97CC	0x4E4E	0x9818	# <CJK>
0x97CD	0x4E4F	0x529B	# <CJK>
0x97CE	0x4E50	0x7DD1	# <CJK>
0x97CF	0x4E51	0x502B	# <CJK>
0x97D0	0x4E52	0x5398	# <CJK>
0x97D1	0x4E53	0x6797	# <CJK>
0x97D2	0x4E54	0x6DCB	# <CJK>
0x97D3	0x4E55	0x71D0	# <CJK>
0x97D4	0x4E56	0x7433	# <CJK>
0x97D5	0x4E57	0x81E8	# <CJK>
0x97D6	0x4E58	0x8F2A	# <CJK>
0x97D7	0x4E59	0x96A3	# <CJK>
0x97D8	0x4E5A	0x9C57	# <CJK>
0x97D9	0x4E5B	0x9E9F	# <CJK>
0x97DA	0x4E5C	0x7460	# <CJK>
0x97DB	0x4E5D	0x5841	# <CJK>
0x97DC	0x4E5E	0x6D99	# <CJK>
0x97DD	0x4E5F	0x7D2F	# <CJK>
0x97DE	0x4E60	0x985E	# <CJK>
0x97DF	0x4E61	0x4EE4	# <CJK>
0x97E0	0x4E62	0x4F36	# <CJK>
0x97E1	0x4E63	0x4F8B	# <CJK>
0x97E2	0x4E64	0x51B7	# <CJK>
0x97E3	0x4E65	0x52B1	# <CJK>
0x97E4	0x4E66	0x5DBA	# <CJK>
0x97E5	0x4E67	0x601C	# <CJK>
0x97E6	0x4E68	0x73B2	# <CJK>
0x97E7	0x4E69	0x793C	# <CJK>
0x97E8	0x4E6A	0x82D3	# <CJK>
0x97E9	0x4E6B	0x9234	# <CJK>
0x97EA	0x4E6C	0x96B7	# <CJK>
0x97EB	0x4E6D	0x96F6	# <CJK>
0x97EC	0x4E6E	0x970A	# <CJK>
0x97ED	0x4E6F	0x9E97	# <CJK>
0x97EE	0x4E70	0x9F62	# <CJK>
0x97EF	0x4E71	0x66A6	# <CJK>
0x97F0	0x4E72	0x6B74	# <CJK>
0x97F1	0x4E73	0x5217	# <CJK>
0x97F2	0x4E74	0x52A3	# <CJK>
0x97F3	0x4E75	0x70C8	# <CJK>
0x97F4	0x4E76	0x88C2	# <CJK>
0x97F5	0x4E77	0x5EC9	# <CJK>
0x97F6	0x4E78	0x604B	# <CJK>
0x97F7	0x4E79	0x6190	# <CJK>
0x97F8	0x4E7A	0x6F23	# <CJK>
0x97F9	0x4E7B	0x7149	# <CJK>
0x97FA	0x4E7C	0x7C3E	# <CJK>
0x97FB	0x4E7D	0x7DF4	# <CJK>
0x97FC	0x4E7E	0x806F	# <CJK>
0x9840	0x4F21	0x84EE	# <CJK>
0x9841	0x4F22	0x9023	# <CJK>
0x9842	0x4F23	0x932C	# <CJK>
0x9843	0x4F24	0x5442	# <CJK>
0x9844	0x4F25	0x9B6F	# <CJK>
0x9845	0x4F26	0x6AD3	# <CJK>
0x9846	0x4F27	0x7089	# <CJK>
0x9847	0x4F28	0x8CC2	# <CJK>
0x9848	0x4F29	0x8DEF	# <CJK>
0x9849	0x4F2A	0x9732	# <CJK>
0x984A	0x4F2B	0x52B4	# <CJK>
0x984B	0x4F2C	0x5A41	# <CJK>
0x984C	0x4F2D	0x5ECA	# <CJK>
0x984D	0x4F2E	0x5F04	# <CJK>
0x984E	0x4F2F	0x6717	# <CJK>
0x984F	0x4F30	0x697C	# <CJK>
0x9850	0x4F31	0x6994	# <CJK>
0x9851	0x4F32	0x6D6A	# <CJK>
0x9852	0x4F33	0x6F0F	# <CJK>
0x9853	0x4F34	0x7262	# <CJK>
0x9854	0x4F35	0x72FC	# <CJK>
0x9855	0x4F36	0x7BED	# <CJK>
0x9856	0x4F37	0x8001	# <CJK>
0x9857	0x4F38	0x807E	# <CJK>
0x9858	0x4F39	0x874B	# <CJK>
0x9859	0x4F3A	0x90CE	# <CJK>
0x985A	0x4F3B	0x516D	# <CJK>
0x985B	0x4F3C	0x9E93	# <CJK>
0x985C	0x4F3D	0x7984	# <CJK>
0x985D	0x4F3E	0x808B	# <CJK>
0x985E	0x4F3F	0x9332	# <CJK>
0x985F	0x4F40	0x8AD6	# <CJK>
0x9860	0x4F41	0x502D	# <CJK>
0x9861	0x4F42	0x548C	# <CJK>
0x9862	0x4F43	0x8A71	# <CJK>
0x9863	0x4F44	0x6B6A	# <CJK>
0x9864	0x4F45	0x8CC4	# <CJK>
0x9865	0x4F46	0x8107	# <CJK>
0x9866	0x4F47	0x60D1	# <CJK>
0x9867	0x4F48	0x67A0	# <CJK>
0x9868	0x4F49	0x9DF2	# <CJK>
0x9869	0x4F4A	0x4E99	# <CJK>
0x986A	0x4F4B	0x4E98	# <CJK>
0x986B	0x4F4C	0x9C10	# <CJK>
0x986C	0x4F4D	0x8A6B	# <CJK>
0x986D	0x4F4E	0x85C1	# <CJK>
0x986E	0x4F4F	0x8568	# <CJK>
0x986F	0x4F50	0x6900	# <CJK>
0x9870	0x4F51	0x6E7E	# <CJK>
0x9871	0x4F52	0x7897	# <CJK>
0x9872	0x4F53	0x8155	# <CJK>
0x989F	0x5021	0x5F0C	# <CJK>
0x98A0	0x5022	0x4E10	# <CJK>
0x98A1	0x5023	0x4E15	# <CJK>
0x98A2	0x5024	0x4E2A	# <CJK>
0x98A3	0x5025	0x4E31	# <CJK>
0x98A4	0x5026	0x4E36	# <CJK>
0x98A5	0x5027	0x4E3C	# <CJK>
0x98A6	0x5028	0x4E3F	# <CJK>
0x98A7	0x5029	0x4E42	# <CJK>
0x98A8	0x502A	0x4E56	# <CJK>
0x98A9	0x502B	0x4E58	# <CJK>
0x98AA	0x502C	0x4E82	# <CJK>
0x98AB	0x502D	0x4E85	# <CJK>
0x98AC	0x502E	0x8C6B	# <CJK>
0x98AD	0x502F	0x4E8A	# <CJK>
0x98AE	0x5030	0x8212	# <CJK>
0x98AF	0x5031	0x5F0D	# <CJK>
0x98B0	0x5032	0x4E8E	# <CJK>
0x98B1	0x5033	0x4E9E	# <CJK>
0x98B2	0x5034	0x4E9F	# <CJK>
0x98B3	0x5035	0x4EA0	# <CJK>
0x98B4	0x5036	0x4EA2	# <CJK>
0x98B5	0x5037	0x4EB0	# <CJK>
0x98B6	0x5038	0x4EB3	# <CJK>
0x98B7	0x5039	0x4EB6	# <CJK>
0x98B8	0x503A	0x4ECE	# <CJK>
0x98B9	0x503B	0x4ECD	# <CJK>
0x98BA	0x503C	0x4EC4	# <CJK>
0x98BB	0x503D	0x4EC6	# <CJK>
0x98BC	0x503E	0x4EC2	# <CJK>
0x98BD	0x503F	0x4ED7	# <CJK>
0x98BE	0x5040	0x4EDE	# <CJK>
0x98BF	0x5041	0x4EED	# <CJK>
0x98C0	0x5042	0x4EDF	# <CJK>
0x98C1	0x5043	0x4EF7	# <CJK>
0x98C2	0x5044	0x4F09	# <CJK>
0x98C3	0x5045	0x4F5A	# <CJK>
0x98C4	0x5046	0x4F30	# <CJK>
0x98C5	0x5047	0x4F5B	# <CJK>
0x98C6	0x5048	0x4F5D	# <CJK>
0x98C7	0x5049	0x4F57	# <CJK>
0x98C8	0x504A	0x4F47	# <CJK>
0x98C9	0x504B	0x4F76	# <CJK>
0x98CA	0x504C	0x4F88	# <CJK>
0x98CB	0x504D	0x4F8F	# <CJK>
0x98CC	0x504E	0x4F98	# <CJK>
0x98CD	0x504F	0x4F7B	# <CJK>
0x98CE	0x5050	0x4F69	# <CJK>
0x98CF	0x5051	0x4F70	# <CJK>
0x98D0	0x5052	0x4F91	# <CJK>
0x98D1	0x5053	0x4F6F	# <CJK>
0x98D2	0x5054	0x4F86	# <CJK>
0x98D3	0x5055	0x4F96	# <CJK>
0x98D4	0x5056	0x5118	# <CJK>
0x98D5	0x5057	0x4FD4	# <CJK>
0x98D6	0x5058	0x4FDF	# <CJK>
0x98D7	0x5059	0x4FCE	# <CJK>
0x98D8	0x505A	0x4FD8	# <CJK>
0x98D9	0x505B	0x4FDB	# <CJK>
0x98DA	0x505C	0x4FD1	# <CJK>
0x98DB	0x505D	0x4FDA	# <CJK>
0x98DC	0x505E	0x4FD0	# <CJK>
0x98DD	0x505F	0x4FE4	# <CJK>
0x98DE	0x5060	0x4FE5	# <CJK>
0x98DF	0x5061	0x501A	# <CJK>
0x98E0	0x5062	0x5028	# <CJK>
0x98E1	0x5063	0x5014	# <CJK>
0x98E2	0x5064	0x502A	# <CJK>
0x98E3	0x5065	0x5025	# <CJK>
0x98E4	0x5066	0x5005	# <CJK>
0x98E5	0x5067	0x4F1C	# <CJK>
0x98E6	0x5068	0x4FF6	# <CJK>
0x98E7	0x5069	0x5021	# <CJK>
0x98E8	0x506A	0x5029	# <CJK>
0x98E9	0x506B	0x502C	# <CJK>
0x98EA	0x506C	0x4FFE	# <CJK>
0x98EB	0x506D	0x4FEF	# <CJK>
0x98EC	0x506E	0x5011	# <CJK>
0x98ED	0x506F	0x5006	# <CJK>
0x98EE	0x5070	0x5043	# <CJK>
0x98EF	0x5071	0x5047	# <CJK>
0x98F0	0x5072	0x6703	# <CJK>
0x98F1	0x5073	0x5055	# <CJK>
0x98F2	0x5074	0x5050	# <CJK>
0x98F3	0x5075	0x5048	# <CJK>
0x98F4	0x5076	0x505A	# <CJK>
0x98F5	0x5077	0x5056	# <CJK>
0x98F6	0x5078	0x506C	# <CJK>
0x98F7	0x5079	0x5078	# <CJK>
0x98F8	0x507A	0x5080	# <CJK>
0x98F9	0x507B	0x509A	# <CJK>
0x98FA	0x507C	0x5085	# <CJK>
0x98FB	0x507D	0x50B4	# <CJK>
0x98FC	0x507E	0x50B2	# <CJK>
0x9940	0x5121	0x50C9	# <CJK>
0x9941	0x5122	0x50CA	# <CJK>
0x9942	0x5123	0x50B3	# <CJK>
0x9943	0x5124	0x50C2	# <CJK>
0x9944	0x5125	0x50D6	# <CJK>
0x9945	0x5126	0x50DE	# <CJK>
0x9946	0x5127	0x50E5	# <CJK>
0x9947	0x5128	0x50ED	# <CJK>
0x9948	0x5129	0x50E3	# <CJK>
0x9949	0x512A	0x50EE	# <CJK>
0x994A	0x512B	0x50F9	# <CJK>
0x994B	0x512C	0x50F5	# <CJK>
0x994C	0x512D	0x5109	# <CJK>
0x994D	0x512E	0x5101	# <CJK>
0x994E	0x512F	0x5102	# <CJK>
0x994F	0x5130	0x5116	# <CJK>
0x9950	0x5131	0x5115	# <CJK>
0x9951	0x5132	0x5114	# <CJK>
0x9952	0x5133	0x511A	# <CJK>
0x9953	0x5134	0x5121	# <CJK>
0x9954	0x5135	0x513A	# <CJK>
0x9955	0x5136	0x5137	# <CJK>
0x9956	0x5137	0x513C	# <CJK>
0x9957	0x5138	0x513B	# <CJK>
0x9958	0x5139	0x513F	# <CJK>
0x9959	0x513A	0x5140	# <CJK>
0x995A	0x513B	0x5152	# <CJK>
0x995B	0x513C	0x514C	# <CJK>
0x995C	0x513D	0x5154	# <CJK>
0x995D	0x513E	0x5162	# <CJK>
0x995E	0x513F	0x7AF8	# <CJK>
0x995F	0x5140	0x5169	# <CJK>
0x9960	0x5141	0x516A	# <CJK>
0x9961	0x5142	0x516E	# <CJK>
0x9962	0x5143	0x5180	# <CJK>
0x9963	0x5144	0x5182	# <CJK>
0x9964	0x5145	0x56D8	# <CJK>
0x9965	0x5146	0x518C	# <CJK>
0x9966	0x5147	0x5189	# <CJK>
0x9967	0x5148	0x518F	# <CJK>
0x9968	0x5149	0x5191	# <CJK>
0x9969	0x514A	0x5193	# <CJK>
0x996A	0x514B	0x5195	# <CJK>
0x996B	0x514C	0x5196	# <CJK>
0x996C	0x514D	0x51A4	# <CJK>
0x996D	0x514E	0x51A6	# <CJK>
0x996E	0x514F	0x51A2	# <CJK>
0x996F	0x5150	0x51A9	# <CJK>
0x9970	0x5151	0x51AA	# <CJK>
0x9971	0x5152	0x51AB	# <CJK>
0x9972	0x5153	0x51B3	# <CJK>
0x9973	0x5154	0x51B1	# <CJK>
0x9974	0x5155	0x51B2	# <CJK>
0x9975	0x5156	0x51B0	# <CJK>
0x9976	0x5157	0x51B5	# <CJK>
0x9977	0x5158	0x51BD	# <CJK>
0x9978	0x5159	0x51C5	# <CJK>
0x9979	0x515A	0x51C9	# <CJK>
0x997A	0x515B	0x51DB	# <CJK>
0x997B	0x515C	0x51E0	# <CJK>
0x997C	0x515D	0x8655	# <CJK>
0x997D	0x515E	0x51E9	# <CJK>
0x997E	0x515F	0x51ED	# <CJK>
0x9980	0x5160	0x51F0	# <CJK>
0x9981	0x5161	0x51F5	# <CJK>
0x9982	0x5162	0x51FE	# <CJK>
0x9983	0x5163	0x5204	# <CJK>
0x9984	0x5164	0x520B	# <CJK>
0x9985	0x5165	0x5214	# <CJK>
0x9986	0x5166	0x520E	# <CJK>
0x9987	0x5167	0x5227	# <CJK>
0x9988	0x5168	0x522A	# <CJK>
0x9989	0x5169	0x522E	# <CJK>
0x998A	0x516A	0x5233	# <CJK>
0x998B	0x516B	0x5239	# <CJK>
0x998C	0x516C	0x524F	# <CJK>
0x998D	0x516D	0x5244	# <CJK>
0x998E	0x516E	0x524B	# <CJK>
0x998F	0x516F	0x524C	# <CJK>
0x9990	0x5170	0x525E	# <CJK>
0x9991	0x5171	0x5254	# <CJK>
0x9992	0x5172	0x526A	# <CJK>
0x9993	0x5173	0x5274	# <CJK>
0x9994	0x5174	0x5269	# <CJK>
0x9995	0x5175	0x5273	# <CJK>
0x9996	0x5176	0x527F	# <CJK>
0x9997	0x5177	0x527D	# <CJK>
0x9998	0x5178	0x528D	# <CJK>
0x9999	0x5179	0x5294	# <CJK>
0x999A	0x517A	0x5292	# <CJK>
0x999B	0x517B	0x5271	# <CJK>
0x999C	0x517C	0x5288	# <CJK>
0x999D	0x517D	0x5291	# <CJK>
0x999E	0x517E	0x8FA8	# <CJK>
0x999F	0x5221	0x8FA7	# <CJK>
0x99A0	0x5222	0x52AC	# <CJK>
0x99A1	0x5223	0x52AD	# <CJK>
0x99A2	0x5224	0x52BC	# <CJK>
0x99A3	0x5225	0x52B5	# <CJK>
0x99A4	0x5226	0x52C1	# <CJK>
0x99A5	0x5227	0x52CD	# <CJK>
0x99A6	0x5228	0x52D7	# <CJK>
0x99A7	0x5229	0x52DE	# <CJK>
0x99A8	0x522A	0x52E3	# <CJK>
0x99A9	0x522B	0x52E6	# <CJK>
0x99AA	0x522C	0x98ED	# <CJK>
0x99AB	0x522D	0x52E0	# <CJK>
0x99AC	0x522E	0x52F3	# <CJK>
0x99AD	0x522F	0x52F5	# <CJK>
0x99AE	0x5230	0x52F8	# <CJK>
0x99AF	0x5231	0x52F9	# <CJK>
0x99B0	0x5232	0x5306	# <CJK>
0x99B1	0x5233	0x5308	# <CJK>
0x99B2	0x5234	0x7538	# <CJK>
0x99B3	0x5235	0x530D	# <CJK>
0x99B4	0x5236	0x5310	# <CJK>
0x99B5	0x5237	0x530F	# <CJK>
0x99B6	0x5238	0x5315	# <CJK>
0x99B7	0x5239	0x531A	# <CJK>
0x99B8	0x523A	0x5323	# <CJK>
0x99B9	0x523B	0x532F	# <CJK>
0x99BA	0x523C	0x5331	# <CJK>
0x99BB	0x523D	0x5333	# <CJK>
0x99BC	0x523E	0x5338	# <CJK>
0x99BD	0x523F	0x5340	# <CJK>
0x99BE	0x5240	0x5346	# <CJK>
0x99BF	0x5241	0x5345	# <CJK>
0x99C0	0x5242	0x4E17	# <CJK>
0x99C1	0x5243	0x5349	# <CJK>
0x99C2	0x5244	0x534D	# <CJK>
0x99C3	0x5245	0x51D6	# <CJK>
0x99C4	0x5246	0x535E	# <CJK>
0x99C5	0x5247	0x5369	# <CJK>
0x99C6	0x5248	0x536E	# <CJK>
0x99C7	0x5249	0x5918	# <CJK>
0x99C8	0x524A	0x537B	# <CJK>
0x99C9	0x524B	0x5377	# <CJK>
0x99CA	0x524C	0x5382	# <CJK>
0x99CB	0x524D	0x5396	# <CJK>
0x99CC	0x524E	0x53A0	# <CJK>
0x99CD	0x524F	0x53A6	# <CJK>
0x99CE	0x5250	0x53A5	# <CJK>
0x99CF	0x5251	0x53AE	# <CJK>
0x99D0	0x5252	0x53B0	# <CJK>
0x99D1	0x5253	0x53B6	# <CJK>
0x99D2	0x5254	0x53C3	# <CJK>
0x99D3	0x5255	0x7C12	# <CJK>
0x99D4	0x5256	0x96D9	# <CJK>
0x99D5	0x5257	0x53DF	# <CJK>
0x99D6	0x5258	0x66FC	# <CJK>
0x99D7	0x5259	0x71EE	# <CJK>
0x99D8	0x525A	0x53EE	# <CJK>
0x99D9	0x525B	0x53E8	# <CJK>
0x99DA	0x525C	0x53ED	# <CJK>
0x99DB	0x525D	0x53FA	# <CJK>
0x99DC	0x525E	0x5401	# <CJK>
0x99DD	0x525F	0x543D	# <CJK>
0x99DE	0x5260	0x5440	# <CJK>
0x99DF	0x5261	0x542C	# <CJK>
0x99E0	0x5262	0x542D	# <CJK>
0x99E1	0x5263	0x543C	# <CJK>
0x99E2	0x5264	0x542E	# <CJK>
0x99E3	0x5265	0x5436	# <CJK>
0x99E4	0x5266	0x5429	# <CJK>
0x99E5	0x5267	0x541D	# <CJK>
0x99E6	0x5268	0x544E	# <CJK>
0x99E7	0x5269	0x548F	# <CJK>
0x99E8	0x526A	0x5475	# <CJK>
0x99E9	0x526B	0x548E	# <CJK>
0x99EA	0x526C	0x545F	# <CJK>
0x99EB	0x526D	0x5471	# <CJK>
0x99EC	0x526E	0x5477	# <CJK>
0x99ED	0x526F	0x5470	# <CJK>
0x99EE	0x5270	0x5492	# <CJK>
0x99EF	0x5271	0x547B	# <CJK>
0x99F0	0x5272	0x5480	# <CJK>
0x99F1	0x5273	0x5476	# <CJK>
0x99F2	0x5274	0x5484	# <CJK>
0x99F3	0x5275	0x5490	# <CJK>
0x99F4	0x5276	0x5486	# <CJK>
0x99F5	0x5277	0x54C7	# <CJK>
0x99F6	0x5278	0x54A2	# <CJK>
0x99F7	0x5279	0x54B8	# <CJK>
0x99F8	0x527A	0x54A5	# <CJK>
0x99F9	0x527B	0x54AC	# <CJK>
0x99FA	0x527C	0x54C4	# <CJK>
0x99FB	0x527D	0x54C8	# <CJK>
0x99FC	0x527E	0x54A8	# <CJK>
0x9A40	0x5321	0x54AB	# <CJK>
0x9A41	0x5322	0x54C2	# <CJK>
0x9A42	0x5323	0x54A4	# <CJK>
0x9A43	0x5324	0x54BE	# <CJK>
0x9A44	0x5325	0x54BC	# <CJK>
0x9A45	0x5326	0x54D8	# <CJK>
0x9A46	0x5327	0x54E5	# <CJK>
0x9A47	0x5328	0x54E6	# <CJK>
0x9A48	0x5329	0x550F	# <CJK>
0x9A49	0x532A	0x5514	# <CJK>
0x9A4A	0x532B	0x54FD	# <CJK>
0x9A4B	0x532C	0x54EE	# <CJK>
0x9A4C	0x532D	0x54ED	# <CJK>
0x9A4D	0x532E	0x54FA	# <CJK>
0x9A4E	0x532F	0x54E2	# <CJK>
0x9A4F	0x5330	0x5539	# <CJK>
0x9A50	0x5331	0x5540	# <CJK>
0x9A51	0x5332	0x5563	# <CJK>
0x9A52	0x5333	0x554C	# <CJK>
0x9A53	0x5334	0x552E	# <CJK>
0x9A54	0x5335	0x555C	# <CJK>
0x9A55	0x5336	0x5545	# <CJK>
0x9A56	0x5337	0x5556	# <CJK>
0x9A57	0x5338	0x5557	# <CJK>
0x9A58	0x5339	0x5538	# <CJK>
0x9A59	0x533A	0x5533	# <CJK>
0x9A5A	0x533B	0x555D	# <CJK>
0x9A5B	0x533C	0x5599	# <CJK>
0x9A5C	0x533D	0x5580	# <CJK>
0x9A5D	0x533E	0x54AF	# <CJK>
0x9A5E	0x533F	0x558A	# <CJK>
0x9A5F	0x5340	0x559F	# <CJK>
0x9A60	0x5341	0x557B	# <CJK>
0x9A61	0x5342	0x557E	# <CJK>
0x9A62	0x5343	0x5598	# <CJK>
0x9A63	0x5344	0x559E	# <CJK>
0x9A64	0x5345	0x55AE	# <CJK>
0x9A65	0x5346	0x557C	# <CJK>
0x9A66	0x5347	0x5583	# <CJK>
0x9A67	0x5348	0x55A9	# <CJK>
0x9A68	0x5349	0x5587	# <CJK>
0x9A69	0x534A	0x55A8	# <CJK>
0x9A6A	0x534B	0x55DA	# <CJK>
0x9A6B	0x534C	0x55C5	# <CJK>
0x9A6C	0x534D	0x55DF	# <CJK>
0x9A6D	0x534E	0x55C4	# <CJK>
0x9A6E	0x534F	0x55DC	# <CJK>
0x9A6F	0x5350	0x55E4	# <CJK>
0x9A70	0x5351	0x55D4	# <CJK>
0x9A71	0x5352	0x5614	# <CJK>
0x9A72	0x5353	0x55F7	# <CJK>
0x9A73	0x5354	0x5616	# <CJK>
0x9A74	0x5355	0x55FE	# <CJK>
0x9A75	0x5356	0x55FD	# <CJK>
0x9A76	0x5357	0x561B	# <CJK>
0x9A77	0x5358	0x55F9	# <CJK>
0x9A78	0x5359	0x564E	# <CJK>
0x9A79	0x535A	0x5650	# <CJK>
0x9A7A	0x535B	0x71DF	# <CJK>
0x9A7B	0x535C	0x5634	# <CJK>
0x9A7C	0x535D	0x5636	# <CJK>
0x9A7D	0x535E	0x5632	# <CJK>
0x9A7E	0x535F	0x5638	# <CJK>
0x9A80	0x5360	0x566B	# <CJK>
0x9A81	0x5361	0x5664	# <CJK>
0x9A82	0x5362	0x562F	# <CJK>
0x9A83	0x5363	0x566C	# <CJK>
0x9A84	0x5364	0x566A	# <CJK>
0x9A85	0x5365	0x5686	# <CJK>
0x9A86	0x5366	0x5680	# <CJK>
0x9A87	0x5367	0x568A	# <CJK>
0x9A88	0x5368	0x56A0	# <CJK>
0x9A89	0x5369	0x5694	# <CJK>
0x9A8A	0x536A	0x568F	# <CJK>
0x9A8B	0x536B	0x56A5	# <CJK>
0x9A8C	0x536C	0x56AE	# <CJK>
0x9A8D	0x536D	0x56B6	# <CJK>
0x9A8E	0x536E	0x56B4	# <CJK>
0x9A8F	0x536F	0x56C2	# <CJK>
0x9A90	0x5370	0x56BC	# <CJK>
0x9A91	0x5371	0x56C1	# <CJK>
0x9A92	0x5372	0x56C3	# <CJK>
0x9A93	0x5373	0x56C0	# <CJK>
0x9A94	0x5374	0x56C8	# <CJK>
0x9A95	0x5375	0x56CE	# <CJK>
0x9A96	0x5376	0x56D1	# <CJK>
0x9A97	0x5377	0x56D3	# <CJK>
0x9A98	0x5378	0x56D7	# <CJK>
0x9A99	0x5379	0x56EE	# <CJK>
0x9A9A	0x537A	0x56F9	# <CJK>
0x9A9B	0x537B	0x5700	# <CJK>
0x9A9C	0x537C	0x56FF	# <CJK>
0x9A9D	0x537D	0x5704	# <CJK>
0x9A9E	0x537E	0x5709	# <CJK>
0x9A9F	0x5421	0x5708	# <CJK>
0x9AA0	0x5422	0x570B	# <CJK>
0x9AA1	0x5423	0x570D	# <CJK>
0x9AA2	0x5424	0x5713	# <CJK>
0x9AA3	0x5425	0x5718	# <CJK>
0x9AA4	0x5426	0x5716	# <CJK>
0x9AA5	0x5427	0x55C7	# <CJK>
0x9AA6	0x5428	0x571C	# <CJK>
0x9AA7	0x5429	0x5726	# <CJK>
0x9AA8	0x542A	0x5737	# <CJK>
0x9AA9	0x542B	0x5738	# <CJK>
0x9AAA	0x542C	0x574E	# <CJK>
0x9AAB	0x542D	0x573B	# <CJK>
0x9AAC	0x542E	0x5740	# <CJK>
0x9AAD	0x542F	0x574F	# <CJK>
0x9AAE	0x5430	0x5769	# <CJK>
0x9AAF	0x5431	0x57C0	# <CJK>
0x9AB0	0x5432	0x5788	# <CJK>
0x9AB1	0x5433	0x5761	# <CJK>
0x9AB2	0x5434	0x577F	# <CJK>
0x9AB3	0x5435	0x5789	# <CJK>
0x9AB4	0x5436	0x5793	# <CJK>
0x9AB5	0x5437	0x57A0	# <CJK>
0x9AB6	0x5438	0x57B3	# <CJK>
0x9AB7	0x5439	0x57A4	# <CJK>
0x9AB8	0x543A	0x57AA	# <CJK>
0x9AB9	0x543B	0x57B0	# <CJK>
0x9ABA	0x543C	0x57C3	# <CJK>
0x9ABB	0x543D	0x57C6	# <CJK>
0x9ABC	0x543E	0x57D4	# <CJK>
0x9ABD	0x543F	0x57D2	# <CJK>
0x9ABE	0x5440	0x57D3	# <CJK>
0x9ABF	0x5441	0x580A	# <CJK>
0x9AC0	0x5442	0x57D6	# <CJK>
0x9AC1	0x5443	0x57E3	# <CJK>
0x9AC2	0x5444	0x580B	# <CJK>
0x9AC3	0x5445	0x5819	# <CJK>
0x9AC4	0x5446	0x581D	# <CJK>
0x9AC5	0x5447	0x5872	# <CJK>
0x9AC6	0x5448	0x5821	# <CJK>
0x9AC7	0x5449	0x5862	# <CJK>
0x9AC8	0x544A	0x584B	# <CJK>
0x9AC9	0x544B	0x5870	# <CJK>
0x9ACA	0x544C	0x6BC0	# <CJK>
0x9ACB	0x544D	0x5852	# <CJK>
0x9ACC	0x544E	0x583D	# <CJK>
0x9ACD	0x544F	0x5879	# <CJK>
0x9ACE	0x5450	0x5885	# <CJK>
0x9ACF	0x5451	0x58B9	# <CJK>
0x9AD0	0x5452	0x589F	# <CJK>
0x9AD1	0x5453	0x58AB	# <CJK>
0x9AD2	0x5454	0x58BA	# <CJK>
0x9AD3	0x5455	0x58DE	# <CJK>
0x9AD4	0x5456	0x58BB	# <CJK>
0x9AD5	0x5457	0x58B8	# <CJK>
0x9AD6	0x5458	0x58AE	# <CJK>
0x9AD7	0x5459	0x58C5	# <CJK>
0x9AD8	0x545A	0x58D3	# <CJK>
0x9AD9	0x545B	0x58D1	# <CJK>
0x9ADA	0x545C	0x58D7	# <CJK>
0x9ADB	0x545D	0x58D9	# <CJK>
0x9ADC	0x545E	0x58D8	# <CJK>
0x9ADD	0x545F	0x58E5	# <CJK>
0x9ADE	0x5460	0x58DC	# <CJK>
0x9ADF	0x5461	0x58E4	# <CJK>
0x9AE0	0x5462	0x58DF	# <CJK>
0x9AE1	0x5463	0x58EF	# <CJK>
0x9AE2	0x5464	0x58FA	# <CJK>
0x9AE3	0x5465	0x58F9	# <CJK>
0x9AE4	0x5466	0x58FB	# <CJK>
0x9AE5	0x5467	0x58FC	# <CJK>
0x9AE6	0x5468	0x58FD	# <CJK>
0x9AE7	0x5469	0x5902	# <CJK>
0x9AE8	0x546A	0x590A	# <CJK>
0x9AE9	0x546B	0x5910	# <CJK>
0x9AEA	0x546C	0x591B	# <CJK>
0x9AEB	0x546D	0x68A6	# <CJK>
0x9AEC	0x546E	0x5925	# <CJK>
0x9AED	0x546F	0x592C	# <CJK>
0x9AEE	0x5470	0x592D	# <CJK>
0x9AEF	0x5471	0x5932	# <CJK>
0x9AF0	0x5472	0x5938	# <CJK>
0x9AF1	0x5473	0x593E	# <CJK>
0x9AF2	0x5474	0x7AD2	# <CJK>
0x9AF3	0x5475	0x5955	# <CJK>
0x9AF4	0x5476	0x5950	# <CJK>
0x9AF5	0x5477	0x594E	# <CJK>
0x9AF6	0x5478	0x595A	# <CJK>
0x9AF7	0x5479	0x5958	# <CJK>
0x9AF8	0x547A	0x5962	# <CJK>
0x9AF9	0x547B	0x5960	# <CJK>
0x9AFA	0x547C	0x5967	# <CJK>
0x9AFB	0x547D	0x596C	# <CJK>
0x9AFC	0x547E	0x5969	# <CJK>
0x9B40	0x5521	0x5978	# <CJK>
0x9B41	0x5522	0x5981	# <CJK>
0x9B42	0x5523	0x599D	# <CJK>
0x9B43	0x5524	0x4F5E	# <CJK>
0x9B44	0x5525	0x4FAB	# <CJK>
0x9B45	0x5526	0x59A3	# <CJK>
0x9B46	0x5527	0x59B2	# <CJK>
0x9B47	0x5528	0x59C6	# <CJK>
0x9B48	0x5529	0x59E8	# <CJK>
0x9B49	0x552A	0x59DC	# <CJK>
0x9B4A	0x552B	0x598D	# <CJK>
0x9B4B	0x552C	0x59D9	# <CJK>
0x9B4C	0x552D	0x59DA	# <CJK>
0x9B4D	0x552E	0x5A25	# <CJK>
0x9B4E	0x552F	0x5A1F	# <CJK>
0x9B4F	0x5530	0x5A11	# <CJK>
0x9B50	0x5531	0x5A1C	# <CJK>
0x9B51	0x5532	0x5A09	# <CJK>
0x9B52	0x5533	0x5A1A	# <CJK>
0x9B53	0x5534	0x5A40	# <CJK>
0x9B54	0x5535	0x5A6C	# <CJK>
0x9B55	0x5536	0x5A49	# <CJK>
0x9B56	0x5537	0x5A35	# <CJK>
0x9B57	0x5538	0x5A36	# <CJK>
0x9B58	0x5539	0x5A62	# <CJK>
0x9B59	0x553A	0x5A6A	# <CJK>
0x9B5A	0x553B	0x5A9A	# <CJK>
0x9B5B	0x553C	0x5ABC	# <CJK>
0x9B5C	0x553D	0x5ABE	# <CJK>
0x9B5D	0x553E	0x5ACB	# <CJK>
0x9B5E	0x553F	0x5AC2	# <CJK>
0x9B5F	0x5540	0x5ABD	# <CJK>
0x9B60	0x5541	0x5AE3	# <CJK>
0x9B61	0x5542	0x5AD7	# <CJK>
0x9B62	0x5543	0x5AE6	# <CJK>
0x9B63	0x5544	0x5AE9	# <CJK>
0x9B64	0x5545	0x5AD6	# <CJK>
0x9B65	0x5546	0x5AFA	# <CJK>
0x9B66	0x5547	0x5AFB	# <CJK>
0x9B67	0x5548	0x5B0C	# <CJK>
0x9B68	0x5549	0x5B0B	# <CJK>
0x9B69	0x554A	0x5B16	# <CJK>
0x9B6A	0x554B	0x5B32	# <CJK>
0x9B6B	0x554C	0x5AD0	# <CJK>
0x9B6C	0x554D	0x5B2A	# <CJK>
0x9B6D	0x554E	0x5B36	# <CJK>
0x9B6E	0x554F	0x5B3E	# <CJK>
0x9B6F	0x5550	0x5B43	# <CJK>
0x9B70	0x5551	0x5B45	# <CJK>
0x9B71	0x5552	0x5B40	# <CJK>
0x9B72	0x5553	0x5B51	# <CJK>
0x9B73	0x5554	0x5B55	# <CJK>
0x9B74	0x5555	0x5B5A	# <CJK>
0x9B75	0x5556	0x5B5B	# <CJK>
0x9B76	0x5557	0x5B65	# <CJK>
0x9B77	0x5558	0x5B69	# <CJK>
0x9B78	0x5559	0x5B70	# <CJK>
0x9B79	0x555A	0x5B73	# <CJK>
0x9B7A	0x555B	0x5B75	# <CJK>
0x9B7B	0x555C	0x5B78	# <CJK>
0x9B7C	0x555D	0x6588	# <CJK>
0x9B7D	0x555E	0x5B7A	# <CJK>
0x9B7E	0x555F	0x5B80	# <CJK>
0x9B80	0x5560	0x5B83	# <CJK>
0x9B81	0x5561	0x5BA6	# <CJK>
0x9B82	0x5562	0x5BB8	# <CJK>
0x9B83	0x5563	0x5BC3	# <CJK>
0x9B84	0x5564	0x5BC7	# <CJK>
0x9B85	0x5565	0x5BC9	# <CJK>
0x9B86	0x5566	0x5BD4	# <CJK>
0x9B87	0x5567	0x5BD0	# <CJK>
0x9B88	0x5568	0x5BE4	# <CJK>
0x9B89	0x5569	0x5BE6	# <CJK>
0x9B8A	0x556A	0x5BE2	# <CJK>
0x9B8B	0x556B	0x5BDE	# <CJK>
0x9B8C	0x556C	0x5BE5	# <CJK>
0x9B8D	0x556D	0x5BEB	# <CJK>
0x9B8E	0x556E	0x5BF0	# <CJK>
0x9B8F	0x556F	0x5BF6	# <CJK>
0x9B90	0x5570	0x5BF3	# <CJK>
0x9B91	0x5571	0x5C05	# <CJK>
0x9B92	0x5572	0x5C07	# <CJK>
0x9B93	0x5573	0x5C08	# <CJK>
0x9B94	0x5574	0x5C0D	# <CJK>
0x9B95	0x5575	0x5C13	# <CJK>
0x9B96	0x5576	0x5C20	# <CJK>
0x9B97	0x5577	0x5C22	# <CJK>
0x9B98	0x5578	0x5C28	# <CJK>
0x9B99	0x5579	0x5C38	# <CJK>
0x9B9A	0x557A	0x5C39	# <CJK>
0x9B9B	0x557B	0x5C41	# <CJK>
0x9B9C	0x557C	0x5C46	# <CJK>
0x9B9D	0x557D	0x5C4E	# <CJK>
0x9B9E	0x557E	0x5C53	# <CJK>
0x9B9F	0x5621	0x5C50	# <CJK>
0x9BA0	0x5622	0x5C4F	# <CJK>
0x9BA1	0x5623	0x5B71	# <CJK>
0x9BA2	0x5624	0x5C6C	# <CJK>
0x9BA3	0x5625	0x5C6E	# <CJK>
0x9BA4	0x5626	0x4E62	# <CJK>
0x9BA5	0x5627	0x5C76	# <CJK>
0x9BA6	0x5628	0x5C79	# <CJK>
0x9BA7	0x5629	0x5C8C	# <CJK>
0x9BA8	0x562A	0x5C91	# <CJK>
0x9BA9	0x562B	0x5C94	# <CJK>
0x9BAA	0x562C	0x599B	# <CJK>
0x9BAB	0x562D	0x5CAB	# <CJK>
0x9BAC	0x562E	0x5CBB	# <CJK>
0x9BAD	0x562F	0x5CB6	# <CJK>
0x9BAE	0x5630	0x5CBC	# <CJK>
0x9BAF	0x5631	0x5CB7	# <CJK>
0x9BB0	0x5632	0x5CC5	# <CJK>
0x9BB1	0x5633	0x5CBE	# <CJK>
0x9BB2	0x5634	0x5CC7	# <CJK>
0x9BB3	0x5635	0x5CD9	# <CJK>
0x9BB4	0x5636	0x5CE9	# <CJK>
0x9BB5	0x5637	0x5CFD	# <CJK>
0x9BB6	0x5638	0x5CFA	# <CJK>
0x9BB7	0x5639	0x5CED	# <CJK>
0x9BB8	0x563A	0x5D8C	# <CJK>
0x9BB9	0x563B	0x5CEA	# <CJK>
0x9BBA	0x563C	0x5D0B	# <CJK>
0x9BBB	0x563D	0x5D15	# <CJK>
0x9BBC	0x563E	0x5D17	# <CJK>
0x9BBD	0x563F	0x5D5C	# <CJK>
0x9BBE	0x5640	0x5D1F	# <CJK>
0x9BBF	0x5641	0x5D1B	# <CJK>
0x9BC0	0x5642	0x5D11	# <CJK>
0x9BC1	0x5643	0x5D14	# <CJK>
0x9BC2	0x5644	0x5D22	# <CJK>
0x9BC3	0x5645	0x5D1A	# <CJK>
0x9BC4	0x5646	0x5D19	# <CJK>
0x9BC5	0x5647	0x5D18	# <CJK>
0x9BC6	0x5648	0x5D4C	# <CJK>
0x9BC7	0x5649	0x5D52	# <CJK>
0x9BC8	0x564A	0x5D4E	# <CJK>
0x9BC9	0x564B	0x5D4B	# <CJK>
0x9BCA	0x564C	0x5D6C	# <CJK>
0x9BCB	0x564D	0x5D73	# <CJK>
0x9BCC	0x564E	0x5D76	# <CJK>
0x9BCD	0x564F	0x5D87	# <CJK>
0x9BCE	0x5650	0x5D84	# <CJK>
0x9BCF	0x5651	0x5D82	# <CJK>
0x9BD0	0x5652	0x5DA2	# <CJK>
0x9BD1	0x5653	0x5D9D	# <CJK>
0x9BD2	0x5654	0x5DAC	# <CJK>
0x9BD3	0x5655	0x5DAE	# <CJK>
0x9BD4	0x5656	0x5DBD	# <CJK>
0x9BD5	0x5657	0x5D90	# <CJK>
0x9BD6	0x5658	0x5DB7	# <CJK>
0x9BD7	0x5659	0x5DBC	# <CJK>
0x9BD8	0x565A	0x5DC9	# <CJK>
0x9BD9	0x565B	0x5DCD	# <CJK>
0x9BDA	0x565C	0x5DD3	# <CJK>
0x9BDB	0x565D	0x5DD2	# <CJK>
0x9BDC	0x565E	0x5DD6	# <CJK>
0x9BDD	0x565F	0x5DDB	# <CJK>
0x9BDE	0x5660	0x5DEB	# <CJK>
0x9BDF	0x5661	0x5DF2	# <CJK>
0x9BE0	0x5662	0x5DF5	# <CJK>
0x9BE1	0x5663	0x5E0B	# <CJK>
0x9BE2	0x5664	0x5E1A	# <CJK>
0x9BE3	0x5665	0x5E19	# <CJK>
0x9BE4	0x5666	0x5E11	# <CJK>
0x9BE5	0x5667	0x5E1B	# <CJK>
0x9BE6	0x5668	0x5E36	# <CJK>
0x9BE7	0x5669	0x5E37	# <CJK>
0x9BE8	0x566A	0x5E44	# <CJK>
0x9BE9	0x566B	0x5E43	# <CJK>
0x9BEA	0x566C	0x5E40	# <CJK>
0x9BEB	0x566D	0x5E4E	# <CJK>
0x9BEC	0x566E	0x5E57	# <CJK>
0x9BED	0x566F	0x5E54	# <CJK>
0x9BEE	0x5670	0x5E5F	# <CJK>
0x9BEF	0x5671	0x5E62	# <CJK>
0x9BF0	0x5672	0x5E64	# <CJK>
0x9BF1	0x5673	0x5E47	# <CJK>
0x9BF2	0x5674	0x5E75	# <CJK>
0x9BF3	0x5675	0x5E76	# <CJK>
0x9BF4	0x5676	0x5E7A	# <CJK>
0x9BF5	0x5677	0x9EBC	# <CJK>
0x9BF6	0x5678	0x5E7F	# <CJK>
0x9BF7	0x5679	0x5EA0	# <CJK>
0x9BF8	0x567A	0x5EC1	# <CJK>
0x9BF9	0x567B	0x5EC2	# <CJK>
0x9BFA	0x567C	0x5EC8	# <CJK>
0x9BFB	0x567D	0x5ED0	# <CJK>
0x9BFC	0x567E	0x5ECF	# <CJK>
0x9C40	0x5721	0x5ED6	# <CJK>
0x9C41	0x5722	0x5EE3	# <CJK>
0x9C42	0x5723	0x5EDD	# <CJK>
0x9C43	0x5724	0x5EDA	# <CJK>
0x9C44	0x5725	0x5EDB	# <CJK>
0x9C45	0x5726	0x5EE2	# <CJK>
0x9C46	0x5727	0x5EE1	# <CJK>
0x9C47	0x5728	0x5EE8	# <CJK>
0x9C48	0x5729	0x5EE9	# <CJK>
0x9C49	0x572A	0x5EEC	# <CJK>
0x9C4A	0x572B	0x5EF1	# <CJK>
0x9C4B	0x572C	0x5EF3	# <CJK>
0x9C4C	0x572D	0x5EF0	# <CJK>
0x9C4D	0x572E	0x5EF4	# <CJK>
0x9C4E	0x572F	0x5EF8	# <CJK>
0x9C4F	0x5730	0x5EFE	# <CJK>
0x9C50	0x5731	0x5F03	# <CJK>
0x9C51	0x5732	0x5F09	# <CJK>
0x9C52	0x5733	0x5F5D	# <CJK>
0x9C53	0x5734	0x5F5C	# <CJK>
0x9C54	0x5735	0x5F0B	# <CJK>
0x9C55	0x5736	0x5F11	# <CJK>
0x9C56	0x5737	0x5F16	# <CJK>
0x9C57	0x5738	0x5F29	# <CJK>
0x9C58	0x5739	0x5F2D	# <CJK>
0x9C59	0x573A	0x5F38	# <CJK>
0x9C5A	0x573B	0x5F41	# <CJK>
0x9C5B	0x573C	0x5F48	# <CJK>
0x9C5C	0x573D	0x5F4C	# <CJK>
0x9C5D	0x573E	0x5F4E	# <CJK>
0x9C5E	0x573F	0x5F2F	# <CJK>
0x9C5F	0x5740	0x5F51	# <CJK>
0x9C60	0x5741	0x5F56	# <CJK>
0x9C61	0x5742	0x5F57	# <CJK>
0x9C62	0x5743	0x5F59	# <CJK>
0x9C63	0x5744	0x5F61	# <CJK>
0x9C64	0x5745	0x5F6D	# <CJK>
0x9C65	0x5746	0x5F73	# <CJK>
0x9C66	0x5747	0x5F77	# <CJK>
0x9C67	0x5748	0x5F83	# <CJK>
0x9C68	0x5749	0x5F82	# <CJK>
0x9C69	0x574A	0x5F7F	# <CJK>
0x9C6A	0x574B	0x5F8A	# <CJK>
0x9C6B	0x574C	0x5F88	# <CJK>
0x9C6C	0x574D	0x5F91	# <CJK>
0x9C6D	0x574E	0x5F87	# <CJK>
0x9C6E	0x574F	0x5F9E	# <CJK>
0x9C6F	0x5750	0x5F99	# <CJK>
0x9C70	0x5751	0x5F98	# <CJK>
0x9C71	0x5752	0x5FA0	# <CJK>
0x9C72	0x5753	0x5FA8	# <CJK>
0x9C73	0x5754	0x5FAD	# <CJK>
0x9C74	0x5755	0x5FBC	# <CJK>
0x9C75	0x5756	0x5FD6	# <CJK>
0x9C76	0x5757	0x5FFB	# <CJK>
0x9C77	0x5758	0x5FE4	# <CJK>
0x9C78	0x5759	0x5FF8	# <CJK>
0x9C79	0x575A	0x5FF1	# <CJK>
0x9C7A	0x575B	0x5FDD	# <CJK>
0x9C7B	0x575C	0x60B3	# <CJK>
0x9C7C	0x575D	0x5FFF	# <CJK>
0x9C7D	0x575E	0x6021	# <CJK>
0x9C7E	0x575F	0x6060	# <CJK>
0x9C80	0x5760	0x6019	# <CJK>
0x9C81	0x5761	0x6010	# <CJK>
0x9C82	0x5762	0x6029	# <CJK>
0x9C83	0x5763	0x600E	# <CJK>
0x9C84	0x5764	0x6031	# <CJK>
0x9C85	0x5765	0x601B	# <CJK>
0x9C86	0x5766	0x6015	# <CJK>
0x9C87	0x5767	0x602B	# <CJK>
0x9C88	0x5768	0x6026	# <CJK>
0x9C89	0x5769	0x600F	# <CJK>
0x9C8A	0x576A	0x603A	# <CJK>
0x9C8B	0x576B	0x605A	# <CJK>
0x9C8C	0x576C	0x6041	# <CJK>
0x9C8D	0x576D	0x606A	# <CJK>
0x9C8E	0x576E	0x6077	# <CJK>
0x9C8F	0x576F	0x605F	# <CJK>
0x9C90	0x5770	0x604A	# <CJK>
0x9C91	0x5771	0x6046	# <CJK>
0x9C92	0x5772	0x604D	# <CJK>
0x9C93	0x5773	0x6063	# <CJK>
0x9C94	0x5774	0x6043	# <CJK>
0x9C95	0x5775	0x6064	# <CJK>
0x9C96	0x5776	0x6042	# <CJK>
0x9C97	0x5777	0x606C	# <CJK>
0x9C98	0x5778	0x606B	# <CJK>
0x9C99	0x5779	0x6059	# <CJK>
0x9C9A	0x577A	0x6081	# <CJK>
0x9C9B	0x577B	0x608D	# <CJK>
0x9C9C	0x577C	0x60E7	# <CJK>
0x9C9D	0x577D	0x6083	# <CJK>
0x9C9E	0x577E	0x609A	# <CJK>
0x9C9F	0x5821	0x6084	# <CJK>
0x9CA0	0x5822	0x609B	# <CJK>
0x9CA1	0x5823	0x6096	# <CJK>
0x9CA2	0x5824	0x6097	# <CJK>
0x9CA3	0x5825	0x6092	# <CJK>
0x9CA4	0x5826	0x60A7	# <CJK>
0x9CA5	0x5827	0x608B	# <CJK>
0x9CA6	0x5828	0x60E1	# <CJK>
0x9CA7	0x5829	0x60B8	# <CJK>
0x9CA8	0x582A	0x60E0	# <CJK>
0x9CA9	0x582B	0x60D3	# <CJK>
0x9CAA	0x582C	0x60B4	# <CJK>
0x9CAB	0x582D	0x5FF0	# <CJK>
0x9CAC	0x582E	0x60BD	# <CJK>
0x9CAD	0x582F	0x60C6	# <CJK>
0x9CAE	0x5830	0x60B5	# <CJK>
0x9CAF	0x5831	0x60D8	# <CJK>
0x9CB0	0x5832	0x614D	# <CJK>
0x9CB1	0x5833	0x6115	# <CJK>
0x9CB2	0x5834	0x6106	# <CJK>
0x9CB3	0x5835	0x60F6	# <CJK>
0x9CB4	0x5836	0x60F7	# <CJK>
0x9CB5	0x5837	0x6100	# <CJK>
0x9CB6	0x5838	0x60F4	# <CJK>
0x9CB7	0x5839	0x60FA	# <CJK>
0x9CB8	0x583A	0x6103	# <CJK>
0x9CB9	0x583B	0x6121	# <CJK>
0x9CBA	0x583C	0x60FB	# <CJK>
0x9CBB	0x583D	0x60F1	# <CJK>
0x9CBC	0x583E	0x610D	# <CJK>
0x9CBD	0x583F	0x610E	# <CJK>
0x9CBE	0x5840	0x6147	# <CJK>
0x9CBF	0x5841	0x613E	# <CJK>
0x9CC0	0x5842	0x6128	# <CJK>
0x9CC1	0x5843	0x6127	# <CJK>
0x9CC2	0x5844	0x614A	# <CJK>
0x9CC3	0x5845	0x613F	# <CJK>
0x9CC4	0x5846	0x613C	# <CJK>
0x9CC5	0x5847	0x612C	# <CJK>
0x9CC6	0x5848	0x6134	# <CJK>
0x9CC7	0x5849	0x613D	# <CJK>
0x9CC8	0x584A	0x6142	# <CJK>
0x9CC9	0x584B	0x6144	# <CJK>
0x9CCA	0x584C	0x6173	# <CJK>
0x9CCB	0x584D	0x6177	# <CJK>
0x9CCC	0x584E	0x6158	# <CJK>
0x9CCD	0x584F	0x6159	# <CJK>
0x9CCE	0x5850	0x615A	# <CJK>
0x9CCF	0x5851	0x616B	# <CJK>
0x9CD0	0x5852	0x6174	# <CJK>
0x9CD1	0x5853	0x616F	# <CJK>
0x9CD2	0x5854	0x6165	# <CJK>
0x9CD3	0x5855	0x6171	# <CJK>
0x9CD4	0x5856	0x615F	# <CJK>
0x9CD5	0x5857	0x615D	# <CJK>
0x9CD6	0x5858	0x6153	# <CJK>
0x9CD7	0x5859	0x6175	# <CJK>
0x9CD8	0x585A	0x6199	# <CJK>
0x9CD9	0x585B	0x6196	# <CJK>
0x9CDA	0x585C	0x6187	# <CJK>
0x9CDB	0x585D	0x61AC	# <CJK>
0x9CDC	0x585E	0x6194	# <CJK>
0x9CDD	0x585F	0x619A	# <CJK>
0x9CDE	0x5860	0x618A	# <CJK>
0x9CDF	0x5861	0x6191	# <CJK>
0x9CE0	0x5862	0x61AB	# <CJK>
0x9CE1	0x5863	0x61AE	# <CJK>
0x9CE2	0x5864	0x61CC	# <CJK>
0x9CE3	0x5865	0x61CA	# <CJK>
0x9CE4	0x5866	0x61C9	# <CJK>
0x9CE5	0x5867	0x61F7	# <CJK>
0x9CE6	0x5868	0x61C8	# <CJK>
0x9CE7	0x5869	0x61C3	# <CJK>
0x9CE8	0x586A	0x61C6	# <CJK>
0x9CE9	0x586B	0x61BA	# <CJK>
0x9CEA	0x586C	0x61CB	# <CJK>
0x9CEB	0x586D	0x7F79	# <CJK>
0x9CEC	0x586E	0x61CD	# <CJK>
0x9CED	0x586F	0x61E6	# <CJK>
0x9CEE	0x5870	0x61E3	# <CJK>
0x9CEF	0x5871	0x61F6	# <CJK>
0x9CF0	0x5872	0x61FA	# <CJK>
0x9CF1	0x5873	0x61F4	# <CJK>
0x9CF2	0x5874	0x61FF	# <CJK>
0x9CF3	0x5875	0x61FD	# <CJK>
0x9CF4	0x5876	0x61FC	# <CJK>
0x9CF5	0x5877	0x61FE	# <CJK>
0x9CF6	0x5878	0x6200	# <CJK>
0x9CF7	0x5879	0x6208	# <CJK>
0x9CF8	0x587A	0x6209	# <CJK>
0x9CF9	0x587B	0x620D	# <CJK>
0x9CFA	0x587C	0x620C	# <CJK>
0x9CFB	0x587D	0x6214	# <CJK>
0x9CFC	0x587E	0x621B	# <CJK>
0x9D40	0x5921	0x621E	# <CJK>
0x9D41	0x5922	0x6221	# <CJK>
0x9D42	0x5923	0x622A	# <CJK>
0x9D43	0x5924	0x622E	# <CJK>
0x9D44	0x5925	0x6230	# <CJK>
0x9D45	0x5926	0x6232	# <CJK>
0x9D46	0x5927	0x6233	# <CJK>
0x9D47	0x5928	0x6241	# <CJK>
0x9D48	0x5929	0x624E	# <CJK>
0x9D49	0x592A	0x625E	# <CJK>
0x9D4A	0x592B	0x6263	# <CJK>
0x9D4B	0x592C	0x625B	# <CJK>
0x9D4C	0x592D	0x6260	# <CJK>
0x9D4D	0x592E	0x6268	# <CJK>
0x9D4E	0x592F	0x627C	# <CJK>
0x9D4F	0x5930	0x6282	# <CJK>
0x9D50	0x5931	0x6289	# <CJK>
0x9D51	0x5932	0x627E	# <CJK>
0x9D52	0x5933	0x6292	# <CJK>
0x9D53	0x5934	0x6293	# <CJK>
0x9D54	0x5935	0x6296	# <CJK>
0x9D55	0x5936	0x62D4	# <CJK>
0x9D56	0x5937	0x6283	# <CJK>
0x9D57	0x5938	0x6294	# <CJK>
0x9D58	0x5939	0x62D7	# <CJK>
0x9D59	0x593A	0x62D1	# <CJK>
0x9D5A	0x593B	0x62BB	# <CJK>
0x9D5B	0x593C	0x62CF	# <CJK>
0x9D5C	0x593D	0x62FF	# <CJK>
0x9D5D	0x593E	0x62C6	# <CJK>
0x9D5E	0x593F	0x64D4	# <CJK>
0x9D5F	0x5940	0x62C8	# <CJK>
0x9D60	0x5941	0x62DC	# <CJK>
0x9D61	0x5942	0x62CC	# <CJK>
0x9D62	0x5943	0x62CA	# <CJK>
0x9D63	0x5944	0x62C2	# <CJK>
0x9D64	0x5945	0x62C7	# <CJK>
0x9D65	0x5946	0x629B	# <CJK>
0x9D66	0x5947	0x62C9	# <CJK>
0x9D67	0x5948	0x630C	# <CJK>
0x9D68	0x5949	0x62EE	# <CJK>
0x9D69	0x594A	0x62F1	# <CJK>
0x9D6A	0x594B	0x6327	# <CJK>
0x9D6B	0x594C	0x6302	# <CJK>
0x9D6C	0x594D	0x6308	# <CJK>
0x9D6D	0x594E	0x62EF	# <CJK>
0x9D6E	0x594F	0x62F5	# <CJK>
0x9D6F	0x5950	0x6350	# <CJK>
0x9D70	0x5951	0x633E	# <CJK>
0x9D71	0x5952	0x634D	# <CJK>
0x9D72	0x5953	0x641C	# <CJK>
0x9D73	0x5954	0x634F	# <CJK>
0x9D74	0x5955	0x6396	# <CJK>
0x9D75	0x5956	0x638E	# <CJK>
0x9D76	0x5957	0x6380	# <CJK>
0x9D77	0x5958	0x63AB	# <CJK>
0x9D78	0x5959	0x6376	# <CJK>
0x9D79	0x595A	0x63A3	# <CJK>
0x9D7A	0x595B	0x638F	# <CJK>
0x9D7B	0x595C	0x6389	# <CJK>
0x9D7C	0x595D	0x639F	# <CJK>
0x9D7D	0x595E	0x63B5	# <CJK>
0x9D7E	0x595F	0x636B	# <CJK>
0x9D80	0x5960	0x6369	# <CJK>
0x9D81	0x5961	0x63BE	# <CJK>
0x9D82	0x5962	0x63E9	# <CJK>
0x9D83	0x5963	0x63C0	# <CJK>
0x9D84	0x5964	0x63C6	# <CJK>
0x9D85	0x5965	0x63E3	# <CJK>
0x9D86	0x5966	0x63C9	# <CJK>
0x9D87	0x5967	0x63D2	# <CJK>
0x9D88	0x5968	0x63F6	# <CJK>
0x9D89	0x5969	0x63C4	# <CJK>
0x9D8A	0x596A	0x6416	# <CJK>
0x9D8B	0x596B	0x6434	# <CJK>
0x9D8C	0x596C	0x6406	# <CJK>
0x9D8D	0x596D	0x6413	# <CJK>
0x9D8E	0x596E	0x6426	# <CJK>
0x9D8F	0x596F	0x6436	# <CJK>
0x9D90	0x5970	0x651D	# <CJK>
0x9D91	0x5971	0x6417	# <CJK>
0x9D92	0x5972	0x6428	# <CJK>
0x9D93	0x5973	0x640F	# <CJK>
0x9D94	0x5974	0x6467	# <CJK>
0x9D95	0x5975	0x646F	# <CJK>
0x9D96	0x5976	0x6476	# <CJK>
0x9D97	0x5977	0x644E	# <CJK>
0x9D98	0x5978	0x652A	# <CJK>
0x9D99	0x5979	0x6495	# <CJK>
0x9D9A	0x597A	0x6493	# <CJK>
0x9D9B	0x597B	0x64A5	# <CJK>
0x9D9C	0x597C	0x64A9	# <CJK>
0x9D9D	0x597D	0x6488	# <CJK>
0x9D9E	0x597E	0x64BC	# <CJK>
0x9D9F	0x5A21	0x64DA	# <CJK>
0x9DA0	0x5A22	0x64D2	# <CJK>
0x9DA1	0x5A23	0x64C5	# <CJK>
0x9DA2	0x5A24	0x64C7	# <CJK>
0x9DA3	0x5A25	0x64BB	# <CJK>
0x9DA4	0x5A26	0x64D8	# <CJK>
0x9DA5	0x5A27	0x64C2	# <CJK>
0x9DA6	0x5A28	0x64F1	# <CJK>
0x9DA7	0x5A29	0x64E7	# <CJK>
0x9DA8	0x5A2A	0x8209	# <CJK>
0x9DA9	0x5A2B	0x64E0	# <CJK>
0x9DAA	0x5A2C	0x64E1	# <CJK>
0x9DAB	0x5A2D	0x62AC	# <CJK>
0x9DAC	0x5A2E	0x64E3	# <CJK>
0x9DAD	0x5A2F	0x64EF	# <CJK>
0x9DAE	0x5A30	0x652C	# <CJK>
0x9DAF	0x5A31	0x64F6	# <CJK>
0x9DB0	0x5A32	0x64F4	# <CJK>
0x9DB1	0x5A33	0x64F2	# <CJK>
0x9DB2	0x5A34	0x64FA	# <CJK>
0x9DB3	0x5A35	0x6500	# <CJK>
0x9DB4	0x5A36	0x64FD	# <CJK>
0x9DB5	0x5A37	0x6518	# <CJK>
0x9DB6	0x5A38	0x651C	# <CJK>
0x9DB7	0x5A39	0x6505	# <CJK>
0x9DB8	0x5A3A	0x6524	# <CJK>
0x9DB9	0x5A3B	0x6523	# <CJK>
0x9DBA	0x5A3C	0x652B	# <CJK>
0x9DBB	0x5A3D	0x6534	# <CJK>
0x9DBC	0x5A3E	0x6535	# <CJK>
0x9DBD	0x5A3F	0x6537	# <CJK>
0x9DBE	0x5A40	0x6536	# <CJK>
0x9DBF	0x5A41	0x6538	# <CJK>
0x9DC0	0x5A42	0x754B	# <CJK>
0x9DC1	0x5A43	0x6548	# <CJK>
0x9DC2	0x5A44	0x6556	# <CJK>
0x9DC3	0x5A45	0x6555	# <CJK>
0x9DC4	0x5A46	0x654D	# <CJK>
0x9DC5	0x5A47	0x6558	# <CJK>
0x9DC6	0x5A48	0x655E	# <CJK>
0x9DC7	0x5A49	0x655D	# <CJK>
0x9DC8	0x5A4A	0x6572	# <CJK>
0x9DC9	0x5A4B	0x6578	# <CJK>
0x9DCA	0x5A4C	0x6582	# <CJK>
0x9DCB	0x5A4D	0x6583	# <CJK>
0x9DCC	0x5A4E	0x8B8A	# <CJK>
0x9DCD	0x5A4F	0x659B	# <CJK>
0x9DCE	0x5A50	0x659F	# <CJK>
0x9DCF	0x5A51	0x65AB	# <CJK>
0x9DD0	0x5A52	0x65B7	# <CJK>
0x9DD1	0x5A53	0x65C3	# <CJK>
0x9DD2	0x5A54	0x65C6	# <CJK>
0x9DD3	0x5A55	0x65C1	# <CJK>
0x9DD4	0x5A56	0x65C4	# <CJK>
0x9DD5	0x5A57	0x65CC	# <CJK>
0x9DD6	0x5A58	0x65D2	# <CJK>
0x9DD7	0x5A59	0x65DB	# <CJK>
0x9DD8	0x5A5A	0x65D9	# <CJK>
0x9DD9	0x5A5B	0x65E0	# <CJK>
0x9DDA	0x5A5C	0x65E1	# <CJK>
0x9DDB	0x5A5D	0x65F1	# <CJK>
0x9DDC	0x5A5E	0x6772	# <CJK>
0x9DDD	0x5A5F	0x660A	# <CJK>
0x9DDE	0x5A60	0x6603	# <CJK>
0x9DDF	0x5A61	0x65FB	# <CJK>
0x9DE0	0x5A62	0x6773	# <CJK>
0x9DE1	0x5A63	0x6635	# <CJK>
0x9DE2	0x5A64	0x6636	# <CJK>
0x9DE3	0x5A65	0x6634	# <CJK>
0x9DE4	0x5A66	0x661C	# <CJK>
0x9DE5	0x5A67	0x664F	# <CJK>
0x9DE6	0x5A68	0x6644	# <CJK>
0x9DE7	0x5A69	0x6649	# <CJK>
0x9DE8	0x5A6A	0x6641	# <CJK>
0x9DE9	0x5A6B	0x665E	# <CJK>
0x9DEA	0x5A6C	0x665D	# <CJK>
0x9DEB	0x5A6D	0x6664	# <CJK>
0x9DEC	0x5A6E	0x6667	# <CJK>
0x9DED	0x5A6F	0x6668	# <CJK>
0x9DEE	0x5A70	0x665F	# <CJK>
0x9DEF	0x5A71	0x6662	# <CJK>
0x9DF0	0x5A72	0x6670	# <CJK>
0x9DF1	0x5A73	0x6683	# <CJK>
0x9DF2	0x5A74	0x6688	# <CJK>
0x9DF3	0x5A75	0x668E	# <CJK>
0x9DF4	0x5A76	0x6689	# <CJK>
0x9DF5	0x5A77	0x6684	# <CJK>
0x9DF6	0x5A78	0x6698	# <CJK>
0x9DF7	0x5A79	0x669D	# <CJK>
0x9DF8	0x5A7A	0x66C1	# <CJK>
0x9DF9	0x5A7B	0x66B9	# <CJK>
0x9DFA	0x5A7C	0x66C9	# <CJK>
0x9DFB	0x5A7D	0x66BE	# <CJK>
0x9DFC	0x5A7E	0x66BC	# <CJK>
0x9E40	0x5B21	0x66C4	# <CJK>
0x9E41	0x5B22	0x66B8	# <CJK>
0x9E42	0x5B23	0x66D6	# <CJK>
0x9E43	0x5B24	0x66DA	# <CJK>
0x9E44	0x5B25	0x66E0	# <CJK>
0x9E45	0x5B26	0x663F	# <CJK>
0x9E46	0x5B27	0x66E6	# <CJK>
0x9E47	0x5B28	0x66E9	# <CJK>
0x9E48	0x5B29	0x66F0	# <CJK>
0x9E49	0x5B2A	0x66F5	# <CJK>
0x9E4A	0x5B2B	0x66F7	# <CJK>
0x9E4B	0x5B2C	0x670F	# <CJK>
0x9E4C	0x5B2D	0x6716	# <CJK>
0x9E4D	0x5B2E	0x671E	# <CJK>
0x9E4E	0x5B2F	0x6726	# <CJK>
0x9E4F	0x5B30	0x6727	# <CJK>
0x9E50	0x5B31	0x9738	# <CJK>
0x9E51	0x5B32	0x672E	# <CJK>
0x9E52	0x5B33	0x673F	# <CJK>
0x9E53	0x5B34	0x6736	# <CJK>
0x9E54	0x5B35	0x6741	# <CJK>
0x9E55	0x5B36	0x6738	# <CJK>
0x9E56	0x5B37	0x6737	# <CJK>
0x9E57	0x5B38	0x6746	# <CJK>
0x9E58	0x5B39	0x675E	# <CJK>
0x9E59	0x5B3A	0x6760	# <CJK>
0x9E5A	0x5B3B	0x6759	# <CJK>
0x9E5B	0x5B3C	0x6763	# <CJK>
0x9E5C	0x5B3D	0x6764	# <CJK>
0x9E5D	0x5B3E	0x6789	# <CJK>
0x9E5E	0x5B3F	0x6770	# <CJK>
0x9E5F	0x5B40	0x67A9	# <CJK>
0x9E60	0x5B41	0x677C	# <CJK>
0x9E61	0x5B42	0x676A	# <CJK>
0x9E62	0x5B43	0x678C	# <CJK>
0x9E63	0x5B44	0x678B	# <CJK>
0x9E64	0x5B45	0x67A6	# <CJK>
0x9E65	0x5B46	0x67A1	# <CJK>
0x9E66	0x5B47	0x6785	# <CJK>
0x9E67	0x5B48	0x67B7	# <CJK>
0x9E68	0x5B49	0x67EF	# <CJK>
0x9E69	0x5B4A	0x67B4	# <CJK>
0x9E6A	0x5B4B	0x67EC	# <CJK>
0x9E6B	0x5B4C	0x67B3	# <CJK>
0x9E6C	0x5B4D	0x67E9	# <CJK>
0x9E6D	0x5B4E	0x67B8	# <CJK>
0x9E6E	0x5B4F	0x67E4	# <CJK>
0x9E6F	0x5B50	0x67DE	# <CJK>
0x9E70	0x5B51	0x67DD	# <CJK>
0x9E71	0x5B52	0x67E2	# <CJK>
0x9E72	0x5B53	0x67EE	# <CJK>
0x9E73	0x5B54	0x67B9	# <CJK>
0x9E74	0x5B55	0x67CE	# <CJK>
0x9E75	0x5B56	0x67C6	# <CJK>
0x9E76	0x5B57	0x67E7	# <CJK>
0x9E77	0x5B58	0x6A9C	# <CJK>
0x9E78	0x5B59	0x681E	# <CJK>
0x9E79	0x5B5A	0x6846	# <CJK>
0x9E7A	0x5B5B	0x6829	# <CJK>
0x9E7B	0x5B5C	0x6840	# <CJK>
0x9E7C	0x5B5D	0x684D	# <CJK>
0x9E7D	0x5B5E	0x6832	# <CJK>
0x9E7E	0x5B5F	0x684E	# <CJK>
0x9E80	0x5B60	0x68B3	# <CJK>
0x9E81	0x5B61	0x682B	# <CJK>
0x9E82	0x5B62	0x6859	# <CJK>
0x9E83	0x5B63	0x6863	# <CJK>
0x9E84	0x5B64	0x6877	# <CJK>
0x9E85	0x5B65	0x687F	# <CJK>
0x9E86	0x5B66	0x689F	# <CJK>
0x9E87	0x5B67	0x688F	# <CJK>
0x9E88	0x5B68	0x68AD	# <CJK>
0x9E89	0x5B69	0x6894	# <CJK>
0x9E8A	0x5B6A	0x689D	# <CJK>
0x9E8B	0x5B6B	0x689B	# <CJK>
0x9E8C	0x5B6C	0x6883	# <CJK>
0x9E8D	0x5B6D	0x6AAE	# <CJK>
0x9E8E	0x5B6E	0x68B9	# <CJK>
0x9E8F	0x5B6F	0x6874	# <CJK>
0x9E90	0x5B70	0x68B5	# <CJK>
0x9E91	0x5B71	0x68A0	# <CJK>
0x9E92	0x5B72	0x68BA	# <CJK>
0x9E93	0x5B73	0x690F	# <CJK>
0x9E94	0x5B74	0x688D	# <CJK>
0x9E95	0x5B75	0x687E	# <CJK>
0x9E96	0x5B76	0x6901	# <CJK>
0x9E97	0x5B77	0x68CA	# <CJK>
0x9E98	0x5B78	0x6908	# <CJK>
0x9E99	0x5B79	0x68D8	# <CJK>
0x9E9A	0x5B7A	0x6922	# <CJK>
0x9E9B	0x5B7B	0x6926	# <CJK>
0x9E9C	0x5B7C	0x68E1	# <CJK>
0x9E9D	0x5B7D	0x690C	# <CJK>
0x9E9E	0x5B7E	0x68CD	# <CJK>
0x9E9F	0x5C21	0x68D4	# <CJK>
0x9EA0	0x5C22	0x68E7	# <CJK>
0x9EA1	0x5C23	0x68D5	# <CJK>
0x9EA2	0x5C24	0x6936	# <CJK>
0x9EA3	0x5C25	0x6912	# <CJK>
0x9EA4	0x5C26	0x6904	# <CJK>
0x9EA5	0x5C27	0x68D7	# <CJK>
0x9EA6	0x5C28	0x68E3	# <CJK>
0x9EA7	0x5C29	0x6925	# <CJK>
0x9EA8	0x5C2A	0x68F9	# <CJK>
0x9EA9	0x5C2B	0x68E0	# <CJK>
0x9EAA	0x5C2C	0x68EF	# <CJK>
0x9EAB	0x5C2D	0x6928	# <CJK>
0x9EAC	0x5C2E	0x692A	# <CJK>
0x9EAD	0x5C2F	0x691A	# <CJK>
0x9EAE	0x5C30	0x6923	# <CJK>
0x9EAF	0x5C31	0x6921	# <CJK>
0x9EB0	0x5C32	0x68C6	# <CJK>
0x9EB1	0x5C33	0x6979	# <CJK>
0x9EB2	0x5C34	0x6977	# <CJK>
0x9EB3	0x5C35	0x695C	# <CJK>
0x9EB4	0x5C36	0x6978	# <CJK>
0x9EB5	0x5C37	0x696B	# <CJK>
0x9EB6	0x5C38	0x6954	# <CJK>
0x9EB7	0x5C39	0x697E	# <CJK>
0x9EB8	0x5C3A	0x696E	# <CJK>
0x9EB9	0x5C3B	0x6939	# <CJK>
0x9EBA	0x5C3C	0x6974	# <CJK>
0x9EBB	0x5C3D	0x693D	# <CJK>
0x9EBC	0x5C3E	0x6959	# <CJK>
0x9EBD	0x5C3F	0x6930	# <CJK>
0x9EBE	0x5C40	0x6961	# <CJK>
0x9EBF	0x5C41	0x695E	# <CJK>
0x9EC0	0x5C42	0x695D	# <CJK>
0x9EC1	0x5C43	0x6981	# <CJK>
0x9EC2	0x5C44	0x696A	# <CJK>
0x9EC3	0x5C45	0x69B2	# <CJK>
0x9EC4	0x5C46	0x69AE	# <CJK>
0x9EC5	0x5C47	0x69D0	# <CJK>
0x9EC6	0x5C48	0x69BF	# <CJK>
0x9EC7	0x5C49	0x69C1	# <CJK>
0x9EC8	0x5C4A	0x69D3	# <CJK>
0x9EC9	0x5C4B	0x69BE	# <CJK>
0x9ECA	0x5C4C	0x69CE	# <CJK>
0x9ECB	0x5C4D	0x5BE8	# <CJK>
0x9ECC	0x5C4E	0x69CA	# <CJK>
0x9ECD	0x5C4F	0x69DD	# <CJK>
0x9ECE	0x5C50	0x69BB	# <CJK>
0x9ECF	0x5C51	0x69C3	# <CJK>
0x9ED0	0x5C52	0x69A7	# <CJK>
0x9ED1	0x5C53	0x6A2E	# <CJK>
0x9ED2	0x5C54	0x6991	# <CJK>
0x9ED3	0x5C55	0x69A0	# <CJK>
0x9ED4	0x5C56	0x699C	# <CJK>
0x9ED5	0x5C57	0x6995	# <CJK>
0x9ED6	0x5C58	0x69B4	# <CJK>
0x9ED7	0x5C59	0x69DE	# <CJK>
0x9ED8	0x5C5A	0x69E8	# <CJK>
0x9ED9	0x5C5B	0x6A02	# <CJK>
0x9EDA	0x5C5C	0x6A1B	# <CJK>
0x9EDB	0x5C5D	0x69FF	# <CJK>
0x9EDC	0x5C5E	0x6B0A	# <CJK>
0x9EDD	0x5C5F	0x69F9	# <CJK>
0x9EDE	0x5C60	0x69F2	# <CJK>
0x9EDF	0x5C61	0x69E7	# <CJK>
0x9EE0	0x5C62	0x6A05	# <CJK>
0x9EE1	0x5C63	0x69B1	# <CJK>
0x9EE2	0x5C64	0x6A1E	# <CJK>
0x9EE3	0x5C65	0x69ED	# <CJK>
0x9EE4	0x5C66	0x6A14	# <CJK>
0x9EE5	0x5C67	0x69EB	# <CJK>
0x9EE6	0x5C68	0x6A0A	# <CJK>
0x9EE7	0x5C69	0x6A12	# <CJK>
0x9EE8	0x5C6A	0x6AC1	# <CJK>
0x9EE9	0x5C6B	0x6A23	# <CJK>
0x9EEA	0x5C6C	0x6A13	# <CJK>
0x9EEB	0x5C6D	0x6A44	# <CJK>
0x9EEC	0x5C6E	0x6A0C	# <CJK>
0x9EED	0x5C6F	0x6A72	# <CJK>
0x9EEE	0x5C70	0x6A36	# <CJK>
0x9EEF	0x5C71	0x6A78	# <CJK>
0x9EF0	0x5C72	0x6A47	# <CJK>
0x9EF1	0x5C73	0x6A62	# <CJK>
0x9EF2	0x5C74	0x6A59	# <CJK>
0x9EF3	0x5C75	0x6A66	# <CJK>
0x9EF4	0x5C76	0x6A48	# <CJK>
0x9EF5	0x5C77	0x6A38	# <CJK>
0x9EF6	0x5C78	0x6A22	# <CJK>
0x9EF7	0x5C79	0x6A90	# <CJK>
0x9EF8	0x5C7A	0x6A8D	# <CJK>
0x9EF9	0x5C7B	0x6AA0	# <CJK>
0x9EFA	0x5C7C	0x6A84	# <CJK>
0x9EFB	0x5C7D	0x6AA2	# <CJK>
0x9EFC	0x5C7E	0x6AA3	# <CJK>
0x9F40	0x5D21	0x6A97	# <CJK>
0x9F41	0x5D22	0x8617	# <CJK>
0x9F42	0x5D23	0x6ABB	# <CJK>
0x9F43	0x5D24	0x6AC3	# <CJK>
0x9F44	0x5D25	0x6AC2	# <CJK>
0x9F45	0x5D26	0x6AB8	# <CJK>
0x9F46	0x5D27	0x6AB3	# <CJK>
0x9F47	0x5D28	0x6AAC	# <CJK>
0x9F48	0x5D29	0x6ADE	# <CJK>
0x9F49	0x5D2A	0x6AD1	# <CJK>
0x9F4A	0x5D2B	0x6ADF	# <CJK>
0x9F4B	0x5D2C	0x6AAA	# <CJK>
0x9F4C	0x5D2D	0x6ADA	# <CJK>
0x9F4D	0x5D2E	0x6AEA	# <CJK>
0x9F4E	0x5D2F	0x6AFB	# <CJK>
0x9F4F	0x5D30	0x6B05	# <CJK>
0x9F50	0x5D31	0x8616	# <CJK>
0x9F51	0x5D32	0x6AFA	# <CJK>
0x9F52	0x5D33	0x6B12	# <CJK>
0x9F53	0x5D34	0x6B16	# <CJK>
0x9F54	0x5D35	0x9B31	# <CJK>
0x9F55	0x5D36	0x6B1F	# <CJK>
0x9F56	0x5D37	0x6B38	# <CJK>
0x9F57	0x5D38	0x6B37	# <CJK>
0x9F58	0x5D39	0x76DC	# <CJK>
0x9F59	0x5D3A	0x6B39	# <CJK>
0x9F5A	0x5D3B	0x98EE	# <CJK>
0x9F5B	0x5D3C	0x6B47	# <CJK>
0x9F5C	0x5D3D	0x6B43	# <CJK>
0x9F5D	0x5D3E	0x6B49	# <CJK>
0x9F5E	0x5D3F	0x6B50	# <CJK>
0x9F5F	0x5D40	0x6B59	# <CJK>
0x9F60	0x5D41	0x6B54	# <CJK>
0x9F61	0x5D42	0x6B5B	# <CJK>
0x9F62	0x5D43	0x6B5F	# <CJK>
0x9F63	0x5D44	0x6B61	# <CJK>
0x9F64	0x5D45	0x6B78	# <CJK>
0x9F65	0x5D46	0x6B79	# <CJK>
0x9F66	0x5D47	0x6B7F	# <CJK>
0x9F67	0x5D48	0x6B80	# <CJK>
0x9F68	0x5D49	0x6B84	# <CJK>
0x9F69	0x5D4A	0x6B83	# <CJK>
0x9F6A	0x5D4B	0x6B8D	# <CJK>
0x9F6B	0x5D4C	0x6B98	# <CJK>
0x9F6C	0x5D4D	0x6B95	# <CJK>
0x9F6D	0x5D4E	0x6B9E	# <CJK>
0x9F6E	0x5D4F	0x6BA4	# <CJK>
0x9F6F	0x5D50	0x6BAA	# <CJK>
0x9F70	0x5D51	0x6BAB	# <CJK>
0x9F71	0x5D52	0x6BAF	# <CJK>
0x9F72	0x5D53	0x6BB2	# <CJK>
0x9F73	0x5D54	0x6BB1	# <CJK>
0x9F74	0x5D55	0x6BB3	# <CJK>
0x9F75	0x5D56	0x6BB7	# <CJK>
0x9F76	0x5D57	0x6BBC	# <CJK>
0x9F77	0x5D58	0x6BC6	# <CJK>
0x9F78	0x5D59	0x6BCB	# <CJK>
0x9F79	0x5D5A	0x6BD3	# <CJK>
0x9F7A	0x5D5B	0x6BDF	# <CJK>
0x9F7B	0x5D5C	0x6BEC	# <CJK>
0x9F7C	0x5D5D	0x6BEB	# <CJK>
0x9F7D	0x5D5E	0x6BF3	# <CJK>
0x9F7E	0x5D5F	0x6BEF	# <CJK>
0x9F80	0x5D60	0x9EBE	# <CJK>
0x9F81	0x5D61	0x6C08	# <CJK>
0x9F82	0x5D62	0x6C13	# <CJK>
0x9F83	0x5D63	0x6C14	# <CJK>
0x9F84	0x5D64	0x6C1B	# <CJK>
0x9F85	0x5D65	0x6C24	# <CJK>
0x9F86	0x5D66	0x6C23	# <CJK>
0x9F87	0x5D67	0x6C5E	# <CJK>
0x9F88	0x5D68	0x6C55	# <CJK>
0x9F89	0x5D69	0x6C62	# <CJK>
0x9F8A	0x5D6A	0x6C6A	# <CJK>
0x9F8B	0x5D6B	0x6C82	# <CJK>
0x9F8C	0x5D6C	0x6C8D	# <CJK>
0x9F8D	0x5D6D	0x6C9A	# <CJK>
0x9F8E	0x5D6E	0x6C81	# <CJK>
0x9F8F	0x5D6F	0x6C9B	# <CJK>
0x9F90	0x5D70	0x6C7E	# <CJK>
0x9F91	0x5D71	0x6C68	# <CJK>
0x9F92	0x5D72	0x6C73	# <CJK>
0x9F93	0x5D73	0x6C92	# <CJK>
0x9F94	0x5D74	0x6C90	# <CJK>
0x9F95	0x5D75	0x6CC4	# <CJK>
0x9F96	0x5D76	0x6CF1	# <CJK>
0x9F97	0x5D77	0x6CD3	# <CJK>
0x9F98	0x5D78	0x6CBD	# <CJK>
0x9F99	0x5D79	0x6CD7	# <CJK>
0x9F9A	0x5D7A	0x6CC5	# <CJK>
0x9F9B	0x5D7B	0x6CDD	# <CJK>
0x9F9C	0x5D7C	0x6CAE	# <CJK>
0x9F9D	0x5D7D	0x6CB1	# <CJK>
0x9F9E	0x5D7E	0x6CBE	# <CJK>
0x9F9F	0x5E21	0x6CBA	# <CJK>
0x9FA0	0x5E22	0x6CDB	# <CJK>
0x9FA1	0x5E23	0x6CEF	# <CJK>
0x9FA2	0x5E24	0x6CD9	# <CJK>
0x9FA3	0x5E25	0x6CEA	# <CJK>
0x9FA4	0x5E26	0x6D1F	# <CJK>
0x9FA5	0x5E27	0x884D	# <CJK>
0x9FA6	0x5E28	0x6D36	# <CJK>
0x9FA7	0x5E29	0x6D2B	# <CJK>
0x9FA8	0x5E2A	0x6D3D	# <CJK>
0x9FA9	0x5E2B	0x6D38	# <CJK>
0x9FAA	0x5E2C	0x6D19	# <CJK>
0x9FAB	0x5E2D	0x6D35	# <CJK>
0x9FAC	0x5E2E	0x6D33	# <CJK>
0x9FAD	0x5E2F	0x6D12	# <CJK>
0x9FAE	0x5E30	0x6D0C	# <CJK>
0x9FAF	0x5E31	0x6D63	# <CJK>
0x9FB0	0x5E32	0x6D93	# <CJK>
0x9FB1	0x5E33	0x6D64	# <CJK>
0x9FB2	0x5E34	0x6D5A	# <CJK>
0x9FB3	0x5E35	0x6D79	# <CJK>
0x9FB4	0x5E36	0x6D59	# <CJK>
0x9FB5	0x5E37	0x6D8E	# <CJK>
0x9FB6	0x5E38	0x6D95	# <CJK>
0x9FB7	0x5E39	0x6FE4	# <CJK>
0x9FB8	0x5E3A	0x6D85	# <CJK>
0x9FB9	0x5E3B	0x6DF9	# <CJK>
0x9FBA	0x5E3C	0x6E15	# <CJK>
0x9FBB	0x5E3D	0x6E0A	# <CJK>
0x9FBC	0x5E3E	0x6DB5	# <CJK>
0x9FBD	0x5E3F	0x6DC7	# <CJK>
0x9FBE	0x5E40	0x6DE6	# <CJK>
0x9FBF	0x5E41	0x6DB8	# <CJK>
0x9FC0	0x5E42	0x6DC6	# <CJK>
0x9FC1	0x5E43	0x6DEC	# <CJK>
0x9FC2	0x5E44	0x6DDE	# <CJK>
0x9FC3	0x5E45	0x6DCC	# <CJK>
0x9FC4	0x5E46	0x6DE8	# <CJK>
0x9FC5	0x5E47	0x6DD2	# <CJK>
0x9FC6	0x5E48	0x6DC5	# <CJK>
0x9FC7	0x5E49	0x6DFA	# <CJK>
0x9FC8	0x5E4A	0x6DD9	# <CJK>
0x9FC9	0x5E4B	0x6DE4	# <CJK>
0x9FCA	0x5E4C	0x6DD5	# <CJK>
0x9FCB	0x5E4D	0x6DEA	# <CJK>
0x9FCC	0x5E4E	0x6DEE	# <CJK>
0x9FCD	0x5E4F	0x6E2D	# <CJK>
0x9FCE	0x5E50	0x6E6E	# <CJK>
0x9FCF	0x5E51	0x6E2E	# <CJK>
0x9FD0	0x5E52	0x6E19	# <CJK>
0x9FD1	0x5E53	0x6E72	# <CJK>
0x9FD2	0x5E54	0x6E5F	# <CJK>
0x9FD3	0x5E55	0x6E3E	# <CJK>
0x9FD4	0x5E56	0x6E23	# <CJK>
0x9FD5	0x5E57	0x6E6B	# <CJK>
0x9FD6	0x5E58	0x6E2B	# <CJK>
0x9FD7	0x5E59	0x6E76	# <CJK>
0x9FD8	0x5E5A	0x6E4D	# <CJK>
0x9FD9	0x5E5B	0x6E1F	# <CJK>
0x9FDA	0x5E5C	0x6E43	# <CJK>
0x9FDB	0x5E5D	0x6E3A	# <CJK>
0x9FDC	0x5E5E	0x6E4E	# <CJK>
0x9FDD	0x5E5F	0x6E24	# <CJK>
0x9FDE	0x5E60	0x6EFF	# <CJK>
0x9FDF	0x5E61	0x6E1D	# <CJK>
0x9FE0	0x5E62	0x6E38	# <CJK>
0x9FE1	0x5E63	0x6E82	# <CJK>
0x9FE2	0x5E64	0x6EAA	# <CJK>
0x9FE3	0x5E65	0x6E98	# <CJK>
0x9FE4	0x5E66	0x6EC9	# <CJK>
0x9FE5	0x5E67	0x6EB7	# <CJK>
0x9FE6	0x5E68	0x6ED3	# <CJK>
0x9FE7	0x5E69	0x6EBD	# <CJK>
0x9FE8	0x5E6A	0x6EAF	# <CJK>
0x9FE9	0x5E6B	0x6EC4	# <CJK>
0x9FEA	0x5E6C	0x6EB2	# <CJK>
0x9FEB	0x5E6D	0x6ED4	# <CJK>
0x9FEC	0x5E6E	0x6ED5	# <CJK>
0x9FED	0x5E6F	0x6E8F	# <CJK>
0x9FEE	0x5E70	0x6EA5	# <CJK>
0x9FEF	0x5E71	0x6EC2	# <CJK>
0x9FF0	0x5E72	0x6E9F	# <CJK>
0x9FF1	0x5E73	0x6F41	# <CJK>
0x9FF2	0x5E74	0x6F11	# <CJK>
0x9FF3	0x5E75	0x704C	# <CJK>
0x9FF4	0x5E76	0x6EEC	# <CJK>
0x9FF5	0x5E77	0x6EF8	# <CJK>
0x9FF6	0x5E78	0x6EFE	# <CJK>
0x9FF7	0x5E79	0x6F3F	# <CJK>
0x9FF8	0x5E7A	0x6EF2	# <CJK>
0x9FF9	0x5E7B	0x6F31	# <CJK>
0x9FFA	0x5E7C	0x6EEF	# <CJK>
0x9FFB	0x5E7D	0x6F32	# <CJK>
0x9FFC	0x5E7E	0x6ECC	# <CJK>
0xE040	0x5F21	0x6F3E	# <CJK>
0xE041	0x5F22	0x6F13	# <CJK>
0xE042	0x5F23	0x6EF7	# <CJK>
0xE043	0x5F24	0x6F86	# <CJK>
0xE044	0x5F25	0x6F7A	# <CJK>
0xE045	0x5F26	0x6F78	# <CJK>
0xE046	0x5F27	0x6F81	# <CJK>
0xE047	0x5F28	0x6F80	# <CJK>
0xE048	0x5F29	0x6F6F	# <CJK>
0xE049	0x5F2A	0x6F5B	# <CJK>
0xE04A	0x5F2B	0x6FF3	# <CJK>
0xE04B	0x5F2C	0x6F6D	# <CJK>
0xE04C	0x5F2D	0x6F82	# <CJK>
0xE04D	0x5F2E	0x6F7C	# <CJK>
0xE04E	0x5F2F	0x6F58	# <CJK>
0xE04F	0x5F30	0x6F8E	# <CJK>
0xE050	0x5F31	0x6F91	# <CJK>
0xE051	0x5F32	0x6FC2	# <CJK>
0xE052	0x5F33	0x6F66	# <CJK>
0xE053	0x5F34	0x6FB3	# <CJK>
0xE054	0x5F35	0x6FA3	# <CJK>
0xE055	0x5F36	0x6FA1	# <CJK>
0xE056	0x5F37	0x6FA4	# <CJK>
0xE057	0x5F38	0x6FB9	# <CJK>
0xE058	0x5F39	0x6FC6	# <CJK>
0xE059	0x5F3A	0x6FAA	# <CJK>
0xE05A	0x5F3B	0x6FDF	# <CJK>
0xE05B	0x5F3C	0x6FD5	# <CJK>
0xE05C	0x5F3D	0x6FEC	# <CJK>
0xE05D	0x5F3E	0x6FD4	# <CJK>
0xE05E	0x5F3F	0x6FD8	# <CJK>
0xE05F	0x5F40	0x6FF1	# <CJK>
0xE060	0x5F41	0x6FEE	# <CJK>
0xE061	0x5F42	0x6FDB	# <CJK>
0xE062	0x5F43	0x7009	# <CJK>
0xE063	0x5F44	0x700B	# <CJK>
0xE064	0x5F45	0x6FFA	# <CJK>
0xE065	0x5F46	0x7011	# <CJK>
0xE066	0x5F47	0x7001	# <CJK>
0xE067	0x5F48	0x700F	# <CJK>
0xE068	0x5F49	0x6FFE	# <CJK>
0xE069	0x5F4A	0x701B	# <CJK>
0xE06A	0x5F4B	0x701A	# <CJK>
0xE06B	0x5F4C	0x6F74	# <CJK>
0xE06C	0x5F4D	0x701D	# <CJK>
0xE06D	0x5F4E	0x7018	# <CJK>
0xE06E	0x5F4F	0x701F	# <CJK>
0xE06F	0x5F50	0x7030	# <CJK>
0xE070	0x5F51	0x703E	# <CJK>
0xE071	0x5F52	0x7032	# <CJK>
0xE072	0x5F53	0x7051	# <CJK>
0xE073	0x5F54	0x7063	# <CJK>
0xE074	0x5F55	0x7099	# <CJK>
0xE075	0x5F56	0x7092	# <CJK>
0xE076	0x5F57	0x70AF	# <CJK>
0xE077	0x5F58	0x70F1	# <CJK>
0xE078	0x5F59	0x70AC	# <CJK>
0xE079	0x5F5A	0x70B8	# <CJK>
0xE07A	0x5F5B	0x70B3	# <CJK>
0xE07B	0x5F5C	0x70AE	# <CJK>
0xE07C	0x5F5D	0x70DF	# <CJK>
0xE07D	0x5F5E	0x70CB	# <CJK>
0xE07E	0x5F5F	0x70DD	# <CJK>
0xE080	0x5F60	0x70D9	# <CJK>
0xE081	0x5F61	0x7109	# <CJK>
0xE082	0x5F62	0x70FD	# <CJK>
0xE083	0x5F63	0x711C	# <CJK>
0xE084	0x5F64	0x7119	# <CJK>
0xE085	0x5F65	0x7165	# <CJK>
0xE086	0x5F66	0x7155	# <CJK>
0xE087	0x5F67	0x7188	# <CJK>
0xE088	0x5F68	0x7166	# <CJK>
0xE089	0x5F69	0x7162	# <CJK>
0xE08A	0x5F6A	0x714C	# <CJK>
0xE08B	0x5F6B	0x7156	# <CJK>
0xE08C	0x5F6C	0x716C	# <CJK>
0xE08D	0x5F6D	0x718F	# <CJK>
0xE08E	0x5F6E	0x71FB	# <CJK>
0xE08F	0x5F6F	0x7184	# <CJK>
0xE090	0x5F70	0x7195	# <CJK>
0xE091	0x5F71	0x71A8	# <CJK>
0xE092	0x5F72	0x71AC	# <CJK>
0xE093	0x5F73	0x71D7	# <CJK>
0xE094	0x5F74	0x71B9	# <CJK>
0xE095	0x5F75	0x71BE	# <CJK>
0xE096	0x5F76	0x71D2	# <CJK>
0xE097	0x5F77	0x71C9	# <CJK>
0xE098	0x5F78	0x71D4	# <CJK>
0xE099	0x5F79	0x71CE	# <CJK>
0xE09A	0x5F7A	0x71E0	# <CJK>
0xE09B	0x5F7B	0x71EC	# <CJK>
0xE09C	0x5F7C	0x71E7	# <CJK>
0xE09D	0x5F7D	0x71F5	# <CJK>
0xE09E	0x5F7E	0x71FC	# <CJK>
0xE09F	0x6021	0x71F9	# <CJK>
0xE0A0	0x6022	0x71FF	# <CJK>
0xE0A1	0x6023	0x720D	# <CJK>
0xE0A2	0x6024	0x7210	# <CJK>
0xE0A3	0x6025	0x721B	# <CJK>
0xE0A4	0x6026	0x7228	# <CJK>
0xE0A5	0x6027	0x722D	# <CJK>
0xE0A6	0x6028	0x722C	# <CJK>
0xE0A7	0x6029	0x7230	# <CJK>
0xE0A8	0x602A	0x7232	# <CJK>
0xE0A9	0x602B	0x723B	# <CJK>
0xE0AA	0x602C	0x723C	# <CJK>
0xE0AB	0x602D	0x723F	# <CJK>
0xE0AC	0x602E	0x7240	# <CJK>
0xE0AD	0x602F	0x7246	# <CJK>
0xE0AE	0x6030	0x724B	# <CJK>
0xE0AF	0x6031	0x7258	# <CJK>
0xE0B0	0x6032	0x7274	# <CJK>
0xE0B1	0x6033	0x727E	# <CJK>
0xE0B2	0x6034	0x7282	# <CJK>
0xE0B3	0x6035	0x7281	# <CJK>
0xE0B4	0x6036	0x7287	# <CJK>
0xE0B5	0x6037	0x7292	# <CJK>
0xE0B6	0x6038	0x7296	# <CJK>
0xE0B7	0x6039	0x72A2	# <CJK>
0xE0B8	0x603A	0x72A7	# <CJK>
0xE0B9	0x603B	0x72B9	# <CJK>
0xE0BA	0x603C	0x72B2	# <CJK>
0xE0BB	0x603D	0x72C3	# <CJK>
0xE0BC	0x603E	0x72C6	# <CJK>
0xE0BD	0x603F	0x72C4	# <CJK>
0xE0BE	0x6040	0x72CE	# <CJK>
0xE0BF	0x6041	0x72D2	# <CJK>
0xE0C0	0x6042	0x72E2	# <CJK>
0xE0C1	0x6043	0x72E0	# <CJK>
0xE0C2	0x6044	0x72E1	# <CJK>
0xE0C3	0x6045	0x72F9	# <CJK>
0xE0C4	0x6046	0x72F7	# <CJK>
0xE0C5	0x6047	0x500F	# <CJK>
0xE0C6	0x6048	0x7317	# <CJK>
0xE0C7	0x6049	0x730A	# <CJK>
0xE0C8	0x604A	0x731C	# <CJK>
0xE0C9	0x604B	0x7316	# <CJK>
0xE0CA	0x604C	0x731D	# <CJK>
0xE0CB	0x604D	0x7334	# <CJK>
0xE0CC	0x604E	0x732F	# <CJK>
0xE0CD	0x604F	0x7329	# <CJK>
0xE0CE	0x6050	0x7325	# <CJK>
0xE0CF	0x6051	0x733E	# <CJK>
0xE0D0	0x6052	0x734E	# <CJK>
0xE0D1	0x6053	0x734F	# <CJK>
0xE0D2	0x6054	0x9ED8	# <CJK>
0xE0D3	0x6055	0x7357	# <CJK>
0xE0D4	0x6056	0x736A	# <CJK>
0xE0D5	0x6057	0x7368	# <CJK>
0xE0D6	0x6058	0x7370	# <CJK>
0xE0D7	0x6059	0x7378	# <CJK>
0xE0D8	0x605A	0x7375	# <CJK>
0xE0D9	0x605B	0x737B	# <CJK>
0xE0DA	0x605C	0x737A	# <CJK>
0xE0DB	0x605D	0x73C8	# <CJK>
0xE0DC	0x605E	0x73B3	# <CJK>
0xE0DD	0x605F	0x73CE	# <CJK>
0xE0DE	0x6060	0x73BB	# <CJK>
0xE0DF	0x6061	0x73C0	# <CJK>
0xE0E0	0x6062	0x73E5	# <CJK>
0xE0E1	0x6063	0x73EE	# <CJK>
0xE0E2	0x6064	0x73DE	# <CJK>
0xE0E3	0x6065	0x74A2	# <CJK>
0xE0E4	0x6066	0x7405	# <CJK>
0xE0E5	0x6067	0x746F	# <CJK>
0xE0E6	0x6068	0x7425	# <CJK>
0xE0E7	0x6069	0x73F8	# <CJK>
0xE0E8	0x606A	0x7432	# <CJK>
0xE0E9	0x606B	0x743A	# <CJK>
0xE0EA	0x606C	0x7455	# <CJK>
0xE0EB	0x606D	0x743F	# <CJK>
0xE0EC	0x606E	0x745F	# <CJK>
0xE0ED	0x606F	0x7459	# <CJK>
0xE0EE	0x6070	0x7441	# <CJK>
0xE0EF	0x6071	0x745C	# <CJK>
0xE0F0	0x6072	0x7469	# <CJK>
0xE0F1	0x6073	0x7470	# <CJK>
0xE0F2	0x6074	0x7463	# <CJK>
0xE0F3	0x6075	0x746A	# <CJK>
0xE0F4	0x6076	0x7476	# <CJK>
0xE0F5	0x6077	0x747E	# <CJK>
0xE0F6	0x6078	0x748B	# <CJK>
0xE0F7	0x6079	0x749E	# <CJK>
0xE0F8	0x607A	0x74A7	# <CJK>
0xE0F9	0x607B	0x74CA	# <CJK>
0xE0FA	0x607C	0x74CF	# <CJK>
0xE0FB	0x607D	0x74D4	# <CJK>
0xE0FC	0x607E	0x73F1	# <CJK>
0xE140	0x6121	0x74E0	# <CJK>
0xE141	0x6122	0x74E3	# <CJK>
0xE142	0x6123	0x74E7	# <CJK>
0xE143	0x6124	0x74E9	# <CJK>
0xE144	0x6125	0x74EE	# <CJK>
0xE145	0x6126	0x74F2	# <CJK>
0xE146	0x6127	0x74F0	# <CJK>
0xE147	0x6128	0x74F1	# <CJK>
0xE148	0x6129	0x74F8	# <CJK>
0xE149	0x612A	0x74F7	# <CJK>
0xE14A	0x612B	0x7504	# <CJK>
0xE14B	0x612C	0x7503	# <CJK>
0xE14C	0x612D	0x7505	# <CJK>
0xE14D	0x612E	0x750C	# <CJK>
0xE14E	0x612F	0x750E	# <CJK>
0xE14F	0x6130	0x750D	# <CJK>
0xE150	0x6131	0x7515	# <CJK>
0xE151	0x6132	0x7513	# <CJK>
0xE152	0x6133	0x751E	# <CJK>
0xE153	0x6134	0x7526	# <CJK>
0xE154	0x6135	0x752C	# <CJK>
0xE155	0x6136	0x753C	# <CJK>
0xE156	0x6137	0x7544	# <CJK>
0xE157	0x6138	0x754D	# <CJK>
0xE158	0x6139	0x754A	# <CJK>
0xE159	0x613A	0x7549	# <CJK>
0xE15A	0x613B	0x755B	# <CJK>
0xE15B	0x613C	0x7546	# <CJK>
0xE15C	0x613D	0x755A	# <CJK>
0xE15D	0x613E	0x7569	# <CJK>
0xE15E	0x613F	0x7564	# <CJK>
0xE15F	0x6140	0x7567	# <CJK>
0xE160	0x6141	0x756B	# <CJK>
0xE161	0x6142	0x756D	# <CJK>
0xE162	0x6143	0x7578	# <CJK>
0xE163	0x6144	0x7576	# <CJK>
0xE164	0x6145	0x7586	# <CJK>
0xE165	0x6146	0x7587	# <CJK>
0xE166	0x6147	0x7574	# <CJK>
0xE167	0x6148	0x758A	# <CJK>
0xE168	0x6149	0x7589	# <CJK>
0xE169	0x614A	0x7582	# <CJK>
0xE16A	0x614B	0x7594	# <CJK>
0xE16B	0x614C	0x759A	# <CJK>
0xE16C	0x614D	0x759D	# <CJK>
0xE16D	0x614E	0x75A5	# <CJK>
0xE16E	0x614F	0x75A3	# <CJK>
0xE16F	0x6150	0x75C2	# <CJK>
0xE170	0x6151	0x75B3	# <CJK>
0xE171	0x6152	0x75C3	# <CJK>
0xE172	0x6153	0x75B5	# <CJK>
0xE173	0x6154	0x75BD	# <CJK>
0xE174	0x6155	0x75B8	# <CJK>
0xE175	0x6156	0x75BC	# <CJK>
0xE176	0x6157	0x75B1	# <CJK>
0xE177	0x6158	0x75CD	# <CJK>
0xE178	0x6159	0x75CA	# <CJK>
0xE179	0x615A	0x75D2	# <CJK>
0xE17A	0x615B	0x75D9	# <CJK>
0xE17B	0x615C	0x75E3	# <CJK>
0xE17C	0x615D	0x75DE	# <CJK>
0xE17D	0x615E	0x75FE	# <CJK>
0xE17E	0x615F	0x75FF	# <CJK>
0xE180	0x6160	0x75FC	# <CJK>
0xE181	0x6161	0x7601	# <CJK>
0xE182	0x6162	0x75F0	# <CJK>
0xE183	0x6163	0x75FA	# <CJK>
0xE184	0x6164	0x75F2	# <CJK>
0xE185	0x6165	0x75F3	# <CJK>
0xE186	0x6166	0x760B	# <CJK>
0xE187	0x6167	0x760D	# <CJK>
0xE188	0x6168	0x7609	# <CJK>
0xE189	0x6169	0x761F	# <CJK>
0xE18A	0x616A	0x7627	# <CJK>
0xE18B	0x616B	0x7620	# <CJK>
0xE18C	0x616C	0x7621	# <CJK>
0xE18D	0x616D	0x7622	# <CJK>
0xE18E	0x616E	0x7624	# <CJK>
0xE18F	0x616F	0x7634	# <CJK>
0xE190	0x6170	0x7630	# <CJK>
0xE191	0x6171	0x763B	# <CJK>
0xE192	0x6172	0x7647	# <CJK>
0xE193	0x6173	0x7648	# <CJK>
0xE194	0x6174	0x7646	# <CJK>
0xE195	0x6175	0x765C	# <CJK>
0xE196	0x6176	0x7658	# <CJK>
0xE197	0x6177	0x7661	# <CJK>
0xE198	0x6178	0x7662	# <CJK>
0xE199	0x6179	0x7668	# <CJK>
0xE19A	0x617A	0x7669	# <CJK>
0xE19B	0x617B	0x766A	# <CJK>
0xE19C	0x617C	0x7667	# <CJK>
0xE19D	0x617D	0x766C	# <CJK>
0xE19E	0x617E	0x7670	# <CJK>
0xE19F	0x6221	0x7672	# <CJK>
0xE1A0	0x6222	0x7676	# <CJK>
0xE1A1	0x6223	0x7678	# <CJK>
0xE1A2	0x6224	0x767C	# <CJK>
0xE1A3	0x6225	0x7680	# <CJK>
0xE1A4	0x6226	0x7683	# <CJK>
0xE1A5	0x6227	0x7688	# <CJK>
0xE1A6	0x6228	0x768B	# <CJK>
0xE1A7	0x6229	0x768E	# <CJK>
0xE1A8	0x622A	0x7696	# <CJK>
0xE1A9	0x622B	0x7693	# <CJK>
0xE1AA	0x622C	0x7699	# <CJK>
0xE1AB	0x622D	0x769A	# <CJK>
0xE1AC	0x622E	0x76B0	# <CJK>
0xE1AD	0x622F	0x76B4	# <CJK>
0xE1AE	0x6230	0x76B8	# <CJK>
0xE1AF	0x6231	0x76B9	# <CJK>
0xE1B0	0x6232	0x76BA	# <CJK>
0xE1B1	0x6233	0x76C2	# <CJK>
0xE1B2	0x6234	0x76CD	# <CJK>
0xE1B3	0x6235	0x76D6	# <CJK>
0xE1B4	0x6236	0x76D2	# <CJK>
0xE1B5	0x6237	0x76DE	# <CJK>
0xE1B6	0x6238	0x76E1	# <CJK>
0xE1B7	0x6239	0x76E5	# <CJK>
0xE1B8	0x623A	0x76E7	# <CJK>
0xE1B9	0x623B	0x76EA	# <CJK>
0xE1BA	0x623C	0x862F	# <CJK>
0xE1BB	0x623D	0x76FB	# <CJK>
0xE1BC	0x623E	0x7708	# <CJK>
0xE1BD	0x623F	0x7707	# <CJK>
0xE1BE	0x6240	0x7704	# <CJK>
0xE1BF	0x6241	0x7729	# <CJK>
0xE1C0	0x6242	0x7724	# <CJK>
0xE1C1	0x6243	0x771E	# <CJK>
0xE1C2	0x6244	0x7725	# <CJK>
0xE1C3	0x6245	0x7726	# <CJK>
0xE1C4	0x6246	0x771B	# <CJK>
0xE1C5	0x6247	0x7737	# <CJK>
0xE1C6	0x6248	0x7738	# <CJK>
0xE1C7	0x6249	0x7747	# <CJK>
0xE1C8	0x624A	0x775A	# <CJK>
0xE1C9	0x624B	0x7768	# <CJK>
0xE1CA	0x624C	0x776B	# <CJK>
0xE1CB	0x624D	0x775B	# <CJK>
0xE1CC	0x624E	0x7765	# <CJK>
0xE1CD	0x624F	0x777F	# <CJK>
0xE1CE	0x6250	0x777E	# <CJK>
0xE1CF	0x6251	0x7779	# <CJK>
0xE1D0	0x6252	0x778E	# <CJK>
0xE1D1	0x6253	0x778B	# <CJK>
0xE1D2	0x6254	0x7791	# <CJK>
0xE1D3	0x6255	0x77A0	# <CJK>
0xE1D4	0x6256	0x779E	# <CJK>
0xE1D5	0x6257	0x77B0	# <CJK>
0xE1D6	0x6258	0x77B6	# <CJK>
0xE1D7	0x6259	0x77B9	# <CJK>
0xE1D8	0x625A	0x77BF	# <CJK>
0xE1D9	0x625B	0x77BC	# <CJK>
0xE1DA	0x625C	0x77BD	# <CJK>
0xE1DB	0x625D	0x77BB	# <CJK>
0xE1DC	0x625E	0x77C7	# <CJK>
0xE1DD	0x625F	0x77CD	# <CJK>
0xE1DE	0x6260	0x77D7	# <CJK>
0xE1DF	0x6261	0x77DA	# <CJK>
0xE1E0	0x6262	0x77DC	# <CJK>
0xE1E1	0x6263	0x77E3	# <CJK>
0xE1E2	0x6264	0x77EE	# <CJK>
0xE1E3	0x6265	0x77FC	# <CJK>
0xE1E4	0x6266	0x780C	# <CJK>
0xE1E5	0x6267	0x7812	# <CJK>
0xE1E6	0x6268	0x7926	# <CJK>
0xE1E7	0x6269	0x7820	# <CJK>
0xE1E8	0x626A	0x792A	# <CJK>
0xE1E9	0x626B	0x7845	# <CJK>
0xE1EA	0x626C	0x788E	# <CJK>
0xE1EB	0x626D	0x7874	# <CJK>
0xE1EC	0x626E	0x7886	# <CJK>
0xE1ED	0x626F	0x787C	# <CJK>
0xE1EE	0x6270	0x789A	# <CJK>
0xE1EF	0x6271	0x788C	# <CJK>
0xE1F0	0x6272	0x78A3	# <CJK>
0xE1F1	0x6273	0x78B5	# <CJK>
0xE1F2	0x6274	0x78AA	# <CJK>
0xE1F3	0x6275	0x78AF	# <CJK>
0xE1F4	0x6276	0x78D1	# <CJK>
0xE1F5	0x6277	0x78C6	# <CJK>
0xE1F6	0x6278	0x78CB	# <CJK>
0xE1F7	0x6279	0x78D4	# <CJK>
0xE1F8	0x627A	0x78BE	# <CJK>
0xE1F9	0x627B	0x78BC	# <CJK>
0xE1FA	0x627C	0x78C5	# <CJK>
0xE1FB	0x627D	0x78CA	# <CJK>
0xE1FC	0x627E	0x78EC	# <CJK>
0xE240	0x6321	0x78E7	# <CJK>
0xE241	0x6322	0x78DA	# <CJK>
0xE242	0x6323	0x78FD	# <CJK>
0xE243	0x6324	0x78F4	# <CJK>
0xE244	0x6325	0x7907	# <CJK>
0xE245	0x6326	0x7912	# <CJK>
0xE246	0x6327	0x7911	# <CJK>
0xE247	0x6328	0x7919	# <CJK>
0xE248	0x6329	0x792C	# <CJK>
0xE249	0x632A	0x792B	# <CJK>
0xE24A	0x632B	0x7940	# <CJK>
0xE24B	0x632C	0x7960	# <CJK>
0xE24C	0x632D	0x7957	# <CJK>
0xE24D	0x632E	0x795F	# <CJK>
0xE24E	0x632F	0x795A	# <CJK>
0xE24F	0x6330	0x7955	# <CJK>
0xE250	0x6331	0x7953	# <CJK>
0xE251	0x6332	0x797A	# <CJK>
0xE252	0x6333	0x797F	# <CJK>
0xE253	0x6334	0x798A	# <CJK>
0xE254	0x6335	0x799D	# <CJK>
0xE255	0x6336	0x79A7	# <CJK>
0xE256	0x6337	0x9F4B	# <CJK>
0xE257	0x6338	0x79AA	# <CJK>
0xE258	0x6339	0x79AE	# <CJK>
0xE259	0x633A	0x79B3	# <CJK>
0xE25A	0x633B	0x79B9	# <CJK>
0xE25B	0x633C	0x79BA	# <CJK>
0xE25C	0x633D	0x79C9	# <CJK>
0xE25D	0x633E	0x79D5	# <CJK>
0xE25E	0x633F	0x79E7	# <CJK>
0xE25F	0x6340	0x79EC	# <CJK>
0xE260	0x6341	0x79E1	# <CJK>
0xE261	0x6342	0x79E3	# <CJK>
0xE262	0x6343	0x7A08	# <CJK>
0xE263	0x6344	0x7A0D	# <CJK>
0xE264	0x6345	0x7A18	# <CJK>
0xE265	0x6346	0x7A19	# <CJK>
0xE266	0x6347	0x7A20	# <CJK>
0xE267	0x6348	0x7A1F	# <CJK>
0xE268	0x6349	0x7980	# <CJK>
0xE269	0x634A	0x7A31	# <CJK>
0xE26A	0x634B	0x7A3B	# <CJK>
0xE26B	0x634C	0x7A3E	# <CJK>
0xE26C	0x634D	0x7A37	# <CJK>
0xE26D	0x634E	0x7A43	# <CJK>
0xE26E	0x634F	0x7A57	# <CJK>
0xE26F	0x6350	0x7A49	# <CJK>
0xE270	0x6351	0x7A61	# <CJK>
0xE271	0x6352	0x7A62	# <CJK>
0xE272	0x6353	0x7A69	# <CJK>
0xE273	0x6354	0x9F9D	# <CJK>
0xE274	0x6355	0x7A70	# <CJK>
0xE275	0x6356	0x7A79	# <CJK>
0xE276	0x6357	0x7A7D	# <CJK>
0xE277	0x6358	0x7A88	# <CJK>
0xE278	0x6359	0x7A97	# <CJK>
0xE279	0x635A	0x7A95	# <CJK>
0xE27A	0x635B	0x7A98	# <CJK>
0xE27B	0x635C	0x7A96	# <CJK>
0xE27C	0x635D	0x7AA9	# <CJK>
0xE27D	0x635E	0x7AC8	# <CJK>
0xE27E	0x635F	0x7AB0	# <CJK>
0xE280	0x6360	0x7AB6	# <CJK>
0xE281	0x6361	0x7AC5	# <CJK>
0xE282	0x6362	0x7AC4	# <CJK>
0xE283	0x6363	0x7ABF	# <CJK>
0xE284	0x6364	0x9083	# <CJK>
0xE285	0x6365	0x7AC7	# <CJK>
0xE286	0x6366	0x7ACA	# <CJK>
0xE287	0x6367	0x7ACD	# <CJK>
0xE288	0x6368	0x7ACF	# <CJK>
0xE289	0x6369	0x7AD5	# <CJK>
0xE28A	0x636A	0x7AD3	# <CJK>
0xE28B	0x636B	0x7AD9	# <CJK>
0xE28C	0x636C	0x7ADA	# <CJK>
0xE28D	0x636D	0x7ADD	# <CJK>
0xE28E	0x636E	0x7AE1	# <CJK>
0xE28F	0x636F	0x7AE2	# <CJK>
0xE290	0x6370	0x7AE6	# <CJK>
0xE291	0x6371	0x7AED	# <CJK>
0xE292	0x6372	0x7AF0	# <CJK>
0xE293	0x6373	0x7B02	# <CJK>
0xE294	0x6374	0x7B0F	# <CJK>
0xE295	0x6375	0x7B0A	# <CJK>
0xE296	0x6376	0x7B06	# <CJK>
0xE297	0x6377	0x7B33	# <CJK>
0xE298	0x6378	0x7B18	# <CJK>
0xE299	0x6379	0x7B19	# <CJK>
0xE29A	0x637A	0x7B1E	# <CJK>
0xE29B	0x637B	0x7B35	# <CJK>
0xE29C	0x637C	0x7B28	# <CJK>
0xE29D	0x637D	0x7B36	# <CJK>
0xE29E	0x637E	0x7B50	# <CJK>
0xE29F	0x6421	0x7B7A	# <CJK>
0xE2A0	0x6422	0x7B04	# <CJK>
0xE2A1	0x6423	0x7B4D	# <CJK>
0xE2A2	0x6424	0x7B0B	# <CJK>
0xE2A3	0x6425	0x7B4C	# <CJK>
0xE2A4	0x6426	0x7B45	# <CJK>
0xE2A5	0x6427	0x7B75	# <CJK>
0xE2A6	0x6428	0x7B65	# <CJK>
0xE2A7	0x6429	0x7B74	# <CJK>
0xE2A8	0x642A	0x7B67	# <CJK>
0xE2A9	0x642B	0x7B70	# <CJK>
0xE2AA	0x642C	0x7B71	# <CJK>
0xE2AB	0x642D	0x7B6C	# <CJK>
0xE2AC	0x642E	0x7B6E	# <CJK>
0xE2AD	0x642F	0x7B9D	# <CJK>
0xE2AE	0x6430	0x7B98	# <CJK>
0xE2AF	0x6431	0x7B9F	# <CJK>
0xE2B0	0x6432	0x7B8D	# <CJK>
0xE2B1	0x6433	0x7B9C	# <CJK>
0xE2B2	0x6434	0x7B9A	# <CJK>
0xE2B3	0x6435	0x7B8B	# <CJK>
0xE2B4	0x6436	0x7B92	# <CJK>
0xE2B5	0x6437	0x7B8F	# <CJK>
0xE2B6	0x6438	0x7B5D	# <CJK>
0xE2B7	0x6439	0x7B99	# <CJK>
0xE2B8	0x643A	0x7BCB	# <CJK>
0xE2B9	0x643B	0x7BC1	# <CJK>
0xE2BA	0x643C	0x7BCC	# <CJK>
0xE2BB	0x643D	0x7BCF	# <CJK>
0xE2BC	0x643E	0x7BB4	# <CJK>
0xE2BD	0x643F	0x7BC6	# <CJK>
0xE2BE	0x6440	0x7BDD	# <CJK>
0xE2BF	0x6441	0x7BE9	# <CJK>
0xE2C0	0x6442	0x7C11	# <CJK>
0xE2C1	0x6443	0x7C14	# <CJK>
0xE2C2	0x6444	0x7BE6	# <CJK>
0xE2C3	0x6445	0x7BE5	# <CJK>
0xE2C4	0x6446	0x7C60	# <CJK>
0xE2C5	0x6447	0x7C00	# <CJK>
0xE2C6	0x6448	0x7C07	# <CJK>
0xE2C7	0x6449	0x7C13	# <CJK>
0xE2C8	0x644A	0x7BF3	# <CJK>
0xE2C9	0x644B	0x7BF7	# <CJK>
0xE2CA	0x644C	0x7C17	# <CJK>
0xE2CB	0x644D	0x7C0D	# <CJK>
0xE2CC	0x644E	0x7BF6	# <CJK>
0xE2CD	0x644F	0x7C23	# <CJK>
0xE2CE	0x6450	0x7C27	# <CJK>
0xE2CF	0x6451	0x7C2A	# <CJK>
0xE2D0	0x6452	0x7C1F	# <CJK>
0xE2D1	0x6453	0x7C37	# <CJK>
0xE2D2	0x6454	0x7C2B	# <CJK>
0xE2D3	0x6455	0x7C3D	# <CJK>
0xE2D4	0x6456	0x7C4C	# <CJK>
0xE2D5	0x6457	0x7C43	# <CJK>
0xE2D6	0x6458	0x7C54	# <CJK>
0xE2D7	0x6459	0x7C4F	# <CJK>
0xE2D8	0x645A	0x7C40	# <CJK>
0xE2D9	0x645B	0x7C50	# <CJK>
0xE2DA	0x645C	0x7C58	# <CJK>
0xE2DB	0x645D	0x7C5F	# <CJK>
0xE2DC	0x645E	0x7C64	# <CJK>
0xE2DD	0x645F	0x7C56	# <CJK>
0xE2DE	0x6460	0x7C65	# <CJK>
0xE2DF	0x6461	0x7C6C	# <CJK>
0xE2E0	0x6462	0x7C75	# <CJK>
0xE2E1	0x6463	0x7C83	# <CJK>
0xE2E2	0x6464	0x7C90	# <CJK>
0xE2E3	0x6465	0x7CA4	# <CJK>
0xE2E4	0x6466	0x7CAD	# <CJK>
0xE2E5	0x6467	0x7CA2	# <CJK>
0xE2E6	0x6468	0x7CAB	# <CJK>
0xE2E7	0x6469	0x7CA1	# <CJK>
0xE2E8	0x646A	0x7CA8	# <CJK>
0xE2E9	0x646B	0x7CB3	# <CJK>
0xE2EA	0x646C	0x7CB2	# <CJK>
0xE2EB	0x646D	0x7CB1	# <CJK>
0xE2EC	0x646E	0x7CAE	# <CJK>
0xE2ED	0x646F	0x7CB9	# <CJK>
0xE2EE	0x6470	0x7CBD	# <CJK>
0xE2EF	0x6471	0x7CC0	# <CJK>
0xE2F0	0x6472	0x7CC5	# <CJK>
0xE2F1	0x6473	0x7CC2	# <CJK>
0xE2F2	0x6474	0x7CD8	# <CJK>
0xE2F3	0x6475	0x7CD2	# <CJK>
0xE2F4	0x6476	0x7CDC	# <CJK>
0xE2F5	0x6477	0x7CE2	# <CJK>
0xE2F6	0x6478	0x9B3B	# <CJK>
0xE2F7	0x6479	0x7CEF	# <CJK>
0xE2F8	0x647A	0x7CF2	# <CJK>
0xE2F9	0x647B	0x7CF4	# <CJK>
0xE2FA	0x647C	0x7CF6	# <CJK>
0xE2FB	0x647D	0x7CFA	# <CJK>
0xE2FC	0x647E	0x7D06	# <CJK>
0xE340	0x6521	0x7D02	# <CJK>
0xE341	0x6522	0x7D1C	# <CJK>
0xE342	0x6523	0x7D15	# <CJK>
0xE343	0x6524	0x7D0A	# <CJK>
0xE344	0x6525	0x7D45	# <CJK>
0xE345	0x6526	0x7D4B	# <CJK>
0xE346	0x6527	0x7D2E	# <CJK>
0xE347	0x6528	0x7D32	# <CJK>
0xE348	0x6529	0x7D3F	# <CJK>
0xE349	0x652A	0x7D35	# <CJK>
0xE34A	0x652B	0x7D46	# <CJK>
0xE34B	0x652C	0x7D73	# <CJK>
0xE34C	0x652D	0x7D56	# <CJK>
0xE34D	0x652E	0x7D4E	# <CJK>
0xE34E	0x652F	0x7D72	# <CJK>
0xE34F	0x6530	0x7D68	# <CJK>
0xE350	0x6531	0x7D6E	# <CJK>
0xE351	0x6532	0x7D4F	# <CJK>
0xE352	0x6533	0x7D63	# <CJK>
0xE353	0x6534	0x7D93	# <CJK>
0xE354	0x6535	0x7D89	# <CJK>
0xE355	0x6536	0x7D5B	# <CJK>
0xE356	0x6537	0x7D8F	# <CJK>
0xE357	0x6538	0x7D7D	# <CJK>
0xE358	0x6539	0x7D9B	# <CJK>
0xE359	0x653A	0x7DBA	# <CJK>
0xE35A	0x653B	0x7DAE	# <CJK>
0xE35B	0x653C	0x7DA3	# <CJK>
0xE35C	0x653D	0x7DB5	# <CJK>
0xE35D	0x653E	0x7DC7	# <CJK>
0xE35E	0x653F	0x7DBD	# <CJK>
0xE35F	0x6540	0x7DAB	# <CJK>
0xE360	0x6541	0x7E3D	# <CJK>
0xE361	0x6542	0x7DA2	# <CJK>
0xE362	0x6543	0x7DAF	# <CJK>
0xE363	0x6544	0x7DDC	# <CJK>
0xE364	0x6545	0x7DB8	# <CJK>
0xE365	0x6546	0x7D9F	# <CJK>
0xE366	0x6547	0x7DB0	# <CJK>
0xE367	0x6548	0x7DD8	# <CJK>
0xE368	0x6549	0x7DDD	# <CJK>
0xE369	0x654A	0x7DE4	# <CJK>
0xE36A	0x654B	0x7DDE	# <CJK>
0xE36B	0x654C	0x7DFB	# <CJK>
0xE36C	0x654D	0x7DF2	# <CJK>
0xE36D	0x654E	0x7DE1	# <CJK>
0xE36E	0x654F	0x7E05	# <CJK>
0xE36F	0x6550	0x7E0A	# <CJK>
0xE370	0x6551	0x7E23	# <CJK>
0xE371	0x6552	0x7E21	# <CJK>
0xE372	0x6553	0x7E12	# <CJK>
0xE373	0x6554	0x7E31	# <CJK>
0xE374	0x6555	0x7E1F	# <CJK>
0xE375	0x6556	0x7E09	# <CJK>
0xE376	0x6557	0x7E0B	# <CJK>
0xE377	0x6558	0x7E22	# <CJK>
0xE378	0x6559	0x7E46	# <CJK>
0xE379	0x655A	0x7E66	# <CJK>
0xE37A	0x655B	0x7E3B	# <CJK>
0xE37B	0x655C	0x7E35	# <CJK>
0xE37C	0x655D	0x7E39	# <CJK>
0xE37D	0x655E	0x7E43	# <CJK>
0xE37E	0x655F	0x7E37	# <CJK>
0xE380	0x6560	0x7E32	# <CJK>
0xE381	0x6561	0x7E3A	# <CJK>
0xE382	0x6562	0x7E67	# <CJK>
0xE383	0x6563	0x7E5D	# <CJK>
0xE384	0x6564	0x7E56	# <CJK>
0xE385	0x6565	0x7E5E	# <CJK>
0xE386	0x6566	0x7E59	# <CJK>
0xE387	0x6567	0x7E5A	# <CJK>
0xE388	0x6568	0x7E79	# <CJK>
0xE389	0x6569	0x7E6A	# <CJK>
0xE38A	0x656A	0x7E69	# <CJK>
0xE38B	0x656B	0x7E7C	# <CJK>
0xE38C	0x656C	0x7E7B	# <CJK>
0xE38D	0x656D	0x7E83	# <CJK>
0xE38E	0x656E	0x7DD5	# <CJK>
0xE38F	0x656F	0x7E7D	# <CJK>
0xE390	0x6570	0x8FAE	# <CJK>
0xE391	0x6571	0x7E7F	# <CJK>
0xE392	0x6572	0x7E88	# <CJK>
0xE393	0x6573	0x7E89	# <CJK>
0xE394	0x6574	0x7E8C	# <CJK>
0xE395	0x6575	0x7E92	# <CJK>
0xE396	0x6576	0x7E90	# <CJK>
0xE397	0x6577	0x7E93	# <CJK>
0xE398	0x6578	0x7E94	# <CJK>
0xE399	0x6579	0x7E96	# <CJK>
0xE39A	0x657A	0x7E8E	# <CJK>
0xE39B	0x657B	0x7E9B	# <CJK>
0xE39C	0x657C	0x7E9C	# <CJK>
0xE39D	0x657D	0x7F38	# <CJK>
0xE39E	0x657E	0x7F3A	# <CJK>
0xE39F	0x6621	0x7F45	# <CJK>
0xE3A0	0x6622	0x7F4C	# <CJK>
0xE3A1	0x6623	0x7F4D	# <CJK>
0xE3A2	0x6624	0x7F4E	# <CJK>
0xE3A3	0x6625	0x7F50	# <CJK>
0xE3A4	0x6626	0x7F51	# <CJK>
0xE3A5	0x6627	0x7F55	# <CJK>
0xE3A6	0x6628	0x7F54	# <CJK>
0xE3A7	0x6629	0x7F58	# <CJK>
0xE3A8	0x662A	0x7F5F	# <CJK>
0xE3A9	0x662B	0x7F60	# <CJK>
0xE3AA	0x662C	0x7F68	# <CJK>
0xE3AB	0x662D	0x7F69	# <CJK>
0xE3AC	0x662E	0x7F67	# <CJK>
0xE3AD	0x662F	0x7F78	# <CJK>
0xE3AE	0x6630	0x7F82	# <CJK>
0xE3AF	0x6631	0x7F86	# <CJK>
0xE3B0	0x6632	0x7F83	# <CJK>
0xE3B1	0x6633	0x7F88	# <CJK>
0xE3B2	0x6634	0x7F87	# <CJK>
0xE3B3	0x6635	0x7F8C	# <CJK>
0xE3B4	0x6636	0x7F94	# <CJK>
0xE3B5	0x6637	0x7F9E	# <CJK>
0xE3B6	0x6638	0x7F9D	# <CJK>
0xE3B7	0x6639	0x7F9A	# <CJK>
0xE3B8	0x663A	0x7FA3	# <CJK>
0xE3B9	0x663B	0x7FAF	# <CJK>
0xE3BA	0x663C	0x7FB2	# <CJK>
0xE3BB	0x663D	0x7FB9	# <CJK>
0xE3BC	0x663E	0x7FAE	# <CJK>
0xE3BD	0x663F	0x7FB6	# <CJK>
0xE3BE	0x6640	0x7FB8	# <CJK>
0xE3BF	0x6641	0x8B71	# <CJK>
0xE3C0	0x6642	0x7FC5	# <CJK>
0xE3C1	0x6643	0x7FC6	# <CJK>
0xE3C2	0x6644	0x7FCA	# <CJK>
0xE3C3	0x6645	0x7FD5	# <CJK>
0xE3C4	0x6646	0x7FD4	# <CJK>
0xE3C5	0x6647	0x7FE1	# <CJK>
0xE3C6	0x6648	0x7FE6	# <CJK>
0xE3C7	0x6649	0x7FE9	# <CJK>
0xE3C8	0x664A	0x7FF3	# <CJK>
0xE3C9	0x664B	0x7FF9	# <CJK>
0xE3CA	0x664C	0x98DC	# <CJK>
0xE3CB	0x664D	0x8006	# <CJK>
0xE3CC	0x664E	0x8004	# <CJK>
0xE3CD	0x664F	0x800B	# <CJK>
0xE3CE	0x6650	0x8012	# <CJK>
0xE3CF	0x6651	0x8018	# <CJK>
0xE3D0	0x6652	0x8019	# <CJK>
0xE3D1	0x6653	0x801C	# <CJK>
0xE3D2	0x6654	0x8021	# <CJK>
0xE3D3	0x6655	0x8028	# <CJK>
0xE3D4	0x6656	0x803F	# <CJK>
0xE3D5	0x6657	0x803B	# <CJK>
0xE3D6	0x6658	0x804A	# <CJK>
0xE3D7	0x6659	0x8046	# <CJK>
0xE3D8	0x665A	0x8052	# <CJK>
0xE3D9	0x665B	0x8058	# <CJK>
0xE3DA	0x665C	0x805A	# <CJK>
0xE3DB	0x665D	0x805F	# <CJK>
0xE3DC	0x665E	0x8062	# <CJK>
0xE3DD	0x665F	0x8068	# <CJK>
0xE3DE	0x6660	0x8073	# <CJK>
0xE3DF	0x6661	0x8072	# <CJK>
0xE3E0	0x6662	0x8070	# <CJK>
0xE3E1	0x6663	0x8076	# <CJK>
0xE3E2	0x6664	0x8079	# <CJK>
0xE3E3	0x6665	0x807D	# <CJK>
0xE3E4	0x6666	0x807F	# <CJK>
0xE3E5	0x6667	0x8084	# <CJK>
0xE3E6	0x6668	0x8086	# <CJK>
0xE3E7	0x6669	0x8085	# <CJK>
0xE3E8	0x666A	0x809B	# <CJK>
0xE3E9	0x666B	0x8093	# <CJK>
0xE3EA	0x666C	0x809A	# <CJK>
0xE3EB	0x666D	0x80AD	# <CJK>
0xE3EC	0x666E	0x5190	# <CJK>
0xE3ED	0x666F	0x80AC	# <CJK>
0xE3EE	0x6670	0x80DB	# <CJK>
0xE3EF	0x6671	0x80E5	# <CJK>
0xE3F0	0x6672	0x80D9	# <CJK>
0xE3F1	0x6673	0x80DD	# <CJK>
0xE3F2	0x6674	0x80C4	# <CJK>
0xE3F3	0x6675	0x80DA	# <CJK>
0xE3F4	0x6676	0x80D6	# <CJK>
0xE3F5	0x6677	0x8109	# <CJK>
0xE3F6	0x6678	0x80EF	# <CJK>
0xE3F7	0x6679	0x80F1	# <CJK>
0xE3F8	0x667A	0x811B	# <CJK>
0xE3F9	0x667B	0x8129	# <CJK>
0xE3FA	0x667C	0x8123	# <CJK>
0xE3FB	0x667D	0x812F	# <CJK>
0xE3FC	0x667E	0x814B	# <CJK>
0xE440	0x6721	0x968B	# <CJK>
0xE441	0x6722	0x8146	# <CJK>
0xE442	0x6723	0x813E	# <CJK>
0xE443	0x6724	0x8153	# <CJK>
0xE444	0x6725	0x8151	# <CJK>
0xE445	0x6726	0x80FC	# <CJK>
0xE446	0x6727	0x8171	# <CJK>
0xE447	0x6728	0x816E	# <CJK>
0xE448	0x6729	0x8165	# <CJK>
0xE449	0x672A	0x8166	# <CJK>
0xE44A	0x672B	0x8174	# <CJK>
0xE44B	0x672C	0x8183	# <CJK>
0xE44C	0x672D	0x8188	# <CJK>
0xE44D	0x672E	0x818A	# <CJK>
0xE44E	0x672F	0x8180	# <CJK>
0xE44F	0x6730	0x8182	# <CJK>
0xE450	0x6731	0x81A0	# <CJK>
0xE451	0x6732	0x8195	# <CJK>
0xE452	0x6733	0x81A4	# <CJK>
0xE453	0x6734	0x81A3	# <CJK>
0xE454	0x6735	0x815F	# <CJK>
0xE455	0x6736	0x8193	# <CJK>
0xE456	0x6737	0x81A9	# <CJK>
0xE457	0x6738	0x81B0	# <CJK>
0xE458	0x6739	0x81B5	# <CJK>
0xE459	0x673A	0x81BE	# <CJK>
0xE45A	0x673B	0x81B8	# <CJK>
0xE45B	0x673C	0x81BD	# <CJK>
0xE45C	0x673D	0x81C0	# <CJK>
0xE45D	0x673E	0x81C2	# <CJK>
0xE45E	0x673F	0x81BA	# <CJK>
0xE45F	0x6740	0x81C9	# <CJK>
0xE460	0x6741	0x81CD	# <CJK>
0xE461	0x6742	0x81D1	# <CJK>
0xE462	0x6743	0x81D9	# <CJK>
0xE463	0x6744	0x81D8	# <CJK>
0xE464	0x6745	0x81C8	# <CJK>
0xE465	0x6746	0x81DA	# <CJK>
0xE466	0x6747	0x81DF	# <CJK>
0xE467	0x6748	0x81E0	# <CJK>
0xE468	0x6749	0x81E7	# <CJK>
0xE469	0x674A	0x81FA	# <CJK>
0xE46A	0x674B	0x81FB	# <CJK>
0xE46B	0x674C	0x81FE	# <CJK>
0xE46C	0x674D	0x8201	# <CJK>
0xE46D	0x674E	0x8202	# <CJK>
0xE46E	0x674F	0x8205	# <CJK>
0xE46F	0x6750	0x8207	# <CJK>
0xE470	0x6751	0x820A	# <CJK>
0xE471	0x6752	0x820D	# <CJK>
0xE472	0x6753	0x8210	# <CJK>
0xE473	0x6754	0x8216	# <CJK>
0xE474	0x6755	0x8229	# <CJK>
0xE475	0x6756	0x822B	# <CJK>
0xE476	0x6757	0x8238	# <CJK>
0xE477	0x6758	0x8233	# <CJK>
0xE478	0x6759	0x8240	# <CJK>
0xE479	0x675A	0x8259	# <CJK>
0xE47A	0x675B	0x8258	# <CJK>
0xE47B	0x675C	0x825D	# <CJK>
0xE47C	0x675D	0x825A	# <CJK>
0xE47D	0x675E	0x825F	# <CJK>
0xE47E	0x675F	0x8264	# <CJK>
0xE480	0x6760	0x8262	# <CJK>
0xE481	0x6761	0x8268	# <CJK>
0xE482	0x6762	0x826A	# <CJK>
0xE483	0x6763	0x826B	# <CJK>
0xE484	0x6764	0x822E	# <CJK>
0xE485	0x6765	0x8271	# <CJK>
0xE486	0x6766	0x8277	# <CJK>
0xE487	0x6767	0x8278	# <CJK>
0xE488	0x6768	0x827E	# <CJK>
0xE489	0x6769	0x828D	# <CJK>
0xE48A	0x676A	0x8292	# <CJK>
0xE48B	0x676B	0x82AB	# <CJK>
0xE48C	0x676C	0x829F	# <CJK>
0xE48D	0x676D	0x82BB	# <CJK>
0xE48E	0x676E	0x82AC	# <CJK>
0xE48F	0x676F	0x82E1	# <CJK>
0xE490	0x6770	0x82E3	# <CJK>
0xE491	0x6771	0x82DF	# <CJK>
0xE492	0x6772	0x82D2	# <CJK>
0xE493	0x6773	0x82F4	# <CJK>
0xE494	0x6774	0x82F3	# <CJK>
0xE495	0x6775	0x82FA	# <CJK>
0xE496	0x6776	0x8393	# <CJK>
0xE497	0x6777	0x8303	# <CJK>
0xE498	0x6778	0x82FB	# <CJK>
0xE499	0x6779	0x82F9	# <CJK>
0xE49A	0x677A	0x82DE	# <CJK>
0xE49B	0x677B	0x8306	# <CJK>
0xE49C	0x677C	0x82DC	# <CJK>
0xE49D	0x677D	0x8309	# <CJK>
0xE49E	0x677E	0x82D9	# <CJK>
0xE49F	0x6821	0x8335	# <CJK>
0xE4A0	0x6822	0x8334	# <CJK>
0xE4A1	0x6823	0x8316	# <CJK>
0xE4A2	0x6824	0x8332	# <CJK>
0xE4A3	0x6825	0x8331	# <CJK>
0xE4A4	0x6826	0x8340	# <CJK>
0xE4A5	0x6827	0x8339	# <CJK>
0xE4A6	0x6828	0x8350	# <CJK>
0xE4A7	0x6829	0x8345	# <CJK>
0xE4A8	0x682A	0x832F	# <CJK>
0xE4A9	0x682B	0x832B	# <CJK>
0xE4AA	0x682C	0x8317	# <CJK>
0xE4AB	0x682D	0x8318	# <CJK>
0xE4AC	0x682E	0x8385	# <CJK>
0xE4AD	0x682F	0x839A	# <CJK>
0xE4AE	0x6830	0x83AA	# <CJK>
0xE4AF	0x6831	0x839F	# <CJK>
0xE4B0	0x6832	0x83A2	# <CJK>
0xE4B1	0x6833	0x8396	# <CJK>
0xE4B2	0x6834	0x8323	# <CJK>
0xE4B3	0x6835	0x838E	# <CJK>
0xE4B4	0x6836	0x8387	# <CJK>
0xE4B5	0x6837	0x838A	# <CJK>
0xE4B6	0x6838	0x837C	# <CJK>
0xE4B7	0x6839	0x83B5	# <CJK>
0xE4B8	0x683A	0x8373	# <CJK>
0xE4B9	0x683B	0x8375	# <CJK>
0xE4BA	0x683C	0x83A0	# <CJK>
0xE4BB	0x683D	0x8389	# <CJK>
0xE4BC	0x683E	0x83A8	# <CJK>
0xE4BD	0x683F	0x83F4	# <CJK>
0xE4BE	0x6840	0x8413	# <CJK>
0xE4BF	0x6841	0x83EB	# <CJK>
0xE4C0	0x6842	0x83CE	# <CJK>
0xE4C1	0x6843	0x83FD	# <CJK>
0xE4C2	0x6844	0x8403	# <CJK>
0xE4C3	0x6845	0x83D8	# <CJK>
0xE4C4	0x6846	0x840B	# <CJK>
0xE4C5	0x6847	0x83C1	# <CJK>
0xE4C6	0x6848	0x83F7	# <CJK>
0xE4C7	0x6849	0x8407	# <CJK>
0xE4C8	0x684A	0x83E0	# <CJK>
0xE4C9	0x684B	0x83F2	# <CJK>
0xE4CA	0x684C	0x840D	# <CJK>
0xE4CB	0x684D	0x8422	# <CJK>
0xE4CC	0x684E	0x8420	# <CJK>
0xE4CD	0x684F	0x83BD	# <CJK>
0xE4CE	0x6850	0x8438	# <CJK>
0xE4CF	0x6851	0x8506	# <CJK>
0xE4D0	0x6852	0x83FB	# <CJK>
0xE4D1	0x6853	0x846D	# <CJK>
0xE4D2	0x6854	0x842A	# <CJK>
0xE4D3	0x6855	0x843C	# <CJK>
0xE4D4	0x6856	0x855A	# <CJK>
0xE4D5	0x6857	0x8484	# <CJK>
0xE4D6	0x6858	0x8477	# <CJK>
0xE4D7	0x6859	0x846B	# <CJK>
0xE4D8	0x685A	0x84AD	# <CJK>
0xE4D9	0x685B	0x846E	# <CJK>
0xE4DA	0x685C	0x8482	# <CJK>
0xE4DB	0x685D	0x8469	# <CJK>
0xE4DC	0x685E	0x8446	# <CJK>
0xE4DD	0x685F	0x842C	# <CJK>
0xE4DE	0x6860	0x846F	# <CJK>
0xE4DF	0x6861	0x8479	# <CJK>
0xE4E0	0x6862	0x8435	# <CJK>
0xE4E1	0x6863	0x84CA	# <CJK>
0xE4E2	0x6864	0x8462	# <CJK>
0xE4E3	0x6865	0x84B9	# <CJK>
0xE4E4	0x6866	0x84BF	# <CJK>
0xE4E5	0x6867	0x849F	# <CJK>
0xE4E6	0x6868	0x84D9	# <CJK>
0xE4E7	0x6869	0x84CD	# <CJK>
0xE4E8	0x686A	0x84BB	# <CJK>
0xE4E9	0x686B	0x84DA	# <CJK>
0xE4EA	0x686C	0x84D0	# <CJK>
0xE4EB	0x686D	0x84C1	# <CJK>
0xE4EC	0x686E	0x84C6	# <CJK>
0xE4ED	0x686F	0x84D6	# <CJK>
0xE4EE	0x6870	0x84A1	# <CJK>
0xE4EF	0x6871	0x8521	# <CJK>
0xE4F0	0x6872	0x84FF	# <CJK>
0xE4F1	0x6873	0x84F4	# <CJK>
0xE4F2	0x6874	0x8517	# <CJK>
0xE4F3	0x6875	0x8518	# <CJK>
0xE4F4	0x6876	0x852C	# <CJK>
0xE4F5	0x6877	0x851F	# <CJK>
0xE4F6	0x6878	0x8515	# <CJK>
0xE4F7	0x6879	0x8514	# <CJK>
0xE4F8	0x687A	0x84FC	# <CJK>
0xE4F9	0x687B	0x8540	# <CJK>
0xE4FA	0x687C	0x8563	# <CJK>
0xE4FB	0x687D	0x8558	# <CJK>
0xE4FC	0x687E	0x8548	# <CJK>
0xE540	0x6921	0x8541	# <CJK>
0xE541	0x6922	0x8602	# <CJK>
0xE542	0x6923	0x854B	# <CJK>
0xE543	0x6924	0x8555	# <CJK>
0xE544	0x6925	0x8580	# <CJK>
0xE545	0x6926	0x85A4	# <CJK>
0xE546	0x6927	0x8588	# <CJK>
0xE547	0x6928	0x8591	# <CJK>
0xE548	0x6929	0x858A	# <CJK>
0xE549	0x692A	0x85A8	# <CJK>
0xE54A	0x692B	0x856D	# <CJK>
0xE54B	0x692C	0x8594	# <CJK>
0xE54C	0x692D	0x859B	# <CJK>
0xE54D	0x692E	0x85EA	# <CJK>
0xE54E	0x692F	0x8587	# <CJK>
0xE54F	0x6930	0x859C	# <CJK>
0xE550	0x6931	0x8577	# <CJK>
0xE551	0x6932	0x857E	# <CJK>
0xE552	0x6933	0x8590	# <CJK>
0xE553	0x6934	0x85C9	# <CJK>
0xE554	0x6935	0x85BA	# <CJK>
0xE555	0x6936	0x85CF	# <CJK>
0xE556	0x6937	0x85B9	# <CJK>
0xE557	0x6938	0x85D0	# <CJK>
0xE558	0x6939	0x85D5	# <CJK>
0xE559	0x693A	0x85DD	# <CJK>
0xE55A	0x693B	0x85E5	# <CJK>
0xE55B	0x693C	0x85DC	# <CJK>
0xE55C	0x693D	0x85F9	# <CJK>
0xE55D	0x693E	0x860A	# <CJK>
0xE55E	0x693F	0x8613	# <CJK>
0xE55F	0x6940	0x860B	# <CJK>
0xE560	0x6941	0x85FE	# <CJK>
0xE561	0x6942	0x85FA	# <CJK>
0xE562	0x6943	0x8606	# <CJK>
0xE563	0x6944	0x8622	# <CJK>
0xE564	0x6945	0x861A	# <CJK>
0xE565	0x6946	0x8630	# <CJK>
0xE566	0x6947	0x863F	# <CJK>
0xE567	0x6948	0x864D	# <CJK>
0xE568	0x6949	0x4E55	# <CJK>
0xE569	0x694A	0x8654	# <CJK>
0xE56A	0x694B	0x865F	# <CJK>
0xE56B	0x694C	0x8667	# <CJK>
0xE56C	0x694D	0x8671	# <CJK>
0xE56D	0x694E	0x8693	# <CJK>
0xE56E	0x694F	0x86A3	# <CJK>
0xE56F	0x6950	0x86A9	# <CJK>
0xE570	0x6951	0x86AA	# <CJK>
0xE571	0x6952	0x868B	# <CJK>
0xE572	0x6953	0x868C	# <CJK>
0xE573	0x6954	0x86B6	# <CJK>
0xE574	0x6955	0x86AF	# <CJK>
0xE575	0x6956	0x86C4	# <CJK>
0xE576	0x6957	0x86C6	# <CJK>
0xE577	0x6958	0x86B0	# <CJK>
0xE578	0x6959	0x86C9	# <CJK>
0xE579	0x695A	0x8823	# <CJK>
0xE57A	0x695B	0x86AB	# <CJK>
0xE57B	0x695C	0x86D4	# <CJK>
0xE57C	0x695D	0x86DE	# <CJK>
0xE57D	0x695E	0x86E9	# <CJK>
0xE57E	0x695F	0x86EC	# <CJK>
0xE580	0x6960	0x86DF	# <CJK>
0xE581	0x6961	0x86DB	# <CJK>
0xE582	0x6962	0x86EF	# <CJK>
0xE583	0x6963	0x8712	# <CJK>
0xE584	0x6964	0x8706	# <CJK>
0xE585	0x6965	0x8708	# <CJK>
0xE586	0x6966	0x8700	# <CJK>
0xE587	0x6967	0x8703	# <CJK>
0xE588	0x6968	0x86FB	# <CJK>
0xE589	0x6969	0x8711	# <CJK>
0xE58A	0x696A	0x8709	# <CJK>
0xE58B	0x696B	0x870D	# <CJK>
0xE58C	0x696C	0x86F9	# <CJK>
0xE58D	0x696D	0x870A	# <CJK>
0xE58E	0x696E	0x8734	# <CJK>
0xE58F	0x696F	0x873F	# <CJK>
0xE590	0x6970	0x8737	# <CJK>
0xE591	0x6971	0x873B	# <CJK>
0xE592	0x6972	0x8725	# <CJK>
0xE593	0x6973	0x8729	# <CJK>
0xE594	0x6974	0x871A	# <CJK>
0xE595	0x6975	0x8760	# <CJK>
0xE596	0x6976	0x875F	# <CJK>
0xE597	0x6977	0x8778	# <CJK>
0xE598	0x6978	0x874C	# <CJK>
0xE599	0x6979	0x874E	# <CJK>
0xE59A	0x697A	0x8774	# <CJK>
0xE59B	0x697B	0x8757	# <CJK>
0xE59C	0x697C	0x8768	# <CJK>
0xE59D	0x697D	0x876E	# <CJK>
0xE59E	0x697E	0x8759	# <CJK>
0xE59F	0x6A21	0x8753	# <CJK>
0xE5A0	0x6A22	0x8763	# <CJK>
0xE5A1	0x6A23	0x876A	# <CJK>
0xE5A2	0x6A24	0x8805	# <CJK>
0xE5A3	0x6A25	0x87A2	# <CJK>
0xE5A4	0x6A26	0x879F	# <CJK>
0xE5A5	0x6A27	0x8782	# <CJK>
0xE5A6	0x6A28	0x87AF	# <CJK>
0xE5A7	0x6A29	0x87CB	# <CJK>
0xE5A8	0x6A2A	0x87BD	# <CJK>
0xE5A9	0x6A2B	0x87C0	# <CJK>
0xE5AA	0x6A2C	0x87D0	# <CJK>
0xE5AB	0x6A2D	0x96D6	# <CJK>
0xE5AC	0x6A2E	0x87AB	# <CJK>
0xE5AD	0x6A2F	0x87C4	# <CJK>
0xE5AE	0x6A30	0x87B3	# <CJK>
0xE5AF	0x6A31	0x87C7	# <CJK>
0xE5B0	0x6A32	0x87C6	# <CJK>
0xE5B1	0x6A33	0x87BB	# <CJK>
0xE5B2	0x6A34	0x87EF	# <CJK>
0xE5B3	0x6A35	0x87F2	# <CJK>
0xE5B4	0x6A36	0x87E0	# <CJK>
0xE5B5	0x6A37	0x880F	# <CJK>
0xE5B6	0x6A38	0x880D	# <CJK>
0xE5B7	0x6A39	0x87FE	# <CJK>
0xE5B8	0x6A3A	0x87F6	# <CJK>
0xE5B9	0x6A3B	0x87F7	# <CJK>
0xE5BA	0x6A3C	0x880E	# <CJK>
0xE5BB	0x6A3D	0x87D2	# <CJK>
0xE5BC	0x6A3E	0x8811	# <CJK>
0xE5BD	0x6A3F	0x8816	# <CJK>
0xE5BE	0x6A40	0x8815	# <CJK>
0xE5BF	0x6A41	0x8822	# <CJK>
0xE5C0	0x6A42	0x8821	# <CJK>
0xE5C1	0x6A43	0x8831	# <CJK>
0xE5C2	0x6A44	0x8836	# <CJK>
0xE5C3	0x6A45	0x8839	# <CJK>
0xE5C4	0x6A46	0x8827	# <CJK>
0xE5C5	0x6A47	0x883B	# <CJK>
0xE5C6	0x6A48	0x8844	# <CJK>
0xE5C7	0x6A49	0x8842	# <CJK>
0xE5C8	0x6A4A	0x8852	# <CJK>
0xE5C9	0x6A4B	0x8859	# <CJK>
0xE5CA	0x6A4C	0x885E	# <CJK>
0xE5CB	0x6A4D	0x8862	# <CJK>
0xE5CC	0x6A4E	0x886B	# <CJK>
0xE5CD	0x6A4F	0x8881	# <CJK>
0xE5CE	0x6A50	0x887E	# <CJK>
0xE5CF	0x6A51	0x889E	# <CJK>
0xE5D0	0x6A52	0x8875	# <CJK>
0xE5D1	0x6A53	0x887D	# <CJK>
0xE5D2	0x6A54	0x88B5	# <CJK>
0xE5D3	0x6A55	0x8872	# <CJK>
0xE5D4	0x6A56	0x8882	# <CJK>
0xE5D5	0x6A57	0x8897	# <CJK>
0xE5D6	0x6A58	0x8892	# <CJK>
0xE5D7	0x6A59	0x88AE	# <CJK>
0xE5D8	0x6A5A	0x8899	# <CJK>
0xE5D9	0x6A5B	0x88A2	# <CJK>
0xE5DA	0x6A5C	0x888D	# <CJK>
0xE5DB	0x6A5D	0x88A4	# <CJK>
0xE5DC	0x6A5E	0x88B0	# <CJK>
0xE5DD	0x6A5F	0x88BF	# <CJK>
0xE5DE	0x6A60	0x88B1	# <CJK>
0xE5DF	0x6A61	0x88C3	# <CJK>
0xE5E0	0x6A62	0x88C4	# <CJK>
0xE5E1	0x6A63	0x88D4	# <CJK>
0xE5E2	0x6A64	0x88D8	# <CJK>
0xE5E3	0x6A65	0x88D9	# <CJK>
0xE5E4	0x6A66	0x88DD	# <CJK>
0xE5E5	0x6A67	0x88F9	# <CJK>
0xE5E6	0x6A68	0x8902	# <CJK>
0xE5E7	0x6A69	0x88FC	# <CJK>
0xE5E8	0x6A6A	0x88F4	# <CJK>
0xE5E9	0x6A6B	0x88E8	# <CJK>
0xE5EA	0x6A6C	0x88F2	# <CJK>
0xE5EB	0x6A6D	0x8904	# <CJK>
0xE5EC	0x6A6E	0x890C	# <CJK>
0xE5ED	0x6A6F	0x890A	# <CJK>
0xE5EE	0x6A70	0x8913	# <CJK>
0xE5EF	0x6A71	0x8943	# <CJK>
0xE5F0	0x6A72	0x891E	# <CJK>
0xE5F1	0x6A73	0x8925	# <CJK>
0xE5F2	0x6A74	0x892A	# <CJK>
0xE5F3	0x6A75	0x892B	# <CJK>
0xE5F4	0x6A76	0x8941	# <CJK>
0xE5F5	0x6A77	0x8944	# <CJK>
0xE5F6	0x6A78	0x893B	# <CJK>
0xE5F7	0x6A79	0x8936	# <CJK>
0xE5F8	0x6A7A	0x8938	# <CJK>
0xE5F9	0x6A7B	0x894C	# <CJK>
0xE5FA	0x6A7C	0x891D	# <CJK>
0xE5FB	0x6A7D	0x8960	# <CJK>
0xE5FC	0x6A7E	0x895E	# <CJK>
0xE640	0x6B21	0x8966	# <CJK>
0xE641	0x6B22	0x8964	# <CJK>
0xE642	0x6B23	0x896D	# <CJK>
0xE643	0x6B24	0x896A	# <CJK>
0xE644	0x6B25	0x896F	# <CJK>
0xE645	0x6B26	0x8974	# <CJK>
0xE646	0x6B27	0x8977	# <CJK>
0xE647	0x6B28	0x897E	# <CJK>
0xE648	0x6B29	0x8983	# <CJK>
0xE649	0x6B2A	0x8988	# <CJK>
0xE64A	0x6B2B	0x898A	# <CJK>
0xE64B	0x6B2C	0x8993	# <CJK>
0xE64C	0x6B2D	0x8998	# <CJK>
0xE64D	0x6B2E	0x89A1	# <CJK>
0xE64E	0x6B2F	0x89A9	# <CJK>
0xE64F	0x6B30	0x89A6	# <CJK>
0xE650	0x6B31	0x89AC	# <CJK>
0xE651	0x6B32	0x89AF	# <CJK>
0xE652	0x6B33	0x89B2	# <CJK>
0xE653	0x6B34	0x89BA	# <CJK>
0xE654	0x6B35	0x89BD	# <CJK>
0xE655	0x6B36	0x89BF	# <CJK>
0xE656	0x6B37	0x89C0	# <CJK>
0xE657	0x6B38	0x89DA	# <CJK>
0xE658	0x6B39	0x89DC	# <CJK>
0xE659	0x6B3A	0x89DD	# <CJK>
0xE65A	0x6B3B	0x89E7	# <CJK>
0xE65B	0x6B3C	0x89F4	# <CJK>
0xE65C	0x6B3D	0x89F8	# <CJK>
0xE65D	0x6B3E	0x8A03	# <CJK>
0xE65E	0x6B3F	0x8A16	# <CJK>
0xE65F	0x6B40	0x8A10	# <CJK>
0xE660	0x6B41	0x8A0C	# <CJK>
0xE661	0x6B42	0x8A1B	# <CJK>
0xE662	0x6B43	0x8A1D	# <CJK>
0xE663	0x6B44	0x8A25	# <CJK>
0xE664	0x6B45	0x8A36	# <CJK>
0xE665	0x6B46	0x8A41	# <CJK>
0xE666	0x6B47	0x8A5B	# <CJK>
0xE667	0x6B48	0x8A52	# <CJK>
0xE668	0x6B49	0x8A46	# <CJK>
0xE669	0x6B4A	0x8A48	# <CJK>
0xE66A	0x6B4B	0x8A7C	# <CJK>
0xE66B	0x6B4C	0x8A6D	# <CJK>
0xE66C	0x6B4D	0x8A6C	# <CJK>
0xE66D	0x6B4E	0x8A62	# <CJK>
0xE66E	0x6B4F	0x8A85	# <CJK>
0xE66F	0x6B50	0x8A82	# <CJK>
0xE670	0x6B51	0x8A84	# <CJK>
0xE671	0x6B52	0x8AA8	# <CJK>
0xE672	0x6B53	0x8AA1	# <CJK>
0xE673	0x6B54	0x8A91	# <CJK>
0xE674	0x6B55	0x8AA5	# <CJK>
0xE675	0x6B56	0x8AA6	# <CJK>
0xE676	0x6B57	0x8A9A	# <CJK>
0xE677	0x6B58	0x8AA3	# <CJK>
0xE678	0x6B59	0x8AC4	# <CJK>
0xE679	0x6B5A	0x8ACD	# <CJK>
0xE67A	0x6B5B	0x8AC2	# <CJK>
0xE67B	0x6B5C	0x8ADA	# <CJK>
0xE67C	0x6B5D	0x8AEB	# <CJK>
0xE67D	0x6B5E	0x8AF3	# <CJK>
0xE67E	0x6B5F	0x8AE7	# <CJK>
0xE680	0x6B60	0x8AE4	# <CJK>
0xE681	0x6B61	0x8AF1	# <CJK>
0xE682	0x6B62	0x8B14	# <CJK>
0xE683	0x6B63	0x8AE0	# <CJK>
0xE684	0x6B64	0x8AE2	# <CJK>
0xE685	0x6B65	0x8AF7	# <CJK>
0xE686	0x6B66	0x8ADE	# <CJK>
0xE687	0x6B67	0x8ADB	# <CJK>
0xE688	0x6B68	0x8B0C	# <CJK>
0xE689	0x6B69	0x8B07	# <CJK>
0xE68A	0x6B6A	0x8B1A	# <CJK>
0xE68B	0x6B6B	0x8AE1	# <CJK>
0xE68C	0x6B6C	0x8B16	# <CJK>
0xE68D	0x6B6D	0x8B10	# <CJK>
0xE68E	0x6B6E	0x8B17	# <CJK>
0xE68F	0x6B6F	0x8B20	# <CJK>
0xE690	0x6B70	0x8B33	# <CJK>
0xE691	0x6B71	0x97AB	# <CJK>
0xE692	0x6B72	0x8B26	# <CJK>
0xE693	0x6B73	0x8B2B	# <CJK>
0xE694	0x6B74	0x8B3E	# <CJK>
0xE695	0x6B75	0x8B28	# <CJK>
0xE696	0x6B76	0x8B41	# <CJK>
0xE697	0x6B77	0x8B4C	# <CJK>
0xE698	0x6B78	0x8B4F	# <CJK>
0xE699	0x6B79	0x8B4E	# <CJK>
0xE69A	0x6B7A	0x8B49	# <CJK>
0xE69B	0x6B7B	0x8B56	# <CJK>
0xE69C	0x6B7C	0x8B5B	# <CJK>
0xE69D	0x6B7D	0x8B5A	# <CJK>
0xE69E	0x6B7E	0x8B6B	# <CJK>
0xE69F	0x6C21	0x8B5F	# <CJK>
0xE6A0	0x6C22	0x8B6C	# <CJK>
0xE6A1	0x6C23	0x8B6F	# <CJK>
0xE6A2	0x6C24	0x8B74	# <CJK>
0xE6A3	0x6C25	0x8B7D	# <CJK>
0xE6A4	0x6C26	0x8B80	# <CJK>
0xE6A5	0x6C27	0x8B8C	# <CJK>
0xE6A6	0x6C28	0x8B8E	# <CJK>
0xE6A7	0x6C29	0x8B92	# <CJK>
0xE6A8	0x6C2A	0x8B93	# <CJK>
0xE6A9	0x6C2B	0x8B96	# <CJK>
0xE6AA	0x6C2C	0x8B99	# <CJK>
0xE6AB	0x6C2D	0x8B9A	# <CJK>
0xE6AC	0x6C2E	0x8C3A	# <CJK>
0xE6AD	0x6C2F	0x8C41	# <CJK>
0xE6AE	0x6C30	0x8C3F	# <CJK>
0xE6AF	0x6C31	0x8C48	# <CJK>
0xE6B0	0x6C32	0x8C4C	# <CJK>
0xE6B1	0x6C33	0x8C4E	# <CJK>
0xE6B2	0x6C34	0x8C50	# <CJK>
0xE6B3	0x6C35	0x8C55	# <CJK>
0xE6B4	0x6C36	0x8C62	# <CJK>
0xE6B5	0x6C37	0x8C6C	# <CJK>
0xE6B6	0x6C38	0x8C78	# <CJK>
0xE6B7	0x6C39	0x8C7A	# <CJK>
0xE6B8	0x6C3A	0x8C82	# <CJK>
0xE6B9	0x6C3B	0x8C89	# <CJK>
0xE6BA	0x6C3C	0x8C85	# <CJK>
0xE6BB	0x6C3D	0x8C8A	# <CJK>
0xE6BC	0x6C3E	0x8C8D	# <CJK>
0xE6BD	0x6C3F	0x8C8E	# <CJK>
0xE6BE	0x6C40	0x8C94	# <CJK>
0xE6BF	0x6C41	0x8C7C	# <CJK>
0xE6C0	0x6C42	0x8C98	# <CJK>
0xE6C1	0x6C43	0x621D	# <CJK>
0xE6C2	0x6C44	0x8CAD	# <CJK>
0xE6C3	0x6C45	0x8CAA	# <CJK>
0xE6C4	0x6C46	0x8CBD	# <CJK>
0xE6C5	0x6C47	0x8CB2	# <CJK>
0xE6C6	0x6C48	0x8CB3	# <CJK>
0xE6C7	0x6C49	0x8CAE	# <CJK>
0xE6C8	0x6C4A	0x8CB6	# <CJK>
0xE6C9	0x6C4B	0x8CC8	# <CJK>
0xE6CA	0x6C4C	0x8CC1	# <CJK>
0xE6CB	0x6C4D	0x8CE4	# <CJK>
0xE6CC	0x6C4E	0x8CE3	# <CJK>
0xE6CD	0x6C4F	0x8CDA	# <CJK>
0xE6CE	0x6C50	0x8CFD	# <CJK>
0xE6CF	0x6C51	0x8CFA	# <CJK>
0xE6D0	0x6C52	0x8CFB	# <CJK>
0xE6D1	0x6C53	0x8D04	# <CJK>
0xE6D2	0x6C54	0x8D05	# <CJK>
0xE6D3	0x6C55	0x8D0A	# <CJK>
0xE6D4	0x6C56	0x8D07	# <CJK>
0xE6D5	0x6C57	0x8D0F	# <CJK>
0xE6D6	0x6C58	0x8D0D	# <CJK>
0xE6D7	0x6C59	0x8D10	# <CJK>
0xE6D8	0x6C5A	0x9F4E	# <CJK>
0xE6D9	0x6C5B	0x8D13	# <CJK>
0xE6DA	0x6C5C	0x8CCD	# <CJK>
0xE6DB	0x6C5D	0x8D14	# <CJK>
0xE6DC	0x6C5E	0x8D16	# <CJK>
0xE6DD	0x6C5F	0x8D67	# <CJK>
0xE6DE	0x6C60	0x8D6D	# <CJK>
0xE6DF	0x6C61	0x8D71	# <CJK>
0xE6E0	0x6C62	0x8D73	# <CJK>
0xE6E1	0x6C63	0x8D81	# <CJK>
0xE6E2	0x6C64	0x8D99	# <CJK>
0xE6E3	0x6C65	0x8DC2	# <CJK>
0xE6E4	0x6C66	0x8DBE	# <CJK>
0xE6E5	0x6C67	0x8DBA	# <CJK>
0xE6E6	0x6C68	0x8DCF	# <CJK>
0xE6E7	0x6C69	0x8DDA	# <CJK>
0xE6E8	0x6C6A	0x8DD6	# <CJK>
0xE6E9	0x6C6B	0x8DCC	# <CJK>
0xE6EA	0x6C6C	0x8DDB	# <CJK>
0xE6EB	0x6C6D	0x8DCB	# <CJK>
0xE6EC	0x6C6E	0x8DEA	# <CJK>
0xE6ED	0x6C6F	0x8DEB	# <CJK>
0xE6EE	0x6C70	0x8DDF	# <CJK>
0xE6EF	0x6C71	0x8DE3	# <CJK>
0xE6F0	0x6C72	0x8DFC	# <CJK>
0xE6F1	0x6C73	0x8E08	# <CJK>
0xE6F2	0x6C74	0x8E09	# <CJK>
0xE6F3	0x6C75	0x8DFF	# <CJK>
0xE6F4	0x6C76	0x8E1D	# <CJK>
0xE6F5	0x6C77	0x8E1E	# <CJK>
0xE6F6	0x6C78	0x8E10	# <CJK>
0xE6F7	0x6C79	0x8E1F	# <CJK>
0xE6F8	0x6C7A	0x8E42	# <CJK>
0xE6F9	0x6C7B	0x8E35	# <CJK>
0xE6FA	0x6C7C	0x8E30	# <CJK>
0xE6FB	0x6C7D	0x8E34	# <CJK>
0xE6FC	0x6C7E	0x8E4A	# <CJK>
0xE740	0x6D21	0x8E47	# <CJK>
0xE741	0x6D22	0x8E49	# <CJK>
0xE742	0x6D23	0x8E4C	# <CJK>
0xE743	0x6D24	0x8E50	# <CJK>
0xE744	0x6D25	0x8E48	# <CJK>
0xE745	0x6D26	0x8E59	# <CJK>
0xE746	0x6D27	0x8E64	# <CJK>
0xE747	0x6D28	0x8E60	# <CJK>
0xE748	0x6D29	0x8E2A	# <CJK>
0xE749	0x6D2A	0x8E63	# <CJK>
0xE74A	0x6D2B	0x8E55	# <CJK>
0xE74B	0x6D2C	0x8E76	# <CJK>
0xE74C	0x6D2D	0x8E72	# <CJK>
0xE74D	0x6D2E	0x8E7C	# <CJK>
0xE74E	0x6D2F	0x8E81	# <CJK>
0xE74F	0x6D30	0x8E87	# <CJK>
0xE750	0x6D31	0x8E85	# <CJK>
0xE751	0x6D32	0x8E84	# <CJK>
0xE752	0x6D33	0x8E8B	# <CJK>
0xE753	0x6D34	0x8E8A	# <CJK>
0xE754	0x6D35	0x8E93	# <CJK>
0xE755	0x6D36	0x8E91	# <CJK>
0xE756	0x6D37	0x8E94	# <CJK>
0xE757	0x6D38	0x8E99	# <CJK>
0xE758	0x6D39	0x8EAA	# <CJK>
0xE759	0x6D3A	0x8EA1	# <CJK>
0xE75A	0x6D3B	0x8EAC	# <CJK>
0xE75B	0x6D3C	0x8EB0	# <CJK>
0xE75C	0x6D3D	0x8EC6	# <CJK>
0xE75D	0x6D3E	0x8EB1	# <CJK>
0xE75E	0x6D3F	0x8EBE	# <CJK>
0xE75F	0x6D40	0x8EC5	# <CJK>
0xE760	0x6D41	0x8EC8	# <CJK>
0xE761	0x6D42	0x8ECB	# <CJK>
0xE762	0x6D43	0x8EDB	# <CJK>
0xE763	0x6D44	0x8EE3	# <CJK>
0xE764	0x6D45	0x8EFC	# <CJK>
0xE765	0x6D46	0x8EFB	# <CJK>
0xE766	0x6D47	0x8EEB	# <CJK>
0xE767	0x6D48	0x8EFE	# <CJK>
0xE768	0x6D49	0x8F0A	# <CJK>
0xE769	0x6D4A	0x8F05	# <CJK>
0xE76A	0x6D4B	0x8F15	# <CJK>
0xE76B	0x6D4C	0x8F12	# <CJK>
0xE76C	0x6D4D	0x8F19	# <CJK>
0xE76D	0x6D4E	0x8F13	# <CJK>
0xE76E	0x6D4F	0x8F1C	# <CJK>
0xE76F	0x6D50	0x8F1F	# <CJK>
0xE770	0x6D51	0x8F1B	# <CJK>
0xE771	0x6D52	0x8F0C	# <CJK>
0xE772	0x6D53	0x8F26	# <CJK>
0xE773	0x6D54	0x8F33	# <CJK>
0xE774	0x6D55	0x8F3B	# <CJK>
0xE775	0x6D56	0x8F39	# <CJK>
0xE776	0x6D57	0x8F45	# <CJK>
0xE777	0x6D58	0x8F42	# <CJK>
0xE778	0x6D59	0x8F3E	# <CJK>
0xE779	0x6D5A	0x8F4C	# <CJK>
0xE77A	0x6D5B	0x8F49	# <CJK>
0xE77B	0x6D5C	0x8F46	# <CJK>
0xE77C	0x6D5D	0x8F4E	# <CJK>
0xE77D	0x6D5E	0x8F57	# <CJK>
0xE77E	0x6D5F	0x8F5C	# <CJK>
0xE780	0x6D60	0x8F62	# <CJK>
0xE781	0x6D61	0x8F63	# <CJK>
0xE782	0x6D62	0x8F64	# <CJK>
0xE783	0x6D63	0x8F9C	# <CJK>
0xE784	0x6D64	0x8F9F	# <CJK>
0xE785	0x6D65	0x8FA3	# <CJK>
0xE786	0x6D66	0x8FAD	# <CJK>
0xE787	0x6D67	0x8FAF	# <CJK>
0xE788	0x6D68	0x8FB7	# <CJK>
0xE789	0x6D69	0x8FDA	# <CJK>
0xE78A	0x6D6A	0x8FE5	# <CJK>
0xE78B	0x6D6B	0x8FE2	# <CJK>
0xE78C	0x6D6C	0x8FEA	# <CJK>
0xE78D	0x6D6D	0x8FEF	# <CJK>
0xE78E	0x6D6E	0x9087	# <CJK>
0xE78F	0x6D6F	0x8FF4	# <CJK>
0xE790	0x6D70	0x9005	# <CJK>
0xE791	0x6D71	0x8FF9	# <CJK>
0xE792	0x6D72	0x8FFA	# <CJK>
0xE793	0x6D73	0x9011	# <CJK>
0xE794	0x6D74	0x9015	# <CJK>
0xE795	0x6D75	0x9021	# <CJK>
0xE796	0x6D76	0x900D	# <CJK>
0xE797	0x6D77	0x901E	# <CJK>
0xE798	0x6D78	0x9016	# <CJK>
0xE799	0x6D79	0x900B	# <CJK>
0xE79A	0x6D7A	0x9027	# <CJK>
0xE79B	0x6D7B	0x9036	# <CJK>
0xE79C	0x6D7C	0x9035	# <CJK>
0xE79D	0x6D7D	0x9039	# <CJK>
0xE79E	0x6D7E	0x8FF8	# <CJK>
0xE79F	0x6E21	0x904F	# <CJK>
0xE7A0	0x6E22	0x9050	# <CJK>
0xE7A1	0x6E23	0x9051	# <CJK>
0xE7A2	0x6E24	0x9052	# <CJK>
0xE7A3	0x6E25	0x900E	# <CJK>
0xE7A4	0x6E26	0x9049	# <CJK>
0xE7A5	0x6E27	0x903E	# <CJK>
0xE7A6	0x6E28	0x9056	# <CJK>
0xE7A7	0x6E29	0x9058	# <CJK>
0xE7A8	0x6E2A	0x905E	# <CJK>
0xE7A9	0x6E2B	0x9068	# <CJK>
0xE7AA	0x6E2C	0x906F	# <CJK>
0xE7AB	0x6E2D	0x9076	# <CJK>
0xE7AC	0x6E2E	0x96A8	# <CJK>
0xE7AD	0x6E2F	0x9072	# <CJK>
0xE7AE	0x6E30	0x9082	# <CJK>
0xE7AF	0x6E31	0x907D	# <CJK>
0xE7B0	0x6E32	0x9081	# <CJK>
0xE7B1	0x6E33	0x9080	# <CJK>
0xE7B2	0x6E34	0x908A	# <CJK>
0xE7B3	0x6E35	0x9089	# <CJK>
0xE7B4	0x6E36	0x908F	# <CJK>
0xE7B5	0x6E37	0x90A8	# <CJK>
0xE7B6	0x6E38	0x90AF	# <CJK>
0xE7B7	0x6E39	0x90B1	# <CJK>
0xE7B8	0x6E3A	0x90B5	# <CJK>
0xE7B9	0x6E3B	0x90E2	# <CJK>
0xE7BA	0x6E3C	0x90E4	# <CJK>
0xE7BB	0x6E3D	0x6248	# <CJK>
0xE7BC	0x6E3E	0x90DB	# <CJK>
0xE7BD	0x6E3F	0x9102	# <CJK>
0xE7BE	0x6E40	0x9112	# <CJK>
0xE7BF	0x6E41	0x9119	# <CJK>
0xE7C0	0x6E42	0x9132	# <CJK>
0xE7C1	0x6E43	0x9130	# <CJK>
0xE7C2	0x6E44	0x914A	# <CJK>
0xE7C3	0x6E45	0x9156	# <CJK>
0xE7C4	0x6E46	0x9158	# <CJK>
0xE7C5	0x6E47	0x9163	# <CJK>
0xE7C6	0x6E48	0x9165	# <CJK>
0xE7C7	0x6E49	0x9169	# <CJK>
0xE7C8	0x6E4A	0x9173	# <CJK>
0xE7C9	0x6E4B	0x9172	# <CJK>
0xE7CA	0x6E4C	0x918B	# <CJK>
0xE7CB	0x6E4D	0x9189	# <CJK>
0xE7CC	0x6E4E	0x9182	# <CJK>
0xE7CD	0x6E4F	0x91A2	# <CJK>
0xE7CE	0x6E50	0x91AB	# <CJK>
0xE7CF	0x6E51	0x91AF	# <CJK>
0xE7D0	0x6E52	0x91AA	# <CJK>
0xE7D1	0x6E53	0x91B5	# <CJK>
0xE7D2	0x6E54	0x91B4	# <CJK>
0xE7D3	0x6E55	0x91BA	# <CJK>
0xE7D4	0x6E56	0x91C0	# <CJK>
0xE7D5	0x6E57	0x91C1	# <CJK>
0xE7D6	0x6E58	0x91C9	# <CJK>
0xE7D7	0x6E59	0x91CB	# <CJK>
0xE7D8	0x6E5A	0x91D0	# <CJK>
0xE7D9	0x6E5B	0x91D6	# <CJK>
0xE7DA	0x6E5C	0x91DF	# <CJK>
0xE7DB	0x6E5D	0x91E1	# <CJK>
0xE7DC	0x6E5E	0x91DB	# <CJK>
0xE7DD	0x6E5F	0x91FC	# <CJK>
0xE7DE	0x6E60	0x91F5	# <CJK>
0xE7DF	0x6E61	0x91F6	# <CJK>
0xE7E0	0x6E62	0x921E	# <CJK>
0xE7E1	0x6E63	0x91FF	# <CJK>
0xE7E2	0x6E64	0x9214	# <CJK>
0xE7E3	0x6E65	0x922C	# <CJK>
0xE7E4	0x6E66	0x9215	# <CJK>
0xE7E5	0x6E67	0x9211	# <CJK>
0xE7E6	0x6E68	0x925E	# <CJK>
0xE7E7	0x6E69	0x9257	# <CJK>
0xE7E8	0x6E6A	0x9245	# <CJK>
0xE7E9	0x6E6B	0x9249	# <CJK>
0xE7EA	0x6E6C	0x9264	# <CJK>
0xE7EB	0x6E6D	0x9248	# <CJK>
0xE7EC	0x6E6E	0x9295	# <CJK>
0xE7ED	0x6E6F	0x923F	# <CJK>
0xE7EE	0x6E70	0x924B	# <CJK>
0xE7EF	0x6E71	0x9250	# <CJK>
0xE7F0	0x6E72	0x929C	# <CJK>
0xE7F1	0x6E73	0x9296	# <CJK>
0xE7F2	0x6E74	0x9293	# <CJK>
0xE7F3	0x6E75	0x929B	# <CJK>
0xE7F4	0x6E76	0x925A	# <CJK>
0xE7F5	0x6E77	0x92CF	# <CJK>
0xE7F6	0x6E78	0x92B9	# <CJK>
0xE7F7	0x6E79	0x92B7	# <CJK>
0xE7F8	0x6E7A	0x92E9	# <CJK>
0xE7F9	0x6E7B	0x930F	# <CJK>
0xE7FA	0x6E7C	0x92FA	# <CJK>
0xE7FB	0x6E7D	0x9344	# <CJK>
0xE7FC	0x6E7E	0x932E	# <CJK>
0xE840	0x6F21	0x9319	# <CJK>
0xE841	0x6F22	0x9322	# <CJK>
0xE842	0x6F23	0x931A	# <CJK>
0xE843	0x6F24	0x9323	# <CJK>
0xE844	0x6F25	0x933A	# <CJK>
0xE845	0x6F26	0x9335	# <CJK>
0xE846	0x6F27	0x933B	# <CJK>
0xE847	0x6F28	0x935C	# <CJK>
0xE848	0x6F29	0x9360	# <CJK>
0xE849	0x6F2A	0x937C	# <CJK>
0xE84A	0x6F2B	0x936E	# <CJK>
0xE84B	0x6F2C	0x9356	# <CJK>
0xE84C	0x6F2D	0x93B0	# <CJK>
0xE84D	0x6F2E	0x93AC	# <CJK>
0xE84E	0x6F2F	0x93AD	# <CJK>
0xE84F	0x6F30	0x9394	# <CJK>
0xE850	0x6F31	0x93B9	# <CJK>
0xE851	0x6F32	0x93D6	# <CJK>
0xE852	0x6F33	0x93D7	# <CJK>
0xE853	0x6F34	0x93E8	# <CJK>
0xE854	0x6F35	0x93E5	# <CJK>
0xE855	0x6F36	0x93D8	# <CJK>
0xE856	0x6F37	0x93C3	# <CJK>
0xE857	0x6F38	0x93DD	# <CJK>
0xE858	0x6F39	0x93D0	# <CJK>
0xE859	0x6F3A	0x93C8	# <CJK>
0xE85A	0x6F3B	0x93E4	# <CJK>
0xE85B	0x6F3C	0x941A	# <CJK>
0xE85C	0x6F3D	0x9414	# <CJK>
0xE85D	0x6F3E	0x9413	# <CJK>
0xE85E	0x6F3F	0x9403	# <CJK>
0xE85F	0x6F40	0x9407	# <CJK>
0xE860	0x6F41	0x9410	# <CJK>
0xE861	0x6F42	0x9436	# <CJK>
0xE862	0x6F43	0x942B	# <CJK>
0xE863	0x6F44	0x9435	# <CJK>
0xE864	0x6F45	0x9421	# <CJK>
0xE865	0x6F46	0x943A	# <CJK>
0xE866	0x6F47	0x9441	# <CJK>
0xE867	0x6F48	0x9452	# <CJK>
0xE868	0x6F49	0x9444	# <CJK>
0xE869	0x6F4A	0x945B	# <CJK>
0xE86A	0x6F4B	0x9460	# <CJK>
0xE86B	0x6F4C	0x9462	# <CJK>
0xE86C	0x6F4D	0x945E	# <CJK>
0xE86D	0x6F4E	0x946A	# <CJK>
0xE86E	0x6F4F	0x9229	# <CJK>
0xE86F	0x6F50	0x9470	# <CJK>
0xE870	0x6F51	0x9475	# <CJK>
0xE871	0x6F52	0x9477	# <CJK>
0xE872	0x6F53	0x947D	# <CJK>
0xE873	0x6F54	0x945A	# <CJK>
0xE874	0x6F55	0x947C	# <CJK>
0xE875	0x6F56	0x947E	# <CJK>
0xE876	0x6F57	0x9481	# <CJK>
0xE877	0x6F58	0x947F	# <CJK>
0xE878	0x6F59	0x9582	# <CJK>
0xE879	0x6F5A	0x9587	# <CJK>
0xE87A	0x6F5B	0x958A	# <CJK>
0xE87B	0x6F5C	0x9594	# <CJK>
0xE87C	0x6F5D	0x9596	# <CJK>
0xE87D	0x6F5E	0x9598	# <CJK>
0xE87E	0x6F5F	0x9599	# <CJK>
0xE880	0x6F60	0x95A0	# <CJK>
0xE881	0x6F61	0x95A8	# <CJK>
0xE882	0x6F62	0x95A7	# <CJK>
0xE883	0x6F63	0x95AD	# <CJK>
0xE884	0x6F64	0x95BC	# <CJK>
0xE885	0x6F65	0x95BB	# <CJK>
0xE886	0x6F66	0x95B9	# <CJK>
0xE887	0x6F67	0x95BE	# <CJK>
0xE888	0x6F68	0x95CA	# <CJK>
0xE889	0x6F69	0x6FF6	# <CJK>
0xE88A	0x6F6A	0x95C3	# <CJK>
0xE88B	0x6F6B	0x95CD	# <CJK>
0xE88C	0x6F6C	0x95CC	# <CJK>
0xE88D	0x6F6D	0x95D5	# <CJK>
0xE88E	0x6F6E	0x95D4	# <CJK>
0xE88F	0x6F6F	0x95D6	# <CJK>
0xE890	0x6F70	0x95DC	# <CJK>
0xE891	0x6F71	0x95E1	# <CJK>
0xE892	0x6F72	0x95E5	# <CJK>
0xE893	0x6F73	0x95E2	# <CJK>
0xE894	0x6F74	0x9621	# <CJK>
0xE895	0x6F75	0x9628	# <CJK>
0xE896	0x6F76	0x962E	# <CJK>
0xE897	0x6F77	0x962F	# <CJK>
0xE898	0x6F78	0x9642	# <CJK>
0xE899	0x6F79	0x964C	# <CJK>
0xE89A	0x6F7A	0x964F	# <CJK>
0xE89B	0x6F7B	0x964B	# <CJK>
0xE89C	0x6F7C	0x9677	# <CJK>
0xE89D	0x6F7D	0x965C	# <CJK>
0xE89E	0x6F7E	0x965E	# <CJK>
0xE89F	0x7021	0x965D	# <CJK>
0xE8A0	0x7022	0x965F	# <CJK>
0xE8A1	0x7023	0x9666	# <CJK>
0xE8A2	0x7024	0x9672	# <CJK>
0xE8A3	0x7025	0x966C	# <CJK>
0xE8A4	0x7026	0x968D	# <CJK>
0xE8A5	0x7027	0x9698	# <CJK>
0xE8A6	0x7028	0x9695	# <CJK>
0xE8A7	0x7029	0x9697	# <CJK>
0xE8A8	0x702A	0x96AA	# <CJK>
0xE8A9	0x702B	0x96A7	# <CJK>
0xE8AA	0x702C	0x96B1	# <CJK>
0xE8AB	0x702D	0x96B2	# <CJK>
0xE8AC	0x702E	0x96B0	# <CJK>
0xE8AD	0x702F	0x96B4	# <CJK>
0xE8AE	0x7030	0x96B6	# <CJK>
0xE8AF	0x7031	0x96B8	# <CJK>
0xE8B0	0x7032	0x96B9	# <CJK>
0xE8B1	0x7033	0x96CE	# <CJK>
0xE8B2	0x7034	0x96CB	# <CJK>
0xE8B3	0x7035	0x96C9	# <CJK>
0xE8B4	0x7036	0x96CD	# <CJK>
0xE8B5	0x7037	0x894D	# <CJK>
0xE8B6	0x7038	0x96DC	# <CJK>
0xE8B7	0x7039	0x970D	# <CJK>
0xE8B8	0x703A	0x96D5	# <CJK>
0xE8B9	0x703B	0x96F9	# <CJK>
0xE8BA	0x703C	0x9704	# <CJK>
0xE8BB	0x703D	0x9706	# <CJK>
0xE8BC	0x703E	0x9708	# <CJK>
0xE8BD	0x703F	0x9713	# <CJK>
0xE8BE	0x7040	0x970E	# <CJK>
0xE8BF	0x7041	0x9711	# <CJK>
0xE8C0	0x7042	0x970F	# <CJK>
0xE8C1	0x7043	0x9716	# <CJK>
0xE8C2	0x7044	0x9719	# <CJK>
0xE8C3	0x7045	0x9724	# <CJK>
0xE8C4	0x7046	0x972A	# <CJK>
0xE8C5	0x7047	0x9730	# <CJK>
0xE8C6	0x7048	0x9739	# <CJK>
0xE8C7	0x7049	0x973D	# <CJK>
0xE8C8	0x704A	0x973E	# <CJK>
0xE8C9	0x704B	0x9744	# <CJK>
0xE8CA	0x704C	0x9746	# <CJK>
0xE8CB	0x704D	0x9748	# <CJK>
0xE8CC	0x704E	0x9742	# <CJK>
0xE8CD	0x704F	0x9749	# <CJK>
0xE8CE	0x7050	0x975C	# <CJK>
0xE8CF	0x7051	0x9760	# <CJK>
0xE8D0	0x7052	0x9764	# <CJK>
0xE8D1	0x7053	0x9766	# <CJK>
0xE8D2	0x7054	0x9768	# <CJK>
0xE8D3	0x7055	0x52D2	# <CJK>
0xE8D4	0x7056	0x976B	# <CJK>
0xE8D5	0x7057	0x9771	# <CJK>
0xE8D6	0x7058	0x9779	# <CJK>
0xE8D7	0x7059	0x9785	# <CJK>
0xE8D8	0x705A	0x977C	# <CJK>
0xE8D9	0x705B	0x9781	# <CJK>
0xE8DA	0x705C	0x977A	# <CJK>
0xE8DB	0x705D	0x9786	# <CJK>
0xE8DC	0x705E	0x978B	# <CJK>
0xE8DD	0x705F	0x978F	# <CJK>
0xE8DE	0x7060	0x9790	# <CJK>
0xE8DF	0x7061	0x979C	# <CJK>
0xE8E0	0x7062	0x97A8	# <CJK>
0xE8E1	0x7063	0x97A6	# <CJK>
0xE8E2	0x7064	0x97A3	# <CJK>
0xE8E3	0x7065	0x97B3	# <CJK>
0xE8E4	0x7066	0x97B4	# <CJK>
0xE8E5	0x7067	0x97C3	# <CJK>
0xE8E6	0x7068	0x97C6	# <CJK>
0xE8E7	0x7069	0x97C8	# <CJK>
0xE8E8	0x706A	0x97CB	# <CJK>
0xE8E9	0x706B	0x97DC	# <CJK>
0xE8EA	0x706C	0x97ED	# <CJK>
0xE8EB	0x706D	0x9F4F	# <CJK>
0xE8EC	0x706E	0x97F2	# <CJK>
0xE8ED	0x706F	0x7ADF	# <CJK>
0xE8EE	0x7070	0x97F6	# <CJK>
0xE8EF	0x7071	0x97F5	# <CJK>
0xE8F0	0x7072	0x980F	# <CJK>
0xE8F1	0x7073	0x980C	# <CJK>
0xE8F2	0x7074	0x9838	# <CJK>
0xE8F3	0x7075	0x9824	# <CJK>
0xE8F4	0x7076	0x9821	# <CJK>
0xE8F5	0x7077	0x9837	# <CJK>
0xE8F6	0x7078	0x983D	# <CJK>
0xE8F7	0x7079	0x9846	# <CJK>
0xE8F8	0x707A	0x984F	# <CJK>
0xE8F9	0x707B	0x984B	# <CJK>
0xE8FA	0x707C	0x986B	# <CJK>
0xE8FB	0x707D	0x986F	# <CJK>
0xE8FC	0x707E	0x9870	# <CJK>
0xE940	0x7121	0x9871	# <CJK>
0xE941	0x7122	0x9874	# <CJK>
0xE942	0x7123	0x9873	# <CJK>
0xE943	0x7124	0x98AA	# <CJK>
0xE944	0x7125	0x98AF	# <CJK>
0xE945	0x7126	0x98B1	# <CJK>
0xE946	0x7127	0x98B6	# <CJK>
0xE947	0x7128	0x98C4	# <CJK>
0xE948	0x7129	0x98C3	# <CJK>
0xE949	0x712A	0x98C6	# <CJK>
0xE94A	0x712B	0x98E9	# <CJK>
0xE94B	0x712C	0x98EB	# <CJK>
0xE94C	0x712D	0x9903	# <CJK>
0xE94D	0x712E	0x9909	# <CJK>
0xE94E	0x712F	0x9912	# <CJK>
0xE94F	0x7130	0x9914	# <CJK>
0xE950	0x7131	0x9918	# <CJK>
0xE951	0x7132	0x9921	# <CJK>
0xE952	0x7133	0x991D	# <CJK>
0xE953	0x7134	0x991E	# <CJK>
0xE954	0x7135	0x9924	# <CJK>
0xE955	0x7136	0x9920	# <CJK>
0xE956	0x7137	0x992C	# <CJK>
0xE957	0x7138	0x992E	# <CJK>
0xE958	0x7139	0x993D	# <CJK>
0xE959	0x713A	0x993E	# <CJK>
0xE95A	0x713B	0x9942	# <CJK>
0xE95B	0x713C	0x9949	# <CJK>
0xE95C	0x713D	0x9945	# <CJK>
0xE95D	0x713E	0x9950	# <CJK>
0xE95E	0x713F	0x994B	# <CJK>
0xE95F	0x7140	0x9951	# <CJK>
0xE960	0x7141	0x9952	# <CJK>
0xE961	0x7142	0x994C	# <CJK>
0xE962	0x7143	0x9955	# <CJK>
0xE963	0x7144	0x9997	# <CJK>
0xE964	0x7145	0x9998	# <CJK>
0xE965	0x7146	0x99A5	# <CJK>
0xE966	0x7147	0x99AD	# <CJK>
0xE967	0x7148	0x99AE	# <CJK>
0xE968	0x7149	0x99BC	# <CJK>
0xE969	0x714A	0x99DF	# <CJK>
0xE96A	0x714B	0x99DB	# <CJK>
0xE96B	0x714C	0x99DD	# <CJK>
0xE96C	0x714D	0x99D8	# <CJK>
0xE96D	0x714E	0x99D1	# <CJK>
0xE96E	0x714F	0x99ED	# <CJK>
0xE96F	0x7150	0x99EE	# <CJK>
0xE970	0x7151	0x99F1	# <CJK>
0xE971	0x7152	0x99F2	# <CJK>
0xE972	0x7153	0x99FB	# <CJK>
0xE973	0x7154	0x99F8	# <CJK>
0xE974	0x7155	0x9A01	# <CJK>
0xE975	0x7156	0x9A0F	# <CJK>
0xE976	0x7157	0x9A05	# <CJK>
0xE977	0x7158	0x99E2	# <CJK>
0xE978	0x7159	0x9A19	# <CJK>
0xE979	0x715A	0x9A2B	# <CJK>
0xE97A	0x715B	0x9A37	# <CJK>
0xE97B	0x715C	0x9A45	# <CJK>
0xE97C	0x715D	0x9A42	# <CJK>
0xE97D	0x715E	0x9A40	# <CJK>
0xE97E	0x715F	0x9A43	# <CJK>
0xE980	0x7160	0x9A3E	# <CJK>
0xE981	0x7161	0x9A55	# <CJK>
0xE982	0x7162	0x9A4D	# <CJK>
0xE983	0x7163	0x9A5B	# <CJK>
0xE984	0x7164	0x9A57	# <CJK>
0xE985	0x7165	0x9A5F	# <CJK>
0xE986	0x7166	0x9A62	# <CJK>
0xE987	0x7167	0x9A65	# <CJK>
0xE988	0x7168	0x9A64	# <CJK>
0xE989	0x7169	0x9A69	# <CJK>
0xE98A	0x716A	0x9A6B	# <CJK>
0xE98B	0x716B	0x9A6A	# <CJK>
0xE98C	0x716C	0x9AAD	# <CJK>
0xE98D	0x716D	0x9AB0	# <CJK>
0xE98E	0x716E	0x9ABC	# <CJK>
0xE98F	0x716F	0x9AC0	# <CJK>
0xE990	0x7170	0x9ACF	# <CJK>
0xE991	0x7171	0x9AD1	# <CJK>
0xE992	0x7172	0x9AD3	# <CJK>
0xE993	0x7173	0x9AD4	# <CJK>
0xE994	0x7174	0x9ADE	# <CJK>
0xE995	0x7175	0x9ADF	# <CJK>
0xE996	0x7176	0x9AE2	# <CJK>
0xE997	0x7177	0x9AE3	# <CJK>
0xE998	0x7178	0x9AE6	# <CJK>
0xE999	0x7179	0x9AEF	# <CJK>
0xE99A	0x717A	0x9AEB	# <CJK>
0xE99B	0x717B	0x9AEE	# <CJK>
0xE99C	0x717C	0x9AF4	# <CJK>
0xE99D	0x717D	0x9AF1	# <CJK>
0xE99E	0x717E	0x9AF7	# <CJK>
0xE99F	0x7221	0x9AFB	# <CJK>
0xE9A0	0x7222	0x9B06	# <CJK>
0xE9A1	0x7223	0x9B18	# <CJK>
0xE9A2	0x7224	0x9B1A	# <CJK>
0xE9A3	0x7225	0x9B1F	# <CJK>
0xE9A4	0x7226	0x9B22	# <CJK>
0xE9A5	0x7227	0x9B23	# <CJK>
0xE9A6	0x7228	0x9B25	# <CJK>
0xE9A7	0x7229	0x9B27	# <CJK>
0xE9A8	0x722A	0x9B28	# <CJK>
0xE9A9	0x722B	0x9B29	# <CJK>
0xE9AA	0x722C	0x9B2A	# <CJK>
0xE9AB	0x722D	0x9B2E	# <CJK>
0xE9AC	0x722E	0x9B2F	# <CJK>
0xE9AD	0x722F	0x9B32	# <CJK>
0xE9AE	0x7230	0x9B44	# <CJK>
0xE9AF	0x7231	0x9B43	# <CJK>
0xE9B0	0x7232	0x9B4F	# <CJK>
0xE9B1	0x7233	0x9B4D	# <CJK>
0xE9B2	0x7234	0x9B4E	# <CJK>
0xE9B3	0x7235	0x9B51	# <CJK>
0xE9B4	0x7236	0x9B58	# <CJK>
0xE9B5	0x7237	0x9B74	# <CJK>
0xE9B6	0x7238	0x9B93	# <CJK>
0xE9B7	0x7239	0x9B83	# <CJK>
0xE9B8	0x723A	0x9B91	# <CJK>
0xE9B9	0x723B	0x9B96	# <CJK>
0xE9BA	0x723C	0x9B97	# <CJK>
0xE9BB	0x723D	0x9B9F	# <CJK>
0xE9BC	0x723E	0x9BA0	# <CJK>
0xE9BD	0x723F	0x9BA8	# <CJK>
0xE9BE	0x7240	0x9BB4	# <CJK>
0xE9BF	0x7241	0x9BC0	# <CJK>
0xE9C0	0x7242	0x9BCA	# <CJK>
0xE9C1	0x7243	0x9BB9	# <CJK>
0xE9C2	0x7244	0x9BC6	# <CJK>
0xE9C3	0x7245	0x9BCF	# <CJK>
0xE9C4	0x7246	0x9BD1	# <CJK>
0xE9C5	0x7247	0x9BD2	# <CJK>
0xE9C6	0x7248	0x9BE3	# <CJK>
0xE9C7	0x7249	0x9BE2	# <CJK>
0xE9C8	0x724A	0x9BE4	# <CJK>
0xE9C9	0x724B	0x9BD4	# <CJK>
0xE9CA	0x724C	0x9BE1	# <CJK>
0xE9CB	0x724D	0x9C3A	# <CJK>
0xE9CC	0x724E	0x9BF2	# <CJK>
0xE9CD	0x724F	0x9BF1	# <CJK>
0xE9CE	0x7250	0x9BF0	# <CJK>
0xE9CF	0x7251	0x9C15	# <CJK>
0xE9D0	0x7252	0x9C14	# <CJK>
0xE9D1	0x7253	0x9C09	# <CJK>
0xE9D2	0x7254	0x9C13	# <CJK>
0xE9D3	0x7255	0x9C0C	# <CJK>
0xE9D4	0x7256	0x9C06	# <CJK>
0xE9D5	0x7257	0x9C08	# <CJK>
0xE9D6	0x7258	0x9C12	# <CJK>
0xE9D7	0x7259	0x9C0A	# <CJK>
0xE9D8	0x725A	0x9C04	# <CJK>
0xE9D9	0x725B	0x9C2E	# <CJK>
0xE9DA	0x725C	0x9C1B	# <CJK>
0xE9DB	0x725D	0x9C25	# <CJK>
0xE9DC	0x725E	0x9C24	# <CJK>
0xE9DD	0x725F	0x9C21	# <CJK>
0xE9DE	0x7260	0x9C30	# <CJK>
0xE9DF	0x7261	0x9C47	# <CJK>
0xE9E0	0x7262	0x9C32	# <CJK>
0xE9E1	0x7263	0x9C46	# <CJK>
0xE9E2	0x7264	0x9C3E	# <CJK>
0xE9E3	0x7265	0x9C5A	# <CJK>
0xE9E4	0x7266	0x9C60	# <CJK>
0xE9E5	0x7267	0x9C67	# <CJK>
0xE9E6	0x7268	0x9C76	# <CJK>
0xE9E7	0x7269	0x9C78	# <CJK>
0xE9E8	0x726A	0x9CE7	# <CJK>
0xE9E9	0x726B	0x9CEC	# <CJK>
0xE9EA	0x726C	0x9CF0	# <CJK>
0xE9EB	0x726D	0x9D09	# <CJK>
0xE9EC	0x726E	0x9D08	# <CJK>
0xE9ED	0x726F	0x9CEB	# <CJK>
0xE9EE	0x7270	0x9D03	# <CJK>
0xE9EF	0x7271	0x9D06	# <CJK>
0xE9F0	0x7272	0x9D2A	# <CJK>
0xE9F1	0x7273	0x9D26	# <CJK>
0xE9F2	0x7274	0x9DAF	# <CJK>
0xE9F3	0x7275	0x9D23	# <CJK>
0xE9F4	0x7276	0x9D1F	# <CJK>
0xE9F5	0x7277	0x9D44	# <CJK>
0xE9F6	0x7278	0x9D15	# <CJK>
0xE9F7	0x7279	0x9D12	# <CJK>
0xE9F8	0x727A	0x9D41	# <CJK>
0xE9F9	0x727B	0x9D3F	# <CJK>
0xE9FA	0x727C	0x9D3E	# <CJK>
0xE9FB	0x727D	0x9D46	# <CJK>
0xE9FC	0x727E	0x9D48	# <CJK>
0xEA40	0x7321	0x9D5D	# <CJK>
0xEA41	0x7322	0x9D5E	# <CJK>
0xEA42	0x7323	0x9D64	# <CJK>
0xEA43	0x7324	0x9D51	# <CJK>
0xEA44	0x7325	0x9D50	# <CJK>
0xEA45	0x7326	0x9D59	# <CJK>
0xEA46	0x7327	0x9D72	# <CJK>
0xEA47	0x7328	0x9D89	# <CJK>
0xEA48	0x7329	0x9D87	# <CJK>
0xEA49	0x732A	0x9DAB	# <CJK>
0xEA4A	0x732B	0x9D6F	# <CJK>
0xEA4B	0x732C	0x9D7A	# <CJK>
0xEA4C	0x732D	0x9D9A	# <CJK>
0xEA4D	0x732E	0x9DA4	# <CJK>
0xEA4E	0x732F	0x9DA9	# <CJK>
0xEA4F	0x7330	0x9DB2	# <CJK>
0xEA50	0x7331	0x9DC4	# <CJK>
0xEA51	0x7332	0x9DC1	# <CJK>
0xEA52	0x7333	0x9DBB	# <CJK>
0xEA53	0x7334	0x9DB8	# <CJK>
0xEA54	0x7335	0x9DBA	# <CJK>
0xEA55	0x7336	0x9DC6	# <CJK>
0xEA56	0x7337	0x9DCF	# <CJK>
0xEA57	0x7338	0x9DC2	# <CJK>
0xEA58	0x7339	0x9DD9	# <CJK>
0xEA59	0x733A	0x9DD3	# <CJK>
0xEA5A	0x733B	0x9DF8	# <CJK>
0xEA5B	0x733C	0x9DE6	# <CJK>
0xEA5C	0x733D	0x9DED	# <CJK>
0xEA5D	0x733E	0x9DEF	# <CJK>
0xEA5E	0x733F	0x9DFD	# <CJK>
0xEA5F	0x7340	0x9E1A	# <CJK>
0xEA60	0x7341	0x9E1B	# <CJK>
0xEA61	0x7342	0x9E1E	# <CJK>
0xEA62	0x7343	0x9E75	# <CJK>
0xEA63	0x7344	0x9E79	# <CJK>
0xEA64	0x7345	0x9E7D	# <CJK>
0xEA65	0x7346	0x9E81	# <CJK>
0xEA66	0x7347	0x9E88	# <CJK>
0xEA67	0x7348	0x9E8B	# <CJK>
0xEA68	0x7349	0x9E8C	# <CJK>
0xEA69	0x734A	0x9E92	# <CJK>
0xEA6A	0x734B	0x9E95	# <CJK>
0xEA6B	0x734C	0x9E91	# <CJK>
0xEA6C	0x734D	0x9E9D	# <CJK>
0xEA6D	0x734E	0x9EA5	# <CJK>
0xEA6E	0x734F	0x9EA9	# <CJK>
0xEA6F	0x7350	0x9EB8	# <CJK>
0xEA70	0x7351	0x9EAA	# <CJK>
0xEA71	0x7352	0x9EAD	# <CJK>
0xEA72	0x7353	0x9761	# <CJK>
0xEA73	0x7354	0x9ECC	# <CJK>
0xEA74	0x7355	0x9ECE	# <CJK>
0xEA75	0x7356	0x9ECF	# <CJK>
0xEA76	0x7357	0x9ED0	# <CJK>
0xEA77	0x7358	0x9ED4	# <CJK>
0xEA78	0x7359	0x9EDC	# <CJK>
0xEA79	0x735A	0x9EDE	# <CJK>
0xEA7A	0x735B	0x9EDD	# <CJK>
0xEA7B	0x735C	0x9EE0	# <CJK>
0xEA7C	0x735D	0x9EE5	# <CJK>
0xEA7D	0x735E	0x9EE8	# <CJK>
0xEA7E	0x735F	0x9EEF	# <CJK>
0xEA80	0x7360	0x9EF4	# <CJK>
0xEA81	0x7361	0x9EF6	# <CJK>
0xEA82	0x7362	0x9EF7	# <CJK>
0xEA83	0x7363	0x9EF9	# <CJK>
0xEA84	0x7364	0x9EFB	# <CJK>
0xEA85	0x7365	0x9EFC	# <CJK>
0xEA86	0x7366	0x9EFD	# <CJK>
0xEA87	0x7367	0x9F07	# <CJK>
0xEA88	0x7368	0x9F08	# <CJK>
0xEA89	0x7369	0x76B7	# <CJK>
0xEA8A	0x736A	0x9F15	# <CJK>
0xEA8B	0x736B	0x9F21	# <CJK>
0xEA8C	0x736C	0x9F2C	# <CJK>
0xEA8D	0x736D	0x9F3E	# <CJK>
0xEA8E	0x736E	0x9F4A	# <CJK>
0xEA8F	0x736F	0x9F52	# <CJK>
0xEA90	0x7370	0x9F54	# <CJK>
0xEA91	0x7371	0x9F63	# <CJK>
0xEA92	0x7372	0x9F5F	# <CJK>
0xEA93	0x7373	0x9F60	# <CJK>
0xEA94	0x7374	0x9F61	# <CJK>
0xEA95	0x7375	0x9F66	# <CJK>
0xEA96	0x7376	0x9F67	# <CJK>
0xEA97	0x7377	0x9F6C	# <CJK>
0xEA98	0x7378	0x9F6A	# <CJK>
0xEA99	0x7379	0x9F77	# <CJK>
0xEA9A	0x737A	0x9F72	# <CJK>
0xEA9B	0x737B	0x9F76	# <CJK>
0xEA9C	0x737C	0x9F95	# <CJK>
0xEA9D	0x737D	0x9F9C	# <CJK>
0xEA9E	0x737E	0x9FA0	# <CJK>
0xEA9F	0x7421	0x582F	# <CJK>
0xEAA0	0x7422	0x69C7	# <CJK>
0xEAA1	0x7423	0x9059	# <CJK>
0xEAA2	0x7424	0x7464	# <CJK>
0xEAA3	0x7425	0x51DC	# <CJK>
0xEAA4	0x7426	0x7199	# <CJK>

Added tools/encoding/jis0212.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
#
#	Name:             JIS X 0212 (1990) to Unicode
#	Unicode version:  1.1
#	Table version:    0.9
#	Table format:     Format A
#	Date:             8 March 1994
#	Authors:          Glenn Adams <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       JIS X 0212 (1983) characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the JIS X 0212 code (in hex as 0xXXXX)
#		 Column #2 is the Unicode (in hex as 0xXXXX)
#		 Column #3 the Unicode name (follows a comment sign, '#')
#					The official names for Unicode characters U+4E00
#					to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
#					where XXXX is the code point.  Including all these
#					names in this file increases its size substantially
#					and needlessly.  The token "<CJK>" is used for the
#					name of these characters.  If necessary, it can be
#					expanded algorithmically by a parser or editor.
#
#	The entries are in JIS X 0212 order
#
#	The following algorithms can be used to change the hex form
#		of JIS 0212 to other standard forms:
#
#		To change hex to EUC form, add 0x8080
#		To change hex to kuten form, first subtract 0x2020.  Then
#			the high and low bytes correspond to the ku and ten of
#			the kuten form.  For example, 0x2121 -> 0x0101 -> 0101;
#			0x6D63 -> 0x4D43 -> 7767
#
#   The kanji mappings are a normative part of ISO/IEC 10646.  The
#       non-kanji mappings are provisional, pending definition of
#       official mappings by Japanese standards bodies
#
#	Any comments or problems, contact <[email protected]>
#
#	Notes:
#
#	1. JIS X 0212 apparently unified the following two symbols
#	   into a single character at 0x2922:
#	
#	   LATIN CAPITAL LETTER D WITH STROKE
#	   LATIN CAPITAL LETTER ETH
#
#	   However, JIS X 0212 maintains the distinction between
#	   the lowercase forms of these two elements at 0x2942 and 0x2943.
#	   Given the structre of these JIS encodings, it is clear that
#	   0x2922 and 0x2942 are intended to be a capital/small pair.
#	   Consequently, in the Unicode mapping, 0x2922 is treated as
#	   LATIN CAPITAL LETTER D WITH STROKE.
#	  
0x222F	0x02D8	# BREVE
0x2230	0x02C7	# CARON (Mandarin Chinese third tone)
0x2231	0x00B8	# CEDILLA
0x2232	0x02D9	# DOT ABOVE (Mandarin Chinese light tone)
0x2233	0x02DD	# DOUBLE ACUTE ACCENT
0x2234	0x00AF	# MACRON
0x2235	0x02DB	# OGONEK
0x2236	0x02DA	# RING ABOVE
0x2237	0x007E	# TILDE
0x2238	0x0384	# GREEK TONOS
0x2239	0x0385	# GREEK DIALYTIKA TONOS
0x2242	0x00A1	# INVERTED EXCLAMATION MARK
0x2243	0x00A6	# BROKEN BAR
0x2244	0x00BF	# INVERTED QUESTION MARK
0x226B	0x00BA	# MASCULINE ORDINAL INDICATOR
0x226C	0x00AA	# FEMININE ORDINAL INDICATOR
0x226D	0x00A9	# COPYRIGHT SIGN
0x226E	0x00AE	# REGISTERED SIGN
0x226F	0x2122	# TRADE MARK SIGN
0x2270	0x00A4	# CURRENCY SIGN
0x2271	0x2116	# NUMERO SIGN
0x2661	0x0386	# GREEK CAPITAL LETTER ALPHA WITH TONOS
0x2662	0x0388	# GREEK CAPITAL LETTER EPSILON WITH TONOS
0x2663	0x0389	# GREEK CAPITAL LETTER ETA WITH TONOS
0x2664	0x038A	# GREEK CAPITAL LETTER IOTA WITH TONOS
0x2665	0x03AA	# GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
0x2667	0x038C	# GREEK CAPITAL LETTER OMICRON WITH TONOS
0x2669	0x038E	# GREEK CAPITAL LETTER UPSILON WITH TONOS
0x266A	0x03AB	# GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
0x266C	0x038F	# GREEK CAPITAL LETTER OMEGA WITH TONOS
0x2671	0x03AC	# GREEK SMALL LETTER ALPHA WITH TONOS
0x2672	0x03AD	# GREEK SMALL LETTER EPSILON WITH TONOS
0x2673	0x03AE	# GREEK SMALL LETTER ETA WITH TONOS
0x2674	0x03AF	# GREEK SMALL LETTER IOTA WITH TONOS
0x2675	0x03CA	# GREEK SMALL LETTER IOTA WITH DIALYTIKA
0x2676	0x0390	# GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
0x2677	0x03CC	# GREEK SMALL LETTER OMICRON WITH TONOS
0x2678	0x03C2	# GREEK SMALL LETTER FINAL SIGMA
0x2679	0x03CD	# GREEK SMALL LETTER UPSILON WITH TONOS
0x267A	0x03CB	# GREEK SMALL LETTER UPSILON WITH DIALYTIKA
0x267B	0x03B0	# GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
0x267C	0x03CE	# GREEK SMALL LETTER OMEGA WITH TONOS
0x2742	0x0402	# CYRILLIC CAPITAL LETTER DJE
0x2743	0x0403	# CYRILLIC CAPITAL LETTER GJE
0x2744	0x0404	# CYRILLIC CAPITAL LETTER UKRAINIAN IE
0x2745	0x0405	# CYRILLIC CAPITAL LETTER DZE
0x2746	0x0406	# CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
0x2747	0x0407	# CYRILLIC CAPITAL LETTER YI
0x2748	0x0408	# CYRILLIC CAPITAL LETTER JE
0x2749	0x0409	# CYRILLIC CAPITAL LETTER LJE
0x274A	0x040A	# CYRILLIC CAPITAL LETTER NJE
0x274B	0x040B	# CYRILLIC CAPITAL LETTER TSHE
0x274C	0x040C	# CYRILLIC CAPITAL LETTER KJE
0x274D	0x040E	# CYRILLIC CAPITAL LETTER SHORT U
0x274E	0x040F	# CYRILLIC CAPITAL LETTER DZHE
0x2772	0x0452	# CYRILLIC SMALL LETTER DJE
0x2773	0x0453	# CYRILLIC SMALL LETTER GJE
0x2774	0x0454	# CYRILLIC SMALL LETTER UKRAINIAN IE
0x2775	0x0455	# CYRILLIC SMALL LETTER DZE
0x2776	0x0456	# CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
0x2777	0x0457	# CYRILLIC SMALL LETTER YI
0x2778	0x0458	# CYRILLIC SMALL LETTER JE
0x2779	0x0459	# CYRILLIC SMALL LETTER LJE
0x277A	0x045A	# CYRILLIC SMALL LETTER NJE
0x277B	0x045B	# CYRILLIC SMALL LETTER TSHE
0x277C	0x045C	# CYRILLIC SMALL LETTER KJE
0x277D	0x045E	# CYRILLIC SMALL LETTER SHORT U
0x277E	0x045F	# CYRILLIC SMALL LETTER DZHE
0x2921	0x00C6	# LATIN CAPITAL LIGATURE AE
0x2922	0x0110	# LATIN CAPITAL LETTER D WITH STROKE
0x2924	0x0126	# LATIN CAPITAL LETTER H WITH STROKE
0x2926	0x0132	# LATIN CAPITAL LIGATURE IJ
0x2928	0x0141	# LATIN CAPITAL LETTER L WITH STROKE
0x2929	0x013F	# LATIN CAPITAL LETTER L WITH MIDDLE DOT
0x292B	0x014A	# LATIN CAPITAL LETTER ENG
0x292C	0x00D8	# LATIN CAPITAL LETTER O WITH STROKE
0x292D	0x0152	# LATIN CAPITAL LIGATURE OE
0x292F	0x0166	# LATIN CAPITAL LETTER T WITH STROKE
0x2930	0x00DE	# LATIN CAPITAL LETTER THORN
0x2941	0x00E6	# LATIN SMALL LIGATURE AE
0x2942	0x0111	# LATIN SMALL LETTER D WITH STROKE
0x2943	0x00F0	# LATIN SMALL LETTER ETH
0x2944	0x0127	# LATIN SMALL LETTER H WITH STROKE
0x2945	0x0131	# LATIN SMALL LETTER DOTLESS I
0x2946	0x0133	# LATIN SMALL LIGATURE IJ
0x2947	0x0138	# LATIN SMALL LETTER KRA
0x2948	0x0142	# LATIN SMALL LETTER L WITH STROKE
0x2949	0x0140	# LATIN SMALL LETTER L WITH MIDDLE DOT
0x294A	0x0149	# LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
0x294B	0x014B	# LATIN SMALL LETTER ENG
0x294C	0x00F8	# LATIN SMALL LETTER O WITH STROKE
0x294D	0x0153	# LATIN SMALL LIGATURE OE
0x294E	0x00DF	# LATIN SMALL LETTER SHARP S
0x294F	0x0167	# LATIN SMALL LETTER T WITH STROKE
0x2950	0x00FE	# LATIN SMALL LETTER THORN
0x2A21	0x00C1	# LATIN CAPITAL LETTER A WITH ACUTE
0x2A22	0x00C0	# LATIN CAPITAL LETTER A WITH GRAVE
0x2A23	0x00C4	# LATIN CAPITAL LETTER A WITH DIAERESIS
0x2A24	0x00C2	# LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0x2A25	0x0102	# LATIN CAPITAL LETTER A WITH BREVE
0x2A26	0x01CD	# LATIN CAPITAL LETTER A WITH CARON
0x2A27	0x0100	# LATIN CAPITAL LETTER A WITH MACRON
0x2A28	0x0104	# LATIN CAPITAL LETTER A WITH OGONEK
0x2A29	0x00C5	# LATIN CAPITAL LETTER A WITH RING ABOVE
0x2A2A	0x00C3	# LATIN CAPITAL LETTER A WITH TILDE
0x2A2B	0x0106	# LATIN CAPITAL LETTER C WITH ACUTE
0x2A2C	0x0108	# LATIN CAPITAL LETTER C WITH CIRCUMFLEX
0x2A2D	0x010C	# LATIN CAPITAL LETTER C WITH CARON
0x2A2E	0x00C7	# LATIN CAPITAL LETTER C WITH CEDILLA
0x2A2F	0x010A	# LATIN CAPITAL LETTER C WITH DOT ABOVE
0x2A30	0x010E	# LATIN CAPITAL LETTER D WITH CARON
0x2A31	0x00C9	# LATIN CAPITAL LETTER E WITH ACUTE
0x2A32	0x00C8	# LATIN CAPITAL LETTER E WITH GRAVE
0x2A33	0x00CB	# LATIN CAPITAL LETTER E WITH DIAERESIS
0x2A34	0x00CA	# LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0x2A35	0x011A	# LATIN CAPITAL LETTER E WITH CARON
0x2A36	0x0116	# LATIN CAPITAL LETTER E WITH DOT ABOVE
0x2A37	0x0112	# LATIN CAPITAL LETTER E WITH MACRON
0x2A38	0x0118	# LATIN CAPITAL LETTER E WITH OGONEK
0x2A3A	0x011C	# LATIN CAPITAL LETTER G WITH CIRCUMFLEX
0x2A3B	0x011E	# LATIN CAPITAL LETTER G WITH BREVE
0x2A3C	0x0122	# LATIN CAPITAL LETTER G WITH CEDILLA
0x2A3D	0x0120	# LATIN CAPITAL LETTER G WITH DOT ABOVE
0x2A3E	0x0124	# LATIN CAPITAL LETTER H WITH CIRCUMFLEX
0x2A3F	0x00CD	# LATIN CAPITAL LETTER I WITH ACUTE
0x2A40	0x00CC	# LATIN CAPITAL LETTER I WITH GRAVE
0x2A41	0x00CF	# LATIN CAPITAL LETTER I WITH DIAERESIS
0x2A42	0x00CE	# LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0x2A43	0x01CF	# LATIN CAPITAL LETTER I WITH CARON
0x2A44	0x0130	# LATIN CAPITAL LETTER I WITH DOT ABOVE
0x2A45	0x012A	# LATIN CAPITAL LETTER I WITH MACRON
0x2A46	0x012E	# LATIN CAPITAL LETTER I WITH OGONEK
0x2A47	0x0128	# LATIN CAPITAL LETTER I WITH TILDE
0x2A48	0x0134	# LATIN CAPITAL LETTER J WITH CIRCUMFLEX
0x2A49	0x0136	# LATIN CAPITAL LETTER K WITH CEDILLA
0x2A4A	0x0139	# LATIN CAPITAL LETTER L WITH ACUTE
0x2A4B	0x013D	# LATIN CAPITAL LETTER L WITH CARON
0x2A4C	0x013B	# LATIN CAPITAL LETTER L WITH CEDILLA
0x2A4D	0x0143	# LATIN CAPITAL LETTER N WITH ACUTE
0x2A4E	0x0147	# LATIN CAPITAL LETTER N WITH CARON
0x2A4F	0x0145	# LATIN CAPITAL LETTER N WITH CEDILLA
0x2A50	0x00D1	# LATIN CAPITAL LETTER N WITH TILDE
0x2A51	0x00D3	# LATIN CAPITAL LETTER O WITH ACUTE
0x2A52	0x00D2	# LATIN CAPITAL LETTER O WITH GRAVE
0x2A53	0x00D6	# LATIN CAPITAL LETTER O WITH DIAERESIS
0x2A54	0x00D4	# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0x2A55	0x01D1	# LATIN CAPITAL LETTER O WITH CARON
0x2A56	0x0150	# LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
0x2A57	0x014C	# LATIN CAPITAL LETTER O WITH MACRON
0x2A58	0x00D5	# LATIN CAPITAL LETTER O WITH TILDE
0x2A59	0x0154	# LATIN CAPITAL LETTER R WITH ACUTE
0x2A5A	0x0158	# LATIN CAPITAL LETTER R WITH CARON
0x2A5B	0x0156	# LATIN CAPITAL LETTER R WITH CEDILLA
0x2A5C	0x015A	# LATIN CAPITAL LETTER S WITH ACUTE
0x2A5D	0x015C	# LATIN CAPITAL LETTER S WITH CIRCUMFLEX
0x2A5E	0x0160	# LATIN CAPITAL LETTER S WITH CARON
0x2A5F	0x015E	# LATIN CAPITAL LETTER S WITH CEDILLA
0x2A60	0x0164	# LATIN CAPITAL LETTER T WITH CARON
0x2A61	0x0162	# LATIN CAPITAL LETTER T WITH CEDILLA
0x2A62	0x00DA	# LATIN CAPITAL LETTER U WITH ACUTE
0x2A63	0x00D9	# LATIN CAPITAL LETTER U WITH GRAVE
0x2A64	0x00DC	# LATIN CAPITAL LETTER U WITH DIAERESIS
0x2A65	0x00DB	# LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0x2A66	0x016C	# LATIN CAPITAL LETTER U WITH BREVE
0x2A67	0x01D3	# LATIN CAPITAL LETTER U WITH CARON
0x2A68	0x0170	# LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
0x2A69	0x016A	# LATIN CAPITAL LETTER U WITH MACRON
0x2A6A	0x0172	# LATIN CAPITAL LETTER U WITH OGONEK
0x2A6B	0x016E	# LATIN CAPITAL LETTER U WITH RING ABOVE
0x2A6C	0x0168	# LATIN CAPITAL LETTER U WITH TILDE
0x2A6D	0x01D7	# LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
0x2A6E	0x01DB	# LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
0x2A6F	0x01D9	# LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
0x2A70	0x01D5	# LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
0x2A71	0x0174	# LATIN CAPITAL LETTER W WITH CIRCUMFLEX
0x2A72	0x00DD	# LATIN CAPITAL LETTER Y WITH ACUTE
0x2A73	0x0178	# LATIN CAPITAL LETTER Y WITH DIAERESIS
0x2A74	0x0176	# LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
0x2A75	0x0179	# LATIN CAPITAL LETTER Z WITH ACUTE
0x2A76	0x017D	# LATIN CAPITAL LETTER Z WITH CARON
0x2A77	0x017B	# LATIN CAPITAL LETTER Z WITH DOT ABOVE
0x2B21	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
0x2B22	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
0x2B23	0x00E4	# LATIN SMALL LETTER A WITH DIAERESIS
0x2B24	0x00E2	# LATIN SMALL LETTER A WITH CIRCUMFLEX
0x2B25	0x0103	# LATIN SMALL LETTER A WITH BREVE
0x2B26	0x01CE	# LATIN SMALL LETTER A WITH CARON
0x2B27	0x0101	# LATIN SMALL LETTER A WITH MACRON
0x2B28	0x0105	# LATIN SMALL LETTER A WITH OGONEK
0x2B29	0x00E5	# LATIN SMALL LETTER A WITH RING ABOVE
0x2B2A	0x00E3	# LATIN SMALL LETTER A WITH TILDE
0x2B2B	0x0107	# LATIN SMALL LETTER C WITH ACUTE
0x2B2C	0x0109	# LATIN SMALL LETTER C WITH CIRCUMFLEX
0x2B2D	0x010D	# LATIN SMALL LETTER C WITH CARON
0x2B2E	0x00E7	# LATIN SMALL LETTER C WITH CEDILLA
0x2B2F	0x010B	# LATIN SMALL LETTER C WITH DOT ABOVE
0x2B30	0x010F	# LATIN SMALL LETTER D WITH CARON
0x2B31	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
0x2B32	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
0x2B33	0x00EB	# LATIN SMALL LETTER E WITH DIAERESIS
0x2B34	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
0x2B35	0x011B	# LATIN SMALL LETTER E WITH CARON
0x2B36	0x0117	# LATIN SMALL LETTER E WITH DOT ABOVE
0x2B37	0x0113	# LATIN SMALL LETTER E WITH MACRON
0x2B38	0x0119	# LATIN SMALL LETTER E WITH OGONEK
0x2B39	0x01F5	# LATIN SMALL LETTER G WITH ACUTE
0x2B3A	0x011D	# LATIN SMALL LETTER G WITH CIRCUMFLEX
0x2B3B	0x011F	# LATIN SMALL LETTER G WITH BREVE
0x2B3D	0x0121	# LATIN SMALL LETTER G WITH DOT ABOVE
0x2B3E	0x0125	# LATIN SMALL LETTER H WITH CIRCUMFLEX
0x2B3F	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
0x2B40	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
0x2B41	0x00EF	# LATIN SMALL LETTER I WITH DIAERESIS
0x2B42	0x00EE	# LATIN SMALL LETTER I WITH CIRCUMFLEX
0x2B43	0x01D0	# LATIN SMALL LETTER I WITH CARON
0x2B45	0x012B	# LATIN SMALL LETTER I WITH MACRON
0x2B46	0x012F	# LATIN SMALL LETTER I WITH OGONEK
0x2B47	0x0129	# LATIN SMALL LETTER I WITH TILDE
0x2B48	0x0135	# LATIN SMALL LETTER J WITH CIRCUMFLEX
0x2B49	0x0137	# LATIN SMALL LETTER K WITH CEDILLA
0x2B4A	0x013A	# LATIN SMALL LETTER L WITH ACUTE
0x2B4B	0x013E	# LATIN SMALL LETTER L WITH CARON
0x2B4C	0x013C	# LATIN SMALL LETTER L WITH CEDILLA
0x2B4D	0x0144	# LATIN SMALL LETTER N WITH ACUTE
0x2B4E	0x0148	# LATIN SMALL LETTER N WITH CARON
0x2B4F	0x0146	# LATIN SMALL LETTER N WITH CEDILLA
0x2B50	0x00F1	# LATIN SMALL LETTER N WITH TILDE
0x2B51	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
0x2B52	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
0x2B53	0x00F6	# LATIN SMALL LETTER O WITH DIAERESIS
0x2B54	0x00F4	# LATIN SMALL LETTER O WITH CIRCUMFLEX
0x2B55	0x01D2	# LATIN SMALL LETTER O WITH CARON
0x2B56	0x0151	# LATIN SMALL LETTER O WITH DOUBLE ACUTE
0x2B57	0x014D	# LATIN SMALL LETTER O WITH MACRON
0x2B58	0x00F5	# LATIN SMALL LETTER O WITH TILDE
0x2B59	0x0155	# LATIN SMALL LETTER R WITH ACUTE
0x2B5A	0x0159	# LATIN SMALL LETTER R WITH CARON
0x2B5B	0x0157	# LATIN SMALL LETTER R WITH CEDILLA
0x2B5C	0x015B	# LATIN SMALL LETTER S WITH ACUTE
0x2B5D	0x015D	# LATIN SMALL LETTER S WITH CIRCUMFLEX
0x2B5E	0x0161	# LATIN SMALL LETTER S WITH CARON
0x2B5F	0x015F	# LATIN SMALL LETTER S WITH CEDILLA
0x2B60	0x0165	# LATIN SMALL LETTER T WITH CARON
0x2B61	0x0163	# LATIN SMALL LETTER T WITH CEDILLA
0x2B62	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
0x2B63	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
0x2B64	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
0x2B65	0x00FB	# LATIN SMALL LETTER U WITH CIRCUMFLEX
0x2B66	0x016D	# LATIN SMALL LETTER U WITH BREVE
0x2B67	0x01D4	# LATIN SMALL LETTER U WITH CARON
0x2B68	0x0171	# LATIN SMALL LETTER U WITH DOUBLE ACUTE
0x2B69	0x016B	# LATIN SMALL LETTER U WITH MACRON
0x2B6A	0x0173	# LATIN SMALL LETTER U WITH OGONEK
0x2B6B	0x016F	# LATIN SMALL LETTER U WITH RING ABOVE
0x2B6C	0x0169	# LATIN SMALL LETTER U WITH TILDE
0x2B6D	0x01D8	# LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
0x2B6E	0x01DC	# LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
0x2B6F	0x01DA	# LATIN SMALL LETTER U WITH DIAERESIS AND CARON
0x2B70	0x01D6	# LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
0x2B71	0x0175	# LATIN SMALL LETTER W WITH CIRCUMFLEX
0x2B72	0x00FD	# LATIN SMALL LETTER Y WITH ACUTE
0x2B73	0x00FF	# LATIN SMALL LETTER Y WITH DIAERESIS
0x2B74	0x0177	# LATIN SMALL LETTER Y WITH CIRCUMFLEX
0x2B75	0x017A	# LATIN SMALL LETTER Z WITH ACUTE
0x2B76	0x017E	# LATIN SMALL LETTER Z WITH CARON
0x2B77	0x017C	# LATIN SMALL LETTER Z WITH DOT ABOVE
0x3021	0x4E02	# <CJK>
0x3022	0x4E04	# <CJK>
0x3023	0x4E05	# <CJK>
0x3024	0x4E0C	# <CJK>
0x3025	0x4E12	# <CJK>
0x3026	0x4E1F	# <CJK>
0x3027	0x4E23	# <CJK>
0x3028	0x4E24	# <CJK>
0x3029	0x4E28	# <CJK>
0x302A	0x4E2B	# <CJK>
0x302B	0x4E2E	# <CJK>
0x302C	0x4E2F	# <CJK>
0x302D	0x4E30	# <CJK>
0x302E	0x4E35	# <CJK>
0x302F	0x4E40	# <CJK>
0x3030	0x4E41	# <CJK>
0x3031	0x4E44	# <CJK>
0x3032	0x4E47	# <CJK>
0x3033	0x4E51	# <CJK>
0x3034	0x4E5A	# <CJK>
0x3035	0x4E5C	# <CJK>
0x3036	0x4E63	# <CJK>
0x3037	0x4E68	# <CJK>
0x3038	0x4E69	# <CJK>
0x3039	0x4E74	# <CJK>
0x303A	0x4E75	# <CJK>
0x303B	0x4E79	# <CJK>
0x303C	0x4E7F	# <CJK>
0x303D	0x4E8D	# <CJK>
0x303E	0x4E96	# <CJK>
0x303F	0x4E97	# <CJK>
0x3040	0x4E9D	# <CJK>
0x3041	0x4EAF	# <CJK>
0x3042	0x4EB9	# <CJK>
0x3043	0x4EC3	# <CJK>
0x3044	0x4ED0	# <CJK>
0x3045	0x4EDA	# <CJK>
0x3046	0x4EDB	# <CJK>
0x3047	0x4EE0	# <CJK>
0x3048	0x4EE1	# <CJK>
0x3049	0x4EE2	# <CJK>
0x304A	0x4EE8	# <CJK>
0x304B	0x4EEF	# <CJK>
0x304C	0x4EF1	# <CJK>
0x304D	0x4EF3	# <CJK>
0x304E	0x4EF5	# <CJK>
0x304F	0x4EFD	# <CJK>
0x3050	0x4EFE	# <CJK>
0x3051	0x4EFF	# <CJK>
0x3052	0x4F00	# <CJK>
0x3053	0x4F02	# <CJK>
0x3054	0x4F03	# <CJK>
0x3055	0x4F08	# <CJK>
0x3056	0x4F0B	# <CJK>
0x3057	0x4F0C	# <CJK>
0x3058	0x4F12	# <CJK>
0x3059	0x4F15	# <CJK>
0x305A	0x4F16	# <CJK>
0x305B	0x4F17	# <CJK>
0x305C	0x4F19	# <CJK>
0x305D	0x4F2E	# <CJK>
0x305E	0x4F31	# <CJK>
0x305F	0x4F60	# <CJK>
0x3060	0x4F33	# <CJK>
0x3061	0x4F35	# <CJK>
0x3062	0x4F37	# <CJK>
0x3063	0x4F39	# <CJK>
0x3064	0x4F3B	# <CJK>
0x3065	0x4F3E	# <CJK>
0x3066	0x4F40	# <CJK>
0x3067	0x4F42	# <CJK>
0x3068	0x4F48	# <CJK>
0x3069	0x4F49	# <CJK>
0x306A	0x4F4B	# <CJK>
0x306B	0x4F4C	# <CJK>
0x306C	0x4F52	# <CJK>
0x306D	0x4F54	# <CJK>
0x306E	0x4F56	# <CJK>
0x306F	0x4F58	# <CJK>
0x3070	0x4F5F	# <CJK>
0x3071	0x4F63	# <CJK>
0x3072	0x4F6A	# <CJK>
0x3073	0x4F6C	# <CJK>
0x3074	0x4F6E	# <CJK>
0x3075	0x4F71	# <CJK>
0x3076	0x4F77	# <CJK>
0x3077	0x4F78	# <CJK>
0x3078	0x4F79	# <CJK>
0x3079	0x4F7A	# <CJK>
0x307A	0x4F7D	# <CJK>
0x307B	0x4F7E	# <CJK>
0x307C	0x4F81	# <CJK>
0x307D	0x4F82	# <CJK>
0x307E	0x4F84	# <CJK>
0x3121	0x4F85	# <CJK>
0x3122	0x4F89	# <CJK>
0x3123	0x4F8A	# <CJK>
0x3124	0x4F8C	# <CJK>
0x3125	0x4F8E	# <CJK>
0x3126	0x4F90	# <CJK>
0x3127	0x4F92	# <CJK>
0x3128	0x4F93	# <CJK>
0x3129	0x4F94	# <CJK>
0x312A	0x4F97	# <CJK>
0x312B	0x4F99	# <CJK>
0x312C	0x4F9A	# <CJK>
0x312D	0x4F9E	# <CJK>
0x312E	0x4F9F	# <CJK>
0x312F	0x4FB2	# <CJK>
0x3130	0x4FB7	# <CJK>
0x3131	0x4FB9	# <CJK>
0x3132	0x4FBB	# <CJK>
0x3133	0x4FBC	# <CJK>
0x3134	0x4FBD	# <CJK>
0x3135	0x4FBE	# <CJK>
0x3136	0x4FC0	# <CJK>
0x3137	0x4FC1	# <CJK>
0x3138	0x4FC5	# <CJK>
0x3139	0x4FC6	# <CJK>
0x313A	0x4FC8	# <CJK>
0x313B	0x4FC9	# <CJK>
0x313C	0x4FCB	# <CJK>
0x313D	0x4FCC	# <CJK>
0x313E	0x4FCD	# <CJK>
0x313F	0x4FCF	# <CJK>
0x3140	0x4FD2	# <CJK>
0x3141	0x4FDC	# <CJK>
0x3142	0x4FE0	# <CJK>
0x3143	0x4FE2	# <CJK>
0x3144	0x4FF0	# <CJK>
0x3145	0x4FF2	# <CJK>
0x3146	0x4FFC	# <CJK>
0x3147	0x4FFD	# <CJK>
0x3148	0x4FFF	# <CJK>
0x3149	0x5000	# <CJK>
0x314A	0x5001	# <CJK>
0x314B	0x5004	# <CJK>
0x314C	0x5007	# <CJK>
0x314D	0x500A	# <CJK>
0x314E	0x500C	# <CJK>
0x314F	0x500E	# <CJK>
0x3150	0x5010	# <CJK>
0x3151	0x5013	# <CJK>
0x3152	0x5017	# <CJK>
0x3153	0x5018	# <CJK>
0x3154	0x501B	# <CJK>
0x3155	0x501C	# <CJK>
0x3156	0x501D	# <CJK>
0x3157	0x501E	# <CJK>
0x3158	0x5022	# <CJK>
0x3159	0x5027	# <CJK>
0x315A	0x502E	# <CJK>
0x315B	0x5030	# <CJK>
0x315C	0x5032	# <CJK>
0x315D	0x5033	# <CJK>
0x315E	0x5035	# <CJK>
0x315F	0x5040	# <CJK>
0x3160	0x5041	# <CJK>
0x3161	0x5042	# <CJK>
0x3162	0x5045	# <CJK>
0x3163	0x5046	# <CJK>
0x3164	0x504A	# <CJK>
0x3165	0x504C	# <CJK>
0x3166	0x504E	# <CJK>
0x3167	0x5051	# <CJK>
0x3168	0x5052	# <CJK>
0x3169	0x5053	# <CJK>
0x316A	0x5057	# <CJK>
0x316B	0x5059	# <CJK>
0x316C	0x505F	# <CJK>
0x316D	0x5060	# <CJK>
0x316E	0x5062	# <CJK>
0x316F	0x5063	# <CJK>
0x3170	0x5066	# <CJK>
0x3171	0x5067	# <CJK>
0x3172	0x506A	# <CJK>
0x3173	0x506D	# <CJK>
0x3174	0x5070	# <CJK>
0x3175	0x5071	# <CJK>
0x3176	0x503B	# <CJK>
0x3177	0x5081	# <CJK>
0x3178	0x5083	# <CJK>
0x3179	0x5084	# <CJK>
0x317A	0x5086	# <CJK>
0x317B	0x508A	# <CJK>
0x317C	0x508E	# <CJK>
0x317D	0x508F	# <CJK>
0x317E	0x5090	# <CJK>
0x3221	0x5092	# <CJK>
0x3222	0x5093	# <CJK>
0x3223	0x5094	# <CJK>
0x3224	0x5096	# <CJK>
0x3225	0x509B	# <CJK>
0x3226	0x509C	# <CJK>
0x3227	0x509E	# <CJK>
0x3228	0x509F	# <CJK>
0x3229	0x50A0	# <CJK>
0x322A	0x50A1	# <CJK>
0x322B	0x50A2	# <CJK>
0x322C	0x50AA	# <CJK>
0x322D	0x50AF	# <CJK>
0x322E	0x50B0	# <CJK>
0x322F	0x50B9	# <CJK>
0x3230	0x50BA	# <CJK>
0x3231	0x50BD	# <CJK>
0x3232	0x50C0	# <CJK>
0x3233	0x50C3	# <CJK>
0x3234	0x50C4	# <CJK>
0x3235	0x50C7	# <CJK>
0x3236	0x50CC	# <CJK>
0x3237	0x50CE	# <CJK>
0x3238	0x50D0	# <CJK>
0x3239	0x50D3	# <CJK>
0x323A	0x50D4	# <CJK>
0x323B	0x50D8	# <CJK>
0x323C	0x50DC	# <CJK>
0x323D	0x50DD	# <CJK>
0x323E	0x50DF	# <CJK>
0x323F	0x50E2	# <CJK>
0x3240	0x50E4	# <CJK>
0x3241	0x50E6	# <CJK>
0x3242	0x50E8	# <CJK>
0x3243	0x50E9	# <CJK>
0x3244	0x50EF	# <CJK>
0x3245	0x50F1	# <CJK>
0x3246	0x50F6	# <CJK>
0x3247	0x50FA	# <CJK>
0x3248	0x50FE	# <CJK>
0x3249	0x5103	# <CJK>
0x324A	0x5106	# <CJK>
0x324B	0x5107	# <CJK>
0x324C	0x5108	# <CJK>
0x324D	0x510B	# <CJK>
0x324E	0x510C	# <CJK>
0x324F	0x510D	# <CJK>
0x3250	0x510E	# <CJK>
0x3251	0x50F2	# <CJK>
0x3252	0x5110	# <CJK>
0x3253	0x5117	# <CJK>
0x3254	0x5119	# <CJK>
0x3255	0x511B	# <CJK>
0x3256	0x511C	# <CJK>
0x3257	0x511D	# <CJK>
0x3258	0x511E	# <CJK>
0x3259	0x5123	# <CJK>
0x325A	0x5127	# <CJK>
0x325B	0x5128	# <CJK>
0x325C	0x512C	# <CJK>
0x325D	0x512D	# <CJK>
0x325E	0x512F	# <CJK>
0x325F	0x5131	# <CJK>
0x3260	0x5133	# <CJK>
0x3261	0x5134	# <CJK>
0x3262	0x5135	# <CJK>
0x3263	0x5138	# <CJK>
0x3264	0x5139	# <CJK>
0x3265	0x5142	# <CJK>
0x3266	0x514A	# <CJK>
0x3267	0x514F	# <CJK>
0x3268	0x5153	# <CJK>
0x3269	0x5155	# <CJK>
0x326A	0x5157	# <CJK>
0x326B	0x5158	# <CJK>
0x326C	0x515F	# <CJK>
0x326D	0x5164	# <CJK>
0x326E	0x5166	# <CJK>
0x326F	0x517E	# <CJK>
0x3270	0x5183	# <CJK>
0x3271	0x5184	# <CJK>
0x3272	0x518B	# <CJK>
0x3273	0x518E	# <CJK>
0x3274	0x5198	# <CJK>
0x3275	0x519D	# <CJK>
0x3276	0x51A1	# <CJK>
0x3277	0x51A3	# <CJK>
0x3278	0x51AD	# <CJK>
0x3279	0x51B8	# <CJK>
0x327A	0x51BA	# <CJK>
0x327B	0x51BC	# <CJK>
0x327C	0x51BE	# <CJK>
0x327D	0x51BF	# <CJK>
0x327E	0x51C2	# <CJK>
0x3321	0x51C8	# <CJK>
0x3322	0x51CF	# <CJK>
0x3323	0x51D1	# <CJK>
0x3324	0x51D2	# <CJK>
0x3325	0x51D3	# <CJK>
0x3326	0x51D5	# <CJK>
0x3327	0x51D8	# <CJK>
0x3328	0x51DE	# <CJK>
0x3329	0x51E2	# <CJK>
0x332A	0x51E5	# <CJK>
0x332B	0x51EE	# <CJK>
0x332C	0x51F2	# <CJK>
0x332D	0x51F3	# <CJK>
0x332E	0x51F4	# <CJK>
0x332F	0x51F7	# <CJK>
0x3330	0x5201	# <CJK>
0x3331	0x5202	# <CJK>
0x3332	0x5205	# <CJK>
0x3333	0x5212	# <CJK>
0x3334	0x5213	# <CJK>
0x3335	0x5215	# <CJK>
0x3336	0x5216	# <CJK>
0x3337	0x5218	# <CJK>
0x3338	0x5222	# <CJK>
0x3339	0x5228	# <CJK>
0x333A	0x5231	# <CJK>
0x333B	0x5232	# <CJK>
0x333C	0x5235	# <CJK>
0x333D	0x523C	# <CJK>
0x333E	0x5245	# <CJK>
0x333F	0x5249	# <CJK>
0x3340	0x5255	# <CJK>
0x3341	0x5257	# <CJK>
0x3342	0x5258	# <CJK>
0x3343	0x525A	# <CJK>
0x3344	0x525C	# <CJK>
0x3345	0x525F	# <CJK>
0x3346	0x5260	# <CJK>
0x3347	0x5261	# <CJK>
0x3348	0x5266	# <CJK>
0x3349	0x526E	# <CJK>
0x334A	0x5277	# <CJK>
0x334B	0x5278	# <CJK>
0x334C	0x5279	# <CJK>
0x334D	0x5280	# <CJK>
0x334E	0x5282	# <CJK>
0x334F	0x5285	# <CJK>
0x3350	0x528A	# <CJK>
0x3351	0x528C	# <CJK>
0x3352	0x5293	# <CJK>
0x3353	0x5295	# <CJK>
0x3354	0x5296	# <CJK>
0x3355	0x5297	# <CJK>
0x3356	0x5298	# <CJK>
0x3357	0x529A	# <CJK>
0x3358	0x529C	# <CJK>
0x3359	0x52A4	# <CJK>
0x335A	0x52A5	# <CJK>
0x335B	0x52A6	# <CJK>
0x335C	0x52A7	# <CJK>
0x335D	0x52AF	# <CJK>
0x335E	0x52B0	# <CJK>
0x335F	0x52B6	# <CJK>
0x3360	0x52B7	# <CJK>
0x3361	0x52B8	# <CJK>
0x3362	0x52BA	# <CJK>
0x3363	0x52BB	# <CJK>
0x3364	0x52BD	# <CJK>
0x3365	0x52C0	# <CJK>
0x3366	0x52C4	# <CJK>
0x3367	0x52C6	# <CJK>
0x3368	0x52C8	# <CJK>
0x3369	0x52CC	# <CJK>
0x336A	0x52CF	# <CJK>
0x336B	0x52D1	# <CJK>
0x336C	0x52D4	# <CJK>
0x336D	0x52D6	# <CJK>
0x336E	0x52DB	# <CJK>
0x336F	0x52DC	# <CJK>
0x3370	0x52E1	# <CJK>
0x3371	0x52E5	# <CJK>
0x3372	0x52E8	# <CJK>
0x3373	0x52E9	# <CJK>
0x3374	0x52EA	# <CJK>
0x3375	0x52EC	# <CJK>
0x3376	0x52F0	# <CJK>
0x3377	0x52F1	# <CJK>
0x3378	0x52F4	# <CJK>
0x3379	0x52F6	# <CJK>
0x337A	0x52F7	# <CJK>
0x337B	0x5300	# <CJK>
0x337C	0x5303	# <CJK>
0x337D	0x530A	# <CJK>
0x337E	0x530B	# <CJK>
0x3421	0x530C	# <CJK>
0x3422	0x5311	# <CJK>
0x3423	0x5313	# <CJK>
0x3424	0x5318	# <CJK>
0x3425	0x531B	# <CJK>
0x3426	0x531C	# <CJK>
0x3427	0x531E	# <CJK>
0x3428	0x531F	# <CJK>
0x3429	0x5325	# <CJK>
0x342A	0x5327	# <CJK>
0x342B	0x5328	# <CJK>
0x342C	0x5329	# <CJK>
0x342D	0x532B	# <CJK>
0x342E	0x532C	# <CJK>
0x342F	0x532D	# <CJK>
0x3430	0x5330	# <CJK>
0x3431	0x5332	# <CJK>
0x3432	0x5335	# <CJK>
0x3433	0x533C	# <CJK>
0x3434	0x533D	# <CJK>
0x3435	0x533E	# <CJK>
0x3436	0x5342	# <CJK>
0x3437	0x534C	# <CJK>
0x3438	0x534B	# <CJK>
0x3439	0x5359	# <CJK>
0x343A	0x535B	# <CJK>
0x343B	0x5361	# <CJK>
0x343C	0x5363	# <CJK>
0x343D	0x5365	# <CJK>
0x343E	0x536C	# <CJK>
0x343F	0x536D	# <CJK>
0x3440	0x5372	# <CJK>
0x3441	0x5379	# <CJK>
0x3442	0x537E	# <CJK>
0x3443	0x5383	# <CJK>
0x3444	0x5387	# <CJK>
0x3445	0x5388	# <CJK>
0x3446	0x538E	# <CJK>
0x3447	0x5393	# <CJK>
0x3448	0x5394	# <CJK>
0x3449	0x5399	# <CJK>
0x344A	0x539D	# <CJK>
0x344B	0x53A1	# <CJK>
0x344C	0x53A4	# <CJK>
0x344D	0x53AA	# <CJK>
0x344E	0x53AB	# <CJK>
0x344F	0x53AF	# <CJK>
0x3450	0x53B2	# <CJK>
0x3451	0x53B4	# <CJK>
0x3452	0x53B5	# <CJK>
0x3453	0x53B7	# <CJK>
0x3454	0x53B8	# <CJK>
0x3455	0x53BA	# <CJK>
0x3456	0x53BD	# <CJK>
0x3457	0x53C0	# <CJK>
0x3458	0x53C5	# <CJK>
0x3459	0x53CF	# <CJK>
0x345A	0x53D2	# <CJK>
0x345B	0x53D3	# <CJK>
0x345C	0x53D5	# <CJK>
0x345D	0x53DA	# <CJK>
0x345E	0x53DD	# <CJK>
0x345F	0x53DE	# <CJK>
0x3460	0x53E0	# <CJK>
0x3461	0x53E6	# <CJK>
0x3462	0x53E7	# <CJK>
0x3463	0x53F5	# <CJK>
0x3464	0x5402	# <CJK>
0x3465	0x5413	# <CJK>
0x3466	0x541A	# <CJK>
0x3467	0x5421	# <CJK>
0x3468	0x5427	# <CJK>
0x3469	0x5428	# <CJK>
0x346A	0x542A	# <CJK>
0x346B	0x542F	# <CJK>
0x346C	0x5431	# <CJK>
0x346D	0x5434	# <CJK>
0x346E	0x5435	# <CJK>
0x346F	0x5443	# <CJK>
0x3470	0x5444	# <CJK>
0x3471	0x5447	# <CJK>
0x3472	0x544D	# <CJK>
0x3473	0x544F	# <CJK>
0x3474	0x545E	# <CJK>
0x3475	0x5462	# <CJK>
0x3476	0x5464	# <CJK>
0x3477	0x5466	# <CJK>
0x3478	0x5467	# <CJK>
0x3479	0x5469	# <CJK>
0x347A	0x546B	# <CJK>
0x347B	0x546D	# <CJK>
0x347C	0x546E	# <CJK>
0x347D	0x5474	# <CJK>
0x347E	0x547F	# <CJK>
0x3521	0x5481	# <CJK>
0x3522	0x5483	# <CJK>
0x3523	0x5485	# <CJK>
0x3524	0x5488	# <CJK>
0x3525	0x5489	# <CJK>
0x3526	0x548D	# <CJK>
0x3527	0x5491	# <CJK>
0x3528	0x5495	# <CJK>
0x3529	0x5496	# <CJK>
0x352A	0x549C	# <CJK>
0x352B	0x549F	# <CJK>
0x352C	0x54A1	# <CJK>
0x352D	0x54A6	# <CJK>
0x352E	0x54A7	# <CJK>
0x352F	0x54A9	# <CJK>
0x3530	0x54AA	# <CJK>
0x3531	0x54AD	# <CJK>
0x3532	0x54AE	# <CJK>
0x3533	0x54B1	# <CJK>
0x3534	0x54B7	# <CJK>
0x3535	0x54B9	# <CJK>
0x3536	0x54BA	# <CJK>
0x3537	0x54BB	# <CJK>
0x3538	0x54BF	# <CJK>
0x3539	0x54C6	# <CJK>
0x353A	0x54CA	# <CJK>
0x353B	0x54CD	# <CJK>
0x353C	0x54CE	# <CJK>
0x353D	0x54E0	# <CJK>
0x353E	0x54EA	# <CJK>
0x353F	0x54EC	# <CJK>
0x3540	0x54EF	# <CJK>
0x3541	0x54F6	# <CJK>
0x3542	0x54FC	# <CJK>
0x3543	0x54FE	# <CJK>
0x3544	0x54FF	# <CJK>
0x3545	0x5500	# <CJK>
0x3546	0x5501	# <CJK>
0x3547	0x5505	# <CJK>
0x3548	0x5508	# <CJK>
0x3549	0x5509	# <CJK>
0x354A	0x550C	# <CJK>
0x354B	0x550D	# <CJK>
0x354C	0x550E	# <CJK>
0x354D	0x5515	# <CJK>
0x354E	0x552A	# <CJK>
0x354F	0x552B	# <CJK>
0x3550	0x5532	# <CJK>
0x3551	0x5535	# <CJK>
0x3552	0x5536	# <CJK>
0x3553	0x553B	# <CJK>
0x3554	0x553C	# <CJK>
0x3555	0x553D	# <CJK>
0x3556	0x5541	# <CJK>
0x3557	0x5547	# <CJK>
0x3558	0x5549	# <CJK>
0x3559	0x554A	# <CJK>
0x355A	0x554D	# <CJK>
0x355B	0x5550	# <CJK>
0x355C	0x5551	# <CJK>
0x355D	0x5558	# <CJK>
0x355E	0x555A	# <CJK>
0x355F	0x555B	# <CJK>
0x3560	0x555E	# <CJK>
0x3561	0x5560	# <CJK>
0x3562	0x5561	# <CJK>
0x3563	0x5564	# <CJK>
0x3564	0x5566	# <CJK>
0x3565	0x557F	# <CJK>
0x3566	0x5581	# <CJK>
0x3567	0x5582	# <CJK>
0x3568	0x5586	# <CJK>
0x3569	0x5588	# <CJK>
0x356A	0x558E	# <CJK>
0x356B	0x558F	# <CJK>
0x356C	0x5591	# <CJK>
0x356D	0x5592	# <CJK>
0x356E	0x5593	# <CJK>
0x356F	0x5594	# <CJK>
0x3570	0x5597	# <CJK>
0x3571	0x55A3	# <CJK>
0x3572	0x55A4	# <CJK>
0x3573	0x55AD	# <CJK>
0x3574	0x55B2	# <CJK>
0x3575	0x55BF	# <CJK>
0x3576	0x55C1	# <CJK>
0x3577	0x55C3	# <CJK>
0x3578	0x55C6	# <CJK>
0x3579	0x55C9	# <CJK>
0x357A	0x55CB	# <CJK>
0x357B	0x55CC	# <CJK>
0x357C	0x55CE	# <CJK>
0x357D	0x55D1	# <CJK>
0x357E	0x55D2	# <CJK>
0x3621	0x55D3	# <CJK>
0x3622	0x55D7	# <CJK>
0x3623	0x55D8	# <CJK>
0x3624	0x55DB	# <CJK>
0x3625	0x55DE	# <CJK>
0x3626	0x55E2	# <CJK>
0x3627	0x55E9	# <CJK>
0x3628	0x55F6	# <CJK>
0x3629	0x55FF	# <CJK>
0x362A	0x5605	# <CJK>
0x362B	0x5608	# <CJK>
0x362C	0x560A	# <CJK>
0x362D	0x560D	# <CJK>
0x362E	0x560E	# <CJK>
0x362F	0x560F	# <CJK>
0x3630	0x5610	# <CJK>
0x3631	0x5611	# <CJK>
0x3632	0x5612	# <CJK>
0x3633	0x5619	# <CJK>
0x3634	0x562C	# <CJK>
0x3635	0x5630	# <CJK>
0x3636	0x5633	# <CJK>
0x3637	0x5635	# <CJK>
0x3638	0x5637	# <CJK>
0x3639	0x5639	# <CJK>
0x363A	0x563B	# <CJK>
0x363B	0x563C	# <CJK>
0x363C	0x563D	# <CJK>
0x363D	0x563F	# <CJK>
0x363E	0x5640	# <CJK>
0x363F	0x5641	# <CJK>
0x3640	0x5643	# <CJK>
0x3641	0x5644	# <CJK>
0x3642	0x5646	# <CJK>
0x3643	0x5649	# <CJK>
0x3644	0x564B	# <CJK>
0x3645	0x564D	# <CJK>
0x3646	0x564F	# <CJK>
0x3647	0x5654	# <CJK>
0x3648	0x565E	# <CJK>
0x3649	0x5660	# <CJK>
0x364A	0x5661	# <CJK>
0x364B	0x5662	# <CJK>
0x364C	0x5663	# <CJK>
0x364D	0x5666	# <CJK>
0x364E	0x5669	# <CJK>
0x364F	0x566D	# <CJK>
0x3650	0x566F	# <CJK>
0x3651	0x5671	# <CJK>
0x3652	0x5672	# <CJK>
0x3653	0x5675	# <CJK>
0x3654	0x5684	# <CJK>
0x3655	0x5685	# <CJK>
0x3656	0x5688	# <CJK>
0x3657	0x568B	# <CJK>
0x3658	0x568C	# <CJK>
0x3659	0x5695	# <CJK>
0x365A	0x5699	# <CJK>
0x365B	0x569A	# <CJK>
0x365C	0x569D	# <CJK>
0x365D	0x569E	# <CJK>
0x365E	0x569F	# <CJK>
0x365F	0x56A6	# <CJK>
0x3660	0x56A7	# <CJK>
0x3661	0x56A8	# <CJK>
0x3662	0x56A9	# <CJK>
0x3663	0x56AB	# <CJK>
0x3664	0x56AC	# <CJK>
0x3665	0x56AD	# <CJK>
0x3666	0x56B1	# <CJK>
0x3667	0x56B3	# <CJK>
0x3668	0x56B7	# <CJK>
0x3669	0x56BE	# <CJK>
0x366A	0x56C5	# <CJK>
0x366B	0x56C9	# <CJK>
0x366C	0x56CA	# <CJK>
0x366D	0x56CB	# <CJK>
0x366E	0x56CF	# <CJK>
0x366F	0x56D0	# <CJK>
0x3670	0x56CC	# <CJK>
0x3671	0x56CD	# <CJK>
0x3672	0x56D9	# <CJK>
0x3673	0x56DC	# <CJK>
0x3674	0x56DD	# <CJK>
0x3675	0x56DF	# <CJK>
0x3676	0x56E1	# <CJK>
0x3677	0x56E4	# <CJK>
0x3678	0x56E5	# <CJK>
0x3679	0x56E6	# <CJK>
0x367A	0x56E7	# <CJK>
0x367B	0x56E8	# <CJK>
0x367C	0x56F1	# <CJK>
0x367D	0x56EB	# <CJK>
0x367E	0x56ED	# <CJK>
0x3721	0x56F6	# <CJK>
0x3722	0x56F7	# <CJK>
0x3723	0x5701	# <CJK>
0x3724	0x5702	# <CJK>
0x3725	0x5707	# <CJK>
0x3726	0x570A	# <CJK>
0x3727	0x570C	# <CJK>
0x3728	0x5711	# <CJK>
0x3729	0x5715	# <CJK>
0x372A	0x571A	# <CJK>
0x372B	0x571B	# <CJK>
0x372C	0x571D	# <CJK>
0x372D	0x5720	# <CJK>
0x372E	0x5722	# <CJK>
0x372F	0x5723	# <CJK>
0x3730	0x5724	# <CJK>
0x3731	0x5725	# <CJK>
0x3732	0x5729	# <CJK>
0x3733	0x572A	# <CJK>
0x3734	0x572C	# <CJK>
0x3735	0x572E	# <CJK>
0x3736	0x572F	# <CJK>
0x3737	0x5733	# <CJK>
0x3738	0x5734	# <CJK>
0x3739	0x573D	# <CJK>
0x373A	0x573E	# <CJK>
0x373B	0x573F	# <CJK>
0x373C	0x5745	# <CJK>
0x373D	0x5746	# <CJK>
0x373E	0x574C	# <CJK>
0x373F	0x574D	# <CJK>
0x3740	0x5752	# <CJK>
0x3741	0x5762	# <CJK>
0x3742	0x5765	# <CJK>
0x3743	0x5767	# <CJK>
0x3744	0x5768	# <CJK>
0x3745	0x576B	# <CJK>
0x3746	0x576D	# <CJK>
0x3747	0x576E	# <CJK>
0x3748	0x576F	# <CJK>
0x3749	0x5770	# <CJK>
0x374A	0x5771	# <CJK>
0x374B	0x5773	# <CJK>
0x374C	0x5774	# <CJK>
0x374D	0x5775	# <CJK>
0x374E	0x5777	# <CJK>
0x374F	0x5779	# <CJK>
0x3750	0x577A	# <CJK>
0x3751	0x577B	# <CJK>
0x3752	0x577C	# <CJK>
0x3753	0x577E	# <CJK>
0x3754	0x5781	# <CJK>
0x3755	0x5783	# <CJK>
0x3756	0x578C	# <CJK>
0x3757	0x5794	# <CJK>
0x3758	0x5797	# <CJK>
0x3759	0x5799	# <CJK>
0x375A	0x579A	# <CJK>
0x375B	0x579C	# <CJK>
0x375C	0x579D	# <CJK>
0x375D	0x579E	# <CJK>
0x375E	0x579F	# <CJK>
0x375F	0x57A1	# <CJK>
0x3760	0x5795	# <CJK>
0x3761	0x57A7	# <CJK>
0x3762	0x57A8	# <CJK>
0x3763	0x57A9	# <CJK>
0x3764	0x57AC	# <CJK>
0x3765	0x57B8	# <CJK>
0x3766	0x57BD	# <CJK>
0x3767	0x57C7	# <CJK>
0x3768	0x57C8	# <CJK>
0x3769	0x57CC	# <CJK>
0x376A	0x57CF	# <CJK>
0x376B	0x57D5	# <CJK>
0x376C	0x57DD	# <CJK>
0x376D	0x57DE	# <CJK>
0x376E	0x57E4	# <CJK>
0x376F	0x57E6	# <CJK>
0x3770	0x57E7	# <CJK>
0x3771	0x57E9	# <CJK>
0x3772	0x57ED	# <CJK>
0x3773	0x57F0	# <CJK>
0x3774	0x57F5	# <CJK>
0x3775	0x57F6	# <CJK>
0x3776	0x57F8	# <CJK>
0x3777	0x57FD	# <CJK>
0x3778	0x57FE	# <CJK>
0x3779	0x57FF	# <CJK>
0x377A	0x5803	# <CJK>
0x377B	0x5804	# <CJK>
0x377C	0x5808	# <CJK>
0x377D	0x5809	# <CJK>
0x377E	0x57E1	# <CJK>
0x3821	0x580C	# <CJK>
0x3822	0x580D	# <CJK>
0x3823	0x581B	# <CJK>
0x3824	0x581E	# <CJK>
0x3825	0x581F	# <CJK>
0x3826	0x5820	# <CJK>
0x3827	0x5826	# <CJK>
0x3828	0x5827	# <CJK>
0x3829	0x582D	# <CJK>
0x382A	0x5832	# <CJK>
0x382B	0x5839	# <CJK>
0x382C	0x583F	# <CJK>
0x382D	0x5849	# <CJK>
0x382E	0x584C	# <CJK>
0x382F	0x584D	# <CJK>
0x3830	0x584F	# <CJK>
0x3831	0x5850	# <CJK>
0x3832	0x5855	# <CJK>
0x3833	0x585F	# <CJK>
0x3834	0x5861	# <CJK>
0x3835	0x5864	# <CJK>
0x3836	0x5867	# <CJK>
0x3837	0x5868	# <CJK>
0x3838	0x5878	# <CJK>
0x3839	0x587C	# <CJK>
0x383A	0x587F	# <CJK>
0x383B	0x5880	# <CJK>
0x383C	0x5881	# <CJK>
0x383D	0x5887	# <CJK>
0x383E	0x5888	# <CJK>
0x383F	0x5889	# <CJK>
0x3840	0x588A	# <CJK>
0x3841	0x588C	# <CJK>
0x3842	0x588D	# <CJK>
0x3843	0x588F	# <CJK>
0x3844	0x5890	# <CJK>
0x3845	0x5894	# <CJK>
0x3846	0x5896	# <CJK>
0x3847	0x589D	# <CJK>
0x3848	0x58A0	# <CJK>
0x3849	0x58A1	# <CJK>
0x384A	0x58A2	# <CJK>
0x384B	0x58A6	# <CJK>
0x384C	0x58A9	# <CJK>
0x384D	0x58B1	# <CJK>
0x384E	0x58B2	# <CJK>
0x384F	0x58C4	# <CJK>
0x3850	0x58BC	# <CJK>
0x3851	0x58C2	# <CJK>
0x3852	0x58C8	# <CJK>
0x3853	0x58CD	# <CJK>
0x3854	0x58CE	# <CJK>
0x3855	0x58D0	# <CJK>
0x3856	0x58D2	# <CJK>
0x3857	0x58D4	# <CJK>
0x3858	0x58D6	# <CJK>
0x3859	0x58DA	# <CJK>
0x385A	0x58DD	# <CJK>
0x385B	0x58E1	# <CJK>
0x385C	0x58E2	# <CJK>
0x385D	0x58E9	# <CJK>
0x385E	0x58F3	# <CJK>
0x385F	0x5905	# <CJK>
0x3860	0x5906	# <CJK>
0x3861	0x590B	# <CJK>
0x3862	0x590C	# <CJK>
0x3863	0x5912	# <CJK>
0x3864	0x5913	# <CJK>
0x3865	0x5914	# <CJK>
0x3866	0x8641	# <CJK>
0x3867	0x591D	# <CJK>
0x3868	0x5921	# <CJK>
0x3869	0x5923	# <CJK>
0x386A	0x5924	# <CJK>
0x386B	0x5928	# <CJK>
0x386C	0x592F	# <CJK>
0x386D	0x5930	# <CJK>
0x386E	0x5933	# <CJK>
0x386F	0x5935	# <CJK>
0x3870	0x5936	# <CJK>
0x3871	0x593F	# <CJK>
0x3872	0x5943	# <CJK>
0x3873	0x5946	# <CJK>
0x3874	0x5952	# <CJK>
0x3875	0x5953	# <CJK>
0x3876	0x5959	# <CJK>
0x3877	0x595B	# <CJK>
0x3878	0x595D	# <CJK>
0x3879	0x595E	# <CJK>
0x387A	0x595F	# <CJK>
0x387B	0x5961	# <CJK>
0x387C	0x5963	# <CJK>
0x387D	0x596B	# <CJK>
0x387E	0x596D	# <CJK>
0x3921	0x596F	# <CJK>
0x3922	0x5972	# <CJK>
0x3923	0x5975	# <CJK>
0x3924	0x5976	# <CJK>
0x3925	0x5979	# <CJK>
0x3926	0x597B	# <CJK>
0x3927	0x597C	# <CJK>
0x3928	0x598B	# <CJK>
0x3929	0x598C	# <CJK>
0x392A	0x598E	# <CJK>
0x392B	0x5992	# <CJK>
0x392C	0x5995	# <CJK>
0x392D	0x5997	# <CJK>
0x392E	0x599F	# <CJK>
0x392F	0x59A4	# <CJK>
0x3930	0x59A7	# <CJK>
0x3931	0x59AD	# <CJK>
0x3932	0x59AE	# <CJK>
0x3933	0x59AF	# <CJK>
0x3934	0x59B0	# <CJK>
0x3935	0x59B3	# <CJK>
0x3936	0x59B7	# <CJK>
0x3937	0x59BA	# <CJK>
0x3938	0x59BC	# <CJK>
0x3939	0x59C1	# <CJK>
0x393A	0x59C3	# <CJK>
0x393B	0x59C4	# <CJK>
0x393C	0x59C8	# <CJK>
0x393D	0x59CA	# <CJK>
0x393E	0x59CD	# <CJK>
0x393F	0x59D2	# <CJK>
0x3940	0x59DD	# <CJK>
0x3941	0x59DE	# <CJK>
0x3942	0x59DF	# <CJK>
0x3943	0x59E3	# <CJK>
0x3944	0x59E4	# <CJK>
0x3945	0x59E7	# <CJK>
0x3946	0x59EE	# <CJK>
0x3947	0x59EF	# <CJK>
0x3948	0x59F1	# <CJK>
0x3949	0x59F2	# <CJK>
0x394A	0x59F4	# <CJK>
0x394B	0x59F7	# <CJK>
0x394C	0x5A00	# <CJK>
0x394D	0x5A04	# <CJK>
0x394E	0x5A0C	# <CJK>
0x394F	0x5A0D	# <CJK>
0x3950	0x5A0E	# <CJK>
0x3951	0x5A12	# <CJK>
0x3952	0x5A13	# <CJK>
0x3953	0x5A1E	# <CJK>
0x3954	0x5A23	# <CJK>
0x3955	0x5A24	# <CJK>
0x3956	0x5A27	# <CJK>
0x3957	0x5A28	# <CJK>
0x3958	0x5A2A	# <CJK>
0x3959	0x5A2D	# <CJK>
0x395A	0x5A30	# <CJK>
0x395B	0x5A44	# <CJK>
0x395C	0x5A45	# <CJK>
0x395D	0x5A47	# <CJK>
0x395E	0x5A48	# <CJK>
0x395F	0x5A4C	# <CJK>
0x3960	0x5A50	# <CJK>
0x3961	0x5A55	# <CJK>
0x3962	0x5A5E	# <CJK>
0x3963	0x5A63	# <CJK>
0x3964	0x5A65	# <CJK>
0x3965	0x5A67	# <CJK>
0x3966	0x5A6D	# <CJK>
0x3967	0x5A77	# <CJK>
0x3968	0x5A7A	# <CJK>
0x3969	0x5A7B	# <CJK>
0x396A	0x5A7E	# <CJK>
0x396B	0x5A8B	# <CJK>
0x396C	0x5A90	# <CJK>
0x396D	0x5A93	# <CJK>
0x396E	0x5A96	# <CJK>
0x396F	0x5A99	# <CJK>
0x3970	0x5A9C	# <CJK>
0x3971	0x5A9E	# <CJK>
0x3972	0x5A9F	# <CJK>
0x3973	0x5AA0	# <CJK>
0x3974	0x5AA2	# <CJK>
0x3975	0x5AA7	# <CJK>
0x3976	0x5AAC	# <CJK>
0x3977	0x5AB1	# <CJK>
0x3978	0x5AB2	# <CJK>
0x3979	0x5AB3	# <CJK>
0x397A	0x5AB5	# <CJK>
0x397B	0x5AB8	# <CJK>
0x397C	0x5ABA	# <CJK>
0x397D	0x5ABB	# <CJK>
0x397E	0x5ABF	# <CJK>
0x3A21	0x5AC4	# <CJK>
0x3A22	0x5AC6	# <CJK>
0x3A23	0x5AC8	# <CJK>
0x3A24	0x5ACF	# <CJK>
0x3A25	0x5ADA	# <CJK>
0x3A26	0x5ADC	# <CJK>
0x3A27	0x5AE0	# <CJK>
0x3A28	0x5AE5	# <CJK>
0x3A29	0x5AEA	# <CJK>
0x3A2A	0x5AEE	# <CJK>
0x3A2B	0x5AF5	# <CJK>
0x3A2C	0x5AF6	# <CJK>
0x3A2D	0x5AFD	# <CJK>
0x3A2E	0x5B00	# <CJK>
0x3A2F	0x5B01	# <CJK>
0x3A30	0x5B08	# <CJK>
0x3A31	0x5B17	# <CJK>
0x3A32	0x5B34	# <CJK>
0x3A33	0x5B19	# <CJK>
0x3A34	0x5B1B	# <CJK>
0x3A35	0x5B1D	# <CJK>
0x3A36	0x5B21	# <CJK>
0x3A37	0x5B25	# <CJK>
0x3A38	0x5B2D	# <CJK>
0x3A39	0x5B38	# <CJK>
0x3A3A	0x5B41	# <CJK>
0x3A3B	0x5B4B	# <CJK>
0x3A3C	0x5B4C	# <CJK>
0x3A3D	0x5B52	# <CJK>
0x3A3E	0x5B56	# <CJK>
0x3A3F	0x5B5E	# <CJK>
0x3A40	0x5B68	# <CJK>
0x3A41	0x5B6E	# <CJK>
0x3A42	0x5B6F	# <CJK>
0x3A43	0x5B7C	# <CJK>
0x3A44	0x5B7D	# <CJK>
0x3A45	0x5B7E	# <CJK>
0x3A46	0x5B7F	# <CJK>
0x3A47	0x5B81	# <CJK>
0x3A48	0x5B84	# <CJK>
0x3A49	0x5B86	# <CJK>
0x3A4A	0x5B8A	# <CJK>
0x3A4B	0x5B8E	# <CJK>
0x3A4C	0x5B90	# <CJK>
0x3A4D	0x5B91	# <CJK>
0x3A4E	0x5B93	# <CJK>
0x3A4F	0x5B94	# <CJK>
0x3A50	0x5B96	# <CJK>
0x3A51	0x5BA8	# <CJK>
0x3A52	0x5BA9	# <CJK>
0x3A53	0x5BAC	# <CJK>
0x3A54	0x5BAD	# <CJK>
0x3A55	0x5BAF	# <CJK>
0x3A56	0x5BB1	# <CJK>
0x3A57	0x5BB2	# <CJK>
0x3A58	0x5BB7	# <CJK>
0x3A59	0x5BBA	# <CJK>
0x3A5A	0x5BBC	# <CJK>
0x3A5B	0x5BC0	# <CJK>
0x3A5C	0x5BC1	# <CJK>
0x3A5D	0x5BCD	# <CJK>
0x3A5E	0x5BCF	# <CJK>
0x3A5F	0x5BD6	# <CJK>
0x3A60	0x5BD7	# <CJK>
0x3A61	0x5BD8	# <CJK>
0x3A62	0x5BD9	# <CJK>
0x3A63	0x5BDA	# <CJK>
0x3A64	0x5BE0	# <CJK>
0x3A65	0x5BEF	# <CJK>
0x3A66	0x5BF1	# <CJK>
0x3A67	0x5BF4	# <CJK>
0x3A68	0x5BFD	# <CJK>
0x3A69	0x5C0C	# <CJK>
0x3A6A	0x5C17	# <CJK>
0x3A6B	0x5C1E	# <CJK>
0x3A6C	0x5C1F	# <CJK>
0x3A6D	0x5C23	# <CJK>
0x3A6E	0x5C26	# <CJK>
0x3A6F	0x5C29	# <CJK>
0x3A70	0x5C2B	# <CJK>
0x3A71	0x5C2C	# <CJK>
0x3A72	0x5C2E	# <CJK>
0x3A73	0x5C30	# <CJK>
0x3A74	0x5C32	# <CJK>
0x3A75	0x5C35	# <CJK>
0x3A76	0x5C36	# <CJK>
0x3A77	0x5C59	# <CJK>
0x3A78	0x5C5A	# <CJK>
0x3A79	0x5C5C	# <CJK>
0x3A7A	0x5C62	# <CJK>
0x3A7B	0x5C63	# <CJK>
0x3A7C	0x5C67	# <CJK>
0x3A7D	0x5C68	# <CJK>
0x3A7E	0x5C69	# <CJK>
0x3B21	0x5C6D	# <CJK>
0x3B22	0x5C70	# <CJK>
0x3B23	0x5C74	# <CJK>
0x3B24	0x5C75	# <CJK>
0x3B25	0x5C7A	# <CJK>
0x3B26	0x5C7B	# <CJK>
0x3B27	0x5C7C	# <CJK>
0x3B28	0x5C7D	# <CJK>
0x3B29	0x5C87	# <CJK>
0x3B2A	0x5C88	# <CJK>
0x3B2B	0x5C8A	# <CJK>
0x3B2C	0x5C8F	# <CJK>
0x3B2D	0x5C92	# <CJK>
0x3B2E	0x5C9D	# <CJK>
0x3B2F	0x5C9F	# <CJK>
0x3B30	0x5CA0	# <CJK>
0x3B31	0x5CA2	# <CJK>
0x3B32	0x5CA3	# <CJK>
0x3B33	0x5CA6	# <CJK>
0x3B34	0x5CAA	# <CJK>
0x3B35	0x5CB2	# <CJK>
0x3B36	0x5CB4	# <CJK>
0x3B37	0x5CB5	# <CJK>
0x3B38	0x5CBA	# <CJK>
0x3B39	0x5CC9	# <CJK>
0x3B3A	0x5CCB	# <CJK>
0x3B3B	0x5CD2	# <CJK>
0x3B3C	0x5CDD	# <CJK>
0x3B3D	0x5CD7	# <CJK>
0x3B3E	0x5CEE	# <CJK>
0x3B3F	0x5CF1	# <CJK>
0x3B40	0x5CF2	# <CJK>
0x3B41	0x5CF4	# <CJK>
0x3B42	0x5D01	# <CJK>
0x3B43	0x5D06	# <CJK>
0x3B44	0x5D0D	# <CJK>
0x3B45	0x5D12	# <CJK>
0x3B46	0x5D2B	# <CJK>
0x3B47	0x5D23	# <CJK>
0x3B48	0x5D24	# <CJK>
0x3B49	0x5D26	# <CJK>
0x3B4A	0x5D27	# <CJK>
0x3B4B	0x5D31	# <CJK>
0x3B4C	0x5D34	# <CJK>
0x3B4D	0x5D39	# <CJK>
0x3B4E	0x5D3D	# <CJK>
0x3B4F	0x5D3F	# <CJK>
0x3B50	0x5D42	# <CJK>
0x3B51	0x5D43	# <CJK>
0x3B52	0x5D46	# <CJK>
0x3B53	0x5D48	# <CJK>
0x3B54	0x5D55	# <CJK>
0x3B55	0x5D51	# <CJK>
0x3B56	0x5D59	# <CJK>
0x3B57	0x5D4A	# <CJK>
0x3B58	0x5D5F	# <CJK>
0x3B59	0x5D60	# <CJK>
0x3B5A	0x5D61	# <CJK>
0x3B5B	0x5D62	# <CJK>
0x3B5C	0x5D64	# <CJK>
0x3B5D	0x5D6A	# <CJK>
0x3B5E	0x5D6D	# <CJK>
0x3B5F	0x5D70	# <CJK>
0x3B60	0x5D79	# <CJK>
0x3B61	0x5D7A	# <CJK>
0x3B62	0x5D7E	# <CJK>
0x3B63	0x5D7F	# <CJK>
0x3B64	0x5D81	# <CJK>
0x3B65	0x5D83	# <CJK>
0x3B66	0x5D88	# <CJK>
0x3B67	0x5D8A	# <CJK>
0x3B68	0x5D92	# <CJK>
0x3B69	0x5D93	# <CJK>
0x3B6A	0x5D94	# <CJK>
0x3B6B	0x5D95	# <CJK>
0x3B6C	0x5D99	# <CJK>
0x3B6D	0x5D9B	# <CJK>
0x3B6E	0x5D9F	# <CJK>
0x3B6F	0x5DA0	# <CJK>
0x3B70	0x5DA7	# <CJK>
0x3B71	0x5DAB	# <CJK>
0x3B72	0x5DB0	# <CJK>
0x3B73	0x5DB4	# <CJK>
0x3B74	0x5DB8	# <CJK>
0x3B75	0x5DB9	# <CJK>
0x3B76	0x5DC3	# <CJK>
0x3B77	0x5DC7	# <CJK>
0x3B78	0x5DCB	# <CJK>
0x3B79	0x5DD0	# <CJK>
0x3B7A	0x5DCE	# <CJK>
0x3B7B	0x5DD8	# <CJK>
0x3B7C	0x5DD9	# <CJK>
0x3B7D	0x5DE0	# <CJK>
0x3B7E	0x5DE4	# <CJK>
0x3C21	0x5DE9	# <CJK>
0x3C22	0x5DF8	# <CJK>
0x3C23	0x5DF9	# <CJK>
0x3C24	0x5E00	# <CJK>
0x3C25	0x5E07	# <CJK>
0x3C26	0x5E0D	# <CJK>
0x3C27	0x5E12	# <CJK>
0x3C28	0x5E14	# <CJK>
0x3C29	0x5E15	# <CJK>
0x3C2A	0x5E18	# <CJK>
0x3C2B	0x5E1F	# <CJK>
0x3C2C	0x5E20	# <CJK>
0x3C2D	0x5E2E	# <CJK>
0x3C2E	0x5E28	# <CJK>
0x3C2F	0x5E32	# <CJK>
0x3C30	0x5E35	# <CJK>
0x3C31	0x5E3E	# <CJK>
0x3C32	0x5E4B	# <CJK>
0x3C33	0x5E50	# <CJK>
0x3C34	0x5E49	# <CJK>
0x3C35	0x5E51	# <CJK>
0x3C36	0x5E56	# <CJK>
0x3C37	0x5E58	# <CJK>
0x3C38	0x5E5B	# <CJK>
0x3C39	0x5E5C	# <CJK>
0x3C3A	0x5E5E	# <CJK>
0x3C3B	0x5E68	# <CJK>
0x3C3C	0x5E6A	# <CJK>
0x3C3D	0x5E6B	# <CJK>
0x3C3E	0x5E6C	# <CJK>
0x3C3F	0x5E6D	# <CJK>
0x3C40	0x5E6E	# <CJK>
0x3C41	0x5E70	# <CJK>
0x3C42	0x5E80	# <CJK>
0x3C43	0x5E8B	# <CJK>
0x3C44	0x5E8E	# <CJK>
0x3C45	0x5EA2	# <CJK>
0x3C46	0x5EA4	# <CJK>
0x3C47	0x5EA5	# <CJK>
0x3C48	0x5EA8	# <CJK>
0x3C49	0x5EAA	# <CJK>
0x3C4A	0x5EAC	# <CJK>
0x3C4B	0x5EB1	# <CJK>
0x3C4C	0x5EB3	# <CJK>
0x3C4D	0x5EBD	# <CJK>
0x3C4E	0x5EBE	# <CJK>
0x3C4F	0x5EBF	# <CJK>
0x3C50	0x5EC6	# <CJK>
0x3C51	0x5ECC	# <CJK>
0x3C52	0x5ECB	# <CJK>
0x3C53	0x5ECE	# <CJK>
0x3C54	0x5ED1	# <CJK>
0x3C55	0x5ED2	# <CJK>
0x3C56	0x5ED4	# <CJK>
0x3C57	0x5ED5	# <CJK>
0x3C58	0x5EDC	# <CJK>
0x3C59	0x5EDE	# <CJK>
0x3C5A	0x5EE5	# <CJK>
0x3C5B	0x5EEB	# <CJK>
0x3C5C	0x5F02	# <CJK>
0x3C5D	0x5F06	# <CJK>
0x3C5E	0x5F07	# <CJK>
0x3C5F	0x5F08	# <CJK>
0x3C60	0x5F0E	# <CJK>
0x3C61	0x5F19	# <CJK>
0x3C62	0x5F1C	# <CJK>
0x3C63	0x5F1D	# <CJK>
0x3C64	0x5F21	# <CJK>
0x3C65	0x5F22	# <CJK>
0x3C66	0x5F23	# <CJK>
0x3C67	0x5F24	# <CJK>
0x3C68	0x5F28	# <CJK>
0x3C69	0x5F2B	# <CJK>
0x3C6A	0x5F2C	# <CJK>
0x3C6B	0x5F2E	# <CJK>
0x3C6C	0x5F30	# <CJK>
0x3C6D	0x5F34	# <CJK>
0x3C6E	0x5F36	# <CJK>
0x3C6F	0x5F3B	# <CJK>
0x3C70	0x5F3D	# <CJK>
0x3C71	0x5F3F	# <CJK>
0x3C72	0x5F40	# <CJK>
0x3C73	0x5F44	# <CJK>
0x3C74	0x5F45	# <CJK>
0x3C75	0x5F47	# <CJK>
0x3C76	0x5F4D	# <CJK>
0x3C77	0x5F50	# <CJK>
0x3C78	0x5F54	# <CJK>
0x3C79	0x5F58	# <CJK>
0x3C7A	0x5F5B	# <CJK>
0x3C7B	0x5F60	# <CJK>
0x3C7C	0x5F63	# <CJK>
0x3C7D	0x5F64	# <CJK>
0x3C7E	0x5F67	# <CJK>
0x3D21	0x5F6F	# <CJK>
0x3D22	0x5F72	# <CJK>
0x3D23	0x5F74	# <CJK>
0x3D24	0x5F75	# <CJK>
0x3D25	0x5F78	# <CJK>
0x3D26	0x5F7A	# <CJK>
0x3D27	0x5F7D	# <CJK>
0x3D28	0x5F7E	# <CJK>
0x3D29	0x5F89	# <CJK>
0x3D2A	0x5F8D	# <CJK>
0x3D2B	0x5F8F	# <CJK>
0x3D2C	0x5F96	# <CJK>
0x3D2D	0x5F9C	# <CJK>
0x3D2E	0x5F9D	# <CJK>
0x3D2F	0x5FA2	# <CJK>
0x3D30	0x5FA7	# <CJK>
0x3D31	0x5FAB	# <CJK>
0x3D32	0x5FA4	# <CJK>
0x3D33	0x5FAC	# <CJK>
0x3D34	0x5FAF	# <CJK>
0x3D35	0x5FB0	# <CJK>
0x3D36	0x5FB1	# <CJK>
0x3D37	0x5FB8	# <CJK>
0x3D38	0x5FC4	# <CJK>
0x3D39	0x5FC7	# <CJK>
0x3D3A	0x5FC8	# <CJK>
0x3D3B	0x5FC9	# <CJK>
0x3D3C	0x5FCB	# <CJK>
0x3D3D	0x5FD0	# <CJK>
0x3D3E	0x5FD1	# <CJK>
0x3D3F	0x5FD2	# <CJK>
0x3D40	0x5FD3	# <CJK>
0x3D41	0x5FD4	# <CJK>
0x3D42	0x5FDE	# <CJK>
0x3D43	0x5FE1	# <CJK>
0x3D44	0x5FE2	# <CJK>
0x3D45	0x5FE8	# <CJK>
0x3D46	0x5FE9	# <CJK>
0x3D47	0x5FEA	# <CJK>
0x3D48	0x5FEC	# <CJK>
0x3D49	0x5FED	# <CJK>
0x3D4A	0x5FEE	# <CJK>
0x3D4B	0x5FEF	# <CJK>
0x3D4C	0x5FF2	# <CJK>
0x3D4D	0x5FF3	# <CJK>
0x3D4E	0x5FF6	# <CJK>
0x3D4F	0x5FFA	# <CJK>
0x3D50	0x5FFC	# <CJK>
0x3D51	0x6007	# <CJK>
0x3D52	0x600A	# <CJK>
0x3D53	0x600D	# <CJK>
0x3D54	0x6013	# <CJK>
0x3D55	0x6014	# <CJK>
0x3D56	0x6017	# <CJK>
0x3D57	0x6018	# <CJK>
0x3D58	0x601A	# <CJK>
0x3D59	0x601F	# <CJK>
0x3D5A	0x6024	# <CJK>
0x3D5B	0x602D	# <CJK>
0x3D5C	0x6033	# <CJK>
0x3D5D	0x6035	# <CJK>
0x3D5E	0x6040	# <CJK>
0x3D5F	0x6047	# <CJK>
0x3D60	0x6048	# <CJK>
0x3D61	0x6049	# <CJK>
0x3D62	0x604C	# <CJK>
0x3D63	0x6051	# <CJK>
0x3D64	0x6054	# <CJK>
0x3D65	0x6056	# <CJK>
0x3D66	0x6057	# <CJK>
0x3D67	0x605D	# <CJK>
0x3D68	0x6061	# <CJK>
0x3D69	0x6067	# <CJK>
0x3D6A	0x6071	# <CJK>
0x3D6B	0x607E	# <CJK>
0x3D6C	0x607F	# <CJK>
0x3D6D	0x6082	# <CJK>
0x3D6E	0x6086	# <CJK>
0x3D6F	0x6088	# <CJK>
0x3D70	0x608A	# <CJK>
0x3D71	0x608E	# <CJK>
0x3D72	0x6091	# <CJK>
0x3D73	0x6093	# <CJK>
0x3D74	0x6095	# <CJK>
0x3D75	0x6098	# <CJK>
0x3D76	0x609D	# <CJK>
0x3D77	0x609E	# <CJK>
0x3D78	0x60A2	# <CJK>
0x3D79	0x60A4	# <CJK>
0x3D7A	0x60A5	# <CJK>
0x3D7B	0x60A8	# <CJK>
0x3D7C	0x60B0	# <CJK>
0x3D7D	0x60B1	# <CJK>
0x3D7E	0x60B7	# <CJK>
0x3E21	0x60BB	# <CJK>
0x3E22	0x60BE	# <CJK>
0x3E23	0x60C2	# <CJK>
0x3E24	0x60C4	# <CJK>
0x3E25	0x60C8	# <CJK>
0x3E26	0x60C9	# <CJK>
0x3E27	0x60CA	# <CJK>
0x3E28	0x60CB	# <CJK>
0x3E29	0x60CE	# <CJK>
0x3E2A	0x60CF	# <CJK>
0x3E2B	0x60D4	# <CJK>
0x3E2C	0x60D5	# <CJK>
0x3E2D	0x60D9	# <CJK>
0x3E2E	0x60DB	# <CJK>
0x3E2F	0x60DD	# <CJK>
0x3E30	0x60DE	# <CJK>
0x3E31	0x60E2	# <CJK>
0x3E32	0x60E5	# <CJK>
0x3E33	0x60F2	# <CJK>
0x3E34	0x60F5	# <CJK>
0x3E35	0x60F8	# <CJK>
0x3E36	0x60FC	# <CJK>
0x3E37	0x60FD	# <CJK>
0x3E38	0x6102	# <CJK>
0x3E39	0x6107	# <CJK>
0x3E3A	0x610A	# <CJK>
0x3E3B	0x610C	# <CJK>
0x3E3C	0x6110	# <CJK>
0x3E3D	0x6111	# <CJK>
0x3E3E	0x6112	# <CJK>
0x3E3F	0x6113	# <CJK>
0x3E40	0x6114	# <CJK>
0x3E41	0x6116	# <CJK>
0x3E42	0x6117	# <CJK>
0x3E43	0x6119	# <CJK>
0x3E44	0x611C	# <CJK>
0x3E45	0x611E	# <CJK>
0x3E46	0x6122	# <CJK>
0x3E47	0x612A	# <CJK>
0x3E48	0x612B	# <CJK>
0x3E49	0x6130	# <CJK>
0x3E4A	0x6131	# <CJK>
0x3E4B	0x6135	# <CJK>
0x3E4C	0x6136	# <CJK>
0x3E4D	0x6137	# <CJK>
0x3E4E	0x6139	# <CJK>
0x3E4F	0x6141	# <CJK>
0x3E50	0x6145	# <CJK>
0x3E51	0x6146	# <CJK>
0x3E52	0x6149	# <CJK>
0x3E53	0x615E	# <CJK>
0x3E54	0x6160	# <CJK>
0x3E55	0x616C	# <CJK>
0x3E56	0x6172	# <CJK>
0x3E57	0x6178	# <CJK>
0x3E58	0x617B	# <CJK>
0x3E59	0x617C	# <CJK>
0x3E5A	0x617F	# <CJK>
0x3E5B	0x6180	# <CJK>
0x3E5C	0x6181	# <CJK>
0x3E5D	0x6183	# <CJK>
0x3E5E	0x6184	# <CJK>
0x3E5F	0x618B	# <CJK>
0x3E60	0x618D	# <CJK>
0x3E61	0x6192	# <CJK>
0x3E62	0x6193	# <CJK>
0x3E63	0x6197	# <CJK>
0x3E64	0x6198	# <CJK>
0x3E65	0x619C	# <CJK>
0x3E66	0x619D	# <CJK>
0x3E67	0x619F	# <CJK>
0x3E68	0x61A0	# <CJK>
0x3E69	0x61A5	# <CJK>
0x3E6A	0x61A8	# <CJK>
0x3E6B	0x61AA	# <CJK>
0x3E6C	0x61AD	# <CJK>
0x3E6D	0x61B8	# <CJK>
0x3E6E	0x61B9	# <CJK>
0x3E6F	0x61BC	# <CJK>
0x3E70	0x61C0	# <CJK>
0x3E71	0x61C1	# <CJK>
0x3E72	0x61C2	# <CJK>
0x3E73	0x61CE	# <CJK>
0x3E74	0x61CF	# <CJK>
0x3E75	0x61D5	# <CJK>
0x3E76	0x61DC	# <CJK>
0x3E77	0x61DD	# <CJK>
0x3E78	0x61DE	# <CJK>
0x3E79	0x61DF	# <CJK>
0x3E7A	0x61E1	# <CJK>
0x3E7B	0x61E2	# <CJK>
0x3E7C	0x61E7	# <CJK>
0x3E7D	0x61E9	# <CJK>
0x3E7E	0x61E5	# <CJK>
0x3F21	0x61EC	# <CJK>
0x3F22	0x61ED	# <CJK>
0x3F23	0x61EF	# <CJK>
0x3F24	0x6201	# <CJK>
0x3F25	0x6203	# <CJK>
0x3F26	0x6204	# <CJK>
0x3F27	0x6207	# <CJK>
0x3F28	0x6213	# <CJK>
0x3F29	0x6215	# <CJK>
0x3F2A	0x621C	# <CJK>
0x3F2B	0x6220	# <CJK>
0x3F2C	0x6222	# <CJK>
0x3F2D	0x6223	# <CJK>
0x3F2E	0x6227	# <CJK>
0x3F2F	0x6229	# <CJK>
0x3F30	0x622B	# <CJK>
0x3F31	0x6239	# <CJK>
0x3F32	0x623D	# <CJK>
0x3F33	0x6242	# <CJK>
0x3F34	0x6243	# <CJK>
0x3F35	0x6244	# <CJK>
0x3F36	0x6246	# <CJK>
0x3F37	0x624C	# <CJK>
0x3F38	0x6250	# <CJK>
0x3F39	0x6251	# <CJK>
0x3F3A	0x6252	# <CJK>
0x3F3B	0x6254	# <CJK>
0x3F3C	0x6256	# <CJK>
0x3F3D	0x625A	# <CJK>
0x3F3E	0x625C	# <CJK>
0x3F3F	0x6264	# <CJK>
0x3F40	0x626D	# <CJK>
0x3F41	0x626F	# <CJK>
0x3F42	0x6273	# <CJK>
0x3F43	0x627A	# <CJK>
0x3F44	0x627D	# <CJK>
0x3F45	0x628D	# <CJK>
0x3F46	0x628E	# <CJK>
0x3F47	0x628F	# <CJK>
0x3F48	0x6290	# <CJK>
0x3F49	0x62A6	# <CJK>
0x3F4A	0x62A8	# <CJK>
0x3F4B	0x62B3	# <CJK>
0x3F4C	0x62B6	# <CJK>
0x3F4D	0x62B7	# <CJK>
0x3F4E	0x62BA	# <CJK>
0x3F4F	0x62BE	# <CJK>
0x3F50	0x62BF	# <CJK>
0x3F51	0x62C4	# <CJK>
0x3F52	0x62CE	# <CJK>
0x3F53	0x62D5	# <CJK>
0x3F54	0x62D6	# <CJK>
0x3F55	0x62DA	# <CJK>
0x3F56	0x62EA	# <CJK>
0x3F57	0x62F2	# <CJK>
0x3F58	0x62F4	# <CJK>
0x3F59	0x62FC	# <CJK>
0x3F5A	0x62FD	# <CJK>
0x3F5B	0x6303	# <CJK>
0x3F5C	0x6304	# <CJK>
0x3F5D	0x630A	# <CJK>
0x3F5E	0x630B	# <CJK>
0x3F5F	0x630D	# <CJK>
0x3F60	0x6310	# <CJK>
0x3F61	0x6313	# <CJK>
0x3F62	0x6316	# <CJK>
0x3F63	0x6318	# <CJK>
0x3F64	0x6329	# <CJK>
0x3F65	0x632A	# <CJK>
0x3F66	0x632D	# <CJK>
0x3F67	0x6335	# <CJK>
0x3F68	0x6336	# <CJK>
0x3F69	0x6339	# <CJK>
0x3F6A	0x633C	# <CJK>
0x3F6B	0x6341	# <CJK>
0x3F6C	0x6342	# <CJK>
0x3F6D	0x6343	# <CJK>
0x3F6E	0x6344	# <CJK>
0x3F6F	0x6346	# <CJK>
0x3F70	0x634A	# <CJK>
0x3F71	0x634B	# <CJK>
0x3F72	0x634E	# <CJK>
0x3F73	0x6352	# <CJK>
0x3F74	0x6353	# <CJK>
0x3F75	0x6354	# <CJK>
0x3F76	0x6358	# <CJK>
0x3F77	0x635B	# <CJK>
0x3F78	0x6365	# <CJK>
0x3F79	0x6366	# <CJK>
0x3F7A	0x636C	# <CJK>
0x3F7B	0x636D	# <CJK>
0x3F7C	0x6371	# <CJK>
0x3F7D	0x6374	# <CJK>
0x3F7E	0x6375	# <CJK>
0x4021	0x6378	# <CJK>
0x4022	0x637C	# <CJK>
0x4023	0x637D	# <CJK>
0x4024	0x637F	# <CJK>
0x4025	0x6382	# <CJK>
0x4026	0x6384	# <CJK>
0x4027	0x6387	# <CJK>
0x4028	0x638A	# <CJK>
0x4029	0x6390	# <CJK>
0x402A	0x6394	# <CJK>
0x402B	0x6395	# <CJK>
0x402C	0x6399	# <CJK>
0x402D	0x639A	# <CJK>
0x402E	0x639E	# <CJK>
0x402F	0x63A4	# <CJK>
0x4030	0x63A6	# <CJK>
0x4031	0x63AD	# <CJK>
0x4032	0x63AE	# <CJK>
0x4033	0x63AF	# <CJK>
0x4034	0x63BD	# <CJK>
0x4035	0x63C1	# <CJK>
0x4036	0x63C5	# <CJK>
0x4037	0x63C8	# <CJK>
0x4038	0x63CE	# <CJK>
0x4039	0x63D1	# <CJK>
0x403A	0x63D3	# <CJK>
0x403B	0x63D4	# <CJK>
0x403C	0x63D5	# <CJK>
0x403D	0x63DC	# <CJK>
0x403E	0x63E0	# <CJK>
0x403F	0x63E5	# <CJK>
0x4040	0x63EA	# <CJK>
0x4041	0x63EC	# <CJK>
0x4042	0x63F2	# <CJK>
0x4043	0x63F3	# <CJK>
0x4044	0x63F5	# <CJK>
0x4045	0x63F8	# <CJK>
0x4046	0x63F9	# <CJK>
0x4047	0x6409	# <CJK>
0x4048	0x640A	# <CJK>
0x4049	0x6410	# <CJK>
0x404A	0x6412	# <CJK>
0x404B	0x6414	# <CJK>
0x404C	0x6418	# <CJK>
0x404D	0x641E	# <CJK>
0x404E	0x6420	# <CJK>
0x404F	0x6422	# <CJK>
0x4050	0x6424	# <CJK>
0x4051	0x6425	# <CJK>
0x4052	0x6429	# <CJK>
0x4053	0x642A	# <CJK>
0x4054	0x642F	# <CJK>
0x4055	0x6430	# <CJK>
0x4056	0x6435	# <CJK>
0x4057	0x643D	# <CJK>
0x4058	0x643F	# <CJK>
0x4059	0x644B	# <CJK>
0x405A	0x644F	# <CJK>
0x405B	0x6451	# <CJK>
0x405C	0x6452	# <CJK>
0x405D	0x6453	# <CJK>
0x405E	0x6454	# <CJK>
0x405F	0x645A	# <CJK>
0x4060	0x645B	# <CJK>
0x4061	0x645C	# <CJK>
0x4062	0x645D	# <CJK>
0x4063	0x645F	# <CJK>
0x4064	0x6460	# <CJK>
0x4065	0x6461	# <CJK>
0x4066	0x6463	# <CJK>
0x4067	0x646D	# <CJK>
0x4068	0x6473	# <CJK>
0x4069	0x6474	# <CJK>
0x406A	0x647B	# <CJK>
0x406B	0x647D	# <CJK>
0x406C	0x6485	# <CJK>
0x406D	0x6487	# <CJK>
0x406E	0x648F	# <CJK>
0x406F	0x6490	# <CJK>
0x4070	0x6491	# <CJK>
0x4071	0x6498	# <CJK>
0x4072	0x6499	# <CJK>
0x4073	0x649B	# <CJK>
0x4074	0x649D	# <CJK>
0x4075	0x649F	# <CJK>
0x4076	0x64A1	# <CJK>
0x4077	0x64A3	# <CJK>
0x4078	0x64A6	# <CJK>
0x4079	0x64A8	# <CJK>
0x407A	0x64AC	# <CJK>
0x407B	0x64B3	# <CJK>
0x407C	0x64BD	# <CJK>
0x407D	0x64BE	# <CJK>
0x407E	0x64BF	# <CJK>
0x4121	0x64C4	# <CJK>
0x4122	0x64C9	# <CJK>
0x4123	0x64CA	# <CJK>
0x4124	0x64CB	# <CJK>
0x4125	0x64CC	# <CJK>
0x4126	0x64CE	# <CJK>
0x4127	0x64D0	# <CJK>
0x4128	0x64D1	# <CJK>
0x4129	0x64D5	# <CJK>
0x412A	0x64D7	# <CJK>
0x412B	0x64E4	# <CJK>
0x412C	0x64E5	# <CJK>
0x412D	0x64E9	# <CJK>
0x412E	0x64EA	# <CJK>
0x412F	0x64ED	# <CJK>
0x4130	0x64F0	# <CJK>
0x4131	0x64F5	# <CJK>
0x4132	0x64F7	# <CJK>
0x4133	0x64FB	# <CJK>
0x4134	0x64FF	# <CJK>
0x4135	0x6501	# <CJK>
0x4136	0x6504	# <CJK>
0x4137	0x6508	# <CJK>
0x4138	0x6509	# <CJK>
0x4139	0x650A	# <CJK>
0x413A	0x650F	# <CJK>
0x413B	0x6513	# <CJK>
0x413C	0x6514	# <CJK>
0x413D	0x6516	# <CJK>
0x413E	0x6519	# <CJK>
0x413F	0x651B	# <CJK>
0x4140	0x651E	# <CJK>
0x4141	0x651F	# <CJK>
0x4142	0x6522	# <CJK>
0x4143	0x6526	# <CJK>
0x4144	0x6529	# <CJK>
0x4145	0x652E	# <CJK>
0x4146	0x6531	# <CJK>
0x4147	0x653A	# <CJK>
0x4148	0x653C	# <CJK>
0x4149	0x653D	# <CJK>
0x414A	0x6543	# <CJK>
0x414B	0x6547	# <CJK>
0x414C	0x6549	# <CJK>
0x414D	0x6550	# <CJK>
0x414E	0x6552	# <CJK>
0x414F	0x6554	# <CJK>
0x4150	0x655F	# <CJK>
0x4151	0x6560	# <CJK>
0x4152	0x6567	# <CJK>
0x4153	0x656B	# <CJK>
0x4154	0x657A	# <CJK>
0x4155	0x657D	# <CJK>
0x4156	0x6581	# <CJK>
0x4157	0x6585	# <CJK>
0x4158	0x658A	# <CJK>
0x4159	0x6592	# <CJK>
0x415A	0x6595	# <CJK>
0x415B	0x6598	# <CJK>
0x415C	0x659D	# <CJK>
0x415D	0x65A0	# <CJK>
0x415E	0x65A3	# <CJK>
0x415F	0x65A6	# <CJK>
0x4160	0x65AE	# <CJK>
0x4161	0x65B2	# <CJK>
0x4162	0x65B3	# <CJK>
0x4163	0x65B4	# <CJK>
0x4164	0x65BF	# <CJK>
0x4165	0x65C2	# <CJK>
0x4166	0x65C8	# <CJK>
0x4167	0x65C9	# <CJK>
0x4168	0x65CE	# <CJK>
0x4169	0x65D0	# <CJK>
0x416A	0x65D4	# <CJK>
0x416B	0x65D6	# <CJK>
0x416C	0x65D8	# <CJK>
0x416D	0x65DF	# <CJK>
0x416E	0x65F0	# <CJK>
0x416F	0x65F2	# <CJK>
0x4170	0x65F4	# <CJK>
0x4171	0x65F5	# <CJK>
0x4172	0x65F9	# <CJK>
0x4173	0x65FE	# <CJK>
0x4174	0x65FF	# <CJK>
0x4175	0x6600	# <CJK>
0x4176	0x6604	# <CJK>
0x4177	0x6608	# <CJK>
0x4178	0x6609	# <CJK>
0x4179	0x660D	# <CJK>
0x417A	0x6611	# <CJK>
0x417B	0x6612	# <CJK>
0x417C	0x6615	# <CJK>
0x417D	0x6616	# <CJK>
0x417E	0x661D	# <CJK>
0x4221	0x661E	# <CJK>
0x4222	0x6621	# <CJK>
0x4223	0x6622	# <CJK>
0x4224	0x6623	# <CJK>
0x4225	0x6624	# <CJK>
0x4226	0x6626	# <CJK>
0x4227	0x6629	# <CJK>
0x4228	0x662A	# <CJK>
0x4229	0x662B	# <CJK>
0x422A	0x662C	# <CJK>
0x422B	0x662E	# <CJK>
0x422C	0x6630	# <CJK>
0x422D	0x6631	# <CJK>
0x422E	0x6633	# <CJK>
0x422F	0x6639	# <CJK>
0x4230	0x6637	# <CJK>
0x4231	0x6640	# <CJK>
0x4232	0x6645	# <CJK>
0x4233	0x6646	# <CJK>
0x4234	0x664A	# <CJK>
0x4235	0x664C	# <CJK>
0x4236	0x6651	# <CJK>
0x4237	0x664E	# <CJK>
0x4238	0x6657	# <CJK>
0x4239	0x6658	# <CJK>
0x423A	0x6659	# <CJK>
0x423B	0x665B	# <CJK>
0x423C	0x665C	# <CJK>
0x423D	0x6660	# <CJK>
0x423E	0x6661	# <CJK>
0x423F	0x66FB	# <CJK>
0x4240	0x666A	# <CJK>
0x4241	0x666B	# <CJK>
0x4242	0x666C	# <CJK>
0x4243	0x667E	# <CJK>
0x4244	0x6673	# <CJK>
0x4245	0x6675	# <CJK>
0x4246	0x667F	# <CJK>
0x4247	0x6677	# <CJK>
0x4248	0x6678	# <CJK>
0x4249	0x6679	# <CJK>
0x424A	0x667B	# <CJK>
0x424B	0x6680	# <CJK>
0x424C	0x667C	# <CJK>
0x424D	0x668B	# <CJK>
0x424E	0x668C	# <CJK>
0x424F	0x668D	# <CJK>
0x4250	0x6690	# <CJK>
0x4251	0x6692	# <CJK>
0x4252	0x6699	# <CJK>
0x4253	0x669A	# <CJK>
0x4254	0x669B	# <CJK>
0x4255	0x669C	# <CJK>
0x4256	0x669F	# <CJK>
0x4257	0x66A0	# <CJK>
0x4258	0x66A4	# <CJK>
0x4259	0x66AD	# <CJK>
0x425A	0x66B1	# <CJK>
0x425B	0x66B2	# <CJK>
0x425C	0x66B5	# <CJK>
0x425D	0x66BB	# <CJK>
0x425E	0x66BF	# <CJK>
0x425F	0x66C0	# <CJK>
0x4260	0x66C2	# <CJK>
0x4261	0x66C3	# <CJK>
0x4262	0x66C8	# <CJK>
0x4263	0x66CC	# <CJK>
0x4264	0x66CE	# <CJK>
0x4265	0x66CF	# <CJK>
0x4266	0x66D4	# <CJK>
0x4267	0x66DB	# <CJK>
0x4268	0x66DF	# <CJK>
0x4269	0x66E8	# <CJK>
0x426A	0x66EB	# <CJK>
0x426B	0x66EC	# <CJK>
0x426C	0x66EE	# <CJK>
0x426D	0x66FA	# <CJK>
0x426E	0x6705	# <CJK>
0x426F	0x6707	# <CJK>
0x4270	0x670E	# <CJK>
0x4271	0x6713	# <CJK>
0x4272	0x6719	# <CJK>
0x4273	0x671C	# <CJK>
0x4274	0x6720	# <CJK>
0x4275	0x6722	# <CJK>
0x4276	0x6733	# <CJK>
0x4277	0x673E	# <CJK>
0x4278	0x6745	# <CJK>
0x4279	0x6747	# <CJK>
0x427A	0x6748	# <CJK>
0x427B	0x674C	# <CJK>
0x427C	0x6754	# <CJK>
0x427D	0x6755	# <CJK>
0x427E	0x675D	# <CJK>
0x4321	0x6766	# <CJK>
0x4322	0x676C	# <CJK>
0x4323	0x676E	# <CJK>
0x4324	0x6774	# <CJK>
0x4325	0x6776	# <CJK>
0x4326	0x677B	# <CJK>
0x4327	0x6781	# <CJK>
0x4328	0x6784	# <CJK>
0x4329	0x678E	# <CJK>
0x432A	0x678F	# <CJK>
0x432B	0x6791	# <CJK>
0x432C	0x6793	# <CJK>
0x432D	0x6796	# <CJK>
0x432E	0x6798	# <CJK>
0x432F	0x6799	# <CJK>
0x4330	0x679B	# <CJK>
0x4331	0x67B0	# <CJK>
0x4332	0x67B1	# <CJK>
0x4333	0x67B2	# <CJK>
0x4334	0x67B5	# <CJK>
0x4335	0x67BB	# <CJK>
0x4336	0x67BC	# <CJK>
0x4337	0x67BD	# <CJK>
0x4338	0x67F9	# <CJK>
0x4339	0x67C0	# <CJK>
0x433A	0x67C2	# <CJK>
0x433B	0x67C3	# <CJK>
0x433C	0x67C5	# <CJK>
0x433D	0x67C8	# <CJK>
0x433E	0x67C9	# <CJK>
0x433F	0x67D2	# <CJK>
0x4340	0x67D7	# <CJK>
0x4341	0x67D9	# <CJK>
0x4342	0x67DC	# <CJK>
0x4343	0x67E1	# <CJK>
0x4344	0x67E6	# <CJK>
0x4345	0x67F0	# <CJK>
0x4346	0x67F2	# <CJK>
0x4347	0x67F6	# <CJK>
0x4348	0x67F7	# <CJK>
0x4349	0x6852	# <CJK>
0x434A	0x6814	# <CJK>
0x434B	0x6819	# <CJK>
0x434C	0x681D	# <CJK>
0x434D	0x681F	# <CJK>
0x434E	0x6828	# <CJK>
0x434F	0x6827	# <CJK>
0x4350	0x682C	# <CJK>
0x4351	0x682D	# <CJK>
0x4352	0x682F	# <CJK>
0x4353	0x6830	# <CJK>
0x4354	0x6831	# <CJK>
0x4355	0x6833	# <CJK>
0x4356	0x683B	# <CJK>
0x4357	0x683F	# <CJK>
0x4358	0x6844	# <CJK>
0x4359	0x6845	# <CJK>
0x435A	0x684A	# <CJK>
0x435B	0x684C	# <CJK>
0x435C	0x6855	# <CJK>
0x435D	0x6857	# <CJK>
0x435E	0x6858	# <CJK>
0x435F	0x685B	# <CJK>
0x4360	0x686B	# <CJK>
0x4361	0x686E	# <CJK>
0x4362	0x686F	# <CJK>
0x4363	0x6870	# <CJK>
0x4364	0x6871	# <CJK>
0x4365	0x6872	# <CJK>
0x4366	0x6875	# <CJK>
0x4367	0x6879	# <CJK>
0x4368	0x687A	# <CJK>
0x4369	0x687B	# <CJK>
0x436A	0x687C	# <CJK>
0x436B	0x6882	# <CJK>
0x436C	0x6884	# <CJK>
0x436D	0x6886	# <CJK>
0x436E	0x6888	# <CJK>
0x436F	0x6896	# <CJK>
0x4370	0x6898	# <CJK>
0x4371	0x689A	# <CJK>
0x4372	0x689C	# <CJK>
0x4373	0x68A1	# <CJK>
0x4374	0x68A3	# <CJK>
0x4375	0x68A5	# <CJK>
0x4376	0x68A9	# <CJK>
0x4377	0x68AA	# <CJK>
0x4378	0x68AE	# <CJK>
0x4379	0x68B2	# <CJK>
0x437A	0x68BB	# <CJK>
0x437B	0x68C5	# <CJK>
0x437C	0x68C8	# <CJK>
0x437D	0x68CC	# <CJK>
0x437E	0x68CF	# <CJK>
0x4421	0x68D0	# <CJK>
0x4422	0x68D1	# <CJK>
0x4423	0x68D3	# <CJK>
0x4424	0x68D6	# <CJK>
0x4425	0x68D9	# <CJK>
0x4426	0x68DC	# <CJK>
0x4427	0x68DD	# <CJK>
0x4428	0x68E5	# <CJK>
0x4429	0x68E8	# <CJK>
0x442A	0x68EA	# <CJK>
0x442B	0x68EB	# <CJK>
0x442C	0x68EC	# <CJK>
0x442D	0x68ED	# <CJK>
0x442E	0x68F0	# <CJK>
0x442F	0x68F1	# <CJK>
0x4430	0x68F5	# <CJK>
0x4431	0x68F6	# <CJK>
0x4432	0x68FB	# <CJK>
0x4433	0x68FC	# <CJK>
0x4434	0x68FD	# <CJK>
0x4435	0x6906	# <CJK>
0x4436	0x6909	# <CJK>
0x4437	0x690A	# <CJK>
0x4438	0x6910	# <CJK>
0x4439	0x6911	# <CJK>
0x443A	0x6913	# <CJK>
0x443B	0x6916	# <CJK>
0x443C	0x6917	# <CJK>
0x443D	0x6931	# <CJK>
0x443E	0x6933	# <CJK>
0x443F	0x6935	# <CJK>
0x4440	0x6938	# <CJK>
0x4441	0x693B	# <CJK>
0x4442	0x6942	# <CJK>
0x4443	0x6945	# <CJK>
0x4444	0x6949	# <CJK>
0x4445	0x694E	# <CJK>
0x4446	0x6957	# <CJK>
0x4447	0x695B	# <CJK>
0x4448	0x6963	# <CJK>
0x4449	0x6964	# <CJK>
0x444A	0x6965	# <CJK>
0x444B	0x6966	# <CJK>
0x444C	0x6968	# <CJK>
0x444D	0x6969	# <CJK>
0x444E	0x696C	# <CJK>
0x444F	0x6970	# <CJK>
0x4450	0x6971	# <CJK>
0x4451	0x6972	# <CJK>
0x4452	0x697A	# <CJK>
0x4453	0x697B	# <CJK>
0x4454	0x697F	# <CJK>
0x4455	0x6980	# <CJK>
0x4456	0x698D	# <CJK>
0x4457	0x6992	# <CJK>
0x4458	0x6996	# <CJK>
0x4459	0x6998	# <CJK>
0x445A	0x69A1	# <CJK>
0x445B	0x69A5	# <CJK>
0x445C	0x69A6	# <CJK>
0x445D	0x69A8	# <CJK>
0x445E	0x69AB	# <CJK>
0x445F	0x69AD	# <CJK>
0x4460	0x69AF	# <CJK>
0x4461	0x69B7	# <CJK>
0x4462	0x69B8	# <CJK>
0x4463	0x69BA	# <CJK>
0x4464	0x69BC	# <CJK>
0x4465	0x69C5	# <CJK>
0x4466	0x69C8	# <CJK>
0x4467	0x69D1	# <CJK>
0x4468	0x69D6	# <CJK>
0x4469	0x69D7	# <CJK>
0x446A	0x69E2	# <CJK>
0x446B	0x69E5	# <CJK>
0x446C	0x69EE	# <CJK>
0x446D	0x69EF	# <CJK>
0x446E	0x69F1	# <CJK>
0x446F	0x69F3	# <CJK>
0x4470	0x69F5	# <CJK>
0x4471	0x69FE	# <CJK>
0x4472	0x6A00	# <CJK>
0x4473	0x6A01	# <CJK>
0x4474	0x6A03	# <CJK>
0x4475	0x6A0F	# <CJK>
0x4476	0x6A11	# <CJK>
0x4477	0x6A15	# <CJK>
0x4478	0x6A1A	# <CJK>
0x4479	0x6A1D	# <CJK>
0x447A	0x6A20	# <CJK>
0x447B	0x6A24	# <CJK>
0x447C	0x6A28	# <CJK>
0x447D	0x6A30	# <CJK>
0x447E	0x6A32	# <CJK>
0x4521	0x6A34	# <CJK>
0x4522	0x6A37	# <CJK>
0x4523	0x6A3B	# <CJK>
0x4524	0x6A3E	# <CJK>
0x4525	0x6A3F	# <CJK>
0x4526	0x6A45	# <CJK>
0x4527	0x6A46	# <CJK>
0x4528	0x6A49	# <CJK>
0x4529	0x6A4A	# <CJK>
0x452A	0x6A4E	# <CJK>
0x452B	0x6A50	# <CJK>
0x452C	0x6A51	# <CJK>
0x452D	0x6A52	# <CJK>
0x452E	0x6A55	# <CJK>
0x452F	0x6A56	# <CJK>
0x4530	0x6A5B	# <CJK>
0x4531	0x6A64	# <CJK>
0x4532	0x6A67	# <CJK>
0x4533	0x6A6A	# <CJK>
0x4534	0x6A71	# <CJK>
0x4535	0x6A73	# <CJK>
0x4536	0x6A7E	# <CJK>
0x4537	0x6A81	# <CJK>
0x4538	0x6A83	# <CJK>
0x4539	0x6A86	# <CJK>
0x453A	0x6A87	# <CJK>
0x453B	0x6A89	# <CJK>
0x453C	0x6A8B	# <CJK>
0x453D	0x6A91	# <CJK>
0x453E	0x6A9B	# <CJK>
0x453F	0x6A9D	# <CJK>
0x4540	0x6A9E	# <CJK>
0x4541	0x6A9F	# <CJK>
0x4542	0x6AA5	# <CJK>
0x4543	0x6AAB	# <CJK>
0x4544	0x6AAF	# <CJK>
0x4545	0x6AB0	# <CJK>
0x4546	0x6AB1	# <CJK>
0x4547	0x6AB4	# <CJK>
0x4548	0x6ABD	# <CJK>
0x4549	0x6ABE	# <CJK>
0x454A	0x6ABF	# <CJK>
0x454B	0x6AC6	# <CJK>
0x454C	0x6AC9	# <CJK>
0x454D	0x6AC8	# <CJK>
0x454E	0x6ACC	# <CJK>
0x454F	0x6AD0	# <CJK>
0x4550	0x6AD4	# <CJK>
0x4551	0x6AD5	# <CJK>
0x4552	0x6AD6	# <CJK>
0x4553	0x6ADC	# <CJK>
0x4554	0x6ADD	# <CJK>
0x4555	0x6AE4	# <CJK>
0x4556	0x6AE7	# <CJK>
0x4557	0x6AEC	# <CJK>
0x4558	0x6AF0	# <CJK>
0x4559	0x6AF1	# <CJK>
0x455A	0x6AF2	# <CJK>
0x455B	0x6AFC	# <CJK>
0x455C	0x6AFD	# <CJK>
0x455D	0x6B02	# <CJK>
0x455E	0x6B03	# <CJK>
0x455F	0x6B06	# <CJK>
0x4560	0x6B07	# <CJK>
0x4561	0x6B09	# <CJK>
0x4562	0x6B0F	# <CJK>
0x4563	0x6B10	# <CJK>
0x4564	0x6B11	# <CJK>
0x4565	0x6B17	# <CJK>
0x4566	0x6B1B	# <CJK>
0x4567	0x6B1E	# <CJK>
0x4568	0x6B24	# <CJK>
0x4569	0x6B28	# <CJK>
0x456A	0x6B2B	# <CJK>
0x456B	0x6B2C	# <CJK>
0x456C	0x6B2F	# <CJK>
0x456D	0x6B35	# <CJK>
0x456E	0x6B36	# <CJK>
0x456F	0x6B3B	# <CJK>
0x4570	0x6B3F	# <CJK>
0x4571	0x6B46	# <CJK>
0x4572	0x6B4A	# <CJK>
0x4573	0x6B4D	# <CJK>
0x4574	0x6B52	# <CJK>
0x4575	0x6B56	# <CJK>
0x4576	0x6B58	# <CJK>
0x4577	0x6B5D	# <CJK>
0x4578	0x6B60	# <CJK>
0x4579	0x6B67	# <CJK>
0x457A	0x6B6B	# <CJK>
0x457B	0x6B6E	# <CJK>
0x457C	0x6B70	# <CJK>
0x457D	0x6B75	# <CJK>
0x457E	0x6B7D	# <CJK>
0x4621	0x6B7E	# <CJK>
0x4622	0x6B82	# <CJK>
0x4623	0x6B85	# <CJK>
0x4624	0x6B97	# <CJK>
0x4625	0x6B9B	# <CJK>
0x4626	0x6B9F	# <CJK>
0x4627	0x6BA0	# <CJK>
0x4628	0x6BA2	# <CJK>
0x4629	0x6BA3	# <CJK>
0x462A	0x6BA8	# <CJK>
0x462B	0x6BA9	# <CJK>
0x462C	0x6BAC	# <CJK>
0x462D	0x6BAD	# <CJK>
0x462E	0x6BAE	# <CJK>
0x462F	0x6BB0	# <CJK>
0x4630	0x6BB8	# <CJK>
0x4631	0x6BB9	# <CJK>
0x4632	0x6BBD	# <CJK>
0x4633	0x6BBE	# <CJK>
0x4634	0x6BC3	# <CJK>
0x4635	0x6BC4	# <CJK>
0x4636	0x6BC9	# <CJK>
0x4637	0x6BCC	# <CJK>
0x4638	0x6BD6	# <CJK>
0x4639	0x6BDA	# <CJK>
0x463A	0x6BE1	# <CJK>
0x463B	0x6BE3	# <CJK>
0x463C	0x6BE6	# <CJK>
0x463D	0x6BE7	# <CJK>
0x463E	0x6BEE	# <CJK>
0x463F	0x6BF1	# <CJK>
0x4640	0x6BF7	# <CJK>
0x4641	0x6BF9	# <CJK>
0x4642	0x6BFF	# <CJK>
0x4643	0x6C02	# <CJK>
0x4644	0x6C04	# <CJK>
0x4645	0x6C05	# <CJK>
0x4646	0x6C09	# <CJK>
0x4647	0x6C0D	# <CJK>
0x4648	0x6C0E	# <CJK>
0x4649	0x6C10	# <CJK>
0x464A	0x6C12	# <CJK>
0x464B	0x6C19	# <CJK>
0x464C	0x6C1F	# <CJK>
0x464D	0x6C26	# <CJK>
0x464E	0x6C27	# <CJK>
0x464F	0x6C28	# <CJK>
0x4650	0x6C2C	# <CJK>
0x4651	0x6C2E	# <CJK>
0x4652	0x6C33	# <CJK>
0x4653	0x6C35	# <CJK>
0x4654	0x6C36	# <CJK>
0x4655	0x6C3A	# <CJK>
0x4656	0x6C3B	# <CJK>
0x4657	0x6C3F	# <CJK>
0x4658	0x6C4A	# <CJK>
0x4659	0x6C4B	# <CJK>
0x465A	0x6C4D	# <CJK>
0x465B	0x6C4F	# <CJK>
0x465C	0x6C52	# <CJK>
0x465D	0x6C54	# <CJK>
0x465E	0x6C59	# <CJK>
0x465F	0x6C5B	# <CJK>
0x4660	0x6C5C	# <CJK>
0x4661	0x6C6B	# <CJK>
0x4662	0x6C6D	# <CJK>
0x4663	0x6C6F	# <CJK>
0x4664	0x6C74	# <CJK>
0x4665	0x6C76	# <CJK>
0x4666	0x6C78	# <CJK>
0x4667	0x6C79	# <CJK>
0x4668	0x6C7B	# <CJK>
0x4669	0x6C85	# <CJK>
0x466A	0x6C86	# <CJK>
0x466B	0x6C87	# <CJK>
0x466C	0x6C89	# <CJK>
0x466D	0x6C94	# <CJK>
0x466E	0x6C95	# <CJK>
0x466F	0x6C97	# <CJK>
0x4670	0x6C98	# <CJK>
0x4671	0x6C9C	# <CJK>
0x4672	0x6C9F	# <CJK>
0x4673	0x6CB0	# <CJK>
0x4674	0x6CB2	# <CJK>
0x4675	0x6CB4	# <CJK>
0x4676	0x6CC2	# <CJK>
0x4677	0x6CC6	# <CJK>
0x4678	0x6CCD	# <CJK>
0x4679	0x6CCF	# <CJK>
0x467A	0x6CD0	# <CJK>
0x467B	0x6CD1	# <CJK>
0x467C	0x6CD2	# <CJK>
0x467D	0x6CD4	# <CJK>
0x467E	0x6CD6	# <CJK>
0x4721	0x6CDA	# <CJK>
0x4722	0x6CDC	# <CJK>
0x4723	0x6CE0	# <CJK>
0x4724	0x6CE7	# <CJK>
0x4725	0x6CE9	# <CJK>
0x4726	0x6CEB	# <CJK>
0x4727	0x6CEC	# <CJK>
0x4728	0x6CEE	# <CJK>
0x4729	0x6CF2	# <CJK>
0x472A	0x6CF4	# <CJK>
0x472B	0x6D04	# <CJK>
0x472C	0x6D07	# <CJK>
0x472D	0x6D0A	# <CJK>
0x472E	0x6D0E	# <CJK>
0x472F	0x6D0F	# <CJK>
0x4730	0x6D11	# <CJK>
0x4731	0x6D13	# <CJK>
0x4732	0x6D1A	# <CJK>
0x4733	0x6D26	# <CJK>
0x4734	0x6D27	# <CJK>
0x4735	0x6D28	# <CJK>
0x4736	0x6C67	# <CJK>
0x4737	0x6D2E	# <CJK>
0x4738	0x6D2F	# <CJK>
0x4739	0x6D31	# <CJK>
0x473A	0x6D39	# <CJK>
0x473B	0x6D3C	# <CJK>
0x473C	0x6D3F	# <CJK>
0x473D	0x6D57	# <CJK>
0x473E	0x6D5E	# <CJK>
0x473F	0x6D5F	# <CJK>
0x4740	0x6D61	# <CJK>
0x4741	0x6D65	# <CJK>
0x4742	0x6D67	# <CJK>
0x4743	0x6D6F	# <CJK>
0x4744	0x6D70	# <CJK>
0x4745	0x6D7C	# <CJK>
0x4746	0x6D82	# <CJK>
0x4747	0x6D87	# <CJK>
0x4748	0x6D91	# <CJK>
0x4749	0x6D92	# <CJK>
0x474A	0x6D94	# <CJK>
0x474B	0x6D96	# <CJK>
0x474C	0x6D97	# <CJK>
0x474D	0x6D98	# <CJK>
0x474E	0x6DAA	# <CJK>
0x474F	0x6DAC	# <CJK>
0x4750	0x6DB4	# <CJK>
0x4751	0x6DB7	# <CJK>
0x4752	0x6DB9	# <CJK>
0x4753	0x6DBD	# <CJK>
0x4754	0x6DBF	# <CJK>
0x4755	0x6DC4	# <CJK>
0x4756	0x6DC8	# <CJK>
0x4757	0x6DCA	# <CJK>
0x4758	0x6DCE	# <CJK>
0x4759	0x6DCF	# <CJK>
0x475A	0x6DD6	# <CJK>
0x475B	0x6DDB	# <CJK>
0x475C	0x6DDD	# <CJK>
0x475D	0x6DDF	# <CJK>
0x475E	0x6DE0	# <CJK>
0x475F	0x6DE2	# <CJK>
0x4760	0x6DE5	# <CJK>
0x4761	0x6DE9	# <CJK>
0x4762	0x6DEF	# <CJK>
0x4763	0x6DF0	# <CJK>
0x4764	0x6DF4	# <CJK>
0x4765	0x6DF6	# <CJK>
0x4766	0x6DFC	# <CJK>
0x4767	0x6E00	# <CJK>
0x4768	0x6E04	# <CJK>
0x4769	0x6E1E	# <CJK>
0x476A	0x6E22	# <CJK>
0x476B	0x6E27	# <CJK>
0x476C	0x6E32	# <CJK>
0x476D	0x6E36	# <CJK>
0x476E	0x6E39	# <CJK>
0x476F	0x6E3B	# <CJK>
0x4770	0x6E3C	# <CJK>
0x4771	0x6E44	# <CJK>
0x4772	0x6E45	# <CJK>
0x4773	0x6E48	# <CJK>
0x4774	0x6E49	# <CJK>
0x4775	0x6E4B	# <CJK>
0x4776	0x6E4F	# <CJK>
0x4777	0x6E51	# <CJK>
0x4778	0x6E52	# <CJK>
0x4779	0x6E53	# <CJK>
0x477A	0x6E54	# <CJK>
0x477B	0x6E57	# <CJK>
0x477C	0x6E5C	# <CJK>
0x477D	0x6E5D	# <CJK>
0x477E	0x6E5E	# <CJK>
0x4821	0x6E62	# <CJK>
0x4822	0x6E63	# <CJK>
0x4823	0x6E68	# <CJK>
0x4824	0x6E73	# <CJK>
0x4825	0x6E7B	# <CJK>
0x4826	0x6E7D	# <CJK>
0x4827	0x6E8D	# <CJK>
0x4828	0x6E93	# <CJK>
0x4829	0x6E99	# <CJK>
0x482A	0x6EA0	# <CJK>
0x482B	0x6EA7	# <CJK>
0x482C	0x6EAD	# <CJK>
0x482D	0x6EAE	# <CJK>
0x482E	0x6EB1	# <CJK>
0x482F	0x6EB3	# <CJK>
0x4830	0x6EBB	# <CJK>
0x4831	0x6EBF	# <CJK>
0x4832	0x6EC0	# <CJK>
0x4833	0x6EC1	# <CJK>
0x4834	0x6EC3	# <CJK>
0x4835	0x6EC7	# <CJK>
0x4836	0x6EC8	# <CJK>
0x4837	0x6ECA	# <CJK>
0x4838	0x6ECD	# <CJK>
0x4839	0x6ECE	# <CJK>
0x483A	0x6ECF	# <CJK>
0x483B	0x6EEB	# <CJK>
0x483C	0x6EED	# <CJK>
0x483D	0x6EEE	# <CJK>
0x483E	0x6EF9	# <CJK>
0x483F	0x6EFB	# <CJK>
0x4840	0x6EFD	# <CJK>
0x4841	0x6F04	# <CJK>
0x4842	0x6F08	# <CJK>
0x4843	0x6F0A	# <CJK>
0x4844	0x6F0C	# <CJK>
0x4845	0x6F0D	# <CJK>
0x4846	0x6F16	# <CJK>
0x4847	0x6F18	# <CJK>
0x4848	0x6F1A	# <CJK>
0x4849	0x6F1B	# <CJK>
0x484A	0x6F26	# <CJK>
0x484B	0x6F29	# <CJK>
0x484C	0x6F2A	# <CJK>
0x484D	0x6F2F	# <CJK>
0x484E	0x6F30	# <CJK>
0x484F	0x6F33	# <CJK>
0x4850	0x6F36	# <CJK>
0x4851	0x6F3B	# <CJK>
0x4852	0x6F3C	# <CJK>
0x4853	0x6F2D	# <CJK>
0x4854	0x6F4F	# <CJK>
0x4855	0x6F51	# <CJK>
0x4856	0x6F52	# <CJK>
0x4857	0x6F53	# <CJK>
0x4858	0x6F57	# <CJK>
0x4859	0x6F59	# <CJK>
0x485A	0x6F5A	# <CJK>
0x485B	0x6F5D	# <CJK>
0x485C	0x6F5E	# <CJK>
0x485D	0x6F61	# <CJK>
0x485E	0x6F62	# <CJK>
0x485F	0x6F68	# <CJK>
0x4860	0x6F6C	# <CJK>
0x4861	0x6F7D	# <CJK>
0x4862	0x6F7E	# <CJK>
0x4863	0x6F83	# <CJK>
0x4864	0x6F87	# <CJK>
0x4865	0x6F88	# <CJK>
0x4866	0x6F8B	# <CJK>
0x4867	0x6F8C	# <CJK>
0x4868	0x6F8D	# <CJK>
0x4869	0x6F90	# <CJK>
0x486A	0x6F92	# <CJK>
0x486B	0x6F93	# <CJK>
0x486C	0x6F94	# <CJK>
0x486D	0x6F96	# <CJK>
0x486E	0x6F9A	# <CJK>
0x486F	0x6F9F	# <CJK>
0x4870	0x6FA0	# <CJK>
0x4871	0x6FA5	# <CJK>
0x4872	0x6FA6	# <CJK>
0x4873	0x6FA7	# <CJK>
0x4874	0x6FA8	# <CJK>
0x4875	0x6FAE	# <CJK>
0x4876	0x6FAF	# <CJK>
0x4877	0x6FB0	# <CJK>
0x4878	0x6FB5	# <CJK>
0x4879	0x6FB6	# <CJK>
0x487A	0x6FBC	# <CJK>
0x487B	0x6FC5	# <CJK>
0x487C	0x6FC7	# <CJK>
0x487D	0x6FC8	# <CJK>
0x487E	0x6FCA	# <CJK>
0x4921	0x6FDA	# <CJK>
0x4922	0x6FDE	# <CJK>
0x4923	0x6FE8	# <CJK>
0x4924	0x6FE9	# <CJK>
0x4925	0x6FF0	# <CJK>
0x4926	0x6FF5	# <CJK>
0x4927	0x6FF9	# <CJK>
0x4928	0x6FFC	# <CJK>
0x4929	0x6FFD	# <CJK>
0x492A	0x7000	# <CJK>
0x492B	0x7005	# <CJK>
0x492C	0x7006	# <CJK>
0x492D	0x7007	# <CJK>
0x492E	0x700D	# <CJK>
0x492F	0x7017	# <CJK>
0x4930	0x7020	# <CJK>
0x4931	0x7023	# <CJK>
0x4932	0x702F	# <CJK>
0x4933	0x7034	# <CJK>
0x4934	0x7037	# <CJK>
0x4935	0x7039	# <CJK>
0x4936	0x703C	# <CJK>
0x4937	0x7043	# <CJK>
0x4938	0x7044	# <CJK>
0x4939	0x7048	# <CJK>
0x493A	0x7049	# <CJK>
0x493B	0x704A	# <CJK>
0x493C	0x704B	# <CJK>
0x493D	0x7054	# <CJK>
0x493E	0x7055	# <CJK>
0x493F	0x705D	# <CJK>
0x4940	0x705E	# <CJK>
0x4941	0x704E	# <CJK>
0x4942	0x7064	# <CJK>
0x4943	0x7065	# <CJK>
0x4944	0x706C	# <CJK>
0x4945	0x706E	# <CJK>
0x4946	0x7075	# <CJK>
0x4947	0x7076	# <CJK>
0x4948	0x707E	# <CJK>
0x4949	0x7081	# <CJK>
0x494A	0x7085	# <CJK>
0x494B	0x7086	# <CJK>
0x494C	0x7094	# <CJK>
0x494D	0x7095	# <CJK>
0x494E	0x7096	# <CJK>
0x494F	0x7097	# <CJK>
0x4950	0x7098	# <CJK>
0x4951	0x709B	# <CJK>
0x4952	0x70A4	# <CJK>
0x4953	0x70AB	# <CJK>
0x4954	0x70B0	# <CJK>
0x4955	0x70B1	# <CJK>
0x4956	0x70B4	# <CJK>
0x4957	0x70B7	# <CJK>
0x4958	0x70CA	# <CJK>
0x4959	0x70D1	# <CJK>
0x495A	0x70D3	# <CJK>
0x495B	0x70D4	# <CJK>
0x495C	0x70D5	# <CJK>
0x495D	0x70D6	# <CJK>
0x495E	0x70D8	# <CJK>
0x495F	0x70DC	# <CJK>
0x4960	0x70E4	# <CJK>
0x4961	0x70FA	# <CJK>
0x4962	0x7103	# <CJK>
0x4963	0x7104	# <CJK>
0x4964	0x7105	# <CJK>
0x4965	0x7106	# <CJK>
0x4966	0x7107	# <CJK>
0x4967	0x710B	# <CJK>
0x4968	0x710C	# <CJK>
0x4969	0x710F	# <CJK>
0x496A	0x711E	# <CJK>
0x496B	0x7120	# <CJK>
0x496C	0x712B	# <CJK>
0x496D	0x712D	# <CJK>
0x496E	0x712F	# <CJK>
0x496F	0x7130	# <CJK>
0x4970	0x7131	# <CJK>
0x4971	0x7138	# <CJK>
0x4972	0x7141	# <CJK>
0x4973	0x7145	# <CJK>
0x4974	0x7146	# <CJK>
0x4975	0x7147	# <CJK>
0x4976	0x714A	# <CJK>
0x4977	0x714B	# <CJK>
0x4978	0x7150	# <CJK>
0x4979	0x7152	# <CJK>
0x497A	0x7157	# <CJK>
0x497B	0x715A	# <CJK>
0x497C	0x715C	# <CJK>
0x497D	0x715E	# <CJK>
0x497E	0x7160	# <CJK>
0x4A21	0x7168	# <CJK>
0x4A22	0x7179	# <CJK>
0x4A23	0x7180	# <CJK>
0x4A24	0x7185	# <CJK>
0x4A25	0x7187	# <CJK>
0x4A26	0x718C	# <CJK>
0x4A27	0x7192	# <CJK>
0x4A28	0x719A	# <CJK>
0x4A29	0x719B	# <CJK>
0x4A2A	0x71A0	# <CJK>
0x4A2B	0x71A2	# <CJK>
0x4A2C	0x71AF	# <CJK>
0x4A2D	0x71B0	# <CJK>
0x4A2E	0x71B2	# <CJK>
0x4A2F	0x71B3	# <CJK>
0x4A30	0x71BA	# <CJK>
0x4A31	0x71BF	# <CJK>
0x4A32	0x71C0	# <CJK>
0x4A33	0x71C1	# <CJK>
0x4A34	0x71C4	# <CJK>
0x4A35	0x71CB	# <CJK>
0x4A36	0x71CC	# <CJK>
0x4A37	0x71D3	# <CJK>
0x4A38	0x71D6	# <CJK>
0x4A39	0x71D9	# <CJK>
0x4A3A	0x71DA	# <CJK>
0x4A3B	0x71DC	# <CJK>
0x4A3C	0x71F8	# <CJK>
0x4A3D	0x71FE	# <CJK>
0x4A3E	0x7200	# <CJK>
0x4A3F	0x7207	# <CJK>
0x4A40	0x7208	# <CJK>
0x4A41	0x7209	# <CJK>
0x4A42	0x7213	# <CJK>
0x4A43	0x7217	# <CJK>
0x4A44	0x721A	# <CJK>
0x4A45	0x721D	# <CJK>
0x4A46	0x721F	# <CJK>
0x4A47	0x7224	# <CJK>
0x4A48	0x722B	# <CJK>
0x4A49	0x722F	# <CJK>
0x4A4A	0x7234	# <CJK>
0x4A4B	0x7238	# <CJK>
0x4A4C	0x7239	# <CJK>
0x4A4D	0x7241	# <CJK>
0x4A4E	0x7242	# <CJK>
0x4A4F	0x7243	# <CJK>
0x4A50	0x7245	# <CJK>
0x4A51	0x724E	# <CJK>
0x4A52	0x724F	# <CJK>
0x4A53	0x7250	# <CJK>
0x4A54	0x7253	# <CJK>
0x4A55	0x7255	# <CJK>
0x4A56	0x7256	# <CJK>
0x4A57	0x725A	# <CJK>
0x4A58	0x725C	# <CJK>
0x4A59	0x725E	# <CJK>
0x4A5A	0x7260	# <CJK>
0x4A5B	0x7263	# <CJK>
0x4A5C	0x7268	# <CJK>
0x4A5D	0x726B	# <CJK>
0x4A5E	0x726E	# <CJK>
0x4A5F	0x726F	# <CJK>
0x4A60	0x7271	# <CJK>
0x4A61	0x7277	# <CJK>
0x4A62	0x7278	# <CJK>
0x4A63	0x727B	# <CJK>
0x4A64	0x727C	# <CJK>
0x4A65	0x727F	# <CJK>
0x4A66	0x7284	# <CJK>
0x4A67	0x7289	# <CJK>
0x4A68	0x728D	# <CJK>
0x4A69	0x728E	# <CJK>
0x4A6A	0x7293	# <CJK>
0x4A6B	0x729B	# <CJK>
0x4A6C	0x72A8	# <CJK>
0x4A6D	0x72AD	# <CJK>
0x4A6E	0x72AE	# <CJK>
0x4A6F	0x72B1	# <CJK>
0x4A70	0x72B4	# <CJK>
0x4A71	0x72BE	# <CJK>
0x4A72	0x72C1	# <CJK>
0x4A73	0x72C7	# <CJK>
0x4A74	0x72C9	# <CJK>
0x4A75	0x72CC	# <CJK>
0x4A76	0x72D5	# <CJK>
0x4A77	0x72D6	# <CJK>
0x4A78	0x72D8	# <CJK>
0x4A79	0x72DF	# <CJK>
0x4A7A	0x72E5	# <CJK>
0x4A7B	0x72F3	# <CJK>
0x4A7C	0x72F4	# <CJK>
0x4A7D	0x72FA	# <CJK>
0x4A7E	0x72FB	# <CJK>
0x4B21	0x72FE	# <CJK>
0x4B22	0x7302	# <CJK>
0x4B23	0x7304	# <CJK>
0x4B24	0x7305	# <CJK>
0x4B25	0x7307	# <CJK>
0x4B26	0x730B	# <CJK>
0x4B27	0x730D	# <CJK>
0x4B28	0x7312	# <CJK>
0x4B29	0x7313	# <CJK>
0x4B2A	0x7318	# <CJK>
0x4B2B	0x7319	# <CJK>
0x4B2C	0x731E	# <CJK>
0x4B2D	0x7322	# <CJK>
0x4B2E	0x7324	# <CJK>
0x4B2F	0x7327	# <CJK>
0x4B30	0x7328	# <CJK>
0x4B31	0x732C	# <CJK>
0x4B32	0x7331	# <CJK>
0x4B33	0x7332	# <CJK>
0x4B34	0x7335	# <CJK>
0x4B35	0x733A	# <CJK>
0x4B36	0x733B	# <CJK>
0x4B37	0x733D	# <CJK>
0x4B38	0x7343	# <CJK>
0x4B39	0x734D	# <CJK>
0x4B3A	0x7350	# <CJK>
0x4B3B	0x7352	# <CJK>
0x4B3C	0x7356	# <CJK>
0x4B3D	0x7358	# <CJK>
0x4B3E	0x735D	# <CJK>
0x4B3F	0x735E	# <CJK>
0x4B40	0x735F	# <CJK>
0x4B41	0x7360	# <CJK>
0x4B42	0x7366	# <CJK>
0x4B43	0x7367	# <CJK>
0x4B44	0x7369	# <CJK>
0x4B45	0x736B	# <CJK>
0x4B46	0x736C	# <CJK>
0x4B47	0x736E	# <CJK>
0x4B48	0x736F	# <CJK>
0x4B49	0x7371	# <CJK>
0x4B4A	0x7377	# <CJK>
0x4B4B	0x7379	# <CJK>
0x4B4C	0x737C	# <CJK>
0x4B4D	0x7380	# <CJK>
0x4B4E	0x7381	# <CJK>
0x4B4F	0x7383	# <CJK>
0x4B50	0x7385	# <CJK>
0x4B51	0x7386	# <CJK>
0x4B52	0x738E	# <CJK>
0x4B53	0x7390	# <CJK>
0x4B54	0x7393	# <CJK>
0x4B55	0x7395	# <CJK>
0x4B56	0x7397	# <CJK>
0x4B57	0x7398	# <CJK>
0x4B58	0x739C	# <CJK>
0x4B59	0x739E	# <CJK>
0x4B5A	0x739F	# <CJK>
0x4B5B	0x73A0	# <CJK>
0x4B5C	0x73A2	# <CJK>
0x4B5D	0x73A5	# <CJK>
0x4B5E	0x73A6	# <CJK>
0x4B5F	0x73AA	# <CJK>
0x4B60	0x73AB	# <CJK>
0x4B61	0x73AD	# <CJK>
0x4B62	0x73B5	# <CJK>
0x4B63	0x73B7	# <CJK>
0x4B64	0x73B9	# <CJK>
0x4B65	0x73BC	# <CJK>
0x4B66	0x73BD	# <CJK>
0x4B67	0x73BF	# <CJK>
0x4B68	0x73C5	# <CJK>
0x4B69	0x73C6	# <CJK>
0x4B6A	0x73C9	# <CJK>
0x4B6B	0x73CB	# <CJK>
0x4B6C	0x73CC	# <CJK>
0x4B6D	0x73CF	# <CJK>
0x4B6E	0x73D2	# <CJK>
0x4B6F	0x73D3	# <CJK>
0x4B70	0x73D6	# <CJK>
0x4B71	0x73D9	# <CJK>
0x4B72	0x73DD	# <CJK>
0x4B73	0x73E1	# <CJK>
0x4B74	0x73E3	# <CJK>
0x4B75	0x73E6	# <CJK>
0x4B76	0x73E7	# <CJK>
0x4B77	0x73E9	# <CJK>
0x4B78	0x73F4	# <CJK>
0x4B79	0x73F5	# <CJK>
0x4B7A	0x73F7	# <CJK>
0x4B7B	0x73F9	# <CJK>
0x4B7C	0x73FA	# <CJK>
0x4B7D	0x73FB	# <CJK>
0x4B7E	0x73FD	# <CJK>
0x4C21	0x73FF	# <CJK>
0x4C22	0x7400	# <CJK>
0x4C23	0x7401	# <CJK>
0x4C24	0x7404	# <CJK>
0x4C25	0x7407	# <CJK>
0x4C26	0x740A	# <CJK>
0x4C27	0x7411	# <CJK>
0x4C28	0x741A	# <CJK>
0x4C29	0x741B	# <CJK>
0x4C2A	0x7424	# <CJK>
0x4C2B	0x7426	# <CJK>
0x4C2C	0x7428	# <CJK>
0x4C2D	0x7429	# <CJK>
0x4C2E	0x742A	# <CJK>
0x4C2F	0x742B	# <CJK>
0x4C30	0x742C	# <CJK>
0x4C31	0x742D	# <CJK>
0x4C32	0x742E	# <CJK>
0x4C33	0x742F	# <CJK>
0x4C34	0x7430	# <CJK>
0x4C35	0x7431	# <CJK>
0x4C36	0x7439	# <CJK>
0x4C37	0x7440	# <CJK>
0x4C38	0x7443	# <CJK>
0x4C39	0x7444	# <CJK>
0x4C3A	0x7446	# <CJK>
0x4C3B	0x7447	# <CJK>
0x4C3C	0x744B	# <CJK>
0x4C3D	0x744D	# <CJK>
0x4C3E	0x7451	# <CJK>
0x4C3F	0x7452	# <CJK>
0x4C40	0x7457	# <CJK>
0x4C41	0x745D	# <CJK>
0x4C42	0x7462	# <CJK>
0x4C43	0x7466	# <CJK>
0x4C44	0x7467	# <CJK>
0x4C45	0x7468	# <CJK>
0x4C46	0x746B	# <CJK>
0x4C47	0x746D	# <CJK>
0x4C48	0x746E	# <CJK>
0x4C49	0x7471	# <CJK>
0x4C4A	0x7472	# <CJK>
0x4C4B	0x7480	# <CJK>
0x4C4C	0x7481	# <CJK>
0x4C4D	0x7485	# <CJK>
0x4C4E	0x7486	# <CJK>
0x4C4F	0x7487	# <CJK>
0x4C50	0x7489	# <CJK>
0x4C51	0x748F	# <CJK>
0x4C52	0x7490	# <CJK>
0x4C53	0x7491	# <CJK>
0x4C54	0x7492	# <CJK>
0x4C55	0x7498	# <CJK>
0x4C56	0x7499	# <CJK>
0x4C57	0x749A	# <CJK>
0x4C58	0x749C	# <CJK>
0x4C59	0x749F	# <CJK>
0x4C5A	0x74A0	# <CJK>
0x4C5B	0x74A1	# <CJK>
0x4C5C	0x74A3	# <CJK>
0x4C5D	0x74A6	# <CJK>
0x4C5E	0x74A8	# <CJK>
0x4C5F	0x74A9	# <CJK>
0x4C60	0x74AA	# <CJK>
0x4C61	0x74AB	# <CJK>
0x4C62	0x74AE	# <CJK>
0x4C63	0x74AF	# <CJK>
0x4C64	0x74B1	# <CJK>
0x4C65	0x74B2	# <CJK>
0x4C66	0x74B5	# <CJK>
0x4C67	0x74B9	# <CJK>
0x4C68	0x74BB	# <CJK>
0x4C69	0x74BF	# <CJK>
0x4C6A	0x74C8	# <CJK>
0x4C6B	0x74C9	# <CJK>
0x4C6C	0x74CC	# <CJK>
0x4C6D	0x74D0	# <CJK>
0x4C6E	0x74D3	# <CJK>
0x4C6F	0x74D8	# <CJK>
0x4C70	0x74DA	# <CJK>
0x4C71	0x74DB	# <CJK>
0x4C72	0x74DE	# <CJK>
0x4C73	0x74DF	# <CJK>
0x4C74	0x74E4	# <CJK>
0x4C75	0x74E8	# <CJK>
0x4C76	0x74EA	# <CJK>
0x4C77	0x74EB	# <CJK>
0x4C78	0x74EF	# <CJK>
0x4C79	0x74F4	# <CJK>
0x4C7A	0x74FA	# <CJK>
0x4C7B	0x74FB	# <CJK>
0x4C7C	0x74FC	# <CJK>
0x4C7D	0x74FF	# <CJK>
0x4C7E	0x7506	# <CJK>
0x4D21	0x7512	# <CJK>
0x4D22	0x7516	# <CJK>
0x4D23	0x7517	# <CJK>
0x4D24	0x7520	# <CJK>
0x4D25	0x7521	# <CJK>
0x4D26	0x7524	# <CJK>
0x4D27	0x7527	# <CJK>
0x4D28	0x7529	# <CJK>
0x4D29	0x752A	# <CJK>
0x4D2A	0x752F	# <CJK>
0x4D2B	0x7536	# <CJK>
0x4D2C	0x7539	# <CJK>
0x4D2D	0x753D	# <CJK>
0x4D2E	0x753E	# <CJK>
0x4D2F	0x753F	# <CJK>
0x4D30	0x7540	# <CJK>
0x4D31	0x7543	# <CJK>
0x4D32	0x7547	# <CJK>
0x4D33	0x7548	# <CJK>
0x4D34	0x754E	# <CJK>
0x4D35	0x7550	# <CJK>
0x4D36	0x7552	# <CJK>
0x4D37	0x7557	# <CJK>
0x4D38	0x755E	# <CJK>
0x4D39	0x755F	# <CJK>
0x4D3A	0x7561	# <CJK>
0x4D3B	0x756F	# <CJK>
0x4D3C	0x7571	# <CJK>
0x4D3D	0x7579	# <CJK>
0x4D3E	0x757A	# <CJK>
0x4D3F	0x757B	# <CJK>
0x4D40	0x757C	# <CJK>
0x4D41	0x757D	# <CJK>
0x4D42	0x757E	# <CJK>
0x4D43	0x7581	# <CJK>
0x4D44	0x7585	# <CJK>
0x4D45	0x7590	# <CJK>
0x4D46	0x7592	# <CJK>
0x4D47	0x7593	# <CJK>
0x4D48	0x7595	# <CJK>
0x4D49	0x7599	# <CJK>
0x4D4A	0x759C	# <CJK>
0x4D4B	0x75A2	# <CJK>
0x4D4C	0x75A4	# <CJK>
0x4D4D	0x75B4	# <CJK>
0x4D4E	0x75BA	# <CJK>
0x4D4F	0x75BF	# <CJK>
0x4D50	0x75C0	# <CJK>
0x4D51	0x75C1	# <CJK>
0x4D52	0x75C4	# <CJK>
0x4D53	0x75C6	# <CJK>
0x4D54	0x75CC	# <CJK>
0x4D55	0x75CE	# <CJK>
0x4D56	0x75CF	# <CJK>
0x4D57	0x75D7	# <CJK>
0x4D58	0x75DC	# <CJK>
0x4D59	0x75DF	# <CJK>
0x4D5A	0x75E0	# <CJK>
0x4D5B	0x75E1	# <CJK>
0x4D5C	0x75E4	# <CJK>
0x4D5D	0x75E7	# <CJK>
0x4D5E	0x75EC	# <CJK>
0x4D5F	0x75EE	# <CJK>
0x4D60	0x75EF	# <CJK>
0x4D61	0x75F1	# <CJK>
0x4D62	0x75F9	# <CJK>
0x4D63	0x7600	# <CJK>
0x4D64	0x7602	# <CJK>
0x4D65	0x7603	# <CJK>
0x4D66	0x7604	# <CJK>
0x4D67	0x7607	# <CJK>
0x4D68	0x7608	# <CJK>
0x4D69	0x760A	# <CJK>
0x4D6A	0x760C	# <CJK>
0x4D6B	0x760F	# <CJK>
0x4D6C	0x7612	# <CJK>
0x4D6D	0x7613	# <CJK>
0x4D6E	0x7615	# <CJK>
0x4D6F	0x7616	# <CJK>
0x4D70	0x7619	# <CJK>
0x4D71	0x761B	# <CJK>
0x4D72	0x761C	# <CJK>
0x4D73	0x761D	# <CJK>
0x4D74	0x761E	# <CJK>
0x4D75	0x7623	# <CJK>
0x4D76	0x7625	# <CJK>
0x4D77	0x7626	# <CJK>
0x4D78	0x7629	# <CJK>
0x4D79	0x762D	# <CJK>
0x4D7A	0x7632	# <CJK>
0x4D7B	0x7633	# <CJK>
0x4D7C	0x7635	# <CJK>
0x4D7D	0x7638	# <CJK>
0x4D7E	0x7639	# <CJK>
0x4E21	0x763A	# <CJK>
0x4E22	0x763C	# <CJK>
0x4E23	0x764A	# <CJK>
0x4E24	0x7640	# <CJK>
0x4E25	0x7641	# <CJK>
0x4E26	0x7643	# <CJK>
0x4E27	0x7644	# <CJK>
0x4E28	0x7645	# <CJK>
0x4E29	0x7649	# <CJK>
0x4E2A	0x764B	# <CJK>
0x4E2B	0x7655	# <CJK>
0x4E2C	0x7659	# <CJK>
0x4E2D	0x765F	# <CJK>
0x4E2E	0x7664	# <CJK>
0x4E2F	0x7665	# <CJK>
0x4E30	0x766D	# <CJK>
0x4E31	0x766E	# <CJK>
0x4E32	0x766F	# <CJK>
0x4E33	0x7671	# <CJK>
0x4E34	0x7674	# <CJK>
0x4E35	0x7681	# <CJK>
0x4E36	0x7685	# <CJK>
0x4E37	0x768C	# <CJK>
0x4E38	0x768D	# <CJK>
0x4E39	0x7695	# <CJK>
0x4E3A	0x769B	# <CJK>
0x4E3B	0x769C	# <CJK>
0x4E3C	0x769D	# <CJK>
0x4E3D	0x769F	# <CJK>
0x4E3E	0x76A0	# <CJK>
0x4E3F	0x76A2	# <CJK>
0x4E40	0x76A3	# <CJK>
0x4E41	0x76A4	# <CJK>
0x4E42	0x76A5	# <CJK>
0x4E43	0x76A6	# <CJK>
0x4E44	0x76A7	# <CJK>
0x4E45	0x76A8	# <CJK>
0x4E46	0x76AA	# <CJK>
0x4E47	0x76AD	# <CJK>
0x4E48	0x76BD	# <CJK>
0x4E49	0x76C1	# <CJK>
0x4E4A	0x76C5	# <CJK>
0x4E4B	0x76C9	# <CJK>
0x4E4C	0x76CB	# <CJK>
0x4E4D	0x76CC	# <CJK>
0x4E4E	0x76CE	# <CJK>
0x4E4F	0x76D4	# <CJK>
0x4E50	0x76D9	# <CJK>
0x4E51	0x76E0	# <CJK>
0x4E52	0x76E6	# <CJK>
0x4E53	0x76E8	# <CJK>
0x4E54	0x76EC	# <CJK>
0x4E55	0x76F0	# <CJK>
0x4E56	0x76F1	# <CJK>
0x4E57	0x76F6	# <CJK>
0x4E58	0x76F9	# <CJK>
0x4E59	0x76FC	# <CJK>
0x4E5A	0x7700	# <CJK>
0x4E5B	0x7706	# <CJK>
0x4E5C	0x770A	# <CJK>
0x4E5D	0x770E	# <CJK>
0x4E5E	0x7712	# <CJK>
0x4E5F	0x7714	# <CJK>
0x4E60	0x7715	# <CJK>
0x4E61	0x7717	# <CJK>
0x4E62	0x7719	# <CJK>
0x4E63	0x771A	# <CJK>
0x4E64	0x771C	# <CJK>
0x4E65	0x7722	# <CJK>
0x4E66	0x7728	# <CJK>
0x4E67	0x772D	# <CJK>
0x4E68	0x772E	# <CJK>
0x4E69	0x772F	# <CJK>
0x4E6A	0x7734	# <CJK>
0x4E6B	0x7735	# <CJK>
0x4E6C	0x7736	# <CJK>
0x4E6D	0x7739	# <CJK>
0x4E6E	0x773D	# <CJK>
0x4E6F	0x773E	# <CJK>
0x4E70	0x7742	# <CJK>
0x4E71	0x7745	# <CJK>
0x4E72	0x7746	# <CJK>
0x4E73	0x774A	# <CJK>
0x4E74	0x774D	# <CJK>
0x4E75	0x774E	# <CJK>
0x4E76	0x774F	# <CJK>
0x4E77	0x7752	# <CJK>
0x4E78	0x7756	# <CJK>
0x4E79	0x7757	# <CJK>
0x4E7A	0x775C	# <CJK>
0x4E7B	0x775E	# <CJK>
0x4E7C	0x775F	# <CJK>
0x4E7D	0x7760	# <CJK>
0x4E7E	0x7762	# <CJK>
0x4F21	0x7764	# <CJK>
0x4F22	0x7767	# <CJK>
0x4F23	0x776A	# <CJK>
0x4F24	0x776C	# <CJK>
0x4F25	0x7770	# <CJK>
0x4F26	0x7772	# <CJK>
0x4F27	0x7773	# <CJK>
0x4F28	0x7774	# <CJK>
0x4F29	0x777A	# <CJK>
0x4F2A	0x777D	# <CJK>
0x4F2B	0x7780	# <CJK>
0x4F2C	0x7784	# <CJK>
0x4F2D	0x778C	# <CJK>
0x4F2E	0x778D	# <CJK>
0x4F2F	0x7794	# <CJK>
0x4F30	0x7795	# <CJK>
0x4F31	0x7796	# <CJK>
0x4F32	0x779A	# <CJK>
0x4F33	0x779F	# <CJK>
0x4F34	0x77A2	# <CJK>
0x4F35	0x77A7	# <CJK>
0x4F36	0x77AA	# <CJK>
0x4F37	0x77AE	# <CJK>
0x4F38	0x77AF	# <CJK>
0x4F39	0x77B1	# <CJK>
0x4F3A	0x77B5	# <CJK>
0x4F3B	0x77BE	# <CJK>
0x4F3C	0x77C3	# <CJK>
0x4F3D	0x77C9	# <CJK>
0x4F3E	0x77D1	# <CJK>
0x4F3F	0x77D2	# <CJK>
0x4F40	0x77D5	# <CJK>
0x4F41	0x77D9	# <CJK>
0x4F42	0x77DE	# <CJK>
0x4F43	0x77DF	# <CJK>
0x4F44	0x77E0	# <CJK>
0x4F45	0x77E4	# <CJK>
0x4F46	0x77E6	# <CJK>
0x4F47	0x77EA	# <CJK>
0x4F48	0x77EC	# <CJK>
0x4F49	0x77F0	# <CJK>
0x4F4A	0x77F1	# <CJK>
0x4F4B	0x77F4	# <CJK>
0x4F4C	0x77F8	# <CJK>
0x4F4D	0x77FB	# <CJK>
0x4F4E	0x7805	# <CJK>
0x4F4F	0x7806	# <CJK>
0x4F50	0x7809	# <CJK>
0x4F51	0x780D	# <CJK>
0x4F52	0x780E	# <CJK>
0x4F53	0x7811	# <CJK>
0x4F54	0x781D	# <CJK>
0x4F55	0x7821	# <CJK>
0x4F56	0x7822	# <CJK>
0x4F57	0x7823	# <CJK>
0x4F58	0x782D	# <CJK>
0x4F59	0x782E	# <CJK>
0x4F5A	0x7830	# <CJK>
0x4F5B	0x7835	# <CJK>
0x4F5C	0x7837	# <CJK>
0x4F5D	0x7843	# <CJK>
0x4F5E	0x7844	# <CJK>
0x4F5F	0x7847	# <CJK>
0x4F60	0x7848	# <CJK>
0x4F61	0x784C	# <CJK>
0x4F62	0x784E	# <CJK>
0x4F63	0x7852	# <CJK>
0x4F64	0x785C	# <CJK>
0x4F65	0x785E	# <CJK>
0x4F66	0x7860	# <CJK>
0x4F67	0x7861	# <CJK>
0x4F68	0x7863	# <CJK>
0x4F69	0x7864	# <CJK>
0x4F6A	0x7868	# <CJK>
0x4F6B	0x786A	# <CJK>
0x4F6C	0x786E	# <CJK>
0x4F6D	0x787A	# <CJK>
0x4F6E	0x787E	# <CJK>
0x4F6F	0x788A	# <CJK>
0x4F70	0x788F	# <CJK>
0x4F71	0x7894	# <CJK>
0x4F72	0x7898	# <CJK>
0x4F73	0x78A1	# <CJK>
0x4F74	0x789D	# <CJK>
0x4F75	0x789E	# <CJK>
0x4F76	0x789F	# <CJK>
0x4F77	0x78A4	# <CJK>
0x4F78	0x78A8	# <CJK>
0x4F79	0x78AC	# <CJK>
0x4F7A	0x78AD	# <CJK>
0x4F7B	0x78B0	# <CJK>
0x4F7C	0x78B1	# <CJK>
0x4F7D	0x78B2	# <CJK>
0x4F7E	0x78B3	# <CJK>
0x5021	0x78BB	# <CJK>
0x5022	0x78BD	# <CJK>
0x5023	0x78BF	# <CJK>
0x5024	0x78C7	# <CJK>
0x5025	0x78C8	# <CJK>
0x5026	0x78C9	# <CJK>
0x5027	0x78CC	# <CJK>
0x5028	0x78CE	# <CJK>
0x5029	0x78D2	# <CJK>
0x502A	0x78D3	# <CJK>
0x502B	0x78D5	# <CJK>
0x502C	0x78D6	# <CJK>
0x502D	0x78E4	# <CJK>
0x502E	0x78DB	# <CJK>
0x502F	0x78DF	# <CJK>
0x5030	0x78E0	# <CJK>
0x5031	0x78E1	# <CJK>
0x5032	0x78E6	# <CJK>
0x5033	0x78EA	# <CJK>
0x5034	0x78F2	# <CJK>
0x5035	0x78F3	# <CJK>
0x5036	0x7900	# <CJK>
0x5037	0x78F6	# <CJK>
0x5038	0x78F7	# <CJK>
0x5039	0x78FA	# <CJK>
0x503A	0x78FB	# <CJK>
0x503B	0x78FF	# <CJK>
0x503C	0x7906	# <CJK>
0x503D	0x790C	# <CJK>
0x503E	0x7910	# <CJK>
0x503F	0x791A	# <CJK>
0x5040	0x791C	# <CJK>
0x5041	0x791E	# <CJK>
0x5042	0x791F	# <CJK>
0x5043	0x7920	# <CJK>
0x5044	0x7925	# <CJK>
0x5045	0x7927	# <CJK>
0x5046	0x7929	# <CJK>
0x5047	0x792D	# <CJK>
0x5048	0x7931	# <CJK>
0x5049	0x7934	# <CJK>
0x504A	0x7935	# <CJK>
0x504B	0x793B	# <CJK>
0x504C	0x793D	# <CJK>
0x504D	0x793F	# <CJK>
0x504E	0x7944	# <CJK>
0x504F	0x7945	# <CJK>
0x5050	0x7946	# <CJK>
0x5051	0x794A	# <CJK>
0x5052	0x794B	# <CJK>
0x5053	0x794F	# <CJK>
0x5054	0x7951	# <CJK>
0x5055	0x7954	# <CJK>
0x5056	0x7958	# <CJK>
0x5057	0x795B	# <CJK>
0x5058	0x795C	# <CJK>
0x5059	0x7967	# <CJK>
0x505A	0x7969	# <CJK>
0x505B	0x796B	# <CJK>
0x505C	0x7972	# <CJK>
0x505D	0x7979	# <CJK>
0x505E	0x797B	# <CJK>
0x505F	0x797C	# <CJK>
0x5060	0x797E	# <CJK>
0x5061	0x798B	# <CJK>
0x5062	0x798C	# <CJK>
0x5063	0x7991	# <CJK>
0x5064	0x7993	# <CJK>
0x5065	0x7994	# <CJK>
0x5066	0x7995	# <CJK>
0x5067	0x7996	# <CJK>
0x5068	0x7998	# <CJK>
0x5069	0x799B	# <CJK>
0x506A	0x799C	# <CJK>
0x506B	0x79A1	# <CJK>
0x506C	0x79A8	# <CJK>
0x506D	0x79A9	# <CJK>
0x506E	0x79AB	# <CJK>
0x506F	0x79AF	# <CJK>
0x5070	0x79B1	# <CJK>
0x5071	0x79B4	# <CJK>
0x5072	0x79B8	# <CJK>
0x5073	0x79BB	# <CJK>
0x5074	0x79C2	# <CJK>
0x5075	0x79C4	# <CJK>
0x5076	0x79C7	# <CJK>
0x5077	0x79C8	# <CJK>
0x5078	0x79CA	# <CJK>
0x5079	0x79CF	# <CJK>
0x507A	0x79D4	# <CJK>
0x507B	0x79D6	# <CJK>
0x507C	0x79DA	# <CJK>
0x507D	0x79DD	# <CJK>
0x507E	0x79DE	# <CJK>
0x5121	0x79E0	# <CJK>
0x5122	0x79E2	# <CJK>
0x5123	0x79E5	# <CJK>
0x5124	0x79EA	# <CJK>
0x5125	0x79EB	# <CJK>
0x5126	0x79ED	# <CJK>
0x5127	0x79F1	# <CJK>
0x5128	0x79F8	# <CJK>
0x5129	0x79FC	# <CJK>
0x512A	0x7A02	# <CJK>
0x512B	0x7A03	# <CJK>
0x512C	0x7A07	# <CJK>
0x512D	0x7A09	# <CJK>
0x512E	0x7A0A	# <CJK>
0x512F	0x7A0C	# <CJK>
0x5130	0x7A11	# <CJK>
0x5131	0x7A15	# <CJK>
0x5132	0x7A1B	# <CJK>
0x5133	0x7A1E	# <CJK>
0x5134	0x7A21	# <CJK>
0x5135	0x7A27	# <CJK>
0x5136	0x7A2B	# <CJK>
0x5137	0x7A2D	# <CJK>
0x5138	0x7A2F	# <CJK>
0x5139	0x7A30	# <CJK>
0x513A	0x7A34	# <CJK>
0x513B	0x7A35	# <CJK>
0x513C	0x7A38	# <CJK>
0x513D	0x7A39	# <CJK>
0x513E	0x7A3A	# <CJK>
0x513F	0x7A44	# <CJK>
0x5140	0x7A45	# <CJK>
0x5141	0x7A47	# <CJK>
0x5142	0x7A48	# <CJK>
0x5143	0x7A4C	# <CJK>
0x5144	0x7A55	# <CJK>
0x5145	0x7A56	# <CJK>
0x5146	0x7A59	# <CJK>
0x5147	0x7A5C	# <CJK>
0x5148	0x7A5D	# <CJK>
0x5149	0x7A5F	# <CJK>
0x514A	0x7A60	# <CJK>
0x514B	0x7A65	# <CJK>
0x514C	0x7A67	# <CJK>
0x514D	0x7A6A	# <CJK>
0x514E	0x7A6D	# <CJK>
0x514F	0x7A75	# <CJK>
0x5150	0x7A78	# <CJK>
0x5151	0x7A7E	# <CJK>
0x5152	0x7A80	# <CJK>
0x5153	0x7A82	# <CJK>
0x5154	0x7A85	# <CJK>
0x5155	0x7A86	# <CJK>
0x5156	0x7A8A	# <CJK>
0x5157	0x7A8B	# <CJK>
0x5158	0x7A90	# <CJK>
0x5159	0x7A91	# <CJK>
0x515A	0x7A94	# <CJK>
0x515B	0x7A9E	# <CJK>
0x515C	0x7AA0	# <CJK>
0x515D	0x7AA3	# <CJK>
0x515E	0x7AAC	# <CJK>
0x515F	0x7AB3	# <CJK>
0x5160	0x7AB5	# <CJK>
0x5161	0x7AB9	# <CJK>
0x5162	0x7ABB	# <CJK>
0x5163	0x7ABC	# <CJK>
0x5164	0x7AC6	# <CJK>
0x5165	0x7AC9	# <CJK>
0x5166	0x7ACC	# <CJK>
0x5167	0x7ACE	# <CJK>
0x5168	0x7AD1	# <CJK>
0x5169	0x7ADB	# <CJK>
0x516A	0x7AE8	# <CJK>
0x516B	0x7AE9	# <CJK>
0x516C	0x7AEB	# <CJK>
0x516D	0x7AEC	# <CJK>
0x516E	0x7AF1	# <CJK>
0x516F	0x7AF4	# <CJK>
0x5170	0x7AFB	# <CJK>
0x5171	0x7AFD	# <CJK>
0x5172	0x7AFE	# <CJK>
0x5173	0x7B07	# <CJK>
0x5174	0x7B14	# <CJK>
0x5175	0x7B1F	# <CJK>
0x5176	0x7B23	# <CJK>
0x5177	0x7B27	# <CJK>
0x5178	0x7B29	# <CJK>
0x5179	0x7B2A	# <CJK>
0x517A	0x7B2B	# <CJK>
0x517B	0x7B2D	# <CJK>
0x517C	0x7B2E	# <CJK>
0x517D	0x7B2F	# <CJK>
0x517E	0x7B30	# <CJK>
0x5221	0x7B31	# <CJK>
0x5222	0x7B34	# <CJK>
0x5223	0x7B3D	# <CJK>
0x5224	0x7B3F	# <CJK>
0x5225	0x7B40	# <CJK>
0x5226	0x7B41	# <CJK>
0x5227	0x7B47	# <CJK>
0x5228	0x7B4E	# <CJK>
0x5229	0x7B55	# <CJK>
0x522A	0x7B60	# <CJK>
0x522B	0x7B64	# <CJK>
0x522C	0x7B66	# <CJK>
0x522D	0x7B69	# <CJK>
0x522E	0x7B6A	# <CJK>
0x522F	0x7B6D	# <CJK>
0x5230	0x7B6F	# <CJK>
0x5231	0x7B72	# <CJK>
0x5232	0x7B73	# <CJK>
0x5233	0x7B77	# <CJK>
0x5234	0x7B84	# <CJK>
0x5235	0x7B89	# <CJK>
0x5236	0x7B8E	# <CJK>
0x5237	0x7B90	# <CJK>
0x5238	0x7B91	# <CJK>
0x5239	0x7B96	# <CJK>
0x523A	0x7B9B	# <CJK>
0x523B	0x7B9E	# <CJK>
0x523C	0x7BA0	# <CJK>
0x523D	0x7BA5	# <CJK>
0x523E	0x7BAC	# <CJK>
0x523F	0x7BAF	# <CJK>
0x5240	0x7BB0	# <CJK>
0x5241	0x7BB2	# <CJK>
0x5242	0x7BB5	# <CJK>
0x5243	0x7BB6	# <CJK>
0x5244	0x7BBA	# <CJK>
0x5245	0x7BBB	# <CJK>
0x5246	0x7BBC	# <CJK>
0x5247	0x7BBD	# <CJK>
0x5248	0x7BC2	# <CJK>
0x5249	0x7BC5	# <CJK>
0x524A	0x7BC8	# <CJK>
0x524B	0x7BCA	# <CJK>
0x524C	0x7BD4	# <CJK>
0x524D	0x7BD6	# <CJK>
0x524E	0x7BD7	# <CJK>
0x524F	0x7BD9	# <CJK>
0x5250	0x7BDA	# <CJK>
0x5251	0x7BDB	# <CJK>
0x5252	0x7BE8	# <CJK>
0x5253	0x7BEA	# <CJK>
0x5254	0x7BF2	# <CJK>
0x5255	0x7BF4	# <CJK>
0x5256	0x7BF5	# <CJK>
0x5257	0x7BF8	# <CJK>
0x5258	0x7BF9	# <CJK>
0x5259	0x7BFA	# <CJK>
0x525A	0x7BFC	# <CJK>
0x525B	0x7BFE	# <CJK>
0x525C	0x7C01	# <CJK>
0x525D	0x7C02	# <CJK>
0x525E	0x7C03	# <CJK>
0x525F	0x7C04	# <CJK>
0x5260	0x7C06	# <CJK>
0x5261	0x7C09	# <CJK>
0x5262	0x7C0B	# <CJK>
0x5263	0x7C0C	# <CJK>
0x5264	0x7C0E	# <CJK>
0x5265	0x7C0F	# <CJK>
0x5266	0x7C19	# <CJK>
0x5267	0x7C1B	# <CJK>
0x5268	0x7C20	# <CJK>
0x5269	0x7C25	# <CJK>
0x526A	0x7C26	# <CJK>
0x526B	0x7C28	# <CJK>
0x526C	0x7C2C	# <CJK>
0x526D	0x7C31	# <CJK>
0x526E	0x7C33	# <CJK>
0x526F	0x7C34	# <CJK>
0x5270	0x7C36	# <CJK>
0x5271	0x7C39	# <CJK>
0x5272	0x7C3A	# <CJK>
0x5273	0x7C46	# <CJK>
0x5274	0x7C4A	# <CJK>
0x5275	0x7C55	# <CJK>
0x5276	0x7C51	# <CJK>
0x5277	0x7C52	# <CJK>
0x5278	0x7C53	# <CJK>
0x5279	0x7C59	# <CJK>
0x527A	0x7C5A	# <CJK>
0x527B	0x7C5B	# <CJK>
0x527C	0x7C5C	# <CJK>
0x527D	0x7C5D	# <CJK>
0x527E	0x7C5E	# <CJK>
0x5321	0x7C61	# <CJK>
0x5322	0x7C63	# <CJK>
0x5323	0x7C67	# <CJK>
0x5324	0x7C69	# <CJK>
0x5325	0x7C6D	# <CJK>
0x5326	0x7C6E	# <CJK>
0x5327	0x7C70	# <CJK>
0x5328	0x7C72	# <CJK>
0x5329	0x7C79	# <CJK>
0x532A	0x7C7C	# <CJK>
0x532B	0x7C7D	# <CJK>
0x532C	0x7C86	# <CJK>
0x532D	0x7C87	# <CJK>
0x532E	0x7C8F	# <CJK>
0x532F	0x7C94	# <CJK>
0x5330	0x7C9E	# <CJK>
0x5331	0x7CA0	# <CJK>
0x5332	0x7CA6	# <CJK>
0x5333	0x7CB0	# <CJK>
0x5334	0x7CB6	# <CJK>
0x5335	0x7CB7	# <CJK>
0x5336	0x7CBA	# <CJK>
0x5337	0x7CBB	# <CJK>
0x5338	0x7CBC	# <CJK>
0x5339	0x7CBF	# <CJK>
0x533A	0x7CC4	# <CJK>
0x533B	0x7CC7	# <CJK>
0x533C	0x7CC8	# <CJK>
0x533D	0x7CC9	# <CJK>
0x533E	0x7CCD	# <CJK>
0x533F	0x7CCF	# <CJK>
0x5340	0x7CD3	# <CJK>
0x5341	0x7CD4	# <CJK>
0x5342	0x7CD5	# <CJK>
0x5343	0x7CD7	# <CJK>
0x5344	0x7CD9	# <CJK>
0x5345	0x7CDA	# <CJK>
0x5346	0x7CDD	# <CJK>
0x5347	0x7CE6	# <CJK>
0x5348	0x7CE9	# <CJK>
0x5349	0x7CEB	# <CJK>
0x534A	0x7CF5	# <CJK>
0x534B	0x7D03	# <CJK>
0x534C	0x7D07	# <CJK>
0x534D	0x7D08	# <CJK>
0x534E	0x7D09	# <CJK>
0x534F	0x7D0F	# <CJK>
0x5350	0x7D11	# <CJK>
0x5351	0x7D12	# <CJK>
0x5352	0x7D13	# <CJK>
0x5353	0x7D16	# <CJK>
0x5354	0x7D1D	# <CJK>
0x5355	0x7D1E	# <CJK>
0x5356	0x7D23	# <CJK>
0x5357	0x7D26	# <CJK>
0x5358	0x7D2A	# <CJK>
0x5359	0x7D2D	# <CJK>
0x535A	0x7D31	# <CJK>
0x535B	0x7D3C	# <CJK>
0x535C	0x7D3D	# <CJK>
0x535D	0x7D3E	# <CJK>
0x535E	0x7D40	# <CJK>
0x535F	0x7D41	# <CJK>
0x5360	0x7D47	# <CJK>
0x5361	0x7D48	# <CJK>
0x5362	0x7D4D	# <CJK>
0x5363	0x7D51	# <CJK>
0x5364	0x7D53	# <CJK>
0x5365	0x7D57	# <CJK>
0x5366	0x7D59	# <CJK>
0x5367	0x7D5A	# <CJK>
0x5368	0x7D5C	# <CJK>
0x5369	0x7D5D	# <CJK>
0x536A	0x7D65	# <CJK>
0x536B	0x7D67	# <CJK>
0x536C	0x7D6A	# <CJK>
0x536D	0x7D70	# <CJK>
0x536E	0x7D78	# <CJK>
0x536F	0x7D7A	# <CJK>
0x5370	0x7D7B	# <CJK>
0x5371	0x7D7F	# <CJK>
0x5372	0x7D81	# <CJK>
0x5373	0x7D82	# <CJK>
0x5374	0x7D83	# <CJK>
0x5375	0x7D85	# <CJK>
0x5376	0x7D86	# <CJK>
0x5377	0x7D88	# <CJK>
0x5378	0x7D8B	# <CJK>
0x5379	0x7D8C	# <CJK>
0x537A	0x7D8D	# <CJK>
0x537B	0x7D91	# <CJK>
0x537C	0x7D96	# <CJK>
0x537D	0x7D97	# <CJK>
0x537E	0x7D9D	# <CJK>
0x5421	0x7D9E	# <CJK>
0x5422	0x7DA6	# <CJK>
0x5423	0x7DA7	# <CJK>
0x5424	0x7DAA	# <CJK>
0x5425	0x7DB3	# <CJK>
0x5426	0x7DB6	# <CJK>
0x5427	0x7DB7	# <CJK>
0x5428	0x7DB9	# <CJK>
0x5429	0x7DC2	# <CJK>
0x542A	0x7DC3	# <CJK>
0x542B	0x7DC4	# <CJK>
0x542C	0x7DC5	# <CJK>
0x542D	0x7DC6	# <CJK>
0x542E	0x7DCC	# <CJK>
0x542F	0x7DCD	# <CJK>
0x5430	0x7DCE	# <CJK>
0x5431	0x7DD7	# <CJK>
0x5432	0x7DD9	# <CJK>
0x5433	0x7E00	# <CJK>
0x5434	0x7DE2	# <CJK>
0x5435	0x7DE5	# <CJK>
0x5436	0x7DE6	# <CJK>
0x5437	0x7DEA	# <CJK>
0x5438	0x7DEB	# <CJK>
0x5439	0x7DED	# <CJK>
0x543A	0x7DF1	# <CJK>
0x543B	0x7DF5	# <CJK>
0x543C	0x7DF6	# <CJK>
0x543D	0x7DF9	# <CJK>
0x543E	0x7DFA	# <CJK>
0x543F	0x7E08	# <CJK>
0x5440	0x7E10	# <CJK>
0x5441	0x7E11	# <CJK>
0x5442	0x7E15	# <CJK>
0x5443	0x7E17	# <CJK>
0x5444	0x7E1C	# <CJK>
0x5445	0x7E1D	# <CJK>
0x5446	0x7E20	# <CJK>
0x5447	0x7E27	# <CJK>
0x5448	0x7E28	# <CJK>
0x5449	0x7E2C	# <CJK>
0x544A	0x7E2D	# <CJK>
0x544B	0x7E2F	# <CJK>
0x544C	0x7E33	# <CJK>
0x544D	0x7E36	# <CJK>
0x544E	0x7E3F	# <CJK>
0x544F	0x7E44	# <CJK>
0x5450	0x7E45	# <CJK>
0x5451	0x7E47	# <CJK>
0x5452	0x7E4E	# <CJK>
0x5453	0x7E50	# <CJK>
0x5454	0x7E52	# <CJK>
0x5455	0x7E58	# <CJK>
0x5456	0x7E5F	# <CJK>
0x5457	0x7E61	# <CJK>
0x5458	0x7E62	# <CJK>
0x5459	0x7E65	# <CJK>
0x545A	0x7E6B	# <CJK>
0x545B	0x7E6E	# <CJK>
0x545C	0x7E6F	# <CJK>
0x545D	0x7E73	# <CJK>
0x545E	0x7E78	# <CJK>
0x545F	0x7E7E	# <CJK>
0x5460	0x7E81	# <CJK>
0x5461	0x7E86	# <CJK>
0x5462	0x7E87	# <CJK>
0x5463	0x7E8A	# <CJK>
0x5464	0x7E8D	# <CJK>
0x5465	0x7E91	# <CJK>
0x5466	0x7E95	# <CJK>
0x5467	0x7E98	# <CJK>
0x5468	0x7E9A	# <CJK>
0x5469	0x7E9D	# <CJK>
0x546A	0x7E9E	# <CJK>
0x546B	0x7F3C	# <CJK>
0x546C	0x7F3B	# <CJK>
0x546D	0x7F3D	# <CJK>
0x546E	0x7F3E	# <CJK>
0x546F	0x7F3F	# <CJK>
0x5470	0x7F43	# <CJK>
0x5471	0x7F44	# <CJK>
0x5472	0x7F47	# <CJK>
0x5473	0x7F4F	# <CJK>
0x5474	0x7F52	# <CJK>
0x5475	0x7F53	# <CJK>
0x5476	0x7F5B	# <CJK>
0x5477	0x7F5C	# <CJK>
0x5478	0x7F5D	# <CJK>
0x5479	0x7F61	# <CJK>
0x547A	0x7F63	# <CJK>
0x547B	0x7F64	# <CJK>
0x547C	0x7F65	# <CJK>
0x547D	0x7F66	# <CJK>
0x547E	0x7F6D	# <CJK>
0x5521	0x7F71	# <CJK>
0x5522	0x7F7D	# <CJK>
0x5523	0x7F7E	# <CJK>
0x5524	0x7F7F	# <CJK>
0x5525	0x7F80	# <CJK>
0x5526	0x7F8B	# <CJK>
0x5527	0x7F8D	# <CJK>
0x5528	0x7F8F	# <CJK>
0x5529	0x7F90	# <CJK>
0x552A	0x7F91	# <CJK>
0x552B	0x7F96	# <CJK>
0x552C	0x7F97	# <CJK>
0x552D	0x7F9C	# <CJK>
0x552E	0x7FA1	# <CJK>
0x552F	0x7FA2	# <CJK>
0x5530	0x7FA6	# <CJK>
0x5531	0x7FAA	# <CJK>
0x5532	0x7FAD	# <CJK>
0x5533	0x7FB4	# <CJK>
0x5534	0x7FBC	# <CJK>
0x5535	0x7FBF	# <CJK>
0x5536	0x7FC0	# <CJK>
0x5537	0x7FC3	# <CJK>
0x5538	0x7FC8	# <CJK>
0x5539	0x7FCE	# <CJK>
0x553A	0x7FCF	# <CJK>
0x553B	0x7FDB	# <CJK>
0x553C	0x7FDF	# <CJK>
0x553D	0x7FE3	# <CJK>
0x553E	0x7FE5	# <CJK>
0x553F	0x7FE8	# <CJK>
0x5540	0x7FEC	# <CJK>
0x5541	0x7FEE	# <CJK>
0x5542	0x7FEF	# <CJK>
0x5543	0x7FF2	# <CJK>
0x5544	0x7FFA	# <CJK>
0x5545	0x7FFD	# <CJK>
0x5546	0x7FFE	# <CJK>
0x5547	0x7FFF	# <CJK>
0x5548	0x8007	# <CJK>
0x5549	0x8008	# <CJK>
0x554A	0x800A	# <CJK>
0x554B	0x800D	# <CJK>
0x554C	0x800E	# <CJK>
0x554D	0x800F	# <CJK>
0x554E	0x8011	# <CJK>
0x554F	0x8013	# <CJK>
0x5550	0x8014	# <CJK>
0x5551	0x8016	# <CJK>
0x5552	0x801D	# <CJK>
0x5553	0x801E	# <CJK>
0x5554	0x801F	# <CJK>
0x5555	0x8020	# <CJK>
0x5556	0x8024	# <CJK>
0x5557	0x8026	# <CJK>
0x5558	0x802C	# <CJK>
0x5559	0x802E	# <CJK>
0x555A	0x8030	# <CJK>
0x555B	0x8034	# <CJK>
0x555C	0x8035	# <CJK>
0x555D	0x8037	# <CJK>
0x555E	0x8039	# <CJK>
0x555F	0x803A	# <CJK>
0x5560	0x803C	# <CJK>
0x5561	0x803E	# <CJK>
0x5562	0x8040	# <CJK>
0x5563	0x8044	# <CJK>
0x5564	0x8060	# <CJK>
0x5565	0x8064	# <CJK>
0x5566	0x8066	# <CJK>
0x5567	0x806D	# <CJK>
0x5568	0x8071	# <CJK>
0x5569	0x8075	# <CJK>
0x556A	0x8081	# <CJK>
0x556B	0x8088	# <CJK>
0x556C	0x808E	# <CJK>
0x556D	0x809C	# <CJK>
0x556E	0x809E	# <CJK>
0x556F	0x80A6	# <CJK>
0x5570	0x80A7	# <CJK>
0x5571	0x80AB	# <CJK>
0x5572	0x80B8	# <CJK>
0x5573	0x80B9	# <CJK>
0x5574	0x80C8	# <CJK>
0x5575	0x80CD	# <CJK>
0x5576	0x80CF	# <CJK>
0x5577	0x80D2	# <CJK>
0x5578	0x80D4	# <CJK>
0x5579	0x80D5	# <CJK>
0x557A	0x80D7	# <CJK>
0x557B	0x80D8	# <CJK>
0x557C	0x80E0	# <CJK>
0x557D	0x80ED	# <CJK>
0x557E	0x80EE	# <CJK>
0x5621	0x80F0	# <CJK>
0x5622	0x80F2	# <CJK>
0x5623	0x80F3	# <CJK>
0x5624	0x80F6	# <CJK>
0x5625	0x80F9	# <CJK>
0x5626	0x80FA	# <CJK>
0x5627	0x80FE	# <CJK>
0x5628	0x8103	# <CJK>
0x5629	0x810B	# <CJK>
0x562A	0x8116	# <CJK>
0x562B	0x8117	# <CJK>
0x562C	0x8118	# <CJK>
0x562D	0x811C	# <CJK>
0x562E	0x811E	# <CJK>
0x562F	0x8120	# <CJK>
0x5630	0x8124	# <CJK>
0x5631	0x8127	# <CJK>
0x5632	0x812C	# <CJK>
0x5633	0x8130	# <CJK>
0x5634	0x8135	# <CJK>
0x5635	0x813A	# <CJK>
0x5636	0x813C	# <CJK>
0x5637	0x8145	# <CJK>
0x5638	0x8147	# <CJK>
0x5639	0x814A	# <CJK>
0x563A	0x814C	# <CJK>
0x563B	0x8152	# <CJK>
0x563C	0x8157	# <CJK>
0x563D	0x8160	# <CJK>
0x563E	0x8161	# <CJK>
0x563F	0x8167	# <CJK>
0x5640	0x8168	# <CJK>
0x5641	0x8169	# <CJK>
0x5642	0x816D	# <CJK>
0x5643	0x816F	# <CJK>
0x5644	0x8177	# <CJK>
0x5645	0x8181	# <CJK>
0x5646	0x8190	# <CJK>
0x5647	0x8184	# <CJK>
0x5648	0x8185	# <CJK>
0x5649	0x8186	# <CJK>
0x564A	0x818B	# <CJK>
0x564B	0x818E	# <CJK>
0x564C	0x8196	# <CJK>
0x564D	0x8198	# <CJK>
0x564E	0x819B	# <CJK>
0x564F	0x819E	# <CJK>
0x5650	0x81A2	# <CJK>
0x5651	0x81AE	# <CJK>
0x5652	0x81B2	# <CJK>
0x5653	0x81B4	# <CJK>
0x5654	0x81BB	# <CJK>
0x5655	0x81CB	# <CJK>
0x5656	0x81C3	# <CJK>
0x5657	0x81C5	# <CJK>
0x5658	0x81CA	# <CJK>
0x5659	0x81CE	# <CJK>
0x565A	0x81CF	# <CJK>
0x565B	0x81D5	# <CJK>
0x565C	0x81D7	# <CJK>
0x565D	0x81DB	# <CJK>
0x565E	0x81DD	# <CJK>
0x565F	0x81DE	# <CJK>
0x5660	0x81E1	# <CJK>
0x5661	0x81E4	# <CJK>
0x5662	0x81EB	# <CJK>
0x5663	0x81EC	# <CJK>
0x5664	0x81F0	# <CJK>
0x5665	0x81F1	# <CJK>
0x5666	0x81F2	# <CJK>
0x5667	0x81F5	# <CJK>
0x5668	0x81F6	# <CJK>
0x5669	0x81F8	# <CJK>
0x566A	0x81F9	# <CJK>
0x566B	0x81FD	# <CJK>
0x566C	0x81FF	# <CJK>
0x566D	0x8200	# <CJK>
0x566E	0x8203	# <CJK>
0x566F	0x820F	# <CJK>
0x5670	0x8213	# <CJK>
0x5671	0x8214	# <CJK>
0x5672	0x8219	# <CJK>
0x5673	0x821A	# <CJK>
0x5674	0x821D	# <CJK>
0x5675	0x8221	# <CJK>
0x5676	0x8222	# <CJK>
0x5677	0x8228	# <CJK>
0x5678	0x8232	# <CJK>
0x5679	0x8234	# <CJK>
0x567A	0x823A	# <CJK>
0x567B	0x8243	# <CJK>
0x567C	0x8244	# <CJK>
0x567D	0x8245	# <CJK>
0x567E	0x8246	# <CJK>
0x5721	0x824B	# <CJK>
0x5722	0x824E	# <CJK>
0x5723	0x824F	# <CJK>
0x5724	0x8251	# <CJK>
0x5725	0x8256	# <CJK>
0x5726	0x825C	# <CJK>
0x5727	0x8260	# <CJK>
0x5728	0x8263	# <CJK>
0x5729	0x8267	# <CJK>
0x572A	0x826D	# <CJK>
0x572B	0x8274	# <CJK>
0x572C	0x827B	# <CJK>
0x572D	0x827D	# <CJK>
0x572E	0x827F	# <CJK>
0x572F	0x8280	# <CJK>
0x5730	0x8281	# <CJK>
0x5731	0x8283	# <CJK>
0x5732	0x8284	# <CJK>
0x5733	0x8287	# <CJK>
0x5734	0x8289	# <CJK>
0x5735	0x828A	# <CJK>
0x5736	0x828E	# <CJK>
0x5737	0x8291	# <CJK>
0x5738	0x8294	# <CJK>
0x5739	0x8296	# <CJK>
0x573A	0x8298	# <CJK>
0x573B	0x829A	# <CJK>
0x573C	0x829B	# <CJK>
0x573D	0x82A0	# <CJK>
0x573E	0x82A1	# <CJK>
0x573F	0x82A3	# <CJK>
0x5740	0x82A4	# <CJK>
0x5741	0x82A7	# <CJK>
0x5742	0x82A8	# <CJK>
0x5743	0x82A9	# <CJK>
0x5744	0x82AA	# <CJK>
0x5745	0x82AE	# <CJK>
0x5746	0x82B0	# <CJK>
0x5747	0x82B2	# <CJK>
0x5748	0x82B4	# <CJK>
0x5749	0x82B7	# <CJK>
0x574A	0x82BA	# <CJK>
0x574B	0x82BC	# <CJK>
0x574C	0x82BE	# <CJK>
0x574D	0x82BF	# <CJK>
0x574E	0x82C6	# <CJK>
0x574F	0x82D0	# <CJK>
0x5750	0x82D5	# <CJK>
0x5751	0x82DA	# <CJK>
0x5752	0x82E0	# <CJK>
0x5753	0x82E2	# <CJK>
0x5754	0x82E4	# <CJK>
0x5755	0x82E8	# <CJK>
0x5756	0x82EA	# <CJK>
0x5757	0x82ED	# <CJK>
0x5758	0x82EF	# <CJK>
0x5759	0x82F6	# <CJK>
0x575A	0x82F7	# <CJK>
0x575B	0x82FD	# <CJK>
0x575C	0x82FE	# <CJK>
0x575D	0x8300	# <CJK>
0x575E	0x8301	# <CJK>
0x575F	0x8307	# <CJK>
0x5760	0x8308	# <CJK>
0x5761	0x830A	# <CJK>
0x5762	0x830B	# <CJK>
0x5763	0x8354	# <CJK>
0x5764	0x831B	# <CJK>
0x5765	0x831D	# <CJK>
0x5766	0x831E	# <CJK>
0x5767	0x831F	# <CJK>
0x5768	0x8321	# <CJK>
0x5769	0x8322	# <CJK>
0x576A	0x832C	# <CJK>
0x576B	0x832D	# <CJK>
0x576C	0x832E	# <CJK>
0x576D	0x8330	# <CJK>
0x576E	0x8333	# <CJK>
0x576F	0x8337	# <CJK>
0x5770	0x833A	# <CJK>
0x5771	0x833C	# <CJK>
0x5772	0x833D	# <CJK>
0x5773	0x8342	# <CJK>
0x5774	0x8343	# <CJK>
0x5775	0x8344	# <CJK>
0x5776	0x8347	# <CJK>
0x5777	0x834D	# <CJK>
0x5778	0x834E	# <CJK>
0x5779	0x8351	# <CJK>
0x577A	0x8355	# <CJK>
0x577B	0x8356	# <CJK>
0x577C	0x8357	# <CJK>
0x577D	0x8370	# <CJK>
0x577E	0x8378	# <CJK>
0x5821	0x837D	# <CJK>
0x5822	0x837F	# <CJK>
0x5823	0x8380	# <CJK>
0x5824	0x8382	# <CJK>
0x5825	0x8384	# <CJK>
0x5826	0x8386	# <CJK>
0x5827	0x838D	# <CJK>
0x5828	0x8392	# <CJK>
0x5829	0x8394	# <CJK>
0x582A	0x8395	# <CJK>
0x582B	0x8398	# <CJK>
0x582C	0x8399	# <CJK>
0x582D	0x839B	# <CJK>
0x582E	0x839C	# <CJK>
0x582F	0x839D	# <CJK>
0x5830	0x83A6	# <CJK>
0x5831	0x83A7	# <CJK>
0x5832	0x83A9	# <CJK>
0x5833	0x83AC	# <CJK>
0x5834	0x83BE	# <CJK>
0x5835	0x83BF	# <CJK>
0x5836	0x83C0	# <CJK>
0x5837	0x83C7	# <CJK>
0x5838	0x83C9	# <CJK>
0x5839	0x83CF	# <CJK>
0x583A	0x83D0	# <CJK>
0x583B	0x83D1	# <CJK>
0x583C	0x83D4	# <CJK>
0x583D	0x83DD	# <CJK>
0x583E	0x8353	# <CJK>
0x583F	0x83E8	# <CJK>
0x5840	0x83EA	# <CJK>
0x5841	0x83F6	# <CJK>
0x5842	0x83F8	# <CJK>
0x5843	0x83F9	# <CJK>
0x5844	0x83FC	# <CJK>
0x5845	0x8401	# <CJK>
0x5846	0x8406	# <CJK>
0x5847	0x840A	# <CJK>
0x5848	0x840F	# <CJK>
0x5849	0x8411	# <CJK>
0x584A	0x8415	# <CJK>
0x584B	0x8419	# <CJK>
0x584C	0x83AD	# <CJK>
0x584D	0x842F	# <CJK>
0x584E	0x8439	# <CJK>
0x584F	0x8445	# <CJK>
0x5850	0x8447	# <CJK>
0x5851	0x8448	# <CJK>
0x5852	0x844A	# <CJK>
0x5853	0x844D	# <CJK>
0x5854	0x844F	# <CJK>
0x5855	0x8451	# <CJK>
0x5856	0x8452	# <CJK>
0x5857	0x8456	# <CJK>
0x5858	0x8458	# <CJK>
0x5859	0x8459	# <CJK>
0x585A	0x845A	# <CJK>
0x585B	0x845C	# <CJK>
0x585C	0x8460	# <CJK>
0x585D	0x8464	# <CJK>
0x585E	0x8465	# <CJK>
0x585F	0x8467	# <CJK>
0x5860	0x846A	# <CJK>
0x5861	0x8470	# <CJK>
0x5862	0x8473	# <CJK>
0x5863	0x8474	# <CJK>
0x5864	0x8476	# <CJK>
0x5865	0x8478	# <CJK>
0x5866	0x847C	# <CJK>
0x5867	0x847D	# <CJK>
0x5868	0x8481	# <CJK>
0x5869	0x8485	# <CJK>
0x586A	0x8492	# <CJK>
0x586B	0x8493	# <CJK>
0x586C	0x8495	# <CJK>
0x586D	0x849E	# <CJK>
0x586E	0x84A6	# <CJK>
0x586F	0x84A8	# <CJK>
0x5870	0x84A9	# <CJK>
0x5871	0x84AA	# <CJK>
0x5872	0x84AF	# <CJK>
0x5873	0x84B1	# <CJK>
0x5874	0x84B4	# <CJK>
0x5875	0x84BA	# <CJK>
0x5876	0x84BD	# <CJK>
0x5877	0x84BE	# <CJK>
0x5878	0x84C0	# <CJK>
0x5879	0x84C2	# <CJK>
0x587A	0x84C7	# <CJK>
0x587B	0x84C8	# <CJK>
0x587C	0x84CC	# <CJK>
0x587D	0x84CF	# <CJK>
0x587E	0x84D3	# <CJK>
0x5921	0x84DC	# <CJK>
0x5922	0x84E7	# <CJK>
0x5923	0x84EA	# <CJK>
0x5924	0x84EF	# <CJK>
0x5925	0x84F0	# <CJK>
0x5926	0x84F1	# <CJK>
0x5927	0x84F2	# <CJK>
0x5928	0x84F7	# <CJK>
0x5929	0x8532	# <CJK>
0x592A	0x84FA	# <CJK>
0x592B	0x84FB	# <CJK>
0x592C	0x84FD	# <CJK>
0x592D	0x8502	# <CJK>
0x592E	0x8503	# <CJK>
0x592F	0x8507	# <CJK>
0x5930	0x850C	# <CJK>
0x5931	0x850E	# <CJK>
0x5932	0x8510	# <CJK>
0x5933	0x851C	# <CJK>
0x5934	0x851E	# <CJK>
0x5935	0x8522	# <CJK>
0x5936	0x8523	# <CJK>
0x5937	0x8524	# <CJK>
0x5938	0x8525	# <CJK>
0x5939	0x8527	# <CJK>
0x593A	0x852A	# <CJK>
0x593B	0x852B	# <CJK>
0x593C	0x852F	# <CJK>
0x593D	0x8533	# <CJK>
0x593E	0x8534	# <CJK>
0x593F	0x8536	# <CJK>
0x5940	0x853F	# <CJK>
0x5941	0x8546	# <CJK>
0x5942	0x854F	# <CJK>
0x5943	0x8550	# <CJK>
0x5944	0x8551	# <CJK>
0x5945	0x8552	# <CJK>
0x5946	0x8553	# <CJK>
0x5947	0x8556	# <CJK>
0x5948	0x8559	# <CJK>
0x5949	0x855C	# <CJK>
0x594A	0x855D	# <CJK>
0x594B	0x855E	# <CJK>
0x594C	0x855F	# <CJK>
0x594D	0x8560	# <CJK>
0x594E	0x8561	# <CJK>
0x594F	0x8562	# <CJK>
0x5950	0x8564	# <CJK>
0x5951	0x856B	# <CJK>
0x5952	0x856F	# <CJK>
0x5953	0x8579	# <CJK>
0x5954	0x857A	# <CJK>
0x5955	0x857B	# <CJK>
0x5956	0x857D	# <CJK>
0x5957	0x857F	# <CJK>
0x5958	0x8581	# <CJK>
0x5959	0x8585	# <CJK>
0x595A	0x8586	# <CJK>
0x595B	0x8589	# <CJK>
0x595C	0x858B	# <CJK>
0x595D	0x858C	# <CJK>
0x595E	0x858F	# <CJK>
0x595F	0x8593	# <CJK>
0x5960	0x8598	# <CJK>
0x5961	0x859D	# <CJK>
0x5962	0x859F	# <CJK>
0x5963	0x85A0	# <CJK>
0x5964	0x85A2	# <CJK>
0x5965	0x85A5	# <CJK>
0x5966	0x85A7	# <CJK>
0x5967	0x85B4	# <CJK>
0x5968	0x85B6	# <CJK>
0x5969	0x85B7	# <CJK>
0x596A	0x85B8	# <CJK>
0x596B	0x85BC	# <CJK>
0x596C	0x85BD	# <CJK>
0x596D	0x85BE	# <CJK>
0x596E	0x85BF	# <CJK>
0x596F	0x85C2	# <CJK>
0x5970	0x85C7	# <CJK>
0x5971	0x85CA	# <CJK>
0x5972	0x85CB	# <CJK>
0x5973	0x85CE	# <CJK>
0x5974	0x85AD	# <CJK>
0x5975	0x85D8	# <CJK>
0x5976	0x85DA	# <CJK>
0x5977	0x85DF	# <CJK>
0x5978	0x85E0	# <CJK>
0x5979	0x85E6	# <CJK>
0x597A	0x85E8	# <CJK>
0x597B	0x85ED	# <CJK>
0x597C	0x85F3	# <CJK>
0x597D	0x85F6	# <CJK>
0x597E	0x85FC	# <CJK>
0x5A21	0x85FF	# <CJK>
0x5A22	0x8600	# <CJK>
0x5A23	0x8604	# <CJK>
0x5A24	0x8605	# <CJK>
0x5A25	0x860D	# <CJK>
0x5A26	0x860E	# <CJK>
0x5A27	0x8610	# <CJK>
0x5A28	0x8611	# <CJK>
0x5A29	0x8612	# <CJK>
0x5A2A	0x8618	# <CJK>
0x5A2B	0x8619	# <CJK>
0x5A2C	0x861B	# <CJK>
0x5A2D	0x861E	# <CJK>
0x5A2E	0x8621	# <CJK>
0x5A2F	0x8627	# <CJK>
0x5A30	0x8629	# <CJK>
0x5A31	0x8636	# <CJK>
0x5A32	0x8638	# <CJK>
0x5A33	0x863A	# <CJK>
0x5A34	0x863C	# <CJK>
0x5A35	0x863D	# <CJK>
0x5A36	0x8640	# <CJK>
0x5A37	0x8642	# <CJK>
0x5A38	0x8646	# <CJK>
0x5A39	0x8652	# <CJK>
0x5A3A	0x8653	# <CJK>
0x5A3B	0x8656	# <CJK>
0x5A3C	0x8657	# <CJK>
0x5A3D	0x8658	# <CJK>
0x5A3E	0x8659	# <CJK>
0x5A3F	0x865D	# <CJK>
0x5A40	0x8660	# <CJK>
0x5A41	0x8661	# <CJK>
0x5A42	0x8662	# <CJK>
0x5A43	0x8663	# <CJK>
0x5A44	0x8664	# <CJK>
0x5A45	0x8669	# <CJK>
0x5A46	0x866C	# <CJK>
0x5A47	0x866F	# <CJK>
0x5A48	0x8675	# <CJK>
0x5A49	0x8676	# <CJK>
0x5A4A	0x8677	# <CJK>
0x5A4B	0x867A	# <CJK>
0x5A4C	0x868D	# <CJK>
0x5A4D	0x8691	# <CJK>
0x5A4E	0x8696	# <CJK>
0x5A4F	0x8698	# <CJK>
0x5A50	0x869A	# <CJK>
0x5A51	0x869C	# <CJK>
0x5A52	0x86A1	# <CJK>
0x5A53	0x86A6	# <CJK>
0x5A54	0x86A7	# <CJK>
0x5A55	0x86A8	# <CJK>
0x5A56	0x86AD	# <CJK>
0x5A57	0x86B1	# <CJK>
0x5A58	0x86B3	# <CJK>
0x5A59	0x86B4	# <CJK>
0x5A5A	0x86B5	# <CJK>
0x5A5B	0x86B7	# <CJK>
0x5A5C	0x86B8	# <CJK>
0x5A5D	0x86B9	# <CJK>
0x5A5E	0x86BF	# <CJK>
0x5A5F	0x86C0	# <CJK>
0x5A60	0x86C1	# <CJK>
0x5A61	0x86C3	# <CJK>
0x5A62	0x86C5	# <CJK>
0x5A63	0x86D1	# <CJK>
0x5A64	0x86D2	# <CJK>
0x5A65	0x86D5	# <CJK>
0x5A66	0x86D7	# <CJK>
0x5A67	0x86DA	# <CJK>
0x5A68	0x86DC	# <CJK>
0x5A69	0x86E0	# <CJK>
0x5A6A	0x86E3	# <CJK>
0x5A6B	0x86E5	# <CJK>
0x5A6C	0x86E7	# <CJK>
0x5A6D	0x8688	# <CJK>
0x5A6E	0x86FA	# <CJK>
0x5A6F	0x86FC	# <CJK>
0x5A70	0x86FD	# <CJK>
0x5A71	0x8704	# <CJK>
0x5A72	0x8705	# <CJK>
0x5A73	0x8707	# <CJK>
0x5A74	0x870B	# <CJK>
0x5A75	0x870E	# <CJK>
0x5A76	0x870F	# <CJK>
0x5A77	0x8710	# <CJK>
0x5A78	0x8713	# <CJK>
0x5A79	0x8714	# <CJK>
0x5A7A	0x8719	# <CJK>
0x5A7B	0x871E	# <CJK>
0x5A7C	0x871F	# <CJK>
0x5A7D	0x8721	# <CJK>
0x5A7E	0x8723	# <CJK>
0x5B21	0x8728	# <CJK>
0x5B22	0x872E	# <CJK>
0x5B23	0x872F	# <CJK>
0x5B24	0x8731	# <CJK>
0x5B25	0x8732	# <CJK>
0x5B26	0x8739	# <CJK>
0x5B27	0x873A	# <CJK>
0x5B28	0x873C	# <CJK>
0x5B29	0x873D	# <CJK>
0x5B2A	0x873E	# <CJK>
0x5B2B	0x8740	# <CJK>
0x5B2C	0x8743	# <CJK>
0x5B2D	0x8745	# <CJK>
0x5B2E	0x874D	# <CJK>
0x5B2F	0x8758	# <CJK>
0x5B30	0x875D	# <CJK>
0x5B31	0x8761	# <CJK>
0x5B32	0x8764	# <CJK>
0x5B33	0x8765	# <CJK>
0x5B34	0x876F	# <CJK>
0x5B35	0x8771	# <CJK>
0x5B36	0x8772	# <CJK>
0x5B37	0x877B	# <CJK>
0x5B38	0x8783	# <CJK>
0x5B39	0x8784	# <CJK>
0x5B3A	0x8785	# <CJK>
0x5B3B	0x8786	# <CJK>
0x5B3C	0x8787	# <CJK>
0x5B3D	0x8788	# <CJK>
0x5B3E	0x8789	# <CJK>
0x5B3F	0x878B	# <CJK>
0x5B40	0x878C	# <CJK>
0x5B41	0x8790	# <CJK>
0x5B42	0x8793	# <CJK>
0x5B43	0x8795	# <CJK>
0x5B44	0x8797	# <CJK>
0x5B45	0x8798	# <CJK>
0x5B46	0x8799	# <CJK>
0x5B47	0x879E	# <CJK>
0x5B48	0x87A0	# <CJK>
0x5B49	0x87A3	# <CJK>
0x5B4A	0x87A7	# <CJK>
0x5B4B	0x87AC	# <CJK>
0x5B4C	0x87AD	# <CJK>
0x5B4D	0x87AE	# <CJK>
0x5B4E	0x87B1	# <CJK>
0x5B4F	0x87B5	# <CJK>
0x5B50	0x87BE	# <CJK>
0x5B51	0x87BF	# <CJK>
0x5B52	0x87C1	# <CJK>
0x5B53	0x87C8	# <CJK>
0x5B54	0x87C9	# <CJK>
0x5B55	0x87CA	# <CJK>
0x5B56	0x87CE	# <CJK>
0x5B57	0x87D5	# <CJK>
0x5B58	0x87D6	# <CJK>
0x5B59	0x87D9	# <CJK>
0x5B5A	0x87DA	# <CJK>
0x5B5B	0x87DC	# <CJK>
0x5B5C	0x87DF	# <CJK>
0x5B5D	0x87E2	# <CJK>
0x5B5E	0x87E3	# <CJK>
0x5B5F	0x87E4	# <CJK>
0x5B60	0x87EA	# <CJK>
0x5B61	0x87EB	# <CJK>
0x5B62	0x87ED	# <CJK>
0x5B63	0x87F1	# <CJK>
0x5B64	0x87F3	# <CJK>
0x5B65	0x87F8	# <CJK>
0x5B66	0x87FA	# <CJK>
0x5B67	0x87FF	# <CJK>
0x5B68	0x8801	# <CJK>
0x5B69	0x8803	# <CJK>
0x5B6A	0x8806	# <CJK>
0x5B6B	0x8809	# <CJK>
0x5B6C	0x880A	# <CJK>
0x5B6D	0x880B	# <CJK>
0x5B6E	0x8810	# <CJK>
0x5B6F	0x8819	# <CJK>
0x5B70	0x8812	# <CJK>
0x5B71	0x8813	# <CJK>
0x5B72	0x8814	# <CJK>
0x5B73	0x8818	# <CJK>
0x5B74	0x881A	# <CJK>
0x5B75	0x881B	# <CJK>
0x5B76	0x881C	# <CJK>
0x5B77	0x881E	# <CJK>
0x5B78	0x881F	# <CJK>
0x5B79	0x8828	# <CJK>
0x5B7A	0x882D	# <CJK>
0x5B7B	0x882E	# <CJK>
0x5B7C	0x8830	# <CJK>
0x5B7D	0x8832	# <CJK>
0x5B7E	0x8835	# <CJK>
0x5C21	0x883A	# <CJK>
0x5C22	0x883C	# <CJK>
0x5C23	0x8841	# <CJK>
0x5C24	0x8843	# <CJK>
0x5C25	0x8845	# <CJK>
0x5C26	0x8848	# <CJK>
0x5C27	0x8849	# <CJK>
0x5C28	0x884A	# <CJK>
0x5C29	0x884B	# <CJK>
0x5C2A	0x884E	# <CJK>
0x5C2B	0x8851	# <CJK>
0x5C2C	0x8855	# <CJK>
0x5C2D	0x8856	# <CJK>
0x5C2E	0x8858	# <CJK>
0x5C2F	0x885A	# <CJK>
0x5C30	0x885C	# <CJK>
0x5C31	0x885F	# <CJK>
0x5C32	0x8860	# <CJK>
0x5C33	0x8864	# <CJK>
0x5C34	0x8869	# <CJK>
0x5C35	0x8871	# <CJK>
0x5C36	0x8879	# <CJK>
0x5C37	0x887B	# <CJK>
0x5C38	0x8880	# <CJK>
0x5C39	0x8898	# <CJK>
0x5C3A	0x889A	# <CJK>
0x5C3B	0x889B	# <CJK>
0x5C3C	0x889C	# <CJK>
0x5C3D	0x889F	# <CJK>
0x5C3E	0x88A0	# <CJK>
0x5C3F	0x88A8	# <CJK>
0x5C40	0x88AA	# <CJK>
0x5C41	0x88BA	# <CJK>
0x5C42	0x88BD	# <CJK>
0x5C43	0x88BE	# <CJK>
0x5C44	0x88C0	# <CJK>
0x5C45	0x88CA	# <CJK>
0x5C46	0x88CB	# <CJK>
0x5C47	0x88CC	# <CJK>
0x5C48	0x88CD	# <CJK>
0x5C49	0x88CE	# <CJK>
0x5C4A	0x88D1	# <CJK>
0x5C4B	0x88D2	# <CJK>
0x5C4C	0x88D3	# <CJK>
0x5C4D	0x88DB	# <CJK>
0x5C4E	0x88DE	# <CJK>
0x5C4F	0x88E7	# <CJK>
0x5C50	0x88EF	# <CJK>
0x5C51	0x88F0	# <CJK>
0x5C52	0x88F1	# <CJK>
0x5C53	0x88F5	# <CJK>
0x5C54	0x88F7	# <CJK>
0x5C55	0x8901	# <CJK>
0x5C56	0x8906	# <CJK>
0x5C57	0x890D	# <CJK>
0x5C58	0x890E	# <CJK>
0x5C59	0x890F	# <CJK>
0x5C5A	0x8915	# <CJK>
0x5C5B	0x8916	# <CJK>
0x5C5C	0x8918	# <CJK>
0x5C5D	0x8919	# <CJK>
0x5C5E	0x891A	# <CJK>
0x5C5F	0x891C	# <CJK>
0x5C60	0x8920	# <CJK>
0x5C61	0x8926	# <CJK>
0x5C62	0x8927	# <CJK>
0x5C63	0x8928	# <CJK>
0x5C64	0x8930	# <CJK>
0x5C65	0x8931	# <CJK>
0x5C66	0x8932	# <CJK>
0x5C67	0x8935	# <CJK>
0x5C68	0x8939	# <CJK>
0x5C69	0x893A	# <CJK>
0x5C6A	0x893E	# <CJK>
0x5C6B	0x8940	# <CJK>
0x5C6C	0x8942	# <CJK>
0x5C6D	0x8945	# <CJK>
0x5C6E	0x8946	# <CJK>
0x5C6F	0x8949	# <CJK>
0x5C70	0x894F	# <CJK>
0x5C71	0x8952	# <CJK>
0x5C72	0x8957	# <CJK>
0x5C73	0x895A	# <CJK>
0x5C74	0x895B	# <CJK>
0x5C75	0x895C	# <CJK>
0x5C76	0x8961	# <CJK>
0x5C77	0x8962	# <CJK>
0x5C78	0x8963	# <CJK>
0x5C79	0x896B	# <CJK>
0x5C7A	0x896E	# <CJK>
0x5C7B	0x8970	# <CJK>
0x5C7C	0x8973	# <CJK>
0x5C7D	0x8975	# <CJK>
0x5C7E	0x897A	# <CJK>
0x5D21	0x897B	# <CJK>
0x5D22	0x897C	# <CJK>
0x5D23	0x897D	# <CJK>
0x5D24	0x8989	# <CJK>
0x5D25	0x898D	# <CJK>
0x5D26	0x8990	# <CJK>
0x5D27	0x8994	# <CJK>
0x5D28	0x8995	# <CJK>
0x5D29	0x899B	# <CJK>
0x5D2A	0x899C	# <CJK>
0x5D2B	0x899F	# <CJK>
0x5D2C	0x89A0	# <CJK>
0x5D2D	0x89A5	# <CJK>
0x5D2E	0x89B0	# <CJK>
0x5D2F	0x89B4	# <CJK>
0x5D30	0x89B5	# <CJK>
0x5D31	0x89B6	# <CJK>
0x5D32	0x89B7	# <CJK>
0x5D33	0x89BC	# <CJK>
0x5D34	0x89D4	# <CJK>
0x5D35	0x89D5	# <CJK>
0x5D36	0x89D6	# <CJK>
0x5D37	0x89D7	# <CJK>
0x5D38	0x89D8	# <CJK>
0x5D39	0x89E5	# <CJK>
0x5D3A	0x89E9	# <CJK>
0x5D3B	0x89EB	# <CJK>
0x5D3C	0x89ED	# <CJK>
0x5D3D	0x89F1	# <CJK>
0x5D3E	0x89F3	# <CJK>
0x5D3F	0x89F6	# <CJK>
0x5D40	0x89F9	# <CJK>
0x5D41	0x89FD	# <CJK>
0x5D42	0x89FF	# <CJK>
0x5D43	0x8A04	# <CJK>
0x5D44	0x8A05	# <CJK>
0x5D45	0x8A07	# <CJK>
0x5D46	0x8A0F	# <CJK>
0x5D47	0x8A11	# <CJK>
0x5D48	0x8A12	# <CJK>
0x5D49	0x8A14	# <CJK>
0x5D4A	0x8A15	# <CJK>
0x5D4B	0x8A1E	# <CJK>
0x5D4C	0x8A20	# <CJK>
0x5D4D	0x8A22	# <CJK>
0x5D4E	0x8A24	# <CJK>
0x5D4F	0x8A26	# <CJK>
0x5D50	0x8A2B	# <CJK>
0x5D51	0x8A2C	# <CJK>
0x5D52	0x8A2F	# <CJK>
0x5D53	0x8A35	# <CJK>
0x5D54	0x8A37	# <CJK>
0x5D55	0x8A3D	# <CJK>
0x5D56	0x8A3E	# <CJK>
0x5D57	0x8A40	# <CJK>
0x5D58	0x8A43	# <CJK>
0x5D59	0x8A45	# <CJK>
0x5D5A	0x8A47	# <CJK>
0x5D5B	0x8A49	# <CJK>
0x5D5C	0x8A4D	# <CJK>
0x5D5D	0x8A4E	# <CJK>
0x5D5E	0x8A53	# <CJK>
0x5D5F	0x8A56	# <CJK>
0x5D60	0x8A57	# <CJK>
0x5D61	0x8A58	# <CJK>
0x5D62	0x8A5C	# <CJK>
0x5D63	0x8A5D	# <CJK>
0x5D64	0x8A61	# <CJK>
0x5D65	0x8A65	# <CJK>
0x5D66	0x8A67	# <CJK>
0x5D67	0x8A75	# <CJK>
0x5D68	0x8A76	# <CJK>
0x5D69	0x8A77	# <CJK>
0x5D6A	0x8A79	# <CJK>
0x5D6B	0x8A7A	# <CJK>
0x5D6C	0x8A7B	# <CJK>
0x5D6D	0x8A7E	# <CJK>
0x5D6E	0x8A7F	# <CJK>
0x5D6F	0x8A80	# <CJK>
0x5D70	0x8A83	# <CJK>
0x5D71	0x8A86	# <CJK>
0x5D72	0x8A8B	# <CJK>
0x5D73	0x8A8F	# <CJK>
0x5D74	0x8A90	# <CJK>
0x5D75	0x8A92	# <CJK>
0x5D76	0x8A96	# <CJK>
0x5D77	0x8A97	# <CJK>
0x5D78	0x8A99	# <CJK>
0x5D79	0x8A9F	# <CJK>
0x5D7A	0x8AA7	# <CJK>
0x5D7B	0x8AA9	# <CJK>
0x5D7C	0x8AAE	# <CJK>
0x5D7D	0x8AAF	# <CJK>
0x5D7E	0x8AB3	# <CJK>
0x5E21	0x8AB6	# <CJK>
0x5E22	0x8AB7	# <CJK>
0x5E23	0x8ABB	# <CJK>
0x5E24	0x8ABE	# <CJK>
0x5E25	0x8AC3	# <CJK>
0x5E26	0x8AC6	# <CJK>
0x5E27	0x8AC8	# <CJK>
0x5E28	0x8AC9	# <CJK>
0x5E29	0x8ACA	# <CJK>
0x5E2A	0x8AD1	# <CJK>
0x5E2B	0x8AD3	# <CJK>
0x5E2C	0x8AD4	# <CJK>
0x5E2D	0x8AD5	# <CJK>
0x5E2E	0x8AD7	# <CJK>
0x5E2F	0x8ADD	# <CJK>
0x5E30	0x8ADF	# <CJK>
0x5E31	0x8AEC	# <CJK>
0x5E32	0x8AF0	# <CJK>
0x5E33	0x8AF4	# <CJK>
0x5E34	0x8AF5	# <CJK>
0x5E35	0x8AF6	# <CJK>
0x5E36	0x8AFC	# <CJK>
0x5E37	0x8AFF	# <CJK>
0x5E38	0x8B05	# <CJK>
0x5E39	0x8B06	# <CJK>
0x5E3A	0x8B0B	# <CJK>
0x5E3B	0x8B11	# <CJK>
0x5E3C	0x8B1C	# <CJK>
0x5E3D	0x8B1E	# <CJK>
0x5E3E	0x8B1F	# <CJK>
0x5E3F	0x8B0A	# <CJK>
0x5E40	0x8B2D	# <CJK>
0x5E41	0x8B30	# <CJK>
0x5E42	0x8B37	# <CJK>
0x5E43	0x8B3C	# <CJK>
0x5E44	0x8B42	# <CJK>
0x5E45	0x8B43	# <CJK>
0x5E46	0x8B44	# <CJK>
0x5E47	0x8B45	# <CJK>
0x5E48	0x8B46	# <CJK>
0x5E49	0x8B48	# <CJK>
0x5E4A	0x8B52	# <CJK>
0x5E4B	0x8B53	# <CJK>
0x5E4C	0x8B54	# <CJK>
0x5E4D	0x8B59	# <CJK>
0x5E4E	0x8B4D	# <CJK>
0x5E4F	0x8B5E	# <CJK>
0x5E50	0x8B63	# <CJK>
0x5E51	0x8B6D	# <CJK>
0x5E52	0x8B76	# <CJK>
0x5E53	0x8B78	# <CJK>
0x5E54	0x8B79	# <CJK>
0x5E55	0x8B7C	# <CJK>
0x5E56	0x8B7E	# <CJK>
0x5E57	0x8B81	# <CJK>
0x5E58	0x8B84	# <CJK>
0x5E59	0x8B85	# <CJK>
0x5E5A	0x8B8B	# <CJK>
0x5E5B	0x8B8D	# <CJK>
0x5E5C	0x8B8F	# <CJK>
0x5E5D	0x8B94	# <CJK>
0x5E5E	0x8B95	# <CJK>
0x5E5F	0x8B9C	# <CJK>
0x5E60	0x8B9E	# <CJK>
0x5E61	0x8B9F	# <CJK>
0x5E62	0x8C38	# <CJK>
0x5E63	0x8C39	# <CJK>
0x5E64	0x8C3D	# <CJK>
0x5E65	0x8C3E	# <CJK>
0x5E66	0x8C45	# <CJK>
0x5E67	0x8C47	# <CJK>
0x5E68	0x8C49	# <CJK>
0x5E69	0x8C4B	# <CJK>
0x5E6A	0x8C4F	# <CJK>
0x5E6B	0x8C51	# <CJK>
0x5E6C	0x8C53	# <CJK>
0x5E6D	0x8C54	# <CJK>
0x5E6E	0x8C57	# <CJK>
0x5E6F	0x8C58	# <CJK>
0x5E70	0x8C5B	# <CJK>
0x5E71	0x8C5D	# <CJK>
0x5E72	0x8C59	# <CJK>
0x5E73	0x8C63	# <CJK>
0x5E74	0x8C64	# <CJK>
0x5E75	0x8C66	# <CJK>
0x5E76	0x8C68	# <CJK>
0x5E77	0x8C69	# <CJK>
0x5E78	0x8C6D	# <CJK>
0x5E79	0x8C73	# <CJK>
0x5E7A	0x8C75	# <CJK>
0x5E7B	0x8C76	# <CJK>
0x5E7C	0x8C7B	# <CJK>
0x5E7D	0x8C7E	# <CJK>
0x5E7E	0x8C86	# <CJK>
0x5F21	0x8C87	# <CJK>
0x5F22	0x8C8B	# <CJK>
0x5F23	0x8C90	# <CJK>
0x5F24	0x8C92	# <CJK>
0x5F25	0x8C93	# <CJK>
0x5F26	0x8C99	# <CJK>
0x5F27	0x8C9B	# <CJK>
0x5F28	0x8C9C	# <CJK>
0x5F29	0x8CA4	# <CJK>
0x5F2A	0x8CB9	# <CJK>
0x5F2B	0x8CBA	# <CJK>
0x5F2C	0x8CC5	# <CJK>
0x5F2D	0x8CC6	# <CJK>
0x5F2E	0x8CC9	# <CJK>
0x5F2F	0x8CCB	# <CJK>
0x5F30	0x8CCF	# <CJK>
0x5F31	0x8CD6	# <CJK>
0x5F32	0x8CD5	# <CJK>
0x5F33	0x8CD9	# <CJK>
0x5F34	0x8CDD	# <CJK>
0x5F35	0x8CE1	# <CJK>
0x5F36	0x8CE8	# <CJK>
0x5F37	0x8CEC	# <CJK>
0x5F38	0x8CEF	# <CJK>
0x5F39	0x8CF0	# <CJK>
0x5F3A	0x8CF2	# <CJK>
0x5F3B	0x8CF5	# <CJK>
0x5F3C	0x8CF7	# <CJK>
0x5F3D	0x8CF8	# <CJK>
0x5F3E	0x8CFE	# <CJK>
0x5F3F	0x8CFF	# <CJK>
0x5F40	0x8D01	# <CJK>
0x5F41	0x8D03	# <CJK>
0x5F42	0x8D09	# <CJK>
0x5F43	0x8D12	# <CJK>
0x5F44	0x8D17	# <CJK>
0x5F45	0x8D1B	# <CJK>
0x5F46	0x8D65	# <CJK>
0x5F47	0x8D69	# <CJK>
0x5F48	0x8D6C	# <CJK>
0x5F49	0x8D6E	# <CJK>
0x5F4A	0x8D7F	# <CJK>
0x5F4B	0x8D82	# <CJK>
0x5F4C	0x8D84	# <CJK>
0x5F4D	0x8D88	# <CJK>
0x5F4E	0x8D8D	# <CJK>
0x5F4F	0x8D90	# <CJK>
0x5F50	0x8D91	# <CJK>
0x5F51	0x8D95	# <CJK>
0x5F52	0x8D9E	# <CJK>
0x5F53	0x8D9F	# <CJK>
0x5F54	0x8DA0	# <CJK>
0x5F55	0x8DA6	# <CJK>
0x5F56	0x8DAB	# <CJK>
0x5F57	0x8DAC	# <CJK>
0x5F58	0x8DAF	# <CJK>
0x5F59	0x8DB2	# <CJK>
0x5F5A	0x8DB5	# <CJK>
0x5F5B	0x8DB7	# <CJK>
0x5F5C	0x8DB9	# <CJK>
0x5F5D	0x8DBB	# <CJK>
0x5F5E	0x8DC0	# <CJK>
0x5F5F	0x8DC5	# <CJK>
0x5F60	0x8DC6	# <CJK>
0x5F61	0x8DC7	# <CJK>
0x5F62	0x8DC8	# <CJK>
0x5F63	0x8DCA	# <CJK>
0x5F64	0x8DCE	# <CJK>
0x5F65	0x8DD1	# <CJK>
0x5F66	0x8DD4	# <CJK>
0x5F67	0x8DD5	# <CJK>
0x5F68	0x8DD7	# <CJK>
0x5F69	0x8DD9	# <CJK>
0x5F6A	0x8DE4	# <CJK>
0x5F6B	0x8DE5	# <CJK>
0x5F6C	0x8DE7	# <CJK>
0x5F6D	0x8DEC	# <CJK>
0x5F6E	0x8DF0	# <CJK>
0x5F6F	0x8DBC	# <CJK>
0x5F70	0x8DF1	# <CJK>
0x5F71	0x8DF2	# <CJK>
0x5F72	0x8DF4	# <CJK>
0x5F73	0x8DFD	# <CJK>
0x5F74	0x8E01	# <CJK>
0x5F75	0x8E04	# <CJK>
0x5F76	0x8E05	# <CJK>
0x5F77	0x8E06	# <CJK>
0x5F78	0x8E0B	# <CJK>
0x5F79	0x8E11	# <CJK>
0x5F7A	0x8E14	# <CJK>
0x5F7B	0x8E16	# <CJK>
0x5F7C	0x8E20	# <CJK>
0x5F7D	0x8E21	# <CJK>
0x5F7E	0x8E22	# <CJK>
0x6021	0x8E23	# <CJK>
0x6022	0x8E26	# <CJK>
0x6023	0x8E27	# <CJK>
0x6024	0x8E31	# <CJK>
0x6025	0x8E33	# <CJK>
0x6026	0x8E36	# <CJK>
0x6027	0x8E37	# <CJK>
0x6028	0x8E38	# <CJK>
0x6029	0x8E39	# <CJK>
0x602A	0x8E3D	# <CJK>
0x602B	0x8E40	# <CJK>
0x602C	0x8E41	# <CJK>
0x602D	0x8E4B	# <CJK>
0x602E	0x8E4D	# <CJK>
0x602F	0x8E4E	# <CJK>
0x6030	0x8E4F	# <CJK>
0x6031	0x8E54	# <CJK>
0x6032	0x8E5B	# <CJK>
0x6033	0x8E5C	# <CJK>
0x6034	0x8E5D	# <CJK>
0x6035	0x8E5E	# <CJK>
0x6036	0x8E61	# <CJK>
0x6037	0x8E62	# <CJK>
0x6038	0x8E69	# <CJK>
0x6039	0x8E6C	# <CJK>
0x603A	0x8E6D	# <CJK>
0x603B	0x8E6F	# <CJK>
0x603C	0x8E70	# <CJK>
0x603D	0x8E71	# <CJK>
0x603E	0x8E79	# <CJK>
0x603F	0x8E7A	# <CJK>
0x6040	0x8E7B	# <CJK>
0x6041	0x8E82	# <CJK>
0x6042	0x8E83	# <CJK>
0x6043	0x8E89	# <CJK>
0x6044	0x8E90	# <CJK>
0x6045	0x8E92	# <CJK>
0x6046	0x8E95	# <CJK>
0x6047	0x8E9A	# <CJK>
0x6048	0x8E9B	# <CJK>
0x6049	0x8E9D	# <CJK>
0x604A	0x8E9E	# <CJK>
0x604B	0x8EA2	# <CJK>
0x604C	0x8EA7	# <CJK>
0x604D	0x8EA9	# <CJK>
0x604E	0x8EAD	# <CJK>
0x604F	0x8EAE	# <CJK>
0x6050	0x8EB3	# <CJK>
0x6051	0x8EB5	# <CJK>
0x6052	0x8EBA	# <CJK>
0x6053	0x8EBB	# <CJK>
0x6054	0x8EC0	# <CJK>
0x6055	0x8EC1	# <CJK>
0x6056	0x8EC3	# <CJK>
0x6057	0x8EC4	# <CJK>
0x6058	0x8EC7	# <CJK>
0x6059	0x8ECF	# <CJK>
0x605A	0x8ED1	# <CJK>
0x605B	0x8ED4	# <CJK>
0x605C	0x8EDC	# <CJK>
0x605D	0x8EE8	# <CJK>
0x605E	0x8EEE	# <CJK>
0x605F	0x8EF0	# <CJK>
0x6060	0x8EF1	# <CJK>
0x6061	0x8EF7	# <CJK>
0x6062	0x8EF9	# <CJK>
0x6063	0x8EFA	# <CJK>
0x6064	0x8EED	# <CJK>
0x6065	0x8F00	# <CJK>
0x6066	0x8F02	# <CJK>
0x6067	0x8F07	# <CJK>
0x6068	0x8F08	# <CJK>
0x6069	0x8F0F	# <CJK>
0x606A	0x8F10	# <CJK>
0x606B	0x8F16	# <CJK>
0x606C	0x8F17	# <CJK>
0x606D	0x8F18	# <CJK>
0x606E	0x8F1E	# <CJK>
0x606F	0x8F20	# <CJK>
0x6070	0x8F21	# <CJK>
0x6071	0x8F23	# <CJK>
0x6072	0x8F25	# <CJK>
0x6073	0x8F27	# <CJK>
0x6074	0x8F28	# <CJK>
0x6075	0x8F2C	# <CJK>
0x6076	0x8F2D	# <CJK>
0x6077	0x8F2E	# <CJK>
0x6078	0x8F34	# <CJK>
0x6079	0x8F35	# <CJK>
0x607A	0x8F36	# <CJK>
0x607B	0x8F37	# <CJK>
0x607C	0x8F3A	# <CJK>
0x607D	0x8F40	# <CJK>
0x607E	0x8F41	# <CJK>
0x6121	0x8F43	# <CJK>
0x6122	0x8F47	# <CJK>
0x6123	0x8F4F	# <CJK>
0x6124	0x8F51	# <CJK>
0x6125	0x8F52	# <CJK>
0x6126	0x8F53	# <CJK>
0x6127	0x8F54	# <CJK>
0x6128	0x8F55	# <CJK>
0x6129	0x8F58	# <CJK>
0x612A	0x8F5D	# <CJK>
0x612B	0x8F5E	# <CJK>
0x612C	0x8F65	# <CJK>
0x612D	0x8F9D	# <CJK>
0x612E	0x8FA0	# <CJK>
0x612F	0x8FA1	# <CJK>
0x6130	0x8FA4	# <CJK>
0x6131	0x8FA5	# <CJK>
0x6132	0x8FA6	# <CJK>
0x6133	0x8FB5	# <CJK>
0x6134	0x8FB6	# <CJK>
0x6135	0x8FB8	# <CJK>
0x6136	0x8FBE	# <CJK>
0x6137	0x8FC0	# <CJK>
0x6138	0x8FC1	# <CJK>
0x6139	0x8FC6	# <CJK>
0x613A	0x8FCA	# <CJK>
0x613B	0x8FCB	# <CJK>
0x613C	0x8FCD	# <CJK>
0x613D	0x8FD0	# <CJK>
0x613E	0x8FD2	# <CJK>
0x613F	0x8FD3	# <CJK>
0x6140	0x8FD5	# <CJK>
0x6141	0x8FE0	# <CJK>
0x6142	0x8FE3	# <CJK>
0x6143	0x8FE4	# <CJK>
0x6144	0x8FE8	# <CJK>
0x6145	0x8FEE	# <CJK>
0x6146	0x8FF1	# <CJK>
0x6147	0x8FF5	# <CJK>
0x6148	0x8FF6	# <CJK>
0x6149	0x8FFB	# <CJK>
0x614A	0x8FFE	# <CJK>
0x614B	0x9002	# <CJK>
0x614C	0x9004	# <CJK>
0x614D	0x9008	# <CJK>
0x614E	0x900C	# <CJK>
0x614F	0x9018	# <CJK>
0x6150	0x901B	# <CJK>
0x6151	0x9028	# <CJK>
0x6152	0x9029	# <CJK>
0x6153	0x902F	# <CJK>
0x6154	0x902A	# <CJK>
0x6155	0x902C	# <CJK>
0x6156	0x902D	# <CJK>
0x6157	0x9033	# <CJK>
0x6158	0x9034	# <CJK>
0x6159	0x9037	# <CJK>
0x615A	0x903F	# <CJK>
0x615B	0x9043	# <CJK>
0x615C	0x9044	# <CJK>
0x615D	0x904C	# <CJK>
0x615E	0x905B	# <CJK>
0x615F	0x905D	# <CJK>
0x6160	0x9062	# <CJK>
0x6161	0x9066	# <CJK>
0x6162	0x9067	# <CJK>
0x6163	0x906C	# <CJK>
0x6164	0x9070	# <CJK>
0x6165	0x9074	# <CJK>
0x6166	0x9079	# <CJK>
0x6167	0x9085	# <CJK>
0x6168	0x9088	# <CJK>
0x6169	0x908B	# <CJK>
0x616A	0x908C	# <CJK>
0x616B	0x908E	# <CJK>
0x616C	0x9090	# <CJK>
0x616D	0x9095	# <CJK>
0x616E	0x9097	# <CJK>
0x616F	0x9098	# <CJK>
0x6170	0x9099	# <CJK>
0x6171	0x909B	# <CJK>
0x6172	0x90A0	# <CJK>
0x6173	0x90A1	# <CJK>
0x6174	0x90A2	# <CJK>
0x6175	0x90A5	# <CJK>
0x6176	0x90B0	# <CJK>
0x6177	0x90B2	# <CJK>
0x6178	0x90B3	# <CJK>
0x6179	0x90B4	# <CJK>
0x617A	0x90B6	# <CJK>
0x617B	0x90BD	# <CJK>
0x617C	0x90CC	# <CJK>
0x617D	0x90BE	# <CJK>
0x617E	0x90C3	# <CJK>
0x6221	0x90C4	# <CJK>
0x6222	0x90C5	# <CJK>
0x6223	0x90C7	# <CJK>
0x6224	0x90C8	# <CJK>
0x6225	0x90D5	# <CJK>
0x6226	0x90D7	# <CJK>
0x6227	0x90D8	# <CJK>
0x6228	0x90D9	# <CJK>
0x6229	0x90DC	# <CJK>
0x622A	0x90DD	# <CJK>
0x622B	0x90DF	# <CJK>
0x622C	0x90E5	# <CJK>
0x622D	0x90D2	# <CJK>
0x622E	0x90F6	# <CJK>
0x622F	0x90EB	# <CJK>
0x6230	0x90EF	# <CJK>
0x6231	0x90F0	# <CJK>
0x6232	0x90F4	# <CJK>
0x6233	0x90FE	# <CJK>
0x6234	0x90FF	# <CJK>
0x6235	0x9100	# <CJK>
0x6236	0x9104	# <CJK>
0x6237	0x9105	# <CJK>
0x6238	0x9106	# <CJK>
0x6239	0x9108	# <CJK>
0x623A	0x910D	# <CJK>
0x623B	0x9110	# <CJK>
0x623C	0x9114	# <CJK>
0x623D	0x9116	# <CJK>
0x623E	0x9117	# <CJK>
0x623F	0x9118	# <CJK>
0x6240	0x911A	# <CJK>
0x6241	0x911C	# <CJK>
0x6242	0x911E	# <CJK>
0x6243	0x9120	# <CJK>
0x6244	0x9125	# <CJK>
0x6245	0x9122	# <CJK>
0x6246	0x9123	# <CJK>
0x6247	0x9127	# <CJK>
0x6248	0x9129	# <CJK>
0x6249	0x912E	# <CJK>
0x624A	0x912F	# <CJK>
0x624B	0x9131	# <CJK>
0x624C	0x9134	# <CJK>
0x624D	0x9136	# <CJK>
0x624E	0x9137	# <CJK>
0x624F	0x9139	# <CJK>
0x6250	0x913A	# <CJK>
0x6251	0x913C	# <CJK>
0x6252	0x913D	# <CJK>
0x6253	0x9143	# <CJK>
0x6254	0x9147	# <CJK>
0x6255	0x9148	# <CJK>
0x6256	0x914F	# <CJK>
0x6257	0x9153	# <CJK>
0x6258	0x9157	# <CJK>
0x6259	0x9159	# <CJK>
0x625A	0x915A	# <CJK>
0x625B	0x915B	# <CJK>
0x625C	0x9161	# <CJK>
0x625D	0x9164	# <CJK>
0x625E	0x9167	# <CJK>
0x625F	0x916D	# <CJK>
0x6260	0x9174	# <CJK>
0x6261	0x9179	# <CJK>
0x6262	0x917A	# <CJK>
0x6263	0x917B	# <CJK>
0x6264	0x9181	# <CJK>
0x6265	0x9183	# <CJK>
0x6266	0x9185	# <CJK>
0x6267	0x9186	# <CJK>
0x6268	0x918A	# <CJK>
0x6269	0x918E	# <CJK>
0x626A	0x9191	# <CJK>
0x626B	0x9193	# <CJK>
0x626C	0x9194	# <CJK>
0x626D	0x9195	# <CJK>
0x626E	0x9198	# <CJK>
0x626F	0x919E	# <CJK>
0x6270	0x91A1	# <CJK>
0x6271	0x91A6	# <CJK>
0x6272	0x91A8	# <CJK>
0x6273	0x91AC	# <CJK>
0x6274	0x91AD	# <CJK>
0x6275	0x91AE	# <CJK>
0x6276	0x91B0	# <CJK>
0x6277	0x91B1	# <CJK>
0x6278	0x91B2	# <CJK>
0x6279	0x91B3	# <CJK>
0x627A	0x91B6	# <CJK>
0x627B	0x91BB	# <CJK>
0x627C	0x91BC	# <CJK>
0x627D	0x91BD	# <CJK>
0x627E	0x91BF	# <CJK>
0x6321	0x91C2	# <CJK>
0x6322	0x91C3	# <CJK>
0x6323	0x91C5	# <CJK>
0x6324	0x91D3	# <CJK>
0x6325	0x91D4	# <CJK>
0x6326	0x91D7	# <CJK>
0x6327	0x91D9	# <CJK>
0x6328	0x91DA	# <CJK>
0x6329	0x91DE	# <CJK>
0x632A	0x91E4	# <CJK>
0x632B	0x91E5	# <CJK>
0x632C	0x91E9	# <CJK>
0x632D	0x91EA	# <CJK>
0x632E	0x91EC	# <CJK>
0x632F	0x91ED	# <CJK>
0x6330	0x91EE	# <CJK>
0x6331	0x91EF	# <CJK>
0x6332	0x91F0	# <CJK>
0x6333	0x91F1	# <CJK>
0x6334	0x91F7	# <CJK>
0x6335	0x91F9	# <CJK>
0x6336	0x91FB	# <CJK>
0x6337	0x91FD	# <CJK>
0x6338	0x9200	# <CJK>
0x6339	0x9201	# <CJK>
0x633A	0x9204	# <CJK>
0x633B	0x9205	# <CJK>
0x633C	0x9206	# <CJK>
0x633D	0x9207	# <CJK>
0x633E	0x9209	# <CJK>
0x633F	0x920A	# <CJK>
0x6340	0x920C	# <CJK>
0x6341	0x9210	# <CJK>
0x6342	0x9212	# <CJK>
0x6343	0x9213	# <CJK>
0x6344	0x9216	# <CJK>
0x6345	0x9218	# <CJK>
0x6346	0x921C	# <CJK>
0x6347	0x921D	# <CJK>
0x6348	0x9223	# <CJK>
0x6349	0x9224	# <CJK>
0x634A	0x9225	# <CJK>
0x634B	0x9226	# <CJK>
0x634C	0x9228	# <CJK>
0x634D	0x922E	# <CJK>
0x634E	0x922F	# <CJK>
0x634F	0x9230	# <CJK>
0x6350	0x9233	# <CJK>
0x6351	0x9235	# <CJK>
0x6352	0x9236	# <CJK>
0x6353	0x9238	# <CJK>
0x6354	0x9239	# <CJK>
0x6355	0x923A	# <CJK>
0x6356	0x923C	# <CJK>
0x6357	0x923E	# <CJK>
0x6358	0x9240	# <CJK>
0x6359	0x9242	# <CJK>
0x635A	0x9243	# <CJK>
0x635B	0x9246	# <CJK>
0x635C	0x9247	# <CJK>
0x635D	0x924A	# <CJK>
0x635E	0x924D	# <CJK>
0x635F	0x924E	# <CJK>
0x6360	0x924F	# <CJK>
0x6361	0x9251	# <CJK>
0x6362	0x9258	# <CJK>
0x6363	0x9259	# <CJK>
0x6364	0x925C	# <CJK>
0x6365	0x925D	# <CJK>
0x6366	0x9260	# <CJK>
0x6367	0x9261	# <CJK>
0x6368	0x9265	# <CJK>
0x6369	0x9267	# <CJK>
0x636A	0x9268	# <CJK>
0x636B	0x9269	# <CJK>
0x636C	0x926E	# <CJK>
0x636D	0x926F	# <CJK>
0x636E	0x9270	# <CJK>
0x636F	0x9275	# <CJK>
0x6370	0x9276	# <CJK>
0x6371	0x9277	# <CJK>
0x6372	0x9278	# <CJK>
0x6373	0x9279	# <CJK>
0x6374	0x927B	# <CJK>
0x6375	0x927C	# <CJK>
0x6376	0x927D	# <CJK>
0x6377	0x927F	# <CJK>
0x6378	0x9288	# <CJK>
0x6379	0x9289	# <CJK>
0x637A	0x928A	# <CJK>
0x637B	0x928D	# <CJK>
0x637C	0x928E	# <CJK>
0x637D	0x9292	# <CJK>
0x637E	0x9297	# <CJK>
0x6421	0x9299	# <CJK>
0x6422	0x929F	# <CJK>
0x6423	0x92A0	# <CJK>
0x6424	0x92A4	# <CJK>
0x6425	0x92A5	# <CJK>
0x6426	0x92A7	# <CJK>
0x6427	0x92A8	# <CJK>
0x6428	0x92AB	# <CJK>
0x6429	0x92AF	# <CJK>
0x642A	0x92B2	# <CJK>
0x642B	0x92B6	# <CJK>
0x642C	0x92B8	# <CJK>
0x642D	0x92BA	# <CJK>
0x642E	0x92BB	# <CJK>
0x642F	0x92BC	# <CJK>
0x6430	0x92BD	# <CJK>
0x6431	0x92BF	# <CJK>
0x6432	0x92C0	# <CJK>
0x6433	0x92C1	# <CJK>
0x6434	0x92C2	# <CJK>
0x6435	0x92C3	# <CJK>
0x6436	0x92C5	# <CJK>
0x6437	0x92C6	# <CJK>
0x6438	0x92C7	# <CJK>
0x6439	0x92C8	# <CJK>
0x643A	0x92CB	# <CJK>
0x643B	0x92CC	# <CJK>
0x643C	0x92CD	# <CJK>
0x643D	0x92CE	# <CJK>
0x643E	0x92D0	# <CJK>
0x643F	0x92D3	# <CJK>
0x6440	0x92D5	# <CJK>
0x6441	0x92D7	# <CJK>
0x6442	0x92D8	# <CJK>
0x6443	0x92D9	# <CJK>
0x6444	0x92DC	# <CJK>
0x6445	0x92DD	# <CJK>
0x6446	0x92DF	# <CJK>
0x6447	0x92E0	# <CJK>
0x6448	0x92E1	# <CJK>
0x6449	0x92E3	# <CJK>
0x644A	0x92E5	# <CJK>
0x644B	0x92E7	# <CJK>
0x644C	0x92E8	# <CJK>
0x644D	0x92EC	# <CJK>
0x644E	0x92EE	# <CJK>
0x644F	0x92F0	# <CJK>
0x6450	0x92F9	# <CJK>
0x6451	0x92FB	# <CJK>
0x6452	0x92FF	# <CJK>
0x6453	0x9300	# <CJK>
0x6454	0x9302	# <CJK>
0x6455	0x9308	# <CJK>
0x6456	0x930D	# <CJK>
0x6457	0x9311	# <CJK>
0x6458	0x9314	# <CJK>
0x6459	0x9315	# <CJK>
0x645A	0x931C	# <CJK>
0x645B	0x931D	# <CJK>
0x645C	0x931E	# <CJK>
0x645D	0x931F	# <CJK>
0x645E	0x9321	# <CJK>
0x645F	0x9324	# <CJK>
0x6460	0x9325	# <CJK>
0x6461	0x9327	# <CJK>
0x6462	0x9329	# <CJK>
0x6463	0x932A	# <CJK>
0x6464	0x9333	# <CJK>
0x6465	0x9334	# <CJK>
0x6466	0x9336	# <CJK>
0x6467	0x9337	# <CJK>
0x6468	0x9347	# <CJK>
0x6469	0x9348	# <CJK>
0x646A	0x9349	# <CJK>
0x646B	0x9350	# <CJK>
0x646C	0x9351	# <CJK>
0x646D	0x9352	# <CJK>
0x646E	0x9355	# <CJK>
0x646F	0x9357	# <CJK>
0x6470	0x9358	# <CJK>
0x6471	0x935A	# <CJK>
0x6472	0x935E	# <CJK>
0x6473	0x9364	# <CJK>
0x6474	0x9365	# <CJK>
0x6475	0x9367	# <CJK>
0x6476	0x9369	# <CJK>
0x6477	0x936A	# <CJK>
0x6478	0x936D	# <CJK>
0x6479	0x936F	# <CJK>
0x647A	0x9370	# <CJK>
0x647B	0x9371	# <CJK>
0x647C	0x9373	# <CJK>
0x647D	0x9374	# <CJK>
0x647E	0x9376	# <CJK>
0x6521	0x937A	# <CJK>
0x6522	0x937D	# <CJK>
0x6523	0x937F	# <CJK>
0x6524	0x9380	# <CJK>
0x6525	0x9381	# <CJK>
0x6526	0x9382	# <CJK>
0x6527	0x9388	# <CJK>
0x6528	0x938A	# <CJK>
0x6529	0x938B	# <CJK>
0x652A	0x938D	# <CJK>
0x652B	0x938F	# <CJK>
0x652C	0x9392	# <CJK>
0x652D	0x9395	# <CJK>
0x652E	0x9398	# <CJK>
0x652F	0x939B	# <CJK>
0x6530	0x939E	# <CJK>
0x6531	0x93A1	# <CJK>
0x6532	0x93A3	# <CJK>
0x6533	0x93A4	# <CJK>
0x6534	0x93A6	# <CJK>
0x6535	0x93A8	# <CJK>
0x6536	0x93AB	# <CJK>
0x6537	0x93B4	# <CJK>
0x6538	0x93B5	# <CJK>
0x6539	0x93B6	# <CJK>
0x653A	0x93BA	# <CJK>
0x653B	0x93A9	# <CJK>
0x653C	0x93C1	# <CJK>
0x653D	0x93C4	# <CJK>
0x653E	0x93C5	# <CJK>
0x653F	0x93C6	# <CJK>
0x6540	0x93C7	# <CJK>
0x6541	0x93C9	# <CJK>
0x6542	0x93CA	# <CJK>
0x6543	0x93CB	# <CJK>
0x6544	0x93CC	# <CJK>
0x6545	0x93CD	# <CJK>
0x6546	0x93D3	# <CJK>
0x6547	0x93D9	# <CJK>
0x6548	0x93DC	# <CJK>
0x6549	0x93DE	# <CJK>
0x654A	0x93DF	# <CJK>
0x654B	0x93E2	# <CJK>
0x654C	0x93E6	# <CJK>
0x654D	0x93E7	# <CJK>
0x654E	0x93F9	# <CJK>
0x654F	0x93F7	# <CJK>
0x6550	0x93F8	# <CJK>
0x6551	0x93FA	# <CJK>
0x6552	0x93FB	# <CJK>
0x6553	0x93FD	# <CJK>
0x6554	0x9401	# <CJK>
0x6555	0x9402	# <CJK>
0x6556	0x9404	# <CJK>
0x6557	0x9408	# <CJK>
0x6558	0x9409	# <CJK>
0x6559	0x940D	# <CJK>
0x655A	0x940E	# <CJK>
0x655B	0x940F	# <CJK>
0x655C	0x9415	# <CJK>
0x655D	0x9416	# <CJK>
0x655E	0x9417	# <CJK>
0x655F	0x941F	# <CJK>
0x6560	0x942E	# <CJK>
0x6561	0x942F	# <CJK>
0x6562	0x9431	# <CJK>
0x6563	0x9432	# <CJK>
0x6564	0x9433	# <CJK>
0x6565	0x9434	# <CJK>
0x6566	0x943B	# <CJK>
0x6567	0x943F	# <CJK>
0x6568	0x943D	# <CJK>
0x6569	0x9443	# <CJK>
0x656A	0x9445	# <CJK>
0x656B	0x9448	# <CJK>
0x656C	0x944A	# <CJK>
0x656D	0x944C	# <CJK>
0x656E	0x9455	# <CJK>
0x656F	0x9459	# <CJK>
0x6570	0x945C	# <CJK>
0x6571	0x945F	# <CJK>
0x6572	0x9461	# <CJK>
0x6573	0x9463	# <CJK>
0x6574	0x9468	# <CJK>
0x6575	0x946B	# <CJK>
0x6576	0x946D	# <CJK>
0x6577	0x946E	# <CJK>
0x6578	0x946F	# <CJK>
0x6579	0x9471	# <CJK>
0x657A	0x9472	# <CJK>
0x657B	0x9484	# <CJK>
0x657C	0x9483	# <CJK>
0x657D	0x9578	# <CJK>
0x657E	0x9579	# <CJK>
0x6621	0x957E	# <CJK>
0x6622	0x9584	# <CJK>
0x6623	0x9588	# <CJK>
0x6624	0x958C	# <CJK>
0x6625	0x958D	# <CJK>
0x6626	0x958E	# <CJK>
0x6627	0x959D	# <CJK>
0x6628	0x959E	# <CJK>
0x6629	0x959F	# <CJK>
0x662A	0x95A1	# <CJK>
0x662B	0x95A6	# <CJK>
0x662C	0x95A9	# <CJK>
0x662D	0x95AB	# <CJK>
0x662E	0x95AC	# <CJK>
0x662F	0x95B4	# <CJK>
0x6630	0x95B6	# <CJK>
0x6631	0x95BA	# <CJK>
0x6632	0x95BD	# <CJK>
0x6633	0x95BF	# <CJK>
0x6634	0x95C6	# <CJK>
0x6635	0x95C8	# <CJK>
0x6636	0x95C9	# <CJK>
0x6637	0x95CB	# <CJK>
0x6638	0x95D0	# <CJK>
0x6639	0x95D1	# <CJK>
0x663A	0x95D2	# <CJK>
0x663B	0x95D3	# <CJK>
0x663C	0x95D9	# <CJK>
0x663D	0x95DA	# <CJK>
0x663E	0x95DD	# <CJK>
0x663F	0x95DE	# <CJK>
0x6640	0x95DF	# <CJK>
0x6641	0x95E0	# <CJK>
0x6642	0x95E4	# <CJK>
0x6643	0x95E6	# <CJK>
0x6644	0x961D	# <CJK>
0x6645	0x961E	# <CJK>
0x6646	0x9622	# <CJK>
0x6647	0x9624	# <CJK>
0x6648	0x9625	# <CJK>
0x6649	0x9626	# <CJK>
0x664A	0x962C	# <CJK>
0x664B	0x9631	# <CJK>
0x664C	0x9633	# <CJK>
0x664D	0x9637	# <CJK>
0x664E	0x9638	# <CJK>
0x664F	0x9639	# <CJK>
0x6650	0x963A	# <CJK>
0x6651	0x963C	# <CJK>
0x6652	0x963D	# <CJK>
0x6653	0x9641	# <CJK>
0x6654	0x9652	# <CJK>
0x6655	0x9654	# <CJK>
0x6656	0x9656	# <CJK>
0x6657	0x9657	# <CJK>
0x6658	0x9658	# <CJK>
0x6659	0x9661	# <CJK>
0x665A	0x966E	# <CJK>
0x665B	0x9674	# <CJK>
0x665C	0x967B	# <CJK>
0x665D	0x967C	# <CJK>
0x665E	0x967E	# <CJK>
0x665F	0x967F	# <CJK>
0x6660	0x9681	# <CJK>
0x6661	0x9682	# <CJK>
0x6662	0x9683	# <CJK>
0x6663	0x9684	# <CJK>
0x6664	0x9689	# <CJK>
0x6665	0x9691	# <CJK>
0x6666	0x9696	# <CJK>
0x6667	0x969A	# <CJK>
0x6668	0x969D	# <CJK>
0x6669	0x969F	# <CJK>
0x666A	0x96A4	# <CJK>
0x666B	0x96A5	# <CJK>
0x666C	0x96A6	# <CJK>
0x666D	0x96A9	# <CJK>
0x666E	0x96AE	# <CJK>
0x666F	0x96AF	# <CJK>
0x6670	0x96B3	# <CJK>
0x6671	0x96BA	# <CJK>
0x6672	0x96CA	# <CJK>
0x6673	0x96D2	# <CJK>
0x6674	0x5DB2	# <CJK>
0x6675	0x96D8	# <CJK>
0x6676	0x96DA	# <CJK>
0x6677	0x96DD	# <CJK>
0x6678	0x96DE	# <CJK>
0x6679	0x96DF	# <CJK>
0x667A	0x96E9	# <CJK>
0x667B	0x96EF	# <CJK>
0x667C	0x96F1	# <CJK>
0x667D	0x96FA	# <CJK>
0x667E	0x9702	# <CJK>
0x6721	0x9703	# <CJK>
0x6722	0x9705	# <CJK>
0x6723	0x9709	# <CJK>
0x6724	0x971A	# <CJK>
0x6725	0x971B	# <CJK>
0x6726	0x971D	# <CJK>
0x6727	0x9721	# <CJK>
0x6728	0x9722	# <CJK>
0x6729	0x9723	# <CJK>
0x672A	0x9728	# <CJK>
0x672B	0x9731	# <CJK>
0x672C	0x9733	# <CJK>
0x672D	0x9741	# <CJK>
0x672E	0x9743	# <CJK>
0x672F	0x974A	# <CJK>
0x6730	0x974E	# <CJK>
0x6731	0x974F	# <CJK>
0x6732	0x9755	# <CJK>
0x6733	0x9757	# <CJK>
0x6734	0x9758	# <CJK>
0x6735	0x975A	# <CJK>
0x6736	0x975B	# <CJK>
0x6737	0x9763	# <CJK>
0x6738	0x9767	# <CJK>
0x6739	0x976A	# <CJK>
0x673A	0x976E	# <CJK>
0x673B	0x9773	# <CJK>
0x673C	0x9776	# <CJK>
0x673D	0x9777	# <CJK>
0x673E	0x9778	# <CJK>
0x673F	0x977B	# <CJK>
0x6740	0x977D	# <CJK>
0x6741	0x977F	# <CJK>
0x6742	0x9780	# <CJK>
0x6743	0x9789	# <CJK>
0x6744	0x9795	# <CJK>
0x6745	0x9796	# <CJK>
0x6746	0x9797	# <CJK>
0x6747	0x9799	# <CJK>
0x6748	0x979A	# <CJK>
0x6749	0x979E	# <CJK>
0x674A	0x979F	# <CJK>
0x674B	0x97A2	# <CJK>
0x674C	0x97AC	# <CJK>
0x674D	0x97AE	# <CJK>
0x674E	0x97B1	# <CJK>
0x674F	0x97B2	# <CJK>
0x6750	0x97B5	# <CJK>
0x6751	0x97B6	# <CJK>
0x6752	0x97B8	# <CJK>
0x6753	0x97B9	# <CJK>
0x6754	0x97BA	# <CJK>
0x6755	0x97BC	# <CJK>
0x6756	0x97BE	# <CJK>
0x6757	0x97BF	# <CJK>
0x6758	0x97C1	# <CJK>
0x6759	0x97C4	# <CJK>
0x675A	0x97C5	# <CJK>
0x675B	0x97C7	# <CJK>
0x675C	0x97C9	# <CJK>
0x675D	0x97CA	# <CJK>
0x675E	0x97CC	# <CJK>
0x675F	0x97CD	# <CJK>
0x6760	0x97CE	# <CJK>
0x6761	0x97D0	# <CJK>
0x6762	0x97D1	# <CJK>
0x6763	0x97D4	# <CJK>
0x6764	0x97D7	# <CJK>
0x6765	0x97D8	# <CJK>
0x6766	0x97D9	# <CJK>
0x6767	0x97DD	# <CJK>
0x6768	0x97DE	# <CJK>
0x6769	0x97E0	# <CJK>
0x676A	0x97DB	# <CJK>
0x676B	0x97E1	# <CJK>
0x676C	0x97E4	# <CJK>
0x676D	0x97EF	# <CJK>
0x676E	0x97F1	# <CJK>
0x676F	0x97F4	# <CJK>
0x6770	0x97F7	# <CJK>
0x6771	0x97F8	# <CJK>
0x6772	0x97FA	# <CJK>
0x6773	0x9807	# <CJK>
0x6774	0x980A	# <CJK>
0x6775	0x9819	# <CJK>
0x6776	0x980D	# <CJK>
0x6777	0x980E	# <CJK>
0x6778	0x9814	# <CJK>
0x6779	0x9816	# <CJK>
0x677A	0x981C	# <CJK>
0x677B	0x981E	# <CJK>
0x677C	0x9820	# <CJK>
0x677D	0x9823	# <CJK>
0x677E	0x9826	# <CJK>
0x6821	0x982B	# <CJK>
0x6822	0x982E	# <CJK>
0x6823	0x982F	# <CJK>
0x6824	0x9830	# <CJK>
0x6825	0x9832	# <CJK>
0x6826	0x9833	# <CJK>
0x6827	0x9835	# <CJK>
0x6828	0x9825	# <CJK>
0x6829	0x983E	# <CJK>
0x682A	0x9844	# <CJK>
0x682B	0x9847	# <CJK>
0x682C	0x984A	# <CJK>
0x682D	0x9851	# <CJK>
0x682E	0x9852	# <CJK>
0x682F	0x9853	# <CJK>
0x6830	0x9856	# <CJK>
0x6831	0x9857	# <CJK>
0x6832	0x9859	# <CJK>
0x6833	0x985A	# <CJK>
0x6834	0x9862	# <CJK>
0x6835	0x9863	# <CJK>
0x6836	0x9865	# <CJK>
0x6837	0x9866	# <CJK>
0x6838	0x986A	# <CJK>
0x6839	0x986C	# <CJK>
0x683A	0x98AB	# <CJK>
0x683B	0x98AD	# <CJK>
0x683C	0x98AE	# <CJK>
0x683D	0x98B0	# <CJK>
0x683E	0x98B4	# <CJK>
0x683F	0x98B7	# <CJK>
0x6840	0x98B8	# <CJK>
0x6841	0x98BA	# <CJK>
0x6842	0x98BB	# <CJK>
0x6843	0x98BF	# <CJK>
0x6844	0x98C2	# <CJK>
0x6845	0x98C5	# <CJK>
0x6846	0x98C8	# <CJK>
0x6847	0x98CC	# <CJK>
0x6848	0x98E1	# <CJK>
0x6849	0x98E3	# <CJK>
0x684A	0x98E5	# <CJK>
0x684B	0x98E6	# <CJK>
0x684C	0x98E7	# <CJK>
0x684D	0x98EA	# <CJK>
0x684E	0x98F3	# <CJK>
0x684F	0x98F6	# <CJK>
0x6850	0x9902	# <CJK>
0x6851	0x9907	# <CJK>
0x6852	0x9908	# <CJK>
0x6853	0x9911	# <CJK>
0x6854	0x9915	# <CJK>
0x6855	0x9916	# <CJK>
0x6856	0x9917	# <CJK>
0x6857	0x991A	# <CJK>
0x6858	0x991B	# <CJK>
0x6859	0x991C	# <CJK>
0x685A	0x991F	# <CJK>
0x685B	0x9922	# <CJK>
0x685C	0x9926	# <CJK>
0x685D	0x9927	# <CJK>
0x685E	0x992B	# <CJK>
0x685F	0x9931	# <CJK>
0x6860	0x9932	# <CJK>
0x6861	0x9933	# <CJK>
0x6862	0x9934	# <CJK>
0x6863	0x9935	# <CJK>
0x6864	0x9939	# <CJK>
0x6865	0x993A	# <CJK>
0x6866	0x993B	# <CJK>
0x6867	0x993C	# <CJK>
0x6868	0x9940	# <CJK>
0x6869	0x9941	# <CJK>
0x686A	0x9946	# <CJK>
0x686B	0x9947	# <CJK>
0x686C	0x9948	# <CJK>
0x686D	0x994D	# <CJK>
0x686E	0x994E	# <CJK>
0x686F	0x9954	# <CJK>
0x6870	0x9958	# <CJK>
0x6871	0x9959	# <CJK>
0x6872	0x995B	# <CJK>
0x6873	0x995C	# <CJK>
0x6874	0x995E	# <CJK>
0x6875	0x995F	# <CJK>
0x6876	0x9960	# <CJK>
0x6877	0x999B	# <CJK>
0x6878	0x999D	# <CJK>
0x6879	0x999F	# <CJK>
0x687A	0x99A6	# <CJK>
0x687B	0x99B0	# <CJK>
0x687C	0x99B1	# <CJK>
0x687D	0x99B2	# <CJK>
0x687E	0x99B5	# <CJK>
0x6921	0x99B9	# <CJK>
0x6922	0x99BA	# <CJK>
0x6923	0x99BD	# <CJK>
0x6924	0x99BF	# <CJK>
0x6925	0x99C3	# <CJK>
0x6926	0x99C9	# <CJK>
0x6927	0x99D3	# <CJK>
0x6928	0x99D4	# <CJK>
0x6929	0x99D9	# <CJK>
0x692A	0x99DA	# <CJK>
0x692B	0x99DC	# <CJK>
0x692C	0x99DE	# <CJK>
0x692D	0x99E7	# <CJK>
0x692E	0x99EA	# <CJK>
0x692F	0x99EB	# <CJK>
0x6930	0x99EC	# <CJK>
0x6931	0x99F0	# <CJK>
0x6932	0x99F4	# <CJK>
0x6933	0x99F5	# <CJK>
0x6934	0x99F9	# <CJK>
0x6935	0x99FD	# <CJK>
0x6936	0x99FE	# <CJK>
0x6937	0x9A02	# <CJK>
0x6938	0x9A03	# <CJK>
0x6939	0x9A04	# <CJK>
0x693A	0x9A0B	# <CJK>
0x693B	0x9A0C	# <CJK>
0x693C	0x9A10	# <CJK>
0x693D	0x9A11	# <CJK>
0x693E	0x9A16	# <CJK>
0x693F	0x9A1E	# <CJK>
0x6940	0x9A20	# <CJK>
0x6941	0x9A22	# <CJK>
0x6942	0x9A23	# <CJK>
0x6943	0x9A24	# <CJK>
0x6944	0x9A27	# <CJK>
0x6945	0x9A2D	# <CJK>
0x6946	0x9A2E	# <CJK>
0x6947	0x9A33	# <CJK>
0x6948	0x9A35	# <CJK>
0x6949	0x9A36	# <CJK>
0x694A	0x9A38	# <CJK>
0x694B	0x9A47	# <CJK>
0x694C	0x9A41	# <CJK>
0x694D	0x9A44	# <CJK>
0x694E	0x9A4A	# <CJK>
0x694F	0x9A4B	# <CJK>
0x6950	0x9A4C	# <CJK>
0x6951	0x9A4E	# <CJK>
0x6952	0x9A51	# <CJK>
0x6953	0x9A54	# <CJK>
0x6954	0x9A56	# <CJK>
0x6955	0x9A5D	# <CJK>
0x6956	0x9AAA	# <CJK>
0x6957	0x9AAC	# <CJK>
0x6958	0x9AAE	# <CJK>
0x6959	0x9AAF	# <CJK>
0x695A	0x9AB2	# <CJK>
0x695B	0x9AB4	# <CJK>
0x695C	0x9AB5	# <CJK>
0x695D	0x9AB6	# <CJK>
0x695E	0x9AB9	# <CJK>
0x695F	0x9ABB	# <CJK>
0x6960	0x9ABE	# <CJK>
0x6961	0x9ABF	# <CJK>
0x6962	0x9AC1	# <CJK>
0x6963	0x9AC3	# <CJK>
0x6964	0x9AC6	# <CJK>
0x6965	0x9AC8	# <CJK>
0x6966	0x9ACE	# <CJK>
0x6967	0x9AD0	# <CJK>
0x6968	0x9AD2	# <CJK>
0x6969	0x9AD5	# <CJK>
0x696A	0x9AD6	# <CJK>
0x696B	0x9AD7	# <CJK>
0x696C	0x9ADB	# <CJK>
0x696D	0x9ADC	# <CJK>
0x696E	0x9AE0	# <CJK>
0x696F	0x9AE4	# <CJK>
0x6970	0x9AE5	# <CJK>
0x6971	0x9AE7	# <CJK>
0x6972	0x9AE9	# <CJK>
0x6973	0x9AEC	# <CJK>
0x6974	0x9AF2	# <CJK>
0x6975	0x9AF3	# <CJK>
0x6976	0x9AF5	# <CJK>
0x6977	0x9AF9	# <CJK>
0x6978	0x9AFA	# <CJK>
0x6979	0x9AFD	# <CJK>
0x697A	0x9AFF	# <CJK>
0x697B	0x9B00	# <CJK>
0x697C	0x9B01	# <CJK>
0x697D	0x9B02	# <CJK>
0x697E	0x9B03	# <CJK>
0x6A21	0x9B04	# <CJK>
0x6A22	0x9B05	# <CJK>
0x6A23	0x9B08	# <CJK>
0x6A24	0x9B09	# <CJK>
0x6A25	0x9B0B	# <CJK>
0x6A26	0x9B0C	# <CJK>
0x6A27	0x9B0D	# <CJK>
0x6A28	0x9B0E	# <CJK>
0x6A29	0x9B10	# <CJK>
0x6A2A	0x9B12	# <CJK>
0x6A2B	0x9B16	# <CJK>
0x6A2C	0x9B19	# <CJK>
0x6A2D	0x9B1B	# <CJK>
0x6A2E	0x9B1C	# <CJK>
0x6A2F	0x9B20	# <CJK>
0x6A30	0x9B26	# <CJK>
0x6A31	0x9B2B	# <CJK>
0x6A32	0x9B2D	# <CJK>
0x6A33	0x9B33	# <CJK>
0x6A34	0x9B34	# <CJK>
0x6A35	0x9B35	# <CJK>
0x6A36	0x9B37	# <CJK>
0x6A37	0x9B39	# <CJK>
0x6A38	0x9B3A	# <CJK>
0x6A39	0x9B3D	# <CJK>
0x6A3A	0x9B48	# <CJK>
0x6A3B	0x9B4B	# <CJK>
0x6A3C	0x9B4C	# <CJK>
0x6A3D	0x9B55	# <CJK>
0x6A3E	0x9B56	# <CJK>
0x6A3F	0x9B57	# <CJK>
0x6A40	0x9B5B	# <CJK>
0x6A41	0x9B5E	# <CJK>
0x6A42	0x9B61	# <CJK>
0x6A43	0x9B63	# <CJK>
0x6A44	0x9B65	# <CJK>
0x6A45	0x9B66	# <CJK>
0x6A46	0x9B68	# <CJK>
0x6A47	0x9B6A	# <CJK>
0x6A48	0x9B6B	# <CJK>
0x6A49	0x9B6C	# <CJK>
0x6A4A	0x9B6D	# <CJK>
0x6A4B	0x9B6E	# <CJK>
0x6A4C	0x9B73	# <CJK>
0x6A4D	0x9B75	# <CJK>
0x6A4E	0x9B77	# <CJK>
0x6A4F	0x9B78	# <CJK>
0x6A50	0x9B79	# <CJK>
0x6A51	0x9B7F	# <CJK>
0x6A52	0x9B80	# <CJK>
0x6A53	0x9B84	# <CJK>
0x6A54	0x9B85	# <CJK>
0x6A55	0x9B86	# <CJK>
0x6A56	0x9B87	# <CJK>
0x6A57	0x9B89	# <CJK>
0x6A58	0x9B8A	# <CJK>
0x6A59	0x9B8B	# <CJK>
0x6A5A	0x9B8D	# <CJK>
0x6A5B	0x9B8F	# <CJK>
0x6A5C	0x9B90	# <CJK>
0x6A5D	0x9B94	# <CJK>
0x6A5E	0x9B9A	# <CJK>
0x6A5F	0x9B9D	# <CJK>
0x6A60	0x9B9E	# <CJK>
0x6A61	0x9BA6	# <CJK>
0x6A62	0x9BA7	# <CJK>
0x6A63	0x9BA9	# <CJK>
0x6A64	0x9BAC	# <CJK>
0x6A65	0x9BB0	# <CJK>
0x6A66	0x9BB1	# <CJK>
0x6A67	0x9BB2	# <CJK>
0x6A68	0x9BB7	# <CJK>
0x6A69	0x9BB8	# <CJK>
0x6A6A	0x9BBB	# <CJK>
0x6A6B	0x9BBC	# <CJK>
0x6A6C	0x9BBE	# <CJK>
0x6A6D	0x9BBF	# <CJK>
0x6A6E	0x9BC1	# <CJK>
0x6A6F	0x9BC7	# <CJK>
0x6A70	0x9BC8	# <CJK>
0x6A71	0x9BCE	# <CJK>
0x6A72	0x9BD0	# <CJK>
0x6A73	0x9BD7	# <CJK>
0x6A74	0x9BD8	# <CJK>
0x6A75	0x9BDD	# <CJK>
0x6A76	0x9BDF	# <CJK>
0x6A77	0x9BE5	# <CJK>
0x6A78	0x9BE7	# <CJK>
0x6A79	0x9BEA	# <CJK>
0x6A7A	0x9BEB	# <CJK>
0x6A7B	0x9BEF	# <CJK>
0x6A7C	0x9BF3	# <CJK>
0x6A7D	0x9BF7	# <CJK>
0x6A7E	0x9BF8	# <CJK>
0x6B21	0x9BF9	# <CJK>
0x6B22	0x9BFA	# <CJK>
0x6B23	0x9BFD	# <CJK>
0x6B24	0x9BFF	# <CJK>
0x6B25	0x9C00	# <CJK>
0x6B26	0x9C02	# <CJK>
0x6B27	0x9C0B	# <CJK>
0x6B28	0x9C0F	# <CJK>
0x6B29	0x9C11	# <CJK>
0x6B2A	0x9C16	# <CJK>
0x6B2B	0x9C18	# <CJK>
0x6B2C	0x9C19	# <CJK>
0x6B2D	0x9C1A	# <CJK>
0x6B2E	0x9C1C	# <CJK>
0x6B2F	0x9C1E	# <CJK>
0x6B30	0x9C22	# <CJK>
0x6B31	0x9C23	# <CJK>
0x6B32	0x9C26	# <CJK>
0x6B33	0x9C27	# <CJK>
0x6B34	0x9C28	# <CJK>
0x6B35	0x9C29	# <CJK>
0x6B36	0x9C2A	# <CJK>
0x6B37	0x9C31	# <CJK>
0x6B38	0x9C35	# <CJK>
0x6B39	0x9C36	# <CJK>
0x6B3A	0x9C37	# <CJK>
0x6B3B	0x9C3D	# <CJK>
0x6B3C	0x9C41	# <CJK>
0x6B3D	0x9C43	# <CJK>
0x6B3E	0x9C44	# <CJK>
0x6B3F	0x9C45	# <CJK>
0x6B40	0x9C49	# <CJK>
0x6B41	0x9C4A	# <CJK>
0x6B42	0x9C4E	# <CJK>
0x6B43	0x9C4F	# <CJK>
0x6B44	0x9C50	# <CJK>
0x6B45	0x9C53	# <CJK>
0x6B46	0x9C54	# <CJK>
0x6B47	0x9C56	# <CJK>
0x6B48	0x9C58	# <CJK>
0x6B49	0x9C5B	# <CJK>
0x6B4A	0x9C5D	# <CJK>
0x6B4B	0x9C5E	# <CJK>
0x6B4C	0x9C5F	# <CJK>
0x6B4D	0x9C63	# <CJK>
0x6B4E	0x9C69	# <CJK>
0x6B4F	0x9C6A	# <CJK>
0x6B50	0x9C5C	# <CJK>
0x6B51	0x9C6B	# <CJK>
0x6B52	0x9C68	# <CJK>
0x6B53	0x9C6E	# <CJK>
0x6B54	0x9C70	# <CJK>
0x6B55	0x9C72	# <CJK>
0x6B56	0x9C75	# <CJK>
0x6B57	0x9C77	# <CJK>
0x6B58	0x9C7B	# <CJK>
0x6B59	0x9CE6	# <CJK>
0x6B5A	0x9CF2	# <CJK>
0x6B5B	0x9CF7	# <CJK>
0x6B5C	0x9CF9	# <CJK>
0x6B5D	0x9D0B	# <CJK>
0x6B5E	0x9D02	# <CJK>
0x6B5F	0x9D11	# <CJK>
0x6B60	0x9D17	# <CJK>
0x6B61	0x9D18	# <CJK>
0x6B62	0x9D1C	# <CJK>
0x6B63	0x9D1D	# <CJK>
0x6B64	0x9D1E	# <CJK>
0x6B65	0x9D2F	# <CJK>
0x6B66	0x9D30	# <CJK>
0x6B67	0x9D32	# <CJK>
0x6B68	0x9D33	# <CJK>
0x6B69	0x9D34	# <CJK>
0x6B6A	0x9D3A	# <CJK>
0x6B6B	0x9D3C	# <CJK>
0x6B6C	0x9D45	# <CJK>
0x6B6D	0x9D3D	# <CJK>
0x6B6E	0x9D42	# <CJK>
0x6B6F	0x9D43	# <CJK>
0x6B70	0x9D47	# <CJK>
0x6B71	0x9D4A	# <CJK>
0x6B72	0x9D53	# <CJK>
0x6B73	0x9D54	# <CJK>
0x6B74	0x9D5F	# <CJK>
0x6B75	0x9D63	# <CJK>
0x6B76	0x9D62	# <CJK>
0x6B77	0x9D65	# <CJK>
0x6B78	0x9D69	# <CJK>
0x6B79	0x9D6A	# <CJK>
0x6B7A	0x9D6B	# <CJK>
0x6B7B	0x9D70	# <CJK>
0x6B7C	0x9D76	# <CJK>
0x6B7D	0x9D77	# <CJK>
0x6B7E	0x9D7B	# <CJK>
0x6C21	0x9D7C	# <CJK>
0x6C22	0x9D7E	# <CJK>
0x6C23	0x9D83	# <CJK>
0x6C24	0x9D84	# <CJK>
0x6C25	0x9D86	# <CJK>
0x6C26	0x9D8A	# <CJK>
0x6C27	0x9D8D	# <CJK>
0x6C28	0x9D8E	# <CJK>
0x6C29	0x9D92	# <CJK>
0x6C2A	0x9D93	# <CJK>
0x6C2B	0x9D95	# <CJK>
0x6C2C	0x9D96	# <CJK>
0x6C2D	0x9D97	# <CJK>
0x6C2E	0x9D98	# <CJK>
0x6C2F	0x9DA1	# <CJK>
0x6C30	0x9DAA	# <CJK>
0x6C31	0x9DAC	# <CJK>
0x6C32	0x9DAE	# <CJK>
0x6C33	0x9DB1	# <CJK>
0x6C34	0x9DB5	# <CJK>
0x6C35	0x9DB9	# <CJK>
0x6C36	0x9DBC	# <CJK>
0x6C37	0x9DBF	# <CJK>
0x6C38	0x9DC3	# <CJK>
0x6C39	0x9DC7	# <CJK>
0x6C3A	0x9DC9	# <CJK>
0x6C3B	0x9DCA	# <CJK>
0x6C3C	0x9DD4	# <CJK>
0x6C3D	0x9DD5	# <CJK>
0x6C3E	0x9DD6	# <CJK>
0x6C3F	0x9DD7	# <CJK>
0x6C40	0x9DDA	# <CJK>
0x6C41	0x9DDE	# <CJK>
0x6C42	0x9DDF	# <CJK>
0x6C43	0x9DE0	# <CJK>
0x6C44	0x9DE5	# <CJK>
0x6C45	0x9DE7	# <CJK>
0x6C46	0x9DE9	# <CJK>
0x6C47	0x9DEB	# <CJK>
0x6C48	0x9DEE	# <CJK>
0x6C49	0x9DF0	# <CJK>
0x6C4A	0x9DF3	# <CJK>
0x6C4B	0x9DF4	# <CJK>
0x6C4C	0x9DFE	# <CJK>
0x6C4D	0x9E0A	# <CJK>
0x6C4E	0x9E02	# <CJK>
0x6C4F	0x9E07	# <CJK>
0x6C50	0x9E0E	# <CJK>
0x6C51	0x9E10	# <CJK>
0x6C52	0x9E11	# <CJK>
0x6C53	0x9E12	# <CJK>
0x6C54	0x9E15	# <CJK>
0x6C55	0x9E16	# <CJK>
0x6C56	0x9E19	# <CJK>
0x6C57	0x9E1C	# <CJK>
0x6C58	0x9E1D	# <CJK>
0x6C59	0x9E7A	# <CJK>
0x6C5A	0x9E7B	# <CJK>
0x6C5B	0x9E7C	# <CJK>
0x6C5C	0x9E80	# <CJK>
0x6C5D	0x9E82	# <CJK>
0x6C5E	0x9E83	# <CJK>
0x6C5F	0x9E84	# <CJK>
0x6C60	0x9E85	# <CJK>
0x6C61	0x9E87	# <CJK>
0x6C62	0x9E8E	# <CJK>
0x6C63	0x9E8F	# <CJK>
0x6C64	0x9E96	# <CJK>
0x6C65	0x9E98	# <CJK>
0x6C66	0x9E9B	# <CJK>
0x6C67	0x9E9E	# <CJK>
0x6C68	0x9EA4	# <CJK>
0x6C69	0x9EA8	# <CJK>
0x6C6A	0x9EAC	# <CJK>
0x6C6B	0x9EAE	# <CJK>
0x6C6C	0x9EAF	# <CJK>
0x6C6D	0x9EB0	# <CJK>
0x6C6E	0x9EB3	# <CJK>
0x6C6F	0x9EB4	# <CJK>
0x6C70	0x9EB5	# <CJK>
0x6C71	0x9EC6	# <CJK>
0x6C72	0x9EC8	# <CJK>
0x6C73	0x9ECB	# <CJK>
0x6C74	0x9ED5	# <CJK>
0x6C75	0x9EDF	# <CJK>
0x6C76	0x9EE4	# <CJK>
0x6C77	0x9EE7	# <CJK>
0x6C78	0x9EEC	# <CJK>
0x6C79	0x9EED	# <CJK>
0x6C7A	0x9EEE	# <CJK>
0x6C7B	0x9EF0	# <CJK>
0x6C7C	0x9EF1	# <CJK>
0x6C7D	0x9EF2	# <CJK>
0x6C7E	0x9EF5	# <CJK>
0x6D21	0x9EF8	# <CJK>
0x6D22	0x9EFF	# <CJK>
0x6D23	0x9F02	# <CJK>
0x6D24	0x9F03	# <CJK>
0x6D25	0x9F09	# <CJK>
0x6D26	0x9F0F	# <CJK>
0x6D27	0x9F10	# <CJK>
0x6D28	0x9F11	# <CJK>
0x6D29	0x9F12	# <CJK>
0x6D2A	0x9F14	# <CJK>
0x6D2B	0x9F16	# <CJK>
0x6D2C	0x9F17	# <CJK>
0x6D2D	0x9F19	# <CJK>
0x6D2E	0x9F1A	# <CJK>
0x6D2F	0x9F1B	# <CJK>
0x6D30	0x9F1F	# <CJK>
0x6D31	0x9F22	# <CJK>
0x6D32	0x9F26	# <CJK>
0x6D33	0x9F2A	# <CJK>
0x6D34	0x9F2B	# <CJK>
0x6D35	0x9F2F	# <CJK>
0x6D36	0x9F31	# <CJK>
0x6D37	0x9F32	# <CJK>
0x6D38	0x9F34	# <CJK>
0x6D39	0x9F37	# <CJK>
0x6D3A	0x9F39	# <CJK>
0x6D3B	0x9F3A	# <CJK>
0x6D3C	0x9F3C	# <CJK>
0x6D3D	0x9F3D	# <CJK>
0x6D3E	0x9F3F	# <CJK>
0x6D3F	0x9F41	# <CJK>
0x6D40	0x9F43	# <CJK>
0x6D41	0x9F44	# <CJK>
0x6D42	0x9F45	# <CJK>
0x6D43	0x9F46	# <CJK>
0x6D44	0x9F47	# <CJK>
0x6D45	0x9F53	# <CJK>
0x6D46	0x9F55	# <CJK>
0x6D47	0x9F56	# <CJK>
0x6D48	0x9F57	# <CJK>
0x6D49	0x9F58	# <CJK>
0x6D4A	0x9F5A	# <CJK>
0x6D4B	0x9F5D	# <CJK>
0x6D4C	0x9F5E	# <CJK>
0x6D4D	0x9F68	# <CJK>
0x6D4E	0x9F69	# <CJK>
0x6D4F	0x9F6D	# <CJK>
0x6D50	0x9F6E	# <CJK>
0x6D51	0x9F6F	# <CJK>
0x6D52	0x9F70	# <CJK>
0x6D53	0x9F71	# <CJK>
0x6D54	0x9F73	# <CJK>
0x6D55	0x9F75	# <CJK>
0x6D56	0x9F7A	# <CJK>
0x6D57	0x9F7D	# <CJK>
0x6D58	0x9F8F	# <CJK>
0x6D59	0x9F90	# <CJK>
0x6D5A	0x9F91	# <CJK>
0x6D5B	0x9F92	# <CJK>
0x6D5C	0x9F94	# <CJK>
0x6D5D	0x9F96	# <CJK>
0x6D5E	0x9F97	# <CJK>
0x6D5F	0x9F9E	# <CJK>
0x6D60	0x9FA1	# <CJK>
0x6D61	0x9FA2	# <CJK>
0x6D62	0x9FA3	# <CJK>
0x6D63	0x9FA5	# <CJK>

Added tools/encoding/ksc5601.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
# What is enclosed below is the mapping between KS C 5601-1987
# and Unicode 2.0.   It's automatically generated from KSC5601.TXT
# (at ftp://ftp.unicode.org/Public/MAPPING/EASTASIA/KSC) which is
# actually NOT the mapping between KS C 5601-1992 and Unicode 2.0
# BUT the mapping table between UHC(Microsoft Unified Hangul Code)
# and Unicode 2.0. Hence, in this pacakge, I renamed it as UHC.TXT
#
# The Unix command  used is 
# egrep '^0x' < KSC5601.TXT |   \
# egrep -v '^0x([8-9]...|A0..|..[4-9].|..A0)' | perl tab.pl
#
# where tab.pl  is as following
#----------tab.pl
#  $n=0;
#  while (<>) {
#    local($euck, $ucs4, @rest) = split;
#    local($u)=hex($ucs4);
#    local($k)=hex($euck);
#    printf ("0x%04X  0x%04X  %s\n",$k-0x8080, $u,join(' ',@rest));
#  }
#
# Column #1 : KS C 5601-1987(KS C 5601-1992 excluding addtional Hangul
#            syllables defined for Johab encoding in Annex 3)
#            in hex as 0xXXXX
# Column #2 : the Unicode (in hex as 0xXXXX)
# Column #3 : the Unicode name (following a comment sign, '#')
# The number of characters enumerated in this table is 8824, the
# as listed in KS C 5601-987
# 
# 
# The entries are in KS C 5601-1987 order
# You can use the following algorithms to convert the hex form
# of KS C 5601 to other forms
#   To get EUCKorea(EUC-KR) code points, add 0x8080.
#   To get row(Hang) and column(Yol) as used in KS C 5601-1987 manual,
#      first subtract 0x2020. Then
#      the high and low bytes correspond to the row(Hang) and the column(Yol),
#      respectively
0x2121  0x3000  # IDEOGRAPHIC SPACE
0x2122  0x3001  # IDEOGRAPHIC COMMA
0x2123  0x3002  # IDEOGRAPHIC FULL STOP
0x2124  0x00B7  # MIDDLE DOT
0x2125  0x2025  # TWO DOT LEADER
0x2126  0x2026  # HORIZONTAL ELLIPSIS
0x2127  0x00A8  # DIAERESIS
0x2128  0x3003  # DITTO MARK
0x2129  0x00AD  # SOFT HYPHEN
0x212A  0x2015  # HORIZONTAL BAR
0x212B  0x2225  # PARALLEL TO
0x212C  0xFF3C  # FULLWIDTH REVERSE SOLIDUS
0x212D  0x223C  # TILDE OPERATOR
0x212E  0x2018  # LEFT SINGLE QUOTATION MARK
0x212F  0x2019  # RIGHT SINGLE QUOTATION MARK
0x2130  0x201C  # LEFT DOUBLE QUOTATION MARK
0x2131  0x201D  # RIGHT DOUBLE QUOTATION MARK
0x2132  0x3014  # LEFT TORTOISE SHELL BRACKET
0x2133  0x3015  # RIGHT TORTOISE SHELL BRACKET
0x2134  0x3008  # LEFT ANGLE BRACKET
0x2135  0x3009  # RIGHT ANGLE BRACKET
0x2136  0x300A  # LEFT DOUBLE ANGLE BRACKET
0x2137  0x300B  # RIGHT DOUBLE ANGLE BRACKET
0x2138  0x300C  # LEFT CORNER BRACKET
0x2139  0x300D  # RIGHT CORNER BRACKET
0x213A  0x300E  # LEFT WHITE CORNER BRACKET
0x213B  0x300F  # RIGHT WHITE CORNER BRACKET
0x213C  0x3010  # LEFT BLACK LENTICULAR BRACKET
0x213D  0x3011  # RIGHT BLACK LENTICULAR BRACKET
0x213E  0x00B1  # PLUS-MINUS SIGN
0x213F  0x00D7  # MULTIPLICATION SIGN
0x2140  0x00F7  # DIVISION SIGN
0x2141  0x2260  # NOT EQUAL TO
0x2142  0x2264  # LESS-THAN OR EQUAL TO
0x2143  0x2265  # GREATER-THAN OR EQUAL TO
0x2144  0x221E  # INFINITY
0x2145  0x2234  # THEREFORE
0x2146  0x00B0  # DEGREE SIGN
0x2147  0x2032  # PRIME
0x2148  0x2033  # DOUBLE PRIME
0x2149  0x2103  # DEGREE CELSIUS
0x214A  0x212B  # ANGSTROM SIGN
0x214B  0xFFE0  # FULLWIDTH CENT SIGN
0x214C  0xFFE1  # FULLWIDTH POUND SIGN
0x214D  0xFFE5  # FULLWIDTH YEN SIGN
0x214E  0x2642  # MALE SIGN
0x214F  0x2640  # FEMALE SIGN
0x2150  0x2220  # ANGLE
0x2151  0x22A5  # UP TACK
0x2152  0x2312  # ARC
0x2153  0x2202  # PARTIAL DIFFERENTIAL
0x2154  0x2207  # NABLA
0x2155  0x2261  # IDENTICAL TO
0x2156  0x2252  # APPROXIMATELY EQUAL TO OR THE IMAGE OF
0x2157  0x00A7  # SECTION SIGN
0x2158  0x203B  # REFERENCE MARK
0x2159  0x2606  # WHITE STAR
0x215A  0x2605  # BLACK STAR
0x215B  0x25CB  # WHITE CIRCLE
0x215C  0x25CF  # BLACK CIRCLE
0x215D  0x25CE  # BULLSEYE
0x215E  0x25C7  # WHITE DIAMOND
0x215F  0x25C6  # BLACK DIAMOND
0x2160  0x25A1  # WHITE SQUARE
0x2161  0x25A0  # BLACK SQUARE
0x2162  0x25B3  # WHITE UP-POINTING TRIANGLE
0x2163  0x25B2  # BLACK UP-POINTING TRIANGLE
0x2164  0x25BD  # WHITE DOWN-POINTING TRIANGLE
0x2165  0x25BC  # BLACK DOWN-POINTING TRIANGLE
0x2166  0x2192  # RIGHTWARDS ARROW
0x2167  0x2190  # LEFTWARDS ARROW
0x2168  0x2191  # UPWARDS ARROW
0x2169  0x2193  # DOWNWARDS ARROW
0x216A  0x2194  # LEFT RIGHT ARROW
0x216B  0x3013  # GETA MARK
0x216C  0x226A  # MUCH LESS-THAN
0x216D  0x226B  # MUCH GREATER-THAN
0x216E  0x221A  # SQUARE ROOT
0x216F  0x223D  # REVERSED TILDE
0x2170  0x221D  # PROPORTIONAL TO
0x2171  0x2235  # BECAUSE
0x2172  0x222B  # INTEGRAL
0x2173  0x222C  # DOUBLE INTEGRAL
0x2174  0x2208  # ELEMENT OF
0x2175  0x220B  # CONTAINS AS MEMBER
0x2176  0x2286  # SUBSET OF OR EQUAL TO
0x2177  0x2287  # SUPERSET OF OR EQUAL TO
0x2178  0x2282  # SUBSET OF
0x2179  0x2283  # SUPERSET OF
0x217A  0x222A  # UNION
0x217B  0x2229  # INTERSECTION
0x217C  0x2227  # LOGICAL AND
0x217D  0x2228  # LOGICAL OR
0x217E  0xFFE2  # FULLWIDTH NOT SIGN
0x2221  0x21D2  # RIGHTWARDS DOUBLE ARROW
0x2222  0x21D4  # LEFT RIGHT DOUBLE ARROW
0x2223  0x2200  # FOR ALL
0x2224  0x2203  # THERE EXISTS
0x2225  0x00B4  # ACUTE ACCENT
0x2226  0xFF5E  # FULLWIDTH TILDE
0x2227  0x02C7  # CARON
0x2228  0x02D8  # BREVE
0x2229  0x02DD  # DOUBLE ACUTE ACCENT
0x222A  0x02DA  # RING ABOVE
0x222B  0x02D9  # DOT ABOVE
0x222C  0x00B8  # CEDILLA
0x222D  0x02DB  # OGONEK
0x222E  0x00A1  # INVERTED EXCLAMATION MARK
0x222F  0x00BF  # INVERTED QUESTION MARK
0x2230  0x02D0  # MODIFIER LETTER TRIANGULAR COLON
0x2231  0x222E  # CONTOUR INTEGRAL
0x2232  0x2211  # N-ARY SUMMATION
0x2233  0x220F  # N-ARY PRODUCT
0x2234  0x00A4  # CURRENCY SIGN
0x2235  0x2109  # DEGREE FAHRENHEIT
0x2236  0x2030  # PER MILLE SIGN
0x2237  0x25C1  # WHITE LEFT-POINTING TRIANGLE
0x2238  0x25C0  # BLACK LEFT-POINTING TRIANGLE
0x2239  0x25B7  # WHITE RIGHT-POINTING TRIANGLE
0x223A  0x25B6  # BLACK RIGHT-POINTING TRIANGLE
0x223B  0x2664  # WHITE SPADE SUIT
0x223C  0x2660  # BLACK SPADE SUIT
0x223D  0x2661  # WHITE HEART SUIT
0x223E  0x2665  # BLACK HEART SUIT
0x223F  0x2667  # WHITE CLUB SUIT
0x2240  0x2663  # BLACK CLUB SUIT
0x2241  0x2299  # CIRCLED DOT OPERATOR
0x2242  0x25C8  # WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND
0x2243  0x25A3  # WHITE SQUARE CONTAINING BLACK SMALL SQUARE
0x2244  0x25D0  # CIRCLE WITH LEFT HALF BLACK
0x2245  0x25D1  # CIRCLE WITH RIGHT HALF BLACK
0x2246  0x2592  # MEDIUM SHADE
0x2247  0x25A4  # SQUARE WITH HORIZONTAL FILL
0x2248  0x25A5  # SQUARE WITH VERTICAL FILL
0x2249  0x25A8  # SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL
0x224A  0x25A7  # SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL
0x224B  0x25A6  # SQUARE WITH ORTHOGONAL CROSSHATCH FILL
0x224C  0x25A9  # SQUARE WITH DIAGONAL CROSSHATCH FILL
0x224D  0x2668  # HOT SPRINGS
0x224E  0x260F  # WHITE TELEPHONE
0x224F  0x260E  # BLACK TELEPHONE
0x2250  0x261C  # WHITE LEFT POINTING INDEX
0x2251  0x261E  # WHITE RIGHT POINTING INDEX
0x2252  0x00B6  # PILCROW SIGN
0x2253  0x2020  # DAGGER
0x2254  0x2021  # DOUBLE DAGGER
0x2255  0x2195  # UP DOWN ARROW
0x2256  0x2197  # NORTH EAST ARROW
0x2257  0x2199  # SOUTH WEST ARROW
0x2258  0x2196  # NORTH WEST ARROW
0x2259  0x2198  # SOUTH EAST ARROW
0x225A  0x266D  # MUSIC FLAT SIGN
0x225B  0x2669  # QUARTER NOTE
0x225C  0x266A  # EIGHTH NOTE
0x225D  0x266C  # BEAMED SIXTEENTH NOTES
0x225E  0x327F  # KOREAN STANDARD SYMBOL
0x225F  0x321C  # PARENTHESIZED HANGUL CIEUC U
0x2260  0x2116  # NUMERO SIGN
0x2261  0x33C7  # SQUARE CO
0x2262  0x2122  # TRADE MARK SIGN
0x2263  0x33C2  # SQUARE AM
0x2264  0x33D8  # SQUARE PM
0x2265  0x2121  # TELEPHONE SIGN
0x2321  0xFF01  # FULLWIDTH EXCLAMATION MARK
0x2322  0xFF02  # FULLWIDTH QUOTATION MARK
0x2323  0xFF03  # FULLWIDTH NUMBER SIGN
0x2324  0xFF04  # FULLWIDTH DOLLAR SIGN
0x2325  0xFF05  # FULLWIDTH PERCENT SIGN
0x2326  0xFF06  # FULLWIDTH AMPERSAND
0x2327  0xFF07  # FULLWIDTH APOSTROPHE
0x2328  0xFF08  # FULLWIDTH LEFT PARENTHESIS
0x2329  0xFF09  # FULLWIDTH RIGHT PARENTHESIS
0x232A  0xFF0A  # FULLWIDTH ASTERISK
0x232B  0xFF0B  # FULLWIDTH PLUS SIGN
0x232C  0xFF0C  # FULLWIDTH COMMA
0x232D  0xFF0D  # FULLWIDTH HYPHEN-MINUS
0x232E  0xFF0E  # FULLWIDTH FULL STOP
0x232F  0xFF0F  # FULLWIDTH SOLIDUS
0x2330  0xFF10  # FULLWIDTH DIGIT ZERO
0x2331  0xFF11  # FULLWIDTH DIGIT ONE
0x2332  0xFF12  # FULLWIDTH DIGIT TWO
0x2333  0xFF13  # FULLWIDTH DIGIT THREE
0x2334  0xFF14  # FULLWIDTH DIGIT FOUR
0x2335  0xFF15  # FULLWIDTH DIGIT FIVE
0x2336  0xFF16  # FULLWIDTH DIGIT SIX
0x2337  0xFF17  # FULLWIDTH DIGIT SEVEN
0x2338  0xFF18  # FULLWIDTH DIGIT EIGHT
0x2339  0xFF19  # FULLWIDTH DIGIT NINE
0x233A  0xFF1A  # FULLWIDTH COLON
0x233B  0xFF1B  # FULLWIDTH SEMICOLON
0x233C  0xFF1C  # FULLWIDTH LESS-THAN SIGN
0x233D  0xFF1D  # FULLWIDTH EQUALS SIGN
0x233E  0xFF1E  # FULLWIDTH GREATER-THAN SIGN
0x233F  0xFF1F  # FULLWIDTH QUESTION MARK
0x2340  0xFF20  # FULLWIDTH COMMERCIAL AT
0x2341  0xFF21  # FULLWIDTH LATIN CAPITAL LETTER A
0x2342  0xFF22  # FULLWIDTH LATIN CAPITAL LETTER B
0x2343  0xFF23  # FULLWIDTH LATIN CAPITAL LETTER C
0x2344  0xFF24  # FULLWIDTH LATIN CAPITAL LETTER D
0x2345  0xFF25  # FULLWIDTH LATIN CAPITAL LETTER E
0x2346  0xFF26  # FULLWIDTH LATIN CAPITAL LETTER F
0x2347  0xFF27  # FULLWIDTH LATIN CAPITAL LETTER G
0x2348  0xFF28  # FULLWIDTH LATIN CAPITAL LETTER H
0x2349  0xFF29  # FULLWIDTH LATIN CAPITAL LETTER I
0x234A  0xFF2A  # FULLWIDTH LATIN CAPITAL LETTER J
0x234B  0xFF2B  # FULLWIDTH LATIN CAPITAL LETTER K
0x234C  0xFF2C  # FULLWIDTH LATIN CAPITAL LETTER L
0x234D  0xFF2D  # FULLWIDTH LATIN CAPITAL LETTER M
0x234E  0xFF2E  # FULLWIDTH LATIN CAPITAL LETTER N
0x234F  0xFF2F  # FULLWIDTH LATIN CAPITAL LETTER O
0x2350  0xFF30  # FULLWIDTH LATIN CAPITAL LETTER P
0x2351  0xFF31  # FULLWIDTH LATIN CAPITAL LETTER Q
0x2352  0xFF32  # FULLWIDTH LATIN CAPITAL LETTER R
0x2353  0xFF33  # FULLWIDTH LATIN CAPITAL LETTER S
0x2354  0xFF34  # FULLWIDTH LATIN CAPITAL LETTER T
0x2355  0xFF35  # FULLWIDTH LATIN CAPITAL LETTER U
0x2356  0xFF36  # FULLWIDTH LATIN CAPITAL LETTER V
0x2357  0xFF37  # FULLWIDTH LATIN CAPITAL LETTER W
0x2358  0xFF38  # FULLWIDTH LATIN CAPITAL LETTER X
0x2359  0xFF39  # FULLWIDTH LATIN CAPITAL LETTER Y
0x235A  0xFF3A  # FULLWIDTH LATIN CAPITAL LETTER Z
0x235B  0xFF3B  # FULLWIDTH LEFT SQUARE BRACKET
0x235C  0xFFE6  # FULLWIDTH WON SIGN
0x235D  0xFF3D  # FULLWIDTH RIGHT SQUARE BRACKET
0x235E  0xFF3E  # FULLWIDTH CIRCUMFLEX ACCENT
0x235F  0xFF3F  # FULLWIDTH LOW LINE
0x2360  0xFF40  # FULLWIDTH GRAVE ACCENT
0x2361  0xFF41  # FULLWIDTH LATIN SMALL LETTER A
0x2362  0xFF42  # FULLWIDTH LATIN SMALL LETTER B
0x2363  0xFF43  # FULLWIDTH LATIN SMALL LETTER C
0x2364  0xFF44  # FULLWIDTH LATIN SMALL LETTER D
0x2365  0xFF45  # FULLWIDTH LATIN SMALL LETTER E
0x2366  0xFF46  # FULLWIDTH LATIN SMALL LETTER F
0x2367  0xFF47  # FULLWIDTH LATIN SMALL LETTER G
0x2368  0xFF48  # FULLWIDTH LATIN SMALL LETTER H
0x2369  0xFF49  # FULLWIDTH LATIN SMALL LETTER I
0x236A  0xFF4A  # FULLWIDTH LATIN SMALL LETTER J
0x236B  0xFF4B  # FULLWIDTH LATIN SMALL LETTER K
0x236C  0xFF4C  # FULLWIDTH LATIN SMALL LETTER L
0x236D  0xFF4D  # FULLWIDTH LATIN SMALL LETTER M
0x236E  0xFF4E  # FULLWIDTH LATIN SMALL LETTER N
0x236F  0xFF4F  # FULLWIDTH LATIN SMALL LETTER O
0x2370  0xFF50  # FULLWIDTH LATIN SMALL LETTER P
0x2371  0xFF51  # FULLWIDTH LATIN SMALL LETTER Q
0x2372  0xFF52  # FULLWIDTH LATIN SMALL LETTER R
0x2373  0xFF53  # FULLWIDTH LATIN SMALL LETTER S
0x2374  0xFF54  # FULLWIDTH LATIN SMALL LETTER T
0x2375  0xFF55  # FULLWIDTH LATIN SMALL LETTER U
0x2376  0xFF56  # FULLWIDTH LATIN SMALL LETTER V
0x2377  0xFF57  # FULLWIDTH LATIN SMALL LETTER W
0x2378  0xFF58  # FULLWIDTH LATIN SMALL LETTER X
0x2379  0xFF59  # FULLWIDTH LATIN SMALL LETTER Y
0x237A  0xFF5A  # FULLWIDTH LATIN SMALL LETTER Z
0x237B  0xFF5B  # FULLWIDTH LEFT CURLY BRACKET
0x237C  0xFF5C  # FULLWIDTH VERTICAL LINE
0x237D  0xFF5D  # FULLWIDTH RIGHT CURLY BRACKET
0x237E  0xFFE3  # FULLWIDTH MACRON
0x2421  0x3131  # HANGUL LETTER KIYEOK
0x2422  0x3132  # HANGUL LETTER SSANGKIYEOK
0x2423  0x3133  # HANGUL LETTER KIYEOK-SIOS
0x2424  0x3134  # HANGUL LETTER NIEUN
0x2425  0x3135  # HANGUL LETTER NIEUN-CIEUC
0x2426  0x3136  # HANGUL LETTER NIEUN-HIEUH
0x2427  0x3137  # HANGUL LETTER TIKEUT
0x2428  0x3138  # HANGUL LETTER SSANGTIKEUT
0x2429  0x3139  # HANGUL LETTER RIEUL
0x242A  0x313A  # HANGUL LETTER RIEUL-KIYEOK
0x242B  0x313B  # HANGUL LETTER RIEUL-MIEUM
0x242C  0x313C  # HANGUL LETTER RIEUL-PIEUP
0x242D  0x313D  # HANGUL LETTER RIEUL-SIOS
0x242E  0x313E  # HANGUL LETTER RIEUL-THIEUTH
0x242F  0x313F  # HANGUL LETTER RIEUL-PHIEUPH
0x2430  0x3140  # HANGUL LETTER RIEUL-HIEUH
0x2431  0x3141  # HANGUL LETTER MIEUM
0x2432  0x3142  # HANGUL LETTER PIEUP
0x2433  0x3143  # HANGUL LETTER SSANGPIEUP
0x2434  0x3144  # HANGUL LETTER PIEUP-SIOS
0x2435  0x3145  # HANGUL LETTER SIOS
0x2436  0x3146  # HANGUL LETTER SSANGSIOS
0x2437  0x3147  # HANGUL LETTER IEUNG
0x2438  0x3148  # HANGUL LETTER CIEUC
0x2439  0x3149  # HANGUL LETTER SSANGCIEUC
0x243A  0x314A  # HANGUL LETTER CHIEUCH
0x243B  0x314B  # HANGUL LETTER KHIEUKH
0x243C  0x314C  # HANGUL LETTER THIEUTH
0x243D  0x314D  # HANGUL LETTER PHIEUPH
0x243E  0x314E  # HANGUL LETTER HIEUH
0x243F  0x314F  # HANGUL LETTER A
0x2440  0x3150  # HANGUL LETTER AE
0x2441  0x3151  # HANGUL LETTER YA
0x2442  0x3152  # HANGUL LETTER YAE
0x2443  0x3153  # HANGUL LETTER EO
0x2444  0x3154  # HANGUL LETTER E
0x2445  0x3155  # HANGUL LETTER YEO
0x2446  0x3156  # HANGUL LETTER YE
0x2447  0x3157  # HANGUL LETTER O
0x2448  0x3158  # HANGUL LETTER WA
0x2449  0x3159  # HANGUL LETTER WAE
0x244A  0x315A  # HANGUL LETTER OE
0x244B  0x315B  # HANGUL LETTER YO
0x244C  0x315C  # HANGUL LETTER U
0x244D  0x315D  # HANGUL LETTER WEO
0x244E  0x315E  # HANGUL LETTER WE
0x244F  0x315F  # HANGUL LETTER WI
0x2450  0x3160  # HANGUL LETTER YU
0x2451  0x3161  # HANGUL LETTER EU
0x2452  0x3162  # HANGUL LETTER YI
0x2453  0x3163  # HANGUL LETTER I
0x2454  0x3164  # HANGUL FILLER
0x2455  0x3165  # HANGUL LETTER SSANGNIEUN
0x2456  0x3166  # HANGUL LETTER NIEUN-TIKEUT
0x2457  0x3167  # HANGUL LETTER NIEUN-SIOS
0x2458  0x3168  # HANGUL LETTER NIEUN-PANSIOS
0x2459  0x3169  # HANGUL LETTER RIEUL-KIYEOK-SIOS
0x245A  0x316A  # HANGUL LETTER RIEUL-TIKEUT
0x245B  0x316B  # HANGUL LETTER RIEUL-PIEUP-SIOS
0x245C  0x316C  # HANGUL LETTER RIEUL-PANSIOS
0x245D  0x316D  # HANGUL LETTER RIEUL-YEORINHIEUH
0x245E  0x316E  # HANGUL LETTER MIEUM-PIEUP
0x245F  0x316F  # HANGUL LETTER MIEUM-SIOS
0x2460  0x3170  # HANGUL LETTER MIEUM-PANSIOS
0x2461  0x3171  # HANGUL LETTER KAPYEOUNMIEUM
0x2462  0x3172  # HANGUL LETTER PIEUP-KIYEOK
0x2463  0x3173  # HANGUL LETTER PIEUP-TIKEUT
0x2464  0x3174  # HANGUL LETTER PIEUP-SIOS-KIYEOK
0x2465  0x3175  # HANGUL LETTER PIEUP-SIOS-TIKEUT
0x2466  0x3176  # HANGUL LETTER PIEUP-CIEUC
0x2467  0x3177  # HANGUL LETTER PIEUP-THIEUTH
0x2468  0x3178  # HANGUL LETTER KAPYEOUNPIEUP
0x2469  0x3179  # HANGUL LETTER KAPYEOUNSSANGPIEUP
0x246A  0x317A  # HANGUL LETTER SIOS-KIYEOK
0x246B  0x317B  # HANGUL LETTER SIOS-NIEUN
0x246C  0x317C  # HANGUL LETTER SIOS-TIKEUT
0x246D  0x317D  # HANGUL LETTER SIOS-PIEUP
0x246E  0x317E  # HANGUL LETTER SIOS-CIEUC
0x246F  0x317F  # HANGUL LETTER PANSIOS
0x2470  0x3180  # HANGUL LETTER SSANGIEUNG
0x2471  0x3181  # HANGUL LETTER YESIEUNG
0x2472  0x3182  # HANGUL LETTER YESIEUNG-SIOS
0x2473  0x3183  # HANGUL LETTER YESIEUNG-PANSIOS
0x2474  0x3184  # HANGUL LETTER KAPYEOUNPHIEUPH
0x2475  0x3185  # HANGUL LETTER SSANGHIEUH
0x2476  0x3186  # HANGUL LETTER YEORINHIEUH
0x2477  0x3187  # HANGUL LETTER YO-YA
0x2478  0x3188  # HANGUL LETTER YO-YAE
0x2479  0x3189  # HANGUL LETTER YO-I
0x247A  0x318A  # HANGUL LETTER YU-YEO
0x247B  0x318B  # HANGUL LETTER YU-YE
0x247C  0x318C  # HANGUL LETTER YU-I
0x247D  0x318D  # HANGUL LETTER ARAEA
0x247E  0x318E  # HANGUL LETTER ARAEAE
0x2521  0x2170  # SMALL ROMAN NUMERAL ONE
0x2522  0x2171  # SMALL ROMAN NUMERAL TWO
0x2523  0x2172  # SMALL ROMAN NUMERAL THREE
0x2524  0x2173  # SMALL ROMAN NUMERAL FOUR
0x2525  0x2174  # SMALL ROMAN NUMERAL FIVE
0x2526  0x2175  # SMALL ROMAN NUMERAL SIX
0x2527  0x2176  # SMALL ROMAN NUMERAL SEVEN
0x2528  0x2177  # SMALL ROMAN NUMERAL EIGHT
0x2529  0x2178  # SMALL ROMAN NUMERAL NINE
0x252A  0x2179  # SMALL ROMAN NUMERAL TEN
0x2530  0x2160  # ROMAN NUMERAL ONE
0x2531  0x2161  # ROMAN NUMERAL TWO
0x2532  0x2162  # ROMAN NUMERAL THREE
0x2533  0x2163  # ROMAN NUMERAL FOUR
0x2534  0x2164  # ROMAN NUMERAL FIVE
0x2535  0x2165  # ROMAN NUMERAL SIX
0x2536  0x2166  # ROMAN NUMERAL SEVEN
0x2537  0x2167  # ROMAN NUMERAL EIGHT
0x2538  0x2168  # ROMAN NUMERAL NINE
0x2539  0x2169  # ROMAN NUMERAL TEN
0x2541  0x0391  # GREEK CAPITAL LETTER ALPHA
0x2542  0x0392  # GREEK CAPITAL LETTER BETA
0x2543  0x0393  # GREEK CAPITAL LETTER GAMMA
0x2544  0x0394  # GREEK CAPITAL LETTER DELTA
0x2545  0x0395  # GREEK CAPITAL LETTER EPSILON
0x2546  0x0396  # GREEK CAPITAL LETTER ZETA
0x2547  0x0397  # GREEK CAPITAL LETTER ETA
0x2548  0x0398  # GREEK CAPITAL LETTER THETA
0x2549  0x0399  # GREEK CAPITAL LETTER IOTA
0x254A  0x039A  # GREEK CAPITAL LETTER KAPPA
0x254B  0x039B  # GREEK CAPITAL LETTER LAMDA
0x254C  0x039C  # GREEK CAPITAL LETTER MU
0x254D  0x039D  # GREEK CAPITAL LETTER NU
0x254E  0x039E  # GREEK CAPITAL LETTER XI
0x254F  0x039F  # GREEK CAPITAL LETTER OMICRON
0x2550  0x03A0  # GREEK CAPITAL LETTER PI
0x2551  0x03A1  # GREEK CAPITAL LETTER RHO
0x2552  0x03A3  # GREEK CAPITAL LETTER SIGMA
0x2553  0x03A4  # GREEK CAPITAL LETTER TAU
0x2554  0x03A5  # GREEK CAPITAL LETTER UPSILON
0x2555  0x03A6  # GREEK CAPITAL LETTER PHI
0x2556  0x03A7  # GREEK CAPITAL LETTER CHI
0x2557  0x03A8  # GREEK CAPITAL LETTER PSI
0x2558  0x03A9  # GREEK CAPITAL LETTER OMEGA
0x2561  0x03B1  # GREEK SMALL LETTER ALPHA
0x2562  0x03B2  # GREEK SMALL LETTER BETA
0x2563  0x03B3  # GREEK SMALL LETTER GAMMA
0x2564  0x03B4  # GREEK SMALL LETTER DELTA
0x2565  0x03B5  # GREEK SMALL LETTER EPSILON
0x2566  0x03B6  # GREEK SMALL LETTER ZETA
0x2567  0x03B7  # GREEK SMALL LETTER ETA
0x2568  0x03B8  # GREEK SMALL LETTER THETA
0x2569  0x03B9  # GREEK SMALL LETTER IOTA
0x256A  0x03BA  # GREEK SMALL LETTER KAPPA
0x256B  0x03BB  # GREEK SMALL LETTER LAMDA
0x256C  0x03BC  # GREEK SMALL LETTER MU
0x256D  0x03BD  # GREEK SMALL LETTER NU
0x256E  0x03BE  # GREEK SMALL LETTER XI
0x256F  0x03BF  # GREEK SMALL LETTER OMICRON
0x2570  0x03C0  # GREEK SMALL LETTER PI
0x2571  0x03C1  # GREEK SMALL LETTER RHO
0x2572  0x03C3  # GREEK SMALL LETTER SIGMA
0x2573  0x03C4  # GREEK SMALL LETTER TAU
0x2574  0x03C5  # GREEK SMALL LETTER UPSILON
0x2575  0x03C6  # GREEK SMALL LETTER PHI
0x2576  0x03C7  # GREEK SMALL LETTER CHI
0x2577  0x03C8  # GREEK SMALL LETTER PSI
0x2578  0x03C9  # GREEK SMALL LETTER OMEGA
0x2621  0x2500  # BOX DRAWINGS LIGHT HORIZONTAL
0x2622  0x2502  # BOX DRAWINGS LIGHT VERTICAL
0x2623  0x250C  # BOX DRAWINGS LIGHT DOWN AND RIGHT
0x2624  0x2510  # BOX DRAWINGS LIGHT DOWN AND LEFT
0x2625  0x2518  # BOX DRAWINGS LIGHT UP AND LEFT
0x2626  0x2514  # BOX DRAWINGS LIGHT UP AND RIGHT
0x2627  0x251C  # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0x2628  0x252C  # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0x2629  0x2524  # BOX DRAWINGS LIGHT VERTICAL AND LEFT
0x262A  0x2534  # BOX DRAWINGS LIGHT UP AND HORIZONTAL
0x262B  0x253C  # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0x262C  0x2501  # BOX DRAWINGS HEAVY HORIZONTAL
0x262D  0x2503  # BOX DRAWINGS HEAVY VERTICAL
0x262E  0x250F  # BOX DRAWINGS HEAVY DOWN AND RIGHT
0x262F  0x2513  # BOX DRAWINGS HEAVY DOWN AND LEFT
0x2630  0x251B  # BOX DRAWINGS HEAVY UP AND LEFT
0x2631  0x2517  # BOX DRAWINGS HEAVY UP AND RIGHT
0x2632  0x2523  # BOX DRAWINGS HEAVY VERTICAL AND RIGHT
0x2633  0x2533  # BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
0x2634  0x252B  # BOX DRAWINGS HEAVY VERTICAL AND LEFT
0x2635  0x253B  # BOX DRAWINGS HEAVY UP AND HORIZONTAL
0x2636  0x254B  # BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
0x2637  0x2520  # BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
0x2638  0x252F  # BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
0x2639  0x2528  # BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
0x263A  0x2537  # BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
0x263B  0x253F  # BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
0x263C  0x251D  # BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
0x263D  0x2530  # BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
0x263E  0x2525  # BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
0x263F  0x2538  # BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
0x2640  0x2542  # BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
0x2641  0x2512  # BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
0x2642  0x2511  # BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
0x2643  0x251A  # BOX DRAWINGS UP HEAVY AND LEFT LIGHT
0x2644  0x2519  # BOX DRAWINGS UP LIGHT AND LEFT HEAVY
0x2645  0x2516  # BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
0x2646  0x2515  # BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
0x2647  0x250E  # BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
0x2648  0x250D  # BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
0x2649  0x251E  # BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
0x264A  0x251F  # BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
0x264B  0x2521  # BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
0x264C  0x2522  # BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
0x264D  0x2526  # BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
0x264E  0x2527  # BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
0x264F  0x2529  # BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
0x2650  0x252A  # BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
0x2651  0x252D  # BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
0x2652  0x252E  # BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
0x2653  0x2531  # BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
0x2654  0x2532  # BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
0x2655  0x2535  # BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
0x2656  0x2536  # BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
0x2657  0x2539  # BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
0x2658  0x253A  # BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
0x2659  0x253D  # BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
0x265A  0x253E  # BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
0x265B  0x2540  # BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
0x265C  0x2541  # BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
0x265D  0x2543  # BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
0x265E  0x2544  # BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
0x265F  0x2545  # BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
0x2660  0x2546  # BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
0x2661  0x2547  # BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
0x2662  0x2548  # BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
0x2663  0x2549  # BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
0x2664  0x254A  # BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
0x2721  0x3395  # SQUARE MU L
0x2722  0x3396  # SQUARE ML
0x2723  0x3397  # SQUARE DL
0x2724  0x2113  # SCRIPT SMALL L
0x2725  0x3398  # SQUARE KL
0x2726  0x33C4  # SQUARE CC
0x2727  0x33A3  # SQUARE MM CUBED
0x2728  0x33A4  # SQUARE CM CUBED
0x2729  0x33A5  # SQUARE M CUBED
0x272A  0x33A6  # SQUARE KM CUBED
0x272B  0x3399  # SQUARE FM
0x272C  0x339A  # SQUARE NM
0x272D  0x339B  # SQUARE MU M
0x272E  0x339C  # SQUARE MM
0x272F  0x339D  # SQUARE CM
0x2730  0x339E  # SQUARE KM
0x2731  0x339F  # SQUARE MM SQUARED
0x2732  0x33A0  # SQUARE CM SQUARED
0x2733  0x33A1  # SQUARE M SQUARED
0x2734  0x33A2  # SQUARE KM SQUARED
0x2735  0x33CA  # SQUARE HA
0x2736  0x338D  # SQUARE MU G
0x2737  0x338E  # SQUARE MG
0x2738  0x338F  # SQUARE KG
0x2739  0x33CF  # SQUARE KT
0x273A  0x3388  # SQUARE CAL
0x273B  0x3389  # SQUARE KCAL
0x273C  0x33C8  # SQUARE DB
0x273D  0x33A7  # SQUARE M OVER S
0x273E  0x33A8  # SQUARE M OVER S SQUARED
0x273F  0x33B0  # SQUARE PS
0x2740  0x33B1  # SQUARE NS
0x2741  0x33B2  # SQUARE MU S
0x2742  0x33B3  # SQUARE MS
0x2743  0x33B4  # SQUARE PV
0x2744  0x33B5  # SQUARE NV
0x2745  0x33B6  # SQUARE MU V
0x2746  0x33B7  # SQUARE MV
0x2747  0x33B8  # SQUARE KV
0x2748  0x33B9  # SQUARE MV MEGA
0x2749  0x3380  # SQUARE PA AMPS
0x274A  0x3381  # SQUARE NA
0x274B  0x3382  # SQUARE MU A
0x274C  0x3383  # SQUARE MA
0x274D  0x3384  # SQUARE KA
0x274E  0x33BA  # SQUARE PW
0x274F  0x33BB  # SQUARE NW
0x2750  0x33BC  # SQUARE MU W
0x2751  0x33BD  # SQUARE MW
0x2752  0x33BE  # SQUARE KW
0x2753  0x33BF  # SQUARE MW MEGA
0x2754  0x3390  # SQUARE HZ
0x2755  0x3391  # SQUARE KHZ
0x2756  0x3392  # SQUARE MHZ
0x2757  0x3393  # SQUARE GHZ
0x2758  0x3394  # SQUARE THZ
0x2759  0x2126  # OHM SIGN
0x275A  0x33C0  # SQUARE K OHM
0x275B  0x33C1  # SQUARE M OHM
0x275C  0x338A  # SQUARE PF
0x275D  0x338B  # SQUARE NF
0x275E  0x338C  # SQUARE MU F
0x275F  0x33D6  # SQUARE MOL
0x2760  0x33C5  # SQUARE CD
0x2761  0x33AD  # SQUARE RAD
0x2762  0x33AE  # SQUARE RAD OVER S
0x2763  0x33AF  # SQUARE RAD OVER S SQUARED
0x2764  0x33DB  # SQUARE SR
0x2765  0x33A9  # SQUARE PA
0x2766  0x33AA  # SQUARE KPA
0x2767  0x33AB  # SQUARE MPA
0x2768  0x33AC  # SQUARE GPA
0x2769  0x33DD  # SQUARE WB
0x276A  0x33D0  # SQUARE LM
0x276B  0x33D3  # SQUARE LX
0x276C  0x33C3  # SQUARE BQ
0x276D  0x33C9  # SQUARE GY
0x276E  0x33DC  # SQUARE SV
0x276F  0x33C6  # SQUARE C OVER KG
0x2821  0x00C6  # LATIN CAPITAL LIGATURE AE
0x2822  0x00D0  # LATIN CAPITAL LETTER ETH
0x2823  0x00AA  # FEMININE ORDINAL INDICATOR
0x2824  0x0126  # LATIN CAPITAL LETTER H WITH STROKE
0x2826  0x0132  # LATIN CAPITAL LIGATURE IJ
0x2828  0x013F  # LATIN CAPITAL LETTER L WITH MIDDLE DOT
0x2829  0x0141  # LATIN CAPITAL LETTER L WITH STROKE
0x282A  0x00D8  # LATIN CAPITAL LETTER O WITH STROKE
0x282B  0x0152  # LATIN CAPITAL LIGATURE OE
0x282C  0x00BA  # MASCULINE ORDINAL INDICATOR
0x282D  0x00DE  # LATIN CAPITAL LETTER THORN
0x282E  0x0166  # LATIN CAPITAL LETTER T WITH STROKE
0x282F  0x014A  # LATIN CAPITAL LETTER ENG
0x2831  0x3260  # CIRCLED HANGUL KIYEOK
0x2832  0x3261  # CIRCLED HANGUL NIEUN
0x2833  0x3262  # CIRCLED HANGUL TIKEUT
0x2834  0x3263  # CIRCLED HANGUL RIEUL
0x2835  0x3264  # CIRCLED HANGUL MIEUM
0x2836  0x3265  # CIRCLED HANGUL PIEUP
0x2837  0x3266  # CIRCLED HANGUL SIOS
0x2838  0x3267  # CIRCLED HANGUL IEUNG
0x2839  0x3268  # CIRCLED HANGUL CIEUC
0x283A  0x3269  # CIRCLED HANGUL CHIEUCH
0x283B  0x326A  # CIRCLED HANGUL KHIEUKH
0x283C  0x326B  # CIRCLED HANGUL THIEUTH
0x283D  0x326C  # CIRCLED HANGUL PHIEUPH
0x283E  0x326D  # CIRCLED HANGUL HIEUH
0x283F  0x326E  # CIRCLED HANGUL KIYEOK A
0x2840  0x326F  # CIRCLED HANGUL NIEUN A
0x2841  0x3270  # CIRCLED HANGUL TIKEUT A
0x2842  0x3271  # CIRCLED HANGUL RIEUL A
0x2843  0x3272  # CIRCLED HANGUL MIEUM A
0x2844  0x3273  # CIRCLED HANGUL PIEUP A
0x2845  0x3274  # CIRCLED HANGUL SIOS A
0x2846  0x3275  # CIRCLED HANGUL IEUNG A
0x2847  0x3276  # CIRCLED HANGUL CIEUC A
0x2848  0x3277  # CIRCLED HANGUL CHIEUCH A
0x2849  0x3278  # CIRCLED HANGUL KHIEUKH A
0x284A  0x3279  # CIRCLED HANGUL THIEUTH A
0x284B  0x327A  # CIRCLED HANGUL PHIEUPH A
0x284C  0x327B  # CIRCLED HANGUL HIEUH A
0x284D  0x24D0  # CIRCLED LATIN SMALL LETTER A
0x284E  0x24D1  # CIRCLED LATIN SMALL LETTER B
0x284F  0x24D2  # CIRCLED LATIN SMALL LETTER C
0x2850  0x24D3  # CIRCLED LATIN SMALL LETTER D
0x2851  0x24D4  # CIRCLED LATIN SMALL LETTER E
0x2852  0x24D5  # CIRCLED LATIN SMALL LETTER F
0x2853  0x24D6  # CIRCLED LATIN SMALL LETTER G
0x2854  0x24D7  # CIRCLED LATIN SMALL LETTER H
0x2855  0x24D8  # CIRCLED LATIN SMALL LETTER I
0x2856  0x24D9  # CIRCLED LATIN SMALL LETTER J
0x2857  0x24DA  # CIRCLED LATIN SMALL LETTER K
0x2858  0x24DB  # CIRCLED LATIN SMALL LETTER L
0x2859  0x24DC  # CIRCLED LATIN SMALL LETTER M
0x285A  0x24DD  # CIRCLED LATIN SMALL LETTER N
0x285B  0x24DE  # CIRCLED LATIN SMALL LETTER O
0x285C  0x24DF  # CIRCLED LATIN SMALL LETTER P
0x285D  0x24E0  # CIRCLED LATIN SMALL LETTER Q
0x285E  0x24E1  # CIRCLED LATIN SMALL LETTER R
0x285F  0x24E2  # CIRCLED LATIN SMALL LETTER S
0x2860  0x24E3  # CIRCLED LATIN SMALL LETTER T
0x2861  0x24E4  # CIRCLED LATIN SMALL LETTER U
0x2862  0x24E5  # CIRCLED LATIN SMALL LETTER V
0x2863  0x24E6  # CIRCLED LATIN SMALL LETTER W
0x2864  0x24E7  # CIRCLED LATIN SMALL LETTER X
0x2865  0x24E8  # CIRCLED LATIN SMALL LETTER Y
0x2866  0x24E9  # CIRCLED LATIN SMALL LETTER Z
0x2867  0x2460  # CIRCLED DIGIT ONE
0x2868  0x2461  # CIRCLED DIGIT TWO
0x2869  0x2462  # CIRCLED DIGIT THREE
0x286A  0x2463  # CIRCLED DIGIT FOUR
0x286B  0x2464  # CIRCLED DIGIT FIVE
0x286C  0x2465  # CIRCLED DIGIT SIX
0x286D  0x2466  # CIRCLED DIGIT SEVEN
0x286E  0x2467  # CIRCLED DIGIT EIGHT
0x286F  0x2468  # CIRCLED DIGIT NINE
0x2870  0x2469  # CIRCLED NUMBER TEN
0x2871  0x246A  # CIRCLED NUMBER ELEVEN
0x2872  0x246B  # CIRCLED NUMBER TWELVE
0x2873  0x246C  # CIRCLED NUMBER THIRTEEN
0x2874  0x246D  # CIRCLED NUMBER FOURTEEN
0x2875  0x246E  # CIRCLED NUMBER FIFTEEN
0x2876  0x00BD  # VULGAR FRACTION ONE HALF
0x2877  0x2153  # VULGAR FRACTION ONE THIRD
0x2878  0x2154  # VULGAR FRACTION TWO THIRDS
0x2879  0x00BC  # VULGAR FRACTION ONE QUARTER
0x287A  0x00BE  # VULGAR FRACTION THREE QUARTERS
0x287B  0x215B  # VULGAR FRACTION ONE EIGHTH
0x287C  0x215C  # VULGAR FRACTION THREE EIGHTHS
0x287D  0x215D  # VULGAR FRACTION FIVE EIGHTHS
0x287E  0x215E  # VULGAR FRACTION SEVEN EIGHTHS
0x2921  0x00E6  # LATIN SMALL LIGATURE AE
0x2922  0x0111  # LATIN SMALL LETTER D WITH STROKE
0x2923  0x00F0  # LATIN SMALL LETTER ETH
0x2924  0x0127  # LATIN SMALL LETTER H WITH STROKE
0x2925  0x0131  # LATIN SMALL LETTER DOTLESS I
0x2926  0x0133  # LATIN SMALL LIGATURE IJ
0x2927  0x0138  # LATIN SMALL LETTER KRA
0x2928  0x0140  # LATIN SMALL LETTER L WITH MIDDLE DOT
0x2929  0x0142  # LATIN SMALL LETTER L WITH STROKE
0x292A  0x00F8  # LATIN SMALL LETTER O WITH STROKE
0x292B  0x0153  # LATIN SMALL LIGATURE OE
0x292C  0x00DF  # LATIN SMALL LETTER SHARP S
0x292D  0x00FE  # LATIN SMALL LETTER THORN
0x292E  0x0167  # LATIN SMALL LETTER T WITH STROKE
0x292F  0x014B  # LATIN SMALL LETTER ENG
0x2930  0x0149  # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
0x2931  0x3200  # PARENTHESIZED HANGUL KIYEOK
0x2932  0x3201  # PARENTHESIZED HANGUL NIEUN
0x2933  0x3202  # PARENTHESIZED HANGUL TIKEUT
0x2934  0x3203  # PARENTHESIZED HANGUL RIEUL
0x2935  0x3204  # PARENTHESIZED HANGUL MIEUM
0x2936  0x3205  # PARENTHESIZED HANGUL PIEUP
0x2937  0x3206  # PARENTHESIZED HANGUL SIOS
0x2938  0x3207  # PARENTHESIZED HANGUL IEUNG
0x2939  0x3208  # PARENTHESIZED HANGUL CIEUC
0x293A  0x3209  # PARENTHESIZED HANGUL CHIEUCH
0x293B  0x320A  # PARENTHESIZED HANGUL KHIEUKH
0x293C  0x320B  # PARENTHESIZED HANGUL THIEUTH
0x293D  0x320C  # PARENTHESIZED HANGUL PHIEUPH
0x293E  0x320D  # PARENTHESIZED HANGUL HIEUH
0x293F  0x320E  # PARENTHESIZED HANGUL KIYEOK A
0x2940  0x320F  # PARENTHESIZED HANGUL NIEUN A
0x2941  0x3210  # PARENTHESIZED HANGUL TIKEUT A
0x2942  0x3211  # PARENTHESIZED HANGUL RIEUL A
0x2943  0x3212  # PARENTHESIZED HANGUL MIEUM A
0x2944  0x3213  # PARENTHESIZED HANGUL PIEUP A
0x2945  0x3214  # PARENTHESIZED HANGUL SIOS A
0x2946  0x3215  # PARENTHESIZED HANGUL IEUNG A
0x2947  0x3216  # PARENTHESIZED HANGUL CIEUC A
0x2948  0x3217  # PARENTHESIZED HANGUL CHIEUCH A
0x2949  0x3218  # PARENTHESIZED HANGUL KHIEUKH A
0x294A  0x3219  # PARENTHESIZED HANGUL THIEUTH A
0x294B  0x321A  # PARENTHESIZED HANGUL PHIEUPH A
0x294C  0x321B  # PARENTHESIZED HANGUL HIEUH A
0x294D  0x249C  # PARENTHESIZED LATIN SMALL LETTER A
0x294E  0x249D  # PARENTHESIZED LATIN SMALL LETTER B
0x294F  0x249E  # PARENTHESIZED LATIN SMALL LETTER C
0x2950  0x249F  # PARENTHESIZED LATIN SMALL LETTER D
0x2951  0x24A0  # PARENTHESIZED LATIN SMALL LETTER E
0x2952  0x24A1  # PARENTHESIZED LATIN SMALL LETTER F
0x2953  0x24A2  # PARENTHESIZED LATIN SMALL LETTER G
0x2954  0x24A3  # PARENTHESIZED LATIN SMALL LETTER H
0x2955  0x24A4  # PARENTHESIZED LATIN SMALL LETTER I
0x2956  0x24A5  # PARENTHESIZED LATIN SMALL LETTER J
0x2957  0x24A6  # PARENTHESIZED LATIN SMALL LETTER K
0x2958  0x24A7  # PARENTHESIZED LATIN SMALL LETTER L
0x2959  0x24A8  # PARENTHESIZED LATIN SMALL LETTER M
0x295A  0x24A9  # PARENTHESIZED LATIN SMALL LETTER N
0x295B  0x24AA  # PARENTHESIZED LATIN SMALL LETTER O
0x295C  0x24AB  # PARENTHESIZED LATIN SMALL LETTER P
0x295D  0x24AC  # PARENTHESIZED LATIN SMALL LETTER Q
0x295E  0x24AD  # PARENTHESIZED LATIN SMALL LETTER R
0x295F  0x24AE  # PARENTHESIZED LATIN SMALL LETTER S
0x2960  0x24AF  # PARENTHESIZED LATIN SMALL LETTER T
0x2961  0x24B0  # PARENTHESIZED LATIN SMALL LETTER U
0x2962  0x24B1  # PARENTHESIZED LATIN SMALL LETTER V
0x2963  0x24B2  # PARENTHESIZED LATIN SMALL LETTER W
0x2964  0x24B3  # PARENTHESIZED LATIN SMALL LETTER X
0x2965  0x24B4  # PARENTHESIZED LATIN SMALL LETTER Y
0x2966  0x24B5  # PARENTHESIZED LATIN SMALL LETTER Z
0x2967  0x2474  # PARENTHESIZED DIGIT ONE
0x2968  0x2475  # PARENTHESIZED DIGIT TWO
0x2969  0x2476  # PARENTHESIZED DIGIT THREE
0x296A  0x2477  # PARENTHESIZED DIGIT FOUR
0x296B  0x2478  # PARENTHESIZED DIGIT FIVE
0x296C  0x2479  # PARENTHESIZED DIGIT SIX
0x296D  0x247A  # PARENTHESIZED DIGIT SEVEN
0x296E  0x247B  # PARENTHESIZED DIGIT EIGHT
0x296F  0x247C  # PARENTHESIZED DIGIT NINE
0x2970  0x247D  # PARENTHESIZED NUMBER TEN
0x2971  0x247E  # PARENTHESIZED NUMBER ELEVEN
0x2972  0x247F  # PARENTHESIZED NUMBER TWELVE
0x2973  0x2480  # PARENTHESIZED NUMBER THIRTEEN
0x2974  0x2481  # PARENTHESIZED NUMBER FOURTEEN
0x2975  0x2482  # PARENTHESIZED NUMBER FIFTEEN
0x2976  0x00B9  # SUPERSCRIPT ONE
0x2977  0x00B2  # SUPERSCRIPT TWO
0x2978  0x00B3  # SUPERSCRIPT THREE
0x2979  0x2074  # SUPERSCRIPT FOUR
0x297A  0x207F  # SUPERSCRIPT LATIN SMALL LETTER N
0x297B  0x2081  # SUBSCRIPT ONE
0x297C  0x2082  # SUBSCRIPT TWO
0x297D  0x2083  # SUBSCRIPT THREE
0x297E  0x2084  # SUBSCRIPT FOUR
0x2A21  0x3041  # HIRAGANA LETTER SMALL A
0x2A22  0x3042  # HIRAGANA LETTER A
0x2A23  0x3043  # HIRAGANA LETTER SMALL I
0x2A24  0x3044  # HIRAGANA LETTER I
0x2A25  0x3045  # HIRAGANA LETTER SMALL U
0x2A26  0x3046  # HIRAGANA LETTER U
0x2A27  0x3047  # HIRAGANA LETTER SMALL E
0x2A28  0x3048  # HIRAGANA LETTER E
0x2A29  0x3049  # HIRAGANA LETTER SMALL O
0x2A2A  0x304A  # HIRAGANA LETTER O
0x2A2B  0x304B  # HIRAGANA LETTER KA
0x2A2C  0x304C  # HIRAGANA LETTER GA
0x2A2D  0x304D  # HIRAGANA LETTER KI
0x2A2E  0x304E  # HIRAGANA LETTER GI
0x2A2F  0x304F  # HIRAGANA LETTER KU
0x2A30  0x3050  # HIRAGANA LETTER GU
0x2A31  0x3051  # HIRAGANA LETTER KE
0x2A32  0x3052  # HIRAGANA LETTER GE
0x2A33  0x3053  # HIRAGANA LETTER KO
0x2A34  0x3054  # HIRAGANA LETTER GO
0x2A35  0x3055  # HIRAGANA LETTER SA
0x2A36  0x3056  # HIRAGANA LETTER ZA
0x2A37  0x3057  # HIRAGANA LETTER SI
0x2A38  0x3058  # HIRAGANA LETTER ZI
0x2A39  0x3059  # HIRAGANA LETTER SU
0x2A3A  0x305A  # HIRAGANA LETTER ZU
0x2A3B  0x305B  # HIRAGANA LETTER SE
0x2A3C  0x305C  # HIRAGANA LETTER ZE
0x2A3D  0x305D  # HIRAGANA LETTER SO
0x2A3E  0x305E  # HIRAGANA LETTER ZO
0x2A3F  0x305F  # HIRAGANA LETTER TA
0x2A40  0x3060  # HIRAGANA LETTER DA
0x2A41  0x3061  # HIRAGANA LETTER TI
0x2A42  0x3062  # HIRAGANA LETTER DI
0x2A43  0x3063  # HIRAGANA LETTER SMALL TU
0x2A44  0x3064  # HIRAGANA LETTER TU
0x2A45  0x3065  # HIRAGANA LETTER DU
0x2A46  0x3066  # HIRAGANA LETTER TE
0x2A47  0x3067  # HIRAGANA LETTER DE
0x2A48  0x3068  # HIRAGANA LETTER TO
0x2A49  0x3069  # HIRAGANA LETTER DO
0x2A4A  0x306A  # HIRAGANA LETTER NA
0x2A4B  0x306B  # HIRAGANA LETTER NI
0x2A4C  0x306C  # HIRAGANA LETTER NU
0x2A4D  0x306D  # HIRAGANA LETTER NE
0x2A4E  0x306E  # HIRAGANA LETTER NO
0x2A4F  0x306F  # HIRAGANA LETTER HA
0x2A50  0x3070  # HIRAGANA LETTER BA
0x2A51  0x3071  # HIRAGANA LETTER PA
0x2A52  0x3072  # HIRAGANA LETTER HI
0x2A53  0x3073  # HIRAGANA LETTER BI
0x2A54  0x3074  # HIRAGANA LETTER PI
0x2A55  0x3075  # HIRAGANA LETTER HU
0x2A56  0x3076  # HIRAGANA LETTER BU
0x2A57  0x3077  # HIRAGANA LETTER PU
0x2A58  0x3078  # HIRAGANA LETTER HE
0x2A59  0x3079  # HIRAGANA LETTER BE
0x2A5A  0x307A  # HIRAGANA LETTER PE
0x2A5B  0x307B  # HIRAGANA LETTER HO
0x2A5C  0x307C  # HIRAGANA LETTER BO
0x2A5D  0x307D  # HIRAGANA LETTER PO
0x2A5E  0x307E  # HIRAGANA LETTER MA
0x2A5F  0x307F  # HIRAGANA LETTER MI
0x2A60  0x3080  # HIRAGANA LETTER MU
0x2A61  0x3081  # HIRAGANA LETTER ME
0x2A62  0x3082  # HIRAGANA LETTER MO
0x2A63  0x3083  # HIRAGANA LETTER SMALL YA
0x2A64  0x3084  # HIRAGANA LETTER YA
0x2A65  0x3085  # HIRAGANA LETTER SMALL YU
0x2A66  0x3086  # HIRAGANA LETTER YU
0x2A67  0x3087  # HIRAGANA LETTER SMALL YO
0x2A68  0x3088  # HIRAGANA LETTER YO
0x2A69  0x3089  # HIRAGANA LETTER RA
0x2A6A  0x308A  # HIRAGANA LETTER RI
0x2A6B  0x308B  # HIRAGANA LETTER RU
0x2A6C  0x308C  # HIRAGANA LETTER RE
0x2A6D  0x308D  # HIRAGANA LETTER RO
0x2A6E  0x308E  # HIRAGANA LETTER SMALL WA
0x2A6F  0x308F  # HIRAGANA LETTER WA
0x2A70  0x3090  # HIRAGANA LETTER WI
0x2A71  0x3091  # HIRAGANA LETTER WE
0x2A72  0x3092  # HIRAGANA LETTER WO
0x2A73  0x3093  # HIRAGANA LETTER N
0x2B21  0x30A1  # KATAKANA LETTER SMALL A
0x2B22  0x30A2  # KATAKANA LETTER A
0x2B23  0x30A3  # KATAKANA LETTER SMALL I
0x2B24  0x30A4  # KATAKANA LETTER I
0x2B25  0x30A5  # KATAKANA LETTER SMALL U
0x2B26  0x30A6  # KATAKANA LETTER U
0x2B27  0x30A7  # KATAKANA LETTER SMALL E
0x2B28  0x30A8  # KATAKANA LETTER E
0x2B29  0x30A9  # KATAKANA LETTER SMALL O
0x2B2A  0x30AA  # KATAKANA LETTER O
0x2B2B  0x30AB  # KATAKANA LETTER KA
0x2B2C  0x30AC  # KATAKANA LETTER GA
0x2B2D  0x30AD  # KATAKANA LETTER KI
0x2B2E  0x30AE  # KATAKANA LETTER GI
0x2B2F  0x30AF  # KATAKANA LETTER KU
0x2B30  0x30B0  # KATAKANA LETTER GU
0x2B31  0x30B1  # KATAKANA LETTER KE
0x2B32  0x30B2  # KATAKANA LETTER GE
0x2B33  0x30B3  # KATAKANA LETTER KO
0x2B34  0x30B4  # KATAKANA LETTER GO
0x2B35  0x30B5  # KATAKANA LETTER SA
0x2B36  0x30B6  # KATAKANA LETTER ZA
0x2B37  0x30B7  # KATAKANA LETTER SI
0x2B38  0x30B8  # KATAKANA LETTER ZI
0x2B39  0x30B9  # KATAKANA LETTER SU
0x2B3A  0x30BA  # KATAKANA LETTER ZU
0x2B3B  0x30BB  # KATAKANA LETTER SE
0x2B3C  0x30BC  # KATAKANA LETTER ZE
0x2B3D  0x30BD  # KATAKANA LETTER SO
0x2B3E  0x30BE  # KATAKANA LETTER ZO
0x2B3F  0x30BF  # KATAKANA LETTER TA
0x2B40  0x30C0  # KATAKANA LETTER DA
0x2B41  0x30C1  # KATAKANA LETTER TI
0x2B42  0x30C2  # KATAKANA LETTER DI
0x2B43  0x30C3  # KATAKANA LETTER SMALL TU
0x2B44  0x30C4  # KATAKANA LETTER TU
0x2B45  0x30C5  # KATAKANA LETTER DU
0x2B46  0x30C6  # KATAKANA LETTER TE
0x2B47  0x30C7  # KATAKANA LETTER DE
0x2B48  0x30C8  # KATAKANA LETTER TO
0x2B49  0x30C9  # KATAKANA LETTER DO
0x2B4A  0x30CA  # KATAKANA LETTER NA
0x2B4B  0x30CB  # KATAKANA LETTER NI
0x2B4C  0x30CC  # KATAKANA LETTER NU
0x2B4D  0x30CD  # KATAKANA LETTER NE
0x2B4E  0x30CE  # KATAKANA LETTER NO
0x2B4F  0x30CF  # KATAKANA LETTER HA
0x2B50  0x30D0  # KATAKANA LETTER BA
0x2B51  0x30D1  # KATAKANA LETTER PA
0x2B52  0x30D2  # KATAKANA LETTER HI
0x2B53  0x30D3  # KATAKANA LETTER BI
0x2B54  0x30D4  # KATAKANA LETTER PI
0x2B55  0x30D5  # KATAKANA LETTER HU
0x2B56  0x30D6  # KATAKANA LETTER BU
0x2B57  0x30D7  # KATAKANA LETTER PU
0x2B58  0x30D8  # KATAKANA LETTER HE
0x2B59  0x30D9  # KATAKANA LETTER BE
0x2B5A  0x30DA  # KATAKANA LETTER PE
0x2B5B  0x30DB  # KATAKANA LETTER HO
0x2B5C  0x30DC  # KATAKANA LETTER BO
0x2B5D  0x30DD  # KATAKANA LETTER PO
0x2B5E  0x30DE  # KATAKANA LETTER MA
0x2B5F  0x30DF  # KATAKANA LETTER MI
0x2B60  0x30E0  # KATAKANA LETTER MU
0x2B61  0x30E1  # KATAKANA LETTER ME
0x2B62  0x30E2  # KATAKANA LETTER MO
0x2B63  0x30E3  # KATAKANA LETTER SMALL YA
0x2B64  0x30E4  # KATAKANA LETTER YA
0x2B65  0x30E5  # KATAKANA LETTER SMALL YU
0x2B66  0x30E6  # KATAKANA LETTER YU
0x2B67  0x30E7  # KATAKANA LETTER SMALL YO
0x2B68  0x30E8  # KATAKANA LETTER YO
0x2B69  0x30E9  # KATAKANA LETTER RA
0x2B6A  0x30EA  # KATAKANA LETTER RI
0x2B6B  0x30EB  # KATAKANA LETTER RU
0x2B6C  0x30EC  # KATAKANA LETTER RE
0x2B6D  0x30ED  # KATAKANA LETTER RO
0x2B6E  0x30EE  # KATAKANA LETTER SMALL WA
0x2B6F  0x30EF  # KATAKANA LETTER WA
0x2B70  0x30F0  # KATAKANA LETTER WI
0x2B71  0x30F1  # KATAKANA LETTER WE
0x2B72  0x30F2  # KATAKANA LETTER WO
0x2B73  0x30F3  # KATAKANA LETTER N
0x2B74  0x30F4  # KATAKANA LETTER VU
0x2B75  0x30F5  # KATAKANA LETTER SMALL KA
0x2B76  0x30F6  # KATAKANA LETTER SMALL KE
0x2C21  0x0410  # CYRILLIC CAPITAL LETTER A
0x2C22  0x0411  # CYRILLIC CAPITAL LETTER BE
0x2C23  0x0412  # CYRILLIC CAPITAL LETTER VE
0x2C24  0x0413  # CYRILLIC CAPITAL LETTER GHE
0x2C25  0x0414  # CYRILLIC CAPITAL LETTER DE
0x2C26  0x0415  # CYRILLIC CAPITAL LETTER IE
0x2C27  0x0401  # CYRILLIC CAPITAL LETTER IO
0x2C28  0x0416  # CYRILLIC CAPITAL LETTER ZHE
0x2C29  0x0417  # CYRILLIC CAPITAL LETTER ZE
0x2C2A  0x0418  # CYRILLIC CAPITAL LETTER I
0x2C2B  0x0419  # CYRILLIC CAPITAL LETTER SHORT I
0x2C2C  0x041A  # CYRILLIC CAPITAL LETTER KA
0x2C2D  0x041B  # CYRILLIC CAPITAL LETTER EL
0x2C2E  0x041C  # CYRILLIC CAPITAL LETTER EM
0x2C2F  0x041D  # CYRILLIC CAPITAL LETTER EN
0x2C30  0x041E  # CYRILLIC CAPITAL LETTER O
0x2C31  0x041F  # CYRILLIC CAPITAL LETTER PE
0x2C32  0x0420  # CYRILLIC CAPITAL LETTER ER
0x2C33  0x0421  # CYRILLIC CAPITAL LETTER ES
0x2C34  0x0422  # CYRILLIC CAPITAL LETTER TE
0x2C35  0x0423  # CYRILLIC CAPITAL LETTER U
0x2C36  0x0424  # CYRILLIC CAPITAL LETTER EF
0x2C37  0x0425  # CYRILLIC CAPITAL LETTER HA
0x2C38  0x0426  # CYRILLIC CAPITAL LETTER TSE
0x2C39  0x0427  # CYRILLIC CAPITAL LETTER CHE
0x2C3A  0x0428  # CYRILLIC CAPITAL LETTER SHA
0x2C3B  0x0429  # CYRILLIC CAPITAL LETTER SHCHA
0x2C3C  0x042A  # CYRILLIC CAPITAL LETTER HARD SIGN
0x2C3D  0x042B  # CYRILLIC CAPITAL LETTER YERU
0x2C3E  0x042C  # CYRILLIC CAPITAL LETTER SOFT SIGN
0x2C3F  0x042D  # CYRILLIC CAPITAL LETTER E
0x2C40  0x042E  # CYRILLIC CAPITAL LETTER YU
0x2C41  0x042F  # CYRILLIC CAPITAL LETTER YA
0x2C51  0x0430  # CYRILLIC SMALL LETTER A
0x2C52  0x0431  # CYRILLIC SMALL LETTER BE
0x2C53  0x0432  # CYRILLIC SMALL LETTER VE
0x2C54  0x0433  # CYRILLIC SMALL LETTER GHE
0x2C55  0x0434  # CYRILLIC SMALL LETTER DE
0x2C56  0x0435  # CYRILLIC SMALL LETTER IE
0x2C57  0x0451  # CYRILLIC SMALL LETTER IO
0x2C58  0x0436  # CYRILLIC SMALL LETTER ZHE
0x2C59  0x0437  # CYRILLIC SMALL LETTER ZE
0x2C5A  0x0438  # CYRILLIC SMALL LETTER I
0x2C5B  0x0439  # CYRILLIC SMALL LETTER SHORT I
0x2C5C  0x043A  # CYRILLIC SMALL LETTER KA
0x2C5D  0x043B  # CYRILLIC SMALL LETTER EL
0x2C5E  0x043C  # CYRILLIC SMALL LETTER EM
0x2C5F  0x043D  # CYRILLIC SMALL LETTER EN
0x2C60  0x043E  # CYRILLIC SMALL LETTER O
0x2C61  0x043F  # CYRILLIC SMALL LETTER PE
0x2C62  0x0440  # CYRILLIC SMALL LETTER ER
0x2C63  0x0441  # CYRILLIC SMALL LETTER ES
0x2C64  0x0442  # CYRILLIC SMALL LETTER TE
0x2C65  0x0443  # CYRILLIC SMALL LETTER U
0x2C66  0x0444  # CYRILLIC SMALL LETTER EF
0x2C67  0x0445  # CYRILLIC SMALL LETTER HA
0x2C68  0x0446  # CYRILLIC SMALL LETTER TSE
0x2C69  0x0447  # CYRILLIC SMALL LETTER CHE
0x2C6A  0x0448  # CYRILLIC SMALL LETTER SHA
0x2C6B  0x0449  # CYRILLIC SMALL LETTER SHCHA
0x2C6C  0x044A  # CYRILLIC SMALL LETTER HARD SIGN
0x2C6D  0x044B  # CYRILLIC SMALL LETTER YERU
0x2C6E  0x044C  # CYRILLIC SMALL LETTER SOFT SIGN
0x2C6F  0x044D  # CYRILLIC SMALL LETTER E
0x2C70  0x044E  # CYRILLIC SMALL LETTER YU
0x2C71  0x044F  # CYRILLIC SMALL LETTER YA
0x3021  0xAC00  # HANGUL SYLLABLE KIYEOK-A
0x3022  0xAC01  # HANGUL SYLLABLE KIYEOK-A-KIYEOK
0x3023  0xAC04  # HANGUL SYLLABLE KIYEOK-A-NIEUN
0x3024  0xAC07  # HANGUL SYLLABLE KIYEOK-A-TIKEUT
0x3025  0xAC08  # HANGUL SYLLABLE KIYEOK-A-RIEUL
0x3026  0xAC09  # HANGUL SYLLABLE KIYEOK-A-RIEULKIYEOK
0x3027  0xAC0A  # HANGUL SYLLABLE KIYEOK-A-RIEULMIEUM
0x3028  0xAC10  # HANGUL SYLLABLE KIYEOK-A-MIEUM
0x3029  0xAC11  # HANGUL SYLLABLE KIYEOK-A-PIEUP
0x302A  0xAC12  # HANGUL SYLLABLE KIYEOK-A-PIEUPSIOS
0x302B  0xAC13  # HANGUL SYLLABLE KIYEOK-A-SIOS
0x302C  0xAC14  # HANGUL SYLLABLE KIYEOK-A-SSANGSIOS
0x302D  0xAC15  # HANGUL SYLLABLE KIYEOK-A-IEUNG
0x302E  0xAC16  # HANGUL SYLLABLE KIYEOK-A-CIEUC
0x302F  0xAC17  # HANGUL SYLLABLE KIYEOK-A-CHIEUCH
0x3030  0xAC19  # HANGUL SYLLABLE KIYEOK-A-THIEUTH
0x3031  0xAC1A  # HANGUL SYLLABLE KIYEOK-A-PHIEUPH
0x3032  0xAC1B  # HANGUL SYLLABLE KIYEOK-A-HIEUH
0x3033  0xAC1C  # HANGUL SYLLABLE KIYEOK-AE
0x3034  0xAC1D  # HANGUL SYLLABLE KIYEOK-AE-KIYEOK
0x3035  0xAC20  # HANGUL SYLLABLE KIYEOK-AE-NIEUN
0x3036  0xAC24  # HANGUL SYLLABLE KIYEOK-AE-RIEUL
0x3037  0xAC2C  # HANGUL SYLLABLE KIYEOK-AE-MIEUM
0x3038  0xAC2D  # HANGUL SYLLABLE KIYEOK-AE-PIEUP
0x3039  0xAC2F  # HANGUL SYLLABLE KIYEOK-AE-SIOS
0x303A  0xAC30  # HANGUL SYLLABLE KIYEOK-AE-SSANGSIOS
0x303B  0xAC31  # HANGUL SYLLABLE KIYEOK-AE-IEUNG
0x303C  0xAC38  # HANGUL SYLLABLE KIYEOK-YA
0x303D  0xAC39  # HANGUL SYLLABLE KIYEOK-YA-KIYEOK
0x303E  0xAC3C  # HANGUL SYLLABLE KIYEOK-YA-NIEUN
0x303F  0xAC40  # HANGUL SYLLABLE KIYEOK-YA-RIEUL
0x3040  0xAC4B  # HANGUL SYLLABLE KIYEOK-YA-SIOS
0x3041  0xAC4D  # HANGUL SYLLABLE KIYEOK-YA-IEUNG
0x3042  0xAC54  # HANGUL SYLLABLE KIYEOK-YAE
0x3043  0xAC58  # HANGUL SYLLABLE KIYEOK-YAE-NIEUN
0x3044  0xAC5C  # HANGUL SYLLABLE KIYEOK-YAE-RIEUL
0x3045  0xAC70  # HANGUL SYLLABLE KIYEOK-EO
0x3046  0xAC71  # HANGUL SYLLABLE KIYEOK-EO-KIYEOK
0x3047  0xAC74  # HANGUL SYLLABLE KIYEOK-EO-NIEUN
0x3048  0xAC77  # HANGUL SYLLABLE KIYEOK-EO-TIKEUT
0x3049  0xAC78  # HANGUL SYLLABLE KIYEOK-EO-RIEUL
0x304A  0xAC7A  # HANGUL SYLLABLE KIYEOK-EO-RIEULMIEUM
0x304B  0xAC80  # HANGUL SYLLABLE KIYEOK-EO-MIEUM
0x304C  0xAC81  # HANGUL SYLLABLE KIYEOK-EO-PIEUP
0x304D  0xAC83  # HANGUL SYLLABLE KIYEOK-EO-SIOS
0x304E  0xAC84  # HANGUL SYLLABLE KIYEOK-EO-SSANGSIOS
0x304F  0xAC85  # HANGUL SYLLABLE KIYEOK-EO-IEUNG
0x3050  0xAC86  # HANGUL SYLLABLE KIYEOK-EO-CIEUC
0x3051  0xAC89  # HANGUL SYLLABLE KIYEOK-EO-THIEUTH
0x3052  0xAC8A  # HANGUL SYLLABLE KIYEOK-EO-PHIEUPH
0x3053  0xAC8B  # HANGUL SYLLABLE KIYEOK-EO-HIEUH
0x3054  0xAC8C  # HANGUL SYLLABLE KIYEOK-E
0x3055  0xAC90  # HANGUL SYLLABLE KIYEOK-E-NIEUN
0x3056  0xAC94  # HANGUL SYLLABLE KIYEOK-E-RIEUL
0x3057  0xAC9C  # HANGUL SYLLABLE KIYEOK-E-MIEUM
0x3058  0xAC9D  # HANGUL SYLLABLE KIYEOK-E-PIEUP
0x3059  0xAC9F  # HANGUL SYLLABLE KIYEOK-E-SIOS
0x305A  0xACA0  # HANGUL SYLLABLE KIYEOK-E-SSANGSIOS
0x305B  0xACA1  # HANGUL SYLLABLE KIYEOK-E-IEUNG
0x305C  0xACA8  # HANGUL SYLLABLE KIYEOK-YEO
0x305D  0xACA9  # HANGUL SYLLABLE KIYEOK-YEO-KIYEOK
0x305E  0xACAA  # HANGUL SYLLABLE KIYEOK-YEO-SSANGKIYEOK
0x305F  0xACAC  # HANGUL SYLLABLE KIYEOK-YEO-NIEUN
0x3060  0xACAF  # HANGUL SYLLABLE KIYEOK-YEO-TIKEUT
0x3061  0xACB0  # HANGUL SYLLABLE KIYEOK-YEO-RIEUL
0x3062  0xACB8  # HANGUL SYLLABLE KIYEOK-YEO-MIEUM
0x3063  0xACB9  # HANGUL SYLLABLE KIYEOK-YEO-PIEUP
0x3064  0xACBB  # HANGUL SYLLABLE KIYEOK-YEO-SIOS
0x3065  0xACBC  # HANGUL SYLLABLE KIYEOK-YEO-SSANGSIOS
0x3066  0xACBD  # HANGUL SYLLABLE KIYEOK-YEO-IEUNG
0x3067  0xACC1  # HANGUL SYLLABLE KIYEOK-YEO-THIEUTH
0x3068  0xACC4  # HANGUL SYLLABLE KIYEOK-YE
0x3069  0xACC8  # HANGUL SYLLABLE KIYEOK-YE-NIEUN
0x306A  0xACCC  # HANGUL SYLLABLE KIYEOK-YE-RIEUL
0x306B  0xACD5  # HANGUL SYLLABLE KIYEOK-YE-PIEUP
0x306C  0xACD7  # HANGUL SYLLABLE KIYEOK-YE-SIOS
0x306D  0xACE0  # HANGUL SYLLABLE KIYEOK-O
0x306E  0xACE1  # HANGUL SYLLABLE KIYEOK-O-KIYEOK
0x306F  0xACE4  # HANGUL SYLLABLE KIYEOK-O-NIEUN
0x3070  0xACE7  # HANGUL SYLLABLE KIYEOK-O-TIKEUT
0x3071  0xACE8  # HANGUL SYLLABLE KIYEOK-O-RIEUL
0x3072  0xACEA  # HANGUL SYLLABLE KIYEOK-O-RIEULMIEUM
0x3073  0xACEC  # HANGUL SYLLABLE KIYEOK-O-RIEULSIOS
0x3074  0xACEF  # HANGUL SYLLABLE KIYEOK-O-RIEULHIEUH
0x3075  0xACF0  # HANGUL SYLLABLE KIYEOK-O-MIEUM
0x3076  0xACF1  # HANGUL SYLLABLE KIYEOK-O-PIEUP
0x3077  0xACF3  # HANGUL SYLLABLE KIYEOK-O-SIOS
0x3078  0xACF5  # HANGUL SYLLABLE KIYEOK-O-IEUNG
0x3079  0xACF6  # HANGUL SYLLABLE KIYEOK-O-CIEUC
0x307A  0xACFC  # HANGUL SYLLABLE KIYEOK-WA
0x307B  0xACFD  # HANGUL SYLLABLE KIYEOK-WA-KIYEOK
0x307C  0xAD00  # HANGUL SYLLABLE KIYEOK-WA-NIEUN
0x307D  0xAD04  # HANGUL SYLLABLE KIYEOK-WA-RIEUL
0x307E  0xAD06  # HANGUL SYLLABLE KIYEOK-WA-RIEULMIEUM
0x3121  0xAD0C  # HANGUL SYLLABLE KIYEOK-WA-MIEUM
0x3122  0xAD0D  # HANGUL SYLLABLE KIYEOK-WA-PIEUP
0x3123  0xAD0F  # HANGUL SYLLABLE KIYEOK-WA-SIOS
0x3124  0xAD11  # HANGUL SYLLABLE KIYEOK-WA-IEUNG
0x3125  0xAD18  # HANGUL SYLLABLE KIYEOK-WAE
0x3126  0xAD1C  # HANGUL SYLLABLE KIYEOK-WAE-NIEUN
0x3127  0xAD20  # HANGUL SYLLABLE KIYEOK-WAE-RIEUL
0x3128  0xAD29  # HANGUL SYLLABLE KIYEOK-WAE-PIEUP
0x3129  0xAD2C  # HANGUL SYLLABLE KIYEOK-WAE-SSANGSIOS
0x312A  0xAD2D  # HANGUL SYLLABLE KIYEOK-WAE-IEUNG
0x312B  0xAD34  # HANGUL SYLLABLE KIYEOK-OE
0x312C  0xAD35  # HANGUL SYLLABLE KIYEOK-OE-KIYEOK
0x312D  0xAD38  # HANGUL SYLLABLE KIYEOK-OE-NIEUN
0x312E  0xAD3C  # HANGUL SYLLABLE KIYEOK-OE-RIEUL
0x312F  0xAD44  # HANGUL SYLLABLE KIYEOK-OE-MIEUM
0x3130  0xAD45  # HANGUL SYLLABLE KIYEOK-OE-PIEUP
0x3131  0xAD47  # HANGUL SYLLABLE KIYEOK-OE-SIOS
0x3132  0xAD49  # HANGUL SYLLABLE KIYEOK-OE-IEUNG
0x3133  0xAD50  # HANGUL SYLLABLE KIYEOK-YO
0x3134  0xAD54  # HANGUL SYLLABLE KIYEOK-YO-NIEUN
0x3135  0xAD58  # HANGUL SYLLABLE KIYEOK-YO-RIEUL
0x3136  0xAD61  # HANGUL SYLLABLE KIYEOK-YO-PIEUP
0x3137  0xAD63  # HANGUL SYLLABLE KIYEOK-YO-SIOS
0x3138  0xAD6C  # HANGUL SYLLABLE KIYEOK-U
0x3139  0xAD6D  # HANGUL SYLLABLE KIYEOK-U-KIYEOK
0x313A  0xAD70  # HANGUL SYLLABLE KIYEOK-U-NIEUN
0x313B  0xAD73  # HANGUL SYLLABLE KIYEOK-U-TIKEUT
0x313C  0xAD74  # HANGUL SYLLABLE KIYEOK-U-RIEUL
0x313D  0xAD75  # HANGUL SYLLABLE KIYEOK-U-RIEULKIYEOK
0x313E  0xAD76  # HANGUL SYLLABLE KIYEOK-U-RIEULMIEUM
0x313F  0xAD7B  # HANGUL SYLLABLE KIYEOK-U-RIEULHIEUH
0x3140  0xAD7C  # HANGUL SYLLABLE KIYEOK-U-MIEUM
0x3141  0xAD7D  # HANGUL SYLLABLE KIYEOK-U-PIEUP
0x3142  0xAD7F  # HANGUL SYLLABLE KIYEOK-U-SIOS
0x3143  0xAD81  # HANGUL SYLLABLE KIYEOK-U-IEUNG
0x3144  0xAD82  # HANGUL SYLLABLE KIYEOK-U-CIEUC
0x3145  0xAD88  # HANGUL SYLLABLE KIYEOK-WEO
0x3146  0xAD89  # HANGUL SYLLABLE KIYEOK-WEO-KIYEOK
0x3147  0xAD8C  # HANGUL SYLLABLE KIYEOK-WEO-NIEUN
0x3148  0xAD90  # HANGUL SYLLABLE KIYEOK-WEO-RIEUL
0x3149  0xAD9C  # HANGUL SYLLABLE KIYEOK-WEO-SSANGSIOS
0x314A  0xAD9D  # HANGUL SYLLABLE KIYEOK-WEO-IEUNG
0x314B  0xADA4  # HANGUL SYLLABLE KIYEOK-WE
0x314C  0xADB7  # HANGUL SYLLABLE KIYEOK-WE-SIOS
0x314D  0xADC0  # HANGUL SYLLABLE KIYEOK-WI
0x314E  0xADC1  # HANGUL SYLLABLE KIYEOK-WI-KIYEOK
0x314F  0xADC4  # HANGUL SYLLABLE KIYEOK-WI-NIEUN
0x3150  0xADC8  # HANGUL SYLLABLE KIYEOK-WI-RIEUL
0x3151  0xADD0  # HANGUL SYLLABLE KIYEOK-WI-MIEUM
0x3152  0xADD1  # HANGUL SYLLABLE KIYEOK-WI-PIEUP
0x3153  0xADD3  # HANGUL SYLLABLE KIYEOK-WI-SIOS
0x3154  0xADDC  # HANGUL SYLLABLE KIYEOK-YU
0x3155  0xADE0  # HANGUL SYLLABLE KIYEOK-YU-NIEUN
0x3156  0xADE4  # HANGUL SYLLABLE KIYEOK-YU-RIEUL
0x3157  0xADF8  # HANGUL SYLLABLE KIYEOK-EU
0x3158  0xADF9  # HANGUL SYLLABLE KIYEOK-EU-KIYEOK
0x3159  0xADFC  # HANGUL SYLLABLE KIYEOK-EU-NIEUN
0x315A  0xADFF  # HANGUL SYLLABLE KIYEOK-EU-TIKEUT
0x315B  0xAE00  # HANGUL SYLLABLE KIYEOK-EU-RIEUL
0x315C  0xAE01  # HANGUL SYLLABLE KIYEOK-EU-RIEULKIYEOK
0x315D  0xAE08  # HANGUL SYLLABLE KIYEOK-EU-MIEUM
0x315E  0xAE09  # HANGUL SYLLABLE KIYEOK-EU-PIEUP
0x315F  0xAE0B  # HANGUL SYLLABLE KIYEOK-EU-SIOS
0x3160  0xAE0D  # HANGUL SYLLABLE KIYEOK-EU-IEUNG
0x3161  0xAE14  # HANGUL SYLLABLE KIYEOK-YI
0x3162  0xAE30  # HANGUL SYLLABLE KIYEOK-I
0x3163  0xAE31  # HANGUL SYLLABLE KIYEOK-I-KIYEOK
0x3164  0xAE34  # HANGUL SYLLABLE KIYEOK-I-NIEUN
0x3165  0xAE37  # HANGUL SYLLABLE KIYEOK-I-TIKEUT
0x3166  0xAE38  # HANGUL SYLLABLE KIYEOK-I-RIEUL
0x3167  0xAE3A  # HANGUL SYLLABLE KIYEOK-I-RIEULMIEUM
0x3168  0xAE40  # HANGUL SYLLABLE KIYEOK-I-MIEUM
0x3169  0xAE41  # HANGUL SYLLABLE KIYEOK-I-PIEUP
0x316A  0xAE43  # HANGUL SYLLABLE KIYEOK-I-SIOS
0x316B  0xAE45  # HANGUL SYLLABLE KIYEOK-I-IEUNG
0x316C  0xAE46  # HANGUL SYLLABLE KIYEOK-I-CIEUC
0x316D  0xAE4A  # HANGUL SYLLABLE KIYEOK-I-PHIEUPH
0x316E  0xAE4C  # HANGUL SYLLABLE SSANGKIYEOK-A
0x316F  0xAE4D  # HANGUL SYLLABLE SSANGKIYEOK-A-KIYEOK
0x3170  0xAE4E  # HANGUL SYLLABLE SSANGKIYEOK-A-SSANGKIYEOK
0x3171  0xAE50  # HANGUL SYLLABLE SSANGKIYEOK-A-NIEUN
0x3172  0xAE54  # HANGUL SYLLABLE SSANGKIYEOK-A-RIEUL
0x3173  0xAE56  # HANGUL SYLLABLE SSANGKIYEOK-A-RIEULMIEUM
0x3174  0xAE5C  # HANGUL SYLLABLE SSANGKIYEOK-A-MIEUM
0x3175  0xAE5D  # HANGUL SYLLABLE SSANGKIYEOK-A-PIEUP
0x3176  0xAE5F  # HANGUL SYLLABLE SSANGKIYEOK-A-SIOS
0x3177  0xAE60  # HANGUL SYLLABLE SSANGKIYEOK-A-SSANGSIOS
0x3178  0xAE61  # HANGUL SYLLABLE SSANGKIYEOK-A-IEUNG
0x3179  0xAE65  # HANGUL SYLLABLE SSANGKIYEOK-A-THIEUTH
0x317A  0xAE68  # HANGUL SYLLABLE SSANGKIYEOK-AE
0x317B  0xAE69  # HANGUL SYLLABLE SSANGKIYEOK-AE-KIYEOK
0x317C  0xAE6C  # HANGUL SYLLABLE SSANGKIYEOK-AE-NIEUN
0x317D  0xAE70  # HANGUL SYLLABLE SSANGKIYEOK-AE-RIEUL
0x317E  0xAE78  # HANGUL SYLLABLE SSANGKIYEOK-AE-MIEUM
0x3221  0xAE79  # HANGUL SYLLABLE SSANGKIYEOK-AE-PIEUP
0x3222  0xAE7B  # HANGUL SYLLABLE SSANGKIYEOK-AE-SIOS
0x3223  0xAE7C  # HANGUL SYLLABLE SSANGKIYEOK-AE-SSANGSIOS
0x3224  0xAE7D  # HANGUL SYLLABLE SSANGKIYEOK-AE-IEUNG
0x3225  0xAE84  # HANGUL SYLLABLE SSANGKIYEOK-YA
0x3226  0xAE85  # HANGUL SYLLABLE SSANGKIYEOK-YA-KIYEOK
0x3227  0xAE8C  # HANGUL SYLLABLE SSANGKIYEOK-YA-RIEUL
0x3228  0xAEBC  # HANGUL SYLLABLE SSANGKIYEOK-EO
0x3229  0xAEBD  # HANGUL SYLLABLE SSANGKIYEOK-EO-KIYEOK
0x322A  0xAEBE  # HANGUL SYLLABLE SSANGKIYEOK-EO-SSANGKIYEOK
0x322B  0xAEC0  # HANGUL SYLLABLE SSANGKIYEOK-EO-NIEUN
0x322C  0xAEC4  # HANGUL SYLLABLE SSANGKIYEOK-EO-RIEUL
0x322D  0xAECC  # HANGUL SYLLABLE SSANGKIYEOK-EO-MIEUM
0x322E  0xAECD  # HANGUL SYLLABLE SSANGKIYEOK-EO-PIEUP
0x322F  0xAECF  # HANGUL SYLLABLE SSANGKIYEOK-EO-SIOS
0x3230  0xAED0  # HANGUL SYLLABLE SSANGKIYEOK-EO-SSANGSIOS
0x3231  0xAED1  # HANGUL SYLLABLE SSANGKIYEOK-EO-IEUNG
0x3232  0xAED8  # HANGUL SYLLABLE SSANGKIYEOK-E
0x3233  0xAED9  # HANGUL SYLLABLE SSANGKIYEOK-E-KIYEOK
0x3234  0xAEDC  # HANGUL SYLLABLE SSANGKIYEOK-E-NIEUN
0x3235  0xAEE8  # HANGUL SYLLABLE SSANGKIYEOK-E-MIEUM
0x3236  0xAEEB  # HANGUL SYLLABLE SSANGKIYEOK-E-SIOS
0x3237  0xAEED  # HANGUL SYLLABLE SSANGKIYEOK-E-IEUNG
0x3238  0xAEF4  # HANGUL SYLLABLE SSANGKIYEOK-YEO
0x3239  0xAEF8  # HANGUL SYLLABLE SSANGKIYEOK-YEO-NIEUN
0x323A  0xAEFC  # HANGUL SYLLABLE SSANGKIYEOK-YEO-RIEUL
0x323B  0xAF07  # HANGUL SYLLABLE SSANGKIYEOK-YEO-SIOS
0x323C  0xAF08  # HANGUL SYLLABLE SSANGKIYEOK-YEO-SSANGSIOS
0x323D  0xAF0D  # HANGUL SYLLABLE SSANGKIYEOK-YEO-THIEUTH
0x323E  0xAF10  # HANGUL SYLLABLE SSANGKIYEOK-YE
0x323F  0xAF2C  # HANGUL SYLLABLE SSANGKIYEOK-O
0x3240  0xAF2D  # HANGUL SYLLABLE SSANGKIYEOK-O-KIYEOK
0x3241  0xAF30  # HANGUL SYLLABLE SSANGKIYEOK-O-NIEUN
0x3242  0xAF32  # HANGUL SYLLABLE SSANGKIYEOK-O-NIEUNHIEUH
0x3243  0xAF34  # HANGUL SYLLABLE SSANGKIYEOK-O-RIEUL
0x3244  0xAF3C  # HANGUL SYLLABLE SSANGKIYEOK-O-MIEUM
0x3245  0xAF3D  # HANGUL SYLLABLE SSANGKIYEOK-O-PIEUP
0x3246  0xAF3F  # HANGUL SYLLABLE SSANGKIYEOK-O-SIOS
0x3247  0xAF41  # HANGUL SYLLABLE SSANGKIYEOK-O-IEUNG
0x3248  0xAF42  # HANGUL SYLLABLE SSANGKIYEOK-O-CIEUC
0x3249  0xAF43  # HANGUL SYLLABLE SSANGKIYEOK-O-CHIEUCH
0x324A  0xAF48  # HANGUL SYLLABLE SSANGKIYEOK-WA
0x324B  0xAF49  # HANGUL SYLLABLE SSANGKIYEOK-WA-KIYEOK
0x324C  0xAF50  # HANGUL SYLLABLE SSANGKIYEOK-WA-RIEUL
0x324D  0xAF5C  # HANGUL SYLLABLE SSANGKIYEOK-WA-SSANGSIOS
0x324E  0xAF5D  # HANGUL SYLLABLE SSANGKIYEOK-WA-IEUNG
0x324F  0xAF64  # HANGUL SYLLABLE SSANGKIYEOK-WAE
0x3250  0xAF65  # HANGUL SYLLABLE SSANGKIYEOK-WAE-KIYEOK
0x3251  0xAF79  # HANGUL SYLLABLE SSANGKIYEOK-WAE-IEUNG
0x3252  0xAF80  # HANGUL SYLLABLE SSANGKIYEOK-OE
0x3253  0xAF84  # HANGUL SYLLABLE SSANGKIYEOK-OE-NIEUN
0x3254  0xAF88  # HANGUL SYLLABLE SSANGKIYEOK-OE-RIEUL
0x3255  0xAF90  # HANGUL SYLLABLE SSANGKIYEOK-OE-MIEUM
0x3256  0xAF91  # HANGUL SYLLABLE SSANGKIYEOK-OE-PIEUP
0x3257  0xAF95  # HANGUL SYLLABLE SSANGKIYEOK-OE-IEUNG
0x3258  0xAF9C  # HANGUL SYLLABLE SSANGKIYEOK-YO
0x3259  0xAFB8  # HANGUL SYLLABLE SSANGKIYEOK-U
0x325A  0xAFB9  # HANGUL SYLLABLE SSANGKIYEOK-U-KIYEOK
0x325B  0xAFBC  # HANGUL SYLLABLE SSANGKIYEOK-U-NIEUN
0x325C  0xAFC0  # HANGUL SYLLABLE SSANGKIYEOK-U-RIEUL
0x325D  0xAFC7  # HANGUL SYLLABLE SSANGKIYEOK-U-RIEULHIEUH
0x325E  0xAFC8  # HANGUL SYLLABLE SSANGKIYEOK-U-MIEUM
0x325F  0xAFC9  # HANGUL SYLLABLE SSANGKIYEOK-U-PIEUP
0x3260  0xAFCB  # HANGUL SYLLABLE SSANGKIYEOK-U-SIOS
0x3261  0xAFCD  # HANGUL SYLLABLE SSANGKIYEOK-U-IEUNG
0x3262  0xAFCE  # HANGUL SYLLABLE SSANGKIYEOK-U-CIEUC
0x3263  0xAFD4  # HANGUL SYLLABLE SSANGKIYEOK-WEO
0x3264  0xAFDC  # HANGUL SYLLABLE SSANGKIYEOK-WEO-RIEUL
0x3265  0xAFE8  # HANGUL SYLLABLE SSANGKIYEOK-WEO-SSANGSIOS
0x3266  0xAFE9  # HANGUL SYLLABLE SSANGKIYEOK-WEO-IEUNG
0x3267  0xAFF0  # HANGUL SYLLABLE SSANGKIYEOK-WE
0x3268  0xAFF1  # HANGUL SYLLABLE SSANGKIYEOK-WE-KIYEOK
0x3269  0xAFF4  # HANGUL SYLLABLE SSANGKIYEOK-WE-NIEUN
0x326A  0xAFF8  # HANGUL SYLLABLE SSANGKIYEOK-WE-RIEUL
0x326B  0xB000  # HANGUL SYLLABLE SSANGKIYEOK-WE-MIEUM
0x326C  0xB001  # HANGUL SYLLABLE SSANGKIYEOK-WE-PIEUP
0x326D  0xB004  # HANGUL SYLLABLE SSANGKIYEOK-WE-SSANGSIOS
0x326E  0xB00C  # HANGUL SYLLABLE SSANGKIYEOK-WI
0x326F  0xB010  # HANGUL SYLLABLE SSANGKIYEOK-WI-NIEUN
0x3270  0xB014  # HANGUL SYLLABLE SSANGKIYEOK-WI-RIEUL
0x3271  0xB01C  # HANGUL SYLLABLE SSANGKIYEOK-WI-MIEUM
0x3272  0xB01D  # HANGUL SYLLABLE SSANGKIYEOK-WI-PIEUP
0x3273  0xB028  # HANGUL SYLLABLE SSANGKIYEOK-YU
0x3274  0xB044  # HANGUL SYLLABLE SSANGKIYEOK-EU
0x3275  0xB045  # HANGUL SYLLABLE SSANGKIYEOK-EU-KIYEOK
0x3276  0xB048  # HANGUL SYLLABLE SSANGKIYEOK-EU-NIEUN
0x3277  0xB04A  # HANGUL SYLLABLE SSANGKIYEOK-EU-NIEUNHIEUH
0x3278  0xB04C  # HANGUL SYLLABLE SSANGKIYEOK-EU-RIEUL
0x3279  0xB04E  # HANGUL SYLLABLE SSANGKIYEOK-EU-RIEULMIEUM
0x327A  0xB053  # HANGUL SYLLABLE SSANGKIYEOK-EU-RIEULHIEUH
0x327B  0xB054  # HANGUL SYLLABLE SSANGKIYEOK-EU-MIEUM
0x327C  0xB055  # HANGUL SYLLABLE SSANGKIYEOK-EU-PIEUP
0x327D  0xB057  # HANGUL SYLLABLE SSANGKIYEOK-EU-SIOS
0x327E  0xB059  # HANGUL SYLLABLE SSANGKIYEOK-EU-IEUNG
0x3321  0xB05D  # HANGUL SYLLABLE SSANGKIYEOK-EU-THIEUTH
0x3322  0xB07C  # HANGUL SYLLABLE SSANGKIYEOK-I
0x3323  0xB07D  # HANGUL SYLLABLE SSANGKIYEOK-I-KIYEOK
0x3324  0xB080  # HANGUL SYLLABLE SSANGKIYEOK-I-NIEUN
0x3325  0xB084  # HANGUL SYLLABLE SSANGKIYEOK-I-RIEUL
0x3326  0xB08C  # HANGUL SYLLABLE SSANGKIYEOK-I-MIEUM
0x3327  0xB08D  # HANGUL SYLLABLE SSANGKIYEOK-I-PIEUP
0x3328  0xB08F  # HANGUL SYLLABLE SSANGKIYEOK-I-SIOS
0x3329  0xB091  # HANGUL SYLLABLE SSANGKIYEOK-I-IEUNG
0x332A  0xB098  # HANGUL SYLLABLE NIEUN-A
0x332B  0xB099  # HANGUL SYLLABLE NIEUN-A-KIYEOK
0x332C  0xB09A  # HANGUL SYLLABLE NIEUN-A-SSANGKIYEOK
0x332D  0xB09C  # HANGUL SYLLABLE NIEUN-A-NIEUN
0x332E  0xB09F  # HANGUL SYLLABLE NIEUN-A-TIKEUT
0x332F  0xB0A0  # HANGUL SYLLABLE NIEUN-A-RIEUL
0x3330  0xB0A1  # HANGUL SYLLABLE NIEUN-A-RIEULKIYEOK
0x3331  0xB0A2  # HANGUL SYLLABLE NIEUN-A-RIEULMIEUM
0x3332  0xB0A8  # HANGUL SYLLABLE NIEUN-A-MIEUM
0x3333  0xB0A9  # HANGUL SYLLABLE NIEUN-A-PIEUP
0x3334  0xB0AB  # HANGUL SYLLABLE NIEUN-A-SIOS
0x3335  0xB0AC  # HANGUL SYLLABLE NIEUN-A-SSANGSIOS
0x3336  0xB0AD  # HANGUL SYLLABLE NIEUN-A-IEUNG
0x3337  0xB0AE  # HANGUL SYLLABLE NIEUN-A-CIEUC
0x3338  0xB0AF  # HANGUL SYLLABLE NIEUN-A-CHIEUCH
0x3339  0xB0B1  # HANGUL SYLLABLE NIEUN-A-THIEUTH
0x333A  0xB0B3  # HANGUL SYLLABLE NIEUN-A-HIEUH
0x333B  0xB0B4  # HANGUL SYLLABLE NIEUN-AE
0x333C  0xB0B5  # HANGUL SYLLABLE NIEUN-AE-KIYEOK
0x333D  0xB0B8  # HANGUL SYLLABLE NIEUN-AE-NIEUN
0x333E  0xB0BC  # HANGUL SYLLABLE NIEUN-AE-RIEUL
0x333F  0xB0C4  # HANGUL SYLLABLE NIEUN-AE-MIEUM
0x3340  0xB0C5  # HANGUL SYLLABLE NIEUN-AE-PIEUP
0x3341  0xB0C7  # HANGUL SYLLABLE NIEUN-AE-SIOS
0x3342  0xB0C8  # HANGUL SYLLABLE NIEUN-AE-SSANGSIOS
0x3343  0xB0C9  # HANGUL SYLLABLE NIEUN-AE-IEUNG
0x3344  0xB0D0  # HANGUL SYLLABLE NIEUN-YA
0x3345  0xB0D1  # HANGUL SYLLABLE NIEUN-YA-KIYEOK
0x3346  0xB0D4  # HANGUL SYLLABLE NIEUN-YA-NIEUN
0x3347  0xB0D8  # HANGUL SYLLABLE NIEUN-YA-RIEUL
0x3348  0xB0E0  # HANGUL SYLLABLE NIEUN-YA-MIEUM
0x3349  0xB0E5  # HANGUL SYLLABLE NIEUN-YA-IEUNG
0x334A  0xB108  # HANGUL SYLLABLE NIEUN-EO
0x334B  0xB109  # HANGUL SYLLABLE NIEUN-EO-KIYEOK
0x334C  0xB10B  # HANGUL SYLLABLE NIEUN-EO-KIYEOKSIOS
0x334D  0xB10C  # HANGUL SYLLABLE NIEUN-EO-NIEUN
0x334E  0xB110  # HANGUL SYLLABLE NIEUN-EO-RIEUL
0x334F  0xB112  # HANGUL SYLLABLE NIEUN-EO-RIEULMIEUM
0x3350  0xB113  # HANGUL SYLLABLE NIEUN-EO-RIEULPIEUP
0x3351  0xB118  # HANGUL SYLLABLE NIEUN-EO-MIEUM
0x3352  0xB119  # HANGUL SYLLABLE NIEUN-EO-PIEUP
0x3353  0xB11B  # HANGUL SYLLABLE NIEUN-EO-SIOS
0x3354  0xB11C  # HANGUL SYLLABLE NIEUN-EO-SSANGSIOS
0x3355  0xB11D  # HANGUL SYLLABLE NIEUN-EO-IEUNG
0x3356  0xB123  # HANGUL SYLLABLE NIEUN-EO-HIEUH
0x3357  0xB124  # HANGUL SYLLABLE NIEUN-E
0x3358  0xB125  # HANGUL SYLLABLE NIEUN-E-KIYEOK
0x3359  0xB128  # HANGUL SYLLABLE NIEUN-E-NIEUN
0x335A  0xB12C  # HANGUL SYLLABLE NIEUN-E-RIEUL
0x335B  0xB134  # HANGUL SYLLABLE NIEUN-E-MIEUM
0x335C  0xB135  # HANGUL SYLLABLE NIEUN-E-PIEUP
0x335D  0xB137  # HANGUL SYLLABLE NIEUN-E-SIOS
0x335E  0xB138  # HANGUL SYLLABLE NIEUN-E-SSANGSIOS
0x335F  0xB139  # HANGUL SYLLABLE NIEUN-E-IEUNG
0x3360  0xB140  # HANGUL SYLLABLE NIEUN-YEO
0x3361  0xB141  # HANGUL SYLLABLE NIEUN-YEO-KIYEOK
0x3362  0xB144  # HANGUL SYLLABLE NIEUN-YEO-NIEUN
0x3363  0xB148  # HANGUL SYLLABLE NIEUN-YEO-RIEUL
0x3364  0xB150  # HANGUL SYLLABLE NIEUN-YEO-MIEUM
0x3365  0xB151  # HANGUL SYLLABLE NIEUN-YEO-PIEUP
0x3366  0xB154  # HANGUL SYLLABLE NIEUN-YEO-SSANGSIOS
0x3367  0xB155  # HANGUL SYLLABLE NIEUN-YEO-IEUNG
0x3368  0xB158  # HANGUL SYLLABLE NIEUN-YEO-KHIEUKH
0x3369  0xB15C  # HANGUL SYLLABLE NIEUN-YE
0x336A  0xB160  # HANGUL SYLLABLE NIEUN-YE-NIEUN
0x336B  0xB178  # HANGUL SYLLABLE NIEUN-O
0x336C  0xB179  # HANGUL SYLLABLE NIEUN-O-KIYEOK
0x336D  0xB17C  # HANGUL SYLLABLE NIEUN-O-NIEUN
0x336E  0xB180  # HANGUL SYLLABLE NIEUN-O-RIEUL
0x336F  0xB182  # HANGUL SYLLABLE NIEUN-O-RIEULMIEUM
0x3370  0xB188  # HANGUL SYLLABLE NIEUN-O-MIEUM
0x3371  0xB189  # HANGUL SYLLABLE NIEUN-O-PIEUP
0x3372  0xB18B  # HANGUL SYLLABLE NIEUN-O-SIOS
0x3373  0xB18D  # HANGUL SYLLABLE NIEUN-O-IEUNG
0x3374  0xB192  # HANGUL SYLLABLE NIEUN-O-PHIEUPH
0x3375  0xB193  # HANGUL SYLLABLE NIEUN-O-HIEUH
0x3376  0xB194  # HANGUL SYLLABLE NIEUN-WA
0x3377  0xB198  # HANGUL SYLLABLE NIEUN-WA-NIEUN
0x3378  0xB19C  # HANGUL SYLLABLE NIEUN-WA-RIEUL
0x3379  0xB1A8  # HANGUL SYLLABLE NIEUN-WA-SSANGSIOS
0x337A  0xB1CC  # HANGUL SYLLABLE NIEUN-OE
0x337B  0xB1D0  # HANGUL SYLLABLE NIEUN-OE-NIEUN
0x337C  0xB1D4  # HANGUL SYLLABLE NIEUN-OE-RIEUL
0x337D  0xB1DC  # HANGUL SYLLABLE NIEUN-OE-MIEUM
0x337E  0xB1DD  # HANGUL SYLLABLE NIEUN-OE-PIEUP
0x3421  0xB1DF  # HANGUL SYLLABLE NIEUN-OE-SIOS
0x3422  0xB1E8  # HANGUL SYLLABLE NIEUN-YO
0x3423  0xB1E9  # HANGUL SYLLABLE NIEUN-YO-KIYEOK
0x3424  0xB1EC  # HANGUL SYLLABLE NIEUN-YO-NIEUN
0x3425  0xB1F0  # HANGUL SYLLABLE NIEUN-YO-RIEUL
0x3426  0xB1F9  # HANGUL SYLLABLE NIEUN-YO-PIEUP
0x3427  0xB1FB  # HANGUL SYLLABLE NIEUN-YO-SIOS
0x3428  0xB1FD  # HANGUL SYLLABLE NIEUN-YO-IEUNG
0x3429  0xB204  # HANGUL SYLLABLE NIEUN-U
0x342A  0xB205  # HANGUL SYLLABLE NIEUN-U-KIYEOK
0x342B  0xB208  # HANGUL SYLLABLE NIEUN-U-NIEUN
0x342C  0xB20B  # HANGUL SYLLABLE NIEUN-U-TIKEUT
0x342D  0xB20C  # HANGUL SYLLABLE NIEUN-U-RIEUL
0x342E  0xB214  # HANGUL SYLLABLE NIEUN-U-MIEUM
0x342F  0xB215  # HANGUL SYLLABLE NIEUN-U-PIEUP
0x3430  0xB217  # HANGUL SYLLABLE NIEUN-U-SIOS
0x3431  0xB219  # HANGUL SYLLABLE NIEUN-U-IEUNG
0x3432  0xB220  # HANGUL SYLLABLE NIEUN-WEO
0x3433  0xB234  # HANGUL SYLLABLE NIEUN-WEO-SSANGSIOS
0x3434  0xB23C  # HANGUL SYLLABLE NIEUN-WE
0x3435  0xB258  # HANGUL SYLLABLE NIEUN-WI
0x3436  0xB25C  # HANGUL SYLLABLE NIEUN-WI-NIEUN
0x3437  0xB260  # HANGUL SYLLABLE NIEUN-WI-RIEUL
0x3438  0xB268  # HANGUL SYLLABLE NIEUN-WI-MIEUM
0x3439  0xB269  # HANGUL SYLLABLE NIEUN-WI-PIEUP
0x343A  0xB274  # HANGUL SYLLABLE NIEUN-YU
0x343B  0xB275  # HANGUL SYLLABLE NIEUN-YU-KIYEOK
0x343C  0xB27C  # HANGUL SYLLABLE NIEUN-YU-RIEUL
0x343D  0xB284  # HANGUL SYLLABLE NIEUN-YU-MIEUM
0x343E  0xB285  # HANGUL SYLLABLE NIEUN-YU-PIEUP
0x343F  0xB289  # HANGUL SYLLABLE NIEUN-YU-IEUNG
0x3440  0xB290  # HANGUL SYLLABLE NIEUN-EU
0x3441  0xB291  # HANGUL SYLLABLE NIEUN-EU-KIYEOK
0x3442  0xB294  # HANGUL SYLLABLE NIEUN-EU-NIEUN
0x3443  0xB298  # HANGUL SYLLABLE NIEUN-EU-RIEUL
0x3444  0xB299  # HANGUL SYLLABLE NIEUN-EU-RIEULKIYEOK
0x3445  0xB29A  # HANGUL SYLLABLE NIEUN-EU-RIEULMIEUM
0x3446  0xB2A0  # HANGUL SYLLABLE NIEUN-EU-MIEUM
0x3447  0xB2A1  # HANGUL SYLLABLE NIEUN-EU-PIEUP
0x3448  0xB2A3  # HANGUL SYLLABLE NIEUN-EU-SIOS
0x3449  0xB2A5  # HANGUL SYLLABLE NIEUN-EU-IEUNG
0x344A  0xB2A6  # HANGUL SYLLABLE NIEUN-EU-CIEUC
0x344B  0xB2AA  # HANGUL SYLLABLE NIEUN-EU-PHIEUPH
0x344C  0xB2AC  # HANGUL SYLLABLE NIEUN-YI
0x344D  0xB2B0  # HANGUL SYLLABLE NIEUN-YI-NIEUN
0x344E  0xB2B4  # HANGUL SYLLABLE NIEUN-YI-RIEUL
0x344F  0xB2C8  # HANGUL SYLLABLE NIEUN-I
0x3450  0xB2C9  # HANGUL SYLLABLE NIEUN-I-KIYEOK
0x3451  0xB2CC  # HANGUL SYLLABLE NIEUN-I-NIEUN
0x3452  0xB2D0  # HANGUL SYLLABLE NIEUN-I-RIEUL
0x3453  0xB2D2  # HANGUL SYLLABLE NIEUN-I-RIEULMIEUM-<3/22/95>
0x3454  0xB2D8  # HANGUL SYLLABLE NIEUN-I-MIEUM
0x3455  0xB2D9  # HANGUL SYLLABLE NIEUN-I-PIEUP
0x3456  0xB2DB  # HANGUL SYLLABLE NIEUN-I-SIOS
0x3457  0xB2DD  # HANGUL SYLLABLE NIEUN-I-IEUNG
0x3458  0xB2E2  # HANGUL SYLLABLE NIEUN-I-PHIEUPH
0x3459  0xB2E4  # HANGUL SYLLABLE TIKEUT-A
0x345A  0xB2E5  # HANGUL SYLLABLE TIKEUT-A-KIYEOK
0x345B  0xB2E6  # HANGUL SYLLABLE TIKEUT-A-SSANGKIYEOK
0x345C  0xB2E8  # HANGUL SYLLABLE TIKEUT-A-NIEUN
0x345D  0xB2EB  # HANGUL SYLLABLE TIKEUT-A-TIKEUT
0x345E  0xB2EC  # HANGUL SYLLABLE TIKEUT-A-RIEUL
0x345F  0xB2ED  # HANGUL SYLLABLE TIKEUT-A-RIEULKIYEOK
0x3460  0xB2EE  # HANGUL SYLLABLE TIKEUT-A-RIEULMIEUM
0x3461  0xB2EF  # HANGUL SYLLABLE TIKEUT-A-RIEULPIEUP
0x3462  0xB2F3  # HANGUL SYLLABLE TIKEUT-A-RIEULHIEUH
0x3463  0xB2F4  # HANGUL SYLLABLE TIKEUT-A-MIEUM
0x3464  0xB2F5  # HANGUL SYLLABLE TIKEUT-A-PIEUP
0x3465  0xB2F7  # HANGUL SYLLABLE TIKEUT-A-SIOS
0x3466  0xB2F8  # HANGUL SYLLABLE TIKEUT-A-SSANGSIOS
0x3467  0xB2F9  # HANGUL SYLLABLE TIKEUT-A-IEUNG
0x3468  0xB2FA  # HANGUL SYLLABLE TIKEUT-A-CIEUC
0x3469  0xB2FB  # HANGUL SYLLABLE TIKEUT-A-CHIEUCH
0x346A  0xB2FF  # HANGUL SYLLABLE TIKEUT-A-HIEUH
0x346B  0xB300  # HANGUL SYLLABLE TIKEUT-AE
0x346C  0xB301  # HANGUL SYLLABLE TIKEUT-AE-KIYEOK
0x346D  0xB304  # HANGUL SYLLABLE TIKEUT-AE-NIEUN
0x346E  0xB308  # HANGUL SYLLABLE TIKEUT-AE-RIEUL
0x346F  0xB310  # HANGUL SYLLABLE TIKEUT-AE-MIEUM
0x3470  0xB311  # HANGUL SYLLABLE TIKEUT-AE-PIEUP
0x3471  0xB313  # HANGUL SYLLABLE TIKEUT-AE-SIOS
0x3472  0xB314  # HANGUL SYLLABLE TIKEUT-AE-SSANGSIOS
0x3473  0xB315  # HANGUL SYLLABLE TIKEUT-AE-IEUNG
0x3474  0xB31C  # HANGUL SYLLABLE TIKEUT-YA
0x3475  0xB354  # HANGUL SYLLABLE TIKEUT-EO
0x3476  0xB355  # HANGUL SYLLABLE TIKEUT-EO-KIYEOK
0x3477  0xB356  # HANGUL SYLLABLE TIKEUT-EO-SSANGKIYEOK
0x3478  0xB358  # HANGUL SYLLABLE TIKEUT-EO-NIEUN
0x3479  0xB35B  # HANGUL SYLLABLE TIKEUT-EO-TIKEUT
0x347A  0xB35C  # HANGUL SYLLABLE TIKEUT-EO-RIEUL
0x347B  0xB35E  # HANGUL SYLLABLE TIKEUT-EO-RIEULMIEUM
0x347C  0xB35F  # HANGUL SYLLABLE TIKEUT-EO-RIEULPIEUP
0x347D  0xB364  # HANGUL SYLLABLE TIKEUT-EO-MIEUM
0x347E  0xB365  # HANGUL SYLLABLE TIKEUT-EO-PIEUP
0x3521  0xB367  # HANGUL SYLLABLE TIKEUT-EO-SIOS
0x3522  0xB369  # HANGUL SYLLABLE TIKEUT-EO-IEUNG
0x3523  0xB36B  # HANGUL SYLLABLE TIKEUT-EO-CHIEUCH
0x3524  0xB36E  # HANGUL SYLLABLE TIKEUT-EO-PHIEUPH
0x3525  0xB370  # HANGUL SYLLABLE TIKEUT-E
0x3526  0xB371  # HANGUL SYLLABLE TIKEUT-E-KIYEOK
0x3527  0xB374  # HANGUL SYLLABLE TIKEUT-E-NIEUN
0x3528  0xB378  # HANGUL SYLLABLE TIKEUT-E-RIEUL
0x3529  0xB380  # HANGUL SYLLABLE TIKEUT-E-MIEUM
0x352A  0xB381  # HANGUL SYLLABLE TIKEUT-E-PIEUP
0x352B  0xB383  # HANGUL SYLLABLE TIKEUT-E-SIOS
0x352C  0xB384  # HANGUL SYLLABLE TIKEUT-E-SSANGSIOS
0x352D  0xB385  # HANGUL SYLLABLE TIKEUT-E-IEUNG
0x352E  0xB38C  # HANGUL SYLLABLE TIKEUT-YEO
0x352F  0xB390  # HANGUL SYLLABLE TIKEUT-YEO-NIEUN
0x3530  0xB394  # HANGUL SYLLABLE TIKEUT-YEO-RIEUL
0x3531  0xB3A0  # HANGUL SYLLABLE TIKEUT-YEO-SSANGSIOS
0x3532  0xB3A1  # HANGUL SYLLABLE TIKEUT-YEO-IEUNG
0x3533  0xB3A8  # HANGUL SYLLABLE TIKEUT-YE
0x3534  0xB3AC  # HANGUL SYLLABLE TIKEUT-YE-NIEUN
0x3535  0xB3C4  # HANGUL SYLLABLE TIKEUT-O
0x3536  0xB3C5  # HANGUL SYLLABLE TIKEUT-O-KIYEOK
0x3537  0xB3C8  # HANGUL SYLLABLE TIKEUT-O-NIEUN
0x3538  0xB3CB  # HANGUL SYLLABLE TIKEUT-O-TIKEUT
0x3539  0xB3CC  # HANGUL SYLLABLE TIKEUT-O-RIEUL
0x353A  0xB3CE  # HANGUL SYLLABLE TIKEUT-O-RIEULMIEUM
0x353B  0xB3D0  # HANGUL SYLLABLE TIKEUT-O-RIEULSIOS
0x353C  0xB3D4  # HANGUL SYLLABLE TIKEUT-O-MIEUM
0x353D  0xB3D5  # HANGUL SYLLABLE TIKEUT-O-PIEUP
0x353E  0xB3D7  # HANGUL SYLLABLE TIKEUT-O-SIOS
0x353F  0xB3D9  # HANGUL SYLLABLE TIKEUT-O-IEUNG
0x3540  0xB3DB  # HANGUL SYLLABLE TIKEUT-O-CHIEUCH
0x3541  0xB3DD  # HANGUL SYLLABLE TIKEUT-O-THIEUTH
0x3542  0xB3E0  # HANGUL SYLLABLE TIKEUT-WA
0x3543  0xB3E4  # HANGUL SYLLABLE TIKEUT-WA-NIEUN
0x3544  0xB3E8  # HANGUL SYLLABLE TIKEUT-WA-RIEUL
0x3545  0xB3FC  # HANGUL SYLLABLE TIKEUT-WAE
0x3546  0xB410  # HANGUL SYLLABLE TIKEUT-WAE-SSANGSIOS
0x3547  0xB418  # HANGUL SYLLABLE TIKEUT-OE
0x3548  0xB41C  # HANGUL SYLLABLE TIKEUT-OE-NIEUN
0x3549  0xB420  # HANGUL SYLLABLE TIKEUT-OE-RIEUL
0x354A  0xB428  # HANGUL SYLLABLE TIKEUT-OE-MIEUM
0x354B  0xB429  # HANGUL SYLLABLE TIKEUT-OE-PIEUP
0x354C  0xB42B  # HANGUL SYLLABLE TIKEUT-OE-SIOS
0x354D  0xB434  # HANGUL SYLLABLE TIKEUT-YO
0x354E  0xB450  # HANGUL SYLLABLE TIKEUT-U
0x354F  0xB451  # HANGUL SYLLABLE TIKEUT-U-KIYEOK
0x3550  0xB454  # HANGUL SYLLABLE TIKEUT-U-NIEUN
0x3551  0xB458  # HANGUL SYLLABLE TIKEUT-U-RIEUL
0x3552  0xB460  # HANGUL SYLLABLE TIKEUT-U-MIEUM
0x3553  0xB461  # HANGUL SYLLABLE TIKEUT-U-PIEUP
0x3554  0xB463  # HANGUL SYLLABLE TIKEUT-U-SIOS
0x3555  0xB465  # HANGUL SYLLABLE TIKEUT-U-IEUNG
0x3556  0xB46C  # HANGUL SYLLABLE TIKEUT-WEO
0x3557  0xB480  # HANGUL SYLLABLE TIKEUT-WEO-SSANGSIOS
0x3558  0xB488  # HANGUL SYLLABLE TIKEUT-WE
0x3559  0xB49D  # HANGUL SYLLABLE TIKEUT-WE-IEUNG
0x355A  0xB4A4  # HANGUL SYLLABLE TIKEUT-WI
0x355B  0xB4A8  # HANGUL SYLLABLE TIKEUT-WI-NIEUN
0x355C  0xB4AC  # HANGUL SYLLABLE TIKEUT-WI-RIEUL
0x355D  0xB4B5  # HANGUL SYLLABLE TIKEUT-WI-PIEUP
0x355E  0xB4B7  # HANGUL SYLLABLE TIKEUT-WI-SIOS
0x355F  0xB4B9  # HANGUL SYLLABLE TIKEUT-WI-IEUNG
0x3560  0xB4C0  # HANGUL SYLLABLE TIKEUT-YU
0x3561  0xB4C4  # HANGUL SYLLABLE TIKEUT-YU-NIEUN
0x3562  0xB4C8  # HANGUL SYLLABLE TIKEUT-YU-RIEUL
0x3563  0xB4D0  # HANGUL SYLLABLE TIKEUT-YU-MIEUM
0x3564  0xB4D5  # HANGUL SYLLABLE TIKEUT-YU-IEUNG
0x3565  0xB4DC  # HANGUL SYLLABLE TIKEUT-EU
0x3566  0xB4DD  # HANGUL SYLLABLE TIKEUT-EU-KIYEOK
0x3567  0xB4E0  # HANGUL SYLLABLE TIKEUT-EU-NIEUN
0x3568  0xB4E3  # HANGUL SYLLABLE TIKEUT-EU-TIKEUT
0x3569  0xB4E4  # HANGUL SYLLABLE TIKEUT-EU-RIEUL
0x356A  0xB4E6  # HANGUL SYLLABLE TIKEUT-EU-RIEULMIEUM
0x356B  0xB4EC  # HANGUL SYLLABLE TIKEUT-EU-MIEUM
0x356C  0xB4ED  # HANGUL SYLLABLE TIKEUT-EU-PIEUP
0x356D  0xB4EF  # HANGUL SYLLABLE TIKEUT-EU-SIOS
0x356E  0xB4F1  # HANGUL SYLLABLE TIKEUT-EU-IEUNG
0x356F  0xB4F8  # HANGUL SYLLABLE TIKEUT-YI
0x3570  0xB514  # HANGUL SYLLABLE TIKEUT-I
0x3571  0xB515  # HANGUL SYLLABLE TIKEUT-I-KIYEOK
0x3572  0xB518  # HANGUL SYLLABLE TIKEUT-I-NIEUN
0x3573  0xB51B  # HANGUL SYLLABLE TIKEUT-I-TIKEUT
0x3574  0xB51C  # HANGUL SYLLABLE TIKEUT-I-RIEUL
0x3575  0xB524  # HANGUL SYLLABLE TIKEUT-I-MIEUM
0x3576  0xB525  # HANGUL SYLLABLE TIKEUT-I-PIEUP
0x3577  0xB527  # HANGUL SYLLABLE TIKEUT-I-SIOS
0x3578  0xB528  # HANGUL SYLLABLE TIKEUT-I-SSANGSIOS
0x3579  0xB529  # HANGUL SYLLABLE TIKEUT-I-IEUNG
0x357A  0xB52A  # HANGUL SYLLABLE TIKEUT-I-CIEUC
0x357B  0xB530  # HANGUL SYLLABLE SSANGTIKEUT-A
0x357C  0xB531  # HANGUL SYLLABLE SSANGTIKEUT-A-KIYEOK
0x357D  0xB534  # HANGUL SYLLABLE SSANGTIKEUT-A-NIEUN
0x357E  0xB538  # HANGUL SYLLABLE SSANGTIKEUT-A-RIEUL
0x3621  0xB540  # HANGUL SYLLABLE SSANGTIKEUT-A-MIEUM
0x3622  0xB541  # HANGUL SYLLABLE SSANGTIKEUT-A-PIEUP
0x3623  0xB543  # HANGUL SYLLABLE SSANGTIKEUT-A-SIOS
0x3624  0xB544  # HANGUL SYLLABLE SSANGTIKEUT-A-SSANGSIOS
0x3625  0xB545  # HANGUL SYLLABLE SSANGTIKEUT-A-IEUNG
0x3626  0xB54B  # HANGUL SYLLABLE SSANGTIKEUT-A-HIEUH
0x3627  0xB54C  # HANGUL SYLLABLE SSANGTIKEUT-AE
0x3628  0xB54D  # HANGUL SYLLABLE SSANGTIKEUT-AE-KIYEOK
0x3629  0xB550  # HANGUL SYLLABLE SSANGTIKEUT-AE-NIEUN
0x362A  0xB554  # HANGUL SYLLABLE SSANGTIKEUT-AE-RIEUL
0x362B  0xB55C  # HANGUL SYLLABLE SSANGTIKEUT-AE-MIEUM
0x362C  0xB55D  # HANGUL SYLLABLE SSANGTIKEUT-AE-PIEUP
0x362D  0xB55F  # HANGUL SYLLABLE SSANGTIKEUT-AE-SIOS
0x362E  0xB560  # HANGUL SYLLABLE SSANGTIKEUT-AE-SSANGSIOS
0x362F  0xB561  # HANGUL SYLLABLE SSANGTIKEUT-AE-IEUNG
0x3630  0xB5A0  # HANGUL SYLLABLE SSANGTIKEUT-EO
0x3631  0xB5A1  # HANGUL SYLLABLE SSANGTIKEUT-EO-KIYEOK
0x3632  0xB5A4  # HANGUL SYLLABLE SSANGTIKEUT-EO-NIEUN
0x3633  0xB5A8  # HANGUL SYLLABLE SSANGTIKEUT-EO-RIEUL
0x3634  0xB5AA  # HANGUL SYLLABLE SSANGTIKEUT-EO-RIEULMIEUM
0x3635  0xB5AB  # HANGUL SYLLABLE SSANGTIKEUT-EO-RIEULPIEUP
0x3636  0xB5B0  # HANGUL SYLLABLE SSANGTIKEUT-EO-MIEUM
0x3637  0xB5B1  # HANGUL SYLLABLE SSANGTIKEUT-EO-PIEUP
0x3638  0xB5B3  # HANGUL SYLLABLE SSANGTIKEUT-EO-SIOS
0x3639  0xB5B4  # HANGUL SYLLABLE SSANGTIKEUT-EO-SSANGSIOS
0x363A  0xB5B5  # HANGUL SYLLABLE SSANGTIKEUT-EO-IEUNG
0x363B  0xB5BB  # HANGUL SYLLABLE SSANGTIKEUT-EO-HIEUH
0x363C  0xB5BC  # HANGUL SYLLABLE SSANGTIKEUT-E
0x363D  0xB5BD  # HANGUL SYLLABLE SSANGTIKEUT-E-KIYEOK
0x363E  0xB5C0  # HANGUL SYLLABLE SSANGTIKEUT-E-NIEUN
0x363F  0xB5C4  # HANGUL SYLLABLE SSANGTIKEUT-E-RIEUL
0x3640  0xB5CC  # HANGUL SYLLABLE SSANGTIKEUT-E-MIEUM
0x3641  0xB5CD  # HANGUL SYLLABLE SSANGTIKEUT-E-PIEUP
0x3642  0xB5CF  # HANGUL SYLLABLE SSANGTIKEUT-E-SIOS
0x3643  0xB5D0  # HANGUL SYLLABLE SSANGTIKEUT-E-SSANGSIOS
0x3644  0xB5D1  # HANGUL SYLLABLE SSANGTIKEUT-E-IEUNG
0x3645  0xB5D8  # HANGUL SYLLABLE SSANGTIKEUT-YEO
0x3646  0xB5EC  # HANGUL SYLLABLE SSANGTIKEUT-YEO-SSANGSIOS
0x3647  0xB610  # HANGUL SYLLABLE SSANGTIKEUT-O
0x3648  0xB611  # HANGUL SYLLABLE SSANGTIKEUT-O-KIYEOK
0x3649  0xB614  # HANGUL SYLLABLE SSANGTIKEUT-O-NIEUN
0x364A  0xB618  # HANGUL SYLLABLE SSANGTIKEUT-O-RIEUL
0x364B  0xB625  # HANGUL SYLLABLE SSANGTIKEUT-O-IEUNG
0x364C  0xB62C  # HANGUL SYLLABLE SSANGTIKEUT-WA
0x364D  0xB634  # HANGUL SYLLABLE SSANGTIKEUT-WA-RIEUL
0x364E  0xB648  # HANGUL SYLLABLE SSANGTIKEUT-WAE
0x364F  0xB664  # HANGUL SYLLABLE SSANGTIKEUT-OE
0x3650  0xB668  # HANGUL SYLLABLE SSANGTIKEUT-OE-NIEUN
0x3651  0xB69C  # HANGUL SYLLABLE SSANGTIKEUT-U
0x3652  0xB69D  # HANGUL SYLLABLE SSANGTIKEUT-U-KIYEOK
0x3653  0xB6A0  # HANGUL SYLLABLE SSANGTIKEUT-U-NIEUN
0x3654  0xB6A4  # HANGUL SYLLABLE SSANGTIKEUT-U-RIEUL
0x3655  0xB6AB  # HANGUL SYLLABLE SSANGTIKEUT-U-RIEULHIEUH
0x3656  0xB6AC  # HANGUL SYLLABLE SSANGTIKEUT-U-MIEUM
0x3657  0xB6B1  # HANGUL SYLLABLE SSANGTIKEUT-U-IEUNG
0x3658  0xB6D4  # HANGUL SYLLABLE SSANGTIKEUT-WE
0x3659  0xB6F0  # HANGUL SYLLABLE SSANGTIKEUT-WI
0x365A  0xB6F4  # HANGUL SYLLABLE SSANGTIKEUT-WI-NIEUN
0x365B  0xB6F8  # HANGUL SYLLABLE SSANGTIKEUT-WI-RIEUL
0x365C  0xB700  # HANGUL SYLLABLE SSANGTIKEUT-WI-MIEUM
0x365D  0xB701  # HANGUL SYLLABLE SSANGTIKEUT-WI-PIEUP
0x365E  0xB705  # HANGUL SYLLABLE SSANGTIKEUT-WI-IEUNG
0x365F  0xB728  # HANGUL SYLLABLE SSANGTIKEUT-EU
0x3660  0xB729  # HANGUL SYLLABLE SSANGTIKEUT-EU-KIYEOK
0x3661  0xB72C  # HANGUL SYLLABLE SSANGTIKEUT-EU-NIEUN
0x3662  0xB72F  # HANGUL SYLLABLE SSANGTIKEUT-EU-TIKEUT
0x3663  0xB730  # HANGUL SYLLABLE SSANGTIKEUT-EU-RIEUL
0x3664  0xB738  # HANGUL SYLLABLE SSANGTIKEUT-EU-MIEUM
0x3665  0xB739  # HANGUL SYLLABLE SSANGTIKEUT-EU-PIEUP
0x3666  0xB73B  # HANGUL SYLLABLE SSANGTIKEUT-EU-SIOS
0x3667  0xB744  # HANGUL SYLLABLE SSANGTIKEUT-YI
0x3668  0xB748  # HANGUL SYLLABLE SSANGTIKEUT-YI-NIEUN
0x3669  0xB74C  # HANGUL SYLLABLE SSANGTIKEUT-YI-RIEUL
0x366A  0xB754  # HANGUL SYLLABLE SSANGTIKEUT-YI-MIEUM
0x366B  0xB755  # HANGUL SYLLABLE SSANGTIKEUT-YI-PIEUP
0x366C  0xB760  # HANGUL SYLLABLE SSANGTIKEUT-I
0x366D  0xB764  # HANGUL SYLLABLE SSANGTIKEUT-I-NIEUN
0x366E  0xB768  # HANGUL SYLLABLE SSANGTIKEUT-I-RIEUL
0x366F  0xB770  # HANGUL SYLLABLE SSANGTIKEUT-I-MIEUM
0x3670  0xB771  # HANGUL SYLLABLE SSANGTIKEUT-I-PIEUP
0x3671  0xB773  # HANGUL SYLLABLE SSANGTIKEUT-I-SIOS
0x3672  0xB775  # HANGUL SYLLABLE SSANGTIKEUT-I-IEUNG
0x3673  0xB77C  # HANGUL SYLLABLE RIEUL-A
0x3674  0xB77D  # HANGUL SYLLABLE RIEUL-A-KIYEOK
0x3675  0xB780  # HANGUL SYLLABLE RIEUL-A-NIEUN
0x3676  0xB784  # HANGUL SYLLABLE RIEUL-A-RIEUL
0x3677  0xB78C  # HANGUL SYLLABLE RIEUL-A-MIEUM
0x3678  0xB78D  # HANGUL SYLLABLE RIEUL-A-PIEUP
0x3679  0xB78F  # HANGUL SYLLABLE RIEUL-A-SIOS
0x367A  0xB790  # HANGUL SYLLABLE RIEUL-A-SSANGSIOS
0x367B  0xB791  # HANGUL SYLLABLE RIEUL-A-IEUNG
0x367C  0xB792  # HANGUL SYLLABLE RIEUL-A-CIEUC
0x367D  0xB796  # HANGUL SYLLABLE RIEUL-A-PHIEUPH
0x367E  0xB797  # HANGUL SYLLABLE RIEUL-A-HIEUH
0x3721  0xB798  # HANGUL SYLLABLE RIEUL-AE
0x3722  0xB799  # HANGUL SYLLABLE RIEUL-AE-KIYEOK
0x3723  0xB79C  # HANGUL SYLLABLE RIEUL-AE-NIEUN
0x3724  0xB7A0  # HANGUL SYLLABLE RIEUL-AE-RIEUL
0x3725  0xB7A8  # HANGUL SYLLABLE RIEUL-AE-MIEUM
0x3726  0xB7A9  # HANGUL SYLLABLE RIEUL-AE-PIEUP
0x3727  0xB7AB  # HANGUL SYLLABLE RIEUL-AE-SIOS
0x3728  0xB7AC  # HANGUL SYLLABLE RIEUL-AE-SSANGSIOS
0x3729  0xB7AD  # HANGUL SYLLABLE RIEUL-AE-IEUNG
0x372A  0xB7B4  # HANGUL SYLLABLE RIEUL-YA
0x372B  0xB7B5  # HANGUL SYLLABLE RIEUL-YA-KIYEOK
0x372C  0xB7B8  # HANGUL SYLLABLE RIEUL-YA-NIEUN
0x372D  0xB7C7  # HANGUL SYLLABLE RIEUL-YA-SIOS
0x372E  0xB7C9  # HANGUL SYLLABLE RIEUL-YA-IEUNG
0x372F  0xB7EC  # HANGUL SYLLABLE RIEUL-EO
0x3730  0xB7ED  # HANGUL SYLLABLE RIEUL-EO-KIYEOK
0x3731  0xB7F0  # HANGUL SYLLABLE RIEUL-EO-NIEUN
0x3732  0xB7F4  # HANGUL SYLLABLE RIEUL-EO-RIEUL
0x3733  0xB7FC  # HANGUL SYLLABLE RIEUL-EO-MIEUM
0x3734  0xB7FD  # HANGUL SYLLABLE RIEUL-EO-PIEUP
0x3735  0xB7FF  # HANGUL SYLLABLE RIEUL-EO-SIOS
0x3736  0xB800  # HANGUL SYLLABLE RIEUL-EO-SSANGSIOS
0x3737  0xB801  # HANGUL SYLLABLE RIEUL-EO-IEUNG
0x3738  0xB807  # HANGUL SYLLABLE RIEUL-EO-HIEUH
0x3739  0xB808  # HANGUL SYLLABLE RIEUL-E
0x373A  0xB809  # HANGUL SYLLABLE RIEUL-E-KIYEOK
0x373B  0xB80C  # HANGUL SYLLABLE RIEUL-E-NIEUN
0x373C  0xB810  # HANGUL SYLLABLE RIEUL-E-RIEUL
0x373D  0xB818  # HANGUL SYLLABLE RIEUL-E-MIEUM
0x373E  0xB819  # HANGUL SYLLABLE RIEUL-E-PIEUP
0x373F  0xB81B  # HANGUL SYLLABLE RIEUL-E-SIOS
0x3740  0xB81D  # HANGUL SYLLABLE RIEUL-E-IEUNG
0x3741  0xB824  # HANGUL SYLLABLE RIEUL-YEO
0x3742  0xB825  # HANGUL SYLLABLE RIEUL-YEO-KIYEOK
0x3743  0xB828  # HANGUL SYLLABLE RIEUL-YEO-NIEUN
0x3744  0xB82C  # HANGUL SYLLABLE RIEUL-YEO-RIEUL
0x3745  0xB834  # HANGUL SYLLABLE RIEUL-YEO-MIEUM
0x3746  0xB835  # HANGUL SYLLABLE RIEUL-YEO-PIEUP
0x3747  0xB837  # HANGUL SYLLABLE RIEUL-YEO-SIOS
0x3748  0xB838  # HANGUL SYLLABLE RIEUL-YEO-SSANGSIOS
0x3749  0xB839  # HANGUL SYLLABLE RIEUL-YEO-IEUNG
0x374A  0xB840  # HANGUL SYLLABLE RIEUL-YE
0x374B  0xB844  # HANGUL SYLLABLE RIEUL-YE-NIEUN
0x374C  0xB851  # HANGUL SYLLABLE RIEUL-YE-PIEUP
0x374D  0xB853  # HANGUL SYLLABLE RIEUL-YE-SIOS
0x374E  0xB85C  # HANGUL SYLLABLE RIEUL-O
0x374F  0xB85D  # HANGUL SYLLABLE RIEUL-O-KIYEOK
0x3750  0xB860  # HANGUL SYLLABLE RIEUL-O-NIEUN
0x3751  0xB864  # HANGUL SYLLABLE RIEUL-O-RIEUL
0x3752  0xB86C  # HANGUL SYLLABLE RIEUL-O-MIEUM
0x3753  0xB86D  # HANGUL SYLLABLE RIEUL-O-PIEUP
0x3754  0xB86F  # HANGUL SYLLABLE RIEUL-O-SIOS
0x3755  0xB871  # HANGUL SYLLABLE RIEUL-O-IEUNG
0x3756  0xB878  # HANGUL SYLLABLE RIEUL-WA
0x3757  0xB87C  # HANGUL SYLLABLE RIEUL-WA-NIEUN
0x3758  0xB88D  # HANGUL SYLLABLE RIEUL-WA-IEUNG
0x3759  0xB8A8  # HANGUL SYLLABLE RIEUL-WAE-SSANGSIOS
0x375A  0xB8B0  # HANGUL SYLLABLE RIEUL-OE
0x375B  0xB8B4  # HANGUL SYLLABLE RIEUL-OE-NIEUN
0x375C  0xB8B8  # HANGUL SYLLABLE RIEUL-OE-RIEUL
0x375D  0xB8C0  # HANGUL SYLLABLE RIEUL-OE-MIEUM
0x375E  0xB8C1  # HANGUL SYLLABLE RIEUL-OE-PIEUP
0x375F  0xB8C3  # HANGUL SYLLABLE RIEUL-OE-SIOS
0x3760  0xB8C5  # HANGUL SYLLABLE RIEUL-OE-IEUNG
0x3761  0xB8CC  # HANGUL SYLLABLE RIEUL-YO
0x3762  0xB8D0  # HANGUL SYLLABLE RIEUL-YO-NIEUN
0x3763  0xB8D4  # HANGUL SYLLABLE RIEUL-YO-RIEUL
0x3764  0xB8DD  # HANGUL SYLLABLE RIEUL-YO-PIEUP
0x3765  0xB8DF  # HANGUL SYLLABLE RIEUL-YO-SIOS
0x3766  0xB8E1  # HANGUL SYLLABLE RIEUL-YO-IEUNG
0x3767  0xB8E8  # HANGUL SYLLABLE RIEUL-U
0x3768  0xB8E9  # HANGUL SYLLABLE RIEUL-U-KIYEOK
0x3769  0xB8EC  # HANGUL SYLLABLE RIEUL-U-NIEUN
0x376A  0xB8F0  # HANGUL SYLLABLE RIEUL-U-RIEUL
0x376B  0xB8F8  # HANGUL SYLLABLE RIEUL-U-MIEUM
0x376C  0xB8F9  # HANGUL SYLLABLE RIEUL-U-PIEUP
0x376D  0xB8FB  # HANGUL SYLLABLE RIEUL-U-SIOS
0x376E  0xB8FD  # HANGUL SYLLABLE RIEUL-U-IEUNG
0x376F  0xB904  # HANGUL SYLLABLE RIEUL-WEO
0x3770  0xB918  # HANGUL SYLLABLE RIEUL-WEO-SSANGSIOS
0x3771  0xB920  # HANGUL SYLLABLE RIEUL-WE
0x3772  0xB93C  # HANGUL SYLLABLE RIEUL-WI
0x3773  0xB93D  # HANGUL SYLLABLE RIEUL-WI-KIYEOK
0x3774  0xB940  # HANGUL SYLLABLE RIEUL-WI-NIEUN
0x3775  0xB944  # HANGUL SYLLABLE RIEUL-WI-RIEUL
0x3776  0xB94C  # HANGUL SYLLABLE RIEUL-WI-MIEUM
0x3777  0xB94F  # HANGUL SYLLABLE RIEUL-WI-SIOS
0x3778  0xB951  # HANGUL SYLLABLE RIEUL-WI-IEUNG
0x3779  0xB958  # HANGUL SYLLABLE RIEUL-YU
0x377A  0xB959  # HANGUL SYLLABLE RIEUL-YU-KIYEOK
0x377B  0xB95C  # HANGUL SYLLABLE RIEUL-YU-NIEUN
0x377C  0xB960  # HANGUL SYLLABLE RIEUL-YU-RIEUL
0x377D  0xB968  # HANGUL SYLLABLE RIEUL-YU-MIEUM
0x377E  0xB969  # HANGUL SYLLABLE RIEUL-YU-PIEUP
0x3821  0xB96B  # HANGUL SYLLABLE RIEUL-YU-SIOS
0x3822  0xB96D  # HANGUL SYLLABLE RIEUL-YU-IEUNG
0x3823  0xB974  # HANGUL SYLLABLE RIEUL-EU
0x3824  0xB975  # HANGUL SYLLABLE RIEUL-EU-KIYEOK
0x3825  0xB978  # HANGUL SYLLABLE RIEUL-EU-NIEUN
0x3826  0xB97C  # HANGUL SYLLABLE RIEUL-EU-RIEUL
0x3827  0xB984  # HANGUL SYLLABLE RIEUL-EU-MIEUM
0x3828  0xB985  # HANGUL SYLLABLE RIEUL-EU-PIEUP
0x3829  0xB987  # HANGUL SYLLABLE RIEUL-EU-SIOS
0x382A  0xB989  # HANGUL SYLLABLE RIEUL-EU-IEUNG
0x382B  0xB98A  # HANGUL SYLLABLE RIEUL-EU-CIEUC
0x382C  0xB98D  # HANGUL SYLLABLE RIEUL-EU-THIEUTH
0x382D  0xB98E  # HANGUL SYLLABLE RIEUL-EU-PHIEUPH
0x382E  0xB9AC  # HANGUL SYLLABLE RIEUL-I
0x382F  0xB9AD  # HANGUL SYLLABLE RIEUL-I-KIYEOK
0x3830  0xB9B0  # HANGUL SYLLABLE RIEUL-I-NIEUN
0x3831  0xB9B4  # HANGUL SYLLABLE RIEUL-I-RIEUL
0x3832  0xB9BC  # HANGUL SYLLABLE RIEUL-I-MIEUM
0x3833  0xB9BD  # HANGUL SYLLABLE RIEUL-I-PIEUP
0x3834  0xB9BF  # HANGUL SYLLABLE RIEUL-I-SIOS
0x3835  0xB9C1  # HANGUL SYLLABLE RIEUL-I-IEUNG
0x3836  0xB9C8  # HANGUL SYLLABLE MIEUM-A
0x3837  0xB9C9  # HANGUL SYLLABLE MIEUM-A-KIYEOK
0x3838  0xB9CC  # HANGUL SYLLABLE MIEUM-A-NIEUN
0x3839  0xB9CE  # HANGUL SYLLABLE MIEUM-A-NIEUNHIEUH
0x383A  0xB9CF  # HANGUL SYLLABLE MIEUM-A-TIKEUT
0x383B  0xB9D0  # HANGUL SYLLABLE MIEUM-A-RIEUL
0x383C  0xB9D1  # HANGUL SYLLABLE MIEUM-A-RIEULKIYEOK
0x383D  0xB9D2  # HANGUL SYLLABLE MIEUM-A-RIEULMIEUM
0x383E  0xB9D8  # HANGUL SYLLABLE MIEUM-A-MIEUM
0x383F  0xB9D9  # HANGUL SYLLABLE MIEUM-A-PIEUP
0x3840  0xB9DB  # HANGUL SYLLABLE MIEUM-A-SIOS
0x3841  0xB9DD  # HANGUL SYLLABLE MIEUM-A-IEUNG
0x3842  0xB9DE  # HANGUL SYLLABLE MIEUM-A-CIEUC
0x3843  0xB9E1  # HANGUL SYLLABLE MIEUM-A-THIEUTH
0x3844  0xB9E3  # HANGUL SYLLABLE MIEUM-A-HIEUH
0x3845  0xB9E4  # HANGUL SYLLABLE MIEUM-AE
0x3846  0xB9E5  # HANGUL SYLLABLE MIEUM-AE-KIYEOK
0x3847  0xB9E8  # HANGUL SYLLABLE MIEUM-AE-NIEUN
0x3848  0xB9EC  # HANGUL SYLLABLE MIEUM-AE-RIEUL
0x3849  0xB9F4  # HANGUL SYLLABLE MIEUM-AE-MIEUM
0x384A  0xB9F5  # HANGUL SYLLABLE MIEUM-AE-PIEUP
0x384B  0xB9F7  # HANGUL SYLLABLE MIEUM-AE-SIOS
0x384C  0xB9F8  # HANGUL SYLLABLE MIEUM-AE-SSANGSIOS
0x384D  0xB9F9  # HANGUL SYLLABLE MIEUM-AE-IEUNG
0x384E  0xB9FA  # HANGUL SYLLABLE MIEUM-AE-CIEUC
0x384F  0xBA00  # HANGUL SYLLABLE MIEUM-YA
0x3850  0xBA01  # HANGUL SYLLABLE MIEUM-YA-KIYEOK
0x3851  0xBA08  # HANGUL SYLLABLE MIEUM-YA-RIEUL
0x3852  0xBA15  # HANGUL SYLLABLE MIEUM-YA-IEUNG
0x3853  0xBA38  # HANGUL SYLLABLE MIEUM-EO
0x3854  0xBA39  # HANGUL SYLLABLE MIEUM-EO-KIYEOK
0x3855  0xBA3C  # HANGUL SYLLABLE MIEUM-EO-NIEUN
0x3856  0xBA40  # HANGUL SYLLABLE MIEUM-EO-RIEUL
0x3857  0xBA42  # HANGUL SYLLABLE MIEUM-EO-RIEULMIEUM
0x3858  0xBA48  # HANGUL SYLLABLE MIEUM-EO-MIEUM
0x3859  0xBA49  # HANGUL SYLLABLE MIEUM-EO-PIEUP
0x385A  0xBA4B  # HANGUL SYLLABLE MIEUM-EO-SIOS
0x385B  0xBA4D  # HANGUL SYLLABLE MIEUM-EO-IEUNG
0x385C  0xBA4E  # HANGUL SYLLABLE MIEUM-EO-CIEUC
0x385D  0xBA53  # HANGUL SYLLABLE MIEUM-EO-HIEUH
0x385E  0xBA54  # HANGUL SYLLABLE MIEUM-E
0x385F  0xBA55  # HANGUL SYLLABLE MIEUM-E-KIYEOK
0x3860  0xBA58  # HANGUL SYLLABLE MIEUM-E-NIEUN
0x3861  0xBA5C  # HANGUL SYLLABLE MIEUM-E-RIEUL
0x3862  0xBA64  # HANGUL SYLLABLE MIEUM-E-MIEUM
0x3863  0xBA65  # HANGUL SYLLABLE MIEUM-E-PIEUP
0x3864  0xBA67  # HANGUL SYLLABLE MIEUM-E-SIOS
0x3865  0xBA68  # HANGUL SYLLABLE MIEUM-E-SSANGSIOS
0x3866  0xBA69  # HANGUL SYLLABLE MIEUM-E-IEUNG
0x3867  0xBA70  # HANGUL SYLLABLE MIEUM-YEO
0x3868  0xBA71  # HANGUL SYLLABLE MIEUM-YEO-KIYEOK
0x3869  0xBA74  # HANGUL SYLLABLE MIEUM-YEO-NIEUN
0x386A  0xBA78  # HANGUL SYLLABLE MIEUM-YEO-RIEUL
0x386B  0xBA83  # HANGUL SYLLABLE MIEUM-YEO-SIOS
0x386C  0xBA84  # HANGUL SYLLABLE MIEUM-YEO-SSANGSIOS
0x386D  0xBA85  # HANGUL SYLLABLE MIEUM-YEO-IEUNG
0x386E  0xBA87  # HANGUL SYLLABLE MIEUM-YEO-CHIEUCH
0x386F  0xBA8C  # HANGUL SYLLABLE MIEUM-YE
0x3870  0xBAA8  # HANGUL SYLLABLE MIEUM-O
0x3871  0xBAA9  # HANGUL SYLLABLE MIEUM-O-KIYEOK
0x3872  0xBAAB  # HANGUL SYLLABLE MIEUM-O-KIYEOKSIOS
0x3873  0xBAAC  # HANGUL SYLLABLE MIEUM-O-NIEUN
0x3874  0xBAB0  # HANGUL SYLLABLE MIEUM-O-RIEUL
0x3875  0xBAB2  # HANGUL SYLLABLE MIEUM-O-RIEULMIEUM
0x3876  0xBAB8  # HANGUL SYLLABLE MIEUM-O-MIEUM
0x3877  0xBAB9  # HANGUL SYLLABLE MIEUM-O-PIEUP
0x3878  0xBABB  # HANGUL SYLLABLE MIEUM-O-SIOS
0x3879  0xBABD  # HANGUL SYLLABLE MIEUM-O-IEUNG
0x387A  0xBAC4  # HANGUL SYLLABLE MIEUM-WA
0x387B  0xBAC8  # HANGUL SYLLABLE MIEUM-WA-NIEUN
0x387C  0xBAD8  # HANGUL SYLLABLE MIEUM-WA-SSANGSIOS
0x387D  0xBAD9  # HANGUL SYLLABLE MIEUM-WA-IEUNG
0x387E  0xBAFC  # HANGUL SYLLABLE MIEUM-OE
0x3921  0xBB00  # HANGUL SYLLABLE MIEUM-OE-NIEUN
0x3922  0xBB04  # HANGUL SYLLABLE MIEUM-OE-RIEUL
0x3923  0xBB0D  # HANGUL SYLLABLE MIEUM-OE-PIEUP
0x3924  0xBB0F  # HANGUL SYLLABLE MIEUM-OE-SIOS
0x3925  0xBB11  # HANGUL SYLLABLE MIEUM-OE-IEUNG
0x3926  0xBB18  # HANGUL SYLLABLE MIEUM-YO
0x3927  0xBB1C  # HANGUL SYLLABLE MIEUM-YO-NIEUN
0x3928  0xBB20  # HANGUL SYLLABLE MIEUM-YO-RIEUL
0x3929  0xBB29  # HANGUL SYLLABLE MIEUM-YO-PIEUP
0x392A  0xBB2B  # HANGUL SYLLABLE MIEUM-YO-SIOS
0x392B  0xBB34  # HANGUL SYLLABLE MIEUM-U
0x392C  0xBB35  # HANGUL SYLLABLE MIEUM-U-KIYEOK
0x392D  0xBB36  # HANGUL SYLLABLE MIEUM-U-SSANGKIYEOK
0x392E  0xBB38  # HANGUL SYLLABLE MIEUM-U-NIEUN
0x392F  0xBB3B  # HANGUL SYLLABLE MIEUM-U-TIKEUT
0x3930  0xBB3C  # HANGUL SYLLABLE MIEUM-U-RIEUL
0x3931  0xBB3D  # HANGUL SYLLABLE MIEUM-U-RIEULKIYEOK
0x3932  0xBB3E  # HANGUL SYLLABLE MIEUM-U-RIEULMIEUM
0x3933  0xBB44  # HANGUL SYLLABLE MIEUM-U-MIEUM
0x3934  0xBB45  # HANGUL SYLLABLE MIEUM-U-PIEUP
0x3935  0xBB47  # HANGUL SYLLABLE MIEUM-U-SIOS
0x3936  0xBB49  # HANGUL SYLLABLE MIEUM-U-IEUNG
0x3937  0xBB4D  # HANGUL SYLLABLE MIEUM-U-THIEUTH
0x3938  0xBB4F  # HANGUL SYLLABLE MIEUM-U-HIEUH
0x3939  0xBB50  # HANGUL SYLLABLE MIEUM-WEO
0x393A  0xBB54  # HANGUL SYLLABLE MIEUM-WEO-NIEUN
0x393B  0xBB58  # HANGUL SYLLABLE MIEUM-WEO-RIEUL
0x393C  0xBB61  # HANGUL SYLLABLE MIEUM-WEO-PIEUP
0x393D  0xBB63  # HANGUL SYLLABLE MIEUM-WEO-SIOS
0x393E  0xBB6C  # HANGUL SYLLABLE MIEUM-WE
0x393F  0xBB88  # HANGUL SYLLABLE MIEUM-WI
0x3940  0xBB8C  # HANGUL SYLLABLE MIEUM-WI-NIEUN
0x3941  0xBB90  # HANGUL SYLLABLE MIEUM-WI-RIEUL
0x3942  0xBBA4  # HANGUL SYLLABLE MIEUM-YU
0x3943  0xBBA8  # HANGUL SYLLABLE MIEUM-YU-NIEUN
0x3944  0xBBAC  # HANGUL SYLLABLE MIEUM-YU-RIEUL
0x3945  0xBBB4  # HANGUL SYLLABLE MIEUM-YU-MIEUM
0x3946  0xBBB7  # HANGUL SYLLABLE MIEUM-YU-SIOS
0x3947  0xBBC0  # HANGUL SYLLABLE MIEUM-EU
0x3948  0xBBC4  # HANGUL SYLLABLE MIEUM-EU-NIEUN
0x3949  0xBBC8  # HANGUL SYLLABLE MIEUM-EU-RIEUL
0x394A  0xBBD0  # HANGUL SYLLABLE MIEUM-EU-MIEUM
0x394B  0xBBD3  # HANGUL SYLLABLE MIEUM-EU-SIOS
0x394C  0xBBF8  # HANGUL SYLLABLE MIEUM-I
0x394D  0xBBF9  # HANGUL SYLLABLE MIEUM-I-KIYEOK
0x394E  0xBBFC  # HANGUL SYLLABLE MIEUM-I-NIEUN
0x394F  0xBBFF  # HANGUL SYLLABLE MIEUM-I-TIKEUT
0x3950  0xBC00  # HANGUL SYLLABLE MIEUM-I-RIEUL
0x3951  0xBC02  # HANGUL SYLLABLE MIEUM-I-RIEULMIEUM
0x3952  0xBC08  # HANGUL SYLLABLE MIEUM-I-MIEUM
0x3953  0xBC09  # HANGUL SYLLABLE MIEUM-I-PIEUP
0x3954  0xBC0B  # HANGUL SYLLABLE MIEUM-I-SIOS
0x3955  0xBC0C  # HANGUL SYLLABLE MIEUM-I-SSANGSIOS
0x3956  0xBC0D  # HANGUL SYLLABLE MIEUM-I-IEUNG
0x3957  0xBC0F  # HANGUL SYLLABLE MIEUM-I-CHIEUCH
0x3958  0xBC11  # HANGUL SYLLABLE MIEUM-I-THIEUTH
0x3959  0xBC14  # HANGUL SYLLABLE PIEUP-A
0x395A  0xBC15  # HANGUL SYLLABLE PIEUP-A-KIYEOK
0x395B  0xBC16  # HANGUL SYLLABLE PIEUP-A-SSANGKIYEOK
0x395C  0xBC17  # HANGUL SYLLABLE PIEUP-A-KIYEOKSIOS
0x395D  0xBC18  # HANGUL SYLLABLE PIEUP-A-NIEUN
0x395E  0xBC1B  # HANGUL SYLLABLE PIEUP-A-TIKEUT
0x395F  0xBC1C  # HANGUL SYLLABLE PIEUP-A-RIEUL
0x3960  0xBC1D  # HANGUL SYLLABLE PIEUP-A-RIEULKIYEOK
0x3961  0xBC1E  # HANGUL SYLLABLE PIEUP-A-RIEULMIEUM
0x3962  0xBC1F  # HANGUL SYLLABLE PIEUP-A-RIEULPIEUP
0x3963  0xBC24  # HANGUL SYLLABLE PIEUP-A-MIEUM
0x3964  0xBC25  # HANGUL SYLLABLE PIEUP-A-PIEUP
0x3965  0xBC27  # HANGUL SYLLABLE PIEUP-A-SIOS
0x3966  0xBC29  # HANGUL SYLLABLE PIEUP-A-IEUNG
0x3967  0xBC2D  # HANGUL SYLLABLE PIEUP-A-THIEUTH
0x3968  0xBC30  # HANGUL SYLLABLE PIEUP-AE
0x3969  0xBC31  # HANGUL SYLLABLE PIEUP-AE-KIYEOK
0x396A  0xBC34  # HANGUL SYLLABLE PIEUP-AE-NIEUN
0x396B  0xBC38  # HANGUL SYLLABLE PIEUP-AE-RIEUL
0x396C  0xBC40  # HANGUL SYLLABLE PIEUP-AE-MIEUM
0x396D  0xBC41  # HANGUL SYLLABLE PIEUP-AE-PIEUP
0x396E  0xBC43  # HANGUL SYLLABLE PIEUP-AE-SIOS
0x396F  0xBC44  # HANGUL SYLLABLE PIEUP-AE-SSANGSIOS
0x3970  0xBC45  # HANGUL SYLLABLE PIEUP-AE-IEUNG
0x3971  0xBC49  # HANGUL SYLLABLE PIEUP-AE-THIEUTH
0x3972  0xBC4C  # HANGUL SYLLABLE PIEUP-YA
0x3973  0xBC4D  # HANGUL SYLLABLE PIEUP-YA-KIYEOK
0x3974  0xBC50  # HANGUL SYLLABLE PIEUP-YA-NIEUN
0x3975  0xBC5D  # HANGUL SYLLABLE PIEUP-YA-PIEUP
0x3976  0xBC84  # HANGUL SYLLABLE PIEUP-EO
0x3977  0xBC85  # HANGUL SYLLABLE PIEUP-EO-KIYEOK
0x3978  0xBC88  # HANGUL SYLLABLE PIEUP-EO-NIEUN
0x3979  0xBC8B  # HANGUL SYLLABLE PIEUP-EO-TIKEUT
0x397A  0xBC8C  # HANGUL SYLLABLE PIEUP-EO-RIEUL
0x397B  0xBC8E  # HANGUL SYLLABLE PIEUP-EO-RIEULMIEUM
0x397C  0xBC94  # HANGUL SYLLABLE PIEUP-EO-MIEUM
0x397D  0xBC95  # HANGUL SYLLABLE PIEUP-EO-PIEUP
0x397E  0xBC97  # HANGUL SYLLABLE PIEUP-EO-SIOS
0x3A21  0xBC99  # HANGUL SYLLABLE PIEUP-EO-IEUNG
0x3A22  0xBC9A  # HANGUL SYLLABLE PIEUP-EO-CIEUC
0x3A23  0xBCA0  # HANGUL SYLLABLE PIEUP-E
0x3A24  0xBCA1  # HANGUL SYLLABLE PIEUP-E-KIYEOK
0x3A25  0xBCA4  # HANGUL SYLLABLE PIEUP-E-NIEUN
0x3A26  0xBCA7  # HANGUL SYLLABLE PIEUP-E-TIKEUT
0x3A27  0xBCA8  # HANGUL SYLLABLE PIEUP-E-RIEUL
0x3A28  0xBCB0  # HANGUL SYLLABLE PIEUP-E-MIEUM
0x3A29  0xBCB1  # HANGUL SYLLABLE PIEUP-E-PIEUP
0x3A2A  0xBCB3  # HANGUL SYLLABLE PIEUP-E-SIOS
0x3A2B  0xBCB4  # HANGUL SYLLABLE PIEUP-E-SSANGSIOS
0x3A2C  0xBCB5  # HANGUL SYLLABLE PIEUP-E-IEUNG
0x3A2D  0xBCBC  # HANGUL SYLLABLE PIEUP-YEO
0x3A2E  0xBCBD  # HANGUL SYLLABLE PIEUP-YEO-KIYEOK
0x3A2F  0xBCC0  # HANGUL SYLLABLE PIEUP-YEO-NIEUN
0x3A30  0xBCC4  # HANGUL SYLLABLE PIEUP-YEO-RIEUL
0x3A31  0xBCCD  # HANGUL SYLLABLE PIEUP-YEO-PIEUP
0x3A32  0xBCCF  # HANGUL SYLLABLE PIEUP-YEO-SIOS
0x3A33  0xBCD0  # HANGUL SYLLABLE PIEUP-YEO-SSANGSIOS
0x3A34  0xBCD1  # HANGUL SYLLABLE PIEUP-YEO-IEUNG
0x3A35  0xBCD5  # HANGUL SYLLABLE PIEUP-YEO-THIEUTH
0x3A36  0xBCD8  # HANGUL SYLLABLE PIEUP-YE
0x3A37  0xBCDC  # HANGUL SYLLABLE PIEUP-YE-NIEUN
0x3A38  0xBCF4  # HANGUL SYLLABLE PIEUP-O
0x3A39  0xBCF5  # HANGUL SYLLABLE PIEUP-O-KIYEOK
0x3A3A  0xBCF6  # HANGUL SYLLABLE PIEUP-O-SSANGKIYEOK
0x3A3B  0xBCF8  # HANGUL SYLLABLE PIEUP-O-NIEUN
0x3A3C  0xBCFC  # HANGUL SYLLABLE PIEUP-O-RIEUL
0x3A3D  0xBD04  # HANGUL SYLLABLE PIEUP-O-MIEUM
0x3A3E  0xBD05  # HANGUL SYLLABLE PIEUP-O-PIEUP
0x3A3F  0xBD07  # HANGUL SYLLABLE PIEUP-O-SIOS
0x3A40  0xBD09  # HANGUL SYLLABLE PIEUP-O-IEUNG
0x3A41  0xBD10  # HANGUL SYLLABLE PIEUP-WA
0x3A42  0xBD14  # HANGUL SYLLABLE PIEUP-WA-NIEUN
0x3A43  0xBD24  # HANGUL SYLLABLE PIEUP-WA-SSANGSIOS
0x3A44  0xBD2C  # HANGUL SYLLABLE PIEUP-WAE
0x3A45  0xBD40  # HANGUL SYLLABLE PIEUP-WAE-SSANGSIOS
0x3A46  0xBD48  # HANGUL SYLLABLE PIEUP-OE
0x3A47  0xBD49  # HANGUL SYLLABLE PIEUP-OE-KIYEOK
0x3A48  0xBD4C  # HANGUL SYLLABLE PIEUP-OE-NIEUN
0x3A49  0xBD50  # HANGUL SYLLABLE PIEUP-OE-RIEUL
0x3A4A  0xBD58  # HANGUL SYLLABLE PIEUP-OE-MIEUM
0x3A4B  0xBD59  # HANGUL SYLLABLE PIEUP-OE-PIEUP
0x3A4C  0xBD64  # HANGUL SYLLABLE PIEUP-YO
0x3A4D  0xBD68  # HANGUL SYLLABLE PIEUP-YO-NIEUN
0x3A4E  0xBD80  # HANGUL SYLLABLE PIEUP-U
0x3A4F  0xBD81  # HANGUL SYLLABLE PIEUP-U-KIYEOK
0x3A50  0xBD84  # HANGUL SYLLABLE PIEUP-U-NIEUN
0x3A51  0xBD87  # HANGUL SYLLABLE PIEUP-U-TIKEUT
0x3A52  0xBD88  # HANGUL SYLLABLE PIEUP-U-RIEUL
0x3A53  0xBD89  # HANGUL SYLLABLE PIEUP-U-RIEULKIYEOK
0x3A54  0xBD8A  # HANGUL SYLLABLE PIEUP-U-RIEULMIEUM
0x3A55  0xBD90  # HANGUL SYLLABLE PIEUP-U-MIEUM
0x3A56  0xBD91  # HANGUL SYLLABLE PIEUP-U-PIEUP
0x3A57  0xBD93  # HANGUL SYLLABLE PIEUP-U-SIOS
0x3A58  0xBD95  # HANGUL SYLLABLE PIEUP-U-IEUNG
0x3A59  0xBD99  # HANGUL SYLLABLE PIEUP-U-THIEUTH
0x3A5A  0xBD9A  # HANGUL SYLLABLE PIEUP-U-PHIEUPH
0x3A5B  0xBD9C  # HANGUL SYLLABLE PIEUP-WEO
0x3A5C  0xBDA4  # HANGUL SYLLABLE PIEUP-WEO-RIEUL
0x3A5D  0xBDB0  # HANGUL SYLLABLE PIEUP-WEO-SSANGSIOS
0x3A5E  0xBDB8  # HANGUL SYLLABLE PIEUP-WE
0x3A5F  0xBDD4  # HANGUL SYLLABLE PIEUP-WI
0x3A60  0xBDD5  # HANGUL SYLLABLE PIEUP-WI-KIYEOK
0x3A61  0xBDD8  # HANGUL SYLLABLE PIEUP-WI-NIEUN
0x3A62  0xBDDC  # HANGUL SYLLABLE PIEUP-WI-RIEUL
0x3A63  0xBDE9  # HANGUL SYLLABLE PIEUP-WI-IEUNG
0x3A64  0xBDF0  # HANGUL SYLLABLE PIEUP-YU
0x3A65  0xBDF4  # HANGUL SYLLABLE PIEUP-YU-NIEUN
0x3A66  0xBDF8  # HANGUL SYLLABLE PIEUP-YU-RIEUL
0x3A67  0xBE00  # HANGUL SYLLABLE PIEUP-YU-MIEUM
0x3A68  0xBE03  # HANGUL SYLLABLE PIEUP-YU-SIOS
0x3A69  0xBE05  # HANGUL SYLLABLE PIEUP-YU-IEUNG
0x3A6A  0xBE0C  # HANGUL SYLLABLE PIEUP-EU
0x3A6B  0xBE0D  # HANGUL SYLLABLE PIEUP-EU-KIYEOK
0x3A6C  0xBE10  # HANGUL SYLLABLE PIEUP-EU-NIEUN
0x3A6D  0xBE14  # HANGUL SYLLABLE PIEUP-EU-RIEUL
0x3A6E  0xBE1C  # HANGUL SYLLABLE PIEUP-EU-MIEUM
0x3A6F  0xBE1D  # HANGUL SYLLABLE PIEUP-EU-PIEUP
0x3A70  0xBE1F  # HANGUL SYLLABLE PIEUP-EU-SIOS
0x3A71  0xBE44  # HANGUL SYLLABLE PIEUP-I
0x3A72  0xBE45  # HANGUL SYLLABLE PIEUP-I-KIYEOK
0x3A73  0xBE48  # HANGUL SYLLABLE PIEUP-I-NIEUN
0x3A74  0xBE4C  # HANGUL SYLLABLE PIEUP-I-RIEUL
0x3A75  0xBE4E  # HANGUL SYLLABLE PIEUP-I-RIEULMIEUM
0x3A76  0xBE54  # HANGUL SYLLABLE PIEUP-I-MIEUM
0x3A77  0xBE55  # HANGUL SYLLABLE PIEUP-I-PIEUP
0x3A78  0xBE57  # HANGUL SYLLABLE PIEUP-I-SIOS
0x3A79  0xBE59  # HANGUL SYLLABLE PIEUP-I-IEUNG
0x3A7A  0xBE5A  # HANGUL SYLLABLE PIEUP-I-CIEUC
0x3A7B  0xBE5B  # HANGUL SYLLABLE PIEUP-I-CHIEUCH
0x3A7C  0xBE60  # HANGUL SYLLABLE SSANGPIEUP-A
0x3A7D  0xBE61  # HANGUL SYLLABLE SSANGPIEUP-A-KIYEOK
0x3A7E  0xBE64  # HANGUL SYLLABLE SSANGPIEUP-A-NIEUN
0x3B21  0xBE68  # HANGUL SYLLABLE SSANGPIEUP-A-RIEUL
0x3B22  0xBE6A  # HANGUL SYLLABLE SSANGPIEUP-A-RIEULMIEUM
0x3B23  0xBE70  # HANGUL SYLLABLE SSANGPIEUP-A-MIEUM
0x3B24  0xBE71  # HANGUL SYLLABLE SSANGPIEUP-A-PIEUP
0x3B25  0xBE73  # HANGUL SYLLABLE SSANGPIEUP-A-SIOS
0x3B26  0xBE74  # HANGUL SYLLABLE SSANGPIEUP-A-SSANGSIOS
0x3B27  0xBE75  # HANGUL SYLLABLE SSANGPIEUP-A-IEUNG
0x3B28  0xBE7B  # HANGUL SYLLABLE SSANGPIEUP-A-HIEUH
0x3B29  0xBE7C  # HANGUL SYLLABLE SSANGPIEUP-AE
0x3B2A  0xBE7D  # HANGUL SYLLABLE SSANGPIEUP-AE-KIYEOK
0x3B2B  0xBE80  # HANGUL SYLLABLE SSANGPIEUP-AE-NIEUN
0x3B2C  0xBE84  # HANGUL SYLLABLE SSANGPIEUP-AE-RIEUL
0x3B2D  0xBE8C  # HANGUL SYLLABLE SSANGPIEUP-AE-MIEUM
0x3B2E  0xBE8D  # HANGUL SYLLABLE SSANGPIEUP-AE-PIEUP
0x3B2F  0xBE8F  # HANGUL SYLLABLE SSANGPIEUP-AE-SIOS
0x3B30  0xBE90  # HANGUL SYLLABLE SSANGPIEUP-AE-SSANGSIOS
0x3B31  0xBE91  # HANGUL SYLLABLE SSANGPIEUP-AE-IEUNG
0x3B32  0xBE98  # HANGUL SYLLABLE SSANGPIEUP-YA
0x3B33  0xBE99  # HANGUL SYLLABLE SSANGPIEUP-YA-KIYEOK
0x3B34  0xBEA8  # HANGUL SYLLABLE SSANGPIEUP-YA-MIEUM
0x3B35  0xBED0  # HANGUL SYLLABLE SSANGPIEUP-EO
0x3B36  0xBED1  # HANGUL SYLLABLE SSANGPIEUP-EO-KIYEOK
0x3B37  0xBED4  # HANGUL SYLLABLE SSANGPIEUP-EO-NIEUN
0x3B38  0xBED7  # HANGUL SYLLABLE SSANGPIEUP-EO-TIKEUT
0x3B39  0xBED8  # HANGUL SYLLABLE SSANGPIEUP-EO-RIEUL
0x3B3A  0xBEE0  # HANGUL SYLLABLE SSANGPIEUP-EO-MIEUM
0x3B3B  0xBEE3  # HANGUL SYLLABLE SSANGPIEUP-EO-SIOS
0x3B3C  0xBEE4  # HANGUL SYLLABLE SSANGPIEUP-EO-SSANGSIOS
0x3B3D  0xBEE5  # HANGUL SYLLABLE SSANGPIEUP-EO-IEUNG
0x3B3E  0xBEEC  # HANGUL SYLLABLE SSANGPIEUP-E
0x3B3F  0xBF01  # HANGUL SYLLABLE SSANGPIEUP-E-IEUNG
0x3B40  0xBF08  # HANGUL SYLLABLE SSANGPIEUP-YEO
0x3B41  0xBF09  # HANGUL SYLLABLE SSANGPIEUP-YEO-KIYEOK
0x3B42  0xBF18  # HANGUL SYLLABLE SSANGPIEUP-YEO-MIEUM
0x3B43  0xBF19  # HANGUL SYLLABLE SSANGPIEUP-YEO-PIEUP
0x3B44  0xBF1B  # HANGUL SYLLABLE SSANGPIEUP-YEO-SIOS
0x3B45  0xBF1C  # HANGUL SYLLABLE SSANGPIEUP-YEO-SSANGSIOS
0x3B46  0xBF1D  # HANGUL SYLLABLE SSANGPIEUP-YEO-IEUNG
0x3B47  0xBF40  # HANGUL SYLLABLE SSANGPIEUP-O
0x3B48  0xBF41  # HANGUL SYLLABLE SSANGPIEUP-O-KIYEOK
0x3B49  0xBF44  # HANGUL SYLLABLE SSANGPIEUP-O-NIEUN
0x3B4A  0xBF48  # HANGUL SYLLABLE SSANGPIEUP-O-RIEUL
0x3B4B  0xBF50  # HANGUL SYLLABLE SSANGPIEUP-O-MIEUM
0x3B4C  0xBF51  # HANGUL SYLLABLE SSANGPIEUP-O-PIEUP
0x3B4D  0xBF55  # HANGUL SYLLABLE SSANGPIEUP-O-IEUNG
0x3B4E  0xBF94  # HANGUL SYLLABLE SSANGPIEUP-OE
0x3B4F  0xBFB0  # HANGUL SYLLABLE SSANGPIEUP-YO
0x3B50  0xBFC5  # HANGUL SYLLABLE SSANGPIEUP-YO-IEUNG
0x3B51  0xBFCC  # HANGUL SYLLABLE SSANGPIEUP-U
0x3B52  0xBFCD  # HANGUL SYLLABLE SSANGPIEUP-U-KIYEOK
0x3B53  0xBFD0  # HANGUL SYLLABLE SSANGPIEUP-U-NIEUN
0x3B54  0xBFD4  # HANGUL SYLLABLE SSANGPIEUP-U-RIEUL
0x3B55  0xBFDC  # HANGUL SYLLABLE SSANGPIEUP-U-MIEUM
0x3B56  0xBFDF  # HANGUL SYLLABLE SSANGPIEUP-U-SIOS
0x3B57  0xBFE1  # HANGUL SYLLABLE SSANGPIEUP-U-IEUNG
0x3B58  0xC03C  # HANGUL SYLLABLE SSANGPIEUP-YU
0x3B59  0xC051  # HANGUL SYLLABLE SSANGPIEUP-YU-IEUNG
0x3B5A  0xC058  # HANGUL SYLLABLE SSANGPIEUP-EU
0x3B5B  0xC05C  # HANGUL SYLLABLE SSANGPIEUP-EU-NIEUN
0x3B5C  0xC060  # HANGUL SYLLABLE SSANGPIEUP-EU-RIEUL
0x3B5D  0xC068  # HANGUL SYLLABLE SSANGPIEUP-EU-MIEUM
0x3B5E  0xC069  # HANGUL SYLLABLE SSANGPIEUP-EU-PIEUP
0x3B5F  0xC090  # HANGUL SYLLABLE SSANGPIEUP-I
0x3B60  0xC091  # HANGUL SYLLABLE SSANGPIEUP-I-KIYEOK
0x3B61  0xC094  # HANGUL SYLLABLE SSANGPIEUP-I-NIEUN
0x3B62  0xC098  # HANGUL SYLLABLE SSANGPIEUP-I-RIEUL
0x3B63  0xC0A0  # HANGUL SYLLABLE SSANGPIEUP-I-MIEUM
0x3B64  0xC0A1  # HANGUL SYLLABLE SSANGPIEUP-I-PIEUP
0x3B65  0xC0A3  # HANGUL SYLLABLE SSANGPIEUP-I-SIOS
0x3B66  0xC0A5  # HANGUL SYLLABLE SSANGPIEUP-I-IEUNG
0x3B67  0xC0AC  # HANGUL SYLLABLE SIOS-A
0x3B68  0xC0AD  # HANGUL SYLLABLE SIOS-A-KIYEOK
0x3B69  0xC0AF  # HANGUL SYLLABLE SIOS-A-KIYEOKSIOS
0x3B6A  0xC0B0  # HANGUL SYLLABLE SIOS-A-NIEUN
0x3B6B  0xC0B3  # HANGUL SYLLABLE SIOS-A-TIKEUT
0x3B6C  0xC0B4  # HANGUL SYLLABLE SIOS-A-RIEUL
0x3B6D  0xC0B5  # HANGUL SYLLABLE SIOS-A-RIEULKIYEOK
0x3B6E  0xC0B6  # HANGUL SYLLABLE SIOS-A-RIEULMIEUM
0x3B6F  0xC0BC  # HANGUL SYLLABLE SIOS-A-MIEUM
0x3B70  0xC0BD  # HANGUL SYLLABLE SIOS-A-PIEUP
0x3B71  0xC0BF  # HANGUL SYLLABLE SIOS-A-SIOS
0x3B72  0xC0C0  # HANGUL SYLLABLE SIOS-A-SSANGSIOS
0x3B73  0xC0C1  # HANGUL SYLLABLE SIOS-A-IEUNG
0x3B74  0xC0C5  # HANGUL SYLLABLE SIOS-A-THIEUTH
0x3B75  0xC0C8  # HANGUL SYLLABLE SIOS-AE
0x3B76  0xC0C9  # HANGUL SYLLABLE SIOS-AE-KIYEOK
0x3B77  0xC0CC  # HANGUL SYLLABLE SIOS-AE-NIEUN
0x3B78  0xC0D0  # HANGUL SYLLABLE SIOS-AE-RIEUL
0x3B79  0xC0D8  # HANGUL SYLLABLE SIOS-AE-MIEUM
0x3B7A  0xC0D9  # HANGUL SYLLABLE SIOS-AE-PIEUP
0x3B7B  0xC0DB  # HANGUL SYLLABLE SIOS-AE-SIOS
0x3B7C  0xC0DC  # HANGUL SYLLABLE SIOS-AE-SSANGSIOS
0x3B7D  0xC0DD  # HANGUL SYLLABLE SIOS-AE-IEUNG
0x3B7E  0xC0E4  # HANGUL SYLLABLE SIOS-YA
0x3C21  0xC0E5  # HANGUL SYLLABLE SIOS-YA-KIYEOK
0x3C22  0xC0E8  # HANGUL SYLLABLE SIOS-YA-NIEUN
0x3C23  0xC0EC  # HANGUL SYLLABLE SIOS-YA-RIEUL
0x3C24  0xC0F4  # HANGUL SYLLABLE SIOS-YA-MIEUM
0x3C25  0xC0F5  # HANGUL SYLLABLE SIOS-YA-PIEUP
0x3C26  0xC0F7  # HANGUL SYLLABLE SIOS-YA-SIOS
0x3C27  0xC0F9  # HANGUL SYLLABLE SIOS-YA-IEUNG
0x3C28  0xC100  # HANGUL SYLLABLE SIOS-YAE
0x3C29  0xC104  # HANGUL SYLLABLE SIOS-YAE-NIEUN
0x3C2A  0xC108  # HANGUL SYLLABLE SIOS-YAE-RIEUL
0x3C2B  0xC110  # HANGUL SYLLABLE SIOS-YAE-MIEUM
0x3C2C  0xC115  # HANGUL SYLLABLE SIOS-YAE-IEUNG
0x3C2D  0xC11C  # HANGUL SYLLABLE SIOS-EO
0x3C2E  0xC11D  # HANGUL SYLLABLE SIOS-EO-KIYEOK
0x3C2F  0xC11E  # HANGUL SYLLABLE SIOS-EO-SSANGKIYEOK
0x3C30  0xC11F  # HANGUL SYLLABLE SIOS-EO-KIYEOKSIOS
0x3C31  0xC120  # HANGUL SYLLABLE SIOS-EO-NIEUN
0x3C32  0xC123  # HANGUL SYLLABLE SIOS-EO-TIKEUT
0x3C33  0xC124  # HANGUL SYLLABLE SIOS-EO-RIEUL
0x3C34  0xC126  # HANGUL SYLLABLE SIOS-EO-RIEULMIEUM
0x3C35  0xC127  # HANGUL SYLLABLE SIOS-EO-RIEULPIEUP
0x3C36  0xC12C  # HANGUL SYLLABLE SIOS-EO-MIEUM
0x3C37  0xC12D  # HANGUL SYLLABLE SIOS-EO-PIEUP
0x3C38  0xC12F  # HANGUL SYLLABLE SIOS-EO-SIOS
0x3C39  0xC130  # HANGUL SYLLABLE SIOS-EO-SSANGSIOS
0x3C3A  0xC131  # HANGUL SYLLABLE SIOS-EO-IEUNG
0x3C3B  0xC136  # HANGUL SYLLABLE SIOS-EO-PHIEUPH
0x3C3C  0xC138  # HANGUL SYLLABLE SIOS-E
0x3C3D  0xC139  # HANGUL SYLLABLE SIOS-E-KIYEOK
0x3C3E  0xC13C  # HANGUL SYLLABLE SIOS-E-NIEUN
0x3C3F  0xC140  # HANGUL SYLLABLE SIOS-E-RIEUL
0x3C40  0xC148  # HANGUL SYLLABLE SIOS-E-MIEUM
0x3C41  0xC149  # HANGUL SYLLABLE SIOS-E-PIEUP
0x3C42  0xC14B  # HANGUL SYLLABLE SIOS-E-SIOS
0x3C43  0xC14C  # HANGUL SYLLABLE SIOS-E-SSANGSIOS
0x3C44  0xC14D  # HANGUL SYLLABLE SIOS-E-IEUNG
0x3C45  0xC154  # HANGUL SYLLABLE SIOS-YEO
0x3C46  0xC155  # HANGUL SYLLABLE SIOS-YEO-KIYEOK
0x3C47  0xC158  # HANGUL SYLLABLE SIOS-YEO-NIEUN
0x3C48  0xC15C  # HANGUL SYLLABLE SIOS-YEO-RIEUL
0x3C49  0xC164  # HANGUL SYLLABLE SIOS-YEO-MIEUM
0x3C4A  0xC165  # HANGUL SYLLABLE SIOS-YEO-PIEUP
0x3C4B  0xC167  # HANGUL SYLLABLE SIOS-YEO-SIOS
0x3C4C  0xC168  # HANGUL SYLLABLE SIOS-YEO-SSANGSIOS
0x3C4D  0xC169  # HANGUL SYLLABLE SIOS-YEO-IEUNG
0x3C4E  0xC170  # HANGUL SYLLABLE SIOS-YE
0x3C4F  0xC174  # HANGUL SYLLABLE SIOS-YE-NIEUN
0x3C50  0xC178  # HANGUL SYLLABLE SIOS-YE-RIEUL
0x3C51  0xC185  # HANGUL SYLLABLE SIOS-YE-IEUNG
0x3C52  0xC18C  # HANGUL SYLLABLE SIOS-O
0x3C53  0xC18D  # HANGUL SYLLABLE SIOS-O-KIYEOK
0x3C54  0xC18E  # HANGUL SYLLABLE SIOS-O-SSANGKIYEOK
0x3C55  0xC190  # HANGUL SYLLABLE SIOS-O-NIEUN
0x3C56  0xC194  # HANGUL SYLLABLE SIOS-O-RIEUL
0x3C57  0xC196  # HANGUL SYLLABLE SIOS-O-RIEULMIEUM
0x3C58  0xC19C  # HANGUL SYLLABLE SIOS-O-MIEUM
0x3C59  0xC19D  # HANGUL SYLLABLE SIOS-O-PIEUP
0x3C5A  0xC19F  # HANGUL SYLLABLE SIOS-O-SIOS
0x3C5B  0xC1A1  # HANGUL SYLLABLE SIOS-O-IEUNG
0x3C5C  0xC1A5  # HANGUL SYLLABLE SIOS-O-THIEUTH
0x3C5D  0xC1A8  # HANGUL SYLLABLE SIOS-WA
0x3C5E  0xC1A9  # HANGUL SYLLABLE SIOS-WA-KIYEOK
0x3C5F  0xC1AC  # HANGUL SYLLABLE SIOS-WA-NIEUN
0x3C60  0xC1B0  # HANGUL SYLLABLE SIOS-WA-RIEUL
0x3C61  0xC1BD  # HANGUL SYLLABLE SIOS-WA-IEUNG
0x3C62  0xC1C4  # HANGUL SYLLABLE SIOS-WAE
0x3C63  0xC1C8  # HANGUL SYLLABLE SIOS-WAE-NIEUN
0x3C64  0xC1CC  # HANGUL SYLLABLE SIOS-WAE-RIEUL
0x3C65  0xC1D4  # HANGUL SYLLABLE SIOS-WAE-MIEUM
0x3C66  0xC1D7  # HANGUL SYLLABLE SIOS-WAE-SIOS
0x3C67  0xC1D8  # HANGUL SYLLABLE SIOS-WAE-SSANGSIOS
0x3C68  0xC1E0  # HANGUL SYLLABLE SIOS-OE
0x3C69  0xC1E4  # HANGUL SYLLABLE SIOS-OE-NIEUN
0x3C6A  0xC1E8  # HANGUL SYLLABLE SIOS-OE-RIEUL
0x3C6B  0xC1F0  # HANGUL SYLLABLE SIOS-OE-MIEUM
0x3C6C  0xC1F1  # HANGUL SYLLABLE SIOS-OE-PIEUP
0x3C6D  0xC1F3  # HANGUL SYLLABLE SIOS-OE-SIOS
0x3C6E  0xC1FC  # HANGUL SYLLABLE SIOS-YO
0x3C6F  0xC1FD  # HANGUL SYLLABLE SIOS-YO-KIYEOK
0x3C70  0xC200  # HANGUL SYLLABLE SIOS-YO-NIEUN
0x3C71  0xC204  # HANGUL SYLLABLE SIOS-YO-RIEUL
0x3C72  0xC20C  # HANGUL SYLLABLE SIOS-YO-MIEUM
0x3C73  0xC20D  # HANGUL SYLLABLE SIOS-YO-PIEUP
0x3C74  0xC20F  # HANGUL SYLLABLE SIOS-YO-SIOS
0x3C75  0xC211  # HANGUL SYLLABLE SIOS-YO-IEUNG
0x3C76  0xC218  # HANGUL SYLLABLE SIOS-U
0x3C77  0xC219  # HANGUL SYLLABLE SIOS-U-KIYEOK
0x3C78  0xC21C  # HANGUL SYLLABLE SIOS-U-NIEUN
0x3C79  0xC21F  # HANGUL SYLLABLE SIOS-U-TIKEUT
0x3C7A  0xC220  # HANGUL SYLLABLE SIOS-U-RIEUL
0x3C7B  0xC228  # HANGUL SYLLABLE SIOS-U-MIEUM
0x3C7C  0xC229  # HANGUL SYLLABLE SIOS-U-PIEUP
0x3C7D  0xC22B  # HANGUL SYLLABLE SIOS-U-SIOS
0x3C7E  0xC22D  # HANGUL SYLLABLE SIOS-U-IEUNG
0x3D21  0xC22F  # HANGUL SYLLABLE SIOS-U-CHIEUCH
0x3D22  0xC231  # HANGUL SYLLABLE SIOS-U-THIEUTH
0x3D23  0xC232  # HANGUL SYLLABLE SIOS-U-PHIEUPH
0x3D24  0xC234  # HANGUL SYLLABLE SIOS-WEO
0x3D25  0xC248  # HANGUL SYLLABLE SIOS-WEO-SSANGSIOS
0x3D26  0xC250  # HANGUL SYLLABLE SIOS-WE
0x3D27  0xC251  # HANGUL SYLLABLE SIOS-WE-KIYEOK
0x3D28  0xC254  # HANGUL SYLLABLE SIOS-WE-NIEUN
0x3D29  0xC258  # HANGUL SYLLABLE SIOS-WE-RIEUL
0x3D2A  0xC260  # HANGUL SYLLABLE SIOS-WE-MIEUM
0x3D2B  0xC265  # HANGUL SYLLABLE SIOS-WE-IEUNG
0x3D2C  0xC26C  # HANGUL SYLLABLE SIOS-WI
0x3D2D  0xC26D  # HANGUL SYLLABLE SIOS-WI-KIYEOK
0x3D2E  0xC270  # HANGUL SYLLABLE SIOS-WI-NIEUN
0x3D2F  0xC274  # HANGUL SYLLABLE SIOS-WI-RIEUL
0x3D30  0xC27C  # HANGUL SYLLABLE SIOS-WI-MIEUM
0x3D31  0xC27D  # HANGUL SYLLABLE SIOS-WI-PIEUP
0x3D32  0xC27F  # HANGUL SYLLABLE SIOS-WI-SIOS
0x3D33  0xC281  # HANGUL SYLLABLE SIOS-WI-IEUNG
0x3D34  0xC288  # HANGUL SYLLABLE SIOS-YU
0x3D35  0xC289  # HANGUL SYLLABLE SIOS-YU-KIYEOK
0x3D36  0xC290  # HANGUL SYLLABLE SIOS-YU-RIEUL
0x3D37  0xC298  # HANGUL SYLLABLE SIOS-YU-MIEUM
0x3D38  0xC29B  # HANGUL SYLLABLE SIOS-YU-SIOS
0x3D39  0xC29D  # HANGUL SYLLABLE SIOS-YU-IEUNG
0x3D3A  0xC2A4  # HANGUL SYLLABLE SIOS-EU
0x3D3B  0xC2A5  # HANGUL SYLLABLE SIOS-EU-KIYEOK
0x3D3C  0xC2A8  # HANGUL SYLLABLE SIOS-EU-NIEUN
0x3D3D  0xC2AC  # HANGUL SYLLABLE SIOS-EU-RIEUL
0x3D3E  0xC2AD  # HANGUL SYLLABLE SIOS-EU-RIEULKIYEOK
0x3D3F  0xC2B4  # HANGUL SYLLABLE SIOS-EU-MIEUM
0x3D40  0xC2B5  # HANGUL SYLLABLE SIOS-EU-PIEUP
0x3D41  0xC2B7  # HANGUL SYLLABLE SIOS-EU-SIOS
0x3D42  0xC2B9  # HANGUL SYLLABLE SIOS-EU-IEUNG
0x3D43  0xC2DC  # HANGUL SYLLABLE SIOS-I
0x3D44  0xC2DD  # HANGUL SYLLABLE SIOS-I-KIYEOK
0x3D45  0xC2E0  # HANGUL SYLLABLE SIOS-I-NIEUN
0x3D46  0xC2E3  # HANGUL SYLLABLE SIOS-I-TIKEUT
0x3D47  0xC2E4  # HANGUL SYLLABLE SIOS-I-RIEUL
0x3D48  0xC2EB  # HANGUL SYLLABLE SIOS-I-RIEULHIEUH
0x3D49  0xC2EC  # HANGUL SYLLABLE SIOS-I-MIEUM
0x3D4A  0xC2ED  # HANGUL SYLLABLE SIOS-I-PIEUP
0x3D4B  0xC2EF  # HANGUL SYLLABLE SIOS-I-SIOS
0x3D4C  0xC2F1  # HANGUL SYLLABLE SIOS-I-IEUNG
0x3D4D  0xC2F6  # HANGUL SYLLABLE SIOS-I-PHIEUPH
0x3D4E  0xC2F8  # HANGUL SYLLABLE SSANGSIOS-A
0x3D4F  0xC2F9  # HANGUL SYLLABLE SSANGSIOS-A-KIYEOK
0x3D50  0xC2FB  # HANGUL SYLLABLE SSANGSIOS-A-KIYEOKSIOS
0x3D51  0xC2FC  # HANGUL SYLLABLE SSANGSIOS-A-NIEUN
0x3D52  0xC300  # HANGUL SYLLABLE SSANGSIOS-A-RIEUL
0x3D53  0xC308  # HANGUL SYLLABLE SSANGSIOS-A-MIEUM
0x3D54  0xC309  # HANGUL SYLLABLE SSANGSIOS-A-PIEUP
0x3D55  0xC30C  # HANGUL SYLLABLE SSANGSIOS-A-SSANGSIOS
0x3D56  0xC30D  # HANGUL SYLLABLE SSANGSIOS-A-IEUNG
0x3D57  0xC313  # HANGUL SYLLABLE SSANGSIOS-A-HIEUH
0x3D58  0xC314  # HANGUL SYLLABLE SSANGSIOS-AE
0x3D59  0xC315  # HANGUL SYLLABLE SSANGSIOS-AE-KIYEOK
0x3D5A  0xC318  # HANGUL SYLLABLE SSANGSIOS-AE-NIEUN
0x3D5B  0xC31C  # HANGUL SYLLABLE SSANGSIOS-AE-RIEUL
0x3D5C  0xC324  # HANGUL SYLLABLE SSANGSIOS-AE-MIEUM
0x3D5D  0xC325  # HANGUL SYLLABLE SSANGSIOS-AE-PIEUP
0x3D5E  0xC328  # HANGUL SYLLABLE SSANGSIOS-AE-SSANGSIOS
0x3D5F  0xC329  # HANGUL SYLLABLE SSANGSIOS-AE-IEUNG
0x3D60  0xC345  # HANGUL SYLLABLE SSANGSIOS-YA-IEUNG
0x3D61  0xC368  # HANGUL SYLLABLE SSANGSIOS-EO
0x3D62  0xC369  # HANGUL SYLLABLE SSANGSIOS-EO-KIYEOK
0x3D63  0xC36C  # HANGUL SYLLABLE SSANGSIOS-EO-NIEUN
0x3D64  0xC370  # HANGUL SYLLABLE SSANGSIOS-EO-RIEUL
0x3D65  0xC372  # HANGUL SYLLABLE SSANGSIOS-EO-RIEULMIEUM
0x3D66  0xC378  # HANGUL SYLLABLE SSANGSIOS-EO-MIEUM
0x3D67  0xC379  # HANGUL SYLLABLE SSANGSIOS-EO-PIEUP
0x3D68  0xC37C  # HANGUL SYLLABLE SSANGSIOS-EO-SSANGSIOS
0x3D69  0xC37D  # HANGUL SYLLABLE SSANGSIOS-EO-IEUNG
0x3D6A  0xC384  # HANGUL SYLLABLE SSANGSIOS-E
0x3D6B  0xC388  # HANGUL SYLLABLE SSANGSIOS-E-NIEUN
0x3D6C  0xC38C  # HANGUL SYLLABLE SSANGSIOS-E-RIEUL
0x3D6D  0xC3C0  # HANGUL SYLLABLE SSANGSIOS-YE-NIEUN
0x3D6E  0xC3D8  # HANGUL SYLLABLE SSANGSIOS-O
0x3D6F  0xC3D9  # HANGUL SYLLABLE SSANGSIOS-O-KIYEOK
0x3D70  0xC3DC  # HANGUL SYLLABLE SSANGSIOS-O-NIEUN
0x3D71  0xC3DF  # HANGUL SYLLABLE SSANGSIOS-O-TIKEUT
0x3D72  0xC3E0  # HANGUL SYLLABLE SSANGSIOS-O-RIEUL
0x3D73  0xC3E2  # HANGUL SYLLABLE SSANGSIOS-O-RIEULMIEUM
0x3D74  0xC3E8  # HANGUL SYLLABLE SSANGSIOS-O-MIEUM
0x3D75  0xC3E9  # HANGUL SYLLABLE SSANGSIOS-O-PIEUP
0x3D76  0xC3ED  # HANGUL SYLLABLE SSANGSIOS-O-IEUNG
0x3D77  0xC3F4  # HANGUL SYLLABLE SSANGSIOS-WA
0x3D78  0xC3F5  # HANGUL SYLLABLE SSANGSIOS-WA-KIYEOK
0x3D79  0xC3F8  # HANGUL SYLLABLE SSANGSIOS-WA-NIEUN
0x3D7A  0xC408  # HANGUL SYLLABLE SSANGSIOS-WA-SSANGSIOS
0x3D7B  0xC410  # HANGUL SYLLABLE SSANGSIOS-WAE
0x3D7C  0xC424  # HANGUL SYLLABLE SSANGSIOS-WAE-SSANGSIOS
0x3D7D  0xC42C  # HANGUL SYLLABLE SSANGSIOS-OE
0x3D7E  0xC430  # HANGUL SYLLABLE SSANGSIOS-OE-NIEUN
0x3E21  0xC434  # HANGUL SYLLABLE SSANGSIOS-OE-RIEUL
0x3E22  0xC43C  # HANGUL SYLLABLE SSANGSIOS-OE-MIEUM
0x3E23  0xC43D  # HANGUL SYLLABLE SSANGSIOS-OE-PIEUP
0x3E24  0xC448  # HANGUL SYLLABLE SSANGSIOS-YO
0x3E25  0xC464  # HANGUL SYLLABLE SSANGSIOS-U
0x3E26  0xC465  # HANGUL SYLLABLE SSANGSIOS-U-KIYEOK
0x3E27  0xC468  # HANGUL SYLLABLE SSANGSIOS-U-NIEUN
0x3E28  0xC46C  # HANGUL SYLLABLE SSANGSIOS-U-RIEUL
0x3E29  0xC474  # HANGUL SYLLABLE SSANGSIOS-U-MIEUM
0x3E2A  0xC475  # HANGUL SYLLABLE SSANGSIOS-U-PIEUP
0x3E2B  0xC479  # HANGUL SYLLABLE SSANGSIOS-U-IEUNG
0x3E2C  0xC480  # HANGUL SYLLABLE SSANGSIOS-WEO
0x3E2D  0xC494  # HANGUL SYLLABLE SSANGSIOS-WEO-SSANGSIOS
0x3E2E  0xC49C  # HANGUL SYLLABLE SSANGSIOS-WE
0x3E2F  0xC4B8  # HANGUL SYLLABLE SSANGSIOS-WI
0x3E30  0xC4BC  # HANGUL SYLLABLE SSANGSIOS-WI-NIEUN
0x3E31  0xC4E9  # HANGUL SYLLABLE SSANGSIOS-YU-IEUNG
0x3E32  0xC4F0  # HANGUL SYLLABLE SSANGSIOS-EU
0x3E33  0xC4F1  # HANGUL SYLLABLE SSANGSIOS-EU-KIYEOK
0x3E34  0xC4F4  # HANGUL SYLLABLE SSANGSIOS-EU-NIEUN
0x3E35  0xC4F8  # HANGUL SYLLABLE SSANGSIOS-EU-RIEUL
0x3E36  0xC4FA  # HANGUL SYLLABLE SSANGSIOS-EU-RIEULMIEUM
0x3E37  0xC4FF  # HANGUL SYLLABLE SSANGSIOS-EU-RIEULHIEUH
0x3E38  0xC500  # HANGUL SYLLABLE SSANGSIOS-EU-MIEUM
0x3E39  0xC501  # HANGUL SYLLABLE SSANGSIOS-EU-PIEUP
0x3E3A  0xC50C  # HANGUL SYLLABLE SSANGSIOS-YI
0x3E3B  0xC510  # HANGUL SYLLABLE SSANGSIOS-YI-NIEUN
0x3E3C  0xC514  # HANGUL SYLLABLE SSANGSIOS-YI-RIEUL
0x3E3D  0xC51C  # HANGUL SYLLABLE SSANGSIOS-YI-MIEUM
0x3E3E  0xC528  # HANGUL SYLLABLE SSANGSIOS-I
0x3E3F  0xC529  # HANGUL SYLLABLE SSANGSIOS-I-KIYEOK
0x3E40  0xC52C  # HANGUL SYLLABLE SSANGSIOS-I-NIEUN
0x3E41  0xC530  # HANGUL SYLLABLE SSANGSIOS-I-RIEUL
0x3E42  0xC538  # HANGUL SYLLABLE SSANGSIOS-I-MIEUM
0x3E43  0xC539  # HANGUL SYLLABLE SSANGSIOS-I-PIEUP
0x3E44  0xC53B  # HANGUL SYLLABLE SSANGSIOS-I-SIOS
0x3E45  0xC53D  # HANGUL SYLLABLE SSANGSIOS-I-IEUNG
0x3E46  0xC544  # HANGUL SYLLABLE IEUNG-A
0x3E47  0xC545  # HANGUL SYLLABLE IEUNG-A-KIYEOK
0x3E48  0xC548  # HANGUL SYLLABLE IEUNG-A-NIEUN
0x3E49  0xC549  # HANGUL SYLLABLE IEUNG-A-NIEUNCIEUC
0x3E4A  0xC54A  # HANGUL SYLLABLE IEUNG-A-NIEUNHIEUH
0x3E4B  0xC54C  # HANGUL SYLLABLE IEUNG-A-RIEUL
0x3E4C  0xC54D  # HANGUL SYLLABLE IEUNG-A-RIEULKIYEOK
0x3E4D  0xC54E  # HANGUL SYLLABLE IEUNG-A-RIEULMIEUM
0x3E4E  0xC553  # HANGUL SYLLABLE IEUNG-A-RIEULHIEUH
0x3E4F  0xC554  # HANGUL SYLLABLE IEUNG-A-MIEUM
0x3E50  0xC555  # HANGUL SYLLABLE IEUNG-A-PIEUP
0x3E51  0xC557  # HANGUL SYLLABLE IEUNG-A-SIOS
0x3E52  0xC558  # HANGUL SYLLABLE IEUNG-A-SSANGSIOS
0x3E53  0xC559  # HANGUL SYLLABLE IEUNG-A-IEUNG
0x3E54  0xC55D  # HANGUL SYLLABLE IEUNG-A-THIEUTH
0x3E55  0xC55E  # HANGUL SYLLABLE IEUNG-A-PHIEUPH
0x3E56  0xC560  # HANGUL SYLLABLE IEUNG-AE
0x3E57  0xC561  # HANGUL SYLLABLE IEUNG-AE-KIYEOK
0x3E58  0xC564  # HANGUL SYLLABLE IEUNG-AE-NIEUN
0x3E59  0xC568  # HANGUL SYLLABLE IEUNG-AE-RIEUL
0x3E5A  0xC570  # HANGUL SYLLABLE IEUNG-AE-MIEUM
0x3E5B  0xC571  # HANGUL SYLLABLE IEUNG-AE-PIEUP
0x3E5C  0xC573  # HANGUL SYLLABLE IEUNG-AE-SIOS
0x3E5D  0xC574  # HANGUL SYLLABLE IEUNG-AE-SSANGSIOS
0x3E5E  0xC575  # HANGUL SYLLABLE IEUNG-AE-IEUNG
0x3E5F  0xC57C  # HANGUL SYLLABLE IEUNG-YA
0x3E60  0xC57D  # HANGUL SYLLABLE IEUNG-YA-KIYEOK
0x3E61  0xC580  # HANGUL SYLLABLE IEUNG-YA-NIEUN
0x3E62  0xC584  # HANGUL SYLLABLE IEUNG-YA-RIEUL
0x3E63  0xC587  # HANGUL SYLLABLE IEUNG-YA-RIEULPIEUP
0x3E64  0xC58C  # HANGUL SYLLABLE IEUNG-YA-MIEUM
0x3E65  0xC58D  # HANGUL SYLLABLE IEUNG-YA-PIEUP
0x3E66  0xC58F  # HANGUL SYLLABLE IEUNG-YA-SIOS
0x3E67  0xC591  # HANGUL SYLLABLE IEUNG-YA-IEUNG
0x3E68  0xC595  # HANGUL SYLLABLE IEUNG-YA-THIEUTH
0x3E69  0xC597  # HANGUL SYLLABLE IEUNG-YA-HIEUH
0x3E6A  0xC598  # HANGUL SYLLABLE IEUNG-YAE
0x3E6B  0xC59C  # HANGUL SYLLABLE IEUNG-YAE-NIEUN
0x3E6C  0xC5A0  # HANGUL SYLLABLE IEUNG-YAE-RIEUL
0x3E6D  0xC5A9  # HANGUL SYLLABLE IEUNG-YAE-PIEUP
0x3E6E  0xC5B4  # HANGUL SYLLABLE IEUNG-EO
0x3E6F  0xC5B5  # HANGUL SYLLABLE IEUNG-EO-KIYEOK
0x3E70  0xC5B8  # HANGUL SYLLABLE IEUNG-EO-NIEUN
0x3E71  0xC5B9  # HANGUL SYLLABLE IEUNG-EO-NIEUNCIEUC
0x3E72  0xC5BB  # HANGUL SYLLABLE IEUNG-EO-TIKEUT
0x3E73  0xC5BC  # HANGUL SYLLABLE IEUNG-EO-RIEUL
0x3E74  0xC5BD  # HANGUL SYLLABLE IEUNG-EO-RIEULKIYEOK
0x3E75  0xC5BE  # HANGUL SYLLABLE IEUNG-EO-RIEULMIEUM
0x3E76  0xC5C4  # HANGUL SYLLABLE IEUNG-EO-MIEUM
0x3E77  0xC5C5  # HANGUL SYLLABLE IEUNG-EO-PIEUP
0x3E78  0xC5C6  # HANGUL SYLLABLE IEUNG-EO-PIEUPSIOS
0x3E79  0xC5C7  # HANGUL SYLLABLE IEUNG-EO-SIOS
0x3E7A  0xC5C8  # HANGUL SYLLABLE IEUNG-EO-SSANGSIOS
0x3E7B  0xC5C9  # HANGUL SYLLABLE IEUNG-EO-IEUNG
0x3E7C  0xC5CA  # HANGUL SYLLABLE IEUNG-EO-CIEUC
0x3E7D  0xC5CC  # HANGUL SYLLABLE IEUNG-EO-KHIEUKH
0x3E7E  0xC5CE  # HANGUL SYLLABLE IEUNG-EO-PHIEUPH
0x3F21  0xC5D0  # HANGUL SYLLABLE IEUNG-E
0x3F22  0xC5D1  # HANGUL SYLLABLE IEUNG-E-KIYEOK
0x3F23  0xC5D4  # HANGUL SYLLABLE IEUNG-E-NIEUN
0x3F24  0xC5D8  # HANGUL SYLLABLE IEUNG-E-RIEUL
0x3F25  0xC5E0  # HANGUL SYLLABLE IEUNG-E-MIEUM
0x3F26  0xC5E1  # HANGUL SYLLABLE IEUNG-E-PIEUP
0x3F27  0xC5E3  # HANGUL SYLLABLE IEUNG-E-SIOS
0x3F28  0xC5E5  # HANGUL SYLLABLE IEUNG-E-IEUNG
0x3F29  0xC5EC  # HANGUL SYLLABLE IEUNG-YEO
0x3F2A  0xC5ED  # HANGUL SYLLABLE IEUNG-YEO-KIYEOK
0x3F2B  0xC5EE  # HANGUL SYLLABLE IEUNG-YEO-SSANGKIYEOK
0x3F2C  0xC5F0  # HANGUL SYLLABLE IEUNG-YEO-NIEUN
0x3F2D  0xC5F4  # HANGUL SYLLABLE IEUNG-YEO-RIEUL
0x3F2E  0xC5F6  # HANGUL SYLLABLE IEUNG-YEO-RIEULMIEUM
0x3F2F  0xC5F7  # HANGUL SYLLABLE IEUNG-YEO-RIEULPIEUP
0x3F30  0xC5FC  # HANGUL SYLLABLE IEUNG-YEO-MIEUM
0x3F31  0xC5FD  # HANGUL SYLLABLE IEUNG-YEO-PIEUP
0x3F32  0xC5FE  # HANGUL SYLLABLE IEUNG-YEO-PIEUPSIOS
0x3F33  0xC5FF  # HANGUL SYLLABLE IEUNG-YEO-SIOS
0x3F34  0xC600  # HANGUL SYLLABLE IEUNG-YEO-SSANGSIOS
0x3F35  0xC601  # HANGUL SYLLABLE IEUNG-YEO-IEUNG
0x3F36  0xC605  # HANGUL SYLLABLE IEUNG-YEO-THIEUTH
0x3F37  0xC606  # HANGUL SYLLABLE IEUNG-YEO-PHIEUPH
0x3F38  0xC607  # HANGUL SYLLABLE IEUNG-YEO-HIEUH
0x3F39  0xC608  # HANGUL SYLLABLE IEUNG-YE
0x3F3A  0xC60C  # HANGUL SYLLABLE IEUNG-YE-NIEUN
0x3F3B  0xC610  # HANGUL SYLLABLE IEUNG-YE-RIEUL
0x3F3C  0xC618  # HANGUL SYLLABLE IEUNG-YE-MIEUM
0x3F3D  0xC619  # HANGUL SYLLABLE IEUNG-YE-PIEUP
0x3F3E  0xC61B  # HANGUL SYLLABLE IEUNG-YE-SIOS
0x3F3F  0xC61C  # HANGUL SYLLABLE IEUNG-YE-SSANGSIOS
0x3F40  0xC624  # HANGUL SYLLABLE IEUNG-O
0x3F41  0xC625  # HANGUL SYLLABLE IEUNG-O-KIYEOK
0x3F42  0xC628  # HANGUL SYLLABLE IEUNG-O-NIEUN
0x3F43  0xC62C  # HANGUL SYLLABLE IEUNG-O-RIEUL
0x3F44  0xC62D  # HANGUL SYLLABLE IEUNG-O-RIEULKIYEOK
0x3F45  0xC62E  # HANGUL SYLLABLE IEUNG-O-RIEULMIEUM
0x3F46  0xC630  # HANGUL SYLLABLE IEUNG-O-RIEULSIOS
0x3F47  0xC633  # HANGUL SYLLABLE IEUNG-O-RIEULHIEUH
0x3F48  0xC634  # HANGUL SYLLABLE IEUNG-O-MIEUM
0x3F49  0xC635  # HANGUL SYLLABLE IEUNG-O-PIEUP
0x3F4A  0xC637  # HANGUL SYLLABLE IEUNG-O-SIOS
0x3F4B  0xC639  # HANGUL SYLLABLE IEUNG-O-IEUNG
0x3F4C  0xC63B  # HANGUL SYLLABLE IEUNG-O-CHIEUCH
0x3F4D  0xC640  # HANGUL SYLLABLE IEUNG-WA
0x3F4E  0xC641  # HANGUL SYLLABLE IEUNG-WA-KIYEOK
0x3F4F  0xC644  # HANGUL SYLLABLE IEUNG-WA-NIEUN
0x3F50  0xC648  # HANGUL SYLLABLE IEUNG-WA-RIEUL
0x3F51  0xC650  # HANGUL SYLLABLE IEUNG-WA-MIEUM
0x3F52  0xC651  # HANGUL SYLLABLE IEUNG-WA-PIEUP
0x3F53  0xC653  # HANGUL SYLLABLE IEUNG-WA-SIOS
0x3F54  0xC654  # HANGUL SYLLABLE IEUNG-WA-SSANGSIOS
0x3F55  0xC655  # HANGUL SYLLABLE IEUNG-WA-IEUNG
0x3F56  0xC65C  # HANGUL SYLLABLE IEUNG-WAE
0x3F57  0xC65D  # HANGUL SYLLABLE IEUNG-WAE-KIYEOK
0x3F58  0xC660  # HANGUL SYLLABLE IEUNG-WAE-NIEUN
0x3F59  0xC66C  # HANGUL SYLLABLE IEUNG-WAE-MIEUM
0x3F5A  0xC66F  # HANGUL SYLLABLE IEUNG-WAE-SIOS
0x3F5B  0xC671  # HANGUL SYLLABLE IEUNG-WAE-IEUNG
0x3F5C  0xC678  # HANGUL SYLLABLE IEUNG-OE
0x3F5D  0xC679  # HANGUL SYLLABLE IEUNG-OE-KIYEOK
0x3F5E  0xC67C  # HANGUL SYLLABLE IEUNG-OE-NIEUN
0x3F5F  0xC680  # HANGUL SYLLABLE IEUNG-OE-RIEUL
0x3F60  0xC688  # HANGUL SYLLABLE IEUNG-OE-MIEUM
0x3F61  0xC689  # HANGUL SYLLABLE IEUNG-OE-PIEUP
0x3F62  0xC68B  # HANGUL SYLLABLE IEUNG-OE-SIOS
0x3F63  0xC68D  # HANGUL SYLLABLE IEUNG-OE-IEUNG
0x3F64  0xC694  # HANGUL SYLLABLE IEUNG-YO
0x3F65  0xC695  # HANGUL SYLLABLE IEUNG-YO-KIYEOK
0x3F66  0xC698  # HANGUL SYLLABLE IEUNG-YO-NIEUN
0x3F67  0xC69C  # HANGUL SYLLABLE IEUNG-YO-RIEUL
0x3F68  0xC6A4  # HANGUL SYLLABLE IEUNG-YO-MIEUM
0x3F69  0xC6A5  # HANGUL SYLLABLE IEUNG-YO-PIEUP
0x3F6A  0xC6A7  # HANGUL SYLLABLE IEUNG-YO-SIOS
0x3F6B  0xC6A9  # HANGUL SYLLABLE IEUNG-YO-IEUNG
0x3F6C  0xC6B0  # HANGUL SYLLABLE IEUNG-U
0x3F6D  0xC6B1  # HANGUL SYLLABLE IEUNG-U-KIYEOK
0x3F6E  0xC6B4  # HANGUL SYLLABLE IEUNG-U-NIEUN
0x3F6F  0xC6B8  # HANGUL SYLLABLE IEUNG-U-RIEUL
0x3F70  0xC6B9  # HANGUL SYLLABLE IEUNG-U-RIEULKIYEOK
0x3F71  0xC6BA  # HANGUL SYLLABLE IEUNG-U-RIEULMIEUM
0x3F72  0xC6C0  # HANGUL SYLLABLE IEUNG-U-MIEUM
0x3F73  0xC6C1  # HANGUL SYLLABLE IEUNG-U-PIEUP
0x3F74  0xC6C3  # HANGUL SYLLABLE IEUNG-U-SIOS
0x3F75  0xC6C5  # HANGUL SYLLABLE IEUNG-U-IEUNG
0x3F76  0xC6CC  # HANGUL SYLLABLE IEUNG-WEO
0x3F77  0xC6CD  # HANGUL SYLLABLE IEUNG-WEO-KIYEOK
0x3F78  0xC6D0  # HANGUL SYLLABLE IEUNG-WEO-NIEUN
0x3F79  0xC6D4  # HANGUL SYLLABLE IEUNG-WEO-RIEUL
0x3F7A  0xC6DC  # HANGUL SYLLABLE IEUNG-WEO-MIEUM
0x3F7B  0xC6DD  # HANGUL SYLLABLE IEUNG-WEO-PIEUP
0x3F7C  0xC6E0  # HANGUL SYLLABLE IEUNG-WEO-SSANGSIOS
0x3F7D  0xC6E1  # HANGUL SYLLABLE IEUNG-WEO-IEUNG
0x3F7E  0xC6E8  # HANGUL SYLLABLE IEUNG-WE
0x4021  0xC6E9  # HANGUL SYLLABLE IEUNG-WE-KIYEOK
0x4022  0xC6EC  # HANGUL SYLLABLE IEUNG-WE-NIEUN
0x4023  0xC6F0  # HANGUL SYLLABLE IEUNG-WE-RIEUL
0x4024  0xC6F8  # HANGUL SYLLABLE IEUNG-WE-MIEUM
0x4025  0xC6F9  # HANGUL SYLLABLE IEUNG-WE-PIEUP
0x4026  0xC6FD  # HANGUL SYLLABLE IEUNG-WE-IEUNG
0x4027  0xC704  # HANGUL SYLLABLE IEUNG-WI
0x4028  0xC705  # HANGUL SYLLABLE IEUNG-WI-KIYEOK
0x4029  0xC708  # HANGUL SYLLABLE IEUNG-WI-NIEUN
0x402A  0xC70C  # HANGUL SYLLABLE IEUNG-WI-RIEUL
0x402B  0xC714  # HANGUL SYLLABLE IEUNG-WI-MIEUM
0x402C  0xC715  # HANGUL SYLLABLE IEUNG-WI-PIEUP
0x402D  0xC717  # HANGUL SYLLABLE IEUNG-WI-SIOS
0x402E  0xC719  # HANGUL SYLLABLE IEUNG-WI-IEUNG
0x402F  0xC720  # HANGUL SYLLABLE IEUNG-YU
0x4030  0xC721  # HANGUL SYLLABLE IEUNG-YU-KIYEOK
0x4031  0xC724  # HANGUL SYLLABLE IEUNG-YU-NIEUN
0x4032  0xC728  # HANGUL SYLLABLE IEUNG-YU-RIEUL
0x4033  0xC730  # HANGUL SYLLABLE IEUNG-YU-MIEUM
0x4034  0xC731  # HANGUL SYLLABLE IEUNG-YU-PIEUP
0x4035  0xC733  # HANGUL SYLLABLE IEUNG-YU-SIOS
0x4036  0xC735  # HANGUL SYLLABLE IEUNG-YU-IEUNG
0x4037  0xC737  # HANGUL SYLLABLE IEUNG-YU-CHIEUCH
0x4038  0xC73C  # HANGUL SYLLABLE IEUNG-EU
0x4039  0xC73D  # HANGUL SYLLABLE IEUNG-EU-KIYEOK
0x403A  0xC740  # HANGUL SYLLABLE IEUNG-EU-NIEUN
0x403B  0xC744  # HANGUL SYLLABLE IEUNG-EU-RIEUL
0x403C  0xC74A  # HANGUL SYLLABLE IEUNG-EU-RIEULPHIEUPH
0x403D  0xC74C  # HANGUL SYLLABLE IEUNG-EU-MIEUM
0x403E  0xC74D  # HANGUL SYLLABLE IEUNG-EU-PIEUP
0x403F  0xC74F  # HANGUL SYLLABLE IEUNG-EU-SIOS
0x4040  0xC751  # HANGUL SYLLABLE IEUNG-EU-IEUNG
0x4041  0xC752  # HANGUL SYLLABLE IEUNG-EU-CIEUC
0x4042  0xC753  # HANGUL SYLLABLE IEUNG-EU-CHIEUCH
0x4043  0xC754  # HANGUL SYLLABLE IEUNG-EU-KHIEUKH
0x4044  0xC755  # HANGUL SYLLABLE IEUNG-EU-THIEUTH
0x4045  0xC756  # HANGUL SYLLABLE IEUNG-EU-PHIEUPH
0x4046  0xC757  # HANGUL SYLLABLE IEUNG-EU-HIEUH
0x4047  0xC758  # HANGUL SYLLABLE IEUNG-YI
0x4048  0xC75C  # HANGUL SYLLABLE IEUNG-YI-NIEUN
0x4049  0xC760  # HANGUL SYLLABLE IEUNG-YI-RIEUL
0x404A  0xC768  # HANGUL SYLLABLE IEUNG-YI-MIEUM
0x404B  0xC76B  # HANGUL SYLLABLE IEUNG-YI-SIOS
0x404C  0xC774  # HANGUL SYLLABLE IEUNG-I
0x404D  0xC775  # HANGUL SYLLABLE IEUNG-I-KIYEOK
0x404E  0xC778  # HANGUL SYLLABLE IEUNG-I-NIEUN
0x404F  0xC77C  # HANGUL SYLLABLE IEUNG-I-RIEUL
0x4050  0xC77D  # HANGUL SYLLABLE IEUNG-I-RIEULKIYEOK
0x4051  0xC77E  # HANGUL SYLLABLE IEUNG-I-RIEULMIEUM
0x4052  0xC783  # HANGUL SYLLABLE IEUNG-I-RIEULHIEUH
0x4053  0xC784  # HANGUL SYLLABLE IEUNG-I-MIEUM
0x4054  0xC785  # HANGUL SYLLABLE IEUNG-I-PIEUP
0x4055  0xC787  # HANGUL SYLLABLE IEUNG-I-SIOS
0x4056  0xC788  # HANGUL SYLLABLE IEUNG-I-SSANGSIOS
0x4057  0xC789  # HANGUL SYLLABLE IEUNG-I-IEUNG
0x4058  0xC78A  # HANGUL SYLLABLE IEUNG-I-CIEUC
0x4059  0xC78E  # HANGUL SYLLABLE IEUNG-I-PHIEUPH
0x405A  0xC790  # HANGUL SYLLABLE CIEUC-A
0x405B  0xC791  # HANGUL SYLLABLE CIEUC-A-KIYEOK
0x405C  0xC794  # HANGUL SYLLABLE CIEUC-A-NIEUN
0x405D  0xC796  # HANGUL SYLLABLE CIEUC-A-NIEUNHIEUH
0x405E  0xC797  # HANGUL SYLLABLE CIEUC-A-TIKEUT
0x405F  0xC798  # HANGUL SYLLABLE CIEUC-A-RIEUL
0x4060  0xC79A  # HANGUL SYLLABLE CIEUC-A-RIEULMIEUM
0x4061  0xC7A0  # HANGUL SYLLABLE CIEUC-A-MIEUM
0x4062  0xC7A1  # HANGUL SYLLABLE CIEUC-A-PIEUP
0x4063  0xC7A3  # HANGUL SYLLABLE CIEUC-A-SIOS
0x4064  0xC7A4  # HANGUL SYLLABLE CIEUC-A-SSANGSIOS
0x4065  0xC7A5  # HANGUL SYLLABLE CIEUC-A-IEUNG
0x4066  0xC7A6  # HANGUL SYLLABLE CIEUC-A-CIEUC
0x4067  0xC7AC  # HANGUL SYLLABLE CIEUC-AE
0x4068  0xC7AD  # HANGUL SYLLABLE CIEUC-AE-KIYEOK
0x4069  0xC7B0  # HANGUL SYLLABLE CIEUC-AE-NIEUN
0x406A  0xC7B4  # HANGUL SYLLABLE CIEUC-AE-RIEUL
0x406B  0xC7BC  # HANGUL SYLLABLE CIEUC-AE-MIEUM
0x406C  0xC7BD  # HANGUL SYLLABLE CIEUC-AE-PIEUP
0x406D  0xC7BF  # HANGUL SYLLABLE CIEUC-AE-SIOS
0x406E  0xC7C0  # HANGUL SYLLABLE CIEUC-AE-SSANGSIOS
0x406F  0xC7C1  # HANGUL SYLLABLE CIEUC-AE-IEUNG
0x4070  0xC7C8  # HANGUL SYLLABLE CIEUC-YA
0x4071  0xC7C9  # HANGUL SYLLABLE CIEUC-YA-KIYEOK
0x4072  0xC7CC  # HANGUL SYLLABLE CIEUC-YA-NIEUN
0x4073  0xC7CE  # HANGUL SYLLABLE CIEUC-YA-NIEUNHIEUH
0x4074  0xC7D0  # HANGUL SYLLABLE CIEUC-YA-RIEUL
0x4075  0xC7D8  # HANGUL SYLLABLE CIEUC-YA-MIEUM
0x4076  0xC7DD  # HANGUL SYLLABLE CIEUC-YA-IEUNG
0x4077  0xC7E4  # HANGUL SYLLABLE CIEUC-YAE
0x4078  0xC7E8  # HANGUL SYLLABLE CIEUC-YAE-NIEUN
0x4079  0xC7EC  # HANGUL SYLLABLE CIEUC-YAE-RIEUL
0x407A  0xC800  # HANGUL SYLLABLE CIEUC-EO
0x407B  0xC801  # HANGUL SYLLABLE CIEUC-EO-KIYEOK
0x407C  0xC804  # HANGUL SYLLABLE CIEUC-EO-NIEUN
0x407D  0xC808  # HANGUL SYLLABLE CIEUC-EO-RIEUL
0x407E  0xC80A  # HANGUL SYLLABLE CIEUC-EO-RIEULMIEUM
0x4121  0xC810  # HANGUL SYLLABLE CIEUC-EO-MIEUM
0x4122  0xC811  # HANGUL SYLLABLE CIEUC-EO-PIEUP
0x4123  0xC813  # HANGUL SYLLABLE CIEUC-EO-SIOS
0x4124  0xC815  # HANGUL SYLLABLE CIEUC-EO-IEUNG
0x4125  0xC816  # HANGUL SYLLABLE CIEUC-EO-CIEUC
0x4126  0xC81C  # HANGUL SYLLABLE CIEUC-E
0x4127  0xC81D  # HANGUL SYLLABLE CIEUC-E-KIYEOK
0x4128  0xC820  # HANGUL SYLLABLE CIEUC-E-NIEUN
0x4129  0xC824  # HANGUL SYLLABLE CIEUC-E-RIEUL
0x412A  0xC82C  # HANGUL SYLLABLE CIEUC-E-MIEUM
0x412B  0xC82D  # HANGUL SYLLABLE CIEUC-E-PIEUP
0x412C  0xC82F  # HANGUL SYLLABLE CIEUC-E-SIOS
0x412D  0xC831  # HANGUL SYLLABLE CIEUC-E-IEUNG
0x412E  0xC838  # HANGUL SYLLABLE CIEUC-YEO
0x412F  0xC83C  # HANGUL SYLLABLE CIEUC-YEO-NIEUN
0x4130  0xC840  # HANGUL SYLLABLE CIEUC-YEO-RIEUL
0x4131  0xC848  # HANGUL SYLLABLE CIEUC-YEO-MIEUM
0x4132  0xC849  # HANGUL SYLLABLE CIEUC-YEO-PIEUP
0x4133  0xC84C  # HANGUL SYLLABLE CIEUC-YEO-SSANGSIOS
0x4134  0xC84D  # HANGUL SYLLABLE CIEUC-YEO-IEUNG
0x4135  0xC854  # HANGUL SYLLABLE CIEUC-YE
0x4136  0xC870  # HANGUL SYLLABLE CIEUC-O
0x4137  0xC871  # HANGUL SYLLABLE CIEUC-O-KIYEOK
0x4138  0xC874  # HANGUL SYLLABLE CIEUC-O-NIEUN
0x4139  0xC878  # HANGUL SYLLABLE CIEUC-O-RIEUL
0x413A  0xC87A  # HANGUL SYLLABLE CIEUC-O-RIEULMIEUM
0x413B  0xC880  # HANGUL SYLLABLE CIEUC-O-MIEUM
0x413C  0xC881  # HANGUL SYLLABLE CIEUC-O-PIEUP
0x413D  0xC883  # HANGUL SYLLABLE CIEUC-O-SIOS
0x413E  0xC885  # HANGUL SYLLABLE CIEUC-O-IEUNG
0x413F  0xC886  # HANGUL SYLLABLE CIEUC-O-CIEUC
0x4140  0xC887  # HANGUL SYLLABLE CIEUC-O-CHIEUCH
0x4141  0xC88B  # HANGUL SYLLABLE CIEUC-O-HIEUH
0x4142  0xC88C  # HANGUL SYLLABLE CIEUC-WA
0x4143  0xC88D  # HANGUL SYLLABLE CIEUC-WA-KIYEOK
0x4144  0xC894  # HANGUL SYLLABLE CIEUC-WA-RIEUL
0x4145  0xC89D  # HANGUL SYLLABLE CIEUC-WA-PIEUP
0x4146  0xC89F  # HANGUL SYLLABLE CIEUC-WA-SIOS
0x4147  0xC8A1  # HANGUL SYLLABLE CIEUC-WA-IEUNG
0x4148  0xC8A8  # HANGUL SYLLABLE CIEUC-WAE
0x4149  0xC8BC  # HANGUL SYLLABLE CIEUC-WAE-SSANGSIOS
0x414A  0xC8BD  # HANGUL SYLLABLE CIEUC-WAE-IEUNG
0x414B  0xC8C4  # HANGUL SYLLABLE CIEUC-OE
0x414C  0xC8C8  # HANGUL SYLLABLE CIEUC-OE-NIEUN
0x414D  0xC8CC  # HANGUL SYLLABLE CIEUC-OE-RIEUL
0x414E  0xC8D4  # HANGUL SYLLABLE CIEUC-OE-MIEUM
0x414F  0xC8D5  # HANGUL SYLLABLE CIEUC-OE-PIEUP
0x4150  0xC8D7  # HANGUL SYLLABLE CIEUC-OE-SIOS
0x4151  0xC8D9  # HANGUL SYLLABLE CIEUC-OE-IEUNG
0x4152  0xC8E0  # HANGUL SYLLABLE CIEUC-YO
0x4153  0xC8E1  # HANGUL SYLLABLE CIEUC-YO-KIYEOK
0x4154  0xC8E4  # HANGUL SYLLABLE CIEUC-YO-NIEUN
0x4155  0xC8F5  # HANGUL SYLLABLE CIEUC-YO-IEUNG
0x4156  0xC8FC  # HANGUL SYLLABLE CIEUC-U
0x4157  0xC8FD  # HANGUL SYLLABLE CIEUC-U-KIYEOK
0x4158  0xC900  # HANGUL SYLLABLE CIEUC-U-NIEUN
0x4159  0xC904  # HANGUL SYLLABLE CIEUC-U-RIEUL
0x415A  0xC905  # HANGUL SYLLABLE CIEUC-U-RIEULKIYEOK
0x415B  0xC906  # HANGUL SYLLABLE CIEUC-U-RIEULMIEUM
0x415C  0xC90C  # HANGUL SYLLABLE CIEUC-U-MIEUM
0x415D  0xC90D  # HANGUL SYLLABLE CIEUC-U-PIEUP
0x415E  0xC90F  # HANGUL SYLLABLE CIEUC-U-SIOS
0x415F  0xC911  # HANGUL SYLLABLE CIEUC-U-IEUNG
0x4160  0xC918  # HANGUL SYLLABLE CIEUC-WEO
0x4161  0xC92C  # HANGUL SYLLABLE CIEUC-WEO-SSANGSIOS
0x4162  0xC934  # HANGUL SYLLABLE CIEUC-WE
0x4163  0xC950  # HANGUL SYLLABLE CIEUC-WI
0x4164  0xC951  # HANGUL SYLLABLE CIEUC-WI-KIYEOK
0x4165  0xC954  # HANGUL SYLLABLE CIEUC-WI-NIEUN
0x4166  0xC958  # HANGUL SYLLABLE CIEUC-WI-RIEUL
0x4167  0xC960  # HANGUL SYLLABLE CIEUC-WI-MIEUM
0x4168  0xC961  # HANGUL SYLLABLE CIEUC-WI-PIEUP
0x4169  0xC963  # HANGUL SYLLABLE CIEUC-WI-SIOS
0x416A  0xC96C  # HANGUL SYLLABLE CIEUC-YU
0x416B  0xC970  # HANGUL SYLLABLE CIEUC-YU-NIEUN
0x416C  0xC974  # HANGUL SYLLABLE CIEUC-YU-RIEUL
0x416D  0xC97C  # HANGUL SYLLABLE CIEUC-YU-MIEUM
0x416E  0xC988  # HANGUL SYLLABLE CIEUC-EU
0x416F  0xC989  # HANGUL SYLLABLE CIEUC-EU-KIYEOK
0x4170  0xC98C  # HANGUL SYLLABLE CIEUC-EU-NIEUN
0x4171  0xC990  # HANGUL SYLLABLE CIEUC-EU-RIEUL
0x4172  0xC998  # HANGUL SYLLABLE CIEUC-EU-MIEUM
0x4173  0xC999  # HANGUL SYLLABLE CIEUC-EU-PIEUP
0x4174  0xC99B  # HANGUL SYLLABLE CIEUC-EU-SIOS
0x4175  0xC99D  # HANGUL SYLLABLE CIEUC-EU-IEUNG
0x4176  0xC9C0  # HANGUL SYLLABLE CIEUC-I
0x4177  0xC9C1  # HANGUL SYLLABLE CIEUC-I-KIYEOK
0x4178  0xC9C4  # HANGUL SYLLABLE CIEUC-I-NIEUN
0x4179  0xC9C7  # HANGUL SYLLABLE CIEUC-I-TIKEUT
0x417A  0xC9C8  # HANGUL SYLLABLE CIEUC-I-RIEUL
0x417B  0xC9CA  # HANGUL SYLLABLE CIEUC-I-RIEULMIEUM
0x417C  0xC9D0  # HANGUL SYLLABLE CIEUC-I-MIEUM
0x417D  0xC9D1  # HANGUL SYLLABLE CIEUC-I-PIEUP
0x417E  0xC9D3  # HANGUL SYLLABLE CIEUC-I-SIOS
0x4221  0xC9D5  # HANGUL SYLLABLE CIEUC-I-IEUNG
0x4222  0xC9D6  # HANGUL SYLLABLE CIEUC-I-CIEUC
0x4223  0xC9D9  # HANGUL SYLLABLE CIEUC-I-THIEUTH
0x4224  0xC9DA  # HANGUL SYLLABLE CIEUC-I-PHIEUPH
0x4225  0xC9DC  # HANGUL SYLLABLE SSANGCIEUC-A
0x4226  0xC9DD  # HANGUL SYLLABLE SSANGCIEUC-A-KIYEOK
0x4227  0xC9E0  # HANGUL SYLLABLE SSANGCIEUC-A-NIEUN
0x4228  0xC9E2  # HANGUL SYLLABLE SSANGCIEUC-A-NIEUNHIEUH
0x4229  0xC9E4  # HANGUL SYLLABLE SSANGCIEUC-A-RIEUL
0x422A  0xC9E7  # HANGUL SYLLABLE SSANGCIEUC-A-RIEULPIEUP
0x422B  0xC9EC  # HANGUL SYLLABLE SSANGCIEUC-A-MIEUM
0x422C  0xC9ED  # HANGUL SYLLABLE SSANGCIEUC-A-PIEUP
0x422D  0xC9EF  # HANGUL SYLLABLE SSANGCIEUC-A-SIOS
0x422E  0xC9F0  # HANGUL SYLLABLE SSANGCIEUC-A-SSANGSIOS
0x422F  0xC9F1  # HANGUL SYLLABLE SSANGCIEUC-A-IEUNG
0x4230  0xC9F8  # HANGUL SYLLABLE SSANGCIEUC-AE
0x4231  0xC9F9  # HANGUL SYLLABLE SSANGCIEUC-AE-KIYEOK
0x4232  0xC9FC  # HANGUL SYLLABLE SSANGCIEUC-AE-NIEUN
0x4233  0xCA00  # HANGUL SYLLABLE SSANGCIEUC-AE-RIEUL
0x4234  0xCA08  # HANGUL SYLLABLE SSANGCIEUC-AE-MIEUM
0x4235  0xCA09  # HANGUL SYLLABLE SSANGCIEUC-AE-PIEUP
0x4236  0xCA0B  # HANGUL SYLLABLE SSANGCIEUC-AE-SIOS
0x4237  0xCA0C  # HANGUL SYLLABLE SSANGCIEUC-AE-SSANGSIOS
0x4238  0xCA0D  # HANGUL SYLLABLE SSANGCIEUC-AE-IEUNG
0x4239  0xCA14  # HANGUL SYLLABLE SSANGCIEUC-YA
0x423A  0xCA18  # HANGUL SYLLABLE SSANGCIEUC-YA-NIEUN
0x423B  0xCA29  # HANGUL SYLLABLE SSANGCIEUC-YA-IEUNG
0x423C  0xCA4C  # HANGUL SYLLABLE SSANGCIEUC-EO
0x423D  0xCA4D  # HANGUL SYLLABLE SSANGCIEUC-EO-KIYEOK
0x423E  0xCA50  # HANGUL SYLLABLE SSANGCIEUC-EO-NIEUN
0x423F  0xCA54  # HANGUL SYLLABLE SSANGCIEUC-EO-RIEUL
0x4240  0xCA5C  # HANGUL SYLLABLE SSANGCIEUC-EO-MIEUM
0x4241  0xCA5D  # HANGUL SYLLABLE SSANGCIEUC-EO-PIEUP
0x4242  0xCA5F  # HANGUL SYLLABLE SSANGCIEUC-EO-SIOS
0x4243  0xCA60  # HANGUL SYLLABLE SSANGCIEUC-EO-SSANGSIOS
0x4244  0xCA61  # HANGUL SYLLABLE SSANGCIEUC-EO-IEUNG
0x4245  0xCA68  # HANGUL SYLLABLE SSANGCIEUC-E
0x4246  0xCA7D  # HANGUL SYLLABLE SSANGCIEUC-E-IEUNG
0x4247  0xCA84  # HANGUL SYLLABLE SSANGCIEUC-YEO
0x4248  0xCA98  # HANGUL SYLLABLE SSANGCIEUC-YEO-SSANGSIOS
0x4249  0xCABC  # HANGUL SYLLABLE SSANGCIEUC-O
0x424A  0xCABD  # HANGUL SYLLABLE SSANGCIEUC-O-KIYEOK
0x424B  0xCAC0  # HANGUL SYLLABLE SSANGCIEUC-O-NIEUN
0x424C  0xCAC4  # HANGUL SYLLABLE SSANGCIEUC-O-RIEUL
0x424D  0xCACC  # HANGUL SYLLABLE SSANGCIEUC-O-MIEUM
0x424E  0xCACD  # HANGUL SYLLABLE SSANGCIEUC-O-PIEUP
0x424F  0xCACF  # HANGUL SYLLABLE SSANGCIEUC-O-SIOS
0x4250  0xCAD1  # HANGUL SYLLABLE SSANGCIEUC-O-IEUNG
0x4251  0xCAD3  # HANGUL SYLLABLE SSANGCIEUC-O-CHIEUCH
0x4252  0xCAD8  # HANGUL SYLLABLE SSANGCIEUC-WA
0x4253  0xCAD9  # HANGUL SYLLABLE SSANGCIEUC-WA-KIYEOK
0x4254  0xCAE0  # HANGUL SYLLABLE SSANGCIEUC-WA-RIEUL
0x4255  0xCAEC  # HANGUL SYLLABLE SSANGCIEUC-WA-SSANGSIOS
0x4256  0xCAF4  # HANGUL SYLLABLE SSANGCIEUC-WAE
0x4257  0xCB08  # HANGUL SYLLABLE SSANGCIEUC-WAE-SSANGSIOS
0x4258  0xCB10  # HANGUL SYLLABLE SSANGCIEUC-OE
0x4259  0xCB14  # HANGUL SYLLABLE SSANGCIEUC-OE-NIEUN
0x425A  0xCB18  # HANGUL SYLLABLE SSANGCIEUC-OE-RIEUL
0x425B  0xCB20  # HANGUL SYLLABLE SSANGCIEUC-OE-MIEUM
0x425C  0xCB21  # HANGUL SYLLABLE SSANGCIEUC-OE-PIEUP
0x425D  0xCB41  # HANGUL SYLLABLE SSANGCIEUC-YO-IEUNG
0x425E  0xCB48  # HANGUL SYLLABLE SSANGCIEUC-U
0x425F  0xCB49  # HANGUL SYLLABLE SSANGCIEUC-U-KIYEOK
0x4260  0xCB4C  # HANGUL SYLLABLE SSANGCIEUC-U-NIEUN
0x4261  0xCB50  # HANGUL SYLLABLE SSANGCIEUC-U-RIEUL
0x4262  0xCB58  # HANGUL SYLLABLE SSANGCIEUC-U-MIEUM
0x4263  0xCB59  # HANGUL SYLLABLE SSANGCIEUC-U-PIEUP
0x4264  0xCB5D  # HANGUL SYLLABLE SSANGCIEUC-U-IEUNG
0x4265  0xCB64  # HANGUL SYLLABLE SSANGCIEUC-WEO
0x4266  0xCB78  # HANGUL SYLLABLE SSANGCIEUC-WEO-SSANGSIOS
0x4267  0xCB79  # HANGUL SYLLABLE SSANGCIEUC-WEO-IEUNG
0x4268  0xCB9C  # HANGUL SYLLABLE SSANGCIEUC-WI
0x4269  0xCBB8  # HANGUL SYLLABLE SSANGCIEUC-YU
0x426A  0xCBD4  # HANGUL SYLLABLE SSANGCIEUC-EU
0x426B  0xCBE4  # HANGUL SYLLABLE SSANGCIEUC-EU-MIEUM
0x426C  0xCBE7  # HANGUL SYLLABLE SSANGCIEUC-EU-SIOS
0x426D  0xCBE9  # HANGUL SYLLABLE SSANGCIEUC-EU-IEUNG
0x426E  0xCC0C  # HANGUL SYLLABLE SSANGCIEUC-I
0x426F  0xCC0D  # HANGUL SYLLABLE SSANGCIEUC-I-KIYEOK
0x4270  0xCC10  # HANGUL SYLLABLE SSANGCIEUC-I-NIEUN
0x4271  0xCC14  # HANGUL SYLLABLE SSANGCIEUC-I-RIEUL
0x4272  0xCC1C  # HANGUL SYLLABLE SSANGCIEUC-I-MIEUM
0x4273  0xCC1D  # HANGUL SYLLABLE SSANGCIEUC-I-PIEUP
0x4274  0xCC21  # HANGUL SYLLABLE SSANGCIEUC-I-IEUNG
0x4275  0xCC22  # HANGUL SYLLABLE SSANGCIEUC-I-CIEUC
0x4276  0xCC27  # HANGUL SYLLABLE SSANGCIEUC-I-HIEUH
0x4277  0xCC28  # HANGUL SYLLABLE CHIEUCH-A
0x4278  0xCC29  # HANGUL SYLLABLE CHIEUCH-A-KIYEOK
0x4279  0xCC2C  # HANGUL SYLLABLE CHIEUCH-A-NIEUN
0x427A  0xCC2E  # HANGUL SYLLABLE CHIEUCH-A-NIEUNHIEUH
0x427B  0xCC30  # HANGUL SYLLABLE CHIEUCH-A-RIEUL
0x427C  0xCC38  # HANGUL SYLLABLE CHIEUCH-A-MIEUM
0x427D  0xCC39  # HANGUL SYLLABLE CHIEUCH-A-PIEUP
0x427E  0xCC3B  # HANGUL SYLLABLE CHIEUCH-A-SIOS
0x4321  0xCC3C  # HANGUL SYLLABLE CHIEUCH-A-SSANGSIOS
0x4322  0xCC3D  # HANGUL SYLLABLE CHIEUCH-A-IEUNG
0x4323  0xCC3E  # HANGUL SYLLABLE CHIEUCH-A-CIEUC
0x4324  0xCC44  # HANGUL SYLLABLE CHIEUCH-AE
0x4325  0xCC45  # HANGUL SYLLABLE CHIEUCH-AE-KIYEOK
0x4326  0xCC48  # HANGUL SYLLABLE CHIEUCH-AE-NIEUN
0x4327  0xCC4C  # HANGUL SYLLABLE CHIEUCH-AE-RIEUL
0x4328  0xCC54  # HANGUL SYLLABLE CHIEUCH-AE-MIEUM
0x4329  0xCC55  # HANGUL SYLLABLE CHIEUCH-AE-PIEUP
0x432A  0xCC57  # HANGUL SYLLABLE CHIEUCH-AE-SIOS
0x432B  0xCC58  # HANGUL SYLLABLE CHIEUCH-AE-SSANGSIOS
0x432C  0xCC59  # HANGUL SYLLABLE CHIEUCH-AE-IEUNG
0x432D  0xCC60  # HANGUL SYLLABLE CHIEUCH-YA
0x432E  0xCC64  # HANGUL SYLLABLE CHIEUCH-YA-NIEUN
0x432F  0xCC66  # HANGUL SYLLABLE CHIEUCH-YA-NIEUNHIEUH
0x4330  0xCC68  # HANGUL SYLLABLE CHIEUCH-YA-RIEUL
0x4331  0xCC70  # HANGUL SYLLABLE CHIEUCH-YA-MIEUM
0x4332  0xCC75  # HANGUL SYLLABLE CHIEUCH-YA-IEUNG
0x4333  0xCC98  # HANGUL SYLLABLE CHIEUCH-EO
0x4334  0xCC99  # HANGUL SYLLABLE CHIEUCH-EO-KIYEOK
0x4335  0xCC9C  # HANGUL SYLLABLE CHIEUCH-EO-NIEUN
0x4336  0xCCA0  # HANGUL SYLLABLE CHIEUCH-EO-RIEUL
0x4337  0xCCA8  # HANGUL SYLLABLE CHIEUCH-EO-MIEUM
0x4338  0xCCA9  # HANGUL SYLLABLE CHIEUCH-EO-PIEUP
0x4339  0xCCAB  # HANGUL SYLLABLE CHIEUCH-EO-SIOS
0x433A  0xCCAC  # HANGUL SYLLABLE CHIEUCH-EO-SSANGSIOS
0x433B  0xCCAD  # HANGUL SYLLABLE CHIEUCH-EO-IEUNG
0x433C  0xCCB4  # HANGUL SYLLABLE CHIEUCH-E
0x433D  0xCCB5  # HANGUL SYLLABLE CHIEUCH-E-KIYEOK
0x433E  0xCCB8  # HANGUL SYLLABLE CHIEUCH-E-NIEUN
0x433F  0xCCBC  # HANGUL SYLLABLE CHIEUCH-E-RIEUL
0x4340  0xCCC4  # HANGUL SYLLABLE CHIEUCH-E-MIEUM
0x4341  0xCCC5  # HANGUL SYLLABLE CHIEUCH-E-PIEUP
0x4342  0xCCC7  # HANGUL SYLLABLE CHIEUCH-E-SIOS
0x4343  0xCCC9  # HANGUL SYLLABLE CHIEUCH-E-IEUNG
0x4344  0xCCD0  # HANGUL SYLLABLE CHIEUCH-YEO
0x4345  0xCCD4  # HANGUL SYLLABLE CHIEUCH-YEO-NIEUN
0x4346  0xCCE4  # HANGUL SYLLABLE CHIEUCH-YEO-SSANGSIOS
0x4347  0xCCEC  # HANGUL SYLLABLE CHIEUCH-YE
0x4348  0xCCF0  # HANGUL SYLLABLE CHIEUCH-YE-NIEUN
0x4349  0xCD01  # HANGUL SYLLABLE CHIEUCH-YE-IEUNG
0x434A  0xCD08  # HANGUL SYLLABLE CHIEUCH-O
0x434B  0xCD09  # HANGUL SYLLABLE CHIEUCH-O-KIYEOK
0x434C  0xCD0C  # HANGUL SYLLABLE CHIEUCH-O-NIEUN
0x434D  0xCD10  # HANGUL SYLLABLE CHIEUCH-O-RIEUL
0x434E  0xCD18  # HANGUL SYLLABLE CHIEUCH-O-MIEUM
0x434F  0xCD19  # HANGUL SYLLABLE CHIEUCH-O-PIEUP
0x4350  0xCD1B  # HANGUL SYLLABLE CHIEUCH-O-SIOS
0x4351  0xCD1D  # HANGUL SYLLABLE CHIEUCH-O-IEUNG
0x4352  0xCD24  # HANGUL SYLLABLE CHIEUCH-WA
0x4353  0xCD28  # HANGUL SYLLABLE CHIEUCH-WA-NIEUN
0x4354  0xCD2C  # HANGUL SYLLABLE CHIEUCH-WA-RIEUL
0x4355  0xCD39  # HANGUL SYLLABLE CHIEUCH-WA-IEUNG
0x4356  0xCD5C  # HANGUL SYLLABLE CHIEUCH-OE
0x4357  0xCD60  # HANGUL SYLLABLE CHIEUCH-OE-NIEUN
0x4358  0xCD64  # HANGUL SYLLABLE CHIEUCH-OE-RIEUL
0x4359  0xCD6C  # HANGUL SYLLABLE CHIEUCH-OE-MIEUM
0x435A  0xCD6D  # HANGUL SYLLABLE CHIEUCH-OE-PIEUP
0x435B  0xCD6F  # HANGUL SYLLABLE CHIEUCH-OE-SIOS
0x435C  0xCD71  # HANGUL SYLLABLE CHIEUCH-OE-IEUNG
0x435D  0xCD78  # HANGUL SYLLABLE CHIEUCH-YO
0x435E  0xCD88  # HANGUL SYLLABLE CHIEUCH-YO-MIEUM
0x435F  0xCD94  # HANGUL SYLLABLE CHIEUCH-U
0x4360  0xCD95  # HANGUL SYLLABLE CHIEUCH-U-KIYEOK
0x4361  0xCD98  # HANGUL SYLLABLE CHIEUCH-U-NIEUN
0x4362  0xCD9C  # HANGUL SYLLABLE CHIEUCH-U-RIEUL
0x4363  0xCDA4  # HANGUL SYLLABLE CHIEUCH-U-MIEUM
0x4364  0xCDA5  # HANGUL SYLLABLE CHIEUCH-U-PIEUP
0x4365  0xCDA7  # HANGUL SYLLABLE CHIEUCH-U-SIOS
0x4366  0xCDA9  # HANGUL SYLLABLE CHIEUCH-U-IEUNG
0x4367  0xCDB0  # HANGUL SYLLABLE CHIEUCH-WEO
0x4368  0xCDC4  # HANGUL SYLLABLE CHIEUCH-WEO-SSANGSIOS
0x4369  0xCDCC  # HANGUL SYLLABLE CHIEUCH-WE
0x436A  0xCDD0  # HANGUL SYLLABLE CHIEUCH-WE-NIEUN
0x436B  0xCDE8  # HANGUL SYLLABLE CHIEUCH-WI
0x436C  0xCDEC  # HANGUL SYLLABLE CHIEUCH-WI-NIEUN
0x436D  0xCDF0  # HANGUL SYLLABLE CHIEUCH-WI-RIEUL
0x436E  0xCDF8  # HANGUL SYLLABLE CHIEUCH-WI-MIEUM
0x436F  0xCDF9  # HANGUL SYLLABLE CHIEUCH-WI-PIEUP
0x4370  0xCDFB  # HANGUL SYLLABLE CHIEUCH-WI-SIOS
0x4371  0xCDFD  # HANGUL SYLLABLE CHIEUCH-WI-IEUNG
0x4372  0xCE04  # HANGUL SYLLABLE CHIEUCH-YU
0x4373  0xCE08  # HANGUL SYLLABLE CHIEUCH-YU-NIEUN
0x4374  0xCE0C  # HANGUL SYLLABLE CHIEUCH-YU-RIEUL
0x4375  0xCE14  # HANGUL SYLLABLE CHIEUCH-YU-MIEUM
0x4376  0xCE19  # HANGUL SYLLABLE CHIEUCH-YU-IEUNG
0x4377  0xCE20  # HANGUL SYLLABLE CHIEUCH-EU
0x4378  0xCE21  # HANGUL SYLLABLE CHIEUCH-EU-KIYEOK
0x4379  0xCE24  # HANGUL SYLLABLE CHIEUCH-EU-NIEUN
0x437A  0xCE28  # HANGUL SYLLABLE CHIEUCH-EU-RIEUL
0x437B  0xCE30  # HANGUL SYLLABLE CHIEUCH-EU-MIEUM
0x437C  0xCE31  # HANGUL SYLLABLE CHIEUCH-EU-PIEUP
0x437D  0xCE33  # HANGUL SYLLABLE CHIEUCH-EU-SIOS
0x437E  0xCE35  # HANGUL SYLLABLE CHIEUCH-EU-IEUNG
0x4421  0xCE58  # HANGUL SYLLABLE CHIEUCH-I
0x4422  0xCE59  # HANGUL SYLLABLE CHIEUCH-I-KIYEOK
0x4423  0xCE5C  # HANGUL SYLLABLE CHIEUCH-I-NIEUN
0x4424  0xCE5F  # HANGUL SYLLABLE CHIEUCH-I-TIKEUT
0x4425  0xCE60  # HANGUL SYLLABLE CHIEUCH-I-RIEUL
0x4426  0xCE61  # HANGUL SYLLABLE CHIEUCH-I-RIEULKIYEOK
0x4427  0xCE68  # HANGUL SYLLABLE CHIEUCH-I-MIEUM
0x4428  0xCE69  # HANGUL SYLLABLE CHIEUCH-I-PIEUP
0x4429  0xCE6B  # HANGUL SYLLABLE CHIEUCH-I-SIOS
0x442A  0xCE6D  # HANGUL SYLLABLE CHIEUCH-I-IEUNG
0x442B  0xCE74  # HANGUL SYLLABLE KHIEUKH-A
0x442C  0xCE75  # HANGUL SYLLABLE KHIEUKH-A-KIYEOK
0x442D  0xCE78  # HANGUL SYLLABLE KHIEUKH-A-NIEUN
0x442E  0xCE7C  # HANGUL SYLLABLE KHIEUKH-A-RIEUL
0x442F  0xCE84  # HANGUL SYLLABLE KHIEUKH-A-MIEUM
0x4430  0xCE85  # HANGUL SYLLABLE KHIEUKH-A-PIEUP
0x4431  0xCE87  # HANGUL SYLLABLE KHIEUKH-A-SIOS
0x4432  0xCE89  # HANGUL SYLLABLE KHIEUKH-A-IEUNG
0x4433  0xCE90  # HANGUL SYLLABLE KHIEUKH-AE
0x4434  0xCE91  # HANGUL SYLLABLE KHIEUKH-AE-KIYEOK
0x4435  0xCE94  # HANGUL SYLLABLE KHIEUKH-AE-NIEUN
0x4436  0xCE98  # HANGUL SYLLABLE KHIEUKH-AE-RIEUL
0x4437  0xCEA0  # HANGUL SYLLABLE KHIEUKH-AE-MIEUM
0x4438  0xCEA1  # HANGUL SYLLABLE KHIEUKH-AE-PIEUP
0x4439  0xCEA3  # HANGUL SYLLABLE KHIEUKH-AE-SIOS
0x443A  0xCEA4  # HANGUL SYLLABLE KHIEUKH-AE-SSANGSIOS
0x443B  0xCEA5  # HANGUL SYLLABLE KHIEUKH-AE-IEUNG
0x443C  0xCEAC  # HANGUL SYLLABLE KHIEUKH-YA
0x443D  0xCEAD  # HANGUL SYLLABLE KHIEUKH-YA-KIYEOK
0x443E  0xCEC1  # HANGUL SYLLABLE KHIEUKH-YA-IEUNG
0x443F  0xCEE4  # HANGUL SYLLABLE KHIEUKH-EO
0x4440  0xCEE5  # HANGUL SYLLABLE KHIEUKH-EO-KIYEOK
0x4441  0xCEE8  # HANGUL SYLLABLE KHIEUKH-EO-NIEUN
0x4442  0xCEEB  # HANGUL SYLLABLE KHIEUKH-EO-TIKEUT
0x4443  0xCEEC  # HANGUL SYLLABLE KHIEUKH-EO-RIEUL
0x4444  0xCEF4  # HANGUL SYLLABLE KHIEUKH-EO-MIEUM
0x4445  0xCEF5  # HANGUL SYLLABLE KHIEUKH-EO-PIEUP
0x4446  0xCEF7  # HANGUL SYLLABLE KHIEUKH-EO-SIOS
0x4447  0xCEF8  # HANGUL SYLLABLE KHIEUKH-EO-SSANGSIOS
0x4448  0xCEF9  # HANGUL SYLLABLE KHIEUKH-EO-IEUNG
0x4449  0xCF00  # HANGUL SYLLABLE KHIEUKH-E
0x444A  0xCF01  # HANGUL SYLLABLE KHIEUKH-E-KIYEOK
0x444B  0xCF04  # HANGUL SYLLABLE KHIEUKH-E-NIEUN
0x444C  0xCF08  # HANGUL SYLLABLE KHIEUKH-E-RIEUL
0x444D  0xCF10  # HANGUL SYLLABLE KHIEUKH-E-MIEUM
0x444E  0xCF11  # HANGUL SYLLABLE KHIEUKH-E-PIEUP
0x444F  0xCF13  # HANGUL SYLLABLE KHIEUKH-E-SIOS
0x4450  0xCF15  # HANGUL SYLLABLE KHIEUKH-E-IEUNG
0x4451  0xCF1C  # HANGUL SYLLABLE KHIEUKH-YEO
0x4452  0xCF20  # HANGUL SYLLABLE KHIEUKH-YEO-NIEUN
0x4453  0xCF24  # HANGUL SYLLABLE KHIEUKH-YEO-RIEUL
0x4454  0xCF2C  # HANGUL SYLLABLE KHIEUKH-YEO-MIEUM
0x4455  0xCF2D  # HANGUL SYLLABLE KHIEUKH-YEO-PIEUP
0x4456  0xCF2F  # HANGUL SYLLABLE KHIEUKH-YEO-SIOS
0x4457  0xCF30  # HANGUL SYLLABLE KHIEUKH-YEO-SSANGSIOS
0x4458  0xCF31  # HANGUL SYLLABLE KHIEUKH-YEO-IEUNG
0x4459  0xCF38  # HANGUL SYLLABLE KHIEUKH-YE
0x445A  0xCF54  # HANGUL SYLLABLE KHIEUKH-O
0x445B  0xCF55  # HANGUL SYLLABLE KHIEUKH-O-KIYEOK
0x445C  0xCF58  # HANGUL SYLLABLE KHIEUKH-O-NIEUN
0x445D  0xCF5C  # HANGUL SYLLABLE KHIEUKH-O-RIEUL
0x445E  0xCF64  # HANGUL SYLLABLE KHIEUKH-O-MIEUM
0x445F  0xCF65  # HANGUL SYLLABLE KHIEUKH-O-PIEUP
0x4460  0xCF67  # HANGUL SYLLABLE KHIEUKH-O-SIOS
0x4461  0xCF69  # HANGUL SYLLABLE KHIEUKH-O-IEUNG
0x4462  0xCF70  # HANGUL SYLLABLE KHIEUKH-WA
0x4463  0xCF71  # HANGUL SYLLABLE KHIEUKH-WA-KIYEOK
0x4464  0xCF74  # HANGUL SYLLABLE KHIEUKH-WA-NIEUN
0x4465  0xCF78  # HANGUL SYLLABLE KHIEUKH-WA-RIEUL
0x4466  0xCF80  # HANGUL SYLLABLE KHIEUKH-WA-MIEUM
0x4467  0xCF85  # HANGUL SYLLABLE KHIEUKH-WA-IEUNG
0x4468  0xCF8C  # HANGUL SYLLABLE KHIEUKH-WAE
0x4469  0xCFA1  # HANGUL SYLLABLE KHIEUKH-WAE-IEUNG
0x446A  0xCFA8  # HANGUL SYLLABLE KHIEUKH-OE
0x446B  0xCFB0  # HANGUL SYLLABLE KHIEUKH-OE-RIEUL
0x446C  0xCFC4  # HANGUL SYLLABLE KHIEUKH-YO
0x446D  0xCFE0  # HANGUL SYLLABLE KHIEUKH-U
0x446E  0xCFE1  # HANGUL SYLLABLE KHIEUKH-U-KIYEOK
0x446F  0xCFE4  # HANGUL SYLLABLE KHIEUKH-U-NIEUN
0x4470  0xCFE8  # HANGUL SYLLABLE KHIEUKH-U-RIEUL
0x4471  0xCFF0  # HANGUL SYLLABLE KHIEUKH-U-MIEUM
0x4472  0xCFF1  # HANGUL SYLLABLE KHIEUKH-U-PIEUP
0x4473  0xCFF3  # HANGUL SYLLABLE KHIEUKH-U-SIOS
0x4474  0xCFF5  # HANGUL SYLLABLE KHIEUKH-U-IEUNG
0x4475  0xCFFC  # HANGUL SYLLABLE KHIEUKH-WEO
0x4476  0xD000  # HANGUL SYLLABLE KHIEUKH-WEO-NIEUN
0x4477  0xD004  # HANGUL SYLLABLE KHIEUKH-WEO-RIEUL
0x4478  0xD011  # HANGUL SYLLABLE KHIEUKH-WEO-IEUNG
0x4479  0xD018  # HANGUL SYLLABLE KHIEUKH-WE
0x447A  0xD02D  # HANGUL SYLLABLE KHIEUKH-WE-IEUNG
0x447B  0xD034  # HANGUL SYLLABLE KHIEUKH-WI
0x447C  0xD035  # HANGUL SYLLABLE KHIEUKH-WI-KIYEOK
0x447D  0xD038  # HANGUL SYLLABLE KHIEUKH-WI-NIEUN
0x447E  0xD03C  # HANGUL SYLLABLE KHIEUKH-WI-RIEUL
0x4521  0xD044  # HANGUL SYLLABLE KHIEUKH-WI-MIEUM
0x4522  0xD045  # HANGUL SYLLABLE KHIEUKH-WI-PIEUP
0x4523  0xD047  # HANGUL SYLLABLE KHIEUKH-WI-SIOS
0x4524  0xD049  # HANGUL SYLLABLE KHIEUKH-WI-IEUNG
0x4525  0xD050  # HANGUL SYLLABLE KHIEUKH-YU
0x4526  0xD054  # HANGUL SYLLABLE KHIEUKH-YU-NIEUN
0x4527  0xD058  # HANGUL SYLLABLE KHIEUKH-YU-RIEUL
0x4528  0xD060  # HANGUL SYLLABLE KHIEUKH-YU-MIEUM
0x4529  0xD06C  # HANGUL SYLLABLE KHIEUKH-EU
0x452A  0xD06D  # HANGUL SYLLABLE KHIEUKH-EU-KIYEOK
0x452B  0xD070  # HANGUL SYLLABLE KHIEUKH-EU-NIEUN
0x452C  0xD074  # HANGUL SYLLABLE KHIEUKH-EU-RIEUL
0x452D  0xD07C  # HANGUL SYLLABLE KHIEUKH-EU-MIEUM
0x452E  0xD07D  # HANGUL SYLLABLE KHIEUKH-EU-PIEUP
0x452F  0xD081  # HANGUL SYLLABLE KHIEUKH-EU-IEUNG
0x4530  0xD0A4  # HANGUL SYLLABLE KHIEUKH-I
0x4531  0xD0A5  # HANGUL SYLLABLE KHIEUKH-I-KIYEOK
0x4532  0xD0A8  # HANGUL SYLLABLE KHIEUKH-I-NIEUN
0x4533  0xD0AC  # HANGUL SYLLABLE KHIEUKH-I-RIEUL
0x4534  0xD0B4  # HANGUL SYLLABLE KHIEUKH-I-MIEUM
0x4535  0xD0B5  # HANGUL SYLLABLE KHIEUKH-I-PIEUP
0x4536  0xD0B7  # HANGUL SYLLABLE KHIEUKH-I-SIOS
0x4537  0xD0B9  # HANGUL SYLLABLE KHIEUKH-I-IEUNG
0x4538  0xD0C0  # HANGUL SYLLABLE THIEUTH-A
0x4539  0xD0C1  # HANGUL SYLLABLE THIEUTH-A-KIYEOK
0x453A  0xD0C4  # HANGUL SYLLABLE THIEUTH-A-NIEUN
0x453B  0xD0C8  # HANGUL SYLLABLE THIEUTH-A-RIEUL
0x453C  0xD0C9  # HANGUL SYLLABLE THIEUTH-A-RIEULKIYEOK
0x453D  0xD0D0  # HANGUL SYLLABLE THIEUTH-A-MIEUM
0x453E  0xD0D1  # HANGUL SYLLABLE THIEUTH-A-PIEUP
0x453F  0xD0D3  # HANGUL SYLLABLE THIEUTH-A-SIOS
0x4540  0xD0D4  # HANGUL SYLLABLE THIEUTH-A-SSANGSIOS
0x4541  0xD0D5  # HANGUL SYLLABLE THIEUTH-A-IEUNG
0x4542  0xD0DC  # HANGUL SYLLABLE THIEUTH-AE
0x4543  0xD0DD  # HANGUL SYLLABLE THIEUTH-AE-KIYEOK
0x4544  0xD0E0  # HANGUL SYLLABLE THIEUTH-AE-NIEUN
0x4545  0xD0E4  # HANGUL SYLLABLE THIEUTH-AE-RIEUL
0x4546  0xD0EC  # HANGUL SYLLABLE THIEUTH-AE-MIEUM
0x4547  0xD0ED  # HANGUL SYLLABLE THIEUTH-AE-PIEUP
0x4548  0xD0EF  # HANGUL SYLLABLE THIEUTH-AE-SIOS
0x4549  0xD0F0  # HANGUL SYLLABLE THIEUTH-AE-SSANGSIOS
0x454A  0xD0F1  # HANGUL SYLLABLE THIEUTH-AE-IEUNG
0x454B  0xD0F8  # HANGUL SYLLABLE THIEUTH-YA
0x454C  0xD10D  # HANGUL SYLLABLE THIEUTH-YA-IEUNG
0x454D  0xD130  # HANGUL SYLLABLE THIEUTH-EO
0x454E  0xD131  # HANGUL SYLLABLE THIEUTH-EO-KIYEOK
0x454F  0xD134  # HANGUL SYLLABLE THIEUTH-EO-NIEUN
0x4550  0xD138  # HANGUL SYLLABLE THIEUTH-EO-RIEUL
0x4551  0xD13A  # HANGUL SYLLABLE THIEUTH-EO-RIEULMIEUM
0x4552  0xD140  # HANGUL SYLLABLE THIEUTH-EO-MIEUM
0x4553  0xD141  # HANGUL SYLLABLE THIEUTH-EO-PIEUP
0x4554  0xD143  # HANGUL SYLLABLE THIEUTH-EO-SIOS
0x4555  0xD144  # HANGUL SYLLABLE THIEUTH-EO-SSANGSIOS
0x4556  0xD145  # HANGUL SYLLABLE THIEUTH-EO-IEUNG
0x4557  0xD14C  # HANGUL SYLLABLE THIEUTH-E
0x4558  0xD14D  # HANGUL SYLLABLE THIEUTH-E-KIYEOK
0x4559  0xD150  # HANGUL SYLLABLE THIEUTH-E-NIEUN
0x455A  0xD154  # HANGUL SYLLABLE THIEUTH-E-RIEUL
0x455B  0xD15C  # HANGUL SYLLABLE THIEUTH-E-MIEUM
0x455C  0xD15D  # HANGUL SYLLABLE THIEUTH-E-PIEUP
0x455D  0xD15F  # HANGUL SYLLABLE THIEUTH-E-SIOS
0x455E  0xD161  # HANGUL SYLLABLE THIEUTH-E-IEUNG
0x455F  0xD168  # HANGUL SYLLABLE THIEUTH-YEO
0x4560  0xD16C  # HANGUL SYLLABLE THIEUTH-YEO-NIEUN
0x4561  0xD17C  # HANGUL SYLLABLE THIEUTH-YEO-SSANGSIOS
0x4562  0xD184  # HANGUL SYLLABLE THIEUTH-YE
0x4563  0xD188  # HANGUL SYLLABLE THIEUTH-YE-NIEUN
0x4564  0xD1A0  # HANGUL SYLLABLE THIEUTH-O
0x4565  0xD1A1  # HANGUL SYLLABLE THIEUTH-O-KIYEOK
0x4566  0xD1A4  # HANGUL SYLLABLE THIEUTH-O-NIEUN
0x4567  0xD1A8  # HANGUL SYLLABLE THIEUTH-O-RIEUL
0x4568  0xD1B0  # HANGUL SYLLABLE THIEUTH-O-MIEUM
0x4569  0xD1B1  # HANGUL SYLLABLE THIEUTH-O-PIEUP
0x456A  0xD1B3  # HANGUL SYLLABLE THIEUTH-O-SIOS
0x456B  0xD1B5  # HANGUL SYLLABLE THIEUTH-O-IEUNG
0x456C  0xD1BA  # HANGUL SYLLABLE THIEUTH-O-PHIEUPH
0x456D  0xD1BC  # HANGUL SYLLABLE THIEUTH-WA
0x456E  0xD1C0  # HANGUL SYLLABLE THIEUTH-WA-NIEUN
0x456F  0xD1D8  # HANGUL SYLLABLE THIEUTH-WAE
0x4570  0xD1F4  # HANGUL SYLLABLE THIEUTH-OE
0x4571  0xD1F8  # HANGUL SYLLABLE THIEUTH-OE-NIEUN
0x4572  0xD207  # HANGUL SYLLABLE THIEUTH-OE-SIOS
0x4573  0xD209  # HANGUL SYLLABLE THIEUTH-OE-IEUNG
0x4574  0xD210  # HANGUL SYLLABLE THIEUTH-YO
0x4575  0xD22C  # HANGUL SYLLABLE THIEUTH-U
0x4576  0xD22D  # HANGUL SYLLABLE THIEUTH-U-KIYEOK
0x4577  0xD230  # HANGUL SYLLABLE THIEUTH-U-NIEUN
0x4578  0xD234  # HANGUL SYLLABLE THIEUTH-U-RIEUL
0x4579  0xD23C  # HANGUL SYLLABLE THIEUTH-U-MIEUM
0x457A  0xD23D  # HANGUL SYLLABLE THIEUTH-U-PIEUP
0x457B  0xD23F  # HANGUL SYLLABLE THIEUTH-U-SIOS
0x457C  0xD241  # HANGUL SYLLABLE THIEUTH-U-IEUNG
0x457D  0xD248  # HANGUL SYLLABLE THIEUTH-WEO
0x457E  0xD25C  # HANGUL SYLLABLE THIEUTH-WEO-SSANGSIOS
0x4621  0xD264  # HANGUL SYLLABLE THIEUTH-WE
0x4622  0xD280  # HANGUL SYLLABLE THIEUTH-WI
0x4623  0xD281  # HANGUL SYLLABLE THIEUTH-WI-KIYEOK
0x4624  0xD284  # HANGUL SYLLABLE THIEUTH-WI-NIEUN
0x4625  0xD288  # HANGUL SYLLABLE THIEUTH-WI-RIEUL
0x4626  0xD290  # HANGUL SYLLABLE THIEUTH-WI-MIEUM
0x4627  0xD291  # HANGUL SYLLABLE THIEUTH-WI-PIEUP
0x4628  0xD295  # HANGUL SYLLABLE THIEUTH-WI-IEUNG
0x4629  0xD29C  # HANGUL SYLLABLE THIEUTH-YU
0x462A  0xD2A0  # HANGUL SYLLABLE THIEUTH-YU-NIEUN
0x462B  0xD2A4  # HANGUL SYLLABLE THIEUTH-YU-RIEUL
0x462C  0xD2AC  # HANGUL SYLLABLE THIEUTH-YU-MIEUM
0x462D  0xD2B1  # HANGUL SYLLABLE THIEUTH-YU-IEUNG
0x462E  0xD2B8  # HANGUL SYLLABLE THIEUTH-EU
0x462F  0xD2B9  # HANGUL SYLLABLE THIEUTH-EU-KIYEOK
0x4630  0xD2BC  # HANGUL SYLLABLE THIEUTH-EU-NIEUN
0x4631  0xD2BF  # HANGUL SYLLABLE THIEUTH-EU-TIKEUT
0x4632  0xD2C0  # HANGUL SYLLABLE THIEUTH-EU-RIEUL
0x4633  0xD2C2  # HANGUL SYLLABLE THIEUTH-EU-RIEULMIEUM
0x4634  0xD2C8  # HANGUL SYLLABLE THIEUTH-EU-MIEUM
0x4635  0xD2C9  # HANGUL SYLLABLE THIEUTH-EU-PIEUP
0x4636  0xD2CB  # HANGUL SYLLABLE THIEUTH-EU-SIOS
0x4637  0xD2D4  # HANGUL SYLLABLE THIEUTH-YI
0x4638  0xD2D8  # HANGUL SYLLABLE THIEUTH-YI-NIEUN
0x4639  0xD2DC  # HANGUL SYLLABLE THIEUTH-YI-RIEUL
0x463A  0xD2E4  # HANGUL SYLLABLE THIEUTH-YI-MIEUM
0x463B  0xD2E5  # HANGUL SYLLABLE THIEUTH-YI-PIEUP
0x463C  0xD2F0  # HANGUL SYLLABLE THIEUTH-I
0x463D  0xD2F1  # HANGUL SYLLABLE THIEUTH-I-KIYEOK
0x463E  0xD2F4  # HANGUL SYLLABLE THIEUTH-I-NIEUN
0x463F  0xD2F8  # HANGUL SYLLABLE THIEUTH-I-RIEUL
0x4640  0xD300  # HANGUL SYLLABLE THIEUTH-I-MIEUM
0x4641  0xD301  # HANGUL SYLLABLE THIEUTH-I-PIEUP
0x4642  0xD303  # HANGUL SYLLABLE THIEUTH-I-SIOS
0x4643  0xD305  # HANGUL SYLLABLE THIEUTH-I-IEUNG
0x4644  0xD30C  # HANGUL SYLLABLE PHIEUPH-A
0x4645  0xD30D  # HANGUL SYLLABLE PHIEUPH-A-KIYEOK
0x4646  0xD30E  # HANGUL SYLLABLE PHIEUPH-A-SSANGKIYEOK
0x4647  0xD310  # HANGUL SYLLABLE PHIEUPH-A-NIEUN
0x4648  0xD314  # HANGUL SYLLABLE PHIEUPH-A-RIEUL
0x4649  0xD316  # HANGUL SYLLABLE PHIEUPH-A-RIEULMIEUM
0x464A  0xD31C  # HANGUL SYLLABLE PHIEUPH-A-MIEUM
0x464B  0xD31D  # HANGUL SYLLABLE PHIEUPH-A-PIEUP
0x464C  0xD31F  # HANGUL SYLLABLE PHIEUPH-A-SIOS
0x464D  0xD320  # HANGUL SYLLABLE PHIEUPH-A-SSANGSIOS
0x464E  0xD321  # HANGUL SYLLABLE PHIEUPH-A-IEUNG
0x464F  0xD325  # HANGUL SYLLABLE PHIEUPH-A-THIEUTH
0x4650  0xD328  # HANGUL SYLLABLE PHIEUPH-AE
0x4651  0xD329  # HANGUL SYLLABLE PHIEUPH-AE-KIYEOK
0x4652  0xD32C  # HANGUL SYLLABLE PHIEUPH-AE-NIEUN
0x4653  0xD330  # HANGUL SYLLABLE PHIEUPH-AE-RIEUL
0x4654  0xD338  # HANGUL SYLLABLE PHIEUPH-AE-MIEUM
0x4655  0xD339  # HANGUL SYLLABLE PHIEUPH-AE-PIEUP
0x4656  0xD33B  # HANGUL SYLLABLE PHIEUPH-AE-SIOS
0x4657  0xD33C  # HANGUL SYLLABLE PHIEUPH-AE-SSANGSIOS
0x4658  0xD33D  # HANGUL SYLLABLE PHIEUPH-AE-IEUNG
0x4659  0xD344  # HANGUL SYLLABLE PHIEUPH-YA
0x465A  0xD345  # HANGUL SYLLABLE PHIEUPH-YA-KIYEOK
0x465B  0xD37C  # HANGUL SYLLABLE PHIEUPH-EO
0x465C  0xD37D  # HANGUL SYLLABLE PHIEUPH-EO-KIYEOK
0x465D  0xD380  # HANGUL SYLLABLE PHIEUPH-EO-NIEUN
0x465E  0xD384  # HANGUL SYLLABLE PHIEUPH-EO-RIEUL
0x465F  0xD38C  # HANGUL SYLLABLE PHIEUPH-EO-MIEUM
0x4660  0xD38D  # HANGUL SYLLABLE PHIEUPH-EO-PIEUP
0x4661  0xD38F  # HANGUL SYLLABLE PHIEUPH-EO-SIOS
0x4662  0xD390  # HANGUL SYLLABLE PHIEUPH-EO-SSANGSIOS
0x4663  0xD391  # HANGUL SYLLABLE PHIEUPH-EO-IEUNG
0x4664  0xD398  # HANGUL SYLLABLE PHIEUPH-E
0x4665  0xD399  # HANGUL SYLLABLE PHIEUPH-E-KIYEOK
0x4666  0xD39C  # HANGUL SYLLABLE PHIEUPH-E-NIEUN
0x4667  0xD3A0  # HANGUL SYLLABLE PHIEUPH-E-RIEUL
0x4668  0xD3A8  # HANGUL SYLLABLE PHIEUPH-E-MIEUM
0x4669  0xD3A9  # HANGUL SYLLABLE PHIEUPH-E-PIEUP
0x466A  0xD3AB  # HANGUL SYLLABLE PHIEUPH-E-SIOS
0x466B  0xD3AD  # HANGUL SYLLABLE PHIEUPH-E-IEUNG
0x466C  0xD3B4  # HANGUL SYLLABLE PHIEUPH-YEO
0x466D  0xD3B8  # HANGUL SYLLABLE PHIEUPH-YEO-NIEUN
0x466E  0xD3BC  # HANGUL SYLLABLE PHIEUPH-YEO-RIEUL
0x466F  0xD3C4  # HANGUL SYLLABLE PHIEUPH-YEO-MIEUM
0x4670  0xD3C5  # HANGUL SYLLABLE PHIEUPH-YEO-PIEUP
0x4671  0xD3C8  # HANGUL SYLLABLE PHIEUPH-YEO-SSANGSIOS
0x4672  0xD3C9  # HANGUL SYLLABLE PHIEUPH-YEO-IEUNG
0x4673  0xD3D0  # HANGUL SYLLABLE PHIEUPH-YE
0x4674  0xD3D8  # HANGUL SYLLABLE PHIEUPH-YE-RIEUL
0x4675  0xD3E1  # HANGUL SYLLABLE PHIEUPH-YE-PIEUP
0x4676  0xD3E3  # HANGUL SYLLABLE PHIEUPH-YE-SIOS
0x4677  0xD3EC  # HANGUL SYLLABLE PHIEUPH-O
0x4678  0xD3ED  # HANGUL SYLLABLE PHIEUPH-O-KIYEOK
0x4679  0xD3F0  # HANGUL SYLLABLE PHIEUPH-O-NIEUN
0x467A  0xD3F4  # HANGUL SYLLABLE PHIEUPH-O-RIEUL
0x467B  0xD3FC  # HANGUL SYLLABLE PHIEUPH-O-MIEUM
0x467C  0xD3FD  # HANGUL SYLLABLE PHIEUPH-O-PIEUP
0x467D  0xD3FF  # HANGUL SYLLABLE PHIEUPH-O-SIOS
0x467E  0xD401  # HANGUL SYLLABLE PHIEUPH-O-IEUNG
0x4721  0xD408  # HANGUL SYLLABLE PHIEUPH-WA
0x4722  0xD41D  # HANGUL SYLLABLE PHIEUPH-WA-IEUNG
0x4723  0xD440  # HANGUL SYLLABLE PHIEUPH-OE
0x4724  0xD444  # HANGUL SYLLABLE PHIEUPH-OE-NIEUN
0x4725  0xD45C  # HANGUL SYLLABLE PHIEUPH-YO
0x4726  0xD460  # HANGUL SYLLABLE PHIEUPH-YO-NIEUN
0x4727  0xD464  # HANGUL SYLLABLE PHIEUPH-YO-RIEUL
0x4728  0xD46D  # HANGUL SYLLABLE PHIEUPH-YO-PIEUP
0x4729  0xD46F  # HANGUL SYLLABLE PHIEUPH-YO-SIOS
0x472A  0xD478  # HANGUL SYLLABLE PHIEUPH-U
0x472B  0xD479  # HANGUL SYLLABLE PHIEUPH-U-KIYEOK
0x472C  0xD47C  # HANGUL SYLLABLE PHIEUPH-U-NIEUN
0x472D  0xD47F  # HANGUL SYLLABLE PHIEUPH-U-TIKEUT
0x472E  0xD480  # HANGUL SYLLABLE PHIEUPH-U-RIEUL
0x472F  0xD482  # HANGUL SYLLABLE PHIEUPH-U-RIEULMIEUM
0x4730  0xD488  # HANGUL SYLLABLE PHIEUPH-U-MIEUM
0x4731  0xD489  # HANGUL SYLLABLE PHIEUPH-U-PIEUP
0x4732  0xD48B  # HANGUL SYLLABLE PHIEUPH-U-SIOS
0x4733  0xD48D  # HANGUL SYLLABLE PHIEUPH-U-IEUNG
0x4734  0xD494  # HANGUL SYLLABLE PHIEUPH-WEO
0x4735  0xD4A9  # HANGUL SYLLABLE PHIEUPH-WEO-IEUNG
0x4736  0xD4CC  # HANGUL SYLLABLE PHIEUPH-WI
0x4737  0xD4D0  # HANGUL SYLLABLE PHIEUPH-WI-NIEUN
0x4738  0xD4D4  # HANGUL SYLLABLE PHIEUPH-WI-RIEUL
0x4739  0xD4DC  # HANGUL SYLLABLE PHIEUPH-WI-MIEUM
0x473A  0xD4DF  # HANGUL SYLLABLE PHIEUPH-WI-SIOS
0x473B  0xD4E8  # HANGUL SYLLABLE PHIEUPH-YU
0x473C  0xD4EC  # HANGUL SYLLABLE PHIEUPH-YU-NIEUN
0x473D  0xD4F0  # HANGUL SYLLABLE PHIEUPH-YU-RIEUL
0x473E  0xD4F8  # HANGUL SYLLABLE PHIEUPH-YU-MIEUM
0x473F  0xD4FB  # HANGUL SYLLABLE PHIEUPH-YU-SIOS
0x4740  0xD4FD  # HANGUL SYLLABLE PHIEUPH-YU-IEUNG
0x4741  0xD504  # HANGUL SYLLABLE PHIEUPH-EU
0x4742  0xD508  # HANGUL SYLLABLE PHIEUPH-EU-NIEUN
0x4743  0xD50C  # HANGUL SYLLABLE PHIEUPH-EU-RIEUL
0x4744  0xD514  # HANGUL SYLLABLE PHIEUPH-EU-MIEUM
0x4745  0xD515  # HANGUL SYLLABLE PHIEUPH-EU-PIEUP
0x4746  0xD517  # HANGUL SYLLABLE PHIEUPH-EU-SIOS
0x4747  0xD53C  # HANGUL SYLLABLE PHIEUPH-I
0x4748  0xD53D  # HANGUL SYLLABLE PHIEUPH-I-KIYEOK
0x4749  0xD540  # HANGUL SYLLABLE PHIEUPH-I-NIEUN
0x474A  0xD544  # HANGUL SYLLABLE PHIEUPH-I-RIEUL
0x474B  0xD54C  # HANGUL SYLLABLE PHIEUPH-I-MIEUM
0x474C  0xD54D  # HANGUL SYLLABLE PHIEUPH-I-PIEUP
0x474D  0xD54F  # HANGUL SYLLABLE PHIEUPH-I-SIOS
0x474E  0xD551  # HANGUL SYLLABLE PHIEUPH-I-IEUNG
0x474F  0xD558  # HANGUL SYLLABLE HIEUH-A
0x4750  0xD559  # HANGUL SYLLABLE HIEUH-A-KIYEOK
0x4751  0xD55C  # HANGUL SYLLABLE HIEUH-A-NIEUN
0x4752  0xD560  # HANGUL SYLLABLE HIEUH-A-RIEUL
0x4753  0xD565  # HANGUL SYLLABLE HIEUH-A-RIEULTHIEUTH
0x4754  0xD568  # HANGUL SYLLABLE HIEUH-A-MIEUM
0x4755  0xD569  # HANGUL SYLLABLE HIEUH-A-PIEUP
0x4756  0xD56B  # HANGUL SYLLABLE HIEUH-A-SIOS
0x4757  0xD56D  # HANGUL SYLLABLE HIEUH-A-IEUNG
0x4758  0xD574  # HANGUL SYLLABLE HIEUH-AE
0x4759  0xD575  # HANGUL SYLLABLE HIEUH-AE-KIYEOK
0x475A  0xD578  # HANGUL SYLLABLE HIEUH-AE-NIEUN
0x475B  0xD57C  # HANGUL SYLLABLE HIEUH-AE-RIEUL
0x475C  0xD584  # HANGUL SYLLABLE HIEUH-AE-MIEUM
0x475D  0xD585  # HANGUL SYLLABLE HIEUH-AE-PIEUP
0x475E  0xD587  # HANGUL SYLLABLE HIEUH-AE-SIOS
0x475F  0xD588  # HANGUL SYLLABLE HIEUH-AE-SSANGSIOS
0x4760  0xD589  # HANGUL SYLLABLE HIEUH-AE-IEUNG
0x4761  0xD590  # HANGUL SYLLABLE HIEUH-YA
0x4762  0xD5A5  # HANGUL SYLLABLE HIEUH-YA-IEUNG
0x4763  0xD5C8  # HANGUL SYLLABLE HIEUH-EO
0x4764  0xD5C9  # HANGUL SYLLABLE HIEUH-EO-KIYEOK
0x4765  0xD5CC  # HANGUL SYLLABLE HIEUH-EO-NIEUN
0x4766  0xD5D0  # HANGUL SYLLABLE HIEUH-EO-RIEUL
0x4767  0xD5D2  # HANGUL SYLLABLE HIEUH-EO-RIEULMIEUM
0x4768  0xD5D8  # HANGUL SYLLABLE HIEUH-EO-MIEUM
0x4769  0xD5D9  # HANGUL SYLLABLE HIEUH-EO-PIEUP
0x476A  0xD5DB  # HANGUL SYLLABLE HIEUH-EO-SIOS
0x476B  0xD5DD  # HANGUL SYLLABLE HIEUH-EO-IEUNG
0x476C  0xD5E4  # HANGUL SYLLABLE HIEUH-E
0x476D  0xD5E5  # HANGUL SYLLABLE HIEUH-E-KIYEOK
0x476E  0xD5E8  # HANGUL SYLLABLE HIEUH-E-NIEUN
0x476F  0xD5EC  # HANGUL SYLLABLE HIEUH-E-RIEUL
0x4770  0xD5F4  # HANGUL SYLLABLE HIEUH-E-MIEUM
0x4771  0xD5F5  # HANGUL SYLLABLE HIEUH-E-PIEUP
0x4772  0xD5F7  # HANGUL SYLLABLE HIEUH-E-SIOS
0x4773  0xD5F9  # HANGUL SYLLABLE HIEUH-E-IEUNG
0x4774  0xD600  # HANGUL SYLLABLE HIEUH-YEO
0x4775  0xD601  # HANGUL SYLLABLE HIEUH-YEO-KIYEOK
0x4776  0xD604  # HANGUL SYLLABLE HIEUH-YEO-NIEUN
0x4777  0xD608  # HANGUL SYLLABLE HIEUH-YEO-RIEUL
0x4778  0xD610  # HANGUL SYLLABLE HIEUH-YEO-MIEUM
0x4779  0xD611  # HANGUL SYLLABLE HIEUH-YEO-PIEUP
0x477A  0xD613  # HANGUL SYLLABLE HIEUH-YEO-SIOS
0x477B  0xD614  # HANGUL SYLLABLE HIEUH-YEO-SSANGSIOS
0x477C  0xD615  # HANGUL SYLLABLE HIEUH-YEO-IEUNG
0x477D  0xD61C  # HANGUL SYLLABLE HIEUH-YE
0x477E  0xD620  # HANGUL SYLLABLE HIEUH-YE-NIEUN
0x4821  0xD624  # HANGUL SYLLABLE HIEUH-YE-RIEUL
0x4822  0xD62D  # HANGUL SYLLABLE HIEUH-YE-PIEUP
0x4823  0xD638  # HANGUL SYLLABLE HIEUH-O
0x4824  0xD639  # HANGUL SYLLABLE HIEUH-O-KIYEOK
0x4825  0xD63C  # HANGUL SYLLABLE HIEUH-O-NIEUN
0x4826  0xD640  # HANGUL SYLLABLE HIEUH-O-RIEUL
0x4827  0xD645  # HANGUL SYLLABLE HIEUH-O-RIEULTHIEUTH
0x4828  0xD648  # HANGUL SYLLABLE HIEUH-O-MIEUM
0x4829  0xD649  # HANGUL SYLLABLE HIEUH-O-PIEUP
0x482A  0xD64B  # HANGUL SYLLABLE HIEUH-O-SIOS
0x482B  0xD64D  # HANGUL SYLLABLE HIEUH-O-IEUNG
0x482C  0xD651  # HANGUL SYLLABLE HIEUH-O-THIEUTH
0x482D  0xD654  # HANGUL SYLLABLE HIEUH-WA
0x482E  0xD655  # HANGUL SYLLABLE HIEUH-WA-KIYEOK
0x482F  0xD658  # HANGUL SYLLABLE HIEUH-WA-NIEUN
0x4830  0xD65C  # HANGUL SYLLABLE HIEUH-WA-RIEUL
0x4831  0xD667  # HANGUL SYLLABLE HIEUH-WA-SIOS
0x4832  0xD669  # HANGUL SYLLABLE HIEUH-WA-IEUNG
0x4833  0xD670  # HANGUL SYLLABLE HIEUH-WAE
0x4834  0xD671  # HANGUL SYLLABLE HIEUH-WAE-KIYEOK
0x4835  0xD674  # HANGUL SYLLABLE HIEUH-WAE-NIEUN
0x4836  0xD683  # HANGUL SYLLABLE HIEUH-WAE-SIOS
0x4837  0xD685  # HANGUL SYLLABLE HIEUH-WAE-IEUNG
0x4838  0xD68C  # HANGUL SYLLABLE HIEUH-OE
0x4839  0xD68D  # HANGUL SYLLABLE HIEUH-OE-KIYEOK
0x483A  0xD690  # HANGUL SYLLABLE HIEUH-OE-NIEUN
0x483B  0xD694  # HANGUL SYLLABLE HIEUH-OE-RIEUL
0x483C  0xD69D  # HANGUL SYLLABLE HIEUH-OE-PIEUP
0x483D  0xD69F  # HANGUL SYLLABLE HIEUH-OE-SIOS
0x483E  0xD6A1  # HANGUL SYLLABLE HIEUH-OE-IEUNG
0x483F  0xD6A8  # HANGUL SYLLABLE HIEUH-YO
0x4840  0xD6AC  # HANGUL SYLLABLE HIEUH-YO-NIEUN
0x4841  0xD6B0  # HANGUL SYLLABLE HIEUH-YO-RIEUL
0x4842  0xD6B9  # HANGUL SYLLABLE HIEUH-YO-PIEUP
0x4843  0xD6BB  # HANGUL SYLLABLE HIEUH-YO-SIOS
0x4844  0xD6C4  # HANGUL SYLLABLE HIEUH-U
0x4845  0xD6C5  # HANGUL SYLLABLE HIEUH-U-KIYEOK
0x4846  0xD6C8  # HANGUL SYLLABLE HIEUH-U-NIEUN
0x4847  0xD6CC  # HANGUL SYLLABLE HIEUH-U-RIEUL
0x4848  0xD6D1  # HANGUL SYLLABLE HIEUH-U-RIEULTHIEUTH
0x4849  0xD6D4  # HANGUL SYLLABLE HIEUH-U-MIEUM
0x484A  0xD6D7  # HANGUL SYLLABLE HIEUH-U-SIOS
0x484B  0xD6D9  # HANGUL SYLLABLE HIEUH-U-IEUNG
0x484C  0xD6E0  # HANGUL SYLLABLE HIEUH-WEO
0x484D  0xD6E4  # HANGUL SYLLABLE HIEUH-WEO-NIEUN
0x484E  0xD6E8  # HANGUL SYLLABLE HIEUH-WEO-RIEUL
0x484F  0xD6F0  # HANGUL SYLLABLE HIEUH-WEO-MIEUM
0x4850  0xD6F5  # HANGUL SYLLABLE HIEUH-WEO-IEUNG
0x4851  0xD6FC  # HANGUL SYLLABLE HIEUH-WE
0x4852  0xD6FD  # HANGUL SYLLABLE HIEUH-WE-KIYEOK
0x4853  0xD700  # HANGUL SYLLABLE HIEUH-WE-NIEUN
0x4854  0xD704  # HANGUL SYLLABLE HIEUH-WE-RIEUL
0x4855  0xD711  # HANGUL SYLLABLE HIEUH-WE-IEUNG
0x4856  0xD718  # HANGUL SYLLABLE HIEUH-WI
0x4857  0xD719  # HANGUL SYLLABLE HIEUH-WI-KIYEOK
0x4858  0xD71C  # HANGUL SYLLABLE HIEUH-WI-NIEUN
0x4859  0xD720  # HANGUL SYLLABLE HIEUH-WI-RIEUL
0x485A  0xD728  # HANGUL SYLLABLE HIEUH-WI-MIEUM
0x485B  0xD729  # HANGUL SYLLABLE HIEUH-WI-PIEUP
0x485C  0xD72B  # HANGUL SYLLABLE HIEUH-WI-SIOS
0x485D  0xD72D  # HANGUL SYLLABLE HIEUH-WI-IEUNG
0x485E  0xD734  # HANGUL SYLLABLE HIEUH-YU
0x485F  0xD735  # HANGUL SYLLABLE HIEUH-YU-KIYEOK
0x4860  0xD738  # HANGUL SYLLABLE HIEUH-YU-NIEUN
0x4861  0xD73C  # HANGUL SYLLABLE HIEUH-YU-RIEUL
0x4862  0xD744  # HANGUL SYLLABLE HIEUH-YU-MIEUM
0x4863  0xD747  # HANGUL SYLLABLE HIEUH-YU-SIOS
0x4864  0xD749  # HANGUL SYLLABLE HIEUH-YU-IEUNG
0x4865  0xD750  # HANGUL SYLLABLE HIEUH-EU
0x4866  0xD751  # HANGUL SYLLABLE HIEUH-EU-KIYEOK
0x4867  0xD754  # HANGUL SYLLABLE HIEUH-EU-NIEUN
0x4868  0xD756  # HANGUL SYLLABLE HIEUH-EU-NIEUNHIEUH
0x4869  0xD757  # HANGUL SYLLABLE HIEUH-EU-TIKEUT
0x486A  0xD758  # HANGUL SYLLABLE HIEUH-EU-RIEUL
0x486B  0xD759  # HANGUL SYLLABLE HIEUH-EU-RIEULKIYEOK
0x486C  0xD760  # HANGUL SYLLABLE HIEUH-EU-MIEUM
0x486D  0xD761  # HANGUL SYLLABLE HIEUH-EU-PIEUP
0x486E  0xD763  # HANGUL SYLLABLE HIEUH-EU-SIOS
0x486F  0xD765  # HANGUL SYLLABLE HIEUH-EU-IEUNG
0x4870  0xD769  # HANGUL SYLLABLE HIEUH-EU-THIEUTH
0x4871  0xD76C  # HANGUL SYLLABLE HIEUH-YI
0x4872  0xD770  # HANGUL SYLLABLE HIEUH-YI-NIEUN
0x4873  0xD774  # HANGUL SYLLABLE HIEUH-YI-RIEUL
0x4874  0xD77C  # HANGUL SYLLABLE HIEUH-YI-MIEUM
0x4875  0xD77D  # HANGUL SYLLABLE HIEUH-YI-PIEUP
0x4876  0xD781  # HANGUL SYLLABLE HIEUH-YI-IEUNG
0x4877  0xD788  # HANGUL SYLLABLE HIEUH-I
0x4878  0xD789  # HANGUL SYLLABLE HIEUH-I-KIYEOK
0x4879  0xD78C  # HANGUL SYLLABLE HIEUH-I-NIEUN
0x487A  0xD790  # HANGUL SYLLABLE HIEUH-I-RIEUL
0x487B  0xD798  # HANGUL SYLLABLE HIEUH-I-MIEUM
0x487C  0xD799  # HANGUL SYLLABLE HIEUH-I-PIEUP
0x487D  0xD79B  # HANGUL SYLLABLE HIEUH-I-SIOS
0x487E  0xD79D  # HANGUL SYLLABLE HIEUH-I-IEUNG
0x4A21  0x4F3D  # <CJK>
0x4A22  0x4F73  # <CJK>
0x4A23  0x5047  # <CJK>
0x4A24  0x50F9  # <CJK>
0x4A25  0x52A0  # <CJK>
0x4A26  0x53EF  # <CJK>
0x4A27  0x5475  # <CJK>
0x4A28  0x54E5  # <CJK>
0x4A29  0x5609  # <CJK>
0x4A2A  0x5AC1  # <CJK>
0x4A2B  0x5BB6  # <CJK>
0x4A2C  0x6687  # <CJK>
0x4A2D  0x67B6  # <CJK>
0x4A2E  0x67B7  # <CJK>
0x4A2F  0x67EF  # <CJK>
0x4A30  0x6B4C  # <CJK>
0x4A31  0x73C2  # <CJK>
0x4A32  0x75C2  # <CJK>
0x4A33  0x7A3C  # <CJK>
0x4A34  0x82DB  # <CJK>
0x4A35  0x8304  # <CJK>
0x4A36  0x8857  # <CJK>
0x4A37  0x8888  # <CJK>
0x4A38  0x8A36  # <CJK>
0x4A39  0x8CC8  # <CJK>
0x4A3A  0x8DCF  # <CJK>
0x4A3B  0x8EFB  # <CJK>
0x4A3C  0x8FE6  # <CJK>
0x4A3D  0x99D5  # <CJK>
0x4A3E  0x523B  # <CJK>
0x4A3F  0x5374  # <CJK>
0x4A40  0x5404  # <CJK>
0x4A41  0x606A  # <CJK>
0x4A42  0x6164  # <CJK>
0x4A43  0x6BBC  # <CJK>
0x4A44  0x73CF  # <CJK>
0x4A45  0x811A  # <CJK>
0x4A46  0x89BA  # <CJK>
0x4A47  0x89D2  # <CJK>
0x4A48  0x95A3  # <CJK>
0x4A49  0x4F83  # <CJK>
0x4A4A  0x520A  # <CJK>
0x4A4B  0x58BE  # <CJK>
0x4A4C  0x5978  # <CJK>
0x4A4D  0x59E6  # <CJK>
0x4A4E  0x5E72  # <CJK>
0x4A4F  0x5E79  # <CJK>
0x4A50  0x61C7  # <CJK>
0x4A51  0x63C0  # <CJK>
0x4A52  0x6746  # <CJK>
0x4A53  0x67EC  # <CJK>
0x4A54  0x687F  # <CJK>
0x4A55  0x6F97  # <CJK>
0x4A56  0x764E  # <CJK>
0x4A57  0x770B  # <CJK>
0x4A58  0x78F5  # <CJK>
0x4A59  0x7A08  # <CJK>
0x4A5A  0x7AFF  # <CJK>
0x4A5B  0x7C21  # <CJK>
0x4A5C  0x809D  # <CJK>
0x4A5D  0x826E  # <CJK>
0x4A5E  0x8271  # <CJK>
0x4A5F  0x8AEB  # <CJK>
0x4A60  0x9593  # <CJK>
0x4A61  0x4E6B  # <CJK>
0x4A62  0x559D  # <CJK>
0x4A63  0x66F7  # <CJK>
0x4A64  0x6E34  # <CJK>
0x4A65  0x78A3  # <CJK>
0x4A66  0x7AED  # <CJK>
0x4A67  0x845B  # <CJK>
0x4A68  0x8910  # <CJK>
0x4A69  0x874E  # <CJK>
0x4A6A  0x97A8  # <CJK>
0x4A6B  0x52D8  # <CJK>
0x4A6C  0x574E  # <CJK>
0x4A6D  0x582A  # <CJK>
0x4A6E  0x5D4C  # <CJK>
0x4A6F  0x611F  # <CJK>
0x4A70  0x61BE  # <CJK>
0x4A71  0x6221  # <CJK>
0x4A72  0x6562  # <CJK>
0x4A73  0x67D1  # <CJK>
0x4A74  0x6A44  # <CJK>
0x4A75  0x6E1B  # <CJK>
0x4A76  0x7518  # <CJK>
0x4A77  0x75B3  # <CJK>
0x4A78  0x76E3  # <CJK>
0x4A79  0x77B0  # <CJK>
0x4A7A  0x7D3A  # <CJK>
0x4A7B  0x90AF  # <CJK>
0x4A7C  0x9451  # <CJK>
0x4A7D  0x9452  # <CJK>
0x4A7E  0x9F95  # <CJK>
0x4B21  0x5323  # <CJK>
0x4B22  0x5CAC  # <CJK>
0x4B23  0x7532  # <CJK>
0x4B24  0x80DB  # <CJK>
0x4B25  0x9240  # <CJK>
0x4B26  0x9598  # <CJK>
0x4B27  0x525B  # <CJK>
0x4B28  0x5808  # <CJK>
0x4B29  0x59DC  # <CJK>
0x4B2A  0x5CA1  # <CJK>
0x4B2B  0x5D17  # <CJK>
0x4B2C  0x5EB7  # <CJK>
0x4B2D  0x5F3A  # <CJK>
0x4B2E  0x5F4A  # <CJK>
0x4B2F  0x6177  # <CJK>
0x4B30  0x6C5F  # <CJK>
0x4B31  0x757A  # <CJK>
0x4B32  0x7586  # <CJK>
0x4B33  0x7CE0  # <CJK>
0x4B34  0x7D73  # <CJK>
0x4B35  0x7DB1  # <CJK>
0x4B36  0x7F8C  # <CJK>
0x4B37  0x8154  # <CJK>
0x4B38  0x8221  # <CJK>
0x4B39  0x8591  # <CJK>
0x4B3A  0x8941  # <CJK>
0x4B3B  0x8B1B  # <CJK>
0x4B3C  0x92FC  # <CJK>
0x4B3D  0x964D  # <CJK>
0x4B3E  0x9C47  # <CJK>
0x4B3F  0x4ECB  # <CJK>
0x4B40  0x4EF7  # <CJK>
0x4B41  0x500B  # <CJK>
0x4B42  0x51F1  # <CJK>
0x4B43  0x584F  # <CJK>
0x4B44  0x6137  # <CJK>
0x4B45  0x613E  # <CJK>
0x4B46  0x6168  # <CJK>
0x4B47  0x6539  # <CJK>
0x4B48  0x69EA  # <CJK>
0x4B49  0x6F11  # <CJK>
0x4B4A  0x75A5  # <CJK>
0x4B4B  0x7686  # <CJK>
0x4B4C  0x76D6  # <CJK>
0x4B4D  0x7B87  # <CJK>
0x4B4E  0x82A5  # <CJK>
0x4B4F  0x84CB  # <CJK>
0x4B50  0xF900  # <CJK>
0x4B51  0x93A7  # <CJK>
0x4B52  0x958B  # <CJK>
0x4B53  0x5580  # <CJK>
0x4B54  0x5BA2  # <CJK>
0x4B55  0x5751  # <CJK>
0x4B56  0xF901  # <CJK>
0x4B57  0x7CB3  # <CJK>
0x4B58  0x7FB9  # <CJK>
0x4B59  0x91B5  # <CJK>
0x4B5A  0x5028  # <CJK>
0x4B5B  0x53BB  # <CJK>
0x4B5C  0x5C45  # <CJK>
0x4B5D  0x5DE8  # <CJK>
0x4B5E  0x62D2  # <CJK>
0x4B5F  0x636E  # <CJK>
0x4B60  0x64DA  # <CJK>
0x4B61  0x64E7  # <CJK>
0x4B62  0x6E20  # <CJK>
0x4B63  0x70AC  # <CJK>
0x4B64  0x795B  # <CJK>
0x4B65  0x8DDD  # <CJK>
0x4B66  0x8E1E  # <CJK>
0x4B67  0xF902  # <CJK>
0x4B68  0x907D  # <CJK>
0x4B69  0x9245  # <CJK>
0x4B6A  0x92F8  # <CJK>
0x4B6B  0x4E7E  # <CJK>
0x4B6C  0x4EF6  # <CJK>
0x4B6D  0x5065  # <CJK>
0x4B6E  0x5DFE  # <CJK>
0x4B6F  0x5EFA  # <CJK>
0x4B70  0x6106  # <CJK>
0x4B71  0x6957  # <CJK>
0x4B72  0x8171  # <CJK>
0x4B73  0x8654  # <CJK>
0x4B74  0x8E47  # <CJK>
0x4B75  0x9375  # <CJK>
0x4B76  0x9A2B  # <CJK>
0x4B77  0x4E5E  # <CJK>
0x4B78  0x5091  # <CJK>
0x4B79  0x6770  # <CJK>
0x4B7A  0x6840  # <CJK>
0x4B7B  0x5109  # <CJK>
0x4B7C  0x528D  # <CJK>
0x4B7D  0x5292  # <CJK>
0x4B7E  0x6AA2  # <CJK>
0x4C21  0x77BC  # <CJK>
0x4C22  0x9210  # <CJK>
0x4C23  0x9ED4  # <CJK>
0x4C24  0x52AB  # <CJK>
0x4C25  0x602F  # <CJK>
0x4C26  0x8FF2  # <CJK>
0x4C27  0x5048  # <CJK>
0x4C28  0x61A9  # <CJK>
0x4C29  0x63ED  # <CJK>
0x4C2A  0x64CA  # <CJK>
0x4C2B  0x683C  # <CJK>
0x4C2C  0x6A84  # <CJK>
0x4C2D  0x6FC0  # <CJK>
0x4C2E  0x8188  # <CJK>
0x4C2F  0x89A1  # <CJK>
0x4C30  0x9694  # <CJK>
0x4C31  0x5805  # <CJK>
0x4C32  0x727D  # <CJK>
0x4C33  0x72AC  # <CJK>
0x4C34  0x7504  # <CJK>
0x4C35  0x7D79  # <CJK>
0x4C36  0x7E6D  # <CJK>
0x4C37  0x80A9  # <CJK>
0x4C38  0x898B  # <CJK>
0x4C39  0x8B74  # <CJK>
0x4C3A  0x9063  # <CJK>
0x4C3B  0x9D51  # <CJK>
0x4C3C  0x6289  # <CJK>
0x4C3D  0x6C7A  # <CJK>
0x4C3E  0x6F54  # <CJK>
0x4C3F  0x7D50  # <CJK>
0x4C40  0x7F3A  # <CJK>
0x4C41  0x8A23  # <CJK>
0x4C42  0x517C  # <CJK>
0x4C43  0x614A  # <CJK>
0x4C44  0x7B9D  # <CJK>
0x4C45  0x8B19  # <CJK>
0x4C46  0x9257  # <CJK>
0x4C47  0x938C  # <CJK>
0x4C48  0x4EAC  # <CJK>
0x4C49  0x4FD3  # <CJK>
0x4C4A  0x501E  # <CJK>
0x4C4B  0x50BE  # <CJK>
0x4C4C  0x5106  # <CJK>
0x4C4D  0x52C1  # <CJK>
0x4C4E  0x52CD  # <CJK>
0x4C4F  0x537F  # <CJK>
0x4C50  0x5770  # <CJK>
0x4C51  0x5883  # <CJK>
0x4C52  0x5E9A  # <CJK>
0x4C53  0x5F91  # <CJK>
0x4C54  0x6176  # <CJK>
0x4C55  0x61AC  # <CJK>
0x4C56  0x64CE  # <CJK>
0x4C57  0x656C  # <CJK>
0x4C58  0x666F  # <CJK>
0x4C59  0x66BB  # <CJK>
0x4C5A  0x66F4  # <CJK>
0x4C5B  0x6897  # <CJK>
0x4C5C  0x6D87  # <CJK>
0x4C5D  0x7085  # <CJK>
0x4C5E  0x70F1  # <CJK>
0x4C5F  0x749F  # <CJK>
0x4C60  0x74A5  # <CJK>
0x4C61  0x74CA  # <CJK>
0x4C62  0x75D9  # <CJK>
0x4C63  0x786C  # <CJK>
0x4C64  0x78EC  # <CJK>
0x4C65  0x7ADF  # <CJK>
0x4C66  0x7AF6  # <CJK>
0x4C67  0x7D45  # <CJK>
0x4C68  0x7D93  # <CJK>
0x4C69  0x8015  # <CJK>
0x4C6A  0x803F  # <CJK>
0x4C6B  0x811B  # <CJK>
0x4C6C  0x8396  # <CJK>
0x4C6D  0x8B66  # <CJK>
0x4C6E  0x8F15  # <CJK>
0x4C6F  0x9015  # <CJK>
0x4C70  0x93E1  # <CJK>
0x4C71  0x9803  # <CJK>
0x4C72  0x9838  # <CJK>
0x4C73  0x9A5A  # <CJK>
0x4C74  0x9BE8  # <CJK>
0x4C75  0x4FC2  # <CJK>
0x4C76  0x5553  # <CJK>
0x4C77  0x583A  # <CJK>
0x4C78  0x5951  # <CJK>
0x4C79  0x5B63  # <CJK>
0x4C7A  0x5C46  # <CJK>
0x4C7B  0x60B8  # <CJK>
0x4C7C  0x6212  # <CJK>
0x4C7D  0x6842  # <CJK>
0x4C7E  0x68B0  # <CJK>
0x4D21  0x68E8  # <CJK>
0x4D22  0x6EAA  # <CJK>
0x4D23  0x754C  # <CJK>
0x4D24  0x7678  # <CJK>
0x4D25  0x78CE  # <CJK>
0x4D26  0x7A3D  # <CJK>
0x4D27  0x7CFB  # <CJK>
0x4D28  0x7E6B  # <CJK>
0x4D29  0x7E7C  # <CJK>
0x4D2A  0x8A08  # <CJK>
0x4D2B  0x8AA1  # <CJK>
0x4D2C  0x8C3F  # <CJK>
0x4D2D  0x968E  # <CJK>
0x4D2E  0x9DC4  # <CJK>
0x4D2F  0x53E4  # <CJK>
0x4D30  0x53E9  # <CJK>
0x4D31  0x544A  # <CJK>
0x4D32  0x5471  # <CJK>
0x4D33  0x56FA  # <CJK>
0x4D34  0x59D1  # <CJK>
0x4D35  0x5B64  # <CJK>
0x4D36  0x5C3B  # <CJK>
0x4D37  0x5EAB  # <CJK>
0x4D38  0x62F7  # <CJK>
0x4D39  0x6537  # <CJK>
0x4D3A  0x6545  # <CJK>
0x4D3B  0x6572  # <CJK>
0x4D3C  0x66A0  # <CJK>
0x4D3D  0x67AF  # <CJK>
0x4D3E  0x69C1  # <CJK>
0x4D3F  0x6CBD  # <CJK>
0x4D40  0x75FC  # <CJK>
0x4D41  0x7690  # <CJK>
0x4D42  0x777E  # <CJK>
0x4D43  0x7A3F  # <CJK>
0x4D44  0x7F94  # <CJK>
0x4D45  0x8003  # <CJK>
0x4D46  0x80A1  # <CJK>
0x4D47  0x818F  # <CJK>
0x4D48  0x82E6  # <CJK>
0x4D49  0x82FD  # <CJK>
0x4D4A  0x83F0  # <CJK>
0x4D4B  0x85C1  # <CJK>
0x4D4C  0x8831  # <CJK>
0x4D4D  0x88B4  # <CJK>
0x4D4E  0x8AA5  # <CJK>
0x4D4F  0xF903  # <CJK>
0x4D50  0x8F9C  # <CJK>
0x4D51  0x932E  # <CJK>
0x4D52  0x96C7  # <CJK>
0x4D53  0x9867  # <CJK>
0x4D54  0x9AD8  # <CJK>
0x4D55  0x9F13  # <CJK>
0x4D56  0x54ED  # <CJK>
0x4D57  0x659B  # <CJK>
0x4D58  0x66F2  # <CJK>
0x4D59  0x688F  # <CJK>
0x4D5A  0x7A40  # <CJK>
0x4D5B  0x8C37  # <CJK>
0x4D5C  0x9D60  # <CJK>
0x4D5D  0x56F0  # <CJK>
0x4D5E  0x5764  # <CJK>
0x4D5F  0x5D11  # <CJK>
0x4D60  0x6606  # <CJK>
0x4D61  0x68B1  # <CJK>
0x4D62  0x68CD  # <CJK>
0x4D63  0x6EFE  # <CJK>
0x4D64  0x7428  # <CJK>
0x4D65  0x889E  # <CJK>
0x4D66  0x9BE4  # <CJK>
0x4D67  0x6C68  # <CJK>
0x4D68  0xF904  # <CJK>
0x4D69  0x9AA8  # <CJK>
0x4D6A  0x4F9B  # <CJK>
0x4D6B  0x516C  # <CJK>
0x4D6C  0x5171  # <CJK>
0x4D6D  0x529F  # <CJK>
0x4D6E  0x5B54  # <CJK>
0x4D6F  0x5DE5  # <CJK>
0x4D70  0x6050  # <CJK>
0x4D71  0x606D  # <CJK>
0x4D72  0x62F1  # <CJK>
0x4D73  0x63A7  # <CJK>
0x4D74  0x653B  # <CJK>
0x4D75  0x73D9  # <CJK>
0x4D76  0x7A7A  # <CJK>
0x4D77  0x86A3  # <CJK>
0x4D78  0x8CA2  # <CJK>
0x4D79  0x978F  # <CJK>
0x4D7A  0x4E32  # <CJK>
0x4D7B  0x5BE1  # <CJK>
0x4D7C  0x6208  # <CJK>
0x4D7D  0x679C  # <CJK>
0x4D7E  0x74DC  # <CJK>
0x4E21  0x79D1  # <CJK>
0x4E22  0x83D3  # <CJK>
0x4E23  0x8A87  # <CJK>
0x4E24  0x8AB2  # <CJK>
0x4E25  0x8DE8  # <CJK>
0x4E26  0x904E  # <CJK>
0x4E27  0x934B  # <CJK>
0x4E28  0x9846  # <CJK>
0x4E29  0x5ED3  # <CJK>
0x4E2A  0x69E8  # <CJK>
0x4E2B  0x85FF  # <CJK>
0x4E2C  0x90ED  # <CJK>
0x4E2D  0xF905  # <CJK>
0x4E2E  0x51A0  # <CJK>
0x4E2F  0x5B98  # <CJK>
0x4E30  0x5BEC  # <CJK>
0x4E31  0x6163  # <CJK>
0x4E32  0x68FA  # <CJK>
0x4E33  0x6B3E  # <CJK>
0x4E34  0x704C  # <CJK>
0x4E35  0x742F  # <CJK>
0x4E36  0x74D8  # <CJK>
0x4E37  0x7BA1  # <CJK>
0x4E38  0x7F50  # <CJK>
0x4E39  0x83C5  # <CJK>
0x4E3A  0x89C0  # <CJK>
0x4E3B  0x8CAB  # <CJK>
0x4E3C  0x95DC  # <CJK>
0x4E3D  0x9928  # <CJK>
0x4E3E  0x522E  # <CJK>
0x4E3F  0x605D  # <CJK>
0x4E40  0x62EC  # <CJK>
0x4E41  0x9002  # <CJK>
0x4E42  0x4F8A  # <CJK>
0x4E43  0x5149  # <CJK>
0x4E44  0x5321  # <CJK>
0x4E45  0x58D9  # <CJK>
0x4E46  0x5EE3  # <CJK>
0x4E47  0x66E0  # <CJK>
0x4E48  0x6D38  # <CJK>
0x4E49  0x709A  # <CJK>
0x4E4A  0x72C2  # <CJK>
0x4E4B  0x73D6  # <CJK>
0x4E4C  0x7B50  # <CJK>
0x4E4D  0x80F1  # <CJK>
0x4E4E  0x945B  # <CJK>
0x4E4F  0x5366  # <CJK>
0x4E50  0x639B  # <CJK>
0x4E51  0x7F6B  # <CJK>
0x4E52  0x4E56  # <CJK>
0x4E53  0x5080  # <CJK>
0x4E54  0x584A  # <CJK>
0x4E55  0x58DE  # <CJK>
0x4E56  0x602A  # <CJK>
0x4E57  0x6127  # <CJK>
0x4E58  0x62D0  # <CJK>
0x4E59  0x69D0  # <CJK>
0x4E5A  0x9B41  # <CJK>
0x4E5B  0x5B8F  # <CJK>
0x4E5C  0x7D18  # <CJK>
0x4E5D  0x80B1  # <CJK>
0x4E5E  0x8F5F  # <CJK>
0x4E5F  0x4EA4  # <CJK>
0x4E60  0x50D1  # <CJK>
0x4E61  0x54AC  # <CJK>
0x4E62  0x55AC  # <CJK>
0x4E63  0x5B0C  # <CJK>
0x4E64  0x5DA0  # <CJK>
0x4E65  0x5DE7  # <CJK>
0x4E66  0x652A  # <CJK>
0x4E67  0x654E  # <CJK>
0x4E68  0x6821  # <CJK>
0x4E69  0x6A4B  # <CJK>
0x4E6A  0x72E1  # <CJK>
0x4E6B  0x768E  # <CJK>
0x4E6C  0x77EF  # <CJK>
0x4E6D  0x7D5E  # <CJK>
0x4E6E  0x7FF9  # <CJK>
0x4E6F  0x81A0  # <CJK>
0x4E70  0x854E  # <CJK>
0x4E71  0x86DF  # <CJK>
0x4E72  0x8F03  # <CJK>
0x4E73  0x8F4E  # <CJK>
0x4E74  0x90CA  # <CJK>
0x4E75  0x9903  # <CJK>
0x4E76  0x9A55  # <CJK>
0x4E77  0x9BAB  # <CJK>
0x4E78  0x4E18  # <CJK>
0x4E79  0x4E45  # <CJK>
0x4E7A  0x4E5D  # <CJK>
0x4E7B  0x4EC7  # <CJK>
0x4E7C  0x4FF1  # <CJK>
0x4E7D  0x5177  # <CJK>
0x4E7E  0x52FE  # <CJK>
0x4F21  0x5340  # <CJK>
0x4F22  0x53E3  # <CJK>
0x4F23  0x53E5  # <CJK>
0x4F24  0x548E  # <CJK>
0x4F25  0x5614  # <CJK>
0x4F26  0x5775  # <CJK>
0x4F27  0x57A2  # <CJK>
0x4F28  0x5BC7  # <CJK>
0x4F29  0x5D87  # <CJK>
0x4F2A  0x5ED0  # <CJK>
0x4F2B  0x61FC  # <CJK>
0x4F2C  0x62D8  # <CJK>
0x4F2D  0x6551  # <CJK>
0x4F2E  0x67B8  # <CJK>
0x4F2F  0x67E9  # <CJK>
0x4F30  0x69CB  # <CJK>
0x4F31  0x6B50  # <CJK>
0x4F32  0x6BC6  # <CJK>
0x4F33  0x6BEC  # <CJK>
0x4F34  0x6C42  # <CJK>
0x4F35  0x6E9D  # <CJK>
0x4F36  0x7078  # <CJK>
0x4F37  0x72D7  # <CJK>
0x4F38  0x7396  # <CJK>
0x4F39  0x7403  # <CJK>
0x4F3A  0x77BF  # <CJK>
0x4F3B  0x77E9  # <CJK>
0x4F3C  0x7A76  # <CJK>
0x4F3D  0x7D7F  # <CJK>
0x4F3E  0x8009  # <CJK>
0x4F3F  0x81FC  # <CJK>
0x4F40  0x8205  # <CJK>
0x4F41  0x820A  # <CJK>
0x4F42  0x82DF  # <CJK>
0x4F43  0x8862  # <CJK>
0x4F44  0x8B33  # <CJK>
0x4F45  0x8CFC  # <CJK>
0x4F46  0x8EC0  # <CJK>
0x4F47  0x9011  # <CJK>
0x4F48  0x90B1  # <CJK>
0x4F49  0x9264  # <CJK>
0x4F4A  0x92B6  # <CJK>
0x4F4B  0x99D2  # <CJK>
0x4F4C  0x9A45  # <CJK>
0x4F4D  0x9CE9  # <CJK>
0x4F4E  0x9DD7  # <CJK>
0x4F4F  0x9F9C  # <CJK>
0x4F50  0x570B  # <CJK>
0x4F51  0x5C40  # <CJK>
0x4F52  0x83CA  # <CJK>
0x4F53  0x97A0  # <CJK>
0x4F54  0x97AB  # <CJK>
0x4F55  0x9EB4  # <CJK>
0x4F56  0x541B  # <CJK>
0x4F57  0x7A98  # <CJK>
0x4F58  0x7FA4  # <CJK>
0x4F59  0x88D9  # <CJK>
0x4F5A  0x8ECD  # <CJK>
0x4F5B  0x90E1  # <CJK>
0x4F5C  0x5800  # <CJK>
0x4F5D  0x5C48  # <CJK>
0x4F5E  0x6398  # <CJK>
0x4F5F  0x7A9F  # <CJK>
0x4F60  0x5BAE  # <CJK>
0x4F61  0x5F13  # <CJK>
0x4F62  0x7A79  # <CJK>
0x4F63  0x7AAE  # <CJK>
0x4F64  0x828E  # <CJK>
0x4F65  0x8EAC  # <CJK>
0x4F66  0x5026  # <CJK>
0x4F67  0x5238  # <CJK>
0x4F68  0x52F8  # <CJK>
0x4F69  0x5377  # <CJK>
0x4F6A  0x5708  # <CJK>
0x4F6B  0x62F3  # <CJK>
0x4F6C  0x6372  # <CJK>
0x4F6D  0x6B0A  # <CJK>
0x4F6E  0x6DC3  # <CJK>
0x4F6F  0x7737  # <CJK>
0x4F70  0x53A5  # <CJK>
0x4F71  0x7357  # <CJK>
0x4F72  0x8568  # <CJK>
0x4F73  0x8E76  # <CJK>
0x4F74  0x95D5  # <CJK>
0x4F75  0x673A  # <CJK>
0x4F76  0x6AC3  # <CJK>
0x4F77  0x6F70  # <CJK>
0x4F78  0x8A6D  # <CJK>
0x4F79  0x8ECC  # <CJK>
0x4F7A  0x994B  # <CJK>
0x4F7B  0xF906  # <CJK>
0x4F7C  0x6677  # <CJK>
0x4F7D  0x6B78  # <CJK>
0x4F7E  0x8CB4  # <CJK>
0x5021  0x9B3C  # <CJK>
0x5022  0xF907  # <CJK>
0x5023  0x53EB  # <CJK>
0x5024  0x572D  # <CJK>
0x5025  0x594E  # <CJK>
0x5026  0x63C6  # <CJK>
0x5027  0x69FB  # <CJK>
0x5028  0x73EA  # <CJK>
0x5029  0x7845  # <CJK>
0x502A  0x7ABA  # <CJK>
0x502B  0x7AC5  # <CJK>
0x502C  0x7CFE  # <CJK>
0x502D  0x8475  # <CJK>
0x502E  0x898F  # <CJK>
0x502F  0x8D73  # <CJK>
0x5030  0x9035  # <CJK>
0x5031  0x95A8  # <CJK>
0x5032  0x52FB  # <CJK>
0x5033  0x5747  # <CJK>
0x5034  0x7547  # <CJK>
0x5035  0x7B60  # <CJK>
0x5036  0x83CC  # <CJK>
0x5037  0x921E  # <CJK>
0x5038  0xF908  # <CJK>
0x5039  0x6A58  # <CJK>
0x503A  0x514B  # <CJK>
0x503B  0x524B  # <CJK>
0x503C  0x5287  # <CJK>
0x503D  0x621F  # <CJK>
0x503E  0x68D8  # <CJK>
0x503F  0x6975  # <CJK>
0x5040  0x9699  # <CJK>
0x5041  0x50C5  # <CJK>
0x5042  0x52A4  # <CJK>
0x5043  0x52E4  # <CJK>
0x5044  0x61C3  # <CJK>
0x5045  0x65A4  # <CJK>
0x5046  0x6839  # <CJK>
0x5047  0x69FF  # <CJK>
0x5048  0x747E  # <CJK>
0x5049  0x7B4B  # <CJK>
0x504A  0x82B9  # <CJK>
0x504B  0x83EB  # <CJK>
0x504C  0x89B2  # <CJK>
0x504D  0x8B39  # <CJK>
0x504E  0x8FD1  # <CJK>
0x504F  0x9949  # <CJK>
0x5050  0xF909  # <CJK>
0x5051  0x4ECA  # <CJK>
0x5052  0x5997  # <CJK>
0x5053  0x64D2  # <CJK>
0x5054  0x6611  # <CJK>
0x5055  0x6A8E  # <CJK>
0x5056  0x7434  # <CJK>
0x5057  0x7981  # <CJK>
0x5058  0x79BD  # <CJK>
0x5059  0x82A9  # <CJK>
0x505A  0x887E  # <CJK>
0x505B  0x887F  # <CJK>
0x505C  0x895F  # <CJK>
0x505D  0xF90A  # <CJK>
0x505E  0x9326  # <CJK>
0x505F  0x4F0B  # <CJK>
0x5060  0x53CA  # <CJK>
0x5061  0x6025  # <CJK>
0x5062  0x6271  # <CJK>
0x5063  0x6C72  # <CJK>
0x5064  0x7D1A  # <CJK>
0x5065  0x7D66  # <CJK>
0x5066  0x4E98  # <CJK>
0x5067  0x5162  # <CJK>
0x5068  0x77DC  # <CJK>
0x5069  0x80AF  # <CJK>
0x506A  0x4F01  # <CJK>
0x506B  0x4F0E  # <CJK>
0x506C  0x5176  # <CJK>
0x506D  0x5180  # <CJK>
0x506E  0x55DC  # <CJK>
0x506F  0x5668  # <CJK>
0x5070  0x573B  # <CJK>
0x5071  0x57FA  # <CJK>
0x5072  0x57FC  # <CJK>
0x5073  0x5914  # <CJK>
0x5074  0x5947  # <CJK>
0x5075  0x5993  # <CJK>
0x5076  0x5BC4  # <CJK>
0x5077  0x5C90  # <CJK>
0x5078  0x5D0E  # <CJK>
0x5079  0x5DF1  # <CJK>
0x507A  0x5E7E  # <CJK>
0x507B  0x5FCC  # <CJK>
0x507C  0x6280  # <CJK>
0x507D  0x65D7  # <CJK>
0x507E  0x65E3  # <CJK>
0x5121  0x671E  # <CJK>
0x5122  0x671F  # <CJK>
0x5123  0x675E  # <CJK>
0x5124  0x68CB  # <CJK>
0x5125  0x68C4  # <CJK>
0x5126  0x6A5F  # <CJK>
0x5127  0x6B3A  # <CJK>
0x5128  0x6C23  # <CJK>
0x5129  0x6C7D  # <CJK>
0x512A  0x6C82  # <CJK>
0x512B  0x6DC7  # <CJK>
0x512C  0x7398  # <CJK>
0x512D  0x7426  # <CJK>
0x512E  0x742A  # <CJK>
0x512F  0x7482  # <CJK>
0x5130  0x74A3  # <CJK>
0x5131  0x7578  # <CJK>
0x5132  0x757F  # <CJK>
0x5133  0x7881  # <CJK>
0x5134  0x78EF  # <CJK>
0x5135  0x7941  # <CJK>
0x5136  0x7947  # <CJK>
0x5137  0x7948  # <CJK>
0x5138  0x797A  # <CJK>
0x5139  0x7B95  # <CJK>
0x513A  0x7D00  # <CJK>
0x513B  0x7DBA  # <CJK>
0x513C  0x7F88  # <CJK>
0x513D  0x8006  # <CJK>
0x513E  0x802D  # <CJK>
0x513F  0x808C  # <CJK>
0x5140  0x8A18  # <CJK>
0x5141  0x8B4F  # <CJK>
0x5142  0x8C48  # <CJK>
0x5143  0x8D77  # <CJK>
0x5144  0x9321  # <CJK>
0x5145  0x9324  # <CJK>
0x5146  0x98E2  # <CJK>
0x5147  0x9951  # <CJK>
0x5148  0x9A0E  # <CJK>
0x5149  0x9A0F  # <CJK>
0x514A  0x9A65  # <CJK>
0x514B  0x9E92  # <CJK>
0x514C  0x7DCA  # <CJK>
0x514D  0x4F76  # <CJK>
0x514E  0x5409  # <CJK>
0x514F  0x62EE  # <CJK>
0x5150  0x6854  # <CJK>
0x5151  0x91D1  # <CJK>
0x5152  0x55AB  # <CJK>
0x5153  0x513A  # <CJK>
0x5154  0xF90B  # <CJK>
0x5155  0xF90C  # <CJK>
0x5156  0x5A1C  # <CJK>
0x5157  0x61E6  # <CJK>
0x5158  0xF90D  # <CJK>
0x5159  0x62CF  # <CJK>
0x515A  0x62FF  # <CJK>
0x515B  0xF90E  # <CJK>
0x515C  0xF90F  # <CJK>
0x515D  0xF910  # <CJK>
0x515E  0xF911  # <CJK>
0x515F  0xF912  # <CJK>
0x5160  0xF913  # <CJK>
0x5161  0x90A3  # <CJK>
0x5162  0xF914  # <CJK>
0x5163  0xF915  # <CJK>
0x5164  0xF916  # <CJK>
0x5165  0xF917  # <CJK>
0x5166  0xF918  # <CJK>
0x5167  0x8AFE  # <CJK>
0x5168  0xF919  # <CJK>
0x5169  0xF91A  # <CJK>
0x516A  0xF91B  # <CJK>
0x516B  0xF91C  # <CJK>
0x516C  0x6696  # <CJK>
0x516D  0xF91D  # <CJK>
0x516E  0x7156  # <CJK>
0x516F  0xF91E  # <CJK>
0x5170  0xF91F  # <CJK>
0x5171  0x96E3  # <CJK>
0x5172  0xF920  # <CJK>
0x5173  0x634F  # <CJK>
0x5174  0x637A  # <CJK>
0x5175  0x5357  # <CJK>
0x5176  0xF921  # <CJK>
0x5177  0x678F  # <CJK>
0x5178  0x6960  # <CJK>
0x5179  0x6E73  # <CJK>
0x517A  0xF922  # <CJK>
0x517B  0x7537  # <CJK>
0x517C  0xF923  # <CJK>
0x517D  0xF924  # <CJK>
0x517E  0xF925  # <CJK>
0x5221  0x7D0D  # <CJK>
0x5222  0xF926  # <CJK>
0x5223  0xF927  # <CJK>
0x5224  0x8872  # <CJK>
0x5225  0x56CA  # <CJK>
0x5226  0x5A18  # <CJK>
0x5227  0xF928  # <CJK>
0x5228  0xF929  # <CJK>
0x5229  0xF92A  # <CJK>
0x522A  0xF92B  # <CJK>
0x522B  0xF92C  # <CJK>
0x522C  0x4E43  # <CJK>
0x522D  0xF92D  # <CJK>
0x522E  0x5167  # <CJK>
0x522F  0x5948  # <CJK>
0x5230  0x67F0  # <CJK>
0x5231  0x8010  # <CJK>
0x5232  0xF92E  # <CJK>
0x5233  0x5973  # <CJK>
0x5234  0x5E74  # <CJK>
0x5235  0x649A  # <CJK>
0x5236  0x79CA  # <CJK>
0x5237  0x5FF5  # <CJK>
0x5238  0x606C  # <CJK>
0x5239  0x62C8  # <CJK>
0x523A  0x637B  # <CJK>
0x523B  0x5BE7  # <CJK>
0x523C  0x5BD7  # <CJK>
0x523D  0x52AA  # <CJK>
0x523E  0xF92F  # <CJK>
0x523F  0x5974  # <CJK>
0x5240  0x5F29  # <CJK>
0x5241  0x6012  # <CJK>
0x5242  0xF930  # <CJK>
0x5243  0xF931  # <CJK>
0x5244  0xF932  # <CJK>
0x5245  0x7459  # <CJK>
0x5246  0xF933  # <CJK>
0x5247  0xF934  # <CJK>
0x5248  0xF935  # <CJK>
0x5249  0xF936  # <CJK>
0x524A  0xF937  # <CJK>
0x524B  0xF938  # <CJK>
0x524C  0x99D1  # <CJK>
0x524D  0xF939  # <CJK>
0x524E  0xF93A  # <CJK>
0x524F  0xF93B  # <CJK>
0x5250  0xF93C  # <CJK>
0x5251  0xF93D  # <CJK>
0x5252  0xF93E  # <CJK>
0x5253  0xF93F  # <CJK>
0x5254  0xF940  # <CJK>
0x5255  0xF941  # <CJK>
0x5256  0xF942  # <CJK>
0x5257  0xF943  # <CJK>
0x5258  0x6FC3  # <CJK>
0x5259  0xF944  # <CJK>
0x525A  0xF945  # <CJK>
0x525B  0x81BF  # <CJK>
0x525C  0x8FB2  # <CJK>
0x525D  0x60F1  # <CJK>
0x525E  0xF946  # <CJK>
0x525F  0xF947  # <CJK>
0x5260  0x8166  # <CJK>
0x5261  0xF948  # <CJK>
0x5262  0xF949  # <CJK>
0x5263  0x5C3F  # <CJK>
0x5264  0xF94A  # <CJK>
0x5265  0xF94B  # <CJK>
0x5266  0xF94C  # <CJK>
0x5267  0xF94D  # <CJK>
0x5268  0xF94E  # <CJK>
0x5269  0xF94F  # <CJK>
0x526A  0xF950  # <CJK>
0x526B  0xF951  # <CJK>
0x526C  0x5AE9  # <CJK>
0x526D  0x8A25  # <CJK>
0x526E  0x677B  # <CJK>
0x526F  0x7D10  # <CJK>
0x5270  0xF952  # <CJK>
0x5271  0xF953  # <CJK>
0x5272  0xF954  # <CJK>
0x5273  0xF955  # <CJK>
0x5274  0xF956  # <CJK>
0x5275  0xF957  # <CJK>
0x5276  0x80FD  # <CJK>
0x5277  0xF958  # <CJK>
0x5278  0xF959  # <CJK>
0x5279  0x5C3C  # <CJK>
0x527A  0x6CE5  # <CJK>
0x527B  0x533F  # <CJK>
0x527C  0x6EBA  # <CJK>
0x527D  0x591A  # <CJK>
0x527E  0x8336  # <CJK>
0x5321  0x4E39  # <CJK>
0x5322  0x4EB6  # <CJK>
0x5323  0x4F46  # <CJK>
0x5324  0x55AE  # <CJK>
0x5325  0x5718  # <CJK>
0x5326  0x58C7  # <CJK>
0x5327  0x5F56  # <CJK>
0x5328  0x65B7  # <CJK>
0x5329  0x65E6  # <CJK>
0x532A  0x6A80  # <CJK>
0x532B  0x6BB5  # <CJK>
0x532C  0x6E4D  # <CJK>
0x532D  0x77ED  # <CJK>
0x532E  0x7AEF  # <CJK>
0x532F  0x7C1E  # <CJK>
0x5330  0x7DDE  # <CJK>
0x5331  0x86CB  # <CJK>
0x5332  0x8892  # <CJK>
0x5333  0x9132  # <CJK>
0x5334  0x935B  # <CJK>
0x5335  0x64BB  # <CJK>
0x5336  0x6FBE  # <CJK>
0x5337  0x737A  # <CJK>
0x5338  0x75B8  # <CJK>
0x5339  0x9054  # <CJK>
0x533A  0x5556  # <CJK>
0x533B  0x574D  # <CJK>
0x533C  0x61BA  # <CJK>
0x533D  0x64D4  # <CJK>
0x533E  0x66C7  # <CJK>
0x533F  0x6DE1  # <CJK>
0x5340  0x6E5B  # <CJK>
0x5341  0x6F6D  # <CJK>
0x5342  0x6FB9  # <CJK>
0x5343  0x75F0  # <CJK>
0x5344  0x8043  # <CJK>
0x5345  0x81BD  # <CJK>
0x5346  0x8541  # <CJK>
0x5347  0x8983  # <CJK>
0x5348  0x8AC7  # <CJK>
0x5349  0x8B5A  # <CJK>
0x534A  0x931F  # <CJK>
0x534B  0x6C93  # <CJK>
0x534C  0x7553  # <CJK>
0x534D  0x7B54  # <CJK>
0x534E  0x8E0F  # <CJK>
0x534F  0x905D  # <CJK>
0x5350  0x5510  # <CJK>
0x5351  0x5802  # <CJK>
0x5352  0x5858  # <CJK>
0x5353  0x5E62  # <CJK>
0x5354  0x6207  # <CJK>
0x5355  0x649E  # <CJK>
0x5356  0x68E0  # <CJK>
0x5357  0x7576  # <CJK>
0x5358  0x7CD6  # <CJK>
0x5359  0x87B3  # <CJK>
0x535A  0x9EE8  # <CJK>
0x535B  0x4EE3  # <CJK>
0x535C  0x5788  # <CJK>
0x535D  0x576E  # <CJK>
0x535E  0x5927  # <CJK>
0x535F  0x5C0D  # <CJK>
0x5360  0x5CB1  # <CJK>
0x5361  0x5E36  # <CJK>
0x5362  0x5F85  # <CJK>
0x5363  0x6234  # <CJK>
0x5364  0x64E1  # <CJK>
0x5365  0x73B3  # <CJK>
0x5366  0x81FA  # <CJK>
0x5367  0x888B  # <CJK>
0x5368  0x8CB8  # <CJK>
0x5369  0x968A  # <CJK>
0x536A  0x9EDB  # <CJK>
0x536B  0x5B85  # <CJK>
0x536C  0x5FB7  # <CJK>
0x536D  0x60B3  # <CJK>
0x536E  0x5012  # <CJK>
0x536F  0x5200  # <CJK>
0x5370  0x5230  # <CJK>
0x5371  0x5716  # <CJK>
0x5372  0x5835  # <CJK>
0x5373  0x5857  # <CJK>
0x5374  0x5C0E  # <CJK>
0x5375  0x5C60  # <CJK>
0x5376  0x5CF6  # <CJK>
0x5377  0x5D8B  # <CJK>
0x5378  0x5EA6  # <CJK>
0x5379  0x5F92  # <CJK>
0x537A  0x60BC  # <CJK>
0x537B  0x6311  # <CJK>
0x537C  0x6389  # <CJK>
0x537D  0x6417  # <CJK>
0x537E  0x6843  # <CJK>
0x5421  0x68F9  # <CJK>
0x5422  0x6AC2  # <CJK>
0x5423  0x6DD8  # <CJK>
0x5424  0x6E21  # <CJK>
0x5425  0x6ED4  # <CJK>
0x5426  0x6FE4  # <CJK>
0x5427  0x71FE  # <CJK>
0x5428  0x76DC  # <CJK>
0x5429  0x7779  # <CJK>
0x542A  0x79B1  # <CJK>
0x542B  0x7A3B  # <CJK>
0x542C  0x8404  # <CJK>
0x542D  0x89A9  # <CJK>
0x542E  0x8CED  # <CJK>
0x542F  0x8DF3  # <CJK>
0x5430  0x8E48  # <CJK>
0x5431  0x9003  # <CJK>
0x5432  0x9014  # <CJK>
0x5433  0x9053  # <CJK>
0x5434  0x90FD  # <CJK>
0x5435  0x934D  # <CJK>
0x5436  0x9676  # <CJK>
0x5437  0x97DC  # <CJK>
0x5438  0x6BD2  # <CJK>
0x5439  0x7006  # <CJK>
0x543A  0x7258  # <CJK>
0x543B  0x72A2  # <CJK>
0x543C  0x7368  # <CJK>
0x543D  0x7763  # <CJK>
0x543E  0x79BF  # <CJK>
0x543F  0x7BE4  # <CJK>
0x5440  0x7E9B  # <CJK>
0x5441  0x8B80  # <CJK>
0x5442  0x58A9  # <CJK>
0x5443  0x60C7  # <CJK>
0x5444  0x6566  # <CJK>
0x5445  0x65FD  # <CJK>
0x5446  0x66BE  # <CJK>
0x5447  0x6C8C  # <CJK>
0x5448  0x711E  # <CJK>
0x5449  0x71C9  # <CJK>
0x544A  0x8C5A  # <CJK>
0x544B  0x9813  # <CJK>
0x544C  0x4E6D  # <CJK>
0x544D  0x7A81  # <CJK>
0x544E  0x4EDD  # <CJK>
0x544F  0x51AC  # <CJK>
0x5450  0x51CD  # <CJK>
0x5451  0x52D5  # <CJK>
0x5452  0x540C  # <CJK>
0x5453  0x61A7  # <CJK>
0x5454  0x6771  # <CJK>
0x5455  0x6850  # <CJK>
0x5456  0x68DF  # <CJK>
0x5457  0x6D1E  # <CJK>
0x5458  0x6F7C  # <CJK>
0x5459  0x75BC  # <CJK>
0x545A  0x77B3  # <CJK>
0x545B  0x7AE5  # <CJK>
0x545C  0x80F4  # <CJK>
0x545D  0x8463  # <CJK>
0x545E  0x9285  # <CJK>
0x545F  0x515C  # <CJK>
0x5460  0x6597  # <CJK>
0x5461  0x675C  # <CJK>
0x5462  0x6793  # <CJK>
0x5463  0x75D8  # <CJK>
0x5464  0x7AC7  # <CJK>
0x5465  0x8373  # <CJK>
0x5466  0xF95A  # <CJK>
0x5467  0x8C46  # <CJK>
0x5468  0x9017  # <CJK>
0x5469  0x982D  # <CJK>
0x546A  0x5C6F  # <CJK>
0x546B  0x81C0  # <CJK>
0x546C  0x829A  # <CJK>
0x546D  0x9041  # <CJK>
0x546E  0x906F  # <CJK>
0x546F  0x920D  # <CJK>
0x5470  0x5F97  # <CJK>
0x5471  0x5D9D  # <CJK>
0x5472  0x6A59  # <CJK>
0x5473  0x71C8  # <CJK>
0x5474  0x767B  # <CJK>
0x5475  0x7B49  # <CJK>
0x5476  0x85E4  # <CJK>
0x5477  0x8B04  # <CJK>
0x5478  0x9127  # <CJK>
0x5479  0x9A30  # <CJK>
0x547A  0x5587  # <CJK>
0x547B  0x61F6  # <CJK>
0x547C  0xF95B  # <CJK>
0x547D  0x7669  # <CJK>
0x547E  0x7F85  # <CJK>
0x5521  0x863F  # <CJK>
0x5522  0x87BA  # <CJK>
0x5523  0x88F8  # <CJK>
0x5524  0x908F  # <CJK>
0x5525  0xF95C  # <CJK>
0x5526  0x6D1B  # <CJK>
0x5527  0x70D9  # <CJK>
0x5528  0x73DE  # <CJK>
0x5529  0x7D61  # <CJK>
0x552A  0x843D  # <CJK>
0x552B  0xF95D  # <CJK>
0x552C  0x916A  # <CJK>
0x552D  0x99F1  # <CJK>
0x552E  0xF95E  # <CJK>
0x552F  0x4E82  # <CJK>
0x5530  0x5375  # <CJK>
0x5531  0x6B04  # <CJK>
0x5532  0x6B12  # <CJK>
0x5533  0x703E  # <CJK>
0x5534  0x721B  # <CJK>
0x5535  0x862D  # <CJK>
0x5536  0x9E1E  # <CJK>
0x5537  0x524C  # <CJK>
0x5538  0x8FA3  # <CJK>
0x5539  0x5D50  # <CJK>
0x553A  0x64E5  # <CJK>
0x553B  0x652C  # <CJK>
0x553C  0x6B16  # <CJK>
0x553D  0x6FEB  # <CJK>
0x553E  0x7C43  # <CJK>
0x553F  0x7E9C  # <CJK>
0x5540  0x85CD  # <CJK>
0x5541  0x8964  # <CJK>
0x5542  0x89BD  # <CJK>
0x5543  0x62C9  # <CJK>
0x5544  0x81D8  # <CJK>
0x5545  0x881F  # <CJK>
0x5546  0x5ECA  # <CJK>
0x5547  0x6717  # <CJK>
0x5548  0x6D6A  # <CJK>
0x5549  0x72FC  # <CJK>
0x554A  0x7405  # <CJK>
0x554B  0x746F  # <CJK>
0x554C  0x8782  # <CJK>
0x554D  0x90DE  # <CJK>
0x554E  0x4F86  # <CJK>
0x554F  0x5D0D  # <CJK>
0x5550  0x5FA0  # <CJK>
0x5551  0x840A  # <CJK>
0x5552  0x51B7  # <CJK>
0x5553  0x63A0  # <CJK>
0x5554  0x7565  # <CJK>
0x5555  0x4EAE  # <CJK>
0x5556  0x5006  # <CJK>
0x5557  0x5169  # <CJK>
0x5558  0x51C9  # <CJK>
0x5559  0x6881  # <CJK>
0x555A  0x6A11  # <CJK>
0x555B  0x7CAE  # <CJK>
0x555C  0x7CB1  # <CJK>
0x555D  0x7CE7  # <CJK>
0x555E  0x826F  # <CJK>
0x555F  0x8AD2  # <CJK>
0x5560  0x8F1B  # <CJK>
0x5561  0x91CF  # <CJK>
0x5562  0x4FB6  # <CJK>
0x5563  0x5137  # <CJK>
0x5564  0x52F5  # <CJK>
0x5565  0x5442  # <CJK>
0x5566  0x5EEC  # <CJK>
0x5567  0x616E  # <CJK>
0x5568  0x623E  # <CJK>
0x5569  0x65C5  # <CJK>
0x556A  0x6ADA  # <CJK>
0x556B  0x6FFE  # <CJK>
0x556C  0x792A  # <CJK>
0x556D  0x85DC  # <CJK>
0x556E  0x8823  # <CJK>
0x556F  0x95AD  # <CJK>
0x5570  0x9A62  # <CJK>
0x5571  0x9A6A  # <CJK>
0x5572  0x9E97  # <CJK>
0x5573  0x9ECE  # <CJK>
0x5574  0x529B  # <CJK>
0x5575  0x66C6  # <CJK>
0x5576  0x6B77  # <CJK>
0x5577  0x701D  # <CJK>
0x5578  0x792B  # <CJK>
0x5579  0x8F62  # <CJK>
0x557A  0x9742  # <CJK>
0x557B  0x6190  # <CJK>
0x557C  0x6200  # <CJK>
0x557D  0x6523  # <CJK>
0x557E  0x6F23  # <CJK>
0x5621  0x7149  # <CJK>
0x5622  0x7489  # <CJK>
0x5623  0x7DF4  # <CJK>
0x5624  0x806F  # <CJK>
0x5625  0x84EE  # <CJK>
0x5626  0x8F26  # <CJK>
0x5627  0x9023  # <CJK>
0x5628  0x934A  # <CJK>
0x5629  0x51BD  # <CJK>
0x562A  0x5217  # <CJK>
0x562B  0x52A3  # <CJK>
0x562C  0x6D0C  # <CJK>
0x562D  0x70C8  # <CJK>
0x562E  0x88C2  # <CJK>
0x562F  0x5EC9  # <CJK>
0x5630  0x6582  # <CJK>
0x5631  0x6BAE  # <CJK>
0x5632  0x6FC2  # <CJK>
0x5633  0x7C3E  # <CJK>
0x5634  0x7375  # <CJK>
0x5635  0x4EE4  # <CJK>
0x5636  0x4F36  # <CJK>
0x5637  0x56F9  # <CJK>
0x5638  0xF95F  # <CJK>
0x5639  0x5CBA  # <CJK>
0x563A  0x5DBA  # <CJK>
0x563B  0x601C  # <CJK>
0x563C  0x73B2  # <CJK>
0x563D  0x7B2D  # <CJK>
0x563E  0x7F9A  # <CJK>
0x563F  0x7FCE  # <CJK>
0x5640  0x8046  # <CJK>
0x5641  0x901E  # <CJK>
0x5642  0x9234  # <CJK>
0x5643  0x96F6  # <CJK>
0x5644  0x9748  # <CJK>
0x5645  0x9818  # <CJK>
0x5646  0x9F61  # <CJK>
0x5647  0x4F8B  # <CJK>
0x5648  0x6FA7  # <CJK>
0x5649  0x79AE  # <CJK>
0x564A  0x91B4  # <CJK>
0x564B  0x96B7  # <CJK>
0x564C  0x52DE  # <CJK>
0x564D  0xF960  # <CJK>
0x564E  0x6488  # <CJK>
0x564F  0x64C4  # <CJK>
0x5650  0x6AD3  # <CJK>
0x5651  0x6F5E  # <CJK>
0x5652  0x7018  # <CJK>
0x5653  0x7210  # <CJK>
0x5654  0x76E7  # <CJK>
0x5655  0x8001  # <CJK>
0x5656  0x8606  # <CJK>
0x5657  0x865C  # <CJK>
0x5658  0x8DEF  # <CJK>
0x5659  0x8F05  # <CJK>
0x565A  0x9732  # <CJK>
0x565B  0x9B6F  # <CJK>
0x565C  0x9DFA  # <CJK>
0x565D  0x9E75  # <CJK>
0x565E  0x788C  # <CJK>
0x565F  0x797F  # <CJK>
0x5660  0x7DA0  # <CJK>
0x5661  0x83C9  # <CJK>
0x5662  0x9304  # <CJK>
0x5663  0x9E7F  # <CJK>
0x5664  0x9E93  # <CJK>
0x5665  0x8AD6  # <CJK>
0x5666  0x58DF  # <CJK>
0x5667  0x5F04  # <CJK>
0x5668  0x6727  # <CJK>
0x5669  0x7027  # <CJK>
0x566A  0x74CF  # <CJK>
0x566B  0x7C60  # <CJK>
0x566C  0x807E  # <CJK>
0x566D  0x5121  # <CJK>
0x566E  0x7028  # <CJK>
0x566F  0x7262  # <CJK>
0x5670  0x78CA  # <CJK>
0x5671  0x8CC2  # <CJK>
0x5672  0x8CDA  # <CJK>
0x5673  0x8CF4  # <CJK>
0x5674  0x96F7  # <CJK>
0x5675  0x4E86  # <CJK>
0x5676  0x50DA  # <CJK>
0x5677  0x5BEE  # <CJK>
0x5678  0x5ED6  # <CJK>
0x5679  0x6599  # <CJK>
0x567A  0x71CE  # <CJK>
0x567B  0x7642  # <CJK>
0x567C  0x77AD  # <CJK>
0x567D  0x804A  # <CJK>
0x567E  0x84FC  # <CJK>
0x5721  0x907C  # <CJK>
0x5722  0x9B27  # <CJK>
0x5723  0x9F8D  # <CJK>
0x5724  0x58D8  # <CJK>
0x5725  0x5A41  # <CJK>
0x5726  0x5C62  # <CJK>
0x5727  0x6A13  # <CJK>
0x5728  0x6DDA  # <CJK>
0x5729  0x6F0F  # <CJK>
0x572A  0x763B  # <CJK>
0x572B  0x7D2F  # <CJK>
0x572C  0x7E37  # <CJK>
0x572D  0x851E  # <CJK>
0x572E  0x8938  # <CJK>
0x572F  0x93E4  # <CJK>
0x5730  0x964B  # <CJK>
0x5731  0x5289  # <CJK>
0x5732  0x65D2  # <CJK>
0x5733  0x67F3  # <CJK>
0x5734  0x69B4  # <CJK>
0x5735  0x6D41  # <CJK>
0x5736  0x6E9C  # <CJK>
0x5737  0x700F  # <CJK>
0x5738  0x7409  # <CJK>
0x5739  0x7460  # <CJK>
0x573A  0x7559  # <CJK>
0x573B  0x7624  # <CJK>
0x573C  0x786B  # <CJK>
0x573D  0x8B2C  # <CJK>
0x573E  0x985E  # <CJK>
0x573F  0x516D  # <CJK>
0x5740  0x622E  # <CJK>
0x5741  0x9678  # <CJK>
0x5742  0x4F96  # <CJK>
0x5743  0x502B  # <CJK>
0x5744  0x5D19  # <CJK>
0x5745  0x6DEA  # <CJK>
0x5746  0x7DB8  # <CJK>
0x5747  0x8F2A  # <CJK>
0x5748  0x5F8B  # <CJK>
0x5749  0x6144  # <CJK>
0x574A  0x6817  # <CJK>
0x574B  0xF961  # <CJK>
0x574C  0x9686  # <CJK>
0x574D  0x52D2  # <CJK>
0x574E  0x808B  # <CJK>
0x574F  0x51DC  # <CJK>
0x5750  0x51CC  # <CJK>
0x5751  0x695E  # <CJK>
0x5752  0x7A1C  # <CJK>
0x5753  0x7DBE  # <CJK>
0x5754  0x83F1  # <CJK>
0x5755  0x9675  # <CJK>
0x5756  0x4FDA  # <CJK>
0x5757  0x5229  # <CJK>
0x5758  0x5398  # <CJK>
0x5759  0x540F  # <CJK>
0x575A  0x550E  # <CJK>
0x575B  0x5C65  # <CJK>
0x575C  0x60A7  # <CJK>
0x575D  0x674E  # <CJK>
0x575E  0x68A8  # <CJK>
0x575F  0x6D6C  # <CJK>
0x5760  0x7281  # <CJK>
0x5761  0x72F8  # <CJK>
0x5762  0x7406  # <CJK>
0x5763  0x7483  # <CJK>
0x5764  0xF962  # <CJK>
0x5765  0x75E2  # <CJK>
0x5766  0x7C6C  # <CJK>
0x5767  0x7F79  # <CJK>
0x5768  0x7FB8  # <CJK>
0x5769  0x8389  # <CJK>
0x576A  0x88CF  # <CJK>
0x576B  0x88E1  # <CJK>
0x576C  0x91CC  # <CJK>
0x576D  0x91D0  # <CJK>
0x576E  0x96E2  # <CJK>
0x576F  0x9BC9  # <CJK>
0x5770  0x541D  # <CJK>
0x5771  0x6F7E  # <CJK>
0x5772  0x71D0  # <CJK>
0x5773  0x7498  # <CJK>
0x5774  0x85FA  # <CJK>
0x5775  0x8EAA  # <CJK>
0x5776  0x96A3  # <CJK>
0x5777  0x9C57  # <CJK>
0x5778  0x9E9F  # <CJK>
0x5779  0x6797  # <CJK>
0x577A  0x6DCB  # <CJK>
0x577B  0x7433  # <CJK>
0x577C  0x81E8  # <CJK>
0x577D  0x9716  # <CJK>
0x577E  0x782C  # <CJK>
0x5821  0x7ACB  # <CJK>
0x5822  0x7B20  # <CJK>
0x5823  0x7C92  # <CJK>
0x5824  0x6469  # <CJK>
0x5825  0x746A  # <CJK>
0x5826  0x75F2  # <CJK>
0x5827  0x78BC  # <CJK>
0x5828  0x78E8  # <CJK>
0x5829  0x99AC  # <CJK>
0x582A  0x9B54  # <CJK>
0x582B  0x9EBB  # <CJK>
0x582C  0x5BDE  # <CJK>
0x582D  0x5E55  # <CJK>
0x582E  0x6F20  # <CJK>
0x582F  0x819C  # <CJK>
0x5830  0x83AB  # <CJK>
0x5831  0x9088  # <CJK>
0x5832  0x4E07  # <CJK>
0x5833  0x534D  # <CJK>
0x5834  0x5A29  # <CJK>
0x5835  0x5DD2  # <CJK>
0x5836  0x5F4E  # <CJK>
0x5837  0x6162  # <CJK>
0x5838  0x633D  # <CJK>
0x5839  0x6669  # <CJK>
0x583A  0x66FC  # <CJK>
0x583B  0x6EFF  # <CJK>
0x583C  0x6F2B  # <CJK>
0x583D  0x7063  # <CJK>
0x583E  0x779E  # <CJK>
0x583F  0x842C  # <CJK>
0x5840  0x8513  # <CJK>
0x5841  0x883B  # <CJK>
0x5842  0x8F13  # <CJK>
0x5843  0x9945  # <CJK>
0x5844  0x9C3B  # <CJK>
0x5845  0x551C  # <CJK>
0x5846  0x62B9  # <CJK>
0x5847  0x672B  # <CJK>
0x5848  0x6CAB  # <CJK>
0x5849  0x8309  # <CJK>
0x584A  0x896A  # <CJK>
0x584B  0x977A  # <CJK>
0x584C  0x4EA1  # <CJK>
0x584D  0x5984  # <CJK>
0x584E  0x5FD8  # <CJK>
0x584F  0x5FD9  # <CJK>
0x5850  0x671B  # <CJK>
0x5851  0x7DB2  # <CJK>
0x5852  0x7F54  # <CJK>
0x5853  0x8292  # <CJK>
0x5854  0x832B  # <CJK>
0x5855  0x83BD  # <CJK>
0x5856  0x8F1E  # <CJK>
0x5857  0x9099  # <CJK>
0x5858  0x57CB  # <CJK>
0x5859  0x59B9  # <CJK>
0x585A  0x5A92  # <CJK>
0x585B  0x5BD0  # <CJK>
0x585C  0x6627  # <CJK>
0x585D  0x679A  # <CJK>
0x585E  0x6885  # <CJK>
0x585F  0x6BCF  # <CJK>
0x5860  0x7164  # <CJK>
0x5861  0x7F75  # <CJK>
0x5862  0x8CB7  # <CJK>
0x5863  0x8CE3  # <CJK>
0x5864  0x9081  # <CJK>
0x5865  0x9B45  # <CJK>
0x5866  0x8108  # <CJK>
0x5867  0x8C8A  # <CJK>
0x5868  0x964C  # <CJK>
0x5869  0x9A40  # <CJK>
0x586A  0x9EA5  # <CJK>
0x586B  0x5B5F  # <CJK>
0x586C  0x6C13  # <CJK>
0x586D  0x731B  # <CJK>
0x586E  0x76F2  # <CJK>
0x586F  0x76DF  # <CJK>
0x5870  0x840C  # <CJK>
0x5871  0x51AA  # <CJK>
0x5872  0x8993  # <CJK>
0x5873  0x514D  # <CJK>
0x5874  0x5195  # <CJK>
0x5875  0x52C9  # <CJK>
0x5876  0x68C9  # <CJK>
0x5877  0x6C94  # <CJK>
0x5878  0x7704  # <CJK>
0x5879  0x7720  # <CJK>
0x587A  0x7DBF  # <CJK>
0x587B  0x7DEC  # <CJK>
0x587C  0x9762  # <CJK>
0x587D  0x9EB5  # <CJK>
0x587E  0x6EC5  # <CJK>
0x5921  0x8511  # <CJK>
0x5922  0x51A5  # <CJK>
0x5923  0x540D  # <CJK>
0x5924  0x547D  # <CJK>
0x5925  0x660E  # <CJK>
0x5926  0x669D  # <CJK>
0x5927  0x6927  # <CJK>
0x5928  0x6E9F  # <CJK>
0x5929  0x76BF  # <CJK>
0x592A  0x7791  # <CJK>
0x592B  0x8317  # <CJK>
0x592C  0x84C2  # <CJK>
0x592D  0x879F  # <CJK>
0x592E  0x9169  # <CJK>
0x592F  0x9298  # <CJK>
0x5930  0x9CF4  # <CJK>
0x5931  0x8882  # <CJK>
0x5932  0x4FAE  # <CJK>
0x5933  0x5192  # <CJK>
0x5934  0x52DF  # <CJK>
0x5935  0x59C6  # <CJK>
0x5936  0x5E3D  # <CJK>
0x5937  0x6155  # <CJK>
0x5938  0x6478  # <CJK>
0x5939  0x6479  # <CJK>
0x593A  0x66AE  # <CJK>
0x593B  0x67D0  # <CJK>
0x593C  0x6A21  # <CJK>
0x593D  0x6BCD  # <CJK>
0x593E  0x6BDB  # <CJK>
0x593F  0x725F  # <CJK>
0x5940  0x7261  # <CJK>
0x5941  0x7441  # <CJK>
0x5942  0x7738  # <CJK>
0x5943  0x77DB  # <CJK>
0x5944  0x8017  # <CJK>
0x5945  0x82BC  # <CJK>
0x5946  0x8305  # <CJK>
0x5947  0x8B00  # <CJK>
0x5948  0x8B28  # <CJK>
0x5949  0x8C8C  # <CJK>
0x594A  0x6728  # <CJK>
0x594B  0x6C90  # <CJK>
0x594C  0x7267  # <CJK>
0x594D  0x76EE  # <CJK>
0x594E  0x7766  # <CJK>
0x594F  0x7A46  # <CJK>
0x5950  0x9DA9  # <CJK>
0x5951  0x6B7F  # <CJK>
0x5952  0x6C92  # <CJK>
0x5953  0x5922  # <CJK>
0x5954  0x6726  # <CJK>
0x5955  0x8499  # <CJK>
0x5956  0x536F  # <CJK>
0x5957  0x5893  # <CJK>
0x5958  0x5999  # <CJK>
0x5959  0x5EDF  # <CJK>
0x595A  0x63CF  # <CJK>
0x595B  0x6634  # <CJK>
0x595C  0x6773  # <CJK>
0x595D  0x6E3A  # <CJK>
0x595E  0x732B  # <CJK>
0x595F  0x7AD7  # <CJK>
0x5960  0x82D7  # <CJK>
0x5961  0x9328  # <CJK>
0x5962  0x52D9  # <CJK>
0x5963  0x5DEB  # <CJK>
0x5964  0x61AE  # <CJK>
0x5965  0x61CB  # <CJK>
0x5966  0x620A  # <CJK>
0x5967  0x62C7  # <CJK>
0x5968  0x64AB  # <CJK>
0x5969  0x65E0  # <CJK>
0x596A  0x6959  # <CJK>
0x596B  0x6B66  # <CJK>
0x596C  0x6BCB  # <CJK>
0x596D  0x7121  # <CJK>
0x596E  0x73F7  # <CJK>
0x596F  0x755D  # <CJK>
0x5970  0x7E46  # <CJK>
0x5971  0x821E  # <CJK>
0x5972  0x8302  # <CJK>
0x5973  0x856A  # <CJK>
0x5974  0x8AA3  # <CJK>
0x5975  0x8CBF  # <CJK>
0x5976  0x9727  # <CJK>
0x5977  0x9D61  # <CJK>
0x5978  0x58A8  # <CJK>
0x5979  0x9ED8  # <CJK>
0x597A  0x5011  # <CJK>
0x597B  0x520E  # <CJK>
0x597C  0x543B  # <CJK>
0x597D  0x554F  # <CJK>
0x597E  0x6587  # <CJK>
0x5A21  0x6C76  # <CJK>
0x5A22  0x7D0A  # <CJK>
0x5A23  0x7D0B  # <CJK>
0x5A24  0x805E  # <CJK>
0x5A25  0x868A  # <CJK>
0x5A26  0x9580  # <CJK>
0x5A27  0x96EF  # <CJK>
0x5A28  0x52FF  # <CJK>
0x5A29  0x6C95  # <CJK>
0x5A2A  0x7269  # <CJK>
0x5A2B  0x5473  # <CJK>
0x5A2C  0x5A9A  # <CJK>
0x5A2D  0x5C3E  # <CJK>
0x5A2E  0x5D4B  # <CJK>
0x5A2F  0x5F4C  # <CJK>
0x5A30  0x5FAE  # <CJK>
0x5A31  0x672A  # <CJK>
0x5A32  0x68B6  # <CJK>
0x5A33  0x6963  # <CJK>
0x5A34  0x6E3C  # <CJK>
0x5A35  0x6E44  # <CJK>
0x5A36  0x7709  # <CJK>
0x5A37  0x7C73  # <CJK>
0x5A38  0x7F8E  # <CJK>
0x5A39  0x8587  # <CJK>
0x5A3A  0x8B0E  # <CJK>
0x5A3B  0x8FF7  # <CJK>
0x5A3C  0x9761  # <CJK>
0x5A3D  0x9EF4  # <CJK>
0x5A3E  0x5CB7  # <CJK>
0x5A3F  0x60B6  # <CJK>
0x5A40  0x610D  # <CJK>
0x5A41  0x61AB  # <CJK>
0x5A42  0x654F  # <CJK>
0x5A43  0x65FB  # <CJK>
0x5A44  0x65FC  # <CJK>
0x5A45  0x6C11  # <CJK>
0x5A46  0x6CEF  # <CJK>
0x5A47  0x739F  # <CJK>
0x5A48  0x73C9  # <CJK>
0x5A49  0x7DE1  # <CJK>
0x5A4A  0x9594  # <CJK>
0x5A4B  0x5BC6  # <CJK>
0x5A4C  0x871C  # <CJK>
0x5A4D  0x8B10  # <CJK>
0x5A4E  0x525D  # <CJK>
0x5A4F  0x535A  # <CJK>
0x5A50  0x62CD  # <CJK>
0x5A51  0x640F  # <CJK>
0x5A52  0x64B2  # <CJK>
0x5A53  0x6734  # <CJK>
0x5A54  0x6A38  # <CJK>
0x5A55  0x6CCA  # <CJK>
0x5A56  0x73C0  # <CJK>
0x5A57  0x749E  # <CJK>
0x5A58  0x7B94  # <CJK>
0x5A59  0x7C95  # <CJK>
0x5A5A  0x7E1B  # <CJK>
0x5A5B  0x818A  # <CJK>
0x5A5C  0x8236  # <CJK>
0x5A5D  0x8584  # <CJK>
0x5A5E  0x8FEB  # <CJK>
0x5A5F  0x96F9  # <CJK>
0x5A60  0x99C1  # <CJK>
0x5A61  0x4F34  # <CJK>
0x5A62  0x534A  # <CJK>
0x5A63  0x53CD  # <CJK>
0x5A64  0x53DB  # <CJK>
0x5A65  0x62CC  # <CJK>
0x5A66  0x642C  # <CJK>
0x5A67  0x6500  # <CJK>
0x5A68  0x6591  # <CJK>
0x5A69  0x69C3  # <CJK>
0x5A6A  0x6CEE  # <CJK>
0x5A6B  0x6F58  # <CJK>
0x5A6C  0x73ED  # <CJK>
0x5A6D  0x7554  # <CJK>
0x5A6E  0x7622  # <CJK>
0x5A6F  0x76E4  # <CJK>
0x5A70  0x76FC  # <CJK>
0x5A71  0x78D0  # <CJK>
0x5A72  0x78FB  # <CJK>
0x5A73  0x792C  # <CJK>
0x5A74  0x7D46  # <CJK>
0x5A75  0x822C  # <CJK>
0x5A76  0x87E0  # <CJK>
0x5A77  0x8FD4  # <CJK>
0x5A78  0x9812  # <CJK>
0x5A79  0x98EF  # <CJK>
0x5A7A  0x52C3  # <CJK>
0x5A7B  0x62D4  # <CJK>
0x5A7C  0x64A5  # <CJK>
0x5A7D  0x6E24  # <CJK>
0x5A7E  0x6F51  # <CJK>
0x5B21  0x767C  # <CJK>
0x5B22  0x8DCB  # <CJK>
0x5B23  0x91B1  # <CJK>
0x5B24  0x9262  # <CJK>
0x5B25  0x9AEE  # <CJK>
0x5B26  0x9B43  # <CJK>
0x5B27  0x5023  # <CJK>
0x5B28  0x508D  # <CJK>
0x5B29  0x574A  # <CJK>
0x5B2A  0x59A8  # <CJK>
0x5B2B  0x5C28  # <CJK>
0x5B2C  0x5E47  # <CJK>
0x5B2D  0x5F77  # <CJK>
0x5B2E  0x623F  # <CJK>
0x5B2F  0x653E  # <CJK>
0x5B30  0x65B9  # <CJK>
0x5B31  0x65C1  # <CJK>
0x5B32  0x6609  # <CJK>
0x5B33  0x678B  # <CJK>
0x5B34  0x699C  # <CJK>
0x5B35  0x6EC2  # <CJK>
0x5B36  0x78C5  # <CJK>
0x5B37  0x7D21  # <CJK>
0x5B38  0x80AA  # <CJK>
0x5B39  0x8180  # <CJK>
0x5B3A  0x822B  # <CJK>
0x5B3B  0x82B3  # <CJK>
0x5B3C  0x84A1  # <CJK>
0x5B3D  0x868C  # <CJK>
0x5B3E  0x8A2A  # <CJK>
0x5B3F  0x8B17  # <CJK>
0x5B40  0x90A6  # <CJK>
0x5B41  0x9632  # <CJK>
0x5B42  0x9F90  # <CJK>
0x5B43  0x500D  # <CJK>
0x5B44  0x4FF3  # <CJK>
0x5B45  0xF963  # <CJK>
0x5B46  0x57F9  # <CJK>
0x5B47  0x5F98  # <CJK>
0x5B48  0x62DC  # <CJK>
0x5B49  0x6392  # <CJK>
0x5B4A  0x676F  # <CJK>
0x5B4B  0x6E43  # <CJK>
0x5B4C  0x7119  # <CJK>
0x5B4D  0x76C3  # <CJK>
0x5B4E  0x80CC  # <CJK>
0x5B4F  0x80DA  # <CJK>
0x5B50  0x88F4  # <CJK>
0x5B51  0x88F5  # <CJK>
0x5B52  0x8919  # <CJK>
0x5B53  0x8CE0  # <CJK>
0x5B54  0x8F29  # <CJK>
0x5B55  0x914D  # <CJK>
0x5B56  0x966A  # <CJK>
0x5B57  0x4F2F  # <CJK>
0x5B58  0x4F70  # <CJK>
0x5B59  0x5E1B  # <CJK>
0x5B5A  0x67CF  # <CJK>
0x5B5B  0x6822  # <CJK>
0x5B5C  0x767D  # <CJK>
0x5B5D  0x767E  # <CJK>
0x5B5E  0x9B44  # <CJK>
0x5B5F  0x5E61  # <CJK>
0x5B60  0x6A0A  # <CJK>
0x5B61  0x7169  # <CJK>
0x5B62  0x71D4  # <CJK>
0x5B63  0x756A  # <CJK>
0x5B64  0xF964  # <CJK>
0x5B65  0x7E41  # <CJK>
0x5B66  0x8543  # <CJK>
0x5B67  0x85E9  # <CJK>
0x5B68  0x98DC  # <CJK>
0x5B69  0x4F10  # <CJK>
0x5B6A  0x7B4F  # <CJK>
0x5B6B  0x7F70  # <CJK>
0x5B6C  0x95A5  # <CJK>
0x5B6D  0x51E1  # <CJK>
0x5B6E  0x5E06  # <CJK>
0x5B6F  0x68B5  # <CJK>
0x5B70  0x6C3E  # <CJK>
0x5B71  0x6C4E  # <CJK>
0x5B72  0x6CDB  # <CJK>
0x5B73  0x72AF  # <CJK>
0x5B74  0x7BC4  # <CJK>
0x5B75  0x8303  # <CJK>
0x5B76  0x6CD5  # <CJK>
0x5B77  0x743A  # <CJK>
0x5B78  0x50FB  # <CJK>
0x5B79  0x5288  # <CJK>
0x5B7A  0x58C1  # <CJK>
0x5B7B  0x64D8  # <CJK>
0x5B7C  0x6A97  # <CJK>
0x5B7D  0x74A7  # <CJK>
0x5B7E  0x7656  # <CJK>
0x5C21  0x78A7  # <CJK>
0x5C22  0x8617  # <CJK>
0x5C23  0x95E2  # <CJK>
0x5C24  0x9739  # <CJK>
0x5C25  0xF965  # <CJK>
0x5C26  0x535E  # <CJK>
0x5C27  0x5F01  # <CJK>
0x5C28  0x8B8A  # <CJK>
0x5C29  0x8FA8  # <CJK>
0x5C2A  0x8FAF  # <CJK>
0x5C2B  0x908A  # <CJK>
0x5C2C  0x5225  # <CJK>
0x5C2D  0x77A5  # <CJK>
0x5C2E  0x9C49  # <CJK>
0x5C2F  0x9F08  # <CJK>
0x5C30  0x4E19  # <CJK>
0x5C31  0x5002  # <CJK>
0x5C32  0x5175  # <CJK>
0x5C33  0x5C5B  # <CJK>
0x5C34  0x5E77  # <CJK>
0x5C35  0x661E  # <CJK>
0x5C36  0x663A  # <CJK>
0x5C37  0x67C4  # <CJK>
0x5C38  0x68C5  # <CJK>
0x5C39  0x70B3  # <CJK>
0x5C3A  0x7501  # <CJK>
0x5C3B  0x75C5  # <CJK>
0x5C3C  0x79C9  # <CJK>
0x5C3D  0x7ADD  # <CJK>
0x5C3E  0x8F27  # <CJK>
0x5C3F  0x9920  # <CJK>
0x5C40  0x9A08  # <CJK>
0x5C41  0x4FDD  # <CJK>
0x5C42  0x5821  # <CJK>
0x5C43  0x5831  # <CJK>
0x5C44  0x5BF6  # <CJK>
0x5C45  0x666E  # <CJK>
0x5C46  0x6B65  # <CJK>
0x5C47  0x6D11  # <CJK>
0x5C48  0x6E7A  # <CJK>
0x5C49  0x6F7D  # <CJK>
0x5C4A  0x73E4  # <CJK>
0x5C4B  0x752B  # <CJK>
0x5C4C  0x83E9  # <CJK>
0x5C4D  0x88DC  # <CJK>
0x5C4E  0x8913  # <CJK>
0x5C4F  0x8B5C  # <CJK>
0x5C50  0x8F14  # <CJK>
0x5C51  0x4F0F  # <CJK>
0x5C52  0x50D5  # <CJK>
0x5C53  0x5310  # <CJK>
0x5C54  0x535C  # <CJK>
0x5C55  0x5B93  # <CJK>
0x5C56  0x5FA9  # <CJK>
0x5C57  0x670D  # <CJK>
0x5C58  0x798F  # <CJK>
0x5C59  0x8179  # <CJK>
0x5C5A  0x832F  # <CJK>
0x5C5B  0x8514  # <CJK>
0x5C5C  0x8907  # <CJK>
0x5C5D  0x8986  # <CJK>
0x5C5E  0x8F39  # <CJK>
0x5C5F  0x8F3B  # <CJK>
0x5C60  0x99A5  # <CJK>
0x5C61  0x9C12  # <CJK>
0x5C62  0x672C  # <CJK>
0x5C63  0x4E76  # <CJK>
0x5C64  0x4FF8  # <CJK>
0x5C65  0x5949  # <CJK>
0x5C66  0x5C01  # <CJK>
0x5C67  0x5CEF  # <CJK>
0x5C68  0x5CF0  # <CJK>
0x5C69  0x6367  # <CJK>
0x5C6A  0x68D2  # <CJK>
0x5C6B  0x70FD  # <CJK>
0x5C6C  0x71A2  # <CJK>
0x5C6D  0x742B  # <CJK>
0x5C6E  0x7E2B  # <CJK>
0x5C6F  0x84EC  # <CJK>
0x5C70  0x8702  # <CJK>
0x5C71  0x9022  # <CJK>
0x5C72  0x92D2  # <CJK>
0x5C73  0x9CF3  # <CJK>
0x5C74  0x4E0D  # <CJK>
0x5C75  0x4ED8  # <CJK>
0x5C76  0x4FEF  # <CJK>
0x5C77  0x5085  # <CJK>
0x5C78  0x5256  # <CJK>
0x5C79  0x526F  # <CJK>
0x5C7A  0x5426  # <CJK>
0x5C7B  0x5490  # <CJK>
0x5C7C  0x57E0  # <CJK>
0x5C7D  0x592B  # <CJK>
0x5C7E  0x5A66  # <CJK>
0x5D21  0x5B5A  # <CJK>
0x5D22  0x5B75  # <CJK>
0x5D23  0x5BCC  # <CJK>
0x5D24  0x5E9C  # <CJK>
0x5D25  0xF966  # <CJK>
0x5D26  0x6276  # <CJK>
0x5D27  0x6577  # <CJK>
0x5D28  0x65A7  # <CJK>
0x5D29  0x6D6E  # <CJK>
0x5D2A  0x6EA5  # <CJK>
0x5D2B  0x7236  # <CJK>
0x5D2C  0x7B26  # <CJK>
0x5D2D  0x7C3F  # <CJK>
0x5D2E  0x7F36  # <CJK>
0x5D2F  0x8150  # <CJK>
0x5D30  0x8151  # <CJK>
0x5D31  0x819A  # <CJK>
0x5D32  0x8240  # <CJK>
0x5D33  0x8299  # <CJK>
0x5D34  0x83A9  # <CJK>
0x5D35  0x8A03  # <CJK>
0x5D36  0x8CA0  # <CJK>
0x5D37  0x8CE6  # <CJK>
0x5D38  0x8CFB  # <CJK>
0x5D39  0x8D74  # <CJK>
0x5D3A  0x8DBA  # <CJK>
0x5D3B  0x90E8  # <CJK>
0x5D3C  0x91DC  # <CJK>
0x5D3D  0x961C  # <CJK>
0x5D3E  0x9644  # <CJK>
0x5D3F  0x99D9  # <CJK>
0x5D40  0x9CE7  # <CJK>
0x5D41  0x5317  # <CJK>
0x5D42  0x5206  # <CJK>
0x5D43  0x5429  # <CJK>
0x5D44  0x5674  # <CJK>
0x5D45  0x58B3  # <CJK>
0x5D46  0x5954  # <CJK>
0x5D47  0x596E  # <CJK>
0x5D48  0x5FFF  # <CJK>
0x5D49  0x61A4  # <CJK>
0x5D4A  0x626E  # <CJK>
0x5D4B  0x6610  # <CJK>
0x5D4C  0x6C7E  # <CJK>
0x5D4D  0x711A  # <CJK>
0x5D4E  0x76C6  # <CJK>
0x5D4F  0x7C89  # <CJK>
0x5D50  0x7CDE  # <CJK>
0x5D51  0x7D1B  # <CJK>
0x5D52  0x82AC  # <CJK>
0x5D53  0x8CC1  # <CJK>
0x5D54  0x96F0  # <CJK>
0x5D55  0xF967  # <CJK>
0x5D56  0x4F5B  # <CJK>
0x5D57  0x5F17  # <CJK>
0x5D58  0x5F7F  # <CJK>
0x5D59  0x62C2  # <CJK>
0x5D5A  0x5D29  # <CJK>
0x5D5B  0x670B  # <CJK>
0x5D5C  0x68DA  # <CJK>
0x5D5D  0x787C  # <CJK>
0x5D5E  0x7E43  # <CJK>
0x5D5F  0x9D6C  # <CJK>
0x5D60  0x4E15  # <CJK>
0x5D61  0x5099  # <CJK>
0x5D62  0x5315  # <CJK>
0x5D63  0x532A  # <CJK>
0x5D64  0x5351  # <CJK>
0x5D65  0x5983  # <CJK>
0x5D66  0x5A62  # <CJK>
0x5D67  0x5E87  # <CJK>
0x5D68  0x60B2  # <CJK>
0x5D69  0x618A  # <CJK>
0x5D6A  0x6249  # <CJK>
0x5D6B  0x6279  # <CJK>
0x5D6C  0x6590  # <CJK>
0x5D6D  0x6787  # <CJK>
0x5D6E  0x69A7  # <CJK>
0x5D6F  0x6BD4  # <CJK>
0x5D70  0x6BD6  # <CJK>
0x5D71  0x6BD7  # <CJK>
0x5D72  0x6BD8  # <CJK>
0x5D73  0x6CB8  # <CJK>
0x5D74  0xF968  # <CJK>
0x5D75  0x7435  # <CJK>
0x5D76  0x75FA  # <CJK>
0x5D77  0x7812  # <CJK>
0x5D78  0x7891  # <CJK>
0x5D79  0x79D5  # <CJK>
0x5D7A  0x79D8  # <CJK>
0x5D7B  0x7C83  # <CJK>
0x5D7C  0x7DCB  # <CJK>
0x5D7D  0x7FE1  # <CJK>
0x5D7E  0x80A5  # <CJK>
0x5E21  0x813E  # <CJK>
0x5E22  0x81C2  # <CJK>
0x5E23  0x83F2  # <CJK>
0x5E24  0x871A  # <CJK>
0x5E25  0x88E8  # <CJK>
0x5E26  0x8AB9  # <CJK>
0x5E27  0x8B6C  # <CJK>
0x5E28  0x8CBB  # <CJK>
0x5E29  0x9119  # <CJK>
0x5E2A  0x975E  # <CJK>
0x5E2B  0x98DB  # <CJK>
0x5E2C  0x9F3B  # <CJK>
0x5E2D  0x56AC  # <CJK>
0x5E2E  0x5B2A  # <CJK>
0x5E2F  0x5F6C  # <CJK>
0x5E30  0x658C  # <CJK>
0x5E31  0x6AB3  # <CJK>
0x5E32  0x6BAF  # <CJK>
0x5E33  0x6D5C  # <CJK>
0x5E34  0x6FF1  # <CJK>
0x5E35  0x7015  # <CJK>
0x5E36  0x725D  # <CJK>
0x5E37  0x73AD  # <CJK>
0x5E38  0x8CA7  # <CJK>
0x5E39  0x8CD3  # <CJK>
0x5E3A  0x983B  # <CJK>
0x5E3B  0x6191  # <CJK>
0x5E3C  0x6C37  # <CJK>
0x5E3D  0x8058  # <CJK>
0x5E3E  0x9A01  # <CJK>
0x5E3F  0x4E4D  # <CJK>
0x5E40  0x4E8B  # <CJK>
0x5E41  0x4E9B  # <CJK>
0x5E42  0x4ED5  # <CJK>
0x5E43  0x4F3A  # <CJK>
0x5E44  0x4F3C  # <CJK>
0x5E45  0x4F7F  # <CJK>
0x5E46  0x4FDF  # <CJK>
0x5E47  0x50FF  # <CJK>
0x5E48  0x53F2  # <CJK>
0x5E49  0x53F8  # <CJK>
0x5E4A  0x5506  # <CJK>
0x5E4B  0x55E3  # <CJK>
0x5E4C  0x56DB  # <CJK>
0x5E4D  0x58EB  # <CJK>
0x5E4E  0x5962  # <CJK>
0x5E4F  0x5A11  # <CJK>
0x5E50  0x5BEB  # <CJK>
0x5E51  0x5BFA  # <CJK>
0x5E52  0x5C04  # <CJK>
0x5E53  0x5DF3  # <CJK>
0x5E54  0x5E2B  # <CJK>
0x5E55  0x5F99  # <CJK>
0x5E56  0x601D  # <CJK>
0x5E57  0x6368  # <CJK>
0x5E58  0x659C  # <CJK>
0x5E59  0x65AF  # <CJK>
0x5E5A  0x67F6  # <CJK>
0x5E5B  0x67FB  # <CJK>
0x5E5C  0x68AD  # <CJK>
0x5E5D  0x6B7B  # <CJK>
0x5E5E  0x6C99  # <CJK>
0x5E5F  0x6CD7  # <CJK>
0x5E60  0x6E23  # <CJK>
0x5E61  0x7009  # <CJK>
0x5E62  0x7345  # <CJK>
0x5E63  0x7802  # <CJK>
0x5E64  0x793E  # <CJK>
0x5E65  0x7940  # <CJK>
0x5E66  0x7960  # <CJK>
0x5E67  0x79C1  # <CJK>
0x5E68  0x7BE9  # <CJK>
0x5E69  0x7D17  # <CJK>
0x5E6A  0x7D72  # <CJK>
0x5E6B  0x8086  # <CJK>
0x5E6C  0x820D  # <CJK>
0x5E6D  0x838E  # <CJK>
0x5E6E  0x84D1  # <CJK>
0x5E6F  0x86C7  # <CJK>
0x5E70  0x88DF  # <CJK>
0x5E71  0x8A50  # <CJK>
0x5E72  0x8A5E  # <CJK>
0x5E73  0x8B1D  # <CJK>
0x5E74  0x8CDC  # <CJK>
0x5E75  0x8D66  # <CJK>
0x5E76  0x8FAD  # <CJK>
0x5E77  0x90AA  # <CJK>
0x5E78  0x98FC  # <CJK>
0x5E79  0x99DF  # <CJK>
0x5E7A  0x9E9D  # <CJK>
0x5E7B  0x524A  # <CJK>
0x5E7C  0xF969  # <CJK>
0x5E7D  0x6714  # <CJK>
0x5E7E  0xF96A  # <CJK>
0x5F21  0x5098  # <CJK>
0x5F22  0x522A  # <CJK>
0x5F23  0x5C71  # <CJK>
0x5F24  0x6563  # <CJK>
0x5F25  0x6C55  # <CJK>
0x5F26  0x73CA  # <CJK>
0x5F27  0x7523  # <CJK>
0x5F28  0x759D  # <CJK>
0x5F29  0x7B97  # <CJK>
0x5F2A  0x849C  # <CJK>
0x5F2B  0x9178  # <CJK>
0x5F2C  0x9730  # <CJK>
0x5F2D  0x4E77  # <CJK>
0x5F2E  0x6492  # <CJK>
0x5F2F  0x6BBA  # <CJK>
0x5F30  0x715E  # <CJK>
0x5F31  0x85A9  # <CJK>
0x5F32  0x4E09  # <CJK>
0x5F33  0xF96B  # <CJK>
0x5F34  0x6749  # <CJK>
0x5F35  0x68EE  # <CJK>
0x5F36  0x6E17  # <CJK>
0x5F37  0x829F  # <CJK>
0x5F38  0x8518  # <CJK>
0x5F39  0x886B  # <CJK>
0x5F3A  0x63F7  # <CJK>
0x5F3B  0x6F81  # <CJK>
0x5F3C  0x9212  # <CJK>
0x5F3D  0x98AF  # <CJK>
0x5F3E  0x4E0A  # <CJK>
0x5F3F  0x50B7  # <CJK>
0x5F40  0x50CF  # <CJK>
0x5F41  0x511F  # <CJK>
0x5F42  0x5546  # <CJK>
0x5F43  0x55AA  # <CJK>
0x5F44  0x5617  # <CJK>
0x5F45  0x5B40  # <CJK>
0x5F46  0x5C19  # <CJK>
0x5F47  0x5CE0  # <CJK>
0x5F48  0x5E38  # <CJK>
0x5F49  0x5E8A  # <CJK>
0x5F4A  0x5EA0  # <CJK>
0x5F4B  0x5EC2  # <CJK>
0x5F4C  0x60F3  # <CJK>
0x5F4D  0x6851  # <CJK>
0x5F4E  0x6A61  # <CJK>
0x5F4F  0x6E58  # <CJK>
0x5F50  0x723D  # <CJK>
0x5F51  0x7240  # <CJK>
0x5F52  0x72C0  # <CJK>
0x5F53  0x76F8  # <CJK>
0x5F54  0x7965  # <CJK>
0x5F55  0x7BB1  # <CJK>
0x5F56  0x7FD4  # <CJK>
0x5F57  0x88F3  # <CJK>
0x5F58  0x89F4  # <CJK>
0x5F59  0x8A73  # <CJK>
0x5F5A  0x8C61  # <CJK>
0x5F5B  0x8CDE  # <CJK>
0x5F5C  0x971C  # <CJK>
0x5F5D  0x585E  # <CJK>
0x5F5E  0x74BD  # <CJK>
0x5F5F  0x8CFD  # <CJK>
0x5F60  0x55C7  # <CJK>
0x5F61  0xF96C  # <CJK>
0x5F62  0x7A61  # <CJK>
0x5F63  0x7D22  # <CJK>
0x5F64  0x8272  # <CJK>
0x5F65  0x7272  # <CJK>
0x5F66  0x751F  # <CJK>
0x5F67  0x7525  # <CJK>
0x5F68  0xF96D  # <CJK>
0x5F69  0x7B19  # <CJK>
0x5F6A  0x5885  # <CJK>
0x5F6B  0x58FB  # <CJK>
0x5F6C  0x5DBC  # <CJK>
0x5F6D  0x5E8F  # <CJK>
0x5F6E  0x5EB6  # <CJK>
0x5F6F  0x5F90  # <CJK>
0x5F70  0x6055  # <CJK>
0x5F71  0x6292  # <CJK>
0x5F72  0x637F  # <CJK>
0x5F73  0x654D  # <CJK>
0x5F74  0x6691  # <CJK>
0x5F75  0x66D9  # <CJK>
0x5F76  0x66F8  # <CJK>
0x5F77  0x6816  # <CJK>
0x5F78  0x68F2  # <CJK>
0x5F79  0x7280  # <CJK>
0x5F7A  0x745E  # <CJK>
0x5F7B  0x7B6E  # <CJK>
0x5F7C  0x7D6E  # <CJK>
0x5F7D  0x7DD6  # <CJK>
0x5F7E  0x7F72  # <CJK>
0x6021  0x80E5  # <CJK>
0x6022  0x8212  # <CJK>
0x6023  0x85AF  # <CJK>
0x6024  0x897F  # <CJK>
0x6025  0x8A93  # <CJK>
0x6026  0x901D  # <CJK>
0x6027  0x92E4  # <CJK>
0x6028  0x9ECD  # <CJK>
0x6029  0x9F20  # <CJK>
0x602A  0x5915  # <CJK>
0x602B  0x596D  # <CJK>
0x602C  0x5E2D  # <CJK>
0x602D  0x60DC  # <CJK>
0x602E  0x6614  # <CJK>
0x602F  0x6673  # <CJK>
0x6030  0x6790  # <CJK>
0x6031  0x6C50  # <CJK>
0x6032  0x6DC5  # <CJK>
0x6033  0x6F5F  # <CJK>
0x6034  0x77F3  # <CJK>
0x6035  0x78A9  # <CJK>
0x6036  0x84C6  # <CJK>
0x6037  0x91CB  # <CJK>
0x6038  0x932B  # <CJK>
0x6039  0x4ED9  # <CJK>
0x603A  0x50CA  # <CJK>
0x603B  0x5148  # <CJK>
0x603C  0x5584  # <CJK>
0x603D  0x5B0B  # <CJK>
0x603E  0x5BA3  # <CJK>
0x603F  0x6247  # <CJK>
0x6040  0x657E  # <CJK>
0x6041  0x65CB  # <CJK>
0x6042  0x6E32  # <CJK>
0x6043  0x717D  # <CJK>
0x6044  0x7401  # <CJK>
0x6045  0x7444  # <CJK>
0x6046  0x7487  # <CJK>
0x6047  0x74BF  # <CJK>
0x6048  0x766C  # <CJK>
0x6049  0x79AA  # <CJK>
0x604A  0x7DDA  # <CJK>
0x604B  0x7E55  # <CJK>
0x604C  0x7FA8  # <CJK>
0x604D  0x817A  # <CJK>
0x604E  0x81B3  # <CJK>
0x604F  0x8239  # <CJK>
0x6050  0x861A  # <CJK>
0x6051  0x87EC  # <CJK>
0x6052  0x8A75  # <CJK>
0x6053  0x8DE3  # <CJK>
0x6054  0x9078  # <CJK>
0x6055  0x9291  # <CJK>
0x6056  0x9425  # <CJK>
0x6057  0x994D  # <CJK>
0x6058  0x9BAE  # <CJK>
0x6059  0x5368  # <CJK>
0x605A  0x5C51  # <CJK>
0x605B  0x6954  # <CJK>
0x605C  0x6CC4  # <CJK>
0x605D  0x6D29  # <CJK>
0x605E  0x6E2B  # <CJK>
0x605F  0x820C  # <CJK>
0x6060  0x859B  # <CJK>
0x6061  0x893B  # <CJK>
0x6062  0x8A2D  # <CJK>
0x6063  0x8AAA  # <CJK>
0x6064  0x96EA  # <CJK>
0x6065  0x9F67  # <CJK>
0x6066  0x5261  # <CJK>
0x6067  0x66B9  # <CJK>
0x6068  0x6BB2  # <CJK>
0x6069  0x7E96  # <CJK>
0x606A  0x87FE  # <CJK>
0x606B  0x8D0D  # <CJK>
0x606C  0x9583  # <CJK>
0x606D  0x965D  # <CJK>
0x606E  0x651D  # <CJK>
0x606F  0x6D89  # <CJK>
0x6070  0x71EE  # <CJK>
0x6071  0xF96E  # <CJK>
0x6072  0x57CE  # <CJK>
0x6073  0x59D3  # <CJK>
0x6074  0x5BAC  # <CJK>
0x6075  0x6027  # <CJK>
0x6076  0x60FA  # <CJK>
0x6077  0x6210  # <CJK>
0x6078  0x661F  # <CJK>
0x6079  0x665F  # <CJK>
0x607A  0x7329  # <CJK>
0x607B  0x73F9  # <CJK>
0x607C  0x76DB  # <CJK>
0x607D  0x7701  # <CJK>
0x607E  0x7B6C  # <CJK>
0x6121  0x8056  # <CJK>
0x6122  0x8072  # <CJK>
0x6123  0x8165  # <CJK>
0x6124  0x8AA0  # <CJK>
0x6125  0x9192  # <CJK>
0x6126  0x4E16  # <CJK>
0x6127  0x52E2  # <CJK>
0x6128  0x6B72  # <CJK>
0x6129  0x6D17  # <CJK>
0x612A  0x7A05  # <CJK>
0x612B  0x7B39  # <CJK>
0x612C  0x7D30  # <CJK>
0x612D  0xF96F  # <CJK>
0x612E  0x8CB0  # <CJK>
0x612F  0x53EC  # <CJK>
0x6130  0x562F  # <CJK>
0x6131  0x5851  # <CJK>
0x6132  0x5BB5  # <CJK>
0x6133  0x5C0F  # <CJK>
0x6134  0x5C11  # <CJK>
0x6135  0x5DE2  # <CJK>
0x6136  0x6240  # <CJK>
0x6137  0x6383  # <CJK>
0x6138  0x6414  # <CJK>
0x6139  0x662D  # <CJK>
0x613A  0x68B3  # <CJK>
0x613B  0x6CBC  # <CJK>
0x613C  0x6D88  # <CJK>
0x613D  0x6EAF  # <CJK>
0x613E  0x701F  # <CJK>
0x613F  0x70A4  # <CJK>
0x6140  0x71D2  # <CJK>
0x6141  0x7526  # <CJK>
0x6142  0x758F  # <CJK>
0x6143  0x758E  # <CJK>
0x6144  0x7619  # <CJK>
0x6145  0x7B11  # <CJK>
0x6146  0x7BE0  # <CJK>
0x6147  0x7C2B  # <CJK>
0x6148  0x7D20  # <CJK>
0x6149  0x7D39  # <CJK>
0x614A  0x852C  # <CJK>
0x614B  0x856D  # <CJK>
0x614C  0x8607  # <CJK>
0x614D  0x8A34  # <CJK>
0x614E  0x900D  # <CJK>
0x614F  0x9061  # <CJK>
0x6150  0x90B5  # <CJK>
0x6151  0x92B7  # <CJK>
0x6152  0x97F6  # <CJK>
0x6153  0x9A37  # <CJK>
0x6154  0x4FD7  # <CJK>
0x6155  0x5C6C  # <CJK>
0x6156  0x675F  # <CJK>
0x6157  0x6D91  # <CJK>
0x6158  0x7C9F  # <CJK>
0x6159  0x7E8C  # <CJK>
0x615A  0x8B16  # <CJK>
0x615B  0x8D16  # <CJK>
0x615C  0x901F  # <CJK>
0x615D  0x5B6B  # <CJK>
0x615E  0x5DFD  # <CJK>
0x615F  0x640D  # <CJK>
0x6160  0x84C0  # <CJK>
0x6161  0x905C  # <CJK>
0x6162  0x98E1  # <CJK>
0x6163  0x7387  # <CJK>
0x6164  0x5B8B  # <CJK>
0x6165  0x609A  # <CJK>
0x6166  0x677E  # <CJK>
0x6167  0x6DDE  # <CJK>
0x6168  0x8A1F  # <CJK>
0x6169  0x8AA6  # <CJK>
0x616A  0x9001  # <CJK>
0x616B  0x980C  # <CJK>
0x616C  0x5237  # <CJK>
0x616D  0xF970  # <CJK>
0x616E  0x7051  # <CJK>
0x616F  0x788E  # <CJK>
0x6170  0x9396  # <CJK>
0x6171  0x8870  # <CJK>
0x6172  0x91D7  # <CJK>
0x6173  0x4FEE  # <CJK>
0x6174  0x53D7  # <CJK>
0x6175  0x55FD  # <CJK>
0x6176  0x56DA  # <CJK>
0x6177  0x5782  # <CJK>
0x6178  0x58FD  # <CJK>
0x6179  0x5AC2  # <CJK>
0x617A  0x5B88  # <CJK>
0x617B  0x5CAB  # <CJK>
0x617C  0x5CC0  # <CJK>
0x617D  0x5E25  # <CJK>
0x617E  0x6101  # <CJK>
0x6221  0x620D  # <CJK>
0x6222  0x624B  # <CJK>
0x6223  0x6388  # <CJK>
0x6224  0x641C  # <CJK>
0x6225  0x6536  # <CJK>
0x6226  0x6578  # <CJK>
0x6227  0x6A39  # <CJK>
0x6228  0x6B8A  # <CJK>
0x6229  0x6C34  # <CJK>
0x622A  0x6D19  # <CJK>
0x622B  0x6F31  # <CJK>
0x622C  0x71E7  # <CJK>
0x622D  0x72E9  # <CJK>
0x622E  0x7378  # <CJK>
0x622F  0x7407  # <CJK>
0x6230  0x74B2  # <CJK>
0x6231  0x7626  # <CJK>
0x6232  0x7761  # <CJK>
0x6233  0x79C0  # <CJK>
0x6234  0x7A57  # <CJK>
0x6235  0x7AEA  # <CJK>
0x6236  0x7CB9  # <CJK>
0x6237  0x7D8F  # <CJK>
0x6238  0x7DAC  # <CJK>
0x6239  0x7E61  # <CJK>
0x623A  0x7F9E  # <CJK>
0x623B  0x8129  # <CJK>
0x623C  0x8331  # <CJK>
0x623D  0x8490  # <CJK>
0x623E  0x84DA  # <CJK>
0x623F  0x85EA  # <CJK>
0x6240  0x8896  # <CJK>
0x6241  0x8AB0  # <CJK>
0x6242  0x8B90  # <CJK>
0x6243  0x8F38  # <CJK>
0x6244  0x9042  # <CJK>
0x6245  0x9083  # <CJK>
0x6246  0x916C  # <CJK>
0x6247  0x9296  # <CJK>
0x6248  0x92B9  # <CJK>
0x6249  0x968B  # <CJK>
0x624A  0x96A7  # <CJK>
0x624B  0x96A8  # <CJK>
0x624C  0x96D6  # <CJK>
0x624D  0x9700  # <CJK>
0x624E  0x9808  # <CJK>
0x624F  0x9996  # <CJK>
0x6250  0x9AD3  # <CJK>
0x6251  0x9B1A  # <CJK>
0x6252  0x53D4  # <CJK>
0x6253  0x587E  # <CJK>
0x6254  0x5919  # <CJK>
0x6255  0x5B70  # <CJK>
0x6256  0x5BBF  # <CJK>
0x6257  0x6DD1  # <CJK>
0x6258  0x6F5A  # <CJK>
0x6259  0x719F  # <CJK>
0x625A  0x7421  # <CJK>
0x625B  0x74B9  # <CJK>
0x625C  0x8085  # <CJK>
0x625D  0x83FD  # <CJK>
0x625E  0x5DE1  # <CJK>
0x625F  0x5F87  # <CJK>
0x6260  0x5FAA  # <CJK>
0x6261  0x6042  # <CJK>
0x6262  0x65EC  # <CJK>
0x6263  0x6812  # <CJK>
0x6264  0x696F  # <CJK>
0x6265  0x6A53  # <CJK>
0x6266  0x6B89  # <CJK>
0x6267  0x6D35  # <CJK>
0x6268  0x6DF3  # <CJK>
0x6269  0x73E3  # <CJK>
0x626A  0x76FE  # <CJK>
0x626B  0x77AC  # <CJK>
0x626C  0x7B4D  # <CJK>
0x626D  0x7D14  # <CJK>
0x626E  0x8123  # <CJK>
0x626F  0x821C  # <CJK>
0x6270  0x8340  # <CJK>
0x6271  0x84F4  # <CJK>
0x6272  0x8563  # <CJK>
0x6273  0x8A62  # <CJK>
0x6274  0x8AC4  # <CJK>
0x6275  0x9187  # <CJK>
0x6276  0x931E  # <CJK>
0x6277  0x9806  # <CJK>
0x6278  0x99B4  # <CJK>
0x6279  0x620C  # <CJK>
0x627A  0x8853  # <CJK>
0x627B  0x8FF0  # <CJK>
0x627C  0x9265  # <CJK>
0x627D  0x5D07  # <CJK>
0x627E  0x5D27  # <CJK>
0x6321  0x5D69  # <CJK>
0x6322  0x745F  # <CJK>
0x6323  0x819D  # <CJK>
0x6324  0x8768  # <CJK>
0x6325  0x6FD5  # <CJK>
0x6326  0x62FE  # <CJK>
0x6327  0x7FD2  # <CJK>
0x6328  0x8936  # <CJK>
0x6329  0x8972  # <CJK>
0x632A  0x4E1E  # <CJK>
0x632B  0x4E58  # <CJK>
0x632C  0x50E7  # <CJK>
0x632D  0x52DD  # <CJK>
0x632E  0x5347  # <CJK>
0x632F  0x627F  # <CJK>
0x6330  0x6607  # <CJK>
0x6331  0x7E69  # <CJK>
0x6332  0x8805  # <CJK>
0x6333  0x965E  # <CJK>
0x6334  0x4F8D  # <CJK>
0x6335  0x5319  # <CJK>
0x6336  0x5636  # <CJK>
0x6337  0x59CB  # <CJK>
0x6338  0x5AA4  # <CJK>
0x6339  0x5C38  # <CJK>
0x633A  0x5C4E  # <CJK>
0x633B  0x5C4D  # <CJK>
0x633C  0x5E02  # <CJK>
0x633D  0x5F11  # <CJK>
0x633E  0x6043  # <CJK>
0x633F  0x65BD  # <CJK>
0x6340  0x662F  # <CJK>
0x6341  0x6642  # <CJK>
0x6342  0x67BE  # <CJK>
0x6343  0x67F4  # <CJK>
0x6344  0x731C  # <CJK>
0x6345  0x77E2  # <CJK>
0x6346  0x793A  # <CJK>
0x6347  0x7FC5  # <CJK>
0x6348  0x8494  # <CJK>
0x6349  0x84CD  # <CJK>
0x634A  0x8996  # <CJK>
0x634B  0x8A66  # <CJK>
0x634C  0x8A69  # <CJK>
0x634D  0x8AE1  # <CJK>
0x634E  0x8C55  # <CJK>
0x634F  0x8C7A  # <CJK>
0x6350  0x57F4  # <CJK>
0x6351  0x5BD4  # <CJK>
0x6352  0x5F0F  # <CJK>
0x6353  0x606F  # <CJK>
0x6354  0x62ED  # <CJK>
0x6355  0x690D  # <CJK>
0x6356  0x6B96  # <CJK>
0x6357  0x6E5C  # <CJK>
0x6358  0x7184  # <CJK>
0x6359  0x7BD2  # <CJK>
0x635A  0x8755  # <CJK>
0x635B  0x8B58  # <CJK>
0x635C  0x8EFE  # <CJK>
0x635D  0x98DF  # <CJK>
0x635E  0x98FE  # <CJK>
0x635F  0x4F38  # <CJK>
0x6360  0x4F81  # <CJK>
0x6361  0x4FE1  # <CJK>
0x6362  0x547B  # <CJK>
0x6363  0x5A20  # <CJK>
0x6364  0x5BB8  # <CJK>
0x6365  0x613C  # <CJK>
0x6366  0x65B0  # <CJK>
0x6367  0x6668  # <CJK>
0x6368  0x71FC  # <CJK>
0x6369  0x7533  # <CJK>
0x636A  0x795E  # <CJK>
0x636B  0x7D33  # <CJK>
0x636C  0x814E  # <CJK>
0x636D  0x81E3  # <CJK>
0x636E  0x8398  # <CJK>
0x636F  0x85AA  # <CJK>
0x6370  0x85CE  # <CJK>
0x6371  0x8703  # <CJK>
0x6372  0x8A0A  # <CJK>
0x6373  0x8EAB  # <CJK>
0x6374  0x8F9B  # <CJK>
0x6375  0xF971  # <CJK>
0x6376  0x8FC5  # <CJK>
0x6377  0x5931  # <CJK>
0x6378  0x5BA4  # <CJK>
0x6379  0x5BE6  # <CJK>
0x637A  0x6089  # <CJK>
0x637B  0x5BE9  # <CJK>
0x637C  0x5C0B  # <CJK>
0x637D  0x5FC3  # <CJK>
0x637E  0x6C81  # <CJK>
0x6421  0xF972  # <CJK>
0x6422  0x6DF1  # <CJK>
0x6423  0x700B  # <CJK>
0x6424  0x751A  # <CJK>
0x6425  0x82AF  # <CJK>
0x6426  0x8AF6  # <CJK>
0x6427  0x4EC0  # <CJK>
0x6428  0x5341  # <CJK>
0x6429  0xF973  # <CJK>
0x642A  0x96D9  # <CJK>
0x642B  0x6C0F  # <CJK>
0x642C  0x4E9E  # <CJK>
0x642D  0x4FC4  # <CJK>
0x642E  0x5152  # <CJK>
0x642F  0x555E  # <CJK>
0x6430  0x5A25  # <CJK>
0x6431  0x5CE8  # <CJK>
0x6432  0x6211  # <CJK>
0x6433  0x7259  # <CJK>
0x6434  0x82BD  # <CJK>
0x6435  0x83AA  # <CJK>
0x6436  0x86FE  # <CJK>
0x6437  0x8859  # <CJK>
0x6438  0x8A1D  # <CJK>
0x6439  0x963F  # <CJK>
0x643A  0x96C5  # <CJK>
0x643B  0x9913  # <CJK>
0x643C  0x9D09  # <CJK>
0x643D  0x9D5D  # <CJK>
0x643E  0x580A  # <CJK>
0x643F  0x5CB3  # <CJK>
0x6440  0x5DBD  # <CJK>
0x6441  0x5E44  # <CJK>
0x6442  0x60E1  # <CJK>
0x6443  0x6115  # <CJK>
0x6444  0x63E1  # <CJK>
0x6445  0x6A02  # <CJK>
0x6446  0x6E25  # <CJK>
0x6447  0x9102  # <CJK>
0x6448  0x9354  # <CJK>
0x6449  0x984E  # <CJK>
0x644A  0x9C10  # <CJK>
0x644B  0x9F77  # <CJK>
0x644C  0x5B89  # <CJK>
0x644D  0x5CB8  # <CJK>
0x644E  0x6309  # <CJK>
0x644F  0x664F  # <CJK>
0x6450  0x6848  # <CJK>
0x6451  0x773C  # <CJK>
0x6452  0x96C1  # <CJK>
0x6453  0x978D  # <CJK>
0x6454  0x9854  # <CJK>
0x6455  0x9B9F  # <CJK>
0x6456  0x65A1  # <CJK>
0x6457  0x8B01  # <CJK>
0x6458  0x8ECB  # <CJK>
0x6459  0x95BC  # <CJK>
0x645A  0x5535  # <CJK>
0x645B  0x5CA9  # <CJK>
0x645C  0x5DD6  # <CJK>
0x645D  0x5EB5  # <CJK>
0x645E  0x6697  # <CJK>
0x645F  0x764C  # <CJK>
0x6460  0x83F4  # <CJK>
0x6461  0x95C7  # <CJK>
0x6462  0x58D3  # <CJK>
0x6463  0x62BC  # <CJK>
0x6464  0x72CE  # <CJK>
0x6465  0x9D28  # <CJK>
0x6466  0x4EF0  # <CJK>
0x6467  0x592E  # <CJK>
0x6468  0x600F  # <CJK>
0x6469  0x663B  # <CJK>
0x646A  0x6B83  # <CJK>
0x646B  0x79E7  # <CJK>
0x646C  0x9D26  # <CJK>
0x646D  0x5393  # <CJK>
0x646E  0x54C0  # <CJK>
0x646F  0x57C3  # <CJK>
0x6470  0x5D16  # <CJK>
0x6471  0x611B  # <CJK>
0x6472  0x66D6  # <CJK>
0x6473  0x6DAF  # <CJK>
0x6474  0x788D  # <CJK>
0x6475  0x827E  # <CJK>
0x6476  0x9698  # <CJK>
0x6477  0x9744  # <CJK>
0x6478  0x5384  # <CJK>
0x6479  0x627C  # <CJK>
0x647A  0x6396  # <CJK>
0x647B  0x6DB2  # <CJK>
0x647C  0x7E0A  # <CJK>
0x647D  0x814B  # <CJK>
0x647E  0x984D  # <CJK>
0x6521  0x6AFB  # <CJK>
0x6522  0x7F4C  # <CJK>
0x6523  0x9DAF  # <CJK>
0x6524  0x9E1A  # <CJK>
0x6525  0x4E5F  # <CJK>
0x6526  0x503B  # <CJK>
0x6527  0x51B6  # <CJK>
0x6528  0x591C  # <CJK>
0x6529  0x60F9  # <CJK>
0x652A  0x63F6  # <CJK>
0x652B  0x6930  # <CJK>
0x652C  0x723A  # <CJK>
0x652D  0x8036  # <CJK>
0x652E  0xF974  # <CJK>
0x652F  0x91CE  # <CJK>
0x6530  0x5F31  # <CJK>
0x6531  0xF975  # <CJK>
0x6532  0xF976  # <CJK>
0x6533  0x7D04  # <CJK>
0x6534  0x82E5  # <CJK>
0x6535  0x846F  # <CJK>
0x6536  0x84BB  # <CJK>
0x6537  0x85E5  # <CJK>
0x6538  0x8E8D  # <CJK>
0x6539  0xF977  # <CJK>
0x653A  0x4F6F  # <CJK>
0x653B  0xF978  # <CJK>
0x653C  0xF979  # <CJK>
0x653D  0x58E4  # <CJK>
0x653E  0x5B43  # <CJK>
0x653F  0x6059  # <CJK>
0x6540  0x63DA  # <CJK>
0x6541  0x6518  # <CJK>
0x6542  0x656D  # <CJK>
0x6543  0x6698  # <CJK>
0x6544  0xF97A  # <CJK>
0x6545  0x694A  # <CJK>
0x6546  0x6A23  # <CJK>
0x6547  0x6D0B  # <CJK>
0x6548  0x7001  # <CJK>
0x6549  0x716C  # <CJK>
0x654A  0x75D2  # <CJK>
0x654B  0x760D  # <CJK>
0x654C  0x79B3  # <CJK>
0x654D  0x7A70  # <CJK>
0x654E  0xF97B  # <CJK>
0x654F  0x7F8A  # <CJK>
0x6550  0xF97C  # <CJK>
0x6551  0x8944  # <CJK>
0x6552  0xF97D  # <CJK>
0x6553  0x8B93  # <CJK>
0x6554  0x91C0  # <CJK>
0x6555  0x967D  # <CJK>
0x6556  0xF97E  # <CJK>
0x6557  0x990A  # <CJK>
0x6558  0x5704  # <CJK>
0x6559  0x5FA1  # <CJK>
0x655A  0x65BC  # <CJK>
0x655B  0x6F01  # <CJK>
0x655C  0x7600  # <CJK>
0x655D  0x79A6  # <CJK>
0x655E  0x8A9E  # <CJK>
0x655F  0x99AD  # <CJK>
0x6560  0x9B5A  # <CJK>
0x6561  0x9F6C  # <CJK>
0x6562  0x5104  # <CJK>
0x6563  0x61B6  # <CJK>
0x6564  0x6291  # <CJK>
0x6565  0x6A8D  # <CJK>
0x6566  0x81C6  # <CJK>
0x6567  0x5043  # <CJK>
0x6568  0x5830  # <CJK>
0x6569  0x5F66  # <CJK>
0x656A  0x7109  # <CJK>
0x656B  0x8A00  # <CJK>
0x656C  0x8AFA  # <CJK>
0x656D  0x5B7C  # <CJK>
0x656E  0x8616  # <CJK>
0x656F  0x4FFA  # <CJK>
0x6570  0x513C  # <CJK>
0x6571  0x56B4  # <CJK>
0x6572  0x5944  # <CJK>
0x6573  0x63A9  # <CJK>
0x6574  0x6DF9  # <CJK>
0x6575  0x5DAA  # <CJK>
0x6576  0x696D  # <CJK>
0x6577  0x5186  # <CJK>
0x6578  0x4E88  # <CJK>
0x6579  0x4F59  # <CJK>
0x657A  0xF97F  # <CJK>
0x657B  0xF980  # <CJK>
0x657C  0xF981  # <CJK>
0x657D  0x5982  # <CJK>
0x657E  0xF982  # <CJK>
0x6621  0xF983  # <CJK>
0x6622  0x6B5F  # <CJK>
0x6623  0x6C5D  # <CJK>
0x6624  0xF984  # <CJK>
0x6625  0x74B5  # <CJK>
0x6626  0x7916  # <CJK>
0x6627  0xF985  # <CJK>
0x6628  0x8207  # <CJK>
0x6629  0x8245  # <CJK>
0x662A  0x8339  # <CJK>
0x662B  0x8F3F  # <CJK>
0x662C  0x8F5D  # <CJK>
0x662D  0xF986  # <CJK>
0x662E  0x9918  # <CJK>
0x662F  0xF987  # <CJK>
0x6630  0xF988  # <CJK>
0x6631  0xF989  # <CJK>
0x6632  0x4EA6  # <CJK>
0x6633  0xF98A  # <CJK>
0x6634  0x57DF  # <CJK>
0x6635  0x5F79  # <CJK>
0x6636  0x6613  # <CJK>
0x6637  0xF98B  # <CJK>
0x6638  0xF98C  # <CJK>
0x6639  0x75AB  # <CJK>
0x663A  0x7E79  # <CJK>
0x663B  0x8B6F  # <CJK>
0x663C  0xF98D  # <CJK>
0x663D  0x9006  # <CJK>
0x663E  0x9A5B  # <CJK>
0x663F  0x56A5  # <CJK>
0x6640  0x5827  # <CJK>
0x6641  0x59F8  # <CJK>
0x6642  0x5A1F  # <CJK>
0x6643  0x5BB4  # <CJK>
0x6644  0xF98E  # <CJK>
0x6645  0x5EF6  # <CJK>
0x6646  0xF98F  # <CJK>
0x6647  0xF990  # <CJK>
0x6648  0x6350  # <CJK>
0x6649  0x633B  # <CJK>
0x664A  0xF991  # <CJK>
0x664B  0x693D  # <CJK>
0x664C  0x6C87  # <CJK>
0x664D  0x6CBF  # <CJK>
0x664E  0x6D8E  # <CJK>
0x664F  0x6D93  # <CJK>
0x6650  0x6DF5  # <CJK>
0x6651  0x6F14  # <CJK>
0x6652  0xF992  # <CJK>
0x6653  0x70DF  # <CJK>
0x6654  0x7136  # <CJK>
0x6655  0x7159  # <CJK>
0x6656  0xF993  # <CJK>
0x6657  0x71C3  # <CJK>
0x6658  0x71D5  # <CJK>
0x6659  0xF994  # <CJK>
0x665A  0x784F  # <CJK>
0x665B  0x786F  # <CJK>
0x665C  0xF995  # <CJK>
0x665D  0x7B75  # <CJK>
0x665E  0x7DE3  # <CJK>
0x665F  0xF996  # <CJK>
0x6660  0x7E2F  # <CJK>
0x6661  0xF997  # <CJK>
0x6662  0x884D  # <CJK>
0x6663  0x8EDF  # <CJK>
0x6664  0xF998  # <CJK>
0x6665  0xF999  # <CJK>
0x6666  0xF99A  # <CJK>
0x6667  0x925B  # <CJK>
0x6668  0xF99B  # <CJK>
0x6669  0x9CF6  # <CJK>
0x666A  0xF99C  # <CJK>
0x666B  0xF99D  # <CJK>
0x666C  0xF99E  # <CJK>
0x666D  0x6085  # <CJK>
0x666E  0x6D85  # <CJK>
0x666F  0xF99F  # <CJK>
0x6670  0x71B1  # <CJK>
0x6671  0xF9A0  # <CJK>
0x6672  0xF9A1  # <CJK>
0x6673  0x95B1  # <CJK>
0x6674  0x53AD  # <CJK>
0x6675  0xF9A2  # <CJK>
0x6676  0xF9A3  # <CJK>
0x6677  0xF9A4  # <CJK>
0x6678  0x67D3  # <CJK>
0x6679  0xF9A5  # <CJK>
0x667A  0x708E  # <CJK>
0x667B  0x7130  # <CJK>
0x667C  0x7430  # <CJK>
0x667D  0x8276  # <CJK>
0x667E  0x82D2  # <CJK>
0x6721  0xF9A6  # <CJK>
0x6722  0x95BB  # <CJK>
0x6723  0x9AE5  # <CJK>
0x6724  0x9E7D  # <CJK>
0x6725  0x66C4  # <CJK>
0x6726  0xF9A7  # <CJK>
0x6727  0x71C1  # <CJK>
0x6728  0x8449  # <CJK>
0x6729  0xF9A8  # <CJK>
0x672A  0xF9A9  # <CJK>
0x672B  0x584B  # <CJK>
0x672C  0xF9AA  # <CJK>
0x672D  0xF9AB  # <CJK>
0x672E  0x5DB8  # <CJK>
0x672F  0x5F71  # <CJK>
0x6730  0xF9AC  # <CJK>
0x6731  0x6620  # <CJK>
0x6732  0x668E  # <CJK>
0x6733  0x6979  # <CJK>
0x6734  0x69AE  # <CJK>
0x6735  0x6C38  # <CJK>
0x6736  0x6CF3  # <CJK>
0x6737  0x6E36  # <CJK>
0x6738  0x6F41  # <CJK>
0x6739  0x6FDA  # <CJK>
0x673A  0x701B  # <CJK>
0x673B  0x702F  # <CJK>
0x673C  0x7150  # <CJK>
0x673D  0x71DF  # <CJK>
0x673E  0x7370  # <CJK>
0x673F  0xF9AD  # <CJK>
0x6740  0x745B  # <CJK>
0x6741  0xF9AE  # <CJK>
0x6742  0x74D4  # <CJK>
0x6743  0x76C8  # <CJK>
0x6744  0x7A4E  # <CJK>
0x6745  0x7E93  # <CJK>
0x6746  0xF9AF  # <CJK>
0x6747  0xF9B0  # <CJK>
0x6748  0x82F1  # <CJK>
0x6749  0x8A60  # <CJK>
0x674A  0x8FCE  # <CJK>
0x674B  0xF9B1  # <CJK>
0x674C  0x9348  # <CJK>
0x674D  0xF9B2  # <CJK>
0x674E  0x9719  # <CJK>
0x674F  0xF9B3  # <CJK>
0x6750  0xF9B4  # <CJK>
0x6751  0x4E42  # <CJK>
0x6752  0x502A  # <CJK>
0x6753  0xF9B5  # <CJK>
0x6754  0x5208  # <CJK>
0x6755  0x53E1  # <CJK>
0x6756  0x66F3  # <CJK>
0x6757  0x6C6D  # <CJK>
0x6758  0x6FCA  # <CJK>
0x6759  0x730A  # <CJK>
0x675A  0x777F  # <CJK>
0x675B  0x7A62  # <CJK>
0x675C  0x82AE  # <CJK>
0x675D  0x85DD  # <CJK>
0x675E  0x8602  # <CJK>
0x675F  0xF9B6  # <CJK>
0x6760  0x88D4  # <CJK>
0x6761  0x8A63  # <CJK>
0x6762  0x8B7D  # <CJK>
0x6763  0x8C6B  # <CJK>
0x6764  0xF9B7  # <CJK>
0x6765  0x92B3  # <CJK>
0x6766  0xF9B8  # <CJK>
0x6767  0x9713  # <CJK>
0x6768  0x9810  # <CJK>
0x6769  0x4E94  # <CJK>
0x676A  0x4F0D  # <CJK>
0x676B  0x4FC9  # <CJK>
0x676C  0x50B2  # <CJK>
0x676D  0x5348  # <CJK>
0x676E  0x543E  # <CJK>
0x676F  0x5433  # <CJK>
0x6770  0x55DA  # <CJK>
0x6771  0x5862  # <CJK>
0x6772  0x58BA  # <CJK>
0x6773  0x5967  # <CJK>
0x6774  0x5A1B  # <CJK>
0x6775  0x5BE4  # <CJK>
0x6776  0x609F  # <CJK>
0x6777  0xF9B9  # <CJK>
0x6778  0x61CA  # <CJK>
0x6779  0x6556  # <CJK>
0x677A  0x65FF  # <CJK>
0x677B  0x6664  # <CJK>
0x677C  0x68A7  # <CJK>
0x677D  0x6C5A  # <CJK>
0x677E  0x6FB3  # <CJK>
0x6821  0x70CF  # <CJK>
0x6822  0x71AC  # <CJK>
0x6823  0x7352  # <CJK>
0x6824  0x7B7D  # <CJK>
0x6825  0x8708  # <CJK>
0x6826  0x8AA4  # <CJK>
0x6827  0x9C32  # <CJK>
0x6828  0x9F07  # <CJK>
0x6829  0x5C4B  # <CJK>
0x682A  0x6C83  # <CJK>
0x682B  0x7344  # <CJK>
0x682C  0x7389  # <CJK>
0x682D  0x923A  # <CJK>
0x682E  0x6EAB  # <CJK>
0x682F  0x7465  # <CJK>
0x6830  0x761F  # <CJK>
0x6831  0x7A69  # <CJK>
0x6832  0x7E15  # <CJK>
0x6833  0x860A  # <CJK>
0x6834  0x5140  # <CJK>
0x6835  0x58C5  # <CJK>
0x6836  0x64C1  # <CJK>
0x6837  0x74EE  # <CJK>
0x6838  0x7515  # <CJK>
0x6839  0x7670  # <CJK>
0x683A  0x7FC1  # <CJK>
0x683B  0x9095  # <CJK>
0x683C  0x96CD  # <CJK>
0x683D  0x9954  # <CJK>
0x683E  0x6E26  # <CJK>
0x683F  0x74E6  # <CJK>
0x6840  0x7AA9  # <CJK>
0x6841  0x7AAA  # <CJK>
0x6842  0x81E5  # <CJK>
0x6843  0x86D9  # <CJK>
0x6844  0x8778  # <CJK>
0x6845  0x8A1B  # <CJK>
0x6846  0x5A49  # <CJK>
0x6847  0x5B8C  # <CJK>
0x6848  0x5B9B  # <CJK>
0x6849  0x68A1  # <CJK>
0x684A  0x6900  # <CJK>
0x684B  0x6D63  # <CJK>
0x684C  0x73A9  # <CJK>
0x684D  0x7413  # <CJK>
0x684E  0x742C  # <CJK>
0x684F  0x7897  # <CJK>
0x6850  0x7DE9  # <CJK>
0x6851  0x7FEB  # <CJK>
0x6852  0x8118  # <CJK>
0x6853  0x8155  # <CJK>
0x6854  0x839E  # <CJK>
0x6855  0x8C4C  # <CJK>
0x6856  0x962E  # <CJK>
0x6857  0x9811  # <CJK>
0x6858  0x66F0  # <CJK>
0x6859  0x5F80  # <CJK>
0x685A  0x65FA  # <CJK>
0x685B  0x6789  # <CJK>
0x685C  0x6C6A  # <CJK>
0x685D  0x738B  # <CJK>
0x685E  0x502D  # <CJK>
0x685F  0x5A03  # <CJK>
0x6860  0x6B6A  # <CJK>
0x6861  0x77EE  # <CJK>
0x6862  0x5916  # <CJK>
0x6863  0x5D6C  # <CJK>
0x6864  0x5DCD  # <CJK>
0x6865  0x7325  # <CJK>
0x6866  0x754F  # <CJK>
0x6867  0xF9BA  # <CJK>
0x6868  0xF9BB  # <CJK>
0x6869  0x50E5  # <CJK>
0x686A  0x51F9  # <CJK>
0x686B  0x582F  # <CJK>
0x686C  0x592D  # <CJK>
0x686D  0x5996  # <CJK>
0x686E  0x59DA  # <CJK>
0x686F  0x5BE5  # <CJK>
0x6870  0xF9BC  # <CJK>
0x6871  0xF9BD  # <CJK>
0x6872  0x5DA2  # <CJK>
0x6873  0x62D7  # <CJK>
0x6874  0x6416  # <CJK>
0x6875  0x6493  # <CJK>
0x6876  0x64FE  # <CJK>
0x6877  0xF9BE  # <CJK>
0x6878  0x66DC  # <CJK>
0x6879  0xF9BF  # <CJK>
0x687A  0x6A48  # <CJK>
0x687B  0xF9C0  # <CJK>
0x687C  0x71FF  # <CJK>
0x687D  0x7464  # <CJK>
0x687E  0xF9C1  # <CJK>
0x6921  0x7A88  # <CJK>
0x6922  0x7AAF  # <CJK>
0x6923  0x7E47  # <CJK>
0x6924  0x7E5E  # <CJK>
0x6925  0x8000  # <CJK>
0x6926  0x8170  # <CJK>
0x6927  0xF9C2  # <CJK>
0x6928  0x87EF  # <CJK>
0x6929  0x8981  # <CJK>
0x692A  0x8B20  # <CJK>
0x692B  0x9059  # <CJK>
0x692C  0xF9C3  # <CJK>
0x692D  0x9080  # <CJK>
0x692E  0x9952  # <CJK>
0x692F  0x617E  # <CJK>
0x6930  0x6B32  # <CJK>
0x6931  0x6D74  # <CJK>
0x6932  0x7E1F  # <CJK>
0x6933  0x8925  # <CJK>
0x6934  0x8FB1  # <CJK>
0x6935  0x4FD1  # <CJK>
0x6936  0x50AD  # <CJK>
0x6937  0x5197  # <CJK>
0x6938  0x52C7  # <CJK>
0x6939  0x57C7  # <CJK>
0x693A  0x5889  # <CJK>
0x693B  0x5BB9  # <CJK>
0x693C  0x5EB8  # <CJK>
0x693D  0x6142  # <CJK>
0x693E  0x6995  # <CJK>
0x693F  0x6D8C  # <CJK>
0x6940  0x6E67  # <CJK>
0x6941  0x6EB6  # <CJK>
0x6942  0x7194  # <CJK>
0x6943  0x7462  # <CJK>
0x6944  0x7528  # <CJK>
0x6945  0x752C  # <CJK>
0x6946  0x8073  # <CJK>
0x6947  0x8338  # <CJK>
0x6948  0x84C9  # <CJK>
0x6949  0x8E0A  # <CJK>
0x694A  0x9394  # <CJK>
0x694B  0x93DE  # <CJK>
0x694C  0xF9C4  # <CJK>
0x694D  0x4E8E  # <CJK>
0x694E  0x4F51  # <CJK>
0x694F  0x5076  # <CJK>
0x6950  0x512A  # <CJK>
0x6951  0x53C8  # <CJK>
0x6952  0x53CB  # <CJK>
0x6953  0x53F3  # <CJK>
0x6954  0x5B87  # <CJK>
0x6955  0x5BD3  # <CJK>
0x6956  0x5C24  # <CJK>
0x6957  0x611A  # <CJK>
0x6958  0x6182  # <CJK>
0x6959  0x65F4  # <CJK>
0x695A  0x725B  # <CJK>
0x695B  0x7397  # <CJK>
0x695C  0x7440  # <CJK>
0x695D  0x76C2  # <CJK>
0x695E  0x7950  # <CJK>
0x695F  0x7991  # <CJK>
0x6960  0x79B9  # <CJK>
0x6961  0x7D06  # <CJK>
0x6962  0x7FBD  # <CJK>
0x6963  0x828B  # <CJK>
0x6964  0x85D5  # <CJK>
0x6965  0x865E  # <CJK>
0x6966  0x8FC2  # <CJK>
0x6967  0x9047  # <CJK>
0x6968  0x90F5  # <CJK>
0x6969  0x91EA  # <CJK>
0x696A  0x9685  # <CJK>
0x696B  0x96E8  # <CJK>
0x696C  0x96E9  # <CJK>
0x696D  0x52D6  # <CJK>
0x696E  0x5F67  # <CJK>
0x696F  0x65ED  # <CJK>
0x6970  0x6631  # <CJK>
0x6971  0x682F  # <CJK>
0x6972  0x715C  # <CJK>
0x6973  0x7A36  # <CJK>
0x6974  0x90C1  # <CJK>
0x6975  0x980A  # <CJK>
0x6976  0x4E91  # <CJK>
0x6977  0xF9C5  # <CJK>
0x6978  0x6A52  # <CJK>
0x6979  0x6B9E  # <CJK>
0x697A  0x6F90  # <CJK>
0x697B  0x7189  # <CJK>
0x697C  0x8018  # <CJK>
0x697D  0x82B8  # <CJK>
0x697E  0x8553  # <CJK>
0x6A21  0x904B  # <CJK>
0x6A22  0x9695  # <CJK>
0x6A23  0x96F2  # <CJK>
0x6A24  0x97FB  # <CJK>
0x6A25  0x851A  # <CJK>
0x6A26  0x9B31  # <CJK>
0x6A27  0x4E90  # <CJK>
0x6A28  0x718A  # <CJK>
0x6A29  0x96C4  # <CJK>
0x6A2A  0x5143  # <CJK>
0x6A2B  0x539F  # <CJK>
0x6A2C  0x54E1  # <CJK>
0x6A2D  0x5713  # <CJK>
0x6A2E  0x5712  # <CJK>
0x6A2F  0x57A3  # <CJK>
0x6A30  0x5A9B  # <CJK>
0x6A31  0x5AC4  # <CJK>
0x6A32  0x5BC3  # <CJK>
0x6A33  0x6028  # <CJK>
0x6A34  0x613F  # <CJK>
0x6A35  0x63F4  # <CJK>
0x6A36  0x6C85  # <CJK>
0x6A37  0x6D39  # <CJK>
0x6A38  0x6E72  # <CJK>
0x6A39  0x6E90  # <CJK>
0x6A3A  0x7230  # <CJK>
0x6A3B  0x733F  # <CJK>
0x6A3C  0x7457  # <CJK>
0x6A3D  0x82D1  # <CJK>
0x6A3E  0x8881  # <CJK>
0x6A3F  0x8F45  # <CJK>
0x6A40  0x9060  # <CJK>
0x6A41  0xF9C6  # <CJK>
0x6A42  0x9662  # <CJK>
0x6A43  0x9858  # <CJK>
0x6A44  0x9D1B  # <CJK>
0x6A45  0x6708  # <CJK>
0x6A46  0x8D8A  # <CJK>
0x6A47  0x925E  # <CJK>
0x6A48  0x4F4D  # <CJK>
0x6A49  0x5049  # <CJK>
0x6A4A  0x50DE  # <CJK>
0x6A4B  0x5371  # <CJK>
0x6A4C  0x570D  # <CJK>
0x6A4D  0x59D4  # <CJK>
0x6A4E  0x5A01  # <CJK>
0x6A4F  0x5C09  # <CJK>
0x6A50  0x6170  # <CJK>
0x6A51  0x6690  # <CJK>
0x6A52  0x6E2D  # <CJK>
0x6A53  0x7232  # <CJK>
0x6A54  0x744B  # <CJK>
0x6A55  0x7DEF  # <CJK>
0x6A56  0x80C3  # <CJK>
0x6A57  0x840E  # <CJK>
0x6A58  0x8466  # <CJK>
0x6A59  0x853F  # <CJK>
0x6A5A  0x875F  # <CJK>
0x6A5B  0x885B  # <CJK>
0x6A5C  0x8918  # <CJK>
0x6A5D  0x8B02  # <CJK>
0x6A5E  0x9055  # <CJK>
0x6A5F  0x97CB  # <CJK>
0x6A60  0x9B4F  # <CJK>
0x6A61  0x4E73  # <CJK>
0x6A62  0x4F91  # <CJK>
0x6A63  0x5112  # <CJK>
0x6A64  0x516A  # <CJK>
0x6A65  0xF9C7  # <CJK>
0x6A66  0x552F  # <CJK>
0x6A67  0x55A9  # <CJK>
0x6A68  0x5B7A  # <CJK>
0x6A69  0x5BA5  # <CJK>
0x6A6A  0x5E7C  # <CJK>
0x6A6B  0x5E7D  # <CJK>
0x6A6C  0x5EBE  # <CJK>
0x6A6D  0x60A0  # <CJK>
0x6A6E  0x60DF  # <CJK>
0x6A6F  0x6108  # <CJK>
0x6A70  0x6109  # <CJK>
0x6A71  0x63C4  # <CJK>
0x6A72  0x6538  # <CJK>
0x6A73  0x6709  # <CJK>
0x6A74  0xF9C8  # <CJK>
0x6A75  0x67D4  # <CJK>
0x6A76  0x67DA  # <CJK>
0x6A77  0xF9C9  # <CJK>
0x6A78  0x6961  # <CJK>
0x6A79  0x6962  # <CJK>
0x6A7A  0x6CB9  # <CJK>
0x6A7B  0x6D27  # <CJK>
0x6A7C  0xF9CA  # <CJK>
0x6A7D  0x6E38  # <CJK>
0x6A7E  0xF9CB  # <CJK>
0x6B21  0x6FE1  # <CJK>
0x6B22  0x7336  # <CJK>
0x6B23  0x7337  # <CJK>
0x6B24  0xF9CC  # <CJK>
0x6B25  0x745C  # <CJK>
0x6B26  0x7531  # <CJK>
0x6B27  0xF9CD  # <CJK>
0x6B28  0x7652  # <CJK>
0x6B29  0xF9CE  # <CJK>
0x6B2A  0xF9CF  # <CJK>
0x6B2B  0x7DAD  # <CJK>
0x6B2C  0x81FE  # <CJK>
0x6B2D  0x8438  # <CJK>
0x6B2E  0x88D5  # <CJK>
0x6B2F  0x8A98  # <CJK>
0x6B30  0x8ADB  # <CJK>
0x6B31  0x8AED  # <CJK>
0x6B32  0x8E30  # <CJK>
0x6B33  0x8E42  # <CJK>
0x6B34  0x904A  # <CJK>
0x6B35  0x903E  # <CJK>
0x6B36  0x907A  # <CJK>
0x6B37  0x9149  # <CJK>
0x6B38  0x91C9  # <CJK>
0x6B39  0x936E  # <CJK>
0x6B3A  0xF9D0  # <CJK>
0x6B3B  0xF9D1  # <CJK>
0x6B3C  0x5809  # <CJK>
0x6B3D  0xF9D2  # <CJK>
0x6B3E  0x6BD3  # <CJK>
0x6B3F  0x8089  # <CJK>
0x6B40  0x80B2  # <CJK>
0x6B41  0xF9D3  # <CJK>
0x6B42  0xF9D4  # <CJK>
0x6B43  0x5141  # <CJK>
0x6B44  0x596B  # <CJK>
0x6B45  0x5C39  # <CJK>
0x6B46  0xF9D5  # <CJK>
0x6B47  0xF9D6  # <CJK>
0x6B48  0x6F64  # <CJK>
0x6B49  0x73A7  # <CJK>
0x6B4A  0x80E4  # <CJK>
0x6B4B  0x8D07  # <CJK>
0x6B4C  0xF9D7  # <CJK>
0x6B4D  0x9217  # <CJK>
0x6B4E  0x958F  # <CJK>
0x6B4F  0xF9D8  # <CJK>
0x6B50  0xF9D9  # <CJK>
0x6B51  0xF9DA  # <CJK>
0x6B52  0xF9DB  # <CJK>
0x6B53  0x807F  # <CJK>
0x6B54  0x620E  # <CJK>
0x6B55  0x701C  # <CJK>
0x6B56  0x7D68  # <CJK>
0x6B57  0x878D  # <CJK>
0x6B58  0xF9DC  # <CJK>
0x6B59  0x57A0  # <CJK>
0x6B5A  0x6069  # <CJK>
0x6B5B  0x6147  # <CJK>
0x6B5C  0x6BB7  # <CJK>
0x6B5D  0x8ABE  # <CJK>
0x6B5E  0x9280  # <CJK>
0x6B5F  0x96B1  # <CJK>
0x6B60  0x4E59  # <CJK>
0x6B61  0x541F  # <CJK>
0x6B62  0x6DEB  # <CJK>
0x6B63  0x852D  # <CJK>
0x6B64  0x9670  # <CJK>
0x6B65  0x97F3  # <CJK>
0x6B66  0x98EE  # <CJK>
0x6B67  0x63D6  # <CJK>
0x6B68  0x6CE3  # <CJK>
0x6B69  0x9091  # <CJK>
0x6B6A  0x51DD  # <CJK>
0x6B6B  0x61C9  # <CJK>
0x6B6C  0x81BA  # <CJK>
0x6B6D  0x9DF9  # <CJK>
0x6B6E  0x4F9D  # <CJK>
0x6B6F  0x501A  # <CJK>
0x6B70  0x5100  # <CJK>
0x6B71  0x5B9C  # <CJK>
0x6B72  0x610F  # <CJK>
0x6B73  0x61FF  # <CJK>
0x6B74  0x64EC  # <CJK>
0x6B75  0x6905  # <CJK>
0x6B76  0x6BC5  # <CJK>
0x6B77  0x7591  # <CJK>
0x6B78  0x77E3  # <CJK>
0x6B79  0x7FA9  # <CJK>
0x6B7A  0x8264  # <CJK>
0x6B7B  0x858F  # <CJK>
0x6B7C  0x87FB  # <CJK>
0x6B7D  0x8863  # <CJK>
0x6B7E  0x8ABC  # <CJK>
0x6C21  0x8B70  # <CJK>
0x6C22  0x91AB  # <CJK>
0x6C23  0x4E8C  # <CJK>
0x6C24  0x4EE5  # <CJK>
0x6C25  0x4F0A  # <CJK>
0x6C26  0xF9DD  # <CJK>
0x6C27  0xF9DE  # <CJK>
0x6C28  0x5937  # <CJK>
0x6C29  0x59E8  # <CJK>
0x6C2A  0xF9DF  # <CJK>
0x6C2B  0x5DF2  # <CJK>
0x6C2C  0x5F1B  # <CJK>
0x6C2D  0x5F5B  # <CJK>
0x6C2E  0x6021  # <CJK>
0x6C2F  0xF9E0  # <CJK>
0x6C30  0xF9E1  # <CJK>
0x6C31  0xF9E2  # <CJK>
0x6C32  0xF9E3  # <CJK>
0x6C33  0x723E  # <CJK>
0x6C34  0x73E5  # <CJK>
0x6C35  0xF9E4  # <CJK>
0x6C36  0x7570  # <CJK>
0x6C37  0x75CD  # <CJK>
0x6C38  0xF9E5  # <CJK>
0x6C39  0x79FB  # <CJK>
0x6C3A  0xF9E6  # <CJK>
0x6C3B  0x800C  # <CJK>
0x6C3C  0x8033  # <CJK>
0x6C3D  0x8084  # <CJK>
0x6C3E  0x82E1  # <CJK>
0x6C3F  0x8351  # <CJK>
0x6C40  0xF9E7  # <CJK>
0x6C41  0xF9E8  # <CJK>
0x6C42  0x8CBD  # <CJK>
0x6C43  0x8CB3  # <CJK>
0x6C44  0x9087  # <CJK>
0x6C45  0xF9E9  # <CJK>
0x6C46  0xF9EA  # <CJK>
0x6C47  0x98F4  # <CJK>
0x6C48  0x990C  # <CJK>
0x6C49  0xF9EB  # <CJK>
0x6C4A  0xF9EC  # <CJK>
0x6C4B  0x7037  # <CJK>
0x6C4C  0x76CA  # <CJK>
0x6C4D  0x7FCA  # <CJK>
0x6C4E  0x7FCC  # <CJK>
0x6C4F  0x7FFC  # <CJK>
0x6C50  0x8B1A  # <CJK>
0x6C51  0x4EBA  # <CJK>
0x6C52  0x4EC1  # <CJK>
0x6C53  0x5203  # <CJK>
0x6C54  0x5370  # <CJK>
0x6C55  0xF9ED  # <CJK>
0x6C56  0x54BD  # <CJK>
0x6C57  0x56E0  # <CJK>
0x6C58  0x59FB  # <CJK>
0x6C59  0x5BC5  # <CJK>
0x6C5A  0x5F15  # <CJK>
0x6C5B  0x5FCD  # <CJK>
0x6C5C  0x6E6E  # <CJK>
0x6C5D  0xF9EE  # <CJK>
0x6C5E  0xF9EF  # <CJK>
0x6C5F  0x7D6A  # <CJK>
0x6C60  0x8335  # <CJK>
0x6C61  0xF9F0  # <CJK>
0x6C62  0x8693  # <CJK>
0x6C63  0x8A8D  # <CJK>
0x6C64  0xF9F1  # <CJK>
0x6C65  0x976D  # <CJK>
0x6C66  0x9777  # <CJK>
0x6C67  0xF9F2  # <CJK>
0x6C68  0xF9F3  # <CJK>
0x6C69  0x4E00  # <CJK>
0x6C6A  0x4F5A  # <CJK>
0x6C6B  0x4F7E  # <CJK>
0x6C6C  0x58F9  # <CJK>
0x6C6D  0x65E5  # <CJK>
0x6C6E  0x6EA2  # <CJK>
0x6C6F  0x9038  # <CJK>
0x6C70  0x93B0  # <CJK>
0x6C71  0x99B9  # <CJK>
0x6C72  0x4EFB  # <CJK>
0x6C73  0x58EC  # <CJK>
0x6C74  0x598A  # <CJK>
0x6C75  0x59D9  # <CJK>
0x6C76  0x6041  # <CJK>
0x6C77  0xF9F4  # <CJK>
0x6C78  0xF9F5  # <CJK>
0x6C79  0x7A14  # <CJK>
0x6C7A  0xF9F6  # <CJK>
0x6C7B  0x834F  # <CJK>
0x6C7C  0x8CC3  # <CJK>
0x6C7D  0x5165  # <CJK>
0x6C7E  0x5344  # <CJK>
0x6D21  0xF9F7  # <CJK>
0x6D22  0xF9F8  # <CJK>
0x6D23  0xF9F9  # <CJK>
0x6D24  0x4ECD  # <CJK>
0x6D25  0x5269  # <CJK>
0x6D26  0x5B55  # <CJK>
0x6D27  0x82BF  # <CJK>
0x6D28  0x4ED4  # <CJK>
0x6D29  0x523A  # <CJK>
0x6D2A  0x54A8  # <CJK>
0x6D2B  0x59C9  # <CJK>
0x6D2C  0x59FF  # <CJK>
0x6D2D  0x5B50  # <CJK>
0x6D2E  0x5B57  # <CJK>
0x6D2F  0x5B5C  # <CJK>
0x6D30  0x6063  # <CJK>
0x6D31  0x6148  # <CJK>
0x6D32  0x6ECB  # <CJK>
0x6D33  0x7099  # <CJK>
0x6D34  0x716E  # <CJK>
0x6D35  0x7386  # <CJK>
0x6D36  0x74F7  # <CJK>
0x6D37  0x75B5  # <CJK>
0x6D38  0x78C1  # <CJK>
0x6D39  0x7D2B  # <CJK>
0x6D3A  0x8005  # <CJK>
0x6D3B  0x81EA  # <CJK>
0x6D3C  0x8328  # <CJK>
0x6D3D  0x8517  # <CJK>
0x6D3E  0x85C9  # <CJK>
0x6D3F  0x8AEE  # <CJK>
0x6D40  0x8CC7  # <CJK>
0x6D41  0x96CC  # <CJK>
0x6D42  0x4F5C  # <CJK>
0x6D43  0x52FA  # <CJK>
0x6D44  0x56BC  # <CJK>
0x6D45  0x65AB  # <CJK>
0x6D46  0x6628  # <CJK>
0x6D47  0x707C  # <CJK>
0x6D48  0x70B8  # <CJK>
0x6D49  0x7235  # <CJK>
0x6D4A  0x7DBD  # <CJK>
0x6D4B  0x828D  # <CJK>
0x6D4C  0x914C  # <CJK>
0x6D4D  0x96C0  # <CJK>
0x6D4E  0x9D72  # <CJK>
0x6D4F  0x5B71  # <CJK>
0x6D50  0x68E7  # <CJK>
0x6D51  0x6B98  # <CJK>
0x6D52  0x6F7A  # <CJK>
0x6D53  0x76DE  # <CJK>
0x6D54  0x5C91  # <CJK>
0x6D55  0x66AB  # <CJK>
0x6D56  0x6F5B  # <CJK>
0x6D57  0x7BB4  # <CJK>
0x6D58  0x7C2A  # <CJK>
0x6D59  0x8836  # <CJK>
0x6D5A  0x96DC  # <CJK>
0x6D5B  0x4E08  # <CJK>
0x6D5C  0x4ED7  # <CJK>
0x6D5D  0x5320  # <CJK>
0x6D5E  0x5834  # <CJK>
0x6D5F  0x58BB  # <CJK>
0x6D60  0x58EF  # <CJK>
0x6D61  0x596C  # <CJK>
0x6D62  0x5C07  # <CJK>
0x6D63  0x5E33  # <CJK>
0x6D64  0x5E84  # <CJK>
0x6D65  0x5F35  # <CJK>
0x6D66  0x638C  # <CJK>
0x6D67  0x66B2  # <CJK>
0x6D68  0x6756  # <CJK>
0x6D69  0x6A1F  # <CJK>
0x6D6A  0x6AA3  # <CJK>
0x6D6B  0x6B0C  # <CJK>
0x6D6C  0x6F3F  # <CJK>
0x6D6D  0x7246  # <CJK>
0x6D6E  0xF9FA  # <CJK>
0x6D6F  0x7350  # <CJK>
0x6D70  0x748B  # <CJK>
0x6D71  0x7AE0  # <CJK>
0x6D72  0x7CA7  # <CJK>
0x6D73  0x8178  # <CJK>
0x6D74  0x81DF  # <CJK>
0x6D75  0x81E7  # <CJK>
0x6D76  0x838A  # <CJK>
0x6D77  0x846C  # <CJK>
0x6D78  0x8523  # <CJK>
0x6D79  0x8594  # <CJK>
0x6D7A  0x85CF  # <CJK>
0x6D7B  0x88DD  # <CJK>
0x6D7C  0x8D13  # <CJK>
0x6D7D  0x91AC  # <CJK>
0x6D7E  0x9577  # <CJK>
0x6E21  0x969C  # <CJK>
0x6E22  0x518D  # <CJK>
0x6E23  0x54C9  # <CJK>
0x6E24  0x5728  # <CJK>
0x6E25  0x5BB0  # <CJK>
0x6E26  0x624D  # <CJK>
0x6E27  0x6750  # <CJK>
0x6E28  0x683D  # <CJK>
0x6E29  0x6893  # <CJK>
0x6E2A  0x6E3D  # <CJK>
0x6E2B  0x6ED3  # <CJK>
0x6E2C  0x707D  # <CJK>
0x6E2D  0x7E21  # <CJK>
0x6E2E  0x88C1  # <CJK>
0x6E2F  0x8CA1  # <CJK>
0x6E30  0x8F09  # <CJK>
0x6E31  0x9F4B  # <CJK>
0x6E32  0x9F4E  # <CJK>
0x6E33  0x722D  # <CJK>
0x6E34  0x7B8F  # <CJK>
0x6E35  0x8ACD  # <CJK>
0x6E36  0x931A  # <CJK>
0x6E37  0x4F47  # <CJK>
0x6E38  0x4F4E  # <CJK>
0x6E39  0x5132  # <CJK>
0x6E3A  0x5480  # <CJK>
0x6E3B  0x59D0  # <CJK>
0x6E3C  0x5E95  # <CJK>
0x6E3D  0x62B5  # <CJK>
0x6E3E  0x6775  # <CJK>
0x6E3F  0x696E  # <CJK>
0x6E40  0x6A17  # <CJK>
0x6E41  0x6CAE  # <CJK>
0x6E42  0x6E1A  # <CJK>
0x6E43  0x72D9  # <CJK>
0x6E44  0x732A  # <CJK>
0x6E45  0x75BD  # <CJK>
0x6E46  0x7BB8  # <CJK>
0x6E47  0x7D35  # <CJK>
0x6E48  0x82E7  # <CJK>
0x6E49  0x83F9  # <CJK>
0x6E4A  0x8457  # <CJK>
0x6E4B  0x85F7  # <CJK>
0x6E4C  0x8A5B  # <CJK>
0x6E4D  0x8CAF  # <CJK>
0x6E4E  0x8E87  # <CJK>
0x6E4F  0x9019  # <CJK>
0x6E50  0x90B8  # <CJK>
0x6E51  0x96CE  # <CJK>
0x6E52  0x9F5F  # <CJK>
0x6E53  0x52E3  # <CJK>
0x6E54  0x540A  # <CJK>
0x6E55  0x5AE1  # <CJK>
0x6E56  0x5BC2  # <CJK>
0x6E57  0x6458  # <CJK>
0x6E58  0x6575  # <CJK>
0x6E59  0x6EF4  # <CJK>
0x6E5A  0x72C4  # <CJK>
0x6E5B  0xF9FB  # <CJK>
0x6E5C  0x7684  # <CJK>
0x6E5D  0x7A4D  # <CJK>
0x6E5E  0x7B1B  # <CJK>
0x6E5F  0x7C4D  # <CJK>
0x6E60  0x7E3E  # <CJK>
0x6E61  0x7FDF  # <CJK>
0x6E62  0x837B  # <CJK>
0x6E63  0x8B2B  # <CJK>
0x6E64  0x8CCA  # <CJK>
0x6E65  0x8D64  # <CJK>
0x6E66  0x8DE1  # <CJK>
0x6E67  0x8E5F  # <CJK>
0x6E68  0x8FEA  # <CJK>
0x6E69  0x8FF9  # <CJK>
0x6E6A  0x9069  # <CJK>
0x6E6B  0x93D1  # <CJK>
0x6E6C  0x4F43  # <CJK>
0x6E6D  0x4F7A  # <CJK>
0x6E6E  0x50B3  # <CJK>
0x6E6F  0x5168  # <CJK>
0x6E70  0x5178  # <CJK>
0x6E71  0x524D  # <CJK>
0x6E72  0x526A  # <CJK>
0x6E73  0x5861  # <CJK>
0x6E74  0x587C  # <CJK>
0x6E75  0x5960  # <CJK>
0x6E76  0x5C08  # <CJK>
0x6E77  0x5C55  # <CJK>
0x6E78  0x5EDB  # <CJK>
0x6E79  0x609B  # <CJK>
0x6E7A  0x6230  # <CJK>
0x6E7B  0x6813  # <CJK>
0x6E7C  0x6BBF  # <CJK>
0x6E7D  0x6C08  # <CJK>
0x6E7E  0x6FB1  # <CJK>
0x6F21  0x714E  # <CJK>
0x6F22  0x7420  # <CJK>
0x6F23  0x7530  # <CJK>
0x6F24  0x7538  # <CJK>
0x6F25  0x7551  # <CJK>
0x6F26  0x7672  # <CJK>
0x6F27  0x7B4C  # <CJK>
0x6F28  0x7B8B  # <CJK>
0x6F29  0x7BAD  # <CJK>
0x6F2A  0x7BC6  # <CJK>
0x6F2B  0x7E8F  # <CJK>
0x6F2C  0x8A6E  # <CJK>
0x6F2D  0x8F3E  # <CJK>
0x6F2E  0x8F49  # <CJK>
0x6F2F  0x923F  # <CJK>
0x6F30  0x9293  # <CJK>
0x6F31  0x9322  # <CJK>
0x6F32  0x942B  # <CJK>
0x6F33  0x96FB  # <CJK>
0x6F34  0x985A  # <CJK>
0x6F35  0x986B  # <CJK>
0x6F36  0x991E  # <CJK>
0x6F37  0x5207  # <CJK>
0x6F38  0x622A  # <CJK>
0x6F39  0x6298  # <CJK>
0x6F3A  0x6D59  # <CJK>
0x6F3B  0x7664  # <CJK>
0x6F3C  0x7ACA  # <CJK>
0x6F3D  0x7BC0  # <CJK>
0x6F3E  0x7D76  # <CJK>
0x6F3F  0x5360  # <CJK>
0x6F40  0x5CBE  # <CJK>
0x6F41  0x5E97  # <CJK>
0x6F42  0x6F38  # <CJK>
0x6F43  0x70B9  # <CJK>
0x6F44  0x7C98  # <CJK>
0x6F45  0x9711  # <CJK>
0x6F46  0x9B8E  # <CJK>
0x6F47  0x9EDE  # <CJK>
0x6F48  0x63A5  # <CJK>
0x6F49  0x647A  # <CJK>
0x6F4A  0x8776  # <CJK>
0x6F4B  0x4E01  # <CJK>
0x6F4C  0x4E95  # <CJK>
0x6F4D  0x4EAD  # <CJK>
0x6F4E  0x505C  # <CJK>
0x6F4F  0x5075  # <CJK>
0x6F50  0x5448  # <CJK>
0x6F51  0x59C3  # <CJK>
0x6F52  0x5B9A  # <CJK>
0x6F53  0x5E40  # <CJK>
0x6F54  0x5EAD  # <CJK>
0x6F55  0x5EF7  # <CJK>
0x6F56  0x5F81  # <CJK>
0x6F57  0x60C5  # <CJK>
0x6F58  0x633A  # <CJK>
0x6F59  0x653F  # <CJK>
0x6F5A  0x6574  # <CJK>
0x6F5B  0x65CC  # <CJK>
0x6F5C  0x6676  # <CJK>
0x6F5D  0x6678  # <CJK>
0x6F5E  0x67FE  # <CJK>
0x6F5F  0x6968  # <CJK>
0x6F60  0x6A89  # <CJK>
0x6F61  0x6B63  # <CJK>
0x6F62  0x6C40  # <CJK>
0x6F63  0x6DC0  # <CJK>
0x6F64  0x6DE8  # <CJK>
0x6F65  0x6E1F  # <CJK>
0x6F66  0x6E5E  # <CJK>
0x6F67  0x701E  # <CJK>
0x6F68  0x70A1  # <CJK>
0x6F69  0x738E  # <CJK>
0x6F6A  0x73FD  # <CJK>
0x6F6B  0x753A  # <CJK>
0x6F6C  0x775B  # <CJK>
0x6F6D  0x7887  # <CJK>
0x6F6E  0x798E  # <CJK>
0x6F6F  0x7A0B  # <CJK>
0x6F70  0x7A7D  # <CJK>
0x6F71  0x7CBE  # <CJK>
0x6F72  0x7D8E  # <CJK>
0x6F73  0x8247  # <CJK>
0x6F74  0x8A02  # <CJK>
0x6F75  0x8AEA  # <CJK>
0x6F76  0x8C9E  # <CJK>
0x6F77  0x912D  # <CJK>
0x6F78  0x914A  # <CJK>
0x6F79  0x91D8  # <CJK>
0x6F7A  0x9266  # <CJK>
0x6F7B  0x92CC  # <CJK>
0x6F7C  0x9320  # <CJK>
0x6F7D  0x9706  # <CJK>
0x6F7E  0x9756  # <CJK>
0x7021  0x975C  # <CJK>
0x7022  0x9802  # <CJK>
0x7023  0x9F0E  # <CJK>
0x7024  0x5236  # <CJK>
0x7025  0x5291  # <CJK>
0x7026  0x557C  # <CJK>
0x7027  0x5824  # <CJK>
0x7028  0x5E1D  # <CJK>
0x7029  0x5F1F  # <CJK>
0x702A  0x608C  # <CJK>
0x702B  0x63D0  # <CJK>
0x702C  0x68AF  # <CJK>
0x702D  0x6FDF  # <CJK>
0x702E  0x796D  # <CJK>
0x702F  0x7B2C  # <CJK>
0x7030  0x81CD  # <CJK>
0x7031  0x85BA  # <CJK>
0x7032  0x88FD  # <CJK>
0x7033  0x8AF8  # <CJK>
0x7034  0x8E44  # <CJK>
0x7035  0x918D  # <CJK>
0x7036  0x9664  # <CJK>
0x7037  0x969B  # <CJK>
0x7038  0x973D  # <CJK>
0x7039  0x984C  # <CJK>
0x703A  0x9F4A  # <CJK>
0x703B  0x4FCE  # <CJK>
0x703C  0x5146  # <CJK>
0x703D  0x51CB  # <CJK>
0x703E  0x52A9  # <CJK>
0x703F  0x5632  # <CJK>
0x7040  0x5F14  # <CJK>
0x7041  0x5F6B  # <CJK>
0x7042  0x63AA  # <CJK>
0x7043  0x64CD  # <CJK>
0x7044  0x65E9  # <CJK>
0x7045  0x6641  # <CJK>
0x7046  0x66FA  # <CJK>
0x7047  0x66F9  # <CJK>
0x7048  0x671D  # <CJK>
0x7049  0x689D  # <CJK>
0x704A  0x68D7  # <CJK>
0x704B  0x69FD  # <CJK>
0x704C  0x6F15  # <CJK>
0x704D  0x6F6E  # <CJK>
0x704E  0x7167  # <CJK>
0x704F  0x71E5  # <CJK>
0x7050  0x722A  # <CJK>
0x7051  0x74AA  # <CJK>
0x7052  0x773A  # <CJK>
0x7053  0x7956  # <CJK>
0x7054  0x795A  # <CJK>
0x7055  0x79DF  # <CJK>
0x7056  0x7A20  # <CJK>
0x7057  0x7A95  # <CJK>
0x7058  0x7C97  # <CJK>
0x7059  0x7CDF  # <CJK>
0x705A  0x7D44  # <CJK>
0x705B  0x7E70  # <CJK>
0x705C  0x8087  # <CJK>
0x705D  0x85FB  # <CJK>
0x705E  0x86A4  # <CJK>
0x705F  0x8A54  # <CJK>
0x7060  0x8ABF  # <CJK>
0x7061  0x8D99  # <CJK>
0x7062  0x8E81  # <CJK>
0x7063  0x9020  # <CJK>
0x7064  0x906D  # <CJK>
0x7065  0x91E3  # <CJK>
0x7066  0x963B  # <CJK>
0x7067  0x96D5  # <CJK>
0x7068  0x9CE5  # <CJK>
0x7069  0x65CF  # <CJK>
0x706A  0x7C07  # <CJK>
0x706B  0x8DB3  # <CJK>
0x706C  0x93C3  # <CJK>
0x706D  0x5B58  # <CJK>
0x706E  0x5C0A  # <CJK>
0x706F  0x5352  # <CJK>
0x7070  0x62D9  # <CJK>
0x7071  0x731D  # <CJK>
0x7072  0x5027  # <CJK>
0x7073  0x5B97  # <CJK>
0x7074  0x5F9E  # <CJK>
0x7075  0x60B0  # <CJK>
0x7076  0x616B  # <CJK>
0x7077  0x68D5  # <CJK>
0x7078  0x6DD9  # <CJK>
0x7079  0x742E  # <CJK>
0x707A  0x7A2E  # <CJK>
0x707B  0x7D42  # <CJK>
0x707C  0x7D9C  # <CJK>
0x707D  0x7E31  # <CJK>
0x707E  0x816B  # <CJK>
0x7121  0x8E2A  # <CJK>
0x7122  0x8E35  # <CJK>
0x7123  0x937E  # <CJK>
0x7124  0x9418  # <CJK>
0x7125  0x4F50  # <CJK>
0x7126  0x5750  # <CJK>
0x7127  0x5DE6  # <CJK>
0x7128  0x5EA7  # <CJK>
0x7129  0x632B  # <CJK>
0x712A  0x7F6A  # <CJK>
0x712B  0x4E3B  # <CJK>
0x712C  0x4F4F  # <CJK>
0x712D  0x4F8F  # <CJK>
0x712E  0x505A  # <CJK>
0x712F  0x59DD  # <CJK>
0x7130  0x80C4  # <CJK>
0x7131  0x546A  # <CJK>
0x7132  0x5468  # <CJK>
0x7133  0x55FE  # <CJK>
0x7134  0x594F  # <CJK>
0x7135  0x5B99  # <CJK>
0x7136  0x5DDE  # <CJK>
0x7137  0x5EDA  # <CJK>
0x7138  0x665D  # <CJK>
0x7139  0x6731  # <CJK>
0x713A  0x67F1  # <CJK>
0x713B  0x682A  # <CJK>
0x713C  0x6CE8  # <CJK>
0x713D  0x6D32  # <CJK>
0x713E  0x6E4A  # <CJK>
0x713F  0x6F8D  # <CJK>
0x7140  0x70B7  # <CJK>
0x7141  0x73E0  # <CJK>
0x7142  0x7587  # <CJK>
0x7143  0x7C4C  # <CJK>
0x7144  0x7D02  # <CJK>
0x7145  0x7D2C  # <CJK>
0x7146  0x7DA2  # <CJK>
0x7147  0x821F  # <CJK>
0x7148  0x86DB  # <CJK>
0x7149  0x8A3B  # <CJK>
0x714A  0x8A85  # <CJK>
0x714B  0x8D70  # <CJK>
0x714C  0x8E8A  # <CJK>
0x714D  0x8F33  # <CJK>
0x714E  0x9031  # <CJK>
0x714F  0x914E  # <CJK>
0x7150  0x9152  # <CJK>
0x7151  0x9444  # <CJK>
0x7152  0x99D0  # <CJK>
0x7153  0x7AF9  # <CJK>
0x7154  0x7CA5  # <CJK>
0x7155  0x4FCA  # <CJK>
0x7156  0x5101  # <CJK>
0x7157  0x51C6  # <CJK>
0x7158  0x57C8  # <CJK>
0x7159  0x5BEF  # <CJK>
0x715A  0x5CFB  # <CJK>
0x715B  0x6659  # <CJK>
0x715C  0x6A3D  # <CJK>
0x715D  0x6D5A  # <CJK>
0x715E  0x6E96  # <CJK>
0x715F  0x6FEC  # <CJK>
0x7160  0x710C  # <CJK>
0x7161  0x756F  # <CJK>
0x7162  0x7AE3  # <CJK>
0x7163  0x8822  # <CJK>
0x7164  0x9021  # <CJK>
0x7165  0x9075  # <CJK>
0x7166  0x96CB  # <CJK>
0x7167  0x99FF  # <CJK>
0x7168  0x8301  # <CJK>
0x7169  0x4E2D  # <CJK>
0x716A  0x4EF2  # <CJK>
0x716B  0x8846  # <CJK>
0x716C  0x91CD  # <CJK>
0x716D  0x537D  # <CJK>
0x716E  0x6ADB  # <CJK>
0x716F  0x696B  # <CJK>
0x7170  0x6C41  # <CJK>
0x7171  0x847A  # <CJK>
0x7172  0x589E  # <CJK>
0x7173  0x618E  # <CJK>
0x7174  0x66FE  # <CJK>
0x7175  0x62EF  # <CJK>
0x7176  0x70DD  # <CJK>
0x7177  0x7511  # <CJK>
0x7178  0x75C7  # <CJK>
0x7179  0x7E52  # <CJK>
0x717A  0x84B8  # <CJK>
0x717B  0x8B49  # <CJK>
0x717C  0x8D08  # <CJK>
0x717D  0x4E4B  # <CJK>
0x717E  0x53EA  # <CJK>
0x7221  0x54AB  # <CJK>
0x7222  0x5730  # <CJK>
0x7223  0x5740  # <CJK>
0x7224  0x5FD7  # <CJK>
0x7225  0x6301  # <CJK>
0x7226  0x6307  # <CJK>
0x7227  0x646F  # <CJK>
0x7228  0x652F  # <CJK>
0x7229  0x65E8  # <CJK>
0x722A  0x667A  # <CJK>
0x722B  0x679D  # <CJK>
0x722C  0x67B3  # <CJK>
0x722D  0x6B62  # <CJK>
0x722E  0x6C60  # <CJK>
0x722F  0x6C9A  # <CJK>
0x7230  0x6F2C  # <CJK>
0x7231  0x77E5  # <CJK>
0x7232  0x7825  # <CJK>
0x7233  0x7949  # <CJK>
0x7234  0x7957  # <CJK>
0x7235  0x7D19  # <CJK>
0x7236  0x80A2  # <CJK>
0x7237  0x8102  # <CJK>
0x7238  0x81F3  # <CJK>
0x7239  0x829D  # <CJK>
0x723A  0x82B7  # <CJK>
0x723B  0x8718  # <CJK>
0x723C  0x8A8C  # <CJK>
0x723D  0xF9FC  # <CJK>
0x723E  0x8D04  # <CJK>
0x723F  0x8DBE  # <CJK>
0x7240  0x9072  # <CJK>
0x7241  0x76F4  # <CJK>
0x7242  0x7A19  # <CJK>
0x7243  0x7A37  # <CJK>
0x7244  0x7E54  # <CJK>
0x7245  0x8077  # <CJK>
0x7246  0x5507  # <CJK>
0x7247  0x55D4  # <CJK>
0x7248  0x5875  # <CJK>
0x7249  0x632F  # <CJK>
0x724A  0x6422  # <CJK>
0x724B  0x6649  # <CJK>
0x724C  0x664B  # <CJK>
0x724D  0x686D  # <CJK>
0x724E  0x699B  # <CJK>
0x724F  0x6B84  # <CJK>
0x7250  0x6D25  # <CJK>
0x7251  0x6EB1  # <CJK>
0x7252  0x73CD  # <CJK>
0x7253  0x7468  # <CJK>
0x7254  0x74A1  # <CJK>
0x7255  0x755B  # <CJK>
0x7256  0x75B9  # <CJK>
0x7257  0x76E1  # <CJK>
0x7258  0x771E  # <CJK>
0x7259  0x778B  # <CJK>
0x725A  0x79E6  # <CJK>
0x725B  0x7E09  # <CJK>
0x725C  0x7E1D  # <CJK>
0x725D  0x81FB  # <CJK>
0x725E  0x852F  # <CJK>
0x725F  0x8897  # <CJK>
0x7260  0x8A3A  # <CJK>
0x7261  0x8CD1  # <CJK>
0x7262  0x8EEB  # <CJK>
0x7263  0x8FB0  # <CJK>
0x7264  0x9032  # <CJK>
0x7265  0x93AD  # <CJK>
0x7266  0x9663  # <CJK>
0x7267  0x9673  # <CJK>
0x7268  0x9707  # <CJK>
0x7269  0x4F84  # <CJK>
0x726A  0x53F1  # <CJK>
0x726B  0x59EA  # <CJK>
0x726C  0x5AC9  # <CJK>
0x726D  0x5E19  # <CJK>
0x726E  0x684E  # <CJK>
0x726F  0x74C6  # <CJK>
0x7270  0x75BE  # <CJK>
0x7271  0x79E9  # <CJK>
0x7272  0x7A92  # <CJK>
0x7273  0x81A3  # <CJK>
0x7274  0x86ED  # <CJK>
0x7275  0x8CEA  # <CJK>
0x7276  0x8DCC  # <CJK>
0x7277  0x8FED  # <CJK>
0x7278  0x659F  # <CJK>
0x7279  0x6715  # <CJK>
0x727A  0xF9FD  # <CJK>
0x727B  0x57F7  # <CJK>
0x727C  0x6F57  # <CJK>
0x727D  0x7DDD  # <CJK>
0x727E  0x8F2F  # <CJK>
0x7321  0x93F6  # <CJK>
0x7322  0x96C6  # <CJK>
0x7323  0x5FB5  # <CJK>
0x7324  0x61F2  # <CJK>
0x7325  0x6F84  # <CJK>
0x7326  0x4E14  # <CJK>
0x7327  0x4F98  # <CJK>
0x7328  0x501F  # <CJK>
0x7329  0x53C9  # <CJK>
0x732A  0x55DF  # <CJK>
0x732B  0x5D6F  # <CJK>
0x732C  0x5DEE  # <CJK>
0x732D  0x6B21  # <CJK>
0x732E  0x6B64  # <CJK>
0x732F  0x78CB  # <CJK>
0x7330  0x7B9A  # <CJK>
0x7331  0xF9FE  # <CJK>
0x7332  0x8E49  # <CJK>
0x7333  0x8ECA  # <CJK>
0x7334  0x906E  # <CJK>
0x7335  0x6349  # <CJK>
0x7336  0x643E  # <CJK>
0x7337  0x7740  # <CJK>
0x7338  0x7A84  # <CJK>
0x7339  0x932F  # <CJK>
0x733A  0x947F  # <CJK>
0x733B  0x9F6A  # <CJK>
0x733C  0x64B0  # <CJK>
0x733D  0x6FAF  # <CJK>
0x733E  0x71E6  # <CJK>
0x733F  0x74A8  # <CJK>
0x7340  0x74DA  # <CJK>
0x7341  0x7AC4  # <CJK>
0x7342  0x7C12  # <CJK>
0x7343  0x7E82  # <CJK>
0x7344  0x7CB2  # <CJK>
0x7345  0x7E98  # <CJK>
0x7346  0x8B9A  # <CJK>
0x7347  0x8D0A  # <CJK>
0x7348  0x947D  # <CJK>
0x7349  0x9910  # <CJK>
0x734A  0x994C  # <CJK>
0x734B  0x5239  # <CJK>
0x734C  0x5BDF  # <CJK>
0x734D  0x64E6  # <CJK>
0x734E  0x672D  # <CJK>
0x734F  0x7D2E  # <CJK>
0x7350  0x50ED  # <CJK>
0x7351  0x53C3  # <CJK>
0x7352  0x5879  # <CJK>
0x7353  0x6158  # <CJK>
0x7354  0x6159  # <CJK>
0x7355  0x61FA  # <CJK>
0x7356  0x65AC  # <CJK>
0x7357  0x7AD9  # <CJK>
0x7358  0x8B92  # <CJK>
0x7359  0x8B96  # <CJK>
0x735A  0x5009  # <CJK>
0x735B  0x5021  # <CJK>
0x735C  0x5275  # <CJK>
0x735D  0x5531  # <CJK>
0x735E  0x5A3C  # <CJK>
0x735F  0x5EE0  # <CJK>
0x7360  0x5F70  # <CJK>
0x7361  0x6134  # <CJK>
0x7362  0x655E  # <CJK>
0x7363  0x660C  # <CJK>
0x7364  0x6636  # <CJK>
0x7365  0x66A2  # <CJK>
0x7366  0x69CD  # <CJK>
0x7367  0x6EC4  # <CJK>
0x7368  0x6F32  # <CJK>
0x7369  0x7316  # <CJK>
0x736A  0x7621  # <CJK>
0x736B  0x7A93  # <CJK>
0x736C  0x8139  # <CJK>
0x736D  0x8259  # <CJK>
0x736E  0x83D6  # <CJK>
0x736F  0x84BC  # <CJK>
0x7370  0x50B5  # <CJK>
0x7371  0x57F0  # <CJK>
0x7372  0x5BC0  # <CJK>
0x7373  0x5BE8  # <CJK>
0x7374  0x5F69  # <CJK>
0x7375  0x63A1  # <CJK>
0x7376  0x7826  # <CJK>
0x7377  0x7DB5  # <CJK>
0x7378  0x83DC  # <CJK>
0x7379  0x8521  # <CJK>
0x737A  0x91C7  # <CJK>
0x737B  0x91F5  # <CJK>
0x737C  0x518A  # <CJK>
0x737D  0x67F5  # <CJK>
0x737E  0x7B56  # <CJK>
0x7421  0x8CAC  # <CJK>
0x7422  0x51C4  # <CJK>
0x7423  0x59BB  # <CJK>
0x7424  0x60BD  # <CJK>
0x7425  0x8655  # <CJK>
0x7426  0x501C  # <CJK>
0x7427  0xF9FF  # <CJK>
0x7428  0x5254  # <CJK>
0x7429  0x5C3A  # <CJK>
0x742A  0x617D  # <CJK>
0x742B  0x621A  # <CJK>
0x742C  0x62D3  # <CJK>
0x742D  0x64F2  # <CJK>
0x742E  0x65A5  # <CJK>
0x742F  0x6ECC  # <CJK>
0x7430  0x7620  # <CJK>
0x7431  0x810A  # <CJK>
0x7432  0x8E60  # <CJK>
0x7433  0x965F  # <CJK>
0x7434  0x96BB  # <CJK>
0x7435  0x4EDF  # <CJK>
0x7436  0x5343  # <CJK>
0x7437  0x5598  # <CJK>
0x7438  0x5929  # <CJK>
0x7439  0x5DDD  # <CJK>
0x743A  0x64C5  # <CJK>
0x743B  0x6CC9  # <CJK>
0x743C  0x6DFA  # <CJK>
0x743D  0x7394  # <CJK>
0x743E  0x7A7F  # <CJK>
0x743F  0x821B  # <CJK>
0x7440  0x85A6  # <CJK>
0x7441  0x8CE4  # <CJK>
0x7442  0x8E10  # <CJK>
0x7443  0x9077  # <CJK>
0x7444  0x91E7  # <CJK>
0x7445  0x95E1  # <CJK>
0x7446  0x9621  # <CJK>
0x7447  0x97C6  # <CJK>
0x7448  0x51F8  # <CJK>
0x7449  0x54F2  # <CJK>
0x744A  0x5586  # <CJK>
0x744B  0x5FB9  # <CJK>
0x744C  0x64A4  # <CJK>
0x744D  0x6F88  # <CJK>
0x744E  0x7DB4  # <CJK>
0x744F  0x8F1F  # <CJK>
0x7450  0x8F4D  # <CJK>
0x7451  0x9435  # <CJK>
0x7452  0x50C9  # <CJK>
0x7453  0x5C16  # <CJK>
0x7454  0x6CBE  # <CJK>
0x7455  0x6DFB  # <CJK>
0x7456  0x751B  # <CJK>
0x7457  0x77BB  # <CJK>
0x7458  0x7C3D  # <CJK>
0x7459  0x7C64  # <CJK>
0x745A  0x8A79  # <CJK>
0x745B  0x8AC2  # <CJK>
0x745C  0x581E  # <CJK>
0x745D  0x59BE  # <CJK>
0x745E  0x5E16  # <CJK>
0x745F  0x6377  # <CJK>
0x7460  0x7252  # <CJK>
0x7461  0x758A  # <CJK>
0x7462  0x776B  # <CJK>
0x7463  0x8ADC  # <CJK>
0x7464  0x8CBC  # <CJK>
0x7465  0x8F12  # <CJK>
0x7466  0x5EF3  # <CJK>
0x7467  0x6674  # <CJK>
0x7468  0x6DF8  # <CJK>
0x7469  0x807D  # <CJK>
0x746A  0x83C1  # <CJK>
0x746B  0x8ACB  # <CJK>
0x746C  0x9751  # <CJK>
0x746D  0x9BD6  # <CJK>
0x746E  0xFA00  # <CJK>
0x746F  0x5243  # <CJK>
0x7470  0x66FF  # <CJK>
0x7471  0x6D95  # <CJK>
0x7472  0x6EEF  # <CJK>
0x7473  0x7DE0  # <CJK>
0x7474  0x8AE6  # <CJK>
0x7475  0x902E  # <CJK>
0x7476  0x905E  # <CJK>
0x7477  0x9AD4  # <CJK>
0x7478  0x521D  # <CJK>
0x7479  0x527F  # <CJK>
0x747A  0x54E8  # <CJK>
0x747B  0x6194  # <CJK>
0x747C  0x6284  # <CJK>
0x747D  0x62DB  # <CJK>
0x747E  0x68A2  # <CJK>
0x7521  0x6912  # <CJK>
0x7522  0x695A  # <CJK>
0x7523  0x6A35  # <CJK>
0x7524  0x7092  # <CJK>
0x7525  0x7126  # <CJK>
0x7526  0x785D  # <CJK>
0x7527  0x7901  # <CJK>
0x7528  0x790E  # <CJK>
0x7529  0x79D2  # <CJK>
0x752A  0x7A0D  # <CJK>
0x752B  0x8096  # <CJK>
0x752C  0x8278  # <CJK>
0x752D  0x82D5  # <CJK>
0x752E  0x8349  # <CJK>
0x752F  0x8549  # <CJK>
0x7530  0x8C82  # <CJK>
0x7531  0x8D85  # <CJK>
0x7532  0x9162  # <CJK>
0x7533  0x918B  # <CJK>
0x7534  0x91AE  # <CJK>
0x7535  0x4FC3  # <CJK>
0x7536  0x56D1  # <CJK>
0x7537  0x71ED  # <CJK>
0x7538  0x77D7  # <CJK>
0x7539  0x8700  # <CJK>
0x753A  0x89F8  # <CJK>
0x753B  0x5BF8  # <CJK>
0x753C  0x5FD6  # <CJK>
0x753D  0x6751  # <CJK>
0x753E  0x90A8  # <CJK>
0x753F  0x53E2  # <CJK>
0x7540  0x585A  # <CJK>
0x7541  0x5BF5  # <CJK>
0x7542  0x60A4  # <CJK>
0x7543  0x6181  # <CJK>
0x7544  0x6460  # <CJK>
0x7545  0x7E3D  # <CJK>
0x7546  0x8070  # <CJK>
0x7547  0x8525  # <CJK>
0x7548  0x9283  # <CJK>
0x7549  0x64AE  # <CJK>
0x754A  0x50AC  # <CJK>
0x754B  0x5D14  # <CJK>
0x754C  0x6700  # <CJK>
0x754D  0x589C  # <CJK>
0x754E  0x62BD  # <CJK>
0x754F  0x63A8  # <CJK>
0x7550  0x690E  # <CJK>
0x7551  0x6978  # <CJK>
0x7552  0x6A1E  # <CJK>
0x7553  0x6E6B  # <CJK>
0x7554  0x76BA  # <CJK>
0x7555  0x79CB  # <CJK>
0x7556  0x82BB  # <CJK>
0x7557  0x8429  # <CJK>
0x7558  0x8ACF  # <CJK>
0x7559  0x8DA8  # <CJK>
0x755A  0x8FFD  # <CJK>
0x755B  0x9112  # <CJK>
0x755C  0x914B  # <CJK>
0x755D  0x919C  # <CJK>
0x755E  0x9310  # <CJK>
0x755F  0x9318  # <CJK>
0x7560  0x939A  # <CJK>
0x7561  0x96DB  # <CJK>
0x7562  0x9A36  # <CJK>
0x7563  0x9C0D  # <CJK>
0x7564  0x4E11  # <CJK>
0x7565  0x755C  # <CJK>
0x7566  0x795D  # <CJK>
0x7567  0x7AFA  # <CJK>
0x7568  0x7B51  # <CJK>
0x7569  0x7BC9  # <CJK>
0x756A  0x7E2E  # <CJK>
0x756B  0x84C4  # <CJK>
0x756C  0x8E59  # <CJK>
0x756D  0x8E74  # <CJK>
0x756E  0x8EF8  # <CJK>
0x756F  0x9010  # <CJK>
0x7570  0x6625  # <CJK>
0x7571  0x693F  # <CJK>
0x7572  0x7443  # <CJK>
0x7573  0x51FA  # <CJK>
0x7574  0x672E  # <CJK>
0x7575  0x9EDC  # <CJK>
0x7576  0x5145  # <CJK>
0x7577  0x5FE0  # <CJK>
0x7578  0x6C96  # <CJK>
0x7579  0x87F2  # <CJK>
0x757A  0x885D  # <CJK>
0x757B  0x8877  # <CJK>
0x757C  0x60B4  # <CJK>
0x757D  0x81B5  # <CJK>
0x757E  0x8403  # <CJK>
0x7621  0x8D05  # <CJK>
0x7622  0x53D6  # <CJK>
0x7623  0x5439  # <CJK>
0x7624  0x5634  # <CJK>
0x7625  0x5A36  # <CJK>
0x7626  0x5C31  # <CJK>
0x7627  0x708A  # <CJK>
0x7628  0x7FE0  # <CJK>
0x7629  0x805A  # <CJK>
0x762A  0x8106  # <CJK>
0x762B  0x81ED  # <CJK>
0x762C  0x8DA3  # <CJK>
0x762D  0x9189  # <CJK>
0x762E  0x9A5F  # <CJK>
0x762F  0x9DF2  # <CJK>
0x7630  0x5074  # <CJK>
0x7631  0x4EC4  # <CJK>
0x7632  0x53A0  # <CJK>
0x7633  0x60FB  # <CJK>
0x7634  0x6E2C  # <CJK>
0x7635  0x5C64  # <CJK>
0x7636  0x4F88  # <CJK>
0x7637  0x5024  # <CJK>
0x7638  0x55E4  # <CJK>
0x7639  0x5CD9  # <CJK>
0x763A  0x5E5F  # <CJK>
0x763B  0x6065  # <CJK>
0x763C  0x6894  # <CJK>
0x763D  0x6CBB  # <CJK>
0x763E  0x6DC4  # <CJK>
0x763F  0x71BE  # <CJK>
0x7640  0x75D4  # <CJK>
0x7641  0x75F4  # <CJK>
0x7642  0x7661  # <CJK>
0x7643  0x7A1A  # <CJK>
0x7644  0x7A49  # <CJK>
0x7645  0x7DC7  # <CJK>
0x7646  0x7DFB  # <CJK>
0x7647  0x7F6E  # <CJK>
0x7648  0x81F4  # <CJK>
0x7649  0x86A9  # <CJK>
0x764A  0x8F1C  # <CJK>
0x764B  0x96C9  # <CJK>
0x764C  0x99B3  # <CJK>
0x764D  0x9F52  # <CJK>
0x764E  0x5247  # <CJK>
0x764F  0x52C5  # <CJK>
0x7650  0x98ED  # <CJK>
0x7651  0x89AA  # <CJK>
0x7652  0x4E03  # <CJK>
0x7653  0x67D2  # <CJK>
0x7654  0x6F06  # <CJK>
0x7655  0x4FB5  # <CJK>
0x7656  0x5BE2  # <CJK>
0x7657  0x6795  # <CJK>
0x7658  0x6C88  # <CJK>
0x7659  0x6D78  # <CJK>
0x765A  0x741B  # <CJK>
0x765B  0x7827  # <CJK>
0x765C  0x91DD  # <CJK>
0x765D  0x937C  # <CJK>
0x765E  0x87C4  # <CJK>
0x765F  0x79E4  # <CJK>
0x7660  0x7A31  # <CJK>
0x7661  0x5FEB  # <CJK>
0x7662  0x4ED6  # <CJK>
0x7663  0x54A4  # <CJK>
0x7664  0x553E  # <CJK>
0x7665  0x58AE  # <CJK>
0x7666  0x59A5  # <CJK>
0x7667  0x60F0  # <CJK>
0x7668  0x6253  # <CJK>
0x7669  0x62D6  # <CJK>
0x766A  0x6736  # <CJK>
0x766B  0x6955  # <CJK>
0x766C  0x8235  # <CJK>
0x766D  0x9640  # <CJK>
0x766E  0x99B1  # <CJK>
0x766F  0x99DD  # <CJK>
0x7670  0x502C  # <CJK>
0x7671  0x5353  # <CJK>
0x7672  0x5544  # <CJK>
0x7673  0x577C  # <CJK>
0x7674  0xFA01  # <CJK>
0x7675  0x6258  # <CJK>
0x7676  0xFA02  # <CJK>
0x7677  0x64E2  # <CJK>
0x7678  0x666B  # <CJK>
0x7679  0x67DD  # <CJK>
0x767A  0x6FC1  # <CJK>
0x767B  0x6FEF  # <CJK>
0x767C  0x7422  # <CJK>
0x767D  0x7438  # <CJK>
0x767E  0x8A17  # <CJK>
0x7721  0x9438  # <CJK>
0x7722  0x5451  # <CJK>
0x7723  0x5606  # <CJK>
0x7724  0x5766  # <CJK>
0x7725  0x5F48  # <CJK>
0x7726  0x619A  # <CJK>
0x7727  0x6B4E  # <CJK>
0x7728  0x7058  # <CJK>
0x7729  0x70AD  # <CJK>
0x772A  0x7DBB  # <CJK>
0x772B  0x8A95  # <CJK>
0x772C  0x596A  # <CJK>
0x772D  0x812B  # <CJK>
0x772E  0x63A2  # <CJK>
0x772F  0x7708  # <CJK>
0x7730  0x803D  # <CJK>
0x7731  0x8CAA  # <CJK>
0x7732  0x5854  # <CJK>
0x7733  0x642D  # <CJK>
0x7734  0x69BB  # <CJK>
0x7735  0x5B95  # <CJK>
0x7736  0x5E11  # <CJK>
0x7737  0x6E6F  # <CJK>
0x7738  0xFA03  # <CJK>
0x7739  0x8569  # <CJK>
0x773A  0x514C  # <CJK>
0x773B  0x53F0  # <CJK>
0x773C  0x592A  # <CJK>
0x773D  0x6020  # <CJK>
0x773E  0x614B  # <CJK>
0x773F  0x6B86  # <CJK>
0x7740  0x6C70  # <CJK>
0x7741  0x6CF0  # <CJK>
0x7742  0x7B1E  # <CJK>
0x7743  0x80CE  # <CJK>
0x7744  0x82D4  # <CJK>
0x7745  0x8DC6  # <CJK>
0x7746  0x90B0  # <CJK>
0x7747  0x98B1  # <CJK>
0x7748  0xFA04  # <CJK>
0x7749  0x64C7  # <CJK>
0x774A  0x6FA4  # <CJK>
0x774B  0x6491  # <CJK>
0x774C  0x6504  # <CJK>
0x774D  0x514E  # <CJK>
0x774E  0x5410  # <CJK>
0x774F  0x571F  # <CJK>
0x7750  0x8A0E  # <CJK>
0x7751  0x615F  # <CJK>
0x7752  0x6876  # <CJK>
0x7753  0xFA05  # <CJK>
0x7754  0x75DB  # <CJK>
0x7755  0x7B52  # <CJK>
0x7756  0x7D71  # <CJK>
0x7757  0x901A  # <CJK>
0x7758  0x5806  # <CJK>
0x7759  0x69CC  # <CJK>
0x775A  0x817F  # <CJK>
0x775B  0x892A  # <CJK>
0x775C  0x9000  # <CJK>
0x775D  0x9839  # <CJK>
0x775E  0x5078  # <CJK>
0x775F  0x5957  # <CJK>
0x7760  0x59AC  # <CJK>
0x7761  0x6295  # <CJK>
0x7762  0x900F  # <CJK>
0x7763  0x9B2A  # <CJK>
0x7764  0x615D  # <CJK>
0x7765  0x7279  # <CJK>
0x7766  0x95D6  # <CJK>
0x7767  0x5761  # <CJK>
0x7768  0x5A46  # <CJK>
0x7769  0x5DF4  # <CJK>
0x776A  0x628A  # <CJK>
0x776B  0x64AD  # <CJK>
0x776C  0x64FA  # <CJK>
0x776D  0x6777  # <CJK>
0x776E  0x6CE2  # <CJK>
0x776F  0x6D3E  # <CJK>
0x7770  0x722C  # <CJK>
0x7771  0x7436  # <CJK>
0x7772  0x7834  # <CJK>
0x7773  0x7F77  # <CJK>
0x7774  0x82AD  # <CJK>
0x7775  0x8DDB  # <CJK>
0x7776  0x9817  # <CJK>
0x7777  0x5224  # <CJK>
0x7778  0x5742  # <CJK>
0x7779  0x677F  # <CJK>
0x777A  0x7248  # <CJK>
0x777B  0x74E3  # <CJK>
0x777C  0x8CA9  # <CJK>
0x777D  0x8FA6  # <CJK>
0x777E  0x9211  # <CJK>
0x7821  0x962A  # <CJK>
0x7822  0x516B  # <CJK>
0x7823  0x53ED  # <CJK>
0x7824  0x634C  # <CJK>
0x7825  0x4F69  # <CJK>
0x7826  0x5504  # <CJK>
0x7827  0x6096  # <CJK>
0x7828  0x6557  # <CJK>
0x7829  0x6C9B  # <CJK>
0x782A  0x6D7F  # <CJK>
0x782B  0x724C  # <CJK>
0x782C  0x72FD  # <CJK>
0x782D  0x7A17  # <CJK>
0x782E  0x8987  # <CJK>
0x782F  0x8C9D  # <CJK>
0x7830  0x5F6D  # <CJK>
0x7831  0x6F8E  # <CJK>
0x7832  0x70F9  # <CJK>
0x7833  0x81A8  # <CJK>
0x7834  0x610E  # <CJK>
0x7835  0x4FBF  # <CJK>
0x7836  0x504F  # <CJK>
0x7837  0x6241  # <CJK>
0x7838  0x7247  # <CJK>
0x7839  0x7BC7  # <CJK>
0x783A  0x7DE8  # <CJK>
0x783B  0x7FE9  # <CJK>
0x783C  0x904D  # <CJK>
0x783D  0x97AD  # <CJK>
0x783E  0x9A19  # <CJK>
0x783F  0x8CB6  # <CJK>
0x7840  0x576A  # <CJK>
0x7841  0x5E73  # <CJK>
0x7842  0x67B0  # <CJK>
0x7843  0x840D  # <CJK>
0x7844  0x8A55  # <CJK>
0x7845  0x5420  # <CJK>
0x7846  0x5B16  # <CJK>
0x7847  0x5E63  # <CJK>
0x7848  0x5EE2  # <CJK>
0x7849  0x5F0A  # <CJK>
0x784A  0x6583  # <CJK>
0x784B  0x80BA  # <CJK>
0x784C  0x853D  # <CJK>
0x784D  0x9589  # <CJK>
0x784E  0x965B  # <CJK>
0x784F  0x4F48  # <CJK>
0x7850  0x5305  # <CJK>
0x7851  0x530D  # <CJK>
0x7852  0x530F  # <CJK>
0x7853  0x5486  # <CJK>
0x7854  0x54FA  # <CJK>
0x7855  0x5703  # <CJK>
0x7856  0x5E03  # <CJK>
0x7857  0x6016  # <CJK>
0x7858  0x629B  # <CJK>
0x7859  0x62B1  # <CJK>
0x785A  0x6355  # <CJK>
0x785B  0xFA06  # <CJK>
0x785C  0x6CE1  # <CJK>
0x785D  0x6D66  # <CJK>
0x785E  0x75B1  # <CJK>
0x785F  0x7832  # <CJK>
0x7860  0x80DE  # <CJK>
0x7861  0x812F  # <CJK>
0x7862  0x82DE  # <CJK>
0x7863  0x8461  # <CJK>
0x7864  0x84B2  # <CJK>
0x7865  0x888D  # <CJK>
0x7866  0x8912  # <CJK>
0x7867  0x900B  # <CJK>
0x7868  0x92EA  # <CJK>
0x7869  0x98FD  # <CJK>
0x786A  0x9B91  # <CJK>
0x786B  0x5E45  # <CJK>
0x786C  0x66B4  # <CJK>
0x786D  0x66DD  # <CJK>
0x786E  0x7011  # <CJK>
0x786F  0x7206  # <CJK>
0x7870  0xFA07  # <CJK>
0x7871  0x4FF5  # <CJK>
0x7872  0x527D  # <CJK>
0x7873  0x5F6A  # <CJK>
0x7874  0x6153  # <CJK>
0x7875  0x6753  # <CJK>
0x7876  0x6A19  # <CJK>
0x7877  0x6F02  # <CJK>
0x7878  0x74E2  # <CJK>
0x7879  0x7968  # <CJK>
0x787A  0x8868  # <CJK>
0x787B  0x8C79  # <CJK>
0x787C  0x98C7  # <CJK>
0x787D  0x98C4  # <CJK>
0x787E  0x9A43  # <CJK>
0x7921  0x54C1  # <CJK>
0x7922  0x7A1F  # <CJK>
0x7923  0x6953  # <CJK>
0x7924  0x8AF7  # <CJK>
0x7925  0x8C4A  # <CJK>
0x7926  0x98A8  # <CJK>
0x7927  0x99AE  # <CJK>
0x7928  0x5F7C  # <CJK>
0x7929  0x62AB  # <CJK>
0x792A  0x75B2  # <CJK>
0x792B  0x76AE  # <CJK>
0x792C  0x88AB  # <CJK>
0x792D  0x907F  # <CJK>
0x792E  0x9642  # <CJK>
0x792F  0x5339  # <CJK>
0x7930  0x5F3C  # <CJK>
0x7931  0x5FC5  # <CJK>
0x7932  0x6CCC  # <CJK>
0x7933  0x73CC  # <CJK>
0x7934  0x7562  # <CJK>
0x7935  0x758B  # <CJK>
0x7936  0x7B46  # <CJK>
0x7937  0x82FE  # <CJK>
0x7938  0x999D  # <CJK>
0x7939  0x4E4F  # <CJK>
0x793A  0x903C  # <CJK>
0x793B  0x4E0B  # <CJK>
0x793C  0x4F55  # <CJK>
0x793D  0x53A6  # <CJK>
0x793E  0x590F  # <CJK>
0x793F  0x5EC8  # <CJK>
0x7940  0x6630  # <CJK>
0x7941  0x6CB3  # <CJK>
0x7942  0x7455  # <CJK>
0x7943  0x8377  # <CJK>
0x7944  0x8766  # <CJK>
0x7945  0x8CC0  # <CJK>
0x7946  0x9050  # <CJK>
0x7947  0x971E  # <CJK>
0x7948  0x9C15  # <CJK>
0x7949  0x58D1  # <CJK>
0x794A  0x5B78  # <CJK>
0x794B  0x8650  # <CJK>
0x794C  0x8B14  # <CJK>
0x794D  0x9DB4  # <CJK>
0x794E  0x5BD2  # <CJK>
0x794F  0x6068  # <CJK>
0x7950  0x608D  # <CJK>
0x7951  0x65F1  # <CJK>
0x7952  0x6C57  # <CJK>
0x7953  0x6F22  # <CJK>
0x7954  0x6FA3  # <CJK>
0x7955  0x701A  # <CJK>
0x7956  0x7F55  # <CJK>
0x7957  0x7FF0  # <CJK>
0x7958  0x9591  # <CJK>
0x7959  0x9592  # <CJK>
0x795A  0x9650  # <CJK>
0x795B  0x97D3  # <CJK>
0x795C  0x5272  # <CJK>
0x795D  0x8F44  # <CJK>
0x795E  0x51FD  # <CJK>
0x795F  0x542B  # <CJK>
0x7960  0x54B8  # <CJK>
0x7961  0x5563  # <CJK>
0x7962  0x558A  # <CJK>
0x7963  0x6ABB  # <CJK>
0x7964  0x6DB5  # <CJK>
0x7965  0x7DD8  # <CJK>
0x7966  0x8266  # <CJK>
0x7967  0x929C  # <CJK>
0x7968  0x9677  # <CJK>
0x7969  0x9E79  # <CJK>
0x796A  0x5408  # <CJK>
0x796B  0x54C8  # <CJK>
0x796C  0x76D2  # <CJK>
0x796D  0x86E4  # <CJK>
0x796E  0x95A4  # <CJK>
0x796F  0x95D4  # <CJK>
0x7970  0x965C  # <CJK>
0x7971  0x4EA2  # <CJK>
0x7972  0x4F09  # <CJK>
0x7973  0x59EE  # <CJK>
0x7974  0x5AE6  # <CJK>
0x7975  0x5DF7  # <CJK>
0x7976  0x6052  # <CJK>
0x7977  0x6297  # <CJK>
0x7978  0x676D  # <CJK>
0x7979  0x6841  # <CJK>
0x797A  0x6C86  # <CJK>
0x797B  0x6E2F  # <CJK>
0x797C  0x7F38  # <CJK>
0x797D  0x809B  # <CJK>
0x797E  0x822A  # <CJK>
0x7A21  0xFA08  # <CJK>
0x7A22  0xFA09  # <CJK>
0x7A23  0x9805  # <CJK>
0x7A24  0x4EA5  # <CJK>
0x7A25  0x5055  # <CJK>
0x7A26  0x54B3  # <CJK>
0x7A27  0x5793  # <CJK>
0x7A28  0x595A  # <CJK>
0x7A29  0x5B69  # <CJK>
0x7A2A  0x5BB3  # <CJK>
0x7A2B  0x61C8  # <CJK>
0x7A2C  0x6977  # <CJK>
0x7A2D  0x6D77  # <CJK>
0x7A2E  0x7023  # <CJK>
0x7A2F  0x87F9  # <CJK>
0x7A30  0x89E3  # <CJK>
0x7A31  0x8A72  # <CJK>
0x7A32  0x8AE7  # <CJK>
0x7A33  0x9082  # <CJK>
0x7A34  0x99ED  # <CJK>
0x7A35  0x9AB8  # <CJK>
0x7A36  0x52BE  # <CJK>
0x7A37  0x6838  # <CJK>
0x7A38  0x5016  # <CJK>
0x7A39  0x5E78  # <CJK>
0x7A3A  0x674F  # <CJK>
0x7A3B  0x8347  # <CJK>
0x7A3C  0x884C  # <CJK>
0x7A3D  0x4EAB  # <CJK>
0x7A3E  0x5411  # <CJK>
0x7A3F  0x56AE  # <CJK>
0x7A40  0x73E6  # <CJK>
0x7A41  0x9115  # <CJK>
0x7A42  0x97FF  # <CJK>
0x7A43  0x9909  # <CJK>
0x7A44  0x9957  # <CJK>
0x7A45  0x9999  # <CJK>
0x7A46  0x5653  # <CJK>
0x7A47  0x589F  # <CJK>
0x7A48  0x865B  # <CJK>
0x7A49  0x8A31  # <CJK>
0x7A4A  0x61B2  # <CJK>
0x7A4B  0x6AF6  # <CJK>
0x7A4C  0x737B  # <CJK>
0x7A4D  0x8ED2  # <CJK>
0x7A4E  0x6B47  # <CJK>
0x7A4F  0x96AA  # <CJK>
0x7A50  0x9A57  # <CJK>
0x7A51  0x5955  # <CJK>
0x7A52  0x7200  # <CJK>
0x7A53  0x8D6B  # <CJK>
0x7A54  0x9769  # <CJK>
0x7A55  0x4FD4  # <CJK>
0x7A56  0x5CF4  # <CJK>
0x7A57  0x5F26  # <CJK>
0x7A58  0x61F8  # <CJK>
0x7A59  0x665B  # <CJK>
0x7A5A  0x6CEB  # <CJK>
0x7A5B  0x70AB  # <CJK>
0x7A5C  0x7384  # <CJK>
0x7A5D  0x73B9  # <CJK>
0x7A5E  0x73FE  # <CJK>
0x7A5F  0x7729  # <CJK>
0x7A60  0x774D  # <CJK>
0x7A61  0x7D43  # <CJK>
0x7A62  0x7D62  # <CJK>
0x7A63  0x7E23  # <CJK>
0x7A64  0x8237  # <CJK>
0x7A65  0x8852  # <CJK>
0x7A66  0xFA0A  # <CJK>
0x7A67  0x8CE2  # <CJK>
0x7A68  0x9249  # <CJK>
0x7A69  0x986F  # <CJK>
0x7A6A  0x5B51  # <CJK>
0x7A6B  0x7A74  # <CJK>
0x7A6C  0x8840  # <CJK>
0x7A6D  0x9801  # <CJK>
0x7A6E  0x5ACC  # <CJK>
0x7A6F  0x4FE0  # <CJK>
0x7A70  0x5354  # <CJK>
0x7A71  0x593E  # <CJK>
0x7A72  0x5CFD  # <CJK>
0x7A73  0x633E  # <CJK>
0x7A74  0x6D79  # <CJK>
0x7A75  0x72F9  # <CJK>
0x7A76  0x8105  # <CJK>
0x7A77  0x8107  # <CJK>
0x7A78  0x83A2  # <CJK>
0x7A79  0x92CF  # <CJK>
0x7A7A  0x9830  # <CJK>
0x7A7B  0x4EA8  # <CJK>
0x7A7C  0x5144  # <CJK>
0x7A7D  0x5211  # <CJK>
0x7A7E  0x578B  # <CJK>
0x7B21  0x5F62  # <CJK>
0x7B22  0x6CC2  # <CJK>
0x7B23  0x6ECE  # <CJK>
0x7B24  0x7005  # <CJK>
0x7B25  0x7050  # <CJK>
0x7B26  0x70AF  # <CJK>
0x7B27  0x7192  # <CJK>
0x7B28  0x73E9  # <CJK>
0x7B29  0x7469  # <CJK>
0x7B2A  0x834A  # <CJK>
0x7B2B  0x87A2  # <CJK>
0x7B2C  0x8861  # <CJK>
0x7B2D  0x9008  # <CJK>
0x7B2E  0x90A2  # <CJK>
0x7B2F  0x93A3  # <CJK>
0x7B30  0x99A8  # <CJK>
0x7B31  0x516E  # <CJK>
0x7B32  0x5F57  # <CJK>
0x7B33  0x60E0  # <CJK>
0x7B34  0x6167  # <CJK>
0x7B35  0x66B3  # <CJK>
0x7B36  0x8559  # <CJK>
0x7B37  0x8E4A  # <CJK>
0x7B38  0x91AF  # <CJK>
0x7B39  0x978B  # <CJK>
0x7B3A  0x4E4E  # <CJK>
0x7B3B  0x4E92  # <CJK>
0x7B3C  0x547C  # <CJK>
0x7B3D  0x58D5  # <CJK>
0x7B3E  0x58FA  # <CJK>
0x7B3F  0x597D  # <CJK>
0x7B40  0x5CB5  # <CJK>
0x7B41  0x5F27  # <CJK>
0x7B42  0x6236  # <CJK>
0x7B43  0x6248  # <CJK>
0x7B44  0x660A  # <CJK>
0x7B45  0x6667  # <CJK>
0x7B46  0x6BEB  # <CJK>
0x7B47  0x6D69  # <CJK>
0x7B48  0x6DCF  # <CJK>
0x7B49  0x6E56  # <CJK>
0x7B4A  0x6EF8  # <CJK>
0x7B4B  0x6F94  # <CJK>
0x7B4C  0x6FE0  # <CJK>
0x7B4D  0x6FE9  # <CJK>
0x7B4E  0x705D  # <CJK>
0x7B4F  0x72D0  # <CJK>
0x7B50  0x7425  # <CJK>
0x7B51  0x745A  # <CJK>
0x7B52  0x74E0  # <CJK>
0x7B53  0x7693  # <CJK>
0x7B54  0x795C  # <CJK>
0x7B55  0x7CCA  # <CJK>
0x7B56  0x7E1E  # <CJK>
0x7B57  0x80E1  # <CJK>
0x7B58  0x82A6  # <CJK>
0x7B59  0x846B  # <CJK>
0x7B5A  0x84BF  # <CJK>
0x7B5B  0x864E  # <CJK>
0x7B5C  0x865F  # <CJK>
0x7B5D  0x8774  # <CJK>
0x7B5E  0x8B77  # <CJK>
0x7B5F  0x8C6A  # <CJK>
0x7B60  0x93AC  # <CJK>
0x7B61  0x9800  # <CJK>
0x7B62  0x9865  # <CJK>
0x7B63  0x60D1  # <CJK>
0x7B64  0x6216  # <CJK>
0x7B65  0x9177  # <CJK>
0x7B66  0x5A5A  # <CJK>
0x7B67  0x660F  # <CJK>
0x7B68  0x6DF7  # <CJK>
0x7B69  0x6E3E  # <CJK>
0x7B6A  0x743F  # <CJK>
0x7B6B  0x9B42  # <CJK>
0x7B6C  0x5FFD  # <CJK>
0x7B6D  0x60DA  # <CJK>
0x7B6E  0x7B0F  # <CJK>
0x7B6F  0x54C4  # <CJK>
0x7B70  0x5F18  # <CJK>
0x7B71  0x6C5E  # <CJK>
0x7B72  0x6CD3  # <CJK>
0x7B73  0x6D2A  # <CJK>
0x7B74  0x70D8  # <CJK>
0x7B75  0x7D05  # <CJK>
0x7B76  0x8679  # <CJK>
0x7B77  0x8A0C  # <CJK>
0x7B78  0x9D3B  # <CJK>
0x7B79  0x5316  # <CJK>
0x7B7A  0x548C  # <CJK>
0x7B7B  0x5B05  # <CJK>
0x7B7C  0x6A3A  # <CJK>
0x7B7D  0x706B  # <CJK>
0x7B7E  0x7575  # <CJK>
0x7C21  0x798D  # <CJK>
0x7C22  0x79BE  # <CJK>
0x7C23  0x82B1  # <CJK>
0x7C24  0x83EF  # <CJK>
0x7C25  0x8A71  # <CJK>
0x7C26  0x8B41  # <CJK>
0x7C27  0x8CA8  # <CJK>
0x7C28  0x9774  # <CJK>
0x7C29  0xFA0B  # <CJK>
0x7C2A  0x64F4  # <CJK>
0x7C2B  0x652B  # <CJK>
0x7C2C  0x78BA  # <CJK>
0x7C2D  0x78BB  # <CJK>
0x7C2E  0x7A6B  # <CJK>
0x7C2F  0x4E38  # <CJK>
0x7C30  0x559A  # <CJK>
0x7C31  0x5950  # <CJK>
0x7C32  0x5BA6  # <CJK>
0x7C33  0x5E7B  # <CJK>
0x7C34  0x60A3  # <CJK>
0x7C35  0x63DB  # <CJK>
0x7C36  0x6B61  # <CJK>
0x7C37  0x6665  # <CJK>
0x7C38  0x6853  # <CJK>
0x7C39  0x6E19  # <CJK>
0x7C3A  0x7165  # <CJK>
0x7C3B  0x74B0  # <CJK>
0x7C3C  0x7D08  # <CJK>
0x7C3D  0x9084  # <CJK>
0x7C3E  0x9A69  # <CJK>
0x7C3F  0x9C25  # <CJK>
0x7C40  0x6D3B  # <CJK>
0x7C41  0x6ED1  # <CJK>
0x7C42  0x733E  # <CJK>
0x7C43  0x8C41  # <CJK>
0x7C44  0x95CA  # <CJK>
0x7C45  0x51F0  # <CJK>
0x7C46  0x5E4C  # <CJK>
0x7C47  0x5FA8  # <CJK>
0x7C48  0x604D  # <CJK>
0x7C49  0x60F6  # <CJK>
0x7C4A  0x6130  # <CJK>
0x7C4B  0x614C  # <CJK>
0x7C4C  0x6643  # <CJK>
0x7C4D  0x6644  # <CJK>
0x7C4E  0x69A5  # <CJK>
0x7C4F  0x6CC1  # <CJK>
0x7C50  0x6E5F  # <CJK>
0x7C51  0x6EC9  # <CJK>
0x7C52  0x6F62  # <CJK>
0x7C53  0x714C  # <CJK>
0x7C54  0x749C  # <CJK>
0x7C55  0x7687  # <CJK>
0x7C56  0x7BC1  # <CJK>
0x7C57  0x7C27  # <CJK>
0x7C58  0x8352  # <CJK>
0x7C59  0x8757  # <CJK>
0x7C5A  0x9051  # <CJK>
0x7C5B  0x968D  # <CJK>
0x7C5C  0x9EC3  # <CJK>
0x7C5D  0x532F  # <CJK>
0x7C5E  0x56DE  # <CJK>
0x7C5F  0x5EFB  # <CJK>
0x7C60  0x5F8A  # <CJK>
0x7C61  0x6062  # <CJK>
0x7C62  0x6094  # <CJK>
0x7C63  0x61F7  # <CJK>
0x7C64  0x6666  # <CJK>
0x7C65  0x6703  # <CJK>
0x7C66  0x6A9C  # <CJK>
0x7C67  0x6DEE  # <CJK>
0x7C68  0x6FAE  # <CJK>
0x7C69  0x7070  # <CJK>
0x7C6A  0x736A  # <CJK>
0x7C6B  0x7E6A  # <CJK>
0x7C6C  0x81BE  # <CJK>
0x7C6D  0x8334  # <CJK>
0x7C6E  0x86D4  # <CJK>
0x7C6F  0x8AA8  # <CJK>
0x7C70  0x8CC4  # <CJK>
0x7C71  0x5283  # <CJK>
0x7C72  0x7372  # <CJK>
0x7C73  0x5B96  # <CJK>
0x7C74  0x6A6B  # <CJK>
0x7C75  0x9404  # <CJK>
0x7C76  0x54EE  # <CJK>
0x7C77  0x5686  # <CJK>
0x7C78  0x5B5D  # <CJK>
0x7C79  0x6548  # <CJK>
0x7C7A  0x6585  # <CJK>
0x7C7B  0x66C9  # <CJK>
0x7C7C  0x689F  # <CJK>
0x7C7D  0x6D8D  # <CJK>
0x7C7E  0x6DC6  # <CJK>
0x7D21  0x723B  # <CJK>
0x7D22  0x80B4  # <CJK>
0x7D23  0x9175  # <CJK>
0x7D24  0x9A4D  # <CJK>
0x7D25  0x4FAF  # <CJK>
0x7D26  0x5019  # <CJK>
0x7D27  0x539A  # <CJK>
0x7D28  0x540E  # <CJK>
0x7D29  0x543C  # <CJK>
0x7D2A  0x5589  # <CJK>
0x7D2B  0x55C5  # <CJK>
0x7D2C  0x5E3F  # <CJK>
0x7D2D  0x5F8C  # <CJK>
0x7D2E  0x673D  # <CJK>
0x7D2F  0x7166  # <CJK>
0x7D30  0x73DD  # <CJK>
0x7D31  0x9005  # <CJK>
0x7D32  0x52DB  # <CJK>
0x7D33  0x52F3  # <CJK>
0x7D34  0x5864  # <CJK>
0x7D35  0x58CE  # <CJK>
0x7D36  0x7104  # <CJK>
0x7D37  0x718F  # <CJK>
0x7D38  0x71FB  # <CJK>
0x7D39  0x85B0  # <CJK>
0x7D3A  0x8A13  # <CJK>
0x7D3B  0x6688  # <CJK>
0x7D3C  0x85A8  # <CJK>
0x7D3D  0x55A7  # <CJK>
0x7D3E  0x6684  # <CJK>
0x7D3F  0x714A  # <CJK>
0x7D40  0x8431  # <CJK>
0x7D41  0x5349  # <CJK>
0x7D42  0x5599  # <CJK>
0x7D43  0x6BC1  # <CJK>
0x7D44  0x5F59  # <CJK>
0x7D45  0x5FBD  # <CJK>
0x7D46  0x63EE  # <CJK>
0x7D47  0x6689  # <CJK>
0x7D48  0x7147  # <CJK>
0x7D49  0x8AF1  # <CJK>
0x7D4A  0x8F1D  # <CJK>
0x7D4B  0x9EBE  # <CJK>
0x7D4C  0x4F11  # <CJK>
0x7D4D  0x643A  # <CJK>
0x7D4E  0x70CB  # <CJK>
0x7D4F  0x7566  # <CJK>
0x7D50  0x8667  # <CJK>
0x7D51  0x6064  # <CJK>
0x7D52  0x8B4E  # <CJK>
0x7D53  0x9DF8  # <CJK>
0x7D54  0x5147  # <CJK>
0x7D55  0x51F6  # <CJK>
0x7D56  0x5308  # <CJK>
0x7D57  0x6D36  # <CJK>
0x7D58  0x80F8  # <CJK>
0x7D59  0x9ED1  # <CJK>
0x7D5A  0x6615  # <CJK>
0x7D5B  0x6B23  # <CJK>
0x7D5C  0x7098  # <CJK>
0x7D5D  0x75D5  # <CJK>
0x7D5E  0x5403  # <CJK>
0x7D5F  0x5C79  # <CJK>
0x7D60  0x7D07  # <CJK>
0x7D61  0x8A16  # <CJK>
0x7D62  0x6B20  # <CJK>
0x7D63  0x6B3D  # <CJK>
0x7D64  0x6B46  # <CJK>
0x7D65  0x5438  # <CJK>
0x7D66  0x6070  # <CJK>
0x7D67  0x6D3D  # <CJK>
0x7D68  0x7FD5  # <CJK>
0x7D69  0x8208  # <CJK>
0x7D6A  0x50D6  # <CJK>
0x7D6B  0x51DE  # <CJK>
0x7D6C  0x559C  # <CJK>
0x7D6D  0x566B  # <CJK>
0x7D6E  0x56CD  # <CJK>
0x7D6F  0x59EC  # <CJK>
0x7D70  0x5B09  # <CJK>
0x7D71  0x5E0C  # <CJK>
0x7D72  0x6199  # <CJK>
0x7D73  0x6198  # <CJK>
0x7D74  0x6231  # <CJK>
0x7D75  0x665E  # <CJK>
0x7D76  0x66E6  # <CJK>
0x7D77  0x7199  # <CJK>
0x7D78  0x71B9  # <CJK>
0x7D79  0x71BA  # <CJK>
0x7D7A  0x72A7  # <CJK>
0x7D7B  0x79A7  # <CJK>
0x7D7C  0x7A00  # <CJK>
0x7D7D  0x7FB2  # <CJK>
0x7D7E  0x8A70  # <CJK>

Added tools/encoding/macCentEuro.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
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
#
#   Name:             MacOS_CentralEurope [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <5>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS CentralEurope code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS CentralEurope code order.
#
#   Notes on MacOS CentralEurope:
#   -----------------------------
#
#   This character set is intended to cover the following languages,
#   which are written in Roman script but using a different set of
#   accented characters which are not in the standard MacOS Roman
#   set (MacOS CentralEurope also contains fewer punctuation and
#   math characters than standard MacOS Roman):
#   - several Slavic languages (Czech, Polish, Slovak, Slovenian)
#   - Hungarian
#   - the languages of the Baltic republics (Estonian, Latvian,
#     Lithuanian)
#
#    The MacOS CentralEurope encoding also includes a number of
#    characters needed for the Mac OS user interface (e.g. ellipsis),
#    Mac OS localization (bullet for echoing passwords, copyright
#    sign, etc.), several typographic punctuation symbols, math
#    symbols, etc. All of the characters in MacOS CentralEurope that
#    are also in the MacOS Roman encoding are at the same code point
#    as in MacOS Roman. This improves application compatibility (since
#    some naughty applications hard-code the MacOS Roman code points
#    of certain characters).
#
#    The MacOS CentralEurope encoding is currently used for the
#    following MacOS localizations: Czech, Polish, and Hungarian.
#
##################

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
#
0x80	0x00C4	# LATIN CAPITAL LETTER A WITH DIAERESIS
0x81	0x0100	# LATIN CAPITAL LETTER A WITH MACRON
0x82	0x0101	# LATIN SMALL LETTER A WITH MACRON
0x83	0x00C9	# LATIN CAPITAL LETTER E WITH ACUTE
0x84	0x0104	# LATIN CAPITAL LETTER A WITH OGONEK
0x85	0x00D6	# LATIN CAPITAL LETTER O WITH DIAERESIS
0x86	0x00DC	# LATIN CAPITAL LETTER U WITH DIAERESIS
0x87	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
0x88	0x0105	# LATIN SMALL LETTER A WITH OGONEK
0x89	0x010C	# LATIN CAPITAL LETTER C WITH CARON
0x8A	0x00E4	# LATIN SMALL LETTER A WITH DIAERESIS
0x8B	0x010D	# LATIN SMALL LETTER C WITH CARON
0x8C	0x0106	# LATIN CAPITAL LETTER C WITH ACUTE
0x8D	0x0107	# LATIN SMALL LETTER C WITH ACUTE
0x8E	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
0x8F	0x0179	# LATIN CAPITAL LETTER Z WITH ACUTE
0x90	0x017A	# LATIN SMALL LETTER Z WITH ACUTE
0x91	0x010E	# LATIN CAPITAL LETTER D WITH CARON
0x92	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
0x93	0x010F	# LATIN SMALL LETTER D WITH CARON
0x94	0x0112	# LATIN CAPITAL LETTER E WITH MACRON
0x95	0x0113	# LATIN SMALL LETTER E WITH MACRON
0x96	0x0116	# LATIN CAPITAL LETTER E WITH DOT ABOVE
0x97	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
0x98	0x0117	# LATIN SMALL LETTER E WITH DOT ABOVE
0x99	0x00F4	# LATIN SMALL LETTER O WITH CIRCUMFLEX
0x9A	0x00F6	# LATIN SMALL LETTER O WITH DIAERESIS
0x9B	0x00F5	# LATIN SMALL LETTER O WITH TILDE
0x9C	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
0x9D	0x011A	# LATIN CAPITAL LETTER E WITH CARON
0x9E	0x011B	# LATIN SMALL LETTER E WITH CARON
0x9F	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
0xA0	0x2020	# DAGGER
0xA1	0x00B0	# DEGREE SIGN
0xA2	0x0118	# LATIN CAPITAL LETTER E WITH OGONEK
0xA3	0x00A3	# POUND SIGN
0xA4	0x00A7	# SECTION SIGN
0xA5	0x2022	# BULLET
0xA6	0x00B6	# PILCROW SIGN
0xA7	0x00DF	# LATIN SMALL LETTER SHARP S
0xA8	0x00AE	# REGISTERED SIGN
0xA9	0x00A9	# COPYRIGHT SIGN
0xAA	0x2122	# TRADE MARK SIGN
0xAB	0x0119	# LATIN SMALL LETTER E WITH OGONEK
0xAC	0x00A8	# DIAERESIS
0xAD	0x2260	# NOT EQUAL TO
0xAE	0x0123	# LATIN SMALL LETTER G WITH CEDILLA
0xAF	0x012E	# LATIN CAPITAL LETTER I WITH OGONEK
0xB0	0x012F	# LATIN SMALL LETTER I WITH OGONEK
0xB1	0x012A	# LATIN CAPITAL LETTER I WITH MACRON
0xB2	0x2264	# LESS-THAN OR EQUAL TO
0xB3	0x2265	# GREATER-THAN OR EQUAL TO
0xB4	0x012B	# LATIN SMALL LETTER I WITH MACRON
0xB5	0x0136	# LATIN CAPITAL LETTER K WITH CEDILLA
0xB6	0x2202	# PARTIAL DIFFERENTIAL
0xB7	0x2211	# N-ARY SUMMATION
0xB8	0x0142	# LATIN SMALL LETTER L WITH STROKE
0xB9	0x013B	# LATIN CAPITAL LETTER L WITH CEDILLA
0xBA	0x013C	# LATIN SMALL LETTER L WITH CEDILLA
0xBB	0x013D	# LATIN CAPITAL LETTER L WITH CARON
0xBC	0x013E	# LATIN SMALL LETTER L WITH CARON
0xBD	0x0139	# LATIN CAPITAL LETTER L WITH ACUTE
0xBE	0x013A	# LATIN SMALL LETTER L WITH ACUTE
0xBF	0x0145	# LATIN CAPITAL LETTER N WITH CEDILLA
0xC0	0x0146	# LATIN SMALL LETTER N WITH CEDILLA
0xC1	0x0143	# LATIN CAPITAL LETTER N WITH ACUTE
0xC2	0x00AC	# NOT SIGN
0xC3	0x221A	# SQUARE ROOT
0xC4	0x0144	# LATIN SMALL LETTER N WITH ACUTE
0xC5	0x0147	# LATIN CAPITAL LETTER N WITH CARON
0xC6	0x2206	# INCREMENT
0xC7	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC8	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC9	0x2026	# HORIZONTAL ELLIPSIS
0xCA	0x00A0	# NO-BREAK SPACE
0xCB	0x0148	# LATIN SMALL LETTER N WITH CARON
0xCC	0x0150	# LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
0xCD	0x00D5	# LATIN CAPITAL LETTER O WITH TILDE
0xCE	0x0151	# LATIN SMALL LETTER O WITH DOUBLE ACUTE
0xCF	0x014C	# LATIN CAPITAL LETTER O WITH MACRON
0xD0	0x2013	# EN DASH
0xD1	0x2014	# EM DASH
0xD2	0x201C	# LEFT DOUBLE QUOTATION MARK
0xD3	0x201D	# RIGHT DOUBLE QUOTATION MARK
0xD4	0x2018	# LEFT SINGLE QUOTATION MARK
0xD5	0x2019	# RIGHT SINGLE QUOTATION MARK
0xD6	0x00F7	# DIVISION SIGN
0xD7	0x25CA	# LOZENGE
0xD8	0x014D	# LATIN SMALL LETTER O WITH MACRON
0xD9	0x0154	# LATIN CAPITAL LETTER R WITH ACUTE
0xDA	0x0155	# LATIN SMALL LETTER R WITH ACUTE
0xDB	0x0158	# LATIN CAPITAL LETTER R WITH CARON
0xDC	0x2039	# SINGLE LEFT-POINTING ANGLE QUOTATION MARK
0xDD	0x203A	# SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
0xDE	0x0159	# LATIN SMALL LETTER R WITH CARON
0xDF	0x0156	# LATIN CAPITAL LETTER R WITH CEDILLA
0xE0	0x0157	# LATIN SMALL LETTER R WITH CEDILLA
0xE1	0x0160	# LATIN CAPITAL LETTER S WITH CARON
0xE2	0x201A	# SINGLE LOW-9 QUOTATION MARK
0xE3	0x201E	# DOUBLE LOW-9 QUOTATION MARK
0xE4	0x0161	# LATIN SMALL LETTER S WITH CARON
0xE5	0x015A	# LATIN CAPITAL LETTER S WITH ACUTE
0xE6	0x015B	# LATIN SMALL LETTER S WITH ACUTE
0xE7	0x00C1	# LATIN CAPITAL LETTER A WITH ACUTE
0xE8	0x0164	# LATIN CAPITAL LETTER T WITH CARON
0xE9	0x0165	# LATIN SMALL LETTER T WITH CARON
0xEA	0x00CD	# LATIN CAPITAL LETTER I WITH ACUTE
0xEB	0x017D	# LATIN CAPITAL LETTER Z WITH CARON
0xEC	0x017E	# LATIN SMALL LETTER Z WITH CARON
0xED	0x016A	# LATIN CAPITAL LETTER U WITH MACRON
0xEE	0x00D3	# LATIN CAPITAL LETTER O WITH ACUTE
0xEF	0x00D4	# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xF0	0x016B	# LATIN SMALL LETTER U WITH MACRON
0xF1	0x016E	# LATIN CAPITAL LETTER U WITH RING ABOVE
0xF2	0x00DA	# LATIN CAPITAL LETTER U WITH ACUTE
0xF3	0x016F	# LATIN SMALL LETTER U WITH RING ABOVE
0xF4	0x0170	# LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
0xF5	0x0171	# LATIN SMALL LETTER U WITH DOUBLE ACUTE
0xF6	0x0172	# LATIN CAPITAL LETTER U WITH OGONEK
0xF7	0x0173	# LATIN SMALL LETTER U WITH OGONEK
0xF8	0x00DD	# LATIN CAPITAL LETTER Y WITH ACUTE
0xF9	0x00FD	# LATIN SMALL LETTER Y WITH ACUTE
0xFA	0x0137	# LATIN SMALL LETTER K WITH CEDILLA
0xFB	0x017B	# LATIN CAPITAL LETTER Z WITH DOT ABOVE
0xFC	0x0141	# LATIN CAPITAL LETTER L WITH STROKE
0xFD	0x017C	# LATIN SMALL LETTER Z WITH DOT ABOVE
0xFE	0x0122	# LATIN CAPITAL LETTER G WITH CEDILLA
0xFF	0x02C7	# CARON

Added tools/encoding/macCroatian.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#
#   Name:             MacOS_Croatian [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <6>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Croatian code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Croatian code order.
#
#   One of these mappings requires the use of a corporate character
#   (for the Apple logo character). See the file "MacOS-CorpCharList".
#   NOTE: The graphic image associated with the Apple logo character
#   is not authorized for use without permission of Apple, and
#   unauthorized use might constitute trademark infringement.
#
#   Notes on MacOS Croatian:
#   ------------------------
#
#   The MacOS Croatian encoding shares the script code smRoman
#   (0) with the standard MacOS Roman encoding. To determine if
#   the Croatian encoding is being used, you must check if the
#   system region code is 68, verCroatia (or 25, verYugoCroatian,
#   only used in older systems).
#
#   This character set is a variant of standard MacOS Roman
#   encoding, adding five accented letter case pairs to handle
#   Croatian. It has 20 code point differences from standard
#   MacOS Roman, but only 10 differences in repertoire.
#
##################

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
#
0x80	0x00C4	# LATIN CAPITAL LETTER A WITH DIAERESIS
0x81	0x00C5	# LATIN CAPITAL LETTER A WITH RING ABOVE
0x82	0x00C7	# LATIN CAPITAL LETTER C WITH CEDILLA
0x83	0x00C9	# LATIN CAPITAL LETTER E WITH ACUTE
0x84	0x00D1	# LATIN CAPITAL LETTER N WITH TILDE
0x85	0x00D6	# LATIN CAPITAL LETTER O WITH DIAERESIS
0x86	0x00DC	# LATIN CAPITAL LETTER U WITH DIAERESIS
0x87	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
0x88	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
0x89	0x00E2	# LATIN SMALL LETTER A WITH CIRCUMFLEX
0x8A	0x00E4	# LATIN SMALL LETTER A WITH DIAERESIS
0x8B	0x00E3	# LATIN SMALL LETTER A WITH TILDE
0x8C	0x00E5	# LATIN SMALL LETTER A WITH RING ABOVE
0x8D	0x00E7	# LATIN SMALL LETTER C WITH CEDILLA
0x8E	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
0x8F	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
0x90	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
0x91	0x00EB	# LATIN SMALL LETTER E WITH DIAERESIS
0x92	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
0x93	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
0x94	0x00EE	# LATIN SMALL LETTER I WITH CIRCUMFLEX
0x95	0x00EF	# LATIN SMALL LETTER I WITH DIAERESIS
0x96	0x00F1	# LATIN SMALL LETTER N WITH TILDE
0x97	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
0x98	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
0x99	0x00F4	# LATIN SMALL LETTER O WITH CIRCUMFLEX
0x9A	0x00F6	# LATIN SMALL LETTER O WITH DIAERESIS
0x9B	0x00F5	# LATIN SMALL LETTER O WITH TILDE
0x9C	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
0x9D	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
0x9E	0x00FB	# LATIN SMALL LETTER U WITH CIRCUMFLEX
0x9F	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
0xA0	0x2020	# DAGGER
0xA1	0x00B0	# DEGREE SIGN
0xA2	0x00A2	# CENT SIGN
0xA3	0x00A3	# POUND SIGN
0xA4	0x00A7	# SECTION SIGN
0xA5	0x2022	# BULLET
0xA6	0x00B6	# PILCROW SIGN
0xA7	0x00DF	# LATIN SMALL LETTER SHARP S
0xA8	0x00AE	# REGISTERED SIGN
0xA9	0x0160	# LATIN CAPITAL LETTER S WITH CARON
0xAA	0x2122	# TRADE MARK SIGN
0xAB	0x00B4	# ACUTE ACCENT
0xAC	0x00A8	# DIAERESIS
0xAD	0x2260	# NOT EQUAL TO
0xAE	0x017D	# LATIN CAPITAL LETTER Z WITH CARON
0xAF	0x00D8	# LATIN CAPITAL LETTER O WITH STROKE
0xB0	0x221E	# INFINITY
0xB1	0x00B1	# PLUS-MINUS SIGN
0xB2	0x2264	# LESS-THAN OR EQUAL TO
0xB3	0x2265	# GREATER-THAN OR EQUAL TO
0xB4	0x2206	# INCREMENT
0xB5	0x00B5	# MICRO SIGN
0xB6	0x2202	# PARTIAL DIFFERENTIAL
0xB7	0x2211	# N-ARY SUMMATION
0xB8	0x220F	# N-ARY PRODUCT
0xB9	0x0161	# LATIN SMALL LETTER S WITH CARON
0xBA	0x222B	# INTEGRAL
0xBB	0x00AA	# FEMININE ORDINAL INDICATOR
0xBC	0x00BA	# MASCULINE ORDINAL INDICATOR
0xBD	0x2126	# OHM SIGN
0xBE	0x017E	# LATIN SMALL LETTER Z WITH CARON
0xBF	0x00F8	# LATIN SMALL LETTER O WITH STROKE
0xC0	0x00BF	# INVERTED QUESTION MARK
0xC1	0x00A1	# INVERTED EXCLAMATION MARK
0xC2	0x00AC	# NOT SIGN
0xC3	0x221A	# SQUARE ROOT
0xC4	0x0192	# LATIN SMALL LETTER F WITH HOOK
0xC5	0x2248	# ALMOST EQUAL TO
0xC6	0x0106	# LATIN CAPITAL LETTER C WITH ACUTE
0xC7	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC8	0x010C	# LATIN CAPITAL LETTER C WITH CARON
0xC9	0x2026	# HORIZONTAL ELLIPSIS
0xCA	0x00A0	# NO-BREAK SPACE
0xCB	0x00C0	# LATIN CAPITAL LETTER A WITH GRAVE
0xCC	0x00C3	# LATIN CAPITAL LETTER A WITH TILDE
0xCD	0x00D5	# LATIN CAPITAL LETTER O WITH TILDE
0xCE	0x0152	# LATIN CAPITAL LIGATURE OE
0xCF	0x0153	# LATIN SMALL LIGATURE OE
0xD0	0x0110	# LATIN CAPITAL LETTER D WITH STROKE
0xD1	0x2014	# EM DASH
0xD2	0x201C	# LEFT DOUBLE QUOTATION MARK
0xD3	0x201D	# RIGHT DOUBLE QUOTATION MARK
0xD4	0x2018	# LEFT SINGLE QUOTATION MARK
0xD5	0x2019	# RIGHT SINGLE QUOTATION MARK
0xD6	0x00F7	# DIVISION SIGN
0xD7	0x25CA	# LOZENGE
0xD8	0xF8FF	# Apple logo
0xD9	0x00A9	# COPYRIGHT SIGN
0xDA	0x2044	# FRACTION SLASH
0xDB	0x00A4	# CURRENCY SIGN
0xDC	0x2039	# SINGLE LEFT-POINTING ANGLE QUOTATION MARK
0xDD	0x203A	# SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
0xDE	0x00C6	# LATIN CAPITAL LIGATURE AE
0xDF	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xE0	0x2013	# EN DASH
0xE1	0x00B7	# MIDDLE DOT
0xE2	0x201A	# SINGLE LOW-9 QUOTATION MARK
0xE3	0x201E	# DOUBLE LOW-9 QUOTATION MARK
0xE4	0x2030	# PER MILLE SIGN
0xE5	0x00C2	# LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xE6	0x0107	# LATIN SMALL LETTER C WITH ACUTE
0xE7	0x00C1	# LATIN CAPITAL LETTER A WITH ACUTE
0xE8	0x010D	# LATIN SMALL LETTER C WITH CARON
0xE9	0x00C8	# LATIN CAPITAL LETTER E WITH GRAVE
0xEA	0x00CD	# LATIN CAPITAL LETTER I WITH ACUTE
0xEB	0x00CE	# LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xEC	0x00CF	# LATIN CAPITAL LETTER I WITH DIAERESIS
0xED	0x00CC	# LATIN CAPITAL LETTER I WITH GRAVE
0xEE	0x00D3	# LATIN CAPITAL LETTER O WITH ACUTE
0xEF	0x00D4	# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xF0	0x0111	# LATIN SMALL LETTER D WITH STROKE
0xF1	0x00D2	# LATIN CAPITAL LETTER O WITH GRAVE
0xF2	0x00DA	# LATIN CAPITAL LETTER U WITH ACUTE
0xF3	0x00DB	# LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xF4	0x00D9	# LATIN CAPITAL LETTER U WITH GRAVE
0xF5	0x0131	# LATIN SMALL LETTER DOTLESS I
0xF6	0x02C6	# MODIFIER LETTER CIRCUMFLEX ACCENT
0xF7	0x02DC	# SMALL TILDE
0xF8	0x00AF	# MACRON
0xF9	0x03C0	# GREEK SMALL LETTER PI
0xFA	0x00CB	# LATIN CAPITAL LETTER E WITH DIAERESIS
0xFB	0x02DA	# RING ABOVE
0xFC	0x00B8	# CEDILLA
0xFD	0x00CA	# LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xFE	0x00E6	# LATIN SMALL LIGATURE AE
0xFF	0x02C7	# CARON

Added tools/encoding/macCyrillic.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#
#   Name:             MacOS_Cyrillic [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <5>)
#   Date:             15 April 1995
#   Authors:          Peter Edberg <[email protected]>
#                     Judy Kettenhofen
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Cyrillic code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Cyrillic code order.
#
#   Notes on MacOS Cyrillic:
#   ------------------------
#
#   The MacOS Cyrillic encoding includes the full Cyrillic letter
#   repertoire of ISO 8859-5 (although not at the same code points).
#   This covers most of the Slavic languages written in Cyrillic
#   script.
#
#   The MacOS Cyrillic encoding also includes a number of characters
#   needed for the MacOS user interface (e.g. ellipsis), MacOS
#   localization (bullet for echoing passwords, copyright sign, etc.
#   All of the characters in MacOS Cyrillic that are also in the MacOS
#   Roman encoding are at the same code point as MacOS Roman. This
#   improves application compatibility (since some naughty applications
#   hard-code the MacOS Roman code points of certain characters).
#
#   A variant of MacOS Cyrillic is used for Ukrainian. A separate
#   mapping table is available for Ukrainian.
#
##################

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
#
0x80	0x0410	# CYRILLIC CAPITAL LETTER A
0x81	0x0411	# CYRILLIC CAPITAL LETTER BE
0x82	0x0412	# CYRILLIC CAPITAL LETTER VE
0x83	0x0413	# CYRILLIC CAPITAL LETTER GHE
0x84	0x0414	# CYRILLIC CAPITAL LETTER DE
0x85	0x0415	# CYRILLIC CAPITAL LETTER IE
0x86	0x0416	# CYRILLIC CAPITAL LETTER ZHE
0x87	0x0417	# CYRILLIC CAPITAL LETTER ZE
0x88	0x0418	# CYRILLIC CAPITAL LETTER I
0x89	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
0x8A	0x041A	# CYRILLIC CAPITAL LETTER KA
0x8B	0x041B	# CYRILLIC CAPITAL LETTER EL
0x8C	0x041C	# CYRILLIC CAPITAL LETTER EM
0x8D	0x041D	# CYRILLIC CAPITAL LETTER EN
0x8E	0x041E	# CYRILLIC CAPITAL LETTER O
0x8F	0x041F	# CYRILLIC CAPITAL LETTER PE
0x90	0x0420	# CYRILLIC CAPITAL LETTER ER
0x91	0x0421	# CYRILLIC CAPITAL LETTER ES
0x92	0x0422	# CYRILLIC CAPITAL LETTER TE
0x93	0x0423	# CYRILLIC CAPITAL LETTER U
0x94	0x0424	# CYRILLIC CAPITAL LETTER EF
0x95	0x0425	# CYRILLIC CAPITAL LETTER HA
0x96	0x0426	# CYRILLIC CAPITAL LETTER TSE
0x97	0x0427	# CYRILLIC CAPITAL LETTER CHE
0x98	0x0428	# CYRILLIC CAPITAL LETTER SHA
0x99	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
0x9A	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
0x9B	0x042B	# CYRILLIC CAPITAL LETTER YERU
0x9C	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
0x9D	0x042D	# CYRILLIC CAPITAL LETTER E
0x9E	0x042E	# CYRILLIC CAPITAL LETTER YU
0x9F	0x042F	# CYRILLIC CAPITAL LETTER YA
0xA0	0x2020	# DAGGER
0xA1	0x00B0	# DEGREE SIGN
0xA2	0x00A2	# CENT SIGN
0xA3	0x00A3	# POUND SIGN
0xA4	0x00A7	# SECTION SIGN
0xA5	0x2022	# BULLET
0xA6	0x00B6	# PILCROW SIGN
0xA7	0x0406	# CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
0xA8	0x00AE	# REGISTERED SIGN
0xA9	0x00A9	# COPYRIGHT SIGN
0xAA	0x2122	# TRADE MARK SIGN
0xAB	0x0402	# CYRILLIC CAPITAL LETTER DJE
0xAC	0x0452	# CYRILLIC SMALL LETTER DJE
0xAD	0x2260	# NOT EQUAL TO
0xAE	0x0403	# CYRILLIC CAPITAL LETTER GJE
0xAF	0x0453	# CYRILLIC SMALL LETTER GJE
0xB0	0x221E	# INFINITY
0xB1	0x00B1	# PLUS-MINUS SIGN
0xB2	0x2264	# LESS-THAN OR EQUAL TO
0xB3	0x2265	# GREATER-THAN OR EQUAL TO
0xB4	0x0456	# CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
0xB5	0x00B5	# MICRO SIGN
0xB6	0x2202	# PARTIAL DIFFERENTIAL
0xB7	0x0408	# CYRILLIC CAPITAL LETTER JE
0xB8	0x0404	# CYRILLIC CAPITAL LETTER UKRAINIAN IE
0xB9	0x0454	# CYRILLIC SMALL LETTER UKRAINIAN IE
0xBA	0x0407	# CYRILLIC CAPITAL LETTER YI
0xBB	0x0457	# CYRILLIC SMALL LETTER YI
0xBC	0x0409	# CYRILLIC CAPITAL LETTER LJE
0xBD	0x0459	# CYRILLIC SMALL LETTER LJE
0xBE	0x040A	# CYRILLIC CAPITAL LETTER NJE
0xBF	0x045A	# CYRILLIC SMALL LETTER NJE
0xC0	0x0458	# CYRILLIC SMALL LETTER JE
0xC1	0x0405	# CYRILLIC CAPITAL LETTER DZE
0xC2	0x00AC	# NOT SIGN
0xC3	0x221A	# SQUARE ROOT
0xC4	0x0192	# LATIN SMALL LETTER F WITH HOOK
0xC5	0x2248	# ALMOST EQUAL TO
0xC6	0x2206	# INCREMENT
0xC7	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC8	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC9	0x2026	# HORIZONTAL ELLIPSIS
0xCA	0x00A0	# NO-BREAK SPACE
0xCB	0x040B	# CYRILLIC CAPITAL LETTER TSHE
0xCC	0x045B	# CYRILLIC SMALL LETTER TSHE
0xCD	0x040C	# CYRILLIC CAPITAL LETTER KJE
0xCE	0x045C	# CYRILLIC SMALL LETTER KJE
0xCF	0x0455	# CYRILLIC SMALL LETTER DZE
0xD0	0x2013	# EN DASH
0xD1	0x2014	# EM DASH
0xD2	0x201C	# LEFT DOUBLE QUOTATION MARK
0xD3	0x201D	# RIGHT DOUBLE QUOTATION MARK
0xD4	0x2018	# LEFT SINGLE QUOTATION MARK
0xD5	0x2019	# RIGHT SINGLE QUOTATION MARK
0xD6	0x00F7	# DIVISION SIGN
0xD7	0x201E	# DOUBLE LOW-9 QUOTATION MARK
0xD8	0x040E	# CYRILLIC CAPITAL LETTER SHORT U
0xD9	0x045E	# CYRILLIC SMALL LETTER SHORT U
0xDA	0x040F	# CYRILLIC CAPITAL LETTER DZHE
0xDB	0x045F	# CYRILLIC SMALL LETTER DZHE
0xDC	0x2116	# NUMERO SIGN
0xDD	0x0401	# CYRILLIC CAPITAL LETTER IO
0xDE	0x0451	# CYRILLIC SMALL LETTER IO
0xDF	0x044F	# CYRILLIC SMALL LETTER YA
0xE0	0x0430	# CYRILLIC SMALL LETTER A
0xE1	0x0431	# CYRILLIC SMALL LETTER BE
0xE2	0x0432	# CYRILLIC SMALL LETTER VE
0xE3	0x0433	# CYRILLIC SMALL LETTER GHE
0xE4	0x0434	# CYRILLIC SMALL LETTER DE
0xE5	0x0435	# CYRILLIC SMALL LETTER IE
0xE6	0x0436	# CYRILLIC SMALL LETTER ZHE
0xE7	0x0437	# CYRILLIC SMALL LETTER ZE
0xE8	0x0438	# CYRILLIC SMALL LETTER I
0xE9	0x0439	# CYRILLIC SMALL LETTER SHORT I
0xEA	0x043A	# CYRILLIC SMALL LETTER KA
0xEB	0x043B	# CYRILLIC SMALL LETTER EL
0xEC	0x043C	# CYRILLIC SMALL LETTER EM
0xED	0x043D	# CYRILLIC SMALL LETTER EN
0xEE	0x043E	# CYRILLIC SMALL LETTER O
0xEF	0x043F	# CYRILLIC SMALL LETTER PE
0xF0	0x0440	# CYRILLIC SMALL LETTER ER
0xF1	0x0441	# CYRILLIC SMALL LETTER ES
0xF2	0x0442	# CYRILLIC SMALL LETTER TE
0xF3	0x0443	# CYRILLIC SMALL LETTER U
0xF4	0x0444	# CYRILLIC SMALL LETTER EF
0xF5	0x0445	# CYRILLIC SMALL LETTER HA
0xF6	0x0446	# CYRILLIC SMALL LETTER TSE
0xF7	0x0447	# CYRILLIC SMALL LETTER CHE
0xF8	0x0448	# CYRILLIC SMALL LETTER SHA
0xF9	0x0449	# CYRILLIC SMALL LETTER SHCHA
0xFA	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
0xFB	0x044B	# CYRILLIC SMALL LETTER YERU
0xFC	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
0xFD	0x044D	# CYRILLIC SMALL LETTER E
0xFE	0x044E	# CYRILLIC SMALL LETTER YU
0xFF	0x00A4	# CURRENCY SIGN

Added tools/encoding/macDingbats.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
#
#   Name:             MacOS_Dingbats [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <4>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Dingbats code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Dingbats code order.
#
#   Several of these mappings require the use of corporate
#   characters. See the file "MacOS-CorpCharList".
#
#   Notes on MacOS Dingbats:
#   ------------------------
#
#   The MacOS Dingbats encoding shares the script code smRoman
#   (0) with the standard MacOS Roman encoding. To determine if
#   the Dingbats encoding is being used, you must check if the
#   font name is "Zapf Dingbats".
#
#   The layout of the Dingbats character set is identical to or
#   a superset of the layout of the Adobe Zapf Dingbats encoding
#   vector.
#
##################

0x20	0x0020	# SPACE
0x21	0x2701	# UPPER BLADE SCISSORS
0x22	0x2702	# BLACK SCISSORS
0x23	0x2703	# LOWER BLADE SCISSORS
0x24	0x2704	# WHITE SCISSORS
0x25	0x260E	# BLACK TELEPHONE
0x26	0x2706	# TELEPHONE LOCATION SIGN
0x27	0x2707	# TAPE DRIVE
0x28	0x2708	# AIRPLANE
0x29	0x2709	# ENVELOPE
0x2A	0x261B	# BLACK RIGHT POINTING INDEX
0x2B	0x261E	# WHITE RIGHT POINTING INDEX
0x2C	0x270C	# VICTORY HAND
0x2D	0x270D	# WRITING HAND
0x2E	0x270E	# LOWER RIGHT PENCIL
0x2F	0x270F	# PENCIL
0x30	0x2710	# UPPER RIGHT PENCIL
0x31	0x2711	# WHITE NIB
0x32	0x2712	# BLACK NIB
0x33	0x2713	# CHECK MARK
0x34	0x2714	# HEAVY CHECK MARK
0x35	0x2715	# MULTIPLICATION X
0x36	0x2716	# HEAVY MULTIPLICATION X
0x37	0x2717	# BALLOT X
0x38	0x2718	# HEAVY BALLOT X
0x39	0x2719	# OUTLINED GREEK CROSS
0x3A	0x271A	# HEAVY GREEK CROSS
0x3B	0x271B	# OPEN CENTRE CROSS
0x3C	0x271C	# HEAVY OPEN CENTRE CROSS
0x3D	0x271D	# LATIN CROSS
0x3E	0x271E	# SHADOWED WHITE LATIN CROSS
0x3F	0x271F	# OUTLINED LATIN CROSS
0x40	0x2720	# MALTESE CROSS
0x41	0x2721	# STAR OF DAVID
0x42	0x2722	# FOUR TEARDROP-SPOKED ASTERISK
0x43	0x2723	# FOUR BALLOON-SPOKED ASTERISK
0x44	0x2724	# HEAVY FOUR BALLOON-SPOKED ASTERISK
0x45	0x2725	# FOUR CLUB-SPOKED ASTERISK
0x46	0x2726	# BLACK FOUR POINTED STAR
0x47	0x2727	# WHITE FOUR POINTED STAR
0x48	0x2605	# BLACK STAR
0x49	0x2729	# STRESS OUTLINED WHITE STAR
0x4A	0x272A	# CIRCLED WHITE STAR
0x4B	0x272B	# OPEN CENTRE BLACK STAR
0x4C	0x272C	# BLACK CENTRE WHITE STAR
0x4D	0x272D	# OUTLINED BLACK STAR
0x4E	0x272E	# HEAVY OUTLINED BLACK STAR
0x4F	0x272F	# PINWHEEL STAR
0x50	0x2730	# SHADOWED WHITE STAR
0x51	0x2731	# HEAVY ASTERISK
0x52	0x2732	# OPEN CENTRE ASTERISK
0x53	0x2733	# EIGHT SPOKED ASTERISK
0x54	0x2734	# EIGHT POINTED BLACK STAR
0x55	0x2735	# EIGHT POINTED PINWHEEL STAR
0x56	0x2736	# SIX POINTED BLACK STAR
0x57	0x2737	# EIGHT POINTED RECTILINEAR BLACK STAR
0x58	0x2738	# HEAVY EIGHT POINTED RECTILINEAR BLACK STAR
0x59	0x2739	# TWELVE POINTED BLACK STAR
0x5A	0x273A	# SIXTEEN POINTED ASTERISK
0x5B	0x273B	# TEARDROP-SPOKED ASTERISK
0x5C	0x273C	# OPEN CENTRE TEARDROP-SPOKED ASTERISK
0x5D	0x273D	# HEAVY TEARDROP-SPOKED ASTERISK
0x5E	0x273E	# SIX PETALLED BLACK AND WHITE FLORETTE
0x5F	0x273F	# BLACK FLORETTE
0x60	0x2740	# WHITE FLORETTE
0x61	0x2741	# EIGHT PETALLED OUTLINED BLACK FLORETTE
0x62	0x2742	# CIRCLED OPEN CENTRE EIGHT POINTED STAR
0x63	0x2743	# HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK
0x64	0x2744	# SNOWFLAKE
0x65	0x2745	# TIGHT TRIFOLIATE SNOWFLAKE
0x66	0x2746	# HEAVY CHEVRON SNOWFLAKE
0x67	0x2747	# SPARKLE
0x68	0x2748	# HEAVY SPARKLE
0x69	0x2749	# BALLOON-SPOKED ASTERISK
0x6A	0x274A	# EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
0x6B	0x274B	# HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
0x6C	0x25CF	# BLACK CIRCLE
0x6D	0x274D	# SHADOWED WHITE CIRCLE
0x6E	0x25A0	# BLACK SQUARE
0x6F	0x274F	# LOWER RIGHT DROP-SHADOWED WHITE SQUARE
0x70	0x2750	# UPPER RIGHT DROP-SHADOWED WHITE SQUARE
0x71	0x2751	# LOWER RIGHT SHADOWED WHITE SQUARE
0x72	0x2752	# UPPER RIGHT SHADOWED WHITE SQUARE
0x73	0x25B2	# BLACK UP-POINTING TRIANGLE
0x74	0x25BC	# BLACK DOWN-POINTING TRIANGLE
0x75	0x25C6	# BLACK DIAMOND
0x76	0x2756	# BLACK DIAMOND MINUS WHITE X
0x77	0x25D7	# RIGHT HALF BLACK CIRCLE
0x78	0x2758	# LIGHT VERTICAL BAR
0x79	0x2759	# MEDIUM VERTICAL BAR
0x7A	0x275A	# HEAVY VERTICAL BAR
0x7B	0x275B	# HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT
0x7C	0x275C	# HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT
0x7D	0x275D	# HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT
0x7E	0x275E	# HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT
0x80	0xF8D7	# medium left parenthesis ornament
0x81	0xF8D8	# medium right parenthesis ornament
0x82	0xF8D9	# medium flattened left parenthesis ornament
0x83	0xF8DA	# medium flattened right parenthesis ornament
0x84	0xF8DB	# medium left-pointing angle bracket ornament
0x85	0xF8DC	# medium right-pointing angle bracket ornament
0x86	0xF8DD	# heavy left-pointing angle quotation mark ornament
0x87	0xF8DE	# heavy right-pointing angle quotation mark ornament
0x88	0xF8DF	# heavy left-pointing angle bracket ornament
0x89	0xF8E0	# heavy right-pointing angle bracket ornament
0x8A	0xF8E1	# light left tortoise shell bracket ornament
0x8B	0xF8E2	# light right tortoise shell bracket ornament
0x8C	0xF8E3	# medium left curly bracket ornament
0x8D	0xF8E4	# medium right curly bracket ornament
0xA1	0x2761	# CURVED STEM PARAGRAPH SIGN ORNAMENT
0xA2	0x2762	# HEAVY EXCLAMATION MARK ORNAMENT
0xA3	0x2763	# HEAVY HEART EXCLAMATION MARK ORNAMENT
0xA4	0x2764	# HEAVY BLACK HEART
0xA5	0x2765	# ROTATED HEAVY BLACK HEART BULLET
0xA6	0x2766	# FLORAL HEART
0xA7	0x2767	# ROTATED FLORAL HEART BULLET
0xA8	0x2663	# BLACK CLUB SUIT
0xA9	0x2666	# BLACK DIAMOND SUIT
0xAA	0x2665	# BLACK HEART SUIT
0xAB	0x2660	# BLACK SPADE SUIT
0xAC	0x2460	# CIRCLED DIGIT ONE
0xAD	0x2461	# CIRCLED DIGIT TWO
0xAE	0x2462	# CIRCLED DIGIT THREE
0xAF	0x2463	# CIRCLED DIGIT FOUR
0xB0	0x2464	# CIRCLED DIGIT FIVE
0xB1	0x2465	# CIRCLED DIGIT SIX
0xB2	0x2466	# CIRCLED DIGIT SEVEN
0xB3	0x2467	# CIRCLED DIGIT EIGHT
0xB4	0x2468	# CIRCLED DIGIT NINE
0xB5	0x2469	# CIRCLED NUMBER TEN
0xB6	0x2776	# DINGBAT NEGATIVE CIRCLED DIGIT ONE
0xB7	0x2777	# DINGBAT NEGATIVE CIRCLED DIGIT TWO
0xB8	0x2778	# DINGBAT NEGATIVE CIRCLED DIGIT THREE
0xB9	0x2779	# DINGBAT NEGATIVE CIRCLED DIGIT FOUR
0xBA	0x277A	# DINGBAT NEGATIVE CIRCLED DIGIT FIVE
0xBB	0x277B	# DINGBAT NEGATIVE CIRCLED DIGIT SIX
0xBC	0x277C	# DINGBAT NEGATIVE CIRCLED DIGIT SEVEN
0xBD	0x277D	# DINGBAT NEGATIVE CIRCLED DIGIT EIGHT
0xBE	0x277E	# DINGBAT NEGATIVE CIRCLED DIGIT NINE
0xBF	0x277F	# DINGBAT NEGATIVE CIRCLED NUMBER TEN
0xC0	0x2780	# DINGBAT CIRCLED SANS-SERIF DIGIT ONE
0xC1	0x2781	# DINGBAT CIRCLED SANS-SERIF DIGIT TWO
0xC2	0x2782	# DINGBAT CIRCLED SANS-SERIF DIGIT THREE
0xC3	0x2783	# DINGBAT CIRCLED SANS-SERIF DIGIT FOUR
0xC4	0x2784	# DINGBAT CIRCLED SANS-SERIF DIGIT FIVE
0xC5	0x2785	# DINGBAT CIRCLED SANS-SERIF DIGIT SIX
0xC6	0x2786	# DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN
0xC7	0x2787	# DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT
0xC8	0x2788	# DINGBAT CIRCLED SANS-SERIF DIGIT NINE
0xC9	0x2789	# DINGBAT CIRCLED SANS-SERIF NUMBER TEN
0xCA	0x278A	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE
0xCB	0x278B	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO
0xCC	0x278C	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE
0xCD	0x278D	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR
0xCE	0x278E	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE
0xCF	0x278F	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX
0xD0	0x2790	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN
0xD1	0x2791	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT
0xD2	0x2792	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE
0xD3	0x2793	# DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN
0xD4	0x2794	# HEAVY WIDE-HEADED RIGHTWARDS ARROW
0xD5	0x2192	# RIGHTWARDS ARROW
0xD6	0x2194	# LEFT RIGHT ARROW
0xD7	0x2195	# UP DOWN ARROW
0xD8	0x2798	# HEAVY SOUTH EAST ARROW
0xD9	0x2799	# HEAVY RIGHTWARDS ARROW
0xDA	0x279A	# HEAVY NORTH EAST ARROW
0xDB	0x279B	# DRAFTING POINT RIGHTWARDS ARROW
0xDC	0x279C	# HEAVY ROUND-TIPPED RIGHTWARDS ARROW
0xDD	0x279D	# TRIANGLE-HEADED RIGHTWARDS ARROW
0xDE	0x279E	# HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW
0xDF	0x279F	# DASHED TRIANGLE-HEADED RIGHTWARDS ARROW
0xE0	0x27A0	# HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW
0xE1	0x27A1	# BLACK RIGHTWARDS ARROW
0xE2	0x27A2	# THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD
0xE3	0x27A3	# THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD
0xE4	0x27A4	# BLACK RIGHTWARDS ARROWHEAD
0xE5	0x27A5	# HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW
0xE6	0x27A6	# HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW
0xE7	0x27A7	# SQUAT BLACK RIGHTWARDS ARROW
0xE8	0x27A8	# HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW
0xE9	0x27A9	# RIGHT-SHADED WHITE RIGHTWARDS ARROW
0xEA	0x27AA	# LEFT-SHADED WHITE RIGHTWARDS ARROW
0xEB	0x27AB	# BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW
0xEC	0x27AC	# FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW
0xED	0x27AD	# HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
0xEE	0x27AE	# HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
0xEF	0x27AF	# NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
0xF1	0x27B1	# NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
0xF2	0x27B2	# CIRCLED HEAVY WHITE RIGHTWARDS ARROW
0xF3	0x27B3	# WHITE-FEATHERED RIGHTWARDS ARROW
0xF4	0x27B4	# BLACK-FEATHERED SOUTH EAST ARROW
0xF5	0x27B5	# BLACK-FEATHERED RIGHTWARDS ARROW
0xF6	0x27B6	# BLACK-FEATHERED NORTH EAST ARROW
0xF7	0x27B7	# HEAVY BLACK-FEATHERED SOUTH EAST ARROW
0xF8	0x27B8	# HEAVY BLACK-FEATHERED RIGHTWARDS ARROW
0xF9	0x27B9	# HEAVY BLACK-FEATHERED NORTH EAST ARROW
0xFA	0x27BA	# TEARDROP-BARBED RIGHTWARDS ARROW
0xFB	0x27BB	# HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW
0xFC	0x27BC	# WEDGE-TAILED RIGHTWARDS ARROW
0xFD	0x27BD	# HEAVY WEDGE-TAILED RIGHTWARDS ARROW
0xFE	0x27BE	# OPEN OUTLINED RIGHTWARDS ARROW

Added tools/encoding/macGreek.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#
#   Name:             MacOS_Greek [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <7>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Greek code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Greek code order.
#
#   One of these mappings requires the use of a corporate character
#   (for an undefined code point). See the file "MacOS-CorpCharList".
#
#   Notes on MacOS Greek:
#   ---------------------
#
#   Although a MacOS script code is defined for Greek (smGreek = 6),
#   the Greek localized system does not currently use it (the font
#   family IDs are in the MacOS Roman range). To determine if the
#   Greek encoding is being used when the script code is smRoman (0),
#   you must check if the system region code is 20, verGreece.
#
#   The MacOS Greek encoding is a superset of the repertoire of
#   ISO 8859-5 (although characters are not at the same code points).
#
#   This character set was used by all MacOS Greek systems 6.x and
#   7.x except for system 6.0.7, which used a variant character set
#   but was quickly replaced with Greek system 6.0.7.1 using the
#   standard character set documented here. Greek system 4.1 used a
#   variant Greek set that had ISO 8859-7 in 0xA0-0xFF (with some
#   holes filled in with DTP characters), and MacOS Roman accented
#   Roman letters in 0x80-0x9F.
#
##################

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
#
0x80	0x00C4	# LATIN CAPITAL LETTER A WITH DIAERESIS
0x81	0x00B9	# SUPERSCRIPT ONE
0x82	0x00B2	# SUPERSCRIPT TWO
0x83	0x00C9	# LATIN CAPITAL LETTER E WITH ACUTE
0x84	0x00B3	# SUPERSCRIPT THREE
0x85	0x00D6	# LATIN CAPITAL LETTER O WITH DIAERESIS
0x86	0x00DC	# LATIN CAPITAL LETTER U WITH DIAERESIS
0x87	0x0385	# GREEK DIALYTIKA TONOS
0x88	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
0x89	0x00E2	# LATIN SMALL LETTER A WITH CIRCUMFLEX
0x8A	0x00E4	# LATIN SMALL LETTER A WITH DIAERESIS
0x8B	0x0384	# GREEK TONOS
0x8C	0x00A8	# DIAERESIS
0x8D	0x00E7	# LATIN SMALL LETTER C WITH CEDILLA
0x8E	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
0x8F	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
0x90	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
0x91	0x00EB	# LATIN SMALL LETTER E WITH DIAERESIS
0x92	0x00A3	# POUND SIGN
0x93	0x2122	# TRADE MARK SIGN
0x94	0x00EE	# LATIN SMALL LETTER I WITH CIRCUMFLEX
0x95	0x00EF	# LATIN SMALL LETTER I WITH DIAERESIS
0x96	0x2022	# BULLET
0x97	0x00BD	# VULGAR FRACTION ONE HALF
0x98	0x2030	# PER MILLE SIGN
0x99	0x00F4	# LATIN SMALL LETTER O WITH CIRCUMFLEX
0x9A	0x00F6	# LATIN SMALL LETTER O WITH DIAERESIS
0x9B	0x00A6	# BROKEN BAR
0x9C	0x00AD	# SOFT HYPHEN
0x9D	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
0x9E	0x00FB	# LATIN SMALL LETTER U WITH CIRCUMFLEX
0x9F	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
0xA0	0x2020	# DAGGER
0xA1	0x0393	# GREEK CAPITAL LETTER GAMMA
0xA2	0x0394	# GREEK CAPITAL LETTER DELTA
0xA3	0x0398	# GREEK CAPITAL LETTER THETA
0xA4	0x039B	# GREEK CAPITAL LETTER LAMBDA
0xA5	0x039E	# GREEK CAPITAL LETTER XI
0xA6	0x03A0	# GREEK CAPITAL LETTER PI
0xA7	0x00DF	# LATIN SMALL LETTER SHARP S
0xA8	0x00AE	# REGISTERED SIGN
0xA9	0x00A9	# COPYRIGHT SIGN
0xAA	0x03A3	# GREEK CAPITAL LETTER SIGMA
0xAB	0x03AA	# GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
0xAC	0x00A7	# SECTION SIGN
0xAD	0x2260	# NOT EQUAL TO
0xAE	0x00B0	# DEGREE SIGN
0xAF	0x0387	# GREEK ANO TELEIA
0xB0	0x0391	# GREEK CAPITAL LETTER ALPHA
0xB1	0x00B1	# PLUS-MINUS SIGN
0xB2	0x2264	# LESS-THAN OR EQUAL TO
0xB3	0x2265	# GREATER-THAN OR EQUAL TO
0xB4	0x00A5	# YEN SIGN
0xB5	0x0392	# GREEK CAPITAL LETTER BETA
0xB6	0x0395	# GREEK CAPITAL LETTER EPSILON
0xB7	0x0396	# GREEK CAPITAL LETTER ZETA
0xB8	0x0397	# GREEK CAPITAL LETTER ETA
0xB9	0x0399	# GREEK CAPITAL LETTER IOTA
0xBA	0x039A	# GREEK CAPITAL LETTER KAPPA
0xBB	0x039C	# GREEK CAPITAL LETTER MU
0xBC	0x03A6	# GREEK CAPITAL LETTER PHI
0xBD	0x03AB	# GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
0xBE	0x03A8	# GREEK CAPITAL LETTER PSI
0xBF	0x03A9	# GREEK CAPITAL LETTER OMEGA
0xC0	0x03AC	# GREEK SMALL LETTER ALPHA WITH TONOS
0xC1	0x039D	# GREEK CAPITAL LETTER NU
0xC2	0x00AC	# NOT SIGN
0xC3	0x039F	# GREEK CAPITAL LETTER OMICRON
0xC4	0x03A1	# GREEK CAPITAL LETTER RHO
0xC5	0x2248	# ALMOST EQUAL TO
0xC6	0x03A4	# GREEK CAPITAL LETTER TAU
0xC7	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC8	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC9	0x2026	# HORIZONTAL ELLIPSIS
0xCA	0x00A0	# NO-BREAK SPACE
0xCB	0x03A5	# GREEK CAPITAL LETTER UPSILON
0xCC	0x03A7	# GREEK CAPITAL LETTER CHI
0xCD	0x0386	# GREEK CAPITAL LETTER ALPHA WITH TONOS
0xCE	0x0388	# GREEK CAPITAL LETTER EPSILON WITH TONOS
0xCF	0x0153	# LATIN SMALL LIGATURE OE
0xD0	0x2013	# EN DASH
0xD1	0x2015	# HORIZONTAL BAR
0xD2	0x201C	# LEFT DOUBLE QUOTATION MARK
0xD3	0x201D	# RIGHT DOUBLE QUOTATION MARK
0xD4	0x2018	# LEFT SINGLE QUOTATION MARK
0xD5	0x2019	# RIGHT SINGLE QUOTATION MARK
0xD6	0x00F7	# DIVISION SIGN
0xD7	0x0389	# GREEK CAPITAL LETTER ETA WITH TONOS
0xD8	0x038A	# GREEK CAPITAL LETTER IOTA WITH TONOS
0xD9	0x038C	# GREEK CAPITAL LETTER OMICRON WITH TONOS
0xDA	0x038E	# GREEK CAPITAL LETTER UPSILON WITH TONOS
0xDB	0x03AD	# GREEK SMALL LETTER EPSILON WITH TONOS
0xDC	0x03AE	# GREEK SMALL LETTER ETA WITH TONOS
0xDD	0x03AF	# GREEK SMALL LETTER IOTA WITH TONOS
0xDE	0x03CC	# GREEK SMALL LETTER OMICRON WITH TONOS
0xDF	0x038F	# GREEK CAPITAL LETTER OMEGA WITH TONOS
0xE0	0x03CD	# GREEK SMALL LETTER UPSILON WITH TONOS
0xE1	0x03B1	# GREEK SMALL LETTER ALPHA
0xE2	0x03B2	# GREEK SMALL LETTER BETA
0xE3	0x03C8	# GREEK SMALL LETTER PSI
0xE4	0x03B4	# GREEK SMALL LETTER DELTA
0xE5	0x03B5	# GREEK SMALL LETTER EPSILON
0xE6	0x03C6	# GREEK SMALL LETTER PHI
0xE7	0x03B3	# GREEK SMALL LETTER GAMMA
0xE8	0x03B7	# GREEK SMALL LETTER ETA
0xE9	0x03B9	# GREEK SMALL LETTER IOTA
0xEA	0x03BE	# GREEK SMALL LETTER XI
0xEB	0x03BA	# GREEK SMALL LETTER KAPPA
0xEC	0x03BB	# GREEK SMALL LETTER LAMBDA
0xED	0x03BC	# GREEK SMALL LETTER MU
0xEE	0x03BD	# GREEK SMALL LETTER NU
0xEF	0x03BF	# GREEK SMALL LETTER OMICRON
0xF0	0x03C0	# GREEK SMALL LETTER PI
0xF1	0x03CE	# GREEK SMALL LETTER OMEGA WITH TONOS
0xF2	0x03C1	# GREEK SMALL LETTER RHO
0xF3	0x03C3	# GREEK SMALL LETTER SIGMA
0xF4	0x03C4	# GREEK SMALL LETTER TAU
0xF5	0x03B8	# GREEK SMALL LETTER THETA
0xF6	0x03C9	# GREEK SMALL LETTER OMEGA
0xF7	0x03C2	# GREEK SMALL LETTER FINAL SIGMA
0xF8	0x03C7	# GREEK SMALL LETTER CHI
0xF9	0x03C5	# GREEK SMALL LETTER UPSILON
0xFA	0x03B6	# GREEK SMALL LETTER ZETA
0xFB	0x03CA	# GREEK SMALL LETTER IOTA WITH DIALYTIKA
0xFC	0x03CB	# GREEK SMALL LETTER UPSILON WITH DIALYTIKA
0xFD	0x0390	# GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
0xFE	0x03B0	# GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
0xFF	0xF8A0	# undefined1

Added tools/encoding/macIceland.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#
#   Name:             MacOS_Icelandic [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <5>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Icelandic code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Icelandic code order.
#
#   One of these mappings requires the use of a corporate character
#   (for the Apple logo character). See the file "MacOS-CorpCharList".
#   NOTE: The graphic image associated with the Apple logo character
#   is not authorized for use without permission of Apple, and
#   unauthorized use might constitute trademark infringement.
#
#   Notes on MacOS Icelandic:
#   -------------------------
#
#   The MacOS Icelandic encoding shares the script code smRoman
#   (0) with the standard MacOS Roman encoding. To determine if
#   the Icelandic encoding is being used, you must also check if
#   the system region code is 21, verIceland.
#
#   This character set is a variant of standard MacOS Roman,
#   adding upper and lower eth, thorn, and Y acute. It has 6 code
#   point differences from standard MacOS Roman.
#
##################

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
#
0x80	0x00C4	# LATIN CAPITAL LETTER A WITH DIAERESIS
0x81	0x00C5	# LATIN CAPITAL LETTER A WITH RING ABOVE
0x82	0x00C7	# LATIN CAPITAL LETTER C WITH CEDILLA
0x83	0x00C9	# LATIN CAPITAL LETTER E WITH ACUTE
0x84	0x00D1	# LATIN CAPITAL LETTER N WITH TILDE
0x85	0x00D6	# LATIN CAPITAL LETTER O WITH DIAERESIS
0x86	0x00DC	# LATIN CAPITAL LETTER U WITH DIAERESIS
0x87	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
0x88	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
0x89	0x00E2	# LATIN SMALL LETTER A WITH CIRCUMFLEX
0x8A	0x00E4	# LATIN SMALL LETTER A WITH DIAERESIS
0x8B	0x00E3	# LATIN SMALL LETTER A WITH TILDE
0x8C	0x00E5	# LATIN SMALL LETTER A WITH RING ABOVE
0x8D	0x00E7	# LATIN SMALL LETTER C WITH CEDILLA
0x8E	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
0x8F	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
0x90	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
0x91	0x00EB	# LATIN SMALL LETTER E WITH DIAERESIS
0x92	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
0x93	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
0x94	0x00EE	# LATIN SMALL LETTER I WITH CIRCUMFLEX
0x95	0x00EF	# LATIN SMALL LETTER I WITH DIAERESIS
0x96	0x00F1	# LATIN SMALL LETTER N WITH TILDE
0x97	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
0x98	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
0x99	0x00F4	# LATIN SMALL LETTER O WITH CIRCUMFLEX
0x9A	0x00F6	# LATIN SMALL LETTER O WITH DIAERESIS
0x9B	0x00F5	# LATIN SMALL LETTER O WITH TILDE
0x9C	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
0x9D	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
0x9E	0x00FB	# LATIN SMALL LETTER U WITH CIRCUMFLEX
0x9F	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
0xA0	0x00DD	# LATIN CAPITAL LETTER Y WITH ACUTE
0xA1	0x00B0	# DEGREE SIGN
0xA2	0x00A2	# CENT SIGN
0xA3	0x00A3	# POUND SIGN
0xA4	0x00A7	# SECTION SIGN
0xA5	0x2022	# BULLET
0xA6	0x00B6	# PILCROW SIGN
0xA7	0x00DF	# LATIN SMALL LETTER SHARP S
0xA8	0x00AE	# REGISTERED SIGN
0xA9	0x00A9	# COPYRIGHT SIGN
0xAA	0x2122	# TRADE MARK SIGN
0xAB	0x00B4	# ACUTE ACCENT
0xAC	0x00A8	# DIAERESIS
0xAD	0x2260	# NOT EQUAL TO
0xAE	0x00C6	# LATIN CAPITAL LIGATURE AE
0xAF	0x00D8	# LATIN CAPITAL LETTER O WITH STROKE
0xB0	0x221E	# INFINITY
0xB1	0x00B1	# PLUS-MINUS SIGN
0xB2	0x2264	# LESS-THAN OR EQUAL TO
0xB3	0x2265	# GREATER-THAN OR EQUAL TO
0xB4	0x00A5	# YEN SIGN
0xB5	0x00B5	# MICRO SIGN
0xB6	0x2202	# PARTIAL DIFFERENTIAL
0xB7	0x2211	# N-ARY SUMMATION
0xB8	0x220F	# N-ARY PRODUCT
0xB9	0x03C0	# GREEK SMALL LETTER PI
0xBA	0x222B	# INTEGRAL
0xBB	0x00AA	# FEMININE ORDINAL INDICATOR
0xBC	0x00BA	# MASCULINE ORDINAL INDICATOR
0xBD	0x2126	# OHM SIGN
0xBE	0x00E6	# LATIN SMALL LIGATURE AE
0xBF	0x00F8	# LATIN SMALL LETTER O WITH STROKE
0xC0	0x00BF	# INVERTED QUESTION MARK
0xC1	0x00A1	# INVERTED EXCLAMATION MARK
0xC2	0x00AC	# NOT SIGN
0xC3	0x221A	# SQUARE ROOT
0xC4	0x0192	# LATIN SMALL LETTER F WITH HOOK
0xC5	0x2248	# ALMOST EQUAL TO
0xC6	0x2206	# INCREMENT
0xC7	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC8	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC9	0x2026	# HORIZONTAL ELLIPSIS
0xCA	0x00A0	# NO-BREAK SPACE
0xCB	0x00C0	# LATIN CAPITAL LETTER A WITH GRAVE
0xCC	0x00C3	# LATIN CAPITAL LETTER A WITH TILDE
0xCD	0x00D5	# LATIN CAPITAL LETTER O WITH TILDE
0xCE	0x0152	# LATIN CAPITAL LIGATURE OE
0xCF	0x0153	# LATIN SMALL LIGATURE OE
0xD0	0x2013	# EN DASH
0xD1	0x2014	# EM DASH
0xD2	0x201C	# LEFT DOUBLE QUOTATION MARK
0xD3	0x201D	# RIGHT DOUBLE QUOTATION MARK
0xD4	0x2018	# LEFT SINGLE QUOTATION MARK
0xD5	0x2019	# RIGHT SINGLE QUOTATION MARK
0xD6	0x00F7	# DIVISION SIGN
0xD7	0x25CA	# LOZENGE
0xD8	0x00FF	# LATIN SMALL LETTER Y WITH DIAERESIS
0xD9	0x0178	# LATIN CAPITAL LETTER Y WITH DIAERESIS
0xDA	0x2044	# FRACTION SLASH
0xDB	0x00A4	# CURRENCY SIGN
0xDC	0x00D0	# LATIN CAPITAL LETTER ETH
0xDD	0x00F0	# LATIN SMALL LETTER ETH
0xDE	0x00DE	# LATIN CAPITAL LETTER THORN
0xDF	0x00FE	# LATIN SMALL LETTER THORN
0xE0	0x00FD	# LATIN SMALL LETTER Y WITH ACUTE
0xE1	0x00B7	# MIDDLE DOT
0xE2	0x201A	# SINGLE LOW-9 QUOTATION MARK
0xE3	0x201E	# DOUBLE LOW-9 QUOTATION MARK
0xE4	0x2030	# PER MILLE SIGN
0xE5	0x00C2	# LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xE6	0x00CA	# LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xE7	0x00C1	# LATIN CAPITAL LETTER A WITH ACUTE
0xE8	0x00CB	# LATIN CAPITAL LETTER E WITH DIAERESIS
0xE9	0x00C8	# LATIN CAPITAL LETTER E WITH GRAVE
0xEA	0x00CD	# LATIN CAPITAL LETTER I WITH ACUTE
0xEB	0x00CE	# LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xEC	0x00CF	# LATIN CAPITAL LETTER I WITH DIAERESIS
0xED	0x00CC	# LATIN CAPITAL LETTER I WITH GRAVE
0xEE	0x00D3	# LATIN CAPITAL LETTER O WITH ACUTE
0xEF	0x00D4	# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xF0	0xF8FF	# Apple logo
0xF1	0x00D2	# LATIN CAPITAL LETTER O WITH GRAVE
0xF2	0x00DA	# LATIN CAPITAL LETTER U WITH ACUTE
0xF3	0x00DB	# LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xF4	0x00D9	# LATIN CAPITAL LETTER U WITH GRAVE
0xF5	0x0131	# LATIN SMALL LETTER DOTLESS I
0xF6	0x02C6	# MODIFIER LETTER CIRCUMFLEX ACCENT
0xF7	0x02DC	# SMALL TILDE
0xF8	0x00AF	# MACRON
0xF9	0x02D8	# BREVE
0xFA	0x02D9	# DOT ABOVE
0xFB	0x02DA	# RING ABOVE
0xFC	0x00B8	# CEDILLA
0xFD	0x02DD	# DOUBLE ACUTE ACCENT
0xFE	0x02DB	# OGONEK
0xFF	0x02C7	# CARON

Added tools/encoding/macJapan.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
#
#   Name:             MacOS_Japanese [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <11>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Japanese code (in hex as 0xNN or 0xNNNN)
#     Column #2 is the Unicode or Unicode sequence (in hex as 0xNNNN
#       or 0xNNNN+0xNNNN).
#     Column #3 is the Unicode name (follows a comment sign, '#')
#     In some cases an additional comment follows the Unicode name.
#
#   The table is divided into three sections, each set off by a header.
#     Basic - Shift-JIS plus five additional one-byte characters. The
#       mappings for this section are based on the UTC mappings for
#       Shift-JIS dated 8 March 1994, adjusted as necessary for the
#       differences between Shift-JIS and this Apple basic set (also
#       adjusted in two places for a better match with the JIS spec).
#       Changes from UTC mappings are noted with additional comments.
#     Apple extensions - additional two-byte characters
#     Vertical forms - separately-encoded vertical forms
#   Within each table, the entries are in MacOS Japanese code order.
#   The mappings are only for the standard version of MacOS Japanese
#     (not for the several variants).
#
#   Note that in three cases, a single MacOS Japanese character maps
#   to a sequence of Unicode characters. This is indicated by joining
#   the Unicode characters with '+'. See entries for MacOS Japanese
#   characters 0x8791, 0x8792, and 0x879D.
#
#   Some of these mappings require the use of corporate characters.
#   See the file "MacOS-CorpCharList".
#
#   Notes on MacOS Japanese:
#   ------------------------
#
#    This table covers the standard MacOS Japanese character set used in
#    System software versions 7.1 and later. Certain fonts may be based
#    on a modified version of this character set. See below for more
#    information.
#
#    There are several MacJapanese encodings. Most of them are ways of
#    representing JIS X0208-1990 and JIS X0201-1976 in the Shift-JIS
#    form, but with additional characters.
#
#    Some of the information below comes from Ken Lunde's book
#    "Understanding Japanese Information Processing", O'Reilly & Assoc.,
#    1993.
#
# 1. Conventional Shift-JIS
#
#    Most Shift-JIS implementations include the following characters:
#
#    a)  One-byte characters with codes from 0x00-0x7F for a Japanese
#        variant of ISO 646 (ASCII), in which the ASCII backslash
#        character at x5C is replaced by a yen sign , the tilde at 0x7E
#        is replaced by overline, and usually the vertical line at 0x7C
#        is replaced by broken bar (this is the Roman repertoire from JIS
#        X0201). The standard MacOS Japanese version retains tilde at
#        0x7E and vertical bar at 0x7C, although the PostScript variant
#        uses broken bar at 0x7C. The difference between vertical line
#        and broken bar is sometimes considered just a glyph variant.
#
#    b)  One-byte katakana and punctuation characters with codes from
#        0xA1-0xDF (this is the katakana repertoire from JIS X0201).
#
#    c)  JIS X0208-1990 characters in Shift-JIS form. In this form, byte
#        values 0x81-0x9F and 0xE0-0xEF are used to indicate the first
#        byte of a 2-byte character in the JIS domain. JIS X0208
#        characters are usually represented in "ku-ten" or row-cell
#        (row-column) form, with row and cell values each running from 1
#        through 94. These are transformed into Shift-JIS form in the
#        following way:
#
#        rowOffset = (row < 63) ? 0x80 : 0xC0;
#        cellOffset = (row % 2 == 1) ? 0x3F + (cell > 63 ? 1 : 0) : 0x9E;
#        shiftJISbyte1 = (row + 1)/2 + rowOffset;
#        shiftJISbyte2 = cell + cellOffset;
#
#        Astute observers will note that (i) in this form the second
#        bytes of Shift-JIS characters are in the range 0x40-0x7E or
#        0x80-0xFC; and (2) the maximum ku-ten code 94,94 maps to
#        Shift-JIS code 0xEFFC.
#
#        Note: PostScript fonts are based on JIS X0208-1983 (formerly
#        known as JIS C6226-1983). This version of JIS was missing two
#        kanji characters that were added for JIS X0208-1990: in ku-ten
#        form these are 84,05 and 84,06; in Shift-JIS form these are
#        0xEAA3 and 0xEAA4. The other differences in the two versions are
#        changes in standard glyphs, not character differences.
#
#    d)  User-defined characters. Usually, byte values 0xF0-0xFC are used
#        to indicate the first byte of a user-defined 2-byte character
#        (the second byte follows the above conventions and is in the
#        range 0x40-0x7E or 0x80-0xFC).
#
#   This provides 13*188 = 2444 characters.
#
# 2. Additional Apple one-byte characters
#
#    The above scheme leaves 5 one-byte characters unused: 0x80, 0xA0,
#    and 0xFD-0xFF. The standard Macintosh Japanese encoding defines
#    these as follows:
#
#        0x80 backslash (the character moved from 0x5C)
#        0xA0 halfwidth no-break space (0xA0 as halfwidth space is a
#             common industry addition))
#        0xFD copyright sign
#        0xFE trademark sign
#        0xFF horizontal ellipsis
#
# 3. Apple two-byte extensions
#
#    Not all of the available JIS X0208 ku-ten codes are assigned to
#    characters. Most vendors make use of this to provide character set
#    extensions, vendor-specific assignments for some of the unused
#    codes. Apple is no exception, but Apple's situation is complex:
#    Different fonts implement different character sets! This situation
#    is cleaned up in the Japanese TrueType fonts for system software
#    7.1.2 and later. However, the PostScript fonts still implement a
#    different character set. I will describe the various extension sets
#    below, then list what I know about fonts that match each one.
#
#    a)  Vertical forms at ku+10 position - some of the characters in
#        rows 1, 4, and 5 (punctuation, hiragana, katakana) have vertical
#        forms (the corresponding form used for vertical text) encoded at
#        a position obtained by adding 10 to the row number (thus giving
#        them Shift-JIS codes 0x86nn, 0x87nn, 0x88nn). This was necessary
#        for vertical text in the past, but vertical forms are handled
#        automatically by QuickDraw(tm) GX in the future and no longer
#        need separate encoding.
#
#        0x8641-0x8681 (symbols), 0x879F-0x87EC (hiragana), 0x8840-0x8896
#        (katakana). Note that Kanji characters begin at 0x889F.
#
#    b)  Vertical forms at ku+84 position - same as above, but vertical
#        forms encoded in a different position, using shift-JIS codes
#        0xEBnn, 0xECnn, 0xEDnn. This is the location in the standard
#        MacOS Japanese encoding, and is also the location of vertical
#        forms in PostScript Japanese fonts (the PostScript fonts have
#        some additional vertical forms for characters in rows other than
#        1, 4, and 5; these additional vertical forms have a more complex
#        mapping, not necessarily at ku+84).
#
#        0xEB41-0xEB81 (symbols), 0xEC9F-0xECEC (hiragana), 0xED40-0xED96
#        (katakana). Note that Kanji characters end at 0xEAA4.
#
#    c)  Various Apple extension characters in JIS rows 9-15, with
#        Shift-JIS codes 0x85nn-0x88nn. These cannot coexist with the
#        ku+10 vertical forms.
#
#    d)  Postscript extension set characters in JIS rows 9-15, with
#        Shift-JIS codes 0x85nn-0x88nn. This is a different extension set
#        and cannot coexist with the ku+10 vertical forms or the Apple
#        extensions. Note: Fonts that have this set also use an earlier
#        version of JIS, X0208-1983, which is missing two kanji that are
#        in JIS X0208-1990.
#
#    Here are some possible variations, the version numbers assigned to
#    some of them, and some fonts that are known to match them:
#
#                 Apple   PostSc  ku+10  ku+84
#    variant      extras  extras  vert   vert   fonts, comments
#    -------      ------  ------  -----  -----  ---------------
#    standard     yes     no      no     yes    TrueType fonts version >= 2.1
#                                               (all TT, system >= J-7.1.2)
#    stdNoVert    yes     no      no     no     Artificial variant for users
#                                               who don't want separately-
#                                               encoded vertical forms (e.g.
#                                               GX users)
#    basic        no      no      no     no     Artificial variant for basic
#                                               interchange
#    screenPS     no      no      no     yes    SaiMincho & ChuGothic screen
#                                               fonts; mostly missing 0xFD-0xFF,
#                                               missing 0xEAA3, 0xEAA4
#    printPS      no      yes     no     yes    SaiMincho & ChuGothic PostScript
#                                               fonts; missing 0x80, 0xFD-0xFF,
#                                               0xEAA3, 0xEAA4; 0x7C is broken
#                                               bar; have extra vertical forms
#    kuPlus10Vert no      no      yes    no     HonMincho & MaruGothic fonts in
#                                               system J-7.1
#
# 4. Halfwidth characters
#
#    The one-byte characters are usually called halfwidth characters,
#    while two-byte characters are called fullwidth. The PostScript
#    printing variant listed above includes two-byte halfwidth characters
#    in addition to one-byte halfwidth characters, so halfwidth does not
#    always imply a one-byte character.
#
##################

##################
# Basic
##################

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 (rendered as Halfwidth Yen Sign)
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 # Apple change
#
0x8140	0x3000	# IDEOGRAPHIC SPACE
0x8141	0x3001	# IDEOGRAPHIC COMMA
0x8142	0x3002	# IDEOGRAPHIC FULL STOP
0x8143	0xFF0C	# FULLWIDTH COMMA
0x8144	0xFF0E	# FULLWIDTH FULL STOP
0x8145	0x30FB	# KATAKANA MIDDLE DOT
0x8146	0xFF1A	# FULLWIDTH COLON
0x8147	0xFF1B	# FULLWIDTH SEMICOLON
0x8148	0xFF1F	# FULLWIDTH QUESTION MARK
0x8149	0xFF01	# FULLWIDTH EXCLAMATION MARK
0x814A	0x309B	# KATAKANA-HIRAGANA VOICED SOUND MARK
0x814B	0x309C	# KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
0x814C	0x00B4	# ACUTE ACCENT
0x814D	0xFF40	# FULLWIDTH GRAVE ACCENT
0x814E	0x00A8	# DIAERESIS
0x814F	0xFF3E	# FULLWIDTH CIRCUMFLEX ACCENT
0x8150	0x203E	# OVERLINE # Change UTC mapping to match JIS spec
0x8151	0xFF3F	# FULLWIDTH LOW LINE
0x8152	0x30FD	# KATAKANA ITERATION MARK
0x8153	0x30FE	# KATAKANA VOICED ITERATION MARK
0x8154	0x309D	# HIRAGANA ITERATION MARK
0x8155	0x309E	# HIRAGANA VOICED ITERATION MARK
0x8156	0x3003	# DITTO MARK
0x8157	0x4EDD	# <CJK>
0x8158	0x3005	# IDEOGRAPHIC ITERATION MARK
0x8159	0x3006	# IDEOGRAPHIC CLOSING MARK
0x815A	0x3007	# IDEOGRAPHIC NUMBER ZERO
0x815B	0x30FC	# KATAKANA-HIRAGANA PROLONGED SOUND MARK
0x815C	0x2014	# EM DASH # Change UTC mapping to match JIS spec
0x815D	0x2010	# HYPHEN
0x815E	0xFF0F	# FULLWIDTH SOLIDUS
0x815F	0xFF3C	# FULLWIDTH REVERSE SOLIDUS # change mapping to separate from MacOS-J 0x80
0x8160	0x301C	# WAVE DASH
0x8161	0x2016	# DOUBLE VERTICAL LINE # 0x8161 could also map to U+2225
0x8162	0xFF5C	# FULLWIDTH VERTICAL LINE
0x8163	0x22EF	# MIDLINE HORIZONTAL ELLIPSIS # change mapping to separate from MacOS-J 0xFF
0x8164	0x2025	# TWO DOT LEADER
0x8165	0x2018	# LEFT SINGLE QUOTATION MARK
0x8166	0x2019	# RIGHT SINGLE QUOTATION MARK
0x8167	0x201C	# LEFT DOUBLE QUOTATION MARK
0x8168	0x201D	# RIGHT DOUBLE QUOTATION MARK
0x8169	0xFF08	# FULLWIDTH LEFT PARENTHESIS
0x816A	0xFF09	# FULLWIDTH RIGHT PARENTHESIS
0x816B	0x3014	# LEFT TORTOISE SHELL BRACKET
0x816C	0x3015	# RIGHT TORTOISE SHELL BRACKET
0x816D	0xFF3B	# FULLWIDTH LEFT SQUARE BRACKET
0x816E	0xFF3D	# FULLWIDTH RIGHT SQUARE BRACKET
0x816F	0xFF5B	# FULLWIDTH LEFT CURLY BRACKET
0x8170	0xFF5D	# FULLWIDTH RIGHT CURLY BRACKET
0x8171	0x3008	# LEFT ANGLE BRACKET
0x8172	0x3009	# RIGHT ANGLE BRACKET
0x8173	0x300A	# LEFT DOUBLE ANGLE BRACKET
0x8174	0x300B	# RIGHT DOUBLE ANGLE BRACKET
0x8175	0x300C	# LEFT CORNER BRACKET
0x8176	0x300D	# RIGHT CORNER BRACKET
0x8177	0x300E	# LEFT WHITE CORNER BRACKET
0x8178	0x300F	# RIGHT WHITE CORNER BRACKET
0x8179	0x3010	# LEFT BLACK LENTICULAR BRACKET
0x817A	0x3011	# RIGHT BLACK LENTICULAR BRACKET
0x817B	0xFF0B	# FULLWIDTH PLUS SIGN
0x817C	0x2212	# MINUS SIGN
0x817D	0x00B1	# PLUS-MINUS SIGN
0x817E	0x00D7	# MULTIPLICATION SIGN
0x8180	0x00F7	# DIVISION SIGN
0x8181	0xFF1D	# FULLWIDTH EQUALS SIGN
0x8182	0x2260	# NOT EQUAL TO
0x8183	0xFF1C	# FULLWIDTH LESS-THAN SIGN
0x8184	0xFF1E	# FULLWIDTH GREATER-THAN SIGN
0x8185	0x2266	# LESS-THAN OVER EQUAL TO
0x8186	0x2267	# GREATER-THAN OVER EQUAL TO
0x8187	0x221E	# INFINITY
0x8188	0x2234	# THEREFORE
0x8189	0x2642	# MALE SIGN
0x818A	0x2640	# FEMALE SIGN
0x818B	0x00B0	# DEGREE SIGN
0x818C	0x2032	# PRIME
0x818D	0x2033	# DOUBLE PRIME
0x818E	0x2103	# DEGREE CELSIUS
0x818F	0xFFE5	# FULLWIDTH YEN SIGN
0x8190	0xFF04	# FULLWIDTH DOLLAR SIGN
0x8191	0x00A2	# CENT SIGN
0x8192	0x00A3	# POUND SIGN
0x8193	0xFF05	# FULLWIDTH PERCENT SIGN
0x8194	0xFF03	# FULLWIDTH NUMBER SIGN
0x8195	0xFF06	# FULLWIDTH AMPERSAND
0x8196	0xFF0A	# FULLWIDTH ASTERISK
0x8197	0xFF20	# FULLWIDTH COMMERCIAL AT
0x8198	0x00A7	# SECTION SIGN
0x8199	0x2606	# WHITE STAR
0x819A	0x2605	# BLACK STAR
0x819B	0x25CB	# WHITE CIRCLE
0x819C	0x25CF	# BLACK CIRCLE
0x819D	0x25CE	# BULLSEYE
0x819E	0x25C7	# WHITE DIAMOND
0x819F	0x25C6	# BLACK DIAMOND
0x81A0	0x25A1	# WHITE SQUARE
0x81A1	0x25A0	# BLACK SQUARE
0x81A2	0x25B3	# WHITE UP-POINTING TRIANGLE
0x81A3	0x25B2	# BLACK UP-POINTING TRIANGLE
0x81A4	0x25BD	# WHITE DOWN-POINTING TRIANGLE
0x81A5	0x25BC	# BLACK DOWN-POINTING TRIANGLE
0x81A6	0x203B	# REFERENCE MARK
0x81A7	0x3012	# POSTAL MARK
0x81A8	0x2192	# RIGHTWARDS ARROW
0x81A9	0x2190	# LEFTWARDS ARROW
0x81AA	0x2191	# UPWARDS ARROW
0x81AB	0x2193	# DOWNWARDS ARROW
0x81AC	0x3013	# GETA MARK
0x81B8	0x2208	# ELEMENT OF
0x81B9	0x220B	# CONTAINS AS MEMBER
0x81BA	0x2286	# SUBSET OF OR EQUAL TO
0x81BB	0x2287	# SUPERSET OF OR EQUAL TO
0x81BC	0x2282	# SUBSET OF
0x81BD	0x2283	# SUPERSET OF
0x81BE	0x222A	# UNION
0x81BF	0x2229	# INTERSECTION
0x81C8	0x2227	# LOGICAL AND
0x81C9	0x2228	# LOGICAL OR
0x81CA	0x00AC	# NOT SIGN
0x81CB	0x21D2	# RIGHTWARDS DOUBLE ARROW
0x81CC	0x21D4	# LEFT RIGHT DOUBLE ARROW
0x81CD	0x2200	# FOR ALL
0x81CE	0x2203	# THERE EXISTS
0x81DA	0x2220	# ANGLE
0x81DB	0x22A5	# UP TACK
0x81DC	0x2312	# ARC
0x81DD	0x2202	# PARTIAL DIFFERENTIAL
0x81DE	0x2207	# NABLA
0x81DF	0x2261	# IDENTICAL TO
0x81E0	0x2252	# APPROXIMATELY EQUAL TO OR THE IMAGE OF
0x81E1	0x226A	# MUCH LESS-THAN
0x81E2	0x226B	# MUCH GREATER-THAN
0x81E3	0x221A	# SQUARE ROOT
0x81E4	0x223D	# REVERSED TILDE # This UTC mapping is questionable
0x81E5	0x221D	# PROPORTIONAL TO
0x81E6	0x2235	# BECAUSE
0x81E7	0x222B	# INTEGRAL
0x81E8	0x222C	# DOUBLE INTEGRAL
0x81F0	0x212B	# ANGSTROM SIGN
0x81F1	0x2030	# PER MILLE SIGN
0x81F2	0x266F	# MUSIC SHARP SIGN
0x81F3	0x266D	# MUSIC FLAT SIGN
0x81F4	0x266A	# EIGHTH NOTE
0x81F5	0x2020	# DAGGER
0x81F6	0x2021	# DOUBLE DAGGER
0x81F7	0x00B6	# PILCROW SIGN
0x81FC	0x25EF	# LARGE CIRCLE
0x824F	0xFF10	# FULLWIDTH DIGIT ZERO
0x8250	0xFF11	# FULLWIDTH DIGIT ONE
0x8251	0xFF12	# FULLWIDTH DIGIT TWO
0x8252	0xFF13	# FULLWIDTH DIGIT THREE
0x8253	0xFF14	# FULLWIDTH DIGIT FOUR
0x8254	0xFF15	# FULLWIDTH DIGIT FIVE
0x8255	0xFF16	# FULLWIDTH DIGIT SIX
0x8256	0xFF17	# FULLWIDTH DIGIT SEVEN
0x8257	0xFF18	# FULLWIDTH DIGIT EIGHT
0x8258	0xFF19	# FULLWIDTH DIGIT NINE
0x8260	0xFF21	# FULLWIDTH LATIN CAPITAL LETTER A
0x8261	0xFF22	# FULLWIDTH LATIN CAPITAL LETTER B
0x8262	0xFF23	# FULLWIDTH LATIN CAPITAL LETTER C
0x8263	0xFF24	# FULLWIDTH LATIN CAPITAL LETTER D
0x8264	0xFF25	# FULLWIDTH LATIN CAPITAL LETTER E
0x8265	0xFF26	# FULLWIDTH LATIN CAPITAL LETTER F
0x8266	0xFF27	# FULLWIDTH LATIN CAPITAL LETTER G
0x8267	0xFF28	# FULLWIDTH LATIN CAPITAL LETTER H
0x8268	0xFF29	# FULLWIDTH LATIN CAPITAL LETTER I
0x8269	0xFF2A	# FULLWIDTH LATIN CAPITAL LETTER J
0x826A	0xFF2B	# FULLWIDTH LATIN CAPITAL LETTER K
0x826B	0xFF2C	# FULLWIDTH LATIN CAPITAL LETTER L
0x826C	0xFF2D	# FULLWIDTH LATIN CAPITAL LETTER M
0x826D	0xFF2E	# FULLWIDTH LATIN CAPITAL LETTER N
0x826E	0xFF2F	# FULLWIDTH LATIN CAPITAL LETTER O
0x826F	0xFF30	# FULLWIDTH LATIN CAPITAL LETTER P
0x8270	0xFF31	# FULLWIDTH LATIN CAPITAL LETTER Q
0x8271	0xFF32	# FULLWIDTH LATIN CAPITAL LETTER R
0x8272	0xFF33	# FULLWIDTH LATIN CAPITAL LETTER S
0x8273	0xFF34	# FULLWIDTH LATIN CAPITAL LETTER T
0x8274	0xFF35	# FULLWIDTH LATIN CAPITAL LETTER U
0x8275	0xFF36	# FULLWIDTH LATIN CAPITAL LETTER V
0x8276	0xFF37	# FULLWIDTH LATIN CAPITAL LETTER W
0x8277	0xFF38	# FULLWIDTH LATIN CAPITAL LETTER X
0x8278	0xFF39	# FULLWIDTH LATIN CAPITAL LETTER Y
0x8279	0xFF3A	# FULLWIDTH LATIN CAPITAL LETTER Z
0x8281	0xFF41	# FULLWIDTH LATIN SMALL LETTER A
0x8282	0xFF42	# FULLWIDTH LATIN SMALL LETTER B
0x8283	0xFF43	# FULLWIDTH LATIN SMALL LETTER C
0x8284	0xFF44	# FULLWIDTH LATIN SMALL LETTER D
0x8285	0xFF45	# FULLWIDTH LATIN SMALL LETTER E
0x8286	0xFF46	# FULLWIDTH LATIN SMALL LETTER F
0x8287	0xFF47	# FULLWIDTH LATIN SMALL LETTER G
0x8288	0xFF48	# FULLWIDTH LATIN SMALL LETTER H
0x8289	0xFF49	# FULLWIDTH LATIN SMALL LETTER I
0x828A	0xFF4A	# FULLWIDTH LATIN SMALL LETTER J
0x828B	0xFF4B	# FULLWIDTH LATIN SMALL LETTER K
0x828C	0xFF4C	# FULLWIDTH LATIN SMALL LETTER L
0x828D	0xFF4D	# FULLWIDTH LATIN SMALL LETTER M
0x828E	0xFF4E	# FULLWIDTH LATIN SMALL LETTER N
0x828F	0xFF4F	# FULLWIDTH LATIN SMALL LETTER O
0x8290	0xFF50	# FULLWIDTH LATIN SMALL LETTER P
0x8291	0xFF51	# FULLWIDTH LATIN SMALL LETTER Q
0x8292	0xFF52	# FULLWIDTH LATIN SMALL LETTER R
0x8293	0xFF53	# FULLWIDTH LATIN SMALL LETTER S
0x8294	0xFF54	# FULLWIDTH LATIN SMALL LETTER T
0x8295	0xFF55	# FULLWIDTH LATIN SMALL LETTER U
0x8296	0xFF56	# FULLWIDTH LATIN SMALL LETTER V
0x8297	0xFF57	# FULLWIDTH LATIN SMALL LETTER W
0x8298	0xFF58	# FULLWIDTH LATIN SMALL LETTER X
0x8299	0xFF59	# FULLWIDTH LATIN SMALL LETTER Y
0x829A	0xFF5A	# FULLWIDTH LATIN SMALL LETTER Z
0x829F	0x3041	# HIRAGANA LETTER SMALL A
0x82A0	0x3042	# HIRAGANA LETTER A
0x82A1	0x3043	# HIRAGANA LETTER SMALL I
0x82A2	0x3044	# HIRAGANA LETTER I
0x82A3	0x3045	# HIRAGANA LETTER SMALL U
0x82A4	0x3046	# HIRAGANA LETTER U
0x82A5	0x3047	# HIRAGANA LETTER SMALL E
0x82A6	0x3048	# HIRAGANA LETTER E
0x82A7	0x3049	# HIRAGANA LETTER SMALL O
0x82A8	0x304A	# HIRAGANA LETTER O
0x82A9	0x304B	# HIRAGANA LETTER KA
0x82AA	0x304C	# HIRAGANA LETTER GA
0x82AB	0x304D	# HIRAGANA LETTER KI
0x82AC	0x304E	# HIRAGANA LETTER GI
0x82AD	0x304F	# HIRAGANA LETTER KU
0x82AE	0x3050	# HIRAGANA LETTER GU
0x82AF	0x3051	# HIRAGANA LETTER KE
0x82B0	0x3052	# HIRAGANA LETTER GE
0x82B1	0x3053	# HIRAGANA LETTER KO
0x82B2	0x3054	# HIRAGANA LETTER GO
0x82B3	0x3055	# HIRAGANA LETTER SA
0x82B4	0x3056	# HIRAGANA LETTER ZA
0x82B5	0x3057	# HIRAGANA LETTER SI
0x82B6	0x3058	# HIRAGANA LETTER ZI
0x82B7	0x3059	# HIRAGANA LETTER SU
0x82B8	0x305A	# HIRAGANA LETTER ZU
0x82B9	0x305B	# HIRAGANA LETTER SE
0x82BA	0x305C	# HIRAGANA LETTER ZE
0x82BB	0x305D	# HIRAGANA LETTER SO
0x82BC	0x305E	# HIRAGANA LETTER ZO
0x82BD	0x305F	# HIRAGANA LETTER TA
0x82BE	0x3060	# HIRAGANA LETTER DA
0x82BF	0x3061	# HIRAGANA LETTER TI
0x82C0	0x3062	# HIRAGANA LETTER DI
0x82C1	0x3063	# HIRAGANA LETTER SMALL TU
0x82C2	0x3064	# HIRAGANA LETTER TU
0x82C3	0x3065	# HIRAGANA LETTER DU
0x82C4	0x3066	# HIRAGANA LETTER TE
0x82C5	0x3067	# HIRAGANA LETTER DE
0x82C6	0x3068	# HIRAGANA LETTER TO
0x82C7	0x3069	# HIRAGANA LETTER DO
0x82C8	0x306A	# HIRAGANA LETTER NA
0x82C9	0x306B	# HIRAGANA LETTER NI
0x82CA	0x306C	# HIRAGANA LETTER NU
0x82CB	0x306D	# HIRAGANA LETTER NE
0x82CC	0x306E	# HIRAGANA LETTER NO
0x82CD	0x306F	# HIRAGANA LETTER HA
0x82CE	0x3070	# HIRAGANA LETTER BA
0x82CF	0x3071	# HIRAGANA LETTER PA
0x82D0	0x3072	# HIRAGANA LETTER HI
0x82D1	0x3073	# HIRAGANA LETTER BI
0x82D2	0x3074	# HIRAGANA LETTER PI
0x82D3	0x3075	# HIRAGANA LETTER HU
0x82D4	0x3076	# HIRAGANA LETTER BU
0x82D5	0x3077	# HIRAGANA LETTER PU
0x82D6	0x3078	# HIRAGANA LETTER HE
0x82D7	0x3079	# HIRAGANA LETTER BE
0x82D8	0x307A	# HIRAGANA LETTER PE
0x82D9	0x307B	# HIRAGANA LETTER HO
0x82DA	0x307C	# HIRAGANA LETTER BO
0x82DB	0x307D	# HIRAGANA LETTER PO
0x82DC	0x307E	# HIRAGANA LETTER MA
0x82DD	0x307F	# HIRAGANA LETTER MI
0x82DE	0x3080	# HIRAGANA LETTER MU
0x82DF	0x3081	# HIRAGANA LETTER ME
0x82E0	0x3082	# HIRAGANA LETTER MO
0x82E1	0x3083	# HIRAGANA LETTER SMALL YA
0x82E2	0x3084	# HIRAGANA LETTER YA
0x82E3	0x3085	# HIRAGANA LETTER SMALL YU
0x82E4	0x3086	# HIRAGANA LETTER YU
0x82E5	0x3087	# HIRAGANA LETTER SMALL YO
0x82E6	0x3088	# HIRAGANA LETTER YO
0x82E7	0x3089	# HIRAGANA LETTER RA
0x82E8	0x308A	# HIRAGANA LETTER RI
0x82E9	0x308B	# HIRAGANA LETTER RU
0x82EA	0x308C	# HIRAGANA LETTER RE
0x82EB	0x308D	# HIRAGANA LETTER RO
0x82EC	0x308E	# HIRAGANA LETTER SMALL WA
0x82ED	0x308F	# HIRAGANA LETTER WA
0x82EE	0x3090	# HIRAGANA LETTER WI
0x82EF	0x3091	# HIRAGANA LETTER WE
0x82F0	0x3092	# HIRAGANA LETTER WO
0x82F1	0x3093	# HIRAGANA LETTER N
0x8340	0x30A1	# KATAKANA LETTER SMALL A
0x8341	0x30A2	# KATAKANA LETTER A
0x8342	0x30A3	# KATAKANA LETTER SMALL I
0x8343	0x30A4	# KATAKANA LETTER I
0x8344	0x30A5	# KATAKANA LETTER SMALL U
0x8345	0x30A6	# KATAKANA LETTER U
0x8346	0x30A7	# KATAKANA LETTER SMALL E
0x8347	0x30A8	# KATAKANA LETTER E
0x8348	0x30A9	# KATAKANA LETTER SMALL O
0x8349	0x30AA	# KATAKANA LETTER O
0x834A	0x30AB	# KATAKANA LETTER KA
0x834B	0x30AC	# KATAKANA LETTER GA
0x834C	0x30AD	# KATAKANA LETTER KI
0x834D	0x30AE	# KATAKANA LETTER GI
0x834E	0x30AF	# KATAKANA LETTER KU
0x834F	0x30B0	# KATAKANA LETTER GU
0x8350	0x30B1	# KATAKANA LETTER KE
0x8351	0x30B2	# KATAKANA LETTER GE
0x8352	0x30B3	# KATAKANA LETTER KO
0x8353	0x30B4	# KATAKANA LETTER GO
0x8354	0x30B5	# KATAKANA LETTER SA
0x8355	0x30B6	# KATAKANA LETTER ZA
0x8356	0x30B7	# KATAKANA LETTER SI
0x8357	0x30B8	# KATAKANA LETTER ZI
0x8358	0x30B9	# KATAKANA LETTER SU
0x8359	0x30BA	# KATAKANA LETTER ZU
0x835A	0x30BB	# KATAKANA LETTER SE
0x835B	0x30BC	# KATAKANA LETTER ZE
0x835C	0x30BD	# KATAKANA LETTER SO
0x835D	0x30BE	# KATAKANA LETTER ZO
0x835E	0x30BF	# KATAKANA LETTER TA
0x835F	0x30C0	# KATAKANA LETTER DA
0x8360	0x30C1	# KATAKANA LETTER TI
0x8361	0x30C2	# KATAKANA LETTER DI
0x8362	0x30C3	# KATAKANA LETTER SMALL TU
0x8363	0x30C4	# KATAKANA LETTER TU
0x8364	0x30C5	# KATAKANA LETTER DU
0x8365	0x30C6	# KATAKANA LETTER TE
0x8366	0x30C7	# KATAKANA LETTER DE
0x8367	0x30C8	# KATAKANA LETTER TO
0x8368	0x30C9	# KATAKANA LETTER DO
0x8369	0x30CA	# KATAKANA LETTER NA
0x836A	0x30CB	# KATAKANA LETTER NI
0x836B	0x30CC	# KATAKANA LETTER NU
0x836C	0x30CD	# KATAKANA LETTER NE
0x836D	0x30CE	# KATAKANA LETTER NO
0x836E	0x30CF	# KATAKANA LETTER HA
0x836F	0x30D0	# KATAKANA LETTER BA
0x8370	0x30D1	# KATAKANA LETTER PA
0x8371	0x30D2	# KATAKANA LETTER HI
0x8372	0x30D3	# KATAKANA LETTER BI
0x8373	0x30D4	# KATAKANA LETTER PI
0x8374	0x30D5	# KATAKANA LETTER HU
0x8375	0x30D6	# KATAKANA LETTER BU
0x8376	0x30D7	# KATAKANA LETTER PU
0x8377	0x30D8	# KATAKANA LETTER HE
0x8378	0x30D9	# KATAKANA LETTER BE
0x8379	0x30DA	# KATAKANA LETTER PE
0x837A	0x30DB	# KATAKANA LETTER HO
0x837B	0x30DC	# KATAKANA LETTER BO
0x837C	0x30DD	# KATAKANA LETTER PO
0x837D	0x30DE	# KATAKANA LETTER MA
0x837E	0x30DF	# KATAKANA LETTER MI
0x8380	0x30E0	# KATAKANA LETTER MU
0x8381	0x30E1	# KATAKANA LETTER ME
0x8382	0x30E2	# KATAKANA LETTER MO
0x8383	0x30E3	# KATAKANA LETTER SMALL YA
0x8384	0x30E4	# KATAKANA LETTER YA
0x8385	0x30E5	# KATAKANA LETTER SMALL YU
0x8386	0x30E6	# KATAKANA LETTER YU
0x8387	0x30E7	# KATAKANA LETTER SMALL YO
0x8388	0x30E8	# KATAKANA LETTER YO
0x8389	0x30E9	# KATAKANA LETTER RA
0x838A	0x30EA	# KATAKANA LETTER RI
0x838B	0x30EB	# KATAKANA LETTER RU
0x838C	0x30EC	# KATAKANA LETTER RE
0x838D	0x30ED	# KATAKANA LETTER RO
0x838E	0x30EE	# KATAKANA LETTER SMALL WA
0x838F	0x30EF	# KATAKANA LETTER WA
0x8390	0x30F0	# KATAKANA LETTER WI
0x8391	0x30F1	# KATAKANA LETTER WE
0x8392	0x30F2	# KATAKANA LETTER WO
0x8393	0x30F3	# KATAKANA LETTER N
0x8394	0x30F4	# KATAKANA LETTER VU
0x8395	0x30F5	# KATAKANA LETTER SMALL KA
0x8396	0x30F6	# KATAKANA LETTER SMALL KE
0x839F	0x0391	# GREEK CAPITAL LETTER ALPHA
0x83A0	0x0392	# GREEK CAPITAL LETTER BETA
0x83A1	0x0393	# GREEK CAPITAL LETTER GAMMA
0x83A2	0x0394	# GREEK CAPITAL LETTER DELTA
0x83A3	0x0395	# GREEK CAPITAL LETTER EPSILON
0x83A4	0x0396	# GREEK CAPITAL LETTER ZETA
0x83A5	0x0397	# GREEK CAPITAL LETTER ETA
0x83A6	0x0398	# GREEK CAPITAL LETTER THETA
0x83A7	0x0399	# GREEK CAPITAL LETTER IOTA
0x83A8	0x039A	# GREEK CAPITAL LETTER KAPPA
0x83A9	0x039B	# GREEK CAPITAL LETTER LAMBDA
0x83AA	0x039C	# GREEK CAPITAL LETTER MU
0x83AB	0x039D	# GREEK CAPITAL LETTER NU
0x83AC	0x039E	# GREEK CAPITAL LETTER XI
0x83AD	0x039F	# GREEK CAPITAL LETTER OMICRON
0x83AE	0x03A0	# GREEK CAPITAL LETTER PI
0x83AF	0x03A1	# GREEK CAPITAL LETTER RHO
0x83B0	0x03A3	# GREEK CAPITAL LETTER SIGMA
0x83B1	0x03A4	# GREEK CAPITAL LETTER TAU
0x83B2	0x03A5	# GREEK CAPITAL LETTER UPSILON
0x83B3	0x03A6	# GREEK CAPITAL LETTER PHI
0x83B4	0x03A7	# GREEK CAPITAL LETTER CHI
0x83B5	0x03A8	# GREEK CAPITAL LETTER PSI
0x83B6	0x03A9	# GREEK CAPITAL LETTER OMEGA
0x83BF	0x03B1	# GREEK SMALL LETTER ALPHA
0x83C0	0x03B2	# GREEK SMALL LETTER BETA
0x83C1	0x03B3	# GREEK SMALL LETTER GAMMA
0x83C2	0x03B4	# GREEK SMALL LETTER DELTA
0x83C3	0x03B5	# GREEK SMALL LETTER EPSILON
0x83C4	0x03B6	# GREEK SMALL LETTER ZETA
0x83C5	0x03B7	# GREEK SMALL LETTER ETA
0x83C6	0x03B8	# GREEK SMALL LETTER THETA
0x83C7	0x03B9	# GREEK SMALL LETTER IOTA
0x83C8	0x03BA	# GREEK SMALL LETTER KAPPA
0x83C9	0x03BB	# GREEK SMALL LETTER LAMBDA
0x83CA	0x03BC	# GREEK SMALL LETTER MU
0x83CB	0x03BD	# GREEK SMALL LETTER NU
0x83CC	0x03BE	# GREEK SMALL LETTER XI
0x83CD	0x03BF	# GREEK SMALL LETTER OMICRON
0x83CE	0x03C0	# GREEK SMALL LETTER PI
0x83CF	0x03C1	# GREEK SMALL LETTER RHO
0x83D0	0x03C3	# GREEK SMALL LETTER SIGMA
0x83D1	0x03C4	# GREEK SMALL LETTER TAU
0x83D2	0x03C5	# GREEK SMALL LETTER UPSILON
0x83D3	0x03C6	# GREEK SMALL LETTER PHI
0x83D4	0x03C7	# GREEK SMALL LETTER CHI
0x83D5	0x03C8	# GREEK SMALL LETTER PSI
0x83D6	0x03C9	# GREEK SMALL LETTER OMEGA
0x8440	0x0410	# CYRILLIC CAPITAL LETTER A
0x8441	0x0411	# CYRILLIC CAPITAL LETTER BE
0x8442	0x0412	# CYRILLIC CAPITAL LETTER VE
0x8443	0x0413	# CYRILLIC CAPITAL LETTER GHE
0x8444	0x0414	# CYRILLIC CAPITAL LETTER DE
0x8445	0x0415	# CYRILLIC CAPITAL LETTER IE
0x8446	0x0401	# CYRILLIC CAPITAL LETTER IO
0x8447	0x0416	# CYRILLIC CAPITAL LETTER ZHE
0x8448	0x0417	# CYRILLIC CAPITAL LETTER ZE
0x8449	0x0418	# CYRILLIC CAPITAL LETTER I
0x844A	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
0x844B	0x041A	# CYRILLIC CAPITAL LETTER KA
0x844C	0x041B	# CYRILLIC CAPITAL LETTER EL
0x844D	0x041C	# CYRILLIC CAPITAL LETTER EM
0x844E	0x041D	# CYRILLIC CAPITAL LETTER EN
0x844F	0x041E	# CYRILLIC CAPITAL LETTER O
0x8450	0x041F	# CYRILLIC CAPITAL LETTER PE
0x8451	0x0420	# CYRILLIC CAPITAL LETTER ER
0x8452	0x0421	# CYRILLIC CAPITAL LETTER ES
0x8453	0x0422	# CYRILLIC CAPITAL LETTER TE
0x8454	0x0423	# CYRILLIC CAPITAL LETTER U
0x8455	0x0424	# CYRILLIC CAPITAL LETTER EF
0x8456	0x0425	# CYRILLIC CAPITAL LETTER HA
0x8457	0x0426	# CYRILLIC CAPITAL LETTER TSE
0x8458	0x0427	# CYRILLIC CAPITAL LETTER CHE
0x8459	0x0428	# CYRILLIC CAPITAL LETTER SHA
0x845A	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
0x845B	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
0x845C	0x042B	# CYRILLIC CAPITAL LETTER YERU
0x845D	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
0x845E	0x042D	# CYRILLIC CAPITAL LETTER E
0x845F	0x042E	# CYRILLIC CAPITAL LETTER YU
0x8460	0x042F	# CYRILLIC CAPITAL LETTER YA
0x8470	0x0430	# CYRILLIC SMALL LETTER A
0x8471	0x0431	# CYRILLIC SMALL LETTER BE
0x8472	0x0432	# CYRILLIC SMALL LETTER VE
0x8473	0x0433	# CYRILLIC SMALL LETTER GHE
0x8474	0x0434	# CYRILLIC SMALL LETTER DE
0x8475	0x0435	# CYRILLIC SMALL LETTER IE
0x8476	0x0451	# CYRILLIC SMALL LETTER IO
0x8477	0x0436	# CYRILLIC SMALL LETTER ZHE
0x8478	0x0437	# CYRILLIC SMALL LETTER ZE
0x8479	0x0438	# CYRILLIC SMALL LETTER I
0x847A	0x0439	# CYRILLIC SMALL LETTER SHORT I
0x847B	0x043A	# CYRILLIC SMALL LETTER KA
0x847C	0x043B	# CYRILLIC SMALL LETTER EL
0x847D	0x043C	# CYRILLIC SMALL LETTER EM
0x847E	0x043D	# CYRILLIC SMALL LETTER EN
0x8480	0x043E	# CYRILLIC SMALL LETTER O
0x8481	0x043F	# CYRILLIC SMALL LETTER PE
0x8482	0x0440	# CYRILLIC SMALL LETTER ER
0x8483	0x0441	# CYRILLIC SMALL LETTER ES
0x8484	0x0442	# CYRILLIC SMALL LETTER TE
0x8485	0x0443	# CYRILLIC SMALL LETTER U
0x8486	0x0444	# CYRILLIC SMALL LETTER EF
0x8487	0x0445	# CYRILLIC SMALL LETTER HA
0x8488	0x0446	# CYRILLIC SMALL LETTER TSE
0x8489	0x0447	# CYRILLIC SMALL LETTER CHE
0x848A	0x0448	# CYRILLIC SMALL LETTER SHA
0x848B	0x0449	# CYRILLIC SMALL LETTER SHCHA
0x848C	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
0x848D	0x044B	# CYRILLIC SMALL LETTER YERU
0x848E	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
0x848F	0x044D	# CYRILLIC SMALL LETTER E
0x8490	0x044E	# CYRILLIC SMALL LETTER YU
0x8491	0x044F	# CYRILLIC SMALL LETTER YA
0x849F	0x2500	# BOX DRAWINGS LIGHT HORIZONTAL
0x84A0	0x2502	# BOX DRAWINGS LIGHT VERTICAL
0x84A1	0x250C	# BOX DRAWINGS LIGHT DOWN AND RIGHT
0x84A2	0x2510	# BOX DRAWINGS LIGHT DOWN AND LEFT
0x84A3	0x2518	# BOX DRAWINGS LIGHT UP AND LEFT
0x84A4	0x2514	# BOX DRAWINGS LIGHT UP AND RIGHT
0x84A5	0x251C	# BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0x84A6	0x252C	# BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0x84A7	0x2524	# BOX DRAWINGS LIGHT VERTICAL AND LEFT
0x84A8	0x2534	# BOX DRAWINGS LIGHT UP AND HORIZONTAL
0x84A9	0x253C	# BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0x84AA	0x2501	# BOX DRAWINGS HEAVY HORIZONTAL
0x84AB	0x2503	# BOX DRAWINGS HEAVY VERTICAL
0x84AC	0x250F	# BOX DRAWINGS HEAVY DOWN AND RIGHT
0x84AD	0x2513	# BOX DRAWINGS HEAVY DOWN AND LEFT
0x84AE	0x251B	# BOX DRAWINGS HEAVY UP AND LEFT
0x84AF	0x2517	# BOX DRAWINGS HEAVY UP AND RIGHT
0x84B0	0x2523	# BOX DRAWINGS HEAVY VERTICAL AND RIGHT
0x84B1	0x2533	# BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
0x84B2	0x252B	# BOX DRAWINGS HEAVY VERTICAL AND LEFT
0x84B3	0x253B	# BOX DRAWINGS HEAVY UP AND HORIZONTAL
0x84B4	0x254B	# BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
0x84B5	0x2520	# BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
0x84B6	0x252F	# BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
0x84B7	0x2528	# BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
0x84B8	0x2537	# BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
0x84B9	0x253F	# BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
0x84BA	0x251D	# BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
0x84BB	0x2530	# BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
0x84BC	0x2525	# BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
0x84BD	0x2538	# BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
0x84BE	0x2542	# BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
0x889F	0x4E9C	# <CJK>
0x88A0	0x5516	# <CJK>
0x88A1	0x5A03	# <CJK>
0x88A2	0x963F	# <CJK>
0x88A3	0x54C0	# <CJK>
0x88A4	0x611B	# <CJK>
0x88A5	0x6328	# <CJK>
0x88A6	0x59F6	# <CJK>
0x88A7	0x9022	# <CJK>
0x88A8	0x8475	# <CJK>
0x88A9	0x831C	# <CJK>
0x88AA	0x7A50	# <CJK>
0x88AB	0x60AA	# <CJK>
0x88AC	0x63E1	# <CJK>
0x88AD	0x6E25	# <CJK>
0x88AE	0x65ED	# <CJK>
0x88AF	0x8466	# <CJK>
0x88B0	0x82A6	# <CJK>
0x88B1	0x9BF5	# <CJK>
0x88B2	0x6893	# <CJK>
0x88B3	0x5727	# <CJK>
0x88B4	0x65A1	# <CJK>
0x88B5	0x6271	# <CJK>
0x88B6	0x5B9B	# <CJK>
0x88B7	0x59D0	# <CJK>
0x88B8	0x867B	# <CJK>
0x88B9	0x98F4	# <CJK>
0x88BA	0x7D62	# <CJK>
0x88BB	0x7DBE	# <CJK>
0x88BC	0x9B8E	# <CJK>
0x88BD	0x6216	# <CJK>
0x88BE	0x7C9F	# <CJK>
0x88BF	0x88B7	# <CJK>
0x88C0	0x5B89	# <CJK>
0x88C1	0x5EB5	# <CJK>
0x88C2	0x6309	# <CJK>
0x88C3	0x6697	# <CJK>
0x88C4	0x6848	# <CJK>
0x88C5	0x95C7	# <CJK>
0x88C6	0x978D	# <CJK>
0x88C7	0x674F	# <CJK>
0x88C8	0x4EE5	# <CJK>
0x88C9	0x4F0A	# <CJK>
0x88CA	0x4F4D	# <CJK>
0x88CB	0x4F9D	# <CJK>
0x88CC	0x5049	# <CJK>
0x88CD	0x56F2	# <CJK>
0x88CE	0x5937	# <CJK>
0x88CF	0x59D4	# <CJK>
0x88D0	0x5A01	# <CJK>
0x88D1	0x5C09	# <CJK>
0x88D2	0x60DF	# <CJK>
0x88D3	0x610F	# <CJK>
0x88D4	0x6170	# <CJK>
0x88D5	0x6613	# <CJK>
0x88D6	0x6905	# <CJK>
0x88D7	0x70BA	# <CJK>
0x88D8	0x754F	# <CJK>
0x88D9	0x7570	# <CJK>
0x88DA	0x79FB	# <CJK>
0x88DB	0x7DAD	# <CJK>
0x88DC	0x7DEF	# <CJK>
0x88DD	0x80C3	# <CJK>
0x88DE	0x840E	# <CJK>
0x88DF	0x8863	# <CJK>
0x88E0	0x8B02	# <CJK>
0x88E1	0x9055	# <CJK>
0x88E2	0x907A	# <CJK>
0x88E3	0x533B	# <CJK>
0x88E4	0x4E95	# <CJK>
0x88E5	0x4EA5	# <CJK>
0x88E6	0x57DF	# <CJK>
0x88E7	0x80B2	# <CJK>
0x88E8	0x90C1	# <CJK>
0x88E9	0x78EF	# <CJK>
0x88EA	0x4E00	# <CJK>
0x88EB	0x58F1	# <CJK>
0x88EC	0x6EA2	# <CJK>
0x88ED	0x9038	# <CJK>
0x88EE	0x7A32	# <CJK>
0x88EF	0x8328	# <CJK>
0x88F0	0x828B	# <CJK>
0x88F1	0x9C2F	# <CJK>
0x88F2	0x5141	# <CJK>
0x88F3	0x5370	# <CJK>
0x88F4	0x54BD	# <CJK>
0x88F5	0x54E1	# <CJK>
0x88F6	0x56E0	# <CJK>
0x88F7	0x59FB	# <CJK>
0x88F8	0x5F15	# <CJK>
0x88F9	0x98F2	# <CJK>
0x88FA	0x6DEB	# <CJK>
0x88FB	0x80E4	# <CJK>
0x88FC	0x852D	# <CJK>
0x8940	0x9662	# <CJK>
0x8941	0x9670	# <CJK>
0x8942	0x96A0	# <CJK>
0x8943	0x97FB	# <CJK>
0x8944	0x540B	# <CJK>
0x8945	0x53F3	# <CJK>
0x8946	0x5B87	# <CJK>
0x8947	0x70CF	# <CJK>
0x8948	0x7FBD	# <CJK>
0x8949	0x8FC2	# <CJK>
0x894A	0x96E8	# <CJK>
0x894B	0x536F	# <CJK>
0x894C	0x9D5C	# <CJK>
0x894D	0x7ABA	# <CJK>
0x894E	0x4E11	# <CJK>
0x894F	0x7893	# <CJK>
0x8950	0x81FC	# <CJK>
0x8951	0x6E26	# <CJK>
0x8952	0x5618	# <CJK>
0x8953	0x5504	# <CJK>
0x8954	0x6B1D	# <CJK>
0x8955	0x851A	# <CJK>
0x8956	0x9C3B	# <CJK>
0x8957	0x59E5	# <CJK>
0x8958	0x53A9	# <CJK>
0x8959	0x6D66	# <CJK>
0x895A	0x74DC	# <CJK>
0x895B	0x958F	# <CJK>
0x895C	0x5642	# <CJK>
0x895D	0x4E91	# <CJK>
0x895E	0x904B	# <CJK>
0x895F	0x96F2	# <CJK>
0x8960	0x834F	# <CJK>
0x8961	0x990C	# <CJK>
0x8962	0x53E1	# <CJK>
0x8963	0x55B6	# <CJK>
0x8964	0x5B30	# <CJK>
0x8965	0x5F71	# <CJK>
0x8966	0x6620	# <CJK>
0x8967	0x66F3	# <CJK>
0x8968	0x6804	# <CJK>
0x8969	0x6C38	# <CJK>
0x896A	0x6CF3	# <CJK>
0x896B	0x6D29	# <CJK>
0x896C	0x745B	# <CJK>
0x896D	0x76C8	# <CJK>
0x896E	0x7A4E	# <CJK>
0x896F	0x9834	# <CJK>
0x8970	0x82F1	# <CJK>
0x8971	0x885B	# <CJK>
0x8972	0x8A60	# <CJK>
0x8973	0x92ED	# <CJK>
0x8974	0x6DB2	# <CJK>
0x8975	0x75AB	# <CJK>
0x8976	0x76CA	# <CJK>
0x8977	0x99C5	# <CJK>
0x8978	0x60A6	# <CJK>
0x8979	0x8B01	# <CJK>
0x897A	0x8D8A	# <CJK>
0x897B	0x95B2	# <CJK>
0x897C	0x698E	# <CJK>
0x897D	0x53AD	# <CJK>
0x897E	0x5186	# <CJK>
0x8980	0x5712	# <CJK>
0x8981	0x5830	# <CJK>
0x8982	0x5944	# <CJK>
0x8983	0x5BB4	# <CJK>
0x8984	0x5EF6	# <CJK>
0x8985	0x6028	# <CJK>
0x8986	0x63A9	# <CJK>
0x8987	0x63F4	# <CJK>
0x8988	0x6CBF	# <CJK>
0x8989	0x6F14	# <CJK>
0x898A	0x708E	# <CJK>
0x898B	0x7114	# <CJK>
0x898C	0x7159	# <CJK>
0x898D	0x71D5	# <CJK>
0x898E	0x733F	# <CJK>
0x898F	0x7E01	# <CJK>
0x8990	0x8276	# <CJK>
0x8991	0x82D1	# <CJK>
0x8992	0x8597	# <CJK>
0x8993	0x9060	# <CJK>
0x8994	0x925B	# <CJK>
0x8995	0x9D1B	# <CJK>
0x8996	0x5869	# <CJK>
0x8997	0x65BC	# <CJK>
0x8998	0x6C5A	# <CJK>
0x8999	0x7525	# <CJK>
0x899A	0x51F9	# <CJK>
0x899B	0x592E	# <CJK>
0x899C	0x5965	# <CJK>
0x899D	0x5F80	# <CJK>
0x899E	0x5FDC	# <CJK>
0x899F	0x62BC	# <CJK>
0x89A0	0x65FA	# <CJK>
0x89A1	0x6A2A	# <CJK>
0x89A2	0x6B27	# <CJK>
0x89A3	0x6BB4	# <CJK>
0x89A4	0x738B	# <CJK>
0x89A5	0x7FC1	# <CJK>
0x89A6	0x8956	# <CJK>
0x89A7	0x9D2C	# <CJK>
0x89A8	0x9D0E	# <CJK>
0x89A9	0x9EC4	# <CJK>
0x89AA	0x5CA1	# <CJK>
0x89AB	0x6C96	# <CJK>
0x89AC	0x837B	# <CJK>
0x89AD	0x5104	# <CJK>
0x89AE	0x5C4B	# <CJK>
0x89AF	0x61B6	# <CJK>
0x89B0	0x81C6	# <CJK>
0x89B1	0x6876	# <CJK>
0x89B2	0x7261	# <CJK>
0x89B3	0x4E59	# <CJK>
0x89B4	0x4FFA	# <CJK>
0x89B5	0x5378	# <CJK>
0x89B6	0x6069	# <CJK>
0x89B7	0x6E29	# <CJK>
0x89B8	0x7A4F	# <CJK>
0x89B9	0x97F3	# <CJK>
0x89BA	0x4E0B	# <CJK>
0x89BB	0x5316	# <CJK>
0x89BC	0x4EEE	# <CJK>
0x89BD	0x4F55	# <CJK>
0x89BE	0x4F3D	# <CJK>
0x89BF	0x4FA1	# <CJK>
0x89C0	0x4F73	# <CJK>
0x89C1	0x52A0	# <CJK>
0x89C2	0x53EF	# <CJK>
0x89C3	0x5609	# <CJK>
0x89C4	0x590F	# <CJK>
0x89C5	0x5AC1	# <CJK>
0x89C6	0x5BB6	# <CJK>
0x89C7	0x5BE1	# <CJK>
0x89C8	0x79D1	# <CJK>
0x89C9	0x6687	# <CJK>
0x89CA	0x679C	# <CJK>
0x89CB	0x67B6	# <CJK>
0x89CC	0x6B4C	# <CJK>
0x89CD	0x6CB3	# <CJK>
0x89CE	0x706B	# <CJK>
0x89CF	0x73C2	# <CJK>
0x89D0	0x798D	# <CJK>
0x89D1	0x79BE	# <CJK>
0x89D2	0x7A3C	# <CJK>
0x89D3	0x7B87	# <CJK>
0x89D4	0x82B1	# <CJK>
0x89D5	0x82DB	# <CJK>
0x89D6	0x8304	# <CJK>
0x89D7	0x8377	# <CJK>
0x89D8	0x83EF	# <CJK>
0x89D9	0x83D3	# <CJK>
0x89DA	0x8766	# <CJK>
0x89DB	0x8AB2	# <CJK>
0x89DC	0x5629	# <CJK>
0x89DD	0x8CA8	# <CJK>
0x89DE	0x8FE6	# <CJK>
0x89DF	0x904E	# <CJK>
0x89E0	0x971E	# <CJK>
0x89E1	0x868A	# <CJK>
0x89E2	0x4FC4	# <CJK>
0x89E3	0x5CE8	# <CJK>
0x89E4	0x6211	# <CJK>
0x89E5	0x7259	# <CJK>
0x89E6	0x753B	# <CJK>
0x89E7	0x81E5	# <CJK>
0x89E8	0x82BD	# <CJK>
0x89E9	0x86FE	# <CJK>
0x89EA	0x8CC0	# <CJK>
0x89EB	0x96C5	# <CJK>
0x89EC	0x9913	# <CJK>
0x89ED	0x99D5	# <CJK>
0x89EE	0x4ECB	# <CJK>
0x89EF	0x4F1A	# <CJK>
0x89F0	0x89E3	# <CJK>
0x89F1	0x56DE	# <CJK>
0x89F2	0x584A	# <CJK>
0x89F3	0x58CA	# <CJK>
0x89F4	0x5EFB	# <CJK>
0x89F5	0x5FEB	# <CJK>
0x89F6	0x602A	# <CJK>
0x89F7	0x6094	# <CJK>
0x89F8	0x6062	# <CJK>
0x89F9	0x61D0	# <CJK>
0x89FA	0x6212	# <CJK>
0x89FB	0x62D0	# <CJK>
0x89FC	0x6539	# <CJK>
0x8A40	0x9B41	# <CJK>
0x8A41	0x6666	# <CJK>
0x8A42	0x68B0	# <CJK>
0x8A43	0x6D77	# <CJK>
0x8A44	0x7070	# <CJK>
0x8A45	0x754C	# <CJK>
0x8A46	0x7686	# <CJK>
0x8A47	0x7D75	# <CJK>
0x8A48	0x82A5	# <CJK>
0x8A49	0x87F9	# <CJK>
0x8A4A	0x958B	# <CJK>
0x8A4B	0x968E	# <CJK>
0x8A4C	0x8C9D	# <CJK>
0x8A4D	0x51F1	# <CJK>
0x8A4E	0x52BE	# <CJK>
0x8A4F	0x5916	# <CJK>
0x8A50	0x54B3	# <CJK>
0x8A51	0x5BB3	# <CJK>
0x8A52	0x5D16	# <CJK>
0x8A53	0x6168	# <CJK>
0x8A54	0x6982	# <CJK>
0x8A55	0x6DAF	# <CJK>
0x8A56	0x788D	# <CJK>
0x8A57	0x84CB	# <CJK>
0x8A58	0x8857	# <CJK>
0x8A59	0x8A72	# <CJK>
0x8A5A	0x93A7	# <CJK>
0x8A5B	0x9AB8	# <CJK>
0x8A5C	0x6D6C	# <CJK>
0x8A5D	0x99A8	# <CJK>
0x8A5E	0x86D9	# <CJK>
0x8A5F	0x57A3	# <CJK>
0x8A60	0x67FF	# <CJK>
0x8A61	0x86CE	# <CJK>
0x8A62	0x920E	# <CJK>
0x8A63	0x5283	# <CJK>
0x8A64	0x5687	# <CJK>
0x8A65	0x5404	# <CJK>
0x8A66	0x5ED3	# <CJK>
0x8A67	0x62E1	# <CJK>
0x8A68	0x64B9	# <CJK>
0x8A69	0x683C	# <CJK>
0x8A6A	0x6838	# <CJK>
0x8A6B	0x6BBB	# <CJK>
0x8A6C	0x7372	# <CJK>
0x8A6D	0x78BA	# <CJK>
0x8A6E	0x7A6B	# <CJK>
0x8A6F	0x899A	# <CJK>
0x8A70	0x89D2	# <CJK>
0x8A71	0x8D6B	# <CJK>
0x8A72	0x8F03	# <CJK>
0x8A73	0x90ED	# <CJK>
0x8A74	0x95A3	# <CJK>
0x8A75	0x9694	# <CJK>
0x8A76	0x9769	# <CJK>
0x8A77	0x5B66	# <CJK>
0x8A78	0x5CB3	# <CJK>
0x8A79	0x697D	# <CJK>
0x8A7A	0x984D	# <CJK>
0x8A7B	0x984E	# <CJK>
0x8A7C	0x639B	# <CJK>
0x8A7D	0x7B20	# <CJK>
0x8A7E	0x6A2B	# <CJK>
0x8A80	0x6A7F	# <CJK>
0x8A81	0x68B6	# <CJK>
0x8A82	0x9C0D	# <CJK>
0x8A83	0x6F5F	# <CJK>
0x8A84	0x5272	# <CJK>
0x8A85	0x559D	# <CJK>
0x8A86	0x6070	# <CJK>
0x8A87	0x62EC	# <CJK>
0x8A88	0x6D3B	# <CJK>
0x8A89	0x6E07	# <CJK>
0x8A8A	0x6ED1	# <CJK>
0x8A8B	0x845B	# <CJK>
0x8A8C	0x8910	# <CJK>
0x8A8D	0x8F44	# <CJK>
0x8A8E	0x4E14	# <CJK>
0x8A8F	0x9C39	# <CJK>
0x8A90	0x53F6	# <CJK>
0x8A91	0x691B	# <CJK>
0x8A92	0x6A3A	# <CJK>
0x8A93	0x9784	# <CJK>
0x8A94	0x682A	# <CJK>
0x8A95	0x515C	# <CJK>
0x8A96	0x7AC3	# <CJK>
0x8A97	0x84B2	# <CJK>
0x8A98	0x91DC	# <CJK>
0x8A99	0x938C	# <CJK>
0x8A9A	0x565B	# <CJK>
0x8A9B	0x9D28	# <CJK>
0x8A9C	0x6822	# <CJK>
0x8A9D	0x8305	# <CJK>
0x8A9E	0x8431	# <CJK>
0x8A9F	0x7CA5	# <CJK>
0x8AA0	0x5208	# <CJK>
0x8AA1	0x82C5	# <CJK>
0x8AA2	0x74E6	# <CJK>
0x8AA3	0x4E7E	# <CJK>
0x8AA4	0x4F83	# <CJK>
0x8AA5	0x51A0	# <CJK>
0x8AA6	0x5BD2	# <CJK>
0x8AA7	0x520A	# <CJK>
0x8AA8	0x52D8	# <CJK>
0x8AA9	0x52E7	# <CJK>
0x8AAA	0x5DFB	# <CJK>
0x8AAB	0x559A	# <CJK>
0x8AAC	0x582A	# <CJK>
0x8AAD	0x59E6	# <CJK>
0x8AAE	0x5B8C	# <CJK>
0x8AAF	0x5B98	# <CJK>
0x8AB0	0x5BDB	# <CJK>
0x8AB1	0x5E72	# <CJK>
0x8AB2	0x5E79	# <CJK>
0x8AB3	0x60A3	# <CJK>
0x8AB4	0x611F	# <CJK>
0x8AB5	0x6163	# <CJK>
0x8AB6	0x61BE	# <CJK>
0x8AB7	0x63DB	# <CJK>
0x8AB8	0x6562	# <CJK>
0x8AB9	0x67D1	# <CJK>
0x8ABA	0x6853	# <CJK>
0x8ABB	0x68FA	# <CJK>
0x8ABC	0x6B3E	# <CJK>
0x8ABD	0x6B53	# <CJK>
0x8ABE	0x6C57	# <CJK>
0x8ABF	0x6F22	# <CJK>
0x8AC0	0x6F97	# <CJK>
0x8AC1	0x6F45	# <CJK>
0x8AC2	0x74B0	# <CJK>
0x8AC3	0x7518	# <CJK>
0x8AC4	0x76E3	# <CJK>
0x8AC5	0x770B	# <CJK>
0x8AC6	0x7AFF	# <CJK>
0x8AC7	0x7BA1	# <CJK>
0x8AC8	0x7C21	# <CJK>
0x8AC9	0x7DE9	# <CJK>
0x8ACA	0x7F36	# <CJK>
0x8ACB	0x7FF0	# <CJK>
0x8ACC	0x809D	# <CJK>
0x8ACD	0x8266	# <CJK>
0x8ACE	0x839E	# <CJK>
0x8ACF	0x89B3	# <CJK>
0x8AD0	0x8ACC	# <CJK>
0x8AD1	0x8CAB	# <CJK>
0x8AD2	0x9084	# <CJK>
0x8AD3	0x9451	# <CJK>
0x8AD4	0x9593	# <CJK>
0x8AD5	0x9591	# <CJK>
0x8AD6	0x95A2	# <CJK>
0x8AD7	0x9665	# <CJK>
0x8AD8	0x97D3	# <CJK>
0x8AD9	0x9928	# <CJK>
0x8ADA	0x8218	# <CJK>
0x8ADB	0x4E38	# <CJK>
0x8ADC	0x542B	# <CJK>
0x8ADD	0x5CB8	# <CJK>
0x8ADE	0x5DCC	# <CJK>
0x8ADF	0x73A9	# <CJK>
0x8AE0	0x764C	# <CJK>
0x8AE1	0x773C	# <CJK>
0x8AE2	0x5CA9	# <CJK>
0x8AE3	0x7FEB	# <CJK>
0x8AE4	0x8D0B	# <CJK>
0x8AE5	0x96C1	# <CJK>
0x8AE6	0x9811	# <CJK>
0x8AE7	0x9854	# <CJK>
0x8AE8	0x9858	# <CJK>
0x8AE9	0x4F01	# <CJK>
0x8AEA	0x4F0E	# <CJK>
0x8AEB	0x5371	# <CJK>
0x8AEC	0x559C	# <CJK>
0x8AED	0x5668	# <CJK>
0x8AEE	0x57FA	# <CJK>
0x8AEF	0x5947	# <CJK>
0x8AF0	0x5B09	# <CJK>
0x8AF1	0x5BC4	# <CJK>
0x8AF2	0x5C90	# <CJK>
0x8AF3	0x5E0C	# <CJK>
0x8AF4	0x5E7E	# <CJK>
0x8AF5	0x5FCC	# <CJK>
0x8AF6	0x63EE	# <CJK>
0x8AF7	0x673A	# <CJK>
0x8AF8	0x65D7	# <CJK>
0x8AF9	0x65E2	# <CJK>
0x8AFA	0x671F	# <CJK>
0x8AFB	0x68CB	# <CJK>
0x8AFC	0x68C4	# <CJK>
0x8B40	0x6A5F	# <CJK>
0x8B41	0x5E30	# <CJK>
0x8B42	0x6BC5	# <CJK>
0x8B43	0x6C17	# <CJK>
0x8B44	0x6C7D	# <CJK>
0x8B45	0x757F	# <CJK>
0x8B46	0x7948	# <CJK>
0x8B47	0x5B63	# <CJK>
0x8B48	0x7A00	# <CJK>
0x8B49	0x7D00	# <CJK>
0x8B4A	0x5FBD	# <CJK>
0x8B4B	0x898F	# <CJK>
0x8B4C	0x8A18	# <CJK>
0x8B4D	0x8CB4	# <CJK>
0x8B4E	0x8D77	# <CJK>
0x8B4F	0x8ECC	# <CJK>
0x8B50	0x8F1D	# <CJK>
0x8B51	0x98E2	# <CJK>
0x8B52	0x9A0E	# <CJK>
0x8B53	0x9B3C	# <CJK>
0x8B54	0x4E80	# <CJK>
0x8B55	0x507D	# <CJK>
0x8B56	0x5100	# <CJK>
0x8B57	0x5993	# <CJK>
0x8B58	0x5B9C	# <CJK>
0x8B59	0x622F	# <CJK>
0x8B5A	0x6280	# <CJK>
0x8B5B	0x64EC	# <CJK>
0x8B5C	0x6B3A	# <CJK>
0x8B5D	0x72A0	# <CJK>
0x8B5E	0x7591	# <CJK>
0x8B5F	0x7947	# <CJK>
0x8B60	0x7FA9	# <CJK>
0x8B61	0x87FB	# <CJK>
0x8B62	0x8ABC	# <CJK>
0x8B63	0x8B70	# <CJK>
0x8B64	0x63AC	# <CJK>
0x8B65	0x83CA	# <CJK>
0x8B66	0x97A0	# <CJK>
0x8B67	0x5409	# <CJK>
0x8B68	0x5403	# <CJK>
0x8B69	0x55AB	# <CJK>
0x8B6A	0x6854	# <CJK>
0x8B6B	0x6A58	# <CJK>
0x8B6C	0x8A70	# <CJK>
0x8B6D	0x7827	# <CJK>
0x8B6E	0x6775	# <CJK>
0x8B6F	0x9ECD	# <CJK>
0x8B70	0x5374	# <CJK>
0x8B71	0x5BA2	# <CJK>
0x8B72	0x811A	# <CJK>
0x8B73	0x8650	# <CJK>
0x8B74	0x9006	# <CJK>
0x8B75	0x4E18	# <CJK>
0x8B76	0x4E45	# <CJK>
0x8B77	0x4EC7	# <CJK>
0x8B78	0x4F11	# <CJK>
0x8B79	0x53CA	# <CJK>
0x8B7A	0x5438	# <CJK>
0x8B7B	0x5BAE	# <CJK>
0x8B7C	0x5F13	# <CJK>
0x8B7D	0x6025	# <CJK>
0x8B7E	0x6551	# <CJK>
0x8B80	0x673D	# <CJK>
0x8B81	0x6C42	# <CJK>
0x8B82	0x6C72	# <CJK>
0x8B83	0x6CE3	# <CJK>
0x8B84	0x7078	# <CJK>
0x8B85	0x7403	# <CJK>
0x8B86	0x7A76	# <CJK>
0x8B87	0x7AAE	# <CJK>
0x8B88	0x7B08	# <CJK>
0x8B89	0x7D1A	# <CJK>
0x8B8A	0x7CFE	# <CJK>
0x8B8B	0x7D66	# <CJK>
0x8B8C	0x65E7	# <CJK>
0x8B8D	0x725B	# <CJK>
0x8B8E	0x53BB	# <CJK>
0x8B8F	0x5C45	# <CJK>
0x8B90	0x5DE8	# <CJK>
0x8B91	0x62D2	# <CJK>
0x8B92	0x62E0	# <CJK>
0x8B93	0x6319	# <CJK>
0x8B94	0x6E20	# <CJK>
0x8B95	0x865A	# <CJK>
0x8B96	0x8A31	# <CJK>
0x8B97	0x8DDD	# <CJK>
0x8B98	0x92F8	# <CJK>
0x8B99	0x6F01	# <CJK>
0x8B9A	0x79A6	# <CJK>
0x8B9B	0x9B5A	# <CJK>
0x8B9C	0x4EA8	# <CJK>
0x8B9D	0x4EAB	# <CJK>
0x8B9E	0x4EAC	# <CJK>
0x8B9F	0x4F9B	# <CJK>
0x8BA0	0x4FA0	# <CJK>
0x8BA1	0x50D1	# <CJK>
0x8BA2	0x5147	# <CJK>
0x8BA3	0x7AF6	# <CJK>
0x8BA4	0x5171	# <CJK>
0x8BA5	0x51F6	# <CJK>
0x8BA6	0x5354	# <CJK>
0x8BA7	0x5321	# <CJK>
0x8BA8	0x537F	# <CJK>
0x8BA9	0x53EB	# <CJK>
0x8BAA	0x55AC	# <CJK>
0x8BAB	0x5883	# <CJK>
0x8BAC	0x5CE1	# <CJK>
0x8BAD	0x5F37	# <CJK>
0x8BAE	0x5F4A	# <CJK>
0x8BAF	0x602F	# <CJK>
0x8BB0	0x6050	# <CJK>
0x8BB1	0x606D	# <CJK>
0x8BB2	0x631F	# <CJK>
0x8BB3	0x6559	# <CJK>
0x8BB4	0x6A4B	# <CJK>
0x8BB5	0x6CC1	# <CJK>
0x8BB6	0x72C2	# <CJK>
0x8BB7	0x72ED	# <CJK>
0x8BB8	0x77EF	# <CJK>
0x8BB9	0x80F8	# <CJK>
0x8BBA	0x8105	# <CJK>
0x8BBB	0x8208	# <CJK>
0x8BBC	0x854E	# <CJK>
0x8BBD	0x90F7	# <CJK>
0x8BBE	0x93E1	# <CJK>
0x8BBF	0x97FF	# <CJK>
0x8BC0	0x9957	# <CJK>
0x8BC1	0x9A5A	# <CJK>
0x8BC2	0x4EF0	# <CJK>
0x8BC3	0x51DD	# <CJK>
0x8BC4	0x5C2D	# <CJK>
0x8BC5	0x6681	# <CJK>
0x8BC6	0x696D	# <CJK>
0x8BC7	0x5C40	# <CJK>
0x8BC8	0x66F2	# <CJK>
0x8BC9	0x6975	# <CJK>
0x8BCA	0x7389	# <CJK>
0x8BCB	0x6850	# <CJK>
0x8BCC	0x7C81	# <CJK>
0x8BCD	0x50C5	# <CJK>
0x8BCE	0x52E4	# <CJK>
0x8BCF	0x5747	# <CJK>
0x8BD0	0x5DFE	# <CJK>
0x8BD1	0x9326	# <CJK>
0x8BD2	0x65A4	# <CJK>
0x8BD3	0x6B23	# <CJK>
0x8BD4	0x6B3D	# <CJK>
0x8BD5	0x7434	# <CJK>
0x8BD6	0x7981	# <CJK>
0x8BD7	0x79BD	# <CJK>
0x8BD8	0x7B4B	# <CJK>
0x8BD9	0x7DCA	# <CJK>
0x8BDA	0x82B9	# <CJK>
0x8BDB	0x83CC	# <CJK>
0x8BDC	0x887F	# <CJK>
0x8BDD	0x895F	# <CJK>
0x8BDE	0x8B39	# <CJK>
0x8BDF	0x8FD1	# <CJK>
0x8BE0	0x91D1	# <CJK>
0x8BE1	0x541F	# <CJK>
0x8BE2	0x9280	# <CJK>
0x8BE3	0x4E5D	# <CJK>
0x8BE4	0x5036	# <CJK>
0x8BE5	0x53E5	# <CJK>
0x8BE6	0x533A	# <CJK>
0x8BE7	0x72D7	# <CJK>
0x8BE8	0x7396	# <CJK>
0x8BE9	0x77E9	# <CJK>
0x8BEA	0x82E6	# <CJK>
0x8BEB	0x8EAF	# <CJK>
0x8BEC	0x99C6	# <CJK>
0x8BED	0x99C8	# <CJK>
0x8BEE	0x99D2	# <CJK>
0x8BEF	0x5177	# <CJK>
0x8BF0	0x611A	# <CJK>
0x8BF1	0x865E	# <CJK>
0x8BF2	0x55B0	# <CJK>
0x8BF3	0x7A7A	# <CJK>
0x8BF4	0x5076	# <CJK>
0x8BF5	0x5BD3	# <CJK>
0x8BF6	0x9047	# <CJK>
0x8BF7	0x9685	# <CJK>
0x8BF8	0x4E32	# <CJK>
0x8BF9	0x6ADB	# <CJK>
0x8BFA	0x91E7	# <CJK>
0x8BFB	0x5C51	# <CJK>
0x8BFC	0x5C48	# <CJK>
0x8C40	0x6398	# <CJK>
0x8C41	0x7A9F	# <CJK>
0x8C42	0x6C93	# <CJK>
0x8C43	0x9774	# <CJK>
0x8C44	0x8F61	# <CJK>
0x8C45	0x7AAA	# <CJK>
0x8C46	0x718A	# <CJK>
0x8C47	0x9688	# <CJK>
0x8C48	0x7C82	# <CJK>
0x8C49	0x6817	# <CJK>
0x8C4A	0x7E70	# <CJK>
0x8C4B	0x6851	# <CJK>
0x8C4C	0x936C	# <CJK>
0x8C4D	0x52F2	# <CJK>
0x8C4E	0x541B	# <CJK>
0x8C4F	0x85AB	# <CJK>
0x8C50	0x8A13	# <CJK>
0x8C51	0x7FA4	# <CJK>
0x8C52	0x8ECD	# <CJK>
0x8C53	0x90E1	# <CJK>
0x8C54	0x5366	# <CJK>
0x8C55	0x8888	# <CJK>
0x8C56	0x7941	# <CJK>
0x8C57	0x4FC2	# <CJK>
0x8C58	0x50BE	# <CJK>
0x8C59	0x5211	# <CJK>
0x8C5A	0x5144	# <CJK>
0x8C5B	0x5553	# <CJK>
0x8C5C	0x572D	# <CJK>
0x8C5D	0x73EA	# <CJK>
0x8C5E	0x578B	# <CJK>
0x8C5F	0x5951	# <CJK>
0x8C60	0x5F62	# <CJK>
0x8C61	0x5F84	# <CJK>
0x8C62	0x6075	# <CJK>
0x8C63	0x6176	# <CJK>
0x8C64	0x6167	# <CJK>
0x8C65	0x61A9	# <CJK>
0x8C66	0x63B2	# <CJK>
0x8C67	0x643A	# <CJK>
0x8C68	0x656C	# <CJK>
0x8C69	0x666F	# <CJK>
0x8C6A	0x6842	# <CJK>
0x8C6B	0x6E13	# <CJK>
0x8C6C	0x7566	# <CJK>
0x8C6D	0x7A3D	# <CJK>
0x8C6E	0x7CFB	# <CJK>
0x8C6F	0x7D4C	# <CJK>
0x8C70	0x7D99	# <CJK>
0x8C71	0x7E4B	# <CJK>
0x8C72	0x7F6B	# <CJK>
0x8C73	0x830E	# <CJK>
0x8C74	0x834A	# <CJK>
0x8C75	0x86CD	# <CJK>
0x8C76	0x8A08	# <CJK>
0x8C77	0x8A63	# <CJK>
0x8C78	0x8B66	# <CJK>
0x8C79	0x8EFD	# <CJK>
0x8C7A	0x981A	# <CJK>
0x8C7B	0x9D8F	# <CJK>
0x8C7C	0x82B8	# <CJK>
0x8C7D	0x8FCE	# <CJK>
0x8C7E	0x9BE8	# <CJK>
0x8C80	0x5287	# <CJK>
0x8C81	0x621F	# <CJK>
0x8C82	0x6483	# <CJK>
0x8C83	0x6FC0	# <CJK>
0x8C84	0x9699	# <CJK>
0x8C85	0x6841	# <CJK>
0x8C86	0x5091	# <CJK>
0x8C87	0x6B20	# <CJK>
0x8C88	0x6C7A	# <CJK>
0x8C89	0x6F54	# <CJK>
0x8C8A	0x7A74	# <CJK>
0x8C8B	0x7D50	# <CJK>
0x8C8C	0x8840	# <CJK>
0x8C8D	0x8A23	# <CJK>
0x8C8E	0x6708	# <CJK>
0x8C8F	0x4EF6	# <CJK>
0x8C90	0x5039	# <CJK>
0x8C91	0x5026	# <CJK>
0x8C92	0x5065	# <CJK>
0x8C93	0x517C	# <CJK>
0x8C94	0x5238	# <CJK>
0x8C95	0x5263	# <CJK>
0x8C96	0x55A7	# <CJK>
0x8C97	0x570F	# <CJK>
0x8C98	0x5805	# <CJK>
0x8C99	0x5ACC	# <CJK>
0x8C9A	0x5EFA	# <CJK>
0x8C9B	0x61B2	# <CJK>
0x8C9C	0x61F8	# <CJK>
0x8C9D	0x62F3	# <CJK>
0x8C9E	0x6372	# <CJK>
0x8C9F	0x691C	# <CJK>
0x8CA0	0x6A29	# <CJK>
0x8CA1	0x727D	# <CJK>
0x8CA2	0x72AC	# <CJK>
0x8CA3	0x732E	# <CJK>
0x8CA4	0x7814	# <CJK>
0x8CA5	0x786F	# <CJK>
0x8CA6	0x7D79	# <CJK>
0x8CA7	0x770C	# <CJK>
0x8CA8	0x80A9	# <CJK>
0x8CA9	0x898B	# <CJK>
0x8CAA	0x8B19	# <CJK>
0x8CAB	0x8CE2	# <CJK>
0x8CAC	0x8ED2	# <CJK>
0x8CAD	0x9063	# <CJK>
0x8CAE	0x9375	# <CJK>
0x8CAF	0x967A	# <CJK>
0x8CB0	0x9855	# <CJK>
0x8CB1	0x9A13	# <CJK>
0x8CB2	0x9E78	# <CJK>
0x8CB3	0x5143	# <CJK>
0x8CB4	0x539F	# <CJK>
0x8CB5	0x53B3	# <CJK>
0x8CB6	0x5E7B	# <CJK>
0x8CB7	0x5F26	# <CJK>
0x8CB8	0x6E1B	# <CJK>
0x8CB9	0x6E90	# <CJK>
0x8CBA	0x7384	# <CJK>
0x8CBB	0x73FE	# <CJK>
0x8CBC	0x7D43	# <CJK>
0x8CBD	0x8237	# <CJK>
0x8CBE	0x8A00	# <CJK>
0x8CBF	0x8AFA	# <CJK>
0x8CC0	0x9650	# <CJK>
0x8CC1	0x4E4E	# <CJK>
0x8CC2	0x500B	# <CJK>
0x8CC3	0x53E4	# <CJK>
0x8CC4	0x547C	# <CJK>
0x8CC5	0x56FA	# <CJK>
0x8CC6	0x59D1	# <CJK>
0x8CC7	0x5B64	# <CJK>
0x8CC8	0x5DF1	# <CJK>
0x8CC9	0x5EAB	# <CJK>
0x8CCA	0x5F27	# <CJK>
0x8CCB	0x6238	# <CJK>
0x8CCC	0x6545	# <CJK>
0x8CCD	0x67AF	# <CJK>
0x8CCE	0x6E56	# <CJK>
0x8CCF	0x72D0	# <CJK>
0x8CD0	0x7CCA	# <CJK>
0x8CD1	0x88B4	# <CJK>
0x8CD2	0x80A1	# <CJK>
0x8CD3	0x80E1	# <CJK>
0x8CD4	0x83F0	# <CJK>
0x8CD5	0x864E	# <CJK>
0x8CD6	0x8A87	# <CJK>
0x8CD7	0x8DE8	# <CJK>
0x8CD8	0x9237	# <CJK>
0x8CD9	0x96C7	# <CJK>
0x8CDA	0x9867	# <CJK>
0x8CDB	0x9F13	# <CJK>
0x8CDC	0x4E94	# <CJK>
0x8CDD	0x4E92	# <CJK>
0x8CDE	0x4F0D	# <CJK>
0x8CDF	0x5348	# <CJK>
0x8CE0	0x5449	# <CJK>
0x8CE1	0x543E	# <CJK>
0x8CE2	0x5A2F	# <CJK>
0x8CE3	0x5F8C	# <CJK>
0x8CE4	0x5FA1	# <CJK>
0x8CE5	0x609F	# <CJK>
0x8CE6	0x68A7	# <CJK>
0x8CE7	0x6A8E	# <CJK>
0x8CE8	0x745A	# <CJK>
0x8CE9	0x7881	# <CJK>
0x8CEA	0x8A9E	# <CJK>
0x8CEB	0x8AA4	# <CJK>
0x8CEC	0x8B77	# <CJK>
0x8CED	0x9190	# <CJK>
0x8CEE	0x4E5E	# <CJK>
0x8CEF	0x9BC9	# <CJK>
0x8CF0	0x4EA4	# <CJK>
0x8CF1	0x4F7C	# <CJK>
0x8CF2	0x4FAF	# <CJK>
0x8CF3	0x5019	# <CJK>
0x8CF4	0x5016	# <CJK>
0x8CF5	0x5149	# <CJK>
0x8CF6	0x516C	# <CJK>
0x8CF7	0x529F	# <CJK>
0x8CF8	0x52B9	# <CJK>
0x8CF9	0x52FE	# <CJK>
0x8CFA	0x539A	# <CJK>
0x8CFB	0x53E3	# <CJK>
0x8CFC	0x5411	# <CJK>
0x8D40	0x540E	# <CJK>
0x8D41	0x5589	# <CJK>
0x8D42	0x5751	# <CJK>
0x8D43	0x57A2	# <CJK>
0x8D44	0x597D	# <CJK>
0x8D45	0x5B54	# <CJK>
0x8D46	0x5B5D	# <CJK>
0x8D47	0x5B8F	# <CJK>
0x8D48	0x5DE5	# <CJK>
0x8D49	0x5DE7	# <CJK>
0x8D4A	0x5DF7	# <CJK>
0x8D4B	0x5E78	# <CJK>
0x8D4C	0x5E83	# <CJK>
0x8D4D	0x5E9A	# <CJK>
0x8D4E	0x5EB7	# <CJK>
0x8D4F	0x5F18	# <CJK>
0x8D50	0x6052	# <CJK>
0x8D51	0x614C	# <CJK>
0x8D52	0x6297	# <CJK>
0x8D53	0x62D8	# <CJK>
0x8D54	0x63A7	# <CJK>
0x8D55	0x653B	# <CJK>
0x8D56	0x6602	# <CJK>
0x8D57	0x6643	# <CJK>
0x8D58	0x66F4	# <CJK>
0x8D59	0x676D	# <CJK>
0x8D5A	0x6821	# <CJK>
0x8D5B	0x6897	# <CJK>
0x8D5C	0x69CB	# <CJK>
0x8D5D	0x6C5F	# <CJK>
0x8D5E	0x6D2A	# <CJK>
0x8D5F	0x6D69	# <CJK>
0x8D60	0x6E2F	# <CJK>
0x8D61	0x6E9D	# <CJK>
0x8D62	0x7532	# <CJK>
0x8D63	0x7687	# <CJK>
0x8D64	0x786C	# <CJK>
0x8D65	0x7A3F	# <CJK>
0x8D66	0x7CE0	# <CJK>
0x8D67	0x7D05	# <CJK>
0x8D68	0x7D18	# <CJK>
0x8D69	0x7D5E	# <CJK>
0x8D6A	0x7DB1	# <CJK>
0x8D6B	0x8015	# <CJK>
0x8D6C	0x8003	# <CJK>
0x8D6D	0x80AF	# <CJK>
0x8D6E	0x80B1	# <CJK>
0x8D6F	0x8154	# <CJK>
0x8D70	0x818F	# <CJK>
0x8D71	0x822A	# <CJK>
0x8D72	0x8352	# <CJK>
0x8D73	0x884C	# <CJK>
0x8D74	0x8861	# <CJK>
0x8D75	0x8B1B	# <CJK>
0x8D76	0x8CA2	# <CJK>
0x8D77	0x8CFC	# <CJK>
0x8D78	0x90CA	# <CJK>
0x8D79	0x9175	# <CJK>
0x8D7A	0x9271	# <CJK>
0x8D7B	0x783F	# <CJK>
0x8D7C	0x92FC	# <CJK>
0x8D7D	0x95A4	# <CJK>
0x8D7E	0x964D	# <CJK>
0x8D80	0x9805	# <CJK>
0x8D81	0x9999	# <CJK>
0x8D82	0x9AD8	# <CJK>
0x8D83	0x9D3B	# <CJK>
0x8D84	0x525B	# <CJK>
0x8D85	0x52AB	# <CJK>
0x8D86	0x53F7	# <CJK>
0x8D87	0x5408	# <CJK>
0x8D88	0x58D5	# <CJK>
0x8D89	0x62F7	# <CJK>
0x8D8A	0x6FE0	# <CJK>
0x8D8B	0x8C6A	# <CJK>
0x8D8C	0x8F5F	# <CJK>
0x8D8D	0x9EB9	# <CJK>
0x8D8E	0x514B	# <CJK>
0x8D8F	0x523B	# <CJK>
0x8D90	0x544A	# <CJK>
0x8D91	0x56FD	# <CJK>
0x8D92	0x7A40	# <CJK>
0x8D93	0x9177	# <CJK>
0x8D94	0x9D60	# <CJK>
0x8D95	0x9ED2	# <CJK>
0x8D96	0x7344	# <CJK>
0x8D97	0x6F09	# <CJK>
0x8D98	0x8170	# <CJK>
0x8D99	0x7511	# <CJK>
0x8D9A	0x5FFD	# <CJK>
0x8D9B	0x60DA	# <CJK>
0x8D9C	0x9AA8	# <CJK>
0x8D9D	0x72DB	# <CJK>
0x8D9E	0x8FBC	# <CJK>
0x8D9F	0x6B64	# <CJK>
0x8DA0	0x9803	# <CJK>
0x8DA1	0x4ECA	# <CJK>
0x8DA2	0x56F0	# <CJK>
0x8DA3	0x5764	# <CJK>
0x8DA4	0x58BE	# <CJK>
0x8DA5	0x5A5A	# <CJK>
0x8DA6	0x6068	# <CJK>
0x8DA7	0x61C7	# <CJK>
0x8DA8	0x660F	# <CJK>
0x8DA9	0x6606	# <CJK>
0x8DAA	0x6839	# <CJK>
0x8DAB	0x68B1	# <CJK>
0x8DAC	0x6DF7	# <CJK>
0x8DAD	0x75D5	# <CJK>
0x8DAE	0x7D3A	# <CJK>
0x8DAF	0x826E	# <CJK>
0x8DB0	0x9B42	# <CJK>
0x8DB1	0x4E9B	# <CJK>
0x8DB2	0x4F50	# <CJK>
0x8DB3	0x53C9	# <CJK>
0x8DB4	0x5506	# <CJK>
0x8DB5	0x5D6F	# <CJK>
0x8DB6	0x5DE6	# <CJK>
0x8DB7	0x5DEE	# <CJK>
0x8DB8	0x67FB	# <CJK>
0x8DB9	0x6C99	# <CJK>
0x8DBA	0x7473	# <CJK>
0x8DBB	0x7802	# <CJK>
0x8DBC	0x8A50	# <CJK>
0x8DBD	0x9396	# <CJK>
0x8DBE	0x88DF	# <CJK>
0x8DBF	0x5750	# <CJK>
0x8DC0	0x5EA7	# <CJK>
0x8DC1	0x632B	# <CJK>
0x8DC2	0x50B5	# <CJK>
0x8DC3	0x50AC	# <CJK>
0x8DC4	0x518D	# <CJK>
0x8DC5	0x6700	# <CJK>
0x8DC6	0x54C9	# <CJK>
0x8DC7	0x585E	# <CJK>
0x8DC8	0x59BB	# <CJK>
0x8DC9	0x5BB0	# <CJK>
0x8DCA	0x5F69	# <CJK>
0x8DCB	0x624D	# <CJK>
0x8DCC	0x63A1	# <CJK>
0x8DCD	0x683D	# <CJK>
0x8DCE	0x6B73	# <CJK>
0x8DCF	0x6E08	# <CJK>
0x8DD0	0x707D	# <CJK>
0x8DD1	0x91C7	# <CJK>
0x8DD2	0x7280	# <CJK>
0x8DD3	0x7815	# <CJK>
0x8DD4	0x7826	# <CJK>
0x8DD5	0x796D	# <CJK>
0x8DD6	0x658E	# <CJK>
0x8DD7	0x7D30	# <CJK>
0x8DD8	0x83DC	# <CJK>
0x8DD9	0x88C1	# <CJK>
0x8DDA	0x8F09	# <CJK>
0x8DDB	0x969B	# <CJK>
0x8DDC	0x5264	# <CJK>
0x8DDD	0x5728	# <CJK>
0x8DDE	0x6750	# <CJK>
0x8DDF	0x7F6A	# <CJK>
0x8DE0	0x8CA1	# <CJK>
0x8DE1	0x51B4	# <CJK>
0x8DE2	0x5742	# <CJK>
0x8DE3	0x962A	# <CJK>
0x8DE4	0x583A	# <CJK>
0x8DE5	0x698A	# <CJK>
0x8DE6	0x80B4	# <CJK>
0x8DE7	0x54B2	# <CJK>
0x8DE8	0x5D0E	# <CJK>
0x8DE9	0x57FC	# <CJK>
0x8DEA	0x7895	# <CJK>
0x8DEB	0x9DFA	# <CJK>
0x8DEC	0x4F5C	# <CJK>
0x8DED	0x524A	# <CJK>
0x8DEE	0x548B	# <CJK>
0x8DEF	0x643E	# <CJK>
0x8DF0	0x6628	# <CJK>
0x8DF1	0x6714	# <CJK>
0x8DF2	0x67F5	# <CJK>
0x8DF3	0x7A84	# <CJK>
0x8DF4	0x7B56	# <CJK>
0x8DF5	0x7D22	# <CJK>
0x8DF6	0x932F	# <CJK>
0x8DF7	0x685C	# <CJK>
0x8DF8	0x9BAD	# <CJK>
0x8DF9	0x7B39	# <CJK>
0x8DFA	0x5319	# <CJK>
0x8DFB	0x518A	# <CJK>
0x8DFC	0x5237	# <CJK>
0x8E40	0x5BDF	# <CJK>
0x8E41	0x62F6	# <CJK>
0x8E42	0x64AE	# <CJK>
0x8E43	0x64E6	# <CJK>
0x8E44	0x672D	# <CJK>
0x8E45	0x6BBA	# <CJK>
0x8E46	0x85A9	# <CJK>
0x8E47	0x96D1	# <CJK>
0x8E48	0x7690	# <CJK>
0x8E49	0x9BD6	# <CJK>
0x8E4A	0x634C	# <CJK>
0x8E4B	0x9306	# <CJK>
0x8E4C	0x9BAB	# <CJK>
0x8E4D	0x76BF	# <CJK>
0x8E4E	0x6652	# <CJK>
0x8E4F	0x4E09	# <CJK>
0x8E50	0x5098	# <CJK>
0x8E51	0x53C2	# <CJK>
0x8E52	0x5C71	# <CJK>
0x8E53	0x60E8	# <CJK>
0x8E54	0x6492	# <CJK>
0x8E55	0x6563	# <CJK>
0x8E56	0x685F	# <CJK>
0x8E57	0x71E6	# <CJK>
0x8E58	0x73CA	# <CJK>
0x8E59	0x7523	# <CJK>
0x8E5A	0x7B97	# <CJK>
0x8E5B	0x7E82	# <CJK>
0x8E5C	0x8695	# <CJK>
0x8E5D	0x8B83	# <CJK>
0x8E5E	0x8CDB	# <CJK>
0x8E5F	0x9178	# <CJK>
0x8E60	0x9910	# <CJK>
0x8E61	0x65AC	# <CJK>
0x8E62	0x66AB	# <CJK>
0x8E63	0x6B8B	# <CJK>
0x8E64	0x4ED5	# <CJK>
0x8E65	0x4ED4	# <CJK>
0x8E66	0x4F3A	# <CJK>
0x8E67	0x4F7F	# <CJK>
0x8E68	0x523A	# <CJK>
0x8E69	0x53F8	# <CJK>
0x8E6A	0x53F2	# <CJK>
0x8E6B	0x55E3	# <CJK>
0x8E6C	0x56DB	# <CJK>
0x8E6D	0x58EB	# <CJK>
0x8E6E	0x59CB	# <CJK>
0x8E6F	0x59C9	# <CJK>
0x8E70	0x59FF	# <CJK>
0x8E71	0x5B50	# <CJK>
0x8E72	0x5C4D	# <CJK>
0x8E73	0x5E02	# <CJK>
0x8E74	0x5E2B	# <CJK>
0x8E75	0x5FD7	# <CJK>
0x8E76	0x601D	# <CJK>
0x8E77	0x6307	# <CJK>
0x8E78	0x652F	# <CJK>
0x8E79	0x5B5C	# <CJK>
0x8E7A	0x65AF	# <CJK>
0x8E7B	0x65BD	# <CJK>
0x8E7C	0x65E8	# <CJK>
0x8E7D	0x679D	# <CJK>
0x8E7E	0x6B62	# <CJK>
0x8E80	0x6B7B	# <CJK>
0x8E81	0x6C0F	# <CJK>
0x8E82	0x7345	# <CJK>
0x8E83	0x7949	# <CJK>
0x8E84	0x79C1	# <CJK>
0x8E85	0x7CF8	# <CJK>
0x8E86	0x7D19	# <CJK>
0x8E87	0x7D2B	# <CJK>
0x8E88	0x80A2	# <CJK>
0x8E89	0x8102	# <CJK>
0x8E8A	0x81F3	# <CJK>
0x8E8B	0x8996	# <CJK>
0x8E8C	0x8A5E	# <CJK>
0x8E8D	0x8A69	# <CJK>
0x8E8E	0x8A66	# <CJK>
0x8E8F	0x8A8C	# <CJK>
0x8E90	0x8AEE	# <CJK>
0x8E91	0x8CC7	# <CJK>
0x8E92	0x8CDC	# <CJK>
0x8E93	0x96CC	# <CJK>
0x8E94	0x98FC	# <CJK>
0x8E95	0x6B6F	# <CJK>
0x8E96	0x4E8B	# <CJK>
0x8E97	0x4F3C	# <CJK>
0x8E98	0x4F8D	# <CJK>
0x8E99	0x5150	# <CJK>
0x8E9A	0x5B57	# <CJK>
0x8E9B	0x5BFA	# <CJK>
0x8E9C	0x6148	# <CJK>
0x8E9D	0x6301	# <CJK>
0x8E9E	0x6642	# <CJK>
0x8E9F	0x6B21	# <CJK>
0x8EA0	0x6ECB	# <CJK>
0x8EA1	0x6CBB	# <CJK>
0x8EA2	0x723E	# <CJK>
0x8EA3	0x74BD	# <CJK>
0x8EA4	0x75D4	# <CJK>
0x8EA5	0x78C1	# <CJK>
0x8EA6	0x793A	# <CJK>
0x8EA7	0x800C	# <CJK>
0x8EA8	0x8033	# <CJK>
0x8EA9	0x81EA	# <CJK>
0x8EAA	0x8494	# <CJK>
0x8EAB	0x8F9E	# <CJK>
0x8EAC	0x6C50	# <CJK>
0x8EAD	0x9E7F	# <CJK>
0x8EAE	0x5F0F	# <CJK>
0x8EAF	0x8B58	# <CJK>
0x8EB0	0x9D2B	# <CJK>
0x8EB1	0x7AFA	# <CJK>
0x8EB2	0x8EF8	# <CJK>
0x8EB3	0x5B8D	# <CJK>
0x8EB4	0x96EB	# <CJK>
0x8EB5	0x4E03	# <CJK>
0x8EB6	0x53F1	# <CJK>
0x8EB7	0x57F7	# <CJK>
0x8EB8	0x5931	# <CJK>
0x8EB9	0x5AC9	# <CJK>
0x8EBA	0x5BA4	# <CJK>
0x8EBB	0x6089	# <CJK>
0x8EBC	0x6E7F	# <CJK>
0x8EBD	0x6F06	# <CJK>
0x8EBE	0x75BE	# <CJK>
0x8EBF	0x8CEA	# <CJK>
0x8EC0	0x5B9F	# <CJK>
0x8EC1	0x8500	# <CJK>
0x8EC2	0x7BE0	# <CJK>
0x8EC3	0x5072	# <CJK>
0x8EC4	0x67F4	# <CJK>
0x8EC5	0x829D	# <CJK>
0x8EC6	0x5C61	# <CJK>
0x8EC7	0x854A	# <CJK>
0x8EC8	0x7E1E	# <CJK>
0x8EC9	0x820E	# <CJK>
0x8ECA	0x5199	# <CJK>
0x8ECB	0x5C04	# <CJK>
0x8ECC	0x6368	# <CJK>
0x8ECD	0x8D66	# <CJK>
0x8ECE	0x659C	# <CJK>
0x8ECF	0x716E	# <CJK>
0x8ED0	0x793E	# <CJK>
0x8ED1	0x7D17	# <CJK>
0x8ED2	0x8005	# <CJK>
0x8ED3	0x8B1D	# <CJK>
0x8ED4	0x8ECA	# <CJK>
0x8ED5	0x906E	# <CJK>
0x8ED6	0x86C7	# <CJK>
0x8ED7	0x90AA	# <CJK>
0x8ED8	0x501F	# <CJK>
0x8ED9	0x52FA	# <CJK>
0x8EDA	0x5C3A	# <CJK>
0x8EDB	0x6753	# <CJK>
0x8EDC	0x707C	# <CJK>
0x8EDD	0x7235	# <CJK>
0x8EDE	0x914C	# <CJK>
0x8EDF	0x91C8	# <CJK>
0x8EE0	0x932B	# <CJK>
0x8EE1	0x82E5	# <CJK>
0x8EE2	0x5BC2	# <CJK>
0x8EE3	0x5F31	# <CJK>
0x8EE4	0x60F9	# <CJK>
0x8EE5	0x4E3B	# <CJK>
0x8EE6	0x53D6	# <CJK>
0x8EE7	0x5B88	# <CJK>
0x8EE8	0x624B	# <CJK>
0x8EE9	0x6731	# <CJK>
0x8EEA	0x6B8A	# <CJK>
0x8EEB	0x72E9	# <CJK>
0x8EEC	0x73E0	# <CJK>
0x8EED	0x7A2E	# <CJK>
0x8EEE	0x816B	# <CJK>
0x8EEF	0x8DA3	# <CJK>
0x8EF0	0x9152	# <CJK>
0x8EF1	0x9996	# <CJK>
0x8EF2	0x5112	# <CJK>
0x8EF3	0x53D7	# <CJK>
0x8EF4	0x546A	# <CJK>
0x8EF5	0x5BFF	# <CJK>
0x8EF6	0x6388	# <CJK>
0x8EF7	0x6A39	# <CJK>
0x8EF8	0x7DAC	# <CJK>
0x8EF9	0x9700	# <CJK>
0x8EFA	0x56DA	# <CJK>
0x8EFB	0x53CE	# <CJK>
0x8EFC	0x5468	# <CJK>
0x8F40	0x5B97	# <CJK>
0x8F41	0x5C31	# <CJK>
0x8F42	0x5DDE	# <CJK>
0x8F43	0x4FEE	# <CJK>
0x8F44	0x6101	# <CJK>
0x8F45	0x62FE	# <CJK>
0x8F46	0x6D32	# <CJK>
0x8F47	0x79C0	# <CJK>
0x8F48	0x79CB	# <CJK>
0x8F49	0x7D42	# <CJK>
0x8F4A	0x7E4D	# <CJK>
0x8F4B	0x7FD2	# <CJK>
0x8F4C	0x81ED	# <CJK>
0x8F4D	0x821F	# <CJK>
0x8F4E	0x8490	# <CJK>
0x8F4F	0x8846	# <CJK>
0x8F50	0x8972	# <CJK>
0x8F51	0x8B90	# <CJK>
0x8F52	0x8E74	# <CJK>
0x8F53	0x8F2F	# <CJK>
0x8F54	0x9031	# <CJK>
0x8F55	0x914B	# <CJK>
0x8F56	0x916C	# <CJK>
0x8F57	0x96C6	# <CJK>
0x8F58	0x919C	# <CJK>
0x8F59	0x4EC0	# <CJK>
0x8F5A	0x4F4F	# <CJK>
0x8F5B	0x5145	# <CJK>
0x8F5C	0x5341	# <CJK>
0x8F5D	0x5F93	# <CJK>
0x8F5E	0x620E	# <CJK>
0x8F5F	0x67D4	# <CJK>
0x8F60	0x6C41	# <CJK>
0x8F61	0x6E0B	# <CJK>
0x8F62	0x7363	# <CJK>
0x8F63	0x7E26	# <CJK>
0x8F64	0x91CD	# <CJK>
0x8F65	0x9283	# <CJK>
0x8F66	0x53D4	# <CJK>
0x8F67	0x5919	# <CJK>
0x8F68	0x5BBF	# <CJK>
0x8F69	0x6DD1	# <CJK>
0x8F6A	0x795D	# <CJK>
0x8F6B	0x7E2E	# <CJK>
0x8F6C	0x7C9B	# <CJK>
0x8F6D	0x587E	# <CJK>
0x8F6E	0x719F	# <CJK>
0x8F6F	0x51FA	# <CJK>
0x8F70	0x8853	# <CJK>
0x8F71	0x8FF0	# <CJK>
0x8F72	0x4FCA	# <CJK>
0x8F73	0x5CFB	# <CJK>
0x8F74	0x6625	# <CJK>
0x8F75	0x77AC	# <CJK>
0x8F76	0x7AE3	# <CJK>
0x8F77	0x821C	# <CJK>
0x8F78	0x99FF	# <CJK>
0x8F79	0x51C6	# <CJK>
0x8F7A	0x5FAA	# <CJK>
0x8F7B	0x65EC	# <CJK>
0x8F7C	0x696F	# <CJK>
0x8F7D	0x6B89	# <CJK>
0x8F7E	0x6DF3	# <CJK>
0x8F80	0x6E96	# <CJK>
0x8F81	0x6F64	# <CJK>
0x8F82	0x76FE	# <CJK>
0x8F83	0x7D14	# <CJK>
0x8F84	0x5DE1	# <CJK>
0x8F85	0x9075	# <CJK>
0x8F86	0x9187	# <CJK>
0x8F87	0x9806	# <CJK>
0x8F88	0x51E6	# <CJK>
0x8F89	0x521D	# <CJK>
0x8F8A	0x6240	# <CJK>
0x8F8B	0x6691	# <CJK>
0x8F8C	0x66D9	# <CJK>
0x8F8D	0x6E1A	# <CJK>
0x8F8E	0x5EB6	# <CJK>
0x8F8F	0x7DD2	# <CJK>
0x8F90	0x7F72	# <CJK>
0x8F91	0x66F8	# <CJK>
0x8F92	0x85AF	# <CJK>
0x8F93	0x85F7	# <CJK>
0x8F94	0x8AF8	# <CJK>
0x8F95	0x52A9	# <CJK>
0x8F96	0x53D9	# <CJK>
0x8F97	0x5973	# <CJK>
0x8F98	0x5E8F	# <CJK>
0x8F99	0x5F90	# <CJK>
0x8F9A	0x6055	# <CJK>
0x8F9B	0x92E4	# <CJK>
0x8F9C	0x9664	# <CJK>
0x8F9D	0x50B7	# <CJK>
0x8F9E	0x511F	# <CJK>
0x8F9F	0x52DD	# <CJK>
0x8FA0	0x5320	# <CJK>
0x8FA1	0x5347	# <CJK>
0x8FA2	0x53EC	# <CJK>
0x8FA3	0x54E8	# <CJK>
0x8FA4	0x5546	# <CJK>
0x8FA5	0x5531	# <CJK>
0x8FA6	0x5617	# <CJK>
0x8FA7	0x5968	# <CJK>
0x8FA8	0x59BE	# <CJK>
0x8FA9	0x5A3C	# <CJK>
0x8FAA	0x5BB5	# <CJK>
0x8FAB	0x5C06	# <CJK>
0x8FAC	0x5C0F	# <CJK>
0x8FAD	0x5C11	# <CJK>
0x8FAE	0x5C1A	# <CJK>
0x8FAF	0x5E84	# <CJK>
0x8FB0	0x5E8A	# <CJK>
0x8FB1	0x5EE0	# <CJK>
0x8FB2	0x5F70	# <CJK>
0x8FB3	0x627F	# <CJK>
0x8FB4	0x6284	# <CJK>
0x8FB5	0x62DB	# <CJK>
0x8FB6	0x638C	# <CJK>
0x8FB7	0x6377	# <CJK>
0x8FB8	0x6607	# <CJK>
0x8FB9	0x660C	# <CJK>
0x8FBA	0x662D	# <CJK>
0x8FBB	0x6676	# <CJK>
0x8FBC	0x677E	# <CJK>
0x8FBD	0x68A2	# <CJK>
0x8FBE	0x6A1F	# <CJK>
0x8FBF	0x6A35	# <CJK>
0x8FC0	0x6CBC	# <CJK>
0x8FC1	0x6D88	# <CJK>
0x8FC2	0x6E09	# <CJK>
0x8FC3	0x6E58	# <CJK>
0x8FC4	0x713C	# <CJK>
0x8FC5	0x7126	# <CJK>
0x8FC6	0x7167	# <CJK>
0x8FC7	0x75C7	# <CJK>
0x8FC8	0x7701	# <CJK>
0x8FC9	0x785D	# <CJK>
0x8FCA	0x7901	# <CJK>
0x8FCB	0x7965	# <CJK>
0x8FCC	0x79F0	# <CJK>
0x8FCD	0x7AE0	# <CJK>
0x8FCE	0x7B11	# <CJK>
0x8FCF	0x7CA7	# <CJK>
0x8FD0	0x7D39	# <CJK>
0x8FD1	0x8096	# <CJK>
0x8FD2	0x83D6	# <CJK>
0x8FD3	0x848B	# <CJK>
0x8FD4	0x8549	# <CJK>
0x8FD5	0x885D	# <CJK>
0x8FD6	0x88F3	# <CJK>
0x8FD7	0x8A1F	# <CJK>
0x8FD8	0x8A3C	# <CJK>
0x8FD9	0x8A54	# <CJK>
0x8FDA	0x8A73	# <CJK>
0x8FDB	0x8C61	# <CJK>
0x8FDC	0x8CDE	# <CJK>
0x8FDD	0x91A4	# <CJK>
0x8FDE	0x9266	# <CJK>
0x8FDF	0x937E	# <CJK>
0x8FE0	0x9418	# <CJK>
0x8FE1	0x969C	# <CJK>
0x8FE2	0x9798	# <CJK>
0x8FE3	0x4E0A	# <CJK>
0x8FE4	0x4E08	# <CJK>
0x8FE5	0x4E1E	# <CJK>
0x8FE6	0x4E57	# <CJK>
0x8FE7	0x5197	# <CJK>
0x8FE8	0x5270	# <CJK>
0x8FE9	0x57CE	# <CJK>
0x8FEA	0x5834	# <CJK>
0x8FEB	0x58CC	# <CJK>
0x8FEC	0x5B22	# <CJK>
0x8FED	0x5E38	# <CJK>
0x8FEE	0x60C5	# <CJK>
0x8FEF	0x64FE	# <CJK>
0x8FF0	0x6761	# <CJK>
0x8FF1	0x6756	# <CJK>
0x8FF2	0x6D44	# <CJK>
0x8FF3	0x72B6	# <CJK>
0x8FF4	0x7573	# <CJK>
0x8FF5	0x7A63	# <CJK>
0x8FF6	0x84B8	# <CJK>
0x8FF7	0x8B72	# <CJK>
0x8FF8	0x91B8	# <CJK>
0x8FF9	0x9320	# <CJK>
0x8FFA	0x5631	# <CJK>
0x8FFB	0x57F4	# <CJK>
0x8FFC	0x98FE	# <CJK>
0x9040	0x62ED	# <CJK>
0x9041	0x690D	# <CJK>
0x9042	0x6B96	# <CJK>
0x9043	0x71ED	# <CJK>
0x9044	0x7E54	# <CJK>
0x9045	0x8077	# <CJK>
0x9046	0x8272	# <CJK>
0x9047	0x89E6	# <CJK>
0x9048	0x98DF	# <CJK>
0x9049	0x8755	# <CJK>
0x904A	0x8FB1	# <CJK>
0x904B	0x5C3B	# <CJK>
0x904C	0x4F38	# <CJK>
0x904D	0x4FE1	# <CJK>
0x904E	0x4FB5	# <CJK>
0x904F	0x5507	# <CJK>
0x9050	0x5A20	# <CJK>
0x9051	0x5BDD	# <CJK>
0x9052	0x5BE9	# <CJK>
0x9053	0x5FC3	# <CJK>
0x9054	0x614E	# <CJK>
0x9055	0x632F	# <CJK>
0x9056	0x65B0	# <CJK>
0x9057	0x664B	# <CJK>
0x9058	0x68EE	# <CJK>
0x9059	0x699B	# <CJK>
0x905A	0x6D78	# <CJK>
0x905B	0x6DF1	# <CJK>
0x905C	0x7533	# <CJK>
0x905D	0x75B9	# <CJK>
0x905E	0x771F	# <CJK>
0x905F	0x795E	# <CJK>
0x9060	0x79E6	# <CJK>
0x9061	0x7D33	# <CJK>
0x9062	0x81E3	# <CJK>
0x9063	0x82AF	# <CJK>
0x9064	0x85AA	# <CJK>
0x9065	0x89AA	# <CJK>
0x9066	0x8A3A	# <CJK>
0x9067	0x8EAB	# <CJK>
0x9068	0x8F9B	# <CJK>
0x9069	0x9032	# <CJK>
0x906A	0x91DD	# <CJK>
0x906B	0x9707	# <CJK>
0x906C	0x4EBA	# <CJK>
0x906D	0x4EC1	# <CJK>
0x906E	0x5203	# <CJK>
0x906F	0x5875	# <CJK>
0x9070	0x58EC	# <CJK>
0x9071	0x5C0B	# <CJK>
0x9072	0x751A	# <CJK>
0x9073	0x5C3D	# <CJK>
0x9074	0x814E	# <CJK>
0x9075	0x8A0A	# <CJK>
0x9076	0x8FC5	# <CJK>
0x9077	0x9663	# <CJK>
0x9078	0x976D	# <CJK>
0x9079	0x7B25	# <CJK>
0x907A	0x8ACF	# <CJK>
0x907B	0x9808	# <CJK>
0x907C	0x9162	# <CJK>
0x907D	0x56F3	# <CJK>
0x907E	0x53A8	# <CJK>
0x9080	0x9017	# <CJK>
0x9081	0x5439	# <CJK>
0x9082	0x5782	# <CJK>
0x9083	0x5E25	# <CJK>
0x9084	0x63A8	# <CJK>
0x9085	0x6C34	# <CJK>
0x9086	0x708A	# <CJK>
0x9087	0x7761	# <CJK>
0x9088	0x7C8B	# <CJK>
0x9089	0x7FE0	# <CJK>
0x908A	0x8870	# <CJK>
0x908B	0x9042	# <CJK>
0x908C	0x9154	# <CJK>
0x908D	0x9310	# <CJK>
0x908E	0x9318	# <CJK>
0x908F	0x968F	# <CJK>
0x9090	0x745E	# <CJK>
0x9091	0x9AC4	# <CJK>
0x9092	0x5D07	# <CJK>
0x9093	0x5D69	# <CJK>
0x9094	0x6570	# <CJK>
0x9095	0x67A2	# <CJK>
0x9096	0x8DA8	# <CJK>
0x9097	0x96DB	# <CJK>
0x9098	0x636E	# <CJK>
0x9099	0x6749	# <CJK>
0x909A	0x6919	# <CJK>
0x909B	0x83C5	# <CJK>
0x909C	0x9817	# <CJK>
0x909D	0x96C0	# <CJK>
0x909E	0x88FE	# <CJK>
0x909F	0x6F84	# <CJK>
0x90A0	0x647A	# <CJK>
0x90A1	0x5BF8	# <CJK>
0x90A2	0x4E16	# <CJK>
0x90A3	0x702C	# <CJK>
0x90A4	0x755D	# <CJK>
0x90A5	0x662F	# <CJK>
0x90A6	0x51C4	# <CJK>
0x90A7	0x5236	# <CJK>
0x90A8	0x52E2	# <CJK>
0x90A9	0x59D3	# <CJK>
0x90AA	0x5F81	# <CJK>
0x90AB	0x6027	# <CJK>
0x90AC	0x6210	# <CJK>
0x90AD	0x653F	# <CJK>
0x90AE	0x6574	# <CJK>
0x90AF	0x661F	# <CJK>
0x90B0	0x6674	# <CJK>
0x90B1	0x68F2	# <CJK>
0x90B2	0x6816	# <CJK>
0x90B3	0x6B63	# <CJK>
0x90B4	0x6E05	# <CJK>
0x90B5	0x7272	# <CJK>
0x90B6	0x751F	# <CJK>
0x90B7	0x76DB	# <CJK>
0x90B8	0x7CBE	# <CJK>
0x90B9	0x8056	# <CJK>
0x90BA	0x58F0	# <CJK>
0x90BB	0x88FD	# <CJK>
0x90BC	0x897F	# <CJK>
0x90BD	0x8AA0	# <CJK>
0x90BE	0x8A93	# <CJK>
0x90BF	0x8ACB	# <CJK>
0x90C0	0x901D	# <CJK>
0x90C1	0x9192	# <CJK>
0x90C2	0x9752	# <CJK>
0x90C3	0x9759	# <CJK>
0x90C4	0x6589	# <CJK>
0x90C5	0x7A0E	# <CJK>
0x90C6	0x8106	# <CJK>
0x90C7	0x96BB	# <CJK>
0x90C8	0x5E2D	# <CJK>
0x90C9	0x60DC	# <CJK>
0x90CA	0x621A	# <CJK>
0x90CB	0x65A5	# <CJK>
0x90CC	0x6614	# <CJK>
0x90CD	0x6790	# <CJK>
0x90CE	0x77F3	# <CJK>
0x90CF	0x7A4D	# <CJK>
0x90D0	0x7C4D	# <CJK>
0x90D1	0x7E3E	# <CJK>
0x90D2	0x810A	# <CJK>
0x90D3	0x8CAC	# <CJK>
0x90D4	0x8D64	# <CJK>
0x90D5	0x8DE1	# <CJK>
0x90D6	0x8E5F	# <CJK>
0x90D7	0x78A9	# <CJK>
0x90D8	0x5207	# <CJK>
0x90D9	0x62D9	# <CJK>
0x90DA	0x63A5	# <CJK>
0x90DB	0x6442	# <CJK>
0x90DC	0x6298	# <CJK>
0x90DD	0x8A2D	# <CJK>
0x90DE	0x7A83	# <CJK>
0x90DF	0x7BC0	# <CJK>
0x90E0	0x8AAC	# <CJK>
0x90E1	0x96EA	# <CJK>
0x90E2	0x7D76	# <CJK>
0x90E3	0x820C	# <CJK>
0x90E4	0x8749	# <CJK>
0x90E5	0x4ED9	# <CJK>
0x90E6	0x5148	# <CJK>
0x90E7	0x5343	# <CJK>
0x90E8	0x5360	# <CJK>
0x90E9	0x5BA3	# <CJK>
0x90EA	0x5C02	# <CJK>
0x90EB	0x5C16	# <CJK>
0x90EC	0x5DDD	# <CJK>
0x90ED	0x6226	# <CJK>
0x90EE	0x6247	# <CJK>
0x90EF	0x64B0	# <CJK>
0x90F0	0x6813	# <CJK>
0x90F1	0x6834	# <CJK>
0x90F2	0x6CC9	# <CJK>
0x90F3	0x6D45	# <CJK>
0x90F4	0x6D17	# <CJK>
0x90F5	0x67D3	# <CJK>
0x90F6	0x6F5C	# <CJK>
0x90F7	0x714E	# <CJK>
0x90F8	0x717D	# <CJK>
0x90F9	0x65CB	# <CJK>
0x90FA	0x7A7F	# <CJK>
0x90FB	0x7BAD	# <CJK>
0x90FC	0x7DDA	# <CJK>
0x9140	0x7E4A	# <CJK>
0x9141	0x7FA8	# <CJK>
0x9142	0x817A	# <CJK>
0x9143	0x821B	# <CJK>
0x9144	0x8239	# <CJK>
0x9145	0x85A6	# <CJK>
0x9146	0x8A6E	# <CJK>
0x9147	0x8CCE	# <CJK>
0x9148	0x8DF5	# <CJK>
0x9149	0x9078	# <CJK>
0x914A	0x9077	# <CJK>
0x914B	0x92AD	# <CJK>
0x914C	0x9291	# <CJK>
0x914D	0x9583	# <CJK>
0x914E	0x9BAE	# <CJK>
0x914F	0x524D	# <CJK>
0x9150	0x5584	# <CJK>
0x9151	0x6F38	# <CJK>
0x9152	0x7136	# <CJK>
0x9153	0x5168	# <CJK>
0x9154	0x7985	# <CJK>
0x9155	0x7E55	# <CJK>
0x9156	0x81B3	# <CJK>
0x9157	0x7CCE	# <CJK>
0x9158	0x564C	# <CJK>
0x9159	0x5851	# <CJK>
0x915A	0x5CA8	# <CJK>
0x915B	0x63AA	# <CJK>
0x915C	0x66FE	# <CJK>
0x915D	0x66FD	# <CJK>
0x915E	0x695A	# <CJK>
0x915F	0x72D9	# <CJK>
0x9160	0x758F	# <CJK>
0x9161	0x758E	# <CJK>
0x9162	0x790E	# <CJK>
0x9163	0x7956	# <CJK>
0x9164	0x79DF	# <CJK>
0x9165	0x7C97	# <CJK>
0x9166	0x7D20	# <CJK>
0x9167	0x7D44	# <CJK>
0x9168	0x8607	# <CJK>
0x9169	0x8A34	# <CJK>
0x916A	0x963B	# <CJK>
0x916B	0x9061	# <CJK>
0x916C	0x9F20	# <CJK>
0x916D	0x50E7	# <CJK>
0x916E	0x5275	# <CJK>
0x916F	0x53CC	# <CJK>
0x9170	0x53E2	# <CJK>
0x9171	0x5009	# <CJK>
0x9172	0x55AA	# <CJK>
0x9173	0x58EE	# <CJK>
0x9174	0x594F	# <CJK>
0x9175	0x723D	# <CJK>
0x9176	0x5B8B	# <CJK>
0x9177	0x5C64	# <CJK>
0x9178	0x531D	# <CJK>
0x9179	0x60E3	# <CJK>
0x917A	0x60F3	# <CJK>
0x917B	0x635C	# <CJK>
0x917C	0x6383	# <CJK>
0x917D	0x633F	# <CJK>
0x917E	0x63BB	# <CJK>
0x9180	0x64CD	# <CJK>
0x9181	0x65E9	# <CJK>
0x9182	0x66F9	# <CJK>
0x9183	0x5DE3	# <CJK>
0x9184	0x69CD	# <CJK>
0x9185	0x69FD	# <CJK>
0x9186	0x6F15	# <CJK>
0x9187	0x71E5	# <CJK>
0x9188	0x4E89	# <CJK>
0x9189	0x75E9	# <CJK>
0x918A	0x76F8	# <CJK>
0x918B	0x7A93	# <CJK>
0x918C	0x7CDF	# <CJK>
0x918D	0x7DCF	# <CJK>
0x918E	0x7D9C	# <CJK>
0x918F	0x8061	# <CJK>
0x9190	0x8349	# <CJK>
0x9191	0x8358	# <CJK>
0x9192	0x846C	# <CJK>
0x9193	0x84BC	# <CJK>
0x9194	0x85FB	# <CJK>
0x9195	0x88C5	# <CJK>
0x9196	0x8D70	# <CJK>
0x9197	0x9001	# <CJK>
0x9198	0x906D	# <CJK>
0x9199	0x9397	# <CJK>
0x919A	0x971C	# <CJK>
0x919B	0x9A12	# <CJK>
0x919C	0x50CF	# <CJK>
0x919D	0x5897	# <CJK>
0x919E	0x618E	# <CJK>
0x919F	0x81D3	# <CJK>
0x91A0	0x8535	# <CJK>
0x91A1	0x8D08	# <CJK>
0x91A2	0x9020	# <CJK>
0x91A3	0x4FC3	# <CJK>
0x91A4	0x5074	# <CJK>
0x91A5	0x5247	# <CJK>
0x91A6	0x5373	# <CJK>
0x91A7	0x606F	# <CJK>
0x91A8	0x6349	# <CJK>
0x91A9	0x675F	# <CJK>
0x91AA	0x6E2C	# <CJK>
0x91AB	0x8DB3	# <CJK>
0x91AC	0x901F	# <CJK>
0x91AD	0x4FD7	# <CJK>
0x91AE	0x5C5E	# <CJK>
0x91AF	0x8CCA	# <CJK>
0x91B0	0x65CF	# <CJK>
0x91B1	0x7D9A	# <CJK>
0x91B2	0x5352	# <CJK>
0x91B3	0x8896	# <CJK>
0x91B4	0x5176	# <CJK>
0x91B5	0x63C3	# <CJK>
0x91B6	0x5B58	# <CJK>
0x91B7	0x5B6B	# <CJK>
0x91B8	0x5C0A	# <CJK>
0x91B9	0x640D	# <CJK>
0x91BA	0x6751	# <CJK>
0x91BB	0x905C	# <CJK>
0x91BC	0x4ED6	# <CJK>
0x91BD	0x591A	# <CJK>
0x91BE	0x592A	# <CJK>
0x91BF	0x6C70	# <CJK>
0x91C0	0x8A51	# <CJK>
0x91C1	0x553E	# <CJK>
0x91C2	0x5815	# <CJK>
0x91C3	0x59A5	# <CJK>
0x91C4	0x60F0	# <CJK>
0x91C5	0x6253	# <CJK>
0x91C6	0x67C1	# <CJK>
0x91C7	0x8235	# <CJK>
0x91C8	0x6955	# <CJK>
0x91C9	0x9640	# <CJK>
0x91CA	0x99C4	# <CJK>
0x91CB	0x9A28	# <CJK>
0x91CC	0x4F53	# <CJK>
0x91CD	0x5806	# <CJK>
0x91CE	0x5BFE	# <CJK>
0x91CF	0x8010	# <CJK>
0x91D0	0x5CB1	# <CJK>
0x91D1	0x5E2F	# <CJK>
0x91D2	0x5F85	# <CJK>
0x91D3	0x6020	# <CJK>
0x91D4	0x614B	# <CJK>
0x91D5	0x6234	# <CJK>
0x91D6	0x66FF	# <CJK>
0x91D7	0x6CF0	# <CJK>
0x91D8	0x6EDE	# <CJK>
0x91D9	0x80CE	# <CJK>
0x91DA	0x817F	# <CJK>
0x91DB	0x82D4	# <CJK>
0x91DC	0x888B	# <CJK>
0x91DD	0x8CB8	# <CJK>
0x91DE	0x9000	# <CJK>
0x91DF	0x902E	# <CJK>
0x91E0	0x968A	# <CJK>
0x91E1	0x9EDB	# <CJK>
0x91E2	0x9BDB	# <CJK>
0x91E3	0x4EE3	# <CJK>
0x91E4	0x53F0	# <CJK>
0x91E5	0x5927	# <CJK>
0x91E6	0x7B2C	# <CJK>
0x91E7	0x918D	# <CJK>
0x91E8	0x984C	# <CJK>
0x91E9	0x9DF9	# <CJK>
0x91EA	0x6EDD	# <CJK>
0x91EB	0x7027	# <CJK>
0x91EC	0x5353	# <CJK>
0x91ED	0x5544	# <CJK>
0x91EE	0x5B85	# <CJK>
0x91EF	0x6258	# <CJK>
0x91F0	0x629E	# <CJK>
0x91F1	0x62D3	# <CJK>
0x91F2	0x6CA2	# <CJK>
0x91F3	0x6FEF	# <CJK>
0x91F4	0x7422	# <CJK>
0x91F5	0x8A17	# <CJK>
0x91F6	0x9438	# <CJK>
0x91F7	0x6FC1	# <CJK>
0x91F8	0x8AFE	# <CJK>
0x91F9	0x8338	# <CJK>
0x91FA	0x51E7	# <CJK>
0x91FB	0x86F8	# <CJK>
0x91FC	0x53EA	# <CJK>
0x9240	0x53E9	# <CJK>
0x9241	0x4F46	# <CJK>
0x9242	0x9054	# <CJK>
0x9243	0x8FB0	# <CJK>
0x9244	0x596A	# <CJK>
0x9245	0x8131	# <CJK>
0x9246	0x5DFD	# <CJK>
0x9247	0x7AEA	# <CJK>
0x9248	0x8FBF	# <CJK>
0x9249	0x68DA	# <CJK>
0x924A	0x8C37	# <CJK>
0x924B	0x72F8	# <CJK>
0x924C	0x9C48	# <CJK>
0x924D	0x6A3D	# <CJK>
0x924E	0x8AB0	# <CJK>
0x924F	0x4E39	# <CJK>
0x9250	0x5358	# <CJK>
0x9251	0x5606	# <CJK>
0x9252	0x5766	# <CJK>
0x9253	0x62C5	# <CJK>
0x9254	0x63A2	# <CJK>
0x9255	0x65E6	# <CJK>
0x9256	0x6B4E	# <CJK>
0x9257	0x6DE1	# <CJK>
0x9258	0x6E5B	# <CJK>
0x9259	0x70AD	# <CJK>
0x925A	0x77ED	# <CJK>
0x925B	0x7AEF	# <CJK>
0x925C	0x7BAA	# <CJK>
0x925D	0x7DBB	# <CJK>
0x925E	0x803D	# <CJK>
0x925F	0x80C6	# <CJK>
0x9260	0x86CB	# <CJK>
0x9261	0x8A95	# <CJK>
0x9262	0x935B	# <CJK>
0x9263	0x56E3	# <CJK>
0x9264	0x58C7	# <CJK>
0x9265	0x5F3E	# <CJK>
0x9266	0x65AD	# <CJK>
0x9267	0x6696	# <CJK>
0x9268	0x6A80	# <CJK>
0x9269	0x6BB5	# <CJK>
0x926A	0x7537	# <CJK>
0x926B	0x8AC7	# <CJK>
0x926C	0x5024	# <CJK>
0x926D	0x77E5	# <CJK>
0x926E	0x5730	# <CJK>
0x926F	0x5F1B	# <CJK>
0x9270	0x6065	# <CJK>
0x9271	0x667A	# <CJK>
0x9272	0x6C60	# <CJK>
0x9273	0x75F4	# <CJK>
0x9274	0x7A1A	# <CJK>
0x9275	0x7F6E	# <CJK>
0x9276	0x81F4	# <CJK>
0x9277	0x8718	# <CJK>
0x9278	0x9045	# <CJK>
0x9279	0x99B3	# <CJK>
0x927A	0x7BC9	# <CJK>
0x927B	0x755C	# <CJK>
0x927C	0x7AF9	# <CJK>
0x927D	0x7B51	# <CJK>
0x927E	0x84C4	# <CJK>
0x9280	0x9010	# <CJK>
0x9281	0x79E9	# <CJK>
0x9282	0x7A92	# <CJK>
0x9283	0x8336	# <CJK>
0x9284	0x5AE1	# <CJK>
0x9285	0x7740	# <CJK>
0x9286	0x4E2D	# <CJK>
0x9287	0x4EF2	# <CJK>
0x9288	0x5B99	# <CJK>
0x9289	0x5FE0	# <CJK>
0x928A	0x62BD	# <CJK>
0x928B	0x663C	# <CJK>
0x928C	0x67F1	# <CJK>
0x928D	0x6CE8	# <CJK>
0x928E	0x866B	# <CJK>
0x928F	0x8877	# <CJK>
0x9290	0x8A3B	# <CJK>
0x9291	0x914E	# <CJK>
0x9292	0x92F3	# <CJK>
0x9293	0x99D0	# <CJK>
0x9294	0x6A17	# <CJK>
0x9295	0x7026	# <CJK>
0x9296	0x732A	# <CJK>
0x9297	0x82E7	# <CJK>
0x9298	0x8457	# <CJK>
0x9299	0x8CAF	# <CJK>
0x929A	0x4E01	# <CJK>
0x929B	0x5146	# <CJK>
0x929C	0x51CB	# <CJK>
0x929D	0x558B	# <CJK>
0x929E	0x5BF5	# <CJK>
0x929F	0x5E16	# <CJK>
0x92A0	0x5E33	# <CJK>
0x92A1	0x5E81	# <CJK>
0x92A2	0x5F14	# <CJK>
0x92A3	0x5F35	# <CJK>
0x92A4	0x5F6B	# <CJK>
0x92A5	0x5FB4	# <CJK>
0x92A6	0x61F2	# <CJK>
0x92A7	0x6311	# <CJK>
0x92A8	0x66A2	# <CJK>
0x92A9	0x671D	# <CJK>
0x92AA	0x6F6E	# <CJK>
0x92AB	0x7252	# <CJK>
0x92AC	0x753A	# <CJK>
0x92AD	0x773A	# <CJK>
0x92AE	0x8074	# <CJK>
0x92AF	0x8139	# <CJK>
0x92B0	0x8178	# <CJK>
0x92B1	0x8776	# <CJK>
0x92B2	0x8ABF	# <CJK>
0x92B3	0x8ADC	# <CJK>
0x92B4	0x8D85	# <CJK>
0x92B5	0x8DF3	# <CJK>
0x92B6	0x929A	# <CJK>
0x92B7	0x9577	# <CJK>
0x92B8	0x9802	# <CJK>
0x92B9	0x9CE5	# <CJK>
0x92BA	0x52C5	# <CJK>
0x92BB	0x6357	# <CJK>
0x92BC	0x76F4	# <CJK>
0x92BD	0x6715	# <CJK>
0x92BE	0x6C88	# <CJK>
0x92BF	0x73CD	# <CJK>
0x92C0	0x8CC3	# <CJK>
0x92C1	0x93AE	# <CJK>
0x92C2	0x9673	# <CJK>
0x92C3	0x6D25	# <CJK>
0x92C4	0x589C	# <CJK>
0x92C5	0x690E	# <CJK>
0x92C6	0x69CC	# <CJK>
0x92C7	0x8FFD	# <CJK>
0x92C8	0x939A	# <CJK>
0x92C9	0x75DB	# <CJK>
0x92CA	0x901A	# <CJK>
0x92CB	0x585A	# <CJK>
0x92CC	0x6802	# <CJK>
0x92CD	0x63B4	# <CJK>
0x92CE	0x69FB	# <CJK>
0x92CF	0x4F43	# <CJK>
0x92D0	0x6F2C	# <CJK>
0x92D1	0x67D8	# <CJK>
0x92D2	0x8FBB	# <CJK>
0x92D3	0x8526	# <CJK>
0x92D4	0x7DB4	# <CJK>
0x92D5	0x9354	# <CJK>
0x92D6	0x693F	# <CJK>
0x92D7	0x6F70	# <CJK>
0x92D8	0x576A	# <CJK>
0x92D9	0x58F7	# <CJK>
0x92DA	0x5B2C	# <CJK>
0x92DB	0x7D2C	# <CJK>
0x92DC	0x722A	# <CJK>
0x92DD	0x540A	# <CJK>
0x92DE	0x91E3	# <CJK>
0x92DF	0x9DB4	# <CJK>
0x92E0	0x4EAD	# <CJK>
0x92E1	0x4F4E	# <CJK>
0x92E2	0x505C	# <CJK>
0x92E3	0x5075	# <CJK>
0x92E4	0x5243	# <CJK>
0x92E5	0x8C9E	# <CJK>
0x92E6	0x5448	# <CJK>
0x92E7	0x5824	# <CJK>
0x92E8	0x5B9A	# <CJK>
0x92E9	0x5E1D	# <CJK>
0x92EA	0x5E95	# <CJK>
0x92EB	0x5EAD	# <CJK>
0x92EC	0x5EF7	# <CJK>
0x92ED	0x5F1F	# <CJK>
0x92EE	0x608C	# <CJK>
0x92EF	0x62B5	# <CJK>
0x92F0	0x633A	# <CJK>
0x92F1	0x63D0	# <CJK>
0x92F2	0x68AF	# <CJK>
0x92F3	0x6C40	# <CJK>
0x92F4	0x7887	# <CJK>
0x92F5	0x798E	# <CJK>
0x92F6	0x7A0B	# <CJK>
0x92F7	0x7DE0	# <CJK>
0x92F8	0x8247	# <CJK>
0x92F9	0x8A02	# <CJK>
0x92FA	0x8AE6	# <CJK>
0x92FB	0x8E44	# <CJK>
0x92FC	0x9013	# <CJK>
0x9340	0x90B8	# <CJK>
0x9341	0x912D	# <CJK>
0x9342	0x91D8	# <CJK>
0x9343	0x9F0E	# <CJK>
0x9344	0x6CE5	# <CJK>
0x9345	0x6458	# <CJK>
0x9346	0x64E2	# <CJK>
0x9347	0x6575	# <CJK>
0x9348	0x6EF4	# <CJK>
0x9349	0x7684	# <CJK>
0x934A	0x7B1B	# <CJK>
0x934B	0x9069	# <CJK>
0x934C	0x93D1	# <CJK>
0x934D	0x6EBA	# <CJK>
0x934E	0x54F2	# <CJK>
0x934F	0x5FB9	# <CJK>
0x9350	0x64A4	# <CJK>
0x9351	0x8F4D	# <CJK>
0x9352	0x8FED	# <CJK>
0x9353	0x9244	# <CJK>
0x9354	0x5178	# <CJK>
0x9355	0x586B	# <CJK>
0x9356	0x5929	# <CJK>
0x9357	0x5C55	# <CJK>
0x9358	0x5E97	# <CJK>
0x9359	0x6DFB	# <CJK>
0x935A	0x7E8F	# <CJK>
0x935B	0x751C	# <CJK>
0x935C	0x8CBC	# <CJK>
0x935D	0x8EE2	# <CJK>
0x935E	0x985B	# <CJK>
0x935F	0x70B9	# <CJK>
0x9360	0x4F1D	# <CJK>
0x9361	0x6BBF	# <CJK>
0x9362	0x6FB1	# <CJK>
0x9363	0x7530	# <CJK>
0x9364	0x96FB	# <CJK>
0x9365	0x514E	# <CJK>
0x9366	0x5410	# <CJK>
0x9367	0x5835	# <CJK>
0x9368	0x5857	# <CJK>
0x9369	0x59AC	# <CJK>
0x936A	0x5C60	# <CJK>
0x936B	0x5F92	# <CJK>
0x936C	0x6597	# <CJK>
0x936D	0x675C	# <CJK>
0x936E	0x6E21	# <CJK>
0x936F	0x767B	# <CJK>
0x9370	0x83DF	# <CJK>
0x9371	0x8CED	# <CJK>
0x9372	0x9014	# <CJK>
0x9373	0x90FD	# <CJK>
0x9374	0x934D	# <CJK>
0x9375	0x7825	# <CJK>
0x9376	0x783A	# <CJK>
0x9377	0x52AA	# <CJK>
0x9378	0x5EA6	# <CJK>
0x9379	0x571F	# <CJK>
0x937A	0x5974	# <CJK>
0x937B	0x6012	# <CJK>
0x937C	0x5012	# <CJK>
0x937D	0x515A	# <CJK>
0x937E	0x51AC	# <CJK>
0x9380	0x51CD	# <CJK>
0x9381	0x5200	# <CJK>
0x9382	0x5510	# <CJK>
0x9383	0x5854	# <CJK>
0x9384	0x5858	# <CJK>
0x9385	0x5957	# <CJK>
0x9386	0x5B95	# <CJK>
0x9387	0x5CF6	# <CJK>
0x9388	0x5D8B	# <CJK>
0x9389	0x60BC	# <CJK>
0x938A	0x6295	# <CJK>
0x938B	0x642D	# <CJK>
0x938C	0x6771	# <CJK>
0x938D	0x6843	# <CJK>
0x938E	0x68BC	# <CJK>
0x938F	0x68DF	# <CJK>
0x9390	0x76D7	# <CJK>
0x9391	0x6DD8	# <CJK>
0x9392	0x6E6F	# <CJK>
0x9393	0x6D9B	# <CJK>
0x9394	0x706F	# <CJK>
0x9395	0x71C8	# <CJK>
0x9396	0x5F53	# <CJK>
0x9397	0x75D8	# <CJK>
0x9398	0x7977	# <CJK>
0x9399	0x7B49	# <CJK>
0x939A	0x7B54	# <CJK>
0x939B	0x7B52	# <CJK>
0x939C	0x7CD6	# <CJK>
0x939D	0x7D71	# <CJK>
0x939E	0x5230	# <CJK>
0x939F	0x8463	# <CJK>
0x93A0	0x8569	# <CJK>
0x93A1	0x85E4	# <CJK>
0x93A2	0x8A0E	# <CJK>
0x93A3	0x8B04	# <CJK>
0x93A4	0x8C46	# <CJK>
0x93A5	0x8E0F	# <CJK>
0x93A6	0x9003	# <CJK>
0x93A7	0x900F	# <CJK>
0x93A8	0x9419	# <CJK>
0x93A9	0x9676	# <CJK>
0x93AA	0x982D	# <CJK>
0x93AB	0x9A30	# <CJK>
0x93AC	0x95D8	# <CJK>
0x93AD	0x50CD	# <CJK>
0x93AE	0x52D5	# <CJK>
0x93AF	0x540C	# <CJK>
0x93B0	0x5802	# <CJK>
0x93B1	0x5C0E	# <CJK>
0x93B2	0x61A7	# <CJK>
0x93B3	0x649E	# <CJK>
0x93B4	0x6D1E	# <CJK>
0x93B5	0x77B3	# <CJK>
0x93B6	0x7AE5	# <CJK>
0x93B7	0x80F4	# <CJK>
0x93B8	0x8404	# <CJK>
0x93B9	0x9053	# <CJK>
0x93BA	0x9285	# <CJK>
0x93BB	0x5CE0	# <CJK>
0x93BC	0x9D07	# <CJK>
0x93BD	0x533F	# <CJK>
0x93BE	0x5F97	# <CJK>
0x93BF	0x5FB3	# <CJK>
0x93C0	0x6D9C	# <CJK>
0x93C1	0x7279	# <CJK>
0x93C2	0x7763	# <CJK>
0x93C3	0x79BF	# <CJK>
0x93C4	0x7BE4	# <CJK>
0x93C5	0x6BD2	# <CJK>
0x93C6	0x72EC	# <CJK>
0x93C7	0x8AAD	# <CJK>
0x93C8	0x6803	# <CJK>
0x93C9	0x6A61	# <CJK>
0x93CA	0x51F8	# <CJK>
0x93CB	0x7A81	# <CJK>
0x93CC	0x6934	# <CJK>
0x93CD	0x5C4A	# <CJK>
0x93CE	0x9CF6	# <CJK>
0x93CF	0x82EB	# <CJK>
0x93D0	0x5BC5	# <CJK>
0x93D1	0x9149	# <CJK>
0x93D2	0x701E	# <CJK>
0x93D3	0x5678	# <CJK>
0x93D4	0x5C6F	# <CJK>
0x93D5	0x60C7	# <CJK>
0x93D6	0x6566	# <CJK>
0x93D7	0x6C8C	# <CJK>
0x93D8	0x8C5A	# <CJK>
0x93D9	0x9041	# <CJK>
0x93DA	0x9813	# <CJK>
0x93DB	0x5451	# <CJK>
0x93DC	0x66C7	# <CJK>
0x93DD	0x920D	# <CJK>
0x93DE	0x5948	# <CJK>
0x93DF	0x90A3	# <CJK>
0x93E0	0x5185	# <CJK>
0x93E1	0x4E4D	# <CJK>
0x93E2	0x51EA	# <CJK>
0x93E3	0x8599	# <CJK>
0x93E4	0x8B0E	# <CJK>
0x93E5	0x7058	# <CJK>
0x93E6	0x637A	# <CJK>
0x93E7	0x934B	# <CJK>
0x93E8	0x6962	# <CJK>
0x93E9	0x99B4	# <CJK>
0x93EA	0x7E04	# <CJK>
0x93EB	0x7577	# <CJK>
0x93EC	0x5357	# <CJK>
0x93ED	0x6960	# <CJK>
0x93EE	0x8EDF	# <CJK>
0x93EF	0x96E3	# <CJK>
0x93F0	0x6C5D	# <CJK>
0x93F1	0x4E8C	# <CJK>
0x93F2	0x5C3C	# <CJK>
0x93F3	0x5F10	# <CJK>
0x93F4	0x8FE9	# <CJK>
0x93F5	0x5302	# <CJK>
0x93F6	0x8CD1	# <CJK>
0x93F7	0x8089	# <CJK>
0x93F8	0x8679	# <CJK>
0x93F9	0x5EFF	# <CJK>
0x93FA	0x65E5	# <CJK>
0x93FB	0x4E73	# <CJK>
0x93FC	0x5165	# <CJK>
0x9440	0x5982	# <CJK>
0x9441	0x5C3F	# <CJK>
0x9442	0x97EE	# <CJK>
0x9443	0x4EFB	# <CJK>
0x9444	0x598A	# <CJK>
0x9445	0x5FCD	# <CJK>
0x9446	0x8A8D	# <CJK>
0x9447	0x6FE1	# <CJK>
0x9448	0x79B0	# <CJK>
0x9449	0x7962	# <CJK>
0x944A	0x5BE7	# <CJK>
0x944B	0x8471	# <CJK>
0x944C	0x732B	# <CJK>
0x944D	0x71B1	# <CJK>
0x944E	0x5E74	# <CJK>
0x944F	0x5FF5	# <CJK>
0x9450	0x637B	# <CJK>
0x9451	0x649A	# <CJK>
0x9452	0x71C3	# <CJK>
0x9453	0x7C98	# <CJK>
0x9454	0x4E43	# <CJK>
0x9455	0x5EFC	# <CJK>
0x9456	0x4E4B	# <CJK>
0x9457	0x57DC	# <CJK>
0x9458	0x56A2	# <CJK>
0x9459	0x60A9	# <CJK>
0x945A	0x6FC3	# <CJK>
0x945B	0x7D0D	# <CJK>
0x945C	0x80FD	# <CJK>
0x945D	0x8133	# <CJK>
0x945E	0x81BF	# <CJK>
0x945F	0x8FB2	# <CJK>
0x9460	0x8997	# <CJK>
0x9461	0x86A4	# <CJK>
0x9462	0x5DF4	# <CJK>
0x9463	0x628A	# <CJK>
0x9464	0x64AD	# <CJK>
0x9465	0x8987	# <CJK>
0x9466	0x6777	# <CJK>
0x9467	0x6CE2	# <CJK>
0x9468	0x6D3E	# <CJK>
0x9469	0x7436	# <CJK>
0x946A	0x7834	# <CJK>
0x946B	0x5A46	# <CJK>
0x946C	0x7F75	# <CJK>
0x946D	0x82AD	# <CJK>
0x946E	0x99AC	# <CJK>
0x946F	0x4FF3	# <CJK>
0x9470	0x5EC3	# <CJK>
0x9471	0x62DD	# <CJK>
0x9472	0x6392	# <CJK>
0x9473	0x6557	# <CJK>
0x9474	0x676F	# <CJK>
0x9475	0x76C3	# <CJK>
0x9476	0x724C	# <CJK>
0x9477	0x80CC	# <CJK>
0x9478	0x80BA	# <CJK>
0x9479	0x8F29	# <CJK>
0x947A	0x914D	# <CJK>
0x947B	0x500D	# <CJK>
0x947C	0x57F9	# <CJK>
0x947D	0x5A92	# <CJK>
0x947E	0x6885	# <CJK>
0x9480	0x6973	# <CJK>
0x9481	0x7164	# <CJK>
0x9482	0x72FD	# <CJK>
0x9483	0x8CB7	# <CJK>
0x9484	0x58F2	# <CJK>
0x9485	0x8CE0	# <CJK>
0x9486	0x966A	# <CJK>
0x9487	0x9019	# <CJK>
0x9488	0x877F	# <CJK>
0x9489	0x79E4	# <CJK>
0x948A	0x77E7	# <CJK>
0x948B	0x8429	# <CJK>
0x948C	0x4F2F	# <CJK>
0x948D	0x5265	# <CJK>
0x948E	0x535A	# <CJK>
0x948F	0x62CD	# <CJK>
0x9490	0x67CF	# <CJK>
0x9491	0x6CCA	# <CJK>
0x9492	0x767D	# <CJK>
0x9493	0x7B94	# <CJK>
0x9494	0x7C95	# <CJK>
0x9495	0x8236	# <CJK>
0x9496	0x8584	# <CJK>
0x9497	0x8FEB	# <CJK>
0x9498	0x66DD	# <CJK>
0x9499	0x6F20	# <CJK>
0x949A	0x7206	# <CJK>
0x949B	0x7E1B	# <CJK>
0x949C	0x83AB	# <CJK>
0x949D	0x99C1	# <CJK>
0x949E	0x9EA6	# <CJK>
0x949F	0x51FD	# <CJK>
0x94A0	0x7BB1	# <CJK>
0x94A1	0x7872	# <CJK>
0x94A2	0x7BB8	# <CJK>
0x94A3	0x8087	# <CJK>
0x94A4	0x7B48	# <CJK>
0x94A5	0x6AE8	# <CJK>
0x94A6	0x5E61	# <CJK>
0x94A7	0x808C	# <CJK>
0x94A8	0x7551	# <CJK>
0x94A9	0x7560	# <CJK>
0x94AA	0x516B	# <CJK>
0x94AB	0x9262	# <CJK>
0x94AC	0x6E8C	# <CJK>
0x94AD	0x767A	# <CJK>
0x94AE	0x9197	# <CJK>
0x94AF	0x9AEA	# <CJK>
0x94B0	0x4F10	# <CJK>
0x94B1	0x7F70	# <CJK>
0x94B2	0x629C	# <CJK>
0x94B3	0x7B4F	# <CJK>
0x94B4	0x95A5	# <CJK>
0x94B5	0x9CE9	# <CJK>
0x94B6	0x567A	# <CJK>
0x94B7	0x5859	# <CJK>
0x94B8	0x86E4	# <CJK>
0x94B9	0x96BC	# <CJK>
0x94BA	0x4F34	# <CJK>
0x94BB	0x5224	# <CJK>
0x94BC	0x534A	# <CJK>
0x94BD	0x53CD	# <CJK>
0x94BE	0x53DB	# <CJK>
0x94BF	0x5E06	# <CJK>
0x94C0	0x642C	# <CJK>
0x94C1	0x6591	# <CJK>
0x94C2	0x677F	# <CJK>
0x94C3	0x6C3E	# <CJK>
0x94C4	0x6C4E	# <CJK>
0x94C5	0x7248	# <CJK>
0x94C6	0x72AF	# <CJK>
0x94C7	0x73ED	# <CJK>
0x94C8	0x7554	# <CJK>
0x94C9	0x7E41	# <CJK>
0x94CA	0x822C	# <CJK>
0x94CB	0x85E9	# <CJK>
0x94CC	0x8CA9	# <CJK>
0x94CD	0x7BC4	# <CJK>
0x94CE	0x91C6	# <CJK>
0x94CF	0x7169	# <CJK>
0x94D0	0x9812	# <CJK>
0x94D1	0x98EF	# <CJK>
0x94D2	0x633D	# <CJK>
0x94D3	0x6669	# <CJK>
0x94D4	0x756A	# <CJK>
0x94D5	0x76E4	# <CJK>
0x94D6	0x78D0	# <CJK>
0x94D7	0x8543	# <CJK>
0x94D8	0x86EE	# <CJK>
0x94D9	0x532A	# <CJK>
0x94DA	0x5351	# <CJK>
0x94DB	0x5426	# <CJK>
0x94DC	0x5983	# <CJK>
0x94DD	0x5E87	# <CJK>
0x94DE	0x5F7C	# <CJK>
0x94DF	0x60B2	# <CJK>
0x94E0	0x6249	# <CJK>
0x94E1	0x6279	# <CJK>
0x94E2	0x62AB	# <CJK>
0x94E3	0x6590	# <CJK>
0x94E4	0x6BD4	# <CJK>
0x94E5	0x6CCC	# <CJK>
0x94E6	0x75B2	# <CJK>
0x94E7	0x76AE	# <CJK>
0x94E8	0x7891	# <CJK>
0x94E9	0x79D8	# <CJK>
0x94EA	0x7DCB	# <CJK>
0x94EB	0x7F77	# <CJK>
0x94EC	0x80A5	# <CJK>
0x94ED	0x88AB	# <CJK>
0x94EE	0x8AB9	# <CJK>
0x94EF	0x8CBB	# <CJK>
0x94F0	0x907F	# <CJK>
0x94F1	0x975E	# <CJK>
0x94F2	0x98DB	# <CJK>
0x94F3	0x6A0B	# <CJK>
0x94F4	0x7C38	# <CJK>
0x94F5	0x5099	# <CJK>
0x94F6	0x5C3E	# <CJK>
0x94F7	0x5FAE	# <CJK>
0x94F8	0x6787	# <CJK>
0x94F9	0x6BD8	# <CJK>
0x94FA	0x7435	# <CJK>
0x94FB	0x7709	# <CJK>
0x94FC	0x7F8E	# <CJK>
0x9540	0x9F3B	# <CJK>
0x9541	0x67CA	# <CJK>
0x9542	0x7A17	# <CJK>
0x9543	0x5339	# <CJK>
0x9544	0x758B	# <CJK>
0x9545	0x9AED	# <CJK>
0x9546	0x5F66	# <CJK>
0x9547	0x819D	# <CJK>
0x9548	0x83F1	# <CJK>
0x9549	0x8098	# <CJK>
0x954A	0x5F3C	# <CJK>
0x954B	0x5FC5	# <CJK>
0x954C	0x7562	# <CJK>
0x954D	0x7B46	# <CJK>
0x954E	0x903C	# <CJK>
0x954F	0x6867	# <CJK>
0x9550	0x59EB	# <CJK>
0x9551	0x5A9B	# <CJK>
0x9552	0x7D10	# <CJK>
0x9553	0x767E	# <CJK>
0x9554	0x8B2C	# <CJK>
0x9555	0x4FF5	# <CJK>
0x9556	0x5F6A	# <CJK>
0x9557	0x6A19	# <CJK>
0x9558	0x6C37	# <CJK>
0x9559	0x6F02	# <CJK>
0x955A	0x74E2	# <CJK>
0x955B	0x7968	# <CJK>
0x955C	0x8868	# <CJK>
0x955D	0x8A55	# <CJK>
0x955E	0x8C79	# <CJK>
0x955F	0x5EDF	# <CJK>
0x9560	0x63CF	# <CJK>
0x9561	0x75C5	# <CJK>
0x9562	0x79D2	# <CJK>
0x9563	0x82D7	# <CJK>
0x9564	0x9328	# <CJK>
0x9565	0x92F2	# <CJK>
0x9566	0x849C	# <CJK>
0x9567	0x86ED	# <CJK>
0x9568	0x9C2D	# <CJK>
0x9569	0x54C1	# <CJK>
0x956A	0x5F6C	# <CJK>
0x956B	0x658C	# <CJK>
0x956C	0x6D5C	# <CJK>
0x956D	0x7015	# <CJK>
0x956E	0x8CA7	# <CJK>
0x956F	0x8CD3	# <CJK>
0x9570	0x983B	# <CJK>
0x9571	0x654F	# <CJK>
0x9572	0x74F6	# <CJK>
0x9573	0x4E0D	# <CJK>
0x9574	0x4ED8	# <CJK>
0x9575	0x57E0	# <CJK>
0x9576	0x592B	# <CJK>
0x9577	0x5A66	# <CJK>
0x9578	0x5BCC	# <CJK>
0x9579	0x51A8	# <CJK>
0x957A	0x5E03	# <CJK>
0x957B	0x5E9C	# <CJK>
0x957C	0x6016	# <CJK>
0x957D	0x6276	# <CJK>
0x957E	0x6577	# <CJK>
0x9580	0x65A7	# <CJK>
0x9581	0x666E	# <CJK>
0x9582	0x6D6E	# <CJK>
0x9583	0x7236	# <CJK>
0x9584	0x7B26	# <CJK>
0x9585	0x8150	# <CJK>
0x9586	0x819A	# <CJK>
0x9587	0x8299	# <CJK>
0x9588	0x8B5C	# <CJK>
0x9589	0x8CA0	# <CJK>
0x958A	0x8CE6	# <CJK>
0x958B	0x8D74	# <CJK>
0x958C	0x961C	# <CJK>
0x958D	0x9644	# <CJK>
0x958E	0x4FAE	# <CJK>
0x958F	0x64AB	# <CJK>
0x9590	0x6B66	# <CJK>
0x9591	0x821E	# <CJK>
0x9592	0x8461	# <CJK>
0x9593	0x856A	# <CJK>
0x9594	0x90E8	# <CJK>
0x9595	0x5C01	# <CJK>
0x9596	0x6953	# <CJK>
0x9597	0x98A8	# <CJK>
0x9598	0x847A	# <CJK>
0x9599	0x8557	# <CJK>
0x959A	0x4F0F	# <CJK>
0x959B	0x526F	# <CJK>
0x959C	0x5FA9	# <CJK>
0x959D	0x5E45	# <CJK>
0x959E	0x670D	# <CJK>
0x959F	0x798F	# <CJK>
0x95A0	0x8179	# <CJK>
0x95A1	0x8907	# <CJK>
0x95A2	0x8986	# <CJK>
0x95A3	0x6DF5	# <CJK>
0x95A4	0x5F17	# <CJK>
0x95A5	0x6255	# <CJK>
0x95A6	0x6CB8	# <CJK>
0x95A7	0x4ECF	# <CJK>
0x95A8	0x7269	# <CJK>
0x95A9	0x9B92	# <CJK>
0x95AA	0x5206	# <CJK>
0x95AB	0x543B	# <CJK>
0x95AC	0x5674	# <CJK>
0x95AD	0x58B3	# <CJK>
0x95AE	0x61A4	# <CJK>
0x95AF	0x626E	# <CJK>
0x95B0	0x711A	# <CJK>
0x95B1	0x596E	# <CJK>
0x95B2	0x7C89	# <CJK>
0x95B3	0x7CDE	# <CJK>
0x95B4	0x7D1B	# <CJK>
0x95B5	0x96F0	# <CJK>
0x95B6	0x6587	# <CJK>
0x95B7	0x805E	# <CJK>
0x95B8	0x4E19	# <CJK>
0x95B9	0x4F75	# <CJK>
0x95BA	0x5175	# <CJK>
0x95BB	0x5840	# <CJK>
0x95BC	0x5E63	# <CJK>
0x95BD	0x5E73	# <CJK>
0x95BE	0x5F0A	# <CJK>
0x95BF	0x67C4	# <CJK>
0x95C0	0x4E26	# <CJK>
0x95C1	0x853D	# <CJK>
0x95C2	0x9589	# <CJK>
0x95C3	0x965B	# <CJK>
0x95C4	0x7C73	# <CJK>
0x95C5	0x9801	# <CJK>
0x95C6	0x50FB	# <CJK>
0x95C7	0x58C1	# <CJK>
0x95C8	0x7656	# <CJK>
0x95C9	0x78A7	# <CJK>
0x95CA	0x5225	# <CJK>
0x95CB	0x77A5	# <CJK>
0x95CC	0x8511	# <CJK>
0x95CD	0x7B86	# <CJK>
0x95CE	0x504F	# <CJK>
0x95CF	0x5909	# <CJK>
0x95D0	0x7247	# <CJK>
0x95D1	0x7BC7	# <CJK>
0x95D2	0x7DE8	# <CJK>
0x95D3	0x8FBA	# <CJK>
0x95D4	0x8FD4	# <CJK>
0x95D5	0x904D	# <CJK>
0x95D6	0x4FBF	# <CJK>
0x95D7	0x52C9	# <CJK>
0x95D8	0x5A29	# <CJK>
0x95D9	0x5F01	# <CJK>
0x95DA	0x97AD	# <CJK>
0x95DB	0x4FDD	# <CJK>
0x95DC	0x8217	# <CJK>
0x95DD	0x92EA	# <CJK>
0x95DE	0x5703	# <CJK>
0x95DF	0x6355	# <CJK>
0x95E0	0x6B69	# <CJK>
0x95E1	0x752B	# <CJK>
0x95E2	0x88DC	# <CJK>
0x95E3	0x8F14	# <CJK>
0x95E4	0x7A42	# <CJK>
0x95E5	0x52DF	# <CJK>
0x95E6	0x5893	# <CJK>
0x95E7	0x6155	# <CJK>
0x95E8	0x620A	# <CJK>
0x95E9	0x66AE	# <CJK>
0x95EA	0x6BCD	# <CJK>
0x95EB	0x7C3F	# <CJK>
0x95EC	0x83E9	# <CJK>
0x95ED	0x5023	# <CJK>
0x95EE	0x4FF8	# <CJK>
0x95EF	0x5305	# <CJK>
0x95F0	0x5446	# <CJK>
0x95F1	0x5831	# <CJK>
0x95F2	0x5949	# <CJK>
0x95F3	0x5B9D	# <CJK>
0x95F4	0x5CF0	# <CJK>
0x95F5	0x5CEF	# <CJK>
0x95F6	0x5D29	# <CJK>
0x95F7	0x5E96	# <CJK>
0x95F8	0x62B1	# <CJK>
0x95F9	0x6367	# <CJK>
0x95FA	0x653E	# <CJK>
0x95FB	0x65B9	# <CJK>
0x95FC	0x670B	# <CJK>
0x9640	0x6CD5	# <CJK>
0x9641	0x6CE1	# <CJK>
0x9642	0x70F9	# <CJK>
0x9643	0x7832	# <CJK>
0x9644	0x7E2B	# <CJK>
0x9645	0x80DE	# <CJK>
0x9646	0x82B3	# <CJK>
0x9647	0x840C	# <CJK>
0x9648	0x84EC	# <CJK>
0x9649	0x8702	# <CJK>
0x964A	0x8912	# <CJK>
0x964B	0x8A2A	# <CJK>
0x964C	0x8C4A	# <CJK>
0x964D	0x90A6	# <CJK>
0x964E	0x92D2	# <CJK>
0x964F	0x98FD	# <CJK>
0x9650	0x9CF3	# <CJK>
0x9651	0x9D6C	# <CJK>
0x9652	0x4E4F	# <CJK>
0x9653	0x4EA1	# <CJK>
0x9654	0x508D	# <CJK>
0x9655	0x5256	# <CJK>
0x9656	0x574A	# <CJK>
0x9657	0x59A8	# <CJK>
0x9658	0x5E3D	# <CJK>
0x9659	0x5FD8	# <CJK>
0x965A	0x5FD9	# <CJK>
0x965B	0x623F	# <CJK>
0x965C	0x66B4	# <CJK>
0x965D	0x671B	# <CJK>
0x965E	0x67D0	# <CJK>
0x965F	0x68D2	# <CJK>
0x9660	0x5192	# <CJK>
0x9661	0x7D21	# <CJK>
0x9662	0x80AA	# <CJK>
0x9663	0x81A8	# <CJK>
0x9664	0x8B00	# <CJK>
0x9665	0x8C8C	# <CJK>
0x9666	0x8CBF	# <CJK>
0x9667	0x927E	# <CJK>
0x9668	0x9632	# <CJK>
0x9669	0x5420	# <CJK>
0x966A	0x982C	# <CJK>
0x966B	0x5317	# <CJK>
0x966C	0x50D5	# <CJK>
0x966D	0x535C	# <CJK>
0x966E	0x58A8	# <CJK>
0x966F	0x64B2	# <CJK>
0x9670	0x6734	# <CJK>
0x9671	0x7267	# <CJK>
0x9672	0x7766	# <CJK>
0x9673	0x7A46	# <CJK>
0x9674	0x91E6	# <CJK>
0x9675	0x52C3	# <CJK>
0x9676	0x6CA1	# <CJK>
0x9677	0x6B86	# <CJK>
0x9678	0x5800	# <CJK>
0x9679	0x5E4C	# <CJK>
0x967A	0x5954	# <CJK>
0x967B	0x672C	# <CJK>
0x967C	0x7FFB	# <CJK>
0x967D	0x51E1	# <CJK>
0x967E	0x76C6	# <CJK>
0x9680	0x6469	# <CJK>
0x9681	0x78E8	# <CJK>
0x9682	0x9B54	# <CJK>
0x9683	0x9EBB	# <CJK>
0x9684	0x57CB	# <CJK>
0x9685	0x59B9	# <CJK>
0x9686	0x6627	# <CJK>
0x9687	0x679A	# <CJK>
0x9688	0x6BCE	# <CJK>
0x9689	0x54E9	# <CJK>
0x968A	0x69D9	# <CJK>
0x968B	0x5E55	# <CJK>
0x968C	0x819C	# <CJK>
0x968D	0x6795	# <CJK>
0x968E	0x9BAA	# <CJK>
0x968F	0x67FE	# <CJK>
0x9690	0x9C52	# <CJK>
0x9691	0x685D	# <CJK>
0x9692	0x4EA6	# <CJK>
0x9693	0x4FE3	# <CJK>
0x9694	0x53C8	# <CJK>
0x9695	0x62B9	# <CJK>
0x9696	0x672B	# <CJK>
0x9697	0x6CAB	# <CJK>
0x9698	0x8FC4	# <CJK>
0x9699	0x4FAD	# <CJK>
0x969A	0x7E6D	# <CJK>
0x969B	0x9EBF	# <CJK>
0x969C	0x4E07	# <CJK>
0x969D	0x6162	# <CJK>
0x969E	0x6E80	# <CJK>
0x969F	0x6F2B	# <CJK>
0x96A0	0x8513	# <CJK>
0x96A1	0x5473	# <CJK>
0x96A2	0x672A	# <CJK>
0x96A3	0x9B45	# <CJK>
0x96A4	0x5DF3	# <CJK>
0x96A5	0x7B95	# <CJK>
0x96A6	0x5CAC	# <CJK>
0x96A7	0x5BC6	# <CJK>
0x96A8	0x871C	# <CJK>
0x96A9	0x6E4A	# <CJK>
0x96AA	0x84D1	# <CJK>
0x96AB	0x7A14	# <CJK>
0x96AC	0x8108	# <CJK>
0x96AD	0x5999	# <CJK>
0x96AE	0x7C8D	# <CJK>
0x96AF	0x6C11	# <CJK>
0x96B0	0x7720	# <CJK>
0x96B1	0x52D9	# <CJK>
0x96B2	0x5922	# <CJK>
0x96B3	0x7121	# <CJK>
0x96B4	0x725F	# <CJK>
0x96B5	0x77DB	# <CJK>
0x96B6	0x9727	# <CJK>
0x96B7	0x9D61	# <CJK>
0x96B8	0x690B	# <CJK>
0x96B9	0x5A7F	# <CJK>
0x96BA	0x5A18	# <CJK>
0x96BB	0x51A5	# <CJK>
0x96BC	0x540D	# <CJK>
0x96BD	0x547D	# <CJK>
0x96BE	0x660E	# <CJK>
0x96BF	0x76DF	# <CJK>
0x96C0	0x8FF7	# <CJK>
0x96C1	0x9298	# <CJK>
0x96C2	0x9CF4	# <CJK>
0x96C3	0x59EA	# <CJK>
0x96C4	0x725D	# <CJK>
0x96C5	0x6EC5	# <CJK>
0x96C6	0x514D	# <CJK>
0x96C7	0x68C9	# <CJK>
0x96C8	0x7DBF	# <CJK>
0x96C9	0x7DEC	# <CJK>
0x96CA	0x9762	# <CJK>
0x96CB	0x9EBA	# <CJK>
0x96CC	0x6478	# <CJK>
0x96CD	0x6A21	# <CJK>
0x96CE	0x8302	# <CJK>
0x96CF	0x5984	# <CJK>
0x96D0	0x5B5F	# <CJK>
0x96D1	0x6BDB	# <CJK>
0x96D2	0x731B	# <CJK>
0x96D3	0x76F2	# <CJK>
0x96D4	0x7DB2	# <CJK>
0x96D5	0x8017	# <CJK>
0x96D6	0x8499	# <CJK>
0x96D7	0x5132	# <CJK>
0x96D8	0x6728	# <CJK>
0x96D9	0x9ED9	# <CJK>
0x96DA	0x76EE	# <CJK>
0x96DB	0x6762	# <CJK>
0x96DC	0x52FF	# <CJK>
0x96DD	0x9905	# <CJK>
0x96DE	0x5C24	# <CJK>
0x96DF	0x623B	# <CJK>
0x96E0	0x7C7E	# <CJK>
0x96E1	0x8CB0	# <CJK>
0x96E2	0x554F	# <CJK>
0x96E3	0x60B6	# <CJK>
0x96E4	0x7D0B	# <CJK>
0x96E5	0x9580	# <CJK>
0x96E6	0x5301	# <CJK>
0x96E7	0x4E5F	# <CJK>
0x96E8	0x51B6	# <CJK>
0x96E9	0x591C	# <CJK>
0x96EA	0x723A	# <CJK>
0x96EB	0x8036	# <CJK>
0x96EC	0x91CE	# <CJK>
0x96ED	0x5F25	# <CJK>
0x96EE	0x77E2	# <CJK>
0x96EF	0x5384	# <CJK>
0x96F0	0x5F79	# <CJK>
0x96F1	0x7D04	# <CJK>
0x96F2	0x85AC	# <CJK>
0x96F3	0x8A33	# <CJK>
0x96F4	0x8E8D	# <CJK>
0x96F5	0x9756	# <CJK>
0x96F6	0x67F3	# <CJK>
0x96F7	0x85AE	# <CJK>
0x96F8	0x9453	# <CJK>
0x96F9	0x6109	# <CJK>
0x96FA	0x6108	# <CJK>
0x96FB	0x6CB9	# <CJK>
0x96FC	0x7652	# <CJK>
0x9740	0x8AED	# <CJK>
0x9741	0x8F38	# <CJK>
0x9742	0x552F	# <CJK>
0x9743	0x4F51	# <CJK>
0x9744	0x512A	# <CJK>
0x9745	0x52C7	# <CJK>
0x9746	0x53CB	# <CJK>
0x9747	0x5BA5	# <CJK>
0x9748	0x5E7D	# <CJK>
0x9749	0x60A0	# <CJK>
0x974A	0x6182	# <CJK>
0x974B	0x63D6	# <CJK>
0x974C	0x6709	# <CJK>
0x974D	0x67DA	# <CJK>
0x974E	0x6E67	# <CJK>
0x974F	0x6D8C	# <CJK>
0x9750	0x7336	# <CJK>
0x9751	0x7337	# <CJK>
0x9752	0x7531	# <CJK>
0x9753	0x7950	# <CJK>
0x9754	0x88D5	# <CJK>
0x9755	0x8A98	# <CJK>
0x9756	0x904A	# <CJK>
0x9757	0x9091	# <CJK>
0x9758	0x90F5	# <CJK>
0x9759	0x96C4	# <CJK>
0x975A	0x878D	# <CJK>
0x975B	0x5915	# <CJK>
0x975C	0x4E88	# <CJK>
0x975D	0x4F59	# <CJK>
0x975E	0x4E0E	# <CJK>
0x975F	0x8A89	# <CJK>
0x9760	0x8F3F	# <CJK>
0x9761	0x9810	# <CJK>
0x9762	0x50AD	# <CJK>
0x9763	0x5E7C	# <CJK>
0x9764	0x5996	# <CJK>
0x9765	0x5BB9	# <CJK>
0x9766	0x5EB8	# <CJK>
0x9767	0x63DA	# <CJK>
0x9768	0x63FA	# <CJK>
0x9769	0x64C1	# <CJK>
0x976A	0x66DC	# <CJK>
0x976B	0x694A	# <CJK>
0x976C	0x69D8	# <CJK>
0x976D	0x6D0B	# <CJK>
0x976E	0x6EB6	# <CJK>
0x976F	0x7194	# <CJK>
0x9770	0x7528	# <CJK>
0x9771	0x7AAF	# <CJK>
0x9772	0x7F8A	# <CJK>
0x9773	0x8000	# <CJK>
0x9774	0x8449	# <CJK>
0x9775	0x84C9	# <CJK>
0x9776	0x8981	# <CJK>
0x9777	0x8B21	# <CJK>
0x9778	0x8E0A	# <CJK>
0x9779	0x9065	# <CJK>
0x977A	0x967D	# <CJK>
0x977B	0x990A	# <CJK>
0x977C	0x617E	# <CJK>
0x977D	0x6291	# <CJK>
0x977E	0x6B32	# <CJK>
0x9780	0x6C83	# <CJK>
0x9781	0x6D74	# <CJK>
0x9782	0x7FCC	# <CJK>
0x9783	0x7FFC	# <CJK>
0x9784	0x6DC0	# <CJK>
0x9785	0x7F85	# <CJK>
0x9786	0x87BA	# <CJK>
0x9787	0x88F8	# <CJK>
0x9788	0x6765	# <CJK>
0x9789	0x83B1	# <CJK>
0x978A	0x983C	# <CJK>
0x978B	0x96F7	# <CJK>
0x978C	0x6D1B	# <CJK>
0x978D	0x7D61	# <CJK>
0x978E	0x843D	# <CJK>
0x978F	0x916A	# <CJK>
0x9790	0x4E71	# <CJK>
0x9791	0x5375	# <CJK>
0x9792	0x5D50	# <CJK>
0x9793	0x6B04	# <CJK>
0x9794	0x6FEB	# <CJK>
0x9795	0x85CD	# <CJK>
0x9796	0x862D	# <CJK>
0x9797	0x89A7	# <CJK>
0x9798	0x5229	# <CJK>
0x9799	0x540F	# <CJK>
0x979A	0x5C65	# <CJK>
0x979B	0x674E	# <CJK>
0x979C	0x68A8	# <CJK>
0x979D	0x7406	# <CJK>
0x979E	0x7483	# <CJK>
0x979F	0x75E2	# <CJK>
0x97A0	0x88CF	# <CJK>
0x97A1	0x88E1	# <CJK>
0x97A2	0x91CC	# <CJK>
0x97A3	0x96E2	# <CJK>
0x97A4	0x9678	# <CJK>
0x97A5	0x5F8B	# <CJK>
0x97A6	0x7387	# <CJK>
0x97A7	0x7ACB	# <CJK>
0x97A8	0x844E	# <CJK>
0x97A9	0x63A0	# <CJK>
0x97AA	0x7565	# <CJK>
0x97AB	0x5289	# <CJK>
0x97AC	0x6D41	# <CJK>
0x97AD	0x6E9C	# <CJK>
0x97AE	0x7409	# <CJK>
0x97AF	0x7559	# <CJK>
0x97B0	0x786B	# <CJK>
0x97B1	0x7C92	# <CJK>
0x97B2	0x9686	# <CJK>
0x97B3	0x7ADC	# <CJK>
0x97B4	0x9F8D	# <CJK>
0x97B5	0x4FB6	# <CJK>
0x97B6	0x616E	# <CJK>
0x97B7	0x65C5	# <CJK>
0x97B8	0x865C	# <CJK>
0x97B9	0x4E86	# <CJK>
0x97BA	0x4EAE	# <CJK>
0x97BB	0x50DA	# <CJK>
0x97BC	0x4E21	# <CJK>
0x97BD	0x51CC	# <CJK>
0x97BE	0x5BEE	# <CJK>
0x97BF	0x6599	# <CJK>
0x97C0	0x6881	# <CJK>
0x97C1	0x6DBC	# <CJK>
0x97C2	0x731F	# <CJK>
0x97C3	0x7642	# <CJK>
0x97C4	0x77AD	# <CJK>
0x97C5	0x7A1C	# <CJK>
0x97C6	0x7CE7	# <CJK>
0x97C7	0x826F	# <CJK>
0x97C8	0x8AD2	# <CJK>
0x97C9	0x907C	# <CJK>
0x97CA	0x91CF	# <CJK>
0x97CB	0x9675	# <CJK>
0x97CC	0x9818	# <CJK>
0x97CD	0x529B	# <CJK>
0x97CE	0x7DD1	# <CJK>
0x97CF	0x502B	# <CJK>
0x97D0	0x5398	# <CJK>
0x97D1	0x6797	# <CJK>
0x97D2	0x6DCB	# <CJK>
0x97D3	0x71D0	# <CJK>
0x97D4	0x7433	# <CJK>
0x97D5	0x81E8	# <CJK>
0x97D6	0x8F2A	# <CJK>
0x97D7	0x96A3	# <CJK>
0x97D8	0x9C57	# <CJK>
0x97D9	0x9E9F	# <CJK>
0x97DA	0x7460	# <CJK>
0x97DB	0x5841	# <CJK>
0x97DC	0x6D99	# <CJK>
0x97DD	0x7D2F	# <CJK>
0x97DE	0x985E	# <CJK>
0x97DF	0x4EE4	# <CJK>
0x97E0	0x4F36	# <CJK>
0x97E1	0x4F8B	# <CJK>
0x97E2	0x51B7	# <CJK>
0x97E3	0x52B1	# <CJK>
0x97E4	0x5DBA	# <CJK>
0x97E5	0x601C	# <CJK>
0x97E6	0x73B2	# <CJK>
0x97E7	0x793C	# <CJK>
0x97E8	0x82D3	# <CJK>
0x97E9	0x9234	# <CJK>
0x97EA	0x96B7	# <CJK>
0x97EB	0x96F6	# <CJK>
0x97EC	0x970A	# <CJK>
0x97ED	0x9E97	# <CJK>
0x97EE	0x9F62	# <CJK>
0x97EF	0x66A6	# <CJK>
0x97F0	0x6B74	# <CJK>
0x97F1	0x5217	# <CJK>
0x97F2	0x52A3	# <CJK>
0x97F3	0x70C8	# <CJK>
0x97F4	0x88C2	# <CJK>
0x97F5	0x5EC9	# <CJK>
0x97F6	0x604B	# <CJK>
0x97F7	0x6190	# <CJK>
0x97F8	0x6F23	# <CJK>
0x97F9	0x7149	# <CJK>
0x97FA	0x7C3E	# <CJK>
0x97FB	0x7DF4	# <CJK>
0x97FC	0x806F	# <CJK>
0x9840	0x84EE	# <CJK>
0x9841	0x9023	# <CJK>
0x9842	0x932C	# <CJK>
0x9843	0x5442	# <CJK>
0x9844	0x9B6F	# <CJK>
0x9845	0x6AD3	# <CJK>
0x9846	0x7089	# <CJK>
0x9847	0x8CC2	# <CJK>
0x9848	0x8DEF	# <CJK>
0x9849	0x9732	# <CJK>
0x984A	0x52B4	# <CJK>
0x984B	0x5A41	# <CJK>
0x984C	0x5ECA	# <CJK>
0x984D	0x5F04	# <CJK>
0x984E	0x6717	# <CJK>
0x984F	0x697C	# <CJK>
0x9850	0x6994	# <CJK>
0x9851	0x6D6A	# <CJK>
0x9852	0x6F0F	# <CJK>
0x9853	0x7262	# <CJK>
0x9854	0x72FC	# <CJK>
0x9855	0x7BED	# <CJK>
0x9856	0x8001	# <CJK>
0x9857	0x807E	# <CJK>
0x9858	0x874B	# <CJK>
0x9859	0x90CE	# <CJK>
0x985A	0x516D	# <CJK>
0x985B	0x9E93	# <CJK>
0x985C	0x7984	# <CJK>
0x985D	0x808B	# <CJK>
0x985E	0x9332	# <CJK>
0x985F	0x8AD6	# <CJK>
0x9860	0x502D	# <CJK>
0x9861	0x548C	# <CJK>
0x9862	0x8A71	# <CJK>
0x9863	0x6B6A	# <CJK>
0x9864	0x8CC4	# <CJK>
0x9865	0x8107	# <CJK>
0x9866	0x60D1	# <CJK>
0x9867	0x67A0	# <CJK>
0x9868	0x9DF2	# <CJK>
0x9869	0x4E99	# <CJK>
0x986A	0x4E98	# <CJK>
0x986B	0x9C10	# <CJK>
0x986C	0x8A6B	# <CJK>
0x986D	0x85C1	# <CJK>
0x986E	0x8568	# <CJK>
0x986F	0x6900	# <CJK>
0x9870	0x6E7E	# <CJK>
0x9871	0x7897	# <CJK>
0x9872	0x8155	# <CJK>
0x989F	0x5F0C	# <CJK>
0x98A0	0x4E10	# <CJK>
0x98A1	0x4E15	# <CJK>
0x98A2	0x4E2A	# <CJK>
0x98A3	0x4E31	# <CJK>
0x98A4	0x4E36	# <CJK>
0x98A5	0x4E3C	# <CJK>
0x98A6	0x4E3F	# <CJK>
0x98A7	0x4E42	# <CJK>
0x98A8	0x4E56	# <CJK>
0x98A9	0x4E58	# <CJK>
0x98AA	0x4E82	# <CJK>
0x98AB	0x4E85	# <CJK>
0x98AC	0x8C6B	# <CJK>
0x98AD	0x4E8A	# <CJK>
0x98AE	0x8212	# <CJK>
0x98AF	0x5F0D	# <CJK>
0x98B0	0x4E8E	# <CJK>
0x98B1	0x4E9E	# <CJK>
0x98B2	0x4E9F	# <CJK>
0x98B3	0x4EA0	# <CJK>
0x98B4	0x4EA2	# <CJK>
0x98B5	0x4EB0	# <CJK>
0x98B6	0x4EB3	# <CJK>
0x98B7	0x4EB6	# <CJK>
0x98B8	0x4ECE	# <CJK>
0x98B9	0x4ECD	# <CJK>
0x98BA	0x4EC4	# <CJK>
0x98BB	0x4EC6	# <CJK>
0x98BC	0x4EC2	# <CJK>
0x98BD	0x4ED7	# <CJK>
0x98BE	0x4EDE	# <CJK>
0x98BF	0x4EED	# <CJK>
0x98C0	0x4EDF	# <CJK>
0x98C1	0x4EF7	# <CJK>
0x98C2	0x4F09	# <CJK>
0x98C3	0x4F5A	# <CJK>
0x98C4	0x4F30	# <CJK>
0x98C5	0x4F5B	# <CJK>
0x98C6	0x4F5D	# <CJK>
0x98C7	0x4F57	# <CJK>
0x98C8	0x4F47	# <CJK>
0x98C9	0x4F76	# <CJK>
0x98CA	0x4F88	# <CJK>
0x98CB	0x4F8F	# <CJK>
0x98CC	0x4F98	# <CJK>
0x98CD	0x4F7B	# <CJK>
0x98CE	0x4F69	# <CJK>
0x98CF	0x4F70	# <CJK>
0x98D0	0x4F91	# <CJK>
0x98D1	0x4F6F	# <CJK>
0x98D2	0x4F86	# <CJK>
0x98D3	0x4F96	# <CJK>
0x98D4	0x5118	# <CJK>
0x98D5	0x4FD4	# <CJK>
0x98D6	0x4FDF	# <CJK>
0x98D7	0x4FCE	# <CJK>
0x98D8	0x4FD8	# <CJK>
0x98D9	0x4FDB	# <CJK>
0x98DA	0x4FD1	# <CJK>
0x98DB	0x4FDA	# <CJK>
0x98DC	0x4FD0	# <CJK>
0x98DD	0x4FE4	# <CJK>
0x98DE	0x4FE5	# <CJK>
0x98DF	0x501A	# <CJK>
0x98E0	0x5028	# <CJK>
0x98E1	0x5014	# <CJK>
0x98E2	0x502A	# <CJK>
0x98E3	0x5025	# <CJK>
0x98E4	0x5005	# <CJK>
0x98E5	0x4F1C	# <CJK>
0x98E6	0x4FF6	# <CJK>
0x98E7	0x5021	# <CJK>
0x98E8	0x5029	# <CJK>
0x98E9	0x502C	# <CJK>
0x98EA	0x4FFE	# <CJK>
0x98EB	0x4FEF	# <CJK>
0x98EC	0x5011	# <CJK>
0x98ED	0x5006	# <CJK>
0x98EE	0x5043	# <CJK>
0x98EF	0x5047	# <CJK>
0x98F0	0x6703	# <CJK>
0x98F1	0x5055	# <CJK>
0x98F2	0x5050	# <CJK>
0x98F3	0x5048	# <CJK>
0x98F4	0x505A	# <CJK>
0x98F5	0x5056	# <CJK>
0x98F6	0x506C	# <CJK>
0x98F7	0x5078	# <CJK>
0x98F8	0x5080	# <CJK>
0x98F9	0x509A	# <CJK>
0x98FA	0x5085	# <CJK>
0x98FB	0x50B4	# <CJK>
0x98FC	0x50B2	# <CJK>
0x9940	0x50C9	# <CJK>
0x9941	0x50CA	# <CJK>
0x9942	0x50B3	# <CJK>
0x9943	0x50C2	# <CJK>
0x9944	0x50D6	# <CJK>
0x9945	0x50DE	# <CJK>
0x9946	0x50E5	# <CJK>
0x9947	0x50ED	# <CJK>
0x9948	0x50E3	# <CJK>
0x9949	0x50EE	# <CJK>
0x994A	0x50F9	# <CJK>
0x994B	0x50F5	# <CJK>
0x994C	0x5109	# <CJK>
0x994D	0x5101	# <CJK>
0x994E	0x5102	# <CJK>
0x994F	0x5116	# <CJK>
0x9950	0x5115	# <CJK>
0x9951	0x5114	# <CJK>
0x9952	0x511A	# <CJK>
0x9953	0x5121	# <CJK>
0x9954	0x513A	# <CJK>
0x9955	0x5137	# <CJK>
0x9956	0x513C	# <CJK>
0x9957	0x513B	# <CJK>
0x9958	0x513F	# <CJK>
0x9959	0x5140	# <CJK>
0x995A	0x5152	# <CJK>
0x995B	0x514C	# <CJK>
0x995C	0x5154	# <CJK>
0x995D	0x5162	# <CJK>
0x995E	0x7AF8	# <CJK>
0x995F	0x5169	# <CJK>
0x9960	0x516A	# <CJK>
0x9961	0x516E	# <CJK>
0x9962	0x5180	# <CJK>
0x9963	0x5182	# <CJK>
0x9964	0x56D8	# <CJK>
0x9965	0x518C	# <CJK>
0x9966	0x5189	# <CJK>
0x9967	0x518F	# <CJK>
0x9968	0x5191	# <CJK>
0x9969	0x5193	# <CJK>
0x996A	0x5195	# <CJK>
0x996B	0x5196	# <CJK>
0x996C	0x51A4	# <CJK>
0x996D	0x51A6	# <CJK>
0x996E	0x51A2	# <CJK>
0x996F	0x51A9	# <CJK>
0x9970	0x51AA	# <CJK>
0x9971	0x51AB	# <CJK>
0x9972	0x51B3	# <CJK>
0x9973	0x51B1	# <CJK>
0x9974	0x51B2	# <CJK>
0x9975	0x51B0	# <CJK>
0x9976	0x51B5	# <CJK>
0x9977	0x51BD	# <CJK>
0x9978	0x51C5	# <CJK>
0x9979	0x51C9	# <CJK>
0x997A	0x51DB	# <CJK>
0x997B	0x51E0	# <CJK>
0x997C	0x8655	# <CJK>
0x997D	0x51E9	# <CJK>
0x997E	0x51ED	# <CJK>
0x9980	0x51F0	# <CJK>
0x9981	0x51F5	# <CJK>
0x9982	0x51FE	# <CJK>
0x9983	0x5204	# <CJK>
0x9984	0x520B	# <CJK>
0x9985	0x5214	# <CJK>
0x9986	0x520E	# <CJK>
0x9987	0x5227	# <CJK>
0x9988	0x522A	# <CJK>
0x9989	0x522E	# <CJK>
0x998A	0x5233	# <CJK>
0x998B	0x5239	# <CJK>
0x998C	0x524F	# <CJK>
0x998D	0x5244	# <CJK>
0x998E	0x524B	# <CJK>
0x998F	0x524C	# <CJK>
0x9990	0x525E	# <CJK>
0x9991	0x5254	# <CJK>
0x9992	0x526A	# <CJK>
0x9993	0x5274	# <CJK>
0x9994	0x5269	# <CJK>
0x9995	0x5273	# <CJK>
0x9996	0x527F	# <CJK>
0x9997	0x527D	# <CJK>
0x9998	0x528D	# <CJK>
0x9999	0x5294	# <CJK>
0x999A	0x5292	# <CJK>
0x999B	0x5271	# <CJK>
0x999C	0x5288	# <CJK>
0x999D	0x5291	# <CJK>
0x999E	0x8FA8	# <CJK>
0x999F	0x8FA7	# <CJK>
0x99A0	0x52AC	# <CJK>
0x99A1	0x52AD	# <CJK>
0x99A2	0x52BC	# <CJK>
0x99A3	0x52B5	# <CJK>
0x99A4	0x52C1	# <CJK>
0x99A5	0x52CD	# <CJK>
0x99A6	0x52D7	# <CJK>
0x99A7	0x52DE	# <CJK>
0x99A8	0x52E3	# <CJK>
0x99A9	0x52E6	# <CJK>
0x99AA	0x98ED	# <CJK>
0x99AB	0x52E0	# <CJK>
0x99AC	0x52F3	# <CJK>
0x99AD	0x52F5	# <CJK>
0x99AE	0x52F8	# <CJK>
0x99AF	0x52F9	# <CJK>
0x99B0	0x5306	# <CJK>
0x99B1	0x5308	# <CJK>
0x99B2	0x7538	# <CJK>
0x99B3	0x530D	# <CJK>
0x99B4	0x5310	# <CJK>
0x99B5	0x530F	# <CJK>
0x99B6	0x5315	# <CJK>
0x99B7	0x531A	# <CJK>
0x99B8	0x5323	# <CJK>
0x99B9	0x532F	# <CJK>
0x99BA	0x5331	# <CJK>
0x99BB	0x5333	# <CJK>
0x99BC	0x5338	# <CJK>
0x99BD	0x5340	# <CJK>
0x99BE	0x5346	# <CJK>
0x99BF	0x5345	# <CJK>
0x99C0	0x4E17	# <CJK>
0x99C1	0x5349	# <CJK>
0x99C2	0x534D	# <CJK>
0x99C3	0x51D6	# <CJK>
0x99C4	0x535E	# <CJK>
0x99C5	0x5369	# <CJK>
0x99C6	0x536E	# <CJK>
0x99C7	0x5918	# <CJK>
0x99C8	0x537B	# <CJK>
0x99C9	0x5377	# <CJK>
0x99CA	0x5382	# <CJK>
0x99CB	0x5396	# <CJK>
0x99CC	0x53A0	# <CJK>
0x99CD	0x53A6	# <CJK>
0x99CE	0x53A5	# <CJK>
0x99CF	0x53AE	# <CJK>
0x99D0	0x53B0	# <CJK>
0x99D1	0x53B6	# <CJK>
0x99D2	0x53C3	# <CJK>
0x99D3	0x7C12	# <CJK>
0x99D4	0x96D9	# <CJK>
0x99D5	0x53DF	# <CJK>
0x99D6	0x66FC	# <CJK>
0x99D7	0x71EE	# <CJK>
0x99D8	0x53EE	# <CJK>
0x99D9	0x53E8	# <CJK>
0x99DA	0x53ED	# <CJK>
0x99DB	0x53FA	# <CJK>
0x99DC	0x5401	# <CJK>
0x99DD	0x543D	# <CJK>
0x99DE	0x5440	# <CJK>
0x99DF	0x542C	# <CJK>
0x99E0	0x542D	# <CJK>
0x99E1	0x543C	# <CJK>
0x99E2	0x542E	# <CJK>
0x99E3	0x5436	# <CJK>
0x99E4	0x5429	# <CJK>
0x99E5	0x541D	# <CJK>
0x99E6	0x544E	# <CJK>
0x99E7	0x548F	# <CJK>
0x99E8	0x5475	# <CJK>
0x99E9	0x548E	# <CJK>
0x99EA	0x545F	# <CJK>
0x99EB	0x5471	# <CJK>
0x99EC	0x5477	# <CJK>
0x99ED	0x5470	# <CJK>
0x99EE	0x5492	# <CJK>
0x99EF	0x547B	# <CJK>
0x99F0	0x5480	# <CJK>
0x99F1	0x5476	# <CJK>
0x99F2	0x5484	# <CJK>
0x99F3	0x5490	# <CJK>
0x99F4	0x5486	# <CJK>
0x99F5	0x54C7	# <CJK>
0x99F6	0x54A2	# <CJK>
0x99F7	0x54B8	# <CJK>
0x99F8	0x54A5	# <CJK>
0x99F9	0x54AC	# <CJK>
0x99FA	0x54C4	# <CJK>
0x99FB	0x54C8	# <CJK>
0x99FC	0x54A8	# <CJK>
0x9A40	0x54AB	# <CJK>
0x9A41	0x54C2	# <CJK>
0x9A42	0x54A4	# <CJK>
0x9A43	0x54BE	# <CJK>
0x9A44	0x54BC	# <CJK>
0x9A45	0x54D8	# <CJK>
0x9A46	0x54E5	# <CJK>
0x9A47	0x54E6	# <CJK>
0x9A48	0x550F	# <CJK>
0x9A49	0x5514	# <CJK>
0x9A4A	0x54FD	# <CJK>
0x9A4B	0x54EE	# <CJK>
0x9A4C	0x54ED	# <CJK>
0x9A4D	0x54FA	# <CJK>
0x9A4E	0x54E2	# <CJK>
0x9A4F	0x5539	# <CJK>
0x9A50	0x5540	# <CJK>
0x9A51	0x5563	# <CJK>
0x9A52	0x554C	# <CJK>
0x9A53	0x552E	# <CJK>
0x9A54	0x555C	# <CJK>
0x9A55	0x5545	# <CJK>
0x9A56	0x5556	# <CJK>
0x9A57	0x5557	# <CJK>
0x9A58	0x5538	# <CJK>
0x9A59	0x5533	# <CJK>
0x9A5A	0x555D	# <CJK>
0x9A5B	0x5599	# <CJK>
0x9A5C	0x5580	# <CJK>
0x9A5D	0x54AF	# <CJK>
0x9A5E	0x558A	# <CJK>
0x9A5F	0x559F	# <CJK>
0x9A60	0x557B	# <CJK>
0x9A61	0x557E	# <CJK>
0x9A62	0x5598	# <CJK>
0x9A63	0x559E	# <CJK>
0x9A64	0x55AE	# <CJK>
0x9A65	0x557C	# <CJK>
0x9A66	0x5583	# <CJK>
0x9A67	0x55A9	# <CJK>
0x9A68	0x5587	# <CJK>
0x9A69	0x55A8	# <CJK>
0x9A6A	0x55DA	# <CJK>
0x9A6B	0x55C5	# <CJK>
0x9A6C	0x55DF	# <CJK>
0x9A6D	0x55C4	# <CJK>
0x9A6E	0x55DC	# <CJK>
0x9A6F	0x55E4	# <CJK>
0x9A70	0x55D4	# <CJK>
0x9A71	0x5614	# <CJK>
0x9A72	0x55F7	# <CJK>
0x9A73	0x5616	# <CJK>
0x9A74	0x55FE	# <CJK>
0x9A75	0x55FD	# <CJK>
0x9A76	0x561B	# <CJK>
0x9A77	0x55F9	# <CJK>
0x9A78	0x564E	# <CJK>
0x9A79	0x5650	# <CJK>
0x9A7A	0x71DF	# <CJK>
0x9A7B	0x5634	# <CJK>
0x9A7C	0x5636	# <CJK>
0x9A7D	0x5632	# <CJK>
0x9A7E	0x5638	# <CJK>
0x9A80	0x566B	# <CJK>
0x9A81	0x5664	# <CJK>
0x9A82	0x562F	# <CJK>
0x9A83	0x566C	# <CJK>
0x9A84	0x566A	# <CJK>
0x9A85	0x5686	# <CJK>
0x9A86	0x5680	# <CJK>
0x9A87	0x568A	# <CJK>
0x9A88	0x56A0	# <CJK>
0x9A89	0x5694	# <CJK>
0x9A8A	0x568F	# <CJK>
0x9A8B	0x56A5	# <CJK>
0x9A8C	0x56AE	# <CJK>
0x9A8D	0x56B6	# <CJK>
0x9A8E	0x56B4	# <CJK>
0x9A8F	0x56C2	# <CJK>
0x9A90	0x56BC	# <CJK>
0x9A91	0x56C1	# <CJK>
0x9A92	0x56C3	# <CJK>
0x9A93	0x56C0	# <CJK>
0x9A94	0x56C8	# <CJK>
0x9A95	0x56CE	# <CJK>
0x9A96	0x56D1	# <CJK>
0x9A97	0x56D3	# <CJK>
0x9A98	0x56D7	# <CJK>
0x9A99	0x56EE	# <CJK>
0x9A9A	0x56F9	# <CJK>
0x9A9B	0x5700	# <CJK>
0x9A9C	0x56FF	# <CJK>
0x9A9D	0x5704	# <CJK>
0x9A9E	0x5709	# <CJK>
0x9A9F	0x5708	# <CJK>
0x9AA0	0x570B	# <CJK>
0x9AA1	0x570D	# <CJK>
0x9AA2	0x5713	# <CJK>
0x9AA3	0x5718	# <CJK>
0x9AA4	0x5716	# <CJK>
0x9AA5	0x55C7	# <CJK>
0x9AA6	0x571C	# <CJK>
0x9AA7	0x5726	# <CJK>
0x9AA8	0x5737	# <CJK>
0x9AA9	0x5738	# <CJK>
0x9AAA	0x574E	# <CJK>
0x9AAB	0x573B	# <CJK>
0x9AAC	0x5740	# <CJK>
0x9AAD	0x574F	# <CJK>
0x9AAE	0x5769	# <CJK>
0x9AAF	0x57C0	# <CJK>
0x9AB0	0x5788	# <CJK>
0x9AB1	0x5761	# <CJK>
0x9AB2	0x577F	# <CJK>
0x9AB3	0x5789	# <CJK>
0x9AB4	0x5793	# <CJK>
0x9AB5	0x57A0	# <CJK>
0x9AB6	0x57B3	# <CJK>
0x9AB7	0x57A4	# <CJK>
0x9AB8	0x57AA	# <CJK>
0x9AB9	0x57B0	# <CJK>
0x9ABA	0x57C3	# <CJK>
0x9ABB	0x57C6	# <CJK>
0x9ABC	0x57D4	# <CJK>
0x9ABD	0x57D2	# <CJK>
0x9ABE	0x57D3	# <CJK>
0x9ABF	0x580A	# <CJK>
0x9AC0	0x57D6	# <CJK>
0x9AC1	0x57E3	# <CJK>
0x9AC2	0x580B	# <CJK>
0x9AC3	0x5819	# <CJK>
0x9AC4	0x581D	# <CJK>
0x9AC5	0x5872	# <CJK>
0x9AC6	0x5821	# <CJK>
0x9AC7	0x5862	# <CJK>
0x9AC8	0x584B	# <CJK>
0x9AC9	0x5870	# <CJK>
0x9ACA	0x6BC0	# <CJK>
0x9ACB	0x5852	# <CJK>
0x9ACC	0x583D	# <CJK>
0x9ACD	0x5879	# <CJK>
0x9ACE	0x5885	# <CJK>
0x9ACF	0x58B9	# <CJK>
0x9AD0	0x589F	# <CJK>
0x9AD1	0x58AB	# <CJK>
0x9AD2	0x58BA	# <CJK>
0x9AD3	0x58DE	# <CJK>
0x9AD4	0x58BB	# <CJK>
0x9AD5	0x58B8	# <CJK>
0x9AD6	0x58AE	# <CJK>
0x9AD7	0x58C5	# <CJK>
0x9AD8	0x58D3	# <CJK>
0x9AD9	0x58D1	# <CJK>
0x9ADA	0x58D7	# <CJK>
0x9ADB	0x58D9	# <CJK>
0x9ADC	0x58D8	# <CJK>
0x9ADD	0x58E5	# <CJK>
0x9ADE	0x58DC	# <CJK>
0x9ADF	0x58E4	# <CJK>
0x9AE0	0x58DF	# <CJK>
0x9AE1	0x58EF	# <CJK>
0x9AE2	0x58FA	# <CJK>
0x9AE3	0x58F9	# <CJK>
0x9AE4	0x58FB	# <CJK>
0x9AE5	0x58FC	# <CJK>
0x9AE6	0x58FD	# <CJK>
0x9AE7	0x5902	# <CJK>
0x9AE8	0x590A	# <CJK>
0x9AE9	0x5910	# <CJK>
0x9AEA	0x591B	# <CJK>
0x9AEB	0x68A6	# <CJK>
0x9AEC	0x5925	# <CJK>
0x9AED	0x592C	# <CJK>
0x9AEE	0x592D	# <CJK>
0x9AEF	0x5932	# <CJK>
0x9AF0	0x5938	# <CJK>
0x9AF1	0x593E	# <CJK>
0x9AF2	0x7AD2	# <CJK>
0x9AF3	0x5955	# <CJK>
0x9AF4	0x5950	# <CJK>
0x9AF5	0x594E	# <CJK>
0x9AF6	0x595A	# <CJK>
0x9AF7	0x5958	# <CJK>
0x9AF8	0x5962	# <CJK>
0x9AF9	0x5960	# <CJK>
0x9AFA	0x5967	# <CJK>
0x9AFB	0x596C	# <CJK>
0x9AFC	0x5969	# <CJK>
0x9B40	0x5978	# <CJK>
0x9B41	0x5981	# <CJK>
0x9B42	0x599D	# <CJK>
0x9B43	0x4F5E	# <CJK>
0x9B44	0x4FAB	# <CJK>
0x9B45	0x59A3	# <CJK>
0x9B46	0x59B2	# <CJK>
0x9B47	0x59C6	# <CJK>
0x9B48	0x59E8	# <CJK>
0x9B49	0x59DC	# <CJK>
0x9B4A	0x598D	# <CJK>
0x9B4B	0x59D9	# <CJK>
0x9B4C	0x59DA	# <CJK>
0x9B4D	0x5A25	# <CJK>
0x9B4E	0x5A1F	# <CJK>
0x9B4F	0x5A11	# <CJK>
0x9B50	0x5A1C	# <CJK>
0x9B51	0x5A09	# <CJK>
0x9B52	0x5A1A	# <CJK>
0x9B53	0x5A40	# <CJK>
0x9B54	0x5A6C	# <CJK>
0x9B55	0x5A49	# <CJK>
0x9B56	0x5A35	# <CJK>
0x9B57	0x5A36	# <CJK>
0x9B58	0x5A62	# <CJK>
0x9B59	0x5A6A	# <CJK>
0x9B5A	0x5A9A	# <CJK>
0x9B5B	0x5ABC	# <CJK>
0x9B5C	0x5ABE	# <CJK>
0x9B5D	0x5ACB	# <CJK>
0x9B5E	0x5AC2	# <CJK>
0x9B5F	0x5ABD	# <CJK>
0x9B60	0x5AE3	# <CJK>
0x9B61	0x5AD7	# <CJK>
0x9B62	0x5AE6	# <CJK>
0x9B63	0x5AE9	# <CJK>
0x9B64	0x5AD6	# <CJK>
0x9B65	0x5AFA	# <CJK>
0x9B66	0x5AFB	# <CJK>
0x9B67	0x5B0C	# <CJK>
0x9B68	0x5B0B	# <CJK>
0x9B69	0x5B16	# <CJK>
0x9B6A	0x5B32	# <CJK>
0x9B6B	0x5AD0	# <CJK>
0x9B6C	0x5B2A	# <CJK>
0x9B6D	0x5B36	# <CJK>
0x9B6E	0x5B3E	# <CJK>
0x9B6F	0x5B43	# <CJK>
0x9B70	0x5B45	# <CJK>
0x9B71	0x5B40	# <CJK>
0x9B72	0x5B51	# <CJK>
0x9B73	0x5B55	# <CJK>
0x9B74	0x5B5A	# <CJK>
0x9B75	0x5B5B	# <CJK>
0x9B76	0x5B65	# <CJK>
0x9B77	0x5B69	# <CJK>
0x9B78	0x5B70	# <CJK>
0x9B79	0x5B73	# <CJK>
0x9B7A	0x5B75	# <CJK>
0x9B7B	0x5B78	# <CJK>
0x9B7C	0x6588	# <CJK>
0x9B7D	0x5B7A	# <CJK>
0x9B7E	0x5B80	# <CJK>
0x9B80	0x5B83	# <CJK>
0x9B81	0x5BA6	# <CJK>
0x9B82	0x5BB8	# <CJK>
0x9B83	0x5BC3	# <CJK>
0x9B84	0x5BC7	# <CJK>
0x9B85	0x5BC9	# <CJK>
0x9B86	0x5BD4	# <CJK>
0x9B87	0x5BD0	# <CJK>
0x9B88	0x5BE4	# <CJK>
0x9B89	0x5BE6	# <CJK>
0x9B8A	0x5BE2	# <CJK>
0x9B8B	0x5BDE	# <CJK>
0x9B8C	0x5BE5	# <CJK>
0x9B8D	0x5BEB	# <CJK>
0x9B8E	0x5BF0	# <CJK>
0x9B8F	0x5BF6	# <CJK>
0x9B90	0x5BF3	# <CJK>
0x9B91	0x5C05	# <CJK>
0x9B92	0x5C07	# <CJK>
0x9B93	0x5C08	# <CJK>
0x9B94	0x5C0D	# <CJK>
0x9B95	0x5C13	# <CJK>
0x9B96	0x5C20	# <CJK>
0x9B97	0x5C22	# <CJK>
0x9B98	0x5C28	# <CJK>
0x9B99	0x5C38	# <CJK>
0x9B9A	0x5C39	# <CJK>
0x9B9B	0x5C41	# <CJK>
0x9B9C	0x5C46	# <CJK>
0x9B9D	0x5C4E	# <CJK>
0x9B9E	0x5C53	# <CJK>
0x9B9F	0x5C50	# <CJK>
0x9BA0	0x5C4F	# <CJK>
0x9BA1	0x5B71	# <CJK>
0x9BA2	0x5C6C	# <CJK>
0x9BA3	0x5C6E	# <CJK>
0x9BA4	0x4E62	# <CJK>
0x9BA5	0x5C76	# <CJK>
0x9BA6	0x5C79	# <CJK>
0x9BA7	0x5C8C	# <CJK>
0x9BA8	0x5C91	# <CJK>
0x9BA9	0x5C94	# <CJK>
0x9BAA	0x599B	# <CJK>
0x9BAB	0x5CAB	# <CJK>
0x9BAC	0x5CBB	# <CJK>
0x9BAD	0x5CB6	# <CJK>
0x9BAE	0x5CBC	# <CJK>
0x9BAF	0x5CB7	# <CJK>
0x9BB0	0x5CC5	# <CJK>
0x9BB1	0x5CBE	# <CJK>
0x9BB2	0x5CC7	# <CJK>
0x9BB3	0x5CD9	# <CJK>
0x9BB4	0x5CE9	# <CJK>
0x9BB5	0x5CFD	# <CJK>
0x9BB6	0x5CFA	# <CJK>
0x9BB7	0x5CED	# <CJK>
0x9BB8	0x5D8C	# <CJK>
0x9BB9	0x5CEA	# <CJK>
0x9BBA	0x5D0B	# <CJK>
0x9BBB	0x5D15	# <CJK>
0x9BBC	0x5D17	# <CJK>
0x9BBD	0x5D5C	# <CJK>
0x9BBE	0x5D1F	# <CJK>
0x9BBF	0x5D1B	# <CJK>
0x9BC0	0x5D11	# <CJK>
0x9BC1	0x5D14	# <CJK>
0x9BC2	0x5D22	# <CJK>
0x9BC3	0x5D1A	# <CJK>
0x9BC4	0x5D19	# <CJK>
0x9BC5	0x5D18	# <CJK>
0x9BC6	0x5D4C	# <CJK>
0x9BC7	0x5D52	# <CJK>
0x9BC8	0x5D4E	# <CJK>
0x9BC9	0x5D4B	# <CJK>
0x9BCA	0x5D6C	# <CJK>
0x9BCB	0x5D73	# <CJK>
0x9BCC	0x5D76	# <CJK>
0x9BCD	0x5D87	# <CJK>
0x9BCE	0x5D84	# <CJK>
0x9BCF	0x5D82	# <CJK>
0x9BD0	0x5DA2	# <CJK>
0x9BD1	0x5D9D	# <CJK>
0x9BD2	0x5DAC	# <CJK>
0x9BD3	0x5DAE	# <CJK>
0x9BD4	0x5DBD	# <CJK>
0x9BD5	0x5D90	# <CJK>
0x9BD6	0x5DB7	# <CJK>
0x9BD7	0x5DBC	# <CJK>
0x9BD8	0x5DC9	# <CJK>
0x9BD9	0x5DCD	# <CJK>
0x9BDA	0x5DD3	# <CJK>
0x9BDB	0x5DD2	# <CJK>
0x9BDC	0x5DD6	# <CJK>
0x9BDD	0x5DDB	# <CJK>
0x9BDE	0x5DEB	# <CJK>
0x9BDF	0x5DF2	# <CJK>
0x9BE0	0x5DF5	# <CJK>
0x9BE1	0x5E0B	# <CJK>
0x9BE2	0x5E1A	# <CJK>
0x9BE3	0x5E19	# <CJK>
0x9BE4	0x5E11	# <CJK>
0x9BE5	0x5E1B	# <CJK>
0x9BE6	0x5E36	# <CJK>
0x9BE7	0x5E37	# <CJK>
0x9BE8	0x5E44	# <CJK>
0x9BE9	0x5E43	# <CJK>
0x9BEA	0x5E40	# <CJK>
0x9BEB	0x5E4E	# <CJK>
0x9BEC	0x5E57	# <CJK>
0x9BED	0x5E54	# <CJK>
0x9BEE	0x5E5F	# <CJK>
0x9BEF	0x5E62	# <CJK>
0x9BF0	0x5E64	# <CJK>
0x9BF1	0x5E47	# <CJK>
0x9BF2	0x5E75	# <CJK>
0x9BF3	0x5E76	# <CJK>
0x9BF4	0x5E7A	# <CJK>
0x9BF5	0x9EBC	# <CJK>
0x9BF6	0x5E7F	# <CJK>
0x9BF7	0x5EA0	# <CJK>
0x9BF8	0x5EC1	# <CJK>
0x9BF9	0x5EC2	# <CJK>
0x9BFA	0x5EC8	# <CJK>
0x9BFB	0x5ED0	# <CJK>
0x9BFC	0x5ECF	# <CJK>
0x9C40	0x5ED6	# <CJK>
0x9C41	0x5EE3	# <CJK>
0x9C42	0x5EDD	# <CJK>
0x9C43	0x5EDA	# <CJK>
0x9C44	0x5EDB	# <CJK>
0x9C45	0x5EE2	# <CJK>
0x9C46	0x5EE1	# <CJK>
0x9C47	0x5EE8	# <CJK>
0x9C48	0x5EE9	# <CJK>
0x9C49	0x5EEC	# <CJK>
0x9C4A	0x5EF1	# <CJK>
0x9C4B	0x5EF3	# <CJK>
0x9C4C	0x5EF0	# <CJK>
0x9C4D	0x5EF4	# <CJK>
0x9C4E	0x5EF8	# <CJK>
0x9C4F	0x5EFE	# <CJK>
0x9C50	0x5F03	# <CJK>
0x9C51	0x5F09	# <CJK>
0x9C52	0x5F5D	# <CJK>
0x9C53	0x5F5C	# <CJK>
0x9C54	0x5F0B	# <CJK>
0x9C55	0x5F11	# <CJK>
0x9C56	0x5F16	# <CJK>
0x9C57	0x5F29	# <CJK>
0x9C58	0x5F2D	# <CJK>
0x9C59	0x5F38	# <CJK>
0x9C5A	0x5F41	# <CJK>
0x9C5B	0x5F48	# <CJK>
0x9C5C	0x5F4C	# <CJK>
0x9C5D	0x5F4E	# <CJK>
0x9C5E	0x5F2F	# <CJK>
0x9C5F	0x5F51	# <CJK>
0x9C60	0x5F56	# <CJK>
0x9C61	0x5F57	# <CJK>
0x9C62	0x5F59	# <CJK>
0x9C63	0x5F61	# <CJK>
0x9C64	0x5F6D	# <CJK>
0x9C65	0x5F73	# <CJK>
0x9C66	0x5F77	# <CJK>
0x9C67	0x5F83	# <CJK>
0x9C68	0x5F82	# <CJK>
0x9C69	0x5F7F	# <CJK>
0x9C6A	0x5F8A	# <CJK>
0x9C6B	0x5F88	# <CJK>
0x9C6C	0x5F91	# <CJK>
0x9C6D	0x5F87	# <CJK>
0x9C6E	0x5F9E	# <CJK>
0x9C6F	0x5F99	# <CJK>
0x9C70	0x5F98	# <CJK>
0x9C71	0x5FA0	# <CJK>
0x9C72	0x5FA8	# <CJK>
0x9C73	0x5FAD	# <CJK>
0x9C74	0x5FBC	# <CJK>
0x9C75	0x5FD6	# <CJK>
0x9C76	0x5FFB	# <CJK>
0x9C77	0x5FE4	# <CJK>
0x9C78	0x5FF8	# <CJK>
0x9C79	0x5FF1	# <CJK>
0x9C7A	0x5FDD	# <CJK>
0x9C7B	0x60B3	# <CJK>
0x9C7C	0x5FFF	# <CJK>
0x9C7D	0x6021	# <CJK>
0x9C7E	0x6060	# <CJK>
0x9C80	0x6019	# <CJK>
0x9C81	0x6010	# <CJK>
0x9C82	0x6029	# <CJK>
0x9C83	0x600E	# <CJK>
0x9C84	0x6031	# <CJK>
0x9C85	0x601B	# <CJK>
0x9C86	0x6015	# <CJK>
0x9C87	0x602B	# <CJK>
0x9C88	0x6026	# <CJK>
0x9C89	0x600F	# <CJK>
0x9C8A	0x603A	# <CJK>
0x9C8B	0x605A	# <CJK>
0x9C8C	0x6041	# <CJK>
0x9C8D	0x606A	# <CJK>
0x9C8E	0x6077	# <CJK>
0x9C8F	0x605F	# <CJK>
0x9C90	0x604A	# <CJK>
0x9C91	0x6046	# <CJK>
0x9C92	0x604D	# <CJK>
0x9C93	0x6063	# <CJK>
0x9C94	0x6043	# <CJK>
0x9C95	0x6064	# <CJK>
0x9C96	0x6042	# <CJK>
0x9C97	0x606C	# <CJK>
0x9C98	0x606B	# <CJK>
0x9C99	0x6059	# <CJK>
0x9C9A	0x6081	# <CJK>
0x9C9B	0x608D	# <CJK>
0x9C9C	0x60E7	# <CJK>
0x9C9D	0x6083	# <CJK>
0x9C9E	0x609A	# <CJK>
0x9C9F	0x6084	# <CJK>
0x9CA0	0x609B	# <CJK>
0x9CA1	0x6096	# <CJK>
0x9CA2	0x6097	# <CJK>
0x9CA3	0x6092	# <CJK>
0x9CA4	0x60A7	# <CJK>
0x9CA5	0x608B	# <CJK>
0x9CA6	0x60E1	# <CJK>
0x9CA7	0x60B8	# <CJK>
0x9CA8	0x60E0	# <CJK>
0x9CA9	0x60D3	# <CJK>
0x9CAA	0x60B4	# <CJK>
0x9CAB	0x5FF0	# <CJK>
0x9CAC	0x60BD	# <CJK>
0x9CAD	0x60C6	# <CJK>
0x9CAE	0x60B5	# <CJK>
0x9CAF	0x60D8	# <CJK>
0x9CB0	0x614D	# <CJK>
0x9CB1	0x6115	# <CJK>
0x9CB2	0x6106	# <CJK>
0x9CB3	0x60F6	# <CJK>
0x9CB4	0x60F7	# <CJK>
0x9CB5	0x6100	# <CJK>
0x9CB6	0x60F4	# <CJK>
0x9CB7	0x60FA	# <CJK>
0x9CB8	0x6103	# <CJK>
0x9CB9	0x6121	# <CJK>
0x9CBA	0x60FB	# <CJK>
0x9CBB	0x60F1	# <CJK>
0x9CBC	0x610D	# <CJK>
0x9CBD	0x610E	# <CJK>
0x9CBE	0x6147	# <CJK>
0x9CBF	0x613E	# <CJK>
0x9CC0	0x6128	# <CJK>
0x9CC1	0x6127	# <CJK>
0x9CC2	0x614A	# <CJK>
0x9CC3	0x613F	# <CJK>
0x9CC4	0x613C	# <CJK>
0x9CC5	0x612C	# <CJK>
0x9CC6	0x6134	# <CJK>
0x9CC7	0x613D	# <CJK>
0x9CC8	0x6142	# <CJK>
0x9CC9	0x6144	# <CJK>
0x9CCA	0x6173	# <CJK>
0x9CCB	0x6177	# <CJK>
0x9CCC	0x6158	# <CJK>
0x9CCD	0x6159	# <CJK>
0x9CCE	0x615A	# <CJK>
0x9CCF	0x616B	# <CJK>
0x9CD0	0x6174	# <CJK>
0x9CD1	0x616F	# <CJK>
0x9CD2	0x6165	# <CJK>
0x9CD3	0x6171	# <CJK>
0x9CD4	0x615F	# <CJK>
0x9CD5	0x615D	# <CJK>
0x9CD6	0x6153	# <CJK>
0x9CD7	0x6175	# <CJK>
0x9CD8	0x6199	# <CJK>
0x9CD9	0x6196	# <CJK>
0x9CDA	0x6187	# <CJK>
0x9CDB	0x61AC	# <CJK>
0x9CDC	0x6194	# <CJK>
0x9CDD	0x619A	# <CJK>
0x9CDE	0x618A	# <CJK>
0x9CDF	0x6191	# <CJK>
0x9CE0	0x61AB	# <CJK>
0x9CE1	0x61AE	# <CJK>
0x9CE2	0x61CC	# <CJK>
0x9CE3	0x61CA	# <CJK>
0x9CE4	0x61C9	# <CJK>
0x9CE5	0x61F7	# <CJK>
0x9CE6	0x61C8	# <CJK>
0x9CE7	0x61C3	# <CJK>
0x9CE8	0x61C6	# <CJK>
0x9CE9	0x61BA	# <CJK>
0x9CEA	0x61CB	# <CJK>
0x9CEB	0x7F79	# <CJK>
0x9CEC	0x61CD	# <CJK>
0x9CED	0x61E6	# <CJK>
0x9CEE	0x61E3	# <CJK>
0x9CEF	0x61F6	# <CJK>
0x9CF0	0x61FA	# <CJK>
0x9CF1	0x61F4	# <CJK>
0x9CF2	0x61FF	# <CJK>
0x9CF3	0x61FD	# <CJK>
0x9CF4	0x61FC	# <CJK>
0x9CF5	0x61FE	# <CJK>
0x9CF6	0x6200	# <CJK>
0x9CF7	0x6208	# <CJK>
0x9CF8	0x6209	# <CJK>
0x9CF9	0x620D	# <CJK>
0x9CFA	0x620C	# <CJK>
0x9CFB	0x6214	# <CJK>
0x9CFC	0x621B	# <CJK>
0x9D40	0x621E	# <CJK>
0x9D41	0x6221	# <CJK>
0x9D42	0x622A	# <CJK>
0x9D43	0x622E	# <CJK>
0x9D44	0x6230	# <CJK>
0x9D45	0x6232	# <CJK>
0x9D46	0x6233	# <CJK>
0x9D47	0x6241	# <CJK>
0x9D48	0x624E	# <CJK>
0x9D49	0x625E	# <CJK>
0x9D4A	0x6263	# <CJK>
0x9D4B	0x625B	# <CJK>
0x9D4C	0x6260	# <CJK>
0x9D4D	0x6268	# <CJK>
0x9D4E	0x627C	# <CJK>
0x9D4F	0x6282	# <CJK>
0x9D50	0x6289	# <CJK>
0x9D51	0x627E	# <CJK>
0x9D52	0x6292	# <CJK>
0x9D53	0x6293	# <CJK>
0x9D54	0x6296	# <CJK>
0x9D55	0x62D4	# <CJK>
0x9D56	0x6283	# <CJK>
0x9D57	0x6294	# <CJK>
0x9D58	0x62D7	# <CJK>
0x9D59	0x62D1	# <CJK>
0x9D5A	0x62BB	# <CJK>
0x9D5B	0x62CF	# <CJK>
0x9D5C	0x62FF	# <CJK>
0x9D5D	0x62C6	# <CJK>
0x9D5E	0x64D4	# <CJK>
0x9D5F	0x62C8	# <CJK>
0x9D60	0x62DC	# <CJK>
0x9D61	0x62CC	# <CJK>
0x9D62	0x62CA	# <CJK>
0x9D63	0x62C2	# <CJK>
0x9D64	0x62C7	# <CJK>
0x9D65	0x629B	# <CJK>
0x9D66	0x62C9	# <CJK>
0x9D67	0x630C	# <CJK>
0x9D68	0x62EE	# <CJK>
0x9D69	0x62F1	# <CJK>
0x9D6A	0x6327	# <CJK>
0x9D6B	0x6302	# <CJK>
0x9D6C	0x6308	# <CJK>
0x9D6D	0x62EF	# <CJK>
0x9D6E	0x62F5	# <CJK>
0x9D6F	0x6350	# <CJK>
0x9D70	0x633E	# <CJK>
0x9D71	0x634D	# <CJK>
0x9D72	0x641C	# <CJK>
0x9D73	0x634F	# <CJK>
0x9D74	0x6396	# <CJK>
0x9D75	0x638E	# <CJK>
0x9D76	0x6380	# <CJK>
0x9D77	0x63AB	# <CJK>
0x9D78	0x6376	# <CJK>
0x9D79	0x63A3	# <CJK>
0x9D7A	0x638F	# <CJK>
0x9D7B	0x6389	# <CJK>
0x9D7C	0x639F	# <CJK>
0x9D7D	0x63B5	# <CJK>
0x9D7E	0x636B	# <CJK>
0x9D80	0x6369	# <CJK>
0x9D81	0x63BE	# <CJK>
0x9D82	0x63E9	# <CJK>
0x9D83	0x63C0	# <CJK>
0x9D84	0x63C6	# <CJK>
0x9D85	0x63E3	# <CJK>
0x9D86	0x63C9	# <CJK>
0x9D87	0x63D2	# <CJK>
0x9D88	0x63F6	# <CJK>
0x9D89	0x63C4	# <CJK>
0x9D8A	0x6416	# <CJK>
0x9D8B	0x6434	# <CJK>
0x9D8C	0x6406	# <CJK>
0x9D8D	0x6413	# <CJK>
0x9D8E	0x6426	# <CJK>
0x9D8F	0x6436	# <CJK>
0x9D90	0x651D	# <CJK>
0x9D91	0x6417	# <CJK>
0x9D92	0x6428	# <CJK>
0x9D93	0x640F	# <CJK>
0x9D94	0x6467	# <CJK>
0x9D95	0x646F	# <CJK>
0x9D96	0x6476	# <CJK>
0x9D97	0x644E	# <CJK>
0x9D98	0x652A	# <CJK>
0x9D99	0x6495	# <CJK>
0x9D9A	0x6493	# <CJK>
0x9D9B	0x64A5	# <CJK>
0x9D9C	0x64A9	# <CJK>
0x9D9D	0x6488	# <CJK>
0x9D9E	0x64BC	# <CJK>
0x9D9F	0x64DA	# <CJK>
0x9DA0	0x64D2	# <CJK>
0x9DA1	0x64C5	# <CJK>
0x9DA2	0x64C7	# <CJK>
0x9DA3	0x64BB	# <CJK>
0x9DA4	0x64D8	# <CJK>
0x9DA5	0x64C2	# <CJK>
0x9DA6	0x64F1	# <CJK>
0x9DA7	0x64E7	# <CJK>
0x9DA8	0x8209	# <CJK>
0x9DA9	0x64E0	# <CJK>
0x9DAA	0x64E1	# <CJK>
0x9DAB	0x62AC	# <CJK>
0x9DAC	0x64E3	# <CJK>
0x9DAD	0x64EF	# <CJK>
0x9DAE	0x652C	# <CJK>
0x9DAF	0x64F6	# <CJK>
0x9DB0	0x64F4	# <CJK>
0x9DB1	0x64F2	# <CJK>
0x9DB2	0x64FA	# <CJK>
0x9DB3	0x6500	# <CJK>
0x9DB4	0x64FD	# <CJK>
0x9DB5	0x6518	# <CJK>
0x9DB6	0x651C	# <CJK>
0x9DB7	0x6505	# <CJK>
0x9DB8	0x6524	# <CJK>
0x9DB9	0x6523	# <CJK>
0x9DBA	0x652B	# <CJK>
0x9DBB	0x6534	# <CJK>
0x9DBC	0x6535	# <CJK>
0x9DBD	0x6537	# <CJK>
0x9DBE	0x6536	# <CJK>
0x9DBF	0x6538	# <CJK>
0x9DC0	0x754B	# <CJK>
0x9DC1	0x6548	# <CJK>
0x9DC2	0x6556	# <CJK>
0x9DC3	0x6555	# <CJK>
0x9DC4	0x654D	# <CJK>
0x9DC5	0x6558	# <CJK>
0x9DC6	0x655E	# <CJK>
0x9DC7	0x655D	# <CJK>
0x9DC8	0x6572	# <CJK>
0x9DC9	0x6578	# <CJK>
0x9DCA	0x6582	# <CJK>
0x9DCB	0x6583	# <CJK>
0x9DCC	0x8B8A	# <CJK>
0x9DCD	0x659B	# <CJK>
0x9DCE	0x659F	# <CJK>
0x9DCF	0x65AB	# <CJK>
0x9DD0	0x65B7	# <CJK>
0x9DD1	0x65C3	# <CJK>
0x9DD2	0x65C6	# <CJK>
0x9DD3	0x65C1	# <CJK>
0x9DD4	0x65C4	# <CJK>
0x9DD5	0x65CC	# <CJK>
0x9DD6	0x65D2	# <CJK>
0x9DD7	0x65DB	# <CJK>
0x9DD8	0x65D9	# <CJK>
0x9DD9	0x65E0	# <CJK>
0x9DDA	0x65E1	# <CJK>
0x9DDB	0x65F1	# <CJK>
0x9DDC	0x6772	# <CJK>
0x9DDD	0x660A	# <CJK>
0x9DDE	0x6603	# <CJK>
0x9DDF	0x65FB	# <CJK>
0x9DE0	0x6773	# <CJK>
0x9DE1	0x6635	# <CJK>
0x9DE2	0x6636	# <CJK>
0x9DE3	0x6634	# <CJK>
0x9DE4	0x661C	# <CJK>
0x9DE5	0x664F	# <CJK>
0x9DE6	0x6644	# <CJK>
0x9DE7	0x6649	# <CJK>
0x9DE8	0x6641	# <CJK>
0x9DE9	0x665E	# <CJK>
0x9DEA	0x665D	# <CJK>
0x9DEB	0x6664	# <CJK>
0x9DEC	0x6667	# <CJK>
0x9DED	0x6668	# <CJK>
0x9DEE	0x665F	# <CJK>
0x9DEF	0x6662	# <CJK>
0x9DF0	0x6670	# <CJK>
0x9DF1	0x6683	# <CJK>
0x9DF2	0x6688	# <CJK>
0x9DF3	0x668E	# <CJK>
0x9DF4	0x6689	# <CJK>
0x9DF5	0x6684	# <CJK>
0x9DF6	0x6698	# <CJK>
0x9DF7	0x669D	# <CJK>
0x9DF8	0x66C1	# <CJK>
0x9DF9	0x66B9	# <CJK>
0x9DFA	0x66C9	# <CJK>
0x9DFB	0x66BE	# <CJK>
0x9DFC	0x66BC	# <CJK>
0x9E40	0x66C4	# <CJK>
0x9E41	0x66B8	# <CJK>
0x9E42	0x66D6	# <CJK>
0x9E43	0x66DA	# <CJK>
0x9E44	0x66E0	# <CJK>
0x9E45	0x663F	# <CJK>
0x9E46	0x66E6	# <CJK>
0x9E47	0x66E9	# <CJK>
0x9E48	0x66F0	# <CJK>
0x9E49	0x66F5	# <CJK>
0x9E4A	0x66F7	# <CJK>
0x9E4B	0x670F	# <CJK>
0x9E4C	0x6716	# <CJK>
0x9E4D	0x671E	# <CJK>
0x9E4E	0x6726	# <CJK>
0x9E4F	0x6727	# <CJK>
0x9E50	0x9738	# <CJK>
0x9E51	0x672E	# <CJK>
0x9E52	0x673F	# <CJK>
0x9E53	0x6736	# <CJK>
0x9E54	0x6741	# <CJK>
0x9E55	0x6738	# <CJK>
0x9E56	0x6737	# <CJK>
0x9E57	0x6746	# <CJK>
0x9E58	0x675E	# <CJK>
0x9E59	0x6760	# <CJK>
0x9E5A	0x6759	# <CJK>
0x9E5B	0x6763	# <CJK>
0x9E5C	0x6764	# <CJK>
0x9E5D	0x6789	# <CJK>
0x9E5E	0x6770	# <CJK>
0x9E5F	0x67A9	# <CJK>
0x9E60	0x677C	# <CJK>
0x9E61	0x676A	# <CJK>
0x9E62	0x678C	# <CJK>
0x9E63	0x678B	# <CJK>
0x9E64	0x67A6	# <CJK>
0x9E65	0x67A1	# <CJK>
0x9E66	0x6785	# <CJK>
0x9E67	0x67B7	# <CJK>
0x9E68	0x67EF	# <CJK>
0x9E69	0x67B4	# <CJK>
0x9E6A	0x67EC	# <CJK>
0x9E6B	0x67B3	# <CJK>
0x9E6C	0x67E9	# <CJK>
0x9E6D	0x67B8	# <CJK>
0x9E6E	0x67E4	# <CJK>
0x9E6F	0x67DE	# <CJK>
0x9E70	0x67DD	# <CJK>
0x9E71	0x67E2	# <CJK>
0x9E72	0x67EE	# <CJK>
0x9E73	0x67B9	# <CJK>
0x9E74	0x67CE	# <CJK>
0x9E75	0x67C6	# <CJK>
0x9E76	0x67E7	# <CJK>
0x9E77	0x6A9C	# <CJK>
0x9E78	0x681E	# <CJK>
0x9E79	0x6846	# <CJK>
0x9E7A	0x6829	# <CJK>
0x9E7B	0x6840	# <CJK>
0x9E7C	0x684D	# <CJK>
0x9E7D	0x6832	# <CJK>
0x9E7E	0x684E	# <CJK>
0x9E80	0x68B3	# <CJK>
0x9E81	0x682B	# <CJK>
0x9E82	0x6859	# <CJK>
0x9E83	0x6863	# <CJK>
0x9E84	0x6877	# <CJK>
0x9E85	0x687F	# <CJK>
0x9E86	0x689F	# <CJK>
0x9E87	0x688F	# <CJK>
0x9E88	0x68AD	# <CJK>
0x9E89	0x6894	# <CJK>
0x9E8A	0x689D	# <CJK>
0x9E8B	0x689B	# <CJK>
0x9E8C	0x6883	# <CJK>
0x9E8D	0x6AAE	# <CJK>
0x9E8E	0x68B9	# <CJK>
0x9E8F	0x6874	# <CJK>
0x9E90	0x68B5	# <CJK>
0x9E91	0x68A0	# <CJK>
0x9E92	0x68BA	# <CJK>
0x9E93	0x690F	# <CJK>
0x9E94	0x688D	# <CJK>
0x9E95	0x687E	# <CJK>
0x9E96	0x6901	# <CJK>
0x9E97	0x68CA	# <CJK>
0x9E98	0x6908	# <CJK>
0x9E99	0x68D8	# <CJK>
0x9E9A	0x6922	# <CJK>
0x9E9B	0x6926	# <CJK>
0x9E9C	0x68E1	# <CJK>
0x9E9D	0x690C	# <CJK>
0x9E9E	0x68CD	# <CJK>
0x9E9F	0x68D4	# <CJK>
0x9EA0	0x68E7	# <CJK>
0x9EA1	0x68D5	# <CJK>
0x9EA2	0x6936	# <CJK>
0x9EA3	0x6912	# <CJK>
0x9EA4	0x6904	# <CJK>
0x9EA5	0x68D7	# <CJK>
0x9EA6	0x68E3	# <CJK>
0x9EA7	0x6925	# <CJK>
0x9EA8	0x68F9	# <CJK>
0x9EA9	0x68E0	# <CJK>
0x9EAA	0x68EF	# <CJK>
0x9EAB	0x6928	# <CJK>
0x9EAC	0x692A	# <CJK>
0x9EAD	0x691A	# <CJK>
0x9EAE	0x6923	# <CJK>
0x9EAF	0x6921	# <CJK>
0x9EB0	0x68C6	# <CJK>
0x9EB1	0x6979	# <CJK>
0x9EB2	0x6977	# <CJK>
0x9EB3	0x695C	# <CJK>
0x9EB4	0x6978	# <CJK>
0x9EB5	0x696B	# <CJK>
0x9EB6	0x6954	# <CJK>
0x9EB7	0x697E	# <CJK>
0x9EB8	0x696E	# <CJK>
0x9EB9	0x6939	# <CJK>
0x9EBA	0x6974	# <CJK>
0x9EBB	0x693D	# <CJK>
0x9EBC	0x6959	# <CJK>
0x9EBD	0x6930	# <CJK>
0x9EBE	0x6961	# <CJK>
0x9EBF	0x695E	# <CJK>
0x9EC0	0x695D	# <CJK>
0x9EC1	0x6981	# <CJK>
0x9EC2	0x696A	# <CJK>
0x9EC3	0x69B2	# <CJK>
0x9EC4	0x69AE	# <CJK>
0x9EC5	0x69D0	# <CJK>
0x9EC6	0x69BF	# <CJK>
0x9EC7	0x69C1	# <CJK>
0x9EC8	0x69D3	# <CJK>
0x9EC9	0x69BE	# <CJK>
0x9ECA	0x69CE	# <CJK>
0x9ECB	0x5BE8	# <CJK>
0x9ECC	0x69CA	# <CJK>
0x9ECD	0x69DD	# <CJK>
0x9ECE	0x69BB	# <CJK>
0x9ECF	0x69C3	# <CJK>
0x9ED0	0x69A7	# <CJK>
0x9ED1	0x6A2E	# <CJK>
0x9ED2	0x6991	# <CJK>
0x9ED3	0x69A0	# <CJK>
0x9ED4	0x699C	# <CJK>
0x9ED5	0x6995	# <CJK>
0x9ED6	0x69B4	# <CJK>
0x9ED7	0x69DE	# <CJK>
0x9ED8	0x69E8	# <CJK>
0x9ED9	0x6A02	# <CJK>
0x9EDA	0x6A1B	# <CJK>
0x9EDB	0x69FF	# <CJK>
0x9EDC	0x6B0A	# <CJK>
0x9EDD	0x69F9	# <CJK>
0x9EDE	0x69F2	# <CJK>
0x9EDF	0x69E7	# <CJK>
0x9EE0	0x6A05	# <CJK>
0x9EE1	0x69B1	# <CJK>
0x9EE2	0x6A1E	# <CJK>
0x9EE3	0x69ED	# <CJK>
0x9EE4	0x6A14	# <CJK>
0x9EE5	0x69EB	# <CJK>
0x9EE6	0x6A0A	# <CJK>
0x9EE7	0x6A12	# <CJK>
0x9EE8	0x6AC1	# <CJK>
0x9EE9	0x6A23	# <CJK>
0x9EEA	0x6A13	# <CJK>
0x9EEB	0x6A44	# <CJK>
0x9EEC	0x6A0C	# <CJK>
0x9EED	0x6A72	# <CJK>
0x9EEE	0x6A36	# <CJK>
0x9EEF	0x6A78	# <CJK>
0x9EF0	0x6A47	# <CJK>
0x9EF1	0x6A62	# <CJK>
0x9EF2	0x6A59	# <CJK>
0x9EF3	0x6A66	# <CJK>
0x9EF4	0x6A48	# <CJK>
0x9EF5	0x6A38	# <CJK>
0x9EF6	0x6A22	# <CJK>
0x9EF7	0x6A90	# <CJK>
0x9EF8	0x6A8D	# <CJK>
0x9EF9	0x6AA0	# <CJK>
0x9EFA	0x6A84	# <CJK>
0x9EFB	0x6AA2	# <CJK>
0x9EFC	0x6AA3	# <CJK>
0x9F40	0x6A97	# <CJK>
0x9F41	0x8617	# <CJK>
0x9F42	0x6ABB	# <CJK>
0x9F43	0x6AC3	# <CJK>
0x9F44	0x6AC2	# <CJK>
0x9F45	0x6AB8	# <CJK>
0x9F46	0x6AB3	# <CJK>
0x9F47	0x6AAC	# <CJK>
0x9F48	0x6ADE	# <CJK>
0x9F49	0x6AD1	# <CJK>
0x9F4A	0x6ADF	# <CJK>
0x9F4B	0x6AAA	# <CJK>
0x9F4C	0x6ADA	# <CJK>
0x9F4D	0x6AEA	# <CJK>
0x9F4E	0x6AFB	# <CJK>
0x9F4F	0x6B05	# <CJK>
0x9F50	0x8616	# <CJK>
0x9F51	0x6AFA	# <CJK>
0x9F52	0x6B12	# <CJK>
0x9F53	0x6B16	# <CJK>
0x9F54	0x9B31	# <CJK>
0x9F55	0x6B1F	# <CJK>
0x9F56	0x6B38	# <CJK>
0x9F57	0x6B37	# <CJK>
0x9F58	0x76DC	# <CJK>
0x9F59	0x6B39	# <CJK>
0x9F5A	0x98EE	# <CJK>
0x9F5B	0x6B47	# <CJK>
0x9F5C	0x6B43	# <CJK>
0x9F5D	0x6B49	# <CJK>
0x9F5E	0x6B50	# <CJK>
0x9F5F	0x6B59	# <CJK>
0x9F60	0x6B54	# <CJK>
0x9F61	0x6B5B	# <CJK>
0x9F62	0x6B5F	# <CJK>
0x9F63	0x6B61	# <CJK>
0x9F64	0x6B78	# <CJK>
0x9F65	0x6B79	# <CJK>
0x9F66	0x6B7F	# <CJK>
0x9F67	0x6B80	# <CJK>
0x9F68	0x6B84	# <CJK>
0x9F69	0x6B83	# <CJK>
0x9F6A	0x6B8D	# <CJK>
0x9F6B	0x6B98	# <CJK>
0x9F6C	0x6B95	# <CJK>
0x9F6D	0x6B9E	# <CJK>
0x9F6E	0x6BA4	# <CJK>
0x9F6F	0x6BAA	# <CJK>
0x9F70	0x6BAB	# <CJK>
0x9F71	0x6BAF	# <CJK>
0x9F72	0x6BB2	# <CJK>
0x9F73	0x6BB1	# <CJK>
0x9F74	0x6BB3	# <CJK>
0x9F75	0x6BB7	# <CJK>
0x9F76	0x6BBC	# <CJK>
0x9F77	0x6BC6	# <CJK>
0x9F78	0x6BCB	# <CJK>
0x9F79	0x6BD3	# <CJK>
0x9F7A	0x6BDF	# <CJK>
0x9F7B	0x6BEC	# <CJK>
0x9F7C	0x6BEB	# <CJK>
0x9F7D	0x6BF3	# <CJK>
0x9F7E	0x6BEF	# <CJK>
0x9F80	0x9EBE	# <CJK>
0x9F81	0x6C08	# <CJK>
0x9F82	0x6C13	# <CJK>
0x9F83	0x6C14	# <CJK>
0x9F84	0x6C1B	# <CJK>
0x9F85	0x6C24	# <CJK>
0x9F86	0x6C23	# <CJK>
0x9F87	0x6C5E	# <CJK>
0x9F88	0x6C55	# <CJK>
0x9F89	0x6C62	# <CJK>
0x9F8A	0x6C6A	# <CJK>
0x9F8B	0x6C82	# <CJK>
0x9F8C	0x6C8D	# <CJK>
0x9F8D	0x6C9A	# <CJK>
0x9F8E	0x6C81	# <CJK>
0x9F8F	0x6C9B	# <CJK>
0x9F90	0x6C7E	# <CJK>
0x9F91	0x6C68	# <CJK>
0x9F92	0x6C73	# <CJK>
0x9F93	0x6C92	# <CJK>
0x9F94	0x6C90	# <CJK>
0x9F95	0x6CC4	# <CJK>
0x9F96	0x6CF1	# <CJK>
0x9F97	0x6CD3	# <CJK>
0x9F98	0x6CBD	# <CJK>
0x9F99	0x6CD7	# <CJK>
0x9F9A	0x6CC5	# <CJK>
0x9F9B	0x6CDD	# <CJK>
0x9F9C	0x6CAE	# <CJK>
0x9F9D	0x6CB1	# <CJK>
0x9F9E	0x6CBE	# <CJK>
0x9F9F	0x6CBA	# <CJK>
0x9FA0	0x6CDB	# <CJK>
0x9FA1	0x6CEF	# <CJK>
0x9FA2	0x6CD9	# <CJK>
0x9FA3	0x6CEA	# <CJK>
0x9FA4	0x6D1F	# <CJK>
0x9FA5	0x884D	# <CJK>
0x9FA6	0x6D36	# <CJK>
0x9FA7	0x6D2B	# <CJK>
0x9FA8	0x6D3D	# <CJK>
0x9FA9	0x6D38	# <CJK>
0x9FAA	0x6D19	# <CJK>
0x9FAB	0x6D35	# <CJK>
0x9FAC	0x6D33	# <CJK>
0x9FAD	0x6D12	# <CJK>
0x9FAE	0x6D0C	# <CJK>
0x9FAF	0x6D63	# <CJK>
0x9FB0	0x6D93	# <CJK>
0x9FB1	0x6D64	# <CJK>
0x9FB2	0x6D5A	# <CJK>
0x9FB3	0x6D79	# <CJK>
0x9FB4	0x6D59	# <CJK>
0x9FB5	0x6D8E	# <CJK>
0x9FB6	0x6D95	# <CJK>
0x9FB7	0x6FE4	# <CJK>
0x9FB8	0x6D85	# <CJK>
0x9FB9	0x6DF9	# <CJK>
0x9FBA	0x6E15	# <CJK>
0x9FBB	0x6E0A	# <CJK>
0x9FBC	0x6DB5	# <CJK>
0x9FBD	0x6DC7	# <CJK>
0x9FBE	0x6DE6	# <CJK>
0x9FBF	0x6DB8	# <CJK>
0x9FC0	0x6DC6	# <CJK>
0x9FC1	0x6DEC	# <CJK>
0x9FC2	0x6DDE	# <CJK>
0x9FC3	0x6DCC	# <CJK>
0x9FC4	0x6DE8	# <CJK>
0x9FC5	0x6DD2	# <CJK>
0x9FC6	0x6DC5	# <CJK>
0x9FC7	0x6DFA	# <CJK>
0x9FC8	0x6DD9	# <CJK>
0x9FC9	0x6DE4	# <CJK>
0x9FCA	0x6DD5	# <CJK>
0x9FCB	0x6DEA	# <CJK>
0x9FCC	0x6DEE	# <CJK>
0x9FCD	0x6E2D	# <CJK>
0x9FCE	0x6E6E	# <CJK>
0x9FCF	0x6E2E	# <CJK>
0x9FD0	0x6E19	# <CJK>
0x9FD1	0x6E72	# <CJK>
0x9FD2	0x6E5F	# <CJK>
0x9FD3	0x6E3E	# <CJK>
0x9FD4	0x6E23	# <CJK>
0x9FD5	0x6E6B	# <CJK>
0x9FD6	0x6E2B	# <CJK>
0x9FD7	0x6E76	# <CJK>
0x9FD8	0x6E4D	# <CJK>
0x9FD9	0x6E1F	# <CJK>
0x9FDA	0x6E43	# <CJK>
0x9FDB	0x6E3A	# <CJK>
0x9FDC	0x6E4E	# <CJK>
0x9FDD	0x6E24	# <CJK>
0x9FDE	0x6EFF	# <CJK>
0x9FDF	0x6E1D	# <CJK>
0x9FE0	0x6E38	# <CJK>
0x9FE1	0x6E82	# <CJK>
0x9FE2	0x6EAA	# <CJK>
0x9FE3	0x6E98	# <CJK>
0x9FE4	0x6EC9	# <CJK>
0x9FE5	0x6EB7	# <CJK>
0x9FE6	0x6ED3	# <CJK>
0x9FE7	0x6EBD	# <CJK>
0x9FE8	0x6EAF	# <CJK>
0x9FE9	0x6EC4	# <CJK>
0x9FEA	0x6EB2	# <CJK>
0x9FEB	0x6ED4	# <CJK>
0x9FEC	0x6ED5	# <CJK>
0x9FED	0x6E8F	# <CJK>
0x9FEE	0x6EA5	# <CJK>
0x9FEF	0x6EC2	# <CJK>
0x9FF0	0x6E9F	# <CJK>
0x9FF1	0x6F41	# <CJK>
0x9FF2	0x6F11	# <CJK>
0x9FF3	0x704C	# <CJK>
0x9FF4	0x6EEC	# <CJK>
0x9FF5	0x6EF8	# <CJK>
0x9FF6	0x6EFE	# <CJK>
0x9FF7	0x6F3F	# <CJK>
0x9FF8	0x6EF2	# <CJK>
0x9FF9	0x6F31	# <CJK>
0x9FFA	0x6EEF	# <CJK>
0x9FFB	0x6F32	# <CJK>
0x9FFC	0x6ECC	# <CJK>
#
0xA0	0x00A0	# NO-BREAK SPACE # Apple extra: 1-byte halfwidth NBSP
0xA1	0xFF61	# HALFWIDTH IDEOGRAPHIC FULL STOP
0xA2	0xFF62	# HALFWIDTH LEFT CORNER BRACKET
0xA3	0xFF63	# HALFWIDTH RIGHT CORNER BRACKET
0xA4	0xFF64	# HALFWIDTH IDEOGRAPHIC COMMA
0xA5	0xFF65	# HALFWIDTH KATAKANA MIDDLE DOT
0xA6	0xFF66	# HALFWIDTH KATAKANA LETTER WO
0xA7	0xFF67	# HALFWIDTH KATAKANA LETTER SMALL A
0xA8	0xFF68	# HALFWIDTH KATAKANA LETTER SMALL I
0xA9	0xFF69	# HALFWIDTH KATAKANA LETTER SMALL U
0xAA	0xFF6A	# HALFWIDTH KATAKANA LETTER SMALL E
0xAB	0xFF6B	# HALFWIDTH KATAKANA LETTER SMALL O
0xAC	0xFF6C	# HALFWIDTH KATAKANA LETTER SMALL YA
0xAD	0xFF6D	# HALFWIDTH KATAKANA LETTER SMALL YU
0xAE	0xFF6E	# HALFWIDTH KATAKANA LETTER SMALL YO
0xAF	0xFF6F	# HALFWIDTH KATAKANA LETTER SMALL TU
0xB0	0xFF70	# HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
0xB1	0xFF71	# HALFWIDTH KATAKANA LETTER A
0xB2	0xFF72	# HALFWIDTH KATAKANA LETTER I
0xB3	0xFF73	# HALFWIDTH KATAKANA LETTER U
0xB4	0xFF74	# HALFWIDTH KATAKANA LETTER E
0xB5	0xFF75	# HALFWIDTH KATAKANA LETTER O
0xB6	0xFF76	# HALFWIDTH KATAKANA LETTER KA
0xB7	0xFF77	# HALFWIDTH KATAKANA LETTER KI
0xB8	0xFF78	# HALFWIDTH KATAKANA LETTER KU
0xB9	0xFF79	# HALFWIDTH KATAKANA LETTER KE
0xBA	0xFF7A	# HALFWIDTH KATAKANA LETTER KO
0xBB	0xFF7B	# HALFWIDTH KATAKANA LETTER SA
0xBC	0xFF7C	# HALFWIDTH KATAKANA LETTER SI
0xBD	0xFF7D	# HALFWIDTH KATAKANA LETTER SU
0xBE	0xFF7E	# HALFWIDTH KATAKANA LETTER SE
0xBF	0xFF7F	# HALFWIDTH KATAKANA LETTER SO
0xC0	0xFF80	# HALFWIDTH KATAKANA LETTER TA
0xC1	0xFF81	# HALFWIDTH KATAKANA LETTER TI
0xC2	0xFF82	# HALFWIDTH KATAKANA LETTER TU
0xC3	0xFF83	# HALFWIDTH KATAKANA LETTER TE
0xC4	0xFF84	# HALFWIDTH KATAKANA LETTER TO
0xC5	0xFF85	# HALFWIDTH KATAKANA LETTER NA
0xC6	0xFF86	# HALFWIDTH KATAKANA LETTER NI
0xC7	0xFF87	# HALFWIDTH KATAKANA LETTER NU
0xC8	0xFF88	# HALFWIDTH KATAKANA LETTER NE
0xC9	0xFF89	# HALFWIDTH KATAKANA LETTER NO
0xCA	0xFF8A	# HALFWIDTH KATAKANA LETTER HA
0xCB	0xFF8B	# HALFWIDTH KATAKANA LETTER HI
0xCC	0xFF8C	# HALFWIDTH KATAKANA LETTER HU
0xCD	0xFF8D	# HALFWIDTH KATAKANA LETTER HE
0xCE	0xFF8E	# HALFWIDTH KATAKANA LETTER HO
0xCF	0xFF8F	# HALFWIDTH KATAKANA LETTER MA
0xD0	0xFF90	# HALFWIDTH KATAKANA LETTER MI
0xD1	0xFF91	# HALFWIDTH KATAKANA LETTER MU
0xD2	0xFF92	# HALFWIDTH KATAKANA LETTER ME
0xD3	0xFF93	# HALFWIDTH KATAKANA LETTER MO
0xD4	0xFF94	# HALFWIDTH KATAKANA LETTER YA
0xD5	0xFF95	# HALFWIDTH KATAKANA LETTER YU
0xD6	0xFF96	# HALFWIDTH KATAKANA LETTER YO
0xD7	0xFF97	# HALFWIDTH KATAKANA LETTER RA
0xD8	0xFF98	# HALFWIDTH KATAKANA LETTER RI
0xD9	0xFF99	# HALFWIDTH KATAKANA LETTER RU
0xDA	0xFF9A	# HALFWIDTH KATAKANA LETTER RE
0xDB	0xFF9B	# HALFWIDTH KATAKANA LETTER RO
0xDC	0xFF9C	# HALFWIDTH KATAKANA LETTER WA
0xDD	0xFF9D	# HALFWIDTH KATAKANA LETTER N
0xDE	0xFF9E	# HALFWIDTH KATAKANA VOICED SOUND MARK
0xDF	0xFF9F	# HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
#
0xE040	0x6F3E	# <CJK>
0xE041	0x6F13	# <CJK>
0xE042	0x6EF7	# <CJK>
0xE043	0x6F86	# <CJK>
0xE044	0x6F7A	# <CJK>
0xE045	0x6F78	# <CJK>
0xE046	0x6F81	# <CJK>
0xE047	0x6F80	# <CJK>
0xE048	0x6F6F	# <CJK>
0xE049	0x6F5B	# <CJK>
0xE04A	0x6FF3	# <CJK>
0xE04B	0x6F6D	# <CJK>
0xE04C	0x6F82	# <CJK>
0xE04D	0x6F7C	# <CJK>
0xE04E	0x6F58	# <CJK>
0xE04F	0x6F8E	# <CJK>
0xE050	0x6F91	# <CJK>
0xE051	0x6FC2	# <CJK>
0xE052	0x6F66	# <CJK>
0xE053	0x6FB3	# <CJK>
0xE054	0x6FA3	# <CJK>
0xE055	0x6FA1	# <CJK>
0xE056	0x6FA4	# <CJK>
0xE057	0x6FB9	# <CJK>
0xE058	0x6FC6	# <CJK>
0xE059	0x6FAA	# <CJK>
0xE05A	0x6FDF	# <CJK>
0xE05B	0x6FD5	# <CJK>
0xE05C	0x6FEC	# <CJK>
0xE05D	0x6FD4	# <CJK>
0xE05E	0x6FD8	# <CJK>
0xE05F	0x6FF1	# <CJK>
0xE060	0x6FEE	# <CJK>
0xE061	0x6FDB	# <CJK>
0xE062	0x7009	# <CJK>
0xE063	0x700B	# <CJK>
0xE064	0x6FFA	# <CJK>
0xE065	0x7011	# <CJK>
0xE066	0x7001	# <CJK>
0xE067	0x700F	# <CJK>
0xE068	0x6FFE	# <CJK>
0xE069	0x701B	# <CJK>
0xE06A	0x701A	# <CJK>
0xE06B	0x6F74	# <CJK>
0xE06C	0x701D	# <CJK>
0xE06D	0x7018	# <CJK>
0xE06E	0x701F	# <CJK>
0xE06F	0x7030	# <CJK>
0xE070	0x703E	# <CJK>
0xE071	0x7032	# <CJK>
0xE072	0x7051	# <CJK>
0xE073	0x7063	# <CJK>
0xE074	0x7099	# <CJK>
0xE075	0x7092	# <CJK>
0xE076	0x70AF	# <CJK>
0xE077	0x70F1	# <CJK>
0xE078	0x70AC	# <CJK>
0xE079	0x70B8	# <CJK>
0xE07A	0x70B3	# <CJK>
0xE07B	0x70AE	# <CJK>
0xE07C	0x70DF	# <CJK>
0xE07D	0x70CB	# <CJK>
0xE07E	0x70DD	# <CJK>
0xE080	0x70D9	# <CJK>
0xE081	0x7109	# <CJK>
0xE082	0x70FD	# <CJK>
0xE083	0x711C	# <CJK>
0xE084	0x7119	# <CJK>
0xE085	0x7165	# <CJK>
0xE086	0x7155	# <CJK>
0xE087	0x7188	# <CJK>
0xE088	0x7166	# <CJK>
0xE089	0x7162	# <CJK>
0xE08A	0x714C	# <CJK>
0xE08B	0x7156	# <CJK>
0xE08C	0x716C	# <CJK>
0xE08D	0x718F	# <CJK>
0xE08E	0x71FB	# <CJK>
0xE08F	0x7184	# <CJK>
0xE090	0x7195	# <CJK>
0xE091	0x71A8	# <CJK>
0xE092	0x71AC	# <CJK>
0xE093	0x71D7	# <CJK>
0xE094	0x71B9	# <CJK>
0xE095	0x71BE	# <CJK>
0xE096	0x71D2	# <CJK>
0xE097	0x71C9	# <CJK>
0xE098	0x71D4	# <CJK>
0xE099	0x71CE	# <CJK>
0xE09A	0x71E0	# <CJK>
0xE09B	0x71EC	# <CJK>
0xE09C	0x71E7	# <CJK>
0xE09D	0x71F5	# <CJK>
0xE09E	0x71FC	# <CJK>
0xE09F	0x71F9	# <CJK>
0xE0A0	0x71FF	# <CJK>
0xE0A1	0x720D	# <CJK>
0xE0A2	0x7210	# <CJK>
0xE0A3	0x721B	# <CJK>
0xE0A4	0x7228	# <CJK>
0xE0A5	0x722D	# <CJK>
0xE0A6	0x722C	# <CJK>
0xE0A7	0x7230	# <CJK>
0xE0A8	0x7232	# <CJK>
0xE0A9	0x723B	# <CJK>
0xE0AA	0x723C	# <CJK>
0xE0AB	0x723F	# <CJK>
0xE0AC	0x7240	# <CJK>
0xE0AD	0x7246	# <CJK>
0xE0AE	0x724B	# <CJK>
0xE0AF	0x7258	# <CJK>
0xE0B0	0x7274	# <CJK>
0xE0B1	0x727E	# <CJK>
0xE0B2	0x7282	# <CJK>
0xE0B3	0x7281	# <CJK>
0xE0B4	0x7287	# <CJK>
0xE0B5	0x7292	# <CJK>
0xE0B6	0x7296	# <CJK>
0xE0B7	0x72A2	# <CJK>
0xE0B8	0x72A7	# <CJK>
0xE0B9	0x72B9	# <CJK>
0xE0BA	0x72B2	# <CJK>
0xE0BB	0x72C3	# <CJK>
0xE0BC	0x72C6	# <CJK>
0xE0BD	0x72C4	# <CJK>
0xE0BE	0x72CE	# <CJK>
0xE0BF	0x72D2	# <CJK>
0xE0C0	0x72E2	# <CJK>
0xE0C1	0x72E0	# <CJK>
0xE0C2	0x72E1	# <CJK>
0xE0C3	0x72F9	# <CJK>
0xE0C4	0x72F7	# <CJK>
0xE0C5	0x500F	# <CJK>
0xE0C6	0x7317	# <CJK>
0xE0C7	0x730A	# <CJK>
0xE0C8	0x731C	# <CJK>
0xE0C9	0x7316	# <CJK>
0xE0CA	0x731D	# <CJK>
0xE0CB	0x7334	# <CJK>
0xE0CC	0x732F	# <CJK>
0xE0CD	0x7329	# <CJK>
0xE0CE	0x7325	# <CJK>
0xE0CF	0x733E	# <CJK>
0xE0D0	0x734E	# <CJK>
0xE0D1	0x734F	# <CJK>
0xE0D2	0x9ED8	# <CJK>
0xE0D3	0x7357	# <CJK>
0xE0D4	0x736A	# <CJK>
0xE0D5	0x7368	# <CJK>
0xE0D6	0x7370	# <CJK>
0xE0D7	0x7378	# <CJK>
0xE0D8	0x7375	# <CJK>
0xE0D9	0x737B	# <CJK>
0xE0DA	0x737A	# <CJK>
0xE0DB	0x73C8	# <CJK>
0xE0DC	0x73B3	# <CJK>
0xE0DD	0x73CE	# <CJK>
0xE0DE	0x73BB	# <CJK>
0xE0DF	0x73C0	# <CJK>
0xE0E0	0x73E5	# <CJK>
0xE0E1	0x73EE	# <CJK>
0xE0E2	0x73DE	# <CJK>
0xE0E3	0x74A2	# <CJK>
0xE0E4	0x7405	# <CJK>
0xE0E5	0x746F	# <CJK>
0xE0E6	0x7425	# <CJK>
0xE0E7	0x73F8	# <CJK>
0xE0E8	0x7432	# <CJK>
0xE0E9	0x743A	# <CJK>
0xE0EA	0x7455	# <CJK>
0xE0EB	0x743F	# <CJK>
0xE0EC	0x745F	# <CJK>
0xE0ED	0x7459	# <CJK>
0xE0EE	0x7441	# <CJK>
0xE0EF	0x745C	# <CJK>
0xE0F0	0x7469	# <CJK>
0xE0F1	0x7470	# <CJK>
0xE0F2	0x7463	# <CJK>
0xE0F3	0x746A	# <CJK>
0xE0F4	0x7476	# <CJK>
0xE0F5	0x747E	# <CJK>
0xE0F6	0x748B	# <CJK>
0xE0F7	0x749E	# <CJK>
0xE0F8	0x74A7	# <CJK>
0xE0F9	0x74CA	# <CJK>
0xE0FA	0x74CF	# <CJK>
0xE0FB	0x74D4	# <CJK>
0xE0FC	0x73F1	# <CJK>
0xE140	0x74E0	# <CJK>
0xE141	0x74E3	# <CJK>
0xE142	0x74E7	# <CJK>
0xE143	0x74E9	# <CJK>
0xE144	0x74EE	# <CJK>
0xE145	0x74F2	# <CJK>
0xE146	0x74F0	# <CJK>
0xE147	0x74F1	# <CJK>
0xE148	0x74F8	# <CJK>
0xE149	0x74F7	# <CJK>
0xE14A	0x7504	# <CJK>
0xE14B	0x7503	# <CJK>
0xE14C	0x7505	# <CJK>
0xE14D	0x750C	# <CJK>
0xE14E	0x750E	# <CJK>
0xE14F	0x750D	# <CJK>
0xE150	0x7515	# <CJK>
0xE151	0x7513	# <CJK>
0xE152	0x751E	# <CJK>
0xE153	0x7526	# <CJK>
0xE154	0x752C	# <CJK>
0xE155	0x753C	# <CJK>
0xE156	0x7544	# <CJK>
0xE157	0x754D	# <CJK>
0xE158	0x754A	# <CJK>
0xE159	0x7549	# <CJK>
0xE15A	0x755B	# <CJK>
0xE15B	0x7546	# <CJK>
0xE15C	0x755A	# <CJK>
0xE15D	0x7569	# <CJK>
0xE15E	0x7564	# <CJK>
0xE15F	0x7567	# <CJK>
0xE160	0x756B	# <CJK>
0xE161	0x756D	# <CJK>
0xE162	0x7578	# <CJK>
0xE163	0x7576	# <CJK>
0xE164	0x7586	# <CJK>
0xE165	0x7587	# <CJK>
0xE166	0x7574	# <CJK>
0xE167	0x758A	# <CJK>
0xE168	0x7589	# <CJK>
0xE169	0x7582	# <CJK>
0xE16A	0x7594	# <CJK>
0xE16B	0x759A	# <CJK>
0xE16C	0x759D	# <CJK>
0xE16D	0x75A5	# <CJK>
0xE16E	0x75A3	# <CJK>
0xE16F	0x75C2	# <CJK>
0xE170	0x75B3	# <CJK>
0xE171	0x75C3	# <CJK>
0xE172	0x75B5	# <CJK>
0xE173	0x75BD	# <CJK>
0xE174	0x75B8	# <CJK>
0xE175	0x75BC	# <CJK>
0xE176	0x75B1	# <CJK>
0xE177	0x75CD	# <CJK>
0xE178	0x75CA	# <CJK>
0xE179	0x75D2	# <CJK>
0xE17A	0x75D9	# <CJK>
0xE17B	0x75E3	# <CJK>
0xE17C	0x75DE	# <CJK>
0xE17D	0x75FE	# <CJK>
0xE17E	0x75FF	# <CJK>
0xE180	0x75FC	# <CJK>
0xE181	0x7601	# <CJK>
0xE182	0x75F0	# <CJK>
0xE183	0x75FA	# <CJK>
0xE184	0x75F2	# <CJK>
0xE185	0x75F3	# <CJK>
0xE186	0x760B	# <CJK>
0xE187	0x760D	# <CJK>
0xE188	0x7609	# <CJK>
0xE189	0x761F	# <CJK>
0xE18A	0x7627	# <CJK>
0xE18B	0x7620	# <CJK>
0xE18C	0x7621	# <CJK>
0xE18D	0x7622	# <CJK>
0xE18E	0x7624	# <CJK>
0xE18F	0x7634	# <CJK>
0xE190	0x7630	# <CJK>
0xE191	0x763B	# <CJK>
0xE192	0x7647	# <CJK>
0xE193	0x7648	# <CJK>
0xE194	0x7646	# <CJK>
0xE195	0x765C	# <CJK>
0xE196	0x7658	# <CJK>
0xE197	0x7661	# <CJK>
0xE198	0x7662	# <CJK>
0xE199	0x7668	# <CJK>
0xE19A	0x7669	# <CJK>
0xE19B	0x766A	# <CJK>
0xE19C	0x7667	# <CJK>
0xE19D	0x766C	# <CJK>
0xE19E	0x7670	# <CJK>
0xE19F	0x7672	# <CJK>
0xE1A0	0x7676	# <CJK>
0xE1A1	0x7678	# <CJK>
0xE1A2	0x767C	# <CJK>
0xE1A3	0x7680	# <CJK>
0xE1A4	0x7683	# <CJK>
0xE1A5	0x7688	# <CJK>
0xE1A6	0x768B	# <CJK>
0xE1A7	0x768E	# <CJK>
0xE1A8	0x7696	# <CJK>
0xE1A9	0x7693	# <CJK>
0xE1AA	0x7699	# <CJK>
0xE1AB	0x769A	# <CJK>
0xE1AC	0x76B0	# <CJK>
0xE1AD	0x76B4	# <CJK>
0xE1AE	0x76B8	# <CJK>
0xE1AF	0x76B9	# <CJK>
0xE1B0	0x76BA	# <CJK>
0xE1B1	0x76C2	# <CJK>
0xE1B2	0x76CD	# <CJK>
0xE1B3	0x76D6	# <CJK>
0xE1B4	0x76D2	# <CJK>
0xE1B5	0x76DE	# <CJK>
0xE1B6	0x76E1	# <CJK>
0xE1B7	0x76E5	# <CJK>
0xE1B8	0x76E7	# <CJK>
0xE1B9	0x76EA	# <CJK>
0xE1BA	0x862F	# <CJK>
0xE1BB	0x76FB	# <CJK>
0xE1BC	0x7708	# <CJK>
0xE1BD	0x7707	# <CJK>
0xE1BE	0x7704	# <CJK>
0xE1BF	0x7729	# <CJK>
0xE1C0	0x7724	# <CJK>
0xE1C1	0x771E	# <CJK>
0xE1C2	0x7725	# <CJK>
0xE1C3	0x7726	# <CJK>
0xE1C4	0x771B	# <CJK>
0xE1C5	0x7737	# <CJK>
0xE1C6	0x7738	# <CJK>
0xE1C7	0x7747	# <CJK>
0xE1C8	0x775A	# <CJK>
0xE1C9	0x7768	# <CJK>
0xE1CA	0x776B	# <CJK>
0xE1CB	0x775B	# <CJK>
0xE1CC	0x7765	# <CJK>
0xE1CD	0x777F	# <CJK>
0xE1CE	0x777E	# <CJK>
0xE1CF	0x7779	# <CJK>
0xE1D0	0x778E	# <CJK>
0xE1D1	0x778B	# <CJK>
0xE1D2	0x7791	# <CJK>
0xE1D3	0x77A0	# <CJK>
0xE1D4	0x779E	# <CJK>
0xE1D5	0x77B0	# <CJK>
0xE1D6	0x77B6	# <CJK>
0xE1D7	0x77B9	# <CJK>
0xE1D8	0x77BF	# <CJK>
0xE1D9	0x77BC	# <CJK>
0xE1DA	0x77BD	# <CJK>
0xE1DB	0x77BB	# <CJK>
0xE1DC	0x77C7	# <CJK>
0xE1DD	0x77CD	# <CJK>
0xE1DE	0x77D7	# <CJK>
0xE1DF	0x77DA	# <CJK>
0xE1E0	0x77DC	# <CJK>
0xE1E1	0x77E3	# <CJK>
0xE1E2	0x77EE	# <CJK>
0xE1E3	0x77FC	# <CJK>
0xE1E4	0x780C	# <CJK>
0xE1E5	0x7812	# <CJK>
0xE1E6	0x7926	# <CJK>
0xE1E7	0x7820	# <CJK>
0xE1E8	0x792A	# <CJK>
0xE1E9	0x7845	# <CJK>
0xE1EA	0x788E	# <CJK>
0xE1EB	0x7874	# <CJK>
0xE1EC	0x7886	# <CJK>
0xE1ED	0x787C	# <CJK>
0xE1EE	0x789A	# <CJK>
0xE1EF	0x788C	# <CJK>
0xE1F0	0x78A3	# <CJK>
0xE1F1	0x78B5	# <CJK>
0xE1F2	0x78AA	# <CJK>
0xE1F3	0x78AF	# <CJK>
0xE1F4	0x78D1	# <CJK>
0xE1F5	0x78C6	# <CJK>
0xE1F6	0x78CB	# <CJK>
0xE1F7	0x78D4	# <CJK>
0xE1F8	0x78BE	# <CJK>
0xE1F9	0x78BC	# <CJK>
0xE1FA	0x78C5	# <CJK>
0xE1FB	0x78CA	# <CJK>
0xE1FC	0x78EC	# <CJK>
0xE240	0x78E7	# <CJK>
0xE241	0x78DA	# <CJK>
0xE242	0x78FD	# <CJK>
0xE243	0x78F4	# <CJK>
0xE244	0x7907	# <CJK>
0xE245	0x7912	# <CJK>
0xE246	0x7911	# <CJK>
0xE247	0x7919	# <CJK>
0xE248	0x792C	# <CJK>
0xE249	0x792B	# <CJK>
0xE24A	0x7940	# <CJK>
0xE24B	0x7960	# <CJK>
0xE24C	0x7957	# <CJK>
0xE24D	0x795F	# <CJK>
0xE24E	0x795A	# <CJK>
0xE24F	0x7955	# <CJK>
0xE250	0x7953	# <CJK>
0xE251	0x797A	# <CJK>
0xE252	0x797F	# <CJK>
0xE253	0x798A	# <CJK>
0xE254	0x799D	# <CJK>
0xE255	0x79A7	# <CJK>
0xE256	0x9F4B	# <CJK>
0xE257	0x79AA	# <CJK>
0xE258	0x79AE	# <CJK>
0xE259	0x79B3	# <CJK>
0xE25A	0x79B9	# <CJK>
0xE25B	0x79BA	# <CJK>
0xE25C	0x79C9	# <CJK>
0xE25D	0x79D5	# <CJK>
0xE25E	0x79E7	# <CJK>
0xE25F	0x79EC	# <CJK>
0xE260	0x79E1	# <CJK>
0xE261	0x79E3	# <CJK>
0xE262	0x7A08	# <CJK>
0xE263	0x7A0D	# <CJK>
0xE264	0x7A18	# <CJK>
0xE265	0x7A19	# <CJK>
0xE266	0x7A20	# <CJK>
0xE267	0x7A1F	# <CJK>
0xE268	0x7980	# <CJK>
0xE269	0x7A31	# <CJK>
0xE26A	0x7A3B	# <CJK>
0xE26B	0x7A3E	# <CJK>
0xE26C	0x7A37	# <CJK>
0xE26D	0x7A43	# <CJK>
0xE26E	0x7A57	# <CJK>
0xE26F	0x7A49	# <CJK>
0xE270	0x7A61	# <CJK>
0xE271	0x7A62	# <CJK>
0xE272	0x7A69	# <CJK>
0xE273	0x9F9D	# <CJK>
0xE274	0x7A70	# <CJK>
0xE275	0x7A79	# <CJK>
0xE276	0x7A7D	# <CJK>
0xE277	0x7A88	# <CJK>
0xE278	0x7A97	# <CJK>
0xE279	0x7A95	# <CJK>
0xE27A	0x7A98	# <CJK>
0xE27B	0x7A96	# <CJK>
0xE27C	0x7AA9	# <CJK>
0xE27D	0x7AC8	# <CJK>
0xE27E	0x7AB0	# <CJK>
0xE280	0x7AB6	# <CJK>
0xE281	0x7AC5	# <CJK>
0xE282	0x7AC4	# <CJK>
0xE283	0x7ABF	# <CJK>
0xE284	0x9083	# <CJK>
0xE285	0x7AC7	# <CJK>
0xE286	0x7ACA	# <CJK>
0xE287	0x7ACD	# <CJK>
0xE288	0x7ACF	# <CJK>
0xE289	0x7AD5	# <CJK>
0xE28A	0x7AD3	# <CJK>
0xE28B	0x7AD9	# <CJK>
0xE28C	0x7ADA	# <CJK>
0xE28D	0x7ADD	# <CJK>
0xE28E	0x7AE1	# <CJK>
0xE28F	0x7AE2	# <CJK>
0xE290	0x7AE6	# <CJK>
0xE291	0x7AED	# <CJK>
0xE292	0x7AF0	# <CJK>
0xE293	0x7B02	# <CJK>
0xE294	0x7B0F	# <CJK>
0xE295	0x7B0A	# <CJK>
0xE296	0x7B06	# <CJK>
0xE297	0x7B33	# <CJK>
0xE298	0x7B18	# <CJK>
0xE299	0x7B19	# <CJK>
0xE29A	0x7B1E	# <CJK>
0xE29B	0x7B35	# <CJK>
0xE29C	0x7B28	# <CJK>
0xE29D	0x7B36	# <CJK>
0xE29E	0x7B50	# <CJK>
0xE29F	0x7B7A	# <CJK>
0xE2A0	0x7B04	# <CJK>
0xE2A1	0x7B4D	# <CJK>
0xE2A2	0x7B0B	# <CJK>
0xE2A3	0x7B4C	# <CJK>
0xE2A4	0x7B45	# <CJK>
0xE2A5	0x7B75	# <CJK>
0xE2A6	0x7B65	# <CJK>
0xE2A7	0x7B74	# <CJK>
0xE2A8	0x7B67	# <CJK>
0xE2A9	0x7B70	# <CJK>
0xE2AA	0x7B71	# <CJK>
0xE2AB	0x7B6C	# <CJK>
0xE2AC	0x7B6E	# <CJK>
0xE2AD	0x7B9D	# <CJK>
0xE2AE	0x7B98	# <CJK>
0xE2AF	0x7B9F	# <CJK>
0xE2B0	0x7B8D	# <CJK>
0xE2B1	0x7B9C	# <CJK>
0xE2B2	0x7B9A	# <CJK>
0xE2B3	0x7B8B	# <CJK>
0xE2B4	0x7B92	# <CJK>
0xE2B5	0x7B8F	# <CJK>
0xE2B6	0x7B5D	# <CJK>
0xE2B7	0x7B99	# <CJK>
0xE2B8	0x7BCB	# <CJK>
0xE2B9	0x7BC1	# <CJK>
0xE2BA	0x7BCC	# <CJK>
0xE2BB	0x7BCF	# <CJK>
0xE2BC	0x7BB4	# <CJK>
0xE2BD	0x7BC6	# <CJK>
0xE2BE	0x7BDD	# <CJK>
0xE2BF	0x7BE9	# <CJK>
0xE2C0	0x7C11	# <CJK>
0xE2C1	0x7C14	# <CJK>
0xE2C2	0x7BE6	# <CJK>
0xE2C3	0x7BE5	# <CJK>
0xE2C4	0x7C60	# <CJK>
0xE2C5	0x7C00	# <CJK>
0xE2C6	0x7C07	# <CJK>
0xE2C7	0x7C13	# <CJK>
0xE2C8	0x7BF3	# <CJK>
0xE2C9	0x7BF7	# <CJK>
0xE2CA	0x7C17	# <CJK>
0xE2CB	0x7C0D	# <CJK>
0xE2CC	0x7BF6	# <CJK>
0xE2CD	0x7C23	# <CJK>
0xE2CE	0x7C27	# <CJK>
0xE2CF	0x7C2A	# <CJK>
0xE2D0	0x7C1F	# <CJK>
0xE2D1	0x7C37	# <CJK>
0xE2D2	0x7C2B	# <CJK>
0xE2D3	0x7C3D	# <CJK>
0xE2D4	0x7C4C	# <CJK>
0xE2D5	0x7C43	# <CJK>
0xE2D6	0x7C54	# <CJK>
0xE2D7	0x7C4F	# <CJK>
0xE2D8	0x7C40	# <CJK>
0xE2D9	0x7C50	# <CJK>
0xE2DA	0x7C58	# <CJK>
0xE2DB	0x7C5F	# <CJK>
0xE2DC	0x7C64	# <CJK>
0xE2DD	0x7C56	# <CJK>
0xE2DE	0x7C65	# <CJK>
0xE2DF	0x7C6C	# <CJK>
0xE2E0	0x7C75	# <CJK>
0xE2E1	0x7C83	# <CJK>
0xE2E2	0x7C90	# <CJK>
0xE2E3	0x7CA4	# <CJK>
0xE2E4	0x7CAD	# <CJK>
0xE2E5	0x7CA2	# <CJK>
0xE2E6	0x7CAB	# <CJK>
0xE2E7	0x7CA1	# <CJK>
0xE2E8	0x7CA8	# <CJK>
0xE2E9	0x7CB3	# <CJK>
0xE2EA	0x7CB2	# <CJK>
0xE2EB	0x7CB1	# <CJK>
0xE2EC	0x7CAE	# <CJK>
0xE2ED	0x7CB9	# <CJK>
0xE2EE	0x7CBD	# <CJK>
0xE2EF	0x7CC0	# <CJK>
0xE2F0	0x7CC5	# <CJK>
0xE2F1	0x7CC2	# <CJK>
0xE2F2	0x7CD8	# <CJK>
0xE2F3	0x7CD2	# <CJK>
0xE2F4	0x7CDC	# <CJK>
0xE2F5	0x7CE2	# <CJK>
0xE2F6	0x9B3B	# <CJK>
0xE2F7	0x7CEF	# <CJK>
0xE2F8	0x7CF2	# <CJK>
0xE2F9	0x7CF4	# <CJK>
0xE2FA	0x7CF6	# <CJK>
0xE2FB	0x7CFA	# <CJK>
0xE2FC	0x7D06	# <CJK>
0xE340	0x7D02	# <CJK>
0xE341	0x7D1C	# <CJK>
0xE342	0x7D15	# <CJK>
0xE343	0x7D0A	# <CJK>
0xE344	0x7D45	# <CJK>
0xE345	0x7D4B	# <CJK>
0xE346	0x7D2E	# <CJK>
0xE347	0x7D32	# <CJK>
0xE348	0x7D3F	# <CJK>
0xE349	0x7D35	# <CJK>
0xE34A	0x7D46	# <CJK>
0xE34B	0x7D73	# <CJK>
0xE34C	0x7D56	# <CJK>
0xE34D	0x7D4E	# <CJK>
0xE34E	0x7D72	# <CJK>
0xE34F	0x7D68	# <CJK>
0xE350	0x7D6E	# <CJK>
0xE351	0x7D4F	# <CJK>
0xE352	0x7D63	# <CJK>
0xE353	0x7D93	# <CJK>
0xE354	0x7D89	# <CJK>
0xE355	0x7D5B	# <CJK>
0xE356	0x7D8F	# <CJK>
0xE357	0x7D7D	# <CJK>
0xE358	0x7D9B	# <CJK>
0xE359	0x7DBA	# <CJK>
0xE35A	0x7DAE	# <CJK>
0xE35B	0x7DA3	# <CJK>
0xE35C	0x7DB5	# <CJK>
0xE35D	0x7DC7	# <CJK>
0xE35E	0x7DBD	# <CJK>
0xE35F	0x7DAB	# <CJK>
0xE360	0x7E3D	# <CJK>
0xE361	0x7DA2	# <CJK>
0xE362	0x7DAF	# <CJK>
0xE363	0x7DDC	# <CJK>
0xE364	0x7DB8	# <CJK>
0xE365	0x7D9F	# <CJK>
0xE366	0x7DB0	# <CJK>
0xE367	0x7DD8	# <CJK>
0xE368	0x7DDD	# <CJK>
0xE369	0x7DE4	# <CJK>
0xE36A	0x7DDE	# <CJK>
0xE36B	0x7DFB	# <CJK>
0xE36C	0x7DF2	# <CJK>
0xE36D	0x7DE1	# <CJK>
0xE36E	0x7E05	# <CJK>
0xE36F	0x7E0A	# <CJK>
0xE370	0x7E23	# <CJK>
0xE371	0x7E21	# <CJK>
0xE372	0x7E12	# <CJK>
0xE373	0x7E31	# <CJK>
0xE374	0x7E1F	# <CJK>
0xE375	0x7E09	# <CJK>
0xE376	0x7E0B	# <CJK>
0xE377	0x7E22	# <CJK>
0xE378	0x7E46	# <CJK>
0xE379	0x7E66	# <CJK>
0xE37A	0x7E3B	# <CJK>
0xE37B	0x7E35	# <CJK>
0xE37C	0x7E39	# <CJK>
0xE37D	0x7E43	# <CJK>
0xE37E	0x7E37	# <CJK>
0xE380	0x7E32	# <CJK>
0xE381	0x7E3A	# <CJK>
0xE382	0x7E67	# <CJK>
0xE383	0x7E5D	# <CJK>
0xE384	0x7E56	# <CJK>
0xE385	0x7E5E	# <CJK>
0xE386	0x7E59	# <CJK>
0xE387	0x7E5A	# <CJK>
0xE388	0x7E79	# <CJK>
0xE389	0x7E6A	# <CJK>
0xE38A	0x7E69	# <CJK>
0xE38B	0x7E7C	# <CJK>
0xE38C	0x7E7B	# <CJK>
0xE38D	0x7E83	# <CJK>
0xE38E	0x7DD5	# <CJK>
0xE38F	0x7E7D	# <CJK>
0xE390	0x8FAE	# <CJK>
0xE391	0x7E7F	# <CJK>
0xE392	0x7E88	# <CJK>
0xE393	0x7E89	# <CJK>
0xE394	0x7E8C	# <CJK>
0xE395	0x7E92	# <CJK>
0xE396	0x7E90	# <CJK>
0xE397	0x7E93	# <CJK>
0xE398	0x7E94	# <CJK>
0xE399	0x7E96	# <CJK>
0xE39A	0x7E8E	# <CJK>
0xE39B	0x7E9B	# <CJK>
0xE39C	0x7E9C	# <CJK>
0xE39D	0x7F38	# <CJK>
0xE39E	0x7F3A	# <CJK>
0xE39F	0x7F45	# <CJK>
0xE3A0	0x7F4C	# <CJK>
0xE3A1	0x7F4D	# <CJK>
0xE3A2	0x7F4E	# <CJK>
0xE3A3	0x7F50	# <CJK>
0xE3A4	0x7F51	# <CJK>
0xE3A5	0x7F55	# <CJK>
0xE3A6	0x7F54	# <CJK>
0xE3A7	0x7F58	# <CJK>
0xE3A8	0x7F5F	# <CJK>
0xE3A9	0x7F60	# <CJK>
0xE3AA	0x7F68	# <CJK>
0xE3AB	0x7F69	# <CJK>
0xE3AC	0x7F67	# <CJK>
0xE3AD	0x7F78	# <CJK>
0xE3AE	0x7F82	# <CJK>
0xE3AF	0x7F86	# <CJK>
0xE3B0	0x7F83	# <CJK>
0xE3B1	0x7F88	# <CJK>
0xE3B2	0x7F87	# <CJK>
0xE3B3	0x7F8C	# <CJK>
0xE3B4	0x7F94	# <CJK>
0xE3B5	0x7F9E	# <CJK>
0xE3B6	0x7F9D	# <CJK>
0xE3B7	0x7F9A	# <CJK>
0xE3B8	0x7FA3	# <CJK>
0xE3B9	0x7FAF	# <CJK>
0xE3BA	0x7FB2	# <CJK>
0xE3BB	0x7FB9	# <CJK>
0xE3BC	0x7FAE	# <CJK>
0xE3BD	0x7FB6	# <CJK>
0xE3BE	0x7FB8	# <CJK>
0xE3BF	0x8B71	# <CJK>
0xE3C0	0x7FC5	# <CJK>
0xE3C1	0x7FC6	# <CJK>
0xE3C2	0x7FCA	# <CJK>
0xE3C3	0x7FD5	# <CJK>
0xE3C4	0x7FD4	# <CJK>
0xE3C5	0x7FE1	# <CJK>
0xE3C6	0x7FE6	# <CJK>
0xE3C7	0x7FE9	# <CJK>
0xE3C8	0x7FF3	# <CJK>
0xE3C9	0x7FF9	# <CJK>
0xE3CA	0x98DC	# <CJK>
0xE3CB	0x8006	# <CJK>
0xE3CC	0x8004	# <CJK>
0xE3CD	0x800B	# <CJK>
0xE3CE	0x8012	# <CJK>
0xE3CF	0x8018	# <CJK>
0xE3D0	0x8019	# <CJK>
0xE3D1	0x801C	# <CJK>
0xE3D2	0x8021	# <CJK>
0xE3D3	0x8028	# <CJK>
0xE3D4	0x803F	# <CJK>
0xE3D5	0x803B	# <CJK>
0xE3D6	0x804A	# <CJK>
0xE3D7	0x8046	# <CJK>
0xE3D8	0x8052	# <CJK>
0xE3D9	0x8058	# <CJK>
0xE3DA	0x805A	# <CJK>
0xE3DB	0x805F	# <CJK>
0xE3DC	0x8062	# <CJK>
0xE3DD	0x8068	# <CJK>
0xE3DE	0x8073	# <CJK>
0xE3DF	0x8072	# <CJK>
0xE3E0	0x8070	# <CJK>
0xE3E1	0x8076	# <CJK>
0xE3E2	0x8079	# <CJK>
0xE3E3	0x807D	# <CJK>
0xE3E4	0x807F	# <CJK>
0xE3E5	0x8084	# <CJK>
0xE3E6	0x8086	# <CJK>
0xE3E7	0x8085	# <CJK>
0xE3E8	0x809B	# <CJK>
0xE3E9	0x8093	# <CJK>
0xE3EA	0x809A	# <CJK>
0xE3EB	0x80AD	# <CJK>
0xE3EC	0x5190	# <CJK>
0xE3ED	0x80AC	# <CJK>
0xE3EE	0x80DB	# <CJK>
0xE3EF	0x80E5	# <CJK>
0xE3F0	0x80D9	# <CJK>
0xE3F1	0x80DD	# <CJK>
0xE3F2	0x80C4	# <CJK>
0xE3F3	0x80DA	# <CJK>
0xE3F4	0x80D6	# <CJK>
0xE3F5	0x8109	# <CJK>
0xE3F6	0x80EF	# <CJK>
0xE3F7	0x80F1	# <CJK>
0xE3F8	0x811B	# <CJK>
0xE3F9	0x8129	# <CJK>
0xE3FA	0x8123	# <CJK>
0xE3FB	0x812F	# <CJK>
0xE3FC	0x814B	# <CJK>
0xE440	0x968B	# <CJK>
0xE441	0x8146	# <CJK>
0xE442	0x813E	# <CJK>
0xE443	0x8153	# <CJK>
0xE444	0x8151	# <CJK>
0xE445	0x80FC	# <CJK>
0xE446	0x8171	# <CJK>
0xE447	0x816E	# <CJK>
0xE448	0x8165	# <CJK>
0xE449	0x8166	# <CJK>
0xE44A	0x8174	# <CJK>
0xE44B	0x8183	# <CJK>
0xE44C	0x8188	# <CJK>
0xE44D	0x818A	# <CJK>
0xE44E	0x8180	# <CJK>
0xE44F	0x8182	# <CJK>
0xE450	0x81A0	# <CJK>
0xE451	0x8195	# <CJK>
0xE452	0x81A4	# <CJK>
0xE453	0x81A3	# <CJK>
0xE454	0x815F	# <CJK>
0xE455	0x8193	# <CJK>
0xE456	0x81A9	# <CJK>
0xE457	0x81B0	# <CJK>
0xE458	0x81B5	# <CJK>
0xE459	0x81BE	# <CJK>
0xE45A	0x81B8	# <CJK>
0xE45B	0x81BD	# <CJK>
0xE45C	0x81C0	# <CJK>
0xE45D	0x81C2	# <CJK>
0xE45E	0x81BA	# <CJK>
0xE45F	0x81C9	# <CJK>
0xE460	0x81CD	# <CJK>
0xE461	0x81D1	# <CJK>
0xE462	0x81D9	# <CJK>
0xE463	0x81D8	# <CJK>
0xE464	0x81C8	# <CJK>
0xE465	0x81DA	# <CJK>
0xE466	0x81DF	# <CJK>
0xE467	0x81E0	# <CJK>
0xE468	0x81E7	# <CJK>
0xE469	0x81FA	# <CJK>
0xE46A	0x81FB	# <CJK>
0xE46B	0x81FE	# <CJK>
0xE46C	0x8201	# <CJK>
0xE46D	0x8202	# <CJK>
0xE46E	0x8205	# <CJK>
0xE46F	0x8207	# <CJK>
0xE470	0x820A	# <CJK>
0xE471	0x820D	# <CJK>
0xE472	0x8210	# <CJK>
0xE473	0x8216	# <CJK>
0xE474	0x8229	# <CJK>
0xE475	0x822B	# <CJK>
0xE476	0x8238	# <CJK>
0xE477	0x8233	# <CJK>
0xE478	0x8240	# <CJK>
0xE479	0x8259	# <CJK>
0xE47A	0x8258	# <CJK>
0xE47B	0x825D	# <CJK>
0xE47C	0x825A	# <CJK>
0xE47D	0x825F	# <CJK>
0xE47E	0x8264	# <CJK>
0xE480	0x8262	# <CJK>
0xE481	0x8268	# <CJK>
0xE482	0x826A	# <CJK>
0xE483	0x826B	# <CJK>
0xE484	0x822E	# <CJK>
0xE485	0x8271	# <CJK>
0xE486	0x8277	# <CJK>
0xE487	0x8278	# <CJK>
0xE488	0x827E	# <CJK>
0xE489	0x828D	# <CJK>
0xE48A	0x8292	# <CJK>
0xE48B	0x82AB	# <CJK>
0xE48C	0x829F	# <CJK>
0xE48D	0x82BB	# <CJK>
0xE48E	0x82AC	# <CJK>
0xE48F	0x82E1	# <CJK>
0xE490	0x82E3	# <CJK>
0xE491	0x82DF	# <CJK>
0xE492	0x82D2	# <CJK>
0xE493	0x82F4	# <CJK>
0xE494	0x82F3	# <CJK>
0xE495	0x82FA	# <CJK>
0xE496	0x8393	# <CJK>
0xE497	0x8303	# <CJK>
0xE498	0x82FB	# <CJK>
0xE499	0x82F9	# <CJK>
0xE49A	0x82DE	# <CJK>
0xE49B	0x8306	# <CJK>
0xE49C	0x82DC	# <CJK>
0xE49D	0x8309	# <CJK>
0xE49E	0x82D9	# <CJK>
0xE49F	0x8335	# <CJK>
0xE4A0	0x8334	# <CJK>
0xE4A1	0x8316	# <CJK>
0xE4A2	0x8332	# <CJK>
0xE4A3	0x8331	# <CJK>
0xE4A4	0x8340	# <CJK>
0xE4A5	0x8339	# <CJK>
0xE4A6	0x8350	# <CJK>
0xE4A7	0x8345	# <CJK>
0xE4A8	0x832F	# <CJK>
0xE4A9	0x832B	# <CJK>
0xE4AA	0x8317	# <CJK>
0xE4AB	0x8318	# <CJK>
0xE4AC	0x8385	# <CJK>
0xE4AD	0x839A	# <CJK>
0xE4AE	0x83AA	# <CJK>
0xE4AF	0x839F	# <CJK>
0xE4B0	0x83A2	# <CJK>
0xE4B1	0x8396	# <CJK>
0xE4B2	0x8323	# <CJK>
0xE4B3	0x838E	# <CJK>
0xE4B4	0x8387	# <CJK>
0xE4B5	0x838A	# <CJK>
0xE4B6	0x837C	# <CJK>
0xE4B7	0x83B5	# <CJK>
0xE4B8	0x8373	# <CJK>
0xE4B9	0x8375	# <CJK>
0xE4BA	0x83A0	# <CJK>
0xE4BB	0x8389	# <CJK>
0xE4BC	0x83A8	# <CJK>
0xE4BD	0x83F4	# <CJK>
0xE4BE	0x8413	# <CJK>
0xE4BF	0x83EB	# <CJK>
0xE4C0	0x83CE	# <CJK>
0xE4C1	0x83FD	# <CJK>
0xE4C2	0x8403	# <CJK>
0xE4C3	0x83D8	# <CJK>
0xE4C4	0x840B	# <CJK>
0xE4C5	0x83C1	# <CJK>
0xE4C6	0x83F7	# <CJK>
0xE4C7	0x8407	# <CJK>
0xE4C8	0x83E0	# <CJK>
0xE4C9	0x83F2	# <CJK>
0xE4CA	0x840D	# <CJK>
0xE4CB	0x8422	# <CJK>
0xE4CC	0x8420	# <CJK>
0xE4CD	0x83BD	# <CJK>
0xE4CE	0x8438	# <CJK>
0xE4CF	0x8506	# <CJK>
0xE4D0	0x83FB	# <CJK>
0xE4D1	0x846D	# <CJK>
0xE4D2	0x842A	# <CJK>
0xE4D3	0x843C	# <CJK>
0xE4D4	0x855A	# <CJK>
0xE4D5	0x8484	# <CJK>
0xE4D6	0x8477	# <CJK>
0xE4D7	0x846B	# <CJK>
0xE4D8	0x84AD	# <CJK>
0xE4D9	0x846E	# <CJK>
0xE4DA	0x8482	# <CJK>
0xE4DB	0x8469	# <CJK>
0xE4DC	0x8446	# <CJK>
0xE4DD	0x842C	# <CJK>
0xE4DE	0x846F	# <CJK>
0xE4DF	0x8479	# <CJK>
0xE4E0	0x8435	# <CJK>
0xE4E1	0x84CA	# <CJK>
0xE4E2	0x8462	# <CJK>
0xE4E3	0x84B9	# <CJK>
0xE4E4	0x84BF	# <CJK>
0xE4E5	0x849F	# <CJK>
0xE4E6	0x84D9	# <CJK>
0xE4E7	0x84CD	# <CJK>
0xE4E8	0x84BB	# <CJK>
0xE4E9	0x84DA	# <CJK>
0xE4EA	0x84D0	# <CJK>
0xE4EB	0x84C1	# <CJK>
0xE4EC	0x84C6	# <CJK>
0xE4ED	0x84D6	# <CJK>
0xE4EE	0x84A1	# <CJK>
0xE4EF	0x8521	# <CJK>
0xE4F0	0x84FF	# <CJK>
0xE4F1	0x84F4	# <CJK>
0xE4F2	0x8517	# <CJK>
0xE4F3	0x8518	# <CJK>
0xE4F4	0x852C	# <CJK>
0xE4F5	0x851F	# <CJK>
0xE4F6	0x8515	# <CJK>
0xE4F7	0x8514	# <CJK>
0xE4F8	0x84FC	# <CJK>
0xE4F9	0x8540	# <CJK>
0xE4FA	0x8563	# <CJK>
0xE4FB	0x8558	# <CJK>
0xE4FC	0x8548	# <CJK>
0xE540	0x8541	# <CJK>
0xE541	0x8602	# <CJK>
0xE542	0x854B	# <CJK>
0xE543	0x8555	# <CJK>
0xE544	0x8580	# <CJK>
0xE545	0x85A4	# <CJK>
0xE546	0x8588	# <CJK>
0xE547	0x8591	# <CJK>
0xE548	0x858A	# <CJK>
0xE549	0x85A8	# <CJK>
0xE54A	0x856D	# <CJK>
0xE54B	0x8594	# <CJK>
0xE54C	0x859B	# <CJK>
0xE54D	0x85EA	# <CJK>
0xE54E	0x8587	# <CJK>
0xE54F	0x859C	# <CJK>
0xE550	0x8577	# <CJK>
0xE551	0x857E	# <CJK>
0xE552	0x8590	# <CJK>
0xE553	0x85C9	# <CJK>
0xE554	0x85BA	# <CJK>
0xE555	0x85CF	# <CJK>
0xE556	0x85B9	# <CJK>
0xE557	0x85D0	# <CJK>
0xE558	0x85D5	# <CJK>
0xE559	0x85DD	# <CJK>
0xE55A	0x85E5	# <CJK>
0xE55B	0x85DC	# <CJK>
0xE55C	0x85F9	# <CJK>
0xE55D	0x860A	# <CJK>
0xE55E	0x8613	# <CJK>
0xE55F	0x860B	# <CJK>
0xE560	0x85FE	# <CJK>
0xE561	0x85FA	# <CJK>
0xE562	0x8606	# <CJK>
0xE563	0x8622	# <CJK>
0xE564	0x861A	# <CJK>
0xE565	0x8630	# <CJK>
0xE566	0x863F	# <CJK>
0xE567	0x864D	# <CJK>
0xE568	0x4E55	# <CJK>
0xE569	0x8654	# <CJK>
0xE56A	0x865F	# <CJK>
0xE56B	0x8667	# <CJK>
0xE56C	0x8671	# <CJK>
0xE56D	0x8693	# <CJK>
0xE56E	0x86A3	# <CJK>
0xE56F	0x86A9	# <CJK>
0xE570	0x86AA	# <CJK>
0xE571	0x868B	# <CJK>
0xE572	0x868C	# <CJK>
0xE573	0x86B6	# <CJK>
0xE574	0x86AF	# <CJK>
0xE575	0x86C4	# <CJK>
0xE576	0x86C6	# <CJK>
0xE577	0x86B0	# <CJK>
0xE578	0x86C9	# <CJK>
0xE579	0x8823	# <CJK>
0xE57A	0x86AB	# <CJK>
0xE57B	0x86D4	# <CJK>
0xE57C	0x86DE	# <CJK>
0xE57D	0x86E9	# <CJK>
0xE57E	0x86EC	# <CJK>
0xE580	0x86DF	# <CJK>
0xE581	0x86DB	# <CJK>
0xE582	0x86EF	# <CJK>
0xE583	0x8712	# <CJK>
0xE584	0x8706	# <CJK>
0xE585	0x8708	# <CJK>
0xE586	0x8700	# <CJK>
0xE587	0x8703	# <CJK>
0xE588	0x86FB	# <CJK>
0xE589	0x8711	# <CJK>
0xE58A	0x8709	# <CJK>
0xE58B	0x870D	# <CJK>
0xE58C	0x86F9	# <CJK>
0xE58D	0x870A	# <CJK>
0xE58E	0x8734	# <CJK>
0xE58F	0x873F	# <CJK>
0xE590	0x8737	# <CJK>
0xE591	0x873B	# <CJK>
0xE592	0x8725	# <CJK>
0xE593	0x8729	# <CJK>
0xE594	0x871A	# <CJK>
0xE595	0x8760	# <CJK>
0xE596	0x875F	# <CJK>
0xE597	0x8778	# <CJK>
0xE598	0x874C	# <CJK>
0xE599	0x874E	# <CJK>
0xE59A	0x8774	# <CJK>
0xE59B	0x8757	# <CJK>
0xE59C	0x8768	# <CJK>
0xE59D	0x876E	# <CJK>
0xE59E	0x8759	# <CJK>
0xE59F	0x8753	# <CJK>
0xE5A0	0x8763	# <CJK>
0xE5A1	0x876A	# <CJK>
0xE5A2	0x8805	# <CJK>
0xE5A3	0x87A2	# <CJK>
0xE5A4	0x879F	# <CJK>
0xE5A5	0x8782	# <CJK>
0xE5A6	0x87AF	# <CJK>
0xE5A7	0x87CB	# <CJK>
0xE5A8	0x87BD	# <CJK>
0xE5A9	0x87C0	# <CJK>
0xE5AA	0x87D0	# <CJK>
0xE5AB	0x96D6	# <CJK>
0xE5AC	0x87AB	# <CJK>
0xE5AD	0x87C4	# <CJK>
0xE5AE	0x87B3	# <CJK>
0xE5AF	0x87C7	# <CJK>
0xE5B0	0x87C6	# <CJK>
0xE5B1	0x87BB	# <CJK>
0xE5B2	0x87EF	# <CJK>
0xE5B3	0x87F2	# <CJK>
0xE5B4	0x87E0	# <CJK>
0xE5B5	0x880F	# <CJK>
0xE5B6	0x880D	# <CJK>
0xE5B7	0x87FE	# <CJK>
0xE5B8	0x87F6	# <CJK>
0xE5B9	0x87F7	# <CJK>
0xE5BA	0x880E	# <CJK>
0xE5BB	0x87D2	# <CJK>
0xE5BC	0x8811	# <CJK>
0xE5BD	0x8816	# <CJK>
0xE5BE	0x8815	# <CJK>
0xE5BF	0x8822	# <CJK>
0xE5C0	0x8821	# <CJK>
0xE5C1	0x8831	# <CJK>
0xE5C2	0x8836	# <CJK>
0xE5C3	0x8839	# <CJK>
0xE5C4	0x8827	# <CJK>
0xE5C5	0x883B	# <CJK>
0xE5C6	0x8844	# <CJK>
0xE5C7	0x8842	# <CJK>
0xE5C8	0x8852	# <CJK>
0xE5C9	0x8859	# <CJK>
0xE5CA	0x885E	# <CJK>
0xE5CB	0x8862	# <CJK>
0xE5CC	0x886B	# <CJK>
0xE5CD	0x8881	# <CJK>
0xE5CE	0x887E	# <CJK>
0xE5CF	0x889E	# <CJK>
0xE5D0	0x8875	# <CJK>
0xE5D1	0x887D	# <CJK>
0xE5D2	0x88B5	# <CJK>
0xE5D3	0x8872	# <CJK>
0xE5D4	0x8882	# <CJK>
0xE5D5	0x8897	# <CJK>
0xE5D6	0x8892	# <CJK>
0xE5D7	0x88AE	# <CJK>
0xE5D8	0x8899	# <CJK>
0xE5D9	0x88A2	# <CJK>
0xE5DA	0x888D	# <CJK>
0xE5DB	0x88A4	# <CJK>
0xE5DC	0x88B0	# <CJK>
0xE5DD	0x88BF	# <CJK>
0xE5DE	0x88B1	# <CJK>
0xE5DF	0x88C3	# <CJK>
0xE5E0	0x88C4	# <CJK>
0xE5E1	0x88D4	# <CJK>
0xE5E2	0x88D8	# <CJK>
0xE5E3	0x88D9	# <CJK>
0xE5E4	0x88DD	# <CJK>
0xE5E5	0x88F9	# <CJK>
0xE5E6	0x8902	# <CJK>
0xE5E7	0x88FC	# <CJK>
0xE5E8	0x88F4	# <CJK>
0xE5E9	0x88E8	# <CJK>
0xE5EA	0x88F2	# <CJK>
0xE5EB	0x8904	# <CJK>
0xE5EC	0x890C	# <CJK>
0xE5ED	0x890A	# <CJK>
0xE5EE	0x8913	# <CJK>
0xE5EF	0x8943	# <CJK>
0xE5F0	0x891E	# <CJK>
0xE5F1	0x8925	# <CJK>
0xE5F2	0x892A	# <CJK>
0xE5F3	0x892B	# <CJK>
0xE5F4	0x8941	# <CJK>
0xE5F5	0x8944	# <CJK>
0xE5F6	0x893B	# <CJK>
0xE5F7	0x8936	# <CJK>
0xE5F8	0x8938	# <CJK>
0xE5F9	0x894C	# <CJK>
0xE5FA	0x891D	# <CJK>
0xE5FB	0x8960	# <CJK>
0xE5FC	0x895E	# <CJK>
0xE640	0x8966	# <CJK>
0xE641	0x8964	# <CJK>
0xE642	0x896D	# <CJK>
0xE643	0x896A	# <CJK>
0xE644	0x896F	# <CJK>
0xE645	0x8974	# <CJK>
0xE646	0x8977	# <CJK>
0xE647	0x897E	# <CJK>
0xE648	0x8983	# <CJK>
0xE649	0x8988	# <CJK>
0xE64A	0x898A	# <CJK>
0xE64B	0x8993	# <CJK>
0xE64C	0x8998	# <CJK>
0xE64D	0x89A1	# <CJK>
0xE64E	0x89A9	# <CJK>
0xE64F	0x89A6	# <CJK>
0xE650	0x89AC	# <CJK>
0xE651	0x89AF	# <CJK>
0xE652	0x89B2	# <CJK>
0xE653	0x89BA	# <CJK>
0xE654	0x89BD	# <CJK>
0xE655	0x89BF	# <CJK>
0xE656	0x89C0	# <CJK>
0xE657	0x89DA	# <CJK>
0xE658	0x89DC	# <CJK>
0xE659	0x89DD	# <CJK>
0xE65A	0x89E7	# <CJK>
0xE65B	0x89F4	# <CJK>
0xE65C	0x89F8	# <CJK>
0xE65D	0x8A03	# <CJK>
0xE65E	0x8A16	# <CJK>
0xE65F	0x8A10	# <CJK>
0xE660	0x8A0C	# <CJK>
0xE661	0x8A1B	# <CJK>
0xE662	0x8A1D	# <CJK>
0xE663	0x8A25	# <CJK>
0xE664	0x8A36	# <CJK>
0xE665	0x8A41	# <CJK>
0xE666	0x8A5B	# <CJK>
0xE667	0x8A52	# <CJK>
0xE668	0x8A46	# <CJK>
0xE669	0x8A48	# <CJK>
0xE66A	0x8A7C	# <CJK>
0xE66B	0x8A6D	# <CJK>
0xE66C	0x8A6C	# <CJK>
0xE66D	0x8A62	# <CJK>
0xE66E	0x8A85	# <CJK>
0xE66F	0x8A82	# <CJK>
0xE670	0x8A84	# <CJK>
0xE671	0x8AA8	# <CJK>
0xE672	0x8AA1	# <CJK>
0xE673	0x8A91	# <CJK>
0xE674	0x8AA5	# <CJK>
0xE675	0x8AA6	# <CJK>
0xE676	0x8A9A	# <CJK>
0xE677	0x8AA3	# <CJK>
0xE678	0x8AC4	# <CJK>
0xE679	0x8ACD	# <CJK>
0xE67A	0x8AC2	# <CJK>
0xE67B	0x8ADA	# <CJK>
0xE67C	0x8AEB	# <CJK>
0xE67D	0x8AF3	# <CJK>
0xE67E	0x8AE7	# <CJK>
0xE680	0x8AE4	# <CJK>
0xE681	0x8AF1	# <CJK>
0xE682	0x8B14	# <CJK>
0xE683	0x8AE0	# <CJK>
0xE684	0x8AE2	# <CJK>
0xE685	0x8AF7	# <CJK>
0xE686	0x8ADE	# <CJK>
0xE687	0x8ADB	# <CJK>
0xE688	0x8B0C	# <CJK>
0xE689	0x8B07	# <CJK>
0xE68A	0x8B1A	# <CJK>
0xE68B	0x8AE1	# <CJK>
0xE68C	0x8B16	# <CJK>
0xE68D	0x8B10	# <CJK>
0xE68E	0x8B17	# <CJK>
0xE68F	0x8B20	# <CJK>
0xE690	0x8B33	# <CJK>
0xE691	0x97AB	# <CJK>
0xE692	0x8B26	# <CJK>
0xE693	0x8B2B	# <CJK>
0xE694	0x8B3E	# <CJK>
0xE695	0x8B28	# <CJK>
0xE696	0x8B41	# <CJK>
0xE697	0x8B4C	# <CJK>
0xE698	0x8B4F	# <CJK>
0xE699	0x8B4E	# <CJK>
0xE69A	0x8B49	# <CJK>
0xE69B	0x8B56	# <CJK>
0xE69C	0x8B5B	# <CJK>
0xE69D	0x8B5A	# <CJK>
0xE69E	0x8B6B	# <CJK>
0xE69F	0x8B5F	# <CJK>
0xE6A0	0x8B6C	# <CJK>
0xE6A1	0x8B6F	# <CJK>
0xE6A2	0x8B74	# <CJK>
0xE6A3	0x8B7D	# <CJK>
0xE6A4	0x8B80	# <CJK>
0xE6A5	0x8B8C	# <CJK>
0xE6A6	0x8B8E	# <CJK>
0xE6A7	0x8B92	# <CJK>
0xE6A8	0x8B93	# <CJK>
0xE6A9	0x8B96	# <CJK>
0xE6AA	0x8B99	# <CJK>
0xE6AB	0x8B9A	# <CJK>
0xE6AC	0x8C3A	# <CJK>
0xE6AD	0x8C41	# <CJK>
0xE6AE	0x8C3F	# <CJK>
0xE6AF	0x8C48	# <CJK>
0xE6B0	0x8C4C	# <CJK>
0xE6B1	0x8C4E	# <CJK>
0xE6B2	0x8C50	# <CJK>
0xE6B3	0x8C55	# <CJK>
0xE6B4	0x8C62	# <CJK>
0xE6B5	0x8C6C	# <CJK>
0xE6B6	0x8C78	# <CJK>
0xE6B7	0x8C7A	# <CJK>
0xE6B8	0x8C82	# <CJK>
0xE6B9	0x8C89	# <CJK>
0xE6BA	0x8C85	# <CJK>
0xE6BB	0x8C8A	# <CJK>
0xE6BC	0x8C8D	# <CJK>
0xE6BD	0x8C8E	# <CJK>
0xE6BE	0x8C94	# <CJK>
0xE6BF	0x8C7C	# <CJK>
0xE6C0	0x8C98	# <CJK>
0xE6C1	0x621D	# <CJK>
0xE6C2	0x8CAD	# <CJK>
0xE6C3	0x8CAA	# <CJK>
0xE6C4	0x8CBD	# <CJK>
0xE6C5	0x8CB2	# <CJK>
0xE6C6	0x8CB3	# <CJK>
0xE6C7	0x8CAE	# <CJK>
0xE6C8	0x8CB6	# <CJK>
0xE6C9	0x8CC8	# <CJK>
0xE6CA	0x8CC1	# <CJK>
0xE6CB	0x8CE4	# <CJK>
0xE6CC	0x8CE3	# <CJK>
0xE6CD	0x8CDA	# <CJK>
0xE6CE	0x8CFD	# <CJK>
0xE6CF	0x8CFA	# <CJK>
0xE6D0	0x8CFB	# <CJK>
0xE6D1	0x8D04	# <CJK>
0xE6D2	0x8D05	# <CJK>
0xE6D3	0x8D0A	# <CJK>
0xE6D4	0x8D07	# <CJK>
0xE6D5	0x8D0F	# <CJK>
0xE6D6	0x8D0D	# <CJK>
0xE6D7	0x8D10	# <CJK>
0xE6D8	0x9F4E	# <CJK>
0xE6D9	0x8D13	# <CJK>
0xE6DA	0x8CCD	# <CJK>
0xE6DB	0x8D14	# <CJK>
0xE6DC	0x8D16	# <CJK>
0xE6DD	0x8D67	# <CJK>
0xE6DE	0x8D6D	# <CJK>
0xE6DF	0x8D71	# <CJK>
0xE6E0	0x8D73	# <CJK>
0xE6E1	0x8D81	# <CJK>
0xE6E2	0x8D99	# <CJK>
0xE6E3	0x8DC2	# <CJK>
0xE6E4	0x8DBE	# <CJK>
0xE6E5	0x8DBA	# <CJK>
0xE6E6	0x8DCF	# <CJK>
0xE6E7	0x8DDA	# <CJK>
0xE6E8	0x8DD6	# <CJK>
0xE6E9	0x8DCC	# <CJK>
0xE6EA	0x8DDB	# <CJK>
0xE6EB	0x8DCB	# <CJK>
0xE6EC	0x8DEA	# <CJK>
0xE6ED	0x8DEB	# <CJK>
0xE6EE	0x8DDF	# <CJK>
0xE6EF	0x8DE3	# <CJK>
0xE6F0	0x8DFC	# <CJK>
0xE6F1	0x8E08	# <CJK>
0xE6F2	0x8E09	# <CJK>
0xE6F3	0x8DFF	# <CJK>
0xE6F4	0x8E1D	# <CJK>
0xE6F5	0x8E1E	# <CJK>
0xE6F6	0x8E10	# <CJK>
0xE6F7	0x8E1F	# <CJK>
0xE6F8	0x8E42	# <CJK>
0xE6F9	0x8E35	# <CJK>
0xE6FA	0x8E30	# <CJK>
0xE6FB	0x8E34	# <CJK>
0xE6FC	0x8E4A	# <CJK>
0xE740	0x8E47	# <CJK>
0xE741	0x8E49	# <CJK>
0xE742	0x8E4C	# <CJK>
0xE743	0x8E50	# <CJK>
0xE744	0x8E48	# <CJK>
0xE745	0x8E59	# <CJK>
0xE746	0x8E64	# <CJK>
0xE747	0x8E60	# <CJK>
0xE748	0x8E2A	# <CJK>
0xE749	0x8E63	# <CJK>
0xE74A	0x8E55	# <CJK>
0xE74B	0x8E76	# <CJK>
0xE74C	0x8E72	# <CJK>
0xE74D	0x8E7C	# <CJK>
0xE74E	0x8E81	# <CJK>
0xE74F	0x8E87	# <CJK>
0xE750	0x8E85	# <CJK>
0xE751	0x8E84	# <CJK>
0xE752	0x8E8B	# <CJK>
0xE753	0x8E8A	# <CJK>
0xE754	0x8E93	# <CJK>
0xE755	0x8E91	# <CJK>
0xE756	0x8E94	# <CJK>
0xE757	0x8E99	# <CJK>
0xE758	0x8EAA	# <CJK>
0xE759	0x8EA1	# <CJK>
0xE75A	0x8EAC	# <CJK>
0xE75B	0x8EB0	# <CJK>
0xE75C	0x8EC6	# <CJK>
0xE75D	0x8EB1	# <CJK>
0xE75E	0x8EBE	# <CJK>
0xE75F	0x8EC5	# <CJK>
0xE760	0x8EC8	# <CJK>
0xE761	0x8ECB	# <CJK>
0xE762	0x8EDB	# <CJK>
0xE763	0x8EE3	# <CJK>
0xE764	0x8EFC	# <CJK>
0xE765	0x8EFB	# <CJK>
0xE766	0x8EEB	# <CJK>
0xE767	0x8EFE	# <CJK>
0xE768	0x8F0A	# <CJK>
0xE769	0x8F05	# <CJK>
0xE76A	0x8F15	# <CJK>
0xE76B	0x8F12	# <CJK>
0xE76C	0x8F19	# <CJK>
0xE76D	0x8F13	# <CJK>
0xE76E	0x8F1C	# <CJK>
0xE76F	0x8F1F	# <CJK>
0xE770	0x8F1B	# <CJK>
0xE771	0x8F0C	# <CJK>
0xE772	0x8F26	# <CJK>
0xE773	0x8F33	# <CJK>
0xE774	0x8F3B	# <CJK>
0xE775	0x8F39	# <CJK>
0xE776	0x8F45	# <CJK>
0xE777	0x8F42	# <CJK>
0xE778	0x8F3E	# <CJK>
0xE779	0x8F4C	# <CJK>
0xE77A	0x8F49	# <CJK>
0xE77B	0x8F46	# <CJK>
0xE77C	0x8F4E	# <CJK>
0xE77D	0x8F57	# <CJK>
0xE77E	0x8F5C	# <CJK>
0xE780	0x8F62	# <CJK>
0xE781	0x8F63	# <CJK>
0xE782	0x8F64	# <CJK>
0xE783	0x8F9C	# <CJK>
0xE784	0x8F9F	# <CJK>
0xE785	0x8FA3	# <CJK>
0xE786	0x8FAD	# <CJK>
0xE787	0x8FAF	# <CJK>
0xE788	0x8FB7	# <CJK>
0xE789	0x8FDA	# <CJK>
0xE78A	0x8FE5	# <CJK>
0xE78B	0x8FE2	# <CJK>
0xE78C	0x8FEA	# <CJK>
0xE78D	0x8FEF	# <CJK>
0xE78E	0x9087	# <CJK>
0xE78F	0x8FF4	# <CJK>
0xE790	0x9005	# <CJK>
0xE791	0x8FF9	# <CJK>
0xE792	0x8FFA	# <CJK>
0xE793	0x9011	# <CJK>
0xE794	0x9015	# <CJK>
0xE795	0x9021	# <CJK>
0xE796	0x900D	# <CJK>
0xE797	0x901E	# <CJK>
0xE798	0x9016	# <CJK>
0xE799	0x900B	# <CJK>
0xE79A	0x9027	# <CJK>
0xE79B	0x9036	# <CJK>
0xE79C	0x9035	# <CJK>
0xE79D	0x9039	# <CJK>
0xE79E	0x8FF8	# <CJK>
0xE79F	0x904F	# <CJK>
0xE7A0	0x9050	# <CJK>
0xE7A1	0x9051	# <CJK>
0xE7A2	0x9052	# <CJK>
0xE7A3	0x900E	# <CJK>
0xE7A4	0x9049	# <CJK>
0xE7A5	0x903E	# <CJK>
0xE7A6	0x9056	# <CJK>
0xE7A7	0x9058	# <CJK>
0xE7A8	0x905E	# <CJK>
0xE7A9	0x9068	# <CJK>
0xE7AA	0x906F	# <CJK>
0xE7AB	0x9076	# <CJK>
0xE7AC	0x96A8	# <CJK>
0xE7AD	0x9072	# <CJK>
0xE7AE	0x9082	# <CJK>
0xE7AF	0x907D	# <CJK>
0xE7B0	0x9081	# <CJK>
0xE7B1	0x9080	# <CJK>
0xE7B2	0x908A	# <CJK>
0xE7B3	0x9089	# <CJK>
0xE7B4	0x908F	# <CJK>
0xE7B5	0x90A8	# <CJK>
0xE7B6	0x90AF	# <CJK>
0xE7B7	0x90B1	# <CJK>
0xE7B8	0x90B5	# <CJK>
0xE7B9	0x90E2	# <CJK>
0xE7BA	0x90E4	# <CJK>
0xE7BB	0x6248	# <CJK>
0xE7BC	0x90DB	# <CJK>
0xE7BD	0x9102	# <CJK>
0xE7BE	0x9112	# <CJK>
0xE7BF	0x9119	# <CJK>
0xE7C0	0x9132	# <CJK>
0xE7C1	0x9130	# <CJK>
0xE7C2	0x914A	# <CJK>
0xE7C3	0x9156	# <CJK>
0xE7C4	0x9158	# <CJK>
0xE7C5	0x9163	# <CJK>
0xE7C6	0x9165	# <CJK>
0xE7C7	0x9169	# <CJK>
0xE7C8	0x9173	# <CJK>
0xE7C9	0x9172	# <CJK>
0xE7CA	0x918B	# <CJK>
0xE7CB	0x9189	# <CJK>
0xE7CC	0x9182	# <CJK>
0xE7CD	0x91A2	# <CJK>
0xE7CE	0x91AB	# <CJK>
0xE7CF	0x91AF	# <CJK>
0xE7D0	0x91AA	# <CJK>
0xE7D1	0x91B5	# <CJK>
0xE7D2	0x91B4	# <CJK>
0xE7D3	0x91BA	# <CJK>
0xE7D4	0x91C0	# <CJK>
0xE7D5	0x91C1	# <CJK>
0xE7D6	0x91C9	# <CJK>
0xE7D7	0x91CB	# <CJK>
0xE7D8	0x91D0	# <CJK>
0xE7D9	0x91D6	# <CJK>
0xE7DA	0x91DF	# <CJK>
0xE7DB	0x91E1	# <CJK>
0xE7DC	0x91DB	# <CJK>
0xE7DD	0x91FC	# <CJK>
0xE7DE	0x91F5	# <CJK>
0xE7DF	0x91F6	# <CJK>
0xE7E0	0x921E	# <CJK>
0xE7E1	0x91FF	# <CJK>
0xE7E2	0x9214	# <CJK>
0xE7E3	0x922C	# <CJK>
0xE7E4	0x9215	# <CJK>
0xE7E5	0x9211	# <CJK>
0xE7E6	0x925E	# <CJK>
0xE7E7	0x9257	# <CJK>
0xE7E8	0x9245	# <CJK>
0xE7E9	0x9249	# <CJK>
0xE7EA	0x9264	# <CJK>
0xE7EB	0x9248	# <CJK>
0xE7EC	0x9295	# <CJK>
0xE7ED	0x923F	# <CJK>
0xE7EE	0x924B	# <CJK>
0xE7EF	0x9250	# <CJK>
0xE7F0	0x929C	# <CJK>
0xE7F1	0x9296	# <CJK>
0xE7F2	0x9293	# <CJK>
0xE7F3	0x929B	# <CJK>
0xE7F4	0x925A	# <CJK>
0xE7F5	0x92CF	# <CJK>
0xE7F6	0x92B9	# <CJK>
0xE7F7	0x92B7	# <CJK>
0xE7F8	0x92E9	# <CJK>
0xE7F9	0x930F	# <CJK>
0xE7FA	0x92FA	# <CJK>
0xE7FB	0x9344	# <CJK>
0xE7FC	0x932E	# <CJK>
0xE840	0x9319	# <CJK>
0xE841	0x9322	# <CJK>
0xE842	0x931A	# <CJK>
0xE843	0x9323	# <CJK>
0xE844	0x933A	# <CJK>
0xE845	0x9335	# <CJK>
0xE846	0x933B	# <CJK>
0xE847	0x935C	# <CJK>
0xE848	0x9360	# <CJK>
0xE849	0x937C	# <CJK>
0xE84A	0x936E	# <CJK>
0xE84B	0x9356	# <CJK>
0xE84C	0x93B0	# <CJK>
0xE84D	0x93AC	# <CJK>
0xE84E	0x93AD	# <CJK>
0xE84F	0x9394	# <CJK>
0xE850	0x93B9	# <CJK>
0xE851	0x93D6	# <CJK>
0xE852	0x93D7	# <CJK>
0xE853	0x93E8	# <CJK>
0xE854	0x93E5	# <CJK>
0xE855	0x93D8	# <CJK>
0xE856	0x93C3	# <CJK>
0xE857	0x93DD	# <CJK>
0xE858	0x93D0	# <CJK>
0xE859	0x93C8	# <CJK>
0xE85A	0x93E4	# <CJK>
0xE85B	0x941A	# <CJK>
0xE85C	0x9414	# <CJK>
0xE85D	0x9413	# <CJK>
0xE85E	0x9403	# <CJK>
0xE85F	0x9407	# <CJK>
0xE860	0x9410	# <CJK>
0xE861	0x9436	# <CJK>
0xE862	0x942B	# <CJK>
0xE863	0x9435	# <CJK>
0xE864	0x9421	# <CJK>
0xE865	0x943A	# <CJK>
0xE866	0x9441	# <CJK>
0xE867	0x9452	# <CJK>
0xE868	0x9444	# <CJK>
0xE869	0x945B	# <CJK>
0xE86A	0x9460	# <CJK>
0xE86B	0x9462	# <CJK>
0xE86C	0x945E	# <CJK>
0xE86D	0x946A	# <CJK>
0xE86E	0x9229	# <CJK>
0xE86F	0x9470	# <CJK>
0xE870	0x9475	# <CJK>
0xE871	0x9477	# <CJK>
0xE872	0x947D	# <CJK>
0xE873	0x945A	# <CJK>
0xE874	0x947C	# <CJK>
0xE875	0x947E	# <CJK>
0xE876	0x9481	# <CJK>
0xE877	0x947F	# <CJK>
0xE878	0x9582	# <CJK>
0xE879	0x9587	# <CJK>
0xE87A	0x958A	# <CJK>
0xE87B	0x9594	# <CJK>
0xE87C	0x9596	# <CJK>
0xE87D	0x9598	# <CJK>
0xE87E	0x9599	# <CJK>
0xE880	0x95A0	# <CJK>
0xE881	0x95A8	# <CJK>
0xE882	0x95A7	# <CJK>
0xE883	0x95AD	# <CJK>
0xE884	0x95BC	# <CJK>
0xE885	0x95BB	# <CJK>
0xE886	0x95B9	# <CJK>
0xE887	0x95BE	# <CJK>
0xE888	0x95CA	# <CJK>
0xE889	0x6FF6	# <CJK>
0xE88A	0x95C3	# <CJK>
0xE88B	0x95CD	# <CJK>
0xE88C	0x95CC	# <CJK>
0xE88D	0x95D5	# <CJK>
0xE88E	0x95D4	# <CJK>
0xE88F	0x95D6	# <CJK>
0xE890	0x95DC	# <CJK>
0xE891	0x95E1	# <CJK>
0xE892	0x95E5	# <CJK>
0xE893	0x95E2	# <CJK>
0xE894	0x9621	# <CJK>
0xE895	0x9628	# <CJK>
0xE896	0x962E	# <CJK>
0xE897	0x962F	# <CJK>
0xE898	0x9642	# <CJK>
0xE899	0x964C	# <CJK>
0xE89A	0x964F	# <CJK>
0xE89B	0x964B	# <CJK>
0xE89C	0x9677	# <CJK>
0xE89D	0x965C	# <CJK>
0xE89E	0x965E	# <CJK>
0xE89F	0x965D	# <CJK>
0xE8A0	0x965F	# <CJK>
0xE8A1	0x9666	# <CJK>
0xE8A2	0x9672	# <CJK>
0xE8A3	0x966C	# <CJK>
0xE8A4	0x968D	# <CJK>
0xE8A5	0x9698	# <CJK>
0xE8A6	0x9695	# <CJK>
0xE8A7	0x9697	# <CJK>
0xE8A8	0x96AA	# <CJK>
0xE8A9	0x96A7	# <CJK>
0xE8AA	0x96B1	# <CJK>
0xE8AB	0x96B2	# <CJK>
0xE8AC	0x96B0	# <CJK>
0xE8AD	0x96B4	# <CJK>
0xE8AE	0x96B6	# <CJK>
0xE8AF	0x96B8	# <CJK>
0xE8B0	0x96B9	# <CJK>
0xE8B1	0x96CE	# <CJK>
0xE8B2	0x96CB	# <CJK>
0xE8B3	0x96C9	# <CJK>
0xE8B4	0x96CD	# <CJK>
0xE8B5	0x894D	# <CJK>
0xE8B6	0x96DC	# <CJK>
0xE8B7	0x970D	# <CJK>
0xE8B8	0x96D5	# <CJK>
0xE8B9	0x96F9	# <CJK>
0xE8BA	0x9704	# <CJK>
0xE8BB	0x9706	# <CJK>
0xE8BC	0x9708	# <CJK>
0xE8BD	0x9713	# <CJK>
0xE8BE	0x970E	# <CJK>
0xE8BF	0x9711	# <CJK>
0xE8C0	0x970F	# <CJK>
0xE8C1	0x9716	# <CJK>
0xE8C2	0x9719	# <CJK>
0xE8C3	0x9724	# <CJK>
0xE8C4	0x972A	# <CJK>
0xE8C5	0x9730	# <CJK>
0xE8C6	0x9739	# <CJK>
0xE8C7	0x973D	# <CJK>
0xE8C8	0x973E	# <CJK>
0xE8C9	0x9744	# <CJK>
0xE8CA	0x9746	# <CJK>
0xE8CB	0x9748	# <CJK>
0xE8CC	0x9742	# <CJK>
0xE8CD	0x9749	# <CJK>
0xE8CE	0x975C	# <CJK>
0xE8CF	0x9760	# <CJK>
0xE8D0	0x9764	# <CJK>
0xE8D1	0x9766	# <CJK>
0xE8D2	0x9768	# <CJK>
0xE8D3	0x52D2	# <CJK>
0xE8D4	0x976B	# <CJK>
0xE8D5	0x9771	# <CJK>
0xE8D6	0x9779	# <CJK>
0xE8D7	0x9785	# <CJK>
0xE8D8	0x977C	# <CJK>
0xE8D9	0x9781	# <CJK>
0xE8DA	0x977A	# <CJK>
0xE8DB	0x9786	# <CJK>
0xE8DC	0x978B	# <CJK>
0xE8DD	0x978F	# <CJK>
0xE8DE	0x9790	# <CJK>
0xE8DF	0x979C	# <CJK>
0xE8E0	0x97A8	# <CJK>
0xE8E1	0x97A6	# <CJK>
0xE8E2	0x97A3	# <CJK>
0xE8E3	0x97B3	# <CJK>
0xE8E4	0x97B4	# <CJK>
0xE8E5	0x97C3	# <CJK>
0xE8E6	0x97C6	# <CJK>
0xE8E7	0x97C8	# <CJK>
0xE8E8	0x97CB	# <CJK>
0xE8E9	0x97DC	# <CJK>
0xE8EA	0x97ED	# <CJK>
0xE8EB	0x9F4F	# <CJK>
0xE8EC	0x97F2	# <CJK>
0xE8ED	0x7ADF	# <CJK>
0xE8EE	0x97F6	# <CJK>
0xE8EF	0x97F5	# <CJK>
0xE8F0	0x980F	# <CJK>
0xE8F1	0x980C	# <CJK>
0xE8F2	0x9838	# <CJK>
0xE8F3	0x9824	# <CJK>
0xE8F4	0x9821	# <CJK>
0xE8F5	0x9837	# <CJK>
0xE8F6	0x983D	# <CJK>
0xE8F7	0x9846	# <CJK>
0xE8F8	0x984F	# <CJK>
0xE8F9	0x984B	# <CJK>
0xE8FA	0x986B	# <CJK>
0xE8FB	0x986F	# <CJK>
0xE8FC	0x9870	# <CJK>
0xE940	0x9871	# <CJK>
0xE941	0x9874	# <CJK>
0xE942	0x9873	# <CJK>
0xE943	0x98AA	# <CJK>
0xE944	0x98AF	# <CJK>
0xE945	0x98B1	# <CJK>
0xE946	0x98B6	# <CJK>
0xE947	0x98C4	# <CJK>
0xE948	0x98C3	# <CJK>
0xE949	0x98C6	# <CJK>
0xE94A	0x98E9	# <CJK>
0xE94B	0x98EB	# <CJK>
0xE94C	0x9903	# <CJK>
0xE94D	0x9909	# <CJK>
0xE94E	0x9912	# <CJK>
0xE94F	0x9914	# <CJK>
0xE950	0x9918	# <CJK>
0xE951	0x9921	# <CJK>
0xE952	0x991D	# <CJK>
0xE953	0x991E	# <CJK>
0xE954	0x9924	# <CJK>
0xE955	0x9920	# <CJK>
0xE956	0x992C	# <CJK>
0xE957	0x992E	# <CJK>
0xE958	0x993D	# <CJK>
0xE959	0x993E	# <CJK>
0xE95A	0x9942	# <CJK>
0xE95B	0x9949	# <CJK>
0xE95C	0x9945	# <CJK>
0xE95D	0x9950	# <CJK>
0xE95E	0x994B	# <CJK>
0xE95F	0x9951	# <CJK>
0xE960	0x9952	# <CJK>
0xE961	0x994C	# <CJK>
0xE962	0x9955	# <CJK>
0xE963	0x9997	# <CJK>
0xE964	0x9998	# <CJK>
0xE965	0x99A5	# <CJK>
0xE966	0x99AD	# <CJK>
0xE967	0x99AE	# <CJK>
0xE968	0x99BC	# <CJK>
0xE969	0x99DF	# <CJK>
0xE96A	0x99DB	# <CJK>
0xE96B	0x99DD	# <CJK>
0xE96C	0x99D8	# <CJK>
0xE96D	0x99D1	# <CJK>
0xE96E	0x99ED	# <CJK>
0xE96F	0x99EE	# <CJK>
0xE970	0x99F1	# <CJK>
0xE971	0x99F2	# <CJK>
0xE972	0x99FB	# <CJK>
0xE973	0x99F8	# <CJK>
0xE974	0x9A01	# <CJK>
0xE975	0x9A0F	# <CJK>
0xE976	0x9A05	# <CJK>
0xE977	0x99E2	# <CJK>
0xE978	0x9A19	# <CJK>
0xE979	0x9A2B	# <CJK>
0xE97A	0x9A37	# <CJK>
0xE97B	0x9A45	# <CJK>
0xE97C	0x9A42	# <CJK>
0xE97D	0x9A40	# <CJK>
0xE97E	0x9A43	# <CJK>
0xE980	0x9A3E	# <CJK>
0xE981	0x9A55	# <CJK>
0xE982	0x9A4D	# <CJK>
0xE983	0x9A5B	# <CJK>
0xE984	0x9A57	# <CJK>
0xE985	0x9A5F	# <CJK>
0xE986	0x9A62	# <CJK>
0xE987	0x9A65	# <CJK>
0xE988	0x9A64	# <CJK>
0xE989	0x9A69	# <CJK>
0xE98A	0x9A6B	# <CJK>
0xE98B	0x9A6A	# <CJK>
0xE98C	0x9AAD	# <CJK>
0xE98D	0x9AB0	# <CJK>
0xE98E	0x9ABC	# <CJK>
0xE98F	0x9AC0	# <CJK>
0xE990	0x9ACF	# <CJK>
0xE991	0x9AD1	# <CJK>
0xE992	0x9AD3	# <CJK>
0xE993	0x9AD4	# <CJK>
0xE994	0x9ADE	# <CJK>
0xE995	0x9ADF	# <CJK>
0xE996	0x9AE2	# <CJK>
0xE997	0x9AE3	# <CJK>
0xE998	0x9AE6	# <CJK>
0xE999	0x9AEF	# <CJK>
0xE99A	0x9AEB	# <CJK>
0xE99B	0x9AEE	# <CJK>
0xE99C	0x9AF4	# <CJK>
0xE99D	0x9AF1	# <CJK>
0xE99E	0x9AF7	# <CJK>
0xE99F	0x9AFB	# <CJK>
0xE9A0	0x9B06	# <CJK>
0xE9A1	0x9B18	# <CJK>
0xE9A2	0x9B1A	# <CJK>
0xE9A3	0x9B1F	# <CJK>
0xE9A4	0x9B22	# <CJK>
0xE9A5	0x9B23	# <CJK>
0xE9A6	0x9B25	# <CJK>
0xE9A7	0x9B27	# <CJK>
0xE9A8	0x9B28	# <CJK>
0xE9A9	0x9B29	# <CJK>
0xE9AA	0x9B2A	# <CJK>
0xE9AB	0x9B2E	# <CJK>
0xE9AC	0x9B2F	# <CJK>
0xE9AD	0x9B32	# <CJK>
0xE9AE	0x9B44	# <CJK>
0xE9AF	0x9B43	# <CJK>
0xE9B0	0x9B4F	# <CJK>
0xE9B1	0x9B4D	# <CJK>
0xE9B2	0x9B4E	# <CJK>
0xE9B3	0x9B51	# <CJK>
0xE9B4	0x9B58	# <CJK>
0xE9B5	0x9B74	# <CJK>
0xE9B6	0x9B93	# <CJK>
0xE9B7	0x9B83	# <CJK>
0xE9B8	0x9B91	# <CJK>
0xE9B9	0x9B96	# <CJK>
0xE9BA	0x9B97	# <CJK>
0xE9BB	0x9B9F	# <CJK>
0xE9BC	0x9BA0	# <CJK>
0xE9BD	0x9BA8	# <CJK>
0xE9BE	0x9BB4	# <CJK>
0xE9BF	0x9BC0	# <CJK>
0xE9C0	0x9BCA	# <CJK>
0xE9C1	0x9BB9	# <CJK>
0xE9C2	0x9BC6	# <CJK>
0xE9C3	0x9BCF	# <CJK>
0xE9C4	0x9BD1	# <CJK>
0xE9C5	0x9BD2	# <CJK>
0xE9C6	0x9BE3	# <CJK>
0xE9C7	0x9BE2	# <CJK>
0xE9C8	0x9BE4	# <CJK>
0xE9C9	0x9BD4	# <CJK>
0xE9CA	0x9BE1	# <CJK>
0xE9CB	0x9C3A	# <CJK>
0xE9CC	0x9BF2	# <CJK>
0xE9CD	0x9BF1	# <CJK>
0xE9CE	0x9BF0	# <CJK>
0xE9CF	0x9C15	# <CJK>
0xE9D0	0x9C14	# <CJK>
0xE9D1	0x9C09	# <CJK>
0xE9D2	0x9C13	# <CJK>
0xE9D3	0x9C0C	# <CJK>
0xE9D4	0x9C06	# <CJK>
0xE9D5	0x9C08	# <CJK>
0xE9D6	0x9C12	# <CJK>
0xE9D7	0x9C0A	# <CJK>
0xE9D8	0x9C04	# <CJK>
0xE9D9	0x9C2E	# <CJK>
0xE9DA	0x9C1B	# <CJK>
0xE9DB	0x9C25	# <CJK>
0xE9DC	0x9C24	# <CJK>
0xE9DD	0x9C21	# <CJK>
0xE9DE	0x9C30	# <CJK>
0xE9DF	0x9C47	# <CJK>
0xE9E0	0x9C32	# <CJK>
0xE9E1	0x9C46	# <CJK>
0xE9E2	0x9C3E	# <CJK>
0xE9E3	0x9C5A	# <CJK>
0xE9E4	0x9C60	# <CJK>
0xE9E5	0x9C67	# <CJK>
0xE9E6	0x9C76	# <CJK>
0xE9E7	0x9C78	# <CJK>
0xE9E8	0x9CE7	# <CJK>
0xE9E9	0x9CEC	# <CJK>
0xE9EA	0x9CF0	# <CJK>
0xE9EB	0x9D09	# <CJK>
0xE9EC	0x9D08	# <CJK>
0xE9ED	0x9CEB	# <CJK>
0xE9EE	0x9D03	# <CJK>
0xE9EF	0x9D06	# <CJK>
0xE9F0	0x9D2A	# <CJK>
0xE9F1	0x9D26	# <CJK>
0xE9F2	0x9DAF	# <CJK>
0xE9F3	0x9D23	# <CJK>
0xE9F4	0x9D1F	# <CJK>
0xE9F5	0x9D44	# <CJK>
0xE9F6	0x9D15	# <CJK>
0xE9F7	0x9D12	# <CJK>
0xE9F8	0x9D41	# <CJK>
0xE9F9	0x9D3F	# <CJK>
0xE9FA	0x9D3E	# <CJK>
0xE9FB	0x9D46	# <CJK>
0xE9FC	0x9D48	# <CJK>
0xEA40	0x9D5D	# <CJK>
0xEA41	0x9D5E	# <CJK>
0xEA42	0x9D64	# <CJK>
0xEA43	0x9D51	# <CJK>
0xEA44	0x9D50	# <CJK>
0xEA45	0x9D59	# <CJK>
0xEA46	0x9D72	# <CJK>
0xEA47	0x9D89	# <CJK>
0xEA48	0x9D87	# <CJK>
0xEA49	0x9DAB	# <CJK>
0xEA4A	0x9D6F	# <CJK>
0xEA4B	0x9D7A	# <CJK>
0xEA4C	0x9D9A	# <CJK>
0xEA4D	0x9DA4	# <CJK>
0xEA4E	0x9DA9	# <CJK>
0xEA4F	0x9DB2	# <CJK>
0xEA50	0x9DC4	# <CJK>
0xEA51	0x9DC1	# <CJK>
0xEA52	0x9DBB	# <CJK>
0xEA53	0x9DB8	# <CJK>
0xEA54	0x9DBA	# <CJK>
0xEA55	0x9DC6	# <CJK>
0xEA56	0x9DCF	# <CJK>
0xEA57	0x9DC2	# <CJK>
0xEA58	0x9DD9	# <CJK>
0xEA59	0x9DD3	# <CJK>
0xEA5A	0x9DF8	# <CJK>
0xEA5B	0x9DE6	# <CJK>
0xEA5C	0x9DED	# <CJK>
0xEA5D	0x9DEF	# <CJK>
0xEA5E	0x9DFD	# <CJK>
0xEA5F	0x9E1A	# <CJK>
0xEA60	0x9E1B	# <CJK>
0xEA61	0x9E1E	# <CJK>
0xEA62	0x9E75	# <CJK>
0xEA63	0x9E79	# <CJK>
0xEA64	0x9E7D	# <CJK>
0xEA65	0x9E81	# <CJK>
0xEA66	0x9E88	# <CJK>
0xEA67	0x9E8B	# <CJK>
0xEA68	0x9E8C	# <CJK>
0xEA69	0x9E92	# <CJK>
0xEA6A	0x9E95	# <CJK>
0xEA6B	0x9E91	# <CJK>
0xEA6C	0x9E9D	# <CJK>
0xEA6D	0x9EA5	# <CJK>
0xEA6E	0x9EA9	# <CJK>
0xEA6F	0x9EB8	# <CJK>
0xEA70	0x9EAA	# <CJK>
0xEA71	0x9EAD	# <CJK>
0xEA72	0x9761	# <CJK>
0xEA73	0x9ECC	# <CJK>
0xEA74	0x9ECE	# <CJK>
0xEA75	0x9ECF	# <CJK>
0xEA76	0x9ED0	# <CJK>
0xEA77	0x9ED4	# <CJK>
0xEA78	0x9EDC	# <CJK>
0xEA79	0x9EDE	# <CJK>
0xEA7A	0x9EDD	# <CJK>
0xEA7B	0x9EE0	# <CJK>
0xEA7C	0x9EE5	# <CJK>
0xEA7D	0x9EE8	# <CJK>
0xEA7E	0x9EEF	# <CJK>
0xEA80	0x9EF4	# <CJK>
0xEA81	0x9EF6	# <CJK>
0xEA82	0x9EF7	# <CJK>
0xEA83	0x9EF9	# <CJK>
0xEA84	0x9EFB	# <CJK>
0xEA85	0x9EFC	# <CJK>
0xEA86	0x9EFD	# <CJK>
0xEA87	0x9F07	# <CJK>
0xEA88	0x9F08	# <CJK>
0xEA89	0x76B7	# <CJK>
0xEA8A	0x9F15	# <CJK>
0xEA8B	0x9F21	# <CJK>
0xEA8C	0x9F2C	# <CJK>
0xEA8D	0x9F3E	# <CJK>
0xEA8E	0x9F4A	# <CJK>
0xEA8F	0x9F52	# <CJK>
0xEA90	0x9F54	# <CJK>
0xEA91	0x9F63	# <CJK>
0xEA92	0x9F5F	# <CJK>
0xEA93	0x9F60	# <CJK>
0xEA94	0x9F61	# <CJK>
0xEA95	0x9F66	# <CJK>
0xEA96	0x9F67	# <CJK>
0xEA97	0x9F6C	# <CJK>
0xEA98	0x9F6A	# <CJK>
0xEA99	0x9F77	# <CJK>
0xEA9A	0x9F72	# <CJK>
0xEA9B	0x9F76	# <CJK>
0xEA9C	0x9F95	# <CJK>
0xEA9D	0x9F9C	# <CJK>
0xEA9E	0x9FA0	# <CJK>
0xEA9F	0x582F	# <CJK>
0xEAA0	0x69C7	# <CJK>
0xEAA1	0x9059	# <CJK>
0xEAA2	0x7464	# <CJK>
0xEAA3	0x51DC	# <CJK>
0xEAA4	0x7199	# <CJK>
#
0xFD	0x00A9	# COPYRIGHT SIGN # Apple extra
0xFE	0x2122	# TRADE MARK SIGN # Apple extra
0xFF	0x2026	# HORIZONTAL ELLIPSIS # Apple extra. Changes mapping of MacOS-J 0x8163

##################
# Apple extensions
##################

0x8540	0x2460	# CIRCLED DIGIT ONE
0x8541	0x2461	# CIRCLED DIGIT TWO
0x8542	0x2462	# CIRCLED DIGIT THREE
0x8543	0x2463	# CIRCLED DIGIT FOUR
0x8544	0x2464	# CIRCLED DIGIT FIVE
0x8545	0x2465	# CIRCLED DIGIT SIX
0x8546	0x2466	# CIRCLED DIGIT SEVEN
0x8547	0x2467	# CIRCLED DIGIT EIGHT
0x8548	0x2468	# CIRCLED DIGIT NINE
0x8549	0x2469	# CIRCLED NUMBER TEN
0x854A	0x246A	# CIRCLED NUMBER ELEVEN
0x854B	0x246B	# CIRCLED NUMBER TWELVE
0x854C	0x246C	# CIRCLED NUMBER THIRTEEN
0x854D	0x246D	# CIRCLED NUMBER FOURTEEN
0x854E	0x246E	# CIRCLED NUMBER FIFTEEN
0x854F	0x246F	# CIRCLED NUMBER SIXTEEN
0x8550	0x2470	# CIRCLED NUMBER SEVENTEEN
0x8551	0x2471	# CIRCLED NUMBER EIGHTEEN
0x8552	0x2472	# CIRCLED NUMBER NINETEEN
0x8553	0x2473	# CIRCLED NUMBER TWENTY
0x855E	0x2474	# PARENTHESIZED DIGIT ONE
0x855F	0x2475	# PARENTHESIZED DIGIT TWO
0x8560	0x2476	# PARENTHESIZED DIGIT THREE
0x8561	0x2477	# PARENTHESIZED DIGIT FOUR
0x8562	0x2478	# PARENTHESIZED DIGIT FIVE
0x8563	0x2479	# PARENTHESIZED DIGIT SIX
0x8564	0x247A	# PARENTHESIZED DIGIT SEVEN
0x8565	0x247B	# PARENTHESIZED DIGIT EIGHT
0x8566	0x247C	# PARENTHESIZED DIGIT NINE
0x8567	0x247D	# PARENTHESIZED NUMBER TEN
0x8568	0x247E	# PARENTHESIZED NUMBER ELEVEN
0x8569	0x247F	# PARENTHESIZED NUMBER TWELVE
0x856A	0x2480	# PARENTHESIZED NUMBER THIRTEEN
0x856B	0x2481	# PARENTHESIZED NUMBER FOURTEEN
0x856C	0x2482	# PARENTHESIZED NUMBER FIFTEEN
0x856D	0x2483	# PARENTHESIZED NUMBER SIXTEEN
0x856E	0x2484	# PARENTHESIZED NUMBER SEVENTEEN
0x856F	0x2485	# PARENTHESIZED NUMBER EIGHTEEN
0x8570	0x2486	# PARENTHESIZED NUMBER NINETEEN
0x8571	0x2487	# PARENTHESIZED NUMBER TWENTY
0x857C	0x2776	# DINGBAT NEGATIVE CIRCLED DIGIT ONE
0x857D	0x2777	# DINGBAT NEGATIVE CIRCLED DIGIT TWO
0x857E	0x2778	# DINGBAT NEGATIVE CIRCLED DIGIT THREE
0x8580	0x2779	# DINGBAT NEGATIVE CIRCLED DIGIT FOUR
0x8581	0x277A	# DINGBAT NEGATIVE CIRCLED DIGIT FIVE
0x8582	0x277B	# DINGBAT NEGATIVE CIRCLED DIGIT SIX
0x8583	0x277C	# DINGBAT NEGATIVE CIRCLED DIGIT SEVEN
0x8584	0x277D	# DINGBAT NEGATIVE CIRCLED DIGIT EIGHT
0x8585	0x277E	# DINGBAT NEGATIVE CIRCLED DIGIT NINE
0x8591	0xF8A1	# digit zero full stop # 0.
0x8592	0x2488	# DIGIT ONE FULL STOP
0x8593	0x2489	# DIGIT TWO FULL STOP
0x8594	0x248A	# DIGIT THREE FULL STOP
0x8595	0x248B	# DIGIT FOUR FULL STOP
0x8596	0x248C	# DIGIT FIVE FULL STOP
0x8597	0x248D	# DIGIT SIX FULL STOP
0x8598	0x248E	# DIGIT SEVEN FULL STOP
0x8599	0x248F	# DIGIT EIGHT FULL STOP
0x859A	0x2490	# DIGIT NINE FULL STOP
0x859F	0x2160	# ROMAN NUMERAL ONE
0x85A0	0x2161	# ROMAN NUMERAL TWO
0x85A1	0x2162	# ROMAN NUMERAL THREE
0x85A2	0x2163	# ROMAN NUMERAL FOUR
0x85A3	0x2164	# ROMAN NUMERAL FIVE
0x85A4	0x2165	# ROMAN NUMERAL SIX
0x85A5	0x2166	# ROMAN NUMERAL SEVEN
0x85A6	0x2167	# ROMAN NUMERAL EIGHT
0x85A7	0x2168	# ROMAN NUMERAL NINE
0x85A8	0x2169	# ROMAN NUMERAL TEN
0x85A9	0x216A	# ROMAN NUMERAL ELEVEN
0x85AA	0x216B	# ROMAN NUMERAL TWELVE
0x85AB	0xF8A2	# roman numeral thirteen # XIII
0x85AC	0xF8A3	# roman numeral fourteen # XIV
0x85AD	0xF8A4	# roman numeral fifteen # XV
0x85B3	0x2170	# SMALL ROMAN NUMERAL ONE
0x85B4	0x2171	# SMALL ROMAN NUMERAL TWO
0x85B5	0x2172	# SMALL ROMAN NUMERAL THREE
0x85B6	0x2173	# SMALL ROMAN NUMERAL FOUR
0x85B7	0x2174	# SMALL ROMAN NUMERAL FIVE
0x85B8	0x2175	# SMALL ROMAN NUMERAL SIX
0x85B9	0x2176	# SMALL ROMAN NUMERAL SEVEN
0x85BA	0x2177	# SMALL ROMAN NUMERAL EIGHT
0x85BB	0x2178	# SMALL ROMAN NUMERAL NINE
0x85BC	0x2179	# SMALL ROMAN NUMERAL TEN
0x85BD	0x217A	# SMALL ROMAN NUMERAL ELEVEN
0x85BE	0x217B	# SMALL ROMAN NUMERAL TWELVE
0x85BF	0xF8A5	# small roman numeral thirteen # xiii
0x85C0	0xF8A6	# small roman numeral fourteen # xiv
0x85C1	0xF8A7	# small roman numeral fifteen # xv
0x85DB	0x249C	# PARENTHESIZED LATIN SMALL LETTER A
0x85DC	0x249D	# PARENTHESIZED LATIN SMALL LETTER B
0x85DD	0x249E	# PARENTHESIZED LATIN SMALL LETTER C
0x85DE	0x249F	# PARENTHESIZED LATIN SMALL LETTER D
0x85DF	0x24A0	# PARENTHESIZED LATIN SMALL LETTER E
0x85E0	0x24A1	# PARENTHESIZED LATIN SMALL LETTER F
0x85E1	0x24A2	# PARENTHESIZED LATIN SMALL LETTER G
0x85E2	0x24A3	# PARENTHESIZED LATIN SMALL LETTER H
0x85E3	0x24A4	# PARENTHESIZED LATIN SMALL LETTER I
0x85E4	0x24A5	# PARENTHESIZED LATIN SMALL LETTER J
0x85E5	0x24A6	# PARENTHESIZED LATIN SMALL LETTER K
0x85E6	0x24A7	# PARENTHESIZED LATIN SMALL LETTER L
0x85E7	0x24A8	# PARENTHESIZED LATIN SMALL LETTER M
0x85E8	0x24A9	# PARENTHESIZED LATIN SMALL LETTER N
0x85E9	0x24AA	# PARENTHESIZED LATIN SMALL LETTER O
0x85EA	0x24AB	# PARENTHESIZED LATIN SMALL LETTER P
0x85EB	0x24AC	# PARENTHESIZED LATIN SMALL LETTER Q
0x85EC	0x24AD	# PARENTHESIZED LATIN SMALL LETTER R
0x85ED	0x24AE	# PARENTHESIZED LATIN SMALL LETTER S
0x85EE	0x24AF	# PARENTHESIZED LATIN SMALL LETTER T
0x85EF	0x24B0	# PARENTHESIZED LATIN SMALL LETTER U
0x85F0	0x24B1	# PARENTHESIZED LATIN SMALL LETTER V
0x85F1	0x24B2	# PARENTHESIZED LATIN SMALL LETTER W
0x85F2	0x24B3	# PARENTHESIZED LATIN SMALL LETTER X
0x85F3	0x24B4	# PARENTHESIZED LATIN SMALL LETTER Y
0x85F4	0x24B5	# PARENTHESIZED LATIN SMALL LETTER Z
0x8640	0x339C	# SQUARE MM
0x8641	0x339F	# SQUARE MM SQUARED
0x8642	0x339D	# SQUARE CM
0x8643	0x33A0	# SQUARE CM SQUARED
0x8644	0x33A4	# SQUARE CM CUBED
0x8645	0xF8A8	# square m (meter?)
0x8646	0x33A1	# SQUARE M SQUARED
0x8647	0x33A5	# SQUARE M CUBED
0x8648	0x339E	# SQUARE KM
0x8649	0x33A2	# SQUARE KM SQUARED
0x864A	0x338E	# SQUARE MG
0x864B	0xF8A9	# square g (gram?)
0x864C	0x338F	# SQUARE KG
0x864D	0x33C4	# SQUARE CC
0x864E	0x3396	# SQUARE ML
0x864F	0x3397	# SQUARE DL
0x8650	0xF8AA	# square l (liter?) # not U+2113, SCRIPT SMALL L
0x8651	0x3398	# SQUARE KL
0x8652	0x33B3	# SQUARE MS
0x8653	0x33B2	# SQUARE MU S
0x8654	0x33B1	# SQUARE NS
0x8655	0x33B0	# SQUARE PS
0x8656	0x2109	# DEGREE FAHRENHEIT
0x8657	0x33D4	# SQUARE MB SMALL
0x8658	0x33CB	# SQUARE HP
0x8659	0x3390	# SQUARE HZ
0x865A	0x3385	# SQUARE KB
0x865B	0x3386	# SQUARE MB
0x865C	0x3387	# SQUARE GB
0x865D	0xF8AB	# square TB
0x869B	0x2116	# NUMERO SIGN
0x869C	0x33CD	# SQUARE KK
0x869D	0x2121	# TELEPHONE SIGN
0x869E	0xF8AC	# FAX sign
0x869F	0x2664	# WHITE SPADE SUIT
0x86A0	0x2667	# WHITE CLUB SUIT
0x86A1	0x2661	# WHITE HEART SUIT
0x86A2	0x2662	# WHITE DIAMOND SUIT
0x86A3	0x2660	# BLACK SPADE SUIT
0x86A4	0x2663	# BLACK CLUB SUIT
0x86A5	0x2665	# BLACK HEART SUIT
0x86A6	0x2666	# BLACK DIAMOND SUIT
0x86B3	0x3020	# POSTAL MARK FACE
0x86B4	0x260E	# BLACK TELEPHONE
0x86B5	0x3004	# JAPANESE INDUSTRIAL STANDARD SYMBOL
0x86C7	0x261E	# WHITE RIGHT POINTING INDEX
0x86C8	0x261C	# WHITE LEFT POINTING INDEX
0x86C9	0x261D	# WHITE UP POINTING INDEX
0x86CA	0x261F	# WHITE DOWN POINTING INDEX
0x86CB	0x21C6	# LEFTWARDS ARROW OVER RIGHTWARDS ARROW
0x86CC	0x21C4	# RIGHTWARDS ARROW OVER LEFTWARDS ARROW
0x86CD	0x21C5	# UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW
0x86CE	0xF8AD	# downwards arrow leftwards of upwards arrow
0x86CF	0x21E8	# RIGHTWARDS WHITE ARROW
0x86D0	0x21E6	# LEFTWARDS WHITE ARROW
0x86D1	0x21E7	# UPWARDS WHITE ARROW
0x86D2	0x21E9	# DOWNWARDS WHITE ARROW
0x86D3	0xF8AE	# rightwards black arrow # not U+279E, HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW
0x86D4	0xF8AF	# leftwards black arrow
0x86D5	0xF8B0	# upwards black arrow
0x86D6	0xF8B1	# downwards black arrow
0x8740	0x3230	# PARENTHESIZED IDEOGRAPH SUN
0x8741	0x322A	# PARENTHESIZED IDEOGRAPH MOON
0x8742	0x322B	# PARENTHESIZED IDEOGRAPH FIRE
0x8743	0x322C	# PARENTHESIZED IDEOGRAPH WATER
0x8744	0x322D	# PARENTHESIZED IDEOGRAPH WOOD
0x8745	0x322E	# PARENTHESIZED IDEOGRAPH METAL
0x8746	0x322F	# PARENTHESIZED IDEOGRAPH EARTH
0x8747	0x3240	# PARENTHESIZED IDEOGRAPH FESTIVAL
0x8748	0x3237	# PARENTHESIZED IDEOGRAPH CONGRATULATION
0x8749	0x3242	# PARENTHESIZED IDEOGRAPH SELF
0x874A	0x3243	# PARENTHESIZED IDEOGRAPH REACH
0x874B	0x3239	# PARENTHESIZED IDEOGRAPH REPRESENT
0x874C	0x323A	# PARENTHESIZED IDEOGRAPH CALL
0x874D	0x3231	# PARENTHESIZED IDEOGRAPH STOCK
0x874E	0x323E	# PARENTHESIZED IDEOGRAPH RESOURCE
0x874F	0x3234	# PARENTHESIZED IDEOGRAPH NAME
0x8750	0x3232	# PARENTHESIZED IDEOGRAPH HAVE
0x8751	0x323B	# PARENTHESIZED IDEOGRAPH STUDY
0x8752	0x3236	# PARENTHESIZED IDEOGRAPH FINANCIAL
0x8753	0x3233	# PARENTHESIZED IDEOGRAPH SOCIETY
0x8754	0x3235	# PARENTHESIZED IDEOGRAPH SPECIAL
0x8755	0x323C	# PARENTHESIZED IDEOGRAPH SUPERVISE
0x8756	0x323D	# PARENTHESIZED IDEOGRAPH ENTERPRISE
0x8757	0x323F	# PARENTHESIZED IDEOGRAPH ALLIANCE
0x8758	0x3238	# PARENTHESIZED IDEOGRAPH LABOR
0x8791	0x5927+0x20DD	# ideograph big + COMBINING ENCLOSING CIRCLE
0x8792	0x5C0F+0x20DD	# ideograph small + COMBINING ENCLOSING CIRCLE
0x8793	0x32A4	# CIRCLED IDEOGRAPH HIGH
0x8794	0x32A5	# CIRCLED IDEOGRAPH CENTRE
0x8795	0x32A6	# CIRCLED IDEOGRAPH LOW
0x8796	0x32A7	# CIRCLED IDEOGRAPH LEFT
0x8797	0x32A8	# CIRCLED IDEOGRAPH RIGHT
0x8798	0x32A9	# CIRCLED IDEOGRAPH MEDICINE
0x8799	0x3296	# CIRCLED IDEOGRAPH FINANCIAL
0x879A	0x329D	# CIRCLED IDEOGRAPH EXCELLENT
0x879B	0x3298	# CIRCLED IDEOGRAPH LABOR
0x879C	0x329E	# CIRCLED IDEOGRAPH PRINT
0x879D	0x63A7+0x20DD	# ideograph memo + COMBINING ENCLOSING CIRCLE
0x879E	0x3299	# CIRCLED IDEOGRAPH SECRET
0x879F	0x3349	# SQUARE MIRI
0x87A0	0x3322	# SQUARE SENTI
0x87A1	0x334D	# SQUARE MEETORU
0x87A2	0x3314	# SQUARE KIRO
0x87A3	0x3316	# SQUARE KIROMEETORU
0x87A4	0x3305	# SQUARE INTI
0x87A5	0x3333	# SQUARE HUIITO
0x87A6	0x334E	# SQUARE YAADO
0x87A7	0x3303	# SQUARE AARU
0x87A8	0x3336	# SQUARE HEKUTAARU
0x87A9	0x3318	# SQUARE GURAMU
0x87AA	0x3315	# SQUARE KIROGURAMU
0x87AB	0x3327	# SQUARE TON
0x87AC	0x3351	# SQUARE RITTORU
0x87AD	0x334A	# SQUARE MIRIBAARU
0x87AE	0x3339	# SQUARE HERUTU
0x87AF	0x3357	# SQUARE WATTO
0x87B0	0x330D	# SQUARE KARORII
0x87B1	0x3342	# SQUARE HOON
0x87B2	0x3323	# SQUARE SENTO
0x87B3	0x3326	# SQUARE DORU
0x87B4	0x333B	# SQUARE PEEZI
0x87B5	0x332B	# SQUARE PAASENTO
0x87BD	0x3300	# SQUARE APAATO
0x87BE	0x331E	# SQUARE KOOPO
0x87BF	0x332A	# SQUARE HAITU
0x87C0	0x3331	# SQUARE BIRU
0x87C1	0x3347	# SQUARE MANSYON
0x87E5	0x337E	# SQUARE ERA NAME MEIZI
0x87E6	0x337D	# SQUARE ERA NAME TAISYOU
0x87E7	0x337C	# SQUARE ERA NAME SYOUWA
0x87E8	0x337B	# SQUARE ERA NAME HEISEI
0x87FA	0x337F	# SQUARE CORPORATION
0x87FB	0xF8B2	# square "limited company, ltd. [yuugen gaisha]"
0x87FC	0xF8B3	# square "foundation [zaidan houjin]"
0x8840	0x222E	# CONTOUR INTEGRAL
0x8841	0x221F	# RIGHT ANGLE
0x8842	0x22BF	# RIGHT TRIANGLE
0x8854	0x301D	# REVERSED DOUBLE PRIME QUOTATION MARK
0x8855	0xF8B4	# inverted double prime quotation mark # paired with 0x8854; not U+301F, DOUBLE PRIME QUOTE MARK
0x8868	0x3094	# HIRAGANA LETTER VU
0x886A	0x30F7	# KATAKANA LETTER VA
0x886B	0x30F8	# KATAKANA LETTER VI
0x886C	0x30F9	# KATAKANA LETTER VE
0x886D	0x30FA	# KATAKANA LETTER VO

##################
# Vertical forms
##################
# Unicodes 0xF8B5-0xF8D6 are Apple corporate Unicode characters.
# Check U+FE32, I think this should be presentation form of katakana prolonged sound mark.
# If so, then we can map MacOS Japanese 0xEB5B to it instead of using a corporate char U+F8B8.
##################

0xEB41	0xF8B5	# presentation form for vertical IDEOGRAPHIC COMMA, U+3001
0xEB42	0xF8B6	# presentation form for vertical IDEOGRAPHIC FULL STOP, U+3002
0xEB50	0xF8B7	# presentation form for vertical OVERLINE, U+203E
0xEB51	0xFE33	# PRESENTATION FORM FOR VERTICAL LOW LINE, U+FF3F
0xEB5B	0xF8B8	# presentation form for vertical KATAKANA-HIRAGANA PROLONGED SOUND MARK, U+30FC # use corp char U+F8B8 until name for U+FE32 is fixed; should map to fixed U+FE32
0xEB5C	0xFE31	# PRESENTATION FORM FOR VERTICAL EM DASH, U+2014
0xEB5D	0xF8B9	# presentation form for vertical HYPHEN, U+2010
0xEB60	0xF8BA	# presentation form for vertical WAVE DASH, U+301C
0xEB61	0xF8BB	# presentation form for vertical DOUBLE VERTICAL LINE, U+2016
0xEB62	0xF8BC	# presentation form for vertical FULLWIDTH VERTICAL LINE, U+FF5C
0xEB63	0xF8BD	# presentation form for vertical MIDLINE HORIZONTAL ELLIPSIS, U+22EF
0xEB64	0xFE30	# PRESENTATION FORM FOR VERTICAL TWO DOT LEADER, U+2025
0xEB69	0xFE35	# PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS, U+FF08
0xEB6A	0xFE36	# PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS, U+FF09
0xEB6B	0xFE39	# PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET, U+3014
0xEB6C	0xFE3A	# PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET, U+3015
0xEB6D	0xF8BE	# presentation form for vertical FULLWIDTH LEFT SQUARE BRACKET, U+FF3B
0xEB6E	0xF8BF	# presentation form for vertical FULLWIDTH RIGHT SQUARE BRACKET, U+FF3D
0xEB6F	0xFE37	# PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET, U+FF5B
0xEB70	0xFE38	# PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET, U+FF5D
0xEB71	0xFE3F	# PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET, U+3008
0xEB72	0xFE40	# PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET, U+3009
0xEB73	0xFE3D	# PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET, U+300A
0xEB74	0xFE3E	# PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET, U+300B
0xEB75	0xFE41	# PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET, U+300C
0xEB76	0xFE42	# PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET, U+300D
0xEB77	0xFE43	# PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET, U+300E
0xEB78	0xFE44	# PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET, U+300F
0xEB79	0xFE3B	# PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET, U+3010
0xEB7A	0xFE3C	# PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET, U+3011
0xEB81	0xF8C0	# presentation form for vertical FULLWIDTH EQUALS SIGN, U+FF1D
0xEC9F	0xF8C1	# presentation form for vertical HIRAGANA LETTER SMALL A, U+3041
0xECA1	0xF8C2	# presentation form for vertical HIRAGANA LETTER SMALL I, U+3043
0xECA3	0xF8C3	# presentation form for vertical HIRAGANA LETTER SMALL U, U+3045
0xECA5	0xF8C4	# presentation form for vertical HIRAGANA LETTER SMALL E, U+3047
0xECA7	0xF8C5	# presentation form for vertical HIRAGANA LETTER SMALL O, U+3049
0xECC1	0xF8C6	# presentation form for vertical HIRAGANA LETTER SMALL TU, U+3063
0xECE1	0xF8C7	# presentation form for vertical HIRAGANA LETTER SMALL YA, U+3083
0xECE3	0xF8C8	# presentation form for vertical HIRAGANA LETTER SMALL YU, U+3085
0xECE5	0xF8C9	# presentation form for vertical HIRAGANA LETTER SMALL YO, U+3087
0xECEC	0xF8CA	# presentation form for vertical HIRAGANA LETTER SMALL WA, U+308E
0xED40	0xF8CB	# presentation form for vertical KATAKANA LETTER SMALL A, U+30A1
0xED42	0xF8CC	# presentation form for vertical KATAKANA LETTER SMALL I, U+30A3
0xED44	0xF8CD	# presentation form for vertical KATAKANA LETTER SMALL U, U+30A5
0xED46	0xF8CE	# presentation form for vertical KATAKANA LETTER SMALL E, U+30A7
0xED48	0xF8CF	# presentation form for vertical KATAKANA LETTER SMALL O, U+30A9
0xED62	0xF8D0	# presentation form for vertical KATAKANA LETTER SMALL TU, U+30C3
0xED83	0xF8D1	# presentation form for vertical KATAKANA LETTER SMALL YA, U+30E3
0xED85	0xF8D2	# presentation form for vertical KATAKANA LETTER SMALL YU, U+30E5
0xED87	0xF8D3	# presentation form for vertical KATAKANA LETTER SMALL YO, U+30E7
0xED8E	0xF8D4	# presentation form for vertical KATAKANA LETTER SMALL WA, U+30EE
0xED95	0xF8D5	# presentation form for vertical KATAKANA LETTER SMALL KA, U+30F5
0xED96	0xF8D6	# presentation form for vertical KATAKANA LETTER SMALL KE, U+30F6

Added tools/encoding/macRoman.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
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
#
#   Name:             MacOS_Roman [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <9>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Roman code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Roman code order.
#
#   One of these mappings requires the use of a corporate character
#   (for the Apple logo character). See the file "MacOS-CorpCharList".
#   NOTE: The graphic image associated with the Apple logo character
#   is not authorized for use without permission of Apple, and
#   unauthorized use might constitute trademark infringement.
#
#   Notes on MacOS Roman:
#   ---------------------
#
#   This character set is used for at least the following MacOS
#   localizations: U.S., British, Canadian French, French, Swiss
#   French, German, Swiss German, Italian, Swiss Italian, Dutch,
#   Swedish, Norwegian, Danish, Finnish, Spanish, Catalan,
#   Portuguese, Brazilian, and the default International system.
#
#   Variants of MacRoman are used for Croatian, Icelandic,
#   Turkish, and Romanian. Separate mapping tables are available
#   for these encodings.
#
#   At least through System 7.5, the bitmap versions of the fonts
#   Chicago, New York, Geneva, and Monaco do not implement the
#   full Roman character set; they only support MacOS Roman character
#   codes up to 0xD8. The TrueType versions of these fonts do
#   implement the full character set, as do both the bitmap and
#   TrueType versions of the other standard Roman fonts.
#
#   In all MacOS encodings, fonts such as Chicago which are used
#   as "system" fonts (for menus, dialogs, etc.) have four glyphs
#   at code points 0x11-0x14 for transient use by the Menu Manager.
#   These glyphs are not intended as characters for use in normal
#   text, and the associated code points are not generally
#   interpreted as associated with these glyphs; they are usually
#   interpreted (if at all) as the control codes DC1-DC4.
#
##################

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
#
0x80	0x00C4	# LATIN CAPITAL LETTER A WITH DIAERESIS
0x81	0x00C5	# LATIN CAPITAL LETTER A WITH RING ABOVE
0x82	0x00C7	# LATIN CAPITAL LETTER C WITH CEDILLA
0x83	0x00C9	# LATIN CAPITAL LETTER E WITH ACUTE
0x84	0x00D1	# LATIN CAPITAL LETTER N WITH TILDE
0x85	0x00D6	# LATIN CAPITAL LETTER O WITH DIAERESIS
0x86	0x00DC	# LATIN CAPITAL LETTER U WITH DIAERESIS
0x87	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
0x88	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
0x89	0x00E2	# LATIN SMALL LETTER A WITH CIRCUMFLEX
0x8A	0x00E4	# LATIN SMALL LETTER A WITH DIAERESIS
0x8B	0x00E3	# LATIN SMALL LETTER A WITH TILDE
0x8C	0x00E5	# LATIN SMALL LETTER A WITH RING ABOVE
0x8D	0x00E7	# LATIN SMALL LETTER C WITH CEDILLA
0x8E	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
0x8F	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
0x90	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
0x91	0x00EB	# LATIN SMALL LETTER E WITH DIAERESIS
0x92	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
0x93	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
0x94	0x00EE	# LATIN SMALL LETTER I WITH CIRCUMFLEX
0x95	0x00EF	# LATIN SMALL LETTER I WITH DIAERESIS
0x96	0x00F1	# LATIN SMALL LETTER N WITH TILDE
0x97	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
0x98	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
0x99	0x00F4	# LATIN SMALL LETTER O WITH CIRCUMFLEX
0x9A	0x00F6	# LATIN SMALL LETTER O WITH DIAERESIS
0x9B	0x00F5	# LATIN SMALL LETTER O WITH TILDE
0x9C	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
0x9D	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
0x9E	0x00FB	# LATIN SMALL LETTER U WITH CIRCUMFLEX
0x9F	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
0xA0	0x2020	# DAGGER
0xA1	0x00B0	# DEGREE SIGN
0xA2	0x00A2	# CENT SIGN
0xA3	0x00A3	# POUND SIGN
0xA4	0x00A7	# SECTION SIGN
0xA5	0x2022	# BULLET
0xA6	0x00B6	# PILCROW SIGN
0xA7	0x00DF	# LATIN SMALL LETTER SHARP S
0xA8	0x00AE	# REGISTERED SIGN
0xA9	0x00A9	# COPYRIGHT SIGN
0xAA	0x2122	# TRADE MARK SIGN
0xAB	0x00B4	# ACUTE ACCENT
0xAC	0x00A8	# DIAERESIS
0xAD	0x2260	# NOT EQUAL TO
0xAE	0x00C6	# LATIN CAPITAL LIGATURE AE
0xAF	0x00D8	# LATIN CAPITAL LETTER O WITH STROKE
0xB0	0x221E	# INFINITY
0xB1	0x00B1	# PLUS-MINUS SIGN
0xB2	0x2264	# LESS-THAN OR EQUAL TO
0xB3	0x2265	# GREATER-THAN OR EQUAL TO
0xB4	0x00A5	# YEN SIGN
0xB5	0x00B5	# MICRO SIGN
0xB6	0x2202	# PARTIAL DIFFERENTIAL
0xB7	0x2211	# N-ARY SUMMATION
0xB8	0x220F	# N-ARY PRODUCT
0xB9	0x03C0	# GREEK SMALL LETTER PI
0xBA	0x222B	# INTEGRAL
0xBB	0x00AA	# FEMININE ORDINAL INDICATOR
0xBC	0x00BA	# MASCULINE ORDINAL INDICATOR
0xBD	0x2126	# OHM SIGN
0xBE	0x00E6	# LATIN SMALL LIGATURE AE
0xBF	0x00F8	# LATIN SMALL LETTER O WITH STROKE
0xC0	0x00BF	# INVERTED QUESTION MARK
0xC1	0x00A1	# INVERTED EXCLAMATION MARK
0xC2	0x00AC	# NOT SIGN
0xC3	0x221A	# SQUARE ROOT
0xC4	0x0192	# LATIN SMALL LETTER F WITH HOOK
0xC5	0x2248	# ALMOST EQUAL TO
0xC6	0x2206	# INCREMENT
0xC7	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC8	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC9	0x2026	# HORIZONTAL ELLIPSIS
0xCA	0x00A0	# NO-BREAK SPACE
0xCB	0x00C0	# LATIN CAPITAL LETTER A WITH GRAVE
0xCC	0x00C3	# LATIN CAPITAL LETTER A WITH TILDE
0xCD	0x00D5	# LATIN CAPITAL LETTER O WITH TILDE
0xCE	0x0152	# LATIN CAPITAL LIGATURE OE
0xCF	0x0153	# LATIN SMALL LIGATURE OE
0xD0	0x2013	# EN DASH
0xD1	0x2014	# EM DASH
0xD2	0x201C	# LEFT DOUBLE QUOTATION MARK
0xD3	0x201D	# RIGHT DOUBLE QUOTATION MARK
0xD4	0x2018	# LEFT SINGLE QUOTATION MARK
0xD5	0x2019	# RIGHT SINGLE QUOTATION MARK
0xD6	0x00F7	# DIVISION SIGN
0xD7	0x25CA	# LOZENGE
0xD8	0x00FF	# LATIN SMALL LETTER Y WITH DIAERESIS
0xD9	0x0178	# LATIN CAPITAL LETTER Y WITH DIAERESIS
0xDA	0x2044	# FRACTION SLASH
0xDB	0x00A4	# CURRENCY SIGN
0xDC	0x2039	# SINGLE LEFT-POINTING ANGLE QUOTATION MARK
0xDD	0x203A	# SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
0xDE	0xFB01	# LATIN SMALL LIGATURE FI
0xDF	0xFB02	# LATIN SMALL LIGATURE FL
0xE0	0x2021	# DOUBLE DAGGER
0xE1	0x00B7	# MIDDLE DOT
0xE2	0x201A	# SINGLE LOW-9 QUOTATION MARK
0xE3	0x201E	# DOUBLE LOW-9 QUOTATION MARK
0xE4	0x2030	# PER MILLE SIGN
0xE5	0x00C2	# LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xE6	0x00CA	# LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xE7	0x00C1	# LATIN CAPITAL LETTER A WITH ACUTE
0xE8	0x00CB	# LATIN CAPITAL LETTER E WITH DIAERESIS
0xE9	0x00C8	# LATIN CAPITAL LETTER E WITH GRAVE
0xEA	0x00CD	# LATIN CAPITAL LETTER I WITH ACUTE
0xEB	0x00CE	# LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xEC	0x00CF	# LATIN CAPITAL LETTER I WITH DIAERESIS
0xED	0x00CC	# LATIN CAPITAL LETTER I WITH GRAVE
0xEE	0x00D3	# LATIN CAPITAL LETTER O WITH ACUTE
0xEF	0x00D4	# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xF0	0xF8FF	# Apple logo
0xF1	0x00D2	# LATIN CAPITAL LETTER O WITH GRAVE
0xF2	0x00DA	# LATIN CAPITAL LETTER U WITH ACUTE
0xF3	0x00DB	# LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xF4	0x00D9	# LATIN CAPITAL LETTER U WITH GRAVE
0xF5	0x0131	# LATIN SMALL LETTER DOTLESS I
0xF6	0x02C6	# MODIFIER LETTER CIRCUMFLEX ACCENT
0xF7	0x02DC	# SMALL TILDE
0xF8	0x00AF	# MACRON
0xF9	0x02D8	# BREVE
0xFA	0x02D9	# DOT ABOVE
0xFB	0x02DA	# RING ABOVE
0xFC	0x00B8	# CEDILLA
0xFD	0x02DD	# DOUBLE ACUTE ACCENT
0xFE	0x02DB	# OGONEK
0xFF	0x02C7	# CARON

Added tools/encoding/macRomania.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#
#   Name:             MacOS_Romanian [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <4>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Romanian code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Romanian code order.
#
#   One of these mappings requires the use of a corporate character
#   (for the Apple logo character). See the file "MacOS-CorpCharList".
#   NOTE: The graphic image associated with the Apple logo character
#   is not authorized for use without permission of Apple, and
#   unauthorized use might constitute trademark infringement.
#
#   Notes on MacOS Romanian:
#   ------------------------
#
#   The MacOS Romanian encoding shares the script code smRoman
#   (0) with the standard MacOS Roman encoding. To determine if
#   the Romanian encoding is being used, you must also check if the
#   system region code is 39, verRomania.
#
#   This character set is a variant of standard MacOS Roman, adding
#   upper and lower A breve, S cedilla, and T cedilla. It has 6 code
#   point differences from standard Roman.
#
##################

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
#
0x80	0x00C4	# LATIN CAPITAL LETTER A WITH DIAERESIS
0x81	0x00C5	# LATIN CAPITAL LETTER A WITH RING ABOVE
0x82	0x00C7	# LATIN CAPITAL LETTER C WITH CEDILLA
0x83	0x00C9	# LATIN CAPITAL LETTER E WITH ACUTE
0x84	0x00D1	# LATIN CAPITAL LETTER N WITH TILDE
0x85	0x00D6	# LATIN CAPITAL LETTER O WITH DIAERESIS
0x86	0x00DC	# LATIN CAPITAL LETTER U WITH DIAERESIS
0x87	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
0x88	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
0x89	0x00E2	# LATIN SMALL LETTER A WITH CIRCUMFLEX
0x8A	0x00E4	# LATIN SMALL LETTER A WITH DIAERESIS
0x8B	0x00E3	# LATIN SMALL LETTER A WITH TILDE
0x8C	0x00E5	# LATIN SMALL LETTER A WITH RING ABOVE
0x8D	0x00E7	# LATIN SMALL LETTER C WITH CEDILLA
0x8E	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
0x8F	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
0x90	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
0x91	0x00EB	# LATIN SMALL LETTER E WITH DIAERESIS
0x92	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
0x93	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
0x94	0x00EE	# LATIN SMALL LETTER I WITH CIRCUMFLEX
0x95	0x00EF	# LATIN SMALL LETTER I WITH DIAERESIS
0x96	0x00F1	# LATIN SMALL LETTER N WITH TILDE
0x97	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
0x98	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
0x99	0x00F4	# LATIN SMALL LETTER O WITH CIRCUMFLEX
0x9A	0x00F6	# LATIN SMALL LETTER O WITH DIAERESIS
0x9B	0x00F5	# LATIN SMALL LETTER O WITH TILDE
0x9C	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
0x9D	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
0x9E	0x00FB	# LATIN SMALL LETTER U WITH CIRCUMFLEX
0x9F	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
0xA0	0x2020	# DAGGER
0xA1	0x00B0	# DEGREE SIGN
0xA2	0x00A2	# CENT SIGN
0xA3	0x00A3	# POUND SIGN
0xA4	0x00A7	# SECTION SIGN
0xA5	0x2022	# BULLET
0xA6	0x00B6	# PILCROW SIGN
0xA7	0x00DF	# LATIN SMALL LETTER SHARP S
0xA8	0x00AE	# REGISTERED SIGN
0xA9	0x00A9	# COPYRIGHT SIGN
0xAA	0x2122	# TRADE MARK SIGN
0xAB	0x00B4	# ACUTE ACCENT
0xAC	0x00A8	# DIAERESIS
0xAD	0x2260	# NOT EQUAL TO
0xAE	0x0102	# LATIN CAPITAL LETTER A WITH BREVE
0xAF	0x015E	# LATIN CAPITAL LETTER S WITH CEDILLA
0xB0	0x221E	# INFINITY
0xB1	0x00B1	# PLUS-MINUS SIGN
0xB2	0x2264	# LESS-THAN OR EQUAL TO
0xB3	0x2265	# GREATER-THAN OR EQUAL TO
0xB4	0x00A5	# YEN SIGN
0xB5	0x00B5	# MICRO SIGN
0xB6	0x2202	# PARTIAL DIFFERENTIAL
0xB7	0x2211	# N-ARY SUMMATION
0xB8	0x220F	# N-ARY PRODUCT
0xB9	0x03C0	# GREEK SMALL LETTER PI
0xBA	0x222B	# INTEGRAL
0xBB	0x00AA	# FEMININE ORDINAL INDICATOR
0xBC	0x00BA	# MASCULINE ORDINAL INDICATOR
0xBD	0x2126	# OHM SIGN
0xBE	0x0103	# LATIN SMALL LETTER A WITH BREVE
0xBF	0x015F	# LATIN SMALL LETTER S WITH CEDILLA
0xC0	0x00BF	# INVERTED QUESTION MARK
0xC1	0x00A1	# INVERTED EXCLAMATION MARK
0xC2	0x00AC	# NOT SIGN
0xC3	0x221A	# SQUARE ROOT
0xC4	0x0192	# LATIN SMALL LETTER F WITH HOOK
0xC5	0x2248	# ALMOST EQUAL TO
0xC6	0x2206	# INCREMENT
0xC7	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC8	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC9	0x2026	# HORIZONTAL ELLIPSIS
0xCA	0x00A0	# NO-BREAK SPACE
0xCB	0x00C0	# LATIN CAPITAL LETTER A WITH GRAVE
0xCC	0x00C3	# LATIN CAPITAL LETTER A WITH TILDE
0xCD	0x00D5	# LATIN CAPITAL LETTER O WITH TILDE
0xCE	0x0152	# LATIN CAPITAL LIGATURE OE
0xCF	0x0153	# LATIN SMALL LIGATURE OE
0xD0	0x2013	# EN DASH
0xD1	0x2014	# EM DASH
0xD2	0x201C	# LEFT DOUBLE QUOTATION MARK
0xD3	0x201D	# RIGHT DOUBLE QUOTATION MARK
0xD4	0x2018	# LEFT SINGLE QUOTATION MARK
0xD5	0x2019	# RIGHT SINGLE QUOTATION MARK
0xD6	0x00F7	# DIVISION SIGN
0xD7	0x25CA	# LOZENGE
0xD8	0x00FF	# LATIN SMALL LETTER Y WITH DIAERESIS
0xD9	0x0178	# LATIN CAPITAL LETTER Y WITH DIAERESIS
0xDA	0x2044	# FRACTION SLASH
0xDB	0x00A4	# CURRENCY SIGN
0xDC	0x2039	# SINGLE LEFT-POINTING ANGLE QUOTATION MARK
0xDD	0x203A	# SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
0xDE	0x0162	# LATIN CAPITAL LETTER T WITH CEDILLA
0xDF	0x0163	# LATIN SMALL LETTER T WITH CEDILLA
0xE0	0x2021	# DOUBLE DAGGER
0xE1	0x00B7	# MIDDLE DOT
0xE2	0x201A	# SINGLE LOW-9 QUOTATION MARK
0xE3	0x201E	# DOUBLE LOW-9 QUOTATION MARK
0xE4	0x2030	# PER MILLE SIGN
0xE5	0x00C2	# LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xE6	0x00CA	# LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xE7	0x00C1	# LATIN CAPITAL LETTER A WITH ACUTE
0xE8	0x00CB	# LATIN CAPITAL LETTER E WITH DIAERESIS
0xE9	0x00C8	# LATIN CAPITAL LETTER E WITH GRAVE
0xEA	0x00CD	# LATIN CAPITAL LETTER I WITH ACUTE
0xEB	0x00CE	# LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xEC	0x00CF	# LATIN CAPITAL LETTER I WITH DIAERESIS
0xED	0x00CC	# LATIN CAPITAL LETTER I WITH GRAVE
0xEE	0x00D3	# LATIN CAPITAL LETTER O WITH ACUTE
0xEF	0x00D4	# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xF0	0xF8FF	# Apple logo
0xF1	0x00D2	# LATIN CAPITAL LETTER O WITH GRAVE
0xF2	0x00DA	# LATIN CAPITAL LETTER U WITH ACUTE
0xF3	0x00DB	# LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xF4	0x00D9	# LATIN CAPITAL LETTER U WITH GRAVE
0xF5	0x0131	# LATIN SMALL LETTER DOTLESS I
0xF6	0x02C6	# MODIFIER LETTER CIRCUMFLEX ACCENT
0xF7	0x02DC	# SMALL TILDE
0xF8	0x00AF	# MACRON
0xF9	0x02D8	# BREVE
0xFA	0x02D9	# DOT ABOVE
0xFB	0x02DA	# RING ABOVE
0xFC	0x00B8	# CEDILLA
0xFD	0x02DD	# DOUBLE ACUTE ACCENT
0xFE	0x02DB	# OGONEK
0xFF	0x02C7	# CARON

Added tools/encoding/macThai.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
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
#
#   Name:             MacOS_Thai [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <6>)
#   Date:             17 November 1995
#   Authors:          Peter Edberg <[email protected]>
#                     Judy Kettenhofen
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Thai code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Thai code order.
#
#   Notes on MacOS Thai:
#   --------------------
#
#   Codes 0xA1-0xDA and 0xDF-0xFB are the character set from Thai
#   standard TIS 620-2533, except that the following changes are
#   made:
#     0xEE is TRADE MARK SIGN (instead of THAI CHARACTER YAMAKKAN)
#     0xFA is REGISTERED SIGN (instead of THAI CHARACTER ANGKHANKHU)
#     0xFB is COPYRIGHT SIGN (instead of THAI CHARACTER KHOMUT)
#
#   Codes 0x80-0x82, 0x8D-0x8E, 0x91, 0x9D-0x9E, and 0xDB-0xDE are
#   various additional punctuation marks (e.g. curly quotes,
#   ellipsis), no-break space, and two special characters "word join"
#   and "word break".
#
#   Codes 0x83-0x8C, 0x8F, and 0x92-0x9C are for positional variants
#   of the upper vowels, tone marks, and other signs at 0xD1,
#   0xD4-0xD7, and 0xE7-0xED. The positional variants would normally
#   be considered presentation forms only and not characters. In most
#   cases they are not typed directly; they are selected automatically
#   at display time by the WorldScript software. However, using the
#   Thai-DTP keyboard, the presentation forms can in fact be typed
#   directly using dead keys. Thus they must be treated as real
#   characters in the MacOS Thai encoding, and  must be mapped to
#   distinct Unicodes - corporate-zone characters in this case - to
#   enable roundtrip mapping.
#
#   Several code points are undefined and unused (they cannot be
#   typed using any of the Mac OS Thai keyboard layouts): 0x90, 0x9F,
#   0xFC-0xFE. In the table below these are mapped to 0xFFFD.
#
##################

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
#
0x80	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0x81	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0x82	0x2026	# HORIZONTAL ELLIPSIS
0x83	0xF88C	# form for THAI CHARACTER MAI EK, low left position
0x84	0xF88F	# form for THAI CHARACTER MAI THO, low left position
0x85	0xF892	# form for THAI CHARACTER MAI TRI, low left position
0x86	0xF895	# form for THAI CHARACTER MAI CHATTAWA, low left position
0x87	0xF898	# form for THAI CHARACTER THANTHAKHAT, low left position
0x88	0xF88B	# form for THAI CHARACTER MAI EK, low position
0x89	0xF88E	# form for THAI CHARACTER MAI THO, low position
0x8A	0xF891	# form for THAI CHARACTER MAI TRI, low position
0x8B	0xF894	# form for THAI CHARACTER MAI CHATTAWA, low position
0x8C	0xF897	# form for THAI CHARACTER THANTHAKHAT, low position
0x8D	0x201C	# LEFT DOUBLE QUOTATION MARK
0x8E	0x201D	# RIGHT DOUBLE QUOTATION MARK
0x8F	0xF899	# form for THAI CHARACTER NIKHAHIT, left position
0x90	0xFFFD	# (not used, map to Unicode replacement character)
0x91	0x2022	# BULLET
0x92	0xF884	# form for THAI CHARACTER MAI HAN-AKAT, left position
0x93	0xF889	# form for THAI CHARACTER MAITAIKHU, left position
0x94	0xF885	# form for THAI CHARACTER SARA I, left position
0x95	0xF886	# form for THAI CHARACTER SARA II, left position
0x96	0xF887	# form for THAI CHARACTER SARA UE, left position
0x97	0xF888	# form for THAI CHARACTER SARA UEE, left position
0x98	0xF88A	# form for THAI CHARACTER MAI EK, left position
0x99	0xF88D	# form for THAI CHARACTER MAI THO, left position
0x9A	0xF890	# form for THAI CHARACTER MAI TRI, left position
0x9B	0xF893	# form for THAI CHARACTER MAI CHATTAWA, left position
0x9C	0xF896	# form for THAI CHARACTER THANTHAKHAT, left position
0x9D	0x2018	# LEFT SINGLE QUOTATION MARK
0x9E	0x2019	# RIGHT SINGLE QUOTATION MARK
0x9F	0xFFFD	# (not used, map to Unicode replacement character)
0xA0	0x00A0	# NO-BREAK SPACE
0xA1	0x0E01	# THAI CHARACTER KO KAI
0xA2	0x0E02	# THAI CHARACTER KHO KHAI
0xA3	0x0E03	# THAI CHARACTER KHO KHUAT
0xA4	0x0E04	# THAI CHARACTER KHO KHWAI
0xA5	0x0E05	# THAI CHARACTER KHO KHON
0xA6	0x0E06	# THAI CHARACTER KHO RAKHANG
0xA7	0x0E07	# THAI CHARACTER NGO NGU
0xA8	0x0E08	# THAI CHARACTER CHO CHAN
0xA9	0x0E09	# THAI CHARACTER CHO CHING
0xAA	0x0E0A	# THAI CHARACTER CHO CHANG
0xAB	0x0E0B	# THAI CHARACTER SO SO
0xAC	0x0E0C	# THAI CHARACTER CHO CHOE
0xAD	0x0E0D	# THAI CHARACTER YO YING
0xAE	0x0E0E	# THAI CHARACTER DO CHADA
0xAF	0x0E0F	# THAI CHARACTER TO PATAK
0xB0	0x0E10	# THAI CHARACTER THO THAN
0xB1	0x0E11	# THAI CHARACTER THO NANGMONTHO
0xB2	0x0E12	# THAI CHARACTER THO PHUTHAO
0xB3	0x0E13	# THAI CHARACTER NO NEN
0xB4	0x0E14	# THAI CHARACTER DO DEK
0xB5	0x0E15	# THAI CHARACTER TO TAO
0xB6	0x0E16	# THAI CHARACTER THO THUNG
0xB7	0x0E17	# THAI CHARACTER THO THAHAN
0xB8	0x0E18	# THAI CHARACTER THO THONG
0xB9	0x0E19	# THAI CHARACTER NO NU
0xBA	0x0E1A	# THAI CHARACTER BO BAIMAI
0xBB	0x0E1B	# THAI CHARACTER PO PLA
0xBC	0x0E1C	# THAI CHARACTER PHO PHUNG
0xBD	0x0E1D	# THAI CHARACTER FO FA
0xBE	0x0E1E	# THAI CHARACTER PHO PHAN
0xBF	0x0E1F	# THAI CHARACTER FO FAN
0xC0	0x0E20	# THAI CHARACTER PHO SAMPHAO
0xC1	0x0E21	# THAI CHARACTER MO MA
0xC2	0x0E22	# THAI CHARACTER YO YAK
0xC3	0x0E23	# THAI CHARACTER RO RUA
0xC4	0x0E24	# THAI CHARACTER RU
0xC5	0x0E25	# THAI CHARACTER LO LING
0xC6	0x0E26	# THAI CHARACTER LU
0xC7	0x0E27	# THAI CHARACTER WO WAEN
0xC8	0x0E28	# THAI CHARACTER SO SALA
0xC9	0x0E29	# THAI CHARACTER SO RUSI
0xCA	0x0E2A	# THAI CHARACTER SO SUA
0xCB	0x0E2B	# THAI CHARACTER HO HIP
0xCC	0x0E2C	# THAI CHARACTER LO CHULA
0xCD	0x0E2D	# THAI CHARACTER O ANG
0xCE	0x0E2E	# THAI CHARACTER HO NOKHUK
0xCF	0x0E2F	# THAI CHARACTER PAIYANNOI
0xD0	0x0E30	# THAI CHARACTER SARA A
0xD1	0x0E31	# THAI CHARACTER MAI HAN-AKAT
0xD2	0x0E32	# THAI CHARACTER SARA AA
0xD3	0x0E33	# THAI CHARACTER SARA AM
0xD4	0x0E34	# THAI CHARACTER SARA I
0xD5	0x0E35	# THAI CHARACTER SARA II
0xD6	0x0E36	# THAI CHARACTER SARA UE
0xD7	0x0E37	# THAI CHARACTER SARA UEE
0xD8	0x0E38	# THAI CHARACTER SARA U
0xD9	0x0E39	# THAI CHARACTER SARA UU
0xDA	0x0E3A	# THAI CHARACTER PHINTHU
0xDB	0xFEFF	# ZERO WIDTH NO-BREAK SPACE
0xDC	0x200B	# ZERO WIDTH SPACE
0xDD	0x2013	# EN DASH
0xDE	0x2014	# EM DASH
0xDF	0x0E3F	# THAI CURRENCY SYMBOL BAHT
0xE0	0x0E40	# THAI CHARACTER SARA E
0xE1	0x0E41	# THAI CHARACTER SARA AE
0xE2	0x0E42	# THAI CHARACTER SARA O
0xE3	0x0E43	# THAI CHARACTER SARA AI MAIMUAN
0xE4	0x0E44	# THAI CHARACTER SARA AI MAIMALAI
0xE5	0x0E45	# THAI CHARACTER LAKKHANGYAO
0xE6	0x0E46	# THAI CHARACTER MAIYAMOK
0xE7	0x0E47	# THAI CHARACTER MAITAIKHU
0xE8	0x0E48	# THAI CHARACTER MAI EK
0xE9	0x0E49	# THAI CHARACTER MAI THO
0xEA	0x0E4A	# THAI CHARACTER MAI TRI
0xEB	0x0E4B	# THAI CHARACTER MAI CHATTAWA
0xEC	0x0E4C	# THAI CHARACTER THANTHAKHAT
0xED	0x0E4D	# THAI CHARACTER NIKHAHIT
0xEE	0x2122	# TRADE MARK SIGN
0xEF	0x0E4F	# THAI CHARACTER FONGMAN
0xF0	0x0E50	# THAI DIGIT ZERO
0xF1	0x0E51	# THAI DIGIT ONE
0xF2	0x0E52	# THAI DIGIT TWO
0xF3	0x0E53	# THAI DIGIT THREE
0xF4	0x0E54	# THAI DIGIT FOUR
0xF5	0x0E55	# THAI DIGIT FIVE
0xF6	0x0E56	# THAI DIGIT SIX
0xF7	0x0E57	# THAI DIGIT SEVEN
0xF8	0x0E58	# THAI DIGIT EIGHT
0xF9	0x0E59	# THAI DIGIT NINE
0xFA	0x00AE	# REGISTERED SIGN
0xFB	0x00A9	# COPYRIGHT SIGN
0xFC	0xFFFD	# (not used, map to Unicode replacement character)
0xFD	0xFFFD	# (not used, map to Unicode replacement character)
0xFE	0xFFFD	# (not used, map to Unicode replacement character)
0xFF	0xFFFD	# (not used, map to Unicode replacement character)

Added tools/encoding/macTurkish.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
#
#   Name:             MacOS_Turkish [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <4>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Turkish code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Turkish code order.
#
#   Two of these mappings requires the use of a corporate character:
#   for the Apple logo character, and for the one undefined code
#   point. See the file "MacOS-CorpCharList".
#   NOTE: The graphic image associated with the Apple logo character
#   is not authorized for use without permission of Apple, and
#   unauthorized use might constitute trademark infringement.
#
#   Notes on MacOS Turkish:
#   -----------------------
#
#   The MacOS Turkish encoding shares the script code smRoman
#   (0) with the standard MacOS Roman encoding. To determine if
#   the Turkish encoding is being used, you must also check if the
#   system region code is 24, verTurkey.
#
#   This character set is a variant of standard MacOS Roman. It adds
#   upper & lower G with breve, upper & lower S with cedilla, upper I
#   with dot, and moves the dotless lower i from its position at 0xF5
#   in standard MacOS Roman to a position at 0xDD here (leaving the
#   0xF5 code point undefined in MacTurkish). This gives a total of 7
#   code point differences from standard MacOS Roman.
#
##################

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
#
0x80	0x00C4	# LATIN CAPITAL LETTER A WITH DIAERESIS
0x81	0x00C5	# LATIN CAPITAL LETTER A WITH RING ABOVE
0x82	0x00C7	# LATIN CAPITAL LETTER C WITH CEDILLA
0x83	0x00C9	# LATIN CAPITAL LETTER E WITH ACUTE
0x84	0x00D1	# LATIN CAPITAL LETTER N WITH TILDE
0x85	0x00D6	# LATIN CAPITAL LETTER O WITH DIAERESIS
0x86	0x00DC	# LATIN CAPITAL LETTER U WITH DIAERESIS
0x87	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
0x88	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
0x89	0x00E2	# LATIN SMALL LETTER A WITH CIRCUMFLEX
0x8A	0x00E4	# LATIN SMALL LETTER A WITH DIAERESIS
0x8B	0x00E3	# LATIN SMALL LETTER A WITH TILDE
0x8C	0x00E5	# LATIN SMALL LETTER A WITH RING ABOVE
0x8D	0x00E7	# LATIN SMALL LETTER C WITH CEDILLA
0x8E	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
0x8F	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
0x90	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
0x91	0x00EB	# LATIN SMALL LETTER E WITH DIAERESIS
0x92	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
0x93	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
0x94	0x00EE	# LATIN SMALL LETTER I WITH CIRCUMFLEX
0x95	0x00EF	# LATIN SMALL LETTER I WITH DIAERESIS
0x96	0x00F1	# LATIN SMALL LETTER N WITH TILDE
0x97	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
0x98	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
0x99	0x00F4	# LATIN SMALL LETTER O WITH CIRCUMFLEX
0x9A	0x00F6	# LATIN SMALL LETTER O WITH DIAERESIS
0x9B	0x00F5	# LATIN SMALL LETTER O WITH TILDE
0x9C	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
0x9D	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
0x9E	0x00FB	# LATIN SMALL LETTER U WITH CIRCUMFLEX
0x9F	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
0xA0	0x2020	# DAGGER
0xA1	0x00B0	# DEGREE SIGN
0xA2	0x00A2	# CENT SIGN
0xA3	0x00A3	# POUND SIGN
0xA4	0x00A7	# SECTION SIGN
0xA5	0x2022	# BULLET
0xA6	0x00B6	# PILCROW SIGN
0xA7	0x00DF	# LATIN SMALL LETTER SHARP S
0xA8	0x00AE	# REGISTERED SIGN
0xA9	0x00A9	# COPYRIGHT SIGN
0xAA	0x2122	# TRADE MARK SIGN
0xAB	0x00B4	# ACUTE ACCENT
0xAC	0x00A8	# DIAERESIS
0xAD	0x2260	# NOT EQUAL TO
0xAE	0x00C6	# LATIN CAPITAL LIGATURE AE
0xAF	0x00D8	# LATIN CAPITAL LETTER O WITH STROKE
0xB0	0x221E	# INFINITY
0xB1	0x00B1	# PLUS-MINUS SIGN
0xB2	0x2264	# LESS-THAN OR EQUAL TO
0xB3	0x2265	# GREATER-THAN OR EQUAL TO
0xB4	0x00A5	# YEN SIGN
0xB5	0x00B5	# MICRO SIGN
0xB6	0x2202	# PARTIAL DIFFERENTIAL
0xB7	0x2211	# N-ARY SUMMATION
0xB8	0x220F	# N-ARY PRODUCT
0xB9	0x03C0	# GREEK SMALL LETTER PI
0xBA	0x222B	# INTEGRAL
0xBB	0x00AA	# FEMININE ORDINAL INDICATOR
0xBC	0x00BA	# MASCULINE ORDINAL INDICATOR
0xBD	0x2126	# OHM SIGN
0xBE	0x00E6	# LATIN SMALL LIGATURE AE
0xBF	0x00F8	# LATIN SMALL LETTER O WITH STROKE
0xC0	0x00BF	# INVERTED QUESTION MARK
0xC1	0x00A1	# INVERTED EXCLAMATION MARK
0xC2	0x00AC	# NOT SIGN
0xC3	0x221A	# SQUARE ROOT
0xC4	0x0192	# LATIN SMALL LETTER F WITH HOOK
0xC5	0x2248	# ALMOST EQUAL TO
0xC6	0x2206	# INCREMENT
0xC7	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC8	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC9	0x2026	# HORIZONTAL ELLIPSIS
0xCA	0x00A0	# NO-BREAK SPACE
0xCB	0x00C0	# LATIN CAPITAL LETTER A WITH GRAVE
0xCC	0x00C3	# LATIN CAPITAL LETTER A WITH TILDE
0xCD	0x00D5	# LATIN CAPITAL LETTER O WITH TILDE
0xCE	0x0152	# LATIN CAPITAL LIGATURE OE
0xCF	0x0153	# LATIN SMALL LIGATURE OE
0xD0	0x2013	# EN DASH
0xD1	0x2014	# EM DASH
0xD2	0x201C	# LEFT DOUBLE QUOTATION MARK
0xD3	0x201D	# RIGHT DOUBLE QUOTATION MARK
0xD4	0x2018	# LEFT SINGLE QUOTATION MARK
0xD5	0x2019	# RIGHT SINGLE QUOTATION MARK
0xD6	0x00F7	# DIVISION SIGN
0xD7	0x25CA	# LOZENGE
0xD8	0x00FF	# LATIN SMALL LETTER Y WITH DIAERESIS
0xD9	0x0178	# LATIN CAPITAL LETTER Y WITH DIAERESIS
0xDA	0x011E	# LATIN CAPITAL LETTER G WITH BREVE
0xDB	0x011F	# LATIN SMALL LETTER G WITH BREVE
0xDC	0x0130	# LATIN CAPITAL LETTER I WITH DOT ABOVE
0xDD	0x0131	# LATIN SMALL LETTER DOTLESS I
0xDE	0x015E	# LATIN CAPITAL LETTER S WITH CEDILLA
0xDF	0x015F	# LATIN SMALL LETTER S WITH CEDILLA
0xE0	0x2021	# DOUBLE DAGGER
0xE1	0x00B7	# MIDDLE DOT
0xE2	0x201A	# SINGLE LOW-9 QUOTATION MARK
0xE3	0x201E	# DOUBLE LOW-9 QUOTATION MARK
0xE4	0x2030	# PER MILLE SIGN
0xE5	0x00C2	# LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xE6	0x00CA	# LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xE7	0x00C1	# LATIN CAPITAL LETTER A WITH ACUTE
0xE8	0x00CB	# LATIN CAPITAL LETTER E WITH DIAERESIS
0xE9	0x00C8	# LATIN CAPITAL LETTER E WITH GRAVE
0xEA	0x00CD	# LATIN CAPITAL LETTER I WITH ACUTE
0xEB	0x00CE	# LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xEC	0x00CF	# LATIN CAPITAL LETTER I WITH DIAERESIS
0xED	0x00CC	# LATIN CAPITAL LETTER I WITH GRAVE
0xEE	0x00D3	# LATIN CAPITAL LETTER O WITH ACUTE
0xEF	0x00D4	# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xF0	0xF8FF	# Apple logo
0xF1	0x00D2	# LATIN CAPITAL LETTER O WITH GRAVE
0xF2	0x00DA	# LATIN CAPITAL LETTER U WITH ACUTE
0xF3	0x00DB	# LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xF4	0x00D9	# LATIN CAPITAL LETTER U WITH GRAVE
0xF5	0xF8A0	# undefined1
0xF6	0x02C6	# MODIFIER LETTER CIRCUMFLEX ACCENT
0xF7	0x02DC	# SMALL TILDE
0xF8	0x00AF	# MACRON
0xF9	0x02D8	# BREVE
0xFA	0x02D9	# DOT ABOVE
0xFB	0x02DA	# RING ABOVE
0xFC	0x00B8	# CEDILLA
0xFD	0x02DD	# DOUBLE ACUTE ACCENT
0xFE	0x02DB	# OGONEK
0xFF	0x02C7	# CARON

Added tools/encoding/macUkraine.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
269
270
271
272
273
274
275
276
277
278
279
#
#   Name:             MacOS_Ukrainian [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <4>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Ukrainian code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Ukrainian code order.
#
#   Notes on MacOS Ukrainian:
#   -------------------------
#
#   The MacOS Ukrainian encoding shares the script code smCyrillic
#   (7) with the standard MacOS Cyrillic encoding. To determine if
#   the Ukrainian encoding is being used, you must also check if
#   the system region code is 62, verUkraine.
#
#   This character set is a variant of standard MacOS Cyrillic. It
#   adds upper & lower GHE WITH UPTURN, for a grand total of 2 code
#   point differences from standard MacOS Cyrillic.
#
##################

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
#
0x80	0x0410	# CYRILLIC CAPITAL LETTER A
0x81	0x0411	# CYRILLIC CAPITAL LETTER BE
0x82	0x0412	# CYRILLIC CAPITAL LETTER VE
0x83	0x0413	# CYRILLIC CAPITAL LETTER GHE
0x84	0x0414	# CYRILLIC CAPITAL LETTER DE
0x85	0x0415	# CYRILLIC CAPITAL LETTER IE
0x86	0x0416	# CYRILLIC CAPITAL LETTER ZHE
0x87	0x0417	# CYRILLIC CAPITAL LETTER ZE
0x88	0x0418	# CYRILLIC CAPITAL LETTER I
0x89	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
0x8A	0x041A	# CYRILLIC CAPITAL LETTER KA
0x8B	0x041B	# CYRILLIC CAPITAL LETTER EL
0x8C	0x041C	# CYRILLIC CAPITAL LETTER EM
0x8D	0x041D	# CYRILLIC CAPITAL LETTER EN
0x8E	0x041E	# CYRILLIC CAPITAL LETTER O
0x8F	0x041F	# CYRILLIC CAPITAL LETTER PE
0x90	0x0420	# CYRILLIC CAPITAL LETTER ER
0x91	0x0421	# CYRILLIC CAPITAL LETTER ES
0x92	0x0422	# CYRILLIC CAPITAL LETTER TE
0x93	0x0423	# CYRILLIC CAPITAL LETTER U
0x94	0x0424	# CYRILLIC CAPITAL LETTER EF
0x95	0x0425	# CYRILLIC CAPITAL LETTER HA
0x96	0x0426	# CYRILLIC CAPITAL LETTER TSE
0x97	0x0427	# CYRILLIC CAPITAL LETTER CHE
0x98	0x0428	# CYRILLIC CAPITAL LETTER SHA
0x99	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
0x9A	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
0x9B	0x042B	# CYRILLIC CAPITAL LETTER YERU
0x9C	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
0x9D	0x042D	# CYRILLIC CAPITAL LETTER E
0x9E	0x042E	# CYRILLIC CAPITAL LETTER YU
0x9F	0x042F	# CYRILLIC CAPITAL LETTER YA
0xA0	0x2020	# DAGGER
0xA1	0x00B0	# DEGREE SIGN
0xA2	0x0490	# CYRILLIC CAPITAL LETTER GHE WITH UPTURN
0xA3	0x00A3	# POUND SIGN
0xA4	0x00A7	# SECTION SIGN
0xA5	0x2022	# BULLET
0xA6	0x00B6	# PILCROW SIGN
0xA7	0x0406	# CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
0xA8	0x00AE	# REGISTERED SIGN
0xA9	0x00A9	# COPYRIGHT SIGN
0xAA	0x2122	# TRADE MARK SIGN
0xAB	0x0402	# CYRILLIC CAPITAL LETTER DJE
0xAC	0x0452	# CYRILLIC SMALL LETTER DJE
0xAD	0x2260	# NOT EQUAL TO
0xAE	0x0403	# CYRILLIC CAPITAL LETTER GJE
0xAF	0x0453	# CYRILLIC SMALL LETTER GJE
0xB0	0x221E	# INFINITY
0xB1	0x00B1	# PLUS-MINUS SIGN
0xB2	0x2264	# LESS-THAN OR EQUAL TO
0xB3	0x2265	# GREATER-THAN OR EQUAL TO
0xB4	0x0456	# CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
0xB5	0x00B5	# MICRO SIGN
0xB6	0x0491	# CYRILLIC SMALL LETTER GHE WITH UPTURN
0xB7	0x0408	# CYRILLIC CAPITAL LETTER JE
0xB8	0x0404	# CYRILLIC CAPITAL LETTER UKRAINIAN IE
0xB9	0x0454	# CYRILLIC SMALL LETTER UKRAINIAN IE
0xBA	0x0407	# CYRILLIC CAPITAL LETTER YI
0xBB	0x0457	# CYRILLIC SMALL LETTER YI
0xBC	0x0409	# CYRILLIC CAPITAL LETTER LJE
0xBD	0x0459	# CYRILLIC SMALL LETTER LJE
0xBE	0x040A	# CYRILLIC CAPITAL LETTER NJE
0xBF	0x045A	# CYRILLIC SMALL LETTER NJE
0xC0	0x0458	# CYRILLIC SMALL LETTER JE
0xC1	0x0405	# CYRILLIC CAPITAL LETTER DZE
0xC2	0x00AC	# NOT SIGN
0xC3	0x221A	# SQUARE ROOT
0xC4	0x0192	# LATIN SMALL LETTER F WITH HOOK
0xC5	0x2248	# ALMOST EQUAL TO
0xC6	0x2206	# INCREMENT
0xC7	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC8	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
0xC9	0x2026	# HORIZONTAL ELLIPSIS
0xCA	0x00A0	# NO-BREAK SPACE
0xCB	0x040B	# CYRILLIC CAPITAL LETTER TSHE
0xCC	0x045B	# CYRILLIC SMALL LETTER TSHE
0xCD	0x040C	# CYRILLIC CAPITAL LETTER KJE
0xCE	0x045C	# CYRILLIC SMALL LETTER KJE
0xCF	0x0455	# CYRILLIC SMALL LETTER DZE
0xD0	0x2013	# EN DASH
0xD1	0x2014	# EM DASH
0xD2	0x201C	# LEFT DOUBLE QUOTATION MARK
0xD3	0x201D	# RIGHT DOUBLE QUOTATION MARK
0xD4	0x2018	# LEFT SINGLE QUOTATION MARK
0xD5	0x2019	# RIGHT SINGLE QUOTATION MARK
0xD6	0x00F7	# DIVISION SIGN
0xD7	0x201E	# DOUBLE LOW-9 QUOTATION MARK
0xD8	0x040E	# CYRILLIC CAPITAL LETTER SHORT U
0xD9	0x045E	# CYRILLIC SMALL LETTER SHORT U
0xDA	0x040F	# CYRILLIC CAPITAL LETTER DZHE
0xDB	0x045F	# CYRILLIC SMALL LETTER DZHE
0xDC	0x2116	# NUMERO SIGN
0xDD	0x0401	# CYRILLIC CAPITAL LETTER IO
0xDE	0x0451	# CYRILLIC SMALL LETTER IO
0xDF	0x044F	# CYRILLIC SMALL LETTER YA
0xE0	0x0430	# CYRILLIC SMALL LETTER A
0xE1	0x0431	# CYRILLIC SMALL LETTER BE
0xE2	0x0432	# CYRILLIC SMALL LETTER VE
0xE3	0x0433	# CYRILLIC SMALL LETTER GHE
0xE4	0x0434	# CYRILLIC SMALL LETTER DE
0xE5	0x0435	# CYRILLIC SMALL LETTER IE
0xE6	0x0436	# CYRILLIC SMALL LETTER ZHE
0xE7	0x0437	# CYRILLIC SMALL LETTER ZE
0xE8	0x0438	# CYRILLIC SMALL LETTER I
0xE9	0x0439	# CYRILLIC SMALL LETTER SHORT I
0xEA	0x043A	# CYRILLIC SMALL LETTER KA
0xEB	0x043B	# CYRILLIC SMALL LETTER EL
0xEC	0x043C	# CYRILLIC SMALL LETTER EM
0xED	0x043D	# CYRILLIC SMALL LETTER EN
0xEE	0x043E	# CYRILLIC SMALL LETTER O
0xEF	0x043F	# CYRILLIC SMALL LETTER PE
0xF0	0x0440	# CYRILLIC SMALL LETTER ER
0xF1	0x0441	# CYRILLIC SMALL LETTER ES
0xF2	0x0442	# CYRILLIC SMALL LETTER TE
0xF3	0x0443	# CYRILLIC SMALL LETTER U
0xF4	0x0444	# CYRILLIC SMALL LETTER EF
0xF5	0x0445	# CYRILLIC SMALL LETTER HA
0xF6	0x0446	# CYRILLIC SMALL LETTER TSE
0xF7	0x0447	# CYRILLIC SMALL LETTER CHE
0xF8	0x0448	# CYRILLIC SMALL LETTER SHA
0xF9	0x0449	# CYRILLIC SMALL LETTER SHCHA
0xFA	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
0xFB	0x044B	# CYRILLIC SMALL LETTER YERU
0xFC	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
0xFD	0x044D	# CYRILLIC SMALL LETTER E
0xFE	0x044E	# CYRILLIC SMALL LETTER YU
0xFF	0x00A4	# CURRENCY SIGN

Added tools/encoding/shiftjis.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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
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
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
#
#	Name:             Shift-JIS to Unicode
#	Unicode version:  1.1
#	Table version:    0.9
#	Table format:     Format A
#	Date:             8 March 1994
#	Authors:          Glenn Adams <[email protected]>
#                     John H. Jenkins <[email protected]>
#
#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on magnetic media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Recipient is granted the right to make copies in any form for
#	internal distribution and to freely use the information supplied
#	in the creation of products supporting Unicode.  Unicode, Inc.
#	specifically excludes the right to re-distribute this file directly
#	to third parties or other organizations whether for profit or not.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       Shift-JIS (a combination of JIS 0201 and JIS 0208) maps into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the shift-JIS code (in hex)
#		 Column #2 is the Unicode (in hex as 0xXXXX)
#		 Column #3 the Unicode name (follows a comment sign, '#')
#					The official names for Unicode characters U+4E00
#					to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
#					where XXXX is the code point.  Including all these
#					names in this file increases its size substantially
#					and needlessly.  The token "<CJK>" is used for the
#					name of these characters.  If necessary, it can be
#					expanded algorithmically by a parser or editor.
#
#	The entries are ordered by their Shift-JIS codes as follows:
#		Single-byte characters precede double-byte characters
#		The single-byte and double-byte blocks are in ascending
#		hexadecimal order
#	There is an alternative order some people might be preferred,
#		where all the entries are in order of the top (or only) byte.
#		This alternate order can be generated from the one given here
#		by a simple sort.  
#
#   The kanji mappings are a normative part of ISO/IEC 10646.  The
#       non-kanji mappings are provisional, pending definition of
#       official mappings by Japanese standards bodies
#
#	Any comments or problems, contact <[email protected]>
#
#
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 (rendered as Halfwidth Yen Sign)
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
0x8140	0x3000	# IDEOGRAPHIC SPACE
0x8141	0x3001	# IDEOGRAPHIC COMMA
0x8142	0x3002	# IDEOGRAPHIC FULL STOP
0x8143	0xFF0C	# FULLWIDTH COMMA
0x8144	0xFF0E	# FULLWIDTH FULL STOP
0x8145	0x30FB	# KATAKANA MIDDLE DOT
0x8146	0xFF1A	# FULLWIDTH COLON
0x8147	0xFF1B	# FULLWIDTH SEMICOLON
0x8148	0xFF1F	# FULLWIDTH QUESTION MARK
0x8149	0xFF01	# FULLWIDTH EXCLAMATION MARK
0x814A	0x309B	# KATAKANA-HIRAGANA VOICED SOUND MARK
0x814B	0x309C	# KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
0x814C	0x00B4	# ACUTE ACCENT
0x814D	0xFF40	# FULLWIDTH GRAVE ACCENT
0x814E	0x00A8	# DIAERESIS
0x814F	0xFF3E	# FULLWIDTH CIRCUMFLEX ACCENT
0x8150	0xFFE3	# FULLWIDTH MACRON
0x8151	0xFF3F	# FULLWIDTH LOW LINE
0x8152	0x30FD	# KATAKANA ITERATION MARK
0x8153	0x30FE	# KATAKANA VOICED ITERATION MARK
0x8154	0x309D	# HIRAGANA ITERATION MARK
0x8155	0x309E	# HIRAGANA VOICED ITERATION MARK
0x8156	0x3003	# DITTO MARK
0x8157	0x4EDD	# <CJK>
0x8158	0x3005	# IDEOGRAPHIC ITERATION MARK
0x8159	0x3006	# IDEOGRAPHIC CLOSING MARK
0x815A	0x3007	# IDEOGRAPHIC NUMBER ZERO
0x815B	0x30FC	# KATAKANA-HIRAGANA PROLONGED SOUND MARK
0x815C	0x2015	# HORIZONTAL BAR
0x815D	0x2010	# HYPHEN
0x815E	0xFF0F	# FULLWIDTH SOLIDUS
0x815F	0xFF3C	# FULLWIDTH REVERSE SOLIDUS
0x8160	0x301C	# WAVE DASH
0x8161	0x2016	# DOUBLE VERTICAL LINE
0x8162	0xFF5C	# FULLWIDTH VERTICAL LINE
0x8163	0x2026	# HORIZONTAL ELLIPSIS
0x8164	0x2025	# TWO DOT LEADER
0x8165	0x2018	# LEFT SINGLE QUOTATION MARK
0x8166	0x2019	# RIGHT SINGLE QUOTATION MARK
0x8167	0x201C	# LEFT DOUBLE QUOTATION MARK
0x8168	0x201D	# RIGHT DOUBLE QUOTATION MARK
0x8169	0xFF08	# FULLWIDTH LEFT PARENTHESIS
0x816A	0xFF09	# FULLWIDTH RIGHT PARENTHESIS
0x816B	0x3014	# LEFT TORTOISE SHELL BRACKET
0x816C	0x3015	# RIGHT TORTOISE SHELL BRACKET
0x816D	0xFF3B	# FULLWIDTH LEFT SQUARE BRACKET
0x816E	0xFF3D	# FULLWIDTH RIGHT SQUARE BRACKET
0x816F	0xFF5B	# FULLWIDTH LEFT CURLY BRACKET
0x8170	0xFF5D	# FULLWIDTH RIGHT CURLY BRACKET
0x8171	0x3008	# LEFT ANGLE BRACKET
0x8172	0x3009	# RIGHT ANGLE BRACKET
0x8173	0x300A	# LEFT DOUBLE ANGLE BRACKET
0x8174	0x300B	# RIGHT DOUBLE ANGLE BRACKET
0x8175	0x300C	# LEFT CORNER BRACKET
0x8176	0x300D	# RIGHT CORNER BRACKET
0x8177	0x300E	# LEFT WHITE CORNER BRACKET
0x8178	0x300F	# RIGHT WHITE CORNER BRACKET
0x8179	0x3010	# LEFT BLACK LENTICULAR BRACKET
0x817A	0x3011	# RIGHT BLACK LENTICULAR BRACKET
0x817B	0xFF0B	# FULLWIDTH PLUS SIGN
0x817C	0x2212	# MINUS SIGN
0x817D	0x00B1	# PLUS-MINUS SIGN
0x817E	0x00D7	# MULTIPLICATION SIGN
0x8180	0x00F7	# DIVISION SIGN
0x8181	0xFF1D	# FULLWIDTH EQUALS SIGN
0x8182	0x2260	# NOT EQUAL TO
0x8183	0xFF1C	# FULLWIDTH LESS-THAN SIGN
0x8184	0xFF1E	# FULLWIDTH GREATER-THAN SIGN
0x8185	0x2266	# LESS-THAN OVER EQUAL TO
0x8186	0x2267	# GREATER-THAN OVER EQUAL TO
0x8187	0x221E	# INFINITY
0x8188	0x2234	# THEREFORE
0x8189	0x2642	# MALE SIGN
0x818A	0x2640	# FEMALE SIGN
0x818B	0x00B0	# DEGREE SIGN
0x818C	0x2032	# PRIME
0x818D	0x2033	# DOUBLE PRIME
0x818E	0x2103	# DEGREE CELSIUS
0x818F	0xFFE5	# FULLWIDTH YEN SIGN
0x8190	0xFF04	# FULLWIDTH DOLLAR SIGN
0x8191	0x00A2	# CENT SIGN
0x8192	0x00A3	# POUND SIGN
0x8193	0xFF05	# FULLWIDTH PERCENT SIGN
0x8194	0xFF03	# FULLWIDTH NUMBER SIGN
0x8195	0xFF06	# FULLWIDTH AMPERSAND
0x8196	0xFF0A	# FULLWIDTH ASTERISK
0x8197	0xFF20	# FULLWIDTH COMMERCIAL AT
0x8198	0x00A7	# SECTION SIGN
0x8199	0x2606	# WHITE STAR
0x819A	0x2605	# BLACK STAR
0x819B	0x25CB	# WHITE CIRCLE
0x819C	0x25CF	# BLACK CIRCLE
0x819D	0x25CE	# BULLSEYE
0x819E	0x25C7	# WHITE DIAMOND
0x819F	0x25C6	# BLACK DIAMOND
0x81A0	0x25A1	# WHITE SQUARE
0x81A1	0x25A0	# BLACK SQUARE
0x81A2	0x25B3	# WHITE UP-POINTING TRIANGLE
0x81A3	0x25B2	# BLACK UP-POINTING TRIANGLE
0x81A4	0x25BD	# WHITE DOWN-POINTING TRIANGLE
0x81A5	0x25BC	# BLACK DOWN-POINTING TRIANGLE
0x81A6	0x203B	# REFERENCE MARK
0x81A7	0x3012	# POSTAL MARK
0x81A8	0x2192	# RIGHTWARDS ARROW
0x81A9	0x2190	# LEFTWARDS ARROW
0x81AA	0x2191	# UPWARDS ARROW
0x81AB	0x2193	# DOWNWARDS ARROW
0x81AC	0x3013	# GETA MARK
0x81B8	0x2208	# ELEMENT OF
0x81B9	0x220B	# CONTAINS AS MEMBER
0x81BA	0x2286	# SUBSET OF OR EQUAL TO
0x81BB	0x2287	# SUPERSET OF OR EQUAL TO
0x81BC	0x2282	# SUBSET OF
0x81BD	0x2283	# SUPERSET OF
0x81BE	0x222A	# UNION
0x81BF	0x2229	# INTERSECTION
0x81C8	0x2227	# LOGICAL AND
0x81C9	0x2228	# LOGICAL OR
0x81CA	0x00AC	# NOT SIGN
0x81CB	0x21D2	# RIGHTWARDS DOUBLE ARROW
0x81CC	0x21D4	# LEFT RIGHT DOUBLE ARROW
0x81CD	0x2200	# FOR ALL
0x81CE	0x2203	# THERE EXISTS
0x81DA	0x2220	# ANGLE
0x81DB	0x22A5	# UP TACK
0x81DC	0x2312	# ARC
0x81DD	0x2202	# PARTIAL DIFFERENTIAL
0x81DE	0x2207	# NABLA
0x81DF	0x2261	# IDENTICAL TO
0x81E0	0x2252	# APPROXIMATELY EQUAL TO OR THE IMAGE OF
0x81E1	0x226A	# MUCH LESS-THAN
0x81E2	0x226B	# MUCH GREATER-THAN
0x81E3	0x221A	# SQUARE ROOT
0x81E4	0x223D	# REVERSED TILDE
0x81E5	0x221D	# PROPORTIONAL TO
0x81E6	0x2235	# BECAUSE
0x81E7	0x222B	# INTEGRAL
0x81E8	0x222C	# DOUBLE INTEGRAL
0x81F0	0x212B	# ANGSTROM SIGN
0x81F1	0x2030	# PER MILLE SIGN
0x81F2	0x266F	# MUSIC SHARP SIGN
0x81F3	0x266D	# MUSIC FLAT SIGN
0x81F4	0x266A	# EIGHTH NOTE
0x81F5	0x2020	# DAGGER
0x81F6	0x2021	# DOUBLE DAGGER
0x81F7	0x00B6	# PILCROW SIGN
0x81FC	0x25EF	# LARGE CIRCLE
0x824F	0xFF10	# FULLWIDTH DIGIT ZERO
0x8250	0xFF11	# FULLWIDTH DIGIT ONE
0x8251	0xFF12	# FULLWIDTH DIGIT TWO
0x8252	0xFF13	# FULLWIDTH DIGIT THREE
0x8253	0xFF14	# FULLWIDTH DIGIT FOUR
0x8254	0xFF15	# FULLWIDTH DIGIT FIVE
0x8255	0xFF16	# FULLWIDTH DIGIT SIX
0x8256	0xFF17	# FULLWIDTH DIGIT SEVEN
0x8257	0xFF18	# FULLWIDTH DIGIT EIGHT
0x8258	0xFF19	# FULLWIDTH DIGIT NINE
0x8260	0xFF21	# FULLWIDTH LATIN CAPITAL LETTER A
0x8261	0xFF22	# FULLWIDTH LATIN CAPITAL LETTER B
0x8262	0xFF23	# FULLWIDTH LATIN CAPITAL LETTER C
0x8263	0xFF24	# FULLWIDTH LATIN CAPITAL LETTER D
0x8264	0xFF25	# FULLWIDTH LATIN CAPITAL LETTER E
0x8265	0xFF26	# FULLWIDTH LATIN CAPITAL LETTER F
0x8266	0xFF27	# FULLWIDTH LATIN CAPITAL LETTER G
0x8267	0xFF28	# FULLWIDTH LATIN CAPITAL LETTER H
0x8268	0xFF29	# FULLWIDTH LATIN CAPITAL LETTER I
0x8269	0xFF2A	# FULLWIDTH LATIN CAPITAL LETTER J
0x826A	0xFF2B	# FULLWIDTH LATIN CAPITAL LETTER K
0x826B	0xFF2C	# FULLWIDTH LATIN CAPITAL LETTER L
0x826C	0xFF2D	# FULLWIDTH LATIN CAPITAL LETTER M
0x826D	0xFF2E	# FULLWIDTH LATIN CAPITAL LETTER N
0x826E	0xFF2F	# FULLWIDTH LATIN CAPITAL LETTER O
0x826F	0xFF30	# FULLWIDTH LATIN CAPITAL LETTER P
0x8270	0xFF31	# FULLWIDTH LATIN CAPITAL LETTER Q
0x8271	0xFF32	# FULLWIDTH LATIN CAPITAL LETTER R
0x8272	0xFF33	# FULLWIDTH LATIN CAPITAL LETTER S
0x8273	0xFF34	# FULLWIDTH LATIN CAPITAL LETTER T
0x8274	0xFF35	# FULLWIDTH LATIN CAPITAL LETTER U
0x8275	0xFF36	# FULLWIDTH LATIN CAPITAL LETTER V
0x8276	0xFF37	# FULLWIDTH LATIN CAPITAL LETTER W
0x8277	0xFF38	# FULLWIDTH LATIN CAPITAL LETTER X
0x8278	0xFF39	# FULLWIDTH LATIN CAPITAL LETTER Y
0x8279	0xFF3A	# FULLWIDTH LATIN CAPITAL LETTER Z
0x8281	0xFF41	# FULLWIDTH LATIN SMALL LETTER A
0x8282	0xFF42	# FULLWIDTH LATIN SMALL LETTER B
0x8283	0xFF43	# FULLWIDTH LATIN SMALL LETTER C
0x8284	0xFF44	# FULLWIDTH LATIN SMALL LETTER D
0x8285	0xFF45	# FULLWIDTH LATIN SMALL LETTER E
0x8286	0xFF46	# FULLWIDTH LATIN SMALL LETTER F
0x8287	0xFF47	# FULLWIDTH LATIN SMALL LETTER G
0x8288	0xFF48	# FULLWIDTH LATIN SMALL LETTER H
0x8289	0xFF49	# FULLWIDTH LATIN SMALL LETTER I
0x828A	0xFF4A	# FULLWIDTH LATIN SMALL LETTER J
0x828B	0xFF4B	# FULLWIDTH LATIN SMALL LETTER K
0x828C	0xFF4C	# FULLWIDTH LATIN SMALL LETTER L
0x828D	0xFF4D	# FULLWIDTH LATIN SMALL LETTER M
0x828E	0xFF4E	# FULLWIDTH LATIN SMALL LETTER N
0x828F	0xFF4F	# FULLWIDTH LATIN SMALL LETTER O
0x8290	0xFF50	# FULLWIDTH LATIN SMALL LETTER P
0x8291	0xFF51	# FULLWIDTH LATIN SMALL LETTER Q
0x8292	0xFF52	# FULLWIDTH LATIN SMALL LETTER R
0x8293	0xFF53	# FULLWIDTH LATIN SMALL LETTER S
0x8294	0xFF54	# FULLWIDTH LATIN SMALL LETTER T
0x8295	0xFF55	# FULLWIDTH LATIN SMALL LETTER U
0x8296	0xFF56	# FULLWIDTH LATIN SMALL LETTER V
0x8297	0xFF57	# FULLWIDTH LATIN SMALL LETTER W
0x8298	0xFF58	# FULLWIDTH LATIN SMALL LETTER X
0x8299	0xFF59	# FULLWIDTH LATIN SMALL LETTER Y
0x829A	0xFF5A	# FULLWIDTH LATIN SMALL LETTER Z
0x829F	0x3041	# HIRAGANA LETTER SMALL A
0x82A0	0x3042	# HIRAGANA LETTER A
0x82A1	0x3043	# HIRAGANA LETTER SMALL I
0x82A2	0x3044	# HIRAGANA LETTER I
0x82A3	0x3045	# HIRAGANA LETTER SMALL U
0x82A4	0x3046	# HIRAGANA LETTER U
0x82A5	0x3047	# HIRAGANA LETTER SMALL E
0x82A6	0x3048	# HIRAGANA LETTER E
0x82A7	0x3049	# HIRAGANA LETTER SMALL O
0x82A8	0x304A	# HIRAGANA LETTER O
0x82A9	0x304B	# HIRAGANA LETTER KA
0x82AA	0x304C	# HIRAGANA LETTER GA
0x82AB	0x304D	# HIRAGANA LETTER KI
0x82AC	0x304E	# HIRAGANA LETTER GI
0x82AD	0x304F	# HIRAGANA LETTER KU
0x82AE	0x3050	# HIRAGANA LETTER GU
0x82AF	0x3051	# HIRAGANA LETTER KE
0x82B0	0x3052	# HIRAGANA LETTER GE
0x82B1	0x3053	# HIRAGANA LETTER KO
0x82B2	0x3054	# HIRAGANA LETTER GO
0x82B3	0x3055	# HIRAGANA LETTER SA
0x82B4	0x3056	# HIRAGANA LETTER ZA
0x82B5	0x3057	# HIRAGANA LETTER SI
0x82B6	0x3058	# HIRAGANA LETTER ZI
0x82B7	0x3059	# HIRAGANA LETTER SU
0x82B8	0x305A	# HIRAGANA LETTER ZU
0x82B9	0x305B	# HIRAGANA LETTER SE
0x82BA	0x305C	# HIRAGANA LETTER ZE
0x82BB	0x305D	# HIRAGANA LETTER SO
0x82BC	0x305E	# HIRAGANA LETTER ZO
0x82BD	0x305F	# HIRAGANA LETTER TA
0x82BE	0x3060	# HIRAGANA LETTER DA
0x82BF	0x3061	# HIRAGANA LETTER TI
0x82C0	0x3062	# HIRAGANA LETTER DI
0x82C1	0x3063	# HIRAGANA LETTER SMALL TU
0x82C2	0x3064	# HIRAGANA LETTER TU
0x82C3	0x3065	# HIRAGANA LETTER DU
0x82C4	0x3066	# HIRAGANA LETTER TE
0x82C5	0x3067	# HIRAGANA LETTER DE
0x82C6	0x3068	# HIRAGANA LETTER TO
0x82C7	0x3069	# HIRAGANA LETTER DO
0x82C8	0x306A	# HIRAGANA LETTER NA
0x82C9	0x306B	# HIRAGANA LETTER NI
0x82CA	0x306C	# HIRAGANA LETTER NU
0x82CB	0x306D	# HIRAGANA LETTER NE
0x82CC	0x306E	# HIRAGANA LETTER NO
0x82CD	0x306F	# HIRAGANA LETTER HA
0x82CE	0x3070	# HIRAGANA LETTER BA
0x82CF	0x3071	# HIRAGANA LETTER PA
0x82D0	0x3072	# HIRAGANA LETTER HI
0x82D1	0x3073	# HIRAGANA LETTER BI
0x82D2	0x3074	# HIRAGANA LETTER PI
0x82D3	0x3075	# HIRAGANA LETTER HU
0x82D4	0x3076	# HIRAGANA LETTER BU
0x82D5	0x3077	# HIRAGANA LETTER PU
0x82D6	0x3078	# HIRAGANA LETTER HE
0x82D7	0x3079	# HIRAGANA LETTER BE
0x82D8	0x307A	# HIRAGANA LETTER PE
0x82D9	0x307B	# HIRAGANA LETTER HO
0x82DA	0x307C	# HIRAGANA LETTER BO
0x82DB	0x307D	# HIRAGANA LETTER PO
0x82DC	0x307E	# HIRAGANA LETTER MA
0x82DD	0x307F	# HIRAGANA LETTER MI
0x82DE	0x3080	# HIRAGANA LETTER MU
0x82DF	0x3081	# HIRAGANA LETTER ME
0x82E0	0x3082	# HIRAGANA LETTER MO
0x82E1	0x3083	# HIRAGANA LETTER SMALL YA
0x82E2	0x3084	# HIRAGANA LETTER YA
0x82E3	0x3085	# HIRAGANA LETTER SMALL YU
0x82E4	0x3086	# HIRAGANA LETTER YU
0x82E5	0x3087	# HIRAGANA LETTER SMALL YO
0x82E6	0x3088	# HIRAGANA LETTER YO
0x82E7	0x3089	# HIRAGANA LETTER RA
0x82E8	0x308A	# HIRAGANA LETTER RI
0x82E9	0x308B	# HIRAGANA LETTER RU
0x82EA	0x308C	# HIRAGANA LETTER RE
0x82EB	0x308D	# HIRAGANA LETTER RO
0x82EC	0x308E	# HIRAGANA LETTER SMALL WA
0x82ED	0x308F	# HIRAGANA LETTER WA
0x82EE	0x3090	# HIRAGANA LETTER WI
0x82EF	0x3091	# HIRAGANA LETTER WE
0x82F0	0x3092	# HIRAGANA LETTER WO
0x82F1	0x3093	# HIRAGANA LETTER N
0x8340	0x30A1	# KATAKANA LETTER SMALL A
0x8341	0x30A2	# KATAKANA LETTER A
0x8342	0x30A3	# KATAKANA LETTER SMALL I
0x8343	0x30A4	# KATAKANA LETTER I
0x8344	0x30A5	# KATAKANA LETTER SMALL U
0x8345	0x30A6	# KATAKANA LETTER U
0x8346	0x30A7	# KATAKANA LETTER SMALL E
0x8347	0x30A8	# KATAKANA LETTER E
0x8348	0x30A9	# KATAKANA LETTER SMALL O
0x8349	0x30AA	# KATAKANA LETTER O
0x834A	0x30AB	# KATAKANA LETTER KA
0x834B	0x30AC	# KATAKANA LETTER GA
0x834C	0x30AD	# KATAKANA LETTER KI
0x834D	0x30AE	# KATAKANA LETTER GI
0x834E	0x30AF	# KATAKANA LETTER KU
0x834F	0x30B0	# KATAKANA LETTER GU
0x8350	0x30B1	# KATAKANA LETTER KE
0x8351	0x30B2	# KATAKANA LETTER GE
0x8352	0x30B3	# KATAKANA LETTER KO
0x8353	0x30B4	# KATAKANA LETTER GO
0x8354	0x30B5	# KATAKANA LETTER SA
0x8355	0x30B6	# KATAKANA LETTER ZA
0x8356	0x30B7	# KATAKANA LETTER SI
0x8357	0x30B8	# KATAKANA LETTER ZI
0x8358	0x30B9	# KATAKANA LETTER SU
0x8359	0x30BA	# KATAKANA LETTER ZU
0x835A	0x30BB	# KATAKANA LETTER SE
0x835B	0x30BC	# KATAKANA LETTER ZE
0x835C	0x30BD	# KATAKANA LETTER SO
0x835D	0x30BE	# KATAKANA LETTER ZO
0x835E	0x30BF	# KATAKANA LETTER TA
0x835F	0x30C0	# KATAKANA LETTER DA
0x8360	0x30C1	# KATAKANA LETTER TI
0x8361	0x30C2	# KATAKANA LETTER DI
0x8362	0x30C3	# KATAKANA LETTER SMALL TU
0x8363	0x30C4	# KATAKANA LETTER TU
0x8364	0x30C5	# KATAKANA LETTER DU
0x8365	0x30C6	# KATAKANA LETTER TE
0x8366	0x30C7	# KATAKANA LETTER DE
0x8367	0x30C8	# KATAKANA LETTER TO
0x8368	0x30C9	# KATAKANA LETTER DO
0x8369	0x30CA	# KATAKANA LETTER NA
0x836A	0x30CB	# KATAKANA LETTER NI
0x836B	0x30CC	# KATAKANA LETTER NU
0x836C	0x30CD	# KATAKANA LETTER NE
0x836D	0x30CE	# KATAKANA LETTER NO
0x836E	0x30CF	# KATAKANA LETTER HA
0x836F	0x30D0	# KATAKANA LETTER BA
0x8370	0x30D1	# KATAKANA LETTER PA
0x8371	0x30D2	# KATAKANA LETTER HI
0x8372	0x30D3	# KATAKANA LETTER BI
0x8373	0x30D4	# KATAKANA LETTER PI
0x8374	0x30D5	# KATAKANA LETTER HU
0x8375	0x30D6	# KATAKANA LETTER BU
0x8376	0x30D7	# KATAKANA LETTER PU
0x8377	0x30D8	# KATAKANA LETTER HE
0x8378	0x30D9	# KATAKANA LETTER BE
0x8379	0x30DA	# KATAKANA LETTER PE
0x837A	0x30DB	# KATAKANA LETTER HO
0x837B	0x30DC	# KATAKANA LETTER BO
0x837C	0x30DD	# KATAKANA LETTER PO
0x837D	0x30DE	# KATAKANA LETTER MA
0x837E	0x30DF	# KATAKANA LETTER MI
0x8380	0x30E0	# KATAKANA LETTER MU
0x8381	0x30E1	# KATAKANA LETTER ME
0x8382	0x30E2	# KATAKANA LETTER MO
0x8383	0x30E3	# KATAKANA LETTER SMALL YA
0x8384	0x30E4	# KATAKANA LETTER YA
0x8385	0x30E5	# KATAKANA LETTER SMALL YU
0x8386	0x30E6	# KATAKANA LETTER YU
0x8387	0x30E7	# KATAKANA LETTER SMALL YO
0x8388	0x30E8	# KATAKANA LETTER YO
0x8389	0x30E9	# KATAKANA LETTER RA
0x838A	0x30EA	# KATAKANA LETTER RI
0x838B	0x30EB	# KATAKANA LETTER RU
0x838C	0x30EC	# KATAKANA LETTER RE
0x838D	0x30ED	# KATAKANA LETTER RO
0x838E	0x30EE	# KATAKANA LETTER SMALL WA
0x838F	0x30EF	# KATAKANA LETTER WA
0x8390	0x30F0	# KATAKANA LETTER WI
0x8391	0x30F1	# KATAKANA LETTER WE
0x8392	0x30F2	# KATAKANA LETTER WO
0x8393	0x30F3	# KATAKANA LETTER N
0x8394	0x30F4	# KATAKANA LETTER VU
0x8395	0x30F5	# KATAKANA LETTER SMALL KA
0x8396	0x30F6	# KATAKANA LETTER SMALL KE
0x839F	0x0391	# GREEK CAPITAL LETTER ALPHA
0x83A0	0x0392	# GREEK CAPITAL LETTER BETA
0x83A1	0x0393	# GREEK CAPITAL LETTER GAMMA
0x83A2	0x0394	# GREEK CAPITAL LETTER DELTA
0x83A3	0x0395	# GREEK CAPITAL LETTER EPSILON
0x83A4	0x0396	# GREEK CAPITAL LETTER ZETA
0x83A5	0x0397	# GREEK CAPITAL LETTER ETA
0x83A6	0x0398	# GREEK CAPITAL LETTER THETA
0x83A7	0x0399	# GREEK CAPITAL LETTER IOTA
0x83A8	0x039A	# GREEK CAPITAL LETTER KAPPA
0x83A9	0x039B	# GREEK CAPITAL LETTER LAMDA
0x83AA	0x039C	# GREEK CAPITAL LETTER MU
0x83AB	0x039D	# GREEK CAPITAL LETTER NU
0x83AC	0x039E	# GREEK CAPITAL LETTER XI
0x83AD	0x039F	# GREEK CAPITAL LETTER OMICRON
0x83AE	0x03A0	# GREEK CAPITAL LETTER PI
0x83AF	0x03A1	# GREEK CAPITAL LETTER RHO
0x83B0	0x03A3	# GREEK CAPITAL LETTER SIGMA
0x83B1	0x03A4	# GREEK CAPITAL LETTER TAU
0x83B2	0x03A5	# GREEK CAPITAL LETTER UPSILON
0x83B3	0x03A6	# GREEK CAPITAL LETTER PHI
0x83B4	0x03A7	# GREEK CAPITAL LETTER CHI
0x83B5	0x03A8	# GREEK CAPITAL LETTER PSI
0x83B6	0x03A9	# GREEK CAPITAL LETTER OMEGA
0x83BF	0x03B1	# GREEK SMALL LETTER ALPHA
0x83C0	0x03B2	# GREEK SMALL LETTER BETA
0x83C1	0x03B3	# GREEK SMALL LETTER GAMMA
0x83C2	0x03B4	# GREEK SMALL LETTER DELTA
0x83C3	0x03B5	# GREEK SMALL LETTER EPSILON
0x83C4	0x03B6	# GREEK SMALL LETTER ZETA
0x83C5	0x03B7	# GREEK SMALL LETTER ETA
0x83C6	0x03B8	# GREEK SMALL LETTER THETA
0x83C7	0x03B9	# GREEK SMALL LETTER IOTA
0x83C8	0x03BA	# GREEK SMALL LETTER KAPPA
0x83C9	0x03BB	# GREEK SMALL LETTER LAMDA
0x83CA	0x03BC	# GREEK SMALL LETTER MU
0x83CB	0x03BD	# GREEK SMALL LETTER NU
0x83CC	0x03BE	# GREEK SMALL LETTER XI
0x83CD	0x03BF	# GREEK SMALL LETTER OMICRON
0x83CE	0x03C0	# GREEK SMALL LETTER PI
0x83CF	0x03C1	# GREEK SMALL LETTER RHO
0x83D0	0x03C3	# GREEK SMALL LETTER SIGMA
0x83D1	0x03C4	# GREEK SMALL LETTER TAU
0x83D2	0x03C5	# GREEK SMALL LETTER UPSILON
0x83D3	0x03C6	# GREEK SMALL LETTER PHI
0x83D4	0x03C7	# GREEK SMALL LETTER CHI
0x83D5	0x03C8	# GREEK SMALL LETTER PSI
0x83D6	0x03C9	# GREEK SMALL LETTER OMEGA
0x8440	0x0410	# CYRILLIC CAPITAL LETTER A
0x8441	0x0411	# CYRILLIC CAPITAL LETTER BE
0x8442	0x0412	# CYRILLIC CAPITAL LETTER VE
0x8443	0x0413	# CYRILLIC CAPITAL LETTER GHE
0x8444	0x0414	# CYRILLIC CAPITAL LETTER DE
0x8445	0x0415	# CYRILLIC CAPITAL LETTER IE
0x8446	0x0401	# CYRILLIC CAPITAL LETTER IO
0x8447	0x0416	# CYRILLIC CAPITAL LETTER ZHE
0x8448	0x0417	# CYRILLIC CAPITAL LETTER ZE
0x8449	0x0418	# CYRILLIC CAPITAL LETTER I
0x844A	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
0x844B	0x041A	# CYRILLIC CAPITAL LETTER KA
0x844C	0x041B	# CYRILLIC CAPITAL LETTER EL
0x844D	0x041C	# CYRILLIC CAPITAL LETTER EM
0x844E	0x041D	# CYRILLIC CAPITAL LETTER EN
0x844F	0x041E	# CYRILLIC CAPITAL LETTER O
0x8450	0x041F	# CYRILLIC CAPITAL LETTER PE
0x8451	0x0420	# CYRILLIC CAPITAL LETTER ER
0x8452	0x0421	# CYRILLIC CAPITAL LETTER ES
0x8453	0x0422	# CYRILLIC CAPITAL LETTER TE
0x8454	0x0423	# CYRILLIC CAPITAL LETTER U
0x8455	0x0424	# CYRILLIC CAPITAL LETTER EF
0x8456	0x0425	# CYRILLIC CAPITAL LETTER HA
0x8457	0x0426	# CYRILLIC CAPITAL LETTER TSE
0x8458	0x0427	# CYRILLIC CAPITAL LETTER CHE
0x8459	0x0428	# CYRILLIC CAPITAL LETTER SHA
0x845A	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
0x845B	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
0x845C	0x042B	# CYRILLIC CAPITAL LETTER YERU
0x845D	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
0x845E	0x042D	# CYRILLIC CAPITAL LETTER E
0x845F	0x042E	# CYRILLIC CAPITAL LETTER YU
0x8460	0x042F	# CYRILLIC CAPITAL LETTER YA
0x8470	0x0430	# CYRILLIC SMALL LETTER A
0x8471	0x0431	# CYRILLIC SMALL LETTER BE
0x8472	0x0432	# CYRILLIC SMALL LETTER VE
0x8473	0x0433	# CYRILLIC SMALL LETTER GHE
0x8474	0x0434	# CYRILLIC SMALL LETTER DE
0x8475	0x0435	# CYRILLIC SMALL LETTER IE
0x8476	0x0451	# CYRILLIC SMALL LETTER IO
0x8477	0x0436	# CYRILLIC SMALL LETTER ZHE
0x8478	0x0437	# CYRILLIC SMALL LETTER ZE
0x8479	0x0438	# CYRILLIC SMALL LETTER I
0x847A	0x0439	# CYRILLIC SMALL LETTER SHORT I
0x847B	0x043A	# CYRILLIC SMALL LETTER KA
0x847C	0x043B	# CYRILLIC SMALL LETTER EL
0x847D	0x043C	# CYRILLIC SMALL LETTER EM
0x847E	0x043D	# CYRILLIC SMALL LETTER EN
0x8480	0x043E	# CYRILLIC SMALL LETTER O
0x8481	0x043F	# CYRILLIC SMALL LETTER PE
0x8482	0x0440	# CYRILLIC SMALL LETTER ER
0x8483	0x0441	# CYRILLIC SMALL LETTER ES
0x8484	0x0442	# CYRILLIC SMALL LETTER TE
0x8485	0x0443	# CYRILLIC SMALL LETTER U
0x8486	0x0444	# CYRILLIC SMALL LETTER EF
0x8487	0x0445	# CYRILLIC SMALL LETTER HA
0x8488	0x0446	# CYRILLIC SMALL LETTER TSE
0x8489	0x0447	# CYRILLIC SMALL LETTER CHE
0x848A	0x0448	# CYRILLIC SMALL LETTER SHA
0x848B	0x0449	# CYRILLIC SMALL LETTER SHCHA
0x848C	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
0x848D	0x044B	# CYRILLIC SMALL LETTER YERU
0x848E	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
0x848F	0x044D	# CYRILLIC SMALL LETTER E
0x8490	0x044E	# CYRILLIC SMALL LETTER YU
0x8491	0x044F	# CYRILLIC SMALL LETTER YA
0x849F	0x2500	# BOX DRAWINGS LIGHT HORIZONTAL
0x84A0	0x2502	# BOX DRAWINGS LIGHT VERTICAL
0x84A1	0x250C	# BOX DRAWINGS LIGHT DOWN AND RIGHT
0x84A2	0x2510	# BOX DRAWINGS LIGHT DOWN AND LEFT
0x84A3	0x2518	# BOX DRAWINGS LIGHT UP AND LEFT
0x84A4	0x2514	# BOX DRAWINGS LIGHT UP AND RIGHT
0x84A5	0x251C	# BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0x84A6	0x252C	# BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0x84A7	0x2524	# BOX DRAWINGS LIGHT VERTICAL AND LEFT
0x84A8	0x2534	# BOX DRAWINGS LIGHT UP AND HORIZONTAL
0x84A9	0x253C	# BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0x84AA	0x2501	# BOX DRAWINGS HEAVY HORIZONTAL
0x84AB	0x2503	# BOX DRAWINGS HEAVY VERTICAL
0x84AC	0x250F	# BOX DRAWINGS HEAVY DOWN AND RIGHT
0x84AD	0x2513	# BOX DRAWINGS HEAVY DOWN AND LEFT
0x84AE	0x251B	# BOX DRAWINGS HEAVY UP AND LEFT
0x84AF	0x2517	# BOX DRAWINGS HEAVY UP AND RIGHT
0x84B0	0x2523	# BOX DRAWINGS HEAVY VERTICAL AND RIGHT
0x84B1	0x2533	# BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
0x84B2	0x252B	# BOX DRAWINGS HEAVY VERTICAL AND LEFT
0x84B3	0x253B	# BOX DRAWINGS HEAVY UP AND HORIZONTAL
0x84B4	0x254B	# BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
0x84B5	0x2520	# BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
0x84B6	0x252F	# BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
0x84B7	0x2528	# BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
0x84B8	0x2537	# BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
0x84B9	0x253F	# BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
0x84BA	0x251D	# BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
0x84BB	0x2530	# BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
0x84BC	0x2525	# BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
0x84BD	0x2538	# BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
0x84BE	0x2542	# BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
0x889F	0x4E9C	# <CJK>
0x88A0	0x5516	# <CJK>
0x88A1	0x5A03	# <CJK>
0x88A2	0x963F	# <CJK>
0x88A3	0x54C0	# <CJK>
0x88A4	0x611B	# <CJK>
0x88A5	0x6328	# <CJK>
0x88A6	0x59F6	# <CJK>
0x88A7	0x9022	# <CJK>
0x88A8	0x8475	# <CJK>
0x88A9	0x831C	# <CJK>
0x88AA	0x7A50	# <CJK>
0x88AB	0x60AA	# <CJK>
0x88AC	0x63E1	# <CJK>
0x88AD	0x6E25	# <CJK>
0x88AE	0x65ED	# <CJK>
0x88AF	0x8466	# <CJK>
0x88B0	0x82A6	# <CJK>
0x88B1	0x9BF5	# <CJK>
0x88B2	0x6893	# <CJK>
0x88B3	0x5727	# <CJK>
0x88B4	0x65A1	# <CJK>
0x88B5	0x6271	# <CJK>
0x88B6	0x5B9B	# <CJK>
0x88B7	0x59D0	# <CJK>
0x88B8	0x867B	# <CJK>
0x88B9	0x98F4	# <CJK>
0x88BA	0x7D62	# <CJK>
0x88BB	0x7DBE	# <CJK>
0x88BC	0x9B8E	# <CJK>
0x88BD	0x6216	# <CJK>
0x88BE	0x7C9F	# <CJK>
0x88BF	0x88B7	# <CJK>
0x88C0	0x5B89	# <CJK>
0x88C1	0x5EB5	# <CJK>
0x88C2	0x6309	# <CJK>
0x88C3	0x6697	# <CJK>
0x88C4	0x6848	# <CJK>
0x88C5	0x95C7	# <CJK>
0x88C6	0x978D	# <CJK>
0x88C7	0x674F	# <CJK>
0x88C8	0x4EE5	# <CJK>
0x88C9	0x4F0A	# <CJK>
0x88CA	0x4F4D	# <CJK>
0x88CB	0x4F9D	# <CJK>
0x88CC	0x5049	# <CJK>
0x88CD	0x56F2	# <CJK>
0x88CE	0x5937	# <CJK>
0x88CF	0x59D4	# <CJK>
0x88D0	0x5A01	# <CJK>
0x88D1	0x5C09	# <CJK>
0x88D2	0x60DF	# <CJK>
0x88D3	0x610F	# <CJK>
0x88D4	0x6170	# <CJK>
0x88D5	0x6613	# <CJK>
0x88D6	0x6905	# <CJK>
0x88D7	0x70BA	# <CJK>
0x88D8	0x754F	# <CJK>
0x88D9	0x7570	# <CJK>
0x88DA	0x79FB	# <CJK>
0x88DB	0x7DAD	# <CJK>
0x88DC	0x7DEF	# <CJK>
0x88DD	0x80C3	# <CJK>
0x88DE	0x840E	# <CJK>
0x88DF	0x8863	# <CJK>
0x88E0	0x8B02	# <CJK>
0x88E1	0x9055	# <CJK>
0x88E2	0x907A	# <CJK>
0x88E3	0x533B	# <CJK>
0x88E4	0x4E95	# <CJK>
0x88E5	0x4EA5	# <CJK>
0x88E6	0x57DF	# <CJK>
0x88E7	0x80B2	# <CJK>
0x88E8	0x90C1	# <CJK>
0x88E9	0x78EF	# <CJK>
0x88EA	0x4E00	# <CJK>
0x88EB	0x58F1	# <CJK>
0x88EC	0x6EA2	# <CJK>
0x88ED	0x9038	# <CJK>
0x88EE	0x7A32	# <CJK>
0x88EF	0x8328	# <CJK>
0x88F0	0x828B	# <CJK>
0x88F1	0x9C2F	# <CJK>
0x88F2	0x5141	# <CJK>
0x88F3	0x5370	# <CJK>
0x88F4	0x54BD	# <CJK>
0x88F5	0x54E1	# <CJK>
0x88F6	0x56E0	# <CJK>
0x88F7	0x59FB	# <CJK>
0x88F8	0x5F15	# <CJK>
0x88F9	0x98F2	# <CJK>
0x88FA	0x6DEB	# <CJK>
0x88FB	0x80E4	# <CJK>
0x88FC	0x852D	# <CJK>
0x8940	0x9662	# <CJK>
0x8941	0x9670	# <CJK>
0x8942	0x96A0	# <CJK>
0x8943	0x97FB	# <CJK>
0x8944	0x540B	# <CJK>
0x8945	0x53F3	# <CJK>
0x8946	0x5B87	# <CJK>
0x8947	0x70CF	# <CJK>
0x8948	0x7FBD	# <CJK>
0x8949	0x8FC2	# <CJK>
0x894A	0x96E8	# <CJK>
0x894B	0x536F	# <CJK>
0x894C	0x9D5C	# <CJK>
0x894D	0x7ABA	# <CJK>
0x894E	0x4E11	# <CJK>
0x894F	0x7893	# <CJK>
0x8950	0x81FC	# <CJK>
0x8951	0x6E26	# <CJK>
0x8952	0x5618	# <CJK>
0x8953	0x5504	# <CJK>
0x8954	0x6B1D	# <CJK>
0x8955	0x851A	# <CJK>
0x8956	0x9C3B	# <CJK>
0x8957	0x59E5	# <CJK>
0x8958	0x53A9	# <CJK>
0x8959	0x6D66	# <CJK>
0x895A	0x74DC	# <CJK>
0x895B	0x958F	# <CJK>
0x895C	0x5642	# <CJK>
0x895D	0x4E91	# <CJK>
0x895E	0x904B	# <CJK>
0x895F	0x96F2	# <CJK>
0x8960	0x834F	# <CJK>
0x8961	0x990C	# <CJK>
0x8962	0x53E1	# <CJK>
0x8963	0x55B6	# <CJK>
0x8964	0x5B30	# <CJK>
0x8965	0x5F71	# <CJK>
0x8966	0x6620	# <CJK>
0x8967	0x66F3	# <CJK>
0x8968	0x6804	# <CJK>
0x8969	0x6C38	# <CJK>
0x896A	0x6CF3	# <CJK>
0x896B	0x6D29	# <CJK>
0x896C	0x745B	# <CJK>
0x896D	0x76C8	# <CJK>
0x896E	0x7A4E	# <CJK>
0x896F	0x9834	# <CJK>
0x8970	0x82F1	# <CJK>
0x8971	0x885B	# <CJK>
0x8972	0x8A60	# <CJK>
0x8973	0x92ED	# <CJK>
0x8974	0x6DB2	# <CJK>
0x8975	0x75AB	# <CJK>
0x8976	0x76CA	# <CJK>
0x8977	0x99C5	# <CJK>
0x8978	0x60A6	# <CJK>
0x8979	0x8B01	# <CJK>
0x897A	0x8D8A	# <CJK>
0x897B	0x95B2	# <CJK>
0x897C	0x698E	# <CJK>
0x897D	0x53AD	# <CJK>
0x897E	0x5186	# <CJK>
0x8980	0x5712	# <CJK>
0x8981	0x5830	# <CJK>
0x8982	0x5944	# <CJK>
0x8983	0x5BB4	# <CJK>
0x8984	0x5EF6	# <CJK>
0x8985	0x6028	# <CJK>
0x8986	0x63A9	# <CJK>
0x8987	0x63F4	# <CJK>
0x8988	0x6CBF	# <CJK>
0x8989	0x6F14	# <CJK>
0x898A	0x708E	# <CJK>
0x898B	0x7114	# <CJK>
0x898C	0x7159	# <CJK>
0x898D	0x71D5	# <CJK>
0x898E	0x733F	# <CJK>
0x898F	0x7E01	# <CJK>
0x8990	0x8276	# <CJK>
0x8991	0x82D1	# <CJK>
0x8992	0x8597	# <CJK>
0x8993	0x9060	# <CJK>
0x8994	0x925B	# <CJK>
0x8995	0x9D1B	# <CJK>
0x8996	0x5869	# <CJK>
0x8997	0x65BC	# <CJK>
0x8998	0x6C5A	# <CJK>
0x8999	0x7525	# <CJK>
0x899A	0x51F9	# <CJK>
0x899B	0x592E	# <CJK>
0x899C	0x5965	# <CJK>
0x899D	0x5F80	# <CJK>
0x899E	0x5FDC	# <CJK>
0x899F	0x62BC	# <CJK>
0x89A0	0x65FA	# <CJK>
0x89A1	0x6A2A	# <CJK>
0x89A2	0x6B27	# <CJK>
0x89A3	0x6BB4	# <CJK>
0x89A4	0x738B	# <CJK>
0x89A5	0x7FC1	# <CJK>
0x89A6	0x8956	# <CJK>
0x89A7	0x9D2C	# <CJK>
0x89A8	0x9D0E	# <CJK>
0x89A9	0x9EC4	# <CJK>
0x89AA	0x5CA1	# <CJK>
0x89AB	0x6C96	# <CJK>
0x89AC	0x837B	# <CJK>
0x89AD	0x5104	# <CJK>
0x89AE	0x5C4B	# <CJK>
0x89AF	0x61B6	# <CJK>
0x89B0	0x81C6	# <CJK>
0x89B1	0x6876	# <CJK>
0x89B2	0x7261	# <CJK>
0x89B3	0x4E59	# <CJK>
0x89B4	0x4FFA	# <CJK>
0x89B5	0x5378	# <CJK>
0x89B6	0x6069	# <CJK>
0x89B7	0x6E29	# <CJK>
0x89B8	0x7A4F	# <CJK>
0x89B9	0x97F3	# <CJK>
0x89BA	0x4E0B	# <CJK>
0x89BB	0x5316	# <CJK>
0x89BC	0x4EEE	# <CJK>
0x89BD	0x4F55	# <CJK>
0x89BE	0x4F3D	# <CJK>
0x89BF	0x4FA1	# <CJK>
0x89C0	0x4F73	# <CJK>
0x89C1	0x52A0	# <CJK>
0x89C2	0x53EF	# <CJK>
0x89C3	0x5609	# <CJK>
0x89C4	0x590F	# <CJK>
0x89C5	0x5AC1	# <CJK>
0x89C6	0x5BB6	# <CJK>
0x89C7	0x5BE1	# <CJK>
0x89C8	0x79D1	# <CJK>
0x89C9	0x6687	# <CJK>
0x89CA	0x679C	# <CJK>
0x89CB	0x67B6	# <CJK>
0x89CC	0x6B4C	# <CJK>
0x89CD	0x6CB3	# <CJK>
0x89CE	0x706B	# <CJK>
0x89CF	0x73C2	# <CJK>
0x89D0	0x798D	# <CJK>
0x89D1	0x79BE	# <CJK>
0x89D2	0x7A3C	# <CJK>
0x89D3	0x7B87	# <CJK>
0x89D4	0x82B1	# <CJK>
0x89D5	0x82DB	# <CJK>
0x89D6	0x8304	# <CJK>
0x89D7	0x8377	# <CJK>
0x89D8	0x83EF	# <CJK>
0x89D9	0x83D3	# <CJK>
0x89DA	0x8766	# <CJK>
0x89DB	0x8AB2	# <CJK>
0x89DC	0x5629	# <CJK>
0x89DD	0x8CA8	# <CJK>
0x89DE	0x8FE6	# <CJK>
0x89DF	0x904E	# <CJK>
0x89E0	0x971E	# <CJK>
0x89E1	0x868A	# <CJK>
0x89E2	0x4FC4	# <CJK>
0x89E3	0x5CE8	# <CJK>
0x89E4	0x6211	# <CJK>
0x89E5	0x7259	# <CJK>
0x89E6	0x753B	# <CJK>
0x89E7	0x81E5	# <CJK>
0x89E8	0x82BD	# <CJK>
0x89E9	0x86FE	# <CJK>
0x89EA	0x8CC0	# <CJK>
0x89EB	0x96C5	# <CJK>
0x89EC	0x9913	# <CJK>
0x89ED	0x99D5	# <CJK>
0x89EE	0x4ECB	# <CJK>
0x89EF	0x4F1A	# <CJK>
0x89F0	0x89E3	# <CJK>
0x89F1	0x56DE	# <CJK>
0x89F2	0x584A	# <CJK>
0x89F3	0x58CA	# <CJK>
0x89F4	0x5EFB	# <CJK>
0x89F5	0x5FEB	# <CJK>
0x89F6	0x602A	# <CJK>
0x89F7	0x6094	# <CJK>
0x89F8	0x6062	# <CJK>
0x89F9	0x61D0	# <CJK>
0x89FA	0x6212	# <CJK>
0x89FB	0x62D0	# <CJK>
0x89FC	0x6539	# <CJK>
0x8A40	0x9B41	# <CJK>
0x8A41	0x6666	# <CJK>
0x8A42	0x68B0	# <CJK>
0x8A43	0x6D77	# <CJK>
0x8A44	0x7070	# <CJK>
0x8A45	0x754C	# <CJK>
0x8A46	0x7686	# <CJK>
0x8A47	0x7D75	# <CJK>
0x8A48	0x82A5	# <CJK>
0x8A49	0x87F9	# <CJK>
0x8A4A	0x958B	# <CJK>
0x8A4B	0x968E	# <CJK>
0x8A4C	0x8C9D	# <CJK>
0x8A4D	0x51F1	# <CJK>
0x8A4E	0x52BE	# <CJK>
0x8A4F	0x5916	# <CJK>
0x8A50	0x54B3	# <CJK>
0x8A51	0x5BB3	# <CJK>
0x8A52	0x5D16	# <CJK>
0x8A53	0x6168	# <CJK>
0x8A54	0x6982	# <CJK>
0x8A55	0x6DAF	# <CJK>
0x8A56	0x788D	# <CJK>
0x8A57	0x84CB	# <CJK>
0x8A58	0x8857	# <CJK>
0x8A59	0x8A72	# <CJK>
0x8A5A	0x93A7	# <CJK>
0x8A5B	0x9AB8	# <CJK>
0x8A5C	0x6D6C	# <CJK>
0x8A5D	0x99A8	# <CJK>
0x8A5E	0x86D9	# <CJK>
0x8A5F	0x57A3	# <CJK>
0x8A60	0x67FF	# <CJK>
0x8A61	0x86CE	# <CJK>
0x8A62	0x920E	# <CJK>
0x8A63	0x5283	# <CJK>
0x8A64	0x5687	# <CJK>
0x8A65	0x5404	# <CJK>
0x8A66	0x5ED3	# <CJK>
0x8A67	0x62E1	# <CJK>
0x8A68	0x64B9	# <CJK>
0x8A69	0x683C	# <CJK>
0x8A6A	0x6838	# <CJK>
0x8A6B	0x6BBB	# <CJK>
0x8A6C	0x7372	# <CJK>
0x8A6D	0x78BA	# <CJK>
0x8A6E	0x7A6B	# <CJK>
0x8A6F	0x899A	# <CJK>
0x8A70	0x89D2	# <CJK>
0x8A71	0x8D6B	# <CJK>
0x8A72	0x8F03	# <CJK>
0x8A73	0x90ED	# <CJK>
0x8A74	0x95A3	# <CJK>
0x8A75	0x9694	# <CJK>
0x8A76	0x9769	# <CJK>
0x8A77	0x5B66	# <CJK>
0x8A78	0x5CB3	# <CJK>
0x8A79	0x697D	# <CJK>
0x8A7A	0x984D	# <CJK>
0x8A7B	0x984E	# <CJK>
0x8A7C	0x639B	# <CJK>
0x8A7D	0x7B20	# <CJK>
0x8A7E	0x6A2B	# <CJK>
0x8A80	0x6A7F	# <CJK>
0x8A81	0x68B6	# <CJK>
0x8A82	0x9C0D	# <CJK>
0x8A83	0x6F5F	# <CJK>
0x8A84	0x5272	# <CJK>
0x8A85	0x559D	# <CJK>
0x8A86	0x6070	# <CJK>
0x8A87	0x62EC	# <CJK>
0x8A88	0x6D3B	# <CJK>
0x8A89	0x6E07	# <CJK>
0x8A8A	0x6ED1	# <CJK>
0x8A8B	0x845B	# <CJK>
0x8A8C	0x8910	# <CJK>
0x8A8D	0x8F44	# <CJK>
0x8A8E	0x4E14	# <CJK>
0x8A8F	0x9C39	# <CJK>
0x8A90	0x53F6	# <CJK>
0x8A91	0x691B	# <CJK>
0x8A92	0x6A3A	# <CJK>
0x8A93	0x9784	# <CJK>
0x8A94	0x682A	# <CJK>
0x8A95	0x515C	# <CJK>
0x8A96	0x7AC3	# <CJK>
0x8A97	0x84B2	# <CJK>
0x8A98	0x91DC	# <CJK>
0x8A99	0x938C	# <CJK>
0x8A9A	0x565B	# <CJK>
0x8A9B	0x9D28	# <CJK>
0x8A9C	0x6822	# <CJK>
0x8A9D	0x8305	# <CJK>
0x8A9E	0x8431	# <CJK>
0x8A9F	0x7CA5	# <CJK>
0x8AA0	0x5208	# <CJK>
0x8AA1	0x82C5	# <CJK>
0x8AA2	0x74E6	# <CJK>
0x8AA3	0x4E7E	# <CJK>
0x8AA4	0x4F83	# <CJK>
0x8AA5	0x51A0	# <CJK>
0x8AA6	0x5BD2	# <CJK>
0x8AA7	0x520A	# <CJK>
0x8AA8	0x52D8	# <CJK>
0x8AA9	0x52E7	# <CJK>
0x8AAA	0x5DFB	# <CJK>
0x8AAB	0x559A	# <CJK>
0x8AAC	0x582A	# <CJK>
0x8AAD	0x59E6	# <CJK>
0x8AAE	0x5B8C	# <CJK>
0x8AAF	0x5B98	# <CJK>
0x8AB0	0x5BDB	# <CJK>
0x8AB1	0x5E72	# <CJK>
0x8AB2	0x5E79	# <CJK>
0x8AB3	0x60A3	# <CJK>
0x8AB4	0x611F	# <CJK>
0x8AB5	0x6163	# <CJK>
0x8AB6	0x61BE	# <CJK>
0x8AB7	0x63DB	# <CJK>
0x8AB8	0x6562	# <CJK>
0x8AB9	0x67D1	# <CJK>
0x8ABA	0x6853	# <CJK>
0x8ABB	0x68FA	# <CJK>
0x8ABC	0x6B3E	# <CJK>
0x8ABD	0x6B53	# <CJK>
0x8ABE	0x6C57	# <CJK>
0x8ABF	0x6F22	# <CJK>
0x8AC0	0x6F97	# <CJK>
0x8AC1	0x6F45	# <CJK>
0x8AC2	0x74B0	# <CJK>
0x8AC3	0x7518	# <CJK>
0x8AC4	0x76E3	# <CJK>
0x8AC5	0x770B	# <CJK>
0x8AC6	0x7AFF	# <CJK>
0x8AC7	0x7BA1	# <CJK>
0x8AC8	0x7C21	# <CJK>
0x8AC9	0x7DE9	# <CJK>
0x8ACA	0x7F36	# <CJK>
0x8ACB	0x7FF0	# <CJK>
0x8ACC	0x809D	# <CJK>
0x8ACD	0x8266	# <CJK>
0x8ACE	0x839E	# <CJK>
0x8ACF	0x89B3	# <CJK>
0x8AD0	0x8ACC	# <CJK>
0x8AD1	0x8CAB	# <CJK>
0x8AD2	0x9084	# <CJK>
0x8AD3	0x9451	# <CJK>
0x8AD4	0x9593	# <CJK>
0x8AD5	0x9591	# <CJK>
0x8AD6	0x95A2	# <CJK>
0x8AD7	0x9665	# <CJK>
0x8AD8	0x97D3	# <CJK>
0x8AD9	0x9928	# <CJK>
0x8ADA	0x8218	# <CJK>
0x8ADB	0x4E38	# <CJK>
0x8ADC	0x542B	# <CJK>
0x8ADD	0x5CB8	# <CJK>
0x8ADE	0x5DCC	# <CJK>
0x8ADF	0x73A9	# <CJK>
0x8AE0	0x764C	# <CJK>
0x8AE1	0x773C	# <CJK>
0x8AE2	0x5CA9	# <CJK>
0x8AE3	0x7FEB	# <CJK>
0x8AE4	0x8D0B	# <CJK>
0x8AE5	0x96C1	# <CJK>
0x8AE6	0x9811	# <CJK>
0x8AE7	0x9854	# <CJK>
0x8AE8	0x9858	# <CJK>
0x8AE9	0x4F01	# <CJK>
0x8AEA	0x4F0E	# <CJK>
0x8AEB	0x5371	# <CJK>
0x8AEC	0x559C	# <CJK>
0x8AED	0x5668	# <CJK>
0x8AEE	0x57FA	# <CJK>
0x8AEF	0x5947	# <CJK>
0x8AF0	0x5B09	# <CJK>
0x8AF1	0x5BC4	# <CJK>
0x8AF2	0x5C90	# <CJK>
0x8AF3	0x5E0C	# <CJK>
0x8AF4	0x5E7E	# <CJK>
0x8AF5	0x5FCC	# <CJK>
0x8AF6	0x63EE	# <CJK>
0x8AF7	0x673A	# <CJK>
0x8AF8	0x65D7	# <CJK>
0x8AF9	0x65E2	# <CJK>
0x8AFA	0x671F	# <CJK>
0x8AFB	0x68CB	# <CJK>
0x8AFC	0x68C4	# <CJK>
0x8B40	0x6A5F	# <CJK>
0x8B41	0x5E30	# <CJK>
0x8B42	0x6BC5	# <CJK>
0x8B43	0x6C17	# <CJK>
0x8B44	0x6C7D	# <CJK>
0x8B45	0x757F	# <CJK>
0x8B46	0x7948	# <CJK>
0x8B47	0x5B63	# <CJK>
0x8B48	0x7A00	# <CJK>
0x8B49	0x7D00	# <CJK>
0x8B4A	0x5FBD	# <CJK>
0x8B4B	0x898F	# <CJK>
0x8B4C	0x8A18	# <CJK>
0x8B4D	0x8CB4	# <CJK>
0x8B4E	0x8D77	# <CJK>
0x8B4F	0x8ECC	# <CJK>
0x8B50	0x8F1D	# <CJK>
0x8B51	0x98E2	# <CJK>
0x8B52	0x9A0E	# <CJK>
0x8B53	0x9B3C	# <CJK>
0x8B54	0x4E80	# <CJK>
0x8B55	0x507D	# <CJK>
0x8B56	0x5100	# <CJK>
0x8B57	0x5993	# <CJK>
0x8B58	0x5B9C	# <CJK>
0x8B59	0x622F	# <CJK>
0x8B5A	0x6280	# <CJK>
0x8B5B	0x64EC	# <CJK>
0x8B5C	0x6B3A	# <CJK>
0x8B5D	0x72A0	# <CJK>
0x8B5E	0x7591	# <CJK>
0x8B5F	0x7947	# <CJK>
0x8B60	0x7FA9	# <CJK>
0x8B61	0x87FB	# <CJK>
0x8B62	0x8ABC	# <CJK>
0x8B63	0x8B70	# <CJK>
0x8B64	0x63AC	# <CJK>
0x8B65	0x83CA	# <CJK>
0x8B66	0x97A0	# <CJK>
0x8B67	0x5409	# <CJK>
0x8B68	0x5403	# <CJK>
0x8B69	0x55AB	# <CJK>
0x8B6A	0x6854	# <CJK>
0x8B6B	0x6A58	# <CJK>
0x8B6C	0x8A70	# <CJK>
0x8B6D	0x7827	# <CJK>
0x8B6E	0x6775	# <CJK>
0x8B6F	0x9ECD	# <CJK>
0x8B70	0x5374	# <CJK>
0x8B71	0x5BA2	# <CJK>
0x8B72	0x811A	# <CJK>
0x8B73	0x8650	# <CJK>
0x8B74	0x9006	# <CJK>
0x8B75	0x4E18	# <CJK>
0x8B76	0x4E45	# <CJK>
0x8B77	0x4EC7	# <CJK>
0x8B78	0x4F11	# <CJK>
0x8B79	0x53CA	# <CJK>
0x8B7A	0x5438	# <CJK>
0x8B7B	0x5BAE	# <CJK>
0x8B7C	0x5F13	# <CJK>
0x8B7D	0x6025	# <CJK>
0x8B7E	0x6551	# <CJK>
0x8B80	0x673D	# <CJK>
0x8B81	0x6C42	# <CJK>
0x8B82	0x6C72	# <CJK>
0x8B83	0x6CE3	# <CJK>
0x8B84	0x7078	# <CJK>
0x8B85	0x7403	# <CJK>
0x8B86	0x7A76	# <CJK>
0x8B87	0x7AAE	# <CJK>
0x8B88	0x7B08	# <CJK>
0x8B89	0x7D1A	# <CJK>
0x8B8A	0x7CFE	# <CJK>
0x8B8B	0x7D66	# <CJK>
0x8B8C	0x65E7	# <CJK>
0x8B8D	0x725B	# <CJK>
0x8B8E	0x53BB	# <CJK>
0x8B8F	0x5C45	# <CJK>
0x8B90	0x5DE8	# <CJK>
0x8B91	0x62D2	# <CJK>
0x8B92	0x62E0	# <CJK>
0x8B93	0x6319	# <CJK>
0x8B94	0x6E20	# <CJK>
0x8B95	0x865A	# <CJK>
0x8B96	0x8A31	# <CJK>
0x8B97	0x8DDD	# <CJK>
0x8B98	0x92F8	# <CJK>
0x8B99	0x6F01	# <CJK>
0x8B9A	0x79A6	# <CJK>
0x8B9B	0x9B5A	# <CJK>
0x8B9C	0x4EA8	# <CJK>
0x8B9D	0x4EAB	# <CJK>
0x8B9E	0x4EAC	# <CJK>
0x8B9F	0x4F9B	# <CJK>
0x8BA0	0x4FA0	# <CJK>
0x8BA1	0x50D1	# <CJK>
0x8BA2	0x5147	# <CJK>
0x8BA3	0x7AF6	# <CJK>
0x8BA4	0x5171	# <CJK>
0x8BA5	0x51F6	# <CJK>
0x8BA6	0x5354	# <CJK>
0x8BA7	0x5321	# <CJK>
0x8BA8	0x537F	# <CJK>
0x8BA9	0x53EB	# <CJK>
0x8BAA	0x55AC	# <CJK>
0x8BAB	0x5883	# <CJK>
0x8BAC	0x5CE1	# <CJK>
0x8BAD	0x5F37	# <CJK>
0x8BAE	0x5F4A	# <CJK>
0x8BAF	0x602F	# <CJK>
0x8BB0	0x6050	# <CJK>
0x8BB1	0x606D	# <CJK>
0x8BB2	0x631F	# <CJK>
0x8BB3	0x6559	# <CJK>
0x8BB4	0x6A4B	# <CJK>
0x8BB5	0x6CC1	# <CJK>
0x8BB6	0x72C2	# <CJK>
0x8BB7	0x72ED	# <CJK>
0x8BB8	0x77EF	# <CJK>
0x8BB9	0x80F8	# <CJK>
0x8BBA	0x8105	# <CJK>
0x8BBB	0x8208	# <CJK>
0x8BBC	0x854E	# <CJK>
0x8BBD	0x90F7	# <CJK>
0x8BBE	0x93E1	# <CJK>
0x8BBF	0x97FF	# <CJK>
0x8BC0	0x9957	# <CJK>
0x8BC1	0x9A5A	# <CJK>
0x8BC2	0x4EF0	# <CJK>
0x8BC3	0x51DD	# <CJK>
0x8BC4	0x5C2D	# <CJK>
0x8BC5	0x6681	# <CJK>
0x8BC6	0x696D	# <CJK>
0x8BC7	0x5C40	# <CJK>
0x8BC8	0x66F2	# <CJK>
0x8BC9	0x6975	# <CJK>
0x8BCA	0x7389	# <CJK>
0x8BCB	0x6850	# <CJK>
0x8BCC	0x7C81	# <CJK>
0x8BCD	0x50C5	# <CJK>
0x8BCE	0x52E4	# <CJK>
0x8BCF	0x5747	# <CJK>
0x8BD0	0x5DFE	# <CJK>
0x8BD1	0x9326	# <CJK>
0x8BD2	0x65A4	# <CJK>
0x8BD3	0x6B23	# <CJK>
0x8BD4	0x6B3D	# <CJK>
0x8BD5	0x7434	# <CJK>
0x8BD6	0x7981	# <CJK>
0x8BD7	0x79BD	# <CJK>
0x8BD8	0x7B4B	# <CJK>
0x8BD9	0x7DCA	# <CJK>
0x8BDA	0x82B9	# <CJK>
0x8BDB	0x83CC	# <CJK>
0x8BDC	0x887F	# <CJK>
0x8BDD	0x895F	# <CJK>
0x8BDE	0x8B39	# <CJK>
0x8BDF	0x8FD1	# <CJK>
0x8BE0	0x91D1	# <CJK>
0x8BE1	0x541F	# <CJK>
0x8BE2	0x9280	# <CJK>
0x8BE3	0x4E5D	# <CJK>
0x8BE4	0x5036	# <CJK>
0x8BE5	0x53E5	# <CJK>
0x8BE6	0x533A	# <CJK>
0x8BE7	0x72D7	# <CJK>
0x8BE8	0x7396	# <CJK>
0x8BE9	0x77E9	# <CJK>
0x8BEA	0x82E6	# <CJK>
0x8BEB	0x8EAF	# <CJK>
0x8BEC	0x99C6	# <CJK>
0x8BED	0x99C8	# <CJK>
0x8BEE	0x99D2	# <CJK>
0x8BEF	0x5177	# <CJK>
0x8BF0	0x611A	# <CJK>
0x8BF1	0x865E	# <CJK>
0x8BF2	0x55B0	# <CJK>
0x8BF3	0x7A7A	# <CJK>
0x8BF4	0x5076	# <CJK>
0x8BF5	0x5BD3	# <CJK>
0x8BF6	0x9047	# <CJK>
0x8BF7	0x9685	# <CJK>
0x8BF8	0x4E32	# <CJK>
0x8BF9	0x6ADB	# <CJK>
0x8BFA	0x91E7	# <CJK>
0x8BFB	0x5C51	# <CJK>
0x8BFC	0x5C48	# <CJK>
0x8C40	0x6398	# <CJK>
0x8C41	0x7A9F	# <CJK>
0x8C42	0x6C93	# <CJK>
0x8C43	0x9774	# <CJK>
0x8C44	0x8F61	# <CJK>
0x8C45	0x7AAA	# <CJK>
0x8C46	0x718A	# <CJK>
0x8C47	0x9688	# <CJK>
0x8C48	0x7C82	# <CJK>
0x8C49	0x6817	# <CJK>
0x8C4A	0x7E70	# <CJK>
0x8C4B	0x6851	# <CJK>
0x8C4C	0x936C	# <CJK>
0x8C4D	0x52F2	# <CJK>
0x8C4E	0x541B	# <CJK>
0x8C4F	0x85AB	# <CJK>
0x8C50	0x8A13	# <CJK>
0x8C51	0x7FA4	# <CJK>
0x8C52	0x8ECD	# <CJK>
0x8C53	0x90E1	# <CJK>
0x8C54	0x5366	# <CJK>
0x8C55	0x8888	# <CJK>
0x8C56	0x7941	# <CJK>
0x8C57	0x4FC2	# <CJK>
0x8C58	0x50BE	# <CJK>
0x8C59	0x5211	# <CJK>
0x8C5A	0x5144	# <CJK>
0x8C5B	0x5553	# <CJK>
0x8C5C	0x572D	# <CJK>
0x8C5D	0x73EA	# <CJK>
0x8C5E	0x578B	# <CJK>
0x8C5F	0x5951	# <CJK>
0x8C60	0x5F62	# <CJK>
0x8C61	0x5F84	# <CJK>
0x8C62	0x6075	# <CJK>
0x8C63	0x6176	# <CJK>
0x8C64	0x6167	# <CJK>
0x8C65	0x61A9	# <CJK>
0x8C66	0x63B2	# <CJK>
0x8C67	0x643A	# <CJK>
0x8C68	0x656C	# <CJK>
0x8C69	0x666F	# <CJK>
0x8C6A	0x6842	# <CJK>
0x8C6B	0x6E13	# <CJK>
0x8C6C	0x7566	# <CJK>
0x8C6D	0x7A3D	# <CJK>
0x8C6E	0x7CFB	# <CJK>
0x8C6F	0x7D4C	# <CJK>
0x8C70	0x7D99	# <CJK>
0x8C71	0x7E4B	# <CJK>
0x8C72	0x7F6B	# <CJK>
0x8C73	0x830E	# <CJK>
0x8C74	0x834A	# <CJK>
0x8C75	0x86CD	# <CJK>
0x8C76	0x8A08	# <CJK>
0x8C77	0x8A63	# <CJK>
0x8C78	0x8B66	# <CJK>
0x8C79	0x8EFD	# <CJK>
0x8C7A	0x981A	# <CJK>
0x8C7B	0x9D8F	# <CJK>
0x8C7C	0x82B8	# <CJK>
0x8C7D	0x8FCE	# <CJK>
0x8C7E	0x9BE8	# <CJK>
0x8C80	0x5287	# <CJK>
0x8C81	0x621F	# <CJK>
0x8C82	0x6483	# <CJK>
0x8C83	0x6FC0	# <CJK>
0x8C84	0x9699	# <CJK>
0x8C85	0x6841	# <CJK>
0x8C86	0x5091	# <CJK>
0x8C87	0x6B20	# <CJK>
0x8C88	0x6C7A	# <CJK>
0x8C89	0x6F54	# <CJK>
0x8C8A	0x7A74	# <CJK>
0x8C8B	0x7D50	# <CJK>
0x8C8C	0x8840	# <CJK>
0x8C8D	0x8A23	# <CJK>
0x8C8E	0x6708	# <CJK>
0x8C8F	0x4EF6	# <CJK>
0x8C90	0x5039	# <CJK>
0x8C91	0x5026	# <CJK>
0x8C92	0x5065	# <CJK>
0x8C93	0x517C	# <CJK>
0x8C94	0x5238	# <CJK>
0x8C95	0x5263	# <CJK>
0x8C96	0x55A7	# <CJK>
0x8C97	0x570F	# <CJK>
0x8C98	0x5805	# <CJK>
0x8C99	0x5ACC	# <CJK>
0x8C9A	0x5EFA	# <CJK>
0x8C9B	0x61B2	# <CJK>
0x8C9C	0x61F8	# <CJK>
0x8C9D	0x62F3	# <CJK>
0x8C9E	0x6372	# <CJK>
0x8C9F	0x691C	# <CJK>
0x8CA0	0x6A29	# <CJK>
0x8CA1	0x727D	# <CJK>
0x8CA2	0x72AC	# <CJK>
0x8CA3	0x732E	# <CJK>
0x8CA4	0x7814	# <CJK>
0x8CA5	0x786F	# <CJK>
0x8CA6	0x7D79	# <CJK>
0x8CA7	0x770C	# <CJK>
0x8CA8	0x80A9	# <CJK>
0x8CA9	0x898B	# <CJK>
0x8CAA	0x8B19	# <CJK>
0x8CAB	0x8CE2	# <CJK>
0x8CAC	0x8ED2	# <CJK>
0x8CAD	0x9063	# <CJK>
0x8CAE	0x9375	# <CJK>
0x8CAF	0x967A	# <CJK>
0x8CB0	0x9855	# <CJK>
0x8CB1	0x9A13	# <CJK>
0x8CB2	0x9E78	# <CJK>
0x8CB3	0x5143	# <CJK>
0x8CB4	0x539F	# <CJK>
0x8CB5	0x53B3	# <CJK>
0x8CB6	0x5E7B	# <CJK>
0x8CB7	0x5F26	# <CJK>
0x8CB8	0x6E1B	# <CJK>
0x8CB9	0x6E90	# <CJK>
0x8CBA	0x7384	# <CJK>
0x8CBB	0x73FE	# <CJK>
0x8CBC	0x7D43	# <CJK>
0x8CBD	0x8237	# <CJK>
0x8CBE	0x8A00	# <CJK>
0x8CBF	0x8AFA	# <CJK>
0x8CC0	0x9650	# <CJK>
0x8CC1	0x4E4E	# <CJK>
0x8CC2	0x500B	# <CJK>
0x8CC3	0x53E4	# <CJK>
0x8CC4	0x547C	# <CJK>
0x8CC5	0x56FA	# <CJK>
0x8CC6	0x59D1	# <CJK>
0x8CC7	0x5B64	# <CJK>
0x8CC8	0x5DF1	# <CJK>
0x8CC9	0x5EAB	# <CJK>
0x8CCA	0x5F27	# <CJK>
0x8CCB	0x6238	# <CJK>
0x8CCC	0x6545	# <CJK>
0x8CCD	0x67AF	# <CJK>
0x8CCE	0x6E56	# <CJK>
0x8CCF	0x72D0	# <CJK>
0x8CD0	0x7CCA	# <CJK>
0x8CD1	0x88B4	# <CJK>
0x8CD2	0x80A1	# <CJK>
0x8CD3	0x80E1	# <CJK>
0x8CD4	0x83F0	# <CJK>
0x8CD5	0x864E	# <CJK>
0x8CD6	0x8A87	# <CJK>
0x8CD7	0x8DE8	# <CJK>
0x8CD8	0x9237	# <CJK>
0x8CD9	0x96C7	# <CJK>
0x8CDA	0x9867	# <CJK>
0x8CDB	0x9F13	# <CJK>
0x8CDC	0x4E94	# <CJK>
0x8CDD	0x4E92	# <CJK>
0x8CDE	0x4F0D	# <CJK>
0x8CDF	0x5348	# <CJK>
0x8CE0	0x5449	# <CJK>
0x8CE1	0x543E	# <CJK>
0x8CE2	0x5A2F	# <CJK>
0x8CE3	0x5F8C	# <CJK>
0x8CE4	0x5FA1	# <CJK>
0x8CE5	0x609F	# <CJK>
0x8CE6	0x68A7	# <CJK>
0x8CE7	0x6A8E	# <CJK>
0x8CE8	0x745A	# <CJK>
0x8CE9	0x7881	# <CJK>
0x8CEA	0x8A9E	# <CJK>
0x8CEB	0x8AA4	# <CJK>
0x8CEC	0x8B77	# <CJK>
0x8CED	0x9190	# <CJK>
0x8CEE	0x4E5E	# <CJK>
0x8CEF	0x9BC9	# <CJK>
0x8CF0	0x4EA4	# <CJK>
0x8CF1	0x4F7C	# <CJK>
0x8CF2	0x4FAF	# <CJK>
0x8CF3	0x5019	# <CJK>
0x8CF4	0x5016	# <CJK>
0x8CF5	0x5149	# <CJK>
0x8CF6	0x516C	# <CJK>
0x8CF7	0x529F	# <CJK>
0x8CF8	0x52B9	# <CJK>
0x8CF9	0x52FE	# <CJK>
0x8CFA	0x539A	# <CJK>
0x8CFB	0x53E3	# <CJK>
0x8CFC	0x5411	# <CJK>
0x8D40	0x540E	# <CJK>
0x8D41	0x5589	# <CJK>
0x8D42	0x5751	# <CJK>
0x8D43	0x57A2	# <CJK>
0x8D44	0x597D	# <CJK>
0x8D45	0x5B54	# <CJK>
0x8D46	0x5B5D	# <CJK>
0x8D47	0x5B8F	# <CJK>
0x8D48	0x5DE5	# <CJK>
0x8D49	0x5DE7	# <CJK>
0x8D4A	0x5DF7	# <CJK>
0x8D4B	0x5E78	# <CJK>
0x8D4C	0x5E83	# <CJK>
0x8D4D	0x5E9A	# <CJK>
0x8D4E	0x5EB7	# <CJK>
0x8D4F	0x5F18	# <CJK>
0x8D50	0x6052	# <CJK>
0x8D51	0x614C	# <CJK>
0x8D52	0x6297	# <CJK>
0x8D53	0x62D8	# <CJK>
0x8D54	0x63A7	# <CJK>
0x8D55	0x653B	# <CJK>
0x8D56	0x6602	# <CJK>
0x8D57	0x6643	# <CJK>
0x8D58	0x66F4	# <CJK>
0x8D59	0x676D	# <CJK>
0x8D5A	0x6821	# <CJK>
0x8D5B	0x6897	# <CJK>
0x8D5C	0x69CB	# <CJK>
0x8D5D	0x6C5F	# <CJK>
0x8D5E	0x6D2A	# <CJK>
0x8D5F	0x6D69	# <CJK>
0x8D60	0x6E2F	# <CJK>
0x8D61	0x6E9D	# <CJK>
0x8D62	0x7532	# <CJK>
0x8D63	0x7687	# <CJK>
0x8D64	0x786C	# <CJK>
0x8D65	0x7A3F	# <CJK>
0x8D66	0x7CE0	# <CJK>
0x8D67	0x7D05	# <CJK>
0x8D68	0x7D18	# <CJK>
0x8D69	0x7D5E	# <CJK>
0x8D6A	0x7DB1	# <CJK>
0x8D6B	0x8015	# <CJK>
0x8D6C	0x8003	# <CJK>
0x8D6D	0x80AF	# <CJK>
0x8D6E	0x80B1	# <CJK>
0x8D6F	0x8154	# <CJK>
0x8D70	0x818F	# <CJK>
0x8D71	0x822A	# <CJK>
0x8D72	0x8352	# <CJK>
0x8D73	0x884C	# <CJK>
0x8D74	0x8861	# <CJK>
0x8D75	0x8B1B	# <CJK>
0x8D76	0x8CA2	# <CJK>
0x8D77	0x8CFC	# <CJK>
0x8D78	0x90CA	# <CJK>
0x8D79	0x9175	# <CJK>
0x8D7A	0x9271	# <CJK>
0x8D7B	0x783F	# <CJK>
0x8D7C	0x92FC	# <CJK>
0x8D7D	0x95A4	# <CJK>
0x8D7E	0x964D	# <CJK>
0x8D80	0x9805	# <CJK>
0x8D81	0x9999	# <CJK>
0x8D82	0x9AD8	# <CJK>
0x8D83	0x9D3B	# <CJK>
0x8D84	0x525B	# <CJK>
0x8D85	0x52AB	# <CJK>
0x8D86	0x53F7	# <CJK>
0x8D87	0x5408	# <CJK>
0x8D88	0x58D5	# <CJK>
0x8D89	0x62F7	# <CJK>
0x8D8A	0x6FE0	# <CJK>
0x8D8B	0x8C6A	# <CJK>
0x8D8C	0x8F5F	# <CJK>
0x8D8D	0x9EB9	# <CJK>
0x8D8E	0x514B	# <CJK>
0x8D8F	0x523B	# <CJK>
0x8D90	0x544A	# <CJK>
0x8D91	0x56FD	# <CJK>
0x8D92	0x7A40	# <CJK>
0x8D93	0x9177	# <CJK>
0x8D94	0x9D60	# <CJK>
0x8D95	0x9ED2	# <CJK>
0x8D96	0x7344	# <CJK>
0x8D97	0x6F09	# <CJK>
0x8D98	0x8170	# <CJK>
0x8D99	0x7511	# <CJK>
0x8D9A	0x5FFD	# <CJK>
0x8D9B	0x60DA	# <CJK>
0x8D9C	0x9AA8	# <CJK>
0x8D9D	0x72DB	# <CJK>
0x8D9E	0x8FBC	# <CJK>
0x8D9F	0x6B64	# <CJK>
0x8DA0	0x9803	# <CJK>
0x8DA1	0x4ECA	# <CJK>
0x8DA2	0x56F0	# <CJK>
0x8DA3	0x5764	# <CJK>
0x8DA4	0x58BE	# <CJK>
0x8DA5	0x5A5A	# <CJK>
0x8DA6	0x6068	# <CJK>
0x8DA7	0x61C7	# <CJK>
0x8DA8	0x660F	# <CJK>
0x8DA9	0x6606	# <CJK>
0x8DAA	0x6839	# <CJK>
0x8DAB	0x68B1	# <CJK>
0x8DAC	0x6DF7	# <CJK>
0x8DAD	0x75D5	# <CJK>
0x8DAE	0x7D3A	# <CJK>
0x8DAF	0x826E	# <CJK>
0x8DB0	0x9B42	# <CJK>
0x8DB1	0x4E9B	# <CJK>
0x8DB2	0x4F50	# <CJK>
0x8DB3	0x53C9	# <CJK>
0x8DB4	0x5506	# <CJK>
0x8DB5	0x5D6F	# <CJK>
0x8DB6	0x5DE6	# <CJK>
0x8DB7	0x5DEE	# <CJK>
0x8DB8	0x67FB	# <CJK>
0x8DB9	0x6C99	# <CJK>
0x8DBA	0x7473	# <CJK>
0x8DBB	0x7802	# <CJK>
0x8DBC	0x8A50	# <CJK>
0x8DBD	0x9396	# <CJK>
0x8DBE	0x88DF	# <CJK>
0x8DBF	0x5750	# <CJK>
0x8DC0	0x5EA7	# <CJK>
0x8DC1	0x632B	# <CJK>
0x8DC2	0x50B5	# <CJK>
0x8DC3	0x50AC	# <CJK>
0x8DC4	0x518D	# <CJK>
0x8DC5	0x6700	# <CJK>
0x8DC6	0x54C9	# <CJK>
0x8DC7	0x585E	# <CJK>
0x8DC8	0x59BB	# <CJK>
0x8DC9	0x5BB0	# <CJK>
0x8DCA	0x5F69	# <CJK>
0x8DCB	0x624D	# <CJK>
0x8DCC	0x63A1	# <CJK>
0x8DCD	0x683D	# <CJK>
0x8DCE	0x6B73	# <CJK>
0x8DCF	0x6E08	# <CJK>
0x8DD0	0x707D	# <CJK>
0x8DD1	0x91C7	# <CJK>
0x8DD2	0x7280	# <CJK>
0x8DD3	0x7815	# <CJK>
0x8DD4	0x7826	# <CJK>
0x8DD5	0x796D	# <CJK>
0x8DD6	0x658E	# <CJK>
0x8DD7	0x7D30	# <CJK>
0x8DD8	0x83DC	# <CJK>
0x8DD9	0x88C1	# <CJK>
0x8DDA	0x8F09	# <CJK>
0x8DDB	0x969B	# <CJK>
0x8DDC	0x5264	# <CJK>
0x8DDD	0x5728	# <CJK>
0x8DDE	0x6750	# <CJK>
0x8DDF	0x7F6A	# <CJK>
0x8DE0	0x8CA1	# <CJK>
0x8DE1	0x51B4	# <CJK>
0x8DE2	0x5742	# <CJK>
0x8DE3	0x962A	# <CJK>
0x8DE4	0x583A	# <CJK>
0x8DE5	0x698A	# <CJK>
0x8DE6	0x80B4	# <CJK>
0x8DE7	0x54B2	# <CJK>
0x8DE8	0x5D0E	# <CJK>
0x8DE9	0x57FC	# <CJK>
0x8DEA	0x7895	# <CJK>
0x8DEB	0x9DFA	# <CJK>
0x8DEC	0x4F5C	# <CJK>
0x8DED	0x524A	# <CJK>
0x8DEE	0x548B	# <CJK>
0x8DEF	0x643E	# <CJK>
0x8DF0	0x6628	# <CJK>
0x8DF1	0x6714	# <CJK>
0x8DF2	0x67F5	# <CJK>
0x8DF3	0x7A84	# <CJK>
0x8DF4	0x7B56	# <CJK>
0x8DF5	0x7D22	# <CJK>
0x8DF6	0x932F	# <CJK>
0x8DF7	0x685C	# <CJK>
0x8DF8	0x9BAD	# <CJK>
0x8DF9	0x7B39	# <CJK>
0x8DFA	0x5319	# <CJK>
0x8DFB	0x518A	# <CJK>
0x8DFC	0x5237	# <CJK>
0x8E40	0x5BDF	# <CJK>
0x8E41	0x62F6	# <CJK>
0x8E42	0x64AE	# <CJK>
0x8E43	0x64E6	# <CJK>
0x8E44	0x672D	# <CJK>
0x8E45	0x6BBA	# <CJK>
0x8E46	0x85A9	# <CJK>
0x8E47	0x96D1	# <CJK>
0x8E48	0x7690	# <CJK>
0x8E49	0x9BD6	# <CJK>
0x8E4A	0x634C	# <CJK>
0x8E4B	0x9306	# <CJK>
0x8E4C	0x9BAB	# <CJK>
0x8E4D	0x76BF	# <CJK>
0x8E4E	0x6652	# <CJK>
0x8E4F	0x4E09	# <CJK>
0x8E50	0x5098	# <CJK>
0x8E51	0x53C2	# <CJK>
0x8E52	0x5C71	# <CJK>
0x8E53	0x60E8	# <CJK>
0x8E54	0x6492	# <CJK>
0x8E55	0x6563	# <CJK>
0x8E56	0x685F	# <CJK>
0x8E57	0x71E6	# <CJK>
0x8E58	0x73CA	# <CJK>
0x8E59	0x7523	# <CJK>
0x8E5A	0x7B97	# <CJK>
0x8E5B	0x7E82	# <CJK>
0x8E5C	0x8695	# <CJK>
0x8E5D	0x8B83	# <CJK>
0x8E5E	0x8CDB	# <CJK>
0x8E5F	0x9178	# <CJK>
0x8E60	0x9910	# <CJK>
0x8E61	0x65AC	# <CJK>
0x8E62	0x66AB	# <CJK>
0x8E63	0x6B8B	# <CJK>
0x8E64	0x4ED5	# <CJK>
0x8E65	0x4ED4	# <CJK>
0x8E66	0x4F3A	# <CJK>
0x8E67	0x4F7F	# <CJK>
0x8E68	0x523A	# <CJK>
0x8E69	0x53F8	# <CJK>
0x8E6A	0x53F2	# <CJK>
0x8E6B	0x55E3	# <CJK>
0x8E6C	0x56DB	# <CJK>
0x8E6D	0x58EB	# <CJK>
0x8E6E	0x59CB	# <CJK>
0x8E6F	0x59C9	# <CJK>
0x8E70	0x59FF	# <CJK>
0x8E71	0x5B50	# <CJK>
0x8E72	0x5C4D	# <CJK>
0x8E73	0x5E02	# <CJK>
0x8E74	0x5E2B	# <CJK>
0x8E75	0x5FD7	# <CJK>
0x8E76	0x601D	# <CJK>
0x8E77	0x6307	# <CJK>
0x8E78	0x652F	# <CJK>
0x8E79	0x5B5C	# <CJK>
0x8E7A	0x65AF	# <CJK>
0x8E7B	0x65BD	# <CJK>
0x8E7C	0x65E8	# <CJK>
0x8E7D	0x679D	# <CJK>
0x8E7E	0x6B62	# <CJK>
0x8E80	0x6B7B	# <CJK>
0x8E81	0x6C0F	# <CJK>
0x8E82	0x7345	# <CJK>
0x8E83	0x7949	# <CJK>
0x8E84	0x79C1	# <CJK>
0x8E85	0x7CF8	# <CJK>
0x8E86	0x7D19	# <CJK>
0x8E87	0x7D2B	# <CJK>
0x8E88	0x80A2	# <CJK>
0x8E89	0x8102	# <CJK>
0x8E8A	0x81F3	# <CJK>
0x8E8B	0x8996	# <CJK>
0x8E8C	0x8A5E	# <CJK>
0x8E8D	0x8A69	# <CJK>
0x8E8E	0x8A66	# <CJK>
0x8E8F	0x8A8C	# <CJK>
0x8E90	0x8AEE	# <CJK>
0x8E91	0x8CC7	# <CJK>
0x8E92	0x8CDC	# <CJK>
0x8E93	0x96CC	# <CJK>
0x8E94	0x98FC	# <CJK>
0x8E95	0x6B6F	# <CJK>
0x8E96	0x4E8B	# <CJK>
0x8E97	0x4F3C	# <CJK>
0x8E98	0x4F8D	# <CJK>
0x8E99	0x5150	# <CJK>
0x8E9A	0x5B57	# <CJK>
0x8E9B	0x5BFA	# <CJK>
0x8E9C	0x6148	# <CJK>
0x8E9D	0x6301	# <CJK>
0x8E9E	0x6642	# <CJK>
0x8E9F	0x6B21	# <CJK>
0x8EA0	0x6ECB	# <CJK>
0x8EA1	0x6CBB	# <CJK>
0x8EA2	0x723E	# <CJK>
0x8EA3	0x74BD	# <CJK>
0x8EA4	0x75D4	# <CJK>
0x8EA5	0x78C1	# <CJK>
0x8EA6	0x793A	# <CJK>
0x8EA7	0x800C	# <CJK>
0x8EA8	0x8033	# <CJK>
0x8EA9	0x81EA	# <CJK>
0x8EAA	0x8494	# <CJK>
0x8EAB	0x8F9E	# <CJK>
0x8EAC	0x6C50	# <CJK>
0x8EAD	0x9E7F	# <CJK>
0x8EAE	0x5F0F	# <CJK>
0x8EAF	0x8B58	# <CJK>
0x8EB0	0x9D2B	# <CJK>
0x8EB1	0x7AFA	# <CJK>
0x8EB2	0x8EF8	# <CJK>
0x8EB3	0x5B8D	# <CJK>
0x8EB4	0x96EB	# <CJK>
0x8EB5	0x4E03	# <CJK>
0x8EB6	0x53F1	# <CJK>
0x8EB7	0x57F7	# <CJK>
0x8EB8	0x5931	# <CJK>
0x8EB9	0x5AC9	# <CJK>
0x8EBA	0x5BA4	# <CJK>
0x8EBB	0x6089	# <CJK>
0x8EBC	0x6E7F	# <CJK>
0x8EBD	0x6F06	# <CJK>
0x8EBE	0x75BE	# <CJK>
0x8EBF	0x8CEA	# <CJK>
0x8EC0	0x5B9F	# <CJK>
0x8EC1	0x8500	# <CJK>
0x8EC2	0x7BE0	# <CJK>
0x8EC3	0x5072	# <CJK>
0x8EC4	0x67F4	# <CJK>
0x8EC5	0x829D	# <CJK>
0x8EC6	0x5C61	# <CJK>
0x8EC7	0x854A	# <CJK>
0x8EC8	0x7E1E	# <CJK>
0x8EC9	0x820E	# <CJK>
0x8ECA	0x5199	# <CJK>
0x8ECB	0x5C04	# <CJK>
0x8ECC	0x6368	# <CJK>
0x8ECD	0x8D66	# <CJK>
0x8ECE	0x659C	# <CJK>
0x8ECF	0x716E	# <CJK>
0x8ED0	0x793E	# <CJK>
0x8ED1	0x7D17	# <CJK>
0x8ED2	0x8005	# <CJK>
0x8ED3	0x8B1D	# <CJK>
0x8ED4	0x8ECA	# <CJK>
0x8ED5	0x906E	# <CJK>
0x8ED6	0x86C7	# <CJK>
0x8ED7	0x90AA	# <CJK>
0x8ED8	0x501F	# <CJK>
0x8ED9	0x52FA	# <CJK>
0x8EDA	0x5C3A	# <CJK>
0x8EDB	0x6753	# <CJK>
0x8EDC	0x707C	# <CJK>
0x8EDD	0x7235	# <CJK>
0x8EDE	0x914C	# <CJK>
0x8EDF	0x91C8	# <CJK>
0x8EE0	0x932B	# <CJK>
0x8EE1	0x82E5	# <CJK>
0x8EE2	0x5BC2	# <CJK>
0x8EE3	0x5F31	# <CJK>
0x8EE4	0x60F9	# <CJK>
0x8EE5	0x4E3B	# <CJK>
0x8EE6	0x53D6	# <CJK>
0x8EE7	0x5B88	# <CJK>
0x8EE8	0x624B	# <CJK>
0x8EE9	0x6731	# <CJK>
0x8EEA	0x6B8A	# <CJK>
0x8EEB	0x72E9	# <CJK>
0x8EEC	0x73E0	# <CJK>
0x8EED	0x7A2E	# <CJK>
0x8EEE	0x816B	# <CJK>
0x8EEF	0x8DA3	# <CJK>
0x8EF0	0x9152	# <CJK>
0x8EF1	0x9996	# <CJK>
0x8EF2	0x5112	# <CJK>
0x8EF3	0x53D7	# <CJK>
0x8EF4	0x546A	# <CJK>
0x8EF5	0x5BFF	# <CJK>
0x8EF6	0x6388	# <CJK>
0x8EF7	0x6A39	# <CJK>
0x8EF8	0x7DAC	# <CJK>
0x8EF9	0x9700	# <CJK>
0x8EFA	0x56DA	# <CJK>
0x8EFB	0x53CE	# <CJK>
0x8EFC	0x5468	# <CJK>
0x8F40	0x5B97	# <CJK>
0x8F41	0x5C31	# <CJK>
0x8F42	0x5DDE	# <CJK>
0x8F43	0x4FEE	# <CJK>
0x8F44	0x6101	# <CJK>
0x8F45	0x62FE	# <CJK>
0x8F46	0x6D32	# <CJK>
0x8F47	0x79C0	# <CJK>
0x8F48	0x79CB	# <CJK>
0x8F49	0x7D42	# <CJK>
0x8F4A	0x7E4D	# <CJK>
0x8F4B	0x7FD2	# <CJK>
0x8F4C	0x81ED	# <CJK>
0x8F4D	0x821F	# <CJK>
0x8F4E	0x8490	# <CJK>
0x8F4F	0x8846	# <CJK>
0x8F50	0x8972	# <CJK>
0x8F51	0x8B90	# <CJK>
0x8F52	0x8E74	# <CJK>
0x8F53	0x8F2F	# <CJK>
0x8F54	0x9031	# <CJK>
0x8F55	0x914B	# <CJK>
0x8F56	0x916C	# <CJK>
0x8F57	0x96C6	# <CJK>
0x8F58	0x919C	# <CJK>
0x8F59	0x4EC0	# <CJK>
0x8F5A	0x4F4F	# <CJK>
0x8F5B	0x5145	# <CJK>
0x8F5C	0x5341	# <CJK>
0x8F5D	0x5F93	# <CJK>
0x8F5E	0x620E	# <CJK>
0x8F5F	0x67D4	# <CJK>
0x8F60	0x6C41	# <CJK>
0x8F61	0x6E0B	# <CJK>
0x8F62	0x7363	# <CJK>
0x8F63	0x7E26	# <CJK>
0x8F64	0x91CD	# <CJK>
0x8F65	0x9283	# <CJK>
0x8F66	0x53D4	# <CJK>
0x8F67	0x5919	# <CJK>
0x8F68	0x5BBF	# <CJK>
0x8F69	0x6DD1	# <CJK>
0x8F6A	0x795D	# <CJK>
0x8F6B	0x7E2E	# <CJK>
0x8F6C	0x7C9B	# <CJK>
0x8F6D	0x587E	# <CJK>
0x8F6E	0x719F	# <CJK>
0x8F6F	0x51FA	# <CJK>
0x8F70	0x8853	# <CJK>
0x8F71	0x8FF0	# <CJK>
0x8F72	0x4FCA	# <CJK>
0x8F73	0x5CFB	# <CJK>
0x8F74	0x6625	# <CJK>
0x8F75	0x77AC	# <CJK>
0x8F76	0x7AE3	# <CJK>
0x8F77	0x821C	# <CJK>
0x8F78	0x99FF	# <CJK>
0x8F79	0x51C6	# <CJK>
0x8F7A	0x5FAA	# <CJK>
0x8F7B	0x65EC	# <CJK>
0x8F7C	0x696F	# <CJK>
0x8F7D	0x6B89	# <CJK>
0x8F7E	0x6DF3	# <CJK>
0x8F80	0x6E96	# <CJK>
0x8F81	0x6F64	# <CJK>
0x8F82	0x76FE	# <CJK>
0x8F83	0x7D14	# <CJK>
0x8F84	0x5DE1	# <CJK>
0x8F85	0x9075	# <CJK>
0x8F86	0x9187	# <CJK>
0x8F87	0x9806	# <CJK>
0x8F88	0x51E6	# <CJK>
0x8F89	0x521D	# <CJK>
0x8F8A	0x6240	# <CJK>
0x8F8B	0x6691	# <CJK>
0x8F8C	0x66D9	# <CJK>
0x8F8D	0x6E1A	# <CJK>
0x8F8E	0x5EB6	# <CJK>
0x8F8F	0x7DD2	# <CJK>
0x8F90	0x7F72	# <CJK>
0x8F91	0x66F8	# <CJK>
0x8F92	0x85AF	# <CJK>
0x8F93	0x85F7	# <CJK>
0x8F94	0x8AF8	# <CJK>
0x8F95	0x52A9	# <CJK>
0x8F96	0x53D9	# <CJK>
0x8F97	0x5973	# <CJK>
0x8F98	0x5E8F	# <CJK>
0x8F99	0x5F90	# <CJK>
0x8F9A	0x6055	# <CJK>
0x8F9B	0x92E4	# <CJK>
0x8F9C	0x9664	# <CJK>
0x8F9D	0x50B7	# <CJK>
0x8F9E	0x511F	# <CJK>
0x8F9F	0x52DD	# <CJK>
0x8FA0	0x5320	# <CJK>
0x8FA1	0x5347	# <CJK>
0x8FA2	0x53EC	# <CJK>
0x8FA3	0x54E8	# <CJK>
0x8FA4	0x5546	# <CJK>
0x8FA5	0x5531	# <CJK>
0x8FA6	0x5617	# <CJK>
0x8FA7	0x5968	# <CJK>
0x8FA8	0x59BE	# <CJK>
0x8FA9	0x5A3C	# <CJK>
0x8FAA	0x5BB5	# <CJK>
0x8FAB	0x5C06	# <CJK>
0x8FAC	0x5C0F	# <CJK>
0x8FAD	0x5C11	# <CJK>
0x8FAE	0x5C1A	# <CJK>
0x8FAF	0x5E84	# <CJK>
0x8FB0	0x5E8A	# <CJK>
0x8FB1	0x5EE0	# <CJK>
0x8FB2	0x5F70	# <CJK>
0x8FB3	0x627F	# <CJK>
0x8FB4	0x6284	# <CJK>
0x8FB5	0x62DB	# <CJK>
0x8FB6	0x638C	# <CJK>
0x8FB7	0x6377	# <CJK>
0x8FB8	0x6607	# <CJK>
0x8FB9	0x660C	# <CJK>
0x8FBA	0x662D	# <CJK>
0x8FBB	0x6676	# <CJK>
0x8FBC	0x677E	# <CJK>
0x8FBD	0x68A2	# <CJK>
0x8FBE	0x6A1F	# <CJK>
0x8FBF	0x6A35	# <CJK>
0x8FC0	0x6CBC	# <CJK>
0x8FC1	0x6D88	# <CJK>
0x8FC2	0x6E09	# <CJK>
0x8FC3	0x6E58	# <CJK>
0x8FC4	0x713C	# <CJK>
0x8FC5	0x7126	# <CJK>
0x8FC6	0x7167	# <CJK>
0x8FC7	0x75C7	# <CJK>
0x8FC8	0x7701	# <CJK>
0x8FC9	0x785D	# <CJK>
0x8FCA	0x7901	# <CJK>
0x8FCB	0x7965	# <CJK>
0x8FCC	0x79F0	# <CJK>
0x8FCD	0x7AE0	# <CJK>
0x8FCE	0x7B11	# <CJK>
0x8FCF	0x7CA7	# <CJK>
0x8FD0	0x7D39	# <CJK>
0x8FD1	0x8096	# <CJK>
0x8FD2	0x83D6	# <CJK>
0x8FD3	0x848B	# <CJK>
0x8FD4	0x8549	# <CJK>
0x8FD5	0x885D	# <CJK>
0x8FD6	0x88F3	# <CJK>
0x8FD7	0x8A1F	# <CJK>
0x8FD8	0x8A3C	# <CJK>
0x8FD9	0x8A54	# <CJK>
0x8FDA	0x8A73	# <CJK>
0x8FDB	0x8C61	# <CJK>
0x8FDC	0x8CDE	# <CJK>
0x8FDD	0x91A4	# <CJK>
0x8FDE	0x9266	# <CJK>
0x8FDF	0x937E	# <CJK>
0x8FE0	0x9418	# <CJK>
0x8FE1	0x969C	# <CJK>
0x8FE2	0x9798	# <CJK>
0x8FE3	0x4E0A	# <CJK>
0x8FE4	0x4E08	# <CJK>
0x8FE5	0x4E1E	# <CJK>
0x8FE6	0x4E57	# <CJK>
0x8FE7	0x5197	# <CJK>
0x8FE8	0x5270	# <CJK>
0x8FE9	0x57CE	# <CJK>
0x8FEA	0x5834	# <CJK>
0x8FEB	0x58CC	# <CJK>
0x8FEC	0x5B22	# <CJK>
0x8FED	0x5E38	# <CJK>
0x8FEE	0x60C5	# <CJK>
0x8FEF	0x64FE	# <CJK>
0x8FF0	0x6761	# <CJK>
0x8FF1	0x6756	# <CJK>
0x8FF2	0x6D44	# <CJK>
0x8FF3	0x72B6	# <CJK>
0x8FF4	0x7573	# <CJK>
0x8FF5	0x7A63	# <CJK>
0x8FF6	0x84B8	# <CJK>
0x8FF7	0x8B72	# <CJK>
0x8FF8	0x91B8	# <CJK>
0x8FF9	0x9320	# <CJK>
0x8FFA	0x5631	# <CJK>
0x8FFB	0x57F4	# <CJK>
0x8FFC	0x98FE	# <CJK>
0x9040	0x62ED	# <CJK>
0x9041	0x690D	# <CJK>
0x9042	0x6B96	# <CJK>
0x9043	0x71ED	# <CJK>
0x9044	0x7E54	# <CJK>
0x9045	0x8077	# <CJK>
0x9046	0x8272	# <CJK>
0x9047	0x89E6	# <CJK>
0x9048	0x98DF	# <CJK>
0x9049	0x8755	# <CJK>
0x904A	0x8FB1	# <CJK>
0x904B	0x5C3B	# <CJK>
0x904C	0x4F38	# <CJK>
0x904D	0x4FE1	# <CJK>
0x904E	0x4FB5	# <CJK>
0x904F	0x5507	# <CJK>
0x9050	0x5A20	# <CJK>
0x9051	0x5BDD	# <CJK>
0x9052	0x5BE9	# <CJK>
0x9053	0x5FC3	# <CJK>
0x9054	0x614E	# <CJK>
0x9055	0x632F	# <CJK>
0x9056	0x65B0	# <CJK>
0x9057	0x664B	# <CJK>
0x9058	0x68EE	# <CJK>
0x9059	0x699B	# <CJK>
0x905A	0x6D78	# <CJK>
0x905B	0x6DF1	# <CJK>
0x905C	0x7533	# <CJK>
0x905D	0x75B9	# <CJK>
0x905E	0x771F	# <CJK>
0x905F	0x795E	# <CJK>
0x9060	0x79E6	# <CJK>
0x9061	0x7D33	# <CJK>
0x9062	0x81E3	# <CJK>
0x9063	0x82AF	# <CJK>
0x9064	0x85AA	# <CJK>
0x9065	0x89AA	# <CJK>
0x9066	0x8A3A	# <CJK>
0x9067	0x8EAB	# <CJK>
0x9068	0x8F9B	# <CJK>
0x9069	0x9032	# <CJK>
0x906A	0x91DD	# <CJK>
0x906B	0x9707	# <CJK>
0x906C	0x4EBA	# <CJK>
0x906D	0x4EC1	# <CJK>
0x906E	0x5203	# <CJK>
0x906F	0x5875	# <CJK>
0x9070	0x58EC	# <CJK>
0x9071	0x5C0B	# <CJK>
0x9072	0x751A	# <CJK>
0x9073	0x5C3D	# <CJK>
0x9074	0x814E	# <CJK>
0x9075	0x8A0A	# <CJK>
0x9076	0x8FC5	# <CJK>
0x9077	0x9663	# <CJK>
0x9078	0x976D	# <CJK>
0x9079	0x7B25	# <CJK>
0x907A	0x8ACF	# <CJK>
0x907B	0x9808	# <CJK>
0x907C	0x9162	# <CJK>
0x907D	0x56F3	# <CJK>
0x907E	0x53A8	# <CJK>
0x9080	0x9017	# <CJK>
0x9081	0x5439	# <CJK>
0x9082	0x5782	# <CJK>
0x9083	0x5E25	# <CJK>
0x9084	0x63A8	# <CJK>
0x9085	0x6C34	# <CJK>
0x9086	0x708A	# <CJK>
0x9087	0x7761	# <CJK>
0x9088	0x7C8B	# <CJK>
0x9089	0x7FE0	# <CJK>
0x908A	0x8870	# <CJK>
0x908B	0x9042	# <CJK>
0x908C	0x9154	# <CJK>
0x908D	0x9310	# <CJK>
0x908E	0x9318	# <CJK>
0x908F	0x968F	# <CJK>
0x9090	0x745E	# <CJK>
0x9091	0x9AC4	# <CJK>
0x9092	0x5D07	# <CJK>
0x9093	0x5D69	# <CJK>
0x9094	0x6570	# <CJK>
0x9095	0x67A2	# <CJK>
0x9096	0x8DA8	# <CJK>
0x9097	0x96DB	# <CJK>
0x9098	0x636E	# <CJK>
0x9099	0x6749	# <CJK>
0x909A	0x6919	# <CJK>
0x909B	0x83C5	# <CJK>
0x909C	0x9817	# <CJK>
0x909D	0x96C0	# <CJK>
0x909E	0x88FE	# <CJK>
0x909F	0x6F84	# <CJK>
0x90A0	0x647A	# <CJK>
0x90A1	0x5BF8	# <CJK>
0x90A2	0x4E16	# <CJK>
0x90A3	0x702C	# <CJK>
0x90A4	0x755D	# <CJK>
0x90A5	0x662F	# <CJK>
0x90A6	0x51C4	# <CJK>
0x90A7	0x5236	# <CJK>
0x90A8	0x52E2	# <CJK>
0x90A9	0x59D3	# <CJK>
0x90AA	0x5F81	# <CJK>
0x90AB	0x6027	# <CJK>
0x90AC	0x6210	# <CJK>
0x90AD	0x653F	# <CJK>
0x90AE	0x6574	# <CJK>
0x90AF	0x661F	# <CJK>
0x90B0	0x6674	# <CJK>
0x90B1	0x68F2	# <CJK>
0x90B2	0x6816	# <CJK>
0x90B3	0x6B63	# <CJK>
0x90B4	0x6E05	# <CJK>
0x90B5	0x7272	# <CJK>
0x90B6	0x751F	# <CJK>
0x90B7	0x76DB	# <CJK>
0x90B8	0x7CBE	# <CJK>
0x90B9	0x8056	# <CJK>
0x90BA	0x58F0	# <CJK>
0x90BB	0x88FD	# <CJK>
0x90BC	0x897F	# <CJK>
0x90BD	0x8AA0	# <CJK>
0x90BE	0x8A93	# <CJK>
0x90BF	0x8ACB	# <CJK>
0x90C0	0x901D	# <CJK>
0x90C1	0x9192	# <CJK>
0x90C2	0x9752	# <CJK>
0x90C3	0x9759	# <CJK>
0x90C4	0x6589	# <CJK>
0x90C5	0x7A0E	# <CJK>
0x90C6	0x8106	# <CJK>
0x90C7	0x96BB	# <CJK>
0x90C8	0x5E2D	# <CJK>
0x90C9	0x60DC	# <CJK>
0x90CA	0x621A	# <CJK>
0x90CB	0x65A5	# <CJK>
0x90CC	0x6614	# <CJK>
0x90CD	0x6790	# <CJK>
0x90CE	0x77F3	# <CJK>
0x90CF	0x7A4D	# <CJK>
0x90D0	0x7C4D	# <CJK>
0x90D1	0x7E3E	# <CJK>
0x90D2	0x810A	# <CJK>
0x90D3	0x8CAC	# <CJK>
0x90D4	0x8D64	# <CJK>
0x90D5	0x8DE1	# <CJK>
0x90D6	0x8E5F	# <CJK>
0x90D7	0x78A9	# <CJK>
0x90D8	0x5207	# <CJK>
0x90D9	0x62D9	# <CJK>
0x90DA	0x63A5	# <CJK>
0x90DB	0x6442	# <CJK>
0x90DC	0x6298	# <CJK>
0x90DD	0x8A2D	# <CJK>
0x90DE	0x7A83	# <CJK>
0x90DF	0x7BC0	# <CJK>
0x90E0	0x8AAC	# <CJK>
0x90E1	0x96EA	# <CJK>
0x90E2	0x7D76	# <CJK>
0x90E3	0x820C	# <CJK>
0x90E4	0x8749	# <CJK>
0x90E5	0x4ED9	# <CJK>
0x90E6	0x5148	# <CJK>
0x90E7	0x5343	# <CJK>
0x90E8	0x5360	# <CJK>
0x90E9	0x5BA3	# <CJK>
0x90EA	0x5C02	# <CJK>
0x90EB	0x5C16	# <CJK>
0x90EC	0x5DDD	# <CJK>
0x90ED	0x6226	# <CJK>
0x90EE	0x6247	# <CJK>
0x90EF	0x64B0	# <CJK>
0x90F0	0x6813	# <CJK>
0x90F1	0x6834	# <CJK>
0x90F2	0x6CC9	# <CJK>
0x90F3	0x6D45	# <CJK>
0x90F4	0x6D17	# <CJK>
0x90F5	0x67D3	# <CJK>
0x90F6	0x6F5C	# <CJK>
0x90F7	0x714E	# <CJK>
0x90F8	0x717D	# <CJK>
0x90F9	0x65CB	# <CJK>
0x90FA	0x7A7F	# <CJK>
0x90FB	0x7BAD	# <CJK>
0x90FC	0x7DDA	# <CJK>
0x9140	0x7E4A	# <CJK>
0x9141	0x7FA8	# <CJK>
0x9142	0x817A	# <CJK>
0x9143	0x821B	# <CJK>
0x9144	0x8239	# <CJK>
0x9145	0x85A6	# <CJK>
0x9146	0x8A6E	# <CJK>
0x9147	0x8CCE	# <CJK>
0x9148	0x8DF5	# <CJK>
0x9149	0x9078	# <CJK>
0x914A	0x9077	# <CJK>
0x914B	0x92AD	# <CJK>
0x914C	0x9291	# <CJK>
0x914D	0x9583	# <CJK>
0x914E	0x9BAE	# <CJK>
0x914F	0x524D	# <CJK>
0x9150	0x5584	# <CJK>
0x9151	0x6F38	# <CJK>
0x9152	0x7136	# <CJK>
0x9153	0x5168	# <CJK>
0x9154	0x7985	# <CJK>
0x9155	0x7E55	# <CJK>
0x9156	0x81B3	# <CJK>
0x9157	0x7CCE	# <CJK>
0x9158	0x564C	# <CJK>
0x9159	0x5851	# <CJK>
0x915A	0x5CA8	# <CJK>
0x915B	0x63AA	# <CJK>
0x915C	0x66FE	# <CJK>
0x915D	0x66FD	# <CJK>
0x915E	0x695A	# <CJK>
0x915F	0x72D9	# <CJK>
0x9160	0x758F	# <CJK>
0x9161	0x758E	# <CJK>
0x9162	0x790E	# <CJK>
0x9163	0x7956	# <CJK>
0x9164	0x79DF	# <CJK>
0x9165	0x7C97	# <CJK>
0x9166	0x7D20	# <CJK>
0x9167	0x7D44	# <CJK>
0x9168	0x8607	# <CJK>
0x9169	0x8A34	# <CJK>
0x916A	0x963B	# <CJK>
0x916B	0x9061	# <CJK>
0x916C	0x9F20	# <CJK>
0x916D	0x50E7	# <CJK>
0x916E	0x5275	# <CJK>
0x916F	0x53CC	# <CJK>
0x9170	0x53E2	# <CJK>
0x9171	0x5009	# <CJK>
0x9172	0x55AA	# <CJK>
0x9173	0x58EE	# <CJK>
0x9174	0x594F	# <CJK>
0x9175	0x723D	# <CJK>
0x9176	0x5B8B	# <CJK>
0x9177	0x5C64	# <CJK>
0x9178	0x531D	# <CJK>
0x9179	0x60E3	# <CJK>
0x917A	0x60F3	# <CJK>
0x917B	0x635C	# <CJK>
0x917C	0x6383	# <CJK>
0x917D	0x633F	# <CJK>
0x917E	0x63BB	# <CJK>
0x9180	0x64CD	# <CJK>
0x9181	0x65E9	# <CJK>
0x9182	0x66F9	# <CJK>
0x9183	0x5DE3	# <CJK>
0x9184	0x69CD	# <CJK>
0x9185	0x69FD	# <CJK>
0x9186	0x6F15	# <CJK>
0x9187	0x71E5	# <CJK>
0x9188	0x4E89	# <CJK>
0x9189	0x75E9	# <CJK>
0x918A	0x76F8	# <CJK>
0x918B	0x7A93	# <CJK>
0x918C	0x7CDF	# <CJK>
0x918D	0x7DCF	# <CJK>
0x918E	0x7D9C	# <CJK>
0x918F	0x8061	# <CJK>
0x9190	0x8349	# <CJK>
0x9191	0x8358	# <CJK>
0x9192	0x846C	# <CJK>
0x9193	0x84BC	# <CJK>
0x9194	0x85FB	# <CJK>
0x9195	0x88C5	# <CJK>
0x9196	0x8D70	# <CJK>
0x9197	0x9001	# <CJK>
0x9198	0x906D	# <CJK>
0x9199	0x9397	# <CJK>
0x919A	0x971C	# <CJK>
0x919B	0x9A12	# <CJK>
0x919C	0x50CF	# <CJK>
0x919D	0x5897	# <CJK>
0x919E	0x618E	# <CJK>
0x919F	0x81D3	# <CJK>
0x91A0	0x8535	# <CJK>
0x91A1	0x8D08	# <CJK>
0x91A2	0x9020	# <CJK>
0x91A3	0x4FC3	# <CJK>
0x91A4	0x5074	# <CJK>
0x91A5	0x5247	# <CJK>
0x91A6	0x5373	# <CJK>
0x91A7	0x606F	# <CJK>
0x91A8	0x6349	# <CJK>
0x91A9	0x675F	# <CJK>
0x91AA	0x6E2C	# <CJK>
0x91AB	0x8DB3	# <CJK>
0x91AC	0x901F	# <CJK>
0x91AD	0x4FD7	# <CJK>
0x91AE	0x5C5E	# <CJK>
0x91AF	0x8CCA	# <CJK>
0x91B0	0x65CF	# <CJK>
0x91B1	0x7D9A	# <CJK>
0x91B2	0x5352	# <CJK>
0x91B3	0x8896	# <CJK>
0x91B4	0x5176	# <CJK>
0x91B5	0x63C3	# <CJK>
0x91B6	0x5B58	# <CJK>
0x91B7	0x5B6B	# <CJK>
0x91B8	0x5C0A	# <CJK>
0x91B9	0x640D	# <CJK>
0x91BA	0x6751	# <CJK>
0x91BB	0x905C	# <CJK>
0x91BC	0x4ED6	# <CJK>
0x91BD	0x591A	# <CJK>
0x91BE	0x592A	# <CJK>
0x91BF	0x6C70	# <CJK>
0x91C0	0x8A51	# <CJK>
0x91C1	0x553E	# <CJK>
0x91C2	0x5815	# <CJK>
0x91C3	0x59A5	# <CJK>
0x91C4	0x60F0	# <CJK>
0x91C5	0x6253	# <CJK>
0x91C6	0x67C1	# <CJK>
0x91C7	0x8235	# <CJK>
0x91C8	0x6955	# <CJK>
0x91C9	0x9640	# <CJK>
0x91CA	0x99C4	# <CJK>
0x91CB	0x9A28	# <CJK>
0x91CC	0x4F53	# <CJK>
0x91CD	0x5806	# <CJK>
0x91CE	0x5BFE	# <CJK>
0x91CF	0x8010	# <CJK>
0x91D0	0x5CB1	# <CJK>
0x91D1	0x5E2F	# <CJK>
0x91D2	0x5F85	# <CJK>
0x91D3	0x6020	# <CJK>
0x91D4	0x614B	# <CJK>
0x91D5	0x6234	# <CJK>
0x91D6	0x66FF	# <CJK>
0x91D7	0x6CF0	# <CJK>
0x91D8	0x6EDE	# <CJK>
0x91D9	0x80CE	# <CJK>
0x91DA	0x817F	# <CJK>
0x91DB	0x82D4	# <CJK>
0x91DC	0x888B	# <CJK>
0x91DD	0x8CB8	# <CJK>
0x91DE	0x9000	# <CJK>
0x91DF	0x902E	# <CJK>
0x91E0	0x968A	# <CJK>
0x91E1	0x9EDB	# <CJK>
0x91E2	0x9BDB	# <CJK>
0x91E3	0x4EE3	# <CJK>
0x91E4	0x53F0	# <CJK>
0x91E5	0x5927	# <CJK>
0x91E6	0x7B2C	# <CJK>
0x91E7	0x918D	# <CJK>
0x91E8	0x984C	# <CJK>
0x91E9	0x9DF9	# <CJK>
0x91EA	0x6EDD	# <CJK>
0x91EB	0x7027	# <CJK>
0x91EC	0x5353	# <CJK>
0x91ED	0x5544	# <CJK>
0x91EE	0x5B85	# <CJK>
0x91EF	0x6258	# <CJK>
0x91F0	0x629E	# <CJK>
0x91F1	0x62D3	# <CJK>
0x91F2	0x6CA2	# <CJK>
0x91F3	0x6FEF	# <CJK>
0x91F4	0x7422	# <CJK>
0x91F5	0x8A17	# <CJK>
0x91F6	0x9438	# <CJK>
0x91F7	0x6FC1	# <CJK>
0x91F8	0x8AFE	# <CJK>
0x91F9	0x8338	# <CJK>
0x91FA	0x51E7	# <CJK>
0x91FB	0x86F8	# <CJK>
0x91FC	0x53EA	# <CJK>
0x9240	0x53E9	# <CJK>
0x9241	0x4F46	# <CJK>
0x9242	0x9054	# <CJK>
0x9243	0x8FB0	# <CJK>
0x9244	0x596A	# <CJK>
0x9245	0x8131	# <CJK>
0x9246	0x5DFD	# <CJK>
0x9247	0x7AEA	# <CJK>
0x9248	0x8FBF	# <CJK>
0x9249	0x68DA	# <CJK>
0x924A	0x8C37	# <CJK>
0x924B	0x72F8	# <CJK>
0x924C	0x9C48	# <CJK>
0x924D	0x6A3D	# <CJK>
0x924E	0x8AB0	# <CJK>
0x924F	0x4E39	# <CJK>
0x9250	0x5358	# <CJK>
0x9251	0x5606	# <CJK>
0x9252	0x5766	# <CJK>
0x9253	0x62C5	# <CJK>
0x9254	0x63A2	# <CJK>
0x9255	0x65E6	# <CJK>
0x9256	0x6B4E	# <CJK>
0x9257	0x6DE1	# <CJK>
0x9258	0x6E5B	# <CJK>
0x9259	0x70AD	# <CJK>
0x925A	0x77ED	# <CJK>
0x925B	0x7AEF	# <CJK>
0x925C	0x7BAA	# <CJK>
0x925D	0x7DBB	# <CJK>
0x925E	0x803D	# <CJK>
0x925F	0x80C6	# <CJK>
0x9260	0x86CB	# <CJK>
0x9261	0x8A95	# <CJK>
0x9262	0x935B	# <CJK>
0x9263	0x56E3	# <CJK>
0x9264	0x58C7	# <CJK>
0x9265	0x5F3E	# <CJK>
0x9266	0x65AD	# <CJK>
0x9267	0x6696	# <CJK>
0x9268	0x6A80	# <CJK>
0x9269	0x6BB5	# <CJK>
0x926A	0x7537	# <CJK>
0x926B	0x8AC7	# <CJK>
0x926C	0x5024	# <CJK>
0x926D	0x77E5	# <CJK>
0x926E	0x5730	# <CJK>
0x926F	0x5F1B	# <CJK>
0x9270	0x6065	# <CJK>
0x9271	0x667A	# <CJK>
0x9272	0x6C60	# <CJK>
0x9273	0x75F4	# <CJK>
0x9274	0x7A1A	# <CJK>
0x9275	0x7F6E	# <CJK>
0x9276	0x81F4	# <CJK>
0x9277	0x8718	# <CJK>
0x9278	0x9045	# <CJK>
0x9279	0x99B3	# <CJK>
0x927A	0x7BC9	# <CJK>
0x927B	0x755C	# <CJK>
0x927C	0x7AF9	# <CJK>
0x927D	0x7B51	# <CJK>
0x927E	0x84C4	# <CJK>
0x9280	0x9010	# <CJK>
0x9281	0x79E9	# <CJK>
0x9282	0x7A92	# <CJK>
0x9283	0x8336	# <CJK>
0x9284	0x5AE1	# <CJK>
0x9285	0x7740	# <CJK>
0x9286	0x4E2D	# <CJK>
0x9287	0x4EF2	# <CJK>
0x9288	0x5B99	# <CJK>
0x9289	0x5FE0	# <CJK>
0x928A	0x62BD	# <CJK>
0x928B	0x663C	# <CJK>
0x928C	0x67F1	# <CJK>
0x928D	0x6CE8	# <CJK>
0x928E	0x866B	# <CJK>
0x928F	0x8877	# <CJK>
0x9290	0x8A3B	# <CJK>
0x9291	0x914E	# <CJK>
0x9292	0x92F3	# <CJK>
0x9293	0x99D0	# <CJK>
0x9294	0x6A17	# <CJK>
0x9295	0x7026	# <CJK>
0x9296	0x732A	# <CJK>
0x9297	0x82E7	# <CJK>
0x9298	0x8457	# <CJK>
0x9299	0x8CAF	# <CJK>
0x929A	0x4E01	# <CJK>
0x929B	0x5146	# <CJK>
0x929C	0x51CB	# <CJK>
0x929D	0x558B	# <CJK>
0x929E	0x5BF5	# <CJK>
0x929F	0x5E16	# <CJK>
0x92A0	0x5E33	# <CJK>
0x92A1	0x5E81	# <CJK>
0x92A2	0x5F14	# <CJK>
0x92A3	0x5F35	# <CJK>
0x92A4	0x5F6B	# <CJK>
0x92A5	0x5FB4	# <CJK>
0x92A6	0x61F2	# <CJK>
0x92A7	0x6311	# <CJK>
0x92A8	0x66A2	# <CJK>
0x92A9	0x671D	# <CJK>
0x92AA	0x6F6E	# <CJK>
0x92AB	0x7252	# <CJK>
0x92AC	0x753A	# <CJK>
0x92AD	0x773A	# <CJK>
0x92AE	0x8074	# <CJK>
0x92AF	0x8139	# <CJK>
0x92B0	0x8178	# <CJK>
0x92B1	0x8776	# <CJK>
0x92B2	0x8ABF	# <CJK>
0x92B3	0x8ADC	# <CJK>
0x92B4	0x8D85	# <CJK>
0x92B5	0x8DF3	# <CJK>
0x92B6	0x929A	# <CJK>
0x92B7	0x9577	# <CJK>
0x92B8	0x9802	# <CJK>
0x92B9	0x9CE5	# <CJK>
0x92BA	0x52C5	# <CJK>
0x92BB	0x6357	# <CJK>
0x92BC	0x76F4	# <CJK>
0x92BD	0x6715	# <CJK>
0x92BE	0x6C88	# <CJK>
0x92BF	0x73CD	# <CJK>
0x92C0	0x8CC3	# <CJK>
0x92C1	0x93AE	# <CJK>
0x92C2	0x9673	# <CJK>
0x92C3	0x6D25	# <CJK>
0x92C4	0x589C	# <CJK>
0x92C5	0x690E	# <CJK>
0x92C6	0x69CC	# <CJK>
0x92C7	0x8FFD	# <CJK>
0x92C8	0x939A	# <CJK>
0x92C9	0x75DB	# <CJK>
0x92CA	0x901A	# <CJK>
0x92CB	0x585A	# <CJK>
0x92CC	0x6802	# <CJK>
0x92CD	0x63B4	# <CJK>
0x92CE	0x69FB	# <CJK>
0x92CF	0x4F43	# <CJK>
0x92D0	0x6F2C	# <CJK>
0x92D1	0x67D8	# <CJK>
0x92D2	0x8FBB	# <CJK>
0x92D3	0x8526	# <CJK>
0x92D4	0x7DB4	# <CJK>
0x92D5	0x9354	# <CJK>
0x92D6	0x693F	# <CJK>
0x92D7	0x6F70	# <CJK>
0x92D8	0x576A	# <CJK>
0x92D9	0x58F7	# <CJK>
0x92DA	0x5B2C	# <CJK>
0x92DB	0x7D2C	# <CJK>
0x92DC	0x722A	# <CJK>
0x92DD	0x540A	# <CJK>
0x92DE	0x91E3	# <CJK>
0x92DF	0x9DB4	# <CJK>
0x92E0	0x4EAD	# <CJK>
0x92E1	0x4F4E	# <CJK>
0x92E2	0x505C	# <CJK>
0x92E3	0x5075	# <CJK>
0x92E4	0x5243	# <CJK>
0x92E5	0x8C9E	# <CJK>
0x92E6	0x5448	# <CJK>
0x92E7	0x5824	# <CJK>
0x92E8	0x5B9A	# <CJK>
0x92E9	0x5E1D	# <CJK>
0x92EA	0x5E95	# <CJK>
0x92EB	0x5EAD	# <CJK>
0x92EC	0x5EF7	# <CJK>
0x92ED	0x5F1F	# <CJK>
0x92EE	0x608C	# <CJK>
0x92EF	0x62B5	# <CJK>
0x92F0	0x633A	# <CJK>
0x92F1	0x63D0	# <CJK>
0x92F2	0x68AF	# <CJK>
0x92F3	0x6C40	# <CJK>
0x92F4	0x7887	# <CJK>
0x92F5	0x798E	# <CJK>
0x92F6	0x7A0B	# <CJK>
0x92F7	0x7DE0	# <CJK>
0x92F8	0x8247	# <CJK>
0x92F9	0x8A02	# <CJK>
0x92FA	0x8AE6	# <CJK>
0x92FB	0x8E44	# <CJK>
0x92FC	0x9013	# <CJK>
0x9340	0x90B8	# <CJK>
0x9341	0x912D	# <CJK>
0x9342	0x91D8	# <CJK>
0x9343	0x9F0E	# <CJK>
0x9344	0x6CE5	# <CJK>
0x9345	0x6458	# <CJK>
0x9346	0x64E2	# <CJK>
0x9347	0x6575	# <CJK>
0x9348	0x6EF4	# <CJK>
0x9349	0x7684	# <CJK>
0x934A	0x7B1B	# <CJK>
0x934B	0x9069	# <CJK>
0x934C	0x93D1	# <CJK>
0x934D	0x6EBA	# <CJK>
0x934E	0x54F2	# <CJK>
0x934F	0x5FB9	# <CJK>
0x9350	0x64A4	# <CJK>
0x9351	0x8F4D	# <CJK>
0x9352	0x8FED	# <CJK>
0x9353	0x9244	# <CJK>
0x9354	0x5178	# <CJK>
0x9355	0x586B	# <CJK>
0x9356	0x5929	# <CJK>
0x9357	0x5C55	# <CJK>
0x9358	0x5E97	# <CJK>
0x9359	0x6DFB	# <CJK>
0x935A	0x7E8F	# <CJK>
0x935B	0x751C	# <CJK>
0x935C	0x8CBC	# <CJK>
0x935D	0x8EE2	# <CJK>
0x935E	0x985B	# <CJK>
0x935F	0x70B9	# <CJK>
0x9360	0x4F1D	# <CJK>
0x9361	0x6BBF	# <CJK>
0x9362	0x6FB1	# <CJK>
0x9363	0x7530	# <CJK>
0x9364	0x96FB	# <CJK>
0x9365	0x514E	# <CJK>
0x9366	0x5410	# <CJK>
0x9367	0x5835	# <CJK>
0x9368	0x5857	# <CJK>
0x9369	0x59AC	# <CJK>
0x936A	0x5C60	# <CJK>
0x936B	0x5F92	# <CJK>
0x936C	0x6597	# <CJK>
0x936D	0x675C	# <CJK>
0x936E	0x6E21	# <CJK>
0x936F	0x767B	# <CJK>
0x9370	0x83DF	# <CJK>
0x9371	0x8CED	# <CJK>
0x9372	0x9014	# <CJK>
0x9373	0x90FD	# <CJK>
0x9374	0x934D	# <CJK>
0x9375	0x7825	# <CJK>
0x9376	0x783A	# <CJK>
0x9377	0x52AA	# <CJK>
0x9378	0x5EA6	# <CJK>
0x9379	0x571F	# <CJK>
0x937A	0x5974	# <CJK>
0x937B	0x6012	# <CJK>
0x937C	0x5012	# <CJK>
0x937D	0x515A	# <CJK>
0x937E	0x51AC	# <CJK>
0x9380	0x51CD	# <CJK>
0x9381	0x5200	# <CJK>
0x9382	0x5510	# <CJK>
0x9383	0x5854	# <CJK>
0x9384	0x5858	# <CJK>
0x9385	0x5957	# <CJK>
0x9386	0x5B95	# <CJK>
0x9387	0x5CF6	# <CJK>
0x9388	0x5D8B	# <CJK>
0x9389	0x60BC	# <CJK>
0x938A	0x6295	# <CJK>
0x938B	0x642D	# <CJK>
0x938C	0x6771	# <CJK>
0x938D	0x6843	# <CJK>
0x938E	0x68BC	# <CJK>
0x938F	0x68DF	# <CJK>
0x9390	0x76D7	# <CJK>
0x9391	0x6DD8	# <CJK>
0x9392	0x6E6F	# <CJK>
0x9393	0x6D9B	# <CJK>
0x9394	0x706F	# <CJK>
0x9395	0x71C8	# <CJK>
0x9396	0x5F53	# <CJK>
0x9397	0x75D8	# <CJK>
0x9398	0x7977	# <CJK>
0x9399	0x7B49	# <CJK>
0x939A	0x7B54	# <CJK>
0x939B	0x7B52	# <CJK>
0x939C	0x7CD6	# <CJK>
0x939D	0x7D71	# <CJK>
0x939E	0x5230	# <CJK>
0x939F	0x8463	# <CJK>
0x93A0	0x8569	# <CJK>
0x93A1	0x85E4	# <CJK>
0x93A2	0x8A0E	# <CJK>
0x93A3	0x8B04	# <CJK>
0x93A4	0x8C46	# <CJK>
0x93A5	0x8E0F	# <CJK>
0x93A6	0x9003	# <CJK>
0x93A7	0x900F	# <CJK>
0x93A8	0x9419	# <CJK>
0x93A9	0x9676	# <CJK>
0x93AA	0x982D	# <CJK>
0x93AB	0x9A30	# <CJK>
0x93AC	0x95D8	# <CJK>
0x93AD	0x50CD	# <CJK>
0x93AE	0x52D5	# <CJK>
0x93AF	0x540C	# <CJK>
0x93B0	0x5802	# <CJK>
0x93B1	0x5C0E	# <CJK>
0x93B2	0x61A7	# <CJK>
0x93B3	0x649E	# <CJK>
0x93B4	0x6D1E	# <CJK>
0x93B5	0x77B3	# <CJK>
0x93B6	0x7AE5	# <CJK>
0x93B7	0x80F4	# <CJK>
0x93B8	0x8404	# <CJK>
0x93B9	0x9053	# <CJK>
0x93BA	0x9285	# <CJK>
0x93BB	0x5CE0	# <CJK>
0x93BC	0x9D07	# <CJK>
0x93BD	0x533F	# <CJK>
0x93BE	0x5F97	# <CJK>
0x93BF	0x5FB3	# <CJK>
0x93C0	0x6D9C	# <CJK>
0x93C1	0x7279	# <CJK>
0x93C2	0x7763	# <CJK>
0x93C3	0x79BF	# <CJK>
0x93C4	0x7BE4	# <CJK>
0x93C5	0x6BD2	# <CJK>
0x93C6	0x72EC	# <CJK>
0x93C7	0x8AAD	# <CJK>
0x93C8	0x6803	# <CJK>
0x93C9	0x6A61	# <CJK>
0x93CA	0x51F8	# <CJK>
0x93CB	0x7A81	# <CJK>
0x93CC	0x6934	# <CJK>
0x93CD	0x5C4A	# <CJK>
0x93CE	0x9CF6	# <CJK>
0x93CF	0x82EB	# <CJK>
0x93D0	0x5BC5	# <CJK>
0x93D1	0x9149	# <CJK>
0x93D2	0x701E	# <CJK>
0x93D3	0x5678	# <CJK>
0x93D4	0x5C6F	# <CJK>
0x93D5	0x60C7	# <CJK>
0x93D6	0x6566	# <CJK>
0x93D7	0x6C8C	# <CJK>
0x93D8	0x8C5A	# <CJK>
0x93D9	0x9041	# <CJK>
0x93DA	0x9813	# <CJK>
0x93DB	0x5451	# <CJK>
0x93DC	0x66C7	# <CJK>
0x93DD	0x920D	# <CJK>
0x93DE	0x5948	# <CJK>
0x93DF	0x90A3	# <CJK>
0x93E0	0x5185	# <CJK>
0x93E1	0x4E4D	# <CJK>
0x93E2	0x51EA	# <CJK>
0x93E3	0x8599	# <CJK>
0x93E4	0x8B0E	# <CJK>
0x93E5	0x7058	# <CJK>
0x93E6	0x637A	# <CJK>
0x93E7	0x934B	# <CJK>
0x93E8	0x6962	# <CJK>
0x93E9	0x99B4	# <CJK>
0x93EA	0x7E04	# <CJK>
0x93EB	0x7577	# <CJK>
0x93EC	0x5357	# <CJK>
0x93ED	0x6960	# <CJK>
0x93EE	0x8EDF	# <CJK>
0x93EF	0x96E3	# <CJK>
0x93F0	0x6C5D	# <CJK>
0x93F1	0x4E8C	# <CJK>
0x93F2	0x5C3C	# <CJK>
0x93F3	0x5F10	# <CJK>
0x93F4	0x8FE9	# <CJK>
0x93F5	0x5302	# <CJK>
0x93F6	0x8CD1	# <CJK>
0x93F7	0x8089	# <CJK>
0x93F8	0x8679	# <CJK>
0x93F9	0x5EFF	# <CJK>
0x93FA	0x65E5	# <CJK>
0x93FB	0x4E73	# <CJK>
0x93FC	0x5165	# <CJK>
0x9440	0x5982	# <CJK>
0x9441	0x5C3F	# <CJK>
0x9442	0x97EE	# <CJK>
0x9443	0x4EFB	# <CJK>
0x9444	0x598A	# <CJK>
0x9445	0x5FCD	# <CJK>
0x9446	0x8A8D	# <CJK>
0x9447	0x6FE1	# <CJK>
0x9448	0x79B0	# <CJK>
0x9449	0x7962	# <CJK>
0x944A	0x5BE7	# <CJK>
0x944B	0x8471	# <CJK>
0x944C	0x732B	# <CJK>
0x944D	0x71B1	# <CJK>
0x944E	0x5E74	# <CJK>
0x944F	0x5FF5	# <CJK>
0x9450	0x637B	# <CJK>
0x9451	0x649A	# <CJK>
0x9452	0x71C3	# <CJK>
0x9453	0x7C98	# <CJK>
0x9454	0x4E43	# <CJK>
0x9455	0x5EFC	# <CJK>
0x9456	0x4E4B	# <CJK>
0x9457	0x57DC	# <CJK>
0x9458	0x56A2	# <CJK>
0x9459	0x60A9	# <CJK>
0x945A	0x6FC3	# <CJK>
0x945B	0x7D0D	# <CJK>
0x945C	0x80FD	# <CJK>
0x945D	0x8133	# <CJK>
0x945E	0x81BF	# <CJK>
0x945F	0x8FB2	# <CJK>
0x9460	0x8997	# <CJK>
0x9461	0x86A4	# <CJK>
0x9462	0x5DF4	# <CJK>
0x9463	0x628A	# <CJK>
0x9464	0x64AD	# <CJK>
0x9465	0x8987	# <CJK>
0x9466	0x6777	# <CJK>
0x9467	0x6CE2	# <CJK>
0x9468	0x6D3E	# <CJK>
0x9469	0x7436	# <CJK>
0x946A	0x7834	# <CJK>
0x946B	0x5A46	# <CJK>
0x946C	0x7F75	# <CJK>
0x946D	0x82AD	# <CJK>
0x946E	0x99AC	# <CJK>
0x946F	0x4FF3	# <CJK>
0x9470	0x5EC3	# <CJK>
0x9471	0x62DD	# <CJK>
0x9472	0x6392	# <CJK>
0x9473	0x6557	# <CJK>
0x9474	0x676F	# <CJK>
0x9475	0x76C3	# <CJK>
0x9476	0x724C	# <CJK>
0x9477	0x80CC	# <CJK>
0x9478	0x80BA	# <CJK>
0x9479	0x8F29	# <CJK>
0x947A	0x914D	# <CJK>
0x947B	0x500D	# <CJK>
0x947C	0x57F9	# <CJK>
0x947D	0x5A92	# <CJK>
0x947E	0x6885	# <CJK>
0x9480	0x6973	# <CJK>
0x9481	0x7164	# <CJK>
0x9482	0x72FD	# <CJK>
0x9483	0x8CB7	# <CJK>
0x9484	0x58F2	# <CJK>
0x9485	0x8CE0	# <CJK>
0x9486	0x966A	# <CJK>
0x9487	0x9019	# <CJK>
0x9488	0x877F	# <CJK>
0x9489	0x79E4	# <CJK>
0x948A	0x77E7	# <CJK>
0x948B	0x8429	# <CJK>
0x948C	0x4F2F	# <CJK>
0x948D	0x5265	# <CJK>
0x948E	0x535A	# <CJK>
0x948F	0x62CD	# <CJK>
0x9490	0x67CF	# <CJK>
0x9491	0x6CCA	# <CJK>
0x9492	0x767D	# <CJK>
0x9493	0x7B94	# <CJK>
0x9494	0x7C95	# <CJK>
0x9495	0x8236	# <CJK>
0x9496	0x8584	# <CJK>
0x9497	0x8FEB	# <CJK>
0x9498	0x66DD	# <CJK>
0x9499	0x6F20	# <CJK>
0x949A	0x7206	# <CJK>
0x949B	0x7E1B	# <CJK>
0x949C	0x83AB	# <CJK>
0x949D	0x99C1	# <CJK>
0x949E	0x9EA6	# <CJK>
0x949F	0x51FD	# <CJK>
0x94A0	0x7BB1	# <CJK>
0x94A1	0x7872	# <CJK>
0x94A2	0x7BB8	# <CJK>
0x94A3	0x8087	# <CJK>
0x94A4	0x7B48	# <CJK>
0x94A5	0x6AE8	# <CJK>
0x94A6	0x5E61	# <CJK>
0x94A7	0x808C	# <CJK>
0x94A8	0x7551	# <CJK>
0x94A9	0x7560	# <CJK>
0x94AA	0x516B	# <CJK>
0x94AB	0x9262	# <CJK>
0x94AC	0x6E8C	# <CJK>
0x94AD	0x767A	# <CJK>
0x94AE	0x9197	# <CJK>
0x94AF	0x9AEA	# <CJK>
0x94B0	0x4F10	# <CJK>
0x94B1	0x7F70	# <CJK>
0x94B2	0x629C	# <CJK>
0x94B3	0x7B4F	# <CJK>
0x94B4	0x95A5	# <CJK>
0x94B5	0x9CE9	# <CJK>
0x94B6	0x567A	# <CJK>
0x94B7	0x5859	# <CJK>
0x94B8	0x86E4	# <CJK>
0x94B9	0x96BC	# <CJK>
0x94BA	0x4F34	# <CJK>
0x94BB	0x5224	# <CJK>
0x94BC	0x534A	# <CJK>
0x94BD	0x53CD	# <CJK>
0x94BE	0x53DB	# <CJK>
0x94BF	0x5E06	# <CJK>
0x94C0	0x642C	# <CJK>
0x94C1	0x6591	# <CJK>
0x94C2	0x677F	# <CJK>
0x94C3	0x6C3E	# <CJK>
0x94C4	0x6C4E	# <CJK>
0x94C5	0x7248	# <CJK>
0x94C6	0x72AF	# <CJK>
0x94C7	0x73ED	# <CJK>
0x94C8	0x7554	# <CJK>
0x94C9	0x7E41	# <CJK>
0x94CA	0x822C	# <CJK>
0x94CB	0x85E9	# <CJK>
0x94CC	0x8CA9	# <CJK>
0x94CD	0x7BC4	# <CJK>
0x94CE	0x91C6	# <CJK>
0x94CF	0x7169	# <CJK>
0x94D0	0x9812	# <CJK>
0x94D1	0x98EF	# <CJK>
0x94D2	0x633D	# <CJK>
0x94D3	0x6669	# <CJK>
0x94D4	0x756A	# <CJK>
0x94D5	0x76E4	# <CJK>
0x94D6	0x78D0	# <CJK>
0x94D7	0x8543	# <CJK>
0x94D8	0x86EE	# <CJK>
0x94D9	0x532A	# <CJK>
0x94DA	0x5351	# <CJK>
0x94DB	0x5426	# <CJK>
0x94DC	0x5983	# <CJK>
0x94DD	0x5E87	# <CJK>
0x94DE	0x5F7C	# <CJK>
0x94DF	0x60B2	# <CJK>
0x94E0	0x6249	# <CJK>
0x94E1	0x6279	# <CJK>
0x94E2	0x62AB	# <CJK>
0x94E3	0x6590	# <CJK>
0x94E4	0x6BD4	# <CJK>
0x94E5	0x6CCC	# <CJK>
0x94E6	0x75B2	# <CJK>
0x94E7	0x76AE	# <CJK>
0x94E8	0x7891	# <CJK>
0x94E9	0x79D8	# <CJK>
0x94EA	0x7DCB	# <CJK>
0x94EB	0x7F77	# <CJK>
0x94EC	0x80A5	# <CJK>
0x94ED	0x88AB	# <CJK>
0x94EE	0x8AB9	# <CJK>
0x94EF	0x8CBB	# <CJK>
0x94F0	0x907F	# <CJK>
0x94F1	0x975E	# <CJK>
0x94F2	0x98DB	# <CJK>
0x94F3	0x6A0B	# <CJK>
0x94F4	0x7C38	# <CJK>
0x94F5	0x5099	# <CJK>
0x94F6	0x5C3E	# <CJK>
0x94F7	0x5FAE	# <CJK>
0x94F8	0x6787	# <CJK>
0x94F9	0x6BD8	# <CJK>
0x94FA	0x7435	# <CJK>
0x94FB	0x7709	# <CJK>
0x94FC	0x7F8E	# <CJK>
0x9540	0x9F3B	# <CJK>
0x9541	0x67CA	# <CJK>
0x9542	0x7A17	# <CJK>
0x9543	0x5339	# <CJK>
0x9544	0x758B	# <CJK>
0x9545	0x9AED	# <CJK>
0x9546	0x5F66	# <CJK>
0x9547	0x819D	# <CJK>
0x9548	0x83F1	# <CJK>
0x9549	0x8098	# <CJK>
0x954A	0x5F3C	# <CJK>
0x954B	0x5FC5	# <CJK>
0x954C	0x7562	# <CJK>
0x954D	0x7B46	# <CJK>
0x954E	0x903C	# <CJK>
0x954F	0x6867	# <CJK>
0x9550	0x59EB	# <CJK>
0x9551	0x5A9B	# <CJK>
0x9552	0x7D10	# <CJK>
0x9553	0x767E	# <CJK>
0x9554	0x8B2C	# <CJK>
0x9555	0x4FF5	# <CJK>
0x9556	0x5F6A	# <CJK>
0x9557	0x6A19	# <CJK>
0x9558	0x6C37	# <CJK>
0x9559	0x6F02	# <CJK>
0x955A	0x74E2	# <CJK>
0x955B	0x7968	# <CJK>
0x955C	0x8868	# <CJK>
0x955D	0x8A55	# <CJK>
0x955E	0x8C79	# <CJK>
0x955F	0x5EDF	# <CJK>
0x9560	0x63CF	# <CJK>
0x9561	0x75C5	# <CJK>
0x9562	0x79D2	# <CJK>
0x9563	0x82D7	# <CJK>
0x9564	0x9328	# <CJK>
0x9565	0x92F2	# <CJK>
0x9566	0x849C	# <CJK>
0x9567	0x86ED	# <CJK>
0x9568	0x9C2D	# <CJK>
0x9569	0x54C1	# <CJK>
0x956A	0x5F6C	# <CJK>
0x956B	0x658C	# <CJK>
0x956C	0x6D5C	# <CJK>
0x956D	0x7015	# <CJK>
0x956E	0x8CA7	# <CJK>
0x956F	0x8CD3	# <CJK>
0x9570	0x983B	# <CJK>
0x9571	0x654F	# <CJK>
0x9572	0x74F6	# <CJK>
0x9573	0x4E0D	# <CJK>
0x9574	0x4ED8	# <CJK>
0x9575	0x57E0	# <CJK>
0x9576	0x592B	# <CJK>
0x9577	0x5A66	# <CJK>
0x9578	0x5BCC	# <CJK>
0x9579	0x51A8	# <CJK>
0x957A	0x5E03	# <CJK>
0x957B	0x5E9C	# <CJK>
0x957C	0x6016	# <CJK>
0x957D	0x6276	# <CJK>
0x957E	0x6577	# <CJK>
0x9580	0x65A7	# <CJK>
0x9581	0x666E	# <CJK>
0x9582	0x6D6E	# <CJK>
0x9583	0x7236	# <CJK>
0x9584	0x7B26	# <CJK>
0x9585	0x8150	# <CJK>
0x9586	0x819A	# <CJK>
0x9587	0x8299	# <CJK>
0x9588	0x8B5C	# <CJK>
0x9589	0x8CA0	# <CJK>
0x958A	0x8CE6	# <CJK>
0x958B	0x8D74	# <CJK>
0x958C	0x961C	# <CJK>
0x958D	0x9644	# <CJK>
0x958E	0x4FAE	# <CJK>
0x958F	0x64AB	# <CJK>
0x9590	0x6B66	# <CJK>
0x9591	0x821E	# <CJK>
0x9592	0x8461	# <CJK>
0x9593	0x856A	# <CJK>
0x9594	0x90E8	# <CJK>
0x9595	0x5C01	# <CJK>
0x9596	0x6953	# <CJK>
0x9597	0x98A8	# <CJK>
0x9598	0x847A	# <CJK>
0x9599	0x8557	# <CJK>
0x959A	0x4F0F	# <CJK>
0x959B	0x526F	# <CJK>
0x959C	0x5FA9	# <CJK>
0x959D	0x5E45	# <CJK>
0x959E	0x670D	# <CJK>
0x959F	0x798F	# <CJK>
0x95A0	0x8179	# <CJK>
0x95A1	0x8907	# <CJK>
0x95A2	0x8986	# <CJK>
0x95A3	0x6DF5	# <CJK>
0x95A4	0x5F17	# <CJK>
0x95A5	0x6255	# <CJK>
0x95A6	0x6CB8	# <CJK>
0x95A7	0x4ECF	# <CJK>
0x95A8	0x7269	# <CJK>
0x95A9	0x9B92	# <CJK>
0x95AA	0x5206	# <CJK>
0x95AB	0x543B	# <CJK>
0x95AC	0x5674	# <CJK>
0x95AD	0x58B3	# <CJK>
0x95AE	0x61A4	# <CJK>
0x95AF	0x626E	# <CJK>
0x95B0	0x711A	# <CJK>
0x95B1	0x596E	# <CJK>
0x95B2	0x7C89	# <CJK>
0x95B3	0x7CDE	# <CJK>
0x95B4	0x7D1B	# <CJK>
0x95B5	0x96F0	# <CJK>
0x95B6	0x6587	# <CJK>
0x95B7	0x805E	# <CJK>
0x95B8	0x4E19	# <CJK>
0x95B9	0x4F75	# <CJK>
0x95BA	0x5175	# <CJK>
0x95BB	0x5840	# <CJK>
0x95BC	0x5E63	# <CJK>
0x95BD	0x5E73	# <CJK>
0x95BE	0x5F0A	# <CJK>
0x95BF	0x67C4	# <CJK>
0x95C0	0x4E26	# <CJK>
0x95C1	0x853D	# <CJK>
0x95C2	0x9589	# <CJK>
0x95C3	0x965B	# <CJK>
0x95C4	0x7C73	# <CJK>
0x95C5	0x9801	# <CJK>
0x95C6	0x50FB	# <CJK>
0x95C7	0x58C1	# <CJK>
0x95C8	0x7656	# <CJK>
0x95C9	0x78A7	# <CJK>
0x95CA	0x5225	# <CJK>
0x95CB	0x77A5	# <CJK>
0x95CC	0x8511	# <CJK>
0x95CD	0x7B86	# <CJK>
0x95CE	0x504F	# <CJK>
0x95CF	0x5909	# <CJK>
0x95D0	0x7247	# <CJK>
0x95D1	0x7BC7	# <CJK>
0x95D2	0x7DE8	# <CJK>
0x95D3	0x8FBA	# <CJK>
0x95D4	0x8FD4	# <CJK>
0x95D5	0x904D	# <CJK>
0x95D6	0x4FBF	# <CJK>
0x95D7	0x52C9	# <CJK>
0x95D8	0x5A29	# <CJK>
0x95D9	0x5F01	# <CJK>
0x95DA	0x97AD	# <CJK>
0x95DB	0x4FDD	# <CJK>
0x95DC	0x8217	# <CJK>
0x95DD	0x92EA	# <CJK>
0x95DE	0x5703	# <CJK>
0x95DF	0x6355	# <CJK>
0x95E0	0x6B69	# <CJK>
0x95E1	0x752B	# <CJK>
0x95E2	0x88DC	# <CJK>
0x95E3	0x8F14	# <CJK>
0x95E4	0x7A42	# <CJK>
0x95E5	0x52DF	# <CJK>
0x95E6	0x5893	# <CJK>
0x95E7	0x6155	# <CJK>
0x95E8	0x620A	# <CJK>
0x95E9	0x66AE	# <CJK>
0x95EA	0x6BCD	# <CJK>
0x95EB	0x7C3F	# <CJK>
0x95EC	0x83E9	# <CJK>
0x95ED	0x5023	# <CJK>
0x95EE	0x4FF8	# <CJK>
0x95EF	0x5305	# <CJK>
0x95F0	0x5446	# <CJK>
0x95F1	0x5831	# <CJK>
0x95F2	0x5949	# <CJK>
0x95F3	0x5B9D	# <CJK>
0x95F4	0x5CF0	# <CJK>
0x95F5	0x5CEF	# <CJK>
0x95F6	0x5D29	# <CJK>
0x95F7	0x5E96	# <CJK>
0x95F8	0x62B1	# <CJK>
0x95F9	0x6367	# <CJK>
0x95FA	0x653E	# <CJK>
0x95FB	0x65B9	# <CJK>
0x95FC	0x670B	# <CJK>
0x9640	0x6CD5	# <CJK>
0x9641	0x6CE1	# <CJK>
0x9642	0x70F9	# <CJK>
0x9643	0x7832	# <CJK>
0x9644	0x7E2B	# <CJK>
0x9645	0x80DE	# <CJK>
0x9646	0x82B3	# <CJK>
0x9647	0x840C	# <CJK>
0x9648	0x84EC	# <CJK>
0x9649	0x8702	# <CJK>
0x964A	0x8912	# <CJK>
0x964B	0x8A2A	# <CJK>
0x964C	0x8C4A	# <CJK>
0x964D	0x90A6	# <CJK>
0x964E	0x92D2	# <CJK>
0x964F	0x98FD	# <CJK>
0x9650	0x9CF3	# <CJK>
0x9651	0x9D6C	# <CJK>
0x9652	0x4E4F	# <CJK>
0x9653	0x4EA1	# <CJK>
0x9654	0x508D	# <CJK>
0x9655	0x5256	# <CJK>
0x9656	0x574A	# <CJK>
0x9657	0x59A8	# <CJK>
0x9658	0x5E3D	# <CJK>
0x9659	0x5FD8	# <CJK>
0x965A	0x5FD9	# <CJK>
0x965B	0x623F	# <CJK>
0x965C	0x66B4	# <CJK>
0x965D	0x671B	# <CJK>
0x965E	0x67D0	# <CJK>
0x965F	0x68D2	# <CJK>
0x9660	0x5192	# <CJK>
0x9661	0x7D21	# <CJK>
0x9662	0x80AA	# <CJK>
0x9663	0x81A8	# <CJK>
0x9664	0x8B00	# <CJK>
0x9665	0x8C8C	# <CJK>
0x9666	0x8CBF	# <CJK>
0x9667	0x927E	# <CJK>
0x9668	0x9632	# <CJK>
0x9669	0x5420	# <CJK>
0x966A	0x982C	# <CJK>
0x966B	0x5317	# <CJK>
0x966C	0x50D5	# <CJK>
0x966D	0x535C	# <CJK>
0x966E	0x58A8	# <CJK>
0x966F	0x64B2	# <CJK>
0x9670	0x6734	# <CJK>
0x9671	0x7267	# <CJK>
0x9672	0x7766	# <CJK>
0x9673	0x7A46	# <CJK>
0x9674	0x91E6	# <CJK>
0x9675	0x52C3	# <CJK>
0x9676	0x6CA1	# <CJK>
0x9677	0x6B86	# <CJK>
0x9678	0x5800	# <CJK>
0x9679	0x5E4C	# <CJK>
0x967A	0x5954	# <CJK>
0x967B	0x672C	# <CJK>
0x967C	0x7FFB	# <CJK>
0x967D	0x51E1	# <CJK>
0x967E	0x76C6	# <CJK>
0x9680	0x6469	# <CJK>
0x9681	0x78E8	# <CJK>
0x9682	0x9B54	# <CJK>
0x9683	0x9EBB	# <CJK>
0x9684	0x57CB	# <CJK>
0x9685	0x59B9	# <CJK>
0x9686	0x6627	# <CJK>
0x9687	0x679A	# <CJK>
0x9688	0x6BCE	# <CJK>
0x9689	0x54E9	# <CJK>
0x968A	0x69D9	# <CJK>
0x968B	0x5E55	# <CJK>
0x968C	0x819C	# <CJK>
0x968D	0x6795	# <CJK>
0x968E	0x9BAA	# <CJK>
0x968F	0x67FE	# <CJK>
0x9690	0x9C52	# <CJK>
0x9691	0x685D	# <CJK>
0x9692	0x4EA6	# <CJK>
0x9693	0x4FE3	# <CJK>
0x9694	0x53C8	# <CJK>
0x9695	0x62B9	# <CJK>
0x9696	0x672B	# <CJK>
0x9697	0x6CAB	# <CJK>
0x9698	0x8FC4	# <CJK>
0x9699	0x4FAD	# <CJK>
0x969A	0x7E6D	# <CJK>
0x969B	0x9EBF	# <CJK>
0x969C	0x4E07	# <CJK>
0x969D	0x6162	# <CJK>
0x969E	0x6E80	# <CJK>
0x969F	0x6F2B	# <CJK>
0x96A0	0x8513	# <CJK>
0x96A1	0x5473	# <CJK>
0x96A2	0x672A	# <CJK>
0x96A3	0x9B45	# <CJK>
0x96A4	0x5DF3	# <CJK>
0x96A5	0x7B95	# <CJK>
0x96A6	0x5CAC	# <CJK>
0x96A7	0x5BC6	# <CJK>
0x96A8	0x871C	# <CJK>
0x96A9	0x6E4A	# <CJK>
0x96AA	0x84D1	# <CJK>
0x96AB	0x7A14	# <CJK>
0x96AC	0x8108	# <CJK>
0x96AD	0x5999	# <CJK>
0x96AE	0x7C8D	# <CJK>
0x96AF	0x6C11	# <CJK>
0x96B0	0x7720	# <CJK>
0x96B1	0x52D9	# <CJK>
0x96B2	0x5922	# <CJK>
0x96B3	0x7121	# <CJK>
0x96B4	0x725F	# <CJK>
0x96B5	0x77DB	# <CJK>
0x96B6	0x9727	# <CJK>
0x96B7	0x9D61	# <CJK>
0x96B8	0x690B	# <CJK>
0x96B9	0x5A7F	# <CJK>
0x96BA	0x5A18	# <CJK>
0x96BB	0x51A5	# <CJK>
0x96BC	0x540D	# <CJK>
0x96BD	0x547D	# <CJK>
0x96BE	0x660E	# <CJK>
0x96BF	0x76DF	# <CJK>
0x96C0	0x8FF7	# <CJK>
0x96C1	0x9298	# <CJK>
0x96C2	0x9CF4	# <CJK>
0x96C3	0x59EA	# <CJK>
0x96C4	0x725D	# <CJK>
0x96C5	0x6EC5	# <CJK>
0x96C6	0x514D	# <CJK>
0x96C7	0x68C9	# <CJK>
0x96C8	0x7DBF	# <CJK>
0x96C9	0x7DEC	# <CJK>
0x96CA	0x9762	# <CJK>
0x96CB	0x9EBA	# <CJK>
0x96CC	0x6478	# <CJK>
0x96CD	0x6A21	# <CJK>
0x96CE	0x8302	# <CJK>
0x96CF	0x5984	# <CJK>
0x96D0	0x5B5F	# <CJK>
0x96D1	0x6BDB	# <CJK>
0x96D2	0x731B	# <CJK>
0x96D3	0x76F2	# <CJK>
0x96D4	0x7DB2	# <CJK>
0x96D5	0x8017	# <CJK>
0x96D6	0x8499	# <CJK>
0x96D7	0x5132	# <CJK>
0x96D8	0x6728	# <CJK>
0x96D9	0x9ED9	# <CJK>
0x96DA	0x76EE	# <CJK>
0x96DB	0x6762	# <CJK>
0x96DC	0x52FF	# <CJK>
0x96DD	0x9905	# <CJK>
0x96DE	0x5C24	# <CJK>
0x96DF	0x623B	# <CJK>
0x96E0	0x7C7E	# <CJK>
0x96E1	0x8CB0	# <CJK>
0x96E2	0x554F	# <CJK>
0x96E3	0x60B6	# <CJK>
0x96E4	0x7D0B	# <CJK>
0x96E5	0x9580	# <CJK>
0x96E6	0x5301	# <CJK>
0x96E7	0x4E5F	# <CJK>
0x96E8	0x51B6	# <CJK>
0x96E9	0x591C	# <CJK>
0x96EA	0x723A	# <CJK>
0x96EB	0x8036	# <CJK>
0x96EC	0x91CE	# <CJK>
0x96ED	0x5F25	# <CJK>
0x96EE	0x77E2	# <CJK>
0x96EF	0x5384	# <CJK>
0x96F0	0x5F79	# <CJK>
0x96F1	0x7D04	# <CJK>
0x96F2	0x85AC	# <CJK>
0x96F3	0x8A33	# <CJK>
0x96F4	0x8E8D	# <CJK>
0x96F5	0x9756	# <CJK>
0x96F6	0x67F3	# <CJK>
0x96F7	0x85AE	# <CJK>
0x96F8	0x9453	# <CJK>
0x96F9	0x6109	# <CJK>
0x96FA	0x6108	# <CJK>
0x96FB	0x6CB9	# <CJK>
0x96FC	0x7652	# <CJK>
0x96FF	0xFF5E	# <CJK>
0x9740	0x8AED	# <CJK>
0x9741	0x8F38	# <CJK>
0x9742	0x552F	# <CJK>
0x9743	0x4F51	# <CJK>
0x9744	0x512A	# <CJK>
0x9745	0x52C7	# <CJK>
0x9746	0x53CB	# <CJK>
0x9747	0x5BA5	# <CJK>
0x9748	0x5E7D	# <CJK>
0x9749	0x60A0	# <CJK>
0x974A	0x6182	# <CJK>
0x974B	0x63D6	# <CJK>
0x974C	0x6709	# <CJK>
0x974D	0x67DA	# <CJK>
0x974E	0x6E67	# <CJK>
0x974F	0x6D8C	# <CJK>
0x9750	0x7336	# <CJK>
0x9751	0x7337	# <CJK>
0x9752	0x7531	# <CJK>
0x9753	0x7950	# <CJK>
0x9754	0x88D5	# <CJK>
0x9755	0x8A98	# <CJK>
0x9756	0x904A	# <CJK>
0x9757	0x9091	# <CJK>
0x9758	0x90F5	# <CJK>
0x9759	0x96C4	# <CJK>
0x975A	0x878D	# <CJK>
0x975B	0x5915	# <CJK>
0x975C	0x4E88	# <CJK>
0x975D	0x4F59	# <CJK>
0x975E	0x4E0E	# <CJK>
0x975F	0x8A89	# <CJK>
0x9760	0x8F3F	# <CJK>
0x9761	0x9810	# <CJK>
0x9762	0x50AD	# <CJK>
0x9763	0x5E7C	# <CJK>
0x9764	0x5996	# <CJK>
0x9765	0x5BB9	# <CJK>
0x9766	0x5EB8	# <CJK>
0x9767	0x63DA	# <CJK>
0x9768	0x63FA	# <CJK>
0x9769	0x64C1	# <CJK>
0x976A	0x66DC	# <CJK>
0x976B	0x694A	# <CJK>
0x976C	0x69D8	# <CJK>
0x976D	0x6D0B	# <CJK>
0x976E	0x6EB6	# <CJK>
0x976F	0x7194	# <CJK>
0x9770	0x7528	# <CJK>
0x9771	0x7AAF	# <CJK>
0x9772	0x7F8A	# <CJK>
0x9773	0x8000	# <CJK>
0x9774	0x8449	# <CJK>
0x9775	0x84C9	# <CJK>
0x9776	0x8981	# <CJK>
0x9777	0x8B21	# <CJK>
0x9778	0x8E0A	# <CJK>
0x9779	0x9065	# <CJK>
0x977A	0x967D	# <CJK>
0x977B	0x990A	# <CJK>
0x977C	0x617E	# <CJK>
0x977D	0x6291	# <CJK>
0x977E	0x6B32	# <CJK>
0x9780	0x6C83	# <CJK>
0x9781	0x6D74	# <CJK>
0x9782	0x7FCC	# <CJK>
0x9783	0x7FFC	# <CJK>
0x9784	0x6DC0	# <CJK>
0x9785	0x7F85	# <CJK>
0x9786	0x87BA	# <CJK>
0x9787	0x88F8	# <CJK>
0x9788	0x6765	# <CJK>
0x9789	0x83B1	# <CJK>
0x978A	0x983C	# <CJK>
0x978B	0x96F7	# <CJK>
0x978C	0x6D1B	# <CJK>
0x978D	0x7D61	# <CJK>
0x978E	0x843D	# <CJK>
0x978F	0x916A	# <CJK>
0x9790	0x4E71	# <CJK>
0x9791	0x5375	# <CJK>
0x9792	0x5D50	# <CJK>
0x9793	0x6B04	# <CJK>
0x9794	0x6FEB	# <CJK>
0x9795	0x85CD	# <CJK>
0x9796	0x862D	# <CJK>
0x9797	0x89A7	# <CJK>
0x9798	0x5229	# <CJK>
0x9799	0x540F	# <CJK>
0x979A	0x5C65	# <CJK>
0x979B	0x674E	# <CJK>
0x979C	0x68A8	# <CJK>
0x979D	0x7406	# <CJK>
0x979E	0x7483	# <CJK>
0x979F	0x75E2	# <CJK>
0x97A0	0x88CF	# <CJK>
0x97A1	0x88E1	# <CJK>
0x97A2	0x91CC	# <CJK>
0x97A3	0x96E2	# <CJK>
0x97A4	0x9678	# <CJK>
0x97A5	0x5F8B	# <CJK>
0x97A6	0x7387	# <CJK>
0x97A7	0x7ACB	# <CJK>
0x97A8	0x844E	# <CJK>
0x97A9	0x63A0	# <CJK>
0x97AA	0x7565	# <CJK>
0x97AB	0x5289	# <CJK>
0x97AC	0x6D41	# <CJK>
0x97AD	0x6E9C	# <CJK>
0x97AE	0x7409	# <CJK>
0x97AF	0x7559	# <CJK>
0x97B0	0x786B	# <CJK>
0x97B1	0x7C92	# <CJK>
0x97B2	0x9686	# <CJK>
0x97B3	0x7ADC	# <CJK>
0x97B4	0x9F8D	# <CJK>
0x97B5	0x4FB6	# <CJK>
0x97B6	0x616E	# <CJK>
0x97B7	0x65C5	# <CJK>
0x97B8	0x865C	# <CJK>
0x97B9	0x4E86	# <CJK>
0x97BA	0x4EAE	# <CJK>
0x97BB	0x50DA	# <CJK>
0x97BC	0x4E21	# <CJK>
0x97BD	0x51CC	# <CJK>
0x97BE	0x5BEE	# <CJK>
0x97BF	0x6599	# <CJK>
0x97C0	0x6881	# <CJK>
0x97C1	0x6DBC	# <CJK>
0x97C2	0x731F	# <CJK>
0x97C3	0x7642	# <CJK>
0x97C4	0x77AD	# <CJK>
0x97C5	0x7A1C	# <CJK>
0x97C6	0x7CE7	# <CJK>
0x97C7	0x826F	# <CJK>
0x97C8	0x8AD2	# <CJK>
0x97C9	0x907C	# <CJK>
0x97CA	0x91CF	# <CJK>
0x97CB	0x9675	# <CJK>
0x97CC	0x9818	# <CJK>
0x97CD	0x529B	# <CJK>
0x97CE	0x7DD1	# <CJK>
0x97CF	0x502B	# <CJK>
0x97D0	0x5398	# <CJK>
0x97D1	0x6797	# <CJK>
0x97D2	0x6DCB	# <CJK>
0x97D3	0x71D0	# <CJK>
0x97D4	0x7433	# <CJK>
0x97D5	0x81E8	# <CJK>
0x97D6	0x8F2A	# <CJK>
0x97D7	0x96A3	# <CJK>
0x97D8	0x9C57	# <CJK>
0x97D9	0x9E9F	# <CJK>
0x97DA	0x7460	# <CJK>
0x97DB	0x5841	# <CJK>
0x97DC	0x6D99	# <CJK>
0x97DD	0x7D2F	# <CJK>
0x97DE	0x985E	# <CJK>
0x97DF	0x4EE4	# <CJK>
0x97E0	0x4F36	# <CJK>
0x97E1	0x4F8B	# <CJK>
0x97E2	0x51B7	# <CJK>
0x97E3	0x52B1	# <CJK>
0x97E4	0x5DBA	# <CJK>
0x97E5	0x601C	# <CJK>
0x97E6	0x73B2	# <CJK>
0x97E7	0x793C	# <CJK>
0x97E8	0x82D3	# <CJK>
0x97E9	0x9234	# <CJK>
0x97EA	0x96B7	# <CJK>
0x97EB	0x96F6	# <CJK>
0x97EC	0x970A	# <CJK>
0x97ED	0x9E97	# <CJK>
0x97EE	0x9F62	# <CJK>
0x97EF	0x66A6	# <CJK>
0x97F0	0x6B74	# <CJK>
0x97F1	0x5217	# <CJK>
0x97F2	0x52A3	# <CJK>
0x97F3	0x70C8	# <CJK>
0x97F4	0x88C2	# <CJK>
0x97F5	0x5EC9	# <CJK>
0x97F6	0x604B	# <CJK>
0x97F7	0x6190	# <CJK>
0x97F8	0x6F23	# <CJK>
0x97F9	0x7149	# <CJK>
0x97FA	0x7C3E	# <CJK>
0x97FB	0x7DF4	# <CJK>
0x97FC	0x806F	# <CJK>
0x9840	0x84EE	# <CJK>
0x9841	0x9023	# <CJK>
0x9842	0x932C	# <CJK>
0x9843	0x5442	# <CJK>
0x9844	0x9B6F	# <CJK>
0x9845	0x6AD3	# <CJK>
0x9846	0x7089	# <CJK>
0x9847	0x8CC2	# <CJK>
0x9848	0x8DEF	# <CJK>
0x9849	0x9732	# <CJK>
0x984A	0x52B4	# <CJK>
0x984B	0x5A41	# <CJK>
0x984C	0x5ECA	# <CJK>
0x984D	0x5F04	# <CJK>
0x984E	0x6717	# <CJK>
0x984F	0x697C	# <CJK>
0x9850	0x6994	# <CJK>
0x9851	0x6D6A	# <CJK>
0x9852	0x6F0F	# <CJK>
0x9853	0x7262	# <CJK>
0x9854	0x72FC	# <CJK>
0x9855	0x7BED	# <CJK>
0x9856	0x8001	# <CJK>
0x9857	0x807E	# <CJK>
0x9858	0x874B	# <CJK>
0x9859	0x90CE	# <CJK>
0x985A	0x516D	# <CJK>
0x985B	0x9E93	# <CJK>
0x985C	0x7984	# <CJK>
0x985D	0x808B	# <CJK>
0x985E	0x9332	# <CJK>
0x985F	0x8AD6	# <CJK>
0x9860	0x502D	# <CJK>
0x9861	0x548C	# <CJK>
0x9862	0x8A71	# <CJK>
0x9863	0x6B6A	# <CJK>
0x9864	0x8CC4	# <CJK>
0x9865	0x8107	# <CJK>
0x9866	0x60D1	# <CJK>
0x9867	0x67A0	# <CJK>
0x9868	0x9DF2	# <CJK>
0x9869	0x4E99	# <CJK>
0x986A	0x4E98	# <CJK>
0x986B	0x9C10	# <CJK>
0x986C	0x8A6B	# <CJK>
0x986D	0x85C1	# <CJK>
0x986E	0x8568	# <CJK>
0x986F	0x6900	# <CJK>
0x9870	0x6E7E	# <CJK>
0x9871	0x7897	# <CJK>
0x9872	0x8155	# <CJK>
0x989F	0x5F0C	# <CJK>
0x98A0	0x4E10	# <CJK>
0x98A1	0x4E15	# <CJK>
0x98A2	0x4E2A	# <CJK>
0x98A3	0x4E31	# <CJK>
0x98A4	0x4E36	# <CJK>
0x98A5	0x4E3C	# <CJK>
0x98A6	0x4E3F	# <CJK>
0x98A7	0x4E42	# <CJK>
0x98A8	0x4E56	# <CJK>
0x98A9	0x4E58	# <CJK>
0x98AA	0x4E82	# <CJK>
0x98AB	0x4E85	# <CJK>
0x98AC	0x8C6B	# <CJK>
0x98AD	0x4E8A	# <CJK>
0x98AE	0x8212	# <CJK>
0x98AF	0x5F0D	# <CJK>
0x98B0	0x4E8E	# <CJK>
0x98B1	0x4E9E	# <CJK>
0x98B2	0x4E9F	# <CJK>
0x98B3	0x4EA0	# <CJK>
0x98B4	0x4EA2	# <CJK>
0x98B5	0x4EB0	# <CJK>
0x98B6	0x4EB3	# <CJK>
0x98B7	0x4EB6	# <CJK>
0x98B8	0x4ECE	# <CJK>
0x98B9	0x4ECD	# <CJK>
0x98BA	0x4EC4	# <CJK>
0x98BB	0x4EC6	# <CJK>
0x98BC	0x4EC2	# <CJK>
0x98BD	0x4ED7	# <CJK>
0x98BE	0x4EDE	# <CJK>
0x98BF	0x4EED	# <CJK>
0x98C0	0x4EDF	# <CJK>
0x98C1	0x4EF7	# <CJK>
0x98C2	0x4F09	# <CJK>
0x98C3	0x4F5A	# <CJK>
0x98C4	0x4F30	# <CJK>
0x98C5	0x4F5B	# <CJK>
0x98C6	0x4F5D	# <CJK>
0x98C7	0x4F57	# <CJK>
0x98C8	0x4F47	# <CJK>
0x98C9	0x4F76	# <CJK>
0x98CA	0x4F88	# <CJK>
0x98CB	0x4F8F	# <CJK>
0x98CC	0x4F98	# <CJK>
0x98CD	0x4F7B	# <CJK>
0x98CE	0x4F69	# <CJK>
0x98CF	0x4F70	# <CJK>
0x98D0	0x4F91	# <CJK>
0x98D1	0x4F6F	# <CJK>
0x98D2	0x4F86	# <CJK>
0x98D3	0x4F96	# <CJK>
0x98D4	0x5118	# <CJK>
0x98D5	0x4FD4	# <CJK>
0x98D6	0x4FDF	# <CJK>
0x98D7	0x4FCE	# <CJK>
0x98D8	0x4FD8	# <CJK>
0x98D9	0x4FDB	# <CJK>
0x98DA	0x4FD1	# <CJK>
0x98DB	0x4FDA	# <CJK>
0x98DC	0x4FD0	# <CJK>
0x98DD	0x4FE4	# <CJK>
0x98DE	0x4FE5	# <CJK>
0x98DF	0x501A	# <CJK>
0x98E0	0x5028	# <CJK>
0x98E1	0x5014	# <CJK>
0x98E2	0x502A	# <CJK>
0x98E3	0x5025	# <CJK>
0x98E4	0x5005	# <CJK>
0x98E5	0x4F1C	# <CJK>
0x98E6	0x4FF6	# <CJK>
0x98E7	0x5021	# <CJK>
0x98E8	0x5029	# <CJK>
0x98E9	0x502C	# <CJK>
0x98EA	0x4FFE	# <CJK>
0x98EB	0x4FEF	# <CJK>
0x98EC	0x5011	# <CJK>
0x98ED	0x5006	# <CJK>
0x98EE	0x5043	# <CJK>
0x98EF	0x5047	# <CJK>
0x98F0	0x6703	# <CJK>
0x98F1	0x5055	# <CJK>
0x98F2	0x5050	# <CJK>
0x98F3	0x5048	# <CJK>
0x98F4	0x505A	# <CJK>
0x98F5	0x5056	# <CJK>
0x98F6	0x506C	# <CJK>
0x98F7	0x5078	# <CJK>
0x98F8	0x5080	# <CJK>
0x98F9	0x509A	# <CJK>
0x98FA	0x5085	# <CJK>
0x98FB	0x50B4	# <CJK>
0x98FC	0x50B2	# <CJK>
0x9940	0x50C9	# <CJK>
0x9941	0x50CA	# <CJK>
0x9942	0x50B3	# <CJK>
0x9943	0x50C2	# <CJK>
0x9944	0x50D6	# <CJK>
0x9945	0x50DE	# <CJK>
0x9946	0x50E5	# <CJK>
0x9947	0x50ED	# <CJK>
0x9948	0x50E3	# <CJK>
0x9949	0x50EE	# <CJK>
0x994A	0x50F9	# <CJK>
0x994B	0x50F5	# <CJK>
0x994C	0x5109	# <CJK>
0x994D	0x5101	# <CJK>
0x994E	0x5102	# <CJK>
0x994F	0x5116	# <CJK>
0x9950	0x5115	# <CJK>
0x9951	0x5114	# <CJK>
0x9952	0x511A	# <CJK>
0x9953	0x5121	# <CJK>
0x9954	0x513A	# <CJK>
0x9955	0x5137	# <CJK>
0x9956	0x513C	# <CJK>
0x9957	0x513B	# <CJK>
0x9958	0x513F	# <CJK>
0x9959	0x5140	# <CJK>
0x995A	0x5152	# <CJK>
0x995B	0x514C	# <CJK>
0x995C	0x5154	# <CJK>
0x995D	0x5162	# <CJK>
0x995E	0x7AF8	# <CJK>
0x995F	0x5169	# <CJK>
0x9960	0x516A	# <CJK>
0x9961	0x516E	# <CJK>
0x9962	0x5180	# <CJK>
0x9963	0x5182	# <CJK>
0x9964	0x56D8	# <CJK>
0x9965	0x518C	# <CJK>
0x9966	0x5189	# <CJK>
0x9967	0x518F	# <CJK>
0x9968	0x5191	# <CJK>
0x9969	0x5193	# <CJK>
0x996A	0x5195	# <CJK>
0x996B	0x5196	# <CJK>
0x996C	0x51A4	# <CJK>
0x996D	0x51A6	# <CJK>
0x996E	0x51A2	# <CJK>
0x996F	0x51A9	# <CJK>
0x9970	0x51AA	# <CJK>
0x9971	0x51AB	# <CJK>
0x9972	0x51B3	# <CJK>
0x9973	0x51B1	# <CJK>
0x9974	0x51B2	# <CJK>
0x9975	0x51B0	# <CJK>
0x9976	0x51B5	# <CJK>
0x9977	0x51BD	# <CJK>
0x9978	0x51C5	# <CJK>
0x9979	0x51C9	# <CJK>
0x997A	0x51DB	# <CJK>
0x997B	0x51E0	# <CJK>
0x997C	0x8655	# <CJK>
0x997D	0x51E9	# <CJK>
0x997E	0x51ED	# <CJK>
0x9980	0x51F0	# <CJK>
0x9981	0x51F5	# <CJK>
0x9982	0x51FE	# <CJK>
0x9983	0x5204	# <CJK>
0x9984	0x520B	# <CJK>
0x9985	0x5214	# <CJK>
0x9986	0x520E	# <CJK>
0x9987	0x5227	# <CJK>
0x9988	0x522A	# <CJK>
0x9989	0x522E	# <CJK>
0x998A	0x5233	# <CJK>
0x998B	0x5239	# <CJK>
0x998C	0x524F	# <CJK>
0x998D	0x5244	# <CJK>
0x998E	0x524B	# <CJK>
0x998F	0x524C	# <CJK>
0x9990	0x525E	# <CJK>
0x9991	0x5254	# <CJK>
0x9992	0x526A	# <CJK>
0x9993	0x5274	# <CJK>
0x9994	0x5269	# <CJK>
0x9995	0x5273	# <CJK>
0x9996	0x527F	# <CJK>
0x9997	0x527D	# <CJK>
0x9998	0x528D	# <CJK>
0x9999	0x5294	# <CJK>
0x999A	0x5292	# <CJK>
0x999B	0x5271	# <CJK>
0x999C	0x5288	# <CJK>
0x999D	0x5291	# <CJK>
0x999E	0x8FA8	# <CJK>
0x999F	0x8FA7	# <CJK>
0x99A0	0x52AC	# <CJK>
0x99A1	0x52AD	# <CJK>
0x99A2	0x52BC	# <CJK>
0x99A3	0x52B5	# <CJK>
0x99A4	0x52C1	# <CJK>
0x99A5	0x52CD	# <CJK>
0x99A6	0x52D7	# <CJK>
0x99A7	0x52DE	# <CJK>
0x99A8	0x52E3	# <CJK>
0x99A9	0x52E6	# <CJK>
0x99AA	0x98ED	# <CJK>
0x99AB	0x52E0	# <CJK>
0x99AC	0x52F3	# <CJK>
0x99AD	0x52F5	# <CJK>
0x99AE	0x52F8	# <CJK>
0x99AF	0x52F9	# <CJK>
0x99B0	0x5306	# <CJK>
0x99B1	0x5308	# <CJK>
0x99B2	0x7538	# <CJK>
0x99B3	0x530D	# <CJK>
0x99B4	0x5310	# <CJK>
0x99B5	0x530F	# <CJK>
0x99B6	0x5315	# <CJK>
0x99B7	0x531A	# <CJK>
0x99B8	0x5323	# <CJK>
0x99B9	0x532F	# <CJK>
0x99BA	0x5331	# <CJK>
0x99BB	0x5333	# <CJK>
0x99BC	0x5338	# <CJK>
0x99BD	0x5340	# <CJK>
0x99BE	0x5346	# <CJK>
0x99BF	0x5345	# <CJK>
0x99C0	0x4E17	# <CJK>
0x99C1	0x5349	# <CJK>
0x99C2	0x534D	# <CJK>
0x99C3	0x51D6	# <CJK>
0x99C4	0x535E	# <CJK>
0x99C5	0x5369	# <CJK>
0x99C6	0x536E	# <CJK>
0x99C7	0x5918	# <CJK>
0x99C8	0x537B	# <CJK>
0x99C9	0x5377	# <CJK>
0x99CA	0x5382	# <CJK>
0x99CB	0x5396	# <CJK>
0x99CC	0x53A0	# <CJK>
0x99CD	0x53A6	# <CJK>
0x99CE	0x53A5	# <CJK>
0x99CF	0x53AE	# <CJK>
0x99D0	0x53B0	# <CJK>
0x99D1	0x53B6	# <CJK>
0x99D2	0x53C3	# <CJK>
0x99D3	0x7C12	# <CJK>
0x99D4	0x96D9	# <CJK>
0x99D5	0x53DF	# <CJK>
0x99D6	0x66FC	# <CJK>
0x99D7	0x71EE	# <CJK>
0x99D8	0x53EE	# <CJK>
0x99D9	0x53E8	# <CJK>
0x99DA	0x53ED	# <CJK>
0x99DB	0x53FA	# <CJK>
0x99DC	0x5401	# <CJK>
0x99DD	0x543D	# <CJK>
0x99DE	0x5440	# <CJK>
0x99DF	0x542C	# <CJK>
0x99E0	0x542D	# <CJK>
0x99E1	0x543C	# <CJK>
0x99E2	0x542E	# <CJK>
0x99E3	0x5436	# <CJK>
0x99E4	0x5429	# <CJK>
0x99E5	0x541D	# <CJK>
0x99E6	0x544E	# <CJK>
0x99E7	0x548F	# <CJK>
0x99E8	0x5475	# <CJK>
0x99E9	0x548E	# <CJK>
0x99EA	0x545F	# <CJK>
0x99EB	0x5471	# <CJK>
0x99EC	0x5477	# <CJK>
0x99ED	0x5470	# <CJK>
0x99EE	0x5492	# <CJK>
0x99EF	0x547B	# <CJK>
0x99F0	0x5480	# <CJK>
0x99F1	0x5476	# <CJK>
0x99F2	0x5484	# <CJK>
0x99F3	0x5490	# <CJK>
0x99F4	0x5486	# <CJK>
0x99F5	0x54C7	# <CJK>
0x99F6	0x54A2	# <CJK>
0x99F7	0x54B8	# <CJK>
0x99F8	0x54A5	# <CJK>
0x99F9	0x54AC	# <CJK>
0x99FA	0x54C4	# <CJK>
0x99FB	0x54C8	# <CJK>
0x99FC	0x54A8	# <CJK>
0x9A40	0x54AB	# <CJK>
0x9A41	0x54C2	# <CJK>
0x9A42	0x54A4	# <CJK>
0x9A43	0x54BE	# <CJK>
0x9A44	0x54BC	# <CJK>
0x9A45	0x54D8	# <CJK>
0x9A46	0x54E5	# <CJK>
0x9A47	0x54E6	# <CJK>
0x9A48	0x550F	# <CJK>
0x9A49	0x5514	# <CJK>
0x9A4A	0x54FD	# <CJK>
0x9A4B	0x54EE	# <CJK>
0x9A4C	0x54ED	# <CJK>
0x9A4D	0x54FA	# <CJK>
0x9A4E	0x54E2	# <CJK>
0x9A4F	0x5539	# <CJK>
0x9A50	0x5540	# <CJK>
0x9A51	0x5563	# <CJK>
0x9A52	0x554C	# <CJK>
0x9A53	0x552E	# <CJK>
0x9A54	0x555C	# <CJK>
0x9A55	0x5545	# <CJK>
0x9A56	0x5556	# <CJK>
0x9A57	0x5557	# <CJK>
0x9A58	0x5538	# <CJK>
0x9A59	0x5533	# <CJK>
0x9A5A	0x555D	# <CJK>
0x9A5B	0x5599	# <CJK>
0x9A5C	0x5580	# <CJK>
0x9A5D	0x54AF	# <CJK>
0x9A5E	0x558A	# <CJK>
0x9A5F	0x559F	# <CJK>
0x9A60	0x557B	# <CJK>
0x9A61	0x557E	# <CJK>
0x9A62	0x5598	# <CJK>
0x9A63	0x559E	# <CJK>
0x9A64	0x55AE	# <CJK>
0x9A65	0x557C	# <CJK>
0x9A66	0x5583	# <CJK>
0x9A67	0x55A9	# <CJK>
0x9A68	0x5587	# <CJK>
0x9A69	0x55A8	# <CJK>
0x9A6A	0x55DA	# <CJK>
0x9A6B	0x55C5	# <CJK>
0x9A6C	0x55DF	# <CJK>
0x9A6D	0x55C4	# <CJK>
0x9A6E	0x55DC	# <CJK>
0x9A6F	0x55E4	# <CJK>
0x9A70	0x55D4	# <CJK>
0x9A71	0x5614	# <CJK>
0x9A72	0x55F7	# <CJK>
0x9A73	0x5616	# <CJK>
0x9A74	0x55FE	# <CJK>
0x9A75	0x55FD	# <CJK>
0x9A76	0x561B	# <CJK>
0x9A77	0x55F9	# <CJK>
0x9A78	0x564E	# <CJK>
0x9A79	0x5650	# <CJK>
0x9A7A	0x71DF	# <CJK>
0x9A7B	0x5634	# <CJK>
0x9A7C	0x5636	# <CJK>
0x9A7D	0x5632	# <CJK>
0x9A7E	0x5638	# <CJK>
0x9A80	0x566B	# <CJK>
0x9A81	0x5664	# <CJK>
0x9A82	0x562F	# <CJK>
0x9A83	0x566C	# <CJK>
0x9A84	0x566A	# <CJK>
0x9A85	0x5686	# <CJK>
0x9A86	0x5680	# <CJK>
0x9A87	0x568A	# <CJK>
0x9A88	0x56A0	# <CJK>
0x9A89	0x5694	# <CJK>
0x9A8A	0x568F	# <CJK>
0x9A8B	0x56A5	# <CJK>
0x9A8C	0x56AE	# <CJK>
0x9A8D	0x56B6	# <CJK>
0x9A8E	0x56B4	# <CJK>
0x9A8F	0x56C2	# <CJK>
0x9A90	0x56BC	# <CJK>
0x9A91	0x56C1	# <CJK>
0x9A92	0x56C3	# <CJK>
0x9A93	0x56C0	# <CJK>
0x9A94	0x56C8	# <CJK>
0x9A95	0x56CE	# <CJK>
0x9A96	0x56D1	# <CJK>
0x9A97	0x56D3	# <CJK>
0x9A98	0x56D7	# <CJK>
0x9A99	0x56EE	# <CJK>
0x9A9A	0x56F9	# <CJK>
0x9A9B	0x5700	# <CJK>
0x9A9C	0x56FF	# <CJK>
0x9A9D	0x5704	# <CJK>
0x9A9E	0x5709	# <CJK>
0x9A9F	0x5708	# <CJK>
0x9AA0	0x570B	# <CJK>
0x9AA1	0x570D	# <CJK>
0x9AA2	0x5713	# <CJK>
0x9AA3	0x5718	# <CJK>
0x9AA4	0x5716	# <CJK>
0x9AA5	0x55C7	# <CJK>
0x9AA6	0x571C	# <CJK>
0x9AA7	0x5726	# <CJK>
0x9AA8	0x5737	# <CJK>
0x9AA9	0x5738	# <CJK>
0x9AAA	0x574E	# <CJK>
0x9AAB	0x573B	# <CJK>
0x9AAC	0x5740	# <CJK>
0x9AAD	0x574F	# <CJK>
0x9AAE	0x5769	# <CJK>
0x9AAF	0x57C0	# <CJK>
0x9AB0	0x5788	# <CJK>
0x9AB1	0x5761	# <CJK>
0x9AB2	0x577F	# <CJK>
0x9AB3	0x5789	# <CJK>
0x9AB4	0x5793	# <CJK>
0x9AB5	0x57A0	# <CJK>
0x9AB6	0x57B3	# <CJK>
0x9AB7	0x57A4	# <CJK>
0x9AB8	0x57AA	# <CJK>
0x9AB9	0x57B0	# <CJK>
0x9ABA	0x57C3	# <CJK>
0x9ABB	0x57C6	# <CJK>
0x9ABC	0x57D4	# <CJK>
0x9ABD	0x57D2	# <CJK>
0x9ABE	0x57D3	# <CJK>
0x9ABF	0x580A	# <CJK>
0x9AC0	0x57D6	# <CJK>
0x9AC1	0x57E3	# <CJK>
0x9AC2	0x580B	# <CJK>
0x9AC3	0x5819	# <CJK>
0x9AC4	0x581D	# <CJK>
0x9AC5	0x5872	# <CJK>
0x9AC6	0x5821	# <CJK>
0x9AC7	0x5862	# <CJK>
0x9AC8	0x584B	# <CJK>
0x9AC9	0x5870	# <CJK>
0x9ACA	0x6BC0	# <CJK>
0x9ACB	0x5852	# <CJK>
0x9ACC	0x583D	# <CJK>
0x9ACD	0x5879	# <CJK>
0x9ACE	0x5885	# <CJK>
0x9ACF	0x58B9	# <CJK>
0x9AD0	0x589F	# <CJK>
0x9AD1	0x58AB	# <CJK>
0x9AD2	0x58BA	# <CJK>
0x9AD3	0x58DE	# <CJK>
0x9AD4	0x58BB	# <CJK>
0x9AD5	0x58B8	# <CJK>
0x9AD6	0x58AE	# <CJK>
0x9AD7	0x58C5	# <CJK>
0x9AD8	0x58D3	# <CJK>
0x9AD9	0x58D1	# <CJK>
0x9ADA	0x58D7	# <CJK>
0x9ADB	0x58D9	# <CJK>
0x9ADC	0x58D8	# <CJK>
0x9ADD	0x58E5	# <CJK>
0x9ADE	0x58DC	# <CJK>
0x9ADF	0x58E4	# <CJK>
0x9AE0	0x58DF	# <CJK>
0x9AE1	0x58EF	# <CJK>
0x9AE2	0x58FA	# <CJK>
0x9AE3	0x58F9	# <CJK>
0x9AE4	0x58FB	# <CJK>
0x9AE5	0x58FC	# <CJK>
0x9AE6	0x58FD	# <CJK>
0x9AE7	0x5902	# <CJK>
0x9AE8	0x590A	# <CJK>
0x9AE9	0x5910	# <CJK>
0x9AEA	0x591B	# <CJK>
0x9AEB	0x68A6	# <CJK>
0x9AEC	0x5925	# <CJK>
0x9AED	0x592C	# <CJK>
0x9AEE	0x592D	# <CJK>
0x9AEF	0x5932	# <CJK>
0x9AF0	0x5938	# <CJK>
0x9AF1	0x593E	# <CJK>
0x9AF2	0x7AD2	# <CJK>
0x9AF3	0x5955	# <CJK>
0x9AF4	0x5950	# <CJK>
0x9AF5	0x594E	# <CJK>
0x9AF6	0x595A	# <CJK>
0x9AF7	0x5958	# <CJK>
0x9AF8	0x5962	# <CJK>
0x9AF9	0x5960	# <CJK>
0x9AFA	0x5967	# <CJK>
0x9AFB	0x596C	# <CJK>
0x9AFC	0x5969	# <CJK>
0x9B40	0x5978	# <CJK>
0x9B41	0x5981	# <CJK>
0x9B42	0x599D	# <CJK>
0x9B43	0x4F5E	# <CJK>
0x9B44	0x4FAB	# <CJK>
0x9B45	0x59A3	# <CJK>
0x9B46	0x59B2	# <CJK>
0x9B47	0x59C6	# <CJK>
0x9B48	0x59E8	# <CJK>
0x9B49	0x59DC	# <CJK>
0x9B4A	0x598D	# <CJK>
0x9B4B	0x59D9	# <CJK>
0x9B4C	0x59DA	# <CJK>
0x9B4D	0x5A25	# <CJK>
0x9B4E	0x5A1F	# <CJK>
0x9B4F	0x5A11	# <CJK>
0x9B50	0x5A1C	# <CJK>
0x9B51	0x5A09	# <CJK>
0x9B52	0x5A1A	# <CJK>
0x9B53	0x5A40	# <CJK>
0x9B54	0x5A6C	# <CJK>
0x9B55	0x5A49	# <CJK>
0x9B56	0x5A35	# <CJK>
0x9B57	0x5A36	# <CJK>
0x9B58	0x5A62	# <CJK>
0x9B59	0x5A6A	# <CJK>
0x9B5A	0x5A9A	# <CJK>
0x9B5B	0x5ABC	# <CJK>
0x9B5C	0x5ABE	# <CJK>
0x9B5D	0x5ACB	# <CJK>
0x9B5E	0x5AC2	# <CJK>
0x9B5F	0x5ABD	# <CJK>
0x9B60	0x5AE3	# <CJK>
0x9B61	0x5AD7	# <CJK>
0x9B62	0x5AE6	# <CJK>
0x9B63	0x5AE9	# <CJK>
0x9B64	0x5AD6	# <CJK>
0x9B65	0x5AFA	# <CJK>
0x9B66	0x5AFB	# <CJK>
0x9B67	0x5B0C	# <CJK>
0x9B68	0x5B0B	# <CJK>
0x9B69	0x5B16	# <CJK>
0x9B6A	0x5B32	# <CJK>
0x9B6B	0x5AD0	# <CJK>
0x9B6C	0x5B2A	# <CJK>
0x9B6D	0x5B36	# <CJK>
0x9B6E	0x5B3E	# <CJK>
0x9B6F	0x5B43	# <CJK>
0x9B70	0x5B45	# <CJK>
0x9B71	0x5B40	# <CJK>
0x9B72	0x5B51	# <CJK>
0x9B73	0x5B55	# <CJK>
0x9B74	0x5B5A	# <CJK>
0x9B75	0x5B5B	# <CJK>
0x9B76	0x5B65	# <CJK>
0x9B77	0x5B69	# <CJK>
0x9B78	0x5B70	# <CJK>
0x9B79	0x5B73	# <CJK>
0x9B7A	0x5B75	# <CJK>
0x9B7B	0x5B78	# <CJK>
0x9B7C	0x6588	# <CJK>
0x9B7D	0x5B7A	# <CJK>
0x9B7E	0x5B80	# <CJK>
0x9B80	0x5B83	# <CJK>
0x9B81	0x5BA6	# <CJK>
0x9B82	0x5BB8	# <CJK>
0x9B83	0x5BC3	# <CJK>
0x9B84	0x5BC7	# <CJK>
0x9B85	0x5BC9	# <CJK>
0x9B86	0x5BD4	# <CJK>
0x9B87	0x5BD0	# <CJK>
0x9B88	0x5BE4	# <CJK>
0x9B89	0x5BE6	# <CJK>
0x9B8A	0x5BE2	# <CJK>
0x9B8B	0x5BDE	# <CJK>
0x9B8C	0x5BE5	# <CJK>
0x9B8D	0x5BEB	# <CJK>
0x9B8E	0x5BF0	# <CJK>
0x9B8F	0x5BF6	# <CJK>
0x9B90	0x5BF3	# <CJK>
0x9B91	0x5C05	# <CJK>
0x9B92	0x5C07	# <CJK>
0x9B93	0x5C08	# <CJK>
0x9B94	0x5C0D	# <CJK>
0x9B95	0x5C13	# <CJK>
0x9B96	0x5C20	# <CJK>
0x9B97	0x5C22	# <CJK>
0x9B98	0x5C28	# <CJK>
0x9B99	0x5C38	# <CJK>
0x9B9A	0x5C39	# <CJK>
0x9B9B	0x5C41	# <CJK>
0x9B9C	0x5C46	# <CJK>
0x9B9D	0x5C4E	# <CJK>
0x9B9E	0x5C53	# <CJK>
0x9B9F	0x5C50	# <CJK>
0x9BA0	0x5C4F	# <CJK>
0x9BA1	0x5B71	# <CJK>
0x9BA2	0x5C6C	# <CJK>
0x9BA3	0x5C6E	# <CJK>
0x9BA4	0x4E62	# <CJK>
0x9BA5	0x5C76	# <CJK>
0x9BA6	0x5C79	# <CJK>
0x9BA7	0x5C8C	# <CJK>
0x9BA8	0x5C91	# <CJK>
0x9BA9	0x5C94	# <CJK>
0x9BAA	0x599B	# <CJK>
0x9BAB	0x5CAB	# <CJK>
0x9BAC	0x5CBB	# <CJK>
0x9BAD	0x5CB6	# <CJK>
0x9BAE	0x5CBC	# <CJK>
0x9BAF	0x5CB7	# <CJK>
0x9BB0	0x5CC5	# <CJK>
0x9BB1	0x5CBE	# <CJK>
0x9BB2	0x5CC7	# <CJK>
0x9BB3	0x5CD9	# <CJK>
0x9BB4	0x5CE9	# <CJK>
0x9BB5	0x5CFD	# <CJK>
0x9BB6	0x5CFA	# <CJK>
0x9BB7	0x5CED	# <CJK>
0x9BB8	0x5D8C	# <CJK>
0x9BB9	0x5CEA	# <CJK>
0x9BBA	0x5D0B	# <CJK>
0x9BBB	0x5D15	# <CJK>
0x9BBC	0x5D17	# <CJK>
0x9BBD	0x5D5C	# <CJK>
0x9BBE	0x5D1F	# <CJK>
0x9BBF	0x5D1B	# <CJK>
0x9BC0	0x5D11	# <CJK>
0x9BC1	0x5D14	# <CJK>
0x9BC2	0x5D22	# <CJK>
0x9BC3	0x5D1A	# <CJK>
0x9BC4	0x5D19	# <CJK>
0x9BC5	0x5D18	# <CJK>
0x9BC6	0x5D4C	# <CJK>
0x9BC7	0x5D52	# <CJK>
0x9BC8	0x5D4E	# <CJK>
0x9BC9	0x5D4B	# <CJK>
0x9BCA	0x5D6C	# <CJK>
0x9BCB	0x5D73	# <CJK>
0x9BCC	0x5D76	# <CJK>
0x9BCD	0x5D87	# <CJK>
0x9BCE	0x5D84	# <CJK>
0x9BCF	0x5D82	# <CJK>
0x9BD0	0x5DA2	# <CJK>
0x9BD1	0x5D9D	# <CJK>
0x9BD2	0x5DAC	# <CJK>
0x9BD3	0x5DAE	# <CJK>
0x9BD4	0x5DBD	# <CJK>
0x9BD5	0x5D90	# <CJK>
0x9BD6	0x5DB7	# <CJK>
0x9BD7	0x5DBC	# <CJK>
0x9BD8	0x5DC9	# <CJK>
0x9BD9	0x5DCD	# <CJK>
0x9BDA	0x5DD3	# <CJK>
0x9BDB	0x5DD2	# <CJK>
0x9BDC	0x5DD6	# <CJK>
0x9BDD	0x5DDB	# <CJK>
0x9BDE	0x5DEB	# <CJK>
0x9BDF	0x5DF2	# <CJK>
0x9BE0	0x5DF5	# <CJK>
0x9BE1	0x5E0B	# <CJK>
0x9BE2	0x5E1A	# <CJK>
0x9BE3	0x5E19	# <CJK>
0x9BE4	0x5E11	# <CJK>
0x9BE5	0x5E1B	# <CJK>
0x9BE6	0x5E36	# <CJK>
0x9BE7	0x5E37	# <CJK>
0x9BE8	0x5E44	# <CJK>
0x9BE9	0x5E43	# <CJK>
0x9BEA	0x5E40	# <CJK>
0x9BEB	0x5E4E	# <CJK>
0x9BEC	0x5E57	# <CJK>
0x9BED	0x5E54	# <CJK>
0x9BEE	0x5E5F	# <CJK>
0x9BEF	0x5E62	# <CJK>
0x9BF0	0x5E64	# <CJK>
0x9BF1	0x5E47	# <CJK>
0x9BF2	0x5E75	# <CJK>
0x9BF3	0x5E76	# <CJK>
0x9BF4	0x5E7A	# <CJK>
0x9BF5	0x9EBC	# <CJK>
0x9BF6	0x5E7F	# <CJK>
0x9BF7	0x5EA0	# <CJK>
0x9BF8	0x5EC1	# <CJK>
0x9BF9	0x5EC2	# <CJK>
0x9BFA	0x5EC8	# <CJK>
0x9BFB	0x5ED0	# <CJK>
0x9BFC	0x5ECF	# <CJK>
0x9C40	0x5ED6	# <CJK>
0x9C41	0x5EE3	# <CJK>
0x9C42	0x5EDD	# <CJK>
0x9C43	0x5EDA	# <CJK>
0x9C44	0x5EDB	# <CJK>
0x9C45	0x5EE2	# <CJK>
0x9C46	0x5EE1	# <CJK>
0x9C47	0x5EE8	# <CJK>
0x9C48	0x5EE9	# <CJK>
0x9C49	0x5EEC	# <CJK>
0x9C4A	0x5EF1	# <CJK>
0x9C4B	0x5EF3	# <CJK>
0x9C4C	0x5EF0	# <CJK>
0x9C4D	0x5EF4	# <CJK>
0x9C4E	0x5EF8	# <CJK>
0x9C4F	0x5EFE	# <CJK>
0x9C50	0x5F03	# <CJK>
0x9C51	0x5F09	# <CJK>
0x9C52	0x5F5D	# <CJK>
0x9C53	0x5F5C	# <CJK>
0x9C54	0x5F0B	# <CJK>
0x9C55	0x5F11	# <CJK>
0x9C56	0x5F16	# <CJK>
0x9C57	0x5F29	# <CJK>
0x9C58	0x5F2D	# <CJK>
0x9C59	0x5F38	# <CJK>
0x9C5A	0x5F41	# <CJK>
0x9C5B	0x5F48	# <CJK>
0x9C5C	0x5F4C	# <CJK>
0x9C5D	0x5F4E	# <CJK>
0x9C5E	0x5F2F	# <CJK>
0x9C5F	0x5F51	# <CJK>
0x9C60	0x5F56	# <CJK>
0x9C61	0x5F57	# <CJK>
0x9C62	0x5F59	# <CJK>
0x9C63	0x5F61	# <CJK>
0x9C64	0x5F6D	# <CJK>
0x9C65	0x5F73	# <CJK>
0x9C66	0x5F77	# <CJK>
0x9C67	0x5F83	# <CJK>
0x9C68	0x5F82	# <CJK>
0x9C69	0x5F7F	# <CJK>
0x9C6A	0x5F8A	# <CJK>
0x9C6B	0x5F88	# <CJK>
0x9C6C	0x5F91	# <CJK>
0x9C6D	0x5F87	# <CJK>
0x9C6E	0x5F9E	# <CJK>
0x9C6F	0x5F99	# <CJK>
0x9C70	0x5F98	# <CJK>
0x9C71	0x5FA0	# <CJK>
0x9C72	0x5FA8	# <CJK>
0x9C73	0x5FAD	# <CJK>
0x9C74	0x5FBC	# <CJK>
0x9C75	0x5FD6	# <CJK>
0x9C76	0x5FFB	# <CJK>
0x9C77	0x5FE4	# <CJK>
0x9C78	0x5FF8	# <CJK>
0x9C79	0x5FF1	# <CJK>
0x9C7A	0x5FDD	# <CJK>
0x9C7B	0x60B3	# <CJK>
0x9C7C	0x5FFF	# <CJK>
0x9C7D	0x6021	# <CJK>
0x9C7E	0x6060	# <CJK>
0x9C80	0x6019	# <CJK>
0x9C81	0x6010	# <CJK>
0x9C82	0x6029	# <CJK>
0x9C83	0x600E	# <CJK>
0x9C84	0x6031	# <CJK>
0x9C85	0x601B	# <CJK>
0x9C86	0x6015	# <CJK>
0x9C87	0x602B	# <CJK>
0x9C88	0x6026	# <CJK>
0x9C89	0x600F	# <CJK>
0x9C8A	0x603A	# <CJK>
0x9C8B	0x605A	# <CJK>
0x9C8C	0x6041	# <CJK>
0x9C8D	0x606A	# <CJK>
0x9C8E	0x6077	# <CJK>
0x9C8F	0x605F	# <CJK>
0x9C90	0x604A	# <CJK>
0x9C91	0x6046	# <CJK>
0x9C92	0x604D	# <CJK>
0x9C93	0x6063	# <CJK>
0x9C94	0x6043	# <CJK>
0x9C95	0x6064	# <CJK>
0x9C96	0x6042	# <CJK>
0x9C97	0x606C	# <CJK>
0x9C98	0x606B	# <CJK>
0x9C99	0x6059	# <CJK>
0x9C9A	0x6081	# <CJK>
0x9C9B	0x608D	# <CJK>
0x9C9C	0x60E7	# <CJK>
0x9C9D	0x6083	# <CJK>
0x9C9E	0x609A	# <CJK>
0x9C9F	0x6084	# <CJK>
0x9CA0	0x609B	# <CJK>
0x9CA1	0x6096	# <CJK>
0x9CA2	0x6097	# <CJK>
0x9CA3	0x6092	# <CJK>
0x9CA4	0x60A7	# <CJK>
0x9CA5	0x608B	# <CJK>
0x9CA6	0x60E1	# <CJK>
0x9CA7	0x60B8	# <CJK>
0x9CA8	0x60E0	# <CJK>
0x9CA9	0x60D3	# <CJK>
0x9CAA	0x60B4	# <CJK>
0x9CAB	0x5FF0	# <CJK>
0x9CAC	0x60BD	# <CJK>
0x9CAD	0x60C6	# <CJK>
0x9CAE	0x60B5	# <CJK>
0x9CAF	0x60D8	# <CJK>
0x9CB0	0x614D	# <CJK>
0x9CB1	0x6115	# <CJK>
0x9CB2	0x6106	# <CJK>
0x9CB3	0x60F6	# <CJK>
0x9CB4	0x60F7	# <CJK>
0x9CB5	0x6100	# <CJK>
0x9CB6	0x60F4	# <CJK>
0x9CB7	0x60FA	# <CJK>
0x9CB8	0x6103	# <CJK>
0x9CB9	0x6121	# <CJK>
0x9CBA	0x60FB	# <CJK>
0x9CBB	0x60F1	# <CJK>
0x9CBC	0x610D	# <CJK>
0x9CBD	0x610E	# <CJK>
0x9CBE	0x6147	# <CJK>
0x9CBF	0x613E	# <CJK>
0x9CC0	0x6128	# <CJK>
0x9CC1	0x6127	# <CJK>
0x9CC2	0x614A	# <CJK>
0x9CC3	0x613F	# <CJK>
0x9CC4	0x613C	# <CJK>
0x9CC5	0x612C	# <CJK>
0x9CC6	0x6134	# <CJK>
0x9CC7	0x613D	# <CJK>
0x9CC8	0x6142	# <CJK>
0x9CC9	0x6144	# <CJK>
0x9CCA	0x6173	# <CJK>
0x9CCB	0x6177	# <CJK>
0x9CCC	0x6158	# <CJK>
0x9CCD	0x6159	# <CJK>
0x9CCE	0x615A	# <CJK>
0x9CCF	0x616B	# <CJK>
0x9CD0	0x6174	# <CJK>
0x9CD1	0x616F	# <CJK>
0x9CD2	0x6165	# <CJK>
0x9CD3	0x6171	# <CJK>
0x9CD4	0x615F	# <CJK>
0x9CD5	0x615D	# <CJK>
0x9CD6	0x6153	# <CJK>
0x9CD7	0x6175	# <CJK>
0x9CD8	0x6199	# <CJK>
0x9CD9	0x6196	# <CJK>
0x9CDA	0x6187	# <CJK>
0x9CDB	0x61AC	# <CJK>
0x9CDC	0x6194	# <CJK>
0x9CDD	0x619A	# <CJK>
0x9CDE	0x618A	# <CJK>
0x9CDF	0x6191	# <CJK>
0x9CE0	0x61AB	# <CJK>
0x9CE1	0x61AE	# <CJK>
0x9CE2	0x61CC	# <CJK>
0x9CE3	0x61CA	# <CJK>
0x9CE4	0x61C9	# <CJK>
0x9CE5	0x61F7	# <CJK>
0x9CE6	0x61C8	# <CJK>
0x9CE7	0x61C3	# <CJK>
0x9CE8	0x61C6	# <CJK>
0x9CE9	0x61BA	# <CJK>
0x9CEA	0x61CB	# <CJK>
0x9CEB	0x7F79	# <CJK>
0x9CEC	0x61CD	# <CJK>
0x9CED	0x61E6	# <CJK>
0x9CEE	0x61E3	# <CJK>
0x9CEF	0x61F6	# <CJK>
0x9CF0	0x61FA	# <CJK>
0x9CF1	0x61F4	# <CJK>
0x9CF2	0x61FF	# <CJK>
0x9CF3	0x61FD	# <CJK>
0x9CF4	0x61FC	# <CJK>
0x9CF5	0x61FE	# <CJK>
0x9CF6	0x6200	# <CJK>
0x9CF7	0x6208	# <CJK>
0x9CF8	0x6209	# <CJK>
0x9CF9	0x620D	# <CJK>
0x9CFA	0x620C	# <CJK>
0x9CFB	0x6214	# <CJK>
0x9CFC	0x621B	# <CJK>
0x9D40	0x621E	# <CJK>
0x9D41	0x6221	# <CJK>
0x9D42	0x622A	# <CJK>
0x9D43	0x622E	# <CJK>
0x9D44	0x6230	# <CJK>
0x9D45	0x6232	# <CJK>
0x9D46	0x6233	# <CJK>
0x9D47	0x6241	# <CJK>
0x9D48	0x624E	# <CJK>
0x9D49	0x625E	# <CJK>
0x9D4A	0x6263	# <CJK>
0x9D4B	0x625B	# <CJK>
0x9D4C	0x6260	# <CJK>
0x9D4D	0x6268	# <CJK>
0x9D4E	0x627C	# <CJK>
0x9D4F	0x6282	# <CJK>
0x9D50	0x6289	# <CJK>
0x9D51	0x627E	# <CJK>
0x9D52	0x6292	# <CJK>
0x9D53	0x6293	# <CJK>
0x9D54	0x6296	# <CJK>
0x9D55	0x62D4	# <CJK>
0x9D56	0x6283	# <CJK>
0x9D57	0x6294	# <CJK>
0x9D58	0x62D7	# <CJK>
0x9D59	0x62D1	# <CJK>
0x9D5A	0x62BB	# <CJK>
0x9D5B	0x62CF	# <CJK>
0x9D5C	0x62FF	# <CJK>
0x9D5D	0x62C6	# <CJK>
0x9D5E	0x64D4	# <CJK>
0x9D5F	0x62C8	# <CJK>
0x9D60	0x62DC	# <CJK>
0x9D61	0x62CC	# <CJK>
0x9D62	0x62CA	# <CJK>
0x9D63	0x62C2	# <CJK>
0x9D64	0x62C7	# <CJK>
0x9D65	0x629B	# <CJK>
0x9D66	0x62C9	# <CJK>
0x9D67	0x630C	# <CJK>
0x9D68	0x62EE	# <CJK>
0x9D69	0x62F1	# <CJK>
0x9D6A	0x6327	# <CJK>
0x9D6B	0x6302	# <CJK>
0x9D6C	0x6308	# <CJK>
0x9D6D	0x62EF	# <CJK>
0x9D6E	0x62F5	# <CJK>
0x9D6F	0x6350	# <CJK>
0x9D70	0x633E	# <CJK>
0x9D71	0x634D	# <CJK>
0x9D72	0x641C	# <CJK>
0x9D73	0x634F	# <CJK>
0x9D74	0x6396	# <CJK>
0x9D75	0x638E	# <CJK>
0x9D76	0x6380	# <CJK>
0x9D77	0x63AB	# <CJK>
0x9D78	0x6376	# <CJK>
0x9D79	0x63A3	# <CJK>
0x9D7A	0x638F	# <CJK>
0x9D7B	0x6389	# <CJK>
0x9D7C	0x639F	# <CJK>
0x9D7D	0x63B5	# <CJK>
0x9D7E	0x636B	# <CJK>
0x9D80	0x6369	# <CJK>
0x9D81	0x63BE	# <CJK>
0x9D82	0x63E9	# <CJK>
0x9D83	0x63C0	# <CJK>
0x9D84	0x63C6	# <CJK>
0x9D85	0x63E3	# <CJK>
0x9D86	0x63C9	# <CJK>
0x9D87	0x63D2	# <CJK>
0x9D88	0x63F6	# <CJK>
0x9D89	0x63C4	# <CJK>
0x9D8A	0x6416	# <CJK>
0x9D8B	0x6434	# <CJK>
0x9D8C	0x6406	# <CJK>
0x9D8D	0x6413	# <CJK>
0x9D8E	0x6426	# <CJK>
0x9D8F	0x6436	# <CJK>
0x9D90	0x651D	# <CJK>
0x9D91	0x6417	# <CJK>
0x9D92	0x6428	# <CJK>
0x9D93	0x640F	# <CJK>
0x9D94	0x6467	# <CJK>
0x9D95	0x646F	# <CJK>
0x9D96	0x6476	# <CJK>
0x9D97	0x644E	# <CJK>
0x9D98	0x652A	# <CJK>
0x9D99	0x6495	# <CJK>
0x9D9A	0x6493	# <CJK>
0x9D9B	0x64A5	# <CJK>
0x9D9C	0x64A9	# <CJK>
0x9D9D	0x6488	# <CJK>
0x9D9E	0x64BC	# <CJK>
0x9D9F	0x64DA	# <CJK>
0x9DA0	0x64D2	# <CJK>
0x9DA1	0x64C5	# <CJK>
0x9DA2	0x64C7	# <CJK>
0x9DA3	0x64BB	# <CJK>
0x9DA4	0x64D8	# <CJK>
0x9DA5	0x64C2	# <CJK>
0x9DA6	0x64F1	# <CJK>
0x9DA7	0x64E7	# <CJK>
0x9DA8	0x8209	# <CJK>
0x9DA9	0x64E0	# <CJK>
0x9DAA	0x64E1	# <CJK>
0x9DAB	0x62AC	# <CJK>
0x9DAC	0x64E3	# <CJK>
0x9DAD	0x64EF	# <CJK>
0x9DAE	0x652C	# <CJK>
0x9DAF	0x64F6	# <CJK>
0x9DB0	0x64F4	# <CJK>
0x9DB1	0x64F2	# <CJK>
0x9DB2	0x64FA	# <CJK>
0x9DB3	0x6500	# <CJK>
0x9DB4	0x64FD	# <CJK>
0x9DB5	0x6518	# <CJK>
0x9DB6	0x651C	# <CJK>
0x9DB7	0x6505	# <CJK>
0x9DB8	0x6524	# <CJK>
0x9DB9	0x6523	# <CJK>
0x9DBA	0x652B	# <CJK>
0x9DBB	0x6534	# <CJK>
0x9DBC	0x6535	# <CJK>
0x9DBD	0x6537	# <CJK>
0x9DBE	0x6536	# <CJK>
0x9DBF	0x6538	# <CJK>
0x9DC0	0x754B	# <CJK>
0x9DC1	0x6548	# <CJK>
0x9DC2	0x6556	# <CJK>
0x9DC3	0x6555	# <CJK>
0x9DC4	0x654D	# <CJK>
0x9DC5	0x6558	# <CJK>
0x9DC6	0x655E	# <CJK>
0x9DC7	0x655D	# <CJK>
0x9DC8	0x6572	# <CJK>
0x9DC9	0x6578	# <CJK>
0x9DCA	0x6582	# <CJK>
0x9DCB	0x6583	# <CJK>
0x9DCC	0x8B8A	# <CJK>
0x9DCD	0x659B	# <CJK>
0x9DCE	0x659F	# <CJK>
0x9DCF	0x65AB	# <CJK>
0x9DD0	0x65B7	# <CJK>
0x9DD1	0x65C3	# <CJK>
0x9DD2	0x65C6	# <CJK>
0x9DD3	0x65C1	# <CJK>
0x9DD4	0x65C4	# <CJK>
0x9DD5	0x65CC	# <CJK>
0x9DD6	0x65D2	# <CJK>
0x9DD7	0x65DB	# <CJK>
0x9DD8	0x65D9	# <CJK>
0x9DD9	0x65E0	# <CJK>
0x9DDA	0x65E1	# <CJK>
0x9DDB	0x65F1	# <CJK>
0x9DDC	0x6772	# <CJK>
0x9DDD	0x660A	# <CJK>
0x9DDE	0x6603	# <CJK>
0x9DDF	0x65FB	# <CJK>
0x9DE0	0x6773	# <CJK>
0x9DE1	0x6635	# <CJK>
0x9DE2	0x6636	# <CJK>
0x9DE3	0x6634	# <CJK>
0x9DE4	0x661C	# <CJK>
0x9DE5	0x664F	# <CJK>
0x9DE6	0x6644	# <CJK>
0x9DE7	0x6649	# <CJK>
0x9DE8	0x6641	# <CJK>
0x9DE9	0x665E	# <CJK>
0x9DEA	0x665D	# <CJK>
0x9DEB	0x6664	# <CJK>
0x9DEC	0x6667	# <CJK>
0x9DED	0x6668	# <CJK>
0x9DEE	0x665F	# <CJK>
0x9DEF	0x6662	# <CJK>
0x9DF0	0x6670	# <CJK>
0x9DF1	0x6683	# <CJK>
0x9DF2	0x6688	# <CJK>
0x9DF3	0x668E	# <CJK>
0x9DF4	0x6689	# <CJK>
0x9DF5	0x6684	# <CJK>
0x9DF6	0x6698	# <CJK>
0x9DF7	0x669D	# <CJK>
0x9DF8	0x66C1	# <CJK>
0x9DF9	0x66B9	# <CJK>
0x9DFA	0x66C9	# <CJK>
0x9DFB	0x66BE	# <CJK>
0x9DFC	0x66BC	# <CJK>
0x9E40	0x66C4	# <CJK>
0x9E41	0x66B8	# <CJK>
0x9E42	0x66D6	# <CJK>
0x9E43	0x66DA	# <CJK>
0x9E44	0x66E0	# <CJK>
0x9E45	0x663F	# <CJK>
0x9E46	0x66E6	# <CJK>
0x9E47	0x66E9	# <CJK>
0x9E48	0x66F0	# <CJK>
0x9E49	0x66F5	# <CJK>
0x9E4A	0x66F7	# <CJK>
0x9E4B	0x670F	# <CJK>
0x9E4C	0x6716	# <CJK>
0x9E4D	0x671E	# <CJK>
0x9E4E	0x6726	# <CJK>
0x9E4F	0x6727	# <CJK>
0x9E50	0x9738	# <CJK>
0x9E51	0x672E	# <CJK>
0x9E52	0x673F	# <CJK>
0x9E53	0x6736	# <CJK>
0x9E54	0x6741	# <CJK>
0x9E55	0x6738	# <CJK>
0x9E56	0x6737	# <CJK>
0x9E57	0x6746	# <CJK>
0x9E58	0x675E	# <CJK>
0x9E59	0x6760	# <CJK>
0x9E5A	0x6759	# <CJK>
0x9E5B	0x6763	# <CJK>
0x9E5C	0x6764	# <CJK>
0x9E5D	0x6789	# <CJK>
0x9E5E	0x6770	# <CJK>
0x9E5F	0x67A9	# <CJK>
0x9E60	0x677C	# <CJK>
0x9E61	0x676A	# <CJK>
0x9E62	0x678C	# <CJK>
0x9E63	0x678B	# <CJK>
0x9E64	0x67A6	# <CJK>
0x9E65	0x67A1	# <CJK>
0x9E66	0x6785	# <CJK>
0x9E67	0x67B7	# <CJK>
0x9E68	0x67EF	# <CJK>
0x9E69	0x67B4	# <CJK>
0x9E6A	0x67EC	# <CJK>
0x9E6B	0x67B3	# <CJK>
0x9E6C	0x67E9	# <CJK>
0x9E6D	0x67B8	# <CJK>
0x9E6E	0x67E4	# <CJK>
0x9E6F	0x67DE	# <CJK>
0x9E70	0x67DD	# <CJK>
0x9E71	0x67E2	# <CJK>
0x9E72	0x67EE	# <CJK>
0x9E73	0x67B9	# <CJK>
0x9E74	0x67CE	# <CJK>
0x9E75	0x67C6	# <CJK>
0x9E76	0x67E7	# <CJK>
0x9E77	0x6A9C	# <CJK>
0x9E78	0x681E	# <CJK>
0x9E79	0x6846	# <CJK>
0x9E7A	0x6829	# <CJK>
0x9E7B	0x6840	# <CJK>
0x9E7C	0x684D	# <CJK>
0x9E7D	0x6832	# <CJK>
0x9E7E	0x684E	# <CJK>
0x9E80	0x68B3	# <CJK>
0x9E81	0x682B	# <CJK>
0x9E82	0x6859	# <CJK>
0x9E83	0x6863	# <CJK>
0x9E84	0x6877	# <CJK>
0x9E85	0x687F	# <CJK>
0x9E86	0x689F	# <CJK>
0x9E87	0x688F	# <CJK>
0x9E88	0x68AD	# <CJK>
0x9E89	0x6894	# <CJK>
0x9E8A	0x689D	# <CJK>
0x9E8B	0x689B	# <CJK>
0x9E8C	0x6883	# <CJK>
0x9E8D	0x6AAE	# <CJK>
0x9E8E	0x68B9	# <CJK>
0x9E8F	0x6874	# <CJK>
0x9E90	0x68B5	# <CJK>
0x9E91	0x68A0	# <CJK>
0x9E92	0x68BA	# <CJK>
0x9E93	0x690F	# <CJK>
0x9E94	0x688D	# <CJK>
0x9E95	0x687E	# <CJK>
0x9E96	0x6901	# <CJK>
0x9E97	0x68CA	# <CJK>
0x9E98	0x6908	# <CJK>
0x9E99	0x68D8	# <CJK>
0x9E9A	0x6922	# <CJK>
0x9E9B	0x6926	# <CJK>
0x9E9C	0x68E1	# <CJK>
0x9E9D	0x690C	# <CJK>
0x9E9E	0x68CD	# <CJK>
0x9E9F	0x68D4	# <CJK>
0x9EA0	0x68E7	# <CJK>
0x9EA1	0x68D5	# <CJK>
0x9EA2	0x6936	# <CJK>
0x9EA3	0x6912	# <CJK>
0x9EA4	0x6904	# <CJK>
0x9EA5	0x68D7	# <CJK>
0x9EA6	0x68E3	# <CJK>
0x9EA7	0x6925	# <CJK>
0x9EA8	0x68F9	# <CJK>
0x9EA9	0x68E0	# <CJK>
0x9EAA	0x68EF	# <CJK>
0x9EAB	0x6928	# <CJK>
0x9EAC	0x692A	# <CJK>
0x9EAD	0x691A	# <CJK>
0x9EAE	0x6923	# <CJK>
0x9EAF	0x6921	# <CJK>
0x9EB0	0x68C6	# <CJK>
0x9EB1	0x6979	# <CJK>
0x9EB2	0x6977	# <CJK>
0x9EB3	0x695C	# <CJK>
0x9EB4	0x6978	# <CJK>
0x9EB5	0x696B	# <CJK>
0x9EB6	0x6954	# <CJK>
0x9EB7	0x697E	# <CJK>
0x9EB8	0x696E	# <CJK>
0x9EB9	0x6939	# <CJK>
0x9EBA	0x6974	# <CJK>
0x9EBB	0x693D	# <CJK>
0x9EBC	0x6959	# <CJK>
0x9EBD	0x6930	# <CJK>
0x9EBE	0x6961	# <CJK>
0x9EBF	0x695E	# <CJK>
0x9EC0	0x695D	# <CJK>
0x9EC1	0x6981	# <CJK>
0x9EC2	0x696A	# <CJK>
0x9EC3	0x69B2	# <CJK>
0x9EC4	0x69AE	# <CJK>
0x9EC5	0x69D0	# <CJK>
0x9EC6	0x69BF	# <CJK>
0x9EC7	0x69C1	# <CJK>
0x9EC8	0x69D3	# <CJK>
0x9EC9	0x69BE	# <CJK>
0x9ECA	0x69CE	# <CJK>
0x9ECB	0x5BE8	# <CJK>
0x9ECC	0x69CA	# <CJK>
0x9ECD	0x69DD	# <CJK>
0x9ECE	0x69BB	# <CJK>
0x9ECF	0x69C3	# <CJK>
0x9ED0	0x69A7	# <CJK>
0x9ED1	0x6A2E	# <CJK>
0x9ED2	0x6991	# <CJK>
0x9ED3	0x69A0	# <CJK>
0x9ED4	0x699C	# <CJK>
0x9ED5	0x6995	# <CJK>
0x9ED6	0x69B4	# <CJK>
0x9ED7	0x69DE	# <CJK>
0x9ED8	0x69E8	# <CJK>
0x9ED9	0x6A02	# <CJK>
0x9EDA	0x6A1B	# <CJK>
0x9EDB	0x69FF	# <CJK>
0x9EDC	0x6B0A	# <CJK>
0x9EDD	0x69F9	# <CJK>
0x9EDE	0x69F2	# <CJK>
0x9EDF	0x69E7	# <CJK>
0x9EE0	0x6A05	# <CJK>
0x9EE1	0x69B1	# <CJK>
0x9EE2	0x6A1E	# <CJK>
0x9EE3	0x69ED	# <CJK>
0x9EE4	0x6A14	# <CJK>
0x9EE5	0x69EB	# <CJK>
0x9EE6	0x6A0A	# <CJK>
0x9EE7	0x6A12	# <CJK>
0x9EE8	0x6AC1	# <CJK>
0x9EE9	0x6A23	# <CJK>
0x9EEA	0x6A13	# <CJK>
0x9EEB	0x6A44	# <CJK>
0x9EEC	0x6A0C	# <CJK>
0x9EED	0x6A72	# <CJK>
0x9EEE	0x6A36	# <CJK>
0x9EEF	0x6A78	# <CJK>
0x9EF0	0x6A47	# <CJK>
0x9EF1	0x6A62	# <CJK>
0x9EF2	0x6A59	# <CJK>
0x9EF3	0x6A66	# <CJK>
0x9EF4	0x6A48	# <CJK>
0x9EF5	0x6A38	# <CJK>
0x9EF6	0x6A22	# <CJK>
0x9EF7	0x6A90	# <CJK>
0x9EF8	0x6A8D	# <CJK>
0x9EF9	0x6AA0	# <CJK>
0x9EFA	0x6A84	# <CJK>
0x9EFB	0x6AA2	# <CJK>
0x9EFC	0x6AA3	# <CJK>
0x9F40	0x6A97	# <CJK>
0x9F41	0x8617	# <CJK>
0x9F42	0x6ABB	# <CJK>
0x9F43	0x6AC3	# <CJK>
0x9F44	0x6AC2	# <CJK>
0x9F45	0x6AB8	# <CJK>
0x9F46	0x6AB3	# <CJK>
0x9F47	0x6AAC	# <CJK>
0x9F48	0x6ADE	# <CJK>
0x9F49	0x6AD1	# <CJK>
0x9F4A	0x6ADF	# <CJK>
0x9F4B	0x6AAA	# <CJK>
0x9F4C	0x6ADA	# <CJK>
0x9F4D	0x6AEA	# <CJK>
0x9F4E	0x6AFB	# <CJK>
0x9F4F	0x6B05	# <CJK>
0x9F50	0x8616	# <CJK>
0x9F51	0x6AFA	# <CJK>
0x9F52	0x6B12	# <CJK>
0x9F53	0x6B16	# <CJK>
0x9F54	0x9B31	# <CJK>
0x9F55	0x6B1F	# <CJK>
0x9F56	0x6B38	# <CJK>
0x9F57	0x6B37	# <CJK>
0x9F58	0x76DC	# <CJK>
0x9F59	0x6B39	# <CJK>
0x9F5A	0x98EE	# <CJK>
0x9F5B	0x6B47	# <CJK>
0x9F5C	0x6B43	# <CJK>
0x9F5D	0x6B49	# <CJK>
0x9F5E	0x6B50	# <CJK>
0x9F5F	0x6B59	# <CJK>
0x9F60	0x6B54	# <CJK>
0x9F61	0x6B5B	# <CJK>
0x9F62	0x6B5F	# <CJK>
0x9F63	0x6B61	# <CJK>
0x9F64	0x6B78	# <CJK>
0x9F65	0x6B79	# <CJK>
0x9F66	0x6B7F	# <CJK>
0x9F67	0x6B80	# <CJK>
0x9F68	0x6B84	# <CJK>
0x9F69	0x6B83	# <CJK>
0x9F6A	0x6B8D	# <CJK>
0x9F6B	0x6B98	# <CJK>
0x9F6C	0x6B95	# <CJK>
0x9F6D	0x6B9E	# <CJK>
0x9F6E	0x6BA4	# <CJK>
0x9F6F	0x6BAA	# <CJK>
0x9F70	0x6BAB	# <CJK>
0x9F71	0x6BAF	# <CJK>
0x9F72	0x6BB2	# <CJK>
0x9F73	0x6BB1	# <CJK>
0x9F74	0x6BB3	# <CJK>
0x9F75	0x6BB7	# <CJK>
0x9F76	0x6BBC	# <CJK>
0x9F77	0x6BC6	# <CJK>
0x9F78	0x6BCB	# <CJK>
0x9F79	0x6BD3	# <CJK>
0x9F7A	0x6BDF	# <CJK>
0x9F7B	0x6BEC	# <CJK>
0x9F7C	0x6BEB	# <CJK>
0x9F7D	0x6BF3	# <CJK>
0x9F7E	0x6BEF	# <CJK>
0x9F80	0x9EBE	# <CJK>
0x9F81	0x6C08	# <CJK>
0x9F82	0x6C13	# <CJK>
0x9F83	0x6C14	# <CJK>
0x9F84	0x6C1B	# <CJK>
0x9F85	0x6C24	# <CJK>
0x9F86	0x6C23	# <CJK>
0x9F87	0x6C5E	# <CJK>
0x9F88	0x6C55	# <CJK>
0x9F89	0x6C62	# <CJK>
0x9F8A	0x6C6A	# <CJK>
0x9F8B	0x6C82	# <CJK>
0x9F8C	0x6C8D	# <CJK>
0x9F8D	0x6C9A	# <CJK>
0x9F8E	0x6C81	# <CJK>
0x9F8F	0x6C9B	# <CJK>
0x9F90	0x6C7E	# <CJK>
0x9F91	0x6C68	# <CJK>
0x9F92	0x6C73	# <CJK>
0x9F93	0x6C92	# <CJK>
0x9F94	0x6C90	# <CJK>
0x9F95	0x6CC4	# <CJK>
0x9F96	0x6CF1	# <CJK>
0x9F97	0x6CD3	# <CJK>
0x9F98	0x6CBD	# <CJK>
0x9F99	0x6CD7	# <CJK>
0x9F9A	0x6CC5	# <CJK>
0x9F9B	0x6CDD	# <CJK>
0x9F9C	0x6CAE	# <CJK>
0x9F9D	0x6CB1	# <CJK>
0x9F9E	0x6CBE	# <CJK>
0x9F9F	0x6CBA	# <CJK>
0x9FA0	0x6CDB	# <CJK>
0x9FA1	0x6CEF	# <CJK>
0x9FA2	0x6CD9	# <CJK>
0x9FA3	0x6CEA	# <CJK>
0x9FA4	0x6D1F	# <CJK>
0x9FA5	0x884D	# <CJK>
0x9FA6	0x6D36	# <CJK>
0x9FA7	0x6D2B	# <CJK>
0x9FA8	0x6D3D	# <CJK>
0x9FA9	0x6D38	# <CJK>
0x9FAA	0x6D19	# <CJK>
0x9FAB	0x6D35	# <CJK>
0x9FAC	0x6D33	# <CJK>
0x9FAD	0x6D12	# <CJK>
0x9FAE	0x6D0C	# <CJK>
0x9FAF	0x6D63	# <CJK>
0x9FB0	0x6D93	# <CJK>
0x9FB1	0x6D64	# <CJK>
0x9FB2	0x6D5A	# <CJK>
0x9FB3	0x6D79	# <CJK>
0x9FB4	0x6D59	# <CJK>
0x9FB5	0x6D8E	# <CJK>
0x9FB6	0x6D95	# <CJK>
0x9FB7	0x6FE4	# <CJK>
0x9FB8	0x6D85	# <CJK>
0x9FB9	0x6DF9	# <CJK>
0x9FBA	0x6E15	# <CJK>
0x9FBB	0x6E0A	# <CJK>
0x9FBC	0x6DB5	# <CJK>
0x9FBD	0x6DC7	# <CJK>
0x9FBE	0x6DE6	# <CJK>
0x9FBF	0x6DB8	# <CJK>
0x9FC0	0x6DC6	# <CJK>
0x9FC1	0x6DEC	# <CJK>
0x9FC2	0x6DDE	# <CJK>
0x9FC3	0x6DCC	# <CJK>
0x9FC4	0x6DE8	# <CJK>
0x9FC5	0x6DD2	# <CJK>
0x9FC6	0x6DC5	# <CJK>
0x9FC7	0x6DFA	# <CJK>
0x9FC8	0x6DD9	# <CJK>
0x9FC9	0x6DE4	# <CJK>
0x9FCA	0x6DD5	# <CJK>
0x9FCB	0x6DEA	# <CJK>
0x9FCC	0x6DEE	# <CJK>
0x9FCD	0x6E2D	# <CJK>
0x9FCE	0x6E6E	# <CJK>
0x9FCF	0x6E2E	# <CJK>
0x9FD0	0x6E19	# <CJK>
0x9FD1	0x6E72	# <CJK>
0x9FD2	0x6E5F	# <CJK>
0x9FD3	0x6E3E	# <CJK>
0x9FD4	0x6E23	# <CJK>
0x9FD5	0x6E6B	# <CJK>
0x9FD6	0x6E2B	# <CJK>
0x9FD7	0x6E76	# <CJK>
0x9FD8	0x6E4D	# <CJK>
0x9FD9	0x6E1F	# <CJK>
0x9FDA	0x6E43	# <CJK>
0x9FDB	0x6E3A	# <CJK>
0x9FDC	0x6E4E	# <CJK>
0x9FDD	0x6E24	# <CJK>
0x9FDE	0x6EFF	# <CJK>
0x9FDF	0x6E1D	# <CJK>
0x9FE0	0x6E38	# <CJK>
0x9FE1	0x6E82	# <CJK>
0x9FE2	0x6EAA	# <CJK>
0x9FE3	0x6E98	# <CJK>
0x9FE4	0x6EC9	# <CJK>
0x9FE5	0x6EB7	# <CJK>
0x9FE6	0x6ED3	# <CJK>
0x9FE7	0x6EBD	# <CJK>
0x9FE8	0x6EAF	# <CJK>
0x9FE9	0x6EC4	# <CJK>
0x9FEA	0x6EB2	# <CJK>
0x9FEB	0x6ED4	# <CJK>
0x9FEC	0x6ED5	# <CJK>
0x9FED	0x6E8F	# <CJK>
0x9FEE	0x6EA5	# <CJK>
0x9FEF	0x6EC2	# <CJK>
0x9FF0	0x6E9F	# <CJK>
0x9FF1	0x6F41	# <CJK>
0x9FF2	0x6F11	# <CJK>
0x9FF3	0x704C	# <CJK>
0x9FF4	0x6EEC	# <CJK>
0x9FF5	0x6EF8	# <CJK>
0x9FF6	0x6EFE	# <CJK>
0x9FF7	0x6F3F	# <CJK>
0x9FF8	0x6EF2	# <CJK>
0x9FF9	0x6F31	# <CJK>
0x9FFA	0x6EEF	# <CJK>
0x9FFB	0x6F32	# <CJK>
0x9FFC	0x6ECC	# <CJK>
0xA1	0xFF61	# HALFWIDTH IDEOGRAPHIC FULL STOP
0xA2	0xFF62	# HALFWIDTH LEFT CORNER BRACKET
0xA3	0xFF63	# HALFWIDTH RIGHT CORNER BRACKET
0xA4	0xFF64	# HALFWIDTH IDEOGRAPHIC COMMA
0xA5	0xFF65	# HALFWIDTH KATAKANA MIDDLE DOT
0xA6	0xFF66	# HALFWIDTH KATAKANA LETTER WO
0xA7	0xFF67	# HALFWIDTH KATAKANA LETTER SMALL A
0xA8	0xFF68	# HALFWIDTH KATAKANA LETTER SMALL I
0xA9	0xFF69	# HALFWIDTH KATAKANA LETTER SMALL U
0xAA	0xFF6A	# HALFWIDTH KATAKANA LETTER SMALL E
0xAB	0xFF6B	# HALFWIDTH KATAKANA LETTER SMALL O
0xAC	0xFF6C	# HALFWIDTH KATAKANA LETTER SMALL YA
0xAD	0xFF6D	# HALFWIDTH KATAKANA LETTER SMALL YU
0xAE	0xFF6E	# HALFWIDTH KATAKANA LETTER SMALL YO
0xAF	0xFF6F	# HALFWIDTH KATAKANA LETTER SMALL TU
0xB0	0xFF70	# HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
0xB1	0xFF71	# HALFWIDTH KATAKANA LETTER A
0xB2	0xFF72	# HALFWIDTH KATAKANA LETTER I
0xB3	0xFF73	# HALFWIDTH KATAKANA LETTER U
0xB4	0xFF74	# HALFWIDTH KATAKANA LETTER E
0xB5	0xFF75	# HALFWIDTH KATAKANA LETTER O
0xB6	0xFF76	# HALFWIDTH KATAKANA LETTER KA
0xB7	0xFF77	# HALFWIDTH KATAKANA LETTER KI
0xB8	0xFF78	# HALFWIDTH KATAKANA LETTER KU
0xB9	0xFF79	# HALFWIDTH KATAKANA LETTER KE
0xBA	0xFF7A	# HALFWIDTH KATAKANA LETTER KO
0xBB	0xFF7B	# HALFWIDTH KATAKANA LETTER SA
0xBC	0xFF7C	# HALFWIDTH KATAKANA LETTER SI
0xBD	0xFF7D	# HALFWIDTH KATAKANA LETTER SU
0xBE	0xFF7E	# HALFWIDTH KATAKANA LETTER SE
0xBF	0xFF7F	# HALFWIDTH KATAKANA LETTER SO
0xC0	0xFF80	# HALFWIDTH KATAKANA LETTER TA
0xC1	0xFF81	# HALFWIDTH KATAKANA LETTER TI
0xC2	0xFF82	# HALFWIDTH KATAKANA LETTER TU
0xC3	0xFF83	# HALFWIDTH KATAKANA LETTER TE
0xC4	0xFF84	# HALFWIDTH KATAKANA LETTER TO
0xC5	0xFF85	# HALFWIDTH KATAKANA LETTER NA
0xC6	0xFF86	# HALFWIDTH KATAKANA LETTER NI
0xC7	0xFF87	# HALFWIDTH KATAKANA LETTER NU
0xC8	0xFF88	# HALFWIDTH KATAKANA LETTER NE
0xC9	0xFF89	# HALFWIDTH KATAKANA LETTER NO
0xCA	0xFF8A	# HALFWIDTH KATAKANA LETTER HA
0xCB	0xFF8B	# HALFWIDTH KATAKANA LETTER HI
0xCC	0xFF8C	# HALFWIDTH KATAKANA LETTER HU
0xCD	0xFF8D	# HALFWIDTH KATAKANA LETTER HE
0xCE	0xFF8E	# HALFWIDTH KATAKANA LETTER HO
0xCF	0xFF8F	# HALFWIDTH KATAKANA LETTER MA
0xD0	0xFF90	# HALFWIDTH KATAKANA LETTER MI
0xD1	0xFF91	# HALFWIDTH KATAKANA LETTER MU
0xD2	0xFF92	# HALFWIDTH KATAKANA LETTER ME
0xD3	0xFF93	# HALFWIDTH KATAKANA LETTER MO
0xD4	0xFF94	# HALFWIDTH KATAKANA LETTER YA
0xD5	0xFF95	# HALFWIDTH KATAKANA LETTER YU
0xD6	0xFF96	# HALFWIDTH KATAKANA LETTER YO
0xD7	0xFF97	# HALFWIDTH KATAKANA LETTER RA
0xD8	0xFF98	# HALFWIDTH KATAKANA LETTER RI
0xD9	0xFF99	# HALFWIDTH KATAKANA LETTER RU
0xDA	0xFF9A	# HALFWIDTH KATAKANA LETTER RE
0xDB	0xFF9B	# HALFWIDTH KATAKANA LETTER RO
0xDC	0xFF9C	# HALFWIDTH KATAKANA LETTER WA
0xDD	0xFF9D	# HALFWIDTH KATAKANA LETTER N
0xDE	0xFF9E	# HALFWIDTH KATAKANA VOICED SOUND MARK
0xDF	0xFF9F	# HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
0xE040	0x6F3E	# <CJK>
0xE041	0x6F13	# <CJK>
0xE042	0x6EF7	# <CJK>
0xE043	0x6F86	# <CJK>
0xE044	0x6F7A	# <CJK>
0xE045	0x6F78	# <CJK>
0xE046	0x6F81	# <CJK>
0xE047	0x6F80	# <CJK>
0xE048	0x6F6F	# <CJK>
0xE049	0x6F5B	# <CJK>
0xE04A	0x6FF3	# <CJK>
0xE04B	0x6F6D	# <CJK>
0xE04C	0x6F82	# <CJK>
0xE04D	0x6F7C	# <CJK>
0xE04E	0x6F58	# <CJK>
0xE04F	0x6F8E	# <CJK>
0xE050	0x6F91	# <CJK>
0xE051	0x6FC2	# <CJK>
0xE052	0x6F66	# <CJK>
0xE053	0x6FB3	# <CJK>
0xE054	0x6FA3	# <CJK>
0xE055	0x6FA1	# <CJK>
0xE056	0x6FA4	# <CJK>
0xE057	0x6FB9	# <CJK>
0xE058	0x6FC6	# <CJK>
0xE059	0x6FAA	# <CJK>
0xE05A	0x6FDF	# <CJK>
0xE05B	0x6FD5	# <CJK>
0xE05C	0x6FEC	# <CJK>
0xE05D	0x6FD4	# <CJK>
0xE05E	0x6FD8	# <CJK>
0xE05F	0x6FF1	# <CJK>
0xE060	0x6FEE	# <CJK>
0xE061	0x6FDB	# <CJK>
0xE062	0x7009	# <CJK>
0xE063	0x700B	# <CJK>
0xE064	0x6FFA	# <CJK>
0xE065	0x7011	# <CJK>
0xE066	0x7001	# <CJK>
0xE067	0x700F	# <CJK>
0xE068	0x6FFE	# <CJK>
0xE069	0x701B	# <CJK>
0xE06A	0x701A	# <CJK>
0xE06B	0x6F74	# <CJK>
0xE06C	0x701D	# <CJK>
0xE06D	0x7018	# <CJK>
0xE06E	0x701F	# <CJK>
0xE06F	0x7030	# <CJK>
0xE070	0x703E	# <CJK>
0xE071	0x7032	# <CJK>
0xE072	0x7051	# <CJK>
0xE073	0x7063	# <CJK>
0xE074	0x7099	# <CJK>
0xE075	0x7092	# <CJK>
0xE076	0x70AF	# <CJK>
0xE077	0x70F1	# <CJK>
0xE078	0x70AC	# <CJK>
0xE079	0x70B8	# <CJK>
0xE07A	0x70B3	# <CJK>
0xE07B	0x70AE	# <CJK>
0xE07C	0x70DF	# <CJK>
0xE07D	0x70CB	# <CJK>
0xE07E	0x70DD	# <CJK>
0xE080	0x70D9	# <CJK>
0xE081	0x7109	# <CJK>
0xE082	0x70FD	# <CJK>
0xE083	0x711C	# <CJK>
0xE084	0x7119	# <CJK>
0xE085	0x7165	# <CJK>
0xE086	0x7155	# <CJK>
0xE087	0x7188	# <CJK>
0xE088	0x7166	# <CJK>
0xE089	0x7162	# <CJK>
0xE08A	0x714C	# <CJK>
0xE08B	0x7156	# <CJK>
0xE08C	0x716C	# <CJK>
0xE08D	0x718F	# <CJK>
0xE08E	0x71FB	# <CJK>
0xE08F	0x7184	# <CJK>
0xE090	0x7195	# <CJK>
0xE091	0x71A8	# <CJK>
0xE092	0x71AC	# <CJK>
0xE093	0x71D7	# <CJK>
0xE094	0x71B9	# <CJK>
0xE095	0x71BE	# <CJK>
0xE096	0x71D2	# <CJK>
0xE097	0x71C9	# <CJK>
0xE098	0x71D4	# <CJK>
0xE099	0x71CE	# <CJK>
0xE09A	0x71E0	# <CJK>
0xE09B	0x71EC	# <CJK>
0xE09C	0x71E7	# <CJK>
0xE09D	0x71F5	# <CJK>
0xE09E	0x71FC	# <CJK>
0xE09F	0x71F9	# <CJK>
0xE0A0	0x71FF	# <CJK>
0xE0A1	0x720D	# <CJK>
0xE0A2	0x7210	# <CJK>
0xE0A3	0x721B	# <CJK>
0xE0A4	0x7228	# <CJK>
0xE0A5	0x722D	# <CJK>
0xE0A6	0x722C	# <CJK>
0xE0A7	0x7230	# <CJK>
0xE0A8	0x7232	# <CJK>
0xE0A9	0x723B	# <CJK>
0xE0AA	0x723C	# <CJK>
0xE0AB	0x723F	# <CJK>
0xE0AC	0x7240	# <CJK>
0xE0AD	0x7246	# <CJK>
0xE0AE	0x724B	# <CJK>
0xE0AF	0x7258	# <CJK>
0xE0B0	0x7274	# <CJK>
0xE0B1	0x727E	# <CJK>
0xE0B2	0x7282	# <CJK>
0xE0B3	0x7281	# <CJK>
0xE0B4	0x7287	# <CJK>
0xE0B5	0x7292	# <CJK>
0xE0B6	0x7296	# <CJK>
0xE0B7	0x72A2	# <CJK>
0xE0B8	0x72A7	# <CJK>
0xE0B9	0x72B9	# <CJK>
0xE0BA	0x72B2	# <CJK>
0xE0BB	0x72C3	# <CJK>
0xE0BC	0x72C6	# <CJK>
0xE0BD	0x72C4	# <CJK>
0xE0BE	0x72CE	# <CJK>
0xE0BF	0x72D2	# <CJK>
0xE0C0	0x72E2	# <CJK>
0xE0C1	0x72E0	# <CJK>
0xE0C2	0x72E1	# <CJK>
0xE0C3	0x72F9	# <CJK>
0xE0C4	0x72F7	# <CJK>
0xE0C5	0x500F	# <CJK>
0xE0C6	0x7317	# <CJK>
0xE0C7	0x730A	# <CJK>
0xE0C8	0x731C	# <CJK>
0xE0C9	0x7316	# <CJK>
0xE0CA	0x731D	# <CJK>
0xE0CB	0x7334	# <CJK>
0xE0CC	0x732F	# <CJK>
0xE0CD	0x7329	# <CJK>
0xE0CE	0x7325	# <CJK>
0xE0CF	0x733E	# <CJK>
0xE0D0	0x734E	# <CJK>
0xE0D1	0x734F	# <CJK>
0xE0D2	0x9ED8	# <CJK>
0xE0D3	0x7357	# <CJK>
0xE0D4	0x736A	# <CJK>
0xE0D5	0x7368	# <CJK>
0xE0D6	0x7370	# <CJK>
0xE0D7	0x7378	# <CJK>
0xE0D8	0x7375	# <CJK>
0xE0D9	0x737B	# <CJK>
0xE0DA	0x737A	# <CJK>
0xE0DB	0x73C8	# <CJK>
0xE0DC	0x73B3	# <CJK>
0xE0DD	0x73CE	# <CJK>
0xE0DE	0x73BB	# <CJK>
0xE0DF	0x73C0	# <CJK>
0xE0E0	0x73E5	# <CJK>
0xE0E1	0x73EE	# <CJK>
0xE0E2	0x73DE	# <CJK>
0xE0E3	0x74A2	# <CJK>
0xE0E4	0x7405	# <CJK>
0xE0E5	0x746F	# <CJK>
0xE0E6	0x7425	# <CJK>
0xE0E7	0x73F8	# <CJK>
0xE0E8	0x7432	# <CJK>
0xE0E9	0x743A	# <CJK>
0xE0EA	0x7455	# <CJK>
0xE0EB	0x743F	# <CJK>
0xE0EC	0x745F	# <CJK>
0xE0ED	0x7459	# <CJK>
0xE0EE	0x7441	# <CJK>
0xE0EF	0x745C	# <CJK>
0xE0F0	0x7469	# <CJK>
0xE0F1	0x7470	# <CJK>
0xE0F2	0x7463	# <CJK>
0xE0F3	0x746A	# <CJK>
0xE0F4	0x7476	# <CJK>
0xE0F5	0x747E	# <CJK>
0xE0F6	0x748B	# <CJK>
0xE0F7	0x749E	# <CJK>
0xE0F8	0x74A7	# <CJK>
0xE0F9	0x74CA	# <CJK>
0xE0FA	0x74CF	# <CJK>
0xE0FB	0x74D4	# <CJK>
0xE0FC	0x73F1	# <CJK>
0xE140	0x74E0	# <CJK>
0xE141	0x74E3	# <CJK>
0xE142	0x74E7	# <CJK>
0xE143	0x74E9	# <CJK>
0xE144	0x74EE	# <CJK>
0xE145	0x74F2	# <CJK>
0xE146	0x74F0	# <CJK>
0xE147	0x74F1	# <CJK>
0xE148	0x74F8	# <CJK>
0xE149	0x74F7	# <CJK>
0xE14A	0x7504	# <CJK>
0xE14B	0x7503	# <CJK>
0xE14C	0x7505	# <CJK>
0xE14D	0x750C	# <CJK>
0xE14E	0x750E	# <CJK>
0xE14F	0x750D	# <CJK>
0xE150	0x7515	# <CJK>
0xE151	0x7513	# <CJK>
0xE152	0x751E	# <CJK>
0xE153	0x7526	# <CJK>
0xE154	0x752C	# <CJK>
0xE155	0x753C	# <CJK>
0xE156	0x7544	# <CJK>
0xE157	0x754D	# <CJK>
0xE158	0x754A	# <CJK>
0xE159	0x7549	# <CJK>
0xE15A	0x755B	# <CJK>
0xE15B	0x7546	# <CJK>
0xE15C	0x755A	# <CJK>
0xE15D	0x7569	# <CJK>
0xE15E	0x7564	# <CJK>
0xE15F	0x7567	# <CJK>
0xE160	0x756B	# <CJK>
0xE161	0x756D	# <CJK>
0xE162	0x7578	# <CJK>
0xE163	0x7576	# <CJK>
0xE164	0x7586	# <CJK>
0xE165	0x7587	# <CJK>
0xE166	0x7574	# <CJK>
0xE167	0x758A	# <CJK>
0xE168	0x7589	# <CJK>
0xE169	0x7582	# <CJK>
0xE16A	0x7594	# <CJK>
0xE16B	0x759A	# <CJK>
0xE16C	0x759D	# <CJK>
0xE16D	0x75A5	# <CJK>
0xE16E	0x75A3	# <CJK>
0xE16F	0x75C2	# <CJK>
0xE170	0x75B3	# <CJK>
0xE171	0x75C3	# <CJK>
0xE172	0x75B5	# <CJK>
0xE173	0x75BD	# <CJK>
0xE174	0x75B8	# <CJK>
0xE175	0x75BC	# <CJK>
0xE176	0x75B1	# <CJK>
0xE177	0x75CD	# <CJK>
0xE178	0x75CA	# <CJK>
0xE179	0x75D2	# <CJK>
0xE17A	0x75D9	# <CJK>
0xE17B	0x75E3	# <CJK>
0xE17C	0x75DE	# <CJK>
0xE17D	0x75FE	# <CJK>
0xE17E	0x75FF	# <CJK>
0xE180	0x75FC	# <CJK>
0xE181	0x7601	# <CJK>
0xE182	0x75F0	# <CJK>
0xE183	0x75FA	# <CJK>
0xE184	0x75F2	# <CJK>
0xE185	0x75F3	# <CJK>
0xE186	0x760B	# <CJK>
0xE187	0x760D	# <CJK>
0xE188	0x7609	# <CJK>
0xE189	0x761F	# <CJK>
0xE18A	0x7627	# <CJK>
0xE18B	0x7620	# <CJK>
0xE18C	0x7621	# <CJK>
0xE18D	0x7622	# <CJK>
0xE18E	0x7624	# <CJK>
0xE18F	0x7634	# <CJK>
0xE190	0x7630	# <CJK>
0xE191	0x763B	# <CJK>
0xE192	0x7647	# <CJK>
0xE193	0x7648	# <CJK>
0xE194	0x7646	# <CJK>
0xE195	0x765C	# <CJK>
0xE196	0x7658	# <CJK>
0xE197	0x7661	# <CJK>
0xE198	0x7662	# <CJK>
0xE199	0x7668	# <CJK>
0xE19A	0x7669	# <CJK>
0xE19B	0x766A	# <CJK>
0xE19C	0x7667	# <CJK>
0xE19D	0x766C	# <CJK>
0xE19E	0x7670	# <CJK>
0xE19F	0x7672	# <CJK>
0xE1A0	0x7676	# <CJK>
0xE1A1	0x7678	# <CJK>
0xE1A2	0x767C	# <CJK>
0xE1A3	0x7680	# <CJK>
0xE1A4	0x7683	# <CJK>
0xE1A5	0x7688	# <CJK>
0xE1A6	0x768B	# <CJK>
0xE1A7	0x768E	# <CJK>
0xE1A8	0x7696	# <CJK>
0xE1A9	0x7693	# <CJK>
0xE1AA	0x7699	# <CJK>
0xE1AB	0x769A	# <CJK>
0xE1AC	0x76B0	# <CJK>
0xE1AD	0x76B4	# <CJK>
0xE1AE	0x76B8	# <CJK>
0xE1AF	0x76B9	# <CJK>
0xE1B0	0x76BA	# <CJK>
0xE1B1	0x76C2	# <CJK>
0xE1B2	0x76CD	# <CJK>
0xE1B3	0x76D6	# <CJK>
0xE1B4	0x76D2	# <CJK>
0xE1B5	0x76DE	# <CJK>
0xE1B6	0x76E1	# <CJK>
0xE1B7	0x76E5	# <CJK>
0xE1B8	0x76E7	# <CJK>
0xE1B9	0x76EA	# <CJK>
0xE1BA	0x862F	# <CJK>
0xE1BB	0x76FB	# <CJK>
0xE1BC	0x7708	# <CJK>
0xE1BD	0x7707	# <CJK>
0xE1BE	0x7704	# <CJK>
0xE1BF	0x7729	# <CJK>
0xE1C0	0x7724	# <CJK>
0xE1C1	0x771E	# <CJK>
0xE1C2	0x7725	# <CJK>
0xE1C3	0x7726	# <CJK>
0xE1C4	0x771B	# <CJK>
0xE1C5	0x7737	# <CJK>
0xE1C6	0x7738	# <CJK>
0xE1C7	0x7747	# <CJK>
0xE1C8	0x775A	# <CJK>
0xE1C9	0x7768	# <CJK>
0xE1CA	0x776B	# <CJK>
0xE1CB	0x775B	# <CJK>
0xE1CC	0x7765	# <CJK>
0xE1CD	0x777F	# <CJK>
0xE1CE	0x777E	# <CJK>
0xE1CF	0x7779	# <CJK>
0xE1D0	0x778E	# <CJK>
0xE1D1	0x778B	# <CJK>
0xE1D2	0x7791	# <CJK>
0xE1D3	0x77A0	# <CJK>
0xE1D4	0x779E	# <CJK>
0xE1D5	0x77B0	# <CJK>
0xE1D6	0x77B6	# <CJK>
0xE1D7	0x77B9	# <CJK>
0xE1D8	0x77BF	# <CJK>
0xE1D9	0x77BC	# <CJK>
0xE1DA	0x77BD	# <CJK>
0xE1DB	0x77BB	# <CJK>
0xE1DC	0x77C7	# <CJK>
0xE1DD	0x77CD	# <CJK>
0xE1DE	0x77D7	# <CJK>
0xE1DF	0x77DA	# <CJK>
0xE1E0	0x77DC	# <CJK>
0xE1E1	0x77E3	# <CJK>
0xE1E2	0x77EE	# <CJK>
0xE1E3	0x77FC	# <CJK>
0xE1E4	0x780C	# <CJK>
0xE1E5	0x7812	# <CJK>
0xE1E6	0x7926	# <CJK>
0xE1E7	0x7820	# <CJK>
0xE1E8	0x792A	# <CJK>
0xE1E9	0x7845	# <CJK>
0xE1EA	0x788E	# <CJK>
0xE1EB	0x7874	# <CJK>
0xE1EC	0x7886	# <CJK>
0xE1ED	0x787C	# <CJK>
0xE1EE	0x789A	# <CJK>
0xE1EF	0x788C	# <CJK>
0xE1F0	0x78A3	# <CJK>
0xE1F1	0x78B5	# <CJK>
0xE1F2	0x78AA	# <CJK>
0xE1F3	0x78AF	# <CJK>
0xE1F4	0x78D1	# <CJK>
0xE1F5	0x78C6	# <CJK>
0xE1F6	0x78CB	# <CJK>
0xE1F7	0x78D4	# <CJK>
0xE1F8	0x78BE	# <CJK>
0xE1F9	0x78BC	# <CJK>
0xE1FA	0x78C5	# <CJK>
0xE1FB	0x78CA	# <CJK>
0xE1FC	0x78EC	# <CJK>
0xE240	0x78E7	# <CJK>
0xE241	0x78DA	# <CJK>
0xE242	0x78FD	# <CJK>
0xE243	0x78F4	# <CJK>
0xE244	0x7907	# <CJK>
0xE245	0x7912	# <CJK>
0xE246	0x7911	# <CJK>
0xE247	0x7919	# <CJK>
0xE248	0x792C	# <CJK>
0xE249	0x792B	# <CJK>
0xE24A	0x7940	# <CJK>
0xE24B	0x7960	# <CJK>
0xE24C	0x7957	# <CJK>
0xE24D	0x795F	# <CJK>
0xE24E	0x795A	# <CJK>
0xE24F	0x7955	# <CJK>
0xE250	0x7953	# <CJK>
0xE251	0x797A	# <CJK>
0xE252	0x797F	# <CJK>
0xE253	0x798A	# <CJK>
0xE254	0x799D	# <CJK>
0xE255	0x79A7	# <CJK>
0xE256	0x9F4B	# <CJK>
0xE257	0x79AA	# <CJK>
0xE258	0x79AE	# <CJK>
0xE259	0x79B3	# <CJK>
0xE25A	0x79B9	# <CJK>
0xE25B	0x79BA	# <CJK>
0xE25C	0x79C9	# <CJK>
0xE25D	0x79D5	# <CJK>
0xE25E	0x79E7	# <CJK>
0xE25F	0x79EC	# <CJK>
0xE260	0x79E1	# <CJK>
0xE261	0x79E3	# <CJK>
0xE262	0x7A08	# <CJK>
0xE263	0x7A0D	# <CJK>
0xE264	0x7A18	# <CJK>
0xE265	0x7A19	# <CJK>
0xE266	0x7A20	# <CJK>
0xE267	0x7A1F	# <CJK>
0xE268	0x7980	# <CJK>
0xE269	0x7A31	# <CJK>
0xE26A	0x7A3B	# <CJK>
0xE26B	0x7A3E	# <CJK>
0xE26C	0x7A37	# <CJK>
0xE26D	0x7A43	# <CJK>
0xE26E	0x7A57	# <CJK>
0xE26F	0x7A49	# <CJK>
0xE270	0x7A61	# <CJK>
0xE271	0x7A62	# <CJK>
0xE272	0x7A69	# <CJK>
0xE273	0x9F9D	# <CJK>
0xE274	0x7A70	# <CJK>
0xE275	0x7A79	# <CJK>
0xE276	0x7A7D	# <CJK>
0xE277	0x7A88	# <CJK>
0xE278	0x7A97	# <CJK>
0xE279	0x7A95	# <CJK>
0xE27A	0x7A98	# <CJK>
0xE27B	0x7A96	# <CJK>
0xE27C	0x7AA9	# <CJK>
0xE27D	0x7AC8	# <CJK>
0xE27E	0x7AB0	# <CJK>
0xE280	0x7AB6	# <CJK>
0xE281	0x7AC5	# <CJK>
0xE282	0x7AC4	# <CJK>
0xE283	0x7ABF	# <CJK>
0xE284	0x9083	# <CJK>
0xE285	0x7AC7	# <CJK>
0xE286	0x7ACA	# <CJK>
0xE287	0x7ACD	# <CJK>
0xE288	0x7ACF	# <CJK>
0xE289	0x7AD5	# <CJK>
0xE28A	0x7AD3	# <CJK>
0xE28B	0x7AD9	# <CJK>
0xE28C	0x7ADA	# <CJK>
0xE28D	0x7ADD	# <CJK>
0xE28E	0x7AE1	# <CJK>
0xE28F	0x7AE2	# <CJK>
0xE290	0x7AE6	# <CJK>
0xE291	0x7AED	# <CJK>
0xE292	0x7AF0	# <CJK>
0xE293	0x7B02	# <CJK>
0xE294	0x7B0F	# <CJK>
0xE295	0x7B0A	# <CJK>
0xE296	0x7B06	# <CJK>
0xE297	0x7B33	# <CJK>
0xE298	0x7B18	# <CJK>
0xE299	0x7B19	# <CJK>
0xE29A	0x7B1E	# <CJK>
0xE29B	0x7B35	# <CJK>
0xE29C	0x7B28	# <CJK>
0xE29D	0x7B36	# <CJK>
0xE29E	0x7B50	# <CJK>
0xE29F	0x7B7A	# <CJK>
0xE2A0	0x7B04	# <CJK>
0xE2A1	0x7B4D	# <CJK>
0xE2A2	0x7B0B	# <CJK>
0xE2A3	0x7B4C	# <CJK>
0xE2A4	0x7B45	# <CJK>
0xE2A5	0x7B75	# <CJK>
0xE2A6	0x7B65	# <CJK>
0xE2A7	0x7B74	# <CJK>
0xE2A8	0x7B67	# <CJK>
0xE2A9	0x7B70	# <CJK>
0xE2AA	0x7B71	# <CJK>
0xE2AB	0x7B6C	# <CJK>
0xE2AC	0x7B6E	# <CJK>
0xE2AD	0x7B9D	# <CJK>
0xE2AE	0x7B98	# <CJK>
0xE2AF	0x7B9F	# <CJK>
0xE2B0	0x7B8D	# <CJK>
0xE2B1	0x7B9C	# <CJK>
0xE2B2	0x7B9A	# <CJK>
0xE2B3	0x7B8B	# <CJK>
0xE2B4	0x7B92	# <CJK>
0xE2B5	0x7B8F	# <CJK>
0xE2B6	0x7B5D	# <CJK>
0xE2B7	0x7B99	# <CJK>
0xE2B8	0x7BCB	# <CJK>
0xE2B9	0x7BC1	# <CJK>
0xE2BA	0x7BCC	# <CJK>
0xE2BB	0x7BCF	# <CJK>
0xE2BC	0x7BB4	# <CJK>
0xE2BD	0x7BC6	# <CJK>
0xE2BE	0x7BDD	# <CJK>
0xE2BF	0x7BE9	# <CJK>
0xE2C0	0x7C11	# <CJK>
0xE2C1	0x7C14	# <CJK>
0xE2C2	0x7BE6	# <CJK>
0xE2C3	0x7BE5	# <CJK>
0xE2C4	0x7C60	# <CJK>
0xE2C5	0x7C00	# <CJK>
0xE2C6	0x7C07	# <CJK>
0xE2C7	0x7C13	# <CJK>
0xE2C8	0x7BF3	# <CJK>
0xE2C9	0x7BF7	# <CJK>
0xE2CA	0x7C17	# <CJK>
0xE2CB	0x7C0D	# <CJK>
0xE2CC	0x7BF6	# <CJK>
0xE2CD	0x7C23	# <CJK>
0xE2CE	0x7C27	# <CJK>
0xE2CF	0x7C2A	# <CJK>
0xE2D0	0x7C1F	# <CJK>
0xE2D1	0x7C37	# <CJK>
0xE2D2	0x7C2B	# <CJK>
0xE2D3	0x7C3D	# <CJK>
0xE2D4	0x7C4C	# <CJK>
0xE2D5	0x7C43	# <CJK>
0xE2D6	0x7C54	# <CJK>
0xE2D7	0x7C4F	# <CJK>
0xE2D8	0x7C40	# <CJK>
0xE2D9	0x7C50	# <CJK>
0xE2DA	0x7C58	# <CJK>
0xE2DB	0x7C5F	# <CJK>
0xE2DC	0x7C64	# <CJK>
0xE2DD	0x7C56	# <CJK>
0xE2DE	0x7C65	# <CJK>
0xE2DF	0x7C6C	# <CJK>
0xE2E0	0x7C75	# <CJK>
0xE2E1	0x7C83	# <CJK>
0xE2E2	0x7C90	# <CJK>
0xE2E3	0x7CA4	# <CJK>
0xE2E4	0x7CAD	# <CJK>
0xE2E5	0x7CA2	# <CJK>
0xE2E6	0x7CAB	# <CJK>
0xE2E7	0x7CA1	# <CJK>
0xE2E8	0x7CA8	# <CJK>
0xE2E9	0x7CB3	# <CJK>
0xE2EA	0x7CB2	# <CJK>
0xE2EB	0x7CB1	# <CJK>
0xE2EC	0x7CAE	# <CJK>
0xE2ED	0x7CB9	# <CJK>
0xE2EE	0x7CBD	# <CJK>
0xE2EF	0x7CC0	# <CJK>
0xE2F0	0x7CC5	# <CJK>
0xE2F1	0x7CC2	# <CJK>
0xE2F2	0x7CD8	# <CJK>
0xE2F3	0x7CD2	# <CJK>
0xE2F4	0x7CDC	# <CJK>
0xE2F5	0x7CE2	# <CJK>
0xE2F6	0x9B3B	# <CJK>
0xE2F7	0x7CEF	# <CJK>
0xE2F8	0x7CF2	# <CJK>
0xE2F9	0x7CF4	# <CJK>
0xE2FA	0x7CF6	# <CJK>
0xE2FB	0x7CFA	# <CJK>
0xE2FC	0x7D06	# <CJK>
0xE340	0x7D02	# <CJK>
0xE341	0x7D1C	# <CJK>
0xE342	0x7D15	# <CJK>
0xE343	0x7D0A	# <CJK>
0xE344	0x7D45	# <CJK>
0xE345	0x7D4B	# <CJK>
0xE346	0x7D2E	# <CJK>
0xE347	0x7D32	# <CJK>
0xE348	0x7D3F	# <CJK>
0xE349	0x7D35	# <CJK>
0xE34A	0x7D46	# <CJK>
0xE34B	0x7D73	# <CJK>
0xE34C	0x7D56	# <CJK>
0xE34D	0x7D4E	# <CJK>
0xE34E	0x7D72	# <CJK>
0xE34F	0x7D68	# <CJK>
0xE350	0x7D6E	# <CJK>
0xE351	0x7D4F	# <CJK>
0xE352	0x7D63	# <CJK>
0xE353	0x7D93	# <CJK>
0xE354	0x7D89	# <CJK>
0xE355	0x7D5B	# <CJK>
0xE356	0x7D8F	# <CJK>
0xE357	0x7D7D	# <CJK>
0xE358	0x7D9B	# <CJK>
0xE359	0x7DBA	# <CJK>
0xE35A	0x7DAE	# <CJK>
0xE35B	0x7DA3	# <CJK>
0xE35C	0x7DB5	# <CJK>
0xE35D	0x7DC7	# <CJK>
0xE35E	0x7DBD	# <CJK>
0xE35F	0x7DAB	# <CJK>
0xE360	0x7E3D	# <CJK>
0xE361	0x7DA2	# <CJK>
0xE362	0x7DAF	# <CJK>
0xE363	0x7DDC	# <CJK>
0xE364	0x7DB8	# <CJK>
0xE365	0x7D9F	# <CJK>
0xE366	0x7DB0	# <CJK>
0xE367	0x7DD8	# <CJK>
0xE368	0x7DDD	# <CJK>
0xE369	0x7DE4	# <CJK>
0xE36A	0x7DDE	# <CJK>
0xE36B	0x7DFB	# <CJK>
0xE36C	0x7DF2	# <CJK>
0xE36D	0x7DE1	# <CJK>
0xE36E	0x7E05	# <CJK>
0xE36F	0x7E0A	# <CJK>
0xE370	0x7E23	# <CJK>
0xE371	0x7E21	# <CJK>
0xE372	0x7E12	# <CJK>
0xE373	0x7E31	# <CJK>
0xE374	0x7E1F	# <CJK>
0xE375	0x7E09	# <CJK>
0xE376	0x7E0B	# <CJK>
0xE377	0x7E22	# <CJK>
0xE378	0x7E46	# <CJK>
0xE379	0x7E66	# <CJK>
0xE37A	0x7E3B	# <CJK>
0xE37B	0x7E35	# <CJK>
0xE37C	0x7E39	# <CJK>
0xE37D	0x7E43	# <CJK>
0xE37E	0x7E37	# <CJK>
0xE380	0x7E32	# <CJK>
0xE381	0x7E3A	# <CJK>
0xE382	0x7E67	# <CJK>
0xE383	0x7E5D	# <CJK>
0xE384	0x7E56	# <CJK>
0xE385	0x7E5E	# <CJK>
0xE386	0x7E59	# <CJK>
0xE387	0x7E5A	# <CJK>
0xE388	0x7E79	# <CJK>
0xE389	0x7E6A	# <CJK>
0xE38A	0x7E69	# <CJK>
0xE38B	0x7E7C	# <CJK>
0xE38C	0x7E7B	# <CJK>
0xE38D	0x7E83	# <CJK>
0xE38E	0x7DD5	# <CJK>
0xE38F	0x7E7D	# <CJK>
0xE390	0x8FAE	# <CJK>
0xE391	0x7E7F	# <CJK>
0xE392	0x7E88	# <CJK>
0xE393	0x7E89	# <CJK>
0xE394	0x7E8C	# <CJK>
0xE395	0x7E92	# <CJK>
0xE396	0x7E90	# <CJK>
0xE397	0x7E93	# <CJK>
0xE398	0x7E94	# <CJK>
0xE399	0x7E96	# <CJK>
0xE39A	0x7E8E	# <CJK>
0xE39B	0x7E9B	# <CJK>
0xE39C	0x7E9C	# <CJK>
0xE39D	0x7F38	# <CJK>
0xE39E	0x7F3A	# <CJK>
0xE39F	0x7F45	# <CJK>
0xE3A0	0x7F4C	# <CJK>
0xE3A1	0x7F4D	# <CJK>
0xE3A2	0x7F4E	# <CJK>
0xE3A3	0x7F50	# <CJK>
0xE3A4	0x7F51	# <CJK>
0xE3A5	0x7F55	# <CJK>
0xE3A6	0x7F54	# <CJK>
0xE3A7	0x7F58	# <CJK>
0xE3A8	0x7F5F	# <CJK>
0xE3A9	0x7F60	# <CJK>
0xE3AA	0x7F68	# <CJK>
0xE3AB	0x7F69	# <CJK>
0xE3AC	0x7F67	# <CJK>
0xE3AD	0x7F78	# <CJK>
0xE3AE	0x7F82	# <CJK>
0xE3AF	0x7F86	# <CJK>
0xE3B0	0x7F83	# <CJK>
0xE3B1	0x7F88	# <CJK>
0xE3B2	0x7F87	# <CJK>
0xE3B3	0x7F8C	# <CJK>
0xE3B4	0x7F94	# <CJK>
0xE3B5	0x7F9E	# <CJK>
0xE3B6	0x7F9D	# <CJK>
0xE3B7	0x7F9A	# <CJK>
0xE3B8	0x7FA3	# <CJK>
0xE3B9	0x7FAF	# <CJK>
0xE3BA	0x7FB2	# <CJK>
0xE3BB	0x7FB9	# <CJK>
0xE3BC	0x7FAE	# <CJK>
0xE3BD	0x7FB6	# <CJK>
0xE3BE	0x7FB8	# <CJK>
0xE3BF	0x8B71	# <CJK>
0xE3C0	0x7FC5	# <CJK>
0xE3C1	0x7FC6	# <CJK>
0xE3C2	0x7FCA	# <CJK>
0xE3C3	0x7FD5	# <CJK>
0xE3C4	0x7FD4	# <CJK>
0xE3C5	0x7FE1	# <CJK>
0xE3C6	0x7FE6	# <CJK>
0xE3C7	0x7FE9	# <CJK>
0xE3C8	0x7FF3	# <CJK>
0xE3C9	0x7FF9	# <CJK>
0xE3CA	0x98DC	# <CJK>
0xE3CB	0x8006	# <CJK>
0xE3CC	0x8004	# <CJK>
0xE3CD	0x800B	# <CJK>
0xE3CE	0x8012	# <CJK>
0xE3CF	0x8018	# <CJK>
0xE3D0	0x8019	# <CJK>
0xE3D1	0x801C	# <CJK>
0xE3D2	0x8021	# <CJK>
0xE3D3	0x8028	# <CJK>
0xE3D4	0x803F	# <CJK>
0xE3D5	0x803B	# <CJK>
0xE3D6	0x804A	# <CJK>
0xE3D7	0x8046	# <CJK>
0xE3D8	0x8052	# <CJK>
0xE3D9	0x8058	# <CJK>
0xE3DA	0x805A	# <CJK>
0xE3DB	0x805F	# <CJK>
0xE3DC	0x8062	# <CJK>
0xE3DD	0x8068	# <CJK>
0xE3DE	0x8073	# <CJK>
0xE3DF	0x8072	# <CJK>
0xE3E0	0x8070	# <CJK>
0xE3E1	0x8076	# <CJK>
0xE3E2	0x8079	# <CJK>
0xE3E3	0x807D	# <CJK>
0xE3E4	0x807F	# <CJK>
0xE3E5	0x8084	# <CJK>
0xE3E6	0x8086	# <CJK>
0xE3E7	0x8085	# <CJK>
0xE3E8	0x809B	# <CJK>
0xE3E9	0x8093	# <CJK>
0xE3EA	0x809A	# <CJK>
0xE3EB	0x80AD	# <CJK>
0xE3EC	0x5190	# <CJK>
0xE3ED	0x80AC	# <CJK>
0xE3EE	0x80DB	# <CJK>
0xE3EF	0x80E5	# <CJK>
0xE3F0	0x80D9	# <CJK>
0xE3F1	0x80DD	# <CJK>
0xE3F2	0x80C4	# <CJK>
0xE3F3	0x80DA	# <CJK>
0xE3F4	0x80D6	# <CJK>
0xE3F5	0x8109	# <CJK>
0xE3F6	0x80EF	# <CJK>
0xE3F7	0x80F1	# <CJK>
0xE3F8	0x811B	# <CJK>
0xE3F9	0x8129	# <CJK>
0xE3FA	0x8123	# <CJK>
0xE3FB	0x812F	# <CJK>
0xE3FC	0x814B	# <CJK>
0xE440	0x968B	# <CJK>
0xE441	0x8146	# <CJK>
0xE442	0x813E	# <CJK>
0xE443	0x8153	# <CJK>
0xE444	0x8151	# <CJK>
0xE445	0x80FC	# <CJK>
0xE446	0x8171	# <CJK>
0xE447	0x816E	# <CJK>
0xE448	0x8165	# <CJK>
0xE449	0x8166	# <CJK>
0xE44A	0x8174	# <CJK>
0xE44B	0x8183	# <CJK>
0xE44C	0x8188	# <CJK>
0xE44D	0x818A	# <CJK>
0xE44E	0x8180	# <CJK>
0xE44F	0x8182	# <CJK>
0xE450	0x81A0	# <CJK>
0xE451	0x8195	# <CJK>
0xE452	0x81A4	# <CJK>
0xE453	0x81A3	# <CJK>
0xE454	0x815F	# <CJK>
0xE455	0x8193	# <CJK>
0xE456	0x81A9	# <CJK>
0xE457	0x81B0	# <CJK>
0xE458	0x81B5	# <CJK>
0xE459	0x81BE	# <CJK>
0xE45A	0x81B8	# <CJK>
0xE45B	0x81BD	# <CJK>
0xE45C	0x81C0	# <CJK>
0xE45D	0x81C2	# <CJK>
0xE45E	0x81BA	# <CJK>
0xE45F	0x81C9	# <CJK>
0xE460	0x81CD	# <CJK>
0xE461	0x81D1	# <CJK>
0xE462	0x81D9	# <CJK>
0xE463	0x81D8	# <CJK>
0xE464	0x81C8	# <CJK>
0xE465	0x81DA	# <CJK>
0xE466	0x81DF	# <CJK>
0xE467	0x81E0	# <CJK>
0xE468	0x81E7	# <CJK>
0xE469	0x81FA	# <CJK>
0xE46A	0x81FB	# <CJK>
0xE46B	0x81FE	# <CJK>
0xE46C	0x8201	# <CJK>
0xE46D	0x8202	# <CJK>
0xE46E	0x8205	# <CJK>
0xE46F	0x8207	# <CJK>
0xE470	0x820A	# <CJK>
0xE471	0x820D	# <CJK>
0xE472	0x8210	# <CJK>
0xE473	0x8216	# <CJK>
0xE474	0x8229	# <CJK>
0xE475	0x822B	# <CJK>
0xE476	0x8238	# <CJK>
0xE477	0x8233	# <CJK>
0xE478	0x8240	# <CJK>
0xE479	0x8259	# <CJK>
0xE47A	0x8258	# <CJK>
0xE47B	0x825D	# <CJK>
0xE47C	0x825A	# <CJK>
0xE47D	0x825F	# <CJK>
0xE47E	0x8264	# <CJK>
0xE480	0x8262	# <CJK>
0xE481	0x8268	# <CJK>
0xE482	0x826A	# <CJK>
0xE483	0x826B	# <CJK>
0xE484	0x822E	# <CJK>
0xE485	0x8271	# <CJK>
0xE486	0x8277	# <CJK>
0xE487	0x8278	# <CJK>
0xE488	0x827E	# <CJK>
0xE489	0x828D	# <CJK>
0xE48A	0x8292	# <CJK>
0xE48B	0x82AB	# <CJK>
0xE48C	0x829F	# <CJK>
0xE48D	0x82BB	# <CJK>
0xE48E	0x82AC	# <CJK>
0xE48F	0x82E1	# <CJK>
0xE490	0x82E3	# <CJK>
0xE491	0x82DF	# <CJK>
0xE492	0x82D2	# <CJK>
0xE493	0x82F4	# <CJK>
0xE494	0x82F3	# <CJK>
0xE495	0x82FA	# <CJK>
0xE496	0x8393	# <CJK>
0xE497	0x8303	# <CJK>
0xE498	0x82FB	# <CJK>
0xE499	0x82F9	# <CJK>
0xE49A	0x82DE	# <CJK>
0xE49B	0x8306	# <CJK>
0xE49C	0x82DC	# <CJK>
0xE49D	0x8309	# <CJK>
0xE49E	0x82D9	# <CJK>
0xE49F	0x8335	# <CJK>
0xE4A0	0x8334	# <CJK>
0xE4A1	0x8316	# <CJK>
0xE4A2	0x8332	# <CJK>
0xE4A3	0x8331	# <CJK>
0xE4A4	0x8340	# <CJK>
0xE4A5	0x8339	# <CJK>
0xE4A6	0x8350	# <CJK>
0xE4A7	0x8345	# <CJK>
0xE4A8	0x832F	# <CJK>
0xE4A9	0x832B	# <CJK>
0xE4AA	0x8317	# <CJK>
0xE4AB	0x8318	# <CJK>
0xE4AC	0x8385	# <CJK>
0xE4AD	0x839A	# <CJK>
0xE4AE	0x83AA	# <CJK>
0xE4AF	0x839F	# <CJK>
0xE4B0	0x83A2	# <CJK>
0xE4B1	0x8396	# <CJK>
0xE4B2	0x8323	# <CJK>
0xE4B3	0x838E	# <CJK>
0xE4B4	0x8387	# <CJK>
0xE4B5	0x838A	# <CJK>
0xE4B6	0x837C	# <CJK>
0xE4B7	0x83B5	# <CJK>
0xE4B8	0x8373	# <CJK>
0xE4B9	0x8375	# <CJK>
0xE4BA	0x83A0	# <CJK>
0xE4BB	0x8389	# <CJK>
0xE4BC	0x83A8	# <CJK>
0xE4BD	0x83F4	# <CJK>
0xE4BE	0x8413	# <CJK>
0xE4BF	0x83EB	# <CJK>
0xE4C0	0x83CE	# <CJK>
0xE4C1	0x83FD	# <CJK>
0xE4C2	0x8403	# <CJK>
0xE4C3	0x83D8	# <CJK>
0xE4C4	0x840B	# <CJK>
0xE4C5	0x83C1	# <CJK>
0xE4C6	0x83F7	# <CJK>
0xE4C7	0x8407	# <CJK>
0xE4C8	0x83E0	# <CJK>
0xE4C9	0x83F2	# <CJK>
0xE4CA	0x840D	# <CJK>
0xE4CB	0x8422	# <CJK>
0xE4CC	0x8420	# <CJK>
0xE4CD	0x83BD	# <CJK>
0xE4CE	0x8438	# <CJK>
0xE4CF	0x8506	# <CJK>
0xE4D0	0x83FB	# <CJK>
0xE4D1	0x846D	# <CJK>
0xE4D2	0x842A	# <CJK>
0xE4D3	0x843C	# <CJK>
0xE4D4	0x855A	# <CJK>
0xE4D5	0x8484	# <CJK>
0xE4D6	0x8477	# <CJK>
0xE4D7	0x846B	# <CJK>
0xE4D8	0x84AD	# <CJK>
0xE4D9	0x846E	# <CJK>
0xE4DA	0x8482	# <CJK>
0xE4DB	0x8469	# <CJK>
0xE4DC	0x8446	# <CJK>
0xE4DD	0x842C	# <CJK>
0xE4DE	0x846F	# <CJK>
0xE4DF	0x8479	# <CJK>
0xE4E0	0x8435	# <CJK>
0xE4E1	0x84CA	# <CJK>
0xE4E2	0x8462	# <CJK>
0xE4E3	0x84B9	# <CJK>
0xE4E4	0x84BF	# <CJK>
0xE4E5	0x849F	# <CJK>
0xE4E6	0x84D9	# <CJK>
0xE4E7	0x84CD	# <CJK>
0xE4E8	0x84BB	# <CJK>
0xE4E9	0x84DA	# <CJK>
0xE4EA	0x84D0	# <CJK>
0xE4EB	0x84C1	# <CJK>
0xE4EC	0x84C6	# <CJK>
0xE4ED	0x84D6	# <CJK>
0xE4EE	0x84A1	# <CJK>
0xE4EF	0x8521	# <CJK>
0xE4F0	0x84FF	# <CJK>
0xE4F1	0x84F4	# <CJK>
0xE4F2	0x8517	# <CJK>
0xE4F3	0x8518	# <CJK>
0xE4F4	0x852C	# <CJK>
0xE4F5	0x851F	# <CJK>
0xE4F6	0x8515	# <CJK>
0xE4F7	0x8514	# <CJK>
0xE4F8	0x84FC	# <CJK>
0xE4F9	0x8540	# <CJK>
0xE4FA	0x8563	# <CJK>
0xE4FB	0x8558	# <CJK>
0xE4FC	0x8548	# <CJK>
0xE540	0x8541	# <CJK>
0xE541	0x8602	# <CJK>
0xE542	0x854B	# <CJK>
0xE543	0x8555	# <CJK>
0xE544	0x8580	# <CJK>
0xE545	0x85A4	# <CJK>
0xE546	0x8588	# <CJK>
0xE547	0x8591	# <CJK>
0xE548	0x858A	# <CJK>
0xE549	0x85A8	# <CJK>
0xE54A	0x856D	# <CJK>
0xE54B	0x8594	# <CJK>
0xE54C	0x859B	# <CJK>
0xE54D	0x85EA	# <CJK>
0xE54E	0x8587	# <CJK>
0xE54F	0x859C	# <CJK>
0xE550	0x8577	# <CJK>
0xE551	0x857E	# <CJK>
0xE552	0x8590	# <CJK>
0xE553	0x85C9	# <CJK>
0xE554	0x85BA	# <CJK>
0xE555	0x85CF	# <CJK>
0xE556	0x85B9	# <CJK>
0xE557	0x85D0	# <CJK>
0xE558	0x85D5	# <CJK>
0xE559	0x85DD	# <CJK>
0xE55A	0x85E5	# <CJK>
0xE55B	0x85DC	# <CJK>
0xE55C	0x85F9	# <CJK>
0xE55D	0x860A	# <CJK>
0xE55E	0x8613	# <CJK>
0xE55F	0x860B	# <CJK>
0xE560	0x85FE	# <CJK>
0xE561	0x85FA	# <CJK>
0xE562	0x8606	# <CJK>
0xE563	0x8622	# <CJK>
0xE564	0x861A	# <CJK>
0xE565	0x8630	# <CJK>
0xE566	0x863F	# <CJK>
0xE567	0x864D	# <CJK>
0xE568	0x4E55	# <CJK>
0xE569	0x8654	# <CJK>
0xE56A	0x865F	# <CJK>
0xE56B	0x8667	# <CJK>
0xE56C	0x8671	# <CJK>
0xE56D	0x8693	# <CJK>
0xE56E	0x86A3	# <CJK>
0xE56F	0x86A9	# <CJK>
0xE570	0x86AA	# <CJK>
0xE571	0x868B	# <CJK>
0xE572	0x868C	# <CJK>
0xE573	0x86B6	# <CJK>
0xE574	0x86AF	# <CJK>
0xE575	0x86C4	# <CJK>
0xE576	0x86C6	# <CJK>
0xE577	0x86B0	# <CJK>
0xE578	0x86C9	# <CJK>
0xE579	0x8823	# <CJK>
0xE57A	0x86AB	# <CJK>
0xE57B	0x86D4	# <CJK>
0xE57C	0x86DE	# <CJK>
0xE57D	0x86E9	# <CJK>
0xE57E	0x86EC	# <CJK>
0xE580	0x86DF	# <CJK>
0xE581	0x86DB	# <CJK>
0xE582	0x86EF	# <CJK>
0xE583	0x8712	# <CJK>
0xE584	0x8706	# <CJK>
0xE585	0x8708	# <CJK>
0xE586	0x8700	# <CJK>
0xE587	0x8703	# <CJK>
0xE588	0x86FB	# <CJK>
0xE589	0x8711	# <CJK>
0xE58A	0x8709	# <CJK>
0xE58B	0x870D	# <CJK>
0xE58C	0x86F9	# <CJK>
0xE58D	0x870A	# <CJK>
0xE58E	0x8734	# <CJK>
0xE58F	0x873F	# <CJK>
0xE590	0x8737	# <CJK>
0xE591	0x873B	# <CJK>
0xE592	0x8725	# <CJK>
0xE593	0x8729	# <CJK>
0xE594	0x871A	# <CJK>
0xE595	0x8760	# <CJK>
0xE596	0x875F	# <CJK>
0xE597	0x8778	# <CJK>
0xE598	0x874C	# <CJK>
0xE599	0x874E	# <CJK>
0xE59A	0x8774	# <CJK>
0xE59B	0x8757	# <CJK>
0xE59C	0x8768	# <CJK>
0xE59D	0x876E	# <CJK>
0xE59E	0x8759	# <CJK>
0xE59F	0x8753	# <CJK>
0xE5A0	0x8763	# <CJK>
0xE5A1	0x876A	# <CJK>
0xE5A2	0x8805	# <CJK>
0xE5A3	0x87A2	# <CJK>
0xE5A4	0x879F	# <CJK>
0xE5A5	0x8782	# <CJK>
0xE5A6	0x87AF	# <CJK>
0xE5A7	0x87CB	# <CJK>
0xE5A8	0x87BD	# <CJK>
0xE5A9	0x87C0	# <CJK>
0xE5AA	0x87D0	# <CJK>
0xE5AB	0x96D6	# <CJK>
0xE5AC	0x87AB	# <CJK>
0xE5AD	0x87C4	# <CJK>
0xE5AE	0x87B3	# <CJK>
0xE5AF	0x87C7	# <CJK>
0xE5B0	0x87C6	# <CJK>
0xE5B1	0x87BB	# <CJK>
0xE5B2	0x87EF	# <CJK>
0xE5B3	0x87F2	# <CJK>
0xE5B4	0x87E0	# <CJK>
0xE5B5	0x880F	# <CJK>
0xE5B6	0x880D	# <CJK>
0xE5B7	0x87FE	# <CJK>
0xE5B8	0x87F6	# <CJK>
0xE5B9	0x87F7	# <CJK>
0xE5BA	0x880E	# <CJK>
0xE5BB	0x87D2	# <CJK>
0xE5BC	0x8811	# <CJK>
0xE5BD	0x8816	# <CJK>
0xE5BE	0x8815	# <CJK>
0xE5BF	0x8822	# <CJK>
0xE5C0	0x8821	# <CJK>
0xE5C1	0x8831	# <CJK>
0xE5C2	0x8836	# <CJK>
0xE5C3	0x8839	# <CJK>
0xE5C4	0x8827	# <CJK>
0xE5C5	0x883B	# <CJK>
0xE5C6	0x8844	# <CJK>
0xE5C7	0x8842	# <CJK>
0xE5C8	0x8852	# <CJK>
0xE5C9	0x8859	# <CJK>
0xE5CA	0x885E	# <CJK>
0xE5CB	0x8862	# <CJK>
0xE5CC	0x886B	# <CJK>
0xE5CD	0x8881	# <CJK>
0xE5CE	0x887E	# <CJK>
0xE5CF	0x889E	# <CJK>
0xE5D0	0x8875	# <CJK>
0xE5D1	0x887D	# <CJK>
0xE5D2	0x88B5	# <CJK>
0xE5D3	0x8872	# <CJK>
0xE5D4	0x8882	# <CJK>
0xE5D5	0x8897	# <CJK>
0xE5D6	0x8892	# <CJK>
0xE5D7	0x88AE	# <CJK>
0xE5D8	0x8899	# <CJK>
0xE5D9	0x88A2	# <CJK>
0xE5DA	0x888D	# <CJK>
0xE5DB	0x88A4	# <CJK>
0xE5DC	0x88B0	# <CJK>
0xE5DD	0x88BF	# <CJK>
0xE5DE	0x88B1	# <CJK>
0xE5DF	0x88C3	# <CJK>
0xE5E0	0x88C4	# <CJK>
0xE5E1	0x88D4	# <CJK>
0xE5E2	0x88D8	# <CJK>
0xE5E3	0x88D9	# <CJK>
0xE5E4	0x88DD	# <CJK>
0xE5E5	0x88F9	# <CJK>
0xE5E6	0x8902	# <CJK>
0xE5E7	0x88FC	# <CJK>
0xE5E8	0x88F4	# <CJK>
0xE5E9	0x88E8	# <CJK>
0xE5EA	0x88F2	# <CJK>
0xE5EB	0x8904	# <CJK>
0xE5EC	0x890C	# <CJK>
0xE5ED	0x890A	# <CJK>
0xE5EE	0x8913	# <CJK>
0xE5EF	0x8943	# <CJK>
0xE5F0	0x891E	# <CJK>
0xE5F1	0x8925	# <CJK>
0xE5F2	0x892A	# <CJK>
0xE5F3	0x892B	# <CJK>
0xE5F4	0x8941	# <CJK>
0xE5F5	0x8944	# <CJK>
0xE5F6	0x893B	# <CJK>
0xE5F7	0x8936	# <CJK>
0xE5F8	0x8938	# <CJK>
0xE5F9	0x894C	# <CJK>
0xE5FA	0x891D	# <CJK>
0xE5FB	0x8960	# <CJK>
0xE5FC	0x895E	# <CJK>
0xE640	0x8966	# <CJK>
0xE641	0x8964	# <CJK>
0xE642	0x896D	# <CJK>
0xE643	0x896A	# <CJK>
0xE644	0x896F	# <CJK>
0xE645	0x8974	# <CJK>
0xE646	0x8977	# <CJK>
0xE647	0x897E	# <CJK>
0xE648	0x8983	# <CJK>
0xE649	0x8988	# <CJK>
0xE64A	0x898A	# <CJK>
0xE64B	0x8993	# <CJK>
0xE64C	0x8998	# <CJK>
0xE64D	0x89A1	# <CJK>
0xE64E	0x89A9	# <CJK>
0xE64F	0x89A6	# <CJK>
0xE650	0x89AC	# <CJK>
0xE651	0x89AF	# <CJK>
0xE652	0x89B2	# <CJK>
0xE653	0x89BA	# <CJK>
0xE654	0x89BD	# <CJK>
0xE655	0x89BF	# <CJK>
0xE656	0x89C0	# <CJK>
0xE657	0x89DA	# <CJK>
0xE658	0x89DC	# <CJK>
0xE659	0x89DD	# <CJK>
0xE65A	0x89E7	# <CJK>
0xE65B	0x89F4	# <CJK>
0xE65C	0x89F8	# <CJK>
0xE65D	0x8A03	# <CJK>
0xE65E	0x8A16	# <CJK>
0xE65F	0x8A10	# <CJK>
0xE660	0x8A0C	# <CJK>
0xE661	0x8A1B	# <CJK>
0xE662	0x8A1D	# <CJK>
0xE663	0x8A25	# <CJK>
0xE664	0x8A36	# <CJK>
0xE665	0x8A41	# <CJK>
0xE666	0x8A5B	# <CJK>
0xE667	0x8A52	# <CJK>
0xE668	0x8A46	# <CJK>
0xE669	0x8A48	# <CJK>
0xE66A	0x8A7C	# <CJK>
0xE66B	0x8A6D	# <CJK>
0xE66C	0x8A6C	# <CJK>
0xE66D	0x8A62	# <CJK>
0xE66E	0x8A85	# <CJK>
0xE66F	0x8A82	# <CJK>
0xE670	0x8A84	# <CJK>
0xE671	0x8AA8	# <CJK>
0xE672	0x8AA1	# <CJK>
0xE673	0x8A91	# <CJK>
0xE674	0x8AA5	# <CJK>
0xE675	0x8AA6	# <CJK>
0xE676	0x8A9A	# <CJK>
0xE677	0x8AA3	# <CJK>
0xE678	0x8AC4	# <CJK>
0xE679	0x8ACD	# <CJK>
0xE67A	0x8AC2	# <CJK>
0xE67B	0x8ADA	# <CJK>
0xE67C	0x8AEB	# <CJK>
0xE67D	0x8AF3	# <CJK>
0xE67E	0x8AE7	# <CJK>
0xE680	0x8AE4	# <CJK>
0xE681	0x8AF1	# <CJK>
0xE682	0x8B14	# <CJK>
0xE683	0x8AE0	# <CJK>
0xE684	0x8AE2	# <CJK>
0xE685	0x8AF7	# <CJK>
0xE686	0x8ADE	# <CJK>
0xE687	0x8ADB	# <CJK>
0xE688	0x8B0C	# <CJK>
0xE689	0x8B07	# <CJK>
0xE68A	0x8B1A	# <CJK>
0xE68B	0x8AE1	# <CJK>
0xE68C	0x8B16	# <CJK>
0xE68D	0x8B10	# <CJK>
0xE68E	0x8B17	# <CJK>
0xE68F	0x8B20	# <CJK>
0xE690	0x8B33	# <CJK>
0xE691	0x97AB	# <CJK>
0xE692	0x8B26	# <CJK>
0xE693	0x8B2B	# <CJK>
0xE694	0x8B3E	# <CJK>
0xE695	0x8B28	# <CJK>
0xE696	0x8B41	# <CJK>
0xE697	0x8B4C	# <CJK>
0xE698	0x8B4F	# <CJK>
0xE699	0x8B4E	# <CJK>
0xE69A	0x8B49	# <CJK>
0xE69B	0x8B56	# <CJK>
0xE69C	0x8B5B	# <CJK>
0xE69D	0x8B5A	# <CJK>
0xE69E	0x8B6B	# <CJK>
0xE69F	0x8B5F	# <CJK>
0xE6A0	0x8B6C	# <CJK>
0xE6A1	0x8B6F	# <CJK>
0xE6A2	0x8B74	# <CJK>
0xE6A3	0x8B7D	# <CJK>
0xE6A4	0x8B80	# <CJK>
0xE6A5	0x8B8C	# <CJK>
0xE6A6	0x8B8E	# <CJK>
0xE6A7	0x8B92	# <CJK>
0xE6A8	0x8B93	# <CJK>
0xE6A9	0x8B96	# <CJK>
0xE6AA	0x8B99	# <CJK>
0xE6AB	0x8B9A	# <CJK>
0xE6AC	0x8C3A	# <CJK>
0xE6AD	0x8C41	# <CJK>
0xE6AE	0x8C3F	# <CJK>
0xE6AF	0x8C48	# <CJK>
0xE6B0	0x8C4C	# <CJK>
0xE6B1	0x8C4E	# <CJK>
0xE6B2	0x8C50	# <CJK>
0xE6B3	0x8C55	# <CJK>
0xE6B4	0x8C62	# <CJK>
0xE6B5	0x8C6C	# <CJK>
0xE6B6	0x8C78	# <CJK>
0xE6B7	0x8C7A	# <CJK>
0xE6B8	0x8C82	# <CJK>
0xE6B9	0x8C89	# <CJK>
0xE6BA	0x8C85	# <CJK>
0xE6BB	0x8C8A	# <CJK>
0xE6BC	0x8C8D	# <CJK>
0xE6BD	0x8C8E	# <CJK>
0xE6BE	0x8C94	# <CJK>
0xE6BF	0x8C7C	# <CJK>
0xE6C0	0x8C98	# <CJK>
0xE6C1	0x621D	# <CJK>
0xE6C2	0x8CAD	# <CJK>
0xE6C3	0x8CAA	# <CJK>
0xE6C4	0x8CBD	# <CJK>
0xE6C5	0x8CB2	# <CJK>
0xE6C6	0x8CB3	# <CJK>
0xE6C7	0x8CAE	# <CJK>
0xE6C8	0x8CB6	# <CJK>
0xE6C9	0x8CC8	# <CJK>
0xE6CA	0x8CC1	# <CJK>
0xE6CB	0x8CE4	# <CJK>
0xE6CC	0x8CE3	# <CJK>
0xE6CD	0x8CDA	# <CJK>
0xE6CE	0x8CFD	# <CJK>
0xE6CF	0x8CFA	# <CJK>
0xE6D0	0x8CFB	# <CJK>
0xE6D1	0x8D04	# <CJK>
0xE6D2	0x8D05	# <CJK>
0xE6D3	0x8D0A	# <CJK>
0xE6D4	0x8D07	# <CJK>
0xE6D5	0x8D0F	# <CJK>
0xE6D6	0x8D0D	# <CJK>
0xE6D7	0x8D10	# <CJK>
0xE6D8	0x9F4E	# <CJK>
0xE6D9	0x8D13	# <CJK>
0xE6DA	0x8CCD	# <CJK>
0xE6DB	0x8D14	# <CJK>
0xE6DC	0x8D16	# <CJK>
0xE6DD	0x8D67	# <CJK>
0xE6DE	0x8D6D	# <CJK>
0xE6DF	0x8D71	# <CJK>
0xE6E0	0x8D73	# <CJK>
0xE6E1	0x8D81	# <CJK>
0xE6E2	0x8D99	# <CJK>
0xE6E3	0x8DC2	# <CJK>
0xE6E4	0x8DBE	# <CJK>
0xE6E5	0x8DBA	# <CJK>
0xE6E6	0x8DCF	# <CJK>
0xE6E7	0x8DDA	# <CJK>
0xE6E8	0x8DD6	# <CJK>
0xE6E9	0x8DCC	# <CJK>
0xE6EA	0x8DDB	# <CJK>
0xE6EB	0x8DCB	# <CJK>
0xE6EC	0x8DEA	# <CJK>
0xE6ED	0x8DEB	# <CJK>
0xE6EE	0x8DDF	# <CJK>
0xE6EF	0x8DE3	# <CJK>
0xE6F0	0x8DFC	# <CJK>
0xE6F1	0x8E08	# <CJK>
0xE6F2	0x8E09	# <CJK>
0xE6F3	0x8DFF	# <CJK>
0xE6F4	0x8E1D	# <CJK>
0xE6F5	0x8E1E	# <CJK>
0xE6F6	0x8E10	# <CJK>
0xE6F7	0x8E1F	# <CJK>
0xE6F8	0x8E42	# <CJK>
0xE6F9	0x8E35	# <CJK>
0xE6FA	0x8E30	# <CJK>
0xE6FB	0x8E34	# <CJK>
0xE6FC	0x8E4A	# <CJK>
0xE740	0x8E47	# <CJK>
0xE741	0x8E49	# <CJK>
0xE742	0x8E4C	# <CJK>
0xE743	0x8E50	# <CJK>
0xE744	0x8E48	# <CJK>
0xE745	0x8E59	# <CJK>
0xE746	0x8E64	# <CJK>
0xE747	0x8E60	# <CJK>
0xE748	0x8E2A	# <CJK>
0xE749	0x8E63	# <CJK>
0xE74A	0x8E55	# <CJK>
0xE74B	0x8E76	# <CJK>
0xE74C	0x8E72	# <CJK>
0xE74D	0x8E7C	# <CJK>
0xE74E	0x8E81	# <CJK>
0xE74F	0x8E87	# <CJK>
0xE750	0x8E85	# <CJK>
0xE751	0x8E84	# <CJK>
0xE752	0x8E8B	# <CJK>
0xE753	0x8E8A	# <CJK>
0xE754	0x8E93	# <CJK>
0xE755	0x8E91	# <CJK>
0xE756	0x8E94	# <CJK>
0xE757	0x8E99	# <CJK>
0xE758	0x8EAA	# <CJK>
0xE759	0x8EA1	# <CJK>
0xE75A	0x8EAC	# <CJK>
0xE75B	0x8EB0	# <CJK>
0xE75C	0x8EC6	# <CJK>
0xE75D	0x8EB1	# <CJK>
0xE75E	0x8EBE	# <CJK>
0xE75F	0x8EC5	# <CJK>
0xE760	0x8EC8	# <CJK>
0xE761	0x8ECB	# <CJK>
0xE762	0x8EDB	# <CJK>
0xE763	0x8EE3	# <CJK>
0xE764	0x8EFC	# <CJK>
0xE765	0x8EFB	# <CJK>
0xE766	0x8EEB	# <CJK>
0xE767	0x8EFE	# <CJK>
0xE768	0x8F0A	# <CJK>
0xE769	0x8F05	# <CJK>
0xE76A	0x8F15	# <CJK>
0xE76B	0x8F12	# <CJK>
0xE76C	0x8F19	# <CJK>
0xE76D	0x8F13	# <CJK>
0xE76E	0x8F1C	# <CJK>
0xE76F	0x8F1F	# <CJK>
0xE770	0x8F1B	# <CJK>
0xE771	0x8F0C	# <CJK>
0xE772	0x8F26	# <CJK>
0xE773	0x8F33	# <CJK>
0xE774	0x8F3B	# <CJK>
0xE775	0x8F39	# <CJK>
0xE776	0x8F45	# <CJK>
0xE777	0x8F42	# <CJK>
0xE778	0x8F3E	# <CJK>
0xE779	0x8F4C	# <CJK>
0xE77A	0x8F49	# <CJK>
0xE77B	0x8F46	# <CJK>
0xE77C	0x8F4E	# <CJK>
0xE77D	0x8F57	# <CJK>
0xE77E	0x8F5C	# <CJK>
0xE780	0x8F62	# <CJK>
0xE781	0x8F63	# <CJK>
0xE782	0x8F64	# <CJK>
0xE783	0x8F9C	# <CJK>
0xE784	0x8F9F	# <CJK>
0xE785	0x8FA3	# <CJK>
0xE786	0x8FAD	# <CJK>
0xE787	0x8FAF	# <CJK>
0xE788	0x8FB7	# <CJK>
0xE789	0x8FDA	# <CJK>
0xE78A	0x8FE5	# <CJK>
0xE78B	0x8FE2	# <CJK>
0xE78C	0x8FEA	# <CJK>
0xE78D	0x8FEF	# <CJK>
0xE78E	0x9087	# <CJK>
0xE78F	0x8FF4	# <CJK>
0xE790	0x9005	# <CJK>
0xE791	0x8FF9	# <CJK>
0xE792	0x8FFA	# <CJK>
0xE793	0x9011	# <CJK>
0xE794	0x9015	# <CJK>
0xE795	0x9021	# <CJK>
0xE796	0x900D	# <CJK>
0xE797	0x901E	# <CJK>
0xE798	0x9016	# <CJK>
0xE799	0x900B	# <CJK>
0xE79A	0x9027	# <CJK>
0xE79B	0x9036	# <CJK>
0xE79C	0x9035	# <CJK>
0xE79D	0x9039	# <CJK>
0xE79E	0x8FF8	# <CJK>
0xE79F	0x904F	# <CJK>
0xE7A0	0x9050	# <CJK>
0xE7A1	0x9051	# <CJK>
0xE7A2	0x9052	# <CJK>
0xE7A3	0x900E	# <CJK>
0xE7A4	0x9049	# <CJK>
0xE7A5	0x903E	# <CJK>
0xE7A6	0x9056	# <CJK>
0xE7A7	0x9058	# <CJK>
0xE7A8	0x905E	# <CJK>
0xE7A9	0x9068	# <CJK>
0xE7AA	0x906F	# <CJK>
0xE7AB	0x9076	# <CJK>
0xE7AC	0x96A8	# <CJK>
0xE7AD	0x9072	# <CJK>
0xE7AE	0x9082	# <CJK>
0xE7AF	0x907D	# <CJK>
0xE7B0	0x9081	# <CJK>
0xE7B1	0x9080	# <CJK>
0xE7B2	0x908A	# <CJK>
0xE7B3	0x9089	# <CJK>
0xE7B4	0x908F	# <CJK>
0xE7B5	0x90A8	# <CJK>
0xE7B6	0x90AF	# <CJK>
0xE7B7	0x90B1	# <CJK>
0xE7B8	0x90B5	# <CJK>
0xE7B9	0x90E2	# <CJK>
0xE7BA	0x90E4	# <CJK>
0xE7BB	0x6248	# <CJK>
0xE7BC	0x90DB	# <CJK>
0xE7BD	0x9102	# <CJK>
0xE7BE	0x9112	# <CJK>
0xE7BF	0x9119	# <CJK>
0xE7C0	0x9132	# <CJK>
0xE7C1	0x9130	# <CJK>
0xE7C2	0x914A	# <CJK>
0xE7C3	0x9156	# <CJK>
0xE7C4	0x9158	# <CJK>
0xE7C5	0x9163	# <CJK>
0xE7C6	0x9165	# <CJK>
0xE7C7	0x9169	# <CJK>
0xE7C8	0x9173	# <CJK>
0xE7C9	0x9172	# <CJK>
0xE7CA	0x918B	# <CJK>
0xE7CB	0x9189	# <CJK>
0xE7CC	0x9182	# <CJK>
0xE7CD	0x91A2	# <CJK>
0xE7CE	0x91AB	# <CJK>
0xE7CF	0x91AF	# <CJK>
0xE7D0	0x91AA	# <CJK>
0xE7D1	0x91B5	# <CJK>
0xE7D2	0x91B4	# <CJK>
0xE7D3	0x91BA	# <CJK>
0xE7D4	0x91C0	# <CJK>
0xE7D5	0x91C1	# <CJK>
0xE7D6	0x91C9	# <CJK>
0xE7D7	0x91CB	# <CJK>
0xE7D8	0x91D0	# <CJK>
0xE7D9	0x91D6	# <CJK>
0xE7DA	0x91DF	# <CJK>
0xE7DB	0x91E1	# <CJK>
0xE7DC	0x91DB	# <CJK>
0xE7DD	0x91FC	# <CJK>
0xE7DE	0x91F5	# <CJK>
0xE7DF	0x91F6	# <CJK>
0xE7E0	0x921E	# <CJK>
0xE7E1	0x91FF	# <CJK>
0xE7E2	0x9214	# <CJK>
0xE7E3	0x922C	# <CJK>
0xE7E4	0x9215	# <CJK>
0xE7E5	0x9211	# <CJK>
0xE7E6	0x925E	# <CJK>
0xE7E7	0x9257	# <CJK>
0xE7E8	0x9245	# <CJK>
0xE7E9	0x9249	# <CJK>
0xE7EA	0x9264	# <CJK>
0xE7EB	0x9248	# <CJK>
0xE7EC	0x9295	# <CJK>
0xE7ED	0x923F	# <CJK>
0xE7EE	0x924B	# <CJK>
0xE7EF	0x9250	# <CJK>
0xE7F0	0x929C	# <CJK>
0xE7F1	0x9296	# <CJK>
0xE7F2	0x9293	# <CJK>
0xE7F3	0x929B	# <CJK>
0xE7F4	0x925A	# <CJK>
0xE7F5	0x92CF	# <CJK>
0xE7F6	0x92B9	# <CJK>
0xE7F7	0x92B7	# <CJK>
0xE7F8	0x92E9	# <CJK>
0xE7F9	0x930F	# <CJK>
0xE7FA	0x92FA	# <CJK>
0xE7FB	0x9344	# <CJK>
0xE7FC	0x932E	# <CJK>
0xE840	0x9319	# <CJK>
0xE841	0x9322	# <CJK>
0xE842	0x931A	# <CJK>
0xE843	0x9323	# <CJK>
0xE844	0x933A	# <CJK>
0xE845	0x9335	# <CJK>
0xE846	0x933B	# <CJK>
0xE847	0x935C	# <CJK>
0xE848	0x9360	# <CJK>
0xE849	0x937C	# <CJK>
0xE84A	0x936E	# <CJK>
0xE84B	0x9356	# <CJK>
0xE84C	0x93B0	# <CJK>
0xE84D	0x93AC	# <CJK>
0xE84E	0x93AD	# <CJK>
0xE84F	0x9394	# <CJK>
0xE850	0x93B9	# <CJK>
0xE851	0x93D6	# <CJK>
0xE852	0x93D7	# <CJK>
0xE853	0x93E8	# <CJK>
0xE854	0x93E5	# <CJK>
0xE855	0x93D8	# <CJK>
0xE856	0x93C3	# <CJK>
0xE857	0x93DD	# <CJK>
0xE858	0x93D0	# <CJK>
0xE859	0x93C8	# <CJK>
0xE85A	0x93E4	# <CJK>
0xE85B	0x941A	# <CJK>
0xE85C	0x9414	# <CJK>
0xE85D	0x9413	# <CJK>
0xE85E	0x9403	# <CJK>
0xE85F	0x9407	# <CJK>
0xE860	0x9410	# <CJK>
0xE861	0x9436	# <CJK>
0xE862	0x942B	# <CJK>
0xE863	0x9435	# <CJK>
0xE864	0x9421	# <CJK>
0xE865	0x943A	# <CJK>
0xE866	0x9441	# <CJK>
0xE867	0x9452	# <CJK>
0xE868	0x9444	# <CJK>
0xE869	0x945B	# <CJK>
0xE86A	0x9460	# <CJK>
0xE86B	0x9462	# <CJK>
0xE86C	0x945E	# <CJK>
0xE86D	0x946A	# <CJK>
0xE86E	0x9229	# <CJK>
0xE86F	0x9470	# <CJK>
0xE870	0x9475	# <CJK>
0xE871	0x9477	# <CJK>
0xE872	0x947D	# <CJK>
0xE873	0x945A	# <CJK>
0xE874	0x947C	# <CJK>
0xE875	0x947E	# <CJK>
0xE876	0x9481	# <CJK>
0xE877	0x947F	# <CJK>
0xE878	0x9582	# <CJK>
0xE879	0x9587	# <CJK>
0xE87A	0x958A	# <CJK>
0xE87B	0x9594	# <CJK>
0xE87C	0x9596	# <CJK>
0xE87D	0x9598	# <CJK>
0xE87E	0x9599	# <CJK>
0xE880	0x95A0	# <CJK>
0xE881	0x95A8	# <CJK>
0xE882	0x95A7	# <CJK>
0xE883	0x95AD	# <CJK>
0xE884	0x95BC	# <CJK>
0xE885	0x95BB	# <CJK>
0xE886	0x95B9	# <CJK>
0xE887	0x95BE	# <CJK>
0xE888	0x95CA	# <CJK>
0xE889	0x6FF6	# <CJK>
0xE88A	0x95C3	# <CJK>
0xE88B	0x95CD	# <CJK>
0xE88C	0x95CC	# <CJK>
0xE88D	0x95D5	# <CJK>
0xE88E	0x95D4	# <CJK>
0xE88F	0x95D6	# <CJK>
0xE890	0x95DC	# <CJK>
0xE891	0x95E1	# <CJK>
0xE892	0x95E5	# <CJK>
0xE893	0x95E2	# <CJK>
0xE894	0x9621	# <CJK>
0xE895	0x9628	# <CJK>
0xE896	0x962E	# <CJK>
0xE897	0x962F	# <CJK>
0xE898	0x9642	# <CJK>
0xE899	0x964C	# <CJK>
0xE89A	0x964F	# <CJK>
0xE89B	0x964B	# <CJK>
0xE89C	0x9677	# <CJK>
0xE89D	0x965C	# <CJK>
0xE89E	0x965E	# <CJK>
0xE89F	0x965D	# <CJK>
0xE8A0	0x965F	# <CJK>
0xE8A1	0x9666	# <CJK>
0xE8A2	0x9672	# <CJK>
0xE8A3	0x966C	# <CJK>
0xE8A4	0x968D	# <CJK>
0xE8A5	0x9698	# <CJK>
0xE8A6	0x9695	# <CJK>
0xE8A7	0x9697	# <CJK>
0xE8A8	0x96AA	# <CJK>
0xE8A9	0x96A7	# <CJK>
0xE8AA	0x96B1	# <CJK>
0xE8AB	0x96B2	# <CJK>
0xE8AC	0x96B0	# <CJK>
0xE8AD	0x96B4	# <CJK>
0xE8AE	0x96B6	# <CJK>
0xE8AF	0x96B8	# <CJK>
0xE8B0	0x96B9	# <CJK>
0xE8B1	0x96CE	# <CJK>
0xE8B2	0x96CB	# <CJK>
0xE8B3	0x96C9	# <CJK>
0xE8B4	0x96CD	# <CJK>
0xE8B5	0x894D	# <CJK>
0xE8B6	0x96DC	# <CJK>
0xE8B7	0x970D	# <CJK>
0xE8B8	0x96D5	# <CJK>
0xE8B9	0x96F9	# <CJK>
0xE8BA	0x9704	# <CJK>
0xE8BB	0x9706	# <CJK>
0xE8BC	0x9708	# <CJK>
0xE8BD	0x9713	# <CJK>
0xE8BE	0x970E	# <CJK>
0xE8BF	0x9711	# <CJK>
0xE8C0	0x970F	# <CJK>
0xE8C1	0x9716	# <CJK>
0xE8C2	0x9719	# <CJK>
0xE8C3	0x9724	# <CJK>
0xE8C4	0x972A	# <CJK>
0xE8C5	0x9730	# <CJK>
0xE8C6	0x9739	# <CJK>
0xE8C7	0x973D	# <CJK>
0xE8C8	0x973E	# <CJK>
0xE8C9	0x9744	# <CJK>
0xE8CA	0x9746	# <CJK>
0xE8CB	0x9748	# <CJK>
0xE8CC	0x9742	# <CJK>
0xE8CD	0x9749	# <CJK>
0xE8CE	0x975C	# <CJK>
0xE8CF	0x9760	# <CJK>
0xE8D0	0x9764	# <CJK>
0xE8D1	0x9766	# <CJK>
0xE8D2	0x9768	# <CJK>
0xE8D3	0x52D2	# <CJK>
0xE8D4	0x976B	# <CJK>
0xE8D5	0x9771	# <CJK>
0xE8D6	0x9779	# <CJK>
0xE8D7	0x9785	# <CJK>
0xE8D8	0x977C	# <CJK>
0xE8D9	0x9781	# <CJK>
0xE8DA	0x977A	# <CJK>
0xE8DB	0x9786	# <CJK>
0xE8DC	0x978B	# <CJK>
0xE8DD	0x978F	# <CJK>
0xE8DE	0x9790	# <CJK>
0xE8DF	0x979C	# <CJK>
0xE8E0	0x97A8	# <CJK>
0xE8E1	0x97A6	# <CJK>
0xE8E2	0x97A3	# <CJK>
0xE8E3	0x97B3	# <CJK>
0xE8E4	0x97B4	# <CJK>
0xE8E5	0x97C3	# <CJK>
0xE8E6	0x97C6	# <CJK>
0xE8E7	0x97C8	# <CJK>
0xE8E8	0x97CB	# <CJK>
0xE8E9	0x97DC	# <CJK>
0xE8EA	0x97ED	# <CJK>
0xE8EB	0x9F4F	# <CJK>
0xE8EC	0x97F2	# <CJK>
0xE8ED	0x7ADF	# <CJK>
0xE8EE	0x97F6	# <CJK>
0xE8EF	0x97F5	# <CJK>
0xE8F0	0x980F	# <CJK>
0xE8F1	0x980C	# <CJK>
0xE8F2	0x9838	# <CJK>
0xE8F3	0x9824	# <CJK>
0xE8F4	0x9821	# <CJK>
0xE8F5	0x9837	# <CJK>
0xE8F6	0x983D	# <CJK>
0xE8F7	0x9846	# <CJK>
0xE8F8	0x984F	# <CJK>
0xE8F9	0x984B	# <CJK>
0xE8FA	0x986B	# <CJK>
0xE8FB	0x986F	# <CJK>
0xE8FC	0x9870	# <CJK>
0xE940	0x9871	# <CJK>
0xE941	0x9874	# <CJK>
0xE942	0x9873	# <CJK>
0xE943	0x98AA	# <CJK>
0xE944	0x98AF	# <CJK>
0xE945	0x98B1	# <CJK>
0xE946	0x98B6	# <CJK>
0xE947	0x98C4	# <CJK>
0xE948	0x98C3	# <CJK>
0xE949	0x98C6	# <CJK>
0xE94A	0x98E9	# <CJK>
0xE94B	0x98EB	# <CJK>
0xE94C	0x9903	# <CJK>
0xE94D	0x9909	# <CJK>
0xE94E	0x9912	# <CJK>
0xE94F	0x9914	# <CJK>
0xE950	0x9918	# <CJK>
0xE951	0x9921	# <CJK>
0xE952	0x991D	# <CJK>
0xE953	0x991E	# <CJK>
0xE954	0x9924	# <CJK>
0xE955	0x9920	# <CJK>
0xE956	0x992C	# <CJK>
0xE957	0x992E	# <CJK>
0xE958	0x993D	# <CJK>
0xE959	0x993E	# <CJK>
0xE95A	0x9942	# <CJK>
0xE95B	0x9949	# <CJK>
0xE95C	0x9945	# <CJK>
0xE95D	0x9950	# <CJK>
0xE95E	0x994B	# <CJK>
0xE95F	0x9951	# <CJK>
0xE960	0x9952	# <CJK>
0xE961	0x994C	# <CJK>
0xE962	0x9955	# <CJK>
0xE963	0x9997	# <CJK>
0xE964	0x9998	# <CJK>
0xE965	0x99A5	# <CJK>
0xE966	0x99AD	# <CJK>
0xE967	0x99AE	# <CJK>
0xE968	0x99BC	# <CJK>
0xE969	0x99DF	# <CJK>
0xE96A	0x99DB	# <CJK>
0xE96B	0x99DD	# <CJK>
0xE96C	0x99D8	# <CJK>
0xE96D	0x99D1	# <CJK>
0xE96E	0x99ED	# <CJK>
0xE96F	0x99EE	# <CJK>
0xE970	0x99F1	# <CJK>
0xE971	0x99F2	# <CJK>
0xE972	0x99FB	# <CJK>
0xE973	0x99F8	# <CJK>
0xE974	0x9A01	# <CJK>
0xE975	0x9A0F	# <CJK>
0xE976	0x9A05	# <CJK>
0xE977	0x99E2	# <CJK>
0xE978	0x9A19	# <CJK>
0xE979	0x9A2B	# <CJK>
0xE97A	0x9A37	# <CJK>
0xE97B	0x9A45	# <CJK>
0xE97C	0x9A42	# <CJK>
0xE97D	0x9A40	# <CJK>
0xE97E	0x9A43	# <CJK>
0xE980	0x9A3E	# <CJK>
0xE981	0x9A55	# <CJK>
0xE982	0x9A4D	# <CJK>
0xE983	0x9A5B	# <CJK>
0xE984	0x9A57	# <CJK>
0xE985	0x9A5F	# <CJK>
0xE986	0x9A62	# <CJK>
0xE987	0x9A65	# <CJK>
0xE988	0x9A64	# <CJK>
0xE989	0x9A69	# <CJK>
0xE98A	0x9A6B	# <CJK>
0xE98B	0x9A6A	# <CJK>
0xE98C	0x9AAD	# <CJK>
0xE98D	0x9AB0	# <CJK>
0xE98E	0x9ABC	# <CJK>
0xE98F	0x9AC0	# <CJK>
0xE990	0x9ACF	# <CJK>
0xE991	0x9AD1	# <CJK>
0xE992	0x9AD3	# <CJK>
0xE993	0x9AD4	# <CJK>
0xE994	0x9ADE	# <CJK>
0xE995	0x9ADF	# <CJK>
0xE996	0x9AE2	# <CJK>
0xE997	0x9AE3	# <CJK>
0xE998	0x9AE6	# <CJK>
0xE999	0x9AEF	# <CJK>
0xE99A	0x9AEB	# <CJK>
0xE99B	0x9AEE	# <CJK>
0xE99C	0x9AF4	# <CJK>
0xE99D	0x9AF1	# <CJK>
0xE99E	0x9AF7	# <CJK>
0xE99F	0x9AFB	# <CJK>
0xE9A0	0x9B06	# <CJK>
0xE9A1	0x9B18	# <CJK>
0xE9A2	0x9B1A	# <CJK>
0xE9A3	0x9B1F	# <CJK>
0xE9A4	0x9B22	# <CJK>
0xE9A5	0x9B23	# <CJK>
0xE9A6	0x9B25	# <CJK>
0xE9A7	0x9B27	# <CJK>
0xE9A8	0x9B28	# <CJK>
0xE9A9	0x9B29	# <CJK>
0xE9AA	0x9B2A	# <CJK>
0xE9AB	0x9B2E	# <CJK>
0xE9AC	0x9B2F	# <CJK>
0xE9AD	0x9B32	# <CJK>
0xE9AE	0x9B44	# <CJK>
0xE9AF	0x9B43	# <CJK>
0xE9B0	0x9B4F	# <CJK>
0xE9B1	0x9B4D	# <CJK>
0xE9B2	0x9B4E	# <CJK>
0xE9B3	0x9B51	# <CJK>
0xE9B4	0x9B58	# <CJK>
0xE9B5	0x9B74	# <CJK>
0xE9B6	0x9B93	# <CJK>
0xE9B7	0x9B83	# <CJK>
0xE9B8	0x9B91	# <CJK>
0xE9B9	0x9B96	# <CJK>
0xE9BA	0x9B97	# <CJK>
0xE9BB	0x9B9F	# <CJK>
0xE9BC	0x9BA0	# <CJK>
0xE9BD	0x9BA8	# <CJK>
0xE9BE	0x9BB4	# <CJK>
0xE9BF	0x9BC0	# <CJK>
0xE9C0	0x9BCA	# <CJK>
0xE9C1	0x9BB9	# <CJK>
0xE9C2	0x9BC6	# <CJK>
0xE9C3	0x9BCF	# <CJK>
0xE9C4	0x9BD1	# <CJK>
0xE9C5	0x9BD2	# <CJK>
0xE9C6	0x9BE3	# <CJK>
0xE9C7	0x9BE2	# <CJK>
0xE9C8	0x9BE4	# <CJK>
0xE9C9	0x9BD4	# <CJK>
0xE9CA	0x9BE1	# <CJK>
0xE9CB	0x9C3A	# <CJK>
0xE9CC	0x9BF2	# <CJK>
0xE9CD	0x9BF1	# <CJK>
0xE9CE	0x9BF0	# <CJK>
0xE9CF	0x9C15	# <CJK>
0xE9D0	0x9C14	# <CJK>
0xE9D1	0x9C09	# <CJK>
0xE9D2	0x9C13	# <CJK>
0xE9D3	0x9C0C	# <CJK>
0xE9D4	0x9C06	# <CJK>
0xE9D5	0x9C08	# <CJK>
0xE9D6	0x9C12	# <CJK>
0xE9D7	0x9C0A	# <CJK>
0xE9D8	0x9C04	# <CJK>
0xE9D9	0x9C2E	# <CJK>
0xE9DA	0x9C1B	# <CJK>
0xE9DB	0x9C25	# <CJK>
0xE9DC	0x9C24	# <CJK>
0xE9DD	0x9C21	# <CJK>
0xE9DE	0x9C30	# <CJK>
0xE9DF	0x9C47	# <CJK>
0xE9E0	0x9C32	# <CJK>
0xE9E1	0x9C46	# <CJK>
0xE9E2	0x9C3E	# <CJK>
0xE9E3	0x9C5A	# <CJK>
0xE9E4	0x9C60	# <CJK>
0xE9E5	0x9C67	# <CJK>
0xE9E6	0x9C76	# <CJK>
0xE9E7	0x9C78	# <CJK>
0xE9E8	0x9CE7	# <CJK>
0xE9E9	0x9CEC	# <CJK>
0xE9EA	0x9CF0	# <CJK>
0xE9EB	0x9D09	# <CJK>
0xE9EC	0x9D08	# <CJK>
0xE9ED	0x9CEB	# <CJK>
0xE9EE	0x9D03	# <CJK>
0xE9EF	0x9D06	# <CJK>
0xE9F0	0x9D2A	# <CJK>
0xE9F1	0x9D26	# <CJK>
0xE9F2	0x9DAF	# <CJK>
0xE9F3	0x9D23	# <CJK>
0xE9F4	0x9D1F	# <CJK>
0xE9F5	0x9D44	# <CJK>
0xE9F6	0x9D15	# <CJK>
0xE9F7	0x9D12	# <CJK>
0xE9F8	0x9D41	# <CJK>
0xE9F9	0x9D3F	# <CJK>
0xE9FA	0x9D3E	# <CJK>
0xE9FB	0x9D46	# <CJK>
0xE9FC	0x9D48	# <CJK>
0xEA40	0x9D5D	# <CJK>
0xEA41	0x9D5E	# <CJK>
0xEA42	0x9D64	# <CJK>
0xEA43	0x9D51	# <CJK>
0xEA44	0x9D50	# <CJK>
0xEA45	0x9D59	# <CJK>
0xEA46	0x9D72	# <CJK>
0xEA47	0x9D89	# <CJK>
0xEA48	0x9D87	# <CJK>
0xEA49	0x9DAB	# <CJK>
0xEA4A	0x9D6F	# <CJK>
0xEA4B	0x9D7A	# <CJK>
0xEA4C	0x9D9A	# <CJK>
0xEA4D	0x9DA4	# <CJK>
0xEA4E	0x9DA9	# <CJK>
0xEA4F	0x9DB2	# <CJK>
0xEA50	0x9DC4	# <CJK>
0xEA51	0x9DC1	# <CJK>
0xEA52	0x9DBB	# <CJK>
0xEA53	0x9DB8	# <CJK>
0xEA54	0x9DBA	# <CJK>
0xEA55	0x9DC6	# <CJK>
0xEA56	0x9DCF	# <CJK>
0xEA57	0x9DC2	# <CJK>
0xEA58	0x9DD9	# <CJK>
0xEA59	0x9DD3	# <CJK>
0xEA5A	0x9DF8	# <CJK>
0xEA5B	0x9DE6	# <CJK>
0xEA5C	0x9DED	# <CJK>
0xEA5D	0x9DEF	# <CJK>
0xEA5E	0x9DFD	# <CJK>
0xEA5F	0x9E1A	# <CJK>
0xEA60	0x9E1B	# <CJK>
0xEA61	0x9E1E	# <CJK>
0xEA62	0x9E75	# <CJK>
0xEA63	0x9E79	# <CJK>
0xEA64	0x9E7D	# <CJK>
0xEA65	0x9E81	# <CJK>
0xEA66	0x9E88	# <CJK>
0xEA67	0x9E8B	# <CJK>
0xEA68	0x9E8C	# <CJK>
0xEA69	0x9E92	# <CJK>
0xEA6A	0x9E95	# <CJK>
0xEA6B	0x9E91	# <CJK>
0xEA6C	0x9E9D	# <CJK>
0xEA6D	0x9EA5	# <CJK>
0xEA6E	0x9EA9	# <CJK>
0xEA6F	0x9EB8	# <CJK>
0xEA70	0x9EAA	# <CJK>
0xEA71	0x9EAD	# <CJK>
0xEA72	0x9761	# <CJK>
0xEA73	0x9ECC	# <CJK>
0xEA74	0x9ECE	# <CJK>
0xEA75	0x9ECF	# <CJK>
0xEA76	0x9ED0	# <CJK>
0xEA77	0x9ED4	# <CJK>
0xEA78	0x9EDC	# <CJK>
0xEA79	0x9EDE	# <CJK>
0xEA7A	0x9EDD	# <CJK>
0xEA7B	0x9EE0	# <CJK>
0xEA7C	0x9EE5	# <CJK>
0xEA7D	0x9EE8	# <CJK>
0xEA7E	0x9EEF	# <CJK>
0xEA80	0x9EF4	# <CJK>
0xEA81	0x9EF6	# <CJK>
0xEA82	0x9EF7	# <CJK>
0xEA83	0x9EF9	# <CJK>
0xEA84	0x9EFB	# <CJK>
0xEA85	0x9EFC	# <CJK>
0xEA86	0x9EFD	# <CJK>
0xEA87	0x9F07	# <CJK>
0xEA88	0x9F08	# <CJK>
0xEA89	0x76B7	# <CJK>
0xEA8A	0x9F15	# <CJK>
0xEA8B	0x9F21	# <CJK>
0xEA8C	0x9F2C	# <CJK>
0xEA8D	0x9F3E	# <CJK>
0xEA8E	0x9F4A	# <CJK>
0xEA8F	0x9F52	# <CJK>
0xEA90	0x9F54	# <CJK>
0xEA91	0x9F63	# <CJK>
0xEA92	0x9F5F	# <CJK>
0xEA93	0x9F60	# <CJK>
0xEA94	0x9F61	# <CJK>
0xEA95	0x9F66	# <CJK>
0xEA96	0x9F67	# <CJK>
0xEA97	0x9F6C	# <CJK>
0xEA98	0x9F6A	# <CJK>
0xEA99	0x9F77	# <CJK>
0xEA9A	0x9F72	# <CJK>
0xEA9B	0x9F76	# <CJK>
0xEA9C	0x9F95	# <CJK>
0xEA9D	0x9F9C	# <CJK>
0xEA9E	0x9FA0	# <CJK>
0xEA9F	0x582F	# <CJK>
0xEAA0	0x69C7	# <CJK>
0xEAA1	0x9059	# <CJK>
0xEAA2	0x7464	# <CJK>
0xEAA3	0x51DC	# <CJK>
0xEAA4	0x7199	# <CJK>

Added tools/encoding/symbol.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
#
#   Name:             MacOS_Symbol [to Unicode]
#   Unicode versions: 1.1, 2.0
#   Table version:    0.2 (from internal ufrm version <4>)
#   Date:             15 April 1995
#   Author:           Peter Edberg <[email protected]>
#
#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
#
#   Apple, the Apple logo, and Macintosh are trademarks of Apple
#   Computer, Inc., registered in the United States and other countries.
#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
#   throughout this document, "Macintosh" can be used to refer to
#   Macintosh computers and "Unicode" can be used to refer to the
#   Unicode standard.
#
#   Apple makes no warranty or representation, either express or
#   implied, with respect to these tables, their quality, accuracy, or
#   fitness for a particular purpose. In no event will Apple be liable
#   for direct, indirect, special, incidental, or consequential damages
#   resulting from any defect or inaccuracy in this document or the
#   accompanying tables.
#
#   These mapping tables and character lists are preliminary and
#   subject to change. Updated tables will be available from the
#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
#   (http://www.info.apple.com), and possibly on diskette from APDA
#   (Apple's mail-order distribution service for developers).
#
#   Format:
#   -------
#
#   Three tab-separated columns;
#   '#' begins a comment which continues to the end of the line.
#     Column #1 is the MacOS Symbol code (in hex as 0xNN)
#     Column #2 is the Unicode (in hex as 0xNNNN)
#     Column #3 is the Unicode name (follows a comment sign, '#')
#
#   The entries are in MacOS Symbol code order.
#
#   Several of these mappings require the use of corporate
#   characters, including the Apple logo character. See the file
#   "MacOS-CorpCharList".
#   NOTE: The graphic image associated with the Apple logo character
#   is not authorized for use without permission of Apple, and
#   unauthorized use might constitute trademark infringement.
#
#   Notes on MacOS Symbol:
#   ----------------------
#
#   The MacOS Symbol encoding shares the script code smRoman
#   (0) with the standard MacOS Roman encoding. To determine if
#   the Symbol encoding is being used, you must check if the
#   font name is "Symbol".
#
#   The layout of the MacOS Symbol character set is identical to
#   the layout of the Adobe Symbol encoding vector, with the
#   addition of the Apple logo character at 0xF0.
#
#   This character set encodes a number of glyph fragments. Some are
#   used as extenders: 0x60 is used to extend radical signs, 0xBD and
#   0xBE are used to extend vertical and horizontal arrows, etc. In
#   addition, there are top, bottom, and center sections for
#   parentheses, brackets, integral signs, and other signs that may
#   extend vertically for 2 or more lines of normal text. In general,
#   Unicode does not encode such fragments, so corporate characters
#   are used for round-trip fidelity.
#
#   In addition, Symbol separately encodes both serif and sans-serif
#   forms for copyright, trademark, and registered signs. Unicode
#   encodes only the abstract characters, so one set of these (the
#   sans-serif forms) are mapped using corporate characters.
#
##################

0x20	0x0020	# SPACE
0x21	0x0021	# EXCLAMATION MARK
0x22	0x2200	# FOR ALL
0x23	0x0023	# NUMBER SIGN
0x24	0x2203	# THERE EXISTS
0x25	0x0025	# PERCENT SIGN
0x26	0x0026	# AMPERSAND
0x27	0x220D	# SMALL CONTAINS AS MEMBER
0x28	0x0028	# LEFT PARENTHESIS
0x29	0x0029	# RIGHT PARENTHESIS
0x2A	0x2217	# ASTERISK OPERATOR
0x2B	0x002B	# PLUS SIGN
0x2C	0x002C	# COMMA
0x2D	0x2212	# MINUS SIGN
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	0x2245	# APPROXIMATELY EQUAL TO
0x41	0x0391	# GREEK CAPITAL LETTER ALPHA
0x42	0x0392	# GREEK CAPITAL LETTER BETA
0x43	0x03A7	# GREEK CAPITAL LETTER CHI
0x44	0x0394	# GREEK CAPITAL LETTER DELTA
0x45	0x0395	# GREEK CAPITAL LETTER EPSILON
0x46	0x03A6	# GREEK CAPITAL LETTER PHI
0x47	0x0393	# GREEK CAPITAL LETTER GAMMA
0x48	0x0397	# GREEK CAPITAL LETTER ETA
0x49	0x0399	# GREEK CAPITAL LETTER IOTA
0x4A	0x03D1	# GREEK THETA SYMBOL
0x4B	0x039A	# GREEK CAPITAL LETTER KAPPA
0x4C	0x039B	# GREEK CAPITAL LETTER LAMBDA
0x4D	0x039C	# GREEK CAPITAL LETTER MU
0x4E	0x039D	# GREEK CAPITAL LETTER NU
0x4F	0x039F	# GREEK CAPITAL LETTER OMICRON
0x50	0x03A0	# GREEK CAPITAL LETTER PI
0x51	0x0398	# GREEK CAPITAL LETTER THETA
0x52	0x03A1	# GREEK CAPITAL LETTER RHO
0x53	0x03A3	# GREEK CAPITAL LETTER SIGMA
0x54	0x03A4	# GREEK CAPITAL LETTER TAU
0x55	0x03A5	# GREEK CAPITAL LETTER UPSILON
0x56	0x03C2	# GREEK SMALL LETTER FINAL SIGMA
0x57	0x03A9	# GREEK CAPITAL LETTER OMEGA
0x58	0x039E	# GREEK CAPITAL LETTER XI
0x59	0x03A8	# GREEK CAPITAL LETTER PSI
0x5A	0x0396	# GREEK CAPITAL LETTER ZETA
0x5B	0x005B	# LEFT SQUARE BRACKET
0x5C	0x2234	# THEREFORE
0x5D	0x005D	# RIGHT SQUARE BRACKET
0x5E	0x22A5	# UP TACK
0x5F	0x005F	# LOW LINE
0x60	0xF8E5	# radical extender
0x61	0x03B1	# GREEK SMALL LETTER ALPHA
0x62	0x03B2	# GREEK SMALL LETTER BETA
0x63	0x03C7	# GREEK SMALL LETTER CHI
0x64	0x03B4	# GREEK SMALL LETTER DELTA
0x65	0x03B5	# GREEK SMALL LETTER EPSILON
0x66	0x03C6	# GREEK SMALL LETTER PHI
0x67	0x03B3	# GREEK SMALL LETTER GAMMA
0x68	0x03B7	# GREEK SMALL LETTER ETA
0x69	0x03B9	# GREEK SMALL LETTER IOTA
0x6A	0x03D5	# GREEK PHI SYMBOL
0x6B	0x03BA	# GREEK SMALL LETTER KAPPA
0x6C	0x03BB	# GREEK SMALL LETTER LAMBDA
0x6D	0x03BC	# GREEK SMALL LETTER MU
0x6E	0x03BD	# GREEK SMALL LETTER NU
0x6F	0x03BF	# GREEK SMALL LETTER OMICRON
0x70	0x03C0	# GREEK SMALL LETTER PI
0x71	0x03B8	# GREEK SMALL LETTER THETA
0x72	0x03C1	# GREEK SMALL LETTER RHO
0x73	0x03C3	# GREEK SMALL LETTER SIGMA
0x74	0x03C4	# GREEK SMALL LETTER TAU
0x75	0x03C5	# GREEK SMALL LETTER UPSILON
0x76	0x03D6	# GREEK PI SYMBOL
0x77	0x03C9	# GREEK SMALL LETTER OMEGA
0x78	0x03BE	# GREEK SMALL LETTER XI
0x79	0x03C8	# GREEK SMALL LETTER PSI
0x7A	0x03B6	# GREEK SMALL LETTER ZETA
0x7B	0x007B	# LEFT CURLY BRACKET
0x7C	0x007C	# VERTICAL LINE
0x7D	0x007D	# RIGHT CURLY BRACKET
0x7E	0x223C	# TILDE OPERATOR
0xA1	0x03D2	# GREEK UPSILON WITH HOOK SYMBOL
0xA2	0x2032	# PRIME
0xA3	0x2264	# LESS-THAN OR EQUAL TO
0xA4	0x2044	# FRACTION SLASH
0xA5	0x221E	# INFINITY
0xA6	0x0192	# LATIN SMALL LETTER F WITH HOOK
0xA7	0x2663	# BLACK CLUB SUIT
0xA8	0x2666	# BLACK DIAMOND SUIT
0xA9	0x2665	# BLACK HEART SUIT
0xAA	0x2660	# BLACK SPADE SUIT
0xAB	0x2194	# LEFT RIGHT ARROW
0xAC	0x2190	# LEFTWARDS ARROW
0xAD	0x2191	# UPWARDS ARROW
0xAE	0x2192	# RIGHTWARDS ARROW
0xAF	0x2193	# DOWNWARDS ARROW
0xB0	0x00B0	# DEGREE SIGN
0xB1	0x00B1	# PLUS-MINUS SIGN
0xB2	0x2033	# DOUBLE PRIME
0xB3	0x2265	# GREATER-THAN OR EQUAL TO
0xB4	0x00D7	# MULTIPLICATION SIGN
0xB5	0x221D	# PROPORTIONAL TO
0xB6	0x2202	# PARTIAL DIFFERENTIAL
0xB7	0x2022	# BULLET
0xB8	0x00F7	# DIVISION SIGN
0xB9	0x2260	# NOT EQUAL TO
0xBA	0x2261	# IDENTICAL TO
0xBB	0x2248	# ALMOST EQUAL TO
0xBC	0x2026	# HORIZONTAL ELLIPSIS
0xBD	0xF8E6	# vertical arrow extender
0xBE	0xF8E7	# horizontal arrow extender
0xBF	0x21B5	# DOWNWARDS ARROW WITH CORNER LEFTWARDS
0xC0	0x2135	# ALEF SYMBOL
0xC1	0x2111	# BLACK-LETTER CAPITAL I
0xC2	0x211C	# BLACK-LETTER CAPITAL R
0xC3	0x2118	# SCRIPT CAPITAL P
0xC4	0x2297	# CIRCLED TIMES
0xC5	0x2295	# CIRCLED PLUS
0xC6	0x2205	# EMPTY SET
0xC7	0x2229	# INTERSECTION
0xC8	0x222A	# UNION
0xC9	0x2283	# SUPERSET OF
0xCA	0x2287	# SUPERSET OF OR EQUAL TO
0xCB	0x2284	# NOT A SUBSET OF
0xCC	0x2282	# SUBSET OF
0xCD	0x2286	# SUBSET OF OR EQUAL TO
0xCE	0x2208	# ELEMENT OF
0xCF	0x2209	# NOT AN ELEMENT OF
0xD0	0x2220	# ANGLE
0xD1	0x2207	# NABLA
0xD2	0x00AE	# REGISTERED SIGN
0xD3	0x00A9	# COPYRIGHT SIGN
0xD4	0x2122	# TRADE MARK SIGN
0xD5	0x220F	# N-ARY PRODUCT
0xD6	0x221A	# SQUARE ROOT
0xD7	0x22C5	# DOT OPERATOR
0xD8	0x00AC	# NOT SIGN
0xD9	0x2227	# LOGICAL AND
0xDA	0x2228	# LOGICAL OR
0xDB	0x21D4	# LEFT RIGHT DOUBLE ARROW
0xDC	0x21D0	# LEFTWARDS DOUBLE ARROW
0xDD	0x21D1	# UPWARDS DOUBLE ARROW
0xDE	0x21D2	# RIGHTWARDS DOUBLE ARROW
0xDF	0x21D3	# DOWNWARDS DOUBLE ARROW
0xE0	0x22C4	# DIAMOND OPERATOR
0xE1	0x2329	# LEFT-POINTING ANGLE BRACKET
0xE2	0xF8E8	# registered sign sans serif
0xE3	0xF8E9	# copyright sign sans serif
0xE4	0xF8EA	# trade mark sign sans serif
0xE5	0x2211	# N-ARY SUMMATION
0xE6	0xF8EB	# left paren top
0xE7	0xF8EC	# left paren extender
0xE8	0xF8ED	# left paren bottom
0xE9	0xF8EE	# left square bracket top
0xEA	0xF8EF	# left square bracket extender
0xEB	0xF8F0	# left square bracket bottom
0xEC	0xF8F1	# left curly bracket top
0xED	0xF8F2	# left curly bracket mid
0xEE	0xF8F3	# left curly bracket bottom
0xEF	0xF8F4	# curly bracket extender
0xF0	0xF8FF	# Apple logo
0xF1	0x232A	# RIGHT-POINTING ANGLE BRACKET
0xF2	0x222B	# INTEGRAL
0xF3	0x2320	# TOP HALF INTEGRAL
0xF4	0xF8F5	# integral extender
0xF5	0x2321	# BOTTOM HALF INTEGRAL
0xF6	0xF8F6	# right paren top
0xF7	0xF8F7	# right paren extender
0xF8	0xF8F8	# right paren bottom
0xF9	0xF8F9	# right square bracket top
0xFA	0xF8FA	# right square bracket extender
0xFB	0xF8FB	# right square bracket bottom
0xFC	0xF8FC	# right curly bracket top
0xFD	0xF8FD	# right curly bracket mid
0xFE	0xF8FE	# right curly bracket bottom

Added tools/encoding/txt2enc.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
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
/*
 * txt2enc.c --
 *
 *	Simple program to compile up the encodings tables from the CD that
 *	came with "The Unicode Standard, Version 2.0" into a form that can
 *	be quickly loaded into Tcl.
 *
 * 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.
 *
 * SCCS: @(#) txt2enc.c 1.1 98/01/28 11:42:09
 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>

typedef unsigned short Rune;

int
main(int argc, char **argv)
{
    FILE *fp;
    Rune *toUnicode[256];
    int i, multiByte, enc, uni, hi, lo, fixmissing, used, maxEnc;
    int ch, encColumn, uniColumn, fallbackKnown, width;
    char *fallbackString, *str, *rest, *dot;
    unsigned int magic, type, symbol, fallbackChar;
    Rune rune;
    char buf[256];
    extern char *optarg;
    extern int optind, opterr;
    static char *typeString[] = {"single", "double", "multi"};

    encColumn = 0;
    uniColumn = 1;
    fallbackString = "QUESTION MARK";
    fallbackChar = '\0';
    fallbackKnown = 0;
    type = -1;
    symbol = 0;
    fixmissing = 1;

    opterr = 0;
    while (1) {
	ch = getopt(argc, argv, "e:u:f:t:sm");
	if (ch == -1) {
	    break;
	}
	switch (ch) {
	case 'e':
	    encColumn = atoi(optarg);
	    break;

	case 'u':
	    uniColumn = atoi(optarg);
	    break;

	case 'f':
	    fallbackKnown = 1;
	    if (optarg[1] == '\0') {
		fallbackChar = optarg[0];
	    } else  {
		fallbackChar = strtol(optarg, &rest, 16);
		if (*rest != '\0') {
		    fallbackChar = '\0';
		    fallbackKnown = 0;
		    fallbackString = optarg;
		}
	    }

	case 't':
	    if (strcmp(optarg, "single") == 0) {
		type = 0;
	    } else if (strcmp(optarg, "double") == 0) {
		type = 1;
	    } else if (strcmp(optarg, "multi") == 0) {
		type = 2;
	    } else {
		goto usage;
	    }
	    break;

	case 's':
	    symbol = 1;
	    break;

	case 'm':
	    fixmissing = 0;
	    break;
	    
	default:
	    goto usage;
	}
    }

    if ((optind < argc - 1) || (optind >= argc)) {
	usage:
	fputs("usage: mkencoding [-e column] [-u column] [-f fallback] [-t type] [-s] [-m] file\n", stderr);
	fputs("    -e\tcolumn containing characters in encoding (default: 0)\n", stderr);
	fputs("    -u\tcolumn containing characters in Unicode (default: 1)\n", stderr);
	fputs("    -f\tfallback character (default: QUESTION MARK)\n", stderr);
	fputs("    -t\toverride implicit type with single, double, or multi\n", stderr);
	fputs("    -s\tsymbol+ascii encoding\n", stderr);
	fputs("    -m\tdon't implicitly include range 0080 to 00FF\n", stderr);
	return 1;
    }

    fp = fopen(argv[argc - 1], "r");
    if (fp == NULL) {
        perror(argv[argc - 1]);
	return 1;
    }

    for (i = 0; i < 256; i++) {
        toUnicode[i] = NULL;
    }

    maxEnc = 0;
    width = 0;
    multiByte = 0;
    while (fgets(buf, sizeof(buf), fp) != NULL) {
	str = buf;
	enc = -1;
	uni = -1;
	while (isspace(*str)) {
	    str++;
	}
	if (str[0] == '#') {
	    continue;
	}
	for (i = 0; *str != '\0'; i++) {
	    if (*str == '#') {
		if (fallbackKnown == 0) {
		    str++;
		    while (isspace(*str)) {
			str++;
		    }
		    str[strlen(str) - 1] = '\0';
		    if (strcmp(str, fallbackString) == 0) {
			fallbackChar = enc;
			fallbackKnown = 1;
		    } else if (strstr(str, fallbackString) != NULL) {
			fallbackChar = enc;
		    }
		}
		break;
	    } else {
		rune = strtol(str, &rest, 16);
		if (rest == str) {
		    rest++;
		} else if (i == uniColumn) {
		    uni = rune;
		} else if (i == encColumn) {
		    enc = rune;
		    if ((width != 0) && (width != rest - str)) {
			multiByte = 1;
		    }
		    width = rest - str;
		    if (enc > maxEnc) {
			maxEnc = enc;
		    }
		}
	    }
	    while (isspace(*rest)) {
		rest++;
	    }
	    str = rest;
	}
	if (enc < 32 || uni < 32) {
	    continue;
	}
	
	hi = enc >> 8;
	lo = enc & 0xff;
	if (toUnicode[hi] == NULL) {
	    toUnicode[hi] = (Rune *) malloc(256 * sizeof(Rune));
	    memset(toUnicode[hi], 0, 256 * sizeof(Rune));
	}
	toUnicode[hi][lo] = uni;
    }
	
    fclose(fp);

    dot = strrchr(argv[argc - 1], '.');
    if (dot != NULL) {
	*dot = '\0';
    }
    if (type == -1) {
	if (multiByte) {
	    type = 2;
	} else if (maxEnc > 255) {
	    type = 1;
	} else {
	    type = 0;
	}
    }
    if (type != 1) {
	if (toUnicode[0] == NULL) {
	    toUnicode[0] = (Rune *) malloc(256 * sizeof(Rune));
	    memset(toUnicode[0], 0, 256 * sizeof(Rune));
	}
	for (i = 0; i < 0x20; i++) {
	    toUnicode[0][i] = i;
	}
	if (fixmissing) {
	    for (i = 0x7F; i < 0xa0; i++) {
		if (toUnicode[i] == NULL && toUnicode[0][i] == 0) {
		    toUnicode[0][i] = i;
		}
	    }
	}
    }

    printf("# Encoding file: %s, %s-byte\n", argv[argc - 1], typeString[type]);

    if (fallbackChar == '\0') {
	fallbackChar = '?';
    }
    used = 0;
    for (hi = 0; hi < 256; hi++) {
	if (toUnicode[hi] != NULL) {
	    used++;
	}
    }
    printf("%c\n%04X %d %d\n", "SDM"[type], fallbackChar, symbol, used);
    
    for (hi = 0; hi < 256; hi++) {
	if (toUnicode[hi] != NULL) {
	    printf("%02X\n", hi);
	    for (lo = 0; lo < 256; lo++) {
		printf("%04X", toUnicode[hi][lo]);
		if ((lo & 0x0f) == 0x0f) {
		    putchar('\n');
		}
	    }
	}
    }
    return 0;
}

Added tools/genStubs.tcl.



























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
# 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.2.2.4 1999/04/01 21:52:57 redman 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.

    variable libraryName "UNKNOWN"

    # interfaces --
    #
    #	An array indexed by interface name that is used to maintain
    #   the set of valid interfaces.  The value is empty.

    array set interfaces {}

    # curName --
    #
    #	The name of the interface currently being defined.

    variable curName "UNKNOWN"

    # hooks --
    #
    #	An array indexed by interface name that contains the set of
    #	subinterfaces that should be defined for a given interface.

    array set hooks {}

    # stubs --
    #
    #	This three dimensional array is indexed first by interface name,
    #	second by platform name, and third by a numeric offset or the
    #	constant "lastNum".  The lastNum entry contains the largest
    #	numeric offset used for a given interface/platform combo.  Each
    #	numeric offset contains the C function specification that
    #	should be used for the given entry in the stub table.  The spec
    #	consists of a list in the form returned by parseDecl.

    array set stubs {}

    # outDir --
    #
    #	The directory where the generated files should be placed.

    variable outDir .
}

# genStubs::library --
#
#	This function is used in the declarations file to set the name
#	of the library that the interfaces are associated with (e.g. "tcl").
#	This value will be used to define the inline conditional macro.
#
# Arguments:
#	name	The library name.
#
# Results:
#	None.

proc genStubs::library {name} {
    variable libraryName $name
}

# genStubs::interface --
#
#	This function is used in the declarations file to set the name
#	of the interface currently being defined.
#
# Arguments:
#	name	The name of the interface.
#
# Results:
#	None.

proc genStubs::interface {name} {
    variable curName $name
    variable interfaces

    set interfaces($name) {}
    return
}

# genStubs::hooks --
#
#	This function defines the subinterface hooks for the current
#	interface.
#
# Arguments:
#	names	The ordered list of interfaces that are reachable through the
#		hook vector.
#
# Results:
#	None.

proc genStubs::hooks {names} {
    variable curName
    variable hooks

    set hooks($curName) $names
    return
}

# genStubs::declare --
#
#	This function is used in the declarations file to declare a new
#	interface entry.
#
# Arguments:
#	index		The index number of the interface.
#	platform	The platform the interface belongs to.  Should be one
#			of generic, win, unix, or mac.
#	decl		The C function declaration, or {} for an undefined
#			entry.
#
# Results:
#	None.

proc genStubs::declare {args} {
    variable stubs
    variable curName

    if {[llength $args] != 3} {
	puts stderr "wrong # args: declare $args"
    }
    lassign $args index platform decl

    # Check for duplicate declarations, then add the declaration and
    # bump the lastNum counter if necessary.

    if {[info exists stubs($curName,$platform,$index)]} {
	puts stderr "Duplicate entry: declare $args"
    }
    regsub -all "\[ \t\n\]+" [string trim $decl] " " decl
    set decl [parseDecl $decl]
    if {$decl != ""} {
	set stubs($curName,$platform,$index) $decl
	if {![info exists stubs($curName,$platform,lastNum)] \
		|| ($index > $stubs($curName,$platform,lastNum))} {
	    set stubs($curName,$platform,lastNum) $index
	}
    }
    return
}

# genStubs::rewriteFile --
#
#	This function replaces the machine generated portion of the
#	specified file with new contents.  It looks for the !BEGIN! and
#	!END! comments to determine where to place the new text.
#
# Arguments:
#	file	The name of the file to modify.
#	text	The new text to place in the file.
#
# Results:
#	None.

proc genStubs::rewriteFile {file text} {
    if {![file exist $file]} {
	puts stderr "Cannot find file: $file"
	return
    }
    set in [open ${file} r]
    set out [open ${file}.new w]

    while {![eof $in]} {
	set line [gets $in]
	if {[regexp {!BEGIN!} $line]} {
	    break
	}
	puts $out $line
    }
    puts $out "/* !BEGIN!: Do not edit below this line. */"
    puts $out $text
    while {![eof $in]} {
	set line [gets $in]
	if {[regexp {!END!} $line]} {
	    break
	}
    }
    puts $out "/* !END!: Do not edit above this line. */"
    puts -nonewline $out [read $in]
    close $in
    close $out
    file rename -force ${file}.new ${file}
    return
}

# genStubs::addPlatformGuard --
#
#	Wrap a string inside a platform #ifdef.
#
# Arguments:
#	plat	Platform to test.
#
# Results:
#	Returns the original text inside an appropriate #ifdef.

proc genStubs::addPlatformGuard {plat text} {
    switch $plat {
	win {
	    return "#ifdef __WIN32__\n${text}#endif /* __WIN32__ */\n"
	}
	unix {
	    return "#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */\n${text}#endif /* UNIX */\n"
	}		    
	mac {
	    return "#ifdef MAC_TCL\n${text}#endif /* MAC_TCL */\n"
	}
    }
    return "$text"
}

# genStubs::emitSlots --
#
#	Generate the stub table slots for the given interface.  If there
#	are no generic slots, then one table is generated for each
#	platform, otherwise one table is generated for all platforms.
#
# Arguments:
#	name	The name of the interface being emitted.
#	textVar	The variable to use for output.
#
# Results:
#	None.

proc genStubs::emitSlots {name textVar} {
    variable stubs
    upvar $textVar text

    forAllStubs $name makeSlot 1 text {"    void *reserved$i;\n"}
    return
}

# genStubs::parseDecl --
#
#	Parse a C function declaration into its component parts.
#
# Arguments:
#	decl	The function declaration.
#
# Results:
#	Returns a list of the form {returnType name args}.  The args
#	element consists of a list of type/name pairs, or a single
#	element "void".  If the function declaration is malformed
#	then an error is displayed and the return value is {}.

proc genStubs::parseDecl {decl} {
    if {![regexp {^(.*)\((.*)\)$} $decl all prefix args]} {
	puts stderr "Malformed declaration: $decl"
	return
    }
    set prefix [string trim $prefix]
    if {![regexp {^(.+[ ][*]*)([^ *]+)$} $prefix all rtype fname]} {
	puts stderr "Bad return type: $decl"
	return
    }
    set rtype [string trim $rtype]
    foreach arg [split $args ,] {
	lappend argList [string trim $arg]
    }
    if {![string compare [lindex $argList end] "..."]} {
	if {[llength $argList] != 2} {
	    puts stderr "Only one argument is allowed in varargs form: $decl"
	}
	set arg [parseArg [lindex $argList 0]]
	if {$arg == "" || ([llength $arg] != 2)} {
	    puts stderr "Bad argument: '[lindex $argList 0]' in '$decl'"
	    return
	}
	set args [list TCL_VARARGS $arg]
    } else {
	set args {}
	foreach arg $argList {
	    set argInfo [parseArg $arg]
	    if {![string compare $argInfo "void"]} {
		lappend args "void"
		break
	    } elseif {[llength $argInfo] == 2 || [llength $argInfo] == 3} {
		lappend args $argInfo
	    } else {
		puts stderr "Bad argument: '$arg' in '$decl'"
		return
	    }
	}
    }
    return [list $rtype $fname $args]
}

# genStubs::parseArg --
#
#	This function parses a function argument into a type and name.
#
# Arguments:
#	arg	The argument to parse.
#
# Results:
#	Returns a list of type and name with an optional third array
#	indicator.  If the argument is malformed, returns "".

proc genStubs::parseArg {arg} {
    if {![regexp {^(.+[ ][*]*)([^][ *]+)(\[\])?$} $arg all type name array]} {
	if {$arg == "void"} {
	    return $arg
	} else {
	    return
	}
    }
    set result [list [string trim $type] $name]
    if {$array != ""} {
	lappend result $array
    }
    return $result
}

# genStubs::makeDecl --
#
#	Generate the prototype for a function.
#
# Arguments:
#	name	The interface name.
#	decl	The function declaration.
#	index	The slot index for this function.
#
# Results:
#	Returns the formatted declaration string.

proc genStubs::makeDecl {name decl index} {
    lassign $decl rtype fname args

    append text "/* $index */\n"
    set line "EXTERN $rtype"
    set count [expr {2 - ([string length $line] / 8)}]
    append line [string range "\t\t\t" 0 $count]
    set pad [expr {24 - [string length $line]}]
    if {$pad <= 0} {
	append line " "
	set pad 0
    }
    append line "$fname _ANSI_ARGS_("

    set arg1 [lindex $args 0]
    switch -exact $arg1 {
	void {
	    append line "(void)"
	}
	TCL_VARARGS {
	    set arg [lindex $args 1]
	    append line "TCL_VARARGS([lindex $arg 0],[lindex $arg 1])"
	}
	default {
	    set sep "("
	    foreach arg $args {
		append line $sep
		set next {}
		append next [lindex $arg 0] " " [lindex $arg 1] \
			[lindex $arg 2]
		if {[string length $line] + [string length $next] \
			+ $pad > 76} {
		    append text $line \n
		    set line "\t\t\t\t"
		    set pad 28
		}
		append line $next
		set sep ", "
	    }
	    append line ")"
	}
    }
    append text $line
    
    append text ");\n"
    return $text
}

# genStubs::makeMacro --
#
#	Generate the inline macro for a function.
#
# Arguments:
#	name	The interface name.
#	decl	The function declaration.
#	index	The slot index for this function.
#
# Results:
#	Returns the formatted macro definition.

proc genStubs::makeMacro {name decl index} {
    lassign $decl rtype fname args

    set lfname [string tolower [string index $fname 0]]
    append lfname [string range $fname 1 end]

    set text "#ifndef $fname\n#define $fname"
    set arg1 [lindex $args 0]
    set argList ""
    switch -exact $arg1 {
	void {
	    set argList "()"
	}
	TCL_VARARGS {
	}
	default {
	    set sep "("
	    foreach arg $args {
		append argList $sep [lindex $arg 1]
		set sep ", "
	    }
	    append argList ")"
	}
    }
    append text " \\\n\t(${name}StubsPtr->$lfname)"
    append text " /* $index */\n#endif\n"
    return $text
}

# genStubs::makeStub --
#
#	Emits a stub function definition.
#
# Arguments:
#	name	The interface name.
#	decl	The function declaration.
#	index	The slot index for this function.
#
# Results:
#	Returns the formatted stub function definition.

proc genStubs::makeStub {name decl index} {
    lassign $decl rtype fname args

    set lfname [string tolower [string index $fname 0]]
    append lfname [string range $fname 1 end]

    append text "/* Slot $index */\n" $rtype "\n" $fname

    set arg1 [lindex $args 0]

    if {![string compare $arg1 "TCL_VARARGS"]} {
	lassign [lindex $args 1] type argName 
	append text " TCL_VARARGS_DEF($type,$argName)\n\{\n"
	append text "    " $type " var;\n    va_list argList;\n"
	if {[string compare $rtype "void"]} {
	    append text "    " $rtype " resultValue;\n"
	}
	append text "\n    var = (" $type ") TCL_VARARGS_START(" \
		$type "," $argName ",argList);\n\n    "
	if {[string compare $rtype "void"]} {
	    append text "resultValue = "
	}
	append text "(" $name "StubsPtr->" $lfname "VA)(var, argList);\n"
	append text "    va_end(argList);\n"
	if {[string compare $rtype "void"]} {
	    append text "return resultValue;\n"
	}
	append text "\}\n\n"
	return $text
    }

    if {![string compare $arg1 "void"]} {
	set argList "()"
	set argDecls ""
    } else {
	set argList ""
	set sep "("
	foreach arg $args {
	    append argList $sep [lindex $arg 1]
	    append argDecls "    " [lindex $arg 0] " " \
		    [lindex $arg 1] [lindex $arg 2] ";\n"
	    set sep ", "
	}
	append argList ")"
    }
    append text $argList "\n" $argDecls "{\n    "
    if {[string compare $rtype "void"]} {
	append text "return "
    }
    append text "(" $name "StubsPtr->" $lfname ")" $argList ";\n}\n\n"
    return $text
}

# genStubs::makeSlot --
#
#	Generate the stub table entry for a function.
#
# Arguments:
#	name	The interface name.
#	decl	The function declaration.
#	index	The slot index for this function.
#
# Results:
#	Returns the formatted table entry.

proc genStubs::makeSlot {name decl index} {
    lassign $decl rtype fname args

    set lfname [string tolower [string index $fname 0]]
    append lfname [string range $fname 1 end]

    set text "    "
    append text $rtype " (*" $lfname ") _ANSI_ARGS_("

    set arg1 [lindex $args 0]
    switch -exact $arg1 {
	void {
	    append text "(void)"
	}
	TCL_VARARGS {
	    set arg [lindex $args 1]
	    append text "TCL_VARARGS([lindex $arg 0],[lindex $arg 1])"
	}
	default {
	    set sep "("
	    foreach arg $args {
		append text $sep [lindex $arg 0] " " [lindex $arg 1] \
			[lindex $arg 2]
		set sep ", "
	    }
	    append text ")"
	}
    }
    
    append text "); /* $index */\n"
    return $text
}

# genStubs::makeInit --
#
#	Generate the prototype for a function.
#
# Arguments:
#	name	The interface name.
#	decl	The function declaration.
#	index	The slot index for this function.
#
# Results:
#	Returns the formatted declaration string.

proc genStubs::makeInit {name decl index} {
    append text "    " [lindex $decl 1] ", /* " $index " */\n"
    return $text
}

# genStubs::forAllStubs --
#
#	This function iterates over all of the platforms and invokes
#	a callback for each slot.  The result of the callback is then
#	placed inside appropriate platform guards.
#
# Arguments:
#	name		The interface name.
#	slotProc	The proc to invoke to handle the slot.  It will
#			have the interface name, the declaration,  and
#			the index appended.
#	onAll		If 1, emit the skip string even if there are
#			definitions for one or more platforms.
#	textVar		The variable to use for output.
#	skipString	The string to emit if a slot is skipped.  This
#			string will be subst'ed in the loop so "$i" can
#			be used to substitute the index value.
#
# Results:
#	None.

proc genStubs::forAllStubs {name slotProc onAll textVar \
	{skipString {"/* Slot $i is reserved */\n"}}} {
    variable stubs
    upvar $textVar text

    set plats [array names stubs $name,*,lastNum]
    if {[info exists stubs($name,generic,lastNum)]} {
	# Emit integrated stubs block
	set lastNum -1
	foreach plat [array names stubs $name,*,lastNum] {
	    if {$stubs($plat) > $lastNum} {
		set lastNum $stubs($plat)
	    }
	}
	for {set i 0} {$i <= $lastNum} {incr i} {
	    set slots [array names stubs $name,*,$i]
	    set emit 0
	    if {[info exists stubs($name,generic,$i)]} {
		if {[llength $slots] > 1} {
		    puts stderr "platform entry duplicates generic entry: $i"
		}
		append text [$slotProc $name $stubs($name,generic,$i) $i]
		set emit 1
	    } elseif {[llength $slots] > 0} {
		foreach plat {unix win mac} {
		    if {[info exists stubs($name,$plat,$i)]} {
			append text [addPlatformGuard $plat \
				[$slotProc $name $stubs($name,$plat,$i) $i]]
			set emit 1
		    } elseif {$onAll} {
			append text [eval {addPlatformGuard $plat} $skipString]
			set emit 1
		    }
		}
	    }
	    if {$emit == 0} {
		eval {append text} $skipString
	    }
	}
	
    } else {
	# Emit separate stubs blocks per platform
	foreach plat {unix win mac} {
	    if {[info exists stubs($name,$plat,lastNum)]} {
		set lastNum $stubs($name,$plat,lastNum)
		set temp {}
		for {set i 0} {$i <= $lastNum} {incr i} {
		    if {![info exists stubs($name,$plat,$i)]} {
			eval {append temp} $skipString
		    } else {
			append temp [$slotProc $name $stubs($name,$plat,$i) $i]
		    }
		}
		append text [addPlatformGuard $plat $temp]
	    }
	}
    }

}

# genStubs::emitDeclarations --
#
#	This function emits the function declarations for this interface.
#
# Arguments:
#	name	The interface name.
#	textVar	The variable to use for output.
#
# Results:
#	None.

proc genStubs::emitDeclarations {name textVar} {
    variable stubs
    upvar $textVar text

    append text "\n/*\n * Exported function declarations:\n */\n\n"
    forAllStubs $name makeDecl 0 text
    return
}

# genStubs::emitMacros --
#
#	This function emits the inline macros for an interface.
#
# Arguments:
#	name	The name of the interface being emitted.
#	textVar	The variable to use for output.
#
# Results:
#	None.

proc genStubs::emitMacros {name textVar} {
    variable stubs
    variable libraryName
    upvar $textVar text

    set upName [string toupper $libraryName]
    append text "\n#if defined(USE_${upName}_STUBS) && !defined(USE_${upName}_STUB_PROCS)\n"
    append text "\n/*\n * Inline function declarations:\n */\n\n"
    
    forAllStubs $name makeMacro 0 text

    append text "\n#endif /* defined(USE_${upName}_STUBS) && !defined(USE_${upName}_STUB_PROCS) */\n"
    return
}

# genStubs::emitHeader --
#
#	This function emits the body of the <name>Decls.h file for
#	the specified interface.
#
# Arguments:
#	name	The name of the interface being emitted.
#
# Results:
#	None.

proc genStubs::emitHeader {name} {
    variable outDir
    variable hooks

    set capName [string toupper [string index $name 0]]
    append capName [string range $name 1 end]

    emitDeclarations $name text

    if {[info exists hooks($name)]} {
	append text "\ntypedef struct ${capName}StubHooks {\n"
	foreach hook $hooks($name) {
	    set capHook [string toupper [string index $hook 0]]
	    append capHook [string range $hook 1 end]
	    append text "    struct ${capHook}Stubs *${hook}Stubs;\n"
	}
	append text "} ${capName}StubHooks;\n"
    }
    append text "\ntypedef struct ${capName}Stubs {\n"
    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
}

# genStubs::emitStubs --
#
#	This function emits the body of the <name>Stubs.c file for
#	the specified interface.
#
# Arguments:
#	name	The name of the interface being emitted.
#
# Results:
#	None.

proc genStubs::emitStubs {name} {
    variable outDir

    append text "\n/*\n * Exported stub functions:\n */\n\n"
    forAllStubs $name makeStub 0 text

    rewriteFile [file join $outDir ${name}Stubs.c] $text
    return    
}

# genStubs::emitInit --
#
#	Generate the table initializers for an interface.
#
# Arguments:
#	name		The name of the interface to initialize.
#	textVar		The variable to use for output.
#
# Results:
#	Returns the formatted output.

proc genStubs::emitInit {name textVar} {
    variable stubs
    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"
    }
    
    forAllStubs $name makeInit 1 text {"    NULL, /* $i */\n"}

    append text "\};\n"
    return
}

# genStubs::emitInits --
#
#	This function emits the body of the <name>StubInit.c file for
#	the specified interface.
#
# Arguments:
#	name	The name of the interface being emitted.
#
# Results:
#	None.

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 --
#
#	This is the main entry point.
#
# Arguments:
#	None.
#
# Results:
#	None.

proc genStubs::init {} {
    global argv argv0
    variable outDir
    variable interfaces

    if {[llength $argv] < 2} {
	puts stderr "usage: $argv0 outDir declFile ?declFile...?"
	exit 1
    }

    set outDir [lindex $argv 0]

    foreach file [lrange $argv 1 end] {
	source $file
    }

    foreach name [lsort [array names interfaces]] {
	puts "Emitting $name"
	emitHeader $name
    }

    emitInits
}

# lassign --
#
#	This function emulates the TclX lassign command.
#
# Arguments:
#	valueList	A list containing the values to be assigned.
#	args		The list of variables to be assigned.
#
# Results:
#	Returns any values that were not assigned to variables.

proc lassign {valueList args} {
  if {[llength $args] == 0} {
      error "wrong # args: lassign list varname ?varname..?"
  }

  uplevel [list foreach $args $valueList {break}]
  return [lrange $valueList [llength $args] end]
}

genStubs::init

Added tools/genWinImage.tcl.

















































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# genWinImage.tcl --
#
#	This script generates the Windows installer.
#
# Copyright (c) 1999 by Scriptics Corporation.
# All rights reserved.
# 
# RCS: @(#) $Id: genWinImage.tcl,v 1.1.2.2 1999/03/26 00:29:20 suresh Exp $


# This file is insensitive to the directory from which it is invoked.

namespace eval genWinImage {
    # toolsDir --
    #
    # This variable points to the platform specific tools directory.

    variable toolsDir

    # tclBuildDir --
    #
    # This variable points to the directory containing the Tcl built tree.

    variable tclBuildDir

    # tkBuildDir --
    #
    # This variable points to the directory containing the Tk built tree.

    variable tkBuildDir
}

# genWinImage::init --
#
#	This is the main entry point.
#
# Arguments:
#	None.
#
# Results:
#	None.

proc genWinImage::init {} {
    global tcl_platform argv argv0
    variable tclBuildDir
    variable tkBuildDir
    variable toolsDir
 
    puts "\n--- genWiImage.tcl started: \
	    [clock format [clock seconds] -format "%Y%m%d-%H:%M"] --\n"

    if {$tcl_platform(platform) != "windows"} {
	puts stderr "ERROR: Cannot build TCL.EXE on Unix systems"
	exit 1
    }

    if {[llength $argv] != 3} {
	puts stderr "usage: $argv0 <tclBuildDir> <tkBuildDir> <toolsDir>"
	exit 0
    }

    set tclBuildDir [lindex $argv 0]
    set tkBuildDir [lindex $argv 1]
    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:
#	None.
#
# Results:
#	Leaves proweb.exe and procd.exe sitting in the curent directory.

proc genWinImage::generateInstallers {} {
    variable toolsDir
    variable tclBuildDir
    variable tkBuildDir

    # Now read the "pro/srcs/install/pro.wse.in" file, have Tcl make
    # appropriate substitutions, write out the resulting file in a
    # current-working-directory.  Use this new file to perform installation
    # image creation.  Note that we have to use this technique to set
    # the value of _WISE_ because wise32 won't use a /d switch for this
    # variable.

    set __TCLBASEDIR__ [file native $tclBuildDir]
    set __TKBASEDIR__ [file native $tkBuildDir]
    set __WISE__ [file native [file join $toolsDir wise]]
    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]} {
	puts stderr "ERROR: $errMsg"
    } else {
	puts "\"TCL.EXE\" created."
    }

    return
}

genWinImage::init

Changes to tools/index.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# index.tcl --
#
# This file defines procedures that are used during the first pass of
# the man page conversion.  It is used to extract information used to
# generate a table of contents and a keyword list.
#
# Copyright (c) 1996 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.
# 
# SCCS: %Z% $Id: index.tcl,v 1.1 1998/04/28 18:53:50 stanton Exp $ 
# 

# Global variables used by these scripts:
#
# state -	state variable that controls action of text proc.
#				
# topics -	array indexed by (package,section,topic) with value











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# index.tcl --
#
# This file defines procedures that are used during the first pass of
# the man page conversion.  It is used to extract information used to
# generate a table of contents and a keyword list.
#
# Copyright (c) 1996 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: index.tcl,v 1.1.2.2 1998/09/24 23:59:41 stanton Exp $
# 

# Global variables used by these scripts:
#
# state -	state variable that controls action of text proc.
#				
# topics -	array indexed by (package,section,topic) with value
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
# from the topics array.
#
# Arguments:
# pkg -			Name of package to search.

proc getSections {pkg} {
    global topics

    foreach i [array names topics "${pkg},*"] {
	regsub {^.*,(.*),.*$} $i {\1} i
	set temp($i) {}
    }
    lsort [array names temp]
}

# getSections --
#
# Generate a sorted list of topics in the specified section of the
# specified package from the topics array.
#
# Arguments:
# pkg -			Name of package to search.
# sect -		Name of section to search.

proc getTopics {pkg sect} {
    global topics


    foreach i [array names topics "${pkg},${sect},*"] {
	regsub {^.*,.*,(.*)$} $i {\1} i
	set temp($i) {}
    }
    lsort [array names temp]
}








>


















>
>







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
# from the topics array.
#
# Arguments:
# pkg -			Name of package to search.

proc getSections {pkg} {
    global topics
    regsub -all {[][*?\\]} $pkg {\\&} pkg
    foreach i [array names topics "${pkg},*"] {
	regsub {^.*,(.*),.*$} $i {\1} i
	set temp($i) {}
    }
    lsort [array names temp]
}

# getSections --
#
# Generate a sorted list of topics in the specified section of the
# specified package from the topics array.
#
# Arguments:
# pkg -			Name of package to search.
# sect -		Name of section to search.

proc getTopics {pkg sect} {
    global topics
    regsub -all {[][*?\\]} $pkg {\\&} pkg
    regsub -all {[][*?\\]} $sect {\\&} sect
    foreach i [array names topics "${pkg},${sect},*"] {
	regsub {^.*,.*,(.*)$} $i {\1} i
	set temp($i) {}
    }
    lsort [array names temp]
}

153
154
155
156
157
158
159

160
161
162
163
164
165
166
		set args [join $args " "]
		puts stderr "Bad .TH macro: .$name $args"
	    }
	    incr curID
	    set topic	[lindex $args 0]	;# Tcl_UpVar
	    set curPkg	[lindex $args 3]	;# Tcl
	    set curSect	[lindex $args 4]	;# {Tcl Library Procedures}

	    set index "$curPkg,$curSect,$topic"
	    set topics($index) $curID
	    lappend keywords($topic) $curID
	}
    }
}








>







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
		set args [join $args " "]
		puts stderr "Bad .TH macro: .$name $args"
	    }
	    incr curID
	    set topic	[lindex $args 0]	;# Tcl_UpVar
	    set curPkg	[lindex $args 3]	;# Tcl
	    set curSect	[lindex $args 4]	;# {Tcl Library Procedures}
	    regsub -all {\\ } $curSect { } curSect
	    set index "$curPkg,$curSect,$topic"
	    set topics($index) $curID
	    lappend keywords($topic) $curID
	}
    }
}

Changes to tools/man2help.tcl.

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
# man2help.tcl --
#
# This file defines procedures that work in conjunction with the
# man2tcl program to generate a Windows help file from Tcl manual
# entries.
#
# Copyright (c) 1996 by Sun Microsystems, Inc.
#
# SCCS: %Z% $Id: man2help.tcl,v 1.1 1998/04/28 18:53:50 stanton Exp $ 
# 

#
# PASS 1
#

proc generateContents {basename version files} {
    global curID topics
    set curID 0
    foreach f $files {
	regsub -all -- {-} [file tail $f] {} curFile
	puts "Pass 1 -- $f"
	flush stdout
	doFile $f
    }
    set fd [open "$basename$version.cnt" w]

    puts $fd ":Base $basename$version.hlp"
    foreach package [getPackages] {
	foreach section [getSections $package] {
	    puts $fd "1 $section"
	    set lastTopic {}
	    foreach topic [getTopics $package $section] {
		if {[string compare $lastTopic $topic] != 0} {








|
















>







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
# man2help.tcl --
#
# This file defines procedures that work in conjunction with the
# man2tcl program to generate a Windows help file from Tcl manual
# entries.
#
# Copyright (c) 1996 by Sun Microsystems, Inc.
#
# RCS: @(#) $Id: man2help.tcl,v 1.1.2.4 1999/03/10 06:49:26 stanton Exp $
# 

#
# PASS 1
#

proc generateContents {basename version files} {
    global curID topics
    set curID 0
    foreach f $files {
	regsub -all -- {-} [file tail $f] {} curFile
	puts "Pass 1 -- $f"
	flush stdout
	doFile $f
    }
    set fd [open "$basename$version.cnt" w]
    fconfigure $fd -translation crlf
    puts $fd ":Base $basename$version.hlp"
    foreach package [getPackages] {
	foreach section [getSections $package] {
	    puts $fd "1 $section"
	    set lastTopic {}
	    foreach topic [getTopics $package $section] {
		if {[string compare $lastTopic $topic] != 0} {
52
53
54
55
56
57
58

59
60
61
62
63
64
65
    foreach key [array names keywords] {
	foreach id $keywords($key) {
	    lappend id_keywords($id) $key
	}
    }
	    
    set file [open "$basename.rtf" w]

    puts $file "\{\\rtf1\\ansi \\deff0\\deflang1033\{\\fonttbl\{\\f0\\froman\\fcharset0\\fprq2 Times New Roman\;\}\}"
    foreach f $files {
	regsub -all -- {-} [file tail $f] {} curFile
	puts "Pass 2 -- $f"
	flush stdout
	initGlobals
	doFile $f







>







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    foreach key [array names keywords] {
	foreach id $keywords($key) {
	    lappend id_keywords($id) $key
	}
    }
	    
    set file [open "$basename.rtf" w]
    fconfigure $file -translation crlf
    puts $file "\{\\rtf1\\ansi \\deff0\\deflang1033\{\\fonttbl\{\\f0\\froman\\fcharset0\\fprq2 Times New Roman\;\}\}"
    foreach f $files {
	regsub -all -- {-} [file tail $f] {} curFile
	puts "Pass 2 -- $f"
	flush stdout
	initGlobals
	doFile $f
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
# Given a file as argument, translate the file to a tcl script and
# evaluate it.
#
# Arguments:
# file -		Name of file to translate.

proc doFile {file} {
    if [catch {eval [exec man2tcl [glob $file]]} msg] {

	global errorInfo
	puts stderr $msg
	puts "in"
	puts $errorInfo
	exit 1
    }
}







|
>







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# Given a file as argument, translate the file to a tcl script and
# evaluate it.
#
# Arguments:
# file -		Name of file to translate.

proc doFile {file} {
    if {[catch {eval [exec man2tcl [glob $file]]} msg] &&
	    [catch {eval [exec ./man2tcl [glob $file]]} msg]} {
	global errorInfo
	puts stderr $msg
	puts "in"
	puts $errorInfo
	exit 1
    }
}

Changes to tools/man2help2.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# man2help2.tcl --
#
# This file defines procedures that are used during the second pass of
# the man page conversion.  It converts the man format input to rtf
# form suitable for use by the Windows help compiler.
#
# Copyright (c) 1996 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.
# 
# SCCS: %Z% $Id: man2help2.tcl,v 1.1 1998/04/28 18:53:51 stanton Exp $ 
# 

# Global variables used by these scripts:
#
# state -	state variable that controls action of text proc.
#				
# topics -	array indexed by (package,section,topic) with value











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# man2help2.tcl --
#
# This file defines procedures that are used during the second pass of
# the man page conversion.  It converts the man format input to rtf
# form suitable for use by the Windows help compiler.
#
# Copyright (c) 1996 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: man2help2.tcl,v 1.1.2.2 1998/09/24 23:59:41 stanton Exp $
# 

# Global variables used by these scripts:
#
# state -	state variable that controls action of text proc.
#				
# topics -	array indexed by (package,section,topic) with value
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
	    if {$state(inTP) == 0} {
		set string [insertRef $string]
	    }
	}
	SEE { 
	    global topics curPkg curSect
	    foreach i [split $string] {
		if ![regexp -nocase {^[a-z_]+} [string trim $i] i ] {
		    continue
		}
		if ![catch {set ref $topics($curPkg,$curSect,$i)} ] {
		    regsub $i $string [link $i $ref] string
		}
	    }
	}







|







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
	    if {$state(inTP) == 0} {
		set string [insertRef $string]
	    }
	}
	SEE { 
	    global topics curPkg curSect
	    foreach i [split $string] {
		if ![regexp -nocase {^[a-z_0-9]+} [string trim $i] i ] {
		    continue
		}
		if ![catch {set ref $topics($curPkg,$curSect,$i)} ] {
		    regsub $i $string [link $i $ref] string
		}
	    }
	}
435
436
437
438
439
440
441

442
443
444
445
446
447
448
	P -
	R {
	    endFont
	    if {$state(textState) == "REF"} {
		set state(textState) INSERT
	    }
	}

	B {
	    beginFont Code
	    if {$state(textState) == "INSERT"} {
		set state(textState) REF
	    }
	}
	I {







>







435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
	P -
	R {
	    endFont
	    if {$state(textState) == "REF"} {
		set state(textState) INSERT
	    }
	}
	C -
	B {
	    beginFont Code
	    if {$state(textState) == "INSERT"} {
		set state(textState) REF
	    }
	}
	I {
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
proc char {name} {
    global file state

    switch -exact $name {
        \\o {
	    set state(intl) 1
	}




	\\0 {
	    textSetup
	    puts -nonewline $file " \\emspace "
	}
	\\\\ {
	    textSetup
	    puts -nonewline $file "\\\\"
	}
	\\(+- {
	    textSetup
	    puts -nonewline $file "\\'b1 "
	}
	\\% -
	\\| {
	}




	default {
	    puts stderr "Unknown character: $name"
	}
    }
}









>
>
>
>















>
>
>
>







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
proc char {name} {
    global file state

    switch -exact $name {
        \\o {
	    set state(intl) 1
	}
	\\\  {
	    textSetup
	    puts -nonewline $file " "
	}
	\\0 {
	    textSetup
	    puts -nonewline $file " \\emspace "
	}
	\\\\ {
	    textSetup
	    puts -nonewline $file "\\\\"
	}
	\\(+- {
	    textSetup
	    puts -nonewline $file "\\'b1 "
	}
	\\% -
	\\| {
	}
	\\(bu {
	    textSetup
	    puts -nonewline $file "�"
	}
	default {
	    puts stderr "Unknown character: $name"
	}
    }
}


747
748
749
750
751
752
753

754
755
756
757
758
759
760
	tab
	return
    }
    if {$length == 2} {
	set count [lindex $argList 1]
	set tab [expr $count * 0.1]i
	newPara $tab -$tab

	setTabs $tab
	formattedText [lindex $argList 0]
	tab
	return
    }
    puts stderr "Bad .IP macro: .IP [join $argList " "]"
}







>







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
	tab
	return
    }
    if {$length == 2} {
	set count [lindex $argList 1]
	set tab [expr $count * 0.1]i
	newPara $tab -$tab
	textSetup
	setTabs $tab
	formattedText [lindex $argList 0]
	tab
	return
    }
    puts stderr "Bad .IP macro: .IP [join $argList " "]"
}
812
813
814
815
816
817
818


819
820
821
822
823
824
825
    }
    incr curID
    set name	[lindex $argList 0]		;# Tcl_UpVar
    set page	[lindex $argList 1]		;# 3
    set vers	[lindex $argList 2]		;# 7.4
    set curPkg	[lindex $argList 3]		;# Tcl
    set curSect	[lindex $argList 4]		;# {Tcl Library Procedures}



    puts $file "#{\\footnote $curID}"		;# Context string
    puts $file "\${\\footnote $name}"		;# Topic title
    set browse "${curSect}${name}"
    regsub -all {[ _-]} $browse {} browse
    puts $file "+{\\footnote $browse}"		;# Browse sequence








>
>







822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
    }
    incr curID
    set name	[lindex $argList 0]		;# Tcl_UpVar
    set page	[lindex $argList 1]		;# 3
    set vers	[lindex $argList 2]		;# 7.4
    set curPkg	[lindex $argList 3]		;# Tcl
    set curSect	[lindex $argList 4]		;# {Tcl Library Procedures}
    
    regsub -all {\\ } $curSect { } curSect	;# Clean up for [incr\ Tcl]

    puts $file "#{\\footnote $curID}"		;# Context string
    puts $file "\${\\footnote $name}"		;# Topic title
    set browse "${curSect}${name}"
    regsub -all {[ _-]} $browse {} browse
    puts $file "+{\\footnote $browse}"		;# Browse sequence

Added tools/man2html.tcl.











































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/proj/tcl/install/5.x-sparc/bin/tclsh7.5

if [catch {

# man2html.tcl --
#
# This file contains procedures that work in conjunction with the
# man2tcl program to generate a HTML files from Tcl manual entries.
#
# Copyright (c) 1996 by Sun Microsystems, Inc.
#
# SCCS: @(#) man2html.tcl 1.5 96/04/11 20:21:43
#

set homeDir /home/rjohnson/Projects/tools/generic

# sarray -
#
# Save an array to a file so that it can be sourced.
#
# Arguments:
# file -		Name of the output file
# args -		Name of the arrays to save
#
proc sarray {file args} {
    set file [open $file w]
    foreach a $args {
	upvar $a array
	if ![array exists array] {
	    puts "sarray: \"$a\" isn't an array"
	    break
	}	
    
	foreach name [lsort [array names array]] {
	    regsub -all " " $name "\\ " name1
	    puts $file "set ${a}($name1) \{$array($name)\}"
	}
    }
    close $file
}



# footer --
#
# Builds footer info for HTML pages
#
# Arguments:
# None

proc footer {packages} {
    lappend f "<HR>"
    set h {[}
    foreach package $packages {
	lappend h "<A HREF=\"../$package/contents.html\">$package</A>"
	lappend h "|"
    }
    lappend f [join [lreplace $h end end {]} ] " "]
    lappend f "<HR>"
    lappend f "<PRE>Copyright &#169; 1989-1994 The Regents of the University of California."
    lappend f "Copyright &#169; 1994-1996 Sun Microsystems, Inc."
    lappend f "</PRE>"
    return [join $f "\n"]
}




# doDir --
#
# Given a directory as argument, translate all the man pages in
# that directory.
#
# Arguments:
# dir -			Name of the directory.

proc doDir dir {
    foreach f [lsort [glob $dir/*.\[13n\]]] {
	do $f	;# defined in man2html1.tcl & man2html2.tcl
    }
}


if {$argc < 2} {
    puts stderr "usage: $argv0 html_dir tcl_dir packages..."
    puts stderr "usage: $argv0 -clean html_dir"
    exit 1
}
	
if {[lindex $argv 0] == "-clean"} {
    set html_dir [lindex $argv 1]
    puts -nonewline "recursively remove: $html_dir? "
    flush stdout
    if {[gets stdin] == "y"} {
	puts "removing: $html_dir"
	exec rm -r $html_dir
    }
    exit 0
}

set html_dir [lindex $argv 0]
set tcl_dir  [lindex $argv 1]
set packages [lrange $argv 2 end]

#### need to add glob capability to packages ####

# make sure there are doc directories for each package

foreach i $packages {
    if ![file exists $tcl_dir/$i/doc] {
	puts stderr "Error: doc directory for package $i is missing"
	exit 1
    }
    if ![file isdirectory $tcl_dir/$i/doc] {
	puts stderr "Error: $tcl_dir/$i/doc is not a directory"
	exit 1
    }
}


# we want to start with a clean sheet

if [file exists $html_dir] {
    puts stderr "Error: HTML directory already exists"
    exit 1
} else {
    exec mkdir $html_dir
}

set footer [footer $packages]


# make the hyperlink arrays and contents.html for all packages
	
foreach package $packages {
    global homeDir
    exec mkdir $html_dir/$package
    
    # build hyperlink database arrays: NAME_file and KEY_file
    #
    puts "\nScanning man pages in $tcl_dir/$package/doc..."
    source $homeDir/man2html1.tcl
    
    doDir $tcl_dir/$package/doc

    # clean up the NAME_file and KEY_file database arrays
    #
    catch {unset KEY_file()}
    foreach name [lsort [array names NAME_file]] {
	set file_name $NAME_file($name)
	if {[llength $file_name] > 1} {
	    set file_name [lsort $file_name]
	    puts stdout "Warning: '$name' multiply defined in: $file_name; using last"
	    set NAME_file($name) [lindex $file_name end]
	}
    }
#   sarray $html_dir/$package/xref.tcl NAME_file KEY_file

    # build the contents file from NAME_file
    #
    puts "\nGenerating contents.html for $package"
    doContents $html_dir/$package/contents.html $lib ;# defined in man2html1.tcl

    # now translate the man pages to HTML pages
    #
    source $homeDir/man2html2.tcl
    puts "\nBuilding html pages from man pages in $tcl_dir/$package/doc..."
    doDir $tcl_dir/$package/doc

    unset NAME_file
}

	

} result] {
    global errorInfo
    puts stderr $result
    puts stderr "in"
    puts stderr $errorInfo
}

Added tools/man2html1.tcl.



























































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# man2html1.tcl --
#
# This file defines procedures that are used during the first pass of the
# man page to html conversion process. It is sourced by h.tcl.
#
# Copyright (c) 1996 by Sun Microsystems, Inc.
#
# SCCS: @(#) man2html1.tcl 1.2 96/03/21 10:48:29
#

# Global variables used by these scripts:
#
# state -	state variable that controls action of text proc.
#				
# curFile -	tail of current man page.
#
# file -	file pointer; for both xref.tcl and contents.html
#
# NAME_file -	array indexed by NAME and containing file names used
#		for hyperlinks.
#
# KEY_file -	array indexed by KEYWORD and containing file names used
#		for hyperlinks.
#
# lib -		contains package name. Used to label section in contents.html
#
# inDT -	in dictionary term. 



# text --
#
# This procedure adds entries to the hypertext arrays NAME_file
# and KEY_file.
#
# DT: might do this: if first word of $dt matches $name and [llength $name==1]
# 	and [llength $dt > 1], then add to NAME_file. 
#
# Arguments:
# string -		Text to index.


proc text string {
    global state curFile NAME_file KEY_file inDT

    switch $state {
	NAME {
	    foreach i [split $string ","] {
		lappend NAME_file([string trim $i]) $curFile
	    }
	}
	KEY {
	    foreach i [split $string ","] {
		lappend KEY_file([string trim $i]) $curFile
	    }
	}
	DT -
	OFF -
	DASH {}
	default {
	    puts stderr "text: unknown state: $state"
	}
    }
}


# macro --
#
# This procedure is invoked to process macro invocations that start
# with "." (instead of ').
#
# Arguments:
# name -	The name of the macro (without the ".").
# args -	Any additional arguments to the macro.

proc macro {name args} {
    switch $name {
	SH {
	    global state

	    switch $args {
		NAME {
		    if {$state == "INIT" } {
			set state NAME
		    }
		}
		DESCRIPTION {set state DT}
		INTRODUCTION {set state DT}
		KEYWORDS {set state KEY}
		default {set state OFF}
	    }
		
	}
	TP {
	    global inDT
	    set inDT 1
	}
	TH {
	    global lib state inDT
	    set inDT 0
	    set state INIT
	    if {[llength $args] != 5} {
		    set args [join $args " "]
		    puts stderr "Bad .TH macro: .$name $args"
	    }
	    set lib [lindex $args 3]				;# Tcl or Tk
	}
    }
}



# dash --
#
# This procedure is invoked to handle dash characters ("\-" in
# troff).  It only function in pass1 is to terminate the NAME state.
#
# Arguments:
# None.

proc dash {} {
    global state
    if {$state == "NAME"} {
	set state DASH
    }
}



# newline --
#
# This procedure is invoked to handle newlines in the troff input.
# It's only purpose is to terminate a DT (dictionary term).
#
# Arguments:
# None.

proc newline {} {
    global inDT
    set inDT 0
}




# initGlobals, tab, font, char, macro2 --
#
# These procedures do nothing during the first pass. 
#
# Arguments:
# None.

proc initGlobals {} {}
proc tab {} {}
proc font type {}
proc char name {}
proc macro2 {name args} {}


# doListing --
#
# Writes an ls like list to a file. Searches NAME_file for entries
# that match the input pattern.
#
# Arguments:
# file -		Output file pointer.
# pattern -		glob style match pattern

proc doListing {file pattern} {
    global NAME_file

    set max_len 0
    foreach name [lsort [array names NAME_file]] {
	set ref $NAME_file($name)
	    if [string match $pattern $ref] {
		lappend type $name
		if {[string length $name] > $max_len} {
		set max_len [string length $name]
	    }
	}
    }
    if [catch {llength $type} ] {
	puts stderr "       doListing: no names matched pattern ($pattern)"
	return
    }
    incr max_len
    set ncols [expr 90/$max_len]
    set nrows [expr int( ceil( [llength $type] / $ncols. ) ) ]

#	? max_len ncols nrows

    set index 0
    foreach f $type {
	lappend row([expr $index % $nrows]) $f
	incr index
    }

    puts -nonewline $file "<PRE>"
    for {set i 0} {$i<$nrows} {incr i} {
	foreach name $row($i) {
	    set str [format "%-*s" $max_len $name]
	    regsub $name $str "<A HREF=\"$NAME_file($name).html\">$name</A>" str
	    puts -nonewline $file $str
	}
	puts $file {}
    }
    puts $file "</PRE>"
}


# doContents --
#
# Generates a HTML contents file using the NAME_file array
# as its input database.
#
# Arguments:
# file -		name of the contents file.
# packageName -	string used in the title and sub-heads of the HTML page. Normally
#				name of the package without version numbers.

proc doContents {file packageName} {
    global footer
    
    set file [open $file w]
    
    puts $file "<HTML><HEAD><TITLE>$packageName Manual</TITLE></HEAD><BODY>"
    puts $file "<H3>$packageName</H3>"
    doListing $file "*.1"

    puts $file "<HR><H3>$packageName Commands</H3>"
    doListing $file "*.n"

    puts $file "<HR><H3>$packageName Library</H3>"
    doListing $file "*.3"

    puts $file $footer
    puts $file "</BODY></HTML>"
    close $file
}




# do --
#
# This is the toplevel procedure that searches a man page
# for hypertext links.  It builds a data base consisting of
# two arrays: NAME_file and KEY file. It runs the man2tcl 
# program to turn the man page into a script, then it evals 
# that script.
#
# Arguments:
# fileName -		Name of the file to scan.

proc do fileName {
    global curFile
    set curFile [file tail $fileName]
    set file stdout
    puts "  Pass 1 -- $fileName"
    flush stdout
    if [catch {eval [exec man2tcl [glob $fileName]]} msg] {
	global errorInfo
	puts stderr $msg
	puts "in"
	puts $errorInfo
	exit 1
    }
}

Added tools/man2html2.tcl.















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
# man2html2.tcl --
#
# This file defines procedures that are used during the second pass of the
# man page to html conversion process. It is sourced by man2html.tcl.
#
# Copyright (c) 1996 by Sun Microsystems, Inc.
#
# SCCS: @(#) man2html2.tcl 1.2 96/03/21 10:48:30
#

# Global variables used by these scripts:
#
# NAME_file -	array indexed by NAME and containing file names used
#		for hyperlinks.
#
# textState -	state variable defining action of 'text' proc.
#
# nestStk -	stack oriented list containing currently active
#		HTML tags (UL, OL, DL). Local to 'nest' proc.
#
# inDT -	set by 'TPmacro', cleared by 'newline'. Used to insert
#		the <DT> tag while in a dictionary list <DL>.
#
# curFont -	Name of special font that is currently in
#		use.  Null means the default paragraph font
#		is being used.
#
# file -	Where to output the generated HTML.
#
# fontStart -	Array to map font names to starting sequences.
#
# fontEnd -	Array to map font names to ending sequences.
#
# noFillCount -	Non-zero means don't fill the next $noFillCount
#		lines: force a line break at each newline.  Zero
#		means filling is enabled, so don't output line
#		breaks for each newline.
#
# footer -	info inserted at bottom of each page. Normally read
#		from the xref.tcl file
	
# initGlobals --
#
# This procedure is invoked to set the initial values of all of the
# global variables, before processing a man page.
#
# Arguments:
# None.

proc initGlobals {} {
    global file noFillCount textState
    global fontStart fontEnd curFont inPRE charCnt

    nest init
    set inPRE 0
    set textState 0
    set curFont ""
    set fontStart(Code) "<B>"
    set fontStart(Emphasis) "<I>"
    set fontEnd(Code) "</B>"
    set fontEnd(Emphasis) "</I>"
    set noFillCount 0
    set charCnt 0
    setTabs 0.5i
}


# beginFont --
#
# Arranges for future text to use a special font, rather than
# the default paragraph font.
#
# Arguments:
# font -		Name of new font to use.

proc beginFont font {
    global curFont file fontStart

    if {$curFont == $font} {
	return
    }
    endFont
    puts -nonewline $file $fontStart($font)
    set curFont $font
}


# endFont --
#
# Reverts to the default font for the paragraph type.
#
# Arguments:
# None.

proc endFont {} {
    global curFont file fontEnd

    if {$curFont != ""} {
    puts -nonewline $file $fontEnd($curFont)
    set curFont ""
    }
}



# text --
#
# This procedure adds text to the current paragraph.  If this is
# the first text in the paragraph then header information for the
# paragraph is output before the text.
#
# Arguments:
# string -		Text to output in the paragraph.

proc text string {
    global file textState inDT charCnt

    set pos [string first "\t" $string]
    if {$pos >= 0} {
    	text [string range $string 0 [expr $pos-1]]
    	tab
    	text [string range $string [expr $pos+1] end]
	return    	
    }
    incr charCnt [string length $string]
    regsub -all {&} $string {\&amp;}  string
    regsub -all {<} $string {\&lt;}  string
    regsub -all {>} $string {\&gt;}  string
    regsub -all {"} $string {\&quot;}  string
    switch $textState {
	REF { 
	    if {$inDT == {}} {
		set string [insertRef $string]
	    }
	}
	SEE { 
	    global NAME_file
	    foreach i [split $string] {
		if ![regexp -nocase {^[a-z_]+} [string trim $i] i ] {
# 		    puts "Warning: $i in SEE ALSO not found"
		    continue
		}
		if ![catch {set ref $NAME_file($i)} ] {
		    regsub $i $string "<A HREF=\"$ref.html\">$i</A>" string
		}
	    }
	}
    }
    puts -nonewline $file "$string"
}



# insertRef --
#
#
# Arguments:
# string -		Text to output in the paragraph.

proc insertRef string {
    global NAME_file self
    set path {}
    if ![catch {set ref $NAME_file([string trim $string])} ] {
	if {"$ref.html" != $self} {
	    set string "<A HREF=\"${path}$ref.html\">$string</A>"
#	    puts "insertRef: $self $ref.html ---$string--"
	}
    }
    return $string
}



# macro --
#
# This procedure is invoked to process macro invocations that start
# with "." (instead of ').
#
# Arguments:
# name -		The name of the macro (without the ".").
# args -		Any additional arguments to the macro.

proc macro {name args} {
    switch $name {
	AP {
	    if {[llength $args] != 3} {
		puts stderr "Bad .AP macro: .$name [join $args " "]"
	    }
	    setTabs {1.25i 2.5i 3.75i}
	    TPmacro {}
	    font B
	    text "[lindex $args 0]  "
	    font I
	    text "[lindex $args 1]"
	    font R
	    text " ([lindex $args 2])"
	    newline
	}
	AS {}				;# next page and previous page
	br {
	    lineBreak	
	}
	BS {}
	BE {}
	CE {
	    global file noFillCount inPRE
	    puts $file </PRE></BLOCKQUOTE>
	    set inPRE 0
	}
	CS {				;# code section
	    global file noFillCount inPRE
	    puts -nonewline $file <BLOCKQUOTE><PRE>
	    set inPRE 1
	}
	DE {
	    global file noFillCount inPRE
	    puts $file </PRE></BLOCKQUOTE>
	    set inPRE 0
	    set noFillCount 0
	}
	DS {
	    global file noFillCount inPRE
	    puts -nonewline $file <BLOCKQUOTE><PRE>
	    set noFillCount 10000000
	    set inPRE 1
	}
	fi {
	    global noFillCount
	    set noFillCount 0
	}
	IP {
	    IPmacro $args
	}
	LP {
	    nest decr
	    nest incr
	    newPara
	}
	ne {
	}
	nf {
	    global noFillCount
	    set noFillCount 1000000
	}
	OP {
	    global inDT file inPRE 
	    if {[llength $args] != 3} {
		puts stderr "Bad .OP macro: .$name [join $args " "]"
	    }
	    nest para DL DT
	    set inPRE 1
	    puts -nonewline $file <PRE>				
	    setTabs 4c
	    text "Command-Line Name:"
	    tab
	    font B
	    set x [lindex $args 0]
	    regsub -all {\\-} $x - x
	    text $x
	    newline
	    font R
	    text "Database Name:"
	    tab
	    font B
	    text [lindex $args 1]
	    newline
	    font R
	    text "Database Class:"
	    tab
	    font B
	    text [lindex $args 2]
	    font R
	    puts -nonewline $file </PRE>				
	    set inDT "\n<DD>"			;# next newline writes inDT 
	    set inPRE 0
	    newline
	}
	PP {
	    nest decr
	    nest incr
	    newPara
	}
	RE {
	    nest decr    
	}
	RS {
	    nest incr
	}
	SE {
	    global noFillCount textState inPRE file

	    font R
	    puts -nonewline $file </PRE>
	    set inPRE 0
	    set noFillCount 0
	    nest reset
	    newPara
	    text "See the "
	    font B
	    set temp $textState
	    set textState REF
	    text options
	    set textState $temp
	    font R
	    text " manual entry for detailed descriptions of the above options."
	}
	SH {
	    SHmacro $args
	}
	SO {
	    global noFillCount inPRE file

	    SHmacro "STANDARD OPTIONS"
	    setTabs {4c 8c 12c}
	    set noFillCount 1000000
	    puts -nonewline $file <PRE>
	    set inPRE 1
	    font B
	}
	so {
	    if {$args != "man.macros"} {
		puts stderr "Unknown macro: .$name [join $args " "]"
	    }
	}
	sp {					;# needs work
	    if {$args == ""} {
		set count 1
	    } else {
		set count [lindex $args 0]
	    }
	    while {$count > 0} {
		lineBreak
		incr count -1
	    }
	}
	ta {
	    setTabs $args
	}
	TH {
	    THmacro $args
	}
	TP {
	    TPmacro $args
	}
	UL {					;# underline
	    global file
	    puts -nonewline $file "<B><U>"
	    text [lindex $args 0]
	    puts -nonewline $file "</U></B>"
	    if {[llength $args] == 2} {
		text [lindex $args 1]
	    }
	}
	VE {
#	    global file
#	    puts -nonewline $file "</FONT>"
	}
	VS {
#	    global file
#	    if {[llength $args] > 0} {
#		puts -nonewline $file "<BR>"
#	    }
#	    puts -nonewline $file "<FONT COLOR=\"GREEN\">"
	}
	default {
	    puts stderr "Unknown macro: .$name [join $args " "]"
	}
    }

#	global nestStk; puts "$name [format "%-20s" $args] $nestStk"
#	flush stdout; flush stderr
}


# font --
#
# This procedure is invoked to handle font changes in the text
# being output.
#
# Arguments:
# type -		Type of font: R, I, B, or S.

proc font type {
    global textState
    switch $type {
	P -
	R {
	    endFont
	    if {$textState == "REF"} {
		set textState INSERT
	    }
	}
	B {
	    beginFont Code
	    if {$textState == "INSERT"} {
		set textState REF
	    }
	}
	I {
	    beginFont Emphasis
	}
	S {
	}
	default {
	    puts stderr "Unknown font: $type"
	}
    }
}



# formattedText --
#
# Insert a text string that may also have \fB-style font changes
# and a few other backslash sequences in it.
#
# Arguments:
# text -		Text to insert.

proc formattedText text {
#	puts "formattedText: $text"
    while {$text != ""} {
	set index [string first \\ $text]
	if {$index < 0} {
	    text $text
	    return
	}
	text [string range $text 0 [expr $index-1]]
	set c [string index $text [expr $index+1]]
	switch -- $c {
	    f {
		font [string index $text [expr $index+2]]
		set text [string range $text [expr $index+3] end]
	    }
	    e {
		text \\
		set text [string range $text [expr $index+2] end]
	    }
	    - {
		dash
		set text [string range $text [expr $index+2] end]
	    }
	    | {
		set text [string range $text [expr $index+2] end]
	    }
	    default {
		puts stderr "Unknown sequence: \\$c"
		set text [string range $text [expr $index+2] end]
	    }
	}
    }
}



# dash --
#
# This procedure is invoked to handle dash characters ("\-" in
# troff).  It outputs a special dash character.
#
# Arguments:
# None.

proc dash {} {
    global textState charCnt
    if {$textState == "NAME"} {
    	set textState 0
    }
    incr charCnt
    text "-"
}


# tab --
#
# This procedure is invoked to handle tabs in the troff input.
# Right now it does nothing.
#
# Arguments:
# None.

proc tab {} {
    global inPRE charCnt tabString
#	? charCnt
    if {$inPRE == 1} {
	set pos [expr $charCnt % [string length $tabString] ]
	set spaces [string first "1" [string range $tabString $pos end] ]
	text [format "%*s" [incr spaces] " "]
    } else {
#	puts "tab: found tab outside of <PRE> block"
    }
}


# setTabs --
#
# This procedure handles the ".ta" macro, which sets tab stops.
#
# Arguments:
# tabList -	List of tab stops, each consisting of a number
#			followed by "i" (inch) or "c" (cm).

proc setTabs {tabList} {
    global file breakPending tabString

#	puts "setTabs: --$tabList--"
    set last 0
    set tabString {}
    set charsPerInch 14.
    set numTabs [llength $tabList]
    foreach arg $tabList {
	if {[scan $arg "%f%s" distance units] != 2} {
	    puts stderr "bad distance \"$arg\""
	    return 0
    	}
	switch -- $units {
	    c	{
		set distance [expr $distance * $charsPerInch / 2.54 ]
	    }
	    i	{
		set distance [expr $distance * $charsPerInch]
	    }
	    default {
		puts stderr "bad units in distance \"$arg\""
		continue
	    }
    	}
#		? distance
    	lappend tabString [format "%*s1" [expr round($distance-$last-1)] " "]
    	set last $distance
    }
    set tabString [join $tabString {}]
#	puts "setTabs: --$tabString--"
}



# lineBreak --
#
# Generates a line break in the HTML output.
#
# Arguments:
# None.

proc lineBreak {} {
    global file inPRE
    puts $file "<BR>"
}



# newline --
#
# This procedure is invoked to handle newlines in the troff input.
# It outputs either a space character or a newline character, depending
# on fill mode.
#
# Arguments:
# None.

proc newline {} {
    global noFillCount file inDT inPRE charCnt

    if {$inDT != {} } {
    	puts $file "\n$inDT"
    	set inDT {}
    } elseif {$noFillCount == 0 || $inPRE == 1} {
	puts $file {}
    } else {
	lineBreak
	incr noFillCount -1
    }
    set charCnt 0
}



# char --
#
# This procedure is called to handle a special character.
#
# Arguments:
# name -		Special character named in troff \x or \(xx construct.

proc char name {
    global file charCnt

    incr charCnt
#	puts "char: $name"
    switch -exact $name {
	\\0 {					;#  \0
	    puts -nonewline $file " "
	}
	\\\\ {					;#  \
	    puts -nonewline $file "\\"
	}
	\\(+- { 				;#  +/-
	    puts -nonewline $file "&#177;"
	}
	\\% {}					;#  \%
	\\| {					;#  \|
	}
	default {
	    puts stderr "Unknown character: $name"
	}
    }
}


# macro2 --
#
# This procedure handles macros that are invoked with a leading "'"
# character instead of space.  Right now it just generates an
# error diagnostic.
#
# Arguments:
# name -		The name of the macro (without the ".").
# args -		Any additional arguments to the macro.

proc macro2 {name args} {
    puts stderr "Unknown macro: '$name [join $args " "]"
}



# SHmacro --
#
# Subsection head; handles the .SH macro.
#
# Arguments:
# name -		Section name.

proc SHmacro argList {
    global file noFillCount textState charCnt

    set args [join $argList " "]
    if {[llength $argList] < 1} {
	puts stderr "Bad .SH macro: .$name $args"
    }

    set noFillCount 0
    nest reset

    puts -nonewline $file "<H3>"
    text $args
    puts $file "</H3>"

#	? args textState

    # control what the text proc does with text
    
    switch $args {
	NAME {set textState NAME}
	DESCRIPTION {set textState INSERT}
	INTRODUCTION {set textState INSERT}
	"WIDGET-SPECIFIC OPTIONS" {set textState INSERT}
	"SEE ALSO" {set textState SEE}
	KEYWORDS {set textState 0}
    }
    set charCnt 0
}



# IPmacro --
#
# This procedure is invoked to handle ".IP" macros, which may take any
# of the following forms:
#
# .IP [1]			Translate to a "1Step" paragraph.
# .IP [x] (x > 1)	Translate to a "Step" paragraph.
# .IP				Translate to a "Bullet" paragraph.
# .IP text count	Translate to a FirstBody paragraph with special
#					indent and tab stop based on "count", and tab after
#					"text".
#
# Arguments:
# argList -		List of arguments to the .IP macro.
#
# HTML limitations: 'count' in '.IP text count' is ignored.

proc IPmacro argList {
    global file

    setTabs 0.5i
    set length [llength $argList]
    if {$length == 0} {
    	nest para UL LI
	return
    }
    if {$length == 1} {
    	nest para OL LI
	    return
	}
    if {$length > 1} {
    	nest para DL DT
	    formattedText [lindex $argList 0]
	    puts $file "\n<DD>"
	    return
    }
    puts stderr "Bad .IP macro: .IP [join $argList " "]"
}


# TPmacro --
#
# This procedure is invoked to handle ".TP" macros, which may take any
# of the following forms:
#
# .TP x		Translate to an indented paragraph with the
# 			specified indent (in 100 twip units).
# .TP		Translate to an indented paragraph with
# 			default indent.
#
# Arguments:
# argList -		List of arguments to the .IP macro.
#
# HTML limitations: 'x' in '.TP x' is ignored.


proc TPmacro {argList} {
    global inDT
    nest para DL DT
    set inDT "\n<DD>"			;# next newline writes inDT 
    setTabs 0.5i
}



# THmacro --
#
# This procedure handles the .TH macro.  It generates the non-scrolling
# header section for a given man page, and enters information into the
# table of contents.  The .TH macro has the following form:
#
# .TH name section date footer header
#
# Arguments:
# argList -		List of arguments to the .TH macro.

proc THmacro {argList} {
    global file

    if {[llength $argList] != 5} {
	set args [join $argList " "]
	puts stderr "Bad .TH macro: .$name $args"
    }
    set name  [lindex $argList 0]		;# Tcl_UpVar
    set page  [lindex $argList 1]		;# 3
    set vers  [lindex $argList 2]		;# 7.4
    set lib   [lindex $argList 3]		;# Tcl
    set pname [lindex $argList 4]		;# {Tcl Library Procedures}

    puts -nonewline $file "<HTML><HEAD><TITLE>"
    text "$lib - $name ($page)"
    puts $file "</TITLE></HEAD><BODY>\n"
    
    puts -nonewline $file "<H1><CENTER>"
    text $pname
    puts $file "</CENTER></H1>\n"
}



# newPara --
#
# This procedure sets the left and hanging indents for a line.
# Indents are specified in units of inches or centimeters, and are
# relative to the current nesting level and left margin.
#
# Arguments:
# None

proc newPara {} {
    global file nestStk
	
    if {[lindex $nestStk end] != "NEW" } {
	nest decr    
    }
    puts -nonewline $file "<P>"
}



# nest --
#
# This procedure takes care of inserting the tags associated with the
# IP, TP, RS, RE, LP and PP macros. Only 'nest para' takes arguments.
#
# Arguments:
# op -				operation: para, incr, decr, reset, init
# listStart -		begin list tag: OL, UL, DL.
# listItem -		item tag:       LI, LI, DT.

proc nest {op {listStart "NEW"} {listItem {} } } {
    global file nestStk inDT charCnt
#	puts "nest: $op $listStart $listItem"
    switch $op {
	para {
	    set top [lindex $nestStk end]
	    if {$top == "NEW" } {
		set nestStk [lreplace $nestStk end end $listStart]
		puts $file "<$listStart>"
	    } elseif {$top != $listStart} {
		puts stderr "nest para: bad stack"
		exit 1
	    }
	    puts $file "\n<$listItem>"
	    set charCnt 0
	}
	incr {
	   lappend nestStk NEW
	}
	decr {
	    if {[llength $nestStk] == 0} {
		puts stderr "nest error: nest length is zero"
		set nestStk NEW
	    }
	    set tag [lindex $nestStk end]
	    if {$tag != "NEW"} {
		puts $file "</$tag>"
	    }
	    set nestStk [lreplace $nestStk end end]
	}
	reset {
	    while {[llength $nestStk] > 0} {
		nest decr
	    }
	    set nestStk NEW
	}
	init {
	    set nestStk NEW
	    set inDT {}
	}
    }
    set charCnt 0
}



# do --
#
# This is the toplevel procedure that translates a man page
# to Frame.  It runs the man2tcl program to turn the man page
# into a script, then it evals that script.
#
# Arguments:
# fileName -		Name of the file to translate.

proc do fileName {
    global file self html_dir package footer
    set self "[file tail $fileName].html"
    set file [open "$html_dir/$package/$self" w]
    puts "  Pass 2 -- $fileName"
    flush stdout
    initGlobals
    if [catch {eval [exec man2tcl [glob $fileName]]} msg] {
	global errorInfo
	puts stderr $msg
	puts "in"
	puts stderr $errorInfo
	exit 1
    }
    nest reset
    puts $file $footer
    puts $file "</BODY></HTML>"
    close $file
}



Changes to tools/man2tcl.c.

12
13
14
15
16
17
18
19
20


21
22
23
24
25
26
27
 *	man2tcl ?fileName?
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: %Z% $Id: man2tcl.c,v 1.1 1998/04/28 18:53:52 stanton Exp $ 
 */



#include <stdio.h>
#include <string.h>
#include <ctype.h>

/*
 * Imported things that aren't defined in header files:







|

>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 *	man2tcl ?fileName?
 *
 * Copyright (c) 1995 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: man2tcl.c,v 1.1.2.2 1998/09/24 23:59:41 stanton Exp $
 */

static char sccsid[] = "@(#) man2tcl.c 1.3 95/08/12 17:34:08";

#include <stdio.h>
#include <string.h>
#include <ctype.h>

/*
 * Imported things that aren't defined in header files:

Added tools/regexpTestLib.tcl.





















































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# regexpTestLib.tcl --
#
# This file contains tcl procedures used by spencer2testregexp.tcl and
# spencer2regexp.tcl, which are programs written to convert Henry
# Spencer's test suite to tcl test files.
#
# Copyright (c) 1996 by Sun Microsystems, Inc.
#
# SCCS: @(#) regexpTestLib.tcl 1.4 98/01/22 14:48:34
# 

proc readInputFile {} {
    global inFileName
    global lineArray

    set fileId [open $inFileName r]

    set i 0
    while {[gets $fileId line] >= 0} {

	set len [string length $line]

	if {($len > 0) && ([string index $line [expr $len - 1]] == "\\")} {
	    if {[info exists lineArray(c$i)] == 0} {
		set lineArray(c$i) 1
	    } else {
		incr lineArray(c$i)
	    }
	    set line [string range $line 0 [expr $len - 2]]
	    append lineArray($i) $line
	    continue
	}
	if {[info exists lineArray(c$i)] == 0} {
	    set lineArray(c$i) 1
	} else {
	    incr lineArray(c$i)
	}
	append lineArray($i) $line
	incr i
    }

    close $fileId
    return $i
}

#
# strings with embedded @'s are truncated
# unpreceeded @'s are replaced by {}
# 
proc removeAts {ls} {
    set len [llength $ls]
    set newLs {}
    foreach item $ls {
	regsub @.* $item "" newItem
	lappend newLs $newItem
    }
    return $newLs
}

proc convertErrCode {code} {

    set errMsg "couldn't compile regular expression pattern:"

    if {[string compare $code "INVARG"] == 0} {
	return "$errMsg invalid argument to regex routine"
    } elseif {[string compare $code "BADRPT"] == 0} {
	return "$errMsg ?+* follows nothing"
    } elseif {[string compare $code "BADBR"] == 0} {
	return "$errMsg invalid repetition count(s)"
    } elseif {[string compare $code "BADOPT"] == 0} {
	return "$errMsg invalid embedded option"
    } elseif {[string compare $code "EPAREN"] == 0} {
	return "$errMsg unmatched ()"
    } elseif {[string compare $code "EBRACE"] == 0} {
	return "$errMsg unmatched {}"
    } elseif {[string compare $code "EBRACK"] == 0} {
	return "$errMsg unmatched \[\]"
    } elseif {[string compare $code "ERANGE"] == 0} {
	return "$errMsg invalid character range"
    } elseif {[string compare $code "ECTYPE"] == 0} {
	return "$errMsg invalid character class"
    } elseif {[string compare $code "ECOLLATE"] == 0} {
	return "$errMsg invalid collating element"
    } elseif {[string compare $code "EESCAPE"] == 0} {
	return "$errMsg invalid escape sequence"
    } elseif {[string compare $code "BADPAT"] == 0} {
	return "$errMsg invalid regular expression"
    } elseif {[string compare $code "ESUBREG"] == 0} {
	return "$errMsg invalid backreference number"
    } elseif {[string compare $code "IMPOSS"] == 0} {
	return "$errMsg can never match"
    }
    return "$errMsg $code"
}

proc writeOutputFile {numLines fcn} {
    global outFileName
    global lineArray

    # open output file and write file header info to it. 

    set fileId [open $outFileName w]

    puts $fileId "# Commands covered:  $fcn"
    puts $fileId "#"
    puts $fileId "# This Tcl-generated file contains tests for the $fcn tcl command."
    puts $fileId "# Sourcing this file into Tcl runs the tests and generates output for"
    puts $fileId "# errors.  No output means no errors were found.  Setting VERBOSE to"
    puts $fileId "# -1 will run tests that are known to fail."
    puts $fileId "#"
    puts $fileId "# Copyright (c) 1998 Sun Microsystems, Inc."
    puts $fileId "#"
    puts $fileId "# See the file \"license.terms\" for information on usage and redistribution"
    puts $fileId "# of this file, and for a DISCLAIMER OF ALL WARRANTIES."
    puts $fileId "#"
    puts $fileId "\# SCCS: \%Z\% \%M\% \%I\% \%E\% \%U\%"
    puts $fileId "\nproc print \{arg\} \{puts \$arg\}\n"
    puts $fileId "if \{\[string compare test \[info procs test\]\] == 1\} \{"
    puts $fileId "    source defs ; set VERBOSE -1\n\}\n"
    puts $fileId "if \{\$VERBOSE != -1\} \{"
    puts $fileId "    proc print \{arg\} \{\}\n\}\n"
    puts $fileId "#"
    puts $fileId "# The remainder of this file is Tcl tests that have been"
    puts $fileId "# converted from Henry Spencer's regexp test suite."
    puts $fileId "#\n"

    set lineNum 0
    set srcLineNum 1
    while {$lineNum < $numLines} {

	set currentLine $lineArray($lineNum)

	# copy comment string to output file and continue

	if {[string index $currentLine 0] == "#"} {
	    puts $fileId $currentLine
	    incr srcLineNum $lineArray(c$lineNum)
	    incr lineNum
	    continue	    
	}

	set len [llength $currentLine]

	# copy empty string to output file and continue

	if {$len == 0} {
	    puts $fileId "\n"
	    incr srcLineNum $lineArray(c$lineNum)
	    incr lineNum
	    continue	    
	}
	if {($len < 3)} {
	    puts "warning: test is too short --\n\t$currentLine"
	    incr srcLineNum $lineArray(c$lineNum)
	    incr lineNum
	    continue
	}

	puts $fileId [convertTestLine $currentLine $len $lineNum $srcLineNum]

	incr srcLineNum $lineArray(c$lineNum)
	incr lineNum
    }

    close $fileId
}

proc convertTestLine {currentLine len lineNum srcLineNum} {

    regsub -all {(?b)\\} $currentLine {\\\\} currentLine
    set re [lindex $currentLine 0]
    set flags [lindex $currentLine 1]
    set str [lindex $currentLine 2]

    # based on flags, decide whether to skip the test

    if {[findSkipFlag $flags]} {
	regsub -all {\[|\]|\(|\)|\{|\}|\#} $currentLine {\&} line
	set msg "\# skipping char mapping test from line $srcLineNum\n"
	append msg "print \{... skip test from line $srcLineNum:  $line\}"
	return $msg
    }

    # perform mapping if '=' flag exists

    set noBraces 0
    if {[regexp {=|>} $flags] == 1} {
	regsub -all {_} $currentLine {\\ } currentLine
	regsub -all {A} $currentLine {\\007} currentLine
	regsub -all {B} $currentLine {\\b} currentLine
	regsub -all {E} $currentLine {\\033} currentLine
	regsub -all {F} $currentLine {\\f} currentLine
	regsub -all {N} $currentLine {\\n} currentLine

	# if and \r substitutions are made, do not wrap re, flags,
	# str, and result in braces

	set noBraces [regsub -all {R} $currentLine {\\\u000D} currentLine]
	regsub -all {T} $currentLine {\\t} currentLine
	regsub -all {V} $currentLine {\\v} currentLine
	if {[regexp {=} $flags] == 1} {
	    set re [lindex $currentLine 0]
	}
	set str [lindex $currentLine 2]
    }
    set flags [removeFlags $flags]

    # find the test result

    set numVars [expr $len - 3]
    set vars {}
    set vals {}
    set result 0
    set v 0
    
    if {[regsub {\*} "$flags" "" newFlags] == 1} {
	# an error is expected
	
	if {[string compare $str "EMPTY"] == 0} {
	    # empty regexp is not an error
	    # skip this test
	    
	    return "\# skipping the empty-re test from line $srcLineNum\n"
	}
	set flags $newFlags
	set result "\{1 \{[convertErrCode $str]\}\}"
    } elseif {$numVars > 0} {
	# at least 1 match is made
	
	if {[regexp {s} $flags] == 1} {
	    set result "\{0 1\}"
	} else {
	    while {$v < $numVars} {
		append vars " var($v)"
		append vals " \$var($v)"
		incr v
	    }
	    set tmp [removeAts [lrange $currentLine 3 $len]]
	    set result "\{0 \{1 $tmp\}\}"
	    if {$noBraces} {
		set result "\[subst $result\]"
	    }
	}
    } else {
	# no match is made
	
	set result "\{0 0\}"
    }

    # set up the test and write it to the output file

    set cmd [prepareCmd $flags $re $str $vars $noBraces]
    if {$cmd == -1} {
	return "\# skipping test with metasyntax from line $srcLineNum\n"	    
    }

    set test "test regexp-1.$srcLineNum \{converted from line $srcLineNum\} \{\n"
    append test "\tcatch {unset var}\n"
    append test "\tlist \[catch \{ \n"
    append test "\t\tset match \[$cmd\] \n"
    append test "\t\tlist \$match $vals \n"
    append test "\t\} msg\] \$msg \n"
    append test "\} $result \n"
    return $test
}

Added tools/str2c.



























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#! /bin/sh
#
# Transform text (.ps, .tcl,...) into a C string
#
# 1997/10 -- dl
#
# $Id: str2c,v 1.1.2.1 1998/09/21 23:40:57 stanton Exp $
#
# restart with tclsh \
exec tclsh8.0 "$0" "$@"

# Max string length
# (some C compiler have a 2048 chars limits (so 2047 real chars with
#  the tariling 0) so we use 2000 to make the count nice)
set MAX 2000

if {$argc} {
    puts stderr "Usage: [file tail [info script]] < text > text.c"
    exit 1
}

set r [read stdin]

proc translate {what} {
    regsub -all {\\} $what {\\\\} what
    regsub -all {"} $what {\\"} what
    regsub -all "\n" $what "\\\\n\\\\\n" what;
    return $what;
}

set lg [string length $r]
if {$lg<$MAX} {
    puts "/*
 * Single part writeable string generated by str2c
 */
static char data\[\]=\"[translate $r]\";"
} else {
    puts "/*
 * Multi parts read only string generated by str2c
 */
static CONST char * CONST data\[\]= {"
    set n 1
    for {set i 0} {$i<$lg} {incr i $MAX} {
	set part [string range $r $i [expr $i+$MAX-1]]
	set len  [string length $part];
	puts "\t/* Start of part $n ($len characters) */"
	puts "\t\"[translate $part]\","
	puts "\t/* End of part $n */\n"
	incr n
    }
    puts "\tNULL\t/* End of data marker */\n};"
    puts "\n/* use for instance with:
    CONST char * CONST *chunk;
    for (chunk=data; *chunk; chunk++) {
        Tcl_AppendResult(interp, *chunk, (char *) NULL);
    }
*/"
}



Deleted tools/tcl.hpj.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[OPTIONS]
REPORT=Yes
TITLE=Tcl/Tk Reference Manual
CONTENTS=contents
COPYRIGHT=Copyright � 1996-1997 Sun Microsystems, Inc.

[FILES]
.\tcl.rtf

[WINDOWS]
main="Tcl/Tk Reference Manual",,0,,,0

[CONFIG]
BrowseButtons()
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Added tools/tcl.hpj.in.







































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
; This file is maintained by HCW. Do not modify this file directly.

[OPTIONS]
HCW=0
LCID=0x409 0x0 0x0 ;English (United States)
REPORT=Yes
TITLE=Tcl/Tk Reference Manual
CNT=tcl81.cnt
COPYRIGHT=Copyright � 1999 Scriptics Corporation
HLP=tcl81.hlp

[FILES]
tcl.rtf

[WINDOWS]
main="Tcl/Tk Reference Manual",,0

[CONFIG]
BrowseButtons()

Added tools/tcl.wse.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
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
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
Document Type: WSE
item: Global
  Version=6.01
  Title=Tcl 8.1 for Windows Installation
  Flags=00010100
  Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  Japanese Font Name=MS Gothic
  Japanese Font Size=10
  Start Gradient=0 0 255
  End Gradient=0 0 0
  Windows Flags=00000000000000010010110000001000
  Log Pathname=%MAINDIR%\INSTALL.LOG
  Message Font=MS Sans Serif
  Font Size=8
  Disk Label=tcl8.0a2
  Disk Filename=setup
  Patch Flags=0000000000000001
  Patch Threshold=85
  Patch Memory=4000
  Variable Name1=_SYS_
  Variable Default1=C:\WINDOWS\SYSTEM
  Variable Flags1=00001000
  Variable Name2=_ODBC16_
  Variable Default2=C:\WINDOWS\SYSTEM
  Variable Flags2=00001000
  Variable Name3=_WISE_
  Variable Default3=${__WISE__}
  Variable Flags3=00001000
end
item: Open/Close INSTALL.LOG
  Flags=00000001
end
item: Check if File/Dir Exists
  Pathname=%SYS%
  Flags=10000100
end
item: Set Variable
  Variable=SYS
  Value=%WIN%
end
item: End Block
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
  Value=http://www.scriptics.com/registration/%PATCHLEVEL%.html
end
item: Set Variable
  Variable=GROUP
  Value=Tcl
end
item: Set Variable
  Variable=DISABLED
  Value=!
end
item: Set Variable
  Variable=MAINDIR
  Value=Tcl
end
item: Check Configuration
  Flags=10111011
end
item: Get Registry Key Value
  Variable=PROGRAM_FILES
  Key=SOFTWARE\Microsoft\Windows\CurrentVersion
  Default=C:\Program Files
  Value Name=ProgramFilesDir
  Flags=00000100
end
item: Set Variable
  Variable=MAINDIR
  Value=%PROGRAM_FILES%\%MAINDIR%
end
item: Set Variable
  Variable=EXPLORER
  Value=1
end
item: Else Statement
end
item: Set Variable
  Variable=MAINDIR
  Value=C:\%MAINDIR%
end
item: End Block
end
item: Set Variable
  Variable=BACKUP
  Value=%MAINDIR%\BACKUP
end
item: Set Variable
  Variable=DOBACKUP
  Value=B
end
item: Set Variable
  Variable=BRANDING
  Value=0
end
remarked item: If/While Statement
  Variable=BRANDING
  Value=1
end
remarked item: Read INI Value
  Variable=NAME
  Pathname=%INST%\CUSTDATA.INI
  Section=Registration
  Item=Name
end
remarked item: Read INI Value
  Variable=COMPANY
  Pathname=%INST%\CUSTDATA.INI
  Section=Registration
  Item=Company
end
remarked item: If/While Statement
  Variable=NAME
end
remarked item: Set Variable
  Variable=DOBRAND
  Value=1
end
remarked item: End Block
end
remarked item: End Block
end
item: Set Variable
  Variable=TYPE
  Value=C
end
item: Set Variable
  Variable=COMPONENTS
  Value=ABC
end
item: Wizard Block
  Direction Variable=DIRECTION
  Display Variable=DISPLAY
  X Position=0
  Y Position=0
  Filler Color=8421440
  Flags=00000001
end
item: Custom Dialog Set
  Name=Splash
  Display Variable=DISPLAY
  item: Dialog
    Title=%APPTITLE% Installation
    Title French=Bienvenue
    Title German=Willkommen
    Title Portuguese=Bem-vindo 
    Title Spanish=Bienvenido
    Title Italian=Benvenuto
    Title Danish=Velkommen
    Title Dutch=Welkom
    Title Norwegian=Velkommen
    Title Swedish=V�lkommen
    Width=273
    Height=250
    Font Name=Helv
    Font Size=8
    item: Push Button
      Rectangle=166 214 208 228
      Variable=DIRECTION
      Value=N
      Create Flags=01010000000000010000000000000001
      Text=&Next >
    end
    item: Push Button
      Rectangle=212 214 254 228
      Action=3
      Create Flags=01010000000000010000000000000000
      Text=Cancel
    end
    item: Static
      Rectangle=0 0 268 233
      Action=2
      Enabled Color=00000000000000001111111111111111
      Create Flags=01010000000000000000000000001011
      Pathname=${__TCLBASEDIR__}\tools\white.bmp
    end
    item: Static
      Rectangle=5 5 268 215
      Destination Dialog=1
      Action=2
      Enabled Color=00000000000000001111111111111111
      Create Flags=01010000000000000000000000001011
      Pathname=${__TCLBASEDIR__}\tools\tclSplash.bmp
    end
  end
end
item: End Block
end
item: Wizard Block
  Direction Variable=DIRECTION
  Display Variable=DISPLAY
  Bitmap Pathname=%_WISE_%\DIALOGS\TEMPLATE\WIZARD.BMP
  X Position=9
  Y Position=10
  Filler Color=8421440
  Dialog=Welcome
  Dialog=Select Destination Directory
  Dialog=Select Installation Type
  Dialog=Select Components
  Dialog=Select Program Manager Group
  Variable=
  Variable=
  Variable=
  Variable=TYPE
  Variable=EXPLORER
  Value=
  Value=
  Value=
  Value=C
  Value=1
  Compare=0
  Compare=0
  Compare=0
  Compare=1
  Compare=0
  Flags=00000011
end
item: Custom Dialog Set
  Name=Welcome
  Display Variable=DISPLAY
  item: Dialog
    Title=%APPTITLE% Installation
    Title French=Installation de %APPTITLE%
    Title German=Installation von %APPTITLE%
    Title Spanish=Instalaci�n de %APPTITLE%
    Title Italian=Installazione di %APPTITLE%
    Width=271
    Height=224
    Font Name=Helv
    Font Size=8
    item: Static
      Rectangle=86 8 258 42
      Create Flags=01010000000000000000000000000000
      Flags=0000000000000001
      Name=Times New Roman
      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
      Text=Welcome!
      Text French=Bienvenue !
      Text German=Willkommen!
      Text Spanish=�Bienvenido!
      Text Italian=Benvenuti!
    end
    item: Push Button
      Rectangle=150 187 195 202
      Variable=DIRECTION
      Value=N
      Create Flags=01010000000000010000000000000001
      Text=&Next >
      Text French=&Suite >
      Text German=&Weiter >
      Text Spanish=&Siguiente >
      Text Italian=&Avanti >
    end
    item: Push Button
      Rectangle=105 187 150 202
      Variable=DISABLED
      Value=!
      Create Flags=01010000000000010000000000000000
      Text=< &Back
      Text French=< &Retour
      Text German=< &Zur�ck
      Text Spanish=< &Atr�s
      Text Italian=< &Indietro
    end
    item: Push Button
      Rectangle=211 187 256 202
      Action=3
      Create Flags=01010000000000010000000000000000
      Text=&Cancel
      Text French=&Annuler
      Text German=&Abbrechen
      Text Spanish=&Cancelar
      Text Italian=&Annulla
    end
    item: Static
      Rectangle=85 41 255 130
      Create Flags=01010000000000000000000000000000
      Text=This installation program will install %APPTITLE%.
      Text=
      Text=Press the Next button to start the installation. You can press the Exit Setup button now if you do not want to install %APPTITLE% at this time. 
      Text=
      Text=It is strongly recommended that you exit all Windows programs before running this installation program.
      Text French=Ce programme d'installation va installer %APPTITLE%.
      Text French=
      Text French=Cliquez sur le bouton Suite pour d�marrer l'installation. Vous pouvez cliquer sur le bouton Quitter l'installation si vous ne voulez pas installer %APPTITLE% tout de suite.
      Text German=Mit diesem Installationsprogramm wird %APPTITLE% installiert.
      Text German=
      Text German=Klicken Sie auf "Weiter", um mit der Installation zu beginnen. Klicken Sie auf "Abbrechen", um die Installation von %APPTITLE% abzubrechen.
      Text Spanish=Este programa de instalaci�n instalar� %APPTITLE%.
      Text Spanish=
      Text Spanish=Presione el bot�n Siguiente para iniciar la instalaci�n. Puede presionar el bot�n Salir de instalaci�n si no desea instalar %APPTITLE% en este momento.
      Text Italian=Questo programma installer� %APPTITLE%.
      Text Italian=
      Text Italian=Per avvviare l'installazione premere il pulsante Avanti. Se non si desidera installare %APPTITLE% ora, premere il pulsante Esci dall'installazione.
    end
    item: Static
      Rectangle=8 180 256 181
      Action=3
      Create Flags=01010000000000000000000000000111
    end
  end
end
item: Custom Dialog Set
  Name=Select Destination Directory
  Display Variable=DISPLAY
  item: Dialog
    Title=%APPTITLE% Installation
    Title French=Installation de %APPTITLE%
    Title German=Installation von %APPTITLE%
    Title Spanish=Instalaci�n de %APPTITLE%
    Title Italian=Installazione di %APPTITLE%
    Width=271
    Height=224
    Font Name=Helv
    Font Size=8
    item: Push Button
      Rectangle=150 187 195 202
      Variable=DIRECTION
      Value=N
      Create Flags=01010000000000010000000000000001
      Text=&Next >
      Text French=&Suite >
      Text German=&Weiter >
      Text Spanish=&Siguiente >
      Text Italian=&Avanti >
    end
    item: Push Button
      Rectangle=105 187 150 202
      Variable=DIRECTION
      Value=B
      Create Flags=01010000000000010000000000000000
      Flags=0000000000000001
      Text=< &Back
      Text French=< &Retour
      Text German=< &Zur�ck
      Text Spanish=< &Atr�s
      Text Italian=< &Indietro
    end
    item: Push Button
      Rectangle=211 187 256 202
      Action=3
      Create Flags=01010000000000010000000000000000
      Text=&Cancel
      Text French=&Annuler
      Text German=&Abbrechen
      Text Spanish=&Cancelar
      Text Italian=&Annulla
    end
    item: Static
      Rectangle=8 180 256 181
      Action=3
      Create Flags=01010000000000000000000000000111
    end
    item: Static
      Rectangle=86 8 258 42
      Create Flags=01010000000000000000000000000000
      Flags=0000000000000001
      Name=Times New Roman
      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
      Text=Select Destination Directory
      Text French=S�lectionner le r�pertoire de destination
      Text German=Zielverzeichnis w�hlen
      Text Spanish=Seleccione el directorio de destino
      Text Italian=Selezionare Directory di destinazione
    end
    item: Static
      Rectangle=86 39 256 114
      Create Flags=01010000000000000000000000000000
      Text=Please select the directory where the %APPTITLE% files are to be installed.
      Text=
      Text=To install in the default directory below, click Next.
      Text=
      Text=To install in a different directory, click Browse and select another directory.
      Text French=Veuillez s�lectionner le r�pertoire dans lequel les fichiers %APPTITLE% doivent �tre install�s.
      Text German=Geben Sie an, in welchem Verzeichnis die %APPTITLE%-Dateien installiert werden sollen.
      Text Spanish=Por favor seleccione el directorio donde desee instalar los archivos de %APPTITLE%.
      Text Italian=Selezionare la directory dove verranno installati i file %APPTITLE%.
    end
    item: Static
      Rectangle=86 130 256 157
      Action=1
      Create Flags=01010000000000000000000000000111
    end
    item: Push Button
      Rectangle=205 138 250 153
      Variable=MAINDIR_SAVE
      Value=%MAINDIR%
      Destination Dialog=1
      Action=2
      Create Flags=01010000000000010000000000000000
      Text=Browse
      Text French=Parcourir
      Text German=Durchsuchen
      Text Spanish=Buscar
      Text Italian=Sfoglie
    end
    item: Static
      Rectangle=91 140 198 151
      Create Flags=01010000000000000000000000000000
      Text=%MAINDIR%
      Text French=%MAINDIR%
      Text German=%MAINDIR%
      Text Spanish=%MAINDIR%
      Text Italian=%MAINDIR%
    end
  end
  item: Dialog
    Title=Select Destination Directory
    Title French=S�lectionner le r�pertoire de destination
    Title German=Zielverzeichnis w�hlen
    Title Spanish=Seleccione el directorio de destino
    Title Italian=Selezionare Directory di destinazione
    Width=221
    Height=173
    Font Name=Helv
    Font Size=8
    item: Listbox
      Rectangle=5 5 163 149
      Variable=MAINDIR
      Create Flags=01010000100000010000000101000000
      Flags=0000110000100010
      Text=%MAINDIR%
      Text French=%MAINDIR%
      Text German=%MAINDIR%
      Text Spanish=%MAINDIR%
      Text Italian=%MAINDIR%
    end
    item: Push Button
      Rectangle=167 6 212 21
      Create Flags=01010000000000010000000000000001
      Text=OK
      Text French=OK
      Text German=OK
      Text Spanish=Aceptar
      Text Italian=OK
    end
    item: Push Button
      Rectangle=167 25 212 40
      Variable=MAINDIR
      Value=%MAINDIR_SAVE%
      Create Flags=01010000000000010000000000000000
      Flags=0000000000000001
      Text=Cancel
      Text French=Annuler
      Text German=Abbrechen
      Text Spanish=Cancelar
      Text Italian=Annulla
    end
  end
end
remarked item: Custom Dialog Set
  Name=Select Installation Type
  Display Variable=DISPLAY
  item: Dialog
    Title=%APPTITLE% Installation
    Title French=Installation de %APPTITLE%
    Title German=Installation von %APPTITLE%
    Title Spanish=Instalaci�n de %APPTITLE%
    Title Italian=Installazione di %APPTITLE%
    Width=271
    Height=224
    Font Name=Helv
    Font Size=8
    item: Push Button
      Rectangle=150 187 195 202
      Variable=DIRECTION
      Value=N
      Create Flags=01010000000000010000000000000001
      Text=&Next >
      Text French=&Suite >
      Text German=&Weiter >
      Text Spanish=&Siguiente >
      Text Italian=&Avanti >
    end
    item: Push Button
      Rectangle=105 187 150 202
      Variable=DIRECTION
      Value=B
      Create Flags=01010000000000010000000000000000
      Text=< &Back
      Text French=< &Retour
      Text German=< &Zur�ck
      Text Spanish=< &Atr�s
      Text Italian=< &Indietro
    end
    item: Push Button
      Rectangle=211 187 256 202
      Action=3
      Create Flags=01010000000000010000000000000000
      Text=&Cancel
      Text French=&Annuler
      Text German=&Abbrechen
      Text Spanish=&Cancelar
      Text Italian=&Annulla
    end
    item: Static
      Rectangle=8 180 256 181
      Action=3
      Create Flags=01010000000000000000000000000111
    end
    item: Static
      Rectangle=86 8 258 42
      Create Flags=01010000000000000000000000000000
      Flags=0000000000000001
      Name=Times New Roman
      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
      Text=Select Installation Type
      Text French=S�lectionner les composants
      Text German=Komponenten ausw�hlen
      Text Spanish=Seleccione componentes
      Text Italian=Selezionare i componenti
    end
    item: Static
      Rectangle=194 162 242 172
      Variable=COMPONENTS
      Value=MAINDIR
      Create Flags=01010000000000000000000000000010
    end
    item: Static
      Rectangle=194 153 242 162
      Variable=COMPONENTS
      Create Flags=01010000000000000000000000000010
    end
    item: Static
      Rectangle=107 153 196 164
      Create Flags=01010000000000000000000000000000
      Text=Disk Space Required:
      Text French=Espace disque requis :
      Text German=Notwendiger Speicherplatz:
      Text Spanish=Espacio requerido en el disco:
      Text Italian=Spazio su disco necessario:
    end
    item: Static
      Rectangle=107 162 196 172
      Create Flags=01010000000000000000000000000000
      Text=Disk Space Remaining:
      Text French=Espace disque disponible :
      Text German=Verbleibender Speicherplatz:
      Text Spanish=Espacio en disco disponible:
      Text Italian=Spazio su disco disponibile:
    end
    item: Static
      Rectangle=86 145 256 175
      Action=1
      Create Flags=01010000000000000000000000000111
    end
    item: Static
      Rectangle=86 42 256 61
      Create Flags=01010000000000000000000000000000
      Text=Choose which type of installation to perform by selecting one of the buttons below.
      Text French=Choisissez les composants que vous voulez installer en cochant les cases ci-dessous.
      Text German=W�hlen Sie die zu installierenden Komponenten, indem Sie in die entsprechenden K�stchen klicken.
      Text Spanish=Elija los componentes que desee instalar marcando los cuadros de abajo.
      Text Italian=Scegliere quali componenti installare selezionando le caselle sottostanti.
    end
    item: Radio Button
      Rectangle=86 74 256 128
      Variable=TYPE
      Create Flags=01010000000000010000000000001001
      Text=&Full Installation (Recommended)
      Text=&Minimal Installation
      Text=C&ustom Installation
      Text=
    end
  end
end
item: Custom Dialog Set
  Name=Select Components
  Display Variable=DISPLAY
  item: Dialog
    Title=%APPTITLE% Installation
    Title French=Installation de %APPTITLE%
    Title German=Installation von %APPTITLE%
    Title Spanish=Instalaci�n de %APPTITLE%
    Title Italian=Installazione di %APPTITLE%
    Width=271
    Height=224
    Font Name=Helv
    Font Size=8
    item: Push Button
      Rectangle=150 187 195 202
      Variable=DIRECTION
      Value=N
      Create Flags=01010000000000010000000000000001
      Text=&Next >
      Text French=&Suite >
      Text German=&Weiter >
      Text Spanish=&Siguiente >
      Text Italian=&Avanti >
    end
    item: Push Button
      Rectangle=105 187 150 202
      Variable=DIRECTION
      Value=B
      Create Flags=01010000000000010000000000000000
      Text=< &Back
      Text French=< &Retour
      Text German=< &Zur�ck
      Text Spanish=< &Atr�s
      Text Italian=< &Indietro
    end
    item: Push Button
      Rectangle=211 187 256 202
      Action=3
      Create Flags=01010000000000010000000000000000
      Text=&Cancel
      Text French=&Annuler
      Text German=&Abbrechen
      Text Spanish=&Cancelar
      Text Italian=&Annulla
    end
    item: Static
      Rectangle=8 180 256 181
      Action=3
      Create Flags=01010000000000000000000000000111
    end
    item: Static
      Rectangle=86 8 258 42
      Create Flags=01010000000000000000000000000000
      Flags=0000000000000001
      Name=Times New Roman
      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
      Text=Select Components
      Text French=S�lectionner les composants
      Text German=Komponenten ausw�hlen
      Text Spanish=Seleccione componentes
      Text Italian=Selezionare i componenti
    end
    item: Checkbox
      Rectangle=86 75 256 129
      Variable=COMPONENTS
      Create Flags=01010000000000010000000000000011
      Flags=0000000000000110
      Text=Tcl Run-Time Files
      Text=Example Scripts
      Text=Help Files
      Text=Header and Library Files
      Text=
      Text French=Tcl Run-Time Files
      Text French=Example Scripts
      Text French=Help Files
      Text French=Header and Library Files
      Text French=
      Text German=Tcl Run-Time Files
      Text German=Example Scripts
      Text German=Help Files
      Text German=Header and Library Files
      Text German=
      Text Spanish=Tcl Run-Time Files
      Text Spanish=Example Scripts
      Text Spanish=Help Files
      Text Spanish=Header and Library Files
      Text Spanish=
      Text Italian=Tcl Run-Time Files
      Text Italian=Example Scripts
      Text Italian=Help Files
      Text Italian=Header and Library Files
      Text Italian=
    end
    item: Static
      Rectangle=194 162 242 172
      Variable=COMPONENTS
      Value=MAINDIR
      Create Flags=01010000000000000000000000000010
    end
    item: Static
      Rectangle=194 153 242 162
      Variable=COMPONENTS
      Create Flags=01010000000000000000000000000010
    end
    item: Static
      Rectangle=107 153 196 164
      Create Flags=01010000000000000000000000000000
      Text=Disk Space Required:
      Text French=Espace disque requis :
      Text German=Notwendiger Speicherplatz:
      Text Spanish=Espacio requerido en el disco:
      Text Italian=Spazio su disco necessario:
    end
    item: Static
      Rectangle=107 162 196 172
      Create Flags=01010000000000000000000000000000
      Text=Disk Space Remaining:
      Text French=Espace disque disponible :
      Text German=Verbleibender Speicherplatz:
      Text Spanish=Espacio en disco disponible:
      Text Italian=Spazio su disco disponibile:
    end
    item: Static
      Rectangle=86 145 256 175
      Action=1
      Create Flags=01010000000000000000000000000111
    end
    item: Static
      Rectangle=86 42 256 61
      Create Flags=01010000000000000000000000000000
      Text=Choose which components to install by checking the boxes below.
      Text French=Choisissez les composants que vous voulez installer en cochant les cases ci-dessous.
      Text German=W�hlen Sie die zu installierenden Komponenten, indem Sie in die entsprechenden K�stchen klicken.
      Text Spanish=Elija los componentes que desee instalar marcando los cuadros de abajo.
      Text Italian=Scegliere quali componenti installare selezionando le caselle sottostanti.
    end
  end
end
item: Custom Dialog Set
  Name=Select Program Manager Group
  Display Variable=DISPLAY
  item: Dialog
    Title=%APPTITLE% Installation
    Title French=Installation de %APPTITLE%
    Title German=Installation von %APPTITLE%
    Title Spanish=Instalaci�n de %APPTITLE%
    Title Italian=Installazione di %APPTITLE%
    Width=271
    Height=224
    Font Name=Helv
    Font Size=8
    item: Push Button
      Rectangle=150 187 195 202
      Variable=DIRECTION
      Value=N
      Create Flags=01010000000000010000000000000001
      Text=&Next >
      Text French=&Suite >
      Text German=&Weiter >
      Text Spanish=&Siguiente >
      Text Italian=&Avanti >
    end
    item: Push Button
      Rectangle=105 187 150 202
      Variable=DIRECTION
      Value=B
      Create Flags=01010000000000010000000000000000
      Flags=0000000000000001
      Text=< &Back
      Text French=< &Retour
      Text German=< &Zur�ck
      Text Spanish=< &Atr�s
      Text Italian=< &Indietro
    end
    item: Push Button
      Rectangle=211 187 256 202
      Action=3
      Create Flags=01010000000000010000000000000000
      Text=&Cancel
      Text French=&Annuler
      Text German=&Abbrechen
      Text Spanish=&Cancelar
      Text Italian=&Annulla
    end
    item: Static
      Rectangle=8 180 256 181
      Action=3
      Create Flags=01010000000000000000000000000111
    end
    item: Static
      Rectangle=86 8 258 42
      Create Flags=01010000000000000000000000000000
      Flags=0000000000000001
      Name=Times New Roman
      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
      Text=Select ProgMan Group
      Text French=S�lectionner le groupe du Gestionnaire de programme 
      Text German=Bestimmung der Programm-Managergruppe
      Text Spanish=Seleccione grupo del Administrador de programas
      Text Italian=Selezionare il gruppo ProgMan 
    end
    item: Static
      Rectangle=86 44 256 68
      Create Flags=01010000000000000000000000000000
      Text=Enter the name of the Program Manager group to add the %APPTITLE% icons to:
      Text French=Entrez le nom du groupe du Gestionnaire de programme dans lequel vous souhaitez ajouter les ic�nes de %APPTITLE% :
      Text German=Geben Sie den Namen der Programmgruppe ein, der das Symbol %APPTITLE% hinzugef�gt werden soll:
      Text Spanish=Escriba el nombre del grupo del Administrador de programas en el que desea agregar los iconos de %APPTITLE%:
      Text Italian=Inserire il nome del gruppo Program Manager per aggiungere le icone %APPTITLE% a:
    end
    item: Combobox
      Rectangle=86 69 256 175
      Variable=GROUP
      Create Flags=01010000000000010000001000000001
      Flags=0000000000000001
      Text=%GROUP%
      Text French=%GROUP%
      Text German=%GROUP%
      Text Spanish=%GROUP%
      Text Italian=%GROUP%
    end
  end
end
item: Custom Dialog Set
  Name=Start Installation
  Display Variable=DISPLAY
  item: Dialog
    Title=%APPTITLE% Installation
    Title French=Installation de %APPTITLE%
    Title German=Installation von %APPTITLE%
    Title Spanish=Instalaci�n de %APPTITLE%
    Title Italian=Installazione di %APPTITLE%
    Width=271
    Height=224
    Font Name=Helv
    Font Size=8
    item: Push Button
      Rectangle=150 187 195 202
      Variable=DIRECTION
      Value=N
      Create Flags=01010000000000010000000000000001
      Text=&Next >
      Text French=&Suite >
      Text German=&Weiter >
      Text Spanish=&Siguiente >
      Text Italian=&Avanti >
    end
    item: Push Button
      Rectangle=105 187 150 202
      Variable=DIRECTION
      Value=B
      Create Flags=01010000000000010000000000000000
      Text=< &Back
      Text French=< &Retour
      Text German=< &Zur�ck
      Text Spanish=< &Atr�s
      Text Italian=< &Indietro
    end
    item: Push Button
      Rectangle=211 187 256 202
      Action=3
      Create Flags=01010000000000010000000000000000
      Text=&Cancel
      Text French=&Annuler
      Text German=&Abbrechen
      Text Spanish=&Cancelar
      Text Italian=&Annulla
    end
    item: Static
      Rectangle=8 180 256 181
      Action=3
      Create Flags=01010000000000000000000000000111
    end
    item: Static
      Rectangle=86 8 258 42
      Create Flags=01010000000000000000000000000000
      Flags=0000000000000001
      Name=Times New Roman
      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
      Text=Ready to Install!
      Text French=Pr�t � installer !
      Text German=Installationsbereit!
      Text Spanish=�Preparado para la instalaci�n!
      Text Italian=Pronto per l'installazione!
    end
    item: Static
      Rectangle=86 42 256 102
      Create Flags=01010000000000000000000000000000
      Text=You are now ready to install %APPTITLE%.
      Text=
      Text=Press the Next button to begin the installation or the Back button to reenter the installation information.
      Text French=Vous �tes maintenant pr�t � installer les fichiers %APPTITLE%.
      Text French=
      Text French=Cliquez sur le bouton Suite pour commencer l'installation ou sur le bouton Retour pour entrer les informations d'installation � nouveau.
      Text German=Sie k�nnen %APPTITLE% nun installieren.
      Text German=
      Text German=Klicken Sie auf "Weiter", um mit der Installation zu beginnen. Klicken Sie auf "Zur�ck", um die Installationsinformationen neu einzugeben.
      Text Spanish=Ya est� listo para instalar %APPTITLE%.
      Text Spanish=
      Text Spanish=Presione el bot�n Siguiente para comenzar la instalaci�n o presione Atr�s para volver a ingresar la informaci�n para la instalaci�n.
      Text Italian=Ora � possibile installare %APPTITLE%.
      Text Italian=
      Text Italian=Premere il pulsante Avanti per avviare l'installazione o il pulsante Indietro per reinserire le informazioni di installazione.
    end
  end
end
item: If/While Statement
  Variable=DISPLAY
  Value=Select Destination Directory
end
item: Set Variable
  Variable=BACKUP
  Value=%MAINDIR%\BACKUP
end
item: End Block
end
item: End Block
end
item: If/While Statement
  Variable=TYPE
  Value=B
end
item: Set Variable
  Variable=COMPONENTS
  Value=A
end
item: End Block
end
item: If/While Statement
  Variable=DOBACKUP
  Value=A
end
item: Set Variable
  Variable=BACKUPDIR
  Value=%BACKUP%
end
item: End Block
end
remarked item: If/While Statement
  Variable=BRANDING
  Value=1
end
remarked item: If/While Statement
  Variable=DOBRAND
  Value=1
end
remarked item: Edit INI File
  Pathname=%INST%\CUSTDATA.INI
  Settings=[Registration]
  Settings=NAME=%NAME%
  Settings=COMPANY=%COMPANY%
  Settings=
end
remarked item: End Block
end
remarked item: End Block
end
item: Set Variable
  Variable=MAINDIRSHORT
  Value=%MAINDIR%
  Flags=00010100
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
end
item: Install File
  Source=${__TKBASEDIR__}\win\release\tk81.lib
  Destination=%MAINDIR%\lib\tk81.lib
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\win\release\tkstub81.lib
  Destination=%MAINDIR%\lib\tkstub81.lib
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\release\tcl81.lib
  Destination=%MAINDIR%\lib\tcl81.lib
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\release\tclstub81.lib
  Destination=%MAINDIR%\lib\tclstub81.lib
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\xlib\X11\Xutil.h
  Destination=%MAINDIR%\include\X11\Xutil.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\xlib\X11\Xlib.h
  Destination=%MAINDIR%\include\X11\Xlib.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\xlib\X11\Xfuncproto.h
  Destination=%MAINDIR%\include\X11\Xfuncproto.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\xlib\X11\Xatom.h
  Destination=%MAINDIR%\include\X11\Xatom.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\xlib\X11\X.h
  Destination=%MAINDIR%\include\X11\X.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\xlib\X11\keysymdef.h
  Destination=%MAINDIR%\include\X11\keysymdef.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\xlib\X11\keysym.h
  Destination=%MAINDIR%\include\X11\keysym.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\xlib\X11\cursorfont.h
  Destination=%MAINDIR%\include\X11\cursorfont.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\generic\tk.h
  Destination=%MAINDIR%\include\tk.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\generic\tkDecls.h
  Destination=%MAINDIR%\include\tkDecls.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\generic\tkIntXlibDecls.h
  Destination=%MAINDIR%\include\tkIntXlibDecls.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\generic\tcl.h
  Destination=%MAINDIR%\include\tcl.h
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\generic\tclDecls.h
  Destination=%MAINDIR%\include\tclDecls.h
  Flags=0000000000000010
end
item: End Block
end
item: If/While Statement
  Variable=COMPONENTS
  Value=A
  Flags=00001010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\msgcat1.0\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\msgcat1.0\pkgIndex.tcl
  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
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\shiftjis.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macUkraine.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macUkraine.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macTurkish.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macTurkish.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macThai.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macThai.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macRomania.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macRomania.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macRoman.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macRoman.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macJapan.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macJapan.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macIceland.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macIceland.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macGreek.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macGreek.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macDingbats.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macDingbats.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macCyrillic.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macCyrillic.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macCroatian.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macCroatian.enc
  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
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\jis0208.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\jis0201.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\jis0201.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso8859-9.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-9.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso8859-8.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-8.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso8859-7.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-7.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso8859-6.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-6.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso8859-5.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-5.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso8859-4.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-4.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso8859-3.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-3.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso8859-2.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-2.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso8859-1.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso8859-1.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso2022.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso2022.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso2022-kr.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso2022-kr.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\iso2022-jp.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\iso2022-jp.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\gb2312.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\gb2312.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\gb1988.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\gb1988.enc
  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
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp950.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp949.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp949.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp936.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp936.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp932.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp932.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp874.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp874.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp869.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp869.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp866.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp866.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp865.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp865.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp864.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp864.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp863.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp863.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp862.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp862.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp861.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp861.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp860.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp860.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp857.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp857.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp855.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp855.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp852.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp852.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp850.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp850.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp775.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp775.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp737.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp737.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp437.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp437.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp1258.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1258.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp1257.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1257.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp1256.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1256.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp1255.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1255.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp1254.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1254.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp1253.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1253.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp1252.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1252.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp1251.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1251.enc
  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
  Destination=%MAINDIR%\lib\tcl%VER%\opt0.4\optparse.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\http2.0\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\http2.0\pkgIndex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\http2.0\http.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\http2.0\http.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\msgbox.tcl
  Destination=%MAINDIR%\lib\tk%VER%\msgbox.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\optMenu.tcl
  Destination=%MAINDIR%\lib\tk%VER%\optMenu.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\clrpick.tcl
  Destination=%MAINDIR%\lib\tk%VER%\clrpick.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\entry.tcl
  Destination=%MAINDIR%\lib\tk%VER%\entry.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\comdlg.tcl
  Destination=%MAINDIR%\lib\tk%VER%\comdlg.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\bgerror.tcl
  Destination=%MAINDIR%\lib\tk%VER%\bgerror.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\obsolete.tcl
  Destination=%MAINDIR%\lib\tk%VER%\obsolete.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\button.tcl
  Destination=%MAINDIR%\lib\tk%VER%\button.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\xmfbox.tcl
  Destination=%MAINDIR%\lib\tk%VER%\xmfbox.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\console.tcl
  Destination=%MAINDIR%\lib\tk%VER%\console.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\listbox.tcl
  Destination=%MAINDIR%\lib\tk%VER%\listbox.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\menu.tcl
  Destination=%MAINDIR%\lib\tk%VER%\menu.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\dialog.tcl
  Destination=%MAINDIR%\lib\tk%VER%\dialog.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\focus.tcl
  Destination=%MAINDIR%\lib\tk%VER%\focus.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\palette.tcl
  Destination=%MAINDIR%\lib\tk%VER%\palette.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\tkfbox.tcl
  Destination=%MAINDIR%\lib\tk%VER%\tkfbox.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\tk.tcl
  Destination=%MAINDIR%\lib\tk%VER%\tk.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\text.tcl
  Destination=%MAINDIR%\lib\tk%VER%\text.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\tearoff.tcl
  Destination=%MAINDIR%\lib\tk%VER%\tearoff.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\tclIndex
  Destination=%MAINDIR%\lib\tk%VER%\tclIndex
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\scrlbar.tcl
  Destination=%MAINDIR%\lib\tk%VER%\scrlbar.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\scale.tcl
  Destination=%MAINDIR%\lib\tk%VER%\scale.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\safetk.tcl
  Destination=%MAINDIR%\lib\tk%VER%\safetk.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\http1.0\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\http1.0\pkgIndex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\http1.0\http.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\http1.0\http.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\reg1.0\pkgIndex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\release\tclreg81.dll
  Destination=%MAINDIR%\lib\tcl%VER%\reg1.0\tclreg81.dll
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\dde1.0\pkgIndex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\release\tcldde81.dll
  Destination=%MAINDIR%\lib\tcl%VER%\dde1.0\tcldde81.dll
  Flags=0000000000000010
end
item: Install File
  Source=C:\WINNT\SYSTEM32\Msvcrt.dll
  Destination=%MAINDIR%\bin\msvcrt.dll
  Flags=0010001000000011
end
item: Install File
  Source=${__TKBASEDIR__}\win\release\wish81.exe
  Destination=%MAINDIR%\bin\wish81.exe
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\release\tclsh81.exe
  Destination=%MAINDIR%\bin\tclsh81.exe
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\release\tclpip81.dll
  Destination=%MAINDIR%\bin\tclpip81.dll
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\release\tcl81.dll
  Destination=%MAINDIR%\bin\tcl81.dll
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\win\release\tk81.dll
  Destination=%MAINDIR%\bin\tk81.dll
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\auto.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\auto.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\history.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\history.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\init.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\init.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\package.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\package.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\parray.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\parray.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\safe.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\safe.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\tclIndex
  Destination=%MAINDIR%\lib\tcl%VER%\tclIndex
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\word.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\word.tcl
  Flags=0000000000000010
end
item: End Block
end
item: If/While Statement
  Variable=COMPONENTS
  Value=B
  Flags=00001010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\tai-ku.gif
  Destination=%MAINDIR%\lib\tk%VER%\images\tai-ku.gif
  Flags=0000000010000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\teapot.ppm
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\teapot.ppm
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\tcllogo.gif
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\tcllogo.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\pattern.bmp
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\pattern.bmp
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\noletter.bmp
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\noletter.bmp
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\letters.bmp
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\letters.bmp
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\gray25.bmp
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\gray25.bmp
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\flagup.bmp
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\flagup.bmp
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\flagdown.bmp
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\flagdown.bmp
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\face.bmp
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\face.bmp
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\earthris.gif
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\earthris.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\images\earth.gif
  Destination=%MAINDIR%\lib\tk%VER%\demos\images\earth.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\vscale.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\vscale.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\twind.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\twin\released.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\text.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\text.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\style.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\style.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\states.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\states.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\search.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\search.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\sayings.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\sayings.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\ruler.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\ruler.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\radio.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\radio.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\puzzle.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\puzzle.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\plot.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\plot.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\msgbox.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\msgbox.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\menubu.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\menubu.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\menu.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\menu.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\label.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\label.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\items.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\items.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\image2.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\image2.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\image1.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\image1.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\icon.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\icon.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\hscale.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\hscale.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\form.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\form.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\ixset
  Destination=%MAINDIR%\lib\tk%VER%\demos\ixset.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\rolodex
  Destination=%MAINDIR%\lib\tk%VER%\demos\rolodex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\square
  Destination=%MAINDIR%\lib\tk%VER%\demos\square.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\Readme
  Destination=%MAINDIR%\lib\tk%VER%\demos\Readme
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\hello
  Destination=%MAINDIR%\lib\tk%VER%\demos\hello.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\tclIndex
  Destination=%MAINDIR%\lib\tk%VER%\demos\tclIndex
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\browse
  Destination=%MAINDIR%\lib\tk%VER%\demos\browse.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\timer
  Destination=%MAINDIR%\lib\tk%VER%\demos\timer.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\widget
  Destination=%MAINDIR%\lib\tk%VER%\demos\widget.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\tcolor
  Destination=%MAINDIR%\lib\tk%VER%\demos\tcolor.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\rmt
  Destination=%MAINDIR%\lib\tk%VER%\demos\rmt.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\floor.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\floor.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\filebox.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\filebox.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\pwrdLogo75.gif
  Destination=%MAINDIR%\lib\tk%VER%\images\pwrdLogo75.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\pwrdLogo200.gif
  Destination=%MAINDIR%\lib\tk%VER%\images\pwrdLogo200.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\pwrdLogo175.gif
  Destination=%MAINDIR%\lib\tk%VER%\images\pwrdLogo175.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\pwrdLogo150.gif
  Destination=%MAINDIR%\lib\tk%VER%\images\pwrdLogo150.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\pwrdLogo100.gif
  Destination=%MAINDIR%\lib\tk%VER%\images\pwrdLogo100.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\logoMed.gif
  Destination=%MAINDIR%\lib\tk%VER%\images\logoMed.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\logoLarge.gif
  Destination=%MAINDIR%\lib\tk%VER%\images\logoLarge.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\logo64.gif
  Destination=%MAINDIR%\lib\tk%VER%\images\logo64.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\logo100.gif
  Destination=%MAINDIR%\lib\tk%VER%\images\logo100.gif
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\images\Readme
  Destination=%MAINDIR%\lib\tk%VER%\images\Readme
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\arrow.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\arrow.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\bind.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\bind.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\bitmap.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\bitmap.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\button.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\button.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\check.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\check.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\clrpick.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\clrpick.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\colors.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\colors.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\cscroll.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\cscroll.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\ctext.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\ctext.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\dialog1.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\dialog1.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\dialog2.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\dialog2.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\entry1.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\entry1.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TKBASEDIR__}\library\demos\entry2.tcl
  Destination=%MAINDIR%\lib\tk%VER%\demos\entry2.tcl
  Flags=0000000000000010
end
item: End Block
end
item: If/While Statement
  Variable=COMPONENTS
  Value=C
  Flags=00001010
end
item: Install File
  Source=${__TCLBASEDIR__}\tools\tcl81.cnt
  Destination=%MAINDIR%\doc\tcl81.cnt
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\tools\tcl81.hlp
  Destination=%MAINDIR%\doc\tcl81.hlp
  Flags=0000000000000010
end
item: End Block
end
item: Set Variable
  Variable=MAINDIR
  Value=%MAINDIR%
  Flags=00010100
end
item: Include Script
  Pathname=\\pop\tools\1.2\win32-ix86\wise\INCLUDE\uninstal.wse
end
item: Check Configuration
  Flags=10111011
end
item: Get Registry Key Value
  Variable=GROUPDIR
  Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
  Default=%WIN%\Start Menu\Programs
  Value Name=Programs
  Flags=00000010
end
item: Set Variable
  Variable=GROUP
  Value=%GROUPDIR%\%GROUP%
end
item: If/While Statement
  Variable=COMPONENTS
  Value=A
  Flags=00001010
end
item: Create Shortcut
  Source=%MAINDIR%\bin\wish81.exe
  Destination=%GROUP%\Wish.lnk
  Working Directory=%MAINDIR%
end
item: End Block
end
item: If/While Statement
  Variable=COMPONENTS
  Value=A
  Flags=00001010
end
item: Create Shortcut
  Source=%MAINDIR%\bin\tclsh81.exe
  Destination=%GROUP%\Tclsh.lnk
  Working Directory=%MAINDIR%
  Key Type=1536
  Flags=00000001
end
item: End Block
end
item: If/While Statement
  Variable=COMPONENTS
  Value=C
  Flags=00001010
end
item: Create Shortcut
  Source=%MAINDIR%\doc\tcl81.hlp
  Destination=%GROUP%\Tcl Help.lnk
  Working Directory=%MAINDIR%
end
item: End Block
end
item: Create Shortcut
  Source=%MAINDIR%\Readme.txt
  Destination=%GROUP%\Readme.lnk
  Working Directory=%MAINDIR%
end
item: If/While Statement
  Variable=COMPONENTS
  Value=B
  Flags=00001010
end
item: Create Shortcut
  Source=%MAINDIR%\lib\tk%VER%\demos\widget.tcl
  Destination=%GROUP%\Widget Tour.lnk
  Working Directory=%MAINDIR%
  Key Type=1536
  Flags=00000001
end
item: End Block
end
item: Else Statement
end
item: If/While Statement
  Variable=COMPONENTS
  Value=B
  Flags=00001010
end
item: Add ProgMan Icon
  Group=%GROUP%
  Icon Name=Widget Tour
  Command Line=%MAINDIR%\lib\tk%VER%\demos\widget.tcl
  Icon Pathname=%MAINDIR%\bin\wish81.exe
  Default Directory=%MAINDIR%
end
item: End Block
end
item: If/While Statement
  Variable=COMPONENTS
  Value=C
  Flags=00001010
end
item: Add ProgMan Icon
  Group=%GROUP%
  Icon Name=Tcl Help
  Command Line=%MAINDIR%\doc\tcl81.hlp
  Default Directory=%MAINDIR%
end
item: End Block
end
item: Add ProgMan Icon
  Group=%GROUP%
  Icon Name=Readme
  Command Line=%MAINDIR%\Readme.txt
  Default Directory=%MAINDIR%
end
item: If/While Statement
  Variable=COMPONENTS
  Value=A
  Flags=00001010
end
item: Add ProgMan Icon
  Group=%GROUP%
  Icon Name=Wish
  Command Line=%MAINDIR%\bin\wish81.exe
  Default Directory=%MAINDIR%
end
item: End Block
end
item: If/While Statement
  Variable=COMPONENTS
  Value=A
  Flags=00001010
end
item: Add ProgMan Icon
  Group=%GROUP%
  Icon Name=Tclsh
  Command Line=%MAINDIR%\bin\tclsh81.exe
  Default Directory=%MAINDIR%
end
item: End Block
end
item: End Block
end
item: Self-Register OCXs/DLLs
  Description=Updating System Configuration, Please Wait...
end
item: Edit Registry
  Total Keys=1
  Key=SOFTWARE\Sun\Tcl\%VER%
  New Value=%MAINDIR%
  Value Name=Root
  Root=2
end
item: Edit Registry
  Total Keys=1
  Key=TclScript\DefaultIcon
  New Value=%MAINDIR%\bin\tk81.dll
end
item: Edit Registry
  Total Keys=1
  Key=.tcl
  New Value=TclScript
end
item: Edit Registry
  Total Keys=1
  Key=TclScript
  New Value=TclScript
end
item: Edit Registry
  Total Keys=1
  Key=TclScript\shell\open\command
  New Value=%MAINDIRSHORT%\bin\wish81.exe "%%1"
end
item: Edit Registry
  Total Keys=1
  Key=TclScript\shell\edit
  New Value=&Edit
end
item: Edit Registry
  Total Keys=1
  Key=TclScript\shell\edit\command
  New Value=notepad "%%1"
end
item: Add Directory to Path
  Directory=%MAINDIR%\bin
end
item: Check Configuration
  Flags=10111011
end
item: Set Variable
  Variable=TO_SCRIPTICS
  Value=A
end
item: Else Statement
end
item: Set Variable
  Variable=TO_SCRIPTICS
end
item: End Block
end
item: Wizard Block
  Direction Variable=DIRECTION
  Display Variable=DISPLAY
  Bitmap Pathname=%_WISE_%\DIALOGS\TEMPLATE\WIZARD.BMP
  X Position=9
  Y Position=10
  Filler Color=8421440
  Flags=00000011
end
item: Custom Dialog Set
  Name=Finished
  Display Variable=DISPLAY
  item: Dialog
    Title=%APPTITLE% Installation
    Title French=Installation de %APPTITLE%
    Title German=Installation von %APPTITLE%
    Title Spanish=Instalaci�n de %APPTITLE%
    Title Italian=Installazione di %APPTITLE%
    Width=271
    Height=224
    Font Name=Helv
    Font Size=8
    item: Push Button
      Rectangle=150 187 195 202
      Variable=DIRECTION
      Value=N
      Create Flags=01010000000000010000000000000001
      Text=&Finish
      Text French=&Fin
      Text German=&Weiter
      Text Spanish=&Terminar
      Text Italian=&Fine
    end
    item: Push Button
      Rectangle=105 187 150 202
      Variable=DISABLED
      Value=!
      Create Flags=01010000000000010000000000000000
      Text=< &Back
      Text French=< &Retour
      Text German=< &Zur�ck
      Text Spanish=< &Atr�s
      Text Italian=< &Indietro
    end
    item: Push Button
      Rectangle=211 187 256 202
      Variable=DISABLED
      Value=!
      Action=3
      Create Flags=01010000000000010000000000000000
      Text=&Cancel
      Text French=&Annuler
      Text German=&Abbrechen
      Text Spanish=&Cancelar
      Text Italian=&Annulla
    end
    item: Static
      Rectangle=8 180 256 181
      Action=3
      Create Flags=01010000000000000000000000000111
    end
    item: Static
      Rectangle=86 8 258 42
      Create Flags=01010000000000000000000000000000
      Flags=0000000000000001
      Name=Times New Roman
      Font Style=-24 0 0 0 700 255 0 0 0 3 2 1 18
      Text=Installation Completed!
      Text French=Installation termin�e !
      Text German=Die Installation ist abgeschlossen!
      Text Spanish=�Instalaci�n terminada!
      Text Italian=Installazione completata!
    end
    item: Static
      Rectangle=86 42 256 153
      Create Flags=01010000000000000000000000000000
      Text=%APPTITLE% has been successfully installed.
      Text=
      Text=Click the Finish button to exit this installation.
      Text=
      Text=You can learn more about Tcl/Tk %VER%, including release notes, updates, tutorials, and more at %URL%.  Check the box below to start your web browser and go there now.
      Text=
      Text=The installer may ask you to reboot your computer, this is to update your PATH and is not necessary to do immediately.
      Text French=%APPTITLE% est maintenant install�.
      Text French=
      Text French=Cliquez sur le bouton Fin pour quitter l'installation.
      Text German=%APPTITLE% wurde erfolgreich installiert.
      Text German=
      Text German=Klicken Sie auf "Weiter", um die Installation zu beenden.
      Text Spanish=%APPTITLE% se ha instalado con �xito.
      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
item: If/While Statement
  Variable=TO_SCRIPTICS
  Value=A
  Flags=00000010
end
item: Execute Program
  Command Line=%URL%
end
item: End Block
end
item: Execute Program
  Pathname=explorer
  Command Line=%GROUP%
end
item: End Block
end

Added tools/tcl8.1-tk8.1-man-html.tcl.





























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
#!/usr/local/bin/tclsh8.0
#
# Convert Ousterhout format man pages into highly crosslinked
# hypertext.
#
# Along the way detect many unmatched font changes and other odd
# things.
#
# Note well, this program is a hack rather than a piece of software
# engineering.  In that sense it's probably a good example of things
# that a scripting language, like Tcl, can do well.  It is offered as
# an example of how someone might convert a specific set of man pages
# into hypertext, not as a general solution to the problem.  If you
# try to use this, you'll be very much on your own.
#
# Copyright (c) 1995-1997 Roger E. Critchlow Jr
#
# The authors hereby grant permission to use, copy, modify, distribute,
# and license this software and its documentation for any purpose, provided
# that existing copyright notices are retained in all copies and that this
# notice is included verbatim in any distributions. No written agreement,
# license, or royalty fee is required for any of the authorized uses.
# Modifications to this software may be copyrighted by their authors
# and need not follow the licensing terms described here, provided that
# the new terms are clearly indicated on the first page of each file where
# they apply.
# 
# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# 
# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
# MODIFICATIONS.
#
# Revisions:
#  May 15, 1995 - initial release
#  May 16, 1995 - added a back to home link to toplevel table of
#	contents.
#  May 18, 1995 - broke toplevel table of contents into separate
#	pages for each section, and broke long table of contents
#	into a one page for each man page.
#  Mar 10, 1996 - updated for tcl7.5b3/tk4.1b3
#  Apr 14, 1996 - incorporated command line parsing from Tom Tromey,
#		  <[email protected]> -- thanks Tom.
#		- updated for tcl7.5/tk4.1 final release.
#		- converted to same copyright as the man pages.
#  Sep 14, 1996 - made various modifications for tcl7.6b1/tk4.2b1
#  Oct 18, 1996 - added tcl7.6/tk4.2 to the list of distributions.
#  Oct 22, 1996 - major hacking on indentation code and elsewhere.
#  Mar  4, 1997 - 
#  May 28, 1997 - added tcl8.0b1/tk8.0b1 to the list of distributions
#		- cleaned source for tclsh8.0 execution
#		- renamed output files for windoze installation
#		- added spaces to tables
#  Oct 24, 1997 - moved from 8.0b1 to 8.0 release
#

set Version "0.14"

proc parse_command_line {} {
    global argv Version

    # These variables determine where the man pages come from and where
    # the converted pages go to.
    global tcltkdir tkdir tcldir webdir

    # Set defaults based on original code.
    set tcltkdir ../..
    set tkdir {}
    set tcldir {}
    set webdir ../html

    # Directory names for Tcl and Tk, in priority order.
    set tclDirList {tcl8.1 tcl8.0 tcl tcl7.4 tcl7.5 tcl7.6}
    set tkDirList {tk8.1 tk8.0 tk tk4.0 tk4.1 tk4.2}

    # Handle arguments a la GNU:
    #   --version
    #   --help
    #   --srcdir=/path
    #   --htmldir=/path

    foreach option $argv {
	switch -glob -- $option {
	    --version {
		puts "tcltk-man-html $Version"
		exit 0
	    }

	    --help {
		puts "usage: tcltk-man-html \[OPTION\] ...\n"
		puts "  --help              print this help, then exit"
		puts "  --version           print version number, then exit"
		puts "  --srcdir=DIR        find tcl and tk source below DIR"
		puts "  --htmldir=DIR       put generated HTML in DIR"
		exit 0
	    }

	    --srcdir=* {
		# length of "--srcdir=" is 9.
		set tcltkdir [string range $option 9 end]
	    }

	    --htmldir=* {
		# length of "--htmldir=" is 10
		set webdir [string range $option 10 end]
	    }

	    default {
		puts stderr "tcltk-man-html: unrecognized option -- `$option'"
		exit 1
	    }
	}
    }

    # Find Tcl.
    foreach dir $tclDirList {
	if {[file isdirectory $tcltkdir/$dir]} then {
	    set tcldir $dir
	    break
	}
    }
    if {$tcldir == ""} then {
	puts stderr "tcltk-man-html: couldn't find Tcl below $tcltkdir"
	exit 1
    }

    # Find Tk.
    foreach dir $tkDirList {
	if {[file isdirectory $tcltkdir/$dir]} then {
	    set tkdir $dir
	    break
	}
    }
    if {$tkdir == ""} then {
	puts stderr "tcltk-man-html: couldn't find Tk below $tcltkdir"
	exit 1
    }

    # the title for the man pages overall
    global overall_title
    set overall_title "[capitalize $tcldir]/[capitalize $tkdir] Manual"
}

proc capitalize {string} {
    return [string toupper [string index $string 0]][string range $string 1 end]
}

##
##
##
set manual(report-level) 1;

proc manerror {msg} {
    global manual;
    set name {};
    set subj {};
    if {[info exists manual(name)]} {
	set name $manual(name);
    }
    if {[info exists manual(section)] && "$manual(section)" != {}} {
	puts stderr "$name: $manual(section):  $msg";
    } else {
	puts stderr "$name: $msg";
    }
}

proc manreport {level msg} {
    global manual;
    if {$level < $manual(report-level)} {
	manerror $msg;
    }
}

proc fatal {msg} {
    global manual;
    manerror $msg;
    exit 1;
}
##
## parsing
##
proc unquote arg {
    regsub -all \" $arg {} arg;
    return $arg;
}

proc parse-directive {line codename restname} {
    upvar $codename code $restname rest;
    return [regexp {^(\.[.a-zA-Z0-9]*) *(.*)} $line all code rest];
}

proc process-text {text} {
    global manual;
    # preprocess text
    regsub -all {\\&} $text \t text;		# some kind of tab?
    regsub -all {&} $text {\&amp;} text;
    regsub -all {\\\\} $text {\&#92;} text;	# reverse solidus, ie backslash
    regsub -all {\\ } $text {\&nbsp;} text;	# non breaking space
    regsub -all {\\%} $text {} text;		# don't break word following?
    regsub -all "\\\\\n" $text "\n" text;	# 
    regsub -all \" $text {\&quot;} text;
    regsub -all {<} $text {\&lt;} text;
    regsub -all {>} $text {\&gt;} text;
    regsub -all {\\-\\\|\\-} $text -- text;	# two hyphens
    regsub -all -- {\\-\\\^\\-} $text -- text;	# two hyphens
    regsub -all {\\-} $text - text;		# a hyphen
    regsub -all {\\0} $text { } text;		# a space
    # regsub -all {\\\|} $text | text;		# a very thin space 
    regsub -all {\\e} $text {\&#92;} text;	# reverse solidus, ie backslash
    regsub -all {\\\(\+-} $text {\&#177;} text;	# plus or minus sign
    regsub -all {\\fP} $text {\\fR} text;	# a funky font in expr.n
    regsub -all {\\\.} $text . text;		# a plain .
    regsub -all "\\\\\n" $text "\\&\#92;\n" text;	# an escaped newline
    while {[regexp {\\} $text]} {
	# C R
	if {[regsub {^([^\\]*)\\fC([^\\]*)\\fR(.*)$} $text {\1<TT>\2</TT>\3} text]} continue
	# B R
	if {[regsub {^([^\\]*)\\fB([^\\]*)\\fR(.*)$} $text {\1<B>\2</B>\3} text]} continue
	# B I
	if {[regsub {^([^\\]*)\\fB([^\\]*)\\fI(.*)$} $text {\1<B>\2</B>\\fI\3} text]} continue
	# I R
	if {[regsub {^([^\\]*)\\fI([^\\]*)\\fR(.*)$} $text {\1<I>\2</I>\3} text]} continue
	# I B
	if {[regsub {^([^\\]*)\\fI([^\\]*)\\fB(.*)$} $text {\1<I>\2</I>\\fB\3} text]} continue
	# B B, I I, R R
	if {[regsub {^([^\\]*)\\fB([^\\]*)\\fB(.*)$} $text {\1\\fB\2\3} ntext]
	    || [regsub {^([^\\]*)\\fI([^\\]*)\\fI(.*)$} $text {\1\\fI\2\3} ntext]
	    || [regsub {^([^\\]*)\\fR([^\\]*)\\fR(.*)$} $text {\1\\fR\2\3} ntext]} {
	    manerror "process-text: impotent font change: $text";
	    set text $ntext;
	    continue;
	}
	# unrecognized 
	manerror "process-text: uncaught backslash: $text"
	regsub -all {\\} $text {#92;} text
    }
    return $text
}    
##
## pass 2 text input and matching
##
proc open-text {} {
    global manual;
    set manual(text-length) [llength $manual(text)];
    set manual(text-pointer) 0;
}
proc more-text {} {
    global manual;
    return [expr $manual(text-pointer) < $manual(text-length)];
}
proc next-text {} {
    global manual;
    if {[more-text]} {
	set text [lindex $manual(text) $manual(text-pointer)];
	incr manual(text-pointer);
	return $text;
    }
    manerror "read past end of text";
    error "fatal";
}
proc is-a-directive {line} {
    return [expr {[string first . $line] == 0}]
}
proc split-directive {line opname restname} {
    upvar $opname op $restname rest
    set op [string range $line 0 2];
    set rest [string trim [string range $line 3 end]];
}
proc next-op-is {op restname} {
    global manual;
    upvar $restname rest;
    if {[more-text]} {
	set text [lindex $manual(text) $manual(text-pointer)];
	if {[string compare [string range $text 0 2] $op] == 0} {
	    set rest [string range $text 4 end];
	    incr manual(text-pointer);
	    return 1;
	}
    }
    return 0;
}
proc backup-text {n} {
    global manual;
    if {$manual(text-pointer)-$n >= 0} {
	incr manual(text-pointer) -$n;
    }
}
proc match-text args {
    global manual;
    set nargs [llength $args];
    if {$manual(text-pointer) + $nargs > $manual(text-length)} {
	return 0;
    }
    set nback 0;
    foreach arg $args {
	if { ! [more-text]} {
	    backup-text $nback;
	    return 0;
	}
	set arg [string trim $arg];
	set targ [string trim [lindex $manual(text) $manual(text-pointer)]];
	if {"$arg" == "$targ"} {
	    incr nback;
	    incr manual(text-pointer);
	    continue;
	}
	if {[regexp {^@([_a-zA-Z0-9]+)$} $arg all name]} {
	    upvar $name var;
	    set var $targ;
	    incr nback;
	    incr manual(text-pointer);
	    continue;
	}
	if {[regexp {^(\.[a-zA-Z][a-zA-Z])@([_a-zA-Z0-9]+)$} $arg all op name] && "$op" == "[lindex $targ 0]"} {
	    upvar $name var;
	    set var [lrange $targ 1 end];
	    incr nback;
	    incr manual(text-pointer);
	    continue;
	}
	backup-text $nback;
	return 0;
    }
    return 1;
}
proc expand-next-text {n} {
    global manual;
    return [join [lrange $manual(text) $manual(text-pointer) [expr $manual(text-pointer)+$n-1]] \n\n];
}
##
## pass 2 output
##
proc man-puts {text} {
    global manual;
    lappend manual(output-$manual(wing-file)-$manual(name)) $text;
}

##
## build hypertext links to tables of contents
##
proc long-toc {text} {
    global manual;
    set here M[incr manual(section-toc-n)]
    set there L[incr manual(long-toc-n)];
    lappend manual(section-toc) "<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$text</A>";
    return "<A NAME=\"$here\">$text</A>";
}
proc option-toc {name class switch} {
    global manual;
    if {"$manual(section)" == {WIDGET-SPECIFIC OPTIONS}} {
	# link the defined option into the long table of contents
	set link [long-toc "$switch, $name, $class"];
	regsub -- "$switch, $name, $class" $link "$switch" link;
	return $link;
    } elseif {"$manual(name):$manual(section)" == {options:DESCRIPTION}} {
	# link the defined standard option to the long table of
	# contents and make a target for the standard option references
	# from other man pages.
	set first [lindex $switch 0];
	set here M$first;
	set there L[incr manual(long-toc-n)];
	set manual(standard-option-$first) "<A HREF=\"$manual(name).htm#$here\">$switch, $name, $class</A>";
	lappend manual(section-toc) "<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$switch, $name, $class</A>";
	return "<A NAME=\"$here\">$switch</A>";
    } else {
	error "option-toc in $manual(name) section $manual(section)";
    }
}
proc std-option-toc {name} {
    global manual;
    if {[info exists manual(standard-option-$name)]} {
	lappend manual(section-toc) <DD>$manual(standard-option-$name);
	return $manual(standard-option-$name);
    }
    set here M[incr manual(section-toc-n)]
    set there L[incr manual(long-toc-n)];
    set other M$name;
    lappend manual(section-toc) "<DD><A HREF=\"options.htm#$other\">$name</A>";
    return "<A HREF=\"options.htm#$other\">$name</A>";
}
##
## process the widget option section
## in widget and options man pages
##
proc output-widget-options {rest} {
    global manual
    man-puts <DL>;
    lappend manual(section-toc) <DL>;
    backup-text 1;
    set para {}
    while {[next-op-is .OP rest]} {
	switch -exact [llength $rest] {
	    3 {
		set switch [lindex $rest 0];
		set name [lindex $rest 1];
		set class [lindex $rest 2];
	    }
	    5 {
		set switch [lrange $rest 0 2];
		set name [lindex $rest 3];
		set class [lindex $rest 4];
	    }
	    default {
		fatal "bad .OP $rest";
	    }
	}
	if { ! [regexp {^(<.>)([-a-zA-Z0-9 ]+)(</.>)$} $switch all oswitch switch cswitch]} {
	    if { ! [regexp {^(<.>)([-a-zA-Z0-9 ]+) or ([-a-zA-Z0-9 ]+)(</.>)$} $switch all oswitch switch1 switch2 cswitch]} {
		error "not Switch: $switch";
	    } else {
		set switch "$switch1$cswitch or $oswitch$switch2";
	    }
	}
	if { ! [regexp {^(<.>)([a-zA-Z0-9]*)(</.>)$} $name all oname name cname]} {
	    error "not Name: $name";
	}
	if { ! [regexp {^(<.>)([a-zA-Z0-9]*)(</.>)$} $class all oclass class cclass]} {
	    error "not Class: $class";
	}
	man-puts "$para<DT>Command-Line Name: $oswitch[option-toc $name $class $switch]$cswitch";
	man-puts "<DT>Database Name: $oname$name$cname";
	man-puts "<DT>Database Class: $oclass$class$cclass";
	man-puts <DD>[next-text];
	set para <P>
    }
    man-puts </DL>;
    lappend manual(section-toc) </DL>;
}

##
## process .RS lists
##
proc output-RS-list {} {
    global manual;
    if {[next-op-is .IP rest]} {
	output-IP-list .RS .IP $rest;
	if {[match-text .RE .sp .RS @rest .IP @rest2]} {
	    man-puts <P>$rest
	    output-IP-list .RS .IP $rest2
	}
	if {[match-text .RE .sp .RS @rest .RE]} {
	    man-puts <P>$rest
	    return;
	}
	if {[next-op-is .RE rest]} {
	    return;
	}
    }
    man-puts <DL><P><DD>;
    while {[more-text]} {
	set line [next-text];
	if {[is-a-directive $line]} {
	    split-directive $line code rest
	    switch -exact $code {
		.RE {
		    break;
		}
		.SH {
		    manerror "unbalanced .RS at section end";
		    backup-text 1;
		    break;
		}
		default {
		    output-directive $line;
		}
	    }
	} else {
	    man-puts $line;
	}
    }	
    man-puts </DL>;
}

##
## process .IP lists which may be plain indents,
## numeric lists, or definition lists
##
proc output-IP-list {context code rest} {
    global manual;
    if {"$rest" == {}} {
	# blank label, plain indent, no contents entry
	man-puts <DL><P><DD>
	while {[more-text]} {
	    set line [next-text];
	    if {[is-a-directive $line]} {
		split-directive $line code rest
		if {"$code" == {.IP} && "$rest" == {}} {
		    man-puts "<P>";
		    continue;
		}
		if {[lsearch {.br .DS .RS} $code] >= 0} {
		    output-directive $line;
		} else {
		    backup-text 1;
		    break;
		}
	    } else {
		man-puts $line;
	    }
	}
	man-puts </DL>;
    } else {
	# labelled list, make contents
	if {"$context" != {.SH}} {
	    man-puts <P>;
	}
	man-puts <DL>
	lappend manual(section-toc) <DL>;
	backup-text 1
	set accept_RE 0
	while {[more-text]} {
	    set line [next-text];
	    if {[is-a-directive $line]} {
		split-directive $line code rest
		switch -exact $code {
		    .IP {
			if {$accept_RE} {
			    output-IP-list .IP $code $rest
			    continue;
			}
			if {"$manual(section)" == {ARGUMENTS} || [regexp {^\[[0-9]+\]$} $rest]} {
			    man-puts "<P><DT>$rest<DD>";
			} else {
			    man-puts "<P><DT>[long-toc $rest]<DD>";
			}
			if {"$manual(name):$manual(section)" == {selection:DESCRIPTION}} {
			    if {[match-text .RE @rest .RS .RS]} {
				man-puts <DT>[long-toc $rest]<DD>;
			    }
			}
		    }
		    .sp -
		    .br -
		    .DS -
		    .CS {
			output-directive $line;
		    }
		    .RS {
			if {[match-text .RS]} {
			    output-directive $line;
			    incr accept_RE 1;
			} elseif {[match-text .CS]} {
			    output-directive .CS
			    incr accept_RE 1;
			} elseif {[match-text .PP]} {
			    output-directive .PP
			    incr accept_RE 1;
			} elseif {[match-text .DS]} {
			    output-directive .DS
			    incr accept_RE 1;
			} else {
			    output-directive $line;
			}
		    }
		    .PP {
			if {[match-text @rest1 .br @rest2 .RS]} {
			    # yet another nroff kludge as above
			    man-puts "<P><DT>[long-toc $rest1]"
			    man-puts "<DT>[long-toc $rest2]<DD>"
			    incr accept_RE 1;
			} elseif {[match-text @rest .RE]} {
			    # gad, this is getting ridiculous
			    if { ! $accept_RE} {
				man-puts "</DL><P>$rest<DL>"
				backup-text 1
				break;
			    } else {
				man-puts "<P>$rest"
				incr accept_RE -1
			    }
			} elseif {$accept_RE} {
			    output-directive $line
			} else {
			    backup-text 1
			    break;
			}
		    }
		    .RE {
			if { ! $accept_RE} {
			    backup-text 1;
			    break;
			}
			incr accept_RE -1
		    }
		    default {
			backup-text 1;
			break;
		    }
		}
	    } else {
		man-puts $line;
	    }
	}
	man-puts <P></DL>;
	lappend manual(section-toc) </DL>;
	if {$accept_RE} {
	    manerror "missing .RE in output-IP-list"
	}
    }
}
##
## handle the NAME section lines
## there's only one line in the NAME section,
## consisting of a comma separated list of names,
## followed by a hyphen and a short description.
##
proc output-name {line} {
    global manual;
    # split name line into pieces
    regexp {^([^-]+) - (.*)$} $line all head tail;
    # output line to manual page untouched
    man-puts $line
    # output line to long table of contents
    lappend manual(section-toc) <DL><DD>$line</DL>
    # separate out the names for future reference
    foreach name [split $head ,] {
	set name [string trim $name];
	if {[llength $name] > 1} {
	    manerror "name has a space: {$name}\nfrom: $line";
	}
	lappend manual(wing-toc) $name;
	lappend manual(name-$name) $manual(wing-file)/$manual(name);
    }
}
##
## build a cross-reference link if appropriate
##
proc cross-reference {ref} {
    global manual;
    if {[string match Tcl_* $ref]} {
	set lref $ref;
    } elseif {[string match Tk_* $ref]} {
	set lref $ref;
    } elseif {"$ref" == {Tcl}} {
	set lref $ref;
    } else {
	set lref [string tolower $ref];
    }
    ##
    ## nothing to reference
    ##
    if { ! [info exists manual(name-$lref)]} {
	foreach name {array file history info interp string trace
	    after clipboard grab image option pack place selection tk tkwait update winfo wm} {
	    if {[regexp "^$name \[a-z0-9]*\$" $lref] && "$manual(tail)" != "$name.n"} {
		return "<A HREF=\"../$manual(name-$name).htm\">$ref</A>";
	    }
	}
	if {[lsearch {stdin stdout stderr end} $lref] >= 0} {
	    # no good place to send these
	    # tcl tokens?
	    # also end
	}
	return $ref;
    }
    ##
    ## would be a self reference
    ##
    foreach name $manual(name-$lref) {
	if {[lsearch $name $manual(wing-file)/$manual(name)] >= 0} {
	    return $ref;
	}
    }
    ##
    ## multiple choices for reference
    ##
    if {[llength $manual(name-$lref)] > 1} {
	set tcl_i [lsearch -glob $manual(name-$lref) *TclCmd*];
	set tcl_ref [lindex $manual(name-$lref) $tcl_i];
	set tk_i [lsearch -glob $manual(name-$lref) *TkCmd*];
	set tk_ref [lindex $manual(name-$lref) $tk_i];
	if {$tcl_i >= 0 && "$manual(wing-file)" == {TclCmd} ||  "$manual(wing-file)" == {TclLib}} {
	    return "<A HREF=\"../$tcl_ref.htm\">$ref</A>";
	}
	if {$tk_i >= 0 && "$manual(wing-file)" == {TkCmd} || "$manual(wing-file)" == {TkLib}} {
	    return "<A HREF=\"../$tk_ref.htm\">$ref</A>";
	}
	if {"$lref" == {exit} && "$manual(tail)" == {tclsh.1} && $tcl_i >= 0} {
	    return "<A HREF=\"../$tcl_ref.htm\">$ref</A>";
	}
	puts stderr "multiple cross reference to $ref in $manual(name-$lref) from $manual(wing-file)/$manual(tail)";
	return $ref;
    }
    ##
    ## exceptions, sigh, to the rule
    ##
    switch $manual(tail) {
	canvas.n {
	    if {$lref == {focus}} {
		upvar tail tail;
		set clue [string first command $tail];
		if {$clue < 0 ||  $clue > 5} {
		    return $ref;
		}
	    }
	    if {[lsearch {bitmap image text} $lref] >= 0} {
		return $ref;
	    }
	}
	checkbutton.n -
	radiobutton.n {
	    if {[lsearch {image} $lref] >= 0} {
		return $ref;
	    }
	}
	menu.n {
	    if {[lsearch {checkbutton radiobutton} $lref] >= 0} {
		return $ref;
	    }
	}
	options.n {
	    if {[lsearch {bitmap image set} $lref] >= 0} {
		return $ref;
	    }
	}
	regexp.n {
	    if {[lsearch {string} $lref] >= 0} {
		return $ref;
	    }
	}
	source.n {
	    if {[lsearch {text} $lref] >= 0} {
		return $ref;
	    }
	}
	history.n {
	    if {[lsearch {exec} $lref] >= 0} {
		return $ref;
	    }
	}
	return.n {
	    if {[lsearch {error continue break} $lref] >= 0} {
		return $ref;
	    }
	}
	scrollbar.n {
	    if {[lsearch {set} $lref] >= 0} {
		return $ref;
	    }
	}
    }
    ##
    ## return the cross reference
    ##
    return "<A HREF=\"../$manual(name-$lref).htm\">$ref</A>";
}
##
## reference generation errors
##
proc reference-error {msg text} {
    global manual;
    puts stderr "$manual(tail): $msg: {$text}";
    return $text;
}
##
## insert as many cross references into this text string as are appropriate
##
proc insert-cross-references {text} {
    global manual;
    ##
    ## we identify cross references by:
    ##     ``quotation''
    ##    <B>emboldening</B>
    ##    Tcl_ prefix
    ##    Tk_ prefix
    ##	  [a-zA-Z0-9]+ manual entry
    ## and we avoid messing with already anchored text
    ##
    ##
    ## find where each item lives
    ##
    array set offset [list \
			  anchor [string first {<A } $text] \
			  end-anchor [string first {</A>} $text] \
			  quote [string first {``} $text] \
			  end-quote [string first {''} $text] \
			  bold [string first {<B>} $text] \
			  end-bold [string first {</B>} $text] \
			  tcl [string first {Tcl_} $text] \
			  tk [string first {Tk_} $text] \
			  Tcl1 [string first {Tcl manual entry} $text] \
			  Tcl2 [string first {Tcl overview manual entry} $text] \
		     ];
    ##
    ## accumulate a list
    ##
    foreach name [array names offset] {
	if {$offset($name) >= 0} {
	    set invert($offset($name)) $name;
	    lappend offsets $offset($name);
	}
    }
    ##
    ## if nothing, then we're done.
    ##
    if { ! [info exists offsets]} {
	return $text;
    }
    ##
    ## sort the offsets
    ##
    set offsets [lsort -integer $offsets];
    ##
    ## see which we want to use
    ##
    switch -exact $invert([lindex $offsets 0]) {
	anchor {
	    if {$offset(end-anchor) < 0} { return [reference-error {Missing end anchor} $text]; }
	    set head [string range $text 0 $offset(end-anchor)];
	    set tail [string range $text [expr $offset(end-anchor)+1] end];
	    return $head[insert-cross-references $tail]
	}
	quote {
	    if {$offset(end-quote) < 0} { return [reference-error {Missing end quote} $text]; }
	    if {"$invert([lindex $offsets 1])" == {tk}} { set offsets [lreplace $offsets 1 1]; }
	    if {"$invert([lindex $offsets 1])" == {tcl}} { set offsets [lreplace $offsets 1 1]; }
	    switch -exact $invert([lindex $offsets 1]) {
		end-quote {
		    set head [string range $text 0 [expr $offset(quote)-1]]
		    set body [string range $text [expr $offset(quote)+2] [expr $offset(end-quote)-1]];
		    set tail [string range $text [expr $offset(end-quote)+2] end];
		    return $head``[cross-reference $body]''[insert-cross-references $tail];
		}
		bold -
		anchor {
		    set head [string range $text 0 [expr $offset(end-quote)+1]]
		    set tail [string range $text [expr $offset(end-quote)+2] end];
		    return $head[insert-cross-references $tail];
		}
	    }
	    return [reference-error {Uncaught quote case} $text];
	}
	bold {
	    if {$offset(end-bold) < 0} { return $text; }
	    if {"$invert([lindex $offsets 1])" == {tk}} { set offsets [lreplace $offsets 1 1]; }
	    if {"$invert([lindex $offsets 1])" == {tcl}} { set offsets [lreplace $offsets 1 1]; }
	    switch -exact $invert([lindex $offsets 1]) {
		end-bold {
		    set head [string range $text 0 [expr $offset(bold)-1]]
		    set body [string range $text [expr $offset(bold)+3] [expr $offset(end-bold)-1]];
		    set tail [string range $text [expr $offset(end-bold)+4] end];
		    return $head<B>[cross-reference $body]</B>[insert-cross-references $tail];
		}
		anchor {
		    set head [string range $text 0 [expr $offset(end-bold)+3]]
		    set tail [string range $text [expr $offset(end-bold)+4] end];
		    return $head[insert-cross-references $tail];
		}
	    }
	    return [reference-error {Uncaught bold case} $text];
	}
	tk {
	    set head [string range $text 0 [expr $offset(tk)-1]]
	    set tail [string range $text $offset(tk) end];
	    if { ! [regexp {^(Tk_[a-zA-Z0-9_]+)(.*)$} $tail all body tail]} { return [reference-error {Tk regexp failed} $text]; }
	    return $head[cross-reference $body][insert-cross-references $tail];
	}
	tcl {
	    set head [string range $text 0 [expr $offset(tcl)-1]]
	    set tail [string range $text $offset(tcl) end];
	    if { ! [regexp {^(Tcl_[a-zA-Z0-9_]+)(.*)$} $tail all body tail]} { return [reference-error {Tcl regexp failed} $text]; }
	    return $head[cross-reference $body][insert-cross-references $tail];
	}
	Tcl1 -
	Tcl2 {
	    set off [lindex $offsets 0];
	    set head [string range $text 0 [expr $off-1]];
	    set body Tcl
	    set tail [string range $text [expr $off+3] end];
	    return $head[cross-reference $body][insert-cross-references $tail];
	}
	end-anchor -
	end-bold -
	end-quote {
	    return [reference-error "Out of place $invert([lindex $offsets 0])" $text];
	}
    }
}
##
## process formatting directives
##
proc output-directive {line} {
    global manual;
    # process format directive
    split-directive $line code rest
    switch -exact $code {
	.BS -
	.BE {
	    # man-puts <HR>;
	}
	.SH {
	    # drain any open lists
	    # announce the subject
	    set manual(section) $rest;
	    # start our own stack of stuff
	    set manual($manual(name)-$manual(section)) {};
	    lappend manual(has-$manual(section)) $manual(name);
	    man-puts "<H3>[long-toc $manual(section)]</H3>";
	    # some sections can simply free wheel their way through the text
	    # some sections can be processed in their own loops
	    switch -exact $manual(section) {
		NAME {
		    if {[lsearch {CrtImgType.3 CrtItemType.3 CrtPhImgFmt.3} $manual(tail)] >= 0} {
			# these manual pages have two NAME sections
			if {[info exists manual($manual(tail)-NAME)]} {
			    return;
			}
			set manual($manual(tail)-NAME) 1
		    }
		    set names {}
		    while {1} {
			set line [next-text];
			if {[is-a-directive $line]} {
			    backup-text 1;
			    output-name [join $names { }]
			    return;
			} else {
			    lappend names [string trim $line]
			}
		    }
		}
		SYNOPSIS {
		    lappend manual(section-toc) <DL>;
		    while {1} {
			if {[next-op-is .nf rest]
			 || [next-op-is .br rest]
			 || [next-op-is .fi rest]} {
			    continue;
			}
			if {[next-op-is .SH rest]
		         || [next-op-is .BE rest]
			 || [next-op-is .SO rest]} {
			    backup-text 1;
			    break;
			}
			if {[next-op-is .sp rest]} {
			    #man-puts <P>;
			    continue;
			}
			set more [next-text];
			if {[is-a-directive $more]} {
			    manerror "in SYNOPSIS found $more";
			    backup-text 1;
			    break;
			} else {
			    foreach more [split $more \n] {
				man-puts $more<BR>;
				if {[lsearch {TclLib TkLib} $manual(wing-file)] < 0} {
				    lappend manual(section-toc) <DD>$more;
				}
			    }
			}
		    }
		    lappend manual(section-toc) </DL>;
		    return;
		}
		{SEE ALSO} {
		    while {[more-text]} {
			if {[next-op-is .SH rest]} {
			    backup-text 1;
			    return;
			}
			set more [next-text];
			if {[is-a-directive $more]} {
			    manerror "$more";
			    backup-text 1;
			    return;
			}
			set nmore {};
			foreach cr [split $more ,] {
			    set cr [string trim $cr];
			    if { ! [regexp {^<B>.*</B>$} $cr]} {
				set cr <B>$cr</B>;
			    }
			    if {[regexp {^<B>(.*)\([13n]\)</B>$} $cr all name]} {
				set cr <B>$name</B>
			    }
			    lappend nmore $cr;
			}
			man-puts [join $nmore {, }];
		    }
		    return;
		}
		KEYWORDS {
		    while {[more-text]} {
			if {[next-op-is .SH rest]} {
			    backup-text 1;
			    return;
			}
			set more [next-text];
			if {[is-a-directive $more]} {
			    manerror "$more";
			    backup-text 1;
			    return;
			}
			set keys {}
			foreach key [split $more ,] {
			    set key [string trim $key]
			    lappend manual(keyword-$key) [list $manual(name) $manual(wing-file)/$manual(name).htm];
			    set initial [string toupper [string index $key 0]]
			    lappend keys "<A href=\"../Keywords/$initial.htm\#$key\">$key</A>"
			}
			man-puts [join $keys {, }]
		    }
		    return;
		}
	    }
	    if {[next-op-is .IP rest]} {
		output-IP-list .SH .IP $rest;
		return;
	    }
	    if {[next-op-is .PP rest]} {
		return;
	    }
	    return;
	}
	.SO {
	    if {[match-text @stuff .SE]} {
		output-directive {.SH STANDARD OPTIONS};
		set opts {};
		foreach line [split $stuff \n] {
		    foreach option [split $line \t] {
			lappend opts $option;
		    }
		}
		man-puts <DL>;
		lappend manual(section-toc) <DL>;
		foreach option [lsort $opts] {
		    man-puts "<DT><B>[std-option-toc $option]</B>";
		}
		man-puts </DL>;
		lappend manual(section-toc) </DL>;
	    } else {
		manerror "unexpected .SO format:\n[expand-next-text 2]";
	    }
	}
	.OP {
	    output-widget-options $rest;
	    return;
	}
	.IP {
	    output-IP-list .IP .IP $rest;
	    return;
	}
	.PP {
	    man-puts <P>;
	}
	.RS {
	    output-RS-list;
	    return;
	}
	.RE {
	    manerror "unexpected .RE";
	    return;
	}
	.br {
	    man-puts <BR>;
	    return;
	}
	.DE {
	    manerror "unexpected .DE";
	    return;
	}
	.DS {
	    if {[next-op-is .ta rest]} {
		;
	    }
	    if {[match-text @stuff .DE]} {
		man-puts <PRE>$stuff</PRE>;
	    } elseif {[match-text .fi @ul1 @ul2 .nf @stuff .DE]} {
		man-puts "<PRE>[lindex $ul1 1][lindex $ul2 1]\n$stuff</PRE>";
	    } else {
		manerror "unexpected .DS format:\n[expand-next-text 2]";
	    }
	    return;
	}
	.CS {
	    if {[next-op-is .ta rest]} {
		;
	    }
	    if {[match-text @stuff .CE]} {
		man-puts <PRE>$stuff</PRE>;
	    } else {
		manerror "unexpected .CS format:\n[expand-next-text 2]";
	    }
	    return;
	}
	.CE {
	    manerror "unexpected .CE";
	    return;
	}
	.sp {
	    man-puts <P>;
	}
	.ta {
	    # these are tab stop settings for short tables
	    switch -exact $manual(name):$manual(section) {
		{bind:MODIFIERS} -
		{bind:EVENT TYPES} -
		{bind:BINDING SCRIPTS AND SUBSTITUTIONS} -
		{expr:OPERANDS} -
		{expr:MATH FUNCTIONS} -
		{history:DESCRIPTION} -
		{history:HISTORY REVISION} -
		{switch:DESCRIPTION} -
		{upvar:DESCRIPTION} {
		    return;			# fix.me
		}
		default {
		    manerror "ignoring $line";
		}
	    }
	}
	.nf {
	    if {[match-text @more .fi]} {
		foreach more [split $more \n] {
		    man-puts $more<BR>;
		}
	    } elseif {[match-text .RS @more .RE .fi]} {
		man-puts <DL><DD>;
		foreach more [split $more \n] {
		    man-puts $more<BR>;
		}
		man-puts </DL>;
	    } elseif {[match-text .RS @more .RS @more2 .RE .RE .fi]} {
		man-puts <DL><DD>;
		foreach more [split $more \n] {
		    man-puts $more<BR>;
		}
		man-puts <DL><DD>;
		foreach more2 [split $more2 \n] {
		    man-puts $more2<BR>;
		}
		man-puts </DL></DL>;
	    } elseif {[match-text .RS @more .RS @more2 .RE @more3 .RE .fi]} {
		man-puts <DL><DD>;
		foreach more [split $more \n] {
		    man-puts $more<BR>;
		}
		man-puts <DL><DD>;
		foreach more2 [split $more2 \n] {
		    man-puts $more2<BR>;
		}
		man-puts </DL><DD>;
		foreach more3 [split $more3 \n] {
		    man-puts $more3<BR>;
		}
		man-puts </DL>;
	    } elseif {[match-text .sp .RS @more .RS @more2 .sp .RE .RE .fi]} {
		man-puts <P><DL><DD>;
		foreach more [split $more \n] {
		    man-puts $more<BR>;
		}
		man-puts <DL><DD>;
		foreach more2 [split $more2 \n] {
		    man-puts $more2<BR>;
		}
		man-puts </DL></DL><P>;
	    } elseif {[match-text .RS .sp @more .sp .RE .fi]} {
		man-puts <P><DL><DD>;
		foreach more [split $more \n] {
		    man-puts $more<BR>;
		}
		man-puts </DL><P>;
	    } else {
		manerror "ignoring $line";
	    }
	}
	.fi {
	    manerror "ignoring $line";
	}
	.na -
	.ad -
	.UL -
	.ne {
	    manerror "ignoring $line";
	}
	default {
	    manerror "unrecognized format directive: $line";
	}
    }
}
##
## merge copyright listings
## 
proc merge-copyrights {l1 l2} {
    foreach copyright [concat $l1 $l2] {
	if {[regexp {^Copyright +\(c\) +([0-9]+) +(by +)?([A-Za-z].*)$} $copyright all date by who]} {
	    lappend dates($who) $date;
	    continue;
	}
	if {[regexp {^Copyright +\(c\) +([0-9]+)-([0-9]+) +(by +)?([A-Za-z].*)$} $copyright all from to by who]} {
	    for {set date $from} {$date <= $to} {incr date} {
		lappend dates($who) $date;
	    }
	    continue;
	}
	if {[regexp {^Copyright +\(c\) +([0-9]+), *([0-9]+) +(by +)?([A-Za-z].*)$} $copyright all date1 date2 by who]} {
	    lappend dates($who) $date1 $date2;
	    continue;
	}
	puts "oops: $copyright";
    }
    foreach who [array names dates] {
	set list [lsort $dates($who)];
	if {[llength $list] == 1 || [lindex $list 0] == [lrange $list end end]} {
	    lappend merge "Copyright (c) [lindex $list 0] $who";
	} else {
	    lappend merge "Copyright (c) [lindex $list 0]-[lrange $list end end] $who";
	}
    }
    return [lsort $merge];
}
    
proc makedirhier {dir} {
    if { ! [file isdirectory $dir]} {
	makedirhier [file dirname $dir];
	if { ! [file isdirectory $dir]} {
	    if {[catch {exec mkdir $dir} error]} {
		error "cannot create directory $dir: $error";
	    }
	}
    }
}
    
##
## foreach of the man directories specified by args
## convert manpages into hypertext in the directory
## specified by html.
##
proc make-man-pages {html args} {
    global env manual overall_title;
    makedirhier $html;
    if { ! [file isdirectory $html]} {
	exec mkdir $html;
    }
    set manual(short-toc-n) 1;
    set manual(short-toc-fp) [open $html/contents.htm w];
    puts $manual(short-toc-fp) "<HTML><HEAD><TITLE>$overall_title</TITLE></HEAD>"
    puts $manual(short-toc-fp) "<BODY><HR><H3>$overall_title</H3><HR><DL>";
    set manual(merge-copyrights) {}
    foreach arg $args {
	set manual(wing-glob) [lindex $arg 0];
	set manual(wing-name) [lindex $arg 1];
	set manual(wing-file) [lindex $arg 2];
	set manual(wing-description) [lindex $arg 3];
	set manual(wing-copyrights) {};
	makedirhier $html/$manual(wing-file);
	set manual(wing-toc-fp) [open $html/$manual(wing-file)/contents.htm w];
	# whistle
	puts stderr "scanning section $manual(wing-name)";
	# put the entry for this section into the short table of contents
	puts $manual(short-toc-fp) "<DT><A HREF=\"$manual(wing-file)/contents.htm\">$manual(wing-name)</A><DD>$manual(wing-description)";
	# initialize the wing table of contents
	puts $manual(wing-toc-fp) "<HTML><HEAD><TITLE>$manual(wing-name) Manual</TITLE></HEAD>"
	puts $manual(wing-toc-fp) "<BODY><HR><H3>$manual(wing-name)</H3><HR>";
	# initialize the short table of contents for this section
	set manual(wing-toc) {};
	# initialize the man directory for this section
	makedirhier $html/$manual(wing-file);
	# initialize the long table of contents for this section
	set manual(long-toc-n) 1;
	# get the manual pages for this section
	set manual(pages) [lsort [glob $manual(wing-glob)]];
	if {[lsearch -glob $manual(pages) */options.n] >= 0} {
	    set n [lsearch $manual(pages) */options.n];
	    set manual(pages) "[lindex $manual(pages) $n] [lreplace $manual(pages) $n $n]";
	}
	# set manual(pages) [lrange $manual(pages) 0 5];
	foreach manual(page) $manual(pages) {
	    # whistle
	    puts stderr "scanning page $manual(page)";
	    set manual(tail) [file tail $manual(page)];
	    set manual(name) [file root $manual(tail)];
	    set manual(section) {};
	    if {[lsearch {case pack-old menubar} $manual(name)] >= 0} {
		# obsolete
		manerror "discarding $manual(name)";
		continue;
	    }
	    set manual(infp) [open "$manual(page)"];
	    set manual(text) {};
	    set manual(partial-text) {};
	    foreach p {.RS .DS .CS .SO} {
		set manual($p) 0;
	    }
	    set manual(stack) {};
	    set manual(section) {};
	    set manual(section-toc) {};
	    set manual(section-toc-n) 1;
	    set manual(copyrights) {};
	    lappend manual(all-pages) $manual(wing-file)/$manual(tail);
	    manreport 100 "$manual(name)";
	    while {[gets $manual(infp) line] >= 0} {
		manreport 100 $line;
		if {[regexp {^[`'][/\\]} $line]} {
		    if {[regexp {Copyright \(c\).*$} $line copyright]} {
			lappend manual(copyrights) $copyright;
		    }
		    # comment
		    continue;
		}
		if {"$line" == {'}} {
		    # comment
		    continue;
		}
		if {[parse-directive $line code rest]} {
		    switch -exact $code {
			.ad -
			.na -
			.so -
			.ne -
			.AS -
			.VE -
			.VS -
			. {
			    # ignore
			    continue;
			}
		    }
		    if {"$manual(partial-text)" != {}} {
			lappend manual(text) [process-text $manual(partial-text)];
			set manual(partial-text) {};
		    }
		    switch -exact $code {
			.SH {
			    if {[llength $rest] == 0} {
				gets $manual(infp) rest;
			    }
			    lappend manual(text) ".SH [unquote $rest]";
			}
			.TH {
			    lappend manual(text) "$code [unquote $rest]";
			}
			.HS -
			.UL -
			.ta {
			    lappend manual(text) "$code [unquote $rest]";
			}
			.BS -
			.BE -
			.br -
			.fi -
			.sp -
			.nf {
			    if {"$rest" != {}} {
				manerror "unexpected argument: $line";
			    }
			    lappend manual(text) $code;
			}
			.AP {
			    lappend manual(text) [concat .IP [process-text "[lindex $rest 0] \\fB[lindex $rest 1]\\fR ([lindex $rest 2])"]];
			}
			.IP {
			    regexp {^(.*) +[0-9]+$} $rest all rest
			    lappend manual(text) ".IP [process-text [unquote [string trim $rest]]]";
			}
			.TP {
			    set next [gets $manual(infp)];
			    if {"$next" != {'}} {
				lappend manual(text) ".IP [process-text $next]";
			    }
			}
			.OP {
			    lappend manual(text) [concat .OP [process-text \
								  "\\fB[lindex $rest 0]\\fR \\fB[lindex $rest 1]\\fR \\fB[lindex $rest 2]\\fR"]];
			}
			.PP -
			.LP {
			    lappend manual(text) {.PP};
			}
			.RS {
			    incr manual(.RS);
			    lappend manual(text) $code;
			}
			.RE {
			    incr manual(.RS) -1;
			    lappend manual(text) $code;
			}
			.SO {
			    incr manual(.SO);
			    lappend manual(text) $code;
			}
			.SE {
			    incr manual(.SO) -1;
			    lappend manual(text) $code;
			}
			.DS {
			    incr manual(.DS);
			    lappend manual(text) $code;
			}
			.DE {
			    incr manual(.DS) -1;
			    lappend manual(text) $code;
			}
			.CS {
			    incr manual(.CS);
			    lappend manual(text) $code;
			}
			.CE {
			    incr manual(.CS) -1;
			    lappend manual(text) $code;
			}
			.de {
			    while {[gets $manual(infp) line] >= 0} {
				if {[regexp {^\.\.} $line]} {
				    break;
				}
			    }
			}
			.. {
			    error "found .. outside of .de";
			}
			default {
			    manerror "unrecognized format directive: $line";
			}
		    }
		} else {
		    if {"$manual(partial-text)" == {}} {
			set manual(partial-text) $line;
		    } else {
			append manual(partial-text) \n$line;
		    }
		}
	    }
	    if {"$manual(partial-text)" != {}} {
		lappend manual(text) [process-text $manual(partial-text)];
	    }
	    close $manual(infp);
	    # fixups
	    if {$manual(.RS) != 0} {
		if {"$manual(name)" != {selection}} {
		    puts "unbalanced .RS .RE";
		}
	    }
	    if {$manual(.DS) != 0} {
		puts "unbalanced .DS .DE";
	    }
	    if {$manual(.CS) != 0} {
		puts "unbalanced .CS .CE";
	    }
	    if {$manual(.SO) != 0} {
		puts "unbalanced .SO .SE";
	    }
	    # output conversion
	    open-text;
	    if {[next-op-is .HS rest]} {
		set manual($manual(name)-title) "[lrange $rest 1 end] [lindex $rest 0] manual page";
		while {[more-text]} {
		    set line [next-text];
		    if {[is-a-directive $line]} {
			output-directive $line;
		    } else {
			man-puts $line;
		    }
		}
		man-puts <HR><PRE>;
		foreach copyright $manual(copyrights) {
		    man-puts "<A HREF=\"../copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]";
		}
		man-puts "<A HREF=\"../copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr.</PRE>";
		set manual(wing-copyrights) [merge-copyrights $manual(wing-copyrights) $manual(copyrights)];
	    } elseif {[next-op-is .TH rest]} {
		set manual($manual(name)-title) "[lrange $rest 4 end] - [lindex $rest 0] manual page";
		while {[more-text]} {
		    set line [next-text];
		    if {[is-a-directive $line]} {
			output-directive $line;
		    } else {
			man-puts $line;
		    }
		}
		man-puts <HR><PRE>;
		foreach copyright $manual(copyrights) {
		    man-puts "<A HREF=\"../copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]";
		}
		man-puts "<A HREF=\"../copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr.</PRE>";
		set manual(wing-copyrights) [merge-copyrights $manual(wing-copyrights) $manual(copyrights)];
	    } else {
		manerror "no .HS or .TH record found";
	    }
	    #
	    # make the long table of contents for this page
	    #
	    set manual(toc-$manual(wing-file)-$manual(name)) [concat <DL> $manual(section-toc) </DL><HR>];
	}

	#
	# make the wing table of contents for the section
	#
	set width 0;
	foreach name $manual(wing-toc) {
	    if {[string length $name] > $width} {
		set width [string length $name];
	    }
	}
	set perline [expr 120 / $width];
	set nrows [expr ([llength $manual(wing-toc)]+$perline)/$perline]
	set n 0;
        catch {unset rows}
	foreach name [lsort $manual(wing-toc)] {
	    set tail $manual(name-$name);
	    if {[llength $tail] > 1} {
		manerror "$name is defined in more than one file: $tail";
		set tail [lindex $tail [expr [llength $tail]-1]];
	    }
	    set tail [file tail $tail];
	    append rows([expr $n%$nrows]) "<td> <a href=\"$tail.htm\">$name</a>"
	    incr n;
	}
	puts $manual(wing-toc-fp) <table>;
        foreach row [lsort -integer [array names rows]] {
	    puts $manual(wing-toc-fp) <tr>$rows($row)</tr>
	}
	puts $manual(wing-toc-fp) </table>;

	#
	# insert wing copyrights
	#
	puts $manual(wing-toc-fp) "<HR><PRE>"
	foreach copyright $manual(wing-copyrights) {
	    puts $manual(wing-toc-fp) "<A HREF=\"../copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]";
	}
	puts $manual(wing-toc-fp) "<A HREF=\"../copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr.";
	puts $manual(wing-toc-fp) "</PRE></BODY></HTML>";
	close $manual(wing-toc-fp);
	set manual(merge-copyrights) [merge-copyrights $manual(merge-copyrights) $manual(wing-copyrights)];
    }

    ##
    ## build the keyword index.
    ##
    proc strcasecmp {a b} { return [string compare [string tolower $a] [string tolower $b]]; }
    set keys [lsort -command strcasecmp [array names manual keyword-*]];
    makedirhier $html/Keywords
    catch {eval exec rm -f [glob $html/Keywords/*]}
    puts $manual(short-toc-fp) {<DT><A HREF="Keywords/contents.htm">Keywords</A><DD>The keywords from the Tcl/Tk man pages.};
    set keyfp [open $html/Keywords/contents.htm w];
    puts $keyfp "<HTML><HEAD><TITLE>Tcl/Tk Keywords</TITLE></HEAD>"
    puts $keyfp "<BODY><HR><H3>Tcl/Tk Keywords</H3><HR><H2>"
    foreach a {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} {
	puts $keyfp "<A HREF=\"$a.htm\">$a</A>"
	set afp [open $html/Keywords/$a.htm w];
	puts $afp "<HTML><HEAD><TITLE>Tcl/Tk Keywords - $a</TITLE></HEAD>"
	puts $afp "<BODY><HR><H3>Tcl/Tk Keywords - $a</H3><HR><H2>"
	foreach b {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} {
	    puts $afp "<A HREF=\"$b.htm\">$b</A>"
	}
	puts $afp "</H2><HR><DL>"
	foreach k $keys {
	    if {[regexp -nocase -- "^keyword-$a" $k]} {
		set k [string range $k 8 end]
		puts $afp "<DT><A NAME=\"$k\">$k</A><DD>"
		set refs {}
		foreach man $manual(keyword-$k) {
		    set name [lindex $man 0];
		    set file [lindex $man 1]
		    lappend refs "<A HREF=\"../$file\">$name</A>";
		}
		puts $afp [join $refs {, }];
	    }
	}
	puts $afp "</DL><HR><PRE>"
	# insert merged copyrights
	foreach copyright $manual(merge-copyrights) {
	    puts $afp "<A HREF=\"copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]";
	}
	puts $afp "<A HREF=\"copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr.";
	puts $afp "</PRE></BODY></HTML>"
	close $afp
    }
    puts $keyfp "</H2><HR><PRE>"

    # insert merged copyrights
    foreach copyright $manual(merge-copyrights) {
	puts $keyfp "<A HREF=\"copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]";
    }
    puts $keyfp "<A HREF=\"copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr.";
    puts $keyfp </PRE><HR></BODY></HTML>
    close $keyfp;

    ##
    ## finish off short table of contents
    ##
    puts $manual(short-toc-fp) {<DT><A HREF="http://www.elf.org">Source</A><DD>More information about these man pages.}
    puts $manual(short-toc-fp) "</DL><HR><PRE>";
    # insert merged copyrights
    foreach copyright $manual(merge-copyrights) {
	puts $manual(short-toc-fp) "<A HREF=\"copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]";
    }
    puts $manual(short-toc-fp) "<A HREF=\"copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr.";
    puts $manual(short-toc-fp) "</PRE></BODY></HTML>";
    close $manual(short-toc-fp);

    ##
    ## output man pages
    ##
    unset manual(section);
    foreach path $manual(all-pages) {
	set manual(wing-file) [file dirname $path];
	set manual(tail) [file tail $path];
	set manual(name) [file root $manual(tail)];
	set text $manual(output-$manual(wing-file)-$manual(name));
	set ntext 0;
	foreach item $text {
	    incr ntext [llength [split $item \n]];
	    incr ntext;
	}
	set toc $manual(toc-$manual(wing-file)-$manual(name));
	set ntoc 0;
	foreach item $toc {
	    incr ntoc [llength [split $item \n]];
	    incr ntoc;
	}
	puts stderr "rescanning page $manual(name) $ntoc/$ntext";
	set manual(outfp) [open $html/$manual(wing-file)/$manual(name).htm w];
	puts $manual(outfp) "<HTML><HEAD><TITLE>$manual($manual(name)-title)</TITLE></HEAD><BODY>"
	if {$ntext > 60 && $ntoc > 32
	    || [lsearch {Hash LinkVar SetVar TraceVar
		ConfigWidg CrtImgType CrtItemType CrtPhImgFmt DoOneEvent GetBitmap GetColor GetCursor GetJustify GetPixels GetVisual
		ParseArgv QueueEvent} $manual(tail)] >= 0} {
	    foreach item $toc {
		puts $manual(outfp) $item;
	    }
	}
	foreach item $text {
	    puts $manual(outfp) [insert-cross-references $item];
	}
	puts $manual(outfp) </BODY></HTML>;
	close $manual(outfp);
    }
    return {};
}

set usercmddesc {The interpreters which implement Tcl and Tk.}
set tclcmddesc {The commands which the <B>tclsh</B> interpreter implements.}
set tkcmddesc {The additional commands which the <B>wish</B> interpreter implements.}
set tcllibdesc {The C functions which a Tcl extended C program may use.}
set tklibdesc {The additional C functions which a Tk extended C program may use.}
		
parse_command_line

if {1} {
    if {[catch {
	make-man-pages $webdir \
	    "$tcltkdir/{$tkdir,$tcldir}/doc/*.1 {Tcl/Tk Applications} UserCmd {$usercmddesc}" \
	    "$tcltkdir/$tcldir/doc/*.n {Tcl Commands} TclCmd {$tclcmddesc}" \
	    "$tcltkdir/$tkdir/doc/*.n {Tk Commands} TkCmd {$tkcmddesc}" \
	    "$tcltkdir/$tcldir/doc/*.3 {Tcl Library} TclLib {$tcllibdesc}" \
	    "$tcltkdir/$tkdir/doc/*.3 {Tk Library} TkLib {$tklibdesc}"
    } error]} {
	puts $error\n$errorInfo;
    }
}

Added tools/tclSplash.bmp.

cannot compute difference between binary files

Added tools/tclmin.wse.















































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
Document Type: WSE
item: Global
  Version=5.0
  Flags=00000100
  Split=1420
  Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  Japanese Font Name=MS Gothic
  Japanese Font Size=10
  Start Gradient=0 0 255
  End Gradient=0 0 0
  Windows Flags=00000000000000010010110000001000
  Message Font=MS Sans Serif
  Font Size=8
  Disk Filename=SETUP
  Patch Flags=0000000000000001
  Patch Threshold=85
  Patch Memory=4000
end
item: Remark
  Text=-------
end
item: Remark
  Text=Tcl 8.0 Minimal Installation
end
item: Remark
  Text=-------
end
item: Install File
  Source=n:\dist\tcl8.0\library\opt0.4\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\opt0.4\pkgIndex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\opt0.4\optparse.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\opt0.4\optparse.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\http2.0\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\http2.0\pkgIndex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\http2.0\http.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\http2.0\http.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\safe.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\safe.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\history.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\history.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\msgbox.tcl
  Destination=%MAINDIR%\lib\tk%VER%\msgbox.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\optMenu.tcl
  Destination=%MAINDIR%\lib\tk%VER%\optMenu.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\clrpick.tcl
  Destination=%MAINDIR%\lib\tk%VER%\clrpick.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\entry.tcl
  Destination=%MAINDIR%\lib\tk%VER%\entry.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\comdlg.tcl
  Destination=%MAINDIR%\lib\tk%VER%\comdlg.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\bgerror.tcl
  Destination=%MAINDIR%\lib\tk%VER%\bgerror.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\obsolete.tcl
  Destination=%MAINDIR%\lib\tk%VER%\obsolete.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\button.tcl
  Destination=%MAINDIR%\lib\tk%VER%\button.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\xmfbox.tcl
  Destination=%MAINDIR%\lib\tk%VER%\xmfbox.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\console.tcl
  Destination=%MAINDIR%\lib\tk%VER%\console.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\listbox.tcl
  Destination=%MAINDIR%\lib\tk%VER%\listbox.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\menu.tcl
  Destination=%MAINDIR%\lib\tk%VER%\menu.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\dialog.tcl
  Destination=%MAINDIR%\lib\tk%VER%\dialog.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\focus.tcl
  Destination=%MAINDIR%\lib\tk%VER%\focus.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\palette.tcl
  Destination=%MAINDIR%\lib\tk%VER%\palette.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\tkfbox.tcl
  Destination=%MAINDIR%\lib\tk%VER%\tkfbox.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\tk.tcl
  Destination=%MAINDIR%\lib\tk%VER%\tk.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\text.tcl
  Destination=%MAINDIR%\lib\tk%VER%\text.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\tearoff.tcl
  Destination=%MAINDIR%\lib\tk%VER%\tearoff.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\tclIndex
  Destination=%MAINDIR%\lib\tk%VER%\tclIndex
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\scrlbar.tcl
  Destination=%MAINDIR%\lib\tk%VER%\scrlbar.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\scale.tcl
  Destination=%MAINDIR%\lib\tk%VER%\scale.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tk8.0\library\safetk.tcl
  Destination=%MAINDIR%\lib\tk%VER%\safetk.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\http1.0\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\http1.0\pkgIndex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\http1.0\http.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\http1.0\http.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\win\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\reg1.0\pkgIndex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\win\tclreg80.dll
  Destination=%MAINDIR%\lib\tcl%VER%\reg1.0\tclreg80.dll
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\win\Tcl1680.dll
  Destination=%SYS32%\Tcl1680.dll
  Flags=0000001000000010
end
item: Install File
  Source=n:\dist\tcl8.0\win\tcl80.dll
  Destination=%SYS32%\tcl80.dll
  Flags=0000001000000010
end
item: Install File
  Source=n:\dist\tcl8.0\win\tclpip80.dll
  Destination=%SYS32%\tclpip80.dll
  Flags=0000001000000010
end
item: Install File
  Source=n:\dist\Bc45\Bin\cw3215.dll
  Destination=%SYS32%\cw3215.dll
  Flags=0000001000000010
end
item: Install File
  Source=n:\dist\tk8.0\win\tk80.dll
  Destination=%SYS32%\tk80.dll
  Flags=0000001000000010
end
item: Install File
  Source=n:\dist\tk8.0\win\wish80.exe
  Destination=%MAINDIR%\bin\wish80.exe
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\win\tclsh80.exe
  Destination=%MAINDIR%\bin\tclsh80.exe
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\tclIndex
  Destination=%MAINDIR%\lib\tcl%VER%\tclIndex
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\init.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\init.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\parray.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\parray.tcl
  Flags=0000000000000010
end
item: Install File
  Source=n:\dist\tcl8.0\library\word.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\word.tcl
  Flags=0000000000000010
end

Added tools/uniParse.tcl.



































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
namespace eval uni {
    set shift 9			;# number of bits of data within a page
    variable pMap		;# map from page to page index, each entry is
				 # an index into the pages table, indexed by
				 # page number
    variable pages		;# map from page index to page info, each
				 # entry is a list of indices into the groups
				 # table, the list is indexed by the offset
    variable groups		;# list of character info values, indexed by
				 # group number, initialized with the
				 # unassigned character group

    variable categories {
	Cn Lu Ll Lt Lm Lo Mn Me Mc Nd Nl No Zs Zl Zp
	Cc Cf Co Cs Pc Pd Ps Pe Pi Pf Po Sm Sc Sk So
    }				;# Ordered list of character categories, must
				 # match the enumeration in the header file.

    variable titleCount 0	;# Count of the number of title case
				 # characters.  This value is used in the
				 # regular expression code to allocate enough
				 # space for the title case variants.
}

proc uni::getValue {items index} {
    variable categories
    variable titleCount

    # Extract character info

    set category [lindex $items 2]
    if {[scan [lindex $items 12] %4x toupper] == 1} {
	set toupper [expr {$index - $toupper}]
    } else {
	set toupper {}
    }
    if {[scan [lindex $items 13] %4x tolower] == 1} {
	set tolower [expr {$tolower - $index}]
    } else {
	set tolower {}
    }
    if {[scan [lindex $items 14] %4x totitle] == 1} {
	set totitle [expr {$index - $totitle}]
    } else {
	set totitle {}
    }

    set categoryIndex [lsearch -exact $categories $category]
    if {$categoryIndex < 0} {
	puts "Unexpected character category: $index($category)"
	set categoryIndex 0
    } elseif {$category == "Lt"} {
	incr titleCount
    }

    return "$categoryIndex,$toupper,$tolower,$totitle"
}

proc uni::getGroup {value} {
    variable groups

    set gIndex [lsearch -exact $groups $value]
    if {$gIndex == -1} {
	set gIndex [llength $groups]
	lappend groups $value
    }
    return $gIndex
}

proc uni::addPage {info} {
    variable pMap
    variable pages
    
    set pIndex [lsearch -exact $pages $info]
    if {$pIndex == -1} {
	set pIndex [llength $pages]
	lappend pages $info
    }
    lappend pMap $pIndex
    return
}
    
proc uni::buildTables {data} {
    variable shift

    variable pMap {}
    variable pages {}
    variable groups {{0,,,}}
    set info {}			;# temporary page info
    
    set mask [expr {(1 << $shift) - 1}]

    set next 0

    foreach line [split $data \n] {
	if {$line == ""} {
	    set line "FFFF;;Cn;0;ON;;;;;N;;;;;\n"
	}

	set items [split $line \;]

	scan [lindex $items 0] %4x index
	set index [format 0x%0.4x $index]
	
	set gIndex [getGroup [getValue $items $index]]

	# Since the input table omits unassigned characters, these will
	# show up as gaps in the index sequence.  There are a few special cases
	# where the gaps correspond to a uniform block of assigned characters.
	# These are indicated as such in the character name.

	# Enter all unassigned characters up to the current character.
	if {($index > $next) \
		&& ![regexp "Last>$" [lindex $items 1]]} {
	    for {} {$next < $index} {incr next} {
		lappend info 0
		if {($next & $mask) == $mask} {
		    addPage $info
		    set info {}
		}
	    }
	}

	# Enter all assigned characters up to the current character
	for {set i $next} {$i <= $index} {incr i} {
	    # Split character index into offset and page number
	    set offset [expr {$i & $mask}]
	    set page [expr {($i >> $shift)}]

	    # Add the group index to the info for the current page
	    lappend info $gIndex

	    # If this is the last entry in the page, add the page
	    if {$offset == $mask} {
		addPage $info
		set info {}
	    }
	}
	set next [expr {$index + 1}]
    }
    return
}

proc uni::main {} {
    global argc argv0 argv
    variable pMap
    variable pages
    variable groups
    variable shift
    variable titleCount

    if {$argc != 2 && $argc != 3} {
	puts stderr "\nusage: $argv0 <datafile> <outdir> ?optimize?\n"
	exit 1
    }
    set f [open [lindex $argv 0] r]
    set data [read $f]
    close $f

    set shift 6
    buildTables $data
    puts "X = [llength $pMap]  Y= [llength $pages]  A= [llength $groups]"
    set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}]
    puts "shift = 6, space = $size"
    puts "title case count = $titleCount"

    set f [open [file join [lindex $argv 1] tclUniData.c] w]
    puts $f "/*
 * tclUtfData.c --
 *
 *	Declarations of Unicode character information tables.  This file is
 *	automatically generated by the tools/uniParse.tcl script.  Do not
 *	modify this file by hand.
 *
 * Copyright (c) 1998 by Scriptics Corporation.
 * All rights reserved.
 *
 * RCS: @(#) \$Id\$
 */

/*
 * A 16-bit Unicode character is split into two parts in order to index
 * into the following tables.  The lower OFFSET_BITS comprise an offset
 * into a page of characters.  The upper bits comprise the page number.
 */

#define OFFSET_BITS $shift

/*
 * The pageMap is indexed by page number and returns an alternate page number
 * that identifies a unique page of characters.  Many Unicode characters map
 * to the same alternate page number.
 */

static char pageMap\[\] = {"
    set line "    "
    set last [expr {[llength $pMap] - 1}]
    for {set i 0} {$i <= $last} {incr i} {
	append line [lindex $pMap $i]
	if {$i != $last} {
	    append line ", "
	}
	if {[string length $line] > 70} {
	    puts $f $line
	    set line "    "
	}
    }
    puts $f $line
    puts $f "};

/*
 * The groupMap is indexed by combining the alternate page number with
 * the page offset and returns a group number that identifies a unique
 * set of character attributes.
 */

static char groupMap\[\] = {"
    set line "    "
    set lasti [expr {[llength $pages] - 1}]
    for {set i 0} {$i <= $lasti} {incr i} {
	set page [lindex $pages $i]
	set lastj [expr {[llength $page] - 1}]
	for {set j 0} {$j <= $lastj} {incr j} {
	    append line [lindex $page $j]
	    if {$j != $lastj || $i != $lasti} {
		append line ", "
	    }
	    if {[string length $line] > 70} {
		puts $f $line
		set line "    "
	    }
	}
    }
    puts $f $line
    puts $f "};

/*
 * Each group represents a unique set of character attributes.  The attributes
 * are encoded into a 32-bit value as follows:
 *
 * Bits 0-4	Character category: see the constants listed below.
 *
 * Bits 5-7	Case delta type: 000 = identity
 *				 010 = add delta for lower
 *				 011 = add delta for lower, add 1 for title
 *				 100 = sutract delta for title/upper
 *				 101 = sub delta for upper, sub 1 for title
 *				 110 = sub delta for upper, add delta for lower
 *
 * Bits 8-21	Reserved for future use.
 *
 * Bits 22-31	Case delta: delta for case conversions.  This should be the
 *			    highest field so we can easily sign extend.
 */

static int groups\[\] = {"
    set line "    "
    set last [expr {[llength $groups] - 1}]
    for {set i 0} {$i <= $last} {incr i} {
	foreach {type toupper tolower totitle} [split [lindex $groups $i] ,] {}
	
	# Compute the case conversion type and delta

	if {$totitle != ""} {
	    if {$totitle == $toupper} {
		# subtract delta for title or upper
		set case 4
		set delta $toupper
	    } elseif {$toupper != ""} {
		# subtract delta for upper, subtract 1 for title
		set case 5
		set delta $toupper
	    } else {
		# add delta for lower, add 1 for title
		set case 3
		set delta $tolower
	    }
	} elseif {$toupper != ""} {
	    # subtract delta for upper, add delta for lower
	    set case 6
	    set delta $toupper
	} elseif {$tolower != ""} {
	    # add delta for lower
	    set case 2
	    set delta $tolower
	} else {
	    # noop
	    set case 0
	    set delta 0
	}

	set val [expr {($delta << 22) | ($case << 5) | $type}]

	append line [format "%d" $val]
	if {$i != $last} {
	    append line ", "
	}
	if {[string length $line] > 65} {
	    puts $f $line
	    set line "    "
	}
    }
    puts $f $line
    puts $f "};

/*
 * The following constants are used to determine the category of a
 * Unicode character.
 */

#define UNICODE_CATEGORY_MASK 0X1F

enum {
    UNASSIGNED,
    UPPERCASE_LETTER,
    LOWERCASE_LETTER,
    TITLECASE_LETTER,
    MODIFIER_LETTER,
    OTHER_LETTER,
    NON_SPACING_MARK,
    ENCLOSING_MARK,
    COMBINING_SPACING_MARK,
    DECIMAL_DIGIT_NUMBER,
    LETTER_NUMBER,
    OTHER_NUMBER,
    SPACE_SEPARATOR,
    LINE_SEPARATOR,
    PARAGRAPH_SEPARATOR,
    CONTROL,
    FORMAT,
    PRIVATE_USE,
    SURROGATE,
    CONNECTOR_PUNCTUATION,
    DASH_PUNCTUATION,
    OPEN_PUNCTUATION,
    CLOSE_PUNCTUATION,
    INITIAL_QUOTE_PUNCTUATION,
    FINAL_QUOTE_PUNCTUATION,
    OTHER_PUNCTUATION,
    MATH_SYMBOL,
    CURRENCY_SYMBOL,
    MODIFIER_SYMBOL,
    OTHER_SYMBOL
};

/*
 * The following macros extract the fields of the character info.  The
 * GetDelta() macro is complicated because we can't rely on the C compiler
 * to do sign extension on right shifts.
 */

#define GetCaseType(info) (((info) & 0xE0) >> 5)
#define GetCategory(info) ((info) & 0x1F)
#define GetDelta(infO) (((info) > 0) ? ((info) >> 22) : (~(~((info)) >> 22)))

/*
 * This macro extracts the information about a character from the
 * Unicode character tables.
 */

#define GetUniCharInfo(ch) (groups\[groupMap\[(pageMap\[(((int)(ch)) & 0xffff) >> OFFSET_BITS\] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))\]\])
"

    close $f
}

uni::main

return

Added tools/white.bmp.

cannot compute difference between binary files

Changes to unix/Makefile.in.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#
# This file is a Makefile for Tcl.  If it has the name "Makefile.in"
# then it is a template for a Makefile;  to generate the actual Makefile,
# run "./configure", which is a configuration script generated by the
# "autoconf" program (constructs like "@foo@" will get replaced in the
# actual Makefile.
#
# SCCS: @(#) Makefile.in 1.190 97/11/05 10:57:38

# Current Tcl version;  used in various names.

VERSION = @TCL_VERSION@

#----------------------------------------------------------------
# Things you can change to personalize the Makefile for your own







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#
# This file is a Makefile for Tcl.  If it has the name "Makefile.in"
# then it is a template for a Makefile;  to generate the actual Makefile,
# run "./configure", which is a configuration script generated by the
# "autoconf" program (constructs like "@foo@" will get replaced in the
# actual Makefile.
#
# RCS: @(#) $Id: Makefile.in,v 1.1.2.25 1999/04/07 00:36:09 stanton Exp $

# Current Tcl version;  used in various names.

VERSION = @TCL_VERSION@

#----------------------------------------------------------------
# Things you can change to personalize the Makefile for your own
67
68
69
70
71
72
73










74
75



76

77
78
79
80
81
82
83
# procedures:
MAN3_INSTALL_DIR =	$(MAN_INSTALL_DIR)/man3

# Directory in which to install manual entries for the built-in
# Tcl commands:
MANN_INSTALL_DIR =	$(MAN_INSTALL_DIR)/mann











# To change the compiler switches, for example to change from -O
# to -g, change the following line:



CFLAGS = -O


# To disable ANSI-C procedure prototypes reverse the comment characters
# on the following lines:
PROTO_FLAGS =
#PROTO_FLAGS = -DNO_PROTOTYPE

# Mathematical functions like sin and atan2 are enabled for expressions







>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
|
>







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
# procedures:
MAN3_INSTALL_DIR =	$(MAN_INSTALL_DIR)/man3

# Directory in which to install manual entries for the built-in
# Tcl commands:
MANN_INSTALL_DIR =	$(MAN_INSTALL_DIR)/mann

# Libraries built with optimization switches have this additional extension
TCL_DBGX =		@TCL_DBGX@

# warning flags
CFLAGS_WARNING =	@CFLAGS_WARNING@

# The default switches for optimization or debugging
CFLAGS_DEBUG =		@CFLAGS_DEBUG@
CFLAGS_OPTIMIZE =	@CFLAGS_OPTIMIZE@

# To change the compiler switches, for example to change from optimization to
# debugging symbols, change the following line:
#CFLAGS = 		$(CFLAGS_DEBUG)
#CFLAGS = 		$(CFLAGS_OPTIMIZE)
#CFLAGS = 		$(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE)
CFLAGS = 		@CFLAGS@


# To disable ANSI-C procedure prototypes reverse the comment characters
# on the following lines:
PROTO_FLAGS =
#PROTO_FLAGS = -DNO_PROTOTYPE

# Mathematical functions like sin and atan2 are enabled for expressions
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
# following pairs of lines.  In addition, you'll have to provide your
# own replacement for the "panic" procedure (see panic.c for what
# the current one does).
GENERIC_FLAGS =
#GENERIC_FLAGS = -DTCL_GENERIC_ONLY
UNIX_OBJS = tclMtherr.o tclUnixChan.o tclUnixEvent.o tclUnixFCmd.o \
	tclUnixFile.o tclUnixPipe.o tclUnixSock.o \
	tclUnixTime.o tclUnixInit.o
#UNIX_OBJS =
NOTIFY_OBJS = tclUnixNotfy.o
#NOTIFY_OBJS =

# To enable memory debugging reverse the comment characters on the following
# lines.  Warning:  if you enable memory debugging, you must do it
# *everywhere*, including all the code that calls Tcl, and you must use
# ckalloc and ckfree everywhere instead of malloc and free.
MEM_DEBUG_FLAGS =
#MEM_DEBUG_FLAGS = -DTCL_MEM_DEBUG










# To enable compilation debugging reverse the comment characters on
# one of the following lines.
COMPILE_DEBUG_FLAGS =
#COMPILE_DEBUG_FLAGS = -DTCL_COMPILE_STATS
#COMPILE_DEBUG_FLAGS = -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS






# Some versions of make, like SGI's, use the following variable to
# determine which shell to use for executing commands:
SHELL =		/bin/sh

# Tcl used to let the configure script choose which program to use
# for installing, but there are just too many different versions of







|










>
>
>
>
>
>
>
>
>






>
>
>
>
>







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
# following pairs of lines.  In addition, you'll have to provide your
# own replacement for the "panic" procedure (see panic.c for what
# the current one does).
GENERIC_FLAGS =
#GENERIC_FLAGS = -DTCL_GENERIC_ONLY
UNIX_OBJS = tclMtherr.o tclUnixChan.o tclUnixEvent.o tclUnixFCmd.o \
	tclUnixFile.o tclUnixPipe.o tclUnixSock.o \
	tclUnixTime.o tclUnixInit.o tclUnixThrd.o 
#UNIX_OBJS =
NOTIFY_OBJS = tclUnixNotfy.o
#NOTIFY_OBJS =

# To enable memory debugging reverse the comment characters on the following
# lines.  Warning:  if you enable memory debugging, you must do it
# *everywhere*, including all the code that calls Tcl, and you must use
# ckalloc and ckfree everywhere instead of malloc and free.
MEM_DEBUG_FLAGS =
#MEM_DEBUG_FLAGS = -DTCL_MEM_DEBUG

# To enable support for stubs in Tcl.
STUB_LIB_FILE = @STUB_LIB_FILE@

TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@
#TCL_STUB_LIB_FILE = libtclstub.a

TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@
#TCL_STUB_LIB_FLAG = -ltclstub

# To enable compilation debugging reverse the comment characters on
# one of the following lines.
COMPILE_DEBUG_FLAGS =
#COMPILE_DEBUG_FLAGS = -DTCL_COMPILE_STATS
#COMPILE_DEBUG_FLAGS = -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS

# To compile without backward compatibility and deprecated code
# uncomment the following
NO_DEPRECATED_FLAGS=
#NO_DEPRECATED_FLAGS= -DTCL_NO_DEPRECATED

# Some versions of make, like SGI's, use the following variable to
# determine which shell to use for executing commands:
SHELL =		/bin/sh

# Tcl used to let the configure script choose which program to use
# for installing, but there are just too many different versions of
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170






171
172
173
174
175
176
177
178
179
180
181
182
183
184
185


186


187
188
189
190
191
192
193
194
195
196

197






198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214

215
216
217
218
219
220


221


222

223
224
225




226
227
228
229




230
231
232
233
234




235
236
237
238
239
240
241
242

243
244
245

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267

268
269
270
271
272






273
274
275


276
277
278
279



280
281
282
283
284
285
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320





321
322
323
324
325
326
327
# The symbols below provide support for dynamic loading and shared
# libraries.  See configure.in for a description of what the
# symbols mean.  The values of the symbols are normally set by the
# configure script.  You shouldn't normally need to modify any of
# these definitions by hand.

SHLIB_LD = @SHLIB_LD@


SHLIB_SUFFIX = @SHLIB_SUFFIX@
#SHLIB_SUFFIX =

DLTEST_TARGETS = dltest/pkg5${SHLIB_SUFFIX} dltest/Makefile

# The following symbol is defined to "$(DLTEST_TARGETS)" if dynamic
# loading is available;  this causes everything in the "dltest"
# subdirectory to be built when making "tcltest.  If dynamic loading
# isn't available, configure defines this symbol to an empty string,
# in which case the shared libraries aren't built.
BUILD_DLTEST = @BUILD_DLTEST@
#BUILD_DLTEST =

TCL_LIB_FILE = @TCL_LIB_FILE@
#TCL_LIB_FILE = libtcl.a







#----------------------------------------------------------------
# The information below is modified by the configure script when
# Makefile is generated from Makefile.in.  You shouldn't normally
# modify any of this stuff by hand.
#----------------------------------------------------------------

COMPAT_OBJS =		@LIBOBJS@

AC_FLAGS =		@DEFS@
RANLIB =		@RANLIB@
SRC_DIR =		@srcdir@
TOP_DIR =		@srcdir@/..
GENERIC_DIR = 		$(TOP_DIR)/generic
COMPAT_DIR =		$(TOP_DIR)/compat
TOOL_DIR =		$(TOP_DIR)/tools


DLTEST_DIR =		@srcdir@/dltest


UNIX_DIR = 		@srcdir@
CC =			@CC@

#----------------------------------------------------------------
# The information below should be usable as is.  The configure
# script won't modify it and you shouldn't need to modify it
# either.
#----------------------------------------------------------------



CC_SWITCHES =	${CFLAGS} ${TCL_SHLIB_CFLAGS} -I${GENERIC_DIR} -I${SRC_DIR} \






${AC_FLAGS} ${MATH_FLAGS} ${GENERIC_FLAGS} ${PROTO_FLAGS} ${MEM_DEBUG_FLAGS} \
${COMPILE_DEBUG_FLAGS} ${ENV_FLAGS} -DTCL_SHLIB_EXT=\"${SHLIB_SUFFIX}\"

LIBS =		@DL_LIBS@ @LIBS@ $(MATH_LIBS) -lc

DEPEND_SWITCHES = ${CFLAGS} -I${GENERIC_DIR} -I${SRC_DIR} \
${AC_FLAGS} ${MATH_FLAGS} \
${GENERIC_FLAGS} ${PROTO_FLAGS} ${MEM_DEBUG_FLAGS} \
-DTCL_SHLIB_EXT=\"${SHLIB_SUFFIX}\"

TCLSH_OBJS = tclAppInit.o

TCLTEST_OBJS = tclTestInit.o tclTest.o tclTestObj.o tclUnixTest.o


XTTEST_OBJS = tclTest.o tclTestObj.o tclUnixTest.o tclXtNotify.o \
	tclXtTest.o xtTestInit.o


GENERIC_OBJS = panic.o regexp.o tclAsync.o tclBasic.o tclBinary.o tclCkalloc.o \
	tclClock.o tclCmdAH.o tclCmdIL.o tclCmdMZ.o tclCompExpr.o \
	tclCompile.o tclDate.o tclEnv.o tclEvent.o tclExecute.o \
	tclFCmd.o tclFileName.o tclGet.o tclHash.o tclHistory.o \
	tclIndexObj.o tclInterp.o tclIO.o tclIOCmd.o tclIOSock.o \
	tclIOUtil.o tclLink.o tclListObj.o tclLoad.o tclMain.o tclNamesp.o \


	tclNotify.o tclObj.o tclParse.o tclPipe.o tclPkg.o tclPosixStr.o \


	tclPreserve.o tclProc.o tclStringObj.o tclTimer.o tclUtil.o tclVar.o


OBJS = ${GENERIC_OBJS} ${UNIX_OBJS} ${NOTIFY_OBJS} ${COMPAT_OBJS} @DL_OBJS@





GENERIC_HDRS = \
	$(GENERIC_DIR)/tclRegexp.h \
	$(GENERIC_DIR)/tcl.h \
	$(GENERIC_DIR)/tclInt.h \




	$(GENERIC_DIR)/tclPort.h \
	$(GENERIC_DIR)/tclPatch.h

GENERIC_SRCS = \
	$(GENERIC_DIR)/regexp.c \




	$(GENERIC_DIR)/tclAsync.c \
	$(GENERIC_DIR)/tclBasic.c \
	$(GENERIC_DIR)/tclBinary.c \
	$(GENERIC_DIR)/tclCkalloc.c \
	$(GENERIC_DIR)/tclClock.c \
	$(GENERIC_DIR)/tclCmdAH.c \
	$(GENERIC_DIR)/tclCmdIL.c \
	$(GENERIC_DIR)/tclCmdMZ.c \

	$(GENERIC_DIR)/tclCompExpr.c \
	$(GENERIC_DIR)/tclCompile.c \
	$(GENERIC_DIR)/tclDate.c \

	$(GENERIC_DIR)/tclEnv.c \
	$(GENERIC_DIR)/tclEvent.c \
	$(GENERIC_DIR)/tclExecute.c \
	$(GENERIC_DIR)/tclFCmd.c \
	$(GENERIC_DIR)/tclFileName.c \
	$(GENERIC_DIR)/tclGet.c \
	$(GENERIC_DIR)/tclHash.c \
	$(GENERIC_DIR)/tclHistory.c \
	$(GENERIC_DIR)/tclIndexObj.c \
	$(GENERIC_DIR)/tclInterp.c \
	$(GENERIC_DIR)/tclIO.c \
	$(GENERIC_DIR)/tclIOCmd.c \
	$(GENERIC_DIR)/tclIOSock.c \
	$(GENERIC_DIR)/tclIOUtil.c \
	$(GENERIC_DIR)/tclLink.c \
	$(GENERIC_DIR)/tclListObj.c \

	$(GENERIC_DIR)/tclLoad.c \
	$(GENERIC_DIR)/tclMain.c \
	$(GENERIC_DIR)/tclNamesp.c \
	$(GENERIC_DIR)/tclNotify.c \
	$(GENERIC_DIR)/tclObj.c \
        $(GENERIC_DIR)/tclParse.c \

	$(GENERIC_DIR)/tclPipe.c \
	$(GENERIC_DIR)/tclPkg.c \
	$(GENERIC_DIR)/tclPosixStr.c \
	$(GENERIC_DIR)/tclPreserve.c \
	$(GENERIC_DIR)/tclProc.c \






	$(GENERIC_DIR)/tclStringObj.c \
	$(GENERIC_DIR)/tclTest.c \
	$(GENERIC_DIR)/tclTestObj.c \


	$(GENERIC_DIR)/tclTimer.c \
	$(GENERIC_DIR)/tclUtil.c \
	$(GENERIC_DIR)/tclVar.c




UNIX_HDRS = \
	$(UNIX_DIR)/tclUnixPort.h

UNIX_SRCS = \
	$(UNIX_DIR)/tclAppInit.c \
	$(UNIX_DIR)/tclMtherr.c \
	$(UNIX_DIR)/tclUnixChan.c \
	$(UNIX_DIR)/tclUnixEvent.c \
	$(UNIX_DIR)/tclUnixFCmd.c \
	$(UNIX_DIR)/tclUnixFile.c \
	$(UNIX_DIR)/tclUnixNotfy.c \
	$(UNIX_DIR)/tclUnixPipe.c \
	$(UNIX_DIR)/tclUnixSock.c \
	$(UNIX_DIR)/tclUnixTest.c \

	$(UNIX_DIR)/tclUnixTime.c \
	$(UNIX_DIR)/tclUnixInit.c

DL_SRCS = \
	$(UNIX_DIR)/tclLoadAix.c \
	$(UNIX_DIR)/tclLoadAout.c \
	$(UNIX_DIR)/tclLoadDl.c \
	$(UNIX_DIR)/tclLoadDl2.c \
	$(UNIX_DIR)/tclLoadDld.c \
	$(GENERIC_DIR)/tclLoadNone.c \
	$(UNIX_DIR)/tclLoadOSF.c \
	$(UNIX_DIR)/tclLoadShl.c

# Note: don't include DL_SRCS in SRCS:  most of those files won't
# compile on the current machine, and they will cause problems for
# things like "make depend".

SRCS = $(GENERIC_SRCS) $(UNIX_SRCS)

all: ${TCL_LIB_FILE} tclsh

# The following target is configured by autoconf to generate either
# a shared library or non-shared library for Tcl.
${TCL_LIB_FILE}: ${OBJS}
	rm -f ${TCL_LIB_FILE}
	@MAKE_LIB@
	$(RANLIB) ${TCL_LIB_FILE}






# Make target which outputs the list of the .o contained in the Tcl lib
# usefull to build a single big shared library containing Tcl and other
# extensions.  used for the Tcl Plugin.  -- dl
# The dependency on OBJS is not there because we just want the list
# of objects here, not actually building them
tclLibObjs:







>

















>
>
>
>
>
>








|






>
>
|
>
>
|









>
|
>
>
>
>
>
>












|
>




>
|
|
|
|
|
|
>
>
|
>
>
|
>



>
>
>
>

|
|

>
>
>
>

|


|
>
>
>
>








>



>
















>






>





>
>
>
>
>
>



>
>




>
>
>














>

















|

|



|



>
>
>
>
>







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# The symbols below provide support for dynamic loading and shared
# libraries.  See configure.in for a description of what the
# symbols mean.  The values of the symbols are normally set by the
# configure script.  You shouldn't normally need to modify any of
# these definitions by hand.

SHLIB_LD = @SHLIB_LD@
SHLIB_CFLAGS = @SHLIB_CFLAGS@

SHLIB_SUFFIX = @SHLIB_SUFFIX@
#SHLIB_SUFFIX =

DLTEST_TARGETS = dltest/pkg5${SHLIB_SUFFIX} dltest/Makefile

# The following symbol is defined to "$(DLTEST_TARGETS)" if dynamic
# loading is available;  this causes everything in the "dltest"
# subdirectory to be built when making "tcltest.  If dynamic loading
# isn't available, configure defines this symbol to an empty string,
# in which case the shared libraries aren't built.
BUILD_DLTEST = @BUILD_DLTEST@
#BUILD_DLTEST =

TCL_LIB_FILE = @TCL_LIB_FILE@
#TCL_LIB_FILE = libtcl.a

TCL_LIB_FLAG = @TCL_LIB_FLAG@
#TCL_LIB_FLAG = -ltcl

TCL_EXP_FILE = @TCL_EXP_FILE@
TCL_BUILD_EXP_FILE = @TCL_BUILD_EXP_FILE@

#----------------------------------------------------------------
# The information below is modified by the configure script when
# Makefile is generated from Makefile.in.  You shouldn't normally
# modify any of this stuff by hand.
#----------------------------------------------------------------

COMPAT_OBJS =		@LIBOBJS@

AC_FLAGS =		@EXTRA_CFLAGS@ @DEFS@
RANLIB =		@RANLIB@
SRC_DIR =		@srcdir@
TOP_DIR =		@srcdir@/..
GENERIC_DIR = 		$(TOP_DIR)/generic
COMPAT_DIR =		$(TOP_DIR)/compat
TOOL_DIR =		$(TOP_DIR)/tools
UNIX_DIR = 		$(TOP_DIR)/unix
# Must be absolute because of the cd dltest $(DLTEST_DIR)/configure below.
DLTEST_DIR =		@TCL_SRC_DIR@/unix/dltest
# Must be absolute to so the corresponding tcltest's tcl_library is absolute.
TCL_BUILDTIME_LIBRARY=  @TCL_SRC_DIR@/library

CC =			@CC@

#----------------------------------------------------------------
# The information below should be usable as is.  The configure
# script won't modify it and you shouldn't need to modify it
# either.
#----------------------------------------------------------------


CC_SWITCHES =	${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} \
-I${GENERIC_DIR} -I${SRC_DIR} \
${AC_FLAGS} ${MATH_FLAGS} ${GENERIC_FLAGS} ${PROTO_FLAGS} ${MEM_DEBUG_FLAGS} \
${COMPILE_DEBUG_FLAGS} ${NO_DEPRECATED_FLAGS} ${ENV_FLAGS} \
-DTCL_SHLIB_EXT=\"${SHLIB_SUFFIX}\"

STUB_CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \
-I${GENERIC_DIR} -I${SRC_DIR} \
${AC_FLAGS} ${MATH_FLAGS} ${GENERIC_FLAGS} ${PROTO_FLAGS} ${MEM_DEBUG_FLAGS} \
${COMPILE_DEBUG_FLAGS} ${ENV_FLAGS} -DTCL_SHLIB_EXT=\"${SHLIB_SUFFIX}\"

LIBS =		@DL_LIBS@ @LIBS@ $(MATH_LIBS) -lc

DEPEND_SWITCHES = ${CFLAGS} -I${GENERIC_DIR} -I${SRC_DIR} \
${AC_FLAGS} ${MATH_FLAGS} \
${GENERIC_FLAGS} ${PROTO_FLAGS} ${MEM_DEBUG_FLAGS} \
-DTCL_SHLIB_EXT=\"${SHLIB_SUFFIX}\"

TCLSH_OBJS = tclAppInit.o

TCLTEST_OBJS = tclTestInit.o tclTest.o tclTestObj.o tclTestProcBodyObj.o \
	tclThreadTest.o	tclUnixTest.o

XTTEST_OBJS = tclTest.o tclTestObj.o tclUnixTest.o tclXtNotify.o \
	tclXtTest.o xtTestInit.o

GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \
	tclAsync.o tclBasic.o tclBinary.o \
	tclCkalloc.o tclClock.o tclCmdAH.o tclCmdIL.o tclCmdMZ.o \
	tclCompCmds.o tclCompExpr.o tclCompile.o tclDate.o tclEncoding.o \
	tclEnv.o tclEvent.o tclExecute.o tclFCmd.o tclFileName.o tclGet.o \
	tclHash.o tclHistory.o tclIndexObj.o tclInterp.o tclIO.o \
	tclIOCmd.o tclIOSock.o tclIOUtil.o tclLink.o tclListObj.o \
	tclLiteral.o tclLoad.o tclMain.o tclNamesp.o tclNotify.o \
	tclObj.o tclPanic.o tclParse.o tclParseExpr.o tclPipe.o \
	tclPkg.o tclPosixStr.o tclPreserve.o tclProc.o tclRegexp.o \
	tclResolve.o tclResult.o tclScan.o tclStringObj.o tclThread.o \
	tclStubInit.o tclStubLib.o tclTimer.o tclUtf.o tclUtil.o tclVar.o

STUB_LIB_OBJS = tclStubLib.o ${COMPAT_OBJS}

OBJS = ${GENERIC_OBJS} ${UNIX_OBJS} ${NOTIFY_OBJS} ${COMPAT_OBJS} @DL_OBJS@

TCL_DECLS = \
	$(GENERIC_DIR)/tcl.decls \
	$(GENERIC_DIR)/tclInt.decls

GENERIC_HDRS = \
	$(GENERIC_DIR)/tcl.h \
	$(GENERIC_DIR)/tclDecls.h \
	$(GENERIC_DIR)/tclInt.h \
	$(GENERIC_DIR)/tclIntDecls.h \
	$(GENERIC_DIR)/tclIntPlatDecls.h \
	$(GENERIC_DIR)/tclPatch.h \
	$(GENERIC_DIR)/tclPlatDecls.h \
	$(GENERIC_DIR)/tclPort.h \
	$(GENERIC_DIR)/tclRegexp.h

GENERIC_SRCS = \
	$(GENERIC_DIR)/regcomp.c \
	$(GENERIC_DIR)/regexec.c \
	$(GENERIC_DIR)/regfree.c \
	$(GENERIC_DIR)/regerror.c \
	$(GENERIC_DIR)/tclAlloc.c \
	$(GENERIC_DIR)/tclAsync.c \
	$(GENERIC_DIR)/tclBasic.c \
	$(GENERIC_DIR)/tclBinary.c \
	$(GENERIC_DIR)/tclCkalloc.c \
	$(GENERIC_DIR)/tclClock.c \
	$(GENERIC_DIR)/tclCmdAH.c \
	$(GENERIC_DIR)/tclCmdIL.c \
	$(GENERIC_DIR)/tclCmdMZ.c \
	$(GENERIC_DIR)/tclCompCmds.c \
	$(GENERIC_DIR)/tclCompExpr.c \
	$(GENERIC_DIR)/tclCompile.c \
	$(GENERIC_DIR)/tclDate.c \
	$(GENERIC_DIR)/tclEncoding.c \
	$(GENERIC_DIR)/tclEnv.c \
	$(GENERIC_DIR)/tclEvent.c \
	$(GENERIC_DIR)/tclExecute.c \
	$(GENERIC_DIR)/tclFCmd.c \
	$(GENERIC_DIR)/tclFileName.c \
	$(GENERIC_DIR)/tclGet.c \
	$(GENERIC_DIR)/tclHash.c \
	$(GENERIC_DIR)/tclHistory.c \
	$(GENERIC_DIR)/tclIndexObj.c \
	$(GENERIC_DIR)/tclInterp.c \
	$(GENERIC_DIR)/tclIO.c \
	$(GENERIC_DIR)/tclIOCmd.c \
	$(GENERIC_DIR)/tclIOSock.c \
	$(GENERIC_DIR)/tclIOUtil.c \
	$(GENERIC_DIR)/tclLink.c \
	$(GENERIC_DIR)/tclListObj.c \
	$(GENERIC_DIR)/tclLiteral.c \
	$(GENERIC_DIR)/tclLoad.c \
	$(GENERIC_DIR)/tclMain.c \
	$(GENERIC_DIR)/tclNamesp.c \
	$(GENERIC_DIR)/tclNotify.c \
	$(GENERIC_DIR)/tclObj.c \
        $(GENERIC_DIR)/tclParse.c \
        $(GENERIC_DIR)/tclParseExpr.c \
	$(GENERIC_DIR)/tclPipe.c \
	$(GENERIC_DIR)/tclPkg.c \
	$(GENERIC_DIR)/tclPosixStr.c \
	$(GENERIC_DIR)/tclPreserve.c \
	$(GENERIC_DIR)/tclProc.c \
	$(GENERIC_DIR)/tclRegexp.c \
	$(GENERIC_DIR)/tclResolve.c \
	$(GENERIC_DIR)/tclResult.c \
	$(GENERIC_DIR)/tclScan.c \
	$(GENERIC_DIR)/tclStubInit.c \
	$(GENERIC_DIR)/tclStubLib.c \
	$(GENERIC_DIR)/tclStringObj.c \
	$(GENERIC_DIR)/tclTest.c \
	$(GENERIC_DIR)/tclTestObj.c \
	$(GENERIC_DIR)/tclTestProcBodyObj.c \
	$(GENERIC_DIR)/tclThread.c \
	$(GENERIC_DIR)/tclTimer.c \
	$(GENERIC_DIR)/tclUtil.c \
	$(GENERIC_DIR)/tclVar.c

STUB_SRCS = \
	$(GENERIC_DIR)/tclStubLib.c

UNIX_HDRS = \
	$(UNIX_DIR)/tclUnixPort.h

UNIX_SRCS = \
	$(UNIX_DIR)/tclAppInit.c \
	$(UNIX_DIR)/tclMtherr.c \
	$(UNIX_DIR)/tclUnixChan.c \
	$(UNIX_DIR)/tclUnixEvent.c \
	$(UNIX_DIR)/tclUnixFCmd.c \
	$(UNIX_DIR)/tclUnixFile.c \
	$(UNIX_DIR)/tclUnixNotfy.c \
	$(UNIX_DIR)/tclUnixPipe.c \
	$(UNIX_DIR)/tclUnixSock.c \
	$(UNIX_DIR)/tclUnixTest.c \
	$(UNIX_DIR)/tclUnixThrd.c \
	$(UNIX_DIR)/tclUnixTime.c \
	$(UNIX_DIR)/tclUnixInit.c

DL_SRCS = \
	$(UNIX_DIR)/tclLoadAix.c \
	$(UNIX_DIR)/tclLoadAout.c \
	$(UNIX_DIR)/tclLoadDl.c \
	$(UNIX_DIR)/tclLoadDl2.c \
	$(UNIX_DIR)/tclLoadDld.c \
	$(GENERIC_DIR)/tclLoadNone.c \
	$(UNIX_DIR)/tclLoadOSF.c \
	$(UNIX_DIR)/tclLoadShl.c

# Note: don't include DL_SRCS in SRCS:  most of those files won't
# compile on the current machine, and they will cause problems for
# things like "make depend".

SRCS = $(GENERIC_SRCS) $(UNIX_SRCS) $(STUB_SRCS)

all: ${TCL_LIB_FILE} $(TCL_STUB_LIB_FILE) tclsh

# The following target is configured by autoconf to generate either
# a shared library or non-shared library for Tcl.
${TCL_LIB_FILE}: ${OBJS} ${STUB_LIB_FILE}
	rm -f ${TCL_LIB_FILE}
	@MAKE_LIB@
	$(RANLIB) ${TCL_LIB_FILE}

${STUB_LIB_FILE}: ${STUB_LIB_OBJS}
	rm -f ${STUB_LIB_FILE}
	@MAKE_STUB_LIB@
	$(RANLIB) ${STUB_LIB_FILE}

# Make target which outputs the list of the .o contained in the Tcl lib
# usefull to build a single big shared library containing Tcl and other
# extensions.  used for the Tcl Plugin.  -- dl
# The dependency on OBJS is not there because we just want the list
# of objects here, not actually building them
tclLibObjs:
348
349
350
351
352
353
354

355
356
357
358
359
360

361
362
363
364
365
366
367
368

# Note, in the target below TCL_LIBRARY needs to be set or else
# "make test" won't work in the case where the compilation directory
# isn't the same as the source directory.

test: tcltest
	LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}; export LD_LIBRARY_PATH; \

	TCL_LIBRARY=${TOP_DIR}/library; export TCL_LIBRARY; \
	( echo cd $(TOP_DIR)/tests\; source all ) | ./tcltest

# Useful target to launch a built tcltest with the proper path,...
runtest:
	LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}; export LD_LIBRARY_PATH; \

	TCL_LIBRARY=${TOP_DIR}/library; export TCL_LIBRARY; \
	./tcltest

# The following target outputs the name of the top-level source directory
# for Tcl (it is used by Tk's configure script, for example).  The
# .NO_PARALLEL line is needed to avoid problems under Sun's "pmake".
# Note: this target is now obsolete (use the autoconf variable
# TCL_SRC_DIR from tclConfig.sh instead).







>
|
|


|

>
|







434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456

# Note, in the target below TCL_LIBRARY needs to be set or else
# "make test" won't work in the case where the compilation directory
# isn't the same as the source directory.

test: tcltest
	LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}; export LD_LIBRARY_PATH; \
	SHLIB_PATH=`pwd`:${SHLIB_PATH}; export SHLIB_PATH; \
	TCL_LIBRARY="${TCL_BUILDTIME_LIBRARY}"; export TCL_LIBRARY; \
	./tcltest $(TOP_DIR)/tests/all.tcl

# Useful target to launch a built tcltest with the proper path,...
runtest: tcltest
	LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}; export LD_LIBRARY_PATH; \
	SHLIB_PATH=`pwd`:${SHLIB_PATH}; export SHLIB_PATH; \
	TCL_LIBRARY="${TCL_BUILDTIME_LIBRARY}"; export TCL_LIBRARY; \
	./tcltest

# The following target outputs the name of the top-level source directory
# for Tcl (it is used by Tk's configure script, for example).  The
# .NO_PARALLEL line is needed to avoid problems under Sun's "pmake".
# Note: this target is now obsolete (use the autoconf variable
# TCL_SRC_DIR from tclConfig.sh instead).
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
# only run by hand as yacc is not available in all environments.
# The name of the .c file is different than the name of the .y file
# so that make doesn't try to automatically regenerate the .c file.

gendate:
	yacc -l $(GENERIC_DIR)/tclGetDate.y
	sed -e 's/yy/TclDate/g' -e '/^#include <values.h>/d' \
	    -e 's/SCCSID/%Z\% %M\% %I\% %E\% %U\%/g' \
	    -e '/#ifdef __STDC__/,/#endif/d' -e '/TclDateerrlab:/d' \
	    -e '/TclDatenewstate:/d' -e '/#pragma/d' \
	    <y.tab.c >$(GENERIC_DIR)/tclDate.c
	rm y.tab.c

# The following targets generate the shared libraries in dltest that
# are used for testing;  they are included as part of the "tcltest"







|







464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
# only run by hand as yacc is not available in all environments.
# The name of the .c file is different than the name of the .y file
# so that make doesn't try to automatically regenerate the .c file.

gendate:
	yacc -l $(GENERIC_DIR)/tclGetDate.y
	sed -e 's/yy/TclDate/g' -e '/^#include <values.h>/d' \
	    -e "s/SCCSID/RCS: @(#) \$Id\$"
	    -e '/#ifdef __STDC__/,/#endif/d' -e '/TclDateerrlab:/d' \
	    -e '/TclDatenewstate:/d' -e '/#pragma/d' \
	    <y.tab.c >$(GENERIC_DIR)/tclDate.c
	rm y.tab.c

# The following targets generate the shared libraries in dltest that
# are used for testing;  they are included as part of the "tcltest"
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423
424
425
426





427
428
429
430





431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451


452
453

454
455
456
457
458
459
460
461
462
463
464
465
466




467
468
469
470
471
472
473
474
475
476
477
478
479
480

install: install-binaries install-libraries install-man

# Note: before running ranlib below, must cd to target directory because
# some ranlibs write to current directory, and this might not always be
# possible (e.g. if installing as root).

install-binaries: $(TCL_LIB_FILE) tclsh

	@for i in $(LIB_INSTALL_DIR) $(BIN_INSTALL_DIR) ; \
	    do \
	    if [ ! -d $$i ] ; then \
		echo "Making directory $$i"; \
		mkdir $$i; \
		chmod 755 $$i; \
		else true; \
		fi; \
	    done;
	@echo "Installing $(TCL_LIB_FILE)"
	@$(INSTALL_DATA) $(TCL_LIB_FILE) $(LIB_INSTALL_DIR)/$(TCL_LIB_FILE)
	@(cd $(LIB_INSTALL_DIR); $(RANLIB) $(TCL_LIB_FILE))
	@chmod 555 $(LIB_INSTALL_DIR)/$(TCL_LIB_FILE)





	@echo "Installing tclsh"
	@$(INSTALL_PROGRAM) tclsh $(BIN_INSTALL_DIR)/tclsh$(VERSION)
	@echo "Installing tclConfig.sh"
	@$(INSTALL_DATA) tclConfig.sh $(LIB_INSTALL_DIR)/tclConfig.sh






install-libraries:
	@for i in $(INSTALL_ROOT)$(prefix)/lib $(INCLUDE_INSTALL_DIR) \
		$(SCRIPT_INSTALL_DIR); \
	    do \
	    if [ ! -d $$i ] ; then \
		echo "Making directory $$i"; \
		mkdir $$i; \
		chmod 755 $$i; \
		else true; \
		fi; \
	    done;
	@for i in http2.0 http1.0 opt0.1; \
	    do \
	    if [ ! -d $(SCRIPT_INSTALL_DIR)/$$i ] ; then \
		echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
		mkdir $(SCRIPT_INSTALL_DIR)/$$i; \
		chmod 755 $(SCRIPT_INSTALL_DIR)/$$i; \
		else true; \
		fi; \
	    done;


	@echo "Installing tcl.h"
	@$(INSTALL_DATA) $(GENERIC_DIR)/tcl.h $(INCLUDE_INSTALL_DIR)/tcl.h

	@for i in $(TOP_DIR)/library/*.tcl $(TOP_DIR)/library/tclIndex $(UNIX_DIR)/tclAppInit.c $(UNIX_DIR)/ldAix; \
	    do \
	    echo "Installing $$i"; \
	    $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR); \
	    done;
	@for i in http2.0 http1.0 opt0.1; \
	    do \
	    for j in $(TOP_DIR)/library/$$i/*.tcl ; \
		do \
		echo "Installing $$j"; \
		$(INSTALL_DATA) $$j $(SCRIPT_INSTALL_DIR)/$$i; \
		done; \
	    done;





install-man:
	@for i in $(MAN_INSTALL_DIR) $(MAN1_INSTALL_DIR) $(MAN3_INSTALL_DIR) $(MANN_INSTALL_DIR) ; \
	    do \
	    if [ ! -d $$i ] ; then \
		echo "Making directory $$i"; \
		mkdir $$i; \
		chmod 755 $$i; \
		else true; \
		fi; \
	    done;
	@cd $(TOP_DIR)/doc; for i in *.1; \
	    do \
	    echo "Installing doc/$$i"; \







|
>




|








>
>
>
>
>




>
>
>
>
>







|




|



|




>
>
|
|
>





|







>
>
>
>






|







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

install: install-binaries install-libraries install-man

# Note: before running ranlib below, must cd to target directory because
# some ranlibs write to current directory, and this might not always be
# possible (e.g. if installing as root).

install-binaries: $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(TCL_BUILD_EXP_FILE) \
		tclsh
	@for i in $(LIB_INSTALL_DIR) $(BIN_INSTALL_DIR) ; \
	    do \
	    if [ ! -d $$i ] ; then \
		echo "Making directory $$i"; \
		mkdir -p $$i; \
		chmod 755 $$i; \
		else true; \
		fi; \
	    done;
	@echo "Installing $(TCL_LIB_FILE)"
	@$(INSTALL_DATA) $(TCL_LIB_FILE) $(LIB_INSTALL_DIR)/$(TCL_LIB_FILE)
	@(cd $(LIB_INSTALL_DIR); $(RANLIB) $(TCL_LIB_FILE))
	@chmod 555 $(LIB_INSTALL_DIR)/$(TCL_LIB_FILE)
	@if test "$(TCL_BUILD_EXP_FILE)" != ""; then \
	    echo "Installing $(TCL_EXP_FILE)"; \
	    $(INSTALL_DATA) $(TCL_BUILD_EXP_FILE) \
			$(LIB_INSTALL_DIR)/$(TCL_EXP_FILE); \
	    fi
	@echo "Installing tclsh"
	@$(INSTALL_PROGRAM) tclsh $(BIN_INSTALL_DIR)/tclsh$(VERSION)
	@echo "Installing tclConfig.sh"
	@$(INSTALL_DATA) tclConfig.sh $(LIB_INSTALL_DIR)/tclConfig.sh
	@if test "$(TCL_STUB_LIB_FILE)" != "" ; then \
	    echo "Installing $(TCL_STUB_LIB_FILE)"; \
	    $(INSTALL_DATA) $(STUB_LIB_FILE) \
			 $(LIB_INSTALL_DIR)/$(TCL_STUB_LIB_FILE); \
	    fi

install-libraries:
	@for i in $(INSTALL_ROOT)$(prefix)/lib $(INCLUDE_INSTALL_DIR) \
		$(SCRIPT_INSTALL_DIR); \
	    do \
	    if [ ! -d $$i ] ; then \
		echo "Making directory $$i"; \
		mkdir -p $$i; \
		chmod 755 $$i; \
		else true; \
		fi; \
	    done;
	@for i in http2.0 http1.0 opt0.4 encoding msgcat1.0; \
	    do \
	    if [ ! -d $(SCRIPT_INSTALL_DIR)/$$i ] ; then \
		echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
		mkdir -p $(SCRIPT_INSTALL_DIR)/$$i; \
		chmod 755 $(SCRIPT_INSTALL_DIR)/$$i; \
		else true; \
		fi; \
	    done;
	@for i in $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h ; \
	    do \
	    echo "Installing $$i"; \
	    $(INSTALL_DATA) $$i $(INCLUDE_INSTALL_DIR); \
	    done;
	@for i in $(TOP_DIR)/library/*.tcl $(TOP_DIR)/library/tclIndex $(UNIX_DIR)/tclAppInit.c $(UNIX_DIR)/ldAix; \
	    do \
	    echo "Installing $$i"; \
	    $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR); \
	    done;
	@for i in http2.0 http1.0 opt0.4 msgcat1.0; \
	    do \
	    for j in $(TOP_DIR)/library/$$i/*.tcl ; \
		do \
		echo "Installing $$j"; \
		$(INSTALL_DATA) $$j $(SCRIPT_INSTALL_DIR)/$$i; \
		done; \
	    done;
	@for i in $(TOP_DIR)/library/encoding/*.enc ; do \
		echo "Installing $$i"; \
		$(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR)/encoding; \
	done;

install-man:
	@for i in $(MAN_INSTALL_DIR) $(MAN1_INSTALL_DIR) $(MAN3_INSTALL_DIR) $(MANN_INSTALL_DIR) ; \
	    do \
	    if [ ! -d $$i ] ; then \
		echo "Making directory $$i"; \
		mkdir -p $$i; \
		chmod 755 $$i; \
		else true; \
		fi; \
	    done;
	@cd $(TOP_DIR)/doc; for i in *.1; \
	    do \
	    echo "Installing doc/$$i"; \
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
clean:
	rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \
		errors tclsh tcltest lib.exp
	if test -f dltest/Makefile; then cd dltest; $(MAKE) clean; fi

distclean: clean
	rm -rf Makefile config.status config.cache config.log tclConfig.sh \
		SUNWtcl.* prototype
	if test -f dltest/Makefile; then cd dltest; $(MAKE) distclean; fi

depend:
	makedepend -- $(DEPEND_SWITCHES) -- $(SRCS)

bp: $(UNIX_DIR)/bp.c
	$(CC) $(CC_SWITCHES) $(UNIX_DIR)/bp.c -o bp

# Test binaries.  The rules for tclTestInit.o and xtTestInit.o are
# complicated because they are compiled from tclAppInit.c.  Can't use
# the "-o" option because this doesn't work on some strange compilers
# (e.g. UnixWare).

tclTestInit.o: $(UNIX_DIR)/tclAppInit.c
	@if test -f tclAppInit.o ; then \
	    rm -f tclAppInit.sav; \
	    mv tclAppInit.o tclAppInit.sav; \
	fi;
	$(CC) -c $(CC_SWITCHES) -DTCL_TEST $(UNIX_DIR)/tclAppInit.c


	rm -f tclTestInit.o
	mv tclAppInit.o tclTestInit.o
	@if test -f tclAppInit.sav ; then \
	    mv tclAppInit.sav tclAppInit.o; \
	fi;

xtTestInit.o: $(UNIX_DIR)/tclAppInit.c







|


















|
>
>







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
clean:
	rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \
		errors tclsh tcltest lib.exp
	if test -f dltest/Makefile; then cd dltest; $(MAKE) clean; fi

distclean: clean
	rm -rf Makefile config.status config.cache config.log tclConfig.sh \
		$(PACKAGE).* prototype
	if test -f dltest/Makefile; then cd dltest; $(MAKE) distclean; fi

depend:
	makedepend -- $(DEPEND_SWITCHES) -- $(SRCS)

bp: $(UNIX_DIR)/bp.c
	$(CC) $(CC_SWITCHES) $(UNIX_DIR)/bp.c -o bp

# Test binaries.  The rules for tclTestInit.o and xtTestInit.o are
# complicated because they are compiled from tclAppInit.c.  Can't use
# the "-o" option because this doesn't work on some strange compilers
# (e.g. UnixWare).

tclTestInit.o: $(UNIX_DIR)/tclAppInit.c
	@if test -f tclAppInit.o ; then \
	    rm -f tclAppInit.sav; \
	    mv tclAppInit.o tclAppInit.sav; \
	fi;
	$(CC) -c $(CC_SWITCHES) \
		-DTCL_BUILDTIME_LIBRARY="\"${TCL_BUILDTIME_LIBRARY}\"" \
		-DTCL_TEST $(UNIX_DIR)/tclAppInit.c
	rm -f tclTestInit.o
	mv tclAppInit.o tclTestInit.o
	@if test -f tclAppInit.sav ; then \
	    mv tclAppInit.sav tclAppInit.o; \
	fi;

xtTestInit.o: $(UNIX_DIR)/tclAppInit.c
550
551
552
553
554
555
556

557



558
559

560





561
562
563
564






565
566
567
568
569
570
571
	mv tclAppInit.o xtTestInit.o
	@if test -f tclAppInit.sav ; then \
	    mv tclAppInit.sav tclAppInit.o; \
	fi;

# Object files used on all Unix systems:


panic.o: $(GENERIC_DIR)/panic.c



	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/panic.c


regexp.o: $(GENERIC_DIR)/regexp.c





	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/regexp.c

tclAppInit.o: $(UNIX_DIR)/tclAppInit.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclAppInit.c







tclAsync.o: $(GENERIC_DIR)/tclAsync.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclAsync.c

tclBasic.o: $(GENERIC_DIR)/tclBasic.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclBasic.c








>
|
>
>
>
|

>
|
>
>
>
>
>
|



>
>
>
>
>
>







658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
	mv tclAppInit.o xtTestInit.o
	@if test -f tclAppInit.sav ; then \
	    mv tclAppInit.sav tclAppInit.o; \
	fi;

# Object files used on all Unix systems:

REGHDRS=$(GENERIC_DIR)/regex.h $(GENERIC_DIR)/regguts.h \
		$(GENERIC_DIR)/regcustom.h
regcomp.o: $(REGHDRS) $(GENERIC_DIR)/regcomp.c $(GENERIC_DIR)/regc_lex.c \
		$(GENERIC_DIR)/regc_color.c $(GENERIC_DIR)/regc_locale.c \
		$(GENERIC_DIR)/regc_nfa.c $(GENERIC_DIR)/regc_cvec.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/regcomp.c

regexec.o: $(REGHDRS) $(GENERIC_DIR)/regexec.c $(GENERIC_DIR)/rege_dfa.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/regexec.c

regfree.o: $(REGHDRS) $(GENERIC_DIR)/regfree.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/regfree.c

regerror.o: $(REGHDRS) $(GENERIC_DIR)/regerrs.h $(GENERIC_DIR)/regerror.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/regerror.c

tclAppInit.o: $(UNIX_DIR)/tclAppInit.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclAppInit.c

# On unix we want to use the normal malloc/free implementation, so we
# specifically set the USE_TCLALLOC flag.

tclAlloc.o: $(GENERIC_DIR)/tclAlloc.c
	$(CC) -c $(CC_SWITCHES) -DUSE_TCLALLOC=0 $(GENERIC_DIR)/tclAlloc.c

tclAsync.o: $(GENERIC_DIR)/tclAsync.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclAsync.c

tclBasic.o: $(GENERIC_DIR)/tclBasic.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclBasic.c

586
587
588
589
590
591
592



593
594
595
596
597
598



599
600
601
602
603
604
605

tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdMZ.c

tclDate.o: $(GENERIC_DIR)/tclDate.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclDate.c




tclCompExpr.o: $(GENERIC_DIR)/tclCompExpr.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompExpr.c

tclCompile.o: $(GENERIC_DIR)/tclCompile.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompile.c




tclEnv.o: $(GENERIC_DIR)/tclEnv.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclEnv.c

tclEvent.o: $(GENERIC_DIR)/tclEvent.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclEvent.c

tclExecute.o: $(GENERIC_DIR)/tclExecute.c







>
>
>






>
>
>







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

tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdMZ.c

tclDate.o: $(GENERIC_DIR)/tclDate.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclDate.c

tclCompCmds.o: $(GENERIC_DIR)/tclCompCmds.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmds.c

tclCompExpr.o: $(GENERIC_DIR)/tclCompExpr.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompExpr.c

tclCompile.o: $(GENERIC_DIR)/tclCompile.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompile.c

tclEncoding.o: $(GENERIC_DIR)/tclEncoding.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclEncoding.c

tclEnv.o: $(GENERIC_DIR)/tclEnv.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclEnv.c

tclEvent.o: $(GENERIC_DIR)/tclEvent.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclEvent.c

tclExecute.o: $(GENERIC_DIR)/tclExecute.c
640
641
642
643
644
645
646



647
648
649
650
651
652
653

tclLink.o: $(GENERIC_DIR)/tclLink.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLink.c

tclListObj.o: $(GENERIC_DIR)/tclListObj.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclListObj.c




tclObj.o: $(GENERIC_DIR)/tclObj.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclObj.c

tclLoad.o: $(GENERIC_DIR)/tclLoad.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLoad.c

tclLoadAix.o: $(UNIX_DIR)/tclLoadAix.c







>
>
>







770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786

tclLink.o: $(GENERIC_DIR)/tclLink.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLink.c

tclListObj.o: $(GENERIC_DIR)/tclListObj.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclListObj.c

tclLiteral.o: $(GENERIC_DIR)/tclLiteral.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLiteral.c

tclObj.o: $(GENERIC_DIR)/tclObj.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclObj.c

tclLoad.o: $(GENERIC_DIR)/tclLoad.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLoad.c

tclLoadAix.o: $(UNIX_DIR)/tclLoadAix.c
685
686
687
688
689
690
691






692
693
694
695
696
697
698
699
700
701
702
703
704
705
706












707
708
709



710
711
712



713
714
715
716
717
718
719
720
721



722
723
724






725
726
727
728
729
730
731

tclNotify.o: $(GENERIC_DIR)/tclNotify.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclNotify.c

tclParse.o: $(GENERIC_DIR)/tclParse.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclParse.c







tclPipe.o: $(GENERIC_DIR)/tclPipe.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPipe.c

tclPkg.o: $(GENERIC_DIR)/tclPkg.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPkg.c

tclPosixStr.o: $(GENERIC_DIR)/tclPosixStr.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPosixStr.c

tclPreserve.o: $(GENERIC_DIR)/tclPreserve.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPreserve.c

tclProc.o: $(GENERIC_DIR)/tclProc.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclProc.c













tclStringObj.o: $(GENERIC_DIR)/tclStringObj.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclStringObj.c




tclUtil.o: $(GENERIC_DIR)/tclUtil.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclUtil.c




tclVar.o: $(GENERIC_DIR)/tclVar.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclVar.c

tclTest.o: $(GENERIC_DIR)/tclTest.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTest.c

tclTestObj.o: $(GENERIC_DIR)/tclTestObj.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTestObj.c




tclTimer.o: $(GENERIC_DIR)/tclTimer.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTimer.c







tclUnixChan.o: $(UNIX_DIR)/tclUnixChan.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixChan.c

tclUnixEvent.o: $(UNIX_DIR)/tclUnixEvent.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixEvent.c

tclUnixFCmd.o: $(UNIX_DIR)/tclUnixFCmd.c







>
>
>
>
>
>















>
>
>
>
>
>
>
>
>
>
>
>



>
>
>



>
>
>









>
>
>



>
>
>
>
>
>







818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897

tclNotify.o: $(GENERIC_DIR)/tclNotify.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclNotify.c

tclParse.o: $(GENERIC_DIR)/tclParse.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclParse.c

tclParseExpr.o: $(GENERIC_DIR)/tclParseExpr.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclParseExpr.c

tclPanic.o: $(GENERIC_DIR)/tclPanic.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPanic.c

tclPipe.o: $(GENERIC_DIR)/tclPipe.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPipe.c

tclPkg.o: $(GENERIC_DIR)/tclPkg.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPkg.c

tclPosixStr.o: $(GENERIC_DIR)/tclPosixStr.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPosixStr.c

tclPreserve.o: $(GENERIC_DIR)/tclPreserve.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclPreserve.c

tclProc.o: $(GENERIC_DIR)/tclProc.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclProc.c

tclRegexp.o: $(GENERIC_DIR)/tclRegexp.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclRegexp.c

tclResolve.o: $(GENERIC_DIR)/tclResolve.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclResolve.c

tclResult.o: $(GENERIC_DIR)/tclResult.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclResult.c

tclScan.o: $(GENERIC_DIR)/tclScan.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclScan.c

tclStringObj.o: $(GENERIC_DIR)/tclStringObj.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclStringObj.c

tclStubInit.o: $(GENERIC_DIR)/tclStubInit.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclStubInit.c

tclUtil.o: $(GENERIC_DIR)/tclUtil.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclUtil.c

tclUtf.o: $(GENERIC_DIR)/tclUtf.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclUtf.c

tclVar.o: $(GENERIC_DIR)/tclVar.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclVar.c

tclTest.o: $(GENERIC_DIR)/tclTest.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTest.c

tclTestObj.o: $(GENERIC_DIR)/tclTestObj.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTestObj.c

tclTestProcBodyObj.o: $(GENERIC_DIR)/tclTestProcBodyObj.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTestProcBodyObj.c

tclTimer.o: $(GENERIC_DIR)/tclTimer.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTimer.c

tclThread.o: $(GENERIC_DIR)/tclThread.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclThread.c

tclThreadTest.o: $(GENERIC_DIR)/tclThreadTest.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclThreadTest.c

tclUnixChan.o: $(UNIX_DIR)/tclUnixChan.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixChan.c

tclUnixEvent.o: $(UNIX_DIR)/tclUnixEvent.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixEvent.c

tclUnixFCmd.o: $(UNIX_DIR)/tclUnixFCmd.c
742
743
744
745
746
747
748



749
750
751
752
753
754
755
756
757



758
759
760
761
762
763
764
765
766
767



768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788







789
790
791

























792
793
794
795
796
797
798

tclUnixSock.o: $(UNIX_DIR)/tclUnixSock.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixSock.c

tclUnixTest.o: $(UNIX_DIR)/tclUnixTest.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixTest.c




tclUnixTime.o: $(UNIX_DIR)/tclUnixTime.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixTime.c

tclUnixInit.o: $(UNIX_DIR)/tclUnixInit.c tclConfig.sh
	$(CC) -c $(CC_SWITCHES) -DTCL_LIBRARY=\"${TCL_LIBRARY}\" \
		-DTCL_PACKAGE_PATH="\"${TCL_PACKAGE_PATH}\"" \
		$(UNIX_DIR)/tclUnixInit.c

# compat binaries




fixstrtod.o: $(COMPAT_DIR)/fixstrtod.c
	$(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/fixstrtod.c

getcwd.o: $(COMPAT_DIR)/getcwd.c
	$(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/getcwd.c

opendir.o: $(COMPAT_DIR)/opendir.c
	$(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/opendir.c




strncasecmp.o: $(COMPAT_DIR)/strncasecmp.c
	$(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/strncasecmp.c

strstr.o: $(COMPAT_DIR)/strstr.c
	$(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/strstr.c

strtod.o: $(COMPAT_DIR)/strtod.c
	$(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/strtod.c

strtol.o: $(COMPAT_DIR)/strtol.c
	$(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/strtol.c

strtoul.o: $(COMPAT_DIR)/strtoul.c
	$(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/strtoul.c

tmpnam.o: $(COMPAT_DIR)/tmpnam.c
	$(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/tmpnam.c

waitpid.o: $(COMPAT_DIR)/waitpid.c
	$(CC) -c $(CC_SWITCHES) $(COMPAT_DIR)/waitpid.c








.c.o:
	$(CC) -c $(CC_SWITCHES) $<


























#
# Target to check for proper usage of UCHAR macro.
#

checkuchar:
	-egrep isalnum\|isalpha\|iscntrl\|isdigit\|islower\|isprint\|ispunct\|isspace\|isupper\|isxdigit\|toupper\|tolower $(SRCS) | grep -v UCHAR








>
>
>



|




|
>
>
>


|


|


|

>
>
>

|


|


|


|


|


|


|

>
>
>
>
>
>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005

tclUnixSock.o: $(UNIX_DIR)/tclUnixSock.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixSock.c

tclUnixTest.o: $(UNIX_DIR)/tclUnixTest.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixTest.c

tclUnixThrd.o: $(UNIX_DIR)/tclUnixThrd.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixThrd.c

tclUnixTime.o: $(UNIX_DIR)/tclUnixTime.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixTime.c

tclUnixInit.o: $(UNIX_DIR)/tclUnixInit.c $(GENERIC_DIR)/tclInitScript.h tclConfig.sh
	$(CC) -c $(CC_SWITCHES) -DTCL_LIBRARY=\"${TCL_LIBRARY}\" \
		-DTCL_PACKAGE_PATH="\"${TCL_PACKAGE_PATH}\"" \
		$(UNIX_DIR)/tclUnixInit.c

# compat binaries, these must be compiled for use in a shared library
# even though they may be placed in a static executable or library.  Since
# they are included in both the tcl library and the stub library, they
# need to be relocatable.

fixstrtod.o: $(COMPAT_DIR)/fixstrtod.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/fixstrtod.c

getcwd.o: $(COMPAT_DIR)/getcwd.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/getcwd.c

opendir.o: $(COMPAT_DIR)/opendir.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/opendir.c

memcmp.o: $(COMPAT_DIR)/memcmp.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/memcmp.c

strncasecmp.o: $(COMPAT_DIR)/strncasecmp.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/strncasecmp.c

strstr.o: $(COMPAT_DIR)/strstr.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/strstr.c

strtod.o: $(COMPAT_DIR)/strtod.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/strtod.c

strtol.o: $(COMPAT_DIR)/strtol.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/strtol.c

strtoul.o: $(COMPAT_DIR)/strtoul.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/strtoul.c

tmpnam.o: $(COMPAT_DIR)/tmpnam.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/tmpnam.c

waitpid.o: $(COMPAT_DIR)/waitpid.c
	$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/waitpid.c

# Stub library binaries, these must be compiled for use in a shared library
# even though they will be placed in a static archive


tclStubLib.o: $(GENERIC_DIR)/tclStubLib.c
	$(CC) -c $(STUB_CC_SWITCHES) $(GENERIC_DIR)/tclStubLib.c

.c.o:
	$(CC) -c $(CC_SWITCHES) $<

#
# Target to regenerate header files and stub files from the *.decls tables.
#

genstubs:
	tclsh $(TOOL_DIR)/genStubs.tcl $(GENERIC_DIR) \
		$(GENERIC_DIR)/tcl.decls $(GENERIC_DIR)/tclInt.decls

#
# Target to check that all exported functions have an entry in the stubs
# tables.
#

checkstubs:
	-@for i in `nm -p $(TCL_LIB_FILE) | awk '$$2 ~ /T/ { print $$3 }' \
		| sort -n`; do \
		match=0; \
		for j in $(TCL_DECLS); do \
		    if [ `grep -c $$i $$j` -gt 0 ]; then \
			match=1; \
		    fi; \
		done; \
		if [ $$match -eq 0 ]; then echo $$i; fi \
	done

#
# Target to check for proper usage of UCHAR macro.
#

checkuchar:
	-egrep isalnum\|isalpha\|iscntrl\|isdigit\|islower\|isprint\|ispunct\|isspace\|isupper\|isxdigit\|toupper\|tolower $(SRCS) | grep -v UCHAR

806
807
808
809
810
811
812

813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838

839
840
841
842
843
844
845
846
847
848
849
850


851
852
853
854
855
856
857
858
859
860
861
862



863
864
865

866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886











887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917


918







919


920
921
922
923
924
925
926
927
928


929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955


956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

#
# Target to create a proper Tcl distribution from information in the
# master source directory.  DISTDIR must be defined to indicate where
# to put the distribution.
#


DISTNAME =	tcl@TCL_VERSION@@TCL_PATCH_LEVEL@
ZIPNAME =	tcl@TCL_MAJOR_VERSION@@TCL_MINOR_VERSION@@[email protected]
DISTDIR =	/proj/tcl/dist/$(DISTNAME)
$(UNIX_DIR)/configure: $(UNIX_DIR)/configure.in
	autoconf $(UNIX_DIR)/configure.in > $(UNIX_DIR)/configure
dist: $(UNIX_DIR)/configure
	rm -rf $(DISTDIR)
	mkdir $(DISTDIR)
	mkdir $(DISTDIR)/unix
	cp -p $(UNIX_DIR)/*.c $(UNIX_DIR)/*.h $(DISTDIR)/unix
	rm -f $(DISTDIR)/unix/bp.c $(DISTDIR)/unix/tclXtNotify.c
	cp $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix
	chmod 664 $(DISTDIR)/unix/Makefile.in
	cp $(UNIX_DIR)/configure $(UNIX_DIR)/configure.in \
		$(UNIX_DIR)/tclConfig.sh.in $(UNIX_DIR)/install-sh \
		$(UNIX_DIR)/porting.notes $(UNIX_DIR)/porting.old \
		$(UNIX_DIR)/README $(UNIX_DIR)/ldAix \
		$(DISTDIR)/unix
	chmod 775 $(DISTDIR)/unix/configure $(DISTDIR)/unix/configure.in
	chmod 775 $(DISTDIR)/unix/ldAix
	chmod +x $(DISTDIR)/unix/install-sh
	tclsh $(UNIX_DIR)/mkLinks.tcl \
		$(UNIX_DIR)/../doc/*.[13n] > $(DISTDIR)/unix/mkLinks
	chmod +x $(DISTDIR)/unix/mkLinks
	mkdir $(DISTDIR)/generic
	cp -p $(GENERIC_DIR)/*.c $(GENERIC_DIR)/*.h $(DISTDIR)/generic

	cp -p $(GENERIC_DIR)/README $(DISTDIR)/generic
	cp -p $(GENERIC_DIR)/tclGetDate.y $(DISTDIR)/generic
	cp -p $(TOP_DIR)/changes $(TOP_DIR)/README $(TOP_DIR)/license.terms \
		$(DISTDIR)
	mkdir $(DISTDIR)/library
	cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/library/*.tcl \
		$(TOP_DIR)/library/tclIndex $(DISTDIR)/library
	for i in http2.0 http1.0 opt0.1; \
	    do \
		mkdir $(DISTDIR)/library/$$i ;\
		cp -p $(TOP_DIR)/library/$$i/*.tcl $(DISTDIR)/library/$$i; \
	    done;


	mkdir $(DISTDIR)/doc
	cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/doc/*.[13n] \
		$(TOP_DIR)/doc/man.macros $(DISTDIR)/doc
	mkdir $(DISTDIR)/compat
	cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/compat/*.c \
		$(TOP_DIR)/compat/*.h $(TOP_DIR)/compat/README \
		$(DISTDIR)/compat
	mkdir $(DISTDIR)/tests
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/tests
	cp -p $(TOP_DIR)/tests/*.test $(TOP_DIR)/tests/README \
		$(TOP_DIR)/tests/all $(TOP_DIR)/tests/remote.tcl \
		$(TOP_DIR)/tests/defs $(DISTDIR)/tests



	mkdir $(DISTDIR)/win
	cp -p $(TOP_DIR)/win/*.c $(TOP_DIR)/win/*.h $(TOP_DIR)/win/*.rc \
		$(DISTDIR)/win

	cp -p $(TOP_DIR)/win/makefile.* $(DISTDIR)/win
	cp -p $(TOP_DIR)/win/README $(DISTDIR)/win
	cp -p $(TOP_DIR)/win/pkgIndex.tcl $(DISTDIR)/win
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/win
	mkdir $(DISTDIR)/mac
	sccs edit -s $(TOP_DIR)/mac/tclMacProjects.sit.hqx
	cp -p tclMacProjects.sit.hqx $(DISTDIR)/mac
	sccs unedit $(TOP_DIR)/mac/tclMacProjects.sit.hqx
	rm -f tclMacProjects.sit.hqx
	cp -p $(TOP_DIR)/mac/*.c $(TOP_DIR)/mac/*.h $(TOP_DIR)/mac/*.r \
		$(DISTDIR)/mac
	cp -p $(TOP_DIR)/mac/porting.notes $(TOP_DIR)/mac/README $(DISTDIR)/mac
	cp -p $(TOP_DIR)/mac/*.exp $(TOP_DIR)/mac/*.pch $(DISTDIR)/mac
	cp -p $(TOP_DIR)/mac/*.doc $(DISTDIR)/mac
	cp -p $(TOP_DIR)/mac/*.html $(DISTDIR)/mac
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/mac
	mkdir $(DISTDIR)/unix/dltest
	cp -p $(UNIX_DIR)/dltest/*.c $(UNIX_DIR)/dltest/Makefile.in \
		$(DISTDIR)/unix/dltest
	cp -p $(UNIX_DIR)/dltest/configure.in $(UNIX_DIR)/dltest/configure \
		$(UNIX_DIR)/dltest/README $(DISTDIR)/unix/dltest












#
# The following target can only be used for non-patch releases.  Use
# the "allpatch" target below for patch releases.
#

alldist: dist
	rm -f /proj/tcl/dist/$(DISTNAME).tar.Z \
		/proj/tcl/dist/$(DISTNAME).tar.gz \
		/proj/tcl/dist/$(ZIPNAME)
	cd /proj/tcl/dist; tar cf $(DISTNAME).tar $(DISTNAME); \
		gzip -9 -c $(DISTNAME).tar > $(DISTNAME).tar.gz; \
		compress $(DISTNAME).tar; zip -r8 $(ZIPNAME) $(DISTNAME)

#
# The target below is similar to "alldist" except it works for patch
# releases.  It is needed because patch releases are peculiar: the
# patch designation appears in the name of the compressed file
# (e.g. tcl8.0p1.tar.gz) but the extracted source directory doesn't
# include the patch designation (e.g. tcl8.0).
#

allpatch: dist
	rm -f /proj/tcl/dist/$(DISTNAME).tar.Z \
		/proj/tcl/dist/$(DISTNAME).tar.gz \
		/proj/tcl/dist/$(ZIPNAME)
	mv /proj/tcl/dist/tcl${VERSION} /proj/tcl/dist/old
	mv /proj/tcl/dist/$(DISTNAME) /proj/tcl/dist/tcl${VERSION}
	cd /proj/tcl/dist; tar cf $(DISTNAME).tar tcl${VERSION}; \
		gzip -9 -c $(DISTNAME).tar > $(DISTNAME).tar.gz; \
		compress $(DISTNAME).tar; zip -r8 $(ZIPNAME) tcl${VERSION}


	mv /proj/tcl/dist/tcl${VERSION} /proj/tcl/dist/$(DISTNAME)







	mv /proj/tcl/dist/old /proj/tcl/dist/tcl${VERSION}



#
# Target to create a Macintosh version of the distribution.  This will
# do a normal distribution and then massage the output to prepare it
# for moving to the Mac platform.  This requires a few scripts and
# programs found only in the Tcl group's tool workspace.
#

macdist: dist


	rm -f $(DISTDIR)/mac/tclMacProjects.sit.hqx
	tclsh $(TOOL_DIR)/man2html.tcl $(DISTDIR)/tmp ../.. tcl$(VERSION)
	mv $(DISTDIR)/tmp/tcl$(VERSION) $(DISTDIR)/html
	rm -rf $(DISTDIR)/doc
	rm -rf $(DISTDIR)/tmp
	tclsh $(TOOL_DIR)/cvtEOL.tcl $(DISTDIR)

#
# Targets to build Solaris package of the distribution for the current
# architecture.  To build stream packages for both sun4 and i86pc
# architectures: 
#
#   On the sun4 machine, execute the following:
#     make distclean; ./configure
#     make DISTDIR=<distdir> package
#
#   Once the build is complete, execute the following on the i86pc
#   machine:
#     make DISTDIR=<distdir> package-quick
#
# <distdir> is the absolute path to a directory where the build should
# take place.  These steps will generate the SUNWtcl.sun4 and
# SUNWtcl.i86pc stream packages.  It is important that the packages be
# built in this fashion in order to ensure that the architecture
# independent files are exactly the same, including timestamps, in
# both packages.
#



package: dist package-config package-common package-binaries package-generate
package-quick: package-config package-binaries package-generate

#
# Configure for the current architecture in the dist directory.
#
package-config:
	mkdir -p $(DISTDIR)/unix/`arch`
	cd $(DISTDIR)/unix/`arch`; \
        ../configure --prefix=/opt/SUNWtcl/$(VERSION) \
		--exec_prefix=/opt/SUNWtcl/$(VERSION)/`arch` \
		--enable-shared
	mkdir -p $(DISTDIR)/SUNWtcl/$(VERSION)
	mkdir -p $(DISTDIR)/SUNWtcl/$(VERSION)/`arch`

#
# Build and install the architecture independent files in the dist directory.
#

package-common:
	cd $(DISTDIR)/unix/`arch`;\
	$(MAKE); \
	$(MAKE) prefix=$(DISTDIR)/SUNWtcl/$(VERSION) \
		exec_prefix=$(DISTDIR)/SUNWtcl/$(VERSION)/`arch` \
		install-libraries install-man
	mkdir -p $(DISTDIR)/SUNWtcl/$(VERSION)/bin
	sed -e "s/TCLVERSION/$(VERSION)/g" < $(UNIX_DIR)/tclsh.sh \
		> $(DISTDIR)/SUNWtcl/$(VERSION)/bin/tclsh$(VERSION)
	chmod 755 $(DISTDIR)/SUNWtcl/$(VERSION)/bin/tclsh$(VERSION)

#
# Build and install the architecture specific files in the dist directory.
#

package-binaries: 
	cd $(DISTDIR)/unix/`arch`; \
	$(MAKE); \
	$(MAKE) install-binaries prefix=$(DISTDIR)/SUNWtcl/$(VERSION) \
		exec_prefix=$(DISTDIR)/SUNWtcl/$(VERSION)/`arch`

#
# Generate a package from the installed files in the dist directory for the
# current architecture.
#

package-generate:
	pkgproto $(DISTDIR)/SUNWtcl/$(VERSION)/bin=bin \
		 $(DISTDIR)/SUNWtcl/$(VERSION)/include=include \
		 $(DISTDIR)/SUNWtcl/$(VERSION)/lib=lib \
		 $(DISTDIR)/SUNWtcl/$(VERSION)/man=man \
		 $(DISTDIR)/SUNWtcl/$(VERSION)/`arch`=`arch` \
	| tclsh $(UNIX_DIR)/mkProto.tcl \
		$(VERSION) $(UNIX_DIR) > prototype
	pkgmk -o -d . -f prototype -a `arch`
	pkgtrans -s . SUNWtcl.`arch` SUNWtcl
	rm -rf SUNWtcl

# DO NOT DELETE THIS LINE -- make depend depends on it.







>


|







|















>


|




|




>
>










|
|
>
>
>



>





<
<
|
<












>
>
>
>
>
>
>
>
>
>
>







|
|
|
|

|










|
|
|
|
|
|


>
>
|
>
>
>
>
>
>
>
|
>
>








|
>
>
|
<
<

<
















|
|




>
>










|
|

|
|








|
|

|

|
|








|
|







|
|
|
|
|



|
|


1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085


1086

1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165


1166

1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249

#
# Target to create a proper Tcl distribution from information in the
# master source directory.  DISTDIR must be defined to indicate where
# to put the distribution.
#

DISTROOT =	/tmp/dist
DISTNAME =	tcl@TCL_VERSION@@TCL_PATCH_LEVEL@
ZIPNAME =	tcl@TCL_MAJOR_VERSION@@TCL_MINOR_VERSION@@[email protected]
DISTDIR =	$(DISTROOT)/$(DISTNAME)
$(UNIX_DIR)/configure: $(UNIX_DIR)/configure.in
	autoconf $(UNIX_DIR)/configure.in > $(UNIX_DIR)/configure
dist: $(UNIX_DIR)/configure
	rm -rf $(DISTDIR)
	mkdir $(DISTDIR)
	mkdir $(DISTDIR)/unix
	cp -p $(UNIX_DIR)/*.c $(UNIX_DIR)/*.h $(DISTDIR)/unix
	rm -f $(DISTDIR)/unix/bp.c
	cp $(UNIX_DIR)/Makefile.in $(DISTDIR)/unix
	chmod 664 $(DISTDIR)/unix/Makefile.in
	cp $(UNIX_DIR)/configure $(UNIX_DIR)/configure.in \
		$(UNIX_DIR)/tclConfig.sh.in $(UNIX_DIR)/install-sh \
		$(UNIX_DIR)/porting.notes $(UNIX_DIR)/porting.old \
		$(UNIX_DIR)/README $(UNIX_DIR)/ldAix \
		$(DISTDIR)/unix
	chmod 775 $(DISTDIR)/unix/configure $(DISTDIR)/unix/configure.in
	chmod 775 $(DISTDIR)/unix/ldAix
	chmod +x $(DISTDIR)/unix/install-sh
	tclsh $(UNIX_DIR)/mkLinks.tcl \
		$(UNIX_DIR)/../doc/*.[13n] > $(DISTDIR)/unix/mkLinks
	chmod +x $(DISTDIR)/unix/mkLinks
	mkdir $(DISTDIR)/generic
	cp -p $(GENERIC_DIR)/*.c $(GENERIC_DIR)/*.h $(DISTDIR)/generic
	cp -p $(GENERIC_DIR)/*.decls $(DISTDIR)/generic
	cp -p $(GENERIC_DIR)/README $(DISTDIR)/generic
	cp -p $(GENERIC_DIR)/tclGetDate.y $(DISTDIR)/generic
	cp -p $(TOP_DIR)/changes $(TOP_DIR)/README* $(TOP_DIR)/license.terms \
		$(DISTDIR)
	mkdir $(DISTDIR)/library
	cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/library/*.tcl \
		$(TOP_DIR)/library/tclIndex $(DISTDIR)/library
	for i in http2.0 http1.0 opt0.4 msgcat1.0; \
	    do \
		mkdir $(DISTDIR)/library/$$i ;\
		cp -p $(TOP_DIR)/library/$$i/*.tcl $(DISTDIR)/library/$$i; \
	    done;
	mkdir $(DISTDIR)/library/encoding
	cp -p $(TOP_DIR)/library/encoding/*.enc $(DISTDIR)/library/encoding
	mkdir $(DISTDIR)/doc
	cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/doc/*.[13n] \
		$(TOP_DIR)/doc/man.macros $(DISTDIR)/doc
	mkdir $(DISTDIR)/compat
	cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/compat/*.c \
		$(TOP_DIR)/compat/*.h $(TOP_DIR)/compat/README \
		$(DISTDIR)/compat
	mkdir $(DISTDIR)/tests
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/tests
	cp -p $(TOP_DIR)/tests/*.test $(TOP_DIR)/tests/README \
		$(TOP_DIR)/tests/all.tcl $(TOP_DIR)/tests/*.tcl \
		$(TOP_DIR)/tests/defs.tcl $(DISTDIR)/tests
	mkdir $(DISTDIR)/tests/pkg
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/tests/pkg
	cp -p $(TOP_DIR)/tests/pkg/*.tcl $(DISTDIR)/tests/pkg
	mkdir $(DISTDIR)/win
	cp -p $(TOP_DIR)/win/*.c $(TOP_DIR)/win/*.h $(TOP_DIR)/win/*.rc \
		$(DISTDIR)/win
	cp -p $(TOP_DIR)/win/*.bat $(DISTDIR)/win
	cp -p $(TOP_DIR)/win/makefile.* $(DISTDIR)/win
	cp -p $(TOP_DIR)/win/README $(DISTDIR)/win
	cp -p $(TOP_DIR)/win/pkgIndex.tcl $(DISTDIR)/win
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/win
	mkdir $(DISTDIR)/mac


	cp -p $(TOP_DIR)/mac/tclMacProjects.sea.hqx $(DISTDIR)/mac

	cp -p $(TOP_DIR)/mac/*.c $(TOP_DIR)/mac/*.h $(TOP_DIR)/mac/*.r \
		$(DISTDIR)/mac
	cp -p $(TOP_DIR)/mac/porting.notes $(TOP_DIR)/mac/README $(DISTDIR)/mac
	cp -p $(TOP_DIR)/mac/*.exp $(TOP_DIR)/mac/*.pch $(DISTDIR)/mac
	cp -p $(TOP_DIR)/mac/*.doc $(DISTDIR)/mac
	cp -p $(TOP_DIR)/mac/*.html $(DISTDIR)/mac
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/mac
	mkdir $(DISTDIR)/unix/dltest
	cp -p $(UNIX_DIR)/dltest/*.c $(UNIX_DIR)/dltest/Makefile.in \
		$(DISTDIR)/unix/dltest
	cp -p $(UNIX_DIR)/dltest/configure.in $(UNIX_DIR)/dltest/configure \
		$(UNIX_DIR)/dltest/README $(DISTDIR)/unix/dltest
	mkdir $(DISTDIR)/tools
	cp -p $(TOP_DIR)/tools/Makefile.in \
	    $(TOP_DIR)/tools/README \
	    $(TOP_DIR)/tools/configure \
	    $(TOP_DIR)/tools/configure.in \
	    $(TOP_DIR)/tools/*.tcl \
	    $(TOP_DIR)/tools/man2tcl.c \
	    $(TOP_DIR)/tools/tcl.wse.in \
	    $(TOP_DIR)/tools/*.bmp \
	    $(TOP_DIR)/tools/tcl.hpj.in \
		$(DISTDIR)/tools

#
# The following target can only be used for non-patch releases.  Use
# the "allpatch" target below for patch releases.
#

alldist: dist
	rm -f $(DISTROOT)/$(DISTNAME).tar.Z \
		$(DISTROOT)/$(DISTNAME).tar.gz \
		$(DISTROOT)/$(ZIPNAME)
	cd $(DISTROOT); tar cf $(DISTNAME).tar $(DISTNAME); \
		gzip -9 -c $(DISTNAME).tar > $(DISTNAME).tar.gz; \
		compress $(DISTNAME).tar; zip -qr8 $(ZIPNAME) $(DISTNAME)

#
# The target below is similar to "alldist" except it works for patch
# releases.  It is needed because patch releases are peculiar: the
# patch designation appears in the name of the compressed file
# (e.g. tcl8.0p1.tar.gz) but the extracted source directory doesn't
# include the patch designation (e.g. tcl8.0).
#

allpatch: dist
	rm -f $(DISTROOT)/$(DISTNAME).tar.Z \
		$(DISTROOT)/$(DISTNAME).tar.gz \
		$(DISTROOT)/$(ZIPNAME)
	mv $(DISTROOT)/tcl${VERSION} $(DISTROOT)/old
	mv $(DISTROOT)/$(DISTNAME) $(DISTROOT)/tcl${VERSION}
	cd $(DISTROOT); tar cf $(DISTNAME).tar tcl${VERSION}; \
		gzip -9 -c $(DISTNAME).tar > $(DISTNAME).tar.gz; \
		compress $(DISTNAME).tar; zip -r8 $(ZIPNAME) tcl${VERSION}
	mv $(DISTROOT)/tcl${VERSION} $(DISTROOT)/$(DISTNAME)
	mv $(DISTROOT)/old $(DISTROOT)/tcl${VERSION}

#
# This target creates the HTML folder for Tcl & Tk and places it
# in DISTDIR/html.  It uses the tcl8.1-tk8.1-man-html.tcl tool from
# the Tcl group's tool workspace.  It depends on the Tcl & Tk being
# in directories called tcl8.1 & tk8.1 up two directories from the
# TOOL_DIR.
#

html: 
	tclsh $(TOOL_DIR)/tcl8.1-tk8.1-man-html.tcl --htmldir=$(DISTDIR)/html

#
# Target to create a Macintosh version of the distribution.  This will
# do a normal distribution and then massage the output to prepare it
# for moving to the Mac platform.  This requires a few scripts and
# programs found only in the Tcl group's tool workspace.
#

macdist: dist machtml

machtml:
	rm -f $(DISTDIR)/mac/tclMacProjects.sea.hqx


	rm -rf $(DISTDIR)/doc

	tclsh $(TOOL_DIR)/cvtEOL.tcl $(DISTDIR)

#
# Targets to build Solaris package of the distribution for the current
# architecture.  To build stream packages for both sun4 and i86pc
# architectures: 
#
#   On the sun4 machine, execute the following:
#     make distclean; ./configure
#     make DISTDIR=<distdir> package
#
#   Once the build is complete, execute the following on the i86pc
#   machine:
#     make DISTDIR=<distdir> package-quick
#
# <distdir> is the absolute path to a directory where the build should
# take place.  These steps will generate the $(PACKAGE).sun4 and
# $(PACKAGE).i86pc stream packages.  It is important that the packages be
# built in this fashion in order to ensure that the architecture
# independent files are exactly the same, including timestamps, in
# both packages.
#

PACKAGE=SCRPtcl

package: dist package-config package-common package-binaries package-generate
package-quick: package-config package-binaries package-generate

#
# Configure for the current architecture in the dist directory.
#
package-config:
	mkdir -p $(DISTDIR)/unix/`arch`
	cd $(DISTDIR)/unix/`arch`; \
        ../configure --prefix=/opt/$(PACKAGE)/$(VERSION) \
		--exec_prefix=/opt/$(PACKAGE)/$(VERSION)/`arch` \
		--enable-shared
	mkdir -p $(DISTDIR)/$(PACKAGE)/$(VERSION)
	mkdir -p $(DISTDIR)/$(PACKAGE)/$(VERSION)/`arch`

#
# Build and install the architecture independent files in the dist directory.
#

package-common:
	cd $(DISTDIR)/unix/`arch`;\
	$(MAKE); \
	$(MAKE) prefix=$(DISTDIR)/$(PACKAGE)/$(VERSION) \
		exec_prefix=$(DISTDIR)/$(PACKAGE)/$(VERSION)/`arch` \
		install-libraries install-man
	mkdir -p $(DISTDIR)/$(PACKAGE)/$(VERSION)/bin
	sed -e "s/TCLVERSION/$(VERSION)/g" < $(UNIX_DIR)/tclsh.sh \
		> $(DISTDIR)/$(PACKAGE)/$(VERSION)/bin/tclsh$(VERSION)
	chmod 755 $(DISTDIR)/$(PACKAGE)/$(VERSION)/bin/tclsh$(VERSION)

#
# Build and install the architecture specific files in the dist directory.
#

package-binaries: 
	cd $(DISTDIR)/unix/`arch`; \
	$(MAKE); \
	$(MAKE) install-binaries prefix=$(DISTDIR)/$(PACKAGE)/$(VERSION) \
		exec_prefix=$(DISTDIR)/$(PACKAGE)/$(VERSION)/`arch`

#
# Generate a package from the installed files in the dist directory for the
# current architecture.
#

package-generate:
	pkgproto $(DISTDIR)/$(PACKAGE)/$(VERSION)/bin=bin \
		 $(DISTDIR)/$(PACKAGE)/$(VERSION)/include=include \
		 $(DISTDIR)/$(PACKAGE)/$(VERSION)/lib=lib \
		 $(DISTDIR)/$(PACKAGE)/$(VERSION)/man=man \
		 $(DISTDIR)/$(PACKAGE)/$(VERSION)/`arch`=`arch` \
	| tclsh $(UNIX_DIR)/mkProto.tcl \
		$(VERSION) $(UNIX_DIR) > prototype
	pkgmk -o -d . -f prototype -a `arch`
	pkgtrans -s . $(PACKAGE).`arch` $(PACKAGE)
	rm -rf $(PACKAGE)

# DO NOT DELETE THIS LINE -- make depend depends on it.

Changes to unix/README.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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.

SCCS: @(#) README 1.15 96/12/19 14:02:23

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







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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.1.2.3 1998/12/14 21:04:38 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
33
34
35
36
37
38
39


40
41
42
43
44
45
46
    switches in addition to the standard ones:
	--enable-gcc		If this switch is set, Tcl will configure
				itself to use gcc if it is available on your
				system.  Note:  it is not safe to modify the
				Makefile to use gcc after configure is run;
				if you do this, then information related to
				dynamic linking will be incorrect.


	--disable-load		If this switch is specified then Tcl will
				configure itself not to allow dynamic loading,
				even if your system appears to support it.
				Normally you can leave this switch out and
				Tcl will build itself for dynamic loading
				if your system supports it.
	--enable-shared		If this switch is specified, Tcl will compile







>
>







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    switches in addition to the standard ones:
	--enable-gcc		If this switch is set, Tcl will configure
				itself to use gcc if it is available on your
				system.  Note:  it is not safe to modify the
				Makefile to use gcc after configure is run;
				if you do this, then information related to
				dynamic linking will be incorrect.
	--enable-threads	If this switch is set, Tcl will compile
				itself with multithreading support.
	--disable-load		If this switch is specified then Tcl will
				configure itself not to allow dynamic loading,
				even if your system appears to support it.
				Normally you can leave this switch out and
				Tcl will build itself for dynamic loading
				if your system supports it.
	--enable-shared		If this switch is specified, Tcl will compile
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
    "exec_prefix" variables in the Makefile.

(g) At this point you can play with Tcl by invoking the "tclsh"
    program and typing Tcl commands.  However, if you haven't installed
    Tcl then you'll first need to set your TCL_LIBRARY variable to
    hold the full path name of the "library" subdirectory.  Note that
    the installed versions of tclsh, libtcl.a, and libtcl.so have a
    version number in their names, such as "tclsh8.0" or "libtcl8.0.so";
    to use the installed versions, either specify the version number
    or create a symbolic link (e.g. from "tclsh" to "tclsh8.0").

If you have trouble compiling Tcl, read through the file" porting.notes".
It contains information that people have provided about changes they had
to make to compile Tcl in various environments.  Or, check out the
following Web URL:
    http://www.sunlabs.com/cgi-bin/tcl/info.8.0
This is an on-line database of porting information.  We make no guarantees
that this information is accurate, complete, or up-to-date, but you may
find it useful.  If you get Tcl running on a new configuration, we would
be happy to receive new information to add to "porting.notes".  You can
also make a new entry into the on-line Web database.  We're also interested
in hearing how to change the configuration setup so that Tcl compiles out
of the box on more platforms.

Test suite
----------

There is a relatively complete test suite for all of the Tcl core in
the subdirectory "tests".  To use it just type "make test" in this
directory.  You should then see a printout of the test files processed.







|

|

|
<
<
<
|
|
|
|
|
|
|
|







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
    "exec_prefix" variables in the Makefile.

(g) At this point you can play with Tcl by invoking the "tclsh"
    program and typing Tcl commands.  However, if you haven't installed
    Tcl then you'll first need to set your TCL_LIBRARY variable to
    hold the full path name of the "library" subdirectory.  Note that
    the installed versions of tclsh, libtcl.a, and libtcl.so have a
    version number in their names, such as "tclsh8.1" or "libtcl8.1.so";
    to use the installed versions, either specify the version number
    or create a symbolic link (e.g. from "tclsh" to "tclsh8.1").

If you have trouble compiling Tcl, check out the following Web URL:



    http://www.scriptics.com/software/install.html#Database
This is an on-line database of porting information.  We make no
guarantees that this information is accurate, complete, or up-to-date,
but you may find it useful.  If you get Tcl running on a new
configuration, we would be happy to receive new information to add to
the database.  We're also interested in hearing how to change the
configuration setup so that Tcl compiles out of the box on more
platforms.

Test suite
----------

There is a relatively complete test suite for all of the Tcl core in
the subdirectory "tests".  To use it just type "make test" in this
directory.  You should then see a printout of the test files processed.

Changes to unix/configure.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
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)
# SCCS: @(#) configure.in 1.144 97/11/20 12:39:44

TCL_VERSION=8.0
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=0
TCL_PATCH_LEVEL="p2"
VERSION=${TCL_VERSION}

if test "${prefix}" = "NONE"; then
    prefix=/usr/local
fi
if test "${exec_prefix}" = "NONE"; then
    exec_prefix=$prefix
fi
TCL_SRC_DIR=`cd $srcdir/..; pwd`

AC_PROG_RANLIB
AC_ARG_ENABLE(gcc, [  --enable-gcc            allow use of gcc if available],
    [tcl_ok=$enableval], [tcl_ok=no])
if test "$tcl_ok" = "yes"; then
    AC_PROG_CC
else
    CC=${CC-cc}
AC_SUBST(CC)
fi
AC_C_CROSS

























































#--------------------------------------------------------------------
#	Supply substitutes for missing POSIX library procedures, or
#	set flags so Tcl uses alternate procedures.
#--------------------------------------------------------------------

# Check if Posix compliant getcwd exists, if not we'll use getwd.
AC_CHECK_FUNCS(getcwd, , AC_DEFINE(USEGETWD))
# Nb: if getcwd uses popen and pwd(1) (like SunOS 4) we should really
# define USEGETWD even if the posix getcwd exists. Add a test ?

AC_REPLACE_FUNCS(opendir strstr)

AC_REPLACE_FUNCS(strtol tmpnam waitpid)
AC_CHECK_FUNC(strerror, , AC_DEFINE(NO_STRERROR))
AC_CHECK_FUNC(getwd, , AC_DEFINE(NO_GETWD))
AC_CHECK_FUNC(wait3, , AC_DEFINE(NO_WAIT3))
AC_CHECK_FUNC(uname, , AC_DEFINE(NO_UNAME))


#--------------------------------------------------------------------
#	On a few very rare systems, all of the libm.a stuff is
#	already in libc.a.  Set compiler flags accordingly.
#	Also, Linux requires the "ieee" library for math to work
#	right (and it must appear before "-lm").
#--------------------------------------------------------------------




|

|

|
|




















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


















>







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
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.1.2.16 1999/04/15 00:35:21 rjohnson Exp $

TCL_VERSION=8.1
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=1
TCL_PATCH_LEVEL=b3
VERSION=${TCL_VERSION}

if test "${prefix}" = "NONE"; then
    prefix=/usr/local
fi
if test "${exec_prefix}" = "NONE"; then
    exec_prefix=$prefix
fi
TCL_SRC_DIR=`cd $srcdir/..; pwd`

AC_PROG_RANLIB
AC_ARG_ENABLE(gcc, [  --enable-gcc            allow use of gcc if available],
    [tcl_ok=$enableval], [tcl_ok=no])
if test "$tcl_ok" = "yes"; then
    AC_PROG_CC
else
    CC=${CC-cc}
AC_SUBST(CC)
fi
AC_C_CROSS

# Threads support
AC_ARG_ENABLE(threads,[  --enable-threads        enable Threads support],,enableval="no")

if test "$enableval" = "yes"; then
  AC_MSG_RESULT(Will compile with Threads support)
  AC_DEFINE(TCL_THREADS)
  AC_DEFINE(_REENTRANT)

  AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
  if test "$tcl_ok" = "yes"; then
     # The space is needed
     THREADS_LIBS=" -lpthread"
  else
     AC_MSG_WARN("Don t know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile...")
  fi
else
  AC_MSG_RESULT(Will compile without Threads support (normal))
fi

# set the warning flags depending on whether or not we are using gcc
if test "${GCC}" = "yes" ; then
    CFLAGS_WARNING="-Wall -Wconversion"
else
    CFLAGS_WARNING=""
fi

#-----------------------------
# 64-bit support
#-----------------------------

AC_ARG_ENABLE(64bit,[  --enable-64bit          enable 64bit support],,enableval="no")

if test "$enableval" = "yes"; then
  AC_MSG_RESULT(Will compile with 64bit support)
  do64bit=yes
else
  do64bit=no
fi

#------------------------------------------------------------------------------
# If we're using GCC, see if the compiler understands -pipe.  If so, use it.
# It makes compiling go faster.  (This is only a performance feature.)
#------------------------------------------------------------------------------

if test -z "$no_pipe"; then
if test -n "$GCC"; then
  AC_MSG_CHECKING([if the compiler understands -pipe])
  OLDCC="$CC"  
  CC="$CC -pipe"
  AC_TRY_COMPILE(,,
    AC_MSG_RESULT(yes),
    CC="$OLDCC"
    AC_MSG_RESULT(no))
fi  
fi

#--------------------------------------------------------------------
#	Supply substitutes for missing POSIX library procedures, or
#	set flags so Tcl uses alternate procedures.
#--------------------------------------------------------------------

# Check if Posix compliant getcwd exists, if not we'll use getwd.
AC_CHECK_FUNCS(getcwd, , AC_DEFINE(USEGETWD))
# Nb: if getcwd uses popen and pwd(1) (like SunOS 4) we should really
# define USEGETWD even if the posix getcwd exists. Add a test ?

AC_REPLACE_FUNCS(opendir strstr)

AC_REPLACE_FUNCS(strtol tmpnam waitpid)
AC_CHECK_FUNC(strerror, , AC_DEFINE(NO_STRERROR))
AC_CHECK_FUNC(getwd, , AC_DEFINE(NO_GETWD))
AC_CHECK_FUNC(wait3, , AC_DEFINE(NO_WAIT3))
AC_CHECK_FUNC(uname, , AC_DEFINE(NO_UNAME))
AC_CHECK_FUNC(realpath, , AC_DEFINE(NO_REALPATH))

#--------------------------------------------------------------------
#	On a few very rare systems, all of the libm.a stuff is
#	already in libc.a.  Set compiler flags accordingly.
#	Also, Linux requires the "ieee" library for math to work
#	right (and it must appear before "-lm").
#--------------------------------------------------------------------
116
117
118
119
120
121
122


123
124
125
126
127


128
129
130
131
132
133
134
135
AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
if test $tcl_ok = 0; then
    AC_DEFINE(NO_STDLIB_H)
fi
AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)


if test $tcl_ok = 0; then
    AC_DEFINE(NO_STRING_H)
fi
AC_CHECK_HEADER(sys/wait.h, , AC_DEFINE(NO_SYS_WAIT_H))
AC_CHECK_HEADER(dlfcn.h, , AC_DEFINE(NO_DLFCN_H))


AC_HAVE_HEADERS(unistd.h)

#---------------------------------------------------------------------------
#	Determine which interface to use to talk to the serial port.
#	Note that #include lines must begin in leftmost column for
#	some compilers to recognize them as preprocessor directives.
#---------------------------------------------------------------------------








>
>





>
>
|







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
if test $tcl_ok = 0; then
    AC_DEFINE(NO_STDLIB_H)
fi
AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
# See also memmove check below for a place where NO_STRING_H can be
# set and why.
if test $tcl_ok = 0; then
    AC_DEFINE(NO_STRING_H)
fi
AC_CHECK_HEADER(sys/wait.h, , AC_DEFINE(NO_SYS_WAIT_H))
AC_CHECK_HEADER(dlfcn.h, , AC_DEFINE(NO_DLFCN_H))

# OS/390 lacks sys/param.h (and doesn't need it, by chance).
AC_HAVE_HEADERS(unistd.h sys/param.h)

#---------------------------------------------------------------------------
#	Determine which interface to use to talk to the serial port.
#	Note that #include lines must begin in leftmost column for
#	some compilers to recognize them as preprocessor directives.
#---------------------------------------------------------------------------

266
267
268
269
270
271
272
273
274
275














276
277
278
279
280
281
282
#
if test $libbsd = yes; then
    AC_DEFINE(USE_DELTA_FOR_TZ)
fi

#--------------------------------------------------------------------
#	Some systems (e.g., IRIX 4.0.5) lack the st_blksize field
#	in struct stat.
#--------------------------------------------------------------------
AC_STRUCT_ST_BLKSIZE















#--------------------------------------------------------------------
#	On some systems strstr is broken: it returns a pointer even
#	even if the original string is empty.
#--------------------------------------------------------------------

AC_MSG_CHECKING([proper strstr implementation])







|


>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
#
if test $libbsd = yes; then
    AC_DEFINE(USE_DELTA_FOR_TZ)
fi

#--------------------------------------------------------------------
#	Some systems (e.g., IRIX 4.0.5) lack the st_blksize field
#	in struct stat.  But we might be able to use fstatfs instead.
#--------------------------------------------------------------------
AC_STRUCT_ST_BLKSIZE
AC_CHECK_FUNC(fstatfs, , AC_DEFINE(NO_FSTATFS))

#--------------------------------------------------------------------
#       Some system have no memcmp or it does not work with 8 bit
#       data, this checks it and add memcmp.o to LIBOBJS if needed
#--------------------------------------------------------------------
AC_FUNC_MEMCMP

#--------------------------------------------------------------------
#       Some system like SunOS 4 and other BSD like systems
#       have no memmove (we assume they have bcopy instead).
#       {The replacement define is in compat/string.h}
#--------------------------------------------------------------------
AC_CHECK_FUNC(memmove, , AC_DEFINE(NO_MEMMOVE) AC_DEFINE(NO_STRING_H))

#--------------------------------------------------------------------
#	On some systems strstr is broken: it returns a pointer even
#	even if the original string is empty.
#--------------------------------------------------------------------

AC_MSG_CHECKING([proper strstr implementation])
433
434
435
436
437
438
439

440
441
442
443
444
445
446
#	Check to see whether the system provides a vfork kernel call.
#	If not, then use fork instead.  Also, check for a problem with
#	vforks and signals that can cause core dumps if a vforked child
#	resets a signal handler.  If the problem exists, then use fork
#	instead of vfork.
#--------------------------------------------------------------------


AC_CHECK_FUNC(vfork, tcl_ok=1, tcl_ok=0)
if test "$tcl_ok" = 1; then
    AC_MSG_CHECKING([vfork/signal bug]);
    AC_TRY_RUN([
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>







>







508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
#	Check to see whether the system provides a vfork kernel call.
#	If not, then use fork instead.  Also, check for a problem with
#	vforks and signals that can cause core dumps if a vforked child
#	resets a signal handler.  If the problem exists, then use fork
#	instead of vfork.
#--------------------------------------------------------------------

AC_TYPE_SIGNAL()
AC_CHECK_FUNC(vfork, tcl_ok=1, tcl_ok=0)
if test "$tcl_ok" = 1; then
    AC_MSG_CHECKING([vfork/signal bug]);
    AC_TRY_RUN([
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
562
563
564
565
566
567
568




569
570
571
572
573
574
575
fi
if test "$tcl_checkBoth" = 1; then
    tk_oldLibs=$LIBS
    LIBS="$LIBS -lsocket -lnsl"
    AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
fi
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"]))





#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
#	dynamic loading and shared libraries:
#
#	DL_OBJS -	Name of the object file that implements dynamic
#			loading for Tcl on this system.







>
>
>
>







638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
fi
if test "$tcl_checkBoth" = 1; then
    tk_oldLibs=$LIBS
    LIBS="$LIBS -lsocket -lnsl"
    AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
fi
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"]))

# Add the threads support libraries

LIBS="$LIBS$THREADS_LIBS"

#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
#	dynamic loading and shared libraries:
#
#	DL_OBJS -	Name of the object file that implements dynamic
#			loading for Tcl on this system.
612
613
614
615
616
617
618











619
620
621
622
623
624
625
#			by platforms that need non-standard library names.
#			Examples:  ${VERSION}.so.1.1 on NetBSD, since it needs
#			to have a version after the .so, and ${VERSION}.a
#			on AIX, since the Tcl shared library needs to have
#			a .a extension whereas shared objects for loadable
#			extensions have a .so extension.  Defaults to
#			${VERSION}${SHLIB_SUFFIX}.











#--------------------------------------------------------------------

# Step 1: set the variable "system" to hold the name and version number
# for the system.  This can usually be done via the "uname" command, but
# there are a few systems, like Next, where this doesn't work.

AC_MSG_CHECKING([system version (for dynamic loading)])







>
>
>
>
>
>
>
>
>
>
>







692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
#			by platforms that need non-standard library names.
#			Examples:  ${VERSION}.so.1.1 on NetBSD, since it needs
#			to have a version after the .so, and ${VERSION}.a
#			on AIX, since the Tcl shared library needs to have
#			a .a extension whereas shared objects for loadable
#			extensions have a .so extension.  Defaults to
#			${VERSION}${SHLIB_SUFFIX}.
#	TCL_NEEDS_EXP_FILE -
#			1 means that an export file is needed to link to a
#			shared library.
#
#	TCL_EXP_FILE -  The name of the installed export / import file which 
#			should be used to link to the Tcl shared library.
#			Empty if Tcl is unshared.
#	TCL_BUILD_EXP_FILE -
#			The name of the built export / import file which
#			should be used to link to the Tcl shared library.
#			Empty if Tcl is unshared.
#--------------------------------------------------------------------

# Step 1: set the variable "system" to hold the name and version number
# for the system.  This can usually be done via the "uname" command, but
# there are a few systems, like Next, where this doesn't work.

AC_MSG_CHECKING([system version (for dynamic loading)])
647
648
649
650
651
652
653

654

655
656


657





658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679

680
681
682
683
684
685
686
687
688
689
690
691










692
693
694
695
696
697
698
699
700
701
702

703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732



733










734

735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
# Step 2: check for existence of -ldl library.  This is needed because
# Linux can use either -ldl or -ldld for dynamic loading.

AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)

# Step 3: set configuration options based on system name and version.


fullSrcDir=`cd $srcdir; pwd`

TCL_SHARED_LIB_SUFFIX=""
TCL_UNSHARED_LIB_SUFFIX=""


TCL_LIB_VERSIONS_OK=ok





case $system in
    AIX-4.[[2-9]])
	SHLIB_CFLAGS=""
	SHLIB_LD="$fullSrcDir/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
	SHLIB_LD_LIBS='${LIBS}'
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS=""
	LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	AIX=yes
	TCL_SHARED_LIB_SUFFIX='${VERSION}.a'
	;;
    AIX-*)
	SHLIB_CFLAGS=""
	SHLIB_LD="$fullSrcDir/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
	SHLIB_LD_LIBS='${LIBS}'
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o tclLoadAix.o"
	DL_LIBS="-lld"
	LD_FLAGS=""
	LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'

	TCL_SHARED_LIB_SUFFIX='${VERSION}.a'
	;;
    BSD/OS-2.1*|BSD/OS-3*)
	SHLIB_CFLAGS=""
	SHLIB_LD="shlicc -r"
	SHLIB_LD_LIBS='${LIBS}'
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS=""
	LD_SEARCH_FLAGS=""
	;;










    dgux*)
	SHLIB_CFLAGS="-K PIC"
	SHLIB_LD="cc -G"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS=""
	LD_SEARCH_FLAGS=""
	;;
    HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)

	AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
	if test "$tcl_ok" = yes; then
	    SHLIB_CFLAGS="+z"
	    SHLIB_LD="ld -b"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".sl"
	    DL_OBJS="tclLoadShl.o"
	    DL_LIBS="-ldld"
	    LD_FLAGS="-Wl,-E"
	    LD_SEARCH_FLAGS='-Wl,+b,${LIB_RUNTIME_DIR}:.'
	fi
	;;
    IRIX-4.*)
	SHLIB_CFLAGS="-G 0"
	SHLIB_SUFFIX=".a"
	SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
	SHLIB_LD_LIBS='${LIBS}'
	DL_OBJS="tclLoadAout.o"
	DL_LIBS=""
	LD_FLAGS="-Wl,-D,08000000"
	LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	TCL_SHARED_LIB_SUFFIX='${VERSION}.a'
	;;
    IRIX-5.*|IRIX-6.*)
	SHLIB_CFLAGS=""
	SHLIB_LD="ld -shared -rdata_shared"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS=""



	LD_FLAGS=""










	LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'

	;;
    IRIX64-6.*)
	SHLIB_CFLAGS=""
	SHLIB_LD="ld -32 -shared -rdata_shared -rpath /usr/local/lib"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS=""
	LD_FLAGS=""
	LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	;;
    Linux*)
	SHLIB_CFLAGS="-fPIC"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	if test "$have_dl" = yes; then
	    SHLIB_LD="${CC} -shared"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LD_FLAGS="-rdynamic"
	    LD_SEARCH_FLAGS=""
	else
	    AC_CHECK_HEADER(dld.h, [
		SHLIB_LD="ld -shared"
		DL_OBJS="tclLoadDld.o"
		DL_LIBS="-ldld"
		LD_FLAGS=""
		LD_SEARCH_FLAGS=""])







>

>
|

>
>

>
>
>
>
>










|
|



|






>
|











>
>
>
>
>
>
>
>
>
>










|
>





<



|











|

|

|




>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>



|
|








|






|







738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819

820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
# Step 2: check for existence of -ldl library.  This is needed because
# Linux can use either -ldl or -ldld for dynamic loading.

AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)

# Step 3: set configuration options based on system name and version.

do64bit_ok=no
fullSrcDir=`cd $srcdir; pwd`
EXTRA_CFLAGS=""
TCL_EXPORT_FILE_SUFFIX=""
TCL_UNSHARED_LIB_SUFFIX=""
TCL_TRIM_DOTS='`echo ${VERSION} | tr -d .`'
ECHO_VERSION='`echo ${VERSION}`'
TCL_LIB_VERSIONS_OK=ok
CFLAGS_DEBUG=-g
CFLAGS_OPTIMIZE=-O
TCL_NEEDS_EXP_FILE=0
TCL_BUILD_EXP_FILE=""
TCL_EXP_FILE=""
case $system in
    AIX-4.[[2-9]])
	SHLIB_CFLAGS=""
	SHLIB_LD="$fullSrcDir/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
	SHLIB_LD_LIBS='${LIBS}'
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS=""
	LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	TCL_NEEDS_EXP_FILE=1
	TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.exp'
	;;
    AIX-*)
	SHLIB_CFLAGS=""
	SHLIB_LD="$fullSrcDir/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512"
	SHLIB_LD_LIBS='${LIBS}'
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o tclLoadAix.o"
	DL_LIBS="-lld"
	LD_FLAGS=""
	LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	TCL_NEEDS_EXP_FILE=1
	TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.exp'
	;;
    BSD/OS-2.1*|BSD/OS-3*)
	SHLIB_CFLAGS=""
	SHLIB_LD="shlicc -r"
	SHLIB_LD_LIBS='${LIBS}'
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS=""
	LD_SEARCH_FLAGS=""
	;;
    BSD/OS-4.*)
	SHLIB_CFLAGS="-export-dynamic -fPIC"
	SHLIB_LD="cc -shared"
	SHLIB_LD_LIBS='${LIBS}'
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS="-export-dynamic"
	LD_SEARCH_FLAGS=""
	;;
    dgux*)
	SHLIB_CFLAGS="-K PIC"
	SHLIB_LD="cc -G"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS=""
	LD_SEARCH_FLAGS=""
	;;
    HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*|HP-UX-*.11.*)
	SHLIB_SUFFIX=".sl"
	AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
	if test "$tcl_ok" = yes; then
	    SHLIB_CFLAGS="+z"
	    SHLIB_LD="ld -b"
	    SHLIB_LD_LIBS=""

	    DL_OBJS="tclLoadShl.o"
	    DL_LIBS="-ldld"
	    LD_FLAGS="-Wl,-E"
	    LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
	fi
	;;
    IRIX-4.*)
	SHLIB_CFLAGS="-G 0"
	SHLIB_SUFFIX=".a"
	SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
	SHLIB_LD_LIBS='${LIBS}'
	DL_OBJS="tclLoadAout.o"
	DL_LIBS=""
	LD_FLAGS="-Wl,-D,08000000"
	LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	TCL_SHARED_LIB_SUFFIX='${VERSION}\$\{DBGX\}.a'
	;;
    IRIX-5.*|IRIX-6.*|IRIX64-6.5*)
	SHLIB_CFLAGS=""
	SHLIB_LD="ld -n32 -shared -rdata_shared"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS=""
	LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then
	    EXTRA_CFLAGS="-mabi=n32"
	    LD_FLAGS="-mabi=n32"
	else
	    case $system in
		IRIX-6.3)
		    # Use to build 6.2 compatible binaries on 6.3.
		    EXTRA_CFLAGS="-n32 -D_OLD_TERMIOS"
		    ;;
		*)
		    EXTRA_CFLAGS="-n32"
		    ;;
	    esac
	    LD_FLAGS="-n32"
	fi
	;;
    IRIX64-6.*)
	SHLIB_CFLAGS=""
	SHLIB_LD="ld -32 -shared -rdata_shared"
	SHLIB_LD_LIBS='${LIBS}'
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS=""
	LD_FLAGS=""
	LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	;;
    Linux*)
	SHLIB_CFLAGS="-fPIC"
	SHLIB_LD_LIBS="${LIBS}"
	SHLIB_SUFFIX=".so"
	if test "$have_dl" = yes; then
	    SHLIB_LD="${CC} -shared"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LD_FLAGS="-rdynamic"
	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	else
	    AC_CHECK_HEADER(dld.h, [
		SHLIB_LD="ld -shared"
		DL_OBJS="tclLoadDld.o"
		DL_LIBS="-ldld"
		LD_FLAGS=""
		LD_SEARCH_FLAGS=""])
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LD_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    TCL_SHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.so.1.0'
	], [
	    SHLIB_CFLAGS=""
	    SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".a"
	    DL_OBJS="tclLoadAout.o"
	    DL_LIBS=""
	    LD_FLAGS=""
	    LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	    TCL_SHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.a'
	])

	# FreeBSD doesn't handle version numbers with dots.

	TCL_UNSHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.a'
	TCL_LIB_VERSIONS_OK=nodots
	;;
    NEXTSTEP-*)
	SHLIB_CFLAGS=""
	SHLIB_LD="cc -nostdlib -r"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"







|









|




|







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
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LD_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    TCL_SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1.0'
	], [
	    SHLIB_CFLAGS=""
	    SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".a"
	    DL_OBJS="tclLoadAout.o"
	    DL_LIBS=""
	    LD_FLAGS=""
	    LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	    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"
899
900
901
902
903
904
905
906
907
908
909

910
911
912
913
914
915
916
917
918
919
920
921

































922

923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
	LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'

	# SunOS can't handle version numbers with dots in them in library
	# specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
	# requires an extra version number at the end of .so file names.
	# So, the library has to have a name like libtcl75.so.1.0

	TCL_SHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.so.1.0'
	TCL_UNSHARED_LIB_SUFFIX='`echo ${VERSION} | tr -d .`.a'
	TCL_LIB_VERSIONS_OK=nodots
	;;

    SunOS-5*)
	SHLIB_CFLAGS="-KPIC"
	SHLIB_LD="/usr/ccs/bin/ld -G -z text"

	# Note: need the LIBS below, otherwise Tk won't find Tcl's
	# symbols when dynamically loaded into tclsh.

	SHLIB_LD_LIBS='${LIBS}'
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS=""

































	LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'

	;;
    ULTRIX-4.*)
	SHLIB_CFLAGS="-G 0"
	SHLIB_SUFFIX=".a"
	SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
	SHLIB_LD_LIBS='${LIBS}'
	DL_OBJS="tclLoadAout.o"
	DL_LIBS=""
	LD_FLAGS="-Wl,-D,08000000"
	LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	;;
    UNIX_SV*)
	SHLIB_CFLAGS="-KPIC"
	SHLIB_LD="cc -G"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	# Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers







|
|


>
|











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|










|







1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
	LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'

	# SunOS can't handle version numbers with dots in them in library
	# specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
	# requires an extra version number at the end of .so file names.
	# So, the library has to have a name like libtcl75.so.1.0

	TCL_SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1.0'
	TCL_UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
	TCL_LIB_VERSIONS_OK=nodots
	;;
    SunOS-5.[[0-6]]*)
#    SunOS-5*)
	SHLIB_CFLAGS="-KPIC"
	SHLIB_LD="/usr/ccs/bin/ld -G -z text"

	# Note: need the LIBS below, otherwise Tk won't find Tcl's
	# symbols when dynamically loaded into tclsh.

	SHLIB_LD_LIBS='${LIBS}'
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS=""
	LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
	;;
    SunOS-5*)
	SHLIB_CFLAGS="-KPIC"
	SHLIB_LD="/usr/ccs/bin/ld -G -z text"
	LD_FLAGS=""
 
        do64bit_ok=no
	if test "$do64bit" = "yes" ; then
          arch=`isainfo`
          if test "$arch" = "sparcv9 sparc" ; then
	    if test "$CC" != "gcc" -a `$CC -v 2>&1 | grep -c gcc` = "0" ; then
    	      do64bit_ok=yes
              EXTRA_CFLAGS="-xarch=v9"
              LD_FLAGS="-xarch=v9"
	    else 
	      AC_MSG_WARN("64bit mode not supported using GCC on $system")
	    fi
          else
            AC_MSG_WARN("64bit mode only supported sparcv9 system")
          fi
	fi
        
        # Note: need the LIBS below, otherwise Tk won't find Tcl's
        # symbols when dynamically loaded into tclsh.

        SHLIB_LD_LIBS='${LIBS}'
        SHLIB_SUFFIX=".so"
        DL_OBJS="tclLoadDl.o"
        DL_LIBS="-ldl"
	if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then
	    LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
	else
	    LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
	fi
        ;;
    ULTRIX-4.*)
	SHLIB_CFLAGS="-G 0"
	SHLIB_SUFFIX=".a"
	SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
	SHLIB_LD_LIBS='${LIBS}'
	DL_OBJS="tclLoadAout.o"
	DL_LIBS=""
	LD_FLAGS="-Wl,-D,08000000"
	LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	;;
    UNIX_SV* | UnixWare-5*)
	SHLIB_CFLAGS="-KPIC"
	SHLIB_LD="cc -G"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	# Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
950
951
952
953
954
955
956




957
958
959
960
961
962
963
	  LD_FLAGS="-Wl,-Bexport"
	else
	  LD_FLAGS=""
	fi
	LD_SEARCH_FLAGS=""
	;;
esac





# Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic
# Loading for Tcl -- What Became of It?".  Proc. 2nd Tcl/Tk Workshop,
# New Orleans, LA, Computerized Processes Unlimited, 1994), then we need
# to determine which of several header files defines the a.out file
# format (a.out.h, sys/exec.h, or sys/exec_aout.h).  At present, we
# support only a file format that is more or less version-7-compatible. 







>
>
>
>







1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
	  LD_FLAGS="-Wl,-Bexport"
	else
	  LD_FLAGS=""
	fi
	LD_SEARCH_FLAGS=""
	;;
esac

if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
  AC_MSG_WARN("64bit support being disabled -- not supported on this platform")
fi

# Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic
# Loading for Tcl -- What Became of It?".  Proc. 2nd Tcl/Tk Workshop,
# New Orleans, LA, Computerized Processes Unlimited, 1994), then we need
# to determine which of several header files defines the a.out file
# format (a.out.h, sys/exec.h, or sys/exec_aout.h).  At present, we
# support only a file format that is more or less version-7-compatible. 
1076
1077
1078
1079
1080
1081
1082












1083
1084
1085
1086
1087
1088
1089
		;;
	    *)
		SHLIB_CFLAGS="-fPIC"
		;;
	esac
    fi
fi













#--------------------------------------------------------------------
#	The statements below check for systems where POSIX-style
#	non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. 
#	On these systems (mostly older ones), use the old BSD-style
#	FIONBIO approach instead.
#--------------------------------------------------------------------







>
>
>
>
>
>
>
>
>
>
>
>







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
		;;
	    *)
		SHLIB_CFLAGS="-fPIC"
		;;
	esac
    fi
fi

# Set the default compiler switches based on the --enable-symbols option 

AC_ARG_ENABLE(symbols, [  --enable-symbols        build with debugging symbols],
    [tcl_ok=$enableval], [tcl_ok=no])
if test "$tcl_ok" = "yes"; then
    CFLAGS='$(CFLAGS_DEBUG)'
    TCL_DBGX=g
else
    CFLAGS='$(CFLAGS_OPTIMIZE)'
    TCL_DBGX=""
fi

#--------------------------------------------------------------------
#	The statements below check for systems where POSIX-style
#	non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. 
#	On these systems (mostly older ones), use the old BSD-style
#	FIONBIO approach instead.
#--------------------------------------------------------------------
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178







1179
1180
1181
1182
1183
1184

1185




1186
1187
1188






1189
1190
1191





1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205


































1206








1207
1208

1209
1210
1211
1212
1213
1214
1215
1216
1217
1218




1219
1220
1221
1222
1223
1224
1225
#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
#	building libtcl as a shared library instead of a static library.
#--------------------------------------------------------------------

realRanlib=$RANLIB
if test "$TCL_SHARED_LIB_SUFFIX" = "" ; then
    TCL_SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'
fi
if test "$TCL_UNSHARED_LIB_SUFFIX" = "" ; then
    TCL_UNSHARED_LIB_SUFFIX='${VERSION}.a'
fi
AC_ARG_ENABLE(shared,
    [  --enable-shared         build libtcl as a shared library],
    [tcl_ok=$enableval], [tcl_ok=no])
if test "$tcl_ok" = "yes" -a "${SHLIB_SUFFIX}" != "" ; then
    TCL_SHARED_BUILD=1
    TCL_SHLIB_CFLAGS="${SHLIB_CFLAGS}"
    TCL_LD_SEARCH_FLAGS="${LD_SEARCH_FLAGS}"
    eval "TCL_LIB_FILE=libtcl${TCL_SHARED_LIB_SUFFIX}"
    if test "x$DL_OBJS" = "xtclLoadAout.o"; then
	MAKE_LIB="ar cr ${TCL_LIB_FILE} \${OBJS}"
    else
	MAKE_LIB="\${SHLIB_LD} -o ${TCL_LIB_FILE} \${OBJS} ${SHLIB_LD_LIBS}"
	RANLIB=":"
    fi
else
    TCL_SHARED_BUILD=0
    case $system in
        BSD/OS*)
	    ;;

	AIX-*)
            ;;

        *)
	    SHLIB_LD_LIBS=""
	    ;;
    esac
    TCL_SHLIB_CFLAGS=""
    TCL_LD_SEARCH_FLAGS=""
    eval "TCL_LIB_FILE=libtcl${TCL_UNSHARED_LIB_SUFFIX}"
    MAKE_LIB="ar cr ${TCL_LIB_FILE} \${OBJS}"
fi








# Note:  in the following variable, it's important to use the absolute
# path name of the Tcl directory rather than "..":  this is because
# AIX remembers this path and will attempt to use it at run-time to look
# up the Tcl library.


if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then




    TCL_BUILD_LIB_SPEC="-L`pwd` -ltcl${VERSION}"
    TCL_LIB_SPEC="-L${exec_prefix}/lib -ltcl${VERSION}"
else






    TCL_BUILD_LIB_SPEC="-L`pwd` -ltcl`echo ${VERSION} | tr -d .`"
    TCL_LIB_SPEC="-L${exec_prefix}/lib -ltcl`echo ${VERSION} | tr -d .`"
fi






#--------------------------------------------------------------------
#	The statements below define the symbol TCL_PACKAGE_PATH, which
#	gives a list of directories that may contain packages.  The list
#	consists of one directory for machine-dependent binaries and
#	another for platform-independent scripts.
#--------------------------------------------------------------------

if test "$prefix" != "$exec_prefix"; then
    TCL_PACKAGE_PATH="${exec_prefix}/lib ${prefix}/lib"
else
    TCL_PACKAGE_PATH="${prefix}/lib"
fi



































AC_SUBST(BUILD_DLTEST)








AC_SUBST(DL_LIBS)
AC_SUBST(DL_OBJS)

AC_SUBST(LD_FLAGS)
AC_SUBST(MAKE_LIB)
AC_SUBST(MATH_LIBS)
AC_SUBST(SHLIB_CFLAGS)
AC_SUBST(SHLIB_LD)
AC_SUBST(SHLIB_LD_LIBS)
AC_SUBST(SHLIB_SUFFIX)
AC_SUBST(TCL_BUILD_LIB_SPEC)
AC_SUBST(TCL_LD_SEARCH_FLAGS)
AC_SUBST(TCL_LIB_FILE)




AC_SUBST(TCL_LIB_SPEC)
AC_SUBST(TCL_LIB_VERSIONS_OK)
AC_SUBST(TCL_MAJOR_VERSION)
AC_SUBST(TCL_MINOR_VERSION)
AC_SUBST(TCL_PACKAGE_PATH)
AC_SUBST(TCL_PATCH_LEVEL)
AC_SUBST(TCL_SHARED_LIB_SUFFIX)







|


|


|
|






|

|
















|

|

>
>
>
>
>
>
>






>
|
>
>
>
>
|
|

>
>
>
>
>
>
|
|

>
>
>
>
>














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>


>










>
>
>
>







1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
#--------------------------------------------------------------------
#	The statements below define a collection of symbols related to
#	building libtcl as a shared library instead of a static library.
#--------------------------------------------------------------------

realRanlib=$RANLIB
if test "$TCL_SHARED_LIB_SUFFIX" = "" ; then
    TCL_SHARED_LIB_SUFFIX='${VERSION}\$\{DBGX\}${SHLIB_SUFFIX}'
fi
if test "$TCL_UNSHARED_LIB_SUFFIX" = "" ; then
    TCL_UNSHARED_LIB_SUFFIX='${VERSION}\$\{DBGX\}.a'
fi
AC_ARG_ENABLE(shared,
    [  --enable-shared         build libtcl as a shared library (on by default)],
    [tcl_ok=$enableval], [tcl_ok=yes])
if test "$tcl_ok" = "yes" -a "${SHLIB_SUFFIX}" != "" ; then
    TCL_SHARED_BUILD=1
    TCL_SHLIB_CFLAGS="${SHLIB_CFLAGS}"
    TCL_LD_SEARCH_FLAGS="${LD_SEARCH_FLAGS}"
    eval "TCL_LIB_FILE=libtcl${TCL_SHARED_LIB_SUFFIX}"
    if test "x$DL_OBJS" = "xtclLoadAout.o"; then
	MAKE_LIB="ar cr \${TCL_LIB_FILE} \${OBJS}"
    else
	MAKE_LIB="\${SHLIB_LD} -o \${TCL_LIB_FILE} \${OBJS} ${SHLIB_LD_LIBS}"
	RANLIB=":"
    fi
else
    TCL_SHARED_BUILD=0
    case $system in
        BSD/OS*)
	    ;;

	AIX-*)
            ;;

        *)
	    SHLIB_LD_LIBS=""
	    ;;
    esac
    TCL_SHLIB_CFLAGS=""
    TCL_LD_SEARCH_FLAGS="${LD_SEARCH_FLAGS}"
    eval "TCL_LIB_FILE=libtcl${TCL_UNSHARED_LIB_SUFFIX}"
    MAKE_LIB="ar cr \${TCL_LIB_FILE} \${OBJS}"
fi

# tclConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# so that the backslashes quoting the DBX braces are dropped.

# Trick to replace DBGX with TCL_DBGX
DBGX='${TCL_DBGX}'
eval "TCL_LIB_FILE=${TCL_LIB_FILE}"

# Note:  in the following variable, it's important to use the absolute
# path name of the Tcl directory rather than "..":  this is because
# AIX remembers this path and will attempt to use it at run-time to look
# up the Tcl library.

if test $TCL_SHARED_BUILD = 0 -o $TCL_NEEDS_EXP_FILE = 0; then
    if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
        TCL_LIB_FLAG="-ltcl${TCL_VERSION}\${TCL_DBGX}"
    else
        TCL_LIB_FLAG="-ltcl`echo ${TCL_VERSION} | tr -d .`\${TCL_DBGX}"
    fi
    TCL_BUILD_LIB_SPEC="-L`pwd` ${TCL_LIB_FLAG}"
    TCL_LIB_SPEC="-L${exec_prefix}/lib ${TCL_LIB_FLAG}"
else
    TCL_BUILD_EXP_FILE="lib.exp"
    eval "TCL_EXP_FILE=libtcl${TCL_EXPORT_FILE_SUFFIX}"

    # Replace DBGX with TCL_DBGX
    eval "TCL_EXP_FILE=\"${TCL_EXP_FILE}\""
    
    TCL_BUILD_LIB_SPEC="-bI:`pwd`/${TCL_BUILD_EXP_FILE}"
    TCL_LIB_SPEC="-bI:${exec_prefix}/lib/${TCL_EXP_FILE}"    
fi
VERSION='${VERSION}'
eval "CFG_TCL_SHARED_LIB_SUFFIX=${TCL_SHARED_LIB_SUFFIX}"
eval "CFG_TCL_UNSHARED_LIB_SUFFIX=${TCL_UNSHARED_LIB_SUFFIX}"
eval "CFG_TCL_EXPORT_FILE_SUFFIX=${TCL_EXPORT_FILE_SUFFIX}"
VERSION=${TCL_VERSION}

#--------------------------------------------------------------------
#	The statements below define the symbol TCL_PACKAGE_PATH, which
#	gives a list of directories that may contain packages.  The list
#	consists of one directory for machine-dependent binaries and
#	another for platform-independent scripts.
#--------------------------------------------------------------------

if test "$prefix" != "$exec_prefix"; then
    TCL_PACKAGE_PATH="${exec_prefix}/lib ${prefix}/lib"
else
    TCL_PACKAGE_PATH="${prefix}/lib"
fi

#--------------------------------------------------------------------
#       The statements below define various symbols relating to Tcl
#       stub support.
#--------------------------------------------------------------------
# Replace ${VERSION} with contents of ${TCL_VERSION}
eval "STUB_LIB_FILE=libtclstub${TCL_UNSHARED_LIB_SUFFIX}"
# Replace DBGX with TCL_DBGX
eval "STUB_LIB_FILE=\"${STUB_LIB_FILE}\""

MAKE_STUB_LIB="ar cr \${STUB_LIB_FILE} \${STUB_LIB_OBJS}"

TCL_STUB_LIB_FILE=${STUB_LIB_FILE}

if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
    TCL_STUB_LIB_FLAG="-ltclstub${TCL_VERSION}\${TCL_DBGX}"
else
    TCL_STUB_LIB_FLAG="-ltclstub`echo ${TCL_VERSION} | tr -d .`\${TCL_DBGX}"
fi

TCL_BUILD_STUB_LIB_SPEC="-L`pwd` ${TCL_STUB_LIB_FLAG}"
TCL_STUB_LIB_SPEC="-L${exec_prefix}/lib ${TCL_STUB_LIB_FLAG}"
TCL_BUILD_STUB_LIB_PATH="`pwd`/${TCL_STUB_LIB_FILE}"
TCL_STUB_LIB_PATH="${exec_prefix}/lib/${TCL_STUB_LIB_FILE}"

AC_SUBST(STUB_LIB_FILE)

AC_SUBST(TCL_STUB_LIB_FILE)
AC_SUBST(TCL_STUB_LIB_FLAG)
AC_SUBST(TCL_BUILD_STUB_LIB_SPEC)
AC_SUBST(TCL_STUB_LIB_SPEC)
AC_SUBST(TCL_BUILD_STUB_LIB_PATH)
AC_SUBST(TCL_STUB_LIB_PATH)
AC_SUBST(MAKE_STUB_LIB)

AC_SUBST(BUILD_DLTEST)
AC_SUBST(CFLAGS)
AC_SUBST(CFLAGS_DEBUG)
AC_SUBST(CFLAGS_OPTIMIZE)
AC_SUBST(CFLAGS_WARNING)
AC_SUBST(CFG_TCL_SHARED_LIB_SUFFIX)
AC_SUBST(CFG_TCL_UNSHARED_LIB_SUFFIX)
AC_SUBST(CFG_TCL_EXPORT_FILE_SUFFIX)
AC_SUBST(TCL_DBGX)
AC_SUBST(DL_LIBS)
AC_SUBST(DL_OBJS)
AC_SUBST(EXTRA_CFLAGS)
AC_SUBST(LD_FLAGS)
AC_SUBST(MAKE_LIB)
AC_SUBST(MATH_LIBS)
AC_SUBST(SHLIB_CFLAGS)
AC_SUBST(SHLIB_LD)
AC_SUBST(SHLIB_LD_LIBS)
AC_SUBST(SHLIB_SUFFIX)
AC_SUBST(TCL_BUILD_LIB_SPEC)
AC_SUBST(TCL_LD_SEARCH_FLAGS)
AC_SUBST(TCL_LIB_FILE)
AC_SUBST(TCL_LIB_FLAG)
AC_SUBST(TCL_NEEDS_EXP_FILE)
AC_SUBST(TCL_BUILD_EXP_FILE)
AC_SUBST(TCL_EXP_FILE)
AC_SUBST(TCL_LIB_SPEC)
AC_SUBST(TCL_LIB_VERSIONS_OK)
AC_SUBST(TCL_MAJOR_VERSION)
AC_SUBST(TCL_MINOR_VERSION)
AC_SUBST(TCL_PACKAGE_PATH)
AC_SUBST(TCL_PATCH_LEVEL)
AC_SUBST(TCL_SHARED_LIB_SUFFIX)

Changes to unix/dltest/Makefile.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
# This Makefile is used to create several test cases for Tcl's load
# command.  It also illustrates how to take advantage of configuration
# exported by Tcl to set up Makefiles for shared libraries.
# SCCS: @(#) Makefile.in 1.12 97/02/22 14:13:54


CC = @CC@
LIBS =			@TCL_BUILD_LIB_SPEC@ @TCL_LIBS@ -lc

SHLIB_CFLAGS =		@SHLIB_CFLAGS@
SHLIB_LD =		@SHLIB_LD@
SHLIB_SUFFIX =		@SHLIB_SUFFIX@
SHLIB_VERSION =		@SHLIB_VERSION@
SRC_DIR =		@srcdir@
TCL_VERSION=		@TCL_VERSION@

CFLAGS = -g
CC_SWITCHES = $(CFLAGS) -I${SRC_DIR}/../../generic -DTCL_MEM_DEBUG \
	${SHLIB_CFLAGS}

all: pkga${SHLIB_SUFFIX} pkgb${SHLIB_SUFFIX} pkgc${SHLIB_SUFFIX} pkgd${SHLIB_SUFFIX} pkge${SHLIB_SUFFIX}

pkga${SHLIB_SUFFIX}: $(SRC_DIR)/pkga.c
	$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkga.c
	${SHLIB_LD} -o pkga${SHLIB_SUFFIX} pkga.o @SHLIB_LD_LIBS@

pkgb${SHLIB_SUFFIX}: $(SRC_DIR)/pkgb.c
	$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkgb.c
	${SHLIB_LD} -o pkgb${SHLIB_SUFFIX} pkgb.o @SHLIB_LD_LIBS@

pkgc${SHLIB_SUFFIX}: $(SRC_DIR)/pkgc.c
	$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkgc.c
	${SHLIB_LD} -o pkgc${SHLIB_SUFFIX} pkgc.o @SHLIB_LD_LIBS@

pkgd${SHLIB_SUFFIX}: $(SRC_DIR)/pkgd.c
	$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkgd.c
	${SHLIB_LD} -o pkgd${SHLIB_SUFFIX} pkgd.o @SHLIB_LD_LIBS@

pkge${SHLIB_SUFFIX}: $(SRC_DIR)/pkge.c
	$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkge.c
	${SHLIB_LD} -o pkge${SHLIB_SUFFIX} pkge.o @SHLIB_LD_LIBS@

clean:
	rm -f *.o *${SHLIB_SUFFIX} config.cache config.log config.status lib.exp

distclean: clean
	rm -f Makefile



|

>

|
>









|





|



|



|



|



|






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
# This Makefile is used to create several test cases for Tcl's load
# command.  It also illustrates how to take advantage of configuration
# exported by Tcl to set up Makefiles for shared libraries.
# RCS: @(#) $Id: Makefile.in,v 1.1.2.5 1999/03/27 23:25:34 redman Exp $

TCL_DBGX =		@TCL_DBGX@
CC = @CC@
LIBS =			@TCL_BUILD_STUB_LIB_SPEC@ @TCL_LIBS@
AC_FLAGS =		@EXTRA_CFLAGS@
SHLIB_CFLAGS =		@SHLIB_CFLAGS@
SHLIB_LD =		@SHLIB_LD@
SHLIB_SUFFIX =		@SHLIB_SUFFIX@
SHLIB_VERSION =		@SHLIB_VERSION@
SRC_DIR =		@srcdir@
TCL_VERSION=		@TCL_VERSION@

CFLAGS = -g
CC_SWITCHES = $(CFLAGS) -I${SRC_DIR}/../../generic -DTCL_MEM_DEBUG \
	${SHLIB_CFLAGS} -DUSE_TCL_STUBS ${AC_FLAGS}

all: pkga${SHLIB_SUFFIX} pkgb${SHLIB_SUFFIX} pkgc${SHLIB_SUFFIX} pkgd${SHLIB_SUFFIX} pkge${SHLIB_SUFFIX}

pkga${SHLIB_SUFFIX}: $(SRC_DIR)/pkga.c
	$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkga.c
	${SHLIB_LD} -o pkga${SHLIB_SUFFIX} pkga.o ${LIBS}

pkgb${SHLIB_SUFFIX}: $(SRC_DIR)/pkgb.c
	$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkgb.c
	${SHLIB_LD} -o pkgb${SHLIB_SUFFIX} pkgb.o ${LIBS}

pkgc${SHLIB_SUFFIX}: $(SRC_DIR)/pkgc.c
	$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkgc.c
	${SHLIB_LD} -o pkgc${SHLIB_SUFFIX} pkgc.o ${LIBS}

pkgd${SHLIB_SUFFIX}: $(SRC_DIR)/pkgd.c
	$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkgd.c
	${SHLIB_LD} -o pkgd${SHLIB_SUFFIX} pkgd.o ${LIBS}

pkge${SHLIB_SUFFIX}: $(SRC_DIR)/pkge.c
	$(CC) -c $(CC_SWITCHES) $(SRC_DIR)/pkge.c
	${SHLIB_LD} -o pkge${SHLIB_SUFFIX} pkge.o ${LIBS}

clean:
	rm -f *.o *${SHLIB_SUFFIX} config.cache config.log config.status lib.exp

distclean: clean
	rm -f Makefile

Changes to unix/dltest/README.

1
2
3
4
5
6
7
8
9
10
11
12
This directory contains several files for testing Tcl's dynamic
loading capabilities.  If this directory is present and the files
in here have been compiled, then the "load" test will use the shared
libraries present here to run a series of tests.  To compile the
shared libraries, first type "./configure".  This will read
configuration information created when Tcl was configured and
create Makefile from Makefile.in.  Be sure that you have configured
Tcl before configuring here, since information learned during Tcl's
configure is needed here.  Then type "make" to create the shared
libraries.

sccsid: @(#) README 1.2 95/08/22 08:13:23











|
1
2
3
4
5
6
7
8
9
10
11
12
This directory contains several files for testing Tcl's dynamic
loading capabilities.  If this directory is present and the files
in here have been compiled, then the "load" test will use the shared
libraries present here to run a series of tests.  To compile the
shared libraries, first type "./configure".  This will read
configuration information created when Tcl was configured and
create Makefile from Makefile.in.  Be sure that you have configured
Tcl before configuring here, since information learned during Tcl's
configure is needed here.  Then type "make" to create the shared
libraries.

RCS: @(#) $Id: README,v 1.1.2.1 1998/09/24 23:59:47 stanton Exp $

Changes to unix/dltest/configure.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
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(pkga.c)
# SCCS: @(#) configure.in 1.9 96/04/15 09:50:20

# Recover information that Tcl computed with its configure script.

. ../tclConfig.sh

CC=$TCL_CC
AC_SUBST(CC)
SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS
AC_SUBST(SHLIB_CFLAGS)


SHLIB_LD=$TCL_SHLIB_LD
AC_SUBST(SHLIB_LD)
SHLIB_LD_LIBS=$TCL_SHLIB_LD_LIBS
AC_SUBST(SHLIB_LD_LIBS)
SHLIB_SUFFIX=$TCL_SHLIB_SUFFIX
AC_SUBST(SHLIB_SUFFIX)
SHLIB_VERSION=$TCL_SHLIB_VERSION
AC_SUBST(SHLIB_VERSION)
AC_SUBST(TCL_BUILD_LIB_SPEC)
TCL_LIBS=$TCL_LIBS
AC_SUBST(TCL_LIBS)
TCL_VERSION=$TCL_VERSION
AC_SUBST(TCL_VERSION)



AC_OUTPUT(Makefile)




|









>
>








|




>
>


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
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(pkga.c)
# RCS: @(#) $Id: configure.in,v 1.1.2.4 1999/03/24 04:22:53 stanton Exp $

# Recover information that Tcl computed with its configure script.

. ../tclConfig.sh

CC=$TCL_CC
AC_SUBST(CC)
SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS
AC_SUBST(SHLIB_CFLAGS)
EXTRA_CFLAGS=$TCL_EXTRA_CFLAGS
AC_SUBST(EXTRA_CFLAGS)
SHLIB_LD=$TCL_SHLIB_LD
AC_SUBST(SHLIB_LD)
SHLIB_LD_LIBS=$TCL_SHLIB_LD_LIBS
AC_SUBST(SHLIB_LD_LIBS)
SHLIB_SUFFIX=$TCL_SHLIB_SUFFIX
AC_SUBST(SHLIB_SUFFIX)
SHLIB_VERSION=$TCL_SHLIB_VERSION
AC_SUBST(SHLIB_VERSION)
AC_SUBST(TCL_BUILD_STUB_LIB_SPEC)
TCL_LIBS=$TCL_LIBS
AC_SUBST(TCL_LIBS)
TCL_VERSION=$TCL_VERSION
AC_SUBST(TCL_VERSION)
TCL_DBGX=$TCL_DBGX
AC_SUBST(TCL_DBGX)

AC_OUTPUT(Makefile)

Changes to unix/dltest/pkga.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * pkga.c --
 *
 *	This file contains a simple Tcl package "pkga" that is intended
 *	for testing the Tcl dynamic loading facilities.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) pkga.c 1.4 96/02/15 12:30:35
 */
#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * pkga.c --
 *
 *	This file contains a simple Tcl package "pkga" that is intended
 *	for testing the Tcl dynamic loading facilities.
 *
 * Copyright (c) 1995 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: pkga.c,v 1.1.2.2 1999/03/12 23:01:01 stanton Exp $
 */
#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */

114
115
116
117
118
119
120



121
122
123
124
125
126
127
128
129
130
int
Pkga_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    int code;




    code = Tcl_PkgProvide(interp, "Pkga", "1.0");
    if (code != TCL_OK) {
	return code;
    }
    Tcl_CreateCommand(interp, "pkga_eq", Pkga_EqCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "pkga_quote", Pkga_QuoteCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    return TCL_OK;
}







>
>
>










114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
int
Pkga_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    int code;

    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
	return TCL_ERROR;
    }
    code = Tcl_PkgProvide(interp, "Pkga", "1.0");
    if (code != TCL_OK) {
	return code;
    }
    Tcl_CreateCommand(interp, "pkga_eq", Pkga_EqCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "pkga_quote", Pkga_QuoteCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    return TCL_OK;
}

Changes to unix/dltest/pkgb.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * pkgb.c --
 *
 *	This file contains a simple Tcl package "pkgb" that is intended
 *	for testing the Tcl dynamic loading facilities.  It can be used
 *	in both safe and unsafe interpreters.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) pkgb.c 1.4 96/02/15 12:30:34
 */
#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * pkgb.c --
 *
 *	This file contains a simple Tcl package "pkgb" that is intended
 *	for testing the Tcl dynamic loading facilities.  It can be used
 *	in both safe and unsafe interpreters.
 *
 * Copyright (c) 1995 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: pkgb.c,v 1.1.2.2 1999/03/12 23:01:01 stanton Exp $
 */
#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */

110
111
112
113
114
115
116



117
118
119
120
121
122
123
int
Pkgb_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    int code;




    code = Tcl_PkgProvide(interp, "Pkgb", "2.3");
    if (code != TCL_OK) {
	return code;
    }
    Tcl_CreateCommand(interp, "pkgb_sub", Pkgb_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "pkgb_unsafe", Pkgb_UnsafeCmd, (ClientData) 0,







>
>
>







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
int
Pkgb_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    int code;

    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
	return TCL_ERROR;
    }
    code = Tcl_PkgProvide(interp, "Pkgb", "2.3");
    if (code != TCL_OK) {
	return code;
    }
    Tcl_CreateCommand(interp, "pkgb_sub", Pkgb_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "pkgb_unsafe", Pkgb_UnsafeCmd, (ClientData) 0,
143
144
145
146
147
148
149



150
151
152
153
 */

int
Pkgb_SafeInit(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{



    Tcl_CreateCommand(interp, "pkgb_sub", Pkgb_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    return TCL_OK;
}







>
>
>




146
147
148
149
150
151
152
153
154
155
156
157
158
159
 */

int
Pkgb_SafeInit(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
	return TCL_ERROR;
    }
    Tcl_CreateCommand(interp, "pkgb_sub", Pkgb_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    return TCL_OK;
}

Changes to unix/dltest/pkgc.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * pkgc.c --
 *
 *	This file contains a simple Tcl package "pkgc" that is intended
 *	for testing the Tcl dynamic loading facilities.  It can be used
 *	in both safe and unsafe interpreters.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) pkgc.c 1.4 96/02/15 12:30:35
 */
#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * pkgc.c --
 *
 *	This file contains a simple Tcl package "pkgc" that is intended
 *	for testing the Tcl dynamic loading facilities.  It can be used
 *	in both safe and unsafe interpreters.
 *
 * Copyright (c) 1995 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: pkgc.c,v 1.1.2.2 1999/03/12 23:01:01 stanton Exp $
 */
#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */

110
111
112
113
114
115
116



117
118
119
120
121
122
123
int
Pkgc_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    int code;




    code = Tcl_PkgProvide(interp, "Pkgc", "1.7.2");
    if (code != TCL_OK) {
	return code;
    }
    Tcl_CreateCommand(interp, "pkgc_sub", Pkgc_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "pkgc_unsafe", Pkgc_UnsafeCmd, (ClientData) 0,







>
>
>







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
int
Pkgc_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    int code;

    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
	return TCL_ERROR;
    }
    code = Tcl_PkgProvide(interp, "Pkgc", "1.7.2");
    if (code != TCL_OK) {
	return code;
    }
    Tcl_CreateCommand(interp, "pkgc_sub", Pkgc_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "pkgc_unsafe", Pkgc_UnsafeCmd, (ClientData) 0,
143
144
145
146
147
148
149



150
151
152
153
 */

int
Pkgc_SafeInit(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{



    Tcl_CreateCommand(interp, "pkgc_sub", Pkgc_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    return TCL_OK;
}







>
>
>




146
147
148
149
150
151
152
153
154
155
156
157
158
159
 */

int
Pkgc_SafeInit(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
	return TCL_ERROR;
    }
    Tcl_CreateCommand(interp, "pkgc_sub", Pkgc_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    return TCL_OK;
}

Changes to unix/dltest/pkgd.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * pkgd.c --
 *
 *	This file contains a simple Tcl package "pkgd" that is intended
 *	for testing the Tcl dynamic loading facilities.  It can be used
 *	in both safe and unsafe interpreters.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) pkgd.c 1.4 96/02/15 12:30:32
 */

#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * pkgd.c --
 *
 *	This file contains a simple Tcl package "pkgd" that is intended
 *	for testing the Tcl dynamic loading facilities.  It can be used
 *	in both safe and unsafe interpreters.
 *
 * Copyright (c) 1995 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: pkgd.c,v 1.1.2.2 1999/03/12 23:01:02 stanton Exp $
 */

#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */
111
112
113
114
115
116
117



118
119
120
121
122
123
124
int
Pkgd_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    int code;




    code = Tcl_PkgProvide(interp, "Pkgd", "7.3");
    if (code != TCL_OK) {
	return code;
    }
    Tcl_CreateCommand(interp, "pkgd_sub", Pkgd_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "pkgd_unsafe", Pkgd_UnsafeCmd, (ClientData) 0,







>
>
>







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
int
Pkgd_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    int code;

    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
	return TCL_ERROR;
    }
    code = Tcl_PkgProvide(interp, "Pkgd", "7.3");
    if (code != TCL_OK) {
	return code;
    }
    Tcl_CreateCommand(interp, "pkgd_sub", Pkgd_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "pkgd_unsafe", Pkgd_UnsafeCmd, (ClientData) 0,
144
145
146
147
148
149
150



151
152
153
154
 */

int
Pkgd_SafeInit(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{



    Tcl_CreateCommand(interp, "pkgd_sub", Pkgd_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    return TCL_OK;
}







>
>
>




147
148
149
150
151
152
153
154
155
156
157
158
159
160
 */

int
Pkgd_SafeInit(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
	return TCL_ERROR;
    }
    Tcl_CreateCommand(interp, "pkgd_sub", Pkgd_SubCmd, (ClientData) 0,
	    (Tcl_CmdDeleteProc *) NULL);
    return TCL_OK;
}

Changes to unix/dltest/pkge.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
/* 
 * pkge.c --
 *
 *	This file contains a simple Tcl package "pkge" that is intended
 *	for testing the Tcl dynamic loading facilities.  Its Init
 *	procedure returns an error in order to test how this is handled.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) pkge.c 1.5 96/03/07 09:34:27
 */

#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */

static int	Pkgd_SubCmd _ANSI_ARGS_((ClientData clientData,












|

>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 
 * pkge.c --
 *
 *	This file contains a simple Tcl package "pkge" that is intended
 *	for testing the Tcl dynamic loading facilities.  Its Init
 *	procedure returns an error in order to test how this is handled.
 *
 * Copyright (c) 1995 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: pkge.c,v 1.1.2.3 1999/03/12 23:01:02 stanton Exp $
 */

#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */

static int	Pkgd_SubCmd _ANSI_ARGS_((ClientData clientData,
41
42
43
44
45
46
47




48
49
 */

int
Pkge_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{




    return Tcl_Eval(interp, "if 44 {open non_existent}");
}







>
>
>
>
|

42
43
44
45
46
47
48
49
50
51
52
53
54
 */

int
Pkge_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    static char script[] = "if 44 {open non_existent}";
    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
	return TCL_ERROR;
    }
    return Tcl_Eval(interp, script);
}

Changes to unix/dltest/pkgf.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * pkgf.c --
 *
 *	This file contains a simple Tcl package "pkgf" that is intended
 *	for testing the Tcl dynamic loading facilities.  Its Init
 *	procedure returns an error in order to test how this is handled.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) pkgf.c 1.2 96/02/15 12:30:32
 */
#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * pkgf.c --
 *
 *	This file contains a simple Tcl package "pkgf" that is intended
 *	for testing the Tcl dynamic loading facilities.  Its Init
 *	procedure returns an error in order to test how this is handled.
 *
 * Copyright (c) 1995 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: pkgf.c,v 1.1.2.2 1999/03/12 23:01:02 stanton Exp $
 */
#include "tcl.h"

/*
 * Prototypes for procedures defined later in this file:
 */

41
42
43
44
45
46
47




48
49
 */

int
Pkgf_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{




    return Tcl_Eval(interp, "if 44 {open non_existent}");
}







>
>
>
>
|

41
42
43
44
45
46
47
48
49
50
51
52
53
 */

int
Pkgf_Init(interp)
    Tcl_Interp *interp;		/* Interpreter in which the package is
				 * to be made available. */
{
    static char script[] = "if 44 {open non_existent}";
    if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) {
	return TCL_ERROR;
    }
    return Tcl_Eval(interp, script);
}

Changes to unix/ldAix.

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
#!/bin/sh
#
# ldAix ldCmd ldArg ldArg ...
#
# This shell script provides a wrapper for ld under AIX in order to
# create the .exp file required for linking.  Its arguments consist
# of the name and arguments that would normally be provided to the
# ld command.  This script extracts the names of the object files
# from the argument list, creates a .exp file describing all of the
# symbols exported by those files, and then invokes "ldCmd" to
# perform the real link.
#
# SCCS: @(#) ldAix 1.8 97/02/21 14:50:27

# Extract from the arguments the names of all of the object files.

args=$*
ofiles=""
for i do
    x=`echo $i | grep '[^.].o$'`
    if test "$x" != ""; then
	ofiles="$ofiles $i"
    fi
done




# Create the export file from all of the object files, using nm followed
# by sed editing.  Here are some tricky aspects of this:
#
# 1. Nm produces different output under AIX 4.1 than under AIX 3.2.5;
#    the following statements handle both versions.
# 2. Use the -g switch to nm instead of -e under 4.1 (this shows just












|











>
>
>







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
#!/bin/sh
#
# ldAix ldCmd ldArg ldArg ...
#
# This shell script provides a wrapper for ld under AIX in order to
# create the .exp file required for linking.  Its arguments consist
# of the name and arguments that would normally be provided to the
# ld command.  This script extracts the names of the object files
# from the argument list, creates a .exp file describing all of the
# symbols exported by those files, and then invokes "ldCmd" to
# perform the real link.
#
# RCS: @(#) $Id: ldAix,v 1.1.2.2 1999/03/10 06:49:27 stanton Exp $

# Extract from the arguments the names of all of the object files.

args=$*
ofiles=""
for i do
    x=`echo $i | grep '[^.].o$'`
    if test "$x" != ""; then
	ofiles="$ofiles $i"
    fi
done

# Extract the name of the object file that we're linking.
outputFile=`echo $args | sed -e 's/.*-o \([^ ]*\).*/\1/'`

# Create the export file from all of the object files, using nm followed
# by sed editing.  Here are some tricky aspects of this:
#
# 1. Nm produces different output under AIX 4.1 than under AIX 3.2.5;
#    the following statements handle both versions.
# 2. Use the -g switch to nm instead of -e under 4.1 (this shows just
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

nmopts="-g -C"
osver=`uname -v`
if test $osver -eq 3; then
  nmopts="-e"
fi
rm -f lib.exp
echo "#! " >lib.exp
/usr/ccs/bin/nm $nmopts -h $ofiles | sed -e '/:$/d' -e '/ U /d' -e '/[ 	]0|extern/d' -e '/unamex/d' -e 's/^\.//' -e 's/[ 	|].*//' | sort | uniq >>lib.exp

# Extract the name of the object file that we're linking.  If it's a .a
# file, then link all the objects together into a single file "shr.o"
# and then put that into the archive.  Otherwise link the object files
# directly into the .a file.

outputFile=`echo $args | sed -e 's/.*-o \([^ ]*\).*/\1/'`
noDotA=`echo $outputFile | sed -e '/\.a$/d'`
echo "noDotA=\"$noDotA\""
if test "$noDotA" = "" ; then
    linkArgs=`echo $args | sed -e 's/-o .*\.a /-o shr.o /'`
    echo $linkArgs







|


<
|
|
|







48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67

nmopts="-g -C"
osver=`uname -v`
if test $osver -eq 3; then
  nmopts="-e"
fi
rm -f lib.exp
echo "#! $outputFile" >lib.exp
/usr/ccs/bin/nm $nmopts -h $ofiles | sed -e '/:$/d' -e '/ U /d' -e '/[ 	]0|extern/d' -e '/unamex/d' -e 's/^\.//' -e 's/[ 	|].*//' | sort | uniq >>lib.exp


# If we're linking a .a file, then link all the objects together into a 
# single file "shr.o" and then put that into the archive.  Otherwise link 
# the object files directly into the .a file.

outputFile=`echo $args | sed -e 's/.*-o \([^ ]*\).*/\1/'`
noDotA=`echo $outputFile | sed -e '/\.a$/d'`
echo "noDotA=\"$noDotA\""
if test "$noDotA" = "" ; then
    linkArgs=`echo $args | sed -e 's/-o .*\.a /-o shr.o /'`
    echo $linkArgs

Changes to unix/mkLinks.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    ln safe.n Base.n
fi
if test -r http.n; then
    rm -f Http.n
    ln http.n Http.n
fi
if test -r safe.n; then
    rm -f Safe.n
    ln safe.n Safe.n
fi
if test -r StringObj.3; then
    rm -f TclConcatObj.3
    ln StringObj.3 TclConcatObj.3
fi
if test -r AddErrInfo.3; then
    rm -f Tcl_AddErrorInfo.3
    ln AddErrInfo.3 Tcl_AddErrorInfo.3
fi
if test -r AddErrInfo.3; then
    rm -f Tcl_AddObjErrorInfo.3







|
|
<
<
<
<







32
33
34
35
36
37
38
39
40




41
42
43
44
45
46
47
    ln safe.n Base.n
fi
if test -r http.n; then
    rm -f Http.n
    ln http.n Http.n
fi
if test -r safe.n; then
    rm -f Safe\.n
    ln safe.n Safe\.n




fi
if test -r AddErrInfo.3; then
    rm -f Tcl_AddErrorInfo.3
    ln AddErrInfo.3 Tcl_AddErrorInfo.3
fi
if test -r AddErrInfo.3; then
    rm -f Tcl_AddObjErrorInfo.3
67
68
69
70
71
72
73




74
75
76
77
78
79
80
    rm -f Tcl_AppendAllObjTypes.3
    ln ObjectType.3 Tcl_AppendAllObjTypes.3
fi
if test -r SetResult.3; then
    rm -f Tcl_AppendElement.3
    ln SetResult.3 Tcl_AppendElement.3
fi




if test -r SetResult.3; then
    rm -f Tcl_AppendResult.3
    ln SetResult.3 Tcl_AppendResult.3
fi
if test -r StringObj.3; then
    rm -f Tcl_AppendStringsToObj.3
    ln StringObj.3 Tcl_AppendStringsToObj.3







>
>
>
>







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    rm -f Tcl_AppendAllObjTypes.3
    ln ObjectType.3 Tcl_AppendAllObjTypes.3
fi
if test -r SetResult.3; then
    rm -f Tcl_AppendElement.3
    ln SetResult.3 Tcl_AppendElement.3
fi
if test -r StringObj.3; then
    rm -f Tcl_AppendObjToObj.3
    ln StringObj.3 Tcl_AppendObjToObj.3
fi
if test -r SetResult.3; then
    rm -f Tcl_AppendResult.3
    ln SetResult.3 Tcl_AppendResult.3
fi
if test -r StringObj.3; then
    rm -f Tcl_AppendStringsToObj.3
    ln StringObj.3 Tcl_AppendStringsToObj.3
127
128
129
130
131
132
133












134
135
136
137
138
139
140
    rm -f Tcl_CommandComplete.3
    ln CmdCmplt.3 Tcl_CommandComplete.3
fi
if test -r Concat.3; then
    rm -f Tcl_Concat.3
    ln Concat.3 Tcl_Concat.3
fi












if test -r SplitList.3; then
    rm -f Tcl_ConvertElement.3
    ln SplitList.3 Tcl_ConvertElement.3
fi
if test -r ObjectType.3; then
    rm -f Tcl_ConvertToType.3
    ln ObjectType.3 Tcl_ConvertToType.3







>
>
>
>
>
>
>
>
>
>
>
>







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
    rm -f Tcl_CommandComplete.3
    ln CmdCmplt.3 Tcl_CommandComplete.3
fi
if test -r Concat.3; then
    rm -f Tcl_Concat.3
    ln Concat.3 Tcl_Concat.3
fi
if test -r StringObj.3; then
    rm -f Tcl_ConcatObj.3
    ln StringObj.3 Tcl_ConcatObj.3
fi
if test -r Thread.3; then
    rm -f Tcl_ConditionNotify.3
    ln Thread.3 Tcl_ConditionNotify.3
fi
if test -r Thread.3; then
    rm -f Tcl_ConditionWait.3
    ln Thread.3 Tcl_ConditionWait.3
fi
if test -r SplitList.3; then
    rm -f Tcl_ConvertElement.3
    ln SplitList.3 Tcl_ConvertElement.3
fi
if test -r ObjectType.3; then
    rm -f Tcl_ConvertToType.3
    ln ObjectType.3 Tcl_ConvertToType.3
159
160
161
162
163
164
165




166
167
168
169
170
171
172
    rm -f Tcl_CreateCloseHandler.3
    ln CrtCloseHdlr.3 Tcl_CreateCloseHandler.3
fi
if test -r CrtCommand.3; then
    rm -f Tcl_CreateCommand.3
    ln CrtCommand.3 Tcl_CreateCommand.3
fi




if test -r Notifier.3; then
    rm -f Tcl_CreateEventSource.3
    ln Notifier.3 Tcl_CreateEventSource.3
fi
if test -r Exit.3; then
    rm -f Tcl_CreateExitHandler.3
    ln Exit.3 Tcl_CreateExitHandler.3







>
>
>
>







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
    rm -f Tcl_CreateCloseHandler.3
    ln CrtCloseHdlr.3 Tcl_CreateCloseHandler.3
fi
if test -r CrtCommand.3; then
    rm -f Tcl_CreateCommand.3
    ln CrtCommand.3 Tcl_CreateCommand.3
fi
if test -r Encoding.3; then
    rm -f Tcl_CreateEncoding.3
    ln Encoding.3 Tcl_CreateEncoding.3
fi
if test -r Notifier.3; then
    rm -f Tcl_CreateEventSource.3
    ln Notifier.3 Tcl_CreateEventSource.3
fi
if test -r Exit.3; then
    rm -f Tcl_CreateExitHandler.3
    ln Exit.3 Tcl_CreateExitHandler.3
191
192
193
194
195
196
197




198
199
200
201
202
203
204
205




206
207
208
209
210
211
212
    rm -f Tcl_CreateObjCommand.3
    ln CrtObjCmd.3 Tcl_CreateObjCommand.3
fi
if test -r CrtSlave.3; then
    rm -f Tcl_CreateSlave.3
    ln CrtSlave.3 Tcl_CreateSlave.3
fi




if test -r CrtTimerHdlr.3; then
    rm -f Tcl_CreateTimerHandler.3
    ln CrtTimerHdlr.3 Tcl_CreateTimerHandler.3
fi
if test -r CrtTrace.3; then
    rm -f Tcl_CreateTrace.3
    ln CrtTrace.3 Tcl_CreateTrace.3
fi




if test -r DString.3; then
    rm -f Tcl_DStringAppend.3
    ln DString.3 Tcl_DStringAppend.3
fi
if test -r DString.3; then
    rm -f Tcl_DStringAppendElement.3
    ln DString.3 Tcl_DStringAppendElement.3







>
>
>
>








>
>
>
>







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
    rm -f Tcl_CreateObjCommand.3
    ln CrtObjCmd.3 Tcl_CreateObjCommand.3
fi
if test -r CrtSlave.3; then
    rm -f Tcl_CreateSlave.3
    ln CrtSlave.3 Tcl_CreateSlave.3
fi
if test -r Exit.3; then
    rm -f Tcl_CreateThreadExitHandler.3
    ln Exit.3 Tcl_CreateThreadExitHandler.3
fi
if test -r CrtTimerHdlr.3; then
    rm -f Tcl_CreateTimerHandler.3
    ln CrtTimerHdlr.3 Tcl_CreateTimerHandler.3
fi
if test -r CrtTrace.3; then
    rm -f Tcl_CreateTrace.3
    ln CrtTrace.3 Tcl_CreateTrace.3
fi
if test -r CrtVersion.3; then
    rm -f Tcl_GetVersion.3
    ln CrtVersion.3 Tcl_GetVersion.3
fi
if test -r DString.3; then
    rm -f Tcl_DStringAppend.3
    ln DString.3 Tcl_DStringAppend.3
fi
if test -r DString.3; then
    rm -f Tcl_DStringAppendElement.3
    ln DString.3 Tcl_DStringAppendElement.3
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
    rm -f Tcl_DeleteHashTable.3
    ln Hash.3 Tcl_DeleteHashTable.3
fi
if test -r CrtInterp.3; then
    rm -f Tcl_DeleteInterp.3
    ln CrtInterp.3 Tcl_DeleteInterp.3
fi




if test -r CrtTimerHdlr.3; then
    rm -f Tcl_DeleteTimerHandler.3
    ln CrtTimerHdlr.3 Tcl_DeleteTimerHandler.3
fi
if test -r CrtTrace.3; then
    rm -f Tcl_DeleteTrace.3
    ln CrtTrace.3 Tcl_DeleteTrace.3
fi
if test -r DetachPids.3; then
    rm -f Tcl_DetachPids.3
    ln DetachPids.3 Tcl_DetachPids.3
fi




if test -r DoOneEvent.3; then
    rm -f Tcl_DoOneEvent.3
    ln DoOneEvent.3 Tcl_DoOneEvent.3
fi
if test -r DoWhenIdle.3; then
    rm -f Tcl_DoWhenIdle.3
    ln DoWhenIdle.3 Tcl_DoWhenIdle.3







>
>
>
>












>
>
>
>







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
    rm -f Tcl_DeleteHashTable.3
    ln Hash.3 Tcl_DeleteHashTable.3
fi
if test -r CrtInterp.3; then
    rm -f Tcl_DeleteInterp.3
    ln CrtInterp.3 Tcl_DeleteInterp.3
fi
if test -r Exit.3; then
    rm -f Tcl_DeleteThreadExitHandler.3
    ln Exit.3 Tcl_DeleteThreadExitHandler.3
fi
if test -r CrtTimerHdlr.3; then
    rm -f Tcl_DeleteTimerHandler.3
    ln CrtTimerHdlr.3 Tcl_DeleteTimerHandler.3
fi
if test -r CrtTrace.3; then
    rm -f Tcl_DeleteTrace.3
    ln CrtTrace.3 Tcl_DeleteTrace.3
fi
if test -r DetachPids.3; then
    rm -f Tcl_DetachPids.3
    ln DetachPids.3 Tcl_DetachPids.3
fi
if test -r SaveResult.3; then
    rm -f Tcl_DiscardResult.3
    ln SaveResult.3 Tcl_DiscardResult.3
fi
if test -r DoOneEvent.3; then
    rm -f Tcl_DoOneEvent.3
    ln DoOneEvent.3 Tcl_DoOneEvent.3
fi
if test -r DoWhenIdle.3; then
    rm -f Tcl_DoWhenIdle.3
    ln DoWhenIdle.3 Tcl_DoWhenIdle.3
331
332
333
334
335
336
337




338
339
340
341
342
343
344








345
346
347
348
349
350
351
    rm -f Tcl_Eof.3
    ln OpenFileChnl.3 Tcl_Eof.3
fi
if test -r Eval.3; then
    rm -f Tcl_Eval.3
    ln Eval.3 Tcl_Eval.3
fi




if test -r Eval.3; then
    rm -f Tcl_EvalFile.3
    ln Eval.3 Tcl_EvalFile.3
fi
if test -r EvalObj.3; then
    rm -f Tcl_EvalObj.3
    ln EvalObj.3 Tcl_EvalObj.3








fi
if test -r Preserve.3; then
    rm -f Tcl_EventuallyFree.3
    ln Preserve.3 Tcl_EventuallyFree.3
fi
if test -r Exit.3; then
    rm -f Tcl_Exit.3







>
>
>
>




|

|
>
>
>
>
>
>
>
>







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
    rm -f Tcl_Eof.3
    ln OpenFileChnl.3 Tcl_Eof.3
fi
if test -r Eval.3; then
    rm -f Tcl_Eval.3
    ln Eval.3 Tcl_Eval.3
fi
if test -r Eval.3; then
    rm -f Tcl_Eval2.3
    ln Eval.3 Tcl_Eval2.3
fi
if test -r Eval.3; then
    rm -f Tcl_EvalFile.3
    ln Eval.3 Tcl_EvalFile.3
fi
if test -r Eval.3; then
    rm -f Tcl_EvalObj.3
    ln Eval.3 Tcl_EvalObj.3
fi
if test -r Eval.3; then
    rm -f Tcl_EvalObjv.3
    ln Eval.3 Tcl_EvalObjv.3
fi
if test -r ParseCmd.3; then
    rm -f Tcl_EvalTokens.3
    ln ParseCmd.3 Tcl_EvalTokens.3
fi
if test -r Preserve.3; then
    rm -f Tcl_EventuallyFree.3
    ln Preserve.3 Tcl_EventuallyFree.3
fi
if test -r Exit.3; then
    rm -f Tcl_Exit.3
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
    rm -f Tcl_ExprObj.3
    ln ExprLongObj.3 Tcl_ExprObj.3
fi
if test -r ExprLong.3; then
    rm -f Tcl_ExprString.3
    ln ExprLong.3 Tcl_ExprString.3
fi








if test -r Exit.3; then
    rm -f Tcl_Finalize.3
    ln Exit.3 Tcl_Finalize.3
fi




if test -r FindExec.3; then
    rm -f Tcl_FindExecutable.3
    ln FindExec.3 Tcl_FindExecutable.3
fi
if test -r Hash.3; then
    rm -f Tcl_FindHashEntry.3
    ln Hash.3 Tcl_FindHashEntry.3
fi
if test -r Hash.3; then
    rm -f Tcl_FirstHashEntry.3
    ln Hash.3 Tcl_FirstHashEntry.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_Flush.3
    ln OpenFileChnl.3 Tcl_Flush.3
fi
if test -r Alloc.3; then
    rm -f Tcl_Free.3
    ln Alloc.3 Tcl_Free.3
fi








if test -r CrtSlave.3; then
    rm -f Tcl_GetAlias.3
    ln CrtSlave.3 Tcl_GetAlias.3
fi
if test -r CrtSlave.3; then
    rm -f Tcl_GetAliasObj.3
    ln CrtSlave.3 Tcl_GetAliasObj.3
fi
if test -r AssocData.3; then
    rm -f Tcl_GetAssocData.3
    ln AssocData.3 Tcl_GetAssocData.3
fi
if test -r GetInt.3; then
    rm -f Tcl_GetBoolean.3
    ln GetInt.3 Tcl_GetBoolean.3
fi
if test -r BoolObj.3; then
    rm -f Tcl_GetBooleanFromObj.3
    ln BoolObj.3 Tcl_GetBooleanFromObj.3
fi




if test -r OpenFileChnl.3; then
    rm -f Tcl_GetChannel.3
    ln OpenFileChnl.3 Tcl_GetChannel.3
fi
if test -r CrtChannel.3; then
    rm -f Tcl_GetChannelBufferSize.3
    ln CrtChannel.3 Tcl_GetChannelBufferSize.3







>
>
>
>
>
>
>
>




>
>
>
>




















>
>
>
>
>
>
>
>




















>
>
>
>







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
    rm -f Tcl_ExprObj.3
    ln ExprLongObj.3 Tcl_ExprObj.3
fi
if test -r ExprLong.3; then
    rm -f Tcl_ExprString.3
    ln ExprLong.3 Tcl_ExprString.3
fi
if test -r Encoding.3; then
    rm -f Tcl_ExternalToUtf.3
    ln Encoding.3 Tcl_ExternalToUtf.3
fi
if test -r Encoding.3; then
    rm -f Tcl_ExternalToUtfDString.3
    ln Encoding.3 Tcl_ExternalToUtfDString.3
fi
if test -r Exit.3; then
    rm -f Tcl_Finalize.3
    ln Exit.3 Tcl_Finalize.3
fi
if test -r Exit.3; then
    rm -f Tcl_FinalizeThread.3
    ln Exit.3 Tcl_FinalizeThread.3
fi
if test -r FindExec.3; then
    rm -f Tcl_FindExecutable.3
    ln FindExec.3 Tcl_FindExecutable.3
fi
if test -r Hash.3; then
    rm -f Tcl_FindHashEntry.3
    ln Hash.3 Tcl_FindHashEntry.3
fi
if test -r Hash.3; then
    rm -f Tcl_FirstHashEntry.3
    ln Hash.3 Tcl_FirstHashEntry.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_Flush.3
    ln OpenFileChnl.3 Tcl_Flush.3
fi
if test -r Alloc.3; then
    rm -f Tcl_Free.3
    ln Alloc.3 Tcl_Free.3
fi
if test -r Encoding.3; then
    rm -f Tcl_FreeEncoding.3
    ln Encoding.3 Tcl_FreeEncoding.3
fi
if test -r ParseCmd.3; then
    rm -f Tcl_FreeParse.3
    ln ParseCmd.3 Tcl_FreeParse.3
fi
if test -r CrtSlave.3; then
    rm -f Tcl_GetAlias.3
    ln CrtSlave.3 Tcl_GetAlias.3
fi
if test -r CrtSlave.3; then
    rm -f Tcl_GetAliasObj.3
    ln CrtSlave.3 Tcl_GetAliasObj.3
fi
if test -r AssocData.3; then
    rm -f Tcl_GetAssocData.3
    ln AssocData.3 Tcl_GetAssocData.3
fi
if test -r GetInt.3; then
    rm -f Tcl_GetBoolean.3
    ln GetInt.3 Tcl_GetBoolean.3
fi
if test -r BoolObj.3; then
    rm -f Tcl_GetBooleanFromObj.3
    ln BoolObj.3 Tcl_GetBooleanFromObj.3
fi
if test -r ByteArrObj.3; then
    rm -f Tcl_GetByteArrayFromObj.3
    ln ByteArrObj.3 Tcl_GetByteArrayFromObj.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_GetChannel.3
    ln OpenFileChnl.3 Tcl_GetChannel.3
fi
if test -r CrtChannel.3; then
    rm -f Tcl_GetChannelBufferSize.3
    ln CrtChannel.3 Tcl_GetChannelBufferSize.3
475
476
477
478
479
480
481












482
483
484
485
486
487
488
    rm -f Tcl_GetDouble.3
    ln GetInt.3 Tcl_GetDouble.3
fi
if test -r DoubleObj.3; then
    rm -f Tcl_GetDoubleFromObj.3
    ln DoubleObj.3 Tcl_GetDoubleFromObj.3
fi












if test -r SetErrno.3; then
    rm -f Tcl_GetErrno.3
    ln SetErrno.3 Tcl_GetErrno.3
fi
if test -r Hash.3; then
    rm -f Tcl_GetHashKey.3
    ln Hash.3 Tcl_GetHashKey.3







>
>
>
>
>
>
>
>
>
>
>
>







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
    rm -f Tcl_GetDouble.3
    ln GetInt.3 Tcl_GetDouble.3
fi
if test -r DoubleObj.3; then
    rm -f Tcl_GetDoubleFromObj.3
    ln DoubleObj.3 Tcl_GetDoubleFromObj.3
fi
if test -r Encoding.3; then
    rm -f Tcl_GetEncoding.3
    ln Encoding.3 Tcl_GetEncoding.3
fi
if test -r Encoding.3; then
    rm -f Tcl_GetEncodingName.3
    ln Encoding.3 Tcl_GetEncodingName.3
fi
if test -r Encoding.3; then
    rm -f Tcl_GetEncodingNames.3
    ln Encoding.3 Tcl_GetEncodingNames.3
fi
if test -r SetErrno.3; then
    rm -f Tcl_GetErrno.3
    ln SetErrno.3 Tcl_GetErrno.3
fi
if test -r Hash.3; then
    rm -f Tcl_GetHashKey.3
    ln Hash.3 Tcl_GetHashKey.3
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
    rm -f Tcl_GetSlave.3
    ln CrtSlave.3 Tcl_GetSlave.3
fi
if test -r GetStdChan.3; then
    rm -f Tcl_GetStdChannel.3
    ln GetStdChan.3 Tcl_GetStdChannel.3
fi




if test -r StringObj.3; then
    rm -f Tcl_GetStringFromObj.3
    ln StringObj.3 Tcl_GetStringFromObj.3
fi
if test -r SetResult.3; then
    rm -f Tcl_GetStringResult.3
    ln SetResult.3 Tcl_GetStringResult.3
fi




if test -r SetVar.3; then
    rm -f Tcl_GetVar.3
    ln SetVar.3 Tcl_GetVar.3
fi
if test -r SetVar.3; then
    rm -f Tcl_GetVar2.3
    ln SetVar.3 Tcl_GetVar2.3
fi




if test -r OpenFileChnl.3; then
    rm -f Tcl_Gets.3
    ln OpenFileChnl.3 Tcl_Gets.3
fi




if test -r Eval.3; then
    rm -f Tcl_GlobalEval.3
    ln Eval.3 Tcl_GlobalEval.3
fi
if test -r EvalObj.3; then
    rm -f Tcl_GlobalEvalObj.3
    ln EvalObj.3 Tcl_GlobalEvalObj.3
fi
if test -r Hash.3; then
    rm -f Tcl_HashStats.3
    ln Hash.3 Tcl_HashStats.3
fi
if test -r CrtSlave.3; then
    rm -f Tcl_HideCommand.3
    ln CrtSlave.3 Tcl_HideCommand.3







>
>
>
>








>
>
>
>








>
>
>
>




>
>
>
>




<
<
<
<







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
    rm -f Tcl_GetSlave.3
    ln CrtSlave.3 Tcl_GetSlave.3
fi
if test -r GetStdChan.3; then
    rm -f Tcl_GetStdChannel.3
    ln GetStdChan.3 Tcl_GetStdChannel.3
fi
if test -r StringObj.3; then
    rm -f Tcl_GetString.3
    ln StringObj.3 Tcl_GetString.3
fi
if test -r StringObj.3; then
    rm -f Tcl_GetStringFromObj.3
    ln StringObj.3 Tcl_GetStringFromObj.3
fi
if test -r SetResult.3; then
    rm -f Tcl_GetStringResult.3
    ln SetResult.3 Tcl_GetStringResult.3
fi
if test -r Thread.3; then
    rm -f Tcl_GetThreadData.3
    ln Thread.3 Tcl_GetThreadData.3
fi
if test -r SetVar.3; then
    rm -f Tcl_GetVar.3
    ln SetVar.3 Tcl_GetVar.3
fi
if test -r SetVar.3; then
    rm -f Tcl_GetVar2.3
    ln SetVar.3 Tcl_GetVar2.3
fi
if test -r SetVar.3; then
    rm -f Tcl_GetVar2Ex.3
    ln SetVar.3 Tcl_GetVar2Ex.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_Gets.3
    ln OpenFileChnl.3 Tcl_Gets.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_GetsObj.3
    ln OpenFileChnl.3 Tcl_GetsObj.3
fi
if test -r Eval.3; then
    rm -f Tcl_GlobalEval.3
    ln Eval.3 Tcl_GlobalEval.3
fi




if test -r Hash.3; then
    rm -f Tcl_HashStats.3
    ln Hash.3 Tcl_HashStats.3
fi
if test -r CrtSlave.3; then
    rm -f Tcl_HideCommand.3
    ln CrtSlave.3 Tcl_HideCommand.3
655
656
657
658
659
660
661








662
663
664
665




666
667
668
669
670
671
672
    rm -f Tcl_MakeTcpClientChannel.3
    ln OpenTcp.3 Tcl_MakeTcpClientChannel.3
fi
if test -r SplitList.3; then
    rm -f Tcl_Merge.3
    ln SplitList.3 Tcl_Merge.3
fi








if test -r BoolObj.3; then
    rm -f Tcl_NewBooleanObj.3
    ln BoolObj.3 Tcl_NewBooleanObj.3
fi




if test -r DoubleObj.3; then
    rm -f Tcl_NewDoubleObj.3
    ln DoubleObj.3 Tcl_NewDoubleObj.3
fi
if test -r IntObj.3; then
    rm -f Tcl_NewIntObj.3
    ln IntObj.3 Tcl_NewIntObj.3







>
>
>
>
>
>
>
>




>
>
>
>







747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
    rm -f Tcl_MakeTcpClientChannel.3
    ln OpenTcp.3 Tcl_MakeTcpClientChannel.3
fi
if test -r SplitList.3; then
    rm -f Tcl_Merge.3
    ln SplitList.3 Tcl_Merge.3
fi
if test -r Thread.3; then
    rm -f Tcl_MutexLock.3
    ln Thread.3 Tcl_MutexLock.3
fi
if test -r Thread.3; then
    rm -f Tcl_MutexUnlock.3
    ln Thread.3 Tcl_MutexUnlock.3
fi
if test -r BoolObj.3; then
    rm -f Tcl_NewBooleanObj.3
    ln BoolObj.3 Tcl_NewBooleanObj.3
fi
if test -r ByteArrObj.3; then
    rm -f Tcl_NewByteArrayObj.3
    ln ByteArrObj.3 Tcl_NewByteArrayObj.3
fi
if test -r DoubleObj.3; then
    rm -f Tcl_NewDoubleObj.3
    ln DoubleObj.3 Tcl_NewDoubleObj.3
fi
if test -r IntObj.3; then
    rm -f Tcl_NewIntObj.3
    ln IntObj.3 Tcl_NewIntObj.3
691
692
693
694
695
696
697




698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721




















722
723
724
725
726
727
728
    rm -f Tcl_NextHashEntry.3
    ln Hash.3 Tcl_NextHashEntry.3
fi
if test -r CrtChannel.3; then
    rm -f Tcl_NotifyChannel.3
    ln CrtChannel.3 Tcl_NotifyChannel.3
fi




if test -r ObjSetVar.3; then
    rm -f Tcl_ObjGetVar2.3
    ln ObjSetVar.3 Tcl_ObjGetVar2.3
fi
if test -r ObjSetVar.3; then
    rm -f Tcl_ObjSetVar2.3
    ln ObjSetVar.3 Tcl_ObjSetVar2.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_OpenCommandChannel.3
    ln OpenFileChnl.3 Tcl_OpenCommandChannel.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_OpenFileChannel.3
    ln OpenFileChnl.3 Tcl_OpenFileChannel.3
fi
if test -r OpenTcp.3; then
    rm -f Tcl_OpenTcpClient.3
    ln OpenTcp.3 Tcl_OpenTcpClient.3
fi
if test -r OpenTcp.3; then
    rm -f Tcl_OpenTcpServer.3
    ln OpenTcp.3 Tcl_OpenTcpServer.3
fi




















if test -r PkgRequire.3; then
    rm -f Tcl_PkgProvide.3
    ln PkgRequire.3 Tcl_PkgProvide.3
fi
if test -r PkgRequire.3; then
    rm -f Tcl_PkgRequire.3
    ln PkgRequire.3 Tcl_PkgRequire.3







>
>
>
>
|

|

|

|

















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
    rm -f Tcl_NextHashEntry.3
    ln Hash.3 Tcl_NextHashEntry.3
fi
if test -r CrtChannel.3; then
    rm -f Tcl_NotifyChannel.3
    ln CrtChannel.3 Tcl_NotifyChannel.3
fi
if test -r Utf.3; then
    rm -f Tcl_NumUtfChars.3
    ln Utf.3 Tcl_NumUtfChars.3
fi
if test -r SetVar.3; then
    rm -f Tcl_ObjGetVar2.3
    ln SetVar.3 Tcl_ObjGetVar2.3
fi
if test -r SetVar.3; then
    rm -f Tcl_ObjSetVar2.3
    ln SetVar.3 Tcl_ObjSetVar2.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_OpenCommandChannel.3
    ln OpenFileChnl.3 Tcl_OpenCommandChannel.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_OpenFileChannel.3
    ln OpenFileChnl.3 Tcl_OpenFileChannel.3
fi
if test -r OpenTcp.3; then
    rm -f Tcl_OpenTcpClient.3
    ln OpenTcp.3 Tcl_OpenTcpClient.3
fi
if test -r OpenTcp.3; then
    rm -f Tcl_OpenTcpServer.3
    ln OpenTcp.3 Tcl_OpenTcpServer.3
fi
if test -r ParseCmd.3; then
    rm -f Tcl_ParseBraces.3
    ln ParseCmd.3 Tcl_ParseBraces.3
fi
if test -r ParseCmd.3; then
    rm -f Tcl_ParseCommand.3
    ln ParseCmd.3 Tcl_ParseCommand.3
fi
if test -r ParseCmd.3; then
    rm -f Tcl_ParseExpr.3
    ln ParseCmd.3 Tcl_ParseExpr.3
fi
if test -r ParseCmd.3; then
    rm -f Tcl_ParseQuotedString.3
    ln ParseCmd.3 Tcl_ParseQuotedString.3
fi
if test -r ParseCmd.3; then
    rm -f Tcl_ParseVarName.3
    ln ParseCmd.3 Tcl_ParseVarName.3
fi
if test -r PkgRequire.3; then
    rm -f Tcl_PkgProvide.3
    ln PkgRequire.3 Tcl_PkgProvide.3
fi
if test -r PkgRequire.3; then
    rm -f Tcl_PkgRequire.3
    ln PkgRequire.3 Tcl_PkgRequire.3
743
744
745
746
747
748
749




750
751
752
753
754
755
756
    rm -f Tcl_QueueEvent.3
    ln Notifier.3 Tcl_QueueEvent.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_Read.3
    ln OpenFileChnl.3 Tcl_Read.3
fi




if test -r Alloc.3; then
    rm -f Tcl_Realloc.3
    ln Alloc.3 Tcl_Realloc.3
fi
if test -r DetachPids.3; then
    rm -f Tcl_ReapDetachedProcs.3
    ln DetachPids.3 Tcl_ReapDetachedProcs.3







>
>
>
>







871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
    rm -f Tcl_QueueEvent.3
    ln Notifier.3 Tcl_QueueEvent.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_Read.3
    ln OpenFileChnl.3 Tcl_Read.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_ReadChars.3
    ln OpenFileChnl.3 Tcl_ReadChars.3
fi
if test -r Alloc.3; then
    rm -f Tcl_Realloc.3
    ln Alloc.3 Tcl_Realloc.3
fi
if test -r DetachPids.3; then
    rm -f Tcl_ReapDetachedProcs.3
    ln DetachPids.3 Tcl_ReapDetachedProcs.3
791
792
793
794
795
796
797








798
799
800
801
802
803
804
    rm -f Tcl_Release.3
    ln Preserve.3 Tcl_Release.3
fi
if test -r SetResult.3; then
    rm -f Tcl_ResetResult.3
    ln SetResult.3 Tcl_ResetResult.3
fi








if test -r SplitList.3; then
    rm -f Tcl_ScanElement.3
    ln SplitList.3 Tcl_ScanElement.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_Seek.3
    ln OpenFileChnl.3 Tcl_Seek.3







>
>
>
>
>
>
>
>







923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
    rm -f Tcl_Release.3
    ln Preserve.3 Tcl_Release.3
fi
if test -r SetResult.3; then
    rm -f Tcl_ResetResult.3
    ln SetResult.3 Tcl_ResetResult.3
fi
if test -r SaveResult.3; then
    rm -f Tcl_RestoreResult.3
    ln SaveResult.3 Tcl_RestoreResult.3
fi
if test -r SaveResult.3; then
    rm -f Tcl_SaveResult.3
    ln SaveResult.3 Tcl_SaveResult.3
fi
if test -r SplitList.3; then
    rm -f Tcl_ScanElement.3
    ln SplitList.3 Tcl_ScanElement.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_Seek.3
    ln OpenFileChnl.3 Tcl_Seek.3
815
816
817
818
819
820
821








822
823
824
825
826
827
828
    rm -f Tcl_SetAssocData.3
    ln AssocData.3 Tcl_SetAssocData.3
fi
if test -r BoolObj.3; then
    rm -f Tcl_SetBooleanObj.3
    ln BoolObj.3 Tcl_SetBooleanObj.3
fi








if test -r CrtChannel.3; then
    rm -f Tcl_SetChannelBufferSize.3
    ln CrtChannel.3 Tcl_SetChannelBufferSize.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_SetChannelOption.3
    ln OpenFileChnl.3 Tcl_SetChannelOption.3







>
>
>
>
>
>
>
>







955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
    rm -f Tcl_SetAssocData.3
    ln AssocData.3 Tcl_SetAssocData.3
fi
if test -r BoolObj.3; then
    rm -f Tcl_SetBooleanObj.3
    ln BoolObj.3 Tcl_SetBooleanObj.3
fi
if test -r ByteArrObj.3; then
    rm -f Tcl_SetByteArrayLength.3
    ln ByteArrObj.3 Tcl_SetByteArrayLength.3
fi
if test -r ByteArrObj.3; then
    rm -f Tcl_SetByteArrayObj.3
    ln ByteArrObj.3 Tcl_SetByteArrayObj.3
fi
if test -r CrtChannel.3; then
    rm -f Tcl_SetChannelBufferSize.3
    ln CrtChannel.3 Tcl_SetChannelBufferSize.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_SetChannelOption.3
    ln OpenFileChnl.3 Tcl_SetChannelOption.3
839
840
841
842
843
844
845




846
847
848
849
850
851
852
    rm -f Tcl_SetDoubleObj.3
    ln DoubleObj.3 Tcl_SetDoubleObj.3
fi
if test -r SetErrno.3; then
    rm -f Tcl_SetErrno.3
    ln SetErrno.3 Tcl_SetErrno.3
fi




if test -r AddErrInfo.3; then
    rm -f Tcl_SetErrorCode.3
    ln AddErrInfo.3 Tcl_SetErrorCode.3
fi
if test -r Hash.3; then
    rm -f Tcl_SetHashValue.3
    ln Hash.3 Tcl_SetHashValue.3







>
>
>
>







987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
    rm -f Tcl_SetDoubleObj.3
    ln DoubleObj.3 Tcl_SetDoubleObj.3
fi
if test -r SetErrno.3; then
    rm -f Tcl_SetErrno.3
    ln SetErrno.3 Tcl_SetErrno.3
fi
if test -r AddErrInfo.3; then
    rm -f Tcl_SetErrorCodeVA.3
    ln AddErrInfo.3 Tcl_SetErrorCodeVA.3
fi
if test -r AddErrInfo.3; then
    rm -f Tcl_SetErrorCode.3
    ln AddErrInfo.3 Tcl_SetErrorCode.3
fi
if test -r Hash.3; then
    rm -f Tcl_SetHashValue.3
    ln Hash.3 Tcl_SetHashValue.3
891
892
893
894
895
896
897




898
899
900
901
902
903
904
905
906
907
908
909




910
911
912
913
914
915
916
    rm -f Tcl_SetStdChannel.3
    ln GetStdChan.3 Tcl_SetStdChannel.3
fi
if test -r StringObj.3; then
    rm -f Tcl_SetStringObj.3
    ln StringObj.3 Tcl_SetStringObj.3
fi




if test -r Notifier.3; then
    rm -f Tcl_SetTimer.3
    ln Notifier.3 Tcl_SetTimer.3
fi
if test -r SetVar.3; then
    rm -f Tcl_SetVar.3
    ln SetVar.3 Tcl_SetVar.3
fi
if test -r SetVar.3; then
    rm -f Tcl_SetVar2.3
    ln SetVar.3 Tcl_SetVar2.3
fi




if test -r Sleep.3; then
    rm -f Tcl_Sleep.3
    ln Sleep.3 Tcl_Sleep.3
fi
if test -r SplitList.3; then
    rm -f Tcl_SplitList.3
    ln SplitList.3 Tcl_SplitList.3







>
>
>
>












>
>
>
>







1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
    rm -f Tcl_SetStdChannel.3
    ln GetStdChan.3 Tcl_SetStdChannel.3
fi
if test -r StringObj.3; then
    rm -f Tcl_SetStringObj.3
    ln StringObj.3 Tcl_SetStringObj.3
fi
if test -r Encoding.3; then
    rm -f Tcl_SetSystemEncoding.3
    ln Encoding.3 Tcl_SetSystemEncoding.3
fi
if test -r Notifier.3; then
    rm -f Tcl_SetTimer.3
    ln Notifier.3 Tcl_SetTimer.3
fi
if test -r SetVar.3; then
    rm -f Tcl_SetVar.3
    ln SetVar.3 Tcl_SetVar.3
fi
if test -r SetVar.3; then
    rm -f Tcl_SetVar2.3
    ln SetVar.3 Tcl_SetVar2.3
fi
if test -r SetVar.3; then
    rm -f Tcl_SetVar2Ex.3
    ln SetVar.3 Tcl_SetVar2Ex.3
fi
if test -r Sleep.3; then
    rm -f Tcl_Sleep.3
    ln Sleep.3 Tcl_Sleep.3
fi
if test -r SplitList.3; then
    rm -f Tcl_SplitList.3
    ln SplitList.3 Tcl_SplitList.3
939
940
941
942
943
944
945
























946
947
948
949
950
951
952
    rm -f Tcl_TraceVar2.3
    ln TraceVar.3 Tcl_TraceVar2.3
fi
if test -r Translate.3; then
    rm -f Tcl_TranslateFileName.3
    ln Translate.3 Tcl_TranslateFileName.3
fi
























if test -r LinkVar.3; then
    rm -f Tcl_UnlinkVar.3
    ln LinkVar.3 Tcl_UnlinkVar.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_UnregisterChannel.3
    ln OpenFileChnl.3 Tcl_UnregisterChannel.3







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
    rm -f Tcl_TraceVar2.3
    ln TraceVar.3 Tcl_TraceVar2.3
fi
if test -r Translate.3; then
    rm -f Tcl_TranslateFileName.3
    ln Translate.3 Tcl_TranslateFileName.3
fi
if test -r Utf.3; then
    rm -f Tcl_UniChar.3
    ln Utf.3 Tcl_UniChar.3
fi
if test -r Utf.3; then
    rm -f Tcl_UniCharAtIndex.3
    ln Utf.3 Tcl_UniCharAtIndex.3
fi
if test -r ToUpper.3; then
    rm -f Tcl_UniCharToLower.3
    ln ToUpper.3 Tcl_UniCharToLower.3
fi
if test -r ToUpper.3; then
    rm -f Tcl_UniCharToTitle.3
    ln ToUpper.3 Tcl_UniCharToTitle.3
fi
if test -r ToUpper.3; then
    rm -f Tcl_UniCharToUpper.3
    ln ToUpper.3 Tcl_UniCharToUpper.3
fi
if test -r Utf.3; then
    rm -f Tcl_UniCharToUtf.3
    ln Utf.3 Tcl_UniCharToUtf.3
fi
if test -r LinkVar.3; then
    rm -f Tcl_UnlinkVar.3
    ln LinkVar.3 Tcl_UnlinkVar.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_UnregisterChannel.3
    ln OpenFileChnl.3 Tcl_UnregisterChannel.3
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
    rm -f Tcl_UpVar2.3
    ln UpVar.3 Tcl_UpVar2.3
fi
if test -r LinkVar.3; then
    rm -f Tcl_UpdateLinkedVar.3
    ln LinkVar.3 Tcl_UpdateLinkedVar.3
fi




















































if test -r Eval.3; then
    rm -f Tcl_VarEval.3
    ln Eval.3 Tcl_VarEval.3
fi
if test -r TraceVar.3; then
    rm -f Tcl_VarTraceInfo.3
    ln TraceVar.3 Tcl_VarTraceInfo.3
fi
if test -r TraceVar.3; then
    rm -f Tcl_VarTraceInfo2.3
    ln TraceVar.3 Tcl_VarTraceInfo2.3
fi
if test -r Notifier.3; then
    rm -f Tcl_WaitForEvent.3
    ln Notifier.3 Tcl_WaitForEvent.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_Write.3
    ln OpenFileChnl.3 Tcl_Write.3
fi








if test -r WrongNumArgs.3; then
    rm -f Tcl_WrongNumArgs.3
    ln WrongNumArgs.3 Tcl_WrongNumArgs.3
fi
if test -r pkgMkIndex.n; then
    rm -f pkg_mkIndex.n
    ln pkgMkIndex.n pkg_mkIndex.n
fi
exit 0







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















>
>
>
>
>
>
>
>









1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
    rm -f Tcl_UpVar2.3
    ln UpVar.3 Tcl_UpVar2.3
fi
if test -r LinkVar.3; then
    rm -f Tcl_UpdateLinkedVar.3
    ln LinkVar.3 Tcl_UpdateLinkedVar.3
fi
if test -r Utf.3; then
    rm -f Tcl_UtfAtIndex.3
    ln Utf.3 Tcl_UtfAtIndex.3
fi
if test -r Utf.3; then
    rm -f Tcl_UtfBackslash.3
    ln Utf.3 Tcl_UtfBackslash.3
fi
if test -r Utf.3; then
    rm -f Tcl_UtfCharComplete.3
    ln Utf.3 Tcl_UtfCharComplete.3
fi
if test -r Utf.3; then
    rm -f Tcl_UtfFindFirst.3
    ln Utf.3 Tcl_UtfFindFirst.3
fi
if test -r Utf.3; then
    rm -f Tcl_UtfFindLast.3
    ln Utf.3 Tcl_UtfFindLast.3
fi
if test -r Utf.3; then
    rm -f Tcl_UtfNext.3
    ln Utf.3 Tcl_UtfNext.3
fi
if test -r Utf.3; then
    rm -f Tcl_UtfPrev.3
    ln Utf.3 Tcl_UtfPrev.3
fi
if test -r Encoding.3; then
    rm -f Tcl_UtfToExternal.3
    ln Encoding.3 Tcl_UtfToExternal.3
fi
if test -r Encoding.3; then
    rm -f Tcl_UtfToExternalDString.3
    ln Encoding.3 Tcl_UtfToExternalDString.3
fi
if test -r ToUpper.3; then
    rm -f Tcl_UtfToLower.3
    ln ToUpper.3 Tcl_UtfToLower.3
fi
if test -r ToUpper.3; then
    rm -f Tcl_UtfToTitle.3
    ln ToUpper.3 Tcl_UtfToTitle.3
fi
if test -r Utf.3; then
    rm -f Tcl_UtfToUniChar.3
    ln Utf.3 Tcl_UtfToUniChar.3
fi
if test -r ToUpper.3; then
    rm -f Tcl_UtfToUpper.3
    ln ToUpper.3 Tcl_UtfToUpper.3
fi
if test -r Eval.3; then
    rm -f Tcl_VarEval.3
    ln Eval.3 Tcl_VarEval.3
fi
if test -r TraceVar.3; then
    rm -f Tcl_VarTraceInfo.3
    ln TraceVar.3 Tcl_VarTraceInfo.3
fi
if test -r TraceVar.3; then
    rm -f Tcl_VarTraceInfo2.3
    ln TraceVar.3 Tcl_VarTraceInfo2.3
fi
if test -r Notifier.3; then
    rm -f Tcl_WaitForEvent.3
    ln Notifier.3 Tcl_WaitForEvent.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_Write.3
    ln OpenFileChnl.3 Tcl_Write.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_WriteChars.3
    ln OpenFileChnl.3 Tcl_WriteChars.3
fi
if test -r OpenFileChnl.3; then
    rm -f Tcl_WriteObj.3
    ln OpenFileChnl.3 Tcl_WriteObj.3
fi
if test -r WrongNumArgs.3; then
    rm -f Tcl_WrongNumArgs.3
    ln WrongNumArgs.3 Tcl_WrongNumArgs.3
fi
if test -r pkgMkIndex.n; then
    rm -f pkg_mkIndex.n
    ln pkgMkIndex.n pkg_mkIndex.n
fi
exit 0

Changes to unix/porting.notes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
This file contains a collection of notes that various people have
provided about porting Tcl to various machines and operating systems.
I don't have personal access to any of these machines, so I make
no guarantees that the notes are correct, complete, or up-to-date.
If you see the word "I" in any explanations, it refers to the person
who contributed the information, not to me;  this means that I
probably can't answer any questions about any of this stuff.  In
some cases, a person has volunteered to act as a contact point for
questions about porting Tcl to a particular machine;  in these
cases the person's name and e-mail address are listed.  I'm
interested in getting new porting information to add to the file;
please mail updates to "[email protected]".

This file reflects information provided for Tcl 7.4 and later releases (8.x).
If there is no information for your configuration in this file, check
the file "porting.old" too;  it contains information that was
submitted for Tcl 7.3 and earlier releases, and some of that information
may still be valid.

A new porting database has recently become available on the Web at
the following URL:
    http://www.sunlabs.com/cgi-bin/tcl/info.8.0
This page provides information about the platforms on which Tcl and
and Tk 8.0 have been compiled and what changes were needed to get Tcl
and Tk to compile.  You can also add new entries to that database
when you install Tcl and Tk on a new platform.  The Web database is
likely to be more up-to-date than this file.

sccsid = SCCS: @(#) porting.notes 1.20 97/11/03 09:43:40

--------------------------------------------
Solaris, various versions
--------------------------------------------

1. If typing "make test" results in an error message saying that
there are no "*.test" files, or you get lots of globbing errors,
it's probably because your system doesn't have cc installed and
you used gcc.  In order for this to work, you have to set your
CC environment variable to gcc and your CPP environment variable
to "gcc -E" before running the configure script.

2. Make sure that /usr/ucb is not in your PATH or LD_LIBRARY_PATH
environment variables;  this will cause confusion between the new
Solaris libraries and older UCB versions (Tcl will expect one version
and get another).

3. There have been several reports of problems with the "glob" command.
So far these reports have all been for older versions of Tcl, but
if you run into problems, edit the Makefile after "configure" is
run and add "-DNO_DIRENT_H=1" to the definitions of DEFS.  Do this
before compiling.

--------------------------------------------
SunOS 4 and potentially other OSes
--------------------------------------------

On systems where both getcwd(3) and getwd(3) exist, check the man
page and if getcwd, like on SunOS 4, uses popen to pwd(1)
add -DUSEGETWD to the flags CFLAGS so getwd will be used instead.

That is, change the CFLAGS = -O line so it reads 
CFLAGS = -O -DUSEGETWD

--------------------------------------------
Linux, ELF, various versions/distributions
--------------------------------------------

If ./configure --enable-shared complains it can not do a shared
library you might have to make the following symbolic link:
ln -s /lib/libdl.so.1 /lib/libdl.so
then remove config.cache and re run configure.

--------------------------------------------
Pyramid DC/OSx SVr4, DC/OSx version 94c079
--------------------------------------------

Tcl seems to dump core in cmdinfo.test when compiled with the
optimiser turned on in TclEval which calls 'free'.  To get around
this, turn the optimiser off.

--------------------------------------------
SGI machines, IRIX 5.2, 5.3, IRIX64 6.0.1
--------------------------------------------

1. If you compile with gcc-2.6.3 under some versions of IRIX (e.g.
   4.0.5), DBL_MAX is defined too large for gcc and Tcl complains
   about all floating-point values being too large to represent.
   If this happens, redefining DBL_MAX to 9.99e299.

2. Add "-D_BSD_TIME" to CFLAGS in Makefile.  This avoids type conflicts
in the prototype for the gettimeofday procedure.

2. If you're running under Irix 6.x and tclsh dumps core, try
removing -O from the CFLAGS in Makefile and recompiling;  compiler
optimizations seem to cause problems on some machines.

--------------------------------------------
IBM RTs, AOS
--------------------------------------------

1. Steal fmod from 4.4BSD
2. Add a #define to tclExpr such that:
extern double fmod(); 
is defined conditionally on ibm032

--------------------------------------------
QNX 4.22
--------------------------------------------

tclPort.h
	- commented out 2 lines containing #include <sys/param.h>

tcl.h
	- changed  #define VARARGS ()
	- to       #ifndef __QNX__
	             #define VARARGS ()
	           #else
	             #define VARARGS (void *, ...)
	           #endif

--------------------------------------------
Interactive UNIX
--------------------------------------------

Add the switch -Xp to LIBS in Makefile;  otherwise strftime will not
be found when linking.

--------------------------------------------
Motorola SVR4 V4.2 (m88k)
--------------------------------------------

For Motorola Unix R40V4.2 (m88k architechure), use /usr/ucb/cc instead of
/usr/bin/cc.  Otherwise, the compile will fail because of conflicts over
the gettimeofday() call.

Also, -DNO_DIRENT_H=1 is required for the "glob" command to work.

--------------------------------------------
NeXTSTEP 3.x
--------------------------------------------

Here's the set of changes I made to make 7.5b3 compile cleanly on
NeXTSTEP3.x.

Here are a couple lines from unix/Makefile:

# Added utsname.o, which implements a uname() emulation for NeXTSTEP.
COMPAT_OBJS =		 getcwd.o strtod.o tmpnam.o utsname.o

TCL_NAMES=\
	-Dstrtod=tcl_strtod -Dtmpnam=tcl_tmpnam -Dgetcwd=tcl_getcwd \
	-Dpanic=tcl_panic -Dmatherr=tcl_matherr \
	-Duname=tcl_uname -Dutsname=tcl_utsname

# Added mode_t, pid_t, and O_NONBLOCK definitions.
AC_FLAGS =		 -DNO_DIRENT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_TIME_H=1  
-DTIME_WITH_SYS_TIME=1 -DHAVE_TM_ZONE=1 -DHAVE_TM_GMTOFF=1 -DHAVE_TIMEZONE_VAR=1  
-DSTDC_HEADERS=1 -Dmode_t=int -Dpid_t=int -DO_NONBLOCK=O_NDELAY ${TCL_NAMES}


Here are diffs for other files.  utsname.[hc] are a couple files I added
to compat/  I'm not clear whether that's where they legitimately belong
- I considered stashing them in tclLoadNext.c instead.  The tclIO.c
change was a bug, I believe, which I reported on comp.lang.tcl and
has apparently been noted and fixed.  The objc_loadModules() change
allows "load" to load object code containing Objective-C code in
addition to plain C code.

---
scott hess <[email protected]> (WWW to "http://www.winternet.com/~shess/")
Work: 12550 Portland Avenue South #121, Burnsville, MN  55337  (612)895-1208


diff -rc tcl7.5b3.orig/compat/utsname.c tcl7.5b3/compat/utsname.c
*** tcl7.5b3.orig/compat/utsname.c	Tue Apr  2 13:57:23 1996
--- tcl7.5b3/compat/utsname.c	Mon Mar 18 11:05:54 1996
***************
*** 0 ****
--- 1,27 ----
+ /*
+  * utsname.c --
+  *
+  *	This file is an emulation of the POSIX uname() function
+  *	under NeXTSTEP 3.x.
+  *
+  */
+ 

+ #include "utsname.h"
+ #include <mach-o/arch.h>
+ #include <stdio.h>
+ 

+ int uname( struct utsname *name)
+ {
+     const NXArchInfo *arch;
+     if( gethostname( name->nodename, sizeof( name->nodename))==-1) {
+ 	return -1;
+     }
+     if( (arch=NXGetLocalArchInfo())==NULL) {
+ 	return -1;
+     }
+     strncpy( name->machine, arch->description, sizeof( name->machine));
+     strcpy( name->sysname, "NEXTSTEP");
+     strcpy( name->release, "0");
+     strcpy( name->version, "3");
+     return 0;
+ }
diff -rc tcl7.5b3.orig/compat/utsname.h tcl7.5b3/compat/utsname.h
*** tcl7.5b3.orig/compat/utsname.h	Tue Apr  2 13:57:26 1996
--- tcl7.5b3/compat/utsname.h	Mon Mar 18 10:34:05 1996
***************
*** 0 ****
--- 1,22 ----
+ /*
+  * utsname.h --
+  *
+  *	This file is an emulation of the POSIX uname() function
+  *	under NeXTSTEP.
+  *
+  */
+ 

+ #ifndef _UTSNAME
+ #define _UTSNAME
+ 

+ struct utsname {
+     char sysname[ 32];
+     char nodename[ 32];
+     char release[ 32];
+     char version[ 32];
+     char machine[ 32];
+ };
+ 

+ extern int uname( struct utsname *name);
+ 

+ #endif /* _UTSNAME */
diff -rc tcl7.5b3.orig/generic/tclIO.c tcl7.5b3/generic/tclIO.c
*** tcl7.5b3.orig/generic/tclIO.c	Fri Mar  8 12:59:53 1996
--- tcl7.5b3/generic/tclIO.c	Mon Mar 18 11:38:57 1996
***************
*** 2542,2548 ****
              }
              result = GetInput(chanPtr);
              if (result != 0) {
!                 if (result == EWOULDBLOCK) {
                      chanPtr->flags |= CHANNEL_BLOCKED;
                      return copied;
                  }
--- 2542,2548 ----
              }
              result = GetInput(chanPtr);
              if (result != 0) {
!                 if (result == EAGAIN) {
                      chanPtr->flags |= CHANNEL_BLOCKED;
                      return copied;
                  }
diff -rc tcl7.5b3.orig/unix/tclLoadNext.c tcl7.5b3/unix/tclLoadNext.c
*** tcl7.5b3.orig/unix/tclLoadNext.c	Sat Feb 17 16:16:42 1996
--- tcl7.5b3/unix/tclLoadNext.c	Mon Mar 18 10:02:36 1996
***************
*** 55,61 ****
    char *files[]={fileName,NULL};
    NXStream *errorStream=NXOpenMemory(0,0,NX_READWRITE);
  

!   if(!rld_load(errorStream,&header,files,NULL)) {
      NXGetMemoryBuffer(errorStream,&data,&len,&maxlen);
      Tcl_AppendResult(interp,"couldn't load file \"",fileName,"\": ",data,NULL);
      NXCloseMemory(errorStream,NX_FREEBUFFER);
--- 55,61 ----
    char *files[]={fileName,NULL};
    NXStream *errorStream=NXOpenMemory(0,0,NX_READWRITE);
  

!   if(objc_loadModules(files,errorStream,NULL,&header,NULL)) {
      NXGetMemoryBuffer(errorStream,&data,&len,&maxlen);
      Tcl_AppendResult(interp,"couldn't load file \"",fileName,"\": ",data,NULL);
      NXCloseMemory(errorStream,NX_FREEBUFFER);
diff -rc tcl7.5b3.orig/unix/tclUnixFile.c tcl7.5b3/unix/tclUnixFile.c
*** tcl7.5b3.orig/unix/tclUnixFile.c	Thu Mar  7 18:16:34 1996
--- tcl7.5b3/unix/tclUnixFile.c	Mon Mar 18 11:10:03 1996
***************
*** 31,37 ****
--- 31,41 ----
  

  static int executableNameExitHandlerSet = 0;
  

+ #if NeXT
+ #define waitpid( p, s, o) wait4( p, s, o, NULL)
+ #else
  extern pid_t waitpid _ANSI_ARGS_((pid_t pid, int *stat_loc, int options));
+ #endif
  

  /*
   * Static routines for this file:
diff -rc tcl7.5b3.orig/unix/tclUnixInit.c tcl7.5b3/unix/tclUnixInit.c
*** tcl7.5b3.orig/unix/tclUnixInit.c	Sat Feb 17 16:16:39 1996
--- tcl7.5b3/unix/tclUnixInit.c	Mon Mar 18 11:50:28 1996
***************
*** 14,20 ****
  #include "tclInt.h"
  #include "tclPort.h"
  #ifndef NO_UNAME
! #   include <sys/utsname.h>
  #endif
  #if defined(__FreeBSD__)
  #include <floatingpoint.h>
--- 14,24 ----
  #include "tclInt.h"
  #include "tclPort.h"
  #ifndef NO_UNAME
! #    if NeXT
! #        include "../compat/utsname.h"
! #    else
! #        include <sys/utsname.h>
! #    endif
  #endif
  #if defined(__FreeBSD__)
  #include <floatingpoint.h>
diff -rc tcl7.5b3.orig/unix/tclUnixPort.h tcl7.5b3/unix/tclUnixPort.h
*** tcl7.5b3.orig/unix/tclUnixPort.h	Thu Mar  7 18:16:31 1996
--- tcl7.5b3/unix/tclUnixPort.h	Mon Mar 18 11:53:14 1996
***************
*** 76,82 ****
   */
  

  #include <sys/socket.h>		/* struct sockaddr, SOCK_STREAM, ... */
! #include <sys/utsname.h>	/* uname system call. */
  #include <netinet/in.h>		/* struct in_addr, struct sockaddr_in */
  #include <arpa/inet.h>		/* inet_ntoa() */
  #include <netdb.h>		/* gethostbyname() */
--- 76,88 ----
   */
  

  #include <sys/socket.h>		/* struct sockaddr, SOCK_STREAM, ... */
! #ifndef NO_UNAME
! #    if NeXT
! #        include "../compat/utsname.h"
! #    else
! #        include <sys/utsname.h>	/* uname system call. */
! #    endif
! #endif
  #include <netinet/in.h>		/* struct in_addr, struct sockaddr_in */
  #include <arpa/inet.h>		/* inet_ntoa() */
  #include <netdb.h>		/* gethostbyname() */

--------------------------------------------
SCO Unix 3.2.4 (ODT 3.0)
--------------------------------------------
 
The macro va_start in /usr/include/stdarg.h is incorrectly terminated by
a semi-colon.  This causes compile of generic/tclBasic.c to fail.  The
best solution is to edit the definition of va_start to remove the `;'.
This will fix this file for anything you want to compile.  If you don't have
permission to edit /usr/include/stdarg.h in place, copy it to the tcl unix
directory and change it there.
 
Contact me directly if you have problems on SCO systems.
Mark Diekhans <[email protected]>
 
--------------------------------------------
SCO Unix 3.2.5 (ODT 5.0)
--------------------------------------------

Expect failures from socket tests 2.9 and 3.1.

Contact me directly if you have problems on SCO systems.
Mark Diekhans <[email protected]>
 
--------------------------------------------
Linux 1.2.13 (gcc 2.7.0, libc.so.5.0.9)
--------------------------------------------

Symptoms:

*	Some extensions could not be loaded dynamically, most
	prominently Blt 2.0

	The given error message essentially said:
	Could not resolve symbol '__eprintf'.

	(This procedure is used by the macro 'assert')

Cause

*	'__eprintf' is defined in 'libgcc.a', not 'libc.so.x.y'.
	It is therefore impossible to load it dynamically.

*	Neither tcl nor tk make use of 'assert', thereby
	preventing a static linkage.

Workaround

*	I included <assert.h> in 'tclAppInit.c' / 'tkAppInit.c'
	and then executed 'assert (argc)' just before the call
	to Tcl_Main / Tk_Main.

	This forced the static linkage of '__eprintf' and
	everything went fine from then on.

	(Something like 'assert (1)', 'assert (a==a)' is not
	sufficient, it will be optimized away).

<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
|
<
<
|
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












1



























































































2



3


4







5



6

































































































7
8


9
10








11




























































































































































































RCS: @(#) $Id: porting.notes,v 1.1.2.2 1998/12/14 21:04:38 stanton Exp $































































































This file used to contain a collection of notes that various people


had provided about porting Tcl to various machines and operating







systems.  This information is now available in the Tcl porting



database at the following location:


































































































    http://www.scriptics.com/software/install.html#Database



If you port Tcl or Tk to a new platform, you can share any information








you might have by adding a new entry to this database.
















































































































































































Changes to unix/porting.old.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
If you see the word "I" in any explanations, it refers to the person
who contributed the information, not to me;  this means that I
probably can't answer any questions about any of this stuff.  In
some cases, a person has volunteered to act as a contact point for
questions about porting Tcl to a particular machine;  in these
cases the person's name and e-mail address are listed.

sccsid = SCCS: @(#) porting.old 1.3 96/02/16 08:56:07

---------------------------------------------
Cray machines running UNICOS:
Contact: John Freeman ([email protected])
---------------------------------------------

1. There is an error in the strstr function in UNICOS such that if the







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
If you see the word "I" in any explanations, it refers to the person
who contributed the information, not to me;  this means that I
probably can't answer any questions about any of this stuff.  In
some cases, a person has volunteered to act as a contact point for
questions about porting Tcl to a particular machine;  in these
cases the person's name and e-mail address are listed.

sccsid = RCS: @(#) $Id: porting.old,v 1.1.2.1 1998/09/24 23:59:43 stanton Exp $

---------------------------------------------
Cray machines running UNICOS:
Contact: John Freeman ([email protected])
---------------------------------------------

1. There is an error in the strstr function in UNICOS such that if the

Changes to unix/tclAppInit.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
/* 
 * tclAppInit.c --
 *
 *	Provides a default version of the main program and Tcl_AppInit
 *	procedure for Tcl applications (without Tk).
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclAppInit.c 1.20 97/03/24 14:29:43
 */

#ifdef TCL_XT_TEST
#include <X11/Intrinsic.h>
#endif

#include "tcl.h"

/*
 * The following variable is a special hack that is needed in order for
 * Sun shared libraries to be used for Tcl.
 */

extern int matherr();
int *tclDummyMathPtr = (int *) matherr;


#ifdef TCL_TEST





EXTERN int		TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));




#endif /* TCL_TEST */

#ifdef TCL_XT_TEST
EXTERN int		Tclxttest_Init _ANSI_ARGS_((Tcl_Interp *interp));
#endif

/*
 *----------------------------------------------------------------------
 *
 * main --
 *








>




|


















>
>
>
>
>
|
|
>
>
>
>

>

|







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
/* 
 * tclAppInit.c --
 *
 *	Provides a default version of the main program and Tcl_AppInit
 *	procedure for Tcl applications (without Tk).
 *
 * Copyright (c) 1993 The Regents of the University of California.
 * Copyright (c) 1994-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: tclAppInit.c,v 1.1.2.4 1999/02/10 23:31:26 stanton Exp $
 */

#ifdef TCL_XT_TEST
#include <X11/Intrinsic.h>
#endif

#include "tcl.h"

/*
 * The following variable is a special hack that is needed in order for
 * Sun shared libraries to be used for Tcl.
 */

extern int matherr();
int *tclDummyMathPtr = (int *) matherr;


#ifdef TCL_TEST

#include "tclInt.h"

extern int		Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp));
extern int		Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
extern int		TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp));
extern int		Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
#ifdef TCL_THREADS
extern int		TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp));
#endif

#endif /* TCL_TEST */

#ifdef TCL_XT_TEST
extern int		Tclxttest_Init _ANSI_ARGS_((Tcl_Interp *interp));
#endif

/*
 *----------------------------------------------------------------------
 *
 * main --
 *
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
 */

int
main(argc, argv)
    int argc;			/* Number of command-line arguments. */
    char **argv;		/* Values of command-line arguments. */
{










#ifdef TCL_XT_TEST
    XtToolkitInitialize();
#endif

    Tcl_Main(argc, argv, Tcl_AppInit);
    return 0;			/* Needed only to prevent compiler warning. */
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppInit --
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in interp->result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */








>
>
>
>
>
>
>
>
>
>



>















|







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
 */

int
main(argc, argv)
    int argc;			/* Number of command-line arguments. */
    char **argv;		/* Values of command-line arguments. */
{
#ifdef TCL_TEST
    /*
     * Pass the build time location of the tcl library (to find init.tcl)
     */
    Tcl_Obj *path;
    path = Tcl_NewStringObj(TCL_BUILDTIME_LIBRARY, -1);
    TclSetLibraryPath(Tcl_NewListObj(1,&path));

#endif

#ifdef TCL_XT_TEST
    XtToolkitInitialize();
#endif

    Tcl_Main(argc, argv, Tcl_AppInit);
    return 0;			/* Needed only to prevent compiler warning. */
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppInit --
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in the interp's result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */

102
103
104
105
106
107
108










109
110
111
112
113
114
115
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
            (Tcl_PackageInitProc *) NULL);
    if (TclObjTest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }










#endif /* TCL_TEST */

    /*
     * Call the init procedures for included packages.  Each call should
     * look like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {







>
>
>
>
>
>
>
>
>
>







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
            (Tcl_PackageInitProc *) NULL);
    if (TclObjTest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
#ifdef TCL_THREADS
    if (TclThread_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
#endif
    if (Procbodytest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init,
            Procbodytest_SafeInit);
#endif /* TCL_TEST */

    /*
     * Call the init procedures for included packages.  Each call should
     * look like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {

Changes to unix/tclConfig.sh.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
# tclConfig.sh --
# 
# This shell script (for sh) is generated automatically by Tcl's
# configure script.  It will create shell variables for most of
# the configuration options discovered by the configure script.
# This script is intended to be included by the configure scripts
# for Tcl extensions so that they don't have to figure this all
# out for themselves.
#
# The information in this file is specific to a single platform.
#
# SCCS: @(#) tclConfig.sh.in 1.20 97/07/01 11:40:19

# Tcl's version number.
TCL_VERSION='@TCL_VERSION@'
TCL_MAJOR_VERSION='@TCL_MAJOR_VERSION@'
TCL_MINOR_VERSION='@TCL_MINOR_VERSION@'
TCL_PATCH_LEVEL='@TCL_PATCH_LEVEL@'

# C compiler to use for compilation.
TCL_CC='@CC@'

# -D flags for use with the C compiler.
TCL_DEFS='@DEFS@'









# Flag, 1: we built a shared lib, 0 we didn't
TCL_SHARED_BUILD=@TCL_SHARED_BUILD@

# The name of the Tcl library (may be either a .a file or a shared library):
TCL_LIB_FILE=@TCL_LIB_FILE@










# Additional libraries to use when linking Tcl.
TCL_LIBS='@DL_LIBS@ @LIBS@ @MATH_LIBS@'

# Top-level directory in which Tcl's platform-independent files are
# installed.
TCL_PREFIX='@prefix@'

# Top-level directory in which Tcl's platform-specific files (e.g.
# executables) are installed.
TCL_EXEC_PREFIX='@exec_prefix@'

# Flags to pass to cc when compiling the components of a shared library:
TCL_SHLIB_CFLAGS='@SHLIB_CFLAGS@'




# Base command to use for combining object files into a shared library:
TCL_SHLIB_LD='@SHLIB_LD@'

# Either '$LIBS' (if dependent libraries should be included when linking
# shared libraries) or an empty string.  See Tcl's configure.in for more
# explanation.
TCL_SHLIB_LD_LIBS='@SHLIB_LD_LIBS@'











|












>
>
>
>
>
>
>
>





|
>
>
>
>
>
>
>
>
>















>
>
>







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
# tclConfig.sh --
# 
# This shell script (for sh) is generated automatically by Tcl's
# configure script.  It will create shell variables for most of
# the configuration options discovered by the configure script.
# This script is intended to be included by the configure scripts
# for Tcl extensions so that they don't have to figure this all
# out for themselves.
#
# The information in this file is specific to a single platform.
#
# RCS: @(#) $Id: tclConfig.sh.in,v 1.1.2.4 1999/03/12 23:01:01 stanton Exp $

# Tcl's version number.
TCL_VERSION='@TCL_VERSION@'
TCL_MAJOR_VERSION='@TCL_MAJOR_VERSION@'
TCL_MINOR_VERSION='@TCL_MINOR_VERSION@'
TCL_PATCH_LEVEL='@TCL_PATCH_LEVEL@'

# C compiler to use for compilation.
TCL_CC='@CC@'

# -D flags for use with the C compiler.
TCL_DEFS='@DEFS@'

# If TCL was built with debugging symbols, generated libraries contain
# this string at the end of the library name (before the extension).
TCL_DBGX=@TCL_DBGX@

# Default flags used in an optimized and debuggable build, respectively.
TCL_CFLAGS_DEBUG='@CFLAGS_DEBUG@'
TCL_CFLAGS_OPTIMIZE='@CFLAGS_OPTIMIZE@'

# Flag, 1: we built a shared lib, 0 we didn't
TCL_SHARED_BUILD=@TCL_SHARED_BUILD@

# The name of the Tcl library (may be either a .a file or a shared library):
TCL_LIB_FILE='@TCL_LIB_FILE@'

# Flag to indicate whether shared libraries need export files.
TCL_NEEDS_EXP_FILE=@TCL_NEEDS_EXP_FILE@

# String that can be evaluated to generate the part of the export file
# name that comes after the "libxxx" (includes version number, if any,
# extension, and anything else needed).  May depend on the variables
# VERSION.  On most UNIX systems this is ${VERSION}.exp.
TCL_EXPORT_FILE_SUFFIX='@CFG_TCL_EXPORT_FILE_SUFFIX@'

# Additional libraries to use when linking Tcl.
TCL_LIBS='@DL_LIBS@ @LIBS@ @MATH_LIBS@'

# Top-level directory in which Tcl's platform-independent files are
# installed.
TCL_PREFIX='@prefix@'

# Top-level directory in which Tcl's platform-specific files (e.g.
# executables) are installed.
TCL_EXEC_PREFIX='@exec_prefix@'

# Flags to pass to cc when compiling the components of a shared library:
TCL_SHLIB_CFLAGS='@SHLIB_CFLAGS@'

# Extra flags to pass to cc:
TCL_EXTRA_CFLAGS='@EXTRA_CFLAGS@'

# Base command to use for combining object files into a shared library:
TCL_SHLIB_LD='@SHLIB_LD@'

# Either '$LIBS' (if dependent libraries should be included when linking
# shared libraries) or an empty string.  See Tcl's configure.in for more
# explanation.
TCL_SHLIB_LD_LIBS='@SHLIB_LD_LIBS@'
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
























# Additional object files linked with Tcl to provide compatibility
# with standard facilities from ANSI C or POSIX.
TCL_COMPAT_OBJS='@LIBOBJS@'

# Name of the ranlib program to use.
TCL_RANLIB='@RANLIB@'




# String to pass to linker to pick up the Tcl library from its
# build directory.
TCL_BUILD_LIB_SPEC='@TCL_BUILD_LIB_SPEC@'

# String to pass to linker to pick up the Tcl library from its
# installed directory.
TCL_LIB_SPEC='@TCL_LIB_SPEC@'

# Indicates whether a version numbers should be used in -l switches
# ("ok" means it's safe to use switches like -ltcl7.5;  "nodots" means
# use switches like -ltcl75).  SunOS and FreeBSD require "nodots", for
# example.
TCL_LIB_VERSIONS_OK='@TCL_LIB_VERSIONS_OK@'

# String that can be evaluated to generate the part of a shared library
# name that comes after the "libxxx" (includes version number, if any,
# extension, and anything else needed).  May depend on the variables
# VERSION and SHLIB_SUFFIX.  On most UNIX systems this is
# ${VERSION}${SHLIB_SUFFIX}.
TCL_SHARED_LIB_SUFFIX='@TCL_SHARED_LIB_SUFFIX@'

# String that can be evaluated to generate the part of an unshared library
# name that comes after the "libxxx" (includes version number, if any,
# extension, and anything else needed).  May depend on the variable
# VERSION.  On most UNIX systems this is ${VERSION}.a.
TCL_UNSHARED_LIB_SUFFIX='@TCL_UNSHARED_LIB_SUFFIX@'

# Location of the top-level source directory from which Tcl was built.
# This is the directory that contains a README file as well as
# subdirectories such as generic, unix, etc.  If Tcl was compiled in a
# different place than the directory containing the source files, this
# points to the location of the sources, not the location where Tcl was
# compiled.
TCL_SRC_DIR='@TCL_SRC_DIR@'

# List of standard directories in which to look for packages during
# "package require" commands.  Contains the "prefix" directory plus also
# the "exec_prefix" directory, if it is different.
TCL_PACKAGE_PATH='@TCL_PACKAGE_PATH@'






























>
>
>




















|





|













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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

# Additional object files linked with Tcl to provide compatibility
# with standard facilities from ANSI C or POSIX.
TCL_COMPAT_OBJS='@LIBOBJS@'

# Name of the ranlib program to use.
TCL_RANLIB='@RANLIB@'

# -l flag to pass to the linker to pick up the Tcl library
TCL_LIB_FLAG='@TCL_LIB_FLAG@'

# String to pass to linker to pick up the Tcl library from its
# build directory.
TCL_BUILD_LIB_SPEC='@TCL_BUILD_LIB_SPEC@'

# String to pass to linker to pick up the Tcl library from its
# installed directory.
TCL_LIB_SPEC='@TCL_LIB_SPEC@'

# Indicates whether a version numbers should be used in -l switches
# ("ok" means it's safe to use switches like -ltcl7.5;  "nodots" means
# use switches like -ltcl75).  SunOS and FreeBSD require "nodots", for
# example.
TCL_LIB_VERSIONS_OK='@TCL_LIB_VERSIONS_OK@'

# String that can be evaluated to generate the part of a shared library
# name that comes after the "libxxx" (includes version number, if any,
# extension, and anything else needed).  May depend on the variables
# VERSION and SHLIB_SUFFIX.  On most UNIX systems this is
# ${VERSION}${SHLIB_SUFFIX}.
TCL_SHARED_LIB_SUFFIX='@CFG_TCL_SHARED_LIB_SUFFIX@'

# String that can be evaluated to generate the part of an unshared library
# name that comes after the "libxxx" (includes version number, if any,
# extension, and anything else needed).  May depend on the variable
# VERSION.  On most UNIX systems this is ${VERSION}.a.
TCL_UNSHARED_LIB_SUFFIX='@CFG_TCL_UNSHARED_LIB_SUFFIX@'

# Location of the top-level source directory from which Tcl was built.
# This is the directory that contains a README file as well as
# subdirectories such as generic, unix, etc.  If Tcl was compiled in a
# different place than the directory containing the source files, this
# points to the location of the sources, not the location where Tcl was
# compiled.
TCL_SRC_DIR='@TCL_SRC_DIR@'

# List of standard directories in which to look for packages during
# "package require" commands.  Contains the "prefix" directory plus also
# the "exec_prefix" directory, if it is different.
TCL_PACKAGE_PATH='@TCL_PACKAGE_PATH@'

# Tcl supports stub.
TCL_SUPPORTS_STUBS=1

# The name of the Tcl stub library (.a):
TCL_STUB_LIB_FILE='@TCL_STUB_LIB_FILE@'

# -l flag to pass to the linker to pick up the Tcl stub library
TCL_STUB_LIB_FLAG='@TCL_STUB_LIB_FLAG@'

# String to pass to linker to pick up the Tcl stub library from its
# build directory.
TCL_BUILD_STUB_LIB_SPEC='@TCL_BUILD_STUB_LIB_SPEC@'

# String to pass to linker to pick up the Tcl stub library from its
# installed directory.
TCL_STUB_LIB_SPEC='@TCL_STUB_LIB_SPEC@'

# Path to the Tcl stub library in the build directory.
TCL_BUILD_STUB_LIB_PATH='@TCL_BUILD_STUB_LIB_PATH@'

# Path to the Tcl stub library in the install directory.
TCL_STUB_LIB_PATH='@TCL_STUB_LIB_PATH@'

Changes to unix/tclLoadAix.c.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *	Not derived from licensed software.

 *	Permission is granted to freely use, copy, modify, and redistribute
 *	this software, provided that the author is not construed to be liable
 *	for any results of using the software, alterations are clearly marked
 *	as such, and this notice is not modified.
 *
 * SCCS: @(#) tclLoadAix.c 1.11 96/10/07 10:41:24
 *
 * Note:  this file has been altered from the original in a few
 * ways in order to work properly with Tcl.
 */

/*
 * @(#)dlfcn.c	1.7 revision of 95/08/14  19:08:38







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *	Not derived from licensed software.

 *	Permission is granted to freely use, copy, modify, and redistribute
 *	this software, provided that the author is not construed to be liable
 *	for any results of using the software, alterations are clearly marked
 *	as such, and this notice is not modified.
 *
 * RCS: @(#) $Id: tclLoadAix.c,v 1.1.2.2 1998/09/24 23:59:43 stanton Exp $
 *
 * Note:  this file has been altered from the original in a few
 * ways in order to work properly with Tcl.
 */

/*
 * @(#)dlfcn.c	1.7 revision of 95/08/14  19:08:38
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
 */
static void caterr(char *s)
{
	register char *p = s;

	while (*p >= '0' && *p <= '9')
		p++;
	switch(atoi(s)) {
	case L_ERROR_TOOMANY:
		strcat(errbuf, "to many errors");
		break;
	case L_ERROR_NOLIB:
		strcat(errbuf, "can't load library");
		strcat(errbuf, p);
		break;
	case L_ERROR_UNDEF:
		strcat(errbuf, "can't find symbol");
		strcat(errbuf, p);
		break;
	case L_ERROR_RLDBAD:
		strcat(errbuf, "bad RLD");
		strcat(errbuf, p);
		break;
	case L_ERROR_FORMAT:
		strcat(errbuf, "bad exec format in");
		strcat(errbuf, p);
		break;
	case L_ERROR_ERRNO:
		strcat(errbuf, strerror(atoi(++p)));
		break;
	default:
		strcat(errbuf, s);
		break;
	}
}








|




















|







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
 */
static void caterr(char *s)
{
	register char *p = s;

	while (*p >= '0' && *p <= '9')
		p++;
	switch(atoi(s)) {		/* INTL: "C", UTF safe. */
	case L_ERROR_TOOMANY:
		strcat(errbuf, "to many errors");
		break;
	case L_ERROR_NOLIB:
		strcat(errbuf, "can't load library");
		strcat(errbuf, p);
		break;
	case L_ERROR_UNDEF:
		strcat(errbuf, "can't find symbol");
		strcat(errbuf, p);
		break;
	case L_ERROR_RLDBAD:
		strcat(errbuf, "bad RLD");
		strcat(errbuf, p);
		break;
	case L_ERROR_FORMAT:
		strcat(errbuf, "bad exec format in");
		strcat(errbuf, p);
		break;
	case L_ERROR_ERRNO:
		strcat(errbuf, strerror(atoi(++p)));	/* INTL: "C", UTF safe. */
		break;
	default:
		strcat(errbuf, s);
		break;
	}
}

Changes to unix/tclLoadAout.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * This work was supported in part by the ARPA Manufacturing Automation
 * and Design Engineering (MADE) Initiative through ARPA contract
 * F33615-94-C-4400.
 *
 * SCCS: @(#) tclLoadAout.c 1.9 97/02/22 14:05:01
 */

#include "tclInt.h"
#include <fcntl.h>
#ifdef HAVE_EXEC_AOUT_H
#   include <sys/exec_aout.h>
#endif







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * This work was supported in part by the ARPA Manufacturing Automation
 * and Design Engineering (MADE) Initiative through ARPA contract
 * F33615-94-C-4400.
 *
 * RCS: @(#) $Id: tclLoadAout.c,v 1.1.2.2 1998/09/24 23:59:43 stanton Exp $
 */

#include "tclInt.h"
#include <fcntl.h>
#ifdef HAVE_EXEC_AOUT_H
#   include <sys/exec_aout.h>
#endif
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
static int FindLibraries _ANSI_ARGS_((Tcl_Interp * interp, char * fileName,
				      Tcl_DString * buf));
static void UnlinkSymbolTable _ANSI_ARGS_((void));

/*
 *----------------------------------------------------------------------
 *
 * TclLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in interp->result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *







|







|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
static int FindLibraries _ANSI_ARGS_((Tcl_Interp * interp, char * fileName,
				      Tcl_DString * buf));
static void UnlinkSymbolTable _ANSI_ARGS_((void));

/*
 *----------------------------------------------------------------------
 *
 * TclpLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in the interp's result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *
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
 *	fail with an `inconsistent memory allocation' error.
 *	It perhaps ought to retry the link, but the failure has
 *	not been observed in two years of daily use of this function.
 *----------------------------------------------------------------------
 */

int
TclLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */



{
  char * inputSymbolTable;	/* Name of the file containing the 
				 * symbol table from the last link. */
  Tcl_DString linkCommandBuf;	/* Command to do the run-time relocation
				 * of the module.*/
  char * linkCommand;
  char relocatedFileName [L_tmpnam];
				/* Name of the file holding the relocated */
				/* text of the module */
  int relocatedFd;		/* File descriptor of the file holding
				 * relocated text */
  struct exec relocatedHead;	/* Header of the relocated text */
  unsigned long relocatedSize;	/* Size of the relocated text */
  char * startAddress;		/* Starting address of the module */
  DictFn dictionary;		/* Dictionary function in the load module */
  int status;			/* Status return from Tcl_ calls */
  char * p;



  /* Find the file that contains the symbols for the run-time link. */

  if (SymbolTableFile != NULL) {
    inputSymbolTable = SymbolTableFile;
  } else if (tclExecutableName == NULL) {
    Tcl_SetResult (interp, "can't find the tclsh executable", TCL_STATIC);
    return TCL_ERROR;







|


|





>
>
>


















>
>







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
 *	fail with an `inconsistent memory allocation' error.
 *	It perhaps ought to retry the link, but the failure has
 *	not been observed in two years of daily use of this function.
 *----------------------------------------------------------------------
 */

int
TclpLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code (UTF-8). */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */
    ClientData *clientDataPtr;	/* Filled with token for dynamically loaded
				 * file which will be passed back to 
				 * TclpUnloadFile() to unload the file. */
{
  char * inputSymbolTable;	/* Name of the file containing the 
				 * symbol table from the last link. */
  Tcl_DString linkCommandBuf;	/* Command to do the run-time relocation
				 * of the module.*/
  char * linkCommand;
  char relocatedFileName [L_tmpnam];
				/* Name of the file holding the relocated */
				/* text of the module */
  int relocatedFd;		/* File descriptor of the file holding
				 * relocated text */
  struct exec relocatedHead;	/* Header of the relocated text */
  unsigned long relocatedSize;	/* Size of the relocated text */
  char * startAddress;		/* Starting address of the module */
  DictFn dictionary;		/* Dictionary function in the load module */
  int status;			/* Status return from Tcl_ calls */
  char * p;

  *clientDataPtr = NULL;
  
  /* Find the file that contains the symbols for the run-time link. */

  if (SymbolTableFile != NULL) {
    inputSymbolTable = SymbolTableFile;
  } else if (tclExecutableName == NULL) {
    Tcl_SetResult (interp, "can't find the tclsh executable", TCL_STATIC);
    return TCL_ERROR;
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
 *
 * FindLibraries --
 *
 *	Find the libraries needed to link a load module at run time.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs,
 *	an error message is left in interp->result.  The -l and -L flags
 *	are concatenated onto the dynamic string `buf'.
 *
 *------------------------------------------------------------------------
 */

static int
FindLibraries (interp, fileName, buf)
     Tcl_Interp * interp;	/* Used for error reporting */
     char * fileName;		/* Name of the load module */
     Tcl_DString * buf;		/* Buffer where the -l an -L flags */
{
  FILE * f;			/* The load module */
  int c;			/* Byte from the load module */
  char * p;



  /* Open the load module */





  if ((f = fopen (fileName, "rb")) == NULL) {
    Tcl_AppendResult (interp, "couldn't open \"", fileName, "\": ",
		      Tcl_PosixError (interp), (char *) NULL);
    return TCL_ERROR;
  }

  /* Search for the library list in the load module */








|
|













>
>



>
>
>
>
|







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
 *
 * FindLibraries --
 *
 *	Find the libraries needed to link a load module at run time.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs,
 *	an error message is left in the interp's result.  The -l and -L
 *	flags are concatenated onto the dynamic string `buf'.
 *
 *------------------------------------------------------------------------
 */

static int
FindLibraries (interp, fileName, buf)
     Tcl_Interp * interp;	/* Used for error reporting */
     char * fileName;		/* Name of the load module */
     Tcl_DString * buf;		/* Buffer where the -l an -L flags */
{
  FILE * f;			/* The load module */
  int c;			/* Byte from the load module */
  char * p;
  Tcl_DString ds;
  CONST char *native;

  /* Open the load module */

  native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
  f = fopen(native, "rb");				/* INTL: Native. */
  Tcl_DStringFree(&ds);
  
  if (f == NULL) {
    Tcl_AppendResult (interp, "couldn't open \"", fileName, "\": ",
		      Tcl_PosixError (interp), (char *) NULL);
    return TCL_ERROR;
  }

  /* Search for the library list in the load module */

403
404
405
406
407
408
409



























410
411
412
413
414
415
416
  ckfree (SymbolTableFile);
  SymbolTableFile = NULL;
}

/*
 *----------------------------------------------------------------------
 *



























 * TclGuessPackageName --
 *
 *	If the "load" command is invoked without providing a package
 *	name, this procedure is invoked to try to figure it out.
 *
 * Results:
 *	Always returns 0 to indicate that we couldn't figure out a







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
  ckfree (SymbolTableFile);
  SymbolTableFile = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpUnloadFile --
 *
 *	Unloads a dynamically loaded binary code file from memory.
 *	Code pointers in the formerly loaded file are no longer valid
 *	after calling this function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Does nothing.  Can anything be done?
 *
 *----------------------------------------------------------------------
 */

void
TclpUnloadFile(clientData)
    ClientData clientData;	/* ClientData returned by a previous call
				 * to TclpLoadFile().  The clientData is 
				 * a token that represents the loaded 
				 * file. */
{
}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *
 *	If the "load" command is invoked without providing a package
 *	name, this procedure is invoked to try to figure it out.
 *
 * Results:
 *	Always returns 0 to indicate that we couldn't figure out a
428
429
430
431
432
433
434

435
436
437
438
439
440
441
TclGuessPackageName(fileName, bufPtr)
    char *fileName;		/* Name of file containing package (already
				 * translated to local form if needed). */
    Tcl_DString *bufPtr;	/* Initialized empty dstring.  Append
				 * package name to this if possible. */
{
    char *p, *q, *r;


    if (q = strrchr(fileName,'/')) {
	q++;
    } else {
	q = fileName;
    }
    if (!strncmp(q,"lib",3)) {







>







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
TclGuessPackageName(fileName, bufPtr)
    char *fileName;		/* Name of file containing package (already
				 * translated to local form if needed). */
    Tcl_DString *bufPtr;	/* Initialized empty dstring.  Append
				 * package name to this if possible. */
{
    char *p, *q, *r;
    int srcOff, dstOff;

    if (q = strrchr(fileName,'/')) {
	q++;
    } else {
	q = fileName;
    }
    if (!strncmp(q,"lib",3)) {
453
454
455
456
457
458
459
460

461

462
463
464
465
466
467
468
469
470
    }

    Tcl_DStringAppend(bufPtr,q, p-q);

    r = Tcl_DStringValue(bufPtr);
    r += strlen(r) - (p-q);

    if (islower(UCHAR(*r))) {

	*r = (char) toupper(UCHAR(*r));

    }
    while (*(++r)) {
	if (isupper(UCHAR(*r))) {
	    *r = (char) tolower(UCHAR(*r));
	}
    }

    return 1;
}







<
>
|
>
|
|
<
|
<
<



492
493
494
495
496
497
498

499
500
501
502
503

504


505
506
507
    }

    Tcl_DStringAppend(bufPtr,q, p-q);

    r = Tcl_DStringValue(bufPtr);
    r += strlen(r) - (p-q);


    /*
     * Capitalize the string and then recompute the length.
     */

    Tcl_UtfToTitle(r);

    Tcl_DStringSetLength(bufPtr, strlen(Tcl_DStringValue(bufPtr)));



    return 1;
}

Changes to unix/tclLoadDl.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclLoadDl.c --
 *
 *	This procedure provides a version of the TclLoadFile that
 *	works with the "dlopen" and "dlsym" library procedures for
 *	dynamic loading.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclLoadDl.c 1.8 96/12/03 16:57:00
 */

#include "tclInt.h"
#ifdef NO_DLFCN_H
#   include "../compat/dlfcn.h"
#else
#   include <dlfcn.h>







|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclLoadDl.c --
 *
 *	This procedure provides a version of the TclLoadFile that
 *	works with the "dlopen" and "dlsym" library procedures for
 *	dynamic loading.
 *
 * 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: tclLoadDl.c,v 1.1.2.2 1998/09/24 23:59:43 stanton Exp $
 */

#include "tclInt.h"
#ifdef NO_DLFCN_H
#   include "../compat/dlfcn.h"
#else
#   include <dlfcn.h>
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
#endif

#ifndef RTLD_GLOBAL
#   define RTLD_GLOBAL 0
#endif

/*
 *----------------------------------------------------------------------
 *
 * TclLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in interp->result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */



{
    VOID *handle;
    Tcl_DString newName;



    handle = dlopen(fileName, RTLD_NOW | RTLD_GLOBAL);




    if (handle == NULL) {
	Tcl_AppendResult(interp, "couldn't load file \"", fileName,
		"\": ", dlerror(), (char *) NULL);
	return TCL_ERROR;
    }

    /* 
     * Some platforms still add an underscore to the beginning of symbol
     * names.  If we can't find a name without an underscore, try again
     * with the underscore.
     */


    *proc1Ptr = (Tcl_PackageInitProc *) dlsym(handle, (char *) sym1);

    if (*proc1Ptr == NULL) {
	Tcl_DStringInit(&newName);
	Tcl_DStringAppend(&newName, "_", 1);
	Tcl_DStringAppend(&newName, sym1, -1);
	*proc1Ptr = (Tcl_PackageInitProc *) dlsym(handle,

		Tcl_DStringValue(&newName));

	Tcl_DStringFree(&newName);
    }

    *proc2Ptr = (Tcl_PackageInitProc *) dlsym(handle, (char *) sym2);

    if (*proc2Ptr == NULL) {
	Tcl_DStringInit(&newName);
	Tcl_DStringAppend(&newName, "_", 1);
	Tcl_DStringAppend(&newName, sym2, -1);
	*proc2Ptr = (Tcl_PackageInitProc *) dlsym(handle,

		Tcl_DStringValue(&newName));

	Tcl_DStringFree(&newName);
    }
    return TCL_OK;
}
































/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *
 *	If the "load" command is invoked without providing a package







|

|







|






|



|








>
>
>


|
>

>
|
>
>
>
>












>
|
>



|
|
>
|
>
|
|
>
|
>



|
|
>
|
>
|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
#endif

#ifndef RTLD_GLOBAL
#   define RTLD_GLOBAL 0
#endif

/*
 *---------------------------------------------------------------------------
 *
 * TclpLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in the interp's result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *---------------------------------------------------------------------------
 */

int
TclpLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */
    ClientData *clientDataPtr;	/* Filled with token for dynamically loaded
				 * file which will be passed back to 
				 * TclpUnloadFile() to unload the file. */
{
    VOID *handle;
    Tcl_DString newName, ds;
    char *native;

    native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
    handle = dlopen(native, RTLD_NOW | RTLD_GLOBAL);	/* INTL: Native. */
    Tcl_DStringFree(&ds);
    
    *clientDataPtr = (ClientData) handle;
    
    if (handle == NULL) {
	Tcl_AppendResult(interp, "couldn't load file \"", fileName,
		"\": ", dlerror(), (char *) NULL);
	return TCL_ERROR;
    }

    /* 
     * Some platforms still add an underscore to the beginning of symbol
     * names.  If we can't find a name without an underscore, try again
     * with the underscore.
     */

    native = Tcl_UtfToExternalDString(NULL, sym1, -1, &ds);
    *proc1Ptr = (Tcl_PackageInitProc *) dlsym(handle,	/* INTL: Native. */
	    native);	
    if (*proc1Ptr == NULL) {
	Tcl_DStringInit(&newName);
	Tcl_DStringAppend(&newName, "_", 1);
	native = Tcl_DStringAppend(&newName, native, -1);
	*proc1Ptr = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */
		native);
	Tcl_DStringFree(&newName);
    }
    Tcl_DStringFree(&ds);

    native = Tcl_UtfToExternalDString(NULL, sym2, -1, &ds);
    *proc2Ptr = (Tcl_PackageInitProc *) dlsym(handle,	/* INTL: Native. */
	    native);
    if (*proc2Ptr == NULL) {
	Tcl_DStringInit(&newName);
	Tcl_DStringAppend(&newName, "_", 1);
	native = Tcl_DStringAppend(&newName, native, -1);
	*proc2Ptr = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */
		native);
	Tcl_DStringFree(&newName);
    }
    Tcl_DStringFree(&ds);
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpUnloadFile --
 *
 *	Unloads a dynamically loaded binary code file from memory.
 *	Code pointers in the formerly loaded file are no longer valid
 *	after calling this function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Code removed from memory.
 *
 *----------------------------------------------------------------------
 */

void
TclpUnloadFile(clientData)
    ClientData clientData;	/* ClientData returned by a previous call
				 * to TclpLoadFile().  The clientData is 
				 * a token that represents the loaded 
				 * file. */
{
    VOID *handle;

    handle = (VOID *) clientData;
    dlclose(handle);
}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *
 *	If the "load" command is invoked without providing a package

Changes to unix/tclLoadDld.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
65
66
67
/* 
 * tclLoadDld.c --
 *
 *	This procedure provides a version of the TclLoadFile that
 *	works with the "dld_link" and "dld_get_func" library procedures
 *	for dynamic loading.  It has been tested on Linux 1.1.95 and
 *	dld-3.2.7.  This file probably isn't needed anymore, since it
 *	makes more sense to use "dl_open" etc.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclLoadDld.c 1.5 97/05/14 13:24:22
 */

#include "tclInt.h"
#include "dld.h"

/*
 * In some systems, like SunOS 4.1.3, the RTLD_NOW flag isn't defined
 * and this argument to dlopen must always be 1.
 */

#ifndef RTLD_NOW
#   define RTLD_NOW 1
#endif

/*
 *----------------------------------------------------------------------
 *
 * TclLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in interp->result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */



{
    static int firstTime = 1;
    int returnCode;

    /*
     *  The dld package needs to know the pathname to the tcl binary.
     *  If that's not know, return an error.









|




|

















|







|










|








>
>
>







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
/* 
 * tclLoadDld.c --
 *
 *	This procedure provides a version of the TclLoadFile that
 *	works with the "dld_link" and "dld_get_func" library procedures
 *	for dynamic loading.  It has been tested on Linux 1.1.95 and
 *	dld-3.2.7.  This file probably isn't needed anymore, since it
 *	makes more sense to use "dl_open" etc.
 *
 * 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: tclLoadDld.c,v 1.1.2.2 1998/09/24 23:59:43 stanton Exp $
 */

#include "tclInt.h"
#include "dld.h"

/*
 * In some systems, like SunOS 4.1.3, the RTLD_NOW flag isn't defined
 * and this argument to dlopen must always be 1.
 */

#ifndef RTLD_NOW
#   define RTLD_NOW 1
#endif

/*
 *----------------------------------------------------------------------
 *
 * TclpLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in the interp's result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclpLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */
    ClientData *clientDataPtr;	/* Filled with token for dynamically loaded
				 * file which will be passed back to 
				 * TclpUnloadFile() to unload the file. */
{
    static int firstTime = 1;
    int returnCode;

    /*
     *  The dld package needs to know the pathname to the tcl binary.
     *  If that's not know, return an error.
87
88
89
90
91
92
93


94
95
































96
97
98
99
100
101
102
    if ((returnCode = dld_link(fileName)) != 0) {
	Tcl_AppendResult(interp, "couldn't load file \"", fileName,
	    "\": ", dld_strerror(returnCode), (char *) NULL);
	return TCL_ERROR;
    }
    *proc1Ptr = (Tcl_PackageInitProc *) dld_get_func(sym1);
    *proc2Ptr = (Tcl_PackageInitProc *) dld_get_func(sym2);


    return TCL_OK;
}

































/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *
 *	If the "load" command is invoked without providing a package







>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    if ((returnCode = dld_link(fileName)) != 0) {
	Tcl_AppendResult(interp, "couldn't load file \"", fileName,
	    "\": ", dld_strerror(returnCode), (char *) NULL);
	return TCL_ERROR;
    }
    *proc1Ptr = (Tcl_PackageInitProc *) dld_get_func(sym1);
    *proc2Ptr = (Tcl_PackageInitProc *) dld_get_func(sym2);
    *clientDataPtr = strcpy(
	    (char *) ckalloc((unsigned) (strlen(fileName) + 1)), fileName);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpUnloadFile --
 *
 *	Unloads a dynamically loaded binary code file from memory.
 *	Code pointers in the formerly loaded file are no longer valid
 *	after calling this function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Code removed from memory.
 *
 *----------------------------------------------------------------------
 */

void
TclpUnloadFile(clientData)
    ClientData clientData;	/* ClientData returned by a previous call
				 * to TclpLoadFile().  The clientData is 
				 * a token that represents the loaded 
				 * file. */
{
    char *fileName;

    handle = (char *) clientData;
    dld_unlink_by_file(handle, 0);
    ckfree(handle);
}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *
 *	If the "load" command is invoked without providing a package

Changes to unix/tclLoadNext.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
/* 
 * tclLoadNext.c --
 *
 *	This procedure provides a version of the TclLoadFile that
 *	works with NeXTs rld_* dynamic loading.  This file provided
 *	by Pedja Bogdanovich.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclLoadNext.c 1.4 96/02/15 11:58:55
 */

#include "tclInt.h"
#include <mach-o/rld.h>
#include <streams/streams.h>

/*
 *----------------------------------------------------------------------
 *
 * TclLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in interp->result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */



{
  struct mach_header *header;
  char *data;
  int len, maxlen;
  char *files[]={fileName,NULL};
  NXStream *errorStream=NXOpenMemory(0,0,NX_READWRITE);








|




|









|







|










|








>
>
>







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
/* 
 * tclLoadNext.c --
 *
 *	This procedure provides a version of the TclLoadFile that
 *	works with NeXTs rld_* dynamic loading.  This file provided
 *	by Pedja Bogdanovich.
 *
 * 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: tclLoadNext.c,v 1.1.2.2 1998/09/24 23:59:44 stanton Exp $
 */

#include "tclInt.h"
#include <mach-o/rld.h>
#include <streams/streams.h>

/*
 *----------------------------------------------------------------------
 *
 * TclpLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in the interp's result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclpLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */
    ClientData *clientDataPtr;	/* Filled with token for dynamically loaded
				 * file which will be passed back to 
				 * TclpUnloadFile() to unload the file. */
{
  struct mach_header *header;
  char *data;
  int len, maxlen;
  char *files[]={fileName,NULL};
  NXStream *errorStream=NXOpenMemory(0,0,NX_READWRITE);

72
73
74
75
76
77
78

79
80



























81
82
83
84
85
86
87

  *proc2Ptr=NULL;
  if(sym2) {
    char sym[strlen(sym2)+2];
    sym[0]='_'; sym[1]=0; strcat(sym,sym2);
    rld_lookup(NULL,sym,(unsigned long *)proc2Ptr);
  }


  return TCL_OK;



























}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *







>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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

  *proc2Ptr=NULL;
  if(sym2) {
    char sym[strlen(sym2)+2];
    sym[0]='_'; sym[1]=0; strcat(sym,sym2);
    rld_lookup(NULL,sym,(unsigned long *)proc2Ptr);
  }
  *clientDataPtr = NULL;

  return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpUnloadFile --
 *
 *	Unloads a dynamically loaded binary code file from memory.
 *	Code pointers in the formerly loaded file are no longer valid
 *	after calling this function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Does nothing.  Can anything be done?
 *
 *----------------------------------------------------------------------
 */

void
TclpUnloadFile(clientData)
    ClientData clientData;	/* ClientData returned by a previous call
				 * to TclpLoadFile().  The clientData is 
				 * a token that represents the loaded 
				 * file. */
{
}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *

Changes to unix/tclLoadOSF.c.

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
 *			includes: MK6, MK7, AD2, AD3 (from OSF RI)
 *
 *	This approach to things was utter @&^#; thankfully,
 * 	OSF/1 eventually supported dlopen().
 *
 *	John Robert LoVerso <[email protected]>
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclLoadOSF.c 1.2 96/02/15 11:58:40
 */

#include "tclInt.h"
#include <sys/types.h>
#include <loader.h>

/*
 *----------------------------------------------------------------------
 *
 * TclLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in interp->result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */



{
    ldr_module_t lm;
    char *pkg;

    lm = (Tcl_PackageInitProc *) load(fileName, LDR_NOFLAGS);
    if (lm == LDR_NULL_MODULE) {
	Tcl_AppendResult(interp, "couldn't load file \"", fileName,
	    "\": ", Tcl_PosixError (interp), (char *) NULL);
	return TCL_ERROR;
    }



    /*
     * My convention is to use a [OSF loader] package name the same as shlib,
     * since the idiots never implemented ldr_lookup() and it is otherwise
     * impossible to get a package name given a module.
     *
     * I build loadable modules with a makefile rule like 
     *		ld ... -export $@: -o $@ $(OBJS)
     */
    if ((pkg = strrchr(fileName, '/')) == NULL)
	pkg = fileName;
    else
	pkg++;
    *proc1Ptr = ldr_lookup_package(pkg, sym1);
    *proc2Ptr = ldr_lookup_package(pkg, sym2);
    return TCL_OK;



























}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *







|




|









|







|










|








>
>
>











>
>















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
 *			includes: MK6, MK7, AD2, AD3 (from OSF RI)
 *
 *	This approach to things was utter @&^#; thankfully,
 * 	OSF/1 eventually supported dlopen().
 *
 *	John Robert LoVerso <[email protected]>
 *
 * 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: tclLoadOSF.c,v 1.1.2.2 1998/09/24 23:59:44 stanton Exp $
 */

#include "tclInt.h"
#include <sys/types.h>
#include <loader.h>

/*
 *----------------------------------------------------------------------
 *
 * TclpLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in the interp's result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclpLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */
    ClientData *clientDataPtr;	/* Filled with token for dynamically loaded
				 * file which will be passed back to 
				 * TclpUnloadFile() to unload the file. */
{
    ldr_module_t lm;
    char *pkg;

    lm = (Tcl_PackageInitProc *) load(fileName, LDR_NOFLAGS);
    if (lm == LDR_NULL_MODULE) {
	Tcl_AppendResult(interp, "couldn't load file \"", fileName,
	    "\": ", Tcl_PosixError (interp), (char *) NULL);
	return TCL_ERROR;
    }

    *clientDataPtr = NULL;
    
    /*
     * My convention is to use a [OSF loader] package name the same as shlib,
     * since the idiots never implemented ldr_lookup() and it is otherwise
     * impossible to get a package name given a module.
     *
     * I build loadable modules with a makefile rule like 
     *		ld ... -export $@: -o $@ $(OBJS)
     */
    if ((pkg = strrchr(fileName, '/')) == NULL)
	pkg = fileName;
    else
	pkg++;
    *proc1Ptr = ldr_lookup_package(pkg, sym1);
    *proc2Ptr = ldr_lookup_package(pkg, sym2);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpUnloadFile --
 *
 *	Unloads a dynamically loaded binary code file from memory.
 *	Code pointers in the formerly loaded file are no longer valid
 *	after calling this function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Does nothing.  Can anything be done?
 *
 *----------------------------------------------------------------------
 */

void
TclpUnloadFile(clientData)
    ClientData clientData;	/* ClientData returned by a previous call
				 * to TclpLoadFile().  The clientData is 
				 * a token that represents the loaded 
				 * file. */
{
}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *

Changes to unix/tclLoadShl.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
65
66
67
68

69
70
71
72
73
74
75
/* 
 * tclLoadShl.c --
 *
 *	This procedure provides a version of the TclLoadFile that works
 *	with the "shl_load" and "shl_findsym" library procedures for
 *	dynamic loading (e.g. for HP machines).
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclLoadShl.c 1.5 96/03/15 15:01:44
 */

#include <dl.h>

/*
 * On some HP machines, dl.h defines EXTERN; remove that definition.
 */

#ifdef EXTERN
#   undef EXTERN
#endif

#include "tcl.h"

/*
 *----------------------------------------------------------------------
 *
 * TclLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in interp->result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */



{
    shl_t handle;
    Tcl_DString newName;











    handle = shl_load(fileName, BIND_IMMEDIATE, 0L);
    if (handle == NULL) {
	Tcl_AppendResult(interp, "couldn't load file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }


    /*
     * Some versions of the HP system software still use "_" at the
     * beginning of exported symbols while others don't;  try both
     * forms of each name.
     */








|




|

















|







|










|








>
>
>




>
>
>
>
>
>
>
>
>
>
|





>







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
/* 
 * tclLoadShl.c --
 *
 *	This procedure provides a version of the TclLoadFile that works
 *	with the "shl_load" and "shl_findsym" library procedures for
 *	dynamic loading (e.g. for HP machines).
 *
 * 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: tclLoadShl.c,v 1.1.2.2 1998/09/24 23:59:44 stanton Exp $
 */

#include <dl.h>

/*
 * On some HP machines, dl.h defines EXTERN; remove that definition.
 */

#ifdef EXTERN
#   undef EXTERN
#endif

#include "tcl.h"

/*
 *----------------------------------------------------------------------
 *
 * TclpLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in the interp's result.  *proc1Ptr and *proc2Ptr
 *	are filled in with the addresses of the symbols given by
 *	*sym1 and *sym2, or NULL if those symbols can't be found.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclpLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */
    ClientData *clientDataPtr;	/* Filled with token for dynamically loaded
				 * file which will be passed back to 
				 * TclpUnloadFile() to unload the file. */
{
    shl_t handle;
    Tcl_DString newName;

    /*
     * The flags below used to be BIND_IMMEDIATE; they were changed at
     * the suggestion of Wolfgang Kechel ([email protected]): "This
     * enables verbosity for missing symbols when loading a shared lib
     * and allows to load libtk8.0.sl into tclsh8.0 without problems.
     * In general, this delays resolving symbols until they are actually
     * needed.  Shared libs do no longer need all libraries linked in
     * when they are build."
     */

    handle = shl_load(fileName, BIND_DEFERRED|BIND_VERBOSE, 0L);
    if (handle == NULL) {
	Tcl_AppendResult(interp, "couldn't load file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }
    *clientDataPtr = (ClientData) handle;

    /*
     * Some versions of the HP system software still use "_" at the
     * beginning of exported symbols while others don't;  try both
     * forms of each name.
     */

93
94
95
96
97
98
99































100
101
102
103
104
105
106
		(short) TYPE_PROCEDURE, (void *) proc2Ptr) != 0) {
	    *proc2Ptr = NULL;
	}
	Tcl_DStringFree(&newName);
    }
    return TCL_OK;
}
































/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *
 *	If the "load" command is invoked without providing a package







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
		(short) TYPE_PROCEDURE, (void *) proc2Ptr) != 0) {
	    *proc2Ptr = NULL;
	}
	Tcl_DStringFree(&newName);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpUnloadFile --
 *
 *	Unloads a dynamically loaded binary code file from memory.
 *	Code pointers in the formerly loaded file are no longer valid
 *	after calling this function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Code removed from memory.
 *
 *----------------------------------------------------------------------
 */

void
TclpUnloadFile(clientData)
    ClientData clientData;	/* ClientData returned by a previous call
				 * to TclpLoadFile().  The clientData is 
				 * a token that represents the loaded 
				 * file. */
{
    shl_t handle;

    handle = (shl_t) clientData;
    shl_unload(handle);
}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *
 *	If the "load" command is invoked without providing a package

Changes to unix/tclMtherr.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
/* 
 * tclMatherr.c --
 *
 *	This function provides a default implementation of the
 *	"matherr" function, for SYS-V systems where it's needed.
 *
 * Copyright (c) 1993-1994 The Regents of the University of California.
 * Copyright (c) 1994 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclMtherr.c 1.12 96/06/22 16:36:57
 */

#include "tclInt.h"
#include <math.h>

#ifndef TCL_GENERIC_ONLY
#include "tclPort.h"
#else
#define NO_ERRNO_H
#endif

#ifdef NO_ERRNO_H
extern int errno;			/* Use errno from tclExecute.c. */
#define EDOM 33
#define ERANGE 34
#endif

/*
 * The following variable is secretly shared with Tcl so we can
 * tell if expression evaluation is in progress.  If not, matherr
 * just emulates the default behavior, which includes printing
 * a message.
 */

extern int tcl_MathInProgress;

/*
 * The following definitions allow matherr to compile on systems
 * that don't really support it.  The compiled procedure is bogus,
 * but it will never be executed on these systems anyway.
 */

#ifndef NEED_MATHERR












|

















<
<
<
<
<
<
<
<
<







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
/* 
 * tclMatherr.c --
 *
 *	This function provides a default implementation of the
 *	"matherr" function, for SYS-V systems where it's needed.
 *
 * Copyright (c) 1993-1994 The Regents of the University of California.
 * Copyright (c) 1994 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: tclMtherr.c,v 1.1.2.2 1998/09/24 23:59:44 stanton Exp $
 */

#include "tclInt.h"
#include <math.h>

#ifndef TCL_GENERIC_ONLY
#include "tclPort.h"
#else
#define NO_ERRNO_H
#endif

#ifdef NO_ERRNO_H
extern int errno;			/* Use errno from tclExecute.c. */
#define EDOM 33
#define ERANGE 34
#endif










/*
 * The following definitions allow matherr to compile on systems
 * that don't really support it.  The compiled procedure is bogus,
 * but it will never be executed on these systems anyway.
 */

#ifndef NEED_MATHERR
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 *----------------------------------------------------------------------
 */

int
matherr(xPtr)
    struct exception *xPtr;	/* Describes error that occurred. */
{
    if (!tcl_MathInProgress) {
	return 0;
    }
    if ((xPtr->type == DOMAIN) || (xPtr->type == SING)) {
	errno = EDOM;
    } else {
	errno = ERANGE;
    }
    return 1;
}







|









61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 *----------------------------------------------------------------------
 */

int
matherr(xPtr)
    struct exception *xPtr;	/* Describes error that occurred. */
{
    if (TclMathInProgress()) {
	return 0;
    }
    if ((xPtr->type == DOMAIN) || (xPtr->type == SING)) {
	errno = EDOM;
    } else {
	errno = ERANGE;
    }
    return 1;
}

Changes to unix/tclUnixChan.c.

1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclUnixChan.c
 *
 *	Common channel driver for Unix channels based on files, command
 *	pipes and TCP sockets.
 *
 * 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.
 *
 * SCCS: @(#) tclUnixChan.c 1.207 97/11/04 14:45:29
 */

#include	"tclInt.h"	/* Internal definitions for Tcl. */
#include	"tclPort.h"	/* Portability features for Tcl. */

/*
 * sys/ioctl.h has already been included by tclPort.h.  Including termios.h







>




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclUnixChan.c
 *
 *	Common channel driver for Unix channels based on files, command
 *	pipes and TCP sockets.
 *
 * Copyright (c) 1995-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: tclUnixChan.c,v 1.1.2.5 1999/04/14 00:34:34 surles Exp $
 */

#include	"tclInt.h"	/* Internal definitions for Tcl. */
#include	"tclPort.h"	/* Portability features for Tcl. */

/*
 * sys/ioctl.h has already been included by tclPort.h.  Including termios.h
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
#undef FF1
#undef ECHO
#undef NOFLSH
#undef TOSTOP
#undef FLUSHO
#undef PENDIN



#ifdef USE_TERMIOS
#   include <termios.h>



#else	/* !USE_TERMIOS */
#ifdef USE_TERMIO
#   include <termio.h>



#else	/* !USE_TERMIO */
#ifdef USE_SGTTY
#   include <sgtty.h>



#endif	/* USE_SGTTY */


#endif	/* !USE_TERMIO */
#endif	/* !USE_TERMIOS */

/*
 * The following structure is used to set or get the serial port
 * attributes in a platform-independant manner.
 */
 
typedef struct TtyAttrs {
    int baud;
    int parity;
    int data;
    int stop;
} TtyAttrs;

/*
 * This structure describes per-instance state of a file based channel.
 */

typedef struct FileState {
    Tcl_Channel channel;	/* Channel associated with this file. */
    int fd;			/* File handle. */
    int validMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which operations are valid on the file. */
    struct FileState *nextPtr;	/* Pointer to next file in list of all
				 * file channels. */
} FileState;



/*



























 * List of all file channels currently open.

 */

static FileState *firstFilePtr = NULL;




/*
 * This structure describes per-instance state of a tcp based channel.
 */

typedef struct TcpState {
    Tcl_Channel channel;	/* Channel associated with this file. */







>
>


>
>
>



>
>
>



>
>
>
|
>
>



<
<
<
<
<
<
<
<
<
<
<
<














>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
|
|
>
>
>







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
#undef FF1
#undef ECHO
#undef NOFLSH
#undef TOSTOP
#undef FLUSHO
#undef PENDIN

#define SUPPORTS_TTY

#ifdef USE_TERMIOS
#   include <termios.h>
#   define IOSTATE			struct termios
#   define GETIOSTATE(fd, statePtr)	tcgetattr((fd), (statePtr))
#   define SETIOSTATE(fd, statePtr)	tcsetattr((fd), TCSADRAIN, (statePtr))
#else	/* !USE_TERMIOS */
#ifdef USE_TERMIO
#   include <termio.h>
#   define IOSTATE			struct termio
#   define GETIOSTATE(fd, statePtr)	ioctl((fd), TCGETA, (statePtr))
#   define SETIOSTATE(fd, statePtr)	ioctl((fd), TCSETAW, (statePtr))
#else	/* !USE_TERMIO */
#ifdef USE_SGTTY
#   include <sgtty.h>
#   define IOSTATE			struct sgttyb
#   define GETIOSTATE(fd, statePtr)	ioctl((fd), TIOCGETP, (statePtr))
#   define SETIOSTATE(fd, statePtr)	ioctl((fd), TIOCSETP, (statePtr))
#else	/* !USE_SGTTY */
#   undef SUPPORTS_TTY
#endif	/* !USE_SGTTY */
#endif	/* !USE_TERMIO */
#endif	/* !USE_TERMIOS */













/*
 * This structure describes per-instance state of a file based channel.
 */

typedef struct FileState {
    Tcl_Channel channel;	/* Channel associated with this file. */
    int fd;			/* File handle. */
    int validMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which operations are valid on the file. */
    struct FileState *nextPtr;	/* Pointer to next file in list of all
				 * file channels. */
} FileState;

#ifdef SUPPORTS_TTY

/*
 * The following structure describes per-instance state of a tty-based
 * channel.
 */

typedef struct TtyState {
    FileState fs;		/* Per-instance state of the file
				 * descriptor.  Must be the first field. */
    IOSTATE savedState;		/* Initial state of device.  Used to reset
				 * state when device closed. */
} TtyState;

/*
 * The following structure is used to set or get the serial port
 * attributes in a platform-independant manner.
 */
 
typedef struct TtyAttrs {
    int baud;
    int parity;
    int data;
    int stop;
} TtyAttrs;

#endif	/* !SUPPORTS_TTY */

typedef struct ThreadSpecificData {
    /*
     * List of all file channels currently open.  This is per thread and is
     * used to match up fd's to channels, which rarely occurs.
     */
    
    FileState *firstFilePtr;
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * This structure describes per-instance state of a tcp based channel.
 */

typedef struct TcpState {
    Tcl_Channel channel;	/* Channel associated with this file. */
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
			    Tcl_DString *dsPtr));
static int		TcpInputProc _ANSI_ARGS_((ClientData instanceData,
		            char *buf, int toRead,  int *errorCode));
static int		TcpOutputProc _ANSI_ARGS_((ClientData instanceData,
		            char *buf, int toWrite, int *errorCode));
static void		TcpWatchProc _ANSI_ARGS_((ClientData instanceData,
		            int mask));


static int		TtyParseMode _ANSI_ARGS_((Tcl_Interp *interp,
			    CONST char *mode, int *speedPtr, int *parityPtr,
			    int *dataPtr, int *stopPtr));
static void		TtyGetAttributes _ANSI_ARGS_((int fd,
			    TtyAttrs *ttyPtr));
static int		TtyGetOptionProc _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp, char *optionName,
			    Tcl_DString *dsPtr));
static void		TtyInit _ANSI_ARGS_((int fd));



static void		TtySetAttributes _ANSI_ARGS_((int fd,
			    TtyAttrs *ttyPtr));
static int		TtySetOptionProc _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp, char *optionName, 
			    char *value));

static int		WaitForConnect _ANSI_ARGS_((TcpState *statePtr,
		            int *errorCodePtr));

/*
 * This structure describes the channel type structure for file based IO:
 */

static Tcl_ChannelType fileChannelType = {
    "file",				/* Type name. */
    FileBlockModeProc,			/* Set blocking/nonblocking mode.*/
    FileCloseProc,			/* Close proc. */
    FileInputProc,			/* Input proc. */
    FileOutputProc,			/* Output proc. */
    FileSeekProc,			/* Seek proc. */
    NULL,				/* Set option proc. */
    NULL,				/* Get option proc. */
    FileWatchProc,			/* Initialize notifier. */
    FileGetHandleProc,			/* Get OS handles out of channel. */
};


/*
 * This structure describes the channel type structure for serial IO.
 * Note that this type is a subclass of the "file" type.
 */

static Tcl_ChannelType ttyChannelType = {
    "tty",				/* Type name. */
    FileBlockModeProc,			/* Set blocking/nonblocking mode.*/
    FileCloseProc,			/* Close proc. */
    FileInputProc,			/* Input proc. */
    FileOutputProc,			/* Output proc. */
    NULL,				/* Seek proc. */
    TtySetOptionProc,			/* Set option proc. */
    TtyGetOptionProc,			/* Get option proc. */
    FileWatchProc,			/* Initialize notifier. */
    FileGetHandleProc,			/* Get OS handles out of channel. */
};


/*
 * This structure describes the channel type structure for TCP socket
 * based IO:
 */

static Tcl_ChannelType tcpChannelType = {







>
>
|
<
<





|
>
>
>





>




















>








|








>







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
			    Tcl_DString *dsPtr));
static int		TcpInputProc _ANSI_ARGS_((ClientData instanceData,
		            char *buf, int toRead,  int *errorCode));
static int		TcpOutputProc _ANSI_ARGS_((ClientData instanceData,
		            char *buf, int toWrite, int *errorCode));
static void		TcpWatchProc _ANSI_ARGS_((ClientData instanceData,
		            int mask));
#ifdef SUPPORTS_TTY
static int		TtyCloseProc _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp));


static void		TtyGetAttributes _ANSI_ARGS_((int fd,
			    TtyAttrs *ttyPtr));
static int		TtyGetOptionProc _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp, char *optionName,
			    Tcl_DString *dsPtr));
static FileState *	TtyInit _ANSI_ARGS_((int fd));
static int		TtyParseMode _ANSI_ARGS_((Tcl_Interp *interp,
			    CONST char *mode, int *speedPtr, int *parityPtr,
			    int *dataPtr, int *stopPtr));
static void		TtySetAttributes _ANSI_ARGS_((int fd,
			    TtyAttrs *ttyPtr));
static int		TtySetOptionProc _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp, char *optionName, 
			    char *value));
#endif	/* SUPPORTS_TTY */
static int		WaitForConnect _ANSI_ARGS_((TcpState *statePtr,
		            int *errorCodePtr));

/*
 * This structure describes the channel type structure for file based IO:
 */

static Tcl_ChannelType fileChannelType = {
    "file",				/* Type name. */
    FileBlockModeProc,			/* Set blocking/nonblocking mode.*/
    FileCloseProc,			/* Close proc. */
    FileInputProc,			/* Input proc. */
    FileOutputProc,			/* Output proc. */
    FileSeekProc,			/* Seek proc. */
    NULL,				/* Set option proc. */
    NULL,				/* Get option proc. */
    FileWatchProc,			/* Initialize notifier. */
    FileGetHandleProc,			/* Get OS handles out of channel. */
};

#ifdef SUPPORTS_TTY
/*
 * This structure describes the channel type structure for serial IO.
 * Note that this type is a subclass of the "file" type.
 */

static Tcl_ChannelType ttyChannelType = {
    "tty",				/* Type name. */
    FileBlockModeProc,			/* Set blocking/nonblocking mode.*/
    TtyCloseProc,			/* Close proc. */
    FileInputProc,			/* Input proc. */
    FileOutputProc,			/* Output proc. */
    NULL,				/* Seek proc. */
    TtySetOptionProc,			/* Set option proc. */
    TtyGetOptionProc,			/* Get option proc. */
    FileWatchProc,			/* Initialize notifier. */
    FileGetHandleProc,			/* Get OS handles out of channel. */
};
#endif	/* SUPPORTS_TTY */

/*
 * This structure describes the channel type structure for TCP socket
 * based IO:
 */

static Tcl_ChannelType tcpChannelType = {
399
400
401
402
403
404
405

406
407





408
409
410
411
412
413
414
415
416
417
418
419
420
421
FileCloseProc(instanceData, interp)
    ClientData instanceData;	/* File state. */
    Tcl_Interp *interp;		/* For error reporting - unused. */
{
    FileState *fsPtr = (FileState *) instanceData;
    FileState **nextPtrPtr;
    int errorCode = 0;


    Tcl_DeleteFileHandler(fsPtr->fd);





    if (!TclInExit()
	    || ((fsPtr->fd != 0) && (fsPtr->fd != 1) && (fsPtr->fd != 2))) {
	if (close(fsPtr->fd) < 0) {
	    errorCode = errno;
	}
    }
    for (nextPtrPtr = &firstFilePtr; (*nextPtrPtr) != NULL;
	 nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
	if ((*nextPtrPtr) == fsPtr) {
	    (*nextPtrPtr) = fsPtr->nextPtr;
	    break;
	}
    }
    ckfree((char *) fsPtr);







>


>
>
>
>
>






|







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
FileCloseProc(instanceData, interp)
    ClientData instanceData;	/* File state. */
    Tcl_Interp *interp;		/* For error reporting - unused. */
{
    FileState *fsPtr = (FileState *) instanceData;
    FileState **nextPtrPtr;
    int errorCode = 0;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    Tcl_DeleteFileHandler(fsPtr->fd);

    /*
     * Do not close standard channels while in thread-exit.
     */

    if (!TclInExit()
	    || ((fsPtr->fd != 0) && (fsPtr->fd != 1) && (fsPtr->fd != 2))) {
	if (close(fsPtr->fd) < 0) {
	    errorCode = errno;
	}
    }
    for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
	 nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
	if ((*nextPtrPtr) == fsPtr) {
	    (*nextPtrPtr) = fsPtr->nextPtr;
	    break;
	}
    }
    ckfree((char *) fsPtr);
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
}

/*
 *----------------------------------------------------------------------
 *
 * FileGetHandleProc --
 *
 *	Called from Tcl_GetChannelFile to retrieve OS handles from
 *	a file based channel.
 *
 * Results:
 *	Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
 *	there is no handle for the specified direction. 
 *
 * Side effects:







|







551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
}

/*
 *----------------------------------------------------------------------
 *
 * FileGetHandleProc --
 *
 *	Called from Tcl_GetChannelHandle to retrieve OS handles from
 *	a file based channel.
 *
 * Results:
 *	Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
 *	there is no handle for the specified direction. 
 *
 * Side effects:
532
533
534
535
536
537
538































539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
    if (direction & fsPtr->validMask) {
	*handlePtr = (ClientData) fsPtr->fd;
	return TCL_OK;
    } else {
	return TCL_ERROR;
    }
}
































/*
 *----------------------------------------------------------------------
 *
 * TtySetOptionProc --
 *
 *	Sets an option on a channel.
 *
 * Results:
 *	A standard Tcl result. Also sets interp->result on error if
 *	interp is not NULL.
 *
 * Side effects:
 *	May modify an option on a device.
 *      Sets Error message if needed (by calling Tcl_BadChannelOption).
 *
 *----------------------------------------------------------------------







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|







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
    if (direction & fsPtr->validMask) {
	*handlePtr = (ClientData) fsPtr->fd;
	return TCL_OK;
    } else {
	return TCL_ERROR;
    }
}

#ifdef SUPPORTS_TTY 

/*
 *----------------------------------------------------------------------
 *
 * TtyCloseProc --
 *
 *	This procedure is called from the generic IO level to perform
 *	channel-type-specific cleanup when a tty based channel is closed.
 *
 * Results:
 *	0 if successful, errno if failed.
 *
 * Side effects:
 *	Restores the settings and closes the device of the channel.
 *
 *----------------------------------------------------------------------
 */

static int
TtyCloseProc(instanceData, interp)
    ClientData instanceData;	/* Tty state. */
    Tcl_Interp *interp;		/* For error reporting - unused. */
{
    TtyState *ttyPtr;

    ttyPtr = (TtyState *) instanceData;
    SETIOSTATE(ttyPtr->fs.fd, &ttyPtr->savedState);
    return FileCloseProc(instanceData, interp);
}

/*
 *----------------------------------------------------------------------
 *
 * TtySetOptionProc --
 *
 *	Sets an option on a channel.
 *
 * Results:
 *	A standard Tcl result. Also sets the interp's result on error if
 *	interp is not NULL.
 *
 * Side effects:
 *	May modify an option on a device.
 *      Sets Error message if needed (by calling Tcl_BadChannelOption).
 *
 *----------------------------------------------------------------------
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
    ClientData instanceData;	/* File state. */
    Tcl_Interp *interp;		/* For error reporting - can be NULL. */
    char *optionName;		/* Option to get. */
    Tcl_DString *dsPtr;		/* Where to store value(s). */
{
    FileState *fsPtr = (FileState *) instanceData;
    unsigned int len;
    char buf[32];
    TtyAttrs tty;

    if (optionName == NULL) {
	Tcl_DStringAppendElement(dsPtr, "-mode");
	len = 0;
    } else {
	len = strlen(optionName);







|







688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
    ClientData instanceData;	/* File state. */
    Tcl_Interp *interp;		/* For error reporting - can be NULL. */
    char *optionName;		/* Option to get. */
    Tcl_DString *dsPtr;		/* Where to store value(s). */
{
    FileState *fsPtr = (FileState *) instanceData;
    unsigned int len;
    char buf[3 * TCL_INTEGER_SPACE + 16];
    TtyAttrs tty;

    if (optionName == NULL) {
	Tcl_DStringAppendElement(dsPtr, "-mode");
	len = 0;
    } else {
	len = strlen(optionName);
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904

905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930

931
932
933

934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951

952
953
954

955
956
957
958
959
960
961
962
963
964
965

966
967

968
969
970
971
972
973
974
975
976
977
978
979
980
981

#endif	/* !DIRECT_BAUD */


/*
 *---------------------------------------------------------------------------
 *
 * TtyInit --
 *
 *	Given file descriptor that refers to a serial port, 
 *	initialize the serial port to a set of sane values so that
 *	Tcl can talk to a device located on the serial port.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Serial device initialized.
 *
 *---------------------------------------------------------------------------
 */

static void
TtyInit(fd)
    int fd;			/* Open file descriptor for serial port to
				 * be initialized. */
{
#ifdef USE_TERMIOS
    struct termios termios;

    tcgetattr(fd, &termios);
    termios.c_iflag = IGNBRK;
    termios.c_oflag = 0;
    termios.c_lflag = 0;
    termios.c_cflag |= CREAD;
    termios.c_cc[VMIN] = 60;
    termios.c_cc[VTIME] = 2;
    tcsetattr(fd, TCSANOW, &termios);
#else	/* !USE_TERMIOS */
#ifdef USE_TERMIO
    struct termio termio;

    ioctl(fd, TCGETA, &termio);
    termio.c_iflag = IGNBRK;
    termio.c_oflag = 0;
    termio.c_lflag = 0;
    termio.c_cflag |= CREAD;
    termio.c_cc[VMIN] = 60;
    termio.c_cc[VTIME] = 2;
    ioctl(fd, TCSETAW, &termio);
#else	/* !USE_TERMIO */
#ifdef USE_SGTTY
    struct sgttyb sgttyb;

    ioctl(fd, TIOCGETP, &sgttyb);
    sgttyb.sg_flags &= (EVENP | ODDP);
    sgttyb.sg_flags |= RAW;
    ioctl(fd, TIOCSETP, &sgttyb);
#endif	/* USE_SGTTY */
#endif	/* !USE_TERMIO */
#endif	/* !USE_TERMIOS */
}

/*
 *---------------------------------------------------------------------------
 *
 * TtyGetAttributes --
 *
 *	Get the current attributes of the specified serial device.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
static void
TtyGetAttributes(fd, ttyPtr)
    int fd;			/* Open file descriptor for serial port to
				 * be queried. */
    TtyAttrs *ttyPtr;		/* Buffer filled with serial port
				 * attributes. */
{
#ifdef USE_TERMIOS
    int parity, data;
    struct termios termios;


    tcgetattr(fd, &termios);
    ttyPtr->baud = TtyGetBaud(cfgetospeed(&termios));
    
    parity = 'n';
#ifdef PAREXT
    switch ((int) (termios.c_cflag & (PARENB | PARODD | PAREXT))) {
	case PARENB		      : parity = 'e'; break;
	case PARENB | PARODD	      :	parity = 'o'; break;
	case PARENB |	       PAREXT : parity = 's'; break;
	case PARENB | PARODD | PAREXT :	parity = 'm'; break;
    }
#else	/* !PAREXT */
    switch ((int) (termios.c_cflag & (PARENB | PARODD))) {
	case PARENB		      : parity = 'e'; break;
	case PARENB | PARODD	      :	parity = 'o'; break;
    }
#endif	/* !PAREXT */
    ttyPtr->parity = parity;

    data = termios.c_cflag & CSIZE;
    ttyPtr->data = (data == CS5) ? 5 : (data == CS6) ? 6 :
	    (data == CS7) ? 7 : 8;

    ttyPtr->stop = (termios.c_cflag & CSTOPB) ? 2 : 1;
#else	/* !USE_TERMIOS */

#ifdef USE_TERMIO
    int parity, data;
    struct termio termio;


    ioctl(fd, TCGETA, &termio);
    ttyPtr->baud = TtyGetBaud(termio.c_cflag & CBAUD);
    parity = 'n';
    switch (termio.c_cflag & (PARENB | PARODD | PAREXT)) {
	case PARENB		      : parity = 'e'; break;
	case PARENB | PARODD	      :	parity = 'o'; break;
	case PARENB |	       PAREXT : parity = 's'; break;
	case PARENB | PARODD | PAREXT :	parity = 'm'; break;
    }
    ttyPtr->parity = parity;

    data = termio.c_cflag & CSIZE;
    ttyPtr->data = (data == CS5) ? 5 : (data == CS6) ? 6 :
	    (data == CS7) ? 7 : 8;

    ttyPtr->stop = (termio.c_cflag & CSTOPB) ? 2 : 1;
#else	/* !USE_TERMIO */

#ifdef USE_SGTTY
    int parity;
    struct sgttyb sgttyb;


    ioctl(fd, TIOCGETP, &sgttyb);
    ttyPtr->baud = TtyGetBaud(sgttyb.sg_ospeed);
    parity = 'n';
    if (sgttyb.sg_flags & EVENP) {
	parity = 'e';
    } else if (sgttyb.sg_flags & ODDP) {
	parity = 'o';
    }
    ttyPtr->parity = parity;
    ttyPtr->data = (sgttyb.sg_flags & (EVENP | ODDP)) ? 7 : 8;

    ttyPtr->stop = 1;
#else	/* !USE_SGTTY */

    ttyPtr->baud = 0;
    ttyPtr->parity = 'n';
    ttyPtr->data = 0;
    ttyPtr->stop = 0;
#endif	/* !USE_SGTTY */
#endif	/* !USE_TERMIO */
#endif	/* !USE_TERMIOS */
}

/*
 *---------------------------------------------------------------------------
 *
 * TtySetAttributes --
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















|
|
|
>

|
|



|






|




<

|
|
<

|
|
>

<
<
>

<
<

|





<

|
|
<

|
|
>

<
<
>

<
<

|

|


|
|
>
|
|
>
|
|
|
|
<
<
<







894
895
896
897
898
899
900



























































901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942

943
944
945

946
947
948
949
950


951
952


953
954
955
956
957
958
959

960
961
962

963
964
965
966
967


968
969


970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985



986
987
988
989
990
991
992

#endif	/* !DIRECT_BAUD */


/*
 *---------------------------------------------------------------------------
 *



























































 * TtyGetAttributes --
 *
 *	Get the current attributes of the specified serial device.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
static void
TtyGetAttributes(fd, ttyPtr)
    int fd;			/* Open file descriptor for serial port to
				 * be queried. */
    TtyAttrs *ttyPtr;		/* Buffer filled with serial port
				 * attributes. */
{
    IOSTATE iostate;
    int baud, parity, data, stop;

    GETIOSTATE(fd, &iostate);

#ifdef USE_TERMIOS
    baud = TtyGetBaud(cfgetospeed(&iostate));
    
    parity = 'n';
#ifdef PAREXT
    switch ((int) (iostate.c_cflag & (PARENB | PARODD | PAREXT))) {
	case PARENB		      : parity = 'e'; break;
	case PARENB | PARODD	      :	parity = 'o'; break;
	case PARENB |	       PAREXT : parity = 's'; break;
	case PARENB | PARODD | PAREXT :	parity = 'm'; break;
    }
#else	/* !PAREXT */
    switch ((int) (iostate.c_cflag & (PARENB | PARODD))) {
	case PARENB		      : parity = 'e'; break;
	case PARENB | PARODD	      :	parity = 'o'; break;
    }
#endif	/* !PAREXT */


    data = iostate.c_cflag & CSIZE;
    data = (data == CS5) ? 5 : (data == CS6) ? 6 : (data == CS7) ? 7 : 8;


    stop = (iostate.c_cflag & CSTOPB) ? 2 : 1;
#endif	/* USE_TERMIOS */

#ifdef USE_TERMIO


    baud = TtyGetBaud(iostate.c_cflag & CBAUD);



    parity = 'n';
    switch (iostate.c_cflag & (PARENB | PARODD | PAREXT)) {
	case PARENB		      : parity = 'e'; break;
	case PARENB | PARODD	      :	parity = 'o'; break;
	case PARENB |	       PAREXT : parity = 's'; break;
	case PARENB | PARODD | PAREXT :	parity = 'm'; break;
    }


    data = iostate.c_cflag & CSIZE;
    data = (data == CS5) ? 5 : (data == CS6) ? 6 : (data == CS7) ? 7 : 8;


    stop = (iostate.c_cflag & CSTOPB) ? 2 : 1;
#endif	/* USE_TERMIO */

#ifdef USE_SGTTY


    baud = TtyGetBaud(iostate.sg_ospeed);



    parity = 'n';
    if (iostate.sg_flags & EVENP) {
	parity = 'e';
    } else if (iostate.sg_flags & ODDP) {
	parity = 'o';
    }

    data = (iostate.sg_flags & (EVENP | ODDP)) ? 7 : 8;

    stop = 1;
#endif	/* USE_SGTTY */

    ttyPtr->baud    = baud;
    ttyPtr->parity  = parity;
    ttyPtr->data    = data;
    ttyPtr->stop    = stop;



}

/*
 *---------------------------------------------------------------------------
 *
 * TtySetAttributes --
 *
993
994
995
996
997
998
999


1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062

1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
static void
TtySetAttributes(fd, ttyPtr)
    int fd;			/* Open file descriptor for serial port to
				 * be modified. */
    TtyAttrs *ttyPtr;		/* Buffer containing new attributes for
				 * serial port. */
{


#ifdef USE_TERMIOS
    int parity, data, flag;
    struct termios termios;

    tcgetattr(fd, &termios);
    cfsetospeed(&termios, TtyGetSpeed(ttyPtr->baud));
    cfsetispeed(&termios, TtyGetSpeed(ttyPtr->baud));

    flag = 0;
    parity = ttyPtr->parity;
    if (parity != 'n') {
	flag |= PARENB;
#ifdef PAREXT
	termios.c_cflag &= ~PAREXT;
	if ((parity == 'm') || (parity == 's')) {
	    flag |= PAREXT;
	}
#endif
	if ((parity == 'm') || (parity == 'o')) {
	    flag |= PARODD;
	}
    }
    data = ttyPtr->data;
    flag |= (data == 5) ? CS5 : (data == 6) ? CS6 : (data == 7) ? CS7 : CS8;
    if (ttyPtr->stop == 2) {
	flag |= CSTOPB;
    }

    termios.c_cflag &= ~(PARENB | PARODD | CSIZE | CSTOPB);
    termios.c_cflag |= flag;
    tcsetattr(fd, TCSANOW, &termios);

#else	/* !USE_TERMIOS */

#ifdef USE_TERMIO
    int parity, data, flag;
    struct termio termio;

    ioctl(fd, TCGETA, &termio);
    termio.c_cflag &= ~CBAUD;
    termio.c_cflag |= TtyGetSpeed(ttyPtr->baud);

    flag = 0;
    parity = ttyPtr->parity;
    if (parity != 'n') {
	flag |= PARENB;
	if ((parity == 'm') || (parity == 's')) {
	    flag |= PAREXT;
	}
	if ((parity == 'm') || (parity == 'o')) {
	    flag |= PARODD;
	}
    }
    data = ttyPtr->data;
    flag |= (data == 5) ? CS5 : (data == 6) ? CS6 : (data == 7) ? CS7 : CS8;
    if (ttyPtr->stop == 2) {
	flag |= CSTOPB;
    }

    termio.c_cflag &= ~(PARENB | PARODD | PAREXT | CSIZE | CSTOPB);
    termio.c_cflag |= flag;
    ioctl(fd, TCSETAW, &termio);

#else	/* !USE_TERMIO */

#ifdef USE_SGTTY
    int parity;
    struct sgttyb sgttyb;

    ioctl(fd, TIOCGETP, &sgttyb);
    sgttyb.sg_ospeed = TtyGetSpeed(ttyPtr->baud);
    sgttyb.sg_ispeed = TtyGetSpeed(ttyPtr->baud);

    parity = ttyPtr->parity;
    if (parity == 'e') {
	sgttyb.sg_flags &= ~ODDP;
	sgttyb.sg_flags |= EVENP;
    } else if (parity == 'o') {
	sgttyb.sg_flags &= ~EVENP;
	sgttyb.sg_flags |= ODDP;
    }
    ioctl(fd, TIOCSETP, &sgttyb);
#endif	/* USE_SGTTY */
#endif	/* !USE_TERMIO */
#endif	/* !USE_TERMIOS */
}

/*
 *---------------------------------------------------------------------------
 *
 * TtyParseMode --
 *
 *	Parse the "-mode" argument to the fconfigure command.  The argument
 *	is of the form baud,parity,data,stop.
 *
 * Results:
 *	The return value is TCL_OK if the argument was successfully
 *	parsed, TCL_ERROR otherwise.  If TCL_ERROR is returned, an
 *	error message is left in interp->result (if interp is non-NULL).
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 







>
>


<

|
|
|






|














|
|
<

|
>


<

|
|
|


















|
|
<

|
>


<

|
|
|



|
|

|
|

<

|
|













|







1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041

1042
1043
1044
1045
1046

1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070

1071
1072
1073
1074
1075

1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
static void
TtySetAttributes(fd, ttyPtr)
    int fd;			/* Open file descriptor for serial port to
				 * be modified. */
    TtyAttrs *ttyPtr;		/* Buffer containing new attributes for
				 * serial port. */
{
    IOSTATE iostate;

#ifdef USE_TERMIOS
    int parity, data, flag;


    GETIOSTATE(fd, &iostate);
    cfsetospeed(&iostate, TtyGetSpeed(ttyPtr->baud));
    cfsetispeed(&iostate, TtyGetSpeed(ttyPtr->baud));

    flag = 0;
    parity = ttyPtr->parity;
    if (parity != 'n') {
	flag |= PARENB;
#ifdef PAREXT
	iostate.c_cflag &= ~PAREXT;
	if ((parity == 'm') || (parity == 's')) {
	    flag |= PAREXT;
	}
#endif
	if ((parity == 'm') || (parity == 'o')) {
	    flag |= PARODD;
	}
    }
    data = ttyPtr->data;
    flag |= (data == 5) ? CS5 : (data == 6) ? CS6 : (data == 7) ? CS7 : CS8;
    if (ttyPtr->stop == 2) {
	flag |= CSTOPB;
    }

    iostate.c_cflag &= ~(PARENB | PARODD | CSIZE | CSTOPB);
    iostate.c_cflag |= flag;


#endif	/* USE_TERMIOS */

#ifdef USE_TERMIO
    int parity, data, flag;


    GETIOSTATE(fd, &iostate);
    iostate.c_cflag &= ~CBAUD;
    iostate.c_cflag |= TtyGetSpeed(ttyPtr->baud);

    flag = 0;
    parity = ttyPtr->parity;
    if (parity != 'n') {
	flag |= PARENB;
	if ((parity == 'm') || (parity == 's')) {
	    flag |= PAREXT;
	}
	if ((parity == 'm') || (parity == 'o')) {
	    flag |= PARODD;
	}
    }
    data = ttyPtr->data;
    flag |= (data == 5) ? CS5 : (data == 6) ? CS6 : (data == 7) ? CS7 : CS8;
    if (ttyPtr->stop == 2) {
	flag |= CSTOPB;
    }

    iostate.c_cflag &= ~(PARENB | PARODD | PAREXT | CSIZE | CSTOPB);
    iostate.c_cflag |= flag;


#endif	/* USE_TERMIO */

#ifdef USE_SGTTY
    int parity;


    GETIOSTATE(fd, &iostate);
    iostate.sg_ospeed = TtyGetSpeed(ttyPtr->baud);
    iostate.sg_ispeed = TtyGetSpeed(ttyPtr->baud);

    parity = ttyPtr->parity;
    if (parity == 'e') {
	iostate.sg_flags &= ~ODDP;
	iostate.sg_flags |= EVENP;
    } else if (parity == 'o') {
	iostate.sg_flags &= ~EVENP;
	iostate.sg_flags |= ODDP;
    }

#endif	/* USE_SGTTY */

    SETIOSTATE(fd, &iostate);
}

/*
 *---------------------------------------------------------------------------
 *
 * TtyParseMode --
 *
 *	Parse the "-mode" argument to the fconfigure command.  The argument
 *	is of the form baud,parity,data,stop.
 *
 * Results:
 *	The return value is TCL_OK if the argument was successfully
 *	parsed, TCL_ERROR otherwise.  If TCL_ERROR is returned, an
 *	error message is left in the interp's result (if interp is non-NULL).
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */
 
1143
1144
1145
1146
1147
1148
1149
1150





























































1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182

1183
1184

1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254

1255



1256

1257
1258





1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
	    Tcl_AppendResult(interp, bad, " stop: should be 1 or 2", NULL);
	}
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*





























































 *----------------------------------------------------------------------
 *
 * Tcl_OpenFileChannel --
 *
 *	Open an file based channel on Unix systems.
 *
 * Results:
 *	The new channel or NULL. If NULL, the output argument
 *	errorCodePtr is set to a POSIX error and an error message is
 *	left in interp->result if interp is not NULL.
 *
 * Side effects:
 *	May open the channel and may cause creation of a file on the
 *	file system.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_OpenFileChannel(interp, fileName, modeString, permissions)
    Tcl_Interp *interp;			/* Interpreter for error reporting;
                                         * can be NULL. */
    char *fileName;			/* Name of file to open. */
    char *modeString;			/* A list of POSIX open modes or
                                         * a string such as "rw". */
    int permissions;			/* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
{
    int fd, seekFlag, mode, channelPermissions;
    FileState *fsPtr;
    char *nativeName, channelName[20];

    Tcl_DString buffer;
    Tcl_ChannelType *channelTypePtr;


    mode = TclGetOpenMode(interp, modeString, &seekFlag);
    if (mode == -1) {
        return NULL;
    }
    switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
	case O_RDONLY:
	    channelPermissions = TCL_READABLE;
	    break;
	case O_WRONLY:
	    channelPermissions = TCL_WRITABLE;
	    break;
	case O_RDWR:
	    channelPermissions = (TCL_READABLE | TCL_WRITABLE);
	    break;
	default:
            /*
             * This may occurr if modeString was "", for example.
             */
	    panic("Tcl_OpenFileChannel: invalid mode value");
	    return NULL;
    }

    nativeName = Tcl_TranslateFileName(interp, fileName, &buffer);
    if (nativeName == NULL) {
	return NULL;
    }
    fd = open(nativeName, mode, permissions);

    /*
     * If nativeName is not NULL, the buffer is valid and we must free
     * the storage.
     */
    
    Tcl_DStringFree(&buffer);

    if (fd < 0) {
        if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "couldn't open \"", fileName, "\": ",
                    Tcl_PosixError(interp), (char *) NULL);
        }
        return NULL;
    }

    /*
     * Set close-on-exec flag on the fd so that child processes will not
     * inherit this fd.
     */
  
    fcntl(fd, F_SETFD, FD_CLOEXEC);
    
    sprintf(channelName, "file%d", fd);
    
    fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState));
    fsPtr->nextPtr = firstFilePtr;
    firstFilePtr = fsPtr;
    fsPtr->validMask = channelPermissions | TCL_EXCEPTION;
    fsPtr->fd = fd;
    
    if (isatty(fd)) {
	/*
	 * Initialize the serial port to a set of sane parameters.
	 * Especially important if the remote device is set to echo and
	 * the serial port driver was also set to echo -- as soon as a char
	 * were sent to the serial port, the remote device would echo it,
	 * then the serial driver would echo it back to the device, etc.
	 */
	 
	TtyInit(fd);
	channelTypePtr = &ttyChannelType;

    } else {



	channelTypePtr = &fileChannelType;

    }






    fsPtr->channel = Tcl_CreateChannel(channelTypePtr, channelName,
	    (ClientData) fsPtr, channelPermissions);

    if (seekFlag) {
        if (Tcl_Seek(fsPtr->channel, 0, SEEK_END) < 0) {
            if (interp != (Tcl_Interp *) NULL) {
                Tcl_AppendResult(interp, "couldn't seek to end of file on \"",
                        channelName, "\": ", Tcl_PosixError(interp), NULL);
            }
            Tcl_Close(NULL, fsPtr->channel);
            return NULL;
        }
    }

    if (channelTypePtr == &ttyChannelType) {
	/*
	 * Gotcha.  Most modems need a "\r" at the end of the command
	 * sequence.  If you just send "at\n", the modem will not respond
	 * with "OK" because it never got a "\r" to actually invoke the
	 * command.  So, by default, newlines are translated to "\r\n" on
	 * output to avoid "bug" reports that the serial port isn't working.
	 */
	 
	if (Tcl_SetChannelOption(interp, fsPtr->channel, "-translation",
		"auto crlf") != TCL_OK) {
	    Tcl_Close(NULL, fsPtr->channel);
	    return NULL;
	}
    }

    return fsPtr->channel;
}








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|






|









|











|
>
|

>



















|



|
|


|
|
<
<
<
<
|



















<
<
<
<
<
|









|

>
|
>
>
>

>


>
>
>
>
>














|









|







1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285




1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305





1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
	    Tcl_AppendResult(interp, bad, " stop: should be 1 or 2", NULL);
	}
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TtyInit --
 *
 *	Given file descriptor that refers to a serial port, 
 *	initialize the serial port to a set of sane values so that
 *	Tcl can talk to a device located on the serial port.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Serial device initialized to non-blocking raw mode, similar to
 *	sockets.  All other modes can be simulated on top of this in Tcl.
 *
 *---------------------------------------------------------------------------
 */

static FileState *
TtyInit(fd)
    int fd;			/* Open file descriptor for serial port to
				 * be initialized. */
{
    IOSTATE iostate;
    TtyState *ttyPtr;

    ttyPtr = (TtyState *) ckalloc((unsigned) sizeof(TtyState));
    GETIOSTATE(fd, &ttyPtr->savedState);

    iostate = ttyPtr->savedState;

#ifdef USE_TERMIOS
    iostate.c_iflag = IGNBRK;
    iostate.c_oflag = 0;
    iostate.c_lflag = 0;
    iostate.c_cflag |= CREAD;
    iostate.c_cc[VMIN] = 1;
    iostate.c_cc[VTIME] = 0;
#endif	/* USE_TERMIOS */

#ifdef USE_TERMIO
    iostate.c_iflag = IGNBRK;
    iostate.c_oflag = 0;
    iostate.c_lflag = 0;
    iostate.c_cflag |= CREAD;
    iostate.c_cc[VMIN] = 1;
    iostate.c_cc[VTIME] = 0;
#endif	/* USE_TERMIO */

#ifdef USE_SGTTY
    iostate.sg_flags &= (EVENP | ODDP);
    iostate.sg_flags |= RAW;
#endif	/* USE_SGTTY */

    SETIOSTATE(fd, &iostate);

    return &ttyPtr->fs;
}
#endif	/* SUPPORTS_TTY */

/*
 *----------------------------------------------------------------------
 *
 * TclpOpenFileChannel --
 *
 *	Open an file based channel on Unix systems.
 *
 * Results:
 *	The new channel or NULL. If NULL, the output argument
 *	errorCodePtr is set to a POSIX error and an error message is
 *	left in the interp's result if interp is not NULL.
 *
 * Side effects:
 *	May open the channel and may cause creation of a file on the
 *	file system.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclpOpenFileChannel(interp, fileName, modeString, permissions)
    Tcl_Interp *interp;			/* Interpreter for error reporting;
                                         * can be NULL. */
    char *fileName;			/* Name of file to open. */
    char *modeString;			/* A list of POSIX open modes or
                                         * a string such as "rw". */
    int permissions;			/* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
{
    int fd, seekFlag, mode, channelPermissions;
    FileState *fsPtr;
    char *native, *translation;
    char channelName[16 + TCL_INTEGER_SPACE];
    Tcl_DString ds, buffer;
    Tcl_ChannelType *channelTypePtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    mode = TclGetOpenMode(interp, modeString, &seekFlag);
    if (mode == -1) {
        return NULL;
    }
    switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
	case O_RDONLY:
	    channelPermissions = TCL_READABLE;
	    break;
	case O_WRONLY:
	    channelPermissions = TCL_WRITABLE;
	    break;
	case O_RDWR:
	    channelPermissions = (TCL_READABLE | TCL_WRITABLE);
	    break;
	default:
            /*
             * This may occurr if modeString was "", for example.
             */
	    panic("TclpOpenFileChannel: invalid mode value");
	    return NULL;
    }

    native = Tcl_TranslateFileName(interp, fileName, &buffer);
    if (native == NULL) {
	return NULL;
    }
    native = Tcl_UtfToExternalDString(NULL, native, -1, &ds);
    fd = open(native, mode, permissions);		/* INTL: Native. */




    Tcl_DStringFree(&ds);    
    Tcl_DStringFree(&buffer);

    if (fd < 0) {
        if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "couldn't open \"", fileName, "\": ",
                    Tcl_PosixError(interp), (char *) NULL);
        }
        return NULL;
    }

    /*
     * Set close-on-exec flag on the fd so that child processes will not
     * inherit this fd.
     */
  
    fcntl(fd, F_SETFD, FD_CLOEXEC);
    
    sprintf(channelName, "file%d", fd);
    





#ifdef SUPPORTS_TTY
    if (isatty(fd)) {
	/*
	 * Initialize the serial port to a set of sane parameters.
	 * Especially important if the remote device is set to echo and
	 * the serial port driver was also set to echo -- as soon as a char
	 * were sent to the serial port, the remote device would echo it,
	 * then the serial driver would echo it back to the device, etc.
	 */
	 
	translation = "auto crlf";
	channelTypePtr = &ttyChannelType;
	fsPtr = TtyInit(fd);
    } else 
#endif	/* SUPPORTS_TTY */
    {
	translation = NULL;
	channelTypePtr = &fileChannelType;
	fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState));
    }

    fsPtr->nextPtr = tsdPtr->firstFilePtr;
    tsdPtr->firstFilePtr = fsPtr;
    fsPtr->validMask = channelPermissions | TCL_EXCEPTION;
    fsPtr->fd = fd;
    
    fsPtr->channel = Tcl_CreateChannel(channelTypePtr, channelName,
	    (ClientData) fsPtr, channelPermissions);

    if (seekFlag) {
        if (Tcl_Seek(fsPtr->channel, 0, SEEK_END) < 0) {
            if (interp != (Tcl_Interp *) NULL) {
                Tcl_AppendResult(interp, "couldn't seek to end of file on \"",
                        channelName, "\": ", Tcl_PosixError(interp), NULL);
            }
            Tcl_Close(NULL, fsPtr->channel);
            return NULL;
        }
    }

    if (translation != NULL) {
	/*
	 * Gotcha.  Most modems need a "\r" at the end of the command
	 * sequence.  If you just send "at\n", the modem will not respond
	 * with "OK" because it never got a "\r" to actually invoke the
	 * command.  So, by default, newlines are translated to "\r\n" on
	 * output to avoid "bug" reports that the serial port isn't working.
	 */
	 
	if (Tcl_SetChannelOption(interp, fsPtr->channel, "-translation",
		translation) != TCL_OK) {
	    Tcl_Close(NULL, fsPtr->channel);
	    return NULL;
	}
    }

    return fsPtr->channel;
}
1308
1309
1310
1311
1312
1313
1314
1315
1316

1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330

1331
1332
1333
1334
1335
1336
1337

1338
1339
1340
1341
1342
1343
1344
Tcl_Channel
Tcl_MakeFileChannel(handle, mode)
    ClientData handle;		/* OS level handle. */
    int mode;			/* ORed combination of TCL_READABLE and
                                 * TCL_WRITABLE to indicate file mode. */
{
    FileState *fsPtr;
    char channelName[20];
    int fd = (int) handle;


    if (mode == 0) {
        return NULL;
    }

    sprintf(channelName, "file%d", fd);

    /*
     * Look to see if a channel with this fd and the same mode already exists.
     * If the fd is used, but the mode doesn't match, return NULL.
     */
    
    for (fsPtr = firstFilePtr; fsPtr != NULL; fsPtr = fsPtr->nextPtr) {
	if (fsPtr->fd == fd) {

	    return (mode == fsPtr->validMask) ? fsPtr->channel : NULL;
	}
    }

    fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState));
    fsPtr->nextPtr = firstFilePtr;
    firstFilePtr = fsPtr;

    fsPtr->fd = fd;
    fsPtr->validMask = mode | TCL_EXCEPTION;
    fsPtr->channel = Tcl_CreateChannel(&fileChannelType, channelName,
            (ClientData) fsPtr, mode);
    
    return fsPtr->channel;
}







|

>












|

>
|




|
|
>







1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
Tcl_Channel
Tcl_MakeFileChannel(handle, mode)
    ClientData handle;		/* OS level handle. */
    int mode;			/* ORed combination of TCL_READABLE and
                                 * TCL_WRITABLE to indicate file mode. */
{
    FileState *fsPtr;
    char channelName[16 + TCL_INTEGER_SPACE];
    int fd = (int) handle;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (mode == 0) {
        return NULL;
    }

    sprintf(channelName, "file%d", fd);

    /*
     * Look to see if a channel with this fd and the same mode already exists.
     * If the fd is used, but the mode doesn't match, return NULL.
     */
    
    for (fsPtr = tsdPtr->firstFilePtr; fsPtr != NULL; fsPtr = fsPtr->nextPtr) {
	if (fsPtr->fd == fd) {
	    return ((mode|TCL_EXCEPTION) == fsPtr->validMask) ?
		    fsPtr->channel : NULL;
	}
    }

    fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState));
    fsPtr->nextPtr = tsdPtr->firstFilePtr;
    tsdPtr->firstFilePtr = fsPtr;

    fsPtr->fd = fd;
    fsPtr->validMask = mode | TCL_EXCEPTION;
    fsPtr->channel = Tcl_CreateChannel(&fileChannelType, channelName,
            (ClientData) fsPtr, mode);
    
    return fsPtr->channel;
}
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
     * Delete a file handler that may be active for this socket if this
     * is a server socket - the file handler was created automatically
     * by Tcl as part of the mechanism to accept new client connections.
     * Channel handlers are already deleted in the generic IO channel
     * closing code that called this function, so we do not have to
     * delete them here.
     */
    
    Tcl_DeleteFileHandler(statePtr->fd);

    if (close(statePtr->fd) < 0) {
	errorCode = errno;
    }
    ckfree((char *) statePtr);








|







1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
     * Delete a file handler that may be active for this socket if this
     * is a server socket - the file handler was created automatically
     * by Tcl as part of the mechanism to accept new client connections.
     * Channel handlers are already deleted in the generic IO channel
     * closing code that called this function, so we do not have to
     * delete them here.
     */

    Tcl_DeleteFileHandler(statePtr->fd);

    if (close(statePtr->fd) < 0) {
	errorCode = errno;
    }
    ckfree((char *) statePtr);

1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660

















1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672

1673
1674



1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
{
    TcpState *statePtr = (TcpState *) instanceData;
    struct sockaddr_in sockname;
    struct sockaddr_in peername;
    struct hostent *hostEntPtr;
    int size = sizeof(struct sockaddr_in);
    size_t len = 0;
    char buf[128];

    if (optionName != (char *) NULL) {
        len = strlen(optionName);
    }


















    if ((len == 0) ||
            ((len > 1) && (optionName[1] == 'p') &&
                    (strncmp(optionName, "-peername", len) == 0))) {
        if (getpeername(statePtr->fd, (struct sockaddr *) &peername, &size)
		>= 0) {
            if (len == 0) {
                Tcl_DStringAppendElement(dsPtr, "-peername");
                Tcl_DStringStartSublist(dsPtr);
            }
            Tcl_DStringAppendElement(dsPtr, inet_ntoa(peername.sin_addr));
            hostEntPtr = gethostbyaddr((char *) &(peername.sin_addr),

                    sizeof(peername.sin_addr), AF_INET);
            if (hostEntPtr != (struct hostent *) NULL) {



                Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
            } else {
                Tcl_DStringAppendElement(dsPtr, inet_ntoa(peername.sin_addr));
            }
            sprintf(buf, "%d", ntohs(peername.sin_port));
            Tcl_DStringAppendElement(dsPtr, buf);
            if (len == 0) {
                Tcl_DStringEndSublist(dsPtr);
            } else {
                return TCL_OK;
            }
        } else {







|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
|





|
>
|
|
>
>
>
|



|







1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
{
    TcpState *statePtr = (TcpState *) instanceData;
    struct sockaddr_in sockname;
    struct sockaddr_in peername;
    struct hostent *hostEntPtr;
    int size = sizeof(struct sockaddr_in);
    size_t len = 0;
    char buf[TCL_INTEGER_SPACE];

    if (optionName != (char *) NULL) {
        len = strlen(optionName);
    }

    if ((len > 1) && (optionName[1] == 'e') &&
	    (strncmp(optionName, "-error", len) == 0)) {
	int optlen;
	int err, ret;
    
	optlen = sizeof(int);
	ret = getsockopt(statePtr->fd, SOL_SOCKET, SO_ERROR,
		(char *)&err, &optlen);
	if (ret < 0) {
	    err = errno;
	}
	if (err != 0) {
	    Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(err), -1);
	}
       return TCL_OK;
    }

    if ((len == 0) ||
            ((len > 1) && (optionName[1] == 'p') &&
                    (strncmp(optionName, "-peername", len) == 0))) {
        if (getpeername(statePtr->fd, (struct sockaddr *) &peername,
		&size) >= 0) {
            if (len == 0) {
                Tcl_DStringAppendElement(dsPtr, "-peername");
                Tcl_DStringStartSublist(dsPtr);
            }
            Tcl_DStringAppendElement(dsPtr, inet_ntoa(peername.sin_addr));
            hostEntPtr = gethostbyaddr(			/* INTL: Native. */
		    (char *) &peername.sin_addr,
		    sizeof(peername.sin_addr), AF_INET);
            if (hostEntPtr != NULL) {
		Tcl_DString ds;

		Tcl_ExternalToUtfDString(NULL, hostEntPtr->h_name, -1, &ds);
                Tcl_DStringAppendElement(dsPtr, Tcl_DStringValue(&ds));
            } else {
                Tcl_DStringAppendElement(dsPtr, inet_ntoa(peername.sin_addr));
            }
            TclFormatInt(buf, ntohs(peername.sin_port));
            Tcl_DStringAppendElement(dsPtr, buf);
            if (len == 0) {
                Tcl_DStringEndSublist(dsPtr);
            } else {
                return TCL_OK;
            }
        } else {
1708
1709
1710
1711
1712
1713
1714
1715

1716
1717



1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
        if (getsockname(statePtr->fd, (struct sockaddr *) &sockname, &size)
		>= 0) {
            if (len == 0) {
                Tcl_DStringAppendElement(dsPtr, "-sockname");
                Tcl_DStringStartSublist(dsPtr);
            }
            Tcl_DStringAppendElement(dsPtr, inet_ntoa(sockname.sin_addr));
            hostEntPtr = gethostbyaddr((char *) &(sockname.sin_addr),

                    sizeof(sockname.sin_addr), AF_INET);
            if (hostEntPtr != (struct hostent *) NULL) {



                Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
            } else {
                Tcl_DStringAppendElement(dsPtr, inet_ntoa(sockname.sin_addr));
            }
            sprintf(buf, "%d", ntohs(sockname.sin_port));
            Tcl_DStringAppendElement(dsPtr, buf);
            if (len == 0) {
                Tcl_DStringEndSublist(dsPtr);
            } else {
                return TCL_OK;
            }
        } else {







|
>


>
>
>
|



|







1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
        if (getsockname(statePtr->fd, (struct sockaddr *) &sockname, &size)
		>= 0) {
            if (len == 0) {
                Tcl_DStringAppendElement(dsPtr, "-sockname");
                Tcl_DStringStartSublist(dsPtr);
            }
            Tcl_DStringAppendElement(dsPtr, inet_ntoa(sockname.sin_addr));
            hostEntPtr = gethostbyaddr(			/* INTL: Native. */
		    (char *) &sockname.sin_addr,
                    sizeof(sockname.sin_addr), AF_INET);
            if (hostEntPtr != (struct hostent *) NULL) {
		Tcl_DString ds;

		Tcl_ExternalToUtfDString(NULL, hostEntPtr->h_name, -1, &ds);
                Tcl_DStringAppendElement(dsPtr, Tcl_DStringValue(&ds));
            } else {
                Tcl_DStringAppendElement(dsPtr, inet_ntoa(sockname.sin_addr));
            }
            TclFormatInt(buf, ntohs(sockname.sin_port));
            Tcl_DStringAppendElement(dsPtr, buf);
            if (len == 0) {
                Tcl_DStringEndSublist(dsPtr);
            } else {
                return TCL_OK;
            }
        } else {
1765
1766
1767
1768
1769
1770
1771







1772
1773
1774
1775
1776
1777

1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
    ClientData instanceData;		/* The socket state. */
    int mask;				/* Events of interest; an OR-ed
                                         * combination of TCL_READABLE,
                                         * TCL_WRITABLE and TCL_EXCEPTION. */
{
    TcpState *statePtr = (TcpState *) instanceData;








    if (mask) {
	Tcl_CreateFileHandler(statePtr->fd, mask,
		(Tcl_FileProc *) Tcl_NotifyChannel,
		(ClientData) statePtr->channel);
    } else {
	Tcl_DeleteFileHandler(statePtr->fd);

    }
}

/*
 *----------------------------------------------------------------------
 *
 * TcpGetHandleProc --
 *
 *	Called from Tcl_GetChannelFile to retrieve OS handles from inside
 *	a TCP socket based channel.
 *
 * Results:
 *	Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
 *	there is no handle for the specified direction. 
 *
 * Side effects:







>
>
>
>
>
>
>
|
|
|
|
|
|
>








|







1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
    ClientData instanceData;		/* The socket state. */
    int mask;				/* Events of interest; an OR-ed
                                         * combination of TCL_READABLE,
                                         * TCL_WRITABLE and TCL_EXCEPTION. */
{
    TcpState *statePtr = (TcpState *) instanceData;

    /*
     * Make sure we don't mess with server sockets since they will never
     * be readable or writable at the Tcl level.  This keeps Tcl scripts
     * from interfering with the -accept behavior.
     */

    if (!statePtr->acceptProc) {
	if (mask) {
	    Tcl_CreateFileHandler(statePtr->fd, mask,
		    (Tcl_FileProc *) Tcl_NotifyChannel,
		    (ClientData) statePtr->channel);
	} else {
	    Tcl_DeleteFileHandler(statePtr->fd);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TcpGetHandleProc --
 *
 *	Called from Tcl_GetChannelHandle to retrieve OS handles from inside
 *	a TCP socket based channel.
 *
 * Results:
 *	Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
 *	there is no handle for the specified direction. 
 *
 * Side effects:
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
 *
 * CreateSocket --
 *
 *	This function opens a new socket in client or server mode
 *	and initializes the TcpState structure.
 *
 * Results:
 *	Returns a new TcpState, or NULL with an error in interp->result,
 *	if interp is not NULL.
 *
 * Side effects:
 *	Opens a socket.
 *
 *----------------------------------------------------------------------
 */








|
|







1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
 *
 * CreateSocket --
 *
 *	This function opens a new socket in client or server mode
 *	and initializes the TcpState structure.
 *
 * Results:
 *	Returns a new TcpState, or NULL with an error in the interp's
 *	result, if interp is not NULL.
 *
 * Side effects:
 *	Opens a socket.
 *
 *----------------------------------------------------------------------
 */

1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968

    statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));
    statePtr->flags = 0;
    if (asyncConnect) {
        statePtr->flags = TCP_ASYNC_CONNECT;
    }
    statePtr->fd = sock;
    
    return statePtr;

addressError:
    if (sock != -1) {
        close(sock);
    }
    if (interp != NULL) {







|







2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077

    statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));
    statePtr->flags = 0;
    if (asyncConnect) {
        statePtr->flags = TCP_ASYNC_CONNECT;
    }
    statePtr->fd = sock;

    return statePtr;

addressError:
    if (sock != -1) {
        close(sock);
    }
    if (interp != NULL) {
2000
2001
2002
2003
2004
2005
2006








2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021



2022
2023
2024



2025
2026
2027
2028
2029
2030
2031

    (void) memset((VOID *) sockaddrPtr, '\0', sizeof(struct sockaddr_in));
    sockaddrPtr->sin_family = AF_INET;
    sockaddrPtr->sin_port = htons((unsigned short) (port & 0xFFFF));
    if (host == NULL) {
	addr.s_addr = INADDR_ANY;
    } else {








        addr.s_addr = inet_addr(host);
        if (addr.s_addr == -1) {
            hostent = gethostbyname(host);
            if (hostent != NULL) {
                memcpy((VOID *) &addr,
                        (VOID *) hostent->h_addr_list[0],
                        (size_t) hostent->h_length);
            } else {
#ifdef	EHOSTUNREACH
                errno = EHOSTUNREACH;
#else
#ifdef ENXIO
                errno = ENXIO;
#endif
#endif



                return 0;	/* error */
            }
        }



    }
        
    /*
     * NOTE: On 64 bit machines the assignment below is rumored to not
     * do the right thing. Please report errors related to this if you
     * observe incorrect behavior on 64 bit machines such as DEC Alphas.
     * Should we modify this code to do an explicit memcpy?







>
>
>
>
>
>
>
>
|

|












>
>
>



>
>
>







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
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154

    (void) memset((VOID *) sockaddrPtr, '\0', sizeof(struct sockaddr_in));
    sockaddrPtr->sin_family = AF_INET;
    sockaddrPtr->sin_port = htons((unsigned short) (port & 0xFFFF));
    if (host == NULL) {
	addr.s_addr = INADDR_ANY;
    } else {
	Tcl_DString ds;
	CONST char *native;

	if (host == NULL) {
	    native = NULL;
	} else {
	    native = Tcl_UtfToExternalDString(NULL, host, -1, &ds);
	}
        addr.s_addr = inet_addr(native);		/* INTL: Native. */
        if (addr.s_addr == -1) {
            hostent = gethostbyname(native);		/* INTL: Native. */
            if (hostent != NULL) {
                memcpy((VOID *) &addr,
                        (VOID *) hostent->h_addr_list[0],
                        (size_t) hostent->h_length);
            } else {
#ifdef	EHOSTUNREACH
                errno = EHOSTUNREACH;
#else
#ifdef ENXIO
                errno = ENXIO;
#endif
#endif
		if (native != NULL) {
		    Tcl_DStringFree(&ds);
		}
                return 0;	/* error */
            }
        }
	if (native != NULL) {
	    Tcl_DStringFree(&ds);
	}
    }
        
    /*
     * NOTE: On 64 bit machines the assignment below is rumored to not
     * do the right thing. Please report errors related to this if you
     * observe incorrect behavior on 64 bit machines such as DEC Alphas.
     * Should we modify this code to do an explicit memcpy?
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
    char *myaddr;			/* Client-side address */
    int myport;				/* Client-side port */
    int async;				/* If nonzero, attempt to do an
                                         * asynchronous connect. Otherwise
                                         * we do a blocking connect. */
{
    TcpState *statePtr;
    char channelName[20];

    /*
     * Create a new client socket and wrap it in a channel.
     */

    statePtr = CreateSocket(interp, port, host, 0, myaddr, myport, async);
    if (statePtr == NULL) {







|







2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
    char *myaddr;			/* Client-side address */
    int myport;				/* Client-side port */
    int async;				/* If nonzero, attempt to do an
                                         * asynchronous connect. Otherwise
                                         * we do a blocking connect. */
{
    TcpState *statePtr;
    char channelName[16 + TCL_INTEGER_SPACE];

    /*
     * Create a new client socket and wrap it in a channel.
     */

    statePtr = CreateSocket(interp, port, host, 0, myaddr, myport, async);
    if (statePtr == NULL) {
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
 */

Tcl_Channel
Tcl_MakeTcpClientChannel(sock)
    ClientData sock;		/* The socket to wrap up into a channel. */
{
    TcpState *statePtr;
    char channelName[20];

    statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));
    statePtr->fd = (int) sock;
    statePtr->acceptProc = NULL;
    statePtr->acceptProcData = (ClientData) NULL;

    sprintf(channelName, "sock%d", statePtr->fd);







|







2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
 */

Tcl_Channel
Tcl_MakeTcpClientChannel(sock)
    ClientData sock;		/* The socket to wrap up into a channel. */
{
    TcpState *statePtr;
    char channelName[16 + TCL_INTEGER_SPACE];

    statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState));
    statePtr->fd = (int) sock;
    statePtr->acceptProc = NULL;
    statePtr->acceptProcData = (ClientData) NULL;

    sprintf(channelName, "sock%d", statePtr->fd);
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
 *
 * Tcl_OpenTcpServer --
 *
 *	Opens a TCP server socket and creates a channel around it.
 *
 * Results:
 *	The channel or NULL if failed. If an error occurred, an
 *	error message is left in interp->result if interp is
 *	not NULL.
 *
 * Side effects:
 *	Opens a server socket and creates a new channel.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_OpenTcpServer(interp, port, myHost, acceptProc, acceptProcData)
    Tcl_Interp *interp;			/* For error reporting - may be
                                         * NULL. */
    int port;				/* Port number to open. */
    char *myHost;			/* Name of local host. */
    Tcl_TcpAcceptProc *acceptProc;	/* Callback for accepting connections
                                         * from new clients. */
    ClientData acceptProcData;		/* Data for the callback. */
{
    TcpState *statePtr;
    char channelName[20];

    /*
     * Create a new client socket and wrap it in a channel.
     */

    statePtr = CreateSocket(interp, port, myHost, 1, NULL, 0, 0);
    if (statePtr == NULL) {







|



















|







2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
 *
 * Tcl_OpenTcpServer --
 *
 *	Opens a TCP server socket and creates a channel around it.
 *
 * Results:
 *	The channel or NULL if failed. If an error occurred, an
 *	error message is left in the interp's result if interp is
 *	not NULL.
 *
 * Side effects:
 *	Opens a server socket and creates a new channel.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_OpenTcpServer(interp, port, myHost, acceptProc, acceptProcData)
    Tcl_Interp *interp;			/* For error reporting - may be
                                         * NULL. */
    int port;				/* Port number to open. */
    char *myHost;			/* Name of local host. */
    Tcl_TcpAcceptProc *acceptProc;	/* Callback for accepting connections
                                         * from new clients. */
    ClientData acceptProcData;		/* Data for the callback. */
{
    TcpState *statePtr;
    char channelName[16 + TCL_INTEGER_SPACE];

    /*
     * Create a new client socket and wrap it in a channel.
     */

    statePtr = CreateSocket(interp, port, myHost, 1, NULL, 0, 0);
    if (statePtr == NULL) {
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
    int mask;				/* Not used. */
{
    TcpState *sockState;		/* Client data of server socket. */
    int newsock;			/* The new client socket */
    TcpState *newSockState;		/* State for new socket. */
    struct sockaddr_in addr;		/* The remote address */
    int len;				/* For accept interface */
    char channelName[20];

    sockState = (TcpState *) data;

    len = sizeof(struct sockaddr_in);
    newsock = accept(sockState->fd, (struct sockaddr *)&addr, &len);
    if (newsock < 0) {
        return;
    }

    /*
     * Set close-on-exec flag to prevent the newly accepted socket from
     * being inherited by child processes.
     */

    (void) fcntl(newsock, F_SETFD, FD_CLOEXEC);
    
    newSockState = (TcpState *) ckalloc((unsigned) sizeof(TcpState));

    newSockState->flags = 0;
    newSockState->fd = newsock;
    newSockState->acceptProc = (Tcl_TcpAcceptProc *) NULL;
    newSockState->acceptProcData = (ClientData) NULL;
        
    sprintf(channelName, "sock%d", newsock);
    newSockState->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
	    (ClientData) newSockState, (TCL_READABLE | TCL_WRITABLE));

    Tcl_SetChannelOption((Tcl_Interp *) NULL, newSockState->channel,
	    "-translation", "auto crlf");

    if (sockState->acceptProc != (Tcl_TcpAcceptProc *) NULL) {
	(sockState->acceptProc) (sockState->acceptProcData,
		newSockState->channel, inet_ntoa(addr.sin_addr),
		ntohs(addr.sin_port));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetDefaultStdChannel --
 *
 *	Creates channels for standard input, standard output or standard
 *	error output if they do not already exist.
 *
 * Results:
 *	Returns the specified default standard channel, or NULL.
 *
 * Side effects:
 *	May cause the creation of a standard channel and the underlying
 *	file.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclGetDefaultStdChannel(type)
    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{
    Tcl_Channel channel = NULL;
    int fd = 0;			/* Initializations needed to prevent */
    int mode = 0;		/* compiler warning (used before set). */
    char *bufMode = NULL;








|




|















|
|





|
|

|
|








|















|







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
    int mask;				/* Not used. */
{
    TcpState *sockState;		/* Client data of server socket. */
    int newsock;			/* The new client socket */
    TcpState *newSockState;		/* State for new socket. */
    struct sockaddr_in addr;		/* The remote address */
    int len;				/* For accept interface */
    char channelName[16 + TCL_INTEGER_SPACE];

    sockState = (TcpState *) data;

    len = sizeof(struct sockaddr_in);
    newsock = accept(sockState->fd, (struct sockaddr *) &addr, &len);
    if (newsock < 0) {
        return;
    }

    /*
     * Set close-on-exec flag to prevent the newly accepted socket from
     * being inherited by child processes.
     */

    (void) fcntl(newsock, F_SETFD, FD_CLOEXEC);
    
    newSockState = (TcpState *) ckalloc((unsigned) sizeof(TcpState));

    newSockState->flags = 0;
    newSockState->fd = newsock;
    newSockState->acceptProc = NULL;
    newSockState->acceptProcData = NULL;
        
    sprintf(channelName, "sock%d", newsock);
    newSockState->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
	    (ClientData) newSockState, (TCL_READABLE | TCL_WRITABLE));

    Tcl_SetChannelOption(NULL, newSockState->channel, "-translation",
	    "auto crlf");

    if (sockState->acceptProc != NULL) {
	(*sockState->acceptProc)(sockState->acceptProcData,
		newSockState->channel, inet_ntoa(addr.sin_addr),
		ntohs(addr.sin_port));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpGetDefaultStdChannel --
 *
 *	Creates channels for standard input, standard output or standard
 *	error output if they do not already exist.
 *
 * Results:
 *	Returns the specified default standard channel, or NULL.
 *
 * Side effects:
 *	May cause the creation of a standard channel and the underlying
 *	file.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclpGetDefaultStdChannel(type)
    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{
    Tcl_Channel channel = NULL;
    int fd = 0;			/* Initializations needed to prevent */
    int mode = 0;		/* compiler warning (used before set). */
    char *bufMode = NULL;

2308
2309
2310
2311
2312
2313
2314



2315
2316
2317
2318
2319
2320
2321
            break;
	default:
	    panic("TclGetDefaultStdChannel: Unexpected channel type");
	    break;
    }

    channel = Tcl_MakeFileChannel((ClientData) fd, mode);




    /*
     * Set up the normal channel options for stdio handles.
     */

    Tcl_SetChannelOption(NULL, channel, "-translation", "auto");
    Tcl_SetChannelOption(NULL, channel, "-buffering", bufMode);







>
>
>







2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
            break;
	default:
	    panic("TclGetDefaultStdChannel: Unexpected channel type");
	    break;
    }

    channel = Tcl_MakeFileChannel((ClientData) fd, mode);
    if (channel == NULL) {
	return NULL;
    }

    /*
     * Set up the normal channel options for stdio handles.
     */

    Tcl_SetChannelOption(NULL, channel, "-translation", "auto");
    Tcl_SetChannelOption(NULL, channel, "-buffering", bufMode);
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
 *
 * Results:
 *	A standard Tcl result. If the channel is registered in the given
 *	interpreter and it is managed by the "file" channel driver, and
 *	it is open for the requested mode, then the output parameter
 *	filePtr is set to a FILE * for the underlying file. On error, the
 *	filePtr is not set, TCL_ERROR is returned and an error message is
 *	left in interp->result.
 *
 * Side effects:
 *	May invoke fdopen to create the FILE * for the requested file.
 *
 *----------------------------------------------------------------------
 */








|







2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
 *
 * Results:
 *	A standard Tcl result. If the channel is registered in the given
 *	interpreter and it is managed by the "file" channel driver, and
 *	it is open for the requested mode, then the output parameter
 *	filePtr is set to a FILE * for the underlying file. On error, the
 *	filePtr is not set, TCL_ERROR is returned and an error message is
 *	left in the interp's result.
 *
 * Side effects:
 *	May invoke fdopen to create the FILE * for the requested file.
 *
 *----------------------------------------------------------------------
 */

2381
2382
2383
2384
2385
2386
2387
2388




2389
2390
2391
2392
2393
2394
2395
    /*
     * We allow creating a FILE * out of file based, pipe based and socket
     * based channels. We currently do not allow any other channel types,
     * because it is likely that stdio will not know what to do with them.
     */

    chanTypePtr = Tcl_GetChannelType(chan);
    if ((chanTypePtr == &fileChannelType) || (chanTypePtr == &tcpChannelType)




	    || (strcmp(chanTypePtr->typeName, "pipe") == 0)) {
        if (Tcl_GetChannelHandle(chan,
		(forWriting ? TCL_WRITABLE : TCL_READABLE),
		(ClientData*) &data) == TCL_OK) {
	    fd = (int) data;

	    /*







|
>
>
>
>







2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
    /*
     * We allow creating a FILE * out of file based, pipe based and socket
     * based channels. We currently do not allow any other channel types,
     * because it is likely that stdio will not know what to do with them.
     */

    chanTypePtr = Tcl_GetChannelType(chan);
    if ((chanTypePtr == &fileChannelType)
#ifdef SUPPORTS_TTY
	    || (chanTypePtr == &ttyChannelType)
#endif	/* SUPPORTS_TTY */
	    || (chanTypePtr == &tcpChannelType)
	    || (strcmp(chanTypePtr->typeName, "pipe") == 0)) {
        if (Tcl_GetChannelHandle(chan,
		(forWriting ? TCL_WRITABLE : TCL_READABLE),
		(ClientData*) &data) == TCL_OK) {
	    fd = (int) data;

	    /*
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
				 * milliseconds.  A value of 0 means don't
				 * wait at all, and a value of -1 means
				 * wait forever. */
{
    Tcl_Time abortTime, now;
    struct timeval blockTime, *timeoutPtr;
    int index, bit, numFound, result = 0;
    static fd_mask readyMasks[3*MASK_SIZE];
				/* This array reflects the readable/writable
				 * conditions that were found to exist by the
				 * last call to select. */

    /*
     * If there is a non-zero finite timeout, compute the time when
     * we give up.







|







2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
				 * milliseconds.  A value of 0 means don't
				 * wait at all, and a value of -1 means
				 * wait forever. */
{
    Tcl_Time abortTime, now;
    struct timeval blockTime, *timeoutPtr;
    int index, bit, numFound, result = 0;
    fd_mask readyMasks[3*MASK_SIZE];
				/* This array reflects the readable/writable
				 * conditions that were found to exist by the
				 * last call to select. */

    /*
     * If there is a non-zero finite timeout, compute the time when
     * we give up.

Changes to unix/tclUnixEvent.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclUnixEvent.c --
 *
 *	This file implements Unix specific event related routines.
 *
 * 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.
 *
 * SCCS: @(#) tclUnixEvent.c 1.1 97/03/04 14:19:34
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 *----------------------------------------------------------------------










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclUnixEvent.c --
 *
 *	This file implements Unix specific event related routines.
 *
 * 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: tclUnixEvent.c,v 1.1.2.2 1998/09/24 23:59:45 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 *----------------------------------------------------------------------
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 *----------------------------------------------------------------------
 */

void
Tcl_Sleep(ms)
    int ms;			/* Number of milliseconds to sleep. */
{
    static struct timeval delay;
    Tcl_Time before, after;

    /*
     * The only trick here is that select appears to return early
     * under some conditions, so we have to check to make sure that
     * the right amount of time really has elapsed.  If it's too
     * early, go back to sleep again.







|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 *----------------------------------------------------------------------
 */

void
Tcl_Sleep(ms)
    int ms;			/* Number of milliseconds to sleep. */
{
    struct timeval delay;
    Tcl_Time before, after;

    /*
     * The only trick here is that select appears to return early
     * under some conditions, so we have to check to make sure that
     * the right amount of time really has elapsed.  If it's too
     * early, go back to sleep again.

Changes to unix/tclUnixFCmd.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tclUnixFCmd.c
 *
 *      This file implements the unix specific portion of file manipulation 
 *      subcommands of the "file" command.  All filename arguments should
 *	already be translated to native format.
 *
 * 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.
 *
 * SCCS: @(#) tclUnixFCmd.c 1.31 97/10/13 16:51:14
 *
 * Portions of this code were derived from NetBSD source code which has
 * the following copyright notice:
 *
 * Copyright (c) 1988, 1993, 1994
 *      The Regents of the University of California.  All rights reserved.
 *







|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tclUnixFCmd.c
 *
 *      This file implements the unix specific portion of file manipulation 
 *      subcommands of the "file" command.  All filename arguments should
 *	already be translated to native format.
 *
 * Copyright (c) 1996-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: tclUnixFCmd.c,v 1.1.2.5 1999/04/06 20:59:58 rjohnson Exp $
 *
 * Portions of this code were derived from NetBSD source code which has
 * the following copyright notice:
 *
 * Copyright (c) 1988, 1993, 1994
 *      The Regents of the University of California.  All rights reserved.
 *
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
 * SUCH DAMAGE.
 */

#include "tclInt.h"
#include "tclPort.h"
#include <utime.h>
#include <grp.h>






/*
 * The following constants specify the type of callback when
 * TraverseUnixTree() calls the traverseProc()
 */

#define DOTREE_PRED   1     /* pre-order directory  */
#define DOTREE_POSTD  2     /* post-order directory */
#define DOTREE_F      3     /* regular file */

/*
 * Callbacks for file attributes code.
 */

static int		GetGroupAttribute _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		GetOwnerAttribute _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		GetPermissionsAttribute _ANSI_ARGS_((
			    Tcl_Interp *interp, int objIndex, char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		SetGroupAttribute _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj *attributePtr));
static int		SetOwnerAttribute _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj *attributePtr));
static int		SetPermissionsAttribute _ANSI_ARGS_((
			    Tcl_Interp *interp, int objIndex, char *fileName,
			    Tcl_Obj *attributePtr));
			  
/*
 * Prototype for the TraverseUnixTree callback function.
 */

typedef int (TraversalProc) _ANSI_ARGS_((char *src, char *dst, 

        struct stat *sb, int type, Tcl_DString *errorPtr));

/*
 * Constants and variables necessary for file attributes subcommand.
 */

enum {
    UNIX_GROUP_ATTRIBUTE,
    UNIX_OWNER_ATTRIBUTE,
    UNIX_PERMISSIONS_ATTRIBUTE
};

char *tclpFileAttrStrings[] = {"-group", "-owner", "-permissions",



	(char *) NULL};


CONST TclFileAttrProcs tclpFileAttrProcs[] = {
	{GetGroupAttribute, SetGroupAttribute},
	{GetOwnerAttribute, SetOwnerAttribute},
	{GetPermissionsAttribute, SetPermissionsAttribute}};


/*
 * Declarations for local procedures defined in this file:
 */

static int		CopyFile _ANSI_ARGS_((char *src, char *dst, 
			    struct stat *srcStatBufPtr));
static int		CopyFileAtts _ANSI_ARGS_((char *src, char *dst, 
			    struct stat *srcStatBufPtr));








static int		TraversalCopy _ANSI_ARGS_((char *src, char *dst, 
			    struct stat *sbPtr, int type,
			    Tcl_DString *errorPtr));
static int		TraversalDelete _ANSI_ARGS_((char *src, char *dst, 
			    struct stat *sbPtr, int type,
			    Tcl_DString *errorPtr));
static int		TraverseUnixTree _ANSI_ARGS_((
			    TraversalProc *traversalProc,
			    Tcl_DString *sourcePath, Tcl_DString *destPath,
			    Tcl_DString *errorPtr));

/*
 *---------------------------------------------------------------------------
 *
 * TclpRenameFile --
 *
 *      Changes the name of an existing file or directory, from src to dst.
 *	If src and dst refer to the same file or directory, does nothing
 *	and returns success.  Otherwise if dst already exists, it will be
 *	deleted and replaced by src subject to the following conditions:
 *	    If src is a directory, dst may be an empty directory.
 *	    If src is a file, dst may be a file.







>
>
>
>
>















|


|


|
|

|


|


|
|





|
>
|











|
>
>
>
|
>
>

|
|
|
>





|
|
|
|
>
>
>
>
>
>
>
>
|
|
|
|
|
|


|





|







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
 * SUCH DAMAGE.
 */

#include "tclInt.h"
#include "tclPort.h"
#include <utime.h>
#include <grp.h>
#ifndef HAVE_ST_BLKSIZE
#ifndef NO_FSTATFS
#include <sys/statfs.h>
#endif
#endif

/*
 * The following constants specify the type of callback when
 * TraverseUnixTree() calls the traverseProc()
 */

#define DOTREE_PRED   1     /* pre-order directory  */
#define DOTREE_POSTD  2     /* post-order directory */
#define DOTREE_F      3     /* regular file */

/*
 * Callbacks for file attributes code.
 */

static int		GetGroupAttribute _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		GetOwnerAttribute _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		GetPermissionsAttribute _ANSI_ARGS_((
			    Tcl_Interp *interp, int objIndex,
			    CONST char *fileName, Tcl_Obj **attributePtrPtr));
static int		SetGroupAttribute _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj *attributePtr));
static int		SetOwnerAttribute _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj *attributePtr));
static int		SetPermissionsAttribute _ANSI_ARGS_((
			    Tcl_Interp *interp, int objIndex,
			    CONST char *fileName, Tcl_Obj *attributePtr));
			  
/*
 * Prototype for the TraverseUnixTree callback function.
 */

typedef int (TraversalProc) _ANSI_ARGS_((Tcl_DString *srcPtr,
	Tcl_DString *dstPtr, CONST struct stat *statBufPtr, int type,
	Tcl_DString *errorPtr));

/*
 * Constants and variables necessary for file attributes subcommand.
 */

enum {
    UNIX_GROUP_ATTRIBUTE,
    UNIX_OWNER_ATTRIBUTE,
    UNIX_PERMISSIONS_ATTRIBUTE
};

char *tclpFileAttrStrings[] = {
    "-group",
    "-owner",
    "-permissions",
    (char *) NULL
};

CONST TclFileAttrProcs tclpFileAttrProcs[] = {
    {GetGroupAttribute,		SetGroupAttribute},
    {GetOwnerAttribute,		SetOwnerAttribute},
    {GetPermissionsAttribute,	SetPermissionsAttribute}
};

/*
 * Declarations for local procedures defined in this file:
 */

static int		CopyFile _ANSI_ARGS_((CONST char *src,
			    CONST char *dst, CONST struct stat *statBufPtr));
static int		CopyFileAtts _ANSI_ARGS_((CONST char *src,
			    CONST char *dst, CONST struct stat *statBufPtr));
static int		DoCopyFile _ANSI_ARGS_((Tcl_DString *srcPtr,
			    Tcl_DString *dstPtr));
static int		DoCreateDirectory _ANSI_ARGS_((Tcl_DString *pathPtr));
static int		DoDeleteFile _ANSI_ARGS_((Tcl_DString *pathPtr));
static int		DoRemoveDirectory _ANSI_ARGS_((Tcl_DString *pathPtr,
			    int recursive, Tcl_DString *errorPtr));
static int		DoRenameFile _ANSI_ARGS_((CONST char *src,
			    CONST char *dst));
static int		TraversalCopy _ANSI_ARGS_((Tcl_DString *srcPtr,
			    Tcl_DString *dstPtr, CONST struct stat *statBufPtr,
			    int type, Tcl_DString *errorPtr));
static int		TraversalDelete _ANSI_ARGS_((Tcl_DString *srcPtr,
			    Tcl_DString *dstPtr, CONST struct stat *statBufPtr,
			    int type, Tcl_DString *errorPtr));
static int		TraverseUnixTree _ANSI_ARGS_((
			    TraversalProc *traversalProc,
			    Tcl_DString *sourcePtr, Tcl_DString *destPtr,
			    Tcl_DString *errorPtr));

/*
 *---------------------------------------------------------------------------
 *
 * TclpRenameFile, DoRenameFile --
 *
 *      Changes the name of an existing file or directory, from src to dst.
 *	If src and dst refer to the same file or directory, does nothing
 *	and returns success.  Otherwise if dst already exists, it will be
 *	deleted and replaced by src subject to the following conditions:
 *	    If src is a directory, dst may be an empty directory.
 *	    If src is a file, dst may be a file.
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
 *	delete if errno is EXDEV.
 *
 *---------------------------------------------------------------------------
 */

int
TclpRenameFile(src, dst)
    char *src;			/* Pathname of file or dir to be renamed. */

    char *dst;			/* New pathname of file or directory. */

{



















    if (rename(src, dst) == 0) {
	return TCL_OK;
    }
    if (errno == ENOTEMPTY) {
	errno = EEXIST;
    }






#ifdef sparc





    /*
     * SunOS 4.1.4 reports overwriting a non-empty directory with a
     * directory as EINVAL instead of EEXIST (first rule out the correct
     * EINVAL result code for moving a directory into itself).  Must be
     * conditionally compiled because realpath() is only defined on SunOS.
     */

    if (errno == EINVAL) {
	char srcPath[MAXPATHLEN], dstPath[MAXPATHLEN];
	DIR *dirPtr;
	struct dirent *dirEntPtr;

	if ((realpath(src, srcPath) != NULL)
		&& (realpath(dst, dstPath) != NULL)
		&& (strncmp(srcPath, dstPath, strlen(srcPath)) != 0)) {
	    dirPtr = opendir(dst);
	    if (dirPtr != NULL) {

		while ((dirEntPtr = readdir(dirPtr)) != NULL) {



		    if ((strcmp(dirEntPtr->d_name, ".") != 0) &&
			    (strcmp(dirEntPtr->d_name, "..") != 0)) {
			errno = EEXIST;
			closedir(dirPtr);
			return TCL_ERROR;
		    }
		}
		closedir(dirPtr);
	    }
	}
	errno = EINVAL;
    }
#endif	/* sparc */

    if (strcmp(src, "/") == 0) {
	/*
	 * Alpha reports renaming / as EBUSY and Linux reports it as EACCES,
	 * instead of EINVAL.
	 */
	 







|
>
|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|






>
>
>
>
>
|
>
>
>
>
>




|







|
|

|

>
|
>
>
>












|







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
 *	delete if errno is EXDEV.
 *
 *---------------------------------------------------------------------------
 */

int
TclpRenameFile(src, dst)
    CONST char *src;		/* Pathname of file or dir to be renamed
				 * (UTF-8). */
    CONST char *dst;		/* New pathname of file or directory
				 * (UTF-8). */
{
    int result;
    Tcl_DString srcString, dstString;

    Tcl_UtfToExternalDString(NULL, src, -1, &srcString);
    Tcl_UtfToExternalDString(NULL, dst, -1, &dstString);
    result = DoRenameFile(Tcl_DStringValue(&srcString),
	    Tcl_DStringValue(&dstString));
    Tcl_DStringFree(&srcString);
    Tcl_DStringFree(&dstString);
    return result;
}

static int
DoRenameFile(src, dst)
    CONST char *src;		/* Pathname of file or dir to be renamed
				 * (native). */
    CONST char *dst;		/* New pathname of file or directory
				 * (native). */
{
    if (rename(src, dst) == 0) {			/* INTL: Native. */
	return TCL_OK;
    }
    if (errno == ENOTEMPTY) {
	errno = EEXIST;
    }

    /*
     * IRIX returns EIO when you attept to move a directory into
     * itself.  We just map EIO to EINVAL get the right message on SGI.
     * Most platforms don't return EIO except in really strange cases.
     */
    
    if (errno == EIO) {
	errno = EINVAL;
    }
    
#ifndef NO_REALPATH
    /*
     * SunOS 4.1.4 reports overwriting a non-empty directory with a
     * directory as EINVAL instead of EEXIST (first rule out the correct
     * EINVAL result code for moving a directory into itself).  Must be
     * conditionally compiled because realpath() not defined on all systems.
     */

    if (errno == EINVAL) {
	char srcPath[MAXPATHLEN], dstPath[MAXPATHLEN];
	DIR *dirPtr;
	struct dirent *dirEntPtr;

	if ((realpath((char *) src, srcPath) != NULL)	/* INTL: Native. */
		&& (realpath((char *) dst, dstPath) != NULL) /* INTL: Native. */
		&& (strncmp(srcPath, dstPath, strlen(srcPath)) != 0)) {
	    dirPtr = opendir(dst);			/* INTL: Native. */
	    if (dirPtr != NULL) {
		while (1) {
		    dirEntPtr = readdir(dirPtr);	/* INTL: Native. */
		    if (dirEntPtr == NULL) {
			break;
		    }
		    if ((strcmp(dirEntPtr->d_name, ".") != 0) &&
			    (strcmp(dirEntPtr->d_name, "..") != 0)) {
			errno = EEXIST;
			closedir(dirPtr);
			return TCL_ERROR;
		    }
		}
		closedir(dirPtr);
	    }
	}
	errno = EINVAL;
    }
#endif	/* !NO_REALPATH */

    if (strcmp(src, "/") == 0) {
	/*
	 * Alpha reports renaming / as EBUSY and Linux reports it as EACCES,
	 * instead of EINVAL.
	 */
	 
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    return TCL_ERROR;
}


/*
 *---------------------------------------------------------------------------
 *
 * TclpCopyFile --
 *
 *      Copy a single file (not a directory).  If dst already exists and
 *	is not a directory, it is removed.
 *
 * Results:
 *	If the file was successfully copied, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the







|







281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
    return TCL_ERROR;
}


/*
 *---------------------------------------------------------------------------
 *
 * TclpCopyFile, DoCopyFile --
 *
 *      Copy a single file (not a directory).  If dst already exists and
 *	is not a directory, it is removed.
 *
 * Results:
 *	If the file was successfully copied, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the
252
253
254
255
256
257
258
259
260
261
















262
263
264


265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296



297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
 *	not the contents of the device that it refers to.
 *
 *---------------------------------------------------------------------------
 */

int 
TclpCopyFile(src, dst)
    char *src;			/* Pathname of file to be copied. */
    char *dst;			/* Pathname of file to copy to. */
{
















    struct stat srcStatBuf, dstStatBuf;
    char link[MAXPATHLEN];
    int length;



    /*
     * Have to do a stat() to determine the filetype.
     */
    
    if (lstat(src, &srcStatBuf) != 0) {
	return TCL_ERROR;
    }
    if (S_ISDIR(srcStatBuf.st_mode)) {
	errno = EISDIR;
	return TCL_ERROR;
    }

    /*
     * symlink, and some of the other calls will fail if the target 
     * exists, so we remove it first
     */
    
    if (lstat(dst, &dstStatBuf) == 0) {
	if (S_ISDIR(dstStatBuf.st_mode)) {
	    errno = EISDIR;
	    return TCL_ERROR;
	}
    }
    if (unlink(dst) != 0) {
	if (errno != ENOENT) {
	    return TCL_ERROR;
	} 
    }

    switch ((int) (srcStatBuf.st_mode & S_IFMT)) {
        case S_IFLNK:



	    length = readlink(src, link, sizeof(link)); 
	    if (length == -1) {
		return TCL_ERROR;
	    }
	    link[length] = '\0';
	    if (symlink(link, dst) < 0) {
		return TCL_ERROR;
	    }
	    break;

        case S_IFBLK:
        case S_IFCHR:
	    if (mknod(dst, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) {

		return TCL_ERROR;
	    }
	    return CopyFileAtts(src, dst, &srcStatBuf);

        case S_IFIFO:
	    if (mkfifo(dst, srcStatBuf.st_mode) < 0) {
		return TCL_ERROR;
	    }
	    return CopyFileAtts(src, dst, &srcStatBuf);

        default:
	    return CopyFile(src, dst, &srcStatBuf);
    }
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CopyFile - 







|
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|
>
>





|












|





|






|
>
>
>
|




|



|

|
|
>



|
|
|



|
|

|
|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
 *	not the contents of the device that it refers to.
 *
 *---------------------------------------------------------------------------
 */

int 
TclpCopyFile(src, dst)
    CONST char *src;		/* Pathname of file to be copied (UTF-8). */
    CONST char *dst;		/* Pathname of file to copy to (UTF-8). */
{
    int result;
    Tcl_DString srcString, dstString;

    Tcl_UtfToExternalDString(NULL, src, -1, &srcString);
    Tcl_UtfToExternalDString(NULL, dst, -1, &dstString);
    result = DoCopyFile(&srcString, &dstString);
    Tcl_DStringFree(&srcString);
    Tcl_DStringFree(&dstString);
    return result;
}

static int
DoCopyFile(srcPtr, dstPtr)
    Tcl_DString *srcPtr;	/* Pathname of file to be copied (native). */
    Tcl_DString *dstPtr;	/* Pathname of file to copy to (native). */
{
    struct stat srcStatBuf, dstStatBuf;
    CONST char *src, *dst;

    src = Tcl_DStringValue(srcPtr);
    dst = Tcl_DStringValue(dstPtr);

    /*
     * Have to do a stat() to determine the filetype.
     */
    
    if (lstat(src, &srcStatBuf) != 0) {			/* INTL: Native. */
	return TCL_ERROR;
    }
    if (S_ISDIR(srcStatBuf.st_mode)) {
	errno = EISDIR;
	return TCL_ERROR;
    }

    /*
     * symlink, and some of the other calls will fail if the target 
     * exists, so we remove it first
     */
    
    if (lstat(dst, &dstStatBuf) == 0) {			/* INTL: Native. */
	if (S_ISDIR(dstStatBuf.st_mode)) {
	    errno = EISDIR;
	    return TCL_ERROR;
	}
    }
    if (unlink(dst) != 0) {				/* INTL: Native. */
	if (errno != ENOENT) {
	    return TCL_ERROR;
	} 
    }

    switch ((int) (srcStatBuf.st_mode & S_IFMT)) {
        case S_IFLNK: {
	    char link[MAXPATHLEN];
	    int length;

	    length = readlink(src, link, sizeof(link)); /* INTL: Native. */
	    if (length == -1) {
		return TCL_ERROR;
	    }
	    link[length] = '\0';
	    if (symlink(link, dst) < 0) {		/* INTL: Native. */
		return TCL_ERROR;
	    }
	    break;
	}
        case S_IFBLK:
        case S_IFCHR: {
	    if (mknod(dst, srcStatBuf.st_mode,		/* INTL: Native. */
		    srcStatBuf.st_rdev) < 0) {
		return TCL_ERROR;
	    }
	    return CopyFileAtts(src, dst, &srcStatBuf);
	}
        case S_IFIFO: {
	    if (mkfifo(dst, srcStatBuf.st_mode) < 0) {	/* INTL: Native. */
		return TCL_ERROR;
	    }
	    return CopyFileAtts(src, dst, &srcStatBuf);
	}
        default: {
	    return CopyFile(src, dst, &srcStatBuf);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * CopyFile - 
338
339
340
341
342
343
344
345
346
347


348
349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366








367


368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
















429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
 * Side effects:
 *      A file is copied.  Dst will be overwritten if it exists.
 *
 *----------------------------------------------------------------------
 */

static int 
CopyFile(src, dst, srcStatBufPtr) 
    char *src;                   /* Pathname of file to copy. */
    char *dst;                   /* Pathname of file to create/overwrite. */


    struct stat *srcStatBufPtr;  /* Used to determine mode and blocksize */
{
    int srcFd;
    int dstFd;
    u_int blockSize;   /* Optimal I/O blocksize for filesystem */
    char *buffer;      /* Data buffer for copy */
    size_t nread;

    if ((srcFd = open(src, O_RDONLY, 0)) < 0) { 
	return TCL_ERROR;
    }

    dstFd = open(dst, O_CREAT | O_TRUNC | O_WRONLY, srcStatBufPtr->st_mode);

    if (dstFd < 0) {
	close(srcFd); 
	return TCL_ERROR;
    }

#if HAVE_ST_BLKSIZE








    blockSize = srcStatBufPtr->st_blksize;


#else
    blockSize = 4096;

#endif

    buffer = ckalloc(blockSize);
    while (1) {
	nread = read(srcFd, buffer, blockSize);
	if ((nread == -1) || (nread == 0)) {
	    break;
	}
	if (write(dstFd, buffer, nread) != nread) {
	    nread = (size_t) -1;
	    break;
	}
    }
	
    ckfree(buffer);
    close(srcFd);
    if ((close(dstFd) != 0) || (nread == -1)) {
	unlink(dst);
	return TCL_ERROR;
    }
    if (CopyFileAtts(src, dst, srcStatBufPtr) == TCL_ERROR) {
	/*
	 * The copy succeeded, but setting the permissions failed, so be in
	 * a consistent state, we remove the file that was created by the
	 * copy.
	 */

	unlink(dst);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpDeleteFile --
 *
 *      Removes a single file (not a directory).
 *
 * Results:
 *	If the file was successfully deleted, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the
 *	error.  Some possible values for errno are:
 *
 *	EACCES:     a parent directory can't be read and/or written.
 *	EISDIR:	    path is a directory.
 *	ENOENT:	    path doesn't exist or is "".
 *
 * Side effects:
 *      The file is deleted, even if it is read-only.
 *
 *---------------------------------------------------------------------------
 */

int
TclpDeleteFile(path) 
    char *path;			/* Pathname of file to be removed. */
{
















    if (unlink(path) != 0) {
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpCreateDirectory --
 *
 *      Creates the specified directory.  All parent directories of the
 *	specified directory must already exist.  The directory is
 *	automatically created with permissions so that user can access
 *	the new directory and create new files or subdirectories in it.
 *
 * Results:







|
|
|
>
>
|







|



|
>





|
>
>
>
>
>
>
>
>
|
>
>
|

>

















|


|






|








|




















|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|








|







415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
 * Side effects:
 *      A file is copied.  Dst will be overwritten if it exists.
 *
 *----------------------------------------------------------------------
 */

static int 
CopyFile(src, dst, statBufPtr) 
    CONST char *src;		/* Pathname of file to copy (native). */
    CONST char *dst;		/* Pathname of file to create/overwrite
				 * (native). */
    CONST struct stat *statBufPtr;
				/* Used to determine mode and blocksize. */
{
    int srcFd;
    int dstFd;
    u_int blockSize;   /* Optimal I/O blocksize for filesystem */
    char *buffer;      /* Data buffer for copy */
    size_t nread;

    if ((srcFd = open(src, O_RDONLY, 0)) < 0) {		/* INTL: Native. */
	return TCL_ERROR;
    }

    dstFd = open(dst, O_CREAT | O_TRUNC | O_WRONLY,	/* INTL: Native. */
	    statBufPtr->st_mode);
    if (dstFd < 0) {
	close(srcFd); 
	return TCL_ERROR;
    }

#ifdef HAVE_ST_BLKSIZE
    blockSize = statBufPtr->st_blksize;
#else
#ifndef NO_FSTATFS
    {
	struct statfs fs;
	if (fstatfs(srcFd, &fs, sizeof(fs), 0) == 0) {
	    blockSize = fs.f_bsize;
	} else {
	    blockSize = 4096;
	}
    }
#else 
    blockSize = 4096;
#endif
#endif

    buffer = ckalloc(blockSize);
    while (1) {
	nread = read(srcFd, buffer, blockSize);
	if ((nread == -1) || (nread == 0)) {
	    break;
	}
	if (write(dstFd, buffer, nread) != nread) {
	    nread = (size_t) -1;
	    break;
	}
    }
	
    ckfree(buffer);
    close(srcFd);
    if ((close(dstFd) != 0) || (nread == -1)) {
	unlink(dst);					/* INTL: Native. */
	return TCL_ERROR;
    }
    if (CopyFileAtts(src, dst, statBufPtr) == TCL_ERROR) {
	/*
	 * The copy succeeded, but setting the permissions failed, so be in
	 * a consistent state, we remove the file that was created by the
	 * copy.
	 */

	unlink(dst);					/* INTL: Native. */
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpDeleteFile, DoDeleteFile --
 *
 *      Removes a single file (not a directory).
 *
 * Results:
 *	If the file was successfully deleted, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the
 *	error.  Some possible values for errno are:
 *
 *	EACCES:     a parent directory can't be read and/or written.
 *	EISDIR:	    path is a directory.
 *	ENOENT:	    path doesn't exist or is "".
 *
 * Side effects:
 *      The file is deleted, even if it is read-only.
 *
 *---------------------------------------------------------------------------
 */

int
TclpDeleteFile(path) 
    CONST char *path;		/* Pathname of file to be removed (UTF-8). */
{
    int result;
    Tcl_DString pathString;

    Tcl_UtfToExternalDString(NULL, path, -1, &pathString);
    result = DoDeleteFile(&pathString);
    Tcl_DStringFree(&pathString);
    return result;
}

static int
DoDeleteFile(pathPtr)
    Tcl_DString *pathPtr;	/* Pathname of file to be removed (native). */
{
    CONST char *path;

    path = Tcl_DStringValue(pathPtr);
    if (unlink(path) != 0) {				/* INTL: Native. */
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpCreateDirectory, DoCreateDirectory --
 *
 *      Creates the specified directory.  All parent directories of the
 *	specified directory must already exist.  The directory is
 *	automatically created with permissions so that user can access
 *	the new directory and create new files or subdirectories in it.
 *
 * Results:
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
 *	permission for u+rwx will always be added.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCreateDirectory(path)
    char *path;			/* Pathname of directory to create. */
{













    mode_t mode;




    mode = umask(0);
    umask(mode);

    /*
     * umask return value is actually the inverse of the permissions.
     */
    
    mode = (0777 & ~mode);

    if (mkdir(path, mode | S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------







|

>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>







|
|

|







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
 *	permission for u+rwx will always be added.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCreateDirectory(path)
    CONST char *path;		/* Pathname of directory to create (UTF-8). */
{
    int result;
    Tcl_DString pathString;

    Tcl_UtfToExternalDString(NULL, path, -1, &pathString);
    result = DoCreateDirectory(&pathString);
    Tcl_DStringFree(&pathString);
    return result;
}

static int
DoCreateDirectory(pathPtr)
    Tcl_DString *pathPtr;	/* Pathname of directory to create (native). */
{
    mode_t mode;
    CONST char *path;

    path = Tcl_DStringValue(pathPtr);

    mode = umask(0);
    umask(mode);

    /*
     * umask return value is actually the inverse of the permissions.
     */

    mode = (0777 & ~mode) | S_IRUSR | S_IWUSR | S_IXUSR;

    if (mkdir(path, mode) != 0) {			/* INTL: Native. */
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
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
 *	processed.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCopyDirectory(src, dst, errorPtr)
    char *src;			/* Pathname of directory to be copied.  */

    char *dst;			/* Pathname of target directory. */
    Tcl_DString *errorPtr;	/* If non-NULL, initialized DString for

				 * error reporting. */
{

    int result;
    Tcl_DString srcBuffer;
    Tcl_DString dstBuffer;

    Tcl_DStringInit(&srcBuffer);
    Tcl_DStringInit(&dstBuffer);
    Tcl_DStringAppend(&srcBuffer, src, -1);
    Tcl_DStringAppend(&dstBuffer, dst, -1);
    result = TraverseUnixTree(TraversalCopy, &srcBuffer, &dstBuffer,
	    errorPtr);
    Tcl_DStringFree(&srcBuffer);
    Tcl_DStringFree(&dstBuffer);
    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpRemoveDirectory --
 *
 *	Removes directory (and its contents, if the recursive flag is set).
 *
 * Results:
 *	If the directory was successfully removed, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR, errno is set to indicate
 *	the error, and the pathname of the file that caused the error







|
>
|
|
>
|

>

<
<

|
|
|
<
|
|
|
|






|







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
 *	processed.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCopyDirectory(src, dst, errorPtr)
    CONST char *src;		/* Pathname of directory to be copied
				 * (UTF-8). */
    CONST char *dst;		/* Pathname of target directory (UTF-8). */
    Tcl_DString *errorPtr;	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    Tcl_DString srcString, dstString;
    int result;



    Tcl_UtfToExternalDString(NULL, src, -1, &srcString);
    Tcl_UtfToExternalDString(NULL, dst, -1, &dstString);


    result = TraverseUnixTree(TraversalCopy, &srcString, &dstString, errorPtr);

    Tcl_DStringFree(&srcString);
    Tcl_DStringFree(&dstString);
    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpRemoveDirectory, DoRemoveDirectory --
 *
 *	Removes directory (and its contents, if the recursive flag is set).
 *
 * Results:
 *	If the directory was successfully removed, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR, errno is set to indicate
 *	the error, and the pathname of the file that caused the error
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
 *	immediately, and remaining files will not be deleted.
 *
 *---------------------------------------------------------------------------
 */
 
int
TclpRemoveDirectory(path, recursive, errorPtr) 
    char *path;			/* Pathname of directory to be removed. */

    int recursive;		/* If non-zero, removes directories that
				 * are nonempty.  Otherwise, will only remove
				 * empty directories. */
    Tcl_DString *errorPtr;	/* If non-NULL, initialized DString for

				 * error reporting. */
{
    int result;
    Tcl_DString buffer;






















    if (rmdir(path) == 0) {
	return TCL_OK;
    }
    if (errno == ENOTEMPTY) {
	errno = EEXIST;
    }
    if ((errno != EEXIST) || (recursive == 0)) {
	if (errorPtr != NULL) {
	    Tcl_DStringAppend(errorPtr, path, -1);
	}
	return TCL_ERROR;
    }
    
    /*
     * The directory is nonempty, but the recursive flag has been
     * specified, so we recursively remove all the files in the directory.
     */

    Tcl_DStringInit(&buffer);
    Tcl_DStringAppend(&buffer, path, -1);
    result = TraverseUnixTree(TraversalDelete, &buffer, NULL, errorPtr);
    Tcl_DStringFree(&buffer);
    return result;
}
	
/*
 *---------------------------------------------------------------------------
 *
 * TraverseUnixTree --
 *







|
>



|
>
|


|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







|









<
<
|
<
<







674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731


732


733
734
735
736
737
738
739
 *	immediately, and remaining files will not be deleted.
 *
 *---------------------------------------------------------------------------
 */
 
int
TclpRemoveDirectory(path, recursive, errorPtr) 
    CONST char *path;		/* Pathname of directory to be removed
				 * (UTF-8). */
    int recursive;		/* If non-zero, removes directories that
				 * are nonempty.  Otherwise, will only remove
				 * empty directories. */
    Tcl_DString *errorPtr;	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    int result;
    Tcl_DString pathString;

    Tcl_UtfToExternalDString(NULL, path, -1, &pathString);
    result = DoRemoveDirectory(&pathString, recursive, errorPtr);
    Tcl_DStringFree(&pathString);

    return result;
}

static int
DoRemoveDirectory(pathPtr, recursive, errorPtr)
    Tcl_DString *pathPtr;	/* Pathname of directory to be removed
				 * (native). */
    int recursive;		/* If non-zero, removes directories that
				 * are nonempty.  Otherwise, will only remove
				 * empty directories. */
    Tcl_DString *errorPtr;	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    CONST char *path;

    path = Tcl_DStringValue(pathPtr);
    if (rmdir(path) == 0) {				/* INTL: Native. */
	return TCL_OK;
    }
    if (errno == ENOTEMPTY) {
	errno = EEXIST;
    }
    if ((errno != EEXIST) || (recursive == 0)) {
	if (errorPtr != NULL) {
	    Tcl_ExternalToUtfDString(NULL, path, -1, errorPtr);
	}
	return TCL_ERROR;
    }
    
    /*
     * The directory is nonempty, but the recursive flag has been
     * specified, so we recursively remove all the files in the directory.
     */



    return TraverseUnixTree(TraversalDelete, pathPtr, NULL, errorPtr);


}
	
/*
 *---------------------------------------------------------------------------
 *
 * TraverseUnixTree --
 *
613
614
615
616
617
618
619
620
621
622
623

624
625
626
627
628
629
630
631
632
633

634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
660
661
662
663
664

665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
 */

static int 
TraverseUnixTree(traverseProc, sourcePtr, targetPtr, errorPtr)
    TraversalProc *traverseProc;/* Function to call for every file and
				 * directory in source hierarchy. */
    Tcl_DString *sourcePtr;	/* Pathname of source directory to be
				 * traversed. */
    Tcl_DString *targetPtr;	/* Pathname of directory to traverse in
				 * parallel with source directory. */
    Tcl_DString *errorPtr;	/* If non-NULL, an initialized DString for

				 * error reporting. */
{
    struct stat statbuf;
    char *source, *target, *errfile;
    int result, sourceLen;
    int targetLen = 0;		/* Initialization needed only to prevent
				 * warning in gcc. */
    struct dirent *dirp;
    DIR *dp;


    result = TCL_OK;
    source = Tcl_DStringValue(sourcePtr);
    if (targetPtr != NULL) {
	target = Tcl_DStringValue(targetPtr);
    } else {
	target = NULL;
    }

    errfile = NULL;
    if (lstat(source, &statbuf) != 0) {
	errfile = source;
	goto end;
    }
    if (!S_ISDIR(statbuf.st_mode)) {
	/*
	 * Process the regular file
	 */

	return (*traverseProc)(source, target, &statbuf, DOTREE_F, errorPtr);

    }

    dp = opendir(source);
    if (dp == NULL) {
	/* 
	 * Can't read directory
	 */

	errfile = source;
	goto end;
    }
    result = (*traverseProc)(source, target, &statbuf, DOTREE_PRED, errorPtr);

    if (result != TCL_OK) {
	closedir(dp);
	return result;
    }
    
    Tcl_DStringAppend(sourcePtr, "/", 1);
    source = Tcl_DStringValue(sourcePtr);
    sourceLen = Tcl_DStringLength(sourcePtr);	

    if (targetPtr != NULL) {
	Tcl_DStringAppend(targetPtr, "/", 1);
	target = Tcl_DStringValue(targetPtr);
	targetLen = Tcl_DStringLength(targetPtr);
    }
				  
    while ((dirp = readdir(dp)) != NULL) {
	if ((strcmp(dirp->d_name, ".") == 0)
	        || (strcmp(dirp->d_name, "..") == 0)) {
	    continue;
	}

	/* 
	 * Append name after slash, and recurse on the file.
	 */

	Tcl_DStringAppend(sourcePtr, dirp->d_name, -1);
	if (targetPtr != NULL) {
	    Tcl_DStringAppend(targetPtr, dirp->d_name, -1);
	}
	result = TraverseUnixTree(traverseProc, sourcePtr, targetPtr,
		errorPtr);
	if (result != TCL_OK) {
	    break;
	}
	
	/*
	 * Remove name after slash.
	 */

	Tcl_DStringSetLength(sourcePtr, sourceLen);
	if (targetPtr != NULL) {
	    Tcl_DStringSetLength(targetPtr, targetLen);
	}
    }
    closedir(dp);
    
    /*
     * Strip off the trailing slash we added
     */

    Tcl_DStringSetLength(sourcePtr, sourceLen - 1);
    source = Tcl_DStringValue(sourcePtr);
    if (targetPtr != NULL) {
	Tcl_DStringSetLength(targetPtr, targetLen - 1);
	target = Tcl_DStringValue(targetPtr);
    }

    if (result == TCL_OK) {
	/*
	 * Call traverseProc() on a directory after visiting all the
	 * files in that directory.
	 */

	result = (*traverseProc)(source, target, &statbuf, DOTREE_POSTD,
		errorPtr);
    }
    end:
    if (errfile != NULL) {
	if (errorPtr != NULL) {
	    Tcl_DStringAppend(errorPtr, errfile, -1);
	}
	result = TCL_ERROR;
    }
	    
    return result;
}








|

|
|
>
|

|
|

|
<
|
|

>

<
<
<
<
|
|
|
<
|



|




|
>

<
|
|







|
>

|




<




<



|
|
|







|

|
















|






<


<








|





|







755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772

773
774
775
776
777




778
779
780

781
782
783
784
785
786
787
788
789
790
791
792

793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809

810
811
812
813

814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852

853
854

855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
 */

static int 
TraverseUnixTree(traverseProc, sourcePtr, targetPtr, errorPtr)
    TraversalProc *traverseProc;/* Function to call for every file and
				 * directory in source hierarchy. */
    Tcl_DString *sourcePtr;	/* Pathname of source directory to be
				 * traversed (native). */
    Tcl_DString *targetPtr;	/* Pathname of directory to traverse in
				 * parallel with source directory (native). */
    Tcl_DString *errorPtr;	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    struct stat statBuf;
    CONST char *source, *errfile;
    int result, sourceLen;
    int targetLen;

    struct dirent *dirEntPtr;
    DIR *dirPtr;

    errfile = NULL;
    result = TCL_OK;




    targetLen = 0;		/* lint. */

    source = Tcl_DStringValue(sourcePtr);

    if (lstat(source, &statBuf) != 0) {			/* INTL: Native. */
	errfile = source;
	goto end;
    }
    if (!S_ISDIR(statBuf.st_mode)) {
	/*
	 * Process the regular file
	 */

	return (*traverseProc)(sourcePtr, targetPtr, &statBuf, DOTREE_F,
		errorPtr);
    }

    dirPtr = opendir(source);				/* INTL: Native. */
    if (dirPtr == NULL) {
	/* 
	 * Can't read directory
	 */

	errfile = source;
	goto end;
    }
    result = (*traverseProc)(sourcePtr, targetPtr, &statBuf, DOTREE_PRED,
	    errorPtr);
    if (result != TCL_OK) {
	closedir(dirPtr);
	return result;
    }
    
    Tcl_DStringAppend(sourcePtr, "/", 1);

    sourceLen = Tcl_DStringLength(sourcePtr);	

    if (targetPtr != NULL) {
	Tcl_DStringAppend(targetPtr, "/", 1);

	targetLen = Tcl_DStringLength(targetPtr);
    }
				  
    while ((dirEntPtr = readdir(dirPtr)) != NULL) {	/* INTL: Native. */
	if ((strcmp(dirEntPtr->d_name, ".") == 0)
	        || (strcmp(dirEntPtr->d_name, "..") == 0)) {
	    continue;
	}

	/* 
	 * Append name after slash, and recurse on the file.
	 */

	Tcl_DStringAppend(sourcePtr, dirEntPtr->d_name, -1);
	if (targetPtr != NULL) {
	    Tcl_DStringAppend(targetPtr, dirEntPtr->d_name, -1);
	}
	result = TraverseUnixTree(traverseProc, sourcePtr, targetPtr,
		errorPtr);
	if (result != TCL_OK) {
	    break;
	}
	
	/*
	 * Remove name after slash.
	 */

	Tcl_DStringSetLength(sourcePtr, sourceLen);
	if (targetPtr != NULL) {
	    Tcl_DStringSetLength(targetPtr, targetLen);
	}
    }
    closedir(dirPtr);
    
    /*
     * Strip off the trailing slash we added
     */

    Tcl_DStringSetLength(sourcePtr, sourceLen - 1);

    if (targetPtr != NULL) {
	Tcl_DStringSetLength(targetPtr, targetLen - 1);

    }

    if (result == TCL_OK) {
	/*
	 * Call traverseProc() on a directory after visiting all the
	 * files in that directory.
	 */

	result = (*traverseProc)(sourcePtr, targetPtr, &statBuf, DOTREE_POSTD,
		errorPtr);
    }
    end:
    if (errfile != NULL) {
	if (errorPtr != NULL) {
	    Tcl_ExternalToUtfDString(NULL, errfile, -1, errorPtr);
	}
	result = TCL_ERROR;
    }
	    
    return result;
}

754
755
756
757
758
759
760
761
762
763

764
765
766

767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791
792
793
794
795

796
797
798
799
800
801
802
803
 *      The file or directory src may be copied to dst, depending on 
 *      the value of type.
 *      
 *----------------------------------------------------------------------
 */

static int 
TraversalCopy(src, dst, sbPtr, type, errorPtr) 
    char *src;			/* Source pathname to copy. */
    char *dst;                  /* Destination pathname of copy. */

    struct stat *sbPtr;		/* Stat info for file specified by src. */
    int type;                   /* Reason for call - see TraverseUnixTree(). */
    Tcl_DString *errorPtr;	/* If non-NULL, initialized DString for

				 * error return. */
{
    switch (type) {
	case DOTREE_F:
	    if (TclpCopyFile(src, dst) == TCL_OK) {
		return TCL_OK;
	    }
	    break;

	case DOTREE_PRED:
	    if (TclpCreateDirectory(dst) == TCL_OK) {
		return TCL_OK;
	    }
	    break;

	case DOTREE_POSTD:
	    if (CopyFileAtts(src, dst, sbPtr) == TCL_OK) {

		return TCL_OK;
	    }
	    break;

    }

    /*
     * There shouldn't be a problem with src, because we already
     * checked it to get here.
     */

    if (errorPtr != NULL) {

	Tcl_DStringAppend(errorPtr, dst, -1);
    }
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *







|
|
|
>
|

|
>
|



|





|





|
>







|
|



>
|







889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
 *      The file or directory src may be copied to dst, depending on 
 *      the value of type.
 *      
 *----------------------------------------------------------------------
 */

static int 
TraversalCopy(srcPtr, dstPtr, statBufPtr, type, errorPtr) 
    Tcl_DString *srcPtr;	/* Source pathname to copy (native). */
    Tcl_DString *dstPtr;	/* Destination pathname of copy (native). */
    CONST struct stat *statBufPtr;
				/* Stat info for file specified by srcPtr. */
    int type;                   /* Reason for call - see TraverseUnixTree(). */
    Tcl_DString *errorPtr;	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    switch (type) {
	case DOTREE_F:
	    if (DoCopyFile(srcPtr, dstPtr) == TCL_OK) {
		return TCL_OK;
	    }
	    break;

	case DOTREE_PRED:
	    if (DoCreateDirectory(dstPtr) == TCL_OK) {
		return TCL_OK;
	    }
	    break;

	case DOTREE_POSTD:
	    if (CopyFileAtts(Tcl_DStringValue(srcPtr),
		    Tcl_DStringValue(dstPtr), statBufPtr) == TCL_OK) {
		return TCL_OK;
	    }
	    break;

    }

    /*
     * There shouldn't be a problem with src, because we already checked it
     * to get here.
     */

    if (errorPtr != NULL) {
	Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(dstPtr),
		Tcl_DStringLength(dstPtr), errorPtr);
    }
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
814
815
816
817
818
819
820
821
822
823

824
825
826

827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847

848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875

876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907

908
909
910
911
912
913
914
 * Side effects:
 *      Files or directory specified by src will be deleted.
 *
 *----------------------------------------------------------------------
 */

static int
TraversalDelete(src, ignore, sbPtr, type, errorPtr) 
    char *src;			/* Source pathname. */
    char *ignore;		/* Destination pathname (not used). */

    struct stat *sbPtr;		/* Stat info for file specified by src. */
    int type;                   /* Reason for call - see TraverseUnixTree(). */
    Tcl_DString *errorPtr;	/* If non-NULL, initialized DString for

				 * error return. */
{
    switch (type) {
        case DOTREE_F:
	    if (unlink(src) == 0) {
		return TCL_OK;
	    }
	    break;

        case DOTREE_PRED:
	    return TCL_OK;

        case DOTREE_POSTD:
	    if (rmdir(src) == 0) {
		return TCL_OK;
	    }
	    break;
	    
    }

    if (errorPtr != NULL) {

	Tcl_DStringAppend(errorPtr, src, -1);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * CopyFileAtts
 *
 *      Copy the file attributes such as owner, group, permissions, and
 *      modification date from one file to another.
 *
 * Results:
 *      Standard Tcl result.
 *
 * Side effects:
 *      user id, group id, permission bits, last modification time, and 
 *      last access time are updated in the new file to reflect the old
 *      file.
 *      
 *----------------------------------------------------------------------
 */

static int
CopyFileAtts(src, dst, statBufPtr) 
    char *src;                 /* Path name of source file */
    char *dst;                 /* Path name of target file */

    struct stat *statBufPtr;   /* ptr to stat info for source file */
{
    struct utimbuf tval;
    mode_t newMode;
    
    newMode = statBufPtr->st_mode
	    & (S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO);
	
    /* 
     * Note that if you copy a setuid file that is owned by someone
     * else, and you are not root, then the copy will be setuid to you.
     * The most correct implementation would probably be to have the
     * copy not setuid to anyone if the original file was owned by 
     * someone else, but this corner case isn't currently handled.
     * It would require another lstat(), or getuid().
     */
    
    if (chmod(dst, newMode)) {
	newMode &= ~(S_ISUID | S_ISGID);
	if (chmod(dst, newMode)) {
	    return TCL_ERROR;
	}
    }

    tval.actime = statBufPtr->st_atime; 
    tval.modtime = statBufPtr->st_mtime; 

    if (utime(dst, &tval)) {
	return TCL_ERROR;
    }
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * GetGroupAttribute
 *
 *      Gets the group attribute of a file.







|
|
|
>
|

|
>
|


|
|



|
|

|
|
|



|

<

>
|





|

|

|
|


|


|
|
|
|
|




|
|
>
|
















|

|







|




>







953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986

987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
 * Side effects:
 *      Files or directory specified by src will be deleted.
 *
 *----------------------------------------------------------------------
 */

static int
TraversalDelete(srcPtr, ignore, statBufPtr, type, errorPtr) 
    Tcl_DString *srcPtr;	/* Source pathname (native). */
    Tcl_DString *ignore;	/* Destination pathname (not used). */
    CONST struct stat *statBufPtr;
				/* Stat info for file specified by srcPtr. */
    int type;                   /* Reason for call - see TraverseUnixTree(). */
    Tcl_DString *errorPtr;	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    switch (type) {
        case DOTREE_F: {
	    if (DoDeleteFile(srcPtr) == 0) {
		return TCL_OK;
	    }
	    break;
	}
        case DOTREE_PRED: {
	    return TCL_OK;
	}
        case DOTREE_POSTD: {
	    if (DoRemoveDirectory(srcPtr, 0, NULL) == 0) {
		return TCL_OK;
	    }
	    break;
	}	    
    }

    if (errorPtr != NULL) {
	Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(srcPtr),
		Tcl_DStringLength(srcPtr), errorPtr);
    }
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * CopyFileAtts --
 *
 *	Copy the file attributes such as owner, group, permissions,
 *	and modification date from one file to another.
 *
 * Results:
 *	Standard Tcl result.
 *
 * Side effects:
 *	user id, group id, permission bits, last modification time, and
 *	last access time are updated in the new file to reflect the
 *	old file.
 *
 *---------------------------------------------------------------------------
 */

static int
CopyFileAtts(src, dst, statBufPtr) 
    CONST char *src;		/* Path name of source file (native). */
    CONST char *dst;		/* Path name of target file (native). */
    CONST struct stat *statBufPtr;
				/* Stat info for source file */
{
    struct utimbuf tval;
    mode_t newMode;
    
    newMode = statBufPtr->st_mode
	    & (S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO);
	
    /* 
     * Note that if you copy a setuid file that is owned by someone
     * else, and you are not root, then the copy will be setuid to you.
     * The most correct implementation would probably be to have the
     * copy not setuid to anyone if the original file was owned by 
     * someone else, but this corner case isn't currently handled.
     * It would require another lstat(), or getuid().
     */
    
    if (chmod(dst, newMode)) {				/* INTL: Native. */
	newMode &= ~(S_ISUID | S_ISGID);
	if (chmod(dst, newMode)) {			/* INTL: Native. */
	    return TCL_ERROR;
	}
    }

    tval.actime = statBufPtr->st_atime; 
    tval.modtime = statBufPtr->st_mtime; 

    if (utime(dst, &tval)) {				/* INTL: Native. */
	return TCL_ERROR;
    }
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * GetGroupAttribute
 *
 *      Gets the group attribute of a file.
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
 *----------------------------------------------------------------------
 */

static int
GetGroupAttribute(interp, objIndex, fileName, attributePtrPtr)
    Tcl_Interp *interp;		/* The interp we are using for errors. */
    int objIndex;		/* The index of the attribute. */
    char *fileName;		/* The name of the file. */
    Tcl_Obj **attributePtrPtr;	/* A pointer to return the object with. */
{
    struct stat statBuf;
    struct group *groupPtr;


    if (stat(fileName, &statBuf) != 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),

		"could not stat file \"", fileName, "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }

    groupPtr = getgrgid(statBuf.st_gid);
    if (groupPtr == NULL) {
	*attributePtrPtr = Tcl_NewIntObj(statBuf.st_gid);
    } else {




	*attributePtrPtr = Tcl_NewStringObj(groupPtr->gr_name, -1);

    }
    endgrent();
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|




>

|
|
>
|




|



>
>
>
>
|
>







1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
 *----------------------------------------------------------------------
 */

static int
GetGroupAttribute(interp, objIndex, fileName, attributePtrPtr)
    Tcl_Interp *interp;		/* The interp we are using for errors. */
    int objIndex;		/* The index of the attribute. */
    CONST char *fileName;	/* The name of the file (UTF-8). */
    Tcl_Obj **attributePtrPtr;	/* A pointer to return the object with. */
{
    struct stat statBuf;
    struct group *groupPtr;
    int result;

    result = TclStat(fileName, &statBuf);
    
    if (result != 0) {
	Tcl_AppendResult(interp, "could not read \"", fileName, "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }

    groupPtr = getgrgid(statBuf.st_gid);		/* INTL: Native. */
    if (groupPtr == NULL) {
	*attributePtrPtr = Tcl_NewIntObj(statBuf.st_gid);
    } else {
	Tcl_DString ds;
	CONST char *utf;

	utf = Tcl_ExternalToUtfDString(NULL, groupPtr->gr_name, -1, &ds); 
	*attributePtrPtr = Tcl_NewStringObj(utf, -1);
	Tcl_DStringFree(&ds);
    }
    endgrent();
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
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
 *----------------------------------------------------------------------
 */

static int
GetOwnerAttribute(interp, objIndex, fileName, attributePtrPtr)
    Tcl_Interp *interp;		/* The interp we are using for errors. */
    int objIndex;		/* The index of the attribute. */
    char *fileName;		/* The name of the file. */
    Tcl_Obj **attributePtrPtr;	/* A pointer to return the object with. */
{
    struct stat statBuf;
    struct passwd *pwPtr;


    if (stat(fileName, &statBuf) != 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),

		"could not stat file \"", fileName, "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }

    pwPtr = getpwuid(statBuf.st_uid);
    if (pwPtr == NULL) {
	*attributePtrPtr = Tcl_NewIntObj(statBuf.st_uid);
    } else {




	*attributePtrPtr = Tcl_NewStringObj(pwPtr->pw_name, -1);

    }
    endpwent();
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|




>

|
|
>
|




|



>
>
>
>
|
>







1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
 *----------------------------------------------------------------------
 */

static int
GetOwnerAttribute(interp, objIndex, fileName, attributePtrPtr)
    Tcl_Interp *interp;		/* The interp we are using for errors. */
    int objIndex;		/* The index of the attribute. */
    CONST char *fileName;	/* The name of the file (UTF-8). */
    Tcl_Obj **attributePtrPtr;	/* A pointer to return the object with. */
{
    struct stat statBuf;
    struct passwd *pwPtr;
    int result;

    result = TclStat(fileName, &statBuf);
    
    if (result != 0) {
	Tcl_AppendResult(interp, "could not read \"", fileName, "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }

    pwPtr = getpwuid(statBuf.st_uid);			/* INTL: Native. */
    if (pwPtr == NULL) {
	*attributePtrPtr = Tcl_NewIntObj(statBuf.st_uid);
    } else {
	Tcl_DString ds;
	CONST char *utf;

	utf = Tcl_ExternalToUtfDString(NULL, pwPtr->pw_name, -1, &ds); 
	*attributePtrPtr = Tcl_NewStringObj(utf, Tcl_DStringLength(&ds));
	Tcl_DStringFree(&ds);
    }
    endpwent();
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022

1023
1024
1025

1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043






























































1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062



1063
1064



1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080


1081

1082
1083



1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184

1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
 *----------------------------------------------------------------------
 */

static int
GetPermissionsAttribute(interp, objIndex, fileName, attributePtrPtr)
    Tcl_Interp *interp;		    /* The interp we are using for errors. */
    int objIndex;		    /* The index of the attribute. */
    char *fileName;		    /* The name of the file. */
    Tcl_Obj **attributePtrPtr;	    /* A pointer to return the object with. */
{
    struct stat statBuf;
    char returnString[6];


    if (stat(fileName, &statBuf) != 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),

		"could not stat file \"", fileName, "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }

    sprintf(returnString, "%0#5lo", (statBuf.st_mode & 0x00007FFF));

    *attributePtrPtr = Tcl_NewStringObj(returnString, -1);
    
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SetGroupAttribute
 *
 *      Sets the file to the given group.






























































 *
 * Results:
 *      Standard TCL result.
 *
 * Side effects:
 *      The group of the file is changed.
 *      
 *----------------------------------------------------------------------
 */

static int
SetGroupAttribute(interp, objIndex, fileName, attributePtr)
    Tcl_Interp *interp;		    /* The interp we are using for errors. */
    int objIndex;		    /* The index of the attribute. */
    char *fileName;		    /* The name of the file. */
    Tcl_Obj *attributePtr;	    /* The attribute to set. */
{
    gid_t groupNumber;
    long placeHolder;




    if (Tcl_GetLongFromObj(interp, attributePtr, &placeHolder) != TCL_OK) {



	struct group *groupPtr;
	char *groupString = Tcl_GetStringFromObj(attributePtr, NULL);

	Tcl_ResetResult(interp);
	groupPtr = getgrnam(groupString);
	if (groupPtr == NULL) {
	    endgrent();
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "could not set group for file \"", fileName,
		    "\": group \"", groupString, "\" does not exist",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	groupNumber = groupPtr->gr_gid;
    } else {
	groupNumber = (gid_t) placeHolder;


    }


    if (chown(fileName, -1, groupNumber) != 0) {



	endgrent();
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"could not set group for file \"", fileName, "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }    
    endgrent();
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SetOwnerAttribute
 *
 *      Sets the file to the given owner.
 *
 * Results:
 *      Standard TCL result.
 *
 * Side effects:
 *      The group of the file is changed.
 *      
 *----------------------------------------------------------------------
 */

static int
SetOwnerAttribute(interp, objIndex, fileName, attributePtr)
    Tcl_Interp *interp;		    /* The interp we are using for errors. */
    int objIndex;		    /* The index of the attribute. */
    char *fileName;		    /* The name of the file. */
    Tcl_Obj *attributePtr;	    /* The attribute to set. */
{
    uid_t userNumber;
    long placeHolder;

    if (Tcl_GetLongFromObj(interp, attributePtr, &placeHolder) != TCL_OK) {
	struct passwd *pwPtr;
	char *ownerString = Tcl_GetStringFromObj(attributePtr, NULL);

	Tcl_ResetResult(interp);
	pwPtr = getpwnam(ownerString);
	if (pwPtr == NULL) {
	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		    "could not set owner for file \"", fileName,
		    "\": user \"", ownerString, "\" does not exist",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	userNumber = pwPtr->pw_uid;
    } else {
	userNumber = (uid_t) placeHolder;
    }

    if (chown(fileName, userNumber, -1) != 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"could not set owner for file \"", fileName, "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }    
	
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SetPermissionsAttribute
 *
 *      Sets the file to the given group.
 *
 * Results:
 *      Standard TCL result.
 *
 * Side effects:
 *      The group of the file is changed.
 *      
 *----------------------------------------------------------------------
 */

static int
SetPermissionsAttribute(interp, objIndex, fileName, attributePtr)
    Tcl_Interp *interp;		    /* The interp we are using for errors. */
    int objIndex;		    /* The index of the attribute. */
    char *fileName;		    /* The name of the file. */
    Tcl_Obj *attributePtr;	    /* The attribute to set. */
{
    long modeInt;
    mode_t newMode;

    /*
     * mode_t is a long under SPARC; an int under SunOS. Since we do not
     * know how big it really is, we get the long and then cast it
     * down to a mode_t.
     */
    
    if (Tcl_GetLongFromObj(interp, attributePtr, &modeInt)
	    != TCL_OK) {
	return TCL_ERROR;
    }


    newMode = (mode_t) modeInt;

    if (chmod(fileName, newMode) != 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"could not set permissions for file \"", fileName, "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}







|



|
>

|
|
>
|












|

|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|

|



|
|

|
|

<
|
>
>
>

|
>
>
>
|
|

|
|
<
<
|
<
<
<
<
|
|
|
|
>
>
|
>
|
|
>
>
>
|
|
|
|


<




|

|

|





|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|


|
|
|
<
<
<
|
<
|
|
<



>
|
|
|







1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281

1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295


1296




1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315

1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332






















































1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344



1345

1346
1347

1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
 *----------------------------------------------------------------------
 */

static int
GetPermissionsAttribute(interp, objIndex, fileName, attributePtrPtr)
    Tcl_Interp *interp;		    /* The interp we are using for errors. */
    int objIndex;		    /* The index of the attribute. */
    CONST char *fileName;	    /* The name of the file (UTF-8). */
    Tcl_Obj **attributePtrPtr;	    /* A pointer to return the object with. */
{
    struct stat statBuf;
    char returnString[7];
    int result;

    result = TclStat(fileName, &statBuf);
    
    if (result != 0) {
	Tcl_AppendResult(interp, "could not read \"", fileName, "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }

    sprintf(returnString, "%0#5lo", (statBuf.st_mode & 0x00007FFF));

    *attributePtrPtr = Tcl_NewStringObj(returnString, -1);
    
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * SetGroupAttribute --
 *
 *      Sets the group of the file to the specified group.
 *
 * Results:
 *      Standard TCL result.
 *
 * Side effects:
 *      As above.
 *      
 *---------------------------------------------------------------------------
 */

static int
SetGroupAttribute(interp, objIndex, fileName, attributePtr)
    Tcl_Interp *interp;		    /* The interp for error reporting. */
    int objIndex;		    /* The index of the attribute. */
    CONST char *fileName;	    /* The name of the file (UTF-8). */
    Tcl_Obj *attributePtr;	    /* New group for file. */
{
    long gid;
    int result;
    Tcl_DString ds;
    CONST char *native;

    if (Tcl_GetLongFromObj(NULL, attributePtr, &gid) != TCL_OK) {
	struct group *groupPtr;
	CONST char *string;
	int length;

	string = Tcl_GetStringFromObj(attributePtr, &length);

	native = Tcl_UtfToExternalDString(NULL, string, length, &ds);
	groupPtr = getgrnam(native);			/* INTL: Native. */
	Tcl_DStringFree(&ds);

	if (groupPtr == NULL) {
	    endgrent();
	    Tcl_AppendResult(interp, "could not set group for file \"",
		    fileName, "\": group \"", string, "\" does not exist",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	gid = groupPtr->gr_gid;
    }

    native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
    result = chown(native, -1, (gid_t) gid);		/* INTL: Native. */
    Tcl_DStringFree(&ds);

    endgrent();
    if (result != 0) {
	Tcl_AppendResult(interp, "could not set group for file \"",
		fileName, "\": ", Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }    
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * SetOwnerAttribute --
 *
 *      Sets the owner of the file to the specified owner.
 *
 * Results:
 *      Standard TCL result.
 *
 * Side effects:
 *      As above.
 *      
 *---------------------------------------------------------------------------
 */

static int
SetOwnerAttribute(interp, objIndex, fileName, attributePtr)
    Tcl_Interp *interp;		    /* The interp for error reporting. */
    int objIndex;		    /* The index of the attribute. */
    CONST char *fileName;	    /* The name of the file (UTF-8). */
    Tcl_Obj *attributePtr;	    /* New owner for file. */
{

    long uid;
    int result;
    Tcl_DString ds;
    CONST char *native;

    if (Tcl_GetLongFromObj(NULL, attributePtr, &uid) != TCL_OK) {
	struct passwd *pwPtr;
	CONST char *string;
	int length;

	string = Tcl_GetStringFromObj(attributePtr, &length);

	native = Tcl_UtfToExternalDString(NULL, string, length, &ds);
	pwPtr = getpwnam(native);			/* INTL: Native. */


	Tcl_DStringFree(&ds);





	if (pwPtr == NULL) {
	    Tcl_AppendResult(interp, "could not set owner for file \"",
		    fileName, "\": user \"", string, "\" does not exist",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	uid = pwPtr->pw_uid;
    }

    native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
    result = chown(native, uid, -1);			/* INTL: Native. */
    Tcl_DStringFree(&ds);

    if (result != 0) {
	Tcl_AppendResult(interp, "could not set owner for file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }    

    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * SetPermissionsAttribute
 *
 *      Sets the file to the given permission.
 *
 * Results:
 *      Standard TCL result.
 *
 * Side effects:
 *      The permission of the file is changed.
 *      
 *---------------------------------------------------------------------------






















































 */

static int
SetPermissionsAttribute(interp, objIndex, fileName, attributePtr)
    Tcl_Interp *interp;		    /* The interp we are using for errors. */
    int objIndex;		    /* The index of the attribute. */
    CONST char *fileName;	    /* The name of the file (UTF-8). */
    Tcl_Obj *attributePtr;	    /* The attribute to set. */
{
    long mode;
    int result;
    CONST char *native;



    Tcl_DString ds;


    if (Tcl_GetLongFromObj(interp, attributePtr, &mode) != TCL_OK) {

	return TCL_ERROR;
    }

    native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
    result = chmod(native, (mode_t) mode);		/* INTL: Native. */
    Tcl_DStringFree(&ds);
    if (result != 0) {
	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
		"could not set permissions for file \"", fileName, "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

Changes to unix/tclUnixFile.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211





212
213
214
215
216
217
218
219
220
221
222

223
224

225
226
227
228

229


230
231
232
233
234
235
236


237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256






257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281







282
283
284
285
286
287
288


289
290

291
292
293
294
295
296
297
298
299

300

301

302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324


325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427


428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446

447

448
449
450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469
470
471
/* 
 * tclUnixFile.c --
 *
 *      This file contains wrappers around UNIX file handling functions.
 *      These wrappers mask differences between Windows and UNIX.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclUnixFile.c 1.48 97/07/07 16:38:11
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * The variable below caches the name of the current working directory
 * in order to avoid repeated calls to getcwd.  The string is malloc-ed.
 * NULL means the cache needs to be refreshed.
 */

static char *currentDir =  NULL;
static int currentDirExitHandlerSet = 0;

/*
 * The variable below is set if the exit routine for deleting the string
 * containing the executable name has been registered.
 */

static int executableNameExitHandlerSet = 0;

extern pid_t waitpid _ANSI_ARGS_((pid_t pid, int *stat_loc, int options));

/*
 * Static routines for this file:
 */

static void	FreeCurrentDir _ANSI_ARGS_((ClientData clientData));
static void	FreeExecutableName _ANSI_ARGS_((ClientData clientData));

/*
 *----------------------------------------------------------------------
 *
 * FreeCurrentDir --
 *
 *	Frees the string stored in the currentDir variable. This routine
 *	is registered as an exit handler and will be called during shutdown.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the memory occuppied by the currentDir value.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static void
FreeCurrentDir(clientData)
    ClientData clientData;	/* Not used. */
{
    if (currentDir != (char *) NULL) {
        ckfree(currentDir);
        currentDir = (char *) NULL;
        currentDirExitHandlerSet = 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FreeExecutableName --
 *
 *	Frees the string stored in the tclExecutableName variable. This
 *	routine is registered as an exit handler and will be called
 *	during shutdown.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the memory occuppied by the tclExecutableName value.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static void
FreeExecutableName(clientData)
    ClientData clientData;	/* Not used. */
{
    if (tclExecutableName != (char *) NULL) {
        ckfree(tclExecutableName);
        tclExecutableName = (char *) NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclChdir --
 *
 *	Change the current working directory.
 *
 * Results:
 *	The result is a standard Tcl result.  If an error occurs and 
 *	interp isn't NULL, an error message is left in interp->result.
 *
 * Side effects:
 *	The working directory for this application is changed.  Also
 *	the cache maintained used by TclGetCwd is deallocated and
 *	set to NULL.
 *
 *----------------------------------------------------------------------
 */

int
TclChdir(interp, dirName)
    Tcl_Interp *interp;		/* If non NULL, used for error reporting. */
    char *dirName;     		/* Path to new working directory. */
{
    if (currentDir != NULL) {
	ckfree(currentDir);
	currentDir = NULL;
    }
    if (chdir(dirName) != 0) {
	if (interp != NULL) {
	    Tcl_AppendResult(interp, "couldn't change working directory to \"",
		    dirName, "\": ", Tcl_PosixError(interp), (char *) NULL);
	}
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetCwd --
 *
 *	Return the path name of the current working directory.
 *
 * Results:
 *	The result is the full path name of the current working
 *	directory, or NULL if an error occurred while figuring it out.
 *	The returned string is owned by the TclGetCwd routine and must
 *	not be freed by the caller.  If an error occurs and interp
 *	isn't NULL, an error message is left in interp->result.
 *
 * Side effects:
 *	The path name is cached to avoid having to recompute it
 *	on future calls;  if it is already cached, the cached
 *	value is returned.
 *
 *----------------------------------------------------------------------
 */

char *
TclGetCwd(interp)
    Tcl_Interp *interp;		/* If non NULL, used for error reporting. */
{
    char buffer[MAXPATHLEN+1];

    if (currentDir == NULL) {
        if (!currentDirExitHandlerSet) {
            currentDirExitHandlerSet = 1;
            Tcl_CreateExitHandler(FreeCurrentDir, (ClientData) NULL);
        }
#ifdef USEGETWD
	if ((int)getwd(buffer) == (int)NULL) {
	    if (interp != NULL) {
		Tcl_AppendResult(interp,
			"error getting working directory name: ",
			buffer, (char *)NULL);
	    }
	    return NULL;
	}
#else
	if (getcwd(buffer, MAXPATHLEN+1) == NULL) {
	    if (interp != NULL) {
		if (errno == ERANGE) {
		    Tcl_SetResult(interp,
			    "working directory name is too long",
		            TCL_STATIC);
		} else {
		    Tcl_AppendResult(interp,
			    "error getting working directory name: ",
			    Tcl_PosixError(interp), (char *) NULL);
		}
	    }
	    return NULL;
	}
#endif
	currentDir = (char *) ckalloc((unsigned) (strlen(buffer) + 1));
	strcpy(currentDir, buffer);
    }
    return currentDir;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FindExecutable --
 *
 *	This procedure computes the absolute path name of the current
 *	application, given its argv[0] value.
 *
 * Results:





 *	None.
 *
 * Side effects:
 *	The variable tclExecutableName gets filled in with the file
 *	name for the application, if we figured it out.  If we couldn't
 *	figure it out, Tcl_FindExecutable is set to NULL.
 *
 *----------------------------------------------------------------------
 */

void

Tcl_FindExecutable(argv0)
    char *argv0;		/* The value of the application's argv[0]. */

{
    char *name, *p, *cwd;
    Tcl_DString buffer;
    int length;

    struct stat statBuf;



    Tcl_DStringInit(&buffer);
    if (tclExecutableName != NULL) {
	ckfree(tclExecutableName);
	tclExecutableName = NULL;
    }



    name = argv0;
    for (p = name; *p != 0; p++) {
	if (*p == '/') {
	    /*
	     * The name contains a slash, so use the name directly
	     * without doing a path search.
	     */

	    goto gotName;
	}
    }

    p = getenv("PATH");
    if (p == NULL) {
	/*
	 * There's no PATH environment variable; use the default that
	 * is used by sh.
	 */

	p = ":/bin:/usr/bin";






    }

    /*
     * Search through all the directories named in the PATH variable
     * to see if argv[0] is in one of them.  If so, use that file
     * name.
     */

    while (*p != 0) {
	while (isspace(UCHAR(*p))) {
	    p++;
	}
	name = p;
	while ((*p != ':') && (*p != 0)) {
	    p++;
	}
	Tcl_DStringSetLength(&buffer, 0);
	if (p != name) {
	    Tcl_DStringAppend(&buffer, name, p-name);
	    if (p[-1] != '/') {
		Tcl_DStringAppend(&buffer, "/", 1);
	    }
	}
	Tcl_DStringAppend(&buffer, argv0, -1);
	if ((access(Tcl_DStringValue(&buffer), X_OK) == 0)







		&& (stat(Tcl_DStringValue(&buffer), &statBuf) == 0)
		&& S_ISREG(statBuf.st_mode)) {
	    name = Tcl_DStringValue(&buffer);
	    goto gotName;
	}
	if (*p == 0) {
	    break;


	}
	p++;

    }
    goto done;

    /*
     * If the name starts with "/" then just copy it to tclExecutableName.
     */

    gotName:
    if (name[0] == '/')  {

	tclExecutableName = (char *) ckalloc((unsigned) (strlen(name) + 1));

	strcpy(tclExecutableName, name);

	goto done;
    }

    /*
     * The name is relative to the current working directory.  First
     * strip off a leading "./", if any, then add the full path name of
     * the current working directory.
     */

    if ((name[0] == '.') && (name[1] == '/')) {
	name += 2;
    }
    cwd = TclGetCwd((Tcl_Interp *) NULL);
    if (cwd == NULL) {
	tclExecutableName = NULL;
	goto done;

    }
    length = strlen(cwd);
    tclExecutableName = (char *) ckalloc((unsigned)
	    (length + strlen(name) + 2));
    strcpy(tclExecutableName, cwd);
    tclExecutableName[length] = '/';
    strcpy(tclExecutableName + length + 1, name);



    done:
    Tcl_DStringFree(&buffer);

    if (!executableNameExitHandlerSet) {
        executableNameExitHandlerSet = 1;
        Tcl_CreateExitHandler(FreeExecutableName, (ClientData) NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetUserHome --
 *
 *	This function takes the passed in user name and finds the
 *	corresponding home directory specified in the password file.
 *
 * Results:
 *	The result is a pointer to a static string containing
 *	the new name.  If there was an error in processing the
 *	user name then the return value is NULL.  Otherwise the
 *	result is stored in bufferPtr, and the caller must call
 *	Tcl_DStringFree(bufferPtr) to free the result.
 *
 * Side effects:
 *	Information may be left in bufferPtr.
 *
 *----------------------------------------------------------------------
 */

char *
TclGetUserHome(name, bufferPtr)
    char *name;			/* User name to use to find home directory. */
    Tcl_DString *bufferPtr;	/* May be used to hold result.  Must not hold
				 * anything at the time of the call, and need
				 * not even be initialized. */
{
    struct passwd *pwPtr;

    pwPtr = getpwnam(name);
    if (pwPtr == NULL) {
	endpwent();
	return NULL;
    }
    Tcl_DStringInit(bufferPtr);
    Tcl_DStringAppend(bufferPtr, pwPtr->pw_dir, -1);
    endpwent();
    return bufferPtr->string;
}

/*
 *----------------------------------------------------------------------
 *
 * TclMatchFiles --
 *
 *	This routine is used by the globbing code to search a
 *	directory for all files which match a given pattern.
 *
 * Results: 
 *	If the tail argument is NULL, then the matching files are
 *	added to the interp->result.  Otherwise, TclDoGlob is called
 *	recursively for each matching subdirectory.  The return value
 *	is a standard Tcl result indicating whether an error occurred
 *	in globbing.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclMatchFiles(interp, separators, dirPtr, pattern, tail)
    Tcl_Interp *interp;		/* Interpreter to receive results. */
    char *separators;		/* Path separators to pass to TclDoGlob. */
    Tcl_DString *dirPtr;	/* Contains path to directory to search. */
    char *pattern;		/* Pattern to match against. */
    char *tail;			/* Pointer to end of pattern. */

{
    char *dirName, *patternEnd = tail;
    char savedChar = 0;		/* Initialization needed only to prevent
				 * compiler warning from gcc. */
    DIR *d;

    struct stat statBuf;
    struct dirent *entryPtr;
    int matchHidden;
    int result = TCL_OK;
    int baseLength = Tcl_DStringLength(dirPtr);

    /*
     * Make sure that the directory part of the name really is a
     * directory.  If the directory name is "", use the name "."
     * instead, because some UNIX systems don't treat "" like "."
     * automatically.  Keep the "" for use in generating file names,
     * otherwise "glob foo.c" would return "./foo.c".
     */

    if (dirPtr->string[0] == '\0') {
	dirName = ".";
    } else {
	dirName = dirPtr->string;
    }


    if ((stat(dirName, &statBuf) != 0) || !S_ISDIR(statBuf.st_mode)) {
	return TCL_OK;
    }

    /*
     * Check to see if the pattern needs to compare with hidden files.
     */

    if ((pattern[0] == '.')
	    || ((pattern[0] == '\\') && (pattern[1] == '.'))) {
	matchHidden = 1;
    } else {
	matchHidden = 0;
    }

    /*
     * Now open the directory for reading and iterate over the contents.
     */


    d = opendir(dirName);

    if (d == NULL) {
	Tcl_ResetResult(interp);

	/*
	 * Strip off a trailing '/' if necessary, before reporting the error.
	 */

	if (baseLength > 0) {
	    savedChar = dirPtr->string[baseLength-1];
	    if (savedChar == '/') {
		dirPtr->string[baseLength-1] = '\0';
	    }
	}
	Tcl_AppendResult(interp, "couldn't read directory \"",

		dirPtr->string, "\": ", Tcl_PosixError(interp), (char *) NULL);
	if (baseLength > 0) {
	    dirPtr->string[baseLength-1] = savedChar;
	}
	return TCL_ERROR;
    }

    /*
     * Clean up the end of the pattern and the tail pointer.  Leave
     * the tail pointing to the first character after the path separator






|




|





<
<
<
<
<
|
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|





>
>
>
>
>
|


|

|

|


<
>
|
|
>

|
|

>
|
>
>
|
<
|
|
<


>
>

|










|







>
>
>
>
>
>








|
|








|




|
|
>
>
>
>
>
>
>
|

<


|

>
>
|
|
>









>
|
>
|
>












|
|
|
|
>
|
|
|
<
|
|
|
>
>
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
|
<



|






|











|




|
>

|
|
<

>

<












|


|

>
>
|


















>
|
>








|

|



>
|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17





18



19
















20
21
































































































































































22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55

56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172








































173
174




175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/* 
 * tclUnixFile.c --
 *
 *      This file contains wrappers around UNIX file handling functions.
 *      These wrappers mask differences between Windows and UNIX.
 *
 * Copyright (c) 1995-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: tclUnixFile.c,v 1.1.2.6 1999/03/12 23:29:20 surles Exp $
 */

#include "tclInt.h"
#include "tclPort.h"










/*
















 *---------------------------------------------------------------------------
 *
































































































































































 * TclpFindExecutable --
 *
 *	This procedure computes the absolute path name of the current
 *	application, given its argv[0] value.
 *
 * Results:
 *	A dirty UTF string that is the path to the executable.  At this
 *	point we may not know the system encoding.  Convert the native
 *	string value to UTF using the default encoding.  The assumption
 *	is that we will still be able to parse the path given the path
 *	name contains ASCII string and '/' chars do not conflict with
 *	other UTF chars.
 *
 * Side effects:
 *	The variable tclNativeExecutableName gets filled in with the file
 *	name for the application, if we figured it out.  If we couldn't
 *	figure it out, tclNativeExecutableName is set to NULL.
 *
 *---------------------------------------------------------------------------
 */


char *
TclpFindExecutable(argv0)
    CONST char *argv0;		/* The value of the application's argv[0]
				 * (native). */
{
    CONST char *name, *p;
    struct stat statBuf;
    int length;
    Tcl_DString buffer, nameString;

    if (argv0 == NULL) {
	return NULL;
    }

    if (tclNativeExecutableName != NULL) {
	return tclNativeExecutableName;

    }

    Tcl_DStringInit(&buffer);

    name = argv0;
    for (p = name; *p != '\0'; p++) {
	if (*p == '/') {
	    /*
	     * The name contains a slash, so use the name directly
	     * without doing a path search.
	     */

	    goto gotName;
	}
    }

    p = getenv("PATH");					/* INTL: Native. */
    if (p == NULL) {
	/*
	 * There's no PATH environment variable; use the default that
	 * is used by sh.
	 */

	p = ":/bin:/usr/bin";
    } else if (*p == '\0') {
	/*
	 * An empty path is equivalent to ".".
	 */

	p = "./";
    }

    /*
     * Search through all the directories named in the PATH variable
     * to see if argv[0] is in one of them.  If so, use that file
     * name.
     */

    while (1) {
	while (isspace(UCHAR(*p))) {		/* INTL: BUG */
	    p++;
	}
	name = p;
	while ((*p != ':') && (*p != 0)) {
	    p++;
	}
	Tcl_DStringSetLength(&buffer, 0);
	if (p != name) {
	    Tcl_DStringAppend(&buffer, name, p - name);
	    if (p[-1] != '/') {
		Tcl_DStringAppend(&buffer, "/", 1);
	    }
	}
	name = Tcl_DStringAppend(&buffer, argv0, -1);

	/*
	 * INTL: The following calls to access() and stat() should not be
	 * converted to Tclp routines because they need to operate on native
	 * strings directly.
	 */

	if ((access(name, X_OK) == 0)		/* INTL: Native. */
		&& (stat(name, &statBuf) == 0)	/* INTL: Native. */
		&& S_ISREG(statBuf.st_mode)) {

	    goto gotName;
	}
	if (*p == '\0') {
	    break;
	} else if (*(p+1) == 0) {
	    p = "./";
	} else {
	    p++;
	}
    }
    goto done;

    /*
     * If the name starts with "/" then just copy it to tclExecutableName.
     */

    gotName:
    if (name[0] == '/')  {
	Tcl_ExternalToUtfDString(NULL, name, -1, &nameString);
	tclNativeExecutableName = (char *)
		ckalloc((unsigned) (Tcl_DStringLength(&nameString) + 1));
	strcpy(tclNativeExecutableName, Tcl_DStringValue(&nameString));
	Tcl_DStringFree(&nameString);
	goto done;
    }

    /*
     * The name is relative to the current working directory.  First
     * strip off a leading "./", if any, then add the full path name of
     * the current working directory.
     */

    if ((name[0] == '.') && (name[1] == '/')) {
	name += 2;
    }

    Tcl_ExternalToUtfDString(NULL, name, -1, &nameString);

    Tcl_DStringFree(&buffer);
    TclpGetCwd(NULL, &buffer);

    length = Tcl_DStringLength(&buffer) + Tcl_DStringLength(&nameString) + 2;
    tclNativeExecutableName = (char *) ckalloc((unsigned) length);

    strcpy(tclNativeExecutableName, Tcl_DStringValue(&buffer));
    tclNativeExecutableName[Tcl_DStringLength(&buffer)] = '/';
    strcpy(tclNativeExecutableName + Tcl_DStringLength(&buffer) + 1,
	    Tcl_DStringValue(&nameString));
    Tcl_DStringFree(&nameString);
    
    done:
    Tcl_DStringFree(&buffer);








































    return tclNativeExecutableName;
}






/*
 *----------------------------------------------------------------------
 *
 * TclpMatchFiles --
 *
 *	This routine is used by the globbing code to search a
 *	directory for all files which match a given pattern.
 *
 * Results: 
 *	If the tail argument is NULL, then the matching files are
 *	added to the the interp's result.  Otherwise, TclDoGlob is called
 *	recursively for each matching subdirectory.  The return value
 *	is a standard Tcl result indicating whether an error occurred
 *	in globbing.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclpMatchFiles(interp, separators, dirPtr, pattern, tail)
    Tcl_Interp *interp;		/* Interpreter to receive results. */
    char *separators;		/* Path separators to pass to TclDoGlob. */
    Tcl_DString *dirPtr;	/* Contains path to directory to search. */
    char *pattern;		/* Pattern to match against. */
    char *tail;			/* Pointer to end of pattern. Must not
				 * refer to a static string. */
{
    char *native, *dirName, *patternEnd = tail;
    char savedChar = 0;		/* lint. */

    DIR *d;
    Tcl_DString ds;
    struct stat statBuf;

    int matchHidden;
    int result = TCL_OK;
    int baseLength = Tcl_DStringLength(dirPtr);

    /*
     * Make sure that the directory part of the name really is a
     * directory.  If the directory name is "", use the name "."
     * instead, because some UNIX systems don't treat "" like "."
     * automatically.  Keep the "" for use in generating file names,
     * otherwise "glob foo.c" would return "./foo.c".
     */

    if (Tcl_DStringLength(dirPtr) == 0) {
	dirName = ".";
    } else {
	dirName = Tcl_DStringValue(dirPtr);
    }

    if ((TclpStat(dirName, &statBuf) != 0)		/* INTL: UTF-8. */
	    || !S_ISDIR(statBuf.st_mode)) {
	return TCL_OK;
    }

    /*
     * Check to see if the pattern needs to compare with hidden files.
     */

    if ((pattern[0] == '.')
	    || ((pattern[0] == '\\') && (pattern[1] == '.'))) {
	matchHidden = 1;
    } else {
	matchHidden = 0;
    }

    /*
     * Now open the directory for reading and iterate over the contents.
     */

    native = Tcl_UtfToExternalDString(NULL, dirName, -1, &ds);
    d = opendir(native);				/* INTL: Native. */
    Tcl_DStringFree(&ds);
    if (d == NULL) {
	Tcl_ResetResult(interp);

	/*
	 * Strip off a trailing '/' if necessary, before reporting the error.
	 */

	if (baseLength > 0) {
	    savedChar = (Tcl_DStringValue(dirPtr))[baseLength-1];
	    if (savedChar == '/') {
		(Tcl_DStringValue(dirPtr))[baseLength-1] = '\0';
	    }
	}
	Tcl_AppendResult(interp, "couldn't read directory \"",
		Tcl_DStringValue(dirPtr), "\": ",
		Tcl_PosixError(interp), (char *) NULL);
	if (baseLength > 0) {
	    (Tcl_DStringValue(dirPtr))[baseLength-1] = savedChar;
	}
	return TCL_ERROR;
    }

    /*
     * Clean up the end of the pattern and the tail pointer.  Leave
     * the tail pointing to the first character after the path separator
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



































































































































































































































































    } else {
	tail++;
    }
    savedChar = *patternEnd;
    *patternEnd = '\0';

    while (1) {



	entryPtr = readdir(d);
	if (entryPtr == NULL) {
	    break;
	}

	/*
	 * Don't match names starting with "." unless the "." is
	 * present in the pattern.
	 */

	if (!matchHidden && (*entryPtr->d_name == '.')) {
	    continue;
	}

	/*
	 * Now check to see if the file matches.  If there are more
	 * characters to be processed, then ensure matching files are
	 * directories before calling TclDoGlob. Otherwise, just add
	 * the file to the result.
	 */


	if (Tcl_StringMatch(entryPtr->d_name, pattern)) {
	    Tcl_DStringSetLength(dirPtr, baseLength);
	    Tcl_DStringAppend(dirPtr, entryPtr->d_name, -1);
	    if (tail == NULL) {
		Tcl_AppendElement(interp, dirPtr->string);
	    } else if ((stat(dirPtr->string, &statBuf) == 0)
		    && S_ISDIR(statBuf.st_mode)) {
		Tcl_DStringAppend(dirPtr, "/", 1);
		result = TclDoGlob(interp, separators, dirPtr, tail);
		if (result != TCL_OK) {

		    break;
		}
	    }
	}

    }
    *patternEnd = savedChar;

    closedir(d);
    return result;
}










































































































































































































































































>
>
>
|




















>
|

|

|
|




>




>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
    } else {
	tail++;
    }
    savedChar = *patternEnd;
    *patternEnd = '\0';

    while (1) {
	char *utf;
	struct dirent *entryPtr;
	
	entryPtr = readdir(d);				/* INTL: Native. */
	if (entryPtr == NULL) {
	    break;
	}

	/*
	 * Don't match names starting with "." unless the "." is
	 * present in the pattern.
	 */

	if (!matchHidden && (*entryPtr->d_name == '.')) {
	    continue;
	}

	/*
	 * Now check to see if the file matches.  If there are more
	 * characters to be processed, then ensure matching files are
	 * directories before calling TclDoGlob. Otherwise, just add
	 * the file to the result.
	 */

	utf = Tcl_ExternalToUtfDString(NULL, entryPtr->d_name, -1, &ds);
	if (Tcl_StringMatch(utf, pattern) != 0) {
	    Tcl_DStringSetLength(dirPtr, baseLength);
	    Tcl_DStringAppend(dirPtr, utf, -1);
	    if (tail == NULL) {
		Tcl_AppendElement(interp, Tcl_DStringValue(dirPtr));
	    } else if ((TclpStat(Tcl_DStringValue(dirPtr), &statBuf) == 0)
		    && S_ISDIR(statBuf.st_mode)) {
		Tcl_DStringAppend(dirPtr, "/", 1);
		result = TclDoGlob(interp, separators, dirPtr, tail);
		if (result != TCL_OK) {
		    Tcl_DStringFree(&ds);
		    break;
		}
	    }
	}
	Tcl_DStringFree(&ds);
    }
    *patternEnd = savedChar;

    closedir(d);
    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpGetUserHome --
 *
 *	This function takes the specified user name and finds their
 *	home directory.
 *
 * Results:
 *	The result is a pointer to a string specifying the user's home
 *	directory, or NULL if the user's home directory could not be
 *	determined.  Storage for the result string is allocated in
 *	bufferPtr; the caller must call Tcl_DStringFree() when the result
 *	is no longer needed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpGetUserHome(name, bufferPtr)
    CONST char *name;		/* User name for desired home directory. */
    Tcl_DString *bufferPtr;	/* Uninitialized or free DString filled
				 * with name of user's home directory. */
{
    struct passwd *pwPtr;
    Tcl_DString ds;
    char *native;

    native = Tcl_UtfToExternalDString(NULL, name, -1, &ds);
    pwPtr = getpwnam(native);				/* INTL: Native. */
    Tcl_DStringFree(&ds);
    
    if (pwPtr == NULL) {
	endpwent();
	return NULL;
    }
    Tcl_ExternalToUtfDString(NULL, pwPtr->pw_dir, -1, bufferPtr);
    endpwent();
    return Tcl_DStringValue(bufferPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpAccess --
 *
 *	This function replaces the library version of access().
 *
 * Results:
 *	See access() documentation.
 *
 * Side effects:
 *	See access() documentation.
 *
 *---------------------------------------------------------------------------
 */

int
TclpAccess(path, mode)
    CONST char *path;		/* Path of file to access (UTF-8). */
    int mode;			/* Permission setting. */
{
    int result;
    Tcl_DString ds;
    char *native;
    
    native = Tcl_UtfToExternalDString(NULL, path, -1, &ds);
    result = access(native, mode);			/* INTL: Native. */
    Tcl_DStringFree(&ds);

    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpChdir --
 *
 *	This function replaces the library version of chdir().
 *
 * Results:
 *	See chdir() documentation.
 *
 * Side effects:
 *	See chdir() documentation.  
 *
 *---------------------------------------------------------------------------
 */

int
TclpChdir(dirName)
    CONST char *dirName;     	/* Path to new working directory (UTF-8). */
{
    int result;
    Tcl_DString ds;
    char *native;

    native = Tcl_UtfToExternalDString(NULL, dirName, -1, &ds);
    result = chdir(native);				/* INTL: Native. */
    Tcl_DStringFree(&ds);

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpLstat --
 *
 *	This function replaces the library version of lstat().
 *
 * Results:
 *	See lstat() documentation.
 *
 * Side effects:
 *	See lstat() documentation.
 *
 *----------------------------------------------------------------------
 */

int
TclpLstat(path, bufPtr)
    CONST char *path;		/* Path of file to stat (UTF-8). */
    struct stat *bufPtr;	/* Filled with results of stat call. */
{
    int result;
    Tcl_DString ds;
    char *native;
    
    native = Tcl_UtfToExternalDString(NULL, path, -1, &ds);
    result = lstat(native, bufPtr);			/* INTL: Native. */
    Tcl_DStringFree(&ds);

    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpGetCwd --
 *
 *	This function replaces the library version of getcwd().
 *
 * Results:
 *	The result is a pointer to a string specifying the current
 *	directory, or NULL if the current directory could not be
 *	determined.  If NULL is returned, an error message is left in the
 *	interp's result.  Storage for the result string is allocated in
 *	bufferPtr; the caller must call Tcl_DStringFree() when the result
 *	is no longer needed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpGetCwd(interp, bufferPtr)
    Tcl_Interp *interp;		/* If non-NULL, used for error reporting. */
    Tcl_DString *bufferPtr;	/* Uninitialized or free DString filled
				 * with name of current directory. */
{
    char buffer[MAXPATHLEN+1];

#ifdef USEGETWD
    if (getwd(buffer) == NULL) {			/* INTL: Native. */
#else
    if (getcwd(buffer, MAXPATHLEN + 1) == NULL) {	/* INTL: Native. */
#endif
	if (interp != NULL) {
	    Tcl_AppendResult(interp,
		    "error getting working directory name: ",
		    Tcl_PosixError(interp), (char *) NULL);
	}
	return NULL;
    }
    return Tcl_ExternalToUtfDString(NULL, buffer, -1, bufferPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpReadlink --
 *
 *	This function replaces the library version of readlink().
 *
 * Results:
 *	The result is a pointer to a string specifying the contents
 *	of the symbolic link given by 'path', or NULL if the symbolic
 *	link could not be read.  Storage for the result string is
 *	allocated in bufferPtr; the caller must call Tcl_DStringFree()
 *	when the result is no longer needed.
 *
 * Side effects:
 *	See readlink() documentation.
 *
 *---------------------------------------------------------------------------
 */

char *
TclpReadlink(path, linkPtr)
    CONST char *path;		/* Path of file to readlink (UTF-8). */
    Tcl_DString *linkPtr;	/* Uninitialized or free DString filled
				 * with contents of link (UTF-8). */
{
    char link[MAXPATHLEN];
    int length;
    char *native;
    Tcl_DString ds;

    native = Tcl_UtfToExternalDString(NULL, path, -1, &ds);
    length = readlink(native, link, sizeof(link));	/* INTL: Native. */
    Tcl_DStringFree(&ds);
    
    if (length < 0) {
	return NULL;
    }

    Tcl_ExternalToUtfDString(NULL, link, length, linkPtr);
    return Tcl_DStringValue(linkPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpStat --
 *
 *	This function replaces the library version of stat().
 *
 * Results:
 *	See stat() documentation.
 *
 * Side effects:
 *	See stat() documentation.
 *
 *----------------------------------------------------------------------
 */

int
TclpStat(path, bufPtr)
    CONST char *path;		/* Path of file to stat (in UTF-8). */
    struct stat *bufPtr;	/* Filled with results of stat call. */
{
    int result;
    Tcl_DString ds;
    char *native;
    
    native = Tcl_UtfToExternalDString(NULL, path, -1, &ds);
    result = stat(native, bufPtr);			/* INTL: Native. */
    Tcl_DStringFree(&ds);

    return result;
}

Changes to unix/tclUnixInit.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

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
/* 
 * tclUnixInit.c --
 *
 *	Contains the Unix-specific interpreter initialization functions.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclUnixInit.c 1.26 97/08/05 20:09:25
 */

#include "tclInt.h"
#include "tclPort.h"

#if defined(__FreeBSD__)
#   include <floatingpoint.h>
#endif
#if defined(__bsdi__)
#   include <sys/param.h>
#   if _BSDI_VERSION > 199501
#	include <dlfcn.h>
#   endif
#endif








/*
 * Default directory in which to look for Tcl library scripts.  The
 * symbol is defined by Makefile.
 */

static char defaultLibraryDir[200] = TCL_LIBRARY;

/*
 * Directory in which to look for packages (each package is typically
 * installed as a subdirectory of this directory).  The symbol is
 * defined by Makefile.
 */

static char pkgPath[200] = TCL_PACKAGE_PATH;








































/*







 * Is this module initialized?








 */


static int initialized = 0;



/*





 * The following string is the startup script executed in new
 * interpreters.  It looks on disk in several different directories

 * for a script "init.tcl" that is compatible with this version



 * of Tcl.  The init.tcl script does all of the real work of




 * initialization.



 */












































static char initScript[] =

"proc tclInit {} {\n\










    global tcl_library tcl_version tcl_patchLevel env errorInfo\n\
    global tcl_pkgPath\n\
    rename tclInit {}\n\
    set errors {}\n\




    set dirs {}\n\

    if [info exists env(TCL_LIBRARY)] {\n\


	lappend dirs $env(TCL_LIBRARY)\n\
    }\n\

    lappend dirs [info library]\n\

    set parentDir [file dirname [file dirname [info nameofexecutable]]]\n\
    lappend dirs $parentDir/lib/tcl$tcl_version\n\
    if [string match {*[ab]*} $tcl_patchLevel] {\n\
	set lib tcl$tcl_patchLevel\n\
    } else {\n\
	set lib tcl$tcl_version\n\

    }\n\
    lappend dirs [file dirname $parentDir]/$lib/library\n\

    lappend dirs $parentDir/library\n\




    foreach i $dirs {\n\


	set tcl_library $i\n\
	set tclfile [file join $i init.tcl]\n\




	if {[file exists $tclfile]} {\n\

            lappend tcl_pkgPath [file dirname $i]\n\
	    if ![catch {uplevel #0 [list source $tclfile]} msg] {\n\




		return\n\
	    } else {\n\
		append errors \"$tclfile: $msg\n$errorInfo\n\"\n\
	    }\n\

	}\n\
    }\n\
    set msg \"Can't find a usable init.tcl in the following directories: \n\"\n\


    append msg \"    $dirs\n\n\"\n\




    append msg \"$errors\n\n\"\n\


    append msg \"This probably means that Tcl wasn't installed properly.\n\"\n\
    error $msg\n\

}\n\







tclInit";











/*


 * Static routines in this file:
 */






static void	PlatformInitExitHandler _ANSI_ARGS_((ClientData clientData));




/*
 *----------------------------------------------------------------------
 *
 * PlatformInitExitHandler --
 *
 *	Uninitializes all values on unload, so that this module can



 *	be later reinitialized.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Returns the module to uninitialized state.
 *
 *----------------------------------------------------------------------
 */

static void






PlatformInitExitHandler(clientData)





    ClientData clientData;		/* Unused. */

{






    strcpy(defaultLibraryDir, TCL_LIBRARY);








    strcpy(pkgPath, TCL_PACKAGE_PATH);





























    initialized = 0;




















}

/*
 *----------------------------------------------------------------------
 *
 * TclPlatformInit --
 *
 *	Performs Unix-specific interpreter initialization related to the
 *      tcl_library and tcl_platform variables, and other platform-
 *	specific things.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets "tcl_library" and "tcl_platform" Tcl variables.
 *
 *----------------------------------------------------------------------
 */

void
TclPlatformInit(interp)
    Tcl_Interp *interp;
{
#ifndef NO_UNAME
    struct utsname name;
#endif
    int unameOK;



    tclPlatform = TCL_PLATFORM_UNIX;
    Tcl_SetVar(interp, "tcl_library", defaultLibraryDir, TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp, "tcl_pkgPath", pkgPath, TCL_GLOBAL_ONLY);
    Tcl_SetVar2(interp, "tcl_platform", "platform", "unix", TCL_GLOBAL_ONLY);
    unameOK = 0;
#ifndef NO_UNAME
    if (uname(&name) >= 0) {


	unameOK = 1;


	Tcl_SetVar2(interp, "tcl_platform", "os", name.sysname,

		TCL_GLOBAL_ONLY);
	/*
	 * The following code is a special hack to handle differences in
	 * the way version information is returned by uname.  On most
	 * systems the full version number is available in name.release.
	 * However, under AIX the major version number is in
	 * name.version and the minor version number is in name.release.
	 */

	if ((strchr(name.release, '.') != NULL) || !isdigit(name.version[0])) {

	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.release,
		    TCL_GLOBAL_ONLY);
	} else {
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.version,
		    TCL_GLOBAL_ONLY);
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", ".",
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE);
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.release,
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE);
	}
	Tcl_SetVar2(interp, "tcl_platform", "machine", name.machine,
		TCL_GLOBAL_ONLY);
    }
#endif
    if (!unameOK) {
	Tcl_SetVar2(interp, "tcl_platform", "os", "", TCL_GLOBAL_ONLY);
	Tcl_SetVar2(interp, "tcl_platform", "osVersion", "", TCL_GLOBAL_ONLY);
	Tcl_SetVar2(interp, "tcl_platform", "machine", "", TCL_GLOBAL_ONLY);
    }

    if (!initialized) {

        /*
         * Create an exit handler so that uninitialization will be done
         * on unload.

         */
        










        Tcl_CreateExitHandler(PlatformInitExitHandler, NULL);
        

	/*
	 * The code below causes SIGPIPE (broken pipe) errors to


	 * be ignored.  This is needed so that Tcl processes don't






	 * die if they create child processes (e.g. using "exec" or
	 * "open") that terminate prematurely.  The signal handler


	 * is only set up when the first interpreter is created;

	 * after this the application can override the handler with
	 * a different one of its own, if it wants.


	 */
    
#ifdef SIGPIPE
	(void) signal(SIGPIPE, SIG_IGN);

#endif /* SIGPIPE */





#ifdef __FreeBSD__

	fpsetround(FP_RN);
	fpsetmask(0L);




#endif



#if defined(__bsdi__) && (_BSDI_VERSION > 199501)




	/*


	 * Find local symbols. Don't report an error if we fail.
	 */
	(void) dlopen (NULL, RTLD_NOW);
#endif
	initialized = 1;
    }



}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Init --
 *
 *	This procedure is typically invoked by Tcl_AppInit procedures
 *	to perform additional initialization for a Tcl interpreter,
 *	such as sourcing the "init.tcl" script.

 *
 * Results:
 *	Returns a standard Tcl completion code and sets interp->result
 *	if there is an error.
 *
 * Side effects:
 *	Depends on what's in the init.tcl script.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Init(interp)
    Tcl_Interp *interp;		/* Interpreter to initialize. */
{













    return Tcl_Eval(interp, initScript);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SourceRCFile --





|




|




>









>
>
>
>
>
>
>






|







|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>


>
|
>
>

|
>
>
>
>
>
|
|
>
|
>
>
>
|
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
|
|
|
|
>
>
>
>
|
>
|
>
>
|
|
>
|
>
|
<
|
|
|
|
>
|
<
>
|
>
>
>
>
|
>
>
|
|
>
>
>
>
|
>
|
|
>
>
>
>
|
|
|
|
>
|
<
|
>
>
|
>
>
>
>
|
>
>
|
|
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
|
>
>
|
|
|
>
>
>
>
>
|
>
>
|
>

|

|

<
>
>
>
|





|

|


|
>
>
>
>
>
>
|
>
>
>
>
>
|
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|

|

|
|












|






>
>

<






>
>

>
>
|
>
|








|
>




















<
<
|
<
<
>
|
|
>
>
>
>
>
>
>
>
>
>
|
|
>
|
<
>
>
|
>
>
>
>
>
>
|
<
>
>
|
>
|
|
>
>
|
|
|
|
>
|
>
>
>
>
|
|
>
|
|
>
>
>
>
|
>
>
|
|
>
>
>
>
|
>
>
|
<
<
|
<
|
>
>
>








<
|
>


|
|











>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471


472


473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497
498
499

500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539


540

541
542
543
544
545
546
547
548
549
550
551
552

553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
/* 
 * tclUnixInit.c --
 *
 *	Contains the Unix-specific interpreter initialization functions.
 *
 * 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: tclUnixInit.c,v 1.1.2.14 1999/04/06 20:21:27 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"
#include <locale.h>
#if defined(__FreeBSD__)
#   include <floatingpoint.h>
#endif
#if defined(__bsdi__)
#   include <sys/param.h>
#   if _BSDI_VERSION > 199501
#	include <dlfcn.h>
#   endif
#endif

/*
 * The Init script (common to Windows and Unix platforms) is
 * defined in tkInitScript.h
 */
#include "tclInitScript.h"


/*
 * Default directory in which to look for Tcl library scripts.  The
 * symbol is defined by Makefile.
 */

static char defaultLibraryDir[sizeof(TCL_LIBRARY)+200] = TCL_LIBRARY;

/*
 * Directory in which to look for packages (each package is typically
 * installed as a subdirectory of this directory).  The symbol is
 * defined by Makefile.
 */

static char pkgPath[sizeof(TCL_PACKAGE_PATH)+200] = TCL_PACKAGE_PATH;

typedef struct LocaleTable {
    CONST char *lang;
    CONST char *encoding;
} LocaleTable;

static CONST LocaleTable localeTable[] = {
    {"ja_JP.SJIS",	"shiftjis"},
    {"ja_JP.EUC",	"euc-jp"},
    {"ja_JP.JIS",	"iso2022-jp"},
    {"ja_JP.mscode",	"shiftjis"},
    {"ja_JP.ujis",	"euc-jp"},
    {"ja_JP",		"euc-jp"},
    {"Ja_JP",		"shiftjis"},
    {"Jp_JP",		"shiftjis"},
    {"japan",		"euc-jp"},
#ifdef hpux
    {"japanese",	"shiftjis"},	
    {"ja",		"shiftjis"},	
#else
    {"japanese",	"euc-jp"},
    {"ja",		"euc-jp"},
#endif
    {"japanese.sjis",	"shiftjis"},
    {"japanese.euc",	"euc-jp"},
    {"japanese-sjis",	"shiftjis"},
    {"japanese-ujis",	"euc-jp"},

    {"ko",              "euc-kr"},
    {"ko_KR",           "euc-kr"},
    {"ko_KR.EUC",       "euc-kr"},
    {"ko_KR.euc",       "euc-kr"},
    {"ko_KR.eucKR",     "euc-kr"},
    {"korean",          "euc-kr"},

    {"zh",		"cp936"},

    {NULL, NULL}
};

/*
 *---------------------------------------------------------------------------
 *
 * TclpInitPlatform --
 *
 *	Initialize all the platform-dependant things like signals and
 *	floating-point error handling.
 *
 *	Called at process initialization time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TclpInitPlatform()
{
    tclPlatform = TCL_PLATFORM_UNIX;

    /*
     * The code below causes SIGPIPE (broken pipe) errors to
     * be ignored.  This is needed so that Tcl processes don't
     * die if they create child processes (e.g. using "exec" or
     * "open") that terminate prematurely.  The signal handler
     * is only set up when the first interpreter is created;
     * after this the application can override the handler with
     * a different one of its own, if it wants.
     */

#ifdef SIGPIPE
    (void) signal(SIGPIPE, SIG_IGN);
#endif /* SIGPIPE */

#ifdef __FreeBSD__
    fpsetround(FP_RN);
    fpsetmask(0L);
#endif

#if defined(__bsdi__) && (_BSDI_VERSION > 199501)
    /*
     * Find local symbols. Don't report an error if we fail.
     */
    (void) dlopen (NULL, RTLD_NOW);			/* INTL: Native. */
#endif
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpInitLibraryPath --
 *
 *	Initialize the library path at startup.  We have a minor
 *	metacircular problem that we don't know the encoding of the
 *	operating system but we may need to talk to operating system
 *	to find the library directories so that we know how to talk to
 *	the operating system.
 *
 *	We do not know the encoding of the operating system.
 *	We do know that the encoding is some multibyte encoding.
 *	In that multibyte encoding, the characters 0..127 are equivalent
 *	    to ascii.
 *
 *	So although we don't know the encoding, it's safe:
 *	    to look for the last slash character in a path in the encoding.
 *	    to append an ascii string to a path.
 *	    to pass those strings back to the operating system.
 *
 *	But any strings that we remembered before we knew the encoding of
 *	the operating system must be translated to UTF-8 once we know the
 *	encoding so that the rest of Tcl can use those strings.
 *
 *	This call sets the library path to strings in the unknown native
 *	encoding.  TclpSetInitialEncodings() will translate the library
 *	path from the native encoding to UTF-8 as soon as it determines
 *	what the native encoding actually is.
 *
 *	Called at process initialization time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TclpInitLibraryPath(path)
CONST char *path;		/* Path to the executable in native 
				 * multi-byte encoding. */
{
#define LIBRARY_SIZE	    32
    Tcl_Obj *pathPtr, *objPtr;
    char *str;
    Tcl_DString buffer, ds;
    int pathc;
    char **pathv;
    char installLib[LIBRARY_SIZE], developLib[LIBRARY_SIZE];

    Tcl_DStringInit(&ds);
    pathPtr = Tcl_NewObj();

    /*
     * Initialize the substrings used when locating an executable.  The
     * installLib variable computes the path as though the executable
     * is installed.  The developLib computes the path as though the
     * executable is run from a develpment directory.
     */
     
    sprintf(installLib, "lib/tcl%s", TCL_VERSION);
    sprintf(developLib, "tcl%s/library",
	    ((TCL_RELEASE_LEVEL < 2) ? TCL_PATCH_LEVEL : TCL_VERSION));

    /*
     * Look for the library relative to default encoding dir.
     */


    str = Tcl_GetDefaultEncodingDir();
    if ((str != NULL) && (str[0] != '\0')) {
	objPtr = Tcl_NewStringObj(str, -1);
	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
    }


    /*
     * Look for the library relative to the TCL_LIBRARY env variable.
     * If the last dirname in the TCL_LIBRARY path does not match the
     * last dirname in the installLib variable, use the last dir name
     * of installLib in addition to the orginal TCL_LIBRARY path.
     */

    str = getenv("TCL_LIBRARY");			/* INTL: Native. */
    Tcl_ExternalToUtfDString(NULL, str, -1, &buffer);
    str = Tcl_DStringValue(&buffer);

    if ((str != NULL) && (str[0] != '\0')) {
	/*
	 * If TCL_LIBRARY is set, search there.
	 */
	 
	objPtr = Tcl_NewStringObj(str, -1);
	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);

	Tcl_SplitPath(str, &pathc, &pathv);
	if ((pathc > 0) && (strcasecmp(installLib + 4, pathv[pathc-1]) != 0)) {
	    /*
	     * If TCL_LIBRARY is set but refers to a different tcl
	     * installation than the current version, try fiddling with the
	     * specified directory to make it refer to this installation by
	     * removing the old "tclX.Y" and substituting the current
	     * version string.
	     */
	    

	    pathv[pathc - 1] = installLib + 4;
	    str = Tcl_JoinPath(pathc, pathv, &ds);
	    objPtr = Tcl_NewStringObj(str, Tcl_DStringLength(&ds));
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
	    Tcl_DStringFree(&ds);
	}
	ckfree((char *) pathv);
    }

    /*
     * Look for the library relative to the executable.  Use both the
     * installLib and developLib because we cannot determine if this
     * is installed or not.
     */
     
    if (path != NULL) {
	Tcl_SplitPath(path, &pathc, &pathv);
	if (pathc > 1) {
	    pathv[pathc - 2] = installLib;
	    path = Tcl_JoinPath(pathc - 1, pathv, &ds);
	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
	    Tcl_DStringFree(&ds);
	}
	if (pathc > 2) {
	    pathv[pathc - 3] = developLib;
	    path = Tcl_JoinPath(pathc - 2, pathv, &ds);
	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
	    Tcl_DStringFree(&ds);
	}
	ckfree((char *) pathv);
    }

    /*
     * Finally, look for the library relative to the compiled-in path.
     * This is needed when users install Tcl with an exec-prefix that
     * is different from the prtefix.
     */
			      
    str = defaultLibraryDir;
    if (str[0] != '\0') {
        objPtr = Tcl_NewStringObj(str, -1);
        Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
    }

    TclSetLibraryPath(pathPtr);    
    Tcl_DStringFree(&buffer);
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpSetInitialEncodings --
 *

 *	Based on the locale, determine the encoding of the operating
 *	system and the default encoding for newly opened files.
 *
 *	Called at process initialization time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The Tcl library path is converted from native encoding to UTF-8.
 *
 *---------------------------------------------------------------------------
 */

void
TclpSetInitialEncodings()
{
    CONST char *encoding;
    int i;
    Tcl_Obj *pathPtr;
    char *langEnv;

    /*
     * Determine the current encoding from the LC_TYPE or LANG environment
     * variables.  We previously used setlocale() to determine the locale,
     * but this does not work on some systems (e.g. Linux/i386 RH 5.0).
     */

    langEnv = getenv("LC_CTYPE");

    if (langEnv == NULL || langEnv[0] == '\0') {
	langEnv = getenv("LANG");
    }
    if (langEnv == NULL || langEnv[0] == '\0') {
	langEnv = NULL;
    }

    encoding = "iso8859-1";
    if (langEnv != NULL) {
	for (i = 0; localeTable[i].lang != NULL; i++) {
	    if (strcmp(localeTable[i].lang, langEnv) == 0) {
		encoding = localeTable[i].encoding;
	    }
	}
    }

    Tcl_SetSystemEncoding(NULL, encoding);

    /*
     * Until the system encoding was actually set, the library path was
     * actually in the native multi-byte encoding, and not really UTF-8
     * as advertised.  We cheated as follows:
     *
     * 1. It was safe to allow the Tcl_SetSystemEncoding() call to 
     * append the ASCII chars that make up the encoding's filename to 
     * the names (in the native encoding) of directories in the library 
     * path, since all Unix multi-byte encodings have ASCII in the
     * beginning.
     *
     * 2. To open the encoding file, the native bytes in the file name
     * were passed to the OS, without translating from UTF-8 to native,
     * because the name was already in the native encoding.
     *
     * Now that the system encoding was actually successfully set,
     * translate all the names in the library path to UTF-8.  That way,
     * next time we search the library path, we'll translate the names 
     * from UTF-8 to the system encoding which will be the native 
     * encoding.
     */

    pathPtr = TclGetLibraryPath();
    if (pathPtr != NULL) {
	int objc;
	Tcl_Obj **objv;
	
	objc = 0;
	Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);
	for (i = 0; i < objc; i++) {
	    int length;
	    char *string;
	    Tcl_DString ds;

	    string = Tcl_GetStringFromObj(objv[i], &length);
	    Tcl_ExternalToUtfDString(NULL, string, length, &ds);
	    Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds), 
		    Tcl_DStringLength(&ds));
	    Tcl_DStringFree(&ds);
	}
    }

    /*
     * Keep the iso8859-1 encoding preloaded.  The IO package uses it for
     * gets on a binary channel.
     */

    Tcl_GetEncoding(NULL, "iso8859-1");
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpSetVariables --
 *
 *	Performs platform-specific interpreter initialization related to
 *	the tcl_library and tcl_platform variables, and other platform-
 *	specific things.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets "tcl_library" and "tcl_platform" Tcl variables.
 *
 *----------------------------------------------------------------------
 */

void
TclpSetVariables(interp)
    Tcl_Interp *interp;
{
#ifndef NO_UNAME
    struct utsname name;
#endif
    int unameOK;
    char *user;
    Tcl_DString ds;


    Tcl_SetVar(interp, "tcl_library", defaultLibraryDir, TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp, "tcl_pkgPath", pkgPath, TCL_GLOBAL_ONLY);
    Tcl_SetVar2(interp, "tcl_platform", "platform", "unix", TCL_GLOBAL_ONLY);
    unameOK = 0;
#ifndef NO_UNAME
    if (uname(&name) >= 0) {
	char *native;
	
	unameOK = 1;

	native = Tcl_ExternalToUtfDString(NULL, name.sysname, -1, &ds);
	Tcl_SetVar2(interp, "tcl_platform", "os", native, TCL_GLOBAL_ONLY);
	Tcl_DStringFree(&ds);
	
	/*
	 * The following code is a special hack to handle differences in
	 * the way version information is returned by uname.  On most
	 * systems the full version number is available in name.release.
	 * However, under AIX the major version number is in
	 * name.version and the minor version number is in name.release.
	 */

	if ((strchr(name.release, '.') != NULL)
		|| !isdigit(UCHAR(name.version[0]))) {	/* INTL: digit */
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.release,
		    TCL_GLOBAL_ONLY);
	} else {
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.version,
		    TCL_GLOBAL_ONLY);
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", ".",
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE);
	    Tcl_SetVar2(interp, "tcl_platform", "osVersion", name.release,
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE);
	}
	Tcl_SetVar2(interp, "tcl_platform", "machine", name.machine,
		TCL_GLOBAL_ONLY);
    }
#endif
    if (!unameOK) {
	Tcl_SetVar2(interp, "tcl_platform", "os", "", TCL_GLOBAL_ONLY);
	Tcl_SetVar2(interp, "tcl_platform", "osVersion", "", TCL_GLOBAL_ONLY);
	Tcl_SetVar2(interp, "tcl_platform", "machine", "", TCL_GLOBAL_ONLY);
    }



    /*


     * Copy USER or LOGNAME environment variable into tcl_platform(user)
     */

    Tcl_DStringInit(&ds);
    user = TclGetEnv("USER", &ds);
    if (user == NULL) {
	user = TclGetEnv("LOGNAME", &ds);
	if (user == NULL) {
	    user = "";
	}
    }
    Tcl_SetVar2(interp, "tcl_platform", "user", user, TCL_GLOBAL_ONLY);
    Tcl_DStringFree(&ds);

}

/*

 *----------------------------------------------------------------------
 *
 * TclpFindVariable --
 *
 *	Locate the entry in environ for a given name.  On Unix this 
 *	routine is case sensetive, on Windows this matches mioxed case.
 *
 * Results:
 *	The return value is the index in environ of an entry with the
 *	name "name", or -1 if there is no such entry.   The integer at

 *	*lengthPtr is filled in with the length of name (if a matching
 *	entry is found) or the length of the environ array (if no matching
 *	entry is found).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclpFindVariable(name, lengthPtr)
    CONST char *name;		/* Name of desired environment variable
				 * (native). */
    int *lengthPtr;		/* Used to return length of name (for
				 * successful searches) or number of non-NULL
				 * entries in environ (for unsuccessful
				 * searches). */
{
    int i, result = -1;
    register CONST char *env, *p1, *p2;
    Tcl_DString envString;

    Tcl_DStringInit(&envString);
    for (i = 0, env = environ[i]; env != NULL; i++, env = environ[i]) {
	p1 = Tcl_ExternalToUtfDString(NULL, env, -1, &envString);
	p2 = name;

	for (; *p2 == *p1; p1++, p2++) {
	    /* NULL loop body. */
	}
	if ((*p1 == '=') && (*p2 == '\0')) {
	    *lengthPtr = p2 - name;
	    result = i;
	    goto done;
	}
	
	Tcl_DStringFree(&envString);
    }
    


    *lengthPtr = i;


    done:
    Tcl_DStringFree(&envString);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Init --
 *
 *	This procedure is typically invoked by Tcl_AppInit procedures

 *	to find and source the "init.tcl" script, which should exist
 *	somewhere on the Tcl library path.
 *
 * Results:
 *	Returns a standard Tcl completion code and sets the interp's
 *	result if there is an error.
 *
 * Side effects:
 *	Depends on what's in the init.tcl script.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Init(interp)
    Tcl_Interp *interp;		/* Interpreter to initialize. */
{
    Tcl_Obj *pathPtr;

    if (tclPreInitScript != NULL) {
	if (Tcl_Eval(interp, tclPreInitScript) == TCL_ERROR) {
	    return (TCL_ERROR);
	};
    }
    
    pathPtr = TclGetLibraryPath();
    if (pathPtr == NULL) {
	pathPtr = Tcl_NewObj();
    }
    Tcl_SetVar2Ex(interp, "tcl_libPath", NULL, pathPtr, TCL_GLOBAL_ONLY);
    return Tcl_Eval(interp, initScript);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SourceRCFile --
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317




























            c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
            if (c != (Tcl_Channel) NULL) {
                Tcl_Close(NULL, c);
		if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
		    errChannel = Tcl_GetStdChannel(TCL_STDERR);
		    if (errChannel) {
			Tcl_Write(errChannel, interp->result, -1);
			Tcl_Write(errChannel, "\n", 1);
		    }
		}
	    }
	}
        Tcl_DStringFree(&temp);
    }
}


































|
|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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

            c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
            if (c != (Tcl_Channel) NULL) {
                Tcl_Close(NULL, c);
		if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
		    errChannel = Tcl_GetStdChannel(TCL_STDERR);
		    if (errChannel) {
			Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
			Tcl_WriteChars(errChannel, "\n", 1);
		    }
		}
	    }
	}
        Tcl_DStringFree(&temp);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCheckStackSpace --
 *
 *	Detect if we are about to blow the stack.  Called before an 
 *	evaluation can happen when nesting depth is checked.
 *
 * Results:
 *	1 if there is enough stack space to continue; 0 if not.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclpCheckStackSpace()
{
    /*
     * This function is unimplemented on Unix platforms.
     */

    return 1;
}

Changes to unix/tclUnixNotfy.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclUnixNotify.c --
 *
 *	This file contains the implementation of the select-based
 *	Unix-specific notifier, which is the lowest-level part of the
 *	Tcl event loop.  This file works together with
 *	../generic/tclNotify.c.
 *
 * 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.
 *
 * SCCS: @(#) tclUnixNotfy.c 1.44 97/11/05 13:02:20
 */

#include "tclInt.h"
#include "tclPort.h"
#include <signal.h> 

/*













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclUnixNotify.c --
 *
 *	This file contains the implementation of the select-based
 *	Unix-specific notifier, which is the lowest-level part of the
 *	Tcl event loop.  This file works together with
 *	../generic/tclNotify.c.
 *
 * 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: tclUnixNotfy.c,v 1.1.2.10 1999/04/09 23:30:01 redman Exp $
 */

#include "tclInt.h"
#include "tclPort.h"
#include <signal.h> 

/*
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
				 * the file (can't point directly to the
				 * FileHandler structure because it could
				 * go away while the event is queued). */
} FileHandlerEvent;

/*
 * The following static structure contains the state information for the
 * select based implementation of the Tcl notifier.

 */

static struct {
    FileHandler *firstFileHandlerPtr;
				/* Pointer to head of file handler list. */
    fd_mask checkMasks[3*MASK_SIZE];
				/* This array is used to build up the masks
				 * to be used in the next call to select.
				 * Bits are set in response to calls to
				 * Tcl_CreateFileHandler. */
    fd_mask readyMasks[3*MASK_SIZE];
				/* This array reflects the readable/writable
				 * conditions that were found to exist by the
				 * last call to select. */
    int numFdBits;		/* Number of valid bits in checkMasks
				 * (one more than highest fd for which
				 * Tcl_WatchFile has been called). */




} notifier;



















/*
 * The following static indicates whether this module has been initialized.



 */




























static int initialized = 0;


































/*
 * Static routines defined in this file.
 */

static void		InitNotifier _ANSI_ARGS_((void));
static void		NotifierExitHandler _ANSI_ARGS_((
			    ClientData clientData));

static int		FileHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
			    int flags));

/*
 *----------------------------------------------------------------------
 *
 * InitNotifier --
 *
 *	Initializes the notifier state.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new exit handler.
 *
 *----------------------------------------------------------------------
 */

static void
InitNotifier()
{

    initialized = 1;


    memset(&notifier, 0, sizeof(notifier));



    Tcl_CreateExitHandler(NotifierExitHandler, NULL);



















}

/*
 *----------------------------------------------------------------------
 *
 * NotifierExitHandler --
 *
 *	This function is called to cleanup the notifier state before
 *	Tcl is unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:

 *	Destroys the notifier window.
 *
 *----------------------------------------------------------------------
 */

static void
NotifierExitHandler(clientData)
    ClientData clientData;		/* Not used. */
{


    initialized = 0;


























































}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetTimer --
 *







|
>


|














>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>

|
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
<
|
>
|
|




|

|


|


|




|
|

>
|
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|


|





>
|




|
|


>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
				 * the file (can't point directly to the
				 * FileHandler structure because it could
				 * go away while the event is queued). */
} FileHandlerEvent;

/*
 * The following static structure contains the state information for the
 * select based implementation of the Tcl notifier.  One of these structures
 * is created for each thread that is using the notifier.  
 */

typedef struct ThreadSpecificData {
    FileHandler *firstFileHandlerPtr;
				/* Pointer to head of file handler list. */
    fd_mask checkMasks[3*MASK_SIZE];
				/* This array is used to build up the masks
				 * to be used in the next call to select.
				 * Bits are set in response to calls to
				 * Tcl_CreateFileHandler. */
    fd_mask readyMasks[3*MASK_SIZE];
				/* This array reflects the readable/writable
				 * conditions that were found to exist by the
				 * last call to select. */
    int numFdBits;		/* Number of valid bits in checkMasks
				 * (one more than highest fd for which
				 * Tcl_WatchFile has been called). */
#ifdef TCL_THREADS
    int onList;			/* True if it is in this list */
    unsigned int pollState;	/* pollState is used to implement a polling 
				 * handshake between each thread and the
				 * notifier thread. Bits defined below. */
    struct ThreadSpecificData *nextPtr, *prevPtr;
                                /* All threads that are currently waiting on 
                                 * an event have their ThreadSpecificData
                                 * structure on a doubly-linked listed formed
                                 * from these pointers.  You must hold the
                                 * notifierMutex lock before accessing these
                                 * fields. */
    Tcl_Condition waitCV;     /* Any other thread alerts a notifier
				 * that an event is ready to be processed
				 * by signaling this condition variable. */
    int eventReady;           /* True if an event is ready to be processed.
                               * Used as condition flag together with
                               * waitCV above. */
#endif
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

#ifdef TCL_THREADS
/*
 * The following static indicates the number of threads that have
 * initialized notifiers.
 *
 * You must hold the notifierMutex lock before accessing this variable.
 */

static int notifierCount = 0;

/*
 * The following variable points to the head of a doubly-linked list of 
 * of ThreadSpecificData structures for all threads that are currently
 * waiting on an event.
 *
 * You must hold the notifierMutex lock before accessing this list.
 */

static ThreadSpecificData *waitingListPtr = NULL;

/*
 * The notifier thread spends all its time in select() waiting for a
 * file descriptor associated with one of the threads on the waitingListPtr
 * list to do something interesting.  But if the contents of the
 * waitingListPtr list ever changes, we need to wake up and restart
 * the select() system call.  You can wake up the notifier thread by
 * writing a single byte to the file descriptor defined below.  This
 * file descriptor is the input-end of a pipe and the notifier thread is
 * listening for data on the output-end of the same pipe.  Hence writing
 * to this file descriptor will cause the select() system call to return
 * and wake up the notifier thread.
 *
 * You must hold the notifierMutex lock before accessing this list.
 */

static int triggerPipe = -1;

/*
 * The notifierMutex locks access to all of the global notifier state. 
 */

TCL_DECLARE_MUTEX(notifierMutex)

/*
 * The notifier thread signals the notifierCV when it has finished
 * initializing the triggerPipe and right before the notifier
 * thread terminates.
 */

static Tcl_Condition notifierCV;

/*
 * The pollState bits
 *	POLL_WANT is set by each thread before it waits on its condition
 *		variable.  It is checked by the notifier before it does
 *		select.
 *	POLL_DONE is set by the notifier if it goes into select after
 *		seeing POLL_WANT.  The idea is to ensure it tries a select
 *		with the same bits the initial thread had set.
 */
#define POLL_WANT	0x1
#define POLL_DONE	0x2

/*
 * This is the thread ID of the notifier thread that does select.
 */
static Tcl_ThreadId notifierThread;

#endif

/*
 * Static routines defined in this file.
 */

#ifdef TCL_THREADS

static void	NotifierThreadProc _ANSI_ARGS_((ClientData clientData));
#endif
static int	FileHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
		    int flags));

/*
 *----------------------------------------------------------------------
 *
 * Tcl_InitNotifier --
 *
 *	Initializes the platform specific notifier state.
 *
 * Results:
 *	Returns a handle to the notifier state for this thread..
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

ClientData
Tcl_InitNotifier()
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

#ifdef TCL_THREADS
    tsdPtr->eventReady = 0;

    /*
     * Start the Notifier thread if necessary.
     */

    Tcl_MutexLock(&notifierMutex);
    if (notifierCount == 0) {
	if (TclpThreadCreate(&notifierThread, NotifierThreadProc, NULL) != TCL_OK) {
	    panic("Tcl_InitNotifier: unable to start notifier thread");
	}
    }
    notifierCount++;

    /*
     * Wait for the notifier pipe to be created.
     */

    while (triggerPipe < 0) {
	Tcl_ConditionWait(&notifierCV, &notifierMutex, NULL);
    }

    Tcl_MutexUnlock(&notifierMutex);
#endif
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FinalizeNotifier --
 *
 *	This function is called to cleanup the notifier state before
 *	a thread is terminated.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May terminate the background notifier thread if this is the
 *	last notifier instance.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_FinalizeNotifier(clientData)
    ClientData clientData;		/* Not used. */
{
#ifdef TCL_THREADS
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    Tcl_MutexLock(&notifierMutex);
    notifierCount--;

    /*
     * If this is the last thread to use the notifier, close the notifier
     * pipe and wait for the background thread to terminate.
     */

    if (notifierCount == 0) {
	if (triggerPipe < 0) {
	    panic("Tcl_FinalizeNotifier: notifier pipe not initialized");
	}
	close(triggerPipe);
	Tcl_ConditionWait(&notifierCV, &notifierMutex, NULL);
    }

    /*
     * Clean up any synchronization objects in the thread local storage.
     */

    TclFinalizeCondition(&(tsdPtr->waitCV));

    Tcl_MutexUnlock(&notifierMutex);
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AlertNotifier --
 *
 *	Wake up the specified notifier from any thread. This routine
 *	is called by the platform independent notifier code whenever
 *	the Tcl_ThreadAlert routine is called.  This routine is
 *	guaranteed not to be called on a given notifier after
 *	Tcl_FinalizeNotifier is called for that notifier.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Signals the notifier condition variable for the specified
 *	notifier.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AlertNotifier(clientData)
    ClientData clientData;
{
#ifdef TCL_THREADS
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
    Tcl_MutexLock(&notifierMutex);
    tsdPtr->eventReady = 1;
    Tcl_ConditionNotify(&tsdPtr->waitCV);
    Tcl_MutexUnlock(&notifierMutex);
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetTimer --
 *
165
166
167
168
169
170
171























172
173
174
175
176
177
178
     * timeout values to Tcl_WaitForEvent.
     */
}

/*
 *----------------------------------------------------------------------
 *























 * Tcl_CreateFileHandler --
 *
 *	This procedure registers a file handler with the Xt notifier.
 *
 * Results:
 *	None.
 *







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
     * timeout values to Tcl_WaitForEvent.
     */
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ServiceModeHook --
 *
 *	This function is invoked whenever the service mode changes.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ServiceModeHook(mode)
    int mode;			/* Either TCL_SERVICE_ALL, or
				 * TCL_SERVICE_NONE. */
{
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateFileHandler --
 *
 *	This procedure registers a file handler with the Xt notifier.
 *
 * Results:
 *	None.
 *
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
				 * TCL_WRITABLE, and TCL_EXCEPTION:
				 * indicates conditions under which
				 * proc should be called. */
    Tcl_FileProc *proc;		/* Procedure to call for each
				 * selected event. */
    ClientData clientData;	/* Arbitrary data to pass to proc. */
{

    FileHandler *filePtr;
    int index, bit;
    
    if (!initialized) {
	InitNotifier();
    }

    for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;
	    filePtr = filePtr->nextPtr) {
	if (filePtr->fd == fd) {
	    break;
	}
    }
    if (filePtr == NULL) {
	filePtr = (FileHandler*) ckalloc(sizeof(FileHandler)); /* MLK */
	filePtr->fd = fd;
	filePtr->readyMask = 0;
	filePtr->nextPtr = notifier.firstFileHandlerPtr;
	notifier.firstFileHandlerPtr = filePtr;
    }
    filePtr->proc = proc;
    filePtr->clientData = clientData;
    filePtr->mask = mask;

    /*
     * Update the check masks for this file.
     */

    index = fd/(NBBY*sizeof(fd_mask));
    bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
    if (mask & TCL_READABLE) {
	notifier.checkMasks[index] |= bit;
    } else {
	notifier.checkMasks[index] &= ~bit;
    } 
    if (mask & TCL_WRITABLE) {
	(notifier.checkMasks+MASK_SIZE)[index] |= bit;
    } else {
	(notifier.checkMasks+MASK_SIZE)[index] &= ~bit;
    }
    if (mask & TCL_EXCEPTION) {
	(notifier.checkMasks+2*(MASK_SIZE))[index] |= bit;
    } else {
	(notifier.checkMasks+2*(MASK_SIZE))[index] &= ~bit;
    }
    if (notifier.numFdBits <= fd) {
	notifier.numFdBits = fd+1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DeleteFileHandler --







>


|
<
<
<
<
|
|





|


|
|












|

|


|

|


|

|

|
|







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
				 * TCL_WRITABLE, and TCL_EXCEPTION:
				 * indicates conditions under which
				 * proc should be called. */
    Tcl_FileProc *proc;		/* Procedure to call for each
				 * selected event. */
    ClientData clientData;	/* Arbitrary data to pass to proc. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    FileHandler *filePtr;
    int index, bit;





    for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
	 filePtr = filePtr->nextPtr) {
	if (filePtr->fd == fd) {
	    break;
	}
    }
    if (filePtr == NULL) {
	filePtr = (FileHandler*) ckalloc(sizeof(FileHandler));
	filePtr->fd = fd;
	filePtr->readyMask = 0;
	filePtr->nextPtr = tsdPtr->firstFileHandlerPtr;
	tsdPtr->firstFileHandlerPtr = filePtr;
    }
    filePtr->proc = proc;
    filePtr->clientData = clientData;
    filePtr->mask = mask;

    /*
     * Update the check masks for this file.
     */

    index = fd/(NBBY*sizeof(fd_mask));
    bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
    if (mask & TCL_READABLE) {
	tsdPtr->checkMasks[index] |= bit;
    } else {
	tsdPtr->checkMasks[index] &= ~bit;
    } 
    if (mask & TCL_WRITABLE) {
	(tsdPtr->checkMasks+MASK_SIZE)[index] |= bit;
    } else {
	(tsdPtr->checkMasks+MASK_SIZE)[index] &= ~bit;
    }
    if (mask & TCL_EXCEPTION) {
	(tsdPtr->checkMasks+2*(MASK_SIZE))[index] |= bit;
    } else {
	(tsdPtr->checkMasks+2*(MASK_SIZE))[index] &= ~bit;
    }
    if (tsdPtr->numFdBits <= fd) {
	tsdPtr->numFdBits = fd+1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DeleteFileHandler --
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
void
Tcl_DeleteFileHandler(fd)
    int fd;		/* Stream id for which to remove callback procedure. */
{
    FileHandler *filePtr, *prevPtr;
    int index, bit, i;
    unsigned long flags;

    if (!initialized) {
	InitNotifier();
    }

    /*
     * Find the entry for the given file (and return if there
     * isn't one).
     */

    for (prevPtr = NULL, filePtr = notifier.firstFileHandlerPtr; ;
	    prevPtr = filePtr, filePtr = filePtr->nextPtr) {
	if (filePtr == NULL) {
	    return;
	}
	if (filePtr->fd == fd) {
	    break;
	}
    }

    /*
     * Update the check masks for this file.
     */

    index = fd/(NBBY*sizeof(fd_mask));
    bit = 1 << (fd%(NBBY*sizeof(fd_mask)));

    if (filePtr->mask & TCL_READABLE) {
	notifier.checkMasks[index] &= ~bit;
    }
    if (filePtr->mask & TCL_WRITABLE) {
	(notifier.checkMasks+MASK_SIZE)[index] &= ~bit;
    }
    if (filePtr->mask & TCL_EXCEPTION) {
	(notifier.checkMasks+2*(MASK_SIZE))[index] &= ~bit;
    }

    /*
     * Find current max fd.
     */

    if (fd+1 == notifier.numFdBits) {
	for (notifier.numFdBits = 0; index >= 0; index--) {
	    flags = notifier.checkMasks[index]
		| (notifier.checkMasks+MASK_SIZE)[index]
		| (notifier.checkMasks+2*(MASK_SIZE))[index];
	    if (flags) {
		for (i = (NBBY*sizeof(fd_mask)); i > 0; i--) {
		    if (flags & (((unsigned long)1) << (i-1))) {
			break;
		    }
		}
		notifier.numFdBits = index * (NBBY*sizeof(fd_mask)) + i;
		break;
	    }
	}
    }

    /*
     * Clean up information in the callback record.
     */

    if (prevPtr == NULL) {
	notifier.firstFileHandlerPtr = filePtr->nextPtr;
    } else {
	prevPtr->nextPtr = filePtr->nextPtr;
    }
    ckfree((char *) filePtr);
}

/*







|
<
<
|
<

|
<


|
|
















|


|


|






|
|
|
|
|






|










|







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
void
Tcl_DeleteFileHandler(fd)
    int fd;		/* Stream id for which to remove callback procedure. */
{
    FileHandler *filePtr, *prevPtr;
    int index, bit, i;
    unsigned long flags;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);




    /*
     * Find the entry for the given file (and return if there isn't one).

     */

    for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ;
	 prevPtr = filePtr, filePtr = filePtr->nextPtr) {
	if (filePtr == NULL) {
	    return;
	}
	if (filePtr->fd == fd) {
	    break;
	}
    }

    /*
     * Update the check masks for this file.
     */

    index = fd/(NBBY*sizeof(fd_mask));
    bit = 1 << (fd%(NBBY*sizeof(fd_mask)));

    if (filePtr->mask & TCL_READABLE) {
	tsdPtr->checkMasks[index] &= ~bit;
    }
    if (filePtr->mask & TCL_WRITABLE) {
	(tsdPtr->checkMasks+MASK_SIZE)[index] &= ~bit;
    }
    if (filePtr->mask & TCL_EXCEPTION) {
	(tsdPtr->checkMasks+2*(MASK_SIZE))[index] &= ~bit;
    }

    /*
     * Find current max fd.
     */

    if (fd+1 == tsdPtr->numFdBits) {
	for (tsdPtr->numFdBits = 0; index >= 0; index--) {
	    flags = tsdPtr->checkMasks[index]
		| (tsdPtr->checkMasks+MASK_SIZE)[index]
		| (tsdPtr->checkMasks+2*(MASK_SIZE))[index];
	    if (flags) {
		for (i = (NBBY*sizeof(fd_mask)); i > 0; i--) {
		    if (flags & (((unsigned long)1) << (i-1))) {
			break;
		    }
		}
		tsdPtr->numFdBits = index * (NBBY*sizeof(fd_mask)) + i;
		break;
	    }
	}
    }

    /*
     * Clean up information in the callback record.
     */

    if (prevPtr == NULL) {
	tsdPtr->firstFileHandlerPtr = filePtr->nextPtr;
    } else {
	prevPtr->nextPtr = filePtr->nextPtr;
    }
    ckfree((char *) filePtr);
}

/*
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

static int
FileHandlerEventProc(evPtr, flags)
    Tcl_Event *evPtr;		/* Event to service. */
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{

    FileHandler *filePtr;
    FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr;
    int mask;


    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the file handlers to find the one whose handle matches
     * the event.  We do this rather than keeping a pointer to the file
     * handler directly in the event, so that the handler can be deleted
     * while the event is queued without leaving a dangling pointer.
     */


    for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;
	    filePtr = filePtr->nextPtr) {
	if (filePtr->fd != fileEvPtr->fd) {
	    continue;
	}

	/*
	 * The code is tricky for two reasons:
	 * 1. The file handler's desired events could have changed







>


<
>












>
|
|







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

static int
FileHandlerEventProc(evPtr, flags)
    Tcl_Event *evPtr;		/* Event to service. */
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    int mask;
    FileHandler *filePtr;
    FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr;

    ThreadSpecificData *tsdPtr;

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the file handlers to find the one whose handle matches
     * the event.  We do this rather than keeping a pointer to the file
     * handler directly in the event, so that the handler can be deleted
     * while the event is queued without leaving a dangling pointer.
     */

    tsdPtr = TCL_TSD_INIT(&dataKey);
    for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
	 filePtr = filePtr->nextPtr) {
	if (filePtr->fd != fileEvPtr->fd) {
	    continue;
	}

	/*
	 * The code is tricky for two reasons:
	 * 1. The file handler's desired events could have changed
431
432
433
434
435
436
437
438
439


440
441
442

443
444
445
446
447
448
449
450
451
452
453

454








455

456
457
458
459





460











































































461
462
463
464
465
466
467
468
469
470
471
472
473
474

475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516



517
518
































































































































































































int
Tcl_WaitForEvent(timePtr)
    Tcl_Time *timePtr;		/* Maximum block time, or NULL. */
{
    FileHandler *filePtr;
    FileHandlerEvent *fileEvPtr;
    struct timeval timeout, *timeoutPtr;
    int bit, index, mask, numFound;



    if (!initialized) {
	InitNotifier();
    }


    /*
     * Set up the timeout structure.  Note that if there are no events to
     * check for, we return with a negative result rather than blocking
     * forever.
     */

    if (timePtr) {
	timeout.tv_sec = timePtr->sec;
	timeout.tv_usec = timePtr->usec;
	timeoutPtr = &timeout;

    } else if (notifier.numFdBits == 0) {








	return -1;

    } else {
	timeoutPtr = NULL;
    }






    memcpy((VOID *) notifier.readyMasks, (VOID *) notifier.checkMasks,











































































	    3*MASK_SIZE*sizeof(fd_mask));
    numFound = select(notifier.numFdBits,
	    (SELECT_MASK *) &notifier.readyMasks[0],
	    (SELECT_MASK *) &notifier.readyMasks[MASK_SIZE],
	    (SELECT_MASK *) &notifier.readyMasks[2*MASK_SIZE], timeoutPtr);

    /*
     * Some systems don't clear the masks after an error, so
     * we have to do it here.
     */

    if (numFound == -1) {
	memset((VOID *) notifier.readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
    }


    /*
     * Queue all detected file events before returning.
     */

    for (filePtr = notifier.firstFileHandlerPtr;
	    (filePtr != NULL) && (numFound > 0);
	    filePtr = filePtr->nextPtr) {
	index = filePtr->fd / (NBBY*sizeof(fd_mask));
	bit = 1 << (filePtr->fd % (NBBY*sizeof(fd_mask)));
	mask = 0;

	if (notifier.readyMasks[index] & bit) {
	    mask |= TCL_READABLE;
	}
	if ((notifier.readyMasks+MASK_SIZE)[index] & bit) {
	    mask |= TCL_WRITABLE;
	}
	if ((notifier.readyMasks+2*(MASK_SIZE))[index] & bit) {
	    mask |= TCL_EXCEPTION;
	}

	if (!mask) {
	    continue;
	} else {
	    numFound--;
	}

	/*
	 * Don't bother to queue an event if the mask was previously
	 * non-zero since an event must still be on the queue.
	 */

	if (filePtr->readyMask == 0) {
	    fileEvPtr = (FileHandlerEvent *) ckalloc(
		sizeof(FileHandlerEvent));
	    fileEvPtr->header.proc = FileHandlerEventProc;
	    fileEvPtr->fd = filePtr->fd;
	    Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
	}
	filePtr->readyMask = mask;
    }



    return 0;
}







































































































































































































|
|
>
>
|
|
<
>











>
|
>
>
>
>
>
>
>
>

>




>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|
|
|







|

>





<
|
|




|


|


|





<
<
















>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
621
622
623
624
625
626
627
628
629
630
631
632
633

634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762

763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780


781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
int
Tcl_WaitForEvent(timePtr)
    Tcl_Time *timePtr;		/* Maximum block time, or NULL. */
{
    FileHandler *filePtr;
    FileHandlerEvent *fileEvPtr;
    struct timeval timeout, *timeoutPtr;
    int bit, index, mask;
#ifdef TCL_THREADS
    int waitForFiles;
#else
    int numFound;
#endif

    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Set up the timeout structure.  Note that if there are no events to
     * check for, we return with a negative result rather than blocking
     * forever.
     */

    if (timePtr) {
	timeout.tv_sec = timePtr->sec;
	timeout.tv_usec = timePtr->usec;
	timeoutPtr = &timeout;
#ifndef TCL_THREADS
    } else if (tsdPtr->numFdBits == 0) {
	/*
	 * If there are no threads, no timeout, and no fds registered,
	 * then there are no events possible and we must avoid deadlock.
	 * Note that this is not entirely correct because there might
	 * be a signal that could interrupt the select call, but we
	 * don't handle that case if we aren't using threads.
	 */

	return -1;
#endif
    } else {
	timeoutPtr = NULL;
    }

#ifdef TCL_THREADS
    /*
     * Place this thread on the list of interested threads, signal the
     * notifier thread, and wait for a response or a timeout.
     */

    Tcl_MutexLock(&notifierMutex);

    waitForFiles = (tsdPtr->numFdBits > 0);
    if (timePtr != NULL && timePtr->sec == 0 && timePtr->usec == 0) {
	/*
	 * Cannot emulate a polling select with a polling condition variable.
	 * Instead, pretend to wait for files and tell the notifier
	 * thread what we are doing.  The notifier thread makes sure
	 * it goes through select with its select mask in the same state
	 * as ours currently is.  We block until that happens.
	 */

	waitForFiles = 1;
	tsdPtr->pollState = POLL_WANT;
	timePtr = NULL;
    } else {
	tsdPtr->pollState = 0;
    }

    if (waitForFiles) {
        /*
         * Add the ThreadSpecificData structure of this thread to the list
         * of ThreadSpecificData structures of all threads that are waiting
         * on file events.
         */


        tsdPtr->nextPtr = waitingListPtr;
        if (waitingListPtr) {
            waitingListPtr->prevPtr = tsdPtr;
        }
        tsdPtr->prevPtr = 0;
        waitingListPtr = tsdPtr;
	tsdPtr->onList = 1;
	
	Tcl_MutexUnlock(&notifierMutex);
	write(triggerPipe, "", 1);
	Tcl_MutexLock(&notifierMutex);
    }

    memset((VOID *) tsdPtr->readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));

    if (!tsdPtr->eventReady) {

        Tcl_ConditionWait(&tsdPtr->waitCV, &notifierMutex, timePtr);
    }
    tsdPtr->eventReady = 0;

    if (waitForFiles && tsdPtr->onList) {
	/*
	 * Remove the ThreadSpecificData structure of this thread from the
	 * waiting list.  Alert the notifier thread to recompute its select
	 * masks - skipping this caused a hang when trying to close a pipe
	 * which the notifier thread was still doing a select on.
	 */

        if (tsdPtr->prevPtr) {
            tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
        } else {
            waitingListPtr = tsdPtr->nextPtr;
        }
        if (tsdPtr->nextPtr) {
            tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
        }
        tsdPtr->nextPtr = tsdPtr->prevPtr = NULL;
	tsdPtr->onList = 0;
        Tcl_MutexUnlock(&notifierMutex);
	write(triggerPipe, "", 1);
        Tcl_MutexLock(&notifierMutex);

    }

    
#else
    memcpy((VOID *) tsdPtr->readyMasks, (VOID *) tsdPtr->checkMasks,
	    3*MASK_SIZE*sizeof(fd_mask));
    numFound = select(tsdPtr->numFdBits,
	    (SELECT_MASK *) &tsdPtr->readyMasks[0],
	    (SELECT_MASK *) &tsdPtr->readyMasks[MASK_SIZE],
	    (SELECT_MASK *) &tsdPtr->readyMasks[2*MASK_SIZE], timeoutPtr);

    /*
     * Some systems don't clear the masks after an error, so
     * we have to do it here.
     */

    if (numFound == -1) {
	memset((VOID *) tsdPtr->readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
    }
#endif

    /*
     * Queue all detected file events before returning.
     */


    for (filePtr = tsdPtr->firstFileHandlerPtr; (filePtr != NULL);
	 filePtr = filePtr->nextPtr) {
	index = filePtr->fd / (NBBY*sizeof(fd_mask));
	bit = 1 << (filePtr->fd % (NBBY*sizeof(fd_mask)));
	mask = 0;

	if (tsdPtr->readyMasks[index] & bit) {
	    mask |= TCL_READABLE;
	}
	if ((tsdPtr->readyMasks+MASK_SIZE)[index] & bit) {
	    mask |= TCL_WRITABLE;
	}
	if ((tsdPtr->readyMasks+2*(MASK_SIZE))[index] & bit) {
	    mask |= TCL_EXCEPTION;
	}

	if (!mask) {
	    continue;


	}

	/*
	 * Don't bother to queue an event if the mask was previously
	 * non-zero since an event must still be on the queue.
	 */

	if (filePtr->readyMask == 0) {
	    fileEvPtr = (FileHandlerEvent *) ckalloc(
		sizeof(FileHandlerEvent));
	    fileEvPtr->header.proc = FileHandlerEventProc;
	    fileEvPtr->fd = filePtr->fd;
	    Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
	}
	filePtr->readyMask = mask;
    }
#ifdef TCL_THREADS
    Tcl_MutexUnlock(&notifierMutex);
#endif
    return 0;
}

#ifdef TCL_THREADS
/*
 *----------------------------------------------------------------------
 *
 * NotifierThreadProc --
 *
 *	This routine is the initial (and only) function executed by the
 *	special notifier thread.  Its job is to wait for file descriptors
 *	to become readable or writable or to have an exception condition
 *	and then to notify other threads who are interested in this
 *	information by signalling a condition variable.  Other threads
 *	can signal this notifier thread of a change in their interests
 *	by writing a single byte to a special pipe that the notifier
 *	thread is monitoring.
 *
 * Result:
 *	None.  Once started, this routine never exits.  It dies with
 *	the overall process.
 *
 * Side effects:
 *	The trigger pipe used to signal the notifier thread is created
 *	when the notifier thread first starts.
 *
 *----------------------------------------------------------------------
 */

static void
NotifierThreadProc(clientData)
    ClientData clientData;	/* Not used. */
{
    ThreadSpecificData *tsdPtr;
    fd_mask masks[3*MASK_SIZE];
    long *maskPtr = (long *)masks;	/* masks[] cast to type long[] */
    int fds[2];
    int i, status, index, bit, numFdBits, found, receivePipe, word;
    struct timeval poll = {0., 0.}, *timePtr;
    int maskSize = 3 * ((MASK_SIZE) / sizeof(long)) * sizeof(fd_mask);
    char buf[2];

    if (pipe(fds) != 0) {
	panic("NotifierThreadProc: could not create trigger pipe.");
    }

    receivePipe = fds[0];

#ifndef USE_FIONBIO
    status = fcntl(receivePipe, F_GETFL);
    status |= O_NONBLOCK;
    if (fcntl(receivePipe, F_SETFL, status) < 0) {
	panic("NotifierThreadProc: could not make receive pipe non blocking.");
    }
#else
    if (ioctl(receivePipe, (int) FIONBIO, &status) < 0) {
	panic("NotifierThreadProc: could not make receive pipe non blocking.");
    }
#endif

    /*
     * Install the write end of the pipe into the global variable.
     */

    Tcl_MutexLock(&notifierMutex);
    triggerPipe = fds[1];

    /*
     * Signal any threads that are waiting.
     */

    Tcl_ConditionNotify(&notifierCV);
    Tcl_MutexUnlock(&notifierMutex);

    /*
     * Look for file events and report them to interested threads.
     */

    while (1) {
	/*
	 * Set up the select mask to include the receive pipe.
	 */

	memset((VOID *)masks, 0, 3*MASK_SIZE*sizeof(fd_mask));
        numFdBits = receivePipe + 1;
	index = receivePipe / (NBBY*sizeof(fd_mask));
	bit = 1 << (receivePipe % (NBBY*sizeof(fd_mask)));
	masks[index] |= bit;

	/*
	 * Add in the check masks from all of the waiting notifiers.
	 */
	
	Tcl_MutexLock(&notifierMutex);
	timePtr = NULL;
        for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
            for (i = 0; i < maskSize; i++) {
                maskPtr[i] |= ((long*)tsdPtr->checkMasks)[i];
            }
            if (tsdPtr->numFdBits > numFdBits) {
                numFdBits = tsdPtr->numFdBits;
            }
	    if (tsdPtr->pollState & POLL_WANT) {
		/*
		 * Here we make sure we go through select() with the same
		 * mask bits that were present when the thread tried to poll.
		 */

		tsdPtr->pollState |= POLL_DONE;
		timePtr = &poll;
	    }
        }
	Tcl_MutexUnlock(&notifierMutex);

	maskSize = 3 * ((MASK_SIZE) / sizeof(long)) * sizeof(fd_mask);

	if (select(numFdBits, (SELECT_MASK *) &masks[0],
		(SELECT_MASK *) &masks[MASK_SIZE],
		(SELECT_MASK *) &masks[2*MASK_SIZE], timePtr) == -1) {
	    /*
	     * Try again immediately on an error.
	     */

	    continue;
        }

	/*
	 * Alert any threads that are waiting on a ready file descriptor.
	 */

	Tcl_MutexLock(&notifierMutex);
        for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
	    found = 0;

            for (i = 0; i < maskSize; i++) {
                word = maskPtr[i] & ((long*)tsdPtr->checkMasks)[i];
                found |= word;
                (((long*)(tsdPtr->readyMasks))[i]) = word;
	    }
            if (found || (tsdPtr->pollState & POLL_DONE)) {
                tsdPtr->eventReady = 1;
		Tcl_ConditionNotify(&tsdPtr->waitCV);
		if (tsdPtr->onList) {
		    /*
		     * Remove the ThreadSpecificData structure of this thread
		     * from the waiting list. This prevents us from continuously
		     * spining on select until the other threads runs and
		     * services the file event.
		     */
	    
		    if (tsdPtr->prevPtr) {
			tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
		    } else {
			waitingListPtr = tsdPtr->nextPtr;
		    }
		    if (tsdPtr->nextPtr) {
			tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
		    }
		    tsdPtr->nextPtr = tsdPtr->prevPtr = NULL;
		    tsdPtr->onList = 0;
		    tsdPtr->pollState = 0;
		}
            }
        }
	Tcl_MutexUnlock(&notifierMutex);
	
	/*
	 * Consume the next byte from the notifier pipe if the pipe was
	 * readable.  Note that there may be multiple bytes pending, but
	 * to avoid a race condition we only read one at a time.
	 */

	if ((masks[index] & bit) && (read(receivePipe, buf, 1) == 0)) {
	    /*
	     * Someone closed the write end of the pipe so we need to
	     * shut down the notifier thread.
	     */

	    break;
	}
    }

    /*
     * Clean up the read end of the pipe and signal any threads waiting on
     * termination of the notifier thread.
     */

    close(receivePipe);
    Tcl_MutexLock(&notifierMutex);
    triggerPipe = -1;
    Tcl_ConditionNotify(&notifierCV);
    Tcl_MutexUnlock(&notifierMutex);
}
#endif

Changes to unix/tclUnixPipe.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclUnixPipe.c --
 *
 *	This file implements the UNIX-specific exec pipeline functions,
 *	the "pipe" channel driver, and the "pid" Tcl command.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * 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.
 *
 * SCCS: @(#) tclUnixPipe.c 1.37 97/10/31 17:23:37
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * The following macros convert between TclFile's and fd's.  The conversion












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 
 * tclUnixPipe.c --
 *
 *	This file implements the UNIX-specific exec pipeline functions,
 *	the "pipe" channel driver, and the "pid" Tcl command.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * 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: tclUnixPipe.c,v 1.1.2.2 1998/09/24 23:59:45 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * The following macros convert between TclFile's and fd's.  The conversion
124
125
126
127
128
129
130
131
132
133
134


135

136

137
138
139
140
141
142
143
 *	May cause a file to be created on the file system.
 *
 *----------------------------------------------------------------------
 */

TclFile
TclpOpenFile(fname, mode)
    char *fname;			/* The name of the file to open. */
    int mode;				/* In what mode to open the file? */
{
    int fd;




    fd = open(fname, mode, 0666);

    if (fd != -1) {
        fcntl(fd, F_SETFD, FD_CLOEXEC);

	/*
	 * If the file is being opened for writing, seek to the end
	 * so we can append to any data already in the file.
	 */







|
|


>
>

>
|
>







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
 *	May cause a file to be created on the file system.
 *
 *----------------------------------------------------------------------
 */

TclFile
TclpOpenFile(fname, mode)
    CONST char *fname;		/* The name of the file to open. */
    int mode;			/* In what mode to open the file? */
{
    int fd;
    char *native;
    Tcl_DString ds;

    native = Tcl_UtfToExternalDString(NULL, fname, -1, &ds);
    fd = open(native, mode, 0666);			/* INTL: Native. */
    Tcl_DStringFree(&ds);
    if (fd != -1) {
        fcntl(fd, F_SETFD, FD_CLOEXEC);

	/*
	 * If the file is being opened for writing, seek to the end
	 * so we can append to any data already in the file.
	 */
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
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TclFile
TclpCreateTempFile(contents, namePtr)
    char *contents;		/* String to write into temp file, or NULL. */
    Tcl_DString *namePtr;	/* If non-NULL, pointer to initialized 
				 * DString that is filled with the name of 
				 * the temp file that was created. */
{
    char fileName[L_tmpnam];
    TclFile file;
    size_t length = (contents == NULL) ? 0 : strlen(contents);

    tmpnam(fileName);
    file = TclpOpenFile(fileName, O_RDWR|O_CREAT|O_TRUNC);




    unlink(fileName);

    if ((file != NULL) && (length > 0)) {
	int fd = GetFd(file);
	while (1) {
	    if (write(fd, contents, length) != -1) {
		break;
	    } else if (errno != EINTR) {
		close(fd);
		return NULL;
	    }
	}
	lseek(fd, 0, SEEK_SET);
    }
    if (namePtr != NULL) {
	Tcl_DStringAppend(namePtr, fileName, -1);
    }
    return file;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCreatePipe --
 *







|
|
<
<
<


|
<

|
|
>
>
>
>
|

|
<
<
|
<
<
|
|
|
<


<
<
<
|







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
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TclFile
TclpCreateTempFile(contents)
    CONST char *contents;	/* String to write into temp file, or NULL. */



{
    char fileName[L_tmpnam];
    int fd;


    tmpnam(fileName);					/* INTL: Native. */
    fd = open(fileName, O_RDWR|O_CREAT|O_TRUNC, 0666);	/* INTL: Native. */
    if (fd == -1) {
	return NULL;
    }
    fcntl(fd, F_SETFD, FD_CLOEXEC);
    unlink(fileName);					/* INTL: Native. */

    if (contents != NULL) {


	if (write(fd, contents, strlen(contents)) == -1) {


	    close(fd);
	    return NULL;
	}

	lseek(fd, 0, SEEK_SET);
    }



    return MakeFile(fd);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCreatePipe --
 *
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
    }
    
    Tcl_DeleteFileHandler(fd);
    return close(fd);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCreateProcess --
 *
 *	Create a child process that has the specified files as its 
 *	standard input, output, and error.  The child process runs
 *	asynchronously and runs with the same environment variables
 *	as the creating process.
 *
 *	The path is searched to find the specified executable.  
 *
 * Results:
 *	The return value is TCL_ERROR and an error message is left in
 *	interp->result if there was a problem creating the child 
 *	process.  Otherwise, the return value is TCL_OK and *pidPtr is
 *	filled with the process id of the child process.
 * 
 * Side effects:
 *	A process is created.
 *	
 *----------------------------------------------------------------------
 */

    /* ARGSUSED */
int
TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile, 
	pidPtr)
    Tcl_Interp *interp;		/* Interpreter in which to leave errors that
				 * occurred when creating the child process.
				 * Error messages from the child process
				 * itself are sent to errorFile. */
    int argc;			/* Number of arguments in following array. */
    char **argv;		/* Array of argument strings.  argv[0]
				 * contains the name of the executable
				 * converted to native format (using the
				 * Tcl_TranslateFileName call).  Additional
				 * arguments have not been converted. */
    TclFile inputFile;		/* If non-NULL, gives the file to use as
				 * input for the child process.  If inputFile
				 * file is not readable or is NULL, the child
				 * will receive no standard input. */
    TclFile outputFile;		/* If non-NULL, gives the file that
				 * receives output from the child process.  If
				 * outputFile file is not writeable or is
				 * NULL, output from the child will be
				 * discarded. */
    TclFile errorFile;		/* If non-NULL, gives the file that
				 * receives errors from the child process.  If
				 * errorFile file is not writeable or is NULL,
				 * errors from the child will be discarded.
				 * errorFile may be the same as outputFile. */
    Tcl_Pid *pidPtr;		/* If this procedure is successful, pidPtr
				 * is filled with the process id of the child
				 * process. */
{
    TclFile errPipeIn, errPipeOut;
    int joinThisError, count, status, fd;
    char errSpace[200];
    int pid;
    
    errPipeIn = NULL;
    errPipeOut = NULL;
    pid = -1;

    /*
     * Create a pipe that the child can use to return error
     * information if anything goes wrong.
     */

    if (TclpCreatePipe(&errPipeIn, &errPipeOut) == 0) {
	Tcl_AppendResult(interp, "couldn't create pipe: ",
		Tcl_PosixError(interp), (char *) NULL);
	goto error;
    }

    joinThisError = (errorFile == outputFile);
    pid = vfork();
    if (pid == 0) {




	fd = GetFd(errPipeOut);

	/*
	 * Set up stdio file handles for the child process.
	 */

	if (!SetupStdFile(inputFile, TCL_STDIN)







|












|






|











|
|
|
|
|




















|




















>
>
>
>







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
    }
    
    Tcl_DeleteFileHandler(fd);
    return close(fd);
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpCreateProcess --
 *
 *	Create a child process that has the specified files as its 
 *	standard input, output, and error.  The child process runs
 *	asynchronously and runs with the same environment variables
 *	as the creating process.
 *
 *	The path is searched to find the specified executable.  
 *
 * Results:
 *	The return value is TCL_ERROR and an error message is left in
 *	the interp's result if there was a problem creating the child 
 *	process.  Otherwise, the return value is TCL_OK and *pidPtr is
 *	filled with the process id of the child process.
 * 
 * Side effects:
 *	A process is created.
 *	
 *---------------------------------------------------------------------------
 */

    /* ARGSUSED */
int
TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile, 
	pidPtr)
    Tcl_Interp *interp;		/* Interpreter in which to leave errors that
				 * occurred when creating the child process.
				 * Error messages from the child process
				 * itself are sent to errorFile. */
    int argc;			/* Number of arguments in following array. */
    char **argv;		/* Array of argument strings in UTF-8.
				 * argv[0] contains the name of the executable
				 * translated using Tcl_TranslateFileName
				 * call).  Additional arguments have not been
				 * converted. */
    TclFile inputFile;		/* If non-NULL, gives the file to use as
				 * input for the child process.  If inputFile
				 * file is not readable or is NULL, the child
				 * will receive no standard input. */
    TclFile outputFile;		/* If non-NULL, gives the file that
				 * receives output from the child process.  If
				 * outputFile file is not writeable or is
				 * NULL, output from the child will be
				 * discarded. */
    TclFile errorFile;		/* If non-NULL, gives the file that
				 * receives errors from the child process.  If
				 * errorFile file is not writeable or is NULL,
				 * errors from the child will be discarded.
				 * errorFile may be the same as outputFile. */
    Tcl_Pid *pidPtr;		/* If this procedure is successful, pidPtr
				 * is filled with the process id of the child
				 * process. */
{
    TclFile errPipeIn, errPipeOut;
    int joinThisError, count, status, fd;
    char errSpace[200 + TCL_INTEGER_SPACE];
    int pid;
    
    errPipeIn = NULL;
    errPipeOut = NULL;
    pid = -1;

    /*
     * Create a pipe that the child can use to return error
     * information if anything goes wrong.
     */

    if (TclpCreatePipe(&errPipeIn, &errPipeOut) == 0) {
	Tcl_AppendResult(interp, "couldn't create pipe: ",
		Tcl_PosixError(interp), (char *) NULL);
	goto error;
    }

    joinThisError = (errorFile == outputFile);
    pid = vfork();
    if (pid == 0) {
	Tcl_DString *dsArray;
	char *oldArgv0;
	int i;

	fd = GetFd(errPipeOut);

	/*
	 * Set up stdio file handles for the child process.
	 */

	if (!SetupStdFile(inputFile, TCL_STDIN)
377
378
379
380
381
382
383










384
385
386
387
388
389
390
391
392
393
	}

	/*
	 * Close the input side of the error pipe.
	 */

	RestoreSignals();










	execvp(argv[0], &argv[0]);
	sprintf(errSpace, "%dcouldn't execute \"%.150s\": ", errno,
		argv[0]);
	write(fd, errSpace, (size_t) strlen(errSpace));
	_exit(1);
    }
    if (pid == -1) {
	Tcl_AppendResult(interp, "couldn't fork child process: ",
		Tcl_PosixError(interp), (char *) NULL);
	goto error;







>
>
>
>
>
>
>
>
>
>
|

|







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
	}

	/*
	 * Close the input side of the error pipe.
	 */

	RestoreSignals();
	for (i = 0; argv[i] != NULL; i++) {
	    /*
	     * How many arguments?
	     */
	}
	oldArgv0 = argv[0];
	dsArray = (Tcl_DString *) ckalloc(i * sizeof(Tcl_DString));
	for (i = 0; argv[i] != NULL; i++) {
	    argv[i] = Tcl_UtfToExternalDString(NULL, argv[i], -1, &dsArray[i]);
	}
	execvp(argv[0], argv);				/* INTL: Native. */
	sprintf(errSpace, "%dcouldn't execute \"%.150s\": ", errno,
		oldArgv0);
	write(fd, errSpace, (size_t) strlen(errSpace));
	_exit(1);
    }
    if (pid == -1) {
	Tcl_AppendResult(interp, "couldn't fork child process: ",
		Tcl_PosixError(interp), (char *) NULL);
	goto error;
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
				 * can be read. */
    int numPids;		/* The number of pids in the pid array. */
    Tcl_Pid *pidPtr;		/* An array of process identifiers.
                                 * Allocated by the caller, freed when
                                 * the channel is closed or the processes
                                 * are detached (in a background exec). */
{
    char channelName[20];
    int channelId;
    PipeState *statePtr = (PipeState *) ckalloc((unsigned) sizeof(PipeState));
    int mode;

    statePtr->inFile = readFile;
    statePtr->outFile = writeFile;
    statePtr->errorFile = errorFile;







|







627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
				 * can be read. */
    int numPids;		/* The number of pids in the pid array. */
    Tcl_Pid *pidPtr;		/* An array of process identifiers.
                                 * Allocated by the caller, freed when
                                 * the channel is closed or the processes
                                 * are detached (in a background exec). */
{
    char channelName[16 + TCL_INTEGER_SPACE];
    int channelId;
    PipeState *statePtr = (PipeState *) ckalloc((unsigned) sizeof(PipeState));
    int mode;

    statePtr->inFile = readFile;
    statePtr->outFile = writeFile;
    statePtr->errorFile = errorFile;
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
 *----------------------------------------------------------------------
 *
 * TclGetAndDetachPids --
 *
 *	This procedure is invoked in the generic implementation of a
 *	background "exec" (An exec when invoked with a terminating "&")
 *	to store a list of the PIDs for processes in a command pipeline
 *	in interp->result and to detach the processes.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Modifies interp->result. Detaches processes.
 *
 *----------------------------------------------------------------------
 */

void
TclGetAndDetachPids(interp, chan)
    Tcl_Interp *interp;
    Tcl_Channel chan;
{
    PipeState *pipePtr;
    Tcl_ChannelType *chanTypePtr;
    int i;
    char buf[20];

    /*
     * Punt if the channel is not a command channel.
     */

    chanTypePtr = Tcl_GetChannelType(chan);
    if (chanTypePtr != &pipeChannelType) {
        return;
    }

    pipePtr = (PipeState *) Tcl_GetChannelInstanceData(chan);
    for (i = 0; i < pipePtr->numPids; i++) {
        sprintf(buf, "%ld", TclpGetPid(pipePtr->pidPtr[i]));
        Tcl_AppendElement(interp, buf);
        Tcl_DetachPids(1, &(pipePtr->pidPtr[i]));
    }
    if (pipePtr->numPids > 0) {
        ckfree((char *) pipePtr->pidPtr);
        pipePtr->numPids = 0;
    }







|





|












|












|







682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
 *----------------------------------------------------------------------
 *
 * TclGetAndDetachPids --
 *
 *	This procedure is invoked in the generic implementation of a
 *	background "exec" (An exec when invoked with a terminating "&")
 *	to store a list of the PIDs for processes in a command pipeline
 *	in the interp's result and to detach the processes.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Modifies the interp's result. Detaches processes.
 *
 *----------------------------------------------------------------------
 */

void
TclGetAndDetachPids(interp, chan)
    Tcl_Interp *interp;
    Tcl_Channel chan;
{
    PipeState *pipePtr;
    Tcl_ChannelType *chanTypePtr;
    int i;
    char buf[TCL_INTEGER_SPACE];

    /*
     * Punt if the channel is not a command channel.
     */

    chanTypePtr = Tcl_GetChannelType(chan);
    if (chanTypePtr != &pipeChannelType) {
        return;
    }

    pipePtr = (PipeState *) Tcl_GetChannelInstanceData(chan);
    for (i = 0; i < pipePtr->numPids; i++) {
        TclFormatInt(buf, (long) TclpGetPid(pipePtr->pidPtr[i]));
        Tcl_AppendElement(interp, buf);
        Tcl_DetachPids(1, &(pipePtr->pidPtr[i]));
    }
    if (pipePtr->numPids > 0) {
        ckfree((char *) pipePtr->pidPtr);
        pipePtr->numPids = 0;
    }
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "?channelId?");
	return TCL_ERROR;
    }
    if (objc == 1) {
	Tcl_SetLongObj(Tcl_GetObjResult(interp), (long) getpid());
    } else {
        chan = Tcl_GetChannel(interp, Tcl_GetStringFromObj(objv[1], NULL),
		NULL);
        if (chan == (Tcl_Channel) NULL) {
	    return TCL_ERROR;
	}
	chanTypePtr = Tcl_GetChannelType(chan);
	if (chanTypePtr != &pipeChannelType) {
	    return TCL_OK;
	}







|
<







1135
1136
1137
1138
1139
1140
1141
1142

1143
1144
1145
1146
1147
1148
1149
    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "?channelId?");
	return TCL_ERROR;
    }
    if (objc == 1) {
	Tcl_SetLongObj(Tcl_GetObjResult(interp), (long) getpid());
    } else {
        chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), NULL);

        if (chan == (Tcl_Channel) NULL) {
	    return TCL_ERROR;
	}
	chanTypePtr = Tcl_GetChannelType(chan);
	if (chanTypePtr != &pipeChannelType) {
	    return TCL_OK;
	}

Changes to unix/tclUnixPort.h.

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
 *	core files.  This file depends on configuration #defines such
 *	as NO_DIRENT_H that are set up by the "configure" script.
 *
 *	Much of the material in this file was originally contributed
 *	by Karl Lehenbauer, Mark Diekhans and Peter da Silva.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclUnixPort.h 1.49 97/07/30 14:11:59
 */

#ifndef _TCLUNIXPORT
#define _TCLUNIXPORT

#ifndef _TCLINT
#   include "tclInt.h"
#endif








#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_NET_ERRNO_H
#   include <net/errno.h>
#endif
#include <pwd.h>
#include <signal.h>

#include <sys/param.h>

#include <sys/types.h>
#ifdef USE_DIRENT2_H
#   include "../compat/dirent2.h"
#else
#   ifdef NO_DIRENT_H
#	include "../compat/dirent.h"
#   else
#	include <dirent.h>
#   endif
#endif
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
#   include <sys/select.h>
#endif
#include <sys/stat.h>
#if TIME_WITH_SYS_TIME
#   include <sys/time.h>
#   include <time.h>
#else
#   if HAVE_SYS_TIME_H
#       include <sys/time.h>
#   else
#       include <time.h>
#   endif
#endif
#ifndef NO_SYS_WAIT_H
#   include <sys/wait.h>
#endif
#ifdef HAVE_UNISTD_H
#   include <unistd.h>
#else
#   include "../compat/unistd.h"
#endif
#ifdef	USE_FIONBIO

    /*
     * Not using the Posix fcntl(...,O_NONBLOCK,...) interface, instead
     * we are using ioctl(..,FIONBIO,..).
     */

#   ifdef HAVE_SYS_FILIO_H
#	include	<sys/filio.h>	/* For FIONBIO. */







|




|








>
>
>
>
>
>
>
>







>
|
>




|
|
|
|
|










|
|
|
|
|










<







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
 *	core files.  This file depends on configuration #defines such
 *	as NO_DIRENT_H that are set up by the "configure" script.
 *
 *	Much of the material in this file was originally contributed
 *	by Karl Lehenbauer, Mark Diekhans and Peter da Silva.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * 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: tclUnixPort.h,v 1.1.2.8 1999/04/06 02:05:38 stanton Exp $
 */

#ifndef _TCLUNIXPORT
#define _TCLUNIXPORT

#ifndef _TCLINT
#   include "tclInt.h"
#endif

/*
 *---------------------------------------------------------------------------
 * The following sets of #includes and #ifdefs are required to get Tcl to
 * compile under the various flavors of unix.
 *---------------------------------------------------------------------------
 */

#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_NET_ERRNO_H
#   include <net/errno.h>
#endif
#include <pwd.h>
#include <signal.h>
#ifdef HAVE_SYS_PARAM_H
#   include <sys/param.h>
#endif
#include <sys/types.h>
#ifdef USE_DIRENT2_H
#   include "../compat/dirent2.h"
#else
#ifdef NO_DIRENT_H
#   include "../compat/dirent.h"
#else
#   include <dirent.h>
#endif
#endif
#include <sys/file.h>
#ifdef HAVE_SYS_SELECT_H
#   include <sys/select.h>
#endif
#include <sys/stat.h>
#if TIME_WITH_SYS_TIME
#   include <sys/time.h>
#   include <time.h>
#else
#if HAVE_SYS_TIME_H
#   include <sys/time.h>
#else
#   include <time.h>
#endif
#endif
#ifndef NO_SYS_WAIT_H
#   include <sys/wait.h>
#endif
#ifdef HAVE_UNISTD_H
#   include <unistd.h>
#else
#   include "../compat/unistd.h"
#endif
#ifdef	USE_FIONBIO

    /*
     * Not using the Posix fcntl(...,O_NONBLOCK,...) interface, instead
     * we are using ioctl(..,FIONBIO,..).
     */

#   ifdef HAVE_SYS_FILIO_H
#	include	<sys/filio.h>	/* For FIONBIO. */
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * Some platforms (e.g. SunOS) don't define FLT_MAX and FLT_MIN, so we
 * look for an alternative definition.  If no other alternative is available
 * we use a reasonable guess.
 */

#ifndef NO_FLOAT_H
#include <float.h>
#else
#   ifndef NO_VALUES_H
#	include <values.h>
#   endif
#endif

#ifndef FLT_MAX
#   ifdef MAXFLOAT
#	define FLT_MAX MAXFLOAT
#   else
#	define FLT_MAX 3.402823466E+38F







|

|
|
|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * Some platforms (e.g. SunOS) don't define FLT_MAX and FLT_MIN, so we
 * look for an alternative definition.  If no other alternative is available
 * we use a reasonable guess.
 */

#ifndef NO_FLOAT_H
#   include <float.h>
#else
#ifndef NO_VALUES_H
#   include <values.h>
#endif
#endif

#ifndef FLT_MAX
#   ifdef MAXFLOAT
#	define FLT_MAX MAXFLOAT
#   else
#	define FLT_MAX 3.402823466E+38F
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

#ifdef HPUX
#  define NBIO_FLAG O_NONBLOCK
#else
#  define NBIO_FLAG O_NDELAY
#endif

/*
 * The following defines denote malloc and free as the system calls
 * used to allocate new memory.  These defines are only used in the
 * file tclCkalloc.c.
 */

#define TclpAlloc(size)		malloc(size)
#define TclpFree(ptr)		free(ptr)
#define TclpRealloc(ptr, size)	realloc(ptr, size)

/*
 * The default platform eol translation on Unix is TCL_TRANSLATE_LF:
 */

#define	TCL_PLATFORM_TRANSLATION	TCL_TRANSLATE_LF

/*
 * Not all systems declare the errno variable in errno.h. so this
 * file does it explicitly.  The list of system error messages also
 * isn't generally declared in a header file anywhere.
 */

extern int errno;

/*
 * The type of the status returned by wait varies from UNIX system
 * to UNIX system.  The macro below defines it:
 */

#ifdef _AIX
#   define WAIT_STATUS_TYPE pid_t







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







152
153
154
155
156
157
158
























159
160
161
162
163
164
165

#ifdef HPUX
#  define NBIO_FLAG O_NONBLOCK
#else
#  define NBIO_FLAG O_NDELAY
#endif

























/*
 * The type of the status returned by wait varies from UNIX system
 * to UNIX system.  The macro below defines it:
 */

#ifdef _AIX
#   define WAIT_STATUS_TYPE pid_t
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
 * Supply macros for seek offsets, if they're not already provided by
 * an include file.
 */

#ifndef SEEK_SET
#   define SEEK_SET 0
#endif

#ifndef SEEK_CUR
#   define SEEK_CUR 1
#endif

#ifndef SEEK_END
#   define SEEK_END 2
#endif

/*
 * The stuff below is needed by the "time" command.  If this
 * system has no gettimeofday call, then must use times and the
 * CLK_TCK #define (from sys/param.h) to compute elapsed time.
 * Unfortunately, some systems only have HZ and no CLK_TCK, and
 * some might not even have HZ.
 */

#ifdef NO_GETTOD
#   include <sys/times.h>
#   include <sys/param.h>
#   ifndef CLK_TCK
#       ifdef HZ







<



<





|
|
|
<
|







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
 * Supply macros for seek offsets, if they're not already provided by
 * an include file.
 */

#ifndef SEEK_SET
#   define SEEK_SET 0
#endif

#ifndef SEEK_CUR
#   define SEEK_CUR 1
#endif

#ifndef SEEK_END
#   define SEEK_END 2
#endif

/*
 * The stuff below is needed by the "time" command.  If this system has no
 * gettimeofday call, then must use times and the CLK_TCK #define (from
 * sys/param.h) to compute elapsed time.  Unfortunately, some systems only

 * have HZ and no CLK_TCK, and some might not even have HZ.
 */

#ifdef NO_GETTOD
#   include <sys/times.h>
#   include <sys/param.h>
#   ifndef CLK_TCK
#       ifdef HZ
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

/*
 * On systems without symbolic links (i.e. S_IFLNK isn't defined)
 * define "lstat" to use "stat" instead.
 */

#ifndef S_IFLNK
#   define lstat stat
#endif

/*
 * Define macros to query file type bits, if they're not already
 * defined.
 */








|







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

/*
 * On systems without symbolic links (i.e. S_IFLNK isn't defined)
 * define "lstat" to use "stat" instead.
 */

#ifndef S_IFLNK
#   define lstat	stat
#endif

/*
 * Define macros to query file type bits, if they're not already
 * defined.
 */

425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462

463




464


465
466

467




468

469

470





471
472









473
474




475
476



477








478


479
480
#endif
#ifndef NFDBITS
#   define NFDBITS NBBY*sizeof(fd_mask)
#endif
#define MASK_SIZE howmany(FD_SETSIZE, NFDBITS)

/*
 * The following implements the Unix method for exiting the process.
 */
#define TclPlatformExit(status) exit(status)

/*
 * The following functions always succeeds under Unix.
 */

#define TclHasSockets(interp) (TCL_OK)
#define TclHasPipes() (1)

/*
 * Variables provided by the C library:
 */

#if defined(_sgi) || defined(__sgi)
#define environ _environ
#endif
extern char **environ;

/*
 * At present (12/91) not all stdlib.h implementations declare strtod.
 * The declaration below is here to ensure that it's declared, so that
 * the compiler won't take the default approach of assuming it returns
 * an int.  There's no ANSI prototype for it because there would end
 * up being too many conflicts with slightly-different prototypes.
 */

extern double strtod();

/*

 * The following macros define time related functions in terms of




 * standard Unix routines.


 */


#define TclpGetDate(t,u) ((u) ? gmtime((t)) : localtime((t)))




#define TclStrftime(s,m,f,t) (strftime((s),(m),(f),(t)))

#define TclpGetPid(pid)	    ((unsigned long) (pid))







#define TclpReleaseFile(file)	










/*
 * The following routine is only exported for testing purposes.




 */




EXTERN int	TclUnixWaitForFile _ANSI_ARGS_((int fd, int mask,








		    int timeout));



#endif /* _TCLUNIXPORT */







|
|
<
|
<
<


|
<






|














>
|
>
>
>
>
|
>
>


>
|
>
>
>
>
|
>
|
>

>
>
>
>
>
|

>
>
>
>
>
>
>
>
>

<
>
>
>
>


>
>
>
|
>
>
>
>
>
>
>
>
|
>
>


407
408
409
410
411
412
413
414
415

416


417
418
419

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
#endif
#ifndef NFDBITS
#   define NFDBITS NBBY*sizeof(fd_mask)
#endif
#define MASK_SIZE howmany(FD_SETSIZE, NFDBITS)

/*
 * Not all systems declare the errno variable in errno.h. so this
 * file does it explicitly.  The list of system error messages also

 * isn't generally declared in a header file anywhere.


 */

extern int errno;


/*
 * Variables provided by the C library:
 */

#if defined(_sgi) || defined(__sgi)
#   define environ _environ
#endif
extern char **environ;

/*
 * At present (12/91) not all stdlib.h implementations declare strtod.
 * The declaration below is here to ensure that it's declared, so that
 * the compiler won't take the default approach of assuming it returns
 * an int.  There's no ANSI prototype for it because there would end
 * up being too many conflicts with slightly-different prototypes.
 */

extern double strtod();

/*
 *---------------------------------------------------------------------------
 * The following macros and declarations represent the interface between 
 * generic and unix-specific parts of Tcl.  Some of the macros may override 
 * functions declared in tclInt.h.
 *---------------------------------------------------------------------------
 */

/*
 * The default platform eol translation on Unix is TCL_TRANSLATE_LF.
 */

#define	TCL_PLATFORM_TRANSLATION	TCL_TRANSLATE_LF

/*
 * The following macros have trivial definitions, allowing generic code to 
 * address platform-specific issues.
 */

#define TclpAsyncMark(async)
#define TclpGetPid(pid)		((unsigned long) (pid))
#define TclpReleaseFile(file)	/* Nothing. */

/*
 * The following macros and declaration wrap the C runtime library
 * functions.
 */

#define TclpExit		exit

#ifdef TclpStat
#undef TclpStat
#endif

EXTERN int		TclpLstat _ANSI_ARGS_((CONST char *path, 
			    struct stat *buf));
EXTERN int		TclpStat _ANSI_ARGS_((CONST char *path, 
			    struct stat *buf));

/*

 * Platform specific mutex definition used by memory allocators.
 * These mutexes are statically allocated and explicitly initialized.
 * Most modules do not use this, but instead use Tcl_Mutex types and
 * Tcl_MutexLock and Tcl_MutexUnlock that are self-initializing.
 */

#ifdef TCL_THREADS
#include <pthread.h>
typedef pthread_mutex_t TclpMutex;
EXTERN void	TclpMutexInit _ANSI_ARGS_((TclpMutex *mPtr));
EXTERN void	TclpMutexLock _ANSI_ARGS_((TclpMutex *mPtr));
EXTERN void	TclpMutexUnlock _ANSI_ARGS_((TclpMutex *mPtr));
#else
typedef int TclpMutex;
#define	TclpMutexInit(a)
#define	TclpMutexLock(a)
#define	TclpMutexUnlock(a)
#endif /* TCL_THREADS */

#include "tclPlatDecls.h"
#include "tclIntPlatDecls.h"

#endif /* _TCLUNIXPORT */

Changes to unix/tclUnixSock.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclUnixSock.c --
 *
 *	This file contains Unix-specific socket related code.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclUnixSock.c 1.9 97/10/09 18:24:49
 */

#include "tcl.h"
#include "tclPort.h"

/*
 * There is no portable macro for the maximum length










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclUnixSock.c --
 *
 *	This file contains Unix-specific socket related code.
 *
 * Copyright (c) 1995 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: tclUnixSock.c,v 1.1.2.7 1999/03/25 23:27:49 stanton Exp $
 */

#include "tcl.h"
#include "tclPort.h"

/*
 * There is no portable macro for the maximum length
37
38
39
40
41
42
43


44
45
46
47
48
49
50

/*
 * The following variable holds the network name of this host.
 */

static char hostname[TCL_HOSTNAME_LEN + 1];
static int  hostnameInited = 0;



/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetHostName --
 *
 *	Returns the name of the local host.







>
>







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

/*
 * The following variable holds the network name of this host.
 */

static char hostname[TCL_HOSTNAME_LEN + 1];
static int  hostnameInited = 0;
TCL_DECLARE_MUTEX(hostMutex)


/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetHostName --
 *
 *	Returns the name of the local host.
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
























char *
Tcl_GetHostName()
{
#ifndef NO_UNAME
    struct utsname u;
    struct hostent *hp;


#endif



    if (hostnameInited) {

        return hostname;
    }


#ifndef NO_UNAME
    (VOID *) memset((VOID *) &u, (int) 0, sizeof(struct utsname));
    if (uname(&u) > -1) {
        hp = gethostbyname(u.nodename);
        if (hp != NULL) {
            strcpy(hostname, hp->h_name);
        } else {
            strcpy(hostname, u.nodename);
        }
        hostnameInited = 1;
        return hostname;
    }
#else
    /*
     * Uname doesn't exist; try gethostname instead.
     */

    if (gethostname(hostname, sizeof(hostname)) > -1) {
	hostnameInited = 1;
        return hostname;
    }
#endif


    hostname[0] = 0;






    return hostname;
}






























>
>

>

>

>



>


|
|

|

|

<
<






|
|
<



>
|
>
>
>
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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

char *
Tcl_GetHostName()
{
#ifndef NO_UNAME
    struct utsname u;
    struct hostent *hp;
#else
    char buffer[sizeof(hostname)];
#endif
    CONST char *native;

    Tcl_MutexLock(&hostMutex);
    if (hostnameInited) {
	Tcl_MutexUnlock(&hostMutex);
        return hostname;
    }

    native = NULL;
#ifndef NO_UNAME
    (VOID *) memset((VOID *) &u, (int) 0, sizeof(struct utsname));
    if (uname(&u) > -1) {				/* INTL: Native. */
        hp = gethostbyname(u.nodename);			/* INTL: Native. */
        if (hp != NULL) {
	    native = hp->h_name;
        } else {
	    native = u.nodename;
        }


    }
#else
    /*
     * Uname doesn't exist; try gethostname instead.
     */

    if (gethostname(buffer, sizeof(buffer)) > -1) {	/* INTL: Native. */
	native = buffer;

    }
#endif

    if (native == NULL) {
	hostname[0] = 0;
    } else {
	Tcl_ExternalToUtf(NULL, NULL, native, -1, 0, NULL, hostname,
		sizeof(hostname), NULL, NULL, NULL);
    }
    hostnameInited = 1;
    Tcl_MutexUnlock(&hostMutex);
    return hostname;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpHasSockets --
 *
 *	Detect if sockets are available on this platform.
 *
 * Results:
 *	Returns TCL_OK.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclpHasSockets(interp)
    Tcl_Interp *interp;		/* Not used. */
{
    return TCL_OK;
}

Changes to unix/tclUnixTest.c.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16








17
18
19
20
21
22
23
/* 
 * tclUnixTest.c --
 *
 *	Contains platform specific test commands for the Unix platform.
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.

 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclUnixTest.c 1.5 97/10/31 17:23:42
 */

#include "tclInt.h"
#include "tclPort.h"









/*
 * The following macros convert between TclFile's and fd's.  The conversion
 * simple involves shifting fd's up by one to ensure that no valid fd is ever
 * the same as NULL.  Note that this code is duplicated from tclUnixPipe.c
 */

#define MakeFile(fd) ((TclFile)((fd)+1))





|
>




|





>
>
>
>
>
>
>
>







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
/* 
 * tclUnixTest.c --
 *
 *	Contains platform specific test commands for the Unix platform.
 *
 * Copyright (c) 1996-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: tclUnixTest.c,v 1.1.2.4 1999/03/12 23:29:21 surles Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * The headers are needed for the testalarm command that verifies the
 * use of SA_RESTART in signal handlers.
 */

#include <signal.h>
#include <sys/resource.h>

/*
 * The following macros convert between TclFile's and fd's.  The conversion
 * simple involves shifting fd's up by one to ensure that no valid fd is ever
 * the same as NULL.  Note that this code is duplicated from tclUnixPipe.c
 */

#define MakeFile(fd) ((TclFile)((fd)+1))
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
				 * this file has triggered and the file
				 * was writable. */
} Pipe;

#define MAX_PIPES 10
static Pipe testPipes[MAX_PIPES];







/*
 * Forward declarations of procedures defined later in this file:
 */

static void		TestFileHandlerProc _ANSI_ARGS_((ClientData clientData,
			    int mask));
static int		TestfilehandlerCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestfilewaitCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));


static int		TestgetopenfileCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));




int			TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));






/*
 *----------------------------------------------------------------------
 *
 * TclplatformtestInit --
 *
 *	Defines commands that test platform specific functionality for







>
>
>
>
>
>










>
>


>
>
>
>

>
>
>
>
>







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
				 * this file has triggered and the file
				 * was writable. */
} Pipe;

#define MAX_PIPES 10
static Pipe testPipes[MAX_PIPES];

/*
 * The stuff below is used by the testalarm and testgotsig ommands.
 */

static char *gotsig = "0";

/*
 * Forward declarations of procedures defined later in this file:
 */

static void		TestFileHandlerProc _ANSI_ARGS_((ClientData clientData,
			    int mask));
static int		TestfilehandlerCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestfilewaitCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestfindexecutableCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestgetopenfileCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestgetdefencdirCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestsetdefencdirCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
int			TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
static int		TestalarmCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static int		TestgotsigCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));
static void 		AlarmHandler _ANSI_ARGS_(());

/*
 *----------------------------------------------------------------------
 *
 * TclplatformtestInit --
 *
 *	Defines commands that test platform specific functionality for
79
80
81
82
83
84
85


86








87
88
89
90
91
92
93
TclplatformtestInit(interp)
    Tcl_Interp *interp;		/* Interpreter to add commands to. */
{
    Tcl_CreateCommand(interp, "testfilehandler", TestfilehandlerCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testfilewait", TestfilewaitCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);


    Tcl_CreateCommand(interp, "testgetopenfile", TestgetopenfileCmd,








            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







>
>

>
>
>
>
>
>
>
>







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
TclplatformtestInit(interp)
    Tcl_Interp *interp;		/* Interpreter to add commands to. */
{
    Tcl_CreateCommand(interp, "testfilehandler", TestfilehandlerCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testfilewait", TestfilewaitCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testfindexecutable", TestfindexecutableCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testgetopenfile", TestgetopenfileCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testgetdefenc", TestgetdefencdirCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testsetdefenc", TestsetdefencdirCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testalarm", TestalarmCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    Tcl_CreateCommand(interp, "testgotsig", TestgotsigCmd,
            (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: should be \"",
                    argv[0], " clear index\"", (char *) NULL);
	    return TCL_ERROR;
	}
	pipePtr->readCount = pipePtr->writeCount = 0;
    } else if (strcmp(argv[1], "counts") == 0) {
	char buf[30];
	
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: should be \"",
                    argv[0], " counts index\"", (char *) NULL);
	    return TCL_ERROR;
	}
	sprintf(buf, "%d %d", pipePtr->readCount, pipePtr->writeCount);







|







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: should be \"",
                    argv[0], " clear index\"", (char *) NULL);
	    return TCL_ERROR;
	}
	pipePtr->readCount = pipePtr->writeCount = 0;
    } else if (strcmp(argv[1], "counts") == 0) {
	char buf[TCL_INTEGER_SPACE * 2];
	
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: should be \"",
                    argv[0], " counts index\"", (char *) NULL);
	    return TCL_ERROR;
	}
	sprintf(buf, "%d %d", pipePtr->readCount, pipePtr->writeCount);
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
	}

	memset((VOID *) buffer, 'a', 4000);
        while (write(GetFd(pipePtr->writeFile), buffer, 4000) > 0) {
            /* Empty loop body. */
        }
    } else if (strcmp(argv[1], "fillpartial") == 0) {
	char buf[30];
	
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: should be \"",
                    argv[0], " empty index\"", (char *) NULL);
	    return TCL_ERROR;
	}

	memset((VOID *) buffer, 'b', 10);
	sprintf(buf, "%d", write(GetFd(pipePtr->writeFile), buffer, 10));
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else if (strcmp(argv[1], "oneevent") == 0) {
	Tcl_DoOneEvent(TCL_FILE_EVENTS|TCL_DONT_WAIT);
    } else if (strcmp(argv[1], "wait") == 0) {
	if (argc != 5) {
	    Tcl_AppendResult(interp, "wrong # arguments: should be \"",
                    argv[0], " wait index readable/writable timeout\"",







|








|







279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
	}

	memset((VOID *) buffer, 'a', 4000);
        while (write(GetFd(pipePtr->writeFile), buffer, 4000) > 0) {
            /* Empty loop body. */
        }
    } else if (strcmp(argv[1], "fillpartial") == 0) {
	char buf[TCL_INTEGER_SPACE];
	
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: should be \"",
                    argv[0], " empty index\"", (char *) NULL);
	    return TCL_ERROR;
	}

	memset((VOID *) buffer, 'b', 10);
	TclFormatInt(buf, write(GetFd(pipePtr->writeFile), buffer, 10));
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else if (strcmp(argv[1], "oneevent") == 0) {
	Tcl_DoOneEvent(TCL_FILE_EVENTS|TCL_DONT_WAIT);
    } else if (strcmp(argv[1], "wait") == 0) {
	if (argc != 5) {
	    Tcl_AppendResult(interp, "wrong # arguments: should be \"",
                    argv[0], " wait index readable/writable timeout\"",
384
385
386
387
388
389
390



















































391
392
393
394
395
396
397
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *



















































 * TestgetopenfileCmd --
 *
 *	This procedure implements the "testgetopenfile" command. It is
 *	used to get a FILE * value from a registered channel.
 *
 * Results:
 *	A standard Tcl result.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestfindexecutableCmd --
 *
 *	This procedure implements the "testfindexecutable" command. It is
 *	used to test Tcl_FindExecutable.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestfindexecutableCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    char *oldName;
    char *oldNativeName;

    if (argc != 2) {
	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
		" argv0\"", (char *) NULL);
	return TCL_ERROR;
    }

    oldName       = tclExecutableName;
    oldNativeName = tclNativeExecutableName;

    tclExecutableName       = NULL;
    tclNativeExecutableName = NULL;

    Tcl_FindExecutable(argv[1]);
    if (tclExecutableName != NULL) {
	Tcl_SetResult(interp, tclExecutableName, TCL_VOLATILE);
	ckfree(tclExecutableName);
    }

    tclExecutableName       = oldName;
    tclNativeExecutableName = oldNativeName;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestgetopenfileCmd --
 *
 *	This procedure implements the "testgetopenfile" command. It is
 *	used to get a FILE * value from a registered channel.
 *
 * Results:
 *	A standard Tcl result.
425
426
427
428
429
430
431



























































































































































































    if (filePtr == (ClientData) NULL) {
        Tcl_AppendResult(interp,
                "Tcl_GetOpenFile succeeded but FILE * NULL!", (char *) NULL);
        return TCL_ERROR;
    }
    return TCL_OK;
}


































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
    if (filePtr == (ClientData) NULL) {
        Tcl_AppendResult(interp,
                "Tcl_GetOpenFile succeeded but FILE * NULL!", (char *) NULL);
        return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestsetdefencdirCmd --
 *
 *	This procedure implements the "testsetdefenc" command. It is
 *	used to set the value of tclDefaultEncodingDir.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestsetdefencdirCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    if (argc != 2) {
        Tcl_AppendResult(interp,
                "wrong # args: should be \"", argv[0],
                " defaultDir\"",
                (char *) NULL);
        return TCL_ERROR;
    }

    if (tclDefaultEncodingDir != NULL) {
	ckfree(tclDefaultEncodingDir);
	tclDefaultEncodingDir = NULL;
    }
    if (*argv[1] != '\0') {
	tclDefaultEncodingDir = (char *)
	    ckalloc((unsigned) strlen(argv[1]) + 1);
	strcpy(tclDefaultEncodingDir, argv[1]);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TestgetdefencdirCmd --
 *
 *	This procedure implements the "testgetdefenc" command. It is
 *	used to get the value of tclDefaultEncodingDir.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestgetdefencdirCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    if (argc != 1) {
        Tcl_AppendResult(interp,
                "wrong # args: should be \"", argv[0],
                (char *) NULL);
        return TCL_ERROR;
    }

    if (tclDefaultEncodingDir != NULL) {
        Tcl_AppendResult(interp, tclDefaultEncodingDir, (char *) NULL);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 * TestalarmCmd --
 *
 *	Test that EINTR is handled correctly by generating and
 *	handling a signal.  This requires using the SA_RESTART
 *	flag when registering the signal handler.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Sets up an signal and async handlers.
 *
 *----------------------------------------------------------------------
 */

static int
TestalarmCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
#ifdef SA_RESTART
    unsigned int sec;
    struct sigaction action;

    if (argc > 1) {
	Tcl_GetInt(interp, argv[1], (int *)&sec);
    } else {
	sec = 1;
    }

    /*
     * Setup the signal handling that automatically retries
     * any interupted I/O system calls.
     */
    action.sa_handler = AlarmHandler;
    memset((void *)&action.sa_mask, 0, sizeof(sigset_t));
    action.sa_flags = SA_RESTART;

    if (sigaction(SIGALRM, &action, NULL) < 0) {
	Tcl_AppendResult(interp, "sigaction: ", Tcl_PosixError(interp), NULL);
	return TCL_ERROR;
    }
    if (alarm(sec) < 0) {
	Tcl_AppendResult(interp, "alarm: ", Tcl_PosixError(interp), NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
#else
    Tcl_AppendResult(interp, "warning: sigaction SA_RESTART not support on this platform", NULL);
    return TCL_ERROR;
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * AlarmHandler --
 *
 *	Signal handler for the alarm command.
 *
 * Results:
 *	None.
 *
 * Side effects:
 * 	Calls the Tcl Async handler.
 *
 *----------------------------------------------------------------------
 */

static void
AlarmHandler()
{
    gotsig = "1";
}

/*
 *----------------------------------------------------------------------
 * TestgotsigCmd --
 *
 * 	Verify the signal was handled after the testalarm command.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Resets the value of gotsig back to '0'.
 *
 *----------------------------------------------------------------------
 */

static int
TestgotsigCmd(clientData, interp, argc, argv)
    ClientData clientData;		/* Not used. */
    Tcl_Interp *interp;			/* Current interpreter. */
    int argc;				/* Number of arguments. */
    char **argv;			/* Argument strings. */
{
    Tcl_AppendResult(interp, gotsig, (char *) NULL);
    gotsig = "0";
    return TCL_OK;
}

Added unix/tclUnixThrd.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
/* 
 * tclUnixThrd.c --
 *
 *	This file implements the UNIX-specific thread support.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * 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.
 *
 * SCCS:  @(#) tclUnixThrd.c 1.18 98/02/19 14:24:12
 */

#include "tclInt.h"

#ifdef TCL_THREADS

#include "tclPort.h"
#include "pthread.h"

/*
 * masterLock is used to serialize creation of mutexes, condition
 * variables, and thread local storage.
 * This is the only place that can count on the ability to statically
 * initialize the mutex.
 */

static pthread_mutex_t masterLock = PTHREAD_MUTEX_INITIALIZER;

/*
 * initLock is used to serialize initialization and finalization
 * of Tcl.  It cannot use any dyamically allocated storage.
 */

static pthread_mutex_t initLock = PTHREAD_MUTEX_INITIALIZER;

/*
 * These are for the critical sections inside this file.
 */

#define MASTER_LOCK	pthread_mutex_lock(&masterLock)
#define MASTER_UNLOCK	pthread_mutex_unlock(&masterLock)

#endif /* TCL_THREADS */



#ifdef TCL_THREADS

/*
 *----------------------------------------------------------------------
 *
 * TclpThreadCreate --
 *
 *	This procedure creates a new thread.
 *
 * Results:
 *	TCL_OK if the thread could be created.  The thread ID is
 *	returned in a parameter.
 *
 * Side effects:
 *	A new thread is created.
 *
 *----------------------------------------------------------------------
 */

int
TclpThreadCreate(idPtr, proc, clientData)
    Tcl_ThreadId *idPtr;		/* Return, the ID of the thread */
    Tcl_ThreadCreateProc proc;		/* Main() function of the thread */
    ClientData clientData;		/* The one argument to Main() */
{
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
    if (pthread_create((pthread_t *)idPtr, &attr, (void * (*)())proc, (void *)clientData) < 0) {
	return TCL_ERROR;
    } else {
	return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpThreadExit --
 *
 *	This procedure terminates the current thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	This procedure terminates the current thread.
 *
 *----------------------------------------------------------------------
 */

void
TclpThreadExit(status)
    int status;
{
    pthread_exit((VOID *)status);
}
#endif /* TCL_THREADS */

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetCurrentThread --
 *
 *	This procedure returns the ID of the currently running thread.
 *
 * Results:
 *	A thread ID.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_ThreadId
Tcl_GetCurrentThread()
{
#ifdef TCL_THREADS
    return (Tcl_ThreadId) pthread_self();
#else
    return (Tcl_ThreadId) 0;
#endif
}


/*
 *----------------------------------------------------------------------
 *
 * TclpInitLock
 *
 *	This procedure is used to grab a lock that serializes initialization
 *	and finalization of Tcl.  On some platforms this may also initialize
 *	the mutex used to serialize creation of more mutexes and thread
 *	local storage keys.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Acquire the initialization mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpInitLock()
{
#ifdef TCL_THREADS
    pthread_mutex_lock(&initLock);
#endif
}


/*
 *----------------------------------------------------------------------
 *
 * TclpInitUnlock
 *
 *	This procedure is used to release a lock that serializes initialization
 *	and finalization of Tcl.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Release the initialization mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpInitUnlock()
{
#ifdef TCL_THREADS
    pthread_mutex_unlock(&initLock);
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * TclpMasterLock
 *
 *	This procedure is used to grab a lock that serializes creation
 *	and finalization of serialization objects.  This interface is
 *	only needed in finalization; it is hidden during
 *	creation of the objects.
 *
 *	This lock must be different than the initLock because the
 *	initLock is held during creation of syncronization objects.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Acquire the master mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpMasterLock()
{
#ifdef TCL_THREADS
    pthread_mutex_lock(&masterLock);
#endif
}


/*
 *----------------------------------------------------------------------
 *
 * TclpMasterUnlock
 *
 *	This procedure is used to release a lock that serializes creation
 *	and finalization of synchronization objects.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Release the master mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpMasterUnlock()
{
#ifdef TCL_THREADS
    pthread_mutex_unlock(&masterLock);
#endif
}

#ifdef TCL_THREADS

/*
 *----------------------------------------------------------------------
 *
 * TclpMutexInit --
 * TclpMutexLock --
 * TclpMutexUnlock --
 *
 *	These procedures use an explicitly initialized mutex.
 *	These are used by memory allocators for their own mutex.
 * 
 * Results:
 *	None.
 *
 * Side effects:
 *	Initialize, Lock, and Unlock the mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpMutexInit(mPtr)
    TclpMutex *mPtr;
{
    pthread_mutex_init((pthread_mutex_t *)mPtr, NULL);
}
void
TclpMutexLock(mPtr)
    TclpMutex *mPtr;
{
    pthread_mutex_lock((pthread_mutex_t *)mPtr);
}
void
TclpMutexUnlock(mPtr)
    TclpMutex *mPtr;
{
    pthread_mutex_unlock((pthread_mutex_t *)mPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_MutexLock --
 *
 *	This procedure is invoked to lock a mutex.  This procedure
 *	handles initializing the mutex, if necessary.  The caller
 *	can rely on the fact that Tcl_Mutex is an opaque pointer.
 *	This routine will change that pointer from NULL after first use.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May block the current thread.  The mutex is aquired when
 *	this returns.  Will allocate memory for a pthread_mutex_t
 *	and initialize this the first time this Tcl_Mutex is used.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_MutexLock(mutexPtr)
    Tcl_Mutex *mutexPtr;	/* Really (pthread_mutex_t **) */
{
    pthread_mutex_t *pmutexPtr;
    if (*mutexPtr == NULL) {
	MASTER_LOCK;
	if (*mutexPtr == NULL) {
	    /* 
	     * Double inside master lock check to avoid a race.
	     */
    
	    pmutexPtr = (pthread_mutex_t *)ckalloc(sizeof(pthread_mutex_t));
	    pthread_mutex_init(pmutexPtr, NULL);
	    *mutexPtr = (Tcl_Mutex)pmutexPtr;
	    TclRememberMutex(mutexPtr);
	}
	MASTER_UNLOCK;
    }
    pmutexPtr = *((pthread_mutex_t **)mutexPtr);
    pthread_mutex_lock(pmutexPtr);
}


/*
 *----------------------------------------------------------------------
 *
 * TclpMutexUnlock --
 *
 *	This procedure is invoked to unlock a mutex.  The mutex must
 *	have been locked by Tcl_MutexLock.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The mutex is released when this returns.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_MutexUnlock(mutexPtr)
    Tcl_Mutex *mutexPtr;	/* Really (pthread_mutex_t **) */
{
    pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **)mutexPtr;
    pthread_mutex_unlock(pmutexPtr);
}


/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeMutex --
 *
 *	This procedure is invoked to clean up one mutex.  This is only
 *	safe to call at the end of time.
 *
 *	This assumes the Master Lock is held.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The mutex list is deallocated.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeMutex(mutexPtr)
    Tcl_Mutex *mutexPtr;
{
    pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **)mutexPtr;
    if (pmutexPtr != NULL) {
	ckfree((char *)pmutexPtr);
	*mutexPtr = NULL;
    }
}


/*
 *----------------------------------------------------------------------
 *
 * TclpThreadDataKeyInit --
 *
 *	This procedure initializes a thread specific data block key.
 *	Each thread has table of pointers to thread specific data.
 *	all threads agree on which table entry is used by each module.
 *	this is remembered in a "data key", that is just an index into
 *	this table.  To allow self initialization, the interface
 *	passes a pointer to this key and the first thread to use
 *	the key fills in the pointer to the key.  The key should be
 *	a process-wide static.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Will allocate memory the first time this process calls for
 *	this key.  In this case it modifies its argument
 *	to hold the pointer to information about the key.
 *
 *----------------------------------------------------------------------
 */

void
TclpThreadDataKeyInit(keyPtr)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (pthread_key_t **) */
{
    pthread_key_t *pkeyPtr;

    MASTER_LOCK;
    if (*keyPtr == NULL) {
	pkeyPtr = (pthread_key_t *)ckalloc(sizeof(pthread_key_t));
	pthread_key_create(pkeyPtr, NULL);
	*keyPtr = (Tcl_ThreadDataKey)pkeyPtr;
	TclRememberDataKey(keyPtr);
    }
    MASTER_UNLOCK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpThreadDataKeyGet --
 *
 *	This procedure returns a pointer to a block of thread local storage.
 *
 * Results:
 *	A thread-specific pointer to the data structure, or NULL
 *	if the memory has not been assigned to this key for this thread.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

VOID *
TclpThreadDataKeyGet(keyPtr)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (pthread_key_t **) */
{
    pthread_key_t *pkeyPtr = *(pthread_key_t **)keyPtr;
    if (pkeyPtr == NULL) {
	return NULL;
    } else {
	return (VOID *)pthread_getspecific(*pkeyPtr);
    }
}


/*
 *----------------------------------------------------------------------
 *
 * TclpThreadDataKeySet --
 *
 *	This procedure sets the pointer to a block of thread local storage.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets up the thread so future calls to TclpThreadDataKeyGet with
 *	this key will return the data pointer.
 *
 *----------------------------------------------------------------------
 */

void
TclpThreadDataKeySet(keyPtr, data)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (pthread_key_t **) */
    VOID *data;			/* Thread local storage */
{
    pthread_key_t *pkeyPtr = *(pthread_key_t **)keyPtr;
    pthread_setspecific(*pkeyPtr, data);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeThreadData --
 *
 *	This procedure cleans up the thread-local storage.  This is
 *	called once for each thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees up all thread local storage.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeThreadData(keyPtr)
    Tcl_ThreadDataKey *keyPtr;
{
    VOID *result;
    pthread_key_t *pkeyPtr;

    if (*keyPtr != NULL) {
	pkeyPtr = *(pthread_key_t **)keyPtr;
	result = (VOID *)pthread_getspecific(*pkeyPtr);
	if (result != NULL) {
	    ckfree((char *)result);
	    pthread_setspecific(*pkeyPtr, (void *)NULL);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeThreadDataKey --
 *
 *	This procedure is invoked to clean up one key.  This is a
 *	process-wide storage identifier.  The thread finalization code
 *	cleans up the thread local storage itself.
 *
 *	This assumes the master lock is held.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The key is deallocated.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeThreadDataKey(keyPtr)
    Tcl_ThreadDataKey *keyPtr;
{
    pthread_key_t *pkeyPtr;
    if (*keyPtr != NULL) {
	pkeyPtr = *(pthread_key_t **)keyPtr;
	pthread_key_delete(*pkeyPtr);
	ckfree((char *)pkeyPtr);
	*keyPtr = NULL;
    }
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConditionWait --
 *
 *	This procedure is invoked to wait on a condition variable.
 *	The mutex is automically released as part of the wait, and
 *	automatically grabbed when the condition is signaled.
 *
 *	The mutex must be held when this procedure is called.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May block the current thread.  The mutex is aquired when
 *	this returns.  Will allocate memory for a pthread_mutex_t
 *	and initialize this the first time this Tcl_Mutex is used.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
    Tcl_Condition *condPtr;	/* Really (pthread_cond_t **) */
    Tcl_Mutex *mutexPtr;	/* Really (pthread_mutex_t **) */
    Tcl_Time *timePtr;		/* Timeout on waiting period */
{
    pthread_cond_t *pcondPtr;
    pthread_mutex_t *pmutexPtr;
    struct timespec ptime;

    if (*condPtr == NULL) {
	MASTER_LOCK;

	/* 
	 * Double check inside mutex to avoid race,
	 * then initialize condition variable if necessary.
	 */

	if (*condPtr == NULL) {
	    pcondPtr = (pthread_cond_t *)ckalloc(sizeof(pthread_cond_t));
	    pthread_cond_init(pcondPtr, NULL);
	    *condPtr = (Tcl_Condition)pcondPtr;
	    TclRememberCondition(condPtr);
	}
	MASTER_UNLOCK;
    }
    pmutexPtr = *((pthread_mutex_t **)mutexPtr);
    pcondPtr = *((pthread_cond_t **)condPtr);
    if (timePtr == NULL) {
	pthread_cond_wait(pcondPtr, pmutexPtr);
    } else {
	ptime.tv_sec = timePtr->sec + TclpGetSeconds();
	ptime.tv_nsec = 1000 * timePtr->usec;
	pthread_cond_timedwait(pcondPtr, pmutexPtr, &ptime);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConditionNotify --
 *
 *	This procedure is invoked to signal a condition variable.
 *
 *	The mutex must be held during this call to avoid races,
 *	but this interface does not enforce that.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May unblock another thread.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ConditionNotify(condPtr)
    Tcl_Condition *condPtr;
{
    pthread_cond_t *pcondPtr = *((pthread_cond_t **)condPtr);
    if (pcondPtr != NULL) {
	pthread_cond_broadcast(pcondPtr);
    } else {
	/*
	 * Noone has used the condition variable, so there are no waiters.
	 */
    }
}


/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeCondition --
 *
 *	This procedure is invoked to clean up a condition variable.
 *	This is only safe to call at the end of time.
 *
 *	This assumes the Master Lock is held.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The condition variable is deallocated.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeCondition(condPtr)
    Tcl_Condition *condPtr;
{
    pthread_cond_t *pcondPtr = *(pthread_cond_t **)condPtr;
    if (pcondPtr != NULL) {
	pthread_cond_destroy(pcondPtr);
	ckfree((char *)pcondPtr);
	*condPtr = NULL;
    }
}



#endif /* TCL_THREADS */

Added unix/tclUnixThrd.h.











































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclUnixThrd.h --
 *
 *      This header file defines things for thread support.
 *
 * 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.
 *
 * SCCS: @(#)
 */
 
#ifndef _TCLUNIXTHRD
#define _TCLUNIXTHRD

#ifdef TCL_THREADS


#endif /* TCL_THREADS */
#endif /* _TCLUNIXTHRD */

Changes to unix/tclUnixTime.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclUnixTime.c --
 *
 *	Contains Unix specific versions of Tcl functions that
 *	obtain time values from the operating system.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclUnixTime.c 1.13 97/10/31 15:04:58
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 *-----------------------------------------------------------------------------











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * tclUnixTime.c --
 *
 *	Contains Unix specific versions of Tcl functions that
 *	obtain time values from the operating system.
 *
 * Copyright (c) 1995 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: tclUnixTime.c,v 1.1.2.6 1999/03/25 00:34:17 redman Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 *-----------------------------------------------------------------------------
161
162
163
164
165
166
167



168
169

170
171
172
173

174
175
176
177
178
179
180
     * not return timezone information on many systems that have moved this
     * information outside of the kernel.
     */
    
#if defined(HAVE_TIMEZONE_VAR) && !defined (TCL_GOT_TIMEZONE)
#   define TCL_GOT_TIMEZONE
    static int setTZ = 0;



    int        timeZone;


    if (!setTZ) {
        tzset();
        setTZ = 1;
    }


    /*
     * Note: this is not a typo in "timezone" below!  See tzset
     * documentation for details.
     */

    timeZone = timezone / 60;







>
>
>


>




>







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
     * not return timezone information on many systems that have moved this
     * information outside of the kernel.
     */
    
#if defined(HAVE_TIMEZONE_VAR) && !defined (TCL_GOT_TIMEZONE)
#   define TCL_GOT_TIMEZONE
    static int setTZ = 0;
#ifdef TCL_THREADS
    static Tcl_Mutex tzMutex;
#endif
    int        timeZone;

    Tcl_MutexLock(&tzMutex);
    if (!setTZ) {
        tzset();
        setTZ = 1;
    }
    Tcl_MutexUnlock(&tzMutex);

    /*
     * Note: this is not a typo in "timezone" below!  See tzset
     * documentation for details.
     */

    timeZone = timezone / 60;
230
231
232
233
234
235
236


























































    struct timeval tv;
    struct timezone tz;
    
    (void) gettimeofday(&tv, &tz);
    timePtr->sec = tv.tv_sec;
    timePtr->usec = tv.tv_usec;
}

































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    struct timeval tv;
    struct timezone tz;
    
    (void) gettimeofday(&tv, &tz);
    timePtr->sec = tv.tv_sec;
    timePtr->usec = tv.tv_usec;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpGetDate --
 *
 *	This function converts between seconds and struct tm.  If
 *	useGMT is true, then the returned date will be in Greenwich
 *	Mean Time (GMT).  Otherwise, it will be in the local time zone.
 *
 * Results:
 *	Returns a static tm structure.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

struct tm *
TclpGetDate(time, useGMT)
    TclpTime_t time;
    int useGMT;
{
    CONST time_t *tp = (CONST time_t *)time;

    if (useGMT) {
	return gmtime(tp);
    } else {
	return localtime(tp);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpStrftime --
 *
 *	On Unix, we can safely call the native strftime implementation.
 *
 * Results:
 *	The normal strftime result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

size_t
TclpStrftime(s, maxsize, format, t)
    char *s;
    size_t maxsize;
    CONST char *format;
    CONST struct tm *t;
{
    return strftime(s, maxsize, format, t);
}

Added unix/tclXtNotify.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
/* 
 * tclXtNotify.c --
 *
 *	This file contains the notifier driver implementation for the
 *	Xt intrinsics.
 *
 * 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: tclXtNotify.c,v 1.1.2.2 1999/02/10 23:31:27 stanton Exp $
 */

#include <X11/Intrinsic.h>
#include <tclInt.h>

/*
 * This structure is used to keep track of the notifier info for a 
 * a registered file.
 */

typedef struct FileHandler {
    int fd;
    int mask;			/* Mask of desired events: TCL_READABLE, etc. */
    int readyMask;		/* Events that have been seen since the
				   last time FileHandlerEventProc was called
				   for this file. */
    XtInputId read;		/* Xt read callback handle. */
    XtInputId write;		/* Xt write callback handle. */
    XtInputId except;		/* Xt exception callback handle. */
    Tcl_FileProc *proc;		/* Procedure to call, in the style of
				 * Tcl_CreateFileHandler. */
    ClientData clientData;	/* Argument to pass to proc. */
    struct FileHandler *nextPtr;/* Next in list of all files we care about. */
} FileHandler;

/*
 * The following structure is what is added to the Tcl event queue when
 * file handlers are ready to fire.
 */

typedef struct FileHandlerEvent {
    Tcl_Event header;		/* Information that is standard for
				 * all events. */
    int fd;			/* File descriptor that is ready.  Used
				 * to find the FileHandler structure for
				 * the file (can't point directly to the
				 * FileHandler structure because it could
				 * go away while the event is queued). */
} FileHandlerEvent;

/*
 * The following static structure contains the state information for the
 * Xt based implementation of the Tcl notifier.
 */

static struct NotifierState {
    XtAppContext appContext;		/* The context used by the Xt
                                         * notifier. Can be set with
                                         * TclSetAppContext. */
    int appContextCreated;		/* Was it created by us? */
    XtIntervalId currentTimeout;	/* Handle of current timer. */
    FileHandler *firstFileHandlerPtr;	/* Pointer to head of file handler
					 * list. */
} notifier;

/*
 * The following static indicates whether this module has been initialized.
 */

static int initialized = 0;

/*
 * Static routines defined in this file.
 */

static int		FileHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
			    int flags));
static void		FileProc _ANSI_ARGS_((caddr_t clientData,
			    int *source, XtInputId *id));
static void		InitNotifier _ANSI_ARGS_((void));
static void		NotifierExitHandler _ANSI_ARGS_((
			    ClientData clientData));
static void		TimerProc _ANSI_ARGS_((caddr_t clientData,
			    XtIntervalId *id));

/*
 * Functions defined in this file for use by users of the Xt Notifier:
 */

EXTERN XtAppContext	TclSetAppContext _ANSI_ARGS_((XtAppContext ctx));

/*
 *----------------------------------------------------------------------
 *
 * TclSetAppContext --
 *
 *	Set the notifier application context.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets the application context used by the notifier. Panics if
 *	the context is already set when called.
 *
 *----------------------------------------------------------------------
 */

XtAppContext
TclSetAppContext(appContext)
    XtAppContext	appContext;
{
    if (!initialized) {
        InitNotifier();
    }

    /*
     * If we already have a context we check whether we were asked to set a
     * new context. If so, we panic because we try to prevent switching
     * contexts by mistake. Otherwise, we return the one we have.
     */
    
    if (notifier.appContext != NULL) {
        if (appContext != NULL) {

	    /*
             * We already have a context. We do not allow switching contexts
             * after initialization, so we panic.
             */
        
            panic("TclSetAppContext:  multiple application contexts");

        }
    } else {

        /*
         * If we get here we have not yet gotten a context, so either create
         * one or use the one supplied by our caller.
         */

        if (appContext == NULL) {

	    /*
             * We must create a new context and tell our caller what it is, so
             * she can use it too.
             */
    
            notifier.appContext = XtCreateApplicationContext();
            notifier.appContextCreated = 1;
        } else {

	    /*
             * Otherwise we remember the context that our caller gave us
             * and use it.
             */
    
            notifier.appContextCreated = 0;
            notifier.appContext = appContext;
        }
    }
    
    return notifier.appContext;
}

/*
 *----------------------------------------------------------------------
 *
 * InitNotifier --
 *
 *	Initializes the notifier state.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new exit handler.
 *
 *----------------------------------------------------------------------
 */

static void
InitNotifier(void)
{
    /*
     * Only reinitialize if we are not in exit handling. The notifier
     * can get reinitialized after its own exit handler has run, because
     * of exit handlers for the I/O and timer sub-systems (order dependency).
     */

    if (TclInExit()) {
        return;
    }

    /*
     * DO NOT create the application context yet; doing so would prevent
     * external applications from setting it for us to their own ones.
     */
    
    initialized = 1;
    memset(&notifier, 0, sizeof(notifier));
    Tcl_CreateExitHandler(NotifierExitHandler, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * NotifierExitHandler --
 *
 *	This function is called to cleanup the notifier state before
 *	Tcl is unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Destroys the notifier window.
 *
 *----------------------------------------------------------------------
 */

static void
NotifierExitHandler(
    ClientData clientData)	/* Not used. */
{
    if (notifier.currentTimeout != 0) {
        XtRemoveTimeOut(notifier.currentTimeout);
    }
    for (; notifier.firstFileHandlerPtr != NULL; ) {
        Tcl_DeleteFileHandler(notifier.firstFileHandlerPtr->fd);
    }
    if (notifier.appContextCreated) {
        XtDestroyApplicationContext(notifier.appContext);
        notifier.appContextCreated = 0;
        notifier.appContext = NULL;
    }
    initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetTimer --
 *
 *	This procedure sets the current notifier timeout value.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Replaces any previous timer.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_SetTimer(timePtr)
    Tcl_Time *timePtr;		/* Timeout value, may be NULL. */
{
    long timeout;

    if (!initialized) {
	InitNotifier();
    }

    TclSetAppContext(NULL);
    if (notifier.currentTimeout != 0) {
	XtRemoveTimeOut(notifier.currentTimeout);
    }
    if (timePtr) {
	timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
	notifier.currentTimeout =
            XtAppAddTimeOut(notifier.appContext, (unsigned long) timeout,
                    TimerProc, NULL);
    } else {
	notifier.currentTimeout = 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TimerProc --
 *
 *	This procedure is the XtTimerCallbackProc used to handle
 *	timeouts.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *      Processes all queued events.
 *
 *----------------------------------------------------------------------
 */

static void
TimerProc(data, id)
    caddr_t data;		/* Not used. */
    XtIntervalId *id;
{
    if (*id != notifier.currentTimeout) {
	return;
    }
    notifier.currentTimeout = 0;

    Tcl_ServiceAll();
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CreateFileHandler --
 *
 *	This procedure registers a file handler with the Xt notifier.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new file handler structure and registers one or more
 *	input procedures with Xt.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_CreateFileHandler(fd, mask, proc, clientData)
    int fd;			/* Handle of stream to watch. */
    int mask;			/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, and TCL_EXCEPTION:
				 * indicates conditions under which
				 * proc should be called. */
    Tcl_FileProc *proc;		/* Procedure to call for each
				 * selected event. */
    ClientData clientData;	/* Arbitrary data to pass to proc. */
{
    FileHandler *filePtr;

    if (!initialized) {
	InitNotifier();
    }

    TclSetAppContext(NULL);

    for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;
	    filePtr = filePtr->nextPtr) {
	if (filePtr->fd == fd) {
	    break;
	}
    }
    if (filePtr == NULL) {
	filePtr = (FileHandler*) ckalloc(sizeof(FileHandler));
	filePtr->fd = fd;
	filePtr->read = 0;
	filePtr->write = 0;
	filePtr->except = 0;
	filePtr->readyMask = 0;
	filePtr->mask = 0;
	filePtr->nextPtr = notifier.firstFileHandlerPtr;
	notifier.firstFileHandlerPtr = filePtr;
    }
    filePtr->proc = proc;
    filePtr->clientData = clientData;

    /*
     * Register the file with the Xt notifier, if it hasn't been done yet.
     */

    if (mask & TCL_READABLE) {
	if (!(filePtr->mask & TCL_READABLE)) {
	    filePtr->read =
                XtAppAddInput(notifier.appContext, fd, XtInputReadMask,
                        FileProc, filePtr);
	}
    } else {
	if (filePtr->mask & TCL_READABLE) {
	    XtRemoveInput(filePtr->read);
	}
    }
    if (mask & TCL_WRITABLE) {
	if (!(filePtr->mask & TCL_WRITABLE)) {
	    filePtr->write =
                XtAppAddInput(notifier.appContext, fd, XtInputWriteMask,
                        FileProc, filePtr);
	}
    } else {
	if (filePtr->mask & TCL_WRITABLE) {
	    XtRemoveInput(filePtr->write);
	}
    }
    if (mask & TCL_EXCEPTION) {
	if (!(filePtr->mask & TCL_EXCEPTION)) {
	    filePtr->except =
                XtAppAddInput(notifier.appContext, fd, XtInputExceptMask,
                        FileProc, filePtr);
	}
    } else {
	if (filePtr->mask & TCL_EXCEPTION) {
	    XtRemoveInput(filePtr->except);
	}
    }
    filePtr->mask = mask;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_DeleteFileHandler --
 *
 *	Cancel a previously-arranged callback arrangement for
 *	a file.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If a callback was previously registered on file, remove it.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_DeleteFileHandler(fd)
    int fd;			/* Stream id for which to remove
				 * callback procedure. */
{
    FileHandler *filePtr, *prevPtr;

    if (!initialized) {
	InitNotifier();
    }

    TclSetAppContext(NULL);

    /*
     * Find the entry for the given file (and return if there
     * isn't one).
     */

    for (prevPtr = NULL, filePtr = notifier.firstFileHandlerPtr; ;
	    prevPtr = filePtr, filePtr = filePtr->nextPtr) {
	if (filePtr == NULL) {
	    return;
	}
	if (filePtr->fd == fd) {
	    break;
	}
    }

    /*
     * Clean up information in the callback record.
     */

    if (prevPtr == NULL) {
	notifier.firstFileHandlerPtr = filePtr->nextPtr;
    } else {
	prevPtr->nextPtr = filePtr->nextPtr;
    }
    if (filePtr->mask & TCL_READABLE) {
	XtRemoveInput(filePtr->read);
    }
    if (filePtr->mask & TCL_WRITABLE) {
	XtRemoveInput(filePtr->write);
    }
    if (filePtr->mask & TCL_EXCEPTION) {
	XtRemoveInput(filePtr->except);
    }
    ckfree((char *) filePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * FileProc --
 *
 *	These procedures are called by Xt when a file becomes readable,
 *	writable, or has an exception.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Makes an entry on the Tcl event queue if the event is
 *	interesting.
 *
 *----------------------------------------------------------------------
 */

static void
FileProc(clientData, fd, id)
    caddr_t clientData;
    int *fd;
    XtInputId *id;
{
    FileHandler *filePtr = (FileHandler *)clientData;
    FileHandlerEvent *fileEvPtr;
    int mask = 0;

    /*
     * Determine which event happened.
     */

    if (*id == filePtr->read) {
	mask = TCL_READABLE;
    } else if (*id == filePtr->write) {
	mask = TCL_WRITABLE;
    } else if (*id == filePtr->except) {
	mask = TCL_EXCEPTION;
    }

    /*
     * Ignore unwanted or duplicate events.
     */

    if (!(filePtr->mask & mask) || (filePtr->readyMask & mask)) {
	return;
    }
    
    /*
     * This is an interesting event, so put it onto the event queue.
     */

    filePtr->readyMask |= mask;
    fileEvPtr = (FileHandlerEvent *) ckalloc(sizeof(FileHandlerEvent));
    fileEvPtr->header.proc = FileHandlerEventProc;
    fileEvPtr->fd = filePtr->fd;
    Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);

    /*
     * Process events on the Tcl event queue before returning to Xt.
     */

    Tcl_ServiceAll();
}

/*
 *----------------------------------------------------------------------
 *
 * FileHandlerEventProc --
 *
 *	This procedure is called by Tcl_ServiceEvent when a file event
 *	reaches the front of the event queue.  This procedure is
 *	responsible for actually handling the event by invoking the
 *	callback for the file handler.
 *
 * Results:
 *	Returns 1 if the event was handled, meaning it should be removed
 *	from the queue.  Returns 0 if the event was not handled, meaning
 *	it should stay on the queue.  The only time the event isn't
 *	handled is if the TCL_FILE_EVENTS flag bit isn't set.
 *
 * Side effects:
 *	Whatever the file handler's callback procedure does.
 *
 *----------------------------------------------------------------------
 */

static int
FileHandlerEventProc(evPtr, flags)
    Tcl_Event *evPtr;		/* Event to service. */
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    FileHandler *filePtr;
    FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr;
    int mask;

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the file handlers to find the one whose handle matches
     * the event.  We do this rather than keeping a pointer to the file
     * handler directly in the event, so that the handler can be deleted
     * while the event is queued without leaving a dangling pointer.
     */

    for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;
	    filePtr = filePtr->nextPtr) {
	if (filePtr->fd != fileEvPtr->fd) {
	    continue;
	}

	/*
	 * The code is tricky for two reasons:
	 * 1. The file handler's desired events could have changed
	 *    since the time when the event was queued, so AND the
	 *    ready mask with the desired mask.
	 * 2. The file could have been closed and re-opened since
	 *    the time when the event was queued.  This is why the
	 *    ready mask is stored in the file handler rather than
	 *    the queued event:  it will be zeroed when a new
	 *    file handler is created for the newly opened file.
	 */

	mask = filePtr->readyMask & filePtr->mask;
	filePtr->readyMask = 0;
	if (mask != 0) {
	    (*filePtr->proc)(filePtr->clientData, mask);
	}
	break;
    }
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_WaitForEvent --
 *
 *	This function is called by Tcl_DoOneEvent to wait for new
 *	events on the message queue.  If the block time is 0, then
 *	Tcl_WaitForEvent just polls without blocking.
 *
 * Results:
 *	Returns 1 if an event was found, else 0.  This ensures that
 *	Tcl_DoOneEvent will return 1, even if the event is handled
 *	by non-Tcl code.
 *
 * Side effects:
 *	Queues file events that are detected by the select.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_WaitForEvent(
    Tcl_Time *timePtr)		/* Maximum block time, or NULL. */
{
    int timeout;

    if (!initialized) {
	InitNotifier();
    }

    TclSetAppContext(NULL);

    if (timePtr) {
        timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
        if (timeout == 0) {
            if (XtAppPending(notifier.appContext)) {
                goto process;
            } else {
                return 0;
            }
        } else {
            Tcl_SetTimer(timePtr);
        }
    }
process:
    XtAppProcessEvent(notifier.appContext, XtIMAll);
    return 1;
}

Changes to unix/tclXtTest.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
/* 
 * tclXtTest.c --
 *
 *	Contains commands for Xt notifier specific tests on Unix.
 *
 * 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.
 *
 * SCCS: @(#) tclXtTest.c 1.2 97/09/15 15:26:52
 */

#include <X11/Intrinsic.h>
#include "tcl.h"

static int	TesteventloopCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));

/*
 *----------------------------------------------------------------------
 *
 * Tclxttest_Init --
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in interp->result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */











|



















|







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
/* 
 * tclXtTest.c --
 *
 *	Contains commands for Xt notifier specific tests on Unix.
 *
 * 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: tclXtTest.c,v 1.1.2.2 1998/09/24 23:59:47 stanton Exp $
 */

#include <X11/Intrinsic.h>
#include "tcl.h"

static int	TesteventloopCmd _ANSI_ARGS_((ClientData clientData,
		    Tcl_Interp *interp, int argc, char **argv));

/*
 *----------------------------------------------------------------------
 *
 * Tclxttest_Init --
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in the interp's result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */

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
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

Tcl 8.0p2 for Windows

by Scott Stanton
Sun Microsystems Laboratories
scott.stanton@eng.sun.com

SCCS: @(#) README 1.25 97/11/21 15:15:40

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.0 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.smli.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.0 Source Distribution (plus any patches)

	Borland C++ 4.52 (both 16-bit and 32-bit compilers)
	  or
	Visual C++ 2.x/4.x
	Visual C++ 1.5 (to build tcl1680.dll for Win32s support of exec)


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".

	2) In the lib\tcl8.0 directory under the installation directory
	   as specified in the registry:

		For Windows NT & 95:
		    HKEY_LOCAL_MACHINE\SOFTWARE\Sun\Tcl\8.0
			Value Name is "Root"

		For Win32s:
		    HKEY_CLASSES_ROOT\SOFTWARE\Sun\Tcl\8.0\

	3) Relative to the directory containing the current .exe.
	    Tcl will look for a directory "..\lib\tcl8.0" relative to the
	    directory containing the currently running .exe.

Note that in order to run tclsh80.exe, you must ensure that tcl80.dll
and tclpip80.dll (plus tcl1680.dll under Win32s) are on your path, in
the system directory, or in the directory containing tclsh80.exe.






















































































4. 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.


5. Known Bugs
-------------

Here is the current list of known bugs/missing features for the
Windows version of Tcl:

- Blocking "after" commands (e.g. "after 3000") don't work on Win32s.
- 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.
- Pipes/files/console/serial ports don't support nonblocking I/O.
- The library cannot be used by two processes at the same time under
  Win32s.

If you have comments or bug reports for the Windows version of Tcl,
please direct them to:

Scott Stanton
[email protected]


or post them to the comp.lang.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
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
Tcl 8.1 for Windows

by Scott Stanton
Scriptics Corporation
scott.stanton@scriptics.com

RCS: @(#) $Id: README,v 1.1.2.7 1999/03/25 00:31:22 rjohnson 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".

	2) In the lib\tcl8.1 directory under the installation directory
	   as specified in the registry:


		HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.1





	3) Relative to the directory containing the current .exe.
	    Tcl will look for a directory "..\lib\tcl8.1" relative to the
	    directory containing the currently running .exe.

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.

Added 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
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
Tcl/Tk 8.1b3 for Windows, Binary Distribution

RCS: @(#) $Id: README.binary,v 1.2.2.7 1999/03/25 01:34:21 rjohnson Exp $ 

1. Introduction
--------------- 

This directory contains the binary distribution of Tcl/Tk 8.1b3 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 second beta 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
-----------------

There is a network news group "comp.lang.tcl" intended for the exchange
of information about Tcl, Tk, and related applications.  Feel free to use
the newsgroup both for general information questions and for bug reports.
We read the newsgroup and will attempt to fix bugs and problems reported
to it.

When using comp.lang.tcl, please be sure that your e-mail return address
is correctly set in your postings.  This allows people to respond directly
to you, rather than the entire newsgroup, for answers that are not of
general interest.  A bad e-mail return address may prevent you from
getting answers to your questions.  You may have to reconfigure your news
reading software to ensure that it is supplying valid e-mail addresses.

8. 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.

9. Tcl Resource Center
----------------------
Visit http://www.scritics.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 extensions, applications, binary
releases, and patches.  You can contribute patches by sending them
to <[email protected]>.  You can also recommend more URLs for the
resource center using the forms labeled "Add a Resource".

10. Mailing lists
----------------

A couple of  Mailing List have been set up to discuss Macintosh or
Windows related Tcl issues.  In order to use these Mailing Lists you
must have access to the internet.  To subscribe send a message to:
	
	[email protected]
	[email protected]
	
In the body of the message (the subject will be ignored) put:
	
	subscribe mactcl Joe Blow
	
Replacing Joe Blow with your real name, of course.  (Use wintcl
instead of mactcl if your interested in the Windows list.)  If you
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.

Changes to win/cat.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * cat.c --
 *
 *	Program used when testing tclWinPipe.c
 *
 * Copyright (c) 1996 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.
 *
 * SCCS: @(#) cat.c 1.3 96/09/18 15:15:32
 */

#include <stdio.h>
#include <io.h>
#include <string.h>

int










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * cat.c --
 *
 *	Program used when testing tclWinPipe.c
 *
 * Copyright (c) 1996 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: cat.c,v 1.1.2.1 1998/09/24 23:59:48 stanton Exp $
 */

#include <stdio.h>
#include <io.h>
#include <string.h>

int

Deleted win/makefile.bc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# SCCS: @(#) makefile.bc 1.82 97/11/20 15:52:39
#
# Borland C++ 4.5 makefile
#

#
# Project directories
#
# ROOT = top of source tree
# TMPDIR = location where .obj files should be stored during build
# TOOLS = location of compiler and other development tools
#

ROOT	= ..
TMPDIR	= .
TOOLS	= c:\bc45

# uncomment the following line to compile with symbols
#DEBUG=1

# uncomment one of the following lines to compile with TCL_MEM_DEBUG,
# TCL_COMPILE_DEBUG, or TCL_COMPILE_STATS
#DEBUGDEFINES   =TCL_MEM_DEBUG 
#DEBUGDEFINES   =TCL_MEM_DEBUG;TCL_COMPILE_DEBUG
#DEBUGDEFINES   =TCL_MEM_DEBUG;TCL_COMPILE_STATS
#DEBUGDEFINES   =TCL_MEM_DEBUG;TCL_COMPILE_DEBUG;TCL_COMPILE_STATS


######################################################################
# Do not modify below this line
######################################################################

STACKSIZE = 1f0001

VERSION = 80

TCLLIB 		= tcl$(VERSION).lib
TCLDLL 		= tcl$(VERSION).dll
TCL16DLL 	= tcl16$(VERSION).dll
TCLSH 		= tclsh$(VERSION).exe
TCLTEST 	= tcltest.exe
DUMPEXTS 	= dumpexts.exe
TCLPIPEDLL 	= tclpip$(VERSION).dll
TCLREGDLL 	= tclreg$(VERSION).dll
CAT16 		= cat16.exe
CAT32 		= cat32.exe

TCLSHOBJS = \
	$(TMPDIR)\tclAppInit.obj

TCLTESTOBJS = \
	$(TMPDIR)\tclTest.obj \
	$(TMPDIR)\tclTestObj.obj \
	$(TMPDIR)\tclWinTest.obj \
	$(TMPDIR)\testMain.obj

TCLOBJS = \
	$(TMPDIR)\panic.obj \
	$(TMPDIR)\regexp.obj \
	$(TMPDIR)\strftime.obj \
	$(TMPDIR)\tclAlloc.obj \
	$(TMPDIR)\tclAsync.obj \
	$(TMPDIR)\tclBasic.obj \
	$(TMPDIR)\tclBinary.obj \
	$(TMPDIR)\tclCkalloc.obj \
	$(TMPDIR)\tclClock.obj \
	$(TMPDIR)\tclCmdAH.obj \
	$(TMPDIR)\tclCmdIL.obj \
	$(TMPDIR)\tclCmdMZ.obj \
	$(TMPDIR)\tclCompExpr.obj \
	$(TMPDIR)\tclCompile.obj \
	$(TMPDIR)\tclDate.obj \
	$(TMPDIR)\tclEnv.obj \
	$(TMPDIR)\tclEvent.obj \
	$(TMPDIR)\tclExecute.obj \
	$(TMPDIR)\tclFCmd.obj \
	$(TMPDIR)\tclFileName.obj \
	$(TMPDIR)\tclGet.obj \
	$(TMPDIR)\tclHash.obj \
	$(TMPDIR)\tclHistory.obj \
	$(TMPDIR)\tclIndexObj.obj \
	$(TMPDIR)\tclInterp.obj \
	$(TMPDIR)\tclIO.obj \
	$(TMPDIR)\tclIOCmd.obj \
	$(TMPDIR)\tclIOSock.obj \
	$(TMPDIR)\tclIOUtil.obj \
	$(TMPDIR)\tclLink.obj \
	$(TMPDIR)\tclListObj.obj \
	$(TMPDIR)\tclLoad.obj \
	$(TMPDIR)\tclMain.obj \
	$(TMPDIR)\tclNamesp.obj \
	$(TMPDIR)\tclNotify.obj \
	$(TMPDIR)\tclObj.obj \
	$(TMPDIR)\tclParse.obj \
	$(TMPDIR)\tclPipe.obj \
	$(TMPDIR)\tclPkg.obj \
	$(TMPDIR)\tclPosixStr.obj \
	$(TMPDIR)\tclPreserve.obj \
	$(TMPDIR)\tclProc.obj \
	$(TMPDIR)\tclStringObj.obj \
	$(TMPDIR)\tclTimer.obj \
	$(TMPDIR)\tclUtil.obj \
	$(TMPDIR)\tclVar.obj \
	$(TMPDIR)\tclWin32Dll.obj \
	$(TMPDIR)\tclWinChan.obj \
	$(TMPDIR)\tclWinError.obj \
	$(TMPDIR)\tclWinFCmd.obj \
	$(TMPDIR)\tclWinFile.obj \
	$(TMPDIR)\tclWinInit.obj \
	$(TMPDIR)\tclWinLoad.obj \
	$(TMPDIR)\tclWinMtherr.obj \
	$(TMPDIR)\tclWinNotify.obj \
	$(TMPDIR)\tclWinPipe.obj \
	$(TMPDIR)\tclWinSock.obj \
	$(TMPDIR)\tclWinTime.obj

cc32		= $(TOOLS)\bin\bcc32.exe
link32		= $(TOOLS)\bin\tlink32.exe
rc32		= $(TOOLS)\bin\brcc32.exe
implib		= $(TOOLS)\bin\implib.exe

cc16		= $(TOOLS)\bin\bcc.exe
link16		= $(TOOLS)\bin\tlink.exe
rc16		= $(TOOLS)\bin\brcc32.exe -31

CP		= copy
RM		= del

WINDIR          = $(ROOT)\win
GENERICDIR	= $(ROOT)\generic

INCLUDES	= $(TOOLS)\include;$(WINDIR);$(GENERICDIR)
LIBDIRS		= $(TOOLS)\lib;$(WINDIR)

CON_CFLAGS	= +cfgexe.cfg -WC
TEST_CFLAGS	= +cfgtest.cfg
DLL16_CFLAGS	= $(PROJECTCCFLAGS) -I$(INCLUDES) -D$(DEFINES) -WD -ml -c \
			-3 -d -w
TCL_CFLAGS	= +cfgdll.cfg

CON_LFLAGS	= -Tpe -ap -c $(DEBUGLDFLAGS) $(TOOLS)\lib\c0x32
DLL_LFLAGS	= -Tpd -aa -c $(DEBUGLDFLAGS) $(TOOLS)\lib\c0d32
GUI_LFLAGS	= -Tpe -aa -c $(DEBUGLDFLAGS) $(TOOLS)\lib\c0w32
DLL16_LFLAGS	= -Twd -c -C -A=16 $(DEBUGLDFLAGS16) $(TOOLS)\lib\c0dl

DLL_LIBS	= import32 cw32mti
CON_LIBS	= $(TCLLIB) import32 cw32mti
DLL16_LIBS	= import cwl

!ifndef DEBUG

# these macros cause maximum optimization and no symbols
DEBUGLDFLAGS = 
DEBUGCCFLAGS = -v- -vi- -O2
DEBUGLDFLAGS16 = -Oc -Oi -Oa -Or
!else

# these macros enable debugging
DEBUGLDFLAGS = -v
DEBUGCCFLAGS = -k -Od -v
DEBUGLDFLAGS16 = 

!endif

DEFINES = MT;_RTLDLL;$(DEBUGDEFINES)
PROJECTCCFLAGS = $(DEBUGCCFLAGS) -w-par -w-stu


# 
# Global makefile settings
#

.AUTODEPEND
.CACHEAUTODEPEND

.suffixes:

#.path.c=$(ROOT)\win;$(ROOT)\generic;$(ROOT)\compat
#.path.obj=$(TMPDIR)
#.path.dll=$(ROOT)\win

#
# Targets
#

release:    $(TCLSH) dlls
all:	    $(TCLSH) dlls $(CAT16) $(CAT32) 
tcltest:    $(TCLTEST) dlls $(CAT16) $(CAT32)
dlls:	    $(TCL16DLL) $(TCLPIPEDLL) $(TCLREGDLL)

test:	    tcltest
	$(TCLTEST) &&|
		cd ../tests
		source all
|


$(DUMPEXTS): cfgexe.cfg $(WINDIR)\winDumpExts.c
	$(cc32) $(CON_CFLAGS) $(WINDIR)\winDumpExts.c
	$(link32) $(CON_LFLAGS) \
		$(TMPDIR)\winDumpExts.obj,$@,,import32 cw32mti,,

$(TCLLIB): $(TCLDLL)
	$(implib) -c $@ $(TCLDLL)

$(TCLDLL): cfgdll.cfg $(TCLOBJS) $(TMPDIR)\tcl.def $(TMPDIR)\tcl.res
	$(link32) $(DLL_LFLAGS) @&&|
		$(TCLOBJS)
$@
-x
$(DLL_LIBS)
|, $(TMPDIR)\tcl.def, $(TMPDIR)\tcl.res


$(TCLSH): cfgexe.cfg $(TCLSHOBJS) $(TCLLIB) $(TMPDIR)\tclsh.res
	$(link32) -S:$(STACKSIZE) $(CON_LFLAGS) @&&|
		$(TCLSHOBJS)
$@
-x
$(CON_LIBS)
|, &&|
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
|, $(TMPDIR)\tclsh.res

$(TCLTEST): cfgtest.cfg $(TCLTESTOBJS) $(TCLLIB) $(TMPDIR)\tclsh.res
	$(link32) -S:$(STACKSIZE) $(CON_LFLAGS) @&&|
		$(TCLTESTOBJS)
$@
-x
$(CON_LIBS)
|, &&|
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
|, $(TMPDIR)\tclsh.res


$(TCL16DLL): tcl16.rc $(ROOT)\win\tclWin16.c
	$(cc16) @&&|
$(DLL16_CFLAGS) -n$(TMPDIR) 
| $(ROOT)\win\tclWin16.c
	$(rc16) @&&|
-i$(INCLUDES) -d__WIN32__;$(DEFINES) -fo$(TMPDIR)\tcl16.res
| tcl16.rc
	@copy >nul &&|
LIBRARY $&;dll
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 1024
EXPORTS
	WEP @1 RESIDENTNAME
	UTPROC @2 
| $(TMPDIR)\tclWin16.def
	$(link16) $(DLL16_LFLAGS) @&&|
$(TMPDIR)\tclWin16.obj
$@
nul
$(DLL16_LIBS)
$(TMPDIR)\tclWin16.def
|
	$(TOOLS)\bin\rlink $(TMPDIR)\tcl16.res $@

$(TCLPIPEDLL): cfgexe.cfg stub16.c
	$(cc32) -c -tWC stub16.c
	$(link32) $(CON_LFLAGS) -L$(TOOLS)\lib \
		stub16.obj,$@,,import32 cw32,,

$(TCLREGDLL): extdll.cfg $(TMPDIR)\tclWinReg.obj
	$(link32) $(DLL_LFLAGS) @&&|
		$(TMPDIR)\tclWinReg.obj
$@
-x
$(DLL_LIBS) $(TCLLIB)
|,,

#
# Special test targets
#

$(CAT32): cat.c
	$(cc32) -c -Ox -tWC -ocat32.obj cat.c
	$(link32) $(CON_LFLAGS) -L$(TOOLS)\lib \
		cat32.obj,$@,,import32 cw32,,

$(CAT16): cat.c
	$(cc16) -W- -ml -Ox -c -ocat16.obj cat.c
	$(link16) -Tde -c -L$(TOOLS)\lib $(TOOLS)\lib\c0l.obj cat16.obj,cat16.exe,,cl.lib,,

#######################################################################
# Implicit Targets
#######################################################################


{$(WINDIR)}.c{$(TMPDIR)}.obj:
	@$(cc32) $(TCL_CFLAGS) {$< }

{$(GENERICDIR)}.c{$(TMPDIR)}.obj:
	@$(cc32) $(TCL_CFLAGS) {$< }

{$(ROOT)\compat}.c{$(TMPDIR)}.obj:
	@$(cc32) $(TCL_CFLAGS) {$< }

{$(WINDIR)}.rc{$(TMPDIR)}.res:
	$(rc32) -i$(INCLUDES) -fo$@ @&&|
-d__WIN32__;$(DEFINES) $<
|

#
# Special case object file targets
#

$(TMPDIR)\tclWinReg.obj : extdll.cfg $(ROOT)\win\tclWinReg.c
	$(cc32) +extdll.cfg -o$@ $(ROOT)\win\tclWinReg.c

$(TMPDIR)\tclAppInit.obj : cfgexe.cfg $(ROOT)\win\tclAppInit.c
	$(cc32) $(CON_CFLAGS) -o$@ $(ROOT)\win\tclAppInit.c

$(TMPDIR)\testMain.obj : cfgexe.cfg $(ROOT)\win\tclAppInit.c
	$(cc32) $(TEST_CFLAGS) -o$@ $(ROOT)\win\tclAppInit.c

$(TMPDIR)\tclWin16.obj : $(ROOT)\win\tclWin16.c
	$(cc16) $(DLL16_CFLAGS) -o$@ $(ROOT)\win\tclWin16.c

#
# Configuration file targets - these files are implicitly used by the compiler
#

cfgdll.cfg:
	@$(CP) &&|
		-n$(TMPDIR) -I$(INCLUDES) -c -WM
		-D$(DEFINES) -3 -d -w $(PROJECTCCFLAGS)
| cfgdll.cfg >NUL

extdll.cfg:
	@$(CP) &&|
		-n$(TMPDIR) -I$(INCLUDES) -c -WD
		-D_RTLDLL;$(DEBUGDEFINES) -3 -d -w $(PROJECTCCFLAGS)
| extdll.cfg >NUL

cfgexe.cfg:
	@$(CP) &&|
		-n$(TMPDIR) -I$(INCLUDES) -c -W
		-D$(DEFINES) -3 -d -w $(PROJECTCCFLAGS)
| cfgexe.cfg >NUL

cfgtest.cfg:
	@$(CP) &&|
		-n$(TMPDIR) -I$(INCLUDES) -c -W
		-D$(DEFINES);TCL_TEST -3 -d -w $(PROJECTCCFLAGS)
| cfgtest.cfg >NUL

cfgcln:
	-@$(RM) *.cfg


# The following rule automatically generates a tcl.def file containing
# an export entry for every public symbol in the tcl.dll library.

$(TMPDIR)\tcl.def: $(TCLOBJS) $(DUMPEXTS)
	$(DUMPEXTS) -o $(TMPDIR)\tcl.def $(TCLDLL) @&&|
		$(TCLOBJS)
|


# the following two rules are a hack to get around the fact that the
# 16-bit compiler doesn't handle long file names :-(

$(ROOT)\win\tclWinIn.h: $(ROOT)\win\tclWinInt.h
	$(CP) $(ROOT)\win\tclWinInt.h $(ROOT)\win\tclWinIn.h

$(ROOT)\win\tclWin16.c: $(ROOT)\win\tclWinIn.h

# remove all generated files

clean:
	-@$(RM) *.exe
	-@$(RM) *.lib
	-@$(RM) *.dll
	-@$(RM) $(TMPDIR)\*.res
	-@$(RM) $(TMPDIR)\*.def
	-@$(RM) $(TMPDIR)\*.obj
	-@$(RM) $(TMPDIR)\*.cfg
	-@$(RM) $(ROOT)\win\tclWinIn.h
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































Changes to win/makefile.vc.

1
2
3
4
5
6


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32


33
34
35
36
37

38


39
40
41
42
43



44
45
46
47


48
49
50




51

52
53
54
55
56



57
58











59


60
61





62
63
64
65






66
67


68
69
70
71




72
73
74
75
76
77
78


79
80
81
82
83
84


85
86
87
88
89
90
91
92
93
94

95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118

119

120
121
122
123
124




125



126

127
128
129
130


131
132
133
134
135
136
137
138
139

140
141


142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236






237
238
239
240
241
242
243
244
245
246

247


248
249
250
251
252




253
254
255
256
257
258
259
260
261
262
263
264
265
266
267



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# Visual C++ 2.x and 4.0 makefile
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# Copyright (c) 1995-1996 Sun Microsystems, Inc.


# SCCS: @(#) makefile.vc 1.82 97/11/20 15:14:01

# Does not depend on the presence of any environment variables in
# order to compile tcl; all needed information is derived from 
# location of the compiler directories.

#
# Project directories
#
# ROOT    = top of source tree
#
# TMPDIR  = location where .obj files should be stored during build
#
# TOOLS32 = location of VC++ 32-bit development tools. Note that the
#	    VC++ 2.0 header files are broken, so you need to use the
#	    ones that come with the developer network CD's, or later
#	    versions of VC++.
#
# TOOLS16 = location of VC++ 1.5 16-bit tools, needed to build thunking
#	    library.  This information is optional; if the 16-bit compiler
#	    is not available, then the 16-bit code will not be built.  
#	    Tcl will still run without the 16-bit code, but...
#		A. Under Windows 3.X you will any calls to the exec command
#	           will return an error.
#		B. A 16-bit program to test the behavior of the exec
#		   command under NT and 95 will not be built.


#

ROOT		= ..
TMPDIR		= .
TOOLS32		= c:\msdev

TOOLS16		= c:\msvc



# Set this to the appropriate value of /MACHINE: for your platform
MACHINE	= IX86

# Comment the following line to compile with symbols



NODEBUG=1

# uncomment one of the following lines to compile with TCL_MEM_DEBUG, 
# TCL_MEM_DEBUG, or TCL_COMPILE_DEBUG


#DEBUGDEFINES	= -DTCL_MEM_DEBUG
#DEBUGDEFINES	= -DTCL_MEM_DEBUG -DTCL_COMPILE_DEBUG
#DEBUGDEFINES	= -DTCL_MEM_DEBUG -DTCL_COMPILE_STATS




#DEBUGDEFINES	= -DTCL_MEM_DEBUG -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS


######################################################################
# Do not modify below this line
######################################################################




VERSION = 80












TCLLIB		= tcl$(VERSION).lib


TCLDLL		= tcl$(VERSION).dll
TCLPLUGINLIB	= tcl$(VERSION)p.lib





TCLPLUGINDLL	= tcl$(VERSION)p.dll
TCL16DLL	= tcl16$(VERSION).dll
TCLSH		= tclsh$(VERSION).exe
TCLSHP		= tclshp$(VERSION).exe






TCLTEST		= tcltest.exe
DUMPEXTS	= $(TMPDIR)\dumpexts.exe


TCLPIPEDLL	= tclpip$(VERSION).dll
TCLREGDLL	= tclreg$(VERSION).dll
CAT16		= cat16.exe
CAT32		= cat32.exe





TCLSHOBJS = \
	$(TMPDIR)\tclAppInit.obj

TCLTESTOBJS = \
	$(TMPDIR)\tclTest.obj \
	$(TMPDIR)\tclTestObj.obj \


	$(TMPDIR)\tclWinTest.obj \
	$(TMPDIR)\testMain.obj

TCLOBJS = \
	$(TMPDIR)\panic.obj \
	$(TMPDIR)\regexp.obj \


	$(TMPDIR)\strftime.obj \
	$(TMPDIR)\tclAlloc.obj \
	$(TMPDIR)\tclAsync.obj \
	$(TMPDIR)\tclBasic.obj \
	$(TMPDIR)\tclBinary.obj \
	$(TMPDIR)\tclCkalloc.obj \
	$(TMPDIR)\tclClock.obj \
	$(TMPDIR)\tclCmdAH.obj \
	$(TMPDIR)\tclCmdIL.obj \
	$(TMPDIR)\tclCmdMZ.obj \

	$(TMPDIR)\tclCompExpr.obj \
	$(TMPDIR)\tclCompile.obj \
	$(TMPDIR)\tclDate.obj \

	$(TMPDIR)\tclEnv.obj \
	$(TMPDIR)\tclEvent.obj \
	$(TMPDIR)\tclExecute.obj \
	$(TMPDIR)\tclFCmd.obj \
	$(TMPDIR)\tclFileName.obj \
	$(TMPDIR)\tclGet.obj \
	$(TMPDIR)\tclHash.obj \
	$(TMPDIR)\tclHistory.obj \
	$(TMPDIR)\tclIndexObj.obj \
	$(TMPDIR)\tclInterp.obj \
	$(TMPDIR)\tclIO.obj \
	$(TMPDIR)\tclIOCmd.obj \
	$(TMPDIR)\tclIOSock.obj \
	$(TMPDIR)\tclIOUtil.obj \
	$(TMPDIR)\tclLink.obj \

	$(TMPDIR)\tclListObj.obj \
	$(TMPDIR)\tclLoad.obj \
	$(TMPDIR)\tclMain.obj \
	$(TMPDIR)\tclNamesp.obj \
	$(TMPDIR)\tclNotify.obj \
	$(TMPDIR)\tclObj.obj \

	$(TMPDIR)\tclParse.obj \

	$(TMPDIR)\tclPipe.obj \
	$(TMPDIR)\tclPkg.obj \
	$(TMPDIR)\tclPosixStr.obj \
	$(TMPDIR)\tclPreserve.obj \
	$(TMPDIR)\tclProc.obj \




	$(TMPDIR)\tclStringObj.obj \



	$(TMPDIR)\tclTimer.obj \

	$(TMPDIR)\tclUtil.obj \
	$(TMPDIR)\tclVar.obj \
	$(TMPDIR)\tclWin32Dll.obj \
	$(TMPDIR)\tclWinChan.obj \


	$(TMPDIR)\tclWinError.obj \
	$(TMPDIR)\tclWinFCmd.obj \
	$(TMPDIR)\tclWinFile.obj \
	$(TMPDIR)\tclWinInit.obj \
	$(TMPDIR)\tclWinLoad.obj \
	$(TMPDIR)\tclWinMtherr.obj \
	$(TMPDIR)\tclWinNotify.obj \
	$(TMPDIR)\tclWinPipe.obj \
	$(TMPDIR)\tclWinSock.obj \

	$(TMPDIR)\tclWinTime.obj 



cc32		= $(TOOLS32)\bin\cl.exe
link32		= $(TOOLS32)\bin\link.exe
rc32		= $(TOOLS32)\bin\rc.exe
include32	= -I$(TOOLS32)\include


cc16		= $(TOOLS16)\bin\cl.exe
link16		= $(TOOLS16)\bin\link.exe
rc16		= $(TOOLS16)\bin\rc.exe
include16	= -I$(TOOLS16)\include

WINDIR          = $(ROOT)\win
GENERICDIR	= $(ROOT)\generic

TCL_INCLUDES	= -I$(WINDIR) -I$(GENERICDIR)
TCL_DEFINES	= -D__WIN32__ $(DEBUGDEFINES)

TCL_CFLAGS	= $(cdebug) $(cflags) $(cvarsdll) $(include32) \
			$(TCL_INCLUDES) $(TCL_DEFINES)
CON_CFLAGS	= $(cdebug) $(cflags) $(cvars) $(include32) -DCONSOLE
DOS_CFLAGS	= $(cdebug) $(cflags) $(include16) -AL 
DLL16_CFLAGS	= $(cdebug) $(cflags) $(include16) -ALw

######################################################################
# Link flags
######################################################################

!IFDEF NODEBUG
ldebug = /RELEASE
!ELSE
ldebug = -debug:full -debugtype:cv
!ENDIF

# declarations common to all linker options
lcommon = /NODEFAULTLIB /RELEASE /NOLOGO

# declarations for use on Intel i386, i486, and Pentium systems
!IF "$(MACHINE)" == "IX86"
DLLENTRY = @12
lflags   = $(lcommon) -align:0x1000 /MACHINE:$(MACHINE)
!ELSE
lflags   = $(lcommon) /MACHINE:$(MACHINE)
!ENDIF

conlflags = $(lflags) -subsystem:console -entry:mainCRTStartup
guilflags = $(lflags) -subsystem:windows -entry:WinMainCRTStartup
dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll

!IF "$(MACHINE)" == "PPC"
libc = libc.lib
libcdll = crtdll.lib
!ELSE
libc = libc.lib oldnames.lib
libcdll = msvcrt.lib oldnames.lib
!ENDIF

baselibs   = kernel32.lib $(optlibs) advapi32.lib user32.lib
winlibs    = $(baselibs) gdi32.lib comdlg32.lib winspool.lib

guilibs	   = $(libc) $(winlibs)
conlibs	   = $(libc) $(baselibs)
guilibsdll = $(libcdll) $(winlibs)
conlibsdll = $(libcdll) $(baselibs)

######################################################################
# Compile flags
######################################################################

!IFDEF NODEBUG

cdebug = -Oti -Gs -GD
!ELSE
cdebug = -Z7 -Od -WX
!ENDIF

# declarations common to all compiler options
ccommon = -c -W3 -nologo -YX -Dtry=__try -Dexcept=__except

!IF "$(MACHINE)" == "IX86"
cflags = $(ccommon) -D_X86_=1
!ELSE
!IF "$(MACHINE)" == "MIPS"
cflags = $(ccommon) -D_MIPS_=1
!ELSE
!IF "$(MACHINE)" == "PPC"
cflags = $(ccommon) -D_PPC_=1
!ELSE
!IF "$(MACHINE)" == "ALPHA"
cflags = $(ccommon) -D_ALPHA_=1
!ENDIF
!ENDIF
!ENDIF
!ENDIF

cvars      = -DWIN32 -D_WIN32
cvarsmt    = $(cvars) -D_MT
cvarsdll   = $(cvarsmt) -D_DLL







######################################################################
# Project specific targets
######################################################################

release:    $(TCLSH) dlls
dlls:	    $(TCL16DLL) $(TCLPIPEDLL) $(TCLREGDLL)
all:	    $(TCLSH) dlls $(CAT16) $(CAT32) 
tcltest:    $(TCLTEST) dlls $(CAT16) $(CAT32)
plugin:	    $(TCLPLUGINDLL) $(TCLSHP)

test:	    $(TCLTEST) dlls $(CAT16) $(CAT32) 


	$(TCLTEST) <<
		cd ../tests
		source all
<<





$(DUMPEXTS): $(WINDIR)\winDumpExts.c
	$(cc32) $(CON_CFLAGS) -Fo$(TMPDIR)\ $?
	set LIB=$(TOOLS32)\lib
	$(link32) $(ldebug) $(conlflags) $(guilibs) -out:$@ \
		$(TMPDIR)\winDumpExts.obj 

$(TCLLIB): $(TCLDLL)

$(TCLDLL): $(TCLOBJS) $(TMPDIR)\tcl.def $(TMPDIR)\tcl.res
	set LIB=$(TOOLS32)\lib
	$(link32) $(ldebug) $(dlllflags) -def:$(TMPDIR)\tcl.def \
		-out:$@ $(TMPDIR)\tcl.res $(guilibsdll) @<<
$(TCLOBJS)
<<




$(TCLPLUGINLIB): $(TCLPLUGINDLL)

$(TCLPLUGINDLL): $(TCLOBJS) $(TMPDIR)\plugin.def $(TMPDIR)\tcl.res
	set LIB=$(TOOLS32)\lib
	$(link32) $(ldebug) $(dlllflags) -def:$(TMPDIR)\plugin.def \
		-out:$@ $(TMPDIR)\tcl.res $(guilibsdll) @<<
$(TCLOBJS)
<<

$(TCLSH): $(TCLSHOBJS) $(TCLLIB) $(TMPDIR)\tclsh.res
	set LIB=$(TOOLS32)\lib
	$(link32) $(ldebug) $(conlflags) $(TMPDIR)\tclsh.res -stack:2300000 \
		-out:$@ $(conlibsdll) $(TCLLIB) $(TCLSHOBJS) 

$(TCLSHP): $(TCLSHOBJS) $(TCLPLUGINLIB) $(TMPDIR)\tclsh.res
	set LIB=$(TOOLS32)\lib
	$(link32) $(ldebug) $(conlflags) $(TMPDIR)\tclsh.res -stack:2300000 \
		-out:$@ $(conlibsdll) $(TCLPLUGINLIB) $(TCLSHOBJS) 

$(TCLTEST): $(TCLTESTOBJS) $(TCLLIB) $(TMPDIR)\tclsh.res
	set LIB=$(TOOLS32)\lib
	$(link32) $(ldebug) $(conlflags) $(TMPDIR)\tclsh.res -stack:2300000 \
		 -out:$@ $(conlibsdll) $(TCLLIB) $(TCLTESTOBJS)

$(TCL16DLL):  $(WINDIR)\tcl16.rc $(WINDIR)\tclWin16.c
	if exist $(cc16) $(cc16) @<<
$(DLL16_CFLAGS) -Fo$(TMPDIR)\ $(WINDIR)\tclWin16.c
<<                         
	@copy << $(TMPDIR)\tclWin16.def > nul
LIBRARY $(@B);dll
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 1024 
EXPORTS






>
>
|








|
<
<










|
|


>
>



<
|
>

>
>




|
>
>
>
|

|
<
>
>
|
|
|
>
>
>
>
|
>





>
>
>
|

>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
|
>
>
>
>
>
|
|
|
|
>
>
>
>
>
>
|

>
>
|
|
|
|
>
>
>
>







>
>




|
|
>
>










>



>















>






>

>





>
>
>
>

>
>
>

>




>
>









>


>
>
|
|
|
|
>

|
|
|
|

|



|











|











|

|







|
|

|
|



|










|
>
|





|

















|
|

>
>
>
>
>
>





|
|
|
|
|
>
|
>
>
|
|
|


>
>
>
>


|






|





>
>
>



|






|









|






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
# Visual C++ 2.x and 4.0 makefile
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# RCS: @(#) $Id: makefile.vc,v 1.1.2.25 1999/04/06 19:19:11 surles Exp $

# Does not depend on the presence of any environment variables in
# order to compile tcl; all needed information is derived from 
# location of the compiler directories.

#
# Project directories
#
# ROOT	  = top of source tree


#
# TOOLS32 = location of VC++ 32-bit development tools. Note that the
#	    VC++ 2.0 header files are broken, so you need to use the
#	    ones that come with the developer network CD's, or later
#	    versions of VC++.
#
# TOOLS16 = location of VC++ 1.5 16-bit tools, needed to build thunking
#	    library.  This information is optional; if the 16-bit compiler
#	    is not available, then the 16-bit code will not be built.  
#	    Tcl will still run without the 16-bit code, but...
#		A. Under Windows 3.X any calls to the exec command
#		   will return an error.
#		B. A 16-bit program to test the behavior of the exec
#		   command under NT and 95 will not be built.
# INSTALLDIR = where the install- targets should copy the binaries and
#	    support files
#

ROOT		= ..

TOOLS32		= c:\program files\devstudio\vc
TOOLS32_rc	= c:\program files\devstudio\sharedide
TOOLS16		= c:\msvc

INSTALLDIR	= c:\program files\Tcl

# Set this to the appropriate value of /MACHINE: for your platform
MACHINE	= IX86

# Uncomment the following line to compile with thread support
#THREADDEFINES = -DTCL_THREADS=1

# Set NODEBUG to 0 to compile with symbols
NODEBUG = 1

# The following defines can be used to control the amount of debugging

# code that is added to the compilation.
#
#	-DTCL_MEM_DEBUG		Enables the debugging memory allocator.
#	-DTCL_COMPILE_DEBUG	Enables byte compilation logging.
#	-DTCL_COMPILE_STATS	Enables byte compilation statistics gathering.
#	-DUSE_TCLALLOC=0	Disables the Tcl memory allocator in favor
#				of the native malloc implementation.  This is
#				needed when using Purify.
#
#DEBUGDEFINES = -DTCL_MEM_DEBUG -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
#DEBUGDEFINES = -DUSE_TCLALLOC=0

######################################################################
# Do not modify below this line
######################################################################

NAMEPREFIX = tcl
STUBPREFIX = $(NAMEPREFIX)stub
DOTVERSION = 8.1
VERSION = 81

BINROOT		= .
!IF "$(NODEBUG)" == "1"
TMPDIRNAME	= Release
DBGX		=
!ELSE
TMPDIRNAME	= Debug
DBGX		= d
!ENDIF
TMPDIR		= $(BINROOT)\$(TMPDIRNAME)
OUTDIRNAME	= $(TMPDIRNAME)
OUTDIR		= $(TMPDIR)

TCLLIB		= $(OUTDIR)\$(NAMEPREFIX)$(VERSION)$(DBGX).lib
TCLDLLNAME	= $(NAMEPREFIX)$(VERSION)$(DBGX).dll
TCLDLL		= $(OUTDIR)\$(TCLDLLNAME)

TCLSTUBLIBNAME	= $(STUBPREFIX)$(VERSION)$(DBGX).lib
TCLSTUBLIB	= $(OUTDIR)\$(TCLSTUBLIBNAME)

TCLPLUGINLIB	= $(OUTDIR)\$(NAMEPREFIX)$(VERSION)p$(DBGX).lib
TCLPLUGINDLLNAME= $(NAMEPREFIX)$(VERSION)p$(DBGX).dll
TCLPLUGINDLL	= $(OUTDIR)\$(TCLPLUGINDLLNAME)
TCL16DLL	= $(OUTDIR)\$(NAMEPREFIX)16$(VERSION)$(DBGX).dll
TCLSH		= $(OUTDIR)\$(NAMEPREFIX)sh$(VERSION)$(DBGX).exe
TCLSHP		= $(OUTDIR)\$(NAMEPREFIX)shp$(VERSION)$(DBGX).exe
TCLPIPEDLLNAME	= $(NAMEPREFIX)pip$(VERSION)$(DBGX).dll
TCLPIPEDLL	= $(OUTDIR)\$(TCLPIPEDLLNAME)
TCLREGDLLNAME	= $(NAMEPREFIX)reg$(VERSION)$(DBGX).dll
TCLREGDLL	= $(OUTDIR)\$(TCLREGDLLNAME)
TCLDDEDLLNAME	= $(NAMEPREFIX)dde$(VERSION)$(DBGX).dll
TCLDDEDLL	= $(OUTDIR)\$(TCLDDEDLLNAME)
TCLTEST		= $(OUTDIR)\$(NAMEPREFIX)test.exe
DUMPEXTS	= $(TMPDIR)\dumpexts.exe
CAT16		= $(TMPDIR)\cat16.exe
CAT32		= $(TMPDIR)\cat32.exe
RMDIR		= .\rmd.bat
MKDIR		= .\mkd.bat
RM		= del

LIB_INSTALL_DIR	= $(INSTALLDIR)\lib
BIN_INSTALL_DIR	= $(INSTALLDIR)\bin
SCRIPT_INSTALL_DIR	= $(INSTALLDIR)\lib\tcl$(DOTVERSION)
INCLUDE_INSTALL_DIR	= $(INSTALLDIR)\include

TCLSHOBJS = \
	$(TMPDIR)\tclAppInit.obj

TCLTESTOBJS = \
	$(TMPDIR)\tclTest.obj \
	$(TMPDIR)\tclTestObj.obj \
	$(TMPDIR)\tclTestProcBodyObj.obj \
	$(TMPDIR)\tclThreadTest.obj \
	$(TMPDIR)\tclWinTest.obj \
	$(TMPDIR)\testMain.obj

TCLOBJS = \
	$(TMPDIR)\regcomp.obj \
	$(TMPDIR)\regexec.obj \
	$(TMPDIR)\regfree.obj \
	$(TMPDIR)\regerror.obj \
	$(TMPDIR)\strftime.obj \
	$(TMPDIR)\tclAlloc.obj \
	$(TMPDIR)\tclAsync.obj \
	$(TMPDIR)\tclBasic.obj \
	$(TMPDIR)\tclBinary.obj \
	$(TMPDIR)\tclCkalloc.obj \
	$(TMPDIR)\tclClock.obj \
	$(TMPDIR)\tclCmdAH.obj \
	$(TMPDIR)\tclCmdIL.obj \
	$(TMPDIR)\tclCmdMZ.obj \
	$(TMPDIR)\tclCompCmds.obj \
	$(TMPDIR)\tclCompExpr.obj \
	$(TMPDIR)\tclCompile.obj \
	$(TMPDIR)\tclDate.obj \
	$(TMPDIR)\tclEncoding.obj \
	$(TMPDIR)\tclEnv.obj \
	$(TMPDIR)\tclEvent.obj \
	$(TMPDIR)\tclExecute.obj \
	$(TMPDIR)\tclFCmd.obj \
	$(TMPDIR)\tclFileName.obj \
	$(TMPDIR)\tclGet.obj \
	$(TMPDIR)\tclHash.obj \
	$(TMPDIR)\tclHistory.obj \
	$(TMPDIR)\tclIndexObj.obj \
	$(TMPDIR)\tclInterp.obj \
	$(TMPDIR)\tclIO.obj \
	$(TMPDIR)\tclIOCmd.obj \
	$(TMPDIR)\tclIOSock.obj \
	$(TMPDIR)\tclIOUtil.obj \
	$(TMPDIR)\tclLink.obj \
	$(TMPDIR)\tclLiteral.obj \
	$(TMPDIR)\tclListObj.obj \
	$(TMPDIR)\tclLoad.obj \
	$(TMPDIR)\tclMain.obj \
	$(TMPDIR)\tclNamesp.obj \
	$(TMPDIR)\tclNotify.obj \
	$(TMPDIR)\tclObj.obj \
	$(TMPDIR)\tclPanic.obj \
	$(TMPDIR)\tclParse.obj \
	$(TMPDIR)\tclParseExpr.obj \
	$(TMPDIR)\tclPipe.obj \
	$(TMPDIR)\tclPkg.obj \
	$(TMPDIR)\tclPosixStr.obj \
	$(TMPDIR)\tclPreserve.obj \
	$(TMPDIR)\tclProc.obj \
	$(TMPDIR)\tclRegexp.obj \
	$(TMPDIR)\tclResolve.obj \
	$(TMPDIR)\tclResult.obj \
	$(TMPDIR)\tclScan.obj \
	$(TMPDIR)\tclStringObj.obj \
	$(TMPDIR)\tclStubInit.obj \
	$(TMPDIR)\tclStubLib.obj \
	$(TMPDIR)\tclThread.obj \
	$(TMPDIR)\tclTimer.obj \
	$(TMPDIR)\tclUtf.obj \
	$(TMPDIR)\tclUtil.obj \
	$(TMPDIR)\tclVar.obj \
	$(TMPDIR)\tclWin32Dll.obj \
	$(TMPDIR)\tclWinChan.obj \
	$(TMPDIR)\tclWinConsole.obj \
	$(TMPDIR)\tclWinSerial.obj \
	$(TMPDIR)\tclWinError.obj \
	$(TMPDIR)\tclWinFCmd.obj \
	$(TMPDIR)\tclWinFile.obj \
	$(TMPDIR)\tclWinInit.obj \
	$(TMPDIR)\tclWinLoad.obj \
	$(TMPDIR)\tclWinMtherr.obj \
	$(TMPDIR)\tclWinNotify.obj \
	$(TMPDIR)\tclWinPipe.obj \
	$(TMPDIR)\tclWinSock.obj \
	$(TMPDIR)\tclWinThrd.obj \
	$(TMPDIR)\tclWinTime.obj 

TCLSTUBOBJS = $(TMPDIR)\tclStubLib.obj \

cc32		= "$(TOOLS32)\bin\cl.exe"
link32		= "$(TOOLS32)\bin\link.exe"
rc32		= "$(TOOLS32_rc)\bin\rc.exe"
include32	= -I"$(TOOLS32)\include"
lib32		= "$(TOOLS32)\bin\lib.exe"

cc16		= "$(TOOLS16)\bin\cl.exe"
link16		= "$(TOOLS16)\bin\link.exe"
rc16		= "$(TOOLS16)\bin\rc.exe"
include16	= -I"$(TOOLS16)\include"

WINDIR		= $(ROOT)\win
GENERICDIR	= $(ROOT)\generic

TCL_INCLUDES	= -I$(WINDIR) -I$(GENERICDIR)
TCL_DEFINES	= -D__WIN32__ $(DEBUGDEFINES) $(THREADDEFINES)

TCL_CFLAGS	= $(cdebug) $(cflags) $(cvarsdll) $(include32) \
			$(TCL_INCLUDES) $(TCL_DEFINES)
CON_CFLAGS	= $(cdebug) $(cflags) $(cvars) $(include32) -DCONSOLE
DOS_CFLAGS	= $(cdebug) $(cflags) $(include16) -AL 
DLL16_CFLAGS	= $(cdebug) $(cflags) $(include16) -ALw

######################################################################
# Link flags
######################################################################

!IF "$(NODEBUG)" == "1"
ldebug = /RELEASE
!ELSE
ldebug = -debug:full -debugtype:cv
!ENDIF

# declarations common to all linker options
lcommon = /NODEFAULTLIB /RELEASE /NOLOGO

# declarations for use on Intel i386, i486, and Pentium systems
!IF "$(MACHINE)" == "IX86"
DLLENTRY = @12
lflags	 = $(lcommon) /MACHINE:$(MACHINE)
!ELSE
lflags	 = $(lcommon) /MACHINE:$(MACHINE)
!ENDIF

conlflags = $(lflags) -subsystem:console -entry:mainCRTStartup
guilflags = $(lflags) -subsystem:windows -entry:WinMainCRTStartup
dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll

!IF "$(MACHINE)" == "PPC"
libc = libc$(DBGX).lib
libcdll = crtdll$(DBGX).lib
!ELSE
libc = libc$(DBGX).lib oldnames.lib
libcdll = msvcrt$(DBGX).lib oldnames.lib
!ENDIF

baselibs   = kernel32.lib $(optlibs) advapi32.lib user32.lib
winlibs	   = $(baselibs) gdi32.lib comdlg32.lib winspool.lib

guilibs	   = $(libc) $(winlibs)
conlibs	   = $(libc) $(baselibs)
guilibsdll = $(libcdll) $(winlibs)
conlibsdll = $(libcdll) $(baselibs)

######################################################################
# Compile flags
######################################################################

!IF "$(NODEBUG)" == "1"
# This cranks the optimization level to maximize speed
cdebug = -O2 -Gs -GD
!ELSE
cdebug = -Z7 -Od -WX
!ENDIF

# declarations common to all compiler options
ccommon = -c -W3 -nologo -YX -Fp$(TMPDIR)\ -Dtry=__try -Dexcept=__except

!IF "$(MACHINE)" == "IX86"
cflags = $(ccommon) -D_X86_=1
!ELSE
!IF "$(MACHINE)" == "MIPS"
cflags = $(ccommon) -D_MIPS_=1
!ELSE
!IF "$(MACHINE)" == "PPC"
cflags = $(ccommon) -D_PPC_=1
!ELSE
!IF "$(MACHINE)" == "ALPHA"
cflags = $(ccommon) -D_ALPHA_=1
!ENDIF
!ENDIF
!ENDIF
!ENDIF

cvars	   = -DWIN32 -D_WIN32
cvarsmt	   = $(cvars) -D_MT
cvarsdll   = $(cvarsmt) -D_DLL

!IF "$(NODEBUG)" == "1"
cvarsdll   = $(cvars) -MD
!ELSE
cvarsdll   = $(cvars) -MDd
!ENDIF

######################################################################
# Project specific targets
######################################################################

release:    setup $(TCLSH) dlls
dlls:	    setup $(TCL16DLL) $(TCLPIPEDLL) $(TCLREGDLL) $(TCLDDEDLL)
all:	    setup $(TCLSH) dlls $(CAT16) $(CAT32) 
tcltest:    setup $(TCLTEST) dlls $(CAT16) $(CAT32)
plugin:	    setup $(TCLPLUGINDLL) $(TCLSHP)
install:    install-binaries install-libraries
test:	    setup $(TCLTEST) dlls $(CAT16) $(CAT32)
	copy $(WINDIR)\pkgIndex.tcl $(OUTDIR)
	set TCL_LIBRARY=$(ROOT)/library
	$(TCLTEST) << "$(TCLREGDLL)"
		load [lindex $$argv 0] registry
		source $(ROOT)/tests/all.tcl
<<

setup:
	@$(MKDIR) $(TMPDIR)
	@$(MKDIR) $(OUTDIR)

$(DUMPEXTS): $(WINDIR)\winDumpExts.c
	$(cc32) $(CON_CFLAGS) -Fo$(TMPDIR)\ $?
	set LIB="$(TOOLS32)\lib"
	$(link32) $(ldebug) $(conlflags) $(guilibs) -out:$@ \
		$(TMPDIR)\winDumpExts.obj 

$(TCLLIB): $(TCLDLL)

$(TCLDLL): $(TCLOBJS) $(TMPDIR)\tcl.def $(TMPDIR)\tcl.res
	set LIB="$(TOOLS32)\lib"
	$(link32) $(ldebug) $(dlllflags) -def:$(TMPDIR)\tcl.def \
		-out:$@ $(TMPDIR)\tcl.res $(guilibsdll) @<<
$(TCLOBJS)
<<

$(TCLSTUBLIB): $(TCLSTUBOBJS)
	$(lib32) /out:$@ $(TCLSTUBOBJS)

$(TCLPLUGINLIB): $(TCLPLUGINDLL)

$(TCLPLUGINDLL): $(TCLOBJS) $(TMPDIR)\plugin.def $(TMPDIR)\tcl.res
	set LIB="$(TOOLS32)\lib"
	$(link32) $(ldebug) $(dlllflags) -def:$(TMPDIR)\plugin.def \
		-out:$@ $(TMPDIR)\tcl.res $(guilibsdll) @<<
$(TCLOBJS)
<<

$(TCLSH): $(TCLSHOBJS) $(TCLLIB) $(TMPDIR)\tclsh.res
	set LIB="$(TOOLS32)\lib"
	$(link32) $(ldebug) $(conlflags) $(TMPDIR)\tclsh.res -stack:2300000 \
		-out:$@ $(conlibsdll) $(TCLLIB) $(TCLSHOBJS) 

$(TCLSHP): $(TCLSHOBJS) $(TCLPLUGINLIB) $(TMPDIR)\tclsh.res
	set LIB=$(TOOLS32)\lib
	$(link32) $(ldebug) $(conlflags) $(TMPDIR)\tclsh.res -stack:2300000 \
		-out:$@ $(conlibsdll) $(TCLPLUGINLIB) $(TCLSHOBJS) 

$(TCLTEST): $(TCLTESTOBJS) $(TCLLIB) $(TMPDIR)\tclsh.res
	set LIB="$(TOOLS32)\lib"
	$(link32) $(ldebug) $(conlflags) $(TMPDIR)\tclsh.res -stack:2300000 \
		 -out:$@ $(conlibsdll) $(TCLLIB) $(TCLTESTOBJS)

$(TCL16DLL):  $(WINDIR)\tcl16.rc $(WINDIR)\tclWin16.c
	if exist $(cc16) $(cc16) @<<
$(DLL16_CFLAGS) -Fo$(TMPDIR)\ $(WINDIR)\tclWin16.c
<<			   
	@copy << $(TMPDIR)\tclWin16.def > nul
LIBRARY $(@B);dll
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 1024 
EXPORTS
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



$(TOOLS16)\lib\ ldllcew oldnames libw toolhelp
$(TMPDIR)\tclWin16.def
<<
	if exist $(cc16) $(rc16) -i $(GENERICDIR) $(TCL_DEFINES) $(WINDIR)\tcl16.rc $@

$(TCLPIPEDLL): $(WINDIR)\stub16.c
	$(cc32) $(CON_CFLAGS) -Fo$(TMPDIR)\ $(WINDIR)\stub16.c
	set LIB=$(TOOLS32)\lib
	$(link32) $(ldebug) $(conlflags) -out:$@ $(TMPDIR)\stub16.obj $(guilibs)






$(TCLREGDLL): $(TMPDIR)\tclWinReg.obj
	set LIB=$(TOOLS32)\lib
	$(link32) $(ldebug) $(dlllflags) -out:$@ $(TMPDIR)\tclWinReg.obj \
		$(conlibsdll) $(TCLLIB)

$(CAT32): $(WINDIR)\cat.c
	$(cc32) $(CON_CFLAGS) -Fo$(TMPDIR)\ $?
	set LIB=$(TOOLS32)\lib
	$(link32) $(conlflags) -out:$@ -stack:16384 $(TMPDIR)\cat.obj $(conlibs)

$(CAT16): $(WINDIR)\cat.c
	if exist $(cc16) $(cc16) $(DOS_CFLAGS) -Fo$(TMPDIR)\ $?
	set LIB=$(TOOLS16)\lib
	if exist $(cc16) $(link16) /NOLOGO /ONERROR:NOEXE /NOI /STACK:16384 \
		$(TMPDIR)\cat.obj,$@,nul,llibce.lib,nul

$(TMPDIR)\tcl.def: $(DUMPEXTS) $(TCLOBJS)
	$(DUMPEXTS) -o $@ $(TCLDLL) @<<
$(TCLOBJS)
<<

$(TMPDIR)\plugin.def: $(DUMPEXTS) $(TCLOBJS)
	$(DUMPEXTS) -o $@ $(TCLPLUGINDLL) @<<
$(TCLOBJS)
<<

















#





































# Special case object file targets
#




$(TMPDIR)\testMain.obj: $(WINDIR)\tclAppInit.c
	$(cc32) $(TCL_CFLAGS) -DTCL_TEST -Fo$(TMPDIR)\testMain.obj $?



#














































# Implicit rules
#

{$(WINDIR)}.c{$(TMPDIR)}.obj:
    $(cc32) $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<

{$(GENERICDIR)}.c{$(TMPDIR)}.obj:
    $(cc32) $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<

{$(ROOT)\compat}.c{$(TMPDIR)}.obj:
    $(cc32) $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<

{$(WINDIR)}.rc{$(TMPDIR)}.res:
	$(rc32) -fo $@ -r -i $(GENERICDIR) -i $(WINDIR) -D__WIN32__ \
		$(TCL_DEFINES) $<

clean:
        -@del *.exp 
	-@del *.lib 
	-@del *.dll 
	-@del *.exe


        -@del $(TMPDIR)\*.obj
        -@del $(TMPDIR)\*.res
        -@del $(TMPDIR)\*.def










|


>
>
>
>
>
|
|

|



|









|




|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
>
>



>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|


|


|






|
|
|
|
>
>
|
|
|
>
>
>
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
$(TOOLS16)\lib\ ldllcew oldnames libw toolhelp
$(TMPDIR)\tclWin16.def
<<
	if exist $(cc16) $(rc16) -i $(GENERICDIR) $(TCL_DEFINES) $(WINDIR)\tcl16.rc $@

$(TCLPIPEDLL): $(WINDIR)\stub16.c
	$(cc32) $(CON_CFLAGS) -Fo$(TMPDIR)\ $(WINDIR)\stub16.c
	set LIB="$(TOOLS32)\lib"
	$(link32) $(ldebug) $(conlflags) -out:$@ $(TMPDIR)\stub16.obj $(guilibs)

$(TCLDDEDLL): $(TMPDIR)\tclWinDde.obj $(TCLSTUBLIB)
	set LIB="$(TOOLS32)\lib"
	$(link32) $(ldebug) $(dlllflags) -out:$@ $(TMPDIR)\tclWinDde.obj \
		$(conlibsdll) $(TCLSTUBLIB)

$(TCLREGDLL): $(TMPDIR)\tclWinReg.obj $(TCLSTUBLIB)
	set LIB="$(TOOLS32)\lib"
	$(link32) $(ldebug) $(dlllflags) -out:$@ $(TMPDIR)\tclWinReg.obj \
		$(conlibsdll) $(TCLSTUBLIB)

$(CAT32): $(WINDIR)\cat.c
	$(cc32) $(CON_CFLAGS) -Fo$(TMPDIR)\ $?
	set LIB="$(TOOLS32)\lib"
	$(link32) $(conlflags) -out:$@ -stack:16384 $(TMPDIR)\cat.obj $(conlibs)

$(CAT16): $(WINDIR)\cat.c
	if exist $(cc16) $(cc16) $(DOS_CFLAGS) -Fo$(TMPDIR)\ $?
	set LIB=$(TOOLS16)\lib
	if exist $(cc16) $(link16) /NOLOGO /ONERROR:NOEXE /NOI /STACK:16384 \
		$(TMPDIR)\cat.obj,$@,nul,llibce.lib,nul

$(TMPDIR)\tcl.def: $(DUMPEXTS) $(TCLOBJS)
	$(DUMPEXTS) -o $@ $(TCLDLLNAME) @<<
$(TCLOBJS)
<<

$(TMPDIR)\plugin.def: $(DUMPEXTS) $(TCLOBJS)
	$(DUMPEXTS) -o $@ $(TCLPLUGINDLLNAME) @<<
$(TCLOBJS)
<<

install-binaries: $(TCLSH)
	$(MKDIR) "$(BIN_INSTALL_DIR)"
	$(MKDIR) "$(LIB_INSTALL_DIR)"
	@echo installing $(TCLDLLNAME)
	@copy "$(TCLDLL)" "$(BIN_INSTALL_DIR)"
	@copy "$(TCLLIB)" "$(LIB_INSTALL_DIR)"
	@echo installing "$(TCLSH)"
	@copy "$(TCLSH)" "$(BIN_INSTALL_DIR)"
	@echo installing $(TCLPIPEDLLNAME)
	@copy "$(TCLPIPEDLL)" "$(BIN_INSTALL_DIR)"
	@echo installing $(TCLREGDLLNAME)
	@copy "$(TCLREGDLL)" "$(LIB_INSTALL_DIR)"
	@echo installing $(TCLDDEDLLNAME)
	@copy "$(TCLDDEDLL)" "$(LIB_INSTALL_DIR)"
	@echo installing $(TCLSTUBLIBNAME)
	@copy "$(TCLSTUBLIB)" "$(LIB_INSTALL_DIR)"

install-libraries:
	-@$(MKDIR) "$(LIB_INSTALL_DIR)"
	-@$(MKDIR) "$(INCLUDE_INSTALL_DIR)"
	-@$(MKDIR) "$(SCRIPT_INSTALL_DIR)"
	-@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\http1.0"
	@copy << "$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
package ifneeded registry 1.0 "load [list [file join $$dir .. $(TCLREGDLLNAME)]] registry"
package ifneeded dde 1.0 "load [list [file join $$dir .. $(TCLDDEDLLNAME)]] dde"
<<
	-@copy "$(ROOT)\library\http1.0\http.tcl"     "$(SCRIPT_INSTALL_DIR)\http1.0"
	-@copy "$(ROOT)\library\http1.0\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\http1.0"
	-@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\http2.0"
	-@copy "$(ROOT)\library\http2.0\http.tcl"     "$(SCRIPT_INSTALL_DIR)\http2.0"
	-@copy "$(ROOT)\library\http2.0\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\http2.0"
	-@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\opt0.4"
	-@copy "$(ROOT)\library\opt0.4\optparse.tcl" "$(SCRIPT_INSTALL_DIR)\opt0.4"
	-@copy "$(ROOT)\library\opt0.4\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\opt0.4"
	-@copy "$(GENERICDIR)\tcl.h"         "$(INCLUDE_INSTALL_DIR)"
	-@copy "$(ROOT)\library\history.tcl" "$(SCRIPT_INSTALL_DIR)"
	-@copy "$(ROOT)\library\init.tcl"    "$(SCRIPT_INSTALL_DIR)"
	-@copy "$(ROOT)\library\ldAout.tcl"  "$(SCRIPT_INSTALL_DIR)"
	-@copy "$(ROOT)\library\parray.tcl"  "$(SCRIPT_INSTALL_DIR)"
	-@copy "$(ROOT)\library\safe.tcl"    "$(SCRIPT_INSTALL_DIR)"
	-@copy "$(ROOT)\library\tclIndex"    "$(SCRIPT_INSTALL_DIR)"
	-@copy "$(ROOT)\library\package.tcl" "$(SCRIPT_INSTALL_DIR)"
	-@copy "$(ROOT)\library\word.tcl"    "$(SCRIPT_INSTALL_DIR)"
	-@copy "$(ROOT)\library\auto.tcl"    "$(SCRIPT_INSTALL_DIR)"

#
# Regenerate the stubs files.
#

genstubs:
	tclsh$(VERSION) $(ROOT)\tools\genStubs.tcl $(GENERICDIR) \
		$(GENERICDIR)\tcl.decls $(GENERICDIR)\tclInt.decls

#
# Special case object file targets
#

$(TMPDIR)\tclWinInit.obj: $(WINDIR)\tclWinInit.c
	$(cc32) -DBUILD_tcl $(TCL_CFLAGS) $(EXTFLAGS) -Fo$(TMPDIR)\ $?

$(TMPDIR)\testMain.obj: $(WINDIR)\tclAppInit.c
	$(cc32) $(TCL_CFLAGS) -DTCL_TEST -Fo$(TMPDIR)\testMain.obj $?

$(TMPDIR)\tclTest.obj: $(GENERICDIR)\tclTest.c
	$(cc32) $(TCL_CFLAGS) -Fo$@ $?

$(TMPDIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c
	$(cc32) $(TCL_CFLAGS) -Fo$@ $?

$(TMPDIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c
	$(cc32) $(TCL_CFLAGS) -Fo$@ $?

$(TMPDIR)\tclAppInit.obj : $(WINDIR)\tclAppInit.c
	$(cc32) $(TCL_CFLAGS) -Fo$@ $?

# The following objects should be built using the stub interfaces

$(TMPDIR)\tclWinReg.obj : $(WINDIR)\tclWinReg.c
	$(cc32) $(TCL_CFLAGS) -DUSE_TCL_STUBS -Fo$@ $?

$(TMPDIR)\tclWinDde.obj : $(WINDIR)\tclWinDde.c
	$(cc32) $(TCL_CFLAGS) -DUSE_TCL_STUBS -Fo$@ $?

# The following objects are part of the stub library and should not
# be built as DLL objects but none of the symbols should be exported

$(TMPDIR)\tclStubLib.obj : $(GENERICDIR)\tclStubLib.c
	$(cc32) $(TCL_CFLAGS) -DSTATIC_BUILD -Fo$@ $?


# Dedependency rules

$(GENERICDIR)\regcomp.c: \
	$(GENERICDIR)\regguts.h \
	$(GENERICDIR)\regc_lex.c \
	$(GENERICDIR)\regc_color.c \
	$(GENERICDIR)\regc_nfa.c \
	$(GENERICDIR)\regc_cvec.c \
	$(GENERICDIR)\regc_locale.c
$(GENERICDIR)\regcustom.h: \
	$(GENERICDIR)\tclInt.h \
	$(GENERICDIR)\tclPort.h \
	$(GENERICDIR)\regex.h
$(GENERICDIR)\regexec.c: \
	$(GENERICDIR)\rege_dfa.c \
	$(GENERICDIR)\regguts.h
$(GENERICDIR)\regerror.c: $(GENERICDIR)\regguts.h
$(GENERICDIR)\regfree.c: $(GENERICDIR)\regguts.h
$(GENERICDIR)\regfronts.c: $(GENERICDIR)\regguts.h
$(GENERICDIR)\regguts.h: $(GENERICDIR)\regcustom.h

#
# Implicit rules
#

{$(WINDIR)}.c{$(TMPDIR)}.obj:
    $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<

{$(GENERICDIR)}.c{$(TMPDIR)}.obj:
    $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<

{$(ROOT)\compat}.c{$(TMPDIR)}.obj:
    $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<

{$(WINDIR)}.rc{$(TMPDIR)}.res:
	$(rc32) -fo $@ -r -i $(GENERICDIR) -i $(WINDIR) -D__WIN32__ \
		$(TCL_DEFINES) $<

clean:
	-@$(RM) $(OUTDIR)\*.exp 
	-@$(RM) $(OUTDIR)\*.lib 
	-@$(RM) $(OUTDIR)\*.dll 
	-@$(RM) $(OUTDIR)\*.exe
	-@$(RM) $(OUTDIR)\*.pdb
	-@$(RM) $(TMPDIR)\*.pch
	-@$(RM) $(TMPDIR)\*.obj
	-@$(RM) $(TMPDIR)\*.res
	-@$(RM) $(TMPDIR)\*.def
	-@$(RM) $(TMPDIR)\*.exe
	-@$(RMDIR) $(OUTDIR)
	-@$(RMDIR) $(TMPDIR)

Added win/mkd.bat.











































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@echo off
rem RCS: @(#) $Id: mkd.bat,v 1.1.2.2 1998/10/06 03:09:26 stanton Exp $

if exist %1\tag.txt goto end

if "%OS%" == "Windows_NT" goto winnt

md %1
if errorlevel 1 goto end

goto success

:winnt
md %1
if errorlevel 1 goto end

:success
echo TAG >%1\tag.txt
echo created directory %1

:end

Changes to win/pkgIndex.tcl.

1
2
3
4
5
6
7
8
9
10
11

# 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.
# 
# SCCS: @(#) pkgIndex.tcl 1.1 97/06/23 14:25:47

package ifneeded registry 1.0 [list tclPkgSetup $dir registry 1.0 {{tclreg80.dll load registry}}]









|

|
>
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.1.2.3 1999/04/02 23:48:34 redman 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}}]

Added win/rmd.bat.



















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
@echo off
rem RCS: @(#) $Id: rmd.bat,v 1.1.2.2 1998/10/06 03:09:26 stanton Exp $

if not exist %1\tag.txt goto end

echo Removing directory %1

if "%OS%" == "Windows_NT" goto winnt

cd %1
if errorlevel 1 goto end
del *.*
cd ..
rmdir %1
if errorlevel 1 goto end
goto success

:winnt
rmdir %1 /s /q
if errorlevel 1 goto end

:success
echo deleted directory %1

:end

Changes to win/stub16.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * stub16.c 
 *
 *	A helper program used for running 16-bit DOS applications under
 *	Windows 95.
 *
 * Copyright (c) 1996 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.
 *
 * SCCS: @(#) stub16.c 1.5 96/12/11 20:01:58
 */

#define STRICT

#include <windows.h>
#include <stdio.h>












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 
 * stub16.c 
 *
 *	A helper program used for running 16-bit DOS applications under
 *	Windows 95.
 *
 * Copyright (c) 1996 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: stub16.c,v 1.1.2.1 1998/09/24 23:59:49 stanton Exp $
 */

#define STRICT

#include <windows.h>
#include <stdio.h>

Changes to win/tcl.rc.

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
// SCCS: @(#) tcl.rc 1.24 97/04/01 19:19:43
//
// Version
//

#define RESOURCE_INCLUDED
#include <tcl.h>



VS_VERSION_INFO VERSIONINFO
 FILEVERSION 	TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
 PRODUCTVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
 FILEFLAGSMASK 	0x3fL
 FILEFLAGS 	0x0L
 FILEOS 	0x4L
 FILETYPE 	0x2L
 FILESUBTYPE 	0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        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 \251 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
    END
END

|







>
>





|
|




|





|


|







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
// RCS: @(#) $Id: tcl.rc,v 1.1.2.2 1998/09/24 23:59:50 stanton Exp $
//
// Version
//

#define RESOURCE_INCLUDED
#include <tcl.h>

LANGUAGE 0x9, 0x1	/* LANG_ENGLISH, SUBLANG_DEFAULT */

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 	TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
 PRODUCTVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
 FILEFLAGSMASK 	0x3fL
 FILEFLAGS 	0x0L
 FILEOS 	0x4	/* VOS__WINDOWS32 */
 FILETYPE 	0x2	/* VFT_DLL */
 FILESUBTYPE 	0x0L
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
    END
END

Changes to win/tcl16.rc.

1
2
3
4
5
6
7
8
// SCCS: @(#) tcl16.rc 1.17 96/09/18 18:19:00
//
// Version
//

#define RESOURCE_INCLUDED
#include <tcl.h>

|







1
2
3
4
5
6
7
8
// RCS: @(#) $Id: tcl16.rc,v 1.1.2.1 1998/09/24 23:59:50 stanton Exp $
//
// Version
//

#define RESOURCE_INCLUDED
#include <tcl.h>

Changes to win/tclAppInit.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
/* 
 * tclAppInit.c --
 *
 *	Provides a default version of the main program and Tcl_AppInit
 *	procedure for Tcl applications (without Tk).  Note that this
 *	program must be built in Win32 console mode to work properly.
 *
 * Copyright (c) 1996 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.
 *
 * SCCS: @(#) tclAppInit.c 1.12 97/04/30 11:04:50
 */

#include "tcl.h"
#include <windows.h>
#include <locale.h>

#ifdef TCL_TEST


EXTERN int		Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int		TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp));



#endif /* TCL_TEST */

static void		setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));


/*
 *----------------------------------------------------------------------







|
>




|







>
>
|
|
>
>
>







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
/* 
 * tclAppInit.c --
 *
 *	Provides a default version of the main program and Tcl_AppInit
 *	procedure for Tcl applications (without Tk).  Note that this
 *	program must be built in Win32 console mode to work properly.
 *
 * Copyright (c) 1996-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: tclAppInit.c,v 1.1.2.4 1999/02/10 23:31:28 stanton Exp $
 */

#include "tcl.h"
#include <windows.h>
#include <locale.h>

#ifdef TCL_TEST
extern int		Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp));
extern int		Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
extern int		Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
extern int		TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp));
#ifdef TCL_THREADS
extern int		TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp));
#endif
#endif /* TCL_TEST */

static void		setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));


/*
 *----------------------------------------------------------------------
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
 */

int
main(argc, argv)
    int argc;			/* Number of command-line arguments. */
    char **argv;		/* Values of command-line arguments. */
{
    char *p;
    char buffer[MAX_PATH];

    /*
     * Set up the default locale to be standard "C" locale so parsing
     * is performed correctly.
     */

    setlocale(LC_ALL, "C");

    setargv(&argc, &argv);

    /*
     * Replace argv[0] with full pathname of executable, and forward
     * slashes substituted for backslashes.
     */

    GetModuleFileName(NULL, buffer, sizeof(buffer));
    argv[0] = buffer;
    for (p = buffer; *p != '\0'; p++) {
	if (*p == '\\') {
	    *p = '/';
	}
    }

    Tcl_Main(argc, argv, Tcl_AppInit);
    return 0;			/* Needed only to prevent compiler warning. */
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppInit --
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in interp->result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */








<
<
<






<


<
<
<
<
<
<
<
<
<
<
<
<
<
















|







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
 */

int
main(argc, argv)
    int argc;			/* Number of command-line arguments. */
    char **argv;		/* Values of command-line arguments. */
{



    /*
     * Set up the default locale to be standard "C" locale so parsing
     * is performed correctly.
     */

    setlocale(LC_ALL, "C");

    setargv(&argc, &argv);














    Tcl_Main(argc, argv, Tcl_AppInit);
    return 0;			/* Needed only to prevent compiler warning. */
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_AppInit --
 *
 *	This procedure performs application-specific initialization.
 *	Most applications, especially those that incorporate additional
 *	packages, will have their own version of this procedure.
 *
 * Results:
 *	Returns a standard Tcl completion code, and leaves an error
 *	message in the interp's result if an error occurs.
 *
 * Side effects:
 *	Depends on the startup script.
 *
 *----------------------------------------------------------------------
 */

109
110
111
112
113
114
115










116
117
118
119
120
121
122
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
            (Tcl_PackageInitProc *) NULL);
    if (TclObjTest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }










#endif /* TCL_TEST */

    /*
     * Call the init procedures for included packages.  Each call should
     * look like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {







>
>
>
>
>
>
>
>
>
>







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
            (Tcl_PackageInitProc *) NULL);
    if (TclObjTest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
#ifdef TCL_THREADS
    if (TclThread_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
#endif
    if (Procbodytest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init,
            Procbodytest_SafeInit);
#endif /* TCL_TEST */

    /*
     * Call the init procedures for included packages.  Each call should
     * look like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {
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
    int *argcPtr;		/* Filled with number of argument strings. */
    char ***argvPtr;		/* Filled with argument strings (malloc'd). */
{
    char *cmdLine, *p, *arg, *argSpace;
    char **argv;
    int argc, size, inquote, copy, slashes;
    
    cmdLine = GetCommandLine();

    /*
     * Precompute an overly pessimistic guess at the number of arguments
     * in the command line by counting non-space spans.
     */

    size = 2;
    for (p = cmdLine; *p != '\0'; p++) {
	if (isspace(*p)) {
	    size++;
	    while (isspace(*p)) {
		p++;
	    }
	    if (*p == '\0') {
		break;
	    }
	}
    }
    argSpace = (char *) ckalloc((unsigned) (size * sizeof(char *) 
	    + strlen(cmdLine) + 1));
    argv = (char **) argSpace;
    argSpace += size * sizeof(char *);
    size--;

    p = cmdLine;
    for (argc = 0; argc < size; argc++) {
	argv[argc] = arg = argSpace;
	while (isspace(*p)) {
	    p++;
	}
	if (*p == '\0') {
	    break;
	}

	inquote = 0;







|








|

|







|
|







|







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
    int *argcPtr;		/* Filled with number of argument strings. */
    char ***argvPtr;		/* Filled with argument strings (malloc'd). */
{
    char *cmdLine, *p, *arg, *argSpace;
    char **argv;
    int argc, size, inquote, copy, slashes;
    
    cmdLine = GetCommandLine();	/* INTL: BUG */

    /*
     * Precompute an overly pessimistic guess at the number of arguments
     * in the command line by counting non-space spans.
     */

    size = 2;
    for (p = cmdLine; *p != '\0'; p++) {
	if ((*p == ' ') || (*p == '\t')) {	/* INTL: ISO space. */
	    size++;
	    while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */
		p++;
	    }
	    if (*p == '\0') {
		break;
	    }
	}
    }
    argSpace = (char *) Tcl_Alloc(
	    (unsigned) (size * sizeof(char *) + strlen(cmdLine) + 1));
    argv = (char **) argSpace;
    argSpace += size * sizeof(char *);
    size--;

    p = cmdLine;
    for (argc = 0; argc < size; argc++) {
	argv[argc] = arg = argSpace;
	while ((*p == ' ') || (*p == '\t')) {	/* INTL: ISO space. */
	    p++;
	}
	if (*p == '\0') {
	    break;
	}

	inquote = 0;
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250

            while (slashes) {
		*arg = '\\';
		arg++;
		slashes--;
	    }

	    if ((*p == '\0') || (!inquote && isspace(*p))) {

		break;
	    }
	    if (copy != 0) {
		*arg = *p;
		arg++;
	    }
	    p++;







|
>







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

            while (slashes) {
		*arg = '\\';
		arg++;
		slashes--;
	    }

	    if ((*p == '\0')
		    || (!inquote && ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */
		break;
	    }
	    if (copy != 0) {
		*arg = *p;
		arg++;
	    }
	    p++;

Changes to win/tclWin16.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * tclWin16.c --
 *
 *      This file contains code for a 16-bit DLL to handle 32-to-16 bit
 *      thunking. This is necessary for the Win32s SynchSpawn() call.
 *
 * 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.
 *
 * SCCS: @(#) tclWin16.c 1.18 97/05/23 13:13:32
 */

#define STRICT

#include <windows.h>  
#include <toolhelp.h> 












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * tclWin16.c --
 *
 *      This file contains code for a 16-bit DLL to handle 32-to-16 bit
 *      thunking. This is necessary for the Win32s SynchSpawn() call.
 *
 * 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: tclWin16.c,v 1.1.2.1 1998/09/24 23:59:50 stanton Exp $
 */

#define STRICT

#include <windows.h>  
#include <toolhelp.h> 

Changes to win/tclWin32Dll.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
/* 

 * tclWin32Dll.c --
 *
 *	This file contains the DLL entry point which sets up the 32-to-16-bit
 *	thunking code for SynchSpawn if the library is running under Win32s.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclWin32Dll.c 1.21 97/08/05 11:47:10
 */

#include "tclWinInt.h"






typedef DWORD (WINAPI * UT32PROC)(LPVOID lpBuff, DWORD dwUserDefined,
	LPVOID *lpTranslationList);

typedef BOOL (WINAPI * PUTREGISTER)(HANDLE hModule, LPCSTR SixteenBitDLL,
	LPCSTR InitName, LPCSTR ProcName, UT32PROC* ThirtyTwoBitThunk,
	FARPROC UT32Callback, LPVOID Buff);

typedef VOID (WINAPI * PUTUNREGISTER)(HANDLE hModule);






static PUTUNREGISTER UTUnRegister = NULL;

static int           tclProcessesAttached = 0;

/*
 * The following data structure is used to keep track of all of the DLL's
 * opened by Tcl so that they can be freed with the Tcl.dll is unloaded.


 */



typedef struct LibraryList {
























    HINSTANCE handle;
    struct LibraryList *nextPtr;
} LibraryList;









static LibraryList *libraryList = NULL;	/* List of currently loaded DLL's.  */


























static HINSTANCE tclInstance;	/* Global library instance handle. */
static int tclPlatformId;	/* Running under NT, 95, or Win32s? */

/*
 * Declarations for functions that are only used in this file.
 */









static void 		UnloadLibraries _ANSI_ARGS_((void));

/*
 * The following declaration is for the VC++ DLL entry point.
 */

BOOL APIENTRY		DllMain _ANSI_ARGS_((HINSTANCE hInst,
			    DWORD reason, LPVOID reserved));






/*
 *----------------------------------------------------------------------
 *
 * DllEntryPoint --
 *
 *	This wrapper function is used by Borland to invoke the

>










|




>
>
>
>
>
|


|
|


|

>
>
>
>
>
|
>
|


|
<
>
>


>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
>
>
>
>
>
>
>
>

|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
|
<
<
<
>
>
>
>
>
>
>

>
|





|
|
>
>
>
>
>







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
/* 

 * tclWin32Dll.c --
 *
 *	This file contains the DLL entry point which sets up the 32-to-16-bit
 *	thunking code for SynchSpawn if the library is running under Win32s.
 *
 * Copyright (c) 1995-1996 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: tclWin32Dll.c,v 1.1.2.5 1999/04/14 00:34:01 surles Exp $
 */

#include "tclWinInt.h"

/*
 * The following data structures are used when loading the thunking 
 * library for execing child processes under Win32s.
 */

typedef DWORD (WINAPI UT32PROC)(LPVOID lpBuff, DWORD dwUserDefined,
	LPVOID *lpTranslationList);

typedef BOOL (WINAPI UTREGISTER)(HANDLE hModule, LPCSTR SixteenBitDLL,
	LPCSTR InitName, LPCSTR ProcName, UT32PROC **ThirtyTwoBitThunk,
	FARPROC UT32Callback, LPVOID Buff);

typedef VOID (WINAPI UTUNREGISTER)(HANDLE hModule);

/* 
 * The following variables keep track of information about this DLL
 * on a per-instance basis.  Each time this DLL is loaded, it gets its own 
 * new data segment with its own copy of all static and global information.
 */

static HINSTANCE hInstance;	/* HINSTANCE of this DLL. */
static int platformId;		/* Running under NT, 95, or Win32s? */

/*
 * The following function tables are used to dispatch to either the

 * wide-character or multi-byte versions of the operating system calls,
 * depending on whether the Unicode calls are available.
 */

static TclWinProcs asciiProcs = {
    0,

    (BOOL (WINAPI *)(CONST TCHAR *, LPDCB)) BuildCommDCBA,
    (TCHAR *(WINAPI *)(TCHAR *)) CharLowerA,
    (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *, BOOL)) CopyFileA,
    (BOOL (WINAPI *)(CONST TCHAR *, LPSECURITY_ATTRIBUTES)) CreateDirectoryA,
    (HANDLE (WINAPI *)(CONST TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *, 
	    DWORD, DWORD, HANDLE)) CreateFileA,
    (BOOL (WINAPI *)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES, 
	    LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *, 
	    LPSTARTUPINFOA, LPPROCESS_INFORMATION)) CreateProcessA,
    (BOOL (WINAPI *)(CONST TCHAR *)) DeleteFileA,
    (HANDLE (WINAPI *)(CONST TCHAR *, WIN32_FIND_DATAT *)) FindFirstFileA,
    (BOOL (WINAPI *)(HANDLE, WIN32_FIND_DATAT *)) FindNextFileA,
    (BOOL (WINAPI *)(WCHAR *, LPDWORD)) GetComputerNameA,
    (DWORD (WINAPI *)(DWORD, WCHAR *)) GetCurrentDirectoryA,
    (DWORD (WINAPI *)(CONST TCHAR *)) GetFileAttributesA,
    (DWORD (WINAPI *)(CONST TCHAR *, DWORD nBufferLength, WCHAR *, 
	    TCHAR **)) GetFullPathNameA,
    (DWORD (WINAPI *)(HMODULE, WCHAR *, int)) GetModuleFileNameA,
    (DWORD (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD)) GetShortPathNameA,
    (UINT (WINAPI *)(CONST TCHAR *, CONST TCHAR *, UINT uUnique, 
	    WCHAR *)) GetTempFileNameA,
    (DWORD (WINAPI *)(DWORD, WCHAR *)) GetTempPathA,
    (BOOL (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD, LPDWORD, LPDWORD, LPDWORD,
	    WCHAR *, DWORD)) GetVolumeInformationA,
    (HINSTANCE (WINAPI *)(CONST TCHAR *)) LoadLibraryA,


    (TCHAR (WINAPI *)(WCHAR *, CONST TCHAR *)) lstrcpyA,
    (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *)) MoveFileA,
    (BOOL (WINAPI *)(CONST TCHAR *)) RemoveDirectoryA,
    (DWORD (WINAPI *)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD, 
	    WCHAR *, TCHAR **)) SearchPathA,
    (BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryA,
    (BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesA,
};

static TclWinProcs unicodeProcs = {
    1,

    (BOOL (WINAPI *)(CONST TCHAR *, LPDCB)) BuildCommDCBW,
    (TCHAR *(WINAPI *)(TCHAR *)) CharLowerW,
    (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *, BOOL)) CopyFileW,
    (BOOL (WINAPI *)(CONST TCHAR *, LPSECURITY_ATTRIBUTES)) CreateDirectoryW,
    (HANDLE (WINAPI *)(CONST TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *, 
	    DWORD, DWORD, HANDLE)) CreateFileW,
    (BOOL (WINAPI *)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES, 
	    LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *, 
	    LPSTARTUPINFOA, LPPROCESS_INFORMATION)) CreateProcessW,
    (BOOL (WINAPI *)(CONST TCHAR *)) DeleteFileW,
    (HANDLE (WINAPI *)(CONST TCHAR *, WIN32_FIND_DATAT *)) FindFirstFileW,
    (BOOL (WINAPI *)(HANDLE, WIN32_FIND_DATAT *)) FindNextFileW,
    (BOOL (WINAPI *)(WCHAR *, LPDWORD)) GetComputerNameW,
    (DWORD (WINAPI *)(DWORD, WCHAR *)) GetCurrentDirectoryW,
    (DWORD (WINAPI *)(CONST TCHAR *)) GetFileAttributesW,
    (DWORD (WINAPI *)(CONST TCHAR *, DWORD nBufferLength, WCHAR *, 
	    TCHAR **)) GetFullPathNameW,
    (DWORD (WINAPI *)(HMODULE, WCHAR *, int)) GetModuleFileNameW,
    (DWORD (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD)) GetShortPathNameW,
    (UINT (WINAPI *)(CONST TCHAR *, CONST TCHAR *, UINT uUnique, 
	    WCHAR *)) GetTempFileNameW,
    (DWORD (WINAPI *)(DWORD, WCHAR *)) GetTempPathW,
    (BOOL (WINAPI *)(CONST TCHAR *, WCHAR *, DWORD, LPDWORD, LPDWORD, LPDWORD, 
	    WCHAR *, DWORD)) GetVolumeInformationW,
    (HINSTANCE (WINAPI *)(CONST TCHAR *)) LoadLibraryW,

    (TCHAR (WINAPI *)(WCHAR *, CONST TCHAR *)) lstrcpyW,



    (BOOL (WINAPI *)(CONST TCHAR *, CONST TCHAR *)) MoveFileW,
    (BOOL (WINAPI *)(CONST TCHAR *)) RemoveDirectoryW,
    (DWORD (WINAPI *)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD, 
	    WCHAR *, TCHAR **)) SearchPathW,
    (BOOL (WINAPI *)(CONST TCHAR *)) SetCurrentDirectoryW,
    (BOOL (WINAPI *)(CONST TCHAR *, DWORD)) SetFileAttributesW,
};

TclWinProcs *tclWinProcs;
static Tcl_Encoding tclWinTCharEncoding;

/*
 * The following declaration is for the VC++ DLL entry point.
 */

BOOL APIENTRY		DllMain(HINSTANCE hInst, DWORD reason, 
				LPVOID reserved);


#ifdef __WIN32__
#ifndef STATIC_BUILD


/*
 *----------------------------------------------------------------------
 *
 * DllEntryPoint --
 *
 *	This wrapper function is used by Borland to invoke the
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269


270

271
272
273
274
275
276




277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

298




299
300
301


302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
 */
BOOL APIENTRY
DllMain(hInst, reason, reserved)
    HINSTANCE hInst;		/* Library instance handle. */
    DWORD reason;		/* Reason this function is being called. */
    LPVOID reserved;		/* Not used. */
{
    OSVERSIONINFO os;

    switch (reason) {
    case DLL_PROCESS_ATTACH:

	/*
	 * Registration of UT need to be done only once for first
	 * attaching process.  At that time set the tclWin32s flag
	 * to indicate if the DLL is executing under Win32s or not.
	 */

	if (tclProcessesAttached++) {
	    return FALSE;         /* Not the first initialization. */
	}

	tclInstance = hInst;
	os.dwOSVersionInfoSize = sizeof(os);
	GetVersionEx(&os);
	tclPlatformId = os.dwPlatformId;

	/*
	 * The following code stops Windows 3.x from automatically putting 
	 * up Sharing Violation dialogs, e.g, when someone tries to
	 * access a file that is locked or a drive with no disk in it.
	 * Tcl already returns the appropriate error to the caller, and they 
	 * can decide to put up their own dialog in response to that failure.  
	 *
	 * Under 95 and NT, the system doesn't automatically put up dialogs 
	 * when the above operations fail.
	 */

	if (tclPlatformId == VER_PLATFORM_WIN32s) {
	    SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS);

	}


	return TRUE;

    case DLL_PROCESS_DETACH:

	tclProcessesAttached--;
	if (tclProcessesAttached == 0) {

	    /*
	     * Unregister the Tcl thunk.
	     */

	    if (UTUnRegister != NULL) {
		UTUnRegister(hInst);
	    }

	    /*
	     * Cleanup any dynamically loaded libraries.
	     */

	    UnloadLibraries();

            /*
             * And finally finalize our use of Tcl.
             */

            Tcl_Finalize();
	}
	break;
    }

    return TRUE; 
}

/*
 *----------------------------------------------------------------------
 *
 * TclWinLoadLibrary --
 *
 *	This function is a wrapper for the system LoadLibrary.  It is
 *	responsible for adding library handles to the library list so
 *	the libraries can be freed when tcl.dll is unloaded.
 *
 * Results:
 *	Returns the handle of the newly loaded library, or NULL on
 *	failure.
 *
 * Side effects:
 *	Loads the specified library into the process.
 *
 *----------------------------------------------------------------------
 */

HINSTANCE
TclWinLoadLibrary(name)
    char *name;			/* Library file to load. */
{
    HINSTANCE handle;
    LibraryList *ptr;

    handle = LoadLibrary(name);
    if (handle != NULL) {
	ptr = (LibraryList*) ckalloc(sizeof(LibraryList));
	ptr->handle = handle;
	ptr->nextPtr = libraryList;
	libraryList = ptr;
    } else {
	TclWinConvertError(GetLastError());
    }
    return handle;
}

/*
 *----------------------------------------------------------------------
 *
 * UnloadLibraries --
 *
 *	Frees any dynamically allocated libraries loaded by Tcl.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees the libraries on the library list as well as the list.
 *
 *----------------------------------------------------------------------
 */

static void
UnloadLibraries()
{
    LibraryList *ptr;

    while (libraryList != NULL) {
	FreeLibrary(libraryList->handle);
	ptr = libraryList->nextPtr;
	ckfree((char*)libraryList);
	libraryList = ptr;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclWinSynchSpawn --
 *
 *	32-bit entry point to the 16-bit SynchSpawn code.
 *
 * Results:
 *	1 on success, 0 on failure.
 *
 * Side effects:
 *	Spawns a command and waits for it to complete.
 *
 *----------------------------------------------------------------------
 */
int 
TclWinSynchSpawn(void *args, int type, void **trans, Tcl_Pid *pidPtr)
{
    static UT32PROC UTProc = NULL;
    static int utErrorCode;

    if (UTUnRegister == NULL) {
	/*
	 * Load the Universal Thunking routines from kernel32.dll.
	 */

	HINSTANCE hKernel;
	PUTREGISTER UTRegister;


	char buffer[] = "TCL16xx.DLL";


	hKernel = TclWinLoadLibrary("Kernel32.Dll");
	if (hKernel == NULL) {
	    return 0;
	}





	UTRegister = (PUTREGISTER) GetProcAddress(hKernel, "UTRegister");
	UTUnRegister = (PUTUNREGISTER) GetProcAddress(hKernel, "UTUnRegister");
	if (!UTRegister || !UTUnRegister) {
	    UnloadLibraries();
	    return 0;
	}

	/*
	 * Construct the complete name of tcl16xx.dll.
	 */

	buffer[5] = '0' + TCL_MAJOR_VERSION;
	buffer[6] = '0' + TCL_MINOR_VERSION;

	/*
	 * Register the Tcl thunk.
	 */

	if (UTRegister(tclInstance, buffer, NULL, "UTProc", &UTProc, NULL,
		NULL) == FALSE) {
	    utErrorCode = GetLastError();

	}




    }

    if (UTProc == NULL) {


	/*
	 * The 16-bit thunking DLL wasn't found.  Return error code that
	 * indicates this problem.
	 */

	SetLastError(utErrorCode);
	return 0;
    }


    UTProc(args, type, trans);
    *pidPtr = 0;
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TclWinGetTclInstance --
 *







<
<


|
|
<
|
<
<
|
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
|
<
<
|

<
<
>


>



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|






|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



















<
<
<
<
<
<
<
<
|
|
>
>
|
>

|
|
|
|

>
>
>
>
|
|
|
|
|
|

|
|
|

|
|

|
|
|

|
|
|
>
|
>
>
>
>
|
|
|
>
>





<
|

>

|
|
|







179
180
181
182
183
184
185


186
187
188
189

190


191



192




193






194


195
196


197
198
199
200
201
202
203
204





















205
206
207
208
209
210
211
212


















213






214








































215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233








234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
 */
BOOL APIENTRY
DllMain(hInst, reason, reserved)
    HINSTANCE hInst;		/* Library instance handle. */
    DWORD reason;		/* Reason this function is being called. */
    LPVOID reserved;		/* Not used. */
{


    switch (reason) {
    case DLL_PROCESS_ATTACH:
	if (hInstance != NULL) {
	    /*

	     * Prevents DLL from being loaded multiple times under Win32s,


	     * since all copies of the DLL share the same data segment and



	     * Tcl isn't set up to handle that.  Under NT or 95, each time 




	     * the DLL is loaded, it gets its own private copy of the data 






	     * segment.


	     */



	    return FALSE;
	}

	TclWinInit(hInst);
	return TRUE;

    case DLL_PROCESS_DETACH:
	if (hInst == hInstance) {





















	    Tcl_Finalize();
	}
	break;
    }

    return TRUE; 
}



















#endif /* !STATIC_BUILD */






#endif /* __WIN32__ */









































/*
 *----------------------------------------------------------------------
 *
 * TclWinSynchSpawn --
 *
 *	32-bit entry point to the 16-bit SynchSpawn code.
 *
 * Results:
 *	1 on success, 0 on failure.
 *
 * Side effects:
 *	Spawns a command and waits for it to complete.
 *
 *----------------------------------------------------------------------
 */
int 
TclWinSynchSpawn(void *args, int type, void **trans, Tcl_Pid *pidPtr)
{








    HINSTANCE hKernel;
    UTREGISTER *utRegisterProc;
    UTUNREGISTER *utUnRegisterProc;
    UT32PROC *ut32Proc;
    char buffer[] = "TCL16xx.DLL";
    int result;

    hKernel = LoadLibraryA("kernel32.dll");
    if (hKernel == NULL) {
	return 0;
    }

    /*
     * Load the Universal Thunking routines from kernel32.dll.
     */

    utRegisterProc = (UTREGISTER *) GetProcAddress(hKernel, "UTRegister");
    utUnRegisterProc = (UTUNREGISTER *) GetProcAddress(hKernel, "UTUnRegister");
    if ((utRegisterProc == NULL) || (utUnRegisterProc == NULL)) {
	result = 0;
	goto done;
    }

    /*
     * Construct the complete name of tcl16xx.dll.
     */

    buffer[5] = '0' + TCL_MAJOR_VERSION;
    buffer[6] = '0' + TCL_MINOR_VERSION;

    /*
     * Register the Tcl thunk.
     */

    if ((*utRegisterProc)(hInstance, buffer, NULL, "UTProc", &ut32Proc, 
	    NULL, NULL) == FALSE) {
	result = 0;
	goto done;
    }
    if (ut32Proc != NULL) {
	/*
	 * Invoke the thunk.
	 */

	*pidPtr = 0;
	(*ut32Proc)(args, type, trans);
	result = 1;
    } else {
	/*
	 * The 16-bit thunking DLL wasn't found.  Return error code that
	 * indicates this problem.
	 */


	result = 0;
    }
    (*utUnRegisterProc)(hInstance);

    done:
    FreeLibrary(hKernel);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclWinGetTclInstance --
 *
328
329
330
331
332
333
334
335














































336
337
338
339
340
341
342
 *
 *----------------------------------------------------------------------
 */

HINSTANCE
TclWinGetTclInstance()
{
    return tclInstance;














































}

/*
 *----------------------------------------------------------------------
 *
 * TclWinGetPlatformId --
 *







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
 *
 *----------------------------------------------------------------------
 */

HINSTANCE
TclWinGetTclInstance()
{
    return hInstance;
}

/*
 *----------------------------------------------------------------------
 *
 * TclWinInit --
 *
 *	This function initializes the internal state of the tcl library.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Initializes the 16-bit thunking library, and the tclPlatformId
 *	variable.
 *
 *----------------------------------------------------------------------
 */

void
TclWinInit(hInst)
    HINSTANCE hInst;		/* Library instance handle. */
{
    OSVERSIONINFO os;

    hInstance = hInst;
    os.dwOSVersionInfoSize = sizeof(os);
    GetVersionEx(&os);
    platformId = os.dwPlatformId;

    /*
     * The following code stops Windows 3.x from automatically putting 
     * up Sharing Violation dialogs, e.g, when someone tries to
     * access a file that is locked or a drive with no disk in it.
     * Tcl already returns the appropriate error to the caller, and they 
     * can decide to put up their own dialog in response to that failure.  
     *
     * Under 95 and NT, the system doesn't automatically put up dialogs 
     * when the above operations fail.
     */

    if (platformId == VER_PLATFORM_WIN32s) {
	SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS);
    }

    tclWinProcs = &asciiProcs;
}

/*
 *----------------------------------------------------------------------
 *
 * TclWinGetPlatformId --
 *
354
355
356
357
358
359
360































































361

362












































































































































 *
 *----------------------------------------------------------------------
 */

int		
TclWinGetPlatformId()
{































































    return tclPlatformId;

}



















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
 *
 *----------------------------------------------------------------------
 */

int		
TclWinGetPlatformId()
{
    return platformId;
}

/*
 *-------------------------------------------------------------------------
 *
 * TclWinNoBackslash --
 *
 *	We're always iterating through a string in Windows, changing the
 *	backslashes to slashes for use in Tcl.
 *
 * Results:
 *	All backslashes in given string are changed to slashes.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

char *
TclWinNoBackslash(
    char *path)			/* String to change. */
{
    char *p;

    for (p = path; *p != '\0'; p++) {
	if (*p == '\\') {
	    *p = '/';
	}
    }
    return path;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCheckStackSpace --
 *
 *	Detect if we are about to blow the stack.  Called before an 
 *	evaluation can happen when nesting depth is checked.
 *
 * Results:
 *	1 if there is enough stack space to continue; 0 if not.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclpCheckStackSpace()
{
    /*
     * We can recurse only if there is at least TCL_WIN_STACK_THRESHOLD
     * bytes of stack space left.  alloca() is cheap on windows; basically
     * it just subtracts from the stack pointer causing the OS to throw an
     * exception if the stack pointer is set below the bottom of the stack.
     */

    try {
	alloca(TCL_WIN_STACK_THRESHOLD);
	return 1;
    } except (1) {}

    return 0;
}


/*
 *----------------------------------------------------------------------
 *
 * TclWinGetPlatform --
 *
 *	This is a kludge that allows the test library to get access
 *	the internal tclPlatform variable.
 *
 * Results:
 *	Returns a pointer to the tclPlatform variable.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TclPlatformType *
TclWinGetPlatform()
{
    return &tclPlatform;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclWinSetInterfaces --
 *
 *	A helper proc that allows the test library to change the
 *	tclWinProcs structure to dispatch to either the wide-character
 *	or multi-byte versions of the operating system calls, depending
 *	on whether Unicode is the system encoding.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TclWinSetInterfaces(
    int wide)			/* Non-zero to use wide interfaces, 0
				 * otherwise. */
{
    Tcl_FreeEncoding(tclWinTCharEncoding);

    if (wide) {
	tclWinProcs = &unicodeProcs;
	tclWinTCharEncoding = Tcl_GetEncoding(NULL, "unicode");
    } else {
	tclWinProcs = &asciiProcs;
	tclWinTCharEncoding = NULL;
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_WinUtfToTChar, Tcl_WinTCharToUtf --
 *
 *	Convert between UTF-8 and Unicode when running Windows NT or 
 *	the current ANSI code page when running Windows 95.
 *
 *	On Mac, Unix, and Windows 95, all strings exchanged between Tcl
 *	and the OS are "char" oriented.  We need only one Tcl_Encoding to
 *	convert between UTF-8 and the system's native encoding.  We use
 *	NULL to represent that encoding.
 *
 *	On NT, some strings exchanged between Tcl and the OS are "char"
 *	oriented, while others are in Unicode.  We need two Tcl_Encoding
 *	APIs depending on whether we are targeting a "char" or Unicode
 *	interface.  
 *
 *	Calling Tcl_UtfToExternal() or Tcl_ExternalToUtf() with an
 *	encoding of NULL should always used to convert between UTF-8
 *	and the system's "char" oriented encoding.  The following two
 *	functions are used in Windows-specific code to convert between
 *	UTF-8 and Unicode strings (NT) or "char" strings(95).  This saves
 *	you the trouble of writing the following type of fragment over and
 *	over:
 *
 *		if (running NT) {
 *		    encoding <- Tcl_GetEncoding("unicode");
 *		    nativeBuffer <- UtfToExternal(encoding, utfBuffer);
 *		    Tcl_FreeEncoding(encoding);
 *		} else {
 *		    nativeBuffer <- UtfToExternal(NULL, utfBuffer);
 *		}
 *
 *	By convention, in Windows a TCHAR is a character in the ANSI code
 *	page on Windows 95, a Unicode character on Windows NT.  If you
 *	plan on targeting a Unicode interfaces when running on NT and a
 *	"char" oriented interface while running on 95, these functions
 *	should be used.  If you plan on targetting the same "char"
 *	oriented function on both 95 and NT, use Tcl_UtfToExternal()
 *	with an encoding of NULL.
 *
 * Results:
 *	The result is a pointer to the string in the desired target
 *	encoding.  Storage for the result string is allocated in
 *	dsPtr; the caller must call Tcl_DStringFree() when the result
 *	is no longer needed.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TCHAR *
Tcl_WinUtfToTChar(string, len, dsPtr)
    CONST char *string;		/* Source string in UTF-8. */
    int len;			/* Source string length in bytes, or < 0 for
				 * strlen(). */
    Tcl_DString *dsPtr;		/* Uninitialized or free DString in which 
				 * the converted string is stored. */
{
    return (TCHAR *) Tcl_UtfToExternalDString(tclWinTCharEncoding, 
	    string, len, dsPtr);
}

char *
Tcl_WinTCharToUtf(string, len, dsPtr)
    CONST TCHAR *string;	/* Source string in Unicode when running
				 * NT, ANSI when running 95. */
    int len;			/* Source string length in bytes, or < 0 for
				 * platform-specific string length. */
    Tcl_DString *dsPtr;		/* Uninitialized or free DString in which 
				 * the converted string is stored. */
{
    return Tcl_ExternalToUtfDString(tclWinTCharEncoding, 
	    (CONST char *) string, len, dsPtr);
}

Changes to win/tclWinChan.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
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
/* 
 * tclWinChan.c
 *
 *	Channel drivers for Windows channels based on files, command
 *	pipes and TCP sockets.
 *
 * 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.
 *
 * SCCS: @(#) tclWinChan.c 1.75 97/09/26 16:17:46
 */

#include "tclWinInt.h"

/*
 * This is the size of the channel name for File based channels
 */

#define CHANNEL_NAME_SIZE	64
static char channelName[CHANNEL_NAME_SIZE+1];

/*
 * The following variable is used to tell whether this module has been
 * initialized.
 */

static int initialized = 0;

/*
 * State flags used in the info structures below.
 */

#define FILE_PENDING	(1<<0)	/* Message is pending in the queue. */
#define FILE_ASYNC	(1<<1)	/* Channel is non-blocking. */
#define FILE_APPEND	(1<<2)	/* File is in append mode. */




/*
 * The following structure contains per-instance data for a file based channel.
 */

typedef struct FileInfo {
    Tcl_Channel channel;	/* Pointer to channel structure. */
    int validMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which operations are valid on the file. */
    int watchMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which events should be reported. */
    int flags;			/* State flags, see above for a list. */
    HANDLE handle;		/* Input/output file. */
    struct FileInfo *nextPtr;	/* Pointer to next registered file. */
} FileInfo;


/*
 * List of all file channels currently open.
 */

static FileInfo *firstFilePtr;




/*
 * The following structure is what is added to the Tcl event queue when
 * file events are generated.
 */

typedef struct FileEvent {
    Tcl_Event header;		/* Information that is standard for
				 * all events. */
    FileInfo *infoPtr;		/* Pointer to file info structure.  Note
				 * that we still have to verify that the
				 * file exists before dereferencing this
				 * pointer. */
} FileEvent;

/*
 * Static routines for this file:
 */

static int		ComGetOptionProc _ANSI_ARGS_((ClientData instanceData, 
			    Tcl_Interp *interp, char *optionName,
			    Tcl_DString *dsPtr));
static int		ComInputProc _ANSI_ARGS_((ClientData instanceData,
	            	    char *buf, int toRead, int *errorCode));
static int		ComSetOptionProc _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp, char *optionName, 
			    char *value));
static int		FileBlockProc _ANSI_ARGS_((ClientData instanceData,
			    int mode));
static void		FileChannelExitHandler _ANSI_ARGS_((
		            ClientData clientData));
static void		FileCheckProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static int		FileCloseProc _ANSI_ARGS_((ClientData instanceData,
		            Tcl_Interp *interp));
static int		FileEventProc _ANSI_ARGS_((Tcl_Event *evPtr, 
			    int flags));
static int		FileGetHandleProc _ANSI_ARGS_((ClientData instanceData,
		            int direction, ClientData *handlePtr));
static void		FileInit _ANSI_ARGS_((void));
static int		FileInputProc _ANSI_ARGS_((ClientData instanceData,
	            	    char *buf, int toRead, int *errorCode));
static int		FileOutputProc _ANSI_ARGS_((ClientData instanceData,
			    char *buf, int toWrite, int *errorCode));
static int		FileSeekProc _ANSI_ARGS_((ClientData instanceData,
			    long offset, int mode, int *errorCode));
static void		FileSetupProc _ANSI_ARGS_((ClientData clientData,











|




<
<
<
<
<
<
<
<
<
<
<
<
<
<







>
>
>


















>
|
|
|

|
>
>
>



















<
<
<
<
<
<
<
<












|







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
/* 
 * tclWinChan.c
 *
 *	Channel drivers for Windows channels based on files, command
 *	pipes and TCP sockets.
 *
 * 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: tclWinChan.c,v 1.1.2.8 1999/04/14 00:34:01 surles Exp $
 */

#include "tclWinInt.h"















/*
 * State flags used in the info structures below.
 */

#define FILE_PENDING	(1<<0)	/* Message is pending in the queue. */
#define FILE_ASYNC	(1<<1)	/* Channel is non-blocking. */
#define FILE_APPEND	(1<<2)	/* File is in append mode. */

#define FILE_TYPE_SERIAL  (FILE_TYPE_PIPE+1)
#define FILE_TYPE_CONSOLE (FILE_TYPE_PIPE+2)

/*
 * The following structure contains per-instance data for a file based channel.
 */

typedef struct FileInfo {
    Tcl_Channel channel;	/* Pointer to channel structure. */
    int validMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which operations are valid on the file. */
    int watchMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which events should be reported. */
    int flags;			/* State flags, see above for a list. */
    HANDLE handle;		/* Input/output file. */
    struct FileInfo *nextPtr;	/* Pointer to next registered file. */
} FileInfo;

typedef struct ThreadSpecificData {
    /*
     * List of all file channels currently open.
     */

    FileInfo *firstFilePtr;
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * The following structure is what is added to the Tcl event queue when
 * file events are generated.
 */

typedef struct FileEvent {
    Tcl_Event header;		/* Information that is standard for
				 * all events. */
    FileInfo *infoPtr;		/* Pointer to file info structure.  Note
				 * that we still have to verify that the
				 * file exists before dereferencing this
				 * pointer. */
} FileEvent;

/*
 * Static routines for this file:
 */









static int		FileBlockProc _ANSI_ARGS_((ClientData instanceData,
			    int mode));
static void		FileChannelExitHandler _ANSI_ARGS_((
		            ClientData clientData));
static void		FileCheckProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static int		FileCloseProc _ANSI_ARGS_((ClientData instanceData,
		            Tcl_Interp *interp));
static int		FileEventProc _ANSI_ARGS_((Tcl_Event *evPtr, 
			    int flags));
static int		FileGetHandleProc _ANSI_ARGS_((ClientData instanceData,
		            int direction, ClientData *handlePtr));
static ThreadSpecificData *FileInit _ANSI_ARGS_((void));
static int		FileInputProc _ANSI_ARGS_((ClientData instanceData,
	            	    char *buf, int toRead, int *errorCode));
static int		FileOutputProc _ANSI_ARGS_((ClientData instanceData,
			    char *buf, int toWrite, int *errorCode));
static int		FileSeekProc _ANSI_ARGS_((ClientData instanceData,
			    long offset, int mode, int *errorCode));
static void		FileSetupProc _ANSI_ARGS_((ClientData clientData,
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
    FileSeekProc,		/* Seek proc. */
    NULL,			/* Set option proc. */
    NULL,			/* Get option proc. */
    FileWatchProc,		/* Set up the notifier to watch the channel. */
    FileGetHandleProc,		/* Get an OS handle from channel. */
};

static Tcl_ChannelType comChannelType = {
    "com",			/* Type name. */
    FileBlockProc,		/* Set blocking or non-blocking mode.*/
    FileCloseProc,		/* Close proc. */
    ComInputProc,		/* Input proc. */
    FileOutputProc,		/* Output proc. */
    NULL,			/* Seek proc. */
    ComSetOptionProc,		/* Set option proc. */
    ComGetOptionProc,		/* Get option proc. */
    FileWatchProc,		/* Set up notifier to watch the channel. */
    FileGetHandleProc		/* Get an OS handle from channel. */
};

/*
 *----------------------------------------------------------------------
 *
 * FileInit --
 *
 *	This function creates the window used to simulate file events.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new window and creates an exit handler. 
 *
 *----------------------------------------------------------------------
 */

static void
FileInit()
{



    initialized = 1;
    firstFilePtr = NULL;
    Tcl_CreateEventSource(FileSetupProc, FileCheckProc, NULL);
    Tcl_CreateExitHandler(FileChannelExitHandler, NULL);


}

/*
 *----------------------------------------------------------------------
 *
 * FileChannelExitHandler --
 *







<
<
<
<
<
<
<
<
<
<
<
<

















|


>
>
>
|
|
|
|
>
>







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
    FileSeekProc,		/* Seek proc. */
    NULL,			/* Set option proc. */
    NULL,			/* Get option proc. */
    FileWatchProc,		/* Set up the notifier to watch the channel. */
    FileGetHandleProc,		/* Get an OS handle from channel. */
};














/*
 *----------------------------------------------------------------------
 *
 * FileInit --
 *
 *	This function creates the window used to simulate file events.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new window and creates an exit handler. 
 *
 *----------------------------------------------------------------------
 */

static ThreadSpecificData *
FileInit()
{
    ThreadSpecificData *tsdPtr =
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
	tsdPtr->firstFilePtr = NULL;
	Tcl_CreateEventSource(FileSetupProc, FileCheckProc, NULL);
	Tcl_CreateThreadExitHandler(FileChannelExitHandler, NULL);
    }
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * FileChannelExitHandler --
 *
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
 */

static void
FileChannelExitHandler(clientData)
    ClientData clientData;	/* Old window proc */
{
    Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL);
    initialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * FileSetupProc --
 *







<







161
162
163
164
165
166
167

168
169
170
171
172
173
174
 */

static void
FileChannelExitHandler(clientData)
    ClientData clientData;	/* Old window proc */
{
    Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL);

}

/*
 *----------------------------------------------------------------------
 *
 * FileSetupProc --
 *
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
void
FileSetupProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    FileInfo *infoPtr;
    Tcl_Time blockTime = { 0, 0 };


    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Check to see if there is a ready file.  If so, poll.
     */


    for (infoPtr = firstFilePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask) {
	    Tcl_SetMaxBlockTime(&blockTime);
	    break;
	}
    }
}








>









>
|







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
void
FileSetupProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    FileInfo *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 file.  If so, poll.
     */

    for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask) {
	    Tcl_SetMaxBlockTime(&blockTime);
	    break;
	}
    }
}

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
static void
FileCheckProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    FileEvent *evPtr;
    FileInfo *infoPtr;


    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Queue events for any ready files that don't already have events
     * queued (caused by persistent states that won't generate WinSock
     * events).
     */


    for (infoPtr = firstFilePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask && !(infoPtr->flags & FILE_PENDING)) {
	    infoPtr->flags |= FILE_PENDING;
	    evPtr = (FileEvent *) ckalloc(sizeof(FileEvent));
	    evPtr->header.proc = FileEventProc;
	    evPtr->infoPtr = infoPtr;
	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
	}







>











>
|







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
static void
FileCheckProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    FileEvent *evPtr;
    FileInfo *infoPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Queue events for any ready files that don't already have events
     * queued (caused by persistent states that won't generate WinSock
     * events).
     */

    for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask && !(infoPtr->flags & FILE_PENDING)) {
	    infoPtr->flags |= FILE_PENDING;
	    evPtr = (FileEvent *) ckalloc(sizeof(FileEvent));
	    evPtr->header.proc = FileEventProc;
	    evPtr->infoPtr = infoPtr;
	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
	}
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
FileEventProc(evPtr, flags)
    Tcl_Event *evPtr;		/* Event to service. */
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    FileEvent *fileEvPtr = (FileEvent *)evPtr;
    FileInfo *infoPtr;


    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the list of watched files for the one whose handle
     * matches the event.  We do this rather than simply dereferencing
     * the handle in the event so that files can be deleted while the
     * event is in the queue.
     */


    for (infoPtr = firstFilePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (fileEvPtr->infoPtr == infoPtr) {
	    infoPtr->flags &= ~(FILE_PENDING);
	    Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask);
	    break;
	}
    }
    return 1;







>












>
|







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
FileEventProc(evPtr, flags)
    Tcl_Event *evPtr;		/* Event to service. */
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    FileEvent *fileEvPtr = (FileEvent *)evPtr;
    FileInfo *infoPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the list of watched files for the one whose handle
     * matches the event.  We do this rather than simply dereferencing
     * the handle in the event so that files can be deleted while the
     * event is in the queue.
     */

    for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (fileEvPtr->infoPtr == infoPtr) {
	    infoPtr->flags &= ~(FILE_PENDING);
	    Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask);
	    break;
	}
    }
    return 1;
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
FileCloseProc(instanceData, interp)
    ClientData instanceData;	/* Pointer to FileInfo structure. */
    Tcl_Interp *interp;		/* Not used. */
{
    FileInfo *fileInfoPtr = (FileInfo *) instanceData;
    FileInfo **nextPtrPtr;
    int errorCode = 0;


    /*
     * Remove the file from the watch list.
     */

    FileWatchProc(instanceData, 0);











    if (CloseHandle(fileInfoPtr->handle) == FALSE) {
	TclWinConvertError(GetLastError());
	errorCode = errno;
    }

    for (nextPtrPtr = &firstFilePtr; (*nextPtrPtr) != NULL;
	 nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
	if ((*nextPtrPtr) == fileInfoPtr) {
	    (*nextPtrPtr) = fileInfoPtr->nextPtr;
	    break;
	}
    }
    ckfree((char *)fileInfoPtr);







>







>
>
>
>
>
>
>
>
>
>
|
|
|
|
>
|







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
FileCloseProc(instanceData, interp)
    ClientData instanceData;	/* Pointer to FileInfo structure. */
    Tcl_Interp *interp;		/* Not used. */
{
    FileInfo *fileInfoPtr = (FileInfo *) instanceData;
    FileInfo **nextPtrPtr;
    int errorCode = 0;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Remove the file from the watch list.
     */

    FileWatchProc(instanceData, 0);

    /*
     * Don't close the Win32 handle if the handle is a standard channel
     * during the exit process.  Otherwise, one thread may kill the stdio
     * of another.
     */

    if (!TclInExit() 
	    || ((GetStdHandle(STD_INPUT_HANDLE) != fileInfoPtr->handle)
		&& (GetStdHandle(STD_OUTPUT_HANDLE) != fileInfoPtr->handle)
		&& (GetStdHandle(STD_ERROR_HANDLE) != fileInfoPtr->handle))) {
	if (CloseHandle(fileInfoPtr->handle) == FALSE) {
	    TclWinConvertError(GetLastError());
	    errorCode = errno;
	}
    }
    for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
	 nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
	if ((*nextPtrPtr) == fileInfoPtr) {
	    (*nextPtrPtr) = fileInfoPtr->nextPtr;
	    break;
	}
    }
    ckfree((char *)fileInfoPtr);
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464
    } else {
        moveMethod = FILE_END;
    }

    newPos = SetFilePointer(infoPtr->handle, offset, NULL, moveMethod);
    if (newPos == 0xFFFFFFFF) {
        TclWinConvertError(GetLastError());

        return -1;
    }
    return newPos;
}

/*
 *----------------------------------------------------------------------
 *







>
|







445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
    } else {
        moveMethod = FILE_END;
    }

    newPos = SetFilePointer(infoPtr->handle, offset, NULL, moveMethod);
    if (newPos == 0xFFFFFFFF) {
        TclWinConvertError(GetLastError());
        *errorCodePtr = errno;
	return -1;
    }
    return newPos;
}

/*
 *----------------------------------------------------------------------
 *
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
}

/*
 *----------------------------------------------------------------------
 *
 * FileGetHandleProc --
 *
 *	Called from Tcl_GetChannelFile to retrieve OS handles from
 *	a file based channel.
 *
 * Results:
 *	Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
 *	there is no handle for the specified direction. 
 *
 * Side effects:







|







596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
}

/*
 *----------------------------------------------------------------------
 *
 * FileGetHandleProc --
 *
 *	Called from Tcl_GetChannelHandle to retrieve OS handles from
 *	a file based channel.
 *
 * Results:
 *	Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
 *	there is no handle for the specified direction. 
 *
 * Side effects:
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866

867
868
869
870
871
872
873
874
875
876


877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
    if (direction & infoPtr->validMask) {
	*handlePtr = (ClientData) infoPtr->handle;
	return TCL_OK;
    } else {
	return TCL_ERROR;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ComInputProc --
 *
 *	Reads input from the IO channel into the buffer given. Returns
 *	count of how many bytes were actually read, and an error indication.
 *
 * Results:
 *	A count of how many bytes were read is returned and an error
 *	indication is returned in an output argument.
 *
 * Side effects:
 *	Reads input from the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
ComInputProc(instanceData, buf, bufSize, errorCode)
    ClientData instanceData;	/* File state. */
    char *buf;			/* Where to store data read. */
    int bufSize;		/* How much space is available 
				 * in the buffer? */
    int *errorCode;		/* Where to store error code. */
{
    FileInfo *infoPtr;
    DWORD bytesRead;
    DWORD dw;
    COMSTAT cs;

    *errorCode = 0;
    infoPtr = (FileInfo *) instanceData;

    if (ClearCommError(infoPtr->handle, &dw, &cs)) {
	if (dw != 0) {
	    *errorCode = EIO;
	    return -1;
	}
	if (cs.cbInQue != 0) {
	    if ((DWORD) bufSize > cs.cbInQue) {
		bufSize = cs.cbInQue;
	    }
	} else {
	    if (infoPtr->flags & FILE_ASYNC) {
		errno = *errorCode = EAGAIN;
		return -1;
	    } else {
		bufSize = 1;
	    }
	}
    }
    
    if (ReadFile(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &bytesRead,
            (LPOVERLAPPED) NULL) == FALSE) {
	TclWinConvertError(GetLastError());
	*errorCode = errno;
	return -1;
    }
    
    return bytesRead;
}

/*
 *----------------------------------------------------------------------
 *
 * ComSetOptionProc --
 *
 *	Sets an option on a channel.
 *
 * Results:
 *	A standard Tcl result. Also sets interp->result on error if
 *	interp is not NULL.
 *
 * Side effects:
 *	May modify an option on a device.
 *
 *----------------------------------------------------------------------
 */

static int		
ComSetOptionProc(instanceData, interp, optionName, value)
    ClientData instanceData;	/* File state. */
    Tcl_Interp *interp;		/* For error reporting - can be NULL. */
    char *optionName;		/* Which option to set? */
    char *value;		/* New value for option. */
{
    FileInfo *infoPtr;
    DCB dcb;
    int len;

    infoPtr = (FileInfo *) instanceData;

    len = strlen(optionName);
    if ((len > 1) && (strncmp(optionName, "-mode", len) == 0)) {
	if (GetCommState(infoPtr->handle, &dcb)) {
	    if ((BuildCommDCB(value, &dcb) == FALSE) ||
		    (SetCommState(infoPtr->handle, &dcb) == FALSE)) {
		/*
		 * one should separate the 2 errors... 
		 */
                if (interp) {
                    Tcl_AppendResult(interp, "bad value for -mode: should be ",
			    "baud,parity,data,stop", NULL);
		}
		return TCL_ERROR;
	    } else {
		return TCL_OK;
	    }
	} else {
	    if (interp) {
		Tcl_AppendResult(interp, "can't get comm state", NULL);
	    }
	    return TCL_ERROR;
	}
    } else {
	return Tcl_BadChannelOption(interp, optionName, "mode");
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ComGetOptionProc --
 *
 *	Gets a mode associated with an IO channel. If the optionName arg
 *	is non NULL, retrieves the value of that option. If the optionName
 *	arg is NULL, retrieves a list of alternating option names and
 *	values for the given channel.
 *
 * Results:
 *	A standard Tcl result. Also sets the supplied DString to the
 *	string value of the option(s) returned.
 *
 * Side effects:
 *	The string returned by this function is in static storage and
 *	may be reused at any time subsequent to the call.
 *
 *----------------------------------------------------------------------
 */

static int		
ComGetOptionProc(instanceData, interp, optionName, dsPtr)
    ClientData instanceData;	/* File state. */
    Tcl_Interp *interp;          /* For error reporting - can be NULL. */
    char *optionName;		/* Option to get. */
    Tcl_DString *dsPtr;		/* Where to store value(s). */
{
    FileInfo *infoPtr;
    DCB dcb;
    int len;

    infoPtr = (FileInfo *) instanceData;

    if (optionName == NULL) {
	Tcl_DStringAppendElement(dsPtr, "-mode");
	len = 0;
    } else {
	len = strlen(optionName);
    }
    if ((len == 0) || 
	    ((len > 1) && (strncmp(optionName, "-mode", len) == 0))) {
	if (GetCommState(infoPtr->handle, &dcb) == 0) {
	    /*
	     * shouldn't we flag an error instead ? 
	     */
	    Tcl_DStringAppendElement(dsPtr, "");
	} else {
	    char parity;
	    char *stop;
	    char buf[32];

	    parity = 'n';
	    if (dcb.Parity < 4) {
		parity = "noems"[dcb.Parity];
	    }

	    stop = (dcb.StopBits == ONESTOPBIT) ? "1" : 
		    (dcb.StopBits == ONE5STOPBITS) ? "1.5" : "2";

	    wsprintf(buf, "%d,%c,%d,%s", dcb.BaudRate, parity, dcb.ByteSize,
		    stop);
	    Tcl_DStringAppendElement(dsPtr, buf);
	}
	return TCL_OK;
    } else {
	return Tcl_BadChannelOption(interp, optionName, "mode");
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_OpenFileChannel --
 *
 *	Open an File based channel on Unix systems.
 *
 * Results:
 *	The new channel or NULL. If NULL, the output argument
 *	errorCodePtr is set to a POSIX error.
 *
 * Side effects:
 *	May open the channel and may cause creation of a file on the
 *	file system.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_OpenFileChannel(interp, fileName, modeString, permissions)
    Tcl_Interp *interp;			/* Interpreter for error reporting;
                                         * can be NULL. */
    char *fileName;			/* Name of file to open. */
    char *modeString;			/* A list of POSIX open modes or
                                         * a string such as "rw". */
    int permissions;			/* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
{
    FileInfo *infoPtr;
    int seekFlag, mode, channelPermissions;
    DWORD accessMode, createMode, shareMode, flags;
    char *nativeName;
    Tcl_DString buffer;
    DCB dcb;
    Tcl_ChannelType *channelTypePtr;
    HANDLE handle;

    if (!initialized) {
	FileInit();
    }


    mode = TclGetOpenMode(interp, modeString, &seekFlag);
    if (mode == -1) {
        return NULL;
    }

    nativeName = Tcl_TranslateFileName(interp, fileName, &buffer);
    if (nativeName == NULL) {
	return NULL;
    }



    switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
	case O_RDONLY:
	    accessMode = GENERIC_READ;
	    channelPermissions = TCL_READABLE;
	    break;
	case O_WRONLY:
	    accessMode = GENERIC_WRITE;
	    channelPermissions = TCL_WRITABLE;
	    break;
	case O_RDWR:
	    accessMode = (GENERIC_READ | GENERIC_WRITE);
	    channelPermissions = (TCL_READABLE | TCL_WRITABLE);
	    break;
	default:
	    panic("Tcl_OpenFileChannel: invalid mode value");
	    break;
    }

    /*
     * Map the creation flags to the NT create mode.
     */








|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|















|









|

|
|
|

<

|
<
|
<
>






|
<


>
>















|







624
625
626
627
628
629
630
631


632




























































633
634
635































































































































636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667

668
669

670

671
672
673
674
675
676
677
678

679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
    if (direction & infoPtr->validMask) {
	*handlePtr = (ClientData) infoPtr->handle;
	return TCL_OK;
    } else {
	return TCL_ERROR;
    }
}
































































/*
 *----------------------------------------------------------------------
 *































































































































 * TclpOpenFileChannel --
 *
 *	Open an File based channel on Unix systems.
 *
 * Results:
 *	The new channel or NULL. If NULL, the output argument
 *	errorCodePtr is set to a POSIX error.
 *
 * Side effects:
 *	May open the channel and may cause creation of a file on the
 *	file system.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclpOpenFileChannel(interp, fileName, modeString, permissions)
    Tcl_Interp *interp;			/* Interpreter for error reporting;
                                         * can be NULL. */
    char *fileName;			/* Name of file to open. */
    char *modeString;			/* A list of POSIX open modes or
                                         * a string such as "rw". */
    int permissions;			/* If the open involves creating a
                                         * file, with what modes to create
                                         * it? */
{
    Tcl_Channel channel = 0;
    int seekFlag, mode, channelPermissions;
    DWORD accessMode, createMode, shareMode, flags, consoleParams, type;
    TCHAR *nativeName;
    Tcl_DString ds, buffer;
    DCB dcb;

    HANDLE handle;
    char channelName[16 + TCL_INTEGER_SPACE];

    TclFile readFile = NULL;

    TclFile writeFile = NULL;

    mode = TclGetOpenMode(interp, modeString, &seekFlag);
    if (mode == -1) {
        return NULL;
    }

    if (Tcl_TranslateFileName(interp, fileName, &ds) == NULL) {

	return NULL;
    }
    nativeName = Tcl_WinUtfToTChar(Tcl_DStringValue(&ds), 
	    Tcl_DStringLength(&ds), &buffer);

    switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
	case O_RDONLY:
	    accessMode = GENERIC_READ;
	    channelPermissions = TCL_READABLE;
	    break;
	case O_WRONLY:
	    accessMode = GENERIC_WRITE;
	    channelPermissions = TCL_WRITABLE;
	    break;
	case O_RDWR:
	    accessMode = (GENERIC_READ | GENERIC_WRITE);
	    channelPermissions = (TCL_READABLE | TCL_WRITABLE);
	    break;
	default:
	    panic("TclpOpenFileChannel: invalid mode value");
	    break;
    }

    /*
     * Map the creation flags to the NT create mode.
     */

925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005


1006
1007
1008
1009

1010
1011
1012




1013



1014

1015
1016
1017
1018
1019
1020
1021











1022







1023
1024
1025
1026

1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071


1072
1073

1074
1075
1076
1077
1078
1079
1080
1081
1082


1083
1084
1085





1086
1087

1088
1089












1090
1091
1092
1093

1094
1095
1096

1097
1098
1099
1100
1101
1102







1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
    if (mode & O_CREAT) {
        if (permissions & S_IWRITE) {
            flags = FILE_ATTRIBUTE_NORMAL;
        } else {
            flags = FILE_ATTRIBUTE_READONLY;
        }
    } else {
	flags = GetFileAttributes(nativeName);
        if (flags == 0xFFFFFFFF) {
	    flags = 0;
	}
    }

    /*
     * Set up the file sharing mode.  We want to allow simultaneous access.
     */

    shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;

    /*
     * Now we get to create the file.
     */

    handle = CreateFile(nativeName, accessMode, shareMode, NULL, createMode,
            flags, (HANDLE) NULL);

    if (handle == INVALID_HANDLE_VALUE) {
	DWORD err;

	openerr:
	err = GetLastError();
	if ((err & 0xffffL) == ERROR_OPEN_FAILED) {
	    err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND;
	}
        TclWinConvertError(err);
	if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "couldn't open \"", fileName, "\": ",
                    Tcl_PosixError(interp), (char *) NULL);
        }
        Tcl_DStringFree(&buffer);
        return NULL;
    }

    if (GetFileType(handle) == FILE_TYPE_CHAR) {
	dcb.DCBlength = sizeof( DCB ) ;
	if (GetCommState(handle, &dcb)) {
	    /*
	     * This is a com port.  Reopen it with the correct modes. 
	     */

	    COMMTIMEOUTS cto;

	    CloseHandle(handle);
	    handle = CreateFile(nativeName, accessMode, 0, NULL, OPEN_EXISTING,
		    flags, NULL);
	    if (handle == INVALID_HANDLE_VALUE) {
		goto openerr;
	    }

	    /*
	     * FileInit the com port.
	     */

	    SetCommMask(handle, EV_RXCHAR);
	    SetupComm(handle, 4096, 4096);
	    PurgeComm(handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR
		    | PURGE_RXCLEAR);
	    cto.ReadIntervalTimeout = MAXDWORD;
	    cto.ReadTotalTimeoutMultiplier = 0;
	    cto.ReadTotalTimeoutConstant = 0;
	    cto.WriteTotalTimeoutMultiplier = 0;
	    cto.WriteTotalTimeoutConstant = 0;
	    SetCommTimeouts(handle, &cto);

	    GetCommState(handle, &dcb);
	    SetCommState(handle, &dcb);
	    channelTypePtr = &comChannelType;
	} else {
	    channelTypePtr = &fileChannelType;
	}
    } else {


	channelTypePtr = &fileChannelType;
    }
    Tcl_DStringFree(&buffer);


    infoPtr = (FileInfo *) ckalloc((unsigned) sizeof(FileInfo));
    infoPtr->nextPtr = firstFilePtr;
    firstFilePtr = infoPtr;




    infoPtr->validMask = channelPermissions;



    infoPtr->watchMask = 0;

    infoPtr->flags = (mode & O_APPEND) ? FILE_APPEND : 0;
    infoPtr->handle = handle;
   
    sprintf(channelName, "file%d", (int) handle);

    infoPtr->channel = Tcl_CreateChannel(channelTypePtr, channelName,
            (ClientData) infoPtr, channelPermissions);



















    if (seekFlag) {
        if (Tcl_Seek(infoPtr->channel, 0, SEEK_END) < 0) {
            if (interp != (Tcl_Interp *) NULL) {
                Tcl_AppendResult(interp, "could not seek to end of file on \"",

                        channelName, "\": ", Tcl_PosixError(interp),
                        (char *) NULL);
            }
            Tcl_Close(NULL, infoPtr->channel);
            return NULL;
        }
    }

    /*
     * Files have default translation of AUTO and ^Z eof char, which
     * means that a ^Z will be appended to them at close.
     */
    
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");
    return infoPtr->channel;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_MakeFileChannel --
 *
 *	Creates a Tcl_Channel from an existing platform specific file
 *	handle.
 *
 * Results:
 *	The Tcl_Channel created around the preexisting file.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_MakeFileChannel(handle, mode)
    ClientData handle;		/* OS level handle */
    int mode;			/* ORed combination of TCL_READABLE and
                                 * TCL_WRITABLE to indicate file mode. */
{
    char channelName[20];
    FileInfo *infoPtr;

    if (!initialized) {


	FileInit();
    }


    if (mode == 0) {
	return NULL;
    }

    sprintf(channelName, "file%d", (int) handle);

    /*
     * See if a channel with this handle already exists.


     */
    
    for (infoPtr = firstFilePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {





	if (infoPtr->handle == (HANDLE) handle) {
	    return (mode == infoPtr->validMask) ? infoPtr->channel : NULL;

	}
    }













    infoPtr = (FileInfo *) ckalloc((unsigned) sizeof(FileInfo));
    infoPtr->nextPtr = firstFilePtr;
    firstFilePtr = infoPtr;

    infoPtr->validMask = mode;
    infoPtr->watchMask = 0;
    infoPtr->flags = 0;

    infoPtr->handle = (HANDLE) handle;
    infoPtr->channel = Tcl_CreateChannel(&fileChannelType, channelName,
            (ClientData) infoPtr, mode);

    /*
     * Windows files have AUTO translation mode and ^Z eof char on input.







     */
    
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");
    return infoPtr->channel;
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetDefaultStdChannel --
 *
 *	Constructs a channel for the specified standard OS handle.
 *
 * Results:
 *	Returns the specified default standard channel, or NULL.
 *
 * Side effects:
 *	May cause the creation of a standard channel and the underlying
 *	file.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclGetDefaultStdChannel(type)
    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{
    Tcl_Channel channel;
    HANDLE handle;
    int mode;
    char *bufMode;
    DWORD handleId;		/* Standard handle to retrieve. */







|















|
|



<
<







|




|
|
|
<
|
<
<
|
<
|
<
<
<
<
<
<
|
<
<
|

|
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
|
>
>
|
|
<
|
>
|
|
|
>
>
>
>
|
>
>
>
|
>
|
|
|
|
|
<
|
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
|
|
|
|
>
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
|




















|
|



|
|
|
|
>
>
|
<
>





|


|
>
>

|
<
>
>
>
>
>
|
<
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
|
>
|
<
<
>
|
<
<
|
<
|
>
>
>
>
>
>
>
|
|
|
<
|





|














|







731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758


759
760
761
762
763
764
765
766
767
768
769
770
771
772
773

774


775

776






777


778
779
780








781
782






783
784
785
786
787

788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807

808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840







841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873

874
875
876
877
878
879
880
881
882
883
884
885
886
887

888
889
890
891
892
893

894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909


910
911
912


913
914


915

916
917
918
919
920
921
922
923
924
925
926

927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
    if (mode & O_CREAT) {
        if (permissions & S_IWRITE) {
            flags = FILE_ATTRIBUTE_NORMAL;
        } else {
            flags = FILE_ATTRIBUTE_READONLY;
        }
    } else {
	flags = (*tclWinProcs->getFileAttributesProc)(nativeName);
        if (flags == 0xFFFFFFFF) {
	    flags = 0;
	}
    }

    /*
     * Set up the file sharing mode.  We want to allow simultaneous access.
     */

    shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;

    /*
     * Now we get to create the file.
     */

    handle = (*tclWinProcs->createFileProc)(nativeName, accessMode, 
	    shareMode, NULL, createMode, flags, (HANDLE) NULL);

    if (handle == INVALID_HANDLE_VALUE) {
	DWORD err;


	err = GetLastError();
	if ((err & 0xffffL) == ERROR_OPEN_FAILED) {
	    err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND;
	}
        TclWinConvertError(err);
	if (interp != (Tcl_Interp *) NULL) {
            Tcl_AppendResult(interp, "couldn't open \"", fileName, "\": ",
			     Tcl_PosixError(interp), (char *) NULL);
        }
        Tcl_DStringFree(&buffer);
        return NULL;
    }
    
    type = GetFileType(handle);


    /*


     * If the file is a character device, we need to try to figure out

     * whether it is a serial port, a console, or something else.  We






     * test for the console case first because this is more common.


     */

    if (type == FILE_TYPE_CHAR) {








	if (GetConsoleMode(handle, &consoleParams)) {
	    type = FILE_TYPE_CONSOLE;






	} else {
	    dcb.DCBlength = sizeof( DCB ) ;
	    if (GetCommState(handle, &dcb)) {
		type = FILE_TYPE_SERIAL;
	    }

	}
    }

    channel = NULL;

    switch (type)
    {
    case FILE_TYPE_SERIAL:
	channel = TclWinOpenSerialChannel(handle, channelName,
	        channelPermissions);
	break;
    case FILE_TYPE_CONSOLE:
	channel = TclWinOpenConsoleChannel(handle, channelName,
	        channelPermissions);
	break;
    case FILE_TYPE_PIPE:
	if (channelPermissions & TCL_READABLE)
	{
	    readFile = TclWinMakeFile(handle);
	}

	if (channelPermissions & TCL_WRITABLE)
	{
	    writeFile = TclWinMakeFile(handle);
	}
	channel = TclpCreateCommandChannel(readFile, writeFile, NULL, 0, NULL);
	break;
    case FILE_TYPE_CHAR:
    default:
	channel = TclWinOpenFileChannel(handle, channelName,
					channelPermissions,
					(mode & O_APPEND) ? FILE_APPEND : 0);
	break;

    }

    Tcl_DStringFree(&buffer);
    Tcl_DStringFree(&ds);

    if (channel != NULL)
    {
	if (seekFlag) {
	    if (Tcl_Seek(channel, 0, SEEK_END) < 0) {
		if (interp != (Tcl_Interp *) NULL) {
		    Tcl_AppendResult(interp,
			    "could not seek to end of file on \"",
			    channelName, "\": ", Tcl_PosixError(interp),
			    (char *) NULL);
		}
		Tcl_Close(NULL, channel);
		return NULL;
	    }
	}
    }







    return channel;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_MakeFileChannel --
 *
 *	Creates a Tcl_Channel from an existing platform specific file
 *	handle.
 *
 * Results:
 *	The Tcl_Channel created around the preexisting file.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
Tcl_MakeFileChannel(rawHandle, mode)
    ClientData rawHandle;	/* OS level handle */
    int mode;			/* ORed combination of TCL_READABLE and
                                 * TCL_WRITABLE to indicate file mode. */
{
    char channelName[16 + TCL_INTEGER_SPACE];
    Tcl_Channel channel = NULL;
    HANDLE handle = (HANDLE) rawHandle;
    DCB dcb;
    DWORD consoleParams;
    DWORD type;
    TclFile readFile = NULL;

    TclFile writeFile = NULL;

    if (mode == 0) {
	return NULL;
    }

    type = GetFileType(handle);

    /*
     * If the file is a character device, we need to try to figure out
     * whether it is a serial port, a console, or something else.  We
     * test for the console case first because this is more common.
     */


    if (type == FILE_TYPE_CHAR) {
	if (GetConsoleMode(handle, &consoleParams)) {
	    type = FILE_TYPE_CONSOLE;
	} else {
	    dcb.DCBlength = sizeof( DCB ) ;
	    if (GetCommState(handle, &dcb)) {

		type = FILE_TYPE_SERIAL;
	    }
	}
    }

    switch (type)
    {
    case FILE_TYPE_SERIAL:
	channel = TclWinOpenSerialChannel(handle, channelName, mode);
	break;
    case FILE_TYPE_CONSOLE:
	channel = TclWinOpenConsoleChannel(handle, channelName, mode);
	break;
    case FILE_TYPE_PIPE:
	if (mode & TCL_READABLE)
	{


	    readFile = TclWinMakeFile(handle);
	}
	if (mode & TCL_WRITABLE)


	{
	    writeFile = TclWinMakeFile(handle);


	}

	channel = TclpCreateCommandChannel(readFile, writeFile, NULL, 0, NULL);
	break;
    case FILE_TYPE_UNKNOWN:
	break;
    case FILE_TYPE_CHAR:
    default:
	channel = TclWinOpenFileChannel(handle, channelName, mode, 0);
	break;

    }


    return channel;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpGetDefaultStdChannel --
 *
 *	Constructs a channel for the specified standard OS handle.
 *
 * Results:
 *	Returns the specified default standard channel, or NULL.
 *
 * Side effects:
 *	May cause the creation of a standard channel and the underlying
 *	file.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclpGetDefaultStdChannel(type)
    int type;			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
{
    Tcl_Channel channel;
    HANDLE handle;
    int mode;
    char *bufMode;
    DWORD handleId;		/* Standard handle to retrieve. */
1163
1164
1165
1166
1167
1168
1169



1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185





































































     */

    if ((handle == INVALID_HANDLE_VALUE) || (handle == 0)) {
	return NULL;
    }

    channel = Tcl_MakeFileChannel(handle, mode);




    /*
     * Set up the normal channel options for stdio handles.
     */

    if ((Tcl_SetChannelOption((Tcl_Interp *) NULL, channel, "-translation",
            "auto") == TCL_ERROR)
	    || (Tcl_SetChannelOption((Tcl_Interp *) NULL, channel, "-eofchar",
		    "\032 {}") == TCL_ERROR)
	    || (Tcl_SetChannelOption((Tcl_Interp *) NULL, channel,
		    "-buffering", bufMode) == TCL_ERROR)) {
        Tcl_Close((Tcl_Interp *) NULL, channel);
        return (Tcl_Channel) NULL;
    }
    return channel;
}












































































>
>
>
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
     */

    if ((handle == INVALID_HANDLE_VALUE) || (handle == 0)) {
	return NULL;
    }

    channel = Tcl_MakeFileChannel(handle, mode);
    if (channel == NULL) {
	return NULL;
    }

    /*
     * Set up the normal channel options for stdio handles.
     */

    if ((Tcl_SetChannelOption((Tcl_Interp *) NULL, channel, "-translation",
            "auto") == TCL_ERROR)
	    || (Tcl_SetChannelOption((Tcl_Interp *) NULL, channel, "-eofchar",
		    "\032 {}") == TCL_ERROR)
	    || (Tcl_SetChannelOption((Tcl_Interp *) NULL, channel,
		    "-buffering", bufMode) == TCL_ERROR)) {
        Tcl_Close((Tcl_Interp *) NULL, channel);
        return (Tcl_Channel) NULL;
    }
    return channel;
}



/*
 *----------------------------------------------------------------------
 *
 * TclWinOpenFileChannel --
 *
 *	Constructs a File channel for the specified standard OS handle.
 *      This is a helper function to break up the construction of 
 *      channels into File, Console, or Serial.
 *
 * Results:
 *	Returns the new channel, or NULL.
 *
 * Side effects:
 *	May open the channel and may cause creation of a file on the
 *	file system.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclWinOpenFileChannel(handle, channelName, permissions, appendMode)
    HANDLE handle;
    char *channelName;
    int permissions;
    int appendMode;
{
    FileInfo *infoPtr;
    ThreadSpecificData *tsdPtr;

    tsdPtr = FileInit();

    /*
     * See if a channel with this handle already exists.
     */
    
    for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->handle == (HANDLE) handle) {
	    return (permissions == infoPtr->validMask) ? infoPtr->channel : NULL;
	}
    }

    infoPtr = (FileInfo *) ckalloc((unsigned) sizeof(FileInfo));
    infoPtr->nextPtr = tsdPtr->firstFilePtr;
    tsdPtr->firstFilePtr = infoPtr;
    infoPtr->validMask = permissions;
    infoPtr->watchMask = 0;
    infoPtr->flags = appendMode;
    infoPtr->handle = handle;
	
    wsprintfA(channelName, "file%lx", (int) infoPtr);
    
    infoPtr->channel = Tcl_CreateChannel(&fileChannelType, channelName,
	    (ClientData) infoPtr, permissions);
    
    /*
     * Files have default translation of AUTO and ^Z eof char, which
     * means that a ^Z will be accepted as EOF when reading.
     */
    
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");

    return infoPtr->channel;
}

Added win/tclWinConsole.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
/* 
 * tclWinConsole.c --
 *
 *	This file implements the Windows-specific console functions,
 *	and the "console" channel driver.
 *
 * Copyright (c) 1999 by Scriptics Corp.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclWinConsole.c,v 1.1.2.7 1999/04/05 21:58:15 stanton Exp $
 */

#include "tclWinInt.h"

#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>

/*
 * The following variable is used to tell whether this module has been
 * initialized.
 */

static int initialized = 0;

/*
 * The consoleMutex locks around access to the initialized variable, and it is
 * used to protect background threads from being terminated while they are
 * using APIs that hold locks.
 */

TCL_DECLARE_MUTEX(consoleMutex)

/*
 * Bit masks used in the flags field of the ConsoleInfo structure below.
 */

#define CONSOLE_PENDING	(1<<0)	/* Message is pending in the queue. */
#define CONSOLE_ASYNC	(1<<1)	/* Channel is non-blocking. */

/*
 * Bit masks used in the sharedFlags field of the ConsoleInfo structure below.
 */

#define CONSOLE_EOF	  (1<<2)  /* Console has reached EOF. */
#define CONSOLE_BUFFERED  (1<<3)  /* data was read into a buffer by the reader
				     thread */

#define CONSOLE_BUFFER_SIZE (8*1024)
/*
 * This structure describes per-instance data for a console based channel.
 */

typedef struct ConsoleInfo {
    HANDLE handle;
    int type;
    struct ConsoleInfo *nextPtr;/* Pointer to next registered console. */
    Tcl_Channel channel;	/* Pointer to channel structure. */
    int validMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which operations are valid on the file. */
    int watchMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which events should be reported. */
    int flags;			/* State flags, see above for a list. */
    Tcl_ThreadId threadId;	/* Thread to which events should be reported.
				 * This value is used by the reader/writer
				 * threads. */
    HANDLE writeThread;		/* Handle to writer thread. */
    HANDLE readThread;		/* Handle to reader thread. */
    HANDLE writable;		/* Manual-reset event to signal when the
				 * writer thread has finished waiting for
				 * the current buffer to be written. */
    HANDLE readable;		/* Manual-reset event to signal when the
				 * reader thread has finished waiting for
				 * input. */
    HANDLE startWriter;		/* Auto-reset event used by the main thread to
				 * signal when the writer thread should attempt
				 * to write to the console. */
    HANDLE startReader;		/* Auto-reset event used by the main thread to
				 * signal when the reader thread should attempt
				 * to read from the console. */
    DWORD writeError;		/* An error caused by the last background
				 * write.  Set to 0 if no error has been
				 * detected.  This word is shared with the
				 * writer thread so access must be
				 * synchronized with the writable object.
				 */
    char *writeBuf;		/* Current background output buffer.
				 * Access is synchronized with the writable
				 * object. */
    int writeBufLen;		/* Size of write buffer.  Access is
				 * synchronized with the writable
				 * object. */
    int toWrite;		/* Current amount to be written.  Access is
				 * synchronized with the writable object. */
    int readFlags;		/* Flags that are shared with the reader
				 * thread.  Access is synchronized with the
				 * readable object.  */
    int bytesRead;              /* number of bytes in the buffer */
    int offset;                 /* number of bytes read out of the buffer */
    char buffer[CONSOLE_BUFFER_SIZE];
                                /* Data consumed by reader thread. */
} ConsoleInfo;

typedef struct ThreadSpecificData {
    /*
     * The following pointer refers to the head of the list of consoles
     * that are being watched for file events.
     */
    
    ConsoleInfo *firstConsolePtr;
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * The following structure is what is added to the Tcl event queue when
 * console events are generated.
 */

typedef struct ConsoleEvent {
    Tcl_Event header;		/* Information that is standard for
				 * all events. */
    ConsoleInfo *infoPtr;	/* Pointer to console info structure.  Note
				 * that we still have to verify that the
				 * console exists before dereferencing this
				 * pointer. */
} ConsoleEvent;

/*
 * Declarations for functions used only in this file.
 */

static int		ApplicationType(Tcl_Interp *interp,
			    const char *fileName, char *fullName);
static void		BuildCommandLine(const char *executable, int argc, 
			    char **argv, Tcl_DString *linePtr);
static void		CopyChannel(HANDLE dst, HANDLE src);
static BOOL		HasConsole(void);
static TclFile		MakeFile(HANDLE handle);
static char *		MakeTempFile(Tcl_DString *namePtr);
static int		ConsoleBlockModeProc(ClientData instanceData, int mode);
static void		ConsoleCheckProc(ClientData clientData, int flags);
static int		ConsoleCloseProc(ClientData instanceData,
			    Tcl_Interp *interp);
static int		ConsoleEventProc(Tcl_Event *evPtr, int flags);
static void		ConsoleExitHandler(ClientData clientData);
static int		ConsoleGetHandleProc(ClientData instanceData,
			    int direction, ClientData *handlePtr);
static ThreadSpecificData *ConsoleInit(void);
static int		ConsoleInputProc(ClientData instanceData, char *buf,
			    int toRead, int *errorCode);
static int		ConsoleOutputProc(ClientData instanceData, char *buf,
			    int toWrite, int *errorCode);
static DWORD WINAPI	ConsoleReaderThread(LPVOID arg);
static void		ConsoleSetupProc(ClientData clientData, int flags);
static void		ConsoleWatchProc(ClientData instanceData, int mask);
static DWORD WINAPI	ConsoleWriterThread(LPVOID arg);
static void		ProcExitHandler(ClientData clientData);
static int		TempFileName(WCHAR name[MAX_PATH]);
static int		WaitForRead(ConsoleInfo *infoPtr, int blocking);

/*
 * This structure describes the channel type structure for command console
 * based IO.
 */

static Tcl_ChannelType consoleChannelType = {
    "console",			/* Type name. */
    ConsoleBlockModeProc,	/* Set blocking or non-blocking mode.*/
    ConsoleCloseProc,		/* Close proc. */
    ConsoleInputProc,		/* Input proc. */
    ConsoleOutputProc,		/* Output proc. */
    NULL,			/* Seek proc. */
    NULL,			/* Set option proc. */
    NULL,			/* Get option proc. */
    ConsoleWatchProc,		/* Set up notifier to watch the channel. */
    ConsoleGetHandleProc,	/* Get an OS handle from channel. */
};

/*
 *----------------------------------------------------------------------
 *
 * ConsoleInit --
 *
 *	This function initializes the static variables for this file.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new event source.
 *
 *----------------------------------------------------------------------
 */

static ThreadSpecificData *
ConsoleInit()
{
    ThreadSpecificData *tsdPtr;

    /*
     * Check the initialized flag first, then check again in the mutex.
     * This is a speed enhancement.
     */

    if (!initialized) {
	Tcl_MutexLock(&consoleMutex);
	if (!initialized) {
	    initialized = 1;
	    Tcl_CreateExitHandler(ProcExitHandler, NULL);
	}
	Tcl_MutexUnlock(&consoleMutex);
    }

    tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
	tsdPtr->firstConsolePtr = NULL;
	Tcl_CreateEventSource(ConsoleSetupProc, ConsoleCheckProc, NULL);
	Tcl_CreateThreadExitHandler(ConsoleExitHandler, NULL);
    }
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleExitHandler --
 *
 *	This function is called to cleanup the console module before
 *	Tcl is unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Removes the console event source.
 *
 *----------------------------------------------------------------------
 */

static void
ConsoleExitHandler(
    ClientData clientData)	/* Old window proc */
{
    Tcl_DeleteEventSource(ConsoleSetupProc, ConsoleCheckProc, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * ProcExitHandler --
 *
 *	This function is called to cleanup the process list before
 *	Tcl is unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resets the process list.
 *
 *----------------------------------------------------------------------
 */

static void
ProcExitHandler(
    ClientData clientData)	/* Old window proc */
{
    Tcl_MutexLock(&consoleMutex);
    initialized = 0;
    Tcl_MutexUnlock(&consoleMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleSetupProc --
 *
 *	This procedure is invoked before Tcl_DoOneEvent blocks waiting
 *	for an event.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Adjusts the block time if needed.
 *
 *----------------------------------------------------------------------
 */

void
ConsoleSetupProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    ConsoleInfo *infoPtr;
    Tcl_Time blockTime = { 0, 0 };
    int block = 1;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Look to see if any events are already pending.  If they are, poll.
     */

    for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask & TCL_WRITABLE) {
	    if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) {
		block = 0;
	    }
	}
	if (infoPtr->watchMask & TCL_READABLE) {
	    if (WaitForRead(infoPtr, 0) >= 0) {
		block = 0;
	    }
	}
    }
    if (!block) {
	Tcl_SetMaxBlockTime(&blockTime);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleCheckProc --
 *
 *	This procedure is called by Tcl_DoOneEvent to check the console
 *	event source for events. 
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May queue an event.
 *
 *----------------------------------------------------------------------
 */

static void
ConsoleCheckProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    ConsoleInfo *infoPtr;
    ConsoleEvent *evPtr;
    int needEvent;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Queue events for any ready consoles that don't already have events
     * queued.
     */

    for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->flags & CONSOLE_PENDING) {
	    continue;
	}
	
	/*
	 * Queue an event if the console is signaled for reading or writing.
	 */

	needEvent = 0;
	if (infoPtr->watchMask & TCL_WRITABLE) {
	    if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) {
		needEvent = 1;
	    }
	}
	
	if (infoPtr->watchMask & TCL_READABLE) {
	    if (WaitForRead(infoPtr, 0) >= 0) {
		needEvent = 1;
	    }
	}

	if (needEvent) {
	    infoPtr->flags |= CONSOLE_PENDING;
	    evPtr = (ConsoleEvent *) ckalloc(sizeof(ConsoleEvent));
	    evPtr->header.proc = ConsoleEventProc;
	    evPtr->infoPtr = infoPtr;
	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
	}
    }
}


/*
 *----------------------------------------------------------------------
 *
 * ConsoleBlockModeProc --
 *
 *	Set blocking or non-blocking mode on channel.
 *
 * Results:
 *	0 if successful, errno when failed.
 *
 * Side effects:
 *	Sets the device into blocking or non-blocking mode.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleBlockModeProc(
    ClientData instanceData,	/* Instance data for channel. */
    int mode)			/* TCL_MODE_BLOCKING or
                                 * TCL_MODE_NONBLOCKING. */
{
    ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
    
    /*
     * Consoles on Windows can not be switched between blocking and nonblocking,
     * hence we have to emulate the behavior. This is done in the input
     * function by checking against a bit in the state. We set or unset the
     * bit here to cause the input function to emulate the correct behavior.
     */

    if (mode == TCL_MODE_NONBLOCKING) {
	infoPtr->flags |= CONSOLE_ASYNC;
    } else {
	infoPtr->flags &= ~(CONSOLE_ASYNC);
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleCloseProc --
 *
 *	Closes a console based IO channel.
 *
 * Results:
 *	0 on success, errno otherwise.
 *
 * Side effects:
 *	Closes the physical channel.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleCloseProc(
    ClientData instanceData,	/* Pointer to ConsoleInfo structure. */
    Tcl_Interp *interp)		/* For error reporting. */
{
    ConsoleInfo *consolePtr = (ConsoleInfo *) instanceData;
    int errorCode;
    ConsoleInfo *infoPtr, **nextPtrPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    errorCode = 0;
    
    /*
     * Clean up the background thread if necessary.  Note that this
     * must be done before we can close the file, since the 
     * thread may be blocking trying to read from the console.
     */
    
    if (consolePtr->readThread) {
	/*
	 * Forcibly terminate the background thread.  We cannot rely on the
	 * thread to cleanly terminate itself because we have no way of
	 * closing the handle without blocking in the case where the
	 * thread is in the middle of an I/O operation.  Note that we need
	 * to guard against terminating the thread while it is in the
	 * middle of Tcl_ThreadAlert because it won't be able to release
	 * the notifier lock.
	 */

	Tcl_MutexLock(&consoleMutex);
	TerminateThread(consolePtr->readThread, 0);
	Tcl_MutexUnlock(&consoleMutex);

	/*
	 * Wait for the thread to terminate.  This ensures that we are
	 * completely cleaned up before we leave this function. 
	 */

	WaitForSingleObject(consolePtr->readThread, INFINITE);
	CloseHandle(consolePtr->readThread);
	CloseHandle(consolePtr->readable);
	CloseHandle(consolePtr->startReader);
	consolePtr->readThread = NULL;
    }
    consolePtr->validMask &= ~TCL_READABLE;

    /*
     * Wait for the writer thread to finish the current buffer, then
     * terminate the thread and close the handles.  If the channel is
     * nonblocking, there should be no pending write operations.
     */
    
    if (consolePtr->writeThread) {
	WaitForSingleObject(consolePtr->writable, INFINITE);

	/*
	 * Forcibly terminate the background thread.  We cannot rely on the
	 * thread to cleanly terminate itself because we have no way of
	 * closing the handle without blocking in the case where the
	 * thread is in the middle of an I/O operation.  Note that we need
	 * to guard against terminating the thread while it is in the
	 * middle of Tcl_ThreadAlert because it won't be able to release
	 * the notifier lock.
	 */

	Tcl_MutexLock(&consoleMutex);
	TerminateThread(consolePtr->writeThread, 0);
	Tcl_MutexUnlock(&consoleMutex);

	/*
	 * Wait for the thread to terminate.  This ensures that we are
	 * completely cleaned up before we leave this function. 
	 */

	WaitForSingleObject(consolePtr->writeThread, INFINITE);
	CloseHandle(consolePtr->writeThread);
	CloseHandle(consolePtr->writable);
	CloseHandle(consolePtr->startWriter);
	consolePtr->writeThread = NULL;
    }
    consolePtr->validMask &= ~TCL_WRITABLE;


    /*
     * Don't close the Win32 handle if the handle is a standard channel
     * during the exit process.  Otherwise, one thread may kill the stdio
     * of another.
     */

    if (!TclInExit() 
	    || ((GetStdHandle(STD_INPUT_HANDLE) != consolePtr->handle)
		&& (GetStdHandle(STD_OUTPUT_HANDLE) != consolePtr->handle)
		&& (GetStdHandle(STD_ERROR_HANDLE) != consolePtr->handle))) {
	if (CloseHandle(consolePtr->handle) == FALSE) {
	    TclWinConvertError(GetLastError());
	    errorCode = errno;
	}
    }
    
    consolePtr->watchMask &= consolePtr->validMask;

    /*
     * Remove the file from the list of watched files.
     */

    for (nextPtrPtr = &(tsdPtr->firstConsolePtr), infoPtr = *nextPtrPtr;
	    infoPtr != NULL;
	    nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) {
	if (infoPtr == (ConsoleInfo *)consolePtr) {
	    *nextPtrPtr = infoPtr->nextPtr;
	    break;
	}
    }
    if (consolePtr->writeBuf != NULL) {
	ckfree(consolePtr->writeBuf);
	consolePtr->writeBuf = 0;
    }
    ckfree((char*) consolePtr);

    return errorCode;
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleInputProc --
 *
 *	Reads input from the IO channel into the buffer given. Returns
 *	count of how many bytes were actually read, and an error indication.
 *
 * Results:
 *	A count of how many bytes were read is returned and an error
 *	indication is returned in an output argument.
 *
 * Side effects:
 *	Reads input from the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleInputProc(
    ClientData instanceData,		/* Console state. */
    char *buf,				/* Where to store data read. */
    int bufSize,			/* How much space is available
                                         * in the buffer? */
    int *errorCode)			/* Where to store error code. */
{
    ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
    DWORD count, bytesRead = 0;
    int result;

    *errorCode = 0;

    /*
     * Synchronize with the reader thread.
     */
    
    result = WaitForRead(infoPtr, (infoPtr->flags & CONSOLE_ASYNC) ? 0 : 1);
    
    /*
     * If an error occurred, return immediately.
     */
    
    if (result == -1) {
	*errorCode = errno;
	return -1;
    }

    if (infoPtr->readFlags & CONSOLE_BUFFERED) {
	/*
	 * Data is stored in the buffer.
	 */

	if (bufSize < (infoPtr->bytesRead - infoPtr->offset)) {
	    memcpy(buf, &infoPtr->buffer[infoPtr->offset], bufSize);
	    bytesRead = bufSize;
	    infoPtr->offset += bufSize;
	} else {
	    memcpy(buf, &infoPtr->buffer[infoPtr->offset], bufSize);
	    bytesRead = infoPtr->bytesRead - infoPtr->offset;

	    /*
	     * Reset the buffer
	     */
	    
	    infoPtr->readFlags &= ~CONSOLE_BUFFERED;
	    infoPtr->offset = 0;
	}

	return bytesRead;
    }
    
    /*
     * Attempt to read bufSize bytes.  The read will return immediately
     * if there is any data available.  Otherwise it will block until
     * at least one byte is available or an EOF occurs.
     */

    if (ReadConsole(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &count,
		    (LPOVERLAPPED) NULL) == TRUE) {
	buf[count] = '\0';
	return count;
    }

    return -1;
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleOutputProc --
 *
 *	Writes the given output on the IO channel. Returns count of how
 *	many characters were actually written, and an error indication.
 *
 * Results:
 *	A count of how many characters were written is returned and an
 *	error indication is returned in an output argument.
 *
 * Side effects:
 *	Writes output on the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleOutputProc(
    ClientData instanceData,		/* Console state. */
    char *buf,				/* The data buffer. */
    int toWrite,			/* How many bytes to write? */
    int *errorCode)			/* Where to store error code. */
{
    ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
    DWORD bytesWritten, timeout;
    
    *errorCode = 0;
    timeout = (infoPtr->flags & CONSOLE_ASYNC) ? 0 : INFINITE;
    if (WaitForSingleObject(infoPtr->writable, timeout) == WAIT_TIMEOUT) {
	/*
	 * The writer thread is blocked waiting for a write to complete
	 * and the channel is in non-blocking mode.
	 */

	errno = EAGAIN;
	goto error;
    }
    
    /*
     * Check for a background error on the last write.
     */

    if (infoPtr->writeError) {
	TclWinConvertError(infoPtr->writeError);
	infoPtr->writeError = 0;
	goto error;
    }

    if (infoPtr->flags & CONSOLE_ASYNC) {
	/*
	 * The console is non-blocking, so copy the data into the output
	 * buffer and restart the writer thread.
	 */

	if (toWrite > infoPtr->writeBufLen) {
	    /*
	     * Reallocate the buffer to be large enough to hold the data.
	     */

	    if (infoPtr->writeBuf) {
		ckfree(infoPtr->writeBuf);
	    }
	    infoPtr->writeBufLen = toWrite;
	    infoPtr->writeBuf = ckalloc(toWrite);
	}
	memcpy(infoPtr->writeBuf, buf, toWrite);
	infoPtr->toWrite = toWrite;
	ResetEvent(infoPtr->writable);
	SetEvent(infoPtr->startWriter);
	bytesWritten = toWrite;
    } else {
	/*
	 * In the blocking case, just try to write the buffer directly.
	 * This avoids an unnecessary copy.
	 */

	if (WriteFile(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite,
		&bytesWritten, (LPOVERLAPPED) NULL) == FALSE) {
	    TclWinConvertError(GetLastError());
	    goto error;
	}
    }
    return bytesWritten;

    error:
    *errorCode = errno;
    return -1;

}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleEventProc --
 *
 *	This function is invoked by Tcl_ServiceEvent when a file event
 *	reaches the front of the event queue.  This procedure invokes
 *	Tcl_NotifyChannel on the console.
 *
 * Results:
 *	Returns 1 if the event was handled, meaning it should be removed
 *	from the queue.  Returns 0 if the event was not handled, meaning
 *	it should stay on the queue.  The only time the event isn't
 *	handled is if the TCL_FILE_EVENTS flag bit isn't set.
 *
 * Side effects:
 *	Whatever the notifier callback does.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleEventProc(
    Tcl_Event *evPtr,		/* Event to service. */
    int flags)			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    ConsoleEvent *consoleEvPtr = (ConsoleEvent *)evPtr;
    ConsoleInfo *infoPtr;
    int mask;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the list of watched consoles for the one whose handle
     * matches the event.  We do this rather than simply dereferencing
     * the handle in the event so that consoles can be deleted while the
     * event is in the queue.
     */

    for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (consoleEvPtr->infoPtr == infoPtr) {
	    infoPtr->flags &= ~(CONSOLE_PENDING);
	    break;
	}
    }

    /*
     * Remove stale events.
     */

    if (!infoPtr) {
	return 1;
    }

    /*
     * Check to see if the console is readable.  Note
     * that we can't tell if a console is writable, so we always report it
     * as being writable unless we have detected EOF.
     */

    mask = 0;
    if (infoPtr->watchMask & TCL_WRITABLE) {
	if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) {
	  mask = TCL_WRITABLE;
	}
    }

    if (infoPtr->watchMask & TCL_READABLE) {
	if (WaitForRead(infoPtr, 0) >= 0) {
	    if (infoPtr->readFlags & CONSOLE_EOF) {
		mask = TCL_READABLE;
	    } else {
		mask |= TCL_READABLE;
	    }
	} 
    }

    /*
     * Inform the channel of the events.
     */

    Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask & mask);
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleWatchProc --
 *
 *	Called by the notifier to set up to watch for events on this
 *	channel.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
ConsoleWatchProc(
    ClientData instanceData,		/* Console state. */
    int mask)				/* What events to watch for, OR-ed
                                         * combination of TCL_READABLE,
                                         * TCL_WRITABLE and TCL_EXCEPTION. */
{
    ConsoleInfo **nextPtrPtr, *ptr;
    ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
    int oldMask = infoPtr->watchMask;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Since most of the work is handled by the background threads,
     * we just need to update the watchMask and then force the notifier
     * to poll once. 
     */

    infoPtr->watchMask = mask & infoPtr->validMask;
    if (infoPtr->watchMask) {
	Tcl_Time blockTime = { 0, 0 };
	if (!oldMask) {
	    infoPtr->nextPtr = tsdPtr->firstConsolePtr;
	    tsdPtr->firstConsolePtr = infoPtr;
	}
	Tcl_SetMaxBlockTime(&blockTime);
    } else {
	if (oldMask) {
	    /*
	     * Remove the console from the list of watched consoles.
	     */

	    for (nextPtrPtr = &(tsdPtr->firstConsolePtr), ptr = *nextPtrPtr;
		 ptr != NULL;
		 nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
		if (infoPtr == ptr) {
		    *nextPtrPtr = ptr->nextPtr;
		    break;
		}
	    }
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleGetHandleProc --
 *
 *	Called from Tcl_GetChannelHandle to retrieve OS handles from
 *	inside a command consoleline based channel.
 *
 * Results:
 *	Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
 *	there is no handle for the specified direction. 
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ConsoleGetHandleProc(
    ClientData instanceData,	/* The console state. */
    int direction,		/* TCL_READABLE or TCL_WRITABLE */
    ClientData *handlePtr)	/* Where to store the handle.  */
{
    ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;

    *handlePtr = (ClientData) infoPtr->handle;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WaitForRead --
 *
 *	Wait until some data is available, the console is at
 *	EOF or the reader thread is blocked waiting for data (if the
 *	channel is in non-blocking mode).
 *
 * Results:
 *	Returns 1 if console is readable.  Returns 0 if there is no data
 *	on the console, but there is buffered data.  Returns -1 if an
 *	error occurred.  If an error occurred, the threads may not
 *	be synchronized.
 *
 * Side effects:
 *	Updates the shared state flags.  If no error occurred,
 *      the reader thread is blocked waiting for a signal from the 
 *      main thread.
 *
 *----------------------------------------------------------------------
 */

static int
WaitForRead(
    ConsoleInfo *infoPtr,		/* Console state. */
    int blocking)		/* Indicates whether call should be
				 * blocking or not. */
{
    DWORD timeout, count;
    HANDLE *handle = infoPtr->handle;
    INPUT_RECORD input;
    
    while (1) {
	/*
	 * Synchronize with the reader thread.
	 */
       
	timeout = blocking ? INFINITE : 0;
	if (WaitForSingleObject(infoPtr->readable, timeout) == WAIT_TIMEOUT) {
	    /*
	     * The reader thread is blocked waiting for data and the channel
	     * is in non-blocking mode.
	     */
	    errno = EAGAIN;
	    return -1;
	}
	
	/*
	 * At this point, the two threads are synchronized, so it is safe
	 * to access shared state.
	 */
	
	/*
	 * If the console has hit EOF, it is always readable.
	 */
	
	if (infoPtr->readFlags & CONSOLE_EOF) {
	    return 1;
	}
	
	if (PeekConsoleInput(handle, &input, 1, &count) == FALSE) {
            /*
	     * Check to see if the peek failed because of EOF.
	     */
	    
	    TclWinConvertError(GetLastError());
	    
	    if (errno == EOF) {
		infoPtr->readFlags |= CONSOLE_EOF;
		return 1;
	    }

	    /*
	     * Ignore errors if there is data in the buffer.
	     */
	    
	    if (infoPtr->readFlags & CONSOLE_BUFFERED) {
		return 0;
	    } else {
		return -1;
	    }
	}

	/*
	 * If there is data in the buffer, the console must be
	 * readable (since it is a line-oriented device).
	 */

	if (infoPtr->readFlags & CONSOLE_BUFFERED) {
	    return 1;
	}

	
	/*
	 * There wasn't any data available, so reset the thread and
	 * try again.
	 */
    
	ResetEvent(infoPtr->readable);
	SetEvent(infoPtr->startReader);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleReaderThread --
 *
 *	This function runs in a separate thread and waits for input
 *	to become available on a console.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Signals the main thread when input become available.  May
 *	cause the main thread to wake up by posting a message.  May
 *	one line from the console for each wait operation.
 *
 *----------------------------------------------------------------------
 */

static DWORD WINAPI
ConsoleReaderThread(LPVOID arg)
{
    ConsoleInfo *infoPtr = (ConsoleInfo *)arg;
    HANDLE *handle = infoPtr->handle;
    DWORD count;

    for (;;) {
	/*
	 * Wait for the main thread to signal before attempting to wait.
	 */

	WaitForSingleObject(infoPtr->startReader, INFINITE);

	count = 0;

	/* 
	 * Look for data on the console, but first ignore any events
	 * that are not KEY_EVENTs 
	 */
	if (ReadConsole(handle, infoPtr->buffer, CONSOLE_BUFFER_SIZE,
		&infoPtr->bytesRead, NULL) != FALSE) {
	    /*
	     * Data was stored in the buffer.
	     */
	    
	    infoPtr->readFlags |= CONSOLE_BUFFERED;
	} else {
	    DWORD err;
	    err = GetLastError();
	    
	    if (err == EOF) {
		infoPtr->readFlags = CONSOLE_EOF;
	    }
	}

	/*
	 * Signal the main thread by signalling the readable event and
	 * then waking up the notifier thread.
	 */

	SetEvent(infoPtr->readable);

	/*
	 * Alert the foreground thread.  Note that we need to treat this like
	 * a critical section so the foreground thread does not terminate
	 * this thread while we are holding a mutex in the notifier code.
	 */

	Tcl_MutexLock(&consoleMutex);
	Tcl_ThreadAlert(infoPtr->threadId);
	Tcl_MutexUnlock(&consoleMutex);
    }
    return 0;			/* NOT REACHED */
}

/*
 *----------------------------------------------------------------------
 *
 * ConsoleWriterThread --
 *
 *	This function runs in a separate thread and writes data
 *	onto a console.
 *
 * Results:
 *	Always returns 0.
 *
 * Side effects:
 *	Signals the main thread when an output operation is completed.
 *	May cause the main thread to wake up by posting a message.  
 *
 *----------------------------------------------------------------------
 */

static DWORD WINAPI
ConsoleWriterThread(LPVOID arg)
{

    ConsoleInfo *infoPtr = (ConsoleInfo *)arg;
    HANDLE *handle = infoPtr->handle;
    DWORD count, toWrite;
    char *buf;

    for (;;) {
	/*
	 * Wait for the main thread to signal before attempting to write.
	 */

	WaitForSingleObject(infoPtr->startWriter, INFINITE);

	buf = infoPtr->writeBuf;
	toWrite = infoPtr->toWrite;

	/*
	 * Loop until all of the bytes are written or an error occurs.
	 */

	while (toWrite > 0) {
	    if (WriteFile(handle, buf, toWrite, &count, NULL) == FALSE) {
		infoPtr->writeError = GetLastError();
		break;
	    } else {
		toWrite -= count;
		buf += count;
	    }
	}

	/*
	 * Signal the main thread by signalling the writable event and
	 * then waking up the notifier thread.
	 */
	
	SetEvent(infoPtr->writable);

	/*
	 * Alert the foreground thread.  Note that we need to treat this like
	 * a critical section so the foreground thread does not terminate
	 * this thread while we are holding a mutex in the notifier code.
	 */

	Tcl_MutexLock(&consoleMutex);
	Tcl_ThreadAlert(infoPtr->threadId);
	Tcl_MutexUnlock(&consoleMutex);
    }
    return 0;			/* NOT REACHED */
}



/*
 *----------------------------------------------------------------------
 *
 * TclWinOpenConsoleChannel --
 *
 *	Constructs a Console channel for the specified standard OS handle.
 *      This is a helper function to break up the construction of 
 *      channels into File, Console, or Serial.
 *
 * Results:
 *	Returns the new channel, or NULL.
 *
 * Side effects:
 *	May open the channel
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclWinOpenConsoleChannel(handle, channelName, permissions)
    HANDLE handle;
    char *channelName;
    int permissions;
{
    char encoding[4 + TCL_INTEGER_SPACE];
    ConsoleInfo *infoPtr;
    ThreadSpecificData *tsdPtr;
    DWORD id;

    tsdPtr = ConsoleInit();

    /*
     * See if a channel with this handle already exists.
     */
    
    infoPtr = (ConsoleInfo *) ckalloc((unsigned) sizeof(ConsoleInfo));
    memset(infoPtr, 0, sizeof(ConsoleInfo));

    infoPtr->validMask = permissions;
    infoPtr->handle = handle;

    wsprintfA(encoding, "cp%d", GetConsoleCP());
    
    /*
     * Use the pointer for the name of the result channel.
     * This keeps the channel names unique, since some may share
     * handles (stdin/stdout/stderr for instance).
     */

    wsprintfA(channelName, "file%lx", (int) infoPtr);
    
    infoPtr->channel = Tcl_CreateChannel(&consoleChannelType, channelName,
            (ClientData) infoPtr, permissions);

    infoPtr->threadId = Tcl_GetCurrentThread();

    if (permissions & TCL_READABLE) {
	infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL);
	infoPtr->startReader = CreateEvent(NULL, FALSE, FALSE, NULL);
	infoPtr->readThread = CreateThread(NULL, 8000, ConsoleReaderThread,
	        infoPtr, 0, &id);
	SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); 
    }

    if (permissions & TCL_WRITABLE) {
	infoPtr->writable = CreateEvent(NULL, TRUE, TRUE, NULL);
	infoPtr->startWriter = CreateEvent(NULL, FALSE, FALSE, NULL);
	infoPtr->writeThread = CreateThread(NULL, 8000, ConsoleWriterThread,
	        infoPtr, 0, &id);
    }

    /*
     * Files have default translation of AUTO and ^Z eof char, which
     * means that a ^Z will be accepted as EOF when reading.
     */
    
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", encoding);

    return infoPtr->channel;
}

Added win/tclWinDde.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
/* 
 * tclWinDde.c --
 *
 *	This file provides procedures that implement the "send"
 *	command, allowing commands to be passed from interpreter
 *	to interpreter.
 *
 * 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: tclWinDde.c,v 1.1.2.3 1999/04/06 03:19:52 redman Exp $
 */

#include "tclPort.h"
#include <ddeml.h>

/*
 * TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the
 * Registry_Init declaration is in the source file itself, which is only
 * accessed when we are building a library.
 */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT

/* 
 * The following structure is used to keep track of the interpreters
 * registered by this process.
 */

typedef struct RegisteredInterp {
    struct RegisteredInterp *nextPtr;
				/* The next interp this application knows
				 * about. */
    char *name;			/* Interpreter's name (malloc-ed). */
    Tcl_Interp *interp;		/* The interpreter attached to this name. */
} RegisteredInterp;

/*
 * Used to keep track of conversations.
 */

typedef struct Conversation {
    struct Conversation *nextPtr;
				/* The next conversation in the list. */
    RegisteredInterp *riPtr;	/* The info we know about the conversation. */
    HCONV hConv;		/* The DDE handle for this conversation. */
    Tcl_Obj *returnPackagePtr;	/* The result package for this conversation. */
} Conversation;

typedef struct ThreadSpecificData {
    Conversation *currentConversations;
                                /* A list of conversations currently
				 * being processed. */
    RegisteredInterp *interpListPtr;
                                /* List of all interpreters registered
				 * in the current process. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * The following variables cannot be placed in thread-local storage.
 * The Mutex ddeMutex guards access to the ddeInstance.
 */
static HSZ ddeService = 0;
static DWORD ddeInstance;       /* The application instance handle given
				 * to us by DdeInitialize. */
static int ddeIsServer = 0;

TCL_DECLARE_MUTEX(ddeMutex)

/*
 * Forward declarations for procedures defined later in this file.
 */

static void		    DdeExitProc _ANSI_ARGS_((ClientData clientData));
static void		    DeleteProc _ANSI_ARGS_((ClientData clientData));
static Tcl_Obj *	    ExecuteRemoteObject _ANSI_ARGS_((
				RegisteredInterp *riPtr, 
				Tcl_Obj *ddeObjectPtr));
static int		    MakeDdeConnection _ANSI_ARGS_((Tcl_Interp *interp,
				char *name, HCONV *ddeConvPtr));
static HDDEDATA CALLBACK    DdeServerProc _ANSI_ARGS_((UINT uType,
				UINT uFmt, HCONV hConv, HSZ ddeTopic,
				HSZ ddeItem, HDDEDATA hData, DWORD dwData1, 
				DWORD dwData2));
static void		    SetDdeError _ANSI_ARGS_((Tcl_Interp *interp));
int Tcl_DdeObjCmd(ClientData clientData,	/* Used only for deletion */
	Tcl_Interp *interp,		/* The interp we are sending from */
	int objc,			/* Number of arguments */
	Tcl_Obj *CONST objv[]);	/* The arguments */

EXTERN int Dde_Init(Tcl_Interp *interp);

/*
 *----------------------------------------------------------------------
 *
 * Dde_Init --
 *
 *	This procedure initializes the dde command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Dde_Init(
    Tcl_Interp *interp)
{
    ThreadSpecificData *tsdPtr;
    
    if (!Tcl_InitStubs(interp, "8.0", 0)) {
	return TCL_ERROR;
    }

    Tcl_CreateObjCommand(interp, "dde", Tcl_DdeObjCmd, NULL, NULL);

    tsdPtr = (ThreadSpecificData *)
	Tcl_GetThreadData((Tcl_ThreadDataKey *) &dataKey, sizeof(ThreadSpecificData));
    
    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
	tsdPtr->currentConversations = NULL;
	tsdPtr->interpListPtr = NULL;
    }
    Tcl_CreateExitHandler(DdeExitProc, NULL);

    return Tcl_PkgProvide(interp, "dde", "1.0");
}



static void
Initialize()
{
    int nameFound = 0;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    
    /*
     * See if the application is already registered; if so, remove its
     * current name from the registry. The deletion of the command
     * will take care of disposing of this entry.
     */

    if (tsdPtr->interpListPtr != NULL) {
	nameFound = 1;
    }

    /*
     * Make sure that the DDE server is there. This is done only once,
     * add an exit handler tear it down.
     */

    if (ddeInstance == 0) {
	Tcl_MutexLock(&ddeMutex);
	if (ddeInstance == 0) {
	    if (DdeInitialize(&ddeInstance, DdeServerProc,
		    CBF_SKIP_REGISTRATIONS
		    | CBF_SKIP_UNREGISTRATIONS
		    | CBF_FAIL_POKES, 0) 
		    != DMLERR_NO_ERROR) {
		DdeUninitialize(ddeInstance);
		ddeInstance = 0;
	    }
	}
	Tcl_MutexUnlock(&ddeMutex);
    }
    if ((ddeService == 0) && (nameFound != 0)) {
	Tcl_MutexLock(&ddeMutex);
	if ((ddeService == 0) && (nameFound != 0)) {
	    ddeIsServer = 1;
	    Tcl_CreateExitHandler(DdeExitProc, NULL);
	    ddeService = DdeCreateStringHandle(ddeInstance, "TclEval", 0);
	    DdeNameService(ddeInstance, ddeService, 0L, DNS_REGISTER);
	} else {
	    ddeIsServer = 0;
	}
	Tcl_MutexUnlock(&ddeMutex);
    }
}    


/*
 *--------------------------------------------------------------
 *
 * DdeSetServerName --
 *
 *	This procedure is called to associate an ASCII name with a Dde
 *	server.  If the interpreter has already been named, the
 *	name replaces the old one.
 *
 * Results:
 *	The return value is the name actually given to the interp.
 *	This will normally be the same as name, but if name was already
 *	in use for a Dde Server then a name of the form "name #2" will
 *	be chosen,  with a high enough number to make the name unique.
 *
 * Side effects:
 *	Registration info is saved, thereby allowing the "send" command
 *	to be used later to invoke commands in the application.  In
 *	addition, the "send" command is created in the application's
 *	interpreter.  The registration will be removed automatically
 *	if the interpreter is deleted or the "send" command is removed.
 *
 *--------------------------------------------------------------
 */

static char *
DdeSetServerName(interp, name)
    Tcl_Interp *interp;
    char *name;			/* The name that will be used to
				 * refer to the interpreter in later
				 * "send" commands.  Must be globally
				 * unique. */
{
    int suffix, offset;
    RegisteredInterp *riPtr, *prevPtr;
    Tcl_DString dString;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * See if the application is already registered; if so, remove its
     * current name from the registry. The deletion of the command
     * will take care of disposing of this entry.
     */

    for (riPtr = tsdPtr->interpListPtr, prevPtr = NULL; riPtr != NULL; 
	    prevPtr = riPtr, riPtr = riPtr->nextPtr) {
	if (riPtr->interp == interp) {
	    if (name != NULL) {
		if (prevPtr == NULL) {
		    tsdPtr->interpListPtr = tsdPtr->interpListPtr->nextPtr;
		} else {
		    prevPtr->nextPtr = riPtr->nextPtr;
		}
		break;
	    } else {
		/*
		 * the name was NULL, so the caller is asking for
		 * the name of the current interp.
		 */

		return riPtr->name;
	    }
	}
    }

    if (name == NULL) {
	/*
	 * the name was NULL, so the caller is asking for
	 * the name of the current interp, but it doesn't
	 * have a name.
	 */

	return "";
    }
    
    /*
     * Pick a name to use for the application.  Use "name" if it's not
     * already in use.  Otherwise add a suffix such as " #2", trying
     * larger and larger numbers until we eventually find one that is
     * unique.
     */

    suffix = 1;
    offset = 0;
    Tcl_DStringInit(&dString);

    /*
     * We have found a unique name. Now add it to the registry.
     */

    riPtr = (RegisteredInterp *) ckalloc(sizeof(RegisteredInterp));
    riPtr->interp = interp;
    riPtr->name = ckalloc(strlen(name) + 1);
    riPtr->nextPtr = tsdPtr->interpListPtr;
    tsdPtr->interpListPtr = riPtr;
    strcpy(riPtr->name, name);

    Tcl_CreateObjCommand(interp, "dde", Tcl_DdeObjCmd,
	    (ClientData) riPtr, DeleteProc);
    if (Tcl_IsSafe(interp)) {
	Tcl_HideCommand(interp, "dde", "dde");
    }
    Tcl_DStringFree(&dString);

    return riPtr->name;
}

/*
 *--------------------------------------------------------------
 *
 * DeleteProc
 *
 *	This procedure is called when the command "dde" is destroyed.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	The interpreter given by riPtr is unregistered.
 *
 *--------------------------------------------------------------
 */

static void
DeleteProc(clientData)
    ClientData clientData;	/* The interp we are deleting passed
				 * as ClientData. */
{
    RegisteredInterp *riPtr = (RegisteredInterp *) clientData;
    RegisteredInterp *searchPtr, *prevPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    for (searchPtr = tsdPtr->interpListPtr, prevPtr = NULL;
	    (searchPtr != NULL) && (searchPtr != riPtr);
	    prevPtr = searchPtr, searchPtr = searchPtr->nextPtr) {
	/*
	 * Empty loop body.
	 */
    }

    if (searchPtr != NULL) {
	if (prevPtr == NULL) {
	    tsdPtr->interpListPtr = tsdPtr->interpListPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = searchPtr->nextPtr;
	}
    }
    ckfree(riPtr->name);
    Tcl_EventuallyFree(clientData, TCL_DYNAMIC);
}

/*
 *--------------------------------------------------------------
 *
 * ExecuteRemoteObject --
 *
 *	Takes the package delivered by DDE and executes it in
 *	the server's interpreter.
 *
 * Results:
 *	A list Tcl_Obj * that describes what happened. The first
 *	element is the numerical return code (TCL_ERROR, etc.).
 *	The second element is the result of the script. If the
 *	return result was TCL_ERROR, then the third element
 *	will be the value of the global "errorCode", and the
 *	fourth will be the value of the global "errorInfo".
 *	The return result will have a refCount of 0.
 *
 * Side effects:
 *	A Tcl script is run, which can cause all kinds of other
 *	things to happen.
 *
 *--------------------------------------------------------------
 */

static Tcl_Obj *
ExecuteRemoteObject(
    RegisteredInterp *riPtr,	    /* Info about this server. */
    Tcl_Obj *ddeObjectPtr)	    /* The object to execute. */
{
    Tcl_Obj *errorObjPtr;
    Tcl_Obj *returnPackagePtr;
    int result;

    result = Tcl_EvalObjEx(riPtr->interp, ddeObjectPtr, TCL_EVAL_GLOBAL);
    returnPackagePtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
    Tcl_ListObjAppendElement(NULL, returnPackagePtr,
	    Tcl_NewIntObj(result));
    Tcl_ListObjAppendElement(NULL, returnPackagePtr,
	    Tcl_GetObjResult(riPtr->interp));
    if (result == TCL_ERROR) {
	errorObjPtr = Tcl_GetVar2Ex(riPtr->interp, "errorCode", NULL,
		TCL_GLOBAL_ONLY);
	Tcl_ListObjAppendElement(NULL, returnPackagePtr, errorObjPtr);
	errorObjPtr = Tcl_GetVar2Ex(riPtr->interp, "errorInfo", NULL,
		TCL_GLOBAL_ONLY);
        Tcl_ListObjAppendElement(NULL, returnPackagePtr, errorObjPtr);
    }

    return returnPackagePtr;
}

/*
 *--------------------------------------------------------------
 *
 * DdeServerProc --
 *
 *	Handles all transactions for this server. Can handle
 *	execute, request, and connect protocols. Dde will
 *	call this routine when a client attempts to run a dde
 *	command using this server.
 *
 * Results:
 *	A DDE Handle with the result of the dde command.
 *
 * Side effects:
 *	Depending on which command is executed, arbitrary
 *	Tcl scripts can be run.
 *
 *--------------------------------------------------------------
 */

static HDDEDATA CALLBACK
DdeServerProc (
    UINT uType,			/* The type of DDE transaction we
				 * are performing. */
    UINT uFmt,			/* The format that data is sent or
				 * received. */
    HCONV hConv,		/* The conversation associated with the 
				 * current transaction. */
    HSZ ddeTopic,		/* A string handle. Transaction-type 
				 * dependent. */
    HSZ ddeItem,		/* A string handle. Transaction-type 
				 * dependent. */
    HDDEDATA hData,		/* DDE data. Transaction-type dependent. */
    DWORD dwData1,		/* Transaction-dependent data. */
    DWORD dwData2)		/* Transaction-dependent data. */
{
    Tcl_DString dString;
    int len;
    char *utilString;
    Tcl_Obj *ddeObjectPtr;
    HDDEDATA ddeReturn = NULL;
    RegisteredInterp *riPtr;
    Conversation *convPtr, *prevConvPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    switch(uType) {
	case XTYP_CONNECT:

	    /*
	     * Dde is trying to initialize a conversation with us. Check
	     * and make sure we have a valid topic.
	     */

	    len = DdeQueryString(ddeInstance, ddeTopic, NULL, 0, 0);
	    Tcl_DStringInit(&dString);
	    Tcl_DStringSetLength(&dString, len);
	    utilString = Tcl_DStringValue(&dString);
	    DdeQueryString(ddeInstance, ddeTopic, utilString, len + 1,
		    CP_WINANSI);

	    for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
		    riPtr = riPtr->nextPtr) {
		if (stricmp(utilString, riPtr->name) == 0) {
		    Tcl_DStringFree(&dString);
		    return (HDDEDATA) TRUE;
		}
	    }

	    Tcl_DStringFree(&dString);
	    return (HDDEDATA) FALSE;

	case XTYP_CONNECT_CONFIRM:

	    /*
	     * Dde has decided that we can connect, so it gives us a 
	     * conversation handle. We need to keep track of it
	     * so we know which execution result to return in an
	     * XTYP_REQUEST.
	     */

	    len = DdeQueryString(ddeInstance, ddeTopic, NULL, 0, 0);
	    Tcl_DStringInit(&dString);
	    Tcl_DStringSetLength(&dString, len);
	    utilString = Tcl_DStringValue(&dString);
	    DdeQueryString(ddeInstance, ddeTopic, utilString, len + 1, 
		    CP_WINANSI);
	    for (riPtr = tsdPtr->interpListPtr; riPtr != NULL; 
		    riPtr = riPtr->nextPtr) {
		if (stricmp(riPtr->name, utilString) == 0) {
		    convPtr = (Conversation *) ckalloc(sizeof(Conversation));
		    convPtr->nextPtr = tsdPtr->currentConversations;
		    convPtr->returnPackagePtr = NULL;
		    convPtr->hConv = hConv;
		    convPtr->riPtr = riPtr;
		    tsdPtr->currentConversations = convPtr;
		    break;
		}
	    }
	    Tcl_DStringFree(&dString);
	    return (HDDEDATA) TRUE;

	case XTYP_DISCONNECT:

	    /*
	     * The client has disconnected from our server. Forget this
	     * conversation.
	     */

	    for (convPtr = tsdPtr->currentConversations, prevConvPtr = NULL;
		    convPtr != NULL; 
		    prevConvPtr = convPtr, convPtr = convPtr->nextPtr) {
		if (hConv == convPtr->hConv) {
		    if (prevConvPtr == NULL) {
			tsdPtr->currentConversations = convPtr->nextPtr;
		    } else {
			prevConvPtr->nextPtr = convPtr->nextPtr;
		    }
		    if (convPtr->returnPackagePtr != NULL) {
			Tcl_DecrRefCount(convPtr->returnPackagePtr);
		    }
		    ckfree((char *) convPtr);
		    break;
		}
	    }
	    return (HDDEDATA) TRUE;

	case XTYP_REQUEST:

	    /*
	     * This could be either a request for a value of a Tcl variable,
	     * or it could be the send command requesting the results of the
	     * last execute.
	     */

	    if (uFmt != CF_TEXT) {
		return (HDDEDATA) FALSE;
	    }

	    ddeReturn = (HDDEDATA) FALSE;
	    for (convPtr = tsdPtr->currentConversations; (convPtr != NULL)
		    && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) {
		/*
		 * Empty loop body.
		 */
	    }

	    if (convPtr != NULL) {
		char *returnString;

		len = DdeQueryString(ddeInstance, ddeItem, NULL, 0,
			CP_WINANSI);
		Tcl_DStringInit(&dString);
		Tcl_DStringSetLength(&dString, len);
		utilString = Tcl_DStringValue(&dString);
		DdeQueryString(ddeInstance, ddeItem, utilString, 
                        len + 1, CP_WINANSI);
		if (stricmp(utilString, "$TCLEVAL$EXECUTE$RESULT") == 0) {
		    returnString =
		        Tcl_GetStringFromObj(convPtr->returnPackagePtr, &len);
		    ddeReturn = DdeCreateDataHandle(ddeInstance,
			    returnString, len+1, 0, ddeItem, CF_TEXT,
			    0);
		} else {
		    Tcl_Obj *variableObjPtr = Tcl_GetVar2Ex(
			    convPtr->riPtr->interp, utilString, NULL, 
			    TCL_GLOBAL_ONLY);
		    if (variableObjPtr != NULL) {
			returnString = Tcl_GetStringFromObj(variableObjPtr,
				&len);
			ddeReturn = DdeCreateDataHandle(ddeInstance,
				returnString, len+1, 0, ddeItem, CF_TEXT, 0);
		    } else {
			ddeReturn = NULL;
		    }
		}
		Tcl_DStringFree(&dString);
	    }
	    return ddeReturn;

	case XTYP_EXECUTE: {

	    /*
	     * Execute this script. The results will be saved into
	     * a list object which will be retreived later. See
	     * ExecuteRemoteObject.
	     */

	    Tcl_Obj *returnPackagePtr;

	    for (convPtr = tsdPtr->currentConversations; (convPtr != NULL)
		    && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) {
		/*
		 * Empty loop body.
		 */

	    }

	    if (convPtr == NULL) {
		return (HDDEDATA) DDE_FNOTPROCESSED;
	    }

	    utilString = (char *) DdeAccessData(hData, &len);
	    ddeObjectPtr = Tcl_NewStringObj(utilString, -1);
	    Tcl_IncrRefCount(ddeObjectPtr);
	    DdeUnaccessData(hData);
	    if (convPtr->returnPackagePtr != NULL) {
		Tcl_DecrRefCount(convPtr->returnPackagePtr);
	    }
	    convPtr->returnPackagePtr = NULL;
	    returnPackagePtr = 
		    ExecuteRemoteObject(convPtr->riPtr, ddeObjectPtr);
	    for (convPtr = tsdPtr->currentConversations; (convPtr != NULL)
 		    && (convPtr->hConv != hConv); convPtr = convPtr->nextPtr) {
		/*
		 * Empty loop body.
		 */

	    }
	    if (convPtr != NULL) {
		Tcl_IncrRefCount(returnPackagePtr);
		convPtr->returnPackagePtr = returnPackagePtr;
	    }
	    Tcl_DecrRefCount(ddeObjectPtr);
	    if (returnPackagePtr == NULL) {
		return (HDDEDATA) DDE_FNOTPROCESSED;
	    } else {
		return (HDDEDATA) DDE_FACK;
	    }
	}
	    
	case XTYP_WILDCONNECT: {

	    /*
	     * Dde wants a list of services and topics that we support.
	     */

	    HSZPAIR *returnPtr;
	    int i;
	    int numItems;

	    for (i = 0, riPtr = tsdPtr->interpListPtr; riPtr != NULL;
		    i++, riPtr = riPtr->nextPtr) {
		/*
		 * Empty loop body.
		 */

	    }

	    numItems = i;
	    ddeReturn = DdeCreateDataHandle(ddeInstance, NULL,
		    (numItems + 1) * sizeof(HSZPAIR), 0, 0, 0, 0);
	    returnPtr = (HSZPAIR *) DdeAccessData(ddeReturn, &len);
	    for (i = 0, riPtr = tsdPtr->interpListPtr; i < numItems; 
		    i++, riPtr = riPtr->nextPtr) {
		returnPtr[i].hszSvc = DdeCreateStringHandle(
                        ddeInstance, "TclEval", CP_WINANSI);
		returnPtr[i].hszTopic = DdeCreateStringHandle(
                        ddeInstance, riPtr->name, CP_WINANSI);
	    }
	    returnPtr[i].hszSvc = NULL;
	    returnPtr[i].hszTopic = NULL;
	    DdeUnaccessData(ddeReturn);
	    return ddeReturn;
	}

    }
    return NULL;
}


/*
 *--------------------------------------------------------------
 *
 * DdeExitProc --
 *
 *	Gets rid of our DDE server when we go away.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The DDE server is deleted.
 *
 *--------------------------------------------------------------
 */

static void
DdeExitProc(
    ClientData clientData)	    /* Not used in this handler. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    DdeNameService(ddeInstance, NULL, 0, DNS_UNREGISTER);
    DdeUninitialize(ddeInstance);
    ddeInstance = 0;
}

/*
 *--------------------------------------------------------------
 *
 * MakeDdeConnection --
 *
 *	This procedure is a utility used to connect to a DDE
 *	server when given a server name and a topic name.
 *
 * Results:
 *	A standard Tcl result.
 *	
 *
 * Side effects:
 *	Passes back a conversation through ddeConvPtr
 *
 *--------------------------------------------------------------
 */

static int
MakeDdeConnection(
    Tcl_Interp *interp,		/* Used to report errors. */
    char *name,			/* The connection to use. */
    HCONV *ddeConvPtr)
{
    HSZ ddeTopic, ddeService;
    HCONV ddeConv;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    
    ddeService = DdeCreateStringHandle(ddeInstance, "TclEval", 0);
    ddeTopic = DdeCreateStringHandle(ddeInstance, name, 0);

    ddeConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
    DdeFreeStringHandle(ddeInstance, ddeService);
    DdeFreeStringHandle(ddeInstance, ddeTopic);

    if (ddeConv == (HCONV) NULL) {
	if (interp != NULL) {
	    Tcl_AppendResult(interp, "no registered server named \"",
		    name, "\"", (char *) NULL);
	}
	return TCL_ERROR;
    }

    *ddeConvPtr = ddeConv;
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * SetDdeError --
 *
 *	Sets the interp result to a cogent error message
 *	describing the last DDE error.
 *
 * Results:
 *	None.
 *	
 *
 * Side effects:
 *	The interp's result object is changed.
 *
 *--------------------------------------------------------------
 */

static void
SetDdeError(
    Tcl_Interp *interp)	    /* The interp to put the message in.*/
{
    Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
    int err;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    err = DdeGetLastError(ddeInstance);
    switch (err) {
	case DMLERR_DATAACKTIMEOUT:
	case DMLERR_EXECACKTIMEOUT:
	case DMLERR_POKEACKTIMEOUT:
	    Tcl_SetStringObj(resultPtr,
		    "remote interpreter did not respond", -1);
	    break;

	case DMLERR_BUSY:
	    Tcl_SetStringObj(resultPtr, "remote server is busy", -1);
	    break;

	case DMLERR_NOTPROCESSED:
	    Tcl_SetStringObj(resultPtr, 
		    "remote server cannot handle this command", -1);
	    break;

	default:
	    Tcl_SetStringObj(resultPtr, "dde command failed", -1);
    }
}

/*
 *--------------------------------------------------------------
 *
 * Tcl_DdeObjCmd --
 *
 *	This procedure is invoked to process the "dde" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tcl_DdeObjCmd(
    ClientData clientData,	/* Used only for deletion */
    Tcl_Interp *interp,		/* The interp we are sending from */
    int objc,			/* Number of arguments */
    Tcl_Obj *CONST objv[])	/* The arguments */
{
    enum {
	DDE_SERVERNAME,
	DDE_EXECUTE,
	DDE_REQUEST,
	DDE_SERVICES,
	DDE_EVAL
    };

    static char *ddeCommands[] = {"servername", "execute",
          "request", "services", "eval", 
	  (char *) NULL};
    static char *ddeOptions[] = {"-async", (char *) NULL};
    int index, argIndex;
    int async = 0;
    int result = TCL_OK;
    HSZ ddeService = NULL;
    HSZ ddeTopic = NULL;
    HSZ ddeItem = NULL;
    HDDEDATA ddeData = NULL;
    HDDEDATA ddeItemData = NULL;
    HCONV hConv;
    HSZ ddeCookie = 0;
    char *serviceName, *topicName, *itemString, *dataString;
    char *string;
    int firstArg, length, dataLength;
    DWORD ddeResult;
    HDDEDATA ddeReturn;
    RegisteredInterp *riPtr;
    Tcl_Interp *sendInterp;
    Tcl_Obj *objPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Initialize DDE server/client
     */
    
    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, 
		"?-async? serviceName topicName value");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], ddeCommands, "command", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch (index) {
	case DDE_SERVERNAME:
	    if ((objc != 3) && (objc != 2)) {
		Tcl_WrongNumArgs(interp, 1, objv, 
			"servername ?serverName?");
		return TCL_ERROR;
	    }
	    firstArg = (objc - 1);
	    break;
	case DDE_EXECUTE:
	    if ((objc < 5) || (objc > 6)) {
		Tcl_WrongNumArgs(interp, 1, objv, 
			"execute ?-async? serviceName topicName value");
		return TCL_ERROR;
	    }
	    if (Tcl_GetIndexFromObj(NULL, objv[2], ddeOptions, "option", 0,
		    &argIndex) != TCL_OK) {
		if (objc != 5) {
		    Tcl_WrongNumArgs(interp, 1, objv,
			    "execute ?-async? serviceName topicName value");
		    return TCL_ERROR;
		}
		async = 0;
		firstArg = 2;
	    } else {
		if (objc != 6) {
		    Tcl_WrongNumArgs(interp, 1, objv,
			    "execute ?-async? serviceName topicName value");
		    return TCL_ERROR;
		}
		async = 1;
		firstArg = 3;
	    }
	    break;
	case DDE_REQUEST:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 1, objv, 
			"request serviceName topicName value");
		return TCL_ERROR;
	    }
	    firstArg = 2;
	    break;
	case DDE_SERVICES:
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 1, objv,
			"services serviceName topicName");
		return TCL_ERROR;
	    }
	    firstArg = 2;
	    break;
	case DDE_EVAL:
	    if (objc < 4) {
		Tcl_WrongNumArgs(interp, 1, objv, 
			"eval ?-async? serviceName args");
		return TCL_ERROR;
	    }
	    if (Tcl_GetIndexFromObj(NULL, objv[2], ddeOptions, "option", 0,
		    &argIndex) != TCL_OK) {
		if (objc < 4) {
		    Tcl_WrongNumArgs(interp, 1, objv,
			    "eval ?-async? serviceName args");
		    return TCL_ERROR;
		}
		async = 0;
		firstArg = 2;
	    } else {
		if (objc < 5) {
		    Tcl_WrongNumArgs(interp, 1, objv,
			    "eval ?-async? serviceName args");
		    return TCL_ERROR;
		}
		async = 1;
		firstArg = 3;
	    }
	    break;
    }

    if (firstArg != 1) {
	serviceName = Tcl_GetStringFromObj(objv[firstArg], &length);
    } else {
	serviceName = NULL;
    }

    if (length == 0) {
	serviceName = NULL;
    } else if (index != DDE_SERVERNAME) {
	ddeService = DdeCreateStringHandle(ddeInstance, serviceName,
		CP_WINANSI);
    }

    if ((index != DDE_SERVERNAME) &&(index != DDE_EVAL)) {
	topicName = Tcl_GetStringFromObj(objv[firstArg + 1], &length);
	if (length == 0) {
	    topicName = NULL;
	} else {
	    ddeTopic = DdeCreateStringHandle(ddeInstance, 
		    topicName, CP_WINANSI);
	}
    }

    switch (index) {
	case DDE_SERVERNAME: {
	    serviceName = DdeSetServerName(interp, serviceName);
	    if (serviceName != NULL) {
		Tcl_SetStringObj(Tcl_GetObjResult(interp),
			serviceName, -1);
		Initialize();
	    } else {
		Tcl_ResetResult(interp);
	    }
	    break;
	}
	case DDE_EXECUTE: {
	    Initialize();
	    dataString = Tcl_GetStringFromObj(objv[firstArg + 2], &dataLength);
	    if (dataLength == 0) {
		Tcl_SetStringObj(Tcl_GetObjResult(interp),
			"cannot execute null data", -1);
		result = TCL_ERROR;
		break;
	    }
	    hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, 
                    NULL);

	    if (hConv == NULL) {
		SetDdeError(interp);
		result = TCL_ERROR;
		break;
	    }

	    ddeData = DdeCreateDataHandle(ddeInstance, dataString,
		    dataLength+1, 0, 0, CF_TEXT, 0);
	    if (ddeData != NULL) {
		if (async) {
		    DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0, 
			    CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
		    DdeAbandonTransaction(ddeInstance, hConv, 
                            ddeResult);
		} else {
		    ddeReturn = DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF,
			    hConv, 0, CF_TEXT, XTYP_EXECUTE, 30000, NULL);
		    if (ddeReturn == 0) {
			SetDdeError(interp);
			result = TCL_ERROR;
		    }
		}
		DdeFreeDataHandle(ddeData);
	    } else {
		SetDdeError(interp);
		result = TCL_ERROR;
	    }
	    DdeDisconnect(hConv);
	    break;
	}
	case DDE_REQUEST: {
	    Initialize();
	    itemString = Tcl_GetStringFromObj(objv[firstArg + 2], &length);
	    if (length == 0) {
		Tcl_SetStringObj(Tcl_GetObjResult(interp),
			"cannot request value of null data", -1);
		return TCL_ERROR;
	    }
	    hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, 
                    NULL);
	    
	    if (hConv == NULL) {
		SetDdeError(interp);
		result = TCL_ERROR;
	    } else {
		Tcl_Obj *returnObjPtr;
		ddeItem = DdeCreateStringHandle(ddeInstance, 
                        itemString, CP_WINANSI);
		if (ddeItem != NULL) {
		    ddeData = DdeClientTransaction(NULL, 0, hConv, ddeItem,
			    CF_TEXT, XTYP_REQUEST, 5000, NULL);
		    if (ddeData == NULL) {
			SetDdeError(interp);
			result = TCL_ERROR;
		    } else {
			dataString = DdeAccessData(ddeData, &dataLength);
			returnObjPtr = Tcl_NewStringObj(dataString, -1);
			DdeUnaccessData(ddeData);
			DdeFreeDataHandle(ddeData);
			Tcl_SetObjResult(interp, returnObjPtr);
		    }
		} else {
		    SetDdeError(interp);
		    result = TCL_ERROR;
		}
		DdeDisconnect(hConv);
	    }

	    break;
	}
	case DDE_SERVICES: {
	    HCONVLIST hConvList;
	    CONVINFO convInfo;
	    Tcl_Obj *convListObjPtr, *elementObjPtr;
	    Tcl_DString dString;
	    char *name;
	    
	    Initialize();
	    convInfo.cb = sizeof(CONVINFO);
	    hConvList = DdeConnectList(ddeInstance, ddeService, 
                    ddeTopic, 0, NULL);
	    hConv = 0;
	    convListObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
	    Tcl_DStringInit(&dString);

	    while (hConv = DdeQueryNextServer(hConvList, hConv), hConv != 0) {
		elementObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
		DdeQueryConvInfo(hConv, QID_SYNC, &convInfo);
		length = DdeQueryString(ddeInstance, 
                        convInfo.hszSvcPartner, NULL, 0, CP_WINANSI);
		Tcl_DStringSetLength(&dString, length);
		name = Tcl_DStringValue(&dString);
		DdeQueryString(ddeInstance, convInfo.hszSvcPartner, 
                        name, length + 1, CP_WINANSI);
		Tcl_ListObjAppendElement(interp, elementObjPtr,
			Tcl_NewStringObj(name, length));
		length = DdeQueryString(ddeInstance, convInfo.hszTopic,
			NULL, 0, CP_WINANSI);
		Tcl_DStringSetLength(&dString, length);
		name = Tcl_DStringValue(&dString);
		DdeQueryString(ddeInstance, convInfo.hszTopic, name,
			length + 1, CP_WINANSI);
		Tcl_ListObjAppendElement(interp, elementObjPtr,
			Tcl_NewStringObj(name, length));
		Tcl_ListObjAppendElement(interp, convListObjPtr, elementObjPtr);
	    }
	    DdeDisconnectList(hConvList);
	    Tcl_SetObjResult(interp, convListObjPtr);
	    Tcl_DStringFree(&dString);
	    break;
	}
	case DDE_EVAL: {
	    Initialize();
	    objc -= (async + 3);
	    ((Tcl_Obj **) objv) += (async + 3);

            /*
	     * See if the target interpreter is local.  If so, execute
	     * the command directly without going through the DDE server.
	     * Don't exchange objects between interps.  The target interp could
	     * compile an object, producing a bytecode structure that refers to 
	     * other objects owned by the target interp.  If the target interp 
	     * is then deleted, the bytecode structure would be referring to 
	     * deallocated objects.
	     */
	    
	    for (riPtr = tsdPtr->interpListPtr; riPtr != NULL; riPtr
		     = riPtr->nextPtr) {
		if (stricmp(serviceName, riPtr->name) == 0) {
		    break;
		}
	    }
	    
	    if (riPtr != NULL) {
		/*
		 * This command is to a local interp. No need to go through
		 * the server.
		 */
		
		Tcl_Preserve((ClientData) riPtr);
		sendInterp = riPtr->interp;
		Tcl_Preserve((ClientData) sendInterp);
		
		/*
		 * Don't exchange objects between interps.  The target interp would
		 * compile an object, producing a bytecode structure that refers to 
		 * other objects owned by the target interp.  If the target interp 
		 * is then deleted, the bytecode structure would be referring to 
		 * deallocated objects.
		 */

		if (objc == 1) {
		    result = Tcl_EvalObjEx(sendInterp, objv[0], TCL_EVAL_GLOBAL);
		} else {
		    objPtr = Tcl_ConcatObj(objc, objv);
		    Tcl_IncrRefCount(objPtr);
		    result = Tcl_EvalObjEx(sendInterp, objPtr, TCL_EVAL_GLOBAL);
		    Tcl_DecrRefCount(objPtr);
		}
		if (interp != sendInterp) {
		    if (result == TCL_ERROR) {
			/*
			 * An error occurred, so transfer error information from the
			 * destination interpreter back to our interpreter.  
			 */
			
			Tcl_ResetResult(interp);
			objPtr = Tcl_GetVar2Ex(sendInterp, "errorInfo", NULL, 
				TCL_GLOBAL_ONLY);
			string = Tcl_GetStringFromObj(objPtr, &length);
			Tcl_AddObjErrorInfo(interp, string, length);
			
			objPtr = Tcl_GetVar2Ex(sendInterp, "errorCode", NULL,
				TCL_GLOBAL_ONLY);
			Tcl_SetObjErrorCode(interp, objPtr);
		    }
		    Tcl_SetObjResult(interp, Tcl_GetObjResult(sendInterp));
		}
		Tcl_Release((ClientData) riPtr);
		Tcl_Release((ClientData) sendInterp);
	    } else {
		/*
		 * This is a non-local request. Send the script to the server and poll
		 * it for a result.
		 */
		
		if (MakeDdeConnection(interp, serviceName, &hConv) != TCL_OK) {
		    goto error;
		}
		
		objPtr = Tcl_ConcatObj(objc, objv);
		string = Tcl_GetStringFromObj(objPtr, &length);
		ddeItemData = DdeCreateDataHandle(ddeInstance, string, length+1, 0, 0,
			CF_TEXT, 0);
		
		if (async) {
		    ddeData = DdeClientTransaction((LPBYTE) ddeItemData, 0xFFFFFFFF, hConv, 0,
			    CF_TEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
		    DdeAbandonTransaction(ddeInstance, hConv, ddeResult);
		} else {
		    ddeData = DdeClientTransaction((LPBYTE) ddeItemData, 0xFFFFFFFF, hConv, 0,
			    CF_TEXT, XTYP_EXECUTE, 30000, NULL);
		    if (ddeData != 0) {
			
			ddeCookie = DdeCreateStringHandle(ddeInstance, 
				"$TCLEVAL$EXECUTE$RESULT", CP_WINANSI);
			ddeData = DdeClientTransaction(NULL, 0, hConv, ddeCookie,
				CF_TEXT, XTYP_REQUEST, 30000, NULL);
		    }
		}
		
		
		Tcl_DecrRefCount(objPtr);
		
		if (ddeData == 0) {
		    SetDdeError(interp);
		    DdeFreeDataHandle(ddeItemData);
		    DdeDisconnect(hConv);
		    goto error;
		}
		
		if (async == 0) {
		    Tcl_Obj *resultPtr;
		    
		    /*
		     * The return handle has a two or four element list in it. The first
		     * element is the return code (TCL_OK, TCL_ERROR, etc.). The
		     * second is the result of the script. If the return code is TCL_ERROR,
		     * then the third element is the value of the variable "errorCode",
		     * and the fourth is the value of the variable "errorInfo".
		     */
		    
		    resultPtr = Tcl_NewObj();
		    length = DdeGetData(ddeData, NULL, 0, 0);
		    Tcl_SetObjLength(resultPtr, length);
		    string = Tcl_GetString(resultPtr);
		    DdeGetData(ddeData, string, length, 0);
		    Tcl_SetObjLength(resultPtr, strlen(string));
		    
		    if (Tcl_ListObjIndex(NULL, resultPtr, 0, &objPtr) != TCL_OK) {
			Tcl_DecrRefCount(resultPtr);
			goto error;
		    }
		    if (Tcl_GetIntFromObj(NULL, objPtr, &result) != TCL_OK) {
			Tcl_DecrRefCount(resultPtr);
			goto error;
		    }
		    if (result == TCL_ERROR) {
			Tcl_ResetResult(interp);
			
			if (Tcl_ListObjIndex(NULL, resultPtr, 3, &objPtr) != TCL_OK) {
			    Tcl_DecrRefCount(resultPtr);
			    goto error;
			}
			length = -1;
			string = Tcl_GetStringFromObj(objPtr, &length);
			Tcl_AddObjErrorInfo(interp, string, length);
			
			Tcl_ListObjIndex(NULL, resultPtr, 2, &objPtr);
			Tcl_SetObjErrorCode(interp, objPtr);
		    }
		    if (Tcl_ListObjIndex(NULL, resultPtr, 1, &objPtr) != TCL_OK) {
			Tcl_DecrRefCount(resultPtr);
			goto error;
		    }
		    Tcl_SetObjResult(interp, objPtr);
		    Tcl_DecrRefCount(resultPtr);
		}
	    }
	}
    }
    if (ddeCookie != NULL) {
	DdeFreeStringHandle(ddeInstance, ddeCookie);
    }
    if (ddeItem != NULL) {
	DdeFreeStringHandle(ddeInstance, ddeItem);
    }
    if (ddeItemData != NULL) {
	DdeFreeDataHandle(ddeItemData);
    }
    if (ddeData != NULL) {
	DdeFreeDataHandle(ddeData);
    }
    if (hConv != NULL) {
	DdeDisconnect(hConv);
    }
    return result;

    error:
    Tcl_SetStringObj(Tcl_GetObjResult(interp),
	    "invalid data returned from server", -1);
    if (ddeCookie != NULL) {
	DdeFreeStringHandle(ddeInstance, ddeCookie);
    }
    if (ddeItem != NULL) {
	DdeFreeStringHandle(ddeInstance, ddeItem);
    }
    if (ddeItemData != NULL) {
	DdeFreeDataHandle(ddeItemData);
    }
    if (ddeData != NULL) {
	DdeFreeDataHandle(ddeData);
    }
    if (hConv != NULL) {
	DdeDisconnect(hConv);
    }
    return TCL_ERROR;
}

Changes to win/tclWinError.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* 
 * tclWinError.c --
 *
 *	This file contains code for converting from Win32 errors to
 *	errno errors.
 *
 * Copyright (c) 1995-1996 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.
 *
 * SCCS: @(#) tclWinError.c 1.7 97/10/28 17:30:33
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * The following table contains the mapping from Win32 errors to
 * errno errors.
 */

static char errorTable[] = {











|


|
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
/* 
 * tclWinError.c --
 *
 *	This file contains code for converting from Win32 errors to
 *	errno errors.
 *
 * Copyright (c) 1995-1996 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: tclWinError.c,v 1.1.2.2 1998/09/24 23:59:51 stanton Exp $
 */

#include "tclWinInt.h"


/*
 * The following table contains the mapping from Win32 errors to
 * errno errors.
 */

static char errorTable[] = {

Changes to win/tclWinFCmd.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


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
/*
 * tclWinFCmd.c
 *
 *      This file implements the Windows specific portion of file manipulation 
 *      subcommands of the "file" command. 
 *
 * 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.
 *
 * SCCS: @(#) tclWinFCmd.c 1.20 97/10/10 11:50:14
 */

#include "tclWinInt.h"

/*
 * The following constants specify the type of callback when
 * TraverseWinTree() calls the traverseProc()
 */

#define DOTREE_PRED   1     /* pre-order directory  */
#define DOTREE_POSTD  2     /* post-order directory */
#define DOTREE_F      3     /* regular file */

/*
 * Callbacks for file attributes code.
 */

static int		GetWinFileAttributes _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		GetWinFileLongName _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		GetWinFileShortName _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		SetWinFileAttributes _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj *attributePtr));
static int		CannotSetAttribute _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName,
			    Tcl_Obj *attributePtr));

/*
 * Constants and variables necessary for file attributes subcommand.
 */

enum {
    WIN_ARCHIVE_ATTRIBUTE,
    WIN_HIDDEN_ATTRIBUTE,
    WIN_LONGNAME_ATTRIBUTE,
    WIN_READONLY_ATTRIBUTE,
    WIN_SHORTNAME_ATTRIBUTE,
    WIN_SYSTEM_ATTRIBUTE
};

static int attributeArray[] = {FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_HIDDEN,
	0, FILE_ATTRIBUTE_READONLY, 0, FILE_ATTRIBUTE_SYSTEM};


char *tclpFileAttrStrings[] = {"-archive", "-hidden", "-longname", "-readonly",

	"-shortname", "-system", (char *) NULL};


CONST TclFileAttrProcs tclpFileAttrProcs[] = {
	{GetWinFileAttributes, SetWinFileAttributes},
	{GetWinFileAttributes, SetWinFileAttributes},
	{GetWinFileLongName, CannotSetAttribute},
	{GetWinFileAttributes, SetWinFileAttributes},
	{GetWinFileShortName, CannotSetAttribute},
	{GetWinFileAttributes, SetWinFileAttributes}};

/*
 * Prototype for the TraverseWinTree callback function.
 */

typedef int (TraversalProc)(char *src, char *dst, DWORD attr, int type, 
	Tcl_DString *errorPtr);

/*
 * Declarations for local procedures defined in this file:
 */

static void		AttributesPosixError _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName, int getOrSet));
static int		ConvertFileNameFormat _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, char *fileName, int longShort,
			    Tcl_Obj **attributePtrPtr));






static int		TraversalCopy(char *src, char *dst, DWORD attr, 
				int type, Tcl_DString *errorPtr);
static int		TraversalDelete(char *src, char *dst, DWORD attr,
				int type, Tcl_DString *errorPtr);
static int		TraverseWinTree(TraversalProc *traverseProc,
			    Tcl_DString *sourcePtr, Tcl_DString *destPtr,
			    Tcl_DString *errorPtr);


/*
 *---------------------------------------------------------------------------
 *
 * TclpRenameFile --
 *
 *      Changes the name of an existing file or directory, from src to dst.
 *	If src and dst refer to the same file or directory, does nothing
 *	and returns success.  Otherwise if dst already exists, it will be
 *	deleted and replaced by src subject to the following conditions:
 *	    If src is a directory, dst may be an empty directory.
 *	    If src is a file, dst may be a file.
 *	In any other situation where dst already exists, the rename will
 *	fail.  
 *
 * Results:
 *	If the directory was successfully created, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR and errno is set to
 *	indicate the error.  Some possible values for errno are:
 *

 *	EACCES:     src or dst parent directory can't be read and/or written.
 *	EEXIST:	    dst is a non-empty directory.
 *	EINVAL:	    src is a root directory or dst is a subdirectory of src.
 *	EISDIR:	    dst is a directory, but src is not.
 *	ENOENT:	    src doesn't exist.  src or dst is "".
 *	ENOTDIR:    src is a directory, but dst is not.  
 *	EXDEV:	    src and dst are on different filesystems.






|




|


















|


|


|


|


|



















|
>
|
>
>
|











|
|





|
<
|
|
|
>
>
>
>
>
>
|
|
|
|

|






|











|



>







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
/*
 * tclWinFCmd.c
 *
 *      This file implements the Windows specific portion of file manipulation 
 *      subcommands of the "file" command. 
 *
 * Copyright (c) 1996-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: tclWinFCmd.c,v 1.1.2.3 1999/04/02 23:44:59 stanton Exp $
 */

#include "tclWinInt.h"

/*
 * The following constants specify the type of callback when
 * TraverseWinTree() calls the traverseProc()
 */

#define DOTREE_PRED   1     /* pre-order directory  */
#define DOTREE_POSTD  2     /* post-order directory */
#define DOTREE_F      3     /* regular file */

/*
 * Callbacks for file attributes code.
 */

static int		GetWinFileAttributes _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		GetWinFileLongName _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		GetWinFileShortName _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj **attributePtrPtr));
static int		SetWinFileAttributes _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj *attributePtr));
static int		CannotSetAttribute _ANSI_ARGS_((Tcl_Interp *interp,
			    int objIndex, CONST char *fileName,
			    Tcl_Obj *attributePtr));

/*
 * Constants and variables necessary for file attributes subcommand.
 */

enum {
    WIN_ARCHIVE_ATTRIBUTE,
    WIN_HIDDEN_ATTRIBUTE,
    WIN_LONGNAME_ATTRIBUTE,
    WIN_READONLY_ATTRIBUTE,
    WIN_SHORTNAME_ATTRIBUTE,
    WIN_SYSTEM_ATTRIBUTE
};

static int attributeArray[] = {FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_HIDDEN,
	0, FILE_ATTRIBUTE_READONLY, 0, FILE_ATTRIBUTE_SYSTEM};


char *tclpFileAttrStrings[] = {
	"-archive", "-hidden", "-longname", "-readonly",
	"-shortname", "-system", (char *) NULL
};

const TclFileAttrProcs tclpFileAttrProcs[] = {
	{GetWinFileAttributes, SetWinFileAttributes},
	{GetWinFileAttributes, SetWinFileAttributes},
	{GetWinFileLongName, CannotSetAttribute},
	{GetWinFileAttributes, SetWinFileAttributes},
	{GetWinFileShortName, CannotSetAttribute},
	{GetWinFileAttributes, SetWinFileAttributes}};

/*
 * Prototype for the TraverseWinTree callback function.
 */

typedef int (TraversalProc)(Tcl_DString *srcPtr, Tcl_DString *dstPtr, 
	int type, Tcl_DString *errorPtr);

/*
 * Declarations for local procedures defined in this file:
 */

static void		StatError(Tcl_Interp *interp, CONST char *fileName);

static int		ConvertFileNameFormat(Tcl_Interp *interp, 
			    int objIndex, CONST char *fileName, int longShort,
			    Tcl_Obj **attributePtrPtr);
static int		DoCopyFile(Tcl_DString *srcPtr, Tcl_DString *dstPtr);
static int		DoCreateDirectory(Tcl_DString *pathPtr);
static int		DoDeleteFile(Tcl_DString *pathPtr);
static int		DoRemoveDirectory(Tcl_DString *pathPtr, int recursive, 
			    Tcl_DString *errorPtr);
static int		DoRenameFile(const TCHAR *nativeSrc, Tcl_DString *dstPtr);
static int		TraversalCopy(Tcl_DString *srcPtr, Tcl_DString *dstPtr, 
			    int type, Tcl_DString *errorPtr);
static int		TraversalDelete(Tcl_DString *srcPtr, Tcl_DString *dstPtr, 
			    int type, Tcl_DString *errorPtr);
static int		TraverseWinTree(TraversalProc *traverseProc,
			    Tcl_DString *sourcePtr, Tcl_DString *dstPtr, 
			    Tcl_DString *errorPtr);


/*
 *---------------------------------------------------------------------------
 *
 * TclpRenameFile, DoRenameFile --
 *
 *      Changes the name of an existing file or directory, from src to dst.
 *	If src and dst refer to the same file or directory, does nothing
 *	and returns success.  Otherwise if dst already exists, it will be
 *	deleted and replaced by src subject to the following conditions:
 *	    If src is a directory, dst may be an empty directory.
 *	    If src is a file, dst may be a file.
 *	In any other situation where dst already exists, the rename will
 *	fail.  
 *
 * Results:
 *	If the file or directory was successfully renamed, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR and errno is set to
 *	indicate the error.  Some possible values for errno are:
 *
 *	ENAMETOOLONG: src or dst names are too long.
 *	EACCES:     src or dst parent directory can't be read and/or written.
 *	EEXIST:	    dst is a non-empty directory.
 *	EINVAL:	    src is a root directory or dst is a subdirectory of src.
 *	EISDIR:	    dst is a directory, but src is not.
 *	ENOENT:	    src doesn't exist.  src or dst is "".
 *	ENOTDIR:    src is a directory, but dst is not.  
 *	EXDEV:	    src and dst are on different filesystems.
134
135
136
137
138
139
140
141


































142

143

144
145


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161




162
163
164




165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189




190
191

192
193
194
195

196
197
198
199
200


201


202
203
204
205
206
207


208
209
210
211



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

308
309
310



311
312


313

314
315
316
317
318
319
320

321
322
323

324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
 *	renames of directories if errno is EXDEV.
 *
 *---------------------------------------------------------------------------
 */

int
TclpRenameFile(
    char *src,			/* Pathname of file or dir to be renamed. */ 


































    char *dst)			/* New pathname for file or directory. */

{

    DWORD srcAttr, dstAttr;
    


    /*
     * Would throw an exception under NT if one of the arguments is a 
     * char block device.
     */

    try {
	if (MoveFile(src, dst) != FALSE) {
	    return TCL_OK;
	}
    } except (-1) {}

    TclWinConvertError(GetLastError());

    srcAttr = GetFileAttributes(src);
    dstAttr = GetFileAttributes(dst);
    if (srcAttr == (DWORD) -1) {




	srcAttr = 0;
    }
    if (dstAttr == (DWORD) -1) {




	dstAttr = 0;
    }

    if (errno == EBADF) {
	errno = EACCES;
	return TCL_ERROR;
    }
    if ((errno == EACCES) && (TclWinGetPlatformId() == VER_PLATFORM_WIN32s)) {
	if ((srcAttr != 0) && (dstAttr != 0)) {
	    /*
	     * Win32s reports trying to overwrite an existing file or directory
	     * as EACCES.
	     */

	    errno = EEXIST;
	}
    }
    if (errno == EACCES) {
	decode:
	if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) {
	    char srcPath[MAX_PATH], dstPath[MAX_PATH];
	    int srcArgc, dstArgc;
	    char **srcArgv, **dstArgv;
	    char *srcRest, *dstRest;
	    int size;





	    size = GetFullPathName(src, sizeof(srcPath), srcPath, &srcRest);

	    if ((size == 0) || (size > sizeof(srcPath))) {
		return TCL_ERROR;
	    }
	    size = GetFullPathName(dst, sizeof(dstPath), dstPath, &dstRest);

	    if ((size == 0) || (size > sizeof(dstPath))) {
		return TCL_ERROR;
	    }
	    if (srcRest == NULL) {
		srcRest = srcPath + strlen(srcPath);


	    }


	    if (strnicmp(srcPath, dstPath, srcRest - srcPath) == 0) {
		/*
		 * Trying to move a directory into itself.
		 */

		errno = EINVAL;


		return TCL_ERROR;
	    }
	    Tcl_SplitPath(srcPath, &srcArgc, &srcArgv);
	    Tcl_SplitPath(dstPath, &dstArgc, &dstArgv);



	    if (srcArgc == 1) {
		/*
		 * They are trying to move a root directory.  Whether
		 * or not it is across filesystems, this cannot be
		 * done.
		 */

		errno = EINVAL;
	    } else if ((srcArgc > 0) && (dstArgc > 0) &&
		    (stricmp(srcArgv[0], dstArgv[0]) != 0)) {
		/*
		 * If src is a directory and dst filesystem != src
		 * filesystem, errno should be EXDEV.  It is very
		 * important to get this behavior, so that the caller
		 * can respond to a cross filesystem rename by
		 * simulating it with copy and delete.  The MoveFile
		 * system call already handles the case of moving a
		 * file between filesystems.
		 */

		errno = EXDEV;
	    }

	    ckfree((char *) srcArgv);
	    ckfree((char *) dstArgv);
	}

	/*
	 * Other types of access failure is that dst is a read-only
	 * filesystem, that an open file referred to src or dest, or that
	 * src or dest specified the current working directory on the
	 * current filesystem.  EACCES is returned for those cases.
	 */

    } else if (errno == EEXIST) {
	/*
	 * Reports EEXIST any time the target already exists.  If it makes
	 * sense, remove the old file and try renaming again.
	 */

	if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) {
	    if (dstAttr & FILE_ATTRIBUTE_DIRECTORY) {
		/*
		 * Overwrite empty dst directory with src directory.  The
		 * following call will remove an empty directory.  If it
		 * fails, it's because it wasn't empty.
		 */

		if (TclpRemoveDirectory(dst, 0, NULL) == TCL_OK) {
		    /*
		     * Now that that empty directory is gone, we can try
		     * renaming again.  If that fails, we'll put this empty
		     * directory back, for completeness.
		     */

		    if (MoveFile(src, dst) != FALSE) {
			return TCL_OK;
		    }

		    /*
		     * Some new error has occurred.  Don't know what it
		     * could be, but report this one.
		     */

		    TclWinConvertError(GetLastError());
		    CreateDirectory(dst, NULL);
		    SetFileAttributes(dst, dstAttr);
		    if (errno == EACCES) {
			/*
			 * Decode the EACCES to a more meaningful error.
			 */

			goto decode;
		    }
		}
	    } else {	/* (dstAttr & FILE_ATTRIBUTE_DIRECTORY) == 0 */
		errno = ENOTDIR;
	    }
	} else {    /* (srcAttr & FILE_ATTRIBUTE_DIRECTORY) == 0 */
	    if (dstAttr & FILE_ATTRIBUTE_DIRECTORY) {
		errno = EISDIR;
	    } else {
		/*
		 * Overwrite existing file by:
		 * 
		 * 1. Rename existing file to temp name.
		 * 2. Rename old file to new name.
		 * 3. If success, delete temp file.  If failure,
		 *    put temp file back to old name.
		 */

		char tempName[MAX_PATH];
		int result, size;
		char *rest;
		
		size = GetFullPathName(dst, sizeof(tempName), tempName, &rest);

		if ((size == 0) || (size > sizeof(tempName)) || (rest == NULL)) {
		    return TCL_ERROR;
		}



		*rest = '\0';
		result = TCL_ERROR;


		if (GetTempFileName(tempName, "tclr", 0, tempName) != 0) {

		    /*
		     * Strictly speaking, need the following DeleteFile and
		     * MoveFile to be joined as an atomic operation so no
		     * other app comes along in the meantime and creates the
		     * same temp file.
		     */
		     

		    DeleteFile(tempName);
		    if (MoveFile(dst, tempName) != FALSE) {
			if (MoveFile(src, dst) != FALSE) {

			    SetFileAttributes(tempName, FILE_ATTRIBUTE_NORMAL);
			    DeleteFile(tempName);
			    return TCL_OK;
			} else {
			    DeleteFile(dst);
			    MoveFile(tempName, dst);
			}
		    } 

		    /*
		     * Can't backup dst file or move src file.  Return that
		     * error.  Could happen if an open file refers to dst.
		     */

		    TclWinConvertError(GetLastError());
		    if (errno == EACCES) {
			/*
			 * Decode the EACCES to a more meaningful error.
			 */

			goto decode;
		    }
		}
		return result;
	    }
	}
    }
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpCopyFile --
 *
 *      Copy a single file (not a directory).  If dst already exists and
 *	is not a directory, it is removed.
 *
 * Results:
 *	If the file was successfully copied, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>

|
>
>






|






|
|
|
>
>
>
>


|
>
>
>
>







|












|
<

<
|
>
>
>
>

|
>
|


|
>
|


<
<
>
>
|
>
>
|





>
>


|
|
>
>
>







|

|










|













|













|






|









|
|
|








|



|










|

|

|
>
|


>
>
>
|

>
>
|
>







>
|
|
|
>
|
|


|
|









|

















|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257


258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
 *	renames of directories if errno is EXDEV.
 *
 *---------------------------------------------------------------------------
 */

int
TclpRenameFile(
    CONST char *src,		/* Pathname of file or dir to be renamed
				 * (UTF-8). */
    CONST char *dst)		/* New pathname of file or directory
				 * (UTF-8). */
{
    int result;
    TCHAR *nativeSrc;
    Tcl_DString srcString, dstString;

    nativeSrc = Tcl_WinUtfToTChar(src, -1, &srcString);
    Tcl_WinUtfToTChar(dst, -1, &dstString);

    if ((TclWinGetPlatformId() == VER_PLATFORM_WIN32s) 
	    && ((Tcl_DStringLength(&srcString) >= MAX_PATH - 1) ||
		    (Tcl_DStringLength(&dstString) >= MAX_PATH - 1))) {
	/*
	 * On Win32s, really long file names cause the MoveFile() call
	 * to lock up, endlessly throwing an access violation and 
	 * retrying the operation.
	 */

	errno = ENAMETOOLONG;
	result = TCL_ERROR;
    } else {
	result = DoRenameFile(nativeSrc, &dstString);
    }
    Tcl_DStringFree(&srcString);
    Tcl_DStringFree(&dstString);
    return result;
}

static int
DoRenameFile(
    CONST TCHAR *nativeSrc,	/* Pathname of file or dir to be renamed
				 * (native). */ 
    Tcl_DString *dstPtr)	/* New pathname for file or directory
				 * (native). */
{    
    const TCHAR *nativeDst;
    DWORD srcAttr, dstAttr;

    nativeDst = (TCHAR *) Tcl_DStringValue(dstPtr);

    /*
     * Would throw an exception under NT if one of the arguments is a 
     * char block device.
     */

    try {
	if ((*tclWinProcs->moveFileProc)(nativeSrc, nativeDst) != FALSE) {
	    return TCL_OK;
	}
    } except (-1) {}

    TclWinConvertError(GetLastError());

    srcAttr = (*tclWinProcs->getFileAttributesProc)(nativeSrc);
    dstAttr = (*tclWinProcs->getFileAttributesProc)(nativeDst);
    if (srcAttr == 0xffffffff) {
	if ((*tclWinProcs->getFullPathNameProc)(nativeSrc, 0, NULL, NULL) >= MAX_PATH) {
	    errno = ENAMETOOLONG;
	    return TCL_ERROR;
	}
	srcAttr = 0;
    }
    if (dstAttr == 0xffffffff) {
	if ((*tclWinProcs->getFullPathNameProc)(nativeDst, 0, NULL, NULL) >= MAX_PATH) {
	    errno = ENAMETOOLONG;
	    return TCL_ERROR;
	}
	dstAttr = 0;
    }

    if (errno == EBADF) {
	errno = EACCES;
	return TCL_ERROR;
    }
    if ((TclWinGetPlatformId() == VER_PLATFORM_WIN32s) && (errno == EACCES)) {
	if ((srcAttr != 0) && (dstAttr != 0)) {
	    /*
	     * Win32s reports trying to overwrite an existing file or directory
	     * as EACCES.
	     */

	    errno = EEXIST;
	}
    }
    if (errno == EACCES) {
	decode:
	if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) {
	    TCHAR *nativeSrcRest, *nativeDstRest;

	    char **srcArgv, **dstArgv;

	    int size, srcArgc, dstArgc;
	    WCHAR nativeSrcPath[MAX_PATH];
	    WCHAR nativeDstPath[MAX_PATH];
	    Tcl_DString srcString, dstString;
	    CONST char *src, *dst;

	    size = (*tclWinProcs->getFullPathNameProc)(nativeSrc, MAX_PATH, 
		    nativeSrcPath, &nativeSrcRest);
	    if ((size == 0) || (size > MAX_PATH)) {
		return TCL_ERROR;
	    }
	    size = (*tclWinProcs->getFullPathNameProc)(nativeDst, MAX_PATH, 
		    nativeDstPath, &nativeDstRest);
	    if ((size == 0) || (size > MAX_PATH)) {
		return TCL_ERROR;
	    }


	    (*tclWinProcs->charLowerProc)((TCHAR *) nativeSrcPath);
	    (*tclWinProcs->charLowerProc)((TCHAR *) nativeDstPath);

	    src = Tcl_WinTCharToUtf((TCHAR *) nativeSrcPath, -1, &srcString);
	    dst = Tcl_WinTCharToUtf((TCHAR *) nativeDstPath, -1, &dstString);
	    if (strncmp(src, dst, Tcl_DStringLength(&srcString)) == 0) {
		/*
		 * Trying to move a directory into itself.
		 */

		errno = EINVAL;
		Tcl_DStringFree(&srcString);
		Tcl_DStringFree(&dstString);
		return TCL_ERROR;
	    }
	    Tcl_SplitPath(src, &srcArgc, &srcArgv);
	    Tcl_SplitPath(dst, &dstArgc, &dstArgv);
	    Tcl_DStringFree(&srcString);
	    Tcl_DStringFree(&dstString);

	    if (srcArgc == 1) {
		/*
		 * They are trying to move a root directory.  Whether
		 * or not it is across filesystems, this cannot be
		 * done.
		 */

		Tcl_SetErrno(EINVAL);
	    } else if ((srcArgc > 0) && (dstArgc > 0) &&
		    (strcmp(srcArgv[0], dstArgv[0]) != 0)) {
		/*
		 * If src is a directory and dst filesystem != src
		 * filesystem, errno should be EXDEV.  It is very
		 * important to get this behavior, so that the caller
		 * can respond to a cross filesystem rename by
		 * simulating it with copy and delete.  The MoveFile
		 * system call already handles the case of moving a
		 * file between filesystems.
		 */

		Tcl_SetErrno(EXDEV);
	    }

	    ckfree((char *) srcArgv);
	    ckfree((char *) dstArgv);
	}

	/*
	 * Other types of access failure is that dst is a read-only
	 * filesystem, that an open file referred to src or dest, or that
	 * src or dest specified the current working directory on the
	 * current filesystem.  EACCES is returned for those cases.
	 */

    } else if (Tcl_GetErrno() == EEXIST) {
	/*
	 * Reports EEXIST any time the target already exists.  If it makes
	 * sense, remove the old file and try renaming again.
	 */

	if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) {
	    if (dstAttr & FILE_ATTRIBUTE_DIRECTORY) {
		/*
		 * Overwrite empty dst directory with src directory.  The
		 * following call will remove an empty directory.  If it
		 * fails, it's because it wasn't empty.
		 */

		if (DoRemoveDirectory(dstPtr, 0, NULL) == TCL_OK) {
		    /*
		     * Now that that empty directory is gone, we can try
		     * renaming again.  If that fails, we'll put this empty
		     * directory back, for completeness.
		     */

		    if ((*tclWinProcs->moveFileProc)(nativeSrc, nativeDst) != FALSE) {
			return TCL_OK;
		    }

		    /*
		     * Some new error has occurred.  Don't know what it
		     * could be, but report this one.
		     */

		    TclWinConvertError(GetLastError());
		    (*tclWinProcs->createDirectoryProc)(nativeDst, NULL);
		    (*tclWinProcs->setFileAttributesProc)(nativeDst, dstAttr);
		    if (Tcl_GetErrno() == EACCES) {
			/*
			 * Decode the EACCES to a more meaningful error.
			 */

			goto decode;
		    }
		}
	    } else {	/* (dstAttr & FILE_ATTRIBUTE_DIRECTORY) == 0 */
		Tcl_SetErrno(ENOTDIR);
	    }
	} else {    /* (srcAttr & FILE_ATTRIBUTE_DIRECTORY) == 0 */
	    if (dstAttr & FILE_ATTRIBUTE_DIRECTORY) {
		Tcl_SetErrno(EISDIR);
	    } else {
		/*
		 * Overwrite existing file by:
		 * 
		 * 1. Rename existing file to temp name.
		 * 2. Rename old file to new name.
		 * 3. If success, delete temp file.  If failure,
		 *    put temp file back to old name.
		 */

		TCHAR *nativeRest, *nativeTmp, *nativePrefix;
		int result, size;
		WCHAR tempBuf[MAX_PATH];
		
		size = (*tclWinProcs->getFullPathNameProc)(nativeDst, MAX_PATH, 
			tempBuf, &nativeRest);
		if ((size == 0) || (size > MAX_PATH) || (nativeRest == NULL)) {
		    return TCL_ERROR;
		}
		nativeTmp = (TCHAR *) tempBuf;
		((char *) nativeRest)[0] = '\0';
		((char *) nativeRest)[1] = '\0';    /* In case it's Unicode. */

		result = TCL_ERROR;
		nativePrefix = (tclWinProcs->useWide) 
			? (TCHAR *) L"tclr" : (TCHAR *) "tclr";
		if ((*tclWinProcs->getTempFileNameProc)(nativeTmp, 
			nativePrefix, 0, tempBuf) != 0) {
		    /*
		     * Strictly speaking, need the following DeleteFile and
		     * MoveFile to be joined as an atomic operation so no
		     * other app comes along in the meantime and creates the
		     * same temp file.
		     */
		     
		    nativeTmp = (TCHAR *) tempBuf;
		    (*tclWinProcs->deleteFileProc)(nativeTmp);
		    if ((*tclWinProcs->moveFileProc)(nativeDst, nativeTmp) != FALSE) {
			if ((*tclWinProcs->moveFileProc)(nativeSrc, nativeDst) != FALSE) {
			    (*tclWinProcs->setFileAttributesProc)(nativeTmp, 
				    FILE_ATTRIBUTE_NORMAL);
			    (*tclWinProcs->deleteFileProc)(nativeTmp);
			    return TCL_OK;
			} else {
			    (*tclWinProcs->deleteFileProc)(nativeDst);
			    (*tclWinProcs->moveFileProc)(nativeTmp, nativeDst);
			}
		    } 

		    /*
		     * Can't backup dst file or move src file.  Return that
		     * error.  Could happen if an open file refers to dst.
		     */

		    TclWinConvertError(GetLastError());
		    if (Tcl_GetErrno() == EACCES) {
			/*
			 * Decode the EACCES to a more meaningful error.
			 */

			goto decode;
		    }
		}
		return result;
	    }
	}
    }
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpCopyFile, DoCopyFile --
 *
 *      Copy a single file (not a directory).  If dst already exists and
 *	is not a directory, it is removed.
 *
 * Results:
 *	If the file was successfully copied, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the
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
 *	It is not an error to copy to a char device.
 *
 *---------------------------------------------------------------------------
 */

int 
TclpCopyFile(
    char *src,			/* Pathname of file to be copied. */
    char *dst)			/* Pathname of file to copy to. */
{





















    /*
     * Would throw an exception under NT if one of the arguments is a char
     * block device.
     */

    try {
	if (CopyFile(src, dst, 0) != FALSE) {
	    return TCL_OK;
	}
    } except (-1) {}

    TclWinConvertError(GetLastError());
    if (errno == EBADF) {
	errno = EACCES;
	return TCL_ERROR;
    }
    if (errno == EACCES) {
	DWORD srcAttr, dstAttr;

	srcAttr = GetFileAttributes(src);
	dstAttr = GetFileAttributes(dst);
	if (srcAttr != (DWORD) -1) {
	    if (dstAttr == (DWORD) -1) {
		dstAttr = 0;
	    }
	    if ((srcAttr & FILE_ATTRIBUTE_DIRECTORY) ||
		    (dstAttr & FILE_ATTRIBUTE_DIRECTORY)) {
		errno = EISDIR;
	    }
	    if (dstAttr & FILE_ATTRIBUTE_READONLY) {

		SetFileAttributes(dst, dstAttr & ~FILE_ATTRIBUTE_READONLY);
		if (CopyFile(src, dst, 0) != FALSE) {
		    return TCL_OK;
		}
		/*
		 * Still can't copy onto dst.  Return that error, and
		 * restore attributes of dst.
		 */

		TclWinConvertError(GetLastError());
		SetFileAttributes(dst, dstAttr);
	    }
	}
    }
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpDeleteFile --
 *
 *      Removes a single file (not a directory).
 *
 * Results:
 *	If the file was successfully deleted, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the
 *	error.  Some possible values for errno are:







|
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|





|
|


|


|
|
|
|




|


>
|
|








|









|







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
 *	It is not an error to copy to a char device.
 *
 *---------------------------------------------------------------------------
 */

int 
TclpCopyFile(
    CONST char *src,		/* Pathname of file to be copied (UTF-8). */
    CONST char *dst)		/* Pathname of file to copy to (UTF-8). */
{
    int result;
    Tcl_DString srcString, dstString;

    Tcl_WinUtfToTChar(src, -1, &srcString);
    Tcl_WinUtfToTChar(dst, -1, &dstString);
    result = DoCopyFile(&srcString, &dstString);
    Tcl_DStringFree(&srcString);
    Tcl_DStringFree(&dstString);
    return result;
}

static int
DoCopyFile(
    Tcl_DString *srcPtr,	/* Pathname of file to be copied (native). */
    Tcl_DString *dstPtr)	/* Pathname of file to copy to (native). */
{
    CONST TCHAR *nativeSrc, *nativeDst;

    nativeSrc = (TCHAR *) Tcl_DStringValue(srcPtr);
    nativeDst = (TCHAR *) Tcl_DStringValue(dstPtr);

    /*
     * Would throw an exception under NT if one of the arguments is a char
     * block device.
     */

    try {
	if ((*tclWinProcs->copyFileProc)(nativeSrc, nativeDst, 0) != FALSE) {
	    return TCL_OK;
	}
    } except (-1) {}

    TclWinConvertError(GetLastError());
    if (Tcl_GetErrno() == EBADF) {
	Tcl_SetErrno(EACCES);
	return TCL_ERROR;
    }
    if (Tcl_GetErrno() == EACCES) {
	DWORD srcAttr, dstAttr;

	srcAttr = (*tclWinProcs->getFileAttributesProc)(nativeSrc);
	dstAttr = (*tclWinProcs->getFileAttributesProc)(nativeDst);
	if (srcAttr != 0xffffffff) {
	    if (dstAttr == 0xffffffff) {
		dstAttr = 0;
	    }
	    if ((srcAttr & FILE_ATTRIBUTE_DIRECTORY) ||
		    (dstAttr & FILE_ATTRIBUTE_DIRECTORY)) {
		Tcl_SetErrno(EISDIR);
	    }
	    if (dstAttr & FILE_ATTRIBUTE_READONLY) {
		(*tclWinProcs->setFileAttributesProc)(nativeDst, 
			dstAttr & ~FILE_ATTRIBUTE_READONLY);
		if ((*tclWinProcs->copyFileProc)(nativeSrc, nativeDst, 0) != FALSE) {
		    return TCL_OK;
		}
		/*
		 * Still can't copy onto dst.  Return that error, and
		 * restore attributes of dst.
		 */

		TclWinConvertError(GetLastError());
		(*tclWinProcs->setFileAttributesProc)(nativeDst, dstAttr);
	    }
	}
    }
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpDeleteFile, DoDeleteFile --
 *
 *      Removes a single file (not a directory).
 *
 * Results:
 *	If the file was successfully deleted, returns TCL_OK.  Otherwise
 *	the return value is TCL_ERROR and errno is set to indicate the
 *	error.  Some possible values for errno are:
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
 *      The file is deleted, even if it is read-only.
 *
 *---------------------------------------------------------------------------
 */

int
TclpDeleteFile(
    char *path)			/* Pathname of file to be removed. */
{













    DWORD attr;



    if (DeleteFile(path) != FALSE) {

	return TCL_OK;
    }
    TclWinConvertError(GetLastError());
    if (path[0] == '\0') {
	/*
	 * Win32s thinks that "" is the same as "." and then reports EISDIR
	 * instead of ENOENT.
	 */



	errno = ENOENT;


    } else if (errno == EACCES) {






        attr = GetFileAttributes(path);
	if (attr != (DWORD) -1) {
	    if (attr & FILE_ATTRIBUTE_DIRECTORY) {
		/*
		 * Windows NT reports removing a directory as EACCES instead
		 * of EISDIR.
		 */

		errno = EISDIR;
	    } else if (attr & FILE_ATTRIBUTE_READONLY) {

		SetFileAttributes(path, attr & ~FILE_ATTRIBUTE_READONLY);
		if (DeleteFile(path) != FALSE) {
		    return TCL_OK;
		}
		TclWinConvertError(GetLastError());
		SetFileAttributes(path, attr);
	    }
	}
    } else if (errno == ENOENT) {
        attr = GetFileAttributes(path);
	if (attr != (DWORD) -1) {
	    if (attr & FILE_ATTRIBUTE_DIRECTORY) {
	    	/*
		 * Windows 95 reports removing a directory as ENOENT instead 
		 * of EISDIR. 
		 */

		errno = EISDIR;
	    }
	}
    } else if (errno == EINVAL) {
	/*
	 * Windows NT reports removing a char device as EINVAL instead of
	 * EACCES.
	 */

	errno = EACCES;
    }

    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------







|

>
>
>
>
>
>
>
>
>
>
>
>
>

>

>
|
>



|
|
|
|
|

>
>
|
>
>
|
>
>
>
>
>
>
|
|






|

>
|
|



|


|
|
|






|


|





|







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
 *      The file is deleted, even if it is read-only.
 *
 *---------------------------------------------------------------------------
 */

int
TclpDeleteFile(
    CONST char *path)		/* Pathname of file to be removed (UTF-8). */
{
    int result;
    Tcl_DString pathString;

    Tcl_WinUtfToTChar(path, -1, &pathString);
    result = DoDeleteFile(&pathString);
    Tcl_DStringFree(&pathString);
    return result;
}

static int
DoDeleteFile(
    Tcl_DString *pathPtr)	/* Pathname of file to be removed (native). */
{
    DWORD attr;
    CONST TCHAR *nativePath;

    nativePath = (TCHAR *) Tcl_DStringValue(pathPtr);
    
    if ((*tclWinProcs->deleteFileProc)(nativePath) != FALSE) {
	return TCL_OK;
    }
    TclWinConvertError(GetLastError());

    /*
     * Win32s thinks that "" is the same as "." and then reports EISDIR
     * instead of ENOENT.
     */

    if (tclWinProcs->useWide) {
	if (((WCHAR *) nativePath)[0] == '\0') {
	    Tcl_SetErrno(ENOENT);
	    return TCL_ERROR;
	}
    } else {
	if (((char *) nativePath)[0] == '\0') {
	    Tcl_SetErrno(ENOENT);
	    return TCL_ERROR;
	}
    }
    if (Tcl_GetErrno() == EACCES) {
        attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
	if (attr != 0xffffffff) {
	    if (attr & FILE_ATTRIBUTE_DIRECTORY) {
		/*
		 * Windows NT reports removing a directory as EACCES instead
		 * of EISDIR.
		 */

		Tcl_SetErrno(EISDIR);
	    } else if (attr & FILE_ATTRIBUTE_READONLY) {
		(*tclWinProcs->setFileAttributesProc)(nativePath, 
			attr & ~FILE_ATTRIBUTE_READONLY);
		if ((*tclWinProcs->deleteFileProc)(nativePath) != FALSE) {
		    return TCL_OK;
		}
		TclWinConvertError(GetLastError());
		(*tclWinProcs->setFileAttributesProc)(nativePath, attr);
	    }
	}
    } else if (Tcl_GetErrno() == ENOENT) {
        attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
	if (attr != 0xffffffff) {
	    if (attr & FILE_ATTRIBUTE_DIRECTORY) {
	    	/*
		 * Windows 95 reports removing a directory as ENOENT instead 
		 * of EISDIR. 
		 */

		Tcl_SetErrno(EISDIR);
	    }
	}
    } else if (Tcl_GetErrno() == EINVAL) {
	/*
	 * Windows NT reports removing a char device as EINVAL instead of
	 * EACCES.
	 */

	Tcl_SetErrno(EACCES);
    }

    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
538
539
540
541
542
543
544
545
546













547

548

549
550
551
552
553

554
555
556
557
558
559
560
 *      A directory is created.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCreateDirectory(
    char *path)			/* Pathname of directory to create */
{













    int error;



    if (CreateDirectory(path, NULL) == 0) {
	error = GetLastError();
	if (TclWinGetPlatformId() == VER_PLATFORM_WIN32s) {
	    if ((error == ERROR_ACCESS_DENIED) 
		    && (GetFileAttributes(path) != (DWORD) -1)) {

		error = ERROR_FILE_EXISTS;
	    }
	}
	TclWinConvertError(error);
	return TCL_ERROR;
    }   
    return TCL_OK;







|

>
>
>
>
>
>
>
>
>
>
>
>
>

>

>
|



|
>







662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
 *      A directory is created.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCreateDirectory(
    CONST char *path)		/* Pathname of directory to create (UTF-8). */
{
    int result;
    Tcl_DString pathString;

    Tcl_WinUtfToTChar(path, -1, &pathString);
    result = DoCreateDirectory(&pathString);
    Tcl_DStringFree(&pathString);
    return result;
}

static int
DoCreateDirectory(
    Tcl_DString *pathPtr)	/* Pathname of directory to create (native). */
{
    int error;
    CONST TCHAR *nativePath;

    nativePath = (TCHAR *) Tcl_DStringValue(pathPtr);
    if ((*tclWinProcs->createDirectoryProc)(nativePath, NULL) == 0) {
	error = GetLastError();
	if (TclWinGetPlatformId() == VER_PLATFORM_WIN32s) {
	    if ((error == ERROR_ACCESS_DENIED) 
		    && ((*tclWinProcs->getFileAttributesProc)(nativePath) 
			    != 0xffffffff)) {
		error = ERROR_FILE_EXISTS;
	    }
	}
	TclWinConvertError(error);
	return TCL_ERROR;
    }   
    return TCL_OK;
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
 *	processed.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCopyDirectory(
    char *src,			/* Pathname of directory to be copied. */

    char *dst,			/* Pathname of target directory. */
    Tcl_DString *errorPtr)	/* If non-NULL, initialized DString for

				 * error reporting. */
{
    int result;
    Tcl_DString srcBuffer;
    Tcl_DString dstBuffer;

    Tcl_DStringInit(&srcBuffer);
    Tcl_DStringInit(&dstBuffer);
    Tcl_DStringAppend(&srcBuffer, src, -1);
    Tcl_DStringAppend(&dstBuffer, dst, -1);
    result = TraverseWinTree(TraversalCopy, &srcBuffer, &dstBuffer, 
	    errorPtr);
    Tcl_DStringFree(&srcBuffer);
    Tcl_DStringFree(&dstBuffer);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpRemoveDirectory -- 
 *
 *	Removes directory (and its contents, if the recursive flag is set).
 *
 * Results:
 *	If the directory was successfully removed, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR, errno is set to indicate
 *	the error, and the pathname of the file that caused the error







|
>
|
|
>
|


|
<

|
|
|
<
|
|
|
|






|







724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739

740
741
742
743

744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
 *	processed.
 *
 *---------------------------------------------------------------------------
 */

int
TclpCopyDirectory(
    CONST char *src,		/* Pathname of directory to be copied
				 * (UTF-8). */
    CONST char *dst,		/* Pathname of target directory (UTF-8). */
    Tcl_DString *errorPtr)	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    int result;
    Tcl_DString srcString, dstString;


    Tcl_WinUtfToTChar(src, -1, &srcString);
    Tcl_WinUtfToTChar(dst, -1, &dstString);


    result = TraverseWinTree(TraversalCopy, &srcString, &dstString, errorPtr);

    Tcl_DStringFree(&srcString);
    Tcl_DStringFree(&dstString);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpRemoveDirectory, DoRemoveDirectory -- 
 *
 *	Removes directory (and its contents, if the recursive flag is set).
 *
 * Results:
 *	If the directory was successfully removed, returns TCL_OK.
 *	Otherwise the return value is TCL_ERROR, errno is set to indicate
 *	the error, and the pathname of the file that caused the error
635
636
637
638
639
640
641
642

643
644
645
646

647
648
649
650




















651
652

653

654
655
656
657
658
659
660
661
662
663




664






665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686

687
688
689
690
691
692
693
694
695
696

697
698
699
700
701
702


703

704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
 *	immediately, and remaining files will not be deleted.
 *
 *----------------------------------------------------------------------
 */

int
TclpRemoveDirectory(
    char *path,			/* Pathname of directory to be removed. */

    int recursive,		/* If non-zero, removes directories that
				 * are nonempty.  Otherwise, will only remove
				 * empty directories. */
    Tcl_DString *errorPtr)	/* If non-NULL, initialized DString for

				 * error reporting. */
{
    int result;
    Tcl_DString buffer;




















    DWORD attr;


    if (RemoveDirectory(path) != FALSE) {

	return TCL_OK;
    }
    TclWinConvertError(GetLastError());
    if (path[0] == '\0') {
	/*
	 * Win32s thinks that "" is the same as "." and then reports EACCES
	 * instead of ENOENT.
	 */

	errno = ENOENT;




    }






    if (errno == EACCES) {
	attr = GetFileAttributes(path);
	if (attr != (DWORD) -1) {
	    if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
		/* 
		 * Windows 95 reports calling RemoveDirectory on a file as an 
		 * EACCES, not an ENOTDIR.
		 */
		
		errno = ENOTDIR;
		goto end;
	    }

	    if (attr & FILE_ATTRIBUTE_READONLY) {
		attr &= ~FILE_ATTRIBUTE_READONLY;
		if (SetFileAttributes(path, attr) == FALSE) {
		    goto end;
		}
		if (RemoveDirectory(path) != FALSE) {
		    return TCL_OK;
		}
		TclWinConvertError(GetLastError());

		SetFileAttributes(path, attr | FILE_ATTRIBUTE_READONLY);
	    }

	    /* 
	     * Windows 95 and Win32s report removing a non-empty directory 
	     * as EACCES, not EEXIST.  If the directory is not empty,
	     * change errno so caller knows what's going on.
	     */

	    if (TclWinGetPlatformId() != VER_PLATFORM_WIN32_NT) {

		HANDLE handle;
		WIN32_FIND_DATA data;
		Tcl_DString buffer;
		char *find;
		int len;



		Tcl_DStringInit(&buffer);

		find = Tcl_DStringAppend(&buffer, path, -1);
		len = Tcl_DStringLength(&buffer);
		if ((len > 0) && (find[len - 1] != '\\')) {
		    Tcl_DStringAppend(&buffer, "\\", 1);
		}
		find = Tcl_DStringAppend(&buffer, "*.*", 3);
		handle = FindFirstFile(find, &data);
		if (handle != INVALID_HANDLE_VALUE) {
		    while (1) {
			if ((strcmp(data.cFileName, ".") != 0)
				&& (strcmp(data.cFileName, "..") != 0)) {
			    /*
			     * Found something in this directory.
			     */

			    errno = EEXIST;
			    break;
			}
			if (FindNextFile(handle, &data) == FALSE) {
			    break;
			}
		    }
		    FindClose(handle);
		}
		Tcl_DStringFree(&buffer);
	    }
	}
    }
    if (errno == ENOTEMPTY) {
	/* 
	 * The caller depends on EEXIST to signify that the directory is
	 * not empty, not ENOTEMPTY. 
	 */

	errno = EEXIST;
    }
    if ((recursive != 0) && (errno == EEXIST)) {
	/*
	 * The directory is nonempty, but the recursive flag has been
	 * specified, so we recursively remove all the files in the directory.
	 */

	Tcl_DStringInit(&buffer);
	Tcl_DStringAppend(&buffer, path, -1);
	result = TraverseWinTree(TraversalDelete, &buffer, NULL, errorPtr);
	Tcl_DStringFree(&buffer);
	return result;
    }

    end:
    if (errorPtr != NULL) {
        Tcl_DStringAppend(errorPtr, path, -1);
    }
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *







|
>



|
>
|


|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
|
>



|
|
|
|
|

|
>
>
>
>
|
>
>
>
>
>
>
|
|
|






|





|


|



>
|









>

|

<


>
>

>
|
<




|








|


|









|





|

|





<
<
|
<
<

|


|







775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875

876
877
878
879
880
881
882

883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922


923


924
925
926
927
928
929
930
931
932
933
934
935
 *	immediately, and remaining files will not be deleted.
 *
 *----------------------------------------------------------------------
 */

int
TclpRemoveDirectory(
    CONST char *path,		/* Pathname of directory to be removed
				 * (UTF-8). */
    int recursive,		/* If non-zero, removes directories that
				 * are nonempty.  Otherwise, will only remove
				 * empty directories. */
    Tcl_DString *errorPtr)	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    int result;
    Tcl_DString pathString;

    Tcl_WinUtfToTChar(path, -1, &pathString);
    result = DoRemoveDirectory(&pathString, recursive, errorPtr);
    Tcl_DStringFree(&pathString);

    return result;
}

static int
DoRemoveDirectory(
    Tcl_DString *pathPtr,	/* Pathname of directory to be removed
				 * (native). */
    int recursive,		/* If non-zero, removes directories that
				 * are nonempty.  Otherwise, will only remove
				 * empty directories. */
    Tcl_DString *errorPtr)	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    CONST TCHAR *nativePath;
    DWORD attr;

    nativePath = (TCHAR *) Tcl_DStringValue(pathPtr);

    if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) {
	return TCL_OK;
    }
    TclWinConvertError(GetLastError());

    /*
     * Win32s thinks that "" is the same as "." and then reports EACCES
     * instead of ENOENT.
     */


    if (tclWinProcs->useWide) {
	if (((WCHAR *) nativePath)[0] == '\0') {
	    Tcl_SetErrno(ENOENT);
	    return TCL_ERROR;
	}
    } else {
	if (((char *) nativePath)[0] == '\0') {
	    Tcl_SetErrno(ENOENT);
	    return TCL_ERROR;
	}
    }
    if (Tcl_GetErrno() == EACCES) {
	attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
	if (attr != 0xffffffff) {
	    if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
		/* 
		 * Windows 95 reports calling RemoveDirectory on a file as an 
		 * EACCES, not an ENOTDIR.
		 */
		
		Tcl_SetErrno(ENOTDIR);
		goto end;
	    }

	    if (attr & FILE_ATTRIBUTE_READONLY) {
		attr &= ~FILE_ATTRIBUTE_READONLY;
		if ((*tclWinProcs->setFileAttributesProc)(nativePath, attr) == FALSE) {
		    goto end;
		}
		if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) {
		    return TCL_OK;
		}
		TclWinConvertError(GetLastError());
		(*tclWinProcs->setFileAttributesProc)(nativePath, 
			attr | FILE_ATTRIBUTE_READONLY);
	    }

	    /* 
	     * Windows 95 and Win32s report removing a non-empty directory 
	     * as EACCES, not EEXIST.  If the directory is not empty,
	     * change errno so caller knows what's going on.
	     */

	    if (TclWinGetPlatformId() != VER_PLATFORM_WIN32_NT) {
		char *path, *find;
		HANDLE handle;
		WIN32_FIND_DATAA data;
		Tcl_DString buffer;

		int len;

		path = (char *) nativePath;

		Tcl_DStringInit(&buffer);
		len = strlen(path);
		find = Tcl_DStringAppend(&buffer, path, len);

		if ((len > 0) && (find[len - 1] != '\\')) {
		    Tcl_DStringAppend(&buffer, "\\", 1);
		}
		find = Tcl_DStringAppend(&buffer, "*.*", 3);
		handle = FindFirstFileA(find, &data);
		if (handle != INVALID_HANDLE_VALUE) {
		    while (1) {
			if ((strcmp(data.cFileName, ".") != 0)
				&& (strcmp(data.cFileName, "..") != 0)) {
			    /*
			     * Found something in this directory.
			     */

			    Tcl_SetErrno(EEXIST);
			    break;
			}
			if (FindNextFileA(handle, &data) == FALSE) {
			    break;
			}
		    }
		    FindClose(handle);
		}
		Tcl_DStringFree(&buffer);
	    }
	}
    }
    if (Tcl_GetErrno() == ENOTEMPTY) {
	/* 
	 * The caller depends on EEXIST to signify that the directory is
	 * not empty, not ENOTEMPTY. 
	 */

	Tcl_SetErrno(EEXIST);
    }
    if ((recursive != 0) && (Tcl_GetErrno() == EEXIST)) {
	/*
	 * The directory is nonempty, but the recursive flag has been
	 * specified, so we recursively remove all the files in the directory.
	 */



	return TraverseWinTree(TraversalDelete, pathPtr, NULL, errorPtr);


    }
    
    end:
    if (errorPtr != NULL) {
	Tcl_WinTCharToUtf(nativePath, -1, errorPtr);
    }
    return TCL_ERROR;
}

/*
 *---------------------------------------------------------------------------
 *
780
781
782
783
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798

799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832

833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848


849
850
851
852
853
854










855


856

857
858


859

860
861
862




863
















864
865






866
867
868
869
870

871
872

873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
 */

static int 
TraverseWinTree(
    TraversalProc *traverseProc,/* Function to call for every file and
				 * directory in source hierarchy. */
    Tcl_DString *sourcePtr,	/* Pathname of source directory to be
				 * traversed. */
    Tcl_DString *targetPtr,	/* Pathname of directory to traverse in
				 * parallel with source directory. */
    Tcl_DString *errorPtr)	/* If non-NULL, an initialized DString for

				 * error reporting. */
{
    DWORD sourceAttr;
    char *source, *target, *errfile;
    int result, sourceLen, targetLen, sourceLenOriginal, targetLenOriginal;
    HANDLE handle;
    WIN32_FIND_DATA data;


    result = TCL_OK;
    source = Tcl_DStringValue(sourcePtr);
    sourceLenOriginal = Tcl_DStringLength(sourcePtr);
    if (targetPtr != NULL) {
	target = Tcl_DStringValue(targetPtr);
	targetLenOriginal = Tcl_DStringLength(targetPtr);
    } else {
	target = NULL;
	targetLenOriginal = 0;
    }

    errfile = NULL;

    sourceAttr = GetFileAttributes(source);
    if (sourceAttr == (DWORD) -1) {
	errfile = source;
	goto end;
    }
    if ((sourceAttr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
	/*
	 * Process the regular file
	 */

	return (*traverseProc)(source, target, sourceAttr, DOTREE_F, errorPtr);
    }

    /*
     * When given the pathname of the form "c:\" (one that already ends
     * with a backslash), must make sure not to add another "\" to the end
     * otherwise it will try to access a network drive.  
     */

    sourceLen = sourceLenOriginal;
    if ((sourceLen > 0) && (source[sourceLen - 1] != '\\')) {

	Tcl_DStringAppend(sourcePtr, "\\", 1);
	sourceLen++;
    }
    source = Tcl_DStringAppend(sourcePtr, "*.*", 3); 
    handle = FindFirstFile(source, &data);
    Tcl_DStringSetLength(sourcePtr, sourceLen);
    if (handle == INVALID_HANDLE_VALUE) {
	/* 
	 * Can't read directory
	 */

	TclWinConvertError(GetLastError());
	errfile = source;
	goto end;
    }



    result = (*traverseProc)(source, target, sourceAttr, DOTREE_PRED, errorPtr);
    if (result != TCL_OK) {
	FindClose(handle);
	return result;
    }











    if (targetPtr != NULL) {


	targetLen = targetLenOriginal;

	if ((targetLen > 0) && (target[targetLen - 1] != '\\')) {
	    target = Tcl_DStringAppend(targetPtr, "\\", 1);


	    targetLen++;

	}
    }





    while (1) {
















	if ((strcmp(data.cFileName, ".") != 0)
	        && (strcmp(data.cFileName, "..") != 0)) {






	    /* 
	     * Append name after slash, and recurse on the file. 
	     */

	    Tcl_DStringAppend(sourcePtr, data.cFileName, -1);

	    if (targetPtr != NULL) {
		Tcl_DStringAppend(targetPtr, data.cFileName, -1);

	    }
	    result = TraverseWinTree(traverseProc, sourcePtr, targetPtr, 
		    errorPtr);
	    if (result != TCL_OK) {
		break;
	    }

	    /*
	     * Remove name after slash.
	     */

	    Tcl_DStringSetLength(sourcePtr, sourceLen);
	    if (targetPtr != NULL) {
		Tcl_DStringSetLength(targetPtr, targetLen);
	    }
	}
	if (FindNextFile(handle, &data) == FALSE) {
	    break;
	}
    }
    FindClose(handle);

    /*
     * Strip off the trailing slash we added
     */

    Tcl_DStringSetLength(sourcePtr, sourceLenOriginal);
    source = Tcl_DStringValue(sourcePtr);
    if (targetPtr != NULL) {
	Tcl_DStringSetLength(targetPtr, targetLenOriginal);
	target = Tcl_DStringValue(targetPtr);
    }

    if (result == TCL_OK) {
	/*
	 * Call traverseProc() on a directory after visiting all the
	 * files in that directory.
	 */

	result = (*traverseProc)(source, target, sourceAttr, 
		DOTREE_POSTD, errorPtr);
    }
    end:
    if (errfile != NULL) {
	TclWinConvertError(GetLastError());
	if (errorPtr != NULL) {
	    Tcl_DStringAppend(errorPtr, errfile, -1);
	}
	result = TCL_ERROR;
    }
	    
    return result;
}








|

|
|
>
|


|
|

|

>

<
<
<
<
<
<
<
|
|
|
<
|
|
|
|







|


<
<
<
<
<
|
|
|
>
|
<

|
|
<
|





|



>
>
|





>
>
>
>
>
>
>
>
>
>

>
>
|
>
|
|
>
>
|
>



>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
|
|
|

|
>
|
|
>
|
|
|
|
|
|

|
|
|

|
|
|
<
<
<
<








|
|

|
|

<






|
|


|


|







953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974







975
976
977

978
979
980
981
982
983
984
985
986
987
988
989
990
991





992
993
994
995
996

997
998
999

1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093




1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107

1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
 */

static int 
TraverseWinTree(
    TraversalProc *traverseProc,/* Function to call for every file and
				 * directory in source hierarchy. */
    Tcl_DString *sourcePtr,	/* Pathname of source directory to be
				 * traversed (native). */
    Tcl_DString *targetPtr,	/* Pathname of directory to traverse in
				 * parallel with source directory (native). */
    Tcl_DString *errorPtr)	/* If non-NULL, uninitialized or free
				 * DString filled with UTF-8 name of file
				 * causing error. */
{
    DWORD sourceAttr;
    TCHAR *nativeSource, *nativeErrfile;
    int result, found, sourceLen, targetLen, oldSourceLen, oldTargetLen;
    HANDLE handle;
    WIN32_FIND_DATAT data;

    nativeErrfile = NULL;
    result = TCL_OK;







    oldTargetLen = 0;		/* lint. */

    nativeSource = (TCHAR *) Tcl_DStringValue(sourcePtr);

    oldSourceLen = Tcl_DStringLength(sourcePtr);
    sourceAttr = (*tclWinProcs->getFileAttributesProc)(nativeSource);
    if (sourceAttr == 0xffffffff) {
	nativeErrfile = nativeSource;
	goto end;
    }
    if ((sourceAttr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
	/*
	 * Process the regular file
	 */

	return (*traverseProc)(sourcePtr, targetPtr, DOTREE_F, errorPtr);
    }






    if (tclWinProcs->useWide) {
	Tcl_DStringAppend(sourcePtr, (char *) L"\\*.*", 4 * sizeof(WCHAR) + 1);
	Tcl_DStringSetLength(sourcePtr, Tcl_DStringLength(sourcePtr) - 1);
    } else {
	Tcl_DStringAppend(sourcePtr, "\\*.*", 4);

    }
    nativeSource = (TCHAR *) Tcl_DStringValue(sourcePtr);
    handle = (*tclWinProcs->findFirstFileProc)(nativeSource, &data);

    if (handle == INVALID_HANDLE_VALUE) {      
	/* 
	 * Can't read directory
	 */

	TclWinConvertError(GetLastError());
	nativeErrfile = nativeSource;
	goto end;
    }

    nativeSource[oldSourceLen + 1] = '\0';
    Tcl_DStringSetLength(sourcePtr, oldSourceLen);
    result = (*traverseProc)(sourcePtr, targetPtr, DOTREE_PRED, errorPtr);
    if (result != TCL_OK) {
	FindClose(handle);
	return result;
    }

    sourceLen = oldSourceLen;

    if (tclWinProcs->useWide) {
	sourceLen += sizeof(WCHAR);
	Tcl_DStringAppend(sourcePtr, (char *) L"\\", sizeof(WCHAR) + 1);
	Tcl_DStringSetLength(sourcePtr, sourceLen);
    } else {
	sourceLen += 1;
	Tcl_DStringAppend(sourcePtr, "\\", 1);
    }
    if (targetPtr != NULL) {
	oldTargetLen = Tcl_DStringLength(targetPtr);

	targetLen = oldTargetLen;
	if (tclWinProcs->useWide) {
	    targetLen += sizeof(WCHAR);
	    Tcl_DStringAppend(targetPtr, (char *) L"\\", sizeof(WCHAR) + 1);
	    Tcl_DStringSetLength(targetPtr, targetLen);
	} else {
	    targetLen += 1;
	    Tcl_DStringAppend(targetPtr, "\\", 1);
	}
    }

    found = 1;
    for ( ; found; found = (*tclWinProcs->findNextFileProc)(handle, &data)) {
	TCHAR *nativeName;
	int len;

	if (tclWinProcs->useWide) {
	    WCHAR *wp;

	    wp = data.w.cFileName;
	    if (*wp == '.') {
		wp++;
		if (*wp == '.') {
		    wp++;
		}
		if (*wp == '\0') {
		    continue;
		}
	    }
	    nativeName = (TCHAR *) data.w.cFileName;
	    len = Tcl_UniCharLen(data.w.cFileName) * sizeof(WCHAR);
	} else {
	    if ((strcmp(data.a.cFileName, ".") == 0) 
		    || (strcmp(data.a.cFileName, "..") == 0)) {
		continue;
	    }
	    nativeName = (TCHAR *) data.a.cFileName;
	    len = strlen(data.a.cFileName);
	}

	/* 
	 * Append name after slash, and recurse on the file. 
	 */

	Tcl_DStringAppend(sourcePtr, (char *) nativeName, len + 1);
	Tcl_DStringSetLength(sourcePtr, Tcl_DStringLength(sourcePtr) - 1);
	if (targetPtr != NULL) {
	    Tcl_DStringAppend(targetPtr, (char *) nativeName, len + 1);
	    Tcl_DStringSetLength(targetPtr, Tcl_DStringLength(targetPtr) - 1);
	}
	result = TraverseWinTree(traverseProc, sourcePtr, targetPtr, 
		errorPtr);
	if (result != TCL_OK) {
	    break;
	}

	/*
	 * Remove name after slash.
	 */

	Tcl_DStringSetLength(sourcePtr, sourceLen);
	if (targetPtr != NULL) {
	    Tcl_DStringSetLength(targetPtr, targetLen);




	}
    }
    FindClose(handle);

    /*
     * Strip off the trailing slash we added
     */

    Tcl_DStringSetLength(sourcePtr, oldSourceLen + 1);
    Tcl_DStringSetLength(sourcePtr, oldSourceLen);
    if (targetPtr != NULL) {
	Tcl_DStringSetLength(targetPtr, oldTargetLen + 1);
	Tcl_DStringSetLength(targetPtr, oldTargetLen);
    }

    if (result == TCL_OK) {
	/*
	 * Call traverseProc() on a directory after visiting all the
	 * files in that directory.
	 */

	result = (*traverseProc)(sourcePtr, targetPtr, DOTREE_POSTD, 
		errorPtr);
    }
    end:
    if (nativeErrfile != NULL) {
	TclWinConvertError(GetLastError());
	if (errorPtr != NULL) {
	    Tcl_WinTCharToUtf(nativeErrfile, -1, errorPtr);
	}
	result = TCL_ERROR;
    }
	    
    return result;
}

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
 *      Depending on the value of type, src may be copied to dst.
 *      
 *----------------------------------------------------------------------
 */

static int 
TraversalCopy(
    char *src,			/* Source pathname to copy. */
    char *dst,			/* Destination pathname of copy. */
    DWORD srcAttr,		/* File attributes for src. */
    int type,			/* Reason for call - see TraverseWinTree() */
    Tcl_DString *errorPtr)	/* If non-NULL, initialized DString for
				 * error return. */
{



    switch (type) {
	case DOTREE_F:
	    if (TclpCopyFile(src, dst) == TCL_OK) {
		return TCL_OK;
	    }
	    break;

	case DOTREE_PRED:
	    if (TclpCreateDirectory(dst) == TCL_OK) {


		if (SetFileAttributes(dst, srcAttr) != FALSE) {

		    return TCL_OK;
		}
		TclWinConvertError(GetLastError());
	    }
	    break;

        case DOTREE_POSTD:
	    return TCL_OK;

    }

    /*
     * There shouldn't be a problem with src, because we already
     * checked it to get here.
     */

    if (errorPtr != NULL) {
	Tcl_DStringAppend(errorPtr, dst, -1);

    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *







|
|
<

|
|

>
>
>

|
|



|
|
|
>
>
|
>





|
|

|








|
>







1141
1142
1143
1144
1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
 *      Depending on the value of type, src may be copied to dst.
 *      
 *----------------------------------------------------------------------
 */

static int 
TraversalCopy(
    Tcl_DString *srcPtr,	/* Source pathname to copy. */
    Tcl_DString *dstPtr,	/* Destination pathname of copy. */

    int type,			/* Reason for call - see TraverseWinTree() */
    Tcl_DString *errorPtr)	/* If non-NULL, initialized DString filled
				 * with UTF-8 name of file causing error. */
{
    TCHAR *nativeDst, *nativeSrc;
    DWORD attr;

    switch (type) {
	case DOTREE_F: {
	    if (DoCopyFile(srcPtr, dstPtr) == TCL_OK) {
		return TCL_OK;
	    }
	    break;
	}
	case DOTREE_PRED: {
	    if (DoCreateDirectory(dstPtr) == TCL_OK) {
		nativeSrc = (TCHAR *) Tcl_DStringValue(srcPtr);
		nativeDst = (TCHAR *) Tcl_DStringValue(dstPtr);
		attr = (*tclWinProcs->getFileAttributesProc)(nativeSrc);
		if ((*tclWinProcs->setFileAttributesProc)(nativeDst, attr) != FALSE) {
		    return TCL_OK;
		}
		TclWinConvertError(GetLastError());
	    }
	    break;
	}
        case DOTREE_POSTD: {
	    return TCL_OK;
	}
    }

    /*
     * There shouldn't be a problem with src, because we already
     * checked it to get here.
     */

    if (errorPtr != NULL) {
	nativeDst = (TCHAR *) Tcl_DStringValue(dstPtr);
	Tcl_WinTCharToUtf(nativeDst, -1, errorPtr);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014


1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
 *      and errno is set accordingly.
 *
 *----------------------------------------------------------------------
 */

static int
TraversalDelete( 
    char *src,			/* Source pathname. */
    char *ignore,		/* Destination pathname (not used). */
    DWORD srcAttr,		/* File attributes for src (not used). */
    int type,			/* Reason for call - see TraverseWinTree(). */
    Tcl_DString *errorPtr)	/* If non-NULL, initialized DString for
				 * error return. */
{


    switch (type) {
	case DOTREE_F:
	    if (TclpDeleteFile(src) == TCL_OK) {
		return TCL_OK;
	    }
	    break;

	case DOTREE_PRED:
	    return TCL_OK;

	case DOTREE_POSTD:
	    if (TclpRemoveDirectory(src, 0, NULL) == TCL_OK) {
		return TCL_OK;
	    }
	    break;

    }

    if (errorPtr != NULL) {
	Tcl_DStringAppend(errorPtr, src, -1);

    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * AttributesPosixError --
 *
 *	Sets the object result with the appropriate error.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      The interp's object result is set with an error message
 *	based on the objIndex, fileName and errno.
 *
 *----------------------------------------------------------------------
 */

static void
AttributesPosixError(
    Tcl_Interp *interp,		/* The interp that has the error */
    int objIndex,		/* The attribute which caused the problem. */
    char *fileName,		/* The name of the file which caused the 
				 * error. */
    int getOrSet)		/* 0 for get; 1 for set */
{
    TclWinConvertError(GetLastError());
    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
	    "cannot ", getOrSet ? "set" : "get", " attribute \"", 
	    tclpFileAttrStrings[objIndex], "\" for file \"", fileName, 
	    "\": ", Tcl_PosixError(interp), (char *) NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * GetWinFileAttributes --
 *







|
|
<
|
|
|

>
>

|
|



|
|

|
|
|



|



|
>







|














|

<
|

<



<
|
|







1209
1210
1211
1212
1213
1214
1215
1216
1217

1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268

1269
1270

1271
1272
1273

1274
1275
1276
1277
1278
1279
1280
1281
1282
 *      and errno is set accordingly.
 *
 *----------------------------------------------------------------------
 */

static int
TraversalDelete( 
    Tcl_DString *srcPtr,	/* Source pathname to delete. */
    Tcl_DString *dstPtr,	/* Not used. */

    int type,			/* Reason for call - see TraverseWinTree() */
    Tcl_DString *errorPtr)	/* If non-NULL, initialized DString filled
				 * with UTF-8 name of file causing error. */
{
    TCHAR *nativeSrc;

    switch (type) {
	case DOTREE_F: {
	    if (DoDeleteFile(srcPtr) == TCL_OK) {
		return TCL_OK;
	    }
	    break;
	}
	case DOTREE_PRED: {
	    return TCL_OK;
	}
	case DOTREE_POSTD: {
	    if (DoRemoveDirectory(srcPtr, 0, NULL) == TCL_OK) {
		return TCL_OK;
	    }
	    break;
	}
    }

    if (errorPtr != NULL) {
	nativeSrc = (TCHAR *) Tcl_DStringValue(srcPtr);
	Tcl_WinTCharToUtf(nativeSrc, -1, errorPtr);
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * StatError --
 *
 *	Sets the object result with the appropriate error.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      The interp's object result is set with an error message
 *	based on the objIndex, fileName and errno.
 *
 *----------------------------------------------------------------------
 */

static void
StatError(
    Tcl_Interp *interp,		/* The interp that has the error */

    CONST char *fileName)	/* The name of the file which caused the 
				 * error. */

{
    TclWinConvertError(GetLastError());
    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 

	    "could not read \"", fileName, "\": ", Tcl_PosixError(interp), 
	    (char *) NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * GetWinFileAttributes --
 *
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097


1098




1099
1100
1101
1102
1103
1104
1105
1106
1107
 *      A new object is allocated if the file is valid.
 *
 *----------------------------------------------------------------------
 */

static int
GetWinFileAttributes(
    Tcl_Interp *interp,		    /* The interp we are using for errors. */
    int objIndex,		    /* The index of the attribute. */
    char *fileName,		    /* The name of the file. */
    Tcl_Obj **attributePtrPtr)	    /* A pointer to return the object with. */
{
    DWORD result = GetFileAttributes(fileName);







    if (result == 0xFFFFFFFF) {
	AttributesPosixError(interp, objIndex, fileName, 0);
	return TCL_ERROR;
    }

    *attributePtrPtr = Tcl_NewBooleanObj(result & attributeArray[objIndex]);
    return TCL_OK;
}








|
|
|
|

|
>
>

>
>
>
>
|
|







1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
 *      A new object is allocated if the file is valid.
 *
 *----------------------------------------------------------------------
 */

static int
GetWinFileAttributes(
    Tcl_Interp *interp,		/* The interp we are using for errors. */
    int objIndex,		/* The index of the attribute. */
    CONST char *fileName,	/* The name of the file. */
    Tcl_Obj **attributePtrPtr)	/* A pointer to return the object with. */
{
    DWORD result;
    Tcl_DString ds;
    TCHAR *nativeName;

    nativeName = Tcl_WinUtfToTChar(fileName, -1, &ds);
    result = (*tclWinProcs->getFileAttributesProc)(nativeName);
    Tcl_DStringFree(&ds);

    if (result == 0xffffffff) {
	StatError(interp, fileName);
	return TCL_ERROR;
    }

    *attributePtrPtr = Tcl_NewBooleanObj(result & attributeArray[objIndex]);
    return TCL_OK;
}

1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151





1152
1153
1154
1155
1156
1157

1158
1159
1160


1161



1162
1163
1164









1165











1166
1167
1168
1169
1170
1171
1172


1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185


1186
1187
1188

1189
1190




1191




1192






1193



1194
1195
1196
1197
1198
1199
1200
1201
1202

1203
1204
1205
1206
1207
1208
1209

1210
1211
1212
1213
1214
1215
1216
 *      A new object is allocated if the file is valid.
 *
 *----------------------------------------------------------------------
 */

static int
ConvertFileNameFormat(
    Tcl_Interp *interp,		    /* The interp we are using for errors. */
    int objIndex,		    /* The index of the attribute. */
    char *fileName,		    /* The name of the file. */
    int longShort,		    /* 0 to short name, 1 to long name. */
    Tcl_Obj **attributePtrPtr)	    /* A pointer to return the object with. */
{
    HANDLE findHandle;
    WIN32_FIND_DATA findData;
    int pathArgc, i;
    char **pathArgv, **newPathArgv;
    char *currentElement, *resultStr;
    Tcl_DString resultDString;
    int result = TCL_OK;

    Tcl_SplitPath(fileName, &pathArgc, &pathArgv);
    newPathArgv = (char **) ckalloc(pathArgc * sizeof(char *));

    i = 0;
    if ((pathArgv[0][0] == '/') 
	    || ((strlen(pathArgv[0]) == 3) && (pathArgv[0][1] == ':'))) {
	newPathArgv[0] = (char *) ckalloc(strlen(pathArgv[0]) + 1);
	strcpy(newPathArgv[0], pathArgv[0]);
	i = 1;





    } 
    for ( ; i < pathArgc; i++) {
	if (strcmp(pathArgv[i], ".") == 0) {
	    currentElement = ckalloc(2);
	    strcpy(currentElement, ".");
	} else if (strcmp(pathArgv[i], "..") == 0) {

	    currentElement = ckalloc(3);
	    strcpy(currentElement, "..");
	} else {


	    int useLong;




	    Tcl_DStringInit(&resultDString);
	    resultStr = Tcl_JoinPath(i + 1, pathArgv, &resultDString);









	    findHandle = FindFirstFile(resultStr, &findData);











	    if (findHandle == INVALID_HANDLE_VALUE) {
		pathArgc = i - 1;
		AttributesPosixError(interp, objIndex, fileName, 0);
		result = TCL_ERROR;
		Tcl_DStringFree(&resultDString);
		goto cleanup;
	    }


	    if (longShort) {
		if (findData.cFileName[0] != '\0') {
		    useLong = 1;
		} else {
		    useLong = 0;
		}
	    } else {
		if (findData.cAlternateFileName[0] == '\0') {
		    useLong = 1;
		} else {
		    useLong = 0;
		}
	    }


	    if (useLong) {
		currentElement = ckalloc(strlen(findData.cFileName) + 1);
		strcpy(currentElement, findData.cFileName);

	    } else {
		currentElement = ckalloc(strlen(findData.cAlternateFileName) 




			+ 1);




		strcpy(currentElement, findData.cAlternateFileName);






	    }



	    Tcl_DStringFree(&resultDString);
	    FindClose(findHandle);
	}
	newPathArgv[i] = currentElement;
    }

    Tcl_DStringInit(&resultDString);
    resultStr = Tcl_JoinPath(pathArgc, newPathArgv, &resultDString);
    *attributePtrPtr = Tcl_NewStringObj(resultStr, Tcl_DStringLength(&resultDString));

    Tcl_DStringFree(&resultDString);

cleanup:
    for (i = 0; i < pathArgc; i++) {
	ckfree(newPathArgv[i]);
    }
    ckfree((char *) newPathArgv);

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * GetWinFileLongName --







|
|
|
|
|

<
<
|
|
|



|
|

|
|
|
<
|
|
>
>
>
>
>
|
<
<
|
<
<
>
|
|

>
>
|
>
>
>


|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
|
|

<


>
>
|
|
|
<
<
|
|
|
|
<
<
|
|
>
>
|
|
|
>
|
|
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
|
|

<



|
|
>



|
|

|
>







1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347


1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359

1360
1361
1362
1363
1364
1365
1366
1367


1368


1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406

1407
1408
1409
1410
1411
1412
1413


1414
1415
1416
1417


1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450

1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
 *      A new object is allocated if the file is valid.
 *
 *----------------------------------------------------------------------
 */

static int
ConvertFileNameFormat(
    Tcl_Interp *interp,		/* The interp we are using for errors. */
    int objIndex,		/* The index of the attribute. */
    CONST char *fileName,	/* The name of the file. */
    int longShort,		/* 0 to short name, 1 to long name. */
    Tcl_Obj **attributePtrPtr)	/* A pointer to return the object with. */
{


    int pathc, i;
    char **pathv, **newv;
    char *resultStr;
    Tcl_DString resultDString;
    int result = TCL_OK;

    Tcl_SplitPath(fileName, &pathc, &pathv);
    newv = (char **) ckalloc(pathc * sizeof(char *));

    for (i = 0; i < pathc; i++) {
	if ((pathv[i][0] == '/')
		|| ((strlen(pathv[i]) == 3) && (pathv[i][1] == ':'))

		|| (strcmp(pathv[i], ".") == 0)
		|| (strcmp(pathv[i], "..") == 0)) {
	    /*
	     * Handle "/", "//machine/export", "c:/", "." or ".." by just
	     * copying the string literally.  Uppercase the drive letter,
	     * just because it looks better under Windows to do so.
	     */



	    simple:


	    pathv[i][0] = (char) Tcl_UniCharToUpper(UCHAR(pathv[i][0]));
	    newv[i] = (char *) ckalloc(strlen(pathv[i]) + 1);
	    lstrcpyA(newv[i], pathv[i]);
	} else {
	    char *str;
	    TCHAR *nativeName;
	    Tcl_DString ds;
	    WIN32_FIND_DATAT data;
	    HANDLE handle;
	    DWORD attr;

	    Tcl_DStringInit(&resultDString);
	    str = Tcl_JoinPath(i + 1, pathv, &resultDString);
	    nativeName = Tcl_WinUtfToTChar(str, -1, &ds);
	    handle = (*tclWinProcs->findFirstFileProc)(nativeName, &data);
	    if (handle == INVALID_HANDLE_VALUE) {
		/*
		 * FindFirstFile() doesn't like root directories.  We 
		 * would only get a root directory here if the caller
		 * specified "c:" or "c:." and the current directory on the
		 * drive was the root directory
		 */

		attr = (*tclWinProcs->getFileAttributesProc)(nativeName);
		if ((attr != 0xFFFFFFFF) && (attr & FILE_ATTRIBUTE_DIRECTORY)) {
		    Tcl_DStringFree(&ds);
		    Tcl_DStringFree(&resultDString);

		    goto simple;
		}
	    }
	    Tcl_DStringFree(&ds);
	    Tcl_DStringFree(&resultDString);

	    if (handle == INVALID_HANDLE_VALUE) {
		pathc = i - 1;
		StatError(interp, fileName);
		result = TCL_ERROR;

		goto cleanup;
	    }
	    if (tclWinProcs->useWide) {
		nativeName = (TCHAR *) data.w.cAlternateFileName;
		if (longShort) {
		    if (data.w.cFileName[0] != '\0') {
			nativeName = (TCHAR *) data.w.cFileName;


		    } 
		} else {
		    if (data.w.cAlternateFileName[0] == '\0') {
			nativeName = (TCHAR *) data.w.cFileName;


		    }
		}
	    } else {
		nativeName = (TCHAR *) data.a.cAlternateFileName;
		if (longShort) {
		    if (data.a.cFileName[0] != '\0') {
			nativeName = (TCHAR *) data.a.cFileName;
		    } 
		} else {
		    if (data.a.cAlternateFileName[0] == '\0') {
			nativeName = (TCHAR *) data.a.cFileName;
		    }
		}
	    }

	    /*
	     * Purify reports a extraneous UMR in Tcl_WinTCharToUtf() trying 
	     * to dereference nativeName as a Unicode string.  I have proven 
	     * to myself that purify is wrong by running the following 
	     * example when nativeName == data.w.cAlternateFileName and 
	     * noting that purify doesn't complain about the first line,
	     * but does complain about the second.
	     *
	     *	fprintf(stderr, "%d\n", data.w.cAlternateFileName[0]);
	     *	fprintf(stderr, "%d\n", ((WCHAR *) nativeName)[0]);
	     */

	    Tcl_WinTCharToUtf(nativeName, -1, &ds);
	    newv[i] = ckalloc(Tcl_DStringLength(&ds) + 1);
	    lstrcpyA(newv[i], Tcl_DStringValue(&ds));
	    Tcl_DStringFree(&ds);
	    FindClose(handle);
	}

    }

    Tcl_DStringInit(&resultDString);
    resultStr = Tcl_JoinPath(pathc, newv, &resultDString);
    *attributePtrPtr = Tcl_NewStringObj(resultStr, 
	    Tcl_DStringLength(&resultDString));
    Tcl_DStringFree(&resultDString);

cleanup:
    for (i = 0; i < pathc; i++) {
	ckfree(newv[i]);
    }
    ckfree((char *) newv);
    ckfree((char *) pathv);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * GetWinFileLongName --
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
 *      A new object is allocated if the file is valid.
 *
 *----------------------------------------------------------------------
 */

static int
GetWinFileLongName(
    Tcl_Interp *interp,		    /* The interp we are using for errors. */
    int objIndex,		    /* The index of the attribute. */
    char *fileName,		    /* The name of the file. */
    Tcl_Obj **attributePtrPtr)	    /* A pointer to return the object with. */
{
    return ConvertFileNameFormat(interp, objIndex, fileName, 1, attributePtrPtr);
}

/*
 *----------------------------------------------------------------------
 *







|
|
|
|







1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
 *      A new object is allocated if the file is valid.
 *
 *----------------------------------------------------------------------
 */

static int
GetWinFileLongName(
    Tcl_Interp *interp,		/* The interp we are using for errors. */
    int objIndex,		/* The index of the attribute. */
    CONST char *fileName,	/* The name of the file. */
    Tcl_Obj **attributePtrPtr)	/* A pointer to return the object with. */
{
    return ConvertFileNameFormat(interp, objIndex, fileName, 1, attributePtrPtr);
}

/*
 *----------------------------------------------------------------------
 *
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
 *      A new object is allocated if the file is valid.
 *
 *----------------------------------------------------------------------
 */

static int
GetWinFileShortName(
    Tcl_Interp *interp,		    /* The interp we are using for errors. */
    int objIndex,		    /* The index of the attribute. */
    char *fileName,		    /* The name of the file. */
    Tcl_Obj **attributePtrPtr)	    /* A pointer to return the object with. */
{
    return ConvertFileNameFormat(interp, objIndex, fileName, 0, attributePtrPtr);
}

/*
 *----------------------------------------------------------------------
 *







|
|
|
|







1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
 *      A new object is allocated if the file is valid.
 *
 *----------------------------------------------------------------------
 */

static int
GetWinFileShortName(
    Tcl_Interp *interp,		/* The interp we are using for errors. */
    int objIndex,		/* The index of the attribute. */
    CONST char *fileName,	/* The name of the file. */
    Tcl_Obj **attributePtrPtr)	/* A pointer to return the object with. */
{
    return ConvertFileNameFormat(interp, objIndex, fileName, 0, attributePtrPtr);
}

/*
 *----------------------------------------------------------------------
 *
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297


1298



1299
1300
1301

1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317

1318




1319
1320
1321
1322
1323
1324
1325
1326
 *      The file's attribute is set.
 *
 *----------------------------------------------------------------------
 */

static int
SetWinFileAttributes(
    Tcl_Interp *interp,		    /* The interp we are using for errors. */
    int objIndex,		    /* The index of the attribute. */
    char *fileName,		    /* The name of the file. */
    Tcl_Obj *attributePtr)	    /* The new value of the attribute. */
{
    DWORD fileAttributes = GetFileAttributes(fileName);
    int yesNo;
    int result;






    if (fileAttributes == 0xFFFFFFFF) {
	AttributesPosixError(interp, objIndex, fileName, 1);
	return TCL_ERROR;

    }

    result = Tcl_GetBooleanFromObj(interp, attributePtr, &yesNo);
    if (result != TCL_OK) {
	return result;
    }

    if (yesNo) {
	fileAttributes |= (attributeArray[objIndex]);
    } else {
	fileAttributes &= ~(attributeArray[objIndex]);
    }

    if (!SetFileAttributes(fileName, fileAttributes)) {
	AttributesPosixError(interp, objIndex, fileName, 1);
	return TCL_ERROR;

    }




    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SetWinFileLongName --
 *







|
|
|
|

|


>
>

>
>
>
|
|
|
>




|








|
|
|
>

>
>
>
>
|







1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
 *      The file's attribute is set.
 *
 *----------------------------------------------------------------------
 */

static int
SetWinFileAttributes(
    Tcl_Interp *interp,		/* The interp we are using for errors. */
    int objIndex,		/* The index of the attribute. */
    CONST char *fileName,	/* The name of the file. */
    Tcl_Obj *attributePtr)	/* The new value of the attribute. */
{
    DWORD fileAttributes;
    int yesNo;
    int result;
    Tcl_DString ds;
    TCHAR *nativeName;

    nativeName = Tcl_WinUtfToTChar(fileName, -1, &ds);
    fileAttributes = (*tclWinProcs->getFileAttributesProc)(nativeName);

    if (fileAttributes == 0xffffffff) {
	StatError(interp, fileName);
	result = TCL_ERROR;
	goto end;
    }

    result = Tcl_GetBooleanFromObj(interp, attributePtr, &yesNo);
    if (result != TCL_OK) {
	goto end;
    }

    if (yesNo) {
	fileAttributes |= (attributeArray[objIndex]);
    } else {
	fileAttributes &= ~(attributeArray[objIndex]);
    }

    if (!(*tclWinProcs->setFileAttributesProc)(nativeName, fileAttributes)) {
	StatError(interp, fileName);
	result = TCL_ERROR;
	goto end;
    }

    end:
    Tcl_DStringFree(&ds);

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * SetWinFileLongName --
 *
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
 *      The object result is set to a pertinant error message.
 *
 *----------------------------------------------------------------------
 */

static int
CannotSetAttribute(
    Tcl_Interp *interp,		    /* The interp we are using for errors. */
    int objIndex,		    /* The index of the attribute. */
    char *fileName,		    /* The name of the file. */
    Tcl_Obj *attributePtr)	    /* The new value of the attribute. */
{
    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
	    "cannot set attribute \"", tclpFileAttrStrings[objIndex],
	    "\" for file \"", fileName, "\" : attribute is readonly", 
	    (char *) NULL);
    return TCL_ERROR;
}


/*
 *---------------------------------------------------------------------------







|
|
|
|



|







1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
 *      The object result is set to a pertinant error message.
 *
 *----------------------------------------------------------------------
 */

static int
CannotSetAttribute(
    Tcl_Interp *interp,		/* The interp we are using for errors. */
    int objIndex,		/* The index of the attribute. */
    CONST char *fileName,	/* The name of the file. */
    Tcl_Obj *attributePtr)	/* The new value of the attribute. */
{
    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
	    "cannot set attribute \"", tclpFileAttrStrings[objIndex],
	    "\" for file \"", fileName, "\": attribute is readonly", 
	    (char *) NULL);
    return TCL_ERROR;
}


/*
 *---------------------------------------------------------------------------
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378

1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391














1392
1393
1394
1395
1396







1397
1398
1399
1400
1401
 *	None
 *
 *---------------------------------------------------------------------------
 */

int
TclpListVolumes( 
    Tcl_Interp *interp)    /* Interpreter to which to pass the volume list */
{
    Tcl_Obj *resultPtr, *elemPtr;
    char buf[4];
    int i;


    resultPtr = Tcl_GetObjResult(interp);

    buf[1] = ':';
    buf[2] = '/';
    buf[3] = '\0';

    /*
     * On Win32s: 
     * GetLogicalDriveStrings() isn't implemented.
     * GetLogicalDrives() returns incorrect information.
     */















    for (i = 0; i < 26; i++) {
        buf[0] = (char) ('a' + i);
	if (GetVolumeInformation(buf, NULL, 0, NULL, NULL, NULL, NULL, 0)  
		|| (GetLastError() == ERROR_NOT_READY)) {
	    elemPtr = Tcl_NewStringObj(buf, -1);







	    Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
	}
    }
    return TCL_OK;	
}







|


|

>



<
<
<
<

|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
>
>
>
>
>
>
>





1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648




1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
 *	None
 *
 *---------------------------------------------------------------------------
 */

int
TclpListVolumes( 
    Tcl_Interp *interp)		/* Interpreter for returning volume list. */
{
    Tcl_Obj *resultPtr, *elemPtr;
    char buf[40 * 4];		/* There couldn't be more than 30 drives??? */
    int i;
    char *p;

    resultPtr = Tcl_GetObjResult(interp);





    /*
     * On Win32s:
     * GetLogicalDriveStrings() isn't implemented.
     * GetLogicalDrives() returns incorrect information.
     */

    if (GetLogicalDriveStringsA(sizeof(buf), buf) == 0) {
	/*
	 * GetVolumeInformation() will detects all drives, but causes
	 * chattering on empty floppy drives.  We only do this if 
	 * GetLogicalDriveStrings() didn't work.  It has also been reported
	 * that on some laptops it takes a while for GetVolumeInformation()
	 * to return when pinging an empty floppy drive, another reason to 
	 * try to avoid calling it.
	 */

	buf[1] = ':';
	buf[2] = '/';
	buf[3] = '\0';

	for (i = 0; i < 26; i++) {
	    buf[0] = (char) ('a' + i);
	    if (GetVolumeInformationA(buf, NULL, 0, NULL, NULL, NULL, NULL, 0)  
		    || (GetLastError() == ERROR_NOT_READY)) {
		elemPtr = Tcl_NewStringObj(buf, -1);
		Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
	    }
	}
    } else {
	for (p = buf; *p != '\0'; p += 4) {
	    p[2] = '/';
	    elemPtr = Tcl_NewStringObj(p, -1);
	    Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
	}
    }
    return TCL_OK;	
}

Changes to win/tclWinFile.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
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
/* 
 * tclWinFile.c --
 *
 *      This file contains temporary wrappers around UNIX file handling
 *      functions. These wrappers map the UNIX functions to Win32 HANDLE-style
 *      files, which can be manipulated through the Win32 console redirection
 *      interfaces.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclWinFile.c 1.45 97/10/29 19:08:35
 */

#include "tclWinInt.h"
#include <sys/stat.h>
#include <shlobj.h>


/*
 * The variable below caches the name of the current working directory
 * in order to avoid repeated calls to getcwd.  The string is malloc-ed.
 * NULL means the cache needs to be refreshed.
 */



static char *currentDir =  NULL;




/*
 *----------------------------------------------------------------------
 *
 * Tcl_FindExecutable --
 *
 *	This procedure computes the absolute path name of the current
 *	application, given its argv[0] value.
 *
 * Results:





 *	None.
 *
 * Side effects:
 *	The variable tclExecutableName gets filled in with the file
 *	name for the application, if we figured it out.  If we couldn't
 *	figure it out, Tcl_FindExecutable is set to NULL.
 *
 *----------------------------------------------------------------------
 */

void

Tcl_FindExecutable(argv0)
    char *argv0;		/* The value of the application's argv[0]. */

{
    Tcl_DString buffer;
    int length;


    Tcl_DStringInit(&buffer);



    if (tclExecutableName != NULL) {
	ckfree(tclExecutableName);
	tclExecutableName = NULL;
    }

    /*
     * Under Windows we ignore argv0, and return the path for the file used to
     * create this process.
     */

    Tcl_DStringSetLength(&buffer, MAX_PATH+1);
    length = GetModuleFileName(NULL, Tcl_DStringValue(&buffer), MAX_PATH+1);
    if (length > 0) {
	tclExecutableName = (char *) ckalloc((unsigned) (length + 1));
	strcpy(tclExecutableName, Tcl_DStringValue(&buffer));

    }
    Tcl_DStringFree(&buffer);


}

/*
 *----------------------------------------------------------------------
 *
 * TclMatchFiles --
 *
 *	This routine is used by the globbing code to search a
 *	directory for all files which match a given pattern.
 *
 * Results: 
 *	If the tail argument is NULL, then the matching files are
 *	added to the interp->result.  Otherwise, TclDoGlob is called
 *	recursively for each matching subdirectory.  The return value
 *	is a standard Tcl result indicating whether an error occurred
 *	in globbing.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------- */

int
TclMatchFiles(interp, separators, dirPtr, pattern, tail)
    Tcl_Interp *interp;		/* Interpreter to receive results. */
    char *separators;		/* Directory separators to pass to TclDoGlob. */
    Tcl_DString *dirPtr;	/* Contains path to directory to search. */
    char *pattern;		/* Pattern to match against. */
    char *tail;			/* Pointer to end of pattern.  Tail must
				 * point to a location in pattern. */

{
    char drivePattern[4] = "?:\\";
    char *newPattern, *p, *dir, *root, c;
    char *src, *dest;
    int length, matchDotFiles;
    int result = TCL_OK;
    int baseLength = Tcl_DStringLength(dirPtr);
    Tcl_DString buffer;
    DWORD atts, volFlags;
    HANDLE handle;
    WIN32_FIND_DATA data;
    BOOL found;



    /*
     * Convert the path to normalized form since some interfaces only
     * accept backslashes.  Also, ensure that the directory ends with a
     * separator character.
     */


    Tcl_DStringInit(&buffer);
    if (baseLength == 0) {
	Tcl_DStringAppend(&buffer, ".", 1);
    } else {


	Tcl_DStringAppend(&buffer, Tcl_DStringValue(dirPtr),
		Tcl_DStringLength(dirPtr));
    }
    for (p = Tcl_DStringValue(&buffer); *p != '\0'; p++) {
	if (*p == '/') {
	    *p = '\\';
	}
    }
    p--;
    if (*p != '\\' && *p != ':') {
	Tcl_DStringAppend(&buffer, "\\", 1);
    }

    dir = Tcl_DStringValue(&buffer);
    
    /*
     * First verify that the specified path is actually a directory.
     */


    atts = GetFileAttributes(dir);


    if ((atts == 0xFFFFFFFF) || ((atts & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
	Tcl_DStringFree(&buffer);
	return TCL_OK;
    }

    /*
     * Next check the volume information for the directory to see whether
     * comparisons should be case sensitive or not.  If the root is null, then
     * we use the root of the current directory.  If the root is just a drive
     * specifier, we use the root directory of the given drive.
     */

    switch (Tcl_GetPathType(dir)) {
	case TCL_PATH_RELATIVE:
	    found = GetVolumeInformation(NULL, NULL, 0, NULL,
		    NULL, &volFlags, NULL, 0);
	    break;
	case TCL_PATH_VOLUME_RELATIVE:
	    if (*dir == '\\') {
		root = NULL;
	    } else {
		root = drivePattern;
		*root = *dir;
	    }
	    found = GetVolumeInformation(root, NULL, 0, NULL,
		    NULL, &volFlags, NULL, 0);
	    break;
	case TCL_PATH_ABSOLUTE:
	    if (dir[1] == ':') {
		root = drivePattern;
		*root = *dir;
		found = GetVolumeInformation(root, NULL, 0, NULL,
			NULL, &volFlags, NULL, 0);
	    } else if (dir[1] == '\\') {


		p = strchr(dir+2, '\\');
		p = strchr(p+1, '\\');
		p++;
		c = *p;
		*p = 0;
		found = GetVolumeInformation(dir, NULL, 0, NULL,
			NULL, &volFlags, NULL, 0);
		*p = c;

	    }
	    break;
    }

    if (!found) {
	Tcl_DStringFree(&buffer);
	TclWinConvertError(GetLastError());
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "couldn't read volume information for \"",
		dirPtr->string, "\": ", Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }
    
    /*
     * In Windows, although some volumes may support case sensitivity, Windows
     * doesn't honor case.  So in globbing we need to ignore the case
     * of file names.
     */

    length = tail - pattern;
    newPattern = ckalloc(length+1);

    for (src = pattern, dest = newPattern; src < tail; src++, dest++) {
	*dest = (char) tolower(*src);
    }
    *dest = '\0';
    
    /*
     * We need to check all files in the directory, so append a *.*
     * to the path. 
     */


    dir = Tcl_DStringAppend(&buffer, "*.*", 3);

    /*
     * Now open the directory for reading and iterate over the contents.
     */

    handle = FindFirstFile(dir, &data);
    Tcl_DStringFree(&buffer);

    if (handle == INVALID_HANDLE_VALUE) {
	TclWinConvertError(GetLastError());
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "couldn't read directory \"",
		dirPtr->string, "\": ", Tcl_PosixError(interp), (char *) NULL);
	ckfree(newPattern);
	return TCL_ERROR;
    }

    /*
     * Clean up the tail pointer.  Leave the tail pointing to the 
     * first character after the path separator or NULL. 
     */









|




|





>

<
|
|
|
|

>
>
|
>
>



|

|





>
>
>
>
>
|


|

|

|


<
>
|
|
>

|
<
>

<
>
>
|
|
|
<







|
|
|
|
|
>
|
<
>
>





|






|










|





|
>

|
|
|
|
|
<
|
|

|

>
>







>
|
|
|

>
>
|

<
|
|
|
|
|
|
|
|
|
>
|
|




>
|
>
>
|
|












|
|


|


|
|

|
|



|
|
|
|

>
>
|
|

|
<
|
|
<
>




|
<
<
<
|
|
<

|






|
|
>
|
<

<
|





<
|
|
<
<
<
|
<
|


<
<
|
<
|
<







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
/* 
 * tclWinFile.c --
 *
 *      This file contains temporary wrappers around UNIX file handling
 *      functions. These wrappers map the UNIX functions to Win32 HANDLE-style
 *      files, which can be manipulated through the Win32 console redirection
 *      interfaces.
 *
 * Copyright (c) 1995-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: tclWinFile.c,v 1.1.2.6 1999/04/02 23:45:00 stanton Exp $
 */

#include "tclWinInt.h"
#include <sys/stat.h>
#include <shlobj.h>
#include <lmaccess.h>		/* For TclpGetUserHome(). */


static time_t		ToCTime(FILETIME fileTime);

typedef NET_API_STATUS NET_API_FUNCTION NETUSERGETINFOPROC
	(LPWSTR servername, LPWSTR username, DWORD level, LPBYTE *bufptr);

typedef NET_API_STATUS NET_API_FUNCTION NETAPIBUFFERFREEPROC
	(LPVOID Buffer);

typedef NET_API_STATUS NET_API_FUNCTION NETGETDCNAMEPROC
	(LPWSTR servername, LPWSTR domainname, LPBYTE *bufptr);


/*
 *---------------------------------------------------------------------------
 *
 * TclpFindExecutable --
 *
 *	This procedure computes the absolute path name of the current
 *	application, given its argv[0] value.
 *
 * Results:
 *	A dirty UTF string that is the path to the executable.  At this
 *	point we may not know the system encoding.  Convert the native
 *	string value to UTF using the default encoding.  The assumption
 *	is that we will still be able to parse the path given the path
 *	name contains ASCII string and '/' chars do not conflict with
 *	other UTF chars.
 *
 * Side effects:
 *	The variable tclNativeExecutableName gets filled in with the file
 *	name for the application, if we figured it out.  If we couldn't
 *	figure it out, tclNativeExecutableName is set to NULL.
 *
 *---------------------------------------------------------------------------
 */


char *
TclpFindExecutable(argv0)
    CONST char *argv0;		/* The value of the application's argv[0]
				 * (native). */
{
    Tcl_DString ds;

    WCHAR wName[MAX_PATH];


    if (argv0 == NULL) {
	return NULL;
    }
    if (tclNativeExecutableName != NULL) {
	return tclNativeExecutableName;

    }

    /*
     * Under Windows we ignore argv0, and return the path for the file used to
     * create this process.
     */

    (*tclWinProcs->getModuleFileNameProc)(NULL, wName, MAX_PATH);
    Tcl_WinTCharToUtf((TCHAR *) wName, -1, &ds);

    tclNativeExecutableName = ckalloc((unsigned) (Tcl_DStringLength(&ds) + 1));
    strcpy(tclNativeExecutableName, Tcl_DStringValue(&ds));
    Tcl_DStringFree(&ds);


    TclWinNoBackslash(tclNativeExecutableName);
    return tclNativeExecutableName;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpMatchFiles --
 *
 *	This routine is used by the globbing code to search a
 *	directory for all files which match a given pattern.
 *
 * Results: 
 *	If the tail argument is NULL, then the matching files are
 *	added to the the interp's result.  Otherwise, TclDoGlob is called
 *	recursively for each matching subdirectory.  The return value
 *	is a standard Tcl result indicating whether an error occurred
 *	in globbing.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------- */

int
TclpMatchFiles(interp, separators, dirPtr, pattern, tail)
    Tcl_Interp *interp;		/* Interpreter to receive results. */
    char *separators;		/* Directory separators to pass to TclDoGlob. */
    Tcl_DString *dirPtr;	/* Contains path to directory to search. */
    char *pattern;		/* Pattern to match against. */
    char *tail;			/* Pointer to end of pattern.  Tail must
				 * point to a location in pattern. Must not
				 * point to a static string. */
{
    char drivePat[] = "?:\\";
    const char *message;
    char *dir, *newPattern, *root;
    int matchDotFiles;
    int dirLength, result = TCL_OK;

    Tcl_DString dirString, patternString;
    DWORD attr, volFlags;
    HANDLE handle;
    WIN32_FIND_DATAT data;
    BOOL found;
    Tcl_DString ds;
    TCHAR *nativeName;

    /*
     * Convert the path to normalized form since some interfaces only
     * accept backslashes.  Also, ensure that the directory ends with a
     * separator character.
     */

    dirLength = Tcl_DStringLength(dirPtr);
    Tcl_DStringInit(&dirString);
    if (dirLength == 0) {
	Tcl_DStringAppend(&dirString, ".\\", 2);
    } else {
	char *p;

	Tcl_DStringAppend(&dirString, Tcl_DStringValue(dirPtr),
		Tcl_DStringLength(dirPtr));

	for (p = Tcl_DStringValue(&dirString); *p != '\0'; p++) {
	    if (*p == '/') {
		*p = '\\';
	    }
	}
	p--;
	if ((*p != '\\') && (*p != ':')) {
	    Tcl_DStringAppend(&dirString, "\\", 1);
	}
    }
    dir = Tcl_DStringValue(&dirString);

    /*
     * First verify that the specified path is actually a directory.
     */

    nativeName = Tcl_WinUtfToTChar(dir, Tcl_DStringLength(&dirString), &ds);
    attr = (*tclWinProcs->getFileAttributesProc)(nativeName);
    Tcl_DStringFree(&ds);

    if ((attr == 0xffffffff) || ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
	Tcl_DStringFree(&dirString);
	return TCL_OK;
    }

    /*
     * Next check the volume information for the directory to see whether
     * comparisons should be case sensitive or not.  If the root is null, then
     * we use the root of the current directory.  If the root is just a drive
     * specifier, we use the root directory of the given drive.
     */

    switch (Tcl_GetPathType(dir)) {
	case TCL_PATH_RELATIVE:
	    found = GetVolumeInformationA(NULL, NULL, 0, NULL, NULL, 
		    &volFlags, NULL, 0);
	    break;
	case TCL_PATH_VOLUME_RELATIVE:
	    if (dir[0] == '\\') {
		root = NULL;
	    } else {
		root = drivePat;
		*root = dir[0];
	    }
	    found = GetVolumeInformationA(root, NULL, 0, NULL, NULL, 
		    &volFlags, NULL, 0);
	    break;
	case TCL_PATH_ABSOLUTE:
	    if (dir[1] == ':') {
		root = drivePat;
		*root = dir[0];
		found = GetVolumeInformationA(root, NULL, 0, NULL, NULL, 
			&volFlags, NULL, 0);
	    } else if (dir[1] == '\\') {
		char *p;

		p = strchr(dir + 2, '\\');
		p = strchr(p + 1, '\\');
		p++;
		nativeName = Tcl_WinUtfToTChar(dir, p - dir, &ds);

		found = (*tclWinProcs->getVolumeInformationProc)(nativeName, 
			NULL, 0, NULL, NULL, &volFlags, NULL, 0);

		Tcl_DStringFree(&ds);
	    }
	    break;
    }

    if (found == 0) {



	message = "couldn't read volume information for \"";
	goto error;

    }

    /*
     * In Windows, although some volumes may support case sensitivity, Windows
     * doesn't honor case.  So in globbing we need to ignore the case
     * of file names.
     */

    Tcl_DStringInit(&patternString);
    newPattern = Tcl_DStringAppend(&patternString, pattern, tail - pattern);
    if ((volFlags & FS_CASE_SENSITIVE) == 0) {
	Tcl_UtfToLower(newPattern);

    }


    /*
     * We need to check all files in the directory, so append a *.*
     * to the path. 
     */


    dir = Tcl_DStringAppend(&dirString, "*.*", 3);
    nativeName = Tcl_WinUtfToTChar(dir, -1, &ds);



    handle = (*tclWinProcs->findFirstFileProc)(nativeName, &data);

    Tcl_DStringFree(&ds);

    if (handle == INVALID_HANDLE_VALUE) {


	message = "couldn't read directory \"";

	goto error;

    }

    /*
     * Clean up the tail pointer.  Leave the tail pointing to the 
     * first character after the path separator or NULL. 
     */

261
262
263
264
265
266
267
268
269


270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285


286
287
288

289
290
291
292
293
294
295
296
297



298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315


316
317
318


319


320
321
322
323
324
325
326
327

328
329

330

331

332



































































































































333
334
335
336
337
338
339
340

341
342


343







344








345





























































346
347
348
349
350
351
352
353
354
355
356
357
358
359
360


361

362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386


387
388
389
390
391
392
393
394
395
396
397
398


399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

419
420
421
422


423


424


425
426


427





428
429
430
431
432
433
434
435
436
437
438

439














































440
441




















































442









































































































443
444
445
446
447
448
449
        matchDotFiles = 0;
    }

    /*
     * Now iterate over all of the files in the directory.
     */

    Tcl_DStringInit(&buffer);
    for (found = 1; found; found = FindNextFile(handle, &data)) {


	char *matchResult;

	/*
	 * Ignore hidden files.
	 */

	if (!matchDotFiles && (data.cFileName[0] == '.')) {
	    continue;
	}


	/*
	 * Check to see if the file matches the pattern.  We need to convert
	 * the file name to lower case for comparison purposes.  Note that we
	 * are ignoring the case sensitivity flag because Windows doesn't honor
	 * case even if the volume is case sensitive.  If the volume also
	 * doesn't preserve case, then we return the lower case form of the


	 * name, otherwise we return the system form.
	 */


	matchResult = NULL;
	Tcl_DStringSetLength(&buffer, 0);
	Tcl_DStringAppend(&buffer, data.cFileName, -1);
	for (p = buffer.string; *p != '\0'; p++) {
	    *p = (char) tolower(*p);
	}
	if (Tcl_StringMatch(buffer.string, newPattern)) {
	    if (volFlags & FS_CASE_IS_PRESERVED) {
		matchResult = data.cFileName;



	    } else {
		matchResult = buffer.string;
	    }	
	}

	if (matchResult == NULL) {
	    continue;
	}

	/*
	 * If the file matches, then we need to process the remainder of the
	 * path.  If there are more characters to process, then ensure matching
	 * files are directories and call TclDoGlob. Otherwise, just add the
	 * file to the result.
	 */

	Tcl_DStringSetLength(dirPtr, baseLength);
	Tcl_DStringAppend(dirPtr, matchResult, -1);


	if (tail == NULL) {
	    Tcl_AppendElement(interp, dirPtr->string);
	} else {


	    atts = GetFileAttributes(dirPtr->string);


	    if (atts & FILE_ATTRIBUTE_DIRECTORY) {
		Tcl_DStringAppend(dirPtr, "/", 1);
		result = TclDoGlob(interp, separators, dirPtr, tail);
		if (result != TCL_OK) {
		    break;
		}
	    }
	}

    }


    Tcl_DStringFree(&buffer);

    FindClose(handle);

    ckfree(newPattern);



































































































































    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclChdir --
 *

 *	Change the current working directory.
 *


 * Results:







 *	The result is a standard Tcl result.  If an error occurs and 








 *	interp isn't NULL, an error message is left in interp->result.





























































 *
 * Side effects:
 *	The working directory for this application is changed.  Also
 *	the cache maintained used by TclGetCwd is deallocated and
 *	set to NULL.
 *
 *----------------------------------------------------------------------
 */

int
TclChdir(interp, dirName)
    Tcl_Interp *interp;		/* If non NULL, used for error reporting. */
    char *dirName;     		/* Path to new working directory. */
{
    if (currentDir != NULL) {


	ckfree(currentDir);

	currentDir = NULL;

    }
    if (!SetCurrentDirectory(dirName)) {
	TclWinConvertError(GetLastError());
	if (interp != NULL) {
	    Tcl_AppendResult(interp, "couldn't change working directory to \"",
		    dirName, "\": ", Tcl_PosixError(interp), (char *) NULL);
	}
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclGetCwd --
 *
 *	Return the path name of the current working directory.
 *
 * Results:
 *	The result is the full path name of the current working
 *	directory, or NULL if an error occurred while figuring it
 *	out.  If an error occurs and interp isn't NULL, an error
 *	message is left in interp->result.


 *
 * Side effects:
 *	The path name is cached to avoid having to recompute it
 *	on future calls;  if it is already cached, the cached
 *	value is returned.
 *
 *----------------------------------------------------------------------
 */

char *
TclGetCwd(interp)
    Tcl_Interp *interp;		/* If non NULL, used for error reporting. */


{
    static char buffer[MAXPATHLEN+1];
    char *bufPtr, *p;

    if (currentDir == NULL) {
	if (GetCurrentDirectory(MAXPATHLEN+1, buffer) == 0) {
	    TclWinConvertError(GetLastError());
	    if (interp != NULL) {
		if (errno == ERANGE) {
		    Tcl_SetResult(interp,
			    "working directory name is too long",
			    TCL_STATIC);
		} else {
		    Tcl_AppendResult(interp,
			    "error getting working directory name: ",
			    Tcl_PosixError(interp), (char *) NULL);
		}
	    }
	    return NULL;
	}

	/*
	 * Watch for the wierd Windows '95 c:\\UNC syntax.
	 */



	if (buffer[0] != '\0' && buffer[1] == ':' && buffer[2] == '\\'


		&& buffer[3] == '\\') {


	    bufPtr = &buffer[2];
	} else {


	    bufPtr = buffer;





	}

	/*
	 * Convert to forward slashes for easier use in scripts.
	 */

	for (p = bufPtr; *p != '\0'; p++) {
	    if (*p == '\\') {
		*p = '/';
	    }
	}

    }














































    return bufPtr;
}






























































































































































#if 0
/*
 *-------------------------------------------------------------------------
 *
 * TclWinResolveShortcut --
 *
 *	Resolve a potential Windows shortcut to get the actual file or 







<
|
>
>
|

<
|
|
|
|
<

>






|
>
>
|


>
|
<
<
<
<
|
<
<
|
>
>
>
|
|
|
<
|
|










|
|
>
>

|

>
>
|
>
>
|







>


>
|
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|

|

>
|
|
>
>

>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
<
<





|
<
|

|
>
>
|
>
|
>
|
|

<
<
<
<
|

|





|

|


|
|
|
|
>
>


<
<
|





|
|
>
>

|
|

<
|
|
|
<
<
<
<
<
|
|
|
|
<
|
|
>
|
|
|

>
>
|
>
>
|
>
>
|
|
>
>
|
>
>
>
>
>
|

|
|
|
|
|
|
|
|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







268
269
270
271
272
273
274

275
276
277
278
279

280
281
282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299




300


301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574


575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591
592




593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613


614
615
616
617
618
619
620
621
622
623
624
625
626
627

628
629
630





631
632
633
634

635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
        matchDotFiles = 0;
    }

    /*
     * Now iterate over all of the files in the directory.
     */


    for (found = 1; found != 0; 
	    found = (*tclWinProcs->findNextFileProc)(handle, &data)) {
	TCHAR *nativeMatchResult;
	char *name;


	if (tclWinProcs->useWide) {
	    nativeName = (TCHAR *) data.w.cFileName;
	} else {
	    nativeName = (TCHAR *) data.a.cFileName;

	}
	name = Tcl_WinTCharToUtf(nativeName, -1, &ds);

	/*
	 * Check to see if the file matches the pattern.  We need to convert
	 * the file name to lower case for comparison purposes.  Note that we
	 * are ignoring the case sensitivity flag because Windows doesn't honor
	 * case even if the volume is case sensitive.  If the volume also
	 * doesn't preserve case, then we previously returned the lower case
	 * form of the name.  This didn't seem quite right since there are
	 * non-case-preserving volumes that actually return mixed case.  So now
	 * we are returning exactly what we get from the system.
	 */

	Tcl_UtfToLower(name);
	nativeMatchResult = NULL;







	if ((matchDotFiles == 0) && (name[0] == '.')) {
	    /*
	     * Ignore hidden files.
	     */
	} else if (Tcl_StringMatch(name, newPattern) != 0) {
	    nativeMatchResult = nativeName;
	}

        Tcl_DStringFree(&ds);
	if (nativeMatchResult == NULL) {
	    continue;
	}

	/*
	 * If the file matches, then we need to process the remainder of the
	 * path.  If there are more characters to process, then ensure matching
	 * files are directories and call TclDoGlob. Otherwise, just add the
	 * file to the result.
	 */

	name = Tcl_WinTCharToUtf(nativeMatchResult, -1, &ds);
	Tcl_DStringAppend(dirPtr, name, -1);
	Tcl_DStringFree(&ds);

	if (tail == NULL) {
	    Tcl_AppendElement(interp, Tcl_DStringValue(dirPtr));
	} else {
	    nativeName = Tcl_WinUtfToTChar(Tcl_DStringValue(dirPtr), 
		    Tcl_DStringLength(dirPtr), &ds);
	    attr = (*tclWinProcs->getFileAttributesProc)(nativeName);
	    Tcl_DStringFree(&ds);

	    if (attr & FILE_ATTRIBUTE_DIRECTORY) {
		Tcl_DStringAppend(dirPtr, "/", 1);
		result = TclDoGlob(interp, separators, dirPtr, tail);
		if (result != TCL_OK) {
		    break;
		}
	    }
	}
	Tcl_DStringSetLength(dirPtr, dirLength);
    }

    FindClose(handle);
    Tcl_DStringFree(&dirString);
    Tcl_DStringFree(&patternString);

    return result;

    error:
    Tcl_DStringFree(&dirString);
    TclWinConvertError(GetLastError());
    Tcl_ResetResult(interp);
    Tcl_AppendResult(interp, message, Tcl_DStringValue(dirPtr), "\": ", 
	    Tcl_PosixError(interp), (char *) NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpGetUserHome --
 *
 *	This function takes the passed in user name and finds the
 *	corresponding home directory specified in the password file.
 *
 * Results:
 *	The result is a pointer to a string specifying the user's home
 *	directory, or NULL if the user's home directory could not be
 *	determined.  Storage for the result string is allocated in
 *	bufferPtr; the caller must call Tcl_DStringFree() when the result
 *	is no longer needed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpGetUserHome(name, bufferPtr)
    CONST char *name;		/* User name for desired home directory. */
    Tcl_DString *bufferPtr;	/* Uninitialized or free DString filled
				 * with name of user's home directory. */
{
    char *result;
    HINSTANCE netapiInst;

    result = NULL;

    Tcl_DStringInit(bufferPtr);

    netapiInst = LoadLibraryA("netapi32.dll");
    if (netapiInst != NULL) {
	NETAPIBUFFERFREEPROC *netApiBufferFreeProc;
	NETGETDCNAMEPROC *netGetDCNameProc;
	NETUSERGETINFOPROC *netUserGetInfoProc;

	netApiBufferFreeProc = (NETAPIBUFFERFREEPROC *)
		GetProcAddress(netapiInst, "NetApiBufferFree");
	netGetDCNameProc = (NETGETDCNAMEPROC *) 
		GetProcAddress(netapiInst, "NetGetDCName");
	netUserGetInfoProc = (NETUSERGETINFOPROC *) 
		GetProcAddress(netapiInst, "NetUserGetInfo");
	if ((netUserGetInfoProc != NULL) && (netGetDCNameProc != NULL)
		&& (netApiBufferFreeProc != NULL)) {
	    USER_INFO_1 *uiPtr;
	    Tcl_DString ds;
	    int nameLen, badDomain;
	    char *domain;
	    WCHAR *wName, *wHomeDir, *wDomain;
	    WCHAR buf[MAX_PATH];

	    badDomain = 0;
	    nameLen = -1;
	    wDomain = NULL;
	    domain = strchr(name, '@');
	    if (domain != NULL) {
		Tcl_DStringInit(&ds);
		wName = Tcl_UtfToUniCharDString(domain + 1, -1, &ds);
		badDomain = (*netGetDCNameProc)(NULL, wName,
			(LPBYTE *) &wDomain);
		Tcl_DStringFree(&ds);
		nameLen = domain - name;
	    }
	    if (badDomain == 0) {
		Tcl_DStringInit(&ds);
		wName = Tcl_UtfToUniCharDString(name, nameLen, &ds);
		if ((*netUserGetInfoProc)(wDomain, wName, 1, 
			(LPBYTE *) &uiPtr) == 0) {
		    wHomeDir = uiPtr->usri1_home_dir;
		    if ((wHomeDir != NULL) && (wHomeDir[0] != L'\0')) {
			Tcl_UniCharToUtfDString(wHomeDir, lstrlenW(wHomeDir),
				bufferPtr);
		    } else {
			/* 
			 * User exists but has no home dir.  Return
			 * "{Windows Drive}:/users/default".
			 */

			GetWindowsDirectoryW(buf, MAX_PATH);
			Tcl_UniCharToUtfDString(buf, 2, bufferPtr);
			Tcl_DStringAppend(bufferPtr, "/users/default", -1);
		    }
		    result = Tcl_DStringValue(bufferPtr);
		    (*netApiBufferFreeProc)((void *) uiPtr);
		}
		Tcl_DStringFree(&ds);
	    }
	    if (wDomain != NULL) {
		(*netApiBufferFreeProc)((void *) wDomain);
	    }
	}
	FreeLibrary(netapiInst);
    }
    if (result == NULL) {
	/*
	 * Look in the "Password Lists" section of system.ini for the 
	 * local user.  There are also entries in that section that begin 
	 * with a "*" character that are used by Windows for other 
	 * purposes; ignore user names beginning with a "*".
	 */

	char buf[MAX_PATH];

	if (name[0] != '*') {
	    if (GetPrivateProfileStringA("Password Lists", name, "", buf, 
		    MAX_PATH, "system.ini") > 0) {
		/* 
		 * User exists, but there is no such thing as a home 
		 * directory in system.ini.  Return "{Windows drive}:/".
		 */

		GetWindowsDirectoryA(buf, MAX_PATH);
		Tcl_DStringAppend(bufferPtr, buf, 3);
		result = Tcl_DStringValue(bufferPtr);
	    }
	}
    }

    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpAccess --
 *
 *	This function replaces the library version of access(), fixing the
 *	following bugs:
 * 
 *	1. access() returns that all files have execute permission.
 *
 * Results:
 *	See access documentation.
 *
 * Side effects:
 *	See access documentation.
 *
 *---------------------------------------------------------------------------
 */

int
TclpAccess(
    CONST char *path,		/* Path of file to access (UTF-8). */
    int mode)			/* Permission setting. */
{
    Tcl_DString ds;
    TCHAR *nativePath;
    DWORD attr;

    nativePath = Tcl_WinUtfToTChar(path, -1, &ds);
    attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
    Tcl_DStringFree(&ds);

    if (attr == 0xffffffff) {
	/*
	 * File doesn't exist. 
	 */

	TclWinConvertError(GetLastError());
	return -1;
    }

    if ((mode & W_OK) && (attr & FILE_ATTRIBUTE_READONLY)) {
	/*
	 * File is not writable.
	 */

	Tcl_SetErrno(EACCES);
	return -1;
    }

    if (mode & X_OK) {
        CONST char *p;

	if (attr & FILE_ATTRIBUTE_DIRECTORY) {
	    /*
	     * Directories are always executable. 
	     */
	    
	    return 0;
	}
	p = strrchr(path, '.');
	if (p != NULL) {
	    p++;
	    if ((stricmp(p, "exe") == 0)
		    || (stricmp(p, "com") == 0)
		    || (stricmp(p, "bat") == 0)) {
		/*
		 * File that ends with .exe, .com, or .bat is executable.
		 */

		return 0;
	    }
	}
	Tcl_SetErrno(EACCES);
	return -1;
    }

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpChdir --
 *
 *	This function replaces the library version of chdir().
 *
 * Results:
 *	See chdir() documentation.
 *
 * Side effects:
 *	See chdir() documentation.  


 *
 *----------------------------------------------------------------------
 */

int
TclpChdir(path)

    CONST char *path;     	/* Path to new working directory (UTF-8). */
{
    int result;
    Tcl_DString ds;
    TCHAR *nativePath;

    nativePath = Tcl_WinUtfToTChar(path, -1, &ds);
    result = (*tclWinProcs->setCurrentDirectoryProc)(nativePath);
    Tcl_DStringFree(&ds);

    if (result == 0) {
	TclWinConvertError(GetLastError());




	return -1;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpGetCwd --
 *
 *	This function replaces the library version of getcwd().
 *
 * Results:
 *	The result is a pointer to a string specifying the current
 *	directory, or NULL if the current directory could not be
 *	determined.  If NULL is returned, an error message is left in the
 *	interp's result.  Storage for the result string is allocated in
 *	bufferPtr; the caller must call Tcl_DStringFree() when the result
 *	is no longer needed.
 *
 * Side effects:


 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpGetCwd(interp, bufferPtr)
    Tcl_Interp *interp;		/* If non-NULL, used for error reporting. */
    Tcl_DString *bufferPtr;	/* Uninitialized or free DString filled
				 * with name of current directory. */
{
    WCHAR buffer[MAX_PATH];
    char *p;


    if ((*tclWinProcs->getCurrentDirectoryProc)(MAX_PATH, buffer) == 0) {
	TclWinConvertError(GetLastError());
	if (interp != NULL) {





	    Tcl_AppendResult(interp,
		    "error getting working directory name: ",
		    Tcl_PosixError(interp), (char *) NULL);
	}

	return NULL;
    }

    /*
     * Watch for the wierd Windows c:\\UNC syntax.
     */

    if (tclWinProcs->useWide) {
	WCHAR *native;

	native = (WCHAR *) buffer;
	if ((native[0] != '\0') && (native[1] == ':') 
		&& (native[2] == '\\') && (native[3] == '\\')) {
	    native += 2;
	}
	Tcl_WinTCharToUtf((TCHAR *) native, -1, bufferPtr);
    } else {
	char *native;

	native = (char *) buffer;
	if ((native[0] != '\0') && (native[1] == ':') 
		&& (native[2] == '\\') && (native[3] == '\\')) {
	    native += 2;
	}
	Tcl_WinTCharToUtf((TCHAR *) native, -1, bufferPtr);
    }

    /*
     * Convert to forward slashes for easier use in scripts.
     */
	      
    for (p = Tcl_DStringValue(bufferPtr); *p != '\0'; p++) {
	if (*p == '\\') {
	    *p = '/';
	}
    }
    return Tcl_DStringValue(bufferPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpStat --
 *
 *	This function replaces the library version of stat(), fixing 
 *	the following bugs:
 *
 *	1. stat("c:") returns an error.
 *	2. Borland stat() return time in GMT instead of localtime.
 *	3. stat("\\server\mount") would return error.
 *	4. Accepts slashes or backslashes.
 *	5. st_dev and st_rdev were wrong for UNC paths.
 *
 * Results:
 *	See stat documentation.
 *
 * Side effects:
 *	See stat documentation.
 *
 *----------------------------------------------------------------------
 */

int
TclpStat(path, statPtr)
    CONST char *path;		/* Path of file to stat (UTF-8). */
    struct stat *statPtr;	/* Filled with results of stat call. */
{
    Tcl_DString ds;
    TCHAR *nativePath;
    WIN32_FIND_DATAT data;
    HANDLE handle;
    DWORD attr;
    WCHAR nativeFullPath[MAX_PATH];
    TCHAR *nativePart;
    char *p, *fullPath;
    int dev, mode;

    /*
     * Eliminate file names containing wildcard characters, or subsequent 
     * call to FindFirstFile() will expand them, matching some other file.
     */

    if (strpbrk(path, "?*") != NULL) {
	Tcl_SetErrno(ENOENT);
	return -1;
    }

    nativePath = Tcl_WinUtfToTChar(path, -1, &ds);
    handle = (*tclWinProcs->findFirstFileProc)(nativePath, &data);
    if (handle == INVALID_HANDLE_VALUE) {
	/* 
	 * FindFirstFile() doesn't work on root directories, so call
	 * GetFileAttributes() to see if the specified file exists.
	 */

	attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
	if (attr == 0xffffffff) {
	    Tcl_DStringFree(&ds);
	    Tcl_SetErrno(ENOENT);
	    return -1;
	}

	/* 
	 * Make up some fake information for this file.  It has the 
	 * correct file attributes and a time of 0.
	 */

	memset(&data, 0, sizeof(data));
	data.a.dwFileAttributes = attr;
    } else {
	FindClose(handle);
    }

    (*tclWinProcs->getFullPathNameProc)(nativePath, MAX_PATH, nativeFullPath,
	    &nativePart);

    Tcl_DStringFree(&ds);
    fullPath = Tcl_WinTCharToUtf((TCHAR *) nativeFullPath, -1, &ds);

    dev = -1;
    if ((fullPath[0] == '\\') && (fullPath[1] == '\\')) {
	char *p;
	DWORD dw;
	TCHAR *nativeVol;
	Tcl_DString volString;

	p = strchr(fullPath + 2, '\\');
	p = strchr(p + 1, '\\');
	if (p == NULL) {
	    /*
	     * Add terminating backslash to fullpath or 
	     * GetVolumeInformation() won't work.
	     */

	    fullPath = Tcl_DStringAppend(&ds, "\\", 1);
	    p = fullPath + Tcl_DStringLength(&ds);
	} else {
	    p++;
	}
	nativeVol = Tcl_WinUtfToTChar(fullPath, p - fullPath, &volString);
	dw = (DWORD) -1;
	(*tclWinProcs->getVolumeInformationProc)(nativeVol, NULL, 0, &dw,
		NULL, NULL, NULL, 0);
	/*
	 * GetFullPathName() turns special devices like "NUL" into "\\.\NUL", 
	 * but GetVolumeInformation() returns failure for "\\.\NUL".  This 
	 * will cause "NUL" to get a drive number of -1, which makes about 
	 * as much sense as anything since the special devices don't live on 
	 * any drive.
	 */

	dev = dw;
	Tcl_DStringFree(&volString);
    } else if ((fullPath[0] != '\0') && (fullPath[1] == ':')) {
	dev = Tcl_UniCharToLower(fullPath[0]) - 'a';
    }
    Tcl_DStringFree(&ds);

    attr = data.a.dwFileAttributes;
    mode  = (attr & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR | S_IEXEC : S_IFREG;
    mode |= (attr & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE;
    p = strrchr(path, '.');
    if (p != NULL) {
	if ((lstrcmpiA(p, ".exe") == 0) 
		|| (lstrcmpiA(p, ".com") == 0) 
		|| (lstrcmpiA(p, ".bat") == 0)
		|| (lstrcmpiA(p, ".pif") == 0)) {
	    mode |= S_IEXEC;
	}
    }

    /*
     * Propagate the S_IREAD, S_IWRITE, S_IEXEC bits to the group and 
     * other positions.
     */

    mode |= (mode & 0x0700) >> 3;
    mode |= (mode & 0x0700) >> 6;
    
    statPtr->st_dev	= (dev_t) dev;
    statPtr->st_ino	= 0;
    statPtr->st_mode	= (unsigned short) mode;
    statPtr->st_nlink	= 1;
    statPtr->st_uid	= 0;
    statPtr->st_gid	= 0;
    statPtr->st_rdev	= (dev_t) dev;
    statPtr->st_size	= data.a.nFileSizeLow;
    statPtr->st_atime	= ToCTime(data.a.ftLastAccessTime);
    statPtr->st_mtime	= ToCTime(data.a.ftLastWriteTime);
    statPtr->st_ctime	= ToCTime(data.a.ftCreationTime);
    return 0;
}

static time_t
ToCTime(
    FILETIME fileTime)		/* UTC Time to convert to local time_t. */
{
    FILETIME localFileTime;
    SYSTEMTIME systemTime;
    struct tm tm;

    if (FileTimeToLocalFileTime(&fileTime, &localFileTime) == 0) {
	return 0;
    }
    if (FileTimeToSystemTime(&localFileTime, &systemTime) == 0) {
	return 0;
    }
    tm.tm_sec = systemTime.wSecond;
    tm.tm_min = systemTime.wMinute;
    tm.tm_hour = systemTime.wHour;
    tm.tm_mday = systemTime.wDay;
    tm.tm_mon = systemTime.wMonth - 1;
    tm.tm_year = systemTime.wYear - 1900;
    tm.tm_wday = 0;
    tm.tm_yday = 0;
    tm.tm_isdst = -1;

    return mktime(&tm);
}

#if 0

    /*
     * Borland's stat doesn't take into account localtime.
     */

    if ((result == 0) && (buf->st_mtime != 0)) {
	TIME_ZONE_INFORMATION tz;
	int time, bias;

	time = GetTimeZoneInformation(&tz);
	bias = tz.Bias;
	if (time == TIME_ZONE_ID_DAYLIGHT) {
	    bias += tz.DaylightBias;
	}
	bias *= 60;
	buf->st_atime -= bias;
	buf->st_ctime -= bias;
	buf->st_mtime -= bias;
    }

#endif


#if 0
/*
 *-------------------------------------------------------------------------
 *
 * TclWinResolveShortcut --
 *
 *	Resolve a potential Windows shortcut to get the actual file or 
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
	Tcl_DStringSetLength(bufferPtr, 0);
	Tcl_DStringAppend(bufferPtr, realFileName, -1);
	return 1;
    }
    return 0;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * TclWinStat, TclWinLstat --
 *
 *	These functions replace the library versions of stat and lstat.
 *
 *	The stat and lstat functions provided by some Windows compilers 
 *	are incomplete.  Ideally, a complete rewrite of stat would go
 *	here; now, the only fix is that stat("c:") used to return an
 *	error instead infor for current dir on specified drive.
 *
 * Results:
 *	See stat documentation.
 *
 * Side effects:
 *	See stat documentation.
 *
 *----------------------------------------------------------------------
 */

int
TclWinStat(path, buf)
    CONST char *path;		/* Path of file to stat (in current CP). */
    struct stat *buf;		/* Filled with results of stat call. */
{
    char name[4];
    int result;

    if ((strlen(path) == 2) && (path[1] == ':')) {
	strcpy(name, path);
	name[2] = '.';
	name[3] = '\0';
	path = name;
    }

#undef stat

    result = stat(path, buf);

#ifndef _MSC_VER

    /*
     * Borland's stat doesn't take into account localtime.
     */

    if ((result == 0) && (buf->st_mtime != 0)) {
	TIME_ZONE_INFORMATION tz;
	int time, bias;

	time = GetTimeZoneInformation(&tz);
	bias = tz.Bias;
	if (time == TIME_ZONE_ID_DAYLIGHT) {
	    bias += tz.DaylightBias;
	}
	bias *= 60;
	buf->st_atime -= bias;
	buf->st_ctime -= bias;
	buf->st_mtime -= bias;
    }

#endif

    return result;
}

/*
 *---------------------------------------------------------------------------
 *
 * TclWinAccess --
 *
 *	This function replaces the library version of access.
 *
 *	The library version of access returns that all files have execute
 *	permission.
 *
 * Results:
 *	See access documentation.
 *
 * Side effects:
 *	See access documentation.
 *
 *---------------------------------------------------------------------------
 */

int
TclWinAccess(
    CONST char *path,		/* Path of file to access (in current CP). */
    int mode)			/* Permission setting. */
{
    int result;
    CONST char *p;

#undef access

    result = access(path, mode);

    if (result == 0) {
	if (mode & 1) {
	    if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) {
		/*
		 * Directories are always executable. 
		 */

		return 0;
	    }
	    p = strrchr(path, '.');
	    if (p != NULL) {
		p++;
		if ((stricmp(p, "exe") == 0)
			|| (stricmp(p, "com") == 0)
			|| (stricmp(p, "bat") == 0)) {
		    /*
		     * File that ends with .exe, .com, or .bat is executable.
		     */

		    return 0;
		}
	    }
	    errno = EACCES;
	    return -1;
	}
    }
    return result;
}








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
950
951
952
953
954
955
956































































































































	Tcl_DStringSetLength(bufferPtr, 0);
	Tcl_DStringAppend(bufferPtr, realFileName, -1);
	return 1;
    }
    return 0;
}
#endif































































































































Changes to win/tclWinInit.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
/* 
 * tclWinInit.c --
 *
 *	Contains the Windows-specific interpreter initialization functions.
 *
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.

 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclWinInit.c 1.32 97/06/24 17:28:26
 */

#include "tclInt.h"
#include "tclPort.h"
#include <winreg.h>
#include <winnt.h>
#include <winbase.h>










/*
 * The following declaration is a workaround for some Microsoft brain damage.
 * The SYSTEM_INFO structure is different in various releases, even though the
 * layout is the same.  So we overlay our own structure on top of it so we
 * can access the interesting slots in a uniform way.
 */






|
>




|


|
<




>
>
>
>
>
>
>
>
>







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
/* 
 * tclWinInit.c --
 *
 *	Contains the Windows-specific interpreter initialization functions.
 *
 * Copyright (c) 1994-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: tclWinInit.c,v 1.1.2.9 1999/04/06 19:06:57 surles Exp $
 */

#include "tclWinInt.h"

#include <winreg.h>
#include <winnt.h>
#include <winbase.h>

/*
 * The following macro can be defined at compile time to specify
 * the root of the Tcl registry keys.
 */
 
#ifndef TCL_REGISTRY_KEY
#define TCL_REGISTRY_KEY "Software\\Scriptics\\Tcl\\" TCL_VERSION
#endif

/*
 * The following declaration is a workaround for some Microsoft brain damage.
 * The SYSTEM_INFO structure is different in various releases, even though the
 * layout is the same.  So we overlay our own structure on top of it so we
 * can access the interesting slots in a uniform way.
 */

62
63
64
65
66
67
68


69

70




71

72




































































































































































































































































































































73








74
75



76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124



125
126

127
128
129
130

131
132
133
134
135
136
137
138
139
140
141


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256












257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280







281
282




















































































283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338

#define NUMPROCESSORS 4
static char* processors[NUMPROCESSORS] = {
    "intel", "mips", "alpha", "ppc"
};

/*


 * The following string is the startup script executed in new

 * interpreters.  It looks on disk in several different directories




 * for a script "init.tcl" that is compatible with this version

 * of Tcl.  The init.tcl script does all of the real work of




































































































































































































































































































































 * initialization.








 */




static char *initScript =
"proc init {} {\n\

    global tcl_library tcl_platform tcl_version tcl_patchLevel env errorInfo\n\
    global tcl_pkgPath\n\
    rename init {}\n\
    set errors {}\n\
    proc tcl_envTraceProc {lo n1 n2 op} {\n\
	global env\n\
	set x $env($n2)\n\
	set env($lo) $x\n\
	set env([string toupper $lo]) $x\n\
    }\n\
    foreach p [array names env] {\n\
	set u [string toupper $p]\n\
	if {$u != $p} {\n\
	    switch -- $u {\n\
		COMSPEC -\n\
		PATH {\n\
		    if {![info exists env($u)]} {\n\
			set env($u) $env($p)\n\
		    }\n\
		    trace variable env($p) w [list tcl_envTraceProc $p]\n\
		    trace variable env($u) w [list tcl_envTraceProc $p]\n\
		}\n\
	    }\n\
	}\n\
    }\n\
    if {![info exists env(COMSPEC)]} {\n\
	if {$tcl_platform(os) == {Windows NT}} {\n\
	    set env(COMSPEC) cmd.exe\n\
	} else {\n\
	    set env(COMSPEC) command.com\n\
	}\n\
    }	\n\
    set dirs {}\n\
    if {[info exists env(TCL_LIBRARY)]} {\n\
	lappend dirs $env(TCL_LIBRARY)\n\
    }\n\
    lappend dirs $tcl_library\n\
    lappend dirs [file join [file dirname [file dirname [info nameofexecutable]]] lib/tcl$tcl_version]\n\
    if [string match {*[ab]*} $tcl_patchLevel] {\n\
	set lib tcl$tcl_patchLevel\n\

    } else {\n\
	set lib tcl$tcl_version\n\
    }\n\
    lappend dirs [file join [file dirname [file dirname [pwd]]] $lib/library]\n\
    lappend dirs [file join [file dirname [pwd]] library]\n\
    foreach i $dirs {\n\
	set tcl_library $i\n\



	set tclfile [file join $i init.tcl]\n\
	if {[file exists $tclfile]} {\n\

            lappend tcl_pkgPath [file dirname $i]\n\
	    if ![catch {uplevel #0 [list source $tclfile]} msg] {\n\
	        return\n\
	    } else {\n\

		append errors \"$tclfile: $msg\n$errorInfo\n\"\n\
	    }\n\
	}\n\
    }\n\
    set msg \"Can't find a usable init.tcl in the following directories: \n\"\n\
    append msg \"    $dirs\n\n\"\n\
    append msg \"$errors\n\n\"\n\
    append msg \"This probably means that Tcl wasn't installed properly.\n\"\n\
    error $msg\n\
}\n\
init\n";



/*
 *----------------------------------------------------------------------
 *
 * TclPlatformInit --
 *
 *	Performs Windows-specific interpreter initialization related to the
 *	tcl_library variable.  Also sets up the HOME environment variable
 *	if it is not already set.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets "tcl_library" and "env(HOME)" Tcl variables
 *
 *----------------------------------------------------------------------
 */

void
TclPlatformInit(interp)
    Tcl_Interp *interp;
{
    char *ptr;
    char buffer[13];
    Tcl_DString ds;
    OSVERSIONINFO osInfo;
    SYSTEM_INFO sysInfo;
    int isWin32s;		/* True if we are running under Win32s. */
    OemId *oemId;
    HKEY key;
    DWORD size;

    tclPlatform = TCL_PLATFORM_WINDOWS;

    Tcl_DStringInit(&ds);

    /*
     * Find out what kind of system we are running on.
     */

    osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&osInfo);

    isWin32s = (osInfo.dwPlatformId == VER_PLATFORM_WIN32s);

    /*
     * Since Win32s doesn't support GetSystemInfo, we use a default value.
     */

    oemId = (OemId *) &sysInfo;
    if (!isWin32s) {
	GetSystemInfo(&sysInfo);
    } else {
	oemId->wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
    }

    /*
     * Initialize the tcl_library variable from the registry.

     */

    if (!isWin32s) {
	if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE,
		"Software\\Sun\\Tcl\\" TCL_VERSION, 0, KEY_READ, &key)
		== ERROR_SUCCESS)
		&& (RegQueryValueEx(key, "Root", NULL, NULL, NULL, &size)
		    == ERROR_SUCCESS)) {
	    Tcl_DStringSetLength(&ds, size);
	    RegQueryValueEx(key, "Root", NULL, NULL,
		    (LPBYTE)Tcl_DStringValue(&ds), &size);
	}
    } else {
	if ((RegOpenKeyEx(HKEY_CLASSES_ROOT,
		"Software\\Sun\\Tcl\\" TCL_VERSION, 0, KEY_READ, &key)
		== ERROR_SUCCESS)
		&& (RegQueryValueEx(key, "", NULL, NULL, NULL, &size)
		    == ERROR_SUCCESS)) {
	    Tcl_DStringSetLength(&ds, size);
	    RegQueryValueEx(key, "", NULL, NULL,
		    (LPBYTE) Tcl_DStringValue(&ds), &size);
	}
    }
    Tcl_SetVar(interp, "tcl_library", Tcl_DStringValue(&ds), TCL_GLOBAL_ONLY);
    if (Tcl_DStringLength(&ds) > 0) {
	char *argv[3];
	argv[0] = Tcl_GetVar(interp, "tcl_library", TCL_GLOBAL_ONLY);
	argv[1] = "lib";
	argv[2] = NULL;
	Tcl_DStringSetLength(&ds, 0);
	Tcl_SetVar(interp, "tcl_pkgPath", Tcl_JoinPath(2, argv, &ds),
		TCL_GLOBAL_ONLY|TCL_LIST_ELEMENT);
	argv[1] = "lib/tcl" TCL_VERSION;
	Tcl_DStringSetLength(&ds, 0);
	Tcl_SetVar(interp, "tcl_library", Tcl_JoinPath(2, argv, &ds), 
		TCL_GLOBAL_ONLY);

    }

    /*
     * Define the tcl_platform array.
     */

    Tcl_SetVar2(interp, "tcl_platform", "platform", "windows",
	    TCL_GLOBAL_ONLY);
    if (osInfo.dwPlatformId < NUMPLATFORMS) {
	Tcl_SetVar2(interp, "tcl_platform", "os",
		platforms[osInfo.dwPlatformId], TCL_GLOBAL_ONLY);
    }
    sprintf(buffer, "%d.%d", osInfo.dwMajorVersion, osInfo.dwMinorVersion);
    Tcl_SetVar2(interp, "tcl_platform", "osVersion", buffer, TCL_GLOBAL_ONLY);
    if (oemId->wProcessorArchitecture < NUMPROCESSORS) {
	Tcl_SetVar2(interp, "tcl_platform", "machine",
		processors[oemId->wProcessorArchitecture],
		TCL_GLOBAL_ONLY);
    }













    /*
     * Set up the HOME environment variable from the HOMEDRIVE & HOMEPATH
     * environment variables, if necessary.
     */


    ptr = Tcl_GetVar2(interp, "env", "HOME", TCL_GLOBAL_ONLY);
    if (ptr == NULL) {
	Tcl_DStringSetLength(&ds, 0);
	ptr = Tcl_GetVar2(interp, "env", "HOMEDRIVE", TCL_GLOBAL_ONLY);
	if (ptr != NULL) {
	    Tcl_DStringAppend(&ds, ptr, -1);
	}
	ptr = Tcl_GetVar2(interp, "env", "HOMEPATH", TCL_GLOBAL_ONLY);
	if (ptr != NULL) {
	    Tcl_DStringAppend(&ds, ptr, -1);
	}
	if (Tcl_DStringLength(&ds) > 0) {
	    Tcl_SetVar2(interp, "env", "HOME", Tcl_DStringValue(&ds),
		    TCL_GLOBAL_ONLY);
	} else {
	    Tcl_SetVar2(interp, "env", "HOME", "c:\\", TCL_GLOBAL_ONLY);
	}
    }








    Tcl_DStringFree(&ds);
}





















































































/*
 *----------------------------------------------------------------------
 *
 * Tcl_Init --
 *
 *	This procedure is typically invoked by Tcl_AppInit procedures
 *	to perform additional initialization for a Tcl interpreter,
 *	such as sourcing the "init.tcl" script.
 *
 * Results:
 *	Returns a standard Tcl completion code and sets interp->result
 *	if there is an error.
 *
 * Side effects:
 *	Depends on what's in the init.tcl script.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Init(interp)
    Tcl_Interp *interp;		/* Interpreter to initialize. */
{
    return Tcl_Eval(interp, initScript);




}

/*
 *----------------------------------------------------------------------
 *
 * TclWinGetPlatform --
 *
 *	This is a kludge that allows the test library to get access
 *	the internal tclPlatform variable.
 *
 * Results:
 *	Returns a pointer to the tclPlatform variable.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TclPlatformType *
TclWinGetPlatform()
{

    return &tclPlatform;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SourceRCFile --
 *







>
>
|
>
|
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>


>
>
>
|
<
>
|
|
|
<
<
<
|
|
|
|
|
|
|
|
|
<
|
|
<
<
<
<
<
<
<
<
|
<
<
<
<
|
|
|
|
|
|
<
|
|
>
|
|
|
<
<
<
|
>
>
>
|
<
>
|
<
<
|
>
|
<
<
<
<
<
<
<
<
<
|
>
>


|

|

|
|
|





|





|
|
|

|
<
<

<

<
<
|
<
<
|

<
<
<
<
|
|
<
<
<
<
<
<


<
<
<
<
<
|
|
<
>
|

<
<
<
|
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>












|







>
>
>
>
>
>
>
>
>
>
>
>





>


<
















>
>
>
>
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|
|











|

>
>
>
|
|
<
<
|
|
<
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
>
|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428

429
430
431
432



433
434
435
436
437
438
439
440
441

442
443








444




445
446
447
448
449
450

451
452
453
454
455
456



457
458
459
460
461

462
463


464
465
466









467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494


495

496


497


498
499




500
501






502
503





504
505

506
507
508



509






510























511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551

552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691


692
693

694
695









696



697
698
699
700
701
702
703
704
705

#define NUMPROCESSORS 4
static char* processors[NUMPROCESSORS] = {
    "intel", "mips", "alpha", "ppc"
};

/*
 * Thread id used for asynchronous notification from signal handlers.
 */

static DWORD mainThreadId;

/*
 * The Init script (common to Windows and Unix platforms) is
 * defined in tkInitScript.h
 */

#include "tclInitScript.h"

static void		AppendEnvironment(Tcl_Obj *listPtr, CONST char *lib);
static void		AppendDllPath(Tcl_Obj *listPtr, HMODULE hModule,
			    CONST char *lib);
static void		AppendRegistry(Tcl_Obj *listPtr, CONST char *lib);
static int		ToUtf(CONST WCHAR *wSrc, char *dst);

/*
 *---------------------------------------------------------------------------
 *
 * TclpInitPlatform --
 *
 *	Initialize all the platform-dependant things like signals and
 *	floating-point error handling.
 *
 *	Called at process initialization time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TclpInitPlatform()
{
    tclPlatform = TCL_PLATFORM_WINDOWS;

    /*
     * The following code stops Windows 3.X and Windows NT 3.51 from 
     * automatically putting up Sharing Violation dialogs, e.g, when 
     * someone tries to access a file that is locked or a drive with no 
     * disk in it.  Tcl already returns the appropriate error to the 
     * caller, and they can decide to put up their own dialog in response 
     * to that failure.  
     *
     * Under 95 and NT 4.0, this is a NOOP because the system doesn't 
     * automatically put up dialogs when the above operations fail.
     */

    SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS);

    /*
     * Save the id of the first thread to intialize the Tcl library.  This
     * thread will be used to handle notifications from async event
     * procedures.  This is not strictly correct.  A better solution involves
     * using a designated "main" notifier that is kept up to date as threads
     * come and go.
     */

    mainThreadId = GetCurrentThreadId();
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpInitLibraryPath --
 *
 *	Initialize the library path at startup.  
 *
 *	This call sets the library path to strings in UTF-8. Any 
 *	pre-existing library path information is assumed to have been 
 *	in the native multibyte encoding.
 *
 *	Called at process initialization time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

void
TclpInitLibraryPath(path)
    CONST char *path;		/* Potentially dirty UTF string that is */
				/* the path to the executable name.     */
{
#define LIBRARY_SIZE	    32
    Tcl_Obj *pathPtr, *objPtr;
    char *str;
    Tcl_DString ds;
    int pathc;
    char **pathv;
    char installLib[LIBRARY_SIZE], developLib[LIBRARY_SIZE];

    Tcl_DStringInit(&ds);
    pathPtr = Tcl_NewObj();

    /*
     * Initialize the substrings used when locating an executable.  The
     * installLib variable computes the path as though the executable
     * is installed.  The developLib computes the path as though the
     * executable is run from a develpment directory.
     */

    sprintf(installLib, "lib/tcl%s", TCL_VERSION);
    sprintf(developLib, "../tcl%s/library",
	    ((TCL_RELEASE_LEVEL < 2) ? TCL_PATCH_LEVEL : TCL_VERSION));

    /*
     * Look for the library relative to default encoding dir.
     */

    str = Tcl_GetDefaultEncodingDir();
    if ((str != NULL) && (str[0] != '\0')) {
	objPtr = Tcl_NewStringObj(str, -1);
	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
    }

    /*
     * Look for the library relative to the TCL_LIBRARY env variable.
     * If the last dirname in the TCL_LIBRARY path does not match the
     * last dirname in the installLib variable, use the last dir name
     * of installLib in addition to the orginal TCL_LIBRARY path.
     */

    AppendEnvironment(pathPtr, installLib);

    /*
     * Look for the library relative to the DLL.  Only use the installLib
     * because in practice, the DLL is always installed.
     */

    AppendDllPath(pathPtr, TclWinGetTclInstance(), installLib);
    
    /*
     * Look for the library relative to the executable.  Use both the
     * installLib and developLib because we cannot determine if this
     * is installed or not.
     */

    if (path != NULL) {
	Tcl_SplitPath(path, &pathc, &pathv);
	if (pathc > 1) {
	    pathv[pathc - 2] = installLib;
	    path = Tcl_JoinPath(pathc - 1, pathv, &ds);
	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
	    Tcl_DStringFree(&ds);
	}
	if (pathc > 2) {
	    pathv[pathc - 3] = developLib;
	    path = Tcl_JoinPath(pathc - 2, pathv, &ds);
	    objPtr = Tcl_NewStringObj(path, Tcl_DStringLength(&ds));
	    Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
	    Tcl_DStringFree(&ds);
	}
	ckfree((char *) pathv);
    }

    TclSetLibraryPath(pathPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * AppendEnvironment --
 *
 *	Append the value of the TCL_LIBRARY environment variable onto the
 *	path pointer.  If the env variable points to another version of
 *	tcl (e.g. "tcl7.6") also append the path to this version (e.g.,
 *	"tcl7.6/../tcl8.1")
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static void
AppendEnvironment(
    Tcl_Obj *pathPtr,
    CONST char *lib)
{
    int pathc;
    WCHAR wBuf[MAX_PATH];
    char buf[MAX_PATH * TCL_UTF_MAX];
    Tcl_Obj *objPtr;
    char *str;
    Tcl_DString ds;
    char **pathv;

    /*
     * The "L" preceeding the TCL_LIBRARY string is used to tell VC++
     * that this is a unicode string.
     */
    
    if (GetEnvironmentVariableW(L"TCL_LIBRARY", wBuf, MAX_PATH) == 0) {
        buf[0] = '\0';
	GetEnvironmentVariableA("TCL_LIBRARY", buf, MAX_PATH);
    } else {
	ToUtf(wBuf, buf);
    }

    if (buf[0] != '\0') {
	objPtr = Tcl_NewStringObj(buf, -1);
	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);

	TclWinNoBackslash(buf);
	Tcl_SplitPath(buf, &pathc, &pathv);

	/* 
	 * The lstrcmpi() will work even if pathv[pathc - 1] is random
	 * UTF-8 chars because I know lib is ascii.
	 */

	if ((pathc > 0) && (lstrcmpiA(lib + 4, pathv[pathc - 1]) != 0)) {
	    /*
	     * TCL_LIBRARY is set but refers to a different tcl
	     * installation than the current version.  Try fiddling with the
	     * specified directory to make it refer to this installation by
	     * removing the old "tclX.Y" and substituting the current
	     * version string.
	     */
	    
	    pathv[pathc - 1] = (char *) (lib + 4);
	    Tcl_DStringInit(&ds);
	    str = Tcl_JoinPath(pathc, pathv, &ds);
	    objPtr = Tcl_NewStringObj(str, Tcl_DStringLength(&ds));
	    Tcl_DStringFree(&ds);
	} else {
	    objPtr = Tcl_NewStringObj(buf, -1);
	}
	Tcl_ListObjAppendElement(NULL, pathPtr, objPtr);
	ckfree((char *) pathv);
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * AppendDllPath --
 *
 *	Append a path onto the path pointer that tries to locate the Tcl
 *	library relative to the location of the Tcl DLL.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static void 
AppendDllPath(
    Tcl_Obj *pathPtr, 
    HMODULE hModule,
    CONST char *lib)
{
    WCHAR wName[MAX_PATH + LIBRARY_SIZE];
    char name[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX];

    if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) {
	GetModuleFileNameA(hModule, name, MAX_PATH);
    } else {
	ToUtf(wName, name);
    }
    if (lib != NULL) {
	char *end, *p;

	end = strrchr(name, '\\');
	*end = '\0';
	p = strrchr(name, '\\');
	if (p != NULL) {
	    end = p;
	}
	*end = '\\';
	strcpy(end + 1, lib);
    }
    TclWinNoBackslash(name);
    Tcl_ListObjAppendElement(NULL, pathPtr, Tcl_NewStringObj(name, -1));
}

/*
 *---------------------------------------------------------------------------
 *
 * ToUtf --
 *
 *	Convert a char string to a UTF string.  
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

static int
ToUtf(
    CONST WCHAR *wSrc,
    char *dst)
{
    char *start;

    start = dst;
    while (*wSrc != '\0') {
	dst += Tcl_UniCharToUtf(*wSrc, dst);
	wSrc++;
    }
    *dst = '\0';
    return dst - start;
}


/*
 *---------------------------------------------------------------------------
 *
 * TclpSetInitialEncodings --
 *
 *	Based on the locale, determine the encoding of the operating
 *	system and the default encoding for newly opened files.
 *
 *	Called at process initialization time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The Tcl library path is converted from native encoding to UTF-8.
 *
 *---------------------------------------------------------------------------
 */

void
TclpSetInitialEncodings()
{
    CONST char *encoding;

    char buf[4 + TCL_INTEGER_SPACE];
    int platformId;
    Tcl_Obj *pathPtr;




    platformId = TclWinGetPlatformId();

    TclWinSetInterfaces(platformId == VER_PLATFORM_WIN32_NT);

    wsprintfA(buf, "cp%d", GetACP());
    Tcl_SetSystemEncoding(NULL, buf);

    if (platformId != VER_PLATFORM_WIN32_NT) {
	pathPtr = TclGetLibraryPath();

	if (pathPtr != NULL) {
	    int i, objc;








	    Tcl_Obj **objv;




	    
	    objc = 0;
	    Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);
	    for (i = 0; i < objc; i++) {
		int length;
		char *string;

		Tcl_DString ds;

		string = Tcl_GetStringFromObj(objv[i], &length);
		Tcl_ExternalToUtfDString(NULL, string, length, &ds);
		Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds), 
			Tcl_DStringLength(&ds));



		Tcl_DStringFree(&ds);
	    }
	}
    }


    /*
     * Keep this encoding preloaded.  The IO package uses it for gets on a


     * binary channel.  
     */










    encoding = "iso8859-1";
    Tcl_GetEncoding(NULL, encoding);
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpSetVariables --
 *
 *	Performs platform-specific interpreter initialization related to
 *	the tcl_library and tcl_platform variables, and other platform-
 *	specific things.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets "tcl_library", "tcl_platform", and "env(HOME)" Tcl variables.
 *
 *----------------------------------------------------------------------
 */

void
TclpSetVariables(interp)
    Tcl_Interp *interp;		/* Interp to initialize. */	
{	    
    char *ptr;
    char buffer[TCL_INTEGER_SPACE * 2];


    SYSTEM_INFO sysInfo;

    OemId *oemId;


    OSVERSIONINFOA osInfo;


    Tcl_DString ds;





    osInfo.dwOSVersionInfoSize = sizeof(osInfo);
    GetVersionExA(&osInfo);







    oemId = (OemId *) &sysInfo;





    if (osInfo.dwPlatformId == VER_PLATFORM_WIN32s) {
	/*

	 * Since Win32s doesn't support GetSystemInfo, we use a default value.
	 */




	oemId->wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;






    } else {























	GetSystemInfo(&sysInfo);
    }

    /*
     * Define the tcl_platform array.
     */

    Tcl_SetVar2(interp, "tcl_platform", "platform", "windows",
	    TCL_GLOBAL_ONLY);
    if (osInfo.dwPlatformId < NUMPLATFORMS) {
	Tcl_SetVar2(interp, "tcl_platform", "os",
		platforms[osInfo.dwPlatformId], TCL_GLOBAL_ONLY);
    }
    wsprintfA(buffer, "%d.%d", osInfo.dwMajorVersion, osInfo.dwMinorVersion);
    Tcl_SetVar2(interp, "tcl_platform", "osVersion", buffer, TCL_GLOBAL_ONLY);
    if (oemId->wProcessorArchitecture < NUMPROCESSORS) {
	Tcl_SetVar2(interp, "tcl_platform", "machine",
		processors[oemId->wProcessorArchitecture],
		TCL_GLOBAL_ONLY);
    }

#ifdef _DEBUG
    /*
     * The existence of the "debug" element of the tcl_platform array indicates
     * that this particular Tcl shell has been compiled with debug information.
     * Using "info exists tcl_platform(debug)" a Tcl script can direct the 
     * interpreter to load debug versions of DLLs with the load command.
     */

    Tcl_SetVar2(interp, "tcl_platform", "debug", "1",
	    TCL_GLOBAL_ONLY);
#endif

    /*
     * Set up the HOME environment variable from the HOMEDRIVE & HOMEPATH
     * environment variables, if necessary.
     */

    Tcl_DStringInit(&ds);
    ptr = Tcl_GetVar2(interp, "env", "HOME", TCL_GLOBAL_ONLY);
    if (ptr == NULL) {

	ptr = Tcl_GetVar2(interp, "env", "HOMEDRIVE", TCL_GLOBAL_ONLY);
	if (ptr != NULL) {
	    Tcl_DStringAppend(&ds, ptr, -1);
	}
	ptr = Tcl_GetVar2(interp, "env", "HOMEPATH", TCL_GLOBAL_ONLY);
	if (ptr != NULL) {
	    Tcl_DStringAppend(&ds, ptr, -1);
	}
	if (Tcl_DStringLength(&ds) > 0) {
	    Tcl_SetVar2(interp, "env", "HOME", Tcl_DStringValue(&ds),
		    TCL_GLOBAL_ONLY);
	} else {
	    Tcl_SetVar2(interp, "env", "HOME", "c:\\", TCL_GLOBAL_ONLY);
	}
    }

    Tcl_DStringSetLength(&ds, 100);
    if (GetUserName(Tcl_DStringValue(&ds), &Tcl_DStringLength(&ds)) != 0) {
	Tcl_SetVar2(interp, "tcl_platform", "user", Tcl_DStringValue(&ds),
		TCL_GLOBAL_ONLY);
    } else {
	Tcl_SetVar2(interp, "tcl_platform", "user", "", TCL_GLOBAL_ONLY);
    }
    Tcl_DStringFree(&ds);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpFindVariable --
 *
 *	Locate the entry in environ for a given name.  On Unix this 
 *	routine is case sensetive, on Windows this matches mioxed case.
 *
 * Results:
 *	The return value is the index in environ of an entry with the
 *	name "name", or -1 if there is no such entry.   The integer at
 *	*lengthPtr is filled in with the length of name (if a matching
 *	entry is found) or the length of the environ array (if no matching
 *	entry is found).
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclpFindVariable(name, lengthPtr)
    CONST char *name;		/* Name of desired environment variable
				 * (UTF-8). */
    int *lengthPtr;		/* Used to return length of name (for
				 * successful searches) or number of non-NULL
				 * entries in environ (for unsuccessful
				 * searches). */
{
    int i, length, result = -1;
    register CONST char *env, *p1, *p2;
    char *envUpper, *nameUpper;
    Tcl_DString envString;

    /*
     * Convert the name to all upper case for the case insensitive
     * comparison.
     */

    length = strlen(name);
    nameUpper = (char *) ckalloc((unsigned) length+1);
    memcpy((VOID *) nameUpper, (VOID *) name, (size_t) length+1);
    Tcl_UtfToUpper(nameUpper);
    
    Tcl_DStringInit(&envString);
    for (i = 0, env = environ[i]; env != NULL; i++, env = environ[i]) {
	/*
	 * Chop the env string off after the equal sign, then Convert
	 * the name to all upper case, so we do not have to convert
	 * all the characters after the equal sign.
	 */
	
	envUpper = Tcl_ExternalToUtfDString(NULL, env, -1, &envString);
	p1 = strchr(envUpper, '=');
	if (p1 == NULL) {
	    continue;
	}
	length = p1 - envUpper;
	Tcl_DStringSetLength(&envString, length+1);
	Tcl_UtfToUpper(envUpper);

	p1 = envUpper;
	p2 = nameUpper;
	for (; *p2 == *p1; p1++, p2++) {
	    /* NULL loop body. */
	}
	if ((*p1 == '=') && (*p2 == '\0')) {
	    *lengthPtr = length;
	    result = i;
	    goto done;
	}
	
	Tcl_DStringFree(&envString);
    }
    
    *lengthPtr = i;

    done:
    Tcl_DStringFree(&envString);
    ckfree(nameUpper);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Init --
 *
 *	This procedure is typically invoked by Tcl_AppInit procedures
 *	to perform additional initialization for a Tcl interpreter,
 *	such as sourcing the "init.tcl" script.
 *
 * Results:
 *	Returns a standard Tcl completion code and sets the interp's
 *	result if there is an error.
 *
 * Side effects:
 *	Depends on what's in the init.tcl script.
 *
 *----------------------------------------------------------------------
 */

int
Tcl_Init(interp)
    Tcl_Interp *interp;		/* Interpreter to initialize. */
{
    Tcl_Obj *pathPtr;

    if (tclPreInitScript != NULL) {
	if (Tcl_Eval(interp, tclPreInitScript) == TCL_ERROR) {
	    return (TCL_ERROR);
	};
    }



    pathPtr = TclGetLibraryPath();

    if (pathPtr == NULL) {
	pathPtr = Tcl_NewObj();









    }



    Tcl_SetVar2Ex(interp, "tcl_libPath", NULL, pathPtr, TCL_GLOBAL_ONLY);
    return Tcl_Eval(interp, initScript);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SourceRCFile --
 *
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394





























            c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
            if (c != (Tcl_Channel) NULL) {
                Tcl_Close(NULL, c);
		if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
		    errChannel = Tcl_GetStdChannel(TCL_STDERR);
		    if (errChannel) {
			Tcl_Write(errChannel, interp->result, -1);
			Tcl_Write(errChannel, "\n", 1);
		    }
		}
	    }
	}
        Tcl_DStringFree(&temp);
    }
}



































|
|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789

            c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
            if (c != (Tcl_Channel) NULL) {
                Tcl_Close(NULL, c);
		if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
		    errChannel = Tcl_GetStdChannel(TCL_STDERR);
		    if (errChannel) {
			Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
			Tcl_WriteChars(errChannel, "\n", 1);
		    }
		}
	    }
	}
        Tcl_DStringFree(&temp);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpAsyncMark --
 *
 *	Wake up the main thread from a signal handler.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sends a message to the main thread.
 *
 *----------------------------------------------------------------------
 */

void
TclpAsyncMark(async)
    Tcl_AsyncHandler async;		/* Token for handler. */
{
    /*
     * Need a way to kick the Windows event loop and tell it to go look at
     * asynchronous events.
     */

    PostThreadMessage(mainThreadId, WM_USER, 0, 0);
}

Changes to win/tclWinInt.h.

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
/*
 * tclWinInt.h --
 *
 *	Declarations of Windows-specific shared variables and procedures.
 *
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclWinInt.h 1.7 97/06/25 10:56:14
 */

#ifndef _TCLWININT
#define _TCLWININT

#ifndef _TCLINT
#include "tclInt.h"
#endif
#ifndef _TCLPORT
#include "tclPort.h"
#endif

/*













 * Some versions of Borland C have a define for the OSVERSIONINFO for
 * Win32s and for NT, but not for Windows 95.
 */

#ifndef VER_PLATFORM_WIN32_WINDOWS
#define VER_PLATFORM_WIN32_WINDOWS 1
#endif






EXTERN int		TclWinSynchSpawn(void *args, int type, void **trans,




				      Tcl_Pid *pidPtr);














































EXTERN int		TclWinGetPlatformId(void);








#endif	/* _TCLWININT */










|













>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>

>
>
>
>


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
/*
 * tclWinInt.h --
 *
 *	Declarations of Windows-specific shared variables and procedures.
 *
 * Copyright (c) 1994-1996 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: tclWinInt.h,v 1.1.2.4 1999/03/10 06:49:30 stanton Exp $
 */

#ifndef _TCLWININT
#define _TCLWININT

#ifndef _TCLINT
#include "tclInt.h"
#endif
#ifndef _TCLPORT
#include "tclPort.h"
#endif

/*
 * The following specifies how much stack space TclpCheckStackSpace()
 * ensures is available.  TclpCheckStackSpace() is called by Tcl_EvalObj()
 * to help avoid overflowing the stack in the case of infinite recursion.
 */

#define TCL_WIN_STACK_THRESHOLD 0x2000

#ifdef BUILD_tcl
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * Some versions of Borland C have a define for the OSVERSIONINFO for
 * Win32s and for NT, but not for Windows 95.
 */

#ifndef VER_PLATFORM_WIN32_WINDOWS
#define VER_PLATFORM_WIN32_WINDOWS 1
#endif

/*
 * The following structure keeps track of whether we are using the 
 * multi-byte or the wide-character interfaces to the operating system.
 * System calls should be made through the following function table.
 */

typedef union {
    WIN32_FIND_DATAA a;
    WIN32_FIND_DATAW w;
} WIN32_FIND_DATAT;

typedef struct TclWinProcs {
    int useWide;

    BOOL (WINAPI *buildCommDCBProc)(CONST TCHAR *, LPDCB);
    TCHAR *(WINAPI *charLowerProc)(TCHAR *);
    BOOL (WINAPI *copyFileProc)(CONST TCHAR *, CONST TCHAR *, BOOL);
    BOOL (WINAPI *createDirectoryProc)(CONST TCHAR *, LPSECURITY_ATTRIBUTES);
    HANDLE (WINAPI *createFileProc)(CONST TCHAR *, DWORD, DWORD, 
	    LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
    BOOL (WINAPI *createProcessProc)(CONST TCHAR *, TCHAR *, 
	    LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, 
	    LPVOID, CONST TCHAR *, LPSTARTUPINFOA, LPPROCESS_INFORMATION);
    BOOL (WINAPI *deleteFileProc)(CONST TCHAR *);
    HANDLE (WINAPI *findFirstFileProc)(CONST TCHAR *, WIN32_FIND_DATAT *);
    BOOL (WINAPI *findNextFileProc)(HANDLE, WIN32_FIND_DATAT *);
    BOOL (WINAPI *getComputerNameProc)(WCHAR *, LPDWORD);
    DWORD (WINAPI *getCurrentDirectoryProc)(DWORD, WCHAR *);
    DWORD (WINAPI *getFileAttributesProc)(CONST TCHAR *);
    DWORD (WINAPI *getFullPathNameProc)(CONST TCHAR *, DWORD nBufferLength, 
	    WCHAR *, TCHAR **);
    DWORD (WINAPI *getModuleFileNameProc)(HMODULE, WCHAR *, int);
    DWORD (WINAPI *getShortPathNameProc)(CONST TCHAR *, WCHAR *, DWORD); 
    UINT (WINAPI *getTempFileNameProc)(CONST TCHAR *, CONST TCHAR *, UINT, 
	    WCHAR *);
    DWORD (WINAPI *getTempPathProc)(DWORD, WCHAR *);
    BOOL (WINAPI *getVolumeInformationProc)(CONST TCHAR *, WCHAR *, DWORD, 
	    LPDWORD, LPDWORD, LPDWORD, WCHAR *, DWORD);
    HINSTANCE (WINAPI *loadLibraryProc)(CONST TCHAR *);
    TCHAR (WINAPI *lstrcpyProc)(WCHAR *, CONST TCHAR *);
    BOOL (WINAPI *moveFileProc)(CONST TCHAR *, CONST TCHAR *);
    BOOL (WINAPI *removeDirectoryProc)(CONST TCHAR *);
    DWORD (WINAPI *searchPathProc)(CONST TCHAR *, CONST TCHAR *, 
	    CONST TCHAR *, DWORD, WCHAR *, TCHAR **);
    BOOL (WINAPI *setCurrentDirectoryProc)(CONST TCHAR *);
    BOOL (WINAPI *setFileAttributesProc)(CONST TCHAR *, DWORD);
} TclWinProcs;

EXTERN TclWinProcs *tclWinProcs;
EXTERN Tcl_Encoding tclWinTCharEncoding;

/*
 * Declarations of functions that are not accessible by way of the
 * stubs table.
 */

EXTERN TclPlatformType *TclWinGetPlatform(void);
EXTERN int		TclWinGetPlatformId(void);
EXTERN void		TclWinInit(HINSTANCE hInst);
EXTERN void		TclWinSetInterfaces(int);

# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT

#include "tclIntPlatDecls.h"

#endif	/* _TCLWININT */

Changes to win/tclWinLoad.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
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
/* 
 * tclWinLoad.c --
 *
 *	This procedure provides a version of the TclLoadFile that
 *	works with the Windows "LoadLibrary" and "GetProcAddress"
 *	API for dynamic loading.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclWinLoad.c 1.6 96/02/15 11:54:07
 */

#include "tclInt.h"
#include "tclPort.h"


/*
 *----------------------------------------------------------------------
 *
 * TclLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in interp->result.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */



{
    HINSTANCE handle;


    char *buffer;





    handle = TclWinLoadLibrary(fileName);
    if (handle == NULL) {

	Tcl_AppendResult(interp, "couldn't load file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }

    /*
     * For each symbol, check for both Symbol and _Symbol, since Borland
     * generates C symbols with a leading '_' by default.
     */

    *proc1Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, sym1);
    if (*proc1Ptr == NULL) {
	buffer = ckalloc(strlen(sym1)+2);
	buffer[0] = '_';
	strcpy(buffer+1, sym1);
	*proc1Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, buffer);
	ckfree(buffer);
    }
    
    *proc2Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, sym2);
    if (*proc2Ptr == NULL) {
	buffer = ckalloc(strlen(sym2)+2);
	buffer[0] = '_';

	strcpy(buffer+1, sym2);
	*proc2Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, buffer);




	ckfree(buffer);

















    }






    

    return TCL_OK;


}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *







|




|


|
<





|







|








|








>
>
>


>
>
|
>
>
>

>
|

>












|
<
|
|
|




<
<
>
|
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
|
>
>







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
/* 
 * tclWinLoad.c --
 *
 *	This procedure provides a version of the TclLoadFile that
 *	works with the Windows "LoadLibrary" and "GetProcAddress"
 *	API for dynamic loading.
 *
 * 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: tclWinLoad.c,v 1.1.2.2 1998/09/24 23:59:52 stanton Exp $
 */

#include "tclWinInt.h"



/*
 *----------------------------------------------------------------------
 *
 * TclpLoadFile --
 *
 *	Dynamically loads a binary code file into memory and returns
 *	the addresses of two procedures within that file, if they
 *	are defined.
 *
 * Results:
 *	A standard Tcl completion code.  If an error occurs, an error
 *	message is left in the interp's result.
 *
 * Side effects:
 *	New code suddenly appears in memory.
 *
 *----------------------------------------------------------------------
 */

int
TclpLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr)
    Tcl_Interp *interp;		/* Used for error reporting. */
    char *fileName;		/* Name of the file containing the desired
				 * code. */
    char *sym1, *sym2;		/* Names of two procedures to look up in
				 * the file's symbol table. */
    Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
				/* Where to return the addresses corresponding
				 * to sym1 and sym2. */
    ClientData *clientDataPtr;	/* Filled with token for dynamically loaded
				 * file which will be passed back to 
				 * TclpUnloadFile() to unload the file. */
{
    HINSTANCE handle;
    TCHAR *nativeName;
    Tcl_DString ds;

    nativeName = Tcl_WinUtfToTChar(fileName, -1, &ds);
    handle = (*tclWinProcs->loadLibraryProc)(nativeName);
    Tcl_DStringFree(&ds);

    *clientDataPtr = (ClientData) handle;
    
    if (handle == NULL) {
	TclWinConvertError(GetLastError());
	Tcl_AppendResult(interp, "couldn't load file \"", fileName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	return TCL_ERROR;
    }

    /*
     * For each symbol, check for both Symbol and _Symbol, since Borland
     * generates C symbols with a leading '_' by default.
     */

    *proc1Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, sym1);
    if (*proc1Ptr == NULL) {
	Tcl_DStringAppend(&ds, "_", 1);

	sym1 = Tcl_DStringAppend(&ds, sym1, -1);
	*proc1Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, sym1);
	Tcl_DStringFree(&ds);
    }
    
    *proc2Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, sym2);
    if (*proc2Ptr == NULL) {


	Tcl_DStringAppend(&ds, "_", 1);
	sym2 = Tcl_DStringAppend(&ds, sym2, -1);
	*proc2Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, sym2);
	Tcl_DStringFree(&ds);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpUnloadFile --
 *
 *	Unloads a dynamically loaded binary code file from memory.
 *	Code pointers in the formerly loaded file are no longer valid
 *	after calling this function.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Code removed from memory.
 *
 *----------------------------------------------------------------------
 */

void
TclpUnloadFile(clientData)
    ClientData clientData;	/* ClientData returned by a previous call
				 * to TclpLoadFile().  The clientData is 
				 * a token that represents the loaded 
				 * file. */
{
    HINSTANCE handle;

    handle = (HINSTANCE) clientData;
    FreeLibrary(handle);
}

/*
 *----------------------------------------------------------------------
 *
 * TclGuessPackageName --
 *

Changes to win/tclWinMtherr.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
/* 
 * tclWinMtherr.c --
 *
 *	This function provides a default implementation of the
 *	_matherr function for Borland C++.
 *
 * Copyright (c) 1995 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclWinMtherr.c 1.2 96/02/15 11:54:05
 */

#include "tclInt.h"
#include "tclPort.h"
#include <math.h>

/*
 * The following variable is secretly shared with Tcl so we can
 * tell if expression evaluation is in progress.  If not, matherr
 * just emulates the default behavior, which includes printing
 * a message.
 */

extern int tcl_MathInProgress;

/*
 *----------------------------------------------------------------------
 *
 * _matherr --
 *
 *	This procedure is invoked by Borland C++ when certain











|


|
<


<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17








18
19
20
21
22
23
24
/* 
 * tclWinMtherr.c --
 *
 *	This function provides a default implementation of the
 *	_matherr function for Borland C++.
 *
 * Copyright (c) 1995 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: tclWinMtherr.c,v 1.1.2.2 1998/09/24 23:59:52 stanton Exp $
 */

#include "tclWinInt.h"

#include <math.h>










/*
 *----------------------------------------------------------------------
 *
 * _matherr --
 *
 *	This procedure is invoked by Borland C++ when certain
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 *----------------------------------------------------------------------
 */

int
_matherr(xPtr)
    struct exception *xPtr;	/* Describes error that occurred. */
{
    if (!tcl_MathInProgress) {
	return 0;
    }
    if ((xPtr->type == DOMAIN) || (xPtr->type == SING)) {
	errno = EDOM;
    } else {
	errno = ERANGE;
    }
    return 1;
}







|









36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 *----------------------------------------------------------------------
 */

int
_matherr(xPtr)
    struct exception *xPtr;	/* Describes error that occurred. */
{
    if (!TclMathInProgress()) {
	return 0;
    }
    if ((xPtr->type == DOMAIN) || (xPtr->type == SING)) {
	errno = EDOM;
    } else {
	errno = ERANGE;
    }
    return 1;
}

Changes to win/tclWinNotify.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
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
/* 
 * tclWinNotify.c --
 *
 *	This file contains Windows-specific procedures for the notifier,
 *	which is the lowest-level part of the Tcl event loop.  This file
 *	works together with ../generic/tclNotify.c.
 *
 * 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.
 *
 * SCCS: @(#) tclWinNotify.c 1.17 97/05/23 10:48:44
 */

#include "tclInt.h"
#include "tclPort.h"
#include <winsock.h>

/*
 * The follwing static indicates whether this module has been initialized.
 */

static int initialized = 0;

#define INTERVAL_TIMER 1		/* Handle of interval timer. */



/*
 * The following static structure contains the state information for the
 * Windows implementation of the Tcl notifier.

 */

static struct {







    HWND hwnd;			/* Messaging window. */
    int timeout;		/* Current timeout value. */
    int timerActive;		/* 1 if interval timer is running. */












} notifier;


/*
 * Static routines defined in this file.
 */

static void		InitNotifier(void);
static void		NotifierExitHandler(ClientData clientData);
static LRESULT CALLBACK	NotifierProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);
static void		UpdateTimer(int timeout);

/*
 *----------------------------------------------------------------------
 *
 * InitNotifier --
 *
 *	Initializes the notifier window.
 *
 * Results:
 *	None.

 *
 * Side effects:
 *	Creates a new notifier window and window class.

 *
 *----------------------------------------------------------------------
 */

static void
InitNotifier(void)
{

    WNDCLASS class;





    initialized = 1;

    notifier.timerActive = 0;
    class.style = 0;
    class.cbClsExtra = 0;
    class.cbWndExtra = 0;
    class.hInstance = TclWinGetTclInstance();
    class.hbrBackground = NULL;
    class.lpszMenuName = NULL;
    class.lpszClassName = "TclNotifier";
    class.lpfnWndProc = NotifierProc;
    class.hIcon = NULL;
    class.hCursor = NULL;

    if (!RegisterClass(&class)) {
	panic("Unable to register TclNotifier window class");
    }



    notifier.hwnd = CreateWindow("TclNotifier", "TclNotifier", WS_TILED,


	    0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL);

    Tcl_CreateExitHandler(NotifierExitHandler, NULL);




}



/*
 *----------------------------------------------------------------------
 *
 * NotifierExitHandler --
 *
 *	This function is called to cleanup the notifier state before
 *	Tcl is unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Destroys the notifier window.
 *
 *----------------------------------------------------------------------
 */

static void
NotifierExitHandler(
    ClientData clientData)	/* Old window proc */
{

    initialized = 0;







    if (notifier.hwnd) {
	KillTimer(notifier.hwnd, INTERVAL_TIMER);
	DestroyWindow(notifier.hwnd);

	UnregisterClass("TclNotifier", TclWinGetTclInstance());






	notifier.hwnd = NULL;


    }

}

/*
 *----------------------------------------------------------------------
 *
 * UpdateTimer --
 *
 *	This function starts or stops the notifier interval timer.






 *
 * Results:
 *	None.
 *
 * Side effects:

 *	None.
 *
 *----------------------------------------------------------------------
 */

void
UpdateTimer(
    int timeout)		/* ms timeout, 0 means cancel timer */

{

    notifier.timeout = timeout;
    if (timeout != 0) {



	notifier.timerActive = 1;

	SetTimer(notifier.hwnd, INTERVAL_TIMER,




		    (unsigned long) notifier.timeout, NULL);






    } else {
	notifier.timerActive = 0;
	KillTimer(notifier.hwnd, INTERVAL_TIMER);

    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetTimer --












|


|
<








|

>
>


|
>


|
>
>
>
>
>
>
>



>
>
>
>
>
>
>
>
>
>
>
>
|
>





<
<


|




|

|


<
>


<
>




|
|

>


>
>
>
>
|
>
|
|
|
|
|
|
|
|
|
|
|

|
|
|
>
>
>
|
>
>
|
>
|
>
>
>
>
|
>
|
>



|


|





|




|
|
|

>
|
>
>
>
>
>
>
>
|
|
|
>
|
>
>
>
>
>
>
|
>
>

>





|

|
>
>
>
>
>
>





>
|





|
<
>

>
|
<
>
>
>
|
>
|
>
>
>
>
|
>
>
>
>
>
>

<
<
>







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
/* 
 * tclWinNotify.c --
 *
 *	This file contains Windows-specific procedures for the notifier,
 *	which is the lowest-level part of the Tcl event loop.  This file
 *	works together with ../generic/tclNotify.c.
 *
 * 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: tclWinNotify.c,v 1.1.2.6 1999/03/24 04:25:17 stanton Exp $
 */

#include "tclWinInt.h"

#include <winsock.h>

/*
 * The follwing static indicates whether this module has been initialized.
 */

static int initialized = 0;

#define INTERVAL_TIMER 1	/* Handle of interval timer. */

#define WM_WAKEUP WM_USER	/* Message that is send by
				 * Tcl_AlertNotifier. */
/*
 * The following static structure contains the state information for the
 * Windows implementation of the Tcl notifier.  One of these structures
 * is created for each thread that is using the notifier.  
 */

typedef struct ThreadSpecificData {
    CRITICAL_SECTION crit;	/* Monitor for this notifier. */
    DWORD thread;		/* Identifier for thread associated with this
				 * notifier. */
    HANDLE event;		/* Event object used to wake up the notifier
				 * thread. */
    int pending;		/* Alert message pending, this field is
				 * locked by the notifierMutex. */
    HWND hwnd;			/* Messaging window. */
    int timeout;		/* Current timeout value. */
    int timerActive;		/* 1 if interval timer is running. */
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * The following static indicates the number of threads that have
 * initialized notifiers.  It controls the lifetime of the TclNotifier
 * window class.
 *
 * You must hold the notifierMutex lock before accessing this variable.
 */

static int notifierCount = 0;
TCL_DECLARE_MUTEX(notifierMutex)

/*
 * Static routines defined in this file.
 */



static LRESULT CALLBACK	NotifierProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);


/*
 *----------------------------------------------------------------------
 *
 * Tcl_InitNotifier --
 *
 *	Initializes the platform specific notifier state.
 *
 * Results:

 *	Returns a handle to the notifier state for this thread..
 *
 * Side effects:

 *	None.
 *
 *----------------------------------------------------------------------
 */

ClientData
Tcl_InitNotifier()
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    WNDCLASS class;

    /*
     * Register Notifier window class if this is the first thread to
     * use this module.
     */

    Tcl_MutexLock(&notifierMutex);
    if (notifierCount == 0) {
	class.style = 0;
	class.cbClsExtra = 0;
	class.cbWndExtra = 0;
	class.hInstance = TclWinGetTclInstance();
	class.hbrBackground = NULL;
	class.lpszMenuName = NULL;
	class.lpszClassName = "TclNotifier";
	class.lpfnWndProc = NotifierProc;
	class.hIcon = NULL;
	class.hCursor = NULL;

	if (!RegisterClassA(&class)) {
	    panic("Unable to register TclNotifier window class");
	}
    }
    notifierCount++;
    Tcl_MutexUnlock(&notifierMutex);

    tsdPtr->pending = 0;
    tsdPtr->timerActive = 0;

    InitializeCriticalSection(&tsdPtr->crit);

    tsdPtr->hwnd = NULL;
    tsdPtr->thread = GetCurrentThreadId();
    tsdPtr->event = CreateEvent(NULL, TRUE /* manual */,
	    FALSE /* !signaled */, NULL);

    return (ClientData) tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FinalizeNotifier --
 *
 *	This function is called to cleanup the notifier state before
 *	a thread is terminated.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May dispose of the notifier window and class.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_FinalizeNotifier(clientData)
    ClientData clientData;	/* Pointer to notifier data. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;

    DeleteCriticalSection(&tsdPtr->crit);
    CloseHandle(tsdPtr->event);

    /*
     * Clean up the timer and messaging window for this thread.
     */

    if (tsdPtr->hwnd) {
	KillTimer(tsdPtr->hwnd, INTERVAL_TIMER);
	DestroyWindow(tsdPtr->hwnd);
    }

    /*
     * If this is the last thread to use the notifier, unregister
     * the notifier window class.
     */

    Tcl_MutexLock(&notifierMutex);
    notifierCount--;
    if (notifierCount == 0) {
	UnregisterClassA("TclNotifier", TclWinGetTclInstance());
    }
    Tcl_MutexUnlock(&notifierMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_AlertNotifier --
 *
 *	Wake up the specified notifier from any thread. This routine
 *	is called by the platform independent notifier code whenever
 *	the Tcl_ThreadAlert routine is called.  This routine is
 *	guaranteed not to be called on a given notifier after
 *	Tcl_FinalizeNotifier is called for that notifier.  This routine
 *	is typically called from a thread other than the notifier's
 *	thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sends a message to the messaging window for the notifier
 *	if there isn't already one pending.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_AlertNotifier(clientData)

    ClientData clientData;	/* Pointer to thread data. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;


    /*
     * Note that we do not need to lock around access to the hwnd
     * because the race condition has no effect since any race condition
     * implies that the notifier thread is already awake.
     */

    if (tsdPtr->hwnd) {
	/*
	 * We do need to lock around access to the pending flag.
	 */

	EnterCriticalSection(&tsdPtr->crit);
	if (!tsdPtr->pending) {
	    PostMessage(tsdPtr->hwnd, WM_WAKEUP, 0, 0);
	}
	tsdPtr->pending = 1;
	LeaveCriticalSection(&tsdPtr->crit);
    } else {


	SetEvent(tsdPtr->event);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_SetTimer --
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
 *----------------------------------------------------------------------
 */

void
Tcl_SetTimer(
    Tcl_Time *timePtr)		/* Maximum block time, or NULL. */
{

    UINT timeout;





    if (!initialized) {

	InitNotifier();


    }

    if (!timePtr) {
	timeout = 0;
    } else {
	/*
	 * Make sure we pass a non-zero value into the timeout argument.
	 * Windows seems to get confused by zero length timers.
	 */

	timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
	if (timeout == 0) {
	    timeout = 1;
	}
    }

    UpdateTimer(timeout);






}


/*
 *----------------------------------------------------------------------
 *
















































 * NotifierProc --
 *
 *	This procedure is invoked by Windows to process the timer

 *	message whenever we are using an external dispatch loop.

 *
 * Results:
 *	A standard windows result.
 *
 * Side effects:
 *	Services any pending events.
 *
 *----------------------------------------------------------------------
 */

static LRESULT CALLBACK
NotifierProc(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{






    if (message != WM_TIMER) {
	return DefWindowProc(hwnd, message, wParam, lParam);
    }
	
    /*
     * Process all of the runnable events.
     */








>


>
>
>
>
|
>
|
>
>









>





>
|
>
>
>
>
>
>
|
|
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
>
|
>

















>

>
>
>
>
|







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
 *----------------------------------------------------------------------
 */

void
Tcl_SetTimer(
    Tcl_Time *timePtr)		/* Maximum block time, or NULL. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    UINT timeout;

    /*
     * We only need to set up an interval timer if we're being called
     * from an external event loop.  If we don't have a window handle
     * then we just return immediately and let Tcl_WaitForEvent handle
     * timeouts.
     */

    if (!tsdPtr->hwnd) {
	return;
    }

    if (!timePtr) {
	timeout = 0;
    } else {
	/*
	 * Make sure we pass a non-zero value into the timeout argument.
	 * Windows seems to get confused by zero length timers.
	 */

	timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
	if (timeout == 0) {
	    timeout = 1;
	}
    }
    tsdPtr->timeout = timeout;
    if (timeout != 0) {
	tsdPtr->timerActive = 1;
	SetTimer(tsdPtr->hwnd, INTERVAL_TIMER,
		    (unsigned long) tsdPtr->timeout, NULL);
    } else {
	tsdPtr->timerActive = 0;
	KillTimer(tsdPtr->hwnd, INTERVAL_TIMER);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ServiceModeHook --
 *
 *	This function is invoked whenever the service mode changes.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	If this is the first time the notifier is set into
 *	TCL_SERVICE_ALL, then the communication window is created.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ServiceModeHook(mode)
    int mode;			/* Either TCL_SERVICE_ALL, or
				 * TCL_SERVICE_NONE. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * If this is the first time that the notifier has been used from a
     * modal loop, then create a communication window.  Note that after
     * this point, the application needs to service events in a timely
     * fashion or Windows will hang waiting for the window to respond
     * to synchronous system messages.  At some point, we may want to
     * consider destroying the window if we leave the modal loop, but
     * for now we'll leave it around.
     */

    if (mode == TCL_SERVICE_ALL && !tsdPtr->hwnd) {
	tsdPtr->hwnd = CreateWindowA("TclNotifier", "TclNotifier", WS_TILED,
		0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL);
	/*
	 * Send an initial message to the window to ensure that we wake up the
	 * notifier once we get into the modal loop.  This will force the
	 * notifier to recompute the timeout value and schedule a timer
	 * if one is needed.
	 */

	Tcl_AlertNotifier((ClientData)tsdPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * NotifierProc --
 *
 *	This procedure is invoked by Windows to process events on
 *	the notifier window.  Messages will be sent to this window
 *	in response to external timer events or calls to
 *	TclpAlertTsdPtr->
 *
 * Results:
 *	A standard windows result.
 *
 * Side effects:
 *	Services any pending events.
 *
 *----------------------------------------------------------------------
 */

static LRESULT CALLBACK
NotifierProc(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (message == WM_WAKEUP) {
	EnterCriticalSection(&tsdPtr->crit);
	tsdPtr->pending = 0;
	LeaveCriticalSection(&tsdPtr->crit);
    } else if (message != WM_TIMER) {
	return DefWindowProc(hwnd, message, wParam, lParam);
    }
	
    /*
     * Process all of the runnable events.
     */

249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273





274
275
276




277


278

279


280









281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296
297
298
299
300





301
302
303
304
305
306
307
308
 *----------------------------------------------------------------------
 */

int
Tcl_WaitForEvent(
    Tcl_Time *timePtr)		/* Maximum block time, or NULL. */
{

    MSG msg;
    int timeout;

    if (!initialized) {
	InitNotifier();
    }

    /*
     * Only use the interval timer for non-zero timeouts.  This avoids
     * generating useless messages when we really just want to poll.
     */

    if (timePtr) {
	timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
    } else {
	timeout = 0;
    }
    UpdateTimer(timeout);





	
    if (!timePtr || (timeout != 0)
	    || PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {




	if (!GetMessage(&msg, NULL, 0, 0)) {




	    /*


	     * The application is exiting, so repost the quit message









	     * and start unwinding.
	     */

	    PostQuitMessage(msg.wParam);
	    return -1;
	}

	/*

	 * Handle timer expiration as a special case so we don't
	 * claim to be doing work when we aren't.
	 */

	if (msg.message == WM_TIMER && msg.hwnd == notifier.hwnd) {
	    return 0;
	}

	TranslateMessage(&msg);
	DispatchMessage(&msg);
	return 1;
    }





    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Sleep --
 *







>

|
|
<
<
|
<

|
<





|

|
>
>
>
>
>
|
<
|
>
>
>
>
|
>
>
|
>
|
>
>
|
>
>
>
>
>
>
>
>
>
|



|
<
|
|
>
|
<
|

<
|
<
|
|
|
|
|
>
>
>
>
>
|







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
 *----------------------------------------------------------------------
 */

int
Tcl_WaitForEvent(
    Tcl_Time *timePtr)		/* Maximum block time, or NULL. */
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    MSG msg;
    DWORD timeout, result;
    int status;




    /*
     * Compute the timeout in milliseconds.

     */

    if (timePtr) {
	timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
    } else {
	timeout = INFINITE;
    }

    /*
     * Check to see if there are any messages in the queue before waiting
     * because MsgWaitForMultipleObjects will not wake up if there are events
     * currently sitting in the queue.
     */


    if (!PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
	/*
	 * Wait for something to happen (a signal from another thread, a
	 * message, or timeout).
	 */

	result = MsgWaitForMultipleObjects(1, &tsdPtr->event, FALSE, timeout,
		QS_ALLINPUT);
    }

    /*
     * Check to see if there are any messages to process.
     */

    if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
	/*
	 * Retrieve and dispatch the first message.
	 */

	result = GetMessage(&msg, NULL, 0, 0);
	if (result == 0) {
	    /*
	     * We received a request to exit this thread (WM_QUIT), so
	     * propagate the quit message and start unwinding.
	     */

	    PostQuitMessage(msg.wParam);
	    status = -1;

	} else if (result == -1) {
	    /*
	     * We got an error from the system.  I have no idea why this would
	     * happen, so we'll just unwind.

	     */


	    status = -1;

	} else {
	    TranslateMessage(&msg);
	    DispatchMessage(&msg);
	    status = 1;
	}
    } else {
	status = 0;
    }

    ResetEvent(tsdPtr->event);
    return status;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Sleep --
 *

Changes to win/tclWinPipe.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
/* 
 * tclWinPipe.c --
 *
 *	This file implements the Windows-specific exec pipeline functions,
 *	the "pipe" channel driver, and the "pid" Tcl command.
 *
 * Copyright (c) 1996-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.
 *
 * SCCS: @(#) tclWinPipe.c 1.49 97/11/06 17:33:03
 */

#include "tclWinInt.h"

#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>

/*
 * The following variable is used to tell whether this module has been
 * initialized.
 */

static int initialized = 0;









/*
 * The following defines identify the various types of applications that 
 * run under windows.  There is special case code for the various types.
 */

#define APPL_NONE	0
#define APPL_DOS	1











|
















>
>
>
>
>
>
>
>







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
/* 
 * tclWinPipe.c --
 *
 *	This file implements the Windows-specific exec pipeline functions,
 *	the "pipe" channel driver, and the "pid" Tcl command.
 *
 * Copyright (c) 1996-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: tclWinPipe.c,v 1.1.2.11 1999/04/14 00:34:02 surles Exp $
 */

#include "tclWinInt.h"

#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>

/*
 * The following variable is used to tell whether this module has been
 * initialized.
 */

static int initialized = 0;

/*
 * The pipeMutex locks around access to the initialized and procList variables,
 * and it is used to protect background threads from being terminated while
 * they are using APIs that hold locks.
 */

TCL_DECLARE_MUTEX(pipeMutex)

/*
 * The following defines identify the various types of applications that 
 * run under windows.  There is special case code for the various types.
 */

#define APPL_NONE	0
#define APPL_DOS	1
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
    DWORD dwProcessId;
    struct ProcInfo *nextPtr;
} ProcInfo;

static ProcInfo *procList;

/*
 * State flags used in the PipeInfo structure below.
 */

#define PIPE_PENDING	(1<<0)	/* Message is pending in the queue. */
#define PIPE_ASYNC	(1<<1)	/* Channel is non-blocking. */








/*
 * This structure describes per-instance data for a pipe based channel.
 */

typedef struct PipeInfo {

    Tcl_Channel channel;	/* Pointer to channel structure. */
    int validMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which operations are valid on the file. */
    int watchMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which events should be reported. */
    int flags;			/* State flags, see above for a list. */
    TclFile readFile;		/* Output from pipe. */
    TclFile writeFile;		/* Input from pipe. */
    TclFile errorFile;		/* Error output from pipe. */
    int numPids;		/* Number of processes attached to pipe. */
    Tcl_Pid *pidPtr;		/* Pids of attached processes. */













    struct PipeInfo *nextPtr;	/* Pointer to next registered pipe. */
























} PipeInfo;


/*
 * The following pointer refers to the head of the list of pipes
 * that are being watched for file events.
 */

static PipeInfo *firstPipePtr;




/*
 * The following structure is what is added to the Tcl event queue when
 * pipe events are generated.
 */

typedef struct PipeEvent {
    Tcl_Event header;		/* Information that is standard for
				 * all events. */
    PipeInfo *infoPtr;		/* Pointer to pipe info structure.  Note
				 * that we still have to verify that the
				 * pipe exists before dereferencing this
				 * pointer. */
} PipeEvent;

/*
 * Declarations for functions used only in this file.
 */

static int	ApplicationType(Tcl_Interp *interp, const char *fileName,
		    char *fullName);

static void	BuildCommandLine(int argc, char **argv, Tcl_DString *linePtr);
static void	CopyChannel(HANDLE dst, HANDLE src);
static BOOL	HasConsole(void);
static TclFile	MakeFile(HANDLE handle);
static char *	MakeTempFile(Tcl_DString *namePtr);
static int	PipeBlockModeProc(ClientData instanceData, int mode);
static void	PipeCheckProc _ANSI_ARGS_((ClientData clientData,

		    int flags));
static int	PipeCloseProc(ClientData instanceData, Tcl_Interp *interp);
static int	PipeEventProc(Tcl_Event *evPtr, int flags);
static void	PipeExitHandler(ClientData clientData);
static int	PipeGetHandleProc(ClientData instanceData, int direction,
		    ClientData *handlePtr);
static void	PipeInit(void);
static int	PipeInputProc(ClientData instanceData, char *buf, int toRead,
		    int *errorCode);
static int	PipeOutputProc(ClientData instanceData, char *buf, int toWrite,
		    int *errorCode);


static void	PipeWatchProc(ClientData instanceData, int mask);

static void	PipeSetupProc _ANSI_ARGS_((ClientData clientData,
		    int flags));
static int	TempFileName(char name[MAX_PATH]);

/*
 * This structure describes the channel type structure for command pipe
 * based IO.
 */

static Tcl_ChannelType pipeChannelType = {
    "pipe",			/* Type name. */
    PipeBlockModeProc,		/* Set blocking or non-blocking mode.*/
    PipeCloseProc,		/* Close proc. */
    PipeInputProc,		/* Input proc. */
    PipeOutputProc,		/* Output proc. */
    NULL,			/* Seek proc. */
    NULL,			/* Set option proc. */
    NULL,			/* Get option proc. */
    PipeWatchProc,		/* Set up notifier to watch the channel. */
    PipeGetHandleProc,		/* Get an OS handle from channel. */

};

/*
 *----------------------------------------------------------------------
 *
 * PipeInit --
 *







|





>
>
>
>
>
>
>





>













>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
|
|
|
|
|
|
>
>
>



















|
|
>
|
|
|
<
|
|
|
>
|
<
|
|
|
|
|
|
|
|
|
>
>
|
>
|
|
|









|







>







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
    DWORD dwProcessId;
    struct ProcInfo *nextPtr;
} ProcInfo;

static ProcInfo *procList;

/*
 * Bit masks used in the flags field of the PipeInfo structure below.
 */

#define PIPE_PENDING	(1<<0)	/* Message is pending in the queue. */
#define PIPE_ASYNC	(1<<1)	/* Channel is non-blocking. */

/*
 * Bit masks used in the sharedFlags field of the PipeInfo structure below.
 */

#define PIPE_EOF	(1<<2)	/* Pipe has reached EOF. */
#define PIPE_EXTRABYTE (1<<3)	/* The reader thread has consumed one byte. */

/*
 * This structure describes per-instance data for a pipe based channel.
 */

typedef struct PipeInfo {
    struct PipeInfo *nextPtr;	/* Pointer to next registered pipe. */
    Tcl_Channel channel;	/* Pointer to channel structure. */
    int validMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which operations are valid on the file. */
    int watchMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which events should be reported. */
    int flags;			/* State flags, see above for a list. */
    TclFile readFile;		/* Output from pipe. */
    TclFile writeFile;		/* Input from pipe. */
    TclFile errorFile;		/* Error output from pipe. */
    int numPids;		/* Number of processes attached to pipe. */
    Tcl_Pid *pidPtr;		/* Pids of attached processes. */
    Tcl_ThreadId threadId;	/* Thread to which events should be reported.
				 * This value is used by the reader/writer
				 * threads. */
    HANDLE writeThread;		/* Handle to writer thread. */
    HANDLE readThread;		/* Handle to reader thread. */
    HANDLE writable;		/* Manual-reset event to signal when the
				 * writer thread has finished waiting for
				 * the current buffer to be written. */
    HANDLE readable;		/* Manual-reset event to signal when the
				 * reader thread has finished waiting for
				 * input. */
    HANDLE startWriter;		/* Auto-reset event used by the main thread to
				 * signal when the writer thread should attempt
				 * to write to the pipe. */
    HANDLE startReader;		/* Auto-reset event used by the main thread to
				 * signal when the reader thread should attempt
				 * to read from the pipe. */
    DWORD writeError;		/* An error caused by the last background
				 * write.  Set to 0 if no error has been
				 * detected.  This word is shared with the
				 * writer thread so access must be
				 * synchronized with the writable object.
				 */
    char *writeBuf;		/* Current background output buffer.
				 * Access is synchronized with the writable
				 * object. */
    int writeBufLen;		/* Size of write buffer.  Access is
				 * synchronized with the writable
				 * object. */
    int toWrite;		/* Current amount to be written.  Access is
				 * synchronized with the writable object. */
    int readFlags;		/* Flags that are shared with the reader
				 * thread.  Access is synchronized with the
				 * readable object.  */
    char extraByte;		/* Buffer for extra character consumed by
				 * reader thread.  This byte is shared with
				 * the reader thread so access must be
				 * synchronized with the readable object. */
} PipeInfo;

typedef struct ThreadSpecificData {
    /*
     * The following pointer refers to the head of the list of pipes
     * that are being watched for file events.
     */
    
    PipeInfo *firstPipePtr;
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * The following structure is what is added to the Tcl event queue when
 * pipe events are generated.
 */

typedef struct PipeEvent {
    Tcl_Event header;		/* Information that is standard for
				 * all events. */
    PipeInfo *infoPtr;		/* Pointer to pipe info structure.  Note
				 * that we still have to verify that the
				 * pipe exists before dereferencing this
				 * pointer. */
} PipeEvent;

/*
 * Declarations for functions used only in this file.
 */

static int		ApplicationType(Tcl_Interp *interp,
			    const char *fileName, char *fullName);
static void		BuildCommandLine(const char *executable, int argc, 
			    char **argv, Tcl_DString *linePtr);
static void		CopyChannel(HANDLE dst, HANDLE src);
static BOOL		HasConsole(void);

static char *		MakeTempFile(Tcl_DString *namePtr);
static int		PipeBlockModeProc(ClientData instanceData, int mode);
static void		PipeCheckProc(ClientData clientData, int flags);
static int		PipeClose2Proc(ClientData instanceData,
			    Tcl_Interp *interp, int flags);

static int		PipeEventProc(Tcl_Event *evPtr, int flags);
static void		PipeExitHandler(ClientData clientData);
static int		PipeGetHandleProc(ClientData instanceData,
			    int direction, ClientData *handlePtr);
static void		PipeInit(void);
static int		PipeInputProc(ClientData instanceData, char *buf,
			    int toRead, int *errorCode);
static int		PipeOutputProc(ClientData instanceData, char *buf,
			    int toWrite, int *errorCode);
static DWORD WINAPI	PipeReaderThread(LPVOID arg);
static void		PipeSetupProc(ClientData clientData, int flags);
static void		PipeWatchProc(ClientData instanceData, int mask);
static DWORD WINAPI	PipeWriterThread(LPVOID arg);
static void		ProcExitHandler(ClientData clientData);
static int		TempFileName(WCHAR name[MAX_PATH]);
static int		WaitForRead(PipeInfo *infoPtr, int blocking);

/*
 * This structure describes the channel type structure for command pipe
 * based IO.
 */

static Tcl_ChannelType pipeChannelType = {
    "pipe",			/* Type name. */
    PipeBlockModeProc,		/* Set blocking or non-blocking mode.*/
    TCL_CLOSE2PROC,		/* Close proc. */
    PipeInputProc,		/* Input proc. */
    PipeOutputProc,		/* Output proc. */
    NULL,			/* Seek proc. */
    NULL,			/* Set option proc. */
    NULL,			/* Get option proc. */
    PipeWatchProc,		/* Set up notifier to watch the channel. */
    PipeGetHandleProc,		/* Get an OS handle from channel. */
    PipeClose2Proc
};

/*
 *----------------------------------------------------------------------
 *
 * PipeInit --
 *
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
 *
 *----------------------------------------------------------------------
 */

static void
PipeInit()
{










    initialized = 1;
    firstPipePtr = NULL;
    procList = NULL;









    Tcl_CreateEventSource(PipeSetupProc, PipeCheckProc, NULL);
    Tcl_CreateExitHandler(PipeExitHandler, NULL);

}

/*
 *----------------------------------------------------------------------
 *
 * PipeExitHandler --
 *
 *	This function is called to cleanup the pipe module before
 *	Tcl is unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Removes the pipe event source.
 *
 *----------------------------------------------------------------------
 */

static void
PipeExitHandler(clientData)
    ClientData clientData;	/* Old window proc */
{
    Tcl_DeleteEventSource(PipeSetupProc, PipeCheckProc, NULL);
























    initialized = 0;

}

/*
 *----------------------------------------------------------------------
 *
 * PipeSetupProc --
 *
 *	This procedure is invoked before Tcl_DoOneEvent blocks waiting
 *	for an event.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Adjusts the block time if needed.
 *
 *----------------------------------------------------------------------
 */

void
PipeSetupProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    PipeInfo *infoPtr;
    Tcl_Time blockTime = { 0, 0 };




    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Check to see if there is a watched pipe.  If so, poll.
     */


    for (infoPtr = firstPipePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask) {




	    Tcl_SetMaxBlockTime(&blockTime);



	    break;



	}




    }
}

/*
 *----------------------------------------------------------------------
 *
 * PipeCheckProc --







>
>
>
>
>
>
>
>
>
>
|
<
|
>
>
>
>
>
>
>
>
>
|
|
>




















|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>




















|
|
|



>
>
>






|


>
|
|
>
>
>
>
|
>
>
>
|
>
>
>
|
>
>
>
>







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
 *
 *----------------------------------------------------------------------
 */

static void
PipeInit()
{
    ThreadSpecificData *tsdPtr;

    /*
     * Check the initialized flag first, then check again in the mutex.
     * This is a speed enhancement.
     */

    if (!initialized) {
	Tcl_MutexLock(&pipeMutex);
	if (!initialized) {
	    initialized = 1;

	    procList = NULL;
	    Tcl_CreateExitHandler(ProcExitHandler, NULL);
	}
	Tcl_MutexUnlock(&pipeMutex);
    }

    tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
	tsdPtr->firstPipePtr = NULL;
	Tcl_CreateEventSource(PipeSetupProc, PipeCheckProc, NULL);
	Tcl_CreateThreadExitHandler(PipeExitHandler, NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PipeExitHandler --
 *
 *	This function is called to cleanup the pipe module before
 *	Tcl is unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Removes the pipe event source.
 *
 *----------------------------------------------------------------------
 */

static void
PipeExitHandler(
    ClientData clientData)	/* Old window proc */
{
    Tcl_DeleteEventSource(PipeSetupProc, PipeCheckProc, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * ProcExitHandler --
 *
 *	This function is called to cleanup the process list before
 *	Tcl is unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resets the process list.
 *
 *----------------------------------------------------------------------
 */

static void
ProcExitHandler(
    ClientData clientData)	/* Old window proc */
{
    Tcl_MutexLock(&pipeMutex);
    initialized = 0;
    Tcl_MutexUnlock(&pipeMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * PipeSetupProc --
 *
 *	This procedure is invoked before Tcl_DoOneEvent blocks waiting
 *	for an event.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Adjusts the block time if needed.
 *
 *----------------------------------------------------------------------
 */

void
PipeSetupProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    PipeInfo *infoPtr;
    Tcl_Time blockTime = { 0, 0 };
    int block = 1;
    WinFile *filePtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Look to see if any events are already pending.  If they are, poll.
     */

    for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask & TCL_WRITABLE) {
	    filePtr = (WinFile*) infoPtr->writeFile;
	    if ((filePtr->type == WIN32S_PIPE) 
		    || (WaitForSingleObject(infoPtr->writable, 0)
			    != WAIT_TIMEOUT)) {
		block = 0;
	    }
	}
	if (infoPtr->watchMask & TCL_READABLE) {
	    filePtr = (WinFile*) infoPtr->readFile;
	    if ((filePtr->type == WIN32S_PIPE) 
		    || (WaitForRead(infoPtr, 0) >= 0)) {
		block = 0;
	    }
	}
    }
    if (!block) {
	Tcl_SetMaxBlockTime(&blockTime);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PipeCheckProc --
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
 * Side effects:
 *	May queue an event.
 *
 *----------------------------------------------------------------------
 */

static void
PipeCheckProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    PipeInfo *infoPtr;
    PipeEvent *evPtr;




    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Queue events for any watched pipes that don't already have events
     * queued.
     */


    for (infoPtr = firstPipePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {










	if (infoPtr->watchMask && !(infoPtr->flags & PIPE_PENDING)) {
















	    infoPtr->flags |= PIPE_PENDING;
	    evPtr = (PipeEvent *) ckalloc(sizeof(PipeEvent));
	    evPtr->header.proc = PipeEventProc;
	    evPtr->infoPtr = infoPtr;
	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MakeFile --
 *
 *	This function constructs a new TclFile from a given data and
 *	type value.
 *
 * Results:
 *	Returns a newly allocated WinFile as a TclFile.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TclFile
MakeFile(handle)
    HANDLE handle;		/* Type-specific data. */
{
    WinFile *filePtr;

    filePtr = (WinFile *) ckalloc(sizeof(WinFile));
    filePtr->type = WIN_FILE;
    filePtr->handle = handle;

    return (TclFile)filePtr;
}















































/*
 *----------------------------------------------------------------------
 *
 * TclpMakeFile --
 *
 *	Make a TclFile from a channel.







|
|
|



>
>
>






|



>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












|













|
|
|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
 * Side effects:
 *	May queue an event.
 *
 *----------------------------------------------------------------------
 */

static void
PipeCheckProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    PipeInfo *infoPtr;
    PipeEvent *evPtr;
    WinFile *filePtr;
    int needEvent;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Queue events for any ready pipes that don't already have events
     * queued.
     */

    for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->flags & PIPE_PENDING) {
	    continue;
	}
	
	/*
	 * Queue an event if the pipe is signaled for reading or writing.
	 */

	needEvent = 0;
	filePtr = (WinFile*) infoPtr->writeFile;
	if (infoPtr->watchMask & TCL_WRITABLE) {
	    if ((filePtr->type == WIN32S_PIPE)
		    || (WaitForSingleObject(infoPtr->writable, 0)
			    != WAIT_TIMEOUT)) {
		needEvent = 1;
	    }
	}
	
	filePtr = (WinFile*) infoPtr->readFile;
	if (infoPtr->watchMask & TCL_READABLE) {
	    if ((filePtr->type == WIN32S_PIPE)
		    || (WaitForRead(infoPtr, 0) >= 0)) {
		needEvent = 1;
	    }
	}

	if (needEvent) {
	    infoPtr->flags |= PIPE_PENDING;
	    evPtr = (PipeEvent *) ckalloc(sizeof(PipeEvent));
	    evPtr->header.proc = PipeEventProc;
	    evPtr->infoPtr = infoPtr;
	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclWinMakeFile --
 *
 *	This function constructs a new TclFile from a given data and
 *	type value.
 *
 * Results:
 *	Returns a newly allocated WinFile as a TclFile.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TclFile
TclWinMakeFile(
    HANDLE handle)		/* Type-specific data. */
{
    WinFile *filePtr;

    filePtr = (WinFile *) ckalloc(sizeof(WinFile));
    filePtr->type = WIN_FILE;
    filePtr->handle = handle;

    return (TclFile)filePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TempFileName --
 *
 *	Gets a temporary file name and deals with the fact that the
 *	temporary file path provided by Windows may not actually exist
 *	if the TMP or TEMP environment variables refer to a 
 *	non-existent directory.
 *
 * Results:    
 *	0 if error, non-zero otherwise.  If non-zero is returned, the
 *	name buffer will be filled with a name that can be used to 
 *	construct a temporary file.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TempFileName(name)
    WCHAR name[MAX_PATH];	/* Buffer in which name for temporary 
				 * file gets stored. */
{
    TCHAR *prefix;

    prefix = (tclWinProcs->useWide) ? (TCHAR *) L"TCL" : (TCHAR *) "TCL";
    if ((*tclWinProcs->getTempPathProc)(MAX_PATH, name) != 0) {
	if ((*tclWinProcs->getTempFileNameProc)((TCHAR *) name, prefix, 0, 
		name) != 0) {
	    return 1;
	}
    }
    if (tclWinProcs->useWide) {
	((WCHAR *) name)[0] = '.';
	((WCHAR *) name)[1] = '\0';
    } else {
	((char *) name)[0] = '.';
	((char *) name)[1] = '\0';
    }
    return (*tclWinProcs->getTempFileNameProc)((TCHAR *) name, prefix, 0, 
	    name);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpMakeFile --
 *
 *	Make a TclFile from a channel.
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

555
556
557
558
559
560
561
562
    Tcl_Channel channel;	/* Channel to get file from. */
    int direction;		/* Either TCL_READABLE or TCL_WRITABLE. */
{
    HANDLE handle;

    if (Tcl_GetChannelHandle(channel, direction, 
	    (ClientData *) &handle) == TCL_OK) {
	return MakeFile(handle);
    } else {
	return (TclFile) NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TempFileName --
 *
 *	Gets a temporary file name and deals with the fact that the
 *	temporary file path provided by Windows may not actually exist
 *	if the TMP or TEMP environment variables refer to a 
 *	non-existent directory.
 *
 * Results:    
 *	0 if error, non-zero otherwise.  If non-zero is returned, the
 *	name buffer will be filled with a name that can be used to 
 *	construct a temporary file.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TempFileName(name)
    char name[MAX_PATH];	/* Buffer in which name for temporary 
				 * file gets stored. */
{
    if ((GetTempPath(MAX_PATH, name) == 0) ||
	    (GetTempFileName(name, "TCL", 0, name) == 0)) {
	name[0] = '.';
	name[1] = '\0';
	if (GetTempFileName(name, "TCL", 0, name) == 0) {
	    return 0;
	}
    }
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCreateTempFile --
 *
 *	This function opens a unique file with the property that it
 *	will be deleted when its file handle is closed.  The temporary
 *	file is created in the system temporary directory.
 *
 * Results:
 *	Returns a valid TclFile, or NULL on failure.
 *
 * Side effects:
 *	Creates a new temporary file.
 *
 *----------------------------------------------------------------------
 */

TclFile
TclpCreateTempFile(contents, namePtr)
    char *contents;		/* String to write into temp file, or NULL. */
    Tcl_DString *namePtr;	/* If non-NULL, pointer to initialized 
				 * DString that is filled with the name of 
				 * the temp file that was created. */
{
    char name[MAX_PATH];
    HANDLE handle;

    if (TempFileName(name) == 0) {
	return NULL;
    }

    handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
	    CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,
	    NULL);
    if (handle == INVALID_HANDLE_VALUE) {
	goto error;
    }

    /*
     * Write the file out, doing line translations on the way.
     */

    if (contents != NULL) {
	DWORD result, length;
	char *p;
	
	for (p = contents; *p != '\0'; p++) {
	    if (*p == '\n') {
		length = p - contents;
		if (length > 0) {
		    if (!WriteFile(handle, contents, length, &result, NULL)) {
			goto error;
		    }
		}
		if (!WriteFile(handle, "\r\n", 2, &result, NULL)) {
		    goto error;
		}
		contents = p+1;
	    }
	}
	length = p - contents;
	if (length > 0) {
	    if (!WriteFile(handle, contents, length, &result, NULL)) {
		goto error;
	    }
	}
    }

    if (SetFilePointer(handle, 0, NULL, FILE_BEGIN) == 0xFFFFFFFF) {
	goto error;
    }

    if (namePtr != NULL) {
        Tcl_DStringAppend(namePtr, name, -1);
    }

    /*
     * Under Win32s a file created with FILE_FLAG_DELETE_ON_CLOSE won't
     * actually be deleted when it is closed, so we have to do it ourselves.
     */

    if (TclWinGetPlatformId() == VER_PLATFORM_WIN32s) {
	TmpFile *tmpFilePtr = (TmpFile *) ckalloc(sizeof(TmpFile));
	tmpFilePtr->file.type = WIN32S_TMPFILE;
	tmpFilePtr->file.handle = handle;
	strcpy(tmpFilePtr->name, name);
	return (TclFile)tmpFilePtr;
    } else {
	return MakeFile(handle);
    }

  error:
    TclWinConvertError(GetLastError());
    CloseHandle(handle);
    DeleteFile(name);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpOpenFile --
 *
 *	This function opens files for use in a pipeline.
 *
 * Results:
 *	Returns a newly allocated TclFile structure containing the
 *	file handle.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TclFile
TclpOpenFile(path, mode)
    char *path;
    int mode;
{
    HANDLE handle;
    DWORD accessMode, createMode, shareMode, flags;
    SECURITY_ATTRIBUTES sec;


    /*
     * Map the access bits to the NT access mode.
     */

    switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
	case O_RDONLY:
	    accessMode = GENERIC_READ;







|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















|
|



|
>
|







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
    Tcl_Channel channel;	/* Channel to get file from. */
    int direction;		/* Either TCL_READABLE or TCL_WRITABLE. */
{
    HANDLE handle;

    if (Tcl_GetChannelHandle(channel, direction, 
	    (ClientData *) &handle) == TCL_OK) {
	return TclWinMakeFile(handle);
    } else {
	return (TclFile) NULL;
    }
}









































































































































/*
 *----------------------------------------------------------------------
 *
 * TclpOpenFile --
 *
 *	This function opens files for use in a pipeline.
 *
 * Results:
 *	Returns a newly allocated TclFile structure containing the
 *	file handle.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TclFile
TclpOpenFile(path, mode)
    CONST char *path;		/* The name of the file to open. */
    int mode;			/* In what mode to open the file? */
{
    HANDLE handle;
    DWORD accessMode, createMode, shareMode, flags;
    Tcl_DString ds;
    TCHAR *nativePath;
    
    /*
     * Map the access bits to the NT access mode.
     */

    switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
	case O_RDONLY:
	    accessMode = GENERIC_READ;
592
593
594
595
596
597
598


599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629

630

631
632


633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649



























































































650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686

687
688

689
690
691
692
693
694

695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
	    createMode = TRUNCATE_EXISTING;
	    break;
	default:
	    createMode = OPEN_EXISTING;
	    break;
    }



    /*
     * If the file is not being created, use the existing file attributes.
     */

    flags = 0;
    if (!(mode & O_CREAT)) {
	flags = GetFileAttributes(path);
	if (flags == 0xFFFFFFFF) {
	    flags = 0;
	}
    }

    /*
     * Set up the security attributes so this file is not inherited by
     * child processes.
     */

    sec.nLength = sizeof(sec);
    sec.lpSecurityDescriptor = NULL;
    sec.bInheritHandle = 0;

    /*
     * Set up the file sharing mode.  We want to allow simultaneous access.
     */

    shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;

    /*
     * Now we get to create the file.
     */


    handle = CreateFile(path, accessMode, shareMode, &sec, createMode, flags,

            (HANDLE) NULL);
    if (handle == INVALID_HANDLE_VALUE) {


	DWORD err = GetLastError();
	if ((err & 0xffffL) == ERROR_OPEN_FAILED) {
	    err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND;
	}
        TclWinConvertError(err);
        return NULL;
    }

    /*
     * Seek to the end of file if we are writing.
     */

    if (mode & O_WRONLY) {
	SetFilePointer(handle, 0, NULL, FILE_END);
    }

    return MakeFile(handle);



























































































}

/*
 *----------------------------------------------------------------------
 *
 * TclpCreatePipe --
 *
 *      Creates an anonymous pipe.  Under Win32s, creates a temp file
 *	that is used to simulate a pipe.
 *
 * Results:
 *      Returns 1 on success, 0 on failure. 
 *
 * Side effects:
 *      Creates a pipe.
 *
 *----------------------------------------------------------------------
 */

int
TclpCreatePipe(readPipe, writePipe)
    TclFile *readPipe;	/* Location to store file handle for
				 * read side of pipe. */
    TclFile *writePipe;	/* Location to store file handle for
				 * write side of pipe. */
{
    HANDLE readHandle, writeHandle;

    if (CreatePipe(&readHandle, &writeHandle, NULL, 0) != 0) {
	*readPipe = MakeFile(readHandle);
	*writePipe = MakeFile(writeHandle);
	return 1;
    }

    if (TclWinGetPlatformId() == VER_PLATFORM_WIN32s) {
	WinPipe *readPipePtr, *writePipePtr;
	char buf[MAX_PATH];


	if (TempFileName(buf) != 0) {

	    readPipePtr = (WinPipe *) ckalloc(sizeof(WinPipe));
	    writePipePtr = (WinPipe *) ckalloc(sizeof(WinPipe));

	    readPipePtr->file.type = WIN32S_PIPE;
	    readPipePtr->otherPtr = writePipePtr;
	    readPipePtr->fileName = strcpy(ckalloc(strlen(buf) + 1), buf);

	    readPipePtr->file.handle = INVALID_HANDLE_VALUE;
	    writePipePtr->file.type = WIN32S_PIPE;
	    writePipePtr->otherPtr = readPipePtr;
	    writePipePtr->fileName = readPipePtr->fileName;
	    writePipePtr->file.handle = INVALID_HANDLE_VALUE;

	    *readPipe = (TclFile)readPipePtr;
	    *writePipe = (TclFile)writePipePtr;

	    return 1;
	}
    }

    TclWinConvertError(GetLastError());
    return 0;







>
>






|





<
<
<
<
<
<
<
<
<










>
|
>
|

>
>
|















|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




















|
|

|





|
|






>

|
>





|
>






|
|







656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676









677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
	    createMode = TRUNCATE_EXISTING;
	    break;
	default:
	    createMode = OPEN_EXISTING;
	    break;
    }

    nativePath = Tcl_WinUtfToTChar(path, -1, &ds);

    /*
     * If the file is not being created, use the existing file attributes.
     */

    flags = 0;
    if (!(mode & O_CREAT)) {
	flags = (*tclWinProcs->getFileAttributesProc)(nativePath);
	if (flags == 0xFFFFFFFF) {
	    flags = 0;
	}
    }










    /*
     * Set up the file sharing mode.  We want to allow simultaneous access.
     */

    shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;

    /*
     * Now we get to create the file.
     */

    handle = (*tclWinProcs->createFileProc)(nativePath, accessMode, 
	    shareMode, NULL, createMode, flags, NULL);
    Tcl_DStringFree(&ds);

    if (handle == INVALID_HANDLE_VALUE) {
	DWORD err;
	
	err = GetLastError();
	if ((err & 0xffffL) == ERROR_OPEN_FAILED) {
	    err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND;
	}
        TclWinConvertError(err);
        return NULL;
    }

    /*
     * Seek to the end of file if we are writing.
     */

    if (mode & O_WRONLY) {
	SetFilePointer(handle, 0, NULL, FILE_END);
    }

    return TclWinMakeFile(handle);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCreateTempFile --
 *
 *	This function opens a unique file with the property that it
 *	will be deleted when its file handle is closed.  The temporary
 *	file is created in the system temporary directory.
 *
 * Results:
 *	Returns a valid TclFile, or NULL on failure.
 *
 * Side effects:
 *	Creates a new temporary file.
 *
 *----------------------------------------------------------------------
 */

TclFile
TclpCreateTempFile(contents)
    CONST char *contents;	/* String to write into temp file, or NULL. */
{
    WCHAR name[MAX_PATH];
    HANDLE handle;

    if (TempFileName(name) == 0) {
	return NULL;
    }

    handle = (*tclWinProcs->createFileProc)((TCHAR *) name, 
	    GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 
	    FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, NULL);
    if (handle == INVALID_HANDLE_VALUE) {
	goto error;
    }

    /*
     * Write the file out, doing line translations on the way.
     */

    if (contents != NULL) {
	DWORD result, length;
	CONST char *p;
	
	for (p = contents; *p != '\0'; p++) {
	    if (*p == '\n') {
		length = p - contents;
		if (length > 0) {
		    if (!WriteFile(handle, contents, length, &result, NULL)) {
			goto error;
		    }
		}
		if (!WriteFile(handle, "\r\n", 2, &result, NULL)) {
		    goto error;
		}
		contents = p+1;
	    }
	}
	length = p - contents;
	if (length > 0) {
	    if (!WriteFile(handle, contents, length, &result, NULL)) {
		goto error;
	    }
	}
	if (SetFilePointer(handle, 0, NULL, FILE_BEGIN) == 0xFFFFFFFF) {
	    goto error;
	}
    }

    /*
     * Under Win32s a file created with FILE_FLAG_DELETE_ON_CLOSE won't
     * actually be deleted when it is closed, so we have to do it ourselves.
     */

    if (TclWinGetPlatformId() == VER_PLATFORM_WIN32s) {
	TmpFile *tmpFilePtr = (TmpFile *) ckalloc(sizeof(TmpFile));
	tmpFilePtr->file.type = WIN32S_TMPFILE;
	tmpFilePtr->file.handle = handle;
	lstrcpyA(tmpFilePtr->name, (char *) name);
	return (TclFile) tmpFilePtr;
    } else {
	return TclWinMakeFile(handle);
    }

  error:
    TclWinConvertError(GetLastError());
    CloseHandle(handle);
    (*tclWinProcs->deleteFileProc)((TCHAR *) name);
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCreatePipe --
 *
 *      Creates an anonymous pipe.  Under Win32s, creates a temp file
 *	that is used to simulate a pipe.
 *
 * Results:
 *      Returns 1 on success, 0 on failure. 
 *
 * Side effects:
 *      Creates a pipe.
 *
 *----------------------------------------------------------------------
 */

int
TclpCreatePipe(
    TclFile *readPipe,	/* Location to store file handle for
				 * read side of pipe. */
    TclFile *writePipe)	/* Location to store file handle for
				 * write side of pipe. */
{
    HANDLE readHandle, writeHandle;

    if (CreatePipe(&readHandle, &writeHandle, NULL, 0) != 0) {
	*readPipe = TclWinMakeFile(readHandle);
	*writePipe = TclWinMakeFile(writeHandle);
	return 1;
    }

    if (TclWinGetPlatformId() == VER_PLATFORM_WIN32s) {
	WinPipe *readPipePtr, *writePipePtr;
	char buf[MAX_PATH];
	int bytes;

	if (TempFileName((WCHAR *) buf) != 0) {
	    bytes = strlen((char *) buf) + 1;
	    readPipePtr = (WinPipe *) ckalloc(sizeof(WinPipe));
	    writePipePtr = (WinPipe *) ckalloc(sizeof(WinPipe));

	    readPipePtr->file.type = WIN32S_PIPE;
	    readPipePtr->otherPtr = writePipePtr;
	    readPipePtr->fileName = (char *) ckalloc(bytes);
	    lstrcpyA(readPipePtr->fileName, buf);
	    readPipePtr->file.handle = INVALID_HANDLE_VALUE;
	    writePipePtr->file.type = WIN32S_PIPE;
	    writePipePtr->otherPtr = readPipePtr;
	    writePipePtr->fileName = readPipePtr->fileName;
	    writePipePtr->file.handle = INVALID_HANDLE_VALUE;

	    *readPipe = (TclFile) readPipePtr;
	    *writePipe = (TclFile) writePipePtr;

	    return 1;
	}
    }

    TclWinConvertError(GetLastError());
    return 0;
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738










739
740
741
742

743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
 * Side effects:
 *	The file is closed and deallocated.
 *
 *----------------------------------------------------------------------
 */

int
TclpCloseFile(file)
    TclFile file;	/* The file to close. */
{
    WinFile *filePtr = (WinFile *) file;
    WinPipe *pipePtr;

    switch (filePtr->type) {
	case WIN_FILE:
	case WIN32S_TMPFILE:










	    if (CloseHandle(filePtr->handle) == FALSE) {
		TclWinConvertError(GetLastError());
		ckfree((char *) filePtr);
		return -1;

	    }
	    /*
	     * Simulate deleting the file on close for Win32s.
	     */

	    if (filePtr->type == WIN32S_TMPFILE) {
		DeleteFile(((TmpFile*)filePtr)->name);
	    }
	    break;

	case WIN32S_PIPE:
	    pipePtr = (WinPipe *) file;

	    if (pipePtr->otherPtr != NULL) {
		pipePtr->otherPtr->otherPtr = NULL;
	    } else {
		if (pipePtr->file.handle != INVALID_HANDLE_VALUE) {
		    CloseHandle(pipePtr->file.handle);
		}
		DeleteFile(pipePtr->fileName);
		ckfree((char *) pipePtr->fileName);
	    }
	    break;

	default:
	    panic("Tcl_CloseFile: unexpected file type");
    }

    ckfree((char *) filePtr);
    return 0;
}

/*







|
|







>
>
>
>
>
>
>
>
>
>
|
|
|
|
>






|












|





|







878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
 * Side effects:
 *	The file is closed and deallocated.
 *
 *----------------------------------------------------------------------
 */

int
TclpCloseFile(
    TclFile file)	/* The file to close. */
{
    WinFile *filePtr = (WinFile *) file;
    WinPipe *pipePtr;

    switch (filePtr->type) {
	case WIN_FILE:
	case WIN32S_TMPFILE:
	    /*
	     * Don't close the Win32 handle if the handle is a standard channel
	     * during the exit process.  Otherwise, one thread may kill the stdio
	     * of another.
	     */

	    if (!TclInExit() 
		    || ((GetStdHandle(STD_INPUT_HANDLE) != filePtr->handle)
			    && (GetStdHandle(STD_OUTPUT_HANDLE) != filePtr->handle)
			    && (GetStdHandle(STD_ERROR_HANDLE) != filePtr->handle))) {
		if (CloseHandle(filePtr->handle) == FALSE) {
		    TclWinConvertError(GetLastError());
		    ckfree((char *) filePtr);
		    return -1;
		}
	    }
	    /*
	     * Simulate deleting the file on close for Win32s.
	     */

	    if (filePtr->type == WIN32S_TMPFILE) {
		DeleteFileA(((TmpFile *) filePtr)->name);
	    }
	    break;

	case WIN32S_PIPE:
	    pipePtr = (WinPipe *) file;

	    if (pipePtr->otherPtr != NULL) {
		pipePtr->otherPtr->otherPtr = NULL;
	    } else {
		if (pipePtr->file.handle != INVALID_HANDLE_VALUE) {
		    CloseHandle(pipePtr->file.handle);
		}
		DeleteFileA(pipePtr->fileName);
		ckfree((char *) pipePtr->fileName);
	    }
	    break;

	default:
	    panic("TclpCloseFile: unexpected file type");
    }

    ckfree((char *) filePtr);
    return 0;
}

/*
788
789
790
791
792
793
794
795
796
797
798
799

800
801

802
803
804

805
806
807
808
809
810
811
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------------------
 */

unsigned long
TclpGetPid(pid)
    Tcl_Pid pid;		/* The HANDLE of the child process. */
{
    ProcInfo *infoPtr;
    

    for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (infoPtr->hProcess == (HANDLE) pid) {

	    return infoPtr->dwProcessId;
	}
    }

    return (unsigned long) -1;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCreateProcess --







|
|


|
>


>



>







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
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------------------
 */

unsigned long
TclpGetPid(
    Tcl_Pid pid)		/* The HANDLE of the child process. */
{
    ProcInfo *infoPtr;

    Tcl_MutexLock(&pipeMutex);
    for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (infoPtr->hProcess == (HANDLE) pid) {
	    Tcl_MutexUnlock(&pipeMutex);
	    return infoPtr->dwProcessId;
	}
    }
    Tcl_MutexUnlock(&pipeMutex);
    return (unsigned long) -1;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpCreateProcess --
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926

927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
 *	The complete Windows search path is searched to find the specified 
 *	executable.  If an executable by the given name is not found, 
 *	automatically tries appending ".com", ".exe", and ".bat" to the 
 *	executable name.
 *
 * Results:
 *	The return value is TCL_ERROR and an error message is left in
 *	interp->result if there was a problem creating the child 
 *	process.  Otherwise, the return value is TCL_OK and *pidPtr is
 *	filled with the process id of the child process.
 * 
 * Side effects:
 *	A process is created.
 *	
 *----------------------------------------------------------------------
 */

int
TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile, 
	pidPtr)
    Tcl_Interp *interp;		/* Interpreter in which to leave errors that
				 * occurred when creating the child process.
				 * Error messages from the child process
				 * itself are sent to errorFile. */
    int argc;			/* Number of arguments in following array. */
    char **argv;		/* Array of argument strings.  argv[0]
				 * contains the name of the executable
				 * converted to native format (using the
				 * Tcl_TranslateFileName call).  Additional
				 * arguments have not been converted. */
    TclFile inputFile;		/* If non-NULL, gives the file to use as
				 * input for the child process.  If inputFile
				 * file is not readable or is NULL, the child
				 * will receive no standard input. */
    TclFile outputFile;		/* If non-NULL, gives the file that
				 * receives output from the child process.  If
				 * outputFile file is not writeable or is
				 * NULL, output from the child will be
				 * discarded. */
    TclFile errorFile;		/* If non-NULL, gives the file that
				 * receives errors from the child process.  If
				 * errorFile file is not writeable or is NULL,
				 * errors from the child will be discarded.
				 * errorFile may be the same as outputFile. */
    Tcl_Pid *pidPtr;		/* If this procedure is successful, pidPtr
				 * is filled with the process id of the child
				 * process. */
{
    int result, applType, createFlags;
    Tcl_DString cmdLine;
    STARTUPINFO startInfo;
    PROCESS_INFORMATION procInfo;
    SECURITY_ATTRIBUTES secAtts;
    HANDLE hProcess, h, inputHandle, outputHandle, errorHandle;
    char execPath[MAX_PATH];
    char *originalName;
    WinFile *filePtr;

    if (!initialized) {
	PipeInit();
    }

    applType = ApplicationType(interp, argv[0], execPath);
    if (applType == APPL_NONE) {
	return TCL_ERROR;
    }
    originalName = argv[0];
    argv[0] = execPath;

    result = TCL_ERROR;
    Tcl_DStringInit(&cmdLine);

    if (TclWinGetPlatformId() == VER_PLATFORM_WIN32s) {
	/*
	 * Under Win32s, there are no pipes.  In order to simulate pipe
	 * behavior, the child processes are run synchronously and their
	 * I/O is redirected from/to temporary files before the next 
	 * stage of the pipeline is started.
	 */

	MSG msg;
	DWORD status;
	DWORD args[4];
	void *trans[5];
	char *inputFileName, *outputFileName;
	Tcl_DString inputTempFile, outputTempFile;

	BuildCommandLine(argc, argv, &cmdLine);

	ZeroMemory(&startInfo, sizeof(startInfo));
	startInfo.cb = sizeof(startInfo);

	Tcl_DStringInit(&inputTempFile);
	Tcl_DStringInit(&outputTempFile);
	outputHandle = INVALID_HANDLE_VALUE;

	inputFileName = NULL;
	outputFileName = NULL;
	if (inputFile != NULL) {
	    filePtr = (WinFile *) inputFile;
	    switch (filePtr->type) {
		case WIN_FILE:
		case WIN32S_TMPFILE: {
		    h = INVALID_HANDLE_VALUE;
		    inputFileName = MakeTempFile(&inputTempFile);
		    if (inputFileName != NULL) {
			h = CreateFile(inputFileName, GENERIC_WRITE, 0, 
				NULL, CREATE_ALWAYS, 0, NULL);

		    }
		    if (h == INVALID_HANDLE_VALUE) {
			Tcl_AppendResult(interp, "couldn't duplicate input handle: ", 
				Tcl_PosixError(interp), (char *) NULL);
			goto end32s;
		    }
		    CopyChannel(h, filePtr->handle);
		    CloseHandle(h);
		    break;
		}
		case WIN32S_PIPE: {
		    inputFileName = ((WinPipe*)inputFile)->fileName;
		    break;
		}
	    }
	}
	if (inputFileName == NULL) {
	    inputFileName = "nul";
	}
	if (outputFile != NULL) {
	    filePtr = (WinFile *)outputFile;
	    if (filePtr->type == WIN_FILE) {
		outputFileName = MakeTempFile(&outputTempFile);
		if (outputFileName == NULL) {
		    Tcl_AppendResult(interp, "couldn't duplicate output handle: ",
			    Tcl_PosixError(interp), (char *) NULL);
		    goto end32s;
		}
		outputHandle = filePtr->handle;
	    } else if (filePtr->type == WIN32S_PIPE) {
		outputFileName = ((WinPipe*)outputFile)->fileName;
	    }
	}
	if (outputFileName == NULL) {
	    outputFileName = "nul";
	}

	if (applType == APPL_DOS) {







|










|
<
|



|
|




|



|




|




|




|
|



|
<


<
|
<





<
<



















|


















|
|
>











|








|









|







988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006

1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041

1042
1043

1044

1045
1046
1047
1048
1049


1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
 *	The complete Windows search path is searched to find the specified 
 *	executable.  If an executable by the given name is not found, 
 *	automatically tries appending ".com", ".exe", and ".bat" to the 
 *	executable name.
 *
 * Results:
 *	The return value is TCL_ERROR and an error message is left in
 *	the interp's result if there was a problem creating the child 
 *	process.  Otherwise, the return value is TCL_OK and *pidPtr is
 *	filled with the process id of the child process.
 * 
 * Side effects:
 *	A process is created.
 *	
 *----------------------------------------------------------------------
 */

int
TclpCreateProcess(

    Tcl_Interp *interp,		/* Interpreter in which to leave errors that
				 * occurred when creating the child process.
				 * Error messages from the child process
				 * itself are sent to errorFile. */
    int argc,			/* Number of arguments in following array. */
    char **argv,		/* Array of argument strings.  argv[0]
				 * contains the name of the executable
				 * converted to native format (using the
				 * Tcl_TranslateFileName call).  Additional
				 * arguments have not been converted. */
    TclFile inputFile,		/* If non-NULL, gives the file to use as
				 * input for the child process.  If inputFile
				 * file is not readable or is NULL, the child
				 * will receive no standard input. */
    TclFile outputFile,		/* If non-NULL, gives the file that
				 * receives output from the child process.  If
				 * outputFile file is not writeable or is
				 * NULL, output from the child will be
				 * discarded. */
    TclFile errorFile,		/* If non-NULL, gives the file that
				 * receives errors from the child process.  If
				 * errorFile file is not writeable or is NULL,
				 * errors from the child will be discarded.
				 * errorFile may be the same as outputFile. */
    Tcl_Pid *pidPtr)		/* If this procedure is successful, pidPtr
				 * is filled with the process id of the child
				 * process. */
{
    int result, applType, createFlags;
    Tcl_DString cmdLine;	/* Complete command line (TCHAR). */
    STARTUPINFOA startInfo;
    PROCESS_INFORMATION procInfo;
    SECURITY_ATTRIBUTES secAtts;
    HANDLE hProcess, h, inputHandle, outputHandle, errorHandle;
    char execPath[MAX_PATH * TCL_UTF_MAX];

    WinFile *filePtr;


    PipeInit();


    applType = ApplicationType(interp, argv[0], execPath);
    if (applType == APPL_NONE) {
	return TCL_ERROR;
    }



    result = TCL_ERROR;
    Tcl_DStringInit(&cmdLine);

    if (TclWinGetPlatformId() == VER_PLATFORM_WIN32s) {
	/*
	 * Under Win32s, there are no pipes.  In order to simulate pipe
	 * behavior, the child processes are run synchronously and their
	 * I/O is redirected from/to temporary files before the next 
	 * stage of the pipeline is started.
	 */

	MSG msg;
	DWORD status;
	DWORD args[4];
	void *trans[5];
	char *inputFileName, *outputFileName;
	Tcl_DString inputTempFile, outputTempFile;

	BuildCommandLine(execPath, argc, argv, &cmdLine);

	ZeroMemory(&startInfo, sizeof(startInfo));
	startInfo.cb = sizeof(startInfo);

	Tcl_DStringInit(&inputTempFile);
	Tcl_DStringInit(&outputTempFile);
	outputHandle = INVALID_HANDLE_VALUE;

	inputFileName = NULL;
	outputFileName = NULL;
	if (inputFile != NULL) {
	    filePtr = (WinFile *) inputFile;
	    switch (filePtr->type) {
		case WIN_FILE:
		case WIN32S_TMPFILE: {
		    h = INVALID_HANDLE_VALUE;
		    inputFileName = MakeTempFile(&inputTempFile);
		    if (inputFileName != NULL) {
			h = CreateFileA((char *) inputFileName, 
				GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 
				NULL);
		    }
		    if (h == INVALID_HANDLE_VALUE) {
			Tcl_AppendResult(interp, "couldn't duplicate input handle: ", 
				Tcl_PosixError(interp), (char *) NULL);
			goto end32s;
		    }
		    CopyChannel(h, filePtr->handle);
		    CloseHandle(h);
		    break;
		}
		case WIN32S_PIPE: {
		    inputFileName = (char *) ((WinPipe *) inputFile)->fileName;
		    break;
		}
	    }
	}
	if (inputFileName == NULL) {
	    inputFileName = "nul";
	}
	if (outputFile != NULL) {
	    filePtr = (WinFile *) outputFile;
	    if (filePtr->type == WIN_FILE) {
		outputFileName = MakeTempFile(&outputTempFile);
		if (outputFileName == NULL) {
		    Tcl_AppendResult(interp, "couldn't duplicate output handle: ",
			    Tcl_PosixError(interp), (char *) NULL);
		    goto end32s;
		}
		outputHandle = filePtr->handle;
	    } else if (filePtr->type == WIN32S_PIPE) {
		outputFileName = (char *) ((WinPipe *) outputFile)->fileName;
	    }
	}
	if (outputFileName == NULL) {
	    outputFileName = "nul";
	}

	if (applType == APPL_DOS) {
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
	    args[0] = (DWORD) Tcl_DStringValue(&cmdLine);
	    trans[0] = &args[0];
	    trans[1] = NULL;
	    if (TclWinSynchSpawn(args, 1, trans, pidPtr) != 0) {
		result = TCL_OK;
	    }
	} else {
	    if (CreateProcess(NULL, Tcl_DStringValue(&cmdLine), NULL, NULL, 
		    FALSE, DETACHED_PROCESS, NULL, NULL, &startInfo, 
		    &procInfo) != 0) {
		CloseHandle(procInfo.hThread);
		while (1) {
		    if (GetExitCodeProcess(procInfo.hProcess, &status) == FALSE) {
			break;
		    }
		    if (status != STILL_ACTIVE) {
			break;
		    }
		    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == TRUE) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		    }
		}
		*pidPtr = (Tcl_Pid) procInfo.hProcess;
		if (*pidPtr != 0) {
		    ProcInfo *procPtr = (ProcInfo *) ckalloc(sizeof(ProcInfo));
		    procPtr->hProcess = procInfo.hProcess;
		    procPtr->dwProcessId = procInfo.dwProcessId;
		    procPtr->nextPtr = procList;
		    procList = procPtr;
		}
		result = TCL_OK;
	    }
	}
	if (result != TCL_OK) {
	    TclWinConvertError(GetLastError());
	    Tcl_AppendResult(interp, "couldn't execute \"", originalName,
		    "\": ", Tcl_PosixError(interp), (char *) NULL);
	}

	end32s:
	if (outputHandle != INVALID_HANDLE_VALUE) {
	    /*
	     * Now copy stuff from temp file to actual output handle. Don't
	     * close outputHandle because it is associated with the output
	     * file owned by the caller.
	     */

	    h = CreateFile(outputFileName, GENERIC_READ, 0, NULL, OPEN_ALWAYS,
		    0, NULL);
	    if (h != INVALID_HANDLE_VALUE) {
		CopyChannel(outputHandle, h);
	    }
	    CloseHandle(h);
	}

	if (inputFileName == Tcl_DStringValue(&inputTempFile)) {
	    DeleteFile(inputFileName);
	}
	
	if (outputFileName == Tcl_DStringValue(&outputTempFile)) {
	    DeleteFile(outputFileName);
	}

	Tcl_DStringFree(&inputTempFile);
	Tcl_DStringFree(&outputTempFile);
        Tcl_DStringFree(&cmdLine);
	return result;
    }







|
|
|















<
<
|
<
<






|











|








|



|







1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164


1165


1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
	    args[0] = (DWORD) Tcl_DStringValue(&cmdLine);
	    trans[0] = &args[0];
	    trans[1] = NULL;
	    if (TclWinSynchSpawn(args, 1, trans, pidPtr) != 0) {
		result = TCL_OK;
	    }
	} else {
	    if (CreateProcessA(NULL, Tcl_DStringValue(&cmdLine), 
		    NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, 
		    &startInfo, &procInfo) != 0) {
		CloseHandle(procInfo.hThread);
		while (1) {
		    if (GetExitCodeProcess(procInfo.hProcess, &status) == FALSE) {
			break;
		    }
		    if (status != STILL_ACTIVE) {
			break;
		    }
		    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == TRUE) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		    }
		}
		*pidPtr = (Tcl_Pid) procInfo.hProcess;
		if (*pidPtr != 0) {


		    TclWinAddProcess(procInfo.hProcess, procInfo.dwProcessId);


		}
		result = TCL_OK;
	    }
	}
	if (result != TCL_OK) {
	    TclWinConvertError(GetLastError());
	    Tcl_AppendResult(interp, "couldn't execute \"", argv[0],
		    "\": ", Tcl_PosixError(interp), (char *) NULL);
	}

	end32s:
	if (outputHandle != INVALID_HANDLE_VALUE) {
	    /*
	     * Now copy stuff from temp file to actual output handle. Don't
	     * close outputHandle because it is associated with the output
	     * file owned by the caller.
	     */

	    h = CreateFileA(outputFileName, GENERIC_READ, 0, NULL, OPEN_ALWAYS,
		    0, NULL);
	    if (h != INVALID_HANDLE_VALUE) {
		CopyChannel(outputHandle, h);
	    }
	    CloseHandle(h);
	}

	if (inputFileName == Tcl_DStringValue(&inputTempFile)) {
	    DeleteFileA(inputFileName);
	}
	
	if (outputFileName == Tcl_DStringValue(&outputTempFile)) {
	    DeleteFileA(outputFileName);
	}

	Tcl_DStringFree(&inputTempFile);
	Tcl_DStringFree(&outputTempFile);
        Tcl_DStringFree(&cmdLine);
	return result;
    }
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174

	if ((TclWinGetPlatformId() == VER_PLATFORM_WIN32_WINDOWS) 
		&& (applType == APPL_DOS)) {
	    if (CreatePipe(&h, &startInfo.hStdOutput, &secAtts, 0) != FALSE) {
		CloseHandle(h);
	    }
	} else {
	    startInfo.hStdOutput = CreateFile("NUL:", GENERIC_WRITE, 0,
		    &secAtts, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	}
    } else {
	DuplicateHandle(hProcess, outputHandle, hProcess, &startInfo.hStdOutput, 
		0, TRUE, DUPLICATE_SAME_ACCESS);
    }
    if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) {
	TclWinConvertError(GetLastError());
	Tcl_AppendResult(interp, "couldn't duplicate output handle: ",
		Tcl_PosixError(interp), (char *) NULL);
	goto end;
    }

    if (errorHandle == INVALID_HANDLE_VALUE) {
	/*
	 * If handle was not set, errors should be sent to an infinitely
	 * deep sink.
	 */

	startInfo.hStdError = CreateFile("NUL:", GENERIC_WRITE, 0,
		&secAtts, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    } else {
	DuplicateHandle(hProcess, errorHandle, hProcess, &startInfo.hStdError, 
		0, TRUE, DUPLICATE_SAME_ACCESS);
    } 
    if (startInfo.hStdError == INVALID_HANDLE_VALUE) {
	TclWinConvertError(GetLastError());







|



















|







1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334

	if ((TclWinGetPlatformId() == VER_PLATFORM_WIN32_WINDOWS) 
		&& (applType == APPL_DOS)) {
	    if (CreatePipe(&h, &startInfo.hStdOutput, &secAtts, 0) != FALSE) {
		CloseHandle(h);
	    }
	} else {
	    startInfo.hStdOutput = CreateFileA("NUL:", GENERIC_WRITE, 0,
		    &secAtts, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	}
    } else {
	DuplicateHandle(hProcess, outputHandle, hProcess, &startInfo.hStdOutput, 
		0, TRUE, DUPLICATE_SAME_ACCESS);
    }
    if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) {
	TclWinConvertError(GetLastError());
	Tcl_AppendResult(interp, "couldn't duplicate output handle: ",
		Tcl_PosixError(interp), (char *) NULL);
	goto end;
    }

    if (errorHandle == INVALID_HANDLE_VALUE) {
	/*
	 * If handle was not set, errors should be sent to an infinitely
	 * deep sink.
	 */

	startInfo.hStdError = CreateFileA("NUL:", GENERIC_WRITE, 0,
		&secAtts, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    } else {
	DuplicateHandle(hProcess, errorHandle, hProcess, &startInfo.hStdError, 
		0, TRUE, DUPLICATE_SAME_ACCESS);
    } 
    if (startInfo.hStdError == INVALID_HANDLE_VALUE) {
	TclWinConvertError(GetLastError());
1271
1272
1273
1274
1275
1276
1277
1278
1279

1280
1281
1282
1283
1284
1285
1286
1287





1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
     * delimiters and backslashes only as paths.
     *
     * Additionally, when calling a 16-bit dos or windows application, 
     * all path names must use the short, cryptic, path format (e.g., 
     * using ab~1.def instead of "a b.default").  
     */

    BuildCommandLine(argc, argv, &cmdLine);


    if (!CreateProcess(NULL, Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE, 
	    createFlags, NULL, NULL, &startInfo, &procInfo)) {
	TclWinConvertError(GetLastError());
	Tcl_AppendResult(interp, "couldn't execute \"", originalName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	goto end;
    }






    if (applType == APPL_DOS) {
	WaitForSingleObject(hProcess, 50);
    }

    /* 
     * "When an application spawns a process repeatedly, a new thread 
     * instance will be created for each process but the previous 
     * instances may not be cleaned up.  This results in a significant 
     * virtual memory loss each time the process is spawned.  If there 
     * is a WaitForInputIdle() call between CreateProcess() and
     * CloseHandle(), the problem does not occur." PSS ID Number: Q124121
     */

    WaitForInputIdle(procInfo.hProcess, 5000);
    CloseHandle(procInfo.hThread);

    *pidPtr = (Tcl_Pid) procInfo.hProcess;
    if (*pidPtr != 0) {
	ProcInfo *procPtr = (ProcInfo *) ckalloc(sizeof(ProcInfo));
	procPtr->hProcess = procInfo.hProcess;
	procPtr->dwProcessId = procInfo.dwProcessId;
	procPtr->nextPtr = procList;
	procList = procPtr;
    }
    result = TCL_OK;

    end:
    Tcl_DStringFree(&cmdLine);
    if (startInfo.hStdInput != INVALID_HANDLE_VALUE) {
        CloseHandle(startInfo.hStdInput);







|

>
|
|

|




>
>
>
>
>


















<
<
|
<
<







1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471


1472


1473
1474
1475
1476
1477
1478
1479
     * delimiters and backslashes only as paths.
     *
     * Additionally, when calling a 16-bit dos or windows application, 
     * all path names must use the short, cryptic, path format (e.g., 
     * using ab~1.def instead of "a b.default").  
     */

    BuildCommandLine(execPath, argc, argv, &cmdLine);

    if ((*tclWinProcs->createProcessProc)(NULL, 
	    (TCHAR *) Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE, 
	    createFlags, NULL, NULL, &startInfo, &procInfo) == 0) {
	TclWinConvertError(GetLastError());
	Tcl_AppendResult(interp, "couldn't execute \"", argv[0],
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	goto end;
    }

    /*
     * This wait is used to force the OS to give some time to the DOS
     * process.
     */

    if (applType == APPL_DOS) {
	WaitForSingleObject(hProcess, 50);
    }

    /* 
     * "When an application spawns a process repeatedly, a new thread 
     * instance will be created for each process but the previous 
     * instances may not be cleaned up.  This results in a significant 
     * virtual memory loss each time the process is spawned.  If there 
     * is a WaitForInputIdle() call between CreateProcess() and
     * CloseHandle(), the problem does not occur." PSS ID Number: Q124121
     */

    WaitForInputIdle(procInfo.hProcess, 5000);
    CloseHandle(procInfo.hThread);

    *pidPtr = (Tcl_Pid) procInfo.hProcess;
    if (*pidPtr != 0) {


	TclWinAddProcess(procInfo.hProcess, procInfo.dwProcessId);


    }
    result = TCL_OK;

    end:
    Tcl_DStringFree(&cmdLine);
    if (startInfo.hStdInput != INVALID_HANDLE_VALUE) {
        CloseHandle(startInfo.hStdInput);
1342
1343
1344
1345
1346
1347
1348


1349
1350
1351
1352
1353
1354
1355
1356
 *
 *----------------------------------------------------------------------
 */

static BOOL
HasConsole()
{


    HANDLE handle = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE,
	    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (handle != INVALID_HANDLE_VALUE) {
        CloseHandle(handle);
	return TRUE;
    } else {
        return FALSE;







>
>
|







1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
 *
 *----------------------------------------------------------------------
 */

static BOOL
HasConsole()
{
    HANDLE handle;
    
    handle = CreateFileA("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE,
	    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (handle != INVALID_HANDLE_VALUE) {
        CloseHandle(handle);
	return TRUE;
    } else {
        return FALSE;
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404

1405
1406
1407
1408



1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424




1425
1426

1427







1428
1429
1430
1431
1432
1433
1434
1435

1436
1437
1438


1439
1440
1441
1442
1443
1444
1445

1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ApplicationType(interp, originalName, fullPath)
    Tcl_Interp *interp;		/* Interp, for error message. */
    const char *originalName;	/* Name of the application to find. */
    char fullPath[MAX_PATH];	/* Filled with complete path to 
				 * application. */
{
    int applType, i;
    HANDLE hFile;

    char *ext, *rest;
    char buf[2];
    DWORD read;
    IMAGE_DOS_HEADER header;



    static char extensions[][5] = {"", ".com", ".exe", ".bat"};

    /* Look for the program as an external program.  First try the name
     * as it is, then try adding .com, .exe, and .bat, in that order, to
     * the name, looking for an executable.
     *
     * Using the raw SearchPath() procedure doesn't do quite what is 
     * necessary.  If the name of the executable already contains a '.' 
     * character, it will not try appending the specified extension when
     * searching (in other words, SearchPath will not find the program 
     * "a.b.exe" if the arguments specified "a.b" and ".exe").   
     * So, first look for the file as it is named.  Then manually append 
     * the extensions, looking for a match.  
     */

    applType = APPL_NONE;




    for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) {
	lstrcpyn(fullPath, originalName, MAX_PATH - 5);

        lstrcat(fullPath, extensions[i]);







	
	SearchPath(NULL, fullPath, NULL, MAX_PATH, fullPath, &rest);

	/*
	 * Ignore matches on directories or data files, return if identified
	 * a known type.
	 */


	if (GetFileAttributes(fullPath) & FILE_ATTRIBUTE_DIRECTORY) {
	    continue;
	}



	ext = strrchr(fullPath, '.');
	if ((ext != NULL) && (strcmpi(ext, ".bat") == 0)) {
	    applType = APPL_DOS;
	    break;
	}


	hFile = CreateFile(fullPath, GENERIC_READ, FILE_SHARE_READ, NULL, 
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE) {
	    continue;
	}

	header.e_magic = 0;
	ReadFile(hFile, (void *) &header, sizeof(header), &read, NULL);
	if (header.e_magic != IMAGE_DOS_SIGNATURE) {
	    /* 
	     * Doesn't have the magic number for relocatable executables.  If 
	     * filename ends with .com, assume it's a DOS application anyhow.
	     * Note that we didn't make this assumption at first, because some
	     * supposed .com files are really 32-bit executables with all the
	     * magic numbers and everything.  
	     */

	    CloseHandle(hFile);
	    if ((ext != NULL) && (strcmpi(ext, ".com") == 0)) {
		applType = APPL_DOS;
		break;
	    }
	    continue;
	}
	if (header.e_lfarlc != sizeof(header)) {
	    /* 







|


|


|

>
|

|

>
>
>
















>
>
>
>

<
>
|
>
>
>
>
>
>
>
|
<






>
|


>
>

|
|



|
>
|
|
















|







1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597

1598
1599
1600
1601
1602
1603
1604
1605
1606
1607

1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ApplicationType(interp, originalName, fullName)
    Tcl_Interp *interp;		/* Interp, for error message. */
    const char *originalName;	/* Name of the application to find. */
    char fullName[];		/* Filled with complete path to 
				 * application. */
{
    int applType, i, nameLen, found;
    HANDLE hFile;
    TCHAR *rest;
    char *ext;
    char buf[2];
    DWORD attr, read;
    IMAGE_DOS_HEADER header;
    Tcl_DString nameBuf, ds;
    TCHAR *nativeName;
    WCHAR nativeFullPath[MAX_PATH];
    static char extensions[][5] = {"", ".com", ".exe", ".bat"};

    /* Look for the program as an external program.  First try the name
     * as it is, then try adding .com, .exe, and .bat, in that order, to
     * the name, looking for an executable.
     *
     * Using the raw SearchPath() procedure doesn't do quite what is 
     * necessary.  If the name of the executable already contains a '.' 
     * character, it will not try appending the specified extension when
     * searching (in other words, SearchPath will not find the program 
     * "a.b.exe" if the arguments specified "a.b" and ".exe").   
     * So, first look for the file as it is named.  Then manually append 
     * the extensions, looking for a match.  
     */

    applType = APPL_NONE;
    Tcl_DStringInit(&nameBuf);
    Tcl_DStringAppend(&nameBuf, originalName, -1);
    nameLen = Tcl_DStringLength(&nameBuf);

    for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) {

	Tcl_DStringSetLength(&nameBuf, nameLen);
	Tcl_DStringAppend(&nameBuf, extensions[i], -1);
        nativeName = Tcl_WinUtfToTChar(Tcl_DStringValue(&nameBuf), 
		Tcl_DStringLength(&nameBuf), &ds);
	found = (*tclWinProcs->searchPathProc)(NULL, nativeName, NULL, 
		MAX_PATH, nativeFullPath, &rest);
	Tcl_DStringFree(&ds);
	if (found == 0) {
	    continue;
	}


	/*
	 * Ignore matches on directories or data files, return if identified
	 * a known type.
	 */

	attr = (*tclWinProcs->getFileAttributesProc)((TCHAR *) nativeFullPath);
	if ((attr == 0xffffffff) || (attr & FILE_ATTRIBUTE_DIRECTORY)) {
	    continue;
	}
	strcpy(fullName, Tcl_WinTCharToUtf((TCHAR *) nativeFullPath, -1, &ds));
	Tcl_DStringFree(&ds);

	ext = strrchr(fullName, '.');
	if ((ext != NULL) && (stricmp(ext, ".bat") == 0)) {
	    applType = APPL_DOS;
	    break;
	}
	
	hFile = (*tclWinProcs->createFileProc)((TCHAR *) nativeFullPath, 
		GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 
		FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE) {
	    continue;
	}

	header.e_magic = 0;
	ReadFile(hFile, (void *) &header, sizeof(header), &read, NULL);
	if (header.e_magic != IMAGE_DOS_SIGNATURE) {
	    /* 
	     * Doesn't have the magic number for relocatable executables.  If 
	     * filename ends with .com, assume it's a DOS application anyhow.
	     * Note that we didn't make this assumption at first, because some
	     * supposed .com files are really 32-bit executables with all the
	     * magic numbers and everything.  
	     */

	    CloseHandle(hFile);
	    if ((ext != NULL) && (strcmp(ext, ".com") == 0)) {
		applType = APPL_DOS;
		break;
	    }
	    continue;
	}
	if (header.e_lfarlc != sizeof(header)) {
	    /* 
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
	     * compiled using the Lahey Fortran90 compiler.
	     */

	    applType = APPL_DOS;
	}
	break;
    }


    if (applType == APPL_NONE) {
	TclWinConvertError(GetLastError());
	Tcl_AppendResult(interp, "couldn't execute \"", originalName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	return APPL_NONE;
    }

    if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) {
	/* 
	 * Replace long path name of executable with short path name for 
	 * 16-bit applications.  Otherwise the application may not be able
	 * to correctly parse its own command line to separate off the 
	 * application name from the arguments.
	 */


	GetShortPathName(fullPath, fullPath, MAX_PATH);


    }
    return applType;
}

/*    
 *----------------------------------------------------------------------
 *







>
















>
|
>
>







1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
	     * compiled using the Lahey Fortran90 compiler.
	     */

	    applType = APPL_DOS;
	}
	break;
    }
    Tcl_DStringFree(&nameBuf);

    if (applType == APPL_NONE) {
	TclWinConvertError(GetLastError());
	Tcl_AppendResult(interp, "couldn't execute \"", originalName,
		"\": ", Tcl_PosixError(interp), (char *) NULL);
	return APPL_NONE;
    }

    if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) {
	/* 
	 * Replace long path name of executable with short path name for 
	 * 16-bit applications.  Otherwise the application may not be able
	 * to correctly parse its own command line to separate off the 
	 * application name from the arguments.
	 */

	(*tclWinProcs->getShortPathNameProc)((TCHAR *) nativeFullPath, 
		nativeFullPath, MAX_PATH);
	strcpy(fullName, Tcl_WinTCharToUtf((TCHAR *) nativeFullPath, -1, &ds));
	Tcl_DStringFree(&ds);
    }
    return applType;
}

/*    
 *----------------------------------------------------------------------
 *
1542
1543
1544
1545
1546
1547
1548
1549


1550
1551
1552
1553
1554
1555
1556

1557


1558
1559



1560
1561
1562
1563



1564
1565
1566
1567
1568
1569
1570
1571




1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610


1611
1612
1613
1614
1615
1616
1617
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
BuildCommandLine(argc, argv, linePtr)


    int argc;			/* Number of arguments. */
    char **argv;		/* Argument strings. */
    Tcl_DString *linePtr;	/* Initialized Tcl_DString that receives the
				 * command line. */
{
    char *start, *special;
    int quote, i;




    for (i = 0; i < argc; i++) {
	if (i > 0) {



	    Tcl_DStringAppend(linePtr, " ", 1);	
	}

	quote = 0;



	for (start = argv[i]; *start != '\0'; start++) {
	    if (isspace(*start)) {
		quote = 1;
		Tcl_DStringAppend(linePtr, "\"", 1);
    		break;
	    }
	}





	start = argv[i];	    
	for (special = argv[i]; ; ) {
	    if ((*special == '\\') && 
		    (special[1] == '\\' || special[1] == '"')) {
		Tcl_DStringAppend(linePtr, start, special - start);
		start = special;
		while (1) {
		    special++;
		    if (*special == '"') {
			/* 
			 * N backslashes followed a quote -> insert 
			 * N * 2 + 1 backslashes then a quote.
			 */

			Tcl_DStringAppend(linePtr, start, special - start);
			break;
		    }
		    if (*special != '\\') {
			break;
		    }
		}
		Tcl_DStringAppend(linePtr, start, special - start);
		start = special;
	    }
	    if (*special == '"') {
		Tcl_DStringAppend(linePtr, start, special - start);
		Tcl_DStringAppend(linePtr, "\\\"", 2);
		start = special + 1;
	    }
	    if (*special == '\0') {
		break;
	    }
	    special++;
	}
	Tcl_DStringAppend(linePtr, start, special - start);
	if (quote) {
	    Tcl_DStringAppend(linePtr, "\"", 1);
	}
    }


}

/*
 *----------------------------------------------------------------------
 *
 * MakeTempFile --
 *







|
>
>
|
|
|
|

|

>

>
>

|
>
>
>
|



>
>
>
|
|
|
<
|
|
|
|
>
>
>
>
|
|


|









|






|



|
|







|

|


>
>







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
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
BuildCommandLine(
    CONST char *executable,	/* Full path of executable (including 
				 * extension).  Replacement for argv[0]. */
    int argc,			/* Number of arguments. */
    char **argv,		/* Argument strings in UTF. */
    Tcl_DString *linePtr)	/* Initialized Tcl_DString that receives the
				 * command line (TCHAR). */
{
    CONST char *arg, *start, *special;
    int quote, i;
    Tcl_DString ds;

    Tcl_DStringInit(&ds);

    for (i = 0; i < argc; i++) {
	if (i == 0) {
	    arg = executable;
	} else {
	    arg = argv[i];
	    Tcl_DStringAppend(&ds, " ", 1);
	}

	quote = 0;
	if (argv[i][0] == '\0') {
	    quote = 1;
	} else {
	    for (start = argv[i]; *start != '\0'; start++) {
		if (isspace(*start)) { /* INTL: ISO space. */
		    quote = 1;

		    break;
		}
	    }
	}
	if (quote) {
	    Tcl_DStringAppend(&ds, "\"", 1);
	}

	start = arg;	    
	for (special = arg; ; ) {
	    if ((*special == '\\') && 
		    (special[1] == '\\' || special[1] == '"')) {
		Tcl_DStringAppend(&ds, start, special - start);
		start = special;
		while (1) {
		    special++;
		    if (*special == '"') {
			/* 
			 * N backslashes followed a quote -> insert 
			 * N * 2 + 1 backslashes then a quote.
			 */

			Tcl_DStringAppend(&ds, start, special - start);
			break;
		    }
		    if (*special != '\\') {
			break;
		    }
		}
		Tcl_DStringAppend(&ds, start, special - start);
		start = special;
	    }
	    if (*special == '"') {
		Tcl_DStringAppend(&ds, start, special - start);
		Tcl_DStringAppend(&ds, "\\\"", 2);
		start = special + 1;
	    }
	    if (*special == '\0') {
		break;
	    }
	    special++;
	}
	Tcl_DStringAppend(&ds, start, special - start);
	if (quote) {
	    Tcl_DStringAppend(&ds, "\"", 1);
	}
    }
    Tcl_WinUtfToTChar(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), linePtr);
    Tcl_DStringFree(&ds);
}

/*
 *----------------------------------------------------------------------
 *
 * MakeTempFile --
 *
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
MakeTempFile(namePtr)
    Tcl_DString *namePtr;	/* Initialized Tcl_DString that is filled 
				 * with the name of the temporary file that 
				 * was created. */
{
    char name[MAX_PATH];

    if (TempFileName(name) == 0) {
	return NULL;
    }

    Tcl_DStringAppend(namePtr, name, -1);
    return Tcl_DStringValue(namePtr);
}








|







1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
MakeTempFile(namePtr)
    Tcl_DString *namePtr;	/* Initialized Tcl_DString that is filled 
				 * with the name of the temporary file that 
				 * was created. */
{
    char name[MAX_PATH];

    if (TempFileName((WCHAR *) name) == 0) {
	return NULL;
    }

    Tcl_DStringAppend(namePtr, name, -1);
    return Tcl_DStringValue(namePtr);
}

1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
CopyChannel(dst, src)
    HANDLE dst;			/* Destination file. */
    HANDLE src;			/* Source file. */
{
    char buf[8192];
    DWORD dwRead, dwWrite;

    while (ReadFile(src, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
	if (dwRead == 0) {
	    break;







|
|
|







1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
CopyChannel(
    HANDLE dst,			/* Destination file. */
    HANDLE src)			/* Source file. */
{
    char buf[8192];
    DWORD dwRead, dwWrite;

    while (ReadFile(src, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
	if (dwRead == 0) {
	    break;
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715

1716


1717



1718
1719



1720

1721
1722
1723

1724
1725
1726
1727
1728



1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751



1752













1753


1754
1755













1756
1757
1758
1759
1760
1761
1762


1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
 * Side effects:
 *	Allocates a new channel.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclpCreateCommandChannel(readFile, writeFile, errorFile, numPids, pidPtr)
    TclFile readFile;		/* If non-null, gives the file for reading. */
    TclFile writeFile;		/* If non-null, gives the file for writing. */
    TclFile errorFile;		/* If non-null, gives the file where errors
				 * can be read. */
    int numPids;		/* The number of pids in the pid array. */
    Tcl_Pid *pidPtr;		/* An array of process identifiers. */
{
    char channelName[20];
    int channelId;

    PipeInfo *infoPtr = (PipeInfo *) ckalloc((unsigned) sizeof(PipeInfo));






    if (!initialized) {
	PipeInit();



    }


    infoPtr->watchMask = 0;
    infoPtr->flags = 0;

    infoPtr->readFile = readFile;
    infoPtr->writeFile = writeFile;
    infoPtr->errorFile = errorFile;
    infoPtr->numPids = numPids;
    infoPtr->pidPtr = pidPtr;




    /*
     * Use one of the fds associated with the channel as the
     * channel id.
     */

    if (readFile) {
	WinPipe *pipePtr = (WinPipe *) readFile;
	if (pipePtr->file.type == WIN32S_PIPE
		&& pipePtr->file.handle == INVALID_HANDLE_VALUE) {
	    pipePtr->file.handle = CreateFile(pipePtr->fileName, GENERIC_READ,
		    0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	}
	channelId = (int) pipePtr->file.handle;
    } else if (writeFile) {
	channelId = (int) ((WinFile*)writeFile)->handle;
    } else if (errorFile) {
	channelId = (int) ((WinFile*)errorFile)->handle;
    } else {
	channelId = 0;
    }

    infoPtr->validMask = 0;



    if (readFile != NULL) {













        infoPtr->validMask |= TCL_READABLE;


    }
    if (writeFile != NULL) {













        infoPtr->validMask |= TCL_WRITABLE;
    }

    /*
     * For backward compatibility with previous versions of Tcl, we
     * use "file%d" as the base name for pipes even though it would
     * be more natural to use "pipe%d".


     */

    sprintf(channelName, "file%d", channelId);
    infoPtr->channel = Tcl_CreateChannel(&pipeChannelType, channelName,
            (ClientData) infoPtr, infoPtr->validMask);

    /*
     * Pipes have AUTO translation mode on Windows and ^Z eof char, which
     * means that a ^Z will be appended to them at close. This is needed
     * for Windows programs that expect a ^Z at EOF.







|
|
|
|

|
|

|

>

>
>

>
>
>
|
<
>
>
>
|
>



>





>
>
>










|












>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>

>
>


>
>
>
>
>
>
>
>
>
>
>
>
>







>
>


|







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
1971
1972
1973
1974
1975
1976
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
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
 * Side effects:
 *	Allocates a new channel.
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclpCreateCommandChannel(
    TclFile readFile,		/* If non-null, gives the file for reading. */
    TclFile writeFile,		/* If non-null, gives the file for writing. */
    TclFile errorFile,		/* If non-null, gives the file where errors
				 * can be read. */
    int numPids,		/* The number of pids in the pid array. */
    Tcl_Pid *pidPtr)		/* An array of process identifiers. */
{
    char channelName[16 + TCL_INTEGER_SPACE];
    int channelId;
    DWORD id;
    PipeInfo *infoPtr = (PipeInfo *) ckalloc((unsigned) sizeof(PipeInfo));
    OSVERSIONINFO os;
    int useThreads;

    /*
     * Fetch the OS version info.
     */


    os.dwOSVersionInfoSize = sizeof(os);
    GetVersionEx(&os);
    useThreads = (os.dwPlatformId != VER_PLATFORM_WIN32s);

    PipeInit();

    infoPtr->watchMask = 0;
    infoPtr->flags = 0;
    infoPtr->readFlags = 0;
    infoPtr->readFile = readFile;
    infoPtr->writeFile = writeFile;
    infoPtr->errorFile = errorFile;
    infoPtr->numPids = numPids;
    infoPtr->pidPtr = pidPtr;
    infoPtr->writeBuf = 0;
    infoPtr->writeBufLen = 0;
    infoPtr->writeError = 0;

    /*
     * Use one of the fds associated with the channel as the
     * channel id.
     */

    if (readFile) {
	WinPipe *pipePtr = (WinPipe *) readFile;
	if (pipePtr->file.type == WIN32S_PIPE
		&& pipePtr->file.handle == INVALID_HANDLE_VALUE) {
	    pipePtr->file.handle = CreateFileA(pipePtr->fileName, GENERIC_READ,
		    0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	}
	channelId = (int) pipePtr->file.handle;
    } else if (writeFile) {
	channelId = (int) ((WinFile*)writeFile)->handle;
    } else if (errorFile) {
	channelId = (int) ((WinFile*)errorFile)->handle;
    } else {
	channelId = 0;
    }

    infoPtr->validMask = 0;

    infoPtr->threadId = Tcl_GetCurrentThread();

    if (readFile != NULL) {
	if (useThreads) {
	    /*
	     * Start the background reader thread.
	     */

	    infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL);
	    infoPtr->startReader = CreateEvent(NULL, FALSE, FALSE, NULL);
	    infoPtr->readThread = CreateThread(NULL, 8000, PipeReaderThread,
		    infoPtr, 0, &id);
	    SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); 
	} else {
	    infoPtr->readThread = 0;
	}
        infoPtr->validMask |= TCL_READABLE;
    } else {
	infoPtr->readThread = 0;
    }
    if (writeFile != NULL) {
	if (useThreads) {
	    /*
	     * Start the background writeer thwrite.
	     */

	    infoPtr->writable = CreateEvent(NULL, TRUE, TRUE, NULL);
	    infoPtr->startWriter = CreateEvent(NULL, FALSE, FALSE, NULL);
	    infoPtr->writeThread = CreateThread(NULL, 8000, PipeWriterThread,
		    infoPtr, 0, &id);
	    SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); 
	} else {
	    infoPtr->writeThread = 0;
	}
        infoPtr->validMask |= TCL_WRITABLE;
    }

    /*
     * For backward compatibility with previous versions of Tcl, we
     * use "file%d" as the base name for pipes even though it would
     * be more natural to use "pipe%d".
     * Use the pointer to keep the channel names unique, in case
     * channels share handles (stdin/stdout).
     */

    wsprintfA(channelName, "file%lx", infoPtr);
    infoPtr->channel = Tcl_CreateChannel(&pipeChannelType, channelName,
            (ClientData) infoPtr, infoPtr->validMask);

    /*
     * Pipes have AUTO translation mode on Windows and ^Z eof char, which
     * means that a ^Z will be appended to them at close. This is needed
     * for Windows programs that expect a ^Z at EOF.
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827

/*
 *----------------------------------------------------------------------
 *
 * TclGetAndDetachPids --
 *
 *	Stores a list of the command PIDs for a command channel in
 *	interp->result.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Modifies interp->result.
 *
 *----------------------------------------------------------------------
 */

void
TclGetAndDetachPids(interp, chan)
    Tcl_Interp *interp;
    Tcl_Channel chan;
{
    PipeInfo *pipePtr;
    Tcl_ChannelType *chanTypePtr;
    int i;
    char buf[20];

    /*
     * Punt if the channel is not a command channel.
     */

    chanTypePtr = Tcl_GetChannelType(chan);
    if (chanTypePtr != &pipeChannelType) {
        return;
    }

    pipePtr = (PipeInfo *) Tcl_GetChannelInstanceData(chan);
    for (i = 0; i < pipePtr->numPids; i++) {
        sprintf(buf, "%lu", TclpGetPid(pipePtr->pidPtr[i]));
        Tcl_AppendElement(interp, buf);
        Tcl_DetachPids(1, &(pipePtr->pidPtr[i]));
    }
    if (pipePtr->numPids > 0) {
        ckfree((char *) pipePtr->pidPtr);
        pipePtr->numPids = 0;
    }







|





|





|
|
|




|












|







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
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075

/*
 *----------------------------------------------------------------------
 *
 * TclGetAndDetachPids --
 *
 *	Stores a list of the command PIDs for a command channel in
 *	the interp's result.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Modifies the interp's result.
 *
 *----------------------------------------------------------------------
 */

void
TclGetAndDetachPids(
    Tcl_Interp *interp,
    Tcl_Channel chan)
{
    PipeInfo *pipePtr;
    Tcl_ChannelType *chanTypePtr;
    int i;
    char buf[TCL_INTEGER_SPACE];

    /*
     * Punt if the channel is not a command channel.
     */

    chanTypePtr = Tcl_GetChannelType(chan);
    if (chanTypePtr != &pipeChannelType) {
        return;
    }

    pipePtr = (PipeInfo *) Tcl_GetChannelInstanceData(chan);
    for (i = 0; i < pipePtr->numPids; i++) {
        wsprintfA(buf, "%lu", TclpGetPid(pipePtr->pidPtr[i]));
        Tcl_AppendElement(interp, buf);
        Tcl_DetachPids(1, &(pipePtr->pidPtr[i]));
    }
    if (pipePtr->numPids > 0) {
        ckfree((char *) pipePtr->pidPtr);
        pipePtr->numPids = 0;
    }
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
 * Side effects:
 *	Sets the device into blocking or non-blocking mode.
 *
 *----------------------------------------------------------------------
 */

static int
PipeBlockModeProc(instanceData, mode)
    ClientData instanceData;	/* Instance data for channel. */
    int mode;			/* TCL_MODE_BLOCKING or
                                 * TCL_MODE_NONBLOCKING. */
{
    PipeInfo *infoPtr = (PipeInfo *) instanceData;
    
    /*
     * Pipes on Windows can not be switched between blocking and nonblocking,
     * hence we have to emulate the behavior. This is done in the input







|
|
|







2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
 * Side effects:
 *	Sets the device into blocking or non-blocking mode.
 *
 *----------------------------------------------------------------------
 */

static int
PipeBlockModeProc(
    ClientData instanceData,	/* Instance data for channel. */
    int mode)			/* TCL_MODE_BLOCKING or
                                 * TCL_MODE_NONBLOCKING. */
{
    PipeInfo *infoPtr = (PipeInfo *) instanceData;
    
    /*
     * Pipes on Windows can not be switched between blocking and nonblocking,
     * hence we have to emulate the behavior. This is done in the input
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
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
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * PipeCloseProc --
 *
 *	Closes a pipe based IO channel.
 *
 * Results:
 *	0 on success, errno otherwise.
 *
 * Side effects:
 *	Closes the physical channel.
 *
 *----------------------------------------------------------------------
 */

static int
PipeCloseProc(instanceData, interp)
    ClientData instanceData;	/* Pointer to PipeInfo structure. */
    Tcl_Interp *interp;		/* For error reporting. */

{
    PipeInfo *pipePtr = (PipeInfo *) instanceData;
    Tcl_Channel errChan;
    int errorCode, result;
    PipeInfo *infoPtr, **nextPtrPtr;



































































































    /*
     * Remove the file from the list of watched files.
     */


    for (nextPtrPtr = &firstPipePtr, infoPtr = *nextPtrPtr; infoPtr != NULL;
	    nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) {
	if (infoPtr == (PipeInfo *)pipePtr) {
	    *nextPtrPtr = infoPtr->nextPtr;
	    break;
	}
    }

    errorCode = 0;
    if (pipePtr->readFile != NULL) {
	if (TclpCloseFile(pipePtr->readFile) != 0) {
	    errorCode = errno;
	}
    }
    if (pipePtr->writeFile != NULL) {
	if (TclpCloseFile(pipePtr->writeFile) != 0) {
	    if (errorCode == 0) {
		errorCode = errno;
	    }
	}
    }
    
    /*
     * Wrap the error file into a channel and give it to the cleanup
     * routine.  If we are running in Win32s, just delete the error file
     * immediately, because it was never used.
     */

    if (pipePtr->errorFile) {
	WinFile *filePtr;
	OSVERSIONINFO os;

	os.dwOSVersionInfoSize = sizeof(os);
	GetVersionEx(&os);
	if (os.dwPlatformId == VER_PLATFORM_WIN32s) {
	    TclpCloseFile(pipePtr->errorFile);
	    errChan = NULL;
	} else {
	    filePtr = (WinFile*)pipePtr->errorFile;
	    errChan = Tcl_MakeFileChannel((ClientData) filePtr->handle,
		    TCL_READABLE);

	}
    } else {
        errChan = NULL;
    }

    result = TclCleanupChildren(interp, pipePtr->numPids, pipePtr->pidPtr,
            errChan);

    if (pipePtr->numPids > 0) {
        ckfree((char *) pipePtr->pidPtr);
    }





    ckfree((char*) pipePtr);

    if (errorCode == 0) {
        return result;
    }
    return errorCode;
}







|













|
|
|
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
|







<
<
<
<
<
<
<
<
<
<
<
<
<
<



















>




>


>



>
>
>
>
>







2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254














2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
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
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * PipeClose2Proc --
 *
 *	Closes a pipe based IO channel.
 *
 * Results:
 *	0 on success, errno otherwise.
 *
 * Side effects:
 *	Closes the physical channel.
 *
 *----------------------------------------------------------------------
 */

static int
PipeClose2Proc(
    ClientData instanceData,	/* Pointer to PipeInfo structure. */
    Tcl_Interp *interp,		/* For error reporting. */
    int flags)			/* Flags that indicate which side to close. */
{
    PipeInfo *pipePtr = (PipeInfo *) instanceData;
    Tcl_Channel errChan;
    int errorCode, result;
    PipeInfo *infoPtr, **nextPtrPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    errorCode = 0;
    if ((!flags || (flags == TCL_CLOSE_READ))
	    && (pipePtr->readFile != NULL)) {
	/*
	 * Clean up the background thread if necessary.  Note that this
	 * must be done before we can close the file, since the 
	 * thread may be blocking trying to read from the pipe.
	 */

	if (pipePtr->readThread) {
	    /*
	     * Forcibly terminate the background thread.  We cannot rely on the
	     * thread to cleanly terminate itself because we have no way of
	     * closing the pipe handle without blocking in the case where the
	     * thread is in the middle of an I/O operation.  Note that we need
	     * to guard against terminating the thread while it is in the
	     * middle of Tcl_ThreadAlert because it won't be able to release
	     * the notifier lock.
	     */

	    Tcl_MutexLock(&pipeMutex);
	    TerminateThread(pipePtr->readThread, 0);
	    Tcl_MutexUnlock(&pipeMutex);

	    /*
	     * Wait for the thread to terminate.  This ensures that we are
	     * completely cleaned up before we leave this function. 
	     */

	    WaitForSingleObject(pipePtr->readThread, INFINITE);
	    CloseHandle(pipePtr->readThread);
	    CloseHandle(pipePtr->readable);
	    CloseHandle(pipePtr->startReader);
	    pipePtr->readThread = NULL;
	}
	if (TclpCloseFile(pipePtr->readFile) != 0) {
	    errorCode = errno;
	}
	pipePtr->validMask &= ~TCL_READABLE;
	pipePtr->readFile = NULL;
    }
    if ((!flags || (flags & TCL_CLOSE_WRITE))
	    && (pipePtr->writeFile != NULL)) {
	/*
	 * Wait for the writer thread to finish the current buffer, then
	 * terminate the thread and close the handles.  If the channel is
	 * nonblocking, there should be no pending write operations.
	 */

	if (pipePtr->writeThread) {
	    WaitForSingleObject(pipePtr->writable, INFINITE);

	    /*
	     * Forcibly terminate the background thread.  We cannot rely on the
	     * thread to cleanly terminate itself because we have no way of
	     * closing the pipe handle without blocking in the case where the
	     * thread is in the middle of an I/O operation.  Note that we need
	     * to guard against terminating the thread while it is in the
	     * middle of Tcl_ThreadAlert because it won't be able to release
	     * the notifier lock.
	     */

	    Tcl_MutexLock(&pipeMutex);
	    TerminateThread(pipePtr->writeThread, 0);
	    Tcl_MutexUnlock(&pipeMutex);


	    /*
	     * Wait for the thread to terminate.  This ensures that we are
	     * completely cleaned up before we leave this function. 
	     */

	    WaitForSingleObject(pipePtr->writeThread, INFINITE);
	    CloseHandle(pipePtr->writeThread);
	    CloseHandle(pipePtr->writable);
	    CloseHandle(pipePtr->startWriter);
	    pipePtr->writeThread = NULL;
	}
	if (TclpCloseFile(pipePtr->writeFile) != 0) {
	    if (errorCode == 0) {
		errorCode = errno;
	    }
	}
	pipePtr->validMask &= ~TCL_WRITABLE;
	pipePtr->writeFile = NULL;
    }

    pipePtr->watchMask &= pipePtr->validMask;

    /*
     * Don't free the channel if any of the flags were set.
     */

    if (flags) {
	return errorCode;
    }

    /*
     * Remove the file from the list of watched files.
     */

    for (nextPtrPtr = &(tsdPtr->firstPipePtr), infoPtr = *nextPtrPtr;
	    infoPtr != NULL;
	    nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) {
	if (infoPtr == (PipeInfo *)pipePtr) {
	    *nextPtrPtr = infoPtr->nextPtr;
	    break;
	}
    }















    /*
     * Wrap the error file into a channel and give it to the cleanup
     * routine.  If we are running in Win32s, just delete the error file
     * immediately, because it was never used.
     */

    if (pipePtr->errorFile) {
	WinFile *filePtr;
	OSVERSIONINFO os;

	os.dwOSVersionInfoSize = sizeof(os);
	GetVersionEx(&os);
	if (os.dwPlatformId == VER_PLATFORM_WIN32s) {
	    TclpCloseFile(pipePtr->errorFile);
	    errChan = NULL;
	} else {
	    filePtr = (WinFile*)pipePtr->errorFile;
	    errChan = Tcl_MakeFileChannel((ClientData) filePtr->handle,
		    TCL_READABLE);
	    ckfree((char *) filePtr);
	}
    } else {
        errChan = NULL;
    }

    result = TclCleanupChildren(interp, pipePtr->numPids, pipePtr->pidPtr,
            errChan);

    if (pipePtr->numPids > 0) {
        ckfree((char *) pipePtr->pidPtr);
    }

    if (pipePtr->writeBuf != NULL) {
	ckfree(pipePtr->writeBuf);
    }

    ckfree((char*) pipePtr);

    if (errorCode == 0) {
        return result;
    }
    return errorCode;
}
1969
1970
1971
1972
1973
1974
1975
1976
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
2011

2012
2013
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
 * Side effects:
 *	Reads input from the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
PipeInputProc(instanceData, buf, bufSize, errorCode)
    ClientData instanceData;		/* Pipe state. */
    char *buf;				/* Where to store data read. */
    int bufSize;			/* How much space is available
                                         * in the buffer? */
    int *errorCode;			/* Where to store error code. */
{
    PipeInfo *infoPtr = (PipeInfo *) instanceData;
    WinFile *filePtr = (WinFile*) infoPtr->readFile;
    DWORD count;
    DWORD bytesRead;

    *errorCode = 0;
    if (filePtr->type == WIN32S_PIPE) {
	if (((WinPipe *)filePtr)->otherPtr != NULL) {
	    panic("PipeInputProc: child process isn't finished writing");
	}
	if (filePtr->handle == INVALID_HANDLE_VALUE) {
	    filePtr->handle = CreateFile(((WinPipe *)filePtr)->fileName,
		    GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
		    NULL);
	}
	if (filePtr->handle == INVALID_HANDLE_VALUE) {
	    goto error;
	}
    } else {
	/*
	 * Pipes will block until the requested number of bytes has been
	 * read.  To avoid blocking unnecessarily, we look ahead and only
	 * read as much as is available.
	 */

	if (PeekNamedPipe(filePtr->handle, (LPVOID) NULL, (DWORD) 0,
		(LPDWORD) NULL, &count, (LPDWORD) NULL) == TRUE) {
	    if ((count != 0) && ((DWORD) bufSize > count)) {
		bufSize = (int) count;


		/*
		 * This code is commented out because on Win95 we don't get
		 * notifier of eof on a pipe unless we try to read it.
		 * The correct solution is to move to threads.

		 */

/* 	    } else if ((count == 0) && (infoPtr->flags & PIPE_ASYNC)) { */
/* 		errno = *errorCode = EAGAIN; */
/* 		return -1; */
	    } else if ((count == 0) && !(infoPtr->flags & PIPE_ASYNC)) {
		bufSize = 1;
	    }
	} else {
	    goto error;
	}





    }






    /*
     * Note that we will block on reads from a console buffer until a
     * full line has been entered.  The only way I know of to get
     * around this is to write a console driver.  We should probably





     * do this at some point, but for now, we just block.




     */

    if (ReadFile(filePtr->handle, (LPVOID) buf, (DWORD) bufSize, &bytesRead,
            (LPOVERLAPPED) NULL) == FALSE) {

	goto error;



    }
    
    return bytesRead;


    error:
    TclWinConvertError(GetLastError());
    if (errno == EPIPE) {

	return 0;
    }
    *errorCode = errno;
    return -1;
}

/*







|
|
|
|

|



|
|







|








|
<
<


<
<
<
<
>

|
<
<
<
>
|

|
|
|
<
<
|
<
<
|
>
>
>
>
>
|
>
>
>
>
>

|
|
|
|
>
>
>
>
>
|
>
>
>
>


|
|
>
|
>
>
>
|
<
|
>




>







2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
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
 * Side effects:
 *	Reads input from the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
PipeInputProc(
    ClientData instanceData,		/* Pipe state. */
    char *buf,				/* Where to store data read. */
    int bufSize,			/* How much space is available
                                         * in the buffer? */
    int *errorCode)			/* Where to store error code. */
{
    PipeInfo *infoPtr = (PipeInfo *) instanceData;
    WinFile *filePtr = (WinFile*) infoPtr->readFile;
    DWORD count, bytesRead = 0;
    int result;

    *errorCode = 0;
    if (filePtr->type == WIN32S_PIPE) {
	if (((WinPipe *)filePtr)->otherPtr != NULL) {
	    panic("PipeInputProc: child process isn't finished writing");
	}
	if (filePtr->handle == INVALID_HANDLE_VALUE) {
	    filePtr->handle = CreateFileA(((WinPipe *)filePtr)->fileName,
		    GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
		    NULL);
	}
	if (filePtr->handle == INVALID_HANDLE_VALUE) {
	    goto error;
	}
    } else {
	/*
	 * Synchronize with the reader thread.


	 */





	result = WaitForRead(infoPtr, (infoPtr->flags & PIPE_ASYNC) ? 0 : 1);

	/*



	 * If an error occurred, return immediately.
	 */

	if (result == -1) {
	    *errorCode = errno;
	    return -1;


	}



	if (infoPtr->readFlags & PIPE_EXTRABYTE) {
	    /*
	     * The reader thread consumed 1 byte as a side effect of
	     * waiting so we need to move it into the buffer.
	     */

	    *buf = infoPtr->extraByte;
	    infoPtr->readFlags &= ~PIPE_EXTRABYTE;
	    buf++;
	    bufSize--;
	    bytesRead = 1;

	    /*
	     * If further read attempts would block, return what we have.
	     */

	    if (result == 0) {
		return bytesRead;
	    }
	}
    }

    /*
     * Attempt to read bufSize bytes.  The read will return immediately
     * if there is any data available.  Otherwise it will block until
     * at least one byte is available or an EOF occurs.
     */

    if (ReadFile(filePtr->handle, (LPVOID) buf, (DWORD) bufSize, &count,
	    (LPOVERLAPPED) NULL) == TRUE) {
	return bytesRead + count;
    } else if (bytesRead) {
	/*
	 * Ignore errors if we have data to return.
	 */


	return bytesRead;
    }

    error:
    TclWinConvertError(GetLastError());
    if (errno == EPIPE) {
	infoPtr->readFlags |= PIPE_EOF;
	return 0;
    }
    *errorCode = errno;
    return -1;
}

/*
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082

















































2083
2084
2085
2086


2087
2088

2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
 * Side effects:
 *	Writes output on the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
PipeOutputProc(instanceData, buf, toWrite, errorCode)
    ClientData instanceData;		/* Pipe state. */
    char *buf;				/* The data buffer. */
    int toWrite;			/* How many bytes to write? */
    int *errorCode;			/* Where to store error code. */
{
    PipeInfo *infoPtr = (PipeInfo *) instanceData;
    WinFile *filePtr = (WinFile*) infoPtr->writeFile;
    DWORD bytesWritten;
    
    *errorCode = 0;

















































    if (WriteFile(filePtr->handle, (LPVOID) buf, (DWORD) toWrite,
	    &bytesWritten, (LPOVERLAPPED) NULL) == FALSE) {
        TclWinConvertError(GetLastError());
        if (errno == EPIPE) {


            return 0;
        }

        *errorCode = errno;
        return -1;
    }
    return bytesWritten;
}

/*
 *----------------------------------------------------------------------
 *
 * PipeEventProc --
 *







|
|
|
|
|



|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
>
>
|
|
>
|
|
|
<







2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498

2499
2500
2501
2502
2503
2504
2505
 * Side effects:
 *	Writes output on the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
PipeOutputProc(
    ClientData instanceData,		/* Pipe state. */
    char *buf,				/* The data buffer. */
    int toWrite,			/* How many bytes to write? */
    int *errorCode)			/* Where to store error code. */
{
    PipeInfo *infoPtr = (PipeInfo *) instanceData;
    WinFile *filePtr = (WinFile*) infoPtr->writeFile;
    DWORD bytesWritten, timeout;
    
    *errorCode = 0;
    timeout = (infoPtr->flags & PIPE_ASYNC) ? 0 : INFINITE;
    if (WaitForSingleObject(infoPtr->writable, timeout) == WAIT_TIMEOUT) {
	/*
	 * The writer thread is blocked waiting for a write to complete
	 * and the channel is in non-blocking mode.
	 */

	errno = EAGAIN;
	goto error;
    }
    
    /*
     * Check for a background error on the last write.
     */

    if (infoPtr->writeError) {
	TclWinConvertError(infoPtr->writeError);
	infoPtr->writeError = 0;
	goto error;
    }

    if (infoPtr->flags & PIPE_ASYNC) {
	/*
	 * The pipe is non-blocking, so copy the data into the output
	 * buffer and restart the writer thread.
	 */

	if (toWrite > infoPtr->writeBufLen) {
	    /*
	     * Reallocate the buffer to be large enough to hold the data.
	     */

	    if (infoPtr->writeBuf) {
		ckfree(infoPtr->writeBuf);
	    }
	    infoPtr->writeBufLen = toWrite;
	    infoPtr->writeBuf = ckalloc(toWrite);
	}
	memcpy(infoPtr->writeBuf, buf, toWrite);
	infoPtr->toWrite = toWrite;
	ResetEvent(infoPtr->writable);
	SetEvent(infoPtr->startWriter);
	bytesWritten = toWrite;
    } else {
	/*
	 * In the blocking case, just try to write the buffer directly.
	 * This avoids an unnecessary copy.
	 */

	if (WriteFile(filePtr->handle, (LPVOID) buf, (DWORD) toWrite,
		&bytesWritten, (LPOVERLAPPED) NULL) == FALSE) {
	    TclWinConvertError(GetLastError());
	    goto error;
	}
    }
    return bytesWritten;

    error:
    *errorCode = errno;
    return -1;


}

/*
 *----------------------------------------------------------------------
 *
 * PipeEventProc --
 *
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
2137
2138

2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160


2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181





2182
2183
2184
2185
2186


2187
2188
2189
2190
2191
2192
2193
 * Side effects:
 *	Whatever the notifier callback does.
 *
 *----------------------------------------------------------------------
 */

static int
PipeEventProc(evPtr, flags)
    Tcl_Event *evPtr;		/* Event to service. */
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    PipeEvent *pipeEvPtr = (PipeEvent *)evPtr;
    PipeInfo *infoPtr;
    WinFile *filePtr;
    int mask;
/*    DWORD count;*/

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the list of watched pipes for the one whose handle
     * matches the event.  We do this rather than simply dereferencing
     * the handle in the event so that pipes can be deleted while the
     * event is in the queue.
     */


    for (infoPtr = firstPipePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (pipeEvPtr->infoPtr == infoPtr) {
	    infoPtr->flags &= ~(PIPE_PENDING);
	    break;
	}
    }

    /*
     * Remove stale events.
     */

    if (!infoPtr) {
	return 1;
    }

    /*
     * If we aren't on Win32s, check to see if the pipe is readable.  Note
     * that we can't tell if a pipe is writable, so we always report it
     * as being writable.
     */

    filePtr = (WinFile*) ((PipeInfo*)infoPtr)->readFile;


    if (filePtr->type != WIN32S_PIPE) {

	/*
	 * On windows 95, PeekNamedPipe returns 0 on eof so we can't
	 * distinguish underflow from eof.  The correct solution is to
	 * switch to the threaded implementation.
	 */
	mask = TCL_WRITABLE|TCL_READABLE;
/* 	if (PeekNamedPipe(filePtr->handle, (LPVOID) NULL, (DWORD) 0, */
/* 		(LPDWORD) NULL, &count, (LPDWORD) NULL) == TRUE) { */
/* 	    if (count != 0) { */
/* 		mask |= TCL_READABLE; */
/* 	    } */
/* 	} else { */

	    /*
	     * If the pipe has been closed by the other side, then 
	     * mark the pipe as readable, but not writable.
	     */

/* 	    if (GetLastError() == ERROR_BROKEN_PIPE) { */





/* 		mask = TCL_READABLE; */
/* 	    } */
/* 	} */
    } else {
	mask = TCL_READABLE | TCL_WRITABLE;


    }

    /*
     * Inform the channel of the events.
     */

    Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask & mask);







|
|
|






|












>
|

















|


|
>
>
|
|
<
<
|
<
<
|
<
<
<
<
<
<
|
<
<
<
<
|
|
>
>
>
>
>
|
<
<
|
|
>
>







2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571


2572


2573






2574




2575
2576
2577
2578
2579
2580
2581
2582


2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
 * Side effects:
 *	Whatever the notifier callback does.
 *
 *----------------------------------------------------------------------
 */

static int
PipeEventProc(
    Tcl_Event *evPtr,		/* Event to service. */
    int flags)			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    PipeEvent *pipeEvPtr = (PipeEvent *)evPtr;
    PipeInfo *infoPtr;
    WinFile *filePtr;
    int mask;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the list of watched pipes for the one whose handle
     * matches the event.  We do this rather than simply dereferencing
     * the handle in the event so that pipes can be deleted while the
     * event is in the queue.
     */

    for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (pipeEvPtr->infoPtr == infoPtr) {
	    infoPtr->flags &= ~(PIPE_PENDING);
	    break;
	}
    }

    /*
     * Remove stale events.
     */

    if (!infoPtr) {
	return 1;
    }

    /*
     * If we aren't on Win32s, check to see if the pipe is readable.  Note
     * that we can't tell if a pipe is writable, so we always report it
     * as being writable unless we have detected EOF.
     */

    filePtr = (WinFile*) ((PipeInfo*)infoPtr)->writeFile;
    mask = 0;
    if (infoPtr->watchMask & TCL_WRITABLE) {
	if ((filePtr->type == WIN32S_PIPE)
		|| (WaitForSingleObject(infoPtr->writable, 0)


			!= WAIT_TIMEOUT)) {


	    mask = TCL_WRITABLE;






	}




    }

    filePtr = (WinFile*) ((PipeInfo*)infoPtr)->readFile;
    if (infoPtr->watchMask & TCL_READABLE) {
	if ((filePtr->type == WIN32S_PIPE)
		|| (WaitForRead(infoPtr, 0) >= 0)) {
	    if (infoPtr->readFlags & PIPE_EOF) {
		mask = TCL_READABLE;


	    } else {
		mask |= TCL_READABLE;
	    }
	} 
    }

    /*
     * Inform the channel of the events.
     */

    Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask & mask);
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223

2224
2225

2226
2227

2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
PipeWatchProc(instanceData, mask)
    ClientData instanceData;		/* Pipe state. */
    int mask;				/* What events to watch for; OR-ed
                                         * combination of TCL_READABLE,
                                         * TCL_WRITABLE and TCL_EXCEPTION. */
{
    PipeInfo **nextPtrPtr, *ptr;
    PipeInfo *infoPtr = (PipeInfo *) instanceData;
    int oldMask = infoPtr->watchMask;


    /*

     * For now, we just send a message to ourselves so we can poll the
     * channel for readable events.

     */

    infoPtr->watchMask = mask & infoPtr->validMask;
    if (infoPtr->watchMask) {
	Tcl_Time blockTime = { 0, 0 };
	if (!oldMask) {
	    infoPtr->nextPtr = firstPipePtr;
	    firstPipePtr = infoPtr;
	}
	Tcl_SetMaxBlockTime(&blockTime);
    } else {
	if (oldMask) {
	    /*
	     * Remove the pipe from the list of watched pipes.
	     */

	    for (nextPtrPtr = &firstPipePtr, ptr = *nextPtrPtr;
		 ptr != NULL;
		 nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
		if (infoPtr == ptr) {
		    *nextPtrPtr = ptr->nextPtr;
		    break;
		}
	    }







|
|
|






>


>
|
<
>






|
|








|







2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628

2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
PipeWatchProc(
    ClientData instanceData,		/* Pipe state. */
    int mask)				/* What events to watch for, OR-ed
                                         * combination of TCL_READABLE,
                                         * TCL_WRITABLE and TCL_EXCEPTION. */
{
    PipeInfo **nextPtrPtr, *ptr;
    PipeInfo *infoPtr = (PipeInfo *) instanceData;
    int oldMask = infoPtr->watchMask;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Since most of the work is handled by the background threads,
     * we just need to update the watchMask and then force the notifier

     * to poll once. 
     */

    infoPtr->watchMask = mask & infoPtr->validMask;
    if (infoPtr->watchMask) {
	Tcl_Time blockTime = { 0, 0 };
	if (!oldMask) {
	    infoPtr->nextPtr = tsdPtr->firstPipePtr;
	    tsdPtr->firstPipePtr = infoPtr;
	}
	Tcl_SetMaxBlockTime(&blockTime);
    } else {
	if (oldMask) {
	    /*
	     * Remove the pipe from the list of watched pipes.
	     */

	    for (nextPtrPtr = &(tsdPtr->firstPipePtr), ptr = *nextPtrPtr;
		 ptr != NULL;
		 nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
		if (infoPtr == ptr) {
		    *nextPtrPtr = ptr->nextPtr;
		    break;
		}
	    }
2268
2269
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
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
PipeGetHandleProc(instanceData, direction, handlePtr)
    ClientData instanceData;	/* The pipe state. */
    int direction;		/* TCL_READABLE or TCL_WRITABLE */
    ClientData *handlePtr;	/* Where to store the handle.  */
{
    PipeInfo *infoPtr = (PipeInfo *) instanceData;
    WinFile *filePtr; 

    if (direction == TCL_READABLE && infoPtr->readFile) {
	filePtr = (WinFile*) infoPtr->readFile;
	if (filePtr->type == WIN32S_PIPE) {
	    if (filePtr->handle == INVALID_HANDLE_VALUE) {
		filePtr->handle = CreateFile(((WinPipe *)filePtr)->fileName,
			GENERIC_READ, 0, NULL, OPEN_ALWAYS,
			FILE_ATTRIBUTE_NORMAL, NULL);
	    }
	    if (filePtr->handle == INVALID_HANDLE_VALUE) {
		return TCL_ERROR;
	    }
	}







|
|
|
|








|







2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
PipeGetHandleProc(
    ClientData instanceData,	/* The pipe state. */
    int direction,		/* TCL_READABLE or TCL_WRITABLE */
    ClientData *handlePtr)	/* Where to store the handle.  */
{
    PipeInfo *infoPtr = (PipeInfo *) instanceData;
    WinFile *filePtr; 

    if (direction == TCL_READABLE && infoPtr->readFile) {
	filePtr = (WinFile*) infoPtr->readFile;
	if (filePtr->type == WIN32S_PIPE) {
	    if (filePtr->handle == INVALID_HANDLE_VALUE) {
		filePtr->handle = CreateFileA(((WinPipe *)filePtr)->fileName,
			GENERIC_READ, 0, NULL, OPEN_ALWAYS,
			FILE_ATTRIBUTE_NORMAL, NULL);
	    }
	    if (filePtr->handle == INVALID_HANDLE_VALUE) {
		return TCL_ERROR;
	    }
	}
2319
2320
2321
2322
2323
2324
2325
2326
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
 *	information record will be deleted and the process handle
 *	will be closed.
 *
 *----------------------------------------------------------------------
 */

Tcl_Pid
Tcl_WaitPid(pid, statPtr, options)
    Tcl_Pid pid;
    int *statPtr;
    int options;
{
    ProcInfo *infoPtr, **prevPtrPtr;
    int flags;
    Tcl_Pid result;
    DWORD ret;

    if (!initialized) {
	PipeInit();
    }

    /*
     * If no pid is specified, do nothing.
     */
    
    if (pid == 0) {
	*statPtr = 0;
	return 0;
    }

    /*
     * Find the process on the process list.
     */


    prevPtrPtr = &procList;
    for (infoPtr = procList; infoPtr != NULL;
	    prevPtrPtr = &infoPtr->nextPtr, infoPtr = infoPtr->nextPtr) {
	 if (infoPtr->hProcess == (HANDLE) pid) {
	    break;
	}
    }


    /*
     * If the pid is not one of the processes we know about (we started it)
     * then do nothing.
     */
    
    if (infoPtr == NULL) {
        *statPtr = 0;
	return 0;
    }

    /*
     * Officially "wait" for it to finish. We either poll (WNOHANG) or







|
|
|
|






<
|
<














>







>





|







2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737

2738

2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
 *	information record will be deleted and the process handle
 *	will be closed.
 *
 *----------------------------------------------------------------------
 */

Tcl_Pid
Tcl_WaitPid(
    Tcl_Pid pid,
    int *statPtr,
    int options)
{
    ProcInfo *infoPtr, **prevPtrPtr;
    int flags;
    Tcl_Pid result;
    DWORD ret;


    PipeInit();


    /*
     * If no pid is specified, do nothing.
     */
    
    if (pid == 0) {
	*statPtr = 0;
	return 0;
    }

    /*
     * Find the process on the process list.
     */

    Tcl_MutexLock(&pipeMutex);
    prevPtrPtr = &procList;
    for (infoPtr = procList; infoPtr != NULL;
	    prevPtrPtr = &infoPtr->nextPtr, infoPtr = infoPtr->nextPtr) {
	 if (infoPtr->hProcess == (HANDLE) pid) {
	    break;
	}
    }
    Tcl_MutexUnlock(&pipeMutex);

    /*
     * If the pid is not one of the processes we know about (we started it)
     * then do nothing.
     */
    		     
    if (infoPtr == NULL) {
        *statPtr = 0;
	return 0;
    }

    /*
     * Officially "wait" for it to finish. We either poll (WNOHANG) or
2406
2407
2408
2409
2410
2411
2412
































2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470





































































































































































































































































































    return result;
}

/*
 *----------------------------------------------------------------------
 *
































 * Tcl_PidObjCmd --
 *
 *	This procedure is invoked to process the "pid" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_PidObjCmd(dummy, interp, objc, objv)
    ClientData dummy;		/* Not used. */
    Tcl_Interp *interp;		/* Current interpreter. */
    int objc;			/* Number of arguments. */
    Tcl_Obj *CONST *objv;	/* Argument strings. */
{
    Tcl_Channel chan;
    Tcl_ChannelType *chanTypePtr;
    PipeInfo *pipePtr;
    int i;
    Tcl_Obj *resultPtr;
    char buf[20];

    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "?channelId?");
	return TCL_ERROR;
    }
    if (objc == 1) {
	resultPtr = Tcl_GetObjResult(interp);
	sprintf(buf, "%lu", (unsigned long) getpid());
	Tcl_SetStringObj(resultPtr, buf, -1);
    } else {
        chan = Tcl_GetChannel(interp, Tcl_GetStringFromObj(objv[1], NULL),
		NULL);
        if (chan == (Tcl_Channel) NULL) {
	    return TCL_ERROR;
	}
	chanTypePtr = Tcl_GetChannelType(chan);
	if (chanTypePtr != &pipeChannelType) {
	    return TCL_OK;
	}

        pipePtr = (PipeInfo *) Tcl_GetChannelInstanceData(chan);
	resultPtr = Tcl_GetObjResult(interp);
        for (i = 0; i < pipePtr->numPids; i++) {
	    sprintf(buf, "%lu", TclpGetPid(pipePtr->pidPtr[i]));
	    Tcl_ListObjAppendElement(/*interp*/ NULL, resultPtr,
		    Tcl_NewStringObj(buf, -1));
	}
    }
    return TCL_OK;
}











































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
















|
|
|
|
|






|







|















|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TclWinAddProcess --
 *
 *     Add a process to the process list so that we can use
 *     Tcl_WaitPid on the process.
 *
 * Results:
 *     None
 *
 * Side effects:
 *	Adds the specified process handle to the process list so
 *	Tcl_WaitPid knows about it.
 *
 *----------------------------------------------------------------------
 */

void
TclWinAddProcess(hProcess, id)
    HANDLE hProcess;           /* Handle to process */
    DWORD id;                  /* Global process identifier */
{
    ProcInfo *procPtr = (ProcInfo *) ckalloc(sizeof(ProcInfo));
    procPtr->hProcess = hProcess;
    procPtr->dwProcessId = id;
    Tcl_MutexLock(&pipeMutex);
    procPtr->nextPtr = procList;
    procList = procPtr;
    Tcl_MutexUnlock(&pipeMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_PidObjCmd --
 *
 *	This procedure is invoked to process the "pid" Tcl command.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
Tcl_PidObjCmd(
    ClientData dummy,		/* Not used. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST *objv)	/* Argument strings. */
{
    Tcl_Channel chan;
    Tcl_ChannelType *chanTypePtr;
    PipeInfo *pipePtr;
    int i;
    Tcl_Obj *resultPtr;
    char buf[TCL_INTEGER_SPACE];

    if (objc > 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "?channelId?");
	return TCL_ERROR;
    }
    if (objc == 1) {
	resultPtr = Tcl_GetObjResult(interp);
	wsprintfA(buf, "%lu", (unsigned long) getpid());
	Tcl_SetStringObj(resultPtr, buf, -1);
    } else {
        chan = Tcl_GetChannel(interp, Tcl_GetStringFromObj(objv[1], NULL),
		NULL);
        if (chan == (Tcl_Channel) NULL) {
	    return TCL_ERROR;
	}
	chanTypePtr = Tcl_GetChannelType(chan);
	if (chanTypePtr != &pipeChannelType) {
	    return TCL_OK;
	}

        pipePtr = (PipeInfo *) Tcl_GetChannelInstanceData(chan);
	resultPtr = Tcl_GetObjResult(interp);
        for (i = 0; i < pipePtr->numPids; i++) {
	    wsprintfA(buf, "%lu", TclpGetPid(pipePtr->pidPtr[i]));
	    Tcl_ListObjAppendElement(/*interp*/ NULL, resultPtr,
		    Tcl_NewStringObj(buf, -1));
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WaitForRead --
 *
 *	Wait until some data is available, the pipe is at
 *	EOF or the reader thread is blocked waiting for data (if the
 *	channel is in non-blocking mode).
 *
 * Results:
 *	Returns 1 if pipe is readable.  Returns 0 if there is no data
 *	on the pipe, but there is buffered data.  Returns -1 if an
 *	error occurred.  If an error occurred, the threads may not
 *	be synchronized.
 *
 * Side effects:
 *	Updates the shared state flags and may consume 1 byte of data
 *	from the pipe.  If no error occurred, the reader thread is
 *	blocked waiting for a signal from the main thread.
 *
 *----------------------------------------------------------------------
 */

static int
WaitForRead(
    PipeInfo *infoPtr,		/* Pipe state. */
    int blocking)		/* Indicates whether call should be
				 * blocking or not. */
{
    DWORD timeout, count;
    HANDLE *handle = ((WinFile *) infoPtr->readFile)->handle;

    while (1) {
	/*
	 * Synchronize with the reader thread.
	 */
       
	timeout = blocking ? INFINITE : 0;
	if (WaitForSingleObject(infoPtr->readable, timeout) == WAIT_TIMEOUT) {
	    /*
	     * The reader thread is blocked waiting for data and the channel
	     * is in non-blocking mode.
	     */

	    errno = EAGAIN;
	    return -1;
	}

	/*
	 * At this point, the two threads are synchronized, so it is safe
	 * to access shared state.
	 */


	/*
	 * If the pipe has hit EOF, it is always readable.
	 */

	if (infoPtr->readFlags & PIPE_EOF) {
	    return 1;
	}
    
	/*
	 * Check to see if there is any data sitting in the pipe.
	 */

	if (PeekNamedPipe(handle, (LPVOID) NULL, (DWORD) 0,
		(LPDWORD) NULL, &count, (LPDWORD) NULL) != TRUE) {
	    TclWinConvertError(GetLastError());
	    /*
	     * Check to see if the peek failed because of EOF.
	     */

	    if (errno == EPIPE) {
		infoPtr->readFlags |= PIPE_EOF;
		return 1;
	    }

	    /*
	     * Ignore errors if there is data in the buffer.
	     */

	    if (infoPtr->readFlags & PIPE_EXTRABYTE) {
		return 0;
	    } else {
		return -1;
	    }
	}

	/*
	 * We found some data in the pipe, so it must be readable.
	 */

	if (count > 0) {
	    return 1;
	}

	/*
	 * The pipe isn't readable, but there is some data sitting
	 * in the buffer, so return immediately.
	 */

	if (infoPtr->readFlags & PIPE_EXTRABYTE) {
	    return 0;
	}

	/*
	 * There wasn't any data available, so reset the thread and
	 * try again.
	 */
    
	ResetEvent(infoPtr->readable);
	SetEvent(infoPtr->startReader);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * PipeReaderThread --
 *
 *	This function runs in a separate thread and waits for input
 *	to become available on a pipe.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Signals the main thread when input become available.  May
 *	cause the main thread to wake up by posting a message.  May
 *	consume one byte from the pipe for each wait operation.
 *
 *----------------------------------------------------------------------
 */

static DWORD WINAPI
PipeReaderThread(LPVOID arg)
{
    PipeInfo *infoPtr = (PipeInfo *)arg;
    HANDLE *handle = ((WinFile *) infoPtr->readFile)->handle;
    DWORD count, err;
    int done = 0;

    while (!done) {
	/*
	 * Wait for the main thread to signal before attempting to wait.
	 */

	WaitForSingleObject(infoPtr->startReader, INFINITE);

	/*
	 * Try waiting for 0 bytes.  This will block until some data is
	 * available on NT, but will return immediately on Win 95.  So,
	 * if no data is available after the first read, we block until
	 * we can read a single byte off of the pipe.
	 */

	if ((ReadFile(handle, NULL, 0, &count, NULL) == FALSE)
		|| (PeekNamedPipe(handle, NULL, 0, NULL, &count,
			NULL) == FALSE)) {
	    /*
	     * The error is a result of an EOF condition, so set the
	     * EOF bit before signalling the main thread.
	     */

	    err = GetLastError();
	    if (err == ERROR_BROKEN_PIPE) {
		infoPtr->readFlags |= PIPE_EOF;
		done = 1;
	    } else if (err == ERROR_INVALID_HANDLE) {
		break;
	    }
	} else if (count == 0) {
	    if (ReadFile(handle, &(infoPtr->extraByte), 1, &count, NULL)
		    != FALSE) {
		/*
		 * One byte was consumed as a side effect of waiting
		 * for the pipe to become readable.
		 */

		infoPtr->readFlags |= PIPE_EXTRABYTE;
	    } else {
		err = GetLastError();
		if (err == ERROR_BROKEN_PIPE) {
		    /*
		     * The error is a result of an EOF condition, so set the
		     * EOF bit before signalling the main thread.
		     */

		    infoPtr->readFlags |= PIPE_EOF;
		    done = 1;
		} else if (err == ERROR_INVALID_HANDLE) {
		    break;
		}
	    }
	}

		
	/*
	 * Signal the main thread by signalling the readable event and
	 * then waking up the notifier thread.
	 */

	SetEvent(infoPtr->readable);
	
	/*
	 * Alert the foreground thread.  Note that we need to treat this like
	 * a critical section so the foreground thread does not terminate
	 * this thread while we are holding a mutex in the notifier code.
	 */

	Tcl_MutexLock(&pipeMutex);
	Tcl_ThreadAlert(infoPtr->threadId);
	Tcl_MutexUnlock(&pipeMutex);
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * PipeWriterThread --
 *
 *	This function runs in a separate thread and writes data
 *	onto a pipe.
 *
 * Results:
 *	Always returns 0.
 *
 * Side effects:
 *	Signals the main thread when an output operation is completed.
 *	May cause the main thread to wake up by posting a message.  
 *
 *----------------------------------------------------------------------
 */

static DWORD WINAPI
PipeWriterThread(LPVOID arg)
{

    PipeInfo *infoPtr = (PipeInfo *)arg;
    HANDLE *handle = ((WinFile *) infoPtr->writeFile)->handle;
    DWORD count, toWrite;
    char *buf;
    int done = 0;

    while (!done) {
	/*
	 * Wait for the main thread to signal before attempting to write.
	 */

	WaitForSingleObject(infoPtr->startWriter, INFINITE);

	buf = infoPtr->writeBuf;
	toWrite = infoPtr->toWrite;

	/*
	 * Loop until all of the bytes are written or an error occurs.
	 */

	while (toWrite > 0) {
	    if (WriteFile(handle, buf, toWrite, &count, NULL) == FALSE) {
		infoPtr->writeError = GetLastError();
		done = 1; 
		break;
	    } else {
		toWrite -= count;
		buf += count;
	    }
	}
	
	/*
	 * Signal the main thread by signalling the writable event and
	 * then waking up the notifier thread.
	 */

	SetEvent(infoPtr->writable);

	/*
	 * Alert the foreground thread.  Note that we need to treat this like
	 * a critical section so the foreground thread does not terminate
	 * this thread while we are holding a mutex in the notifier code.
	 */

	Tcl_MutexLock(&pipeMutex);
	Tcl_ThreadAlert(infoPtr->threadId);
	Tcl_MutexUnlock(&pipeMutex);
    }
    return 0;
}

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
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
/*
 * 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-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclWinPort.h 1.53 97/07/30 14:12:17
 */

#ifndef _TCLWINPORT
#define _TCLWINPORT

























#include <malloc.h>
#include <stdio.h>


#include <stdlib.h>
#include <string.h>

#include <errno.h>

#include <process.h>
#include <signal.h>
#include <winsock.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <time.h>
#include <io.h>
#include <fcntl.h>
#include <float.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN






/*
 * Define EINPROGRESS in terms of WSAEINPROGRESS.
 */

#ifndef	EINPROGRESS
#define EINPROGRESS WSAEINPROGRESS
#endif

/*
 * If ENOTSUP is not defined, define it to a value that will never occur.
 */

#ifndef ENOTSUP
#define	ENOTSUP		-1030507
#endif

/*
 * The following defines wrap the system memory allocation routines for
 * use by tclAlloc.c.
 */

#define TclpSysAlloc(size, isBin)	((void*)GlobalAlloc(GMEM_FIXED, \
					    (DWORD)size))
#define TclpSysFree(ptr)		(GlobalFree((HGLOBAL)ptr))
#define TclpSysRealloc(ptr, size)	((void*)GlobalReAlloc((HGLOBAL)ptr, \
					    (DWORD)size, 0))

/*
 * The default platform eol translation on Windows is TCL_TRANSLATE_CRLF:
 */

#define	TCL_PLATFORM_TRANSLATION	TCL_TRANSLATE_CRLF

/*
 * Declare dynamic loading extension macro.
 */

#define TCL_SHLIB_EXT ".dll"

/*
 * Supply definitions for macros to query wait status, if not already
 * defined in header files above.
 */

#if TCL_UNION_WAIT
#   define WAIT_STATUS_TYPE union wait
#else
#   define WAIT_STATUS_TYPE int
#endif

#ifndef WIFEXITED
#   define WIFEXITED(stat)  (((*((int *) &(stat))) & 0xff) == 0)
#endif

#ifndef WEXITSTATUS
#   define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff)
#endif

#ifndef WIFSIGNALED
#   define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff)))
#endif

#ifndef WTERMSIG
#   define WTERMSIG(stat)    ((*((int *) &(stat))) & 0x7f)
#endif

#ifndef WIFSTOPPED
#   define WIFSTOPPED(stat)  (((*((int *) &(stat))) & 0xff) == 0177)
#endif

#ifndef WSTOPSIG
#   define WSTOPSIG(stat)    (((*((int *) &(stat))) >> 8) & 0xff)
#endif

/*
 * Define constants for waitpid() system call if they aren't defined
 * by a system header file.
 */

#ifndef WNOHANG
#   define WNOHANG 1
#endif
#ifndef WUNTRACED
#   define WUNTRACED 2
#endif

/*
 * Define MAXPATHLEN in terms of MAXPATH if available
 */

#ifndef MAXPATH
#define MAXPATH MAX_PATH
#endif /* MAXPATH */

#ifndef MAXPATHLEN
#define MAXPATHLEN MAXPATH
#endif /* MAXPATHLEN */

#ifndef F_OK
#    define F_OK 00
#endif
#ifndef X_OK
#    define X_OK 01
#endif
#ifndef W_OK
#    define W_OK 02
#endif
#ifndef R_OK
#    define R_OK 04
#endif

/*
 * Define macros to query file type bits, if they're not already
 * defined.
 */

#ifndef S_ISREG
#   ifdef S_IFREG
#       define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#   else
#       define S_ISREG(m) 0
#   endif
# endif
#ifndef S_ISDIR
#   ifdef S_IFDIR
#       define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#   else
#       define S_ISDIR(m) 0
#   endif
# endif
#ifndef S_ISCHR
#   ifdef S_IFCHR
#       define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#   else
#       define S_ISCHR(m) 0
#   endif
# endif
#ifndef S_ISBLK
#   ifdef S_IFBLK
#       define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#   else
#       define S_ISBLK(m) 0
#   endif
# endif
#ifndef S_ISFIFO
#   ifdef S_IFIFO
#       define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#   else
#       define S_ISFIFO(m) 0
#   endif
# endif

/*
 * Define pid_t and uid_t if they're not already defined.
 */

#if ! TCL_PID_T
#   define pid_t int
#endif
#if ! TCL_UID_T
#   define uid_t int
#endif

/*
 * Provide a stub definition for TclGetUserHome().
 */

#define TclGetUserHome(name,bufferPtr) (NULL)

/*
 * Visual C++ has some odd names for common functions, so we need to
 * define a few macros to handle them.  Also, it defines EDEADLOCK and
 * EDEADLK as the same value, which confuses Tcl_ErrnoId().
 */

#ifdef _MSC_VER
#    define environ _environ
#    define hypot _hypot
#    define exception _exception
#    undef EDEADLOCK
#endif /* _MSC_VER */

/*
 * The following defines redefine the Windows Socket errors as
 * BSD errors so Tcl_PosixError can do the right thing.
 */

#ifndef EWOULDBLOCK
#define EWOULDBLOCK             EAGAIN







|




|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

>
|
|
>
|
>


|


|
|
|
<




>
>
>
>
>

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
/*
 * 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.1.2.6 1999/03/10 06:49:30 stanton Exp $
 */

#ifndef _TCLWINPORT
#define _TCLWINPORT

#ifndef _TCLINT
#   include "tclInt.h"
#endif

#ifdef CHECK_UNICODE_CALLS

#define _UNICODE
#define UNICODE

#define __TCHAR_DEFINED
typedef float *_TCHAR;

#define _TCHAR_DEFINED
typedef float *TCHAR;

#endif

/*
 *---------------------------------------------------------------------------
 * The following sets of #includes and #ifdefs are required to get Tcl to
 * compile under the windows compilers.
 *---------------------------------------------------------------------------
 */

#include <stdio.h>
#include <stdlib.h>

#include <direct.h>
#include <errno.h>
#include <fcntl.h>
#include <float.h>
#include <io.h>
#include <malloc.h>
#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
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

/*
 * Define EINPROGRESS in terms of WSAEINPROGRESS.
 */

#ifndef	EINPROGRESS
#define EINPROGRESS WSAEINPROGRESS
#endif

/*
 * If ENOTSUP is not defined, define it to a value that will never occur.
 */

#ifndef ENOTSUP
#define	ENOTSUP		-1030507
#endif







































































































































































/*
 * The following defines redefine the Windows Socket errors as
 * BSD errors so Tcl_PosixError can do the right thing.
 */

#ifndef EWOULDBLOCK
#define EWOULDBLOCK             EAGAIN
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
#ifndef ESTALE
#define ESTALE		151	/* Stale NFS file handle */
#endif
#ifndef EREMOTE
#define EREMOTE		66	/* The object is remote */
#endif


































































































































































/*
 * The following define ensures that we use the native putenv
 * implementation to modify the environment array.  This keeps
 * the C level environment in synch with the system level environment.
 */

#define USE_PUTENV	1
    












/*
 * The following defines map from standard socket names to our internal
 * wrappers that redirect through the winSock function table (see the
 * file tclWinSock.c).
 */

#define getservbyname	TclWinGetServByName
#define getsockopt	TclWinGetSockOpt
#define ntohs		TclWinNToHS
#define setsockopt	TclWinSetSockOpt

/*
 * The following implements the Windows method for exiting the process.

 */
#define TclPlatformExit(status) exit(status)



/*
 * The following declarations belong in tclInt.h, but depend on platform
 * specific types (e.g. struct tm).

 */

EXTERN struct tm *	TclpGetDate _ANSI_ARGS_((const time_t *tp,
			    int useGMT));
EXTERN unsigned long	TclpGetPid _ANSI_ARGS_((Tcl_Pid pid));
EXTERN size_t		TclStrftime _ANSI_ARGS_((char *s, size_t maxsize,
			    const char *format, const struct tm *t));

/*
 * The following prototypes and defines replace the Windows versions
 * of POSIX function that various compilier vendors didn't implement 
 * well or consistantly.
 */

#define stat(path, buf)		TclWinStat(path, buf)
#define lstat			stat
#define access(path, mode)	TclWinAccess(path, mode)



EXTERN int		TclWinStat _ANSI_ARGS_((CONST char *path, 

			    struct stat *buf));
EXTERN int		TclWinAccess _ANSI_ARGS_((CONST char *path, 
			    int mode));

#define TclpReleaseFile(file)	ckfree((char *) file)


/*
 * Declarations for Windows specific functions.



 */



EXTERN void		TclWinConvertError _ANSI_ARGS_((DWORD errCode));
EXTERN void		TclWinConvertWSAError _ANSI_ARGS_((DWORD errCode));
EXTERN struct servent * PASCAL FAR
			TclWinGetServByName _ANSI_ARGS_((const char FAR *nm,
		            const char FAR *proto));
EXTERN int PASCAL FAR	TclWinGetSockOpt _ANSI_ARGS_((SOCKET s, int level,
		            int optname, char FAR * optval, int FAR *optlen));
EXTERN HINSTANCE	TclWinGetTclInstance _ANSI_ARGS_((void));
EXTERN HINSTANCE	TclWinLoadLibrary _ANSI_ARGS_((char *name));
EXTERN u_short PASCAL FAR

			TclWinNToHS _ANSI_ARGS_((u_short ns));


EXTERN int PASCAL FAR	TclWinSetSockOpt _ANSI_ARGS_((SOCKET s, int level,


		            int optname, const char FAR * optval, int optlen));
#endif /* _TCLWINPORT */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
>
>
>
>
>
>
>
>
>
>
>
>












|
>

<

>


|
<
>


<
|
<
|
<


|
<
<


<
<
<
>
>
|
|
>
|
|
|

<
>


|
>
>
>


>
>
|
|
<
|
<
|
|
|
|
|
>
|
>
>
|
>
>
|

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389

390
391
392
393
394

395
396
397

398

399

400
401
402


403
404



405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423
424
425
426

427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
#ifndef ESTALE
#define ESTALE		151	/* Stale NFS file handle */
#endif
#ifndef EREMOTE
#define EREMOTE		66	/* The object is remote */
#endif

/*
 * Supply definitions for macros to query wait status, if not already
 * defined in header files above.
 */

#if TCL_UNION_WAIT
#   define WAIT_STATUS_TYPE union wait
#else
#   define WAIT_STATUS_TYPE int
#endif

#ifndef WIFEXITED
#   define WIFEXITED(stat)  (((*((int *) &(stat))) & 0xff) == 0)
#endif

#ifndef WEXITSTATUS
#   define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff)
#endif

#ifndef WIFSIGNALED
#   define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff)))
#endif

#ifndef WTERMSIG
#   define WTERMSIG(stat)    ((*((int *) &(stat))) & 0x7f)
#endif

#ifndef WIFSTOPPED
#   define WIFSTOPPED(stat)  (((*((int *) &(stat))) & 0xff) == 0177)
#endif

#ifndef WSTOPSIG
#   define WSTOPSIG(stat)    (((*((int *) &(stat))) >> 8) & 0xff)
#endif

/*
 * Define constants for waitpid() system call if they aren't defined
 * by a system header file.
 */

#ifndef WNOHANG
#   define WNOHANG 1
#endif
#ifndef WUNTRACED
#   define WUNTRACED 2
#endif

/*
 * Define access mode constants if they aren't already defined.
 */

#ifndef F_OK
#    define F_OK 00
#endif
#ifndef X_OK
#    define X_OK 01
#endif
#ifndef W_OK
#    define W_OK 02
#endif
#ifndef R_OK
#    define R_OK 04
#endif

/*
 * Define macros to query file type bits, if they're not already
 * defined.
 */

#ifndef S_ISREG
#   ifdef S_IFREG
#       define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#   else
#       define S_ISREG(m) 0
#   endif
# endif
#ifndef S_ISDIR
#   ifdef S_IFDIR
#       define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#   else
#       define S_ISDIR(m) 0
#   endif
# endif
#ifndef S_ISCHR
#   ifdef S_IFCHR
#       define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#   else
#       define S_ISCHR(m) 0
#   endif
# endif
#ifndef S_ISBLK
#   ifdef S_IFBLK
#       define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#   else
#       define S_ISBLK(m) 0
#   endif
# endif
#ifndef S_ISFIFO
#   ifdef S_IFIFO
#       define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#   else
#       define S_ISFIFO(m) 0
#   endif
# endif

/*
 * Define MAXPATHLEN in terms of MAXPATH if available
 */

#ifndef MAXPATH
#define MAXPATH MAX_PATH
#endif /* MAXPATH */

#ifndef MAXPATHLEN
#define MAXPATHLEN MAXPATH
#endif /* MAXPATHLEN */

/*
 * Define pid_t and uid_t if they're not already defined.
 */

#if ! TCL_PID_T
#   define pid_t int
#endif
#if ! TCL_UID_T
#   define uid_t int
#endif

/*
 * Visual C++ has some odd names for common functions, so we need to
 * define a few macros to handle them.  Also, it defines EDEADLOCK and
 * EDEADLK as the same value, which confuses Tcl_ErrnoId().
 */

#ifdef _MSC_VER
#    define environ _environ
#    define hypot _hypot
#    define exception _exception
#    undef EDEADLOCK
#endif /* _MSC_VER */

/*
 *---------------------------------------------------------------------------
 * The following macros and declarations represent the interface between 
 * generic and windows-specific parts of Tcl.  Some of the macros may 
 * override functions declared in tclInt.h.
 *---------------------------------------------------------------------------
 */

/*
 * The default platform eol translation on Windows is TCL_TRANSLATE_CRLF:
 */

#define	TCL_PLATFORM_TRANSLATION	TCL_TRANSLATE_CRLF

/*
 * Declare dynamic loading extension macro.
 */

#define TCL_SHLIB_EXT ".dll"

/*
 * The following define ensures that we use the native putenv
 * implementation to modify the environment array.  This keeps
 * the C level environment in synch with the system level environment.
 */

#define USE_PUTENV	1

/*
 * The following defines wrap the system memory allocation routines for
 * use by tclAlloc.c.
 */

#define TclpSysAlloc(size, isBin)	((void*)HeapAlloc(GetProcessHeap(), \
					    (DWORD)0, (DWORD)size))
#define TclpSysFree(ptr)		(HeapFree(GetProcessHeap(), \
					    (DWORD)0, (HGLOBAL)ptr))
#define TclpSysRealloc(ptr, size)	((void*)HeapReAlloc(GetProcessHeap(), \
					    (DWORD)0, (LPVOID)ptr, (DWORD)size))

/*
 * The following defines map from standard socket names to our internal
 * wrappers that redirect through the winSock function table (see the
 * file tclWinSock.c).
 */

#define getservbyname	TclWinGetServByName
#define getsockopt	TclWinGetSockOpt
#define ntohs		TclWinNToHS
#define setsockopt	TclWinSetSockOpt

/*
 * The following macros have trivial definitions, allowing generic code to 
 * address platform-specific issues.
 */


#define TclpReleaseFile(file)	ckfree((char *) file)

/*
 * The following macros and declarations wrap the C runtime library 

 * functions.
 */


#define TclpExit		exit

#define TclpLstat		TclpStat


/*
 * Declarations for Windows-only functions.


 */




EXTERN Tcl_Channel  TclWinOpenSerialChannel _ANSI_ARGS_((HANDLE handle,
                        char *channelName, int permissions));
					 
EXTERN Tcl_Channel  TclWinOpenConsoleChannel _ANSI_ARGS_((HANDLE handle,
                        char *channelName, int permissions));

EXTERN Tcl_Channel  TclWinOpenFileChannel _ANSI_ARGS_((HANDLE handle,
                        char *channelName, int permissions, int appendMode));


EXTERN TclFile TclWinMakeFile _ANSI_ARGS_((HANDLE handle));

/*
 * Platform specific mutex definition used by memory allocators.
 * These mutexes are statically allocated and explicitly initialized.
 * Most modules do not use this, but instead use Tcl_Mutex types and
 * Tcl_MutexLock and Tcl_MutexUnlock that are self-initializing.
 */

#ifdef TCL_THREADS
typedef CRITICAL_SECTION TclpMutex;
EXTERN void	TclpMutexInit _ANSI_ARGS_((TclpMutex *mPtr));
EXTERN void	TclpMutexLock _ANSI_ARGS_((TclpMutex *mPtr));

EXTERN void	TclpMutexUnlock _ANSI_ARGS_((TclpMutex *mPtr));

#else
typedef int TclpMutex;
#define	TclpMutexInit(a)
#define	TclpMutexLock(a)
#define	TclpMutexUnlock(a)
#endif /* TCL_THREADS */

#include "tclPlatDecls.h"
#include "tclIntPlatDecls.h"

# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT

#endif /* _TCLWINPORT */

Changes to win/tclWinReg.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
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
/* 
 * tclWinReg.c --
 *
 *	This file contains the implementation of the "registry" Tcl
 *	built-in command.  This command is built as a dynamically
 *	loadable extension in a separate DLL.
 *
 * 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.
 *
 * SCCS: @(#) tclWinReg.c 1.8 97/08/01 11:17:49
 */

#include <tcl.h>
#include <stdlib.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN

/*
 * VC++ has an alternate entry point called DllMain, so we need to rename
 * our entry point.

 */

#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

/*
 * The following macros convert between different endian ints.
 */

#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
 
/*
 * The following flag is used in OpenKeys to indicate that the specified
 * key should be created if it doesn't currently exist.
 */

#define REG_CREATE 1

/*
 * The following tables contain the mapping from registry root names
 * to the system predefined keys.
 */

static char *rootKeyNames[] = {
    "HKEY_LOCAL_MACHINE", "HKEY_USERS", "HKEY_CLASSES_ROOT",
    "HKEY_CURRENT_USER", "HKEY_CURRENT_CONFIG", NULL

};

static HKEY rootKeys[] = {
    HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,
    HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, HKEY_DYN_DATA
};

/*
 * The following table maps from registry types to strings.  Note that
 * the indices for this array are the same as the constants for the
 * known registry types so we don't need a separate table to hold the
 * mapping.
 */

static char *typeNames[] = {
    "none", "sz", "expand_sz", "binary", "dword", 
    "dword_big_endian", "link", "multi_sz", "resource_list", NULL
};

static DWORD lastType = REG_RESOURCE_REQUIREMENTS_LIST;





















































































/*
 * Declarations for functions defined in this file.
 */

static void		AppendSystemError(Tcl_Interp *interp, DWORD error);
|







>




|


|







|
|
>


|
<
<
<
<
<
<
<
|
<
<
<







|














|
>















|



|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
/*
 * tclWinReg.c --
 *
 *	This file contains the implementation of the "registry" Tcl
 *	built-in command.  This command is built as a dynamically
 *	loadable extension in a separate DLL.
 *
 * 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: tclWinReg.c,v 1.1.2.5 1999/04/01 21:56:03 stanton Exp $
 */

#include <tclPort.h>
#include <stdlib.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN

/*
 * TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the
 * Registry_Init declaration is in the source file itself, which is only
 * accessed when we are building a library.
 */

#undef TCL_STORAGE_CLASS







#define TCL_STORAGE_CLASS DLLEXPORT




/*
 * The following macros convert between different endian ints.
 */

#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))

/*
 * The following flag is used in OpenKeys to indicate that the specified
 * key should be created if it doesn't currently exist.
 */

#define REG_CREATE 1

/*
 * The following tables contain the mapping from registry root names
 * to the system predefined keys.
 */

static char *rootKeyNames[] = {
    "HKEY_LOCAL_MACHINE", "HKEY_USERS", "HKEY_CLASSES_ROOT",
    "HKEY_CURRENT_USER", "HKEY_CURRENT_CONFIG",
    "HKEY_PERFORMANCE_DATA", "HKEY_DYN_DATA", NULL
};

static HKEY rootKeys[] = {
    HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,
    HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, HKEY_DYN_DATA
};

/*
 * The following table maps from registry types to strings.  Note that
 * the indices for this array are the same as the constants for the
 * known registry types so we don't need a separate table to hold the
 * mapping.
 */

static char *typeNames[] = {
    "none", "sz", "expand_sz", "binary", "dword",
    "dword_big_endian", "link", "multi_sz", "resource_list", NULL
};

static DWORD lastType = REG_RESOURCE_LIST;

/*
 * The following structures allow us to select between the Unicode and ASCII
 * interfaces at run time based on whether Unicode APIs are available.  The
 * Unicode APIs are preferable because they will handle characters outside
 * of the current code page.
 */

typedef struct RegWinProcs {
    int useWide;

    LONG (WINAPI *regConnectRegistryProc)(TCHAR *, HKEY, PHKEY);
    LONG (WINAPI *regCreateKeyExProc)(HKEY, CONST TCHAR *, DWORD, TCHAR *,
	    DWORD, REGSAM, SECURITY_ATTRIBUTES *, HKEY *, DWORD *); 
    LONG (WINAPI *regDeleteKeyProc)(HKEY, CONST TCHAR *);
    LONG (WINAPI *regDeleteValueProc)(HKEY, CONST TCHAR *);
    LONG (WINAPI *regEnumKeyProc)(HKEY, DWORD, TCHAR *, DWORD);
    LONG (WINAPI *regEnumKeyExProc)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,
	    TCHAR *, DWORD *, FILETIME *);
    LONG (WINAPI *regEnumValueProc)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,
	    DWORD *, BYTE *, DWORD *);
    LONG (WINAPI *regOpenKeyExProc)(HKEY, CONST TCHAR *, DWORD, REGSAM,
	    HKEY *);
    LONG (WINAPI *regQueryInfoKeyProc)(HKEY, TCHAR *, DWORD *, DWORD *,
	    DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *,
	    FILETIME *);
    LONG (WINAPI *regQueryValueExProc)(HKEY, CONST TCHAR *, DWORD *, DWORD *,
	    BYTE *, DWORD *);
    LONG (WINAPI *regSetValueExProc)(HKEY, CONST TCHAR *, DWORD, DWORD,
	    CONST BYTE*, DWORD);
} RegWinProcs;

static RegWinProcs *regWinProcs;

static RegWinProcs asciiProcs = {
    0,

    (LONG (WINAPI *)(TCHAR *, HKEY, PHKEY)) RegConnectRegistryA,
    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, TCHAR *,
	    DWORD, REGSAM, SECURITY_ATTRIBUTES *, HKEY *,
	    DWORD *)) RegCreateKeyExA, 
    (LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteKeyA,
    (LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteValueA,
    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD)) RegEnumKeyA,
    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,
	    TCHAR *, DWORD *, FILETIME *)) RegEnumKeyExA,
    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,
	    DWORD *, BYTE *, DWORD *)) RegEnumValueA,
    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, REGSAM,
	    HKEY *)) RegOpenKeyExA,
    (LONG (WINAPI *)(HKEY, TCHAR *, DWORD *, DWORD *,
	    DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *,
	    FILETIME *)) RegQueryInfoKeyA,
    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD *, DWORD *,
	    BYTE *, DWORD *)) RegQueryValueExA,
    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, DWORD,
	    CONST BYTE*, DWORD)) RegSetValueExA,
};

static RegWinProcs unicodeProcs = {
    1,

    (LONG (WINAPI *)(TCHAR *, HKEY, PHKEY)) RegConnectRegistryW,
    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, TCHAR *,
	    DWORD, REGSAM, SECURITY_ATTRIBUTES *, HKEY *,
	    DWORD *)) RegCreateKeyExW, 
    (LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteKeyW,
    (LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteValueW,
    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD)) RegEnumKeyW,
    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,
	    TCHAR *, DWORD *, FILETIME *)) RegEnumKeyExW,
    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,
	    DWORD *, BYTE *, DWORD *)) RegEnumValueW,
    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, REGSAM,
	    HKEY *)) RegOpenKeyExW,
    (LONG (WINAPI *)(HKEY, TCHAR *, DWORD *, DWORD *,
	    DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *,
	    FILETIME *)) RegQueryInfoKeyW,
    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD *, DWORD *,
	    BYTE *, DWORD *)) RegQueryValueExW,
    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, DWORD,
	    CONST BYTE*, DWORD)) RegSetValueExW,
};


/*
 * Declarations for functions defined in this file.
 */

static void		AppendSystemError(Tcl_Interp *interp, DWORD error);
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
			    REGSAM mode, int flags, HKEY *keyPtr);
static DWORD		OpenSubKey(char *hostName, HKEY rootKey,
			    char *keyName, REGSAM mode, int flags,
			    HKEY *keyPtr);
static int		ParseKeyName(Tcl_Interp *interp, char *name,
			    char **hostNamePtr, HKEY *rootKeyPtr,
			    char **keyNamePtr);
static DWORD		RecursiveDeleteKey(HKEY hStartKey, LPTSTR pKeyName);
static int		RegistryObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]);

static int		SetValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj,
			    Tcl_Obj *valueNameObj, Tcl_Obj *dataObj,
			    Tcl_Obj *typeObj);

EXTERN EXPORT(int,Registry_Init)(Tcl_Interp *interp);

/*
 *----------------------------------------------------------------------
 *
 * DllEntryPoint --
 *
 *	This wrapper function is used by Windows to invoke the
 *	initialization code for the DLL.  If we are compiling
 *	with Visual C++, this routine will be renamed to DllMain.
 *	routine.
 *
 * Results:
 *	Returns TRUE;
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#ifdef __WIN32__
#ifndef STATIC_BUILD
BOOL APIENTRY
DllEntryPoint(
    HINSTANCE hInst,		/* Library instance handle. */
    DWORD reason,		/* Reason this function is being called. */
    LPVOID reserved)		/* Not used. */
{
    return TRUE;
}
#endif
#endif

/*
 *----------------------------------------------------------------------
 *
 * Registry_Init --
 *
 *	This procedure initializes the registry command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */


EXPORT(int,Registry_Init)(
    Tcl_Interp *interp)
{




















    Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd, NULL, NULL);
    return Tcl_PkgProvide(interp, "registry", "1.0");
}

/*
 *----------------------------------------------------------------------
 *







|

|
>




|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















>
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
			    REGSAM mode, int flags, HKEY *keyPtr);
static DWORD		OpenSubKey(char *hostName, HKEY rootKey,
			    char *keyName, REGSAM mode, int flags,
			    HKEY *keyPtr);
static int		ParseKeyName(Tcl_Interp *interp, char *name,
			    char **hostNamePtr, HKEY *rootKeyPtr,
			    char **keyNamePtr);
static DWORD		RecursiveDeleteKey(HKEY hStartKey, TCHAR * pKeyName);
static int		RegistryObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * CONST objv[]);
static int		SetValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj,
			    Tcl_Obj *valueNameObj, Tcl_Obj *dataObj,
			    Tcl_Obj *typeObj);

EXTERN int Registry_Init(Tcl_Interp *interp);

































/*
 *----------------------------------------------------------------------
 *
 * Registry_Init --
 *
 *	This procedure initializes the registry command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
Registry_Init(
    Tcl_Interp *interp)
{
    OSVERSIONINFO os;

    if (!Tcl_InitStubs(interp, "8.0", 0)) {
	return TCL_ERROR;
    }

    /*
     * Determine if the unicode interfaces are available and select the
     * appropriate registry function table.
     */

    os.dwOSVersionInfoSize = sizeof(os);
    GetVersionEx(&os);

    if (os.dwPlatformId == VER_PLATFORM_WIN32_NT) {
	regWinProcs = &unicodeProcs;
    } else {
	regWinProcs = &asciiProcs;
    }

    Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd, NULL, NULL);
    return Tcl_PkgProvide(interp, "registry", "1.0");
}

/*
 *----------------------------------------------------------------------
 *
295
296
297
298
299
300
301

302
303
304
305
306
307
308
    Tcl_Obj *keyNameObj)	/* Name of key to delete. */
{
    char *tail, *buffer, *hostName, *keyName;
    HKEY rootKey, subkey;
    DWORD result;
    int length;
    Tcl_Obj *resultPtr;


    /*
     * Find the parent of the key being deleted and open it.
     */

    keyName = Tcl_GetStringFromObj(keyNameObj, &length);
    buffer = ckalloc(length + 1);







>







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
    Tcl_Obj *keyNameObj)	/* Name of key to delete. */
{
    char *tail, *buffer, *hostName, *keyName;
    HKEY rootKey, subkey;
    DWORD result;
    int length;
    Tcl_Obj *resultPtr;
    Tcl_DString buf;

    /*
     * Find the parent of the key being deleted and open it.
     */

    keyName = Tcl_GetStringFromObj(keyNameObj, &length);
    buffer = ckalloc(length + 1);
342
343
344
345
346
347
348

349

350
351
352
353
354
355
356
	}
    }

    /*
     * Now we recursively delete the key and everything below it.
     */


    result = RecursiveDeleteKey(subkey, tail);


    if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
	Tcl_AppendToObj(resultPtr, "unable to delete key: ", -1);
	AppendSystemError(interp, result);
	result = TCL_ERROR;
    } else {
	result = TCL_OK;







>

>







409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
	}
    }

    /*
     * Now we recursively delete the key and everything below it.
     */

    tail = Tcl_WinUtfToTChar(tail, -1, &buf);
    result = RecursiveDeleteKey(subkey, tail);
    Tcl_DStringFree(&buf);

    if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
	Tcl_AppendToObj(resultPtr, "unable to delete key: ", -1);
	AppendSystemError(interp, result);
	result = TCL_ERROR;
    } else {
	result = TCL_OK;
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
    Tcl_Obj *valueNameObj)	/* Name of value to delete. */
{
    HKEY key;
    char *valueName;
    int length;
    DWORD result;
    Tcl_Obj *resultPtr;

    
    /*
     * Attempt to open the key for deletion.
     */

    if (OpenKey(interp, keyNameObj, KEY_SET_VALUE, 0, &key)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    resultPtr = Tcl_GetObjResult(interp);
    valueName = Tcl_GetStringFromObj(valueNameObj, &length);
    result = RegDeleteValue(key, valueName);


    if (result != ERROR_SUCCESS) {
	Tcl_AppendStringsToObj(resultPtr, "unable to delete value \"",
		Tcl_GetStringFromObj(valueNameObj, NULL), "\" from key \"",
		Tcl_GetStringFromObj(keyNameObj, NULL), "\": ", NULL);
	AppendSystemError(interp, result);
	result = TCL_ERROR;
    } else {
	result = TCL_OK;
    }
    RegCloseKey(key);
    return result;







>
|











|
>
>


|
|







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
    Tcl_Obj *valueNameObj)	/* Name of value to delete. */
{
    HKEY key;
    char *valueName;
    int length;
    DWORD result;
    Tcl_Obj *resultPtr;
    Tcl_DString ds;

    /*
     * Attempt to open the key for deletion.
     */

    if (OpenKey(interp, keyNameObj, KEY_SET_VALUE, 0, &key)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    resultPtr = Tcl_GetObjResult(interp);
    valueName = Tcl_GetStringFromObj(valueNameObj, &length);
    Tcl_WinUtfToTChar(valueName, length, &ds);
    result = (*regWinProcs->regDeleteValueProc)(key, Tcl_DStringValue(&ds));
    Tcl_DStringFree(&ds);
    if (result != ERROR_SUCCESS) {
	Tcl_AppendStringsToObj(resultPtr, "unable to delete value \"",
		Tcl_GetString(valueNameObj), "\" from key \"",
		Tcl_GetString(keyNameObj), "\": ", NULL);
	AppendSystemError(interp, result);
	result = TCL_ERROR;
    } else {
	result = TCL_OK;
    }
    RegCloseKey(key);
    return result;
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
GetKeyNames(
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Obj *keyNameObj,	/* Key to enumerate. */
    Tcl_Obj *patternObj)	/* Optional match pattern. */
{
    HKEY key;
    DWORD index;
    char buffer[MAX_PATH+1], *pattern;
    Tcl_Obj *resultPtr;
    int result = TCL_OK;


    /*
     * Attempt to open the key for enumeration.
     */

    if (OpenKey(interp, keyNameObj, KEY_ENUMERATE_SUB_KEYS, 0, &key)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    if (patternObj) {
	pattern = Tcl_GetStringFromObj(patternObj, NULL);
    } else {
	pattern = NULL;
    }

    /*
     * Enumerate over the subkeys until we get an error, indicating the
     * end of the list.
     */

    resultPtr = Tcl_GetObjResult(interp);
    for (index = 0; RegEnumKey(key, index, buffer, MAX_PATH+1)
	     == ERROR_SUCCESS; index++) {


	if (pattern && !Tcl_StringMatch(buffer, pattern)) {

	    continue;
	}
	result = Tcl_ListObjAppendElement(interp, resultPtr,
		Tcl_NewStringObj(buffer, -1));

	if (result != TCL_OK) {
	    break;
	}
    }

    RegCloseKey(key);
    return result;







|


>











|










|
|
>
>
|
>



|
>







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
GetKeyNames(
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Obj *keyNameObj,	/* Key to enumerate. */
    Tcl_Obj *patternObj)	/* Optional match pattern. */
{
    HKEY key;
    DWORD index;
    char buffer[MAX_PATH+1], *pattern, *name;
    Tcl_Obj *resultPtr;
    int result = TCL_OK;
    Tcl_DString ds;

    /*
     * Attempt to open the key for enumeration.
     */

    if (OpenKey(interp, keyNameObj, KEY_ENUMERATE_SUB_KEYS, 0, &key)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    if (patternObj) {
	pattern = Tcl_GetString(patternObj);
    } else {
	pattern = NULL;
    }

    /*
     * Enumerate over the subkeys until we get an error, indicating the
     * end of the list.
     */

    resultPtr = Tcl_GetObjResult(interp);
    for (index = 0; (*regWinProcs->regEnumKeyProc)(key, index, buffer,
	    MAX_PATH+1) == ERROR_SUCCESS; index++) {
	Tcl_WinTCharToUtf((TCHAR *) buffer, -1, &ds);
	name = Tcl_DStringValue(&ds);
	if (pattern && !Tcl_StringMatch(name, pattern)) {
	    Tcl_DStringFree(&ds);
	    continue;
	}
	result = Tcl_ListObjAppendElement(interp, resultPtr,
		Tcl_NewStringObj(name, Tcl_DStringLength(&ds)));
	Tcl_DStringFree(&ds);
	if (result != TCL_OK) {
	    break;
	}
    }

    RegCloseKey(key);
    return result;
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
    Tcl_Obj *keyNameObj,	/* Name of key. */
    Tcl_Obj *valueNameObj)	/* Name of value to get. */
{
    HKEY key;
    Tcl_Obj *resultPtr;
    DWORD result;
    DWORD type;



    
    /*
     * Attempt to open the key for reading.
     */

    if (OpenKey(interp, keyNameObj, KEY_QUERY_VALUE, 0, &key)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Get the type of the value.
     */

    resultPtr = Tcl_GetObjResult(interp);

    result = RegQueryValueEx(key, Tcl_GetStringFromObj(valueNameObj, NULL),


	    NULL, &type, NULL, NULL);

    RegCloseKey(key);

    if (result != ERROR_SUCCESS) {
	Tcl_AppendStringsToObj(resultPtr, "unable to get type of value \"",
		Tcl_GetStringFromObj(valueNameObj, NULL), "\" from key \"",
		Tcl_GetStringFromObj(keyNameObj, NULL), "\": ", NULL);
	AppendSystemError(interp, result);
	return TCL_ERROR;
    }

    /*
     * Set the type into the result.  Watch out for unknown types.
     * If we don't know about the type, just use the numeric value.
     */

    if (type > lastType) {
	Tcl_SetIntObj(resultPtr, type);
    } else {
	Tcl_SetStringObj(resultPtr, typeNames[type], -1);
    }
    return TCL_OK;
}








>
>
>
|















|
>
>
|
>




|
|









|







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
    Tcl_Obj *keyNameObj,	/* Name of key. */
    Tcl_Obj *valueNameObj)	/* Name of value to get. */
{
    HKEY key;
    Tcl_Obj *resultPtr;
    DWORD result;
    DWORD type;
    Tcl_DString ds;
    char *valueName;
    int length;

    /*
     * Attempt to open the key for reading.
     */

    if (OpenKey(interp, keyNameObj, KEY_QUERY_VALUE, 0, &key)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Get the type of the value.
     */

    resultPtr = Tcl_GetObjResult(interp);

    valueName = Tcl_GetStringFromObj(valueNameObj, &length);
    valueName = Tcl_WinUtfToTChar(valueName, length, &ds);
    result = (*regWinProcs->regQueryValueExProc)(key, valueName, NULL, &type,
	    NULL, NULL);
    Tcl_DStringFree(&ds);
    RegCloseKey(key);

    if (result != ERROR_SUCCESS) {
	Tcl_AppendStringsToObj(resultPtr, "unable to get type of value \"",
		Tcl_GetString(valueNameObj), "\" from key \"",
		Tcl_GetString(keyNameObj), "\": ", NULL);
	AppendSystemError(interp, result);
	return TCL_ERROR;
    }

    /*
     * Set the type into the result.  Watch out for unknown types.
     * If we don't know about the type, just use the numeric value.
     */

    if (type > lastType || type < 0) {
	Tcl_SetIntObj(resultPtr, type);
    } else {
	Tcl_SetStringObj(resultPtr, typeNames[type], -1);
    }
    return TCL_OK;
}

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
    Tcl_Obj *keyNameObj,	/* Name of key. */
    Tcl_Obj *valueNameObj)	/* Name of value to get. */
{
    HKEY key;
    char *valueName;
    DWORD result, length, type;
    Tcl_Obj *resultPtr;
    Tcl_DString data;


    /*
     * Attempt to open the key for reading.
     */

    if (OpenKey(interp, keyNameObj, KEY_QUERY_VALUE, 0, &key)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    /*


     * Get the value once to determine the length then again to store
     * the data in the buffer.



     */

    Tcl_DStringInit(&data);



    resultPtr = Tcl_GetObjResult(interp);

    valueName = Tcl_GetStringFromObj(valueNameObj, (int*) &length);


    result = RegQueryValueEx(key, valueName, NULL, &type, NULL, &length);

    if (result == ERROR_SUCCESS) {
	Tcl_DStringSetLength(&data, length);
	result = RegQueryValueEx(key, valueName, NULL, &type,
		(LPBYTE) Tcl_DStringValue(&data), &length);
    }

    RegCloseKey(key);
    if (result != ERROR_SUCCESS) {
	Tcl_AppendStringsToObj(resultPtr, "unable to get value \"",
		Tcl_GetStringFromObj(valueNameObj, NULL), "\" from key \"",
		Tcl_GetStringFromObj(keyNameObj, NULL), "\": ", NULL);
	AppendSystemError(interp, result);
	Tcl_DStringFree(&data);
	return TCL_ERROR;
    }

    /*
     * If the data is a 32-bit quantity, store it as an integer object.  If it
     * is a multi-string, store it as a list of strings.  For null-terminated
     * strings, append up the to first null.  Otherwise, store it as a binary
     * string.
     */

    if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {
	Tcl_SetIntObj(resultPtr, ConvertDWORD(type,
		*((DWORD*) Tcl_DStringValue(&data))));
    } else if (type == REG_MULTI_SZ) {
	char *p = Tcl_DStringValue(&data);
	char *lastChar = Tcl_DStringValue(&data) + Tcl_DStringLength(&data);

	/*
	 * Multistrings are stored as an array of null-terminated strings,
	 * terminated by two null characters.  Also do a bounds check in
	 * case we get bogus data.
	 */

	while (p < lastChar && *p != '\0') {


	    Tcl_ListObjAppendElement(interp, resultPtr,
		    Tcl_NewStringObj(p, -1));




	    while (*p++ != '\0') {}
	}


    } else if ((type == REG_SZ) || (type == REG_EXPAND_SZ)) {

	Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&data), -1);


    } else {




	Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&data), length);
    }
    Tcl_DStringFree(&data);
    return result;
}

/*
 *----------------------------------------------------------------------







|
>











>
>
|
|
>
>
>



>
>
>


|
>
>
|
>
|
|
|
|

>



|
|

















|






|
|
>
>

|
>
>
>
>
|
|
>
>

>
|
>
>

>
>
>
>
|







657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
    Tcl_Obj *keyNameObj,	/* Name of key. */
    Tcl_Obj *valueNameObj)	/* Name of value to get. */
{
    HKEY key;
    char *valueName;
    DWORD result, length, type;
    Tcl_Obj *resultPtr;
    Tcl_DString data, buf;
    int nameLen;

    /*
     * Attempt to open the key for reading.
     */

    if (OpenKey(interp, keyNameObj, KEY_QUERY_VALUE, 0, &key)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Initialize a Dstring to maximum statically allocated size
     * we could get one more byte by avoiding Tcl_DStringSetLength()
     * and just setting length to TCL_DSTRING_STATIC_SIZE, but this
     * should be safer if the implementation of Dstrings changes.
     *
     * This allows short values to be read from the registy in one call.
     * Longer values need a second call with an expanded DString.
     */

    Tcl_DStringInit(&data);
    length = TCL_DSTRING_STATIC_SIZE - 1;
    Tcl_DStringSetLength(&data, length);

    resultPtr = Tcl_GetObjResult(interp);

    valueName = Tcl_GetStringFromObj(valueNameObj, &nameLen);
    valueName = Tcl_WinUtfToTChar(valueName, nameLen, &buf);

    result = (*regWinProcs->regQueryValueExProc)(key, valueName, NULL, &type,
	    (BYTE *) Tcl_DStringValue(&data), &length);
    if (result == ERROR_MORE_DATA) {
        Tcl_DStringSetLength(&data, length);
        result = (*regWinProcs->regQueryValueExProc)(key, valueName, NULL,
		&type, (BYTE *) Tcl_DStringValue(&data), &length);
    }
    Tcl_DStringFree(&buf);
    RegCloseKey(key);
    if (result != ERROR_SUCCESS) {
	Tcl_AppendStringsToObj(resultPtr, "unable to get value \"",
		Tcl_GetString(valueNameObj), "\" from key \"",
		Tcl_GetString(keyNameObj), "\": ", NULL);
	AppendSystemError(interp, result);
	Tcl_DStringFree(&data);
	return TCL_ERROR;
    }

    /*
     * If the data is a 32-bit quantity, store it as an integer object.  If it
     * is a multi-string, store it as a list of strings.  For null-terminated
     * strings, append up the to first null.  Otherwise, store it as a binary
     * string.
     */

    if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {
	Tcl_SetIntObj(resultPtr, ConvertDWORD(type,
		*((DWORD*) Tcl_DStringValue(&data))));
    } else if (type == REG_MULTI_SZ) {
	char *p = Tcl_DStringValue(&data);
	char *end = Tcl_DStringValue(&data) + length;

	/*
	 * Multistrings are stored as an array of null-terminated strings,
	 * terminated by two null characters.  Also do a bounds check in
	 * case we get bogus data.
	 */
 
	while (p < end 	&& ((regWinProcs->useWide) 
		? *((Tcl_UniChar *)p) : *p) != 0) {
	    Tcl_WinTCharToUtf((TCHAR *) p, -1, &buf);
	    Tcl_ListObjAppendElement(interp, resultPtr,
		    Tcl_NewStringObj(Tcl_DStringValue(&buf),
			    Tcl_DStringLength(&buf)));
	    if (regWinProcs->useWide) {
		while (*((Tcl_UniChar *)p)++ != 0) {}
	    } else {
		while (*p++ != '\0') {}
	    }
	    Tcl_DStringFree(&buf);
	}
    } else if ((type == REG_SZ) || (type == REG_EXPAND_SZ)) {
	Tcl_WinTCharToUtf((TCHAR *) Tcl_DStringValue(&data), -1, &buf);
	Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&buf),
		Tcl_DStringLength(&buf));
	Tcl_DStringFree(&buf);
    } else {
	/*
	 * Save binary data as a byte array.
	 */

	Tcl_SetByteArrayObj(resultPtr, Tcl_DStringValue(&data), length);
    }
    Tcl_DStringFree(&data);
    return result;
}

/*
 *----------------------------------------------------------------------
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712

713
714
715
716
717
718
719
720
721
722
723
724
725
726
727


728
729







730
731
732
733

734
735
736


737
738
739
740
741
742
743
744
745
GetValueNames(
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Obj *keyNameObj,	/* Key to enumerate. */
    Tcl_Obj *patternObj)	/* Optional match pattern. */
{
    HKEY key;
    Tcl_Obj *resultPtr;
    DWORD index, size, result;
    Tcl_DString buffer;
    char *pattern;

    /*
     * Attempt to open the key for enumeration.
     */

    if (OpenKey(interp, keyNameObj, KEY_QUERY_VALUE, 0, &key)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    resultPtr = Tcl_GetObjResult(interp);

    /*
     * Query the key to determine the appropriate buffer size to hold the
     * largest value name plus the terminating null.
     */

    result = RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, &index,
	&size, NULL, NULL, NULL);
    if (result != ERROR_SUCCESS) {
	Tcl_AppendStringsToObj(resultPtr, "unable to query key \"",
		Tcl_GetStringFromObj(keyNameObj, NULL), "\": ", NULL);
	AppendSystemError(interp, result);
	RegCloseKey(key);
	result = TCL_ERROR;
	goto done;
    }
    size++;


    Tcl_DStringInit(&buffer);
    Tcl_DStringSetLength(&buffer, size);

    index = 0;
    result = TCL_OK;

    if (patternObj) {
	pattern = Tcl_GetStringFromObj(patternObj, NULL);
    } else {
	pattern = NULL;
    }

    /*
     * Enumerate the values under the given subkey until we get an error,
     * indicating the end of the list.  Note that we need to reset size
     * after each iteration because RegEnumValue smashes the old value.
     */



    while (RegEnumValue(key, index, Tcl_DStringValue(&buffer), &size, NULL,
	    NULL, NULL, NULL) == ERROR_SUCCESS) {







	if (!pattern || Tcl_StringMatch(Tcl_DStringValue(&buffer), pattern)) {
	    result = Tcl_ListObjAppendElement(interp, resultPtr,
		    Tcl_NewStringObj(Tcl_DStringValue(&buffer), size));
	    if (result != TCL_OK) {

		break;
	    }
	}


	index++;
	size = Tcl_DStringLength(&buffer);
    }
    Tcl_DStringFree(&buffer);

    done:
    RegCloseKey(key);
    return result;
}







|
|
|

















|
|


|





|



|
>




|










>
>
|
|
>
>
>
>
>
>
>
|

|

>



>
>

|







782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
GetValueNames(
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Obj *keyNameObj,	/* Key to enumerate. */
    Tcl_Obj *patternObj)	/* Optional match pattern. */
{
    HKEY key;
    Tcl_Obj *resultPtr;
    DWORD index, size, maxSize, result;
    Tcl_DString buffer, ds;
    char *pattern, *name;

    /*
     * Attempt to open the key for enumeration.
     */

    if (OpenKey(interp, keyNameObj, KEY_QUERY_VALUE, 0, &key)
	    != TCL_OK) {
	return TCL_ERROR;
    }

    resultPtr = Tcl_GetObjResult(interp);

    /*
     * Query the key to determine the appropriate buffer size to hold the
     * largest value name plus the terminating null.
     */

    result = (*regWinProcs->regQueryInfoKeyProc)(key, NULL, NULL, NULL, NULL,
	    NULL, NULL, &index, &maxSize, NULL, NULL, NULL);
    if (result != ERROR_SUCCESS) {
	Tcl_AppendStringsToObj(resultPtr, "unable to query key \"",
		Tcl_GetString(keyNameObj), "\": ", NULL);
	AppendSystemError(interp, result);
	RegCloseKey(key);
	result = TCL_ERROR;
	goto done;
    }
    maxSize++;


    Tcl_DStringInit(&buffer);
    Tcl_DStringSetLength(&buffer,
	    (regWinProcs->useWide) ? maxSize*2 : maxSize);
    index = 0;
    result = TCL_OK;

    if (patternObj) {
	pattern = Tcl_GetString(patternObj);
    } else {
	pattern = NULL;
    }

    /*
     * Enumerate the values under the given subkey until we get an error,
     * indicating the end of the list.  Note that we need to reset size
     * after each iteration because RegEnumValue smashes the old value.
     */

    size = maxSize;
    while ((*regWinProcs->regEnumValueProc)(key, index,
	    Tcl_DStringValue(&buffer), &size, NULL, NULL, NULL, NULL)
	    == ERROR_SUCCESS) {

	if (regWinProcs->useWide) {
	    size *= 2;
	}

	Tcl_WinTCharToUtf((TCHAR *) Tcl_DStringValue(&buffer), size, &ds);
	name = Tcl_DStringValue(&ds);
	if (!pattern || Tcl_StringMatch(name, pattern)) {
	    result = Tcl_ListObjAppendElement(interp, resultPtr,
		    Tcl_NewStringObj(name, Tcl_DStringLength(&ds)));
	    if (result != TCL_OK) {
		Tcl_DStringFree(&ds);
		break;
	    }
	}
	Tcl_DStringFree(&ds);

	index++;
	size = maxSize;
    }
    Tcl_DStringFree(&buffer);

    done:
    RegCloseKey(key);
    return result;
}
820
821
822
823
824
825
826

827
828
829
830
831
832

833


834
835
836
837
838
839
840
841
842
843

844
845
846
847
848
849

850

851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
    HKEY rootKey,		/* Root registry key. */
    char *keyName,		/* Subkey name. */
    REGSAM mode,		/* Access mode. */
    int flags,			/* 0 or REG_CREATE. */
    HKEY *keyPtr)		/* Returned HKEY. */
{
    DWORD result;


    /*
     * Attempt to open the root key on a remote host if necessary.
     */

    if (hostName) {

	result = RegConnectRegistry(hostName, rootKey, &rootKey);


	if (result != ERROR_SUCCESS) {
	    return result;
	}
    }

    /*
     * Now open the specified key with the requested permissions.  Note
     * that this key must be closed by the caller.
     */


    if (flags & REG_CREATE) {
	DWORD create;
	result = RegCreateKeyEx(rootKey, keyName, 0, "",
		REG_OPTION_NON_VOLATILE, mode, NULL, keyPtr, &create);
    } else {
	result = RegOpenKeyEx(rootKey, keyName, 0, mode, keyPtr);

    }


    /*
     * Be sure to close the root key since we are done with it now.
     */

    if (hostName) {
	RegCloseKey(rootKey);
    }
    return result; 
}

/*
 *----------------------------------------------------------------------
 *
 * ParseKeyName --
 *
 *	This function parses a key name into the host, root, and subkey
 *	parts. 
 *
 * Results:
 *	The pointers to the start of the host and subkey names are
 *	returned in the hostNamePtr and keyNamePtr variables.  The
 *	specified root HKEY is returned in rootKeyPtr.  Returns
 *	a standard Tcl result.
 *







>






>
|
>
>










>


|


|
>

>








|








|







944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
    HKEY rootKey,		/* Root registry key. */
    char *keyName,		/* Subkey name. */
    REGSAM mode,		/* Access mode. */
    int flags,			/* 0 or REG_CREATE. */
    HKEY *keyPtr)		/* Returned HKEY. */
{
    DWORD result;
    Tcl_DString buf;

    /*
     * Attempt to open the root key on a remote host if necessary.
     */

    if (hostName) {
	hostName = Tcl_WinUtfToTChar(hostName, -1, &buf);
	result = (*regWinProcs->regConnectRegistryProc)(hostName, rootKey,
		&rootKey);
	Tcl_DStringFree(&buf);
	if (result != ERROR_SUCCESS) {
	    return result;
	}
    }

    /*
     * Now open the specified key with the requested permissions.  Note
     * that this key must be closed by the caller.
     */

    keyName = Tcl_WinUtfToTChar(keyName, -1, &buf);
    if (flags & REG_CREATE) {
	DWORD create;
	result = (*regWinProcs->regCreateKeyExProc)(rootKey, keyName, 0, "",
		REG_OPTION_NON_VOLATILE, mode, NULL, keyPtr, &create);
    } else {
	result = (*regWinProcs->regOpenKeyExProc)(rootKey, keyName, 0, mode,
		keyPtr);
    }
    Tcl_DStringFree(&buf);

    /*
     * Be sure to close the root key since we are done with it now.
     */

    if (hostName) {
	RegCloseKey(rootKey);
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseKeyName --
 *
 *	This function parses a key name into the host, root, and subkey
 *	parts.
 *
 * Results:
 *	The pointers to the start of the host and subkey names are
 *	returned in the hostNamePtr and keyNamePtr variables.  The
 *	specified root HKEY is returned in rootKeyPtr.  Returns
 *	a standard Tcl result.
 *
960
961
962
963
964
965
966
967

968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994

995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
 *
 *----------------------------------------------------------------------
 */

static DWORD
RecursiveDeleteKey(
    HKEY startKey,		/* Parent of key to be deleted. */
    char *keyName)		/* Name of key to be deleted. */

{
    DWORD result, subKeyLength;
    Tcl_DString subkey;
    HKEY hKey;

    /*
     * Do not allow NULL or empty key name.
     */

    if (!keyName || lstrlen(keyName) == '\0') {
	return ERROR_BADKEY;
    }

    result = RegOpenKeyEx(startKey, keyName, 0,
	    KEY_ENUMERATE_SUB_KEYS | DELETE | KEY_QUERY_VALUE, &hKey);
    if (result != ERROR_SUCCESS) {
	return result;
    }
    result = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, &subKeyLength,
	    NULL, NULL, NULL, NULL, NULL, NULL);
    subKeyLength++;
    if (result != ERROR_SUCCESS) {
	return result;
    }

    Tcl_DStringInit(&subkey);
    Tcl_DStringSetLength(&subkey, subKeyLength);


    while (result == ERROR_SUCCESS) {
	/*
	 * Always get index 0 because key deletion changes ordering.
	 */

	subKeyLength = Tcl_DStringLength(&subkey);
	result=RegEnumKeyEx(hKey, 0, Tcl_DStringValue(&subkey), &subKeyLength,
		NULL, NULL, NULL, NULL);
	if (result == ERROR_NO_MORE_ITEMS) {
	    result = RegDeleteKey(startKey, keyName);
	    break;
	} else if (result == ERROR_SUCCESS) {
	    result = RecursiveDeleteKey(hKey, Tcl_DStringValue(&subkey));
	}
    }
    Tcl_DStringFree(&subkey);
    RegCloseKey(hKey);







|
>

|







|



|




|
|
|





|
>






|
|
|

|







1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
 *
 *----------------------------------------------------------------------
 */

static DWORD
RecursiveDeleteKey(
    HKEY startKey,		/* Parent of key to be deleted. */
    char *keyName)		/* Name of key to be deleted in external
				 * encoding, not UTF. */
{
    DWORD result, size, maxSize;
    Tcl_DString subkey;
    HKEY hKey;

    /*
     * Do not allow NULL or empty key name.
     */

    if (!keyName || *keyName == '\0') {
	return ERROR_BADKEY;
    }

    result = (*regWinProcs->regOpenKeyExProc)(startKey, keyName, 0,
	    KEY_ENUMERATE_SUB_KEYS | DELETE | KEY_QUERY_VALUE, &hKey);
    if (result != ERROR_SUCCESS) {
	return result;
    }
    result = (*regWinProcs->regQueryInfoKeyProc)(hKey, NULL, NULL, NULL, NULL,
	    &maxSize, NULL, NULL, NULL, NULL, NULL, NULL);
    maxSize++;
    if (result != ERROR_SUCCESS) {
	return result;
    }

    Tcl_DStringInit(&subkey);
    Tcl_DStringSetLength(&subkey,
	    (regWinProcs->useWide) ? maxSize * 2 : maxSize);

    while (result == ERROR_SUCCESS) {
	/*
	 * Always get index 0 because key deletion changes ordering.
	 */

	size = maxSize;
	result=(*regWinProcs->regEnumKeyExProc)(hKey, 0,
		Tcl_DStringValue(&subkey), &size, NULL, NULL, NULL, NULL);
	if (result == ERROR_NO_MORE_ITEMS) {
	    result = (*regWinProcs->regDeleteKeyProc)(startKey, keyName);
	    break;
	} else if (result == ERROR_SUCCESS) {
	    result = RecursiveDeleteKey(hKey, Tcl_DStringValue(&subkey));
	}
    }
    Tcl_DStringFree(&subkey);
    RegCloseKey(hKey);
1040
1041
1042
1043
1044
1045
1046

1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061

1062
1063
1064
1065
1066
1067

1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081

1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094








1095
1096



1097
1098
1099
1100

1101

1102
1103


1104
1105
1106
1107
1108
1109




1110

1111



1112



1113

1114

1115

1116
1117
1118
1119
1120
1121
1122
    Tcl_Obj *typeObj)		/* Type of data to be written. */
{
    DWORD type, result;
    HKEY key;
    int length;
    char *valueName;
    Tcl_Obj *resultPtr;


    if (typeObj == NULL) {
	type = REG_SZ;
    } else if (Tcl_GetIndexFromObj(interp, typeObj, typeNames, "type",
	    0, (int *) &type) != TCL_OK) {
	if (Tcl_GetIntFromObj(NULL, typeObj, (int*) &type) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_ResetResult(interp);
    }
    if (OpenKey(interp, keyNameObj, KEY_ALL_ACCESS, 1, &key) != TCL_OK) {
	return TCL_ERROR;
    }

    valueName = Tcl_GetStringFromObj(valueNameObj, &length);

    resultPtr = Tcl_GetObjResult(interp);

    if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {
	DWORD value;
	if (Tcl_GetIntFromObj(interp, dataObj, (int*) &value) != TCL_OK) {
	    RegCloseKey(key);

	    return TCL_ERROR;
	}

	value = ConvertDWORD(type, value);
	result = RegSetValueEx(key, valueName, 0, type, (BYTE*) &value,
		sizeof(DWORD));
    } else if (type == REG_MULTI_SZ) {
	Tcl_DString data;
	int objc, i;
	Tcl_Obj **objv;
	char *element;

	if (Tcl_ListObjGetElements(interp, dataObj, &objc, &objv) != TCL_OK) {
	    RegCloseKey(key);

	    return TCL_ERROR;
	}

	/*
	 * Append the elements as null terminated strings.  Note that
	 * we must not assume the length of the string in case there are
	 * embedded nulls, which aren't allowed in REG_MULTI_SZ values.
	 */

	Tcl_DStringInit(&data);
	for (i = 0; i < objc; i++) {
	    element = Tcl_GetStringFromObj(objv[i], NULL);
	    Tcl_DStringAppend(&data, element, -1);








	    Tcl_DStringSetLength(&data, Tcl_DStringLength(&data)+1);
	}



	result = RegSetValueEx(key, valueName, 0, type,
		(LPBYTE) Tcl_DStringValue(&data),
		(DWORD) (Tcl_DStringLength(&data)+1));
	Tcl_DStringFree(&data);

    } else {

	char *data = Tcl_GetStringFromObj(dataObj, &length);



	/*
	 * Include the null in the length if we are storing a null terminated
	 * string.  Note that we also need to call strlen to find the first
	 * null so we don't pass bad data to the registry.
	 */





	if (type == REG_SZ || type == REG_EXPAND_SZ) {

	    length = strlen(data) + 1;



	}





	result = RegSetValueEx(key, valueName, 0, type, (LPBYTE)data, length);

    }

    RegCloseKey(key);
    if (result != ERROR_SUCCESS) {
	Tcl_AppendToObj(resultPtr, "unable to set value: ", -1);
	AppendSystemError(interp, result);
	return TCL_ERROR;
    }
    return TCL_OK;







>















>






>




|
|

|


<



>











<
|
>
>
>
>
>
>
>
>


>
>
>
|
|
|

>
|
>


>
>

|
<
<


>
>
>
>
|
>
|
>
>
>
|
>
>
>

>
|
>

>







1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228

1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255


1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
    Tcl_Obj *typeObj)		/* Type of data to be written. */
{
    DWORD type, result;
    HKEY key;
    int length;
    char *valueName;
    Tcl_Obj *resultPtr;
    Tcl_DString nameBuf;

    if (typeObj == NULL) {
	type = REG_SZ;
    } else if (Tcl_GetIndexFromObj(interp, typeObj, typeNames, "type",
	    0, (int *) &type) != TCL_OK) {
	if (Tcl_GetIntFromObj(NULL, typeObj, (int*) &type) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_ResetResult(interp);
    }
    if (OpenKey(interp, keyNameObj, KEY_ALL_ACCESS, 1, &key) != TCL_OK) {
	return TCL_ERROR;
    }

    valueName = Tcl_GetStringFromObj(valueNameObj, &length);
    valueName = Tcl_WinUtfToTChar(valueName, length, &nameBuf);
    resultPtr = Tcl_GetObjResult(interp);

    if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {
	DWORD value;
	if (Tcl_GetIntFromObj(interp, dataObj, (int*) &value) != TCL_OK) {
	    RegCloseKey(key);
	    Tcl_DStringFree(&nameBuf);
	    return TCL_ERROR;
	}

	value = ConvertDWORD(type, value);
	result = (*regWinProcs->regSetValueExProc)(key, valueName, 0, type,
		(BYTE*) &value, sizeof(DWORD));
    } else if (type == REG_MULTI_SZ) {
	Tcl_DString data, buf;
	int objc, i;
	Tcl_Obj **objv;


	if (Tcl_ListObjGetElements(interp, dataObj, &objc, &objv) != TCL_OK) {
	    RegCloseKey(key);
	    Tcl_DStringFree(&nameBuf);
	    return TCL_ERROR;
	}

	/*
	 * Append the elements as null terminated strings.  Note that
	 * we must not assume the length of the string in case there are
	 * embedded nulls, which aren't allowed in REG_MULTI_SZ values.
	 */

	Tcl_DStringInit(&data);
	for (i = 0; i < objc; i++) {

	    Tcl_DStringAppend(&data, Tcl_GetString(objv[i]), -1);

	    /*
	     * Add a null character to separate this value from the next.
	     * We accomplish this by growing the string by one byte.  Since the
	     * DString always tacks on an extra null byte, the new byte will
	     * already be set to null.
	     */

	    Tcl_DStringSetLength(&data, Tcl_DStringLength(&data)+1);
	}

	Tcl_WinUtfToTChar(Tcl_DStringValue(&data), Tcl_DStringLength(&data)+1,
		&buf);
	result = (*regWinProcs->regSetValueExProc)(key, valueName, 0, type,
		(BYTE *) Tcl_DStringValue(&buf),
		(DWORD) Tcl_DStringLength(&buf));
	Tcl_DStringFree(&data);
	Tcl_DStringFree(&buf);
    } else if (type == REG_SZ || type == REG_EXPAND_SZ) {
	Tcl_DString buf;
	char *data = Tcl_GetStringFromObj(dataObj, &length);

	data = Tcl_WinUtfToTChar(data, length, &buf);

	/*
	 * Include the null in the length, padding if needed for Unicode.


	 */

	if (regWinProcs->useWide) {
	    Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf)+1);
	}
	length = Tcl_DStringLength(&buf) + 1;

	result = (*regWinProcs->regSetValueExProc)(key, valueName, 0, type,
		(BYTE*)data, length);
	Tcl_DStringFree(&buf);
    } else {
	char *data;

	/*
	 * Store binary data in the registry.
	 */

	data = Tcl_GetByteArrayFromObj(dataObj, &length);
	result = (*regWinProcs->regSetValueExProc)(key, valueName, 0, type,
		(BYTE *)data, length);
    }
    Tcl_DStringFree(&nameBuf);
    RegCloseKey(key);
    if (result != ERROR_SUCCESS) {
	Tcl_AppendToObj(resultPtr, "unable to set value: ", -1);
	AppendSystemError(interp, result);
	return TCL_ERROR;
    }
    return TCL_OK;
1141
1142
1143
1144
1145
1146
1147

1148


1149
1150






1151
1152
1153
1154
1155







1156
1157
1158
1159

1160
1161
1162










1163
1164
1165
1166
1167
1168
1169
1170
1171
1172


1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184

static void
AppendSystemError(
    Tcl_Interp *interp,		/* Current interpreter. */
    DWORD error)		/* Result code from error. */
{
    int length;

    char *msgbuf, id[10];


    Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);







    sprintf(id, "%d", error);
    length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
	    | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
	    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msgbuf,
	    0, NULL);







    if (length == 0) {
	if (error == ERROR_CALL_NOT_IMPLEMENTED) {
	    msgbuf = "function not supported under Win32s";
	} else {

	    msgbuf = id;
	}
    } else {










	/*
	 * Trim the trailing CR/LF from the system message.
	 */
	if (msgbuf[length-1] == '\n') {
	    msgbuf[--length] = 0;
	}
	if (msgbuf[length-1] == '\r') {
	    msgbuf[--length] = 0;
	}
    }


    Tcl_SetErrorCode(interp, "WINDOWS", id, msgbuf, (char *) NULL);
    Tcl_AppendToObj(resultPtr, msgbuf, -1);

    if (length != 0) {
	LocalFree(msgbuf);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConvertDWORD --







>
|
>
>


>
>
>
>
>
>
|
|
|
|
|
>
>
>
>
>
>
>


|

>
|


>
>
>
>
>
>
>
>
>
>



|
|

|
|


>
>
|
|


|







1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375

static void
AppendSystemError(
    Tcl_Interp *interp,		/* Current interpreter. */
    DWORD error)		/* Result code from error. */
{
    int length;
    WCHAR *wMsgPtr;
    char *msg;
    char id[TCL_INTEGER_SPACE], msgBuf[24 + TCL_INTEGER_SPACE];
    Tcl_DString ds;
    Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);

    length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
	    | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
	    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (WCHAR *) &wMsgPtr,
	    0, NULL);
    if (length == 0) {
	char *msgPtr;

	length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
		| FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &msgPtr,
		0, NULL);
	if (length > 0) {
	    wMsgPtr = (WCHAR *) LocalAlloc(LPTR, (length + 1) * sizeof(WCHAR));
	    MultiByteToWideChar(CP_ACP, 0, msgPtr, length + 1, wMsgPtr,
		    length + 1);
	    LocalFree(msgPtr);
	}
    }
    if (length == 0) {
	if (error == ERROR_CALL_NOT_IMPLEMENTED) {
	    msg = "function not supported under Win32s";
	} else {
	    sprintf(msgBuf, "unknown error: %d", error);
	    msg = msgBuf;
	}
    } else {
	Tcl_Encoding encoding;

	encoding = Tcl_GetEncoding(NULL, "unicode");
	Tcl_ExternalToUtfDString(encoding, (char *) wMsgPtr, -1, &ds);
	Tcl_FreeEncoding(encoding);
	LocalFree(wMsgPtr);

	msg = Tcl_DStringValue(&ds);
	length = Tcl_DStringLength(&ds);

	/*
	 * Trim the trailing CR/LF from the system message.
	 */
	if (msg[length-1] == '\n') {
	    msg[--length] = 0;
	}
	if (msg[length-1] == '\r') {
	    msg[--length] = 0;
	}
    }

    sprintf(id, "%d", error);
    Tcl_SetErrorCode(interp, "WINDOWS", id, msg, (char *) NULL);
    Tcl_AppendToObj(resultPtr, msg, length);

    if (length != 0) {
	Tcl_DStringFree(&ds);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ConvertDWORD --

Added win/tclWinSerial.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
/* 
 * Tclwinserial.c --
 *
 *	This file implements the Windows-specific serial port functions,
 *	and the "serial" channel driver.
 *
 * Copyright (c) 1999 by Scriptics Corp.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclWinSerial.c,v 1.1.2.6 1999/04/05 21:58:16 stanton Exp $
 */

#include "tclWinInt.h"

#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>

/*
 * The following variable is used to tell whether this module has been
 * initialized.
 */

static int initialized = 0;

/*
 * The serialMutex locks around access to the initialized variable, and it is
 * used to protect background threads from being terminated while they are
 * using APIs that hold locks.
 */

TCL_DECLARE_MUTEX(serialMutex)

/*
 * Bit masks used in the flags field of the SerialInfo structure below.
 */

#define SERIAL_PENDING	(1<<0)	/* Message is pending in the queue. */
#define SERIAL_ASYNC	(1<<1)	/* Channel is non-blocking. */

/*
 * Bit masks used in the sharedFlags field of the SerialInfo structure below.
 */

#define SERIAL_EOF	 (1<<2)  /* Serial has reached EOF. */
#define SERIAL_EXTRABYTE (1<<3)  /* Extra byte consumed while waiting for data */
/*
 * This structure describes per-instance data for a serial based channel.
 */

typedef struct SerialInfo {
    HANDLE handle;
    struct SerialInfo *nextPtr;	/* Pointer to next registered serial. */
    Tcl_Channel channel;	/* Pointer to channel structure. */
    int validMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which operations are valid on the file. */
    int watchMask;		/* OR'ed combination of TCL_READABLE,
				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
				 * which events should be reported. */
    int flags;			/* State flags, see above for a list. */
    Tcl_ThreadId threadId;	/* Thread to which events should be reported.
				 * This value is used by the reader/writer
				 * threads. */
    HANDLE writeThread;		/* Handle to writer thread. */
    HANDLE readThread;		/* Handle to reader thread. */
    HANDLE writable;		/* Manual-reset event to signal when the
				 * writer thread has finished waiting for
				 * the current buffer to be written. */
    HANDLE readable;		/* Manual-reset event to signal when the
				 * reader thread has finished waiting for
				 * input. */
    HANDLE startWriter;		/* Auto-reset event used by the main thread to
				 * signal when the writer thread should attempt
				 * to write to the serial. */
    HANDLE startReader;		/* Auto-reset event used by the main thread to
				 * signal when the reader thread should attempt
				 * to read from the serial. */
    DWORD writeError;		/* An error caused by the last background
				 * write.  Set to 0 if no error has been
				 * detected.  This word is shared with the
				 * writer thread so access must be
				 * synchronized with the writable object.
				 */
    char *writeBuf;		/* Current background output buffer.
				 * Access is synchronized with the writable
				 * object. */
    int writeBufLen;		/* Size of write buffer.  Access is
				 * synchronized with the writable
				 * object. */
    int toWrite;		/* Current amount to be written.  Access is
				 * synchronized with the writable object. */
    int readFlags;		/* Flags that are shared with the reader
				 * thread.  Access is synchronized with the
				 * readable object.  */
    int writeFlags;		/* Flags that are shared with the writer
				 * thread.  Access is synchronized with the
				 * readable object.  */
    int readyMask;              /* Events that need to be checked on. */
    char extraByte;
    
} SerialInfo;

typedef struct ThreadSpecificData {
    /*
     * The following pointer refers to the head of the list of serials
     * that are being watched for file events.
     */
    
    SerialInfo *firstSerialPtr;
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * The following structure is what is added to the Tcl event queue when
 * serial events are generated.
 */

typedef struct SerialEvent {
    Tcl_Event header;		/* Information that is standard for
				 * all events. */
    SerialInfo *infoPtr;	/* Pointer to serial info structure.  Note
				 * that we still have to verify that the
				 * serial exists before dereferencing this
				 * pointer. */
} SerialEvent;

/*
 * Declarations for functions used only in this file.
 */

static int		SerialBlockProc(ClientData instanceData, int mode);
static void		SerialCheckProc(ClientData clientData, int flags);
static int		SerialCloseProc(ClientData instanceData,
			    Tcl_Interp *interp);
static int		SerialEventProc(Tcl_Event *evPtr, int flags);
static void		SerialExitHandler(ClientData clientData);
static int		SerialGetHandleProc(ClientData instanceData,
			    int direction, ClientData *handlePtr);
static ThreadSpecificData *SerialInit(void);
static int		SerialInputProc(ClientData instanceData, char *buf,
			    int toRead, int *errorCode);
static int		SerialOutputProc(ClientData instanceData, char *buf,
			    int toWrite, int *errorCode);
static DWORD WINAPI	SerialReaderThread(LPVOID arg);
static void		SerialSetupProc(ClientData clientData, int flags);
static void		SerialWatchProc(ClientData instanceData, int mask);
static DWORD WINAPI	SerialWriterThread(LPVOID arg);
static void		ProcExitHandler(ClientData clientData);
static int		WaitForRead(SerialInfo *infoPtr, int blocking);
static int	     SerialGetOptionProc _ANSI_ARGS_((ClientData instanceData, 
			    Tcl_Interp *interp, char *optionName,
			    Tcl_DString *dsPtr));
static int	     SerialSetOptionProc _ANSI_ARGS_((ClientData instanceData,
			    Tcl_Interp *interp, char *optionName, 
			    char *value));

/*
 * This structure describes the channel type structure for command serial
 * based IO.
 */

static Tcl_ChannelType serialChannelType = {
    "serial",			/* Type name. */
    SerialBlockProc,	        /* Set blocking or non-blocking mode.*/
    SerialCloseProc,		/* Close proc. */
    SerialInputProc,		/* Input proc. */
    SerialOutputProc,		/* Output proc. */
    NULL,			/* Seek proc. */
    SerialSetOptionProc,	/* Set option proc. */
    SerialGetOptionProc,	/* Get option proc. */
    SerialWatchProc,		/* Set up notifier to watch the channel. */
    SerialGetHandleProc,	/* Get an OS handle from channel. */
};

/*
 *----------------------------------------------------------------------
 *
 * SerialInit --
 *
 *	This function initializes the static variables for this file.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Creates a new event source.
 *
 *----------------------------------------------------------------------
 */

static ThreadSpecificData *
SerialInit()
{
    ThreadSpecificData *tsdPtr;

    /*
     * Check the initialized flag first, then check it again in the mutex.
     * This is a speed enhancement.
     */
    
    if (!initialized) {
	Tcl_MutexLock(&serialMutex);
	if (!initialized) {
	    initialized = 1;
	    Tcl_CreateExitHandler(ProcExitHandler, NULL);
	}
	Tcl_MutexUnlock(&serialMutex);
    }

    tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
	tsdPtr->firstSerialPtr = NULL;
	Tcl_CreateEventSource(SerialSetupProc, SerialCheckProc, NULL);
	Tcl_CreateThreadExitHandler(SerialExitHandler, NULL);
    }
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * SerialExitHandler --
 *
 *	This function is called to cleanup the serial module before
 *	Tcl is unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Removes the serial event source.
 *
 *----------------------------------------------------------------------
 */

static void
SerialExitHandler(
    ClientData clientData)	/* Old window proc */
{
    Tcl_DeleteEventSource(SerialSetupProc, SerialCheckProc, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * ProcExitHandler --
 *
 *	This function is called to cleanup the process list before
 *	Tcl is unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Resets the process list.
 *
 *----------------------------------------------------------------------
 */

static void
ProcExitHandler(
    ClientData clientData)	/* Old window proc */
{
    Tcl_MutexLock(&serialMutex);
    initialized = 0;
    Tcl_MutexUnlock(&serialMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * SerialSetupProc --
 *
 *	This procedure is invoked before Tcl_DoOneEvent blocks waiting
 *	for an event.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Adjusts the block time if needed.
 *
 *----------------------------------------------------------------------
 */

void
SerialSetupProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    SerialInfo *infoPtr;
    Tcl_Time blockTime = { 0, 0 };
    int block = 1;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Look to see if any events are already pending.  If they are, poll.
     */

    for (infoPtr = tsdPtr->firstSerialPtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask & TCL_WRITABLE) {
	    if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) {
		block = 0;
	    }
	}
	if (infoPtr->watchMask & TCL_READABLE) {
	    if (WaitForRead(infoPtr, 0) >= 0) {
		block = 0;
	    }
	}
    }
    if (!block) {
	Tcl_SetMaxBlockTime(&blockTime);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SerialCheckProc --
 *
 *	This procedure is called by Tcl_DoOneEvent to check the serial
 *	event source for events. 
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May queue an event.
 *
 *----------------------------------------------------------------------
 */

static void
SerialCheckProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    SerialInfo *infoPtr;
    SerialEvent *evPtr;
    int needEvent;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Queue events for any ready serials that don't already have events
     * queued.
     */

    for (infoPtr = tsdPtr->firstSerialPtr; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->flags & SERIAL_PENDING) {
	    continue;
	}
	
	/*
	 * Queue an event if the serial is signaled for reading or writing.
	 */

	needEvent = 0;
	if (infoPtr->watchMask & TCL_WRITABLE) {
	    if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) {
		needEvent = 1;
	    }
	}
	
	if (infoPtr->watchMask & TCL_READABLE) {
	    if (WaitForRead(infoPtr, 0) >= 0) {
		needEvent = 1;
	    }
	}

	if (needEvent) {
	    infoPtr->flags |= SERIAL_PENDING;
	    evPtr = (SerialEvent *) ckalloc(sizeof(SerialEvent));
	    evPtr->header.proc = SerialEventProc;
	    evPtr->infoPtr = infoPtr;
	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SerialBlockProc --
 *
 *	Set blocking or non-blocking mode on channel.
 *
 * Results:
 *	0 if successful, errno when failed.
 *
 * Side effects:
 *	Sets the device into blocking or non-blocking mode.
 *
 *----------------------------------------------------------------------
 */

static int
SerialBlockProc(
    ClientData instanceData,	/* Instance data for channel. */
    int mode)			/* TCL_MODE_BLOCKING or
                                 * TCL_MODE_NONBLOCKING. */
{
    SerialInfo *infoPtr = (SerialInfo *) instanceData;
    
    /*
     * Serial IO on Windows can not be switched between blocking & nonblocking,
     * hence we have to emulate the behavior. This is done in the input
     * function by checking against a bit in the state. We set or unset the
     * bit here to cause the input function to emulate the correct behavior.
     */

    if (mode == TCL_MODE_NONBLOCKING) {
	infoPtr->flags |= SERIAL_ASYNC;
    } else {
	infoPtr->flags &= ~(SERIAL_ASYNC);
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * SerialCloseProc --
 *
 *	Closes a serial based IO channel.
 *
 * Results:
 *	0 on success, errno otherwise.
 *
 * Side effects:
 *	Closes the physical channel.
 *
 *----------------------------------------------------------------------
 */

static int
SerialCloseProc(
    ClientData instanceData,	/* Pointer to SerialInfo structure. */
    Tcl_Interp *interp)		/* For error reporting. */
{
    SerialInfo *serialPtr = (SerialInfo *) instanceData;
    int errorCode, result = 0;
    SerialInfo *infoPtr, **nextPtrPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    errorCode = 0;
    if (serialPtr->readThread) {
	/*
	 * Forcibly terminate the background thread.  We cannot rely on the
	 * thread to cleanly terminate itself because we have no way of
	 * closing the handle without blocking in the case where the
	 * thread is in the middle of an I/O operation.  Note that we need
	 * to guard against terminating the thread while it is in the
	 * middle of Tcl_ThreadAlert because it won't be able to release
	 * the notifier lock.
	 */

	Tcl_MutexLock(&serialMutex);
	TerminateThread(serialPtr->readThread, 0);
	Tcl_MutexUnlock(&serialMutex);

	/*
	 * Wait for the thread to terminate.  This ensures that we are
	 * completely cleaned up before we leave this function. 
	 */

	WaitForSingleObject(serialPtr->readThread, INFINITE);
	CloseHandle(serialPtr->readThread);
	CloseHandle(serialPtr->readable);
	CloseHandle(serialPtr->startReader);
	serialPtr->readThread = NULL;
    }
    serialPtr->validMask &= ~TCL_READABLE;

    if (serialPtr->writeThread) {
	WaitForSingleObject(serialPtr->writable, INFINITE);

	/*
	 * Forcibly terminate the background thread.  We cannot rely on the
	 * thread to cleanly terminate itself because we have no way of
	 * closing the handle without blocking in the case where the
	 * thread is in the middle of an I/O operation.  Note that we need
	 * to guard against terminating the thread while it is in the
	 * middle of Tcl_ThreadAlert because it won't be able to release
	 * the notifier lock.
	 */

	Tcl_MutexLock(&serialMutex);
	TerminateThread(serialPtr->writeThread, 0);
	Tcl_MutexUnlock(&serialMutex);

	/*
	 * Wait for the thread to terminate.  This ensures that we are
	 * completely cleaned up before we leave this function. 
	 */

	WaitForSingleObject(serialPtr->writeThread, INFINITE);
	CloseHandle(serialPtr->writeThread);
	CloseHandle(serialPtr->writable);
	CloseHandle(serialPtr->startWriter);
	serialPtr->writeThread = NULL;
    }
    serialPtr->validMask &= ~TCL_WRITABLE;

    /*
     * Don't close the Win32 handle if the handle is a standard channel
     * during the exit process.  Otherwise, one thread may kill the stdio
     * of another.
     */

    if (!TclInExit() 
	    || ((GetStdHandle(STD_INPUT_HANDLE) != serialPtr->handle)
		&& (GetStdHandle(STD_OUTPUT_HANDLE) != serialPtr->handle)
		&& (GetStdHandle(STD_ERROR_HANDLE) != serialPtr->handle))) {
	if (CloseHandle(serialPtr->handle) == FALSE) {
	    TclWinConvertError(GetLastError());
	    errorCode = errno;
	}
    }
    
    serialPtr->watchMask &= serialPtr->validMask;

    /*
     * Remove the file from the list of watched files.
     */

    for (nextPtrPtr = &(tsdPtr->firstSerialPtr), infoPtr = *nextPtrPtr;
	    infoPtr != NULL;
	    nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) {
	if (infoPtr == (SerialInfo *)serialPtr) {
	    *nextPtrPtr = infoPtr->nextPtr;
	    break;
	}
    }

    /*
     * Wrap the error file into a channel and give it to the cleanup
     * routine. 
     */

    if (serialPtr->writeBuf != NULL) {
	ckfree(serialPtr->writeBuf);
	serialPtr->writeBuf = NULL;
    }

    ckfree((char*) serialPtr);

    if (errorCode == 0) {
        return result;
    }
    return errorCode;
}

/*
 *----------------------------------------------------------------------
 *
 * SerialInputProc --
 *
 *	Reads input from the IO channel into the buffer given. Returns
 *	count of how many bytes were actually read, and an error indication.
 *
 * Results:
 *	A count of how many bytes were read is returned and an error
 *	indication is returned in an output argument.
 *
 * Side effects:
 *	Reads input from the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
SerialInputProc(
    ClientData instanceData,		/* Serial state. */
    char *buf,				/* Where to store data read. */
    int bufSize,			/* How much space is available
                                         * in the buffer? */
    int *errorCode)			/* Where to store error code. */
{
    SerialInfo *infoPtr = (SerialInfo *) instanceData;
    DWORD bytesRead = 0;
    int result;
    DWORD err;

    *errorCode = 0;

    /*
     * Synchronize with the reader thread.
     */
    
    result = WaitForRead(infoPtr, (infoPtr->flags & SERIAL_ASYNC) ? 0 : 1);
    
    /*
     * If an error occurred, return immediately.
     */
    
    if (result == -1) {
	*errorCode = errno;
	return -1;
    }

    if (infoPtr->readFlags & SERIAL_EXTRABYTE) {

	/*
	 * If a byte was consumed waiting, then put it in the buffer.
	 */

	*buf = infoPtr->extraByte;
	infoPtr->readFlags &= ~SERIAL_EXTRABYTE;
	buf++;
	bufSize--;
	bytesRead = 1;

	if (result == 0) {
	    return bytesRead;
	}
    }

    if (ReadFile(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &bytesRead,
		 NULL) == FALSE) {
	err = GetLastError();
	if (err != ERROR_IO_PENDING) {
	    goto error;
	}
    }
	
    return bytesRead;
	
    error:
    TclWinConvertError(GetLastError());
    *errorCode = errno;
    return -1;
}

/*
 *----------------------------------------------------------------------
 *
 * SerialOutputProc --
 *
 *	Writes the given output on the IO channel. Returns count of how
 *	many characters were actually written, and an error indication.
 *
 * Results:
 *	A count of how many characters were written is returned and an
 *	error indication is returned in an output argument.
 *
 * Side effects:
 *	Writes output on the actual channel.
 *
 *----------------------------------------------------------------------
 */

static int
SerialOutputProc(
    ClientData instanceData,		/* Serial state. */
    char *buf,				/* The data buffer. */
    int toWrite,			/* How many bytes to write? */
    int *errorCode)			/* Where to store error code. */
{
    SerialInfo *infoPtr = (SerialInfo *) instanceData;
    DWORD bytesWritten, timeout, err;

    *errorCode = 0;
    timeout = (infoPtr->flags & SERIAL_ASYNC) ? 0 : INFINITE;
    if (WaitForSingleObject(infoPtr->writable, timeout) == WAIT_TIMEOUT) {
	/*
	 * The writer thread is blocked waiting for a write to complete
	 * and the channel is in non-blocking mode.
	 */

	errno = EAGAIN;
	goto error;
    }
    
    /*
     * Check for a background error on the last write.
     */

    if (infoPtr->writeError) {
	TclWinConvertError(infoPtr->writeError);
	infoPtr->writeError = 0;
	goto error;
    }

    if (infoPtr->flags & SERIAL_ASYNC) {
	/*
	 * The serial is non-blocking, so copy the data into the output
	 * buffer and restart the writer thread.
	 */

	if (toWrite > infoPtr->writeBufLen) {
	    /*
	     * Reallocate the buffer to be large enough to hold the data.
	     */

	    if (infoPtr->writeBuf) {
		ckfree(infoPtr->writeBuf);
	    }
	    infoPtr->writeBufLen = toWrite;
	    infoPtr->writeBuf = ckalloc(toWrite);
	}
	memcpy(infoPtr->writeBuf, buf, toWrite);
	infoPtr->toWrite = toWrite;
	ResetEvent(infoPtr->writable);
	SetEvent(infoPtr->startWriter);
	bytesWritten = toWrite;
    } else {
	/*
	 * In the blocking case, just try to write the buffer directly.
	 * This avoids an unnecessary copy.
	 */
	if (WriteFile(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite,
		&bytesWritten, NULL) == FALSE) {
	    err = GetLastError();
	    if (err != ERROR_IO_PENDING) {
		TclWinConvertError(GetLastError());
		goto error;
	    }
	}
    }
    return bytesWritten;

    error:
    *errorCode = errno;
    return -1;

}

/*
 *----------------------------------------------------------------------
 *
 * SerialEventProc --
 *
 *	This function is invoked by Tcl_ServiceEvent when a file event
 *	reaches the front of the event queue.  This procedure invokes
 *	Tcl_NotifyChannel on the serial.
 *
 * Results:
 *	Returns 1 if the event was handled, meaning it should be removed
 *	from the queue.  Returns 0 if the event was not handled, meaning
 *	it should stay on the queue.  The only time the event isn't
 *	handled is if the TCL_FILE_EVENTS flag bit isn't set.
 *
 * Side effects:
 *	Whatever the notifier callback does.
 *
 *----------------------------------------------------------------------
 */

static int
SerialEventProc(
    Tcl_Event *evPtr,		/* Event to service. */
    int flags)			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    SerialEvent *serialEvPtr = (SerialEvent *)evPtr;
    SerialInfo *infoPtr;
    int mask;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the list of watched serials for the one whose handle
     * matches the event.  We do this rather than simply dereferencing
     * the handle in the event so that serials can be deleted while the
     * event is in the queue.
     */

    for (infoPtr = tsdPtr->firstSerialPtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (serialEvPtr->infoPtr == infoPtr) {
	    infoPtr->flags &= ~(SERIAL_PENDING);
	    break;
	}
    }
    /*
     * Remove stale events.
     */

    if (!infoPtr) {
	return 1;
    }

    /*
     * Check to see if the serial is readable.  Note
     * that we can't tell if a serial is writable, so we always report it
     * as being writable unless we have detected EOF.
     */

    mask = 0;
    if (infoPtr->watchMask & TCL_WRITABLE) {
	if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) {
	  mask = TCL_WRITABLE;
	}
    }

    if (infoPtr->watchMask & TCL_READABLE) {
	if (WaitForRead(infoPtr, 0) >= 0) {
	    if (infoPtr->readFlags & SERIAL_EOF) {
		mask = TCL_READABLE;
	    } else {
		mask |= TCL_READABLE;
	    }
	} 
    }

    /*
     * Inform the channel of the events.
     */

    Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask & mask);
    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * SerialWatchProc --
 *
 *	Called by the notifier to set up to watch for events on this
 *	channel.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
SerialWatchProc(
    ClientData instanceData,		/* Serial state. */
    int mask)				/* What events to watch for, OR-ed
                                         * combination of TCL_READABLE,
                                         * TCL_WRITABLE and TCL_EXCEPTION. */
{
    SerialInfo **nextPtrPtr, *ptr;
    SerialInfo *infoPtr = (SerialInfo *) instanceData;
    int oldMask = infoPtr->watchMask;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Since the file is always ready for events, we set the block time
     * to zero so we will poll.
     */

    infoPtr->watchMask = mask & infoPtr->validMask;
    if (infoPtr->watchMask) {
	Tcl_Time blockTime = { 0, 0 };
	if (!oldMask) {
	    infoPtr->nextPtr = tsdPtr->firstSerialPtr;
	    tsdPtr->firstSerialPtr = infoPtr;
	}
	Tcl_SetMaxBlockTime(&blockTime);
    } else {
	if (oldMask) {
	    /*
	     * Remove the serial port from the list of watched serial ports.
	     */

	    for (nextPtrPtr = &(tsdPtr->firstSerialPtr), ptr = *nextPtrPtr;
		 ptr != NULL;
		 nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
		if (infoPtr == ptr) {
		    *nextPtrPtr = ptr->nextPtr;
		    break;
		}
	    }
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SerialGetHandleProc --
 *
 *	Called from Tcl_GetChannelHandle to retrieve OS handles from
 *	inside a command serial port based channel.
 *
 * Results:
 *	Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
 *	there is no handle for the specified direction. 
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
SerialGetHandleProc(
    ClientData instanceData,	/* The serial state. */
    int direction,		/* TCL_READABLE or TCL_WRITABLE */
    ClientData *handlePtr)	/* Where to store the handle.  */
{
    SerialInfo *infoPtr = (SerialInfo *) instanceData;

    *handlePtr = (ClientData) infoPtr->handle;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WaitForRead --
 *
 *	Wait until some data is available, the serial is at
 *	EOF or the reader thread is blocked waiting for data (if the
 *	channel is in non-blocking mode).
 *
 * Results:
 *	Returns 1 if serial is readable.  Returns 0 if there is no data
 *	on the serial, but there is buffered data.  Returns -1 if an
 *	error occurred.  If an error occurred, the threads may not
 *	be synchronized.
 *
 * Side effects:
 *	Updates the shared state flags and may consume 1 byte of data
 *	from the serial.  If no error occurred, the reader thread is
 *	blocked waiting for a signal from the main thread.
 *
 *----------------------------------------------------------------------
 */

static int
WaitForRead(
    SerialInfo *infoPtr,	/* Serial state. */
    int blocking)		/* Indicates whether call should be
				 * blocking or not. */
{
    DWORD timeout, errors;
    HANDLE *handle = infoPtr->handle;
    COMSTAT stat;
    
    while (1) {
	/*
	 * Synchronize with the reader thread.
	 */
	
	timeout = blocking ? INFINITE : 0;
	if (WaitForSingleObject(infoPtr->readable, timeout) == WAIT_TIMEOUT) {
	    /*
	     * The reader thread is blocked waiting for data and the channel
	     * is in non-blocking mode.
	     */
	    
	    errno = EAGAIN;
	    return -1;
	}
	
	/*
	 * At this point, the two threads are synchronized, so it is safe
	 * to access shared state.  This code is not called in the ReaderThread
	 * in blocking mode, so it needs to be checked here.
	 */

	/*
	 * If the serial has hit EOF, it is always readable.
	 */
    
	if (infoPtr->readFlags & SERIAL_EOF) {
	    return 1;
	}
	
	if (ClearCommError(infoPtr->handle, &errors, &stat)) {
	    /*
	     * If there are errors, then signal an I/O error.
	     */

	    if (errors != 0) {
		errno = EIO;
		return -1;
	    }
	}
	
	/*
	 * If data is in the queue return 1
	 */
	
	if (stat.cbInQue != 0) {
	    return 1;
	}

	/*
	 * if there is an extra byte that was consumed while
	 * waiting, but no data in the queue, return 0
	 */
	
	if (infoPtr->readFlags & SERIAL_EXTRABYTE) {
	    return 0;
	}
	    
	ResetEvent(infoPtr->readable);
	SetEvent(infoPtr->startReader);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SerialReaderThread --
 *
 *	This function runs in a separate thread and waits for input
 *	to become available on a serial.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Signals the main thread when input become available.  May
 *	cause the main thread to wake up by posting a message.  May
 *	consume one byte from the serial for each wait operation.
 *
 *----------------------------------------------------------------------
 */

static DWORD WINAPI
SerialReaderThread(LPVOID arg)
{
    SerialInfo *infoPtr = (SerialInfo *)arg;
    HANDLE *handle = infoPtr->handle;
    DWORD mask = EV_RXCHAR;
    DWORD count;
    
    for (;;) {
	/*
	 * Wait for the main thread to signal before attempting to wait.
	 */

	WaitForSingleObject(infoPtr->startReader, INFINITE);

	/*
	 * Try waiting for a Comm event.
	 */
	
	WaitCommEvent(handle, NULL, NULL);
	

	/*
	 * try to read one byte
	 */
	
	if (ReadFile(handle, &(infoPtr->extraByte), 1, &count, NULL)
		!= FALSE) {

	    /*
	     * one byte was consumed while waiting to read, keep it
	     */

	    if (count != 0) {
		infoPtr->readFlags |= SERIAL_EXTRABYTE;
	    }

	} else {
            /*
	     * There is an error, signal an EOF.
	     */
	    
	    infoPtr->readFlags |= SERIAL_EOF;
	}

	/*
	 * Signal the main thread by signalling the readable event and
	 * then waking up the notifier thread.
	 */

	SetEvent(infoPtr->readable);

	/*
	 * Alert the foreground thread.  Note that we need to treat this like
	 * a critical section so the foreground thread does not terminate
	 * this thread while we are holding a mutex in the notifier code.
	 */

	Tcl_MutexLock(&serialMutex);
	Tcl_ThreadAlert(infoPtr->threadId);
	Tcl_MutexUnlock(&serialMutex);
    }
    return 0;			/* NOT REACHED */
}

/*
 *----------------------------------------------------------------------
 *
 * SerialWriterThread --
 *
 *	This function runs in a separate thread and writes data
 *	onto a serial.
 *
 * Results:
 *	Always returns 0.
 *
 * Side effects:
 *	Signals the main thread when an output operation is completed.
 *	May cause the main thread to wake up by posting a message.  
 *
 *----------------------------------------------------------------------
 */

static DWORD WINAPI
SerialWriterThread(LPVOID arg)
{

    SerialInfo *infoPtr = (SerialInfo *)arg;
    HANDLE *handle = infoPtr->handle;
    DWORD count, toWrite, err;
    char *buf;

    for (;;) {
	/*
	 * Wait for the main thread to signal before attempting to write.
	 */

	WaitForSingleObject(infoPtr->startWriter, INFINITE);

	buf = infoPtr->writeBuf;
	toWrite = infoPtr->toWrite;

	/*
	 * Loop until all of the bytes are written or an error occurs.
	 */

	while (toWrite > 0) {
	    if (WriteFile(handle, (LPVOID) buf, (DWORD) toWrite,
			  &count, NULL) == FALSE) {
		err = GetLastError();
		if (err != ERROR_IO_PENDING) {
		    TclWinConvertError(GetLastError());
		    infoPtr->writeError = err;
		    break;
		}
	    } else {
		toWrite -= count;
		buf += count;
	    }
	}
	
	/*
	 * Signal the main thread by signalling the writable event and
	 * then waking up the notifier thread.
	 */

	SetEvent(infoPtr->writable);

	/*
	 * Alert the foreground thread.  Note that we need to treat this like
	 * a critical section so the foreground thread does not terminate
	 * this thread while we are holding a mutex in the notifier code.
	 */

	Tcl_MutexLock(&serialMutex);
	Tcl_ThreadAlert(infoPtr->threadId);
	Tcl_MutexUnlock(&serialMutex);
    }
    return 0;			/* NOT REACHED */
}



/*
 *----------------------------------------------------------------------
 *
 * TclWinOpenSerialChannel --
 *
 *	Constructs a Serial port channel for the specified standard OS handle.
 *      This is a helper function to break up the construction of 
 *      channels into File, Console, or Serial.
 *
 * Results:
 *	Returns the new channel, or NULL.
 *
 * Side effects:
 *	May open the channel
 *
 *----------------------------------------------------------------------
 */

Tcl_Channel
TclWinOpenSerialChannel(handle, channelName, permissions)
    HANDLE handle;
    char *channelName;
    int permissions;
{
    SerialInfo *infoPtr;
    COMMTIMEOUTS cto;
    ThreadSpecificData *tsdPtr;
    DWORD id;

    tsdPtr = SerialInit();

    SetCommMask(handle, EV_RXCHAR);
    SetupComm(handle, 4096, 4096);
    PurgeComm(handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR
	      | PURGE_RXCLEAR);
    cto.ReadIntervalTimeout = MAXDWORD;
    cto.ReadTotalTimeoutMultiplier = MAXDWORD;
    cto.ReadTotalTimeoutConstant = 1;
    cto.WriteTotalTimeoutMultiplier = 0;
    cto.WriteTotalTimeoutConstant = 0;
    SetCommTimeouts(handle, &cto);
    
    infoPtr = (SerialInfo *) ckalloc((unsigned) sizeof(SerialInfo));
    memset(infoPtr, 0, sizeof(SerialInfo));
    
    infoPtr->validMask = permissions;
    infoPtr->handle = handle;
	
    /*
     * Use the pointer to keep the channel names unique, in case
     * the handles are shared between multiple channels (stdin/stdout).
     */

    wsprintfA(channelName, "file%lx", (int) infoPtr);
	
    infoPtr->channel = Tcl_CreateChannel(&serialChannelType, channelName,
            (ClientData) infoPtr, permissions);
	

    infoPtr->threadId = Tcl_GetCurrentThread();
    
    if (permissions & TCL_READABLE) {
	infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL);
	infoPtr->startReader = CreateEvent(NULL, FALSE, FALSE, NULL);
	infoPtr->readThread = CreateThread(NULL, 8000, SerialReaderThread,
	        infoPtr, 0, &id);
    }
    if (permissions & TCL_WRITABLE) {
	infoPtr->writable = CreateEvent(NULL, TRUE, TRUE, NULL);
	infoPtr->startWriter = CreateEvent(NULL, FALSE, FALSE, NULL);
	infoPtr->writeThread = CreateThread(NULL, 8000, SerialWriterThread,
	        infoPtr, 0, &id);
    }

    /*
     * Files have default translation of AUTO and ^Z eof char, which
     * means that a ^Z will be accepted as EOF when reading.
     */
    
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto");
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}");

    return infoPtr->channel;
}

/*
 *----------------------------------------------------------------------
 *
 * SerialSetOptionProc --
 *
 *	Sets an option on a channel.
 *
 * Results:
 *	A standard Tcl result. Also sets the interp's result on error if
 *	interp is not NULL.
 *
 * Side effects:
 *	May modify an option on a device.
 *
 *----------------------------------------------------------------------
 */

static int		
SerialSetOptionProc(instanceData, interp, optionName, value)
    ClientData instanceData;	/* File state. */
    Tcl_Interp *interp;		/* For error reporting - can be NULL. */
    char *optionName;		/* Which option to set? */
    char *value;		/* New value for option. */
{
    SerialInfo *infoPtr;
    DCB dcb;
    int len;
    BOOL result;
    Tcl_DString ds;
    TCHAR *native;

    infoPtr = (SerialInfo *) instanceData;

    len = strlen(optionName);
    if ((len > 1) && (strncmp(optionName, "-mode", len) == 0)) {
	if (GetCommState(infoPtr->handle, &dcb)) {
	    native = Tcl_WinUtfToTChar(value, -1, &ds);
	    result = (*tclWinProcs->buildCommDCBProc)(native, &dcb);
	    Tcl_DStringFree(&ds);

	    if ((result == FALSE) || 
		    (SetCommState(infoPtr->handle, &dcb) == FALSE)) {
		/*
		 * one should separate the 2 errors... 
		 */

                if (interp) {
                    Tcl_AppendResult(interp, "bad value for -mode: should be ",
			    "baud,parity,data,stop", NULL);
		}
		return TCL_ERROR;
	    } else {
		return TCL_OK;
	    }
	} else {
	    if (interp) {
		Tcl_AppendResult(interp, "can't get comm state", NULL);
	    }
	    return TCL_ERROR;
	}
    } else {
	return Tcl_BadChannelOption(interp, optionName, "mode");
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SerialGetOptionProc --
 *
 *	Gets a mode associated with an IO channel. If the optionName arg
 *	is non NULL, retrieves the value of that option. If the optionName
 *	arg is NULL, retrieves a list of alternating option names and
 *	values for the given channel.
 *
 * Results:
 *	A standard Tcl result. Also sets the supplied DString to the
 *	string value of the option(s) returned.
 *
 * Side effects:
 *	The string returned by this function is in static storage and
 *	may be reused at any time subsequent to the call.
 *
 *----------------------------------------------------------------------
 */
static int		
SerialGetOptionProc(instanceData, interp, optionName, dsPtr)
    ClientData instanceData;	/* File state. */
    Tcl_Interp *interp;          /* For error reporting - can be NULL. */
    char *optionName;		/* Option to get. */
    Tcl_DString *dsPtr;		/* Where to store value(s). */
{
    SerialInfo *infoPtr;
    DCB dcb;
    int len;

    infoPtr = (SerialInfo *) instanceData;

    if (optionName == NULL) {
	Tcl_DStringAppendElement(dsPtr, "-mode");
	len = 0;
    } else {
	len = strlen(optionName);
    }
    if ((len == 0) || 
	    ((len > 1) && (strncmp(optionName, "-mode", len) == 0))) {
	if (GetCommState(infoPtr->handle, &dcb) == 0) {
	    /*
	     * shouldn't we flag an error instead ? 
	     */

	    Tcl_DStringAppendElement(dsPtr, "");

	} else {
	    char parity;
	    char *stop;
	    char buf[2 * TCL_INTEGER_SPACE + 16];

	    parity = 'n';
	    if (dcb.Parity < 4) {
		parity = "noems"[dcb.Parity];
	    }

	    stop = (dcb.StopBits == ONESTOPBIT) ? "1" : 
		    (dcb.StopBits == ONE5STOPBITS) ? "1.5" : "2";

	    wsprintfA(buf, "%d,%c,%d,%s", dcb.BaudRate, parity, dcb.ByteSize,
		    stop);
	    Tcl_DStringAppendElement(dsPtr, buf);
	}
	return TCL_OK;
    } else {
	return Tcl_BadChannelOption(interp, optionName, "mode");
    }
}

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
49
50
51
52
53



54
55
56
57
58
59
60
/* 
 * 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.
 *
 * SCCS: @(#) tclWinSock.c 1.80 97/10/09 18:24:59
 */

#include "tclInt.h"
#include "tclPort.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. */


/*
 * 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.
 */

static struct {
    HINSTANCE hInstance;	/* Handle to WinSock library. */
    HWND hwnd;			/* Handle to window for socket messages. */
    SOCKET (PASCAL FAR *accept)(SOCKET s, struct sockaddr FAR *addr,
	    int FAR *addrlen);
    int (PASCAL FAR *bind)(SOCKET s, const struct sockaddr FAR *addr,
	    int namelen);
    int (PASCAL FAR *closesocket)(SOCKET s);
    int (PASCAL FAR *connect)(SOCKET s, const struct sockaddr FAR *name,
	    int namelen);
    int (PASCAL FAR *ioctlsocket)(SOCKET s, long cmd, u_long FAR *argp);
    int (PASCAL FAR *getsockopt)(SOCKET s, int level, int optname,
	    char FAR * optval, int FAR *optlen);
    u_short (PASCAL FAR *htons)(u_short hostshort);
    unsigned long (PASCAL FAR *inet_addr)(const char FAR * cp);
    char FAR * (PASCAL FAR *inet_ntoa)(struct in_addr in);
    int (PASCAL FAR *listen)(SOCKET s, int backlog);
    u_short (PASCAL FAR *ntohs)(u_short netshort);
    int (PASCAL FAR *recv)(SOCKET s, char FAR * buf, int len, int flags);



    int (PASCAL FAR *send)(SOCKET s, const char FAR * buf, int len, int flags);
    int (PASCAL FAR *setsockopt)(SOCKET s, int level, int optname,
	    const char FAR * optval, int optlen);
    int (PASCAL FAR *shutdown)(SOCKET s, int how);
    SOCKET (PASCAL FAR *socket)(int af, int type, int protocol);
    struct hostent FAR * (PASCAL FAR *gethostbyname)(const char FAR * name);
    struct hostent FAR * (PASCAL FAR *gethostbyaddr)(const char FAR *addr,










|


|
<











>










<
















>
>
>







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
/* 
 * 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.1.2.10 1999/04/14 00:34:03 surles 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.
 */

static struct {
    HINSTANCE hInstance;	/* Handle to WinSock library. */

    SOCKET (PASCAL FAR *accept)(SOCKET s, struct sockaddr FAR *addr,
	    int FAR *addrlen);
    int (PASCAL FAR *bind)(SOCKET s, const struct sockaddr FAR *addr,
	    int namelen);
    int (PASCAL FAR *closesocket)(SOCKET s);
    int (PASCAL FAR *connect)(SOCKET s, const struct sockaddr FAR *name,
	    int namelen);
    int (PASCAL FAR *ioctlsocket)(SOCKET s, long cmd, u_long FAR *argp);
    int (PASCAL FAR *getsockopt)(SOCKET s, int level, int optname,
	    char FAR * optval, int FAR *optlen);
    u_short (PASCAL FAR *htons)(u_short hostshort);
    unsigned long (PASCAL FAR *inet_addr)(const char FAR * cp);
    char FAR * (PASCAL FAR *inet_ntoa)(struct in_addr in);
    int (PASCAL FAR *listen)(SOCKET s, int backlog);
    u_short (PASCAL FAR *ntohs)(u_short netshort);
    int (PASCAL FAR *recv)(SOCKET s, char FAR * buf, int len, int flags);
    int (PASCAL FAR *select)(int nfds, fd_set FAR * readfds,
	    fd_set FAR * writefds, fd_set FAR * exceptfds,
	    const struct timeval FAR * tiemout);
    int (PASCAL FAR *send)(SOCKET s, const char FAR * buf, int len, int flags);
    int (PASCAL FAR *setsockopt)(SOCKET s, int level, int optname,
	    const char FAR * optval, int optlen);
    int (PASCAL FAR *shutdown)(SOCKET s, int how);
    SOCKET (PASCAL FAR *socket)(int af, int type, int protocol);
    struct hostent FAR * (PASCAL FAR *gethostbyname)(const char FAR * name);
    struct hostent FAR * (PASCAL FAR *gethostbyaddr)(const char FAR *addr,
135
136
137
138
139
140
141

142
143
144
145

146



147
148
149
150
151
152
153
#define SOCKET_ASYNC		(1<<0)	/* The socket is in blocking mode. */
#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 */


/*
 * Every open socket has an entry on the following list.
 */


static SocketInfo *socketList;




/*
 * Static functions defined in this file.
 */

static SocketInfo *	CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,
			    int port, char *host, int server, char *myaddr,







>
|
|
|
|
>
|
>
>
>







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#define SOCKET_ASYNC		(1<<0)	/* The socket is in blocking mode. */
#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,
			    int port, char *host, int server, char *myaddr,
162
163
164
165
166
167
168


169
170
171
172
173
174
175
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		TcpAccept _ANSI_ARGS_((SocketInfo *infoPtr));
static int		TcpBlockProc _ANSI_ARGS_((ClientData instanceData,
			    int mode));
static int		TcpCloseProc _ANSI_ARGS_((ClientData instanceData,
	            	    Tcl_Interp *interp));
static int		TcpGetOptionProc _ANSI_ARGS_((ClientData instanceData,
		            Tcl_Interp *interp, char *optionName,







>
>







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
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));
static int		TcpCloseProc _ANSI_ARGS_((ClientData instanceData,
	            	    Tcl_Interp *interp));
static int		TcpGetOptionProc _ANSI_ARGS_((ClientData instanceData,
		            Tcl_Interp *interp, char *optionName,
214
215
216
217
218
219
220


221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237


238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299




300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400

401


402



403




404

405






406


407


408

409
410

411


412
413
414
415
416
417
418




























419
420
421
422
423
424
425
 *
 * 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;
    OSVERSIONINFO info;
    WNDCLASS class;




    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)
	    || (SearchPath(NULL, "WINSOCK", ".DLL", 0, NULL, NULL) != 0)) {
	winSock.hInstance = LoadLibrary("wsock32.dll");
    } else {
	winSock.hInstance = NULL;
    }

    /*
     * Initialize the function table.
     */

    if (winSock.hInstance == NULL) {
	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,
            const struct sockaddr FAR *addr, int namelen))
        GetProcAddress(winSock.hInstance, "bind");
    winSock.closesocket = (int (PASCAL FAR *)(SOCKET s))
        GetProcAddress(winSock.hInstance, "closesocket");
    winSock.connect = (int (PASCAL FAR *)(SOCKET s,
            const struct sockaddr FAR *name, int namelen))
        GetProcAddress(winSock.hInstance, "connect");
    winSock.ioctlsocket = (int (PASCAL FAR *)(SOCKET s, long cmd,

            u_long FAR *argp)) GetProcAddress(winSock.hInstance, "ioctlsocket");
    winSock.getsockopt = (int (PASCAL FAR *)(SOCKET s,
            int level, int optname, char FAR * optval, int FAR *optlen))
        GetProcAddress(winSock.hInstance, "getsockopt");
    winSock.htons = (u_short (PASCAL FAR *)(u_short hostshort))
        GetProcAddress(winSock.hInstance, "htons");
    winSock.inet_addr = (unsigned long (PASCAL FAR *)(const char FAR *cp))
        GetProcAddress(winSock.hInstance, "inet_addr");
    winSock.inet_ntoa = (char FAR * (PASCAL FAR *)(struct in_addr in))
        GetProcAddress(winSock.hInstance, "inet_ntoa");
    winSock.listen = (int (PASCAL FAR *)(SOCKET s, int backlog))
        GetProcAddress(winSock.hInstance, "listen");
    winSock.ntohs = (u_short (PASCAL FAR *)(u_short netshort))
        GetProcAddress(winSock.hInstance, "ntohs");
    winSock.recv = (int (PASCAL FAR *)(SOCKET s, char FAR * buf,
            int len, int flags)) GetProcAddress(winSock.hInstance, "recv");




    winSock.send = (int (PASCAL FAR *)(SOCKET s, const char FAR * buf,
            int len, int flags)) GetProcAddress(winSock.hInstance, "send");
    winSock.setsockopt = (int (PASCAL FAR *)(SOCKET s, int level,
            int optname, const char FAR * optval, int optlen))
        GetProcAddress(winSock.hInstance, "setsockopt");
    winSock.shutdown = (int (PASCAL FAR *)(SOCKET s, int how))
        GetProcAddress(winSock.hInstance, "shutdown");
    winSock.socket = (SOCKET (PASCAL FAR *)(int af, int type,
            int protocol)) GetProcAddress(winSock.hInstance, "socket");
    winSock.gethostbyaddr = (struct hostent FAR * (PASCAL FAR *)
            (const char FAR *addr, int addrlen, int addrtype))
        GetProcAddress(winSock.hInstance, "gethostbyaddr");
    winSock.gethostbyname = (struct hostent FAR * (PASCAL FAR *)
            (const char FAR *name))
        GetProcAddress(winSock.hInstance, "gethostbyname");
    winSock.gethostname = (int (PASCAL FAR *)(char FAR * name,
            int namelen)) GetProcAddress(winSock.hInstance, "gethostname");
    winSock.getpeername = (int (PASCAL FAR *)(SOCKET sock,
            struct sockaddr FAR *name, int FAR *namelen))
        GetProcAddress(winSock.hInstance, "getpeername");
    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) ||
            (winSock.bind == NULL) ||
            (winSock.closesocket == NULL) ||
            (winSock.connect == NULL) ||
            (winSock.ioctlsocket == NULL) ||
            (winSock.getsockopt == NULL) ||
            (winSock.htons == NULL) ||
            (winSock.inet_addr == NULL) ||
            (winSock.inet_ntoa == NULL) ||
            (winSock.listen == NULL) ||
            (winSock.ntohs == NULL) ||
            (winSock.recv == NULL) ||

            (winSock.send == NULL) ||
            (winSock.setsockopt == NULL) ||
            (winSock.socket == NULL) ||
            (winSock.gethostbyname == NULL) ||
            (winSock.gethostbyaddr == NULL) ||
            (winSock.gethostname == NULL) ||
            (winSock.getpeername == NULL) ||
            (winSock.getservbyname == NULL) ||
            (winSock.getsockname == NULL) ||
            (winSock.WSAStartup == NULL) ||
            (winSock.WSACleanup == NULL) ||
            (winSock.WSAGetLastError == NULL) ||
            (winSock.WSAAsyncSelect == NULL)) {
	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;
    }

    /*
     * 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 (RegisterClass(&class)) {

	winSock.hwnd = CreateWindow("TclSocket", "TclSocket", WS_TILED, 0, 0,


		0, 0, NULL, NULL, class.hInstance, NULL);



    } else {




	winSock.hwnd = NULL;

    }






    if (winSock.hwnd == NULL) {


	TclWinConvertError(GetLastError());


	(*winSock.WSACleanup)();

	goto unloadLibrary;
    }

    Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);


    return;

unloadLibrary:
    FreeLibrary(winSock.hInstance);
    winSock.hInstance = NULL;
    return;
}





























/*
 *----------------------------------------------------------------------
 *
 * SocketExitHandler --
 *
 *	Callback invoked during exit clean up to delete the socket







>
>
















|
>
>

>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
>
|
>
>
|
>
>
>
|
>
>
>
>
|
>
|
>
>
>
>
>
>
|
>
>
|
>
>
|
>
|
|
>
|
>
>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386












387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
 *
 * 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,
		const struct sockaddr FAR *addr, int namelen))
	    GetProcAddress(winSock.hInstance, "bind");
	winSock.closesocket = (int (PASCAL FAR *)(SOCKET s))
	    GetProcAddress(winSock.hInstance, "closesocket");
	winSock.connect = (int (PASCAL FAR *)(SOCKET s,
		const struct sockaddr FAR *name, int namelen))
	    GetProcAddress(winSock.hInstance, "connect");
	winSock.ioctlsocket = (int (PASCAL FAR *)(SOCKET s, long cmd,
		u_long FAR *argp))
	    GetProcAddress(winSock.hInstance, "ioctlsocket");
	winSock.getsockopt = (int (PASCAL FAR *)(SOCKET s,
		int level, int optname, char FAR * optval, int FAR *optlen))
	    GetProcAddress(winSock.hInstance, "getsockopt");
	winSock.htons = (u_short (PASCAL FAR *)(u_short hostshort))
	    GetProcAddress(winSock.hInstance, "htons");
	winSock.inet_addr = (unsigned long (PASCAL FAR *)(const char FAR *cp))
	    GetProcAddress(winSock.hInstance, "inet_addr");
	winSock.inet_ntoa = (char FAR * (PASCAL FAR *)(struct in_addr in))
	    GetProcAddress(winSock.hInstance, "inet_ntoa");
	winSock.listen = (int (PASCAL FAR *)(SOCKET s, int backlog))
	    GetProcAddress(winSock.hInstance, "listen");
	winSock.ntohs = (u_short (PASCAL FAR *)(u_short netshort))
	    GetProcAddress(winSock.hInstance, "ntohs");
	winSock.recv = (int (PASCAL FAR *)(SOCKET s, char FAR * buf,
		int len, int flags)) GetProcAddress(winSock.hInstance, "recv");
	winSock.select = (int (PASCAL FAR *)(int nfds, fd_set FAR * readfds,
		fd_set FAR * writefds, fd_set FAR * exceptfds,
		const struct timeval FAR * tiemout))
	    GetProcAddress(winSock.hInstance, "select");
	winSock.send = (int (PASCAL FAR *)(SOCKET s, const char FAR * buf,
		int len, int flags)) GetProcAddress(winSock.hInstance, "send");
	winSock.setsockopt = (int (PASCAL FAR *)(SOCKET s, int level,
		int optname, const char FAR * optval, int optlen))
	    GetProcAddress(winSock.hInstance, "setsockopt");
	winSock.shutdown = (int (PASCAL FAR *)(SOCKET s, int how))
	    GetProcAddress(winSock.hInstance, "shutdown");
	winSock.socket = (SOCKET (PASCAL FAR *)(int af, int type,
		int protocol)) GetProcAddress(winSock.hInstance, "socket");
	winSock.gethostbyaddr = (struct hostent FAR * (PASCAL FAR *)
		(const char FAR *addr, int addrlen, int addrtype))
	    GetProcAddress(winSock.hInstance, "gethostbyaddr");
	winSock.gethostbyname = (struct hostent FAR * (PASCAL FAR *)
		(const char FAR *name))
	    GetProcAddress(winSock.hInstance, "gethostbyname");
	winSock.gethostname = (int (PASCAL FAR *)(char FAR * name,
		int namelen)) GetProcAddress(winSock.hInstance, "gethostname");
	winSock.getpeername = (int (PASCAL FAR *)(SOCKET sock,
		struct sockaddr FAR *name, int FAR *namelen))
	    GetProcAddress(winSock.hInstance, "getpeername");
	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) ||
		(winSock.bind == NULL) ||
		(winSock.closesocket == NULL) ||
		(winSock.connect == NULL) ||
		(winSock.ioctlsocket == NULL) ||
		(winSock.getsockopt == NULL) ||
		(winSock.htons == NULL) ||
		(winSock.inet_addr == NULL) ||
		(winSock.inet_ntoa == NULL) ||
		(winSock.listen == NULL) ||
		(winSock.ntohs == NULL) ||
		(winSock.recv == NULL) ||
		(winSock.select == NULL) ||
		(winSock.send == NULL) ||
		(winSock.setsockopt == NULL) ||
		(winSock.socket == NULL) ||
		(winSock.gethostbyname == NULL) ||
		(winSock.gethostbyaddr == NULL) ||
		(winSock.gethostname == NULL) ||
		(winSock.getpeername == NULL) ||
		(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 --
 *
 *	Check that the WinSock DLL is loaded and ready.
 *
 * Results:
 *	1 if it is.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

    /* ARGSUSED */
static int
SocketsEnabled()
{
    int enabled;
    Tcl_MutexLock(&socketMutex);
    enabled = (winSock.hInstance != NULL);
    Tcl_MutexUnlock(&socketMutex);
    return enabled;
}


/*
 *----------------------------------------------------------------------
 *
 * SocketExitHandler --
 *
 *	Callback invoked during exit clean up to delete the socket
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
 */

    /* ARGSUSED */
static void
SocketExitHandler(clientData)
    ClientData clientData;              /* Not used. */
{

    if (winSock.hInstance) {
	DestroyWindow(winSock.hwnd);
	UnregisterClass("TclSocket", TclWinGetTclInstance());
	(*winSock.WSACleanup)();
	FreeLibrary(winSock.hInstance);
	winSock.hInstance = NULL;
    }
    Tcl_DeleteEventSource(SocketSetupProc, SocketCheckProc, NULL);
    initialized = 0;
    hostnameInitialized = 0;































}

/*
 *----------------------------------------------------------------------
 *
 * TclHasSockets --
 *
 *	This function determines whether sockets are available on the
 *	current system and returns an error in interp if they are not.
 *	Note that interp may be NULL.
 *
 * Results:
 *	Returns TCL_OK if the system supports sockets, or TCL_ERROR with
 *	an error in interp.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TclHasSockets(interp)
    Tcl_Interp *interp;
{
    if (!initialized) {
	InitSockets();

    }
    
    if (winSock.hInstance != NULL) {
	return TCL_OK;
    }
    if (interp != NULL) {
	Tcl_AppendResult(interp, "sockets are not available on this system",
		NULL);
    }
    return TCL_ERROR;







>

<
|




<


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
















|


|
|
>
|
|
<







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
 */

    /* 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 --
 *
 *	Callback invoked during thread clean up to delete the socket
 *	event source.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Delete the event source.
 *
 *----------------------------------------------------------------------
 */

    /* ARGSUSED */
static void
SocketThreadExitHandler(clientData)
    ClientData clientData;              /* Not used. */
{
    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    DestroyWindow(tsdPtr->hwnd);

    Tcl_DeleteEventSource(SocketSetupProc, SocketCheckProc, NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpHasSockets --
 *
 *	This function determines whether sockets are available on the
 *	current system and returns an error in interp if they are not.
 *	Note that interp may be NULL.
 *
 * Results:
 *	Returns TCL_OK if the system supports sockets, or TCL_ERROR with
 *	an error in interp.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

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);
    }
    return TCL_ERROR;
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
531
void
SocketSetupProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    SocketInfo *infoPtr;
    Tcl_Time blockTime = { 0, 0 };


    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Check to see if there is a ready socket.  If so, poll.
     */


    for (infoPtr = socketList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (infoPtr->readyEvents & infoPtr->watchEvents) {
	    Tcl_SetMaxBlockTime(&blockTime);
	    break;
	}
    }
}








>









>
|







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
void
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;
	}
    }
}

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
static void
SocketCheckProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    SocketInfo *infoPtr;
    SocketEvent *evPtr;


    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 = 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);







>











>
|







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
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);
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
    Tcl_Event *evPtr;		/* Event to service. */
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    SocketInfo *infoPtr;
    SocketEvent *eventPtr = (SocketEvent *) evPtr;
    int mask = 0;
    u_long nBytes;
    int status, events;


    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Find the specified socket on the socket list.
     */


    for (infoPtr = socketList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (infoPtr->socket == eventPtr->socket) {
	    break;
	}
    }

    /*
     * Discard events that have gone stale.







<
|
>









>
|







697
698
699
700
701
702
703

704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
    Tcl_Event *evPtr;		/* Event to service. */
    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.
661
662
663
664
665
666
667



668
669
670



671
672
673
674
675
676
677
678
679
680
681
682
683

684
685
686
687
688
689
690
691



692
693

694
695
696
697
698
699
700
701
702
703
	 * it's simpler than trying to do unwind protection.
	 */

	Tcl_Time blockTime = { 0, 0 };
	Tcl_SetMaxBlockTime(&blockTime);
	mask |= TCL_READABLE;
    } else if (events & FD_READ) {



	/*
	 * We must check to see if data is really available, since someone
	 * could have consumed the data in the meantime.



	 */

	status = (*winSock.ioctlsocket)(infoPtr->socket, FIONREAD,
		&nBytes);
	if (status != SOCKET_ERROR && nBytes > 0) {
	    mask |= TCL_READABLE;
	} else {
	    /*
	     * We are in a strange state, probably because someone
	     * besides Tcl is reading from this socket.  Try to
	     * recover by clearing the read event.
	     */
	    

	    infoPtr->readyEvents &= ~(FD_READ);

 	    /*
 	     * Re-issue WSAAsyncSelect() since we are gobbling up an
 	     * event,  without letting the reader do any I/O to re-enable
	     * the notification.
 	     */




 	    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd,
 		    SOCKET_MESSAGE, infoPtr->selectEvents);

	}
    }
    if (events & FD_WRITE) {
	mask |= TCL_WRITABLE;
    }

    if (mask) {
	Tcl_NotifyChannel(infoPtr->channel, mask);
    }
    return 1;







>
>
>


|
>
>
>


|
<
<
<
<
<
<
<
<
<
|
>
|
|
<
<
<
|
<
|
>
>
>
|
|
>


|







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775









776
777
778
779



780

781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
	 * it's simpler than trying to do unwind protection.
	 */

	Tcl_Time blockTime = { 0, 0 };
	Tcl_SetMaxBlockTime(&blockTime);
	mask |= TCL_READABLE;
    } else if (events & FD_READ) {
	fd_set readFds;
	struct timeval timeout;

	/*
	 * 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);
    }
    return 1;
758
759
760
761
762
763
764

765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797

798
799
800
801
802
803
804
TcpCloseProc(instanceData, interp)
    ClientData instanceData;	/* The socket to close. */
    Tcl_Interp *interp;		/* Unused. */
{
    SocketInfo *infoPtr = (SocketInfo *) instanceData;
    SocketInfo **nextPtrPtr;
    int errorCode = 0;


    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (winSock.hInstance != NULL) {
        
	/*
         * Clean up the OS socket handle.  The default Windows setting
	 * for a socket is SO_DONTLINGER, which does a graceful shutdown
	 * in the background.
         */
    
        if ((*winSock.closesocket)(infoPtr->socket) == SOCKET_ERROR) {
            TclWinConvertWSAError((*winSock.WSAGetLastError)());
            errorCode = Tcl_GetErrno();
        }
    }

    /*
     * Remove the socket from socketList.
     */

    for (nextPtrPtr = &socketList; (*nextPtrPtr) != NULL;
	 nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
	if ((*nextPtrPtr) == infoPtr) {
	    (*nextPtrPtr) = infoPtr->nextPtr;
	    break;
	}
    }

    ckfree((char *) infoPtr);
    return errorCode;
}

/*
 *----------------------------------------------------------------------
 *







>








|

















|






>







852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
TcpCloseProc(instanceData, interp)
    ClientData instanceData;	/* The socket to close. */
    Tcl_Interp *interp;		/* Unused. */
{
    SocketInfo *infoPtr = (SocketInfo *) instanceData;
    SocketInfo **nextPtrPtr;
    int errorCode = 0;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (SocketsEnabled()) {
        
	/*
         * Clean up the OS socket handle.  The default Windows setting
	 * for a socket is SO_DONTLINGER, which does a graceful shutdown
	 * in the background.
         */
    
        if ((*winSock.closesocket)(infoPtr->socket) == SOCKET_ERROR) {
            TclWinConvertWSAError((*winSock.WSAGetLastError)());
            errorCode = Tcl_GetErrno();
        }
    }

    /*
     * 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;
}

/*
 *----------------------------------------------------------------------
 *
817
818
819
820
821
822
823

824
825
826
827
828
829
830
831
832

833
834

835
836
837
838
839
840
841
 */

static SocketInfo *
NewSocketInfo(socket)
    SOCKET socket;
{
    SocketInfo *infoPtr;


    infoPtr = (SocketInfo *) ckalloc((unsigned) sizeof(SocketInfo));
    infoPtr->socket = socket;
    infoPtr->flags = 0;
    infoPtr->watchEvents = 0;
    infoPtr->readyEvents = 0;
    infoPtr->selectEvents = 0;
    infoPtr->acceptProc = NULL;
    infoPtr->lastError = 0;

    infoPtr->nextPtr = socketList;
    socketList = infoPtr;

    return infoPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateSocket --







>









>
|
|
>







913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
 */

static SocketInfo *
NewSocketInfo(socket)
    SOCKET socket;
{
    SocketInfo *infoPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    infoPtr = (SocketInfo *) ckalloc((unsigned) sizeof(SocketInfo));
    infoPtr->socket = socket;
    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;
}

/*
 *----------------------------------------------------------------------
 *
 * CreateSocket --
867
868
869
870
871
872
873


874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898







899
900
901
902
903
904
905
    u_long flag = 1;			/* Indicates nonblocking mode. */
    int asyncConnect = 0;		/* Will be 1 if async connect is
                                         * in progress. */
    struct sockaddr_in sockaddr;	/* Socket address */
    struct sockaddr_in mysockaddr;	/* Socket address for client */
    SOCKET sock;
    SocketInfo *infoPtr;		/* The returned value. */



    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */
    
    if (winSock.hInstance == NULL) {
        return NULL;
    }
    
    if (! CreateSocketAddress(&sockaddr, host, port)) {
	goto error;
    }
    if ((myaddr != NULL || myport != 0) &&
	    ! CreateSocketAddress(&mysockaddr, myaddr, myport)) {
	goto error;
    }

    sock = (*winSock.socket)(AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET) {
	goto error;
    }








    /*
     * Set kernel space buffering
     */

    TclSockMinimumBuffers(sock, TCP_BUFFER_SIZE);

    if (server) {







>
>







|
|


|













>
>
>
>
>
>
>







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
    u_long flag = 1;			/* Indicates nonblocking mode. */
    int asyncConnect = 0;		/* Will be 1 if async connect is
                                         * in progress. */
    struct sockaddr_in sockaddr;	/* Socket address */
    struct sockaddr_in mysockaddr;	/* Socket address for client */
    SOCKET sock;
    SocketInfo *infoPtr;		/* The returned value. */
    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (!SocketsEnabled()) {
        return NULL;
    }

    if (! CreateSocketAddress(&sockaddr, host, port)) {
	goto error;
    }
    if ((myaddr != NULL || myport != 0) &&
	    ! CreateSocketAddress(&mysockaddr, myaddr, myport)) {
	goto error;
    }

    sock = (*winSock.socket)(AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET) {
	goto error;
    }

    /*
     * Win-NT has a misfeature that sockets are inherited in child
     * processes by default.  Turn off the inherit bit.
     */

    SetHandleInformation( (HANDLE) sock, HANDLE_FLAG_INHERIT, 0 );
	
    /*
     * Set kernel space buffering
     */

    TclSockMinimumBuffers(sock, TCP_BUFFER_SIZE);

    if (server) {
1002
1003
1004
1005
1006
1007
1008

1009
1010
1011
1012
1013
1014
1015
1016
    }

    /*
     * Register for interest in events in the select mask.  Note that this
     * automatically places the socket into non-blocking mode.
     */


    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, winSock.hwnd,
	    SOCKET_MESSAGE, infoPtr->selectEvents);

    return infoPtr;

error:
    TclWinConvertWSAError((*winSock.WSAGetLastError)());
    if (interp != NULL) {







>
|







1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
    }

    /*
     * 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) {
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (winSock.hInstance == NULL) {
        Tcl_SetErrno(EFAULT);
        return 0;
    }
    
    (void) memset((char *) sockaddrPtr, '\0', sizeof(struct sockaddr_in));
    sockaddrPtr->sin_family = AF_INET;
    sockaddrPtr->sin_port = (*winSock.htons)((short) (port & 0xFFFF));
    if (host == NULL) {
	addr.s_addr = INADDR_ANY;
    } else {
        addr.s_addr = (*winSock.inet_addr)(host);







|



|







1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (!SocketsEnabled()) {
        Tcl_SetErrno(EFAULT);
        return 0;
    }

    (void) memset((char *) sockaddrPtr, '\0', sizeof(struct sockaddr_in));
    sockaddrPtr->sin_family = AF_INET;
    sockaddrPtr->sin_port = (*winSock.htons)((short) (port & 0xFFFF));
    if (host == NULL) {
	addr.s_addr = INADDR_ANY;
    } else {
        addr.s_addr = (*winSock.inet_addr)(host);
1120
1121
1122
1123
1124
1125
1126


1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148

1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159

1160
1161

1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176






1177
1178







1179
1180
1181
1182
1183
1184
1185
    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;



    /*
     * Be sure to disable event servicing so we are truly modal.
     */

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
    
    while (!(infoPtr->readyEvents & events)) {
	if (infoPtr->flags & SOCKET_ASYNC) {
	    if (!PeekMessage(&msg, winSock.hwnd, SOCKET_MESSAGE,
		    SOCKET_MESSAGE, PM_REMOVE)) {
		*errorCodePtr = EWOULDBLOCK;
		result = 0;
		break;
	    }
	} else {
	    /*
	     * Look for a socket event.  Note that we will be getting
	     * events for all of Tcl's sockets, not just the one we wanted.
	     */

	    result = GetMessage(&msg, winSock.hwnd, SOCKET_MESSAGE,

		    SOCKET_MESSAGE);
	    if (result == -1) {
		TclWinConvertError(GetLastError());
		*errorCodePtr = Tcl_GetErrno();
		result = 0;
		break;
	    }

	    /*
	     * I don't think we can get a WM_QUIT during a tight modal
	     * loop, but just in case...

	     */


	    if (result == 0) {
		panic("WaitForSocketEvent: Got WM_QUIT during modal loop!");
	    }
	}

	/*
	 * Dispatch the message and then check for an error on the socket.
	 */

	infoPtr->lastError = 0;
	DispatchMessage(&msg);
	if (infoPtr->lastError) {
	    *errorCodePtr = infoPtr->lastError;
	    result = 0;
	    break;






	}
    }








    (void) Tcl_SetServiceMode(oldMode);
    return result;
}

/*
 *----------------------------------------------------------------------







>
>







<
<
<
<
<
<
<
<
<
|
<
|
|

|
>
|
<
<
<
<
<
|
|
|
<
<
>
|

>
|
<
|
|
<
<
<
<
<
<
<




>
>
>
>
>
>

|
>
>
>
>
>
>
>







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
    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;
}

/*
 *----------------------------------------------------------------------
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
    char *host;				/* Host on which to open port. */
    char *myaddr;			/* Client-side address */
    int myport;				/* Client-side port */
    int async;				/* If nonzero, should connect
                                         * client socket asynchronously. */
{
    SocketInfo *infoPtr;
    char channelName[20];

    if (TclHasSockets(interp) != TCL_OK) {
	return NULL;
    }

    /*
     * Create a new client socket and wrap it in a channel.
     */

    infoPtr = CreateSocket(interp, port, host, 0, myaddr, myport, async);
    if (infoPtr == NULL) {
	return NULL;
    }

    sprintf(channelName, "sock%d", infoPtr->socket);

    infoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
	    (ClientData) infoPtr, (TCL_READABLE | TCL_WRITABLE));
    if (Tcl_SetChannelOption(interp, infoPtr->channel, "-translation",
	    "auto crlf") == TCL_ERROR) {
        Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel);
        return (Tcl_Channel) NULL;







|

|












|







1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
    char *host;				/* Host on which to open port. */
    char *myaddr;			/* Client-side address */
    int myport;				/* Client-side port */
    int async;				/* If nonzero, should connect
                                         * client socket asynchronously. */
{
    SocketInfo *infoPtr;
    char channelName[16 + TCL_INTEGER_SPACE];

    if (TclpHasSockets(interp) != TCL_OK) {
	return NULL;
    }

    /*
     * Create a new client socket and wrap it in a channel.
     */

    infoPtr = CreateSocket(interp, port, host, 0, myaddr, myport, async);
    if (infoPtr == NULL) {
	return NULL;
    }

    wsprintfA(channelName, "sock%d", infoPtr->socket);

    infoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
	    (ClientData) infoPtr, (TCL_READABLE | TCL_WRITABLE));
    if (Tcl_SetChannelOption(interp, infoPtr->channel, "-translation",
	    "auto crlf") == TCL_ERROR) {
        Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel);
        return (Tcl_Channel) NULL;
1260
1261
1262
1263
1264
1265
1266
1267


1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
 */

Tcl_Channel
Tcl_MakeTcpClientChannel(sock)
    ClientData sock;		/* The socket to wrap up into a channel. */
{
    SocketInfo *infoPtr;
    char channelName[20];



    if (TclHasSockets(NULL) != TCL_OK) {
	return NULL;
    }

    /*
     * 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, winSock.hwnd,
	    SOCKET_MESSAGE, infoPtr->selectEvents);

    sprintf(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;
}

/*







|
>
>

|
















|


|







1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
 */

Tcl_Channel
Tcl_MakeTcpClientChannel(sock)
    ClientData sock;		/* The socket to wrap up into a channel. */
{
    SocketInfo *infoPtr;
    char channelName[16 + TCL_INTEGER_SPACE];
    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    if (TclpHasSockets(NULL) != TCL_OK) {
	return NULL;
    }

    /*
     * 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;
}

/*
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
    int port;				/* Port number to open. */
    char *host;				/* Name of local host. */
    Tcl_TcpAcceptProc *acceptProc;	/* Callback for accepting connections
                                         * from new clients. */
    ClientData acceptProcData;		/* Data for the callback. */
{
    SocketInfo *infoPtr;
    char channelName[20];

    if (TclHasSockets(interp) != TCL_OK) {
	return NULL;
    }

    /*
     * Create a new client socket and wrap it in a channel.
     */

    infoPtr = CreateSocket(interp, port, host, 1, NULL, 0, 0);
    if (infoPtr == NULL) {
	return NULL;
    }

    infoPtr->acceptProc = acceptProc;
    infoPtr->acceptProcData = acceptProcData;

    sprintf(channelName, "sock%d", infoPtr->socket);

    infoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
	    (ClientData) infoPtr, 0);
    if (Tcl_SetChannelOption(interp, infoPtr->channel, "-eofchar", "")
	    == TCL_ERROR) {
        Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel);
        return (Tcl_Channel) NULL;







|

|















|







1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
    int port;				/* Port number to open. */
    char *host;				/* Name of local host. */
    Tcl_TcpAcceptProc *acceptProc;	/* Callback for accepting connections
                                         * from new clients. */
    ClientData acceptProcData;		/* Data for the callback. */
{
    SocketInfo *infoPtr;
    char channelName[16 + TCL_INTEGER_SPACE];

    if (TclpHasSockets(interp) != TCL_OK) {
	return NULL;
    }

    /*
     * Create a new client socket and wrap it in a channel.
     */

    infoPtr = CreateSocket(interp, port, host, 1, NULL, 0, 0);
    if (infoPtr == NULL) {
	return NULL;
    }

    infoPtr->acceptProc = acceptProc;
    infoPtr->acceptProcData = acceptProcData;

    wsprintfA(channelName, "sock%d", infoPtr->socket);

    infoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
	    (ClientData) infoPtr, 0);
    if (Tcl_SetChannelOption(interp, infoPtr->channel, "-eofchar", "")
	    == TCL_ERROR) {
        Tcl_Close((Tcl_Interp *) NULL, infoPtr->channel);
        return (Tcl_Channel) NULL;
1373
1374
1375
1376
1377
1378
1379
1380


1381
1382
1383
1384
1385
1386
1387
TcpAccept(infoPtr)
    SocketInfo *infoPtr;	/* Socket to accept. */
{
    SOCKET newSocket;
    SocketInfo *newInfoPtr;
    struct sockaddr_in addr;
    int len;
    char channelName[20];



    /*
     * Accept the incoming connection request.
     */

    len = sizeof(struct sockaddr_in);
    newSocket = (*winSock.accept)(infoPtr->socket, (struct sockaddr *)&addr,







|
>
>







1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
TcpAccept(infoPtr)
    SocketInfo *infoPtr;	/* Socket to accept. */
{
    SOCKET newSocket;
    SocketInfo *newInfoPtr;
    struct sockaddr_in addr;
    int len;
    char channelName[16 + TCL_INTEGER_SPACE];
    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    /*
     * Accept the incoming connection request.
     */

    len = sizeof(struct sockaddr_in);
    newSocket = (*winSock.accept)(infoPtr->socket, (struct sockaddr *)&addr,
1395
1396
1397
1398
1399
1400
1401







1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423

    infoPtr->readyEvents &= ~(FD_ACCEPT);

    if (newSocket == INVALID_SOCKET) {
        return;
    }








    /*
     * Add this socket to the global list of sockets.
     */

    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, winSock.hwnd, 
	    SOCKET_MESSAGE, newInfoPtr->selectEvents);

    sprintf(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;
    }







>
>
>
>
>
>
>











|


|







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

    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.
     */

    SetHandleInformation( (HANDLE) newSocket, HANDLE_FLAG_INHERIT, 0 );
	
    /*
     * Add this socket to the global list of sockets.
     */

    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;
    }
1461
1462
1463
1464
1465
1466
1467


1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
    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;


    
    *errorCodePtr = 0;

    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (winSock.hInstance == NULL) {
        *errorCodePtr = EFAULT;
        return -1;
    }

    /*
     * First check to see if EOF was already detected, to prevent
     * calling the socket stack after the first time EOF is detected.







>
>










|







1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
    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
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (!SocketsEnabled()) {
        *errorCodePtr = EFAULT;
        return -1;
    }

    /*
     * First check to see if EOF was already detected, to prevent
     * calling the socket stack after the first time EOF is detected.
1503
1504
1505
1506
1507
1508
1509
1510

1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531

1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557

1558
1559




1560
1561
1562
1563
1564
1565
1566
     * 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 (infoPtr->readyEvents & (FD_CLOSE|FD_READ)) {

	    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) {
		return bytesRead;
	    }

	    /*
	     * 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;

		return 0;
	    }

	    /*
	     * 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();
		return -1;
	    }

	} else if (infoPtr->flags & SOCKET_ASYNC) {
	    *errorCodePtr = EWOULDBLOCK;
	    return -1;
	}

	/*
	 * In the blocking case, wait until the file becomes readable
	 * or closed and try again.
	 */

	if (!WaitForSocketEvent(infoPtr, FD_READ|FD_CLOSE, errorCodePtr)) {
	    return -1;

	}
    }




}

/*
 *----------------------------------------------------------------------
 *
 * TcpOutputProc --
 *







|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
<
|
<
<
<








|
>
|

>
>
>
>







1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660

1661



1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
     * 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 --
 *
1582
1583
1584
1585
1586
1587
1588


1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613


1614
1615
1616
1617
1618
1619
1620
    char *buf;				/* Where to get data. */
    int toWrite;			/* Maximum number of bytes to write. */
    int *errorCodePtr;			/* Where to store error codes. */
{
    SocketInfo *infoPtr = (SocketInfo *) instanceData;
    int bytesWritten;
    int error;



    *errorCodePtr = 0;

    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (winSock.hInstance == NULL) {
        *errorCodePtr = EFAULT;
        return -1;
    }
    
    /*
     * Check to see if the socket is connected before trying to write.
     */
    
    if ((infoPtr->flags & SOCKET_ASYNC_CONNECT)
	    && ! WaitForSocketEvent(infoPtr,  FD_CONNECT, errorCodePtr)) {
	return -1;
    }

    while (1) {


	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.
	     */







>
>










|



|










>
>







1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
    char *buf;				/* Where to get data. */
    int toWrite;			/* Maximum number of bytes to write. */
    int *errorCodePtr;			/* Where to store error codes. */
{
    SocketInfo *infoPtr = (SocketInfo *) instanceData;
    int bytesWritten;
    int error;
    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    *errorCodePtr = 0;

    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (! SocketsEnabled()) {
        *errorCodePtr = EFAULT;
        return -1;
    }

    /*
     * Check to see if the socket is connected before trying to write.
     */
    
    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.
	     */
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
	 */

	error = (*winSock.WSAGetLastError)();
	if (error == WSAEWOULDBLOCK) {
	    infoPtr->readyEvents &= ~(FD_WRITE);
	    if (infoPtr->flags & SOCKET_ASYNC) {
		*errorCodePtr = EWOULDBLOCK;

		return -1;
	    } 
	} else {
	    TclWinConvertWSAError(error);
	    *errorCodePtr = Tcl_GetErrno();

	    return -1;
	}

	/*
	 * In the blocking case, wait until the file becomes writable
	 * or closed and try again.
	 */

	if (!WaitForSocketEvent(infoPtr, FD_WRITE|FD_CLOSE, errorCodePtr)) {

	    return -1;
	}
    }



    return bytesWritten;
}

/*
 *----------------------------------------------------------------------
 *
 * TcpGetOptionProc --







>
|




>
|








>
|



>
>







1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
	 */

	error = (*winSock.WSAGetLastError)();
	if (error == WSAEWOULDBLOCK) {
	    infoPtr->readyEvents &= ~(FD_WRITE);
	    if (infoPtr->flags & SOCKET_ASYNC) {
		*errorCodePtr = EWOULDBLOCK;
		bytesWritten = -1;
		break;
	    } 
	} else {
	    TclWinConvertWSAError(error);
	    *errorCodePtr = Tcl_GetErrno();
	    bytesWritten = -1;
	    break;
	}

	/*
	 * In the blocking case, wait until the file becomes writable
	 * or closed and try again.
	 */

	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 --
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721


















1722
1723
1724
1725
1726
1727
1728
    SocketInfo *infoPtr;
    struct sockaddr_in sockname;
    struct sockaddr_in peername;
    struct hostent *hostEntPtr;
    SOCKET sock;
    int size = sizeof(struct sockaddr_in);
    size_t len = 0;
    char buf[128];

    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (winSock.hInstance == NULL) {
	if (interp) {
	    Tcl_AppendResult(interp, "winsock is not initialized", NULL);
	}
        return TCL_ERROR;
    }
    
    infoPtr = (SocketInfo *) instanceData;
    sock = (int) infoPtr->socket;
    if (optionName != (char *) NULL) {
        len = strlen(optionName);
    }



















    if ((len == 0) ||
            ((len > 1) && (optionName[1] == 'p') &&
                    (strncmp(optionName, "-peername", len) == 0))) {
        if ((*winSock.getpeername)(sock, (struct sockaddr *) &peername, &size)
                == 0) {
            if (len == 0) {







|








|











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
    SocketInfo *infoPtr;
    struct sockaddr_in sockname;
    struct sockaddr_in peername;
    struct hostent *hostEntPtr;
    SOCKET sock;
    int size = sizeof(struct sockaddr_in);
    size_t len = 0;
    char buf[TCL_INTEGER_SPACE];

    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (!SocketsEnabled()) {
	if (interp) {
	    Tcl_AppendResult(interp, "winsock is not initialized", NULL);
	}
        return TCL_ERROR;
    }
    
    infoPtr = (SocketInfo *) instanceData;
    sock = (int) infoPtr->socket;
    if (optionName != (char *) NULL) {
        len = strlen(optionName);
    }

    if ((len > 1) && (optionName[1] == 'e') &&
	    (strncmp(optionName, "-error", len) == 0)) {
	int optlen;
	int err, ret;
    
	optlen = sizeof(int);
	ret = TclWinGetSockOpt(sock, SOL_SOCKET, SO_ERROR,
		(char *)&err, &optlen);
	if (ret == SOCKET_ERROR) {
	    err = (*winSock.WSAGetLastError)();
	}
	if (err) {
	    TclWinConvertWSAError(err);
	    Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1);
	}
	return TCL_OK;
    }

    if ((len == 0) ||
            ((len > 1) && (optionName[1] == 'p') &&
                    (strncmp(optionName, "-peername", len) == 0))) {
        if ((*winSock.getpeername)(sock, (struct sockaddr *) &peername, &size)
                == 0) {
            if (len == 0) {
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
                AF_INET);
            if (hostEntPtr != (struct hostent *) NULL) {
                Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
            } else {
                Tcl_DStringAppendElement(dsPtr,
                        (*winSock.inet_ntoa)(peername.sin_addr));
            }
            sprintf(buf, "%d", (*winSock.ntohs)(peername.sin_port));
            Tcl_DStringAppendElement(dsPtr, buf);
            if (len == 0) {
                Tcl_DStringEndSublist(dsPtr);
            } else {
                return TCL_OK;
            }
        } else {







|







1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
                AF_INET);
            if (hostEntPtr != (struct hostent *) NULL) {
                Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
            } else {
                Tcl_DStringAppendElement(dsPtr,
                        (*winSock.inet_ntoa)(peername.sin_addr));
            }
	    TclFormatInt(buf, (*winSock.ntohs)(peername.sin_port));
            Tcl_DStringAppendElement(dsPtr, buf);
            if (len == 0) {
                Tcl_DStringEndSublist(dsPtr);
            } else {
                return TCL_OK;
            }
        } else {
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
                AF_INET);
            if (hostEntPtr != (struct hostent *) NULL) {
                Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
            } else {
                Tcl_DStringAppendElement(dsPtr,
                        (*winSock.inet_ntoa)(sockname.sin_addr));
            }
            sprintf(buf, "%d", (*winSock.ntohs)(sockname.sin_port));
            Tcl_DStringAppendElement(dsPtr, buf);
            if (len == 0) {
                Tcl_DStringEndSublist(dsPtr);
            } else {
                return TCL_OK;
            }
        } else {







|







1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
                AF_INET);
            if (hostEntPtr != (struct hostent *) NULL) {
                Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name);
            } else {
                Tcl_DStringAppendElement(dsPtr,
                        (*winSock.inet_ntoa)(sockname.sin_addr));
            }
            TclFormatInt(buf, (*winSock.ntohs)(sockname.sin_port));
            Tcl_DStringAppendElement(dsPtr, buf);
            if (len == 0) {
                Tcl_DStringEndSublist(dsPtr);
            } else {
                return TCL_OK;
            }
        } else {
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
     */
    
    infoPtr->watchEvents = 0;
    if (mask & TCL_READABLE) {
	infoPtr->watchEvents |= (FD_READ|FD_CLOSE|FD_ACCEPT);
    }
    if (mask & TCL_WRITABLE) {
	infoPtr->watchEvents |= (FD_WRITE);
    }

    /*
     * 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);
    }		
}

/*
 *----------------------------------------------------------------------
 *
 * TcpGetProc --
 *
 *	Called from Tcl_GetChannelFile to retrieve an OS handle from inside
 *	a TCP socket based channel.
 *
 * Results:
 *	Returns TCL_OK with the socket in handlePtr.
 *
 * Side effects:
 *	None.







|


















|







1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
     */
    
    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);
    }		
}

/*
 *----------------------------------------------------------------------
 *
 * TcpGetProc --
 *
 *	Called from Tcl_GetChannelHandle to retrieve an OS handle from inside
 *	a TCP socket based channel.
 *
 * Results:
 *	Returns TCL_OK with the socket in handlePtr.
 *
 * Side effects:
 *	None.
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
    UINT message;
    WPARAM wParam;
    LPARAM lParam;
{
    int event, error;
    SOCKET socket;
    SocketInfo *infoPtr;


    if (message != SOCKET_MESSAGE) {
	return DefWindowProc(hwnd, message, wParam, lParam);
    }

    event = WSAGETSELECTEVENT(lParam);
    error = WSAGETSELECTERROR(lParam);
    socket = (SOCKET) wParam;

    /*
     * Find the specified socket on the socket list and update its
     * eventState flag.
     */


    for (infoPtr = socketList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {
	if (infoPtr->socket == socket) {
	    /*
	     * Update the socket state.
	     */

	    if (event & FD_CLOSE) {
		infoPtr->readyEvents &= ~(FD_WRITE|FD_ACCEPT);







>














>
|







2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
    UINT message;
    WPARAM wParam;
    LPARAM lParam;
{
    int event, error;
    SOCKET socket;
    SocketInfo *infoPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (message != SOCKET_MESSAGE) {
	return DefWindowProc(hwnd, message, wParam, lParam);
    }

    event = WSAGETSELECTEVENT(lParam);
    error = WSAGETSELECTERROR(lParam);
    socket = (SOCKET) wParam;

    /*
     * Find the specified socket on the socket list and update its
     * eventState flag.
     */

    for (infoPtr = tsdPtr->socketList; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->socket == socket) {
	    /*
	     * Update the socket state.
	     */

	    if (event & FD_CLOSE) {
		infoPtr->readyEvents &= ~(FD_WRITE|FD_ACCEPT);
1957
1958
1959
1960
1961
1962
1963








1964
1965
1966
1967
1968
1969
1970

		if (error != ERROR_SUCCESS) {
		    TclWinConvertWSAError(error);
		    infoPtr->lastError = Tcl_GetErrno();
		}

	    } 








	    infoPtr->readyEvents |= event;
	    break;
	}
    }

    /*
     * Flush the Tcl event queue before returning to the event loop.







>
>
>
>
>
>
>
>







2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125

		if (error != ERROR_SUCCESS) {
		    TclWinConvertWSAError(error);
		    infoPtr->lastError = Tcl_GetErrno();
		}

	    } 
	    if(infoPtr->flags & SOCKET_ASYNC_CONNECT) {
		infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
		if (error != ERROR_SUCCESS) {
		    TclWinConvertWSAError(error);
		    infoPtr->lastError = Tcl_GetErrno();
		}
		infoPtr->readyEvents |= FD_WRITE;
	    }
	    infoPtr->readyEvents |= event;
	    break;
	}
    }

    /*
     * Flush the Tcl event queue before returning to the event loop.
1993
1994
1995
1996
1997
1998
1999
2000
2001

2002

2003
2004
2005
2006




2007
2008

2009
2010
2011
2012
2013
2014

2015
2016
2017

2018




2019
2020
2021
2022

2023
2024
2025
2026
2027
2028
2029
 *----------------------------------------------------------------------
 */

char *
Tcl_GetHostName()
{
    DWORD length;
    char *p;


    if (hostnameInitialized) {

        return hostname;
    }

    if (TclHasSockets(NULL) == TCL_OK) {




	if ((*winSock.gethostname)(hostname, sizeof(hostname)) == 0) {
	    hostnameInitialized = 1;

	    return hostname;
	}
    }
    length = sizeof(hostname);
    if (GetComputerName(hostname, &length) != 0) {
	for (p = hostname; *p != '\0'; p++) {

	    if (isupper(*((unsigned char *) p))) {
		*p = (char) tolower(*((unsigned char *) p));
	    }

	}




    } else {
	hostname[0] = '\0';
    }
    hostnameInitialized = 1;

    return hostname;
}

/*
 *----------------------------------------------------------------------
 *
 * TclWinGetSockOpt, et al. --







|

>

>



|
>
>
>
>


>




|
<
>
|
|
|
>
|
>
>
>
>




>







2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175

2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
 *----------------------------------------------------------------------
 */

char *
Tcl_GetHostName()
{
    DWORD length;
    WCHAR wbuf[MAX_COMPUTERNAME_LENGTH + 1];

    Tcl_MutexLock(&socketMutex);
    if (hostnameInitialized) {
	Tcl_MutexUnlock(&socketMutex);
        return hostname;
    }

    if (TclpHasSockets(NULL) == TCL_OK) {
	/*
	 * INTL: bug
	 */

	if ((*winSock.gethostname)(hostname, sizeof(hostname)) == 0) {
	    hostnameInitialized = 1;
	    Tcl_MutexUnlock(&socketMutex);
	    return hostname;
	}
    }
    length = sizeof(hostname);
    if ((*tclWinProcs->getComputerNameProc)(wbuf, &length) != 0) {

	/*
	 * Convert string from native to UTF then change to lowercase.
	 */

	Tcl_DString ds;

	lstrcpynA(hostname, Tcl_WinTCharToUtf((TCHAR *) wbuf, -1, &ds),
		sizeof(hostname));
	Tcl_DStringFree(&ds);
	Tcl_UtfToLower(hostname);
    } else {
	hostname[0] = '\0';
    }
    hostnameInitialized = 1;
    Tcl_MutexUnlock(&socketMutex);
    return hostname;
}

/*
 *----------------------------------------------------------------------
 *
 * TclWinGetSockOpt, et al. --
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
 *
 * Side effects:
 *	As defined for each function.
 *
 *----------------------------------------------------------------------
 */

int PASCAL FAR
TclWinGetSockOpt(SOCKET s, int level, int optname, char FAR * optval,
	int FAR *optlen)
{
    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (winSock.hInstance == NULL) {
        return SOCKET_ERROR;
    }
    
    return (*winSock.getsockopt)(s, level, optname, optval, optlen);
}

int PASCAL FAR
TclWinSetSockOpt(SOCKET s, int level, int optname, const char FAR * optval,
	int optlen)
{
    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (winSock.hInstance == NULL) {
        return SOCKET_ERROR;
    }

    return (*winSock.setsockopt)(s, level, optname, optval, optlen);
}

u_short PASCAL FAR
TclWinNToHS(u_short netshort)
{
    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (winSock.hInstance == NULL) {
        return (u_short) -1;
    }

    return (*winSock.ntohs)(netshort);
}

struct servent FAR * PASCAL FAR
TclWinGetServByName(const char FAR * name, const char FAR * proto)
{
    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (winSock.hInstance == NULL) {
        return (struct servent FAR *) NULL;
    }

    return (*winSock.getservbyname)(name, proto);
}







|
|









|






|
|








|
<






|









|






|
|







|
<
|




2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241

2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274

2275
2276
2277
2278
2279
 *
 * Side effects:
 *	As defined for each function.
 *
 *----------------------------------------------------------------------
 */

int
TclWinGetSockOpt(SOCKET s, int level, int optname, char * optval,
	int FAR *optlen)
{
    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (!SocketsEnabled()) {
        return SOCKET_ERROR;
    }
    
    return (*winSock.getsockopt)(s, level, optname, optval, optlen);
}

int
TclWinSetSockOpt(SOCKET s, int level, int optname, const char * optval,
	int optlen)
{
    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */
    if (!SocketsEnabled()) {

        return SOCKET_ERROR;
    }

    return (*winSock.setsockopt)(s, level, optname, optval, optlen);
}

u_short
TclWinNToHS(u_short netshort)
{
    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */

    if (!SocketsEnabled()) {
        return (u_short) -1;
    }

    return (*winSock.ntohs)(netshort);
}

struct servent *
TclWinGetServByName(const char * name, const char * proto)
{
    /*
     * Check that WinSock is initialized; do not call it if not, to
     * prevent system crashes. This can happen at exit time if the exit
     * handler for WinSock ran before other exit handlers that want to
     * use sockets.
     */
    if (!SocketsEnabled()) {

        return (struct servent *) NULL;
    }

    return (*winSock.getservbyname)(name, proto);
}

Changes to win/tclWinTest.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 
 * tclWinTest.c --
 *
 *	Contains commands for platform specific tests on Windows.
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * SCCS: @(#) tclWinTest.c 1.2 97/03/20 15:04:12
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * Forward declarations of procedures defined later in this file:
 */
int			TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
static int		TesteventloopCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));










|


|
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
/* 
 * tclWinTest.c --
 *
 *	Contains commands for platform specific tests on Windows.
 *
 * Copyright (c) 1996 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: tclWinTest.c,v 1.1.2.2 1998/09/24 23:59:54 stanton Exp $
 */

#include "tclWinInt.h"


/*
 * Forward declarations of procedures defined later in this file:
 */
int			TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
static int		TesteventloopCmd _ANSI_ARGS_((ClientData dummy,
			    Tcl_Interp *interp, int argc, char **argv));

Added win/tclWinThrd.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
/* 
 * tclWinThread.c --
 *
 *	This file implements the Windows-specific thread operations.
 *
 * Copyright (c) 1998 by Sun Microsystems, Inc.
 * Copyright (c) 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.
 *
 * SCCS:  @(#) tclWinThrd.c 1.13 98/02/18 14:00:23
 */

#include "tclWinInt.h"

#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>

/*
 * This is the master lock used to serialize access to other
 * serialization data structures.
 */

static CRITICAL_SECTION masterLock;
static int init = 0;
#define MASTER_LOCK  EnterCriticalSection(&masterLock)
#define MASTER_UNLOCK  LeaveCriticalSection(&masterLock)

/*
 * This is the master lock used to serialize initialization and finalization
 * of Tcl as a whole.
 */

static CRITICAL_SECTION initLock;

/*
 * Condition variables are implemented with a combination of a 
 * per-thread Windows Event and a per-condition waiting queue.
 * The idea is that each thread has its own Event that it waits
 * on when it is doing a ConditionWait; it uses the same event for
 * all condition variables because it only waits on one at a time.
 * Each condition variable has a queue of waiting threads, and a 
 * mutex used to serialize access to this queue.
 *
 * Special thanks to David Nichols and
 * Jim Davidson for advice on the Condition Variable implementation.
 */

/*
 * The per-thread event and queue pointers.
 */

typedef struct ThreadSpecificData {
    HANDLE condEvent;			/* Per-thread condition event */
    struct ThreadSpecificData *nextPtr;	/* Queue pointers */
    struct ThreadSpecificData *prevPtr;
    int flags;				/* See flags below */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * State bits for the thread.
 * WIN_THREAD_UNINIT		Uninitialized.  Must be zero because
 *				of the way ThreadSpecificData is created.
 * WIN_THREAD_RUNNING		Running, not waiting.
 * WIN_THREAD_BLOCKED		Waiting, or trying to wait.
 * WIN_THREAD_DEAD		Dying - no per-thread event anymore.
 */ 

#define WIN_THREAD_UNINIT	0x0
#define WIN_THREAD_RUNNING	0x1
#define WIN_THREAD_BLOCKED	0x2
#define WIN_THREAD_DEAD		0x4

/*
 * The per condition queue pointers and the
 * Mutex used to serialize access to the queue.
 */

typedef struct WinCondition {
    CRITICAL_SECTION condLock;	/* Lock to serialize queuing on the condition */
    struct ThreadSpecificData *firstPtr;	/* Queue pointers */
    struct ThreadSpecificData *lastPtr;
} WinCondition;

static void FinalizeConditionEvent(ClientData data);


/*
 *----------------------------------------------------------------------
 *
 * TclpThreadCreate --
 *
 *	This procedure creates a new thread.
 *
 * Results:
 *	TCL_OK if the thread could be created.  The thread ID is
 *	returned in a parameter.
 *
 * Side effects:
 *	A new thread is created.
 *
 *----------------------------------------------------------------------
 */

int
TclpThreadCreate(idPtr, proc, clientData)
    Tcl_ThreadId *idPtr;		/* Return, the ID of the thread */
    Tcl_ThreadCreateProc proc;		/* Main() function of the thread */
    ClientData clientData;		/* The one argument to Main() */
{
    HANDLE tHandle;

    tHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) proc,
		(DWORD *)clientData, 0, (DWORD *)idPtr);
    if (tHandle == NULL) {
	return TCL_ERROR;
    } else {
	return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpThreadExit --
 *
 *	This procedure terminates the current thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	This procedure terminates the current thread.
 *
 *----------------------------------------------------------------------
 */

void
TclpThreadExit(status)
    int status;
{
    ExitThread((DWORD)status);
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetCurrentThread --
 *
 *	This procedure returns the ID of the currently running thread.
 *
 * Results:
 *	A thread ID.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_ThreadId
Tcl_GetCurrentThread()
{
    return (Tcl_ThreadId)GetCurrentThreadId();
}


/*
 *----------------------------------------------------------------------
 *
 * TclpInitLock
 *
 *	This procedure is used to grab a lock that serializes initialization
 *	and finalization of Tcl.  On some platforms this may also initialize
 *	the mutex used to serialize creation of more mutexes and thread
 *	local storage keys.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Acquire the initialization mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpInitLock()
{
    if (!init) {
	/*
	 * There is a fundamental race here that is solved by creating
	 * the first Tcl interpreter in a single threaded environment.
	 * Once the interpreter has been created, it is safe to create
	 * more threads that create interpreters in parallel.
	 */
	init = 1;
	InitializeCriticalSection(&initLock);
	InitializeCriticalSection(&masterLock);
    }
    EnterCriticalSection(&initLock);
}


/*
 *----------------------------------------------------------------------
 *
 * TclpInitUnlock
 *
 *	This procedure is used to release a lock that serializes initialization
 *	and finalization of Tcl.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Release the initialization mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpInitUnlock()
{
    LeaveCriticalSection(&initLock);
}


/*
 *----------------------------------------------------------------------
 *
 * TclpMasterLock
 *
 *	This procedure is used to grab a lock that serializes creation
 *	of mutexes, condition variables, and thread local storage keys.
 *
 *	This lock must be different than the initLock because the
 *	initLock is held during creation of syncronization objects.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Acquire the master mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpMasterLock()
{
    if (!init) {
	/*
	 * There is a fundamental race here that is solved by creating
	 * the first Tcl interpreter in a single threaded environment.
	 * Once the interpreter has been created, it is safe to create
	 * more threads that create interpreters in parallel.
	 */
	init = 1;
	InitializeCriticalSection(&initLock);
	InitializeCriticalSection(&masterLock);
    }
    EnterCriticalSection(&masterLock);
}


/*
 *----------------------------------------------------------------------
 *
 * TclpMasterUnlock
 *
 *	This procedure is used to release a lock that serializes creation
 *	and deletion of synchronization objects.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Release the master mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpMasterUnlock()
{
    LeaveCriticalSection(&masterLock);
}

#ifdef TCL_THREADS

/*
 *----------------------------------------------------------------------
 *
 * TclpMutexInit --
 * TclpMutexLock --
 * TclpMutexUnlock --
 *
 *	These procedures use an explicitly initialized mutex.
 *	These are used by memory allocators for their own mutex.
 * 
 * Results:
 *	None.
 *
 * Side effects:
 *	Initialize, Lock, and Unlock the mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpMutexInit(mPtr)
    TclpMutex *mPtr;
{
    InitializeCriticalSection((CRITICAL_SECTION *)mPtr);
}
void
TclpMutexLock(mPtr)
    TclpMutex *mPtr;
{
    EnterCriticalSection((CRITICAL_SECTION *)mPtr);
}
void
TclpMutexUnlock(mPtr)
    TclpMutex *mPtr;
{
    LeaveCriticalSection((CRITICAL_SECTION *)mPtr);
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_MutexLock --
 *
 *	This procedure is invoked to lock a mutex.  This is a self 
 *	initializing mutex that is automatically finalized during
 *	Tcl_Finalize.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May block the current thread.  The mutex is aquired when
 *	this returns.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_MutexLock(mutexPtr)
    Tcl_Mutex *mutexPtr;	/* The lock */
{
    CRITICAL_SECTION *csPtr;
    if (*mutexPtr == NULL) {
	MASTER_LOCK;

	/* 
	 * Double inside master lock check to avoid a race.
	 */

	if (*mutexPtr == NULL) {
	    csPtr = (CRITICAL_SECTION *)ckalloc(sizeof(CRITICAL_SECTION));
	    InitializeCriticalSection(csPtr);
	    *mutexPtr = (Tcl_Mutex)csPtr;
	    TclRememberMutex(mutexPtr);
	}
	MASTER_UNLOCK;
    }
    csPtr = *((CRITICAL_SECTION **)mutexPtr);
    EnterCriticalSection(csPtr);
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_MutexUnlock --
 *
 *	This procedure is invoked to unlock a mutex.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The mutex is released when this returns.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_MutexUnlock(mutexPtr)
    Tcl_Mutex *mutexPtr;	/* The lock */
{
    CRITICAL_SECTION *csPtr = *((CRITICAL_SECTION **)mutexPtr);
    LeaveCriticalSection(csPtr);
}


/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeMutex --
 *
 *	This procedure is invoked to clean up one mutex.  This is only
 *	safe to call at the end of time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The mutex list is deallocated.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeMutex(mutexPtr)
    Tcl_Mutex *mutexPtr;
{
    CRITICAL_SECTION *csPtr = *(CRITICAL_SECTION **)mutexPtr;
    if (csPtr != NULL) {
	ckfree((char *)csPtr);
	*mutexPtr = NULL;
    }
}


/*
 *----------------------------------------------------------------------
 *
 * TclpThreadDataKeyInit --
 *
 *	This procedure initializes a thread specific data block key.
 *	Each thread has table of pointers to thread specific data.
 *	all threads agree on which table entry is used by each module.
 *	this is remembered in a "data key", that is just an index into
 *	this table.  To allow self initialization, the interface
 *	passes a pointer to this key and the first thread to use
 *	the key fills in the pointer to the key.  The key should be
 *	a process-wide static.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Will allocate memory the first time this process calls for
 *	this key.  In this case it modifies its argument
 *	to hold the pointer to information about the key.
 *
 *----------------------------------------------------------------------
 */

void
TclpThreadDataKeyInit(keyPtr)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (DWORD **) */
{
    DWORD *indexPtr;

    MASTER_LOCK;
    if (*keyPtr == NULL) {
	indexPtr = (DWORD *)ckalloc(sizeof(DWORD));
	*indexPtr = TlsAlloc();
	*keyPtr = (Tcl_ThreadDataKey)indexPtr;
	TclRememberDataKey(keyPtr);
    }
    MASTER_UNLOCK;
}


/*
 *----------------------------------------------------------------------
 *
 * TclpThreadDataKeyGet --
 *
 *	This procedure returns a pointer to a block of thread local storage.
 *
 * Results:
 *	A thread-specific pointer to the data structure, or NULL
 *	if the memory has not been assigned to this key for this thread.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

VOID *
TclpThreadDataKeyGet(keyPtr)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (DWORD **) */
{
    DWORD *indexPtr = *(DWORD **)keyPtr;
    if (indexPtr == NULL) {
	return NULL;
    } else {
	return (VOID *) TlsGetValue(*indexPtr);
    }
}


/*
 *----------------------------------------------------------------------
 *
 * TclpThreadDataKeySet --
 *
 *	This procedure sets the pointer to a block of thread local storage.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Sets up the thread so future calls to TclpThreadDataKeyGet with
 *	this key will return the data pointer.
 *
 *----------------------------------------------------------------------
 */

void
TclpThreadDataKeySet(keyPtr, data)
    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,
				 * really (pthread_key_t **) */
    VOID *data;			/* Thread local storage */
{
    DWORD *indexPtr = *(DWORD **)keyPtr;
    TlsSetValue(*indexPtr, (void *)data);
}


/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeThreadData --
 *
 *	This procedure cleans up the thread-local storage.  This is
 *	called once for each thread.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Frees up the memory.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeThreadData(keyPtr)
    Tcl_ThreadDataKey *keyPtr;
{
    VOID *result;
    DWORD *indexPtr;

    if (*keyPtr != NULL) {
	indexPtr = *(DWORD **)keyPtr;
	result = (VOID *)TlsGetValue(*indexPtr);
	if (result != NULL) {
	    ckfree((char *)result);
	    TlsSetValue(*indexPtr, (void *)NULL);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeThreadDataKey --
 *
 *	This procedure is invoked to clean up one key.  This is a
 *	process-wide storage identifier.  The thread finalization code
 *	cleans up the thread local storage itself.
 *
 *	This assumes the master lock is held.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The key is deallocated.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeThreadDataKey(keyPtr)
    Tcl_ThreadDataKey *keyPtr;
{
    DWORD *indexPtr;
    if (*keyPtr != NULL) {
	indexPtr = *(DWORD **)keyPtr;
	TlsFree(*indexPtr);
	ckfree((char *)indexPtr);
	*keyPtr = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConditionWait --
 *
 *	This procedure is invoked to wait on a condition variable.
 *	The mutex is automically released as part of the wait, and
 *	automatically grabbed when the condition is signaled.
 *
 *	The mutex must be held when this procedure is called.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May block the current thread.  The mutex is aquired when
 *	this returns.  Will allocate memory for a HANDLE
 *	and initialize this the first time this Tcl_Condition is used.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
    Tcl_Condition *condPtr;	/* Really (WinCondition **) */
    Tcl_Mutex *mutexPtr;	/* Really (CRITICAL_SECTION **) */
    Tcl_Time *timePtr;		/* Timeout on waiting period */
{
    WinCondition *winCondPtr;	/* Per-condition queue head */
    CRITICAL_SECTION *csPtr;	/* Caller's Mutex, after casting */
    DWORD wtime;		/* Windows time value */
    int timeout;		/* True if we got a timeout */
    int doExit = 0;		/* True if we need to do exit setup */
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (tsdPtr->flags & WIN_THREAD_DEAD) {
	/*
	 * No more per-thread event on which to wait.
	 */

	return;
    }

    /*
     * Self initialize the two parts of the contition.
     * The per-condition and per-thread parts need to be
     * handled independently.
     */

    if (tsdPtr->flags == WIN_THREAD_UNINIT) {
	MASTER_LOCK;

	/* 
	 * Create the per-thread event and queue pointers.
	 */

	if (tsdPtr->flags == WIN_THREAD_UNINIT) {
	    tsdPtr->condEvent = CreateEvent(NULL, TRUE /* manual reset */,
			FALSE /* non signaled */, NULL);
	    tsdPtr->nextPtr = NULL;
	    tsdPtr->prevPtr = NULL;
	    tsdPtr->flags = WIN_THREAD_RUNNING;
	    doExit = 1;
	}
	MASTER_UNLOCK;

	if (doExit) {
	    /*
	     * Create a per-thread exit handler to clean up the condEvent.
	     * We must be careful do do this outside the Master Lock
	     * because Tcl_CreateThreadExitHandler uses its own
	     * ThreadSpecificData, and initializing that may drop
	     * back into the Master Lock.
	     */
	    
	    Tcl_CreateThreadExitHandler(FinalizeConditionEvent,
		    (ClientData) tsdPtr);
	}
    }

    if (*condPtr == NULL) {
	MASTER_LOCK;

	/*
	 * Initialize the per-condition queue pointers and Mutex.
	 */

	if (*condPtr == NULL) {
	    winCondPtr = (WinCondition *)ckalloc(sizeof(WinCondition));
	    InitializeCriticalSection(&winCondPtr->condLock);
	    winCondPtr->firstPtr = NULL;
	    winCondPtr->lastPtr = NULL;
	    *condPtr = (Tcl_Condition)winCondPtr;
	    TclRememberCondition(condPtr);
	}
	MASTER_UNLOCK;
    }
    csPtr = *((CRITICAL_SECTION **)mutexPtr);
    winCondPtr = *((WinCondition **)condPtr);
    if (timePtr == NULL) {
	wtime = INFINITE;
    } else {
	wtime = timePtr->sec * 1000 + timePtr->usec / 1000;
    }

    /*
     * Queue the thread on the condition, using
     * the per-condition lock for serialization.
     */

    tsdPtr->flags = WIN_THREAD_BLOCKED;
    tsdPtr->nextPtr = NULL;
    EnterCriticalSection(&winCondPtr->condLock);
    tsdPtr->prevPtr = winCondPtr->lastPtr;		/* A: */
    winCondPtr->lastPtr = tsdPtr;
    if (tsdPtr->prevPtr != NULL) {
        tsdPtr->prevPtr->nextPtr = tsdPtr;
    }
    if (winCondPtr->firstPtr == NULL) {
        winCondPtr->firstPtr = tsdPtr;
    }

    /*
     * Unlock the caller's mutex and wait for the condition, or a timeout.
     * There is a minor issue here in that we don't count down the
     * timeout if we get notified, but another thread grabs the condition
     * before we do.  In that race condition we'll wait again for the
     * full timeout.  Timed waits are dubious anyway.  Either you have
     * the locking protocol wrong and are masking a deadlock,
     * or you are using conditions to pause your thread.
     */
    
    LeaveCriticalSection(csPtr);
    timeout = 0;
    while (!timeout && (tsdPtr->flags & WIN_THREAD_BLOCKED)) {
	ResetEvent(tsdPtr->condEvent);
	LeaveCriticalSection(&winCondPtr->condLock);
	if (WaitForSingleObject(tsdPtr->condEvent, wtime) == WAIT_TIMEOUT) {
	    timeout = 1;
	}
	EnterCriticalSection(&winCondPtr->condLock);
    }

    /*
     * Be careful on timeouts because the signal might arrive right around
     * time time limit and someone else could have taken us off the queue.
     */
    
    if (timeout) {
	if (tsdPtr->flags & WIN_THREAD_RUNNING) {
	    timeout = 0;
	} else {
	    /*
	     * When dequeuing, we can leave the tsdPtr->nextPtr
	     * and tsdPtr->prevPtr with dangling pointers because
	     * they are reinitialilzed w/out reading them when the
	     * thread is enqueued later.
	     */

            if (winCondPtr->firstPtr == tsdPtr) {
                winCondPtr->firstPtr = tsdPtr->nextPtr;
            } else {
                tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
            }
            if (winCondPtr->lastPtr == tsdPtr) {
                winCondPtr->lastPtr = tsdPtr->prevPtr;
            } else {
                tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
            }
            tsdPtr->flags = WIN_THREAD_RUNNING;
	}
    }

    LeaveCriticalSection(&winCondPtr->condLock);
    EnterCriticalSection(csPtr);
}


/*
 *----------------------------------------------------------------------
 *
 * Tcl_ConditionNotify --
 *
 *	This procedure is invoked to signal a condition variable.
 *
 *	The mutex must be held during this call to avoid races,
 *	but this interface does not enforce that.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	May unblock another thread.
 *
 *----------------------------------------------------------------------
 */

void
Tcl_ConditionNotify(condPtr)
    Tcl_Condition *condPtr;
{
    WinCondition *winCondPtr;
    ThreadSpecificData *tsdPtr;
    if (condPtr != NULL) {
	winCondPtr = *((WinCondition **)condPtr);

	/*
	 * Loop through all the threads waiting on the condition
	 * and notify them (i.e., broadcast semantics).  The queue
	 * manipulation is guarded by the per-condition coordinating mutex.
	 */

	EnterCriticalSection(&winCondPtr->condLock);
	while (winCondPtr->firstPtr != NULL) {
	    tsdPtr = winCondPtr->firstPtr;
	    winCondPtr->firstPtr = tsdPtr->nextPtr;
	    if (winCondPtr->lastPtr == tsdPtr) {
		winCondPtr->lastPtr = NULL;
	    }
	    tsdPtr->flags = WIN_THREAD_RUNNING;
	    tsdPtr->nextPtr = NULL;
	    tsdPtr->prevPtr = NULL;	/* Not strictly necessary, see A: */
	    SetEvent(tsdPtr->condEvent);
	}
	LeaveCriticalSection(&winCondPtr->condLock);
    } else {
	/*
	 * Noone has used the condition variable, so there are no waiters.
	 */
    }
}


/*
 *----------------------------------------------------------------------
 *
 * FinalizeConditionEvent --
 *
 *	This procedure is invoked to clean up the per-thread
 *	event used to implement condition waiting.
 *	This is only safe to call at the end of time.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The per-thread event is closed.
 *
 *----------------------------------------------------------------------
 */

static void
FinalizeConditionEvent(data)
    ClientData data;
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)data;
    tsdPtr->flags = WIN_THREAD_DEAD;
    CloseHandle(tsdPtr->condEvent);
}

/*
 *----------------------------------------------------------------------
 *
 * TclpFinalizeCondition --
 *
 *	This procedure is invoked to clean up a condition variable.
 *	This is only safe to call at the end of time.
 *
 *	This assumes the Master Lock is held.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The condition variable is deallocated.
 *
 *----------------------------------------------------------------------
 */

void
TclpFinalizeCondition(condPtr)
    Tcl_Condition *condPtr;
{
    WinCondition *winCondPtr = *(WinCondition **)condPtr;

    /*
     * Note - this is called long after the thread-local storage is
     * reclaimed.  The per-thread condition waiting event is
     * reclaimed earlier in a per-thread exit handler, which is
     * called before thread local storage is reclaimed.
     */

    if (winCondPtr != NULL) {
	ckfree((char *)winCondPtr);
	*condPtr = NULL;
    }
}
#endif /* TCL_THREADS */

Added win/tclWinThrd.h.











































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclWinThrd.h --
 *
 *      This header file defines things for thread support.
 *
 * 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.
 *
 * SCCS: @(#) tclWinThrd.h 1.2 98/01/27 11:48:05
 */
 
#ifndef _TCLWINTHRD
#define _TCLWINTHRD

#ifdef TCL_THREADS

#endif /* TCL_THREADS */

#endif /* _TCLWINTHRD */

Changes to win/tclWinTime.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
/* 
 * tclWinTime.c --
 *
 *	Contains Windows specific versions of Tcl functions that
 *	obtain time values from the operating system.
 *
 * Copyright 1995 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.
 *
 * SCCS: @(#) tclWinTime.c 1.6 97/04/14 17:25:56
 */

#include "tclInt.h"
#include "tclPort.h"

#define SECSPERDAY (60L * 60L * 24L)
#define SECSPERYEAR (SECSPERDAY * 365L)
#define SECSPER4YEAR (SECSPERYEAR * 4L + SECSPERDAY)

/*
 * The following arrays contain the day of year for the last day of
 * each month, where index 1 is January.
 */

static int normalDays[] = {
    -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364
};

static int leapDays[] = {
    -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
};







/*
 * Declarations for functions defined later in this file.
 */

static struct tm *	ComputeGMT _ANSI_ARGS_((const time_t *tp));







|




|


|
<

















>
>
>
>
>
>







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
/* 
 * tclWinTime.c --
 *
 *	Contains Windows specific versions of Tcl functions that
 *	obtain time values from the operating system.
 *
 * Copyright 1995-1998 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: tclWinTime.c,v 1.1.2.4 1999/04/06 00:29:19 stanton Exp $
 */

#include "tclWinInt.h"


#define SECSPERDAY (60L * 60L * 24L)
#define SECSPERYEAR (SECSPERDAY * 365L)
#define SECSPER4YEAR (SECSPERYEAR * 4L + SECSPERDAY)

/*
 * The following arrays contain the day of year for the last day of
 * each month, where index 1 is January.
 */

static int normalDays[] = {
    -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364
};

static int leapDays[] = {
    -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
};

typedef struct ThreadSpecificData {
    char tzName[64];		/* Time zone name */
    struct tm tm;		/* time information */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Declarations for functions defined later in this file.
 */

static struct tm *	ComputeGMT _ANSI_ARGS_((const time_t *tp));

158
159
160
161
162
163
164
165
166






167












168







169








170






















171
172

173
174
175
176
177
178
179
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpGetTZName()
{






    tzset();












    if (_daylight && _tzname[1] != NULL) {







	return _tzname[1];








    } else {






















	return _tzname[0];
    }

}

/*
 *----------------------------------------------------------------------
 *
 * TclpGetDate --
 *







|

>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

>







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
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
TclpGetTZName(int dst)
{
    int len;
    char *zone, *p;
    TIME_ZONE_INFORMATION tz;
    Tcl_Encoding encoding;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    char *name = tsdPtr->tzName;

    /*
     * tzset() under Borland doesn't seem to set up tzname[] at all.
     * tzset() under MSVC has the following weird observed behavior:
     *	 First time we call "clock format [clock seconds] -format %Z -gmt 1"
     *	 we get "GMT", but on all subsequent calls we get the current time 
     *	 zone string, even though env(TZ) is GMT and the variable _timezone 
     *   is 0.
     */

    name[0] = '\0';

    zone = getenv("TZ");
    if (zone != NULL) {
	/*
	 * TZ is of form "NST-4:30NDT", where "NST" would be the
	 * name of the standard time zone for this area, "-4:30" is
	 * the offset from GMT in hours, and "NDT is the name of 
	 * the daylight savings time zone in this area.  The offset 
	 * and DST strings are optional.
	 */

	len = strlen(zone);
	if (len > 3) {
	    len = 3;
	}
	if (dst != 0) {
	    /*
	     * Skip the offset string and get the DST string.
	     */

	    p = zone + len;
	    p += strspn(p, "+-:0123456789");
	    if (*p != '\0') {
		zone = p;
		len = strlen(zone);
		if (len > 3) {
		    len = 3;
		}
	    }
	}
	Tcl_ExternalToUtf(NULL, NULL, zone, len, 0, NULL, name,
		sizeof(tsdPtr->tzName), NULL, NULL, NULL);
    }
    if ((name[0] == '\0') 
	    && (GetTimeZoneInformation(&tz) != TIME_ZONE_ID_UNKNOWN)) {
	encoding = Tcl_GetEncoding(NULL, "unicode");
	Tcl_ExternalToUtf(NULL, encoding, 
		(char *) ((dst) ? tz.DaylightName : tz.StandardName), -1, 
		0, NULL, name, sizeof(tsdPtr->tzName), NULL, NULL, NULL);
	Tcl_FreeEncoding(encoding);
    } 
    if (name[0] == '\0') {
	return "%Z";
    }
    return name;
}

/*
 *----------------------------------------------------------------------
 *
 * TclpGetDate --
 *
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
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

struct tm *
TclpGetDate(tp, useGMT)
    const time_t *tp;
    int useGMT;
{

    struct tm *tmPtr;
    long time;

    if (!useGMT) {
	tzset();

	/*
	 * If we are in the valid range, let the C run-time library
	 * handle it.  Otherwise we need to fake it.  Note that this
	 * algorithm ignores daylight savings time before the epoch.
	 */

	time = *tp - _timezone;
	if (time >= 0) {
	    return localtime(tp);
	}


	
	/*
	 * If we aren't near to overflowing the long, just add the bias and
	 * use the normal calculation.  Otherwise we will need to adjust
	 * the result at the end.
	 */








|
|


>












<
|


>
>







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
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

struct tm *
TclpGetDate(t, useGMT)
    TclpTime_t t;
    int useGMT;
{
    const time_t *tp = (const time_t *) t;
    struct tm *tmPtr;
    long time;

    if (!useGMT) {
	tzset();

	/*
	 * If we are in the valid range, let the C run-time library
	 * handle it.  Otherwise we need to fake it.  Note that this
	 * algorithm ignores daylight savings time before the epoch.
	 */


	if (*tp >= 0) {
	    return localtime(tp);
	}

	time = *tp - _timezone;
	
	/*
	 * If we aren't near to overflowing the long, just add the bias and
	 * use the normal calculation.  Otherwise we will need to adjust
	 * the result at the end.
	 */

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
 *
 * ComputeGMT --
 *
 *	This function computes GMT given the number of seconds since
 *	the epoch (midnight Jan 1 1970).
 *
 * Results:
 *	Returns a statically allocated struct tm.
 *
 * Side effects:
 *	Updates the values of the static struct tm.
 *
 *----------------------------------------------------------------------
 */

static struct tm *
ComputeGMT(tp)
    const time_t *tp;
{
    static struct tm tm;	  /* This should be allocated per thread.*/
    long tmp, rem;
    int isLeap;
    int *days;




    /*
     * Compute the 4 year span containing the specified time.
     */

    tmp = *tp / SECSPER4YEAR;
    rem = *tp % SECSPER4YEAR;







|











|



>
>
>







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
 *
 * ComputeGMT --
 *
 *	This function computes GMT given the number of seconds since
 *	the epoch (midnight Jan 1 1970).
 *
 * Results:
 *	Returns a (per thread) statically allocated struct tm.
 *
 * Side effects:
 *	Updates the values of the static struct tm.
 *
 *----------------------------------------------------------------------
 */

static struct tm *
ComputeGMT(tp)
    const time_t *tp;
{
    struct tm *tmPtr;
    long tmp, rem;
    int isLeap;
    int *days;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    tmPtr = &tsdPtr->tm;

    /*
     * Compute the 4 year span containing the specified time.
     */

    tmp = *tp / SECSPER4YEAR;
    rem = *tp % SECSPER4YEAR;
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
		tmp++;
		rem -= SECSPERYEAR + SECSPERDAY;
	    } else {
		isLeap = 1;
	    }
	}
    }
    tm.tm_year = tmp;

    /*
     * Compute the day of year and leave the seconds in the current day in
     * the remainder.
     */

    tm.tm_yday = rem / SECSPERDAY;
    rem %= SECSPERDAY;
    
    /*
     * Compute the time of day.
     */

    tm.tm_hour = rem / 3600;
    rem %= 3600;
    tm.tm_min = rem / 60;
    tm.tm_sec = rem % 60;

    /*
     * Compute the month and day of month.
     */

    days = (isLeap) ? leapDays : normalDays;
    for (tmp = 1; days[tmp] < tm.tm_yday; tmp++) {
    }
    tm.tm_mon = --tmp;
    tm.tm_mday = tm.tm_yday - days[tmp];

    /*
     * Compute day of week.  Epoch started on a Thursday.
     */

    tm.tm_wday = (*tp / SECSPERDAY) + 4;
    if ((*tp % SECSPERDAY) < 0) {
	tm.tm_wday--;
    }
    tm.tm_wday %= 7;
    if (tm.tm_wday < 0) {
	tm.tm_wday += 7;
    }

    return &tm;
}







|






|






|

|
|






|

|
|





|

|

|
|
|


|

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
		tmp++;
		rem -= SECSPERYEAR + SECSPERDAY;
	    } else {
		isLeap = 1;
	    }
	}
    }
    tmPtr->tm_year = tmp;

    /*
     * Compute the day of year and leave the seconds in the current day in
     * the remainder.
     */

    tmPtr->tm_yday = rem / SECSPERDAY;
    rem %= SECSPERDAY;
    
    /*
     * Compute the time of day.
     */

    tmPtr->tm_hour = rem / 3600;
    rem %= 3600;
    tmPtr->tm_min = rem / 60;
    tmPtr->tm_sec = rem % 60;

    /*
     * Compute the month and day of month.
     */

    days = (isLeap) ? leapDays : normalDays;
    for (tmp = 1; days[tmp] < tmPtr->tm_yday; tmp++) {
    }
    tmPtr->tm_mon = --tmp;
    tmPtr->tm_mday = tmPtr->tm_yday - days[tmp];

    /*
     * Compute day of week.  Epoch started on a Thursday.
     */

    tmPtr->tm_wday = (*tp / SECSPERDAY) + 4;
    if ((*tp % SECSPERDAY) < 0) {
	tmPtr->tm_wday--;
    }
    tmPtr->tm_wday %= 7;
    if (tmPtr->tm_wday < 0) {
	tmPtr->tm_wday += 7;
    }

    return tmPtr;
}

Changes to win/tclsh.rc.

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
// SCCS: @(#) tclsh.rc 1.15 96/09/18 18:19:38
//
// Version
//

#define RESOURCE_INCLUDED
#include <tcl.h>



VS_VERSION_INFO VERSIONINFO
 FILEVERSION 	TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
 PRODUCTVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
 FILEFLAGSMASK 	0x3fL
 FILEFLAGS 	0x0L
 FILEOS 	0x4L
 FILETYPE	0x1L
 FILESUBTYPE 	0x0L
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 \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
|







>
>





|
|










|







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
// RCS: @(#) $Id: tclsh.rc,v 1.1.2.2 1998/09/24 23:59:54 stanton Exp $
//
// Version
//

#define RESOURCE_INCLUDED
#include <tcl.h>

LANGUAGE 0x9, 0x1	/* LANG_ENGLISH, SUBLANG_DEFAULT */

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 	TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
 PRODUCTVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL
 FILEFLAGSMASK 	0x3fL
 FILEFLAGS 	0x0L
 FILEOS 	0x4	/* VOS__WINDOWS32 */
 FILETYPE 	0x2	/* VFT_DLL */
 FILESUBTYPE 	0x0L
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

Changes to win/winDumpExts.c.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 *           this other compilers.  If _MSC_VER is defined,
 *           the underscore is removed.  If not, it isn't.  To get a
 *           full dump of an object file, use the -f option.  This can
 *           help determine the something that may be different with a
 *           compiler other than Visual C++.
 *----------------------------------------------------------------------
 *
 * SCCS: @(#) winDumpExts.c 1.11 96/09/18 15:25:11
 */

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <process.h>








|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 *           this other compilers.  If _MSC_VER is defined,
 *           the underscore is removed.  If not, it isn't.  To get a
 *           full dump of an object file, use the -f option.  This can
 *           help determine the something that may be different with a
 *           compiler other than Visual C++.
 *----------------------------------------------------------------------
 *
 * RCS: @(#) $Id: winDumpExts.c,v 1.1.2.2 1999/02/10 23:31:29 stanton Exp $
 */

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <process.h>

232
233
234
235
236
237
238






239
240
241
242
243
244
245
246
247
		    strncpy(symbol, pSymbolTable->N.ShortName, 8);
		    symbol[8] = 0;
		} else {
		    s = stringTable + pSymbolTable->N.Name.Long;
		    strcpy(symbol, s);
		}
		s = symbol;






		f = strchr(s, '@');
		if (f) {
		    *f = 0;
		}
#if defined(_MSC_VER) && defined(_X86_)
		if (symbol[0] == '_') {
		    s = &symbol[1];
		}
#endif







>
>
>
>
>
>
|
|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
		    strncpy(symbol, pSymbolTable->N.ShortName, 8);
		    symbol[8] = 0;
		} else {
		    s = stringTable + pSymbolTable->N.Name.Long;
		    strcpy(symbol, s);
		}
		s = symbol;

		/*
		 * Skip to the last @ and ensure it is followed by digits,
		 * otherwise it is probably part of a C++ mangled name.
		 */

		f = strrchr(s, '@');
		if (f && f[1] >= '0' && f[1] <= '9') {
		    *f = 0;
		}
#if defined(_MSC_VER) && defined(_X86_)
		if (symbol[0] == '_') {
		    s = &symbol[1];
		}
#endif
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
    
    if (! full) {
	char *dllname = argv[arg];
	arg++;
	if (arg == argc) {
	    goto Usage;
	}
	fprintf(fout, "LIBRARY    %s\n", dllname);
	fprintf(fout, "EXETYPE WINDOWS\n");
	fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
	fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
	fprintf(fout, "EXPORTS\n");
    }

    for (; arg < argc; arg++) {
	if (argv[arg][0] == '@') {
	    FILE *fargs = fopen(&argv[arg][1], "r");
	    if (fargs == NULL) {







<
<
<
<







470
471
472
473
474
475
476




477
478
479
480
481
482
483
    
    if (! full) {
	char *dllname = argv[arg];
	arg++;
	if (arg == argc) {
	    goto Usage;
	}




	fprintf(fout, "EXPORTS\n");
    }

    for (; arg < argc; arg++) {
	if (argv[arg][0] == '@') {
	    FILE *fargs = fopen(&argv[arg][1], "r");
	    if (fargs == NULL) {